diff --git a/.github/workflows/auto-label-issues.yml b/.github/workflows/auto-label-issues.yml new file mode 100644 index 0000000000000000000000000000000000000000..cd889b5941989a62e0784a73e974b25c166e6f4c --- /dev/null +++ b/.github/workflows/auto-label-issues.yml @@ -0,0 +1,17 @@ +# If the author of the issues is not a contributor to the project, label +# the issue with 'Z0-unconfirmed' + +name: Label New Issues +on: + issues: + types: [opened] + +jobs: + label-new-issues: + runs-on: ubuntu-latest + steps: + - name: Label drafts + uses: andymckay/labeler@master + if: github.event.issue.author_association == 'NONE' + with: + add-labels: 'Z0-unconfirmed' diff --git a/.github/workflows/auto-label-prs.yml b/.github/workflows/auto-label-prs.yml new file mode 100644 index 0000000000000000000000000000000000000000..f0b8e9b343e29ce7eb25bfb41a3f56277b4d7558 --- /dev/null +++ b/.github/workflows/auto-label-prs.yml @@ -0,0 +1,21 @@ +name: Label PRs +on: + pull_request: + types: [opened,ready_for_review] + +jobs: + label-new-prs: + runs-on: ubuntu-latest + steps: + - name: Label drafts + uses: andymckay/labeler@master + if: github.event.pull_request.draft == true + with: + add-labels: 'A3-inprogress' + remove-labels: 'A0-pleasereview' + - name: Label PRs + uses: andymckay/labeler@master + if: github.event.pull_request.draft == false && ! contains(github.event.pull_request.labels.*.name, 'A2-insubstantial') + with: + add-labels: 'A0-pleasereview' + remove-labels: 'A3-inprogress' diff --git a/.github/workflows/burnin-label-notification.yml b/.github/workflows/burnin-label-notification.yml new file mode 100644 index 0000000000000000000000000000000000000000..da422a659ee08600885c4241bbd39ddb5e62f25d --- /dev/null +++ b/.github/workflows/burnin-label-notification.yml @@ -0,0 +1,17 @@ +name: Notify devops when burn-in label applied +on: + pull_request: + types: [labeled] + +jobs: + notify-devops: + runs-on: ubuntu-latest + steps: + - name: Notify devops + if: github.event.label.name == 'A1-needsburnin' + uses: s3krit/matrix-message-action@v0.0.2 + with: + room_id: ${{ secrets.POLKADOT_DEVOPS_MATRIX_ROOM_ID }} + access_token: ${{ secrets.POLKADOT_DEVOPS_MATRIX_ACCESS_TOKEN }} + message: "@room Burn-in request received for [${{ github.event.pull_request.title }}](${{ github.event.pull_request.html_url }})" + server: "matrix.parity.io" diff --git a/.github/workflows/polkadot-companion-labels.yml b/.github/workflows/polkadot-companion-labels.yml new file mode 100644 index 0000000000000000000000000000000000000000..27f743e1bd4529dc83ee7dfd5b96c6c5bb4ac3f8 --- /dev/null +++ b/.github/workflows/polkadot-companion-labels.yml @@ -0,0 +1,31 @@ +name: Check Polkadot Companion and Label + +on: + pull_request: + types: [opened, synchronize] + +jobs: + check_status: + runs-on: ubuntu-latest + steps: + - name: Monitor the status of the gitlab-check-companion-build job + uses: s3krit/await-status-action@v1.0.1 + id: 'check-companion-status' + with: + authToken: ${{ secrets.GITHUB_TOKEN }} + ref: ${{ github.event.pull_request.head.sha }} + contexts: 'continuous-integration/gitlab-check-polkadot-companion-build' + timeout: 1800 + notPresentTimeout: 3600 # It can take quite a while before the job starts... + failureStates: failure + interruptedStates: error # Error = job was probably cancelled. We don't want to label the PR in that case + - name: Label success + uses: andymckay/labeler@master + if: steps.check-companion-status.outputs.result == 'success' + with: + remove-labels: 'A7-needspolkadotpr' + - name: Label failure + uses: andymckay/labeler@master + if: steps.check-companion-status.outputs.result == 'failure' + with: + add-labels: 'A7-needspolkadotpr' diff --git a/.gitignore b/.gitignore index 6398c09fe796278130978c2a8598ee9270399388..353d49df28f34b896567b0aa91bb08e056a5832c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ rls*.log .local **/hfuzz_target/ **/hfuzz_workspace/ +.cargo/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 681453350608eedd3bae6ac7da8c30f48754e775..c97d68bab0030484317757c9a69737430c80d5d8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,7 +10,7 @@ # # my-example-job: # stage: test # One of the stages listed below this job (required) -# image: parity/tools:latest # Any docker image (required) +# image: paritytech/tools:latest # Any docker image (required) # allow_failure: true # Allow the pipeline to continue if this job fails (default: false) # dependencies: # - build-rust-doc-release # Any jobs that are required to run before this job (optional) @@ -22,28 +22,28 @@ # - ./.maintain/gitlab/my_amazing_script.sh stages: + - check - test - build - post-build-test + - docker + - chaos - publish - - kubernetes + - deploy - flaming-fir -variables: +variables: &default-vars GIT_STRATEGY: fetch GIT_DEPTH: 100 - SCCACHE_DIR: "/ci-cache/${CI_PROJECT_NAME}/sccache" CARGO_INCREMENTAL: 0 - CI_SERVER_NAME: "GitLab CI" DOCKER_OS: "debian:stretch" ARCH: "x86_64" # FIXME set to release CARGO_UNLEASH_INSTALL_PARAMS: "--version 1.0.0-alpha.10" CARGO_UNLEASH_PKG_DEF: "--skip node node-* pallet-template pallet-example pallet-example-* subkey chain-spec-builder" - CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER: "wasm-bindgen-test-runner" - WASM_BINDGEN_TEST_TIMEOUT: 120 - CHROMEDRIVER_ARGS: "--log-level=INFO --whitelisted-ips=127.0.0.1" +default: + cache: {} .collect-artifacts: &collect-artifacts artifacts: @@ -58,30 +58,32 @@ variables: - kubernetes-parity-build environment: name: parity-build + interruptible: true .docker-env: &docker-env - image: parity/rust-builder:latest + image: paritytech/ci-linux:production before_script: - rustup show - cargo --version - sccache -s - only: - - master - - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 - - schedules - - web - - /^[0-9]+$/ # PRs retry: max: 2 when: - runner_system_failure - unknown_failure - api_failure - dependencies: [] interruptible: true tags: - linux-docker +.docker-env-only: &docker-env-only + only: + - master + - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + - schedules + - web + - /^[0-9]+$/ # PRs + .build-only: &build-only only: - master @@ -89,66 +91,94 @@ variables: - /^pre-v[0-9]+\.[0-9]+-[0-9a-f]+$/ - web +.build-rules: &build-rules + rules: + - if: '$DEPLOY_TAG' + when: never + - if: $CI_COMMIT_REF_NAME=="master" + when: always + - if: $CI_PIPELINE_SOURCE=="web" + when: always + - if: $CI_COMMIT_REF_NAME=~ /^v[0-9]+\.[0-9]+.*$/ + when: always + - if: $CI_COMMIT_REF_NAME=~ /^pre-v[0-9]+\.[0-9]+-[0-9a-f]+$/ + when: always + - if: '$CI_COMMIT_MESSAGE =~ /\[chaos:(basic|medium|large)\]/ && $CI_COMMIT_REF_NAME=~ /^[0-9]+$/' # i.e add [chaos:basic] in commit message to trigger + when: always + - when: never + +.chaos-only: &chaos-only + only: + variables: + - '$CI_COMMIT_MESSAGE =~ /\[chaos:(basic|medium|large)\]/ && $CI_COMMIT_REF_NAME=~ /^[0-9]+$/' # i.e add [chaos:basic] in commit message to trigger + #### stage: .pre skip-if-draft: - image: parity/tools:latest + image: paritytech/tools:latest <<: *kubernetes-build stage: .pre only: - /^[0-9]+$/ # Pull requests script: + - echo "Commit message is ${CI_COMMIT_MESSAGE}" + - echo "Ref is ${CI_COMMIT_REF_NAME}" + - echo "pipeline source is ${CI_PIPELINE_SOURCE}" + - echo "deploy tag is ${DEPLOY_TAG}" - ./.maintain/gitlab/skip_if_draft.sh -#### stage: test +#### stage: check check-runtime: - stage: test - image: parity/tools:latest + stage: check + image: paritytech/tools:latest <<: *kubernetes-build only: - /^[0-9]+$/ variables: + <<: *default-vars GITLAB_API: "https://gitlab.parity.io/api/v4" GITHUB_API_PROJECT: "parity%2Finfrastructure%2Fgithub-api" script: - ./.maintain/gitlab/check_runtime.sh - interruptible: true allow_failure: true check-signed-tag: - stage: test - image: parity/tools:latest + stage: check + image: paritytech/tools:latest <<: *kubernetes-build only: - - tags + - /^ci-release-.*$/ - /^v[0-9]+\.[0-9]+\.[0-9]+.*$/ script: - ./.maintain/gitlab/check_signed.sh - allow_failure: false check-line-width: - stage: test - image: parity/tools:latest + stage: check + image: paritytech/tools:latest <<: *kubernetes-build only: - /^[0-9]+$/ script: - ./.maintain/gitlab/check_line_width.sh - interruptible: true allow_failure: true -check-polkadot-companion-build: - stage: build - <<: *docker-env +test-dependency-rules: + stage: check + image: paritytech/tools:latest + <<: *kubernetes-build + except: + variables: + - $DEPLOY_TAG script: - - ./.maintain/gitlab/check_polkadot_companion_build.sh - interruptible: true - allow_failure: true + - .maintain/ensure-deps.sh + +#### stage: test cargo-audit: stage: test <<: *docker-env + <<: *docker-env-only except: - /^[0-9]+$/ script: @@ -158,6 +188,11 @@ cargo-audit: cargo-deny: stage: test <<: *docker-env + <<: *docker-env-only + only: + - schedules + - tags + - web script: - cargo deny check --hide-inclusion-graph -c .maintain/deny.toml after_script: @@ -173,55 +208,68 @@ cargo-deny: cargo-check-benches: stage: test <<: *docker-env + <<: *docker-env-only script: - BUILD_DUMMY_WASM_BINARY=1 time cargo +nightly check --benches --all + - cargo run --release -p node-bench -- ::node::import::native::sr25519::transfer_keep_alive::paritydb::small + - cargo run --release -p node-bench -- ::trie::read::small - sccache -s cargo-check-subkey: stage: test <<: *docker-env - except: - - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + <<: *docker-env-only script: - cd ./bin/utils/subkey - BUILD_DUMMY_WASM_BINARY=1 time cargo check --release - sccache -s -test-linux-stable: &test-linux +test-deterministic-wasm: stage: test <<: *docker-env + <<: *docker-env-only variables: - # Enable debug assertions since we are running optimized builds for testing - # but still want to have debug assertions. - RUSTFLAGS: -Cdebug-assertions=y + <<: *default-vars except: variables: - $DEPLOY_TAG script: - - WASM_BUILD_NO_COLOR=1 time cargo test --all --release --verbose --locked |& - tee output.log + # build runtime + - WASM_BUILD_NO_COLOR=1 cargo build --verbose --release -p node-runtime + # make checksum + - sha256sum target/release/wbuild/target/wasm32-unknown-unknown/release/node_runtime.wasm > checksum.sha256 + # clean up – FIXME: can we reuse some of the artifacts? + - cargo clean + # build again + - WASM_BUILD_NO_COLOR=1 cargo build --verbose --release -p node-runtime + # confirm checksum + - sha256sum -c checksum.sha256 - sccache -s - - echo "____Test job successful, checking for warnings____" - - awk '/^warning:/,/^$/ { print }' output.log > ${CI_COMMIT_SHORT_SHA}_warnings.log - - if [ -s ${CI_COMMIT_SHORT_SHA}_warnings.log ]; then - cat ${CI_COMMIT_SHORT_SHA}_warnings.log; - exit 1; - else - echo "___No warnings___"; - fi -test-dependency-rules: +test-linux-stable: &test-linux stage: test <<: *docker-env + <<: *docker-env-only + variables: + <<: *default-vars + # Enable debug assertions since we are running optimized builds for testing + # but still want to have debug assertions. + RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" + RUST_BACKTRACE: 1 + WASM_BUILD_NO_COLOR: 1 except: variables: - $DEPLOY_TAG script: - - .maintain/ensure-deps.sh + # this job runs all tests in former runtime-benchmarks, frame-staking and wasmtime tests + - time cargo test --workspace --locked --release --verbose --features runtime-benchmarks --manifest-path bin/node/cli/Cargo.toml + - WASM_BUILD_NO_COLOR=1 SUBSTRATE_TEST_TIMEOUT=1 time cargo test -p substrate-test-utils --release --verbose --locked -- --ignored timeout + - sccache -s unleash-check: stage: test <<: *docker-env + <<: *docker-env-only only: - master - tags @@ -229,26 +277,13 @@ unleash-check: - cargo install cargo-unleash ${CARGO_UNLEASH_INSTALL_PARAMS} - cargo unleash check ${CARGO_UNLEASH_PKG_DEF} -test-frame-staking: - stage: test - <<: *docker-env - variables: - # Enable debug assertions since we are running optimized builds for testing - # but still want to have debug assertions. - RUSTFLAGS: -Cdebug-assertions=y - RUST_BACKTRACE: 1 - except: - variables: - - $DEPLOY_TAG - script: - - cd frame/staking/ - - WASM_BUILD_NO_COLOR=1 time cargo test --release --verbose --no-default-features --features "std testing-utils" - - sccache -s - test-frame-examples-compile-to-wasm: + # into one job stage: test <<: *docker-env + <<: *docker-env-only variables: + <<: *default-vars # Enable debug assertions since we are running optimized builds for testing # but still want to have debug assertions. RUSTFLAGS: -Cdebug-assertions=y @@ -263,49 +298,16 @@ test-frame-examples-compile-to-wasm: - cargo +nightly build --target=wasm32-unknown-unknown --no-default-features - sccache -s -test-wasmtime: - stage: test - <<: *docker-env - variables: - # Enable debug assertions since we are running optimized builds for testing - # but still want to have debug assertions. - RUSTFLAGS: -Cdebug-assertions=y - RUST_BACKTRACE: 1 - except: - variables: - - $DEPLOY_TAG - script: - - cd client/executor - - WASM_BUILD_NO_COLOR=1 time cargo test --release --verbose --features wasmtime - - sccache -s - -test-runtime-benchmarks: - stage: test - <<: *docker-env - variables: - # Enable debug assertions since we are running optimized builds for testing - # but still want to have debug assertions. - RUSTFLAGS: -Cdebug-assertions=y - RUST_BACKTRACE: 1 - except: - variables: - - $DEPLOY_TAG - script: - - cd bin/node/cli - - WASM_BUILD_NO_COLOR=1 time cargo test --release --verbose --features runtime-benchmarks - - sccache -s - test-linux-stable-int: <<: *test-linux except: - refs: - - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 variables: - $DEPLOY_TAG script: - echo "___Logs will be partly shown at the end in case of failure.___" - echo "___Full log will be saved to the job artifacts only in case of failure.___" - - WASM_BUILD_NO_COLOR=1 RUST_LOG=sync=trace,consensus=trace,client=trace,state-db=trace,db=trace,forks=trace,state_db=trace,storage_cache=trace + - WASM_BUILD_NO_COLOR=1 + RUST_LOG=sync=trace,consensus=trace,client=trace,state-db=trace,db=trace,forks=trace,state_db=trace,storage_cache=trace time cargo test -p node-cli --release --verbose --locked -- --ignored &> ${CI_COMMIT_SHORT_SHA}_int_failure.log - sccache -s @@ -321,8 +323,7 @@ test-linux-stable-int: check-web-wasm: stage: test <<: *docker-env - except: - - /^v[0-9]+\.[0-9]+.*$/ # i.e. v1.0, v2.1rc1 + <<: *docker-env-only script: # WASM support is in progress. As more and more crates support WASM, we # should add entries here. See https://github.com/paritytech/substrate/issues/2416 @@ -340,7 +341,9 @@ check-web-wasm: test-full-crypto-feature: stage: test <<: *docker-env + <<: *docker-env-only variables: + <<: *default-vars # Enable debug assertions since we are running optimized builds for testing # but still want to have debug assertions. RUSTFLAGS: -Cdebug-assertions=y @@ -357,21 +360,59 @@ test-full-crypto-feature: cargo-check-macos: stage: test + # shell runner on mac ignores the image set in *docker-env <<: *docker-env + <<: *docker-env-only script: - BUILD_DUMMY_WASM_BINARY=1 time cargo check --release - sccache -s tags: - osx +test-prometheus-alerting-rules: + stage: test + image: paritytech/tools:latest + <<: *kubernetes-build + script: + - promtool check rules .maintain/monitoring/alerting-rules/alerting-rules.yaml + - cat .maintain/monitoring/alerting-rules/alerting-rules.yaml | promtool test rules .maintain/monitoring/alerting-rules/alerting-rule-tests.yaml + #### stage: build +check-polkadot-companion-status: + stage: build + image: paritytech/tools:latest + <<: *kubernetes-build + only: + - /^[0-9]+$/ # PRs + script: + - ./.maintain/gitlab/check_polkadot_companion_status.sh + +check-polkadot-companion-build: + stage: build + <<: *docker-env + <<: *docker-env-only + needs: + - job: test-linux-stable-int + artifacts: false + script: + - ./.maintain/gitlab/check_polkadot_companion_build.sh + after_script: + - cd polkadot && git rev-parse --abbrev-ref HEAD + allow_failure: true + test-browser-node: stage: build <<: *docker-env + <<: *docker-env-only needs: - job: check-web-wasm artifacts: false + variables: + <<: *default-vars + CHROMEDRIVER_ARGS: "--log-level=INFO --whitelisted-ips=127.0.0.1" + CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER: "wasm-bindgen-test-runner" + WASM_BINDGEN_TEST_TIMEOUT: 120 script: - cargo +nightly test --target wasm32-unknown-unknown -p node-browser-testing -Z features=itarget @@ -379,12 +420,12 @@ build-linux-substrate: &build-binary stage: build <<: *collect-artifacts <<: *docker-env - <<: *build-only + <<: *build-rules + needs: + - job: test-linux-stable + artifacts: false before_script: - mkdir -p ./artifacts/substrate/ - except: - variables: - - $DEPLOY_TAG script: - WASM_BUILD_NO_COLOR=1 time cargo build --release --verbose - mv ./target/release/substrate ./artifacts/substrate/. @@ -394,7 +435,7 @@ build-linux-substrate: &build-binary else ./artifacts/substrate/substrate --version | sed -n -E 's/^substrate ([0-9.]+.*-[0-9a-f]{7,13})-.*$/\1/p' | - tee ./artifacts/substrate/VERSION; + tee ./artifacts/substrate/VERSION; fi - sha256sum ./artifacts/substrate/substrate | tee ./artifacts/substrate/substrate.sha256 - printf '\n# building node-template\n\n' @@ -404,7 +445,14 @@ build-linux-substrate: &build-binary build-linux-subkey: &build-subkey - <<: *build-binary + stage: build + <<: *collect-artifacts + <<: *docker-env + <<: *docker-env-only + <<: *build-only + needs: + - job: cargo-check-subkey + artifacts: false before_script: - mkdir -p ./artifacts/subkey script: @@ -431,6 +479,7 @@ build-macos-subkey: build-rust-doc-release: stage: build <<: *docker-env + <<: *docker-env-only allow_failure: true artifacts: name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}-doc" @@ -441,23 +490,16 @@ build-rust-doc-release: <<: *build-only script: - rm -f ./crate-docs/index.html # use it as an indicator if the job succeeds - - BUILD_DUMMY_WASM_BINARY=1 RUSTDOCFLAGS="--html-in-header $(pwd)/.maintain/rustdoc-header.html" time cargo +nightly doc --release --all --verbose + - BUILD_DUMMY_WASM_BINARY=1 RUSTDOCFLAGS="--html-in-header $(pwd)/.maintain/rustdoc-header.html" + time cargo +nightly doc --release --all --verbose - cp -R ./target/doc ./crate-docs - echo "" > ./crate-docs/index.html - sccache -s -check-polkadot-companion-status: - stage: post-build-test - image: parity/tools:latest - <<: *kubernetes-build - only: - - /^[0-9]+$/ - script: - - ./.maintain/gitlab/check_polkadot_companion_status.sh - +#### stage: post-build-test trigger-contracts-ci: - stage: publish + stage: post-build-test needs: - job: build-linux-substrate artifacts: false @@ -471,14 +513,88 @@ trigger-contracts-ci: - master - schedules +#### stage: docker +docker-build-chaos: &docker-build-chaos + <<: *chaos-only + stage: docker + needs: + - job: build-linux-substrate + image: docker:stable + tags: + - kubernetes-parity-build + variables: + <<: *default-vars + DOCKER_HOST: tcp://localhost:2375 + DOCKER_DRIVER: overlay2 + PRODUCT: substrate + DOCKERFILE: $PRODUCT.Dockerfile + CONTAINER_IMAGE: paritypr/$PRODUCT + environment: + name: parity-chaosnet + services: + - docker:dind + before_script: + - test "$DOCKER_CHAOS_USER" -a "$DOCKER_CHAOS_TOKEN" + || ( echo "no docker credentials provided"; exit 1 ) + - docker login -u "$DOCKER_CHAOS_USER" -p "$DOCKER_CHAOS_TOKEN" + - docker info + script: + - cd ./artifacts/$PRODUCT/ + - VERSION="ci-${CI_COMMIT_SHORT_SHA}" + - echo "${PRODUCT} version = ${VERSION}" + - test -z "${VERSION}" && exit 1 + - docker build + --build-arg VCS_REF="${CI_COMMIT_SHA}" + --build-arg BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" + --tag $CONTAINER_IMAGE:$VERSION + --file $DOCKERFILE . + - docker push $CONTAINER_IMAGE:$VERSION + after_script: + - docker logout + +#### stage: chaos +chaos-test-singlenodeheight: + <<: *chaos-only + stage: chaos + image: parity/chaostools:latest + needs: + - job: docker-build-chaos + tags: + - parity-chaos + variables: + <<: *default-vars + PRODUCT: substrate + DOCKERFILE: $PRODUCT.Dockerfile + CONTAINER_IMAGE: paritypr/$PRODUCT + KEEP_NAMESPACE: 0 + NAMESPACE: "substrate-ci-${CI_COMMIT_SHORT_SHA}-${CI_PIPELINE_ID}" + VERSION: "ci-${CI_COMMIT_SHORT_SHA}" + interruptible: true + environment: + name: parity-chaosnet + script: + - cd ./.maintain/chaostest + - npm link + - chaostest spawn dev -i $CONTAINER_IMAGE:$VERSION + - chaostest singlenodeheight -h 30 + after_script: + - chaostest clean + #### stage: publish -.publish-docker-release: &publish-docker-release +.build-push-docker-image: &build-push-docker-image <<: *build-only <<: *kubernetes-build image: docker:stable services: - docker:dind + variables: &docker-build-vars + <<: *default-vars + DOCKER_HOST: tcp://localhost:2375 + DOCKER_DRIVER: overlay2 + GIT_STRATEGY: none + DOCKERFILE: $PRODUCT.Dockerfile + CONTAINER_IMAGE: parity/$PRODUCT before_script: - test "$Docker_Hub_User_Parity" -a "$Docker_Hub_Pass_Parity" || ( echo "no docker credentials provided"; exit 1 ) @@ -500,18 +616,15 @@ trigger-contracts-ci: publish-docker-substrate: stage: publish - <<: *publish-docker-release + <<: *build-push-docker-image # collect VERSION artifact here to pass it on to kubernetes <<: *collect-artifacts - dependencies: - - build-linux-substrate + needs: + - job: build-linux-substrate + artifacts: true variables: - DOCKER_HOST: tcp://localhost:2375 - DOCKER_DRIVER: overlay2 - GIT_STRATEGY: none + <<: *docker-build-vars PRODUCT: substrate - DOCKERFILE: $PRODUCT.Dockerfile - CONTAINER_IMAGE: parity/$PRODUCT after_script: - docker logout # only VERSION information is needed for the deployment @@ -519,16 +632,13 @@ publish-docker-substrate: publish-docker-subkey: stage: publish - <<: *publish-docker-release - dependencies: - - build-linux-subkey + <<: *build-push-docker-image + needs: + - job: build-linux-subkey + artifacts: true variables: - DOCKER_HOST: tcp://localhost:2375 - DOCKER_DRIVER: overlay2 - GIT_STRATEGY: none + <<: *docker-build-vars PRODUCT: subkey - DOCKERFILE: $PRODUCT.Dockerfile - CONTAINER_IMAGE: parity/$PRODUCT after_script: - docker logout @@ -536,10 +646,12 @@ publish-s3-release: stage: publish <<: *build-only <<: *kubernetes-build - dependencies: - - build-linux-substrate - - build-linux-subkey - image: parity/awscli:latest + needs: + - job: build-linux-substrate + artifacts: true + - job: build-linux-subkey + artifacts: true + image: paritytech/awscli:latest variables: GIT_STRATEGY: none BUCKET: "releases.parity.io" @@ -555,11 +667,11 @@ publish-s3-release: publish-s3-doc: stage: publish - image: parity/awscli:latest + image: paritytech/awscli:latest allow_failure: true - dependencies: - - build-rust-doc-release - cache: {} + needs: + - job: build-rust-doc-release + artifacts: true <<: *build-only <<: *kubernetes-build variables: @@ -579,104 +691,64 @@ publish-s3-doc: publish-draft-release: stage: publish - image: parity/tools:latest + image: paritytech/tools:latest only: - - tags + - /^ci-release-.*$/ - /^v[0-9]+\.[0-9]+\.[0-9]+.*$/ script: - ./.maintain/gitlab/publish_draft_release.sh - interruptible: true allow_failure: true publish-to-crates-io: stage: publish <<: *docker-env + <<: *docker-env-only only: - - tags - /^ci-release-.*$/ + - /^v[0-9]+\.[0-9]+\.[0-9]+.*$/ script: - cargo install cargo-unleash ${CARGO_UNLEASH_INSTALL_PARAMS} - cargo unleash em-dragons --no-check ${CARGO_UNLEASH_PKG_DEF} - interruptible: true allow_failure: true -.deploy-template: &deploy - stage: kubernetes - when: manual + + +deploy-kubernetes-alerting-rules: + stage: deploy + interruptible: true retry: 1 - image: parity/kubetools:latest - <<: *build-only tags: - # this is the runner that is used to deploy it - kubernetes-parity-build - before_script: - - test -z "${DEPLOY_TAG}" && - test -f ./artifacts/substrate/VERSION && - DEPLOY_TAG="$(cat ./artifacts/substrate/VERSION)" - - test "${DEPLOY_TAG}" || ( echo "Neither DEPLOY_TAG nor VERSION information available"; exit 1 ) - script: - - echo "Substrate version = ${DEPLOY_TAG}" - # or use helm to render the template - - helm template - --values ./.maintain/kubernetes/values.yaml - --set image.tag=${DEPLOY_TAG} - --set validator.keys=${VALIDATOR_KEYS} - ./.maintain/kubernetes | kubectl apply -f - --dry-run=false - - echo "# substrate namespace ${KUBE_NAMESPACE}" - - kubectl -n ${KUBE_NAMESPACE} get all - - echo "# substrate's nodes' external ip addresses:" - - kubectl get nodes -l node=substrate - -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{range @.status.addresses[?(@.type=="ExternalIP")]}{.address}{"\n"}{end}' - - echo "# substrate' nodes" - - kubectl -n ${KUBE_NAMESPACE} get pods - -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}{end}' - - echo "# wait for the rollout to complete" - - kubectl -n ${KUBE_NAMESPACE} rollout status statefulset/substrate - -# have environment:url eventually point to the logs - -.deploy-cibuild: &deploy-cibuild - <<: *deploy - dependencies: - - publish-docker-substrate - -.deploy-tag: &deploy-tag - <<: *deploy - only: - variables: - - $DEPLOY_TAG - -# have environment:url eventually point to the logs - -deploy-ew3: - <<: *deploy-cibuild + image: paritytech/kubetools:latest environment: - name: parity-prod-ew3 - -deploy-ue1: - <<: *deploy-cibuild - environment: - name: parity-prod-ue1 + name: parity-mgmt-polkadot-alerting + variables: + NAMESPACE: monitoring + PROMETHEUSRULE: prometheus-k8s-rules-polkadot-alerting + RULES: .maintain/monitoring/alerting-rules/alerting-rules.yaml + script: + - echo "deploying prometheus alerting rules" + - kubectl -n ${NAMESPACE} patch prometheusrule ${PROMETHEUSRULE} + --type=merge --patch "$(sed 's/^/ /;1s/^/spec:\n/' ${RULES})" + only: + refs: + - master + changes: + - "${RULES}" -deploy-ew3-tag: - <<: *deploy-tag - environment: - name: parity-prod-ew3 -deploy-ue1-tag: - <<: *deploy-tag - environment: - name: parity-prod-ue1 .validator-deploy: &validator-deploy - # script will fail if there is no artifacts/substrate/VERSION <<: *build-only stage: flaming-fir - dependencies: - - build-linux-substrate + needs: + # script will fail if there is no artifacts/substrate/VERSION + - job: publish-docker-substrate + artifacts: true image: parity/azure-ansible:v1 allow_failure: true when: manual + interruptible: true tags: - linux-docker @@ -684,15 +756,29 @@ validator 1 4: <<: *validator-deploy script: - ./.maintain/flamingfir-deploy.sh flamingfir-validator1 + validator 2 4: <<: *validator-deploy script: - ./.maintain/flamingfir-deploy.sh flamingfir-validator2 + validator 3 4: <<: *validator-deploy script: - ./.maintain/flamingfir-deploy.sh flamingfir-validator3 + validator 4 4: <<: *validator-deploy script: - ./.maintain/flamingfir-deploy.sh flamingfir-validator4 + +#### stage: .post + +check-labels: + stage: .post + image: paritytech/tools:latest + <<: *kubernetes-build + only: + - /^[0-9]+$/ + script: + - ./.maintain/gitlab/check_labels.sh diff --git a/.maintain/chaostest/.eslintignore b/.maintain/chaostest/.eslintignore new file mode 100644 index 0000000000000000000000000000000000000000..3c3629e647f5ddf82548912e337bea9826b434af --- /dev/null +++ b/.maintain/chaostest/.eslintignore @@ -0,0 +1 @@ +node_modules diff --git a/.maintain/chaostest/.eslintrc.json b/.maintain/chaostest/.eslintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..43e483a80b2ea2d5809d4cdc659d2442445a7db8 --- /dev/null +++ b/.maintain/chaostest/.eslintrc.json @@ -0,0 +1,19 @@ +{ + "env": { + "node": true, + "commonjs": true, + "es6": true + }, + "extends": [ + "standard" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaVersion": 2018 + }, + "rules": { + } +} diff --git a/.maintain/chaostest/.gitignore b/.maintain/chaostest/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..ef9e9d1e696e4a55dae8ddba96512fd68ae5bced --- /dev/null +++ b/.maintain/chaostest/.gitignore @@ -0,0 +1,11 @@ +*-debug.log +*-error.log +/.nyc_output +/dist +/tmp +/log +.DS_Store +.editorconfig +yarn.lock +node_modules +/src/config/config.json diff --git a/.maintain/chaostest/README.md b/.maintain/chaostest/README.md new file mode 100644 index 0000000000000000000000000000000000000000..dc3d07b57905ef2e2639149be76f573574361941 --- /dev/null +++ b/.maintain/chaostest/README.md @@ -0,0 +1,89 @@ +chaostest +========= + +A cli for chaos testing on substrate + +[![oclif](https://img.shields.io/badge/cli-oclif-brightgreen.svg)](https://oclif.io) +[![Version](https://img.shields.io/npm/v/chaostest.svg)](https://npmjs.org/package/chaostest) +[![Downloads/week](https://img.shields.io/npm/dw/chaostest.svg)](https://npmjs.org/package/chaostest) + + +* [Usage](#usage) +* [Commands](#commands) + +# Usage + +```sh-session +$ npm install -g chaostest // yarn add global chaostest +$ chaostest COMMAND +running command... +$ chaostest (-v|--version|version) +chaostest/0.0.0 darwin-x64 node-v8.16.0 +$ chaostest --help [COMMAND] +USAGE + $ chaostest COMMAND +... +``` + +# Commands + +* [`chaostest spawn`](#chaostest-spawn) +* [`chaostest singlenodeheight`](#chaostest-singlenodeheight) +* [`chaostest clean`](#chaostest-clean) + +## `chaostest spawn` + +Spawn a testnet based on your local k8s configuration. Could be either a dev node, a two node alicebob chain or a customized chain with various validators/fullnodes. + +``` +USAGE + $ chaostest spawn [ARGUMENTS] [FLAGS] + +Arguments + dev, a single fullnode in --dev mode + alicebob, a two nodes private chain with Alice as bootnode and Bob as validator + [chainName], a customized chain deployed with -v numbers of validators and -n numbers of fullnodes + +Flags + --image, -i, the image tag of the certain substrate version you want to deploy + --port, -p, the port to expose when image is deployed in a pod + --namespace, the desired namespace to deploy on + --validator, -v, the number of substrate validators to deploy + --node, -n, the number of full nodes, if not set but exists, default to 1 + +DESCRIPTION + ... + Extra documentation goes here +``` + +_See code: [src/commands/spawn/index.js](https://github.com/paritytech/substrate/blob/harry/chaostest-init/.maintain/chaostest/src/commands/spawn/index.js)_ + +## `chaostest singlenodeheight` + +Test against a fullnode on --dev mode to check if it can successfully produce blocks to a certain height. + +``` +USAGE + $ chaostest singlenodeheight [FLAGS] + +FLAGS + -h , the desired height of blocks to check if reachable, this only works with integers smaller than 2^6 + -t, the wait time out before it halts the polling +``` + +_See code: [src/commands/singlenodeheight/index.js](https://github.com/paritytech/substrate/blob/harry/chaostest-init/.maintain/chaostest/src/commands/singlenodeheight/index.js)_ + +## `chaostest clean` + +Clean up the k8s deployment by namespace. + +``` +USAGE + $ chaostest clean [FLAGS] + +FLAGS + -n , the desired namespace to delete on your k8s cluster +``` + +_See code: [src/commands/clean/index.js](https://github.com/paritytech/substrate/blob/harry/chaostest-init/.maintain/chaostest/src/commands/clean/index.js)_ + diff --git a/.maintain/chaostest/bin/run b/.maintain/chaostest/bin/run new file mode 100755 index 0000000000000000000000000000000000000000..30b14e177331d199dc14f783a9f44a9daa697c4f --- /dev/null +++ b/.maintain/chaostest/bin/run @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +require('@oclif/command').run() +.then(require('@oclif/command/flush')) +.catch(require('@oclif/errors/handle')) diff --git a/.maintain/chaostest/bin/run.cmd b/.maintain/chaostest/bin/run.cmd new file mode 100644 index 0000000000000000000000000000000000000000..968fc30758e686d7c4a569f87580ccd310d0b152 --- /dev/null +++ b/.maintain/chaostest/bin/run.cmd @@ -0,0 +1,3 @@ +@echo off + +node "%~dp0\run" %* diff --git a/.maintain/chaostest/package-lock.json b/.maintain/chaostest/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..8855f221a133d14040312ce255bbf5ced3c27183 --- /dev/null +++ b/.maintain/chaostest/package-lock.json @@ -0,0 +1,5950 @@ +{ + "name": "chaostest", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true + }, + "@babel/runtime": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz", + "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@kubernetes/client-node": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.11.2.tgz", + "integrity": "sha512-Uhwd2y2qCvugICnHRC5h2MT5vw0a1dJPVVltVwmkeMuyGTPBccsTtpTcSfSLitwOrh4yr+9wG5bRcMdgeRjYPw==", + "requires": { + "@types/js-yaml": "^3.12.1", + "@types/node": "^10.12.0", + "@types/request": "^2.47.1", + "@types/underscore": "^1.8.9", + "@types/ws": "^6.0.1", + "byline": "^5.0.0", + "execa": "1.0.0", + "isomorphic-ws": "^4.0.1", + "js-yaml": "^3.13.1", + "jsonpath-plus": "^0.19.0", + "openid-client": "2.5.0", + "request": "^2.88.0", + "rfc4648": "^1.3.0", + "shelljs": "^0.8.2", + "tslib": "^1.9.3", + "underscore": "^1.9.1", + "ws": "^6.1.0" + }, + "dependencies": { + "jsonpath-plus": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-0.19.0.tgz", + "integrity": "sha512-GSVwsrzW9LsA5lzsqe4CkuZ9wp+kxBb2GwNniaWzI2YFn5Ig42rSW8ZxVpWXaAfakXNrx5pgY5AbQq7kzX29kg==" + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@oclif/command": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.6.1.tgz", + "integrity": "sha512-pvmMmfGn+zm4e4RwVw63mg9sIaqKqmVsFbImQoUrCO/43UmWzoSHWNXKdgEGigOezWrkZfFucaeZcSbp149OWg==", + "requires": { + "@oclif/config": "^1.15.1", + "@oclif/errors": "^1.2.2", + "@oclif/parser": "^3.8.3", + "@oclif/plugin-help": "^3", + "debug": "^4.1.1", + "semver": "^5.6.0" + }, + "dependencies": { + "@oclif/plugin-help": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-3.0.1.tgz", + "integrity": "sha512-Q1OITeUBkkydPf6r5qX75KgE9capr1mNrfHtfD7gkVXmqoTndrbc++z4KfAYNf5nhTCY7N9l52sjbF6BrSGu9w==", + "requires": { + "@oclif/command": "^1.5.20", + "@oclif/config": "^1.15.1", + "chalk": "^2.4.1", + "indent-string": "^4.0.0", + "lodash.template": "^4.4.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0", + "widest-line": "^2.0.1", + "wrap-ansi": "^4.0.0" + } + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "@oclif/config": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.15.1.tgz", + "integrity": "sha512-GdyHpEZuWlfU8GSaZoiywtfVBsPcfYn1KuSLT1JTfvZGpPG6vShcGr24YZ3HG2jXUFlIuAqDcYlTzOrqOdTPNQ==", + "requires": { + "@oclif/errors": "^1.0.0", + "@oclif/parser": "^3.8.0", + "debug": "^4.1.1", + "tslib": "^1.9.3" + } + }, + "@oclif/dev-cli": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@oclif/dev-cli/-/dev-cli-1.22.2.tgz", + "integrity": "sha512-c7633R37RxrQIpwqPKxjNRm6/jb1yuG8fd16hmNz9Nw+/MUhEtQtKHSCe9ScH8n5M06l6LEo4ldk9LEGtpaWwA==", + "dev": true, + "requires": { + "@oclif/command": "^1.5.13", + "@oclif/config": "^1.12.12", + "@oclif/errors": "^1.2.2", + "@oclif/plugin-help": "^2.1.6", + "cli-ux": "^5.2.1", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "github-slugger": "^1.2.1", + "lodash": "^4.17.11", + "normalize-package-data": "^2.5.0", + "qqjs": "^0.3.10", + "tslib": "^1.9.3" + } + }, + "@oclif/errors": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.2.2.tgz", + "integrity": "sha512-Eq8BFuJUQcbAPVofDxwdE0bL14inIiwt5EaKRVY9ZDIG11jwdXZqiQEECJx0VfnLyUZdYfRd/znDI/MytdJoKg==", + "requires": { + "clean-stack": "^1.3.0", + "fs-extra": "^7.0.0", + "indent-string": "^3.2.0", + "strip-ansi": "^5.0.0", + "wrap-ansi": "^4.0.0" + } + }, + "@oclif/linewrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", + "integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==" + }, + "@oclif/parser": { + "version": "3.8.5", + "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.8.5.tgz", + "integrity": "sha512-yojzeEfmSxjjkAvMRj0KzspXlMjCfBzNRPkWw8ZwOSoNWoJn+OCS/m/S+yfV6BvAM4u2lTzX9Y5rCbrFIgkJLg==", + "requires": { + "@oclif/errors": "^1.2.2", + "@oclif/linewrap": "^1.0.0", + "chalk": "^2.4.2", + "tslib": "^1.9.3" + } + }, + "@oclif/plugin-help": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-2.2.3.tgz", + "integrity": "sha512-bGHUdo5e7DjPJ0vTeRBMIrfqTRDBfyR5w0MP41u0n3r7YG5p14lvMmiCXxi6WDaP2Hw5nqx3PnkAIntCKZZN7g==", + "requires": { + "@oclif/command": "^1.5.13", + "chalk": "^2.4.1", + "indent-string": "^4.0.0", + "lodash.template": "^4.4.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0", + "widest-line": "^2.0.1", + "wrap-ansi": "^4.0.0" + }, + "dependencies": { + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "@oclif/screen": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-1.0.4.tgz", + "integrity": "sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw==", + "dev": true + }, + "@oclif/test": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@oclif/test/-/test-1.2.6.tgz", + "integrity": "sha512-8BQm0VFwTf/JpDnI3x6Lbp3S4RRUvQcv8WalKm82+7FNEylWMAXFNgBuzG65cNPj11J2jhlVo0gOWGF6hbiaJQ==", + "dev": true, + "requires": { + "fancy-test": "^1.4.3" + } + }, + "@polkadot/api": { + "version": "0.95.2", + "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-0.95.2.tgz", + "integrity": "sha512-SrYiEE9T+AmCx18NyhEk5l/7yPvVqogiz7rmW8YGlOZ89OEPHe2dOTaD5tZJ5daKXEkXFsqPPtwemCv2OZ2F1g==", + "requires": { + "@babel/runtime": "^7.6.3", + "@polkadot/api-derive": "^0.95.2", + "@polkadot/api-metadata": "^0.95.2", + "@polkadot/keyring": "^1.6.1", + "@polkadot/rpc-core": "^0.95.2", + "@polkadot/rpc-provider": "^0.95.2", + "@polkadot/types": "^0.95.2", + "@polkadot/util-crypto": "^1.6.1" + } + }, + "@polkadot/api-derive": { + "version": "0.95.2", + "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-0.95.2.tgz", + "integrity": "sha512-IScOMoUnrs/TCPk2zZZWUfw1EfV718HuFbIRFVg11PiG/uYQ+knNpr9cG/auRWelDMO0ef7eI+YOpf9+gV3EZw==", + "requires": { + "@babel/runtime": "^7.6.3", + "@polkadot/api": "^0.95.2", + "@polkadot/types": "^0.95.2" + } + }, + "@polkadot/api-metadata": { + "version": "0.95.2", + "resolved": "https://registry.npmjs.org/@polkadot/api-metadata/-/api-metadata-0.95.2.tgz", + "integrity": "sha512-RyHr6o8Qdi0k1cTJj11AqZ3MFoPbqUK37RMpFH8vK6VHlZRlpqaZsCctWMEiOXQC2CtTnE5CIoQH11AKeIK+jw==", + "requires": { + "@babel/runtime": "^7.6.3", + "@polkadot/types": "^0.95.2", + "@polkadot/util": "^1.6.1", + "@polkadot/util-crypto": "^1.6.1" + } + }, + "@polkadot/jsonrpc": { + "version": "0.95.2", + "resolved": "https://registry.npmjs.org/@polkadot/jsonrpc/-/jsonrpc-0.95.2.tgz", + "integrity": "sha512-U8cx5MuhWPRcuosSHv/Qw4OmlgSk410oTQtYvHAFDoHuPDcYXTBcCJ0e31cCZFBkaed+GTelkex9EPnHFi0x1g==", + "requires": { + "@babel/runtime": "^7.6.3" + } + }, + "@polkadot/keyring": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-1.8.1.tgz", + "integrity": "sha512-KeDbfP8biY3bXEhMv1ANp9d3kCuXj2oxseuDK0jvxRo7CehVME9UwAMGQK3Y9NCUuYWd+xTO2To0ZOqR7hdmuQ==", + "requires": { + "@babel/runtime": "^7.7.7", + "@polkadot/util": "^1.8.1", + "@polkadot/util-crypto": "^1.8.1" + } + }, + "@polkadot/rpc-core": { + "version": "0.95.2", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-0.95.2.tgz", + "integrity": "sha512-IjuzYfNSBWalzingkvpGdO9lZH6s5wFc5lWCINFDP/MSlnLfKzufzR0JeSiVCluraoohtUB/INVuBujDziZPzg==", + "requires": { + "@babel/runtime": "^7.6.3", + "@polkadot/jsonrpc": "^0.95.2", + "@polkadot/rpc-provider": "^0.95.2", + "@polkadot/types": "^0.95.2", + "@polkadot/util": "^1.6.1", + "rxjs": "^6.5.3" + } + }, + "@polkadot/rpc-provider": { + "version": "0.95.2", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-0.95.2.tgz", + "integrity": "sha512-+vSoI9mdHPnjL7jK666+HLJ21Ymxo8GHdO72mI1A3xGO7wBmjKbUMHEYUtRwxg7DGF4mSZ/HJogoSU4i9smzpw==", + "requires": { + "@babel/runtime": "^7.6.3", + "@polkadot/api-metadata": "^0.95.2", + "@polkadot/util": "^1.6.1", + "@polkadot/util-crypto": "^1.6.1", + "@types/nock": "^11.1.0", + "eventemitter3": "^4.0.0", + "isomorphic-fetch": "^2.2.1", + "websocket": "^1.0.30" + } + }, + "@polkadot/types": { + "version": "0.95.2", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-0.95.2.tgz", + "integrity": "sha512-YiZbLgJ82rmgwbsYWEL8vtYqO1n1xEPxD5C8D0dmZQcwn9iSUibIqeij1xfd8y2ZyUmMW3YhdoJR6a8Ah6g3yw==", + "requires": { + "@babel/runtime": "^7.6.3", + "@polkadot/util": "^1.6.1", + "@polkadot/util-crypto": "^1.6.1", + "@types/memoizee": "^0.4.3", + "memoizee": "^0.4.14" + } + }, + "@polkadot/util": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-1.8.1.tgz", + "integrity": "sha512-sFpr+JLCG9d+epjboXsmJ1qcKa96r8ZYzXmVo8+aPzI/9jKKyez6Unox/dnfnpKppZB2nJuLcsxQm6nocp2Caw==", + "requires": { + "@babel/runtime": "^7.7.7", + "@types/bn.js": "^4.11.6", + "bn.js": "^4.11.8", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "ip-regex": "^4.1.0", + "moment": "^2.24.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@polkadot/util-crypto": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-1.8.1.tgz", + "integrity": "sha512-ypUs10hV1HPvYc0ZsEu+LTGSEh0rkr0as/FUh7+Z9v3Bxibn3aO+EOxJPQuDbZZ59FSMRmc9SeOSa0wn9ddrnw==", + "requires": { + "@babel/runtime": "^7.7.7", + "@polkadot/util": "^1.8.1", + "@polkadot/wasm-crypto": "^0.14.1", + "@types/bip39": "^2.4.2", + "@types/bs58": "^4.0.0", + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^3.5.0", + "@types/xxhashjs": "^0.2.1", + "base-x": "3.0.5", + "bip39": "^2.5.0", + "blakejs": "^1.1.0", + "bs58": "^4.0.1", + "js-sha3": "^0.8.0", + "secp256k1": "^3.8.0", + "tweetnacl": "^1.0.1", + "xxhashjs": "^0.2.2" + }, + "dependencies": { + "secp256k1": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", + "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", + "requires": { + "bindings": "^1.5.0", + "bip66": "^1.1.5", + "bn.js": "^4.11.8", + "create-hash": "^1.2.0", + "drbg.js": "^1.0.1", + "elliptic": "^6.5.2", + "nan": "^2.14.0", + "safe-buffer": "^5.1.2" + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + } + } + }, + "@polkadot/wasm-crypto": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-0.14.1.tgz", + "integrity": "sha512-Xng7L2Z8TNZa/5g6pot4O06Jf0ohQRZdvfl8eQL+E/L2mcqJYC1IjkMxJBSBuQEV7hisWzh9mHOy5WCcgPk29Q==" + }, + "@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==" + }, + "@types/bip39": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/bip39/-/bip39-2.4.2.tgz", + "integrity": "sha512-Vo9lqOIRq8uoIzEVrV87ZvcIM0PN9t0K3oYZ/CS61fIYKCBdOIM7mlWzXuRvSXrDtVa1uUO2w1cdfufxTC0bzg==", + "requires": { + "@types/node": "*" + } + }, + "@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "requires": { + "@types/node": "*" + } + }, + "@types/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-yfAgiWgVLjFCmRv8zAcOIHywYATEwiTVccTLnRp6UxTNavT55M9d/uhK3T03St/+8/z/wW+CRjGKUNmEqoHHCA==", + "requires": { + "base-x": "^3.0.6" + }, + "dependencies": { + "base-x": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", + "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", + "requires": { + "safe-buffer": "^5.0.1" + } + } + } + }, + "@types/caseless": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", + "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" + }, + "@types/chai": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", + "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==", + "dev": true + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/js-yaml": { + "version": "3.12.4", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.4.tgz", + "integrity": "sha512-fYMgzN+9e28R81weVN49inn/u798ruU91En1ZnGvSZzCRc5jXx9B2EDhlRaWmcO1RIxFHL8AajRXzxDuJu93+A==" + }, + "@types/lodash": { + "version": "4.14.152", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.152.tgz", + "integrity": "sha512-Vwf9YF2x1GE3WNeUMjT5bTHa2DqgUo87ocdgTScupY2JclZ5Nn7W2RLM/N0+oreexUk8uaVugR81NnTY/jNNXg==", + "dev": true + }, + "@types/memoizee": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@types/memoizee/-/memoizee-0.4.4.tgz", + "integrity": "sha512-c9+1g6+6vEqcw5UuM0RbfQV0mssmZcoG9+hNC5ptDCsv4G+XJW1Z4pE13wV5zbc9e0+YrDydALBTiD3nWG1a3g==" + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/mocha": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", + "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", + "dev": true + }, + "@types/nock": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@types/nock/-/nock-11.1.0.tgz", + "integrity": "sha512-jI/ewavBQ7X5178262JQR0ewicPAcJhXS/iFaNJl0VHLfyosZ/kwSrsa6VNQNSO8i9d8SqdRgOtZSOKJ/+iNMw==", + "requires": { + "nock": "*" + } + }, + "@types/node": { + "version": "10.17.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.24.tgz", + "integrity": "sha512-5SCfvCxV74kzR3uWgTYiGxrd69TbT1I6+cMx1A5kEly/IVveJBimtAMlXiEyVFn5DvUFewQWxOOiJhlxeQwxgA==" + }, + "@types/pbkdf2": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.0.0.tgz", + "integrity": "sha512-6J6MHaAlBJC/eVMy9jOwj9oHaprfutukfW/Dyt0NEnpQ/6HN6YQrpvLwzWdWDeWZIdenjGHlbYDzyEODO5Z+2Q==", + "requires": { + "@types/node": "*" + } + }, + "@types/request": { + "version": "2.48.5", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.5.tgz", + "integrity": "sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ==", + "requires": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "@types/secp256k1": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-3.5.3.tgz", + "integrity": "sha512-NGcsPDR0P+Q71O63e2ayshmiZGAwCOa/cLJzOIuhOiDvmbvrCIiVtEpqdCJGogG92Bnr6tw/6lqVBsRMEl15OQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/sinon": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.4.tgz", + "integrity": "sha512-sJmb32asJZY6Z2u09bl0G2wglSxDlROlAejCjsnor+LzBMz17gu8IU7vKC/vWDnv9zEq2wqADHVXFjf4eE8Gdw==", + "dev": true, + "requires": { + "@types/sinonjs__fake-timers": "*" + } + }, + "@types/sinonjs__fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz", + "integrity": "sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA==", + "dev": true + }, + "@types/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==" + }, + "@types/underscore": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.10.0.tgz", + "integrity": "sha512-ZAbqul7QAKpM2h1PFGa5ETN27ulmqtj0QviYHasw9LffvXZvVHuraOx/FOsIPPDNGZN0Qo1nASxxSfMYOtSoCw==" + }, + "@types/ws": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", + "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", + "requires": { + "@types/node": "*" + } + }, + "@types/xxhashjs": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@types/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-+hlk/W1kgnZn0vR22XNhxHk/qIRQYF54i0UTF2MwBAPd0e7xSy+jKOJwSwTdRQrNnOMRVv+vsh8ITV0uyhp2yg==", + "requires": { + "@types/node": "*" + } + }, + "acorn": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", + "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "dev": true + }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, + "aggregate-error": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-1.0.0.tgz", + "integrity": "sha1-iINE2tAiCnLjr1CQYRf0h3GSX6w=", + "requires": { + "clean-stack": "^1.0.0", + "indent-string": "^3.0.0" + } + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + } + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base-x": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.5.tgz", + "integrity": "sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" + }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bip39": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.6.0.tgz", + "integrity": "sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg==", + "requires": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", + "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "blakejs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", + "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" + }, + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "requires": { + "pako": "~1.0.5" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=" + }, + "cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "requires": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" + } + } + }, + "caching-transform": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", + "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^2.0.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.4.2" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + } + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", + "dev": true, + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "clean-stack": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz", + "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-progress": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.8.2.tgz", + "integrity": "sha512-qRwBxLldMSfxB+YGFgNRaj5vyyHe1yMpVeDL79c+7puGujdKJHQHydgqXDcrkvQgJ5U/d3lpf6vffSoVVUftVQ==", + "dev": true, + "requires": { + "colors": "^1.1.2", + "string-width": "^4.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "cli-ux": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/cli-ux/-/cli-ux-5.4.6.tgz", + "integrity": "sha512-EeiS2TzEndRVknCqE+8Ri8g0bsP617a1nq6n+3Trwft1JCDzyUNlX2J1fl7fwTgRPWtmBmiF6xIyueL5YGs65g==", + "dev": true, + "requires": { + "@oclif/command": "^1.6.0", + "@oclif/errors": "^1.2.1", + "@oclif/linewrap": "^1.0.0", + "@oclif/screen": "^1.0.3", + "ansi-escapes": "^4.3.0", + "ansi-styles": "^4.2.0", + "cardinal": "^2.1.1", + "chalk": "^2.4.1", + "clean-stack": "^2.0.0", + "cli-progress": "^3.4.0", + "extract-stack": "^1.0.0", + "fs-extra": "^7.0.1", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^1.1.0", + "js-yaml": "^3.13.1", + "lodash": "^4.17.11", + "natural-orderby": "^2.0.1", + "object-treeify": "^1.1.4", + "password-prompt": "^1.1.2", + "semver": "^5.6.0", + "string-width": "^3.1.0", + "strip-ansi": "^5.1.0", + "supports-color": "^5.5.0", + "supports-hyperlinks": "^1.0.1", + "tslib": "^1.9.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + } + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "color": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colornames": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", + "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "requires": { + "color": "3.0.x", + "text-hex": "1.0.x" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cp-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", + "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^2.0.0", + "nested-error-stacks": "^2.0.0", + "pify": "^4.0.1", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=" + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", + "dev": true + }, + "diagnostics": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", + "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", + "requires": { + "colorspace": "1.1.x", + "enabled": "1.0.x", + "kuler": "1.0.x" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "drbg.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", + "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", + "requires": { + "browserify-aes": "^1.0.6", + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, + "enabled": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", + "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", + "requires": { + "env-variable": "0.0.x" + } + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "env-variable": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.6.tgz", + "integrity": "sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + }, + "dependencies": { + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + } + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.1.0.tgz", + "integrity": "sha512-DfS3b8iHMK5z/YLSme8K5cge168I8j8o1uiVmFCgnnjxZQbCGyraF8bMl7Ju4yfBmCuxD7shOF7eqGkcuIHfsA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0", + "eslint-visitor-keys": "^1.1.0", + "espree": "^7.0.0", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "eslint-ast-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz", + "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==", + "dev": true, + "requires": { + "lodash.get": "^4.4.2", + "lodash.zip": "^4.2.0" + } + }, + "eslint-config-oclif": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-3.1.0.tgz", + "integrity": "sha512-Tqgy43cNXsSdhTLWW4RuDYGFhV240sC4ISSv/ZiUEg/zFxExSEUpRE6J+AGnkKY9dYwIW4C9b2YSUVv8z/miMA==", + "dev": true, + "requires": { + "eslint-config-xo-space": "^0.20.0", + "eslint-plugin-mocha": "^5.2.0", + "eslint-plugin-node": "^7.0.1", + "eslint-plugin-unicorn": "^6.0.1" + }, + "dependencies": { + "eslint-plugin-es": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.1.tgz", + "integrity": "sha512-5fa/gR2yR3NxQf+UXkeLeP8FBBl6tSgdrAz1+cF84v1FMM4twGwQoqTnn+QxFLcPOrF4pdKEJKDB/q9GoyJrCA==", + "dev": true, + "requires": { + "eslint-utils": "^1.4.2", + "regexpp": "^2.0.1" + } + }, + "eslint-plugin-node": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz", + "integrity": "sha512-lfVw3TEqThwq0j2Ba/Ckn2ABdwmL5dkOgAux1rvOk6CO7A6yGyPI2+zIxN6FyNkp1X1X/BSvKOceD6mBWSj4Yw==", + "dev": true, + "requires": { + "eslint-plugin-es": "^1.3.1", + "eslint-utils": "^1.3.1", + "ignore": "^4.0.2", + "minimatch": "^3.0.4", + "resolve": "^1.8.1", + "semver": "^5.5.0" + } + }, + "eslint-plugin-unicorn": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-6.0.1.tgz", + "integrity": "sha512-hjy9LhTdtL7pz8WTrzS0CGXRkWK3VAPLDjihofj8JC+uxQLfXm0WwZPPPB7xKmcjRyoH+jruPHOCrHNEINpG/Q==", + "dev": true, + "requires": { + "clean-regexp": "^1.0.0", + "eslint-ast-utils": "^1.0.0", + "import-modules": "^1.1.0", + "lodash.camelcase": "^4.1.1", + "lodash.kebabcase": "^4.0.1", + "lodash.snakecase": "^4.0.1", + "lodash.upperfirst": "^4.2.0", + "safe-regex": "^1.1.0" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + } + } + }, + "eslint-config-standard": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", + "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", + "dev": true + }, + "eslint-config-xo": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.24.2.tgz", + "integrity": "sha512-ivQ7qISScW6gfBp+p31nQntz1rg34UCybd3uvlngcxt5Utsf4PMMi9QoAluLFcPUM5Tvqk4JGraR9qu3msKPKQ==", + "dev": true + }, + "eslint-config-xo-space": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/eslint-config-xo-space/-/eslint-config-xo-space-0.20.0.tgz", + "integrity": "sha512-bOsoZA8M6v1HviDUIGVq1fLVnSu3mMZzn85m2tqKb73tSzu4GKD4Jd2Py4ZKjCgvCbRRByEB5HPC3fTMnnJ1uw==", + "dev": true, + "requires": { + "eslint-config-xo": "^0.24.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.20.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz", + "integrity": "sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "eslint-plugin-mocha": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-5.3.0.tgz", + "integrity": "sha512-3uwlJVLijjEmBeNyH60nzqgA1gacUWLUmcKV8PIGNvj1kwP/CTgAWQHn2ayyJVwziX+KETkr9opNwT1qD/RZ5A==", + "dev": true, + "requires": { + "ramda": "^0.26.1" + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-promise": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", + "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", + "dev": true + }, + "eslint-plugin-standard": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz", + "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==", + "dev": true + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.0.0.tgz", + "integrity": "sha512-/r2XEx5Mw4pgKdyb7GNLQNsu++asx/dltf/CI8RFi9oGHxmQFgvLbc5Op4U6i8Oaj+kdslhJtVlEZeAqH5qOTw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", + "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==" + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + } + } + }, + "extract-stack": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/extract-stack/-/extract-stack-1.0.0.tgz", + "integrity": "sha1-uXrK+UQe6iMyUpYktzL8WhyBZfo=", + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fancy-test": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/fancy-test/-/fancy-test-1.4.8.tgz", + "integrity": "sha512-/uCv78YSAz4UOQ3ZptnxOq6qYhJDMtwFHQnsghzGl2g6uO2VNfJDKlyczqFpG+KueXe7phoeIS6hMU1x/qhizQ==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/lodash": "*", + "@types/mocha": "*", + "@types/node": "*", + "@types/sinon": "*", + "lodash": "^4.17.13", + "mock-stdin": "^0.3.1", + "stdout-stderr": "^0.1.9" + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" + }, + "fast-glob": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", + "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" + }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fecha": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "foreground-child": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "github-slugger": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.3.0.tgz", + "integrity": "sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q==", + "dev": true, + "requires": { + "emoji-regex": ">=6.0.0 <=6.1.1" + }, + "dependencies": { + "emoji-regex": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", + "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", + "dev": true + } + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "requires": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + } + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hasha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==" + }, + "http-call": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/http-call/-/http-call-5.3.0.tgz", + "integrity": "sha512-ahwimsC23ICE4kPl9xTBjKB4inbRaeLyZeRunC/1Jy/Z6X8tv22MEAjK+KBOMSVLaqXPTTmd8638waVIKLGx2w==", + "dev": true, + "requires": { + "content-type": "^1.0.4", + "debug": "^4.1.1", + "is-retry-allowed": "^1.1.0", + "is-stream": "^2.0.0", + "parse-json": "^4.0.0", + "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "hyperlinker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", + "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-1.1.0.tgz", + "integrity": "sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "inquirer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" + }, + "into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "requires": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + } + }, + "ip-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.1.0.tgz", + "integrity": "sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA==" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", + "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0" + } + }, + "isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "requires": { + "json-buffer": "3.0.0" + } + }, + "kuler": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", + "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", + "requires": { + "colornames": "^1.1.1" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "load-json-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", + "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^5.0.0", + "strip-bom": "^4.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", + "dev": true + }, + "lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=", + "dev": true + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=", + "dev": true + }, + "lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", + "dev": true + }, + "logform": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz", + "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==", + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^2.3.3", + "ms": "^2.1.1", + "triple-beam": "^1.3.0" + } + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "requires": { + "es5-ext": "~0.10.2" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "memoizee": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", + "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", + "requires": { + "d": "1", + "es5-ext": "^0.10.45", + "es6-weak-map": "^2.0.2", + "event-emitter": "^0.3.5", + "is-promise": "^2.1", + "lru-queue": "0.1", + "next-tick": "1", + "timers-ext": "^0.1.5" + } + }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "merge2": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "mock-stdin": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/mock-stdin/-/mock-stdin-0.3.1.tgz", + "integrity": "sha1-xlfZZC2QeGQ1xkyl6Zu9TQm9fdM=", + "dev": true + }, + "moment": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", + "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nan": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", + "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "natural-orderby": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", + "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", + "dev": true + }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", + "dev": true + }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "nock": { + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/nock/-/nock-12.0.3.tgz", + "integrity": "sha512-QNb/j8kbFnKCiyqi9C5DD0jH/FubFGj5rt9NQFONXwQm3IPB0CULECg/eS3AU1KgZb/6SwUa4/DTRKhVxkGABw==", + "requires": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.13", + "propagate": "^2.0.0" + } + }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + }, + "node-forge": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.5.tgz", + "integrity": "sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q==" + }, + "node-jose": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-1.1.4.tgz", + "integrity": "sha512-L31IFwL3pWWcMHxxidCY51ezqrDXMkvlT/5pLTfNw5sXmmOLJuN6ug7txzF/iuZN55cRpyOmoJrotwBQIoo5Lw==", + "requires": { + "base64url": "^3.0.1", + "browserify-zlib": "^0.2.0", + "buffer": "^5.5.0", + "es6-promise": "^4.2.8", + "lodash": "^4.17.15", + "long": "^4.0.0", + "node-forge": "^0.8.5", + "process": "^0.11.10", + "react-zlib-js": "^1.0.4", + "uuid": "^3.3.3" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "requires": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "nyc": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", + "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "caching-transform": "^3.0.2", + "convert-source-map": "^1.6.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.2.3", + "uuid": "^3.3.2", + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==" + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-treeify": { + "version": "1.1.24", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.24.tgz", + "integrity": "sha512-ttlIN3MoqnhevarRtDNELvNjQ85Wguq2zSkR2N9DGFM3pFWMjsz7tSqbjX7lx16BmFwLOwBa3w0TY1jJajklFg==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "oidc-token-hash": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-3.0.2.tgz", + "integrity": "sha512-dTzp80/y/da+um+i+sOucNqiPpwRL7M/xPwj7pH1TFA2/bqQ+OK2sJahSXbemEoLtPkHcFLyhLhLWZa9yW5+RA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "one-time": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", + "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "openid-client": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-2.5.0.tgz", + "integrity": "sha512-t3hFD7xEoW1U25RyBcRFaL19fGGs6hNVTysq9pgmiltH0IVUPzH/bQV9w24pM5Q7MunnGv2/5XjIru6BQcWdxg==", + "requires": { + "base64url": "^3.0.0", + "got": "^8.3.2", + "lodash": "^4.17.11", + "lru-cache": "^5.1.1", + "node-jose": "^1.1.0", + "object-hash": "^1.3.1", + "oidc-token-hash": "^3.0.1", + "p-any": "^1.1.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-any": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-any/-/p-any-1.1.0.tgz", + "integrity": "sha512-Ef0tVa4CZ5pTAmKn+Cg3w8ABBXh+hHO1aV8281dKOoUHfX+3tjG2EaFcC+aZyagg9b4EYGsHEjz21DnEE8Og2g==", + "requires": { + "p-some": "^2.0.0" + } + }, + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=" + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-some": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-some/-/p-some-2.0.1.tgz", + "integrity": "sha1-Zdh8ixVO289SIdFnd4ttLhUPbwY=", + "requires": { + "aggregate-error": "^1.0.0" + } + }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "requires": { + "p-finally": "^1.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "password-prompt": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.2.tgz", + "integrity": "sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.1.0", + "cross-spawn": "^6.0.5" + }, + "dependencies": { + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + } + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qqjs": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/qqjs/-/qqjs-0.3.11.tgz", + "integrity": "sha512-pB2X5AduTl78J+xRSxQiEmga1jQV0j43jOPs/MTgTLApGFEOn6NgdE2dEjp7nvDtjkIOZbvFIojAiYUx6ep3zg==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "debug": "^4.1.1", + "execa": "^0.10.0", + "fs-extra": "^6.0.1", + "get-stream": "^5.1.0", + "glob": "^7.1.2", + "globby": "^10.0.1", + "http-call": "^5.1.2", + "load-json-file": "^6.2.0", + "pkg-dir": "^4.2.0", + "tar-fs": "^2.0.0", + "tmp": "^0.1.0", + "write-json-file": "^4.1.1" + }, + "dependencies": { + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } + } + }, + "fs-extra": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", + "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "ramda": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz", + "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "react-zlib-js": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/react-zlib-js/-/react-zlib-js-1.0.4.tgz", + "integrity": "sha512-ynXD9DFxpE7vtGoa3ZwBtPmZrkZYw2plzHGbanUjBOSN4RtuXdektSfABykHtTiWEHMh7WdYj45LHtp228ZF1A==" + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", + "dev": true, + "requires": { + "esprima": "~4.0.0" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rfc4648": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfc4648/-/rfc4648-1.3.0.tgz", + "integrity": "sha512-x36K12jOflpm1V8QjPq3I+pt7Z1xzeZIjiC8J2Oxd7bE1efTrOG241DTYVJByP/SxR9jl1t7iZqYxDX864jgBQ==" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "shelljs": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", + "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "spawn-wrap": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", + "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, + "stdout-stderr": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/stdout-stderr/-/stdout-stderr-0.1.13.tgz", + "integrity": "sha512-Xnt9/HHHYfjZ7NeQLvuQDyL1LnbsbddgMFKCuaQKwGCdJm8LnstZIXop+uOY36UR1UXXoHXfMbC1KlVdVd2JLA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + } + }, + "string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-json-comments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", + "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-hyperlinks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz", + "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==", + "dev": true, + "requires": { + "has-flag": "^2.0.0", + "supports-color": "^5.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + } + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "tar-fs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz", + "integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "tar-stream": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", + "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", + "dev": true, + "requires": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + } + }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + }, + "timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "requires": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, + "tmp": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", + "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "dev": true, + "requires": { + "rimraf": "^2.6.3" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "underscore": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", + "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + } + }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "websocket": { + "version": "1.0.31", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.31.tgz", + "integrity": "sha512-VAouplvGKPiKFDTeCCO65vYHsyay8DqoBSlzIO3fayrfOgU94lQN5a1uWVnFrMLceTJw/+fQXR5PGbUVRaHshQ==", + "requires": { + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "nan": "^2.14.0", + "typedarray-to-buffer": "^3.1.5", + "yaeti": "^0.0.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "whatwg-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", + "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "requires": { + "string-width": "^2.1.1" + } + }, + "winston": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz", + "integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==", + "requires": { + "async": "^2.6.1", + "diagnostics": "^1.1.1", + "is-stream": "^1.1.0", + "logform": "^2.1.1", + "one-time": "0.0.4", + "readable-stream": "^3.1.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.3.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "winston-transport": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", + "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", + "requires": { + "readable-stream": "^2.3.6", + "triple-beam": "^1.2.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-4.0.0.tgz", + "integrity": "sha512-uMTsj9rDb0/7kk1PbcbCcwvHUxp60fGDB/NNXpVa0Q+ic/e7y5+BwTxKfQ33VYgDppSwi/FBzpetYzo8s6tfbg==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "write-json-file": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-4.3.0.tgz", + "integrity": "sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ==", + "dev": true, + "requires": { + "detect-indent": "^6.0.0", + "graceful-fs": "^4.1.15", + "is-plain-obj": "^2.0.0", + "make-dir": "^3.0.0", + "sort-keys": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "sort-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-4.0.0.tgz", + "integrity": "sha512-hlJLzrn/VN49uyNkZ8+9b+0q9DjmmYcYOnbMQtpkLrYpPwRApDPZfmqbUfJnAA3sb/nRib+nDot7Zi/1ER1fuA==", + "dev": true, + "requires": { + "is-plain-obj": "^2.0.0" + } + } + } + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xxhashjs": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", + "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", + "requires": { + "cuint": "^0.2.2" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/.maintain/chaostest/package.json b/.maintain/chaostest/package.json new file mode 100644 index 0000000000000000000000000000000000000000..b659f751811130eae4ee951b10020c9577bdeb93 --- /dev/null +++ b/.maintain/chaostest/package.json @@ -0,0 +1,61 @@ +{ + "name": "chaostest", + "description": "A cli for chaos testing on substrate", + "version": "0.0.0", + "author": "HarryHong", + "bin": { + "chaostest": "./bin/run" + }, + "bugs": "https://github.com/paritytech/substrate/issues", + "dependencies": { + "@kubernetes/client-node": "^0.11.1", + "@oclif/command": "^1", + "@oclif/config": "^1", + "@oclif/plugin-help": "^2", + "@polkadot/api": "^0.95.0-beta.14", + "@polkadot/keyring": "^1.6.0-beta.9", + "winston": "^3.2.1" + }, + "devDependencies": { + "@oclif/dev-cli": "^1", + "@oclif/test": "^1", + "chai": "^4", + "eslint": "^7.1.0", + "eslint-config-oclif": "^3.1", + "eslint-config-standard": "^14.1.1", + "eslint-plugin-import": "^2.20.2", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^4.0.1", + "globby": "^10", + "nyc": "^14" + }, + "engines": { + "node": ">=8.0.0" + }, + "files": [ + "/bin", + "/npm-shrinkwrap.json", + "/oclif.manifest.json", + "/src" + ], + "homepage": "https://github.com/paritytech/substrate/tree/master/.maintain/chaostest", + "keywords": [ + "oclif" + ], + "main": "src/index.js", + "oclif": { + "commands": "./src/commands", + "bin": "chaostest", + "plugins": [ + "@oclif/plugin-help" + ] + }, + "repository": "https://github.com/paritytech/substrate/tree/master/.maintain/chaostest", + "scripts": { + "postpack": "rm -f oclif.manifest.json", + "posttest": "eslint .", + "prepack": "oclif-dev manifest && oclif-dev readme", + "version": "oclif-dev readme && git add README.md" + } +} diff --git a/.maintain/chaostest/src/commands/clean/index.js b/.maintain/chaostest/src/commands/clean/index.js new file mode 100644 index 0000000000000000000000000000000000000000..9f8f5b95f8978374ed13ee37bb1d2a022519f306 --- /dev/null +++ b/.maintain/chaostest/src/commands/clean/index.js @@ -0,0 +1,31 @@ +const { Command, flags } = require('@oclif/command') +const CONFIG = require('../../config')() +const logger = require('../../utils/logger') +const Hypervisor = require('../../hypervisor') + +class CleanCommand extends Command { + async run () { + const { flags } = this.parse(CleanCommand) + const namespace = flags.namespace || CONFIG.namespace + const hypervisor = new Hypervisor(CONFIG) + // Delete corresponding namespace, default to CONFIG.namespace + try { + if (namespace) { + await hypervisor.cleanup(namespace) + } else { + logger.debug('Nothing to clean up') + } + } catch (error) { + logger.error(error) + process.exit(1) + } + } +} + +CleanCommand.description = 'Clean up resources based on namespace' + +CleanCommand.flags = { + namespace: flags.string({ char: 'n', description: 'desired namespace to clean up', env: 'NAMESPACE' }) +} + +module.exports = CleanCommand diff --git a/.maintain/chaostest/src/commands/singlenodeheight/index.js b/.maintain/chaostest/src/commands/singlenodeheight/index.js new file mode 100644 index 0000000000000000000000000000000000000000..05006d745b4e2bf554a6cfce1efe924ba338daf9 --- /dev/null +++ b/.maintain/chaostest/src/commands/singlenodeheight/index.js @@ -0,0 +1,63 @@ +const { Command, flags } = require('@oclif/command') +const CONFIG = require('../../config')() +const { succeedExit, errorExit } = require('../../utils/exit') +const Hypervisor = require('../../hypervisor') +const logger = require('../../utils/logger') + +class SingleNodeHeightCommand extends Command { + async run () { + const { flags } = this.parse(SingleNodeHeightCommand) + let port = flags.port + let url = flags.url + const wait = flags.wait || 600 * 1000 + const height = flags.height || 10 + const namespace = flags.namespace || CONFIG.namespace + const pod = flags.pod || (CONFIG.nodes && CONFIG.nodes[0]) ? CONFIG.nodes[0].podName : undefined + const now = Date.now() + + const hypervisor = new Hypervisor(CONFIG) + if (!!url && !!port) { + JsonRpcCallTestHeight(url, port) + } else if (!!pod && !!namespace) { + url = 'http://127.0.0.1' + port = 9933 + await hypervisor.startForwardServer(namespace, pod, port) + JsonRpcCallTestHeight(url, port) + } else { + errorExit('Not enough parameters provided. Either specify url and port or pod and namespace.') + } + + async function JsonRpcCallTestHeight (url, port) { + logger.debug('Polling chain height...') + if (Date.now() < now + wait) { + try { + const curHeight = await hypervisor.getChainBlockHeight(url, port) + logger.debug('Current Block Height: ' + curHeight) + if (curHeight > height) { + logger.info(`Single dev node Blockheight reached ${height}`) + succeedExit() + } else { + setTimeout(() => JsonRpcCallTestHeight(url, port), 2000) + } + } catch (error) { + errorExit('Error requesting chain block height', error) + } + } else { + errorExit('Timed out') + } + } + } +} + +SingleNodeHeightCommand.description = 'Test if targeted node is producing blocks > certain height' + +SingleNodeHeightCommand.flags = { + port: flags.integer({ char: 'p', description: 'port to deploy' }), + url: flags.string({ char: 'u', description: 'connect url' }), + timeout: flags.string({ char: 't', description: 'wait time in miliseconds to halt' }), + height: flags.string({ char: 'h', description: 'desired height to test' }), + pod: flags.string({ description: 'desired pod to test' }), + namespace: flags.string({ description: 'desired namespace to test' }) +} + +module.exports = SingleNodeHeightCommand diff --git a/.maintain/chaostest/src/commands/spawn/index.js b/.maintain/chaostest/src/commands/spawn/index.js new file mode 100644 index 0000000000000000000000000000000000000000..785037b029536203185f762a2565b88b8ab64735 --- /dev/null +++ b/.maintain/chaostest/src/commands/spawn/index.js @@ -0,0 +1,52 @@ +const { Command, flags } = require('@oclif/command') +const logger = require('../../utils/logger') +const Hypervisor = require('../../hypervisor') +const CONFIG = require('../../config')() + +class SpawnCommand extends Command { + async run () { + const { flags } = this.parse(SpawnCommand) + const { args } = this.parse(SpawnCommand) + const imageTag = flags.image || 'parity/substrate:latest' + const port = flags.port || 9933 + const namespace = flags.namespace || 'substrate-ci' + const validator = flags.validator || 0 + const node = flags.node || 1 + + const hypervisor = new Hypervisor(CONFIG) + try { + // Check/Create namespace + await hypervisor.readOrCreateNamespace(namespace) + const chainName = args.chainName + if (chainName) { + if (chainName === 'dev') { + logger.debug('Starting a fullnode in dev mode...') + await hypervisor.createDevNode(imageTag, port) + } else if (chainName === 'alicebob') { + await hypervisor.createAliceBobNodes(imageTag, port) + } else { + // TODO: customized chain with chainName + } + } + } catch (error) { + logger.error(error) + process.exit(1) + } + } +} + +SpawnCommand.description = 'Spawn a local testnet with options' + +SpawnCommand.flags = { + image: flags.string({ char: 'i', description: 'image to deploy' }), + port: flags.integer({ char: 'p', description: 'port to deploy on' }), + namespace: flags.string({ description: 'desired namespace to deploy to', env: 'NAMESPACE' }), + validator: flags.string({ char: 'v', description: 'number of validators' }), + node: flags.string({ char: 'n', description: 'number of full nodes, if not set but exists, default to 1' }), + key: flags.string({ char: 'k', description: 'number of full nodes, if not set but exists, default to 1' }), + chainspec: flags.string({ char: 'c', description: 'number of full nodes, if not set but exists, default to 1' }) +} + +SpawnCommand.args = [{ name: 'chainName' }] + +module.exports = SpawnCommand diff --git a/.maintain/chaostest/src/config/README.md b/.maintain/chaostest/src/config/README.md new file mode 100644 index 0000000000000000000000000000000000000000..655e6deacb3761e12a7aba446da8e462cf61b449 --- /dev/null +++ b/.maintain/chaostest/src/config/README.md @@ -0,0 +1,34 @@ +chaostest CONFIG +========= + +Since deployment can behave differently, we want to keep a state between phases including different test subjects. + +# Content +The state could include informations such as: +``` +{ + namespace, + image, + bootnode: { + podname, + ip, + port, + peerId, + privateKey, + publicKey + }, + nodes: [{ + podname, + ip, + port, + nodeType: 'validator' | 'bootnode' | , + privateKey (validator only), + publicKey (validator only) + }] +} +``` + +# TODO +k8s configuration +chainspec +chaos-agent diff --git a/.maintain/chaostest/src/config/index.js b/.maintain/chaostest/src/config/index.js new file mode 100644 index 0000000000000000000000000000000000000000..400597c2bddccabb31b1a8554c27503c7dad9568 --- /dev/null +++ b/.maintain/chaostest/src/config/index.js @@ -0,0 +1,70 @@ +const fs = require('fs') +const path = require('path') +const configPath = path.join(__dirname, './config.json') +const logger = require('../utils/logger') + +class Config { + constructor () { + this.load() + } + + async load () { + fs.readFile(configPath, (err, data) => { + if (err) { + if (err.code === 'ENOENT') { + this.reset() + } else { + throw err + } + } else { + try { + Object.assign(this, JSON.parse(data)) + } catch (error) { + logger.error('config file is corrupted, resetting...') + this.reset() + } + }; + }) + }; + + getConfig () { + return this + } + + async update () { + const data = JSON.stringify(this.getConfig()) + fs.writeFile(configPath, data, (err) => { + if (err) throw err + logger.debug('Configuration updated') + }) + } + + async setNamespace (namespace) { + this.namespace = namespace + this.update() + } + + async addNode (node) { + if (!this.nodes || Array.isArray(this.nodes)) { + this.nodes = [] + } + if (node.nodeType === 'bootnode') { + this.bootnode = node + } + this.nodes.push(node) + this.update() + } + + async reset () { + const data = JSON.stringify({}) + fs.writeFile(configPath, data, (err) => { + if (err) throw err + this.load() + }) + } +} + +module.exports = () => { + const config = new Config() + return config +} diff --git a/.maintain/chaostest/src/hypervisor/chainApi/api.js b/.maintain/chaostest/src/hypervisor/chainApi/api.js new file mode 100644 index 0000000000000000000000000000000000000000..f9265b6386ee48ab691b5b3cb717d5cdeea49acc --- /dev/null +++ b/.maintain/chaostest/src/hypervisor/chainApi/api.js @@ -0,0 +1,16 @@ +const chainApi = require('../modules/chainApi') + +exports.getApi = async function (endpoint) { + if (this._apiInstance && this._apiInstance.endpoint === endpoint) { + return this._apiInstance.instance + } else { + const instance = await chainApi.getApi(endpoint) + this._apiInstance = { endpoint, instance } + return instance + } +} + +exports.getChainBlockHeight = async function (url, port) { + const api = await this.getApi(url + ':' + port) + return chainApi.getChainBlockHeight(api) +} diff --git a/.maintain/chaostest/src/hypervisor/chainApi/index.js b/.maintain/chaostest/src/hypervisor/chainApi/index.js new file mode 100644 index 0000000000000000000000000000000000000000..c0802401d918224e1294de677805d81c34d92008 --- /dev/null +++ b/.maintain/chaostest/src/hypervisor/chainApi/index.js @@ -0,0 +1,4 @@ +const api = require('./api') +module.exports = function (Hypervisor) { + Object.assign(Hypervisor.prototype, api) +} diff --git a/.maintain/chaostest/src/hypervisor/deployment/deployment.js b/.maintain/chaostest/src/hypervisor/deployment/deployment.js new file mode 100644 index 0000000000000000000000000000000000000000..906734393af6793c207f16188cf2f26eb13a0d8c --- /dev/null +++ b/.maintain/chaostest/src/hypervisor/deployment/deployment.js @@ -0,0 +1,123 @@ +const k8s = require('../modules/k8s') +const { pollUntil } = require('../../utils/wait') +const { getBootNodeUrl } = require('../../utils') +const logger = require('../../utils/logger') + +exports.readOrCreateNamespace = async function (namespace) { + try { + logger.debug('Reading namespace') + await k8s.readNamespace(namespace) // if namespace is available, do not create here + } catch (error) { + if (error.response.statusCode !== 404) { + logger.error(error) + throw error + } + logger.debug('Namespace not present, creating...') + await k8s.createNamespace(namespace) + } + this.config.setNamespace(namespace) +} +exports.createAlice = async function (image, port) { + const substrateArgs = [ + '--chain=local', + '--node-key', + '0000000000000000000000000000000000000000000000000000000000000001', + '--validator', + '--no-telemetry', + '--rpc-cors', + 'all', + '--alice'] + const nodeSpec = { + nodeId: 'alice', + image, + port, + args: substrateArgs + } + nodeSpec.extraInfo = { + nodeType: 'bootnode', + privateKey: '', + publicKey: '', + peerId: '12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp' + } + await this.createNode(nodeSpec) +} + +exports.createBob = async function (image, port) { + const substrateArgs = [ + '--chain=local', + '--node-key', + '0000000000000000000000000000000000000000000000000000000000000002', + '--validator', + '--bob', + '--no-telemetry', + '--rpc-cors', + 'all', + '--bootnodes', + getBootNodeUrl(this.config.bootnode)] + const nodeSpec = { + nodeId: 'bob', + image, + port, + args: substrateArgs + } + nodeSpec.extraInfo = { + nodeType: 'validator', + privateKey: '', + publicKey: '' + } + await this.createNode(nodeSpec) +} + +exports.createAliceBobNodes = async function (image, port) { + await this.createAlice(image, port) + await this.createBob(image, port) +} + +exports.createDevNode = async function (image, port) { + const substrateArgs = ['--dev', '--rpc-external', '--ws-external'] + const nodeSpec = { + nodeId: 'node-1', + image, + port, + args: substrateArgs + } + await this.createNode(nodeSpec) +} + +exports.createNode = async function (nodeSpec) { + logger.info(`Creating ${nodeSpec.nodeId} as ${nodeSpec.extraInfo ? nodeSpec.extraInfo.nodeType : 'FullNode'} in ${this.config.namespace}`) + await k8s.createPod(nodeSpec, this.config.namespace) + logger.debug('Polling pod status') + const pod = await pollUntil( + () => k8s.getPod(nodeSpec.nodeId, this.config.namespace) + ) + const nodeInfo = { + podName: nodeSpec.nodeId, + ip: pod.status.podIP, + port: nodeSpec.port + } + if (nodeSpec.extraInfo) { + Object.assign(nodeInfo, nodeSpec.extraInfo) + } + logger.info(`${nodeSpec.nodeId} is created`) + this.config.addNode(nodeInfo) +} + +exports.cleanup = async function (namespace) { + await k8s.deleteNamespace(namespace) + if (namespace === this.config.namespace) { + this.config.reset() + } +} + +exports.getPodInfoInConfig = function (namespace, podName) { + if (this.config.namespace === namespace && Array.isArray(this.config.nodes)) { + return this.config.nodes.find((node) => node.podName === podName) + } else { + throw Error('No pod present in the namespace in config') + } +} + +exports.startForwardServer = async function (namespace, pod, port, onReady) { + await k8s.startForwardServer(namespace, pod, port, onReady) +} diff --git a/.maintain/chaostest/src/hypervisor/deployment/index.js b/.maintain/chaostest/src/hypervisor/deployment/index.js new file mode 100644 index 0000000000000000000000000000000000000000..a01865b6a5438b540df57aad9bbea5cdf83f0909 --- /dev/null +++ b/.maintain/chaostest/src/hypervisor/deployment/index.js @@ -0,0 +1,4 @@ +const deployment = require('./deployment') +module.exports = function (Hypervisor) { + Object.assign(Hypervisor.prototype, deployment) +} diff --git a/.maintain/chaostest/src/hypervisor/index.js b/.maintain/chaostest/src/hypervisor/index.js new file mode 100644 index 0000000000000000000000000000000000000000..607f3a33d84218d55dff976e742f5499c10a87dd --- /dev/null +++ b/.maintain/chaostest/src/hypervisor/index.js @@ -0,0 +1,11 @@ +const CONFIG = require('../config')() + +function Hypervisor (config) { + this.config = config || CONFIG +} + +// Mount sub modules of the Hypervisor class +require('./deployment')(Hypervisor) +require('./chainApi')(Hypervisor) + +module.exports = Hypervisor diff --git a/.maintain/chaostest/src/hypervisor/modules/chainApi.js b/.maintain/chaostest/src/hypervisor/modules/chainApi.js new file mode 100644 index 0000000000000000000000000000000000000000..b2ad897d06cbad2993993ecf0bc125c518a90dff --- /dev/null +++ b/.maintain/chaostest/src/hypervisor/modules/chainApi.js @@ -0,0 +1,18 @@ +const { ApiPromise, WsProvider } = require('@polkadot/api') +const { HttpProvider } = require('@polkadot/rpc-provider') + +const getApi = async (url) => { + const httpProvider = new HttpProvider(url) + return httpProvider + // const api = await ApiPromise.create({ provider: wsProvider }) + // return api + // TODO: tried to use websocket provider here, but the polkadot/api version is not stable yet, using http provider for now +} + +const getChainBlockHeight = async (provider) => { + const data = await provider.send('chain_getBlock', []) + const height = parseInt(data.block.header.number, 16) + return height +} + +module.exports = { getApi, getChainBlockHeight } diff --git a/.maintain/chaostest/src/hypervisor/modules/k8s.js b/.maintain/chaostest/src/hypervisor/modules/k8s.js new file mode 100644 index 0000000000000000000000000000000000000000..14f22ff5e8dfffc7c596789e3d6d5ee80f334aa0 --- /dev/null +++ b/.maintain/chaostest/src/hypervisor/modules/k8s.js @@ -0,0 +1,113 @@ +const k8s = require('@kubernetes/client-node') +const { isFunction } = require('../../utils') +const logger = require('../../utils/logger') + +// load k8s +const kc = new k8s.KubeConfig() +kc.loadFromDefault() + +// load k8s Apis +const k8sAppApi = kc.makeApiClient(k8s.AppsV1Api) +const k8sCoreApi = kc.makeApiClient(k8s.CoreV1Api) + +const createNamespace = async namespace => { + const namespaceJson = { + apiVersion: 'v1', + kind: 'Namespace', + metadata: { + name: namespace + } + } + return await k8sCoreApi.createNamespace(namespaceJson) +} + +const readNamespace = async namespace => { + return await k8sCoreApi.readNamespace(namespace) +} + +const createPod = async (nodeSpec, namespace) => { + const { label, nodeId, image, args, port } = nodeSpec + const spec = { + metadata: { + labels: { + app: label + }, + name: nodeId + }, + spec: { + containers: [ + { + image: image, + imagePullPolicy: 'Always', + name: nodeId, + ports: [{ containerPort: port }], + args: args + } + ] + } + } + return await k8sCoreApi.createNamespacedPod(namespace, spec) +} + +const getDeploymentStatus = async (deploymentName, namespace) => { + const response = await k8sAppApi.readNamespacedDeploymentStatus(deploymentName, namespace) + const status = response.response.body.status + function getAvailability (item) { + return item.type === 'Available' + } + if (status && status.conditions) { + return status.conditions.find(getAvailability) + } + return undefined +} + +const deleteNamespace = async (namespace) => { + logger.debug(`Taking down Namespace ${namespace}...`) + if (process.env.KEEP_NAMESPACE && process.env.KEEP_NAMESPACE === 1) { + return + } + return k8sCoreApi.deleteNamespace(namespace) +} + +const getNamespacedPods = async (namespace) => { + const response = await k8sCoreApi.listNamespacedPod(namespace) + return response.body.items +} + +const getPod = async (podName, namespace) => { + const pods = await getNamespacedPods(namespace) + const found = pods.find( + (pod) => !!pod.metadata && pod.metadata.name === podName && !!pod.status && pod.status.podIP + ) + if (!found) { + throw Error(`GetNode(${podName}): node is not present in the cluster`) + } + return found +} + +const startForwardServer = async (namespace, pod, port, onReady) => new Promise((resolve, reject) => { + const net = require('net') + const forward = new k8s.PortForward(kc) + + // This simple server just forwards traffic from itself to a service running in kubernetes + // -> localhost:8080 -> port-forward-tunnel -> kubernetes-pod + // This is basically equivalent to 'kubectl port-forward ...' but in Javascript. + const server = net.createServer((socket) => { + forward.portForward(namespace, pod, [port], socket, null, socket) + }) + // TODO: add Ws proxy server to adopt the polkadot/api + server.listen(port, '127.0.0.1', (err) => { + if (err) { + logger.error('Error starting server') + reject(err) + } + logger.info('Forwarding server started, ready to connect') + resolve() + // Optional onReady hook when server started + if (onReady && isFunction(onReady)) { + onReady() + } + }) +}) + +module.exports = { createNamespace, readNamespace, createPod, deleteNamespace, getDeploymentStatus, getPod, getNamespacedPods, startForwardServer } diff --git a/.maintain/chaostest/src/index.js b/.maintain/chaostest/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..176eca6d71ba6119e12f1b5f4fe7e59db4f00911 --- /dev/null +++ b/.maintain/chaostest/src/index.js @@ -0,0 +1 @@ +module.exports = require('@oclif/command') diff --git a/.maintain/chaostest/src/utils/exit.js b/.maintain/chaostest/src/utils/exit.js new file mode 100644 index 0000000000000000000000000000000000000000..3cf06d290440b1d638d1559589f616421f75ad2f --- /dev/null +++ b/.maintain/chaostest/src/utils/exit.js @@ -0,0 +1,12 @@ +const logger = require('../utils/logger') + +const succeedExit = function () { + process.exit(0) +} + +const errorExit = function (msg, err) { + logger.error(msg, err) + process.exit(1) +} + +module.exports = { succeedExit, errorExit } diff --git a/.maintain/chaostest/src/utils/index.js b/.maintain/chaostest/src/utils/index.js new file mode 100644 index 0000000000000000000000000000000000000000..b50c177215a244cca92965c8342e74c37e2da16d --- /dev/null +++ b/.maintain/chaostest/src/utils/index.js @@ -0,0 +1,9 @@ +const getBootNodeUrl = (bootnode) => { + return `/dns4/${bootnode.ip}/tcp/30333/p2p/${bootnode.peerId}` +} + +const isFunction = (obj) => { + return !!(obj && obj.constructor && obj.call && obj.apply) +} + +module.exports = { getBootNodeUrl, isFunction } diff --git a/.maintain/chaostest/src/utils/logger.js b/.maintain/chaostest/src/utils/logger.js new file mode 100644 index 0000000000000000000000000000000000000000..e1da0d8d07f491c38739aa0d280481f1b9a8125c --- /dev/null +++ b/.maintain/chaostest/src/utils/logger.js @@ -0,0 +1,50 @@ +const winston = require('winston') +const fs = require('fs') +const logDir = 'log' // Or read from a configuration +const { format, transports } = winston +const env = process.env.NODE_ENV || 'development' +const util = require('util') + +if (!fs.existsSync(logDir)) { + // Create the directory if it does not exist + fs.mkdirSync(logDir) +} + +const logFormat = format.printf(info => { + info.message = util.format(info.message) + if (info.metadata && Object.keys(info.metadata).length) { + info.message = util.format(info.message, info.metadata) + } + return `${info.timestamp} ${info.level}: ${info.message}` +}) + +const logger = winston.createLogger({ + level: env === 'development' ? 'debug' : 'info', + transports: [ + new transports.Console({ + format: format.combine( + format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), + // Format the metadata object + format.metadata({ fillExcept: ['message', 'level', 'timestamp', 'label'] }), + format.colorize(), + logFormat + ) + }), + new winston.transports.File({ + level: env === 'development' ? 'debug' : 'info', + filename: logDir + '/logs.log', + format: format.combine( + format.timestamp(), + format.json() + ), + maxsize: 1024 * 1024 * 10 // 10MB + }) + ], + exceptionHandlers: [ + new winston.transports.File({ + filename: 'log/exceptions.log' + }) + ] +}) + +module.exports = logger diff --git a/.maintain/chaostest/src/utils/wait.js b/.maintain/chaostest/src/utils/wait.js new file mode 100644 index 0000000000000000000000000000000000000000..72498d1acb2a62c9b61c64464162d282713d2d61 --- /dev/null +++ b/.maintain/chaostest/src/utils/wait.js @@ -0,0 +1,32 @@ +const logger = require('./logger') +/** + * Wait n milliseconds + * + * @param n - In milliseconds + */ +function waitNMilliseconds (n) { + return new Promise((resolve) => { + setTimeout(resolve, n) + }) +} + +/** + * Run a function until that function correctly resolves + * + * @param fn - The function to run + */ +async function pollUntil (fn) { + try { + const result = await fn() + + return result + } catch (_error) { + logger.error('Error polling', _error) + logger.debug('awaiting...') + await waitNMilliseconds(5000) // FIXME We can add exponential delay here + + return pollUntil(fn) + } +} + +module.exports = { pollUntil, waitNMilliseconds } diff --git a/.maintain/flamingfir-deploy.sh b/.maintain/flamingfir-deploy.sh index 596bb04ece091cd03f3c993d655f5d45770362ea..8f0fb3a2bc016067d0bf11ae993a3bfa1636280f 100755 --- a/.maintain/flamingfir-deploy.sh +++ b/.maintain/flamingfir-deploy.sh @@ -5,7 +5,7 @@ RETRY_ATTEMPT=0 SLEEP_TIME=15 TARGET_HOST="$1" COMMIT=$(cat artifacts/substrate/VERSION) -DOWNLOAD_URL="https://releases.parity.io/substrate/x86_64-debian:stretch/${COMMIT}/substrate" +DOWNLOAD_URL="https://releases.parity.io/substrate/x86_64-debian:stretch/${COMMIT}/substrate/substrate" POST_DATA='{"extra_vars":{"artifact_path":"'${DOWNLOAD_URL}'","target_host":"'${TARGET_HOST}'"}}' JOB_ID=$(wget -O - --header "Authorization: Bearer ${AWX_TOKEN}" --header "Content-type: application/json" --post-data "${POST_DATA}" https://ansible-awx.parity.io/api/v2/job_templates/32/launch/ | jq .job) diff --git a/.maintain/gitlab/check_labels.sh b/.maintain/gitlab/check_labels.sh new file mode 100755 index 0000000000000000000000000000000000000000..5ab099b38291cc66b6f370430b8f06e6b2f5c24f --- /dev/null +++ b/.maintain/gitlab/check_labels.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +#shellcheck source=lib.sh +source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/lib.sh" + +ensure_labels() { + for label in "$@"; do + if has_label 'paritytech/substrate' "$CI_COMMIT_BRANCH" "$label"; then + return 0 + fi + done + return 1 +} + +# Must have one of the following labels +releasenotes_labels=( + 'B0-silent' + 'B3-apinoteworthy' + 'B5-clientnoteworthy' + 'B7-runtimenoteworthy' +) + +criticality_labels=( + 'C1-low' + 'C3-medium' + 'C7-high' + 'C9-critical' +) + +echo "[+] Checking release notes (B) labels for $CI_COMMIT_BRANCH" +if ensure_labels "${releasenotes_labels[@]}"; then + echo "[+] Release notes label detected. All is well." +else + echo "[!] Release notes label not detected. Please add one of: ${releasenotes_labels[*]}" + exit 1 +fi + +echo "[+] Checking release criticality (C) labels for $CI_COMMIT_BRANCH" +if ensure_labels "${criticality_labels[@]}"; then + echo "[+] Release criticality label detected. All is well." +else + echo "[!] Release criticality label not detected. Please add one of: ${criticality_labels[*]}" + exit 1 +fi + +exit 0 diff --git a/.maintain/gitlab/check_line_width.sh b/.maintain/gitlab/check_line_width.sh index f382d630b183c6396115cc1e76e77dfab4c20047..611d3ae2681e2ef145753a0f774c5183fc9df7d9 100755 --- a/.maintain/gitlab/check_line_width.sh +++ b/.maintain/gitlab/check_line_width.sh @@ -2,47 +2,50 @@ # # check if line width of rust source files is not beyond x characters # +set -e +set -o pipefail +BASE_ORIGIN="origin" +BASE_BRANCH_NAME="master" +LINE_WIDTH="120" +GOOD_LINE_WIDTH="100" +BASE_BRANCH="${BASE_ORIGIN}/${BASE_BRANCH_NAME}" +git fetch ${BASE_ORIGIN} ${BASE_BRANCH_NAME} --depth 100 +BASE_HASH=$(git merge-base ${BASE_BRANCH} HEAD) -BASE_BRANCH="origin/master" -LINE_WIDTH="121" -GOOD_LINE_WIDTH="101" - - -git diff --name-only ${BASE_BRANCH}...${CI_COMMIT_SHA} \*.rs | ( while read file +git diff --name-only ${BASE_HASH} -- \*.rs | ( while read file do if [ ! -f ${file} ]; then echo "Skipping removed file." - elif git diff ${BASE_BRANCH}...${CI_COMMIT_SHA} ${file} | grep -q "^+.\{${LINE_WIDTH}\}" + elif git diff ${BASE_HASH} -- ${file} | grep -q "^+.\{$(( $LINE_WIDTH + 1 ))\}" then if [ -z "${FAIL}" ] then - echo "| warning!" - echo "| Lines should not be longer than 120 characters." + echo "| error!" + echo "| Lines must not be longer than ${LINE_WIDTH} characters." echo "| " echo "| see more https://wiki.parity.io/Substrate-Style-Guide" echo "|" FAIL="true" fi echo "| file: ${file}" - git diff ${BASE_BRANCH}...${CI_COMMIT_SHA} ${file} \ - | grep -n "^+.\{${LINE_WIDTH}\}" + git diff ${BASE_HASH} -- ${file} \ + | grep -n "^+.\{$(( $LINE_WIDTH + 1))\}" echo "|" else - if git diff ${BASE_BRANCH}...${CI_COMMIT_SHA} ${file} | grep -q "^+.\{${GOOD_LINE_WIDTH}\}" + if git diff ${BASE_HASH} -- ${file} | grep -q "^+.\{$(( $GOOD_LINE_WIDTH + 1 ))\}" then if [ -z "${FAIL}" ] then echo "| warning!" - echo "| Lines should be longer than 100 characters only in exceptional circumstances!" + echo "| Lines should be longer than ${GOOD_LINE_WIDTH} characters only in exceptional circumstances!" echo "| " echo "| see more https://wiki.parity.io/Substrate-Style-Guide" echo "|" fi echo "| file: ${file}" - git diff ${BASE_BRANCH}...${CI_COMMIT_SHA} ${file} \ - | grep -n "^+.\{${LINE_WIDTH}\}" + git diff ${BASE_HASH} -- ${file} | grep -n "^+.\{$(( $GOOD_LINE_WIDTH + 1 ))\}" echo "|" fi fi diff --git a/.maintain/gitlab/check_polkadot_companion_build.sh b/.maintain/gitlab/check_polkadot_companion_build.sh index c2ecf8cb6a071b116af4591097251efdba254746..b78c26dea8458b0bcc7c172d163d31be68354b90 100755 --- a/.maintain/gitlab/check_polkadot_companion_build.sh +++ b/.maintain/gitlab/check_polkadot_companion_build.sh @@ -12,7 +12,7 @@ github_api_substrate_pull_url="https://api.github.com/repos/paritytech/substrate/pulls" # use github api v3 in order to access the data without authentication -github_header="Accept: application/vnd.github.v3+json" +github_header="Authorization: token ${GITHUB_PR_TOKEN}" boldprint () { printf "|\n| \033[1m${@}\033[0m\n|\n" ; } boldcat () { printf "|\n"; while read l; do printf "| \033[1m${l}\033[0m\n"; done; printf "|\n" ; } @@ -31,10 +31,7 @@ polkadot companion: paritytech/polkadot#567 it will then run cargo check from this polkadot's branch with substrate code -from this pull request. in absence of that string it will check if a polkadot -pr is mentioned and will use the last one instead. if none of the above can be -found it will check if polkadot has a branch of the exact same name than the -substrate's branch. if it can't find anything, it will uses master instead +from this pull request. otherwise, it will uses master instead EOT @@ -50,7 +47,9 @@ SUBSTRATE_PATH=$(pwd) git merge origin/master # Clone the current Polkadot master branch into ./polkadot. -git clone --depth 1 https://github.com/paritytech/polkadot.git +# NOTE: we need to pull enough commits to be able to find a common +# ancestor for successfully performing merges below. +git clone --depth 20 https://github.com/paritytech/polkadot.git cd polkadot @@ -72,30 +71,14 @@ then -e 's;^.*polkadot companion: https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ | tail -n 1)" - if [ -z "${pr_companion}" ] - then - pr_companion="$(echo "${pr_body}" | sed -n -r \ - -e 's;^.*paritytech/polkadot/#([0-9]+).*$;\1;p' \ - -e 's;^.*https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ - | tail -n 1)" - fi - if [ "${pr_companion}" ] then boldprint "companion pr specified/detected: #${pr_companion}" - git fetch --depth 1 origin refs/pull/${pr_companion}/head:pr/${pr_companion} + git fetch origin refs/pull/${pr_companion}/head:pr/${pr_companion} git checkout pr/${pr_companion} git merge origin/master else - pr_ref="$(grep -Po '"ref"\s*:\s*"\K(?!master)[^"]*' "${pr_data_file}")" - if git fetch --depth 1 origin "$pr_ref":branch/"$pr_ref" 2>/dev/null - then - boldprint "companion branch detected: $pr_ref" - git checkout branch/"$pr_ref" - git merge origin/master - else - boldprint "no companion branch found - building polkadot:master" - fi + boldprint "no companion branch found - building polkadot:master" fi rm -f "${pr_data_file}" else @@ -111,9 +94,5 @@ echo "paths = [ \"$SUBSTRATE_PATH\" ]" > .cargo/config mkdir -p target/debug/wbuild/.cargo cp .cargo/config target/debug/wbuild/.cargo/config -# package, others are updated along the way. -cargo update - # Test Polkadot pr or master branch with this Substrate commit. time cargo test --all --release --verbose - diff --git a/.maintain/gitlab/check_polkadot_companion_status.sh b/.maintain/gitlab/check_polkadot_companion_status.sh index 5387e68f25cbba284433b8946f20f6eacfc76b9f..35c2983886f46d23fe42ec5f68a16df232110949 100755 --- a/.maintain/gitlab/check_polkadot_companion_status.sh +++ b/.maintain/gitlab/check_polkadot_companion_status.sh @@ -1,13 +1,13 @@ #!/bin/sh # -# check for a polkadot companion pr and ensure it has approvals and is +# check for a polkadot companion pr and ensure it has approvals and is # mergeable # github_api_substrate_pull_url="https://api.github.com/repos/paritytech/substrate/pulls" github_api_polkadot_pull_url="https://api.github.com/repos/paritytech/polkadot/pulls" # use github api v3 in order to access the data without authentication -github_header="Accept: application/vnd.github.v3+json" +github_header="Authorization: token ${GITHUB_PR_TOKEN}" boldprint () { printf "|\n| \033[1m${@}\033[0m\n|\n" ; } boldcat () { printf "|\n"; while read l; do printf "| \033[1m${l}\033[0m\n"; done; printf "|\n" ; } @@ -24,8 +24,7 @@ this job checks if there is a string in the description of the pr like polkadot companion: paritytech/polkadot#567 -or any other polkadot pr is mentioned in this pr's description and checks its -status. +and checks its status. EOT @@ -48,14 +47,6 @@ pr_companion="$(echo "${pr_body}" | sed -n -r \ -e 's;^.*polkadot companion: https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ | tail -n 1)" -# get companion mentioned in the description -if [ -z "${pr_companion}" ] -then - pr_companion="$(echo "${pr_body}" | sed -n -r \ - 's;^.*https://github.com/paritytech/polkadot/pull/([0-9]+).*$;\1;p' \ - | tail -n 1)" -fi - if [ -z "${pr_companion}" ] then boldprint "no companion pr found" @@ -68,7 +59,10 @@ boldprint "companion pr: #${pr_companion}" # mergable and approved curl -H "${github_header}" -sS -o companion_pr.json \ - ${github_api_polkadot_pull_url}/${pr_companion} + ${github_api_polkadot_pull_url}/${pr_companion} + +pr_head_sha=$(jq -r -e '.head.sha' < companion_pr.json) +boldprint "Polkadot PR's HEAD SHA: $pr_head_sha" if jq -e .merged < companion_pr.json >/dev/null then @@ -85,11 +79,20 @@ else fi curl -H "${github_header}" -sS -o companion_pr_reviews.json \ - ${github_api_polkadot_pull_url}/${pr_companion}/reviews - -if [ -n "$(jq -r -e '.[].state | select(. == "CHANGES_REQUESTED")' < companion_pr_reviews.json)" ] && \ - [ -z "$(jq -r -e '.[].state | select(. == "APPROVED")' < companion_pr_reviews.json)" ] -then + ${github_api_polkadot_pull_url}/${pr_companion}/reviews + +# If there are any 'CHANGES_REQUESTED' reviews for the *current* review +jq -r -e '.[] | select(.state == "CHANGES_REQUESTED").commit_id' \ + < companion_pr_reviews.json > companion_pr_reviews_current.json +while IFS= read -r line; do + if [ "$line" = "$pr_head_sha" ]; then + boldprint "polkadot pr #${pr_companion} has CHANGES_REQUESTED for the latest commit" + exit 1 + fi +done < companion_pr_reviews_current.json + +# Then we check for at least 1 APPROVED +if [ -z "$(jq -r -e '.[].state | select(. == "APPROVED")' < companion_pr_reviews.json)" ]; then boldprint "polkadot pr #${pr_companion} not APPROVED" exit 1 fi diff --git a/.maintain/gitlab/check_runtime.sh b/.maintain/gitlab/check_runtime.sh index 5b7e25e3afc4eabef01d984047a98d675ab09757..6d009c5aafc6a8907fb9d8e598e8870854af8db7 100755 --- a/.maintain/gitlab/check_runtime.sh +++ b/.maintain/gitlab/check_runtime.sh @@ -67,7 +67,7 @@ sub_spec_version="$(git diff tags/release...${CI_COMMIT_SHA} ${VERSIONS_FILE} \ if [ "${add_spec_version}" != "${sub_spec_version}" ] then - github_label "B2-breaksapi" + github_label "D2-breaksapi" boldcat <<-EOT diff --git a/.maintain/gitlab/generate_changelog.sh b/.maintain/gitlab/generate_changelog.sh index ba2a507e4cac694f918aa2c88cf1585991faa373..c13871f50ee49c3917f59785d9f372067f7a6e67 100755 --- a/.maintain/gitlab/generate_changelog.sh +++ b/.maintain/gitlab/generate_changelog.sh @@ -11,6 +11,7 @@ runtime_changes="" api_changes="" client_changes="" changes="" +migrations="" while IFS= read -r line; do pr_id=$(echo "$line" | sed -E 's/.*#([0-9]+)\)$/\1/') @@ -19,25 +20,29 @@ while IFS= read -r line; do if has_label 'paritytech/substrate' "$pr_id" 'B0-silent'; then continue fi - if has_label 'paritytech/substrate' "$pr_id" 'B1-runtimenoteworthy'; then - runtime_changes="$runtime_changes + if has_label 'paritytech/substrate' "$pr_id" 'B3-apinoteworthy' ; then + api_changes="$api_changes $line" fi - if has_label 'paritytech/substrate' "$pr_id" 'B1-clientnoteworthy'; then + if has_label 'paritytech/substrate' "$pr_id" 'B5-clientnoteworthy'; then client_changes="$client_changes $line" fi - if has_label 'paritytech/substrate' "$pr_id" 'B1-apinoteworthy' ; then - api_changes="$api_changes + if has_label 'paritytech/substrate' "$pr_id" 'B7-runtimenoteworthy'; then + runtime_changes="$runtime_changes +$line" + fi + if has_label 'paritytech/substrate' "$pr_id" 'D1-runtime-migration'; then + migrations="$migrations $line" - continue fi done <<< "$all_changes" # Make the substrate section if there are any substrate changes if [ -n "$runtime_changes" ] || [ -n "$api_changes" ] || - [ -n "$client_changes" ]; then + [ -n "$client_changes" ] || + [ -n "$migrations" ]; then changes=$(cat << EOF Substrate changes ----------------- @@ -69,5 +74,12 @@ $api_changes" $changes" fi +if [ -n "$migrations" ]; then + changes="$changes + +Runtime Migrations +------------------ +$migrations" +fi echo "$changes" diff --git a/.maintain/gitlab/lib.sh b/.maintain/gitlab/lib.sh index ecc9a5f54288cd4636a05cb7f2a2d0535e40ebe9..33477b52f5891a6855f15aec62cd3c41454dc85c 100755 --- a/.maintain/gitlab/lib.sh +++ b/.maintain/gitlab/lib.sh @@ -5,7 +5,7 @@ api_base="https://api.github.com/repos" # Function to take 2 git tags/commits and get any lines from commit messages # that contain something that looks like a PR reference: e.g., (#1234) sanitised_git_logs(){ - git --no-pager log --pretty=format:"%s" "$1..$2" | + git --no-pager log --pretty=format:"%s" "$1...$2" | # Only find messages referencing a PR grep -E '\(#[0-9]+\)' | # Strip any asterisks @@ -66,8 +66,12 @@ has_label(){ repo="$1" pr_id="$2" label="$3" - out=$(curl -H "Authorization: token $GITHUB_RELEASE_TOKEN" -s "$api_base/$repo/pulls/$pr_id") - [ -n "$(echo "$out" | jq ".labels | .[] | select(.name==\"$label\")")" ] + if [ -n "$GITHUB_RELEASE_TOKEN" ]; then + out=$(curl -H "Authorization: token $GITHUB_RELEASE_TOKEN" -s "$api_base/$repo/pulls/$pr_id") + else + out=$(curl -H "Authorization: token $GITHUB_PR_TOKEN" -s "$api_base/$repo/pulls/$pr_id") + fi + [ -n "$(echo "$out" | tr -d '\r\n' | jq ".labels | .[] | select(.name==\"$label\")")" ] } # Formats a message into a JSON string for posting to Matrix diff --git a/.maintain/gitlab/skip_if_draft.sh b/.maintain/gitlab/skip_if_draft.sh index a234a6c18e21c8e415c840f6bba1cf988d2a744c..cf6ea6a5b31155da9d6ac0c09079f4dffcec2dfa 100755 --- a/.maintain/gitlab/skip_if_draft.sh +++ b/.maintain/gitlab/skip_if_draft.sh @@ -2,7 +2,7 @@ url="https://api.github.com/repos/paritytech/substrate/pulls/${CI_COMMIT_REF_NAME}" echo "[+] API URL: $url" -draft_state=$(curl "$url" | jq -r .draft) +draft_state=$(curl -H "Authorization: token ${GITHUB_PR_TOKEN}" "$url" | jq -r .draft) echo "[+] Draft state: $draft_state" if [ "$draft_state" = 'true' ]; then diff --git a/.maintain/monitoring/alerting-rules/alerting-rule-tests.yaml b/.maintain/monitoring/alerting-rules/alerting-rule-tests.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5b0daba3d81893d9cd1dfadc152076da72d87978 --- /dev/null +++ b/.maintain/monitoring/alerting-rules/alerting-rule-tests.yaml @@ -0,0 +1,236 @@ +rule_files: + - /dev/stdin + +evaluation_interval: 1m + +tests: + - interval: 1m + input_series: + - series: 'polkadot_sub_libp2p_peers_count{ + job="polkadot", + pod="polkadot-abcdef01234-abcdef", + instance="polkadot-abcdef01234-abcdef", + }' + values: '3 2+0x4 1+0x9' # 3 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + + - series: 'polkadot_sub_txpool_validations_scheduled{ + job="polkadot", + pod="polkadot-abcdef01234-abcdef", + instance="polkadot-abcdef01234-abcdef", + }' + values: '11+1x10 22+2x30 10043x5' + + - series: 'polkadot_sub_txpool_validations_finished{ + job="polkadot", + pod="polkadot-abcdef01234-abcdef", + instance="polkadot-abcdef01234-abcdef", + }' + values: '0+1x42 42x5' + + - series: 'polkadot_block_height{ + status="best", job="polkadot", + pod="polkadot-abcdef01234-abcdef", + instance="polkadot-abcdef01234-abcdef", + }' + values: '1+1x3 4+0x13' # 1 2 3 4 4 4 4 4 4 4 4 4 ... + + - series: 'polkadot_block_height{ + status="finalized", + job="polkadot", + pod="polkadot-abcdef01234-abcdef", + instance="polkadot-abcdef01234-abcdef", + }' + values: '1+1x3 4+0x13' # 1 2 3 4 4 4 4 4 4 4 4 4 ... + + alert_rule_test: + + ###################################################################### + # Block production + ###################################################################### + + - eval_time: 6m + alertname: LowNumberOfNewBlocks + exp_alerts: + - eval_time: 7m + alertname: LowNumberOfNewBlocks + exp_alerts: + - exp_labels: + severity: warning + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + status: best + exp_annotations: + message: "Less than one new block per minute on instance + polkadot-abcdef01234-abcdef." + + - eval_time: 14m + alertname: LowNumberOfNewBlocks + exp_alerts: + - exp_labels: + severity: warning + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + status: best + exp_annotations: + message: "Less than one new block per minute on instance + polkadot-abcdef01234-abcdef." + - exp_labels: + severity: critical + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + status: best + exp_annotations: + message: "Less than one new block per minute on instance + polkadot-abcdef01234-abcdef." + + ###################################################################### + # Block finalization + ###################################################################### + + - eval_time: 6m + alertname: BlockFinalizationSlow + exp_alerts: + - eval_time: 7m + alertname: BlockFinalizationSlow + exp_alerts: + - exp_labels: + severity: warning + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + status: finalized + exp_annotations: + message: "Finalized block on instance + polkadot-abcdef01234-abcdef increases by less than 1 per + minute." + + - eval_time: 14m + alertname: BlockFinalizationSlow + exp_alerts: + - exp_labels: + severity: warning + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + status: finalized + exp_annotations: + message: "Finalized block on instance + polkadot-abcdef01234-abcdef increases by less than 1 per + minute." + - exp_labels: + severity: critical + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + status: finalized + exp_annotations: + message: "Finalized block on instance + polkadot-abcdef01234-abcdef increases by less than 1 per + minute." + + ###################################################################### + # Transaction queue + ###################################################################### + + - eval_time: 11m + alertname: TransactionQueueSizeIncreasing + # Number of validations scheduled and finished both grow at a rate + # of 1 in the first 10 minutes, thereby the queue is not increasing + # in size, thus don't expect an alert. + exp_alerts: + - eval_time: 22m + alertname: TransactionQueueSizeIncreasing + # Number of validations scheduled is growing twice as fast as the + # number of validations finished after minute 10. Thus expect + # warning alert after 20 minutes. + exp_alerts: + - exp_labels: + severity: warning + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + exp_annotations: + message: "The transaction pool size on node + polkadot-abcdef01234-abcdef has been monotonically + increasing for the last 10 minutes." + - eval_time: 43m + alertname: TransactionQueueSizeIncreasing + # Number of validations scheduled is growing twice as fast as the + # number of validations finished after minute 10. Thus expect + # both warning and critical alert after 40 minutes. + exp_alerts: + - exp_labels: + severity: warning + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + exp_annotations: + message: "The transaction pool size on node + polkadot-abcdef01234-abcdef has been monotonically + increasing for the last 10 minutes." + - exp_labels: + severity: critical + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + exp_annotations: + message: "The transaction pool size on node + polkadot-abcdef01234-abcdef has been monotonically + increasing for the last 30 minutes." + - eval_time: 49m + alertname: TransactionQueueSizeHigh + # After minute 43 the number of validations scheduled jumps up + # drastically while the number of validations finished stays the + # same. Thus expect an alert. + exp_alerts: + - exp_labels: + severity: critical + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + exp_annotations: + message: "The transaction pool size on node + polkadot-abcdef01234-abcdef has been above 10_000 for the + last 5 minutes." + + ###################################################################### + # Networking + ###################################################################### + + - eval_time: 3m # Values: 3 2 2 + alertname: LowNumberOfPeers + exp_alerts: + - eval_time: 4m # Values: 2 2 2 + alertname: LowNumberOfPeers + exp_alerts: + - exp_labels: + severity: warning + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + exp_annotations: + message: "The node polkadot-abcdef01234-abcdef has less + than 3 peers for more than 3 minutes" + + - eval_time: 16m # Values: 3 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 + alertname: LowNumberOfPeers + exp_alerts: + - exp_labels: + severity: warning + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + exp_annotations: + message: "The node polkadot-abcdef01234-abcdef has less + than 3 peers for more than 3 minutes" + - exp_labels: + severity: critical + pod: polkadot-abcdef01234-abcdef + instance: polkadot-abcdef01234-abcdef + job: polkadot + exp_annotations: + message: "The node polkadot-abcdef01234-abcdef has less + than 3 peers for more than 15 minutes" diff --git a/.maintain/monitoring/alerting-rules/alerting-rules.yaml b/.maintain/monitoring/alerting-rules/alerting-rules.yaml new file mode 100644 index 0000000000000000000000000000000000000000..12f46e17ad85b3b29ea169a2b3ac861c7118b6a3 --- /dev/null +++ b/.maintain/monitoring/alerting-rules/alerting-rules.yaml @@ -0,0 +1,125 @@ +groups: +- name: polkadot.rules + rules: + + ############################################################################## + # Block production + ############################################################################## + + - alert: LowNumberOfNewBlocks + annotations: + message: 'Less than one new block per minute on instance {{ + $labels.instance }}.' + expr: increase(polkadot_block_height{status="best"}[1m]) < 1 + for: 3m + labels: + severity: warning + - alert: LowNumberOfNewBlocks + annotations: + message: 'Less than one new block per minute on instance {{ + $labels.instance }}.' + expr: increase(polkadot_block_height{status="best"}[1m]) < 1 + for: 10m + labels: + severity: critical + + ############################################################################## + # Block finalization + ############################################################################## + + - alert: BlockFinalizationSlow + expr: increase(polkadot_block_height{status="finalized"}[1m]) < 1 + for: 3m + labels: + severity: warning + annotations: + message: 'Finalized block on instance {{ $labels.instance }} increases by + less than 1 per minute.' + - alert: BlockFinalizationSlow + expr: increase(polkadot_block_height{status="finalized"}[1m]) < 1 + for: 10m + labels: + severity: critical + annotations: + message: 'Finalized block on instance {{ $labels.instance }} increases by + less than 1 per minute.' + - alert: BlockFinalizationLaggingBehind + # Under the assumption of an average block production of 6 seconds, + # "best" and "finalized" being more than 10 blocks apart would imply + # more than a 1 minute delay between block production and finalization. + expr: '(polkadot_block_height_number{status="best"} - ignoring(status) + polkadot_block_height_number{status="finalized"}) > 10' + for: 8m + labels: + severity: critical + annotations: + message: "Block finalization on instance {{ $labels.instance }} is behind + block production by {{ $value }} for more than 8m" + + ############################################################################## + # Transaction queue + ############################################################################## + + - alert: TransactionQueueSizeIncreasing + expr: 'increase(polkadot_sub_txpool_validations_scheduled[5m]) - + increase(polkadot_sub_txpool_validations_finished[5m]) > 0' + for: 10m + labels: + severity: warning + annotations: + message: 'The transaction pool size on node {{ $labels.instance }} has + been monotonically increasing for the last 10 minutes.' + - alert: TransactionQueueSizeIncreasing + expr: 'increase(polkadot_sub_txpool_validations_scheduled[5m]) - + increase(polkadot_sub_txpool_validations_finished[5m]) > 0' + for: 30m + labels: + severity: critical + annotations: + message: 'The transaction pool size on node {{ $labels.instance }} has + been monotonically increasing for the last 30 minutes.' + - alert: TransactionQueueSizeHigh + expr: 'polkadot_sub_txpool_validations_scheduled - + polkadot_sub_txpool_validations_finished > 10000' + for: 5m + labels: + severity: critical + annotations: + message: 'The transaction pool size on node {{ $labels.instance }} has + been above 10_000 for the last 5 minutes.' + + ############################################################################## + # Networking + ############################################################################## + + - alert: LowNumberOfPeers + expr: polkadot_sub_libp2p_peers_count < 3 + for: 3m + labels: + severity: warning + annotations: + message: 'The node {{ $labels.instance }} has less than 3 peers for more + than 3 minutes' + - alert: LowNumberOfPeers + expr: polkadot_sub_libp2p_peers_count < 3 + for: 15m + labels: + severity: critical + annotations: + message: 'The node {{ $labels.instance }} has less than 3 peers for more + than 15 minutes' + + ############################################################################## + # Others + ############################################################################## + + - alert: AuthorityDiscoveryHighDiscoveryFailure + expr: 'polkadot_authority_discovery_handle_value_found_event_failure / + ignoring(name) + polkadot_authority_discovery_dht_event_received{name="value_found"} > 0.5' + for: 2h + labels: + severity: warning + annotations: + message: "Authority discovery on node {{ $labels.instance }} fails to + process more than 50 % of the values found on the DHT." diff --git a/.maintain/monitoring/grafana-dashboards/substrate-networking.json b/.maintain/monitoring/grafana-dashboards/substrate-networking.json new file mode 100644 index 0000000000000000000000000000000000000000..6eeae8e11e22a374aed85e4a179034e0984e8d34 --- /dev/null +++ b/.maintain/monitoring/grafana-dashboards/substrate-networking.json @@ -0,0 +1,2925 @@ +{ + "__inputs": [ + { + "name": "VAR_METRIC_NAMESPACE", + "type": "constant", + "label": "Prefix of the metrics", + "value": "polkadot", + "description": "" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "6.7.3" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "" + }, + { + "type": "panel", + "id": "heatmap", + "name": "Heatmap", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + }, + { + "datasource": "$data_source", + "enable": true, + "expr": "count(count(${metric_namespace}_sub_libp2p_connections / max_over_time(${metric_namespace}_sub_libp2p_connections[1h]) < 0.1) >= count(${metric_namespace}_sub_libp2p_connections) / 10)", + "hide": false, + "iconColor": "#C4162A", + "limit": 100, + "name": "Connection losses events", + "showIn": 0, + "step": "5m", + "tags": [], + "titleFormat": "Network-wide connectivity loss", + "type": "tags" + } + ] + }, + "description": "Information related to the networking layer of Substrate", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1594715467007, + "links": [], + "panels": [ + { + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 167, + "title": "Sync", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 24, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 101, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatDirection": "v", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "1 - (${metric_namespace}_sub_libp2p_peerset_num_requested{instance=~\"${nodename}\"} - ${metric_namespace}_sub_libp2p_peers_count{instance=~\"${nodename}\"}) / ${metric_namespace}_sub_libp2p_peerset_num_requested{instance=~\"${nodename}\"}", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of peer slots filled", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1.0", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 29, + "panels": [], + "repeat": "request_protocol", + "title": "Requests (${request_protocol})", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 12, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 148, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(${metric_namespace}_sub_libp2p_requests_out_started_total{instance=~\"${nodename}\", protocol=\"${request_protocol}\"}[5m])", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Requests emitted per second", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 12, + "x": 12, + "y": 7 + }, + "hiddenSeries": false, + "id": 151, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(${metric_namespace}_sub_libp2p_requests_in_total_count{instance=~\"${nodename}\", protocol=\"${request_protocol}\"}[5m])", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Requests served per second", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "reqps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 12, + "x": 0, + "y": 11 + }, + "hiddenSeries": false, + "id": 146, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.5, sum(rate(${metric_namespace}_sub_libp2p_requests_out_finished_bucket{instance=~\"${nodename}\", protocol=\"${request_protocol}\"}[5m])) by (instance, le)) > 0", + "instant": false, + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Median request answer time", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 12, + "x": 12, + "y": 11 + }, + "hiddenSeries": false, + "id": 145, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.5, sum(rate(${metric_namespace}_sub_libp2p_requests_in_total_bucket{instance=~\"${nodename}\", protocol=\"${request_protocol}\"}[5m])) by (instance, le))", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Median request serving time", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 12, + "x": 0, + "y": 15 + }, + "hiddenSeries": false, + "id": 150, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(${metric_namespace}_sub_libp2p_requests_out_finished_bucket{instance=~\"${nodename}\", protocol=\"${request_protocol}\"}[5m])) by (instance, le)) > 0", + "instant": false, + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "99th percentile request answer time", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 12, + "x": 12, + "y": 15 + }, + "hiddenSeries": false, + "id": 149, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(${metric_namespace}_sub_libp2p_requests_in_total_bucket{instance=~\"${nodename}\", protocol=\"${request_protocol}\"}[5m])) by (instance, le))", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "99th percentile request serving time", + "tooltip": { + "shared": false, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 32 + }, + "id": 23, + "panels": [], + "repeat": "notif_protocol", + "title": "Notifications (${notif_protocol})", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 33 + }, + "hiddenSeries": false, + "id": 31, + "interval": "1m", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "maxPerRow": 2, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatDirection": "v", + "seriesOverrides": [ + { + "alias": "/(in)/", + "color": "#73BF69" + }, + { + "alias": "/(out)/", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg by (direction) (irate(${metric_namespace}_sub_libp2p_notifications_sizes_count{instance=~\"${nodename}\", protocol=\"${notif_protocol}\"}[$__interval]))", + "interval": "", + "legendFormat": "{{direction}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average network notifications per second", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "cps", + "label": "Notifs/sec", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 33 + }, + "hiddenSeries": false, + "id": 37, + "interval": "1m", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "maxPerRow": 2, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatDirection": "v", + "seriesOverrides": [ + { + "alias": "/(in)/", + "color": "#73BF69" + }, + { + "alias": "/(out)/", + "color": "#F2495C" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(irate(${metric_namespace}_sub_libp2p_notifications_sizes_sum{instance=~\"${nodename}\", protocol=\"${notif_protocol}\"}[$__interval])) by (direction)", + "instant": false, + "interval": "", + "legendFormat": "{{direction}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average bandwidth used by notifications", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": "Bandwidth", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 40 + }, + "hiddenSeries": false, + "id": 16, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "max(${metric_namespace}_sub_libp2p_out_events_notifications_sizes{instance=~\"${nodename}\", protocol=\"${notif_protocol}\", action=\"sent\"} - ignoring(action) ${metric_namespace}_sub_libp2p_out_events_notifications_sizes{instance=~\"${nodename}\", protocol=\"${notif_protocol}\", action=\"received\"}) by (instance) > 0", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total sizes of notifications waiting to be delivered to the rest of Substrate", + "tooltip": { + "shared": false, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 1, + "fillGradient": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 40 + }, + "hiddenSeries": false, + "id": 21, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "6.4.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(${metric_namespace}_sub_libp2p_notifications_sizes_sum{instance=~\"${nodename}\", protocol=\"${notif_protocol}\"}[5m])) by (direction, protocol) / sum(rate(${metric_namespace}_sub_libp2p_notifications_sizes_count{instance=~\"${nodename}\", protocol=\"${notif_protocol}\"}[5m])) by (direction, protocol)", + "format": "time_series", + "interval": "", + "legendFormat": "{{direction}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average size of sent and received notifications in the past 5 minutes", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "Max. notification size", + "logBase": 10, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "description": "99.9% of the time, the output queue size for this protocol is below the given value", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 46 + }, + "hiddenSeries": false, + "id": 14, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "hideEmpty": false, + "hideZero": true, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "max", + "fill": 1, + "linewidth": 0 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(${metric_namespace}_sub_libp2p_notifications_queues_size_bucket{instance=~\"${nodename}\", protocol=\"${notif_protocol}\"}[2m])) by (le, instance))", + "hide": false, + "interval": "", + "legendFormat": "{{protocol}}", + "refId": "A" + }, + { + "expr": "max(histogram_quantile(0.99, sum(rate(${metric_namespace}_sub_libp2p_notifications_queues_size_bucket{instance=~\"${nodename}\", protocol=\"${notif_protocol}\"}[2m])) by (le, instance)))", + "interval": "", + "legendFormat": "max", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "99th percentile of queues sizes", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": "300", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 1, + "fillGradient": 1, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 46 + }, + "hiddenSeries": false, + "id": 134, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pluginVersion": "6.4.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(1.0, sum(rate(${metric_namespace}_sub_libp2p_notifications_sizes_bucket{instance=~\"${nodename}\", protocol=\"${notif_protocol}\"}[5m])) by (direction, le))", + "format": "time_series", + "interval": "", + "legendFormat": "{{direction}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Maximum size of sent and received notifications in the past 5 minutes", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "Max. notification size", + "logBase": 10, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 96 + }, + "id": 27, + "panels": [], + "title": "Transport", + "type": "row" + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 97 + }, + "hiddenSeries": false, + "id": 19, + "interval": "1m", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "maxPerRow": 2, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatDirection": "v", + "seriesOverrides": [ + { + "alias": "established (in)", + "color": "#37872D" + }, + { + "alias": "established (out)", + "color": "#C4162A" + }, + { + "alias": "pending (out)", + "color": "#FF7383" + }, + { + "alias": "closed-recently", + "color": "#FADE2A", + "steppedLine": true + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "avg(sum(${metric_namespace}_sub_libp2p_connections_opened_total{direction=\"in\", instance=~\"${nodename}\"}) by (instance) - sum(${metric_namespace}_sub_libp2p_connections_closed_total{direction=\"in\", instance=~\"${nodename}\"}) by (instance))", + "format": "time_series", + "hide": false, + "interval": "", + "legendFormat": "established (in)", + "refId": "A" + }, + { + "expr": "avg(sum(${metric_namespace}_sub_libp2p_connections_opened_total{direction=\"out\", instance=~\"${nodename}\"}) by (instance) - sum(${metric_namespace}_sub_libp2p_connections_closed_total{direction=\"out\", instance=~\"${nodename}\"}) by (instance))", + "hide": false, + "instant": false, + "interval": "", + "legendFormat": "established (out)", + "refId": "C" + }, + { + "expr": "avg(sum by (instance) (${metric_namespace}_sub_libp2p_pending_connections{instance=~\"${nodename}\"}))", + "hide": false, + "interval": "", + "legendFormat": "pending (out)", + "refId": "B" + }, + { + "expr": "avg(sum by(instance) (increase(${metric_namespace}_sub_libp2p_connections_closed_total{instance=~\"${nodename}\"}[$__interval])))", + "hide": false, + "interval": "", + "legendFormat": "closed-recently", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average transport-level (TCP, QUIC, ...) connections per node", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "Connections", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 103 + }, + "hiddenSeries": false, + "id": 189, + "interval": "1m", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "maxPerRow": 2, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "repeatDirection": "v", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "1 - \n\navg(\n ${metric_namespace}_sub_libp2p_distinct_peers_connections_opened_total{instance=~\"${nodename}\"} - ${metric_namespace}_sub_libp2p_distinct_peers_connections_closed_total{instance=~\"${nodename}\"}\n) by (instance)\n\n/\n\navg(\r\n sum(${metric_namespace}_sub_libp2p_connections_opened_total{instance=~\"${nodename}\"}) by (instance) - sum(${metric_namespace}_sub_libp2p_connections_closed_total{instance=~\"${nodename}\"}) by (instance)\r\n) by (instance)", + "format": "time_series", + "hide": false, + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Percentage of peers for which we have more than one connection open", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 109 + }, + "hiddenSeries": false, + "id": 39, + "interval": "1m", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*/", + "color": "#FF780A" + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "avg(increase(${metric_namespace}_sub_libp2p_incoming_connections_handshake_errors_total{instance=~\"${nodename}\"}[$__interval])) by (reason)", + "interval": "", + "legendFormat": "{{reason}}", + "refId": "A" + }, + { + "expr": "avg(increase(${metric_namespace}_sub_libp2p_listeners_errors_total{instance=~\"${nodename}\"}[$__interval]))", + "interval": "", + "legendFormat": "pre-handshake", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of incoming connection errors, averaged by node", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "Errors", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cards": { + "cardPadding": null, + "cardRound": null + }, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateOranges", + "exponent": 0.5, + "max": 100, + "min": 0, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "datasource": "$data_source", + "description": "Each bucket represent a certain number of nodes using a certain bandwidth range.", + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 109 + }, + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "id": 4, + "legend": { + "show": false + }, + "reverseYBuckets": false, + "targets": [ + { + "expr": "${metric_namespace}_network_per_sec_bytes{instance=~\"${nodename}\"}", + "format": "time_series", + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Heatmap of network bandwidth", + "tooltip": { + "show": true, + "showHistogram": false + }, + "type": "heatmap", + "xAxis": { + "show": true + }, + "xBucketNumber": null, + "xBucketSize": "2.5m", + "yAxis": { + "decimals": null, + "format": "Bps", + "logBase": 1, + "max": null, + "min": null, + "show": true, + "splitFactor": null + }, + "yBucketBound": "auto", + "yBucketNumber": null, + "yBucketSize": null + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 115 + }, + "hiddenSeries": false, + "id": 81, + "interval": "1m", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatDirection": "v", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "avg(increase(${metric_namespace}_sub_libp2p_pending_connections_errors_total{instance=~\"${nodename}\"}[$__interval])) by (reason)", + "interval": "", + "legendFormat": "{{reason}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Dialing attempt errors, averaged per node", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 115 + }, + "hiddenSeries": false, + "id": 46, + "interval": "1m", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "maxPerRow": 2, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatDirection": "v", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "avg(increase(${metric_namespace}_sub_libp2p_connections_closed_total{instance=~\"${nodename}\"}[$__interval])) by (reason)", + "interval": "", + "legendFormat": "{{reason}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disconnects, averaged per node", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": "Disconnects", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 122 + }, + "id": 52, + "panels": [], + "title": "GrandPa", + "type": "row" + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 123 + }, + "hiddenSeries": false, + "id": 54, + "interval": "1m", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatDirection": "v", + "seriesOverrides": [ + { + "alias": "/discard/", + "color": "#FA6400", + "zindex": -2 + }, + { + "alias": "/keep/", + "color": "#73BF69", + "zindex": 2 + }, + { + "alias": "/process_and_discard/", + "color": "#5794F2" + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "avg(increase(${metric_namespace}_finality_grandpa_communication_gossip_validator_messages{instance=~\"${nodename}\"}[$__interval])) by (action, message)", + "interval": "", + "legendFormat": "{{message}} => {{action}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "GrandPa messages received from the network, and action", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 129 + }, + "id": 25, + "panels": [], + "repeat": null, + "title": "Kademlia & authority-discovery", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "description": "", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 130 + }, + "hiddenSeries": false, + "id": 33, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": true, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "${metric_namespace}_sub_libp2p_kbuckets_num_nodes{instance=~\"${nodename}\"}", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of entries in Kademlia k-buckets", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "max": 0, + "min": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 7, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 130 + }, + "hiddenSeries": false, + "id": 35, + "interval": "", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(${metric_namespace}_sub_libp2p_kademlia_random_queries_total{instance=~\"${nodename}\"}[5m])", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Kademlia random discovery queries started per second", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "cps", + "label": "Queries per second", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 12, + "x": 0, + "y": 135 + }, + "hiddenSeries": false, + "id": 111, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "${metric_namespace}_sub_libp2p_kademlia_records_count{instance=~\"${nodename}\"}", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of Kademlia records", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 12, + "x": 12, + "y": 135 + }, + "hiddenSeries": false, + "id": 112, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "${metric_namespace}_sub_libp2p_kademlia_records_sizes_total{instance=~\"${nodename}\"}", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total size of Kademlia records", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "description": "", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 139 + }, + "hiddenSeries": false, + "id": 211, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": true, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "${metric_namespace}_authority_discovery_known_authorities_count{instance=~\"${nodename}\"}", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of authorities discovered by authority-discovery", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "max": 0, + "min": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "description": "", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 139 + }, + "hiddenSeries": false, + "id": 233, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": true, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "${metric_namespace}_authority_discovery_amount_external_addresses_last_published{instance=~\"${nodename}\"}", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of addresses published by authority-discovery", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "max": 0, + "min": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 144 + }, + "hiddenSeries": false, + "id": 68, + "interval": "1m", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "repeat": null, + "repeatDirection": "v", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(${metric_namespace}_authority_discovery_dht_event_received{name=\"value_found\"}[2h]) / ignoring(name) (\n rate(${metric_namespace}_authority_discovery_dht_event_received{name=\"value_found\"}[2h]) +\n ignoring(name) rate(${metric_namespace}_authority_discovery_dht_event_received{name=\"value_not_found\"}[2h])\n)", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Authority discovery get_value success rate in past two hours", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1.0", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 144 + }, + "hiddenSeries": false, + "id": 234, + "interval": "1m", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "repeatDirection": "v", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(${metric_namespace}_authority_discovery_dht_event_received{name=\"value_put\"}[2h]) / ignoring(name) (\n rate(${metric_namespace}_authority_discovery_dht_event_received{name=\"value_put\"}[2h]) +\n ignoring(name) rate(${metric_namespace}_authority_discovery_dht_event_received{name=\"value_put_failed\"}[2h])\n)", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Authority discovery put_value success rate in past two hours", + "tooltip": { + "shared": true, + "sort": 1, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1.0", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "1m", + "schemaVersion": 22, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "$data_source", + "definition": "${metric_namespace}_cpu_usage_percentage", + "hide": 0, + "includeAll": true, + "index": -1, + "label": "Instance name filter", + "multi": true, + "name": "nodename", + "options": [], + "query": "${metric_namespace}_cpu_usage_percentage", + "refresh": 1, + "regex": "/instance=\"(.*?)\"/", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "$data_source", + "definition": "${metric_namespace}_sub_libp2p_notifications_sizes_count", + "hide": 2, + "includeAll": true, + "index": -1, + "label": null, + "multi": false, + "name": "notif_protocol", + "options": [], + "query": "${metric_namespace}_sub_libp2p_notifications_sizes_count", + "refresh": 1, + "regex": "/protocol=\"(.*?)\"/", + "skipUrlSync": false, + "sort": 5, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "$data_source", + "definition": "${metric_namespace}_sub_libp2p_requests_out_started_total", + "hide": 2, + "includeAll": true, + "index": -1, + "label": null, + "multi": false, + "name": "request_protocol", + "options": [], + "query": "${metric_namespace}_sub_libp2p_requests_out_started_total", + "refresh": 1, + "regex": "/protocol=\"(.*?)\"/", + "skipUrlSync": false, + "sort": 5, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "current": { + "selected": false, + "text": "prometheus.parity-mgmt", + "value": "prometheus.parity-mgmt" + }, + "hide": 0, + "includeAll": false, + "label": "Source of data", + "multi": false, + "name": "data_source", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "value": "${VAR_METRIC_NAMESPACE}", + "text": "${VAR_METRIC_NAMESPACE}" + }, + "hide": 2, + "label": "Prefix of the metrics", + "name": "metric_namespace", + "options": [ + { + "value": "${VAR_METRIC_NAMESPACE}", + "text": "${VAR_METRIC_NAMESPACE}" + } + ], + "query": "${VAR_METRIC_NAMESPACE}", + "skipUrlSync": false, + "type": "constant" + } + ] + }, + "time": { + "from": "now-24h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Substrate Networking", + "uid": "vKVuiD9Zk", + "variables": { + "list": [] + }, + "version": 113 +} diff --git a/.maintain/monitoring/grafana-dashboards/substrate-service-tasks.json b/.maintain/monitoring/grafana-dashboards/substrate-service-tasks.json new file mode 100644 index 0000000000000000000000000000000000000000..245071c210bfc48d815b6f963f3d51fbc4dd61b4 --- /dev/null +++ b/.maintain/monitoring/grafana-dashboards/substrate-service-tasks.json @@ -0,0 +1,1232 @@ +{ + "__inputs": [ + { + "name": "VAR_METRIC_NAMESPACE", + "type": "constant", + "label": "Prefix of the metrics", + "value": "polkadot", + "description": "" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "6.7.3" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + }, + { + "datasource": "$data_source", + "enable": true, + "expr": "increase(${metric_namespace}_tasks_ended_total{reason=\"panic\", instance=~\"${nodename}\"}[5m])", + "hide": true, + "iconColor": "rgba(255, 96, 96, 1)", + "limit": 100, + "name": "Task panics", + "rawQuery": "SELECT\n extract(epoch from time_column) AS time,\n text_column as text,\n tags_column as tags\nFROM\n metric_table\nWHERE\n $__timeFilter(time_column)\n", + "showIn": 0, + "step": "", + "tags": [], + "textFormat": "{{instance}} - {{task_name}}", + "titleFormat": "Panic!", + "type": "tags" + }, + { + "datasource": "$data_source", + "enable": true, + "expr": "changes(${metric_namespace}_process_start_time_seconds{instance=~\"${nodename}\"}[5m])", + "hide": false, + "iconColor": "#8AB8FF", + "name": "Node reboots", + "showIn": 0, + "step": "", + "textFormat": "{{instance}}", + "titleFormat": "Reboots" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "iteration": 1594822742772, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 25, + "panels": [], + "title": "CPU & Memory", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "stddev-above", + "fillBelowTo": "stddev-below", + "hideTooltip": true, + "lines": false + }, + { + "alias": "stddev-below", + "hideTooltip": true, + "lines": false + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(${metric_namespace}_cpu_usage_percentage{instance=~\"${nodename}\"})", + "interval": "", + "legendFormat": "cpu-usage", + "refId": "A" + }, + { + "expr": "avg(${metric_namespace}_cpu_usage_percentage{instance=~\"${nodename}\"}) - stddev(${metric_namespace}_cpu_usage_percentage{instance=~\"${nodename}\"})", + "interval": "", + "legendFormat": "stddev-below", + "refId": "B" + }, + { + "expr": "avg(${metric_namespace}_cpu_usage_percentage{instance=~\"${nodename}\"}) + stddev(${metric_namespace}_cpu_usage_percentage{instance=~\"${nodename}\"})", + "interval": "", + "legendFormat": "stddev-above", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average CPU usage and standard deviation", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 20, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "${metric_namespace}_memory_usage_bytes{instance=~\"${nodename}\"}", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory usage", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 29, + "panels": [], + "title": "Tasks", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 11, + "interval": "1m", + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "avg(increase(${metric_namespace}_tasks_polling_duration_sum{instance=~\"${nodename}\"}[$__interval])) by (task_name) * 1000 / $__interval_ms", + "interval": "", + "legendFormat": "{{task_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU time spent on each task (average per node)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 20 + }, + "hiddenSeries": false, + "id": 30, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "avg(rate(${metric_namespace}_tasks_polling_duration_count{instance=~\"${nodename}\"}[5m])) by (task_name)", + "interval": "", + "legendFormat": "{{task_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Task polling rate per second (average per node)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "cps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 26 + }, + "hiddenSeries": false, + "id": 31, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "max(rate(${metric_namespace}_tasks_polling_duration_count{instance=~\"${nodename}\"}[5m])) by (task_name)", + "interval": "", + "legendFormat": "{{task_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Task polling rate per second (maximum per node)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "cps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 32 + }, + "hiddenSeries": false, + "id": 15, + "interval": "", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "avg by(task_name) (irate(${metric_namespace}_tasks_spawned_total{instance=~\"${nodename}\"}[5m]))", + "interval": "", + "legendFormat": "{{task_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of tasks started per second (average per node)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 10, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 38 + }, + "hiddenSeries": false, + "id": 16, + "interval": "", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "max by(task_name) (irate(${metric_namespace}_tasks_spawned_total{instance=~\"${nodename}\"}[5m]))", + "interval": "", + "legendFormat": "{{task_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of tasks started per second (maximum over all nodes)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 10, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 44 + }, + "hiddenSeries": false, + "id": 2, + "interval": "", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "avg by(task_name) (${metric_namespace}_tasks_spawned_total{instance=~\"${nodename}\"} - sum(${metric_namespace}_tasks_ended_total{instance=~\"${nodename}\"}) without(reason))", + "interval": "", + "legendFormat": "{{task_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of tasks running (average per node)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 10, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 50 + }, + "hiddenSeries": false, + "id": 3, + "interval": "", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "max by(task_name) (${metric_namespace}_tasks_spawned_total{instance=~\"${nodename}\"} - sum(${metric_namespace}_tasks_ended_total{instance=~\"${nodename}\"}) without(reason))", + "interval": "", + "legendFormat": "{{task_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of tasks running (maximum over all nodes)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 10, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 56 + }, + "hiddenSeries": false, + "id": 7, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": true, + "targets": [ + { + "expr": "avg(\n rate(${metric_namespace}_tasks_polling_duration_bucket{instance=~\"${nodename}\", le=\"+Inf\"}[1m])\n - ignoring(le)\n rate(${metric_namespace}_tasks_polling_duration_bucket{instance=~\"${nodename}\", le=\"1.024\"}[1m])\n) by (task_name) > 0", + "interval": "", + "legendFormat": "{{task_name}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Calls to `Future::poll` that took more than one second (average per node)", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "cps", + "label": "Calls to `Future::poll`/second", + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 62 + }, + "id": 27, + "panels": [], + "title": "Misc", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$data_source", + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 63 + }, + "hiddenSeries": false, + "id": 23, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "${metric_namespace}_threads{instance=~\"${nodename}\"}", + "interval": "", + "legendFormat": "{{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Number of threads", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "30s", + "schemaVersion": 22, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "$data_source", + "definition": "${metric_namespace}_cpu_usage_percentage", + "hide": 0, + "includeAll": true, + "index": -1, + "label": "Instance filter", + "multi": true, + "name": "nodename", + "options": [], + "query": "${metric_namespace}_cpu_usage_percentage", + "refresh": 1, + "regex": "/instance=\"(.*?)\"/", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "current": { + "value": "${VAR_METRIC_NAMESPACE}", + "text": "${VAR_METRIC_NAMESPACE}" + }, + "hide": 2, + "label": "Prefix of the metrics", + "name": "metric_namespace", + "options": [ + { + "value": "${VAR_METRIC_NAMESPACE}", + "text": "${VAR_METRIC_NAMESPACE}" + } + ], + "query": "${VAR_METRIC_NAMESPACE}", + "skipUrlSync": false, + "type": "constant" + }, + { + "current": { + "selected": false, + "text": "prometheus.parity-mgmt", + "value": "prometheus.parity-mgmt" + }, + "hide": 0, + "includeAll": false, + "label": "Source of all the data", + "multi": false, + "name": "data_source", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-12h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Substrate Service Tasks", + "uid": "3LA6XNqZz", + "variables": { + "list": [] + }, + "version": 44 +} diff --git a/.maintain/rename-crates-for-2.0.sh b/.maintain/rename-crates-for-2.0.sh index 5d873d26cdfca69db389ae569b6be534d142af1d..01d559448438b3cb857d1b46af2f8bc544232066 100755 --- a/.maintain/rename-crates-for-2.0.sh +++ b/.maintain/rename-crates-for-2.0.sh @@ -64,7 +64,7 @@ TO_RENAME=( "substrate-keyring sp-keyring" "substrate-offchain-primitives sp-offchain" "substrate-panic-handler sp-panic-handler" - "substrate-phragmen sp-phragmen" + "substrate-phragmen sp-npos-elections" "substrate-rpc-primitives sp-rpc" "substrate-runtime-interface sp-runtime-interface" "substrate-runtime-interface-proc-macro sp-runtime-interface-proc-macro" diff --git a/.maintain/sentry-node/docker-compose.yml b/.maintain/sentry-node/docker-compose.yml index 376538dde5786e15d1524dc8f75072aa4c1cb59d..2af9449853c771be95d34c8a25aef8adc867d72c 100644 --- a/.maintain/sentry-node/docker-compose.yml +++ b/.maintain/sentry-node/docker-compose.yml @@ -47,9 +47,9 @@ services: - "--validator" - "--alice" - "--sentry-nodes" - - "/dns4/sentry-a/tcp/30333/p2p/QmV7EhW6J6KgmNdr558RH1mPx2xGGznW7At4BhXzntRFsi" + - "/dns/sentry-a/tcp/30333/p2p/QmV7EhW6J6KgmNdr558RH1mPx2xGGznW7At4BhXzntRFsi" - "--reserved-nodes" - - "/dns4/sentry-a/tcp/30333/p2p/QmV7EhW6J6KgmNdr558RH1mPx2xGGznW7At4BhXzntRFsi" + - "/dns/sentry-a/tcp/30333/p2p/QmV7EhW6J6KgmNdr558RH1mPx2xGGznW7At4BhXzntRFsi" # Not only bind to localhost. - "--unsafe-ws-external" - "--unsafe-rpc-external" @@ -83,11 +83,11 @@ services: - "--port" - "30333" - "--sentry" - - "/dns4/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" + - "/dns/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" - "--reserved-nodes" - - "/dns4/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" + - "/dns/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" - "--bootnodes" - - "/dns4/validator-b/tcp/30333/p2p/QmSVnNf9HwVMT1Y4cK1P6aoJcEZjmoTXpjKBmAABLMnZEk" + - "/dns/validator-b/tcp/30333/p2p/QmSVnNf9HwVMT1Y4cK1P6aoJcEZjmoTXpjKBmAABLMnZEk" - "--no-telemetry" - "--rpc-cors" - "all" @@ -118,9 +118,9 @@ services: - "--validator" - "--bob" - "--bootnodes" - - "/dns4/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" + - "/dns/validator-a/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR" - "--bootnodes" - - "/dns4/sentry-a/tcp/30333/p2p/QmV7EhW6J6KgmNdr558RH1mPx2xGGznW7At4BhXzntRFsi" + - "/dns/sentry-a/tcp/30333/p2p/QmV7EhW6J6KgmNdr558RH1mPx2xGGznW7At4BhXzntRFsi" - "--no-telemetry" - "--rpc-cors" - "all" @@ -131,11 +131,6 @@ services: - "sub-authority-discovery=trace" - "--prometheus-external" - ui: - image: polkadot-js/apps - ports: - - "3000:80" - prometheus: image: prom/prometheus networks: diff --git a/.maintain/sentry-node/prometheus/prometheus.yml b/.maintain/sentry-node/prometheus/prometheus.yml index 831b84ba0b7018948ae235619eb600b51e75c75d..547d4bea57ae5c55f210743165b347dd732ec0de 100644 --- a/.maintain/sentry-node/prometheus/prometheus.yml +++ b/.maintain/sentry-node/prometheus/prometheus.yml @@ -2,7 +2,7 @@ global: scrape_interval: 15s scrape_configs: - - job_name: 'substrate_validator-a' + - job_name: 'substrate-nodes' static_configs: - targets: ['validator-a:9615'] labels: diff --git a/Cargo.lock b/Cargo.lock index cae4d7c8f281e2a2e1cedae43e4e2ee73a67b354..18a7266d3ccc1d44d0cd374f545f438bb6886d49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,10 +11,39 @@ dependencies = [ ] [[package]] -name = "adler32" -version = "1.0.4" +name = "addr2line" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" +dependencies = [ + "gimli 0.22.0", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + +[[package]] +name = "aead" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" +dependencies = [ + "generic-array 0.14.3", +] + +[[package]] +name = "aes" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" +checksum = "f7001367fde4c768a19d1029f0a8be5abd9308e1119846d5bd9ad26297b8faf5" +dependencies = [ + "aes-soft 0.4.0", + "aesni 0.7.0", + "block-cipher", +] [[package]] name = "aes-ctr" @@ -22,10 +51,23 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2e5b0458ea3beae0d1d8c0f3946564f8e10f90646cf78c06b4351052058d1ee" dependencies = [ - "aes-soft", - "aesni", + "aes-soft 0.3.3", + "aesni 0.6.0", "ctr", - "stream-cipher", + "stream-cipher 0.3.2", +] + +[[package]] +name = "aes-gcm" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f5007801316299f922a6198d1d09a0bae95786815d066d5880d13f7c45ead1" +dependencies = [ + "aead", + "aes", + "block-cipher", + "ghash", + "subtle 2.2.3", ] [[package]] @@ -36,7 +78,18 @@ checksum = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d" dependencies = [ "block-cipher-trait", "byteorder 1.3.4", - "opaque-debug", + "opaque-debug 0.2.3", +] + +[[package]] +name = "aes-soft" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4925647ee64e5056cf231608957ce7c81e12d6d6e316b9ce1404778cc1d35fa7" +dependencies = [ + "block-cipher", + "byteorder 1.3.4", + "opaque-debug 0.2.3", ] [[package]] @@ -46,8 +99,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100" dependencies = [ "block-cipher-trait", - "opaque-debug", - "stream-cipher", + "opaque-debug 0.2.3", + "stream-cipher 0.3.2", +] + +[[package]] +name = "aesni" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050d39b0b7688b3a3254394c3e30a9d66c41dcf9b05b0e2dbdc623f6505d264" +dependencies = [ + "block-cipher", + "opaque-debug 0.2.3", ] [[package]] @@ -59,11 +122,17 @@ dependencies = [ "const-random", ] +[[package]] +name = "ahash" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" + [[package]] name = "aho-corasick" -version = "0.7.10" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" dependencies = [ "memchr", ] @@ -76,7 +145,7 @@ checksum = "4f823d037a7ec6ea2197046bafd4ae150e6bc36f9ca347404f46a46823fa84f2" dependencies = [ "approx", "num-complex", - "num-traits 0.2.11", + "num-traits", ] [[package]] @@ -85,7 +154,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -94,26 +163,14 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "anyhow" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a60d744a80c30fcb657dfe2c1b22bcb3e814c1a1e3674f32bf5820b570fbff" - -[[package]] -name = "app_dirs" -version = "1.2.1" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d" -dependencies = [ - "ole32-sys", - "shell32-sys", - "winapi 0.2.8", - "xdg", -] +checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" [[package]] name = "approx" @@ -121,20 +178,20 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" dependencies = [ - "num-traits 0.2.11", + "num-traits", ] [[package]] name = "arbitrary" -version = "0.4.1" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75153c95fdedd7db9732dfbfc3702324a1627eec91ba56e37cd0ac78314ab2ed" +checksum = "7cb544f1057eaaff4b34f8c4dcf56fc3cd04debd291998405d135017a7c3c0f4" [[package]] name = "arc-swap" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d663a8e9a99154b5fb793032533f6328da35e23aac63d5c152279aa8ba356825" +checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" [[package]] name = "arrayref" @@ -172,8 +229,8 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] @@ -195,54 +252,82 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5" +[[package]] +name = "async-channel" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee81ba99bee79f3c8ae114ae4baa7eaa326f63447cf2ec65e4393618b63f8770" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + [[package]] name = "async-std" -version = "1.5.0" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "538ecb01eb64eecd772087e5b6f7540cbc917f047727339a472dafed2185b267" +checksum = "00d68a33ebc8b57800847d00787307f84a562224a14db069b0acefe4c2abbf5d" dependencies = [ "async-task", - "broadcaster", - "crossbeam-channel", - "crossbeam-deque", "crossbeam-utils", + "futures-channel", "futures-core", "futures-io", - "futures-timer 2.0.2", + "futures-timer 3.0.2", "kv-log-macro", "log", "memchr", - "mio", - "mio-uds", "num_cpus", - "once_cell", + "once_cell 1.4.0", "pin-project-lite", "pin-utils", "slab", + "smol", + "wasm-bindgen-futures", ] [[package]] name = "async-task" -version = "1.3.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ac2c016b079e771204030951c366db398864f5026f84a44dafb0ff20f02085d" -dependencies = [ - "libc", - "winapi 0.3.8", -] +checksum = "c17772156ef2829aadc587461c7753af20b7e8db1529bc66855add962a3b35d3" [[package]] name = "async-tls" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fd83426b89b034bf4e9ceb9c533c2f2386b813fd3dcae0a425ec6f1837d78a" +checksum = "df097e3f506bec0e1a24f06bb3c962c228f36671de841ff579cb99f371772634" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "rustls", "webpki", "webpki-roots 0.19.0", ] +[[package]] +name = "async-trait" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caae68055714ff28740f310927e04f2eba76ff580b16fb18ed90073ee71646f7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f46ca51dca4837f1520754d1c8c36636356b81553d928dc9c177025369a06e" + +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + [[package]] name = "atty" version = "0.2.14" @@ -251,7 +336,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -268,26 +353,18 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] name = "backtrace" -version = "0.3.46" +version = "0.3.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e" +checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293" dependencies = [ - "backtrace-sys", + "addr2line", "cfg-if", "libc", + "miniz_oxide", + "object 0.20.0", "rustc-demangle", ] -[[package]] -name = "backtrace-sys" -version = "0.1.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8aba10a69c8e8d7622c5710229485ec32e9d55fdad160ea559c086fdcd118" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "base58" version = "0.1.0" @@ -302,15 +379,15 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" [[package]] name = "base64" -version = "0.12.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5ca2cd0adc3f48f9e9ea5a6bbdf9ccc0bfade884847e484d452414c7ccffb3" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] name = "bincode" -version = "1.2.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf" +checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d" dependencies = [ "byteorder 1.3.4", "serde", @@ -318,28 +395,43 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.53.2" +version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb26d6a69a335b8cb0e7c7e9775cd5666611dc50a37177c3f2cedcfc040e8c8" +checksum = "c72a978d268b1d70b0e963217e60fdabd9523a941457a6c42a7315d15c7e89e5" dependencies = [ "bitflags", "cexpr", "cfg-if", "clang-sys", "clap", - "env_logger 0.7.1", + "env_logger", "lazy_static", "lazycell", "log", "peeking_take_while", "proc-macro2", - "quote 1.0.3", + "quote", "regex", "rustc-hash", "shlex", "which", ] +[[package]] +name = "bip39" +version = "0.6.0-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059804e226b3ac116519a252d7f5fb985a5ccc0e93255e036a5f7e7283323f4" +dependencies = [ + "failure", + "hashbrown 0.1.8", + "hmac", + "once_cell 0.1.8", + "pbkdf2", + "rand 0.6.5", + "sha2 0.8.2", +] + [[package]] name = "bitflags" version = "1.2.1" @@ -364,14 +456,15 @@ dependencies = [ [[package]] name = "blake2" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" +checksum = "84ce5b6108f8e154604bd4eb76a2f726066c3464d5a552a4229262a18c9bb471" dependencies = [ "byte-tools", - "crypto-mac", - "digest", - "opaque-debug", + "byteorder 1.3.4", + "crypto-mac 0.8.0", + "digest 0.9.0", + "opaque-debug 0.2.3", ] [[package]] @@ -415,7 +508,25 @@ dependencies = [ "block-padding", "byte-tools", "byteorder 1.3.4", - "generic-array", + "generic-array 0.12.3", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.3", +] + +[[package]] +name = "block-cipher" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa136449e765dc7faa244561ccae839c394048667929af599b5d931ebe7b7f10" +dependencies = [ + "generic-array 0.14.3", ] [[package]] @@ -424,7 +535,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" dependencies = [ - "generic-array", + "generic-array 0.12.3", ] [[package]] @@ -437,30 +548,30 @@ dependencies = [ ] [[package]] -name = "broadcaster" -version = "1.0.0" +name = "blocking" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c972e21e0d055a36cf73e4daae870941fe7a8abcd5ac3396aab9e4c126bd87" +checksum = "d2468ff7bf85066b4a3678fede6fe66db31846d753ff0adfbfab2c6a6e81612b" dependencies = [ - "futures-channel", - "futures-core", - "futures-sink", - "futures-util", - "parking_lot 0.10.2", - "slab", + "async-channel", + "atomic-waker", + "futures-lite", + "once_cell 1.4.0", + "parking", + "waker-fn", ] [[package]] name = "bs58" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae" +checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" [[package]] name = "bstr" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41" +checksum = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931" dependencies = [ "lazy_static", "memchr", @@ -479,9 +590,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.2.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187" +checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" [[package]] name = "byte-slice-cast" @@ -520,9 +631,9 @@ dependencies = [ [[package]] name = "bytes" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "c_linked_list" @@ -530,13 +641,19 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4964518bd3b4a8190e832886cdc0da9794f12e8e6c1613a9e90ff331c4c8724b" +[[package]] +name = "cache-padded" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" + [[package]] name = "cargo_metadata" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" +checksum = "052dbdd9db69a339d5fa9ac87bfe2e1319f709119f0345988a597af82bb1011c" dependencies = [ - "semver 0.9.0", + "semver 0.10.0", "serde", "serde_derive", "serde_json", @@ -553,9 +670,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.50" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" +checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518" dependencies = [ "jobserver", ] @@ -576,17 +693,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] -name = "chacha20-poly1305-aead" -version = "0.1.2" +name = "chacha20" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77d2058ba29594f69c75e8a9018e0485e3914ca5084e3613cd64529042f5423b" +checksum = "086c0f07ac275808b7bf9a39f2fd013aae1498be83632814c8c4e0bd53f2dc58" dependencies = [ - "constant_time_eq", + "stream-cipher 0.4.1", + "zeroize", +] + +[[package]] +name = "chacha20poly1305" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18b0c90556d8e3fec7cf18d84a2f53d27b21288f2fe481b830fadcf809e48205" +dependencies = [ + "aead", + "chacha20", + "poly1305", + "stream-cipher 0.4.1", + "zeroize", ] [[package]] name = "chain-spec-builder" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "ansi_term 0.12.1", "node-cli", @@ -599,13 +730,13 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" +checksum = "c74d84029116787153e02106bf53e66828452a4b325cc8652b788b5967c0a0b6" dependencies = [ "js-sys", "num-integer", - "num-traits 0.2.11", + "num-traits", "time", "wasm-bindgen", ] @@ -623,9 +754,9 @@ dependencies = [ [[package]] name = "clap" -version = "2.33.0" +version = "2.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" dependencies = [ "ansi_term 0.11.0", "atty", @@ -636,15 +767,6 @@ dependencies = [ "vec_map", ] -[[package]] -name = "clear_on_drop" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" -dependencies = [ - "cc", -] - [[package]] name = "cloudabi" version = "0.0.3" @@ -656,13 +778,22 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.42" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" +checksum = "0e56268c17a6248366d66d4a47a3381369d068cce8409bb1716ed77ea32163bb" dependencies = [ "cc", ] +[[package]] +name = "concurrent-queue" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83c06aff61f2d899eb87c379df3cbf7876f14471dcab474e0b6dc90ab96c080" +dependencies = [ + "cache-padded", +] + [[package]] name = "console_error_panic_hook" version = "0.1.6" @@ -725,40 +856,46 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" +[[package]] +name = "cpuid-bool" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" + [[package]] name = "cranelift-bforest" -version = "0.63.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4425bb6c3f3d2f581c650f1a1fdd3196a975490149cf59bea9d34c3bea79eda" +checksum = "8dcc286b052ee24a1e5a222e7c1125e6010ad35b0f248709b9b3737a8fedcfdf" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.63.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d166b289fd30062ee6de86284750fc3fe5d037c6b864b3326ce153239b0626e1" +checksum = "9d9badfe36176cb653506091693bc2bb1970c9bddfcd6ec7fac404f7eaec6f38" dependencies = [ "byteorder 1.3.4", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", "cranelift-entity", - "gimli", + "gimli 0.21.0", "log", "regalloc", "serde", - "smallvec 1.3.0", + "smallvec 1.4.1", "target-lexicon", "thiserror", ] [[package]] name = "cranelift-codegen-meta" -version = "0.63.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c9fb2306a36d41c5facd4bf3400bc6c157185c43a96eaaa503471c34c5144b" +checksum = "3c3f460031861e4f4ad510be62b2ae50bba6cc886b598a36f9c0a970feab9598" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -766,36 +903,36 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.63.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44e0cfe9b1f97d9f836bca551618106c7d53b93b579029ecd38e73daa7eb689e" +checksum = "76ad12409e922e7697cd0bdc7dc26992f64a77c31880dfe5e3c7722f4710206d" [[package]] name = "cranelift-entity" -version = "0.63.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926a73c432e5ba9c891171ff50b75e7d992cd76cd271f0a0a0ba199138077472" +checksum = "d97cdc58972ea065d107872cfb9079f4c92ade78a8af85aaff519a65b5d13f71" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.63.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e45f82e3446dd1ebb8c2c2f6a6b0e6cd6cd52965c7e5f7b1b35e9a9ace31ccde" +checksum = "2ef419efb4f94ecc02e5d9fbcc910d2bb7f0040e2de570e63a454f883bc891d6" dependencies = [ "cranelift-codegen", "log", - "smallvec 1.3.0", + "smallvec 1.4.1", "target-lexicon", ] [[package]] name = "cranelift-native" -version = "0.63.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488b5d481bb0996a143e55a9d1739ef425efa20d4a5e5e98c859a8573c9ead9a" +checksum = "6e69d44d59826eef6794066ac2c0f4ad3975f02d97030c60dbc04e3886adf36e" dependencies = [ "cranelift-codegen", "raw-cpuid", @@ -804,9 +941,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.63.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00aa8dde71fd9fdb1958e7b0ef8f524c1560e2c6165e4ea54bc302b40551c161" +checksum = "979df666b1304624abe99738e9e0e7c7479ee5523ba4b8b237df9ff49996acbb" dependencies = [ "cranelift-codegen", "cranelift-entity", @@ -814,7 +951,7 @@ dependencies = [ "log", "serde", "thiserror", - "wasmparser 0.51.4", + "wasmparser 0.59.0", ] [[package]] @@ -828,50 +965,24 @@ dependencies = [ [[package]] name = "criterion" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394" -dependencies = [ - "atty", - "cast", - "clap", - "criterion-plot 0.3.1", - "csv", - "itertools", - "lazy_static", - "libc", - "num-traits 0.2.11", - "rand_core 0.3.1", - "rand_os", - "rand_xoshiro", - "rayon", - "rayon-core", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc755679c12bda8e5523a71e4d654b6bf2e14bd838dfc48cde6559a05caf7d1" +checksum = "70daa7ceec6cf143990669a04c7df13391d55fb27bd4079d252fca774ba244d8" dependencies = [ "atty", "cast", "clap", - "criterion-plot 0.4.1", + "criterion-plot", "csv", - "itertools", + "itertools 0.9.0", "lazy_static", - "num-traits 0.2.11", + "num-traits", "oorandom", "plotters", "rayon", "regex", "serde", + "serde_cbor", "serde_derive", "serde_json", "tinytemplate", @@ -880,33 +991,12 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e" -dependencies = [ - "byteorder 1.3.4", - "cast", - "itertools", -] - -[[package]] -name = "criterion-plot" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01e15e0ea58e8234f96146b1f91fa9d0e4dd7a38da93ff7a75d42c0b9d3a545" +checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d" dependencies = [ "cast", - "itertools", -] - -[[package]] -name = "crossbeam-channel" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061" -dependencies = [ - "crossbeam-utils", - "maybe-uninit", + "itertools 0.9.0", ] [[package]] @@ -932,17 +1022,18 @@ dependencies = [ "lazy_static", "maybe-uninit", "memoffset", - "scopeguard", + "scopeguard 1.1.0", ] [[package]] name = "crossbeam-queue" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" +checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" dependencies = [ "cfg-if", "crossbeam-utils", + "maybe-uninit", ] [[package]] @@ -968,10 +1059,20 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" dependencies = [ - "generic-array", + "generic-array 0.12.3", "subtle 1.0.0", ] +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array 0.14.3", + "subtle 2.2.3", +] + [[package]] name = "csv" version = "1.1.3" @@ -996,21 +1097,21 @@ dependencies = [ [[package]] name = "ct-logs" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3686f5fa27dbc1d76c751300376e167c5a43387f44bb451fd1c24776e49113" +checksum = "8c8e13110a84b6315df212c045be706af261fd364791cad863285439ebba672e" dependencies = [ "sct", ] [[package]] name = "ctor" -version = "0.1.13" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c5e5ac752e18207b12e16b10631ae5f7f68f8805f335f9b817ead83d9ffce1" +checksum = "39858aa5bac06462d4dd4b9164848eb81ffc4aa5c479746393598fd193afa227" dependencies = [ - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] @@ -1020,7 +1121,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "022cd691704491df67d25d006fe8eca083098253c4d43516c2206479c58c6736" dependencies = [ "block-cipher-trait", - "stream-cipher", + "stream-cipher 0.3.2", ] [[package]] @@ -1035,32 +1136,32 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" +checksum = "5d85653f070353a16313d0046f173f70d1aadd5b42600a14de626f0dfb3473a5" dependencies = [ "byteorder 1.3.4", - "digest", + "digest 0.8.1", "rand_core 0.5.1", - "subtle 2.2.2", + "subtle 2.2.3", "zeroize", ] [[package]] name = "data-encoding" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c0346158a19b3627234e15596f5e465c360fcdb97d817bcb255e0510f5a788" +checksum = "72aa14c04dfae8dd7d8a2b1cb7ca2152618cd01336dbfe704b8dcbf8d41dbd69" [[package]] name = "derive_more" -version = "0.99.5" +version = "0.99.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2323f3f47db9a0e77ce7a300605d8d2098597fc451ed1a97bb1f6411bb550a7" +checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] @@ -1075,7 +1176,16 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" dependencies = [ - "generic-array", + "generic-array 0.12.3", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.3", ] [[package]] @@ -1090,16 +1200,21 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" dependencies = [ - "cfg-if", "libc", "redox_users", - "winapi 0.3.8", + "winapi 0.3.9", ] +[[package]] +name = "dissimilar" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4b29f4b9bb94bf267d57269fd0706d343a160937108e9619fe380645428abb" + [[package]] name = "dns-parser" version = "0.8.0" @@ -1116,16 +1231,54 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "dyn-clonable" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" +dependencies = [ + "dyn-clonable-impl", + "dyn-clone", +] + +[[package]] +name = "dyn-clonable-impl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dyn-clone" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c53dc3a653e0f64081026e4bf048d48fec9fce90c66e8326ca7292df0ff2d82" + +[[package]] +name = "ed25519" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf038a7b6fd7ef78ad3348b63f3a17550877b0e28f8d68bcc94894d1412158bc" +dependencies = [ + "signature", +] + [[package]] name = "ed25519-dalek" -version = "1.0.0-pre.3" +version = "1.0.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978710b352437433c97b2bff193f2fb1dfd58a093f863dd95e225a19baa599a2" +checksum = "21a8a37f4e8b35af971e6db5e3897e7a6344caa3f92f6544f88125a1f5f0035a" dependencies = [ - "clear_on_drop", "curve25519-dalek", + "ed25519", "rand 0.7.3", - "sha2", + "serde", + "sha2 0.8.2", + "zeroize", ] [[package]] @@ -1134,48 +1287,24 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" -[[package]] -name = "enum-primitive-derive" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b90e520ec62c1864c8c78d637acbfe8baf5f63240f2fb8165b8325c07812dd" -dependencies = [ - "num-traits 0.1.43", - "quote 0.3.15", - "syn 0.11.11", -] - [[package]] name = "enumflags2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a80e524ebf194285b57e5e7944018721c7fffc673253f5183f7accd88a2a3b0c" +checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ed9afacaea0301eefb738c9deea725e6d53938004597cdc518a8cf9a7aa2f03" +checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", -] - -[[package]] -name = "env_logger" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", + "quote", + "syn", ] [[package]] @@ -1199,22 +1328,22 @@ checksum = "516aa8d7a71cb00a1c4146f0798549b93d083d4f189b3ced8f3de6b8f11ee6c4" [[package]] name = "erased-serde" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d88b6d1705e16a4d62e05ea61cc0496c2bd190f4fa8e5c1f11ce747be6bcf3d1" +checksum = "6ca8b296792113e1500fd935ae487be6e00ce318952a6880555554824d6ebf38" dependencies = [ "serde", ] [[package]] name = "errno" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b480f641ccf0faf324e20c1d3e53d81b7484c698b42ea677f6907ae4db195371" +checksum = "6eab5ee3df98a279d9b316b1af6ac95422127b1290317e6d18c1743c99418b01" dependencies = [ "errno-dragonfly", "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1227,11 +1356,44 @@ dependencies = [ "libc", ] +[[package]] +name = "ethbloom" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71a6567e6fd35589fea0c63b94b4cf2e55573e413901bdbe60ab15cf0e25e5df" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-rlp", + "impl-serde", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473aecff686bd8e7b9db0165cbbb53562376b39bf35b427f0c60446a9e1634b0" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-rlp", + "impl-serde", + "primitive-types", + "uint", +] + +[[package]] +name = "event-listener" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "699d84875f1b72b4da017e6b0f77dfa88c0137f089958a88974d15938cbc2976" + [[package]] name = "evm" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a5c0ebf219b2b878bde1838282e0bb69828338df37fd136f1e93182ae35a59" +checksum = "68224b0aa788720ef0c8a23030a4412a021ed73df069a922bee8f0db9ed617e2" dependencies = [ "evm-core", "evm-gasometer", @@ -1244,18 +1406,18 @@ dependencies = [ [[package]] name = "evm-core" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d944a07232006a3435df8aa014fd364ed04cb28d731782339e9c56436594f2d4" +checksum = "4a040378759577447945c89da1b07d6e33fda32a97a104afe0ec3fa1c382949d" dependencies = [ "primitive-types", ] [[package]] name = "evm-gasometer" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a0d986953234d3786d0ca1beaaabab6a581d2128f8ec36c8c57e9c45e3d2b32" +checksum = "7bb5bc051afad6bb0735c82b46656bbdfac41917861307a608b1404a546fec42" dependencies = [ "evm-core", "evm-runtime", @@ -1264,9 +1426,9 @@ dependencies = [ [[package]] name = "evm-runtime" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1833c22f9518007d3cc28e14ff586263543516a1c7a147b260c603e4deb95403" +checksum = "7410f5677a52203d3fca02b0eb8f96f9799f3a45cff82946a8ed28379e6b1b04" dependencies = [ "evm-core", "primitive-types", @@ -1279,29 +1441,14 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e43f2f1833d64e33f15592464d6fdd70f349dda7b1a53088eb83cd94014008c5" dependencies = [ - "futures 0.3.4", -] - -[[package]] -name = "faerie" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfef65b0e94693295c5d2fe2506f0ee6f43465342d4b5331659936aee8b16084" -dependencies = [ - "goblin", - "indexmap", - "log", - "scroll", - "string-interner", - "target-lexicon", - "thiserror", + "futures 0.3.5", ] [[package]] name = "failure" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" dependencies = [ "backtrace", "failure_derive", @@ -1309,13 +1456,13 @@ dependencies = [ [[package]] name = "failure_derive" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", "synstructure", ] @@ -1331,6 +1478,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fastrand" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a9cb09840f81cd211e435d00a4e487edd263dc3c8ff815c32dd76ad668ebed" + [[package]] name = "fdlimit" version = "0.1.4" @@ -1342,11 +1495,11 @@ dependencies = [ [[package]] name = "file-per-thread-logger" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505b75b31ef7285168dd237c4a7db3c1f3e0927e7d314e670bc98e854272fe9" +checksum = "8b3937f028664bd0e13df401ba49a4567ccda587420365823242977f06609ed1" dependencies = [ - "env_logger 0.6.2", + "env_logger", "log", ] @@ -1357,10 +1510,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8feb87a63249689640ac9c011742c33139204e3c134293d3054022276869133b" dependencies = [ "either", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 2.0.2", "log", - "num-traits 0.2.11", + "num-traits", "parity-scale-codec", "parking_lot 0.9.0", "rand 0.6.5", @@ -1368,9 +1521,9 @@ dependencies = [ [[package]] name = "fixed-hash" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32529fc42e86ec06e5047092082aab9ad459b070c5d2a76b14f4f5ce70bf2e84" +checksum = "11498d382790b7a8f2fd211780bec78619bba81cdad3a283997c0c41f836759c" dependencies = [ "byteorder 1.3.4", "rand 0.7.3", @@ -1386,9 +1539,9 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" +checksum = "68c90b0fc46cf89d227cc78b40e494ff81287a92dd07631e5af0d06fe3cf885e" dependencies = [ "cfg-if", "crc32fast", @@ -1399,23 +1552,24 @@ dependencies = [ [[package]] name = "fnv" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", ] [[package]] name = "frame-benchmarking" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", + "hex-literal", "linregress", "parity-scale-codec", "paste", @@ -1424,11 +1578,12 @@ dependencies = [ "sp-runtime", "sp-runtime-interface", "sp-std", + "sp-storage", ] [[package]] name = "frame-benchmarking-cli" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "parity-scale-codec", @@ -1445,7 +1600,7 @@ dependencies = [ [[package]] name = "frame-executive" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -1465,7 +1620,7 @@ dependencies = [ [[package]] name = "frame-metadata" -version = "11.0.0-dev" +version = "11.0.0-rc6" dependencies = [ "parity-scale-codec", "serde", @@ -1475,7 +1630,7 @@ dependencies = [ [[package]] name = "frame-support" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "bitmask", "frame-metadata", @@ -1483,11 +1638,13 @@ dependencies = [ "frame-system", "impl-trait-for-tuples", "log", - "once_cell", + "once_cell 1.4.0", "parity-scale-codec", + "parity-util-mem", "paste", "pretty_assertions", "serde", + "smallvec 1.4.1", "sp-arithmetic", "sp-core", "sp-inherents", @@ -1500,37 +1657,37 @@ dependencies = [ [[package]] name = "frame-support-procedural" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support-procedural-tools", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "frame-support-procedural-tools" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "frame-support-procedural-tools-derive" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "frame-support-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "parity-scale-codec", @@ -1542,14 +1699,15 @@ dependencies = [ "sp-io", "sp-runtime", "sp-state-machine", + "sp-std", "trybuild", ] [[package]] name = "frame-system" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "criterion 0.2.11", + "criterion", "frame-support", "impl-trait-for-tuples", "parity-scale-codec", @@ -1565,7 +1723,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -1580,7 +1738,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "sp-api", @@ -1595,7 +1753,7 @@ dependencies = [ "lazy_static", "libc", "libloading", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1605,7 +1763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" dependencies = [ "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -1644,9 +1802,9 @@ checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" [[package]] name = "futures" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780" +checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613" dependencies = [ "futures-channel", "futures-core", @@ -1659,9 +1817,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8" +checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" dependencies = [ "futures-core", "futures-sink", @@ -1678,9 +1836,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" +checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" [[package]] name = "futures-core-preview" @@ -1705,7 +1863,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdcef58a173af8148b182684c9f2d5250875adbcaff7b5794073894f9d8634a9" dependencies = [ "futures 0.1.29", - "futures 0.3.4", + "futures 0.3.5", "lazy_static", "log", "parking_lot 0.9.0", @@ -1716,9 +1874,9 @@ dependencies = [ [[package]] name = "futures-executor" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba" +checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314" dependencies = [ "futures-core", "futures-task", @@ -1728,33 +1886,51 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.4" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" + +[[package]] +name = "futures-lite" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6" +checksum = "180d8fc9819eb48a0c976672fbeea13a73e10999e812bdc9e14644c25ad51d60" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] [[package]] name = "futures-macro" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" +checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39" dependencies = [ "proc-macro-hack", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "futures-sink" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6" +checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" [[package]] name = "futures-task" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27" +checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" +dependencies = [ + "once_cell 1.4.0", +] [[package]] name = "futures-timer" @@ -1774,9 +1950,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5" +checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" dependencies = [ "futures 0.1.29", "futures-channel", @@ -1786,6 +1962,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", + "pin-project", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -1806,12 +1983,12 @@ dependencies = [ [[package]] name = "futures_codec" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a73299e4718f5452e45980fc1d6957a070abe308d3700b63b8673f47e1c2b3" +checksum = "ce54d63f8b0c75023ed920d46fd71d0cbbb830b0ee012726b5b4f506fb6dea5b" dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", + "bytes 0.5.6", + "futures 0.3.5", "memchr", "pin-project", ] @@ -1831,6 +2008,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "generic-array" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60fb4bb6bba52f78a471264d9a3b7d026cc0af47b22cd2cffbc0b787ca003e63" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "get_if_addrs" version = "0.5.3" @@ -1865,20 +2052,32 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "ghash" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6e27f0689a6e15944bdce7e45425efb87eaa8ab0c6e87f11d0987a9133e2531" +dependencies = [ + "polyval", +] + [[package]] name = "gimli" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dd6190aad0f05ddbbf3245c54ed14ca4aa6dd32f22312b70d8f168c3e3e633" +checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" dependencies = [ - "arrayvec 0.5.1", - "byteorder 1.3.4", "fallible-iterator", "indexmap", - "smallvec 1.3.0", "stable_deref_trait", ] +[[package]] +name = "gimli" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" + [[package]] name = "glob" version = "0.2.11" @@ -1917,17 +2116,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "goblin" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3081214398d39e4bd7f2c1975f0488ed04614ffdd976c6fc7a0708278552c0da" -dependencies = [ - "log", - "plain", - "scroll", -] - [[package]] name = "h2" version = "0.1.26" @@ -1948,23 +2136,29 @@ dependencies = [ [[package]] name = "h2" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377038bf3c89d18d6ca1431e7a5027194fbd724ca10592b9487ede5e8e144f42" +checksum = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "fnv", "futures-core", "futures-sink", "futures-util", "http 0.2.1", "indexmap", - "log", "slab", - "tokio 0.2.18", + "tokio 0.2.22", "tokio-util", + "tracing", ] +[[package]] +name = "half" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177" + [[package]] name = "hash-db" version = "0.15.2" @@ -1980,16 +2174,36 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hashbrown" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" +dependencies = [ + "byteorder 1.3.4", + "scopeguard 0.3.3", +] + [[package]] name = "hashbrown" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" dependencies = [ - "ahash", + "ahash 0.2.18", "autocfg 0.1.7", ] +[[package]] +name = "hashbrown" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb" +dependencies = [ + "ahash 0.3.8", + "autocfg 1.0.0", +] + [[package]] name = "heck" version = "0.3.1" @@ -2001,9 +2215,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.10" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e" +checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" dependencies = [ "libc", ] @@ -2016,22 +2230,15 @@ checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" [[package]] name = "hex-literal" -version = "0.2.1" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "961de220ec9a91af2e1e5bd80d02109155695e516771762381ef8581317066e0" -dependencies = [ - "hex-literal-impl", - "proc-macro-hack", -] +checksum = "5af1f635ef1bc545d78392b136bfe1c9809e029023c84a3638a864a10b8819c8" [[package]] -name = "hex-literal-impl" -version = "0.2.1" +name = "hex_fmt" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d4c5c844e2fee0bf673d54c2c177f1713b3d2af2ff6e666b49cb7572e6cf42d" -dependencies = [ - "proc-macro-hack", -] +checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" [[package]] name = "hmac" @@ -2039,8 +2246,8 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" dependencies = [ - "crypto-mac", - "digest", + "crypto-mac 0.7.0", + "digest 0.8.1", ] [[package]] @@ -2049,16 +2256,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" dependencies = [ - "digest", - "generic-array", + "digest 0.8.1", + "generic-array 0.12.3", "hmac", ] [[package]] name = "honggfuzz" -version = "0.5.47" +version = "0.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3de2c3273ef7735df1c5a72128ca85b1d20105b9aac643cdfd7a6e581311150" +checksum = "832bac18a82ec7d6c21887daa8616b238fe90d5d5e762d0d4b9372cdaa9e097f" dependencies = [ "arbitrary", "lazy_static", @@ -2082,7 +2289,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "fnv", "itoa", ] @@ -2105,7 +2312,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "http 0.2.1", ] @@ -2156,42 +2363,42 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.4" +version = "0.13.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6081100e960d9d74734659ffc9cc91daf1c0fc7aceb8eaa94ee1a3f5046f2e" +checksum = "3e68a8dd9716185d9e64ea473ea6ef63529252e3e27623295a0378a19665d5eb" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "futures-channel", "futures-core", "futures-util", - "h2 0.2.4", + "h2 0.2.6", "http 0.2.1", "http-body 0.3.1", "httparse", "itoa", - "log", - "net2", "pin-project", + "socket2", "time", - "tokio 0.2.18", + "tokio 0.2.22", "tower-service", + "tracing", "want 0.3.0", ] [[package]] name = "hyper-rustls" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac965ea399ec3a25ac7d13b8affd4b8f39325cca00858ddf5eb29b79e6b14b08" +checksum = "37743cc83e8ee85eacfce90f2f4102030d9ff0a95244098d781e9bee4a90abb6" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "ct-logs", "futures-util", - "hyper 0.13.4", + "hyper 0.13.7", "log", "rustls", "rustls-native-certs", - "tokio 0.2.18", + "tokio 0.2.22", "tokio-rustls", "webpki", ] @@ -2238,18 +2445,9 @@ dependencies = [ [[package]] name = "impl-serde" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-serde" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bbe9ea9b182f0fb1cabbd61f4ff9b7b7b9197955e95a7e4c27de5055eb29ff8" +checksum = "b47ca4d2b6931707a55fce5cf66aff80e2178c8b63bbb4ecb5695cbc870ddf6f" dependencies = [ "serde", ] @@ -2261,17 +2459,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef5550a42e3740a0e71f909d4c861056a284060af885ae7aa6242820f920d9d" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "indexmap" -version = "1.3.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" +checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7" dependencies = [ "autocfg 1.0.0", + "hashbrown 0.8.1", + "serde", ] [[package]] @@ -2280,19 +2480,13 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" -[[package]] -name = "interleaved-ordered" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "141340095b15ed7491bd3d4ced9d20cebfb826174b6bb03386381f62b01e3d77" - [[package]] name = "intervalier" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64fa110ec7b8f493f416eed552740d10e7030ad5f63b2308f82c9608ec2df275" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "futures-timer 2.0.2", ] @@ -2326,11 +2520,20 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" +checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" [[package]] name = "jobserver" @@ -2343,18 +2546,18 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.37" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055" +checksum = "fa5a448de267e7358beaf4a5d849518fe9a0c13fce7afd44b06e68550e5562a7" dependencies = [ "wasm-bindgen", ] [[package]] name = "jsonrpc-client-transports" -version = "14.1.0" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2307a7e78cf969759e390a8a2151ea12e783849a45bb00aa871b468ba58ea79e" +checksum = "ecbdaacc17243168d9d1fa6b2bd7556a27e1e60a621d8a2a6e590ae2b145d158" dependencies = [ "failure", "futures 0.1.29", @@ -2369,9 +2572,9 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "14.1.0" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25525f6002338fb4debb5167a89a0b47f727a5a48418417545ad3429758b7fec" +checksum = "a0747307121ffb9703afd93afbd0fb4f854c38fb873f2c8b90e0e902f27c7b62" dependencies = [ "futures 0.1.29", "log", @@ -2382,30 +2585,30 @@ dependencies = [ [[package]] name = "jsonrpc-core-client" -version = "14.1.0" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f9382e831a6d630c658df103aac3f971da096deb57c136ea2b760d3b4e3f9f" +checksum = "34221123bc79b66279a3fde2d3363553835b43092d629b34f2e760c44dc94713" dependencies = [ "jsonrpc-client-transports", ] [[package]] name = "jsonrpc-derive" -version = "14.0.5" +version = "14.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8609af8f63b626e8e211f52441fcdb6ec54f1a446606b10d5c89ae9bf8a20058" +checksum = "0fadf6945e227246825a583514534d864554e9f23d80b3c77d034b10983db5ef" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "jsonrpc-http-server" -version = "14.1.0" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52860f0549694aa4abb12766856f56952ab46d3fb9f0815131b2db3d9cc2f29" +checksum = "0da906d682799df05754480dac1b9e70ec92e12c19ebafd2662a5ea1c9fd6522" dependencies = [ "hyper 0.12.35", "jsonrpc-core", @@ -2416,23 +2619,38 @@ dependencies = [ "unicase", ] +[[package]] +name = "jsonrpc-ipc-server" +version = "14.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dedccd693325d833963b549e959137f30a7a0ea650cde92feda81dc0c1393cb5" +dependencies = [ + "jsonrpc-core", + "jsonrpc-server-utils", + "log", + "parity-tokio-ipc", + "parking_lot 0.10.2", + "tokio-service", +] + [[package]] name = "jsonrpc-pubsub" -version = "14.1.0" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ca5e391d6c6a2261d4adca029f427fe63ea546ad6cef2957c654c08495ec16" +checksum = "2d44f5602a11d657946aac09357956d2841299ed422035edf140c552cb057986" dependencies = [ "jsonrpc-core", "log", "parking_lot 0.10.2", + "rand 0.7.3", "serde", ] [[package]] name = "jsonrpc-server-utils" -version = "14.1.0" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f06add502b48351e05dd95814835327fb115e4e9f834ca42fd522d3b769d4d2" +checksum = "56cbfb462e7f902e21121d9f0d1c2b77b2c5b642e1a4e8f4ebfa2e15b94402bb" dependencies = [ "bytes 0.4.12", "globset", @@ -2446,9 +2664,9 @@ dependencies = [ [[package]] name = "jsonrpc-ws-server" -version = "14.1.0" +version = "14.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "017a7dd5083d9ed62c5e1dd3e317975c33c3115dac5447f4480fe05a8c354754" +checksum = "903d3109fe7c4acb932b567e1e607e0f524ed04741b09fb0e61841bc40a022fc" dependencies = [ "jsonrpc-core", "jsonrpc-server-utils", @@ -2466,13 +2684,13 @@ checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" [[package]] name = "keccak-hasher" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3468207deea1359a0e921591ae9b4c928733d94eb9d6a2eeda994cfd59f42cf8" +checksum = "711adba9940a039f4374fc5724c0a5eaca84a2d558cce62256bfe26f0dbef05e" dependencies = [ "hash-db", "hash256-std-hasher", - "tiny-keccak 1.5.0", + "tiny-keccak", ] [[package]] @@ -2487,28 +2705,28 @@ dependencies = [ [[package]] name = "kv-log-macro" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c54d9f465d530a752e6ebdc217e081a7a614b48cb200f6f0aee21ba6bc9aabb" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" dependencies = [ "log", ] [[package]] name = "kvdb" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad096c6849b2ef027fabe35c4aed356d0e3d3f586d0a8361e5e17f1e50a7ce5" +checksum = "0315ef2f688e33844400b31f11c263f2b3dc21d8b9355c6891c5f185fae43f9a" dependencies = [ "parity-util-mem", - "smallvec 1.3.0", + "smallvec 1.4.1", ] [[package]] name = "kvdb-memorydb" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa954d12cfac958822dfd77aab34f3eec71f103b918c4ab79ab59a36ee594ea" +checksum = "73de822b260a3bdfb889dbbb65bb2d473eee2253973d6fa4a5d149a2a4a7c66e" dependencies = [ "kvdb", "parity-util-mem", @@ -2517,12 +2735,11 @@ dependencies = [ [[package]] name = "kvdb-rocksdb" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3f14c3a10c8894d26175e57e9e26032e6d6c49c30cbe2468c5bf5f6b64bb0be" +checksum = "7c341ef15cfb1f923fa3b5138bfbd2d4813a2c1640b473727a53351c7f0b0fa2" dependencies = [ "fs-swap", - "interleaved-ordered", "kvdb", "log", "num_cpus", @@ -2531,16 +2748,16 @@ dependencies = [ "parking_lot 0.10.2", "regex", "rocksdb", - "smallvec 1.3.0", + "smallvec 1.4.1", ] [[package]] name = "kvdb-web" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f96eec962af83cdf7c83036b3dbb0ae6a1249ddab746820618e2567ca8ebcd" +checksum = "2701a1369d6ea4f1b9f606db46e5e2a4a8e47f22530a07823d653f85ab1f6c34" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "js-sys", "kvdb", "kvdb-memorydb", @@ -2571,21 +2788,9 @@ checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" [[package]] name = "libc" -version = "0.2.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" - -[[package]] -name = "libflate" -version = "0.1.27" +version = "0.2.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9135df43b1f5d0e333385cb6e7897ecd1a43d7d11b91ac003f4d2c2d2401fdd" -dependencies = [ - "adler32", - "crc32fast", - "rle-decode-fast", - "take_mut", -] +checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9" [[package]] name = "libloading" @@ -2594,7 +2799,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" dependencies = [ "cc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -2605,12 +2810,13 @@ checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" [[package]] name = "libp2p" -version = "0.18.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ea742c86405b659c358223a8f0f9f5a9eb27bb6083894c6340959b05269662" +checksum = "76c101edbb9c06955fd4085b77d2abc31cf3650134d77068b35c44967756ada8" dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", + "atomic", + "bytes 0.5.6", + "futures 0.3.5", "lazy_static", "libp2p-core", "libp2p-core-derive", @@ -2626,6 +2832,7 @@ dependencies = [ "libp2p-ping", "libp2p-plaintext", "libp2p-pnet", + "libp2p-request-response", "libp2p-secio", "libp2p-swarm", "libp2p-tcp", @@ -2634,32 +2841,32 @@ dependencies = [ "libp2p-websocket", "libp2p-yamux", "multihash", - "parity-multiaddr 0.8.0", + "parity-multiaddr", "parking_lot 0.10.2", "pin-project", - "smallvec 1.3.0", + "smallvec 1.4.1", "wasm-timer", ] [[package]] name = "libp2p-core" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d2c17158c4dca984a77a5927aac6f0862d7f50c013470a415f93be498b5739" +checksum = "17cea54ea4a846a7c47e4347db0fc7a4129dcb0fb57f07f57e473820edbfcbde" dependencies = [ "asn1_der", "bs58", "ed25519-dalek", "either", "fnv", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "lazy_static", "libsecp256k1", "log", "multihash", "multistream-select", - "parity-multiaddr 0.8.0", + "parity-multiaddr", "parking_lot 0.10.2", "pin-project", "prost", @@ -2667,115 +2874,116 @@ dependencies = [ "rand 0.7.3", "ring", "rw-stream-sink", - "sha2", - "smallvec 1.3.0", + "sha2 0.8.2", + "smallvec 1.4.1", "thiserror", - "unsigned-varint", + "unsigned-varint 0.4.0", "void", "zeroize", ] [[package]] name = "libp2p-core-derive" -version = "0.18.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329127858e4728db5ab60c33d5ae352a999325fdf190ed022ec7d3a4685ae2e6" +checksum = "f753d9324cd3ec14bf04b8a8cd0d269c87f294153d6bf2a84497a63a5ad22213" dependencies = [ - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "libp2p-deflate" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad32b006ea922da8cc66e537cf2df4b0fad8ebaa467d2a8c63d7784ac252ec6" +checksum = "bc6174d6addc9cc5fd84af7099480774035dd1a7cdf48dd31b23dea45cf57638" dependencies = [ "flate2", - "futures 0.3.4", + "futures 0.3.5", "libp2p-core", ] [[package]] name = "libp2p-dns" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0d0993481203d68e5ce2f787d033fb0cac6b850659ed6c784612db678977c71" +checksum = "fce8769cfe677a567d2677dc02a9e5be27a24acf1ff78a59cef425caae009a6a" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "libp2p-core", "log", ] [[package]] name = "libp2p-floodsub" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3673153ca967c179d745fadf047d069355d6669ecf7f261b450fbaebf1bffd3d" +checksum = "2f2342965ac7ea4b85f4df5288089796421f9297ba4020dc9692f4ef728590dc" dependencies = [ "cuckoofilter", "fnv", - "futures 0.3.4", + "futures 0.3.5", "libp2p-core", "libp2p-swarm", "prost", "prost-build", "rand 0.7.3", - "smallvec 1.3.0", + "smallvec 1.4.1", ] [[package]] name = "libp2p-gossipsub" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f7f3f79f060864db0317cc47641b7d35276dee52a0ffa91553fbd0c153863a3" +checksum = "0828b4f0c76c2edc68da574e391ce981bac5316d65785cddfe8c273d4c9bd4bb" dependencies = [ "base64 0.11.0", "byteorder 1.3.4", - "bytes 0.5.4", + "bytes 0.5.6", "fnv", - "futures 0.3.4", + "futures 0.3.5", "futures_codec", + "hex_fmt", "libp2p-core", "libp2p-swarm", "log", - "lru", + "lru_time_cache", "prost", "prost-build", "rand 0.7.3", - "sha2", - "smallvec 1.3.0", - "unsigned-varint", + "sha2 0.8.2", + "smallvec 1.4.1", + "unsigned-varint 0.4.0", "wasm-timer", ] [[package]] name = "libp2p-identify" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38ca3eb807789e26f41c82ca7cd2b3843c66c5587b8b5f709a2f421f3061414" +checksum = "41efcb5b521b65d2c45432a244ce6427cdd3649228cd192f397d1fa67682aef2" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "libp2p-core", "libp2p-swarm", "log", "prost", "prost-build", - "smallvec 1.3.0", + "smallvec 1.4.1", "wasm-timer", ] [[package]] name = "libp2p-kad" -version = "0.18.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92cda1fb8149ea64d092a2b99d2bd7a2c309eee38ea322d02e4480bd6ee1759" +checksum = "ca9b4ccc868863317af3f65eb241811ceadd971d133183040140f5496037e0ae" dependencies = [ "arrayvec 0.5.1", - "bytes 0.5.4", + "bytes 0.5.6", "either", "fnv", - "futures 0.3.4", + "futures 0.3.5", "futures_codec", "libp2p-core", "libp2p-swarm", @@ -2784,67 +2992,68 @@ dependencies = [ "prost", "prost-build", "rand 0.7.3", - "sha2", - "smallvec 1.3.0", + "sha2 0.8.2", + "smallvec 1.4.1", "uint", - "unsigned-varint", + "unsigned-varint 0.4.0", "void", "wasm-timer", ] [[package]] name = "libp2p-mdns" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e908d2aaf8ff0ec6ad1f02fe1844fd777fb0b03a68a226423630750ab99471" +checksum = "d4fe5614c2c5af74ef5870aad0fce73c9e4707716c4ee7cdf06cf9a0376d3815" dependencies = [ "async-std", "data-encoding", "dns-parser", "either", - "futures 0.3.4", + "futures 0.3.5", "lazy_static", "libp2p-core", "libp2p-swarm", "log", "net2", "rand 0.7.3", - "smallvec 1.3.0", + "smallvec 1.4.1", "void", "wasm-timer", ] [[package]] name = "libp2p-mplex" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0832882b06619b2e81d74e71447753ea3c068164a0bca67847d272e856a04a02" +checksum = "df9e79541e71590846f773efce1b6d0538804992ee54ff2f407e05d63a9ddc23" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "fnv", - "futures 0.3.4", + "futures 0.3.5", "futures_codec", "libp2p-core", "log", "parking_lot 0.10.2", - "unsigned-varint", + "unsigned-varint 0.4.0", ] [[package]] name = "libp2p-noise" -version = "0.18.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918e94a649e1139c24ee9f1f8c1f2adaba6d157b9471af787f2d9beac8c29c77" +checksum = "0beba6459d06153f5f8e23da3df1d2183798b1f457c7c9468ff99760bcbcc60b" dependencies = [ + "bytes 0.5.6", "curve25519-dalek", - "futures 0.3.4", + "futures 0.3.5", "lazy_static", "libp2p-core", "log", "prost", "prost-build", "rand 0.7.3", - "sha2", + "sha2 0.8.2", "snow", "static_assertions", "x25519-dalek", @@ -2853,11 +3062,11 @@ dependencies = [ [[package]] name = "libp2p-ping" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9bfbf87eebb492d040f9899c5c81c9738730465ac5e78d9b7a7d086d0f07230" +checksum = "670261ef938567b614746b078e049b03b55617538a8d415071c518f97532d043" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "libp2p-core", "libp2p-swarm", "log", @@ -2868,45 +3077,62 @@ dependencies = [ [[package]] name = "libp2p-plaintext" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabb00553a49bf6d4a8ce362f6eefac410227a14d03c3acffbb8cc3f022ea019" +checksum = "b3a61dfd53d1264ddff1206e4827193efaa72bab27782dfcd63c0dec120a1875" dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", + "bytes 0.5.6", + "futures 0.3.5", "futures_codec", "libp2p-core", "log", "prost", "prost-build", "rw-stream-sink", - "unsigned-varint", + "unsigned-varint 0.4.0", "void", ] [[package]] name = "libp2p-pnet" -version = "0.18.0" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d0db10e139d22d7af0b23ed7949449ec86262798aa0fd01595abdbcb02dc87" +dependencies = [ + "futures 0.3.5", + "log", + "pin-project", + "rand 0.7.3", + "salsa20", + "sha3", +] + +[[package]] +name = "libp2p-request-response" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f81b8b37ff529e1f51c20c396dac657def2108da174c1d27e57e72c9fe2d411" +checksum = "4af0de0e56a11d46c5191a61019733b5618dc955c0a36f82866bb6d5d81a7f8f" dependencies = [ - "futures 0.3.4", + "async-trait", + "futures 0.3.5", + "libp2p-core", + "libp2p-swarm", "log", - "pin-project", + "lru 0.6.0", "rand 0.7.3", - "salsa20", - "sha3", + "smallvec 1.4.1", + "wasm-timer", ] [[package]] name = "libp2p-secio" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a0509a7e47245259954fef58b85b81bf4d29ae33a4365e38d718a866698774" +checksum = "a04b320cc0394554e8d0adca21f4efd9f8c2da4930211d92e411a19a4dfd769e" dependencies = [ "aes-ctr", "ctr", - "futures 0.3.4", + "futures 0.3.5", "hmac", "js-sys", "lazy_static", @@ -2920,7 +3146,7 @@ dependencies = [ "rand 0.7.3", "ring", "rw-stream-sink", - "sha2", + "sha2 0.8.2", "static_assertions", "twofish", "wasm-bindgen", @@ -2930,53 +3156,54 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.18.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44ab289ae44cc691da0a6fe96aefa43f26c86c6c7813998e203f6d80f1860f18" +checksum = "57e4a7e64156e9d1a2daae36b5d791f057b9c53c9364a8e75f7f9848b54f9d68" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "libp2p-core", "log", "rand 0.7.3", - "smallvec 1.3.0", + "smallvec 1.4.1", "void", "wasm-timer", ] [[package]] name = "libp2p-tcp" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b37ea44823d3ed223e4605da94b50177bc520f05ae2452286700549a32d81669" +checksum = "f0f65400ccfbbf9a356733bceca6c519c9db0deb5fbcc0b81f89837c4cd53997" dependencies = [ "async-std", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "get_if_addrs", "ipnet", "libp2p-core", "log", + "socket2", ] [[package]] name = "libp2p-uds" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "281c18ea2faacb9c8a6ff76c4405df5918d9a263770e3847bf03f099abadc010" +checksum = "95bc8b0ca1dda4cccb1bb156d47a32e45cfa447ef18f737209f014a63f94a4a2" dependencies = [ "async-std", - "futures 0.3.4", + "futures 0.3.5", "libp2p-core", "log", ] [[package]] name = "libp2p-wasm-ext" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ac7dbde0f88cad191dcdfd073b8bae28d01823e8ca313f117b6ecb914160c3" +checksum = "0f2f7b06d80d036ac5763a811185b7fe6951ad71c00544b17cc378a9069bb7c2" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "js-sys", "libp2p-core", "parity-send-wrapper", @@ -2986,14 +3213,13 @@ dependencies = [ [[package]] name = "libp2p-websocket" -version = "0.18.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6874c9069ce93d899df9dc7b29f129c706b2a0fdc048f11d878935352b580190" +checksum = "a5b350db65cf0a7c83a539a596ea261caae1552c0df2245df0f916ed2fd04572" dependencies = [ "async-tls", - "bytes 0.5.4", "either", - "futures 0.3.4", + "futures 0.3.5", "libp2p-core", "log", "quicksink", @@ -3007,11 +3233,11 @@ dependencies = [ [[package]] name = "libp2p-yamux" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f91aea50f6571e0bc6c058dc0e9b270afd41ec28dd94e9e4bf607e78b9ab87" +checksum = "b3969ead4ce530efb6f304623924245caf410f3b0b0139bd7007f205933788aa" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "libp2p-core", "parking_lot 0.10.2", "thiserror", @@ -3020,9 +3246,9 @@ dependencies = [ [[package]] name = "librocksdb-sys" -version = "6.6.4" +version = "6.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3b727e2dd20ec2fb7ed93f23d9fd5328a0871185485ebdaff007b47d3e27e4" +checksum = "883213ae3d09bfc3d104aefe94b25ebb183b6f4d3a515b23b14817e1f4854005" dependencies = [ "bindgen", "cc", @@ -3038,11 +3264,11 @@ checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" dependencies = [ "arrayref", "crunchy", - "digest", + "digest 0.8.1", "hmac-drbg", "rand 0.7.3", - "sha2", - "subtle 2.2.2", + "sha2 0.8.2", + "subtle 2.2.3", "typenum", ] @@ -3060,15 +3286,15 @@ dependencies = [ [[package]] name = "linked-hash-map" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" +checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" [[package]] name = "linked_hash_set" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7c91c4c7bbeb4f2f7c4e5be11e6a05bd6830bc37249c47ce1ad86ad453ff9c" +checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" dependencies = [ "linked-hash-map", ] @@ -3086,27 +3312,45 @@ dependencies = [ [[package]] name = "lite-json" -version = "0.1.0" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c73e713a23ac6e12074c9e96ef2dfb770921e0cb9244c093bd38424209e0e523" +dependencies = [ + "lite-parser", +] + +[[package]] +name = "lite-parser" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa835713bb12ba5204013497da16caf2dd2eee25ca829d0efaa054fb38c4ddd" +checksum = "0c50092e40e0ccd1bf2015a10333fde0502ff95b832b0895dc1ca0d7ac6c52f6" dependencies = [ "paste", ] +[[package]] +name = "lock_api" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" +dependencies = [ + "scopeguard 0.3.3", +] + [[package]] name = "lock_api" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" dependencies = [ - "scopeguard", + "scopeguard 1.1.0", ] [[package]] name = "log" -version = "0.4.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ "cfg-if", ] @@ -3117,18 +3361,51 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0609345ddee5badacf857d4f547e0e5a2e987db77085c24cd887f73573a04237" dependencies = [ - "hashbrown", + "hashbrown 0.6.3", +] + +[[package]] +name = "lru" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c456c123957de3a220cd03786e0d86aa542a88b46029973b542f426da6ef34" +dependencies = [ + "hashbrown 0.6.3", +] + +[[package]] +name = "lru" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111b945ac72ec09eb7bc62a0fbdc3cc6e80555a7245f52a69d3921a75b53b153" +dependencies = [ + "hashbrown 0.8.1", ] +[[package]] +name = "lru_time_cache" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb241df5c4caeb888755363fc95f8a896618dc0d435e9e775f7930cb099beab" + [[package]] name = "mach" -version = "0.2.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" dependencies = [ "libc", ] +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + [[package]] name = "matches" version = "0.1.8" @@ -3163,27 +3440,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" dependencies = [ "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "memoffset" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" +checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" dependencies = [ "autocfg 1.0.0", ] [[package]] name = "memory-db" -version = "0.20.1" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be512cb2ccb4ecbdca937fdd4a62ea5f09f8e7195466a85e4632b3d5bcce82e6" +checksum = "36f36ddb0b2cdc25d38babba472108798e3477f02be5165f038c5e393e50c57a" dependencies = [ - "ahash", "hash-db", - "hashbrown", + "hashbrown 0.8.1", "parity-util-mem", ] @@ -3207,18 +3483,18 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.3.6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" +checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f" dependencies = [ - "adler32", + "adler", ] [[package]] name = "mio" -version = "0.6.21" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" dependencies = [ "cfg-if", "fuchsia-zircon", @@ -3227,7 +3503,7 @@ dependencies = [ "kernel32-sys", "libc", "log", - "miow", + "miow 0.2.1", "net2", "slab", "winapi 0.2.8", @@ -3245,11 +3521,23 @@ dependencies = [ "slab", ] +[[package]] +name = "mio-named-pipes" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0840c1c50fd55e521b247f949c241c9997709f23bd7f023b9762cd561e935656" +dependencies = [ + "log", + "mio", + "miow 0.3.5", + "winapi 0.3.9", +] + [[package]] name = "mio-uds" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" dependencies = [ "iovec", "libc", @@ -3268,6 +3556,16 @@ dependencies = [ "ws2_32-sys", ] +[[package]] +name = "miow" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" +dependencies = [ + "socket2", + "winapi 0.3.9", +] + [[package]] name = "more-asserts" version = "0.2.1" @@ -3276,17 +3574,17 @@ checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" [[package]] name = "multihash" -version = "0.10.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47fbc227f7e2b1cb701f95404579ecb2668abbdd3c7ef7a6cbb3cc0d3b236869" +checksum = "f75db05d738947aa5389863aadafbcf2e509d7ba099dc2ddcdf4fc66bf7a9e03" dependencies = [ "blake2b_simd", "blake2s_simd", - "digest", + "digest 0.8.1", "sha-1", - "sha2", + "sha2 0.8.2", "sha3", - "unsigned-varint", + "unsigned-varint 0.3.3", ] [[package]] @@ -3297,16 +3595,16 @@ checksum = "d8883adfde9756c1d30b0f519c9b8c502a94b41ac62f696453c37c7fc0a958ce" [[package]] name = "multistream-select" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74cdcf7cfb3402881e15a1f95116cb033d69b33c83d481e1234777f5ef0c3d2c" +checksum = "c9157e87afbc2ef0d84cc0345423d715f445edde00141c93721c162de35a05e5" dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", + "bytes 0.5.6", + "futures 0.3.5", "log", "pin-project", - "smallvec 1.3.0", - "unsigned-varint", + "smallvec 1.4.1", + "unsigned-varint 0.4.0", ] [[package]] @@ -3317,11 +3615,11 @@ checksum = "aaa9fddbc34c8c35dd2108515587b8ce0cab396f17977b8c738568e4edb521a2" dependencies = [ "alga", "approx", - "generic-array", + "generic-array 0.12.3", "matrixmultiply", "num-complex", "num-rational", - "num-traits 0.2.11", + "num-traits", "rand 0.6.5", "typenum", ] @@ -3337,27 +3635,13 @@ dependencies = [ [[package]] name = "net2" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ "cfg-if", "libc", - "winapi 0.3.8", -] - -[[package]] -name = "netstat2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29449d242064c48d3057a194b049a2bdcccadda16faa18a91468677b44e8d422" -dependencies = [ - "bitflags", - "byteorder 1.3.4", - "enum-primitive-derive", - "libc", - "num-traits 0.2.11", - "thiserror", + "winapi 0.3.9", ] [[package]] @@ -3375,10 +3659,11 @@ dependencies = [ [[package]] name = "node-bench" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "derive_more", "fs_extra", + "futures 0.3.5", "hash-db", "hex", "kvdb", @@ -3386,17 +3671,25 @@ dependencies = [ "lazy_static", "log", "node-primitives", + "node-runtime", "node-testing", "parity-db", "parity-util-mem", "rand 0.7.3", + "sc-basic-authorship", "sc-cli", "sc-client-api", + "sc-transaction-pool", "serde", "serde_json", + "sp-consensus", "sp-core", + "sp-finality-tracker", + "sp-inherents", "sp-runtime", "sp-state-machine", + "sp-timestamp", + "sp-transaction-pool", "sp-trie", "structopt", "tempfile", @@ -3404,9 +3697,9 @@ dependencies = [ [[package]] name = "node-browser-testing" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "jsonrpc-core", "libp2p", @@ -3421,15 +3714,16 @@ dependencies = [ [[package]] name = "node-cli" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "assert_cmd", "frame-benchmarking-cli", "frame-support", "frame-system", - "futures 0.3.4", + "futures 0.3.5", "hex-literal", "jsonrpc-core", + "jsonrpc-pubsub", "log", "nix", "node-executor", @@ -3484,9 +3778,11 @@ dependencies = [ "sp-runtime", "sp-timestamp", "sp-transaction-pool", + "sp-trie", "structopt", "substrate-browser-utils", "substrate-build-script-utils", + "substrate-frame-cli", "tempfile", "tracing", "wasm-bindgen", @@ -3495,9 +3791,9 @@ dependencies = [ [[package]] name = "node-executor" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "criterion 0.3.1", + "criterion", "frame-benchmarking", "frame-support", "frame-system", @@ -3529,7 +3825,7 @@ dependencies = [ [[package]] name = "node-inspect" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "derive_more", "log", @@ -3545,7 +3841,7 @@ dependencies = [ [[package]] name = "node-primitives" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-system", "parity-scale-codec", @@ -3558,9 +3854,10 @@ dependencies = [ [[package]] name = "node-rpc" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "jsonrpc-core", + "jsonrpc-pubsub", "node-primitives", "node-runtime", "pallet-contracts-rpc", @@ -3572,20 +3869,22 @@ dependencies = [ "sc-finality-grandpa", "sc-finality-grandpa-rpc", "sc-keystore", + "sc-rpc", + "sc-rpc-api", "sp-api", + "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-runtime", "sp-transaction-pool", "substrate-frame-rpc-system", ] [[package]] name = "node-rpc-client" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "env_logger 0.7.1", + "env_logger", "futures 0.1.29", "hyper 0.12.35", "jsonrpc-core-client", @@ -3596,7 +3895,7 @@ dependencies = [ [[package]] name = "node-runtime" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-executive", @@ -3604,6 +3903,7 @@ dependencies = [ "frame-system", "frame-system-benchmarking", "frame-system-rpc-runtime-api", + "hex-literal", "integer-sqrt", "node-primitives", "pallet-authority-discovery", @@ -3622,8 +3922,10 @@ dependencies = [ "pallet-im-online", "pallet-indices", "pallet-membership", + "pallet-multisig", "pallet-offences", "pallet-offences-benchmarking", + "pallet-proxy", "pallet-randomness-collective-flip", "pallet-recovery", "pallet-scheduler", @@ -3656,17 +3958,17 @@ dependencies = [ "sp-std", "sp-transaction-pool", "sp-version", + "static_assertions", "substrate-wasm-builder-runner", ] [[package]] name = "node-template" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "futures 0.3.4", - "log", + "jsonrpc-core", "node-template-runtime", - "parking_lot 0.10.2", + "pallet-transaction-payment-rpc", "sc-basic-authorship", "sc-cli", "sc-client-api", @@ -3674,9 +3976,13 @@ dependencies = [ "sc-consensus-aura", "sc-executor", "sc-finality-grandpa", - "sc-network", + "sc-rpc", + "sc-rpc-api", "sc-service", "sc-transaction-pool", + "sp-api", + "sp-block-builder", + "sp-blockchain", "sp-consensus", "sp-consensus-aura", "sp-core", @@ -3686,15 +3992,17 @@ dependencies = [ "sp-transaction-pool", "structopt", "substrate-build-script-utils", + "substrate-frame-rpc-system", ] [[package]] name = "node-template-runtime" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-executive", "frame-support", "frame-system", + "frame-system-rpc-runtime-api", "pallet-aura", "pallet-balances", "pallet-grandpa", @@ -3703,6 +4011,7 @@ dependencies = [ "pallet-template", "pallet-timestamp", "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "serde", "sp-api", @@ -3710,7 +4019,6 @@ dependencies = [ "sp-consensus-aura", "sp-core", "sp-inherents", - "sp-io", "sp-offchain", "sp-runtime", "sp-session", @@ -3722,13 +4030,13 @@ dependencies = [ [[package]] name = "node-testing" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "criterion 0.3.1", + "criterion", "frame-support", "frame-system", "fs_extra", - "futures 0.3.4", + "futures 0.3.5", "log", "node-executor", "node-primitives", @@ -3780,23 +4088,14 @@ checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" [[package]] name = "nom" -version = "5.1.1" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6" +checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" dependencies = [ "memchr", "version_check", ] -[[package]] -name = "ntapi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26e041cd983acbc087e30fcba770380cfa352d0e392e175b2344ebaf7ea0602" -dependencies = [ - "winapi 0.3.8", -] - [[package]] name = "num-bigint" version = "0.2.6" @@ -3805,7 +4104,7 @@ checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ "autocfg 1.0.0", "num-integer", - "num-traits 0.2.11", + "num-traits", ] [[package]] @@ -3815,17 +4114,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" dependencies = [ "autocfg 1.0.0", - "num-traits 0.2.11", + "num-traits", ] [[package]] name = "num-integer" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" dependencies = [ "autocfg 1.0.0", - "num-traits 0.2.11", + "num-traits", ] [[package]] @@ -3837,23 +4136,14 @@ dependencies = [ "autocfg 1.0.0", "num-bigint", "num-integer", - "num-traits 0.2.11", + "num-traits", ] [[package]] name = "num-traits" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -dependencies = [ - "num-traits 0.2.11", -] - -[[package]] -name = "num-traits" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" dependencies = [ "autocfg 1.0.0", "libm", @@ -3861,9 +4151,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ "hermit-abi", "libc", @@ -3871,37 +4161,44 @@ dependencies = [ [[package]] name = "object" -version = "0.18.0" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2" + +[[package]] +name = "object" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5666bbb90bc4d1e5bdcb26c0afda1822d25928341e9384ab187a9b37ab69e36" +checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" dependencies = [ - "target-lexicon", + "crc32fast", + "indexmap", + "wasmparser 0.57.0", ] [[package]] -name = "ole32-sys" -version = "0.2.0" +name = "once_cell" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2c49021782e5233cd243168edfa8037574afed4eba4bbaf538b3d8d1789d8c" +checksum = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "parking_lot 0.7.1", ] [[package]] name = "once_cell" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b" +checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" dependencies = [ - "parking_lot 0.9.0", + "parking_lot 0.10.2", ] [[package]] name = "oorandom" -version = "11.1.0" +version = "11.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405" +checksum = "a170cebd8021a008ea92e4db85a72f80b35df514ec664b296fdcbb654eac0b2c" [[package]] name = "opaque-debug" @@ -3909,6 +4206,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "openssl-probe" version = "0.1.2" @@ -3921,7 +4224,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -3935,10 +4238,25 @@ dependencies = [ [[package]] name = "pallet-assets" -version = "2.0.0-dev" +version = "2.0.0-rc6" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-atomic-swap" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", + "pallet-balances", "parity-scale-codec", "serde", "sp-core", @@ -3949,7 +4267,7 @@ dependencies = [ [[package]] name = "pallet-aura" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -3971,7 +4289,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -3989,7 +4307,7 @@ dependencies = [ [[package]] name = "pallet-authorship" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4005,11 +4323,17 @@ dependencies = [ [[package]] name = "pallet-babe" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", + "pallet-authorship", + "pallet-balances", + "pallet-offences", "pallet-session", + "pallet-staking", + "pallet-staking-reward-curve", "pallet-timestamp", "parity-scale-codec", "serde", @@ -4020,6 +4344,7 @@ dependencies = [ "sp-inherents", "sp-io", "sp-runtime", + "sp-session", "sp-staking", "sp-std", "sp-timestamp", @@ -4027,7 +4352,7 @@ dependencies = [ [[package]] name = "pallet-balances" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4043,7 +4368,7 @@ dependencies = [ [[package]] name = "pallet-benchmark" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4057,7 +4382,7 @@ dependencies = [ [[package]] name = "pallet-collective" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4074,9 +4399,11 @@ dependencies = [ [[package]] name = "pallet-contracts" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "assert_matches", + "bitflags", + "frame-benchmarking", "frame-support", "frame-system", "hex-literal", @@ -4084,9 +4411,9 @@ dependencies = [ "pallet-contracts-primitives", "pallet-randomness-collective-flip", "pallet-timestamp", - "pallet-transaction-payment", "parity-scale-codec", "parity-wasm 0.41.0", + "pretty_assertions", "pwasm-utils", "serde", "sp-core", @@ -4094,13 +4421,13 @@ dependencies = [ "sp-runtime", "sp-sandbox", "sp-std", - "wabt", "wasmi-validation", + "wat", ] [[package]] name = "pallet-contracts-primitives" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -4109,7 +4436,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4128,7 +4455,7 @@ dependencies = [ [[package]] name = "pallet-contracts-rpc-runtime-api" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "pallet-contracts-primitives", "parity-scale-codec", @@ -4139,7 +4466,7 @@ dependencies = [ [[package]] name = "pallet-democracy" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4154,11 +4481,12 @@ dependencies = [ "sp-runtime", "sp-std", "sp-storage", + "substrate-test-utils", ] [[package]] name = "pallet-elections" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4174,18 +4502,18 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "hex-literal", "pallet-balances", - "pallet-scheduler", "parity-scale-codec", "serde", "sp-core", "sp-io", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-std", "substrate-test-utils", @@ -4193,15 +4521,17 @@ dependencies = [ [[package]] name = "pallet-evm" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "evm", "frame-support", "frame-system", + "impl-trait-for-tuples", "pallet-balances", "pallet-timestamp", "parity-scale-codec", "primitive-types", + "ripemd160", "rlp", "serde", "sha3", @@ -4213,7 +4543,7 @@ dependencies = [ [[package]] name = "pallet-example" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4229,7 +4559,7 @@ dependencies = [ [[package]] name = "pallet-example-offchain-worker" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4244,7 +4574,7 @@ dependencies = [ [[package]] name = "pallet-finality-tracker" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4261,7 +4591,7 @@ dependencies = [ [[package]] name = "pallet-generic-asset" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4275,11 +4605,13 @@ dependencies = [ [[package]] name = "pallet-grandpa" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "finality-grandpa", + "frame-benchmarking", "frame-support", "frame-system", + "pallet-authorship", "pallet-balances", "pallet-finality-tracker", "pallet-offences", @@ -4302,7 +4634,7 @@ dependencies = [ [[package]] name = "pallet-identity" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "enumflags2", "frame-benchmarking", @@ -4319,7 +4651,7 @@ dependencies = [ [[package]] name = "pallet-im-online" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4338,8 +4670,9 @@ dependencies = [ [[package]] name = "pallet-indices" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "pallet-balances", @@ -4354,10 +4687,26 @@ dependencies = [ [[package]] name = "pallet-membership" -version = "2.0.0-dev" +version = "2.0.0-rc6" +dependencies = [ + "frame-support", + "frame-system", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-multisig" +version = "2.0.0-rc6" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", + "pallet-balances", "parity-scale-codec", "serde", "sp-core", @@ -4368,7 +4717,7 @@ dependencies = [ [[package]] name = "pallet-nicks" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4383,7 +4732,7 @@ dependencies = [ [[package]] name = "pallet-offences" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4399,7 +4748,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4422,9 +4771,26 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-proxy" +version = "2.0.0-rc6" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-utility", + "parity-scale-codec", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-randomness-collective-flip" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4438,7 +4804,7 @@ dependencies = [ [[package]] name = "pallet-recovery" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "enumflags2", "frame-support", @@ -4454,7 +4820,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4465,11 +4831,12 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", + "substrate-test-utils", ] [[package]] name = "pallet-scored-pool" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4484,7 +4851,7 @@ dependencies = [ [[package]] name = "pallet-session" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4505,7 +4872,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4516,16 +4883,18 @@ dependencies = [ "pallet-staking-reward-curve", "pallet-timestamp", "parity-scale-codec", + "rand 0.7.3", "serde", "sp-core", "sp-io", "sp-runtime", + "sp-session", "sp-std", ] [[package]] name = "pallet-society" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4541,28 +4910,26 @@ dependencies = [ [[package]] name = "pallet-staking" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "env_logger 0.7.1", + "env_logger", "frame-benchmarking", "frame-support", "frame-system", "hex", "pallet-authorship", "pallet-balances", - "pallet-indices", "pallet-session", "pallet-staking-reward-curve", "pallet-timestamp", "parity-scale-codec", "parking_lot 0.10.2", - "rand 0.7.3", "rand_chacha 0.2.2", "serde", "sp-application-crypto", "sp-core", "sp-io", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-staking", "sp-std", @@ -4587,25 +4954,25 @@ dependencies = [ "parity-scale-codec", "sp-core", "sp-io", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-std", ] [[package]] name = "pallet-staking-reward-curve" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote 1.0.3", + "quote", "sp-runtime", - "syn 1.0.17", + "syn", ] [[package]] name = "pallet-sudo" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4619,7 +4986,7 @@ dependencies = [ [[package]] name = "pallet-template" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", @@ -4631,7 +4998,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4649,13 +5016,15 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", "pallet-balances", "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", + "serde", + "smallvec 1.4.1", "sp-core", "sp-io", "sp-runtime", @@ -4665,7 +5034,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -4682,7 +5051,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "parity-scale-codec", @@ -4695,7 +5064,7 @@ dependencies = [ [[package]] name = "pallet-treasury" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4707,11 +5076,12 @@ dependencies = [ "sp-io", "sp-runtime", "sp-std", + "sp-storage", ] [[package]] name = "pallet-utility" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-benchmarking", "frame-support", @@ -4727,7 +5097,7 @@ dependencies = [ [[package]] name = "pallet-vesting" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "enumflags2", "frame-benchmarking", @@ -4746,41 +5116,23 @@ dependencies = [ [[package]] name = "parity-db" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00d595e372d119261593297debbe4193811a4dc811d2a1ccbb8caaa6666ad7ab" -dependencies = [ - "blake2-rfc", - "crc32fast", - "libc", - "log", - "memmap", - "parking_lot 0.10.2", -] - -[[package]] -name = "parity-multiaddr" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f77055f9e81921a8cc7bebeb6cded3d128931d51f1e3dd6251f0770a6d431477" -dependencies = [ - "arrayref", - "bs58", - "byteorder 1.3.4", - "data-encoding", - "parity-multihash", - "percent-encoding 2.1.0", - "serde", - "static_assertions", - "unsigned-varint", - "url 2.1.1", +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d595e372d119261593297debbe4193811a4dc811d2a1ccbb8caaa6666ad7ab" +dependencies = [ + "blake2-rfc", + "crc32fast", + "libc", + "log", + "memmap", + "parking_lot 0.10.2", ] [[package]] name = "parity-multiaddr" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4db35e222f783ef4e6661873f6c165c4eb7b65e0c408349818517d5705c2d7d3" +checksum = "cc20af3143a62c16e7c9e92ea5c6ae49f7d271d97d4d8fe73afc28f0514a3d0f" dependencies = [ "arrayref", "bs58", @@ -4790,30 +5142,15 @@ dependencies = [ "percent-encoding 2.1.0", "serde", "static_assertions", - "unsigned-varint", + "unsigned-varint 0.4.0", "url 2.1.1", ] -[[package]] -name = "parity-multihash" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1cd2ba02391b81367bec529fb209019d718684fdc8ad6a712c2b536e46f775" -dependencies = [ - "blake2", - "bytes 0.5.4", - "rand 0.7.3", - "sha-1", - "sha2", - "sha3", - "unsigned-varint", -] - [[package]] name = "parity-scale-codec" -version = "1.3.0" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329c8f7f4244ddb5c37c103641027a76c530e65e8e4b8240b29f81ea40508b17" +checksum = "34d38aeaffc032ec69faa476b3caaca8d4dd7f3f798137ff30359e5c7869ceb6" dependencies = [ "arrayvec 0.5.1", "bitvec", @@ -4824,14 +5161,14 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" +checksum = "cd20ff7e0399b274a5f5bb37b712fccb5b3a64b9128200d1c3cc40fe709cb073" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] @@ -4840,19 +5177,41 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9777aa91b8ad9dd5aaa04a9b6bcb02c7f1deb952fca5a66034d5e63afc5c6f" +[[package]] +name = "parity-tokio-ipc" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e57fea504fea33f9fbb5f49f378359030e7e026a6ab849bb9e8f0787376f1bf" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.29", + "libc", + "log", + "mio-named-pipes", + "miow 0.3.5", + "rand 0.7.3", + "tokio 0.1.22", + "tokio-named-pipes", + "tokio-uds", + "winapi 0.3.9", +] + [[package]] name = "parity-util-mem" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6e2583649a3ca84894d1d71da249abcfda54d5aca24733d72ca10d0f02361c" +checksum = "297ff91fa36aec49ce183484b102f6b75b46776822bd81525bfc4cc9b0dd0f5c" dependencies = [ "cfg-if", + "ethereum-types", + "hashbrown 0.8.1", "impl-trait-for-tuples", + "lru 0.5.3", "parity-util-mem-derive", "parking_lot 0.10.2", "primitive-types", - "smallvec 1.3.0", - "winapi 0.3.8", + "smallvec 1.4.1", + "winapi 0.3.9", ] [[package]] @@ -4862,7 +5221,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ "proc-macro2", - "syn 1.0.17", + "syn", "synstructure", ] @@ -4881,13 +5240,29 @@ version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc878dac00da22f8f61e7af3157988424567ab01d9920b962ef7dcbd7cd865" +[[package]] +name = "parking" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d4a6da31f8144a32532fe38fe8fb439a6842e0ec633f0037f0144c14e7f907" + +[[package]] +name = "parking_lot" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" +dependencies = [ + "lock_api 0.1.5", + "parking_lot_core 0.4.0", +] + [[package]] name = "parking_lot" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" dependencies = [ - "lock_api", + "lock_api 0.3.4", "parking_lot_core 0.6.2", "rustc_version", ] @@ -4898,8 +5273,21 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" dependencies = [ - "lock_api", - "parking_lot_core 0.7.1", + "lock_api 0.3.4", + "parking_lot_core 0.7.2", +] + +[[package]] +name = "parking_lot_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" +dependencies = [ + "libc", + "rand 0.6.5", + "rustc_version", + "smallvec 0.6.13", + "winapi 0.3.9", ] [[package]] @@ -4914,28 +5302,28 @@ dependencies = [ "redox_syscall", "rustc_version", "smallvec 0.6.13", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "parking_lot_core" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e136c1904604defe99ce5fd71a28d473fa60a12255d511aa78a9ddf11237aeb" +checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" dependencies = [ "cfg-if", "cloudabi", "libc", "redox_syscall", - "smallvec 1.3.0", - "winapi 0.3.8", + "smallvec 1.4.1", + "winapi 0.3.9", ] [[package]] name = "paste" -version = "0.1.10" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4fb1930692d1b6a9cfabdde3d06ea0a7d186518e2f4d67660d8970e2fa647a" +checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880" dependencies = [ "paste-impl", "proc-macro-hack", @@ -4943,14 +5331,11 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.10" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62486e111e571b1e93b710b61e8f493c0013be39629b714cb166bdb06aa5a8a" +checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6" dependencies = [ "proc-macro-hack", - "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", ] [[package]] @@ -4960,7 +5345,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "006c038a43a45995a9670da19e67600114740e8511d4333bf97a56e66a7542d9" dependencies = [ "byteorder 1.3.4", - "crypto-mac", + "crypto-mac 0.7.0", + "rayon", ] [[package]] @@ -4989,9 +5375,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "petgraph" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" +checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" dependencies = [ "fixedbitset", "indexmap", @@ -4999,47 +5385,41 @@ dependencies = [ [[package]] name = "pin-project" -version = "0.4.9" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f6a7f5eee6292c559c793430c55c00aea9d3b3d1905e855806ca4d7253426a2" +checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.9" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8988430ce790d8682672117bc06dda364c0be32d3abd738234f19f3240bad99a" +checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "pin-project-lite" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" +checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" [[package]] name = "pin-utils" -version = "0.1.0-alpha.4" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" - -[[package]] -name = "plain" -version = "0.2.3" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" [[package]] name = "platforms" @@ -5049,27 +5429,46 @@ checksum = "feb3b2b1033b8a60b4da6ee470325f887758c95d5320f52f9ce0df055a55940e" [[package]] name = "plotters" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb" +checksum = "0d1685fbe7beba33de0330629da9d955ac75bd54f33d7b79f9a895590124f6bb" dependencies = [ "js-sys", - "num-traits 0.2.11", + "num-traits", "wasm-bindgen", "web-sys", ] +[[package]] +name = "poly1305" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b42192ab143ed7619bf888a7f9c6733a9a2153b218e2cd557cfdb52fbf9bb1" +dependencies = [ + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9a50142b55ab3ed0e9f68dfb3709f1d90d29da24e91033f28b96330643107dc" +dependencies = [ + "cfg-if", + "universal-hash", +] + [[package]] name = "ppv-lite86" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" [[package]] name = "predicates" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "347a1b6f0b21e636bc9872fb60b83b8e185f6f5516298b8238699f7f9a531030" +checksum = "96bfead12e90dccead362d62bb2c90a5f6fc4584963645bc7f71a735e0b0735a" dependencies = [ "difference", "predicates-core", @@ -5105,98 +5504,82 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5e4b9943a2da369aec5e96f7c10ebc74fcf434d39590d974b0a3460e6f67fbb" +checksum = "c55c21c64d0eaa4d7ed885d959ef2d62d9e488c27c0e02d9aa5ce6c877b7d5f8" dependencies = [ "fixed-hash", "impl-codec", "impl-rlp", - "impl-serde 0.3.0", + "impl-serde", "uint", ] [[package]] name = "proc-macro-crate" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ "toml", ] [[package]] name = "proc-macro-error" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" +checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" dependencies = [ "proc-macro-error-attr", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", "version_check", ] [[package]] name = "proc-macro-error-attr" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" +checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", "syn-mid", "version_check", ] [[package]] name = "proc-macro-hack" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" +checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" [[package]] name = "proc-macro-nested" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" +checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" [[package]] name = "proc-macro2" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" -dependencies = [ - "unicode-xid 0.2.0", -] - -[[package]] -name = "procfs" -version = "0.7.8" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe50036aa1b71e553a4a0c48ab7baabf8aa8c7a5a61aae06bf38c2eab7430475" +checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" dependencies = [ - "bitflags", - "byteorder 1.3.4", - "chrono", - "hex", - "lazy_static", - "libc", - "libflate", + "unicode-xid", ] [[package]] name = "prometheus" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0575e258dab62268e7236d7307caa38848acbda7ec7ab87bd9093791e999d20" +checksum = "dd0ced56dee39a6e960c15c74dc48849d614586db2eaada6497477af7c7811cd" dependencies = [ "cfg-if", "fnv", "lazy_static", - "protobuf", "spin", "thiserror", ] @@ -5207,7 +5590,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "prost-derive", ] @@ -5217,9 +5600,9 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "heck", - "itertools", + "itertools 0.8.2", "log", "multimap", "petgraph", @@ -5236,10 +5619,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" dependencies = [ "anyhow", - "itertools", + "itertools 0.8.2", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] @@ -5248,21 +5631,15 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "prost", ] -[[package]] -name = "protobuf" -version = "2.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e86d370532557ae7573551a1ec8235a0f8d6cb276c7c9e6aa490b511c447485" - [[package]] name = "pwasm-utils" -version = "0.12.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f7a12f176deee919f4ba55326ee17491c8b707d0987aed822682c821b660192" +checksum = "0f53bc2558e8376358ebdc28301546471d67336584f6438ed4b7c7457a055fd7" dependencies = [ "byteorder 1.3.4", "log", @@ -5281,7 +5658,7 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" dependencies = [ - "env_logger 0.7.1", + "env_logger", "log", "rand 0.7.3", "rand_core 0.5.1", @@ -5300,15 +5677,9 @@ dependencies = [ [[package]] name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.3" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ "proc-macro2", ] @@ -5339,7 +5710,7 @@ dependencies = [ "libc", "rand_core 0.3.1", "rdrand", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -5352,7 +5723,7 @@ dependencies = [ "fuchsia-cprng", "libc", "rand_core 0.3.1", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -5371,7 +5742,7 @@ dependencies = [ "rand_os", "rand_pcg 0.1.2", "rand_xorshift", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -5467,7 +5838,7 @@ checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" dependencies = [ "libc", "rand_core 0.4.2", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -5482,7 +5853,7 @@ dependencies = [ "rand_core 0.4.2", "rdrand", "wasm-bindgen", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -5513,16 +5884,6 @@ dependencies = [ "rand_core 0.3.1", ] -[[package]] -name = "rand_xoshiro" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929" -dependencies = [ - "byteorder 1.3.4", - "rand_core 0.3.1", -] - [[package]] name = "raw-cpuid" version = "7.0.3" @@ -5542,10 +5903,11 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" +checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080" dependencies = [ + "autocfg 1.0.0", "crossbeam-deque", "either", "rayon-core", @@ -5553,9 +5915,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" +checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280" dependencies = [ "crossbeam-deque", "crossbeam-queue", @@ -5575,9 +5937,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_users" @@ -5592,40 +5954,40 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a214c7875e1b63fc1618db7c80efc0954f6156c9ff07699fd9039e255accdd1" +checksum = "745c1787167ddae5569661d5ffb8b25ae5fedbf46717eaa92d652221cec72623" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eb59cda66fcb9aec25841fb76bc01d2b34282dcdd705028da297db6f3eec8" +checksum = "7d21b475ab879ef0e315ad99067fa25778c3b0377f57f1b00207448dac1a3144" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "regalloc" -version = "0.0.21" +version = "0.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b27b256b41986ac5141b37b8bbba85d314fbf546c182eb255af6720e07e4f804" +checksum = "b9ba8aaf5fe7cf307c6dbdaeed85478961d29e25e3bee5169e11b92fa9f027a8" dependencies = [ "log", "rustc-hash", - "smallvec 1.3.0", + "smallvec 1.4.1", ] [[package]] name = "regex" -version = "1.3.6" +version = "1.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" dependencies = [ "aho-corasick", "memchr", @@ -5640,55 +6002,88 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" dependencies = [ "byteorder 1.3.4", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" +checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" [[package]] name = "region" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "448e868c6e4cfddfa49b6a72c95906c04e8547465e9536575b95c70a4044f856" +checksum = "877e54ea2adcd70d80e9179344c97f93ef0dffd6b03e1f4529e6e83ab2fa9ae0" dependencies = [ "bitflags", "libc", "mach", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] name = "remove_dir_all" -version = "0.5.2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "rental" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" +checksum = "8545debe98b2b139fb04cad8618b530e9b07c152d99a5de83c860b877d67847f" dependencies = [ - "winapi 0.3.8", + "rental-impl", + "stable_deref_trait", +] + +[[package]] +name = "rental-impl" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "475e68978dc5b743f2f40d8e0a8fdc83f1c5e78cbf4b8fa5e74e73beebc340de" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] +[[package]] +name = "retain_mut" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e005d658ad26eacc2b6c506dfde519f4e277e328d0eb3379ca61647d70a8f531" + [[package]] name = "ring" -version = "0.16.12" +version = "0.16.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba5a8ec64ee89a76c98c549af81ff14813df09c3e6dc4766c3856da48597a0c" +checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4" dependencies = [ "cc", - "lazy_static", "libc", + "once_cell 1.4.0", "spin", "untrusted", "web-sys", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] -name = "rle-decode-fast" -version = "1.0.1" +name = "ripemd160" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug 0.3.0", +] [[package]] name = "rlp" @@ -5701,9 +6096,9 @@ dependencies = [ [[package]] name = "rocksdb" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12069b106981c6103d3eab7dd1c86751482d0779a520b7c14954c8b586c1e643" +checksum = "61aa17a99a2413cd71c1106691bf59dad7de0cd5099127f90e9d99c429c40d4a" dependencies = [ "libc", "librocksdb-sys", @@ -5716,7 +6111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99371657d3c8e4d816fb6221db98fa408242b0b53bac08f8676a41f8554fe99f" dependencies = [ "libc", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -5760,11 +6155,11 @@ dependencies = [ [[package]] name = "rustls" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1" +checksum = "cac94b333ee2aac3284c5b8a1b7fb4dd11cba88c244e3fe33cdbd047af0eb693" dependencies = [ - "base64 0.11.0", + "base64 0.12.3", "log", "ring", "sct", @@ -5773,9 +6168,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75ffeb84a6bd9d014713119542ce415db3a3e4748f0bfce1e1416cd224a23a5" +checksum = "629d439a7672da82dd955498445e496ee2096fe2117b9f796558a43fdb9e59b8" dependencies = [ "openssl-probe", "rustls", @@ -5785,13 +6180,13 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" +checksum = "b9bdc5e856e51e685846fb6c13a1f5e5432946c2c90501bdc76a1319f19e29da" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] @@ -5800,16 +6195,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4da5fcb054c46f5a5dff833b129285a93d3f0179531735e6c866e8cc307d2020" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "pin-project", "static_assertions", ] [[package]] name = "ryu" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "safe-mix" @@ -5828,7 +6223,7 @@ checksum = "2324b0e8c3bb9a586a571fdb3136f70e7e2c748de00a78043f86e0cff91f91fe" dependencies = [ "byteorder 1.3.4", "salsa20-core", - "stream-cipher", + "stream-cipher 0.3.2", ] [[package]] @@ -5837,7 +6232,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fe6cc1b9f5a5867853ade63099de70f042f7679e408d1ffe52821c9248e6e69" dependencies = [ - "stream-cipher", + "stream-cipher 0.3.2", ] [[package]] @@ -5851,12 +6246,12 @@ dependencies = [ [[package]] name = "sc-authority-discovery" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "derive_more", - "env_logger 0.7.1", - "futures 0.3.4", + "env_logger", + "futures 0.3.5", "futures-timer 3.0.2", "libp2p", "log", @@ -5881,15 +6276,16 @@ dependencies = [ [[package]] name = "sc-basic-authorship" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "log", "parity-scale-codec", "parking_lot 0.10.2", "sc-block-builder", "sc-client-api", + "sc-proposer-metrics", "sc-telemetry", "sc-transaction-pool", "sp-api", @@ -5899,13 +6295,14 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-transaction-pool", + "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tokio-executor 0.2.0-alpha.6", ] [[package]] name = "sc-block-builder" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -5914,6 +6311,7 @@ dependencies = [ "sp-blockchain", "sp-consensus", "sp-core", + "sp-inherents", "sp-runtime", "sp-state-machine", "sp-trie", @@ -5922,7 +6320,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "impl-trait-for-tuples", "sc-chain-spec-derive", @@ -5937,43 +6335,50 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "sc-cli" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "ansi_term 0.12.1", - "app_dirs", "atty", + "bip39", "chrono", - "clap", "derive_more", - "env_logger 0.7.1", + "env_logger", "fdlimit", - "futures 0.3.4", + "futures 0.3.5", + "hex", "lazy_static", + "libp2p", "log", "names", "nix", + "parity-scale-codec", "parity-util-mem", + "rand 0.7.3", "regex", "rpassword", "sc-client-api", "sc-informant", + "sc-keystore", "sc-network", "sc-service", "sc-telemetry", "sc-tracing", + "serde", "serde_json", + "sp-application-crypto", "sp-blockchain", "sp-core", + "sp-io", "sp-keyring", "sp-panic-handler", "sp-runtime", @@ -5984,16 +6389,16 @@ dependencies = [ "substrate-prometheus-endpoint", "tempfile", "time", - "tokio 0.2.18", + "tokio 0.2.22", ] [[package]] name = "sc-client-api" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "derive_more", "fnv", - "futures 0.3.4", + "futures 0.3.5", "hash-db", "hex-literal", "kvdb", @@ -6027,10 +6432,10 @@ dependencies = [ [[package]] name = "sc-client-db" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "blake2-rfc", - "env_logger 0.7.1", + "env_logger", "hash-db", "kvdb", "kvdb-memorydb", @@ -6045,6 +6450,7 @@ dependencies = [ "sc-client-api", "sc-executor", "sc-state-db", + "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-core", @@ -6060,7 +6466,7 @@ dependencies = [ [[package]] name = "sc-consensus" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "sc-client-api", "sp-blockchain", @@ -6070,11 +6476,11 @@ dependencies = [ [[package]] name = "sc-consensus-aura" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "derive_more", - "env_logger 0.7.1", - "futures 0.3.4", + "env_logger", + "futures 0.3.5", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -6101,28 +6507,31 @@ dependencies = [ "sp-runtime", "sp-timestamp", "sp-version", + "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", ] [[package]] name = "sc-consensus-babe" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "derive_more", - "env_logger 0.7.1", + "env_logger", "fork-tree", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "log", "merlin", "num-bigint", "num-rational", - "num-traits 0.2.11", + "num-traits", "parity-scale-codec", "parking_lot 0.10.2", "pdqselect", "rand 0.7.3", + "rand_chacha 0.2.2", + "retain_mut", "sc-block-builder", "sc-client-api", "sc-consensus-epochs", @@ -6149,24 +6558,29 @@ dependencies = [ "sp-keyring", "sp-runtime", "sp-timestamp", + "sp-utils", "sp-version", + "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", ] [[package]] name = "sc-consensus-babe-rpc" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "derive_more", - "futures 0.3.4", + "futures 0.3.5", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", + "sc-consensus", "sc-consensus-babe", "sc-consensus-epochs", "sc-keystore", + "sc-rpc-api", "serde", + "serde_json", "sp-api", "sp-application-crypto", "sp-blockchain", @@ -6181,7 +6595,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "fork-tree", "parity-scale-codec", @@ -6193,12 +6607,12 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "assert_matches", "derive_more", - "env_logger 0.7.1", - "futures 0.3.4", + "env_logger", + "futures 0.3.5", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -6214,18 +6628,19 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-transaction-pool", + "substrate-prometheus-endpoint", "substrate-test-runtime-client", "substrate-test-runtime-transaction-pool", "tempfile", - "tokio 0.2.18", + "tokio 0.2.22", ] [[package]] name = "sc-consensus-pow" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "derive_more", - "futures 0.3.4", + "futures 0.3.5", "log", "parity-scale-codec", "sc-client-api", @@ -6238,13 +6653,14 @@ dependencies = [ "sp-inherents", "sp-runtime", "sp-timestamp", + "substrate-prometheus-endpoint", ] [[package]] name = "sc-consensus-slots" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -6252,8 +6668,10 @@ dependencies = [ "sc-client-api", "sc-telemetry", "sp-api", + "sp-application-crypto", "sp-blockchain", "sp-consensus", + "sp-consensus-slots", "sp-core", "sp-inherents", "sp-runtime", @@ -6263,7 +6681,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "log", "sc-client-api", @@ -6276,7 +6694,7 @@ dependencies = [ [[package]] name = "sc-executor" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "assert_matches", "derive_more", @@ -6291,6 +6709,7 @@ dependencies = [ "sc-executor-wasmi", "sc-executor-wasmtime", "sc-runtime-test", + "sc-tracing", "sp-api", "sp-core", "sp-externalities", @@ -6300,18 +6719,20 @@ dependencies = [ "sp-runtime-interface", "sp-serializer", "sp-state-machine", + "sp-tracing", "sp-trie", "sp-version", "sp-wasm-interface", "substrate-test-runtime", "test-case", + "tracing", "wabt", "wasmi", ] [[package]] name = "sc-executor-common" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "derive_more", "log", @@ -6327,7 +6748,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "log", "parity-scale-codec", @@ -6341,35 +6762,32 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "assert_matches", - "cranelift-codegen", - "cranelift-wasm", "log", "parity-scale-codec", "parity-wasm 0.41.0", + "pwasm-utils", "sc-executor-common", "scoped-tls", "sp-allocator", "sp-core", "sp-runtime-interface", "sp-wasm-interface", - "substrate-wasmtime", - "substrate-wasmtime-runtime", - "wasmtime-environ", + "wasmtime", ] [[package]] name = "sc-finality-grandpa" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "assert_matches", "derive_more", - "env_logger 0.7.1", + "env_logger", "finality-grandpa", "fork-tree", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "log", "parity-scale-codec", @@ -6386,6 +6804,7 @@ dependencies = [ "sc-telemetry", "serde_json", "sp-api", + "sp-application-crypto", "sp-arithmetic", "sp-blockchain", "sp-consensus", @@ -6401,72 +6820,105 @@ dependencies = [ "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", - "tokio 0.2.18", + "tokio 0.2.22", ] [[package]] name = "sc-finality-grandpa-rpc" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "derive_more", "finality-grandpa", - "futures 0.3.4", + "futures 0.3.5", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", + "jsonrpc-pubsub", + "lazy_static", "log", + "parity-scale-codec", + "sc-block-builder", "sc-finality-grandpa", + "sc-network-test", + "sc-rpc", "serde", "serde_json", + "sp-blockchain", + "sp-consensus", "sp-core", + "sp-finality-grandpa", + "sp-keyring", + "sp-runtime", + "substrate-test-runtime-client", ] [[package]] name = "sc-informant" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "ansi_term 0.12.1", - "futures 0.3.4", + "futures 0.3.5", "log", "parity-util-mem", "sc-client-api", "sc-network", - "sc-service", "sp-blockchain", "sp-runtime", + "sp-transaction-pool", + "sp-utils", "wasm-timer", ] [[package]] name = "sc-keystore" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "derive_more", "hex", + "merlin", "parking_lot 0.10.2", "rand 0.7.3", "serde_json", "sp-application-crypto", "sp-core", - "subtle 2.2.2", + "subtle 2.2.3", "tempfile", ] +[[package]] +name = "sc-light" +version = "2.0.0-rc6" +dependencies = [ + "hash-db", + "lazy_static", + "parity-scale-codec", + "parking_lot 0.10.2", + "sc-client-api", + "sc-executor", + "sp-api", + "sp-blockchain", + "sp-core", + "sp-externalities", + "sp-runtime", + "sp-state-machine", +] + [[package]] name = "sc-network" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "assert_matches", "async-std", "bitflags", - "bytes 0.5.4", + "bs58", + "bytes 0.5.6", "derive_more", "either", - "env_logger 0.7.1", + "env_logger", "erased-serde", "fnv", "fork-tree", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "futures_codec", "hex", @@ -6475,7 +6927,7 @@ dependencies = [ "linked-hash-map", "linked_hash_set", "log", - "lru", + "lru 0.4.3", "nohash-hasher", "parity-scale-codec", "parking_lot 0.10.2", @@ -6505,7 +6957,7 @@ dependencies = [ "substrate-test-runtime-client", "tempfile", "thiserror", - "unsigned-varint", + "unsigned-varint 0.4.0", "void", "wasm-timer", "zeroize", @@ -6513,14 +6965,14 @@ dependencies = [ [[package]] name = "sc-network-gossip" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "async-std", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "libp2p", "log", - "lru", + "lru 0.4.3", "quickcheck", "rand 0.7.3", "sc-network", @@ -6531,10 +6983,10 @@ dependencies = [ [[package]] name = "sc-network-test" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ - "env_logger 0.7.1", - "futures 0.3.4", + "env_logger", + "futures 0.3.5", "futures-timer 3.0.2", "libp2p", "log", @@ -6557,16 +7009,16 @@ dependencies = [ [[package]] name = "sc-offchain" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "bytes 0.5.4", - "env_logger 0.7.1", - "fdlimit", + "bytes 0.5.6", + "env_logger", "fnv", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", - "hyper 0.13.4", + "hyper 0.13.7", "hyper-rustls", + "lazy_static", "log", "num_cpus", "parity-scale-codec", @@ -6585,14 +7037,14 @@ dependencies = [ "sp-utils", "substrate-test-runtime-client", "threadpool", - "tokio 0.2.18", + "tokio 0.2.22", ] [[package]] name = "sc-peerset" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "libp2p", "log", "rand 0.7.3", @@ -6601,16 +7053,25 @@ dependencies = [ "wasm-timer", ] +[[package]] +name = "sc-proposer-metrics" +version = "0.8.0-rc6" +dependencies = [ + "log", + "substrate-prometheus-endpoint", +] + [[package]] name = "sc-rpc" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "assert_matches", "futures 0.1.29", - "futures 0.3.4", + "futures 0.3.5", "hash-db", "jsonrpc-core", "jsonrpc-pubsub", + "lazy_static", "log", "parity-scale-codec", "parking_lot 0.10.2", @@ -6641,10 +7102,10 @@ dependencies = [ [[package]] name = "sc-rpc-api" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "derive_more", - "futures 0.3.4", + "futures 0.3.5", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", @@ -6664,10 +7125,11 @@ dependencies = [ [[package]] name = "sc-rpc-server" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "jsonrpc-core", "jsonrpc-http-server", + "jsonrpc-ipc-server", "jsonrpc-pubsub", "jsonrpc-ws-server", "log", @@ -6678,7 +7140,7 @@ dependencies = [ [[package]] name = "sc-runtime-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "sp-allocator", "sp-core", @@ -6691,23 +7153,24 @@ dependencies = [ [[package]] name = "sc-service" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ + "async-std", "derive_more", + "directories", "exit-future", "futures 0.1.29", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "hash-db", + "jsonrpc-core", + "jsonrpc-pubsub", "lazy_static", "log", - "netstat2", - "parity-multiaddr 0.7.3", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", "pin-project", - "procfs", "rand 0.7.3", "sc-block-builder", "sc-chain-spec", @@ -6715,7 +7178,9 @@ dependencies = [ "sc-client-db", "sc-executor", "sc-finality-grandpa", + "sc-informant", "sc-keystore", + "sc-light", "sc-network", "sc-offchain", "sc-rpc", @@ -6735,6 +7200,7 @@ dependencies = [ "sp-core", "sp-externalities", "sp-finality-grandpa", + "sp-inherents", "sp-io", "sp-runtime", "sp-session", @@ -6745,19 +7211,20 @@ dependencies = [ "sp-version", "substrate-prometheus-endpoint", "substrate-test-runtime-client", - "sysinfo", + "tempfile", + "tokio 0.2.22", "tracing", "wasm-timer", ] [[package]] name = "sc-service-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "env_logger 0.7.1", + "env_logger", "fdlimit", "futures 0.1.29", - "futures 0.3.4", + "futures 0.3.5", "hex-literal", "log", "parity-scale-codec", @@ -6766,6 +7233,7 @@ dependencies = [ "sc-client-api", "sc-client-db", "sc-executor", + "sc-light", "sc-network", "sc-service", "sp-api", @@ -6787,9 +7255,9 @@ dependencies = [ [[package]] name = "sc-state-db" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ - "env_logger 0.7.1", + "env_logger", "log", "parity-scale-codec", "parity-util-mem", @@ -6801,10 +7269,9 @@ dependencies = [ [[package]] name = "sc-telemetry" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "bytes 0.5.4", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "libp2p", "log", @@ -6822,32 +7289,35 @@ dependencies = [ [[package]] name = "sc-tracing" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "erased-serde", "log", "parking_lot 0.10.2", + "rustc-hash", "sc-telemetry", "serde", "serde_json", "slog", + "sp-tracing", "tracing", - "tracing-core", + "tracing-subscriber", ] [[package]] name = "sc-transaction-graph" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "assert_matches", - "criterion 0.3.1", + "criterion", "derive_more", - "futures 0.3.4", + "futures 0.3.5", "linked-hash-map", "log", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", + "retain_mut", "serde", "sp-blockchain", "sp-core", @@ -6860,11 +7330,11 @@ dependencies = [ [[package]] name = "sc-transaction-pool" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "assert_matches", "derive_more", - "futures 0.3.4", + "futures 0.3.5", "futures-diagnose", "hex", "intervalier", @@ -6872,10 +7342,12 @@ dependencies = [ "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", + "sc-block-builder", "sc-client-api", "sc-transaction-graph", "sp-api", "sp-blockchain", + "sp-consensus", "sp-core", "sp-keyring", "sp-runtime", @@ -6890,12 +7362,12 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "039c25b130bd8c1321ee2d7de7fde2659fa9c2744e4bb29711cfc852ea53cd19" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" dependencies = [ "lazy_static", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -6911,8 +7383,8 @@ dependencies = [ "merlin", "rand 0.7.3", "rand_core 0.5.1", - "sha2", - "subtle 2.2.2", + "sha2 0.8.2", + "subtle 2.2.3", "zeroize", ] @@ -6922,6 +7394,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" + [[package]] name = "scopeguard" version = "1.1.0" @@ -6939,13 +7417,13 @@ dependencies = [ [[package]] name = "scroll_derive" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8584eea9b9ff42825b46faf46a8c24d2cff13ec152fa2a50df788b87c07ee28" +checksum = "e367622f934864ffa1c704ba2b82280aab856e3d8213c84c5720257eb34b15b9" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] @@ -6958,11 +7436,20 @@ dependencies = [ "untrusted", ] +[[package]] +name = "secrecy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9182278ed645df3477a9c27bfee0621c621aa16f6972635f7f795dae3d81070f" +dependencies = [ + "zeroize", +] + [[package]] name = "security-framework" -version = "0.4.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572dfa3a0785509e7a44b5b4bebcf94d41ba34e9ed9eb9df722545c3b3c4144a" +checksum = "ad502866817f0575705bd7be36e2b2535cc33262d493aa733a2ec862baa2bc2b" dependencies = [ "bitflags", "core-foundation", @@ -6973,9 +7460,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "0.4.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb15a5fec93b7021b8a9e96009c5d8d51c15673569f7c0f6b7204e5b7b404f" +checksum = "51ceb04988b17b6d1dcd555390fa822ca5637b4a14e1f5099f13d351bed4d6c7" dependencies = [ "core-foundation-sys", "libc", @@ -6995,6 +7482,15 @@ name = "semver" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "394cec28fa623e00903caf7ba4fa6fb9a0e260280bb8cdbbba029611108a0190" dependencies = [ "semver-parser", "serde", @@ -7026,29 +7522,39 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.106" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" +checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" dependencies = [ "serde_derive", ] +[[package]] +name = "serde_cbor" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" -version = "1.0.106" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" +checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "serde_json" -version = "1.0.51" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9" +checksum = "3433e879a558dde8b5e8feb2a04899cf34fdde1fafb894687e52105fc1162ac3" dependencies = [ "itoa", "ryu", @@ -7061,28 +7567,35 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" dependencies = [ - "block-buffer", - "digest", + "block-buffer 0.7.3", + "digest 0.8.1", "fake-simd", - "opaque-debug", + "opaque-debug 0.2.3", ] [[package]] -name = "sha1" -version = "0.6.0" +name = "sha2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] [[package]] name = "sha2" -version = "0.8.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" +checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" dependencies = [ - "block-buffer", - "digest", - "fake-simd", - "opaque-debug", + "block-buffer 0.9.0", + "cfg-if", + "cpuid-bool", + "digest 0.9.0", + "opaque-debug 0.3.0", ] [[package]] @@ -7091,21 +7604,20 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" dependencies = [ - "block-buffer", + "block-buffer 0.7.3", "byte-tools", - "digest", + "digest 0.8.1", "keccak", - "opaque-debug", + "opaque-debug 0.2.3", ] [[package]] -name = "shell32-sys" -version = "0.1.2" +name = "sharded-slab" +version = "0.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c" +checksum = "06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "lazy_static", ] [[package]] @@ -7124,6 +7636,12 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65211b7b6fc3f14ff9fc7a2011a434e3e6880585bd2e9e9396315ae24cbf7852" + [[package]] name = "slab" version = "0.4.2" @@ -7170,8 +7688,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a945ec7f7ce853e89ffa36be1e27dce9a43e82ff9093bf3461c30d5da74ed11b" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] @@ -7185,51 +7703,80 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.3.0" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f" + +[[package]] +name = "smol" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05720e22615919e4734f6a99ceae50d00226c3c5aca406e102ebc33298214e0a" +checksum = "620cbb3c6e34da57d3a248cda0cd01cd5848164dc062e764e65d06fe3ea7aed5" +dependencies = [ + "async-task", + "blocking", + "concurrent-queue", + "fastrand", + "futures-io", + "futures-util", + "libc", + "once_cell 1.4.0", + "scoped-tls", + "slab", + "socket2", + "wepoll-sys-stjepang", + "winapi 0.3.9", +] [[package]] name = "snow" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb767eee7d257ba202f0b9b08673bc13b22281632ef45267b19f13100accd2f" +checksum = "32bf8474159a95551661246cda4976e89356999e3cbfef36f493dacc3fae1e8e" dependencies = [ - "arrayref", - "blake2-rfc", - "chacha20-poly1305-aead", + "aes-gcm", + "blake2", + "chacha20poly1305", "rand 0.7.3", "rand_core 0.5.1", "ring", "rustc_version", - "sha2", - "subtle 2.2.2", + "sha2 0.9.1", + "subtle 2.2.3", "x25519-dalek", ] +[[package]] +name = "socket2" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.9", +] + [[package]] name = "soketto" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9dab3f95c9ebdf3a88268c19af668f637a3c5039c2c56ff2d40b1b2d64a25b" +checksum = "85457366ae0c6ce56bf05a958aef14cd38513c236568618edbcd9a8c52cb80b0" dependencies = [ - "base64 0.11.0", - "bytes 0.5.4", + "base64 0.12.3", + "bytes 0.5.6", "flate2", - "futures 0.3.4", - "http 0.2.1", + "futures 0.3.5", "httparse", "log", "rand 0.7.3", - "sha1", - "smallvec 1.3.0", - "static_assertions", - "thiserror", + "sha-1", ] [[package]] name = "sp-allocator" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "derive_more", "log", @@ -7240,7 +7787,7 @@ dependencies = [ [[package]] name = "sp-api" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "hash-db", "parity-scale-codec", @@ -7255,20 +7802,20 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "blake2-rfc", "proc-macro-crate", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "sp-api-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "criterion 0.3.1", + "criterion", "parity-scale-codec", "rustversion", "sc-block-builder", @@ -7285,7 +7832,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "serde", @@ -7296,7 +7843,7 @@ dependencies = [ [[package]] name = "sp-application-crypto-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "sp-api", "sp-application-crypto", @@ -7307,11 +7854,11 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "criterion 0.3.1", + "criterion", "integer-sqrt", - "num-traits 0.2.11", + "num-traits", "parity-scale-codec", "primitive-types", "rand 0.7.3", @@ -7323,18 +7870,18 @@ dependencies = [ [[package]] name = "sp-arithmetic-fuzzer" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "honggfuzz", "num-bigint", - "num-traits 0.2.11", + "num-traits", "primitive-types", "sp-arithmetic", ] [[package]] name = "sp-authority-discovery" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "sp-api", @@ -7345,7 +7892,7 @@ dependencies = [ [[package]] name = "sp-authorship" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7355,7 +7902,7 @@ dependencies = [ [[package]] name = "sp-block-builder" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "sp-api", @@ -7366,22 +7913,23 @@ dependencies = [ [[package]] name = "sp-blockchain" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "derive_more", "log", - "lru", + "lru 0.4.3", "parity-scale-codec", "parking_lot 0.10.2", "sp-block-builder", "sp-consensus", + "sp-database", "sp-runtime", "sp-state-machine", ] [[package]] name = "sp-chain-spec" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "serde", "serde_json", @@ -7389,29 +7937,33 @@ dependencies = [ [[package]] name = "sp-consensus" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "derive_more", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "libp2p", "log", "parity-scale-codec", "parking_lot 0.10.2", "serde", + "sp-api", "sp-core", "sp-inherents", "sp-runtime", "sp-state-machine", "sp-std", "sp-test-primitives", + "sp-trie", "sp-utils", "sp-version", + "substrate-prometheus-endpoint", + "wasm-timer", ] [[package]] name = "sp-consensus-aura" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "parity-scale-codec", "sp-api", @@ -7424,14 +7976,16 @@ dependencies = [ [[package]] name = "sp-consensus-babe" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "merlin", "parity-scale-codec", "sp-api", "sp-application-crypto", "sp-consensus", + "sp-consensus-slots", "sp-consensus-vrf", + "sp-core", "sp-inherents", "sp-runtime", "sp-std", @@ -7440,7 +7994,7 @@ dependencies = [ [[package]] name = "sp-consensus-pow" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "parity-scale-codec", "sp-api", @@ -7449,9 +8003,17 @@ dependencies = [ "sp-std", ] +[[package]] +name = "sp-consensus-slots" +version = "0.8.0-rc6" +dependencies = [ + "parity-scale-codec", + "sp-runtime", +] + [[package]] name = "sp-consensus-vrf" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -7462,35 +8024,39 @@ dependencies = [ [[package]] name = "sp-core" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "base58", "blake2-rfc", "byteorder 1.3.4", - "criterion 0.2.11", + "criterion", + "derive_more", + "dyn-clonable", "ed25519-dalek", - "futures 0.3.4", + "futures 0.3.5", "hash-db", "hash256-std-hasher", "hex", "hex-literal", - "impl-serde 0.3.0", + "impl-serde", "lazy_static", "libsecp256k1", "log", "merlin", - "num-traits 0.2.11", + "num-traits", "parity-scale-codec", "parity-util-mem", "parking_lot 0.10.2", "pretty_assertions", "primitive-types", "rand 0.7.3", + "rand_chacha 0.2.2", "regex", "schnorrkel", + "secrecy", "serde", "serde_json", - "sha2", + "sha2 0.8.2", "sp-debug-derive", "sp-externalities", "sp-runtime-interface", @@ -7499,7 +8065,7 @@ dependencies = [ "sp-storage", "substrate-bip39", "tiny-bip39", - "tiny-keccak 2.0.2", + "tiny-keccak", "twox-hash", "wasmi", "zeroize", @@ -7507,7 +8073,7 @@ dependencies = [ [[package]] name = "sp-database" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "kvdb", "parking_lot 0.10.2", @@ -7515,16 +8081,16 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "sp-externalities" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "environmental", "parity-scale-codec", @@ -7534,7 +8100,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "finality-grandpa", "log", @@ -7549,7 +8115,7 @@ dependencies = [ [[package]] name = "sp-finality-tracker" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "sp-inherents", @@ -7558,7 +8124,7 @@ dependencies = [ [[package]] name = "sp-inherents" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "derive_more", "parity-scale-codec", @@ -7569,9 +8135,9 @@ dependencies = [ [[package]] name = "sp-io" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "hash-db", "libsecp256k1", "log", @@ -7582,13 +8148,14 @@ dependencies = [ "sp-runtime-interface", "sp-state-machine", "sp-std", + "sp-tracing", "sp-trie", "sp-wasm-interface", ] [[package]] name = "sp-keyring" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "lazy_static", "sp-core", @@ -7597,62 +8164,61 @@ dependencies = [ ] [[package]] -name = "sp-offchain" -version = "2.0.0-dev" -dependencies = [ - "sp-api", - "sp-core", - "sp-runtime", - "sp-state-machine", -] - -[[package]] -name = "sp-panic-handler" -version = "2.0.0-dev" -dependencies = [ - "backtrace", - "log", -] - -[[package]] -name = "sp-phragmen" -version = "2.0.0-dev" +name = "sp-npos-elections" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "rand 0.7.3", "serde", "sp-arithmetic", - "sp-phragmen", - "sp-phragmen-compact", + "sp-npos-elections-compact", "sp-runtime", "sp-std", "substrate-test-utils", ] [[package]] -name = "sp-phragmen-compact" -version = "2.0.0-dev" +name = "sp-npos-elections-compact" +version = "2.0.0-rc6" dependencies = [ "proc-macro-crate", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] -name = "sp-phragmen-fuzzer" +name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" dependencies = [ "honggfuzz", "rand 0.7.3", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-std", ] +[[package]] +name = "sp-offchain" +version = "2.0.0-rc6" +dependencies = [ + "sp-api", + "sp-core", + "sp-runtime", + "sp-state-machine", +] + +[[package]] +name = "sp-panic-handler" +version = "2.0.0-rc6" +dependencies = [ + "backtrace", + "log", +] + [[package]] name = "sp-rpc" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "serde", "serde_json", @@ -7661,8 +8227,9 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ + "either", "hash256-std-hasher", "impl-trait-for-tuples", "log", @@ -7683,7 +8250,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "primitive-types", @@ -7695,6 +8262,7 @@ dependencies = [ "sp-runtime-interface-test-wasm", "sp-state-machine", "sp-std", + "sp-storage", "sp-tracing", "sp-wasm-interface", "static_assertions", @@ -7703,18 +8271,18 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "Inflector", "proc-macro-crate", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "sp-runtime-interface-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "sc-executor", "sp-core", @@ -7729,7 +8297,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-test-wasm" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "sp-core", "sp-io", @@ -7740,7 +8308,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-test-wasm-deprecated" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "sp-core", "sp-io", @@ -7751,7 +8319,7 @@ dependencies = [ [[package]] name = "sp-sandbox" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "assert_matches", "parity-scale-codec", @@ -7765,7 +8333,7 @@ dependencies = [ [[package]] name = "sp-serializer" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "serde", "serde_json", @@ -7773,7 +8341,7 @@ dependencies = [ [[package]] name = "sp-session" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "sp-api", @@ -7785,7 +8353,7 @@ dependencies = [ [[package]] name = "sp-staking" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -7794,15 +8362,18 @@ dependencies = [ [[package]] name = "sp-state-machine" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "hash-db", "hex-literal", + "itertools 0.9.0", "log", - "num-traits 0.2.11", + "num-traits", "parity-scale-codec", "parking_lot 0.10.2", + "pretty_assertions", "rand 0.7.3", + "smallvec 1.4.1", "sp-core", "sp-externalities", "sp-panic-handler", @@ -7814,13 +8385,14 @@ dependencies = [ [[package]] name = "sp-std" -version = "2.0.0-dev" +version = "2.0.0-rc6" [[package]] name = "sp-storage" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "impl-serde 0.2.3", + "impl-serde", + "parity-scale-codec", "ref-cast", "serde", "sp-debug-derive", @@ -7829,7 +8401,7 @@ dependencies = [ [[package]] name = "sp-test-primitives" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "parity-scale-codec", "parity-util-mem", @@ -7841,7 +8413,7 @@ dependencies = [ [[package]] name = "sp-timestamp" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7854,30 +8426,32 @@ dependencies = [ [[package]] name = "sp-tracing" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ + "log", + "rental", "tracing", ] [[package]] name = "sp-transaction-pool" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "derive_more", - "futures 0.3.4", + "futures 0.3.5", "log", "parity-scale-codec", "serde", "sp-api", + "sp-blockchain", "sp-runtime", - "sp-utils", ] [[package]] name = "sp-trie" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "criterion 0.2.11", + "criterion", "hash-db", "hex-literal", "memory-db", @@ -7893,19 +8467,20 @@ dependencies = [ [[package]] name = "sp-utils" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "futures-core", + "futures-timer 3.0.2", "lazy_static", "prometheus", ] [[package]] name = "sp-version" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "impl-serde 0.2.3", + "impl-serde", "parity-scale-codec", "serde", "sp-runtime", @@ -7914,7 +8489,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -7930,9 +8505,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "stable_deref_trait" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "static_assertions" @@ -7955,25 +8530,25 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8131256a5896cabcf5eb04f4d6dacbe1aefda854b0d9896e09cb58829ec5638c" dependencies = [ - "generic-array", + "generic-array 0.12.3", ] [[package]] -name = "string" -version = "0.2.1" +name = "stream-cipher" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" +checksum = "09f8ed9974042b8c3672ff3030a69fcc03b74c47c3d1ecb7755e8a3626011e88" dependencies = [ - "bytes 0.4.12", + "generic-array 0.14.3", ] [[package]] -name = "string-interner" -version = "0.7.1" +name = "string" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd710eadff449a1531351b0e43eb81ea404336fa2f56c777427ab0e32a4cf183" +checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" dependencies = [ - "serde", + "bytes 0.4.12", ] [[package]] @@ -7984,9 +8559,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6da2e8d107dfd7b74df5ef4d205c6aebee0706c647f6bc6a2d5789905c00fb" +checksum = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c" dependencies = [ "clap", "lazy_static", @@ -7995,15 +8570,15 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a489c87c08fbaf12e386665109dd13470dcc9c4583ea3e10dd2b4523e5ebd9ac" +checksum = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118" dependencies = [ "heck", "proc-macro-error", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] @@ -8023,38 +8598,21 @@ checksum = "0054a7df764039a6cd8592b9de84be4bec368ff081d203a7d5371cbfa8e65c81" dependencies = [ "heck", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] name = "subkey" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "clap", - "derive_more", "frame-system", - "futures 0.1.29", - "hex", - "hex-literal", - "hyper 0.12.35", - "itertools", - "jsonrpc-core-client", - "libp2p", "node-primitives", "node-runtime", - "pallet-balances", - "pallet-grandpa", - "pallet-transaction-payment", - "parity-scale-codec", - "rand 0.7.3", - "rpassword", - "sc-rpc", - "serde_json", + "sc-cli", "sp-core", - "sp-runtime", - "substrate-bip39", - "tiny-bip39", + "structopt", + "substrate-frame-cli", ] [[package]] @@ -8066,19 +8624,18 @@ dependencies = [ "hmac", "pbkdf2", "schnorrkel", - "sha2", + "sha2 0.8.2", ] [[package]] name = "substrate-browser-utils" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "chrono", - "clear_on_drop", "console_error_panic_hook", "console_log", "futures 0.1.29", - "futures 0.3.4", + "futures 0.3.5", "futures-timer 3.0.2", "js-sys", "kvdb-web", @@ -8097,43 +8654,56 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "platforms", ] +[[package]] +name = "substrate-frame-cli" +version = "2.0.0-rc6" +dependencies = [ + "frame-system", + "sc-cli", + "sp-core", + "sp-runtime", + "structopt", +] + [[package]] name = "substrate-frame-rpc-support" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "frame-support", "frame-system", - "futures 0.3.4", + "futures 0.3.5", "jsonrpc-client-transports", "jsonrpc-core", "parity-scale-codec", "sc-rpc-api", "serde", "sp-storage", - "tokio 0.2.18", + "tokio 0.2.22", ] [[package]] name = "substrate-frame-rpc-system" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "env_logger 0.7.1", + "env_logger", "frame-system-rpc-runtime-api", - "futures 0.3.4", + "futures 0.3.5", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", "log", "parity-scale-codec", "sc-client-api", + "sc-rpc-api", "sc-transaction-pool", "serde", "sp-api", + "sp-block-builder", "sp-blockchain", "sp-core", "sp-runtime", @@ -8143,29 +8713,34 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" -version = "0.8.0-dev" +version = "0.8.0-rc6" dependencies = [ "async-std", "derive_more", "futures-util", - "hyper 0.13.4", + "hyper 0.13.7", "log", "prometheus", - "tokio 0.2.18", + "tokio 0.2.22", ] [[package]] name = "substrate-test-client" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "futures 0.3.4", + "futures 0.1.29", + "futures 0.3.5", "hash-db", + "hex", "parity-scale-codec", "sc-client-api", "sc-client-db", "sc-consensus", "sc-executor", + "sc-light", "sc-service", + "serde", + "serde_json", "sp-blockchain", "sp-consensus", "sp-core", @@ -8176,7 +8751,7 @@ dependencies = [ [[package]] name = "substrate-test-runtime" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "cfg-if", "frame-executive", @@ -8219,13 +8794,14 @@ dependencies = [ [[package]] name = "substrate-test-runtime-client" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "parity-scale-codec", "sc-block-builder", "sc-client-api", "sc-consensus", + "sc-light", "sc-service", "sp-api", "sp-blockchain", @@ -8238,10 +8814,10 @@ dependencies = [ [[package]] name = "substrate-test-runtime-transaction-pool" -version = "2.0.0-dev" +version = "2.0.0-rc6" dependencies = [ "derive_more", - "futures 0.3.4", + "futures 0.3.5", "parity-scale-codec", "parking_lot 0.10.2", "sc-transaction-graph", @@ -8253,115 +8829,51 @@ dependencies = [ [[package]] name = "substrate-test-utils" -version = "2.0.0-dev" - -[[package]] -name = "substrate-wasm-builder" -version = "1.0.10" +version = "2.0.0-rc6" dependencies = [ - "atty", - "build-helper", - "cargo_metadata", - "fs2", - "itertools", - "tempfile", - "toml", - "walkdir", - "wasm-gc-api", + "futures 0.3.5", + "sc-service", + "substrate-test-utils-derive", + "tokio 0.2.22", + "trybuild", ] [[package]] -name = "substrate-wasm-builder-runner" -version = "1.0.6" - -[[package]] -name = "substrate-wasmtime" -version = "0.16.0-threadsafe.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40a6f3d5d3c00754e348863fead4f37763c32eedf950f5b23df87769882311" +name = "substrate-test-utils-derive" +version = "0.8.0-rc6" dependencies = [ - "anyhow", - "backtrace", - "cfg-if", - "lazy_static", - "libc", - "region", - "rustc-demangle", - "substrate-wasmtime-jit", - "substrate-wasmtime-profiling", - "substrate-wasmtime-runtime", - "target-lexicon", - "wasmparser 0.52.2", - "wasmtime-environ", - "wat", - "winapi 0.3.8", + "proc-macro-crate", + "quote", + "syn", ] [[package]] -name = "substrate-wasmtime-jit" -version = "0.16.0-threadsafe.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09712de4f56a2c2912bee7763b0877d17d72cfb2237987d63ab78956907e7692" +name = "substrate-test-utils-test-crate" +version = "0.1.0" dependencies = [ - "anyhow", - "cfg-if", - "cranelift-codegen", - "cranelift-entity", - "cranelift-frontend", - "cranelift-native", - "cranelift-wasm", - "gimli", - "log", - "more-asserts", - "region", - "substrate-wasmtime-profiling", - "substrate-wasmtime-runtime", - "target-lexicon", - "thiserror", - "wasmparser 0.52.2", - "wasmtime-debug", - "wasmtime-environ", - "winapi 0.3.8", + "sc-service", + "substrate-test-utils", + "tokio 0.2.22", ] [[package]] -name = "substrate-wasmtime-profiling" -version = "0.16.0-threadsafe.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31505dd221f001634a54ea51472bc0058bcbde9186eaf8dd31d0859638121385" -dependencies = [ - "anyhow", - "cfg-if", - "gimli", - "lazy_static", - "libc", - "object", - "scroll", - "serde", - "substrate-wasmtime-runtime", - "target-lexicon", - "wasmtime-environ", +name = "substrate-wasm-builder" +version = "2.0.0" +dependencies = [ + "atty", + "build-helper", + "cargo_metadata", + "fs2", + "itertools 0.8.2", + "tempfile", + "toml", + "walkdir", + "wasm-gc-api", ] [[package]] -name = "substrate-wasmtime-runtime" -version = "0.16.0-threadsafe.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3708081f04d9216d4dee487abf94872065f930cf82e287bd0c5bdb57895460ba" -dependencies = [ - "backtrace", - "cc", - "cfg-if", - "indexmap", - "lazy_static", - "libc", - "memoffset", - "more-asserts", - "region", - "thiserror", - "wasmtime-environ", - "winapi 0.3.8", -] +name = "substrate-wasm-builder-runner" +version = "1.0.6" [[package]] name = "subtle" @@ -8371,30 +8883,19 @@ checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" [[package]] name = "subtle" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941" - -[[package]] -name = "syn" -version = "0.11.11" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid 0.0.4", -] +checksum = "502d53007c02d7605a05df1c1a73ee436952781653da5d0bf57ad608f66932c1" [[package]] name = "syn" -version = "1.0.17" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" +checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0" dependencies = [ "proc-macro2", - "quote 1.0.3", - "unicode-xid 0.2.0", + "quote", + "unicode-xid", ] [[package]] @@ -8404,44 +8905,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", -] - -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -dependencies = [ - "unicode-xid 0.0.4", + "quote", + "syn", ] [[package]] name = "synstructure" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", - "unicode-xid 0.2.0", -] - -[[package]] -name = "sysinfo" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0338198966bde7feb14b011a33d404a62a6e03b843352c71512a2a002634b7" -dependencies = [ - "cfg-if", - "doc-comment", - "libc", - "ntapi", - "once_cell", - "rayon", - "winapi 0.3.8", + "quote", + "syn", + "unicode-xid", ] [[package]] @@ -8467,7 +8944,7 @@ dependencies = [ "rand 0.7.3", "redox_syscall", "remove_dir_all", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -8487,8 +8964,8 @@ checksum = "a605baa797821796a751f4a959e1206079b24a4b7e1ed302b7d785d81a9276c9" dependencies = [ "lazy_static", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", "version_check", ] @@ -8503,22 +8980,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.15" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b3d3d2ff68104100ab257bb6bb0cb26c901abe4bd4ba15961f3bf867924012" +checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.15" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca972988113b7715266f91250ddb98070d033c62a011fa0fcc57434a649310dd" +checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", ] [[package]] @@ -8532,22 +9009,21 @@ dependencies = [ [[package]] name = "threadpool" -version = "1.7.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" dependencies = [ "num_cpus", ] [[package]] name = "time" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "redox_syscall", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -8558,23 +9034,14 @@ checksum = "b0165e045cc2ae1660270ca65e1676dbaab60feb0f91b10f7d0665e9b47e31f2" dependencies = [ "failure", "hmac", - "once_cell", + "once_cell 1.4.0", "pbkdf2", "rand 0.7.3", "rustc-hash", - "sha2", + "sha2 0.8.2", "unicode-normalization", ] -[[package]] -name = "tiny-keccak" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" -dependencies = [ - "crunchy", -] - [[package]] name = "tiny-keccak" version = "2.0.2" @@ -8586,14 +9053,20 @@ dependencies = [ [[package]] name = "tinytemplate" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a3c6667d3e65eb1bc3aed6fd14011c6cbc3a0665218ab7f5daf040b9ec371a" +checksum = "6d3dc76004a03cec1c5932bca4cdc2e39aaa798e3f82363dd94f9adf6098c12f" dependencies = [ "serde", "serde_json", ] +[[package]] +name = "tinyvec" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" + [[package]] name = "tokio" version = "0.1.22" @@ -8620,11 +9093,11 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.18" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ef16d072d2b6dc8b4a56c70f5c5ced1a37752116f8e7c1e80c659aa7cb6713" +checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "fnv", "futures-core", "iovec", @@ -8638,7 +9111,7 @@ dependencies = [ "signal-hook-registry", "slab", "tokio-macros", - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -8723,8 +9196,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", +] + +[[package]] +name = "tokio-named-pipes" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d282d483052288b2308ba5ee795f5673b159c9bdf63c385a05609da782a5eae" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.29", + "mio", + "mio-named-pipes", + "tokio 0.1.22", ] [[package]] @@ -8748,16 +9234,25 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4adb8b3e5f86b707f1b54e7c15b6de52617a823608ccda98a15d3a24222f265a" +checksum = "228139ddd4fea3fa345a29233009635235833e52807af7ea6448ead03890d6a9" dependencies = [ "futures-core", "rustls", - "tokio 0.2.18", + "tokio 0.2.22", "webpki", ] +[[package]] +name = "tokio-service" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" +dependencies = [ + "futures 0.1.29", +] + [[package]] name = "tokio-sync" version = "0.1.8" @@ -8839,9 +9334,9 @@ dependencies = [ [[package]] name = "tokio-uds" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5076db410d6fdc6523df7595447629099a1fdc47b3d9f896220780fa48faf798" +checksum = "ab57a4ac4111c8c9dbcf70779f6fc8bc35ae4b2454809febac840ad19bd7e4e0" dependencies = [ "bytes 0.4.12", "futures 0.1.29", @@ -8861,12 +9356,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "futures-core", "futures-sink", "log", "pin-project-lite", - "tokio 0.2.18", + "tokio 0.2.22", ] [[package]] @@ -8886,32 +9381,75 @@ checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" [[package]] name = "tracing" -version = "0.1.13" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1721cc8cf7d770cc4257872507180f35a4797272f5962f24c806af9e7faf52ab" +checksum = "f0aae59226cf195d8e74d4b34beae1859257efb4e5fed3f147d2dc2c7d372178" dependencies = [ "cfg-if", + "log", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbad39da2f9af1cae3016339ad7f2c7a9e870f12e8fd04c4fd7ef35b30c0d2b" +checksum = "f0693bf8d6f2bf22c690fc61a9d21ac69efdbb894a17ed596b9af0f01e64b84b" dependencies = [ - "quote 1.0.3", - "syn 1.0.17", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "tracing-core" -version = "0.1.10" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2734b5a028fa697686f16c6d18c2c6a3c7e41513f9a213abb6754c4acb3c8d7" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6ccba2f8f16e0ed268fc765d9b7ff22e965e7185d32f8f1ec8294fe17d86e79" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa83a9a47081cd522c09c81b31aec2c9273424976f922ad61c053b58350b715" +checksum = "f7b33f8b2ef2ab0c3778c12646d9c42a24f7772bee4cdafc72199644a9f58fdc" dependencies = [ + "ansi_term 0.12.1", + "chrono", "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec 1.4.1", + "tracing-core", + "tracing-log", + "tracing-serde", ] [[package]] @@ -8922,11 +9460,11 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" [[package]] name = "trie-bench" -version = "0.21.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48b309cdda1abbdada28424bdc46f8b85362b3e66d6786d91223e83874429c7" +checksum = "af2cc37cac8cc158119982c920cbb9b8243d8540c1d13b8aca84484bfc83a426" dependencies = [ - "criterion 0.2.11", + "criterion", "hash-db", "keccak-hasher", "memory-db", @@ -8938,15 +9476,15 @@ dependencies = [ [[package]] name = "trie-db" -version = "0.20.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc309f34008563989045a4c4dbcc5770467f3a3785ee80a9b5cc0d83362475f" +checksum = "39f1a9a9252d38c5337cf0c5392988821a5cf1b2103245016968f2ab41de9e38" dependencies = [ "hash-db", - "hashbrown", + "hashbrown 0.8.1", "log", "rustc-hex", - "smallvec 1.3.0", + "smallvec 1.4.1", ] [[package]] @@ -8970,16 +9508,17 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "trybuild" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459186ab1afd6d93bd23c2269125f4f7694f8771fe0e64434b4bdc212b94034d" +checksum = "bbe777c4e2060f44d83892be1189f96200be8ed3d99569d5c2d5ee26e62c0ea9" dependencies = [ + "dissimilar", "glob 0.3.0", "lazy_static", "serde", @@ -8996,7 +9535,7 @@ checksum = "712d261e83e727c8e2dbb75dacac67c36e35db36a958ee504f2164fc052434e1" dependencies = [ "block-cipher-trait", "byteorder 1.3.4", - "opaque-debug", + "opaque-debug 0.2.3", ] [[package]] @@ -9005,7 +9544,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56" dependencies = [ - "rand 0.7.3", + "rand 0.5.6", ] [[package]] @@ -9016,9 +9555,9 @@ checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" [[package]] name = "uint" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" +checksum = "173cd16430c206dc1a430af8a89a0e9c076cf15cb42b4aedb10e8cc8fee73681" dependencies = [ "byteorder 1.3.4", "crunchy", @@ -9046,11 +9585,11 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" +checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" dependencies = [ - "smallvec 1.3.0", + "tinyvec", ] [[package]] @@ -9061,29 +9600,39 @@ checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" [[package]] name = "unicode-width" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.0.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] -name = "unicode-xid" -version = "0.2.0" +name = "universal-hash" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" +dependencies = [ + "generic-array 0.14.3", + "subtle 2.2.3", +] [[package]] name = "unsigned-varint" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f67332660eb59a6f1eb24ff1220c9e8d01738a8503c6002e30bcfe4bd9f2b4a9" + +[[package]] +name = "unsigned-varint" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "669d776983b692a906c881fcd0cfb34271a48e197e4d6cb8df32b05bfc3d3fa5" dependencies = [ - "bytes 0.5.4", + "bytes 0.5.6", "futures-io", "futures-util", "futures_codec", @@ -9091,9 +9640,9 @@ dependencies = [ [[package]] name = "untrusted" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" @@ -9119,21 +9668,21 @@ dependencies = [ [[package]] name = "vcpkg" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" +checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" [[package]] name = "vec_map" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] name = "void" @@ -9155,9 +9704,9 @@ dependencies = [ [[package]] name = "wabt-sys" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7043ebb3e5d96fad7a8d3ca22ee9880748ff8c3e18092cfb2a49d3b8f9084" +checksum = "01c695f98f7eb81fd4e2f6b65301ccc916a950dc2265eeefc4d376b34ce666df" dependencies = [ "cc", "cmake", @@ -9173,6 +9722,12 @@ dependencies = [ "libc", ] +[[package]] +name = "waker-fn" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9571542c2ce85ce642e6b58b3364da2fb53526360dfb7c211add4f5c23105ff7" + [[package]] name = "walkdir" version = "2.3.1" @@ -9180,7 +9735,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" dependencies = [ "same-file", - "winapi 0.3.8", + "winapi 0.3.9", "winapi-util", ] @@ -9213,9 +9768,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasm-bindgen" -version = "0.2.62" +version = "0.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c7d40d09cdbf0f4895ae58cf57d92e1e57a9dd8ed2e8390514b54a47cc5551" +checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c" dependencies = [ "cfg-if", "serde", @@ -9225,24 +9780,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.62" +version = "0.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3972e137ebf830900db522d6c8fd74d1900dcfc733462e9a12e942b00b4ac94" +checksum = "bc71e4c5efa60fb9e74160e89b93353bc24059999c0ae0fb03affc39770310b0" dependencies = [ "bumpalo", "lazy_static", "log", "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7add542ea1ac7fdaa9dc25e031a6af33b7d63376292bd24140c637d00d1c312a" +checksum = "8a369c5e1dfb7569e14d62af4da642a3cbc2f9a3652fe586e26ac22222aa4b04" dependencies = [ "cfg-if", "js-sys", @@ -9252,38 +9807,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.62" +version = "0.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cd85aa2c579e8892442954685f0d801f9129de24fa2136b2c6a539c76b65776" +checksum = "97c57cefa5fa80e2ba15641578b44d36e7a64279bc5ed43c6dbaf329457a2ed2" dependencies = [ - "quote 1.0.3", + "quote", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.62" +version = "0.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a" +checksum = "841a6d1c35c6f596ccea1f82504a192a60378f64b3bb0261904ad8f2f5657556" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.62" +version = "0.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91c2916119c17a8e316507afaaa2dd94b47646048014bbdf6bef098c1bb58ad" +checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092" [[package]] name = "wasm-bindgen-test" -version = "0.3.10" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "648da3460c6d2aa04b715a936329e2e311180efe650b2127d6267f4193ccac14" +checksum = "fd8e9dad8040e378f0696b017570c6bc929aac373180e06b3d67ac5059c52da3" dependencies = [ "console_error_panic_hook", "js-sys", @@ -9295,12 +9850,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.10" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2f86cd78a2aa7b1fb4bb6ed854eccb7f9263089c79542dca1576a1518a8467" +checksum = "c358c8d2507c1bae25efa069e62ea907aa28700b25c8c33dafb0b15ba4603627" dependencies = [ "proc-macro2", - "quote 1.0.3", + "quote", ] [[package]] @@ -9320,7 +9875,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "324c5e65a08699c9c4334ba136597ab22b85dccd4b65dd1e36ccf8f723a95b54" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "js-sys", "parking_lot 0.9.0", "pin-utils", @@ -9340,7 +9895,7 @@ dependencies = [ "libc", "memory_units", "num-rational", - "num-traits 0.2.11", + "num-traits", "parity-wasm 0.41.0", "wasmi-validation", ] @@ -9356,43 +9911,70 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.51.4" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeb1956b19469d1c5e63e459d29e7b5aa0f558d9f16fcef09736f8a265e6c10a" +checksum = "32fddd575d477c6e9702484139cf9f23dcd554b06d185ed0f56c857dd3a47aa6" [[package]] name = "wasmparser" -version = "0.52.2" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a950e6a618f62147fd514ff445b2a0b53120d382751960797f85f058c7eda9b9" + +[[package]] +name = "wasmtime" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733954023c0b39602439e60a65126fd31b003196d3a1e8e4531b055165a79b31" +checksum = "1cd3c4f449382779ef6e0a7c3ec6752ae614e20a42e4100000c3efdc973100e2" +dependencies = [ + "anyhow", + "backtrace", + "cfg-if", + "lazy_static", + "libc", + "log", + "region", + "rustc-demangle", + "smallvec 1.4.1", + "target-lexicon", + "wasmparser 0.59.0", + "wasmtime-environ", + "wasmtime-jit", + "wasmtime-profiling", + "wasmtime-runtime", + "wat", + "winapi 0.3.9", +] [[package]] name = "wasmtime-debug" -version = "0.16.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39ba645aee700b29ff0093028b4123556dd142a74973f04ed6225eedb40e77d" +checksum = "6e634af9067a3af6cf2c7d33dc3b84767ddaf5d010ba68e80eecbcea73d4a349" dependencies = [ "anyhow", - "faerie", - "gimli", + "gimli 0.21.0", "more-asserts", + "object 0.20.0", "target-lexicon", "thiserror", - "wasmparser 0.51.4", + "wasmparser 0.59.0", "wasmtime-environ", ] [[package]] name = "wasmtime-environ" -version = "0.16.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed54fd9d64dfeeee7c285fd126174a6b5e6d4efc7e5a1566fdb635e60ff6a74e" +checksum = "08f85619a94ee4034bd5bb87fc3dcf71fd2237b81c840809da1201061eec9ab3" dependencies = [ "anyhow", - "base64 0.12.0", + "base64 0.12.3", "bincode", + "cfg-if", "cranelift-codegen", "cranelift-entity", + "cranelift-frontend", "cranelift-wasm", "directories", "errno", @@ -9403,37 +9985,120 @@ dependencies = [ "more-asserts", "rayon", "serde", - "sha2", + "sha2 0.8.2", "thiserror", "toml", - "wasmparser 0.51.4", - "winapi 0.3.8", + "wasmparser 0.59.0", + "winapi 0.3.9", "zstd", ] +[[package]] +name = "wasmtime-jit" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e914c013c7a9f15f4e429d5431f2830fb8adb56e40567661b69c5ec1d645be23" +dependencies = [ + "anyhow", + "cfg-if", + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "cranelift-native", + "cranelift-wasm", + "gimli 0.21.0", + "log", + "more-asserts", + "object 0.20.0", + "region", + "target-lexicon", + "thiserror", + "wasmparser 0.59.0", + "wasmtime-debug", + "wasmtime-environ", + "wasmtime-obj", + "wasmtime-profiling", + "wasmtime-runtime", + "winapi 0.3.9", +] + +[[package]] +name = "wasmtime-obj" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e81d8e02e9bc9fe2da9b6d48bbc217f96e089f7df613f11a28a3958abc44641e" +dependencies = [ + "anyhow", + "more-asserts", + "object 0.20.0", + "target-lexicon", + "wasmtime-debug", + "wasmtime-environ", +] + +[[package]] +name = "wasmtime-profiling" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e8d4d1af8dd5f7096cfcc89dd668d358e52980c38cce199643372ffd6590e27" +dependencies = [ + "anyhow", + "cfg-if", + "gimli 0.21.0", + "lazy_static", + "libc", + "object 0.19.0", + "scroll", + "serde", + "target-lexicon", + "wasmtime-environ", + "wasmtime-runtime", +] + +[[package]] +name = "wasmtime-runtime" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a25f140bbbaadb07c531cba99ce1a966dba216138dc1b2a0ddecec851a01a93" +dependencies = [ + "backtrace", + "cc", + "cfg-if", + "indexmap", + "lazy_static", + "libc", + "log", + "memoffset", + "more-asserts", + "region", + "thiserror", + "wasmtime-environ", + "winapi 0.3.9", +] + [[package]] name = "wast" -version = "13.0.0" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b20abd8b4a26f7e0d4dd5e357e90a3d555ec190e94472c9b2b27c5b9777f9ae" +checksum = "0b1844f66a2bc8526d71690104c0e78a8e59ffa1597b7245769d174ebb91deb5" dependencies = [ "leb128", ] [[package]] name = "wat" -version = "1.0.14" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51a615830ee3e7200b505c441fec09aac2f114deae69df52f215cb828ba112c4" +checksum = "ce85d72b74242c340e9e3492cfb602652d7bb324c3172dd441b5577e39a2e18c" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.37" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb" +checksum = "8bc359e5dd3b46cb9687a051d50a2fdd228e4ba7cf6fcf861a5365c3d671a642" dependencies = [ "js-sys", "wasm-bindgen", @@ -9441,9 +10106,9 @@ dependencies = [ [[package]] name = "webpki" -version = "0.21.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f50e1972865d6b1adb54167d1c8ed48606004c2c9d0ea5f1eeb34d95e863ef" +checksum = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae" dependencies = [ "ring", "untrusted", @@ -9467,6 +10132,15 @@ dependencies = [ "webpki", ] +[[package]] +name = "wepoll-sys-stjepang" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694" +dependencies = [ + "cc", +] + [[package]] name = "which" version = "3.1.1" @@ -9484,9 +10158,9 @@ checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", @@ -9506,11 +10180,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.8", + "winapi 0.3.9", ] [[package]] @@ -9558,19 +10232,13 @@ dependencies = [ "zeroize", ] -[[package]] -name = "xdg" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" - [[package]] name = "yamux" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84300bb493cc878f3638b981c62b4632ec1a5c52daaa3036651e8c106d3b55ea" +checksum = "cd37e58a1256a0b328ce9c67d8b62ecdd02f4803ba443df478835cb1a41a637c" dependencies = [ - "futures 0.3.4", + "futures 0.3.5", "log", "nohash-hasher", "parking_lot 0.10.2", @@ -9594,25 +10262,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ "proc-macro2", - "quote 1.0.3", - "syn 1.0.17", + "quote", + "syn", "synstructure", ] [[package]] name = "zstd" -version = "0.5.1+zstd.1.4.4" +version = "0.5.3+zstd.1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5d978b793ae64375b80baf652919b148f6a496ac8802922d9999f5a553194f" +checksum = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "2.0.3+zstd.1.4.4" +version = "2.0.5+zstd.1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee25eac9753cfedd48133fa1736cbd23b774e253d89badbeac7d12b23848d3f" +checksum = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055" dependencies = [ "libc", "zstd-sys", @@ -9620,11 +10288,12 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "1.4.15+zstd.1.4.4" +version = "1.4.17+zstd.1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89719b034dc22d240d5b407fb0a3fe6d29952c181cff9a9f95c0bd40b4f8f7d8" +checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b" dependencies = [ "cc", "glob 0.3.0", + "itertools 0.9.0", "libc", ] diff --git a/Cargo.toml b/Cargo.toml index d9ee8709d1334f7ffbab48f02028a94f79b5e295..7589e8d774124c5b45e5425b072681fd2848acdb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ members = [ "client/executor/runtime-test", "client/finality-grandpa", "client/informant", + "client/light", "client/tracing", "client/keystore", "client/network", @@ -45,6 +46,7 @@ members = [ "client/network-gossip", "client/offchain", "client/peerset", + "client/proposer-metrics", "client/rpc-servers", "client/rpc", "client/rpc-api", @@ -58,6 +60,7 @@ members = [ "utils/wasm-builder-runner", "frame/assets", "frame/aura", + "frame/atomic-swap", "frame/authority-discovery", "frame/authorship", "frame/babe", @@ -83,8 +86,10 @@ members = [ "frame/indices", "frame/membership", "frame/metadata", + "frame/multisig", "frame/nicks", "frame/offences", + "frame/proxy", "frame/randomness-collective-flip", "frame/recovery", "frame/scheduler", @@ -135,9 +140,9 @@ members = [ "primitives/keyring", "primitives/offchain", "primitives/panic-handler", - "primitives/phragmen", - "primitives/phragmen/fuzzer", - "primitives/phragmen/compact", + "primitives/npos-elections", + "primitives/npos-elections/fuzzer", + "primitives/npos-elections/compact", "primitives/rpc", "primitives/runtime-interface", "primitives/runtime-interface/proc-macro", @@ -166,18 +171,89 @@ members = [ "primitives/utils", "primitives/wasm-interface", "test-utils/client", + "test-utils/derive", "test-utils/runtime", "test-utils/runtime/client", "test-utils/runtime/transaction-pool", + "test-utils/test-crate", "utils/browser", "utils/build-script-utils", "utils/fork-tree", "utils/frame/benchmarking-cli", + "utils/frame/frame-utilities-cli", "utils/frame/rpc/support", "utils/frame/rpc/system", "utils/wasm-builder", ] +# The list of dependencies below (which can be both direct and indirect dependencies) are crates +# that are suspected to be CPU-intensive, and that are unlikely to require debugging (as some of +# their debug info might be missing) or to require to be frequently recompiled. We compile these +# dependencies with `opt-level=3` even in "dev" mode in order to make "dev" mode more usable. +# The majority of these crates are cryptographic libraries. +# +# Note that this does **not** affect crates that depend on Substrate. In other words, if you add +# a dependency on Substrate, you have to copy-paste this list in your own `Cargo.toml` (assuming +# that you want the same list). This list is only relevant when running `cargo build` from within +# the Substrate workspace. +# +# If you see an error mentioning "profile package spec ... did not match any packages", it +# probably concerns this list. +# +# This list is ordered alphabetically. +[profile.dev.package] +aes-ctr = { opt-level = 3 } +aes-soft = { opt-level = 3 } +aesni = { opt-level = 3 } +blake2 = { opt-level = 3 } +blake2-rfc = { opt-level = 3 } +blake2b_simd = { opt-level = 3 } +blake2s_simd = { opt-level = 3 } +chacha20poly1305 = { opt-level = 3 } +cranelift-codegen = { opt-level = 3 } +cranelift-wasm = { opt-level = 3 } +crc32fast = { opt-level = 3 } +crossbeam-deque = { opt-level = 3 } +crossbeam-queue = { opt-level = 3 } +crypto-mac = { opt-level = 3 } +ctr = { opt-level = 3 } +curve25519-dalek = { opt-level = 3 } +ed25519-dalek = { opt-level = 3 } +evm-core = { opt-level = 3 } +evm-runtime = { opt-level = 3 } +flate2 = { opt-level = 3 } +futures-channel = { opt-level = 3 } +hashbrown = { opt-level = 3 } +h2 = { opt-level = 3 } +hash-db = { opt-level = 3 } +hmac = { opt-level = 3 } +httparse = { opt-level = 3 } +integer-sqrt = { opt-level = 3 } +keccak = { opt-level = 3 } +libm = { opt-level = 3 } +librocksdb-sys = { opt-level = 3 } +libsecp256k1 = { opt-level = 3 } +libz-sys = { opt-level = 3 } +mio = { opt-level = 3 } +nalgebra = { opt-level = 3 } +num-bigint = { opt-level = 3 } +parking_lot = { opt-level = 3 } +parking_lot_core = { opt-level = 3 } +percent-encoding = { opt-level = 3 } +primitive-types = { opt-level = 3 } +ring = { opt-level = 3 } +rustls = { opt-level = 3 } +sha2 = { opt-level = 3 } +sha3 = { opt-level = 3 } +smallvec = { opt-level = 3 } +snow = { opt-level = 3 } +twox-hash = { opt-level = 3 } +uint = { opt-level = 3 } +wasmi = { opt-level = 3 } +x25519-dalek = { opt-level = 3 } +yamux = { opt-level = 3 } +zeroize = { opt-level = 3 } + [profile.release] # Substrate runtime requires unwinding. panic = "unwind" diff --git a/LICENSE-APACHE2 b/LICENSE-APACHE2 new file mode 100644 index 0000000000000000000000000000000000000000..fbb0616d18b261c461b5a004f6bba6dda702ec09 --- /dev/null +++ b/LICENSE-APACHE2 @@ -0,0 +1,211 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +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. + + NOTE + +Individual files contain the following tag instead of the full license +text. + + SPDX-License-Identifier: Apache-2.0 + +This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ \ No newline at end of file diff --git a/LICENSE b/LICENSE-GPL3 similarity index 96% rename from LICENSE rename to LICENSE-GPL3 index 9cecc1d4669ee8af2ca727a5d8cde10cd8b2d7cc..2ba7526ee695722852efd2c162ea57f87e4fd54c 100644 --- a/LICENSE +++ b/LICENSE-GPL3 @@ -672,3 +672,29 @@ 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 . + + "CLASSPATH" EXCEPTION TO THE GPL + + Linking this library statically or dynamically with other modules is making +a combined work based on this library. Thus, the terms and conditions of the +GNU General Public License cover the whole combination. + + As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent modules, +and to copy and distribute the resulting executable under terms of your +choice, provided that you also meet, for each linked independent module, +the terms and conditions of the license of that module. An independent +module is a module which is not derived from or based on this library. +If you modify this library, you may extend this exception to your version +of the library, but you are not obligated to do so. If you do not wish to +do so, delete this exception statement from your version. + + NOTE + + Individual files contain the following tag instead of the full license text. + + SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + + This enables machine processing of license information based on the SPDX +License Identifiers that are here available: http://spdx.org/licenses/ \ No newline at end of file diff --git a/Process.json b/Process.json new file mode 100644 index 0000000000000000000000000000000000000000..540bd644311cff2ef7bb593cc47525384e024983 --- /dev/null +++ b/Process.json @@ -0,0 +1,29 @@ +[{ + "project_name": "Networking", + "owner": "tomaka", + "matrix_room_id": "!vUADSGcyXmxhKLeDsW:matrix.parity.io" +}, +{ "project_name": "Client", + "owner": "gnunicorn", + "matrix_room_id": "!aenJixaHcSKbJOWxYk:matrix.parity.io" +}, +{ + "project_name": "Runtime", + "owner": "gavofyork", + "matrix_room_id": "!yBKstWVBkwzUkPslsp:matrix.parity.io" +}, +{ + "project_name": "Consensus", + "owner": "andresilva", + "matrix_room_id": "!XdNWDTfVNFVixljKZU:matrix.parity.io" +}, +{ + "project_name": "Smart Contracts", + "owner": "pepyakin", + "matrix_room_id": "!yBKstWVBkwzUkPslsp:matrix.parity.io" +}, +{ + "project_name": "Benchmarking and Weights", + "owner": "shawntabrizi", + "matrix_room_id": "!pZPWqCRLVtORZTEsEf:matrix.parity.io" +}] diff --git a/Process.toml b/Process.toml deleted file mode 100644 index ecaf5c7120ff5cb1b5cc0f923b51e7fda4df9fca..0000000000000000000000000000000000000000 --- a/Process.toml +++ /dev/null @@ -1,24 +0,0 @@ -[Networking] -owner = "tomaka" -whitelist = [] -matrix_room_id = "!vUADSGcyXmxhKLeDsW:matrix.parity.io" - -[Client] -owner = "gnunicorn" -whitelist = [] -matrix_room_id = "!aenJixaHcSKbJOWxYk:matrix.parity.io" - -[Runtime] -owner = "gavofyork" -whitelist = [] -matrix_room_id = "!yBKstWVBkwzUkPslsp:matrix.parity.io" - -[Consensus] -owner = "andresilva" -whitelist = [] -matrix_room_id = "!XdNWDTfVNFVixljKZU:matrix.parity.io" - -[Smart Contracts] -owner = "pepyakin" -whitelist = [] -matrix_room_id = "!yBKstWVBkwzUkPslsp:matrix.parity.io" diff --git a/README.md b/README.md index cd00013d1ae8ad4fb86dee4044061f9b7b5e732b..c586919a1ddc3a6b1eb290c7dfdf424a624e08cf 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,21 @@ -# Substrate · [![GitHub license](https://img.shields.io/github/license/paritytech/substrate)](LICENSE) [![GitLab Status](https://gitlab.parity.io/parity/substrate/badges/master/pipeline.svg)](https://gitlab.parity.io/parity/substrate/pipelines) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](docs/CONTRIBUTING.adoc) +# Substrate · [![GitHub license](https://img.shields.io/badge/license-GPL3%2FApache2-blue)](LICENSE) [![GitLab Status](https://gitlab.parity.io/parity/substrate/badges/master/pipeline.svg)](https://gitlab.parity.io/parity/substrate/pipelines) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](docs/CONTRIBUTING.adoc) -Substrate is a next-generation framework for blockchain innovation. +

+ +

+ + +Substrate is a next-generation framework for blockchain innovation 🚀. ## Trying it out -Simply go to [substrate.dev](https://substrate.dev) and follow the [getting started](https://substrate.dev/docs/en/overview/getting-started/) instructions. +Simply go to [substrate.dev](https://substrate.dev) and follow the +[installation](https://substrate.dev/docs/en/knowledgebase/getting-started/) instructions. You can +also try out one of the [tutorials](https://substrate.dev/en/tutorials). ## Contributions & Code of Conduct -Please follow the contributions guidelines as outlined in [`docs/CONTRIBUTING.adoc`](docs/CONTRIBUTING.adoc). In all communications and contributions, this project follows the [Contributor Covenant Code of Conduct](docs/CODE_OF_CONDUCT.adoc). +Please follow the contributions guidelines as outlined in [`docs/CONTRIBUTING.adoc`](docs/CONTRIBUTING.adoc). In all communications and contributions, this project follows the [Contributor Covenant Code of Conduct](docs/CODE_OF_CONDUCT.md). ## Security @@ -16,4 +23,9 @@ The security policy and procedures can be found in [`docs/SECURITY.md`](docs/SEC ## License -Substrate is [GPL 3.0 licensed](LICENSE). +- Substrate Primitives (`sp-*`), Frame (`frame-*`) and the pallets (`pallets-*`), binaries (`/bin`) and all other utilities are licensed under [Apache 2.0](LICENSE-APACHE2). +- Substrate Client (`/client/*` / `sc-*`) is licensed under [GPL v3.0 with a classpath linking exception](LICENSE-GPL3). + +The reason for the split-licensing is to ensure that for the vast majority of teams using Substrate to create feature-chains, then all changes can be made entirely in Apache2-licensed code, allowing teams full freedom over what and how they release and giving licensing clarity to commercial teams. + +In the interests of the community, we require any deeper improvements made to Substrate's core logic (e.g. Substrate's internal consensus, crypto or database code) to be contributed back so everyone can benefit. diff --git a/bin/node-template/README.md b/bin/node-template/README.md index c1730d51e5c137e6a02ebee623f6a5fba25a2630..5623fedb5342bef16f03285b33ce9fc1daf184cd 100644 --- a/bin/node-template/README.md +++ b/bin/node-template/README.md @@ -1,22 +1,30 @@ # Substrate Node Template -A new FRAME-based Substrate node, ready for hacking. +A new FRAME-based Substrate node, ready for hacking :rocket: -## Build +## Local Development -Install Rust: +Follow these steps to prepare a local Substrate development environment :hammer_and_wrench: -```bash -curl https://sh.rustup.rs -sSf | sh -``` +### Simple Setup -Initialize your Wasm Build environment: +Install all the required dependencies with a single command (be patient, this can take up to 30 +minutes). ```bash -./scripts/init.sh +curl https://getsubstrate.io -sSf | bash -s -- --fast ``` -Build Wasm and native code: +### Manual Setup + +Find manual setup instructions at the +[Substrate Developer Hub](https://substrate.dev/docs/en/knowledgebase/getting-started/#manual-installation). + +### Build + +Once the development environment is set up, build the node template. This command will build the +[Wasm](https://substrate.dev/docs/en/knowledgebase/advanced/executor#wasm-execution) and +[native](https://substrate.dev/docs/en/knowledgebase/advanced/executor#native-execution) code: ```bash cargo build --release @@ -24,31 +32,38 @@ cargo build --release ## Run -### Single node development chain +### Single Node Development Chain -Purge any existing developer chain state: +Purge any existing dev chain state: ```bash ./target/release/node-template purge-chain --dev ``` -Start a development chain with: +Start a dev chain: ```bash ./target/release/node-template --dev ``` -Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`. +Or, start a dev chain with detailed logging: -### Multi-node local testnet +```bash +RUST_LOG=debug RUST_BACKTRACE=1 ./target/release/node-template -lruntime=debug --dev +``` -If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units. +### Multi-Node Local Testnet -Optionally, give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). +To see the multi-node consensus algorithm in action, run a local testnet with two validator nodes, +Alice and Bob, that have been [configured](/bin/node-template/node/src/chain_spec.rs) as the initial +authorities of the `local` testnet chain and endowed with testnet units. -You'll need two terminal windows open. +Note: this will require two terminal sessions (one for each node). -We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The bootnode ID of her node is `QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR`, which is generated from the `--node-key` value that we specify below: +Start Alice's node first. The command below uses the default TCP port (30333) and specifies +`/tmp/alice` as the chain database location. Alice's node ID will be +`12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp` (legacy representation: +`QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR`); this is determined by the `node-key`. ```bash cargo run -- \ @@ -60,17 +75,133 @@ cargo run -- \ --validator ``` -In the second terminal, we'll start Bob's substrate node on a different TCP port of 30334, and with his chain database stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's bootnode ID on TCP port 30333: +In another terminal, use the following command to start Bob's node on a different TCP port (30334) +and with a chain database location of `/tmp/bob`. The `--bootnodes` option will connect his node to +Alice's on TCP port 30333: ```bash cargo run -- \ --base-path /tmp/bob \ - --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/QmRpheLN4JWdAnY7HGJfWFNbfkQCb6tFf4vvA6hgjMZKrR \ + --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp \ --chain=local \ --bob \ --port 30334 \ + --ws-port 9945 \ --telemetry-url 'ws://telemetry.polkadot.io:1024 0' \ --validator ``` -Additional CLI usage options are available and may be shown by running `cargo run -- --help`. +Execute `cargo run -- --help` to learn more about the template node's CLI options. + +## Template Structure + +A Substrate project such as this consists of a number of components that are spread across a few +directories. + +### Node + +A blockchain node is an application that allows users to participate in a blockchain network. +Substrate-based blockchain nodes expose a number of capabilities: + +- Networking: Substrate nodes use the [`libp2p`](https://libp2p.io/) networking stack to allow the + nodes in the network to communicate with one another. +- Consensus: Blockchains must have a way to come to + [consensus](https://substrate.dev/docs/en/knowledgebase/advanced/consensus) on the state of the + network. Substrate makes it possible to supply custom consensus engines and also ships with + several consensus mechanisms that have been built on top of + [Web3 Foundation research](https://research.web3.foundation/en/latest/polkadot/NPoS/index.html). +- RPC Server: A remote procedure call (RPC) server is used to interact with Substrate nodes. + +There are several files in the `node` directory - take special note of the following: + +- [`chain_spec.rs`](./node/src/chain_spec.rs): A + [chain specification](https://substrate.dev/docs/en/knowledgebase/integrate/chain-spec) is a + source code file that defines a Substrate chain's initial (genesis) state. Chain specifications + are useful for development and testing, and critical when architecting the launch of a + production chain. Take note of the `development_config` and `testnet_genesis` functions, which + are used to define the genesis state for the local development chain configuration. These + functions identify some + [well-known accounts](https://substrate.dev/docs/en/knowledgebase/integrate/subkey#well-known-keys) + and use them to configure the blockchain's initial state. +- [`service.rs`](./node/src/service.rs): This file defines the node implementation. Take note of + the libraries that this file imports and the names of the functions it invokes. In particular, + there are references to consensus-related topics, such as the + [longest chain rule](https://substrate.dev/docs/en/knowledgebase/advanced/consensus#longest-chain-rule), + the [Aura](https://substrate.dev/docs/en/knowledgebase/advanced/consensus#aura) block authoring + mechanism and the + [GRANDPA](https://substrate.dev/docs/en/knowledgebase/advanced/consensus#grandpa) finality + gadget. + +After the node has been [built](#build), refer to the embedded documentation to learn more about the +capabilities and configuration parameters that it exposes: + +```shell +./target/release/node-template --help +``` + +### Runtime + +In Substrate, the terms +"[runtime](https://substrate.dev/docs/en/knowledgebase/getting-started/glossary#runtime)" and +"[state transition function](https://substrate.dev/docs/en/knowledgebase/getting-started/glossary#stf-state-transition-function)" +are analogous - they refer to the core logic of the blockchain that is responsible for validating +blocks and executing the state changes they define. The Substrate project in this repository uses +the [FRAME](https://substrate.dev/docs/en/knowledgebase/runtime/frame) framework to construct a +blockchain runtime. FRAME allows runtime developers to declare domain-specific logic in modules +called "pallets". At the heart of FRAME is a helpful +[macro language](https://substrate.dev/docs/en/knowledgebase/runtime/macros) that makes it easy to +create pallets and flexibly compose them to create blockchains that can address +[a variety of needs](https://www.substrate.io/substrate-users/). + +Review the [FRAME runtime implementation](./runtime/src/lib.rs) included in this template and note +the following: + +- This file configures several pallets to include in the runtime. Each pallet configuration is + defined by a code block that begins with `impl $PALLET_NAME::Trait for Runtime`. +- The pallets are composed into a single runtime by way of the + [`construct_runtime!`](https://crates.parity.io/frame_support/macro.construct_runtime.html) + macro, which is part of the core + [FRAME Support](https://substrate.dev/docs/en/knowledgebase/runtime/frame#support-library) + library. + +### Pallets + +The runtime in this project is constructed using many FRAME pallets that ship with the +[core Substrate repository](https://github.com/paritytech/substrate/tree/master/frame) and a +template pallet that is [defined in the `pallets`](./pallets/template/src/lib.rs) directory. + +A FRAME pallet is compromised of a number of blockchain primitives: + +- Storage: FRAME defines a rich set of powerful + [storage abstractions](https://substrate.dev/docs/en/knowledgebase/runtime/storage) that makes + it easy to use Substrate's efficient key-value database to manage the evolving state of a + blockchain. +- Dispatchables: FRAME pallets define special types of functions that can be invoked (dispatched) + from outside of the runtime in order to update its state. +- Events: Substrate uses [events](https://substrate.dev/docs/en/knowledgebase/runtime/events) to + notify users of important changes in the runtime. +- Errors: When a dispatchable fails, it returns an error. +- Trait: The `Trait` configuration interface is used to define the types and parameters upon which + a FRAME pallet depends. + +## Generate a Custom Node Template + +Generate a Substrate node template based on a particular commit by running the following commands: + +```bash +# Clone from the main Substrate repo +git clone https://github.com/paritytech/substrate.git +cd substrate + +# Switch to the branch or commit to base the template on +git checkout + +# Run the helper script to generate a node template. This script compiles Substrate, so it will take +# a while to complete. It expects a single parameter: the location for the script's output expressed +# as a relative path. +.maintain/node-template-release.sh ../node-template.tar.gz +``` + +Custom node templates are not supported. Please use a recently tagged version of the +[Substrate Developer Node Template](https://github.com/substrate-developer-hub/substrate-node-template) +in order to receive support. diff --git a/bin/node-template/node/Cargo.toml b/bin/node-template/node/Cargo.toml index 030672ee6ff1accbe00aa9cb67a1eef37e85c44e..d8cc9478bbda8e07459b06433095de1b0550cccb 100644 --- a/bin/node-template/node/Cargo.toml +++ b/bin/node-template/node/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "node-template" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Anonymous"] -description = "Substrate Node template" +description = "A new FRAME-based Substrate node, ready for hacking." edition = "2018" license = "Unlicense" build = "build.rs" @@ -16,30 +16,36 @@ targets = ["x86_64-unknown-linux-gnu"] name = "node-template" [dependencies] -futures = "0.3.4" -log = "0.4.8" structopt = "0.3.8" -parking_lot = "0.10.0" -sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sc-executor = { version = "0.8.0-dev", path = "../../../client/executor" } -sc-service = { version = "0.8.0-dev", path = "../../../client/service" } -sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } -sc-transaction-pool = { version = "2.0.0-dev", path = "../../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } -sc-network = { version = "0.8.0-dev", path = "../../../client/network" } -sc-consensus-aura = { version = "0.8.0-dev", path = "../../../client/consensus/aura" } -sp-consensus-aura = { version = "0.8.0-dev", path = "../../../primitives/consensus/aura" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -sc-consensus = { version = "0.8.0-dev", path = "../../../client/consensus/common" } -sc-finality-grandpa = { version = "0.8.0-dev", path = "../../../client/finality-grandpa" } -sp-finality-grandpa = { version = "2.0.0-dev", path = "../../../primitives/finality-grandpa" } -sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sc-basic-authorship = { path = "../../../client/basic-authorship", version = "0.8.0-dev"} +sc-cli = { version = "0.8.0-rc6", path = "../../../client/cli", features = ["wasmtime"] } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sc-executor = { version = "0.8.0-rc6", path = "../../../client/executor", features = ["wasmtime"] } +sc-service = { version = "0.8.0-rc6", path = "../../../client/service", features = ["wasmtime"] } +sp-inherents = { version = "2.0.0-rc6", path = "../../../primitives/inherents" } +sc-transaction-pool = { version = "2.0.0-rc6", path = "../../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../../primitives/transaction-pool" } +sc-consensus-aura = { version = "0.8.0-rc6", path = "../../../client/consensus/aura" } +sp-consensus-aura = { version = "0.8.0-rc6", path = "../../../primitives/consensus/aura" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sc-consensus = { version = "0.8.0-rc6", path = "../../../client/consensus/common" } +sc-finality-grandpa = { version = "0.8.0-rc6", path = "../../../client/finality-grandpa" } +sp-finality-grandpa = { version = "2.0.0-rc6", path = "../../../primitives/finality-grandpa" } +sc-client-api = { version = "2.0.0-rc6", path = "../../../client/api" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } -node-template-runtime = { version = "2.0.0-dev", path = "../runtime" } +# These dependencies are used for the node template's RPCs +jsonrpc-core = "14.0.3" +sc-rpc = { version = "2.0.0-rc6", path = "../../../client/rpc" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +sc-rpc-api = { version = "0.8.0-rc6", path = "../../../client/rpc-api" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-block-builder = { version = "2.0.0-rc6", path = "../../../primitives/block-builder" } +sc-basic-authorship = { version = "0.8.0-rc6", path = "../../../client/basic-authorship" } +substrate-frame-rpc-system = { version = "2.0.0-rc6", path = "../../../utils/frame/rpc/system" } +pallet-transaction-payment-rpc = { version = "2.0.0-rc6", path = "../../../frame/transaction-payment/rpc/" } + +node-template-runtime = { version = "2.0.0-rc6", path = "../runtime" } [build-dependencies] -substrate-build-script-utils = { version = "2.0.0-dev", path = "../../../utils/build-script-utils" } +substrate-build-script-utils = { version = "2.0.0-rc6", path = "../../../utils/build-script-utils" } diff --git a/bin/node-template/node/src/chain_spec.rs b/bin/node-template/node/src/chain_spec.rs index fb53edd9a1a06b44fd2626feda427b79b0c08a5f..41f582fb64a46cf598c0f424b23793b95f0291db 100644 --- a/bin/node-template/node/src/chain_spec.rs +++ b/bin/node-template/node/src/chain_spec.rs @@ -8,13 +8,13 @@ use sp_finality_grandpa::AuthorityId as GrandpaId; use sp_runtime::traits::{Verify, IdentifyAccount}; use sc_service::ChainType; -// Note this is the URL for the telemetry server -//const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; +// The URL for the telemetry server. +// const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; /// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type. pub type ChainSpec = sc_service::GenericChainSpec; -/// Helper function to generate a crypto pair from seed +/// Generate a crypto pair from seed. pub fn get_from_seed(seed: &str) -> ::Public { TPublic::Pair::from_string(&format!("//{}", seed), None) .expect("static values are valid; qed") @@ -23,14 +23,14 @@ pub fn get_from_seed(seed: &str) -> ::Pu type AccountPublic = ::Signer; -/// Helper function to generate an account ID from seed +/// Generate an account ID from seed. pub fn get_account_id_from_seed(seed: &str) -> AccountId where AccountPublic: From<::Public> { AccountPublic::from(get_from_seed::(seed)).into_account() } -/// Helper function to generate an authority key for Aura +/// Generate an Aura authority key. pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { ( get_from_seed::(s), @@ -38,16 +38,24 @@ pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { ) } -pub fn development_config() -> ChainSpec { - ChainSpec::from_genesis( +pub fn development_config() -> Result { + let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?; + + Ok(ChainSpec::from_genesis( + // Name "Development", + // ID "dev", ChainType::Development, - || testnet_genesis( + move || testnet_genesis( + wasm_binary, + // Initial PoA authorities vec![ authority_keys_from_seed("Alice"), ], + // Sudo account get_account_id_from_seed::("Alice"), + // Pre-funded accounts vec![ get_account_id_from_seed::("Alice"), get_account_id_from_seed::("Bob"), @@ -56,25 +64,38 @@ pub fn development_config() -> ChainSpec { ], true, ), + // Bootnodes vec![], + // Telemetry None, + // Protocol ID None, + // Properties None, + // Extensions None, - ) + )) } -pub fn local_testnet_config() -> ChainSpec { - ChainSpec::from_genesis( +pub fn local_testnet_config() -> Result { + let wasm_binary = WASM_BINARY.ok_or("Development wasm binary not available".to_string())?; + + Ok(ChainSpec::from_genesis( + // Name "Local Testnet", + // ID "local_testnet", ChainType::Local, - || testnet_genesis( + move || testnet_genesis( + wasm_binary, + // Initial PoA authorities vec![ authority_keys_from_seed("Alice"), authority_keys_from_seed("Bob"), ], + // Sudo account get_account_id_from_seed::("Alice"), + // Pre-funded accounts vec![ get_account_id_from_seed::("Alice"), get_account_id_from_seed::("Bob"), @@ -91,33 +112,45 @@ pub fn local_testnet_config() -> ChainSpec { ], true, ), + // Bootnodes vec![], + // Telemetry None, + // Protocol ID None, + // Properties None, + // Extensions None, - ) + )) } -fn testnet_genesis(initial_authorities: Vec<(AuraId, GrandpaId)>, +/// Configure initial storage state for FRAME modules. +fn testnet_genesis( + wasm_binary: &[u8], + initial_authorities: Vec<(AuraId, GrandpaId)>, root_key: AccountId, endowed_accounts: Vec, - _enable_println: bool) -> GenesisConfig { + _enable_println: bool, +) -> GenesisConfig { GenesisConfig { - system: Some(SystemConfig { - code: WASM_BINARY.to_vec(), + frame_system: Some(SystemConfig { + // Add Wasm runtime to storage. + code: wasm_binary.to_vec(), changes_trie_config: Default::default(), }), - balances: Some(BalancesConfig { + pallet_balances: Some(BalancesConfig { + // Configure endowed accounts with initial balance of 1 << 60. balances: endowed_accounts.iter().cloned().map(|k|(k, 1 << 60)).collect(), }), - aura: Some(AuraConfig { + pallet_aura: Some(AuraConfig { authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(), }), - grandpa: Some(GrandpaConfig { + pallet_grandpa: Some(GrandpaConfig { authorities: initial_authorities.iter().map(|x| (x.1.clone(), 1)).collect(), }), - sudo: Some(SudoConfig { + pallet_sudo: Some(SudoConfig { + // Assign network admin rights. key: root_key, }), } diff --git a/bin/node-template/node/src/cli.rs b/bin/node-template/node/src/cli.rs index 0091ef7d75912f736c1cbffde84d29e17186038c..46ab9bc3dafac3b95c1ab196c10aae0a544bf413 100644 --- a/bin/node-template/node/src/cli.rs +++ b/bin/node-template/node/src/cli.rs @@ -1,5 +1,5 @@ -use sc_cli::{RunCmd, Subcommand}; use structopt::StructOpt; +use sc_cli::{RunCmd, Subcommand}; #[derive(Debug, StructOpt)] pub struct Cli { diff --git a/bin/node-template/node/src/command.rs b/bin/node-template/node/src/command.rs index baac33e9aca83311fe76a378afe04966a0337c6c..9cd2248d6547a133b09a09fb7c62e9b6b8c357bf 100644 --- a/bin/node-template/node/src/command.rs +++ b/bin/node-template/node/src/command.rs @@ -1,80 +1,86 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use crate::chain_spec; use crate::cli::Cli; use crate::service; -use sc_cli::SubstrateCli; +use sc_cli::{SubstrateCli, RuntimeVersion, Role, ChainSpec}; +use sc_service::PartialComponents; +use crate::service::new_partial; impl SubstrateCli for Cli { - fn impl_name() -> &'static str { - "Substrate Node" + fn impl_name() -> String { + "Substrate Node".into() } - fn impl_version() -> &'static str { - env!("SUBSTRATE_CLI_IMPL_VERSION") + fn impl_version() -> String { + env!("SUBSTRATE_CLI_IMPL_VERSION").into() } - fn description() -> &'static str { - env!("CARGO_PKG_DESCRIPTION") + fn description() -> String { + env!("CARGO_PKG_DESCRIPTION").into() } - fn author() -> &'static str { - env!("CARGO_PKG_AUTHORS") + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() } - fn support_url() -> &'static str { - "support.anonymous.an" + fn support_url() -> String { + "support.anonymous.an".into() } fn copyright_start_year() -> i32 { 2017 } - fn executable_name() -> &'static str { - env!("CARGO_PKG_NAME") - } - fn load_spec(&self, id: &str) -> Result, String> { Ok(match id { - "dev" => Box::new(chain_spec::development_config()), - "" | "local" => Box::new(chain_spec::local_testnet_config()), + "dev" => Box::new(chain_spec::development_config()?), + "" | "local" => Box::new(chain_spec::local_testnet_config()?), path => Box::new(chain_spec::ChainSpec::from_json_file( std::path::PathBuf::from(path), )?), }) } + + fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { + &node_template_runtime::VERSION + } } /// Parse and run command line arguments pub fn run() -> sc_cli::Result<()> { let cli = Cli::from_args(); - match &cli.subcommand { - Some(subcommand) => { + match cli.subcommand { + Some(ref subcommand) => { let runner = cli.create_runner(subcommand)?; - runner.run_subcommand(subcommand, |config| Ok(new_full_start!(config).0)) + runner.run_subcommand(subcommand, |config| { + let PartialComponents { client, backend, task_manager, import_queue, .. } + = new_partial(&config)?; + Ok((client, backend, import_queue, task_manager)) + }) } None => { let runner = cli.create_runner(&cli.run)?; - runner.run_node( - service::new_light, - service::new_full, - node_template_runtime::VERSION - ) + runner.run_node_until_exit(|config| match config.role { + Role::Light => service::new_light(config), + _ => service::new_full(config), + }) } } } diff --git a/bin/node-template/node/src/lib.rs b/bin/node-template/node/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..777c4f0a77147b76f2d86c7318d6ca64a7323dfa --- /dev/null +++ b/bin/node-template/node/src/lib.rs @@ -0,0 +1,3 @@ +pub mod chain_spec; +pub mod service; +pub mod rpc; diff --git a/bin/node-template/node/src/main.rs b/bin/node-template/node/src/main.rs index 369e6932a030811b542ae8de9f26e9324f22e069..4449d28b9fa416b37b713c7fd1cfe35b9fe61a03 100644 --- a/bin/node-template/node/src/main.rs +++ b/bin/node-template/node/src/main.rs @@ -6,6 +6,7 @@ mod chain_spec; mod service; mod cli; mod command; +mod rpc; fn main() -> sc_cli::Result<()> { command::run() diff --git a/bin/node-template/node/src/rpc.rs b/bin/node-template/node/src/rpc.rs new file mode 100644 index 0000000000000000000000000000000000000000..c1f0e0a8457bc75f9b7c23f50887929174c92817 --- /dev/null +++ b/bin/node-template/node/src/rpc.rs @@ -0,0 +1,64 @@ +//! A collection of node-specific RPC methods. +//! Substrate provides the `sc-rpc` crate, which defines the core RPC layer +//! used by Substrate nodes. This file extends those RPC definitions with +//! capabilities that are specific to this project's runtime configuration. + +#![warn(missing_docs)] + +use std::sync::Arc; + +use node_template_runtime::{opaque::Block, AccountId, Balance, Index}; +use sp_api::ProvideRuntimeApi; +use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend}; +use sp_block_builder::BlockBuilder; +pub use sc_rpc_api::DenyUnsafe; +use sp_transaction_pool::TransactionPool; + + +/// Full client dependencies. +pub struct FullDeps { + /// The client instance to use. + pub client: Arc, + /// Transaction pool instance. + pub pool: Arc

, + /// Whether to deny unsafe calls + pub deny_unsafe: DenyUnsafe, +} + +/// Instantiate all full RPC extensions. +pub fn create_full( + deps: FullDeps, +) -> jsonrpc_core::IoHandler where + C: ProvideRuntimeApi, + C: HeaderBackend + HeaderMetadata + 'static, + C: Send + Sync + 'static, + C::Api: substrate_frame_rpc_system::AccountNonceApi, + C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, + C::Api: BlockBuilder, + P: TransactionPool + 'static, +{ + use substrate_frame_rpc_system::{FullSystem, SystemApi}; + use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi}; + + let mut io = jsonrpc_core::IoHandler::default(); + let FullDeps { + client, + pool, + deny_unsafe, + } = deps; + + io.extend_with( + SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe)) + ); + + io.extend_with( + TransactionPaymentApi::to_delegate(TransactionPayment::new(client.clone())) + ); + + // Extend this RPC with a custom API by using the following syntax. + // `YourRpcStruct` should have a reference to a client, which is needed + // to call into the runtime. + // `io.extend_with(YourRpcTrait::to_delegate(YourRpcStruct::new(ReferenceToClient, ...)));` + + io +} diff --git a/bin/node-template/node/src/service.rs b/bin/node-template/node/src/service.rs index 36555b5a223b56f9aa79952259a7366798e96228..5984d67322333287a4a2c8fb2dbdb02653c42ba0 100644 --- a/bin/node-template/node/src/service.rs +++ b/bin/node-template/node/src/service.rs @@ -2,17 +2,14 @@ use std::sync::Arc; use std::time::Duration; -use sc_client_api::ExecutorProvider; -use sc_consensus::LongestChain; +use sc_client_api::{ExecutorProvider, RemoteBackend}; use node_template_runtime::{self, opaque::Block, RuntimeApi}; -use sc_service::{error::{Error as ServiceError}, AbstractService, Configuration, ServiceBuilder}; +use sc_service::{error::Error as ServiceError, Configuration, TaskManager}; use sp_inherents::InherentDataProviders; use sc_executor::native_executor_instance; pub use sc_executor::NativeExecutor; use sp_consensus_aura::sr25519::{AuthorityPair as AuraPair}; -use sc_finality_grandpa::{ - FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider, SharedVoterState, -}; +use sc_finality_grandpa::{FinalityProofProvider as GrandpaFinalityProofProvider, SharedVoterState}; // Our native executor instance. native_executor_instance!( @@ -21,115 +18,158 @@ native_executor_instance!( node_template_runtime::native_version, ); -/// Starts a `ServiceBuilder` for a full service. -/// -/// Use this macro if you don't actually need the full service, but just the builder in order to -/// be able to perform chain operations. -macro_rules! new_full_start { - ($config:expr) => {{ - use std::sync::Arc; - use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; - - let mut import_setup = None; - let inherent_data_providers = sp_inherents::InherentDataProviders::new(); - - let builder = sc_service::ServiceBuilder::new_full::< - node_template_runtime::opaque::Block, node_template_runtime::RuntimeApi, crate::service::Executor - >($config)? - .with_select_chain(|_config, backend| { - Ok(sc_consensus::LongestChain::new(backend.clone())) - })? - .with_transaction_pool(|config, client, _fetcher, prometheus_registry| { - let pool_api = sc_transaction_pool::FullChainApi::new(client.clone()); - Ok(sc_transaction_pool::BasicPool::new(config, std::sync::Arc::new(pool_api), prometheus_registry)) - })? - .with_import_queue(|_config, client, mut select_chain, _transaction_pool, spawn_task_handle| { - let select_chain = select_chain.take() - .ok_or_else(|| sc_service::Error::SelectChainRequired)?; - - let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( - client.clone(), - &(client.clone() as Arc<_>), - select_chain, - )?; - - let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new( - grandpa_block_import.clone(), client.clone(), - ); - - let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>( - sc_consensus_aura::slot_duration(&*client)?, - aura_block_import, - Some(Box::new(grandpa_block_import.clone())), - None, - client, - inherent_data_providers.clone(), - spawn_task_handle, - )?; - - import_setup = Some((grandpa_block_import, grandpa_link)); - - Ok(import_queue) - })?; - - (builder, import_setup, inherent_data_providers) - }} +type FullClient = sc_service::TFullClient; +type FullBackend = sc_service::TFullBackend; +type FullSelectChain = sc_consensus::LongestChain; + +pub fn new_partial(config: &Configuration) -> Result, + sc_transaction_pool::FullPool, + ( + sc_finality_grandpa::GrandpaBlockImport, + sc_finality_grandpa::LinkHalf + ) +>, ServiceError> { + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); + + let (client, backend, keystore, task_manager) = + sc_service::new_full_parts::(&config)?; + let client = Arc::new(client); + + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + config.prometheus_registry(), + task_manager.spawn_handle(), + client.clone(), + ); + + let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import( + client.clone(), &(client.clone() as Arc<_>), select_chain.clone(), + )?; + + let aura_block_import = sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new( + grandpa_block_import.clone(), client.clone(), + ); + + let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _, _>( + sc_consensus_aura::slot_duration(&*client)?, + aura_block_import, + Some(Box::new(grandpa_block_import.clone())), + None, + client.clone(), + inherent_data_providers.clone(), + &task_manager.spawn_handle(), + config.prometheus_registry(), + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()), + )?; + + Ok(sc_service::PartialComponents { + client, backend, task_manager, import_queue, keystore, select_chain, transaction_pool, + inherent_data_providers, + other: (grandpa_block_import, grandpa_link), + }) } /// Builds a new service for a full client. -pub fn new_full(config: Configuration) -> Result { +pub fn new_full(config: Configuration) -> Result { + let sc_service::PartialComponents { + client, backend, mut task_manager, import_queue, keystore, select_chain, transaction_pool, + inherent_data_providers, + other: (block_import, grandpa_link), + } = new_partial(&config)?; + + let finality_proof_provider = + GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone()); + + let (network, network_status_sinks, system_rpc_tx, network_starter) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + on_demand: None, + block_announce_validator_builder: None, + finality_proof_request_builder: None, + finality_proof_provider: Some(finality_proof_provider.clone()), + })?; + + if config.offchain_worker.enabled { + sc_service::build_offchain_workers( + &config, backend.clone(), task_manager.spawn_handle(), client.clone(), network.clone(), + ); + } + let role = config.role.clone(); let force_authoring = config.force_authoring; let name = config.network.node_name.clone(); - let disable_grandpa = config.disable_grandpa; + let enable_grandpa = !config.disable_grandpa; + let prometheus_registry = config.prometheus_registry().cloned(); + let telemetry_connection_sinks = sc_service::TelemetryConnectionSinks::default(); - let (builder, mut import_setup, inherent_data_providers) = new_full_start!(config); + let rpc_extensions_builder = { + let client = client.clone(); + let pool = transaction_pool.clone(); - let (block_import, grandpa_link) = - import_setup.take() - .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); + Box::new(move |deny_unsafe, _| { + let deps = crate::rpc::FullDeps { + client: client.clone(), + pool: pool.clone(), + deny_unsafe, + }; - let service = builder - .with_finality_proof_provider(|client, backend| { - // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider - let provider = client as Arc>; - Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) - })? - .build()?; + crate::rpc::create_full(deps) + }) + }; - if role.is_authority() { - let proposer = - sc_basic_authorship::ProposerFactory::new(service.client(), service.transaction_pool()); + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + network: network.clone(), + client: client.clone(), + keystore: keystore.clone(), + task_manager: &mut task_manager, + transaction_pool: transaction_pool.clone(), + telemetry_connection_sinks: telemetry_connection_sinks.clone(), + rpc_extensions_builder: rpc_extensions_builder, + on_demand: None, + remote_blockchain: None, + backend, network_status_sinks, system_rpc_tx, config, + })?; - let client = service.client(); - let select_chain = service.select_chain() - .ok_or(ServiceError::SelectChainRequired)?; + if role.is_authority() { + let proposer = sc_basic_authorship::ProposerFactory::new( + client.clone(), + transaction_pool, + prometheus_registry.as_ref(), + ); let can_author_with = sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); let aura = sc_consensus_aura::start_aura::<_, _, _, _, _, AuraPair, _, _, _>( sc_consensus_aura::slot_duration(&*client)?, - client, + client.clone(), select_chain, block_import, proposer, - service.network(), + network.clone(), inherent_data_providers.clone(), force_authoring, - service.keystore(), + keystore.clone(), can_author_with, )?; // the AURA authoring task is considered essential, i.e. if it // fails we take down the service with it. - service.spawn_essential_task("aura", aura); + task_manager.spawn_essential_handle().spawn_blocking("aura", aura); } // if the node isn't actively participating in consensus then it doesn't // need a keystore, regardless of which protocol we use below. let keystore = if role.is_authority() { - Some(service.keystore()) + Some(keystore as sp_core::traits::BareCryptoStorePtr) } else { None }; @@ -144,7 +184,6 @@ pub fn new_full(config: Configuration) -> Result Result Result { - let inherent_data_providers = InherentDataProviders::new(); - - ServiceBuilder::new_light::(config)? - .with_select_chain(|_config, backend| { - Ok(LongestChain::new(backend.clone())) - })? - .with_transaction_pool(|config, client, fetcher, prometheus_registry| { - let fetcher = fetcher - .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?; - - let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone()); - let pool = sc_transaction_pool::BasicPool::with_revalidation_type( - config, Arc::new(pool_api), prometheus_registry, sc_transaction_pool::RevalidationType::Light, - ); - Ok(pool) - })? - .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool, spawn_task_handle| { - let fetch_checker = fetcher - .map(|fetcher| fetcher.checker().clone()) - .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; - let grandpa_block_import = sc_finality_grandpa::light_block_import( - client.clone(), - backend, - &(client.clone() as Arc<_>), - Arc::new(fetch_checker), - )?; - let finality_proof_import = grandpa_block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); - - let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _>( - sc_consensus_aura::slot_duration(&*client)?, - grandpa_block_import, - None, - Some(Box::new(finality_proof_import)), - client, - inherent_data_providers.clone(), - spawn_task_handle, - )?; - - Ok((import_queue, finality_proof_request_builder)) - })? - .with_finality_proof_provider(|client, backend| { - // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider - let provider = client as Arc>; - Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) - })? - .build() +pub fn new_light(config: Configuration) -> Result { + let (client, backend, keystore, mut task_manager, on_demand) = + sc_service::new_light_parts::(&config)?; + + let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light( + config.transaction_pool.clone(), + config.prometheus_registry(), + task_manager.spawn_handle(), + client.clone(), + on_demand.clone(), + )); + + let grandpa_block_import = sc_finality_grandpa::light_block_import( + client.clone(), backend.clone(), &(client.clone() as Arc<_>), + Arc::new(on_demand.checker().clone()) as Arc<_>, + )?; + let finality_proof_import = grandpa_block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); + + let import_queue = sc_consensus_aura::import_queue::<_, _, _, AuraPair, _, _>( + sc_consensus_aura::slot_duration(&*client)?, + grandpa_block_import, + None, + Some(Box::new(finality_proof_import)), + client.clone(), + InherentDataProviders::new(), + &task_manager.spawn_handle(), + config.prometheus_registry(), + sp_consensus::NeverCanAuthor, + )?; + + let finality_proof_provider = + GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone()); + + let (network, network_status_sinks, system_rpc_tx, network_starter) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + on_demand: Some(on_demand.clone()), + block_announce_validator_builder: None, + finality_proof_request_builder: Some(finality_proof_request_builder), + finality_proof_provider: Some(finality_proof_provider), + })?; + + if config.offchain_worker.enabled { + sc_service::build_offchain_workers( + &config, backend.clone(), task_manager.spawn_handle(), client.clone(), network.clone(), + ); + } + + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + remote_blockchain: Some(backend.remote_blockchain()), + transaction_pool, + task_manager: &mut task_manager, + on_demand: Some(on_demand), + rpc_extensions_builder: Box::new(|_, _| ()), + telemetry_connection_sinks: sc_service::TelemetryConnectionSinks::default(), + config, + client, + keystore, + backend, + network, + network_status_sinks, + system_rpc_tx, + })?; + + network_starter.start_network(); + + Ok(task_manager) } diff --git a/bin/node-template/pallets/template/Cargo.toml b/bin/node-template/pallets/template/Cargo.toml index 01484c608cf66fc35534f6f8dc603bcd6a356c77..106e4af37a8f858c7dd56f9bf6dfcf14070c63b7 100644 --- a/bin/node-template/pallets/template/Cargo.toml +++ b/bin/node-template/pallets/template/Cargo.toml @@ -2,40 +2,41 @@ authors = ['Anonymous'] edition = '2018' name = 'pallet-template' -version = "2.0.0-dev" +version = "2.0.0-rc6" license = "Unlicense" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -description = "FRAME pallet template" +description = "FRAME pallet template for defining custom runtime logic." [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } [dependencies.frame-support] default-features = false -version = "2.0.0-dev" +version = "2.0.0-rc6" path = "../../../../frame/support" [dependencies.frame-system] default-features = false -version = "2.0.0-dev" +version = "2.0.0-rc6" path = "../../../../frame/system" + [dev-dependencies.sp-core] default-features = false -version = "2.0.0-dev" +version = "2.0.0-rc6" path = "../../../../primitives/core" [dev-dependencies.sp-io] default-features = false -version = "2.0.0-dev" +version = "2.0.0-rc6" path = "../../../../primitives/io" [dev-dependencies.sp-runtime] default-features = false -version = "2.0.0-dev" +version = "2.0.0-rc6" path = "../../../../primitives/runtime" diff --git a/bin/node-template/pallets/template/README.md b/bin/node-template/pallets/template/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8d751a42207ddd3f2d4d361248077a468b64f36a --- /dev/null +++ b/bin/node-template/pallets/template/README.md @@ -0,0 +1 @@ +License: Unlicense \ No newline at end of file diff --git a/bin/node-template/pallets/template/src/lib.rs b/bin/node-template/pallets/template/src/lib.rs index 1f82857c43e4769ad60ab6cc4001536ac8cd8dcb..729a71278aa9f1c2f37760274b547253799871fb 100644 --- a/bin/node-template/pallets/template/src/lib.rs +++ b/bin/node-template/pallets/template/src/lib.rs @@ -1,16 +1,11 @@ #![cfg_attr(not(feature = "std"), no_std)] -/// A FRAME pallet template with necessary imports +/// Edit this file to define custom logic or remove it if it is not needed. +/// Learn more about FRAME and the core library of Substrate FRAME pallets: +/// https://substrate.dev/docs/en/knowledgebase/runtime/frame -/// Feel free to remove or edit this file as needed. -/// If you change the name of this file, make sure to update its references in runtime/src/lib.rs -/// If you remove this file, you can remove those references - -/// For more guidance on Substrate FRAME, see the example pallet -/// https://github.com/paritytech/substrate/blob/master/frame/example/src/lib.rs - -use frame_support::{decl_module, decl_storage, decl_event, decl_error, dispatch}; -use frame_system::{self as system, ensure_signed}; +use frame_support::{decl_module, decl_storage, decl_event, decl_error, dispatch, traits::Get}; +use frame_system::ensure_signed; #[cfg(test)] mod mock; @@ -18,88 +13,87 @@ mod mock; #[cfg(test)] mod tests; -/// The pallet's configuration trait. -pub trait Trait: system::Trait { - // Add other types and constants required to configure this pallet. - - /// The overarching event type. - type Event: From> + Into<::Event>; +/// Configure the pallet by specifying the parameters and types on which it depends. +pub trait Trait: frame_system::Trait { + /// Because this pallet emits events, it depends on the runtime's definition of an event. + type Event: From> + Into<::Event>; } -// This pallet's storage items. +// The pallet's runtime storage items. +// https://substrate.dev/docs/en/knowledgebase/runtime/storage decl_storage! { - // It is important to update your storage name so that your pallet's - // storage items are isolated from other pallets. + // A unique name is used to ensure that the pallet's storage items are isolated. + // This name may be updated, but each pallet in the runtime must use a unique name. // ---------------------------------vvvvvvvvvvvvvv trait Store for Module as TemplateModule { - // Just a dummy storage item. - // Here we are declaring a StorageValue, `Something` as a Option - // `get(fn something)` is the default getter which returns either the stored `u32` or `None` if nothing stored + // Learn more about declaring storage items: + // https://substrate.dev/docs/en/knowledgebase/runtime/storage#declaring-storage-items Something get(fn something): Option; } } -// The pallet's events +// Pallets use events to inform users when important changes are made. +// https://substrate.dev/docs/en/knowledgebase/runtime/events decl_event!( - pub enum Event where AccountId = ::AccountId { - /// Just a dummy event. - /// Event `Something` is declared with a parameter of the type `u32` and `AccountId` - /// To emit this event, we call the deposit function, from our runtime functions + pub enum Event where AccountId = ::AccountId { + /// Event documentation should end with an array that provides descriptive names for event + /// parameters. [something, who] SomethingStored(u32, AccountId), } ); -// The pallet's errors +// Errors inform users that something went wrong. decl_error! { pub enum Error for Module { - /// Value was None + /// Error names should be descriptive. NoneValue, - /// Value reached maximum and cannot be incremented further + /// Errors should have helpful documentation associated with them. StorageOverflow, } } -// The pallet's dispatchable functions. +// Dispatchable functions allows users to interact with the pallet and invoke state changes. +// These functions materialize as "extrinsics", which are often compared to transactions. +// Dispatchable functions must be annotated with a weight and must return a DispatchResult. decl_module! { - /// The module declaration. pub struct Module for enum Call where origin: T::Origin { - // Initializing errors - // this includes information about your errors in the node's metadata. - // it is needed only if you are using errors in your pallet + // Errors must be initialized if they are used by the pallet. type Error = Error; - // Initializing events - // this is needed only if you are using events in your pallet + // Events must be initialized if they are used by the pallet. fn deposit_event() = default; - /// Just a dummy entry point. - /// function that can be called by the external world as an extrinsics call - /// takes a parameter of the type `AccountId`, stores it, and emits an event - #[weight = 0] + /// An example dispatchable that takes a singles value as a parameter, writes the value to + /// storage and emits an event. This function must be dispatched by a signed extrinsic. + #[weight = 10_000 + T::DbWeight::get().writes(1)] pub fn do_something(origin, something: u32) -> dispatch::DispatchResult { - // Check it was signed and get the signer. See also: ensure_root and ensure_none + // Check that the extrinsic was signed and get the signer. + // This function will return an error if the extrinsic is not signed. + // https://substrate.dev/docs/en/knowledgebase/runtime/origin let who = ensure_signed(origin)?; - // Code to execute when something calls this. - // For example: the following line stores the passed in u32 in the storage + // Update storage. Something::put(something); - // Here we are raising the Something event + // Emit an event. Self::deposit_event(RawEvent::SomethingStored(something, who)); + // Return a successful DispatchResult Ok(()) } - /// Another dummy entry point. - /// takes no parameters, attempts to increment storage value, and possibly throws an error - #[weight = 0] + /// An example dispatchable that may throw a custom error. + #[weight = 10_000 + T::DbWeight::get().reads_writes(1,1)] pub fn cause_error(origin) -> dispatch::DispatchResult { - // Check it was signed and get the signer. See also: ensure_root and ensure_none let _who = ensure_signed(origin)?; + // Read a value from storage. match Something::get() { + // Return an error if the value has not been set. None => Err(Error::::NoneValue)?, Some(old) => { + // Increment the value read from storage; will error in the event of overflow. let new = old.checked_add(1).ok_or(Error::::StorageOverflow)?; + // Update the value in storage with the incremented result. Something::put(new); Ok(()) }, diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index 33c66e2a4e80d616a64255701279bdc9170a9240..8c3bf2b40473c81b2fa946b3fae86d250f448c3f 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -1,5 +1,3 @@ -// Creating mock runtime here - use crate::{Module, Trait}; use sp_core::H256; use frame_support::{impl_outer_origin, parameter_types, weights::Weight}; @@ -12,9 +10,8 @@ impl_outer_origin! { pub enum Origin for Test {} } -// For testing the pallet, we construct most of a mock runtime. This means -// first constructing a configuration type (`Test`) which `impl`s each of the -// configuration traits of pallets we want to use. +// Configure a mock runtime to test the pallet. + #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -23,7 +20,9 @@ parameter_types! { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } + impl system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Call = (); type Index = u64; @@ -39,6 +38,7 @@ impl system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -46,14 +46,16 @@ impl system::Trait for Test { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } + impl Trait for Test { type Event = (); } + pub type TemplateModule = Module; -// This function basically just builds a genesis storage key/value store according to -// our desired mockup. +// Build genesis storage according to the mock runtime. pub fn new_test_ext() -> sp_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() } diff --git a/bin/node-template/pallets/template/src/tests.rs b/bin/node-template/pallets/template/src/tests.rs index ec123a50c7cc984f15c8f80983ed300d95ecdccf..3356b29ff35980d08d751b4eca01aac403df8380 100644 --- a/bin/node-template/pallets/template/src/tests.rs +++ b/bin/node-template/pallets/template/src/tests.rs @@ -1,15 +1,12 @@ -// Tests to be written here - use crate::{Error, mock::*}; use frame_support::{assert_ok, assert_noop}; #[test] fn it_works_for_default_value() { new_test_ext().execute_with(|| { - // Just a dummy test for the dummy function `do_something` - // calling the `do_something` function with a value 42 + // Dispatch a signed extrinsic. assert_ok!(TemplateModule::do_something(Origin::signed(1), 42)); - // asserting that the stored value is equal to what we stored + // Read pallet storage and assert an expected result. assert_eq!(TemplateModule::something(), Some(42)); }); } @@ -17,7 +14,7 @@ fn it_works_for_default_value() { #[test] fn correct_error_for_none_value() { new_test_ext().execute_with(|| { - // Ensure the correct error is thrown on None value + // Ensure the expected error is thrown when no value is present. assert_noop!( TemplateModule::cause_error(Origin::signed(1)), Error::::NoneValue diff --git a/bin/node-template/runtime/Cargo.toml b/bin/node-template/runtime/Cargo.toml index dfd517130b216215d8ded2098fd68ee2b7df93cc..3cb0754089d91306841695be88e3d7d165f3a6b3 100644 --- a/bin/node-template/runtime/Cargo.toml +++ b/bin/node-template/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node-template-runtime" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Anonymous"] edition = "2018" license = "Unlicense" @@ -11,33 +11,36 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } -aura = { version = "2.0.0-dev", default-features = false, package = "pallet-aura", path = "../../../frame/aura" } -balances = { version = "2.0.0-dev", default-features = false, package = "pallet-balances", path = "../../../frame/balances" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../../../frame/support" } -grandpa = { version = "2.0.0-dev", default-features = false, package = "pallet-grandpa", path = "../../../frame/grandpa" } -randomness-collective-flip = { version = "2.0.0-dev", default-features = false, package = "pallet-randomness-collective-flip", path = "../../../frame/randomness-collective-flip" } -sudo = { version = "2.0.0-dev", default-features = false, package = "pallet-sudo", path = "../../../frame/sudo" } -system = { version = "2.0.0-dev", default-features = false, package = "frame-system", path = "../../../frame/system" } -timestamp = { version = "2.0.0-dev", default-features = false, package = "pallet-timestamp", path = "../../../frame/timestamp" } -transaction-payment = { version = "2.0.0-dev", default-features = false, package = "pallet-transaction-payment", path = "../../../frame/transaction-payment" } -frame-executive = { version = "2.0.0-dev", default-features = false, path = "../../../frame/executive" } +pallet-aura = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/aura" } +pallet-balances = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/balances" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/support" } +pallet-grandpa = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/grandpa" } +pallet-randomness-collective-flip = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/randomness-collective-flip" } +pallet-sudo = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/sudo" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/system" } +pallet-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/transaction-payment" } +frame-executive = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/executive" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/api" } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-dev"} -sp-consensus-aura = { version = "0.8.0-dev", default-features = false, path = "../../../primitives/consensus/aura" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } -sp-inherents = { path = "../../../primitives/inherents", default-features = false, version = "2.0.0-dev"} -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/io" } -sp-offchain = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/offchain" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } -sp-session = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/session" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } -sp-transaction-pool = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/transaction-pool" } -sp-version = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/version" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/api" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-rc6"} +sp-consensus-aura = { version = "0.8.0-rc6", default-features = false, path = "../../../primitives/consensus/aura" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/core" } +sp-inherents = { path = "../../../primitives/inherents", default-features = false, version = "2.0.0-rc6"} +sp-offchain = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/offchain" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/runtime" } +sp-session = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/session" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/std" } +sp-transaction-pool = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/version" } -template = { version = "2.0.0-dev", default-features = false, path = "../pallets/template", package = "pallet-template" } +# Used for the node template's RPCs +frame-system-rpc-runtime-api = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } + +template = { version = "2.0.0-rc6", default-features = false, path = "../pallets/template", package = "pallet-template" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } @@ -45,29 +48,30 @@ wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-run [features] default = ["std"] std = [ - "aura/std", - "balances/std", "codec/std", "frame-executive/std", "frame-support/std", - "grandpa/std", - "randomness-collective-flip/std", + "pallet-aura/std", + "pallet-balances/std", + "pallet-grandpa/std", + "pallet-randomness-collective-flip/std", + "pallet-sudo/std", + "pallet-timestamp/std", + "pallet-transaction-payment/std", + "pallet-transaction-payment-rpc-runtime-api/std", "serde", "sp-api/std", "sp-block-builder/std", "sp-consensus-aura/std", "sp-core/std", "sp-inherents/std", - "sp-io/std", "sp-offchain/std", "sp-runtime/std", "sp-session/std", "sp-std/std", "sp-transaction-pool/std", "sp-version/std", - "sudo/std", - "system/std", - "timestamp/std", - "transaction-payment/std", + "frame-system/std", + "frame-system-rpc-runtime-api/std", "template/std", ] diff --git a/bin/node-template/runtime/build.rs b/bin/node-template/runtime/build.rs index 39f7f56feb0b1730d7f2c9a7daa898fe54bfd052..52705043a2019c43604f4af498af2f785d5a8555 100644 --- a/bin/node-template/runtime/build.rs +++ b/bin/node-template/runtime/build.rs @@ -3,7 +3,7 @@ use wasm_builder_runner::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates("1.0.9") + .with_wasm_builder_from_crates("2.0.0") .export_heap_base() .import_memory() .build() diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 8261577586e47ebc0714cbcc50cda6377a28c0d6..06e34e4551673b69dacb667de0376e99ee36e12b 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -1,5 +1,3 @@ -//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm. - #![cfg_attr(not(feature = "std"), no_std)] // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit="256"] @@ -15,12 +13,12 @@ use sp_runtime::{ transaction_validity::{TransactionValidity, TransactionSource}, }; use sp_runtime::traits::{ - BlakeTwo256, Block as BlockT, IdentityLookup, Verify, ConvertInto, IdentifyAccount, NumberFor, + BlakeTwo256, Block as BlockT, IdentityLookup, Verify, IdentifyAccount, NumberFor, Saturating, }; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; -use grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList}; -use grandpa::fg_primitives; +use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList}; +use pallet_grandpa::fg_primitives; use sp_version::RuntimeVersion; #[cfg(feature = "std")] use sp_version::NativeVersion; @@ -28,19 +26,19 @@ use sp_version::NativeVersion; // A few exports that help ease life for downstream crates. #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; -pub use timestamp::Call as TimestampCall; -pub use balances::Call as BalancesCall; +pub use pallet_timestamp::Call as TimestampCall; +pub use pallet_balances::Call as BalancesCall; pub use sp_runtime::{Permill, Perbill}; pub use frame_support::{ construct_runtime, parameter_types, StorageValue, traits::{KeyOwnerProofSystem, Randomness}, weights::{ - Weight, + Weight, IdentityFee, constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, }, }; -/// Importing a template pallet +/// Import the template pallet. pub use template; /// An index to a block. @@ -93,7 +91,6 @@ pub mod opaque { } } -/// This runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("node-template"), impl_name: create_runtime_str!("node-template"), @@ -108,7 +105,7 @@ pub const MILLISECS_PER_BLOCK: u64 = 6000; pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; -// These time units are defined in number of blocks. +// Time is measured by number of blocks. pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); pub const HOURS: BlockNumber = MINUTES * 60; pub const DAYS: BlockNumber = HOURS * 24; @@ -123,15 +120,22 @@ pub fn native_version() -> NativeVersion { } parameter_types! { - pub const BlockHashCount: BlockNumber = 250; + pub const BlockHashCount: BlockNumber = 2400; /// We allow for 2 seconds of compute with a 6 second average block time. pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + /// Assume 10% of weight for average on_initialize calls. + pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get() + .saturating_sub(Perbill::from_percent(10)) * MaximumBlockWeight::get(); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; } -impl system::Trait for Runtime { +// Configure FRAME pallets to include in runtime. + +impl frame_system::Trait for Runtime { + /// The basic call filter to use in dispatchable. + type BaseCallFilter = (); /// The identifier used to distinguish between accounts. type AccountId = AccountId; /// The aggregated dispatch type that is available for extrinsics. @@ -164,6 +168,10 @@ impl system::Trait for Runtime { /// The base weight of any extrinsic processed by the runtime, independent of the /// logic of that extrinsic. (Signature verification, nonce increment, fee, etc...) type ExtrinsicBaseWeight = ExtrinsicBaseWeight; + /// The maximum weight that a single extrinsic of `Normal` dispatch class can have, + /// idependent of the logic of that extrinsics. (Roughly max block weight - average on + /// initialize cost). + type MaximumExtrinsicWeight = MaximumExtrinsicWeight; /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. type MaximumBlockLength = MaximumBlockLength; /// Portion of the block weight that is available to all normal transactions. @@ -179,14 +187,16 @@ impl system::Trait for Runtime { /// What to do if an account is fully reaped from the system. type OnKilledAccount = (); /// The data to be stored in an account. - type AccountData = balances::AccountData; + type AccountData = pallet_balances::AccountData; + /// Weight information for the extrinsics of this pallet. + type SystemWeightInfo = (); } -impl aura::Trait for Runtime { +impl pallet_aura::Trait for Runtime { type AuthorityId = AuraId; } -impl grandpa::Trait for Runtime { +impl pallet_grandpa::Trait for Runtime { type Event = Event; type Call = Call; @@ -207,18 +217,19 @@ parameter_types! { pub const MinimumPeriod: u64 = SLOT_DURATION / 2; } -impl timestamp::Trait for Runtime { +impl pallet_timestamp::Trait for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = Aura; type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } parameter_types! { pub const ExistentialDeposit: u128 = 500; } -impl balances::Trait for Runtime { +impl pallet_balances::Trait for Runtime { /// The type for recording an account's balance. type Balance = Balance; /// The ubiquitous event type. @@ -226,45 +237,47 @@ impl balances::Trait for Runtime { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { pub const TransactionByteFee: Balance = 1; } -impl transaction_payment::Trait for Runtime { - type Currency = balances::Module; +impl pallet_transaction_payment::Trait for Runtime { + type Currency = Balances; type OnTransactionPayment = (); type TransactionByteFee = TransactionByteFee; - type WeightToFee = ConvertInto; + type WeightToFee = IdentityFee; type FeeMultiplierUpdate = (); } -impl sudo::Trait for Runtime { +impl pallet_sudo::Trait for Runtime { type Event = Event; type Call = Call; } -/// Used for the module template in `./template.rs` +/// Configure the pallet template in pallets/template. impl template::Trait for Runtime { type Event = Event; } +// Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = opaque::Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Config, Storage, Event}, - RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, - Timestamp: timestamp::{Module, Call, Storage, Inherent}, - Aura: aura::{Module, Config, Inherent(Timestamp)}, - Grandpa: grandpa::{Module, Call, Storage, Config, Event}, - Balances: balances::{Module, Call, Storage, Config, Event}, - TransactionPayment: transaction_payment::{Module, Storage}, - Sudo: sudo::{Module, Call, Config, Storage, Event}, - // Used for the module template in `./template.rs` + System: frame_system::{Module, Call, Config, Storage, Event}, + RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage}, + Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent}, + Aura: pallet_aura::{Module, Config, Inherent}, + Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event}, + Balances: pallet_balances::{Module, Call, Storage, Config, Event}, + TransactionPayment: pallet_transaction_payment::{Module, Storage}, + Sudo: pallet_sudo::{Module, Call, Config, Storage, Event}, + // Include the custom logic from the template pallet in the runtime. TemplateModule: template::{Module, Call, Storage, Event}, } ); @@ -281,19 +294,26 @@ pub type SignedBlock = generic::SignedBlock; pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( - system::CheckVersion, - system::CheckGenesis, - system::CheckEra, - system::CheckNonce, - system::CheckWeight, - transaction_payment::ChargeTransactionPayment + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, + frame_system::CheckGenesis, + frame_system::CheckEra, + frame_system::CheckNonce, + frame_system::CheckWeight, + pallet_transaction_payment::ChargeTransactionPayment ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive, Runtime, AllModules>; +pub type Executive = frame_executive::Executive< + Runtime, + Block, + frame_system::ChainContext, + Runtime, + AllModules, +>; impl_runtime_apis! { impl sp_api::Core for Runtime { @@ -383,7 +403,7 @@ impl_runtime_apis! { Grandpa::grandpa_authorities() } - fn submit_report_equivocation_extrinsic( + fn submit_report_equivocation_unsigned_extrinsic( _equivocation_proof: fg_primitives::EquivocationProof< ::Hash, NumberFor, @@ -403,4 +423,19 @@ impl_runtime_apis! { None } } + + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { + fn account_nonce(account: AccountId) -> Index { + System::account_nonce(account) + } + } + + impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { + fn query_info( + uxt: ::Extrinsic, + len: u32, + ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { + TransactionPayment::query_info(uxt, len) + } + } } diff --git a/bin/node/bench/Cargo.toml b/bin/node/bench/Cargo.toml index 809600b99f46722cadd1bf2d0c7c1d4c05007cc8..adefbd07082a3b9ed91ee603f0559c5afd8bcaa1 100644 --- a/bin/node/bench/Cargo.toml +++ b/bin/node/bench/Cargo.toml @@ -1,34 +1,43 @@ [package] name = "node-bench" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Substrate node integration benchmarks." edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] log = "0.4.8" -node-primitives = { version = "2.0.0-dev", path = "../primitives" } -node-testing = { version = "2.0.0-dev", path = "../testing" } -sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-dev", path = "../../../client/api/" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } +node-primitives = { version = "2.0.0-rc6", path = "../primitives" } +node-testing = { version = "2.0.0-rc6", path = "../testing" } +node-runtime = { version = "2.0.0-rc6", path = "../runtime" } +sc-cli = { version = "0.8.0-rc6", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-rc6", path = "../../../client/api/" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../../primitives/state-machine" } serde = "1.0.101" serde_json = "1.0.41" structopt = "0.3" derive_more = "0.99.2" -kvdb = "0.5" -kvdb-rocksdb = "0.7" -sp-trie = { version = "2.0.0-dev", path = "../../../primitives/trie" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +kvdb = "0.7" +kvdb-rocksdb = "0.9" +sp-trie = { version = "2.0.0-rc6", path = "../../../primitives/trie" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../../primitives/transaction-pool" } +sc-basic-authorship = { version = "0.8.0-rc6", path = "../../../client/basic-authorship" } +sp-inherents = { version = "2.0.0-rc6", path = "../../../primitives/inherents" } +sp-finality-tracker = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/finality-tracker" } +sp-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/timestamp" } hash-db = "0.15.2" tempfile = "3.1.0" fs_extra = "1" hex = "0.4.0" rand = { version = "0.7.2", features = ["small_rng"] } lazy_static = "1.4.0" -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } parity-db = { version = "0.1.2" } +sc-transaction-pool = { version = "2.0.0-rc6", path = "../../../client/transaction-pool" } +futures = { version = "0.3.4", features = ["thread-pool"] } diff --git a/bin/node/bench/src/common.rs b/bin/node/bench/src/common.rs new file mode 100644 index 0000000000000000000000000000000000000000..2637d6e9bd04d809af5b374790adcc6e5207993f --- /dev/null +++ b/bin/node/bench/src/common.rs @@ -0,0 +1,48 @@ + +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +#[derive(Clone, Copy, Debug, derive_more::Display)] +pub enum SizeType { + #[display(fmt = "empty")] + Empty, + #[display(fmt = "small")] + Small, + #[display(fmt = "medium")] + Medium, + #[display(fmt = "large")] + Large, + #[display(fmt = "full")] + Full, + #[display(fmt = "custom")] + Custom(usize), +} + +impl SizeType { + pub fn transactions(&self) -> Option { + match self { + SizeType::Empty => Some(0), + SizeType::Small => Some(10), + SizeType::Medium => Some(100), + SizeType::Large => Some(500), + SizeType::Full => None, + // Custom SizeType will use the `--transactions` input parameter + SizeType::Custom(val) => Some(*val), + } + } +} \ No newline at end of file diff --git a/bin/node/bench/src/construct.rs b/bin/node/bench/src/construct.rs new file mode 100644 index 0000000000000000000000000000000000000000..e23594dd4364a1de30d65096fe69ab1627599a36 --- /dev/null +++ b/bin/node/bench/src/construct.rs @@ -0,0 +1,296 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +//! Block construction benchmark. +//! +//! This benchmark is expected to measure block construction. +//! We want to protect against cold-cache attacks, and so this +//! benchmark should not rely on any caching (except those entries that +//! DO NOT depend on user input). Thus transaction generation should be +//! based on randomized data. + +use std::{ + borrow::Cow, + collections::HashMap, + pin::Pin, + sync::Arc, +}; +use futures::Future; + +use node_primitives::Block; +use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes, DatabaseType}; +use sp_runtime::{ + generic::BlockId, + traits::NumberFor, + OpaqueExtrinsic, +}; +use sp_transaction_pool::{ + ImportNotificationStream, + PoolFuture, + PoolStatus, + TransactionFor, + TransactionSource, + TransactionStatusStreamFor, + TxHash, +}; +use sp_consensus::{Environment, Proposer, RecordProof}; + +use crate::{ + common::SizeType, + core::{self, Path, Mode}, +}; + +pub struct ConstructionBenchmarkDescription { + pub profile: Profile, + pub key_types: KeyTypes, + pub block_type: BlockType, + pub size: SizeType, + pub database_type: DatabaseType, +} + +pub struct ConstructionBenchmark { + profile: Profile, + database: BenchDb, + transactions: Transactions, +} + +impl core::BenchmarkDescription for ConstructionBenchmarkDescription { + fn path(&self) -> Path { + + let mut path = Path::new(&["node", "proposer"]); + + match self.profile { + Profile::Wasm => path.push("wasm"), + Profile::Native => path.push("native"), + } + + match self.key_types { + KeyTypes::Sr25519 => path.push("sr25519"), + KeyTypes::Ed25519 => path.push("ed25519"), + } + + match self.block_type { + BlockType::RandomTransfersKeepAlive => path.push("transfer"), + BlockType::RandomTransfersReaping => path.push("transfer_reaping"), + BlockType::Noop => path.push("noop"), + } + + match self.database_type { + DatabaseType::RocksDb => path.push("rocksdb"), + DatabaseType::ParityDb => path.push("paritydb"), + } + + path.push(&format!("{}", self.size)); + + path + } + + fn setup(self: Box) -> Box { + let mut extrinsics: Vec> = Vec::new(); + + let mut bench_db = BenchDb::with_key_types( + self.database_type, + 50_000, + self.key_types + ); + + let client = bench_db.client(); + + let content_type = self.block_type.to_content(self.size.transactions()); + for transaction in bench_db.block_content(content_type, &client) { + extrinsics.push(Arc::new(transaction.into())); + } + + Box::new(ConstructionBenchmark { + profile: self.profile, + database: bench_db, + transactions: Transactions(extrinsics), + }) + } + + fn name(&self) -> Cow<'static, str> { + format!( + "Block construction ({:?}/{}, {:?}, {:?} backend)", + self.block_type, + self.size, + self.profile, + self.database_type, + ).into() + } +} + +impl core::Benchmark for ConstructionBenchmark { + fn run(&mut self, mode: Mode) -> std::time::Duration { + let context = self.database.create_context(self.profile); + + let _ = context.client.runtime_version_at(&BlockId::Number(0)) + .expect("Failed to get runtime version") + .spec_version; + + if mode == Mode::Profile { + std::thread::park_timeout(std::time::Duration::from_secs(3)); + } + + let mut proposer_factory = sc_basic_authorship::ProposerFactory::new( + context.client.clone(), + self.transactions.clone().into(), + None, + ); + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); + inherent_data_providers + .register_provider(sp_timestamp::InherentDataProvider) + .expect("Failed to register timestamp data provider"); + + let start = std::time::Instant::now(); + + let proposer = futures::executor::block_on(proposer_factory.init( + &context.client.header(&BlockId::number(0)) + .expect("Database error querying block #0") + .expect("Block #0 should exist"), + )).expect("Proposer initialization failed"); + + let _block = futures::executor::block_on( + proposer.propose( + inherent_data_providers.create_inherent_data().expect("Create inherent data failed"), + Default::default(), + std::time::Duration::from_secs(20), + RecordProof::Yes, + ), + ).map(|r| r.block).expect("Proposing failed"); + + let elapsed = start.elapsed(); + + if mode == Mode::Profile { + std::thread::park_timeout(std::time::Duration::from_secs(1)); + } + + elapsed + } +} + +#[derive(Clone, Debug)] +pub struct PoolTransaction { + data: OpaqueExtrinsic, + hash: node_primitives::Hash, +} + +impl From for PoolTransaction { + fn from(e: OpaqueExtrinsic) -> Self { + PoolTransaction { + data: e, + hash: node_primitives::Hash::zero(), + } + } +} + +impl sp_transaction_pool::InPoolTransaction for PoolTransaction { + type Transaction = OpaqueExtrinsic; + type Hash = node_primitives::Hash; + + fn data(&self) -> &Self::Transaction { + &self.data + } + + fn hash(&self) -> &Self::Hash { + &self.hash + } + + fn priority(&self) -> &u64 { unimplemented!() } + + fn longevity(&self) -> &u64 { unimplemented!() } + + fn requires(&self) -> &[Vec] { unimplemented!() } + + fn provides(&self) -> &[Vec] { unimplemented!() } + + fn is_propagable(&self) -> bool { unimplemented!() } +} + +#[derive(Clone, Debug)] +pub struct Transactions(Vec>); + +impl sp_transaction_pool::TransactionPool for Transactions { + type Block = Block; + type Hash = node_primitives::Hash; + type InPoolTransaction = PoolTransaction; + type Error = sp_transaction_pool::error::Error; + + /// Returns a future that imports a bunch of unverified transactions to the pool. + fn submit_at( + &self, + _at: &BlockId, + _source: TransactionSource, + _xts: Vec>, + ) -> PoolFuture>, Self::Error> { + unimplemented!() + } + + /// Returns a future that imports one unverified transaction to the pool. + fn submit_one( + &self, + _at: &BlockId, + _source: TransactionSource, + _xt: TransactionFor, + ) -> PoolFuture, Self::Error> { + unimplemented!() + } + + fn submit_and_watch( + &self, + _at: &BlockId, + _source: TransactionSource, + _xt: TransactionFor, + ) -> PoolFuture>, Self::Error> { + unimplemented!() + } + + fn ready_at(&self, _at: NumberFor) + -> Pin> + Send>> + Send>> + { + let iter: Box> + Send> = Box::new(self.0.clone().into_iter()); + Box::pin(futures::future::ready(iter)) + } + + fn ready(&self) -> Box> + Send> { + unimplemented!() + } + + fn remove_invalid(&self, _hashes: &[TxHash]) -> Vec> { + Default::default() + } + + fn status(&self) -> PoolStatus { + unimplemented!() + } + + fn import_notification_stream(&self) -> ImportNotificationStream> { + unimplemented!() + } + + fn on_broadcasted(&self, _propagations: HashMap, Vec>) { + unimplemented!() + } + + fn hash_of(&self, _xt: &TransactionFor) -> TxHash { + unimplemented!() + } + + fn ready_transaction(&self, _hash: &TxHash) -> Option> { + unimplemented!() + } +} \ No newline at end of file diff --git a/bin/node/bench/src/core.rs b/bin/node/bench/src/core.rs index db0b1180f4f20af35bddda8f9d7794de96887712..6faa7b72721f495ac6a481f3f48dd0b86e9efd3a 100644 --- a/bin/node/bench/src/core.rs +++ b/bin/node/bench/src/core.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{fmt, borrow::{Cow, ToOwned}}; use serde::Serialize; @@ -73,14 +75,14 @@ impl fmt::Display for NsFormatter { } if self.0 < 1_000_000 { - return write!(f, "{:.2} ms", v as f64 / 1_000_000.0) + return write!(f, "{:.4} ms", v as f64 / 1_000_000.0) } if self.0 < 100_000_000 { - return write!(f, "{} ms", v as f64 / 1_000_000.0) + return write!(f, "{:.1} ms", v as f64 / 1_000_000.0) } - write!(f, "{:.2} s", v as f64 / 1_000_000_000.0) + write!(f, "{:.4} s", v as f64 / 1_000_000_000.0) } } @@ -91,26 +93,26 @@ pub enum Mode { } impl std::str::FromStr for Mode { - type Err = &'static str; - fn from_str(day: &str) -> Result { - match day { - "regular" => Ok(Mode::Regular), - "profile" => Ok(Mode::Profile), - _ => Err("Could not parse mode"), - } - } + type Err = &'static str; + fn from_str(day: &str) -> Result { + match day { + "regular" => Ok(Mode::Regular), + "profile" => Ok(Mode::Profile), + _ => Err("Could not parse mode"), + } + } } impl fmt::Display for BenchmarkOutput { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( f, "{}: avg {}, w_avg {}", self.name, NsFormatter(self.raw_average), NsFormatter(self.average), ) - } + } } pub fn run_benchmark( @@ -157,4 +159,4 @@ macro_rules! matrix( } }; () => { vec![] } -); \ No newline at end of file +); diff --git a/bin/node/bench/src/generator.rs b/bin/node/bench/src/generator.rs index 895f523497036d26dcd517da7700b9c10ef19f59..759a4299c72758f540e92349de6a25591c506d39 100644 --- a/bin/node/bench/src/generator.rs +++ b/bin/node/bench/src/generator.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{collections::HashMap, sync::Arc}; diff --git a/bin/node/bench/src/import.rs b/bin/node/bench/src/import.rs index 10f5ee8dca0df4dd5247e27dc9e1a08a8685370f..e49a359fb6af16fc26a7f252ca759442c35bbe1a 100644 --- a/bin/node/bench/src/import.rs +++ b/bin/node/bench/src/import.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Block import benchmark. //! @@ -34,38 +36,12 @@ use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes, DatabaseType}; use node_primitives::Block; use sc_client_api::backend::Backend; use sp_runtime::generic::BlockId; +use sp_state_machine::InspectState; -use crate::core::{self, Path, Mode}; - -#[derive(Clone, Copy, Debug, derive_more::Display)] -pub enum SizeType { - #[display(fmt = "empty")] - Empty, - #[display(fmt = "small")] - Small, - #[display(fmt = "medium")] - Medium, - #[display(fmt = "large")] - Large, - #[display(fmt = "full")] - Full, - #[display(fmt = "custom")] - Custom, -} - -impl SizeType { - pub fn transactions(&self) -> usize { - match self { - SizeType::Empty => 0, - SizeType::Small => 10, - SizeType::Medium => 100, - SizeType::Large => 500, - SizeType::Full => 4000, - // Custom SizeType will use the `--transactions` input parameter - SizeType::Custom => 0, - } - } -} +use crate::{ + common::SizeType, + core::{self, Path, Mode}, +}; pub struct ImportBenchmarkDescription { pub profile: Profile, @@ -79,6 +55,7 @@ pub struct ImportBenchmark { profile: Profile, database: BenchDb, block: Block, + block_type: BlockType, } impl core::BenchmarkDescription for ImportBenchmarkDescription { @@ -97,9 +74,9 @@ impl core::BenchmarkDescription for ImportBenchmarkDescription { } match self.block_type { - BlockType::RandomTransfersKeepAlive(_) => path.push("transfer_keep_alive"), - BlockType::RandomTransfersReaping(_) => path.push("transfer_reaping"), - BlockType::Noop(_) => path.push("noop"), + BlockType::RandomTransfersKeepAlive => path.push("transfer_keep_alive"), + BlockType::RandomTransfersReaping => path.push("transfer_reaping"), + BlockType::Noop => path.push("noop"), } match self.database_type { @@ -119,9 +96,10 @@ impl core::BenchmarkDescription for ImportBenchmarkDescription { 50_000, self.key_types ); - let block = bench_db.generate_block(self.block_type); + let block = bench_db.generate_block(self.block_type.to_content(self.size.transactions())); Box::new(ImportBenchmark { database: bench_db, + block_type: self.block_type, block, profile, }) @@ -129,8 +107,9 @@ impl core::BenchmarkDescription for ImportBenchmarkDescription { fn name(&self) -> Cow<'static, str> { format!( - "Import benchmark ({:?}, {:?}, {:?} backend)", + "Block import ({:?}/{}, {:?}, {:?} backend)", self.block_type, + self.size, self.profile, self.database_type, ).into() @@ -153,6 +132,41 @@ impl core::Benchmark for ImportBenchmark { context.import_block(self.block.clone()); let elapsed = start.elapsed(); + // Sanity checks. + context.client.state_at(&BlockId::number(1)).expect("state_at failed for block#1") + .inspect_with(|| { + match self.block_type { + BlockType::RandomTransfersKeepAlive => { + // should be 5 per signed extrinsic + 1 per unsigned + // we have 1 unsigned and the rest are signed in the block + // those 5 events per signed are: + // - new account (RawEvent::NewAccount) as we always transfer fund to non-existant account + // - endowed (RawEvent::Endowed) for this new account + // - successful transfer (RawEvent::Transfer) for this transfer operation + // - deposit event for charging transaction fee + // - extrinsic success + assert_eq!( + node_runtime::System::events().len(), + (self.block.extrinsics.len() - 1) * 5 + 1, + ); + }, + BlockType::Noop => { + assert_eq!( + node_runtime::System::events().len(), + + // should be 2 per signed extrinsic + 1 per unsigned + // we have 1 unsigned and the rest are signed in the block + // those 2 events per signed are: + // - deposit event for charging transaction fee + // - extrinsic success + (self.block.extrinsics.len() - 1) * 2 + 1, + ); + }, + _ => {}, + } + } + ); + if mode == Mode::Profile { std::thread::park_timeout(std::time::Duration::from_secs(1)); } diff --git a/bin/node/bench/src/main.rs b/bin/node/bench/src/main.rs index df7e4c2da2be4fd7652f098ca3bc270ee354488b..96ef1d920c1f551cb0a467814599f0e9afbf5ce8 100644 --- a/bin/node/bench/src/main.rs +++ b/bin/node/bench/src/main.rs @@ -1,34 +1,46 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . +mod common; +mod construct; #[macro_use] mod core; mod import; -mod trie; -mod simple_trie; mod generator; -mod tempdb; +mod simple_trie; mod state_sizes; +mod tempdb; +mod trie; +mod txpool; -use crate::core::{run_benchmark, Mode as BenchmarkMode}; -use crate::tempdb::DatabaseType; -use import::{ImportBenchmarkDescription, SizeType}; -use trie::{TrieReadBenchmarkDescription, TrieWriteBenchmarkDescription, DatabaseSize}; -use node_testing::bench::{Profile, KeyTypes, BlockType, DatabaseType as BenchDataBaseType}; use structopt::StructOpt; +use node_testing::bench::{Profile, KeyTypes, BlockType, DatabaseType as BenchDataBaseType}; + +use crate::{ + common::SizeType, + core::{run_benchmark, Mode as BenchmarkMode}, + tempdb::DatabaseType, + import::ImportBenchmarkDescription, + trie::{TrieReadBenchmarkDescription, TrieWriteBenchmarkDescription, DatabaseSize}, + construct::ConstructionBenchmarkDescription, + txpool::PoolBenchmarkDescription, +}; + #[derive(Debug, StructOpt)] #[structopt(name = "node-bench", about = "Node integration benchmarks")] struct Opt { @@ -79,19 +91,15 @@ fn main() { SizeType::Medium, SizeType::Large, SizeType::Full, - SizeType::Custom, + SizeType::Custom(opt.transactions.unwrap_or(0)), ].iter() { - let txs = match size { - SizeType::Custom => opt.transactions.unwrap_or(0), - _ => size.transactions() - }; for block_type in [ - BlockType::RandomTransfersKeepAlive(txs), - BlockType::RandomTransfersReaping(txs), - BlockType::Noop(txs), + BlockType::RandomTransfersKeepAlive, + BlockType::RandomTransfersReaping, + BlockType::Noop, ].iter() { for database_type in [BenchDataBaseType::RocksDb, BenchDataBaseType::ParityDb].iter() { - import_benchmarks.push((profile, size, block_type.clone(), database_type)); + import_benchmarks.push((profile, size.clone(), block_type.clone(), database_type)); } } } @@ -102,7 +110,7 @@ fn main() { ImportBenchmarkDescription { profile: *profile, key_types: KeyTypes::Sr25519, - size: *size, + size: size, block_type: block_type, database_type: *database_type, }, @@ -128,6 +136,21 @@ fn main() { ] .iter().map(move |db_type| (size, db_type))) => TrieWriteBenchmarkDescription { database_size: *size, database_type: *db_type }, + ConstructionBenchmarkDescription { + profile: Profile::Wasm, + key_types: KeyTypes::Sr25519, + block_type: BlockType::RandomTransfersKeepAlive, + size: SizeType::Medium, + database_type: BenchDataBaseType::RocksDb, + }, + ConstructionBenchmarkDescription { + profile: Profile::Wasm, + key_types: KeyTypes::Sr25519, + block_type: BlockType::RandomTransfersKeepAlive, + size: SizeType::Large, + database_type: BenchDataBaseType::RocksDb, + }, + PoolBenchmarkDescription { database_type: BenchDataBaseType::RocksDb }, ); if opt.list { @@ -154,6 +177,11 @@ fn main() { } } + if results.is_empty() { + eprintln!("No benchmark was found for query"); + std::process::exit(1); + } + if opt.json { let json_result: String = serde_json::to_string(&results).expect("Failed to construct json"); println!("{}", json_result); diff --git a/bin/node/bench/src/simple_trie.rs b/bin/node/bench/src/simple_trie.rs index 50078a11df6b5290157bdbdfbc02389f1711261b..3cfd7ddb300a9101b22d55a2d460526a283fa0e2 100644 --- a/bin/node/bench/src/simple_trie.rs +++ b/bin/node/bench/src/simple_trie.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{collections::HashMap, sync::Arc}; diff --git a/bin/node/bench/src/tempdb.rs b/bin/node/bench/src/tempdb.rs index 4a0a793a22ccb4fdc561a1eed2942eb3a2a850e6..4020fd1029368209c71c2a1d5ce59bc6a0c140a3 100644 --- a/bin/node/bench/src/tempdb.rs +++ b/bin/node/bench/src/tempdb.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{io, sync::Arc}; use kvdb::{KeyValueDB, DBTransaction}; @@ -41,17 +43,14 @@ impl KeyValueDB for ParityDbWrapper { } /// Write a transaction of changes to the buffer. - fn write_buffered(&self, transaction: DBTransaction) { + fn write(&self, transaction: DBTransaction) -> io::Result<()> { self.0.commit( transaction.ops.iter().map(|op| match op { kvdb::DBOp::Insert { col, key, value } => (*col as u8, &key[key.len() - 32..], Some(value.to_vec())), kvdb::DBOp::Delete { col, key } => (*col as u8, &key[key.len() - 32..], None), + kvdb::DBOp::DeletePrefix { col: _, prefix: _ } => unimplemented!() }) ).expect("db error"); - } - - /// Flush all buffered data. - fn flush(&self) -> io::Result<()> { Ok(()) } @@ -61,7 +60,7 @@ impl KeyValueDB for ParityDbWrapper { } /// Iterate over flushed data for a given column, starting from a given prefix. - fn iter_from_prefix<'a>( + fn iter_with_prefix<'a>( &'a self, _col: u32, _prefix: &'a [u8], @@ -125,7 +124,6 @@ impl Clone for TempDatabase { .map(|f_result| f_result.expect("failed to read file in seed db") .path() - .clone() ).collect(); fs_extra::copy_items( &self_db_files, diff --git a/bin/node/bench/src/trie.rs b/bin/node/bench/src/trie.rs index 9a52e3c301617dfe8e6524389974b827c5115e6a..886dc6011492f4564aa679f6f5f483025c057b58 100644 --- a/bin/node/bench/src/trie.rs +++ b/bin/node/bench/src/trie.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Trie benchmark (integrated). diff --git a/bin/node/bench/src/txpool.rs b/bin/node/bench/src/txpool.rs new file mode 100644 index 0000000000000000000000000000000000000000..7ea13fc15ec68fb3a02ea7889282d281409bd67e --- /dev/null +++ b/bin/node/bench/src/txpool.rs @@ -0,0 +1,105 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +//! Transaction pool integrated benchmarks. +//! +//! The goal of this benchmark is to figure out time needed to fill +//! the transaction pool for the next block. + +use std::borrow::Cow; + +use node_testing::bench::{BenchDb, Profile, BlockType, KeyTypes, DatabaseType}; + +use sc_transaction_pool::BasicPool; +use sp_runtime::generic::BlockId; +use sp_transaction_pool::{TransactionPool, TransactionSource}; + +use crate::core::{self, Path, Mode}; + +pub struct PoolBenchmarkDescription { + pub database_type: DatabaseType, +} + +pub struct PoolBenchmark { + database: BenchDb, +} + +impl core::BenchmarkDescription for PoolBenchmarkDescription { + fn path(&self) -> Path { + Path::new(&["node", "txpool"]) + } + + fn setup(self: Box) -> Box { + Box::new(PoolBenchmark { + database: BenchDb::with_key_types( + self.database_type, + 50_000, + KeyTypes::Sr25519, + ), + }) + } + + fn name(&self) -> Cow<'static, str> { + "Transaction pool benchmark".into() + } +} + +impl core::Benchmark for PoolBenchmark { + fn run(&mut self, mode: Mode) -> std::time::Duration { + let context = self.database.create_context(Profile::Wasm); + + let _ = context.client.runtime_version_at(&BlockId::Number(0)) + .expect("Failed to get runtime version") + .spec_version; + + if mode == Mode::Profile { + std::thread::park_timeout(std::time::Duration::from_secs(3)); + } + + let executor = sp_core::testing::TaskExecutor::new(); + let txpool = BasicPool::new_full( + Default::default(), + None, + executor, + context.client.clone(), + ); + + let generated_transactions = self.database.block_content( + BlockType::RandomTransfersKeepAlive.to_content(Some(100)), + &context.client, + ).into_iter().collect::>(); + + let start = std::time::Instant::now(); + let submissions = generated_transactions.into_iter().map(|tx| { + txpool.submit_one( + &BlockId::Number(0), + TransactionSource::External, + tx, + ) + }); + futures::executor::block_on( + futures::future::join_all(submissions) + ); + let elapsed = start.elapsed(); + + if mode == Mode::Profile { + std::thread::park_timeout(std::time::Duration::from_secs(1)); + } + elapsed + } +} diff --git a/bin/node/browser-testing/Cargo.toml b/bin/node/browser-testing/Cargo.toml index 0f2a4751a8d8f48284775bcbf27b8025d7afbee8..1cfc0623dd98079a2e6bfadb1fad5e999f9c81f7 100644 --- a/bin/node/browser-testing/Cargo.toml +++ b/bin/node/browser-testing/Cargo.toml @@ -1,21 +1,21 @@ [package] name = "node-browser-testing" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] description = "Tests for the in-browser light client." edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" [dependencies] futures-timer = "3.0.2" -libp2p = { version = "0.18.0", default-features = false } -jsonrpc-core = "14.0.5" +libp2p = { version = "0.24.0", default-features = false } +jsonrpc-core = "14.2.0" serde = "1.0.106" serde_json = "1.0.48" -wasm-bindgen = { version = "=0.2.62", features = ["serde-serialize"] } +wasm-bindgen = { version = "=0.2.67", features = ["serde-serialize"] } wasm-bindgen-futures = "0.4.10" wasm-bindgen-test = "0.3.10" futures = "0.3.4" -node-cli = { path = "../cli", default-features = false, features = ["browser"] , version = "2.0.0-dev"} -sc-rpc-api = { path = "../../../client/rpc-api" , version = "0.8.0-dev"} +node-cli = { path = "../cli", default-features = false, features = ["browser"] , version = "2.0.0-rc6"} +sc-rpc-api = { path = "../../../client/rpc-api" , version = "0.8.0-rc6"} diff --git a/bin/node/browser-testing/src/lib.rs b/bin/node/browser-testing/src/lib.rs index 65f1e4620ba9c8aa59164e8776f051d513f7489d..777e5ea9f132e44d888ce8ea68b8d9e8fdf44655 100644 --- a/bin/node/browser-testing/src/lib.rs +++ b/bin/node/browser-testing/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! # Running //! Running this test can be done with @@ -36,34 +37,34 @@ use serde::de::DeserializeOwned; wasm_bindgen_test_configure!(run_in_browser); fn rpc_call(method: &str) -> String { - serde_json::to_string(&MethodCall { - jsonrpc: Some(Version::V2), - method: method.into(), - params: Params::None, - id: Id::Num(1) - }).unwrap() + serde_json::to_string(&MethodCall { + jsonrpc: Some(Version::V2), + method: method.into(), + params: Params::None, + id: Id::Num(1) + }).unwrap() } fn deserialize_rpc_result(js_value: JsValue) -> T { - let string = js_value.as_string().unwrap(); - let value = serde_json::from_str::(&string).unwrap().result; - // We need to convert a `Value::Object` into a proper type. - let value_string = serde_json::to_string(&value).unwrap(); - serde_json::from_str(&value_string).unwrap() + let string = js_value.as_string().unwrap(); + let value = serde_json::from_str::(&string).unwrap().result; + // We need to convert a `Value::Object` into a proper type. + let value_string = serde_json::to_string(&value).unwrap(); + serde_json::from_str(&value_string).unwrap() } #[wasm_bindgen_test] async fn runs() { - let mut client = node_cli::start_client(None, "info".into()) - .await - .unwrap(); + let mut client = node_cli::start_client(None, "info".into()) + .await + .unwrap(); - // Check that the node handles rpc calls. - // TODO: Re-add the code that checks if the node is syncing. - let chain_name: String = deserialize_rpc_result( - JsFuture::from(client.rpc_send(&rpc_call("system_chain"))) - .await - .unwrap() - ); - assert_eq!(chain_name, "Development"); + // Check that the node handles rpc calls. + // TODO: Re-add the code that checks if the node is syncing. + let chain_name: String = deserialize_rpc_result( + JsFuture::from(client.rpc_send(&rpc_call("system_chain"))) + .await + .unwrap() + ); + assert_eq!(chain_name, "Development"); } diff --git a/bin/node/cli/Cargo.toml b/bin/node/cli/Cargo.toml index de38ac66e548906b89d95ed934a6907e92692a89..92f223427a710c8241e76e01c48c8b99e9166f02 100644 --- a/bin/node/cli/Cargo.toml +++ b/bin/node/cli/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "node-cli" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] description = "Generic Substrate node implementation in Rust." build = "build.rs" edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" default-run = "substrate" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -34,88 +34,90 @@ crate-type = ["cdylib", "rlib"] [dependencies] # third-party dependencies -codec = { package = "parity-scale-codec", version = "1.3.0" } +codec = { package = "parity-scale-codec", version = "1.3.4" } serde = { version = "1.0.102", features = ["derive"] } futures = { version = "0.3.1", features = ["compat"] } -hex-literal = "0.2.1" -jsonrpc-core = "14.0.3" +hex-literal = "0.3.1" +jsonrpc-core = "14.2.0" +jsonrpc-pubsub = "14.2.0" log = "0.4.8" rand = "0.7.2" structopt = { version = "0.3.8", optional = true } -tracing = "0.1.10" +tracing = "0.1.18" parking_lot = "0.10.0" # primitives -sp-authority-discovery = { version = "2.0.0-dev", path = "../../../primitives/authority-discovery" } -sp-consensus-babe = { version = "0.8.0-dev", path = "../../../primitives/consensus/babe" } -grandpa-primitives = { version = "2.0.0-dev", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/timestamp" } -sp-finality-tracker = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/finality-tracker" } -sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } -sp-keyring = { version = "2.0.0-dev", path = "../../../primitives/keyring" } -sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } +sp-authority-discovery = { version = "2.0.0-rc6", path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8.0-rc6", path = "../../../primitives/consensus/babe" } +grandpa-primitives = { version = "2.0.0-rc6", package = "sp-finality-grandpa", path = "../../../primitives/finality-grandpa" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/timestamp" } +sp-finality-tracker = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/finality-tracker" } +sp-inherents = { version = "2.0.0-rc6", path = "../../../primitives/inherents" } +sp-keyring = { version = "2.0.0-rc6", path = "../../../primitives/keyring" } +sp-io = { version = "2.0.0-rc6", path = "../../../primitives/io" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../../primitives/transaction-pool" } # client dependencies -sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } -sc-chain-spec = { version = "2.0.0-dev", path = "../../../client/chain-spec" } -sc-consensus = { version = "0.8.0-dev", path = "../../../client/consensus/common" } -sc-transaction-pool = { version = "2.0.0-dev", path = "../../../client/transaction-pool" } -sc-network = { version = "0.8.0-dev", path = "../../../client/network" } -sc-consensus-babe = { version = "0.8.0-dev", path = "../../../client/consensus/babe" } -grandpa = { version = "0.8.0-dev", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } -sc-client-db = { version = "0.8.0-dev", default-features = false, path = "../../../client/db" } -sc-offchain = { version = "2.0.0-dev", path = "../../../client/offchain" } -sc-rpc = { version = "2.0.0-dev", path = "../../../client/rpc" } -sc-basic-authorship = { version = "0.8.0-dev", path = "../../../client/basic-authorship" } -sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service" } -sc-tracing = { version = "2.0.0-dev", path = "../../../client/tracing" } -sc-telemetry = { version = "2.0.0-dev", path = "../../../client/telemetry" } -sc-authority-discovery = { version = "0.8.0-dev", path = "../../../client/authority-discovery" } +sc-client-api = { version = "2.0.0-rc6", path = "../../../client/api" } +sc-chain-spec = { version = "2.0.0-rc6", path = "../../../client/chain-spec" } +sc-consensus = { version = "0.8.0-rc6", path = "../../../client/consensus/common" } +sc-transaction-pool = { version = "2.0.0-rc6", path = "../../../client/transaction-pool" } +sc-network = { version = "0.8.0-rc6", path = "../../../client/network" } +sc-consensus-babe = { version = "0.8.0-rc6", path = "../../../client/consensus/babe" } +grandpa = { version = "0.8.0-rc6", package = "sc-finality-grandpa", path = "../../../client/finality-grandpa" } +sc-client-db = { version = "0.8.0-rc6", default-features = false, path = "../../../client/db" } +sc-offchain = { version = "2.0.0-rc6", path = "../../../client/offchain" } +sc-rpc = { version = "2.0.0-rc6", path = "../../../client/rpc" } +sc-basic-authorship = { version = "0.8.0-rc6", path = "../../../client/basic-authorship" } +sc-service = { version = "0.8.0-rc6", default-features = false, path = "../../../client/service" } +sc-tracing = { version = "2.0.0-rc6", path = "../../../client/tracing" } +sc-telemetry = { version = "2.0.0-rc6", path = "../../../client/telemetry" } +sc-authority-discovery = { version = "0.8.0-rc6", path = "../../../client/authority-discovery" } # frame dependencies -pallet-indices = { version = "2.0.0-dev", path = "../../../frame/indices" } -pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../../frame/timestamp" } -pallet-contracts = { version = "2.0.0-dev", path = "../../../frame/contracts" } -frame-system = { version = "2.0.0-dev", path = "../../../frame/system" } -pallet-balances = { version = "2.0.0-dev", path = "../../../frame/balances" } -pallet-transaction-payment = { version = "2.0.0-dev", path = "../../../frame/transaction-payment" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../../../frame/support" } -pallet-im-online = { version = "2.0.0-dev", default-features = false, path = "../../../frame/im-online" } -pallet-authority-discovery = { version = "2.0.0-dev", path = "../../../frame/authority-discovery" } -pallet-staking = { version = "2.0.0-dev", path = "../../../frame/staking" } -pallet-grandpa = { version = "2.0.0-dev", path = "../../../frame/grandpa" } +pallet-indices = { version = "2.0.0-rc6", path = "../../../frame/indices" } +pallet-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/timestamp" } +pallet-contracts = { version = "2.0.0-rc6", path = "../../../frame/contracts" } +frame-system = { version = "2.0.0-rc6", path = "../../../frame/system" } +pallet-balances = { version = "2.0.0-rc6", path = "../../../frame/balances" } +pallet-transaction-payment = { version = "2.0.0-rc6", path = "../../../frame/transaction-payment" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/support" } +pallet-im-online = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/im-online" } +pallet-authority-discovery = { version = "2.0.0-rc6", path = "../../../frame/authority-discovery" } +pallet-staking = { version = "2.0.0-rc6", path = "../../../frame/staking" } +pallet-grandpa = { version = "2.0.0-rc6", path = "../../../frame/grandpa" } # node-specific dependencies -node-runtime = { version = "2.0.0-dev", path = "../runtime" } -node-rpc = { version = "2.0.0-dev", path = "../rpc" } -node-primitives = { version = "2.0.0-dev", path = "../primitives" } -node-executor = { version = "2.0.0-dev", path = "../executor" } +node-runtime = { version = "2.0.0-rc6", path = "../runtime" } +node-rpc = { version = "2.0.0-rc6", path = "../rpc" } +node-primitives = { version = "2.0.0-rc6", path = "../primitives" } +node-executor = { version = "2.0.0-rc6", path = "../executor" } # CLI-specific dependencies -sc-cli = { version = "0.8.0-dev", optional = true, path = "../../../client/cli" } -frame-benchmarking-cli = { version = "2.0.0-dev", optional = true, path = "../../../utils/frame/benchmarking-cli" } -node-inspect = { version = "0.8.0-dev", optional = true, path = "../inspect" } +sc-cli = { version = "0.8.0-rc6", optional = true, path = "../../../client/cli" } +frame-benchmarking-cli = { version = "2.0.0-rc6", optional = true, path = "../../../utils/frame/benchmarking-cli" } +node-inspect = { version = "0.8.0-rc6", optional = true, path = "../inspect" } # WASM-specific dependencies wasm-bindgen = { version = "0.2.57", optional = true } wasm-bindgen-futures = { version = "0.4.7", optional = true } -browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-dev"} +browser-utils = { package = "substrate-browser-utils", path = "../../../utils/browser", optional = true, version = "0.8.0-rc6"} [target.'cfg(target_arch="x86_64")'.dependencies] -node-executor = { version = "2.0.0-dev", path = "../executor", features = [ "wasmtime" ] } -sc-cli = { version = "0.8.0-dev", optional = true, path = "../../../client/cli", features = [ "wasmtime" ] } -sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service", features = [ "wasmtime" ] } +node-executor = { version = "2.0.0-rc6", path = "../executor", features = [ "wasmtime" ] } +sc-cli = { version = "0.8.0-rc6", optional = true, path = "../../../client/cli", features = [ "wasmtime" ] } +sc-service = { version = "0.8.0-rc6", default-features = false, path = "../../../client/service", features = [ "wasmtime" ] } +sp-trie = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/trie", features = ["memory-tracker"] } [dev-dependencies] -sc-keystore = { version = "2.0.0-dev", path = "../../../client/keystore" } -sc-consensus = { version = "0.8.0-dev", path = "../../../client/consensus/common" } -sc-consensus-babe = { version = "0.8.0-dev", features = ["test-helpers"], path = "../../../client/consensus/babe" } -sc-consensus-epochs = { version = "0.8.0-dev", path = "../../../client/consensus/epochs" } -sc-service-test = { version = "2.0.0-dev", path = "../../../client/service/test" } +sc-keystore = { version = "2.0.0-rc6", path = "../../../client/keystore" } +sc-consensus = { version = "0.8.0-rc6", path = "../../../client/consensus/common" } +sc-consensus-babe = { version = "0.8.0-rc6", features = ["test-helpers"], path = "../../../client/consensus/babe" } +sc-consensus-epochs = { version = "0.8.0-rc6", path = "../../../client/consensus/epochs" } +sc-service-test = { version = "2.0.0-rc6", path = "../../../client/service/test" } futures = "0.3.4" tempfile = "3.1.0" assert_cmd = "1.0" @@ -126,12 +128,13 @@ platforms = "0.2.1" [build-dependencies] structopt = { version = "0.3.8", optional = true } -node-inspect = { version = "0.8.0-dev", optional = true, path = "../inspect" } -frame-benchmarking-cli = { version = "2.0.0-dev", optional = true, path = "../../../utils/frame/benchmarking-cli" } -substrate-build-script-utils = { version = "2.0.0-dev", optional = true, path = "../../../utils/build-script-utils" } +node-inspect = { version = "0.8.0-rc6", optional = true, path = "../inspect" } +frame-benchmarking-cli = { version = "2.0.0-rc6", optional = true, path = "../../../utils/frame/benchmarking-cli" } +substrate-build-script-utils = { version = "2.0.0-rc6", optional = true, path = "../../../utils/build-script-utils" } +substrate-frame-cli = { version = "2.0.0-rc6", optional = true, path = "../../../utils/frame/frame-utilities-cli" } [build-dependencies.sc-cli] -version = "0.8.0-dev" +version = "0.8.0-rc6" package = "sc-cli" path = "../../../client/cli" optional = true @@ -148,6 +151,7 @@ cli = [ "node-inspect", "sc-cli", "frame-benchmarking-cli", + "substrate-frame-cli", "sc-service/db", "structopt", "substrate-build-script-utils", diff --git a/bin/node/cli/bin/main.rs b/bin/node/cli/bin/main.rs index cfad84a4cb5520f2542dc18da771d4cfa4a0a9ed..299b760c82e36b2b6540f6ae4efd8111cf430640 100644 --- a/bin/node/cli/bin/main.rs +++ b/bin/node/cli/bin/main.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate Node CLI diff --git a/bin/node/cli/browser-demo/README.md b/bin/node/cli/browser-demo/README.md index 08f1646f114a3104fa1cac14e83c03306860e7c9..a11b250ba1f15d9e17b9d9e70f757714ae007765 100644 --- a/bin/node/cli/browser-demo/README.md +++ b/bin/node/cli/browser-demo/README.md @@ -1,6 +1,10 @@ # How to run this demo ```sh -cargo install wasm-bindgen-cli # If necessary +# If necessary, install wasm-bindgen +# The version must match that used when building the browser demo. +cargo install --version 0.2.67 wasm-bindgen-cli + +# Run the build script ./build.sh ``` diff --git a/bin/node/cli/browser-demo/build.sh b/bin/node/cli/browser-demo/build.sh index be52b7a523f0177728181bfa18b8aef614185a26..ea0380b760e31f4037d49509c7852b02baf81501 100755 --- a/bin/node/cli/browser-demo/build.sh +++ b/bin/node/cli/browser-demo/build.sh @@ -1,4 +1,4 @@ #!/usr/bin/env sh cargo +nightly build --release -p node-cli --target wasm32-unknown-unknown --no-default-features --features browser -Z features=itarget wasm-bindgen ../../../../target/wasm32-unknown-unknown/release/node_cli.wasm --out-dir pkg --target web -python -m http.server 8000 +python -m SimpleHTTPServer 8000 diff --git a/bin/node/cli/build.rs b/bin/node/cli/build.rs index 12e0cab58ada5797c069e9a24970be6daa06de4f..a36f0d01a0a034a10686d3565e6abf538e6a5886 100644 --- a/bin/node/cli/build.rs +++ b/bin/node/cli/build.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . fn main() { #[cfg(feature = "cli")] diff --git a/bin/node/cli/res/flaming-fir.json b/bin/node/cli/res/flaming-fir.json index 7cc2c11c327e158842332faf6405d91983b6886c..e2ecac2b44880a93482e9e4143b3c726536cdf10 100644 --- a/bin/node/cli/res/flaming-fir.json +++ b/bin/node/cli/res/flaming-fir.json @@ -1,24 +1,24 @@ { "name": "Flaming Fir", - "id": "flamingfir7", + "id": "flamingfir8", "chainType": "Live", "bootNodes": [ - "/ip4/35.246.224.91/tcp/30333/p2p/QmaGKGpdm2iLiVCAnEcwrAhHxrcjMdGao4UubJxq7AF77n", - "/ip4/35.246.224.91/tcp/30334/ws/p2p/QmaGKGpdm2iLiVCAnEcwrAhHxrcjMdGao4UubJxq7AF77n", - "/ip4/35.246.210.11/tcp/30333/p2p/QmbS1xrmWyP5h4xsPwAS7CJEJNStsuAUDUzhggqDJtLpou", - "/ip4/35.246.210.11/tcp/30334/ws/p2p/QmbS1xrmWyP5h4xsPwAS7CJEJNStsuAUDUzhggqDJtLpou", - "/ip4/35.198.110.45/tcp/30333/p2p/QmdSHZLmwEL5Axz5JvWNE2mmxU7qyd7xHBFpyUfktgAdg7", - "/ip4/35.198.110.45/tcp/30334/ws/p2p/QmdSHZLmwEL5Axz5JvWNE2mmxU7qyd7xHBFpyUfktgAdg7", - "/ip4/35.198.114.154/tcp/30333/p2p/Qmeo7it7YGbhGZqkDGpgnR3xMRFSp6AutA9oTDZPQyny8h", - "/ip4/35.198.114.154/tcp/30334/ws/p2p/Qmeo7it7YGbhGZqkDGpgnR3xMRFSp6AutA9oTDZPQyny8h" + "/dns/0.flamingfir.paritytech.net/tcp/30333/p2p/12D3KooWLK2gMLhWsYJzjW3q35zAs9FDDVqfqVfVuskiGZGRSMvR", + "/dns/0.flamingfir.paritytech.net/tcp/30334/ws/p2p/12D3KooWLK2gMLhWsYJzjW3q35zAs9FDDVqfqVfVuskiGZGRSMvR", + "/dns/1.flamingfir.paritytech.net/tcp/30333/p2p/12D3KooWHyUSQkoL1WtnhLUYHuKbowZEZW1NNJe7TePKYZf9ucBY", + "/dns/1.flamingfir.paritytech.net/tcp/30334/ws/p2p/12D3KooWHyUSQkoL1WtnhLUYHuKbowZEZW1NNJe7TePKYZf9ucBY", + "/dns/2.flamingfir.paritytech.net/tcp/30333/p2p/12D3KooWFcry65ShtPT6roTTEPXD9H89A1iA2wPKgJCgXW1yZwyy", + "/dns/2.flamingfir.paritytech.net/tcp/30334/ws/p2p/12D3KooWFcry65ShtPT6roTTEPXD9H89A1iA2wPKgJCgXW1yZwyy", + "/dns/3.flamingfir.paritytech.net/tcp/30333/p2p/12D3KooWDfFapccu3KgvWyVMdXhMGPPpKiJ1yEhSMEupBZppfi9U", + "/dns/3.flamingfir.paritytech.net/tcp/30334/ws/p2p/12D3KooWDfFapccu3KgvWyVMdXhMGPPpKiJ1yEhSMEupBZppfi9U" ], "telemetryEndpoints": [ [ - "/dns4/telemetry.polkadot.io/tcp/443/x-parity-wss/%2Fsubmit%2F", + "/dns/telemetry.polkadot.io/tcp/443/x-parity-wss/%2Fsubmit%2F", 0 ] ], - "protocolId": "fir7", + "protocolId": "fir8", "properties": { "tokenDecimals": 15, "tokenSymbol": "FIR" @@ -29,111 +29,111 @@ "genesis": { "raw": { "top": { - "0x5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1": "0x08000000", - "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x106e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f910600299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", - "0x426e15054d267946093858132eb537f195999521c6c89cd80b677e53ce20f98c": "0x9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", - "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc40a81aa5d99517e5635e7865ccd909c4066bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630f0000c16ff286230f0000c16ff286230000", - "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a00000000c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x00", - "0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3": "0x00", - "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb354352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106", "0xcec5070d609dd3497f72bde07fc96ba0e0cdd062e6eaf24295ad4ccfc41d4609": "0x109c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d129becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26633919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d655633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde787932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", + "0xf2794c22e353e9a839f12faab03a911be2f6cb0456905c189bcb0458f9440f13": "0x00000000", + "0x5f3e4907f716ac89b6347d15ececedcac29a0310e1bb45d20cace77ccb62c97d": "0x00e1f505", + "0x426e15054d267946093858132eb537f1ba7fb8745735dc3be2a2c61a72c39e78": "0x049ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e16903c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a00000000c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a0000000054352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca138e71612491192d68deab7e6f563fe1": "0x08000000", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb37441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9a8d6d78917f3d243ed0a3d1dfb3878099c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x00000000030000c16ff28623000000000000000000000000000000000000000000000000000000c16ff286230000000000000000000000c16ff28623000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f05c8ba6ac2a99ca6175646980482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950279056c0dd3fd147696d6f6e806e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195082216e38506cc6f7626162658000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", "0xf2794c22e353e9a839f12faab03a911b7f17cdfbfa73331856cca0acddd7842e": "0x00000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195088c3e18f0a370f936772616e809becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x5f3e4907f716ac89b6347d15ececedcaac0a2cbf8e355f5ea6cb2de8727bfb0c": "0x54000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc65018afb0daf0c8654bf248b8e9f3ca3cf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x047374616b696e67200000c16ff2862300000000000000000002", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e1690354352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950606e9687c0a4d75f696d6f6e80482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe7079091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526", + "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0xd503106e6f6465", "0xf2794c22e353e9a839f12faab03a911bbdcb0c5143a8617ed38ae3810dd45bc6": "0x00000000", - "0x426e15054d267946093858132eb537f105fe52c2045750c3c492ccdcf62e2b9c": "0x9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", - "0xc2261276cc9d1f8598ea4b6a74b15c2f308ce9615de0775a82f8a94dc3d285a1": "0x01", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9bed2903186223711a06d85784e730efd547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x00000000030000c16ff28623000000000000000000000000000000000000000000000000000000c16ff286230000000000000000000000c16ff28623000000000000000000", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195082c7c7fe191a6e68696d6f6e80482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e169037441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x00", - "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a000000007441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x0ff6ffc06ff286230ff6ffc06ff2862300", - "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a0000000054352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x0ff6ffc06ff286230ff6ffc06ff2862300", - "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe707441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ecffd7b6c0f78751baa9d281e0bfa3a6d6f646c70792f74727372790000000000000000000000000000000000000000": "0x000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0x492a52699edf49c972c21db794cfcf57ba7fb8745735dc3be2a2c61a72c39e78": "0x00", - "0x4342193e496fab7ec59d615ed0dc5530d2d505c0e6f76fd7ce0796ebe187401c": "0x0000000020a107000000000020a107000000000020a107000000000020a107000000000020a107000000000020a107000000000020a1070000000000e0f7050400000000e024370500000000e0f705040000000020a107000000000020a107000000000080f0fa020000000000e1f50500000000040000000000010010000000004000000020000000", - "0x5f3e4907f716ac89b6347d15ececedca5579297f4dfb9609e7e4c2ebab9ce40a": "0x109c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e1690379091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x00", - "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade9854352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x00", - "0x5f3e4907f716ac89b6347d15ececedcaad811cd65a470ddc5f1d628ff0550982b4def25cfda6ef3a00000000": "0x00000000", - "0x5f3e4907f716ac89b6347d15ececedcac29a0310e1bb45d20cace77ccb62c97d": "0x00e1f505", - "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00401eae822458363600000000000000", - "0x11f3ba2e1cdd6d62f2ff9b5589e7ff81ba7fb8745735dc3be2a2c61a72c39e78": "0x049ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", - "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", - "0x5f3e4907f716ac89b6347d15ececedcaac0a2cbf8e355f5ea6cb2de8727bfb0c": "0x54000000", - "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb379091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a", - "0x3a636f6465": "0x0061736d01000000018e033760037f7f7f017f60027f7f017f60027f7f0060017f0060037f7f7f0060057f7f7f7f7f0060047f7f7f7f0060017f017e60037f7e7e0060017e017f60027e7e0060017e017e60017e006000006000017f60027f7e017e60047f7e7e7e017f60027e7e017e60037e7e7e0060037f7e7f017f60047f7e7e7f017f60067f7e7e7f7f7f017f60047f7f7f7f017f6000017e60037e7e7f017e60017f017f60027f7e017f60027f7f017e60037f7f7e017e60037e7f7f017f60067f7f7f7f7f7f017f60077f7f7f7f7f7f7f017f60057f7f7f7f7f017f60027f7e0060047f7f7e7e0060057f7e7e7f7f0060057f7f7f7e7e0060067f7f7f7f7f7f0060057f7f7e7e7f0060047e7e7e7e017f60067f7f7f7e7e7f0060077f7e7e7e7e7e7e0060067f7f7e7f7e7e0060077f7f7f7e7e7f7f0060077f7f7f7f7e7e7f0060087e7e7e7e7e7e7e7e017f60047f7f7f7f017e60067f7f7f7f7e7e0060057f7e7e7e7e0060087f7f7f7f7f7e7e7f0060077f7f7e7e7f7f7f0060027e7f0060037f7e7f0060067f7e7e7e7e7f0060047f7e7e7f0002cd103403656e76066d656d6f727902001403656e76196578745f6c6f6767696e675f6c6f675f76657273696f6e5f31000803656e761e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f31000903656e76196578745f73746f726167655f7365745f76657273696f6e5f31000a03656e761d6578745f68617368696e675f74776f785f36345f76657273696f6e5f31000903656e76206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f31000903656e76196578745f73746f726167655f6765745f76657273696f6e5f31000b03656e761d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f31000c03656e761b6578745f73746f726167655f636c6561725f76657273696f6e5f31000c03656e76226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f31000c03656e76206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f31000903656e761c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f31000c03656e76276578745f63727970746f5f73746172745f62617463685f7665726966795f76657273696f6e5f31000d03656e76286578745f63727970746f5f66696e6973685f62617463685f7665726966795f76657273696f6e5f31000e03656e76236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f31000e03656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f31000f03656e76346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f31001003656e76276578745f64656661756c745f6368696c645f73746f726167655f6765745f76657273696f6e5f31001103656e76306578745f64656661756c745f6368696c645f73746f726167655f73746f726167655f6b696c6c5f76657273696f6e5f31000c03656e76276578745f64656661756c745f6368696c645f73746f726167655f7365745f76657273696f6e5f31001203656e76296578745f64656661756c745f6368696c645f73746f726167655f636c6561725f76657273696f6e5f31000a03656e76226578745f6f6666636861696e5f72616e646f6d5f736565645f76657273696f6e5f31000e03656e76236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f32001303656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f31000803656e76206578745f73616e64626f785f6d656d6f72795f6e65775f76657273696f6e5f31000103656e76256578745f73616e64626f785f6d656d6f72795f74656172646f776e5f76657273696f6e5f31000303656e76216578745f73616e64626f785f696e7374616e74696174655f76657273696f6e5f31001403656e761c6578745f73616e64626f785f696e766f6b655f76657273696f6e5f31001503656e76276578745f73616e64626f785f696e7374616e63655f74656172646f776e5f76657273696f6e5f31000303656e76206578745f73616e64626f785f6d656d6f72795f6765745f76657273696f6e5f31001603656e76206578745f73616e64626f785f6d656d6f72795f7365745f76657273696f6e5f31001603656e761e6578745f68617368696e675f736861325f3235365f76657273696f6e5f31000903656e76206578745f68617368696e675f6b656363616b5f3235365f76657273696f6e5f31000903656e76236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f31001303656e76286578745f64656661756c745f6368696c645f73746f726167655f726f6f745f76657273696f6e5f31000b03656e761c6578745f73746f726167655f617070656e645f76657273696f6e5f31000a03656e761a6578745f73746f726167655f726f6f745f76657273696f6e5f31001703656e76226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f31000b03656e76226578745f6d6973635f72756e74696d655f76657273696f6e5f76657273696f6e5f31000b03656e761c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f31000c03656e761e6578745f73746f726167655f6e6578745f6b65795f76657273696f6e5f31000b03656e762a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f31000903656e76246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f31001703656e76296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f31000b03656e761a6578745f73746f726167655f726561645f76657273696f6e5f31001803656e761e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f31001903656e761c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f31000303656e76256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f31001a03656e76376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f31001b03656e76256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f31001a03656e76286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f31000703656e76216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f31001c03f407f20719190303000019191b0d0d0d04040204000d0d0500010102010202020204011d0303071e1604040005010101191f01010104010100062001010001010000010003040102020402040200010104010201010203040404040404040404040404040402040404040404040404040404040404040404040402040302020401020304040202020202020202040202020403210202020102070205220502040206040404040404040302040202042308020202030d1903020202040202020202020102030202020202040306022002020401192402040402020425020203020426020220022722010403060604020303030d020202020506060402030102030106020404040402020402030302190202020402040402020202040204040402020401040404020204020402020202040404020404010228020319220204020228060303020303030202030202020206250103020604020204030419190402020303290303040404040402020202020202020202020202020d02020204040402020403031b021b0203020202060d0303020202011b021b031b02021b021b02020202021b041b041b020204042a04021b020502010201020d1b021b1b1b1b021b2b022c1b02041b05051b1b04041b02020d020203040504010406020203020302020405040104020202030302292d01052700030303030202020202020202022206020402040402020303010403050101010d020302020402040c02020407021d21030303030303030302040202010102030001012e02020602020602020402020202060402040202030303020303030202020203020202020302020204020602020202022f020202063002250d06060606060606060606060606060606060606060606060606060606060606060606163132060303020102020202020403030303030303030303030303030303030303030303030303030303030302020202020202020202020202020216040202020203040202020d0406040404040406020404040202020202040303030202020302020202020402030302040306030206040122040402030204070202020303020303030202020203030302020202020200020202020202032602020303023002330504020204030302020203030203060202010206020204040203030303020201020604000406020201030302020203030303030203020202040302020602020206020304040504340202020102040201050202030303040202060102040101050202040403030303020202010402010101010101010101040201020104010401040403010204010304041901010201010501010604060401050504040204060301010130353035300d300b1111111108300303303030111108303035303000000000363636360407017001a902a9020619037f01418080c0000b7f00419cb5cc000b7f00419cb5cc000b07e8051a195f5f696e6469726563745f66756e6374696f6e5f7461626c65010009686173685f74657374003b0c436f72655f76657273696f6e00b30312436f72655f657865637574655f626c6f636b00b50315436f72655f696e697469616c697a655f626c6f636b00c303114d657461646174615f6d6574616461746100c5031c426c6f636b4275696c6465725f6170706c795f65787472696e73696300c7031b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00ca0320426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637300cc031c426c6f636b4275696c6465725f636865636b5f696e686572656e747300d20318426c6f636b4275696c6465725f72616e646f6d5f7365656400d4032b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e00d603214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b657200de031e4772616e6470614170695f6772616e6470615f617574686f72697469657300e70315426162654170695f636f6e66696775726174696f6e00e9031b426162654170695f63757272656e745f65706f63685f737461727400ea0321417574686f72697479446973636f766572794170695f617574686f72697469657300eb031d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e636500ec0311436f6e7472616374734170695f63616c6c00ee0318436f6e7472616374734170695f6765745f73746f7261676500f2031c436f6e7472616374734170695f72656e745f70726f6a656374696f6e00f503205472616e73616374696f6e5061796d656e744170695f71756572795f696e666f00f8032153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797300f9031f53657373696f6e4b6579735f6465636f64655f73657373696f6e5f6b65797300fc030a5f5f646174615f656e6403010b5f5f686561705f62617365030209be04010041010ba8024b51655cee075d5e8201c60171dd04c203e203e403bd04be049c059d059e059f05a005a105a205a305a405a505a605a705a805a905aa05ab05ac05ad05ae05af05b005b105b205b305b405b505b605b705b805b905ba05bb05bc05bd05e304dc04c505aa07b907bc07bd07ae0766e507f607d2078008dc07de07544748497555676a6b6c6d6e7c7d7e80018101850183018401f001eb06ef018105e8019a06ee01ed01ec01eb01e901e701f501f40162f302f702a904ee05fd02fc02fb02fa0263e6068c048f048e04a804a704a604a504b804f007bf04d804eb07e004e104e204fe04ff048605fa04850584058305e706f10799069806cc059d06a90693039203cd058907b2038b048d04d604d504d704fb06fa06880799049804ce05f202f102cf05f4028803d005d105e601e301d205f3019f02ea06e906d305f906fd04fc04d4058205c30591078f07d505a1079007f602f502d605f9029003a606a506d705d805d905da05e506e406db05f806c606c506dc05c706d906dd05de05df05e005e105bc06bb06e205d506d404d204e305df04fb04e4059307a204a104e505a404b704bf06be06e605c006da068e078d07e7059807f804f704e805f904c2058705e905f005ef05ed05ec05eb05ea05f205f105f505f405f605d4079c069b06a206a106a0069f069e06bd06c406c306c206c106cc06cb06ca06c906c80684048504870486048304f003e206e106e306e806ec06910492049404930490049504ed07ce07d107cf07d307d507d007e207d807fe078108ff070a9ca066f2070600200010340b06002000102c0b0600200010360b06002000102d0b0a0020002001200210380b2801017f02402002102c2203450d002003200020022001200120024b1b109d081a2000102d0b20030b06002000103a0b1c01017f02402000102c2201450d00200141002000109f081a0b20010bff0202017f037e230041206b220224002001ad42adfed5e4d485fda8d8007e42b9e0007c210302400240024002400240200141084b0d00200141014b0d0120010d02420021040c030b0240200141104b0d00200241106a2000290000200385420042adfed5e4d485fda8d8004200108408200241186a29030020022903107c200120006a41786a2900008521040c040b200120006a41786a2900002105200321040340200029000020048542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e2003852103200041086a2100200442cf829ebbefefde82147c2104200141786a220141084b0d000b200320058521040c030b0240200141034b0d00200120006a417e6a33000042108620003300008420038521040c030b200120006a417c6a35000042208620003500008420038521040c020b200031000021040b200420038521040b20022004420042adfed5e4d485fda8d8004200108408200241086a290300210420022903002103200241206a2400200420037c42c300850b0500103d000b2400410041d09bcc00ad4280808080f0008441d79bcc00ad4280808080a00484100000000b1100418080c0004111419480c000103f000b4701017f230041206b22032400200341146a4100360200200341b0b4cc00360210200342013702042003200136021c200320003602182003200341186a36020020032002104c000bdd0101047f0240024002400240200041046a2802002203200041086a28020022046b200220016b2202490d00200028020021050c010b200420026a22052004490d01200341017422062005200620054b1b22064100480d010240024002402003450d00200028020022050d010b024020060d00410121050c020b2006103322050d010c040b024020032006460d00200520032006103721050b2005450d03200041086a28020021040b20002005360200200041046a20063602000b200520046a20012002109d081a200041086a200420026a3602000f0b103e000b103c000b8b0301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b024020040d004100410041bc80c0001042000b024002402006410f4b0d00200341046a280200450d010b200620066a220720064f0d010b4100210741012105200241086a21060c010b2007417f4c0d01200241086a2106024020070d0041002107410121050c010b200710332205450d020b20024100360210200220053602082002200736020c2002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a41cc80c000200241186a10430d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b1044000b1045000b41e480c0004133200241186a419881c00041a881c0001046000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341c886c000360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a2002104c000bba06010a7f230041306b22032400200341246a2001360200200341033a002820034280808080800437030820032000360220410021042003410036021820034100360210024002400240024020022802082205450d0020022802002106200228020422072002410c6a2802002208200820074b1b2209450d01200241146a280200210a2002280210210b41012108200020062802002006280204200128020c1100000d03200541106a2102200641086a2100410121040240024003402003200241746a28020036020c20032002410c6a2d00003a00282003200241786a280200360208200241086a28020021084100210541002101024002400240200241046a2802000e03010002010b2008200a4f0d032008410374210c41002101200b200c6a220c2802044102470d01200c28020028020021080b410121010b2003200836021420032001360210200228020021080240024002402002417c6a2802000e03010002010b2008200a4f0d0420084103742101200b20016a22012802044102470d01200128020028020021080b410121050b2003200836021c200320053602180240200241706a2802002208200a4f0d00200b20084103746a2208280200200341086a20082802041101000d06200420094f0d05200041046a210120002802002105200241206a2102200041086a210041012108200441016a2104200328022020052001280200200328022428020c110000450d010c070b0b2008200a41a08bc0001042000b2008200a41908bc0001042000b2008200a41908bc0001042000b2002280200210620022802042207200241146a2802002208200820074b1b220a450d002002280210210241012108200020062802002006280204200128020c1100000d02200641086a21004101210403402002280200200341086a200241046a2802001101000d022004200a4f0d01200041046a210120002802002105200241086a2102200041086a210041012108200441016a2104200328022020052001280200200328022428020c110000450d000c030b0b0240200720044d0d00410121082003280220200620044103746a22022802002002280204200328022428020c1100000d020b410021080c010b410121080b200341306a240020080b0500103e000b0500103c000b7e01017f230041c0006b220524002005200136020c2005200036020820052003360214200520023602102005412c6a41023602002005413c6a41033602002005420237021c200541cc92c800360218200541043602342005200541306a3602282005200541106a3602382005200541086a360230200541186a2004104c000b120020002802002001200120026a104041000bcb0301047f230041106b22022400200028020021000240024002400240024002402001418001490d002002410036020c2001418010490d012002410c6a210302402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c050b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c040b0240024020002802082203200041046a280200460d00200028020021040c010b200341016a22042003490d02200341017422052004200520044b1b22054100480d020240024002402003450d00200028020022040d010b024020050d00410121040c020b2005103322040d010c050b024020032005460d00200420032005103721040b2004450d04200028020821030b20002004360200200041046a20053602000b200420036a20013a00002000200028020841016a3602080c040b20022001413f71418001723a000d20022001410676411f7141c001723a000c2002410c6a2103410221010c020b103e000b103c000b20002003200320016a10400b200241106a240041000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41cc80c000200241086a10432101200241206a240020010b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c2002419482c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41ac82c000104c000b0d0020003502004101200110520b3401017f230041106b220224002002200136020c20022000360208200241d886c000360204200241b0b4cc0036020020021053000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241fc82c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a419483c000104c000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241d083c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41e883c000104c000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c2002418c84c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41a484c000104c000bc40101037f0240024002402002417f4c0d000240024020020d0041002103410121040c010b20022103200210332204450d020b0240024020032002490d00200321050c010b02400240200341017422052002200520024b1b22054100480d00024002402003450d0020040d010b2005103322040d030c060b20032005470d01200321050c020b103e000b20042003200510372204450d030b200420012002109d0821032000200236020820002005360204200020033602000f0b1044000b1045000b103c000b0d0020002802001a037f0c000b0bd40203027f017e037f230041306b22032400412721040240024020004290ce005a0d00200021050c010b412721040340200341096a20046a2206417c6a200020004290ce0080220542f0b17f7e7ca7220741ffff037141e4006e2208410174419a87c0006a2f00003b00002006417e6a2008419c7f6c20076a41ffff0371410174419a87c0006a2f00003b00002004417c6a2104200042ffc1d72f5621062005210020060d000b0b02402005a7220641e3004c0d00200341096a2004417e6a22046a2005a7220741ffff037141e4006e2206419c7f6c20076a41ffff0371410174419a87c0006a2f00003b00000b024002402006410a480d00200341096a2004417e6a22046a2006410174419a87c0006a2f00003b00000c010b200341096a2004417f6a22046a200641306a3a00000b2002200141b0b4cc004100200341096a20046a412720046b10562104200341306a240020040b6f01017f230041c0006b220124002001200036020c200141346a41013602002001420137022420014188b2cc003602202001410536023c2001200141386a36023020012001410c6a360238200141106a200141206a1041410141d09bcc0041072001280210200128021810ef0700000b02000b0d0042a98089cda5ebd0e9ae7f0b830601067f024002402001450d00412b418080c4002000280200220641017122011b2107200120056a21080c010b200541016a210820002802002106412d21070b0240024020064104710d00410021020c010b4100210902402003450d002003210a200221010340200920012d000041c00171418001466a2109200141016a2101200a417f6a220a0d000b0b200820036a20096b21080b410121010240024020002802084101460d00200020072002200310570d012000280218200420052000411c6a28020028020c11000021010c010b02402000410c6a280200220920084b0d00200020072002200310570d012000280218200420052000411c6a28020028020c1100000f0b0240024020064108710d0041002101200920086b22092108024002400240410120002d0020220a200a4103461b0e0402010001020b20094101762101200941016a41017621080c010b41002108200921010b200141016a210103402001417f6a2201450d0220002802182000280204200028021c280210110100450d000b41010f0b200028020421062000413036020420002d0020210b41012101200041013a0020200020072002200310570d0141002101200920086b220a2103024002400240410120002d0020220920094103461b0e0402010001020b200a4101762101200a41016a41017621030c010b41002103200a21010b200141016a2101024003402001417f6a2201450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210a41012101200028021820042005200028021c28020c1100000d01200341016a2109200028021c210320002802182102024003402009417f6a2209450d01410121012002200a20032802101101000d030c000b0b2000200b3a00202000200636020441000f0b2000280204210a41012101200020072002200310570d00200028021820042005200028021c28020c1100000d00200841016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110100450d000b0b20010b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101101000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11000021040b20040b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341e488c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002104c000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c2003419c89c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002104c000b9307010c7f200041106a28020021030240024002400240200041086a28020022044101460d0020034101460d012000280218200120022000411c6a28020028020c11000021030c030b20034101470d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20044101460d002000280218200120022000411c6a28020028020c1100000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1100000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a2209210a024002400240410020002d0020220320034103461b0e0402010001020b20094101762107200941016a410176210a0c010b4100210a200921070b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1100000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110100450d000b41010f0b20030bc80801067f230041f0006b220524002005200336020c20052002360208410121062001210702402001418102490d00410020016b2108418002210903400240200920014f0d00200020096a2c000041bf7f4c0d0041002106200921070c020b2009417f6a21074100210620094101460d01200820096a210a20072109200a4101470d000b0b200520073602142005200036021020054100410520061b36021c200541b0b4cc0041e089c00020061b3602180240024002400240200220014b22090d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200520023602202002450d0220022001460d02200141016a210a03400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210920024101460d04200a2002462107200921022007450d000c040b0b20052002200320091b360228200541306a41146a4103360200200541c8006a41146a4104360200200541d4006a410436020020054203370234200541e889c0003602302005410136024c2005200541c8006a3602402005200541186a3602582005200541106a3602502005200541286a360248200541306a2004104c000b200541e4006a4104360200200541c8006a41146a4104360200200541d4006a4101360200200541306a41146a410436020020054204370234200541808ac0003602302005410136024c2005200541c8006a3602402005200541186a3602602005200541106a36025820052005410c6a3602502005200541086a360248200541306a2004104c000b200221090b024020092001460d00410121070240024002400240200020096a220a2c00002202417f4a0d0041002106200020016a220721010240200a41016a2007460d00200a41026a2101200a2d0001413f7121060b2002411f71210a200241ff017141df014b0d012006200a4106747221010c020b2005200241ff0171360224200541286a21020c020b4100210020072108024020012007460d00200141016a210820012d0000413f7121000b200020064106747221010240200241ff017141f0014f0d002001200a410c747221010c010b41002102024020082007460d0020082d0000413f7121020b2001410674200a411274418080f00071722002722201418080c400460d020b2005200136022441012107200541286a21022001418001490d00410221072001418010490d0041034104200141808004491b21070b200520093602282005200720096a36022c200541306a41146a4105360200200541ec006a4104360200200541e4006a4104360200200541c8006a41146a4106360200200541d4006a410736020020054205370234200541a08ac000360230200520023602582005410136024c2005200541c8006a3602402005200541186a3602682005200541106a3602602005200541246a3602502005200541206a360248200541306a2004104c000b41958dcc00412b2004103f000b1000200120002802002000280204105a0b800101037f230041206b22022400024002402000280200200110610d002001411c6a2802002103200128021821042002411c6a4100360200200241b0b4cc003602182002420137020c200241888bc00036020820042003200241086a1043450d010b200241206a240041010f0b2000280204200110612101200241206a240020010bdd0502047f017e410121020240200128021841272001411c6a2802002802101101000d0041022103024002400240024002402000280200220041776a2204411e4d0d00200041dc00470d010c020b41f40021050240024020040e1f05010202000202020202020202020202020202020202020202030202020203050b41f20021050c040b41ee0021050c030b0240024002402000105f0d00024002400240200041808004490d00200041808008490d0120004190fc476a4190fc0b490d02200041b5d9736a41b5db2b490d02200041e28b746a41e20b490d022000419fa8746a419f18490d02200041dee2746a410e490d02200041feffff0071419ef00a460d02200041a2b2756a4122490d02200041cb91756a410a4b0d050c020b200041f08bc000412941c28cc00041a20241e48ec00041b5021060450d010c040b2000419991c000412641e591c00041af01419493c00041a30310600d030b200041017267410276410773ad4280808080d0008421060c010b200041017267410276410773ad4280808080d0008421060b410321030c020b410121030c010b0b200021050b03402003210441dc002100410121024101210302400240024002400240024020040e0402010500020b02400240024002402006422088a741ff01710e06050302010006050b200642ffffffff8f608342808080803084210641f50021000c060b200642ffffffff8f608342808080802084210641fb0021000c050b20052006a72204410274411c7176410f712203413072200341d7006a2003410a491b210002402004450d002006427f7c42ffffffff0f832006428080808070838421060c050b200642ffffffff8f60834280808080108421060c040b200642ffffffff8f6083210641fd0021000c030b41002103200521000c030b20012802184127200128021c2802101101000f0b200642ffffffff8f60834280808080c0008421060b410321030b20012802182000200128021c280210110100450d000b0b20020b9d0301057f0240024002404100410f200041a49a04491b2201200141086a2201200141027441f896c0006a280200410b742000410b7422014b1b2202200241046a2202200241027441f896c0006a280200410b7420014b1b2202200241026a2202200241027441f896c0006a280200410b7420014b1b2202200241016a2202200241027441f896c0006a280200410b7420014b1b220241027441f896c0006a280200410b74220320014620032001496a20026a2201411e4b0d002001410274210241b105210302402001411e460d00200241fc96c0006a2204450d00200428020041157621030b4100210402402001417f6a220520014b0d002005411f4f0d03200541027441f896c0006a28020041ffffff007121040b02402003200241f896c0006a280200411576220141016a460d00200020046b21022003417f6a2103410021000340200141b0054b0d0320002001418498c0006a2d00006a220020024b0d012003200141016a2201470d000b0b20014101710f0b2001411f41b89dc0001042000b200141b10541c89dc0001042000b2005411f41f497c0001042000bea0201067f200120024101746a210720004180fe0371410876210841002109200041ff0171210a0240024002400340200141026a210b200920012d000122026a210c024020012d000022012008460d00200120084b0d03200c2109200b2101200b2007470d010c030b0240200c2009490d00200c20044b0d02200320096a2101024003402002450d012002417f6a210220012d00002109200141016a21012009200a470d000b410021020c050b200c2109200b2101200b2007470d010c030b0b2009200c41b896c0001059000b200c200441b896c0001058000b200041ffff03712109200520066a210c4101210202400340200541016a210a0240024020052d00002201411874411875220b4100480d00200a21050c010b200a200c460d02200b41ff007141087420052d0001722101200541026a21050b200920016b22094100480d02200241017321022005200c470d000c020b0b41958dcc00412b41c896c000103f000b20024101710bab0201037f23004180016b2202240002400240024002400240200128020022034110710d0020034120710d012000ad41012001105221000c020b410021030340200220036a41ff006a2000410f712204413072200441d7006a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141d88bc0004102200220036a4180016a410020036b105621000c010b410021030340200220036a41ff006a2000410f712204413072200441376a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141d88bc0004102200220036a4180016a410020036b105621000b20024180016a240020000f0b200041800141c88bc0001059000b200041800141c88bc0001059000b1c00200128021841c99ec000410b2001411c6a28020028020c1100000b1c00200128021841d49ec000410e2001411c6a28020028020c1100000b5b01017f230041306b220324002003200136020c20032000360208200341246a41013602002003420137021420034188b2cc003602102003410436022c2003200341286a3602202003200341086a360228200341106a2002104c000b140020002802002001200028020428020c1101000b15002001200028020022002802002000280204105a0bb10401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d00200028020041a69fc0004104200028020428020c1100000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a200120021068024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d0420092005200610a008450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b10682003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1100000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b2006410441ac9fc0001058000b200120024100200441bc9fc000105b000b200120022004200241d089c000105b000b410121040b200341306a240020040bf80201067f410021040240024020024103712205450d00410420056b2205450d0020032005200520034b1b210441002105200141ff01712106034020042005460d01200220056a2107200541016a210520072d000022072006470d000b410121032007200141ff01714641016a41017120056a417f6a21050c010b200141ff017121060240024020034108490d002004200341786a22084b0d00200641818284086c210502400340200220046a220741046a2802002005732209417f73200941fffdfb776a7120072802002005732207417f73200741fffdfb776a7172418081828478710d01200441086a220420084d0d000b0b200420034b0d010b200220046a2109200320046b210241002103410021050240034020022005460d01200920056a2107200541016a210520072d000022072006470d000b410121032007200141ff01714641016a41017120056a417f6a21050b200520046a21050c010b2004200341e89fc0001059000b20002005360204200020033602000bbb0302047f027e230041c0006b2205240041012106024020002d00040d0020002d000521070240200028020022082d00004104710d004101210620082802184196a0c0004193a0c000200741ff017122071b4102410320071b2008411c6a28020028020c1100000d014101210620002802002208280218200120022008411c6a28020028020c1100000d01410121062000280200220828021841dc92c80041022008411c6a28020028020c1100000d0120032000280200200428020c11010021060c010b0240200741ff01710d004101210620082802184198a0c00041032008411c6a28020028020c1100000d01200028020021080b41012106200541013a0017200541346a419ca0c000360200200520082902183703082005200541176a360210200829020821092008290210210a200520082d00203a00382005200a37032820052009370320200520082902003703182005200541086a360230200541086a2001200210670d00200541086a41dc92c800410210670d002003200541186a200428020c1101000d00200528023041b4a0c0004102200528023428020c11000021060b200041013a0005200020063a0004200541c0006a240020000b8b0201027f230041106b220224002002410036020c02400240024002402001418001490d002001418010490d012002410c6a21032001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c2002410c6a2103410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c2002410c6a2103410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b20002003200110672101200241106a240020010b6001017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41b8a0c000200241086a10432101200241206a240020010b0d0020002802002001200210670b0b0020002802002001106a0b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41b8a0c000200241086a10432101200241206a240020010bd30202047f027e230041c0006b2203240041012104024020002d00080d00200028020421050240200028020022062d00004104710d004101210420062802184196a0c00041d3a0c00020051b4102410120051b2006411c6a28020028020c1100000d0120012000280200200228020c11010021040c010b024020050d0041012104200628021841d4a0c00041022006411c6a28020028020c1100000d01200028020021060b41012104200341013a0017200341346a419ca0c000360200200320062902183703082003200341176a3602102006290208210720062902102108200320062d00203a00382003200837032820032007370320200320062902003703182003200341086a3602302001200341186a200228020c1101000d00200328023041b4a0c0004102200328023428020c11000021040b200020043a00082000200028020441016a360204200341c0006a240020000bd40202037f027e230041c0006b2203240041012104024020002d00040d0020002d000521040240200028020022052d00004104710d000240200441ff0171450d004101210420052802184196a0c00041022005411c6a28020028020c1100000d02200028020021050b20012005200228020c11010021040c010b0240200441ff01710d0041012104200528021841d7a0c00041012005411c6a28020028020c1100000d01200028020021050b41012104200341013a0017200341346a419ca0c000360200200320052902183703082003200341176a3602102005290208210620052902102107200320052d00203a00382003200737032820032006370320200320052902003703182003200341086a3602302001200341186a200228020c1101000d00200328023041b4a0c0004102200328023428020c11000021040b200041013a0005200020043a0004200341c0006a240020000b6401027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a10432100200241206a240020000bd70a020c7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101101000d000240024020010d00410021050c010b200020016a21064100210520002107410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210c0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210c0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220c418080c400470d020c040b200b41ff0171210c0b200a21070b4102210a024002400240024002400240200c41776a220b411e4d0d00200c41dc00470d010c020b41f400210e02400240200b0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b0240200c105f0d0002400240200c41808004490d00200c41808008490d01200c4190fc476a4190fc0b490d02200c41b5d9736a41b5db2b490d02200c41e28b746a41e20b490d02200c419fa8746a419f18490d02200c41dee2746a410e490d02200c41feffff0071419ef00a460d02200c41a2b2756a4122490d02200c41cb91756a410a4d0d020c060b200c41f08bc000412941c28cc00041a20241e48ec00041b5021060450d010c050b200c419991c000412641e591c00041af01419493c00041a30310600d040b200c41017267410276410773ad4280808080d00084210f4103210a0c010b0b200c210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110000450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a1073000b0340200a210b4101210441dc0021054101210a024002400240024002400240200b0e0402010500020b0240024002400240200f422088a741ff01710e06050302010006050b200f42ffffffff8f608342808080803084210f4103210a41f50021050c070b200f42ffffffff8f608342808080802084210f4103210a41fb0021050c060b200e200fa7220b410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200b450d00200f427f7c42ffffffff0f83200f4280808080708384210f0c050b200f42ffffffff8f608342808080801084210f0c040b200f42ffffffff8f6083210f4103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200c418001490d004102210a200c418010490d0041034104200c41808004491b210a0b200a20086a21050c040b200f42ffffffff8f60834280808080c00084210f0b4103210a0b20022802182005200228021c280210110100450d000c050b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1100000d0020022802184122200228021c28021011010021040b200341206a240020040f0b200020012005200141d089c000105b000b2b01017f2000280200220128020020012802042000280204280200200028020828020041dca0c000105b000bee0704057f017e017f017e02400240024002402002450d00410020016b410020014103711b2103200241796a4100200241074b1b210441002105034002400240200120056a2d000022064118744118752207417f4a0d004280808080802021080240200641c884c0006a2d0000417e6a220941024d0d00428080808010210a0c070b0240024002400240024020090e03000102000b200541016a22062002490d024200210a0c090b4200210a200541016a220920024f0d08200120096a2d0000210902400240200641a07e6a2206410d4b0d000240024020060e0e0002020202020202020202020201000b200941e0017141a001460d02428080808010210a0c0c0b02402009411874411875417f4c0d00428080808010210a0c0c0b200941ff017141a001490d01428080808010210a0c0b0b02402007411f6a41ff0171410b4b0d0002402009411874411875417f4c0d00428080808010210a0c0c0b200941ff017141c001490d01428080808010210a0c0b0b0240200941ff017141bf014d0d00428080808010210a0c0b0b0240200741fe017141ee01460d00428080808010210a0c0b0b2009411874411875417f4c0d00428080808010210a0c0a0b42002108200541026a220620024f0d09200120066a2d000041c00171418001460d020c070b4200210a200541016a220920024f0d07200120096a2d0000210902400240200641907e6a220641044b0d000240024020060e050002020201000b200941f0006a41ff01714130490d02428080808010210a0c0b0b02402009411874411875417f4c0d00428080808010210a0c0b0b200941ff0171419001490d01428080808010210a0c0a0b0240200941ff017141bf014d0d00428080808010210a0c0a0b02402007410f6a41ff017141024d0d00428080808010210a0c0a0b2009411874411875417f4c0d00428080808010210a0c090b200541026a220620024f0d07200120066a2d000041c00171418001470d0642002108200541036a220620024f0d08200120066a2d000041c00171418001460d01428080808080e0002108428080808010210a0c080b428080808010210a200120066a2d000041c00171418001470d070b200641016a21050c010b0240200320056b4103710d000240200520044f0d000340200120056a220641046a280200200628020072418081828478710d01200541086a22052004490d000b0b200520024f0d010340200120056a2c00004100480d022002200541016a2205470d000c040b0b200541016a21050b20052002490d000b0b20002001360204200041086a2002360200200041003602000f0b428080808080c0002108428080808010210a0c010b420021080b2000200a2005ad84200884370204200041013602000b1c0020012802184190b2cc0041052001411c6a28020028020c1100000bb30101037f200028020421020240024020002802004101470d002000410c6a28020022002001107720004103742200450d01200220006a2103034020022802002100200241046a2802002204200110772001200020041078200241086a22022003470d000c020b0b200041086a28020022002001107720004103742200450d00200220006a2103034020022802002100200241046a2802002204200110772001200020041078200241086a22022003470d000b0b0bab0101017f230041106b220224000240024002400240200041c000490d00200041808001490d012000418080808004490d02200241033a00032001200241036a41011078200220003602042001200241046a410410780c030b200220004102743a00032001200241036a410110780c020b200220004102744101723b010a20012002410a6a410210780c010b2002200041027441027236020c20012002410c6a410410780b200241106a24000bcd0101047f0240024002400240200041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422062005200620054b1b22064100480d010240024020030d00024020060d00410121050c020b2006103322050d010c040b2000280200210520032006460d0020052003200610372205450d03200041086a28020021040b20002005360200200041046a20063602000b200520046a20012002109d081a200041086a200420026a3602000f0b103e000b103c000bff0101037f200028020421020240024020002802004101470d002000410c6a2802002200200110772000450d01200041186c2103200241146a21000340200041706a2802002102200041746a28020022042001107720012002200410782000417c6a280200210220002802002204200110772001200220041078200041186a2100200341686a22030d000c020b0b200041086a2802002200200110772000450d00200041186c2103200241146a21000340200041706a2802002102200041746a28020022042001107720012002200410782000417c6a280200210220002802002204200110772001200220041078200041186a2100200341686a22030d000b0b0ba90701057f230041206b2203240020012002107702402001450d00200141d8006c2104410021050340200020056a220141046a2802002106200141086a28020022072002107720022006200710782003200141d4006a2d00003a000d20022003410d6a4101107802402001410c6a2d0000220641024b0d0002400240024020060e03000102000b200341003a000e20022003410e6a41011078200141146a2802002106200141186a28020022072002107720022006200710780c020b200341013a000e20022003410e6a4101107802402001410d6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110780b200141146a2802002106200141186a2802002207200210772002200620071078200141206a2802002106200141246a280200220720021077200220062007107820032001410e6a2d00003a000e20022003410e6a410110780c010b200341023a000e20022003410e6a4101107802402001410d6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110780b200141146a2802002106200141186a2802002207200210772002200620071078200141206a2802002106200141246a28020022072002107720022006200710782001412c6a2802002106200141306a28020022072002107720022006200710782001410e6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110780b02400240200141346a2802004101470d00200141386a2802002106200141c0006a28020022072002107720022006200710780c010b200341106a200141386a2802002001413c6a28020028020c11020020032802102106200328021822072002107720022006200710782003280214450d00200610350b200141c4006a200210762004200541d8006a2205470d000b0b200341206a24000b8605010e7f2001410c6a2802002102200128020821032001280204210402400240024002400240024002400240200128020022050d0020030d010c060b200420056b2101024020030d00200121060c020b2001200220036b6a220620014f0d010240024020042005460d00200541016a21070c010b20022003460d064100210720032105200341016a21030b4100210841002106410121090340200420076b210a2008410174210b20022003220c6b210d410021010340200720016a210e20052d000021030240200820016a22052006470d002005417f417f2004200e6b2206200d6a220f200f2006491b200d200e1b220641016a220f200f2006491b6a22062005490d06200b2006200b20064b1b22064100480d06024020050d00024020060d00410121090c020b2006103322090d010c080b20052006460d0020092005200610372209450d070b200920086a20016a20033a00000240200e450d00200a2001460d00200b41026a210b200141016a2101200e21050c010b0b200c2002460d03200541016a2108200c41016a210341002107200c21050c000b0b200220036b21060b0240024020060d00410121090c010b20064100480d02200610332209450d030b4100210b0240024020050d00200921010c010b024020042005470d00200921010c010b200921012005210e03402001200e2d00003a0000200141016a21012004200e41016a220e470d000b200420056b210b0b2003450d0420022003460d042003210e03402001200e2d00003a0000200141016a21012002200e41016a220e470d000b2002200b20036b6a210b0c040b200541016a210b0c030b103e000b103c000b410121094100210b410021060b2000200b36020820002006360204200020093602000bd40101037f02400240024002402000280200220041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004103322050d010c040b2000280200210520032004460d0020052003200410372205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a20012002109d081a200041086a200420026a36020041000f0b103e000b103c000bbf0301047f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b0240024002400240200041046a2802002203200041086a28020022046b2001490d00200028020021050c010b200420016a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004103322050d010c040b2000280200210520032004460d0020052003200410372205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a2002410c6a2001109d081a200041086a200420016a360200200241106a240041000f0b103e000b103c000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41e4a1c000200241086a10432101200241206a240020010bcd0101037f0240024002400240200041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004103322050d010c040b2000280200210520032004460d0020052003200410372205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a20012002109d081a200041086a200420026a3602000f0b103e000b103c000b040041010bb60101017f230041c0006b2202240020024100360210200242013703082002410836021c20022001410c6a3602202002200241206a3602182002200241086a3602242002413c6a41013602002002420137022c20024188b2cc003602282002200241186a360238200241246a41e4a1c000200241286a10431a20012d0000417f6a41ff0171200141046a290200200235021042208620023502088410000240200228020c450d00200228020810350b200241c0006a24000b6901037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a10432101200241206a240020010b040041000b02000b02000bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff03712001470d00200141027422014100480d00024020030d0020010d02410421020c040b20002802002102200341027422032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014102763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad420c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003410c6c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a2001410c6e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42307e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341306c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141306e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42307e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341306c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141306e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410121020c040b20002802002102200341057422032001460d03024020030d0020010d02410121020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014105763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42387e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341386c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141386e3602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff00712001470d00200141047422014100480d00024020030d0020010d02410421020c040b20002802002102200341047422032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014104763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42247e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341246c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141246e3602000b0bb40101027f0240200041046a280200220320016b20024f0d000240024002400240200120026a22042001490d00200341017422022004200220044b1b220420046a22012004490d0020014100480d00024020030d0020010d02410221030c040b2000280200210320022001460d03024020020d0020010d02410221030c040b20032002200110372203450d020c030b103e000b2001103322030d010b103c000b20002003360200200041046a20014101763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42287e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341286c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141286e3602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff01712001470d00200141037422014100480d00024020030d0020010d02410421020c040b20002802002102200341037422032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014103763602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410421020c040b20002802002102200341057422032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014105763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42b0027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341b0026c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141b0026e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42f0007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341f0006c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141f0006e3602000b0bba0101027f0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1b220241ffffff1f712002470d00200241067422024100480d00024020010d0020020d02410821030c040b20002802002103200141067422012002460d03024020010d0020020d02410821030c040b20032001200210372203450d020c030b103e000b2002103322030d010b103c000b20002003360200200041046a20024106763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d8027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d8026c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141d8026e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42e8007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341e8006c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141e8006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42187e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341186c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141186e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad422c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003412c6c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a2001412c6e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42147e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341146c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141146e3602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff00712001470d00200141047422014100480d00024020030d0020010d02410821020c040b20002802002102200341047422032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014104763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d8007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d8006c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141d8006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42187e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341186c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141186e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42287e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341286c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141286e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42227e2204422088a70d002004a722014100480d00024020030d0020010d02410221020c040b20002802002102200341226c22032001460d03024020030d0020010d02410221020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141226e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c4007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341c4006c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141c4006e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42a0017e2204422088a70d002004a722014100480d00024020030d0020010d02410121020c040b20002802002102200341a0016c22032001460d03024020030d0020010d02410121020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141a0016e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410821020c040b20002802002102200341057422032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014105763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42387e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341386c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141386e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d0007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d0006c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141d0006e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42e0007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341e0006c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141e0006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42347e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341346c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141346e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff1f712001470d00200141067422014100480d00024020030d0020010d02410421020c040b20002802002102200341067422032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014106763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d0027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d0026c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141d0026e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c8007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341c8006c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141c8006e3602000b0bbc0102027f017e0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1bad42c8037e2204422088a70d002004a722024100480d00024020010d0020020d02410821030c040b20002802002103200141c8036c22012002460d03024020010d0020020d02410821030c040b20032001200210372203450d020c030b103e000b2002103322030d010b103c000b20002003360200200041046a200241c8036e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad423c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003413c6c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a2001413c6e3602000b0b800b04047f017e127f037e230041d0036b22012400200141f0006a41186a4200370300200141f0006a41106a22024200370300200141f0006a41086a220342003703002001420037037041f7edcb00ad4280808080f000841001220429000021052003200441086a290000370300200120053703702004103541eeedcb00ad4280808080900184100122042900002105200141206a41086a2206200441086a2900003703002001200537032020041035200220012903202205370300200141c0006a41086a22042003290300370300200141c0006a41106a2005370300200141c0006a41186a200629030037030020012001290370370340200141f0006a200141c0006a10ac0102400240024020012903704202510d002000280208210320002802042107200028020021082001200228020010ad01200141f0006a200128020022092001280208220a10ae012004200141f0006a410c6a290200370300200120012902743703400240024020012802704101460d00200141106a410c6a4100360200200142003703100c010b200141106a41086a200141c0006a41086a290300370300200120012903403703100b02402003450d002008200341246c6a210b20014184016a210c2001411c6a210d200141106a410472210e200141e8006a210f200141c0006a41206a211020082111034020112802202112200141206a41186a2213201141186a290000370300200141206a41106a2214201141106a290000370300200141206a41086a2215201141086a290000370300200120112900003703200240024020012802142206450d00200128021821160c010b200141f0006a410041e002109f081a200f410036020020104200370300200141c0006a41186a22004200370300200141c0006a41106a22034200370300200141c0006a41086a220442003703002001420037034041940310332206450d0541002116200641003b010620064100360200200641086a200141f0006a41e002109d081a20064190036a200f28020036020020064188036a201029030037020020064180036a2000290300370200200641f8026a2003290300370200200641f0026a2004290300370200200620012903403702e80220014100360218200120063602140b201141246a2111024002400340200641086a210320062f01062217410574210041002104024003402000450d01200141206a2003412010a0082202450d03200041606a2100200441016a2104200341206a21032002417f4a0d000b2004417f6a21170b02402016450d002016417f6a2116200620174102746a4194036a28020021060c010b0b200141c0006a41186a20132903002205370300200141c0006a41106a20142903002218370300200141c0006a41086a2015290300221937030020012001290320221a370340200c201a370200200c41086a2019370200200c41106a2018370200200c41186a20053702002001200d360280012001201736027c2001200e3602782001200636027420014100360270200141f0006a410010af0121000c010b200620044102746a41e8026a21000b2000200028020020126a3602002001200128021020126a3602102011200b470d000b0b02402007450d00200741246c450d00200810350b200141fc006a200141106a41086a290300370200200120012903102205370274200141013602702001410036024820014201370340410410332200450d0220002005a73600002001200036024020014284808080c000370244200141f0006a41086a2200200141c0006a10b00120012802442103200aad4220862009ad84200135024842208620012802402204ad84100202402003450d00200410350b200010b1012001280204450d01200910350c010b200041046a2802002203450d00200341246c450d00200028020010350b200141d0036a24000f0b103c000bd60202057f027e230041d0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822010d00200042023703000c010b200228020c210302400240200241106a28020022044104490d0020044104460d0020012d0004220541014b0d0020012800002106420021070240024020050e020100010b2004417b6a4108490d0120012900052108420121070b20002008370308200041106a20063602000c010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b420221070b200020073703002003450d00200110350b200241d0006a24000bfc0403027f017e057f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541ccb5c000ad4280808080800284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bcd0b030e7f047e087f230041a0046b220324002003200236021420032001360210200341186a2002ad4220862001ad84100510c20102400240200328021822040d00200041003602000c010b200328021c21052003200341206a280200220136022c2003200436022802400240024020014104490d0020032001417c6a36022c2003200441046a36022820042800002106200341086a200341286a10c40120032802080d00200328020c21072003410036024820034100360240200341c0006a41086a210802400240024002402007450d00200341d4016a2109200328022c210a200341b8016a210b4100210c034041002101200341003a00e001200c41016a210c024002400340200a2001460d01200341c0016a20016a2003280228220d2d00003a00002003200d41016a3602282003200141016a22023a00e0012002210120024120470d000b20034190016a41086a220e200341c0016a41086a29030037030020034190016a41106a220f200341c0016a41106a29030037030020034190016a41186a2210200341c0016a41186a290300370300200320032903c001370390012003200a20026b220136022c200141044f0d010c050b2003410036022c200141ff0171450d04200341003a00e001410021010c050b200341d0006a41086a200e2903002211370300200341d0006a41106a200f2903002212370300200341d0006a41186a20102903002213370300200320032903900122143703502003200d41056a36022820032001417c6a220a36022c200d2800012115200341f0006a41186a22162013370300200341f0006a41106a22172012370300200341f0006a41086a22182011370300200320143703700240024020032802402219450d002003280244211a0c010b200341c0016a410041e002109f081a200b410036020020034190016a41206a2201420037030020104200370300200f4200370300200e4200370300200342003703900141940310332219450d034100211a201941003b010620194100360200201941086a200341c0016a41e002109d081a20194190036a200b28020036020020194188036a200129030037020020194180036a2010290300370200201941f8026a200f290300370200201941f0026a200e29030037020020192003290390013702e80220034100360244200320193602400b024002400340201941086a210220192f0106221b41057421014100210d024003402001450d01200341f0006a2002412010a008221c450d03200141606a2101200d41016a210d200241206a2102201c417f4a0d000b200d417f6a211b0b0240201a450d00201a417f6a211a2019201b4102746a4194036a28020021190c010b0b201020162903002211370300200f20172903002212370300200e201829030022133703002003200329037022143703900120092014370200200941086a2013370200200941106a2012370200200941186a2011370200200320083602d0012003201b3602cc01200320193602c401200341003602c0012003200341c0006a3602c801200341c0016a201510af011a0c010b2019200d4102746a41e8026a20153602000b200c2007470d000b0b410121010c020b103c000b410021010b200341306a41086a20082802002202360200200320032903402211370330200341c0016a41086a2002360200200320113703c00120010d01200341c0016a10b1010b4100210120034100360298012003420137039001200341093602742003200341106a360270200320034190016a360250200341d4016a4101360200200342013702c401200341c888c2003602c0012003200341f0006a3602d001200341d0006a41e88ac500200341c0016a10431a200335029801422086200335029001841006200328029401450d0120032802900110350c010b20034190016a41086a200341c0016a41086a2802002201360200200320032903c00122113703900120002006360204200041086a2011370200200041106a2001360200410121010b200020013602002005450d00200410350b200341a0046a24000bed0701087f23004190046b2202240020002802102203200328020041016a360200200241086a2203200041086a29020037030020022000290200370300200241306a41186a2000412c6a290000370300200241306a41106a200041246a290000370300200241306a41086a2000411c6a29000037030020022000290014370330200241d0006a2002200241306a200110fe0202400240024020022d00504101470d002003200241d9006a290000370300200241106a200241e1006a290000370300200241186a200241e9006a29000037030020022002290051370300200241d0006a412c6a280200210120024188016a280200210420024184016a280200210320024180016a2802002105200228028c012106200241f8006a28020022002802002207450d0120002f01042108200241f4006a2802002109200241d0006a410172210003402002200841ffff037136022c20022001360228200220073602242002200941016a360220200241306a41186a200241186a2201290300370300200241306a41106a200241106a2207290300370300200241306a41086a200241086a220829030037030020022002290300370330200241d0006a200241206a200241306a20052003200410ff0220022d00504101470d032008200041086a2900003703002007200041106a2900003703002001200041186a29000037030020022000290000370300200228027c2101200228028801210420022802840121032002280280012105200228027822082802002207450d0220082f01042108200228027421090c000b0b200241d0006a41086a280200200241d0006a41106a2802004102746a41e8026a21060c010b200241d0006a410272410041be03109f081a02400240024041c40310332200450d0020004100360200200041046a200241d0006a41c003109d081a200020012802002207360294032001200036020020012001280204220841016a360204200741003b010420072000360200200241d0006a41186a200241186a290300370300200241d0006a41106a200241106a290300370300200241d0006a41086a200241086a2903003703002002200229030037035020082004470d0120002f01062201410a4b0d02200020014105746a220441206a200241d0006a41186a290300370000200441186a200241d0006a41106a290300370000200441106a200241d0006a41086a290300370000200441086a2002290350370000200020014102746a41e8026a20053602002000200141016a22014102746a4194036a2003360200200020013b0106200320013b0104200320003602000c030b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b20024190046a240020060bef0403057f027e027f230041c0006b22022400200041086a28020022032001107702400240024020002802002204450d00024020002802042205450d002005210020042106034020062802940321062000417f6a22000d000b200421000340200020002f01064102746a4194036a28020021002005417f6a22050d000b200241186a2105200621040c020b200241186a2105200421000c010b410021042002410036021c200241186a21050c010b2002200036021c200241246a20002f010636020020024100360220200241003602180b200241086a41086a200541086a2902002207370300200220052902002208370308200241306a2007370300200242003703202002200436021c20024100360218200220083703282002200336023802402003450d00034020022003417f6a360238200241186a410020041b2206280200210020062802082109024002400240200628020c2205200628020422032f01064f0d00200321040c010b0240034020032802002204450d01200041016a210020032f0104210520042103200520042f0106490d020c000b0b2009ad2107410021040c010b2005ad4220862009ad8421070b2007422088a7220941016a21052007a7210a0240024020000d00200421030c010b200420054102746a4194036a2802002103410021052000417f6a2200450d00034020032802940321032000417f6a22000d000b0b2006200536020c2006200a36020820062003360204200641003602002001200420094105746a41086a412010782002200420094102746a41e8026a28020036023c20012002413c6a4104107820022802382203450d01200228021c21040c000b0b200241c0006a24000bb50201047f024020002802002201450d0020002802082102024020002802042200450d00034020012802940321012000417f6a22000d000b0b02402002450d004100210303400240024002402001450d002002417f6a2102200320012f0106490d0141002104034002400240200128020022000d0041002103410021000c010b200441016a210420012f010421030b2001103520002101200320002f01064f0d000b200341016a2103024020040d00200021010c030b200020034102746a4194036a2802002101410021032004417f6a2200450d02034020012802940321012000417f6a22000d000c030b0b41958dcc00412b41c08dcc00103f000b200341016a21030b20020d000b0b2001450d0020012802002100200110352000450d00034020002802002101200010352001210020010d000b0b0ba20703027f017e067f230041e0006b2203240041f7edcb00ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541d6a9c000ad4280808080b00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b0240024002400240412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2007109d081a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420066a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000ba20703027f017e067f230041e0006b2203240041f7edcb00ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541e9a9c000ad4280808080b00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b0240024002400240412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2007109d081a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420066a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541c0a9c000ad4280808080e00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541f393ca00ad4280808080a00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bda0503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a29000037030020022004370308200310354189aac000ad4280808080900184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240410410332203450d0020034104412010372203450d0320032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200128022021052003412041c00010372201450d032001200536002020022001ad4280808080c004841003220329000037033820031035200241cc006a200141246a360200200220013602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200110352002280230220641206a2203417f4c0d01200228022821070240024020030d0041002105410121010c010b200310332201450d01200321050b024002402005410f4d0d00200521080c010b200541017422084110200841104b1b22084100480d03024020050d002008103322010d010c050b20052008460d0020012005200810372201450d040b20012002290308370000200141086a200241086a41086a2903003700000240024020084170714110460d00200821050c010b200841017422054120200541204b1b22054100480d0320082005460d0020012008200510372201450d040b20012002290318370010200141186a200241186a41086a29030037000002400240200541606a2006490d00200521080c010b2006415f4b0d03200541017422082003200820034b1b22084100480d0320052008460d0020012005200810372201450d040b200141206a20072006109d081a2000200336020820002008360204200020013602000240200228022c450d00200710350b200241d0006a24000f0b1045000b1044000b103e000b103c000bc20503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a200341086a290000370300200220043703002003103541c6a9c000ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bfc0403027f017e057f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541feedcb00ad4280808080d00284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bb10503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541cca9c000ad4280808080a00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541fca9c000ad4280808080d00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b890603027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241186a41086a200341086a290000370300200220043703182003103541fca9c000ad4280808080d00184100122032900002104200241286a41086a200341086a2900003703002002200437032820031035200128020021010240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad428080808080048410032201290000370348200110352002410c6a200341206a360200200220033602082002200241c8006a41086a3602042002200241c8006a360200200241386a2002107b200310352002280240220541206a2201417f4c0d01200228023821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290318370000200341086a200241186a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290328370010200341186a200241286a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a0240200228023c450d00200610350b20022003200110bc01200241286a41086a2207200241086a280200360200200220022903003703280240200228020c2201450d002000200229032837020020002002290310370210200041086a20072802003602000b2000200136020c02402008450d00200310350b200241d0006a24000f0b1045000b1044000b103e000b103c000ba20503067f017e027f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d002000410036020c0c010b200328021421042003200341186a2802002202360224200320013602200240024020024104490d002003200141046a36022020032002417c6a220536022420054104490d00200128000021062003200141086a3602202003200241786a220536022420054104490d00200128000421052003200241746a36022420032001410c6a360220200128000821072003200341206a10c40120032802000d002003280224220820032802044102742202490d0002400240024002402002417f4c0d000240024020020d00420021094101210a0c010b20021039220a450d02200a2003280220220b2002109d081a2003200820026b3602242003200b20026a3602202002ad21090b200a450d04024020092002ad422086842209422088a722020d002009a721020c030b0240200a2002724103710d002009a722024103710d0020024102762208450d032009422288a7210b0c040b2009a7450d04200a10350c040b1044000b1045000b4100210b02402002450d00200a10350b410021084104210a0b41000d00200a450d00200020083602102000200a36020c200020073602082000200536020420002006360200200041146a200b3602000c010b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b2000410036020c0b2004450d00200110350b200341e0006a24000bfc0403027f017e057f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541efb5c000ad4280808080e00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bfc0403027f017e057f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541dcb5c000ad4280808080b00284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000b9b540f047f017e017f017e027f017e067f027e017f017e037f017e087f047e047f230041c0046b22022400200241d0006a41186a22034200370300200241d0006a41106a22044200370300200241d0006a41086a220542003703002002420037035041f7edcb00ad4280808080f000842206100122072900002108200241e0026a41086a2209200741086a290000370300200220083703e0022007103520052009290300370300200220022903e00237035041e4edcb00ad4280808080a0018422081001220a290000210b200241b0036a41086a2207200a41086a2900003703002002200b3703b003200a1035200420022903b003220b37030020024190046a41086a220c200529030037030020024190046a41106a220d200b37030020024190046a41186a220e20072903003703002002200229035037039004200241286a20024190046a412010c0012002280228210f200228022c21102003420037030020044200370300200542003703002002420037035020061001220a290000210b2009200a41086a2900003703002002200b3703e002200a103520052009290300370300200220022903e00237035020081001220a29000021082007200a41086a290000370300200220083703b003200a1035200420022903b0032208370300200c2005290300370300200d2008370300200e20072903003703002002200229035037039004410121054100210a2002201041016a4100200f1b221136025020024190046aad42808080808004842212200241d0006aad22134280808080c00084100220061001220329000021062009200341086a290000370300200220063703e0022003103541feedcb00ad4280808080d002841001220929000021062007200941086a290000370300200220063703b00320091035200220113602f0032002200241f0036aad4280808080c00084100322092900003703900420091035200241dc006a200241f4036a3602002002200c3602542002200241f0036a360258200220024190046a36025020024190026a200241d0006a107b024002400240024002400240024002400240024002400240024002400240200228029802220341206a220c417f4c0d00200228029002210d0240200c450d00200c10332205450d07200c210a0b02400240200a410f4d0d00200a21070c010b200a41017422094110200941104b1b22074100480d0b0240200a0d002007103322050d010c100b200a2007460d002005200a200710372205450d0f0b200520022903e002370000200541086a200241e0026a41086a2903003700000240024020074170714110460d00200721090c010b200741017422094120200941204b1b22094100480d0b20072009460d0020052007200910372205450d0f0b200520022903b003370010200541186a200241b0036a41086a29030037000002400240200941606a2003490d00200921070c010b200341206a22072003490d0b2009410174220a2007200a20074b1b22074100480d0b20092007460d0020052009200710372205450d0f0b200541206a200d2003109d081a0240200228029402450d00200d10350b20022001360250200cad4220862005ad8420134280808080c00084100202402007450d00200510350b200241d0006a41186a220a4200370300200241d0006a41106a22144200370300200241d0006a41086a220542003703002002420037035041f7edcb00ad4280808080f000842206100122072900002108200241e0026a41086a2209200741086a290000370300200220083703e0022007103520052009290300370300200220022903e00237035041b5edcb00ad4280808080c001841001220c2900002108200241b0036a41086a2207200c41086a290000370300200220083703b003200c1035200420022903b003370000200441086a200729030037000020024190046a41086a200529030037030020024190046a41106a201429030037030020024190046a41186a200a2903003703002002200229035037039004200241206a20024190046a412010c00102402011200228022441016a41d50020022802201b6b220c20114b0d00200c10c1010b200a420037030020144200370300200542003703002002420037035020061001220a29000021062009200a41086a290000370300200220063703e002200a103520052009290300370300200220022903e00237035041b3b6c000ad4280808080d001841001220929000021062007200941086a290000370300200220063703b00320091035201420022903b0032206370300200241306a41086a2005290300370300200241306a41106a2006370300200241306a41186a200729030037030020022002290350370330200241203602d4012002200241306a3602d001200241d8016a200241306aad42808080808004842215100510c20120022802d8012216450d0520022802dc0121172002200241d8016a41086a2802003602ec01200220163602e801200241d0006a200241e8016a10c30120022802502218450d03200241d0006a41086a35020021192002280254211a200241186a200241e8016a10c40120022802180d01200228021c221b20022802ec01220741d0006e22052005201b4b1bad42d0007e2206422088a70d002006a72205417f4c0d000240024020050d004108211c0c010b20051033221c450d070b4100210a200241003602f8012002201c3602f0012002200541d0006e221d3602f4010240201b450d00200241b4046a211e200241d0006a41206a211f4100210a4100210c02400340200241003a00d003200c41016a210c41002105024002400240034020072005460d01200241b0036a20056a20022802e80122092d00003a00002002200941016a3602e8012002200541016a22093a00d0032009210520094120470d000b200241f0036a41086a2205200241b0036a41086a2203290300370300200241f0036a41106a220d200241b0036a41106a2201290300370300200241f0036a41186a220e200241b0036a41186a220f290300370300200220022903b0033703f0032002200720096b3602ec0120024190046a200241e8016a10c50120022802b00422090d01410021090c020b200241003602ec010240200541ff0171450d00200241003a00d0030b410021090c010b201f200229039004370300200241d0006a41186a2207200e290300370300200241d0006a41106a220e200d290300370300200241d0006a41086a220d2005290300370300201f41086a20024190046a41086a290300370300201f41106a20024190046a41106a290300370300201f41186a20024190046a41186a290300370300200241a0036a41086a201e41086a280200360200200220022903f0033703502002201e2902003703a003200241b0036a41386a200241d0006a41386a290300370300200241b0036a41306a200241d0006a41306a290300370300200241b0036a41286a200241d0006a41286a290300370300200241b0036a41206a201f290300370300200f20072903003703002001200e2903003703002003200d290300370300200220022903503703b0030b200241e0026a41386a2205200241b0036a41386a290300370300200241e0026a41306a2207200241b0036a41306a290300370300200241e0026a41286a2203200241b0036a41286a290300370300200241e0026a41206a220d200241b0036a41206a290300370300200241e0026a41186a2201200241b0036a41186a290300370300200241e0026a41106a220e200241b0036a41106a290300370300200241e0026a41086a220f200241b0036a41086a290300370300200241d0026a41086a2210200241a0036a41086a280200360200200220022903b0033703e002200220022903a0033703d00202402009450d0020024190026a41386a2220200529030037030020024190026a41306a2221200729030037030020024190026a41286a2207200329030037030020024190026a41206a2203200d29030037030020024190026a41186a220d200129030037030020024190026a41106a2201200e29030037030020024190026a41086a220e200f29030037030020024180026a41086a220f2010280200360200200220022903e00237039002200220022903d002370380020240200a20022802f401470d00200241f0016a200a410110a30120022802f001211c20022802f801210a0b201c200a41d0006c6a220520022903900237030020012903002106200d29030021082003290300210b200729030021222021290300212320202903002124200e290300212520052009360240200541086a20253703002005200229038002370244200541cc006a200f280200360200200541386a2024370300200541306a2023370300200541286a2022370300200541206a200b370300200541186a2008370300200541106a20063703002002200a41016a220a3602f801200c201b460d0220022802ec0121070c010b0b0240200a450d00200a41d0006c2109201c41c4006a21050340024020052802002207450d00200741306c450d002005417c6a28020010350b200541d0006a2105200941b07f6a22090d000b0b20022802f4012205450d03200541d0006c450d03201c10350c030b20022802f401211d0b201c450d010240024020022802ec012205450d0020022005417f6a3602ec01200220022802e801220541016a3602e80120052d000022264103490d010b0240200a450d00200a41d0006c2109201c41c4006a21050340024020052802002207450d00200741306c450d002005417c6a28020010350b200541d0006a2105200941b07f6a22090d000b0b0240201d450d00201d41d0006c450d00201c10350b201a41ffffff3f71450d040c030b2019422086201aad8421240c040b1044000b201a41ffffff3f71450d010b201810350b200241003602b803200242013703b003200241093602e4022002200241d0016a3602e0022002200241b0036a36029002200241e4006a410136020020024201370254200241c888c2003602502002200241e0026a36026020024190026a41e88ac500200241d0006a10431a20023502b80342208620023502b003841006024020022802b403450d0020022802b00310350b410321260b02402017450d00201610350b20264103460d00201510070c040b200241003602d802200242083703d002200241003602a803200242013703a00341f7edcb00ad4280808080f00084100122052900002106200241e0026a41086a2209200541086a290000370300200220063703e0022005103541f393ca00ad4280808080a00184100122052900002106200241b0036a41086a2207200541086a290000370300200220063703b00320051035412010332205450d00200520022903e002370000200520022903b003370010200541086a2009290300370000200541186a220a2007290300370000412010332209450d0020092005290000370000200941186a200a290000370000200941106a200541106a290000370000200941086a200541086a290000370000200241306a41026a220a200241d0006a41026a2d00003a0000200220022f00503b0130200241f0036a41106a42a0808080800437030041002107200241003a008804200220053602fc03200242a080808080043702f403200220093602f0032002418b046a200a2d00003a0000200220022f01303b008904200241d0006a200241f0036a10c701024020022802504101470d00200241d0006a410472210a410121164108211b4100210c0340200241b0036a41206a200a41206a280200360200200241b0036a41186a2205200a41186a2902002206370300200241b0036a41106a2209200a41106a2902002208370300200241b0036a41086a2220200a41086a290200220b3703002002200a29020022223703b00320024190026a41186a220e200637030020024190026a41106a220f200837030020024190026a41086a2210200b3703002002202237039002200241d0006a41186a22032005290300370300200241d0006a41106a220d2009290300370300200241d0006a41086a22012020290300370300200220022903b00337035020024190026a10c8012106412010332209450d0a2009200229039002370000200941186a200e290300370000200941106a200f290300370000200941086a2010290300370000200241e0026a41086a20012903002208370300200241e0026a41106a200d290300220b370300200241e0026a41186a200329030022223703002002200229035022233703e00220024190046a41186a2220202237030020024190046a41106a2221200b37030020024190046a41086a221f200837030020022023370390040240200c20022802d402470d00200241d0026a200c4101108b0120022802d002211b20022802d802210c0b201b200c41386c6a22052006370300201f2903002106202129030021082020290300210b20022903900421222005412c6a4281808080103702002005200936022820052022370308200541206a200b370300200541186a2008370300200541106a20063703002002200c41016a220c3602d8022003200e290300370300200d200f2903003703002001201029030037030020022002290390023703500240200720022802a403470d00200241a0036a20074101108a0120022802a003211620022802a80321070b201620074105746a22052002290350370000200541186a2003290300370000200541106a200d290300370000200541086a20012903003700002002200741016a22073602a803200241d0006a200241f0036a10c70120022802504101460d000b0b024020022802f403450d0020022802f00310350b0240200228028004450d0020022802fc0310350b41f7edcb00ad4280808080f00084100122052900002106200241e0026a41086a2209200541086a290000370300200220063703e0022005103541cca9c000ad4280808080a00184100122052900002106200241b0036a41086a2207200541086a290000370300200220063703b00320051035412010332205450d00200520022903e002370000200520022903b003370010200541086a2009290300370000200541186a220a2007290300370000412010332209450d0020092005290000370000200941186a200a290000370000200941106a200541106a290000370000200941086a200541086a29000037000020024190026a41026a220a200241d0006a41026a2d00003a0000200220022f00503b019002200241d0006a41106a220742a080808080043703002002200536025c200242a0808080800437025420022009360250200241003a0068200241eb006a200a2d00003a0000200220022f0190023b0069200241d0026a200241d0006a10c901200241d0006a41186a220a420037030020074200370300200241d0006a41086a220542003703002002420037035041f7edcb00ad4280808080f000842206100122092900002108200241e0026a41086a220c200941086a290000370300200220083703e002200910352005200c290300370300200220022903e00237035041c1edcb00ad4280808080e00184100122032900002108200241b0036a41086a2209200341086a290000370300200220083703b00320031035201420022903b003370000201441086a220d2009290300370000200241306a41086a22012005290300370300200241306a41106a220e2007290300370300200241306a41186a220f200a29030037030020022002290350370330200241106a200241306a412010c0012002280214211020022802102120200a42003703002007420037030020054200370300200242003703502006100122032900002106200c200341086a290000370300200220063703e002200310352005200c290300370300200220022903e00237035041cfedcb00ad4280808080d002841001220c29000021062009200c41086a290000370300200220063703b003200c1035201420022903b003370000200d200929030037000020012005290300370300200e2007290300370300200f200a29030037030020022002290350370330200241086a200241306a412010c001200228020c21072002280208210a2009200241a0036a41086a280200360200200220022903a0033703b0032005200241d0026a41086a280200360200200220022903d00237035020024190046a2010410020201b20074104200a1b22054101200541014b1b200241b0036a200241d0006a10ca01024020022802900422170d00410321260c040b200241a4046a280200210c20024190046a41106a28020021162002419c046a280200211f20024190046a41086a2802002105200228029404211b2002410036025820024201370350200241d0006a4100200541306c220741306e108a012002280258210a0240024020070d00200228025021180c010b20022802502218200a4105746a210520172109034020052009290000370000200541186a200941186a290000370000200541106a200941106a290000370000200541086a200941086a290000370000200a41016a210a200541206a2105200941306a2109200741506a22070d000b0b20023502542108200241003602f803200242043703f003200241f0036a4100200c412c6c2205412c6d109801201f20056a210d20022802f803210320022802f00321210240200c0d00201f21050c020b200241b0036a410c6a212020212003412c6c6a2109200241b0036a410472210720024190026a41206a210120024190026a41186a210e20024190026a41106a210f20024190026a41086a2110201f210503402005280200210c2001200541246a290200370300200e2005411c6a290200370300200f200541146a29020037030020102005410c6a2902003703002002200541046a290200370390020240200c0d002005412c6a21050c030b2007200229039002370200200741086a2010290300370200200741106a200f290300370200200741186a200e290300370200200741206a20012903003702002002200c3602b003202010c8012106200241d0006a41286a200241b0036a41286a280200360200200241d0006a41206a200241b0036a41206a290300370300200241d0006a41186a200241b0036a41186a290300370300200241d0006a41106a200241b0036a41106a290300370300200241d0006a41086a200241b0036a41086a290300370300200220022903b003370350200241e0026a200241d0006a2006420010cb01200941286a200241e0026a41286a280200360200200941206a200241e0026a41206a290300370200200941186a200241e0026a41186a290300370200200941106a200241e0026a41106a290300370200200941086a200241e0026a41086a290300370200200920022903e002370200200341016a21032009412c6a21092005412c6a2205200d470d000b200220033602f8030c020b1045000b200220033602f8032005200d460d00034020052209412c6a21050240200941046a2802002207450d00200741246c450d00200928020010350b200d2005470d000b0b02402016450d002016412c6c450d00201f10350b20022802f403210d200241d0006a2018200a2021200310cc01024002402002280250220c0d00410021054100210c410021010c010b2002280258210102400240200228025422090d00200c21050c010b20092105200c2107034020072802c80521072005417f6a22050d000b200c21050340200520052f01064102746a41c8056a28020021052009417f6a22090d000b2007210c0b20052f010621090b200241ec006a2009360200200241e8006a4100360200200241e4006a20053602002002200136027020024100360260200242003703582002200c36025420024100360250200aad21062002200241306a360274200241b0036a200241d0006a10cd0120022802b003211c20022802b403211d20022802b803210a02402003450d002003412c6c21092021210503400240200541046a2802002207450d00200741306c450d00200528020010350b2005412c6a2105200941546a22090d000b0b200642208621060240200d450d00200d412c6c450d00202110350b2006200884212441002126201b450d00201b41306c450d00201710350b200241d0006a41186a22094200370300200241d0006a41106a22074200370300200241d0006a41086a220542003703002002420037035041f7edcb00ad4280808080f0008422081001220c2900002106200241e0026a41086a2203200c41086a290000370300200220063703e002200c103520052003290300370300200220022903e00237035041ceeecb00ad4280808080b001841001220c2900002106200241b0036a41086a220d200c41086a290000370300200220063703b003200c1035201420022903b003370000201441086a200d290300370000200241306a41086a2005290300370300200241306a41106a2007290300370300200241306a41186a200929030037030020022002290350370330201510074100210c20264103460d032009420037030020074200370300200542003703002002420037035020081001220c29000021062003200c41086a290000370300200220063703e002200c103520052003290300370300200220022903e00237035041b6aac000ad42808080809002841001220c2900002106200d200c41086a290000370300200220063703b003200c1035200420022903b003370000200441086a200d29030037000020024190046a41086a200529030037030020024190046a41106a200729030037030020024190046a41186a20092903003703002002200229035037039004410110332205450d04200541003a000020122005ad4280808080108410022005103542002108200241d0006a41186a22274200370300200241d0006a41106a22284200370300200241d0006a41086a221a42003703002002420037035041f7edcb00ad4280808080f00084220610012205290000210b200241e0026a41086a2229200541086a2900003703002002200b3703e00220051035201a2029290300370300200220022903e0023703504192aac000ad4280808080a0028410012205290000210b200241b0036a41086a220e200541086a2900003703002002200b3703b00320051035200420022903b003370000200441086a2209200e29030037000020024190046a41086a2221201a29030037030020024190046a41106a221f202829030037030020024190046a41186a221620272903003703002002200229035037039004201210072027420037030020284200370300201a42003703002002420037035020061001220529000021062029200541086a290000370300200220063703e00220051035201a2029290300370300200220022903e00237035041a4aac000ad4280808080a00284100122052900002106200e200541086a290000370300200220063703b00320051035200420022903b0033700002009200e2903003700002021201a290300370300201f202829030037030020162027290300370300200220022903503703900420121007201c200a41d0006c6a21200240200a0d00201c210d420021060c020b200241e0026a41106a211b20024190026a41106a210f200241b4026a2104200241d0006a41206a21014200210842002106201c210d0340200241b0036a41386a220a200d220541386a290300370300200241b0036a41306a220c200541306a290300370300200241b0036a41286a2203200541286a290300370300200241b0036a41206a2210200541206a290300370300200241b0036a41186a2209200541186a290300370300200241b0036a41106a2207200541106a290300370300200e200541086a2903003703002005290300210b200241d0026a41086a2214200541cc006a2802003602002002200b3703b0032002200541c4006a2902003703d002200541d0006a210d200541c0006a2802002205450d02200241d0006a41386a200a290300370300200241d0006a41306a200c290300370300200241d0006a41286a2003290300370300200120102903003703002027200929030037030020282007290300370300201a200e290300370300200220022903b003370350200241f0036a41186a2009290300370300200241f0036a41106a2007290300370300200241f0036a41086a200e290300370300200220022903b0033703f00320024190026a41186a2217200141186a290300370300200f200141106a29030037030020024190026a41086a221e200141086a290300220b370300200220053602b00220022001290300222237039002200420022903d002370200200441086a201428020036020020024190046a2011200241f0036a10ce0120023502980421232002280290042110200241003602e802200242013703e002200220024190026a360230200241306a200241e0026a10cf012002200f360230200241306a200241e0026a10cf0120022802b002210520022802b8022209200241e0026a107702402009450d00200941306c210c03400240024020022802e402220a20022802e80222096b4120490d0020022802e00221070c010b200941206a22072009490d04200a41017422032007200320074b1b22034100480d0402400240200a0d00024020030d00410121070c020b200310332207450d0a0c010b20022802e0022107200a2003460d002007200a200310372207450d090b200220033602e402200220073602e0020b200720096a2207200541106a290000370000200741186a200541286a290000370000200741106a200541206a290000370000200741086a200541186a2900003700002002200941206a3602e80220022005360230200241306a200241e0026a10cf01200541306a2105200c41506a220c0d000b0b20022802e402210520234220862010ad8420023502e80242208620022802e0022209ad84100202402005450d00200910350b0240200228029404450d00201010350b20162017290300370300201f200f2903003703002021201e29030037030020022002290390023703900420022802bc02210720022802b402210a20022802b0022109024020022802b802220541c100490d0020092005410041202005676b10d00141c00021050b200241e0026a41186a2016290300370300201b201f2903003703002029202129030037030020022002290390043703e0022002200736028c0320022005360288032002200a360284032002200936028003200241a0036a2011200241f0036a10d10120023502a803212320022802a003211020024100360238200242013703302002200241e0026a3602800220024180026a200241306a10cf012002201b3602800220024180026a200241306a10cf0120022802800321052002280288032209200241306a107702402009450d00200941306c210c0340024002402002280234220a200228023822096b4120490d00200228023021070c010b200941206a22072009490d04200a41017422032007200320074b1b22034100480d0402400240200a0d00024020030d00410121070c020b200310332207450d0a0c010b20022802302107200a2003460d002007200a200310372207450d090b20022003360234200220073602300b200720096a2207200541106a290000370000200741186a200541286a290000370000200741106a200541206a290000370000200741086a200541186a2900003700002002200941206a360238200220053602800220024180026a200241306a10cf01200541306a2105200c41506a220c0d000b0b2006200b7c200820227c220b2008542205ad7c21082002280234210920234220862010ad84200235023842208620022802302207ad84100202402009450d00200710350b2008200651210920082006542107024020022802a403450d00201010350b2005200720091b210502402002280284032209450d00200941306c450d0020022802800310350b427f200820051b2106427f200b20051b2108200d2020470d000c030b0b103e000b2020200d460d000340200d220541d0006a210d0240200541c4006a2802002209450d00200941306c450d00200541c0006a28020010350b2020200d470d000b0b0240201d450d00201d41d0006c450d00201c10350b200241b0036a201110bd0120022802b003210520023502b803210b2002200637035820022008370350200b4220862005ad84201342808080808002841002024020022802b403450d00200510350b02402024422088a7410574220a450d00200241b0036aad210b201821050340200241d0006a200510b501200220022802502207200228025810d2012002280204410020022802001b210902402002280254450d00200710350b200241d0006a2011200510d3012002350258210620022802502107200241003a00b5030240024002400240200941c000490d00200941808001490d012009418080808004490d02200241053a00b503200241033a00b003200220093600b1034280808080d00021080c030b200241013a00b503200220094102743a00b00342808080801021080c020b200241023a00b503200220094102744101723b01b00342808080802021080c010b200241043a00b503200220094102744102723602b0034280808080c00021080b20064220862007ad842008200b841002024020022d00b503450d00200241003a00b5030b02402002280254450d00200710350b200541206a2105200a41606a220a0d000b0b200241d9006a20263a0000200241d8006a41043a0000200241043a005041b0b4cc004100200241d0006a10d4012018210c0b200020243702042000200c360200200241c0046a24000f0b103c000b8f0201037f230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822040d00410021010c010b200328020c210502400240200341106a2802004104490d0020042800002102410121010c010b4100210120034100360220200342013703182003410936022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341c888c2003602382003200341286a360248200341346a41e88ac500200341386a10431a200335022042208620033502188410060240200328021c450d00200328021810350b0b2005450d00200410350b2000200236020420002001360200200341d0006a24000bd71704027f017e077f017e230041d0006b2201240041f7edcb00ad4280808080f00084100122022900002103200141086a41086a200241086a290000370300200120033703082002103541e4b6c000ad4280808080b00184100122022900002103200141186a41086a200241086a2900003703002001200337031820021035200120003602342001200141346aad22034280808080c000841003220229000037033820021035200141cc006a200141386a3602002001200141386a41086a22043602442001200141346a3602482001200141386a360240200141286a200141c0006a107b02400240024002402001280230220541206a2206417f4c0d00200128022821070240024020060d0041002108410121020c010b200610332202450d02200621080b024002402008410f4d0d00200821090c010b200841017422094110200941104b1b22094100480d03024020080d002009103322020d010c050b20082009460d0020022008200910372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020094170714110460d00200921080c010b200941017422084120200841204b1b22084100480d0320092008460d0020022009200810372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200841606a2005490d00200821090c010b200541206a22092005490d032008410174220a2009200a20094b1b22094100480d0320082009460d0020022008200910372202450d040b200241206a20072005109d081a0240200128022c450d00200710350b2006ad4220862002ad84100802402009450d00200210350b41f7edcb00ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002103541d2b6c000ad4280808080a0028410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002103520012000360234200120034280808080c000841003220229000037033820021035200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a107b2001280230220541206a2208417f4c0d00200128022821070240024020080d0041002109410121020c010b200810332202450d02200821090b024002402009410f4d0d00200921060c010b200941017422064110200641104b1b22064100480d03024020090d00200610332202450d050c010b20092006460d0020022009200610372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020064170714110460d00200621090c010b200641017422094120200941204b1b22094100480d0320062009460d0020022006200910372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200941606a2005490d00200921060c010b2005415f4b0d03200941017422062008200620084b1b22064100480d0320092006460d0020022009200610372202450d040b200241206a20072005109d081a0240200128022c450d00200710350b2008ad4220862002ad84100802402006450d00200210350b41f7edcb00ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002103541c0b6c000ad4280808080a0028410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002103520012000360234200120034280808080c000841003220229000037033820021035200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a107b2001280230220541206a2208417f4c0d00200128022821070240024020080d0041002109410121020c010b200810332202450d02200821090b024002402009410f4d0d00200921060c010b200941017422064110200641104b1b22064100480d03024020090d00200610332202450d050c010b20092006460d0020022009200610372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020064170714110460d00200621090c010b200641017422094120200941204b1b22094100480d0320062009460d0020022006200910372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200941606a2005490d00200921060c010b2005415f4b0d03200941017422062008200620084b1b22064100480d0320092006460d0020022009200610372202450d040b200241206a20072005109d081a0240200128022c450d00200710350b2008ad4220862002ad84100802402006450d00200210350b41f7edcb00ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002103541dcb5c000ad4280808080b0028410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002103520012000360234200120034280808080c000841003220229000037033820021035200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a107b2001280230220541206a2208417f4c0d00200128022821070240024020080d0041002109410121020c010b200810332202450d02200821090b024002402009410f4d0d00200921060c010b200941017422064110200641104b1b22064100480d03024020090d00200610332202450d050c010b20092006460d0020022009200610372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020064170714110460d00200621090c010b200641017422094120200941204b1b22094100480d0320062009460d0020022006200910372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200941606a2005490d00200921060c010b2005415f4b0d03200941017422062008200620084b1b22064100480d0320092006460d0020022009200610372202450d040b200241206a20072005109d081a0240200128022c450d00200710350b2008ad4220862002ad84100702402006450d00200210350b200141c0006a200010ad01200135024842208620012802402202ad84100702402001280244450d00200210350b41f7edcb00ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002103541efb5c000ad4280808080e0018410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002103520012000360234200120034280808080c000841003220229000037033820021035200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a107b2001280230220641206a2208417f4c0d00200128022821050240024020080d0041002104410121020c010b200810332202450d02200821040b024002402004410f4d0d00200421090c010b200441017422094110200941104b1b22094100480d03024020040d00200910332202450d050c010b20042009460d0020022004200910372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020094170714110460d00200921040c010b200941017422044120200441204b1b22044100480d0320092004460d0020022009200410372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200441606a2006490d00200421090c010b2006415f4b0d03200441017422092008200920084b1b22094100480d0320042009460d0020022004200910372202450d040b200241206a20052006109d081a0240200128022c450d00200510350b2008ad4220862002ad84100702402009450d00200210350b200141c0006a200010b801200135024842208620012802402202ad84100702402001280244450d00200210350b200141d0006a24000f0b1044000b1045000b103e000b103c000bb10201067f230041206b22022400024002402001422088a722030d00410121040c010b2001a721040b200220033602142002200436021002402003450d0020042d0000210520022003417f6a3602142002200441016a360210200541014b0d0041002106024002400240024020050e020100010b200241086a200241106a10c40120022802080d0320022802142205200228020c2203490d032003417f4c0d010240024020030d0042002101410121060c010b200310392206450d032006200228021022072003109d081a2002200520036b3602142002200720036a3602102003ad21010b2006450d0320012003ad4220868421010b200020013702042000200636020020041035200241206a24000f0b1044000b1045000b41b89acc00412e200241186a41c09bcc0041e89acc001046000ba20401097f230041e0006b220224002002200110c40102400240024002402002280200450d00200041003602000c010b2002280204220320012802044105762204200420034b1b22044105742205417f4c0d010240024020040d00410121060c010b200510332206450d030b41002107200241003602102002200436020c20022006360208024002402003450d0041002108034041002105200241003a0058200841016a21082001280204417f6a210403402004417f460d03200241386a20056a200128020022092d00003a0000200120043602042001200941016a3602002002200541016a22093a00582004417f6a21042009210520094120470d000b200241186a41186a2205200241386a41186a290300370300200241186a41106a2209200241386a41106a290300370300200241186a41086a220a200241386a41086a2903003703002002200229033837031802402007200228020c470d00200241086a20074101108a0120022802082106200228021021070b200620074105746a22042002290318370000200441186a2005290300370000200441106a2009290300370000200441086a200a2903003700002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c010b0240200541ff0171450d00200241003a00580b20004100360200200228020c41ffffff3f71450d00200610350b200241e0006a24000f0b1044000b1045000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141808004492106200141027621070c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000b990707017f047e027f017e057f047e017f23004190026b22022400200241c0006a200110f60102400240024002400240024002402002290340a70d00200241c0006a41106a290300210320022903482104200241286a200110f6012002290328a70d03200241286a41106a290300210520022903302106200241206a200110c40120022802200d0220022802242207200128020441306e2208200820074b1bad42307e2209422088a7450d010c060b200041003602200c040b2009a72208417f4c0d040240024020080d004108210a0c010b20081033220a450d030b4100210b200241003602602002200a3602582002200841306e36025c0240024002402007450d004100210c03404100210d200241003a008802200c41016a210c2001280204417f6a210803402008417f460d03200241e8016a200d6a2001280200220e2d00003a0000200120083602042001200e41016a3602002002200d41016a220e3a0088022008417f6a2108200e210d200e4120470d000b200241c8016a41186a2208200241e8016a41186a290300370300200241c8016a41106a220d200241e8016a41106a290300370300200241c8016a41086a220e200241e8016a41086a290300370300200220022903e8013703c801200241086a200110f6012002290308a70d03200241086a41106a29030021092002290310210f20024188016a41086a200e290300221037030020024188016a41106a200d290300221137030020024188016a41186a20082903002212370300200241e8006a41086a220d2010370300200241e8006a41106a220e2011370300200241e8006a41186a22132012370300200220022903c801221037038801200220103703680240200b200228025c470d00200241d8006a200b41011088012002280258210a2002280260210b0b200a200b41306c6a220820093703082008200f37030020082002290368370310200841186a200d290300370300200841206a200e290300370300200841286a20132903003703002002200b41016a220b360260200c2007470d000b0b200a450d02200229025c210920002004370300200020093702242000200a3602202000200637031020002003370308200041186a20053703000c050b200d41ff0171450d00200241003a0088020b20024188016a41086a200241a8016a41086a290300370300200228025c2201450d00200141306c450d00200a10350b200041003602200c020b200041003602200c010b1045000b20024190026a24000f0b1044000bbd0101047f230041106b22022400200028020421032000280200210041012104200128021841d9a0c00041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d0003402002200036020c20022002410c6a41accfc70010701a200041016a21002003417f6a22030d000b20022d000421050b0240200541ff01710d002002280200220028021841d8a0c00041012000411c6a28020028020c11000021040b200241106a240020040b8a0604057f017e047f037e230041f0006b22022400200241286a200141146a350200422086200135020c84102710c2010240024020022802282203450d00200141086a2104200141106a210503400240024020042802002206200229022c2207422088a722084b0d00200128020022092003460d0120092003200610a008450d010b2007a7450d02200310350c020b02402005280200450d00200128020c10350b2001200336020c2005200737020020022003200810d201024002402002280200450d002002280204210a024020012d0018450d002001350214422086200135020c8410070b2001280214220820042802002203490d0102400240200820036b22084108490d00200841786a2106200128020c20036a41086a21090c010b410021060240410028028cb54c0d0041b0b4cc0021090c010b410021064100280298b54c21034100280294b54c21084100280290b54c210b200241e500360268200242b48080801037036020024187a1c00036025c20024213370254200241f4a0c0003602502002420037034841b0b4cc002109200241b0b4cc0036024420024201370338200241eca0c00036023420024113360230200241f4a0c00036022c20024101360228200841aca2c000200b410246220b1b200241286a200341c4a2c000200b1b2802101102000b41002103200241003a00480240034020062003460d01200241286a20036a200920036a2d00003a00002002200341016a22083a00482008210320084120470d000b200241086a41186a200241286a41186a2903002207370300200241086a41106a200241286a41106a290300220c370300200241086a41086a200241286a41086a290300220d37030020022002290328220e3703082000411c6a2007370000200041146a200c3700002000410c6a200d3700002000200e370004200041246a200a360200200041013602000c050b200341ff0171450d00200241003a00480b200241286a2001350214422086200135020c84102710c201200228022822030d010c020b0b2003200841889aca001059000b200041003602000b200241f0006a24000bda0b04047f017e027f027e23004190026b2201240020014180026a200010b401200141d8006a200128028002220020012802880210d501200141e0016a41086a2202200141e1006a290000370300200141e0016a41106a2203200141e9006a290000370300200141e0016a41186a2204200141f1006a290000370300200120012900593703e0010240024002400240024002400240024020012d00584101470d00200141386a41186a2004290300370300200141386a41106a2003290300370300200141386a41086a2002290300370300200120012903e0013703380240200128028402450d00200010350b200141d8006a41186a2202200141386a41186a290300370300200141d8006a41106a2203200141386a41106a290300370300200141d8006a41086a2204200141386a41086a2903003703002001200129033837035841f7edcb00ad4280808080f00084100122002900002105200141b0016a41086a200041086a290000370300200120053703b0012000103541c6a9c000ad4280808080e00084100122002900002105200141c0016a41086a200041086a290000370300200120053703c00120001035412010332200450d0420002001290358370000200041186a2002290300370000200041106a2003290300370000200041086a20042903003700002000ad428080808080048410042202290000210520014180026a41086a200241086a290000370300200120053703800220021035200141ec016a200041206a360200200120003602e801200120014180026a41106a3602e401200120014180026a3602e001200141d0016a200141e0016a107b2000103520012802d801220641206a2202417f4c0d0520012802d00121070240024020020d0041002103410121000c010b200210332200450d05200221030b024002402003410f4d0d00200321040c010b200341017422044110200441104b1b22044100480d07024020030d002004103322000d010c090b20032004460d0020002003200410372200450d080b200020012903b001370000200041086a200141b0016a41086a2903003700000240024020044170714110460d00200421030c010b200441017422034120200341204b1b22034100480d0720042003460d0020002004200310372200450d080b200020012903c001370010200041186a200141c0016a41086a29030037000002400240200341606a2006490d00200321040c010b2006415f4b0d07200341017422042002200420024b1b22044100480d0720032004460d0020002003200410372200450d080b200041206a20072006109d081a024020012802d401450d00200710350b200141d8006a2000200210d60120012802782203450d01200141f0006a290300210820014188016a280200210620014184016a280200210720012903682109200128027c210202402004450d00200010350b02402002450d00200241186c450d00200310350b200641ffffffff0371450d03200710350c030b200128028402450d01200010350c010b2004450d00200010350b42002109420021080b200141d8006a41186a4200370300200141d8006a41106a22034200370300200141d8006a41086a220042003703002001420037035841b6fdc600ad42808080808001841001220229000021052000200241086a290000370300200120053703582002103541e489c200ad4280808080d00184100122022900002105200141386a41086a2204200241086a2900003703002001200537033820021035200320012903382205370300200141e0016a41086a2000290300370300200141e0016a41106a2005370300200141e0016a41186a2004290300370300200120012903583703e001200141206a200141e0016a412010d701200141106a2001290328200141206a41106a290300427f420010980820012009200820012903104200200128022022001b220542012005420156200141106a41086a290300420020001b22054200522005501b22001b2005420020001b1098082001290300210520014190026a240020050f0b1045000b1044000b103e000b103c000be80808097f017e0c7f017e017f017e017f037e230041f0016b22022400200241086a41186a200141186a280200360200200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241e8006a200241086a10c905024020022d0098014102460d00200041046a21030340200241a0016a41286a200241e8006a41286a280200360200200241a0016a41206a200241e8006a41206a2201290300370300200241a0016a41186a2204200241e8006a41186a2205290300370300200241a0016a41106a2206200241e8006a41106a2207290300370300200241a0016a41086a2208200241e8006a41086a2209290300370300200220022903683703a0012001280200210a0240200229028c01220b422088a7220c450d00200228029401210d4100210e200a21014100210f024002400340200220013602cc01200241d0016a200241cc016a10bb01024002400240024020022802dc012210450d0020022802d8012111024020022802e00141ffffffff0371450d00201010350b2011200d4b0d010b200e0d014100210e0c020b200e41016a210e0c010b200f200e6b2210200c4f0d02200241d0016a41186a22112001200e4105746b221041186a2212290000370300200241d0016a41106a2213201041106a2214290000370300200241d0016a41086a2215201041086a2216290000370300200220102900003703d001200141086a22172900002118200141106a2219290000211a200141186a221b290000211c201020012900003700002012201c3700002014201a37000020162018370000201b20112903003700002019201329030037000020172015290300370000200120022903d0013700000b200141206a2101200c200f41016a220f460d020c000b0b2010200c41f485cc001042000b200e417f6a200c4f0d00200b42ffffffff0f83200c200e6bad42208684210b0b200241c8006a41186a22012004290300370300200241c8006a41106a220e2006290300370300200241c8006a41086a220f2008290300370300200220022903a001370348200a450d01200520012903003703002007200e2903003703002009200f29030037030020022002290348370368200241e8006a10c8012118200241286a41186a2001290300221a370300200241286a41106a200e290300221c370300200241286a41086a200f290300221d37030020022002290348221e3703282005201a3703002007201c3703002009201d3703002002201e3703680240200041086a220f280200220e2003280200470d002000200e4101108b010b2000280200200e41386c6a22012002290368370308200120183703002001200a360228200141106a2009290300370300200141186a2007290300370300200141206a20052903003703002001412c6a200b370200200f200e41016a360200200241e8006a200241086a10c90520022d0098014102470d000b0b0240200228020c450d00200228020810350b0240200241186a280200450d00200228021410350b200241f0016a24000bab2104027f017e107f077e23004190026b2205240020054100360238200541003602300240024002400240200441086a280200200341086a28020022066aad42e0007e2207422088a70d002007a72208417f4c0d0041082109024002402008450d00200810332209450d010b20054100360248200520093602402005200841e0006e3602442003280204210a2003280200210b2005410036029801200542083703900120054190016a410020064105742209410575109b01200528029801210c02402006450d00200941606a410576210d200528029001200c41d8006c6a210e200541f0016a2108200541e8016a210f41002106200b21030340200541a0016a41186a2210200341186a2211290000370300200541a0016a41106a2212200341106a2213290000370300200541a0016a41086a2214200341086a2215290000370300200520032900003703a001200541e0006a41186a2011290000370300200541e0006a41106a2013290000370300200541e0006a41086a201529000037030020052003290000370360200541306a200541e0006a2006108403200541c0016a41086a4200370300200541c0016a41106a4200370300200541c0016a41186a4200370300200541c0016a41206a4200370300200f4200370300200841186a2010290300370000200841106a2012290300370000200841086a2014290300370000200820052903a001370000200542003703c001200e200541c0016a41d000109d08220e41d0006a41003a0000200e41d8006a210e200341206a2103200641016a2106200941606a22090d000b200c200d6a41016a210c0b2005200c360298010240200a41ffffff3f71450d00200b10350b200541d0006a41086a20054190016a41086a2802002203360200200520052903900137035020032002490d032004280204210620042802002103200541c0006a2005280248200441086a28020041386c220941386d10a4012005280240210e20052802482108200541d4016a200541d0006a3602002005200320096a3602cc01200520033602c801200520063602c401200520033602c0012005200541306a3602d001200541e0006a41086a20083602002005200541c8006a3602642005200e200841e0006c6a360260200541c0016a200541e0006a109a042001ad42307e2207422088a70d012007a72208417f4c0d01200528025821030240024020080d00410821040c010b200810332204450d010b20054100360218200520043602102005200841306e3602142001412c6c2208417f4c0d010240024020080d00410421160c010b200810332216450d010b4100210b2005410036022820052001360224200520163602202003200120032001491b2217450d024100210b200541c0016a41186a210a200541c0016a41106a210f200541c0016a41086a210d4100210203402005280250210602402003450d00200341d8006c21082006210303400240200341d0006a2d00000d0002400240200341206a2903002218200341286a29030022198450450d0042002107427f2118427f21190c010b427f21072005427f427f20182019109808200541086a2903002119200529030021180b2003201837030020032019370308200341106a2007370300200341186a20073703000b200341d8006a2103200841a87f6a22080d000b0b0240024020052802482203450d0020052802402209200341e0006c6a21120340024020092802382203450d00200341c8006c2106200928023041206a210303402005280258220e200328020022084d0d0402402005280250200841d8006c6a22082d00500d0020082903202207200841286a290300221884500d00200541c0016a2009290310200941186a2903002009290300200941086a29030020072018109b04200820082903002207427f2007427f20052903c80120052802c001410146220e1b22197c221820182007542210200841086a22112903002207427f200f290300200e1b221a7c2010ad7c221820075420182007511b220e1b2019201a845022101b37030020112007427f2018200e1b20101b3703000b200341c8006a2103200641b87f6a22060d000b0b200941e0006a22092012470d000b200528025021060b200241016a2102200528025841d8006c2103200641a87f6a210803402003450d05200341a87f6a2103200841d8006a2108200641d0006a2109200641d8006a220e210620092d00000d000b02402003450d00200841086a2903002107200841186a2903002118200841106a29030021192008290300211a4100210603400240200e20066a220941d0006a2d00000d00200941086a290300221b2007201a2007201920182009290300221c201b200941106a290300221d200941186a290300221e109c0441ff017141014622101b2107201c201a20101b211a201e201820101b2118201d201920101b21192009200820101b21080b2003200641d8006a2206470d000b2008450d050b200841013a0050024020052802482203450d0020052802402206200341e0006c6a21012008410c6a2114200841306a21150340200641e0006a210c024020062802382209450d0020062802302103200941c8006c210903400240024020142003460d00200341246a2015412010a0080d010b200641186a220e290300211a200841086a2210290300210720062903102119200829030021182008290310211b200341186a200841186a2211290300370300200341106a201b3703002003200742002007201a7d2018201954ad7d221b201820197d221c201856201b200756201b2007511b22121b2019201a845022131b370308200320184200201c20121b20131b37030020102903002107201129030021182008290300211920062008290310370320200641286a201837030020062019370310200e20073703000b200341c8006a2103200941b87f6a22090d000b0b200c2106200c2001470d000b0b200a200841c8006a290000370300200f200841c0006a290000370300200d200841386a290000370300200520082900303703c001200841286a2903002107200829032021180240200b2005280214470d00200541106a200b4101108801200528021021042005280218210b0b2004200b41306c6a220320052903c001370300200d2903002119200f290300211a200a290300211b20032018370320200341286a2007370300200341186a201b370300200341106a201a370300200341086a20193703002005200b41016a220b360218200220174f0d04200528025821030c010b0b2008200e41f4c4c8001042000b1045000b1044000b024020052802482203450d0020052802402214200341e0006c6a2102200b41306c210c200541ec006a220b41186a210a200b41106a210d200b41086a2117410021010340200b201429003c370000200a201441d4006a290000370000200d201441cc006a2900003700002017201441c4006a2900003700002005410036026820054204370360024020142802382203450d0020142802302212200341c8006c6a2115201441106a210f410021114104211303402012221041246a2106201041c8006a211241002109200c210820042103024003402008450d01024020062003460d0020032006412010a008210e200941016a2109200841506a2108200341306a2103200e0d010b0b418094ebdc0321080240200f2010109d040d004100210302402010290310201429032085201041186a290300201441286a29030085844200520d00200541c0016a428094ebdc0342002010290300201041086a290300200f290300200f41086a290300109b04427f20052903c80120052802c00141014622031b221842ffffffff0f56427f200541c0016a41106a29030020031b22074200522007501b0d012018a7220341ff93ebdc034b0d010b200321080b200541c0016a41186a22062010413c6a290000370300200541c0016a41106a2209201041346a290000370300200541c0016a41086a220e2010412c6a290000370300200520102900243703c001024020112005280264470d00200541e0006a20114101108d0120052802602113200528026821110b2013201141246c6a220320052903c001370200200e2903002107200929030021182006290300211920032008360220200341186a2019370200200341106a2018370200200341086a20073702002005201141016a22113602680b20122015470d000b024002402011450d0002400240201141246c22060d00410021030c010b201341206a2108410021030340417f200320082802006a220920092003491b2103200841246a21082006415c6a22060d000b0b02404100418094ebdc0320036b22032003418094ebdc034b1b221020116e2203418094ebdc032003418094ebdc03491b220e450d00201341206a210341002108034020112008460d032005417f20032802002206200e6a220920092006491b22063602c0012005418094ebdc033602c4012003200541c0016a2006418094ebdc034b4102746a280200360200200341246a21032011200841016a2208470d000b0b02402010200e20116c6b220e450d004100210303402005417f2013200320117041246c6a2208280220220641016a220920092006491b22063602c0012005418094ebdc033602c4012008200541c0016a2006418094ebdc034b4102746a280200360220200341016a2203200e490d000b0b200541c0016a41286a2208200541e0006a41286a280200360200200541c0016a41206a2206200541e0006a41206a290300370300200541c0016a41186a2209200541e0006a41186a290300370300200541c0016a41106a220e200541e0006a41106a290300370300200541c0016a41086a2210200541e0006a41086a290300370300200520052903603703c001024020012005280224470d00200541206a2001410110980120052802202116200528022821010b20162001412c6c6a220320052903c001370200200341286a2008280200360200200341206a2006290300370200200341186a2009290300370200200341106a200e290300370200200341086a20102903003702002005200141016a22013602280c020b20052802642203450d01200341246c450d01201310350c010b200820114184c5c8001042000b201441e0006a22142002470d000b0b200541c0016a41086a2203200541106a41086a280200360200200541d4016a200541206a41086a28020036020020002005290310370200200520052903203702cc01200041086a2003290300370200200041106a200541c0016a41106a290300370200024020052802542203450d00200341d8006c450d00200528025010350b024020052802482203450d00200341e0006c2108200528024041346a21030340024020032802002206450d00200641c8006c450d002003417c6a28020010350b200341e0006a2103200841a07f6a22080d000b0b024020052802442203450d00200341e0006c450d00200528024010350b200541306a10b1010c010b20004100360200024020052802542203450d00200341d8006c450d00200528025010350b024020052802482203450d00200341e0006c2108200528024041346a21030340024020032802002206450d00200641c8006c450d002003417c6a28020010350b200341e0006a2103200841a07f6a22080d000b0b024020052802442203450d00200341e0006c450d00200528024010350b200541306a10b101200428020021060240200441086a2802002203450d00200341386c21082006412c6a210303400240200328020041ffffff3f71450d002003417c6a28020010350b200341386a2103200841486a22080d000b0b200441046a2802002203450d00200341386c450d00200610350b20054190026a24000be80b08077f017e017f037e027f037e027f037e230041d0016b22042400200128020421052001280200210602400240024020012802082207450d00200741246c2108410021090340200620096a220741206a280200210a200441b0016a41186a200741186a290000370300200441b0016a41106a200741106a290000370300200441b0016a41086a200741086a290000370300200420072900003703b001200a0d022008200941246a2209470d000b0b4200210b4108210c4100210902402005450d00200541246c450d00200610354200210b0b4200210d410021070c010b200441306a20022003428094ebdc034200109808200441206a2004290330220e200441306a41086a290300220f4280ec94a37c427f108408200441106a200e200f200aad220d4200108408200441d0006a41086a220a200441b0016a41086a290300370300200441d0006a41106a2210200441b0016a41106a290300370300200441d0006a41186a2211200441b0016a41186a290300370300200420042903b001220b3703702004200b370350200d200429032020027c22127e220d428094ebdc0380210b20042903102113200441106a41086a29030021140240024041301033220c450d00200c2013200ba7417f200d428080808080c0b2cd3b541b200d200b4280ec94a37c7e7c4280cab5ee01566aad7c220b370320200c2004290350370300200c41286a2014200b201354ad7c220d370300200c41186a2011290300370300200c41106a2010290300370300200c41086a200a29030037030020044281808080103702442004200c36024002402008415c6a2009470d00410121090c020b200741c4006a210a200820096b41b87f6a2108410121090340200a2802002115200441b0016a41186a2210200a41606a220741186a290000370300200441b0016a41106a2211200741106a290000370300200441b0016a41086a2216200741086a290000370300200420072900003703b0010240024020150d002008450d040c010b2004200e200f2015ad22134200108408200441f0006a41086a20162903002214370300200441f0006a41106a20112903002217370300200441f0006a41186a20102903002218370300200420042903b0012219370370201020183703002011201737030020162014370300200420193703b001200b20042903002214201320127e2213428094ebdc03802217a7417f2013428080808080c0b2cd3b541b201320174280ec94a37c7e7c4280cab5ee01566aad7c22137c2217200b542207200d200441086a2903002013201454ad7c22147c2007ad7c220b200d54200b200d511b2107024020092004280244470d00200441c0006a200941011088012004280240210c0b427f200b20071b210d427f201720071b210b200c200941306c6a220720042903b00137030020162903002117201129030021182010290300211920072013370320200741286a2014370300200741186a2019370300200741106a2018370300200741086a20173703002004200941016a22093602482008450d030b2008415c6a2108200a41246a210a0c000b0b1045000b02402005450d00200541246c450d00200610350b200428024421070b024002402002200b7d22142002562003200d7d2002200b54ad7d221320035620132003511b4101470d00200b20027d2213200b56200d20037d200b200254ad7d220b200d56200b200d511b0d012009450d01200941306c200c6a41706a220a4200200a290300220d20137d22142014200d56200a41086a220a2903002214200b7d200d201354ad7d220d201456200d2014511b22081b370300200a4200200d20081b3703000c010b2009450d00200941306c200c6a41706a220a427f200a290300220d20147c220b200b200d542208200a41086a220a290300220d20137c2008ad7c220b200d54200b200d511b22081b370300200a427f200b20081b3703000b20002009360208200020073602042000200c3602002000200129020c37020c200041146a200141146a2902003702002000411c6a2001411c6a290200370200200041246a200141246a290200370200200441d0016a24000ba028030f7f047e1b7f230022052106200541e00b6b41607122072400200741003602182007410036021002400240024002402002450d00200120024105746a2108200741e0056a41027221094100210a034020074200370348200742003703402007410036025820074208370350200741a8026a41186a220b200141186a290000370300200741a8026a41106a220c200141106a290000370300200741a8026a41086a220d200141086a290000370300200720012900003703a80202400240200a450d002007280214210e0c010b200741e0056a410041e002109f081a200741f8026a410041e002109f081a41c8051033220a450d054100210e200a41003b0106200a4100360200200a41086a200741e0056a41e002109d081a200a41e8026a200741f8026a41e002109d081a200741003602142007200a3602100b200141206a21010240024002400240024002400340200a41066a210f200a2f01062210410574210241002111200a41086a22122105024003402002450d01200741a8026a2005412010a0082213450d03200241606a2102201141016a2111200541206a21052013417f4a0d000b2011417f6a21100b0240200e450d00200e417f6a210e200a20104102746a41c8056a280200210a0c010b0b200741f0006a41186a2202200b290300370300200741f0006a41106a200c2903002214370300200741f0006a41086a200d2903002215370300200720072903a80222163703702007200728021841016a360218200c2014370300200d2015370300200b2002290300370300200720163703a80220072903582114200729035021152007290348211620072903402117200f2f01002205410b490d01200741e0056a410041e002109f081a200741f8026a410041e002109f081a41c80510332218450d0a201841003b010620184100360200201841086a200741e0056a41e002109d082105201841e8026a200741f8026a41e002109d082111200741e0056a41086a2219200a41b0046a290300370300200741e0056a41106a221a200a41b8046a290300370300200741e0056a41186a221b200a41c0046a2903003703002007200a41db016a2900003703e0022007200a41e0016a2900003700e5022007200a41a8046a2903003703e0052007200a41c8016a2f00003b01f4022007200a41ca016a2d00003a00f602200a41cb016a280000211c200a41cf016a280000211d200a41d3016a280000211e200a41d7016a280000211f2005200a41e8016a200a2f010641796a22024105742213109d0821052011200a41c8046a2013109d082111200a41063b0106201820023b0106200720072f01f4023b01dc02200720072d00f6023a00de02200720072903e0023703c802200720072900e5023700cd02200741f8026a41186a2220201b290300370300200741f8026a41106a2221201a290300370300200741f8026a41086a22222019290300370300200720072903e0053703f8020240024020104107490d002005201041057441c07e6a220e6a2005201041796a221341057422106a2205200241ffff037120136b410574109e081a200541186a200b290300370000200541106a200c290300370000200541086a200d290300370000200520072903a8023700002011200e6a201120106a2202201841066a220f2f010020136b410574109e081a200241186a20143703002002201537031020022016370308200220173703000c010b20122010410574220541206a22116a201220056a2202200f2f010020106b410574109e081a200241186a200b290300370000200241106a200c290300370000200241086a200d290300370000200220072903a802370000200a41e8026a220220116a200220056a2202200f2f010020106b410574109e081a200241186a20143703002002201537031020022016370308200220173703000b200f200f2f010041016a3b010020074190026a41026a220220072d00de023a0000200741d8016a41086a22232022290300370300200741d8016a41106a22242021290300370300200741d8016a41186a22252020290300370300200720072f01dc023b019002200720072903c8023703c801200720072900cd023700cd01200720072903f8023703d801200741a4016a41026a222620022d00003a0000200720072f0190023b01a401200720072900cd0137009501200720072903c80137039001200741a8016a41186a22272025290300370300200741a8016a41106a22282024290300370300200741a8016a41086a22292023290300370300200720072903d8013703a8010240200a280200220e0d004100212a200741106a21020c040b200a2f0104210f4100212a0340200741a4026a41026a222b20262d00003a0000200720072f01a4013b01a402200720072903900137039002200720072900950137009502200b2027290300370300200c2028290300370300200d2029290300370300200720072903a8013703a80241000d03200f41ffff0371210a024002400240200e2f01062202410b490d002009410041f205109f081a41f80510332213450d0e20134100360200201341046a200741e0056a41f405109d081a2007200e2f00c8013b01f4022007200e41ca016a2d00003a00f6022007200e41db016a2900003703e0022007200e41e0016a2900003700e502200e41cb016a280000212c200e41cf016a280000212d200e41d3016a280000212e200e41d7016a280000212f201b200e41c0046a290300370300201a200e41b8046a2903003703002019200e41b0046a2903003703002007200e2903a8043703e005201341086a200e41e8016a200e2f0106220241796a22054105742211109d082130201341e8026a200e41c8046a2011109d082131201341c8056a200e41e4056a2002417a6a2210410274109d082112200e41063b0106201320053b010602402010450d00410021022012210503402005280200221120023b010420112013360200200541046a21052010200241016a2202470d000b0b2020201b2903003703002021201a29030037030020222019290300370300200720072903e0053703f802200720072f01f4023b01dc02200720072d00f6023a00de02200720072903e0023703c802200720072900e5023700cd02200741dc056a41026a221020072d00de023a0000200720072f01dc023b01dc05200720072903c8023703c801200720072900cd023700cd01201b2020290300370300201a202129030037030020192022290300370300200720072903f8023703e005200f41ffff037122054107490d012030200a417a6a2211410574220f6a2030200a41796a220241057422326a220520132f010620026b410574109e081a200541186a2007290095023700002005201f36000f2005201e36000b2005201d3600072005201c360003200541026a202b2d00003a0000200520072f01a4023b000020052007290390023700132031200f6a203120326a220520132f0106220f20026b410574109e081a200541186a200b290300370300200541106a200c290300370300200541086a200d290300370300200520072903a8023703002013200f41016a22053b0106200a410274221c20126a416c6a201220114102746a220f200541ffff0371220a20116b410274109e081a200f2018360200200a2011490d022013201c6a41b0056a2105034020052802002211200241016a22023b010420112013360200200541046a21052002200a490d000c030b0b200e41086a2205200a41016a221141057422136a2005200a41057422106a22052002200a6b410574220f109e081a2005201f36000f2005201e36000b2005201d3600072005201c360003200541026a202b2d00003a0000200520072f01a4023b00002005200729039002370013200541186a200729009502370000200e41e8026a220520136a200520106a2205200f109e081a200541186a200b290300370300200541106a200c290300370300200541086a200d290300370300200520072903a802370300200e200241016a22023b0106200a410274200e41c8056a22056a41086a200520114102746a2205200241ffff037120116b410274109e081a20052018360200200a200e2f010622024f0d07201820113b01042018200e360200201120024f0d072002417f6a2113200e2011417f6a22024102746a41d0056a2105034020052802002211200241026a3b01042011200e360200200541046a21052013200241016a2202470d000c080b0b200e41086a2202200a41016a2211410574220f6a2002200a41057422126a2202200e2f01062230200a6b4105742231109e081a2002201f36000f2002201e36000b2002201d3600072002201c360003200241026a202b2d00003a0000200220072f01a4023b00002002200729039002370013200241186a200729009502370000200e41e8026a2202200f6a200220126a22022031109e081a200241186a200b290300370300200241106a200c290300370300200241086a200d290300370300200220072903a802370300200e203041016a22023b0106200a4102742212200e41c8056a220f6a41086a200f20114102746a220f200241ffff037120116b410274109e081a200f20183602002005200e2f010622114f0d00200e20126a41cc056a2102034020022802002205200a41016a220a3b01042005200e360200200241046a21022011200a470d000b0b202a41016a212a2007418c026a41026a220220102d00003a0000202320192903003703002024201a2903003703002025201b290300370300200720072f01dc053b018c02200720072903c8013703f801200720072900cd013700fd01200720072903e0053703d801202620022d00003a0000200720072f018c023b01a401200720072900fd0137009501200720072903f80137039001202720252903003703002028202429030037030020292023290300370300200720072903d8013703a8010240200e28020022020d00200741106a2102202c211c202f211f202e211e202d211d201321180c050b200e2f0104210f202c211c202f211f202e211e202d211d2002210e201321180c000b0b200a20114105746a22024180036a2205290300211520052007290358370300200241f8026a2205290300211420052007290350370300200241f0026a2205290300211620052007290348370300200241e8026a2202290300211720022007290340370300200720153703f805200720143703f005200720163703e805200720173703e0052014a72202450d0420072802f4052205450d04200541306c450d04200210350c040b20122010410574221141206a22136a201220116a2202200520106b410574109e081a200241186a200b290300370000200241106a200c290300370000200241086a200d290300370000200220072903a802370000200a41e8026a220220136a200220116a2202200a2f010620106b410574109e081a200241186a2014370300200220153703102002201637030820022017370300200a200a2f010641016a3b0106200741003602f0050c030b41d684cc00413541c086cc00103f000b2009410041f205109f081a41f80510332205450d0620054100360200200541046a200741e0056a41f405109d081a2005200228020022113602c8052002200536020020022002280204221341016a360204201141003b010420112005360200200741a8026a41026a220a20262d00003a0000200720072f01a4013b01a80220072007290390013703f80220072007290095013700fd02201b2027290300370300201a202829030037030020192029290300370300200720072903a8013703e0052013202a470d0520052f01062211410a4b0d04200520114105746a2202410a6a200a2d00003a0000200241086a20072f01a8023b0000200241176a201f360000200241136a201e3600002002410f6a201d3600002002410b6a201c3600002002411b6a20072903f802370000200241206a20072900fd02370000200241e8026a20072903e005370300200241f0026a2019290300370300200241f8026a201a29030037030020024180036a201b2903003703002005201141016a22024102746a41c8056a2018360200200520023b0106201820023b0104201820053602000b200741003602f0050b20012008460d012007280210210a0c000b0b0240024020040d004100210b0c010b20032004412c6c6a210d4100210b034020032202412c6a21030240200228020841306c2205450d002002280200220a20056a210c2002410c6a21120340200a41306a210f0240024002402007280210220e450d00200728021421010340200e41086a2105200e2f01062210410574210241002111024003402002450d01200a2005412010a0082213450d04200241606a2102201141016a2111200541206a21052013417f4a0d000b2011417f6a21100b2001450d012001417f6a2101200e20104102746a41c8056a280200210e0c000b0b417f200b41016a22022002200b491b210b0c010b200e20114105746a220241e8026a2205427f20052903002214200a2903207c221520152014542205200241f0026a22112903002214200a41286a22132903007c2005ad7c221520145420152014511b22051b3703002011427f201520051b37030020122900002114200741e0056a41086a220e201241086a290000370300200741e0056a41106a2201201241106a290000370300200741e0056a41186a2210201241186a290000370300200720143703e00520132903002114200a2903202115200241f8026a2113024020024180036a22052802002211200241fc026a280200470d00201320114101108801200528020021110b2013280200201141306c6a220220072903e00537030020022015370320200241186a2010290300370300200241106a2001290300370300200241086a200e290300370300200241286a20143703002005200528020041016a3602000b200f210a200f200c470d000b0b2003200d470d000b0b200020072903103702002000200b36020c200041086a200741106a41086a280200360200200624000f0b41af84cc00412741c086cc00103f000b41ff83cc00413041c086cc00103f000b103c000be91105077f017e047f017e097f230041a0026b2202240002400240024002400240024002400240024020012802202203450d0020012003417f6a220436022020012802042203450d02200128020821052001280200210602402001410c6a280200220720032f0106490d00034002400240200328020022080d002005ad2109410021080c010b200641016a210620033301044220862005ad8421090b200310352009a72105200821032009422088a7220720082f01064f0d000b200821030b20024190016a41186a220a200320074105746a220841206a29000037030020024190016a41106a220b200841186a29000037030020024190016a41086a220c200841106a2900003703002002200841086a29000037039001200241f0016a41086a220d20084184036a2802003602002002200841fc026a2902003703f001200741016a2107200841f0026a2903002109200841e8026a290300210e200841f8026a280200210f02402006450d00200320074102746a41c8056a2802002103410021072006417f6a2208450d00034020032802c80521032008417f6a22080d000b0b200241186a41186a200a290300370300200241186a41106a200b290300370300200241186a41086a200c29030037030020024190026a41086a200d2802003602002002200229039001370318200220022903f001370390022001200736020c200120053602082001200336020420014100360200200f0d010b20024180016a41003602000c060b200241b8016a2009370300200241c0016a200f360200200241c4016a20022903900237020020024190016a41186a200241186a41186a29030037030020024190016a41106a200241186a41106a29030037030020024190016a41086a200241186a41086a290300370300200241cc016a20024190026a41086a2802003602002002200e3703b0012002200229031837039001200241c0006a200141246a20024190016a10860220024180016a280200450d0520024190016a200241c0006a41d000109d081a417f200441016a220320032004491bad42d0007e2209422088a70d012009a72203417f4c0d01200310332210450d02201020024190016a41d000109d082108200241013602102002200341d0006e36020c20022008360208200241186a41206a200141206a2902002209370300200241186a41186a200141186a290200370300200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318024002402009a72203450d0020022003417f6a220f360238200228021c2203450d0520022802202105200228021821070240200241246a280200220620032f0106490d00034002400240200328020022080d002005ad2109410021080c010b200741016a210720033301044220862005ad8421090b200310352009a72105200821032009422088a7220620082f01064f0d000b200821030b20024190016a41186a2201200320064105746a220841206a29000037030020024190016a41106a220b200841186a29000037030020024190016a41086a220c200841106a2900003703002002200841086a2900003703900120024190026a41086a220d20084184036a2802003602002002200841fc026a29020037039002200641016a2106200841f0026a2903002109200841e8026a290300210e200841f8026a280200210a02402007450d00200320064102746a41c8056a2802002103410021062007417f6a2208450d00034020032802c80521032008417f6a22080d000b0b200241f0016a41186a2001290300370300200241f0016a41106a200b290300370300200241f0016a41086a200c290300370300200241e0016a41086a200d28020036020020022002290390013703f00120022002290390023703e00120022006360224200220053602202002200336021c20024100360218200a450d002002413c6a2111200241c4016a2104200241b8016a2112410121010340200420022903e0013702002012200937030020024190016a41186a220b200241f0016a41186a221329030037030020024190016a41106a220c200241f0016a41106a221429030037030020024190016a41086a220d200241f0016a41086a2215290300370300200441086a200241e0016a41086a22162802003602002002200e3703b001200220022903f001370390012002200a3602c001200241c0006a201120024190016a108602200228028001450d0220024190016a200241c0006a41d000109d081a02402001200228020c470d00200241086a2001417f200f41016a22082008200f491b10a301200228020821100b2010200141d0006c6a20024190016a41d000109d081a2002200141016a2201360210200f450d012002200f417f6a220f3602382003450d07410021070240200620032f0106490d00034002400240200328020022080d002005ad2109410021080c010b200741016a210720033301044220862005ad8421090b200310352009a72105200821032009422088a7220620082f01064f0d000b200821030b200b200320064105746a220841206a290000370300200c200841186a290000370300200d200841106a2900003703002002200841086a29000037039001200841f8026a280200210a20024190026a41086a221720084184036a2802003602002002200841fc026a29020037039002200641016a2106200841f0026a2903002109200841e8026a290300210e02402007450d00200320064102746a41c8056a2802002103410021062007417f6a2208450d00034020032802c80521032008417f6a22080d000b0b2013200b2903003703002014200c2903003703002015200d2903003703002016201728020036020020022002290390013703f00120022002290390023703e00120022006360224200220053602202002200336021c20024100360218200a0d000b0b20024100360280010b200241186a109e02200041086a200241086a41086a280200360200200020022903083702000c060b41958dcc00412b41c08dcc00103f000b1044000b1045000b41958dcc00412b41c08dcc00103f000b41958dcc00412b41c08dcc00103f000b20004100360208200042083702002001109e020b200241a0026a24000ba20703027f017e067f230041e0006b2203240041f7edcb00ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541e4b6c000ad4280808080b00184100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b0240024002400240412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2007109d081a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420066a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000ba50403017f027e027f230041e0006b220224000240024020002802002200290300220342c000544100200041086a29030022045022051b0d0002400240024020034280800154410020051b0d00200342808080800454410020051b0d01411020047920037942c0007c20044200521ba741037622056b4104490d022002413320054102746b3a00482001200241c8006a41011078200029030021032002200041086a290300220437030820022003370300200541706a21000340200220033c00482001200241c8006a410110782003420888200442388684210320044208882104200041016a22052000492106200521002006450d000b20022003370300200220043703082003200484500d04200241286a41146a410a360200200241346a410b360200200241106a41146a410336020020022002360240200241d0caca00360244200241c8006a41146a410036020020024203370214200241a0b3cc003602102002410b36022c200241b0b4cc003602582002420137024c20024188caca003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41b0b4cc00104c000b20022003a74102744101723b01482001200241c8006a410210780c030b20022003a74102744102723602482001200241c8006a410410780c020b41c6c9ca00413641c086cc00103f000b20022003a74102743a00482001200241c8006a410110780b200241e0006a24000bf12c080a7f017e017f047e147f017e017f017e230041d0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d00200020011085072003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00410241012000200a41306c6a220d290300220e200d41506a220f290300221056200d41086a2903002211200f41086a29030022125620112012511b220f1b200f200d41306a29030022132010200e200f1b221056200d41386a290300220e20122011200f1b221156200e2011511b22141b2013201020141b2000200a200a417f6a2215200f1b221641306c6a220d29030056200e201120141b2211200d41086a29030022125620112012511b22176a2000200c41306c6a220d290300220e200d41506a2218290300221056200d41086a2903002211201841086a29030022125620112012511b22186a2000200c410172221941306c6a220d29030022132010200e20181b221056200d41086a290300220e2012201120181b221156200e2011511b221a6a20132010201a1b2000200c200c417f6a221b20181b221c41306c6a220d29030056200e2011201a1b2211200d41086a29030022125620112012511b221d6a2000200b41306c6a220d290300220e200d41506a221e290300221056200d41086a2903002211201e41086a29030022125620112012511b221e6a200d41306a29030022132010200e201e1b221056200d41386a290300220e20122011201e1b221156200e2011511b221f6a20132010201f1b2000200b200b417f6a2220201e1b222141306c6a220d29030056200e2011201f1b2211200d41086a29030022125620112012511b22066a210d2021200b41016a2020200b201e1b201f1b20061b210b201c2019201b200c20181b201a1b201d1b210c2016200a41016a2015200a200f1b20141b20171b210a0b200d2000200c41306c6a220f290300220e2000200a41306c6a2218290300221056200f41086a2903002211201841086a29030022125620112012511b220f6a2000200b41306c6a220d29030022132010200e200f1b221056200d41086a290300220e20122011200f1b221156200e2011511b220d6a211820132010200d1b2000200c200a200f1b222141306c6a221e29030058200e2011200d1b2211201e41086a29030022125820112012511b450d01200b200a200c200f1b200d1b21210c020b200020011086070c0f0b201841016a2218410c490d0002402001410176220b450d002000200141306c6a41506a210a2000210c0340200441a0026a41286a220f200c41286a220d290300370300200441a0026a41206a2218200c41206a221e290300370300200441a0026a41186a2214200c41186a221a290300370300200441a0026a41106a221f200c41106a2215290300370300200441a0026a41086a2216200c41086a22172903003703002004200c2903003703a002200a41086a22192903002111200a41106a221b2903002112200a41186a221c290300210e200a41206a221d2903002110200a41286a22202903002113200c200a290300370300200d2013370300201e2010370300201a200e37030020152012370300201720113703002020200f290300370300201d2018290300370300201c2014290300370300201b201f29030037030020192016290300370300200a20042903a002370300200c41306a210c200a41506a210a200b417f6a220b0d000b0b20012021417f736a21214101210a0c010b201845210a0b0240200a452009724101710d00200020011087070d0d0b2002450d02202120014f0d01024020022903002000202141306c6a220a29030056200241086a2903002211200a41086a220c29030022125620112012511b450d0020002108200121070c040b200441a0026a41286a221a200041286a2218290300370300200441a0026a41206a221f200041206a221e290300370300200441a0026a41186a2215200041186a2214290300370300200441a0026a41106a2216200041106a220b290300370300200441a0026a41086a2217200041086a220f290300370300200420002903003703a002200c2903002111200a41106a220d2903002112200a41186a2219290300210e200a41206a221b2903002110200a41286a221c29030021132000200a29030037030020182013370300201e20103703002014200e370300200b2012370300200f2011370300201c201a290300370300201b201f29030037030020192015290300370300200d2016290300370300200c2017290300370300200a20042903a002370300200f29030021112000290300210e200441186a221c2018290300370300200441106a221d201e290300370300200441086a222020142903003703002004200b290300370300200041506a2119200041306a211b4100210c2001210b03400240200c200b417f6a220f4f0d00201b200c41306c6a210a0340200e200a290300582011200a41086a29030022125820112012511b450d01200a41306a210a200f200c41016a220c470d000b200f210c0b2019200b41306c6a210a02400340200c200b417f6a220b4f0d01200a2903002112200a41086a210f200a41506a220d210a200e2012562011200f29030022125620112012511b0d000b201a201b200c41306c6a220a41286a220f290300370300201f200a41206a22212903003703002015200a41186a22062903003703002016200a41106a22222903003703002017200a41086a22232903003703002004200a2903003703a002200d41386a22242903002112200d41c0006a22252903002110200d41c8006a22262903002113200d41d0006a22272903002128200d41d8006a2229290300212a200a200d41306a220d290300370300200f202a370300202120283703002006201337030020222010370300202320123703002029201a2903003703002027201f290300370300202620152903003703002025201629030037030020242017290300370300200d20042903a002370300200c41016a210c0c010b0b2000200e370300200020113703082000200429030037031020142020290300370300201e201d2903003703002018201c29030037030002402001200c41016a220a490d002000200a41306c6a21002001200a6b220141154f0d010c0c0b0b200a200141e485cc001059000b2021200141d086cc001042000b2007450d010b202120074f0d01200441a0026a41286a2217200841286a2222290300370300200441a0026a41206a2219200841206a2223290300370300200441a0026a41186a221b200841186a2224290300370300200441a0026a41106a221c200841106a2225290300370300200441a0026a41086a221d200841086a2226290300370300200420082903003703a0022008202141306c6a220a41086a220c2903002111200a41106a220b2903002112200a41186a220f290300210e200a41206a220d2903002110200a41286a220029030021132008200a29030037030020222013370300202320103703002024200e370300202520123703002026201137030020002017290300370300200d2019290300370300200f201b290300370300200b201c290300370300200c201d290300370300200a20042903a0023703002026290300211120082903002112200441186a22272022290300370300200441106a22292023290300370300200441086a2205202429030037030020042025290300370300200841306a2101410021212007417f6a220f450d022001210a0340200a290300201256200a41086a290300220e201156200e2011511b450d03200a41306a210a200f202141016a2221470d000b200f21210c020b4100410041f485cc001042000b20212007418486cc001042000b2008200741306c6a210a200f210b02400340200a2100200b220c20214d22060d01200c417f6a210b200041506a220a290300201258200a41086a290300220e201158200e2011511b0d000b0b0240200c2021490d00200f200c490d0241800121154100210d4100211a4100210f4100211441800121162001202141306c6a220921010340200020016b220a41306e210c0240200a41afe0004b22200d00200c41807f6a200c201a200d492014200f49220b7222181b210a02402018450d002016200a200b1b2116200a2015200b1b21150c010b200a200a41017622166b21150b02402014200f470d00024020160d00200441206a220f21140c010b4100210c200441206a2214210f2001210a0340200f200c3a0000200f410041014102200a2903002210201285200a41086a290300220e20118584501b2010201254200e201154200e2011511b1b41027441c4cfca006a2802006a210f200a41306a210a2016200c41016a220c470d000b0b0240201a200d470d00024020150d00200441a0016a220d211a0c010b200041506a210a4100210c200441a0016a221a210d0340200d200c3a0000200d410041014102200a2903002210201285200a41086a290300220e20118584501b2010201254200e201154200e2011511b1b41027441d0cfca006a2802006a210d200a41506a210a2015200c41016a220c470d000b0b0240200d201a6b220a200f20146b220c200c200a4b1b221f450d002017200120142d000041306c6a220a41286a2903003703002019200a41206a290300370300201b200a41186a290300370300201c200a41106a290300370300201d200a41086a2903003703002004200a2903003703a002200120142d000041306c6a220a2000201a2d0000417f7341306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a2903003703000240201f4101460d004100210b03402000201a200b6a22182d0000417f7341306c6a220a20012014200b6a41016a221e2d000041306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a2903003703002001201e2d000041306c6a220a2000201841016a2d0000417f7341306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a290300370300200b41026a210a200b41016a220c210b200a201f490d000b201a200c6a211a2014200c6a21140b2000201a2d0000417f7341306c6a220a20042903a002370300200a41286a2017290300370300200a41206a2019290300370300200a41186a201b290300370300200a41106a201c290300370300200a41086a201d290300370300201a41016a211a201441016a21140b2001201641306c6a20012014200f461b21012000410020156b41306c6a2000201a200d461b210020200d000b024002402014200f4f0d002000210a034020172001200f417f6a220f2d000041306c6a220c41286a220b2903003703002019200c41206a220d290300370300201b200c41186a2200290300370300201c200c41106a2218290300370300201d200c41086a221e2903003703002004200c2903003703a002200a41506a220a41086a221a290300210e200a41106a221f2903002110200a41186a22152903002113200a41206a22162903002128200a41286a2220290300212a200c200a290300370300200b202a370300200d20283703002000201337030020182010370300201e200e37030020202017290300370300201620192903003703002015201b290300370300201f201c290300370300201a201d290300370300200a20042903a0023703002014200f490d000c020b0b2001210a201a200d4f0d000340200d417f6a220d2d0000210c2017200a41286a220b2903003703002019200a41206a220f290300370300201b200a41186a2201290300370300201c200a41106a2218290300370300201d200a41086a221e2903003703002004200a2903003703a0022000200c417f7341306c6a220c41086a2214290300210e200c41106a221f2903002110200c41186a22152903002113200c41206a22162903002128200c41286a2220290300212a200a200c290300370300200b202a370300200f20283703002001201337030020182010370300201e200e37030020202017290300370300201620192903003703002015201b290300370300201f201c2903003703002014201d290300370300200c20042903a002370300200a41306a210a201a200d490d000b0b2008201137030820082012370300200820042903003703102024200529030037030020232029290300370300202220272903003703002007200a20096b41306e20216a22014d0d032017202229030037030020192023290300370300201b2024290300370300201c2025290300370300201d2026290300370300200420082903003703a0022008200141306c6a220a41086a220c2903002111200a41106a220b2903002112200a41186a220f290300210e200a41206a220d2903002110200a41286a220029030021132008200a29030037030020222013370300202320103703002024200e370300202520123703002026201137030020002017290300370300200d2019290300370300200f201b290300370300200b201c290300370300200c201d290300370300200a20042903a002370300200720016b220c450d04200c20012001200c4b1b210b2007410376210f200a41306a2100024002402001200c417f6a220c490d002000200c200a200310d001200821000c010b200820012002200310d001200a2102200c21010b200b200f4f2105200141154f0d010c050b0b2021200c419486cc001059000b200c200f419486cc001058000b20012007418486cc001042000b41a486cc00411c41c086cc00103f000b20014102490d00200041a07f6a210d410021184101210c0340200c41016a210f02402000200c41306c6a220b290300220e200b41506a220a29030058200b41086a221e2903002211200a41086a221429030022125820112012511b0d00200441186a221a200b41286a221f290300370300200441106a2215200b41206a2216290300370300200441086a2217200b41186a22192903003703002004200b290310370300200b200a290300370300201e2014290300370300200b41106a200a41106a2903003703002019200a41186a2903003703002016200a41206a290300370300201f200a41286a2903003703002000200c417f6a221e41306c6a211402400240201e0d004100211e0c010b2018210c200d210a200e200b41a07f6a220b290300582011200b41086a29030022125820112012511b0d00024002400340200a4188016a200a41d8006a290300370300200a4180016a200a41d0006a290300370300200a41f8006a200a41c8006a290300370300200a41f0006a200a41c0006a290300370300200a41e8006a200a41386a290300370300200a41e0006a200a41306a290300370300200c4101460d01200a2903002112200a41086a210b200c417f6a210c200a41506a210a200e2012562011200b29030022125620112012511b0d000c020b0b4100210c0b2000200c41306c6a2114200c211e0b2014200e370300201420113703082000201e41306c6a220a41286a201a290300370300200a41206a2015290300370300200a41186a2017290300370300200a20042903003703100b201841016a2118200d41306a210d200f210c200f2001470d000b0b200441d0026a24000ba20703027f017e067f230041e0006b2203240041f7edcb00ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541d2b6c000ad4280808080a00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b0240024002400240412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2007109d081a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420066a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000bac0201037f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00410021020c010b200328021421042003200341186a280200360224200320013602202003200341206a10c4010240024020032802000d0020032802042105410121020c010b4100210220034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b0b2004450d00200110350b2000200536020420002002360200200341e0006a24000ba20703027f017e067f230041e0006b2203240041f7edcb00ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541c0b6c000ad4280808080a00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b0240024002400240412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2007109d081a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420066a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000bf52a07047f017e047f027e017f027e057f230041c0026b22032400200341c8016a41186a4200370300200341c8016a41106a22044200370300200341c8016a41086a22054200370300200342003703c80141d1c4c700ad4280808080e00084100122062900002107200341e8016a41086a2208200641086a290000370300200320073703e8012006103520052008290300370300200320032903e8013703c80141e7c4c700ad4280808080e00084100122062900002107200341a0026a41086a2208200641086a290000370300200320073703a00220061035200420032903a0022207370300200341a8016a41086a2005290300370300200341a8016a41106a2007370300200341a8016a41186a2008290300370300200320032903c8013703a801200341086a200341a8016a412010c001024002400240024002402003280208450d00200328020c2209450d00200341c8016a41186a220a4200370300200341c8016a41106a220b4200370300200341c8016a41086a22054200370300200342003703c80141d1c4c700ad4280808080e00084100122062900002107200341e8016a41086a2208200641086a290000370300200320073703e8012006103520052008290300370300200320032903e8013703c8014188f2c700ad4280808080e00184100122062900002107200341a0026a41086a2208200641086a290000370300200320073703a00220061035200420032903a002370000200441086a2008290300370000200341a8016a41086a2005290300370300200341a8016a41106a200b290300370300200341a8016a41186a200a290300370300200320032903c8013703a8012003412036028c022003200341a8016a36028802200341a0026a200341a8016aad220c4280808080800484220d100510c2010240024020032802a00222060d00410321050c010b20032802a402210b02400240024020082802002208450d0020062d0000220e41024b0d004101210502400240200e0e03000401000b2008417f6a4104490d012006280001210a410021050c030b410221050c010b200341003602d001200342013703c801200341093602ec01200320034188026a3602e8012003200341c8016a3602f801200341246a410136020020034201370214200341c888c2003602102003200341e8016a360220200341f8016a41e88ac500200341106a10431a20033502d00142208620033502c801841006024020032802cc01450d0020032802c80110350b410321050b0b200b450d00200610350b200341003602d001200342013703c801200341c8016a41002001108a014102200520054103461b210b20032802d001210602402001450d0020032802c80120064105746a210520062001410574220841606a4105766a210e20002106034020052006290000370000200541086a200641086a290000370000200541106a200641106a290000370000200541186a200641186a290000370000200541206a2105200641206a2106200841606a22080d000b200e41016a21060b200341a8016a41086a2208200636020020034194016a200a360200200320032903c8013703a8012003200b36029001200341106a2002418001109d081a200341a0016a2008280200360200200320032903a80137039801200341c8016a41186a22064200370300200341c8016a41106a22024200370300200341c8016a41086a22054200370300200342003703c80141d1c4c700ad4280808080e00084220f1001220a2900002107200341e8016a41086a220b200a41086a290000370300200320073703e801200a10352005200b290300370300200320032903e8013703c8014198f0c700ad4280808080a0018422101001220a2900002107200341a0026a41086a220e200a41086a290000370300200320073703a002200a1035200420032903a002370000200441086a220a200e29030037000020082005290300370300200341a8016a41106a22112002290300370300200341a8016a41186a22122006290300370300200320032903c8013703a8012003200341a8016a412010c00102402003280204410020032802001b221341016a221420134f0d00200341106a21060c040b200642003703002002420037030020054200370300200342003703c801200f100122152900002107200b201541086a290000370300200320073703e801201510352005200b290300370300200320032903e8013703c80120101001220b2900002107200e200b41086a290000370300200320073703a002200b1035200420032903a002370000200a200e290300370000200820052903003703002011200229030037030020122006290300370300200320032903c8013703a801200320143602c801200d200341c8016aad4280808080c000841002200341003602d001200342013703c801024002400240200328029001220541024b0d0002400240024020050e03000102000b410110332205450d07200341013602cc01200320053602c801200541003a0000200341013602d00120032802940121020240024020032802cc012208417f6a4104490d004101210520032802c80121060c010b41012105200841017422064105200641054b1b220a4100480d0420032802c801210602402008200a460d0020062008200a10372206450d0920032802d00121050b2003200a3602cc01200320063602c8010b200620056a20023600002003200541046a3602d0010c020b410110332205450d06200341013602cc01200320053602c801200541013a0000200341013602d0010c010b410110332205450d05200341013602cc01200320053602c801200541023a0000200341013602d0010b200341106a200341c8016a1082062003280298012106200341a0016a2802002205200341c8016a107702402005450d002005410574210b0340412010332205450d0320052006290000370000200541186a220e200641186a290000370000200541106a2211200641106a290000370000200541086a2212200641086a2900003700000240024020032802cc01220a20032802d00122086b4120490d0020032802c80121020c010b200841206a22022008490d03200a41017422142002201420024b1b22144100480d0302400240200a0d00024020140d00410121020c020b2014103322020d010c090b20032802c8012102200a2014460d002002200a201410372202450d0820032802d00121080b200320143602cc01200320023602c8010b200641206a2106200220086a22022005290000370000200241186a200e290000370000200241106a2011290000370000200241086a20122900003700002003200841206a3602d00120051035200b41606a220b0d000b0b20032802cc01210220032802c801210820033502d0012107200341c8016a41186a220a4200370300200341c8016a41106a220b4200370300200341c8016a41086a22054200370300200342003703c80141d1c4c700ad4280808080e0008410012206290000210d200341e8016a41086a220e200641086a2900003703002003200d3703e801200610352005200e290300370300200320032903e8013703c80141cccfc700ad4280808080e0008410012206290000210d200341a0026a41086a220e200641086a2900003703002003200d3703a00220061035200420032903a002370000200441086a200e290300370000200341a8016a41086a2005290300370300200341a8016a41106a200b290300370300200341a8016a41186a200a290300370300200320032903c8013703a801200c428080808080048420074220862008ad84102202402002450d00200810350b2001450d0320014105742112200341a8016a41106a210441d1c4c700ad4280808080e00084210c41d2cfc700ad4280808080b00184210d0340200c100122052900002107200341e8016a41086a220e200541086a290000370300200320073703e80120051035200d100122052900002107200341a0026a41086a2211200541086a290000370300200320073703a00220051035412010332205450d0220052000290000370000200541186a200041186a290000370000200541106a200041106a290000370000200541086a200041086a2900003700002005ad4280808080800484100422062900002107200341a8016a41086a2214200641086a290000370300200320073703a801200610352003200541206a3602d401200320053602d001200320043602cc012003200341a8016a3602c80120034188026a200341c8016a107b2005103502400240024002400240024002400240200328029002220a41206a2206417f4c0d00200328028802210b0240024020060d0041002108410121050c010b200610332205450d0b200621080b024002402008410f4d0d00200821020c010b200841017422024110200241104b1b22024100480d0a024020080d00200210332205450d0f0c010b20082002460d0020052008200210372205450d0e0b200520032903e801370000200541086a200e2903003700000240024020024170714110460d00200221080c010b200241017422084120200841204b1b22084100480d0a20022008460d0020052002200810372205450d0e0b200520032903a002370010200541186a201129030037000002400240200841606a200a490d00200821020c010b200a415f4b0d0a200841017422022006200220064b1b22024100480d0a20082002460d0020052008200210372205450d0e0b200541206a200b200a109d081a0240200328028c02450d00200b10350b200341a8016a2006ad4220862005ad842207100510c2010240024020032802a801450d00200341f8016a41086a2014280200360200200320032903a8013703f8010c010b410410332206450d0b200342043702cc01200320063602c8014100200341c8016a1077200341f8016a41086a20032802d001360200200320032903c8013703f8010b20034188026a41086a200341f8016a41086a2802002206360200200320032903f80137038802024002400240024002402006450d00200341c8016a2003280288022006410110f10420032802c8014101460d0420032802cc01210b20032802d401220820032802d001220a460d0320062008200a6b6a220641046a220e417f4c0d05200e0d014100210e410121110c020b410120034188026a107702400240200328028c02220a20032802900222066b4104490d0020032802880221080c010b200641046a22082006490d0e200a410174220b2008200b20084b1b220b4100480d0e02400240200a0d000240200b0d00410121080c020b200b10332208450d140c010b2003280288022108200a200b460d002008200a200b10372208450d1320032802900221060b2003200b36028c0220032008360288020b200820066a20093600002003200641046a22063602900202400240200328028c02220a20066b4104490d0020032802880221080c010b200641046a22082006490d0e200a410174220b2008200b20084b1b220b4100480d0e02400240200a0d000240200b0d00410121080c020b200b10332208450d140c010b2003280288022108200a200b460d002008200a200b10372208450d1320032802900221060b2003200b36028c0220032008360288020b200820066a2013360000200641046a21080c090b200e10332211450d0d0b200320113602e8012003200e3602ec01200320063602f0012003200341e8016a3602c801200b200341c8016a200810f20420062008490d0320032802f001220b2006490d04200328029002220b200a490d0520032802e801210e20032802880221112003200620086b2206360298022003200b200a6b220b36029c022006200b470d06200e20086a2011200a6a2006109d081a0240024020032802ec01220a20032802f00122066b4104490d0020032802e80121080c010b200641046a22082006490d0c200a410174220b2008200b20084b1b220b4100480d0c02400240200a0d000240200b0d00410121080c020b200b10332208450d120c010b20032802e8012108200a200b460d002008200a200b10372208450d1120032802f00121060b2003200b3602ec01200320083602e8010b200820066a20093600002003200641046a22063602f0010240024020032802ec01220a20066b4104490d0020032802e80121080c010b200641046a22082006490d0c200a410174220b2008200b20084b1b220b4100480d0c02400240200a0d000240200b0d00410121080c020b200b10332208450d120c010b20032802e8012108200a200b460d002008200a200b10372208450d1120032802f00121060b2003200b3602ec01200320083602e8010b200820066a2013360000200641046a210820032802e801210620032802ec01210a200328028c02450d0820032802880210350c080b200320034188026a3602c801200b200341c8016a200a10f20402400240200328028c02220a20032802900222066b4104490d0020032802880221080c010b200641046a22082006490d0b200a410174220b2008200b20084b1b220b4100480d0b02400240200a0d000240200b0d00410121080c020b200b10332208450d110c010b2003280288022108200a200b460d002008200a200b10372208450d1020032802900221060b2003200b36028c0220032008360288020b200820066a20093600002003200641046a22063602900202400240200328028c02220a20066b4104490d0020032802880221080c010b200641046a22082006490d0b200a410174220b2008200b20084b1b220b4100480d0b02400240200a0d000240200b0d00410121080c020b200b10332208450d110c010b2003280288022108200a200b460d002008200a200b10372208450d1020032802900221060b2003200b36028c0220032008360288020b200820066a2013360000200641046a21080c060b200328028c02450d0720032802880210350c070b1044000b2008200641e88cc5001059000b2006200b41e88cc5001058000b200a200b41f88cc5001059000b200341a8016a41146a410a360200200341b4016a410c360200200341a0026a41146a4103360200200320034198026a3602b80220032003419c026a3602bc02200341c8016a41146a4100360200200342033702a402200341a0b3cc003602a0022003410c3602ac01200341b0b4cc003602d801200342013702cc01200341f4b3cc003602c8012003200341a8016a3602b0022003200341c8016a3602b8012003200341bc026a3602b0012003200341b8026a3602a801200341a0026a41b0b4cc00104c000b2003200836029002200328028c02210a20032802880221060b2006450d0020072008ad4220862006ad8410020240200a450d00200610350b02402002450d00200510350b200041206a2100201241606a22120d010c050b0b200341106a21062002450d05200510350c050b103e000b1045000b20021097060c030b200341106a1097062003419c016a28020041ffffff3f71450d0220032802980110350c020b103c000b20061097062003419c016a28020041ffffff3f71450d0020032802980110350b200341c0026a24000bd50302047f047e230041f0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022040d00200041003a00000c010b200341186a28020021052003280214210641002101200341003a006802400240034020052001460d01200341c8006a20016a200420016a2d00003a00002003200141016a22023a00682002210120024120470d000b200341206a41186a200341c8006a41186a2903002207370300200341206a41106a200341c8006a41106a2903002208370300200341206a41086a200341c8006a41086a290300220937030020032003290348220a370320200041196a2007370000200041116a2008370000200041096a20093700002000200a370001410121010c010b0240200141ff0171450d00200341003a00680b410021012003410036022820034201370320200341093602442003200341086a3602402003200341206a36026c200341dc006a41013602002003420137024c200341c888c2003602482003200341c0006a360258200341ec006a41e88ac500200341c8006a10431a200335022842208620033502208410062003280224450d00200328022010350b200020013a00002006450d00200410350b200341f0006a24000b970b06047f057e027f017e027f027e230041f0016b220324002003200236026420032001360260200341e8006a2002ad4220862001ad84100510c201024002400240200328026822040d00200041003602200c010b200328026c21052003200341f0006a280200220636029c01200320043602980141002101200341003a00e8010240024002400240034020062001460d01200341c8016a20016a200420016a22022d00003a00002003200241016a360298012003200141016a22023a00e8012002210120024120470d000b200341a8016a41086a200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200341a8016a41186a200341c8016a41186a290300370300200320032903c8013703a8012003200620026b36029c01200341c8006a20034198016a10f6012003290348a70d02200341c8006a41106a290300210720032903502108200341306a20034198016a10f6012003290330a70d02200341306a41106a29030021092003290338210a200341286a20034198016a10c40120032802280d02200328022c2206200328029c0141186e2201200120064b1bad42187e220b422088a7450d010c050b2003410036029c01200141ff0171450d01200341003a00e8010c010b200ba72202417f4c0d03024002400240024002400240024020020d004108210c0c010b20021033220c450d010b41002101200341003602d0012003200c3602c8012003200241186e22023602cc0102400240024002402006450d0041002101200341206a210d0340200341106a20034198016a10f6012003290310a70d02200d290300210b2003290318210e200341086a20034198016a10c40120032802080d02200328020c210f0240200120032802cc01470d00200341c8016a20014101109c0120032802c801210c20032802d00121010b200c200141186c6a2202200f3602102002200b3703082002200e3703002003200141016a22013602d0012006417f6a22060d000b20032802cc0121020b200c450d08200320034198016a10c40120032802000d06200328029c01220d20032802044102742206490d062006417f4c0d0b20060d014200210b4101210f0c020b20032802cc012201450d07200141186c0d060c070b20061039220f450d01200f20032802980122102006109d081a2003200d20066b36029c012003201020066a360298012006ad210b0b200f450d030240200b2006ad42208684220b422088a722060d00200ba721060c020b0240200f2006724103710d00200ba722064103710d002006410276220d450d02200b422288a721100c030b200ba7450d03200f10350c030b1045000b4100211002402006450d00200f10350b4100210d4104210f0b41000d00200f450d00200341f8006a41186a200341a8016a41186a290300220b370300200341f8006a41106a200341a8016a41106a290300220e370300200341f8006a41086a200341a8016a41086a2903002211370300200320032903a8012212370378200041186a20093703002000200a3703102000200737030820002008370300200041346a2010360200200041306a200d3602002000412c6a200f360200200041286a2001360200200020023602242000200c360220200041386a2012370300200041c0006a2011370300200041c8006a200e370300200041d0006a200b3703000c030b2002450d01200241186c450d010b200c10350b200341003602b001200342013703a8012003410936027c2003200341e0006a3602782003200341a8016a3602a401200341dc016a4101360200200342013702cc01200341c888c2003602c8012003200341f8006a3602d801200341a4016a41e88ac500200341c8016a10431a20033502b00142208620033502a801841006024020032802ac01450d0020032802a80110350b200041003602200b2005450d00200410350b200341f0016a24000f0b1044000ba80202017f037e230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822010d00420021040c010b200328020c210202400240200341086a41086a2802004110490d00200141086a290000210520012900002106420121040c010b20034100360220200342013703182003410936022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341c888c2003602382003200341286a360248200341346a41e88ac500200341386a10431a200335022042208620033502188410060240200328021c450d00200328021810350b420021040b2002450d00200110350b2000200637030820002004370300200041106a2005370300200341d0006a24000b9f4014047f017e017f017e017f017e057f017e087f017e037f017e017f017e077f027e037f017e037f067e230041e0036b22012400200141e0026a41186a22024200370300200141e0026a41106a22034200370300200141e0026a41086a22044200370300200142003703e00241f7edcb00ad4280808080f000842205100122062900002107200141d0006a41086a2208200641086a290000370300200120073703502006103520042008290300370300200120012903503703e00241eeedcb00ad428080808090018422071001220629000021092008200641086a2900003703002001200937035020061035200320012903502209370300200141a8016a41086a220a2004290300370300200141a8016a41106a220b2009370300200141a8016a41186a220c2008290300370300200120012903e0023703a801200141e0026a200141a8016a10ac012003280200210d20012903e0022109200242003703002003420037030020044200370300200142003703e00220051001220629000021052008200641086a290000370300200120053703502006103520042008290300370300200120012903503703e00220071001220629000021052008200641086a2900003703002001200537035020061035200320012903502205370300200a2004290300370300200b2005370300200c2008290300370300200120012903e0023703a80102400240410410332208450d0020084100200d41016a20094202511b220e36000020084104410810372208450d0041002102200841003a0004200141a8016aad220f42808080808004842008ad4280808080d00084100220081035200141e0026a41186a220a4200370300200141e0026a41106a220b4200370300200141e0026a41086a22044200370300200142003703e00241f7edcb00ad4280808080f00084100122062900002105200141d0006a41086a2208200641086a290000370300200120053703502006103520042008290300370300200120012903503703e00241aeeecb00ad4280808080a001841001220629000021052008200641086a290000370300200120053703502006103520032001290350370000200341086a2008290300370000200141a8016a41086a2004290300370300200141a8016a41106a200b290300370300200141a8016a41186a200a290300370300200120012903e0023703a801200141a0026a200141a8016a10d90102400240024020012802a00222100d00200141003602900120014204370388010c010b20012902a402210520012010360288012001200537028c012005422088a722082005a72202470d010b20014188016a20024101109001200128028801211020012802900121080b201020084103746a220420003602042004200e3602002001200841016a2211360290010240024002400240200e41a1054f0d00201121120c010b024020110d004100211220014100360290010c010b200e41e07a6a2104200841ffffffff017141016a2106410021132010210802400340200828020020044f0d01200841086a21082006201341016a2213470d000b0b0240024020112013490d004100211220014100360290012013450d0120134103742114200141a0026aad4280808080c000842105200141a4026a2115200141d0006a41086a21162010210c0340200c280200210d41f7edcb00ad4280808080f00084220710012208290000210920014180026a41086a2200200841086a29000037030020012009370380022008103541d6a9c000ad4280808080b0028410012208290000210920014190026a41086a220a200841086a2900003703002001200937039002200810352001200d3602a002200120051003220829000037035020081035200120153602ec02200120163602e4022001200141a0026a3602e8022001200141d0006a3602e002200141a8016a200141e0026a107b20012802b001220b41206a2204417f4c0d0720012802a80121170240024020040d0041002106410121080c010b200410332208450d06200421060b024002402006410f4d0d00200621020c010b200641017422024110200241104b1b22024100480d05024020060d002002103322080d010c080b20062002460d0020082006200210372208450d070b2008200129038002370000200841086a20002903003700000240024020024170714110460d00200221060c010b200241017422064120200641204b1b22064100480d0520022006460d0020082002200610372208450d070b2008200129039002370010200841186a200a29030037000002400240200641606a200b490d00200621020c010b2004200b490d05200641017422022004200220044b1b22024100480d0520062002460d0020082006200210372208450d070b200841206a2017200b109d081a024020012802ac01450d00201710350b2004ad4220862008ad84100802402002450d00200810350b20071001220829000021072000200841086a29000037030020012007370380022008103541e9a9c000ad4280808080b00284100122082900002107200a200841086a2900003703002001200737039002200810352001200d3602a002200120051003220829000037035020081035200120153602ec02200120163602e4022001200141a0026a3602e8022001200141d0006a3602e002200141a8016a200141e0026a107b20012802b001220b41206a2204417f4c0d0720012802a801210d0240024020040d0041002106410121080c010b200410332208450d06200421060b024002402006410f4d0d00200621020c010b200641017422024110200241104b1b22024100480d05024020060d00200210332208450d080c010b20062002460d0020082006200210372208450d070b2008200129038002370000200841086a20002903003700000240024020024170714110460d00200221060c010b200241017422064120200641204b1b22064100480d0520022006460d0020082002200610372208450d070b2008200129039002370010200841186a200a29030037000002400240200641606a200b490d00200621020c010b200b415f4b0d05200641017422022004200220044b1b22024100480d0520062002460d0020082006200210372208450d070b200841206a200d200b109d081a024020012802ac01450d00200d10350b2004ad4220862008ad84100802402002450d00200810350b200c41086a210c201441786a22140d000c020b0b20132011104f000b201120136b2214450d0002402013450d002010201020134103746a2014410374109e081a0b200120143602900120102802042112200141e0026a41186a4200370300200141e0026a41106a22134200370300200141e0026a41086a22084200370300200142003703e00241a3edcb00ad4280808080f0008410012204290000210520014180026a41086a2206200441086a2900003703002001200537038002200410352008200629030037030020012001290380023703e00241aaedcb00ad4280808080b0018410012204290000210520014190026a41086a2206200441086a29000037030020012005370390022004103520132001290390022205370300200141a0026a41086a2008290300370300200141a0026a41106a2005370300200141a0026a41186a2006290300370300200120012903e0023703a002200141e0026a200141a0026a412010da014101210820012902e40221180240024020012802e00222044101460d00200441014621080c010b2018422088a722112012201220114b1b22172018a72200490d000240201720004d0d00200141a0026aad4280808080c000842107200141a4026a2115200141d0006a41086a211641a3edcb00ad4280808080f0008421090340200910012208290000210520014180026a41086a220c200841086a2900003703002001200537038002200810354196eaca00ad4280808080a0028410012208290000210520014190026a41086a220d200841086a290000370300200120053703900220081035200120003602a002200120071003220829000037035020081035200120153602ec02200120163602e4022001200141a0026a3602e8022001200141d0006a3602e002200141a8016a200141e0026a107b20012802b001220a41206a2204417f4c0d0720012802a801210b0240024020040d0041002106410121080c010b200410332208450d06200421060b024002402006410f4d0d00200621020c010b200641017422024110200241104b1b22024100480d05024020060d00200210332208450d080c010b20062002460d0020082006200210372208450d070b2008200129038002370000200841086a200c2903003700000240024020024170714110460d00200221060c010b200241017422064120200641204b1b22064100480d0520022006460d0020082002200610372208450d070b2008200129039002370010200841186a200d29030037000002400240200641606a200a490d00200621020c010b200a415f4b0d05200641017422022004200220044b1b22024100480d0520062002460d0020082006200210372208450d070b200841206a200b200a109d081a024020012802ac01450d00200b10350b200041016a21002004ad4220862008ad84100702402002450d00200810350b20172000470d000b0b201220114921082018428080808070832017ad8421180b200120183702ac01200120083602a8010240024020080d00200141e0026a41186a22064200370300200141e0026a41106a22024200370300200141e0026a41086a22084200370300200142003703e00241a3edcb00ad4280808080f0008410012204290000210520014180026a41086a2200200441086a2900003703002001200537038002200410352008200029030037030020012001290380023703e00241aaedcb00ad4280808080b0018410012204290000210520014190026a41086a2200200441086a2900003703002001200537039002200410352013200129039002370000201341086a2000290300370000200141a0026a41086a2008290300370300200141a0026a41106a2002290300370300200141a0026a41186a2006290300370300200120012903e0023703a002200141a0026aad428080808080048410070c010b200141e0026a41186a22064200370300200141e0026a41106a22024200370300200141e0026a41086a22084200370300200142003703e00241a3edcb00ad4280808080f0008410012204290000210520014180026a41086a2200200441086a2900003703002001200537038002200410352008200029030037030020012001290380023703e00241aaedcb00ad4280808080b0018410012204290000210520014190026a41086a2200200441086a2900003703002001200537039002200410352013200129039002370000201341086a2000290300370000200141a0026a41086a2008290300370300200141a0026a41106a2002290300370300200141a0026a41186a2006290300370300200120012903e0023703a002200141203602e4022001200141a0026a3602e002200141a8016a410472200141e0026a10db010b201421120b200128028c012115200141e0026a41186a22024200370300200141e0026a41106a22004200370300200141e0026a41086a22044200370300200142003703e00241f7edcb00ad4280808080f00084100122062900002105200141d0006a41086a2208200641086a290000370300200120053703502006103520042008290300370300200120012903503703e00241aeeecb00ad4280808080a001841001220629000021052008200641086a290000370300200120053703502006103520032001290350370000200341086a2008290300370000200141a8016a41086a2004290300370300200141a8016a41106a2000290300370300200141a8016a41186a2002290300370300200120012903e0023703a8010240024020100d00200f428080808080048410070c010b20124103744104722208417f4c0d04200810332204450d02200141003602e802200120083602e402200120043602e0022012200141e0026a10770240024020120d0020012802e802210820012802e00221020c010b201020124103746a2114410020012802e802220b6b210020012802e4022104410021080340200b20086a210a201020086a220c280200210d02400240200420006a4104490d0020012802e0022102200421060c010b200a41046a2206200a490d04200441017422022006200220064b1b22064100480d040240024020040d00024020060d00410121020c020b200610332202450d080c010b20012802e002210220042006460d0020022004200610372202450d070b200120063602e402200120023602e0020b2002200b6a20086a200d3600002001200a41046a22043602e802200c41046a280200210d02400240200620006a417c6a41034d0d00200621040c010b200441046a22172004490d04200641017422042017200420174b1b22044100480d040240024020060d00024020040d00410121020c020b200410332202450d080c010b20062004460d0020022006200410372202450d070b200120043602e402200120023602e0020b2002200b6a20086a41046a200d3600002001200a41086a3602e802200041786a2100200841086a2108200c41086a2014470d000b200b20086a21080b20012802e4022104200f42808080808004842008ad4220862002ad84100202402004450d00200210350b201541ffffffff0171450d00201010350b200141e0026a41186a22194200370300200141e0026a41106a221a4200370300200141e0026a41086a221b4200370300200142003703e00241f7edcb00ad4280808080f00084221c100122082900002105200141d0006a41086a221d200841086a2900003703002001200537035020081035201b201d290300370300200120012903503703e00241b8eecb00ad4280808080e00284221e100122082900002105201d200841086a290000370300200120053703502008103520032001290350370000200341086a221f201d290300370000200141a8016a41086a2220201b290300370300200141a8016a41106a2221201a290300370300200141a8016a41186a22222019290300370300200120012903e0023703a801200141c8006a200141a8016a412010c001200128024c21230240200128024822244101470d00024020234100200e41d87e6a22082008200e4b1b22254f0d00200141e0026aad42808080808002842126200141a0026aad42808080808004842127200141e0026a41106a210a200141e0016a2128200141a8016a41246a2100200141e0026a41286a2114202321290340200141a8016a202910dc01200141e0026a20012802a801220820012802b001220410dd010240024020012802e002222a0d004200212b4108212a0c010b2004ad4220862008ad84100720012902e402212b0b024020012802ac01450d00200810350b202a202b422088a7220841d8006c6a2117202a210202402008450d000340200141a8016a41186a2208200241186a290300370300200141a8016a41106a2204200241106a290300370300200141a8016a41086a2206200241086a2903003703002002280220210c20022903002105200141e0026a41206a2210200241c4006a2902003703002014200241cc006a290200370300200141e0026a41306a2215200241d4006a280200360200200141e0026a41086a220b2002412c6a290200370300200a200241346a290200370300200141e0026a41186a220d2002413c6a290200370300200120053703a8012001200241246a2902003703e002200241d8006a2102200c450d0120014188016a41186a2216200829030037030020014188016a41106a2213200429030037030020014188016a41086a220e2006290300370300200141d0006a41086a2212200b290300370300200141d0006a41106a2211200a290300370300200141d0006a41186a222c200d290300370300200141d0006a41206a222d2010290300370300200141d0006a41286a22102014290300370300200141d0006a41306a222e2015280200360200200120012903a80137038801200120012903e00237035020082016290300370300200420132903003703002006200e29030037030020002001290350370200200041086a2012290300370200200041106a2011290300370200200041186a202c290300370200200041206a202d290300370200200041286a2010290300370200200041306a202e28020036020020012001290388013703a8012001200c3602c801200142003703c802200142003703c002200120082903003703d802200120042903003703d002202820012903a8012006290300200141d0026a200141c0026a10de01024020012802d0012208450d00200841306c2104200c210803402008200841206a290300200841286a290300200141d0026a200141c0026a10de01200841306a2108200441506a22040d000b0b200141c0026a41086a290300212f20012903c002213020012802d4012110024002400240024020012903d0022207200141d0026a41086a290300220584500d0020012802dc012208450d00200141386a203020072030200754202f200554202f2005511b22041b2231202f200520041b22322008ad420010980820084105742104200141386a41086a29030021092001290338213320312105203221072010210803402008203320052005203356200720095620072009511b22061b22182009200720061b223410df01200720347d2005201854ad7d2107200520187d2105200841206a2108200441606a22040d000b427f203020317d220920057c220520052009542208202f20327d2030203154ad7d220520077c2008ad7c220720055420072005511b22081b2205427f200720081b2207844200520d01200d4200370300200a4200370300200b4200370300200142003703e00241b6fdc600ad4280808080800184220510012204290000210720014180026a41086a2208200441086a290000370300200120073703800220041035200b200829030037030020012001290380023703e00241e489c200ad4280808080d00184220710012206290000210920014190026a41086a2204200641086a290000370300200120093703900220061035200a200129039002370000200a41086a22162004290300370000200141a0026a41086a2213200b290300370300200141a0026a41106a220e200a290300370300200141a0026a41186a2212200d290300370300200120012903e0023703a002200141206a200141a0026a412010d701200141206a41106a29030021092001290328211820012802202106200d4200370300200a4200370300200b4200370300200142003703e00220051001221529000021052008201541086a290000370300200120053703800220151035200b200829030037030020012001290380023703e00220071001220829000021052004200841086a290000370300200120053703900220081035200a200129039002370000201620042903003700002013200b290300370300200e200a2903003703002012200d290300370300200120012903e0023703a00220012009420020061b3703e80220012018420020061b3703e0022027202610020c030b2030202f844200520d01200d4200370300200a4200370300200b4200370300200142003703e00241b6fdc600ad4280808080800184220510012204290000210720014180026a41086a2208200441086a290000370300200120073703800220041035200b200829030037030020012001290380023703e00241e489c200ad4280808080d00184220710012206290000210920014190026a41086a2204200641086a290000370300200120093703900220061035200a200129039002370000200a41086a22162004290300370000200141a0026a41086a2213200b290300370300200141a0026a41106a220e200a290300370300200141a0026a41186a2212200d290300370300200120012903e0023703a002200141086a200141a0026a412010d701200141086a41106a29030021092001290310211820012802082106200d4200370300200a4200370300200b4200370300200142003703e00220051001221529000021052008201541086a290000370300200120053703800220151035200b200829030037030020012001290380023703e00220071001220829000021052004200841086a290000370300200120053703900220081035200a200129039002370000201620042903003700002013200b290300370300200e200a2903003703002012200d290300370300200120012903e0023703a00220012009420020061b3703e80220012018420020061b3703e0022027202610020c020b200142f0f2bda1a7ee9cb9f9003703a002200141e0026a200141a0026a10e001200141e0026a2005200710df01200d2007370300200120053703f002200141063a00e8022001410c3a00e00241b0b4cc004100200141e0026a10d4010c010b200142f0f2bda1a7ee9cb9f9003703a002200141e0026a200141a0026a10e001200141e0026a2030202f10df01200d202f370300200120303703f002200141063a00e8022001410c3a00e00241b0b4cc004100200141e0026a10d4010b024020012802cc012208450d00200841306c450d00200c10350b024020012802d80141ffffff3f71450d00201010350b20022017470d000b201721020b202ba72104024020172002460d0003400240200241246a2802002208450d00200841306c450d00200241206a28020010350b200241d8006a21080240200241306a28020041ffffff3f71450d002002412c6a28020010350b2008210220172008470d000b0b202941016a212902402004450d00200441d8006c450d00202a10350b20292025470d000b0b20232025202320254b1b21230b20194200370300201a4200370300201b4200370300200142003703e002201c100122082900002105201d200841086a2900003703002001200537035020081035201b201d290300370300200120012903503703e002201e100122082900002105201d200841086a290000370300200120053703502008103520032001290350370000201f201d2903003700002020201b2903003703002021201a29030037030020222019290300370300200120012903e0023703a8010240024020240d00200f428080808080048410070c010b200120233602e002200f4280808080800484200141e0026aad4280808080c0008410020b200141e0036a24000f0b103e000b1045000b103c000b1044000bed0401097f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c2010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c4010240024020022802000d0020022802042205200228022422064103762201200120054b1b22014103742207417f4c0d030240024020010d00410421080c010b200710332208450d050b200241003602502002200136024c200220083602480240024002402005450d004100210103402002410036022820064104490d0320022002280220220741046a36022020072800002109200241003602282006417c6a4104490d022002200741086a3602202007280004210702402001200228024c470d00200241c8006a2001410110900120022802482108200228025021010b200641786a2106200820014103746a220a2007360204200a20093602002002200141016a22013602502005417f6a22050d000b200220063602240b2008450d022000200229024c370204200020083602000c030b2006417c6a21060b20022006360224200228024c41ffffffff0171450d00200810350b20024100360230200242013703282002410936023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b200041003602000b2004450d00200310350b200241e0006a24000f0b1044000b1045000bbb0201037f230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822010d00200041003602000c010b200341106a2802002102200328020c2104200341003602380240024020024104490d0020012800002105200341003602382002417c714104460d00200041086a200128000436020020002005360204410121020c010b20034100360220200342013703182003410936022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341c888c2003602382003200341286a360248200341346a41e88ac500200341386a10431a200335022042208620033502188410060240200328021c450d00200328021810350b410021020b200020023602002004450d00200110350b200341d0006a24000b3c01017f02404108103322020d001045000b200220002802003600002002200028020436000420012902002002ad42808080808001841002200210350bfc0403027f017e057f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541efb6c000ad4280808080800284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000b800b06057f017e077f017e037f037e230041e0016b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c2010240024002400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360224200320043602202003200341206a10c40102400240024020032802000d00200328020422062003280224220741d8006e2201200120064b1bad42d8007e2208422088a70d042008a72201417f4c0d040240024020010d00410821090c010b200110332209450d060b4100210a20034100360230200320093602282003200141d8006e36022c02402006450d004100210b034041002101200341003a00d801200b41016a210b02400240024002400240034020072001460d01200341b8016a20016a2003280220220c2d00003a00002003200c41016a3602202003200141016a22023a00d8012002210120024120470d000b20034198016a41086a220d200341b8016a41086a29030037030020034198016a41106a220e200341b8016a41106a29030037030020034198016a41186a220f200341b8016a41186a290300370300200320032903b801370398012003200720026b220136022420014110490d032003200c41116a3602202003200141706a360224200c41096a2900002108200c2900012110200341b8016a200341206a10aa0220032802b801220c450d0320032802c001211120032802bc012102200341b8016a200341206a10c30120032802b80122070d012002450d03200241306c0d020c030b20034100360224200141ff0171450d02200341003a00d8010c020b20032802bc01211220032802242201410f4b0d020240201241ffffff3f71450d00200710350b2002450d01200241306c450d010b200c10350b200341d8006a41086a200341f8006a41086a2903003703000240200a450d00200a41d8006c2102200941306a210103400240200141746a280200220c450d00200c41306c450d00200141706a28020010350b0240200128020041ffffff3f71450d002001417c6a28020010350b200141d8006a2101200241a87f6a22020d000b0b200328022c2201450d03200141d8006c450d03200910350c030b20032802c0012113200341d8006a41086a200d2903002214370300200341d8006a41106a200e2903002215370300200341d8006a41186a200f2903002216370300200341386a41186a220d2016370300200341386a41106a220e2015370300200341386a41086a220f20143703002003200141706a36022420032003280220220141106a3602202003200329039801221437035820032014370338200141086a2900002114200129000021150240200a200328022c470d00200341286a200a4101109b01200328022821092003280230210a0b2009200a41d8006c6a2201201537031020012008370308200120103703002001200c360220200141186a2014370300200141346a2013360200200141306a20123602002001412c6a2007360200200141286a2011360200200141246a2002360200200141386a2003290338370200200141c0006a200f290300370200200141c8006a200e290300370200200141d0006a200d2903003702002003200a41016a220a360230200b2006460d01200328022421070c000b0b20090d010b200341003602a00120034201370398012003410936027c2003200341086a360278200320034198016a360258200341cc016a4101360200200342013702bc01200341c888c2003602b8012003200341f8006a3602c801200341d8006a41e88ac500200341b8016a10431a20033502a0014220862003350298018410060240200328029c01450d0020032802980110350b200041003602000c010b2000200329022c370204200020093602000b2005450d00200410350b200341e0016a24000f0b1044000b1045000b8d22020f7f137e23004190066b22052400200541386a200010b401200541e0046a20052802382206200528024010d501200541e0036a41086a2207200541e9046a290000370300200541e0036a41106a2208200541f1046a290000370300200541e0036a41186a2209200541f9046a290000370300200520052900e1043703e0034100210a024020052d00e0044101470d00200541e0026a41186a2009290300370300200541e0026a41106a2008290300370300200541e0026a41086a2007290300370300200520052903e0033703e0024101210a0b0240200528023c450d00200610350b02400240200a450d00200541186a41186a200541e0026a41186a2206290300370300200541186a41106a200541e0026a41106a2207290300370300200541186a41086a200541e0026a41086a2208290300370300200520052903e002370318200541f0016a200541186a10b701200541e0046a20052802f001220920052802f80110d601200541a0016a41086a220b200541e0046a41086a290300370300200541a0016a41106a220c200541e0046a41106a290300370300200541a0016a41186a220d200541e0046a41186a290300370300200541e0036a41086a220e2005418c056a290200370300200541e0036a41106a220f20054194056a290200370300200541e0036a41186a22102005419c056a290200370300200541e0036a41206a2211200541a4056a290200370300200541e0036a41286a2212200541ac056a290200370300200541e0036a41306a2213200541b4056a280200360200200520052903e0043703a00120052005290284053703e0030240200528028005220a450d00200541a8026a41186a200d290300370300200541a8026a41106a200c290300370300200541a8026a41086a200b2903003703002008200e2903003703002007200f29030037030020062010290300370300200541e0026a41206a2011290300370300200541e0026a41286a2012290300370300200541e0026a41306a2013280200360200200520052903a0013703a802200520052903e0033703e0020b024020052802f401450d00200910350b200a450d00200541dc006a20052903e002370200200541386a41186a2206200541a8026a41186a290300370300200541386a41106a2207200541a8026a41106a290300370300200541386a41086a2208200541a8026a41086a290300370300200541e4006a200541e0026a41086a290300370200200541ec006a200541e0026a41106a290300370200200541f4006a200541e0026a41186a290300370200200541fc006a20054180036a29030037020020054184016a200541e0026a41286a2903003702002005418c016a20054190036a280200360200200520052903a8023703382005200a36025820082903002114200529033821150240024020072903002216200120162001542006290300221720025420172002511b22071b22182017200220071b22198450450d002015211a2014211b0c010b2006201720197d2016201854ad7d221c3703002005201620187d221a37034802400240201a428080e983b1de1656201c420052201c501b450d0020182116201921170c010b200541d0006a420037030020054200370348201c20027c201a20017c2201201a54ad7c21020b20054200201420177d2015201654ad7d2218201520167d221c201556201820145620182014511b22061b221b37034020054200201c20061b221a370338200220177d2001201654ad7d2102200120167d21010b02400240200541386a41286a28020022060d004100210a410021060c010b200641186c21084100210603400240200a2903002216200120012016562002200a41086a220929030022175620022017511b22071b22182017200220071b221984500d00200a201620187d221a370300200a201720197d2016201854ad7d221c37030802400240201a428080e983b1de1656201c420052201c501b450d002001211c20182116201921170c010b200a4200370308200a42003703002002201c7c2001201a7c221c200154ad7c21020b200541386a41086a220742002007290300220120177d20052903382218201654ad7d2219201820167d221a201856201920015620192001511b22071b221b37030020054200201a20071b221a370338200220177d201c201654ad7d2102201c20167d210120092903002117200a29030021160b024020162017844200520d00200a41186a210a200641016a2106200841686a22080d010b0b2005280260220a2006490d020b200541003602600240200a20066b220a450d0002402006450d00200528025822072007200641186c6a200a41186c109e081a0b2005200a3602600b024042002015201a7d221620162015562014201b7d2015201a54ad7d221620145620162014511b220a1b220242002016200a1b220184500d0020054190016a2000108e02200541a0016a20052802900122062005280298012208108f0220052903a001211b200542003703a001200541e8016a280200210920052d00ec01210b02400240201b4201510d004200211c200541f0016a41306a4200370300200541f0016a41286a4200370300200541f0016a41206a4200370300200541f0016a41186a420037030020054180026a4200370300200541f8016a4200370300200542003703f0014200211942002117420021164200211d0c010b200541d8016a2903002118200541a0016a41306a290300211a200541a0016a41206a2903002119200541a0016a41186a290300211c200541e0016a290300211d20052903b001211620052903a8012117200541f0016a41206a200541a0016a41286a290300370300200541f0016a41286a201a370300200541f0016a41306a201837030020054180026a201c3703002005201937038802200520173703f001200520163703f8010b20052017200220172017200256201620015620162001511b220a1b221a7d22143703f0012005201620012016200a1b221e7d2017201a54ad7d22183703f801201620197c211f2017201c7c2220201754220cad2121200541f0016a41106a210a024002402002201a7d22152001201e7d2002201a54ad7d22228450450d004200211c420021222002211e200121230c010b20054188026a201920222019201c201556201920225620192022511b22071b22237d201c2015201c20071b221754ad7d3703002005201c20177d37038002202220237d2015201754ad7d21222023201e7c2017201a7c221e201754ad7c2123201520177d211c0b201f20217c2117200541a8026a41186a200a41086a2903002219370300200541a8026a41206a2207200a41106a290300370300200541d0026a220d200a41186a290300370300200541d8026a220e200a41206a2903003703002005200a290300221a3703b802200520143703a802200520183703b00202400240427f2014201a7c221a201a201454220a201820197c200aad7c221920185420192018511b220a1b221a428080e983b1de16544100427f2019200a1b2215501b0d00200541b8026a290300211a200e2903002115200d290300211f2007290300212120052903b002212420052903a80221254201211920052903c00221260c010b02400240201a20158450450d00420021190c010b42002119200541e0046a41186a220f4200370300200541e0046a41106a220d4200370300200541e0046a41086a22074200370300200542003703e00441b6fdc600ad4280808080800184221f1001220e290000212120054180066a41086a220a200e41086a2900003703002005202137038006200e10352007200a29030037030020052005290380063703e00441e489c200ad4280808080d0018422211001220e2900002124200a200e41086a2900003703002005202437038006200e1035200d2005290380062224370300200541e0056a41086a22102007290300370300200541e0056a41106a22112024370300200541e0056a41186a2212200a290300370300200520052903e0043703e0052005200541e0056a412010d701200541106a2903002124200529030821252005280200210e200f4200370300200d420037030020074200370300200542003703e004201f1001220f290000211f200a200f41086a2900003703002005201f37038006200f10352007200a29030037030020052005290380063703e00420211001220f290000211f200a200f41086a2900003703002005201f37038006200f1035200d200529038006221f370300201020072903003703002011201f3703002012200a290300370300200520052903e0043703e0052005420020244200200e1b221f20157d20254200200e1b2221201a54ad7d22242021201a7d22252021562024201f562024201f511b220a1b3703e804200542002025200a1b3703e004200541e0056aad4280808080800484200541e0046aad4280808080800284100220054198056a201537030020054190056a201a370300200741013a0000200541e9046a2000290000370000200541f1046a200041086a290000370000200541f9046a200041106a29000037000020054181056a200041186a290000370000200541033a00e00441b0b4cc004100200541e0046a10d4010b0b2017201651210a20172016542107200541c8016a2021370300200541d0016a201f370300200541b0016a2024370300200541d8016a2015370300200541b8016a201a370300200520263703c0012005201d3703e001200520253703a8012005200b4100201b420151220d1b3a00ec01200520094100200d1b3602e801200520194201512209ad3703a0010240024020090d002008ad4220862006ad8410070c010b200520083602e404200520063602e004200541a8016a200541e0046a10e7020b200c2007200a1b210a0240200528029401450d00200610350b427f2017200a1b2116427f2020200a1b21172019420152210a024002400240201b4201510d00200a0d0041032106200541e0036a210a0c010b201b420152200a410173720d0141042106200541e0026a210a0b200a41086a20063a0000200a41003a0000200a41096a2000290000370000200a41116a200041086a290000370000200a41196a200041106a290000370000200a41216a200041186a29000037000041b0b4cc004100200a10d4010b024020172016844200520d0020054198056a201837030020054190056a2014370300200541e0046a41086a41003a0000200541e9046a2000290000370000200541f1046a200041086a290000370000200541f9046a200041106a29000037000020054181056a200041186a290000370000200541033a00e00441b0b4cc004100200541e0046a10d4010b2004427f20042903002216201e7c22172017201654220a200441086a2206290300221620237c200aad7c221720165420172016511b220a1b3703002006427f2017200a1b3703000240201c202284500d002003420020032903002216201c7d22172017201656200341086a220a290300221720227d2016201c54ad7d221620175620162017511b22061b370300200a4200201620061b3703000b200542f3e885db96cddbb3203703e002200541e0026a200541386a41386a2005290338200541386a41086a290300411f109002200541e0046a200541186a10b70120052802e004210a200520052802e8043602e4032005200a3602e003200541386a200541e0036a10e101024020052802e404450d00200a10350b200541e0046a41386a200137030020054190056a2002370300200541e0046a41086a41023a0000200541e9046a2000290000370000200541f1046a200041086a290000370000200541f9046a200041106a29000037000020054181056a200041186a290000370000200541043a00e00441b0b4cc004100200541e0046a10d4010b0240200528025c220a450d00200a41186c450d00200528025810350b200541e8006a28020041ffffffff0371450d00200528026410350b20054190066a24000f0b2006200a104f000bbf0908017f037e037f017e017f017e047f037e230041e0016b22032400200320023703582003200137035002400240200120028450450d0042002104420021050c010b2003200036021c200341206a2000200341d0006a2003411c6a10b002024020032903204201520d00200341306a2903002105200329032821040c010b200341c8006a2903002105200341c0006a290300210420032903284201520d00200341206a41106a290300210620034198016a200341206a41186a29030037030020034190016a2006370300200341e0006a41086a41003a0000200341e9006a2000290000370000200341f1006a200041086a290000370000200341f9006a200041106a29000037000020034181016a200041186a290000370000200341033a006041b0b4cc004100200341e0006a10d4010b200341e0006a41186a22074200370300200341e0006a41106a22084200370300200341e0006a41086a220942003703002003420037036041b6fdc600ad4280808080800184220a1001220b2900002106200341d0006a41086a2200200b41086a29000037030020032006370350200b1035200920002903003703002003200329035037036041e489c200ad4280808080d00184220c1001220b29000021062000200b41086a29000037030020032006370350200b1035200820032903502206370300200341206a41086a220d2009290300370300200341206a41106a220e2006370300200341206a41186a220f2000290300370300200320032903603703202003200341206a412010d701200220057d2001200454ad7d200520027d2004200154ad7d200420015820052002582005200251220b1b22101b2111200120047d200420017d20101b2112200341106a2903004200200328020022101b21062003290308420020101b21130240024020042001562005200256200b1b0d0020074200370300200842003703002009420037030020034200370360200a1001220b29000021012000200b41086a29000037030020032001370350200b10352009200029030037030020032003290350370360200c1001220b29000021012000200b41086a29000037030020032001370350200b103520082003290350370000200841086a2000290300370000200d2009290300370300200e2008290300370300200f20072903003703002003200329036037032020034200200620117d2013201254ad7d2201201320127d2202201356200120065620012006511b22001b37036820034200200220001b370360200341e0006a21000c010b20074200370300200842003703002009420037030020034200370360200a1001220b29000021012000200b41086a29000037030020032001370350200b10352009200029030037030020032003290350370360200c1001220b29000021012000200b41086a29000037030020032001370350200b103520082003290350370000200841086a2000290300370000200d2009290300370300200e2008290300370300200f2007290300370300200320032903603703202003427f200620117c201320127c22022013542200ad7c22012000200120065420012006511b22001b3703682003427f200220001b370360200341e0006a21000b200341206aad42808080808004842000ad42808080808002841002200341e0016a24000bdd0201067f230041d0006b22022400024002400240410410332203450d00200341edde91e306360000410c210420034104410c10372205450d0120052001290000370004200241003a004820052101410021060340200241003a0008200241086a200120044100472203109d081a024020040d00200241003a00080b20042003490d03200241286a20066a20022d00083a00002002200641016a22073a0048200420036b2104200120036a21012007210620074120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a2203200241286a41106a290300370300200241086a41086a2201200241286a41086a2903003703002002200229032837030820051035200041186a2004290300370000200041106a2003290300370000200041086a200129030037000020002002290308370000200241d0006a24000f0b1045000b103c000b2003200441b89dcc001059000bd80301067f230041106b2202240020024100360208200242013703000240412010332203450d0020032000290038370000200341086a200041c0006a290000370000200341106a200041c8006a290000370000200341186a200041d0006a29000037000020022003360200200242a080808080043702042002200036020c2002410c6a200210cf012002200041106a36020c2002410c6a200210cf0120002802202103200041286a28020022042002107702402004450d002003200441186c6a210403402002200336020c2002410c6a200210cf01200341106a200210e2012004200341186a2203470d000b0b200028022c2105200041346a28020022032002107702400240024020022802042206200228020822046b20034102742200490d0020022802002103200621070c010b200420006a22032004490d01200641017422072003200720034b1b22074100480d010240024020060d00024020070d00410121030c020b2007103322030d010c040b2002280200210320062007460d0020032006200710372203450d030b20022007360204200220033602000b200320046a20052000109d081a2001290200200420006aad4220862003ad84100202402007450d00200310350b200241106a24000f0b103e000b103c000bb30101027f230041106b2202240002400240024002402000280200220341c000490d00200341808001490d012003418080808004490d02200241033a00032001200241036a41011078200220002802003602042001200241046a410410780c030b200220034102743a00032001200241036a410110780c020b200220034102744101723b010a20012002410a6a410210780c010b2002200341027441027236020c20012002410c6a410410780b200241106a24000b13002000411836020420004180b7c0003602000bab0407047f017e017f017e017f017e037f230041d0006b22002400200041206a41186a22014200370300200041206a41106a22024200370300200041206a41086a220342003703002000420037032041f7edcb00ad4280808080f000842204100122052900002106200041c0006a41086a2207200541086a290000370300200020063703402005103520032007290300370300200020002903403703204193eecb00ad428080808080018422081001220529000021062007200541086a2900003703002000200637034020051035200220002903402206370300200041086a22092003290300370300200041106a220a2006370300200041186a220b2007290300370300200020002903203703000240024002404100200010e5012205200541ff01714104461b41ff0171417f6a220541024b0d0020050e03010001010b2001420037030020024200370300200342003703002000420037032020041001220529000021062007200541086a2900003703002000200637034020051035200320072903003703002000200029034037032020081001220529000021062007200541086a290000370300200020063703402005103520022000290340370000200241086a200729030037000020092003290300370300200a2002290300370300200b200129030037030020002000290320370300410110332207450d01200741013a00002000ad42808080808004842007ad428080808010841002200710350b200041d0006a24000f0b103c000b810201037f230041d0006b220124002001412036020420012000360200200141086a2000ad4280808080800484100510c20102400240200128020822020d00410421000c010b200128020c210302400240200141106a280200450d0020022d000022004104490d010b20014100360220200142013703182001410936022c200120013602282001200141186a360234200141cc006a41013602002001420137023c200141c888c2003602382001200141286a360248200141346a41e88ac500200141386a10431a200135022042208620013502188410060240200128021c450d00200128021810350b410421000b2003450d00200210350b200141d0006a240020000b3400200041f7edcb0036020420004100360200200041146a4124360200200041106a41bcaac100360200200041086a42073702000b2b01017f02404101103322020d00103c000b200042818080801037020420002002360200200241023a00000b2b01017f02404101103322020d00103c000b200042818080801037020420002002360200200241003a00000b5301017f0240411010332202450d00200242003700082002420037000020024110412010372202450d0020024200370010200042a0808080800437020420002002360200200241186a42003700000f0b103c000b940302047f017e230041206b2203240002400240200241d8006c4104722204417f4c0d00200410332205450d0120034100360208200320043602042003200536020020022003107702402002450d002001200241d8006c6a210603402003200141386a41201078200129030021072003200141086a290300370318200320073703102003200341106a4110107820012802202102200128022822042003107702402004450d002002200441306c6a210403402003200241201078200241206a29030021072003200241286a290300370318200320073703102003200341106a411010782004200241306a2202470d000b0b200141d8006a2105200128022c2102200141346a28020022042003107702402004450d002004410574210403402003200241201078200241206a2102200441606a22040d000b0b200129031021072003200141186a290300370318200320073703102003200341106a411010782005210120052006470d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1044000b1045000b3301017f02404110103322020d001045000b2002420037000820024200370000200042908080808002370204200020023602000b860101027f230041206b220224002002410c6a410036020020024200370300200241003602182002420137031002404104103322030d00103c000b200341003600002002200336021020024284808080c00037021420024104722203200241106a10b001200041086a200228021836020020002002290310370200200310b101200241206a24000be90101047f230041106b220224002002410036020c02400240410110332203450d000240024002400240200228020c220441c000490d00200441808001490d012004418080808004490d02200341033a0000200228020c21044105210520034101410510372203450d05200320043600010c030b200320044102743a0000410121050c020b4102210520034101410210372203450d03200320044102744101723b00000c010b4104210520034101410410372203450d02200320044102744102723600000b200020053602082000200536020420002003360200200241106a24000f0b1045000b103c000bf60301087f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a10cf012002200336023c2002413c6a200241306a10cf012002280220210320042802002204200241306a10770240024002402004450d00200441306c210503400240024020022802342206200228023822046b4120490d00200441206a2107200228023021080c010b200441206a22072004490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009103322080d010c060b2002280230210820062009460d0020082006200910372208450d050b20022009360234200220083602300b200820046a2204200341106a290000370000200441186a200341286a290000370000200441106a200341206a290000370000200441086a200341186a290000370000200220073602382002200336023c2002413c6a200241306a10cf01200341306a2103200541506a22050d000b0b20002002290330370200200041086a200241306a41086a280200360200024020022802242203450d00200341306c450d00200228022010350b200241c0006a24000f0b103e000b103c000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241043600000b2d01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241d4003600000b820b06057f017e017f017e047f0a7e23004190016b22022400200241386a41186a2203420037030041102104200241386a41106a22054200370300200241386a41086a220642003703002002420037033841f7edcb00ad4280808080f000842207100122082900002109200241d8006a41086a220a200841086a29000037030020022009370358200810352006200a2903003703002002200229035837033841b6aac000ad4280808080900284100122082900002109200a200841086a2900003703002002200937035820081035200520022903582209370300200241186a41086a220b2006290300370300200241186a41106a2009370300200241186a41186a220c200a29030037030020022002290338370318200241106a200241186a10f20102402002280210417d71450d002003420037030041102104200241386a41106a220d420037030020064200370300200242003703382007100122082900002109200a200841086a29000037030020022009370358200810352006200a2903003703002002200229035837033841e4edcb00ad4280808080a00184100122082900002109200a200841086a290000370300200220093703582008103520052002290358370000200541086a200a290300370000200b2006290300370300200241186a41106a200d290300370300200c200329030037030020022002290338370318200241086a200241186a412010c001024020022802084101470d00200228020c2001470d010b42002109200241386a41186a22044200370300200241386a41106a22034200370300200241386a41086a220642003703002002420037033841f7edcb00ad4280808080f00084100122082900002107200241d8006a41086a220a200841086a29000037030020022007370358200810352006200a2903003703002002200229035837033841ceeecb00ad4280808080b00184100122082900002107200a200841086a290000370300200220073703582008103520052002290358370000200541086a200a290300370000200241186a41086a2006290300370300200241186a41106a2003290300370300200241186a41186a2004290300370300200220022903383703182002412036026c2002200241186a360268200241f0006a200241186aad4280808080800484100510c201024002402002280270220a0d000c010b20022802742106024002400240200241f0006a41086a28020022054110490d00200541707122054110460d0020054120470d010b200241003602602002420137035820024109360284012002200241e8006a360280012002200241d8006a36028c01200241cc006a41013602002002420137023c200241c888c200360238200220024180016a3602482002418c016a41e88ac500200241386a10431a200235026042208620023502588410060240200228025c450d00200228025810350b420021090c010b200a41086a290000210e200a290000210f200a41286a2900002107200a41186a2900002110200a2900202111200a2900102112420121090b2006450d00200a10350b0240024002402009500d00200041286a2903002109200041186a2903002113200041086a290300211420002903202115200029031021162000290300211741031033220a450d01200a417f20152011852009200785844200522015201154200920075420092007511b22081b3a0002200a417f20162012852013201085844200522016201254201320105420132010511b1b22053a0001200a417f2017200f852014200e85844200522017200f542014200e542014200e511b1b22063a0000200641014b0d020240024020060e020001000b200541014b0d03024020050e020001000b200a1035411121042008450d040c010b200a10350b411d21040c020b103c000b200a1035411121040b20024190016a240020040bb40201067f230041d0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822030d00410221010c010b200228020c210402400240200241106a2802002205450d0020032d0000220641014b0d0041002101024020060e020200020b2005417f6a4104490d0020032800012107410121010c010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b410221010b2004450d00200310350b2000200736020420002001360200200241d0006a24000b130020004102360204200041f0f0c1003602000b2d01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241a0053600000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241063600000bde0506067f017e017f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b024020054102762209410c4b0d0002400240024020090e0d00030303010303030303030302000b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210a0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210a0c050b20064110490d03200441096a290000210a2004290001210820012003416f6a3602042001200441116a360200200a428080808080808080015421070c040b200941046a220641104b0d022003417e6a2103200441026a21044100210541012107200241186a210b420021084200210a03402003417f460d01200241106a2004417f6a3100004200200541037441f8007110a30820012003360204200120043602002003417f6a2103200441016a2104200b290300200a84210a20022903102008842108200541016a220541ff01712006490d000b2002427f427f41e80020094103746b41f8007110a4082008200229030058200a200241086a290300220c58200a200c511b21070c030b0c020b4200210a410021070c010b410121070b20002008370308200041106a200a37030020002007ad370300200241206a24000bd53901037f230041106b2202240020002802002103200028020822042001107702402004450d00200320044103746a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a41021078200341086a22032004470d000b0b200028020c2103200041146a28020022042001107702402004450d0020032004410c6c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a410210782003410c6a22032004470d000b0b20002802182103200041206a28020022042001107702402004450d00200320044104746a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a41021078200341106a22032004470d000b0b200028022421032000412c6a28020022042001107702402004450d002003200441146c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a41021078200341146a22032004470d000b0b20002802302103200041386a28020022042001107702402004450d002003200441186c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a41021078200341186a22032004470d000b0b200028023c2103200041c4006a28020022042001107702402004450d0020032004411c6c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a410210782003411c6a22032004470d000b0b20002802482103200041d0006a28020022042001107702402004450d00200320044105746a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a41021078200341206a22032004470d000b0b20002802542103200041dc006a28020022042001107702402004450d002003200441246c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a41021078200341246a22032004470d000b0b20002802602103200041e8006a28020022042001107702402004450d002003200441286c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a41021078200341286a22032004470d000b0b200028026c2103200041f4006a28020022042001107702402004450d0020032004412c6c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a410210782003412c6a22032004470d000b0b2000280278210320004180016a28020022042001107702402004450d002003200441306c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a41021078200341306a22032004470d000b0b20002802840121032000418c016a28020022042001107702402004450d002003200441346c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a4102107820022003412e6a2f01003b010c20012002410c6a410210782002200341306a2f01003b010c20012002410c6a41021078200341346a22032004470d000b0b200028029001210320004198016a28020022042001107702402004450d002003200441386c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a4102107820022003412e6a2f01003b010c20012002410c6a410210782002200341306a2f01003b010c20012002410c6a410210782002200341326a2f01003b010c20012002410c6a410210782002200341346a2f01003b010c20012002410c6a41021078200341386a22032004470d000b0b200028029c012103200041a4016a28020022042001107702402004450d0020032004413c6c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a4102107820022003412e6a2f01003b010c20012002410c6a410210782002200341306a2f01003b010c20012002410c6a410210782002200341326a2f01003b010c20012002410c6a410210782002200341346a2f01003b010c20012002410c6a410210782002200341366a2f01003b010c20012002410c6a410210782002200341386a2f01003b010c20012002410c6a410210782003413c6a22032004470d000b0b20002802a8012103200041b0016a28020022042001107702402004450d00200320044106746a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a4102107820022003412e6a2f01003b010c20012002410c6a410210782002200341306a2f01003b010c20012002410c6a410210782002200341326a2f01003b010c20012002410c6a410210782002200341346a2f01003b010c20012002410c6a410210782002200341366a2f01003b010c20012002410c6a410210782002200341386a2f01003b010c20012002410c6a4102107820022003413a6a2f01003b010c20012002410c6a4102107820022003413c6a2f01003b010c20012002410c6a41021078200341c0006a22032004470d000b0b20002802b4012103200041bc016a28020022002001107702402000450d002003200041c4006c6a210003402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a4102107820022003412e6a2f01003b010c20012002410c6a410210782002200341306a2f01003b010c20012002410c6a410210782002200341326a2f01003b010c20012002410c6a410210782002200341346a2f01003b010c20012002410c6a410210782002200341366a2f01003b010c20012002410c6a410210782002200341386a2f01003b010c20012002410c6a4102107820022003413a6a2f01003b010c20012002410c6a4102107820022003413c6a2f01003b010c20012002410c6a4102107820022003413e6a2f01003b010c20012002410c6a410210782002200341c0006a2f01003b010c20012002410c6a41021078200341c4006a22032000470d000b0b200241106a24000bd2ae0109097f017e067f037e217f027e0b7f017e047f23004190046b22022400200241f8006a200110c4010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802780d00200228027c220320012802044103762204200420034b1b22054103742204417f4c0d020240024020050d00410421060c010b200410332206450d040b41002104200241003602980320022005360294032002200636029003024002402003450d00410021040340200128020422054104490d0220012802002207280000210820012005417c6a22093602042001200741046a220736020020094102490d0220072f0000210920012005417a6a3602042001200741026a36020002402004200228029403470d0020024190036a20044101109001200228029003210620022802980321040b200620044103746a220520093b0104200520083602002002200441016a2204360298032003417f6a22030d000b20022802940321050b2006450d01200241f0006a200110c4012002280270450d020c180b20022802940341ffffffff0171450d00200610350b200041003602000c180b2002280274220a2001280204410c6e22072007200a4b1bad420c7e220b422088a70d00200ba72203417f4c0d000240024020030d004104210c0c010b20031033220c450d020b4100210720024100360298032002200c3602900320022003410c6e220d36029403024002400240200a450d00410021070340200128020422034104490d0220012802002209280000210e20012003417c6a220d3602042001200941046a2208360200200d4102490d0220082f0000210f20012003417a6a220d3602042001200841026a360200200d4102490d0220092f0006210d2001200341786a22083602042001200941086a220936020020084102490d0220092f000021082001200341766a3602042001200941026a36020002402007200228029403470d0020024190036a20074101108701200228029003210c20022802980321070b200c2007410c6c6a220320083b01082003200f3b01042003200e360200200341066a200d3b01002002200741016a220736029803200a417f6a220a0d000b200228029403210d0b200c450d17200241e8006a200110c4012002280268450d010c160b2002280294032201450d162001410c6c450d16200c10350c160b4104210f200228026c220e200128020441047622032003200e4b1b22034104742209417f4c0d0002402003450d0020091033220f450d020b41002108200241003602980320022003360294032002200f36029003024002400240200e450d00410021080340200128020422034104490d0220012802002209280000211020012003417c6a22113602042001200941046a220a36020020114102490d02200a330000210b20012003417a6a22113602042001200a41026a36020020114102490d02200933000621122001200341786a22113602042001200941086a220a36020020114102490d02200a33000021132001200341766a22113602042001200a41026a36020020114102490d02200933000a21142001200341746a220a36020420012009410c6a2209360200200a4102490d0220092f0000210a2001200341726a3602042001200941026a3602002014423086201342208684201242108684200b84210b02402008200228029403470d0020024190036a20084101108c01200228029003210f20022802980321080b200f20084104746a2203200a3b010c2003200b370204200320103602002002200841016a220836029803200e417f6a220e0d000b20022802940321030b200f450d16200241e0006a200110c4012002280260450d010c150b20022802940341ffffffff0071450d15200f10350c150b20022802642210200128020441146e2209200920104b1bad42147e220b422088a70d00200ba72209417f4c0d000240024020090d00410421150c010b200910332215450d020b4100210e200241003602980320022015360290032002200941146e2211360294030240024002402010450d004100210e0340200128020422094104490d022001280200220a280000211620012009417c6a22173602042001200a41046a221136020020174102490d0220112f0000211820012009417a6a22173602042001201141026a36020020174102490d02200a2f000621192001200941786a22173602042001200a41086a221136020020174102490d0220112f0000211a2001200941766a22173602042001201141026a36020020174102490d02200a2f000a211b2001200941746a22173602042001200a410c6a221136020020174102490d0220112f0000211c2001200941726a22173602042001201141026a36020020174102490d02200a2f000e21172001200941706a22113602042001200a41106a220a36020020114102490d02200a2f0000211120012009416e6a3602042001200a41026a3602000240200e200228029403470d0020024190036a200e41011099012002280290032115200228029803210e0b2015200e41146c6a220920113b0110200920183b0104200920163602002009410e6a20173b01002009410c6a201c3b01002009410a6a201b3b0100200941086a201a3b0100200941066a20193b01002002200e41016a220e360298032010417f6a22100d000b20022802940321110b2015450d15200241d8006a200110c4012002280258450d010c140b2002280294032201450d14200141146c450d14201510350c140b200228025c2217200128020441186e2209200920174b1bad42187e220b422088a70d00200ba72209417f4c0d000240024020090d00410421180c010b200910332218450d020b41002110200241003602980320022018360290032002200941186e2216360294030240024002402017450d00410021100340200128020422094104490d022001280200220a280000211a20012009417c6a22193602042001200a41046a221636020020194102490d0220162f0000211b20012009417a6a22193602042001201641026a36020020194102490d02200a2f0006211c2001200941786a22193602042001200a41086a221636020020194102490d0220162f0000211d2001200941766a22193602042001201641026a36020020194102490d02200a2f000a211e2001200941746a22193602042001200a410c6a221636020020194102490d0220162f0000211f2001200941726a22193602042001201641026a36020020194102490d02200a2f000e21202001200941706a22193602042001200a41106a221636020020194102490d0220162f0000212120012009416e6a22193602042001201641026a36020020194102490d02200a2f0012211920012009416c6a22163602042001200a41146a220a36020020164102490d02200a2f0000211620012009416a6a3602042001200a41026a36020002402010200228029403470d0020024190036a20104101109701200228029003211820022802980321100b2018201041186c6a220920163b01142009201b3b01042009201a360200200941126a20193b0100200941106a20213b01002009410e6a20203b01002009410c6a201f3b01002009410a6a201e3b0100200941086a201d3b0100200941066a201c3b01002002201041016a2210360298032017417f6a22170d000b20022802940321160b2018450d14200241d0006a200110c4012002280250450d010c130b2002280294032201450d13200141186c450d13201810350c130b200228025422192001280204411c6e2209200920194b1bad421c7e220b422088a70d00200ba72209417f4c0d000240024020090d004104211b0c010b20091033221b450d020b4100211720024100360298032002201b3602900320022009411c6e221a360294030240024002402019450d00410021170340200128020422094104490d022001280200220a280000211d20012009417c6a221c3602042001200a41046a221a360200201c4102490d02201a2f0000211e20012009417a6a221c3602042001201a41026a360200201c4102490d02200a2f0006211f2001200941786a221c3602042001200a41086a221a360200201c4102490d02201a2f000021202001200941766a221c3602042001201a41026a360200201c4102490d02200a2f000a21212001200941746a221c3602042001200a410c6a221a360200201c4102490d02201a2f000021222001200941726a221c3602042001201a41026a360200201c4102490d02200a2f000e21232001200941706a221c3602042001200a41106a221a360200201c4102490d02201a2f0000212420012009416e6a221c3602042001201a41026a360200201c4102490d02200a2f0012212520012009416c6a221c3602042001200a41146a221a360200201c4102490d02201a2f0000212620012009416a6a221c3602042001201a41026a360200201c4102490d02200a2f0016211c2001200941686a221a3602042001200a41186a220a360200201a4102490d02200a2f0000211a2001200941666a3602042001200a41026a36020002402017200228029403470d0020024190036a2017410110f901200228029003211b20022802980321170b201b2017411c6c6a2209201a3b01182009201e3b01042009201d360200200941166a201c3b0100200941146a20263b0100200941126a20253b0100200941106a20243b01002009410e6a20233b01002009410c6a20223b01002009410a6a20213b0100200941086a20203b0100200941066a201f3b01002002201741016a2217360298032019417f6a22190d000b200228029403211a0b201b450d13200241c8006a200110c4012002280248450d010c120b2002280294032201450d122001411c6c450d12201b10350c120b200228024c221c200128020441057622092009201c4b1b2209410574220a417f4c0d000240024020090d004104211e0c010b200a1033221e450d020b41002119200241003602980320022009360294032002201e36029003024002400240201c450d00410021190340200128020422094104490d022001280200220a280000212020012009417c6a221f3602042001200a41046a221d360200201f4102490d02201d2f0000212120012009417a6a221f3602042001201d41026a360200201f4102490d02200a2f000621222001200941786a221f3602042001200a41086a221d360200201f4102490d02201d2f000021232001200941766a221f3602042001201d41026a360200201f4102490d02200a2f000a21242001200941746a221f3602042001200a410c6a221d360200201f4102490d02201d2f000021252001200941726a221f3602042001201d41026a360200201f4102490d02200a2f000e21262001200941706a221f3602042001200a41106a221d360200201f4102490d02201d2f0000212720012009416e6a221f3602042001201d41026a360200201f4102490d02200a2f0012212820012009416c6a221f3602042001200a41146a221d360200201f4102490d02201d2f0000212920012009416a6a221f3602042001201d41026a360200201f4102490d02200a2f0016212a2001200941686a221f3602042001200a41186a221d360200201f4102490d02201d2f0000212b2001200941666a221f3602042001201d41026a360200201f4102490d02200a2f001a211f2001200941646a221d3602042001200a411c6a220a360200201d4102490d02200a2f0000211d2001200941626a3602042001200a41026a36020002402019200228029403470d0020024190036a20194101109101200228029003211e20022802980321190b201e20194105746a2209201d3b011c200920213b0104200920203602002009411a6a201f3b0100200941186a202b3b0100200941166a202a3b0100200941146a20293b0100200941126a20283b0100200941106a20273b01002009410e6a20263b01002009410c6a20253b01002009410a6a20243b0100200941086a20233b0100200941066a20223b01002002201941016a221936029803201c417f6a221c0d000b20022802940321090b201e450d12200241c0006a200110c4012002280240450d010c110b20022802940341ffffff3f71450d11201e10350c110b2002280244221f200128020441246e220a200a201f4b1bad42247e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421210c010b200a10332221450d020b4100211d200241003602980320022021360290032002200a41246e222036029403024002400240201f450d004100211d03402001280204220a4104490d022001280200221c28000021232001200a417c6a22223602042001201c41046a222036020020224102490d0220202f000021242001200a417a6a22223602042001202041026a36020020224102490d02201c2f000621252001200a41786a22223602042001201c41086a222036020020224102490d0220202f000021262001200a41766a22223602042001202041026a36020020224102490d02201c2f000a21272001200a41746a22223602042001201c410c6a222036020020224102490d0220202f000021282001200a41726a22223602042001202041026a36020020224102490d02201c2f000e21292001200a41706a22223602042001201c41106a222036020020224102490d0220202f0000212a2001200a416e6a22223602042001202041026a36020020224102490d02201c2f0012212b2001200a416c6a22223602042001201c41146a222036020020224102490d0220202f0000212c2001200a416a6a22223602042001202041026a36020020224102490d02201c2f0016212d2001200a41686a22223602042001201c41186a222036020020224102490d0220202f0000212e2001200a41666a22223602042001202041026a36020020224102490d02201c2f001a212f2001200a41646a22223602042001201c411c6a222036020020224102490d0220202f000021302001200a41626a22223602042001202041026a36020020224102490d02201c2f001e21222001200a41606a22203602042001201c41206a221c36020020204102490d02201c2f000021202001200a415e6a3602042001201c41026a3602000240201d200228029403470d0020024190036a201d4101108d012002280290032121200228029803211d0b2021201d41246c6a220a20203b0120200a20243b0104200a2023360200200a411e6a20223b0100200a411c6a20303b0100200a411a6a202f3b0100200a41186a202e3b0100200a41166a202d3b0100200a41146a202c3b0100200a41126a202b3b0100200a41106a202a3b0100200a410e6a20293b0100200a410c6a20283b0100200a410a6a20273b0100200a41086a20263b0100200a41066a20253b01002002201d41016a221d36029803201f417f6a221f0d000b20022802940321200b2021450d11200241386a200110c4012002280238450d010c100b2002280294032201450d10200141246c450d10202110350c100b200228023c2222200128020441286e220a200a20224b1bad42287e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421230c010b200a10332223450d020b4100211f200241003602980320022023360290032002200a41286e2224360294030240024002402022450d004100211f03402001280204220a4104490d022001280200221c28000021262001200a417c6a22253602042001201c41046a222436020020254102490d0220242f000021272001200a417a6a22253602042001202441026a36020020254102490d02201c2f000621282001200a41786a22253602042001201c41086a222436020020254102490d0220242f000021292001200a41766a22253602042001202441026a36020020254102490d02201c2f000a212a2001200a41746a22253602042001201c410c6a222436020020254102490d0220242f0000212b2001200a41726a22253602042001202441026a36020020254102490d02201c2f000e212c2001200a41706a22253602042001201c41106a222436020020254102490d0220242f0000212d2001200a416e6a22253602042001202441026a36020020254102490d02201c2f0012212e2001200a416c6a22253602042001201c41146a222436020020254102490d0220242f0000212f2001200a416a6a22253602042001202441026a36020020254102490d02201c2f001621302001200a41686a22253602042001201c41186a222436020020254102490d0220242f000021312001200a41666a22253602042001202441026a36020020254102490d02201c2f001a21322001200a41646a22253602042001201c411c6a222436020020254102490d0220242f000021332001200a41626a22253602042001202441026a36020020254102490d02201c2f001e21342001200a41606a22253602042001201c41206a222436020020254102490d0220242f000021352001200a415e6a22253602042001202441026a36020020254102490d02201c2f002221252001200a415c6a22243602042001201c41246a221c36020020244102490d02201c2f000021242001200a415a6a3602042001201c41026a3602000240201f200228029403470d0020024190036a201f4101109d012002280290032123200228029803211f0b2023201f41286c6a220a20243b0124200a20273b0104200a2026360200200a41226a20253b0100200a41206a20353b0100200a411e6a20343b0100200a411c6a20333b0100200a411a6a20323b0100200a41186a20313b0100200a41166a20303b0100200a41146a202f3b0100200a41126a202e3b0100200a41106a202d3b0100200a410e6a202c3b0100200a410c6a202b3b0100200a410a6a202a3b0100200a41086a20293b0100200a41066a20283b01002002201f41016a221f360298032022417f6a22220d000b20022802940321240b2023450d10200241306a200110c4012002280230450d010c0f0b2002280294032201450d0f200141286c450d0f202310350c0f0b200228023422252001280204412c6e220a200a20254b1bad422c7e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421260c010b200a10332226450d020b41002122200241003602880120022026360280012002200a412c6e22273602840102402025450d004100212203402001280204220a4104490d0e2001280200221c280000212b2001200a417c6a22283602042001201c41046a2227360200200241003a00b403200241003b01d00320284102490d0e20272f000021292001200a417a6a22283602042001202741026a360200200241003b01d00320284102490d0e201c2f000621282001200a41786a222a3602042001201c41086a2227360200200220293b019003200241013a00b403200220283b019203200241003b01d003202a4102490d0d20272f000021292001200a41766a22283602042001202741026a360200200241003b01d003202841014d0d0d201c2f000a21282001200a41746a222a3602042001201c410c6a2227360200200220293b019403200220283b019603200241023a00b403200241003b01d003202a4102490d0d20272f000021292001200a41726a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f000e21282001200a41706a222a3602042001201c41106a2227360200200220293b019803200241033a00b403200220283b019a03200241003b01d003202a4102490d0d20272f000021292001200a416e6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001221282001200a416c6a222a3602042001201c41146a2227360200200220293b019c03200241043a00b403200220283b019e03200241003b01d003202a4102490d0d20272f000021292001200a416a6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001621282001200a41686a222a3602042001201c41186a2227360200200220293b01a003200241053a00b403200220283b01a203200241003b01d003202a4102490d0d20272f000021292001200a41666a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001a21282001200a41646a222a3602042001201c411c6a2227360200200220293b01a403200241063a00b403200220283b01a603200241003b01d003202a4102490d0d20272f000021292001200a41626a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001e21282001200a41606a222a3602042001201c41206a2227360200200220293b01a803200241073a00b403200220283b01aa03200241003b01d003202a4102490d0d20272f000021292001200a415e6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f002221282001200a415c6a222a3602042001201c41246a2227360200200220293b01ac03200241083a00b403200220283b01ae03200241003b01d003202a4102490d0d20272f000021292001200a415a6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f002621272001200a41586a22283602042001201c41286a221c360200200220293b01b003200241093a00b403200220273b01b203200241d0036a41206a20022802b0032227360200200241d0036a41186a20024190036a41186a290300220b370300200241d0036a41106a20024190036a41106a2903002212370300200241d0036a41086a20024190036a41086a2903002213370300200220022903900322143703d003200241d0026a41206a22292027360200200241d0026a41186a2227200b370300200241d0026a41106a222a2012370300200241d0026a41086a222c2013370300200220143703d00220284102490d0e201c2f000021282001200a41566a3602042001201c41026a36020020024190026a41106a202a290300220b370300200241d0016a41086a202c2903002212370300200241d0016a41106a200b370300200241d0016a41186a20272903002213370300200241d0016a41206a2029280200220a360200200220022903d00222143703d00120024190016a41206a221c200a36020020024190016a41186a2227201337030020024190016a41106a2229200b37030020024190016a41086a222a2012370300200220143703900102402022200228028401470d0020024180016a20224101109801200228028001212620022802880121220b20262022412c6c6a220a202b360200200a200229039001370204201c280200211c2027290300210b20292903002112202a2903002113200a20283b0128200a410c6a2013370200200a41146a2012370200200a411c6a200b370200200a41246a201c3602002002202241016a2222360288012025417f6a22250d000b20022802840121270b2026450d0d200241286a200110c40120022802280d0a200228022c2228200128020441306e220a200a20284b1bad42307e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421290c010b200a10332229450d020b41002125200241003602880120022029360280012002200a41306e222a3602840102402028450d004100212503402001280204220a4104490d0b2001280200221c280000212e2001200a417c6a222b3602042001201c41046a222a360200200241003a00b803200241003b01d003202b4102490d0b202a2f0000212c2001200a417a6a222b3602042001202a41026a360200200241003b01d003202b4102490d0b201c2f0006212b2001200a41786a222d3602042001201c41086a222a3602002002202c3b019003200241013a00b8032002202b3b019203200241003b01d003202d4102490d0a202a2f0000212c2001200a41766a222b3602042001202a41026a360200200241003b01d003202b41014d0d0a201c2f000a212b2001200a41746a222d3602042001201c410c6a222a3602002002202c3b0194032002202b3b019603200241023a00b803200241003b01d003202d4102490d0a202a2f0000212c2001200a41726a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f000e212b2001200a41706a222d3602042001201c41106a222a3602002002202c3b019803200241033a00b8032002202b3b019a03200241003b01d003202d4102490d0a202a2f0000212c2001200a416e6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0012212b2001200a416c6a222d3602042001201c41146a222a3602002002202c3b019c03200241043a00b8032002202b3b019e03200241003b01d003202d4102490d0a202a2f0000212c2001200a416a6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0016212b2001200a41686a222d3602042001201c41186a222a3602002002202c3b01a003200241053a00b8032002202b3b01a203200241003b01d003202d4102490d0a202a2f0000212c2001200a41666a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f001a212b2001200a41646a222d3602042001201c411c6a222a3602002002202c3b01a403200241063a00b8032002202b3b01a603200241003b01d003202d4102490d0a202a2f0000212c2001200a41626a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f001e212b2001200a41606a222d3602042001201c41206a222a3602002002202c3b01a803200241073a00b8032002202b3b01aa03200241003b01d003202d4102490d0a202a2f0000212c2001200a415e6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0022212b2001200a415c6a222d3602042001201c41246a222a3602002002202c3b01ac03200241083a00b8032002202b3b01ae03200241003b01d003202d4102490d0a202a2f0000212c2001200a415a6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0026212b2001200a41586a222d3602042001201c41286a222a3602002002202c3b01b003200241093a00b8032002202b3b01b203200241003b01d003202d4102490d0a202a2f0000212c2001200a41566a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f002a212a2001200a41546a222b3602042001201c412c6a221c3602002002202c3b01b4032002410a3a00b8032002202a3b01b603200241d0036a41206a20024190036a41206a290300220b370300200241d0036a41186a20024190036a41186a2903002212370300200241d0036a41106a20024190036a41106a2903002213370300200241d0036a41086a20024190036a41086a2903002214370300200220022903900322363703d003200241d0026a41206a222a200b370300200241d0026a41186a222c2012370300200241d0026a41106a222d2013370300200241d0026a41086a222f2014370300200220363703d002202b4102490d0b201c2f0000212b2001200a41526a3602042001201c41026a36020020024190026a41106a202d290300220b370300200241d0016a41086a202f2903002212370300200241d0016a41106a200b370300200241d0016a41186a202c2903002213370300200241d0016a41206a202a2903002214370300200220022903d00222363703d00120024190016a41206a221c201437030020024190016a41186a222a201337030020024190016a41106a222c200b37030020024190016a41086a222d2012370300200220363703900102402025200228028401470d0020024180016a20254101108901200228028001212920022802880121250b2029202541306c6a220a202e360200200a200229039001370204201c290300210b202a2903002112202c2903002113202d2903002114200a202b3b012c200a410c6a2014370200200a41146a2013370200200a411c6a2012370200200a41246a200b3702002002202541016a2225360288012028417f6a22280d000b200228028401212a0b2029450d0a200241206a200110c40120022802200d072002280224222b200128020441346e220a200a202b4b1bad42347e220b422088a70d00200ba7220a417f4c0d0002400240200a0d004104212c0c010b200a1033222c450d020b4100212820024100360288012002202c360280012002200a41346e222d360284010240202b450d004100212803402001280204220a4104490d082001280200221c28000021312001200a417c6a222e3602042001201c41046a222d360200200241003a00bc03200241003b01d003202e4102490d08202d2f0000212f2001200a417a6a222e3602042001202d41026a360200200241003b01d003202e4102490d08201c2f0006212e2001200a41786a22303602042001201c41086a222d3602002002202f3b019003200241013a00bc032002202e3b019203200241003b01d00320304102490d07202d2f0000212f2001200a41766a222e3602042001202d41026a360200200241003b01d003202e41014d0d07201c2f000a212e2001200a41746a22303602042001201c410c6a222d3602002002202f3b0194032002202e3b019603200241023a00bc03200241003b01d00320304102490d07202d2f0000212f2001200a41726a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f000e212e2001200a41706a22303602042001201c41106a222d3602002002202f3b019803200241033a00bc032002202e3b019a03200241003b01d00320304102490d07202d2f0000212f2001200a416e6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0012212e2001200a416c6a22303602042001201c41146a222d3602002002202f3b019c03200241043a00bc032002202e3b019e03200241003b01d00320304102490d07202d2f0000212f2001200a416a6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0016212e2001200a41686a22303602042001201c41186a222d3602002002202f3b01a003200241053a00bc032002202e3b01a203200241003b01d00320304102490d07202d2f0000212f2001200a41666a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f001a212e2001200a41646a22303602042001201c411c6a222d3602002002202f3b01a403200241063a00bc032002202e3b01a603200241003b01d00320304102490d07202d2f0000212f2001200a41626a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f001e212e2001200a41606a22303602042001201c41206a222d3602002002202f3b01a803200241073a00bc032002202e3b01aa03200241003b01d00320304102490d07202d2f0000212f2001200a415e6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0022212e2001200a415c6a22303602042001201c41246a222d3602002002202f3b01ac03200241083a00bc032002202e3b01ae03200241003b01d00320304102490d07202d2f0000212f2001200a415a6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0026212e2001200a41586a22303602042001201c41286a222d3602002002202f3b01b003200241093a00bc032002202e3b01b203200241003b01d00320304102490d07202d2f0000212f2001200a41566a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f002a212e2001200a41546a22303602042001201c412c6a222d3602002002202f3b01b4032002410a3a00bc032002202e3b01b603200241003b01d00320304102490d07202d2f0000212f2001200a41526a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f002e212d2001200a41506a222e3602042001201c41306a221c3602002002202f3b01b8032002410b3a00bc032002202d3b01ba03200241d0036a41286a20022802b803222d360200200241d0036a41206a20024190036a41206a290300220b370300200241d0036a41186a20024190036a41186a2903002212370300200241d0036a41106a20024190036a41106a2903002213370300200241d0036a41086a20024190036a41086a2903002214370300200220022903900322363703d003200241d0026a41286a222f202d360200200241d0026a41206a222d200b370300200241d0026a41186a22302012370300200241d0026a41106a22322013370300200241d0026a41086a22332014370300200220363703d002202e4102490d08201c2f0000212e2001200a414e6a3602042001201c41026a36020020024190026a41106a2032290300220b37030020024190026a41186a20302903002212370300200241d0016a41086a220a2033290300370300200241d0016a41106a221c200b370300200241d0016a41186a22302012370300200241d0016a41206a2232202d290300370300200241d0016a41286a222d202f280200360200200220022903d0023703d00120024190016a41286a222f202d28020036020020024190016a41206a222d203229030037030020024190016a41186a2232203029030037030020024190016a41106a2230201c29030037030020024190016a41086a221c200a290300370300200220022903d0013703900102402028200228028401470d0020024180016a2028410110a501200228028001212c20022802880121280b202c202841346c6a220a2031360200200a200229039001370204202f280200212f202d290300210b2032290300211220302903002113201c2903002114200a202e3b0130200a410c6a2014370200200a41146a2013370200200a411c6a2012370200200a41246a200b370200200a412c6a202f3602002002202841016a222836028801202b417f6a222b0d000b200228028401212d0b202c450d07200241186a200110c40120022802180d04200228021c222e200128020441386e220a200a202e4b1bad42387e220b422088a70d00200ba7220a417f4c0d0002400240200a0d004104212f0c010b200a1033222f450d020b4100212b20024100360288012002202f360280012002200a41386e2234360284010240202e450d004100212b03402001280204220a4104490d052001280200221c28000021342001200a417c6a22313602042001201c41046a2230360200200241003a00c003200241003b01d00320314102490d0520302f000021322001200a417a6a22313602042001203041026a360200200241003b01d00320314102490d05201c2f000621312001200a41786a22333602042001201c41086a2230360200200220323b019003200241013a00c003200220313b019203200241003b01d00320334102490d0420302f000021322001200a41766a22313602042001203041026a360200200241003b01d003203141014d0d04201c2f000a21312001200a41746a22333602042001201c410c6a2230360200200220323b019403200220313b019603200241023a00c003200241003b01d00320334102490d0420302f000021322001200a41726a22313602042001203041026a360200200241003b01d00320314102490d04201c2f000e21312001200a41706a22333602042001201c41106a2230360200200220323b019803200241033a00c003200220313b019a03200241003b01d00320334102490d0420302f000021322001200a416e6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001221312001200a416c6a22333602042001201c41146a2230360200200220323b019c03200241043a00c003200220313b019e03200241003b01d00320334102490d0420302f000021322001200a416a6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001621312001200a41686a22333602042001201c41186a2230360200200220323b01a003200241053a00c003200220313b01a203200241003b01d00320334102490d0420302f000021322001200a41666a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001a21312001200a41646a22333602042001201c411c6a2230360200200220323b01a403200241063a00c003200220313b01a603200241003b01d00320334102490d0420302f000021322001200a41626a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001e21312001200a41606a22333602042001201c41206a2230360200200220323b01a803200241073a00c003200220313b01aa03200241003b01d00320334102490d0420302f000021322001200a415e6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002221312001200a415c6a22333602042001201c41246a2230360200200220323b01ac03200241083a00c003200220313b01ae03200241003b01d00320334102490d0420302f000021322001200a415a6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002621312001200a41586a22333602042001201c41286a2230360200200220323b01b003200241093a00c003200220313b01b203200241003b01d00320334102490d0420302f000021322001200a41566a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002a21312001200a41546a22333602042001201c412c6a2230360200200220323b01b4032002410a3a00c003200220313b01b603200241003b01d00320334102490d0420302f000021322001200a41526a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002e21312001200a41506a22333602042001201c41306a2230360200200220323b01b8032002410b3a00c003200220313b01ba03200241003b01d00320334102490d0420302f000021322001200a414e6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f003221302001200a414c6a22313602042001201c41346a221c360200200220323b01bc032002410c3a00c003200220303b01be03200241d0036a41286a20024190036a41286a290300220b370300200241d0036a41206a20024190036a41206a2903002212370300200241d0036a41186a20024190036a41186a2903002213370300200241d0036a41106a20024190036a41106a2903002214370300200241d0036a41086a20024190036a41086a2903002236370300200220022903900322373703d003200241d0026a41286a2230200b370300200241d0026a41206a22322012370300200241d0026a41186a22332013370300200241d0026a41106a22352014370300200241d0026a41086a22382036370300200220373703d00220314102490d05201c2f000021312001200a414a6a3602042001201c41026a36020020024190026a41106a2035290300220b37030020024190026a41186a20332903002212370300200241d0016a41086a220a2038290300370300200241d0016a41106a221c200b370300200241d0016a41186a22332012370300200241d0016a41206a22352032290300370300200241d0016a41286a22322030290300370300200220022903d0023703d00120024190016a41286a2230203229030037030020024190016a41206a2232203529030037030020024190016a41186a2235203329030037030020024190016a41106a2233201c29030037030020024190016a41086a221c200a290300370300200220022903d001370390010240202b200228028401470d0020024180016a202b410110a201200228028001212f200228028801212b0b202f202b41386c6a220a2034360200200a2002290390013702042030290300210b203229030021122035290300211320332903002114201c2903002136200a20313b0134200a410c6a2036370200200a41146a2014370200200a411c6a2013370200200a41246a2012370200200a412c6a200b3702002002202b41016a222b36028801202e417f6a222e0d000b20022802840121340b202f450d04200241106a200110c401024002400240024002400240024020022802100d00200228021422392001280204413c6e220a200a20394b1bad423c7e220b422088a70d07200ba7220a417f4c0d0702400240200a0d004104213a0c010b200a1033223a450d090b4100213b20024100360288012002203a360280012002200a413c6e2235360284010240024002402039450d004100213b4100213c0340200128020422354104490d03203c41016a213c417c211c20012802002238280000213d20012035417c6a3602042001203841046a3602004100210a200241003a00c403410021310340200241003b01d0032035201c6a222e4102490d032038200a6a223041046a2f000021322001202e417e6a222e3602042001203041066a2230360200200241003b01d003202e4102490d0320024190036a200a6a223320323b0100203341026a20302f00003b01002001202e417e6a3602042001203041026a3602002002203141016a22313a00c403201c417c6a211c200a41046a220a4134470d000b200241d0036a41306a222e20024190036a41306a280200360200200241d0036a41286a223020024190036a41286a290300370300200241d0036a41206a223220024190036a41206a290300370300200241d0036a41186a223320024190036a41186a290300370300200241d0036a41106a223e20024190036a41106a290300370300200241d0036a41086a223f20024190036a41086a29030037030020022002290390033703d003203141ff0171410d490d03200241d0026a41306a2231202e280200360200200241d0026a41286a222e2030290300370300200241d0026a41206a22302032290300370300200241d0026a41186a22322033290300370300200241d0026a41106a2233203e290300370300200241d0026a41086a223e203f290300370300200220022903d0033703d0022035201c6a41014d0d032038200a6a221c41046a2f0000213820012035200a6b417a6a3602042001201c41066a36020020024190026a41086a203e290300220b37030020024190026a41106a2033290300221237030020024190026a41186a2032290300221337030020024190026a41206a2030290300221437030020024190026a41286a202e290300223637030020024190026a41306a2031280200220a360200200220022903d002223737039002200241d0016a41306a221c200a360200200241d0016a41286a220a2036370300200241d0016a41206a222e2014370300200241d0016a41186a22302013370300200241d0016a41106a22312012370300200241d0016a41086a2232200b370300200220373703d00120024190016a41306a2233201c28020036020020024190016a41286a221c200a29030037030020024190016a41206a2235202e29030037030020024190016a41186a222e203029030037030020024190016a41106a2230203129030037030020024190016a41086a22312032290300370300200220022903d001370390010240203b200228028401470d0020024180016a203b410110aa01200228028001213a200228028801213b0b203a203b413c6c6a220a203d360200200a20022903900137020420332802002132201c290300210b20352903002112202e29030021132030290300211420312903002136200a20383b0138200a410c6a2036370200200a41146a2014370200200a411c6a2013370200200a41246a2012370200200a412c6a200b370200200a41346a20323602002002203b41016a223b36028801203c2039470d000b20022802840121350b203a450d02200241086a200110c40120022802080d05200228020c223d2001280204410676220a200a203d4b1b221c410674220a417f4c0d09201c0d034104213c0c040b203141ff0171450d00200241003a00c4030b200241d0016a41306a20024190026a41306a280200360200200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d002001413c6c450d00203a10350b2000410036020002402034450d00203441386c450d00202f10350b0240202d450d00202d41346c450d00202c10350b0240202a450d00202a41306c450d00202910350b02402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d1c0c1d0b200a1033223c450d060b4100213e20024100360288012002201c360284012002203c36028001024002400240203d450d004100213e4100213f0340200128020422384104490d03203f41016a213f417c211c20012802002239280000214020012038417c6a3602042001203941046a3602004100210a200241003a00c803410021310340200241003b01d0032038201c6a222e4102490d032039200a6a223041046a2f000021322001202e417e6a222e3602042001203041066a2230360200200241003b01d003202e4102490d0320024190036a200a6a223320323b0100203341026a20302f00003b01002001202e417e6a3602042001203041026a3602002002203141016a22313a00c803201c417c6a211c200a41046a220a4138470d000b200241d0036a41306a222e20024190036a41306a290300370300200241d0036a41286a223020024190036a41286a290300370300200241d0036a41206a223220024190036a41206a290300370300200241d0036a41186a223320024190036a41186a290300370300200241d0036a41106a224120024190036a41106a290300370300200241d0036a41086a224220024190036a41086a29030037030020022002290390033703d003203141ff0171410e490d03200241d0026a41306a2231202e290300370300200241d0026a41286a222e2030290300370300200241d0026a41206a22302032290300370300200241d0026a41186a22322033290300370300200241d0026a41106a22332041290300370300200241d0026a41086a22412042290300370300200220022903d0033703d0022038201c6a41014d0d032039200a6a221c41046a2f0000213920012038200a6b417a6a3602042001201c41066a36020020024190026a41086a2041290300220b37030020024190026a41106a2033290300221237030020024190026a41186a2032290300221337030020024190026a41206a2030290300221437030020024190026a41286a202e290300223637030020024190026a41306a20312903002237370300200220022903d002224337039002200241d0016a41306a220a2037370300200241d0016a41286a221c2036370300200241d0016a41206a222e2014370300200241d0016a41186a22302013370300200241d0016a41106a22312012370300200241d0016a41086a2232200b370300200220433703d00120024190016a41306a2233200a29030037030020024190016a41286a2238201c29030037030020024190016a41206a221c202e29030037030020024190016a41186a222e203029030037030020024190016a41106a2230203129030037030020024190016a41086a22312032290300370300200220022903d001370390010240203e200228028401470d0020024180016a203e410110a601200228028001213c200228028801213e0b203c203e4106746a220a2040360200200a2002290390013702042033290300210b20382903002112201c2903002113202e29030021142030290300213620312903002137200a20393b013c200a410c6a2037370200200a41146a2036370200200a411c6a2014370200200a41246a2013370200200a412c6a2012370200200a41346a200b3702002002203e41016a223e36028801203f203d470d000b200228028401211c0b203c450d022002200110c40120022802000d0520022802042240200128020441c4006e220a200a20404b1bad42c4007e220b422088a70d06200ba7220a417f4c0d06200a0d034104213f0c040b203141ff0171450d00200241003a00c8030b200241d0016a41306a20024190026a41306a290300370300200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a29030037030020022802840141ffffff1f71450d00203c10350b2000410036020002402035450d002035413c6c450d00203a10350b02402034450d00203441386c450d00202f10350b0240202d450d00202d41346c450d00202c10350b0240202a450d00202a41306c450d00202910350b02402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d190c1a0b200a1033223f450d030b20024100360288012002203f360280012002200a41c4006e360284010240024002402040450d0041002142410021410340200128020422394104490d03204141016a2141417c212e2001280200223d280000214420012039417c6a3602042001203d41046a3602004100210a200241003a00cc03410021320340200241003b01d0032039202e6a22304102490d03203d200a6a223141046a2f0000213320012030417e6a22303602042001203141066a2231360200200241003b01d00320304102490d0320024190036a200a6a223820333b0100203841026a20312f00003b010020012030417e6a3602042001203141026a3602002002203241016a22323a00cc03202e417c6a212e200a41046a220a413c470d000b200241d0036a41386a223020024190036a41386a280200360200200241d0036a41306a223120024190036a41306a290300370300200241d0036a41286a223320024190036a41286a290300370300200241d0036a41206a223820024190036a41206a290300370300200241d0036a41186a224520024190036a41186a290300370300200241d0036a41106a224620024190036a41106a290300370300200241d0036a41086a224720024190036a41086a29030037030020022002290390033703d003203241ff0171410f490d03200241d0026a41386a22322030280200360200200241d0026a41306a22302031290300370300200241d0026a41286a22312033290300370300200241d0026a41206a22332038290300370300200241d0026a41186a22382045290300370300200241d0026a41106a22452046290300370300200241d0026a41086a22462047290300370300200220022903d0033703d0022039202e6a41014d0d03203d200a6a222e41046a2f0000213d20012039200a6b417a6a3602042001202e41066a36020020024190026a41086a220a204629030037030020024190026a41106a222e204529030037030020024190026a41186a2239203829030037030020024190026a41206a2238203329030037030020024190026a41286a2233203129030037030020024190026a41306a2231203029030037030020024190026a41386a22302032280200360200200220022903d00237039002200241d0016a41086a200a290300220b370300200241d0016a41106a202e2903002212370300200241d0016a41186a20392903002213370300200241d0016a41206a20382903002214370300200241d0016a41286a20332903002236370300200241d0016a41306a20312903002237370300200241d0016a41386a2030280200220a36020020024190016a41086a222e200b37030020024190016a41106a2230201237030020024190016a41186a2231201337030020024190016a41206a2232201437030020024190016a41286a2233203637030020024190016a41306a2238203737030020024190016a41386a2239200a3602002002200229039002220b3703d0012002200b3703900102402042200228028401470d0020024180016a20424101109f01200228028001213f20022802880121420b203f204241c4006c6a220a2044360200200a200229039001370204203928020021392038290300210b20332903002112203229030021132031290300211420302903002136202e2903002137200a203d3b0140200a410c6a2037370200200a41146a2036370200200a411c6a2014370200200a41246a2013370200200a412c6a2012370200200a41346a200b370200200a413c6a20393602002002204241016a22423602880120412040470d000b0b203f450d02200229028401210b2000200536020420002006360200200041b8016a200b370200200041b4016a203f360200200041b0016a203e360200200041ac016a201c360200200041a8016a203c360200200041a4016a203b360200200041a0016a20353602002000419c016a203a36020020004198016a202b36020020004194016a203436020020004190016a202f3602002000418c016a202836020020004188016a202d36020020004184016a202c36020020004180016a2025360200200041fc006a202a360200200041f8006a2029360200200041f4006a2022360200200041f0006a2027360200200041ec006a2026360200200041e8006a201f360200200041e4006a2024360200200041e0006a2023360200200041dc006a201d360200200041d8006a2020360200200041d4006a2021360200200041d0006a2019360200200041cc006a2009360200200041c8006a201e360200200041c4006a2017360200200041c0006a201a3602002000413c6a201b360200200041386a2010360200200041346a2016360200200041306a20183602002000412c6a200e360200200041286a2011360200200041246a2015360200200041206a20083602002000411c6a2003360200200041186a200f360200200041146a2007360200200041106a200d3602002000410c6a200c360200200041086a20043602000c1a0b203241ff0171450d00200241003a00cc030b200241d0016a41386a20024190026a41386a280200360200200241d0016a41306a20024190026a41306a290300370300200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141c4006c450d00203f10350b200041003602000240201c41ffffff1f71450d00203c10350b02402035450d002035413c6c450d00203a10350b02402034450d00203441386c450d00202f10350b0240202d450d00202d41346c450d00202c10350b0240202a450d00202a41306c450d00202910350b02402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff0171450d170c160b1044000b1045000b200241003a00c0030b200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141386c450d00202f10350b200041003602000240202d450d00202d41346c450d00202c10350b0240202a450d00202a41306c450d00202910350b02402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d110c120b200241003a00bc030b200241d0016a41286a20024190026a41286a280200360200200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141346c450d00202c10350b200041003602000240202a450d00202a41306c450d00202910350b02402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d0e0c0f0b200241003a00b8030b200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141306c450d00202910350b2000410036020002402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d0b0c0c0b200241003a00b4030b200241d0016a41206a20024190026a41206a280200360200200241d0016a41186a20024190026a41186a2903003703002002280284012201450d002001412c6c450d00202610350b2000410036020002402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d080c090b2000410036020002402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d070c080b200041003602000240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d060c070b200041003602000240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d050c060b2000410036020002402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d040c050b2000410036020002402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d030c040b200041003602000240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d020c030b200041003602000240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d010c020b20004100360200200541ffffffff0171450d010b200610350b20024190046a24000bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad421c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003411c6c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a2001411c6e3602000b0bf70301017f0240200041046a28020041ffffffff0171450d00200028020010350b0240200041106a2802002201450d002001410c6c450d00200028020c10350b02402000411c6a28020041ffffffff0071450d00200028021810350b0240200041286a2802002201450d00200141146c450d00200028022410350b0240200041346a2802002201450d00200141186c450d00200028023010350b0240200041c0006a2802002201450d002001411c6c450d00200028023c10350b0240200041cc006a28020041ffffff3f71450d00200028024810350b0240200041d8006a2802002201450d00200141246c450d00200028025410350b0240200041e4006a2802002201450d00200141286c450d00200028026010350b0240200041f0006a2802002201450d002001412c6c450d00200028026c10350b0240200041fc006a2802002201450d00200141306c450d00200028027810350b024020004188016a2802002201450d00200141346c450d0020002802840110350b024020004194016a2802002201450d00200141386c450d0020002802900110350b0240200041a0016a2802002201450d002001413c6c450d00200028029c0110350b0240200041ac016a28020041ffffff1f71450d0020002802a80110350b0240200041b8016a2802002201450d00200141c4006c450d0020002802b40110350b0be49301032a7f047e247f23004180026b22042400200441b8016a4200370300200441b0016a22054280808080c000370300200441a0016a420037030020044198016a22064280808080c00037030020044188016a420037030020044180016a22074280808080c000370300200441f0006a4200370300200441e8006a22084280808080c000370300200441d8006a4200370300200441d0006a22094280808080c000370300200441c0006a4200370300200441386a220a4280808080c000370300200441286a4200370300200441206a220b4280808080c000370300200441106a4200370300200442043703a8012004420437039001200442043703782004420437036020044204370348200442043703302004420437031820044280808080c000370308200442043703002001280200220c2001280208220d412c6c220e6a210f20012802042110200c2101024002400240200d450d00200441bc016a2111200441b4016a2112200441a8016a2113200441a4016a21142004419c016a211520044190016a21162004418c016a211720044184016a2118200441f8006a2119200441f4006a211a200441ec006a211b200441e0006a211c200441dc006a211d200441d4006a211e200441c8006a211f200441c4006a21202004413c6a2121200441306a21222004412c6a2123200441246a2124200441186a2125200441146a21262004410c6a2127200441086a2128200e41546a210d200441e0016a41086a2129200441e0016a41106a212a200441e0016a41186a212b200c210e0340200e280208212c200e280204212d2029200e41146a290200370300202a200e411c6a290200370300202b200e41246a2902003703002004200e29020c3703e001200e412c6a2101200e280200220e450d01200441c0016a41186a202b290300222e370300200441c0016a41106a202a290300222f370300200441c0016a41086a20292903002230370300200420042903e00122313703c001202b202e370300202a202f37030020292030370300200420313703e001024002400240202c41104d0d00410121320c010b024002400240024002400240024002400240024002400240024002400240024002400240202c0e11000102030405060708090a0b0c0d0e0f10000b0240202d450d00202d41226c450d00200e10350b2001200f460d150c120b4102213220022802082233450d102002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c120b0b20032802082234450d102003280200212c203441057421354100213402400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c120b0b2034418080044f0d1002402004280208222c2004280204470d002004202c41011090012004280208212c0b2004280200202c4103746a222c20343b0104202c20333602002028212c0c0f0b4102213220022802082233450d0f2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c110b0b2003280208222c450d0f41002135202c4105742237213620032802002234212c02400340200e202c460d012035202c200e412010a00822384100476a21352038450d01202c41206a212c203641606a22360d000c110b0b203541ffff034b0d0f200e41226a2136200e2f012021394100212c0240034020362034460d01202c20342036412010a00822384100476a212c2038450d01203441206a2134203741606a22370d000c110b0b202c41ffff034b0d0f0240200428021422322004280210470d00202720324101108701200428021421320b200428020c2032410c6c6a2232202c3b0108203220353b010420322033360200203241066a20393b01002026212c0c0e0b4102213220022802082233450d0e2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c100b0b2003280208222c450d0e41002134202c410574223a213520032802002238212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c100b0b203441ffff034b0d0e200e41226a2136200e2f0120213b41002135203a21372038212c024003402036202c460d012035202c2036412010a00822394100476a21352039450d01202c41206a212c203741606a22370d000c100b0b203541ffff034b0d0e200e41c4006a2136200e41c2006a2f010021394100212c0240034020362038460d01202c20382036412010a00822374100476a212c2037450d01203841206a2138203a41606a223a0d000c100b0b202c41ffff034b0d0e024020042802202232200428021c470d00202520324101108c01200428022021320b200428021820324104746a2232202c3b010c203220343b0104203220333602002032410a6a20393b0100203241086a20353b0100203241066a203b3b0100200b212c0c0d0b4102213220022802082233450d0d2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0f0b0b2003280208222c450d0d41002134202c410574223b213520032802002237212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0f0b0b203441ffff034b0d0d200e41226a2136200e2f0120213c41002135203b21382037212c024003402036202c460d012035202c2036412010a00822394100476a21352039450d01202c41206a212c203841606a22380d000c0f0b0b203541ffff034b0d0d200e41c4006a2138200e41c2006a2f0100213d41002136203b21392037212c024003402038202c460d012036202c2038412010a008223a4100476a2136203a450d01202c41206a212c203941606a22390d000c0f0b0b203641ffff034b0d0d200e41e6006a2138200e41e4006a2f0100213a4100212c0240034020382037460d01202c20372038412010a00822394100476a212c2039450d01203741206a2137203b41606a223b0d000c0f0b0b202c41ffff034b0d0d0240200428022c22322004280228470d00202420324101109901200428022c21320b2004280224203241146c6a2232202c3b0110203220343b0104203220333602002032410e6a203a3b01002032410c6a20363b01002032410a6a203d3b0100203241086a20353b0100203241066a203c3b01002023212c0c0c0b4102213220022802082233450d0c2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0e0b0b2003280208222c450d0c41002134202c410574223b213520032802002239212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0e0b0b203441ffff034b0d0c200e41226a2136200e2f0120213d41002135203b21382039212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c0e0b0b203541ffff034b0d0c200e41c4006a2138200e41c2006a2f0100213e41002136203b21372039212c024003402038202c460d012036202c2038412010a008223a4100476a2136203a450d01202c41206a212c203741606a22370d000c0e0b0b203641ffff034b0d0c200e41e6006a2137200e41e4006a2f0100213f41002138203b213a2039212c024003402037202c460d012038202c2037412010a008223c4100476a2138203c450d01202c41206a212c203a41606a223a0d000c0e0b0b203841ffff034b0d0c200e4188016a2137200e4186016a2f0100213c4100212c0240034020372039460d01202c20392037412010a008223a4100476a212c203a450d01203941206a2139203b41606a223b0d000c0e0b0b202c41ffff034b0d0c0240200428023822322004280234470d00202220324101109701200428023821320b2004280230203241186c6a2232202c3b0114203220343b010420322033360200203241126a203c3b0100203241106a20383b01002032410e6a203f3b01002032410c6a20363b01002032410a6a203e3b0100203241086a20353b0100203241066a203d3b0100200a212c0c0b0b4102213220022802082233450d0b2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0d0b0b2003280208222c450d0b41002134202c410574223c21352003280200223a212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0d0b0b203441ffff034b0d0b200e41226a2136200e2f0120213e41002135203c2138203a212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c0d0b0b203541ffff034b0d0b200e41c4006a2138200e41c2006a2f0100213f41002136203c2137203a212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c0d0b0b203641ffff034b0d0b200e41e6006a2137200e41e4006a2f0100214041002138203c2139203a212c024003402037202c460d012038202c2037412010a008223b4100476a2138203b450d01202c41206a212c203941606a22390d000c0d0b0b203841ffff034b0d0b200e4188016a2139200e4186016a2f0100214141002137203c213b203a212c024003402039202c460d012037202c2039412010a008223d4100476a2137203d450d01202c41206a212c203b41606a223b0d000c0d0b0b203741ffff034b0d0b200e41aa016a2139200e41a8016a2f0100213d4100212c024003402039203a460d01202c203a2039412010a008223b4100476a212c203b450d01203a41206a213a203c41606a223c0d000c0d0b0b202c41ffff034b0d0b0240200428024422322004280240470d0020212032410110f901200428024421320b200428023c2032411c6c6a2232202c3b0118203220343b010420322033360200203241166a203d3b0100203241146a20373b0100203241126a20413b0100203241106a20383b01002032410e6a20403b01002032410c6a20363b01002032410a6a203f3b0100203241086a20353b0100203241066a203e3b01002020212c0c0a0b4102213220022802082233450d0a2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0c0b0b2003280208222c450d0a41002134202c410574223c21352003280200223a212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0c0b0b203441ffff034b0d0a200e41226a2136200e2f0120213f41002135203c2138203a212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c0c0b0b203541ffff034b0d0a200e41c4006a2138200e41c2006a2f0100214041002136203c2137203a212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c0c0b0b203641ffff034b0d0a200e41e6006a2137200e41e4006a2f0100214141002138203c2139203a212c024003402037202c460d012038202c2037412010a008223b4100476a2138203b450d01202c41206a212c203941606a22390d000c0c0b0b203841ffff034b0d0a200e4188016a2139200e4186016a2f0100214241002137203c213b203a212c024003402039202c460d012037202c2039412010a008223d4100476a2137203d450d01202c41206a212c203b41606a223b0d000c0c0b0b203741ffff034b0d0a200e41aa016a213b200e41a8016a2f0100214341002139203c213d203a212c02400340203b202c460d012039202c203b412010a008223e4100476a2139203e450d01202c41206a212c203d41606a223d0d000c0c0b0b203941ffff034b0d0a200e41cc016a213b200e41ca016a2f0100213e4100212c02400340203b203a460d01202c203a203b412010a008223d4100476a212c203d450d01203a41206a213a203c41606a223c0d000c0c0b0b202c41ffff034b0d0a024020042802502232200428024c470d00201f20324101109101200428025021320b200428024820324105746a2232202c3b011c203220343b0104203220333602002032411a6a203e3b0100203241186a20393b0100203241166a20433b0100203241146a20373b0100203241126a20423b0100203241106a20383b01002032410e6a20413b01002032410c6a20363b01002032410a6a20403b0100203241086a20353b0100203241066a203f3b01002009212c0c090b4102213220022802082233450d092002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0b0b0b2003280208222c450d0941002134202c410574223d21352003280200223b212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0b0b0b203441ffff034b0d09200e41226a2136200e2f0120214041002135203d2138203b212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c0b0b0b203541ffff034b0d09200e41c4006a2138200e41c2006a2f0100214141002136203d2137203b212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c0b0b0b203641ffff034b0d09200e41e6006a2137200e41e4006a2f0100214241002138203d2139203b212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a22390d000c0b0b0b203841ffff034b0d09200e4188016a2139200e4186016a2f0100214341002137203d213a203b212c024003402039202c460d012037202c2039412010a008223c4100476a2137203c450d01202c41206a212c203a41606a223a0d000c0b0b0b203741ffff034b0d09200e41aa016a213a200e41a8016a2f0100214441002139203d213c203b212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203c41606a223c0d000c0b0b0b203941ffff034b0d09200e41cc016a213c200e41ca016a2f010021454100213a203d213e203b212c02400340203c202c460d01203a202c203c412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c0b0b0b203a41ffff034b0d09200e41ee016a213c200e41ec016a2f0100213f4100212c02400340203c203b460d01202c203b203c412010a008223e4100476a212c203e450d01203b41206a213b203d41606a223d0d000c0b0b0b202c41ffff034b0d090240200428025c22322004280258470d00201e20324101108d01200428025c21320b2004280254203241246c6a2232202c3b0120203220343b0104203220333602002032411e6a203f3b01002032411c6a203a3b01002032411a6a20453b0100203241186a20393b0100203241166a20443b0100203241146a20373b0100203241126a20433b0100203241106a20383b01002032410e6a20423b01002032410c6a20363b01002032410a6a20413b0100203241086a20353b0100203241066a20403b0100201d212c0c080b4102213220022802082233450d082002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0a0b0b2003280208222c450d0841002134202c410574223d21352003280200223b212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0a0b0b203441ffff034b0d08200e41226a2136200e2f0120214141002135203d2138203b212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c0a0b0b203541ffff034b0d08200e41c4006a2138200e41c2006a2f0100214241002136203d2137203b212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c0a0b0b203641ffff034b0d08200e41e6006a2137200e41e4006a2f0100214341002138203d2139203b212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a22390d000c0a0b0b203841ffff034b0d08200e4188016a2139200e4186016a2f0100214441002137203d213a203b212c024003402039202c460d012037202c2039412010a008223c4100476a2137203c450d01202c41206a212c203a41606a223a0d000c0a0b0b203741ffff034b0d08200e41aa016a213a200e41a8016a2f0100214541002139203d213c203b212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203c41606a223c0d000c0a0b0b203941ffff034b0d08200e41cc016a213c200e41ca016a2f010021464100213a203d213e203b212c02400340203c202c460d01203a202c203c412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c0a0b0b203a41ffff034b0d08200e41ee016a213e200e41ec016a2f010021474100213c203d213f203b212c02400340203e202c460d01203c202c203e412010a00822404100476a213c2040450d01202c41206a212c203f41606a223f0d000c0a0b0b203c41ffff034b0d08200e4190026a213e200e418e026a2f010021404100212c02400340203e203b460d01202c203b203e412010a008223f4100476a212c203f450d01203b41206a213b203d41606a223d0d000c0a0b0b202c41ffff034b0d080240200428026822322004280264470d00201c20324101109d01200428026821320b2004280260203241286c6a2232202c3b0124203220343b010420322033360200203241226a20403b0100203241206a203c3b01002032411e6a20473b01002032411c6a203a3b01002032411a6a20463b0100203241186a20393b0100203241166a20453b0100203241146a20373b0100203241126a20443b0100203241106a20383b01002032410e6a20433b01002032410c6a20363b01002032410a6a20423b0100203241086a20353b0100203241066a20413b01002008212c0c070b4102213220022802082233450d072002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c090b0b2003280208222c450d0741002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c090b0b203441ffff034b0d07200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c090b0b203541ffff034b0d07200e41c4006a2138200e41c2006a2f0100214341002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c090b0b203641ffff034b0d07200e41e6006a2137200e41e4006a2f0100214441002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a22390d000c090b0b203841ffff034b0d07200e4188016a2139200e4186016a2f0100214541002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a0d000c090b0b203741ffff034b0d07200e41aa016a213a200e41a8016a2f0100214641002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b0d000c090b0b203941ffff034b0d07200e41cc016a213b200e41ca016a2f010021474100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c090b0b203a41ffff034b0d07200e41ee016a213e200e41ec016a2f010021484100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f0d000c090b0b203b41ffff034b0d07200e4190026a213f200e418e026a2f010021494100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a22400d000c090b0b203e41ffff034b0d07200e41b2026a213f200e41b0026a2f010021414100212c02400340203f203c460d01202c203c203f412010a00822404100476a212c2040450d01203c41206a213c203d41606a223d0d000c090b0b202c41ffff034b0d070240200428027422322004280270470d00201b20324101109801200428027421320b200428026c2032412c6c6a2232202c3b0128203220343b010420322033360200203241266a20413b0100203241246a203e3b0100203241226a20493b0100203241206a203b3b01002032411e6a20483b01002032411c6a203a3b01002032411a6a20473b0100203241186a20393b0100203241166a20463b0100203241146a20373b0100203241126a20453b0100203241106a20383b01002032410e6a20443b01002032410c6a20363b01002032410a6a20433b0100203241086a20353b0100203241066a20423b0100201a212c0c060b4102213220022802082233450d062002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c080b0b2003280208222c450d0641002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c080b0b203441ffff034b0d06200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c080b0b203541ffff034b0d06200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c080b0b203641ffff034b0d06200e41e6006a2137200e41e4006a2f0100214541002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a22390d000c080b0b203841ffff034b0d06200e4188016a2139200e4186016a2f0100214641002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a0d000c080b0b203741ffff034b0d06200e41aa016a213a200e41a8016a2f0100214741002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b0d000c080b0b203941ffff034b0d06200e41cc016a213b200e41ca016a2f010021484100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c080b0b203a41ffff034b0d06200e41ee016a213e200e41ec016a2f010021494100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f0d000c080b0b203b41ffff034b0d06200e4190026a213f200e418e026a2f0100214a4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a22400d000c080b0b203e41ffff034b0d06200e41b2026a2140200e41b0026a2f0100214b4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d080c000b0b203f41ffff034b0d06200e41d4026a2140200e41d2026a2f010021434100212c024003402040203c460d01202c203c2040412010a00822414100476a212c2041450d01203c41206a213c203d41606a223d450d080c000b0b202c41ffff034b0d0602402004280280012232200428027c470d0020192032410110890120042802800121320b2004280278203241306c6a2232202c3b012c203220343b0104203220333602002032412a6a20433b0100203241286a203f3b0100203241266a204b3b0100203241246a203e3b0100203241226a204a3b0100203241206a203b3b01002032411e6a20493b01002032411c6a203a3b01002032411a6a20483b0100203241186a20393b0100203241166a20473b0100203241146a20373b0100203241126a20463b0100203241106a20383b01002032410e6a20453b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002007212c0c050b4102213220022802082233450d052002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a2234450d070c000b0b2003280208222c450d0541002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a2235450d070c000b0b203441ffff034b0d05200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a2238450d070c000b0b203541ffff034b0d05200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a2237450d070c000b0b203641ffff034b0d05200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a2239450d070c000b0b203841ffff034b0d05200e4188016a2139200e4186016a2f0100214741002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a450d070c000b0b203741ffff034b0d05200e41aa016a213a200e41a8016a2f0100214841002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b450d070c000b0b203941ffff034b0d05200e41cc016a213b200e41ca016a2f010021494100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e450d070c000b0b203a41ffff034b0d05200e41ee016a213e200e41ec016a2f0100214a4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f450d070c000b0b203b41ffff034b0d05200e4190026a213f200e418e026a2f0100214b4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a2240450d070c000b0b203e41ffff034b0d05200e41b2026a2140200e41b0026a2f0100214c4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d070c000b0b203f41ffff034b0d05200e41d4026a2141200e41d2026a2f0100214d41002140203d2143203c212c024003402041202c460d012040202c2041412010a00822454100476a21402045450d01202c41206a212c204341606a2243450d070c000b0b204041ffff034b0d05200e41f6026a2141200e41f4026a2f010021454100212c024003402041203c460d01202c203c2041412010a00822434100476a212c2043450d01203c41206a213c203d41606a223d450d070c000b0b202c41ffff034b0d050240200428028c012232200428028801470d0020182032410110a501200428028c0121320b200428028401203241346c6a2232202c3b0130203220343b0104203220333602002032412e6a20453b01002032412c6a20403b01002032412a6a204d3b0100203241286a203f3b0100203241266a204c3b0100203241246a203e3b0100203241226a204b3b0100203241206a203b3b01002032411e6a204a3b01002032411c6a203a3b01002032411a6a20493b0100203241186a20393b0100203241166a20483b0100203241146a20373b0100203241126a20473b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002017212c0c040b4102213220022802082233450d042002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a2234450d060c000b0b2003280208222c450d0441002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a2235450d060c000b0b203441ffff034b0d04200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a2238450d060c000b0b203541ffff034b0d04200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a2237450d060c000b0b203641ffff034b0d04200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a2239450d060c000b0b203841ffff034b0d04200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a450d060c000b0b203741ffff034b0d04200e41aa016a213a200e41a8016a2f0100214941002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b450d060c000b0b203941ffff034b0d04200e41cc016a213b200e41ca016a2f0100214a4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e450d060c000b0b203a41ffff034b0d04200e41ee016a213e200e41ec016a2f0100214b4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f450d060c000b0b203b41ffff034b0d04200e4190026a213f200e418e026a2f0100214c4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a2240450d060c000b0b203e41ffff034b0d04200e41b2026a2140200e41b0026a2f0100214d4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d060c000b0b203f41ffff034b0d04200e41d4026a2141200e41d2026a2f0100214e41002140203d2143203c212c024003402041202c460d012040202c2041412010a00822454100476a21402045450d01202c41206a212c204341606a2243450d060c000b0b204041ffff034b0d04200e41f6026a2143200e41f4026a2f0100214f41002141203d2145203c212c024003402043202c460d012041202c2043412010a00822474100476a21412047450d01202c41206a212c204541606a2245450d060c000b0b204141ffff034b0d04200e4198036a2143200e4196036a2f010021474100212c024003402043203c460d01202c203c2043412010a00822454100476a212c2045450d01203c41206a213c203d41606a223d450d060c000b0b202c41ffff034b0d0402402004280298012232200428029401470d0020162032410110a20120042802980121320b200428029001203241386c6a2232202c3b0134203220343b010420322033360200203241326a20473b0100203241306a20413b01002032412e6a204f3b01002032412c6a20403b01002032412a6a204e3b0100203241286a203f3b0100203241266a204d3b0100203241246a203e3b0100203241226a204c3b0100203241206a203b3b01002032411e6a204b3b01002032411c6a203a3b01002032411a6a204a3b0100203241186a20393b0100203241166a20493b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002006212c0c030b4102213220022802082233450d032002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a2234450d050c000b0b2003280208222c450d0341002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a2235450d050c000b0b203441ffff034b0d03200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a2238450d050c000b0b203541ffff034b0d03200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a2237450d050c000b0b203641ffff034b0d03200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a2239450d050c000b0b203841ffff034b0d03200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a450d050c000b0b203741ffff034b0d03200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b450d050c000b0b203941ffff034b0d03200e41cc016a213b200e41ca016a2f0100214b4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e450d050c000b0b203a41ffff034b0d03200e41ee016a213e200e41ec016a2f0100214c4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f450d050c000b0b203b41ffff034b0d03200e4190026a213f200e418e026a2f0100214d4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a2240450d050c000b0b203e41ffff034b0d03200e41b2026a2140200e41b0026a2f0100214e4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d050c000b0b203f41ffff034b0d03200e41d4026a2141200e41d2026a2f0100214f41002140203d2143203c212c024003402041202c460d012040202c2041412010a00822454100476a21402045450d01202c41206a212c204341606a2243450d050c000b0b204041ffff034b0d03200e41f6026a2143200e41f4026a2f0100215041002141203d2145203c212c024003402043202c460d012041202c2043412010a00822474100476a21412047450d01202c41206a212c204541606a2245450d050c000b0b204141ffff034b0d03200e4198036a2145200e4196036a2f0100215141002143203d2147203c212c024003402045202c460d012043202c2045412010a00822494100476a21432049450d01202c41206a212c204741606a2247450d050c000b0b204341ffff034b0d03200e41ba036a2145200e41b8036a2f010021494100212c024003402045203c460d01202c203c2045412010a00822474100476a212c2047450d01203c41206a213c203d41606a223d450d050c000b0b202c41ffff034b0d03024020042802a401223220042802a001470d0020152032410110aa0120042802a40121320b200428029c012032413c6c6a2232202c3b0138203220343b010420322033360200203241366a20493b0100203241346a20433b0100203241326a20513b0100203241306a20413b01002032412e6a20503b01002032412c6a20403b01002032412a6a204f3b0100203241286a203f3b0100203241266a204e3b0100203241246a203e3b0100203241226a204d3b0100203241206a203b3b01002032411e6a204c3b01002032411c6a203a3b01002032411a6a204b3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002014212c0c020b4102213220022802082233450d022002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a2234450d040c000b0b2003280208222c450d0241002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a2235450d040c000b0b203441ffff034b0d02200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a2238450d040c000b0b203541ffff034b0d02200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a2237450d040c000b0b203641ffff034b0d02200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a2239450d040c000b0b203841ffff034b0d02200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a450d040c000b0b203741ffff034b0d02200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b450d040c000b0b203941ffff034b0d02200e41cc016a213b200e41ca016a2f0100214c4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e450d040c000b0b203a41ffff034b0d02200e41ee016a213e200e41ec016a2f0100214d4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f450d040c000b0b203b41ffff034b0d02200e4190026a213f200e418e026a2f0100214e4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a2240450d040c000b0b203e41ffff034b0d02200e41b2026a2140200e41b0026a2f0100214f4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d040c000b0b203f41ffff034b0d02200e41d4026a2141200e41d2026a2f0100215041002140203d2143203c212c024003402041202c460d012040202c2041412010a00822454100476a21402045450d01202c41206a212c204341606a2243450d040c000b0b204041ffff034b0d02200e41f6026a2143200e41f4026a2f0100215141002141203d2145203c212c024003402043202c460d012041202c2043412010a00822474100476a21412047450d01202c41206a212c204541606a2245450d040c000b0b204141ffff034b0d02200e4198036a2145200e4196036a2f0100215241002143203d2147203c212c024003402045202c460d012043202c2045412010a00822494100476a21432049450d01202c41206a212c204741606a2247450d040c000b0b204341ffff034b0d02200e41ba036a2147200e41b8036a2f0100215341002145203d2149203c212c024003402047202c460d012045202c2047412010a008224b4100476a2145204b450d01202c41206a212c204941606a2249450d040c000b0b204541ffff034b0d02200e41dc036a2147200e41da036a2f0100214b4100212c024003402047203c460d01202c203c2047412010a00822494100476a212c2049450d01203c41206a213c203d41606a223d450d040c000b0b202c41ffff034b0d02024020042802b001223220042802ac01470d0020132032410110a60120042802b00121320b20042802a80120324106746a2232202c3b013c203220343b0104203220333602002032413a6a204b3b0100203241386a20453b0100203241366a20533b0100203241346a20433b0100203241326a20523b0100203241306a20413b01002032412e6a20513b01002032412c6a20403b01002032412a6a20503b0100203241286a203f3b0100203241266a204f3b0100203241246a203e3b0100203241226a204e3b0100203241206a203b3b01002032411e6a204d3b01002032411c6a203a3b01002032411a6a204c3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002005212c0c010b4102213220022802082233450d012002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a2234450d030c000b0b2003280208222c450d0141002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a2235450d030c000b0b203441ffff034b0d01200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a2238450d030c000b0b203541ffff034b0d01200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a2237450d030c000b0b203641ffff034b0d01200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a2239450d030c000b0b203841ffff034b0d01200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a450d030c000b0b203741ffff034b0d01200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b450d030c000b0b203941ffff034b0d01200e41cc016a213b200e41ca016a2f0100214c4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e450d030c000b0b203a41ffff034b0d01200e41ee016a213e200e41ec016a2f0100214e4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f450d030c000b0b203b41ffff034b0d01200e4190026a213f200e418e026a2f0100214f4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a2240450d030c000b0b203e41ffff034b0d01200e41b2026a2140200e41b0026a2f010021504100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d030c000b0b203f41ffff034b0d01200e41d4026a2141200e41d2026a2f0100215141002140203d2143203c212c024003402041202c460d012040202c2041412010a00822454100476a21402045450d01202c41206a212c204341606a2243450d030c000b0b204041ffff034b0d01200e41f6026a2143200e41f4026a2f0100215241002141203d2145203c212c024003402043202c460d012041202c2043412010a00822474100476a21412047450d01202c41206a212c204541606a2245450d030c000b0b204141ffff034b0d01200e4198036a2145200e4196036a2f0100215341002143203d2147203c212c024003402045202c460d012043202c2045412010a00822494100476a21432049450d01202c41206a212c204741606a2247450d030c000b0b204341ffff034b0d01200e41ba036a2147200e41b8036a2f0100215441002145203d2149203c212c024003402047202c460d012045202c2047412010a008224b4100476a2145204b450d01202c41206a212c204941606a2249450d030c000b0b204541ffff034b0d01200e41dc036a2149200e41da036a2f0100215541002147203d214b203c212c024003402049202c460d012047202c2049412010a008224d4100476a2147204d450d01202c41206a212c204b41606a224b450d030c000b0b204741ffff034b0d01200e41fe036a2149200e41fc036a2f0100214d4100212c024003402049203c460d01202c203c2049412010a008224b4100476a212c204b450d01203c41206a213c203d41606a223d450d030c000b0b202c41ffff034b0d01024020042802bc01223220042802b801470d00201220324101109f0120042802bc0121320b20042802b401203241c4006c6a2232202c3b0140203220343b0104203220333602002032413e6a204d3b01002032413c6a20473b01002032413a6a20553b0100203241386a20453b0100203241366a20543b0100203241346a20433b0100203241326a20533b0100203241306a20413b01002032412e6a20523b01002032412c6a20403b01002032412a6a20513b0100203241286a203f3b0100203241266a20503b0100203241246a203e3b0100203241226a204f3b0100203241206a203b3b01002032411e6a204e3b01002032411c6a203a3b01002032411a6a204c3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002011212c0b202c202c28020041016a3602000240202d450d00202d41226c450d00200e10350b2001200f460d040c010b200041013a0000200020323a00010240202d450d00202d41226c450d00200e10350b0240200f2001460d0003400240200141046a280200220e450d00200e41226c450d00200128020010350b2001412c6a2101200d41546a220d0d000b0b02402010450d002010412c6c450d00200c10350b200410fa010c040b200d41546a210d2001210e0c000b0b200f2001460d0003402001220d412c6a21010240200d41046a280200220e450d00200e41226c450d00200d28020010350b200f2001470d000b0b02402010450d002010412c6c450d00200c10350b200041046a200441c001109d081a200041003a00000b20044180026a24000bdb0401097f230041c0016b2202240020024188016a200110b701200241306a200228028801220320022802900110d60120024198016a41086a2204200241ec006a29020037030020024198016a41106a2205200241f4006a29020037030020024198016a41186a2206200241fc006a29020037030020024198016a41206a220720024184016a2802003602002002200241e4006a290200370398010240024020022802502208450d00200241e0006a2802002109200241dc006a280200210a20022802542101200241086a41206a2007280200360200200241086a41186a2006290300370300200241086a41106a2005290300370300200241086a41086a200429030037030020022002290398013703080240200228028c01450d00200310350b200241306a41106a200241086a41106a290300370300200241306a41086a200241086a41086a290300370300200241306a41186a200241086a41186a290300370300200241306a41206a200241086a41206a28020036020020024198016a41086a2002413c6a29020037030020024198016a41106a200241c4006a29020037030020024198016a41186a200241cc006a29020037030020022002290308370330200220022902343703980102402001450d00200141186c450d00200810350b0240200941ffffffff0371450d00200a10350b2000200229039801370001200041196a200241b0016a290300370000200041116a200241a8016a290300370000200041096a200241a0016a290300370000410121010c010b0240200228028c01450d00200310350b410021010b200020013a0000200241c0016a24000bea4711047f017e017f017e0c7f017e017f017e067f027e027f037e017f017e047f017e017f23004180046b22052400200541f8026a41186a22064200370300200541f8026a41106a22074200370300200541f8026a41086a22084200370300200542003703f80241f7edcb00ad4280808080f0008422091001220a290000210b200541a8026a41086a220c200a41086a2900003703002005200b3703a802200a10352008200c290300370300200520052903a8023703f80241b6aac000ad42808080809002841001220a290000210b200541b8026a41086a220d200a41086a2900003703002005200b3703b802200a1035200720052903b802220b370300200541b8036a41086a220a2008290300370300200541b8036a41106a220e200b370300200541b8036a41186a220f200d290300370300200520052903f8023703b803200541e0016a200541b8036a10f20141012110024020052802e001417d710d00200642003703002007420037030020084200370300200542003703f802200910012210290000210b200c201041086a2900003703002005200b3703a802201010352008200c290300370300200520052903a8023703f802419beecb00ad4280808080b002841001220c290000210b200d200c41086a2900003703002005200b3703b802200c1035200720052903b802370000200741086a200d290300370000200a2008290300370300200e2007290300370300200f2006290300370300200520052903f8023703b803200541203602bc022005200541b8036a3602b802200541e8016a200541b8036aad42808080808004842209100510c201410021100240024020052802e80122080d00410021110c010b20052802ec01210a02400240200541f0016a2802004104490d00410121112008280000220f418194ebdc03490d010b4100211120054100360290022005420137038802200541093602e4032005200541b8026a3602e003200520054188026a3602a8022005418c036a4101360200200542013702fc02200541c888c2003602f8022005200541e0036a36028803200541a8026a41e88ac500200541f8026a10431a200535029002422086200535028802841006200528028c02450d0020052802880210350b200a450d00200810350b200541f8026a41186a220d4200370300200541f8026a41106a220c4200370300200541f8026a41086a22084200370300200542003703f80241f7edcb00ad4280808080f000841001220a290000210b200541a8026a41086a2206200a41086a2900003703002005200b3703a802200a103520082006290300370300200520052903a8023703f80241eeedcb00ad42808080809001841001220a290000210b200541b8026a41086a2206200a41086a2900003703002005200b3703b802200a1035200720052903b802370000200741086a2006290300370000200541b8036a41086a2008290300370300200541b8036a41106a200c290300370300200541b8036a41186a200d290300370300200520052903f8023703b803200541f8026a200541b8036a10ac0120052903f8024202510d00200541f8026a200c280200221210b801200541d8016a20052802f802220a20052802800310c00120052802dc01210c20052802d8012108024020052802fc02450d00200a10350b02400240024020080d0041fdb5c000ad4280808080e0068410064100201241e07a6a2208200820124b1b2113201221140c010b4100201241e07a6a2208200820124b1b21130240200c20044b0d00201221140c010b200541f8026a41186a220c4200370300200541f8026a41106a220d4200370300200541f8026a41086a22084200370300200542003703f80241f7edcb00ad4280808080f000841001220a290000210b200541a8026a41086a2206200a41086a2900003703002005200b3703a802200a103520082006290300370300200520052903a8023703f80241aeeecb00ad4280808080a001841001220a290000210b200541b8026a41086a2206200a41086a2900003703002005200b3703b802200a1035200720052903b802370000200741086a2006290300370000200541b8036a41086a2008290300370300200541b8036a41106a200d290300370300200541b8036a41186a200c290300370300200520052903f8023703b803200541f8026a200541b8036a10d90120052802f8022208410420081b220d20052902fc02420020081b220b422088a741037422086a210a03402008450d02200841786a2108200a417c6a210c200a41786a210a200c28020020044b0d000b200d20086a2802002114200b42ffffffff0183500d00200d10350b200541f8026a41186a22154200370300200541f8026a41106a22164200370300200541f8026a41086a22174200370300200542003703f80241f7edcb00ad4280808080f00084221810012208290000210b200541a8026a41086a2219200841086a2900003703002005200b3703a8022008103520172019290300370300200520052903a8023703f80241b8eecb00ad4280808080e00284220b10012208290000211a200541b8026a41086a221b200841086a2900003703002005201a3703b80220081035200720052903b802370000200741086a221c201b290300370000200541b8036a41086a220e2017290300370300200541b8036a41106a221d2016290300370300200541b8036a41186a221e2015290300370300200520052903f8023703b803200541d0016a200541b8036a412010c00120052802d401210a20052802d001210c201542003703002016420037030020174200370300200542003703f802201810012208290000211a2019200841086a2900003703002005201a3703a8022008103520172019290300370300200520052903a8023703f802200b10012208290000210b201b200841086a2900003703002005200b3703b80220081035200720052903b802370000201c201b290300370000200e2017290300370300201d2016290300370300201e2015290300370300200520052903f8023703b8032005200a2012200c4101461b3602f8022009200541f8026aad220b4280808080c00084100220032001200120034b1b221f450d01200f410020111b2120200541a8036aad4280808080c000842121200b42808080808002842122200541a8036a41046a2123200541e0036a41086a2111200021034100212402400240024002400340201542003703002016420037030020174200370300200542003703f802201810012208290000210b2019200841086a2900003703002005200b3703a8022008103520172019290300370300200520052903a8023703f8024194c4c100ad4280808080d0018410012208290000210b201b200841086a2900003703002005200b3703b80220081035200720052903b802370000201c201b290300370000200e2017290300370300201d2016290300370300201e2015290300370300200520052903f8023703b803200541f8026a200541b8036a10fe0120052902fc02420020052802f80222081b220b422088a7410574210a2024220c41016a21242002200c4102746a21042000200c41e0006c6a210f2008410120081b22102108024003400240200a0d004100210d0c020b4101210d20032008460d012008200f412010a008210c200a41606a210a200841206a2108200c0d000b0b0240200b42ffffff3f83500d00201010350b0240200d0d0020042802002108200542003703b002200542003703a802200541c0016a200f290320220b200f41286a290300428094ebdc034200109808200541a0016a200f2903302209200f41386a290300428094ebdc034200109808200541b0016a20052903c001221a200541c0016a41086a29030022254280ec94a37c427f108408200541f0006a201a20252008ad2226420010840820054190016a20052903a001221a200541a0016a41086a29030022254280ec94a37c427f10840820054180016a201a202520264200108408200542003703c002200542003703b802202620092005290390017c7e221a428094ebdc0380212502400240200529037042002026200b20052903b0017c7e220b428094ebdc03802209a7417f200b428080808080c0b2cd3b541b200b20094280ec94a37c7e7c4280cab5ee01566a220aad7d85200541f0006a41086a2903004200200a410047ad7d8584500d00200529038001210920054180016a41086a2903002127200541e8016a2014200f10b20120052802e801210a200520052802f001220c3602f4032005200a3602f00320054188026a200cad422086200aad84100510c20102400240200528028802220c0d004200210b0c010b200528028c0221100240024020052802900222044104490d00200c280000220d418094ebdc034b0d004201210b2004417c6a410f4b0d010b200541003602c003200542013703b803200541093602e4032005200541f0036a3602e0032005200541b8036a3602a8032005410136028c03200542013702fc02200541c888c2003602f8022005200541e0036a36028803200541a8036a41e88ac500200541f8026a10431a20053502c00342208620053502b803841006024020052802bc03450d0020052802b80310350b4200210b2028210d0b02402010450d00200c10350b200d21280b024020052802ec01450d00200a10350b200820284100200b4200521b22064d0d02200541f8026a2014200f10b201200535028003212920052802f802210c41101033220a0d010c070b200542003703f001200542003703e80120054200370390022005420037038802200541f0036a200f10ba01200541b8036a20052802f003220a20052802f80310bc012011200e280200360200200520052903b8033703e003024020052802c4032208450d00200541a8036a41086a2011280200360200200520052903e0033703a80320052903c803210b0b024020052802f403450d00200a10350b0240024020080d00200542003703c80320054280808080c0003703c003200520133602bc03200541003602b803200541f0036a200f10ba0120052802f0032108200520052802f8033602e403200520083602e003200541b8036a200541e0036a10ff01024020052802f403450d00200810350b2011200e280200360200200520052903b8033703e00320052903c803210b410421080c010b2011200541a8036a41086a280200360200200520052903a8033703e0030b201720052903e003370200201741086a2011280200360200200541003a00a4032005200f3602fc02200520133602f802200520203602a0032005200b370390032005200836028c03200520054188026a36029c032005200541e8016a36029803200541b8036a200541f8026a2014108002024020052802c0034102460d0020052802b803200528028003470d002017201210810221082005410120052d00a40320081b22083a00a403200541b8036a200f10b50120053502c00342208620052802b803220aad841007024020052802bc03450d00200a10350b200541b8036a200f10b90120053502c00342208620052802b803220aad841007024020052802bc03450d00200a10350b0240200f10820241ff0171220a4102460d00200a410171450d0010e4010b200841ff0171450d00200528029403220f41027421084101210d200528028c03210a200528028003210120052802f80221042005280284032206210c02400340024020080d00200520062004200620044b1b360284030c020b200d417f6a210d2008417c6a2108200c20044b2110200c200a2802006b210c200a41046a210a20100d000b200f21080240200f2010200d6b220a490d002005200a36029403200a21080b200520062004200620044b1b3602840341000d002001200f6b220a200120086b4f0d00200f20086b210c20052802fc0221080340201e200841186a290000370300201d200841106a290000370300200e200841086a290000370300200520082900003703b8032005200a3602d803200541f0036a200541b8036a10b60120053502f80342208620052802f003220dad841007024020052802f403450d00200d10350b200a41016a210a200c417f6a220c0d000b0b200541b8036a20052802fc0210ba0120052802b8032108200520052802c0033602f403200520083602f0032017200541f0036a10ff0120052802bc03450d00200810350b20052802900341ffffffff0371450d01200528028c0310350c010b200a2008360000200a4110412010372208450d04200820092025a7417f201a428080808080c0b2cd3b541b201a20254280ec94a37c7e7c4280cab5ee01566aad7c220b3700042008410c6a2027200b200954ad7c221a3700002029422086200cad842008ad4280808080c00284100220081035024020052802fc02450d00200c10350b20054188026a200f10ba01200541b8036a200528028802220a20052802900210bc012011200e280200360200200520052903b8033703e003024020052802c4032208450d00200541e8016a41086a2011280200360200200520052903e0033703e80120052903c80321090b0240200528028c02450d00200a10350b0240024020080d00200542003703c80320054280808080c0003703c003200520133602bc03200541003602b80320054188026a200f10ba01200528028802210820052005280290023602f403200520083602f003200541b8036a200541f0036a10ff010240200528028c02450d00200810350b200541f0036a41086a200e280200360200200520052903b8033703f00320052903c8032109410421080c010b200541f0036a41086a200541e8016a41086a280200360200200520052903e8013703f0030b201720052903f003370200201741086a222a200541f0036a41086a280200360200200541003a00a4032005200f3602fc02200520133602f802200520203602a00320052009370390032005200836028c032005200541b8026a36029c032005200541a8026a36029803200541e8006a200541f8026a2014200b201a10830202400240024020052802684101470d00200528026c200528028003460d010b20052d00a40321080c010b2017201210810221082005410120052d00a40320081b22083a00a403200541b8036a200f10b50120053502c00342208620052802b803220aad841007024020052802bc03450d00200a10350b200541b8036a200f10b90120053502c00342208620052802b803220aad841007024020052802bc03450d00200a10350b200f10820241ff0171220a4102460d00200a410171450d0010e4010b0240200841ff0171450d00200528029403222b41027421084101210d200528028c03210a200528028003212c20052802f80221042005280284032201210c02400340024020080d00200520012004200120044b1b360284030c020b200d417f6a210d2008417c6a2108200c20044b2110200c200a2802006b210c200a41046a210a20100d000b202b21080240202b2010200d6b220a490d002005200a36029403200a21080b200520012004200120044b1b3602840341000d00202c202b6b220a202c20086b4f0d00202b20086b210c20052802fc0221080340201e200841186a290000370300201d200841106a290000370300200e200841086a290000370300200520082900003703b8032005200a3602d80320054188026a200541b8036a10b601200535029002422086200528028802220dad8410070240200528028c02450d00200d10350b200a41016a210a200c417f6a220c0d000b0b200541b8036a20052802fc0210ba0120052802b8032108200520052802c00336028c022005200836028802201720054188026a10ff0120052802bc03450d00200810350b024020052802900341ffffffff0371450d00200528028c0310350b200541003602d002200542083703c802200542003703f001200542003703e801200541c8026a4100200f41c8006a220828020010880102400240200828020022080d004200210920052802c802210d4200211a0c010b200f2802402201200841306c6a212d2006ad2127034020054200370390022005420037038802200541c0006a2001290300221a200141086a290300428094ebdc034200109808200541306a2005290340220b200541c0006a41086a29030022094280ec94a37c427f108408200541206a200b200920274200108408200541106a200b200920264200108408200541f8026a2014200141106a220610b301200541d0006a20052802f802220a20052802800310d7014200200541106a41086a290300200529031022092026201a20052903307c221a7e220b428094ebdc03802225a7417f200b428080808080c0b2cd3b541b200b20254280ec94a37c7e7c4280cab5ee01566aad7c220b200954ad7c2209200541206a41086a290300200529032022252027201a7e221a428094ebdc03802229a7417f201a428080808080c0b2cd3b541b201a20294280ec94a37c7e7c4280cab5ee01566aad7c221a202554ad7c7d200b201a54ad7d2225200b201a7d221a200b56202520095620252009511b22081b21094200201a20081b210b200541d0006a41106a290300211a2005290358212520052802502108024020052802fc02450d00200a10350b200541b8036a2014200610b30120052802b803210a20053502c003212920052025420020081b2225200b7c220b3703f8022005201a420020081b20097c200b202554ad7c2209370380032029422086200aad8420221002024020052802bc03450d00200a10350b200541f0036a200610ba01200541b8036a20052802f003220a20052802f80310bc012011200e280200360200200520052903b8033703e003024020052802c4032208450d00200541a8036a41086a2011280200360200200520052903e0033703a80320052903c803212e0b024020052802f403450d00200a10350b0240024020080d00200542003703c80320054280808080c0003703c003200520133602bc03200541003602b803200541f0036a200610ba0120052802f0032108200520052802f8033602e403200520083602e003200541b8036a200541e0036a10ff01024020052802f403450d00200810350b2011200e280200360200200520052903b8033703e00320052903c803211a410421080c010b2011200541a8036a41086a280200360200200520052903a8033703e003202e211a0b201720052903e003370200202a2011280200360200200541003a00a403200520063602fc02200520133602f802200520203602a0032005201a370390032005200836028c03200520054188026a36029c032005200541e8016a36029803200541086a200541f8026a2014200b20091083020240024020052802084101470d00200528020c200528028003470d002017201210810221082005410120052d00a40320081b22083a00a4030c010b20052d00a40321080b0240200841ff0171450d00200528029403222c41027421084101210d200528028c03210a200528028003212f20052802f8022104200528028403222b210c02400340024020080d002005202b2004202b20044b1b360284030c020b200d417f6a210d2008417c6a2108200c20044b2110200c200a2802006b210c200a41046a210a20100d000b202c21080240202c2010200d6b220a490d002005200a36029403200a21080b2005202b2004202b20044b1b3602840341000d00202f202c6b220a202f20086b4f0d00202c20086b210c20052802fc0221080340201e200841186a290000370300201d200841106a290000370300200e200841086a290000370300200520082900003703b8032005200a3602d803200541f0036a200541b8036a10b60120053502f80342208620052802f003220dad841007024020052802f403450d00200d10350b200a41016a210a200c417f6a220c0d000b0b200541b8036a20052802fc0210ba0120052802b8032108200520052802c0033602f403200520083602f0032017200541f0036a10ff0120052802bc03450d00200810350b024020052802900341ffffffff0371450d00200528028c0310350b200141306a2101200641086a290000210b200629000021092015200641186a2900003703002016200641106a2900003703002017200b370300200520093703f80220054188026a41086a290300210b2005290388022109024020052802d002220a20052802cc02470d00200541c8026a200a410110880120052802d002210a0b20052802c802220d200a41306c6a22082009370320200820052903f802370300200841286a200b370300200841086a2017290300370300200841106a2016290300370300200841186a20152903003703002005200a41016a3602d0022001202d470d000b200541e8016a41086a290300211a20052903e80121090b2019290300212520052903a802210b200541e8016a41086a2208200f41086a290300370300200541e8016a41106a220a200f41106a290300370300200541e8016a41186a220c200f41186a2903003703002005200f2903003703e801200d450d00201b290300212620052903b802212720052902cc02212920054188026a41186a2204200c29030037030020054188026a41106a2201200a29030037030020054188026a41086a222b2008290300370300200520052903e80137038802200f280258221041ffffff3f712010470d022010410574220c417f4c0d02200f280250210802400240200c0d004101210a0c010b200c1033220a450d060b20054100360280032005200a3602f8022005200c4105763602fc02200541f8026a41002010108a0120052802800321060240024020100d0020052802f802212c0c010b20052802f802222c20064105746a210a0340200a2008290000370000200a41186a200841186a290000370000200a41106a200841106a290000370000200a41086a200841086a290000370000200a41206a210a200841206a2108200c41606a220c0d000b201041057441606a41057620066a41016a21060b20052802fc02212f201e2004290300370300201d2001290300370300200e202b29030037030020052005290388023703b803201810012208290000212e2019200841086a2900003703002005202e3703a8022008103541efb6c000ad428080808080028410012208290000212e201b200841086a2900003703002005202e3703b80220081035200520123602a80320052021100322082900003703e003200810352005202336028403200520113602fc022005200541a8036a360280032005200541e0036a3602f802200541f0036a200541f8026a107b20052802f803220441206a220a417f4c0d0220052802f003210f02400240200a0d0041002108410121100c010b200a10332210450d06200a21080b024002402008410f4d0d002008210c0c010b2008410174220c4110200c41104b1b220c4100480d04024020080d00200c103322100d010c060b2008200c460d0020102008200c10372210450d050b201020052903a802370000201041086a201929030037000002400240200c4170714110460d00200c21080c010b200c41017422084120200841204b1b22084100480d04200c2008460d002010200c200810372210450d050b201020052903b802370010201041186a201b29030037000002400240200841606a2004490d00200821010c010b2004415f4b0d042008410174220c200a200c200a4b1b22014100480d0420082001460d0020102008200110372210450d050b200b20097c2209200b542108201041206a200f2004109d081a024020052802f403450d00200f10350b2025201a7c210b2008ad211a200541f8026a2010200a10dd010240024020052802f80222040d004100210f200541003602c002200542083703b802410821044100210c0c010b200520052902fc0222253702bc02200520043602b8022025422088a7210c2025a7210f0b200b201a7c210b2015201e2903003703002016201d2903003703002017200e290300370300200520052903b8033703f8020240200c200f470d00200541b8026a200c4101109b0120052802bc02210f20052802b802210420052802c002210c0b2004200c41d8006c222b6a2208200937031020082026370308200820273703002008202c36022c2008200d360220200841186a200b370300200841346a2006360200200841306a202f360200200841246a2029370200200820052903f802370338200841c0006a2017290300370300200841c8006a2016290300370300200841d0006a20152903003703002005200c41016a22083602c0020240024020040d00200aad4220862010ad8410070c010b200541f8026a2004200810ea01200aad4220862010ad8420053502800342208620052802f802220aad841002024020052802fc02450d00200a10350b02402008450d00200441306a2108202b41d8006a210a03400240200841746a280200220c450d00200c41306c450d00200841706a28020010350b0240200828020041ffffff3f71450d002008417c6a28020010350b200841d8006a2108200a41a87f6a220a0d000b0b200f450d00200f41d8006c450d00200410350b2001450d00201010350b200341e0006a21032024201f490d000b410021100c050b1044000b103e000b103c000b1045000b41002110200b42ffffffff0183500d00200d10350b20054180046a240020100bbf0201027f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a10c3010240024020022802480d0020024100360230200242013703282002410936023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b200041003602000c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2003450d00200110350b200241e0006a24000b8f0301067f230041106b220224002002410036020820024201370300200028020021030240410410332204450d002004200336000020024284808080c000370204200220043602002000280204210320044104410810372204450d0020042003360004200242888080808001370204200220043602002000280208210320044108411010372204450d002004200336000820024290808080c00137020420022004360200200028020c2105200041146a28020022002002107702400240024020022802042206200228020822046b20004102742203490d0020022802002100200621070c010b200420036a22002004490d01200641017422072000200720004b1b22074100480d010240024020060d00024020070d00410121000c020b2007103322000d010c040b2002280200210020062007460d0020002006200710372200450d030b20022007360204200220003602000b200020046a20052003109d081a2001290200200420036aad4220862000ad84100202402007450d00200010350b200241106a24000f0b103e000b103c000bbd0101057f2001280208210302402001410c6a280200220420024b0d002000410036020820002004ad4220862003ad843702000f0b024002402001411c6a2802002205450d00200141146a2802002101200541027421062003417f6a2103034002402004200128020022076b220520024b0d00200420024b0d030b200141046a21012003417f6a2103200521042006417c6a22060d000b0b200041023602080f0b2000200736020c2000410136020820002005ad4220862003ad843702000ba00201067f410021020240200141016a2203200028020422044d0d000240200041146a22052802002201200041106a280200470d000240024002400240200141016a22022001490d00200141017422062002200620024b1b220241ffffffff03712002470d00200241027422024100480d00024020010d0020020d02410421060c040b200028020c2106200141027422072002460d03024020070d0020020d02410421060c040b20062007200210372206450d020c030b103e000b2002103322060d010b103c000b2000200636020c200041106a20024102763602000b200028020c220241046a20022001410274109e081a2002200320046b36020020002003360204410121022005200141016a3602002000200028020041016a3602000b20020bd20f07047f017e047f017e047f017e017f23004190016b22012400200141386a41186a4200370300200141386a41106a22024200370300200141386a41086a220342003703002001420037033841a3edcb00ad4280808080f000841001220429000021052003200441086a290000370300200120053703382004103541f393ca00ad4280808080a00184100122042900002105200141286a41086a2206200441086a2900003703002001200537032820041035200220012903282205370300200141e8006a41086a2003290300370300200141e8006a41106a2005370300200141e8006a41186a200629030037030020012001290338370368200141386a200141e8006a10fe0120012802382203410120031b21074102210802400240200129023c420020031b2205422088a72203450d002003410574210241002104200721030240034020002003460d01200420032000412010a00822064100476a21042006450d01200341206a2103200241606a22020d000c020b0b200141386a41186a4200370300200141386a41106a22094200370300200141386a41086a220042003703002001420037033841a3edcb00ad4280808080f0008410012202290000210a200141286a41086a2203200241086a2900003703002001200a37032820021035200020032903003703002001200129032837033841beebcb00ad4280808080a0028410012202290000210a2003200241086a2900003703002001200a3703282002103520092001290328220a370300200141e8006a41086a2000290300370300200141e8006a41106a200a370300200141e8006a41186a200329030037030020012001290338370368200141186a200141e8006a10c5020240024002402001280218220b0d004100210c20014100360210200142043703084104210b4100210d410021030c010b200129021c210a2001200b3602082001200a37020c200aa7210d4100210302400240200a422088a7220c41014b0d00200c0e020201020b200c2100034020032000410176220220036a22062004200b20064102746a280200491b2103200020026b220041014b0d000b0b4100210802402004200b20034102746a2802002200470d00410021060c020b2003200420004b6a21030b200141386a41186a22084200370300200141386a41106a220e4200370300200141386a41086a220242003703002001420037033841a3edcb00ad4280808080f0008410012206290000210a200141286a41086a2200200641086a2900003703002001200a37032820061035200220002903003703002001200129032837033841f393ca00ad4280808080a0018410012206290000210a2000200641086a2900003703002001200a3703282006103520092001290328370000200941086a2000290300370000200141e8006a41086a2002290300370300200141e8006a41106a200e290300370300200141e8006a41186a200829030037030020012001290338370368200141286a200141e8006aad4280808080800484100510c201024002400240024020012802282202450d00200128022c21062001200028020036023c200120023602382001200141386a10c4012001280200450d01410021000c020b2001420037023c20014101360238200141386a108a0321000c020b200128020421000b2006450d00200210350b20002000418094ebdc036e22024180ec94a37c6c6aad4280fd87d1007e220f428094ebdc0380210a200c2003490d0220024180fd87d1006c200f200a4280ec94a37c7e7c4280cab5ee015672200aa76a21020240200c200d470d00200141086a200d4101108601200128020c210d2001280208210b0b200b20034102746a220041046a2000200c20036b410274109e081a20002004360200410121062001200c41016a220c360210200c20024b21080b200141386a41186a220e4200370300200141386a41106a22104200370300200141386a41086a220042003703002001420037033841a3edcb00ad4280808080f0008410012202290000210a200141286a41086a2203200241086a2900003703002001200a37032820021035200020032903003703002001200129032837033841beebcb00ad4280808080a0028410012202290000210a2003200241086a2900003703002001200a3703282002103520092001290328370000200941086a2003290300370000200141e8006a41086a2000290300370300200141e8006a41106a2010290300370300200141e8006a41186a200e2903003703002001200129033837036802400240200b0d00200141e8006aad428080808080048410070c010b2001412036023c2001200141e8006a360238200b200c200141386a109503200d41ffffffff0371450d00200b10350b2006450d00200141e8006a41086a22032004ad37030020014102360268200141386a200141e8006a108805200141336a2200200141386a41086a2802003600002001200129033837002b200141386a410c6a2001412f6a2202290000370000200141c6a4b9da04360039200141023a00382001200129002837003d200141386a108204200141013602382001200436023c200141e8006a200141386a108104200020032802003600002001200129036837002b200141e8006a410c6a2002290000370000200141c28289aa04360069200141023a00682001200129002837006d200141e8006a1082040b0240200542ffffff3f83500d00200710350b20014190016a240020080f0b2003200c104d000b9a0d04047f017e027f067e230041d0026b22052400200541c8016a2001200210800202400240024002400240024020052802d0014102460d0020052802c8012106200541c8016a41086a2001280204220741086a290000370300200541c8016a41106a200741106a290000370300200541c8016a41186a200741186a290000370300200520063602e801200520072900003703c801200541f0016a200541c8016a10b60120052802f0012108200520052802f801220736028402200520083602800220054188026a2007ad4220862008ad84100510c2010240024020052802880222070d00420021090c010b200528028c02210a02400240024020054188026a41086a280200220b4110490d00200b4170714110470d010b200541003602a0022005420137039802200541093602ac02200520054180026a3602a802200520054198026a3602b402200541cc026a4101360200200542013702bc02200541c888c2003602b8022005200541a8026a3602c802200541b4026a41e88ac500200541b8026a10431a20053502a0024220862005350298028410060240200528029c02450d0020052802980210350b420021090c010b200741186a290000210c200741086a290000210d2007290010210e2007290000210f420121090b200a450d00200710350b200d4200200942005222071b210d200f420020071b210f024020052802f401450d00200810350b200c420020071b210c200e420020071b210e200f200354200d200454200d2004511b0d01200f200385200d2004858450450d03200541b8016a20032004428094ebdc034200109808200541a8016a20052903b801220d200541b8016a41086a290300220f4280ec94a37c427f10840820054198016a200d200f20013502282209420010840820054188016a4200200529039801220f200920052903a80120037c7e220d428094ebdc03802209a7417f200d428080808080c0b2cd3b541b200d20094280ec94a37c7e7c4280cab5ee01566aad7c220d200e7d22092009200d5620054198016a41086a290300200d200f54ad7c220f200c7d200d200e54ad7d220d200f56200d200f511b22021b220f4200200d20021b428094ebdc034200109808200541f8006a200529038801220d20054188016a41086a29030022094280ec94a37c427f108408200541e8006a200d20094280cab5ee014200108408200541e8006a41086a29030020052903682209200f20052903787c220d420188220fa7417f200d4280cab5ee017e220d428080808080c0b2cd3b541b200d200f4280ec94a37c7e7c4280cab5ee01566aad7c220d200954ad7c210f410021020c020b410021010c040b200541c8006a20032004428094ebdc034200109808200541d8006a20032004428094ebdc034200108608200541386a2005290348200541c8006a41086a290300200135022822094200108408200541286a420020052903382210200920052903587e2209428094ebdc03802211a7417f2009428080808080c0b2cd3b541b200920114280ec94a37c7e7c4280cab5ee01566aad7c2209200e7d22112011200956200541386a41086a2903002009201054ad7c2210200c7d2009200e54ad7d220920105620092010511b22071b22104200200920071b428094ebdc034200109808200541186a20052903282209200541286a41086a29030022114280ec94a37c427f108408200541086a200920114280cab5ee014200108408200128022422072003200f7d220920072903007c2211370300200741086a22072004200d7d2003200f54ad7d20072903007c2011200954ad7c370300200141106a2207200728020022072002200720024b1b360200200541086a41086a2903002005290308220f201020052903187c220d4201882209a7417f200d4280cab5ee017e220d428080808080c0b2cd3b541b200d20094280ec94a37c7e7c4280cab5ee01566aad7c220d200f54ad7c210f410121020b02400240200d200f84500d002001280220220220022903002209200d7c2210370300200241086a22022002290300200f7c2010200954ad7c370300200c200f7c200e200d7c220d200e54ad7c210c200d210e0c010b2002450d010b200141013a002c200541b8026a200541c8016a10b60120053502c002210d20052802b8022102411010332201450d01200120033700002001200437000820014110412010372201450d012001200e370010200141186a200c370000200d4220862002ad842001ad428080808080048410022001103520052802bc02450d00200210350b410121010c010b103c000b2000200636020420002001360200200541d0026a24000be70403057f017e037f23004180016b22022400200241206a41186a22034200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032041f7edcb00ad4280808080f000841001220629000021072005200641086a290000370300200220073703202006103541eeedcb00ad4280808080900184100122062900002107200241086a2208200641086a2900003703002002200737030020061035200420022903002207370300200241e0006a41086a22062005290300370300200241e0006a41106a22092007370300200241e0006a41186a220a200829030037030020022002290320370360200241206a200241e0006a10ac010240024020022903204202520d00200041003602200c010b200241d0006a2004280200200110ce01200241206a200228025022082002280258108502200a2003290300370300200920042903003703002006200529030037030020022002290320370360200241cc006a280200210402400240200228024022050d0042002107200241186a4200370300200241106a420037030041082105200241086a4200370300200242003703000c010b200241086a200241e0006a41086a290300370300200241106a200241e0006a41106a290300370300200241186a200241e0006a41186a29030037030020022002290360370300200229024421070b02402002280254450d00200810350b2000200229030037030020002007370224200020053602202000412c6a2004360200200041186a200241186a290300370300200041106a200241106a290300370300200041086a200241086a2903003703000b20024180016a24000b860301017f230041f0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822010d00200041003602200c010b200328020c21022003200341086a41086a28020036024c20032001360248200341186a200341c8006a10c5010240024020032802380d00200341003602582003420137035020034109360264200320033602602003200341d0006a36026c2003412c6a41013602002003420137021c200341c888c2003602182003200341e0006a360228200341ec006a41e88ac500200341186a10431a2003350258422086200335025084100602402003280254450d00200328025010350b200041003602200c010b20002003290318370300200041286a200341186a41286a290300370300200041206a200341186a41206a290300370300200041186a200341186a41186a290300370300200041106a200341186a41106a290300370300200041086a200341186a41086a2903003703000b2002450d00200110350b200341f0006a24000bc00908057f047e027f027e067f017e037f017e230041e0016b22032400200241386a2802002104200241346a2802002105200241306a2802002106200341c0006a41186a200241186a290000370300200341c0006a41106a200241106a290000370300200341c0006a41086a200241086a290000370300200320022900003703404100210720034100360268200342083703600240024020040d0042002108420021094200210a4200210b0c010b200441306c210c200341b0016a41106a21044108210d42002108420021094200210a4200210b200621020340200241286a290300210e200241206a290300210f200341f0006a41186a2210200241186a290300370300200341f0006a41106a2211200241106a290300370300200341f0006a41086a2212200241086a29030037030020032002290300370370200341b0016a41186a2213420037030020044200370300200341b0016a41086a22144200370300200342003703b00141b6fdc600ad42808080808001841001221529000021162014201541086a290000370300200320163703b0012015103541e489c200ad4280808080d00184100122152900002116200341d0016a41086a2217201541086a290000370300200320163703d00120151035200420032903d001370000200441086a201729030037000020034190016a41086a2215201429030037030020034190016a41106a2217200429030037030020034190016a41186a22182013290300370300200320032903b00137039001200341286a20034190016a412010d701200341186a2003290330200341286a41106a290300427f4200109808200341086a20032903184200200328022822191b221642012016420156200341186a41086a290300420020191b22164200522016501b22191b2016420020191b200f200e1084082018201029030037030020172011290300370300201520122903003703002003200329037037039001200341086a41086a29030021162003290308210e0240024020034190016a200341c0006a412010a008450d0020132018290300370300200420172903003703002014201529030037030020032003290390013703b001024020072003280264470d00200341e0006a200741011088012003280260210d200328026821070b200d200741306c6a221520163703082015200e370300201520032903b001370310201541186a2014290300370300201541206a2004290300370300201541286a20132903003703002003200741016a22073602680c010b427f200920167c2008200e7c221a2008542214ad7c220f2014200f200954200f2009511b22141b2109427f201a20141b21080b200241306a2102427f200b20167c200a200e7c2216200a542214ad7c220a2014200a200b54200a200b511b22141b210b427f201620141b210a200c41506a220c0d000b0b02402005450d00200541306c450d00200610350b2000200a37032020002003290340370000200041386a2009370300200041306a2008370300200041286a200b370300200041c0006a2003290360370200200041186a200341c0006a41186a290300370000200041106a200341c0006a41106a290300370000200041086a200341c0006a41086a290300370000200041c8006a200341e0006a41086a280200360200200341e0016a24000ba21904047f017e047f037e230041d0016b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220341174b0d0020030e180102030405060708090a0b0c0d0e0f101112131415161718010b41cfa2cc00412841c086cc00103f000b4101210302400240200141046a2d00004101470d00200141086a28020021040c010b200241c2016a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b01c00120022001410c6a290000370300200141086a2800002104410021030b200041286a2001290328370300200041046a20033a0000200041056a20022f01c0013b0000200041086a20043602002000410c6a2002290300370200200041306a200141306a290300370300200041076a200241c2016a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a28020036020020012d00012101200041013a0000200020013a00010c170b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c160b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c150b200041043a00000c140b200041053a0000200041046a200141046a2802003602000c130b2001410c6a2802002205ad42247e2206422088a70d132006a72204417f4c0d13200141046a28020021030240024020040d00410421010c010b200410332201450d150b200241003602c801200220013602c0012002200441246e3602c401200241c0016a41002005108d0120022802c801210402402005450d00200541246c210520022802c001200441246c6a2101200241ce016a210703400240024020032d00004101470d00200341046a2802002108410121090c010b2007200341036a2d00003a0000200341046a2800002108200341016a2f00002109200241086a200341106a290000370300200241106a200341186a290000370300200241186a200341206a2d00003a0000200220093b01cc012002200341086a290000370300410021090b200341246a2103200120093a0000200141046a2008360200200141016a20022f01cc013b0000200141036a20072d00003a0000200141086a2002290300370200200141106a200241086a290300370200200141186a200241106a290300370200200141206a200241186a280200360200200141246a2101200441016a21042005415c6a22050d000b0b200241086a2004360200200220022903c00122063703002000410c6a2004360200200041046a2006370200200041063a00000c120b200041073a00000c110b200041083a0000200020012d00013a00010c100b4101210302400240200141046a2d00004101470d00200141086a28020021010c010b200241c2016a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b01c00120022001410c6a290000370300200141086a2800002101410021030b200041093a0000200041046a20033a0000200041056a20022f01c0013b0000200041086a20013602002000410c6a2002290300370200200041076a200241c2016a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c0f0b2000410a3a0000200041046a200141046a2802003602000c0e0b2000410b3a00000c0d0b2000410c3a00000c0c0b2001410c6a280200220741ffffff3f712007470d0c20074105742203417f4c0d0c200141046a28020021050240024020030d00410121040c010b200310332204450d0e0b41002101200241003602082002200436020020022003410576360204200241002007108a012002280208210a02402007450d00200741057421082002280200200a4105746a21090340200920016a2203200520016a2204290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002008200141206a2201470d000b200741057441606a410576200a6a41016a210a0b200241c8016a200a3602002002200229030022063703c0012000410c6a200a360200200041046a20063702002000410d3a00000c0b0b2000410e3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0a0b2000410f3a00000c090b200141106a280200220341ffffffff03712003470d0920034102742204417f4c0d09200141046a2802002105200141086a28020021084104210102402004450d00200410332201450d0b0b2002410036020820022001360200200220044102763602042002410020031086012002280200200228020822014102746a20082003410274109d081a200241c0016a41086a200120036a22013602002002200229030022063703c001200041046a2005360200200041086a2006370200200041106a2001360200200041103a00000c080b200141106a2802002203ad42247e2206422088a70d082006a72204417f4c0d08200141046a2802002108200141086a28020021010240024020040d00410421050c010b200410332205450d0a0b20024100360208200220053602002002200441246e360204200241002003108d012002280208210402402003450d00200341246c21052002280200200441246c6a21030340200141086a2902002106200141106a290200210b200141186a290200210c2001290200210d200341206a200141206a280200360200200341186a200c370200200341106a200b370200200341086a20063702002003200d370200200341246a2103200441016a2104200141246a21012005415c6a22050d000b0b200241c0016a41086a20043602002002200229030022063703c001200041046a2008360200200041086a2006370200200041106a2004360200200041113a00000c070b200041123a0000200041046a200141046a2802003602000c060b200041133a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c050b200041143a0000200041106a200141106a290300370300200041086a200141086a2903003703000c040b200041153a0000200041046a200141046a2802003602000c030b200041163a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c020b2001410c6a280200220320036a22042003490d022004417f4c0d02200141046a28020021050240024020040d00410221080c010b200410332208450d040b200241003602082002200836020020022004410176360204200241002003108e012002280200200228020822044101746a20052003410174109d081a200241c0016a41086a2205200420036a360200200220022903003703c0012002200141106a108802200041046a20022903c0013702002000410c6a200528020036020020012802d0012103200041106a200241c001109d081a200041d0016a2003360200200041173a000020004180026a200141d8016a220141286a290300370300200041f8016a200141206a290300370300200041f0016a200141186a290300370300200041e8016a200141106a290300370300200041e0016a200141086a290300370300200041d8016a20012903003703000c010b2001410c6a280200220320036a22042003490d012004417f4c0d01200141046a28020021050240024020040d00410221080c010b200410332208450d030b200241003602082002200836020020022004410176360204200241002003108e012002280200200228020822044101746a20052003410174109d081a200241c0016a41086a2205200420036a360200200220022903003703c0012002200141106a108802200041046a20022903c0013702002000410c6a200528020036020020012802d0012103200041106a200241c001109d081a200041d0016a2003360200200041183a000020004180026a200141d8016a220141286a290300370300200041f8016a200141206a290300370300200041f0016a200141186a290300370300200041e8016a200141106a290300370300200041e0016a200141086a290300370300200041d8016a20012903003703000b200241d0016a24000f0b1044000b1045000bc11702057f017e23004180026b22022400024002402001280208220341ffffffff01712003470d0020034103742204417f4c0d00200128020021050240024020040d00410421060c010b200410332206450d020b200241003602f801200220063602f001200220044103763602f401200241f0016a4100200310900120022802f00120022802f80122044103746a20052003410374109d081a200041086a200420036a360200200020022903f001370200200141146a2802002204ad420c7e2207422088a70d002007a72203417f4c0d00200128020c21064104210502402003450d00200310332205450d020b200241003602f801200220053602f00120022003410c6e3602f401200241f0016a4100200410870120022802f00120022802f8012205410c6c6a20062003109d081a200241086a200520046a360200200220022903f001370300200141206a280200220341ffffffff00712003470d0020034104742204417f4c0d00200128021821064104210502402004450d00200410332205450d020b200241003602f801200220053602f001200220044104763602f401200241f0016a41002003108c0120022802f00120022802f80122044104746a20062003410474109d081a200241186a200420036a360200200220022903f0013703102001412c6a2802002204ad42147e2207422088a70d002007a72203417f4c0d00200128022421050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341146e3602f401200241f0016a4100200410990120022802f00120022802f801220641146c6a20052003109d081a200241286a200620046a360200200220022903f001370320200141386a2802002204ad42187e2207422088a70d002007a72203417f4c0d00200128023021050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341186e3602f401200241f0016a4100200410970120022802f00120022802f801220641186c6a20052003109d081a200241386a200620046a360200200220022903f001370330200141c4006a2802002204ad421c7e2207422088a70d002007a72203417f4c0d00200128023c21050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f00120022003411c6e3602f401200241f0016a4100200410f90120022802f00120022802f8012206411c6c6a20052003109d081a200241c8006a200620046a360200200220022903f001370340200141d0006a280200220341ffffff3f712003470d0020034105742204417f4c0d00200128024821050240024020040d00410421060c010b200410332206450d020b200241003602f801200220063602f001200220044105763602f401200241f0016a4100200310910120022802f00120022802f80122044105746a20052003410574109d081a200241d8006a200420036a360200200220022903f001370350200141dc006a2802002204ad42247e2207422088a70d002007a72203417f4c0d00200128025421050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341246e3602f401200241f0016a41002004108d0120022802f00120022802f801220641246c6a20052003109d081a200241e8006a200620046a360200200220022903f001370360200141e8006a2802002204ad42287e2207422088a70d002007a72203417f4c0d00200128026021050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341286e3602f401200241f0016a41002004109d0120022802f00120022802f801220641286c6a20052003109d081a200241f8006a200620046a360200200220022903f001370370200141f4006a2802002204ad422c7e2207422088a70d002007a72203417f4c0d00200128026c21050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f00120022003412c6e3602f401200241f0016a4100200410980120022802f00120022802f8012206412c6c6a20052003109d081a20024188016a200620046a360200200220022903f0013703800120014180016a2802002204ad42307e2207422088a70d002007a72203417f4c0d00200128027821050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341306e3602f401200241f0016a4100200410890120022802f00120022802f801220641306c6a20052003109d081a20024198016a200620046a360200200220022903f001370390012001418c016a2802002204ad42347e2207422088a70d002007a72203417f4c0d0020012802840121050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341346e3602f401200241f0016a4100200410a50120022802f00120022802f801220641346c6a20052003109d081a200241a8016a200620046a360200200220022903f0013703a00120014198016a2802002204ad42387e2207422088a70d002007a72203417f4c0d0020012802900121050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341386e3602f401200241f0016a4100200410a20120022802f00120022802f801220641386c6a20052003109d081a200241b8016a200620046a360200200220022903f0013703b001200141a4016a2802002204ad423c7e2207422088a70d002007a72203417f4c0d00200128029c0121050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f00120022003413c6e3602f401200241f0016a4100200410aa0120022802f00120022802f8012206413c6c6a20052003109d081a200241c8016a200620046a360200200220022903f0013703c001200141b0016a280200220341ffffff1f712003470d0020034106742204417f4c0d0020012802a80121050240024020040d00410421060c010b200410332206450d020b200241003602f801200220063602f001200220044106763602f401200241f0016a4100200310a60120022802f00120022802f80122044106746a20052003410674109d081a200241d8016a200420036a360200200220022903f0013703d001200141bc016a2802002204ad42c4007e2207422088a70d002007a72203417f4c0d0020012802b40121010240024020030d00410421050c010b200310332205450d020b200241003602f801200220053602f0012002200341c4006e3602f401200241f0016a41002004109f0120022802f00120022802f801220541c4006c6a20012003109d081a200241e0016a41086a2201200520046a360200200220022903f0013703e001200041146a200241086a2802003602002000200229030037020c20002002290310370218200041206a200241106a41086a280200360200200020022903203702242000412c6a200241206a41086a28020036020020002002290330370230200041386a200241306a41086a280200360200200041c4006a200241c0006a41086a2802003602002000200229034037023c200041d0006a200241d0006a41086a28020036020020002002290350370248200041dc006a200241e0006a41086a28020036020020002002290360370254200041e8006a200241f0006a41086a28020036020020002002290370370260200041f4006a20024180016a41086a280200360200200020022903800137026c20004180016a20024190016a41086a28020036020020002002290390013702782000418c016a200241a0016a41086a280200360200200020022903a0013702840120004198016a200241b0016a41086a280200360200200020022903b00137029001200041a4016a200241c0016a41086a280200360200200020022903c00137029c01200041b0016a200241d0016a41086a280200360200200020022903d0013702a801200041bc016a2001280200360200200020022903e0013702b40120024180026a24000f0b1044000b1045000b89f0020a017f027e017f017e127f037e037f037e067f047e230041900c6b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e19000102030405061a1917161514131211100f0e0d0c0b0a0908000b200341940a6a4101360200200342013702840a200341e8d4ca003602800a200341043602f4062003419cd5ca003602f0062003200341f0066a3602900a200341800a6a41b0b4cc00104c000b200141306a2903002104200141286a290300210520012d0001210620034190076a200141246a280200360200200341f0066a41186a2001411c6a290200370300200341f0066a41106a200141146a290200370300200341f0066a41086a2001410c6a2902003703002003200141046a2902003703f0062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211941012101024020022d00000d0020022d000141014721010b200320073701e80b200320083a00e70b200320093a00e60b2003200a3b01e40b2003200b3a00e30b2003200c3a00e20b2003200d3b01e00b2003200e3a00df0b2003200f3a00de0b200320103b01dc0b200320113a00db0b200320123a00da0b200320133b01d80b200320143a00d70b200320153a00d60b200320163b01d40b200320173a00d30b200320183a00d20b200320193b01d00b0240024020010d00200341e0086a41186a200341d00b6a41186a290100370300200341e0086a41106a200341d00b6a41106a290100370300200341e0086a41086a200341d00b6a41086a290100370300200320032901d00b3703e008200341800a6a200341e0086a10b401200341206a20032802800a220220032802880a41b0b4cc0041004100108a0220032802202101024020032802840a450d00200210350b4103210220014101470d0141a1a6c0002101410d21084180800821090c260b41022102410021090c250b200341800a6a41206a200341f0066a41206a280200360200200341800a6a41186a200341f0066a41186a290300370300200341800a6a41106a200341f0066a41106a290300370300200341800a6a41086a200341f0066a41086a290300370300200320032903f0063703800a200341d0096a200341800a6a108b0220032d00d0094101460d05200341d0096a41086a2d00002101200341d9096a2f00002108200341db096a2d00002109200341dc096a2d0000210a200341dd096a2f0000210b200341df096a2d0000210c200341d0096a41106a2d0000210d200341e1096a2f0000210e200341e3096a2d0000210f200341e4096a2d00002110200341e5096a2f00002111200341e7096a2d00002112200341d0096a41186a2d0000211320032d00d109211420032d00d209211520032d00d309211620032d00d409211720032f00d509211820032d00d70921192003200341e9096a2900003703a009200320133a009f09200320123a009e09200320113b019c09200320103a009b092003200f3a009a092003200e3b0198092003200d3a0097092003200c3a0096092003200b3b0194092003200a3a009309200320093a009209200320083b019009200320013a008f09200320193a008e09200320183b018c09200320173a008b09200320163a008a09200320153a008909200320143a008809200341800a6a20034188096a10b701200341186a20032802800a220820032802880a41b0b4cc0041004100108a0220032802182101024020032802840a450d00200810350b024020014101470d004194a6c0002101410d21084180800c21090c250b02402005428080e983b1de165441002004501b450d0041d8a5c0002101411121084180801c21090c250b200341800a6a200341e0086a10b40120033502880a210720032802800a2101412010332202450d162002200329038809370000200241186a20034188096a41186a290300370000200241106a20034188096a41106a290300370000200241086a20034188096a41086a29030037000020074220862001ad842002ad4280808080800484100220021035024020032802840a450d00200110350b200341800a6a200341e0086a108c0220033502880a210720032802800a210102400240200641037122024103470d00410121024200211a410121080c010b024002400240024020020e03000102000b410021080c020b410121080c010b410221080b200320083a00f00b410110332202450d22200220083a000041002108428080808010211a0b20074220862001ad84201a2002ad841002024020080d00200210350b024020032802840a450d00200110350b200341e0086a108d0241f7edcb00ad4280808080f0008422071001220228000021012002290004211a200228000c21082002103541e4edcb00ad4280808080a0018410012202290000211b2002290008211c200210352003201c3701c8082003201b3701c008200320083601bc082003201a3701b408200320013601b008200341106a200341b0086a412010c0012003280214210120032802102108200710012202280000210920022900042107200228000c210a2002103541b5edcb00ad4280808080c0018410012202290000211a2002290008211b200210352003201b3701c8082003201a3701c0082003200a3601bc08200320073701b408200320093601b008200341086a200341b0086a412010c001200328020c210220032802082109200341d0096a200341e0086a108e02200341800a6a20032802d009220a20032802d809108f0241002001410020081b2208200241d40020091b6b2202200220084b1b2102200341800a6a41106a290300420020032903800a42015122011b210720032903880a420020011b211a024020032802d409450d00200a10350b200341800a6a41086a41053a0000200341890a6a20032903e008370000200341910a6a200341e0086a41086a2201290300370000200341990a6a200341e0086a41106a2209290300370000200341a10a6a200341e0086a41186a220a290300370000200341b80a6a220b20072004201a200554200720045420072004511b220c1b2207370300200341b00a6a201a2005200c1b2204370300200341043a00800a41b0b4cc004100200341800a6a10d40120012f0100210c20092f0100210d200a290300210520032f01e008210e20032d00e208210f20032d00e308211020032f01e408211120032d00e608211220032d00e708211320032d00ea08211420032d00eb08211520032f01ec08211620032d00ee08211720032d00ef08211820032d00f208211920032d00f308210620032f01f408211d20032d00f608211e20032d00f708211f200341003602d809200342043703d009200341d0096a41004100200820026b220a200a20084b1b10860120032802d80921090240200820024d0d0020032802d00920094102746a2101034020012002360200200141046a21012008200241016a2202470d000b200a20096a21090b200341b0086a41086a22022009360200200341d00a6a2005370300200341cf0a6a201f3a0000200341ce0a6a201e3a0000200341cc0a6a201d3b0100200341cb0a6a20063a0000200341ca0a6a20193a0000200341c80a6a200d3b0100200341c70a6a20183a0000200341c60a6a20173a0000200341c40a6a20163b0100200341c30a6a20153a0000200341c20a6a20143a0000200341c00a6a200c3b0100200341bf0a6a20133a0000200341be0a6a20123a0000200341bc0a6a20113b0100200341bb0a6a20103a0000200341ba0a6a200f3a0000200320032903d0093703b0082003200e3b01b80a200341800a6a41186a2007370300200341a80a6a4100360200200341b40a6a2002280200360200200320043703900a200320073703880a200320043703800a200342083703a00a200320032903b0083702ac0a200342f3e885db96cddbb3203703f00b200341f00b6a200b20042007411f109002200341d0096a20034188096a10b70120032802d0092102200320032802d8093602b408200320023602b008200341800a6a200341b0086a10e101024020032802d409450d00200210350b024020032802a40a2202450d00200241186c450d0020032802a00a10350b200341b00a6a28020041ffffffff0371450d2320032802ac0a10350c230b200141106a290300211b200141086a290300211c2002411a6a290100211a200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113410e21012002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d00002118200241086a2d00002119200241066a2f01002106200241056a2d0000211d200241046a2d0000211e200241026a2f0100211f20022d0001210b20022d0000210a41f7edcb00ad4280808080f0008410012202280000210820022900042107200228000c21092002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320083601b008200341286a200341b0086a10f2014103210202402003280228417d71450d0041dca2c0002108418080ec0021090c220b02400240200a41ff01710d00200b41ff01714101470d002003201a3703880c2003200c3a00870c2003200d3a00860c2003200e3b01840c2003200f3a00830c200320103a00820c200320113b01800c200320123a00ff0b200320133a00fe0b200320143b01fc0b200320153a00fb0b200320163a00fa0b200320173b01f80b200320183a00f70b200320193a00f60b200320063b01f40b2003201d3a00f30b2003201e3a00f20b2003201f3b01f00b200341f0066a200341f00b6a10b401200341800a6a20032802f006220920032802f80610d501200341990a6a2900002107200341980a6a2d0000210a200341970a6a2d0000210b200341950a6a2f0000210c200341940a6a2d0000210d200341930a6a2d0000210e200341910a6a2f0000210f200341900a6a2d000021102003418f0a6a2d000021112003418d0a6a2f000021122003418c0a6a2d000021132003418b0a6a2d00002114200341890a6a2f0000211541082101200341800a6a41086a2d0000211620032d00870a211720032f00850a211820032d00840a211920032d00830a210620032d00820a211d20032d00810a211e20032d00800a2108024020032802f406450d00200910350b200841ff01714101460d0141aea6c00021084180800421090c230b41022102410021090c220b200320073703e8092003200a3a00e7092003200b3a00e6092003200c3b01e4092003200d3a00e3092003200e3a00e2092003200f3b01e009200320103a00df09200320113a00de09200320123b01dc09200320133a00db09200320143a00da09200320153b01d809200320163a00d709200320173a00d609200320183b01d409200320193a00d309200320063a00d2092003201d3a00d1092003201e3a00d009200341d00b6a200341d0096a10b701200341800a6a20032802d00b220120032802d80b10d601200341b0086a41086a2208200341bc0a6a290200370300200341b0086a41106a2209200341c40a6a290200370300200341b0086a41186a220a200341cc0a6a290200370300200341b0086a41206a220b200341d40a6a2802003602002003200341b40a6a2902003703b0080240024020032802a00a220c450d00200341800a6a41186a2903002105200341800a6a41086a2903002104200341b00a6a2802002102200341ac0a6a280200210d200341a80a6a280200210e20032903900a211a20032903800a210720032802a40a210f20034188096a41206a200b28020036020020034188096a41186a200a29030037030020034188096a41106a200929030037030020034188096a41086a2008290300370300200320032903b00837038809024020032802d40b450d00200110350b200341e0086a41086a220120034188096a41086a290300370300200341e0086a41106a220820034188096a41106a290300370300200341e0086a41186a220920034188096a41186a290300370300200341e0086a41206a220a20034188096a41206a280200360200200341f0066a41186a2005370300200341a0076a200236020020034198076a200e36020020034194076a200f36020020032003290388093703e0082003201a37038007200320073703f0062003200d36029c072003200c36029007200320043703f806200341c4076a200a280200360200200341bc076a2009290300370200200341b4076a2008290300370200200341ac076a2001290300370200200341a4076a20032903e008370200200341b0086a200341f00b6a108e02200341800a6a20032802b008220120032802b808108f02200341800a6a41106a290300420020032903800a42015122021b210520032903880a420020021b211a024020032802b408450d0020011035200341f0066a41086a290300210420032903f00621070b201a20077d2220201a56200520047d201a200754ad7d221a200556201a2005511b0d01200341f0066a41186a2202290300212120032003290380072222201c20202020201c56201a201b56201a201b511b22011b22057c221c3703800720022021201b201a20011b221a7c201c202254ad7c3703002003200520077c22073703f0062003201a20047c2007200554ad7c22043703f806200341800a6a41386a201a370300200341b00a6a2005370300200341800a6a41086a41053a0000200341890a6a20032903f00b370000200341910a6a200341f00b6a41086a290300370000200341990a6a200341800c6a290300370000200341a10a6a200341f00b6a41186a290300370000200341043a00800a41b0b4cc004100200341800a6a10d401200342f3e885db96cddbb3203703880920034188096a200341f0066a41386a20072004411f109002200341800a6a200341d0096a10b70120032802800a2102200320032802880a3602b408200320023602b008200341f0066a200341b0086a10e101024020032802840a450d00200210350b02402003280294072202450d00200241186c450d0020032802900710350b20032802a00741ffffffff0371450d24200328029c0710350c240b024020032802d40b450d00200110350b41b6a6c0002108410d2101410021090c220b02402003280294072202450d00200241186c450d0020032802900710350b20032802a00741ffffffff0371450d22200328029c0710350c220b200141106a290300211b200141086a290300211c2002411a6a290100211a200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113410e21012002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d00002118200241086a2d00002119200241066a2f01002106200241056a2d0000211d200241046a2d0000211e200241026a2f0100211f20022d0001210b20022d0000210a41f7edcb00ad4280808080f0008410012202280000210820022900042107200228000c21092002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320083601b008200341386a200341b0086a10f201410321020240024002402003280238417d71450d0041dca2c0002108418090ec0021090c010b0240200a41ff01710d00200b41ff01714101470d002003201a3703e8092003200c3a00e7092003200d3a00e6092003200e3b01e4092003200f3a00e309200320103a00e209200320113b01e009200320123a00df09200320133a00de09200320143b01dc09200320153a00db09200320163a00da09200320173b01d809200320183a00d709200320193a00d609200320063b01d4092003201d3a00d3092003201e3a00d2092003201f3b01d009200341f00b6a200341d0096a10b701200341800a6a20032802f00b220b20032802f80b10d601200341b0086a41086a220c200341bc0a6a290200370300200341b0086a41106a220d200341c40a6a290200370300200341b0086a41186a220e200341cc0a6a290200370300200341b0086a41206a220f200341d40a6a2802003602002003200341b40a6a2902003703b008024020032802a00a2209450d00200341800a6a41186a2903002107200341800a6a41086a2903002105200341b00a6a280200210a200341ac0a6a2802002110200341a80a6a280200210120032903900a210420032903800a211a20032802a40a210820034188096a41206a200f28020036020020034188096a41186a200e29030037030020034188096a41106a200d29030037030020034188096a41086a200c290300370300200320032903b00837038809024020032802f40b450d00200b10350b200341e0086a41086a220b20034188096a41086a290300370300200341e0086a41106a220c20034188096a41106a290300370300200341e0086a41186a220d20034188096a41186a290300370300200341e0086a41206a220e20034188096a41206a280200360200200341f0066a41186a2007370300200341a0076a200a36020020034198076a200136020020034194076a200836020020032003290388093703e00820032004370380072003201a3703f0062003201036029c072003200936029007200320053703f806200341c4076a200e280200360200200341bc076a200d290300370200200341b4076a200c290300370200200341ac076a200b290300370200200341a4076a20032903e0083702002001411f4d0d0302402008450d00200841186c450d002009103520032802a007210a0b0240200a41ffffffff0371450d00200328029c0710350b41cca5c0002108410c21014180902021090c020b024020032802f40b450d00200b10350b41b6a6c0002108410d210141801021090c010b4102210241801021090b20004200370308200041206a20013602002000411c6a2008360200200041186a20092002723602000c240b200341f0066a41206a210202402004201c2004201c542007201b542007201b511b220a1b22052007201b200a1b221a844200510d00200341f0066a41186a42002007201a7d2004200554ad7d221b200420057d221c428080e983b1de16544100201b501b220a1b37030020034200201c200a1b3703800741f7edcb00ad4280808080f000841001220b280000210c200b290004211b200b28000c210d200b103541e4edcb00ad4280808080a001841001220b290000211c200b2900082120200b1035200320203701c8082003201c3701c0082003200d3601bc082003201b3701b4082003200c3601b008200341306a200341b0086a412010c0012007201a200a1b210720042005200a1b2104200328023441a0056a41a00520032802301b210a024020012008470d00200220084101109c01200328029807210120032802900721090b2009200141186c6a22012007370308200120043703002001200a360210200320032802980741016a36029807200342f3e885db96cddbb3203703880920034188096a200341f0066a41386a20032903f006200341f0066a41086a290300411f109002200341800a6a200341d0096a10b70120032802800a2101200320032802880a3602b408200320013602b008200341f0066a200341b0086a10e101024020032802840a450d00200110350b200341800a6a41386a2007370300200341b00a6a2004370300200341800a6a41086a41063a0000200341890a6a20032903a807370000200341910a6a200341b0076a290300370000200341990a6a200341b8076a290300370000200341a10a6a200341c0076a290300370000200341043a00800a41b0b4cc004100200341800a6a10d4010b0240200241046a2802002201450d00200141186c450d00200228020010350b20032802a00741ffffffff0371450d21200328029c0710350c210b2002411a6a290100211a200241196a2d0000210e200241186a2d0000210f200241166a2f01002110200241156a2d00002111200241146a2d00002112200241126a2f01002113200241116a2d00002114200241106a2d00002115410e21082002410e6a2f010021162002410d6a2d000021172002410c6a2d000021182002410a6a2f01002119200241096a2d0000210641082101200241086a2d0000211d200241066a2f0100211e200241056a2d0000211f200241046a2d00002123200241026a2f0100210b20022d0001210d20022d0000210c41f7edcb00ad4280808080f0008410012202280000210920022900042107200228000c210a2002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c0082003200a3601bc08200320073701b408200320093601b008200341c8006a200341b0086a10f20141032102024002402003280248417d710d000240200c41ff01710d00200d41ff01714101470d002003201a3703880c2003200e3a00870c2003200f3a00860c200320103b01840c200320113a00830c200320123a00820c200320133b01800c200320143a00ff0b200320153a00fe0b200320163b01fc0b200320173a00fb0b200320183a00fa0b200320193b01f80b200320063a00f70b2003201d3a00f60b2003201e3b01f40b2003201f3a00f30b200320233a00f20b2003200b3a00f00b2003200b4108763a00f10b200341d0096a200341f00b6a10b701200341800a6a20032802d009220220032802d80910d601200341b0086a41086a2201200341bc0a6a290200370300200341b0086a41106a2208200341c40a6a290200370300200341b0086a41186a2209200341cc0a6a290200370300200341b0086a41206a220a200341d40a6a2802003602002003200341b40a6a2902003703b00802400240024020032802a00a220b450d00200341800a6a41186a2903002107200341800a6a41086a290300211b200341b00a6a280200210c200341ac0a6a280200210d200341a80a6a280200210e20032903900a210420032903800a211c20032802a40a210f20034188096a41206a200a28020036020020034188096a41186a200929030037030020034188096a41106a200829030037030020034188096a41086a2001290300370300200320032903b00837038809024020032802d409450d00200210350b200341e0086a41086a220220034188096a41086a290300370300200341e0086a41106a220120034188096a41106a290300370300200341e0086a41186a220820034188096a41186a290300370300200341e0086a41206a220920034188096a41206a280200360200200341f0066a41186a220a2007370300200341a0076a200c36020020034198076a200e36020020034194076a200f36020020032003290388093703e00820032004370380072003201c3703f0062003200d36029c072003200b360290072003201b3703f806200341c4076a2009280200360200200341bc076a220c2008290300370200200341b4076a220d2001290300370200200341ac076a220e2002290300370200200341a4076a20032903e008370200200341d0096a41186a200341c0076a220f290300370300200341d0096a41106a200341b8076a2210290300370300200341d0096a41086a200341b0076a2211290300370300200320032903a8073703d00941f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21082002103541e4edcb00ad4280808080a001841001220229000021042002290008210520021035200320053701c808200320043701c008200320083601bc08200320073701b408200320013601b008200341c0006a200341b0086a412010c00120032802404101460d01200a2903002120200329038007212120032802980721080c020b024020032802d409450d00200210350b41b6a6c0002109410d210841032102410821014100210a4100210b0c040b20032802442109200341b0086a41086a2003419c076a220b41086a2802003602002003200b2902003703b0082003280290072112200a2903002120200341aa076a2d00002113200341ab076a2d00002114200e2f01002115200341ae076a2d00002116200341af076a2d0000211720112f01002111200341b2076a2d00002118200341b3076a2d00002119200d2f01002106200341b6076a2d0000211d200341b7076a2d0000211e20102f01002110200341ba076a2d0000211f200341bb076a2d00002123200c2f01002124200341be076a2d00002125200341bf076a2d00002126200f2903002122200329038007212120032f01a807210f200328029407210d201c2107201b2104024002400240200328029807220e450d002012200e41186c6a210a200e41186c41686a2101201c2107201b2104201221020340200241086a290300211a200229030021052009200241106a2802002208490d0242002004201a7d2007200554ad7d221a200720057d2205200756201a200456201a2004511b22081b21044200200520081b2107200141686a2101200241186a2202200a470d000b0b4108210c410021080240200d450d00200d41186c450d00201210350b410021020c010b41181033220c450d18200c2005370300200c2008360210200c201a37030820034281808080103702840a2003200c3602800a0240024020010d00410121080c010b200241186a2127200e41186c20126a41686a21284101210803402027210202400340200241086a290300211a200229030021052009200241106a2802002201490d0142002004201a7d2007200554ad7d221a200720057d2205200756201a200456201a2004511b22011b21044200200520011b2107200241186a2202200a470d000c030b0b0240200820032802840a470d00200341800a6a20084101109c0120032802800a210c0b200241186a2127200c200841186c6a220e2001360210200e201a370308200e20053703002003200841016a22083602880a20282002470d000b0b0240200d450d00200d41186c450d00201210350b20032802840a21020b200b20032903b00837020020034188076a2020370300200b41086a200341b0086a41086a2802003602002003202137038007200320073703f006200320083602980720032002360294072003200c36029007200320223703c007200320263a00bf07200320253a00be07200320243b01bc07200320233a00bb072003201f3a00ba07200320103b01b8072003201e3a00b7072003201d3a00b607200320063b01b407200320193a00b307200320183a00b207200320113b01b007200320173a00af07200320163a00ae07200320153b01ac07200320143a00ab07200320133a00aa072003200f3b01a807200320043703f8060b024002400240024020080d002021202084500d010b200342f3e885db96cddbb3203703880920034188096a200341a8076a20032903f006200341f8066a290300411f109002200341800a6a200341f00b6a10b70120032802800a2102200320032802880a3602b408200320023602b008200341f0066a200341b0086a10e10120032802840a450d01200210350c010b200341800a6a200341d0096a10910220032d00800a22024104470d01200342f3e885db96cddbb3203703d00b200341d00b6a200341d0096a1092020b0240201c20032903f006220458201b200341f0066a41086a290300220758201b2007511b0d00200341b00a6a201c20047d370300200341800a6a41086a41073a0000200341890a6a20032903d009370000200341910a6a200341d0096a41086a290300370000200341990a6a200341e0096a290300370000200341a10a6a200341e8096a290300370000200341b80a6a201b20077d201c200454ad7d370300200341043a00800a41b0b4cc004100200341800a6a10d4010b02402003280294072202450d00200241186c450d0020032802900710350b20032802a00741ffffffff0371450d24200328029c0710350c240b20032d00830a411074210120032f00810a210820032902840a210702402003280294072209450d00200941186c450d0020032802900710350b2008200172210120074220882104024020032802a00741ffffffff0371450d00200328029c0710350b2001411076210a2001410876210b2004a721082007a721090c020b410221020b41dca2c0002109411b210b4100210a0b20004200370308200041206a20083602002000411c6a2009360200200041186a200a411874200b411074418080fc07717220014108744180fe0371722002723602000c220b2002411a6a290100211a200241196a2d0000210d200241186a2d0000210e200241166a2f0100210f200241156a2d00002110200241146a2d00002111200241126a2f01002112200241116a2d00002113200241106a2d00002114410e21082002410e6a2f010021152002410d6a2d000021162002410c6a2d000021172002410a6a2f01002118200241096a2d00002119200241086a2d00002106200241066a2f0100211d200241056a2d0000211e200241046a2d0000211f200241026a2f01002123200141046a280200210b20022d0001210c20022d0000210a41f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21092002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320013601b008200341d0006a200341b0086a10f20141032102024002402003280250417d71450d0041dca2c0002101418090ec0021090c010b0240200a41ff01710d00200c41ff01714101470d002003201a3703e8092003200d3a00e7092003200e3a00e6092003200f3b01e409200320103a00e309200320113a00e209200320123b01e009200320133a00df09200320143a00de09200320153b01dc09200320163a00db09200320173a00da09200320183b01d809200320193a00d709200320063a00d6092003201d3b01d4092003201e3a00d3092003201f3a00d209200320233b01d009200341f00b6a200341d0096a10b701200341800a6a20032802f00b220a20032802f80b10d601200341b0086a41086a220c200341bc0a6a290200370300200341b0086a41106a220d200341c40a6a290200370300200341b0086a41186a220e200341cc0a6a290200370300200341b0086a41206a220f200341d40a6a2802003602002003200341b40a6a2902003703b008024020032802a00a2201450d00200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a2802002108200341ac0a6a2802002109200341a80a6a280200211020032903900a210520032903800a211a20032802a40a210220034188096a41206a200f28020036020020034188096a41186a200e29030037030020034188096a41106a200d29030037030020034188096a41086a200c290300370300200320032903b00837038809024020032802f40b450d00200a10350b200341e0086a41086a220a20034188096a41086a290300370300200341e0086a41106a220c20034188096a41106a290300370300200341e0086a41186a220d20034188096a41186a290300370300200341e0086a41206a220e20034188096a41206a280200360200200341f0066a41186a2007370300200341a0076a200836020020034198076a201036020020034194076a200236020020032003290388093703e00820032005370380072003201a3703f0062003200936029c072003200136029007200320043703f806200341c4076a200e280200360200200341bc076a200d290300370200200341b4076a200c290300370200200341ac076a200a290300370200200341a4076a20032903e008370200200341800a6a200341a8076a220a10b90120033502880a42208620032802800a220cad841007024020032802840a450d00200c10350b200341800a6a200a10b50120033502880a210720032802800a210a200341003a00b5080240024002400240200b41c000490d00200b41808001490d01200b418080808004490d02200341053a00b508200341033a00b0082003200b3600b1084280808080d00021040c030b200341013a00b5082003200b4102743a00b00842808080801021040c020b200341023a00b5082003200b4102744101723b01b00842808080802021040c010b200341043a00b5082003200b4102744102723602b0084280808080c00021040b2007422086200aad842004200341b0086aad841002024020032d00b508450d00200341003a00b5080b024020032802840a450d00200a10350b02402002450d00200241186c450d00200110350b200841ffffffff0371450d22200910350c220b024020032802f40b450d00200a10350b41b6a6c0002101410d210841801021090c010b4102210241801021090b20004200370308200041206a20083602002000411c6a2001360200200041186a20092002723602000c210b2001410c6a280200210e200141086a2802002108200141046a280200210b2002411a6a290100211a200241196a2d0000210f200241186a2d00002110200241166a2f01002111200241156a2d00002112200241146a2d00002113200241126a2f01002114200241116a2d00002115200241106a2d00002116410e21012002410e6a2f010021172002410d6a2d000021182002410c6a2d000021192002410a6a2f01002106200241096a2d0000211d200241086a2d0000211e200241066a2f0100211f200241056a2d00002123200241046a2d00002124200241026a2f0100212520022d0001210d20022d0000210c41f7edcb00ad4280808080f0008410012202280000210920022900042107200228000c210a2002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c0082003200a3601bc08200320073701b408200320093601b008200341e0006a200341b0086a10f2014103210202402003280260417d71450d0041dca2c0002109411b210a0c170b200c41ff01710d14200d41ff01714101470d142003201a3703c8092003200f3a00c709200320103a00c609200320113b01c409200320123a00c309200320133a00c209200320143b01c009200320153a00bf09200320163a00be09200320173b01bc09200320183a00bb09200320193a00ba09200320063b01b8092003201d3a00b7092003201e3a00b6092003201f3b01b409200320233a00b309200320243a00b209200320253b01b009200341d0096a200341b0096a10b701200341800a6a20032802d009220c20032802d80910d601200341b0086a41086a220d200341bc0a6a290200370300200341b0086a41106a220f200341c40a6a290200370300200341b0086a41186a2210200341cc0a6a290200370300200341b0086a41206a2211200341d40a6a2802003602002003200341b40a6a2902003703b008024002400240024020032802a00a2209450d00200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a280200210a200341ac0a6a2802002112200341a80a6a280200211320032903900a210520032903800a211a20032802a40a210120034188096a41206a201128020036020020034188096a41186a201029030037030020034188096a41106a200f29030037030020034188096a41086a200d290300370300200320032903b00837038809024020032802d409450d00200c10350b200341e0086a41086a220c20034188096a41086a290300370300200341e0086a41106a220d20034188096a41106a290300370300200341e0086a41186a220f20034188096a41186a290300370300200341e0086a41206a221020034188096a41206a280200360200200341f0066a41186a2007370300200341a0076a200a36020020034198076a2013360200200341f0066a41246a200136020020032003290388093703e00820032005370380072003201a3703f0062003201236029c072003200936029007200320043703f806200341c4076a2010280200360200200341bc076a200f290300370200200341b4076a200d290300370200200341ac076a200c290300370200200341a4076a20032903e008370200200e450d190240200e41246c2202450d00200341d0096a41086a220c200b41096a290000370300200341d0096a41106a220d200b41116a290000370300200341d0096a41186a220f200b41196a290000370300200341ef096a2210200b41206a2800003600002003200b2900013703d009200b2d000022114102470d020b4100210c0c020b024020032802d409450d00200c10350b41b6a6c0002109410d21014100210a0c190b200341800a6a41096a200c290300370000200341800a6a41116a200d290300370000200341800a6a41196a200f290300370000200341800a6a41206a2010280000360000200320113a00800a200320032903d0093700810a200341b0086a200341800a6a108b0220034188096a41086a200341b0086a41096a29000037030020034188096a41106a200341b0086a41116a29000037030020034188096a41186a200341b0086a41196a290000370300200320032900b108370388094101210c20032d00b0084101470d01200341f00b6a41086a200341e0086a41086a290300370300200341f00b6a41106a200341e0086a41106a290300370300200341f00b6a41186a200341e0086a41186a290300370300200320032903e0083703f00b0b4100210e4101210f02402008450d00200841246c450d00200b10350b410021020c190b200341d00b6a41086a220c20034188096a41086a290300370300200341d00b6a41106a220d20034188096a41106a290300370300200341d00b6a41186a221020034188096a41186a290300370300200320032903880922073703f00b200320073703d00b41201033220f450d11200f20032903d00b370000200f41186a2010290300370000200f41106a200d290300370000200f41086a200c29030037000020034281808080103702c40b2003200f3602c00b02400240200b20026a200b41246a460d00200341d0096a41086a2202200b412d6a290000370300200341d0096a41106a220c200b41356a290000370300200341d0096a41186a220d200b413d6a290000370300200341ef096a2210200b41c4006a2800003600002003200b2900253703d009200b2d002422114102460d00200341800a6a41096a2002290300370000200341800a6a41116a200c290300370000200341800a6a41196a200d290300370000200341800a6a41206a2010280000360000200320113a00800a200320032903d0093700810a200341b0086a200341800a6a108b0220034188096a41086a200341b0086a41096a29000037030020034188096a41106a200341b0086a41116a29000037030020034188096a41186a200341b0086a41196a290000370300200320032900b1083703880920032d00b0084101470d01200341f00b6a41086a200341e0086a41086a290300370300200341f00b6a41106a200341e0086a41106a290300370300200341f00b6a41186a200341e0086a41186a290300370300200320032903e0083703f00b4101210c410121020c190b4100210c410121020c180b200b41c8006a210d200341f00b6a41086a222420034188096a41086a221d2903002207370300200341d00b6a41186a221420034188096a41186a221e290300370300200341d00b6a41106a221520034188096a41106a221f290300370300200341d00b6a41086a22162007370300200320032903880922073703f00b200320073703d00b200e41246c41b87f6a2113200341b0086a4101722110200341800a6a410172210e200341d0096a411f6a210641202111410221024101210c0340200341800a6a41186a22172014290300370300200341800a6a41106a22182015290300370300200341800a6a41086a22192016290300370300200320032903d00b3703800a02402002417f6a200c470d00200341c00b6a200c4101108a0120032802c00b210f0b200f20116a220c20032903800a370000200c41186a2017290300370000200c41106a2018290300370000200c41086a2019290300370000200320023602c80b4100210c20024110460d182013450d18200341d0096a41086a2217200d41096a290000370300200341d0096a41106a2218200d41116a290000370300200341d0096a41186a2219200d41196a2900003703002006200d41206a2800003600002003200d2900013703d009200d2d000022234102460d18200e20032903d009370000200e41086a2017290300370000200e41106a2018290300370000200e41186a2019290300370000200e411f6a2006280000360000200320233a00800a200341b0086a200341800a6a108b02201d201041086a290000370300201f201041106a290000370300201e201041186a2900003703002003201029000037038809024020032d00b0084101470d00200341f00b6a41086a200341e0086a41086a290300370300200341f00b6a41106a200341e0086a41106a290300370300200341f00b6a41186a200341e0086a41186a290300370300200320032903e0083703f00b4101210c0c190b200d41246a210d2024201d29030022073703002014201e2903003703002015201f29030037030020162007370300200320032903880922073703f00b200320073703d00b201141206a2111200241016a21022013415c6a211320032802c40b210c0c000b0b41012102410021090c1e0b2001410c6a280200210a200141086a2802002108200141046a2802002109200141d0016a280200210b200341f0066a200141106a41c001109d081a200341d8086a20014180026a290300370300200341d0086a200141f8016a290300370300200341c8086a200141f0016a290300370300200341b0086a41106a200141e8016a290300370300200341b0086a41086a200141e0016a2903003703002003200141d8016a2903003703b0080240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000d0020022d000141ff01714102470d002003200a360290092003200836028c092003200936028809200341800a6a200341f0066a41c001109d081a200341d0096a41286a200341b0086a41286a290300370300200341d0096a41206a200341b0086a41206a290300370300200341d0096a41186a200341b0086a41186a290300370300200341d0096a41106a200341b0086a41106a290300370300200341d0096a41086a200341b0086a41086a290300370300200320032903b0083703d00920034188096a200341800a6a4102200341d0096a200b109302220941ff0171411d460d3c41dca2c0002102410e2108418080ec0021012009411f710e1d0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d010b200341f0066a10fa012008450d1d200841ffffffff0771450d1d200910350c1d0b200341940a6a4101360200200342013702840a200341e8d4ca003602800a200341043602d409200341f0d5ca003602d0092003200341d0096a3602900a200341800a6a41b0b4cc00104c000b41b6a6c0002102410d2108410021010c1a0b41aea6c0002102410821084180800421010c190b41a1a6c0002102410d21084180800821010c180b4194a6c0002102410d21084180800c21010c170b4188a6c0002102410c21084180801021010c160b41faa5c00021024180801421010c150b41e9a5c0002102411121084180801821010c140b41d8a5c0002102411121084180801c21010c130b41cca5c0002102410c21084180802021010c120b41bfa5c0002102410d21084180802421010c110b41b3a5c0002102410c21084180802821010c100b41a1a5c0002102411221084180802c21010c0f0b4187a5c0002102411a21084180803021010c0e0b41f5a4c0002102411221084180803421010c0d0b41e7a4c00021024180803821010c0c0b41d0a4c0002102411721084180803c21010c0b0b41baa4c000210241162108418080c00021010c0a0b41a7a4c000210241132108418080c40021010c090b418fa4c000210241182108418080c80021010c080b41fca3c000210241132108418080cc0021010c070b41e8a3c000210241142108418080d00021010c060b41d2a3c000210241162108418080d40021010c050b41bba3c000210241172108418080d80021010c040b41a2a3c000210241192108418080dc0021010c030b418da3c000210241152108418080e00021010c020b41fca2c000210241112108418080e40021010c010b41eaa2c000210241122108418080e80021010b410321090c010b41022109410021010b20004200370308200041206a20083602002000411c6a2002360200200041186a2001418080fc0071200972418010723602000c1e0b2001410c6a280200210a200141086a2802002108200141046a2802002109200141d0016a280200210b200341f0066a200141106a41c001109d081a200341d8086a20014180026a290300370300200341d0086a200141f8016a290300370300200341c8086a200141f0016a290300370300200341b0086a41106a200141e8016a290300370300200341b0086a41086a200141e0016a2903003703002003200141d8016a2903003703b0080240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000d0020022d00014101470d002003200a360290092003200836028c092003200936028809200341800a6a200341f0066a41c001109d081a200341d0096a41286a200341b0086a41286a290300370300200341d0096a41206a200341b0086a41206a290300370300200341d0096a41186a200341b0086a41186a290300370300200341d0096a41106a200341b0086a41106a290300370300200341d0096a41086a200341b0086a41086a290300370300200320032903b0083703d00920034188096a200341800a6a4101200341d0096a200b109302220941ff0171411d460d3b41dca2c0002102410e2108418080ec0021012009411f710e1d0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d010b200341f0066a10fa012008450d1d200841ffffffff0771450d1d200910350c1d0b200341940a6a4101360200200342013702840a200341e8d4ca003602800a200341043602d409200341f0d5ca003602d0092003200341d0096a3602900a200341800a6a41b0b4cc00104c000b41b6a6c0002102410d2108410021010c1a0b41aea6c0002102410821084180800421010c190b41a1a6c0002102410d21084180800821010c180b4194a6c0002102410d21084180800c21010c170b4188a6c0002102410c21084180801021010c160b41faa5c00021024180801421010c150b41e9a5c0002102411121084180801821010c140b41d8a5c0002102411121084180801c21010c130b41cca5c0002102410c21084180802021010c120b41bfa5c0002102410d21084180802421010c110b41b3a5c0002102410c21084180802821010c100b41a1a5c0002102411221084180802c21010c0f0b4187a5c0002102411a21084180803021010c0e0b41f5a4c0002102411221084180803421010c0d0b41e7a4c00021024180803821010c0c0b41d0a4c0002102411721084180803c21010c0b0b41baa4c000210241162108418080c00021010c0a0b41a7a4c000210241132108418080c40021010c090b418fa4c000210241182108418080c80021010c080b41fca3c000210241132108418080cc0021010c070b41e8a3c000210241142108418080d00021010c060b41d2a3c000210241162108418080d40021010c050b41bba3c000210241172108418080d80021010c040b41a2a3c000210241192108418080dc0021010c030b418da3c000210241152108418080e00021010c020b41fca2c000210241112108418080e40021010c010b41eaa2c000210241122108418080e80021010b410321090c010b41022109410021010b20004200370308200041206a20083602002000411c6a2002360200200041186a2001418080fc0071200972418010723602000c1d0b200341f0066a41186a200141196a290000370300200341f0066a41106a200141116a290000370300200341f8066a200141096a290000370300200320012900013703f006200341d0096a200341f0066a108e02200341800a6a20032802d009220120032802d809108f02200341800a6a41106a290300420020032903800a42015122021b210720032903880a420020021b2104200341a00a6a290300420020021b2105200341800a6a41186a290300420020021b211a024020032802d409450d00200110350b024002400240427f2004201a7c221a201a2004542202200720057c2002ad7c220420075420042007511b22021b427f200420021b844200520d00200341800a6a200341f0066a10910220032d00800a22024104460d0220032f00810a20032d00830a4110747241087422094180fe037121012009418080fc077121082009418080807871210920032902840a2207422088a7210a2007a7210b0c010b41b3a5c000210b410c210a410321024180102101418080282108410021090b20004200370308200041206a200a3602002000411c6a200b360200200041186a20092008722001722002723602000c1d0b200342f3e885db96cddbb3203703b008200341b0086a200341f0066a1092020c1a0b024020022d000120022d0000410047720d00200141046a280200210841f7edcb00ad4280808080f00084221a10012202280000210120022900042107200228000c21092002103541e4edcb00ad4280808080a001841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320013601b008200341e8066a200341b0086a412010c00120032802e8064101470d1a20032802ec062101201a10012202280000210920022900042107200228000c210a2002103541b5edcb00ad4280808080c0018422041001220229000021052002290008211a200210352003201a3701c808200320053701c0082003200a3601bc08200320073701b408200320093601b008200341e0066a200341b0086a412010c00102404100200120032802e40641d40020032802e0061b6b2202200220014b1b22024100200120086b2209200920014b1b22014f0d000340200210c1012001200241016a2202470d000b0b41f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21092002103520041001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320013601b008200320083602800a200341b0086aad4280808080800484200341800a6aad4280808080c0008410020c1a0b20004200370308200041186a41023602000c1b0b200141106a2903002107200141086a290300211b2002411a6a290100211c200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113410e21012002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d00002118200241086a2d00002119200241066a2f01002106200241056a2d0000211d200241046a2d0000211e200241026a2f0100211f20022d0001210b20022d0000210a41f7edcb00ad4280808080f0008410012202280000210820022900042104200228000c21092002103541b6aac000ad42808080809002841001220229000021052002290008211a200210352003201a3701c808200320053701c008200320093601bc08200320043701b408200320083601b008200341d8066a200341b0086a10f201410321020240024020032802d806417d71450d0041dca2c0002108418090ec0021090c010b02400240200a41ff01710d00200b41ff01714101470d002003201c3703880c2003200c3a00870c2003200d3a00860c2003200e3b01840c2003200f3a00830c200320103a00820c200320113b01800c200320123a00ff0b200320133a00fe0b200320143b01fc0b200320153a00fb0b200320163a00fa0b200320173b01f80b200320183a00f70b200320193a00f60b200320063b01f40b2003201d3a00f30b2003201e3a00f20b2003201f3b01f00b200341f0066a200341f00b6a10b701200341800a6a20032802f006220820032802f80610d601200341b0086a41086a220a200341bc0a6a290200370300200341b0086a41106a220b200341c40a6a290200370300200341b0086a41186a220c200341cc0a6a290200370300200341b0086a41206a220d200341d40a6a2802003602002003200341b40a6a2902003703b00820032802a00a2209450d01200341800a6a41186a290300211c200341800a6a41086a2903002129200341b00a6a280200210f200341ac0a6a2802002110200341a80a6a280200210120032903900a212020032903800a212a20032802a40a210e20034188096a41206a200d28020036020020034188096a41186a200c29030037030020034188096a41106a200b29030037030020034188096a41086a200a290300370300200320032903b00837038809024020032802f406450d00200810350b200341e0086a41106a20034188096a41106a2903002204370300200341d0096a41086a220820034188096a41086a290300370300200341d0096a41106a220a2004370300200341d0096a41186a220b20034188096a41186a290300370300200341d0096a41206a220c20034188096a41206a28020036020020032003290388093703d00902402001450d00200341f0066a41206a200c280200360200200341f0066a41186a200b290300370300200341f0066a41106a200a290300370300200341f0066a41086a2008290300370300200320032903d0093703f006200141186c20096a41686a2102420021214200212202400340024020010d00410021010c020b02402002290300220420217c2205201b58200241086a290300222b20227c2005200454ad7c221a200758201a20075122081b0d0020022004201b20217d22057d3703002002202b200720227d201b202154ad7d22077d2004200554ad7d3703082007201c7c200520207c2220200554ad7c211c0c020b2001417f6a2101202b201c7c200420207c2220200454ad7c211c200241686a210220052121201a21222005201b54201a20075420081b0d000b0b200341800a6a41186a201c370300200341b00a6a200f360200200341a80a6a2001360200200341a40a6a200e360200200341b40a6a20032903f006370200200341bc0a6a200341f8066a290300370200200341c40a6a20034180076a290300370200200341cc0a6a200341f0066a41186a290300370200200341d40a6a20034190076a280200360200200320203703900a2003202a3703800a200320103602ac0a200320093602a00a200320293703880a200342f3e885db96cddbb3203703880920034188096a200341b80a6a202a2029411f109002200341f0066a200341f00b6a10b70120032802f0062102200320032802f8063602b408200320023602b008200341800a6a200341b0086a10e101024020032802f406450d00200210350b024020032802a40a2202450d00200241186c450d0020032802a00a10350b20032802b00a41ffffffff0371450d1c20032802ac0a10350c1c0b0240200e450d00200e41186c450d00200910350b0240200f41ffffffff0371450d00201010350b41bfa5c0002108410d21014180902421090c020b4102210241801021090c010b024020032802f406450d00200810350b41b6a6c0002108410d210141801021090b20004200370308200041206a20013602002000411c6a2008360200200041186a20092002723602000c1a0b200141246a280200210a20022d0001210b20022d00002109200341c8096a200141196a290000370300200341c0096a200141116a290000370300200341b8096a200141096a290000370300200320012900013703b00941f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21082002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701e80b200320043701e00b200320083601dc0b200320073701d40b200320013601d00b200341d0066a200341d00b6a10f201410321020240024002400240024002400240024002400240024020032802d006417d710d0041022102200941ff01710d00200b41ff01714101470d00200341f00b6a41186a200341b0096a41186a290300370300200341f00b6a41106a200341b0096a41106a290300370300200341f00b6a41086a200341b0096a41086a290300370300200320032903b0093703f00b41f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21082002103541e4edcb00ad4280808080a001841001220229000021042002290008210520021035200320053701e80b200320043701e00b200320083601dc0b200320073701d40b200320013601d00b200341c8066a200341d00b6a412010c00141a1a5c0002101411221084180802c210920032802c806450d0220032802cc06220b200a490d0241f7edcb00ad4280808080f00084221a10012202280000210c20022900042107200228000c210d2002103541b5edcb00ad4280808080c001841001220229000021042002290008210520021035200320053701e80b200320043701e00b2003200d3601dc0b200320073701d40b2003200c3601d00b200341c0066a200341d00b6a412010c001200a4100200b20032802c40641d40020032802c0061b6b22022002200b4b1b220b490d02201a10012202280000210c20022900042107200228000c210d2002103541eeeecb00ad4280808080a001841001220229000021042002290008210520021035200320053701e80b200320043701e00b2003200d3601dc0b200320073701d40b2003200c3601d00b200341b8066a200341d00b6a412010c001024020032802b8064101470d0020032802bc06200a4b0d030b200341800a6a200a10be01200341a0066a20032802800a220c20032802880a10d701200341b0066a290300210420032903a806210720032802a0062102024020032802840a450d00200c10350b2002450d02200341f0066a200341f00b6a10b401200341800a6a20032802f006220120032802f80610d501200341990a6a2900002105200341980a6a2d00002108200341970a6a2d00002109200341950a6a2f0000210c200341940a6a2d0000210d200341930a6a2d0000210e200341910a6a2f0000210f200341900a6a2d000021102003418f0a6a2d000021112003418d0a6a2f000021122003418c0a6a2d000021132003418b0a6a2d00002114200341890a6a2f00002115200341880a6a2d0000211620032d00870a211720032f00850a211820032d00840a211920032d00830a210620032d00820a211d20032d00810a211e20032d00800a2102024020032802f406450d00200110350b200241ff01714101470d01200320053703e809200320083a00e709200320093a00e6092003200c3b01e4092003200d3a00e3092003200e3a00e2092003200f3b01e009200320103a00df09200320113a00de09200320123b01dc09200320133a00db09200320143a00da09200320153b01d809200320163a00d709200320173a00d609200320183b01d409200320193a00d309200320063a00d2092003201d3a00d1092003201e3a00d009200341e0086a200341d0096a10b701200341800a6a20032802e008220220032802e80810d601200341b0086a41086a2208200341bc0a6a290200370300200341b0086a41106a2209200341c40a6a290200370300200341b0086a41186a220c200341cc0a6a290200370300200341b0086a41206a220d200341d40a6a2802003602002003200341b40a6a2902003703b00802400240024020032802a00a220e450d00200341800a6a41186a2903002105200341800a6a41086a290300211a200341b00a6a280200210f200341ac0a6a2802002101200341a80a6a280200211020032903900a211b20032903800a211c20032802a40a211120034188096a41206a200d28020036020020034188096a41186a200c29030037030020034188096a41106a200929030037030020034188096a41086a2008290300370300200320032903b00837038809024020032802e408450d00200210350b200341f0066a41186a2005370300200341a0076a200f36020020034198076a201036020020034194076a2011360200200341a4076a2202200329038809370200200341ac076a20034190096a290300370200200341b4076a20034198096a290300370200200341bc076a20034188096a41186a290300370200200341c4076a200341a8096a2802003602002003201b370380072003201c3703f0062003200136029c072003200e360290072003201a3703f8060240200228020022090d0041002108410021020c030b41002102410021080340024002400240200b2001280200220c4b0d0020020d01410021020c020b200241016a21020c010b200820026b220d20094f0d08200120024102746b220d280200210e200d200c3602002001200e3602000b200141046a21012009200841016a2208470d000b024002402002450d0020032802a407220c200920026b2202490d01200320023602a4072002210c0c010b20032802a407210c0b200328029c0721014100210802400240200c41014b0d0041002102200c0e020401040b200c2102034020082002410176220920086a220b200a2001200b4102746a280200491b2108200220096b220241014b0d000b0b41032102200a200120084102746a2802002209470d010c0a0b024020032802e408450d00200210350b41b6a6c0002101410d210841032102410021090c0a0b200c2008200a20094b6a2208490d05200c21020b0240200220032802a007470d002003419c076a20024101108601200328029c0721010b200120084102746a220141046a2001200220086b410274109e081a2001200a3602002003200241016a3602a407200341b0086a200a200341a8076a220c10d101200341800a6a20032802b008220220032802b8081085020240024020032802a00a22160d00420021054100211541082116410021104200211a4200211c420021200c010b200341880a6a2903002120200341980a6a290300211a200341a80a6a280200211020032903800a211c20032903900a210520032802a40a21150b024020032802b408450d00200210350b200341800a6a200341d0096a10b70120032802800a2102200320032802880a3602b408200320023602b008200341f0066a200341b0086a10e101024020032802840a450d00200210350b200341d00b6a200a10940241042102200341d00b6a41047221170240024020032802d40b220d450d0020032802d00b2111200341d00b6a41086a280200210e0340200d41086a2108200d2f0106220f4105742101410021090240024003402001450d01200c2008412010a008220b450d02200141606a2101200941016a2109200841206a2108200b417f4a0d000b2009417f6a210f0b200e450d02200e417f6a210e200d200f4102746a4194036a280200210d0c010b0b200d20094102746a41e8026a2802002201450d0020114101201141014b1b2202418094ebdc036e220820022008418094ebdc036c476a22084101200841014b1b220820024b0d0720034188066a20072004428094ebdc034200109808200341f8056a200329038806220420034188066a41086a290300221b4280ec94a37c427f108408200341e8056a2004201b2002200120022001491b20086ead428094ebdc037e200220086ead8042ffffffff0f8322214200108408200341800a6a200a200341f00b6a10d30120034198066a20032802800a220120032802880a10d201200341e8056a41086a29030020032903e80522042021200720032903f8057c7e2207428094ebdc0380221ba7417f2007428080808080c0b2cd3b541b2007201b4280ec94a37c7e7c4280cab5ee01566aad7c2207200454ad7c211b200328029c0641002003280298061b2102024020032802840a450d00200110350b200341c0056a2007201b428094ebdc034200109808200341b0056a20032903c0052204200341c0056a41086a29030022214280ec94a37c427f108408200341a0056a200420212002ad2222420010840820034190056a200720032903a00522212022200720032903b0057c7e2204428094ebdc03802222a7417f2004428080808080c0b2cd3b541b200420224280ec94a37c7e7c4280cab5ee01566aad7c22047d222b201b200341a0056a41086a2903002004202154ad7c22297d2007200454ad7d428094ebdc03420010980820034180056a200329039005222120034190056a41086a29030022224280ec94a37c427f108408200341f0046a202120222005201a201c2020109502ad22054200108408200341d0056a200c20032903f004221a20047c2207202b2003290380057c222b20057e2204428094ebdc03802205a7417f2004428080808080c0b2cd3b541b200420054280ec94a37c7e7c4280cab5ee01566aad7c2204200341f0046a41086a29030020297c2007201a54ad7c2004200754ad7c109602200341d0056a41106a290300210720032903d805210420032903d0052205a74101470d01200341b0076a2903002105200341b8076a290300211a200341c0076a290300211b20032903a8072129200341b80a6a2007370300200341b00a6a2004370300200341a10a6a201b370000200341990a6a201a370000200341910a6a2005370000200341890a6a2029370000200341800a6a41086a220241013a0000200341043a00800a41b0b4cc004100200341800a6a10d40120034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a2002200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e008200341c0046a200341e0086a412010d701200341c0046a41106a290300211b20032903c804212920032802c0042109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c2029420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020c080b201710b1012015450d08201541306c450d08201610350c080b20054201520d0620034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a200341800a6a41086a2202200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e008200341d8046a200341e0086a412010d701200341d8046a41106a290300211b20032903e004212920032802d8042109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c2029420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020c060b41dca2c0002101410e2108418080ec0021090c080b41aea6c0002101410821084180800421090b410321020c060b200d200941f485cc001042000b2008200c104d000b4190edc40041194180efc400103f000b0240201041306c2202450d00201620026a210f201641286a2102200341800a6aad4280808080800284212a200341e0086aad4280808080800484212c20034188096a41106a2101200341890a6a210b200341b80a6a2114034020034198046a20212022200241586a2208290300200841086a290300201c2020109502ad22074200108408200341a8046a200241686a220a20032903980422042007202b7e2207428094ebdc03802205a7417f2007428080808080c0b2cd3b541b200720054280ec94a37c7e7c4280cab5ee01566aad7c220720034198046a41086a2903002007200454ad7c109602200341a8046a41106a290300210720032903b004210402400240024020032903a8042205a74101470d00200241786a2900002105200a290000211a2002290000211b2003200241706a29000022293701b8082003201a3701b008200320053701c0082003201b3701c808200b201a370000200b41086a2029370000200b41106a2005370000200b41186a201b370000200320043703b00a20142007370300200341013a00880a200341043a00800a41b0b4cc004100200341800a6a10d40120034188096a41186a220c42003703002001420037030020034188096a41086a22094200370300200342003703880941b6fdc600ad428080808080018422051001220d290000211a200341800a6a41086a2208200d41086a2900003703002003201a3703800a200d103520092008290300370300200320032903800a3703880941e489c200ad4280808080d00184221a1001220d290000211b2008200d41086a2900003703002003201b3703800a200d1035200120032903800a370000200141086a22102008290300370000200341e0086a41086a22112009290300370300200341e0086a41106a22122001290300370300200341e0086a41186a2213200c29030037030020032003290388093703e008200341e8036a200341e0086a412010d701200341e8036a41106a290300211b20032903f003212920032802e803210d200c42003703002001420037030020094200370300200342003703880920051001220e29000021052008200e41086a290000370300200320053703800a200e103520092008290300370300200320032903800a37038809201a1001220e29000021052008200e41086a290000370300200320053703800a200e1035200120032903800a3700002010200829030037000020112009290300370300201220012903003703002013200c29030037030020032003290388093703e0082003427f201b4200200d1b220520077c20294200200d1b220720047c22042007542208ad7c22072008200720055420072005511b22081b3703880a2003427f200420081b3703800a0c010b20054201520d0120034188096a41186a220c42003703002001420037030020034188096a41086a22094200370300200342003703880941b6fdc600ad428080808080018422051001220d290000211a200341800a6a41086a2208200d41086a2900003703002003201a3703800a200d103520092008290300370300200320032903800a3703880941e489c200ad4280808080d00184221a1001220d290000211b2008200d41086a2900003703002003201b3703800a200d1035200120032903800a370000200141086a22102008290300370000200341e0086a41086a22112009290300370300200341e0086a41106a22122001290300370300200341e0086a41186a2213200c29030037030020032003290388093703e00820034180046a200341e0086a412010d70120034180046a41106a290300211b2003290388042129200328028004210d200c42003703002001420037030020094200370300200342003703880920051001220e29000021052008200e41086a290000370300200320053703800a200e103520092008290300370300200320032903800a37038809201a1001220e29000021052008200e41086a290000370300200320053703800a200e1035200120032903800a3700002010200829030037000020112009290300370300201220012903003703002013200c29030037030020032003290388093703e0082003427f201b4200200d1b220520077c20294200200d1b220720047c22042007542208ad7c22072008200720055420072005511b22081b3703880a2003427f200420081b3703800a0b202c202a10020b200241306a2102200a41206a200f470d000b0b201710b10102402015450d00201541306c450d00201610350b02402003280294072202450d00200241186c450d0020032802900710350b024020032802a00741ffffffff0371450d00200328029c0710350b420021070c030b02402003280294072201450d00200141186c450d0020032802900710350b41e7a4c0002101410e210841808038210920032802a00741ffffffff0371450d00200328029c0710350b4200210720024104460d010b200041206a20083602002000411c6a2001360200200041186a2009418080fc007120027241801072360200420121070b200042003703080c1a0b4102210802400240024002400240024002400240024002400240024020022d00000d0020022d00014101470d00200141046a28020021082002411a6a2901002107200241196a2d00002109200241186a2d0000210a200241166a2f0100210b200241156a2d0000210c200241146a2d0000210d200241126a2f0100210e200241116a2d0000210f200241106a2d000021102002410e6a2f010021112002410d6a2d000021122002410c6a2d000021132002410a6a2f01002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f010021012003200241096a2d00003a00d70b200320153a00d60b200320163b01d40b200320173a00d30b200320183a00d20b200320013a00d00b200320014108763a00d10b2003200f3a00df0b200320103a00de0b200320113b01dc0b200320123a00db0b200320133a00da0b200320143b01d80b200320093a00e70b2003200a3a00e60b2003200b3b01e40b2003200c3a00e30b2003200d3a00e20b2003200e3b01e00b200320073701e80b200341e8096a2007370300200341e0096a20032901e00b370300200341d0096a41086a20032901d80b370300200320032901d00b3703d00941f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21092002103541eeeecb00ad4280808080a001841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320013601b008200341e0036a200341b0086a412010c00141a1a5c0002102411221094180802c210120032802e003450d0420032802e40320084d0d0441f7edcb00ad4280808080f000841001220a280000210b200a2900042107200a28000c210c200a103541e4edcb00ad4280808080a001841001220a2900002104200a2900082105200a1035200320053701c808200320043701c0082003200c3601bc08200320073701b4082003200b3601b008200341d8036a200341b0086a412010c00120032802d803450d0420032802dc03220b2008490d0441f7edcb00ad4280808080f000841001220a280000210c200a2900042107200a28000c210d200a103541b5edcb00ad4280808080c001841001220a2900002104200a2900082105200a1035200320053701c808200320043701c0082003200d3601bc08200320073701b4082003200c3601b008200341d0036a200341b0086a412010c0014100200b20032802d40341d40020032802d0031b6b220a200a200b4b1b220a20084b0d04200341800a6a200810be01200341b8036a20032802800a220c20032802880a10d701200341c8036a290300210420032903c003210720032802b803210b024020032802840a450d00200c10350b200b450d04200341e0086a200341d0096a10b701200341800a6a20032802e008220220032802e80810d601200341b0086a41086a2201200341bc0a6a290200370300200341b0086a41106a2209200341c40a6a290200370300200341b0086a41186a220b200341cc0a6a290200370300200341b0086a41206a220c200341d40a6a2802003602002003200341b40a6a2902003703b0080240024020032802a00a220d450d00200341800a6a41186a2903002105200341800a6a41086a290300211a200341b00a6a280200210e200341ac0a6a280200210f200341a80a6a280200211020032903900a211b20032903800a211c20032802a40a211120034188096a41206a200c28020036020020034188096a41186a200b29030037030020034188096a41106a200929030037030020034188096a41086a2001290300370300200320032903b00837038809024020032802e408450d00200210350b200341f0066a41186a2005370300200341a0076a200e36020020034198076a201036020020034194076a2011360200200341a4076a200329038809370200200341ac076a20034190096a290300370200200341b4076a20034198096a290300370200200341bc076a20034188096a41186a290300370200200341c4076a200341a8096a2802003602002003201b370380072003201c3703f0062003200f36029c072003200d360290072003201a3703f80641f7edcb00ad4280808080f0008410012202280000210120022900042105200228000c21092002103541b6aac000ad428080808090028410012202290000211a2002290008211b200210352003201b3701c8082003201a3701c008200320093601bc08200320053701b408200320013601b008200341b0036a200341b0086a10f20120032802b003417d71450d01200341800a6a200341a8076a108c0220032802800a220220032802880a10970241ff01712109024020032802840a450d00200210350b200941034b0d0141dca2c0002102418080ec00210120090e0405010105050b024020032802e408450d00200210350b41b6a6c0002102410d210941002101410321080c080b200328029c072102024020032802a407220b0d0041002101410021090c070b41002101410021090340024002400240200a2002280200220c4b0d0020010d01410021010c020b200141016a21010c010b200920016b220d200b4f0d03200220014102746b220d280200210e200d200c3602002002200e3602000b200241046a2102200b200941016a2209470d000b024002402001450d0020032802a407220c200b20016b2202490d01200320023602a4072002210c0c010b20032802a407210c0b200328029c072102410021010240200c41014b0d0041002109200c0e020703070b200c2109034020012009410176220a20016a220b20082002200b4102746a280200491b21012009200a6b220941014b0d000c030b0b410021010c060b200d200b41f485cc001042000b2008200220014102746a2802002209470d0241e7a4c00021024180803821010b02402003280294072208450d00200841186c450d0020032802900710350b024020032802a00741ffffffff0371450d00200328029c0710350b410e21090b410321080c020b200c2001200820094b6a2201490d02200c21090b0240200920032802a007470d002003419c076a20094101108601200328029c0721020b200220014102746a220241046a2002200920016b410274109e081a200220083602002003200941016a3602a407200341800a6a200341d0096a10b70120032802800a2102200320032802880a3602b408200320023602b008200341f0066a200341b0086a10e101024020032802840a450d00200210350b200341b0086a2008109402200341800a6a2008200341a8076a220a10d301200341a8036a20032802800a220220032802880a10d20120032802a803210f20032802ac032110024020032802840a450d00200210350b20034188096a2008200a10d101200341800a6a20032802880922022003280290091085020240024020032802a00a22120d0042002105410821124100210e4200211a4200211b4200211c0c010b200341880a6a290300211a200341980a6a290300211c20032903800a210520032903900a211b20032802a40a210e0b0240200328028c09450d00200210350b201b201c2005201a10950221110240024020032802b408220b0d00410021010c010b200341b0086a41086a280200210c0340200b41086a2101200b2f0106220d4105742102410021080240024003402002450d01200a2001412010a0082209450d02200241606a2102200841016a2108200141206a21012009417f4a0d000b2008417f6a210d0b0240200c0d00410021010c030b200c417f6a210c200b200d4102746a4194036a280200210b0c010b0b200b20084102746a41e8026a28020021010b20032802b00822024101200241014b1b2202418094ebdc036e220820022008418094ebdc036c476a22084101200841014b1b220820024b0d0220034180036a20072004428094ebdc034200109808200341f0026a200329038003220420034180036a41086a29030022054280ec94a37c427f1084082003418094ebdc033602840a20032011ad4100418094ebdc0320104100200f1b22096b220b200b418094ebdc034b1bad7e428094ebdc0380a7220b3602800a200341800a6a200b418094ebdc034b4102746a280200210b2003418094ebdc033602840a2003417f2009200b6a220b200b2009491b22093602800a200341800a6a2009418094ebdc034b4102746a350200211a2003418094ebdc033602840a2003201a2002200120022001491b20086ead428094ebdc037e200220086ead8042ffffffff0f837e428094ebdc0380a722023602800a200341e0026a20042005200341800a6a2002418094ebdc034b4102746a350200221a420010840820034190036a200a20032903e0022204201a200720032903f0027c7e2207428094ebdc03802205a7417f2007428080808080c0b2cd3b541b200720054280ec94a37c7e7c4280cab5ee01566aad7c2207200341e0026a41086a2903002007200454ad7c10960220034190036a41106a2903002107200329039803210402402003290390032205a74101470d0020032903d009210520032903d809211a20032903e009211b20032903e809211c200341b80a6a2007370300200341b00a6a2004370300200341a10a6a201c370000200341990a6a201b370000200341910a6a201a370000200341890a6a2005370000200341800a6a41086a220241013a0000200341043a00800a41b0b4cc004100200341800a6a10d40120034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a2002200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e008200341b0026a200341e0086a412010d701200341b0026a41106a290300211b20032903b802211c20032802b0022109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c201c420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020c040b20054201520d0320034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a200341800a6a41086a2202200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e008200341c8026a200341e0086a412010d701200341c8026a41106a290300211b20032903d002211c20032802c8022109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c201c420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020c030b200041206a20093602002000411c6a2002360200200041186a2001418080fc007120087241801072360200420121070c030b2001200c104d000b4190edc40041194180efc400103f000b200341b0086a41047221020240200e450d00200e41306c450d00201210350b200210b10102402003280294072202450d00200241186c450d0020032802900710350b024020032802a00741ffffffff0371450d00200328029c0710350b420021070b200042003703080c190b2001410c6a2802002108200141086a280200210b41022109024002400240024002400240024002400240024002400240024020022d00000d0020022d00014101470d00200141106a280200210c200141046a28020021092002411a6a2901002107200241196a2d0000210a200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021132002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241086a2d00002118200241066a2f01002119200241056a2d00002106200241046a2d0000211d200241026a2f010021012003200241096a2d00003a00d70b200320183a00d60b200320193b01d40b200320063a00d30b2003201d3a00d20b200320013a00d00b200320014108763a00d10b200320123a00df0b200320133a00de0b200320143b01dc0b200320153a00db0b200320163a00da0b200320173b01d80b2003200a3a00e70b2003200d3a00e60b2003200e3b01e40b2003200f3a00e30b200320103a00e20b200320113b01e00b200320073701e80b200341880c6a2007370300200341f00b6a41106a20032901e00b370300200341f00b6a41086a20032901d80b370300200320032901d00b3703f00b0240200c41104d0d004187a5c0002102411a210a410c21010c0b0b41f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c210a2002103541eeeecb00ad4280808080a001841001220229000021042002290008210520021035200320053701c808200320043701c0082003200a3601bc08200320073701b408200320013601b008200341a8026a200341b0086a412010c00141a1a5c00021024112210a410b210120032802a802450d0a200920032802ac024f0d0a41f7edcb00ad4280808080f000841001220d280000210e200d2900042107200d28000c210f200d103541e4edcb00ad4280808080a001841001220d2900002104200d2900082105200d1035200320053701c808200320043701c0082003200f3601bc08200320073701b4082003200e3601b008200341a0026a200341b0086a412010c00120032802a002450d0a200920032802a402220e4b0d0a41f7edcb00ad4280808080f000841001220d280000210f200d2900042107200d28000c2110200d103541b5edcb00ad4280808080c001841001220d2900002104200d2900082105200d1035200320053701c808200320043701c008200320103601bc08200320073701b4082003200f3601b00820034198026a200341b0086a412010c00120094100200e200328029c0241d4002003280298021b6b220d200d200e4b1b220d490d0a200341800a6a200910be0120034180026a20032802800a220f20032802880a10d70120034190026a290300211a2003290388022105200328028002210e024020032802840a450d00200f10350b200e450d0a200341d0096a200341f00b6a10b701200341800a6a20032802d009220220032802d80910d601200341b0086a41086a2201200341bc0a6a290200370300200341b0086a41106a220a200341c40a6a290200370300200341b0086a41186a220e200341cc0a6a290200370300200341b0086a41206a220f200341d40a6a2802003602002003200341b40a6a2902003703b0080240024020032802a00a2210450d00200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a2802002111200341ac0a6a2802002112200341a80a6a280200211320032903900a211b20032903800a211c20032802a40a211420034188096a41206a200f28020036020020034188096a41186a200e29030037030020034188096a41106a200a29030037030020034188096a41086a2001290300370300200320032903b00837038809024020032802d409450d00200210350b200341f0066a41186a2007370300200341a0076a201136020020034198076a201336020020034194076a2014360200200341a4076a200329038809370200200341ac076a20034190096a290300370200200341b4076a20034198096a290300370200200341bc076a20034188096a41186a290300370200200341c4076a200341a8096a2802003602002003201b370380072003201c3703f0062003201236029c072003201036029007200320043703f80641f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c210a2002103541b6aac000ad42808080809002841001220229000021042002290008211b200210352003201b3701c808200320043701c0082003200a3601bc08200320073701b408200320013601b008200341f8016a200341b0086a10f20120032802f801417d71450d01200341800a6a200341a8076a108c0220032802800a220220032802880a10970241ff0171210a024020032802840a450d00200210350b200a41034b0d0141dca2c0002102411b2101200a0e0406010106060b024020032802d409450d00200210350b41b6a6c0002102410d210a410021010c0b0b200328029c072102024020032802a407220e0d00410021014100210a0c070b410021014100210a0340024002400240200d2002280200220f4b0d0020010d01410021010c020b200141016a21010c010b200a20016b2210200e4f0d03200220014102746b221028020021112010200f360200200220113602000b200241046a2102200e200a41016a220a470d000b024002402001450d0020032802a407220f200e20016b2202490d01200320023602a4072002210f0c010b20032802a407210f0b200328029c072102410021010240200f41014b0d004100210a200f0e020704070b200f210a03402001200a410176220d20016a220e20092002200e4102746a280200491b2101200a200d6b220a41014b0d000c040b0b2008450d01200841246c450d01200b10350c0a0b2010200e41f485cc001042000b0c080b2009200220014102746a280200220a470d0141e7a4c0002102410e21010b02402003280294072209450d00200941186c450d0020032802900710350b024020032802a00741ffffffff0371450d00200328029c0710350b410e210a0c050b200f20012009200a4b6a2201490d01200f210a0b0240200a20032802a007470d002003419c076a200a4101108601200328029c0721020b200220014102746a220241046a2002200a20016b410274109e081a200220093602002003200a41016a3602a407200341800a6a200341f00b6a10b70120032802800a2102200320032802880a3602d409200320023602d009200341f0066a200341d0096a10e101024020032802840a450d00200210350b200341b0086a20091094020240200c41246c22020d00410021150c030b200b20026a2213415c6a2118200341a8076a2110200b2101410021150340200121020340200241206a2802002101200341d0096a41186a200241186a290000370300200341d0096a41106a200241106a290000370300200341d0096a41086a200241086a290000370300200320022900003703d009200341800a6a2009200341d0096a10d301200341f0016a20032802800a220a20032802880a10d20120032802f001211120032802f4012112024020032802840a450d00200a10350b20034188096a2009200341d0096a10d101200341800a6a200328028809220e2003280290091085020240024020032802a00a220c0d00420021074100210d4108210c4100210a420021040c010b200341800a6a41086a290300210420032903800a210720032802a40a210d20032802a80a210a0b0240200328028c09450d00200e10350b02400240200a20014d0d00200c200141306c6a2201450d0002402010200141106a220a460d00200a2010412010a0080d020b2001290300200141086a2903002007200410950221190240024020032802b40822140d004100210a0c010b20032802b80821160340201441086a210a20142f0106221741057421014100210e0240024003402001450d01200341d0096a200a412010a008220f450d02200141606a2101200e41016a210e200a41206a210a200f417f4a0d000b200e417f6a21170b024020160d004100210a0c030b2016417f6a2116201420174102746a4194036a28020021140c010b0b2014200e4102746a41e8026a280200210a0b20032802b00822014101200141014b1b2201418094ebdc036e220e2001200e418094ebdc036c476a220e4101200e41014b1b220e20014b0d052003418094ebdc033602840a20032001200a2001200a491b200e6ead428094ebdc037e2001200e6ead8042ffffffff0f834100418094ebdc032012410020111b6b22012001418094ebdc034b1bad7e428094ebdc0380a722013602800a200341800a6a2001418094ebdc034b4102746a35020021072003418094ebdc033602840a200320072019ad7e428094ebdc0380a722013602800a200341800a6a2001418094ebdc034b4102746a28020021012003418094ebdc033602840a2003417f201520016a220120012015491b22013602800a200341800a6a2001418094ebdc034b4102746a28020021150b0240200d450d00200d41306c450d00200c10350b200241246a210120182002460d050c020b200241246a21020240200d450d00200d41306c450d00200c10350b20132002460d040c000b0b0b2001200f104d000b4190edc40041194180efc400103f000b02402008450d00200841246c450d00200b10350b200341c8016a2005201a428094ebdc034200109808200341b8016a20032903c8012207200341c8016a41086a29030022044280ec94a37c427f108408200341a8016a200720042015ad221a4200108408200341d8016a200341f0066a41386a20032903a8012204201a200520032903b8017c7e2207428094ebdc03802205a7417f2007428080808080c0b2cd3b541b200720054280ec94a37c7e7c4280cab5ee01566aad7c2207200341a8016a41086a2903002007200454ad7c109602200341d8016a41106a290300210720032903e00121040240024020032903d8012205a74101470d0020032903f00b210520032903f80b211a20032903800c211b20032903880c211c200341800a6a41386a2007370300200341b00a6a2004370300200341a10a6a201c370000200341990a6a201b370000200341910a6a201a370000200341890a6a2005370000200341800a6a41086a220241013a0000200341043a00800a41b0b4cc004100200341800a6a10d40120034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a2002200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e008200341f8006a200341e0086a412010d701200341f8006a41106a290300211b200329038001211c20032802782109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c201c420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020c010b20054201520d0020034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a200341800a6a41086a2202200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e00820034190016a200341e0086a412010d70120034190016a41106a290300211b200329039801211c2003280290012109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c201c420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020b200341b0086a41047210b10102402003280294072202450d00200241186c450d0020032802900710350b024020032802a00741ffffffff0371450d00200328029c0710350b420021070c020b02402008450d00200841246c450d00200b10350b410321090b200041206a200a3602002000411c6a2002360200200041186a200141ff017141107420097241801072360200420121070b200042003703080c180b4102210a200241036a2d0000210820022f00012109200141106a280200210b2001410c6a2802002113200141086a2802002112200141046a280200211402400240024020022d0000220c417f6a220141024b0d00024020010e03000102000b200241046a2d00000d00200241086a2802004102742002410c6a28020041036c4f0d010b2009200841107472200c4100477241ff0171450d0041801021020c010b4103210a0240200b0d004188a6c0002108410c21014180901021020c010b200b41016a210120122102024003402001417f6a22014102490d01200241046a210820022802002109200241046a210220092008280200490d000b41f5a4c0002108411221014180903421020c010b200341800a6a201410dc01200341f0066a20032802800a220120032802880a10dd0120032902f406420020032802f00622021b2107024020032802840a450d00200110350b2002410820021b211102400240200b410274220b20126a417c6a2802002007422088a722024f0d0041002101417f210820122109034020012009280200220c6a22022007422088a7220d4f0d022011200241d8006c6a220228022c210f20022802202110200241306a280200210e200241246a280200210a2002200241d8006a2008200d6a200c6b41d8006c109e081a0240200a450d00200a41306c450d00201010350b0240200e41ffffff3f71450d00200f10350b200941046a210920074280808080707c2107200841016a21082001417f6a2101200b417c6a220b0d000b0240201341ffffffff0371450d00201210350b200341f0066a201410dc0120032802f006210220033502f8062104200341800a6a20112007422088a7220110ea0120044220862002ad8420033502880a42208620032802800a2208ad841002024020032802840a450d00200810350b024020032802f406450d00200210350b02402001450d00201141306a21022007422088a741d8006c210103400240200241746a2802002208450d00200841306c450d00200241706a28020010350b0240200228020041ffffff3f71450d002002417c6a28020010350b200241d8006a2102200141a87f6a22010d000b0b2007a72202450d17200241d8006c450d17201110350c170b02402002450d00200241d8006c2101201141306a210203400240200241746a2802002208450d00200841306c450d00200241706a28020010350b0240200228020041ffffff3f71450d002002417c6a28020010350b200241d8006a2102200141a87f6a22010d000b0b41e9a5c0002108411121014180901821022007a72209450d01200941d8006c450d01201110350c010b2002200d104e000b0240201341ffffffff0371450d00201210350b20004200370308200041206a20013602002000411c6a2008360200200041186a2002200a723602000c160b024020022d000120022d0000410047720d0041f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c2108200210354193eecb00ad42808080808001841001220229000021042002290008210520021035200320053701c808200320043701c008200320083601bc08200320073701b408200320013601b008200341033a00f00b410110332202450d12200220032d00f00b3a0000200341b0086aad42808080808004842002ad428080808010841002200210350c140b20004200370308200041186a41023602000c150b200341980a6a200141196a290000370300200341800a6a41106a200141116a290000370300200341880a6a200141096a290000370300200320012900013703800a4100210102400240024020022d000120022d0000410047720d00200341f0066a200341800a6a10910220032d00f00622024104460d0220032902f406210720032f00f10620032d00f3064110747241087421010c010b410221020b200042003703082000411c6a2007370200200041186a20012002723602000c150b200342f3e885db96cddbb3203703d009200341d0096a200341800a6a1092020c120b200141086a2802002108200141046a2802002109024020022d000120022d0000410047720d002001410c6a280200210141f7edcb00ad4280808080f0008410012202280000210a20022900042107200228000c210b200210354194c4c100ad4280808080d001841001220229000021042002290008210520021035200320053701c808200320043701c0082003200b3601bc08200320073701b4082003200a3601b008200341203602840a2003200341b0086a3602800a20092001200341800a6a109802200841ffffff3f71450d12200910350c120b0240200841ffffff3f71450d00200910350b20004200370308200041186a41023602000c130b024020022d000120022d0000410047720d0041f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c2108200210354193eecb00ad42808080808001841001220229000021042002290008210520021035200320053701c808200320043701c008200320083601bc08200320073701b408200320013601b008200341013a00f00b410110332202450d0f200220032d00f00b3a0000200341b0086aad42808080808004842002ad428080808010841002200210350c110b20004200370308200041186a41023602000c120b024020022d000120022d0000410047720d0041f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c2108200210354193eecb00ad42808080808001841001220229000021042002290008210520021035200320053701c808200320043701c008200320083601bc08200320073701b408200320013601b008200341023a00f00b410110332202450d0e200220032d00f00b3a0000200341b0086aad42808080808004842002ad428080808010841002200210350c100b20004200370308200041186a41023602000c110b024020022d000120022d000041004772450d0020004200370308200041186a41023602000c110b200141046a280200210141f7edcb00ad4280808080f0008410012202280000210820022900042107200228000c21092002103541c1edcb00ad4280808080e001841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320083601b008200320013602800a200341b0086aad4280808080800484200341800a6aad4280808080c0008410020c0e0b200341a8096a200141246a28020036020020034188096a41186a2001411c6a29020037030020034188096a41106a200141146a29020037030020034188096a41086a2001410c6a2902003703002003200141046a290200370388092002411a6a2901002107200241196a2d00002109200241186a2d0000210a200241166a2f0100210b200241156a2d0000210c200241146a2d0000210d200241126a2f0100210e200241116a2d0000210f200241106a2d000021102002410e6a2f010021112002410d6a2d000021122002410c6a2d000021132002410a6a2f01002114200241096a2d00002115200241086a2d00002116200241066a2f01002117200241056a2d00002118200241046a2d0000211941022101200241026a2f0100210641012108024020022d00000d0020022d000141014721080b200320073701c808200320093a00c7082003200a3a00c6082003200b3b01c4082003200c3a00c3082003200d3a00c2082003200e3b01c0082003200f3a00bf08200320103a00be08200320113b01bc08200320123a00bb08200320133a00ba08200320143b01b808200320153a00b708200320163a00b608200320173b01b408200320183a00b308200320193a00b208200320063b01b0080240024002402008450d0041801021080c010b200341d00b6a41186a200341b0086a41186a290100370300200341d00b6a41106a200341b0086a41106a290100370300200341d00b6a41086a200341b0086a41086a290100370300200320032901b0083703d00b200341f0066a200341d00b6a10b401200341800a6a20032802f006220120032802f80610d50120032802f4062102024020032d00800a4101470d00200341990a6a2900002107200341800a6a41186a2d00002108200341970a6a2d00002109200341950a6a2f0000210a200341940a6a2d0000210b200341930a6a2d0000210c200341910a6a2f0000210d200341800a6a41106a2d0000210e2003418f0a6a2d0000210f2003418d0a6a2f000021102003418c0a6a2d000021112003418b0a6a2d00002112200341890a6a2f00002113200341800a6a41086a2d0000211420032d00870a211520032f00850a211620032d00840a211720032d00830a211820032d00820a211920032d00810a210602402002450d00200110350b200320073703880c200320083a00870c200320093a00860c2003200a3b01840c2003200b3a00830c2003200c3a00820c2003200d3b01800c2003200e3a00ff0b2003200f3a00fe0b200320103b01fc0b200320113a00fb0b200320123a00fa0b200320133b01f80b200320143a00f70b200320153a00f60b200320163b01f40b200320173a00f30b200320183a00f20b200320193a00f10b200320063a00f00b200341800a6a41206a20034188096a41206a280200360200200341800a6a41186a20034188096a41186a290300370300200341800a6a41106a20034188096a41106a290300370300200341800a6a41086a20034188096a41086a29030037030020032003290388093703800a200341f0066a200341800a6a108b0241012101410d2102024020032d00f0064101460d00200341f0066a41086a2d00002101200341f9066a2f00002108200341fb066a2d00002109200341fc066a2d0000210a200341f0066a410d6a2f0000210b200341ff066a2d0000210c200341f0066a41106a2d0000210d20034181076a2f0000210e20034183076a2d0000210f20034184076a2d0000211020034185076a2f0000211120034187076a2d00002112200341f0066a41186a2d0000211320032d00f106211420032d00f206211520032d00f306211620032d00f406211720032f00f506211820032d00f7062119200320034189076a2900003703f808200320133a00f708200320123a00f608200320113b01f408200320103a00f3082003200f3a00f2082003200e3b01f0082003200d3a00ef082003200c3a00ee082003200b3b01ec082003200a3a00eb08200320093a00ea08200320083b01e808200320013a00e708200320193a00e608200320183b01e408200320173a00e308200320163a00e208200320153a00e108200320143a00e008200341800a6a200341e0086a10b701200341f0006a20032802800a220120032802880a41b0b4cc0041004100108a0220032802702108024020032802840a450d00200110350b4103210120084101470d030b4194a6c00021094180900c21080c010b02402002450d00200110350b41aea6c000210941082102410321014180900421080b200041206a20023602002000411c6a2009360200200041186a2008200172360200200042003703080c100b200341e0086a200341f00b6a412010a008450d0d200341800a6a200341d00b6a10b40120033502880a210720032802800a2101412010332202450d00200220032903e008370000200241186a200341e0086a41186a290300370000200241106a200341e0086a41106a290300370000200241086a200341e0086a41086a29030037000020074220862001ad842002ad4280808080800484100220021035024020032802840a450d00200110350b200341b0096a200341f00b6a10b701200341800a6a20032802b009220120032802b809220810d601024020032802a00a2202450d002008ad4220862001ad8410070b200341f0066a41086a2208200341bc0a6a290200370300200341f0066a41106a2209200341c40a6a290200370300200341f0066a41186a220a200341cc0a6a290200370300200341f0066a41206a220b200341d40a6a2802003602002003200341b40a6a2902003703f006200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a280200210c200341ac0a6a280200210d200341a80a6a280200210e20032903900a210520032903800a211a20032802a40a210f200341b0086a41206a2210200b280200360200200341b0086a41186a220b200a290300370300200341b0086a41106a220a2009290300370300200341b0086a41086a22092008290300370300200320032903f0063703b00802402002450d00200341d0096a41206a2010280200360200200341d0096a41186a200b290300370300200341d0096a41106a200a290300370300200341d0096a41086a2009290300370300200320032903b0083703d009024020032802b409450d00200110350b200341800a6a41186a2007370300200341b00a6a200c360200200341a80a6a200e360200200341a40a6a200f360200200341b40a6a20032903d009370200200341bc0a6a200341d0096a41086a290300370200200341c40a6a200341d0096a41106a290300370200200341cc0a6a200341d0096a41186a290300370200200341d40a6a200341d0096a41206a280200360200200320053703900a200320043703880a2003201a3703800a2003200d3602ac0a200320023602a00a200341b0086a200341e0086a10b70120033502b808210720032802b008210b200341003602f806200342013703f006412010332202450d0c200220032903b80a370000200241086a200341c00a6a290300370000200241106a200341c80a6a290300370000200241186a200341d00a6a290300370000200320023602f006200342a080808080043702f4062003200341800a6a3602b009200341b0096a200341f0066a10cf012003200341800a6a41106a3602b009200341b0096a200341f0066a10cf0120032802a00a210220032802a80a2201200341f0066a107702402001450d002002200141186c6a21010340200320023602b009200341b0096a200341f0066a10cf01200241106a200341f0066a10e2012001200241186a2202470d000b0b20032802ac0a210c20032802b40a2202200341f0066a10770240024020032802f406220a20032802f80622016b20024102742208490d0020032802f0062102200a21090c010b200120086a22022001490d0c200a41017422092002200920024b1b22094100480d0c02400240200a0d00024020090d00410121020c020b200910332202450d0f0c010b20032802f0062102200a2009460d002002200a200910372202450d0e0b200320093602f406200320023602f0060b200220016a200c2008109d081a2007422086200bad84200120086aad4220862002ad84100202402009450d00200210350b024020032802b408450d00200b10350b024020032802a40a2202450d00200241186c450d0020032802a00a10350b20032802b00a41ffffffff0371450d0e20032802ac0a10350c0e0b20032802b409450d0d200110350c0d0b1045000b4182102108024020022d00000d0020022d00014101470d0020012d00012119200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100210120032002411a6a2901003703e809200320083a00e709200320093a00e6092003200a3b01e4092003200b3a00e3092003200c3a00e2092003200d3b01e0092003200e3a00df092003200f3a00de09200320103b01dc09200320113a00db09200320123a00da09200320133b01d809200320143a00d709200320153a00d609200320163b01d409200320173a00d309200320183a00d209200320013a00d009200320014108763a00d109200341f00b6a200341d0096a10b701200341800a6a20032802f00b220120032802f80b10d601200341b0086a41086a220b200341bc0a6a290200370300200341b0086a41106a220c200341c40a6a290200370300200341b0086a41186a220d200341cc0a6a290200370300200341b0086a41206a220e200341d40a6a2802003602002003200341b40a6a2902003703b008024020032802a00a2208450d00200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a2802002109200341ac0a6a280200210a200341a80a6a280200210f20032903900a210520032903800a211a20032802a40a210220034188096a41206a200e28020036020020034188096a41186a200d29030037030020034188096a41106a200c29030037030020034188096a41086a200b290300370300200320032903b00837038809024020032802f40b450d00200110350b200341e0086a41086a220120034188096a41086a290300370300200341e0086a41106a220b20034188096a41106a290300370300200341e0086a41186a220c20034188096a41186a290300370300200341e0086a41206a220d20034188096a41206a280200360200200341f0066a41186a2007370300200341a0076a200936020020034198076a200f36020020034194076a200236020020032003290388093703e00820032005370380072003201a3703f0062003200a36029c072003200836029007200320043703f806200341c4076a200d280200360200200341bc076a200c290300370200200341b4076a200b290300370200200341ac076a2001290300370200200341a4076a20032903e008370200200341800a6a200341a8076a108c0220033502880a210720032802800a210b02400240201941037122014103470d0041012101420021044101210c0c010b024002400240024020010e03000102000b4100210c0c020b4101210c0c010b4102210c0b2003200c3a00f00b410110332201450d0c2001200c3a00004100210c42808080801021040b2007422086200bad8420042001ad8410020240200c0d00200110350b024020032802840a450d00200b10350b02402002450d00200241186c450d00200810350b200941ffffffff0371450d0d200a10350c0d0b024020032802f40b450d00200110350b41831021080b20004200370308200041206a410d3602002000411c6a41b6a6c000360200200041186a20083602000c0d0b2002411a6a290100211a200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113410e21012002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d00002118200241086a2d00002119200241066a2f01002106200241056a2d0000211d200241046a2d0000211e200241026a2f0100211f20022d0001210b20022d0000210a41f7edcb00ad4280808080f0008410012202280000210820022900042107200228000c21092002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320083601b008200341e8006a200341b0086a10f20141032102024002402003280268417d71450d0041dca2c0002108418090ec0021090c010b0240200a41ff01710d00200b41ff01714101470d002003201a3703e8092003200c3a00e7092003200d3a00e6092003200e3b01e4092003200f3a00e309200320103a00e209200320113b01e009200320123a00df09200320133a00de09200320143b01dc09200320153a00db09200320163a00da09200320173b01d809200320183a00d709200320193a00d609200320063b01d4092003201d3a00d3092003201e3a00d2092003201f3b01d009200341f00b6a200341d0096a10b701200341800a6a20032802f00b220a20032802f80b10d601200341b0086a41086a220b200341bc0a6a290200370300200341b0086a41106a220c200341c40a6a290200370300200341b0086a41186a220d200341cc0a6a290200370300200341b0086a41206a220e200341d40a6a2802003602002003200341b40a6a2902003703b008024020032802a00a2201450d00200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a2802002108200341ac0a6a2802002109200341a80a6a280200210f20032903900a210520032903800a211a20032802a40a210220034188096a41206a200e28020036020020034188096a41186a200d29030037030020034188096a41106a200c29030037030020034188096a41086a200b290300370300200320032903b00837038809024020032802f40b450d00200a10350b200341e0086a41086a220a20034188096a41086a290300370300200341e0086a41106a220b20034188096a41106a290300370300200341e0086a41186a220c20034188096a41186a290300370300200341e0086a41206a220d20034188096a41206a280200360200200341f0066a41186a2007370300200341a0076a200836020020034198076a200f36020020034194076a200236020020032003290388093703e00820032005370380072003201a3703f0062003200936029c072003200136029007200320043703f806200341c4076a200d280200360200200341bc076a200c290300370200200341b4076a200b290300370200200341ac076a200a290300370200200341a4076a20032903e008370200200341800a6a200341a8076a220a10b50120033502880a42208620032802800a220bad841007024020032802840a450d00200b10350b200341800a6a200a10b90120033502880a42208620032802800a220aad841007024020032802840a450d00200a10350b02402002450d00200241186c450d00200110350b200841ffffffff0371450d0d200910350c0d0b024020032802f40b450d00200a10350b41b6a6c0002108410d210141801021090c010b4102210241801021090b20004200370308200041206a20013602002000411c6a2008360200200041186a20092002723602000c0c0b410221020c010b02402001450d00200141186c450d00200910350b0240200a41ffffffff0371450d00201210350b4188a6c0002109410c21014104210a0b2008450d02200841246c450d02200b10350c020b02402008450d00200841246c450d00200b10350b20032802c40b41ffffff3f71210e0b02400240200c450d00200e450d01200f10350c010b200f0d020b02402001450d00200141186c450d00200910350b0240200a41ffffffff0371450d00201210350b410121020b20004200370308200041206a20013602002000411c6a2009360200200041186a200a41ff0171411074200272418010723602000c060b41f7edcb00ad4280808080f0008410012201280000210820012900042107200128000c21092001103541e4edcb00ad4280808080a001841001220129000021042001290008210520011035200320053701c808200320043701c008200320093601bc08200320073701b408200320083601b008200341d8006a200341b0086a412010c001200328025c211120032802582112200341800a6a200341a8076a220110b50120033502880a42208620032802800a2208ad841007024020032802840a450d00200810350b200341d0096a200110b90120033502d809210720032802d0092110200341003602880a200342013703800a2002200341800a6a10770240024020020d0020032802840a210920032802880a21010c010b2002410574210b410020032802880a22016b210a20032802800a210d20032802840a2109200f210c0340200c210202402009200a6a411f4b0d00200141206a22082001490d032009410174220c2008200c20084b1b22084100480d03024002400240024020090d00024020080d004101210d0c020b20081033210d0c030b20092008470d010b200821090c020b200d200920081037210d0b20082109200d450d040b200241206a210c200d20016a22082002290000370000200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200a41606a210a200141206a2101200b41606a220b0d000b200320093602840a200320013602880a2003200d3602800a0b02400240200920016b4104490d0020032802800a2108200921020c010b200141046a22022001490d01200941017422082002200820024b1b22024100480d010240024020090d00024020020d00410121080c020b200210332208450d040c010b20032802800a210820092002460d0020082009200210372208450d030b200320023602840a200320083602800a0b200820016a2011410020121b3600002003200141046a22013602880a41002109200341003a00f00b0240024020022001460d00200121020c010b200241016a22012002490d01200241017422092001200920014b1b22014100480d010240024020020d0041002102024020010d00410121080c020b200110332208450d040c010b20022001460d0020082002200110372208450d030b200320013602840a200320083602800a20032d00f00b21090b200820026a20093a000020032802840a210120074220862010ad84200241016aad42208620032802800a2202ad84100202402001450d00200210350b024020032802d409450d00201010350b0240200e450d00200f10350b02402003280294072202450d00200241186c450d0020032802900710350b20032802a00741ffffffff0371450d03200328029c0710350c030b103e000b103c000b20004200370308200041206a20013602002000411c6a2008360200200041186a2009418080fc0071200272418010723602000c020b42002107200042003703080c020b200041206a20083602002000411c6a200136020020004200370308200041186a20094180801c71200272418010723602000b420121070b20002007370300200341900c6a24000b9d0102017f017e230041106b2206240002402002ad4220862001ad842004ad4220862003ad842005102b2207422088a72204450d002007a722052d0000220341014b0d00410021010240024020030e020100010b2004417f6a4104490d0120052800012102410121010b200510352000200236020420002001360200200641106a24000f0b41b89acc00412e200641086a41c09bcc0041e89acc001046000b850501067f230041c0016b22022400200241ce006a2203200141036a2d00003a0000200241306a41086a2204200141106a290200370300200241306a41106a2205200141186a290200370300200241306a41186a2206200141206a280200360200200220012f00013b014c2002200141086a290200370330200141046a280200210702400240024020012d00004101470d0020024188016a2007109604200241d0006a200228028801220120022802900110cb0220024198016a41086a200241e7006a29000037030020024198016a41106a200241ef006a29000037030020024198016a41186a200241f7006a2d00003a0000200220022f01583b01b8012002200241da006a2d00003a00ba012002200229005f37039801024020022903504201520d00200241db006a2800002107200241086a41086a20024198016a41086a290300370300200241086a41106a20024198016a41106a290300370300200241086a41186a20024198016a41186a2d00003a0000200220022d00ba013a002a200220022f01b8013b01282002200229039801370308200228028c01450d02200110350c020b0240200228028c01450d00200110350b410121010c020b200241086a41086a2004290300370300200241086a41106a2005290300370300200241086a41186a20062d00003a0000200220022f014c3b012820022002290330370308200220032d00003a002a0b200041036a20022d002a3a0000200020022f01283b0001200041046a2007360000200041086a2002290308370000200041106a200241086a41086a290300370000200041186a200241086a41106a290300370000200041206a200241086a41186a2d00003a0000410021010b200020013a0000200241c0016a24000bb10503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a29000037030020022004370308200310354188c5c100ad4280808080d00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bce0203027f017e037f23004180026b22012400200141086a2000108e02200141e0006a2001280208220020012802102202108f0220012903602103200141b8016a200141e8006a41c400109d081a200141b4016a41026a2204200141af016a2d00003a0000200120012f00ad013b01b4010240024020034201510d0041002105200141186a410041c400109f081a0c010b20012d00ac012105200141186a200141b8016a41c400109d081a200141146a41026a20042d00003a0000200120012f01b4013b01140b200141e8006a200141186a41c400109d082104200141af016a200141166a2d00003a0000200142013703602001417f2005411874220541808080086a220620062005491b4118763a00ac01200120012f01143b00ad01200120023602bc01200120003602b8012004200141b8016a10e7020240200128020c450d00200010350b20014180026a24000bc20503027f017e047f230041d0006b2202240041d1c4c700ad4280808080e00084100122032900002104200241086a200341086a290000370300200220043703002003103541d7c4c700ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000baa0406027f017e017f037e017f037e230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822010d00200042003703000c010b200328020c2102024002400240200341106a28020022044104490d0020044104460d002004417b6a4110490d002004416b6a4110490d002004415b6a4110490d002004414b6a410f4b0d010b20034100360220200342013703182003410936022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341c888c2003602382003200341286a360248200341346a41e88ac500200341386a10431a200335022042208620033502188410060240200328021c450d00200328021810350b420021050c010b2001280000210420012d000421062001410d6a2900002105200129000521072001411d6a290000210820012900152109200341286a41026a220a200341386a41026a2d00003a0000200320032f00383b01282001412d6a290000210b2001290025210c2001290035210d200041c0006a2001413d6a290000370300200041386a200d370300200041306a200b370300200041286a200c370300200041206a2008370300200041186a2009370300200041106a200537030020002007370308200020063a004c200041c8006a2004360200200020032f01283b004d200041cf006a200a2d00003a0000420121050b200020053703002002450d00200110350b200341d0006a24000be80e03037f017e0d7f230022052106200541e0016b41607122052400024002402002200384500d00200441ff01712207450d002000290000210841002109024020074101460d004102410120044101711b21090b20052002370300200520093a00182005200837031020052003370308200541c0016a200110eb0220052802c001210a20052802c401210b02400240024020052802c801220c450d00200a200c41057422046a210d200441606a210e200541a0016a411072210f200541a0016a4119722110200a21040340200541e8006a41106a2211200441106a290300370300200541e8006a41086a2212200441086a29030037030020052004290300370368200441186a2d000021072005200441196a28000036023820052004411c6a28000036003b20074103460d0120102005280238360000201041036a200528003b360000200520112903003703b001200520122903003703a801200520052903683703a001200520073a00b80102400240200f2000460d00200f2900002000290000510d00200520052903b801220237039801200520052903b00137039001200520052903a80137038801200520052903a001370380010c010b200541033a00d80120052005290318220237039801200520052903103703900120052005290308370388012005200529030037038001200520052903d001370310200520052903c801370308200520052903c001370300200520052903d80122033703182003a721090b2002a7220741ff01714103470d02200e41606a210e200441206a2204200d470d000b0b200541003602a801200542083703a001200b41ffffff3f71450d01200a10350c010b200541d0006a41106a2210200529039001370300200541d0006a41086a22112005290388013703002005200528009c0136004320052005280099013602402005200529038001370350200520052802403602482005200528004336004b41201033220f450d02200f2005290350370300200f20073a0018200f2005280248360019200f411c6a200528004b360000200f41106a2010290300370300200f41086a2011290300370300200542818080801037022c2005200f3602280240200e450d00200441206a210e200c410574200a6a41606a211320054180016a4119722114200541a0016a4110722112200541a0016a41197221104101210c0340200e21040340200541e8006a41106a220e200441106a290300370300200541e8006a41086a2211200441086a29030037030020052004290300370368200441186a2d000021072005200441196a28000036023820052004411c6a28000036003b20074103460d0220102005280238360000201041036a200528003b3600002005200e2903003703b001200520112903003703a801200520052903683703a001200520073a00b8010240024020122000460d0020122900002000290000510d00200520052903b801220237039801200520052903b00137039001200520052903a80137038801200520052903a001370380010c010b200541033a00d80120052005290318220237039801200520052903103703900120052005290308370388012005200529030037038001200520052903d001370310200520052903c801370308200520052903c001370300200520052903d80122033703182003a721090b02402002a7220741ff01714103470d00200441206a2204200d470d010c030b0b200541d0006a41106a220e200529039001370300200541d0006a41086a2211200529038801370300200520142800003602402005201441036a2800003600432005200529038001370350200520052802403602482005200528004336004b200541c0016a41086a22152011290300370300200541c0016a41106a2211200e290300370300200520052903503703c001200520052802483602a0012005200528004b3600a3010240200c200528022c470d00200541286a200c410110a1012005280228210f0b200441206a210e201529030021022011290300210320052903c0012108200f200c4105746a221120073a001820112008370300201120052802a0013600192011411c6a20052800a301360000201141106a2003370300201141086a20023703002005200c41016a220c36023020132004470d000b0b0240200b41ffffff3f71450d00200a10350b200541a0016a41086a200541286a41086a280200360200200520052903283703a0010b02400240200941ff01714103470d0020052802a801210420052802a0012107200541a0016a21050c010b200541c0016a41186a22102005290318370300200541c0016a41106a220e2005290310370300200541c0016a41086a22112005290308370300200520052903003703c001024020052802a801220420052802a401470d00200541a0016a2004410110a10120052802a80121040b20052802a001220720044105746a220020052903c001370300200041086a2011290300370300200041106a200e290300370300200041186a20102903003703002005200441016a22043602a801200541a0016a21050b20012007200410ec02200541046a28020041ffffff3f71450d00200528020010350b200624000f0b1045000bf90703057f027e037f230041a0016b22022400200241e8006a200110b401200241f8006a200228026822032002280270220410d501024020022d00782205450d002004ad4220862003ad8410070b200241086a41176a220420024191016a290000370000200241086a41106a22062002418a016a290100370300200241086a41086a20024182016a29010022073703002002200229017a220837030820022d00792109200241f8006a41176a220a2004290000370000200241f8006a41106a22042006290300370300200241f8006a41086a22062007370300200220083703780240024020054101470d00200241c8006a41176a200a290000370000200241c8006a41106a2004290300370300200241c8006a41086a2006290300370300200220022903783703480240200228026c450d00200310350b200241286a41176a2203200241c8006a41176a290000370000200241286a41106a2205200241c8006a41106a290300370300200241116a200241d0006a290300370000200241196a2005290300370000200241206a2003290000370000200220093a000820022002290348370009200241f8006a200241086a10b70120023502800142208620022802782203ad8410070240200228027c450d00200310350b200241f8006a2001108c0220023502800142208620022802782203ad8410070240200228027c450d00200310350b200241f8006a200110b50120023502800142208620022802782203ad8410070240200228027c450d00200310350b200241f8006a200110b90120023502800142208620022802782203ad8410070240200228027c450d00200310350b200241c8006a200110ba01200241f8006a200228024822032002280250220510bc010240200228028401220b450d002005ad4220862003ad8410070b2002290388012107200228027821090240200228024c450d00200310350b0240200b450d00200b2007422088a74102746a210a41002103200b21052009210602400340024002402003417e714102460d0041022103200921040c010b2005450d02200a2005460d02200541046a2105410321032006417f6a220621040b200241f8006a41186a200141186a290000370300200241f8006a41106a200141106a290000370300200241f8006a41086a200141086a290000370300200220043602980120022001290000370378200241c8006a200241f8006a10b601200235025042208620022802482204ad841007200228024c450d00200410350c000b0b200742ffffffff0383500d00200b10350b2001109902200041043a00000c010b0240200228026c450d00200310350b200041086a4108360200200041046a41aea6c000360200200041026a41013a000020004183103b01000b200241a0016a24000bac0304107f027e017f017e230041306b220224002002200110eb022002280200210302400240200228020822040d00410021040c010b200041706a210541002106200321074100210802400240034002400240024020052007460d00200741106a22092900002000290000510d0020060d01410021060c020b200641016a21060c010b200820066b220a20044f0d02200241106a41186a220b200720064105746b220a41186a220c290300370300200241106a41106a220d200a41106a220e290300370300200241106a41086a220f200a41086a22102903003703002002200a290300370310200741086a2211290300211220092903002113200741186a22142903002115200a2007290300370300200c2015370300200e2013370300201020123703002014200b2903003703002009200d2903003703002011200f290300370300200720022903103703000b200741206a21072004200841016a2208460d020c000b0b200a200441f485cc001042000b2006417f6a20044f0d002002200420066b22043602080b20012003200410ec020240200228020441ffffff3f71450d00200310350b200241306a24000bcb3e0a027f017e017f027e017f017e117f017e077f077e230041a0036b22052400200541e0006a41286a200341286a290300370300200541e0006a41206a200341206a290300370300200541e0006a41186a200341186a290300370300200541e0006a41106a200341106a290300370300200541e0006a41086a200341086a290300370300200520032903003703600240024002400240024002400240024002400240024002400240024002400240024002400240200541e0006a200410f101220441ff0171411d470d0020054180036a41086a22044200370300200542003703800341f7edcb00ad4280808080f0008410012206290000210720054190036a41086a2208200641086a290000370300200520073703900320061035200420082903003703002005200529039003370380034192aac000ad4280808080a002841001220629000021072006290008210920061035200541e0026a41086a2004290300370300200520093703f802200520073703f00220052005290380033703e002200541e0006a200541e0026aad4280808080800484220a100510c2010240024020052802602204450d00200528026421062005200541e8006a2802003602a402200520043602a002200541386a200541a0026a10c401024002402005280238450d004101210b41b0b4cc0021080c010b200528023c21084100210b0b02402006450d00200410350b41122104200b450d010c020b410021080b20054180036a41086a22064200370300200542003703800341f7edcb00ad4280808080f00084220c10012204290000210720054190036a41086a220b200441086a2900003703002005200737039003200410352006200b29030037030020052005290390033703800341c1edcb00ad4280808080e001841001220429000021072004290008210920041035200541e0026a41086a220d2006290300370300200520093703f802200520073703f00220052005290380033703e002200541306a200541e0026a412010c00141132104200041086a28020020082005280234410020052802301b220e200e20084b1b2208470d00200642003703002005420037038003200c100122042900002107200b200441086a2900003703002005200737039003200410352006200b2903003703002005200529039003370380034192aac000ad4280808080a002841001220429000021072004290008210920041035200d2006290300370300200520093703f802200520073703f00220052005290380033703e002200541e0006a200541e0026a10fe01024020052802602206450d00200520052902642207370244200520063602402000280200210f20002802042110024020080d00411d21040c050b411421042007422088a7200f2f010022004d0d04200541e8006a220b200620004105746a220441096a290000370300200541f0006a2200200441116a290000370300200541f7006a2206200441186a2900003700002005200429000137036020042d0000210441201033220e450d06200e20043a0000200e2005290360370001200e41096a200b290300370000200e41116a2000290300370000200e41186a200629000037000020054281808080103702e4022005200e3602e0024101210b411d210420084101460d032005280248200f2f010222004d0d02200541a0026a41086a2211200528024020004105746a220041096a290000370300200541a0026a41106a2212200041116a290000370300200541a0026a41176a2213200041186a290000370000200520002900013703a002200f41046a210d2008410174417c6a210820002d00002114412121064102210b410121000340200541e0006a41176a22152013290000370000200541e0006a41106a22162012290300370300200541e0006a41086a22172011290300370300200520052903a0023703600240200b417f6a2000470d00200541e0026a20004101108a0120052802e002210e0b200e20066a2200417f6a20143a000020002005290360370000200041086a2017290300370000200041106a2016290300370000200041176a20152900003700002005200b3602e8022008450d042005280248200d2f010022004d0d032011200528024020004105746a220041096a2900003703002012200041116a2900003703002013200041186a290000370000200520002900013703a0022008417e6a2108200d41026a210d200641206a2106200b41016a210b20002d0000211420052802e40221000c000b0b411221040b200110fa01200041046a28020041808080807872418080808078460d11200028020010350c110b411421040b0240201041808080807872418080808078460d00200f10350b20052802e40241ffffff3f7121110c010b410021114101210e0240201041808080807872418080808078460d00200f10350b4100210b0b02402004411d460d00410121032011450d0d0c0c0b20054180036a41086a22044200370300200542003703800341f7edcb00ad4280808080f0008410012200290000210720054190036a41086a2206200041086a2900003703002005200737039003200010352004200629030037030020052005290390033703800341a4aac000ad4280808080a002841001220029000021072000290008210920001035200541e0026a41086a2004290300370300200520093703f802200520073703f00220052005290380033703e002200541e0006a200541e0026a10fe0120052802602214450d0820052005290264220737025420052014360250200541e0006a200141c001109d081a200541a0026a200541e0006a200541d0006a200541c0006a109b022007a7211720052d00a0024101460d0620052802a4022218200541a0026a410c6a2802002219412c6c221a6a211b200541a0026a41086a221c280200211d0240201a450d00200541e0026a41086a210f41f7edcb00ad4280808080f00084210741f393ca00ad4280808080a00184211e201821120340200710012204290000210920054190036a41086a2213200441086a290000370300200520093703900320041035201e1001220429000821092004280004211f2004280000212020041035412010332204450d0220042012410c6a2200290000370000200441186a200041186a2221290000370000200441106a200041106a2222290000370000200441086a200041086a222329000037000020052004ad4280808080800484100322062900003703e002200610352005200441206a36026c200520043602682005200f3602642005200541e0026a360260200541a0026a200541e0006a107b2004103520052802a802221541206a2206417f4c0d0c20052802a00221160240024020060d0041002108410121040c010b200610332204450d03200621080b024002402008410f4d0d002008210d0c010b2008410174220d4110200d41104b1b220d4100480d04024020080d00200d103322040d010c090b2008200d460d0020042008200d10372204450d080b2004200529039003370000200441086a201329030037000002400240200d4170714110460d00200d21080c010b200d41017422084120200841204b1b22084100480d04200d2008460d002004200d200810372204450d080b200420093700182004201f3600142004202036001002400240200841606a2015490d002008210d0c010b2015415f4b0d042008410174220d2006200d20064b1b220d4100480d042008200d460d0020042008200d10372204450d080b200441206a20162015109d081a024020052802a402450d00201610350b200541286a2004200641b0b4cc0041004100108a022005280228211f0240200d450d00200410350b20071001220429000021092013200441086a29000037030020052009370390032004103541cca9c000ad4280808080a00184100122042900082109200428000421202004280000212420041035412010332204450d0220042000290000370000200441186a2021290000370000200441106a2022290000370000200441086a202329000037000020052004ad4280808080800484100322062900003703e002200610352005200441206a36026c200520043602682005200f3602642005200541e0026a360260200541a0026a200541e0006a107b2004103520052802a802221541206a2206417f4c0d0c20052802a00221160240024020060d0041002108410121040c010b200610332204450d03200621080b024002402008410f4d0d002008210d0c010b2008410174220d4110200d41104b1b220d4100480d04024020080d00200d10332204450d090c010b2008200d460d0020042008200d10372204450d080b2004200529039003370000200441086a201329030037000002400240200d4170714110460d00200d21080c010b200d41017422084120200841204b1b22084100480d04200d2008460d002004200d200810372204450d080b20042009370018200420203600142004202436001002400240200841606a2015490d002008210d0c010b2015415f4b0d042008410174220d2006200d20064b1b220d4100480d042008200d460d0020042008200d10372204450d080b200441206a20162015109d081a024020052802a402450d00201610350b200541e0006a20042006109c02024020052d0070220641024622130d0020052802602110200528026421252005290368210c0b0240200d450d00200410350b02400240024002400240201f410146220420064102472208460d002004450d010240201241086a2802004101470d000240201228020022042000460d0020042000412010a0080d010b20042f012041ffff03460d030b4119210420064102460d0b202541ffffff3f710d0a0c0b0b4116210420064102460d0a202541ffffff3f71450d0a0c090b02402008450d00024020122802082204450d002012280200220d200441226c6a2115200c422088a72116200ca7410574211303402005200d22063602a002200641226a210d20132100201021040340024020000d00411721040c0c0b024020062004460d0020042006412010a0082108200041606a2100200441206a210420080d010b0b200541e0006a200541a0026a10bb010240200528026c2204450d00200528026821000240200528027041ffffffff0371450d00200410350b200020164d0d00411821040c0b0b200d2015470d000b0b202541ffffff3f71450d030c020b4185f3c10041fd004184f4c1001064000b20130d01202541ffffff3f71450d010b201010350b2012412c6a2212201b470d000b0b200541003602e802200542043703e002200541e0026a4100201a412c6d10980120052802e002210020052802e80221042005201b36026c200520183602682005201d36026420052018360260200520054190036a360270201c20043602002005200541e0026a41086a3602a402200520002004412c6c6a3602a002200541e0006a200541a0026a109d0220052802e4022110200541e0006a200e200b20052802e002222020052802e802221f10cc012005280268210f2005280264211220052802602116411a21040240200528026c0d000240024002402016450d0002402012450d002012210420162100034020002802c80521002004417f6a22040d000b20162104201221060340200420042f01064102746a41c8056a28020021042006417f6a22060d000b200541e0006a21060c020b200541e0006a210620162100201621040c010b4100210020054100360264200541e0006a21060c010b20052004360264200541ec006a20042f010636020020054100360268200541003602600b200541e0026a41086a200641086a29020022073703002005200629020022093703e002200541e0006a41186a200737030042002126200542003703682005200036026420054100360260200520093703702005200f3602800102400240200f0d00427f21274200210c4200212842002129427f211e0c010b2005200f417f6a36028001200541e0006a410020001b220d2802002106200d28020821130240024002400240200d28020c2208200d28020422042f01064f0d00200421000c010b034020042802002200450d02200641016a210620042f0104210820002104200820002f01064f0d000b0b2008ad4220862013ad8421070c010b2013ad2107410021000b2007422088a7221341016a21082007a721150240024020060d00200021040c010b200020084102746a41c8056a2802002104410021082006417f6a2206450d00034020042802c80521042006417f6a22060d000b0b200d200836020c200d2015360208200d2004360204200d4100360200200020134105746a41e8026a2104427f2127427f211e4200212842002129420021264200210c0340200541086a200441086a29030022094200200429030022074200108408200541186a2007420020074200108408427f200c427f200541186a41086a290300222a2005290308222b202b7c7c222b20092005290310222c84202c84420052202b202a547222041b7c2026427f200529031820041b7c222a2026542204ad7c222620042026200c542026200c511b22041b210c427f202a20041b21262009201e20072027542009201e542009201e511b22041b211e2007202720041b2127200920297c200720287c2228200754ad7c21292005280280012204450d0120052004417f6a36028001200541e0006a410020052802641b220d2802002106200d2802082113024002400240200d28020c2208200d28020422042f01064f0d00200421000c010b0240034020042802002200450d01200641016a210620042f0104210820002104200820002f0106490d020c000b0b2013ad2107410021000c010b2008ad4220862013ad8421070b2007422088a7221341016a21082007a721150240024020060d00200021040c010b200020084102746a41c8056a2802002104410021082006417f6a2206450d00034020042802c80521042006417f6a22060d000b0b200d200836020c200d2015360208200d2004360204200d4100360200200020134105746a41e8026a21040c000b0b200541c8026a200c370300200541a0026a41186a2029370300200520263703c002200520283703b002200520273703a0022005201e3703a80202400240200541a0026a2003460d00200541a0026a2003413010a0080d010b0240024020160d0041002116410021034100210f0c010b0240024020120d00201621030c010b2012210320162104034020042802c80521042003417f6a22030d000b201621030340200320032f01064102746a41c8056a28020021032012417f6a22120d000b200421160b20032f010621040b200541fc006a2004360200200541e0006a41186a4100360200200541f4006a20033602002005200f3602800120054100360270200542003703682005201636026420054100360260200520054190036a36028401200541d0026a200541e0006a10cd0120052802d002211320052802d402211520052802d802211220054180036a41086a22034200370300200542003703800341f7edcb00ad4280808080f0008410012204290000210720054190036a41086a2200200441086a2900003703002005200737039003200410352003200029030037030020052005290390033703800341b3b6c000ad4280808080d001841001220429000021072004290008210920041035200541e0026a41086a2003290300370300200520093703f802200520073703f00220052005290380033703e0022005410036026820054201370360200b200541e0006a10770240200b450d00200b410574210b4100200528026822046b210120052802642106200e2103034002400240200620016a4120490d00200528026021000c010b200441206a22002004490d06200641017422082000200820004b1b22084100480d060240024020060d00024020080d00410121000c020b200810332200450d0c0c010b2005280260210020062008460d0020002006200810372200450d0b0b2005200836026420052000360260200821060b200020046a22002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a2900003700002005200441206a2204360268200141606a2101200341206a2103200b41606a220b0d000b0b2012200541e0006a107702402012450d002013201241d0006c6a210d2013210b03400240024020052802642200200528026822036b4120490d00200528026021040c010b200341206a22042003490d06200041017422012004200120044b1b22014100480d060240024020000d00024020010d00410121040c020b200110332204450d0c0c010b2005280260210420002001460d0020042000200110372204450d0b0b20052001360264200520043602600b200420036a2204200b290000370000200441186a200b41186a290000370000200441106a200b41106a290000370000200441086a200b41086a2900003700002005200341206a3602682005200b41206a3602900320054190036a200541e0006a10cf012005200b41306a3602900320054190036a200541e0006a10cf01200b2802402103200b2802482204200541e0006a107702402004450d00200441306c210603400240024020052802642201200528026822046b4120490d00200528026021000c010b200441206a22002004490d08200141017422082000200820004b1b22084100480d080240024020010d00024020080d00410121000c020b200810332200450d0e0c010b2005280260210020012008460d0020002001200810372200450d0d0b20052008360264200520003602600b200020046a2200200341106a290000370000200041186a200341286a290000370000200041106a200341206a290000370000200041086a200341186a2900003700002005200441206a360268200520033602900320054190036a200541e0006a10cf01200341306a2103200641506a22060d000b0b200d200b41d0006a220b470d000b0b024002400240024002400240200241ff0171220341024b0d0020030e03010203010b2005280268210320052802642100200528026021040c040b410021010c020b410121010c010b410221010b200520013a009003024002402005280264220020052802682203460d00200528026021040c010b200341016a22042003490d05200341017422002004200020044b1b22004100480d050240024020030d0041002103024020000d00410121040c020b200010332204450d0b0c010b2005280260210420032000460d0020042003200010372204450d0a0b20052000360264200520043602600b200420036a20013a00002005200341016a22033602680b200a2003ad4220862004ad84100202402000450d00200410350b02402011450d00200e10350b02402012450d00201241d0006c2104201341c4006a21030340024020032802002200450d00200041306c450d002003417c6a28020010350b200341d0006a2103200441b07f6a22040d000b0b02402015450d00201541d0006c450d00201310350b200541e0006a41286a2200200541a0026a41286a290300370300200541e0006a41206a2201200541a0026a41206a290300370300200541e0006a41186a2206200541a0026a41186a290300370300200541e0006a41106a2208200541a0026a41106a290300370300200541e0006a41086a220b200541a0026a41086a290300370300200520052903a00237036020054180036a41086a22034200370300200542003703800341f7edcb00ad4280808080f0008410012204290000210720054190036a41086a2202200441086a2900003703002005200737039003200410352003200229030037030020052005290390033703800341ceeecb00ad4280808080b001841001220429000021072004290008210920041035200541e0026a41086a2003290300370300200520093703f802200520073703f00220052005290380033703e002413010332203450d0220032005290360370000200341286a2000290300370000200341206a2001290300370000200341186a2006290300370000200341106a2008290300370000200341086a200b290300370000200a2003ad42808080808006841002200310350240201f450d00201f412c6c21042020210303400240200341046a2802002200450d00200041306c450d00200328020010350b2003412c6a2103200441546a22040d000b0b02402010450d002010412c6c450d00202010350b0240201741ffffff3f71450d00201410350b0240200528024441ffffff3f71450d00200528024010350b411d21040c0f0b411b21040b0240024020160d004100210f200541f4006a4100360200200541003602640c010b0240024020120d00201621030c010b2012210320162100034020002802c80521002003417f6a22030d000b201621030340200320032f01064102746a41c8056a28020021032012417f6a22120d000b200021160b200541fc006a20032f0106360200200541f8006a4100360200200541f4006a2003360200200541003602702005420037036820052016360264200541003602600b2005200f36028001200541e0006a109e020240201f450d00201f412c6c21002020210303400240200341046a2802002206450d00200641306c450d00200328020010350b2003412c6a2103200041546a22000d000b0b2010450d072010412c6c450d07202010350c070b1045000b103e000b202541ffffff3f71450d010b201010350b02402019450d002019412c6c21002018210303400240200341046a2802002206450d00200641226c450d00200328020010350b2003412c6a2103200041546a22000d000b0b201d450d02201d412c6c450d02201810350c020b103c000b411521040b41002103201741ffffff3f71450d012014103520110d030c040b41122104410121030b20110d010c020b1044000b200e10350b0240200528024441ffffff3f71450d00200528024010350b2003450d00200110fa010b200541a0036a240020040be10503027f017e057f230041e0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241206a41086a200341086a290000370300200220043703202003103541ccb5c000ad4280808080800284100122032900002104200241c0006a41086a200341086a2900003703002002200437034020031035200220013602542002200241d4006aad4280808080c000841003220329000037035820031035200241146a200241d8006a3602002002200241d8006a41086a36020c2002200241d4006a3602102002200241d8006a360208200241306a200241086a107b02400240024002402002280238220541206a2206417f4c0d00200228023021070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290320370000200341086a200241206a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290340370010200341186a200241c0006a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a02402002280234450d00200710350b200241086a2003200610ae01200241c0006a41086a2201200241086a410c6a2902003703002002200229020c3703400240024020022802084101460d00200042003702002000410c6a41003602000c010b20002002290340370200200041086a20012903003702000b02402008450d00200310350b200241e0006a24000f0b1044000b1045000b103e000b103c000bbb0302027f037e230041d0006b22042400200441386a20024201200242015620034200522003501b22051b22022003420020051b2203428094ebdc034200109808200441286a20042903382206200441386a41086a2903002207428094ebdc034200108408200441186a20022003200620022004290328852003200441286a41086a2903008584420052ad7c22084201200842015620072008200654ad7c22064200522006501b22051b22082006420020051b220710980802400240024020042903182206428080808010544100200441186a41086a290300501b450d00200441086a200220002002200054200320015420032001511b22051b2003200120051b2008200710980820042903082203428080808010544100200441086a41086a290300501b450d012006a7450d02200441d0006a2400200342ffffffff0f83428094ebdc037e200642ffffffff0f8380a70f0b2004411136024c20044190efc40036024841bcedc40041de00200441c8006a41acedc400419ceec4001046000b2004411136024c20044190efc40036024841bcedc40041de00200441c8006a41acedc40041f0eec4001046000b4190edc40041194180efc400103f000bf619020c7f087e23004190046b2204240020044190036a2001108c024100200428029003220520042802980310970241ff0171220620064103461b21060240200428029403450d00200510350b0240024002400240024020060e03000201000b200441a0016a200110b40120044190036a20042802a001220620042802a80110d50120044180026a41086a220520044199036a29000037030020044180026a41106a2207200441a1036a29000037030020044180026a41186a2208200441a9036a29000037030020042004290091033703800202400240024020042d0090034101470d0020044180016a41186a200829030037030020044180016a41106a200729030037030020044180016a41086a2005290300370300200420042903800237038001024020042802a401450d00200610350b200441e0016a41186a20044180016a41186a290300370300200441e0016a41106a20044180016a41106a290300370300200441e0016a41086a20044180016a41086a29030037030020042004290380013703e001200441c0006a200441e0016a10b70120044190036a20042802402209200428024810d601200441a0016a41086a220520044190036a41086a290300370300200441a0016a41106a220720044190036a41106a290300370300200441a0016a41186a220820044190036a41186a29030037030020044180026a41086a220a200441bc036a29020037030020044180026a41106a220b200441c4036a29020037030020044180026a41186a220c200441cc036a29020037030020044180026a41206a220d200441d4036a29020037030020044180026a41286a220e200441dc036a29020037030020044180026a41306a220f200441e4036a28020036020020042004290390033703a001200420042902b4033703800220042802b0032206450d01200441e0026a41186a2008290300370300200441e0026a41106a2007290300370300200441e0026a41086a2005290300370300200441086a41086a200a290300370300200441086a41106a200b290300370300200441086a41186a200c290300370300200441086a41206a200d290300370300200441086a41286a200e290300370300200441086a41306a200f280200360200200420042903a0013703e002200420042903800237030802402004280244450d00200910350b20044180026a41186a200441e0016a41186a290300221037030020044180026a41106a200441e0016a41106a290300221137030020044180026a41086a200441e0016a41086a2903002212370300200420042903e00122133703800220044190036a41186a201037030020044190036a41106a201137030020044190036a41086a201237030020044190036a41286a200441e0026a41086a290300221437030020044190036a41306a200441e0026a41106a290300221537030020044190036a41386a200441e0026a41186a29030022163703002004201337039003200420042903e00222173703b003200441c0006a41386a2016370300200441c0006a41306a2015370300200441c0006a41286a2014370300200441e0006a2017370300200441c0006a41186a2010370300200441c0006a41106a2011370300200441c0006a41086a2012370300200420133703400c020b20042802a401450d04200610350c040b02402004280244450d00200910350b20044180026a41186a200441e0016a41186a29030037030020044180026a41106a200441e0016a41106a29030037030020044180026a41086a200441e0016a41086a290300370300200420042903e001370380020b2006450d02200441a0016a41386a2207200441c0006a41386a290300370300200441a0016a41306a2208200441c0006a41306a290300370300200441a0016a41286a220a200441c0006a41286a290300370300200441a0016a41206a220b200441c0006a41206a290300370300200441a0016a41186a200441c0006a41186a2205290300370300200441a0016a41106a200441c0006a41106a220c290300370300200441a0016a41086a200441c0006a41086a220d290300370300200420042903403703a001200441e0016a41186a2005290300370300200441e0016a41106a200c290300370300200441e0016a41086a200d290300370300200420042903403703e00120044180026a41186a2205200729030037030020044180026a41106a2207200829030037030020044180026a41086a2208200a290300370300200420063602a0022004200b29030037038002200441a4026a2004290308370200200441ac026a200441086a41086a290300370200200441b4026a200441086a41106a290300370200200441bc026a200441086a41186a290300370200200441c4026a200441086a41206a290300370200200441cc026a200441086a41286a290300370200200441d4026a200441086a41306a2802003602002005290300211020072007290300221120027c22123703002005201020037c2012201154ad7c3703002008200829030020037c200429038002221020027c2211201054ad7c221237030020042011370380022004200337038801200420023703800102400240200220038450450d004200210342002110420021020c010b200420013602dc02200441e0026a200120044180016a200441dc026a109a02024020042802e0024101470d004200211020042903e8022103420121020c010b20044188036a290300211020044180036a29030021034200210220042903e8024201520d00200441e0026a41106a2903002113200441c8036a200441e0026a41186a290300370300200441c0036a201337030020044190036a41086a41003a000020044199036a2001290000370000200441a1036a200141086a290000370000200441a9036a200141106a290000370000200441b1036a200141186a290000370000200441033a00900341b0b4cc00410020044190036a10d4010b200442f3e885db96cddbb3203703800120044180016a20044180026a41386a20112012411f10900220044190036a200441e0016a10b701200428029003210120042004280298033602e402200420013602e00220044180026a200441e0026a10e1010240200428029403450d00200110350b024020042802a4022201450d00200141186c450d0020042802a00210350b0240200441b0026a28020041ffffffff0371450d0020042802ac0210350b200242018521020c030b200441a0016a200110b40120044190036a20042802a001220120042802a80110d50120044180026a41086a220620044199036a29000037030020044180026a41106a2205200441a1036a29000037030020044180026a41186a2207200441a9036a290000370300200420042900910337038002024020042d0090034101470d00200441c0006a41186a2007290300370300200441c0006a41106a2005290300370300200441c0006a41086a20062903003703002004200429038002370340024020042802a401450d00200110350b200441a0016a41186a200441c0006a41186a290300370300200441a0016a41106a200441c0006a41106a290300370300200441a0016a41086a200441c0006a41086a290300370300200420042903403703a001200420023703082004200337031002400240200220038450450d004200210242002103420021100c010b2004200441a0016a3602e00220044180026a200441a0016a200441086a200441e0026a109a0202402004280280024101470d00420021102004290388022103420121020c010b200441a8026a2903002110200441a0026a2903002103420021022004290388024201520d0020044180026a41106a2903002111200441c8036a20044180026a41186a290300370300200441c0036a201137030020044190036a41086a41003a000020044199036a20042903a001370000200441a1036a200441a0016a41086a290300370000200441a9036a200441a0016a41106a290300370000200441b1036a200441a0016a41186a290300370000200441033a00900341b0b4cc00410020044190036a10d4010b200242018521020c030b20042802a401450d0120011035420021020c020b200420023703a001200420033703a80102400240200220038450450d004200210342002110420021020c010b2004200136024020044180026a2001200441a0016a200441c0006a109a0202402004280280024101470d00420021102004290388022103420121020c010b200441a8026a2903002110200441a0026a2903002103420021022004290388024201520d0020044180026a41106a2903002111200441c8036a20044180026a41186a290300370300200441c0036a201137030020044190036a41086a41003a000020044199036a2001290000370000200441a1036a200141086a290000370000200441a9036a200141106a290000370000200441b1036a200141186a290000370000200441033a00900341b0b4cc00410020044190036a10d4010b200242018521020c010b420021020b2000200337030820002002370300200041106a201037030020044190046a24000b800201027f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad84100510c20102400240200228020822010d00410321000c010b200228020c210302400240200241106a280200450d0020012d000022004103490d010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b410321000b2003450d00200110350b200241d0006a240020000ba30301067f230041106b22032400024020014105744104722204417f4c0d000240200410332205450d002003410036020820032004360204200320053602002001200310770240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020002101024002402006200522046b4120490d00200441206a21050c010b024002400240200441206a22052004490d00200641017422002005200020054b1b22004100480d000240024020060d00024020000d00410121070c020b2000103321070c040b20062000470d020b200021060c030b103e000b200720062000103721070b2000210620070d00103c000b200141206a2100200720046a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100202402006450d00200710350b200341106a24000f0b1045000b1044000bce0203027f017e037f23004180026b22012400200141086a2000108e02200141e0006a2001280208220020012802102202108f0220012903602103200141b8016a200141e8006a41c400109d081a200141b4016a41026a2204200141af016a2d00003a0000200120012f00ad013b01b4010240024020034201510d0041002105200141186a410041c400109f081a0c010b20012d00ac012105200141186a200141b8016a41c400109d081a200141146a41026a20042d00003a0000200120012f01b4013b01140b200141e8006a200141186a41c400109d082104200141af016a200141166a2d00003a000020014201370360200141002005411874220541808080786a2206200620054b1b4118763a00ac01200120012f01143b00ad01200120023602bc01200120003602b8012004200141b8016a10e7020240200128020c450d00200010350b20014180026a24000bbe1007047f027e027f067e037f067e047f230041d0036b2204240020032802002105200441206a2001108e02200441a0016a2004280220220620042802282207108f0220042903a001210842002109200442003703a001200441e8016a280200210a20042d00ec01210b02400240200842015122030d00200441306a41306a4200370300200441306a41286a4200370300200441306a41206a4200370300200441306a41186a4200370300200441c0006a4200370300200441386a4200370300200442003703304200210c4200210d4200210e4200210f0c010b200441d8016a2903002110200441a0016a41306a2903002111200441a0016a41206a290300210c200441a0016a41186a2903002109200441e0016a290300210f20042903b001210e20042903a801210d200441306a41206a200441a0016a41286a290300370300200441306a41286a2011370300200441306a41306a2010370300200441c0006a20093703002004200c3703482004200d3703302004200e3703380b024002400240427f200d20097c22092009200d542212200e200c7c2012ad7c2209200e542009200e511b22121b427f200920121b84500d000240200d2002290300220c7c2209200d542212200e200241086a29030022107c2012ad7c220d200e54200d200e511b450d00200441a0026a41086a4108360200200441a7d6ca003602a402200441023a00a202200441830c3b01a002200441a0026a21020c020b200420093703302004200d370338200441e8006a41186a200441c0006a220241086a290300220e370300200441e8006a41206a2212200241106a29030037030020044190016a2213200241186a29030037030020044198016a2214200241206a2903003703002004200d3703702004200937036820042002290300221137037802400240427f200920117c221120112009542202200d200e7c2002ad7c220e200d54200e200d511b22021b2211428080e983b1de16544100427f200e20021b220e501b0d00200441e8006a41106a290300210e201429030021112013290300211520122903002116200429037021172004290368211842012119200429038001211a0c010b024002402011200e8450450d00420021190c010b42002119200441a0026a41186a221b4200370300200441a0026a41106a22134200370300200441a0026a41086a22124200370300200442003703a00241b6fdc600ad42808080808001842215100122142900002116200441c0036a41086a2202201441086a290000370300200420163703c0032014103520122002290300370300200420042903c0033703a00241e489c200ad4280808080d0018422161001221429000021172002201441086a290000370300200420173703c00320141035201320042903c0032217370300200441a0036a41086a221c2012290300370300200441a0036a41106a221d2017370300200441a0036a41186a221e2002290300370300200420042903a0023703a003200441086a200441a0036a412010d701200441086a41106a29030021172004290310211820042802082114201b42003703002013420037030020124200370300200442003703a00220151001221b29000021152002201b41086a290000370300200420153703c003201b103520122002290300370300200420042903c0033703a00220161001221b29000021152002201b41086a290000370300200420153703c003201b1035201320042903c0032215370300201c2012290300370300201d2015370300201e2002290300370300200420042903a0023703a003200442002017420020141b2215200e7d2018420020141b2216201154ad7d2217201620117d2218201656201720155620172015511b22021b3703a80220044200201820021b3703a002200441a0036aad4280808080800484200441a0026aad42808080808002841002200441d8026a200e370300200441d0026a2011370300201241013a0000200441a9026a2005290000370000200441b1026a200541086a290000370000200441b9026a200541106a290000370000200441c1026a200541186a290000370000200441033a00a00241b0b4cc004100200441a0026a10d4010b0b200441c8016a2016370300200441d0016a2015370300200441b0016a2017370300200441d8016a2011370300200441b8016a200e3703002004201a3703c0012004200f3703e001200420183703a8014201210e410021022004200b4100200842015122121b3a00ec012004200a410020121b3602e801200420194201512212ad3703a001024020120d002007ad4220862006ad8410074200210e420021080c030b200420073602a402200420063602a002200441a8016a200441a0026a10e702420021080c020b200441a8026a410b360200200441ea88c2003602a402200441073a00a202200441830c3b01a002200441a0026a21020b200241046a290200220d4280807c832108200d42088842ff0183210e200da7210320022802002112410121020b02402004280224450d00200610350b024002402002450d0020002012360204200041086a200e4208862003ad42ff018384200884370200410121010c010b024002400240200341ff017122030d00200e4200510d0041032102200441a0026a21030c010b2003450d01200e4200520d0141042102200441a0016a21030b200341086a20023a0000200341003a0000200341096a2001290000370000200341116a200141086a290000370000200341196a200141106a290000370000200341216a200141186a29000037000041b0b4cc004100200310d4010b200041286a2010370300200041206a200c370300200041186a200d370300200041106a2009370300200041086a4200370300410021010b20002001360200200441d0036a24000bf6c8010e077f017e057f017e0b7f017e037f017e017f017e017f017e017f017e230041d0016b220424002004200336020c20044100360218200442043703102001280204210520012802002106024002400240024002400240024002400240024020012802082203450d0020034103742107200441b0016a41106a2108200441b0016a41176a21092006210a03402002280208200a290200220ba722034d0d07200441b0016a41086a220c200228020020034105746a220341096a2900003703002008200341116a2900003703002009200341186a290000370000200420032900013703b00120032d0000210d412210332203450d02200428020c220e280208200b422088a741ffff0371220f4d0d06200441c0006a41106a2210200e280200200f4105746a220e41116a290000370300200441c0006a41176a220f200e41186a290000370000200441c0006a41086a200e41096a2900002211370300200e290001210b2003200e2d00003a00002003200b370001200341096a2011370000200341ffff033b0120200341116a2010290300370000200341186a200f2900003700002004200b37034020044190016a41176a220f200929000037000020044190016a41106a2210200829030037030020044190016a41086a2212200c290300370300200420042903b0013703900102402004280218220e2004280214470d00200441106a200e41011098012004280218210e0b200a41086a210a2004280210200e412c6c6a220e200d3a000c200e428180808010370204200e2003360200200e410d6a200429039001370000200e41156a2012290300370000200e411d6a2010290300370000200e41246a200f2900003700002004200428021841016a360218200741786a22070d000b0b0240200541ffffffff0171450d00200610350b200128020c2113200141106a2802002114200141146a2802002203450d0320132003410c6c6a211520044190016a41106a210720044190016a41176a210c2013210a034002400240200a41066a2f0100220841ffff03460d002002280208200a28020022034b0d0120004181043b01000c050b200041013b01000c040b200a41086a2f01002109200a41046a2f0100210e20044190016a41086a2210200228020020034105746a220341096a2900003703002007200341116a290000370300200c200341186a290000370000200420032900013703900120032d0000211241c40010332203450d01200428020c220d280208220f200e4d0d02200441b0016a41086a2206200d280200220d200e4105746a220e41096a290000370300200441b0016a41106a2205200e41116a290000370300200441b0016a41176a2216200e41186a2900003700002004200e2900013703b0010240200f20094d0d00200e2d0000210f200441c0006a41086a2217200d20094105746a220e41096a290000370300200441c0006a41106a2209200e41116a290000370300200441c0006a41176a220d200e41186a290000370000200e290001210b200e2d0000210e2003200f3a0000200320042903b001370001200341096a2006290300370000200341116a2005290300370000200341186a20162900003700002003200e3a0022200320083b01202004200b370340200320042903403700232003412b6a2017290300370000200341336a20092903003700002003413a6a200d29000037000020032008417f733b0142200441206a41176a2208200c290000370000200441206a41106a22092007290300370300200441206a41086a220d2010290300370300200420042903900137032002402004280218220e2004280214470d00200441106a200e41011098012004280218210e0b2004280210200e412c6c6a220e20123a000c200e428280808020370204200e2003360200200e410d6a2004290320370000200e41156a200d290300370000200e411d6a2009290300370000200e41246a20082900003700002004200428021841016a360218200a410c6a220a2015470d010c050b0b20004181043b0100200310350c020b103c000b20004181043b0100200310350b4100210641012102200441106a210802402014450d002014410c6c450d00201310350b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f4101211041012112410121140c040b02402014450d002014410c6c450d00201310350b200128021821172001411c6a28020021150240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141206a2802002203450d00201720034104746a2116200441c0006a41086a210e200441c0006a41106a210a200441c0006a41176a2108201721090240024003402009410c6a2f0100210c2009280200210d2004200941046a290200220b3703800102400240200428020c2203280208200ba741ffff037122074d0d00200e200328020020074105746a220341096a290000370300200a200341116a2900003703002008200341186a2900003700002004200329000137034020032d00002107412210332203450d06200320073a0000200320042903403700012003200b421088a722123b0120200341096a200e290300370000200341116a200a290300370000200341186a20082900003700002004428180808010370294012004200336029001200428020c220f28020820042f01840122104b0d0141000d004122450d00200310350b20004181043b01000c3a0b20042f0186012107200441b0016a41176a2206200f28020020104105746a220341186a290000370000200441b0016a41106a2210200341116a290000370300200441b0016a41086a220f200341096a290000220b3703002004200329000122113703b00120032d0000210520082006290000370000200a2010290300370300200e200b3703002004201137034020044190016a41014101109e01200428029001220320053a0022200341236a20042903403700002003412b6a200e290300370000200341336a200a2903003700002003413a6a2008290000370000200341c2006a20073b01002004410236022820042004280294012210360224200420033602200240417f2012411074221220074110746a220720072012491b411076220741ffff03470d00200041013b01000c030b200428020c2212280208200c4d0d012007417f732106200e2012280200200c4105746a220741096a290000370300200a200741116a2900003703002008200741186a290000370000200420072900013703404102210c20072d00002107024020104102470d00200441206a41024101109e01200428022021032004280228210c0b2003200c41226c6a220320073a000020032004290340370001200320063b0120200341096a200e290300370000200341116a200a290300370000200341186a20082900003700002004200428022841016a36022802402002280208200d4d0d0020022802002103200f200441206a41086a280200360200200e2003200d4105746a220341096a290000370300200a200341116a2900003703002008200341186a290000370000200420042903203703b0012004200329000137034020032d000021070240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b001370200200320073a000c200341086a200f2802003602002003410d6a2004290340370000200341156a200e2903003700002003411d6a200a290300370000200341246a20082900003700002004200428021841016a360218200941106a22092016470d010c040b0b20004181043b0100200428022421100c010b20004181043b01000b2010450d36201041226c450d36200428022010350c360b0240201541ffffffff0071450d00201710350b20012802242118200141286a280200211902402001412c6a2802002203450d002018200341146c6a211a2004418a016a211b20044180016a41086a211c200441c0006a41106a2107200441c0006a41176a210c20182115024002400240034020152f01102114201528020021132015290104210b201c2015410c6a2801003602002004200b3703800102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f018201210e200441c0006a41086a220d2003280200200a4105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d0000210341221033220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200d290300370000200f41116a2007290300370000200f41186a200c2900003700002004428180808010370294012004200f360290010240200428020c220328020820042f018401220a4b0d00410221034101210a0c390b201541146a2115417f200e411074220e20042f01860122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201b21080340200c201629000037000020072005290300370300200d2012290300370300200420042903b0013703400240200e417f6a2003470d0020044190016a20034101109e01200428029001210f0b200f200a6a220941606a20173a0000200941616a22032004290340370000200c290000210b20072903002111200d290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e360298010240200a41e400470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d0000211720042802940121030c000b0b410221030c380b200428029401210a20034103470d362004200e3602282004200a3602242004200f3602200240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200d200328020020144105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d000021090240200a200e470d00200441206a200e4101109e012004280220210f2004280228210e0b200f200e41226c6a220320093a000020032004290340370001200c290000210b20072903002111200d290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b3700002004200428022841016a360228200228020820134d0d03200228020021032012200441206a41086a280200360200200d200320134105746a220341096a2900003703002007200341116a290000370300200c200341186a290000370000200420042903203703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200d2903003700002003411d6a2007290300370000200341246a200c2900003700002004200428021841016a3602182015201a470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b01002004280224210a0b200a450d34200a41226c450d34200428022010350c340b02402019450d00201941146c450d00201810350b20012802302118200141346a28020021190240200141386a2802002203450d002018200341186c6a211a2004419a016a211b20044190016a41086a211c200441c0006a41106a2107200441c0006a41176a210c20182115024002400240034020152f01142114201528020021132015290104210b201c2015410c6a2901003703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220d2003280200200a4105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d0000210341221033220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200d290300370000200f41116a2007290300370000200f41186a200c29000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c350b201541186a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201b21080340200c201629000037000020072005290300370300200d2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a22032004290340370000200c290000210b20072903002111200d290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a418601470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c340b2004280224210a20034103470d322004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200d200328020020144105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a000020032004290340370001200c290000210b20072903002111200d290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200d200320134105746a220341096a2900003703002007200341116a290000370300200c200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200d2903003700002003411d6a2007290300370000200341246a200c2900003700002004200428021841016a3602182015201a470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d30200a41226c450d3020042802800110350c300b02402019450d00201941186c450d00201810350b200128023c2119200141c0006a280200211e0240200141c4006a2802002203450d0020192003411c6c6a21182004419a016a211a20044190016a41106a211c20044190016a41086a211b200441c0006a41176a210720192115024002400240034020152f01182114201528020021132015410c6a29010021112015290104210b201c201541146a280100360200201b20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221033220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c310b2015411c6a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201a2108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41a801470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c300b2004280224210a20034103470d2e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152018470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d2c200a41226c450d2c20042802800110350c2c0b0240201e450d00201e411c6c450d00201910350b20012802482119200141cc006a280200211e0240200141d0006a2802002203450d00201920034105746a21182004419a016a211a20044190016a41106a211c20044190016a41086a211b200441c0006a41176a210720192115024002400240034020152f011c2114201528020021132015410c6a29010021112015290104210b201c201541146a290100370300201b20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221033220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c2d0b201541206a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201a2108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41ca01470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c2c0b2004280224210a20034103470d2a2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152018470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d28200a41226c450d2820042802800110350c280b0240201e41ffffff3f71450d00201910350b2001280254211f200141d8006a280200211e0240200141dc006a2802002203450d00201f200341246c6a21192004419a016a211820044190016a41186a211c20044190016a41106a211b20044190016a41086a211a200441c0006a41176a2107201f2115024002400240034020152f01202114201528020021132015410c6a2901002111201541146a290100211d2015290104210b201c2015411c6a280100360200201b201d370300201a20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221033220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c290b201541246a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e20182108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41ec01470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c280b2004280224210a20034103470d262004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152019470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d24200a41226c450d2420042802800110350c240b0240201e450d00201e41246c450d00201f10350b2001280260211f200141e4006a280200211e0240200141e8006a2802002203450d00201f200341286c6a2119200441ca006a2118200441c0006a41186a211c200441c0006a41106a211b200441c0006a41086a211a200441b0016a41176a2107201f2115024002400240034020152f01242114201528020021132015410c6a2901002111201541146a290100211d2015290104210b201c2015411c6a290100370300201b201d370300201a20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c250b201541286a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20182108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a418e02470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c240b2004280224210a20034103470d222004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152019470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d20200a41226c450d2020042802800110350c200b0240201e450d00201e41286c450d00201f10350b200128026c211f200141f0006a28020021200240200141f4006a2802002203450d00201f2003412c6c6a211e200441ca006a2119200441e0006a211c200441c0006a41186a211b200441c0006a41106a211a200441c0006a41086a2118200441b0016a41176a2107201f2115024002400240034020152f01282114201528020021132015410c6a2901002111201541146a290100211d2015411c6a29010021212015290104210b201c201541246a280100360200201b2021370300201a201d370300201820113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c210b2015412c6a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20192108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41b002470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c200b2004280224210a20034103470d1e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201e470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d1c200a41226c450d1c20042802800110350c1c0b02402020450d002020412c6c450d00201f10350b20012802782120200141fc006a280200211f024020014180016a2802002203450d002020200341306c6a211e200441ca006a2119200441e0006a211c200441c0006a41186a211b200441c0006a41106a211a200441c0006a41086a2118200441b0016a41176a210720202115024002400240034020152f012c2114201528020021132015410c6a2901002111201541146a290100211d2015411c6a29010021212015290104210b201c201541246a290100370300201b2021370300201a201d370300201820113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c1d0b201541306a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20192108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41d202470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c1c0b2004280224210a20034103470d1a2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201e470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d18200a41226c450d1820042802800110350c180b0240201f450d00201f41306c450d00202010350b200128028401212020014188016a280200212202402001418c016a2802002203450d002020200341346c6a211f200441ca006a211e200441e8006a211c200441e0006a211b200441c0006a41186a211a200441c0006a41106a2118200441c0006a41086a2119200441b0016a41176a210720202115024002400240034020152f01302114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015290104210b201c2015412c6a280100360200201b2023370300201a20213703002018201d370300201920113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c190b201541346a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201e2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41f402470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c180b2004280224210a20034103470d162004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201f470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d14200a41226c450d1420042802800110350c140b02402022450d00202241346c450d00202010350b200128029001212020014194016a2802002122024020014198016a2802002203450d002020200341386c6a211f200441ca006a211e200441e8006a211c200441e0006a211b200441c0006a41186a211a200441c0006a41106a2118200441c0006a41086a2119200441b0016a41176a210720202115024002400240034020152f01342114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015290104210b201c2015412c6a290100370300201b2023370300201a20213703002018201d370300201920113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c150b201541386a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201e2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a419603470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c140b2004280224210a20034103470d122004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201f470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d10200a41226c450d1020042802800110350c100b02402022450d00202241386c450d00202010350b200128029c012124200141a0016a28020021220240200141a4016a2802002203450d0020242003413c6c6a2120200441ca006a211f200441f0006a211c200441e8006a211b200441e0006a211a200441c0006a41186a2118200441c0006a41106a2119200441c0006a41086a211e200441b0016a41176a210720242115024002400240034020152f01382114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015412c6a29010021252015290104210b201c201541346a280100360200201b2025370300201a2023370300201820213703002019201d370300201e20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c110b2015413c6a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201f2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41b803470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c100b2004280224210a20034103470d0e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152020470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d0c200a41226c450d0c20042802800110350c0c0b02402022450d002022413c6c450d00202410350b20012802a8012122200141ac016a28020021240240200141b0016a2802002203450d00202220034106746a2120200441ca006a211f200441f0006a211c200441e8006a211b200441e0006a211a200441c0006a41186a2118200441c0006a41106a2119200441c0006a41086a211e200441b0016a41176a210720222115024002400240034020152f013c2114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015412c6a29010021252015290104210b201c201541346a290100370300201b2025370300201a2023370300201820213703002019201d370300201e20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c0e0b201541c0006a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201f2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41da03470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c0d0b2004280224210a20034103470d0b2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152020470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d09200a41226c450d0920042802800110350c090b0240202441ffffff1f71450d00202210350b20012802b4012126200141b8016a2802002124200141bc016a2802002203450d022026200341c4006c6a2122200441ca006a2120200441f8006a211c200441f0006a211b200441e8006a211a200441e0006a2118200441c0006a41186a2119200441c0006a41106a211e200441c0006a41086a211f200441b0016a41176a21072026211502400240034020152f01402114201528020021132015410c6a290100210b201541146a29010021112015411c6a290100211d201541246a29010021212015412c6a2901002123201541346a290100212520152901042127201c2015413c6a280100360200201b2025370300201a2023370300201820213703002019201d370300201e2011370300201f200b3703002004202737034002400240200428020c220328020820042f0140220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d05200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c090b201541c4006a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20202108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41fc03470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c080b2004280224210a20034103470d062004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152022470d010c060b0b200041013b01000c030b20004181043b01000c020b20004181043b0100200428028401210a0c010b1045000b200a450d03200a41226c450d0320042802800110350c030b02402024450d00202441c4006c450d00202610350b200041003a0000200041046a20042903103702002000410c6a200441186a2802003602000c370b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b41002102200441106a210802402024450d00202441c4006c450d00202610350b41002109410021050c060b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210941012102200441106a21080240202441ffffff1f710d00410021050c040b20221035410021050c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210541012102200441106a210802402022450d002022413c6c450d00202410350b410121090b410021160c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100211641012102200441106a210802402022450d00202241386c450d00202010350b41012109410121050b410021170c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100211741012102200441106a210802402022450d00202241346c450d00202010350b4101210941012105410121160b410021150c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100211541012102200441106a21080240201f450d00201f41306c450d00202010350b410121094101210541012116410121170b410021070c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210741012102200441106a210802402020450d002020412c6c450d00201f10350b41012109410121054101211641012117410121150b4100210c0c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210c41012102200441106a21080240201e450d00201e41286c450d00201f10350b4101210941012105410121164101211741012115410121070b410021000c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210041012102200441106a21080240201e450d00201e41246c450d00201f10350b4101210941012105410121164101211741012115410121074101210c0b4100210d0c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210d41012102200441106a21080240201e41ffffff3f71450d00201910350b4101210941012105410121164101211741012115410121074101210c410121000b4100210f0c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210f41012102200441106a21080240201e450d00201e411c6c450d00201910350b4101210941012105410121164101211741012115410121074101210c410121004101210d0b410021100c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100211041012102200441106a210802402019450d00201941186c450d00201810350b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f0b410021120c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100211241012102200441106a210802402019450d00201941146c450d00201810350b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f410121100b41002114410021060c040b4100211441012102200441106a21080240201541ffffffff0071450d00201710350b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f4101211041012112410021060c030b20004181043b0100200310350c010b20004181043b01000b41012102200441106a21080240200541ffffffff0171450d00200610350b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f410121104101211241012114410121060b02402004280218220e450d0020042802102103200e412c6c210e03400240200341046a280200220a450d00200a41226c450d00200328020010350b2003412c6a2103200e41546a220e0d000b0b0240200841046a2802002203450d002003412c6c450d00200828020010350b02402006450d00200141106a2802002203450d002003410c6c450d00200128020c10350b02402014450d002001411c6a28020041ffffffff0071450d00200128021810350b02402012450d00200141286a2802002203450d00200341146c450d00200128022410350b02402010450d00200141346a2802002203450d00200341186c450d00200128023010350b0240200f450d00200141c0006a2802002203450d002003411c6c450d00200128023c10350b0240200d450d00200141cc006a28020041ffffff3f71450d00200128024810350b02402000450d00200141d8006a2802002203450d00200341246c450d00200128025410350b0240200c450d00200141e4006a2802002203450d00200341286c450d00200128026010350b02402007450d00200141f0006a2802002203450d002003412c6c450d00200128026c10350b02402015450d00200141fc006a2802002203450d00200341306c450d00200128027810350b02402017450d0020014188016a2802002203450d00200341346c450d0020012802840110350b02402016450d0020014194016a2802002203450d00200341386c450d0020012802900110350b02402005450d00200141a0016a2802002203450d002003413c6c450d00200128029c0110350b02402009450d00200141ac016a28020041ffffff1f71450d0020012802a80110350b2002450d00200141b8016a2802002203450d00200341c4006c450d0020012802b40110350b200441d0016a24000bb00401087f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041023a00100c010b200328021421042003200341106a41086a28020036022420032001360220200341c8006a200341206a10c301024002400240024020032802482205450d00200328024c2106024002400240200328022422024104490d00200341c8006a41086a280200210720032002417c6a220836022420032003280220220941046a220a3602202008450d012009280000210920032002417b6a3602242003200a41016a360220200a2d0000220a41014b0d0141002102200a0e020504050b200641ffffff3f710d010c020b200641ffffff3f71450d010b200510350b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b410221020c020b410121020b200341386a41026a200341286a41026a2d0000220a3a0000200341c8006a41026a200a3a0000200320032f002822083b01382000200936020c200020073602082000200636020420002005360200200320083b0148200041136a200a3a0000200020083b00110b200020023a00102004450d00200110350b200341e0006a24000bcb0f0a0f7f017e087f017e017f017e017f027e047f057e230041d0026b22022400200141086a2802002103200128020421042000280204210520002802002106024020002802082207200028020c2208460d0020012802002109200241f0006a410c6a210a200241f0006a410472210b200241c8006a41086a210c200241c8006a41106a210d200241c8006a41186a210e200241c8006a41206a210f0340200c20072200410c6a290200370300200d200041146a290200370300200e2000411c6a290200370300200f200041246a290200370300200220002902043703482000412c6a210720002802002210450d01200b2002290348370200200b41086a200c290300370200200b41106a200d290300370200200b41186a200e290300370200200b41206a200f29030037020020022010360270200a10c8012111200241a0016a41086a2212200a41086a290200370300200241a0016a41106a2213200a41106a290200370300200241a0016a41186a2214200a41186a2902003703002002200a2902003703a00120022802742115024002400240200228027841226c2201450d00201021000340200041206a2f01002116200241b0026a41186a2217200041186a290000370300200241b0026a41106a2218200041106a290000370300200241b0026a41086a2219200041086a290000370300200220002900003703b00220160d02200041226a21002001415e6a22010d000b0b4200211a4108211b4100210002402015450d00201541226c450d00201010354200211a0b4200211c4100211d0c010b200241386a2011420042ffff034200109808200241286a2002290338221e200241386a41086a290300221f4281807c427f108408200241186a201e201f2016ad4200108408200241d0016a41086a22202019290300370300200241d0016a41106a22212018290300370300200241d0016a41186a22222017290300370300200220022903b002221c3703f0012002201c3703d0012016200229032820117ca722236c221641ffff036e211d2002290318211c200241186a41086a29030021240240024041301033221b450d00201b201c201d417f20164180807c491b2016201d4181807c6c6a41ffff014b6aad42ffff03837c221a370320201b20022903d001370300201b41286a2024201a201c54ad7c221c370300201b41186a2022290300370300201b41106a2021290300370300201b41086a202029030037030020024281808080103702c4012002201b3602c001024020014122470d004101211d0c020b200141bc7f6a21214101211d410021160340200020166a220141c2006a2f0100212020172001413a6a2900003703002018200141326a29000037030020192001412a6a2900003703002002200141226a2900003703b0020240024020200d0020212016460d040c010b200241086a201e201f2020ad4200108408200241f0016a41086a20192903002224370300200241f0016a41106a20182903002225370300200241f0016a41186a20172903002226370300200220022903b00222273703f001201720263703002018202537030020192024370300200220273703b002201a20022903082225202020236c220141ffff036e2220417f20014180807c491b200120204181807c6c6a41ffff014b6aad42ffff03837c22247c2226201a542201201c200241086a41086a2903002024202554ad7c22257c2001ad7c221a201c54201a201c511b21010240201d20022802c401470d00200241c0016a201d410110880120022802c001211b0b427f201a20011b211c427f202620011b211a201b201d41306c6a220120022903b00237030020192903002126201829030021272017290300212820012024370320200141286a2025370300200141186a2028370300200141106a2027370300200141086a20263703002002201d41016a221d3602c80120212016460d030b201641226a21160c000b0b1045000b02402015450d00201541226c450d00201010350b20022802c40121000b024002402011201a7d22252011564200201c2011201a54ad7c7d22244200522024501b4101470d00201a20117d2224201a56201c201a201154ad7d2225201c56201a20115a1b0d01201d450d01201d41306c201b6a41706a220142002001290300221c20247d221a201a201c56200141086a2201290300221a20257d201c202454ad7d221c201a56201c201a511b22171b37030020014200201c20171b3703000c010b201d450d00201d41306c201b6a41706a2201427f2001290300221c20257c221a201a201c542217200141086a2201290300221c20247c2017ad7c221a201c54201a201c511b22171b3703002001427f201a20171b3703000b200241b0026a41186a22012014290300370300200241b0026a41106a22172013290300370300200241b0026a41086a22182012290300370300200220022903a0013703b002200920003602042009201d3602082009201b360200200920022903b00237020c200941146a20182903003702002009411c6a2017290300370200200941246a2001290300370200200341016a21032009412c6a210920072008470d000b200821070b20042003360200200820076b2200412c6d210102402000450d002001412c6c210003400240200741046a2802002201450d00200141226c450d00200728020010350b2007412c6a2107200041546a22000d000b0b02402005450d002005412c6c450d00200610350b200241d0026a24000b880303057f017e027f02400240024020002802202201450d00034020002001417f6a36022020002802042201450d0320002802082102200028020021030240200028020c220420012f0106490d00034002400240200128020022050d002002ad2106410021050c010b200341016a210320013301044220862002ad8421060b200110352006a72102200521012006422088a7220420052f01064f0d000b200521010b200441016a2107200120044105746a220541fc026a2802002104200541f8026a280200210802402003450d00200120074102746a41c8056a2802002101410021072003417f6a2205450d00034020012802c80521012005417f6a22050d000b0b2000200736020c2000200236020820002001360204200041003602002008450d0202402004450d00200441306c450d00200810350b200028022022010d000b0b200028020421010b02402001450d0020012802002105200110352005450d00034020052802002101200510352001210520010d000b0b0f0b41958dcc00412b41c08dcc00103f000b13002000411c360204200041c8f4c1003602000be60203047f017e017f024020002802002201450d0020002802082102024020002802042200450d00034020012802e40121012000417f6a22000d000b0b02402002450d0041002103024003402001450d01410021040240200320012f0106490d00034002400240200128020022000d0041002103410021000c010b200441016a210420012f010421030b2001103520002101200320002f01064f0d000b200021010b200341016a210020012003410c6c6a220341e4006a2902002105200341e0006a28020021060240024020040d00200021030c010b200120004102746a41e4016a2802002101410021032004417f6a2200450d00034020012802e40121012000417f6a22000d000b0b2006450d022002417f6a210202402005a7450d00200610350b20020d000c020b0b41958dcc00412b41c08dcc00103f000b2001450d0020012802002100200110352000450d00034020002802002101200010352001210020010d000b0b0b9a9e0106047f017e087f047e287f037e230041c0056b22002400200041b0036a41186a4200370300200041b0036a41106a22014200370300200041b0036a41086a22024200370300200042003703b00341a0e4cb00ad42808080808002841001220329000021042002200341086a290000370300200020043703b0032003103541e1b8c800ad4280808080a0018410012203290000210420004190056a41086a2205200341086a29000037030020002004370390052003103520012000290390052204370300200041f8026a41086a2002290300370300200041f8026a41106a2004370300200041f8026a41186a2005290300370300200020002903b0033703f802200041b0036a200041f8026a10fe010240024020002802b00322020d004100210620004100360298022000420137039002410121020c010b200020002902b40322043702940220002002360290022004422088a721060b024002400240200641ffffff3f712006470d0020064105742203417f4c0d000240024020030d00410121050c010b200310332205450d020b200041003602b803200020053602b003200020034105763602b403200041b0036a41002006108a0120002802b80321070240024020060d0020002802b00321080c010b2006410574210520002802b003220820074105746a2103034020032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a290000370000200341206a2103200241206a2102200541606a22050d000b200641057441606a41057620076a41016a21070b20002802b4032109200041b0036a41186a22054200370300200041b0036a41106a220a4200370300200041b0036a41086a22024200370300200042003703b00341a0e4cb00ad42808080808002841001220329000021042002200341086a290000370300200020043703b003200310354189eaca00ad4280808080f0008410012203290000210420004190056a41086a220b200341086a2900003703002000200437039005200310352001200029039005370000200141086a200b290300370000200041f8026a41086a2002290300370300200041f8026a41106a200a290300370300200041f8026a41186a2005290300370300200020002903b0033703f802200041b0036a200041f8026a10a20220002802b003210220002902b4032104200041003602b803200042013703b003200041b0036a41002004420020021b2204422088a7220341306c220a41306d108a012004a7210b2002410820021b210c20002802b803210502402003450d0020002802b00320054105746a2102200c21030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000200541016a2105200241206a2102200341306a2103200a41506a220a0d000b0b200020053602b8030240200b450d00200b41306c450d00200c10350b20002802b403210320002802b003210220004190026a20062005108a01200028029002200028029802220a4105746a20022005410574109d081a2000200a20056a220b360298020240200341ffffff3f71450d00200210350b200041b0036a41186a22054200370300200041b0036a41106a220a4200370300200041b0036a41086a22024200370300200042003703b00341a0e4cb00ad42808080808002841001220329000021042002200341086a290000370300200020043703b0032003103541c699c200ad428080808090018410012203290000210420004190056a41086a2206200341086a2900003703002000200437039005200310352001200029039005370000200141086a2006290300370000200041f8026a41086a2002290300370300200041f8026a41106a200a290300370300200041f8026a41186a2005290300370300200020002903b0033703f802200041b0036a200041f8026a10a20220002802b003210220002902b4032104200041003602b803200042013703b003200041b0036a41002004420020021b2204422088a7220341306c220a41306d108a012004a721062002410820021b210120002802b803210502402003450d0020002802b00320054105746a2102200121030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000200541016a2105200241206a2102200341306a2103200a41506a220a0d000b0b200020053602b80302402006450d00200641306c450d00200110350b20002802b403210320002802b003210220004190026a200b2005108a01200028029002200028029802220a4105746a20022005410574109d081a2000200a20056a360298020240200341ffffff3f71450d00200210350b41a0e4cb00ad4280808080800284100122022900002104200041f0046a41086a2203200241086a290000370300200020043703f004200210354190eaca00ad4280808080e0008410012202290000210420004190056a41086a2205200241086a290000370300200020043703900520021035412010332202450d01200220002903f0043700002002200029039005370010200241086a2003290300370000200241186a220a2005290300370000412010332203450d0120032002290000370000200341186a200a290000370000200341106a200241106a290000370000200341086a200241086a290000370000200041b8026a41026a2205200041b0036a41026a2d00003a0000200020002f00b0033b01b802200041d8026a41106a42a08080808004370300200041003a00f002200020023602e402200042a080808080043702dc02200020033602d802200041f3026a20052d00003a0000200020002f01b8023b00f102200020004190056a3602f402200041b0036a200041d8026a10a3020240024020002802e0032205450d00200041f0046a41186a220a200041b0036a41186a290300370300200041f0046a41106a2206200041b0036a41106a290300370300200041f0046a41086a220b200041b0036a41086a290300370300200020002903b0033703f004200041d8036a290300210d20002903d003210e20002902e403210f200041f8026a41186a4200370300200041f8026a41106a22014200370300200041f8026a41086a22024200370300200042003703f80241b6fdc600ad42808080808001841001220329000021042002200341086a290000370300200020043703f8022003103541e489c200ad4280808080d00184100122032900002104200041b0056a41086a220c200341086a290000370300200020043703b00520031035200120002903b005220437030020004190056a41086a200229030037030020004190056a41106a200437030020004190056a41186a200c290300370300200020002903f80237039005200041f8016a20004190056a412010d701200041e8016a200029038002200041f8016a41106a290300427f420010980820002802f8012102200041b0046a41186a2203200a290300370300200041b0046a41106a2006290300370300200041b0046a41086a200b290300370300200020002903f0043703b004200041e8016a41086a290300210420002903e8012110413810332211450d03200041d8016a200e200d2010420020021b2210420120104201562004420020021b22044200522004501b22021b2004420020021b109808201120002903b0043703082011200f37022c20112005360228201141106a200041b0046a41086a2202290300370300201141186a200041b0046a41106a2205290300370300201141206a2003290300370300201120002903d80137030020004281808080103702a402200020113602a0022003200041d8026a41186a2903003703002005200041d8026a41106a2903003703002002200041d8026a41086a290300370300200020002903d8023703b004200041b0036a200041b0046a10a3020240024020002802e003220b0d00410121120c010b200041b0036a41286a21134138210a41012106410121030340200041d0046a41186a220c200041b0036a41186a290300370300200041d0046a41106a2214200041b0036a41106a290300370300200041d0046a41086a2215200041b0036a41086a290300370300200020002903b0033703d0042013290300210d20002902e403210e20002903d003210f200041f8026a41186a22164200370300200041f8026a41106a22174200370300200041f8026a41086a22024200370300200042003703f80241b6fdc600ad42808080808001841001220529000021042002200541086a290000370300200020043703f8022005103541e489c200ad4280808080d00184100122052900002104200041b0056a41086a2218200541086a290000370300200020043703b00520051035200120002903b005370000200141086a201829030037000020004190056a41086a200229030037030020004190056a41106a201729030037030020004190056a41186a2016290300370300200020002903f80237039005200041c0016a20004190056a412010d701200041b0016a20002903c801200041c0016a41106a290300427f4200109808200041a0016a200f200d20002903b001420020002802c00122021b220442012004420156200041b0016a41086a290300420020021b22044200522004501b22021b2004420020021b109808200041f0046a41186a2205200c290300370300200041f0046a41106a220c2014290300370300200041f0046a41086a22142015290300370300200020002903d0043703f00420002903a0012104024020032006470d00200041a0026a20064101108b0120002802a00221110b2011200a6a22022004370300200241086a20002903f00437030020052903002104200c290300210d2014290300210f2002412c6a200e370200200241286a200b360200200241106a200f370300200241186a200d370300200241206a20043703002000200341016a22023602a802200041b0036a200041b0046a10a302024020002802e003220b450d00200a41386a210a20002802a4022106200221030c010b0b200341016a21120b024020002802b404450d0020002802b00410350b0240200041c0046a280200450d0020002802bc0410350b20002802a40221190c010b024020002802dc02450d0020002802d80210350b4108211141002112024020002802e802450d0020002802e40210350b410021190b20004190056a41086a20004190026a41086a2802003602002000200029039002370390052012ad42387e2204422088a70d002004a72202417f4c0d000240024020020d00410821030c010b200210332203450d020b2000410036028003200020033602f8022000200241386e3602fc02200041f8026a41002012108b01200028028003210102402012450d00201241386c210a20002802f802200141386c6a2102201241037441786a410376210b200041b0036a41286a2106200041b0036a41086a2105201121030340200541186a200341206a290300370300200541106a200341186a290300370300200541086a200341106a2903003703002005200341086a290300370300200020032903003703b0032006200341286a10a402200241306a200041b0036a41306a290300370300200241286a2006290300370300200241206a200041b0036a41206a290300370300200241186a200041b0036a41186a290300370300200241106a200041b0036a41106a290300370300200241086a2005290300370300200220002903b003370300200241386a2102200341386a2103200a41486a220a0d000b2001200b6a41016a21010b4108210a200041b0036a41086a22022001360200200020002903f8023703b003200041a0026a4114410020004190056a200041b0036a10ca010240024020002802a002220c0d0041012118200041013a00b403200041093a00b00341b0b4cc004100200041b0036a10d401200041f8026a2101200041b0036a21060c010b200041a0026a41146a2802002115200041a0026a41106a2802002116200041ac026a2802002101200041a0026a41086a280200210b20002802a402211442002104200041b0036a41186a4200370300200041b0036a41106a221a420037030020024200370300200042003703b00341a0e4cb00ad428080808080028410012203290000210d200041f0046a41086a2205200341086a2900003703002000200d3703f0042003103520022005290300370300200020002903f0043703b0034189eaca00ad4280808080f0008410012203290000210d20004190056a41086a2205200341086a2900003703002000200d3703900520031035201a200029039005220d370300200041f8026a41086a2002290300370300200041f8026a41106a200d370300200041f8026a41186a2005290300370300200020002903b0033703f802200041b0036a200041f8026a10a202024020002802b0032202450d00200041f8026aad4280808080800484100720002902b40321042002210a0b200041003602b803200042013703b003200041b0036a41002004422088a7220241306c220541306d108a012004a7210620002802b803211b02402002450d0020002802b003201b4105746a2102200a21030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000201b41016a211b200241206a2102200341306a2103200541506a22050d000b0b2000201b3602b80302402006450d00200641306c450d00200a10350b20002802b403211c20002802b003211d42002104200041b0036a41186a22054200370300200041b0036a41106a220642003703004108210a200041b0036a41086a22024200370300200042003703b00341a0e4cb00ad428080808080028410012203290000210d200041f0046a41086a2217200341086a2900003703002000200d3703f0042003103520022017290300370300200020002903f0043703b00341c699c200ad428080808090018410012203290000210d20004190056a41086a2217200341086a2900003703002000200d3703900520031035201a200029039005370000201a41086a2017290300370000200041f8026a41086a2002290300370300200041f8026a41106a2006290300370300200041f8026a41186a2005290300370300200020002903b0033703f802200041b0036a200041f8026a10a202024020002802b0032202450d00200041f8026aad4280808080800484100720002902b40321042002210a0b200041003602b803200042013703b003200041b0036a41002004422088a7220241306c220541306d108a012004a7210620002802b803211e02402002450d0020002802b003201e4105746a2102200a21030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000201e41016a211e200241206a2102200341306a2103200541506a22050d000b0b2000201e3602b80302402006450d00200641306c450d00200a10350b20002802b403211f20002802b0032120024002400240200b41306c2203450d00200c21020340200241286a2903002104200241206a290300210d200041f8026a41186a200241186a290000370300200041f8026a41106a200241106a290000370300200041f8026a41086a200241086a290000370300200020022900003703f802200d2004844200520d02200241306a2102200341506a22030d000b0b410121214100210b02402014450d00201441306c450d00200c10350b410021220c010b200041b0046a41086a2205200041f8026a41086a290300370300200041b0046a41106a220a200041f8026a41106a290300370300200041b0046a41186a2206200041f8026a41186a290300370300200020002903f80222043703d004200020043703b004412010332221450d03202120002903b004370000202141186a2006290300370000202141106a200a290300370000202141086a200529030037000020004281808080103702b403200020213602b0030240024020034130470d004101210b0c010b200241306a2105200c200b41306c6a220641506a21174101210b03402005210202400340200241286a2903002104200241206a290300210d200041f8026a41186a2203200241186a290000370300200041f8026a41106a2205200241106a290000370300200041f8026a41086a220a200241086a290000370300200020022900003703f802200d2004844200520d012006200241306a2202470d000c030b0b20004190056a41086a200a290300220437030020004190056a41106a2005290300220d37030020004190056a41186a2003290300220e370300200020002903f802220f37039005200041d0046a41186a220a200e370300200041d0046a41106a2218200d370300200041d0046a41086a221320043703002000200f3703d0040240200b20002802b403470d00200041b0036a200b4101108a0120002802b00321210b200241306a21052021200b4105746a220320002903d004370000200341186a200a290300370000200341106a2018290300370000200341086a20132903003700002000200b41016a220b3602b80320172002470d000b0b02402014450d00201441306c450d00200c10350b20002802b40321220b200020004190056a3602f0042000410036029805200042043703900520004190056a41002015412c6c2203412c6d109801200028029005210520002802980521022000200120036a3602bc03200020013602b803200020163602b403200020013602b0032000200041f0046a3602c003200041f8026a41086a22162002360200200020004190056a41086a22233602fc02200020052002412c6c6a3602f802200041b0036a200041f8026a10a5022000280294052124200041b0036a2021200b2000280290052225200028029805222610cc01200041b8026a41086a200041b0036a41086a2217280200360200200020002903b0033703b802200041003602d804200042083703d004200041d0046a4100200b410574220241057510880120002802d804212720002802d004212802402002450d00202120026a21292028202741306c6a2101200041f8026a41106a211541b6fdc600ad4280808080800184210f2021210b0340200b41086a2900002104200b41106a290000210d200b290000210e200041b0036a41186a2218200b41186a290000370300200041b0036a41106a2213200d370300201720043703002000200e3703b0030240024020002802b8022206450d00200b41206a210b20002802bc02210c0340200641086a210320062f01062214410574210241002105024003402002450d01200041b0036a2003412010a008220a450d04200241606a2102200541016a2105200341206a2103200a417f4a0d000b2005417f6a21140b200c450d01200c417f6a210c200620144102746a41c8056a28020021060c000b0b41b894ca0041da00419495ca001064000b200041f0046a41186a22032018290300370300200041f0046a41106a220a2013290300370300200041f0046a41086a220c2017290300370300200020002903b0033703f004200620054105746a220241f0026a290300210d200241e8026a290300210e200041f8026a41186a220542003703002015420037030020164200370300200042003703f802200f1001220229000021042016200241086a290000370300200020043703f8022002103541e489c200ad4280808080d00184100122022900002104200041b0056a41086a2206200241086a290000370300200020043703b00520021035201520002903b005370000201541086a20062903003700002023201629030037030020004190056a41106a201529030037030020004190056a41186a2005290300370300200020002903f8023703900520004188016a20004190056a412010d701200041f8006a20002903900120004188016a41106a290300427f4200109808200041e8006a2000290378420020002802880122021b220442012004420156200041f8006a41086a290300420020021b22044200522004501b22021b2004420020021b200e200d108408200141186a2003290300370300200141106a200a290300370300200141086a200c290300370300200120002903f004370300200141286a200041e8006a41086a29030037030020012000290368370320202741016a2127200141306a2101200b2029470d000b0b200020273602d8040240202241ffffff3f71450d00202110350b20002802d404212a024002402027410d2027410d491b222b0d00200041003602b803200042083703b003200041b0036a4100410010880120002802b80321290c010b202b41306c220510332202450d03200041003602b8032000202b3602b403200020023602b003200041b0036a4100202b10880120002802b00320002802b803222941306c6a2102202821030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102202941016a2129200341306a2103200541506a22050d000b200020293602b8030b20002802b403212c20002802b00321170240024020294115490d002029410176ad42307e2204422088a70d032004a7222d417f4c0d03202d1033222e450d042000410036028003200042043703f802201741506a212f201741f07e6a21304104210541002103410021312029212303402023210b410021234101210c0240200b417f6a2206450d000240024002400240024002402017200641306c6a200b41306c220220176a41a07f6a412010a0084100480d00200b417e6a2101203020026a2102410021234100210a034002402001200a470d00200b210c0c080b200a41016a210a200241306a2002412010a0082106200241506a21022006417f4a0d000b200a41016a210c200a417f73200b6a21060c010b2030200b41066c41037422146a210202400340024020064101470d00410021060c020b2006417f6a2106200241306a2002412010a008210a200241506a2102200a4100480d000b0b200b2006490d01200b20294b0d02200b20066b220c4101762201450d00202f20146a21022017200641306c6a210a0340200041b0036a41286a2214200a41286a2215290300370300200041b0036a41206a2216200a41206a2218290300370300200041b0036a41186a2213200a41186a2223290300370300200041b0036a41106a2221200a41106a2222290300370300200041b0036a41086a2232200a41086a22332903003703002000200a2903003703b003200241086a22342903002104200241106a2235290300210d200241186a2236290300210e200241206a2237290300210f200241286a22382903002110200a2002290300370300201520103703002018200f3703002023200e3703002022200d370300203320043703002038201429030037030020372016290300370300203620132903003703002035202129030037030020342032290300370300200220002903b003370300200241506a2102200a41306a210a2001417f6a22010d000b0b024020060d00200621230c050b0240200c41094d0d00200621230c050b200b20294b0d02200b20066b21012017200641306c6a21140340200b2006417f6a2223490d040240200b20236b220c4102490d002017200641306c6a22022017202341306c6a2206412010a008417f4a0d002006290300210420062002290300370300200041b0036a41286a2213200641286a220a290300370300200041b0036a41206a2221200641206a2215290300370300200041b0036a41186a2222200641186a2216290300370300200041b0036a41106a2232200641106a2218290300370300200041b0036a41086a2233200641086a22342903003703002034200241086a2903003703002018200241106a2903003703002016200241186a2903003703002015200241206a290300370300200a200241286a290300370300200020043703b003410121180240200c4103490d00200641e0006a200041b0036a412010a008417f4a0d004102210a2014210202400340200241286a200241d8006a290300370300200241206a200241d0006a290300370300200241186a200241c8006a290300370300200241106a200241c0006a290300370300200241086a200241386a2903003703002002200241306a22152903003703002001200a460d01200241e0006a2116200a211820152102200a41016a210a2016200041b0036a412010a008417f4a0d020c000b0b200a21180b2006201841306c6a220220002903b003370300200241286a2013290300370300200241206a2021290300370300200241186a2022290300370300200241106a2032290300370300200241086a20332903003703000b2023450d05201441506a2114200141016a210120232106200c410a4f0d050c000b0b2006200b41eccfca001059000b200b202941eccfca001058000b200b2006417f6a2223490d00200b202941fccfca001058000b2023200b41fccfca001059000b0240203120002802fc02470d00200041f8026a2031410110900120002802f8022105200028028003220321310b200520314103746a2202200c360204200220233602002000200341016a22033602800320032131024020034102490d000240024003400240024002400240024020052003417f6a4103746a2202280200450d00200341037420056a220141746a28020022062002280204220a4b0d010b20034103490d022002280204210a20052003417d6a22164103746a28020421020c010b41022131200341024d0d0620052003417d6a22164103746a2802042202200a20066a4d0d0041032131200341034d0d06200141646a280200200220066a4b0d050b2002200a490d010b2003417e6a21160b02400240024002400240024002402003201641016a22184d0d00200320164d0d012005201641037422216a2202280204222220022802006a22022005201841037422326a22032802002213490d02200220294b0d032017201341306c6a22142003280204221541306c22036a210a200241306c2105200220136b220120156b220220154f0d04202e200a200241306c2203109d08220c20036a210620154101480d0520024101480d05202f20056a2103200a210203402003200241506a220a200641506a22012001200a412010a008410048220b1b2205290300370300200341286a200541286a290300370300200341206a200541206a290300370300200341186a200541186a290300370300200341106a200541106a290300370300200341086a200541086a29030037030020062001200b1b210602402014200a2002200b1b2202490d00200c21050c080b200341506a2103200c2105200c2006490d000c070b0b20182003418cd0ca001042000b20162003419cd0ca001042000b2013200241acd0ca001059000b2002202941acd0ca001058000b202e20142003109d08220c20036a2106024020154101480d00200120154c0d00201720056a210b200c21052014210203402002200a2005200a2005412010a00841004822011b2203290300370300200241286a200341286a290300370300200241206a200341206a290300370300200241186a200341186a290300370300200241106a200341106a290300370300200241086a200341086a2903003703002005200541306a20011b2105200241306a2102200a41306a200a20011b220a200b4f0d03200620054b0d000c030b0b20142102200c21050c010b200a2102200c21050b20022005200620056b220320034130706b109d081a0240200028028003220220164d0d0020002802f802220520216a2203202220156a36020420032013360200200220184d0d02200520326a2203200341086a20022018417f736a410374109e081a20002002417f6a220336028003200341014b0d010c030b0b2016200241bcd0ca001042000b20182002104e000b200321310b20230d000b024020002802fc0241ffffffff0171450d00200510350b202d4130702102202d4130490d01202d2002460d01202e10350c010b20294102490d002029417f6a2103202941306c20176a41506a21064101210503400240024002400240202920032202417f6a2203490d00202920036b22014102490d032017200241306c6a22022017200341306c6a220a412010a008417f4a0d03200a2903002104200a2002290300370300200041b0036a41286a2215200a41286a220b290300370300200041b0036a41206a2216200a41206a220c290300370300200041b0036a41186a2218200a41186a2214290300370300200041b0036a41106a2213200a41106a2223290300370300200041b0036a41086a2221200a41086a22222903003703002022200241086a2903003703002023200241106a2903003703002014200241186a290300370300200c200241206a290300370300200b200241286a290300370300200020043703b0034101210220014103490d02200a41e0006a200041b0036a412010a008417f4a0d0241002101200621020340200241286a200241d8006a290300370300200241206a200241d0006a290300370300200241186a200241c8006a290300370300200241106a200241c0006a290300370300200241086a200241386a2903003703002002200241306a220c29030037030020052001220b460d02200b417f6a2101200241e0006a2114200c21022014200041b0036a412010a008417f4a0d020c000b0b2003202941dccfca001059000b4102200b6b21020b200a200241306c6a220220002903b003370300200241286a2015290300370300200241206a2016290300370300200241186a2018290300370300200241106a2013290300370300200241086a20212903003703000b200641506a21062005417f6a210520030d000b0b200041003602b803200042083703b003200041b0036a4100202941306c221341306e2223109a0120002802b803210b0240024020130d0020002802b00321010c010b20002802b0032201200b4104746a21022013210520172103034020022003360200200241086a4200370300200241106a2102200b41016a210b200341306a2103200541506a22050d000b0b2011201241386c6a211520002802b403212102400240024020120d002011210c0c010b200b41014b2118201121020340200241386a210c20022802282216450d0102402002412c6a290200220e422088a74105742203450d002002290300210d024020180d000240200b0e020200020b2001280200210542102104201621020340024020052002412010a0080d0020012001290308200d200442ffffffff0f837e7c3703080b200241206a21022004427f7c2104200341606a22030d000c020b0b201620036a21144200210420162106024003400240200b450d0041002102200b210303402003410176220520026a220a20022001200a4104746a2802002006412010a0084101481b2102200320056b220341014b0d000b200120024104746a22032802002006412010a0080d00200b20024d0d0220032003290308200d421020047d42ffffffff0f837e7c3703080b200442017c21042014200641206a2206460d020c000b0b2002200b41d099c2001042000b0240200e42ffffff3f83500d00201610350b200c2102200c2015470d000c020b0b2015200c460d000340200c41386a21020240200c412c6a28020041ffffff3f71450d00200c41286a28020010350b2002210c20152002470d000b0b02402019450d00201941386c450d00201110350b201720136a210c024002400240200b450d0020012802002203450d000240200b4101460d002001200b4104746a2106200141106a210220012903082104034020022802002205450d012004200241086a290300220d2004200d56220a1b210420032005200a1b2103200241106a22022006470d000b0b0240202141ffffffff0071450d00200110350b20030d01410021160c020b41002116202141ffffffff0071450d01200110350c010b200041d8026a41186a200341186a290000370300200041d8026a41106a200341106a290000370300200041d8026a41086a200341086a290000370300200020032900003703d802410121160b200041003602b803200042013703b003200041b0036a41002023108a0120002802b8032105024002402017200c4722310d0020002802b00321340c010b202941306c210a20002802b003223420054105746a210220172103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200541016a2105200241206a2102200341306a2103200a41506a220a0d000b0b20002802b403212f200041003602b803200042083703b003200041b0036a41002028202741306c22026a22032028202b41306c220a6a6b41306e10880120002802b8032115024002402027410d4b0d0020002802b00321360c010b200a20026b210a20002802b0032236201541306c6a2102200341506a21030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102200341506a2103201541016a2115200a41306a220a0d000b0b20002802b4032137200041003602b803200042013703b003200041b0036a41002015108a0120002802b803210a02400240201541306c22060d0020002802b00321210c010b20002802b0032221200a4105746a210220362103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200a41016a210a200241206a2102200341306a2103200641506a22060d000b0b20002802b4032127200041b0036a20342005201d201b10a602200041c4036a280200220b41ffffff3f71200b470d01200b4105742201417f4c0d01200041c0036a280200211b20002802bc03212220002802b403213020002802b003212b0240024020010d00410121020c010b200110332202450d030b200041003602b803200020023602b0032000200141057622183602b403200041b0036a4100200b108a0120002802b803210c02400240200b0d0020002802b00321140c010b200b410574210620002802b0032214200c4105746a210220222103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200241206a2102200341206a2103200641606a22060d000b200b41057441606a410576200c6a41016a210c0b20002802b40321022014200c2034200510a7020240200241ffffff3f71450d00201410350b200041b0046a41186a2202200041d8026a41186a290300370300200041b0046a41106a2203200041d8026a41106a290300370300200041b0046a41086a2205200041d8026a41086a290300370300200020002903d8023703b0040240024020160d00200041f8026a41186a4200370300200041f8026a41106a22054200370300200041f8026a41086a22024200370300200042003703f80241dad5ca00ad4280808080b002841001220329000021042002200341086a290000370300200020043703f80220031035419cdfca00ad4280808080d00084100122032900002104200041b0056a41086a2206200341086a290000370300200020043703b00520031035200520002903b0052204370300200041f0046a41086a2002290300370300200041f0046a41106a2004370300200041f0046a41186a2006290300370300200020002903f8023703f004200041f0046aad428080808080048410070c010b200041b0036a41186a2002290300370300200041b0036a41106a2003290300370300200041b0036a41086a2005290300370300200020002903b0043703b00320004190056a41186a420037030020004190056a41106a2205420037030020004190056a41086a22024200370300200042003703900541dad5ca00ad4280808080b002841001220329000021042002200341086a290000370300200020043703900520031035419cdfca00ad4280808080d00084100122032900002104200041f8026a41086a2206200341086a290000370300200020043703f80220031035200520002903f8022204370300200041d0046a41086a2002290300370300200041d0046a41106a2004370300200041d0046a41186a200629030037030020002000290390053703d004412010332202450d03200220002903b003370000200241186a200041b0036a41186a290300370000200241106a200041b0036a41106a290300370000200241086a200041b0036a41086a290300370000200041d0046aad42808080808004842002ad42808080808004841002200210350b0240024020010d00410121030c010b200110332203450d030b41002102200041003602b803200020183602b403200020033602b003200041b0036a4100200b108a0120002802b803210c0240200b450d00200b410574210620002802b003200c4105746a21010340200120026a2203202220026a2205290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a2900003700002006200241206a2202470d000b200b41057441606a410576200c6a41016a210c0b200041b8046a200c360200200020002903b0033703b004200041b0036a2021200a2020201e10a602200041c4036a2802002103200041c0036a280200210520002802bc032102024020002802b40341ffffff3f71450d0020002802b00310350b200041b0046a20002802b804200341057422034105752206108a0120002802b004222e20002802b80422014105746a20022003109d081a2000200120066a22383602b8040240200541ffffff3f71450d00200210350b02402007450d00200820074105746a2118200a4105742113200041b0036aad42808080808002842139200041f8026aad4280808080800484213a200041b0036a41106a2101200041b9036a2132202941014b2123200041e8036a21352008210b0340200b41086a2900002104200b41106a290000210d200b290000210e20004190056a41186a220c200b41186a29000037030020004190056a41106a2214200d37030020004190056a41086a221620043703002000200e37039005200b41206a210b410021030240024002400240024020230d0020290e020201020b202921050340200041b0036a41186a20172005410176220a20036a220641306c6a220241186a2900003703002001200241106a290000370300200041b0036a41086a200241086a290000370300200020022900003703b00320062003200041b0036a20004190056a412010a0084101481b21032005200a6b220541014b0d000b0b200041b0036a41186a2017200341306c6a220241186a2900003703002001200241106a290000370300200041b0036a41086a200241086a290000370300200020022900003703b0032013210320212102200041b0036a20004190056a412010a0080d010c020b20132103202121020b024003402003450d0120004190056a2002460d02200341606a2103200220004190056a412010a0082105200241206a210220050d000c020b0b200042003703f80420004280809aa6eaafe3013703f004200020004190056a3602d004200041f8026a20004190056a200041f0046a200041d0046a10a802200041f8026a41206a290300210d2000290390032104024020002903f8024201520d00200029038003210e2035200041f8026a41106a2903003703002032200029039005370000203241086a2016290300370000203241106a2014290300370000203241186a200c2903003700002000200e3703e003200041003a00b803200041033a00b00341b0b4cc004100200041b0036a10d4010b200020043703d0042000200d3703d804024002402004200d844200520d00200041b0036a41186a2205420037030020014200370300200041b0036a41086a22034200370300200042003703b00341b6fdc600ad428080808080018422041001220a290000210d200041f0046a41086a2202200a41086a2900003703002000200d3703f004200a103520032002290300370300200020002903f0043703b00341e489c200ad4280808080d00184220d1001220a290000210e2002200a41086a2900003703002000200e3703f004200a1035200120002903f004370000200141086a220c2002290300370000200041f8026a41086a22142003290300370300200041f8026a41106a22162001290300370300200041f8026a41186a22332005290300370300200020002903b0033703f802200041386a200041f8026a412010d701200041386a41106a290300210e2000290340210f2000280238210a200542003703002001420037030020034200370300200042003703b00320041001220629000021042002200641086a290000370300200020043703f0042006103520032002290300370300200020002903f0043703b003200d1001220629000021042002200641086a290000370300200020043703f00420061035200120002903f004370000200c2002290300370000201420032903003703002016200129030037030020332005290300370300200020002903b0033703f8022000200e4200200a1b3703b8032000200f4200200a1b3703b0030c010b200020043703d0042000200d3703d804200041b0036a41186a2205420037030020014200370300200041b0036a41086a22034200370300200042003703b00341b6fdc600ad4280808080800184220e1001220a290000210f200041f0046a41086a2202200a41086a2900003703002000200f3703f004200a103520032002290300370300200020002903f0043703b00341e489c200ad4280808080d00184220f1001220a29000021102002200a41086a290000370300200020103703f004200a1035200120002903f004370000200141086a220c2002290300370000200041f8026a41086a22142003290300370300200041f8026a41106a22162001290300370300200041f8026a41186a22332005290300370300200020002903b0033703f802200041d0006a200041f8026a412010d701200041d0006a41106a29030021102000290358213b2000280250210a200542003703002001420037030020034200370300200042003703b003200e10012206290000210e2002200641086a2900003703002000200e3703f0042006103520032002290300370300200020002903f0043703b003200f10012206290000210e2002200641086a2900003703002000200e3703f00420061035200120002903f004370000200c2002290300370000201420032903003703002016200129030037030020332005290300370300200020002903b0033703f8022000420020104200200a1b220e200d7d203b4200200a1b220d200454ad7d220f200d20047d2204200d56200f200e56200f200e511b22021b3703b80320004200200420021b3703b0030b203a203910020b200b2018470d000b0b0240200941ffffff3f71450d00200810350b20002802b404213302402038450d0020384105742101200041b0036aad42808080808002842139200041f8026aad4280808080800484213a200041b0036a41106a2102200041b9036a210b200041e8036a2132202e21030340200341086a2900002104200341106a290000210d2003290000210e20004190056a41186a2205200341186a29000037030020004190056a41106a220a200d37030020004190056a41086a220620043703002000200e37039005200042003703f80420004280809aa6eaafe3013703f004200020004190056a3602d004200041f8026a20004190056a200041f0046a200041d0046a10a802200041f8026a41206a290300210d2000290390032104024020002903f8024201520d00200029038003210e2032200041f8026a41106a290300370300200b200029039005370000200b41086a2006290300370000200b41106a200a290300370000200b41186a20052903003700002000200e3703e003200041003a00b803200041033a00b00341b0b4cc004100200041b0036a10d4010b200020043703d0042000200d3703d804024002402004200d844200520d00200041b0036a41186a2206420037030020024200370300200041b0036a41086a220a4200370300200042003703b00341b6fdc600ad428080808080018422041001220c290000210d200041f0046a41086a2205200c41086a2900003703002000200d3703f004200c1035200a2005290300370300200020002903f0043703b00341e489c200ad4280808080d00184220d1001220c290000210e2005200c41086a2900003703002000200e3703f004200c1035200220002903f004370000200241086a22162005290300370000200041f8026a41086a2218200a290300370300200041f8026a41106a22132002290300370300200041f8026a41186a22232006290300370300200020002903b0033703f802200041086a200041f8026a412010d701200041086a41106a290300210e2000290310210f2000280208210c2006420037030020024200370300200a4200370300200042003703b00320041001221429000021042005201441086a290000370300200020043703f00420141035200a2005290300370300200020002903f0043703b003200d1001221429000021042005201441086a290000370300200020043703f00420141035200220002903f004370000201620052903003700002018200a2903003703002013200229030037030020232006290300370300200020002903b0033703f8022000200e4200200c1b3703b8032000200f4200200c1b3703b0030c010b200020043703d0042000200d3703d804200041b0036a41186a2206420037030020024200370300200041b0036a41086a220a4200370300200042003703b00341b6fdc600ad4280808080800184220e1001220c290000210f200041f0046a41086a2205200c41086a2900003703002000200f3703f004200c1035200a2005290300370300200020002903f0043703b00341e489c200ad4280808080d00184220f1001220c29000021102005200c41086a290000370300200020103703f004200c1035200220002903f004370000200241086a22162005290300370000200041f8026a41086a2218200a290300370300200041f8026a41106a22132002290300370300200041f8026a41186a22232006290300370300200020002903b0033703f802200041206a200041f8026a412010d701200041206a41106a29030021102000290328213b2000280220210c2006420037030020024200370300200a4200370300200042003703b003200e10012214290000210e2005201441086a2900003703002000200e3703f00420141035200a2005290300370300200020002903f0043703b003200f10012214290000210e2005201441086a2900003703002000200e3703f00420141035200220002903f004370000201620052903003700002018200a2903003703002013200229030037030020232006290300370300200020002903b0033703f8022000420020104200200c1b220e200d7d203b4200200c1b220d200454ad7d220f200d20047d2204200d56200f200e56200f200e511b22051b3703b80320004200200420051b3703b0030b203a20391002200341206a2103200141606a22010d000b0b0240203341ffffff3f71450d00202e10350b200041b0036a41186a22034200370300200041b0036a41106a22054200370300200041b0036a41086a22024200370300200042003703b00341a0e4cb00ad4280808080800284220410012206290000210d200041f0046a41086a220a200641086a2900003703002000200d3703f004200610352002200a290300370300200020002903f0043703b0034189eaca00ad4280808080f0008410012201290000210d20004190056a41086a2206200141086a2900003703002000200d3703900520011035201a200029039005370000201a41086a220b2006290300370000200041f8026a41086a220c2002290300370300200041f8026a41106a22142005290300370300200041f8026a41186a22162003290300370300200020002903b0033703f802200041203602b4032000200041f8026a3602b00320172029200041b0036a10a902200342003703002005420037030020024200370300200042003703b0032004100122012900002104200a200141086a290000370300200020043703f004200110352002200a290300370300200020002903f0043703b00341c699c200ad42808080809001841001220a29000021042006200a41086a2900003703002000200437039005200a1035201a200029039005370000200b2006290300370000200c20022903003703002014200529030037030020162003290300370300200020002903b0033703f802200041203602b4032000200041f8026a3602b00320362015200041b0036a10a9022029ad42307e2204422088a70d012004a72202417f4c0d010240024020020d00410821030c010b200210332203450d030b200041003602b803200020033602b0032000200241306e3602b403200041b0036a4100202910880120002802b80321050240024020310d0020002802b00321010c010b202941306c210a20002802b0032201200541306c6a2102201721030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102200541016a2105200341306a2103200a41506a220a0d000b0b2005ad42307e2204422088a70d012004a72202417f4c0d0120002802b40321060240024020020d00410821030c010b200210332203450d030b200041003602b803200020033602b0032000200241306e3602b403200041b0036a4100200510880120002802b803210a0240200541306c2205450d0020002802b003200a41306c6a2102200121030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102200a41016a210a200341306a2103200541506a22050d000b0b20004183036a200a360000200020002903b0033700fb02200041bc036a200041ff026a290000370000200041003a00b403200041093a00b003200020002900f8023700b50341b0b4cc004100200041b0036a10d40102402006450d00200641306c450d00200110350b0240201b41ffffff3f71450d00202210350b0240203041ffffff3f71450d00202b10350b0240202741ffffff3f71450d00202110350b02402037450d00203741306c450d00203610350b0240202f41ffffff3f71450d00203410350b0240202c450d00202c41306c450d00201710350b0240202a450d00202a41306c450d00202810350b0240024020002802b802220a0d0041002106200041c4036a4100360200200041003602b4030c010b20002802c00221060240024020002802bc0222030d00200a21020c010b20032102200a2105034020052802c80521052002417f6a22020d000b200a21020340200220022f01064102746a41c8056a28020021022003417f6a22030d000b2005210a0b200041cc036a20022f0106360200200041c8036a4100360200200041c4036a2002360200200041003602c003200042003703b8032000200a3602b403200041003602b0030b200020063602d003200041b0036a109e0202402026450d002026412c6c21032025210203400240200241046a2802002205450d00200541306c450d00200228020010350b2002412c6a2102200341546a22030d000b0b02402024450d002024412c6c450d00202510350b0240201f41ffffff3f71450d00202010350b41002118200041b0036a2106200041f8026a2101201c41ffffff3f71450d00201d10350b200041b0036a41186a220b4200370300200041b0036a41106a22024200370300200041b0036a41086a22034200370300200042003703b00341a0e4cb00ad428080808080028422041001220a290000210d200041f0046a41086a2205200a41086a2900003703002000200d3703f004200a1035200641086a220c2005290300370000200620002903f00437000041e1b8c800ad4280808080a0018410012214290000210d20004190056a41086a220a201441086a2900003703002000200d37039005201410352002200029039005220d370300200041f8026a41086a22142003290300370300200041f8026a41106a2215200d370300200041f8026a41186a2216200a290300370300200020002903b0033703f8022001ad42808080808004841007200b42003703002002420037030020034200370300200042003703b003200410012217290000210d2005201741086a2900003703002000200d3703f00420171035200c2005290300370000200620002903f00437000041b0e4cb00ad4280808080e00184220d10012217290000210e200a201741086a2900003703002000200e37039005201710352002200029039005220e370300201420032903003703002015200e3703002016200a290300370300200020002903b0033703f80220002001412010c0012000280200211720002802042113200b42003703002002420037030020034200370300200042003703b00320041001220129000021042005200141086a290000370300200020043703f00420011035200c2005290300370000200620002903f004370000200d100122052900002104200a200541086a2900003703002000200437039005200510352002200029039005220437030020142003290300370300201520043703002016200a290300370300200020002903b0033703f8022000201341016a410120171b3602b003200041f8026aad4280808080800484200041b0036aad4280808080c0008410020240024020002802a00222020d0020180d010c040b2018450d03024020002802a4022203450d00200341306c450d00200210350b200041ac026a280200210a0240200041b4026a2802002202450d002002412c6c2103200a210203400240200241046a2802002205450d00200541246c450d00200228020010350b2002412c6a2102200341546a22030d000b0b200041b0026a2802002202450d002002412c6c450d00200a10350b02402012450d00201241386c21032011412c6a210203400240200228020041ffffff3f71450d002002417c6a28020010350b200241386a2102200341486a22030d000b0b02402019450d00201941386c450d00201110350b200941ffffff3f71450d02200810350c020b1044000b1045000b200041c0056a24000bbf0201027f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a10aa020240024020022802480d0020024100360230200242013703282002410936023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b200041003602000c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2003450d00200110350b200241e0006a24000ba00605057f017e037f027e027f230041f0006b22022400200241286a200141146a350200422086200135020c84102710c2010240024020022802282203450d00200141086a2104200141106a210503400240024020042802002206200229022c2207422088a722084b0d00200128020022092003460d0120092003200610a008450d010b2007a7450d02200310350c020b02402005280200450d00200128020c10350b2001200336020c20052007370200200241086a2003200810cc02024002402002280218220a450d00200241086a41086a29030021072002290308210b2002290320210c200228021c210d024020012d0018450d002001350214422086200135020c8410070b2001280214220820042802002203490d0102400240200820036b22084108490d00200841786a2106200128020c20036a41086a21090c010b410021060240410028028cb54c0d0041b0b4cc0021090c010b410021064100280298b54c21034100280294b54c21084100280290b54c210e200241e500360268200242b48080801037036020024187a1c00036025c20024213370254200241f4a0c0003602502002420037034841b0b4cc002109200241b0b4cc0036024420024201370338200241eca0c00036023420024113360230200241f4a0c00036022c20024101360228200841aca2c000200e410246220e1b200241286a200341c4a2c000200e1b2802101102000b41002103200241003a00480240034020062003460d01200241286a20036a200920036a2d00003a00002002200341016a22083a00482008210320084120470d000b20002002290328370000200041186a200241286a41186a290300370000200041106a200241286a41106a290300370000200041086a200241286a41086a290300370000200041286a20073703002000200b370320200041386a200c3703002000200d3602342000200a3602300c050b0240200341ff0171450d00200241003a00480b200d41ffffff3f71450d00200a10350b200241286a2001350214422086200135020c84102710c201200228022822030d010c020b0b2003200841889aca001059000b200041003602300b200241f0006a24000ba10201087f230041106b22022400024002402001280208220341ffffff3f712003470d0020034105742204417f4c0d00200128020021050240024020040d00410121060c010b200410332206450d020b41002101200241003602082002200636020020022004410576360204200241002003108a012002280208210702402003450d0020034105742108200228020020074105746a21090340200920016a2204200520016a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002008200141206a2201470d000b200341057441606a41057620076a41016a21070b20002002290300370200200041086a2007360200200241106a24000f0b1044000b1045000b8509050f7f027e017f017e027f23004180026b22022400200141086a2802002103200128020421042000280204210520002802002106024020002802082207200028020c2208460d002001280200210020024190016a410c6a2109200241c0016a41106a210120024190016a410472210a200241386a41206a210b200241386a41186a210c200241386a41086a210d024003402007280200210e200b200741246a290200370300200c2007411c6a290200370300200241386a41106a220f200741146a290200370300200d2007410c6a2902003703002002200741046a290200370338200e450d01200a2002290338370200200a41086a200d290300370200200a41106a200f290300370200200a41186a200c290300370200200a41206a200b2903003702002002200e36029001200241e0006a200910e502200241c0016a20022802602210200228026810cc02200241c0016a41086a220e290300211120022802d001210f20022903c001211220022802d401211302402002280264450d00201010350b20114200200f1b211420124200200f1b21120240200f450d00201341ffffff3f71450d00200f4101200f1b10350b200241c0016a41186a220f420037030020014200370300200e4200370300200242003703c00141b6fdc600ad4280808080800184100122132900002111200e201341086a290000370300200220113703c0012013103541e489c200ad4280808080d00184100122132900002111200241f0016a41086a2210201341086a290000370300200220113703f00120131035200120022903f001370000200141086a2010290300370000200241e0006a41086a2213200e290300370300200241e0006a41106a22102001290300370300200241e0006a41186a2215200f290300370300200220022903c001370360200241206a200241e0006a412010d701200241106a2002290328200241206a41106a290300427f420010980820022012201420022903104200200228022022161b221142012011420156200241106a41086a290300420020161b22114200522011501b22161b2011420020161b109808200241c0016a41286a20024190016a41286a280200360200200241c0016a41206a20024190016a41206a290300370300200f20024190016a41186a290300370300200120024190016a41106a290300370300200e20024190016a41086a29030037030020022002290390013703c001200241e0006a200241c0016a2002290300420010cb01200041286a200241e0006a41286a280200360200200041206a200241e0006a41206a290300370200200041186a2015290300370200200041106a2010290300370200200041086a201329030037020020002002290360370200200341016a21032000412c6a21002007412c6a22072008470d000b200821070c010b2007412c6a21070b20042003360200200820076b2200412c6d210102402000450d002001412c6c210003400240200741046a2802002201450d00200141246c450d00200728020010350b2007412c6a2107200041546a22000d000b0b02402005450d002005412c6c450d00200610350b20024180026a24000bd907010f7f230041c0006b22052400200541003602082005420137030020054100360218200542013703102003410020041b21062001410020021b2107200341206a200320041b2108200141206a200120021b2109200120024105746a210a200320044105746a210b4101210c4100210d4101210e4101210f410021100340200e211120102102200821032006210102400340024020010d004100210620070d02200020052903003702002000200529031037020c200041086a200541086a280200360200200041146a200541106a41086a280200360200200541c0006a24000f0b024020070d00200541206a41186a2203200641186a290000370300200541206a41106a2202200641106a290000370300200541206a41086a2207200641086a29000037030020052006290000370320024020102005280214470d00200541106a20104101108a012005280210210e200528021821100b200e20104105746a22012005290320370000200141186a2003290300370000200141106a2002290300370000200141086a20072903003700002005201041016a221036021841002107410020082008200b4622011b2106200e210f2008200841206a20011b21080c030b0240024020012007460d0020012007412010a00822040d010b2003200341206a2003200b4622011b2108410020092009200a4622041b21074100200320011b21062011210e200221102009200941206a20041b21090c030b02402004417f4c0d00200121060c020b200541206a41186a2204200141186a290000370300200541206a41106a2212200141106a290000370300200541206a41086a2213200141086a29000037030020052001290000370320024020022005280214470d00200541106a20024101108a012005280218210220052802102211210f0b200f20024105746a22012005290320370000200141186a2004290300370000200141106a2012290300370000200141086a20132903003700002005200241016a2202360218410020032003200b4622041b21012003200341206a20041b21030c000b0b200541206a41186a2204200741186a290000370300200541206a41106a2212200741106a290000370300200541206a41086a2213200741086a290000370300200520072900003703200240200d2005280204470d002005200d4101108a012005280200210c2005280208210d0b200c200d4105746a22012005290320370000200141186a2004290300370000200141106a2012290300370000200141086a20132903003700002005200d41016a220d360208410020092009200a4622011b21072011210e200221102009200941206a20011b2109200321080c000b0be80f06087f017e047f017e057f077e230022042105200441a0016b41607122042400024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610332207450d020b41002108200441003602282004200736022020042006410576360224200441206a41002001108a012004280228210902402001450d002001410574210a200428022020094105746a210b0340200b20086a2206200020086a2207290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200a200841206a2208470d000b200141057441606a41057620096a41016a21090b200441086a200936020020042004290320220c370300200ca72009410041202009676b10c105200441206a41186a22014200370300200441206a41106a220d4200370300200441206a41086a220e42003703002004420037032041dad5ca00ad4280808080b0028410012208290000210c200e200841086a2900003703002004200c370320200810354180eaca00ad428080808090018410012208290000210c200441e8006a41086a220f200841086a2900003703002004200c37036820081035200d2004290368220c37030020044180016a41086a200e29030037030020044180016a41106a200c37030020044180016a41186a200f2903003703002004200429032037038001200441206a20044180016a412010b50220042802202208410120081b21102004290224420020081b2211422088a72208450d022008410574210920044180016a410c722112200441206a410c6a2100200441206a4114722113200441206a41087221142010210803402001200841186a290000370300200d200841106a290000370300200e200841086a29000037030020042008290000370320200441106a200441206a108c07200441206a2004280210220b2004280218221510de02200f200041086a290200370300200441e8006a41106a220a200041106a2802003602002004200029020037036820042802402106024020042802282207450d002004290320210c20122004290368370200201241086a200f290300370200201241106a200a2802003602002004200c37038001200621160b200420073602880120044100360228200429039801211720042004290338221837039801200429039001211920042004290330221a37039001200429038001211b20042004290320221c37038001200429038801210c20042004290328221d37038801201da7210702400240200ca7220a0d00201d210c201a211920182117201621060c010b2004201b3703202004200c37032820042019370330200420173703382004200a2019a74105746a3602742004200a3602702004200c422088a736026c2004200a36026820042004360278200441d8006a200441e8006a10ca05201441086a200441d8006a41086a22162802003602002014200429035837020020042019422088a7220a2017422088a74105746a3602742004200a36027020042017a736026c2004200a36026820042004360278200441d8006a200441e8006a10ca05201341086a2016280200360200201320042903583702002004290328210c2004290320211c200429033821172004290330211902402007450d002018a7210a0240201d422088a741ffffff3f71450d00200710350b200a41ffffff3f71450d00201a422088a710350b2004201c370380012004200c3703880120042019370390012004201737039801200ca721070b2004200c37032820042019370330200120173703002004201c37032020042006360240200ca7210a0240024020070d002015ad422086200bad8410070c010b2004201536026c2004200b360268200441206a200441e8006a108b070b0240200a450d002017a721070240200c422088a741ffffff3f71450d00200a10350b200741ffffff3f71450d002019422088a710350b02402004280214450d00200b10350b200841206a210820062116200941606a22090d000c030b0b1044000b1045000b0240201142ffffff3f83500d00201010350b200441206a41186a220a4200370300200441206a41106a22074200370300200441206a41086a220642003703002004420037032041dad5ca00ad4280808080b00284220c10012200290000211c200441e8006a41086a2208200041086a2900003703002004201c3703682000103520062008290300370300200420042903683703204189eaca00ad4280808080f0008410012200290000211c2008200041086a2900003703002004201c3703682000103520072004290368221c37030020044180016a41086a220b200629030037030020044180016a41106a2201201c37030020044180016a41186a22092008290300370300200420042903203703800120044120360224200420044180016a36022020022003200441206a10a806200a4200370300200742003703002006420037030020044200370320200c10012200290000210c2008200041086a2900003703002004200c370368200010352006200829030037030020042004290368370320419cdfca00ad4280808080d0008410012200290000210c2008200041086a2900003703002004200c3703682000103520072004290368220c370300200b20062903003703002001200c37030020092008290300370300200420042903203703800120044180016aad428080808080048410070240200428020441ffffff3f71450d00200428020010350b200524000b9d0f07037f027e027f0a7e037f067e047f230041d0036b2204240020032802002105200441206a2001108e02200441a0016a2004280220220320042802282206108f0220042903a001210742002108200442003703a001200441e8016a280200210920042d00ec01210a0240024020074201510d00200441306a41306a4200370300200441306a41286a4200370300200441306a41206a4200370300200441306a41186a4200370300200441c0006a4200370300200441386a4200370300200442003703304200210b4200210c4200210d4200210e0c010b200441d8016a290300210f200441a0016a41306a2903002110200441a0016a41206a290300210b200441a0016a41186a2903002108200441e0016a290300210e20042903b001210d20042903a801210c200441306a41206a200441a0016a41286a290300370300200441306a41286a2010370300200441306a41306a200f370300200441c0006a20083703002004200b3703482004200c3703302004200d3703380b200441306a41186a200b200241086a2903002210200b20082002290300221156200b201056200b2010511b22021b22127d20082011200820021b220f54ad7d221337030020042008200f7d2214370340200441e8006a41186a2013370300200441e8006a41206a2215200441306a41206a290300370300200441e8006a41286a2216200441306a41286a290300370300200441e8006a41306a2217200441306a41306a290300370300200420143703782004200c3703682004200d370370427f200d200b7c200c20087c220b200c542202ad7c220820022008200d542008200d511b22021b2118427f200b20021b211902400240427f200c20147c22082008200c542202200d20137c2002ad7c2208200d542008200d511b22021b220b428080e983b1de16544100427f200820021b2213501b0d00200441f8006a290300210b20172903002113201629030021142015290300211a2004290370211b2004290368211c42012108200429038001211d0c010b02400240200b20138450450d00420021080c010b42002108200441a0026a41186a221e4200370300200441a0026a41106a22164200370300200441a0026a41086a22154200370300200442003703a00241b6fdc600ad4280808080800184221410012217290000211a200441c0036a41086a2202201741086a2900003703002004201a3703c0032017103520152002290300370300200420042903c0033703a00241e489c200ad4280808080d00184221a10012217290000211b2002201741086a2900003703002004201b3703c00320171035201620042903c003221b370300200441a0036a41086a221f2015290300370300200441a0036a41106a2220201b370300200441a0036a41186a22212002290300370300200420042903a0023703a003200441086a200441a0036a412010d701200441086a41106a290300211b2004290310211c20042802082117201e42003703002016420037030020154200370300200442003703a00220141001221e29000021142002201e41086a290000370300200420143703c003201e103520152002290300370300200420042903c0033703a002201a1001221e29000021142002201e41086a290000370300200420143703c003201e1035201620042903c0032214370300201f20152903003703002020201437030020212002290300370300200420042903a0023703a00320044200201b420020171b221420137d201c420020171b221a200b54ad7d221b201a200b7d221c201a56201b201456201b2014511b22021b3703a80220044200201c20021b3703a002200441a0036aad4280808080800484200441a0026aad42808080808002841002200441d8026a2013370300200441d0026a200b370300201541013a0000200441a9026a2005290000370000200441b1026a200541086a290000370000200441b9026a200541106a290000370000200441c1026a200541186a290000370000200441033a00a00241b0b4cc004100200441a0026a10d4010b0b2011200f54210220192018842118200441c8016a201a370300200441d0016a2014370300200441b0016a201b370300200441d8016a2013370300200441b8016a200b3703002004201d3703c0012004200e3703e0012004201c3703a8012004200a4100200742015122051b3a00ec0120042009410020051b3602e801200420084201512205ad3703a0010240024020050d002006ad4220862003ad8410070c010b200420063602a402200420033602a002200441a8016a200441a0026a10e7020b201020127d210b2002ad2110201850210202402004280224450d00200310350b200b20107d210b2002ad21102011200f7d21112008420152210202400240024020074201510d0020020d0041032103200441a0026a21020c010b20074201522002410173720d0141042103200441a0016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b2000200f3703182000200c37030820002010370300200041306a200b370300200041286a2011370300200041206a2012370300200041106a200d370300200441d0036a24000bac0402067f027e230041106b220324000240024002400240200141306c4104722204417f4c0d00200410332205450d012003410036020820032004360204200320053602002001200310770240024020010d002003280208210120032802042105200328020021060c010b2000200141306c6a2107200328020021062003280204210520032802082101034002400240200520016b4120490d00200141206a2104200521080c010b200141206a22042001490d05200541017422082004200820044b1b22084100480d05024020050d00024020080d00410121060c020b2008103322060d010c070b20052008460d0020062005200810372206450d060b200620016a22012000290000370000200141186a200041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200041286a2903002109200041206a290300210a02400240200820046b4110490d00200441106a2101200821050c010b200441106a22012004490d05200841017422052001200520014b1b22054100480d05024020080d00024020050d00410121060c020b200510332206450d070c010b20082005460d0020062008200510372206450d060b200620046a220420093700082004200a3700002007200041306a2200470d000b2003200536020420032001360208200320063602000b20022902002001ad4220862006ad84100202402005450d00200610350b200341106a24000f0b1044000b1045000b103e000b103c000bcf0504037f017e087f047e23004180016b220224002002200110c40102400240024002402002280200450d00200041003602000c010b20022802042203200128020441306e2204200420034b1bad42307e2205422088a70d012005a72204417f4c0d010240024020040d00410821060c010b200410332206450d030b4100210720024100360210200220063602082002200441306e36020c0240024002402003450d0041002108034041002104200241003a0078200841016a210820012802042109417f210a034020092004460d03200241d8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0078200a417f6a210a200c2104200c4120470d000b200241386a41186a2204200241d8006a41186a290300370300200241386a41106a220a200241d8006a41106a290300370300200241386a41086a220d200241d8006a41086a290300370300200220022903583703382009200c6b220c4110490d03200b41096a2900002105200b290001210e2001200c41706a3602042001200b41116a360200200241186a41086a220c200d290300370300200241186a41106a2209200a290300370300200241186a41186a220a20042903003703002002200229033837031802402007200228020c470d00200241086a2007410110880120022802082106200228021021070b2006200741306c6a22042002290318370300200c290300210f20092903002110200a29030021112004200e370320200441286a2005370300200441186a2011370300200441106a2010370300200441086a200f3703002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c020b200441ff0171450d00200241003a00780b20004100360200200228020c2204450d00200441306c450d00200610350b20024180016a24000f0b1044000b1045000bcaf80102517f0d7e230041d0106b2201240020014100360210200141003602080240024002400240024002400240200041086a22022802002203450d00200141f8076a4102722104200141fd026a2105200141d0026a41206a2106200141386a41206a2107200141f8076a41206a2108200141186a41186a2109200141186a41106a210a4100210b034002402002280200220c200b4b0d00200b200c41e099c2001042000b20092000280200200b412c6c220d6a220e41246a290000370300200a200e411c6a290000370300200141186a41086a220f200e41146a2900003703002001200e29000c370318200e280200210c200e280208210e2001410036028008200142013703f807200141f8076a4100200e108a01200128028008211002400240200e41306c22110d0020012802f80721120c010b20012802f807221220104105746a210e0340200e200c290000370000200e41186a200c41186a290000370000200e41106a200c41106a290000370000200e41086a200c41086a290000370000201041016a2110200e41206a210e200c41306a210c201141506a22110d000b0b20012802fc072113024020104102490d00024002402010417f6a221420106c410176220c41ffffff1f71200c470d00200c410674220c417f4c0d00024002400240200c0d00410121150c010b200c10332215450d010b201241206a2116200c4106762117410021184100210c03400240200c41016a221920104f0d002012200c4105746a21112014211a2016210e0340200141f8076a41086a221b201141086a290000370300200141f8076a41106a221c201141106a290000370300200141f8076a41186a221d201141186a290000370300200120112900003703f8072008200e290000370000200841086a200e41086a290000370000200841106a200e41106a290000370000200841186a200e41186a290000370000024020182017470d00024002400240201741016a220c2017490d002017410174221e200c201e200c4b1b220c41ffffff1f71200c470d00200c410674220c4100480d00024020170d00200c0d02410121150c030b20174106742217200c460d02024020170d00200c0d02410121150c030b20152017200c10372215450d120c020b103e000b200c10332215450d100b200c41067621170b201520184106746a220c20012903f807370000200c41386a200141f8076a41386a290300370000200c41306a200141f8076a41306a290300370000200c41286a200141f8076a41286a290300370000200c41206a2008290300370000200c41186a201d290300370000200c41106a201c290300370000200c41086a201b290300370000200e41206a210e201841016a2118201a417f6a221a0d000b0b2014417f6a2114201641206a21162019210c20192010470d000b2018450d02201520184106746a211f2015211e02400340200141386a41386a201e41386a290000370300200141386a41306a201e41306a290000370300200141386a41286a201e41286a2900003703002007201e41206a290000370300200141386a41186a201e41186a220c290000370300200141386a41106a201e41106a220e290000370300200141386a41086a201e41086a22112900003703002001201e290000370338200141f8006a41186a2218200c290000370300200141f8006a41106a220c200e290000370300200141f8006a41086a220e20112900003703002001201e29000037037820014198016a41186a200741186a221129000037030020014198016a41106a200741106a221a29000037030020014198016a41086a200741086a221b2900003703002001200729000037039801200141d0026a41186a22202018290300370300200141d0026a41106a2221200c290300370300200141d0026a41086a2222200e29030037030020062007290000370000200641086a201b290000370000200641106a201a290000370000200641186a2011290000370000200120012903783703d002024002402001280208221b450d00200128020c211c0c010b200141f8076a410041c005109f081a200141e8046a410041e002109f081a41a8081033221b450d0e4100211c201b41003b0106201b4100360200201b41086a200141f8076a41c005109d081a201b41c8056a200141e8046a41e002109d081a2001410036020c2001201b3602080b201e41c0006a211e024002400240024002400240024002400240024002400240024003400240201b2f0106221a410674220e450d00201b41286a210c41002111034002400240200141d0026a200c41606a412010a0082218450d00201841004e0d012011211a0c030b2006200c412010a0082218450d04201841004e0d002011211a0c020b201141016a2111200c41c0006a210c200e41406a220e0d000b0b201c450d02201c417f6a211c201b201a4102746a41a8086a280200211b0c000b0b20022802002219200b4d0d032000280200221d200d6a220c28020841306c221a450d0a201b201141057422236a41c8056a2110200c280200210c4100211803404101210e0240200141f8006a200c460d00200c200141f8006a412010a008450d00024020014198016a200c470d004101210e0c010b200c20014198016a412010a00845210e0b200c41306a210c200e20186a2118201a41506a221a0d000b20184102470d0a2019412c6c210e0340201d210c200e450d0b0240200c410c6a22182010460d00200e41546a210e200c412c6a211d20182010412010a0080d010b0b0240200c41086a280200220e450d00200e41306c211a200141f8006a200c28020022186b211d20014198016a20186b21194100210c0340201d200c460d032018200c6a220e200141f8006a412010a008450d032019200c460d03200e20014198016a412010a008450d03201a200c41306a220c470d000b0b41082124410021250c070b200141b8016a41386a220c200141d0026a41386a290300370300200141b8016a41306a220e200141d0026a41306a290300370300200141b8016a41286a2211200141d0026a41286a290300370300200141b8016a41206a22182006290300370300200141b8016a41186a221c2020290300370300200141b8016a41106a221d2021290300370300200141b8016a41086a22102022290300370300200120012903d0023703b8012001200128021041016a360210200141a0036a41386a2226200c290300370300200141a0036a41306a2227200e290300370300200141a0036a41286a22282011290300370300200141a0036a41206a22242018290300370300200141a0036a41186a2223201c290300370300200141a0036a41106a2225201d290300370300200141a0036a41086a22292010290300370300200120012903b8013703a003200141d0076a41186a222a2009290300370300200141d0076a41106a222b200a290300370300200141d0076a41086a222c200f290300370300200120012903183703d0070240201b2f0106220e410b490d00200141f8076a410041c005109f081a200141e8046a410041e002109f081a41a8081033220c450d19200c41003b0106200c4100360200200c41086a200141f8076a41c005109d08210e200c41c8056a200141e8046a41e002109d082118200141f8076a41086a2210201b41a3036a290000370300200141f8076a41106a2219201b41ab036a290000370300200141f8076a41186a2214201b41b3036a2900003703002008201b41bb036a290000370300200141f8076a41256a2216201b41c0036a2900003700002001201b4188036a2f00003b0188042001201b418a036a2d00003a008a042001201b419b036a2900003703f807201b418b036a280000212d201b418f036a280000212e201b4193036a280000212f201b4197036a2800002130200141c8046a41186a2231201b41a0076a290000370300200141c8046a41106a2232201b4198076a290000370300200141c8046a41086a2233201b4190076a2900003703002001201b290088073703c804200e201b41c8036a201b2f010641796a2211410674109d08210e2018201b41a8076a2011410574109d082118201b41063b0106200c20113b0106200141e0036a41026a221c20012d008a043a0000200141e8046a41086a22342010290300370300200141e8046a41106a22352019290300370300200141e8046a41186a22362014290300370300200141e8046a41206a22372008290300370300200141e8046a41256a22382016290000370000200120012f0188043b01e003200120012903f8073703e804200141a8046a41186a22392031290300370300200141a8046a41106a223a2032290300370300200141a8046a41086a223b2033290300370300200120012903c8043703a80402400240201a4107490d00200e201a417a6a221d4106746a200e201a41796a221a4106746a220e201141ffff0371201a6b410674109e081a200e41386a2026290300370000200e41306a2027290300370000200e41286a2028290300370000200e41206a2024290300370000200e41186a2023290300370000200e41106a2025290300370000200e41086a2029290300370000200e20012903a0033700002018201d4105746a2018201a4105746a220e200c2f0106201a6b410574109e081a200e41186a202a290300370000200e41106a202b290300370000200e41086a202c290300370000200e20012903d007370000200c200c2f010641016a3b01060c010b201b41086a220e201a41016a22114106746a200e201a4106746a220e201b2f0106201a6b410674109e081a200e41386a2026290300370000200e41306a2027290300370000200e41286a2028290300370000200e41206a2024290300370000200e41186a2023290300370000200e41106a2025290300370000200e41086a2029290300370000200e20012903a003370000201b41c8056a220e20114105746a200e201a4105746a220e201b2f0106201a6b410574109e081a200e41186a202a290300370000200e41106a202b290300370000200e41086a202c290300370000200e20012903d007370000201b201b2f010641016a3b01060b200520012903a804370000200141f4076a41026a220e201c2d00003a000020222034290300370300202120352903003703002020203629030037030020062037290300370300200141d0026a41256a22282038290000370000200541086a2211203b290300370000200541106a2218203a290300370000200541186a221a2039290300370000200120012f01e0033b01f407200120012903e8043703d002200141cc026a41026a223c200e2d00003a000020014198026a41086a223d202229030037030020014198026a41106a223e202129030037030020014198026a41186a223f202029030037030020014198026a41206a2240200629030037030020014198026a41256a22412028290000370000200120012f01f4073b01cc02200120012903d00237039802200141f8016a41186a2242201a290000370300200141f8016a41106a22432018290000370300200141f8016a41086a22442011290000370300200120052900003703f8010240201b28020022180d004100211d200141086a210e200c21110c0a0b201b2f0104212641002145200c2146034020014184046a41026a2247203c2d00003a00002022203d2903003703002021203e2903003703002020203f2903003703002006204029030037030020282041290000370000200120012f01cc023b01840420012001290398023703d00220014188046a41186a2248204229030037030020014188046a41106a2249204329030037030020014188046a41086a224a2044290300370300200120012903f8013703880441000d03202641ffff0371211c02400240024020182f0106220c410b490d002004410041d208109f081a41d8081033221a450d1d201a4100360200201a41046a200141f8076a41d408109d081a200141d0076a41026a224b2018418a036a2d00003a00002010201841a3036a2900003703002019201841ab036a2900003703002014201841b3036a2900003703002008201841bb036a2900003703002016201841c0036a290000370000200120184188036a2f00003b01d00720012018419b036a2900003703f8072018418b036a280000214c2018418f036a280000214d20184193036a280000214e20184197036a280000214f2031201841a0076a290000370300203220184198076a290000370300203320184190076a29000037030020012018290088073703c804201a41086a201841c8036a20182f0106220e41796a220c410674109d082150201a41c8056a201841a8076a200c410574109d082151201a41a8086a201841c4086a200e417a6a221d410274109d082127201841063b0106201a200c3b01060240201d450d004100210c2027210e0340200e2802002211200c3b01042011201a360200200e41046a210e201d200c41016a220c470d000b0b2034201029030037030020352019290300370300203620142903003703002037200829030037030020382016290000370000203b2033290300370300203a203229030037030020392031290300370300200120012f01d0073b01f407200120012903f8073703e804200120012903c8043703a8042001204b2d00003a00f607200141cc076a41026a221d20012d00f6073a00002010203429030037030020192035290300370300201420362903003703002008203729030037030020162038290000370000200120012f01f4073b01cc07200120012903e8043703f807202a2039290300370300202b203a290300370300202c203b290300370300200120012903a8043703d007202641ffff037122264107490d012050201c417a6a22114106746a2050201c41796a220c4106746a220e201a2f0106200c6b410674109e081a200e203036000f200e202f36000b200e202e360007200e202d360003200e41026a20472d00003a0000200e20012f0184043b0000200e20012903d002370013200e411b6a2022290300370000200e41236a2021290300370000200e412b6a2020290300370000200e41336a2006290300370000200e41386a2028290000370000205120114105746a2051200c4105746a220e201a2f01062226200c6b410574109e081a200e41186a2048290300370000200e41106a2049290300370000200e41086a204a290300370000200e200129038804370000201a202641016a220e3b0106201c410274222620276a416c6a202720114102746a221c200e41ffff037120116b410274109e081a201c20463602002011201a2f0106221c4b0d02201a20266a4190086a210e0340200e2802002211200c41016a220c3b01042011201a360200200e41046a210e200c201c490d000c030b0b201841086a220e201c41016a22114106746a200e201c4106746a220e200c201c6b410674109e081a200e203036000f200e202f36000b200e202e360007200e202d360003200e41026a20472d00003a0000200e20012f0184043b0000200e20012903d002370013200e411b6a2022290300370000200e41236a2021290300370000200e412b6a2020290300370000200e41336a2006290300370000200e41386a2028290000370000201841c8056a220c20114105746a200c201c4105746a220c20182f0106220e201c6b410574109e081a200c41186a2048290300370000200c41106a2049290300370000200c41086a204a290300370000200c2001290388043700002018200e41016a220c3b0106201c410274201841a8086a220e6a41086a200e20114102746a220e200c41ffff037120116b410274109e081a200e20463602000240201c20182f0106221a4f0d0020182011417f6a220c4102746a41ac086a210e0340200e2802002211200c41016a220c3b010420112018360200200e41046a210e200c201a490d000b0b41001a200141086a1a201b1a0c0d0b201841086a220c201c41016a220e4106746a200c201c4106746a220c20182f0106201c6b410674109e081a200c203036000f200c202f36000b200c202e360007200c202d360003200c41026a20472d00003a0000200c20012f0184043b0000200c20012903d002370013200c411b6a2022290300370000200c41236a2021290300370000200c412b6a2020290300370000200c41336a2006290300370000200c41386a2028290000370000201841c8056a220c200e4105746a200c201c4105746a220c20182f01062211201c6b410574109e081a200c41186a2048290300370000200c41106a2049290300370000200c41086a204a290300370000200c2001290388043700002018201141016a220c3b0106201c4102742227201841a8086a22116a41086a2011200e4102746a2211200c41ffff0371200e6b410274109e081a20112046360200202620182f010622114f0d00201820276a41ac086a210c0340200c280200220e201c41016a221c3b0104200e2018360200200c41046a210c2011201c470d000b0b204541016a210c20014180046a41026a220e201d2d00003a000020292010290300370300202520192903003703002023201429030037030020242008290300370300200141a0036a41256a22112016290000370000200141e0036a41086a221c202c290300370300200141e0036a41106a221d202b290300370300200141e0036a41186a2226202a290300370300200120012f01cc073b018004200120012903f8073703a003200120012903d0073703e003203c200e2d00003a0000203d2029290300370300203e2025290300370300203f20232903003703002040202429030037030020412011290000370000200120012f0180043b01cc02200120012903a00337039802204220262903003703002043201d2903003703002044201c290300370300200120012903e0033703f80102402018280200220e0d00204c212d200141086a220e1a20181a204f2130204e212f204d212e200c211d201a21110c0b0b20182f01042126200141086a1a204c212d20181a204f2130204e212f204d212e200e2118201a2146200c21450c000b0b201b41086a220c201a41016a22114106746a200c201a4106746a220c200e201a6b410674109e081a200c41386a2026290300370000200c41306a2027290300370000200c41286a2028290300370000200c41206a2024290300370000200c41186a2023290300370000200c41106a2025290300370000200c41086a2029290300370000200c20012903a003370000201b41c8056a220c20114105746a200c201a4105746a220c201b2f0106201a6b410574109e081a200c41186a202a290300370000200c41106a202b290300370000200c41086a202c290300370000200c20012903d007370000201b201b2f010641016a3b01060c090b200141f8076a41086a22292018200c6a220e41086a290300370300200141f8076a41106a222a200e41106a290300370300200141f8076a41186a222b200e41186a2903003703002001200e2903003703f807200e41286a2903002152200e41206a2903002153413010332224450d0c20242053370320202420012903f807370300202441286a2052370300202441186a202b290300370300202441106a202a290300370300202441086a202929030037030020014281808080103702ec04200120243602e8040240201a41506a200c470d0020012802ec0421250c060b200e41306a211d2018201a6a220e41506a21204101211a0340201d210c024002400340200141f8006a200c460d01200c200141f8006a412010a008450d0120014198016a200c460d01200c20014198016a412010a008450d01200e200c41306a220c470d000c020b0b200c41286a2903002152200c41206a2903002153200141c8046a41186a2219200c41186a290300370300200141c8046a41106a2214200c41106a290300370300200141c8046a41086a2216200c41086a2903003703002001200c2903003703c8040240201a20012802ec04470d00200141e8046a201a410110880120012802e80421240b200c41306a211d2024201a41306c6a221820012903c80437030020162903002154201429030021552019290300215620182053370320201841286a2052370300201841186a2056370300201841106a2055370300201841086a20543703002001201a41016a221a3602f0042020200c470d010b0b20012802ec042125201a4102490d05201a4102470d0441e0001033221d450d0c2001420237029c022001201d3602980202402002280200220c200b4d0d000240024002402000280200200d6a220c28020841306c221a0d004102210c0c010b200c280200210c41002118034002400240200141f8006a200c460d00200c200141f8006a412010a008210e20014198016a200c460d00200e450d00200c20014198016a412010a0080d010b200141f8016a41186a2219200c41186a290300370300200141f8016a41106a2214200c41106a290300370300200141f8016a41086a2216200c41086a2903003703002001200c2903003703f801200c41286a2903002152200c41206a290300215302402018200128029c02470d0020014198026a20184101108801200128029802211d20012802a00221180b201d201841306c6a220e20012903f801370300201629030021542014290300215520192903002156200e2053370320200e41286a2052370300200e41186a2056370300200e41106a2055370300200e41086a20543703002001201841016a22183602a0020b200c41306a210c201a41506a221a0d000b20184102460d01200128029c02210c0b200c450d08200c41306c450d08201d10350c080b0240201d2024460d002024201d412010a008450d00200141f8076a41286a220c202441286a220e2903003703002008202441206a2218290300370300202b202441186a221a290300370300202a202441106a22192903003703002029202441086a2214290300370300200120242903003703f807200e202441d8006a22162903003703002018202441d0006a220e290300370300201a202441c8006a22182903003703002019202441c0006a221a2903003703002014202441386a2219290300370300202420242903303703002016200c290300370300200e20082903003703002018202b290300370300201a202a29030037030020192029290300370300202420012903f8073703300b2001427f3703f0042001427f3703e8044100211a200141003602d0072001410036028008200142083703f807200141f8076a4100410410880120012802f8072235200128028008221641306c6a210c0240201d450d00200141e8046a41086a290300215420012903e8042157410021194100211a03400240201d20196a220e41206a2903002253205756200e41286a290300225220545620522054511b0d00200120533703e8042001201a3602d007200120523703f00420532157205221540b200c20196a2218200e290300370300200e41086a2903002155200e41106a2903002156200e41186a2903002158201841286a2052370300201841206a2053370300201841186a2058370300201841106a2056370300201841086a2055370300201a41016a211a201941306a221941e000470d000b2016201a6a2116200c20196a210c0b02402024450d00202441e0006a221d2024460d00200141e8046a41086a290300215420012903e80421572024210e0340200e41306a21180240200e41206a2903002253205756200e41286a290300225220545620522054511b0d00200120533703e8042001201a3602d007200120523703f00420532157205221540b200c200e290300370300200e41086a2903002155200e41106a2903002156200e41186a2903002158200c41286a2052370300200c41206a2053370300200c41186a2058370300200c41106a2056370300200c41086a2055370300200c41306a210c201a41016a211a201641016a21162018210e201d2018470d000b0b20012802fc072131200141003602c001200142043703b801200141003602a803200142043703a00320012802d007210c200141a0036a4100410110860120012802a003222820012802a803220e4102746a200c3602002001200e41016a220c3602a80302400240024020012802d00722184102490d00200141b8016a4100410110860120012802b80120012802c001220e4102746a201841017141037322183602002001200e41016a220e3602c0012018417e6a21180240200c20012802a403470d00200141a0036a200c410110860120012802a003212820012802a803210c0b2028200c4102746a20183602002001200c41016a22343602a80320012802d007417e6a210c200e20012802bc01470d02200141b8016a200e41011086010c010b200141b8016a4100410110860120012802b80120012802c001220e4102746a410120186b3602002001200e41016a220e3602c001410320186b21180240200c20012802a403470d00200141a0036a200c410110860120012802a003212820012802a803210c0b2028200c4102746a20183602002001200c41016a22343602a80320012802d00741026a210c200e20012802bc01470d01200141b8016a200e41011086010b20012802c001210e0b20012802b8012227200e4102746a200c3602002001200e41016a220c3602c00141041033222c450d0d200142013702d4022001202c3602d00220012802bc0121360240200c450d002027200c4102746a212620272122034002400240202228020022214102490d00202b201041186a290000370300202a201041106a2900003703002029201041086a290000370300200120102900003703f8070c010b202b2009290300370300202a200a2903003703002029200f290300370300200120012903183703f8070b02402002280200220c450d0020002802002219200c412c6c6a21142035202141306c6a211a034002400240200141f8076a2019410c6a220c460d00200c200141f8076a412010a0080d010b2019280208210c0240201620214d0d00200c41306c210e4100211820192802002220210c02400340200e450d03201a200c460d01200c201a412010a008211d201841016a2118200e41506a210e200c41306a210c201d0d000b201d4541016a41017120186a417f6a21180b2020201841306c6a220c427f200c290320225220012903e8047c22532053205254220e200c41286a220c2903002252200141e8046a41086a2903007c200ead7c225320525420532052511b220e1b370320200c427f2053200e1b3703000c010b200c450d002021201641909ac2001042000b2019412c6a22192014470d000b0b202241046a22222026470d000b0b0240203641ffffffff0371450d00202710350b20012802a40321320240024020340d00410021270c010b202820344102746a21364100212720282134034002400240203428020022224102490d00202b201041186a290000370300202a201041106a2900003703002029201041086a290000370300200120102900003703f8070c010b202b2009290300370300202a200a2903003703002029200f290300370300200120012903183703f8070b02402002280200220c450d0020002802002219200c412c6c6a21202035202241306c6a211a034002400240200141f8076a2019410c6a220c460d00200c200141f8076a412010a0080d010b201941086a2226280200211402400240201620224d0d00201441306c210e4100211820192802002221210c02400340200e450d04201a200c460d01200c201a412010a008211d201841016a2118200e41506a210e200c41306a210c201d0d000b201d4541016a41017120186a417f6a21180b42002021201841306c6a220c290320225220012903e80422547d22532053205256200c41286a2903002253200141e8046a41086a2903007d2052205454ad7d225220535620522053511b220e1b225342002052200e1b225284500d01200c41206a220c2053370300200c20523703080c020b2014450d012022201641a09ac2001042000b200c200c41306a20142018417f736a41306c109e081a20262014417f6a3602000240202720012802d402470d00200141d0026a2027410110860120012802d80221270b20012802d002222c20274102746a20223602002001202741016a22273602d8020b2019412c6a22192020470d000b0b203441046a22342036470d000b0b0240203241ffffffff0371450d00202810350b202c417c6a21182027410274220c210e024003400240200e0d00410021180c020b200e417c6a210e201841046a221828020041014b0d000b0b20012802d402211d202c210e024003400240200c0d004100210c0c020b200c417c6a210c200e280200211a200e41046a210e201a4102490d000b4101210c0b0240201d41ffffffff0371450d00202c10350b0240024020180d00200c450d0120102001290318370000201041186a2009290300370000201041106a200a290300370000201041086a200f2903003700000c060b200c450d0520012001280210417f6a360210201b41086a210c02400240201c450d00201c417f6a210e200c20114106746a2118201b20114102746a41a8086a280200210c02400340200c2f01062111200e450d01200e417f6a210e200c20114102746a41a8086a280200210c0c000b0b200c410020111b221b41086a220e2011417f6a410020111b22114106746a220c2900002152200c2900082153200c2900102154200c41186a2900002155200c2900202156200c41286a2900002158200c41306a2900002157200c41386a290000215941012137200c200e201141016a221a4106746a2011417f73220e201b2f01066a410674109e081a201b41c8056a221c20114105746a220c290000215a200c290008215b200c290010215c200c41186a290000215d200c201c201a4105746a200e201b2f01066a410574109e081a201b201b2f0106417f6a3b0106201841386a2059370000201841306a2057370000201841286a205837000020182056370020201841186a2055370000201820543700102018205337000820182052370000201041186a205d3700002010205c3700102010205b3700082010205a370000201b2f0106210c0c010b200c20114106746a200c201141016a220e4106746a2011417f73220c201b2f01066a410674109e081a201b41c8056a221820236a2018200e4105746a200c201b2f01066a410574109e081a201b201b2f0106417f6a220c3b0106410021370b200c41ffff037141044b0d0441002122200141086a210e201b210c410021200240024002400240024002400240024002400240024002400240024002400340200c280200221a450d1402400240200c33010422524200520d0041002121201a4100201a2f0106220c1b211a42002052422086200c1b200ead8421520c010b2052422086200ead844280808080707c2152410121210b02400240201a41a8086a220e2052422088a7221841016a220c41027422276a221c28020022192f01062210200e201841027422236a2226280200221d2f010622146a2233410b490d0020210d052010450d01201941c0006a2900002152201941386a2900002153201941306a2900002154201941286a2900002155201941206a2900002156201941186a2900002158201941106a290000215720192900082159201941086a201941c8006a201041067441406a109e081a201941e0056a290000215a201941d8056a290000215b201941d0056a290000215c20192900c805215d201941c8056a201941e8056a201041057441606a109e081a20200d034100211d0c040b202041016a2120201a2f01062116200141f8076a41386a222c201a41086a223420184106746a220e41386a290000370300200141f8076a41306a2236200e41306a290000370300200141f8076a41286a2228200e41286a2900003703002008200e41206a290000370300202b200e41186a290000370300202a200e41106a2900003703002029200e41086a2900003703002001200e2900003703f807200e2034200c4106746a20162018417f7322346a410674109e081a201d41086a223220144106746a220e41386a202c290300370000200e41306a2036290300370000200e41286a2028290300370000200e41206a2008290300370000200e41186a202b290300370000200e41106a202a290300370000200e41086a2029290300370000200e20012903f8073700002032201441016a22164106746a201941086a2010410674109d081a201a2f0106212c200141c8046a41186a2236201a41c8056a222820184105746a220e41186a290000370300200141c8046a41106a2218200e41106a290000370300200141c8046a41086a2232200e41086a2900003703002001200e2900003703c804200e2028200c4105746a2034202c6a410574109e081a201d41c8056a222c20144105746a220e41186a2036290300370000200e41106a2018290300370000200e41086a2032290300370000200e20012903c804370000202c20164105746a201941c8056a2010410574109d081a201c202641086a412c20276b109e081a0240200c201a2f0106221c4f0d00201a20236a41ac086a210e0340200e2802002218200c3b01042018201a360200200e41046a210e201c200c41016a220c470d000b201a2f0106211c0b201a201c417f6a3b0106201d2010201d2f01066a41016a3b0106024020204102490d00201d20164102746a41a8086a201941a8086a201041027441046a109d081a2016203341026a4f0d00201041016a2118201d20144102746a41ac086a210c2016210e0340200c280200221c200e3b0104201c201d360200200c41046a210c200e41016a210e2018417f6a22180d000b0b20191035024020222021417f73724101710d0020204101470d102016410020211b20116a2111201a20236a41a8086a280200211b0b2052a7210e201a220c2f01062218450d064101212220184105490d010c150b0b41e4dec600412041c086cc00103f000b20192802a808211d201941a8086a220c201941ac086a2010410274109e081a4100210e201d41003602000340200c280200221c200e3b0104201c2019360200200c41046a210c2010200e41016a220e470d000b2020417f6a211c20192f010621100b20192010417f6a3b0106201a20184106746a220c41206a220e290000215e200e2056370000200c41186a220e2900002156200e2058370000200c41106a220e2900002158200e2057370000200c41086a220e2900002157200e2059370000200c41c0006a220e2900002159200e2052370000200c41386a220e2900002152200e2053370000200c41306a220e2900002153200e2054370000200c41286a220c2900002154200c2055370000201a20184105746a220c41d8056a220e2900002155200e205b370000200c41d0056a220e290000215b200e205c370000200c41c8056a220e290000215c200e205d370000200c41e0056a220c290000215d200c205a3700002026280200210c02402020450d00201d450d052020417f6a201c470d06200c2f01062218410a4b0d07200c20184106746a220e41c0006a2059370000200e41386a2052370000200e41306a2053370000200e41286a2054370000200e41206a205e370000200e41186a2056370000200e41106a2058370000200e41086a2057370000200c20184105746a220e41e0056a205d370000200e41d8056a2055370000200e41d0056a205b370000200e41c8056a205c370000200c201841016a220e4102746a41a8086a2218201d360200200c200c2f010641016a3b010620182802002218200e3b01042018200c3602000c020b200c2f01062218410b4f0d07200c20184106746a220e41c0006a2059370000200e41386a2052370000200e41306a2053370000200e41286a2054370000200e41206a205e370000200e41186a2056370000200e41106a2058370000200e41086a2057370000200c20184105746a220e41d8056a2055370000200e41d0056a205b370000200e41c8056a205c370000200e41e0056a205d370000200c200c2f010641016a3b01060c010b0240024002402014450d00201d2014417f6a220e4105746a220c41e0056a2900002152200c41d8056a2900002153200c41d0056a2900002154200c41c8056a2900002155201d200e4106746a220c41c0006a2900002156200c41386a2900002158200c41306a2900002157200c41286a2900002159200c41206a290000215a200c41186a290000215b200c41106a290000215c200c41086a290000215d20200d014100210e0c020b41e4dec600412041c086cc00103f000b201d20144102746a41a8086a280200220e41003602002020417f6a2110201d2f010621140b201d2014417f6a3b0106201a20184106746a220c41206a221d290000215e201d205a370000200c41186a221d290000215a201d205b370000200c41106a221d290000215b201d205c370000200c41086a221d290000215c201d205d370000200c41c0006a221d290000215d201d2056370000200c41386a221d2900002156201d2058370000200c41306a221d2900002158201d2057370000200c41286a220c2900002157200c2059370000201a20184105746a220c41d8056a2218290000215920182053370000200c41d0056a2218290000215320182054370000200c41c8056a2218290000215420182055370000200c41e0056a220c2900002155200c2052370000201c280200211802402020450d00200e450d082020417f6a2010470d09024020182f0106220c410a4b0d00201841c8006a201841086a200c410674109e081a201841386a2056370000201841306a2058370000201841286a2057370000201841186a205a370000201841106a205b3700002018205c370008201841c0006a205d370000201841206a205e370000201841e8056a201841c8056a200c410574109e081a201841e0056a2055370000201841d8056a2059370000201841d0056a2053370000201820543700c805201841ac086a201841a8086a220c20182f010641027441046a109e081a2018200e3602a808201820182f010641016a220e3b0106200e41ffff037141016a211c4100210e0340200c280200221a200e3b0104201a2018360200200c41046a210c201c200e41016a220e470d000c030b0b41af84cc00412741c086cc00103f000b20182f0106220c410b4f0d09201841c8006a201841086a200c410674109e081a201841386a2056370000201841306a2058370000201841286a2057370000201841186a205a370000201841106a205b3700002018205c370008201841c0006a205d370000201841206a205e370000201841e8056a201841c8056a200c410574109e081a201841e0056a2055370000201841d8056a2059370000201841d0056a2053370000201820543700c805201820182f010641016a3b01060b2022417f732021710d010c0f0b0240200e2802042218450d00200e280200221a2802a808210c200e2018417f6a360204200e200c360200200c4100360200201a10350c0f0b41c3dec600412141c086cc00103f000b2011201b2f0106490d084100210e024003400240201b280200220c0d00410021114100210c0c020b200e41016a210e201b2f01042111200c211b2011200c2f01064f0d000b0b201141016a21110240200e0d00200c211b0c0e0b200c20114102746a41a8086a280200211b41002111200e417f6a220c450d0d0340201b2802a808211b200c417f6a220c0d000c0e0b0b41958dcc00412b41ecdfc600103f000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b41af84cc00412741c086cc00103f000b41958dcc00412b4184dfc600103f000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b41cfa2cc00412841c086cc00103f000b201141016a21110c040b41b09ac200412941c086cc00103f000b200b200c41809ac2001042000b41d684cc00413541c086cc00103f000b200b201941f099c2001042000b2037450d002011201b2f0106490d000340201b280200220c450d01201b2f0104210e200c211b200e200c2f01064f0d000b0b02402031450d00203141306c450d00203510350b200128029c02220c450d00200c41306c450d0020012802980210350b2025450d03202541306c450d03202410350c030b20102001290318370000201041186a2009290300370000201041106a200a290300370000201041086a200f2903003700000b2025450d01202541306c450d01202410350c010b2004410041d208109f081a41d8081033220c450d0f200c4100360200200c41046a200141f8076a41d408109d081a200c200e28020022183602a808200e200c360200200e200e280204221a41016a360204201841003b01042018200c360200200141d0026a41026a221c203c2d00003a00002010203d2903003703002019203e2903003703002014203f2903003703002008204029030037030020162041290000370000200120012f01cc023b01d00220012001290398023703f807203620422903003703002035204329030037030020342044290300370300200120012903f8013703e804201a201d470d01200c2f01062218410a4b0d03200c20184106746a220e410a6a201c2d00003a0000200e41086a20012f01d0023b0000200e41176a2030360000200e41136a202f360000200e410f6a202e360000200e410b6a202d360000200e41c0006a2016290000370000200e413b6a2008290300370000200e41236a2010290300370000200e411b6a20012903f807370000200e41336a2014290300370000200e412b6a2019290300370000200c20184105746a220e41e0056a2036290300370000200e41d8056a2035290300370000200e41d0056a2034290300370000200e41c8056a20012903e804370000200c201841016a220e4102746a41a8086a2011360200200c200e3b01062011200c3602002011200e3b010441001a201b1a0b201e201f470d010c050b0b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b1045000b1044000b201741ffffff1f71450d00201510350b200b41016a210b0240201341ffffff3f71450d00201210350b200b2003470d000b2001280208220c0d010b2001418c086a41003602002001410036029808200141003602fc070c010b2001280210211702400240200128020c22110d00200c210e0c010b2011210e200c2108034020082802a8082108200e417f6a220e0d000b200c210e0340200e200e2f01064102746a41a8086a280200210e2011417f6a22110d000b2008210c0b20014194086a200e2f0106360200200141f8076a41186a41003602002001418c086a200e3602002001201736029808200141003602f807200141003602880820014200370380082001200c3602fc0702402017450d00200141a0036a41186a211a200141b0036a211b200141a8036a211c4100211841002111034020012017417f6a221736029808200c450d034100210802402018200c2f0106490d00034002400240200c280200220e0d002011ad21524100210e0c010b200841016a2108200c3301044220862011ad8421520b200c10352052a72111200e210c2052422088a72218200e2f01064f0d000b200e210c0b201a200c20184105746a220e41e0056a290000370300201b200e41d8056a290000370300201c200e41d0056a2900003703002001200e41c8056a2900003703a003201841016a211802402008450d00200c20184102746a41a8086a280200210c410021182008417f6a220e450d000340200c2802a808210c200e417f6a220e0d000b0b200120183602840820012011360280082001200c3602fc07200141003602f80720170d000b0b200c450d00200c280200210e200c1035200e450d000340200e280200210c200e1035200c210e200c0d000b0b200141003602d004200141003602c80402400240200041086a22322802002204450d00200141c8046a41086a21412000280200210c200141e8046a41186a2139200141d0076a41106a2146200141d0076a41086a2147200141d0026a41016a222e41286a2149202e41206a214a200141f5026a21452004210e4100212303400240200e20234b0d002023200e41dc9ac2001042000b200141d0076a41186a2248200c2023412c6c22406a221141246a29000037030020462011411c6a2900003703002047201141146a2900003703002001201129000c3703d00702402011280208450d00410021370340200c20406a280200210c200141386a41186a22152048290300370300200141386a41106a22062046290300370300200141386a41086a221e2047290300370300200120012903d007370338200141003a0058200141b8016a41186a2210200c203741306c6a220c41186a290000370300200141b8016a41106a2219200c41106a290000370300200141b8016a41086a2207200c41086a2900003703004101211d200141013a00d8012001200c2900003703b8010240024020012802c80422170d004100210c410021140c010b2017211a20012802cc04221b211c02400340201a41286a210c201a2f0106221d41216c210e41002108024002400340200821110240200e0d00201d21110c020b02400240200141386a200c41606a412010a0082208450d0041012118200841004e0d010c030b200c2d00002208450d03417f410120081b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201c0d004101211d0c030b201c417f6a211c201a20114102746a41a0036a280200211a0c010b0b4100211d0b2017211a02400340201a41286a210c201a2f0106221c41216c210e41002108024002400340200821110240200e0d00201c21110c020b02400240200141b8016a200c41606a412010a0082208450d0041012118200841004e0d010c030b200c2d000022084101460d03417f4101200841014b1b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201b0d00410021140c030b201b417f6a211b201a20114102746a41a0036a280200211a0c010b0b201a20114102746a41f4026a21140b2017210c0b200141a0036a41186a223a2015290300370300200141a0036a41106a223b2006290300370300200141a0036a41086a222d201e290300370300200120012903383703a003200141003a00c00302400240200c450d0020012802cc04211a0c010b200141f8076a410041eb02109f081a20494100360000204a4200370000202e41186a4200370000202e41106a4200370000202e41086a4200370000202e420037000041a00310332217450d094100211a201741003b010620174100360200201741086a200141f8076a41eb02109d081a20174198036a204529000037000020174193036a200141d0026a41206a2900003700002017418b036a200141d0026a41186a29000037000020174183036a200141d0026a41106a290000370000201741fb026a200141d0026a41086a290000370000201720012900d0023700f302200141003602cc04200120173602c8040b024002400340201741286a210c20172f0106221b41216c210e4100210802400340200821110240200e0d00201b21110c020b02400240200141a0036a200c41606a412010a0082208450d0041012118200841004e0d010c030b200c2d00002208450d04417f410120081b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201a450d00201a417f6a211a201720114102746a41a0036a28020021170c010b0b203920012903a003370000203941086a202d290300370000203941106a203b290300370000203941186a203a290300370000203941206a200141a0036a41206a2d00003a0000200120413602fc04200120113602f804200120173602f0044100210c200141003602ec042001200141c8046a3602f4040c010b200120413602fc04200120113602f804200120173602f0042001201a3602ec042001200141c8046a3602f4044101210c0b2001200c3602e804200141f8076a41086a2234201e290300370300200141f8076a41106a22352006290300370300200141f8076a41186a22362015290300370300200141f8076a41206a221c200141386a41206a2d00003a0000200120012903383703f80741341033220c450d08200c4200370208200c428180808010370200200c20012903f807370210200c20012f00d0023b0031200c41186a2034290300370200200c41206a2035290300370200200c41286a2036290300370200200c41306a201c2d00003a0000200c41336a200141d0026a41026a22152d00003a000002400240024002400240024002400240200141e8046a200c10ac02280200222628020041016a220c41014d0d002026200c360200203a2010290300370300203b2019290300370300202d2007290300370300200120012903b8013703a003200141013a00c0030240024020012802c8042217450d0020012802cc04211a0c010b200141f8076a410041eb02109f081a20494100360000204a4200370000202e41186a4200370000202e41106a4200370000202e41086a4200370000202e420037000041a00310332217450d114100211a201741003b010620174100360200201741086a200141f8076a41eb02109d081a20174198036a204529000037000020174193036a200141d0026a41206a2900003700002017418b036a200141d0026a41186a29000037000020174183036a200141d0026a41106a290000370000201741fb026a200141d0026a41086a290000370000201720012900d0023700f302200141003602cc04200120173602c8040b024002400340201741286a210c20172f0106221b41216c210e4100210802400340200821110240200e0d00201b21110c020b02400240200141a0036a200c41606a412010a0082208450d0041012118200841004e0d010c030b200c2d000022084101460d04417f4101200841014b1b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201a450d00201a417f6a211a201720114102746a41a0036a28020021170c010b0b203920012903a003370000203941086a202d290300370000203941106a203b290300370000203941186a203a290300370000203941206a200141a0036a41206a2d00003a0000200120413602fc04200120113602f804200120173602f0044100210c200141003602ec042001200141c8046a3602f4040c010b200120413602fc04200120113602f804200120173602f0042001201a3602ec042001200141c8046a3602f4044101210c0b2001200c3602e804203420072903003703002035201929030037030020362010290300370300201c200141b8016a41206a2d00003a0000200120012903b8013703f80741341033220c450d10200c4200370208200c428180808010370200200c20012903f807370210200c20012f00d0023b0031200c41186a2034290300370200200c41206a2035290300370200200c41286a2036290300370200200c41306a201c2d00003a0000200c41336a20152d00003a0000200141e8046a200c10ac022802002227280200220e41016a220c41014d0d002027200c360200024002400240024002400240024002400240024002400240024002400240024002400240201d450d0020140d03202628020041016a220c41014d0d122026200c36020020272802080d0b2027417f360208202728020c220c0d014100210c0c020b2014450d03200141f8076a202610ad022001280284082144200128028008214e20012802fc07213820012802f807212f200141f8076a202710ad022001280284082142200128028008214f20012802fc0721300240202f20012802f807223e460d00202f28020841016a220c41004c0d0d202f200c360208203e280208220c41016a220e41004c0d0c203e200e360208202f41106a203e41106a412010a0080d0e202f2d0030203e2d0030470d0e203e200c360208202f202f280208417f6a3602080b20302042410274222b6a211c20382044410274222a6a2111202a0d04410021170c050b200c200c280200417f6a3602000240202728020c220c2802000d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10ae02200c28020c210e0b200e200e280204417f6a360204200c28020c220c2802040d00200c10350b202728020c220c200c280204417f6a360204202728020c220c2802040d00200c10350b202728020841016a210c0b2027200c3602080c130b200e417e4f0d0e2027200e41026a36020020262802080d062026417f36020802400240202628020c220c0d004100210c0c010b200c200c280200417f6a3602000240202628020c220c2802000d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10ae02200c28020c210e0b200e200e280204417f6a360204200c28020c220c2802040d00200c10350b202628020c220c200c280204417f6a360204202628020c220c2802040d00200c10350b202628020841016a210c0b2026200c3602082026202736020c0c130b202628020041016a220c41014d0d0d2026200c36020020272802080d042027417f3602080240202728020c220c0d00202741003602080c120b200c200c280200417f6a3602000240202728020c220c2802000d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10ae02200c28020c210e0b200e200e280204417f6a360204200c28020c220c2802040d00200c10350b202728020c220c200c280204417f6a360204202728020c220c2802040d00200c10350b2027202728020841016a3602080c110b41002117201c210820112118034020302008460d01024002402018417c6a2218280200220c2008417c6a2208280200220e460d00200c28020841016a221a41004c0d05200c201a360208200e280208221a41016a221b41004c0d04200e201b360208200c41106a200e41106a412010a0080d01200c2d0030200e2d0030470d01200e201a360208200c200c280208417f6a3602080b201741016a211720382018470d010c020b0b200e201a360208200c200c280208417f6a3602080b2001410036028008200142043703f807204420176b211a204220176b220b41016a210e024020300d004100210c2038450d0a201a450d0a201a201120386b410276220c200c201a4b1b210c0c0a0b2038450d084100210c410021080240200e450d00200e201c20306b41027622082008200e4b1b21080b0240201a450d00201a201120386b410276220c200c201a4b1b210c0b2008200c6a220c20084f0d09410421144100211841002115203021080340024002402008450d000240200e0d004100210e0c010b200e417f6a210e201c2008460d002008280200220c28020041016a221741014d0d0e200c2017360200200c450d00200841046a21080c010b201a450d0c201120386b410276220c4100200c201a6b22082008200c4b1b220c4d0d0c2011200c4102746b417c6a2211280200220c28020041016a220841014d0d0d200c2008360200200c450d0c201a417f6a211a410021080b0240201520012802fc07470d0002400240024020080d00201a0d01410021170c020b4100211b410021170240200e450d00200e201c20086b41027622172017200e4b1b21170b0240201a450d00201a201120386b410276221b201b201a4b1b211b0b417f2017201b6a221b201b2017491b21170c010b201a201120386b41027622172017201a4b1b21170b200141f8076a2015417f201741016a221b201b2017491b10860120012802f80721140b201420186a200c3602002001201541016a221536028008201841046a21180c000b0b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b203e200c360208202f202f280208417f6a360208204fad4220862030ad842252204ead4220862038ad842253204420424b22151b2254a7211d02400240024002402042204420151b2206410274220e450d00201d200e6a211c41012118201d2111201d21080340024002402018450d00201c20116b41027620184d0d03201120184102746a21110c010b201c2011460d020b2008280200221728020041016a220c41014d0d082017200c3602002011280200220c2802080d02200841046a2108200c417f360208410021184100211a0240200c28020c221b450d00201b201b280200417f6a3602000240200c28020c221a2802000d000240201a28020c221b450d00201b201b280200417f6a360200201a28020c221b2802000d000240201b28020c450d00201b410c6a10ae02201a28020c211b0b201b201b280204417f6a360204201a28020c221a2802040d00201a10350b200c28020c221a201a280204417f6a360204200c28020c221a2802040d00201a10350b200c28020841016a211a0b201141046a2111200c201a360208200c201736020c201c2008470d000b0b2006450d0102402044204220151b22180d0041004100419c9bc2001042000b2053205220151b2252a72217280200221128020041016a220c41014d0d062011200c360200201d280200220c2802080d02200c417f36020802400240200c28020c22080d00410021080c010b20082008280200417f6a3602000240200c28020c22082802000d000240200828020c221a450d00201a201a280200417f6a360200200828020c221a2802000d000240201a28020c450d00201a410c6a10ae02200828020c211a0b201a201a280204417f6a360204200828020c22082802040d00200810350b200c28020c22082008280204417f6a360204200c28020c22082802040d00200810350b200c28020841016a21080b2052422088215220544220882153200c2008360208200c201136020c201841027421112017210c0340200c28020022082008280200417f6a3602000240200c28020022082802000d000240200828020c2218450d0020182018280200417f6a360200200828020c22182802000d000240201828020c450d002018410c6a10ae02200828020c21180b20182018280204417f6a360204200828020c22082802040d00200810350b200c28020022082008280204417f6a360204200c28020022082802040d00200810350b200c41046a210c2011417c6a22110d000b02402052500d002052a7410274450d00201710350b201d210c0340200c28020022112011280200417f6a3602000240200c28020022112802000d000240201128020c2208450d0020082008280200417f6a360200201128020c22082802000d000240200828020c450d002008410c6a10ae02201128020c21080b20082008280204417f6a360204201128020c22112802040d00201110350b200c28020022112011280204417f6a360204200c28020022112802040d00201110350b200c41046a210c200e417c6a220e0d000b02402053500d002053a7410274450d00201d10350b203e203e280200417f6a220c360200203741016a2137200c0d090240203e28020c220c450d00200c200c280200417f6a360200203e28020c220c2802000d000240200c28020c450d00200c410c6a10ae02203e28020c210c0b200c200c280204417f6a360204203e28020c220c2802040d00200c10350b203e203e280204417f6a220c360204200c0d09203e10350c090b41a797cc004110200141a8046a41a08bc50041c897cc001046000b41004100418c9bc2001042000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b0240200e0d004100210c0c010b200e201c20306b410276220c200c200e4b1b210c0b200141f8076a4100200c10860120012802f807221420012802800822154102746a210c02402030450d00200e450d00203020424102746a211b2042417f7320176a21082030210e0340201b200e460d01200e280200221828020041016a221741014d0d0320182017360200200c2018360200201541016a2115200c41046a210c200e41046a210e200841016a221820084f21172018210820170d000b0b02402038450d00201a450d000240201120386b410276220e201a4d0d00200e201a417f736a2208200e4f0d01201120084102746b417c6a21110b20112038460d0003402011417c6a2211280200220e28020041016a220841014d0d03200e2008360200200c200e360200201541016a2115200c41046a210c20382011470d000b0b20012015360280080b20012802fc07215120014198026a41186a224b420037030020014198026a41106a224c420037030020014198026a41086a224d42003703002001420037039802203a4200370300203b4200370300202d4200370300200142003703a0034100211e0240024020150d00427f2152427f2153410021074100212c410021250c010b2015417f6a2116427f215241002107427f21534100212c41002125427f2155427f21544100211a0240024002400240024003402014201a4102746a280200220c28020841016a220e41004c0d01201a41016a211b0240200c2d00300d00200c200e360208200141d0026a41186a221c200c41286a290000370300200141d0026a41106a221d200c41206a290000370300200141d0026a41086a2206200c41186a290000370300200c200c280208417f6a3602082001200c2900103703d0022015201b41002016201a4b1b220c4d0d032014200c4102746a280200220c28020841016a220e41004c0d04200c200e3602082039200c41286a290000370300200141e8046a41106a2210200c41206a290000370300200141e8046a41086a2219200c41186a290000370300200c200c280208417f6a3602082001200c2900103703e8042015201a2015201a1b417f6a220c4d0d052014200c4102746a280200220c28020841016a220e41004c0d06200c200e3602082036200c41286a2900003703002035200c41206a2900003703002034200c41186a290000370300200c200c280208417f6a3602082001200c2900103703f8072032280200412c6c220e2111200028020022082118024003402018210c2011450d010240200141d0026a200c410c6a2217460d00201141546a2111200c412c6a21182017200141d0026a412010a0080d010b0b200c41086a28020041306c2111200c280200211803402018210c2011450d010240200141e8046a200c460d00201141506a2111200c41306a2118200c200141e8046a412010a0080d010b0b2052200c41206a2903002258582054200c41286a29030022565820542056511b0d00204b2039290300370300204c2010290300370300204d2019290300370300202d2006290300370300203b201d290300370300203a201c290300370300200120012903e80437039802200120012903d0023703a0034101212c2058215220562153201a2107201a212520562155205621540b03402008210c200e450d010240200141d0026a200c410c6a2211460d00200e41546a210e200c412c6a21082011200141d0026a412010a0080d010b0b200c41086a28020041306c210e200c280200211103402011210c200e450d010240200141f8076a200c460d00200e41506a210e200c41306a2111200c200141f8076a412010a0080d010b0b205521542052200c41206a2903002258582055200c41286a29030022565820552056511b0d00204b2036290300370300204c2035290300370300204d2034290300370300202d2006290300370300203b201d290300370300203a201c290300370300200120012903f80737039802200120012903d0023703a0034100212c2058215220562153201a2107201a212520562155205621540b201b211a201b2015460d060c000b0b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b200c201541ac9bc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b200c201541bc9bc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b200141003602d802200142043703d0022025202c6a21500240024020150d0041012119417f213f0c010b2015417f6a213f41012119205041017121434100211e202c212041002106024003400240024002400240024002400240201420064102746a2229280200221028020841016a220c41004c0d00200641016a21222010200c36020820102d00300d0620152006201520061b417f6a220c4d0d012014200c4102746a2233280200222828020841016a220c41004c0d022028200c36020802402032280200220c0d002022210c2006211b0c060b20002802002217200c412c6c6a211d202841106a210e201041106a211a202c45200620074671213120430d034100211c2006211b034002400240201a2017410c6a220c460d00200c201a412010a0080d010b201741086a2224280200222141306c21114100210820172802002216210c024003402011450d02200e200c460d01200c200e412010a0082118200841016a2108201141506a2111200c41306a210c20180d000b20184541016a41017120086a417f6a21080b0240427f2016200841306c6a220c290320225520527c225420542055542211200c41286a290300225420537c2011ad7c225620545420562054511b22111b4200205520527d22582058205556205420537d2055205254ad7d225520545620552054511b22181b201b41017122161b2254427f205620111b4200205520181b20161b225584500d00200c41206a220c2054370300200c20553703080c010b200c200c41306a20212008417f736a41306c109e081a20242021417f6a36020041002120410020192023201c461b211902402031450d00200721252007211b0c010b2029280200220c28020041016a221141014d0d0c200c20113602002033280200221128020041016a220841014d0d0c201120083602000240201e20012802d402470d00200141d0026a201e410110900120012802d802211e0b20012802d002201e4103746a220820113602042008200c3602002001201e41016a221e3602d802202c2120200721252006211b0b201c41016a211c2017412c6a2217201d470d000c050b0b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b200c201541cc9bc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b4100211c2006211b034002400240201a2017410c6a220c460d00200c201a412010a0080d010b201741086a2224280200222141306c21114100210820172802002216210c024003402011450d02200e200c460d01200c200e412010a0082118200841016a2108201141506a2111200c41306a210c20180d000b20184541016a41017120086a417f6a21080b024042002016200841306c6a220c290320225520527d22542054205556200c41286a290300225420537d2055205254ad7d225620545620562054511b22111b427f205520527c225820582055542218205420537c2018ad7c225520545420552054511b22181b201b41017122161b22544200205620111b427f205520181b20161b225584500d00200c41206a220c2054370300200c20553703080c010b200c200c41306a20212008417f736a41306c109e081a20242021417f6a36020041002120410020192023201c461b211902402031450d00200721252007211b0c010b2029280200220c28020041016a22114102490d08200c20113602002033280200221128020041016a22084102490d08201120083602000240201e20012802d402470d00200141d0026a201e410110900120012802d802211e0b20012802d002201e4103746a220820113602042008200c3602002001201e41016a221e3602d802202c2120200721252006211b0b201c41016a211c2017412c6a2217201d470d000b0b201b41016a210c0b024002400240024002402015200c4100203f201b4b1b220c4d0d002014200c4102746a280200223128020841016a220c41004c0d012031200c3602082032280200220e450d0420002802002217200e412c6c6a211d202c4101462006200746712133203141106a210e201041106a211a201420224100203f20064b1b223c4102746a213d20430d024100211c034002400240201a2017410c6a220c460d00200c201a412010a0080d010b201741086a2224280200222141306c21114100210820172802002216210c024003402011450d02200e200c460d01200c200e412010a0082118200841016a2108201141506a2111200c41306a210c20180d000b20184541016a41017120086a417f6a21080b024042002016200841306c6a220c290320225520527d22542054205556200c41286a290300225420537d2055205254ad7d225620545620562054511b22111b427f205520527c225820582055542218205420537c2018ad7c225520545420552054511b22181b201b41017122161b22544200205620111b427f205520181b20161b225584500d00200c41206a220c2054370300200c20553703080c010b200c200c41306a20212008417f736a41306c109e081a20242021417f6a360200410020192023201c461b21194101212002402033450d00200721252007211b0c010b2029280200220c28020041016a221141014d0d0b200c20113602002015203c4d0d09203d280200221128020041016a220841014d0d0b201120083602000240201e20012802d402470d00200141d0026a201e410110900120012802d802211e0b20012802d002201e4103746a220820113602042008200c3602002001201e41016a221e3602d802202c2120200721252006211b0b201c41016a211c2017412c6a2217201d470d000c040b0b200c201541dc9bc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b4100211c034002400240201a2017410c6a220c460d00200c201a412010a0080d010b201741086a2224280200222141306c21114100210820172802002216210c024003402011450d02200e200c460d01200c200e412010a0082118200841016a2108201141506a2111200c41306a210c20180d000b20184541016a41017120086a417f6a21080b0240427f2016200841306c6a220c290320225520527c225420542055542211200c41286a290300225420537c2011ad7c225620545420562054511b22111b4200205520527d22582058205556205420537d2055205254ad7d225520545620552054511b22181b201b41017122161b2254427f205620111b4200205520181b20161b225584500d00200c41206a220c2054370300200c20553703080c010b200c200c41306a20212008417f736a41306c109e081a20242021417f6a360200410020192023201c461b21194101212002402033450d00200721252007211b0c010b2029280200220c28020041016a22114102490d08200c20113602002015203c4d0d06203d280200221128020041016a22084102490d08201120083602000240201e20012802d402470d00200141d0026a201e410110900120012802d802211e0b20012802d002201e4103746a220820113602042008200c3602002001201e41016a221e3602d802202c2120200721252006211b0b201c41016a211c2017412c6a2217201d470d000b0b2031280208210c0b2031200c417f6a36020820282028280208417f6a3602082010280208210c0b2010200c417f6a3602082022210620222015470d000b2020212c0c010b203c201541ec9bc2001042000b0240202c4101470d002025203f460d030b41c0001033220e450d10200e20012903a003370000200e200129039802370020200e41186a203a290300370000200e41106a203b290300370000200e41086a202d290300370000200e41286a204d290300370000200e41306a204c290300370000200e41386a204b290300370000024002402050200b4b0d002042417f6a221b450d014100210802400240024002400240034020082042460d01203020084102746a2217280200220c280200221141016a221841014d0d08200c2018360200200c28020841016a41004c0d02200c20113602002039200c41286a290000370300200141e8046a41106a200c41206a290000370300200141e8046a41086a200c41186a2900003703002001200c2900103703e8042042200841016a22084d0d03203020084102746a221a280200220c280200221141016a221841014d0d08200c2018360200200c28020841016a41004c0d04200c20113602002036200c41286a2900003703002035200c41206a2900003703002034200c41186a2900003703002001200c2900103703f8074100210c02400340200c41c000460d01200e200c6a2111200c41206a210c2011200141e8046a412010a0080d000b4100210c0340200c41c000460d01200e200c6a2111200c41206a210c2011200141f8076a412010a0080d000c090b0b2017280200221128020041016a220c41014d0d082011200c360200201a280200220c2802080d05200c417f36020802400240200c28020c22180d00410021180c010b20182018280200417f6a3602000240200c28020c22182802000d000240201828020c2217450d0020172017280200417f6a360200201828020c22172802000d000240201728020c450d002017410c6a10ae02201828020c21170b20172017280204417f6a360204201828020c22182802040d00201810350b200c28020c22182018280204417f6a360204200c28020c22182802040d00201810350b200c28020841016a21180b200c2018360208200c201136020c2008201b470d000c070b0b20422042419c9cc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b2008204241ac9cc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b02402044417f6a221b450d004100210802400240024002400240034020082044460d01203820084102746a2217280200220c280200221141016a221841014d0d08200c2018360200200c28020841016a41004c0d02200c20113602002039200c41286a290000370300200141e8046a41106a200c41206a290000370300200141e8046a41086a200c41186a2900003703002001200c2900103703e8042044200841016a22084d0d03203820084102746a221a280200220c280200221141016a221841014d0d08200c2018360200200c28020841016a41004c0d04200c20113602002036200c41286a2900003703002035200c41206a2900003703002034200c41186a2900003703002001200c2900103703f8074100210c02400340200c41c000460d01200e200c6a2111200c41206a210c2011200141e8046a412010a0080d000b4100210c0340200c41c000460d01200e200c6a2111200c41206a210c2011200141f8076a412010a0080d000c080b0b2017280200221128020041016a220c41014d0d082011200c360200201a280200220c2802080d05200c417f36020802400240200c28020c22180d00410021180c010b20182018280200417f6a3602000240200c28020c22182802000d000240201828020c2217450d0020172017280200417f6a360200201828020c22172802000d000240201728020c450d002017410c6a10ae02201828020c21170b20172017280204417f6a360204201828020c22182802040d00201810350b200c28020c22182018280204417f6a360204200c28020c22182802040d00201810350b200c28020841016a21180b200c2018360208200c201136020c2008201b470d000c060b0b2044204441fc9bc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b20082044418c9cc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b202728020041016a220c41014d0d012027200c360200024020262802080d002026417f36020802400240202628020c220c0d004100210c0c010b200c200c280200417f6a3602000240202628020c220c2802000d000240200c28020c2211450d0020112011280200417f6a360200200c28020c22112802000d000240201128020c450d002011410c6a10ae02200c28020c21110b20112011280204417f6a360204200c28020c220c2802040d00200c10350b202628020c220c200c280204417f6a360204202628020c220c2802040d00200c10350b202628020841016a210c0b2026200c3602082026202736020c200e10350c040b41a797cc004110200141a8046a41a08bc50041c897cc001046000b202628020041016a220c41014d0d002026200c36020020272802080d012027417f36020802400240202728020c220c0d004100210c0c010b200c200c280200417f6a3602000240202728020c220c2802000d000240200c28020c2211450d0020112011280200417f6a360200200c28020c22112802000d000240201128020c450d002011410c6a10ae02200c28020c21110b20112011280204417f6a360204200c28020c220c2802040d00200c10350b202728020c220c200c280204417f6a360204202728020c220c2802040d00200c10350b202728020841016a210c0b2027200c3602082027202636020c200e10350c020b00000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b20012802d0022217201e4103746a210820012802d402211b2017210e0240024002400240201e450d0020172111024003402011280200220c450d010240024002400240200c201141046a280200220e10af020d00200e200c10af02450d03200e2802080d09200e417f360208200e28020c22180d01410021180c020b200c2802080d07200c417f36020802400240200c28020c22180d00410021180c010b20182018280200417f6a3602000240200c28020c22182802000d000240201828020c221a450d00201a201a280200417f6a360200201828020c221a2802000d000240201a28020c450d00201a410c6a10ae02201828020c211a0b201a201a280204417f6a360204201828020c22182802040d00201810350b200c28020c22182018280204417f6a360204200c28020c22182802040d00201810350b200c28020841016a21180b200c2018360208200c410036020c0c020b20182018280200417f6a3602000240200e28020c22182802000d000240201828020c221a450d00201a201a280200417f6a360200201828020c221a2802000d000240201a28020c450d00201a410c6a10ae02201828020c211a0b201a201a280204417f6a360204201828020c22182802040d00201810350b200e28020c22182018280204417f6a360204200e28020c22182802040d00201810350b200e28020841016a21180b200e2018360208200e410036020c0b200e200e280200417f6a2218360200024020180d000240200e28020c2218450d0020182018280200417f6a360200200e28020c22182802000d000240201828020c450d002018410c6a10ae02200e28020c21180b20182018280204417f6a360204200e28020c22182802040d00201810350b200e200e280204417f6a221836020420180d00200e10350b200c200c280200417f6a220e3602000240200e0d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10ae02200c28020c210e0b200e200e280204417f6a360204200c28020c220e2802040d00200e10350b200c200c280204417f6a220e360204200e0d00200c10350b201141086a22112008470d000c030b0b201141086a210e0b2008200e460d000340200e220c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2211450d0020112011280200417f6a360200200e28020c22112802000d000240201128020c450d002011410c6a10ae02200e28020c21110b20112011280204417f6a360204200e28020c220e2802040d00200e10350b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10350b200c41086a210e200c41046a220c28020022112011280200417f6a3602000240200c28020022112802000d000240201128020c2218450d0020182018280200417f6a360200201128020c22182802000d000240201828020c450d002018410c6a10ae02201128020c21180b20182018280204417f6a360204201128020c22112802040d00201110350b200c28020022112011280204417f6a360204200c280200220c2802040d00200c10350b2008200e470d000b0b0240201b41ffffffff0171450d00201710350b02402015450d002015410274210e2014210c0340200c28020022112011280200417f6a3602000240200c28020022112802000d000240201128020c2208450d0020082008280200417f6a360200201128020c22082802000d000240200828020c450d002008410c6a10ae02201128020c21080b20082008280204417f6a360204201128020c22112802040d00201110350b200c28020022112011280204417f6a360204200c28020022112802040d00201110350b200c41046a210c200e417c6a220e0d000b0b0240205141ffffffff0371450d00201410350b02402042450d002030210c0340200c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2211450d0020112011280200417f6a360200200e28020c22112802000d000240201128020c450d002011410c6a10ae02200e28020c21110b20112011280204417f6a360204200e28020c220e2802040d00200e10350b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10350b200c41046a210c202b417c6a222b0d000b0b0240204f41ffffffff0371450d00203010350b203e203e280200417f6a220c3602000240200c0d000240203e28020c220c450d00200c200c280200417f6a360200203e28020c220c2802000d000240200c28020c450d00200c410c6a10ae02203e28020c210c0b200c200c280204417f6a360204203e28020c220c2802040d00200c10350b203e203e280204417f6a220c360204200c0d00203e10350b201941ff0171210802402044450d002038210c0340200c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2211450d0020112011280200417f6a360200200e28020c22112802000d000240201128020c450d002011410c6a10ae02200e28020c21110b20112011280204417f6a360204200e28020c220e2802040d00200e10350b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10350b200c41046a210c202a417c6a222a0d000b0b203720086a2137204e41ffffffff0371450d02203810350c020b41a797cc004110200141a8046a41a08bc50041c897cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b202f202f280200417f6a220c3602000240200c0d000240202f28020c220c450d00200c200c280200417f6a360200202f28020c220c2802000d000240200c28020c450d00200c410c6a10ae02202f28020c210c0b200c200c280204417f6a360204202f28020c220c2802040d00200c10350b202f202f280204417f6a220c360204200c0d00202f10350b20272027280200417f6a220c3602000240200c0d000240202728020c220c450d00200c200c280200417f6a360200202728020c220c2802000d000240200c28020c450d00200c410c6a10ae02202728020c210c0b200c200c280204417f6a360204202728020c220c2802040d00200c10350b20272027280204417f6a220c360204200c0d00202710350b20262026280200417f6a220c360200200c0d030240202628020c220c450d00200c200c280200417f6a360200202628020c220c2802000d000240200c28020c450d00200c410c6a10ae02202628020c210c0b200c200c280204417f6a360204202628020c220c2802040d00200c10350b20262026280204417f6a220c360204200c0d030c020b2027202636020c0b20272027280200417f6a220c3602000240200c0d000240202728020c220c450d00200c200c280200417f6a360200202728020c220c2802000d000240200c28020c450d00200c410c6a10ae02202728020c210c0b200c200c280204417f6a360204202728020c220c2802040d00200c10350b20272027280204417f6a220c360204200c0d00202710350b203741016a213720262026280200417f6a220c360200200c0d010240202628020c220c450d00200c200c280200417f6a360200202628020c220c2802000d000240200c28020c450d00200c410c6a10ae02202628020c210c0b200c200c280204417f6a360204202628020c220c2802040d00200c10350b20262026280204417f6a220c360204200c0d010b202610350b02402032280200220e20234d0d002000280200220c20406a28020820374d0d020c010b0b2023200e41ec9ac2001042000b202341016a22232004470d000b20012802c804220c0d010b2001418c086a41003602002001410036029808200141003602fc070c030b20012802d004211a0240024020012802cc0422110d00200c210e0c010b2011210e200c2108034020082802a0032108200e417f6a220e0d000b200c210e0340200e200e2f01064102746a41a0036a280200210e2011417f6a22110d000b2008210c0b20014194086a200e2f010636020020014190086a41003602002001418c086a200e3602002001201a36029808200141003602f807200141003602880820014200370380082001200c3602fc07201a450d014100211841002111024003402001201a417f6a221a36029808200c450d014100210802402018200c2f0106490d00034002400240200c280200220e0d002011ad21524100210e0c010b200841016a2108200c3301044220862011ad8421520b200c10352052a72111200e210c2052422088a72218200e2f01064f0d000b200e210c0b201841016a210e200c20184102746a41f4026a2802002117200c201841216c6a41286a2d0000211b0240024020080d00200e21180c010b200c200e4102746a41a0036a280200210c410021182008417f6a220e450d000340200c2802a003210c200e417f6a220e0d000b0b200120183602840820012011360280082001200c3602fc07200141003602f807201b41ff01714102460d0320172017280200417f6a220e3602000240200e0d000240201728020c220e450d00200e200e280200417f6a360200201728020c220e2802000d000240200e28020c450d00200e410c6a10ae02201728020c210e0b200e200e280204417f6a360204201728020c220e2802040d00200e10350b20172017280204417f6a220e360204200e0d00201710350b201a0d000c030b0b41958dcc00412b41c08dcc00103f000b41958dcc00412b41c08dcc00103f000b200c450d00200c280200210e200c1035200e450d000340200e280200210c200e1035200c210e200c0d000b0b200141d0106a24000f0b103c000bdb21011d7f230041b0046b220224000240024002400240024002400240024020002802004101460d00200041146a2802002203200328020041016a360200200041106a28020021042000410c6a2802002105200041086a280200210320002802042106200241e0006a41206a2207200041386a2d00003a0000200241e0006a41186a2208200041306a290000370300200241e0006a41106a2209200041286a290000370300200241e0006a41086a220a200041206a2900003703002002200041186a29000037036020032f0106220b410b490d01200241c0016a410041eb02109f081a200241d9006a4100360000200241306a41216a4200370000200241c9006a4200370000200241c1006a4200370000200241396a42003700002002420037003141a0031033220c450d05200c41003b0106200c4100360200200c41086a200241c0016a41eb02109d082107200c4198036a200241d5006a290000370000200c4193036a200241306a41206a290000370000200c418b036a200241306a41186a290000370000200c4183036a200241306a41106a290000370000200c41fb026a200241306a41086a290000370000200c20022900303700f3022002200341ce016a2f00003b01182002200341d0016a2d00003a001a200341d1016a280000210d200341d5016a280000210e200341d9016a280000210f200341dd016a28000021102002200341e7016a2900003701c6012002200341e1016a2900003703c001200328028c0321112007200341ef016a20032f010641796a220041216c109d082107200c41f4026a20034190036a2000410274109d082108200341063b0106200c20003b01062002412c6a41026a20022d001a3a0000200220022f01183b012c200220022903c001370330200220022901c6013701360240024020044107490d00200441216c20076a220741ba7e6a200741997e6a2207200041ffff0371200441796a22096b41216c109e081a200741206a200241e0006a41206a2d00003a0000200741186a200241e0006a41186a290300370000200741106a200241e0006a41106a290300370000200741086a200241e0006a41086a29030037000020072002290360370000200441027420086a41686a2107200820094102746a2112200c41066a22002f010020096b21040c010b200341086a200441216c6a220741216a2007200341066a22002f010020046b41216c109e081a200741206a200241e0006a41206a2d00003a0000200741186a200241e0006a41186a290300370000200741106a200241e0006a41106a290300370000200741086a200241e0006a41086a29030037000020072002290360370000200341f4026a20044102746a221241046a210720002f010020046b21040b200720122004410274109e081a20122001360200200241146a41026a2002412c6a41026a22132d000022013a0000200020002f010041016a3b0100200241106a41026a221420013a000020022002290136370196012002200229033037039001200220022f012c22003b0114200220003b0110200220022903900137030020022002290196013701060240200328020022070d00410021000c040b20032f01042115200241c0016a4102722116200241306a41016a210a410021000340201320142d00003a0000200220022f01103b012c200220022903003703182002200229010637011e20062000470d03201541ffff0371210802400240024020072f01062200410b490d00200a41286a4100360000200a41206a4200370000200a41186a4200370000200a41106a4200370000200a41086a4200370000200a42003700002016410041ed02109f081a200241e0006a41086a22004200370300200241e0006a41106a22034200370300200241e0006a41186a22044200370300200241e0006a41206a22094200370300200241e0006a41286a220b420037030020024190016a41256a2217200241306a41256a29000037000020024190016a41206a2218200241306a41206a29000037030020024190016a41186a2219200241306a41186a29000037030020024190016a41106a221a200241306a41106a29000037030020024190016a41086a221b200241306a41086a29000037030020024200370360200220022900303703900141d00310332201450d0920014100360200200141046a200241c0016a41ef02109d081a20014198036a201729000037000020014193036a20182903003700002001418b036a201929030037000020014183036a201a290300370000200141fb026a201b29030037000020012002290390013700f302200120022903603702a003200141a8036a2000290300370200200141b0036a2003290300370200200141b8036a2004290300370200200141c0036a2009290300370200200141c8036a200b29030037020020024190016a41026a220b200741d0016a2d00003a00002002200741ce016a2f00003b0190012002200741e1016a2900003703c0012002200741e7016a2900003701c601200741d1016a2800002118200741d5016a2800002119200741d9016a280000211a200741dd016a280000211b200728028c03211c200141086a200741ef016a20072f0106220341796a220041216c109d08211d200141f4026a20074190036a2000410274109d08211e200141a0036a200741bc036a2003417a6a2209410274109d082117200741063b0106200120003b010602402009450d00410021002017210303402003280200220420003b010420042001360200200341046a21032009200041016a2200470d000b0b200220022f01900122003b0130200220022903c001370360200220022901c6013701662002200b2d000022033a0032200b20033a0000200220003b019001200220022903603703c001200220022901663701c601201541ffff037122034107490d01200841216c201d6a220041ba7e6a200041997e6a220320012f0106200841796a22006b41216c109e081a2003201036000f2003200f36000b2003200e3600072003200d360003200341026a20132d00003a0000200320022f012c3b000020032002290318370013200341196a200229011e370000201e2008417a6a220341027422046a201e20004102746a220920012f0106221520006b410274109e081a200920113602002001201541016a22093b01062008410274221520176a416c6a201720046a2204200941ffff0371220820036b410274109e081a2004200c36020020082003490d02200120156a4188036a2103034020032802002204200041016a22003b010420042001360200200341046a210320002008490d000c030b0b2007200841216c6a220341296a200341086a2201200020086b41216c109e081a200341176a2010360000200341136a200f3600002003410f6a200e3600002003410b6a200d3600002003410a6a2002412c6a41026a2d00003a0000200120022f012c3b00002003411b6a2002290318370000200341216a200229011e370000200741f4026a2203200841016a220041027422016a2003200841027422046a220320072f0106220920086b410274109e081a200320113602002007200941016a22033b01062004200741a0036a22086a41086a200820016a2201200341ffff0371220420006b410274109e081a2001200c360200201541ffff037120044f0d0720072000417f6a22004102746a41a4036a2103034020032802002201200041016a22003b010420012007360200200341046a210320002004490d000c080b0b200741086a200841216c6a220041216a200020072f010620086b41216c109e081a2000201036000f2000200f36000b2000200e3600072000200d360003200041026a20132d00003a0000200020022f012c3b000020002002290318370013200041196a200229011e370000200741f4026a2204200841016a220941027422156a2004200841027422006a220420072f0106221720086b410274109e081a200420113602002007201741016a22043b01062000200741a0036a22176a41086a201720156a2215200441ffff0371220420096b410274109e081a2015200c360200200320044f0d00200720006a41a4036a2100034020002802002203200841016a22083b010420032007360200200041046a210020042008470d000b0b200641016a21002014200b2d00003a0000200220022f0190013b0110200220022903c001370300200220022901c6013701060240200728020022030d002018210d201b2110201a210f2019210e2001210c201c21110c050b20072f010421152018210d201b2110201a210f2019210e20032107201c21112001210c200021060c000b0b20012001280200417f6a2203360200200041086a280200200041106a2802004102746a41f4026a211220030d030240200128020c2200450d0020002000280200417f6a360200200128020c22002802000d000240200028020c450d002000410c6a10ae02200128020c21000b20002000280204417f6a360204200128020c22002802040d00200010350b20012001280204417f6a220036020420000d03200110350c030b2003200441216c6a220041296a200041086a220c200b20046b41216c109e081a200041286a20072d00003a0000200041206a2008290300370000200041186a2009290300370000200041106a200a290300370000200c2002290360370000200320044102746a220041f8026a200041f4026a221220032f010620046b410274109e081a20122001360200200320032f010641016a3b01060c020b41d684cc00413541c086cc00103f000b200241b9016a4100360000200241b1016a4200370000200241a9016a4200370000200241a1016a420037000020024199016a42003700002002420037009101200241c0016a410272410041ed02109f081a200241e0006a41086a22014200370300200241e0006a41106a22044200370300200241e0006a41186a22074200370300200241e0006a41206a2208420037030020024188016a22094200370300200241306a41256a220a20024190016a41256a290000370000200241306a41206a220b20024190016a41206a290000370300200241306a41186a220620024190016a41186a290000370300200241306a41106a221520024190016a41106a290000370300200241306a41086a221720024190016a41086a29000037030020024200370360200220022900900137033041d00310332203450d0120034100360200200341046a200241c0016a41ef02109d081a20034198036a200a29000037000020034193036a200b2903003700002003418b036a200629030037000020034183036a2015290300370000200341fb026a2017290300370000200320022903303700f302200320022903603702a003200341a8036a2001290300370200200341b0036a2004290300370200200341b8036a2007290300370200200341c0036a2008290300370200200341c8036a20092903003702002003200528020022013602a0032005200336020020052005280204220441016a360204200141003b010420012003360200200241e0006a41026a200241106a41026a2d00003a0000200220022f01103b0160200220022903003703c001200220022901063701c60120042000470d0220032f01062201410a4b0d032003200141216c6a2200410a6a200241e0006a41026a2d00003a0000200041086a20022f01603b0000200041176a2010360000200041136a200f3600002000410f6a200e3600002000410b6a200d3600002000411b6a20022903c001370000200041216a20022901c6013700002003200141016a22004102746a41a0036a200c360200200320014102746a41f4026a2011360200200320003b0106200c20003b0104200c20033602000b200241b0046a240020120f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000baf0b010c7f230041306b220224002002410036021020024204370308200241003602202002420437031802400240024002400240200128020041016a220341014d0d0020012003360200200241086a4100410110860120022802082204200228021022034102746a20013602002002200341016a22053602102001280200220341016a41014d0d002001200341016a360200200241186a4100410110860120022802182206200228022022034102746a20013602002002200341016a2207360220200128020041016a220841014d0d00200120083602000340200841016a220341014d0d0120012003360200200128020841016a220941004c0d0220012009360208200128020c2208450d0502402007450d002007410274210a200841106a210b20062109034002400240200928020022032008460d00200328020841016a220c41004c0d072003200c3602082008280208220c41016a220d41004c0d082008200d360208200341106a200b412010a0080d0120032d003020082d0030470d012008200c36020820032003280208417f6a3602080b20012802002103200128020821090c080b200941046a21092008200c36020820032003280208417f6a360208200a417c6a220a0d000b200128020c21080b200828020041016a220341014d0d012008200336020002402005200228020c470d00200241086a2005410110860120022802082104200228021021050b200420054102746a20083602002002200541016a2205360210200128020c220328020041016a220841014d0d012003200836020020012001280200417f6a2208360200024020080d000240200128020c2208450d0020082008280200417f6a360200200128020c22082802000d000240200828020c450d002008410c6a10ae02200128020c21080b20082008280204417f6a360204200128020c22082802040d00200810350b20012001280204417f6a220836020420080d00200110350b200328020041016a220841014d0d012003200836020002402007200228021c470d00200241186a2007410110860120022802182106200228022021070b200620074102746a200336020020012001280208417f6a36020820012001280200417f6a22083602002002200741016a2207360220024020080d000240200128020c2208450d0020082008280200417f6a360200200128020c22082802000d000240200828020c450d002008410c6a10ae02200128020c21080b20082008280204417f6a360204200128020c22082802040d00200810350b20012001280204417f6a220836020420080d00200110350b20032802002108200321010c000b0b00000b41ac96cc004118200241286a41808bc50041d496cc001046000b41ac96cc004118200241286a41e495ca0041d496cc001046000b41ac96cc004118200241286a41e495ca0041d496cc001046000b20012003417f6a220336020020012009417f6a360208024020030d000240200128020c2203450d0020032003280200417f6a360200200128020c22032802000d000240200328020c450d002003410c6a10ae02200128020c21030b20032003280204417f6a360204200128020c22032802040d00200310350b20012001280204417f6a220336020420030d00200110350b20002001360200200020022903083702042000410c6a200241106a28020036020002402007450d0020074102742108200621030340200328020022092009280200417f6a3602000240200328020022092802000d000240200928020c2201450d0020012001280200417f6a360200200928020c22012802000d000240200128020c450d002001410c6a10ae02200928020c21010b20012001280204417f6a360204200928020c22092802040d00200910350b200328020022092009280204417f6a360204200328020022092802040d00200910350b200341046a21032008417c6a22080d000b0b0240200228021c41ffffffff0371450d00200610350b200241306a24000b5c01017f200028020022012001280200417f6a3602000240200028020022012802000d000240200128020c450d002001410c6a10ae02200028020021010b20012001280204417f6a360204200028020022002802040d00200010350b0ba50201047f230041106b22022400410021030240024002400240024002400240200028020841016a220441004c0d00200028020c2205450d0620002004360208024020052001470d00410121030c060b200528020841016a220341004c0d01200520033602082001280208220441016a220341004c0d0220012003360208200541106a200141106a412010a0080d034101210320052d003020012d0030470d030c040b41ac96cc004118200241086a41808bc50041d496cc001046000b41ac96cc004118200241086a41808bc50041d496cc001046000b41ac96cc004118200241086a41808bc50041d496cc001046000b410021030b2001200436020820052005280208417f6a360208200028020821040b20002004417f6a3602080b200241106a240020030b80150c047f027e027f067e017f037e037f027e037f037e037f017e230041e0036b2204240020032802002105200441306a2001108e02200441b0016a2004280230220620042802382207108f0220042903b001210842002109200442003703b001200441f8016a280200210a20042d00fc01210b02400240200842015122030d00200441c0006a41306a4200370300200441c0006a41286a4200370300200441c0006a41206a4200370300200441c0006a41186a4200370300200441d0006a4200370300200441c8006a4200370300200442003703404200210c4200210d4200210e4200210f0c010b200441e8016a2903002110200441b0016a41306a2903002111200441b0016a41206a290300210c200441b0016a41186a2903002109200441f0016a290300210f20042903c001210e20042903b801210d200441c0006a41206a200441b0016a41286a290300370300200441c0006a41286a2011370300200441c0006a41306a2010370300200441d0006a20093703002004200c3703582004200d3703402004200e3703480b427f200e200c7c200d20097c220c200d542212ad7c220920122009200e542009200e511b22121b2113427f200c20121b21144200210c024002402002290300221542ffffe883b1de1656200241086a29030022094200522009501b0d00201420138450450d0041002103410021124200210e410121020c010b4200200e20097c200d20157c2210200d542202ad7c220d2002200d200e54200d200e511b22021b210e4200201020021b2111024020024101470d002011421088200e42308684210c200e421088210e2011420888a721122011a72103410121020c010b200441b0026a41186a22164200370300200441b0026a41106a22174200370300200441b0026a41086a22124200370300200442003703b00241b6fdc600ad4280808080800184220c100122182900002119200441d0036a41086a2202201841086a290000370300200420193703d0032018103520122002290300370300200420042903d0033703b00241e489c200ad4280808080d00184221910012218290000211a2002201841086a2900003703002004201a3703d00320181035201720042903d003221a370300200441b0036a41086a221b2012290300370300200441b0036a41106a221c201a370300200441b0036a41186a221d2002290300370300200420042903b0023703b003200441186a200441b0036a412010d701200441186a41106a290300211a2004290320211e20042802182118201642003703002017420037030020124200370300200442003703b002200c10012216290000210c2002201641086a2900003703002004200c3703d0032016103520122002290300370300200420042903d0033703b002201910012216290000210c2002201641086a2900003703002004200c3703d00320161035201720042903d003220c370300201b2012290300370300201c200c370300201d2002290300370300200420042903b0023703b0032004201a420020181b3703b8022004201e420020181b3703b002200441b0036aad4280808080800484221a200441b0026aad221e428080808080028410022004200e37034820042011370340200441f8006a41186a200441d0006a220241086a290300220c370300200441f8006a41206a2212200241106a290300370300200441a0016a2218200241186a290300370300200441a8016a2216200241206a2903003703002004200e37038001200420113703782004200229030022193703880102400240427f201120197c221920192011542202200e200c7c2002ad7c220c200e54200c200e511b22021b220e428080e983b1de16544100427f200c20021b220c501b0d00200441f8006a41106a290300210e2016290300210c2018290300211120122903002119200429038001211a2004290378211e4201211f20042903900121200c010b02400240200e200c8450450d004200211f0c010b4200211f200441b0026a41186a22184200370300200441b0026a41106a22164200370300200441b0026a41086a22124200370300200442003703b00241b6fdc600ad428080808080018422111001221b2900002119200441d0036a41086a2202201b41086a290000370300200420193703d003201b103520122002290300370300200420042903d0033703b00241e489c200ad4280808080d0018422191001221b29000021202002201b41086a290000370300200420203703d003201b1035201720042903d003370000201741086a221d2002290300370000200441b0036a41086a22212012290300370300200441b0036a41106a22222016290300370300200441b0036a41186a22232018290300370300200420042903b0023703b0032004200441b0036a412010d701200441106a2903002120200429030821242004280200211b201842003703002016420037030020124200370300200442003703b00220111001221c29000021112002201c41086a290000370300200420113703d003201c103520122002290300370300200420042903d0033703b00220191001221c29000021112002201c41086a290000370300200420113703d003201c1035201720042903d003370000201d2002290300370000202120122903003703002022201629030037030020232018290300370300200420042903b0023703b0032004420020204200201b1b2211200c7d20244200201b1b2219200e54ad7d22202019200e7d2224201956202020115620202011511b22021b3703b80220044200202420021b3703b002201a201e42808080808002841002200441e8026a200c370300200441e0026a200e370300201241013a0000200441b9026a2005290000370000200441c1026a200541086a290000370000200441c9026a200541106a290000370000200441d1026a200541186a290000370000200441033a00b00241b0b4cc004100200441b0026a10d4010b0b200441d8016a2019370300200441e0016a2011370300200441c0016a201a370300200441e8016a200c370300200441c8016a200e370300200420203703d0012004200f3703f0012004201e3703b801410021022004200b4100200842015122121b3a00fc012004200a410020121b3602f8012004201f4201512212ad3703b001201420138450ad423086210c4200210e024020120d002007ad4220862006ad841007410021120c010b200420073602b402200420063602b002200441b8016a200441b0026a10e70241012112410021020b02402004280234450d00200610350b024002402002450d00200041106a200e421086200c4230888437030020002012ad42ff01834208862003ad42ff018384200c421086843703084201210e0c010b200c423088200e42108684210e024002400240200341ff017122020d00201241ff0171450d0041032103200441b0026a21020c010b2002450d01201241ff01710d0141042103200441b0016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b2000200e370308200041286a2009370300200041206a2015370300200041186a200d370300200041106a20103703004200210e0b2000200e370300200441e0036a24000bd60302057f047e230041f0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022030d00200041003a00000c010b200241186a28020021042002280214210541002101200241003a006802400240034020042001460d01200241c8006a20016a200320016a2d00003a00002002200141016a22063a00682006210120064120470d000b200241206a41186a200241c8006a41186a2903002207370300200241206a41106a200241c8006a41106a2903002208370300200241206a41086a200241c8006a41086a290300220937030020022002290348220a370320200041196a2007370000200041116a2008370000200041096a20093700002000200a370001410121010c010b0240200141ff0171450d00200241003a00680b410021012002410036022820024201370320200241093602442002200241086a3602402002200241206a36026c200241dc006a41013602002002420137024c200241c888c2003602482002200241c0006a360258200241ec006a41e88ac500200241c8006a10431a200235022842208620023502208410062002280224450d00200228022010350b200020013a00002005450d00200310350b200241f0006a24000ba11005097f037e027f037e037f230041f0026b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022040d00200042023703000c010b200328021421052003200341186a28020022063602a401200320043602a00141002107200341003a00e8022004210220062101024002400240024002400240024002400340200721082001450d01200341c8026a20086a20022d00003a000020032001417f6a22013602a4012003200241016a22023602a0012003200841016a22073a00e80220074120470d000b200341a8016a41086a200341c8026a41086a290300370300200341a8016a41106a200341c8026a41106a290300370300200341a8016a41186a200341c8026a41186a290300370300200320032903c8023703a80141002107200341003a00e802200620086b417e6a2108034020012007460d02200341c8026a20076a200220076a22062d00003a00002003200641016a3602a0012003200741016a22063a00e802200320083602a4012008417f6a21082006210720064120470d000b200341c8016a41086a200341c8026a41086a290300370300200341c8016a41106a200341c8026a41106a290300370300200341c8016a41186a200341c8026a41186a290300370300200320032903c8023703c80120012006460d05200220066a22092d00002102200320083602a4012003200941016a22073602a001200241014b0d0520020e020302030b200841ff0171450d04200341003a00e8020c040b200741ff0171450d03200341003a00e8020c030b200941116a210741002102200341003a00e802200120066b416f6a21010240034020082002460d01200341c8026a20026a200920026a41016a2d00003a000020032001410f6a3602a4012003200741716a3602a0012003200241016a22063a00e8022001417f6a2101200741016a21072006210220064120470d000b200341a8026a41186a2202200341c8026a41186a290300370300200341a8026a41106a220a200341c8026a41106a290300370300200341a8026a41086a220b200341c8026a41086a290300370300200320032903c8023703a802200820066b4110490d03200920066a220841096a290000210c200841016a290000210d20034188026a41086a200b29030037030020034188026a41106a200a29030037030020034188026a41186a2002290300370300200320013602a401200320073602a001200320032903a802370388024201210e200121080c020b200241ff0171450d02200341003a00e8020c020b4200210e0b200341e8016a41186a20034188026a41186a290300370300200341e8016a41106a20034188026a41106a290300370300200341e8016a41086a20034188026a41086a29030037030020032003290388023703e8012008450d0020072d0000210120032008417f6a22023602a4012003200741016a3602a001200141014b0d00410021060240024020010e020100010b20024104490d012007280001210920032008417b6a3602a4012003200741056a3602a001410121060b200341c8026a200341a0016a10aa0220032802c8020d010b200341003602b002200342013703a8022003410936028c022003200341086a360288022003200341a8026a3602e801200341dc026a4101360200200342013702cc02200341c888c2003602c802200320034188026a3602d802200341e8016a41e88ac500200341c8026a10431a20033502b00242208620033502a802841006024020032802ac02450d0020032802a80210350b4202210e0c010b200341f0006a41086a2202200341c8026a41086a2201280200360200200341d0006a41086a2207200341a8016a41086a290300370300200341d0006a41106a2208200341a8016a41106a290300370300200341d0006a41186a220a200341a8016a41186a290300370300200341306a41086a220b200341c8016a41086a290300370300200341306a41106a220f200341c8016a41106a290300370300200341306a41186a2210200341c8016a41186a290300370300200320032903c802370370200320032903a801370350200320032903c80137033020034180016a41186a200341e8016a41186a290300221137030020034180016a41106a200341e8016a41106a290300221237030020034180016a41086a200341e8016a41086a290300221337030020012013370300200341c8026a41106a22142012370300200341c8026a41186a22152011370300200341206a41086a22162002280200360200200320032903e801221137038001200320113703c80220032003290370370320200341a8026a41186a2202200a290300370300200341a8026a41106a220a2008290300370300200341a8026a41086a22082007290300370300200320032903503703a80220034188026a41186a2207201029030037030020034188026a41106a2210200f29030037030020034188026a41086a220f200b2903003703002003200329033037038802200041306a200c370300200041286a200d3703002000413c6a2009360200200041386a2006360200200041206a2015290300370300200041186a2014290300370300200041106a2001290300370300200020032903c802370308200041c0006a2003290320370300200041c8006a2016280200360200200020032903a80237024c200041d4006a2008290300370200200041dc006a200a290300370200200041e4006a200229030037020020004184016a2007290300370200200041fc006a2010290300370200200041f4006a200f290300370200200020032903880237026c0b2000200e3703002005450d00200410350b200341f0026a24000be00903067f067e057f230041a0016b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022040d00200041023a00000c010b2003280214210502400240200341186a2802002206450d0020042d0000220141014b0d002006417f6a210202400240024020010e020001000b20024104490d022004280001210741002101200341003a0098012006417b6a21080240034020082001460d01200341f8006a20016a200420016a41056a2d00003a00002003200141016a22023a0098012002210120024120470d000b200341d8006a41186a200341f8006a41186a290300370300200341d8006a41106a200341f8006a41106a290300370300200341d8006a41086a200341f8006a41086a290300370300200320032903783703582006417b6a2002460d03200420026a220141056a2d0000220841034f0d03200620026b2202417a6a4104490d03200241766a4110490d03200241666a4110490d03200241566a4110490d03200141066a2800002106200141126a29000021092001410a6a290000210a200341286a41086a200341d8006a41086a290300370300200341286a41106a200341d8006a41106a290300370300200341286a41186a200341d8006a41186a29030037030020032003290358370328200320032800503602202003200341d3006a280000360023200141326a290000210b2001412a6a290000210c200141226a290000210d2001411a6a290000210e200320032f014e3b014c410021010c020b200141ff0171450d02200341003a0098010c020b2002450d0120042d0001220141014b0d012006417e6a2108410021020240024020010e020100010b410121020b200841034d0d01200341286a41086a200341f8006a41086a290300370300200341286a41106a200341f8006a41106a290300370300200341286a41186a200341f8006a41186a29030037030020032003290378370328200320032800583602202003200341d8006a41036a2800003600232004280002210f410121010b200341f8006a41086a2210200341286a41086a290300370300200341f8006a41106a2211200341286a41106a290300370300200341f8006a41186a2212200341286a41186a290300370300200320032f014c22133b015020032003290328370378200320032802203602582003200328002336005b200041306a200b370000200041286a200c370000200041206a200d370000200041186a200e370000200041106a2009370000200041086a200a370000200020023a00012000413c6a2006360000200041386a2007360000200041046a200f360000200041026a20133b0000200041e0006a20083a0000200041c0006a2003290378370000200041c8006a2010290300370000200041d0006a2011290300370000200041d8006a2012290300370000200041e1006a2003280258360000200041e4006a200328005b3600000c010b20034100360260200342013703582003410936022c2003200341086a3602282003200341d8006a3602502003418c016a41013602002003420137027c200341c888c2003602782003200341286a36028801200341d0006a41e88ac500200341f8006a10431a200335026042208620033502588410060240200328025c450d00200328025810350b410221010b200020013a00002005450d00200410350b200341a0016a24000b880504057f017e027f017e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c2010240024002400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360224200320043602202003200341206a10c4010240024020032802000d00200328020422062003280224220741186e2201200120064b1bad42187e2208422088a70d032008a72202417f4c0d030240024020020d00410821090c010b200210332209450d050b4100210120034100360250200320093602482003200241186e36024c0240024002402006450d00034020074104490d0320032003280220220241046a3602202007417c6a4110490d022002280000210a2003200241146a3602202002410c6a29000021082002290004210b02402001200328024c470d00200341c8006a20014101109c0120032802482109200328025021010b2007416c6a21072009200141186c6a2202200a3602002002200b370308200241106a20083703002003200141016a22013602502006417f6a22060d000b200320073602240b2009450d022000200329024c370204200020093602000c030b2007417c6a21070b20032007360224200328024c2201450d00200141186c450d00200910350b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602000b2005450d00200410350b200341e0006a24000f0b1044000b1045000bbe0201017f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602000c010b200328021421022003200341106a41086a28020036022420032001360220200341c8006a200341206a10c3010240024020032802480d0020034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602000c010b20002003290348370200200041086a200341c8006a41086a2802003602000b2002450d00200110350b200341e0006a24000b901304057f017e107f027e230041e0026b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c2010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c4010240024020022802000d00200228020422052002280224220641c4006e2201200120054b1bad42c4007e2207422088a70d032007a72201417f4c0d030240024020010d00410421080c010b200110332208450d050b20024100360230200220083602282002200141c4006e36022c0240024002402005450d00200241b8026a41077221094100210a4100210b03402006450d0220022006417f6a220c36022420022002280220220d41016a360220200d2d0000220141014b0d0202400240024020010e020001000b200c4104490d04200241f4016a41026a200241f8016a41026a2d00003a0000200241d8016a41086a20024198026a41086a290200370300200241d8016a41106a20024198026a41106a290200370300200241d8016a41186a20024198026a41186a2d00003a0000200241b8016a41086a200241b8026a41086a290100370300200241b8016a41106a200241b8026a41106a290100370300200241b8016a41186a200241b8026a41186a290100370300200220022f00f8013b01f40120022002290298023703d801200220022901b8023703b80120022006417b6a220e3602242002200d41056a360220200d280001210f200220022f0194023b01b601410021100c010b41002111200241003a00d8022006417e6a2110024002400240024002400340200c20112201460d01200241b8026a20016a200d20016a221141016a2d00003a00002002201141026a3602202002200141016a22113a00d802200220103602242010417f6a211020114120470d000b20024194026a41026a221220022d00ba023a0000200241f8016a41086a2213200941086a290000370300200241f8016a41106a2214200941106a290000370300200241f8016a41186a2215200941186a2d00003a0000200220022f01b8023b019402200220092900003703f8014100210e200c2011460d0220022800bb022116200220103602242002200d20116a220c41026a360220200c41016a2d0000221141014d0d012010210e410221100c050b0240200141ff0171450d00200241003a00d8020b4100210e410221100c040b024020110e020200020b41002111200241003a00d802200620016b417c6a21010240034020102011460d01200241b8026a20116a200c20116a220d41026a2d00003a00002002200d41036a3602202002201141016a220d3a00d802200220013602242001417f6a2101200d2111200d4120470d000b20024198026a41186a200241b8026a41186a29030037030020024198026a41106a200241b8026a41106a29030037030020024198026a41086a200241b8026a41086a290300370300200220022903b802370398022010200d6b210e410121170c030b0240201141ff0171450d00200241003a00d8020b4100210e0b410221100c020b410021172010210e0b200241b8016a41186a20024198026a41186a290300370300200241b8016a41106a20024198026a41106a290300370300200241b8016a41086a20024198026a41086a290300370300200241f4016a41026a20122d00003a0000200241d8016a41086a2013290300370300200241d8016a41106a2014290300370300200241d8016a41186a20152d00003a000020022002290398023703b801200220022f0194023b01f401200220022903f8013703d801410121102016210f0b200241b2016a41026a2201200241f4016a41026a2d00003a000020024198016a41086a2211200241d8016a41086a29030037030020024198016a41106a220d200241d8016a41106a29030037030020024198016a41186a220c200241d8016a41186a2d00003a0000200241f8006a41086a2206200241b8016a41086a290300370300200241f8006a41106a2212200241b8016a41106a290300370300200241f8006a41186a2213200241b8016a41186a290300370300200220022f01f4013b01b201200220022903d80137039801200220022903b801370378200220022f01b6013b017620104102460d03200b41016a210b200241f2006a41026a221420012d00003a0000200241d8006a41086a22152011290300370300200241d8006a41106a2211200d290300370300200241d8006a41186a220d200c2d00003a0000200241386a41086a220c2006290300370300200241386a41106a22062012290300370300200241386a41186a22122013290300370300200220022f01b2013b0172200220022903980137035820022002290378370338200220022f01763b01360240200a200228022c470d00200241286a200a4101109f01200228022821082002280230210a0b2008200a41c4006c6a220120103a00002001200f360004200141036a20142d00003a0000200120022f01723b0001200d2d00002110201129030021072015290300211820022903582119200120173a002120012019370008200141106a2018370000200141186a2007370000200141206a20103a000020012002290338370022200c29030021072006290300211820122903002119200120022f01363b00422001413a6a2019370000200141326a20183700002001412a6a20073700002002200a41016a220a360230200e2106200b2005470d000b0b2008450d022000200229022c370204200020083602000c030b200241b2016a41026a200241f4016a41026a2d00003a000020024198016a41086a200241d8016a41086a29030037030020024198016a41106a200241d8016a41106a29030037030020024198016a41186a200241d8016a41186a2d00003a0000200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a200241b8016a41106a290300370300200241f8006a41186a200241b8016a41186a290300370300200220022f01f4013b01b201200220022903d80137039801200220022903b801370378200220022f01b6013b01760b200228022c2201450d00200141c4006c450d00200810350b200241003602a0022002420137039802200241093602bc012002200241086a3602b801200220024198026a360278200241cc026a4101360200200242013702bc02200241c888c2003602b8022002200241b8016a3602c802200241f8006a41e88ac500200241b8026a10431a20023502a0024220862002350298028410060240200228029c02450d0020022802980210350b200041003602000b2004450d00200310350b200241e0026a24000f0b1044000b1045000bd20402067f047e230041f0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822030d00200041023a00000c010b200228020c210402400240200241106a2802002205450d0020032d0000220641014b0d004100210102400240024020060e020100010b41002101200241003a0068200341016a21072005417f6a2106034020062001460d02200241c8006a20016a200720016a2d00003a00002002200141016a22053a00682005210120054120470d000b200241186a41186a200241c8006a41186a290300370300200241186a41106a200241c8006a41106a290300370300200241186a41086a200241c8006a41086a29030037030020022002290348370318410121010b200241c8006a41186a200241186a41186a2903002208370300200241c8006a41106a200241186a41106a2903002209370300200241c8006a41086a200241186a41086a290300220a37030020022002290318220b370348200041196a2008370000200041116a2009370000200041096a200a3700002000200b3700010c020b200141ff0171450d00200241003a00680b20024100360220200242013703182002410936023c200220023602382002200241186a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235022042208620023502188410060240200228021c450d00200228021810350b410221010b200020013a00002004450d00200310350b200241f0006a24000ba90d03047f017e147f230041e00c6b220324002003200236021c20032001360218200341206a2002ad4220862001ad84100510c2010240024002400240200328022022040d00200041003602000c010b200328022421052003200341286a28020036023420032004360230200341106a200341306a10c40102400240024020032802100d00200328021422062003280234220141d0026e2202200220064b1bad42d0027e2207422088a70d052007a72208417f4c0d050240024020080d00410821090c010b200810332209450d050b4100210220034100360240200320093602382003200841d0026e36023c02402006450d002006417f6a21080340024002402001450d002003280230220a2d0000210b20032001417f6a220c3602342003200a41016a360230200b41014b0d00410221060240200b0e020200020b024002400240200c0d00410221060c010b200a2d0001210b20032001417e6a220c360234410221062003200a41026a36023002400240200b41014b0d0041002101024002400240200b0e020100010b200341086a200341306a10c40120032802080d022003280234200328020c220b490d02200b417f4c0d0f02400240200b0d004100210a410121010c010b200b10392201450d0f2003280234200b490d0220012003280230200b109d081a2003280234220a200b490d042003200a200b6b36023420032003280230200b6a360230200b210a0b2001450d02200bad422086200aad8421072003280234210c0b2007a7210b02400240024002400240200c450d002003280230220d2d0000210a2003200c417f6a3602342003200d41016a360230200341b00a6a200341306a10b90220032802b00a411b460d0320034180086a200341b00a6a41b002109d081a2003280234220c450d042003280230220e2d0000210d2003200c417f6a220f3602342003200e41016a360230200d41014b0d0441002106200d0e020201020b2001450d07200b450d070c040b200f4104490d02200e280001210d2003200e41056a3602302003200c417b6a220636023420064104490d02200e28000521102003200c41776a3602342003200e41096a36023041012106200d21110b2007422088a72112200341b00a6a20034180086a41b002109d081a200320032800f9073602f0072003200341f9076a41036a2800003600f3070c060b2001450d04200b450d040c010b20034180086a10ba022001450d01200b450d010b200110350b2013210a2014210b20152101410221060c020b200b200a41a4f0cb001059000b2013210a2014210b201521010b200341c0056a200341b00a6a41b002109d081a200320032800f3073600bb05200320032802f0073602b805024020064102460d00200341b00a6a200341c0056a41b002109d081a200320032800bb0536008308200320032802b8053602800820012116200b211720122118200a21192010211a2011211b200a2113200b2114200121150c020b200a2113200b2114200121150b410321060b20034188036a200341b00a6a41b002109d081a200320032800830836008303200320032802800836028003024020064103460d00200341d0006a20034188036a41b002109d081a200320032800830336004b200320032802800336024802402002200328023c470d00200341386a2002410110a70120032802382109200328024021020b2009200241d0026c6a200341d0006a41b002109d08220141c8026a20193a0000200141c4026a201a3602002001201b3602c002200120063602bc02200120183602b802200120173602b402200120163602b002200141c9026a2003280248360000200141cc026a200328004b3600002003200241016a22023602402008450d022008417f6a2108200328023421010c010b0b02402002450d00200241d0026c21022009210103400240200141bc026a2802004102460d000240200141b0026a2802002206450d00200141b4026a280200450d00200610350b200110bb020b200141d0026a2101200241b07d6a22020d000b0b200328023c2201450d01200141d0026c450d01200910350c010b20090d010b20034100360288082003420137038008200341093602c4052003200341186a3602c005200320034180086a36028803200341c40a6a4101360200200342013702b40a200341c888c2003602b00a2003200341c0056a3602c00a20034188036a41e88ac500200341b00a6a10431a2003350288084220862003350280088410060240200328028408450d0020032802800810350b200041003602000c010b2000200329023c370204200020093602000b2005450d00200410350b200341e00c6a24000f0b1045000b1044000bd2870307087f027e0b7f087e057f027e1b7f23004190116b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005411b4b0d25200141046a210720050e1c0102030405060708090a0b0c0d0e0f10111213141516171819222324010b2000411b3602000c600b2006450d5e20042d0001210520012003417e6a22083602042001200441026a360200200541094b0d5e410a2109024002400240024002400240024002400240024020050e0a00010203040506070809000b20084104490d672004280002210620012003417a6a3602042001200441066a3602002006418194ebdc034f0d67410121090c080b2002200110c40120022802000d66200728020020022802042204490d662004417f4c0d2c0240024020040d004200210a410121060c010b200410392206450d2120072802002004490d66200620012802002004109d081a200128020422032004490d2e2001200320046b3602042001200128020020046a3602002004ad210a0b2006450d66200a2004ad42208684210a410221090c070b20084108490d652004290002210a2001200341766a36020420012004410a6a360200410321090c060b200241086a200110c40120022802080d642007280200200228020c2204490d642004417f4c0d2a0240024020040d004200210a410121060c010b200410392206450d1f20072802002004490d64200620012802002004109d081a200128020422032004490d2d2001200320046b3602042001200128020020046a3602002004ad210a0b2006450d64200a2004ad42208684210a410421090c050b200241106a200110c40120022802100d63200728020020022802142204490d632004417f4c0d290240024020040d004200210a410121060c010b200410392206450d1e20072802002004490d63200620012802002004109d081a200128020422032004490d2d2001200320046b3602042001200128020020046a3602002004ad210a0b2006450d63200a2004ad42208684210a410521090c040b2008450d6220042d0002210520012003417d6a22073602042001200441036a360200200541014b0d624106210941002106024020050e020400040b20074104490d622004350003210a2001200341796a22053602042001200441076a36020020054104490d622004350007210b2001200341756a36020420012004410b6a360200200b422086200a84210a410121060c030b200241286a200110c40120022802280d61200228022c2209200728020041186e2204200420094b1bad42187e220a422088a70d27200aa72204417f4c0d270240024020040d00410421060c010b200410332206450d1c0b41002105200241003602b80c200220063602b00c2002200441186e3602b40c024002400240024002402009450d000340200241206a200110c40120022802200d05200728020020022802242204490d052004417f4c0d2d0240024020040d004100210c410121080c010b200410392208450d2220072802002004490d05200820012802002004109d081a200128020422032004490d322001200320046b3602042001200128020020046a3602002004210c0b200241186a200110c40120022802180d032007280200200228021c2203490d032003417f4c0d2d0240024020030d004100210d4101210e0c010b20031039220e450d2220072802002003490d03200e20012802002003109d081a2001280204220d2003490d332001200d20036b3602042001200128020020036a3602002003210d0b2004ad422086200cad84210a2003ad422086200dad84210b0240200520022802b40c470d00200241b00c6a2005410110970120022802b00c210620022802b80c21050b2006200541186c6a2204200e36020c2004200a37020420042008360200200441106a200b3702002002200541016a22053602b80c2009417f6a22090d000b0b2006450d6520022902b40c210a410721090c060b200e10350b200c450d010b200810350b02402005450d00200541186c21042006210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141186a2101200441686a22040d000b0b20022802b40c2201450d61200141186c450d610c600b200241386a200110c40120022802380d60200228023c22092007280200410c6e2204200420094b1bad420c7e220a422088a70d26200aa72204417f4c0d260240024020040d00410421060c010b200410332206450d1b0b41002103200241003602b80c200220063602b00c20022004410c6e3602b40c0240024002402009450d000340200241306a200110c40120022802300d03200728020020022802342204490d032004417f4c0d2a0240024020040d0041002108410121050c010b200410392205450d1f20072802002004490d03200520012802002004109d081a200128020422082004490d312001200820046b3602042001200128020020046a360200200421080b2004ad4220862008ad84210a0240200320022802b40c470d00200241b00c6a2003410110870120022802b00c210620022802b80c21030b20062003410c6c6a2204200a370204200420053602002002200341016a22033602b80c2009417f6a22090d000b0b2006450d6220022902b40c210a410821090c030b200510350b02402003450d002003410c6c21042006210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b20022802b40c2201450d602001410c6c0d5f0c600b200241c0006a200110c40120022802400d5f200728020020022802442204490d5f2004417f4c0d250240024020040d004200210a410121060c010b200410392206450d1a20072802002004490d5f200620012802002004109d081a200128020422032004490d2d2001200320046b3602042001200128020020046a3602002004ad210a0b2006450d5f200a2004ad42208684210a410921090b20004100360200200041106a200a3702002000410c6a2006360200200041086a2009360200200041186a200241e00e6a419802109d081a0c5f0b2006450d5a20042d0001210520012003417e6a22063602042001200441026a360200200541044b0d5a02400240024002400240024002400240024020050e050001020304000b200241e00e6a200110c80520022802e00e2204450d622004411876210f20022902e40e220aa722034118762110200a422088a7210d41012111410021120c050b20064102490d6120042f0002210520012003417c6a3602042001200441046a360200200241e00e6a200110b90220022802e00e2101200241b00c6a200241e00e6a41047241ac02109d081a2001411b460d61200241e00e6a200241b00c6a41ac02109d081a41b002103322040d030c620b20064102490d6020042f0002210520012003417c6a3602042001200441046a360200200241e00e6a200110c30120022802e00e2204450d6020022802e40e2103024020072802002206450d00200241e80e6a280200210d200128020022092d0000210720012006417f6a22083602042001200941016a360200200741014b0d004200210a4100210e0240024020070e020100010b20084104490d012009350001210a20012006417b6a22073602042001200941056a36020020074104490d01200928000521132001200641776a3602042001200941096a360200200a422086210a4101210e0b200241e00e6a200110b90220022802e00e2106200241b00c6a200241e00e6a41047241ac02109d081a2006411b460d06200241e00e6a200241b00c6a41ac02109d081a41b00210332201450d62200a200ead84210a20012006360200200141046a200241e00e6a41ac02109d081a200341187621102004411876210f20054180fe03714108762112410321110c040b200341ffffff3f71450d600c5f0b20064102490d5f20042f0002210820012003417c6a3602042001200441046a360200200241e00e6a200110c30120022802e00e2206450d5f20022802e40e2109024020072802002204450d00200241e80e6a2802002107200128020022052d0000210320012004417f6a220d3602042001200541016a360200200341014b0d004100210e0240024020030e020100010b200d4104490d012005280001210c20012004417b6a22033602042001200541056a36020020034104490d01200528000521142001200441776a220d3602042001200541096a3602004101210e0b41002103200241003a00800f200d417f6a2104024003402004417f460d01200241e00e6a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00800f2004417f6a21042005210320054120470d000b200220022800e30e3600c30b200220022802e00e22153602c00b20022900e70e220aa72203411876211020022800c30b2204411876210f20022f00c10b2205410876211220022900f70e220b422088a72101200a422088a7210d200241ef0e6a290000210a200241ff0e6a2d00002116200ba72113410421110c050b0240200341ff0171450d00200241003a00800f0b200941ffffff3f71450d60200610350c600b200941ffffff3f71450d5f200610350c5f0b20064102490d5e20042f0002210820012003417c6a3602042001200441046a360200200241e00e6a200110c30120022802e00e2206450d5e20022802e40e21090240200728020022034104490d00200241e80e6a28020021072001280200220d280000210e20012003417c6a22043602042001200d41046a36020020044104490d00200d280004210c2001200341786a22143602042001200d41086a36020041002104200241003a00800f200341776a21030240034020142004460d01200241e00e6a20046a200d20046a220541086a2d00003a0000200120033602042001200541096a3602002002200441016a22053a00800f2003417f6a21032005210420054120470d000b200220022800e30e3600c30b200220022802e00e22153602c00b20022801c20b2212410876210420022900f70e2217422088a7210120022900e70e220b422088a7210d200b421888a72110200241ef0e6a290000210a200241ff0e6a2d0000211620022d00c10b210520022d00c60b210f2017a72113200ba72103410521110c040b0240200441ff0171450d00200241003a00800f0b200941ffffff3f71450d5f200610350c5f0b200941ffffff3f71450d5e200610350c5e0b20042001360200200441046a200241e00e6a41ac02109d081a2004411876210f20054180fe037141087621122002280288092113200228028408210c200228028808211441022111410021100b0b200020153a0005200020113a0004200041013602002000413c6a2014360200200041386a200c360200200041346a200e360200200041306a20073602002000412c6a2009360200200041286a2006360200200041266a20083b0100200041246a20163a0000200041206a20013602002000411c6a2013360200200041146a200a370200200041106a200d3602002000410c6a2010411874200341ffffff077172360200200041086a200f411874200441ffffff077172360200200041066a2012410874200541ff0171723b0100200041c0006a20024190066a41f001109d081a0c5f0b200341ffffff3f710d590c5a0b02402006450d0020012003417e6a3602042001200441026a3602000b2000411b3602000c5d0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241c8006a20011091062002290348a70d002002290350210a20004103360200200041086a200a370300200041106a200241e00e6a41a002109d081a0c5d0b2000411b3602000c5c0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241b00c6a200110cf0320022802b00c2201450d00200041086a20022902b40c3702002000200136020420004104360200200041106a200241e00e6a41a002109d081a0c5c0b2000411b3602000c5b0b02402006450d0020042d0001210520012003417e6a22063602042001200441026a360200200541034b0d00024002400240024020050e0400010203000b20064104490d032004280002210920012003417a6a3602042001200441066a3602004200210a410121060c570b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200220022800b30c3600c30b200220022802b00c22053602c00b200320076b2203417e6a4104490d03200241b00c6a410f6a290000210b200241cf0c6a310000211820022900b70c211720022900c70c210a20022f00c10b210820022800c30b210941022106200420076a220441026a280000210e20012003417a6a3602042001200441066a36020020022017370380082002200b370388082002200a37039008200a423888201842ff018342088684a721042017421888a721012017420888a7210320024180086a410f6a290000210b200229008708210a2017a721070c580b200541ff0171450d02200241003a00d00c0c020b20064104490d012004280002210920012003417a6a3602042001200441066a3602004200210a410321060c550b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200241e80b6a41106a200241b00c6a410f6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022800b30c3600c30b200220022802b00c22053602c00b200220022d00c60b3a00e80b200220022900b70c220ba722063b00e90b200220064110763a00eb0b2002200b421888200a422886843702ec0b41042106200320076b2203417e6a4104490d01200241cf0c6a310000210b20022900c70c210a20022d00c10b210c20022801c20b2108200420076a220441026a280000210e20012003417a6a3602042001200441066a36020020024180096a41086a200241e80b6a410172220141086a2900003703002002200129000022173703800920022d00e80b41187420084108767221092002200a37039009200a423888200b42ff018342088684a72104200c200841087472210820024180096a410f6a290000210b200228008309210120022f0081092103200229008709210a2017a721070c560b200541ff0171450d00200241003a00d00c0b2000411b3602000c5a0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541034b0d00024002400240024020050e0400010203000b200241b00c6a200110920620022d00b00c4102460d03200241c40c6a290200210a200241bc0c6a290200210b200241cc0c6a2902002117200241b80c6a280200210420022802b40c210320022802b00c2105200241d8006a200110f60120022802580d03200241e8006a290300211841012101200229036021190c550b200241b00c6a200110920620022d00b00c4102460d02200241c40c6a290200210a200241bc0c6a290200210b200241cc0c6a2902002117200241b80c6a280200210420022802b40c210320022802b00c210520024188016a200110f601200229038801a70d0220024188016a41106a29030021182002290390012119200241f0006a200110f6012002290370a70d02200241f0006a41106a290300211a2002290378211b410221010c540b200241b00c6a200110920620022d00b00c4102460d01200241c40c6a290200210a200241bc0c6a290200210b200241cc0c6a2902002117200241b00c6a41086a2206280200210420022802b40c210320022802b00c2105200241b00c6a200110920620022d00b00c4102460d0120024190066a41206a2207200241b00c6a41206a28020036020020024190066a41186a2209200241b00c6a41186a29030037030020024190066a41106a2208200241b00c6a41106a29030037030020024190066a41086a2006290300370300200220022903b00c37039006200241a0016a200110f60120022903a001a70d01200241a0016a41106a290300211c20022903a801211d2009290300211a2008290300211b20024198066a29030021182007350200211e2002290390062119410321010c530b200241b00c6a200110920620022d00b00c4102460d00200241c40c6a290200210a200241bc0c6a290200210b200241cc0c6a2902002117200241b80c6a280200210420022802b40c210320022802b00c2105200241b8016a200110f60120022802b8010d00200241c8016a29030021184104210120022903c00121190c520b2000411b3602000c590b2006450d4d20042d0001210520012003417e6a221f3602042001200441026a360200200541174b0d4d4104210d02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e1800010267030405060708090a0b0c0d0e0f10111213151617000b200241e00e6a200110920620022d00e00e4102460d64200241fc0e6a290200210b200241f40e6a290200210a200241ec0e6a290200211920022902e40e211e20022802e00e2109200241d0016a200110f60120022903d001a70d6420072802002204450d64200241e0016a290300211820022903d8012117200128020022032d0000210e20012004417f6a3602044101210d2001200341016a360200200e41024b0d64200241a80b6a41106a200241b00c6a41106a290200370300200241a80b6a41086a200241b00c6a41086a290200370300200241900b6a41086a20024180096a41086a290300370300200241900b6a41106a20024180096a41106a290300370300200241f80a6a41086a20024180086a41086a290200370300200241f80a6a41106a20024180086a41106a290200370300200220022902b00c3703a80b20022002290380093703900b20022002290280083703f80a200241e00a6a41106a200241980c6a41106a290300370300200241e00a6a41086a200241980c6a41086a290300370300200220022903980c3703e00a201e422088a72106200b422088a7210f200b421088a72120200b420888a721212019422088a72114201ea721082019a7210c0c660b200241e8016a200110f60120022903e801a70d63200241e8016a41106a290300210a20022903f001210b200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a200b422088a72106200a422088a72114200ba72108200aa7210c4102210d0c650b20024180026a200110f601200229038002a70d6220024180026a41106a290300210a200229038802210b200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a200b422088a72106200a422088a72114200ba72108200aa7210c4103210d0c640b20024198026a200110c4012002280298020d61200228029c022109200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a4105210d0c620b200241a0026a200110c40120022802a0020d6020022802a4022203200728020041246e2204200420034b1bad42247e220a422088a70d30200aa72204417f4c0d300240024020040d00410421090c010b200410332209450d250b41002106200241003602880c200220093602800c2002200441246e22083602840c024002402003450d0041002106200241e00e6a41206a2114200241e00e6a41106a21130340200241e00e6a200110920620022802840c210420022d00e00e22054102460d022014310000210a2013290300210b20022903f80e211720022903e80e211820022f01820f210720022d00810f210820022802e40e210e20022f01e20e210c20022d00e10e210d024020062004470d00200241800c6a20064101108d0120022802800c210920022802880c21060b2009200641246c6a220420073b0022200420083a0021200420173700182004200e3600042004200c3b00022004200d3a0001200420053a0000200441206a200a3c000020042018370008200441106a200b3700002002200641016a22063602880c2003417f6a22030d000b20022802840c21080b2009450d61200241a80b6a41106a200241b00c6a41106a290200370300200241a80b6a41086a200241b00c6a41086a290200370300200241900b6a41086a20024180096a41086a290300370300200241900b6a41106a20024180096a41106a290300370300200241f80a6a41086a20024180086a41086a290200370300200241f80a6a41106a20024180086a41106a290200370300200220022902b00c3703a80b20022002290380093703900b20022002290280083703f80a200241e00a6a41106a200241980c6a41106a290300370300200241e00a6a41086a200241980c6a41086a290300370300200220022903980c3703e00a4106210d0c630b2004450d60200441246c0d5d0c600b4107210d0c610b201f450d5e20042d0002210e20012003417d6a3602042001200441036a360200200e41024b0d5e200241a80b6a41106a200241e00e6a41106a2901003703004108210d200241a80b6a41086a200241e00e6a41086a290100370300200241900b6a41086a200241b00c6a41086a290100370300200241900b6a41106a200241b00c6a41106a290100370300200241f80a6a41086a20024180096a41086a290100370300200241f80a6a41106a20024180096a41106a290100370300200220022901e00e3703a80b200220022901b00c3703900b20022002290180093703f80a200241e00a6a41106a20024180086a41106a290100370300200241e00a6a41086a20024180086a41086a29010037030020022002290180083703e00a410021144100210c410021060c600b200241e00e6a200110920620022d00e00e4102460d5d200241d00b6a41086a2201200241fc0e6a280200360200200241a80b6a41086a200241b00c6a41086a290200370300200241a80b6a41106a200241b00c6a41106a2902003703002002200241f40e6a290200220a3703d00b200220022902b00c3703a80b200241800f6a280200210f200241ec0e6a290200211720022802e00e210920022902e40e21182001310000210b20022f01da0b212020022d00d90b2121200241900b6a41106a20024180096a41106a290300370300200241900b6a41086a20024180096a41086a29030037030020022002290380093703900b200241f80a6a41106a20024180086a41106a290200370300200241f80a6a41086a20024180086a41086a29020037030020022002290280083703f80a200241e00a6a41106a200241980c6a41106a290300370300200241e00a6a41086a200241980c6a41086a290300370300200220022903980c3703e00a2018422088a721062017422088a721142018a721082017a7210c4109210d0c5f0b200241a8026a200110c40120022802a8020d5c20022802ac022109200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a410a210d0c5d0b410b210d0c5d0b410c210d0c5c0b200241980c6a200110c30120022802980c2209450d59200241a80b6a41086a200241e00e6a41086a290200370300200241a80b6a41106a200241e00e6a41106a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200229029c0c210a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a200a422088a72106200aa72108410d210d0c5b0b41002105200241003a00800f2003417e6a21072003417d6a21030240034020072005460d01200241e00e6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00800f2003417f6a21032006210520064120470d000b20024198096a2201200241ff0e6a2d00003a000020024180096a41106a200241f70e6a290000220a370300200241a80b6a41086a200241b00c6a41086a290000370300200241a80b6a41106a200241b00c6a41106a290000370300200220022900b00c3703a80b200241ef0e6a290000211720022800e30e210920022f00e10e212220022d00e00e210e20022900e70e21182001310000210b200241900b6a41106a20024180086a41106a290000370300200241900b6a41086a20024180086a41086a29000037030020022002290080083703900b200241f80a6a41106a200241980c6a41106a290000370300200241f80a6a41086a200241980c6a41086a290000370300200220022900980c3703f80a200241e00a6a41106a200241800c6a41106a290000370300200241e00a6a41086a200241800c6a41086a290000370300200220022900800c3703e00a2018422088a721062017422088a721142018a721082017a7210c410e210d0c5b0b200541ff0171450d58200241003a00800f0c580b410f210d0c590b201f4104490d562004280002210920012003417a6a3602042001200441066a360200200241b0026a200110c40120022802b0020d56200728020020022802b4024102742204490d562004417f4c0d260240024020040d004200210a410121080c010b200410392208450d1b20072802002004490d30200820012802002004109d081a200128020422032004490d2f2001200320046b3602042001200128020020046a3602002004ad210a0b2008450d560240200a2004ad42208684220a422088a722010d00200aa721010c550b024020082001724103710d00200aa722014103710d0020014102762206450d55200a422288a7210c0c560b200aa7450d56200810350c560b201f4104490d552004280002210920012003417a6a3602042001200441066a360200200241b8026a200110c40120022802b8020d5520022802bc02220d200728020041246e22042004200d4b1bad42247e220a422088a70d25200aa72204417f4c0d250240024020040d00410421080c010b200410332208450d1a0b4100210c200241003602880c200220083602800c2002200441246e22063602840c024002400240200d450d00200241ef0e6a2113200241e00e6a411f6a210f200241f40b6a2110200241f00b6a21114100210c410021140340200241003a00800f201441016a211420072802002106417f210341002104034020062004460d03200241e00e6a20046a2001280200220e2d00003a00002001200620036a3602042001200e41016a3602002002200441016a22053a00800f2003417f6a21032005210420054120470d000b200220022800e30e3600c30b200220022802e00e3602c00b200620056b22044104490d032013290000210a200f310000211720022900e70e210b20022900f70e2118200e28000121032001200e41056a36020020012004417c6a360204200241e80b6a41106a2205200a4238883c00002010200a4218883e0200200220022d00c60b3a00e80b2002200ba722043b00e90b200220044110763a00eb0b2002200b421888200a422886843702ec0b20022d00c00b210620022d00c10b210e20022801c20b21120240200c20022802840c470d00200241800c6a200c4101108d0120022802800c210820022802880c210c0b2008200c41246c6a220420123601022004200e3a0001200420063a000020052d000021052011290200210a20022902e80b210b2004411f6a20173c0000200420183700172004200b370106200420033602202004410e6a200a370100200441166a20053a00002002200c41016a220c3602880c2014200d470d000b20022802840c21060b2008450d57200241a80b6a41106a200241b00c6a41106a290200370300200241a80b6a41086a200241b00c6a41086a290200370300200241900b6a41086a20024180096a41086a290200370300200241900b6a41106a20024180096a41106a290200370300200241f80a6a41086a20024180086a41086a290200370300200241f80a6a41106a20024180086a41106a290200370300200220022902b00c3703a80b20022002290280093703900b20022002290280083703f80a200241e00a6a41106a200241980c6a41106a290200370300200241e00a6a41086a200241980c6a41086a290200370300200220022902980c3703e00a4111210d0c590b200441ff0171450d00200241003a00800f0b20022802840c2201450d55200141246c450d55200810350c550b201f4104490d542004280002210920012003417a6a3602042001200441066a360200200241a80b6a41086a20024180096a41086a290200370300200241a80b6a41106a20024180096a41106a290200370300200241900b6a41086a200241980c6a41086a290300370300200241900b6a41106a200241980c6a41106a29030037030020022002290280093703a80b200220022903980c3703900b20022d00d90b212120022f01da0b212020022802dc0b210f200241f80a6a41106a200241800c6a41106a290200370300200241f80a6a41086a200241800c6a41086a290200370300200241e00a6a41086a200241e80b6a41086a290300370300200241e00a6a41106a200241e80b6a41106a290300370300200220022902800c3703f80a200220022903e80b3703e00a200241c80c6a290300211a20022903c00c211b4112210d0c030b41002105200241003a00800f2003417e6a2109417d21060240034020092005460d01200241e00e6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00800f2006417f6a21062007210520074120470d000b20024180096a41186a2205200241ff0e6a2d00003a000020024180096a41106a200241f70e6a290000220a370300200320076b2203417e6a4104490d54200241ef0e6a290000211720022800e30e210920022f00e10e212220022d00e00e210e20022900e70e21182005310000210b200420076a220441026a280000210f20012003417a6a3602042001200441066a360200200241a80b6a41086a200241980c6a41086a290200370300200241a80b6a41106a200241980c6a41106a290200370300200241900b6a41086a200241800c6a41086a290300370300200241900b6a41106a200241800c6a41106a290300370300200241f80a6a41086a200241e80b6a41086a290200370300200241f80a6a41106a200241e80b6a41106a290200370300200220022902980c3703a80b200220022903800c3703900b200220022902e80b3703f80a200241e00a6a41106a200241d00b6a41106a290300370300200241e00a6a41086a200241d00b6a41086a290300370300200220022903d00b3703e00a2018422088a721062017422088a72114200241b00c6a41186a290300211a20022903c00c211b2018a721082017a7210c4113210d0c560b200541ff0171450d53200241003a00800f0c530b200241c0026a200110f60120022903c002a70d52200241c0026a41106a290300210a20022903c802210b200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a200b422088a72106200a422088a72114200ba72108200aa7210c4114210d0c540b200241d8026a200110c40120022802d8020d5120022802dc022109200241a80b6a41086a20024180096a41086a290200370300200241a80b6a41106a20024180096a41106a290200370300200241900b6a41086a20024180086a41086a290300370300200241900b6a41106a20024180086a41106a290300370300200241f80a6a41086a200241980c6a41086a290200370300200241f80a6a41106a200241980c6a41106a29020037030020022002290280093703a80b20022002290380083703900b200220022902980c3703f80a20022802f40b210f20022f01f20b212020022d00f10b2121200241e00a6a41106a200241800c6a41106a290300370300200241e00a6a41086a200241800c6a41086a290300370300200220022903800c3703e00a200241c80c6a290300211a20022903c00c211b4115210d0b410021144100210c41002106410021080c520b41002105200241003a00800f2003417e6a21072003417d6a21030240034020072005460d01200241e00e6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00800f2003417f6a21032006210520064120470d000b20024198096a2201200241ff0e6a2d00003a000020024180096a41106a200241f70e6a290000220a370300200241a80b6a41086a200241b00c6a41086a290000370300200241a80b6a41106a200241b00c6a41106a290000370300200220022900b00c3703a80b200241ef0e6a290000211720022800e30e210920022f00e10e212220022d00e00e210e20022900e70e21182001310000210b200241900b6a41106a20024180086a41106a290000370300200241900b6a41086a20024180086a41086a29000037030020022002290080083703900b200241f80a6a41106a200241980c6a41106a290000370300200241f80a6a41086a200241980c6a41086a290000370300200220022900980c3703f80a200241e00a6a41106a200241800c6a41106a290000370300200241e00a6a41086a200241800c6a41086a290000370300200220022900800c3703e00a2018422088a721062017422088a721142018a721082017a7210c4116210d0c520b200541ff0171450d4f200241003a00800f0c4f0b200241e0026a200110c40120022802e0020d4e200728020020022802e4024101742204490d4e2004417f4c0d1e0240024020040d004200210a410121090c010b200410392209450d1320072802002004490d4c200920012802002004109d081a200128020422032004490d292001200320046b3602042001200128020020046a3602002004ad210a0b2009450d4e02402004ad422086200a84220a422088a722040d00200aa721040c4a0b024020092004724101710d00200aa722044101710d0020044101762208450d4a200a422188a721060c4b0b200aa70d4b0c4e0b200241e8026a200110c40120022802e8020d4d200728020020022802ec024101742204490d4d2004417f4c0d1d0240024020040d004200210a410121090c010b200410392209450d1220072802002004490d4b200920012802002004109d081a200128020422032004490d292001200320046b3602042001200128020020046a3602002004ad210a0b2009450d4d02402004ad422086200a84220a422088a722040d00200aa721040c470b024020092004724101710d00200aa722044101710d0020044101762208450d47200a422188a721060c480b200aa70d4a0c4d0b2006450d2a20042d0001210520012003417e6a3602042001200441026a360200200541014b0d2a410021040240024020050e020001000b200241b00c6a200110c20220022d00b00c4101460d2b20024190066a200241b00c6a410172418001109d081a200241f0026a200110c40120022802f0020d2b200728020020022802f4022203490d2b2003417f4c0d1d0240024020030d004200210a410121040c010b200310392204450d1220072802002003490d2b200420012802002003109d081a200128020422052003490d2a2001200520036b3602042001200128020020036a3602002003ad210a0b2004450d2b200a2003ad42208684210a20024180096a20024190066a418001109d081a0b20024180086a20024180096a418001109d081a200041086a200a3702002000200436020420004108360200200041106a20024180086a418001109d081a20004190016a200241e00e6a41a001109d081a0c570b02402006450d0020042d0001210520012003417e6a22233602042001200441026a3602002005411c4b0d00410e2113410021090240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e1d000102030405060708090a0b0c610d0e0f101112131415161718191a1b000b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b200241bf0c6a2900002119200241cf0c6a310000210a20022900b70c210b20022900c70c211e200241c50b6a2d0000210420022d00c10b210820022d00c20b210e20022d00c60b210d20022f00c30b2103200241f8026a200110f60120022903f802a70d1d200241f8026a41106a29030021182002290380032117201e422088200a42ff018342208684210a200320044110747241ffffff077121092019420888a721122019421088a7210f2019422088a72111201ea721102019a72116410121130c610b200541ff0171450d1c200241003a00d00c0c1c0b20024190036a200110c4012002280290030d1b2002280294032209411876210d410221130c5d0b20024198036a200110c4012002280298030d1a200228029c032109200241b00c6a200110ca0220022d00b00c4102460d1a2009411876210d200241c40c6a350200200241b00c6a41186a31000042208684210a200241d00c6a2903002117200241cc0c6a2802002114200241ca0c6a2f01002115200241c90c6a2d0000210c200241c00c6a2802002110200241bc0c6a2802002111200241ba0c6a2f0100210f200241b90c6a2d00002112200241b80c6a2d0000211620022903b00c210b42002118410321134100210e0c5e0b200241a0036a200110c40120022802a0030d1920022802a4032109200241b00c6a200110ca0220022d00b00c4102460d192009411876210d200241c40c6a350200200241b00c6a41186a31000042208684210a200241d00c6a2903002117200241cc0c6a2802002114200241ca0c6a2f01002115200241c90c6a2d0000210c200241c00c6a2802002110200241bc0c6a2802002111200241ba0c6a2f0100210f200241b90c6a2d00002112200241b80c6a2d0000211620022903b00c210b42002118410421134100210e0c5d0b20234104490d182004280002210920012003417a6a3602042001200441066a3602002009411876210d410521130c5a0b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116410621130c5c0b200541ff0171450d17200241003a00d00c0c170b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116410721130c5b0b200541ff0171450d16200241003a00d00c0c160b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116410821130c5a0b200541ff0171450d15200241003a00d00c0c150b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b200320076b2203417e6a4104490d15200241c50b6a2d0000210920022f00c30b210c200241bf0c6a290000210a200241cf0c6a310000211920022900b70c210b20022900c70c211820022d00c10b210820022d00c20b210e20022d00c60b210d200420076a220441026a280000211420012003417a6a22053602042001200441066a220736020020054104490d15200a422088a72111200a421088a7210f200a420888a72112200aa72116200735000021172001200341766a36020420012004410a6a3602002018422088201942ff018342208684210a200c20094110747241ffffff077121092018a7211042002118410921130c590b200541ff0171450d14200241003a00d00c0c140b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116410a21130c580b200541ff0171450d13200241003a00d00c0c130b200241a8036a200110c40120022802a8030d1220022802ac032209411876210d410b21130c540b20234104490d112004280002210920012003417a6a3602042001200441066a3602002009411876210d410c21130c530b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116410d21130c550b200541ff0171450d10200241003a00d00c0c100b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109410f2113200241b00c6a410f6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a721160c540b200541ff0171450d0f200241003a00d00c0c0f0b41002105200241003a00d00c2003417e6a2108417d21070240034020082005460d01200241b00c6a20056a200420056a220641026a2d00003a00002001200320076a3602042001200641036a3602002002200541016a22093a00d00c2007417f6a21072009210520094120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b2003417e6a2009460d0f200241c50b6a2d0000211420022f00c30b2110200241bf0c6a290000210a200241cf0c6a310000211e20022900b70c210b20022900c70c211920022d00c10b210820022d00c20b210e20022d00c60b210d200420096a220441026a2d0000210c2001200320076a22053602042001200441036a360200200c41064b0d0f4110211320054110490d0f200a422088a72111200a421088a7210f200a420888a72112200aa721162004410b6a2900002118200441036a29000021172001200320096b416d6a3602042001200441136a3602002019422088201e42ff018342208684210a201020144110747241ffffff077121092019a721100c530b200541ff0171450d0e200241003a00d00c0c0e0b411121130c500b411221130c4f0b200241b0036a200110c40120022802b0030d0b200728020020022802b4032204490d0b2004417f4c0d270240024020040d004200210a410121090c010b200410392209450d1c20072802002004490d0b200920012802002004109d081a200128020422032004490d372001200320046b3602042001200128020020046a3602002004ad210a0b2009450d0b200a2004ad42208684210b2009411876210d411321134100210e0c4f0b200241b8036a200110c40120022802b8030d0a200728020020022802bc032204490d0a2004417f4c0d260240024020040d004200210a410121090c010b200410392209450d1b20072802002004490d0a200920012802002004109d081a200128020422032004490d372001200320046b3602042001200128020020046a3602002004ad210a0b2009450d0a200a2004ad42208684210b2009411876210d411421134100210e0c4e0b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116411521130c4e0b200541ff0171450d09200241003a00d00c0c090b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022800c30b2209411876210d20022f00c10b2208410876210e200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b2018a721102017a72116411621130c4d0b200541ff0171450d08200241003a00d00c0c080b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20064180fe0371410876210820022801c20b220e4108762109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c60b210d2018a721102017a72116411721130c4c0b200541ff0171450d07200241003a00d00c0c070b20234104490d062004280002210920012003417a6a3602042001200441066a360200411821132009411876210d0c480b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b20024198086a200241cf0c6a310000220a3c0000200220022800b30c3600c30b200220022802b00c22063602c00b200220022900c70c221837039008200220022900b70c220b370380082002200241bf0c6a290000221737038808200320076b2203417e6a4104490d06200241c50b6a2d0000210520022f00c30b210920022d00c10b210820022d00c20b210e20022d00c60b210d200420076a220441026a280000211420012003417a6a3602042001200441066a3602002018422088200a42ff018342208684210a200920054110747241ffffff077121092017422088a72111201742ffffffff0f832219421088a7210f2019420888a721122018a721102017a72116411921130c4a0b200541ff0171450d05200241003a00d00c0c050b41002105200241003a00d00c2003417e6a2109417d21070240034020092005460d01200241b00c6a20056a200420056a220641026a2d00003a00002001200320076a3602042001200641036a3602002002200541016a220e3a00d00c2007417f6a2107200e2105200e4120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b2003417e6a200e460d05200241bf0c6a2900002119200241cf0c6a310000210a20022900b70c210b20022900c70c211e20022f00c10b210820022800c30b21092004200e6a220441026a2d0000210c2001200320076a22053602042001200441036a360200200c41064b0d0520054110490d052004410b6a2900002118200441036a290000211720012003200e6b416d6a3602042001200441136a360200201e422088200a42ff018342208684210a2009411876210d20084180fe0371410876210e2019422088a721112019421088a7210f2019420888a72112201ea721102019a72116411a21130c490b200541ff0171450d04200241003a00d00c0c040b411b21130c460b20234104490d022004280002210920012003417a6a3602042001200441066a3602002009411876210d411c21130c440b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200241e80b6a41106a200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022800b30c3600c30b200220022802b00c22063602c00b200220022d00c60b3a00e80b200220022900b70c220ba722053b00e90b200220054110763a00eb0b2002200b421888200a422886843702ec0b200320076b2203417e6a4104490d02200241cf0c6a310000210a20022900c70c211720022d00c10b210820022801c20b210e200420076a220441026a280000211420012003417a6a3602042001200441066a36020020024180096a41086a200241e80b6a410172220141086a290000220b3703002017422088200a42ff018342208684210a200e4108762109200ba721162001290000210b20022d00e80b210d20022d008909211220022f018a09210f200228028c0921112017a72110411d21130c460b200541ff0171450d01200241003a00d00c0c010b200910350b2000411b3602000c560b200241b00c6a2001109306024020022d00b00c4106460d0020024190066a41286a200241b00c6a41286a290300220a37030020024190066a41206a200241b00c6a41206a290300220b37030020024190066a41186a200241b00c6a41186a290300221737030020024190066a41106a200241b00c6a41106a290300221837030020024190066a41086a200241b00c6a41086a2903002219370300200220022903b00c221e370390062000410a3602002000201e3702042000410c6a2019370200200041146a20183702002000411c6a2017370200200041246a200b3702002000412c6a200a370200200041346a200241e00e6a41fc01109d081a0c560b2000411b3602000c550b200241b00c6a2001109306024020022d00b00c4106460d0020024190066a41286a200241b00c6a41286a290300220a37030020024190066a41206a200241b00c6a41206a290300220b37030020024190066a41186a200241b00c6a41186a290300221737030020024190066a41106a200241b00c6a41106a290300221837030020024190066a41086a200241b00c6a41086a2903002219370300200220022903b00c221e370390062000410b3602002000201e3702042000410c6a2019370200200041146a20183702002000411c6a2017370200200041246a200b3702002000412c6a200a370200200041346a200241e00e6a41fc01109d081a0c550b2000411b3602000c540b2006450d3d20042d0001210520012003417e6a360204410221032001200441026a360200200541054b0d3d02400240024002400240024020050e06000501020304000b200241b00c6a200110c30120022802b00c2204450d42200241b80c6a280200210720022802b40c2106200241c0036a200110f601024020022903c003a70d00200241d0036a290300211720022903c803210b410121030c050b200641ffffff3f71450d42200410350c420b200241b00c6a200110920620022d00b00c4102460d41200241c40c6a2902002117200241bc0c6a290200210b200241cc0c6a290200210a200241b80c6a280200210720022802b40c210620022802b00c2104410321030c030b410421030c020b410521030c010b200241b00c6a200110920620022d00b00c4102460d3e200241c40c6a2902002117200241bc0c6a290200210b200241cc0c6a290200210a200241b80c6a280200210720022802b40c210620022802b00c2104410621030b2000410c360200200041206a2017370200200041186a200b370200200041286a200a370200200041146a2007360200200041106a20063602002000410c6a2004360200200041086a2003360200200041306a200241e00e6a418002109d081a0c530b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541064b0d004200211941072106410021074200211c4200211b4200211a4200210b420021244200212502400240024002400240024020050e0700010203040542000b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200241e80b6a41106a200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022800b30c3600c30b200220022802b00c22083602c00b200220022900b70c220ba722013b00e90b200220014110763a00eb0b2002200b421888200a422886843702ec0b20022900c70c220b422088200241cf0c6a31000042208684210a20022801c20b2209410876210720022d00c10b210e20022d00c60b210c200241f10b6a290000211820022900e90b2117200ba7211142002119410121060c400b200541ff0171450d05200241003a00d00c0c050b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200241e80b6a41106a2201200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e020020024190066a41106a20012d00003a0000200220022900b70c220b421888200a422886843702ec0b20024190066a41086a200241e80b6a41086a290200370300200220022800b30c3600c30b200220022d00c60b3a00e80b2002200ba722013b00e90b200220014110763a00eb0b200220022802b00c22083602c00b200220022902e80b3703900620022d00c10b210e20022801c20b210920022900c70c210b200241a9066a200241cf0c6a310000220a3c00002002200b3700a106200b422088200a42208684210a2009410876210720024199066a2900002118200229009106211720022d009006210c200ba7211142002119410221060c3f0b200541ff0171450d04200241003a00d00c0c040b41002105200241003a00d00c410220036b21092003417d6a2106024002400340200920056a450d01200241b00c6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200241e80b6a41106a200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022802b00c22083602c00b200220022800b30c3600c30b200220022900b70c220ba722053b00e90b200220054110763a00eb0b2002200b421888200a422886843702ec0b200241cf0c6a310000210a20022900c70c210b20022d00c10b210e20022d00c60b210c20022801c20b2109200241f10b6a290000211820022900e90b211741002105200241003a00d00c200420076a210d200720036b41026a2103200941087621070340200320056a450d02200241b00c6a20056a200d20056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00d00c2006417f6a21062004210520044120470d000b200241e80b6a41106a200241bf0c6a29000022194238883c0000200241f40b6a20194218883e0200200220022800b30c3600c30b200220022802b00c22103602c00b200220022900b70c221ea722013b00e90b200220014110763a00eb0b2002201e4218882019422886843702ec0b20022d00c60b41187420022801c20b2201410876722113200b422088200a42ff018342208684210a200141087420022d00c10b72210f20022900e90b221e42ffffffff0f832119201e42808080807083211b200241f10b6a290000221e42ffffffff0f832124201e428080808070832125200241cf0c6a310000211d20022900c70c211e200ba721114200211c410321064200211a4200210b0c410b200541ff0171450d04200241003a00d00c0c040b200541ff0171450d03200241003a00d00c0c030b200241b00c6a200110c30120022802b00c2207450d022007411876210c20023502840920024188096a31000042208684210a20022902b40c211720022d008909211020022f018a09210f20022d008908210d20022f018a082114420021184104210641002109420021190c3d0b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22083602c00b20022900c70c220b422088200241cf0c6a31000042208684210a20022801c20b22094108762107200241bf0c6a290000211820022900b70c211720022d00c10b210e20022d00c60b210c200ba7211142002119410521060c3c0b200541ff0171450d01200241003a00d00c0c010b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200241e80b6a41106a200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022900b70c220b421888200a422886843702ec0b20024180096a41086a2201200241f10b6a290000370300200220022800b30c3600c30b2002200ba722043b00e90b200220044110763a00eb0b200220022802b00c22083602c00b200220022d00c60b220c3a00e80b200220022900e90b3703800920022d00c10b210e20022801c20b210920022900c70c210b20024198096a200241cf0c6a310000220a3c00002002200b37039009200b422088200a42208684210a20094108762107200129030021182002290380092117200ba7211142002119410621060c3b0b200541ff0171450d00200241003a00d00c0b2000411b3602000c520b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241d8036a200110c40120022802d8030d0020022802dc0321012000410e36020020002001360204200041086a200241e00e6a41a802109d081a0c520b2000411b3602000c510b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e0036a200110c40120022802e0030d00200728020020022802e4032204490d002004417f4c0d1602400240024020040d004200210a410121030c010b200410392203450d0c20072802002004490d01200320012802002004109d081a200128020422052004490d292001200520046b3602042001200128020020046a3602002004ad210a0b2003450d01200020033602042000410f360200200041086a200a2004ad42208684370200200041106a200241e00e6a41a002109d081a0c520b200310350b2000411b3602000c500b2006450d3320042d0001210520012003417e6a3602042001200441026a360200200541074b0d3302400240024002400240024002400240024020050e080001020304050607000b200241e8036a200110f60120022903e803a70d3b200241f8036a290300210a20022903f003210b200241b00c6a200110920620022d00b00c4102460d3b200241d80b6a2205200241cc0c6a2802003602002002200b3703980c2002200a3703a00c20022902b40c2219421888200241bc0c6a290200220b42288684210a20022802b00c22034118762101200b4218882118200241c40c6a290200210b200241d00c6a28020021042005310000211720022f01da0b210720022d00d90b21092019a721084101210e4100210c0c3d0b20024180046a200110c4012002280280040d3a2002280284042103200241980c6a41106a200241b00c6a41106a290300370300200241980c6a41086a200241b00c6a41086a290300370300200220022903b00c3703980c200341187621014200210a4102210e0c3b0b20024188046a200110c4012002280288040d39200228028c042103200241980c6a41106a200241b00c6a41106a290300370300200241980c6a41086a200241b00c6a41086a290300370300200220022903b00c3703980c200341187621014200210a4103210e0c3a0b20024190046a200110c4012002280290040d3820072802002002280294042206490d382006417f4c0d1902400240024020060d004200210a410121040c010b200610392204450d0f20072802002006490d01200420012802002006109d081a200128020422032006490d2d2001200320066b3602042001200128020020066a3602002006ad210a0b2004450d3941002105200241003a00d00c2007280200417f6a2103200a2006ad42208684220a422088a72109200aa72107024003402003417f460d01200241b00c6a20056a200128020022062d00003a0000200120033602042001200641016a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22053602c00b2002200936029c0c200220073602980c20022900b70c2219421888200241bf0c6a290000220b42288684210a20054180fe03714108762106200b421888211820022801c20b220c4108762103200241cf0c6a310000211720022900c70c210b20022d00c60b21012019a721084104210e0c3c0b0240200541ff0171450d00200241003a00d00c0b2007450d390b200410350c380b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200241980c6a41086a20024190066a41086a290000370300200241980c6a41106a20024190066a41106a290000370300200220022800b30c3600c30b200220022802b00c22053602c00b20022002290090063703980c20022900b70c2219421888200241bf0c6a290000220b42288684210a200b421888211820022800c30b2203411876210120022f00c10b2206410876210c200241cf0c6a310000211720022900c70c210b2019a721084105210e0c3a0b200541ff0171450d37200241003a00d00c0c370b20024198046a200110c4012002280298040d362007280200200228029c042205490d362005417f4c0d170240024020050d004200210a410121040c010b200510392204450d0c20072802002005490d36200420012802002005109d081a200128020422032005490d2b2001200320056b3602042001200128020020056a3602002005ad210a0b2004450d3641002103200241003a00d00c200a2005ad42208684220a422088a7210e200aa7210820072802002107417f21050240034020072003460d01200241b00c6a20036a200128020022092d00003a00002001200720056a3602042001200941016a3602002002200341016a22063a00d00c2005417f6a21052006210320064120470d000b200220022800b30c3600c30b200220022802b00c22053602c00b200720066b22074110490d03200241bf0c6a2900002118200241cf0c6a310000211720022900b70c211920022900c70c210b20022f00c10b210620022800c30b2103200241980c6a41106a200941096a2900003703002009290001210a2001200741706a3602042001200941116a3602002002200e36029c0c200220083602980c2002200a3703a00c2019421888201842288684210a200341187621012018421888211820064180fe0371410876210c2019a721084106210e0c390b0240200341ff0171450d00200241003a00d00c0b2008450d360c350b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b20024180096a41186a200241cf0c6a31000022173c0000200220022800b30c3600c30b200220022802b00c22053602c00b200220022900c70c220b37039009200220022900b70c2219370380092002200241bf0c6a290000221837038809200320076b2209417e6a4110490d3620022f00c10b210620022800c30b2103200420076a220441026a290000210a2004410a6a290000211e20012009416e6a3602042001200441126a3602002002201e3703a00c2002200a3703980c2019421888201842288684210a200341187621012018421888211820064180fe0371410876210c2019a721084107210e0c380b200541ff0171450d35200241003a00d00c0c350b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b4108210e200241980c6a41086a20024190066a41086a290000370300200241980c6a41106a20024190066a41106a290000370300200220022800b30c3600c30b200220022802b00c22053602c00b200220022900b70c220aa722084110763a00eb0b20022002290090063703980c200a421888200241bf0c6a290000220b42288684210a200b421888211820022801c20b220c4108762103200241cf0c6a310000211720022900c70c210b20022d00c10b210620022d00c60b21010c370b200541ff0171450d34200241003a00d00c0c340b20080d320c330b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541044b0d0002400240024002400240024002400240024020050e050001020304000b200241e00e6a200110db0220022d00e80f4102460d08200241a80b6a41086a200241e00e6a41106a290300370300200241a80b6a41106a200241f80e6a2d00003a0000200241980c6a41086a200241900f6a290300370300200241980c6a41106a200241980f6a290300370300200220022903e80e3703a80b200220022903880f3703980c200241fc0e6a2802002104200241840f6a280200210c20022903e00e210a20022d00f90e210520022d00fa0e210620022d00fb0e210820022802800f210d20022903a00f210b20024190066a200241e00e6a41c8006a41c800109d081a200241b00a6a41026a20024180086a41026a2d00003a0000200220022f0080083b01b00a410121010c050b200241a0046a200110c40120022802a0040d07200728020020022802a4042204490d072004417f4c0d1b02400240024020040d004200210a410121090c010b200410392209450d1120072802002004490d01200920012802002004109d081a200128020422032004490d312001200320046b3602042001200128020020046a3602002004ad210a0b2009450d08200a2004ad42208684210a41022101200241b00a6a41026a200241d00b6a41026a2d00003a0000200241a80b6a41086a200241e80b6a41086a290300370300200241a80b6a41106a200241e80b6a41106a2d00003a0000200241980c6a41086a20024180086a41086a290300370300200241980c6a41106a20024180086a41106a290300370300200220022f00d00b3b01b00a200220022903e80b3703a80b20022002290380083703980c20024190066a200241e00e6a41c800109d081a0c040b200910350c070b20024180086a200110920620022d0080084102460d06200241f00b6a20024194086a290200370300200241e80b6a41106a2002419c086a2d00003a000020022002418c086a2902003703e80b2002419d086a2d000021052002419e086a2d000021062002419f086a2d00002108200241a0086a2802002104200229028408210a2002280280082109200241c0046a200110f60120022903c004a70d06200241c0046a41106a290300211720022903c8042118200241b0046a200110910620022903b004a70d0620022903b804210b200241a8046a200110c40120022802a8040d06200728020020022802ac042203490d062003417f4c0d1a0240024020030d00420021194101210d0c010b20031039220d450d0f20072802002003490d06200d20012802002003109d081a200128020422072003490d302001200720036b3602042001200128020020036a3602002003ad21190b200d450d06200241a80b6a41106a200241e80b6a41106a2d00003a0000200241a80b6a41086a200241e80b6a41086a290300370300200241980c6a41106a2017370300200241b00a6a41026a200241d00b6a41026a2d00003a0000200220022903e80b3703a80b200220183703a00c200220022f00d00b3b01b00a200220192003ad4220868422174220883e02980c20024190066a200241e00e6a41c800109d081a2017a7210c410321010c030b200241f0046a200110f60120022903f004a70d0520024180056a290300210b20022903f8042117200241e0046a200110910620022903e004a70d0520022903e804211841002103200241003a00a0082007280200417f6a2104024002400240024003402004417f460d0120024180086a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a0082004417f6a21042005210320054120470d000b200241e20a6a20022d0082083a0000200241e00b6a2002419f086a2d00003a0000200241d80b6a20024197086a2900003703002002200229008f08220a3703e80b200220022f0180083b01e00a2002200a3703d00b200229008708210a2002280083082109200241d8046a200110c40120022802d8040d09200728020020022802dc04220c490d09200c417f4c0d1d200c0d01410121044101450d094100210d0c020b200341ff0171450d08200241003a00a0080c080b200c10392204450d0f2007280200200c490d0120042001280200200c109d08210320012802042205200c490d3120012005200c6b36020420012001280200200c6a3602002003450d07200c210d0b200241b00a6a41026a200241e00a6a41026a2d00003a0000200241a80b6a41086a200241d00b6a41086a290300370300200241a80b6a41106a200241d00b6a41106a2d00003a0000200220022f01e00a3b01b00a200220022903d00b3703a80b200220173703980c200220183703a80c2002200b3703a00c20024190066a200241e00e6a41c800109d081a410421010c020b200410350c050b41002105200241003a00a0082003417e6a21092003417d6a2106024002400240034020092005460d0120024180086a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00a0082006417f6a21062007210520074120470d000b200241c80a6a41026a20022d0082083a0000200241e00b6a2002419f086a2d00003a0000200241d80b6a20024197086a2900003703002002200229008f08220a3703e80b200220022f0180083b01c80a2002200a3703d00b2003417e6a2007460d07200229008708210a2002280083082109200420076a220e41026a2d00002114200120063602042001200e41036a360200201441014b0d074100210520140e020201020b200541ff0171450d06200241003a00a0080c060b41002104200241003a00a008200720036b41036a2106200320076b417c6a21030340200620046a450d0420024180086a20046a200e20046a220541036a2d00003a0000200120033602042001200541046a3602002002200441016a22053a00a0082003417f6a21032005210420054120470d000b200241e80b6a41106a22012002418f086a290000220b4238883c0000200241f40b6a200b4218883e020020022002280083083600c30b200220022802800822063602c00b200220022d00c60b3a00e80b20022002290087082217a722043b00e90b200220044110763a00eb0b200220174218882218200b422886843702ec0b2002419f086a3100002117200229009708210b20022d00c10b210820022801c20b210420022802e80b210d200241800b6a20012d00003a0000200220022902f00b3703f80a2018a7210c410121050b200241a90c6a20173c0000200241980c6a41086a200241f80a6a41086a2d00003a0000200241b00a6a41026a200241c80a6a41026a2d00003a0000200241a80b6a41086a200241d00b6a41086a290300370300200241a80b6a41106a200241d00b6a41106a2d00003a00002002200b3700a10c200220022903f80a3703980c200220022f01c80a3b01b00a200220022903d00b3703a80b200241ae0c6a200241e40a6a2f01003b0100200220022801e00a3601aa0c20024190066a200241e00e6a41c800109d081a410521010b0b200241980a6a41026a2203200241b00a6a41026a2d00003a0000200241900b6a41086a2207200241a80b6a41086a290300370300200241900b6a41106a220e200241a80b6a41106a2d00003a0000200241800c6a41086a2214200241980c6a41086a290300370300200241800c6a41106a2213200241980c6a41106a290300370300200220022f01b00a3b01980a200220022903a80b3703900b200220022903980c3703800c20024180096a20024190066a41c800109d081a200041086a20013a000020004111360200200020022f01980a3b00092000410b6a20032d00003a0000200041106a200a3702002000410c6a2009360200200041186a20022903900b370000200041206a2007290300370000200041286a200e2d00003a0000200041346a200c360200200041306a200d3602002000412c6a2004360200200020083a002b200020063a002a200020053a0029200041d0006a200b370200200041c8006a2013290300370200200041c0006a2014290300370200200041386a20022903800c370200200041d8006a20024180096a41c800109d081a200041a0016a200241b00c6a419001109d081a0c510b200441ff0171450d01200241003a00a0080c010b200d10350b2000411b3602000c4e0b200241b00c6a2001109406024020022802b00c4104460d0020024190066a41286a200241b00c6a41286a280200220136020020024190066a41206a200241b00c6a41206a290300220a37030020024190066a41186a200241b00c6a41186a290300220b37030020024190066a41106a200241b00c6a41106a290300221737030020024190066a41086a200241b00c6a41086a2903002218370300200220022903b00c22193703900620004112360200200020193702042000410c6a2018370200200041146a20173702002000411c6a200b370200200041246a200a3702002000412c6a2001360200200041306a200241e00e6a418002109d081a0c4e0b2000411b3602000c4d0b02402006450d0020042d0001210520012003417e6a22063602042001200441026a36020020050d0020064104490d002004280002210520012003417a6a3602042001200441066a36020020024198056a200110c4012002280298050d002007280200200228029c052204490d002004417f4c0d1202400240024002400240024002400240024020040d0041002103410121060c010b200410392206450d0e20072802002004490d01200620012802002004109d081a200128020422032004490d312001200320046b3602042001200128020020046a360200200421030b2006450d0720024190056a200110c4012004ad4220862003ad84220ba7210d02402002280290050d0020022802940522082007280200410c6e2204200420084b1bad420c7e220a422088a70d1a200aa72204417f4c0d1a0240024020040d004104210e0c010b20041033220e450d0f0b41002103200241003602b80c2002200e3602b00c20022004410c6e22093602b40c0240024002402008450d0041002103034020024188056a200110c4012002280288050d032007280200200228028c052204490d032004417f4c0d1e0240024020040d004100210c410121090c010b200410392209450d1320072802002004490d03200920012802002004109d081a2001280204220c2004490d372001200c20046b3602042001200128020020046a3602002004210c0b2004ad422086200cad84210a0240200320022802b40c470d00200241b00c6a2003410110870120022802b00c210e20022802b80c21030b200e2003410c6c6a2204200a370204200420093602002002200341016a22033602b80c2008417f6a22080d000b20022802b40c21090b200e450d022006450d0a200728020022074104490d042001280200220c280000211320012007417c6a22043602042001200c41046a36020020044104490d05200c280004210f2001200741786a22043602042001200c41086a36020020044104490d06200b422088a72110200c28000821112001200741746a22143602042001200c410c6a36020041002104200241003a00f00c200741736a2107034020142004460d08200241b00c6a20046a200c20046a2208410c6a2d00003a00002001200736020420012008410d6a3602002002200441016a22083a00f00c2007417f6a210720082104200841c000470d000b200841ff017141c000490d082006450d0a200241e80c6a290300210a200241b80c6a290300210b20022903e00c211720022903b00c211820022802dc0c210120022902d40c211920022802d00c210420022802cc0c210720022f01ca0c210820022d00c80c210c20022903c00c211e200020022d00c90c3a00452000200536020420004113360200200041e4006a200a370200200041dc006a2017370200200041346a200b3702002000412c6a2018370200200041d8006a2001360200200041d0006a2019370200200041cc006a2004360200200041c8006a2007360200200041c6006a20083b0100200041c4006a200c3a00002000413c6a201e370200200041286a2011360200200041246a200f360200200041206a20133602002000411c6a2003360200200041186a2009360200200041146a200e360200200041106a20103602002000410c6a200d360200200041086a2006360200200041ec006a200241e00e6a41c401109d081a0c570b200910350b02402003450d002003410c6c2104200e210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b20022802b40c2201450d002001410c6c450d00200e10350b200d450d070b200610350c060b0240200d450d00200610350b02402003450d002003410c6c2104200e210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b2009450d052009410c6c0d040c050b0240200d450d00200610350b02402003450d002003410c6c2104200e210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b2009450d042009410c6c0d030c040b0240200d450d00200610350b02402003450d002003410c6c2104200e210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b2009450d032009410c6c0d020c030b200441ff0171450d00200241003a00f00c0b0240200d450d00200610350b02402003450d002003410c6c2104200e210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b2009450d012009410c6c450d010b200e10350b2000411b3602000c4c0b02402006450d0020012003417e6a3602042001200441026a3602000b2000411b3602000c4b0b02402006450d0020012003417e6a3602042001200441026a3602000b2000411b3602000c4a0b02402006450d0020012003417e6a3602042001200441026a3602000b2000411b3602000c490b2006450d2a20042d0001210620012003417e6a22263602042001200441026a3602002006410a4b0d2a410421274200212402400240024002400240024002400240024002400240024020060e0b0001020b03040506070809000b41002105200241003a00800f2003417e6a21072003417d6a21030240034020072005460d01200241e00e6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00800f2003417f6a21032006210520064120470d000b200241a80b6a41086a200241b00c6a41086a290000370300200241a80b6a41106a200241b00c6a41106a290000370300200241900b6a41086a20024190066a41086a290000370300200241900b6a41106a20024190066a41106a290000370300200220022900b00c3703a80b20022002290090063703900b200241ef0e6a290000210b200241ff0e6a310000210a20022800e30e210920022f00e10e212820022d00e00e212920022900e70e211720022900f70e2118200241f80a6a41106a20024180096a41106a290000370300200241f80a6a41086a20024180096a41086a29000037030020022002290080093703f80a200241e00a6a41106a20024180086a41106a290000370300200241e00a6a41086a20024180086a41086a29000037030020022002290080083703e00a2018422088200a42208684210a2017422088a72105200b422088a7210f200b4280feffff0f83420888a7212a2018a721142017a72108200ba7210c41012127410021100c0b0b200541ff0171450d35200241003a00800f0c350b200241a0056a200110c40120022802a0050d3420022802a4052206200728020041c8006e2204200420064b1bad42c8007e220a422088a70d17200aa72204417f4c0d170240024020040d00410421090c010b200410332209450d0c0b41002105200241003602c80b200220093602c00b2002200441c8006e22083602c40b0240024002402006450d00200241b00c6a410c6a2110410021050340200241b00c6a200110ad040240024020022d00b00c22034106470d00410621030c010b200241980c6a41086a220e201041086a290200370300200241980c6a41106a220c201041106a290200370300200220102902003703980c20022802b80c210420022802b40c210820022f01b20c210d20022d00b10c2114200241e00e6a200110ad04024020022d00e00e4106470d00024020034101470d002004450d00200810350b410621030c010b200241800c6a41106a200c290300370300200241800c6a41086a200e29030037030020024190066a41086a200241e00e6a41086a29030037030020024190066a41106a200241e00e6a41106a29030037030020024190066a41186a200241e00e6a41186a29030037030020024190066a41206a200241e00e6a41206a280200360200200220022903980c3703800c200220022903e00e37039006200d21112014211220042116200821150b200241e80b6a41086a2204200241800c6a41086a290300370300200241e80b6a41106a2208200241800c6a41106a29030037030020024180096a41086a220e20024190066a41086a29030037030020024180096a41106a220c20024190066a41106a29030037030020024180096a41186a220d20024190066a41186a29030037030020024180096a41206a221420024190066a41206a280200360200200220022903800c3703e80b20022002290390063703800920034106460d02200241d00b6a41106a22132008290300370300200241d00b6a41086a2208200429030037030020024180086a41086a220f200e29030037030020024180086a41106a220e200c29030037030020024180086a41186a220c200d29030037030020024180086a41206a220d2014280200360200200220022903e80b3703d00b2002200229038009370380080240200520022802c40b470d00200241c00b6a2005410110a80120022802c00b210920022802c80b21050b2009200541c8006c6a220420123a0001200420033a0000200441086a2016360000200441046a2015360000200441026a20113b00002004410c6a20022903d00b370000200441146a20082903003700002004411c6a2013290300370000200441246a2002290380083700002004412c6a200f290300370000200441346a200e2903003700002004413c6a200c290300370000200441c4006a200d2802003600002002200541016a22053602c80b2006417f6a22060d000b20022802c40b21080b20090d010c360b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b20022802c40b2201450d35200141c8006c450d35200910350c350b200241e00e6a200110ad0402400240024002400240024002400240024020022d00e00e220c4106460d00200241800f6a280200210d200241f80e6a290300210b200241f40e6a2204280200210e200241ec0e6a2203290200210a200241e80e6a2206280200211420022802e40e210f20022f01e20e212720022d00e10e2128200241e00e6a200110ad0420022d00e00e22104106460d01200241fc0e6a2216290200211920042902002118200329020021172006280200211120022802e40e211320023301e20e212420023100e10e2125200241e00e6a200110ad0420022d00e00e22124106460d0220024180086a41086a200241f40e6a220429020037030020024180086a41106a20162902003703002002200241ec0e6a220329020037038008200241e00e6a41086a2206280200211620022802e40e211520022f01e20e212b20022d00e10e212c200241e00e6a200110ad0420022d00e00e22234106460d0320024180096a41086a200429020037030020024180096a41106a200241fc0e6a220429020037030020022003290200370380092006280200212d20022802e40e212e20022f01e20e212020022d00e10e212f200241e00e6a200110ad0420022d00e00e22304106460d0620024190066a41086a200241f40e6a290200370300200241a0066a20042902003703002002200241ec0e6a29020037039006200241e00e6a41086a280200212220022802e40e212120072802002204450d0720022f01e20e213120022d00e10e2132200128020022032d0000210620012004417f6a22073602042001200341016a360200200641014b0d074200211e410021334200211d20060e020504050b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d3c200841c8006c450d3c200910350c3c0b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d3b200841c8006c450d3b200910350c3b0b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d3a200841c8006c450d3a200910350c3a0b024020124101470d002016450d00201510350b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d39200841c8006c450d39200910350c390b2007450d0220032d0001213420012004417e6a22063602042001200341026a3602002006450d0220032d0002210720012004417d6a22063602042001200341036a3602002006450d0220032d0003213520012004417c6a22063602042001200341046a3602002006450d0220032d0004213620012004417b6a22063602042001200341056a3602002006450d0220032d0005213320012004417a6a22063602042001200341066a3602002006450d0220032d000621372001200441796a22063602042001200341076a3602002006450d0220032d000721382001200441786a22063602042001200341086a3602002006450d0220032d0008211f2001200441776a22063602042001200341096a3602002006450d0220032d000921392001200441766a220636020420012003410a6a3602002006450d0220032d000a213a2001200441756a220636020420012003410b6a3602002006450d0220032d000b21292001200441746a220636020420012003410c6a3602002006450d0220032d000c213b2001200441736a220636020420012003410d6a3602002006450d0220032d000d213c2001200441726a220636020420012003410e6a3602002006450d0220032d000e213d2001200441716a220636020420012003410f6a3602002006450d0220032d000f212a2001200441706a22063602042001200341106a3602002006450d0220032d0010213e20012004416f6a22063602042001200341116a3602002006450d0220032d0011212620012004416e6a22063602042001200341126a3602002006450d0220032d0012213f20012004416d6a22063602042001200341136a3602002006450d0220032d0013214020012004416c6a22063602042001200341146a3602002006450d022003310014211e20012004416b6a3602042001200341156a3602002002203641187420354110747220074108747222042034723602e00e2002203bad4238862029ad42ff018342308684203aad42ff0183422886842039ad42ff018342208684201fad42ff018342188684221d2038ad42ff0183421086842037ad42ff0183420886842033ad42ff0183843702e40e201d421888201e4238862040ad42ff018342308684203fad42ff0183422886842026ad42ff018342208684203ead42ff018342188684202aad42ff018342108684203dad42ff018342088684203cad42ff018384221d42288684211e20044108762135201d421888211d20022800e30e2136410121330b200241e00e6a200110ad0420022d00e00e22374106460d02200241b00c6a41086a2204200241f40e6a290200370300200241b00c6a41106a2203200241fc0e6a2902003703002002200241ec0e6a22062902003703b00c200241e00e6a41086a2207280200213820022802e40e211f20022f01e20e213a20022d00e10e2139200241e00e6a200110ad0420022d00e00e4106470d0b024020374101470d002038450d00201f10350b024020304101470d002022450d00202110350b024020234101470d00202d450d00202e10350b024020124101470d002016450d00201510350b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d37200841c8006c450d37200910350c370b024020234101470d00202d450d00202e10350b024020124101470d002016450d00201510350b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d36200841c8006c450d36200910350c360b024020304101470d002022450d00202110350b024020234101470d00202d450d00202e10350b024020124101470d002016450d00201510350b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d35200841c8006c450d35200910350c350b024020304101470d002022450d00202110350b024020234101470d00202d450d00202e10350b024020124101470d002016450d00201510350b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d34200841c8006c450d34200910350c340b200241a8056a200110c40120022802a8050d3320022802ac052215200728020041c4006e2204200420154b1bad42c4007e220a422088a70d16200aa72204417f4c0d160240024020040d00410421090c010b200410332209450d0b0b200241003602880c200220093602800c2002200441c4006e3602840c024002402015450d00200241e80b6a410172210c20024180096a41186a2123200241f40b6a212c4100210641002108034041002103200241003a00800f200841016a21082007280200417f6a210402400240024003402004417f460d01200241e00e6a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00800f2004417f6a21042005210320054120470d000b200220022800e30e3600c30b200220022802e00e3602c00b200241e00e6a410f6a2900002117200241e00e6a411f6a310000211b20022900e70e211820022900f70e211a200241e00e6a200110ad0420022d00e00e22034106470d01410621030c020b0240200341ff0171450d00200241003a00800f0b410621030c010b200241e80b6a41106a20174238883c0000202c20174218883e0200200220022d00c60b3a00e80b20022018a722043b00e90b200220044110763a00eb0b200220184218882017422886843702ec0b200241e00e6a41106a290300211e200241e00e6a41206a310000211c20022903e80e211920022903f80e211d20022801c20b210e20022d00c10b211420022d00c00b211320022d00e10e210f20022f01e20e211020022802e40e211120022d00810f211220022f01820f2116201a210a201b210b0b2023200b3c000020024180096a41086a2204200c41086a2900003703002002200a370390092002200c2900003703800920034106460d0220022d00e80b2105200e410876210d2004290300211720022903800921180240200620022802840c470d00200241800c6a20064101109f0120022802800c210920022802880c21060b2009200641c4006c6a220420163b0042200420123a00412004201d37003820042011360024200420103b00222004200f3a0021200420033a00202004200a37001720042005411874200d723600032004200e410874201441ff0171723b0001200420133a0000200441c0006a201c3c00002004411f6a200b3c00002004201937002820042018370007200441306a201e3700002004410f6a20173700002002200641016a22063602880c20082015470d000b0b2009450d3420022902840c210a200241a80b6a41106a200241b00c6a41106a290200370300200241a80b6a41086a200241b00c6a41086a290200370300200241900b6a41086a20024190066a41086a290300370300200241900b6a41106a20024190066a41106a290300370300200241f80a6a41086a20024180086a41086a290200370300200241f80a6a41106a20024180086a41106a290200370300200220022902b00c3703a80b20022002290390063703900b20022002290280083703f80a200241e00a6a41106a200241980c6a41106a290300370300200241e00a6a41086a200241980c6a41086a290300370300200220022903980c3703e00a200a422088a72105200aa7210841032127410021100c090b02402006450d00200641c4006c2104200941286a210103400240200141786a2d00004101470d002001280200450d002001417c6a28020010350b200141c4006a2101200441bc7f6a22040d000b0b20022802840c2201450d33200141c4006c450d33200910350c330b200241c8056a200110c40120022802c8050d3220022802cc052109200241b0056a200110f60120022903b005a70d32200241b0056a41106a290300210a20022903b805210b200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024190066a41086a290200370300200241f80a6a41106a20024190066a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290290063703f80a200241e00a6a41106a20024180096a41106a290300370300200241e00a6a41086a20024180096a41086a29030037030020022002290380093703e00a200b422088a72105200a422088a7210f200a4280feffff0f83420888a7212a200ba72108200aa7210c41052127410021100c070b20264104490d312004280002210920012003417a6a360204410621272001200441066a360200200241a80b6a41086a200241e00e6a41086a290200370300200241a80b6a41106a200241e00e6a41106a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024190066a41086a290200370300200241f80a6a41106a20024190066a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290290063703f80a200241e00a6a41106a20024180096a41106a290300370300200241e00a6a41086a20024180096a41086a29030037030020022002290380093703e00a410021054100212a4100210c410021100c060b200241e8056a200110c40120022802e8050d3020022802ec052109200241d0056a200110f60120022903d005a70d30200241d0056a41106a290300210a20022903d805210b200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024190066a41086a290200370300200241f80a6a41106a20024190066a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290290063703f80a200241e00a6a41106a20024180096a41106a290300370300200241e00a6a41086a20024180096a41086a29030037030020022002290380093703e00a200b422088a72105200a422088a7210f200a4280feffff0f83420888a7212a200ba72108200aa7210c41072127410021100c050b200241f0056a200110c40120022802f0050d2f20022802f405210e41002103200241003a00800f2007280200417f6a2104024003402004417f460d01200241e00e6a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00800f2004417f6a21042005210320054120470d000b41082127200241a80b6a41086a20024180096a41086a290200370300200241a80b6a41106a20024180096a41106a290200370300200241900b6a41086a200241980c6a41086a290300370300200241900b6a41106a200241980c6a41106a29030037030020022002290280093703a80b200220022903980c3703900b200241ef0e6a290000210b200241ff0e6a310000210a20022800e30e210920022f00e10e212820022d00e00e212920022900e70e211820022900f70e211920022802d40b211120022903d80b2117200241f80a6a41106a200241800c6a41106a290200370300200241f80a6a41086a200241800c6a41086a290200370300200220022902800c3703f80a200241e00a6a41106a200241e80b6a41106a290300370300200241e00a6a41086a200241e80b6a41086a290300370300200220022903e80b3703e00a2019422088200a42208684210a2018422088a72105200b422088a7210f200b4280feffff0f83420888a7212a200241c40c6a290200211d20022902bc0c211e20022802cc0c213e20022802b80c213620022f01b60c213520022d00b50c213420022d00b40c213320022802b00c213d2019a721142018a72108200ba7210c410021100c050b200341ff0171450d2f200241003a00800f0c2f0b200241f8056a200110c40120022802f8050d2e200728020022044108490d2e20022802fc05210920012802002203290000210a2001200441786a3602042001200341086a360200200a4280025a0d2e200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024190066a41086a290200370300200241f80a6a41106a20024190066a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290290063703f80a200241e00a6a41106a20024180096a41106a290300370300200241e00a6a41086a20024180096a41086a29030037030020022002290380093703e00a200a422088a72105200aa7210841092127410021100c030b20024180066a200110c4012002280280060d2d2002280284062109200241e00e6a200110920620022d00e00e4102460d2d20072802002203450d2d200241e80e6a3502002118200241800f6a350200210b200241fc0e6a280200210e200241f40e6a290200210a200241f00e6a2802002114200241ec0e6a280200210f20022903e00e2119200128020022052d0000210420012003417f6a22063602042001200541016a360200200441064b0d2d42002117410021114100210d0240024002400240024002400240024020040e0707000501020304070b20064110490d34200541096a29000021172005290001211e20012003416f6a3602042001200541116a360200201e422088a72111201ea721134101210d0c060b4103210d0c040b4104210d0c030b4105210d0c020b4106210d0c010b4102210d0b0b200241a80b6a41106a200241980c6a41106a290200370300200241a80b6a41086a200241980c6a41086a290200370300200241900b6a41086a200241800c6a41086a290300370300200241900b6a41106a200241800c6a41106a290300370300200241f80a6a41086a200241e80b6a41086a290200370300200241f80a6a41106a200241e80b6a41106a290200370300200220022902980c3703a80b200220022903800c3703900b200220022902e80b3703f80a200241e00a6a41106a200241d00b6a41106a290300370300200241e00a6a41086a200241d00b6a41086a290300370300200220022903d00b3703e00a2019422088a7210520184280feffff0f83420888a7212a200241c40c6a290200211d20022802b80c213620022802cc0c213e20022902bc0c211e20022f01b60c213520022d00b50c213420022d00b40c21332019a721082018a7210c410a212741002110420021240c020b200241e00e6a200110920620022d00e00e4102460d2c200241d00b6a41086a200241fc0e6a280200360200200241a80b6a41086a20024180096a41086a290200370300200241a80b6a41106a20024180096a41106a2902003703002002200241e00e6a41146a29020022193703d00b20022002290280093703a80b200241800f6a280200210e200241ec0e6a290200210b20022802e00e210920022902e40e211820022802ec0b211120022903f00b211720022902d40b210a200241900b6a41106a20024180086a41106a290300370300200241900b6a41086a20024180086a41086a29030037030020022002290380083703900b200241f80a6a41106a200241980c6a41106a290200370300200241f80a6a41086a200241980c6a41086a290200370300200220022902980c3703f80a200241e00a6a41106a200241800c6a41106a290300370300200241e00a6a41086a200241800c6a41086a290300370300200220022903800c3703e00a2018422088a72105200b422088a7210f200b4280feffff0f83420888a7212a200241b00c6a41146a290200211d20022902bc0c211e20022802cc0c213e20022802b80c213620022f01b60c213520022d00b50c213420022d00b40c21332018a721082019a72114200ba7210c410b2127410021100c010b200241a80b6a41086a20024180086a41086a290300370300200241a80b6a41106a20024180086a41106a290300370300200241900b6a41086a20024180096a41086a290300370300200241900b6a41106a20024180096a41106a29030037030020022002290380083703a80b20022002290380093703900b200241f80e6a290300211a200241e00e6a41106a290300211b200241800f6a280200213d2006280200213c2007280200213b20022903e00e211c200241f80a6a41106a20024190066a41106a290300370300200241f80a6a41086a20024190066a41086a29030037030020022002290390063703f80a200241e00a6a41106a2003290300370300200241e00a6a41086a2004290300370300200220022903b00c3703e00a2027410874202841ff017172212a20244208862025842124410221270b200241c80a6a41106a2201200241a80b6a41106a290300370300200241c80a6a41086a2204200241a80b6a41086a290300370300200241b00a6a41086a2203200241900b6a41086a290300370300200241b00a6a41106a2206200241900b6a41106a290300370300200241980a6a41086a2207200241f80a6a41086a290300370300200241980a6a41106a2226200241f80a6a41106a290300370300200220022903a80b3703c80a200220022903900b3703b00a200220022903f80a3703980a200241800a6a41106a223f200241e00a6a41106a290300370300200241800a6a41086a2240200241e00a6a41086a290300370300200220022903e00a3703800a200041d8006a2019370200200041d0006a2018370200200041186a202a410874ad200cad42ff0183843e0200200041106a2005ad4220862008ad84370200200041e8006a2016360200200041e4006a20153602002000202b3b00622000202c3a0061200041e0006a20123a0000200041c8006a2017370200200041c4006a2011360200200041c0006a2013360200200041386a20244228862010ad42ff018342208684200dad84370200200041306a200b3702002000412c6a200e360200200041246a200a370200200041206a20143602002000411c6a200f3602002000410c6a2009360200200020283b000a200020293a0009200041086a20273a00002000411736020020004188016a202e3602002000418c016a202d360200200020203b0086012000202f3a00850120004184016a20233a0000200041a8016a20303a0000200020323a00a901200020313b00aa01200041b0016a2022360200200041ac016a2021360200200041fc006a2001290300370200200041f4006a2004290300370200200041ec006a20022903c80a37020020004190016a20022903b00a37020020004198016a2003290300370200200041a0016a2006290300370200200041cc016a20373a0000200020393a00cd012000203a3b00ce01200041d4016a2038360200200041d0016a201f360200200041a4026a201d3700002000419c026a201e37000020004188026a201a37020020004180026a201b37020020004194026a20333a0000200020343a009502200020353b009602200041ac026a203e36020020004198026a203636000020004190026a203d360200200041fc016a203c360200200041f8016a203b360200200041f0016a201c370200200041c4016a2026290300370200200041bc016a2007290300370200200041b4016a20022903980a370200200041d8016a20022903800a370200200041e0016a2040290300370200200041e8016a203f2903003702000c480b2006450d0720042d0001210520012003417e6a22123602042001200441026a3602002005410b4b0d074107210d4200211d4100211141002106024002400240024002400240024020050e0c0001020304052f0608090a0b000b20124110490d0d2004410a6a29000021172004290002210b20012003416e6a3602042001200441126a3602004101210d4200211e410021064200211d0c2e0b20124104490d0c2004280002210c20012003417a6a3602042001200441066a3602004102210d0c2c0b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200220022800b30c3600c30b200220022802b00c22083602c00b200320076b2203417e6a4110490d0c200241bf0c6a2900002117200241cf0c6a310000211c20022900b70c210b20022900c70c210a20022f00c10b211420022800c30b210c200420076a2204410e6a2800002113200441066a290000211d200441026a280000210620012003416e6a22053602042001200441126a220736020020054110490d0c2004411a6a29000021192007290000211820012003415e6a3602042001200441226a360200201d421088211e20064180807c712111201ca741ff017121104103210d0c2d0b200541ff0171450d0b200241003a00d00c0c0b0b4104210d20124104490d0a2004280002210c20012003417a6a3602042001200441066a3602000c2a0b200241b00c6a200110920620022d00b00c4102460d0920072802002203450d09200241bc0c6a2902002117200241d00c6a280200210e200241ce0c6a2f0100210f200241cd0c6a2d00002109200241cc0c6a2d00002110200241c40c6a290200210a20022902b40c210b20022802b00c210c200128020022052d0000210420012003417f6a3602042001200541016a360200200441014b0d09410021080240024020040e020100010b410121080b20023502900620023301940642208684211e200241a2066a2901002119200229019a06211820022801960621134105210d41002111410021060c2a0b2012450d0820042d0002210520012003417d6a3602042001200441036a360200200541014b0d084106210d410021114200211e410021064200211d4100210820050e022906290b41002105200241003a00d00c2003417e6a2108417d2106024002400240034020082005460d01200241b00c6a20056a200420056a220941026a2d00003a00002001200320066a3602042001200941036a3602002002200541016a22093a00d00c2006417f6a21062009210520094120470d000b20024198086a200241cf0c6a31000022183c0000200220022800b30c3600c30b200220022802b00c22083602c00b200220022900c70c220a37039008200220022900b70c220b370380082002200241bf0c6a290000221737038808200320096b2203417e6a4104490d0a200241c50b6a2d0000210520022f00c30b210c20022d00c10b211420022d00c20b211320022d00c60b210d200420096a220441026a280000210e20012003417a6a3602042001200441066a36020020024188066a200110c4012002280288060d0a2007280200200228028c062204490d0a2004417f4c0d0f20040d0142002119410121060c020b200541ff0171450d09200241003a00d00c0c090b200410392206450d0120072802002004490d07200620012802002004109d081a200128020422032004490d262001200320046b3602042001200128020020046a3602002004ad21190b2006450d07200d411874200c20054110747241ffffff077172210c20192004ad42208684221d421088211e20064180807c7121114108210d201341087420147221142018a741ff017121100c280b1045000b4109210d410021060c260b41002105200241003a00d00c2003417e6a21092003417d6a2106024002400240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200220022800b30c3600c30b200220022802b00c22083602c00b2003417e6a2007460d07200241bf0c6a2900002117200241cf0c6a310000211820022900b70c210b20022900c70c210a20022f00c10b211420022800c30b210c200420076a220341026a2d00002104200120063602042001200341036a360200200441014b0d074100210920040e020201020b200541ff0171450d06200241003a00d00c0c060b410121090b2018a741ff01712110410a210d0c230b41002105200241003a00d00c2003417e6a21092003417d6a21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200241e80b6a41106a200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022800b30c3600c30b200220022802b00c22083602c00b200220022d00c60b3a00e80b200220022900b70c220ba722053b00e90b200220054110763a00eb0b2002200b421888200a422886843702ec0b2003417e6a2007460d04200241cf0c6a310000210b20022900c70c210a20022d00c10b210520022801c20b2103200420076a220441026a2d00002109200120063602042001200441036a360200200941034f0d0420022d00e80b411874200341087672210c20034108742005722114200ba741ff01712110200241e80b6a410172220141086a29000021172001290000210b410b210d0c230b200541ff0171450d03200241003a00d00c0c030b20124104490d022004280002210c20012003417a6a3602042001200441066a360200410c210d0c220b410121084200211e41002111410021064200211d0c220b200610350b2000411b3602000c3f0b200241b00c6a2001109506024020022d00b00c410a460d0020024190066a200241b00c6a41c400109d081a20004119360200200041046a20024190066a41c400109d081a200041c8006a200241e00e6a41e801109d081a0c3f0b2000411b3602000c3e0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d004101210402400240024020050e03020001020b200241b00c6a20011092064102210420022d00b00c4102460d02200241c40c6a2902002117200241bc0c6a290200210b200241cc0c6a290200210a200241b80c6a280200210320022802b40c210620022802b00c21090c010b200241b00c6a200110920620022d00b00c4102460d01200728020022054110490d01200241c40c6a2902002117200241bc0c6a290200210b200241cc0c6a290200210a200241b00c6a41086a280200210320022802b40c210620022802b00c21092001280200220441086a2900002119200429000021182001200441106a3602002001200541706a220736020420074110490d01200441186a290000211d2004290010211e2001200541606a22073602042001200441206a36020020074104490d012004280020210820012005415c6a3602042001200441246a360200410321040b2000411a360200200041c8006a201d370200200041c0006a201e370200200041386a2019370200200041306a2018370200200041206a2017370200200041186a200b370200200041d0006a2008360200200041286a200a370200200041146a2003360200200041106a20063602002000410c6a2009360200200041086a2004360200200041d8006a200241e00e6a41d801109d081a0c3e0b2000411b3602000c3d0b02402006450d0020012003417e6a3602042001200441026a3602000b2000411b3602000c3c0b2000411b3602000c3b0b1044000b2004200341a4f0cb001059000b2004200341a4f0cb001059000b2004200341a4f0cb001059000b2004200341a4f0cb001059000b2003200d41a4f0cb001059000b2004200841a4f0cb001059000b2004200341a4f0cb001059000b2004200341a4f0cb001059000b200810350c260b2004200341a4f0cb001059000b2004200341a4f0cb001059000b2003200541a4f0cb001059000b200410350b2000411b3602000c2c0b2004200341a4f0cb001059000b2004200341a4f0cb001059000b2004200541a4f0cb001059000b2006200341a4f0cb001059000b2005200341a4f0cb001059000b2004200341a4f0cb001059000b2003200741a4f0cb001059000b200c200541a4f0cb001059000b2004200341a4f0cb001059000b2004200c41a4f0cb001059000b2004200341a4f0cb001059000b4200211e41002111410021064200211d0c010b4200211e410021064200211d0b2000200f3b012a200020093a0029200020143b010a200020083a000920004118360200200041c8006a2019370200200041c0006a2018370200200041186a2017370200200041106a200b3702002000413c6a20133602002000412c6a200e360200200041286a20103a0000200041206a200a3702002000410c6a200c360200200041086a200d3a0000200041346a201e421086201d42ffff038384370200200041306a2011200641ffff037172360200200041d0006a200241e00e6a41e001109d081a0c1e0b2000411b3602000c1d0b200410350b2000411b3602000c1b0b4100210c420021180b200241800c6a41106a200241980c6a41106a2903002219370300200241800c6a41086a200241980c6a41086a290300221e370300200220022903980c221d3703800c200041286a20173c0000200041206a200b370200200041186a2018421886200a42288884370200200041106a200a4218862008ad42ffffff0783843702002000412c6a20043602002000412a6a20073b0100200020093a00292000410c6a2001411874200341ffffff0771723602002000200c410874200641ff0171723b000a200020053a0009200041086a200e3a000020004110360200200041306a201d370200200041386a201e370200200041c0006a2019370200200041c8006a200241e00e6a41e801109d081a0c190b0b4200211c4200211b4200211a4200210b42002124420021250b200020143b00462000200d3a00452000200f3b0026200020103a0025200020083a0005200020063a00042000410d360200200041246a200a4220883c0000200041206a200a3e0000200041c4006a201d3c00002000413c6a201e370000200041146a20183700002000410c6a2017370000200041286a20133600002000411c6a2011360000200041086a200c411874200741ffffff07717236000020002009410874200e41ff0171723b00062000412c6a200b200b84201b84201984370000200041346a2025202484201a84201c84370000200041c8006a200241e00e6a41e801109d081a0c160b2000411b3602000c150b4100210e0b0b200020153b012a2000200c3a00292000200f3b011a200020123a0019200020063a000920004109360200200041286a200a4220883c0000200041246a200a3e0200200041386a2018370200200041306a20173702002000412c6a2014360200200041206a20103602002000411c6a2011360200200041186a20163a0000200041106a200b370200200041086a20133a00002000410c6a200d411874200941ffffff0771723602002000200e410874200841ff0171723b000a200041c0006a200241e00e6a41f001109d081a0c120b4100210802402004450d00200910350b41022109410021060b41000d052009450d05200241e00e6a200110f80102400240024020022802e00e450d00200241b00c6a200241e00e6a41c001109d081a200728020022034110490d012001280200220441086a290000211e200429000021192001200441106a3602002001200341706a220536020420054110490d01200441186a290000211c2004290010211d2001200341606a22053602042001200441206a36020020054110490d01200441286a290000211a2004290020211b2001200341506a22053602042001200441306a36020020054104490d022004280030211320012003414c6a3602042001200441346a360200200241a80b6a41086a200241ec0c6a290200370300200241a80b6a41106a200241f40c6a2902003703002002200241b00c6a41346a2902003703a80b200241b00c6a41106a310000210b200241d00c6a2903002118200241c40c6a280200210f200241b00c6a41286a2d00002110200241dc0c6a280200211120022903b80c210a20022903c80c211720022802b00c210c20022802b40c211420022d00c10c212120022f01c20c212020022d00d90c213220022f01da0c213120022802e00c2112200241900b6a41086a200241900d6a290300370300200241900b6a41106a200241980d6a290300370300200241f80a6a41086a200241b40d6a290200370300200241f80a6a41106a200241bc0d6a2902003703002002200241880d6a2903003703900b2002200241ac0d6a2902003703f80a200241800d6a2802002115200241fc0c6a2d00002116200241a40d6a280200212b200241a00d6a2d0000212c20022802840d212320022f01fe0c213520022d00fd0c213420022802a80d212d20022f01a20d213320022d00a10d2136200241e00a6a41106a200241e00d6a290300370300200241e00a6a41086a200241d80d6a2903003703002002200241d00d6a2903003703e00a200241c80d6a2802002130200241c40d6a2d0000212e200241e80d6a290300212420022802cc0d212f20022f01c60d213820022d00c50d21374118210d0c0a0b20080d040c070b200241b00c6a10fa01200841808080807872418080808078470d030c060b200241b00c6a10fa012008450d050c020b4100210802402004450d00200910350b41022109410021060b41000d032009450d03200241e00e6a200110f80102400240024020022802e00e450d00200241b00c6a200241e00e6a41c001109d081a200728020022034110490d012001280200220441086a290000211e200429000021192001200441106a3602002001200341706a220536020420054110490d01200441186a290000211c2004290010211d2001200341606a22053602042001200441206a36020020054110490d01200441286a290000211a2004290020211b2001200341506a22053602042001200441306a36020020054104490d022004280030211320012003414c6a3602042001200441346a360200200241a80b6a41086a200241ec0c6a290200370300200241a80b6a41106a200241f40c6a2902003703002002200241b00c6a41346a2902003703a80b200241b00c6a41106a310000210b200241d00c6a2903002118200241c40c6a280200210f200241b00c6a41286a2d00002110200241dc0c6a280200211120022903b80c210a20022903c80c211720022802b00c210c20022802b40c211420022d00c10c212120022f01c20c212020022d00d90c213220022f01da0c213120022802e00c2112200241900b6a41086a200241900d6a290300370300200241900b6a41106a200241980d6a290300370300200241f80a6a41086a200241b40d6a290200370300200241f80a6a41106a200241bc0d6a2902003703002002200241880d6a2903003703900b2002200241ac0d6a2902003703f80a200241800d6a2802002115200241fc0c6a2d00002116200241a40d6a280200212b200241a00d6a2d0000212c20022802840d212320022f01fe0c213520022d00fd0c213420022802a80d212d20022f01a20d213320022d00a10d2136200241e00a6a41106a200241e00d6a290300370300200241e00a6a41086a200241d80d6a2903003703002002200241d00d6a2903003703e00a200241c80d6a2802002130200241c40d6a2d0000212e200241e80d6a290300212420022802cc0d212f20022f01c60d213820022d00c50d21374117210d0c080b20080d020c050b200241b00c6a10fa01200841808080807872418080808078470d010c040b200241b00c6a10fa012008450d030b200910350c020b4100210602402001450d00200810350b410421084100210c0b41000d002008450d004110210d200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290200370300200241900b6a41106a200241b00c6a41106a290200370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022902b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290200370300200241e00a6a41086a20024180086a41086a29020037030020022002290280083703e00a0c020b2000411b3602000c0a0b410021144100210c410021060b200241c80a6a41106a2201200241a80b6a41106a290300370300200241c80a6a41086a2204200241a80b6a41086a290300370300200241b00a6a41086a2203200241900b6a41086a290300370300200241b00a6a41106a2205200241900b6a41106a290300370300200241980a6a41086a2207200241f80a6a41086a290300370300200241980a6a41106a221f200241f80a6a41106a290300370300200220022903a80b3703c80a200220022903900b3703b00a200220022903f80a3703980a200241800a6a41106a2239200241e00a6a41106a290300370300200241800a6a41086a223a200241e00a6a41086a290300370300200220022903e00a3703800a200041386a2018370200200041306a2017370200200041286a200b3c0000200041206a200a370200200041186a2014ad422086200cad84370200200041106a2006ad4220862008ad84370200200041c8006a2012360200200041c4006a2011360200200020313b0042200020323a0041200041c0006a20103a00002000412c6a200f360200200020203b012a200020213a00292000410c6a2009360200200020223b010a2000200e3a0009200041086a200d3a000020004107360200200041e8006a2015360200200041ec006a2023360200200020353b0066200020343a0065200041e4006a20163a0000200041cc006a20022903c80a370200200041d4006a2004290300370200200041dc006a20012903003702002000418c016a202b36020020004190016a202d360200200020333b008a01200020363a00890120004188016a202c3a0000200041f0006a20022903b00a370200200041f8006a200329030037020020004180016a2005290300370200200041a4016a201f2903003702002000419c016a200729030037020020004194016a20022903980a370200200041b4016a202f360200200041b0016a2030360200200020383b00ae01200020373a00ad01200041ac016a202e3a0000200041c8016a2039290300370200200041c0016a203a290300370200200041b8016a20022903800a37020020004188026a201a37020020004180026a201b370200200041f8016a201c370200200041f0016a201d370200200041e8016a201e370200200041e0016a2019370200200041d8016a2013360200200041d0016a2024370200200041a8026a20024190066a41186a290300370300200041a0026a20024190066a41106a29030037030020004198026a20024190066a41086a29030037030020004190026a2002290390063703000c080b20004106360200200041e0006a201c370200200041d8006a201d370200200041c8006a201a370200200041c0006a201b370200200041386a2018370200200041306a2019370200200041206a200a370200200041186a200b370200200041d0006a201e370200200041286a2017370200200041146a2004360200200041106a20033602002000410c6a2005360200200041086a2001360200200041e8006a200241e00e6a41c801109d081a0c070b410021014200210b410021034100210e0b200041003a0025200020043b0023200020083b0006200020053a0005200020063a0004200041053602002000411b6a200b370000200041136a200a370000200041286a200e360200200041266a41003b01002000410f6a20013600002000410d6a20033b00002000410c6a20073a0000200041086a20093602002000412c6a200241e00e6a418402109d081a0c050b200410350b2000411b3602000c030b103c000b200610350b2000411b3602000b20024190116a24000b9d1401037f02402000280200220141194b0d0002400240024002400240024002400240024002400240024002400240024002400240024020010e1a0001121202121203040506070809120a0b0c0d0e1212120f1011000b200041086a280200417e6a220141074b0d1102400240024002400240024020010e080017010217030405000b200041106a280200450d162000410c6a28020010350f0b200041106a280200450d152000410c6a28020010350f0b200041106a280200450d142000410c6a28020010350f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141186a2101200241686a22020d000b0b200041106a2802002201450d13200141186c450d13200028020c10350f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d122001410c6c450d12200028020c10350f0b200041106a280200450d112000410c6a28020010350f0b024020002d0004220141044b0d00024002400240024020010e051500010203150b0240200041106a2802002202450d00200041086a2802002101200241b0026c21020340200110bb02200141b0026a2101200241d07d6a22020d000b0b2000410c6a2802002201450d14200141b0026c450d14200028020810350f0b200041086a220128020010ba02200128020010350f0b02402000410c6a28020041ffffff3f71450d00200041086a28020010350b200041206a220128020010ba02200128020010350f0b2000412c6a28020041ffffff3f71450d11200041286a28020010350f0b2000412c6a28020041ffffff3f71450d10200041286a28020010350f0b02402000410c6a2802002201450d00200141f0006c2102200028020441046a21010340200110b1030240200141046a2802002203450d00200341246c450d00200128020010350b200141f0006a2101200241907f6a22020d000b0b200041086a2802002201450d0f200141f0006c450d0f200028020410350f0b0240200041086a2d0000220141174b0d000240024002400240024020010e18141414141414001414141414140114140203141414141404140b200041106a2802002201450d13200141246c450d132000410c6a28020010350f0b200041106a28020041ffffff3f71450d122000410c6a28020010350f0b200041146a28020041ffffffff0371450d11200041106a28020010350f0b200041146a2802002201450d10200141246c450d10200041106a28020010350f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010350b200041186a10fa010f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010350b200041186a10fa010f0b20002802042201450d0d200041086a280200450d0d200110350f0b200041086a2d0000416d6a220141014b0d0c0240024020010e020001000b200041106a280200450d0d2000410c6a28020010350f0b200041106a280200450d0c2000410c6a28020010350f0b20002d0004417f6a220141024b0d0b02400240024020010e03000102000b2000412c6a28020041ffffff3f71450d0d200041286a28020010350f0b200041086a220128020010ba02200128020010350f0b2000410c6a220128020010ba02200128020010350f0b20002d0004417f6a220141024b0d0a02400240024020010e03000102000b2000412c6a28020041ffffff3f71450d0c200041286a28020010350f0b200041086a220128020010ba02200128020010350f0b2000410c6a220128020010ba02200128020010350f0b200041086a2802004101470d09200041106a28020041ffffff3f71450d092000410c6a28020010350f0b20002d00044104470d082000410c6a28020041ffffff3f71450d08200041086a28020010350f0b200041086a280200450d07200028020410350f0b200041086a2d0000417c6a220141024b0d060240024020010e03000801000b200041306a280200450d072000412c6a28020010350f0b200041306a280200450d062000412c6a28020010350f0b200041086a2d0000417e6a220141024b0d0502400240024020010e03000102000b200041106a280200450d072000410c6a28020010350c070b200041346a280200450d06200041306a28020010350f0b200041306a280200450d052000412c6a28020010350f0b02402000280204220141024b0d00024020010e03060006060b200041086a220128020010ba02200128020010350f0b2000412c6a220128020010ba02200128020010350f0b02402000410c6a280200450d00200041086a28020010350b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b200041186a2802002201450d032001410c6c450d03200028021410350f0b200041086a2d0000417e6a220141014b0d020240024020010e020001000b0240200041146a2802002202450d002000410c6a2802002201200241c8006c6a21020340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b0240200041106a2802002201450d00200141c8006c450d00200028020c10350b0240200041186a2d00004101470d00200041206a280200450d002000411c6a28020010350b02402000413c6a2d00004101470d00200041c4006a280200450d00200041c0006a28020010350b0240200041e0006a2d00004101470d00200041e8006a280200450d00200041e4006a28020010350b024020004184016a2d00004101470d002000418c016a280200450d0020004188016a28020010350b0240200041a8016a2d00004101470d00200041b0016a280200450d00200041ac016a28020010350b0240200041cc016a2d00004101470d00200041d4016a280200450d00200041d0016a28020010350b200041f0016a2d00004101470d03200041f8016a280200450d03200041f4016a28020010350f0b0240200041146a2802002201450d00200141c4006c21022000410c6a28020041286a210103400240200141786a2d00004101470d002001280200450d002001417c6a28020010350b200141c4006a2101200241bc7f6a22020d000b0b200041106a2802002201450d02200141c4006c450d02200028020c10350f0b200041086a2d00004108470d01200041346a280200450d01200041306a28020010350f0b20002d0004417f6a220141024b0d000240024020010e03000201000b200041286a220128020010ba02200128020010350f0b2000410c6a28020041ffffff3f71450d00200041086a28020010350f0b0b9d1401037f02402000280200220141194b0d0002400240024002400240024002400240024002400240024002400240024002400240024020010e1a0001121202121203040506070809120a0b0c0d0e1212120f1011000b200041086a280200417e6a220141074b0d1102400240024002400240024020010e080017010217030405000b200041106a280200450d162000410c6a28020010350f0b200041106a280200450d152000410c6a28020010350f0b200041106a280200450d142000410c6a28020010350f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141186a2101200241686a22020d000b0b200041106a2802002201450d13200141186c450d13200028020c10350f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d122001410c6c450d12200028020c10350f0b200041106a280200450d112000410c6a28020010350f0b024020002d0004220141044b0d00024002400240024020010e051500010203150b0240200041106a2802002202450d00200041086a2802002101200241b0026c21020340200110bb02200141b0026a2101200241d07d6a22020d000b0b2000410c6a2802002201450d14200141b0026c450d14200028020810350f0b200041086a220128020010bb02200128020010350f0b02402000410c6a28020041ffffff3f71450d00200041086a28020010350b200041206a220128020010bb02200128020010350f0b2000412c6a28020041ffffff3f71450d11200041286a28020010350f0b2000412c6a28020041ffffff3f71450d10200041286a28020010350f0b02402000410c6a2802002201450d00200141f0006c2102200028020441046a21010340200110b1030240200141046a2802002203450d00200341246c450d00200128020010350b200141f0006a2101200241907f6a22020d000b0b200041086a2802002201450d0f200141f0006c450d0f200028020410350f0b0240200041086a2d0000220141174b0d000240024002400240024020010e18141414141414001414141414140114140203141414141404140b200041106a2802002201450d13200141246c450d132000410c6a28020010350f0b200041106a28020041ffffff3f71450d122000410c6a28020010350f0b200041146a28020041ffffffff0371450d11200041106a28020010350f0b200041146a2802002201450d10200141246c450d10200041106a28020010350f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010350b200041186a10fa010f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010350b200041186a10fa010f0b20002802042201450d0d200041086a280200450d0d200110350f0b200041086a2d0000416d6a220141014b0d0c0240024020010e020001000b200041106a280200450d0d2000410c6a28020010350f0b200041106a280200450d0c2000410c6a28020010350f0b20002d0004417f6a220141024b0d0b02400240024020010e03000102000b2000412c6a28020041ffffff3f71450d0d200041286a28020010350f0b200041086a220128020010bb02200128020010350f0b2000410c6a220128020010bb02200128020010350f0b20002d0004417f6a220141024b0d0a02400240024020010e03000102000b2000412c6a28020041ffffff3f71450d0c200041286a28020010350f0b200041086a220128020010bb02200128020010350f0b2000410c6a220128020010bb02200128020010350f0b200041086a2802004101470d09200041106a28020041ffffff3f71450d092000410c6a28020010350f0b20002d00044104470d082000410c6a28020041ffffff3f71450d08200041086a28020010350f0b200041086a280200450d07200028020410350f0b200041086a2d0000417c6a220141024b0d060240024020010e03000801000b200041306a280200450d072000412c6a28020010350f0b200041306a280200450d062000412c6a28020010350f0b200041086a2d0000417e6a220141024b0d0502400240024020010e03000102000b200041106a280200450d072000410c6a28020010350c070b200041346a280200450d06200041306a28020010350f0b200041306a280200450d052000412c6a28020010350f0b02402000280204220141024b0d00024020010e03060006060b200041086a220128020010bb02200128020010350f0b2000412c6a220128020010bb02200128020010350f0b02402000410c6a280200450d00200041086a28020010350b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b200041186a2802002201450d032001410c6c450d03200028021410350f0b200041086a2d0000417e6a220141014b0d020240024020010e020001000b0240200041146a2802002202450d002000410c6a2802002201200241c8006c6a21020340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b0240200041106a2802002201450d00200141c8006c450d00200028020c10350b0240200041186a2d00004101470d00200041206a280200450d002000411c6a28020010350b02402000413c6a2d00004101470d00200041c4006a280200450d00200041c0006a28020010350b0240200041e0006a2d00004101470d00200041e8006a280200450d00200041e4006a28020010350b024020004184016a2d00004101470d002000418c016a280200450d0020004188016a28020010350b0240200041a8016a2d00004101470d00200041b0016a280200450d00200041ac016a28020010350b0240200041cc016a2d00004101470d00200041d4016a280200450d00200041d0016a28020010350b200041f0016a2d00004101470d03200041f8016a280200450d03200041f4016a28020010350f0b0240200041146a2802002201450d00200141c4006c21022000410c6a28020041286a210103400240200141786a2d00004101470d002001280200450d002001417c6a28020010350b200141c4006a2101200241bc7f6a22020d000b0b200041106a2802002201450d02200141c4006c450d02200028020c10350f0b200041086a2d00004108470d01200041346a280200450d01200041306a28020010350f0b20002d0004417f6a220141024b0d000240024020010e03000201000b200041286a220128020010bb02200128020010350f0b2000410c6a28020041ffffff3f71450d00200041086a28020010350f0b0bad0204017f017e017f027e230041d0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822010d00420021030c010b200228020c210402400240200241086a41086a2802004110490d00200141086a290000210520012900002106420121030c010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b420021030b2004450d00200110350b2000200637030820002003370300200041106a2005370300200241d0006a24000b950201047f230041d0006b220124002001412036020420012000360200200141086a2000ad4280808080800484100510c20102400240200128020822020d00410221000c010b200128020c210302400240200141106a280200450d0020022d0000220441014b0d0041002100024020040e020200020b410121000c010b20014100360220200142013703182001410936022c200120013602282001200141186a360234200141cc006a41013602002001420137023c200141c888c2003602382001200141286a360248200141346a41e88ac500200141386a10431a200135022042208620013502188410060240200128021c450d00200128021810350b410221000b2003450d00200210350b200141d0006a240020000bad0e04057f017e107f047e230041a0036b220224002002412036021420022001360210200241186a2001ad4280808080800484100510c2010240024002400240200228021822030d00200041003602000c010b200228021c21042002200241206a28020036022c20022003360228200241086a200241286a10c40102400240024020022802080d00200228020c2205200228022c220641e8006e2201200120054b1bad42e8007e2207422088a70d052007a72201417f4c0d050240024020010d00410821080c010b200110332208450d050b20024100360238200220083602302002200141e8006e36023402402005450d00200241e8026a41017221094100210a4100210b034041002101200241003a008803200b41016a210b0240024002400240034020062001460d01200241e8026a20016a2002280228220c2d00003a00002002200c41016a3602282002200141016a220c3a008803200c2101200c4120470d000b20024190026a41086a2201200241e8026a41086a220d29030037030020024190026a41106a220e200241e8026a41106a220f29030037030020024190026a41186a2210200241e8026a41186a2211290300370300200220022903e8023703900220022006200c6b36022c200241e8026a200241286a10bf0220022d00e802220c4102470d010c020b2002410036022c200141ff0171450d01200241003a0088034102210c0c020b200241b0026a412f6a22062009412f6a290000370000200241b0026a41286a2212200941286a290000370300200241b0026a41206a2213200941206a290000370300200241b0026a41186a2214200941186a290000370300200241b0026a41106a2215200941106a290000370300200241b0026a41086a2216200941086a290000370300200220092900003703b002200228022c22174110490d00200241f0016a41086a2001290300370300200241f0016a41106a200e290300370300200241f0016a41186a2010290300370300200d2016290300370300200f201529030037030020112014290300370300200241e8026a41206a2013290300370300200241e8026a41286a2012290300370300200241e8026a412f6a200629000037000020022002290390023703f001200220022903b0023703e8022002201741706a36022c20022002280228220141106a360228200141086a2900002118200129000021190c010b4102210c0b200241b8016a412f6a2201200241e8026a412f6a290000370000200241b8016a41286a2206200241e8026a41286a290300370300200241b8016a41206a220d200241e8026a41206a290300370300200241b8016a41186a220e200241e8026a41186a290300370300200241b8016a41106a220f200241e8026a41106a290300370300200241b8016a41086a2210200241e8026a41086a29030037030020024198016a41086a2211200241f0016a41086a29030037030020024198016a41106a2212200241f0016a41106a29030037030020024198016a41186a2213200241f0016a41186a290300370300200220022903e8023703b801200220022903f001370398010240200c4102460d00200241e0006a412f6a22142001290000370000200241e0006a41286a22152006290300370300200241e0006a41206a2206200d290300370300200241e0006a41186a220d200e290300370300200241e0006a41106a220e200f290300370300200241e0006a41086a220f2010290300370300200241c0006a41086a22102011290300370300200241c0006a41106a22112012290300370300200241c0006a41186a22122013290300370300200220022903b80137036020022002290398013703400240200a2002280234470d00200241306a200a4101109601200228023021082002280238210a0b2008200a41e8006c6a2201200c3a0000200141196a200d290300370000200141116a200e290300370000200141096a200f29030037000020012002290360370001201429000021072015290300211a2006290300211b200141c0006a2018370000200141386a2019370000200141216a201b370000200141296a201a370000200141306a2007370000200141c8006a2002290340370000200141d0006a2010290300370000200141d8006a2011290300370000200141e0006a20122903003700002002200a41016a220a360238200b2005460d02200228022c21060c010b0b20022802342201450d01200141e8006c450d01200810350c010b20080d010b200241003602b802200242013703b002200241093602bc012002200241106a3602b8012002200241b0026a360260200241fc026a4101360200200242013702ec02200241c888c2003602e8022002200241b8016a3602f802200241e0006a41e88ac500200241e8026a10431a20023502b80242208620023502b002841006024020022802b402450d0020022802b00210350b200041003602000c010b20002002290234370204200020083602000b2004450d00200310350b200241a0036a24000f0b1045000b1044000bcc0502077f067e230041f0006b2102024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541014b0d0320050e020102010b200041023a00000f0b024020064110490d00200041003a000020002002280028360001200041086a2004290001370300200041186a2002290348370300200041106a200441096a29000037030020012003416f6a3602042001200441116a360200200041046a2002412b6a280000360000200041206a200241c8006a41086a290300370300200041286a200241c8006a41106a290300370300200041306a200241c8006a41186a2903003703000f0b200041023a00000f0b41002105200241003a00682003417f6a2107417e210602400240034020072005460d01200241c8006a20056a200420056a220841016a2d00003a00002001200320066a3602042001200841026a3602002002200541016a22083a00682006417f6a21062008210520084120470d000b200241286a41186a2205200241c8006a41186a290300370300200241286a41106a2206200241c8006a41106a290300370300200241286a41086a2207200241c8006a41086a290300370300200220022903483703282008417f7320036a4110490d01200241086a41086a20072903002209370300200241086a41106a2006290300220a370300200241086a41186a2005290300220b370300200420086a220541016a290000210c200541096a290000210d2001200320086b416f6a3602042001200541116a36020020022002290328220e370308200041013a00002000200e370001200041096a2009370000200041116a200a370000200041196a200b370000200041306a200d370300200041286a200c370300200041216a2002280001360000200041246a200241046a2800003600000f0b200541ff0171450d00200241003a00680b200041023a00000f0b200041023a00000bfe0301057f230041f0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022030d00200041033a00200c010b200241186a28020021042002280214210541002101200241003a0068024002400240034020042001460d01200241c8006a20016a200320016a2d00003a00002002200141016a22063a00682006210120064120470d000b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a2903003703002002200229034837032820042006460d01200320066a2d0000220141034f0d0120002002290328370000200041186a200241286a41186a290300370000200041106a200241286a41106a290300370000200041086a200241286a41086a2903003700000c020b200141ff0171450d00200241003a00680b2002410036023020024201370328200241093602242002200241086a3602202002200241286a36026c200241dc006a41013602002002420137024c200241c888c2003602482002200241206a360258200241ec006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b410321010b200020013a00202005450d00200310350b200241f0006a24000bd60201027f230041c0026b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003a00000c010b200328021421042003200341186a2802003602ac02200320013602a802200341a0016a200341a8026a10c202410121020240024020032d00a0014101470d00410021022003410036022820034201370320200341093602b4022003200341086a3602b0022003200341206a3602bc02200341b4016a4101360200200342013702a401200341c888c2003602a0012003200341b0026a3602b001200341bc026a41e88ac500200341a0016a10431a200335022842208620033502208410062003280224450d01200328022010350c010b200341206a200341a0016a410172418001109d081a200041016a200341206a418001109d081a0b200020023a00002004450d00200110350b200341c0026a24000ba60901077f230041d0026b2202240041002103200241003a002820012802042104417f210502400240024002400240034020042003460d01200241086a20036a200128020022062d00003a00002001200420056a3602042001200641016a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b20024188016a41086a200241086a41086a29030037030020024188016a41106a200241086a41106a29030037030020024188016a41186a200241086a41186a290300370300200220022903083703880141002108200241003a0028200420076b2107200420056a2103034020072008460d02200241086a20086a200620086a220541016a2d00003a0000200120033602042001200541026a3602002002200841016a22053a00282003417f6a21032005210820054120470d000b200241a8016a41086a200241086a41086a290300370300200241a8016a41106a200241086a41106a290300370300200241a8016a41186a200241086a41186a290300370300200220022903083703a80141002107200241003a0028200620056a210803402003417f460d03200241086a20076a200820076a220541016a2d00003a0000200120033602042001200541026a3602002002200741016a22053a00282003417f6a21032005210720054120470d000b200241c8016a41086a200241086a41086a290300370300200241c8016a41106a200241086a41106a290300370300200241c8016a41186a200241086a41186a290300370300200220022903083703c80141002107200241003a00c802200820056a41016a210503402003417f460d04200241a8026a20076a20052d00003a0000200120033602042001200541016a22053602002002200741016a22083a00c8022003417f6a21032008210720084120470d000b200241e8016a41086a2201200241a8026a41086a290300370300200241e8016a41106a2203200241a8026a41106a290300370300200241e8016a41186a2205200241a8026a41186a290300370300200241086a41086a20024188016a41086a290300370300200241086a41106a20024188016a41106a290300370300200241086a41186a20024188016a41186a290300370300200220022903a8023703e8012002200229038801370308200241c0006a200241a8016a41186a290300370300200241386a200241a8016a41106a290300370300200241306a200241a8016a41086a290300370300200220022903a801370328200241e0006a200241c8016a41186a290300370300200241d8006a200241c8016a41106a290300370300200241d0006a200241c8016a41086a290300370300200220022903c80137034820024180016a2005290300370300200241f8006a2003290300370300200241f0006a2001290300370300200220022903e801370368200041016a200241086a418001109d081a200041003a00000c040b0240200341ff0171450d00200241003a00280b200041013a00000c030b0240200841ff0171450d00200241003a00280b200041013a00000c020b0240200741ff0171450d00200241003a00280b200041013a00000c010b0240200741ff0171450d00200241003a00c8020b200041013a00000b200241d0026a24000b8a06010c7f23004190016b220324002003200236021420032001360210200341186a2002ad4220862001ad84100510c2010240024002400240200328021822040d00200041003602000c010b200328021c21052003200341206a28020036022c20032004360228200341086a200341286a10c4010240024020032802080d00200328020c2206200328022c22074105762201200120064b1b22014105742202417f4c0d030240024020010d00410121080c010b200210332208450d050b41002109200341003602402003200136023c20032008360238024002402006450d004100210a03402007210b41002101200341003a008801200a41016a210a0340200b2001460d03200341e8006a20016a200328022822022d00003a00002003200241016a3602282003200141016a22023a0088012002210120024120470d000b200341c8006a41186a220c200341e8006a41186a290300370300200341c8006a41106a220d200341e8006a41106a290300370300200341c8006a41086a220e200341e8006a41086a2903003703002003200329036837034802402009200328023c470d00200341386a20094101108a0120032802382108200328024021090b200b20026b2107200820094105746a22012003290348370000200141186a200c290300370000200141106a200d290300370000200141086a200e2903003700002003200941016a2209360240200a2006470d000b2003200b20026b36022c0b2008450d012000200329023c370204200020083602000c020b2003410036022c0240200141ff0171450d00200341003a0088010b200328023c41ffffff3f71450d00200810350b20034100360250200342013703482003410936023c2003200341106a3602382003200341c8006a360234200341fc006a41013602002003420137026c200341c888c2003602682003200341386a360278200341346a41e88ac500200341e8006a10431a200335025042208620033502488410060240200328024c450d00200328024810350b200041003602000b2005450d00200410350b20034190016a24000f0b1044000b1045000bab0602057f047e23004190016b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022040d00200041023a00000c010b2003280214210502400240200341186a2802002201450d0020042d0000220241014b0d002001417f6a2106024002400240024020020e020001000b41002101200341003a008801200441016a21070240034020062001460d01200341e8006a20016a200720016a2d00003a00002003200141016a22023a0088012002210120024120470d000b200341c8006a41186a200341e8006a41186a2903002208370300200341206a41086a200341e8006a41086a290300370300200341206a41106a200341e8006a41106a290300370300200341206a41186a200837030020032003290368370320410021010c020b200141ff0171450d03200341003a0088010c030b41002101200341003a008801200441016a2107034020062001460d02200341e8006a20016a200720016a2d00003a00002003200141016a22023a0088012002210120024120470d000b200341c8006a41186a200341e8006a41186a2903002208370300200341206a41086a200341e8006a41086a290300370300200341206a41106a200341e8006a41106a290300370300200341206a41186a200837030020032003290368370320410121010b200341e8006a41186a200341206a41186a2903002208370300200341e8006a41106a200341206a41106a2903002209370300200341e8006a41086a200341206a41086a290300220a37030020032003290320220b370368200041196a2008370000200041116a2009370000200041096a200a3700002000200b3700010c020b200141ff0171450d00200341003a0088010b2003410036025020034201370348200341093602242003200341086a3602202003200341c8006a360244200341fc006a41013602002003420137026c200341c888c2003602682003200341206a360278200341c4006a41e88ac500200341e8006a10431a200335025042208620033502488410060240200328024c450d00200328024810350b410221010b200020013a00002005450d00200410350b20034190016a24000ba20403047f017e027f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022010d00200041003602000c010b200228021421032002200241186a280200360224200220013602202002200241206a10c4010240024020022802000d002002280224220420022802044102742205490d0002400240024002402005417f4c0d000240024020050d0042002106410121070c010b200510392207450d022007200228022022082005109d081a2002200420056b3602242002200820056a3602202005ad21060b2007450d04024020062005ad422086842206422088a722050d002006a721050c030b024020072005724103710d002006a722054103710d0020054102762204450d032006422288a721080c040b2006a7450d04200710350c040b1044000b1045000b4100210802402005450d00200710350b41002104410421070b41000d002007450d002000200436020420002007360200200041086a20083602000c010b20024100360230200242013703282002410936023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b200041003602000b2003450d00200110350b200241e0006a24000bef1104047f017e137f047e23004180036b220224002002412036022420022001360220200241286a2001ad4280808080800484100510c2010240024002400240200228022822030d00200041003602000c010b200228022c21042002200241306a28020036023c20022003360238200241186a200241386a10c4010240024020022802180d00200228021c2205200228023c411c6e2201200120054b1bad421c7e2206422088a70d032006a72201417f4c0d030240024020010d00410421070c010b200110332207450d050b200241003602482002200736024020022001411c6e36024402400240024002400240024002402005450d00200241a0026a41c4006a2108410021094100210a0340200241106a200241386a10c40120022802100d072002280214220b200228023c41e0006e22012001200b4b1bad42e0007e2206422088a70d0b2006a72201417f4c0d0b0240024020010d004108210c0c010b20011033220c450d0d0b200241003602582002200c3602502002200141e0006e3602540240024002400240200b450d004100210d0340200241a0026a200241386a10c702200241e0016a41386a2201200241a0026a41386a290300370300200241e0016a41306a220e200241a0026a41306a290300370300200241e0016a41286a220f200241a0026a41286a290300370300200241e0016a41206a2210200241a0026a41206a290300370300200241e0016a41186a2211200241a0026a41186a290300370300200241e0016a41106a2212200241a0026a41106a290300370300200241e0016a41086a2213200241a0026a41086a290300370300200241c0016a41086a2214200841086a290200370300200241c0016a41106a2215200841106a290200370300200241c0016a41186a2216200841186a280200360200200220022903a0023703e001200220082902003703c00120022802e0022217450d0220024180016a41386a2218200129030037030020024180016a41306a2219200e29030037030020024180016a41286a220e200f29030037030020024180016a41206a220f201029030037030020024180016a41186a2210201129030037030020024180016a41106a2211201229030037030020024180016a41086a22122013290300370300200241e0006a41086a22132014290300370300200241e0006a41106a22142015290300370300200241e0006a41186a22152016280200360200200220022903e00137038001200220022903c0013703600240200d2002280254470d00200241d0006a200d410110a4012002280250210c2002280258210d0b200c200d41e0006c6a2201200229038001370300200141106a2011290300370300200141086a2012290300370300201929030021062018290300211a200e290300211b200f290300211c2010290300211d200141c0006a2017360200200141186a201d370300200141206a201c370300200141286a201b370300200141c4006a2002290360370200200141386a201a370300200141306a2006370300200141cc006a2013290300370200200141d4006a2014290300370200200141dc006a20152802003602002002200d41016a220d360258200b417f6a220b0d000b0b200c450d0a20022902542106200241086a200241386a10c40120022802080d07200228020c220b200228023c220d41027622012001200b4b1b2201410274220e417f4c0d0e20010d014104210f0c020b0240200d450d00200d41e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010350b0240200128020041ffffff3f71450d002001417c6a28020010350b200141e0006a2101200d41a07f6a220d0d000b0b20022802542201450d09200141e0006c0d080c090b200e1033220f450d0d0b200241003602a802200220013602a4022002200f3602a0020240200b450d00410021010340200d4104490d0520022002280238220e41046a360238200e280000220e418094ebdc034b0d040240200120022802a402470d00200241a0026a2001410110860120022802a002210f20022802a80221010b200d417c6a210d200f20014102746a200e3602002002200141016a22013602a802200b417f6a220b0d000b2002200d36023c0b200f450d0420022902a402211a200d4104490d05200a41016a210a2002200d417c6a36023c20022002280238220141046a3602382001280000210d024020092002280244470d00200241c0006a2009410110f90120022802402107200228024821090b20072009411c6c6a2201200d360218200120063702042001200c360200200141106a201a3702002001410c6a200f3602002002200941016a2209360248200a2005470d000b0b2007450d0620002002290244370204200020073602000c070b200d417c6a210d0b2002200d36023c20022802a40241ffffffff0371450d00200f10350b02402006422088a72201450d00200141e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010350b0240200128020041ffffff3f71450d002001417c6a28020010350b200141e0006a2101200d41a07f6a220d0d000b0b2006a72201450d02200141e0006c0d010c020b0240201a42ffffffff0383500d00200f10350b02402006422088a72201450d00200141e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010350b0240200128020041ffffff3f71450d002001417c6a28020010350b200141e0006a2101200d41a07f6a220d0d000b0b2006a72201450d01200141e0006c450d010b200c10350b2007200910c80220022802442201450d002001411c6c450d00200710350b200241003602e801200242013703e00120024109360284012002200241206a360280012002200241e0016a3602c001200241b4026a4101360200200242013702a402200241c888c2003602a002200220024180016a3602b002200241c0016a41e88ac500200241a0026a10431a20023502e80142208620023502e001841006024020022802e401450d0020022802e00110350b200041003602000b2004450d00200310350b20024180036a24000f0b1044000b1045000b9e06020a7f017e230041d0016b2202240041002103200241003a00c0012001280204417f6a2104024002400240024003402004417f460d01200241a0016a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c0012004417f6a21042005210320054120470d000b20024180016a41186a2204200241a0016a41186a220329030037030020024180016a41106a2205200241a0016a41106a220629030037030020024180016a41086a2207200241a0016a41086a2208290300370300200220022903a00137038001200241a0016a200110c50120022802c0012209450d01200241c0006a41186a220a2004290300370300200241c0006a41106a220b2005290300370300200241c0006a41086a22052007290300370300200241c0006a41286a22072008290300370300200241c0006a41306a22082006290300370300200241c0006a41386a220620032903003703002002200229038001370340200220022903a001370360200241c4016a2802002104200241a0016a41286a290300210c200241086a2005290300370300200241106a200b290300370300200241186a200a290300370300200241206a22032002290360370300200241286a22052007290300370300200241306a22072008290300370300200241386a2208200629030037030020022002290340370300200241c0006a200110c3012002280240450d02200241a0016a41086a2201200241c0006a41086a280200360200200220022903403703a001200041386a2008290300370300200041306a2007290300370300200041286a2005290300370300200041206a2003290300370300200041186a200241186a290300370300200041106a200241106a290300370300200041086a200241086a29030037030020002002290300370300200041c8006a200c3703002000200436024420002009360240200041d0006a20022903a001370300200041d8006a20012802003602000c030b200341ff0171450d00200241003a00c0010b200041003602400c010b200041003602402004450d00200441306c450d00200910350b200241d0016a24000bd90101037f02402001450d0020002001411c6c6a21020340024020002802082201450d00200141e0006c2103200028020041d4006a210103400240200141706a2802002204450d00200441306c450d002001416c6a28020010350b0240200128020041ffffff3f71450d002001417c6a28020010350b200141e0006a2101200341a07f6a22030d000b0b0240200041046a2802002201450d00200141e0006c450d00200028020010350b2000411c6a21010240200041106a28020041ffffffff0371450d00200028020c10350b2001210020012002470d000b0b0bbb1005057f017e067f077e017f230041c0016b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c2010240024002400240200328021022020d00200041023a00000c010b200328021421042003200341186a280200220536025420032002360250024002402005450d0020022d0000210120032005417f6a22063602542003200241016a360250200141014b0d00024002400240024020010e020001000b2003200341d0006a10c40120032802000d03200328020422062003280254220141306e2207200720064b1bad42307e2208422088a70d062008a72207417f4c0d060240024020070d00410821090c010b200710332209450d080b4100210a20034100360268200320093602602003200741306e220b36026402402006450d002006417f6a210720034198016a41017221064100210a02400240034020014104490d0120032802502205350000210820032001417c6a3602542003200541046a36025020034198016a200341d0006a10ca0220032d00980122054102460d01200341f0006a411f6a220b2006411f6a290000370000200341f0006a41186a220c200641186a290000370300200341f0006a41106a220d200641106a290000370300200341f0006a41086a220e200641086a290000370300200320062900003703700240200a2003280264470d00200341e0006a200a4101108801200328026021092003280268210a0b2009200a41306c6a220120053a000820012008370300200141096a2003290370370000200141116a200e290300370000200141196a200d290300370000200141216a200c290300370000200141286a200b2900003700002003200a41016a220a3602682007450d022007417f6a2107200328025421010c000b0b20032802642201450d05200141306c450d05200910350c050b2003280264210b0b2009450d0302400240200328025422014110490d0020032003280250220641106a3602502003200141706a220736025420074110490d00200641086a290000210f200629000021102003200641206a3602502003200141606a220736025420074104490d01200641186a2900002108200629001021112003200641246a36025020032001415c6a220736025420074110490d0120062800202107200341386a2006412c6a290000370300200341cc006a41026a200341dd006a41026a2d00003a000020032011370320200320032f005d3b014c20032007360240200320062900243703302003200837032820032001414c6a3602542003200641346a360250410021010c030b200b450d04200b41306c450d04200910350c040b200b450d03200b41306c450d03200910350c030b20064110490d0220032005416f6a220a3602542003200241116a360250200241096a29000021082002290001211141002101200341003a00b801416e21060340200a2001460d0220034198016a20016a200220016a220741116a2d00003a00002003200520066a3602542003200741126a3602502003200141016a22073a00b8012006417f6a21062007210120074120470d000b200341e2006a20032d009a013a0000200320032f0198013b01602005416f6a2007460d02200341af016a290000210f20032900a7012110200328009b012109200328009f01210b20032800a301210a20032d00b701210d200220076a220141116a2d0000210c2003200520066a22063602542003200141126a360250200c41074f0d0220064110490d022003200141226a220e3602502003200520076b2207415e6a220636025420064110490d022001411a6a2900002112200141126a29000021132003200141326a220536025020032007414e6a220636025420064104490d022001412a6a2900002114200e2900002115200528000021062003200141366a220e36025020032007414a6a220536025420054110490d02200341cc006a41026a200341e0006a41026a2d00003a0000200341c0006a2012370300200341206a41106a2008370300200320032f01603b014c2003200741ba7f6a3602542003200141c6006a36025020032013370338200320113703282003200c3a00212003200d3a0020200320032801703601222003200341f4006a2f01003b01262001413e6a2900002111200e2900002108410121010b200341f0006a41026a200341cc006a41026a2d000022073a000020034198016a41086a2205200341206a41086a29030037030020034198016a41106a220c200341206a41106a29030037030020034198016a41186a220d200341206a41186a29030037030020034198016a41206a220e200341206a41206a290300370300200320032f014c22163b01702003200329032037039801200041186a200f370000200041106a2010370000200041036a20073a0000200020163b00012000410c6a200a360000200041086a200b360000200041046a2009360000200041e8006a2006360000200041e0006a2011370000200041d8006a2008370000200041d0006a2014370000200041c8006a2015370000200041206a200329039801370000200041286a2005290300370000200041306a200c290300370000200041386a200d290300370000200041c0006a200e2903003700000c020b200141ff0171450d00200341003a00b8010b2003410036022820034201370320200341093602742003200341086a3602702003200341206a360260200341ac016a41013602002003420137029c01200341c888c200360298012003200341f0006a3602a801200341e0006a41e88ac50020034198016a10431a2003350228422086200335022084100602402003280224450d00200328022010350b410221010b200020013a00002004450d00200210350b200341c0016a24000f0b1044000b1045000b840402067f047e230041206b21020240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a2207360200200541014b0d0320050e020102010b200041023a00000f0b02402006450d0020042d0001210520012003417e6a22063602042001200441026a360200200541ff0071220741064b0d0020064110490d00200041003a0000200041086a2004290002370300200041026a20073a0000200020054107763a0001200041036a2002280009360000200041186a2002290310370300200041106a2004410a6a29000037030020012003416e6a3602042001200441126a360200200041076a2002410d6a2d00003a0000200041206a200241106a41086a2903003703000f0b200041023a00000f0b200241106a41086a220542003703002002420037031020064110490d01200741086a29000021082007290000210920012003416f6a22063602042001200441116a2207360200200542003703002002420037031020064110490d01200741086a290000210a2007290000210b20012003415f6a3602042001200441216a360200200041206a200a370300200041186a200b370300200041106a2008370300200041086a2009370300200041013a000020002002280009360001200041046a2002410c6a2800003600000f0b200041023a00000f0b200041023a00000bbb0402097f057e230041f0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022040d00200042003703000c010b200341186a28020021052003280214210641002101200341003a0068024002400240034020052001460d01200341c8006a20016a200420016a2d00003a00002003200141016a22023a00682002210120024120470d000b200341286a41186a2201200341c8006a41186a2207290300370300200341286a41106a2208200341c8006a41106a2209290300370300200341286a41086a220a200341c8006a41086a220b29030037030020032003290348370328200520026b410f4d0d01200b200a290300220c37030020092008290300220d37030020072001290300220e37030020032003290328220f370348200420026a22012900002110200041306a200141086a290000370300200041286a2010370300200041206a200e370300200041186a200d370300200041106a200c3703002000200f3703084201210c0c020b200141ff0171450d00200341003a00680b2003410036023020034201370328200341093602242003200341086a3602202003200341286a36026c200341dc006a41013602002003420137024c200341c888c2003602482003200341206a360258200341ec006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b4200210c0b2000200c3703002006450d00200410350b200341f0006a24000bf80202027f037e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602100c010b200328021421042003200341106a41086a28020022023602242003200136022002400240024020024110490d002003200241706a3602242003200141106a360220200141086a290000210520012900002106200341c8006a200341206a10c301200328024822020d010b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602100c010b200329024c2107200020053703082000200637030020002007370214200020023602100b2004450d00200110350b200341e0006a24000bde0201037f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602040c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d0020032002417c6a3602242003200141046a36022020012800002102200341c8006a200341206a10c301200328024822050d010b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602040c010b2000200329024c37020820002005360204200020023602000b2004450d00200110350b200341e0006a24000bb10201037f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022010d00200041003602000c010b200228021421032002200241186a28020036022420022001360220200241c8006a200241206a10cf0202400240200228024822040d0020024100360230200242013703282002410936023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b200041003602000c010b2000200229024c370204200020043602000b2003450d00200110350b200241e0006a24000b8f0d05037f017e0a7f017e047f23004180016b22022400200241086a200110c40102400240024002402002280208450d00200041003602000c010b200228020c2203200128020441246e2204200420034b1bad42247e2205422088a70d022005a72204417f4c0d020240024020040d00410421060c010b200410332206450d020b4100210720024100360218200220063602102002200441246e36021402402003450d00200241cd006a2108200241eb006a220941056a210a4100210b0340024002400240024002402001280204220c450d002001280200220d2d000021042001200c417f6a220e3602042001200d41016a360200200441074b0d00024002400240024002400240024020040e080007010703040205000b2002200110c40120022802000d06200128020420022802042204490d062004417f4c0d0f024020040d004101210f4101450d074100210d0c090b20041039220f450d0e20012802042004490d05200f20012802002004109d08210c2001280204220d2004490d072001200d20046b3602042001200128020020046a360200200c450d062004210d0c080b41002104200241003a0078200c417e6a210c02400340200e2004460d01200241d8006a20046a200d20046a220f41016a2d00003a00002001200c3602042001200f41026a3602002002200441016a220f3a0078200c417f6a210c200f2104200f4120470d000b200220092900003703402002200a290000370045200228005f210d20022f0158210420022d005a210c200228005b210f20022900632110200841026a200241d5006a41026a2d00003a0000200820022f00553b00002010428080808070832105200f41087621112004200c41107472210c2010a721044100210e0c0a0b200441ff0171450d05200241003a00780c050b200241d8006a200110c405200228025c220d450d0420022f015820022d005a41107472210c20022d005b210f200229036022104280808080708321052010a721044101210e0c080b200241d8006a200110c405200228025c220d450d0320022f015820022d005a41107472210c20022d005b210f200229036022104280808080708321052010a721044102210e0c070b200241d8006a200110c405200228025c220d450d0220022f015820022d005a41107472210c20022d005b210f200229036022104280808080708321052010a721044103210e0c060b200e450d01200d2d000121042001200c417e6a220f3602042001200d41026a36020020040d01200f450d01200d2d000221042001200c417d6a220e3602042001200d41036a360200200441014b0d014100210f0240024020040e020100010b200e4104490d02200d28000321122001200c41796a22043602042001200d41076a36020020044104490d02200d28000721132001200c41756a3602042001200d410b6a3602004101210f0b200241c0006a41086a200241d8006a41086a290200370300200220022902583703404104210e4200210541002111201321042012210d0c040b200f10350b200241306a41086a200241c0006a41086a290300370300200220022903403703302000410036020002402007450d00200741246c21042006210103400240024020012d0000220c41044b0d00024002400240200c0e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012004415c6a22040d000b0b20022802142201450d06200141246c450d06200610350c060b2004200d41a4f0cb001059000b200241c0006a41086a200241d8006a41086a29020037030020022002290258370340200f41087621114105210e420021050b0b200b41016a210b200241306a41086a200241c0006a41086a2903002210370300200241206a41086a22142010370300200220022903402210370330200220103703202011410874200f41ff017172210f20052004ad842105024020072002280214470d00200241106a20074101108d0120022802102106200228021821070b2006200741246c6a2204200537000c2004200d3600082004200f3600042004200c3b00012004200e3a0000200441036a200c4110763a0000200420022903203700142004411c6a20142903003700002002200741016a2207360218200b2003470d000b0b20002002290310370200200041086a200241106a41086a2802003602000b20024180016a24000f0b1045000b1044000ba00302037f037e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602140c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d002003200141046a36022020032002417c6a220536022420054110490d002001280000210520032002416c6a3602242003200141146a3602202001410c6a290000210620012900042107200341c8006a200341206a10c301200328024822020d010b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602140c010b200329024c210820002006370308200020073703002000200837031820002002360214200020053602100b2004450d00200110350b200341e0006a24000b940201037f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad84100510c20102400240200228020822010d00410221000c010b200228020c210302400240200241106a280200450d0020012d0000220441014b0d0041002100024020040e020200020b410121000c010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b410221000b2003450d00200110350b200241d0006a240020000bd70b06057f017e057f017e027f037e230041a0016b220324002003200236021420032001360210200341186a2002ad4220862001ad84100510c2010240024002400240200328021822010d00200041023a00000c010b200328021c21042003200341206a280200220236024c20032001360248024002402002450d0020012d0000210520032002417f6a220636024c2003200141016a360248200541014b0d000240024002400240024020050e020001000b20064104490d04200341c4006a41026a200341d8006a41026a2d00003a0000200341286a41086a200341f8006a41086a290300370300200341286a41106a200341f8006a41106a290300370300200341286a41186a200341f8006a41186a280200360200200320032f00583b0144200320032903783703282001280001210520032002417b6a36024c2003200141056a360248410021020c010b200341086a200341c8006a10c40120032802080d03200328024c2207200328020c2205490d032005417f4c0d060240024020050d0042002108410121090c010b200510392209450d082009200328024822022005109d081a2003200720056b220736024c2003200220056a3602482005ad21080b2009450d0341002102200341003a0098012005ad4220862008842208422088a7210a2008a7210b417f21050240024002400240034020072002460d01200341f8006a20026a2003280248220c2d00003a00002003200720056a36024c2003200c41016a3602482003200241016a22063a0098012005417f6a21052006210220064120470d000b200341d2006a20032d007a3a0000200341e0006a20034187016a290000370300200341d8006a41106a2003418f016a290000370300200341f0006a20034197016a2d00003a0000200320032f01783b01502003200329007f370358200720066b22024110490d01200328007b21052003200c41116a3602482003200241706a220d36024c200d4104490d05200c41096a290000210e200c29000121082003200c41156a36024820032002416c6a36024c2007416c6a2006460d05200c28001121062003200c41166a36024820032002416b6a220f36024c200c2d0015221041014b0d054100210d20100e020302030b200241ff0171450d00200341003a0098010b200b0d040c050b200f4104490d022003200c411a6a3602482003200241676a36024c200c28001621074101210d0b200341c4006a41026a200341d0006a41026a2d00003a0000200341286a41086a200341d8006a41086a290300370300200341286a41106a200341d8006a41106a290300370300200341286a41186a200341d8006a41186a2d00003a0000200341c3006a200341d5006a41026a2d00003a0000200320032f01503b014420032003290358370328200320032f00553b0041410121020b200341d8006a41026a200341c4006a41026a2d0000220c3a0000200341f8006a41086a200341286a41086a2903002211370300200341f8006a41106a200341286a41106a2903002212370300200341f8006a41186a200341286a41186a2802002210360200200320032f0144220f3b0158200320032903282213370378200041036a200c3a00002000200f3b0001200041046a2005360000200041c8006a200e370000200041c0006a2008370000200041086a2013370000200041106a2011370000200041186a2012370000200041206a2010360000200041386a2007360000200041346a200d360000200041306a20063600002000412c6a200a360000200041286a200b360000200041246a20093600000c030b200b450d010b200910350b20034100360230200342013703282003410936025c2003200341106a3602582003200341286a3602502003418c016a41013602002003420137027c200341c888c2003602782003200341d8006a36028801200341d0006a41e88ac500200341f8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b410221020b200020023a00002004450d00200110350b200341a0016a24000f0b1044000b1045000b850604067f027e027f057e23004190016b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822020d00200041003602180c010b200328020c21042003200341106a280200220136023c200320023602380240024020014104490d002003200241046a36023820032001417c6a220536023c20054104490d00200228000021062003200241086a3602382003200141786a220536023c20054110490d00200228000421072003200141686a220836023c2003200241186a360238200241106a29000021092002290008210a41002101200341003a0088010240034020082001460d01200341e8006a20016a200220016a220541186a2d00003a00002003200541196a3602382003200141016a22053a0088012005210120054120470d000b200341c8006a41086a2201200341e8006a41086a290300370300200341c8006a41106a220b200341e8006a41106a290300370300200341c8006a41186a220c200341e8006a41186a290300370300200320032903683703482003200820056b36023c200341e8006a200341386a10c30120032802682205450d01200341186a41086a2001290300220d370300200341186a41106a200b290300220e370300200341186a41186a200c290300220f370300200320032903482210370318200329026c2111200020093703082000200a3703002000201137021c200020053602182000200736021420002006360210200041246a20103702002000412c6a200d370200200041346a200e3702002000413c6a200f3702000c020b2003410036023c200141ff0171450d00200341003a0088010b20034100360250200342013703482003410936021c200320033602182003200341c8006a360244200341fc006a41013602002003420137026c200341c888c2003602682003200341186a360278200341c4006a41e88ac500200341e8006a10431a200335025042208620033502488410060240200328024c450d00200328024810350b200041003602180b2004450d00200210350b20034190016a24000bfa4f07087f017e017f017e017f027e4f7f230041d0086b220324002003200236021420032001360210200341186a2002ad4220862001ad84100510c20102400240200328021822040d00200041023a00a4020c010b200328021c21052003200341186a41086a280200360294022003200436029002200320034190026a36028804200341086a20034188046a10d5020240024020032802080d004108210602400240200328020c22074180012007418001491b2201450d00200141057410332206450d010b2003410036028808200320013602840820032006360280080240024002400240024002402007450d00200341b0086a2108410021010340200341003602a808200341a8086a20032802900222092003280294022202410420024104491b220a109d081a20032002200a6b3602940220032009200a6a360290020240200241034b0d00200341a8086a200a6a41004104200a6b109f081a0b20033502a808210b200341003a00a80820032802940222022002410047220a490d02200341a8086a2003280290022209200a109d081a20032002200a6b220c3602940220032009200a6a220a3602900202400240024020020d004200210d0c010b20032d00a808220241064b0d044200210d02400240024002400240024020020e0707000102030405070b200341a8086a200c4110200c4110491b22026a41004100411020026b22092002410f4b1b109f08210e200341a8086a200a2002109d081a2003200c20026b360294022003200a20026a360290020240200c410f4b0d00200e41002009109f081a0b2008290300210f20032903a80821104201210d0c060b4202210d0c040b4203210d0c030b4204210d0c020b4205210d0c010b4206210d0b0b02402001200328028408470d0020034180086a2001410110a101200328028008210620032802880821010b200620014105746a2202200d3703082002200b370300200241186a200f370300200241106a20103703002003200141016a2201360288082007417f6a22070d000b0b2006450d06200329028408210d200341b0086a220a4200370300200342003703a808200341a8086a20032802900222072003280294022201411020014110491b2202109d081a2003200120026b360294022003200720026a3602900202402001410f4b0d00200341a8086a20026a4100411020026b109f081a0b200a290300210f20032903a8082110200320034188046a10d50220032802000d0320032802042209413820094138491b22070d014104210a0c020b20032802840841ffffff3f71450d0520061035410221010c060b200741c8006c1033220a450d030b410021022003410036028006200320073602fc052003200a3602f805024002400240024002400240024002402009450d0020034180086a410c6a211120034180086a410172211241002102034020034180086a20034188046a10d6020240024020032d00800822074106470d00410621070c010b200341fc076a41026a2208201241026a2d00003a0000200341e0076a41086a220e201141086a290200370300200341e0076a41106a2213201141106a290200370300200320122f00003b01fc07200320112902003703e007200328028408210c2003280288082101200341a8086a20034188046a10d602024020032d00a8084106470d00024020074101470d002001450d00200c10350b410621070c010b200341dc076a41026a20082d00003a0000200341c0076a41086a200e290300370300200341c0076a41106a201329030037030020034198076a41086a200341a8086a41086a29030037030020034198076a41106a200341a8086a41106a29030037030020034198076a41186a200341a8086a41186a29030037030020034198076a41206a200341a8086a41206a280200360200200320032f01fc073b01dc07200320032903e0073703c007200320032903a8083703980720012114200c21150b20034194076a41026a2201200341dc076a41026a2d00003a0000200341f8066a41086a220c200341c0076a41086a290300370300200341f8066a41106a2208200341c0076a41106a290300370300200341d0066a41086a220e20034198076a41086a290300370300200341d0066a41106a221320034198076a41106a290300370300200341d0066a41186a221620034198076a41186a290300370300200341d0066a41206a221720034198076a41206a280200360200200320032f01dc073b019407200320032903c0073703f80620032003290398073703d00620074106460d02200341cc066a41026a221820012d00003a0000200341b0066a41086a2219200c290300370300200341b0066a41106a220c200829030037030020034188066a41086a2208200e29030037030020034188066a41106a220e201329030037030020034188066a41186a2213201629030037030020034188066a41206a22162017280200360200200320032f0194073b01cc06200320032903f8063703b006200320032903d006370388060240200220032802fc05470d00200341f8056a2002410110a80120032802f805210a20032802800621020b200a200241c8006c6a220120073a0000200141086a2014360000200141046a2015360000200141036a20182d00003a0000200120032f01cc063b0001200141146a20192903003700002001411c6a200c2903003700002001410c6a20032903b006370000200141246a200329038806370000200141346a200e2903003700002001412c6a20082903003700002001413c6a2013290300370000200141c4006a20162802003600002003200241016a2202360280062009417f6a22090d000b20032802fc0521070b200a450d07200341a8086a20034188046a10d60220032d00a80822094106460d0120034194076a41026a20032d00ab083a0000200341c0076a41086a200341bc086a2201290200370300200341c0076a41106a200341c4086a2213290200370300200320032f00a9083b0194072003200341b4086a22162902003703c007200341a8086a41086a2217280200210c20032802ac082108200341a8086a20034188046a10d60220032d00a808220e4106460d02200341dc076a41026a20032d00ab083a0000200341e0076a41086a2001290200370300200341e0076a41106a2013290200370300200320032f00a9083b01dc07200320162902003703e0072017280200211320032802ac082116200341a8086a20034188046a10d60220032d00a80822174106460d03200341fc076a41026a20032d00ab083a000020034188066a41086a200341bc086a220129020037030020034188066a41106a200341c4086a2214290200370300200320032f00a9083b01fc072003200341b4086a221529020037038806200341a8086a41086a2212280200211820032802ac082119200341a8086a20034188046a10d60220032d00a80822114106460d04200341f8056a41026a20032d00ab083a0000200341d0066a41086a2001290200370300200341d0066a41106a2014290200370300200320032f00a9083b01f805200320152902003703d0062012280200211420032802ac082115200341a8086a20034188046a10d60220032d00a80822124106470d05024020114101470d002014450d00201510350b024020174101470d002018450d00201910350b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d07200741c8006c0d060c070b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b20032802fc052201450d06200141c8006c0d050c060b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d05200741c8006c0d040c050b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d04200741c8006c0d030c040b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d03200741c8006c0d020c030b024020174101470d002018450d00201910350b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d02200741c8006c0d010c020b200341b2066a20032d00ab083a000020034198076a41086a200341bc086a290200370300200341a8076a200341c4086a290200370300200320032f00a9083b01b0062003200341b4086a29020037039807200341a8086a41086a280200211a20032802ac08211b200341003a00a8080240024020032802940222012001410047221c490d00200341a8086a200328029002221d201c109d081a20032001201c6b221e360294022003201d201c6a221f360290020240024020010d00410021010c010b20032d00a808222041014b0d0141002101024020200e020100010b200341003a00a808201e201e4100472201490d01200341a8086a201f2001109d081a2003201e20016b221d360294022003201f20016a22213602900202400240201e450d0020032d00a808211c0c010b4100211c200341003a00a8080b200341003a00a808201d201d4100472201490d01200341a8086a20212001109d081a2003201d20016b2222360294022003202120016a22213602900202400240201d450d0020032d00a808211d0c010b4100211d200341003a00a8080b200341003a00a808202220224100472201490d01200341a8086a20212001109d081a2003202220016b2223360294022003202120016a222436029002024002402022450d0020032d00a80821210c010b41002121200341003a00a8080b200341003a00a808202320234100472201490d01200341a8086a20242001109d081a2003202320016b2225360294022003202420016a222436029002024002402023450d0020032d00a80821220c010b41002122200341003a00a8080b200341003a00a808202520254100472201490d01200341a8086a20242001109d081a2003202520016b2226360294022003202420016a222436029002024002402025450d0020032d00a80821230c010b41002123200341003a00a8080b200341003a00a808202620264100472201490d01200341a8086a20242001109d081a2003202620016b2225360294022003202420016a222736029002024002402026450d0020032d00a80821240c010b41002124200341003a00a8080b200341003a00a808202520254100472201490d01200341a8086a20272001109d081a2003202520016b2226360294022003202720016a222736029002024002402025450d0020032d00a80821250c010b41002125200341003a00a8080b200341003a00a808202620264100472201490d01200341a8086a20272001109d081a2003202620016b2228360294022003202720016a222736029002024002402026450d0020032d00a80821260c010b41002126200341003a00a8080b200341003a00a808202820284100472201490d01200341a8086a20272001109d081a2003202820016b2229360294022003202720016a222a36029002024002402028450d0020032d00a80821270c010b41002127200341003a00a8080b200341003a00a808202920294100472201490d01200341a8086a202a2001109d081a2003202920016b222b360294022003202a20016a222a36029002024002402029450d0020032d00a80821280c010b41002128200341003a00a8080b200341003a00a808202b202b4100472201490d01200341a8086a202a2001109d081a2003202b20016b222c360294022003202a20016a222a3602900202400240202b450d0020032d00a80821290c010b41002129200341003a00a8080b200341003a00a808202c202c4100472201490d01200341a8086a202a2001109d081a2003202c20016b222b360294022003202a20016a222d3602900202400240202c450d0020032d00a808212a0c010b4100212a200341003a00a8080b200341003a00a808202b202b4100472201490d01200341a8086a202d2001109d081a2003202b20016b222c360294022003202d20016a222d3602900202400240202b450d0020032d00a808212b0c010b4100212b200341003a00a8080b200341003a00a808202c202c4100472201490d01200341a8086a202d2001109d081a2003202c20016b222e360294022003202d20016a222d3602900202400240202c450d0020032d00a808212c0c010b4100212c200341003a00a8080b200341003a00a808202e202e4100472201490d01200341a8086a202d2001109d081a2003202e20016b222f360294022003202d20016a22303602900202400240202e450d0020032d00a808212d0c010b4100212d200341003a00a8080b200341003a00a808202f202f4100472201490d01200341a8086a20302001109d081a2003202f20016b2231360294022003203020016a22303602900202400240202f450d0020032d00a808212e0c010b4100212e200341003a00a8080b200341003a00a808203120314100472201490d01200341a8086a20302001109d081a2003203120016b2232360294022003203020016a223036029002024002402031450d0020032d00a808212f0c010b4100212f200341003a00a8080b200341003a00a808203220324100472201490d01200341a8086a20302001109d081a2003203220016b2231360294022003203020016a221e36029002024002402032450d0020032d00a80821300c010b41002130200341003a00a8080b200341003a00a808203120314100472201490d01200341a8086a201e2001109d081a2003203120016b2232360294022003201e20016a221e36029002024002402031450d0020032d00a80821310c010b41002131200341003a00a8080b200341003a00a808203220324100472201490d01200341a8086a201e2001109d081a2003203220016b360294022003201e20016a36029002024002402032450d0020032d00a80821320c010b41002132200341003a00a8080b410121010b200341a8086a20034188046a10d60220032d00a808221e4106460d01200341f8066a41026a223320032d00ab083a000020034180086a41086a2234200341bc086a29020037030020034180086a41106a2235200341c4086a290200370300200320032f00a9083b01f8062003200341b4086a29020037038008200341a8086a41086a2236280200211f20032802ac082120200341a8086a20034188046a10d60220032d00a8084106470d040240201e4101470d00201f450d00202010350b024020124101470d00201a450d00201b10350b024020114101470d002014450d00201510350b024020174101470d002018450d00201910350b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d03200741c8006c0d020c030b024020124101470d00201a450d00201b10350b024020114101470d002014450d00201510350b024020174101470d002018450d00201910350b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d02200741c8006c0d010c020b024020124101470d00201a450d00201b10350b024020114101470d002014450d00201510350b024020174101470d002018450d00201910350b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d01200741c8006c450d010b200a10350b200d42ffffff3f83500d0220061035410221010c030b20034190046a41206a2237200341a8086a41206a223828020036020020034190046a41186a2239200341a8086a41186a223a29030037030020034190046a41106a223b200341a8086a41106a223c29030037030020034190046a41086a223d2036290300370300200341f2056a41026a223e20034194076a41026a223f2d00003a0000200341d8056a41086a2240200341c0076a41086a2241290300370300200341d8056a41106a2242200341c0076a41106a2243290300370300200320032903a80837039004200320032f0194073b01f205200320032903c0073703d805200341d4056a41026a2244200341dc076a41026a22452d00003a0000200320032f01dc073b01d405200341b8056a41106a2246200341e0076a41106a2247290300370300200341b8056a41086a2248200341e0076a41086a2249290300370300200320032903e0073703b805200341b4056a41026a224a200341fc076a41026a224b2d00003a0000200320032f01fc073b01b40520034198056a41106a224c20034188066a41106a224d29030037030020034198056a41086a224e20034188066a41086a224f29030037030020032003290388063703980520034194056a41026a2250200341f8056a41026a22512d00003a0000200320032f01f8053b019405200341f8046a41106a2252200341d0066a41106a2253290300370300200341f8046a41086a2254200341d0066a41086a2255290300370300200320032903d0063703f804200341f4046a41026a2256200341b0066a41026a22572d00003a0000200320032f01b0063b01f404200341d8046a41106a225820034198076a41106a2259290300370300200341d8046a41086a225a20034198076a41086a225b29030037030020032003290398073703d804200341d4046a41026a225c20332d00003a0000200320032f01f8063b01d404200341b8046a41106a225d2035290300370300200341b8046a41086a225e203429030037030020032003290380083703b8042003418c046a41026a225f200341f5056a41026a2d00003a0000200320032f00f5053b018c042033203e2d00003a0000200320032f01f2053b01f8062035204229030037030020342040290300370300200320032903d80537038008205720442d00003a0000200320032f01d4053b01b00620592046290300370300205b2048290300370300200320032903b805370398072051204a2d00003a0000200320032f01b4053b01f8052053204c2903003703002055204e29030037030020032003290398053703d006204b20502d00003a0000200320032f0194053b01fc07204d2052290300370300204f2054290300370300200320032903f80437038806204520562d00003a0000200320032f01f4043b01dc07204720582903003703002049205a290300370300200320032903d8043703e007203f205c2d00003a0000200320032f01d4043b0194072043205d2903003703002041205e290300370300200320032903b8043703c00720382037280200360200203a2039290300370300203c203b2903003703002036203d29030037030020032003290390043703a808200341cc066a41026a205f2d00003a0000200320032f018c043b01cc060c020b1045000b410221010b20034184046a41026a200341f8066a41026a2d00003a0000200341e8036a41086a20034180086a41086a290300370300200341e8036a41106a223320034180086a41106a290300370300200341e4036a41026a200341b0066a41026a2d00003a0000200341c8036a41086a20034198076a41086a290300370300200341c8036a41106a223420034198076a41106a290300370300200320032f01f8063b01840420032003290380083703e803200320032f01b0063b01e40320032003290398073703c803200341c4036a41026a200341f8056a41026a2d00003a0000200341a8036a41086a200341d0066a41086a290300370300200341a8036a41106a2235200341d0066a41106a290300370300200341a4036a41026a200341fc076a41026a2d00003a000020034188036a41086a20034188066a41086a29030037030020034188036a41106a223620034188066a41106a290300370300200320032f01f8053b01c403200320032903d0063703a803200320032f01fc073b01a40320032003290388063703880320034184036a41026a200341dc076a41026a2d00003a0000200341e8026a41106a2237200341e0076a41106a290300370300200341e8026a41086a200341e0076a41086a290300370300200341e4026a41026a20034194076a41026a2d00003a0000200341c8026a41106a2238200341c0076a41106a290300370300200341c8026a41086a200341c0076a41086a290300370300200320032f01dc073b018403200320032903e0073703e802200320032f0194073b01e402200320032903c0073703c802200341a0026a41206a2239200341a8086a41206a280200360200200341a0026a41186a223a200341a8086a41186a290300370300200341a0026a41106a223b200341a8086a41106a290300370300200341a0026a41086a200341a8086a41086a290300370300200320032903a8083703a0022003419c026a41026a200341cc066a41026a2d00003a0000200320032f01cc063b019c020240024020014102470d00200341003602880820034201370380082003410936029c072003200341106a36029807200320034180086a3602d006200341bc086a4101360200200342013702ac08200341c888c2003602a808200320034198076a3602b808200341d0066a41e88ac500200341a8086a10431a200335028808422086200335028008841006200328028408450d0120032802800810350c010b2003418c026a41026a223c20034184046a41026a2d00003a0000200341f0016a41086a223d200341e8036a41086a290300370300200341f0016a41106a223e2033290300370300200341ec016a41026a2233200341e4036a41026a2d00003a0000200341d0016a41086a223f200341c8036a41086a290300370300200341d0016a41106a22402034290300370300200320032f0184043b018c02200320032903e8033703f001200320032f01e4033b01ec01200320032903c8033703d001200341cc016a41026a2234200341c4036a41026a2d00003a0000200341b0016a41086a2241200341a8036a41086a290300370300200341b0016a41106a22422035290300370300200341ac016a41026a2235200341a4036a41026a2d00003a000020034190016a41086a224320034188036a41086a29030037030020034190016a41106a22442036290300370300200320032f01c4033b01cc01200320032903a8033703b001200320032f01a4033b01ac012003200329038803370390012003418c016a41026a223620034184036a41026a2d00003a0000200341f0006a41106a22452037290300370300200341f0006a41086a2237200341e8026a41086a290300370300200341ec006a41026a2246200341e4026a41026a2d00003a0000200341d0006a41106a22472038290300370300200341d0006a41086a2238200341c8026a41086a290300370300200320032f0184033b018c01200320032903e802370370200320032f01e4023b016c200320032903c802370350200341286a41206a22482039280200360200200341286a41186a2239203a290300370300200341286a41106a223a203b290300370300200341286a41086a223b200341a0026a41086a290300370300200320032903a002370328200341a8086a41026a22492003419c026a41026a2d00003a0000200320032f019c023b01a8082000200f37030820002010370300200020093a002820002002360224200020073602202000200a36021c2000200d370214200020063602102000200c3602302000200836022c200020032f018c023b00292000412b6a203c2d00003a0000200020032903f0013702342000413c6a203d290300370200200041c4006a203e2903003702002000200e3a004c200041cf006a20332d00003a0000200020032f01ec013b004d2000201336025420002016360250200041e8006a2040290300370200200041e0006a203f290300370200200020032903d001370258200020173a0070200041f3006a20342d00003a0000200020032f01cc013b007120002018360278200020193602742000418c016a204229030037020020004184016a2041290300370200200020032903b00137027c200020113a00940120004197016a20352d00003a0000200020032f01ac013b0095012000201436029c012000201536029801200041b0016a2044290300370200200041a8016a204329030037020020002003290390013702a001200020123a00b801200041bb016a20362d00003a0000200020032f018c013b00b9012000201a3602c0012000201b3602bc01200041d4016a2045290300370200200041cc016a2037290300370200200020032903703702c4012000201e3a00dc01200041df016a20462d00003a0000200020032f016c3b00dd012000201f3602e401200020203602e001200041f8016a2047290300370200200041f0016a2038290300370200200020032903503702e801200041a0026a204828020036020020004198026a203929030037020020004190026a203a29030037020020004188026a203b2903003702002000200329032837028002200041b8026a20323a0000200041b7026a20313a0000200041b6026a20303a0000200041b5026a202f3a0000200041b4026a202e3a0000200041b3026a202d3a0000200041b2026a202c3a0000200041b1026a202b3a0000200041b0026a202a3a0000200041af026a20293a0000200041ae026a20283a0000200041ad026a20273a0000200041ac026a20263a0000200041ab026a20253a0000200041aa026a20243a0000200041a9026a20233a0000200041a8026a20223a0000200041a7026a20213a0000200041a6026a201d3a00002000201c3a00a502200041bb026a20492d00003a0000200041b9026a20032f01a8083b00000b200020013a00a4022005450d00200410350b200341d0086a24000bd90401057f230041106b22022400200241003a000502400240024002400240024020012802002203280204220420044100472205490d00200241056a200328020022062005109d081a2003200420056b3602042003200620056a360200024020040d00410021040c050b024020022d0005220441037122034103460d000240024020030e03070001070b200241003b0106200220043a00064101210420012802002201280204220320034100472205490d04200241066a410172200128020022042005109d0821062001200320056b3602042001200420056a360200024020030d00200620056a22044100200241066a20046b41026a109f081a0b20022f0106220441ff014d0d0220044102762103410021040c070b20024100360208200220043a0008200241086a4101722001280200220428020020042802042205410320054103491b2203109d082106200428020422012003490d042004200120036b3602042004200428020020036a3602000240200541024b0d00200620036a22044100200241086a20046b41046a109f081a0b2002280208220341808004492104200341027621030c060b200441034d0d010b410121040c040b2002410036020c2002410c6a20012802002204280200220120042802042203410420034104491b2205109d081a2004200320056b3602042004200120056a3602000240200341034b0d002002410c6a20056a4100410420056b109f081a0b200228020c22034180808080044921040c030b0c020b2003200141a4f0cb001059000b20044102762103410021040b2000200336020420002004360200200241106a24000b8913010b7f23004180016b22022400200241003a004002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802002203280204220420044100472205490d00200241c0006a200328020022062005109d081a2003200420056b3602042003200620056a360200024020040d00410021062002410d6a2107200241106a2108200241246a21090c140b2002410d6a2107200241106a2108200241246a210920022d0040220a41254b0d0141002106200a0e261301010101010101010101010101010101010101010101010101010101010101010102030405130b200041063a00000c130b0240200a417f6a220441ff01714121490d00200041063a00000c130b024020040d00410121034100210441002105410121060c120b0240200410392203450d002003200128020022012802002001280204220a2004200a2004491b2205109d08210b200128020422062005490d052001200620056b3602042001200128020020056a360200410121060240200a20044f0d00200b20056a22014100200b20046a20016b109f081a0b200421050c120b1045000b200241003a00784100210a02400340200241003a004020012802002203280204220420044100472205490d01200a41016a2106200241c0006a2003280200220b2005109d081a2003200420056b3602042003200b20056a360200024002402004450d0020022d004021040c010b41002104200241003a00400b200241d8006a200a6a20043a0000200220063a00782006210a20064120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c100b41012101200a41ff01710d040c0e0b200241003a00784100210a02400340200241003a004020012802002203280204220420044100472205490d01200a41016a2106200241c0006a2003280200220b2005109d081a2003200420056b3602042003200b20056a360200024002402004450d0020022d004021040c010b41002104200241003a00400b200241d8006a200a6a20043a0000200220063a00782006210a20064120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c0d0b41012101200a41ff01710d040c0b0b200241003a00784100210a02400340200241003a004020012802002203280204220420044100472205490d01200a41016a2106200241c0006a2003280200220b2005109d081a2003200420056b3602042003200b20056a360200024002402004450d0020022d004021040c010b41002104200241003a00400b200241d8006a200a6a20043a0000200220063a00782006210a20064120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c0a0b41012101200a41ff01710d040c080b200241003a00784100210a02400340200241003a004020012802002203280204220420044100472205490d01200a41016a2106200241c0006a2003280200220b2005109d081a2003200420056b3602042003200b20056a360200024002402004450d0020022d004021040c010b41002104200241003a00400b200241d8006a200a6a20043a0000200220063a00782006210a20064120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c070b41012101200a41ff01710d040c050b2005200641a4f0cb001059000b200241003a00780c090b200241003a00780c060b200241003a00780c030b200241003a00780b0b2002413c6a41026a2206200241d4006a41026a2d00003a0000200241286a41086a220a200241c0006a41086a290300370300200241286a41106a220b200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20062d00003a0000200241106a41086a200a290300370300200241106a41106a200b2d00003a0000200220022f013c3b012420022002290328370310410521060c070b200041063a00000c070b0b2002413c6a41026a2206200241d4006a41026a2d00003a0000200241286a41086a220a200241c0006a41086a290300370300200241286a41106a220b200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20062d00003a0000200241106a41086a200a290300370300200241106a41106a200b2d00003a0000200220022f013c3b012420022002290328370310410421060c050b200041063a00000c050b0b2002413c6a41026a2206200241d4006a41026a2d00003a0000200241286a41086a220a200241c0006a41086a290300370300200241286a41106a220b200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20062d00003a0000200241106a41086a200a290300370300200241106a41106a200b2d00003a0000200220022f013c3b012420022002290328370310410321060c030b200041063a00000c030b0b410221062002413c6a41026a220a200241d4006a41026a2d00003a0000200241286a41086a220b200241c0006a41086a290300370300200241286a41106a220c200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a200a2d00003a0000200241106a41086a200b290300370300200241106a41106a200c2d00003a0000200220022f013c3b0124200220022903283703100c010b200041063a00000c010b200020063a0000200020092f00003b00012000410c6a2004360000200041086a2005360000200041046a2003360000200041106a2008290000370000200041216a20072f00003b0000200041036a200941026a2d00003a0000200041186a200841086a290000370000200041206a200841106a2d00003a0000200041236a200741026a2d00003a00000b20024180016a24000bb10201017f230041a0016b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822010d00200041003602400c010b200328020c21022003200341106a28020036027c20032001360278200341186a200341f8006a10c7020240024020032802580d002003410036028801200342013703800120034109360294012003200336029001200320034180016a36029c012003412c6a41013602002003420137021c200341c888c200360218200320034190016a3602282003419c016a41e88ac500200341186a10431a2003350288014220862003350280018410060240200328028401450d0020032802800110350b200041003602400c010b2000200341186a41e000109d081a0b2002450d00200110350b200341a0016a24000b8b06010d7f23004190016b220224002002412036021420022001360210200241186a2001ad4280808080800484100510c2010240024002400240200228021822030d00200041003602000c010b200228021c21042002200241206a28020036022c20022003360228200241086a200241286a10c4010240024020022802080d00200228020c2205200228022c22064105762201200120054b1b22014105742207417f4c0d030240024020010d00410121080c010b200710332208450d050b41002109200241003602402002200136023c20022008360238024002402005450d004100210a03402006210b41002101200241003a008801200a41016a210a0340200b2001460d03200241e8006a20016a200228022822072d00003a00002002200741016a3602282002200141016a22073a0088012007210120074120470d000b200241c8006a41186a220c200241e8006a41186a290300370300200241c8006a41106a220d200241e8006a41106a290300370300200241c8006a41086a220e200241e8006a41086a2903003703002002200229036837034802402009200228023c470d00200241386a20094101108a0120022802382108200228024021090b200b20076b2106200820094105746a22012002290348370000200141186a200c290300370000200141106a200d290300370000200141086a200e2903003700002002200941016a2209360240200a2005470d000b2002200b20076b36022c0b2008450d012000200229023c370204200020083602000c020b2002410036022c0240200141ff0171450d00200241003a0088010b200228023c41ffffff3f71450d00200810350b20024100360250200242013703482002410936023c2002200241106a3602382002200241c8006a360234200241fc006a41013602002002420137026c200241c888c2003602682002200241386a360278200241346a41e88ac500200241e8006a10431a200235025042208620023502488410060240200228024c450d00200228024810350b200041003602000b2004450d00200310350b20024190016a24000f0b1044000b1045000bb80c07057f017e067f017e037f027e017f23004190016b220324002003200236021420032001360210200341186a2002ad4220862001ad84100510c20102400240200328021822040d00200041023a00000c010b200328021c21052003200341206a280200220236023c20032004360238024002402002450d0020042d0000210120032002417f6a36023c2003200441016a360238200141014b0d00024002400240024002400240024020010e020001000b200341086a200341386a10c40120032802080d06200328023c2206200328020c2201490d062001417f4c0d030240024020010d0041002102410121070c010b200110392207450d052007200328023822022001109d081a2003200620016b220636023c2003200220016a360238200121020b2007450d062001ad4220862002ad842208a7210902400240024002400240024020064104490d002008422088a7210a2003280238220b280000210c20032006417c6a220d36023c2003200b41046a36023841002101200341003a008801417b210202400340200d2001460d01200341e8006a20016a200b20016a220e41046a2d00003a00002003200620026a36023c2003200e41056a3602382003200141016a220e3a0088012002417f6a2102200e2101200e4120470d000b2003200328006b3600432003200328026836024020032003280240360250200320032800433600532006200e6b2201417c6a4110490d06200341f7006a2900002108200329006f210f200328007f2102200328008301210d20032d00870121102003200b200e6a221141146a221236023820032001416c6a220b36023c200b4104490d042011410c6a2900002113201141046a29000021142012280000210b2003200141686a36023c2003201141186a2212360238200641686a200e460d0520122d000021122003200141676a221536023c2003201141196a360238201241014b0d054100210e20120e020302030b0240200141ff0171450d00200341003a0088010b2009450d0c0c0b0b2009450d0b200710350c0b0b20154104490d02201141196a28000021062003200141636a36023c20032011411d6a3602384101210e0b2003200328005336006320032003280250360260200320032802603602282003200328006336002b200320032800593602302003200341dc006a280000360033410021010c040b2009450d08200710350c080b2009450d07200710350c070b20090d050c060b41002101200341003a0088012002417f6a21062002417e6a2102034020062001460d02200341e8006a20016a200420016a220e41016a2d00003a00002003200e41026a3602382003200141016a220e3a0088012003200236023c2002417f6a2102200e2101200e4120470d000b2003200328006b3600432003200328026836024020032003280043360053200320032802403602502003200328025036026020032003280053360063200341f7006a2900002113200329006f2114200328007f2107200328008301210920032d008701210a20032003280063360033200320032802603602302003200341dc006a28000036002b20032003280059360228410121010b2003200328003336006b20032003280230360268200320032802283602402003200328002b360043200041106a2013370000200041086a2014370000200041046a200328006b36000020002003280268360001200041306a20063600002000412c6a200e360000200041286a200b360000200041246a200c360000200041206a200a3600002000411c6a2009360000200041186a2007360000200041c3006a20083700002000413b6a200f370000200041d3006a20103a0000200041cf006a200d360000200041cb006a2002360000200041346a2003280240360000200041376a20032800433600000c050b200141ff0171450d03200341003a0088010c030b1044000b1045000b200710350b2003410036024820034201370340200341093602542003200341106a3602502003200341c0006a360260200341fc006a41013602002003420137026c200341c888c2003602682003200341d0006a360278200341e0006a41e88ac500200341e8006a10431a2003350248422086200335024084100602402003280244450d00200328024010350b410221010b200020013a00002005450d00200410350b20034190016a24000bf30201047f230041d0016b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822010d00200041023a0088010c010b200228020c21032002200241106a2802003602ac01200220013602a801200241186a200241a8016a10db020240024020022d00a00122044102470d00200241003602b801200242013703b001200241093602c401200220023602c0012002200241b0016a3602cc012002412c6a41013602002002420137021c200241c888c2003602182002200241c0016a360228200241cc016a41e88ac500200241186a10431a20023502b80142208620023502b00184100620022802b401450d0120022802b00110350c010b2000200241186a418801109d0821052002200241186a418c016a2800003600b301200220022800a1013602b0012005418c016a20022800b301360000200520022802b001360089010b200020043a0088012003450d00200110350b200241d0016a24000bfe0703057f0e7e067f230041106b21020240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064108490d00200429000421072001200341746a220636020420012004410c6a36020020064108490d00200429000c210820012003416c6a22063602042001200441146a36020020064108490d00200429001421092001200341646a220636020420012004411c6a36020020064108490d00200429001c210a20012003415c6a22063602042001200441246a36020020064108490d002004290024210b2001200341546a220636020420012004412c6a36020020064108490d00200429002c210c20012003414c6a22063602042001200441346a36020020064108490d002004290034210d2001200341446a220636020420012004413c6a36020020064108490d00200429003c210e2001200341bc7f6a22063602042001200441c4006a36020020064108490d002004290044210f2001200341b47f6a22063602042001200441cc006a36020020064108490d00200429004c21102001200341ac7f6a22063602042001200441d4006a36020020064108490d00200429005421112001200341a47f6a22063602042001200441dc006a36020020064108490d00200429005c211220012003419c7f6a22063602042001200441e4006a36020020064108490d00200429006421132001200341947f6a22063602042001200441ec006a36020020064108490d00200429006c211420012003418c7f6a22063602042001200441f4006a36020020064104490d00200428007421152001200341887f6a22063602042001200441f8006a36020020064104490d00200428007821162001200341847f6a22063602042001200441fc006a36020020064104490d00200428007c21172001200341807f6a2206360204200120044180016a36020020064104490d0020042800800121182001200341fc7e6a2206360204200120044184016a22043602002006450d0020042d000021062001200341fb7e6a22193602042001200441016a360200200641014b0d004100211a0240024020060e020100010b4101211a0b20194104490d00200428000121062001200341f77e6a3602042001200441056a3602002000201a3a008801200020063602840120002018360280012000201736027c20002016360278200020153602742000200536027020002014370368200020133703602000201237035820002011370350200020103703482000200f3703402000200e3703382000200d3703302000200c3703282000200b3703202000200a3703182000200937031020002008370308200020073703002000418c016a2002410c6a28000036000020002002280009360089010f0b200041023a0088010b8b0a040a7f017e037f037e23004180026b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c2010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c4010240024020022802000d0020022802042205200228022422064106762201200120054b1b22014106742207417f4c0d030240024020010d00410821080c010b200710332208450d050b41002109200241003602302002200136022c200220083602280240024002402005450d004100210a03400240024002402006450d0020022002280220220b41016a3602202006417f6a2107200b2d0000220141014b0d054200210c20010e020201020b200241003602240c050b41002101200241003a00f8012006417f6a210d024002400240024002400340200d2001460d01200241d8016a20016a200b20016a220741016a2d00003a00002002200741026a3602202002200141016a22073a00f8012007210120074120470d000b200241b8016a41186a220d200241d8016a41186a290300370300200241b8016a41106a220e200241d8016a41106a290300370300200241b8016a41086a220f200241d8016a41086a290300370300200220022903d8013703b8012007417f7320066a4110490d022002200b20076a220141116a220b360220200620076b2207416f6a41074b0d012007416f6a21010c030b0240200141ff0171450d00200241003a00f8010b410021010c020b200141096a2900002110200141016a29000021112002200141196a360220200b2900002212428002540d02200741676a21010c010b2007417f7320066a21010b200241f8006a41086a20024198016a41086a290300370300200241f8006a41106a20024198016a41106a2903003703002002200229039801370378200220013602240c050b200741676a2107200241f8006a41086a200f290300220c370300200241d8006a41186a200d290300370300200241d8006a41106a200e290300370300200241d8006a41086a200c370300200220022903b801220c3703782002200c3703584201210c0b200a41016a210a200241386a41186a220b200241d8006a41186a290300370300200241386a41106a220d200241d8006a41106a290300370300200241386a41086a2206200241d8006a41086a2903003703002002200229035837033802402009200228022c470d00200241286a200910940120022802282108200228023021090b200820094106746a220120113703082001200c370300200141106a2010370300200141186a2012370300200141206a2002290338370300200141286a2006290300370300200141306a200d290300370300200141386a200b2903003703002002200941016a220936023020072106200a2005470d000b200220073602240b2008450d022000200229022c370204200020083602000c030b200220073602240b200228022c41ffffff1f71450d00200810350b200241003602c001200242013703b8012002410936029c012002200241086a360298012002200241b8016a360278200241ec016a4101360200200242013702dc01200241c888c2003602d801200220024198016a3602e801200241f8006a41e88ac500200241d8016a10431a20023502c00142208620023502b801841006024020022802bc01450d0020022802b80110350b200041003602000b2004450d00200310350b20024180026a24000f0b1044000b1045000b980704057f017e087f037e230041a0016b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c2010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c4010240024020022802000d00200228020422052002280224220641286e2201200120054b1bad42287e2207422088a70d032007a72201417f4c0d030240024020010d00410821080c010b200110332208450d050b4100210920024100360230200220083602282002200141286e36022c02400240024002402005450d004100210a034041002101200241003a009801200a41016a210a034020062001460d03200241f8006a20016a2002280220220b2d00003a00002002200b41016a3602202002200141016a220c3a009801200c2101200c4120470d000b200241d8006a41186a2201200241f8006a41186a290300370300200241d8006a41106a220d200241f8006a41106a290300370300200241d8006a41086a220e200241f8006a41086a290300370300200220022903783703582006200c6b220c4108490d03200241386a41086a220f200e290300370300200241386a41106a220e200d290300370300200241386a41186a220d2001290300370300200220022903583703382002200b41096a360220200b290001210702402009200228022c470d00200241286a20094101108f0120022802282108200228023021090b200c41786a21062008200941286c6a22012002290338370300200f2903002110200e2903002111200d290300211220012007370320200141186a2012370300200141106a2011370300200141086a20103703002002200941016a2209360230200a2005470d000b2002200c41786a3602240b2008450d032000200229022c370204200020083602000c040b20024100360224200141ff0171450d01200241003a0098010c010b2002200c3602240b200228022c2201450d00200141286c450d00200810350b20024100360260200242013703582002410936023c2002200241086a3602382002200241d8006a3602282002418c016a41013602002002420137027c200241c888c2003602782002200241386a36028801200241286a41e88ac500200241f8006a10431a200235026042208620023502588410060240200228025c450d00200228025810350b200041003602000b2004450d00200310350b200241a0016a24000f0b1044000b1045000bd304010a7f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602080c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d002003200141046a36022020032002417c6a220536022420054104490d00200128000021062003200241786a3602242003200141086a36022020012800042107200341c8006a200341206a10c30120032802482202450d00200341c8006a41086a2802002108200328024c2105200341c8006a200341206a10c3010240024020032802482209450d00200328024c210a2003280224220b41044f0d030240200a41ffffff3f71450d00200910350b200541ffffff3f710d010c020b200541ffffff3f71450d010b200210350b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602080c010b200341d0006a280200210c2000200536020c200020023602082000200736020420002006360200200041206a200328022022022800003602002000411c6a200c360200200041186a200a360200200041146a2009360200200041106a20083602002003200b417c6a3602242003200241046a3602200b2004450d00200110350b200341e0006a24000be70804067f027e077f027e230041e0016b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822040d00200042003703000c010b200341106a2802002105200328020c210641002101200341003a00d801200541706a21070240024002400240034020052001460d01200341b8016a20016a200420016a2d00003a00002003200141016a22023a00d8012007417f6a21072002210120024120470d000b200341d8006a41086a200341b8016a41086a290300370300200341d8006a41106a200341b8016a41106a290300370300200341d8006a41186a200341b8016a41186a290300370300200320032903b801370358200520026b22084110490d02200420026a22052900002109200541086a290000210a41002101200341003a00d801200841706a2108034020082001460d02200341b8016a20016a200520016a41106a2d00003a00002003200141016a22023a00d8012002210120024120470d000b200341f8006a41086a220b200341b8016a41086a2201290300370300200341f8006a41106a220c200341b8016a41106a2208290300370300200341f8006a41186a220d200341b8016a41186a220e290300370300200320032903b801370378200720026b410f4d0d02200341386a41086a2207200341d8006a41086a290300370300200341386a41106a220f200341d8006a41106a290300370300200341386a41186a2210200341d8006a41186a290300370300200341186a41086a2211200b290300370300200341186a41106a220b200c290300370300200341186a41186a220c200d2903003703002003200329035837033820032003290378370318200520026a220241106a2900002112200241186a2900002113200120072903003703002008200f290300370300200e201029030037030020034198016a41086a2202201129030037030020034198016a41106a2207200b29030037030020034198016a41186a2205200c290300370300200320032903383703b8012003200329031837039801200041206a2013370300200041186a2012370300200041106a200a37030020002009370308200041286a20032903b801370300200041306a2001290300370300200041386a2008290300370300200041c0006a200e290300370300200041c8006a200329039801370300200041d0006a2002290300370300200041d8006a2007290300370300200041e0006a2005290300370300420121090c030b200141ff0171450d01200341003a00d8010c010b200141ff0171450d00200341003a00d8010b200341003602a00120034201370398012003410936027c20032003360278200320034198016a360258200341cc016a4101360200200342013702bc01200341c888c2003602b8012003200341f8006a3602c801200341d8006a41e88ac500200341b8016a10431a20033502a0014220862003350298018410060240200328029c01450d0020032802980110350b420021090b200020093703002006450d00200410350b200341e0016a24000ba30303037f017e027f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c2010240024002400240200328021022010d00200041003602000c010b200328021421022003200341186a280200360224200320013602202003200341206a10c40102400240024020032802000d002003280224220420032802042205490d002005417f4c0d040240024020050d0042002106410121070c010b200510392207450d062007200328022022082005109d081a2003200420056b3602242003200820056a3602202005ad21060b20070d010b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602000c010b200020062005ad42208684370204200020073602000b2002450d00200110350b200341e0006a24000f0b1044000b1045000b990204017f017e017f017e230041d0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822010d00420021030c010b200228020c210402400240200241086a41086a2802004108490d0020012900002105420121030c010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b420021030b2004450d00200110350b2000200537030820002003370300200241d0006a24000bb20403037f027e057f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602140c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d002003200141046a36022020032002417c6a220536022420054110490d002001280000210520032002416c6a3602242003200141146a3602202001410c6a290000210620012900042107200341c8006a200341206a10c30120032802482202450d00200328024c21082003280224220941024f0d01200841ffffff3f71450d00200210350b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602140c010b200341d0006a280200210a200341386a41046a200341286a41046a2f0100220b3b010020032003280128220c36023820032009417e6a36022420032003280220220941026a36022020092f000021092000200637030820002007370300200041206a20093b01002000411c6a200a3602002000200836021820002002360214200020053602102000200c360122200041266a200b3b01000b2004450d00200110350b200341e0006a24000be70203017f017e017f23004190056b22032400200320023602b402200320013602b002200341b8026a2002ad4220862001ad842204100510c2010240024020032802b80222010d00411b21010c010b20032802bc0221052003200341c0026a2802003602fc04200320013602f804200341c8026a200341f8046a10b9020240024020032802c8022202411b470d00200341003602082003420137030020034109360284052003200341b0026a360280052003200336028c05200341dc026a4101360200200342013702cc02200341c888c2003602c802200320034180056a3602d8022003418c056a41e88ac500200341c8026a10431a200335020842208620033502008410062003280204450d01200328020010350c010b2003200341c8026a41047241ac02109d081a0b02402005450d00200110350b411b21012002411b460d0020041007200221010b20002001360200200041046a200341ac02109d081a20034190056a24000b9b0203017f017e017f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad842203100510c20102400240200228020822010d00410321000c010b200228020c210402400240200241106a280200450d0020012d000022004103490d010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b02402004450d00200110350b410321000c010b02402004450d00200110350b200310070b200241d0006a240020000bb10503027f017e047f230041d0006b2202240041a0e4cb00ad4280808080800284100122032900002104200241086a41086a200341086a29000037030020022004370308200310354190eaca00ad4280808080e00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b8e280b037f027e037f047e027f017e027f087e017f027e087f230041f0086b22062400200620043703402006200337033820062001360234200620053a004f024002400240024020012002460d002003200484500d0020012002412010a008450d00200641d0006a2002108e02200641e0006a2006280250220720062802582208108f02200629036021094200210a20064200370360200641a8016a280200210b20062d00ac01210c024002402009420151220d0d00200641b0016a41386a4200370300200641b0016a41306a4200370300200641b0016a41286a4200370300200641d0016a4200370300200641b0016a41186a4200370300200641c0016a4200370300200641b8016a4200370300200642003703b0014200210e4200210f420021100c010b200641e0006a41386a2903002103200641e0006a41306a2903002104200641e0006a41206a290300210e200641e0006a41186a290300210a200641a0016a2903002111200629037021102006290368210f200641d0016a200641e0006a41286a290300370300200641b0016a41286a2004370300200641b0016a41306a2003370300200641c0016a200a3703002006200e3703c801200620113703e8012006200f3703b001200620103703b8010b200641f0036a20062802342212108e0220064180046a20062802f003221320062802f8032201108f022006290380042114420021032006420037038004200641c8046a280200211520062d00cc04211602400240201442015122050d00200641d0046a41306a4200370300200641d0046a41286a4200370300200641d0046a41206a4200370300200641d0046a41186a4200370300200641d0046a41106a4200370300200641d8046a4200370300200642003703d004420021044200211742002118420021190c010b200641b8046a290300211120064180046a41306a290300211a20064180046a41206a290300211820064180046a41186a2903002117200641c0046a290300211920062903900421042006290388042103200641d0046a41206a20064180046a41286a290300370300200641d0046a41286a201a370300200641d0046a41306a2011370300200641d0046a41106a2017370300200620183703e804200620033703d004200620043703d8040b0240024020032006290338221b7d221a2003562004200641386a41086a290300221c7d2003201b54ad7d221120045620112004511b450d00419089c20021054280808080b00221114180800c21010c010b2006201a3703d004200620113703d804024020062903b001221d201b7c221e201d54221f200641b0016a41086a2903002220201c7c201fad7c221d202054201d2020511b450d0041a7d6ca0021054280808080800121114180800821010c010b2006201e3703b001200641c8016a29030021202006201d3703b8010240427f201e20062903c0017c22212021201e54221f201d20207c201fad7c2220201d542020201d511b221f1b428080e983b1de16544100427f2020201f1b501b450d0041fe88c20021054280808080a00221114180801021010c010b0240201b201c84500d0020064188056a2006280234108e02200641c0076a2006280288052222200628029005108f02200641f0076a290300420020062903c007420151221f1b211b200641e8076a2903004200201f1b211d0240200628028c05450d00202210350b201d201a56201b201156201b2011511b450d004180800421014280808080d002211141a389c20021050c010b0240024020062d004f4101460d00201a428080e983b1de165441002011501b0d010c040b20064188056a2006280234108e02200641c0076a200628028805221f200628029005108f0220062d008c08212220062903c007211b0240200628028c05450d00201f10350b201a42ffffe883b1de165620114200522011501b0d03201b4201520d03202241ff0171450d030b41f588c20021054280808080900121114180801421010b20014180801c7141830c7221152005ad220342088842ff018321042011200384428080fcffff0383211b4101211f0c020b200041043a00000c020b20064188056a41186a200641d0046a41186a290300221b37030020064188056a41206a2222200641d0046a41206a29030037030020064188056a41286a2223200641d0046a41286a29030037030020064188056a41306a2224200641d0046a41306a290300370300200620062903e004221d370398052006201a370388052006201137039005427f200320177c221c201c200354221f200420187c201fad7c220320045420032004511b221f1b427f2003201f1b8450212502400240427f201a201d7c22032003201a54221f2011201b7c201fad7c220320115420032011511b221f1b2204428080e983b1de16544100427f2003201f1b2203501b0d0020064198056a29030021042024290300211d2023290300211c20222903002117200629039005211820062903880521204201211b20062903a005211e0c010b02400240200420038450450d004200211b0c010b4200211b200641c0076a41186a22264200370300200641c0076a41106a22234200370300200641c0076a41086a22224200370300200642003703c00741b6fdc600ad4280808080800184221d10012224290000211c200641e0086a41086a221f202441086a2900003703002006201c3703e008202410352022201f290300370300200620062903e0083703c00741e489c200ad4280808080d00184221c100122242900002117201f202441086a290000370300200620173703e00820241035202320062903e0082217370300200641c0086a41086a22272022290300370300200641c0086a41106a22282017370300200641c0086a41186a2229201f290300370300200620062903c0073703c008200641186a200641c0086a412010d701200641186a41106a29030021172006290320211820062802182124202642003703002023420037030020224200370300200642003703c007201d10012226290000211d201f202641086a2900003703002006201d3703e008202610352022201f290300370300200620062903e0083703c007201c10012226290000211d201f202641086a2900003703002006201d3703e00820261035202320062903e008221d370300202720222903003703002028201d3703002029201f290300370300200620062903c0073703c008200642002017420020241b221d20037d2018420020241b221c200454ad7d2217201c20047d2218201c562017201d562017201d511b221f1b3703c807200642002018201f1b3703c007200641c0086aad4280808080800484200641c0076aad42808080808002841002200641f8076a2003370300200641f0076a2004370300202241013a0000200641c9076a2012290000370000200641d1076a201241086a290000370000200641d9076a201241106a290000370000200641e1076a201241186a290000370000200641033a00c00741b0b4cc004100200641c0076a10d4010b0b2025ad2103200641a8046a2017370300200641b0046a201c37030020064190046a2018370300200641b8046a201d37030020064198046a20043703002006201e3703a004200620193703c0042006202037038804420121044100211f200620164100201442015122221b3a00cc0420062015410020221b3602c8042006201b4201512215ad37038004024020150d002001ad4220862013ad841007420021044200211b0c010b200620013602c407200620133602c00720064188046a200641c0076a10e7024200211b0b024020062802f403450d00201310350b200641b0016a41106a210102400240201f0d00024002400240200541ff017122050d0020044200510d0041032115200641c0066a21050c010b2005450d0120044200520d0141042115200641c0056a21050b200541086a20153a0000200541003a0000200541096a2012290000370000200541116a201241086a290000370000200541196a201241106a290000370000200541216a201241186a29000037000041b0b4cc004100200510d4010b410421154100210520034201520d01200641f8076a2011370300200641f0076a201a37030041002105200641c0076a41086a41003a0000200641c9076a2012290000370000200641d1076a201241086a290000370000200641d9076a201241106a290000370000200641e1076a201241186a290000370000200641033a00c00741b0b4cc004100200641c0076a10d4010c010b20044208862005ad42ff018384201b842103201541807e7121050b200641c0056a41086a2212200141086a290300370300200641c0056a41106a221f200141106a290300370300200641c0056a41186a2213200141186a290300370300200641c0056a41206a2216200141206a290300370300200620012903003703c005200641b0016a41086a290300210420062903b001211102400240201541ff017122014104460d0020034280807c83211a200342088842ff01832110200520017221012003a7210d410121050c010b20062903e801211a200641c0066a41186a2012290300221b370300200641c0066a41206a201f290300370300200641e8066a22052013290300370300200641f0066a22152016290300370300200620062903c00522143703d006200620113703c006200620043703c806427f200f200a7c22032003200f5422012010200e7c2001ad7c220320105420032010511b22011b427f200320011b8450211202400240427f201120147c2203200320115422012004201b7c2001ad7c220320045420032004511b22011b2210428080e983b1de16544100427f200320011b2203501b0d00200641d0066a29030021102015290300211b2005290300210a200641e0066a290300210f20062903c806211420062903c006210e4201211d20062903d806211c0c010b02400240201020038450450d004200211d0c010b4200211d200641c0076a41186a22134200370300200641c0076a41106a22154200370300200641c0076a41086a22054200370300200642003703c00741b6fdc600ad4280808080800184221b1001221f290000210a200641e0086a41086a2201201f41086a2900003703002006200a3703e008201f103520052001290300370300200620062903e0083703c00741e489c200ad4280808080d00184220a1001221f290000210f2001201f41086a2900003703002006200f3703e008201f1035201520062903e008220f370300200641c0086a41086a22162005290300370300200641c0086a41106a2222200f370300200641c0086a41186a22252001290300370300200620062903c0073703c0082006200641c0086a412010d701200641106a290300210f200629030821142006280200211f201342003703002015420037030020054200370300200642003703c007201b10012213290000211b2001201341086a2900003703002006201b3703e0082013103520052001290300370300200620062903e0083703c007200a10012213290000211b2001201341086a2900003703002006201b3703e00820131035201520062903e008221b370300201620052903003703002022201b37030020252001290300370300200620062903c0073703c00820064200200f4200201f1b221b20037d20144200201f1b220a201054ad7d220f200a20107d2214200a56200f201b56200f201b511b22011b3703c80720064200201420011b3703c007200641c0086aad4280808080800484200641c0076aad42808080808002841002200641f8076a2003370300200641f0076a2010370300200541013a0000200641c9076a2002290000370000200641d1076a200241086a290000370000200641d9076a200241106a290000370000200641e1076a200241186a290000370000200641033a00c00741b0b4cc004100200641c0076a10d4010b0b2012ad210320064188016a200f37030020064190016a200a370300200641f0006a201437030020064198016a201b370300200641f8006a20103703002006201c370380012006201a3703a0012006200e37036842012110410021052006200c4100200942015122011b3a00ac012006200b410020011b3602a8012006201d4201512201ad370360024020010d002008ad4220862007ad841007420021104200211a0c010b200620083602c407200620073602c007200641e8006a200641c0076a10e7024200211a0b02402006280254450d00200710350b02400240024020050d00024002400240200d41ff017122010d0020104200510d0041032105200641f0026a21010c010b2001450d0120104200520d0141042105200641f0016a21010b200141086a20053a0000200141003a0000200141096a2002290000370000200141116a200241086a290000370000200141196a200241106a290000370000200141216a200241186a29000037000041b0b4cc004100200110d4010b20034201520d01200641f8076a2004370300200641f0076a2011370300200641c0076a41086a41003a0000200641c9076a2002290000370000200641d1076a200241086a290000370000200641d9076a200241106a290000370000200641e1076a200241186a290000370000200641033a00c00741b0b4cc004100200641c0076a10d4010c010b200141ff01714104470d010b200628023421012006290338210320064198086a200641386a41086a29030037030020064190086a2003370300200641c0076a41086a41023a0000200641c9076a2001290000370000200641d1076a200141086a290000370000200641d9076a200141106a290000370000200641e1076a200141186a290000370000200641e9076a2002290000370000200641f1076a200241086a290000370000200641f9076a200241106a29000037000020064181086a200241186a290000370000200641033a00c00741b0b4cc004100200641c0076a10d401200041043a00000c010b2000200141087622023b0001200020013a0000200041036a20024110763a0000200041046a2010420886200dad42ff018384201a843700000b200641f0086a24000bfd0102027f027e200028024021020240410410332203450d002003200236000020002d0044210220034104410810372203450d00200320023a0004200041086a29030021042000290300210520034108411510372203450d00200320053700052003410d6a2004370000200041186a29030021042000290310210520034115412a10372203450d00200320053700152003411d6a2004370000200041286a2903002104200029032021052003412a41d40010372203450d00200320053700252003412d6a2004370000200320002903303700352003413d6a200041386a29030037000020012902002003ad4280808080d008841002200310350f0b103c000b830404047f017e037f027e230041d0006b22012400200141206a41186a4200370300200141206a41106a22024200370300200141206a41086a220342003703002001420037032041a0e4cb00ad42808080808002841001220429000021052003200441086a29000037030020012005370320200410354189eaca00ad4280808080f00084100122042900002105200141c0006a41086a2206200441086a2900003703002001200537034020041035200220012903402205370300200141086a2003290300370300200141106a2005370300200141186a200629030037030020012001290320370300200141206a200110a20220012802202103200129022421052001410036022820014201370320200141206a41002005420020031b2205422088a7220441306c220641306d108a012005a721072003410820031b21082001280228210202402004450d00200128022020024105746a2103200821040340200441086a2900002105200441106a29000021092004290000210a200341186a200441186a290000370000200341106a2009370000200341086a20053700002003200a370000200241016a2102200341206a2103200441306a2104200641506a22060d000b0b2001200236022802402007450d00200741306c450d00200810350b20002001290320370200200041086a200141206a41086a280200360200200141d0006a24000b8d0303047f017e027f230041d0006b22012400200141206a41186a4200370300200141206a41106a22024200370300200141206a41086a220342003703002001420037032041a0e4cb00ad42808080808002841001220429000021052003200441086a29000037030020012005370320200410354189eaca00ad4280808080f00084100122042900002105200141c0006a41086a2206200441086a2900003703002001200537034020041035200220012903402205370300200141086a2003290300370300200141106a2005370300200141186a200629030037030020012001290320370300200141206a200110a20220012802202204410820041b2107410021030240024002402001290224420020041b2205422088a7220441014b0d0020040e020201020b03402004410176220220036a220620032007200641306c6a2000412010a0084101481b2103200420026b220441014b0d000b0b2007200341306c6a2000412010a0084521030b02402005a72204450d00200441306c450d00200710350b200141d0006a240020030bc00c07027f017e027f017e087f057e017f230022042105200441a0016b4160712204240002402002200384500d002000290000210620044180016a200110eb022004280280012107200428028401210842012109024002400240200428028801220a450d002007200a410574220a6a210b200a41406a210c200441e0006a41106a210d200441e0006a41196a210e2007210a02400340200441c0006a41106a220f200a41106a290300370300200441c0006a41086a2210200a41086a2903003703002004200a290300370340200a41186a2d000021112004200a41196a2800003602282004200a411c6a28000036002b20114103460d02200d200f290300370300200441e0006a41086a2010290300370300200e2004280228360000200e41036a200428002b36000020042004290340370360200420113a00780240024002400240200d2000460d00200d2900002000290000510d002004200e2800003602582004200e41036a28000036005b200441e8006a290300211220042903602113200429037021140c010b2009a7210f200441033a0098012004290390012106200429038001211520042903880121162004290398012109200f41ff01714103460d01200441e8006a2903002212200320042903602213200256201220035620122003511b220d1b211220132002200d1b2113201141022011200f41ff0171461b21112004290370211420152102201621030b2004200428005b36003320042004280258360230200420042802303602382004200428003336003b0240412010332217450d0020172013370300201720113a00182017201437031020172004280238360019201720123703082017411c6a200428003b360000200442818080801037021c20042017360218200c4160460d02200a41206a210a200441e0006a41106a210f200441e0006a41196a21104101210e0340200441c0006a41106a220d200a41106a290300370300200441c0006a41086a220b200a41086a2903003703002004200a290300370340200a41186a2d000021112004200a41196a2800003602282004200a411c6a28000036002b20114103460d03200f200d290300370300200441e0006a41086a220d200b29030037030020102004280228360000201041036a220b200428002b36000020042004290340370360200420113a0078024002400240200f2000460d00200f2900002000290000510d00200420102800003602582004200b28000036005b200d2903002112200429036021132004290370211420022115200321160c010b2009a7210b200441033a00980120042903900121062004290380012115200429038801211620042903980121090240200b41ff0171220b4103460d00200d2903002212200320042903602213200256201220035620122003511b220d1b211220132002200d1b2113201141022011200b461b2111200429037021140c010b200c450d070c010b2004200428005b36003320042004280258360230200420042802303602382004200428003336003b2004200428003b3600830120042004280238360280010240200e200428021c470d00200441186a200e410110a101200428021821170b2017200e4105746a220d20113a0018200d2014370310200d200428028001360019200d411c6a200428008301360000200d2012370308200d20133703002004200e41016a220e360220200c450d060b200a41206a210a200c41606a210c20152102201621030c000b0b1045000b200c41606a210c2015210220162103200a41206a220a200b470d010c040b0b20022115200321160b0240200841ffffff3f71450d00200710350b20044180016a41086a200441186a41086a28020036020020042004290318370380010c020b20022115200321160b20044100360288012004420837038001200841ffffff3f71450d00200710350b02400240200942ff01834203854200520d00200428028801210a200428028001210c20044180016a21040c010b0240200428028801220a200428028401470d0020044180016a200a410110a101200428028801210a0b200428028001220c200a4105746a221120063703102011201637030820112015370300201141186a20093703002004200a41016a220a3602880120044180016a21040b2001200c200a10ec02200441046a28020041ffffff3f71450d00200428020010350b200524000ba70704087f017e027f057e23004190016b22022400200241106a200110ed022002280210210320022002280218220136022420022003360220200241286a2001ad4220862003ad84100510c2010240024002400240024020022802282204450d00200228022c21052002200241306a28020036023c20022004360238200241086a200241386a10c40102400240024002402002280208450d0041002106200241003602400c010b200228020c2207200228023c4105762201200120074b1b22014105742206417f4c0d070240024020010d00410821080c010b200610332208450d070b41002106200241003602582002200136025420022008360250024002402007450d00034020024180016a200241386a10ee020240024020022d0080014101460d0041032109200228023c22014110490d01200229008101210a2002200141706a220b36023c20022002280238220c41106a360238200b450d01200c41086a290000210d200c290000210e20022001416f6a36023c2002200c41116a36023841032109200c2d0010220141034f0d012002200228008001360278200220024180016a41036a28000036007b200a210f200e2110200d2111200121090c010b410321090b200220022802783602702002200228007b36007320094103460d022002200228007336006b20022002280270360268024020062002280254470d00200241d0006a2006410110a10120022802502108200228025821060b200820064105746a220120093a00182001200f370310200120022802683600192001411c6a200228006b36000020012011370308200120103703002002200641016a22063602582007417f6a22070d000b0b200241c0006a41086a200241d0006a41086a28020036020020022002290350220f370340200fa722064521012006450d022002290244210f0c030b4100210620024100360240200228025441ffffff3f71450d00200810350b410121010b200241003602482002420137034020024109360284012002200241206a360280012002200241c0006a360278200241e4006a410136020020024201370254200241c888c200360250200220024180016a360260200241f8006a41e88ac500200241d0006a10431a2002350248422086200235024084100602402002280244450d00200228024010350b0b02402005450d00200410350b2001450d010b20004100360208200042083702000c010b2000200f370204200020063602000b02402002280214450d00200310350b20024190016a24000f0b1045000b1044000bb0180d037f027e027f067e027f027e017f017e027f017e037f027e017f230041b0056b22032400200341286a2000108e02200341386a2003280228220420032802302205108f0220032903382106420021072003420037033820034180016a280200210820032d00840121090240024020064201510d0020034188016a41386a420037030020034188016a41306a420037030020034188016a41286a420037030020034188016a41206a420037030020034188016a41186a420037030020034198016a420037030020034190016a420037030020034200370388014200210a4200210b4200210c0c010b200341386a41386a290300210d200341386a41306a290300210e200341386a41206a290300210a200341386a41186a2903002107200341f8006a290300210f2003290348210c2003290340210b20034188016a41206a200341386a41286a29030037030020034188016a41286a200e37030020034188016a41306a200d37030020034198016a20073703002003200a3703a0012003200f3703c0012003200b370388012003200c370390010b4200210d200341c0016a2210420037030020034188016a41306a420037030020034188016a41286a22114200370300200342003703a801200c200a7c2112200b20077c2213200b542214ad211520034188016a41106a211602402002450d00200241057421174200210d4200210f420021184200210e200121190340024002400240201941186a221a2d0000221b417f6a41ff017141014b0d002011200e201941086a290300220720182019290300220a56200e200756200e2007511b221b1b220e37030020032018200a201b1b22183703a801201a2d0000221b4102460d010b201b41ff01710d01201941086a29030021072019290300210a0b2010200d2007200f200a56200d200756200d2007511b221b1b220d3703002003200f200a201b1b220f3703b8010b201941206a2119201741606a22170d000b0b201220157c2107200341c8016a41186a201641086a290300220a370300200341c8016a41206a221b201641106a290300370300200341c8016a41286a201641186a290300370300200341c8016a41306a201641206a29030037030020032016290300220e3703d8012003200b3703c8012003200c3703d00102400240427f200b200e7c220e200e200b542219200c200a7c2019ad7c220a200c54200a200c511b22191b220e428080e983b1de16544100427f200a20191b220f501b0d00200341d8016a290300210e200341f8016a290300210f200341f0016a2903002118201b290300211220032903d001211520032903c801211c4201210a20032903e001211d0c010b02400240200e200f8450450d004200210a0c010b4200210a20034180046a41186a2210420037030020034180046a41106a2217420037030020034180046a41086a221b4200370300200342003703800441b6fdc600ad428080808080018422181001221a2900002112200341a0056a41086a2219201a41086a290000370300200320123703a005201a1035201b2019290300370300200320032903a0053703800441e489c200ad4280808080d0018422121001221a29000021152019201a41086a290000370300200320153703a005201a1035201720032903a005221537030020034180056a41086a2211201b29030037030020034180056a41106a2216201537030020034180056a41186a221e2019290300370300200320032903800437038005200341106a20034180056a412010d701200341106a41106a29030021152003290318211c2003280210211a2010420037030020174200370300201b4200370300200342003703800420181001221029000021182019201041086a290000370300200320183703a00520101035201b2019290300370300200320032903a0053703800420121001221029000021182019201041086a290000370300200320183703a00520101035201720032903a00522183703002011201b29030037030020162018370300201e20192903003703002003200329038004370380052003420020154200201a1b2218200f7d201c4200201a1b2212200e54ad7d22152012200e7d221c201256201520185620152018511b22191b3703880420034200201c20191b3703800420034180056aad428080808080048420034180046aad42808080808002841002200341b8046a200f370300200341b0046a200e370300201b41013a000020034189046a200029000037000020034191046a200041086a29000037000020034199046a200041106a290000370000200341a1046a200041186a290000370000200341033a00800441b0b4cc00410020034180046a10d4010b0b2007200c5121192007200c54211b200341e0006a2012370300200341e8006a2018370300200341c8006a2015370300200341f0006a200f370300200341d0006a200e3703002003201d3703582003200d3703782003201c370340200320094100200642015122171b3a00840120032008410020171b360280012003200a4201512217ad3703380240024020170d002005ad4220862004ad8410070c010b20032005360284042003200436028004200341c0006a20034180046a10e7020b2014201b20191b21190240200328022c450d00200410350b427f200720191b2107427f201320191b210d200a420152211902400240024020064201510d0020190d004103211b20034180036a21190c010b20064201522019410173720d014104211b20034180026a21190b201941086a201b3a0000201941003a0000201941096a2000290000370000201941116a200041086a290000370000201941196a200041106a290000370000201941216a200041186a29000037000041b0b4cc004100201910d4010b0240200d2007844200520d00200341b8046a200c370300200341b0046a200b37030020034180046a41086a41003a000020034189046a200029000037000020034191046a200041086a29000037000020034199046a200041106a290000370000200341a1046a200041186a290000370000200341033a00800441b0b4cc00410020034180046a10d4010b20034180046a200010ed02200341086a200328028004221920032802880441b0b4cc0041004100108a02200328020821040240200328028404450d00201910350b0240024002400240024002402002450d0020034180036a200010ed0220024105744104722219417f4c0d02200335028803210d200328028003210520191033221b450d03200341003602880420032019360284042003201b36028004200220034180046a107720024105742111200328028404211a2003280288042117034002400240201a20176b4108490d00200328028004211b201a21100c010b201741086a22192017490d06201a410174221b2019201b20194b1b22104100480d0602400240201a0d00024020100d004101211b0c020b20101033221b0d010c090b200328028004211b201a2010460d00201b201a20101037221b450d080b20032010360284042003201b360280040b201b20176a200141106a2900003700002003201741086a221a36028804200141086a29030021072001290300210a024002402010201a6b410f4d0d00201021190c010b201a41106a2219201a490d06201041017422162019201620194b1b22194100480d060240024020100d00024020190d004101211b0c020b20191033221b450d090c010b20102019460d00201b201020191037221b450d080b20032019360284042003201b360280040b201b201a6a221a2007370008201a200a3700002003201741186a221736028804200141186a2d000021100240024020192017460d002019211a201721190c010b201941016a22172019490d062019410174221a2017201a20174b1b221a4100480d060240024020190d00410021190240201a0d004101211b0c020b201a1033221b450d090c010b2019201a460d00201b2019201a1037221b450d080b2003201a360284042003201b360280040b200141206a2101201b20196a20103a00002003201941016a221736028804201141606a22110d000b2003280284042119200d4220862005ad842017ad422086200328028004221bad84100202402019450d00201b10350b0240200328028403450d00200510350b20044101460d012000108d020c010b20034180046a200010ed022003350288044220862003280280042219ad8410070240200328028404450d00201910350b20044101470d0020001099020b200341b0056a24000f0b1044000b1045000b103e000b103c000bc20503027f017e047f230041d0006b2202240041b6fdc600ad4280808080800184100122032900002104200241086a200341086a290000370300200220043703002003103541b8a2c600ad4280808080d00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bf00204027f017e017f077e0240024020012802042202450d0020012802002203310000210420012002417f6a22053602042001200341016a3602002005450d012003310001210620012002417e6a22053602042001200341026a3602002005450d012003310002210720012002417d6a22053602042001200341036a3602002005450d012003310003210820012002417c6a22053602042001200341046a3602002005450d012003310004210920012002417b6a22053602042001200341056a3602002005450d012003310005210a20012002417a6a22053602042001200341066a3602002005450d012003310006210b2001200241796a22053602042001200341076a3602002005450d01200041003a00002003310007210c2001200241786a3602042001200341086a3602002000200c423886200b42308684200a422886842009422086842008421886842007421086842006420886842004843700010f0b200041013a00000f0b200041013a00000bb3270f037f017e037f057e037f017e037f027e017f027e017f017e027f047e047f230041900a6b220624002006200437034020062003370338200620053a004f024002400240024002400240024002400240024002402003200484500d0020012002460d0320012002412010a008450d03200641d0016a2002108e02200641e0016a20062802d001220720062802d8012208108f0220062903e001210942002104200642003703e001200641a8026a280200210a20062d00ac02210b2009420151220c0d01200641b0026a41386a4200370300200641b0026a41306a4200370300200641b0026a41286a4200370300200641d0026a4200370300200641b0026a41186a4200370300200641c0026a4200370300200641b8026a4200370300200642003703b002420021034200210d4200210e0c020b20004100360200200041106a4200370300200041086a42003703000c090b200641e0016a41386a290300210f200641e0016a41306a2903002110200641e0016a41206a290300210e200641e0016a41186a290300210d200641a0026a290300211120062903f001210320062903e8012104200641d0026a200641e0016a41286a290300370300200641b0026a41286a2010370300200641b0026a41306a200f370300200641c0026a200d3703002006200e3703c802200620113703e802200620043703b002200620033703b8020b200641b0026a41106a2105427f2004200d7c220d200d20045422122003200e7c2012ad7c220420035420042003511b22121b427f200420121b84500d01200641f0046a2001108e0220064180056a20062802f004221320062802f8042214108f022006290380052115420021032006420037038005200641c8056a280200211620062d00cc05211702400240201542015122180d00200641d0056a41306a4200370300200641d0056a41286a4200370300200641d0056a41206a4200370300200641d0056a41186a4200370300200641e0056a4200370300200641d8056a4200370300200642003703d005420021044200210e4200210d420021190c010b200641b8056a290300210f20064180056a41306a290300211020064180056a41206a290300210420064180056a41186a2903002103200641c0056a2903002119200629039005210d200629038805210e200641d0056a41206a20064180056a41286a290300370300200641d0056a41286a2010370300200641d0056a41306a200f370300200641e0056a2003370300200620043703e8052006200e3703d0052006200d3703d8050b200641386a41086a2903002210200420032006290338221156200420105620042010511b22121b211a2011200320121b210f0240024020062d004f4101470d00200641d0066a21122005211b20062903c002221c200f7c221d201c54221e200641c8026a290300221f201a7c201ead7c221c201f54201c201f511b0d010c040b200641c0066a2112200641b0026a211b20062903b002221c200f7c221d201c54221e200641b0026a41086a290300221f201a7c201ead7c221c201f54201c201f511b4101470d030b201241086a4108360200201241046a221841a7d6ca00360200201241026a41023a0000201241830c3b0100201829020022034280807c83210f200342088842ff018321042003a721182012280200211b410121120c030b02402005450d00200641e0076a2001108e02200641e0086a20062802e007220220062802e807108f0220064180096a290300420020062903e00842015122011b210e200641f8086a290300420020011b210d024020062802e407450d00200210350b20004100360200200041106a42002004200e7d2003200d54ad7d220e2003200d7d220d200356200e200456200e2004511b22011b370300200041086a4200200d20011b3703000c070b200620033703e006200620043703e806200620013602f003200641e0076a2001200641e0066a200641f0036a10f00220064180086a290300210320062903f8072104024020062903e0074201520d0020062903e807210d20064198096a200641e0076a41106a29030037030020064190096a200d370300200641e0086a41086a41003a0000200641e9086a2001290000370000200641f1086a200141086a290000370000200641f9086a200141106a29000037000020064181096a200141186a290000370000200641033a00e00841b0b4cc004100200641e0086a10d4010b200041106a2003370300200041086a2004370300200041003602000c060b200641e0066a41206a200541206a290300370300200641e0066a41186a200541186a290300370300200641e0066a41106a200541106a290300370300200641e0066a41086a200541086a290300370300200620052903003703e00641ea88c200ad4280808080b0018421034200211041838c1c211b0c020b201b201d370300201b201c370308200641d0056a41186a2004201a7d2003200f54ad7d37030020062003200f7d3703e00520064188066a41186a200641e0056a221241086a290300221c37030020064188066a41206a221b201241106a290300370300200641b0066a2220201241186a290300370300200641b8066a2221201241206a29030037030020062012290300221d370398062006200e370388062006200d370390062010201a7d21102011200f54ad211a427f200e20037c22032003200e542212200d20047c2012ad7c2203200d542003200d511b22121b427f200320121b8450211e02400240427f200e201d7c22032003200e542212200d201c7c2012ad7c2203200d542003200d511b22121b2204428080e983b1de16544100427f200320121b2203501b0d0020064188066a41106a29030021042021290300211c2020290300211d201b290300211f200629039006212220062903880621234201212420062903a00621250c010b02400240200420038450450d00420021240c010b42002124200641e0086a41186a22264200370300200641e0086a41106a22204200370300200641e0086a41086a221b4200370300200642003703e00841b6fdc600ad4280808080800184221c10012221290000211d200641800a6a41086a2212202141086a2900003703002006201d3703800a20211035201b2012290300370300200620062903800a3703e00841e489c200ad4280808080d00184221d10012221290000211f2012202141086a2900003703002006201f3703800a20211035202020062903800a221f370300200641e0096a41086a2227201b290300370300200641e0096a41106a2228201f370300200641e0096a41186a22292012290300370300200620062903e0083703e009200641206a200641e0096a412010d701200641206a41106a290300211f20062903282122200628022021212026420037030020204200370300201b4200370300200642003703e008201c10012226290000211c2012202641086a2900003703002006201c3703800a20261035201b2012290300370300200620062903800a3703e008201d10012226290000211c2012202641086a2900003703002006201c3703800a20261035202020062903800a221c3703002027201b2903003703002028201c37030020292012290300370300200620062903e0083703e00920064200201f420020211b221c20037d2022420020211b221d200454ad7d221f201d20047d2222201d56201f201c56201f201c511b22121b3703e80820064200202220121b3703e008200641e0096aad4280808080800484200641e0086aad4280808080800284100220064198096a200337030020064190096a2004370300201b41013a0000200641e9086a2001290000370000200641f1086a200141086a290000370000200641f9086a200141106a29000037000020064181096a200141186a290000370000200641033a00e00841b0b4cc004100200641e0086a10d4010b0b2010201a7d21102011200f7d2111201ead2103200641a8056a201f370300200641b0056a201d37030020064190056a2022370300200641b8056a201c37030020064198056a2004370300200620253703a005200620193703c005200620233703880542012104410021122006201741002015420151221b1b3a00cc05200620164100201b1b3602c80520062024420151221bad370380050240201b0d002014ad4220862013ad841007420021044200210f0c010b200620143602e408200620133602e00820064188056a200641e0086a10e7024200210f0b024020062802f404450d00201310350b024002402012450d0020044208862018ad42ff018384200f842103410121180c010b02400240201841ff017122120d0020044200510d0041032118200641e0076a21120c010b410021182012450d0120044200520d0141042118200641e0066a21120b201241086a20183a000041002118201241003a0000201241096a2001290000370000201241116a200141086a290000370000201241196a200141106a290000370000201241216a200141186a29000037000041b0b4cc004100201210d4010b024002402018450d0042002110410121120c010b41002112024020034201520d0020064198096a200d37030020064190096a200e37030041002112200641e0086a41086a41003a0000200641e9086a2001290000370000200641f1086a200141086a290000370000200641f9086a200141106a29000037000020064181096a200141186a290000370000200641033a00e00841b0b4cc004100200641e0086a10d4010b201121030b200641b0026a41086a290300210420062903b002210d20062903e802210e200641e0066a41206a2201200541206a290300370300200641e0066a41186a2218200541186a290300370300200641e0066a41106a2213200541106a290300370300200641e0066a41086a2216200541086a290300370300200620052903003703e0062012450d010b20034280807c83210d200342088842ff018321042003a7210c410121010c010b200641e0076a41186a2016290300220f370300200641e0076a41206a201329030037030020064188086a2205201829030037030020064190086a22122001290300370300200620062903e00622113703f0072006200d3703e007200620043703e80702400240427f200d20117c22112011200d5422012004200f7c2001ad7c220d200454200d2004511b22011b2204428080e983b1de16544100427f200d20011b220d501b0d00200641f0076a29030021042012290300210d2005290300210f20064180086a290300211120062903e807211a20062903e00721154201211c20062903f80721190c010b024002402004200d8450450d004200211c0c010b4200211c200641e0086a41186a22134200370300200641e0086a41106a22124200370300200641e0086a41086a22054200370300200642003703e00841b6fdc600ad4280808080800184220f100122182900002111200641800a6a41086a2201201841086a290000370300200620113703800a2018103520052001290300370300200620062903800a3703e00841e489c200ad4280808080d00184221110012218290000211a2001201841086a2900003703002006201a3703800a20181035201220062903800a221a370300200641e0096a41086a22162005290300370300200641e0096a41106a2217201a370300200641e0096a41186a22142001290300370300200620062903e0083703e009200641086a200641e0096a412010d701200641086a41106a290300211a2006290310211520062802082118201342003703002012420037030020054200370300200642003703e008200f10012213290000210f2001201341086a2900003703002006200f3703800a2013103520052001290300370300200620062903800a3703e008201110012213290000210f2001201341086a2900003703002006200f3703800a20131035201220062903800a220f370300201620052903003703002017200f37030020142001290300370300200620062903e0083703e00920064200201a420020181b220f200d7d2015420020181b2211200454ad7d221a201120047d2215201156201a200f56201a200f511b22011b3703e80820064200201520011b3703e008200641e0096aad4280808080800484200641e0086aad4280808080800284100220064198096a200d37030020064190096a2004370300200541013a0000200641e9086a2002290000370000200641f1086a200241086a290000370000200641f9086a200241106a29000037000020064181096a200241186a290000370000200641033a00e00841b0b4cc004100200641e0086a10d4010b0b20064188026a201137030020064190026a200f370300200641f0016a201a37030020064198026a200d370300200641f8016a200437030020062019370380022006200e3703a002200620153703e80142012104410021012006200b4100200942015122051b3a00ac022006200a410020051b3602a8022006201c4201512205ad3703e0010240024020050d002008ad4220862007ad841007420021040c010b200620083602e408200620073602e008200641e8016a200641e0086a10e7020b4200210d0b024020062802d401450d00200710350b024020010d00024002400240200c41ff017122010d0020044200510d0041032105200641f0036a21010c010b2001450d0120044200520d0141042105200641f0026a21010b200141086a20053a0000200141003a0000200141096a2002290000370000200141116a200241086a290000370000200141196a200241106a290000370000200141216a200241186a29000037000041b0b4cc004100200110d4010b200041106a2010370300200041086a2003370300200041003602000c010b2000201b360204200041086a2004420886200cad42ff018384200d84370200200041013602000b200641900a6a24000bc50f07037f027e027f0c7e037f047e047f230041d0036b2204240020032802002105200441206a2001108e02200441a0016a2004280220220320042802282206108f0220042903a001210742002108200442003703a001200441e8016a280200210920042d00ec01210a0240024020074201510d00200441306a41306a4200370300200441306a41286a4200370300200441306a41206a4200370300200441306a41186a4200370300200441c0006a4200370300200441386a4200370300200442003703304200210b4200210c4200210d4200210e0c010b200441d8016a290300210f200441a0016a41306a2903002110200441a0016a41206a290300210b200441a0016a41186a2903002108200441e0016a290300210e20042903b001210d20042903a801210c200441306a41206a200441a0016a41286a290300370300200441306a41286a2010370300200441306a41306a200f370300200441c0006a20083703002004200b3703482004200c3703302004200d3703380b200441306a41186a200b200241086a2903002211200b20082002290300221256200b201156200b2011511b22021b22137d20082012200820021b221054ad7d22143703002004200820107d22153703402004427f200d20137c200c20107c2216200c542202ad7c220f2002200f200d54200f200d511b22021b220f3703382004427f201620021b2216370330200441e8006a41186a2014370300200441e8006a41206a2217200441306a41206a290300370300200441e8006a41286a2218200441306a41286a290300370300200441e8006a41306a2219200441306a41306a2903003703002004200f3703702004201637036820042015370378427f200d200b7c200c20087c220b200c542202ad7c220820022008200d542008200d511b22021b210c427f200b20021b211a02400240427f201620157c220d200d2016542202200f20147c2002ad7c220d200f54200d200f511b22021b2208428080e983b1de16544100427f200d20021b220b501b0d00200441f8006a29030021082019290300210b20182903002114201729030021152004290370211b2004290368211c4201210d200429038001211d0c010b024002402008200b8450450d004200210d0c010b4200210d200441a0026a41186a221e4200370300200441a0026a41106a22184200370300200441a0026a41086a22174200370300200442003703a00241b6fdc600ad42808080808001842214100122192900002115200441c0036a41086a2202201941086a290000370300200420153703c0032019103520172002290300370300200420042903c0033703a00241e489c200ad4280808080d00184221510012219290000211b2002201941086a2900003703002004201b3703c00320191035201820042903c003221b370300200441a0036a41086a221f2017290300370300200441a0036a41106a2220201b370300200441a0036a41186a22212002290300370300200420042903a0023703a003200441086a200441a0036a412010d701200441086a41106a290300211b2004290310211c20042802082119201e42003703002018420037030020174200370300200442003703a00220141001221e29000021142002201e41086a290000370300200420143703c003201e103520172002290300370300200420042903c0033703a00220151001221e29000021142002201e41086a290000370300200420143703c003201e1035201820042903c0032214370300201f20172903003703002020201437030020212002290300370300200420042903a0023703a00320044200201b420020191b2214200b7d201c420020191b2215200854ad7d221b201520087d221c201556201b201456201b2014511b22021b3703a80220044200201c20021b3703a002200441a0036aad4280808080800484200441a0026aad42808080808002841002200441d8026a200b370300200441d0026a2008370300201741013a0000200441a9026a2005290000370000200441b1026a200541086a290000370000200441b9026a200541106a290000370000200441c1026a200541186a290000370000200441033a00a00241b0b4cc004100200441a0026a10d4010b0b20122010542102201a200c84210c200441c8016a2015370300200441d0016a2014370300200441b0016a201b370300200441d8016a200b370300200441b8016a20083703002004201d3703c0012004200e3703e0012004201c3703a8012004200a4100200742015122051b3a00ec0120042009410020051b3602e8012004200d4201512205ad3703a0010240024020050d002006ad4220862003ad8410070c010b200420063602a402200420033602a002200441a8016a200441a0026a10e7020b201120137d21082002ad210b200c50210202402004280224450d00200310350b2008200b7d21082002ad210b201220107d210c200d420152210202400240024020074201510d0020020d0041032103200441a0026a21020c010b20074201522002410173720d0141042103200441a0016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b2000200c370318200020163703082000200b370300200041206a2008370300200041106a200f370300200441d0036a24000b130020004104360204200041f89cc2003602000b3400200041b6fdc60036020420004100360200200041146a4104360200200041106a41c4b6c200360200200041086a42083702000b830101017f0240411010332202450d00200242003700082002420037000020024110412010372202450d0020024200370010200241186a42003700002002412041c00010372202450d002002420037003020024200370020200042c0808080800837020420002002360200200241386a4200370000200241286a42003700000f0b103c000b130020004101360204200041f4bec2003602000b130020004106360204200041ecbfc2003602000b3400200041a0e4cb0036020420004100360200200041146a4105360200200041106a41d8d8c200360200200041086a42103702000b3a01017f230041206b22022400200241186a41003602002002420037030820024200370300200242013703102000200210f802200241206a24000bad0301077f230041106b220224000240200141186a28020022034105744114722204417f4c0d000240200410332205450d00200520012903003700002005200141086a2903003700082002411036020820022004360204200220053602002001280210210620032002107702402003450d0020034105742107200228020021082002280204210420022802082103034020062101024002402004200322056b4120490d00200541206a21030c010b024002400240200541206a22032005490d00200441017422062003200620034b1b22064100480d000240024020040d00024020060d00410121080c020b2006103321080c040b20042006470d020b200621040c030b103e000b200820042006103721080b2006210420080d00103c000b200141206a2106200820056a22052001290000370000200541186a200141186a290000370000200541106a200141106a290000370000200541086a200141086a290000370000200741606a22070d000b2002200436020420022003360208200220083602000b20002002290300370200200041086a200241086a280200360200200241106a24000f0b1045000b1044000b130020004106360204200041d8e0c2003602000b3501017f02404108103322020d001045000b20004288808080800137020420002002360200200242f0d0c9abc6add9b1f4003700000b2e01017f02404104103322020d001045000b20004284808080c0003702042000200236020020024180a70c3600000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241073600000b2c01017f02404104103322020d001045000b20004284808080c000370204200020023602002002410d3600000b8709010f7f23004190036b2204240002400240200141046a28020022052f01062206410b490d002001280208210720012802002108200441306a410041e002109f081a200441286a22064100360200200441206a22094200370300200441186a220a4200370300200441106a220b4200370300200441086a220c42003703002004420037030002404194031033220d450d00200d41003b0106200d4100360200200d41086a200441306a41e002109d08210e200d4190036a2006280200360200200d4188036a2009290300370200200d4180036a200a290300370200200d41f8026a200b290300370200200d41f0026a200c290300370200200d20042903003702e802200441306a41086a2209200541d0016a290000370300200441306a41106a220f200541d8016a290000370300200441306a41186a2210200541e0016a290000370300200420052900c8013703302005280280032111200e200541e8016a20052f010641796a2206410574109d08210e200d41e8026a20054184036a2006410274109d082112200541063b0106200d20063b0106200a2010290300370300200b200f290300370300200c20092903003703002004200429033037030002400240200128020c22014107490d00200d41066a210a200e2001417a6a220c4105746a200e200141796a22014105746a220b200641ffff037120016b410574109e081a200b41186a200241186a290000370000200b41106a200241106a290000370000200b41086a200241086a290000370000200b20022900003700002012200c4102746a2106201220014102746a21020c010b200541086a220a200141016a220b4105746a200a20014105746a2206200541066a220a2f010020016b410574109e081a200641186a200241186a290000370000200641106a200241106a290000370000200641086a200241086a29000037000020062002290000370000200541e8026a220620014102746a21022006200b4102746a2106200121010b20062002200a2f010020016b410274109e081a20022003360200200041013a00002000200236023c200041386a4100360200200041346a200d360200200041306a20113602002000412c6a2007360000200041286a2005360000200041246a200836000020002004290300370001200041096a200441086a290300370000200041116a200441106a290300370000200041196a200441186a290300370000200a200a2f010041016a3b01000c020b103c000b200541086a220a200128020c220d41016a220b4105746a200a200d4105746a220a2006200d6b410574109e081a200a41186a200241186a290000370000200a41106a200241106a290000370000200a41086a200241086a290000370000200a2002290000370000200541e8026a2202200b4102746a2002200d4102746a220220052f0106200d6b410274109e081a20022003360200200520052f010641016a3b0106200441306a410b6a200141086a280000360000200041003a00002000200236023c200041106a200d3600002004200129000037003320002004290030370001200041086a200441376a2900003700000b20044190036a24000be60b020f7f047e23004180046b220624000240024020012802002207417f6a2005470d000240024002400240200141046a28020022082f01062209410b490d002001280208210a200641c0006a410272410041be03109f081a41c4031033220b450d05200b4100360200200b41046a200641c0006a41c003109d081a200641c0006a41186a220c200841e0016a290000370300200641c0006a41106a220d200841d8016a290000370300200641c0006a41086a220e200841d0016a290000370300200620082900c801370340200828028003210f200b41086a200841e8016a20082f0106221041796a2205410574109d082111200b41e8026a20084184036a2005410274109d082112200b4194036a200841b0036a2010417a6a2213410274109d082114200841063b0106200b20053b010602402013450d00410021052014211003402010280200220920053b01042009200b360200201041046a21102013200541016a2205470d000b0b200641206a41186a200c2903002215370300200641206a41106a200d2903002216370300200641206a41086a200e2903002217370300200620062903402218370320200641186a2015370300200641106a2016370300200641086a201737030020062018370300200128020c22054107490d0120112005417a6a22014105746a2011200541796a22104105746a2209200b2f010620106b410574109e081a200941186a200241186a290000370000200941106a200241106a290000370000200941086a200241086a290000370000200920022900003700002012200141027422096a201220104102746a2213200b2f010620106b410274109e081a20132003360200200b200b2f010641016a22133b01062005410274220220146a416c6a201420096a2205201341ffff037120016b410274109e081a200520043602002001200b2f010622134b0d022002200b6a41fc026a2105034020052802002209201041016a22103b01042009200b360200200541046a210520102013490d000c030b0b200841086a2205200128020c221341016a22104105746a200520134105746a2205200920136b410574109e081a200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a29000037000020052002290000370000200841e8026a22092010410274220b6a2009201341027422056a220920082f010620136b410274109e081a20092003360200200820082f010641016a22093b0106200520084194036a22026a41086a2002200b6a220b200941ffff037120106b410274109e081a200b20043602000240201020082f0106220b4b0d00200820056a4198036a210520132110034020052802002209201041016a22103b010420092008360200200541046a21052010200b490d000b0b200041003a0000200041046a2001290200370200200041106a20133602002000410c6a200141086a2802003602000c020b200841086a2210200541016a22094105746a201020054105746a221020082f010620056b410574109e081a201041186a200241186a290000370000201041106a200241106a290000370000201041086a200241086a29000037000020102002290000370000200841e8026a2213200941027422016a2013200541027422106a221320082f010620056b410274109e081a20132003360200200820082f010641016a22133b0106201020084194036a22026a41086a200220016a2201201341ffff037120096b410274109e081a20012004360200200520082f010622134f0d00200820106a4198036a2110034020102802002209200541016a22053b010420092008360200201041046a211020132005470d000b0b20002006290300370001200041013a00002000412c6a200a360200200041286a2008360200200041246a2007360200200041386a2007360200200041346a200b360200200041306a200f360200200041096a200641086a290300370000200041116a200641106a290300370000200041196a200641186a2903003700000b20064180046a24000f0b41d684cc00413541c086cc00103f000b103c000bb71a01197f230041d0116b2202240020002802102203200328020041016a360200200028020c2104200028020821052000280200210620002802042103200241206a41186a22072000412c6a290000370300200241206a41106a2208200041246a290000370300200241206a41086a22092000411c6a29000037030020022000290014370320200241a0026a200141e000109d081a024002400240024002400240024020032f01062201410b490d00200241b0036a410041e002109f081a20024198066a410041a008109f081a41880b1033220a450d04200a41003b0106200a4100360200200a41086a200241b0036a41e002109d082101200a41e8026a20024198066a41a008109d0821072002200341c8016a2f00003b01ac032002200341ca016a2d00003a00ae032002200341db016a290000370398032002200341e0016a29000037009d03200341cb016a280000210b200341cf016a280000210c200341d3016a280000210d200341d7016a280000210e20024198066a200341a8076a41e000109d081a2001200341e8016a20032f010641796a2200410574109d082101200720034188086a200041e0006c109d082107200341063b0106200a20003b0106200220022f01ac033b019403200220022d00ae033a0096032002200229039803370380032002200229009d0337008503200241b0036a20024198066a41e000109d081a0240024020044107490d00200441057420016a41c07e6a2001200441796a22084105746a2201200041ffff037120086b410574109e081a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200441e0006c20076a220041c07b6a200041e07a6a220f200a41066a22002f010020086b41e0006c109e081a200f200241a0026a41e000109d081a0c010b200341086a20044105746a220141206a2001200341066a22002f010020046b410574109e081a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200341e8026a200441e0006c6a220f41e0006a200f20002f010020046b41e0006c109e081a200f200241a0026a41e000109d081a0b20024188026a41026a220420022d0096033a0000200020002f010041016a3b0100200220022f0194033b01880220022002290380033703800120022002290085033700850120024190016a200241b0036a41e000109d081a2002411c6a41026a221020042d00003a0000200220022f0188023b011c2002200229038001370308200220022900850137000d200241206a20024190016a41e000109d081a200328020022070d01410021030c020b200320044105746a220041286a200041086a2206200120046b410574109e081a200041206a2007290300370000200041186a2008290300370000200041106a2009290300370000200620022903203700002003200441e0006c6a220041c8036a200041e8026a220f20032f010620046b41e0006c109e081a200f200241a0026a41e000109d081a200320032f010641016a3b01060c020b20032f0104211120024198066a410272211241002103024003402002419c026a41026a221320102d00003a0000200220022f011c3b019c0220022002290308370388022002200229000d37008d02200241a0026a200241206a41e000109d081a20062003470d01201141ffff0371210802400240024020072f01062203410b490d002012410041b20b109f081a41b80b10332201450d0720014100360200200141046a20024198066a41b40b109d081a200220072f00c8013b01ac032002200741ca016a2d00003a00ae032002200741db016a290000370398032002200741e0016a29000037009d03200741cb016a2800002114200741cf016a2800002115200741d3016a2800002116200741d7016a280000211720024198066a200741a8076a41e000109d081a200141086a200741e8016a20072f0106220041796a2203410574109d082118200141e8026a20074188086a200341e0006c109d082119200141880b6a200741a40b6a2000417a6a2209410274109d08211a200741063b0106200120033b010602402009450d0041002103201a210003402000280200220420033b010420042001360200200041046a21002009200341016a2203470d000b0b200241b0036a20024198066a41e000109d081a200220022d00ae0322033a009603200220022f01ac0322003b0194032002200229009d033700850320022002290398033703800320024194066a41026a220920033a0000200220003b01940620022002290380033703800120022002290085033700850120024198066a200241b0036a41e000109d081a201141ffff037122004107490d0120182008417a6a22044105746a2018200841796a22034105746a220020012f010620036b410574109e081a200041186a200229008d023700002000200e36000f2000200d36000b2000200c3600072000200b360003200041026a20132d00003a0000200020022f019c023b00002000200229038802370013200841e0006c20196a220041c07b6a200041e07a6a220020012f010620036b41e0006c109e081a2000200241a0026a41e000109d081a200120012f010641016a22003b01062008410274220b201a6a416c6a201a20044102746a2211200041ffff0371220820046b410274109e081a2011200a36020020082004490d022001200b6a41f00a6a2100034020002802002204200341016a22033b010420042001360200200041046a210020032008490d000c030b0b200741086a2200200841016a22044105746a200020084105746a2200200320086b2201410574109e081a2000200e36000f2000200d36000b2000200c3600072000200b360003200041026a2002419c026a41026a2d00003a0000200020022f019c023b00002000200229038802370013200041186a200229008d023700002007200841e0006c6a220041c8036a200041e8026a2200200141e0006c109e081a2000200241a0026a41e000109d081a2007200341016a22033b01062008410274200741880b6a22006a41086a200020044102746a2200200341ffff037120046b410274109e081a2000200a360200201141ffff037120072f010622034f0d05200a20043b0104200a2007360200200420034f0d052003417f6a210120072004417f6a22034102746a41900b6a2100034020002802002204200341026a3b010420042007360200200041046a21002001200341016a2203470d000c060b0b200741086a2203200841016a22044105746a200320084105746a220320072f0106221120086b221a410574109e081a2003200e36000f2003200d36000b2003200c3600072003200b360003200341026a20132d00003a0000200320022f019c023b00002003200229038802370013200341186a200229008d02370000200741e8026a200841e0006c6a220341e0006a2003201a41e0006c109e081a2003200241a0026a41e000109d081a2007201141016a22033b01062008410274221a200741880b6a22116a41086a201120044102746a2211200341ffff037120046b410274109e081a2011200a360200200020072f010622044f0d002007201a6a418c0b6a2103034020032802002200200841016a22083b010420002007360200200341046a210320042008470d000b0b200641016a210320024184026a41026a220020092d00003a0000200220022f0194063b01840220022002290380013703f00120022002290085013700f50120024190016a20024198066a41e000109d081a201020002d00003a0000200220022f0184023b011c200220022903f001370308200220022900f50137000d200241206a20024190016a41e000109d081a0240200728020022000d002014210b2017210e2016210d2015210c2001210a0c030b20072f010421112014210b2017210e2016210d2015210c200021072001210a200321060c000b0b41d684cc00413541c086cc00103f000b20024198066a410272410041b20b109f081a41b80b10332200450d0120004100360200200041046a20024198066a41b40b109d081a2000200528020022043602880b2005200036020020052005280204220141016a360204200441003b010420042000360200200241a0026a41026a2002411c6a41026a2d00003a0000200220022f011c3b01a002200220022903083703b0032002200229000d3700b50320024198066a200241206a41e000109d081a20012003470d0220002f01062204410a4b0d03200020044105746a2203410a6a200241a0026a41026a2d00003a0000200341086a20022f01a0023b0000200341176a200e360000200341136a200d3600002003410f6a200c3600002003410b6a200b3600002003411b6a20022903b003370000200341206a20022900b5033700002000200441e0006c6a41e8026a20024198066a41e000109d081a2000200441016a22034102746a41880b6a200a360200200020033b0106200a20033b0104200a20003602000b200241d0116a2400200f0f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000bfb0203057f017e027f0240024020002802202201450d00034020002001417f6a36022020002802042201450d0220002802082102200028020021030240200028020c220420012f0106490d00034002400240200128020022050d002002ad2106410021050c010b200341016a210320013301044220862002ad8421060b200110352006a72102200521012006422088a7220420052f01064f0d000b200521010b200441016a210720012004410c6c6a220541ec026a2802002108200541e8026a280200210402402003450d00200120074102746a41ec036a2802002101410021072003417f6a2205450d00034020012802ec0321012005417f6a22050d000b0b2000200736020c20002002360208200020013602042000410036020002402004450d002008450d00200410350b200028022022010d000b0b024020002802042205450d0020052802002101200510352001450d00034020012802002105200110352005210120050d000b0b0f0b41958dcc00412b41c08dcc00103f000bc91305027f017e067f037e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2105200028020821062000280200210320002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024002400240024020002f01062201410b490d00200241d0026a410272410041da00109f081a200241386a4100418401109f081a41e40110332208450d0420084100360200200841046a200241d0026a41dc00109d081a200841e0006a200241386a418401109d082107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413f6a2d0000210a200041386a350000210b2000413c6a330000210c2000413e6a310000210d200841086a200041c0006a20002f010641796a2201410374109d08210e2007200041b4016a2001410c6c109d082107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200b200c200d4210868442208684210b0240024020054107490d002005410374200e6a41506a200e200541796a22094103746a220e200141ffff037120096b410374109e081a200e20043700002005410c6c20076a220541b87f6a200541ac7f6a2205200841066a22012f010020096b410c6c109e081a200541086a200241f0016a41086a280200360200200520022903f0013702000c010b200041086a20054103746a220741086a2007200041066a22012f010020056b410374109e081a20072004370000200041e0006a2005410c6c6a2207410c6a200720012f010020056b410c6c109e081a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002205360200200241086a221120053602002002200a3a0017200220022903d00222043703282002200b3e02102002200b4230883c00162002200b4220883d01142002200437030020022903102104200028020022090d01410021120c020b200020054103746a220341106a200341086a2203200120056b410374109e081a2003200437000020002005410c6c6a220341ec006a200341e0006a220120002f010620056b410c6c109e081a200341e8006a2007280200360200200120022903f001370200200020002f010641016a3b01060c020b20002f01042113200241d0026a41027221144100210002400340200220093602242002200341016a2212360220200f20112802003602002002200229030037032820032000470d01201341ffff0371210702400240024020092f01062203410b490d002014410041da00109f081a200241f0016a200241d0026a41dc00109d081a200241386a410041b401109f081a41940210332201450d0720014100360200200141046a200241f0016a41dc00109d081a200141e0006a200241386a41b401109d0821002009290038210b200241386a41086a220e200941b0016a280200360200200220092902a801370338200141086a200941c0006a20092f0106220541796a2203410374109d0821152000200941b4016a2003410c6c109d082116200141e4016a20094180026a2005417a6a220a410274109d082117200941063b0106200120033b01060240200a450d00410021032017210003402000280200220520033b010420052001360200200041046a2100200a200341016a2203470d000b0b2010200e280200220336020020022002290338220c3703d002200e20033602002002200c370338201341ffff037122004107490d0120152007417a6a22004103746a2015200741796a22034103746a220520012f010620036b410374109e081a200520043700002007410c6c20166a220541b87f6a200541ac7f6a220520012f0106220a20036b410c6c109e081a200541086a200f280200360200200520022903283702002001200a41016a22053b01062007410274221320176a416c6a201720004102746a220a200541ffff0371220720006b410274109e081a200a200836020020072000490d02200120136a41cc016a2100034020002802002205200341016a22033b010420052001360200200041046a210020032007490d000c030b0b200941086a2205200741016a22004103746a200520074103746a2205200320076b2201410374109e081a2005200437000020092007410c6c6a220541ec006a200541e0006a220a2001410c6c109e081a200541e8006a200241286a41086a280200360200200a20022903283702002009200341016a22033b01062007410274200941e4016a22056a41086a200520004102746a2205200341ffff0371220120006b410274109e081a20052008360200201341ffff037120014f0d0520092000417f6a22034102746a41e8016a2100034020002802002205200341016a22033b010420052009360200200041046a210020032001490d000c060b0b200941086a2203200741016a220a4103746a200320074103746a220320092f0106220520076b2213410374109e081a20032004370000200941e0006a2007410c6c6a2203410c6a20032013410c6c109e081a200341086a200f280200360200200320022903283702002009200541016a22033b010620074102742217200941e4016a22056a41086a2005200a4102746a2213200341ffff03712205200a6b410274109e081a20132008360200200020054f0d00200920176a41e8016a2103034020032802002200200741016a22073b010420002009360200200341046a210320052007470d000b0b200241106a41086a200e280200220336020020112003360200200220022903382204370310200220043703000240200928020022030d0020012108200b21040c030b20092f0104211320032109200b21042001210820122100201221030c000b0b41d684cc00413541c086cc00103f000b200241d0026a410272410041da00109f081a200241f0016a200241d0026a41dc00109d081a200241386a410041b401109f081a41940210332203450d0120034100360200200341046a200241f0016a41dc00109d081a200341e0006a200241386a41b401109d0821052003200628020022003602e4012006200336020020062006280204220141016a360204200041003b010420002003360200200241386a41086a200241086a2802003602002002200229030037033820012012470d0220032f01062200410a4b0d0320052000410c6c6a22052002290338370200200320004103746a41086a2004370000200541086a200241386a41086a2802003602002003200041016a22004102746a41e4016a2008360200200320003b0106200820003b0104200820033602000b200241b0036a24000f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000bfa20021b7f017e23004180076b22042400200441e0006a41186a200241186a290000370300200441e0006a41106a200241106a290000370300200441e0006a41086a200241086a290000370300200420022900003703600240024002400240024020012802002205450d00200128020421060c010b41002106200441e8026a410041e002109f081a200441c0016a4100418401109f081a41ec0310332205450d01200541003b010620054100360200200541086a200441e8026a41e002109d081a200541e8026a200441c0016a418401109d081a20014100360204200120053602000b200420013602c801200420053602c401200420063602c00102400240024002400340200541086a2107200541066a210820052f0106220941057421024100210a024002400240024003402002450d010240200441e0006a2007412010a008220b0d00410021022006210c0c030b200241606a2102200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21090b20060d01410121024100210c2009210a0b200441e8026a41106a200a360200200441e8026a410c6a2001360200200441e8026a41086a22072005360200200420013602c801200420053602c401200420063602c0012004200c3602ec02200420023602e80202402002450d00200441086a41186a2207200441e0006a41186a2202290300370300200441086a41106a220b200441e0006a41106a2206290300370300200441086a41086a2209200441e0006a41086a220d290300370300200420042903603703082001200128020841016a360208200220072903003703002006200b290300370300200d200929030037030020042004290308370360200441d8026a41086a200341086a280200360200200420032902003703d80220082f0100220b410b490d02200441e8026a410041e002109f081a200441c0016a4100418401109f081a41ec0310332203450d08200341003b010620034100360200200341086a200441e8026a41e002109d082107200341e8026a200441c0016a418401109d08210b200441e8026a41086a2206200541b8036a2802003602002004200541db016a2900003703a8012004200541e0016a2900003700ad01200420052902b0033703e8022004200541c8016a2f00003b01bc012004200541ca016a2d00003a00be01200541cb016a280000210e200541cf016a280000210f200541d3016a2800002110200541d7016a28000021112007200541e8016a20052f010641796a2202410574109d082107200b200541bc036a2002410c6c109d08210b200541063b0106200320023b0106200420042f01bc013b01a401200420042d00be013a00a601200420042903a8013703c001200420042900ad013700c501200441286a41086a2006280200360200200420042903e80237032802400240200a4107490d00200a41057420076a41c07e6a2007200a41796a22064105746a2207200241ffff037120066b410574109e081a200741186a200441e0006a41186a290300370000200741106a200441e0006a41106a290300370000200741086a200441e0006a41086a29030037000020072004290360370000200a410c6c200b6a220241b87f6a200241ac7f6a2202200341066a22082f010020066b410c6c109e081a200241086a200441d8026a41086a280200360200200220042903d8023702000c010b200541086a200a4105746a220241206a200220082f0100200a6b410574109e081a200241186a200441e0006a41186a290300370000200241106a200441e0006a41106a290300370000200241086a200441e0006a41086a29030037000020022004290360370000200541e8026a200a410c6c6a2202410c6a200220082f0100200a6b410c6c109e081a200241086a200441d8026a41086a280200360200200220042903d8023702000b200820082f010041016a3b010020044198016a41026a220220042d00a6013a0000200441c8026a41086a2212200441286a41086a280200360200200420042f01a4013b019801200420042903c001370350200420042900c501370055200420042903283703c8022004413c6a41026a221320022d00003a0000200420042f0198013b013c2004200429005537002d20042004290350370328200441c0006a41086a22142012280200360200200420042903c8023703400240200528020022060d00410021020c060b20052f01042108200441e8026a410272211541002102034020044194016a41026a221620132d00003a0000200420042f013c3b019401200420042903283703602004200429002d37006520044198016a41086a221720142802003602002004200429034037039801200c2002470d05200841ffff0371210502400240024020062f01062202410b490d0020154100419604109f081a419c041033220b450d0c200b4100360200200b41046a200441e8026a419804109d081a2004200641c8016a2f00003b01bc012004200641ca016a2d00003a00be012004200641db016a2900003703a8012004200641e0016a2900003700ad01200641cb016a2800002118200641cf016a2800002119200641d3016a280000211a200641d7016a280000211b200441e8026a41086a221c200641b8036a280200360200200420062902b0033703e802200b41086a200641e8016a20062f0106220741796a2202410574109d08211d200b41e8026a200641bc036a2002410c6c109d08211e200b41ec036a20064188046a2007417a6a2209410274109d08210d200641063b0106200b20023b010602402009450d0041002102200d210703402007280200220a20023b0104200a200b360200200741046a21072009200241016a2202470d000b0b200441d8026a41086a2202201c280200360200200420042d00be0122073a00a601200420042f01bc01220a3b01a401200420042903a8013703c001200420042900ad013700c501200420042903e8023703d802200441c4026a41026a220920073a00002004200a3b01c402200420042903c0013703e802200420042900c5013700ed0220122002280200360200200420042903d8023703c802200841ffff037122074107490d01201d2005417a6a220a4105746a201d200541796a22024105746a2207200b2f010620026b410574109e081a200741186a20042900653700002007201136000f2007201036000b2007200f3600072007200e360003200741026a20162d00003a0000200720042f0194013b0000200720042903603700132005410c6c201e6a220741b87f6a200741ac7f6a2207200b2f0106220820026b410c6c109e081a200741086a20172802003602002007200429039801370200200b200841016a22073b01062005410274220e200d6a416c6a200d200a4102746a2208200741ffff03712205200a6b410274109e081a200820033602002005200a490d02200b200e6a41d4036a210703402007280200220a200241016a22023b0104200a200b360200200741046a210720022005490d000c030b0b200641086a2207200541016a220a4105746a200720054105746a2207200220056b410574109e081a200741186a20042900653700002007201136000f2007201036000b2007200f3600072007200e360003200741026a20044194016a41026a2d00003a0000200720042f0194013b00002007200429036037001320062005410c6c6a220241f4026a200241e8026a220720062f0106220b20056b410c6c109e081a200241f0026a20044198016a41086a28020036020020072004290398013702002006200b41016a22023b01062005410274200641ec036a22076a41086a2007200a4102746a2207200241ffff0371220b200a6b410274109e081a20072003360200200841ffff0371200b4f0d092006200a417f6a22024102746a41f0036a210703402007280200220a200241016a22023b0104200a2006360200200741046a21072002200b490d000c0a0b0b200641086a2202200541016a22084105746a200220054105746a220220062f010620056b410574109e081a200241186a20042900653700002002201136000f2002201036000b2002200f3600072002200e360003200241026a20162d00003a0000200220042f0194013b000020022004290360370013200641e8026a2005410c6c6a2202410c6a200220062f0106220a20056b410c6c109e081a200241086a201728020036020020022004290398013702002006200a41016a22023b01062005410274220e200641ec036a220a6a41086a200a20084102746a220d200241ffff0371220a20086b410274109e081a200d20033602002007200a4f0d002006200e6a41f0036a2102034020022802002207200541016a22053b010420072006360200200241046a2102200a2005470d000b0b200c41016a210220044190016a41026a220720092d00003a000020044180016a41086a220a2012280200360200200420042f01c40222053b019001200420042903e802370350200420042900ed02370055200420042903c80237038001201320072d00003a0000200420053b013c2004200429005537002d200420042903503703282014200a28020036020020042004290380013703400240200628020022070d002018210e201b2111201a21102019210f200b21030c070b20062f010421082018210e201b2111201a21102019210f20072106200b21032002210c0c000b0b20072005200a410c6c6a220241f0026a220a2802003602002004200241e8026a22022902003703e80220022003290200370200200a200341086a280200360200200441c0016a41086a20072802002202360200200420042903e802221f3703c0012000410c6a20023602002000201f370204200041013602000c060b2006417f6a2106200520094102746a41ec036a28020021050c010b0b2005200a4105746a220741286a200741086a2206200b200a6b410574109e081a200741206a2002290300370000200741186a200441e0006a41106a290300370000200741106a200441e0006a41086a290300370000200620042903603700002005200a410c6c6a220241f4026a200241e8026a220720052f0106200a6b410c6c109e081a200241f0026a200441d8026a41086a280200360200200720042903d802370200200520052f010641016a3b01060c020b41d684cc00413541c086cc00103f000b200441e8026a4102724100419604109f081a419c0410332207450d0220074100360200200741046a200441e8026a419804109d081a20072001280200220a3602ec032001200736020020012001280204220b41016a360204200a41003b0104200a2007360200200441e0006a41026a2004413c6a41026a2d00003a0000200420042f013c3b0160200420042903283703e8022004200429002d3700ed02200441c0016a41086a200441c0006a41086a280200360200200420042903403703c001200b2002470d0320072f0106220a410a4b0d042007200a4105746a2202410a6a200441e0006a41026a2d00003a0000200241086a20042f01603b0000200241176a2011360000200241136a20103600002002410f6a200f3600002002410b6a200e3600002002411b6a20042903e802370000200241206a20042900ed023700002007200a410c6c6a220241f0026a200441c0016a41086a280200360200200241e8026a20042903c0013702002007200a41016a22024102746a41ec036a2003360200200720023b0106200320023b0104200320073602000b200041003602000b20044180076a24000f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000bf70c01087f230041c0046b22032400200341206a41186a200141186a290000370300200341206a41106a200141106a290000370300200341206a41086a200141086a290000370300200320012900003703200240024002400240024020002802002204450d00200028020421050c010b4100210520034180016a410041e002109f081a200341f8006a22014100360200200341f0006a22064200370300200341d0006a41186a4200370300200341d0006a41106a4200370300200341d0006a41086a42003703002003420037035041940310332204450d01200441003b010620044100360200200441086a20034180016a41e002109d081a20044190036a200128020036020020044188036a200629030037020020044180036a200341e8006a290300370200200441f8026a200341e0006a290300370200200441f0026a200341d0006a41086a290300370200200420032903503702e80220004100360204200020043602000b2003200036025820032004360254200320053602500240034020042f01062207410574210841002101410021060240024002400240034020082001460d010240200341206a200420016a41086a412010a00822090d0041002101200521090c030b200141206a2101200641016a21062009417f4a0d000b2006417f6a21070b20050d014101210141002109200721060b20034180016a41106a20063602002003418c016a200036020020034180016a41086a20043602002003200036025820032004360254200320053602502003200936028401200320013602800102402001450d00200341186a2201200341206a41186a2207290300370300200341106a2208200341206a41106a290300370300200341086a2205200341206a41086a290300370300200320032903203703002000200028020841016a3602082003200636024c200320003602482003200436024420032009360240200341d0006a41186a2001290300370300200341d0006a41106a2008290300370300200341d0006a41086a20052903003703002003200329030037035020034180016a200341c0006a200341d0006a200210fe0220032d0080014101470d04200341206a41086a220520034189016a290000370300200341206a41106a220020034191016a290000370300200720034199016a2900003703002003200329008101370320200341ac016a2802002106200341b8016a2802002108200341b4016a2802002109200341b0016a2802002104200341a8016a28020022012802002207450d0220012f01042102200341a4016a280200210a20034180016a410172210103402003200241ffff037136024c20032006360248200320073602442003200a41016a360240200341d0006a41186a200341206a41186a2206290300370300200341d0006a41106a2000290300370300200341d0006a41086a20052903003703002003200329032037035020034180016a200341c0006a200341d0006a20042009200810ff0220032d0080014101470d052005200141086a2900003703002000200141106a2900003703002006200141186a2900003703002003200129000037032020032802ac01210620032802b801210820032802b401210920032802b001210420032802a80122022802002207450d0320022f0104210220032802a401210a0c000b0b200420064102746a41e8026a20023602000c030b2005417f6a2105200420074102746a4194036a28020021040c010b0b20034180016a410272410041be03109f081a41c40310332201450d0120014100360200200141046a20034180016a41c003109d081a200120062802002205360294032006200136020020062006280204220041016a360204200541003b01042005200136020020034180016a41186a200341206a41186a29030037030020034180016a41106a200341206a41106a29030037030020034180016a41086a200341206a41086a290300370300200320032903203703800120002008470d0220012f01062206410a4b0d03200120064105746a220841206a20034180016a41186a290300370000200841186a20034180016a41106a290300370000200841106a20034180016a41086a290300370000200841086a200329038001370000200120064102746a41e8026a20043602002001200641016a22064102746a4194036a2009360200200120063b0106200920063b0104200920013602000b200341c0046a24000f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b920c02057f027e230041d0006b220224000240024002400240024002402001280200417f6a220341034b0d0020030e0401020304010b41cfa2cc00412841c086cc00103f000b410121030240024020012d00044101470d00200141086a28020021040c010b2002410a6a200141046a220341036a2d00003a0000200241306a41086a200141146a290200370300200241c0006a2001411c6a290200370300200241c8006a200141246a2d00003a0000200220032f00013b010820022001410c6a290200370330200141086a2802002104410021030b200020033a0004200020022f01083b000520004101360200200041286a2001290328370300200041086a20043602002000410c6a2002290330370200200041306a200141306a290300370300200041076a2002410a6a2d00003a0000200041146a200241306a41086a2903003702002000411c6a200241c0006a290300370200200041246a200241c8006a2802003602000c030b410121030240024020012d00044101470d00200141086a28020021040c010b2002410a6a200141046a220341036a2d00003a0000200241306a41086a200141146a290200370300200241c0006a2001411c6a290200370300200241c8006a200141246a2d00003a0000200220032f00013b010820022001410c6a290200370330200141086a2802002104410021030b200020033a0004200020022f01083b0005200041286a2001290328370300200041386a2001290338370300200041086a20043602002000410c6a2002290330370200200041306a200141306a290300370300200041c0006a200141c0006a290300370300200041076a200241086a41026a2d00003a0000200041146a200241306a41086a2903003702002000411c6a200241c0006a290300370200200041246a200241c8006a280200360200200041023602000c020b200141286a2103410121040240024020012d00044101470d00200141086a28020021050c010b2002412a6a200141046a220441036a2d00003a0000200241086a41086a200141146a290200370300200241186a2001411c6a290200370300200241206a200141246a2d00003a0000200220042f00013b012820022001410c6a290200370308200141086a2802002105410021040b410121060240024020032d00004101470d002001412c6a28020021030c010b2002412e6a200341036a2d00003a0000200241386a200141386a290200370300200241c0006a200141c0006a290200370300200241c8006a200141c8006a2d00003a0000200220032f00013b012c2002200141306a2902003703302001412c6a2802002103410021060b200020043a0004200020022f01283b0005200020022f012c3b0029200041086a20053602002000410c6a2002290308370200200041286a20063a0000200041076a200241286a41026a2d00003a0000200041146a200241086a41086a2903003702002000411c6a200241086a41106a290300370200200041246a200241086a41186a2802003602002000412b6a2002412c6a41026a2d00003a0000200141d8006a2903002107200129035021082000412c6a2003360200200041d0006a2008370300200041d8006a200737030020004103360200200041306a2002290330370200200041386a200241306a41086a290300370200200041c0006a200241306a41106a290300370200200041c8006a200241306a41186a2802003602000c010b410121030240024020012d00044101470d00200141086a28020021040c010b2002410a6a200141046a220341036a2d00003a0000200241306a41086a200141146a290200370300200241c0006a2001411c6a290200370300200241c8006a200141246a2d00003a0000200220032f00013b010820022001410c6a290200370330200141086a2802002104410021030b200020033a0004200020022f01083b000520004104360200200041286a2001290328370300200041086a20043602002000410c6a2002290330370200200041306a200141306a290300370300200041076a2002410a6a2d00003a0000200041146a200241306a41086a2903003702002000411c6a200241c0006a290300370200200041246a200241c8006a2802003602000b200241d0006a24000bbe0702097f017e230041306b2202240002400240024002400240024002400240024002402001280200417f6a220341054b0d0020030e06010203040506010b41cfa2cc00412841c086cc00103f000b2001410c6a280200220441ffffff3f712004470d0620044105742205417f4c0d06200128020421060240024020050d00410121070c010b200510332207450d080b41002103200241003602182002200736021020022005410576360214200241106a41002004108a012002280218210802402004450d0020044105742109200228021020084105746a210a0340200a20036a2205200620036a2207290000370000200541186a200741186a290000370000200541106a200741106a290000370000200541086a200741086a2900003700002009200341206a2203470d000b200441057441606a41057620086a41016a21080b200241086a200836020020022002290310220b3703002000200b3702042000410c6a200836020020004101360200200041186a200141186a290300370300200041106a20012903103703000c050b200041023602000c040b410121030240024020012d00044101470d00200141086a28020021050c010b200241026a200141046a220341036a2d00003a0000200241106a41086a200141146a290200370300200241206a2001411c6a290200370300200241286a200141246a2d00003a0000200220032f00013b010020022001410c6a290200370310200141086a2802002105410021030b200020033a0004200020022f01003b000520004103360200200041086a20053602002000410c6a2002290310370200200041076a200241026a2d00003a0000200041146a200241106a41086a2903003702002000411c6a200241206a290300370200200041246a200241286a2802003602000c030b200041043602000c020b200041053602000c010b410121030240024020012d00044101470d00200141086a28020021050c010b200241026a200141046a220341036a2d00003a0000200241106a41086a200141146a290200370300200241206a2001411c6a290200370300200241286a200141246a2d00003a0000200220032f00013b010020022001410c6a290200370310200141086a2802002105410021030b200020033a0004200020022f01003b000520004106360200200041086a20053602002000410c6a2002290310370200200041076a200241026a2d00003a0000200041146a200241106a41086a2903003702002000411c6a200241206a290300370200200041246a200241286a2802003602000b200241306a24000f0b1044000b1045000bf64006017f027e117f0e7e027f017e230041d0066b220324000240024002400240024002400240024002400240024020012802000e050001020304000b200341ac056a41013602002003420137029c05200341e8d4ca00360298052003410436029c042003419cd5ca0036029804200320034198046a3602a80520034198056a41b0b4cc00104c000b200141306a2903002104200141286a2903002105200341b8046a200141246a28020036020020034198046a41186a2001411c6a29020037030020034198046a41106a200141146a29020037030020034198046a41086a2001410c6a2902003703002003200129020437039804410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703f802200320013a00f702200320063a00f602200320073b01f402200320083a00f302200320093a00f2022003200a3b01f0022003200b3a00ef022003200c3a00ee022003200d3b01ec022003200e3a00eb022003200f3a00ea02200320103b01e802200320113a00e702200320123a00e602200320133b01e402200320143a00e302200320153a00e202200320163b01e00220034198056a41206a20034198046a41206a28020036020020034198056a41186a20034198046a41186a29030037030020034198056a41106a20034198046a41106a29030037030020034198056a41086a20034198046a41086a29030037030020032003290398043703980520034198036a20034198056a108b02200341a0066a41086a2201200341a1036a290000370300200341a0066a41106a2202200341a9036a290000370300200341a0066a41186a2206200341b1036a29000037030020032003290099033703a006024020032d0098034101460d00200341d8016a41186a2006290300370300200341d8016a41106a2002290300370300200341d8016a41086a2001290300370300200320032903a0063703d80120034198056a200341e0026a200341d8016a20052004410110e60220032d00980522014104460d0a20032f00990520032d009b05411074722102200329029c0521040c020b410121010b0b200042003703082000411c6a2004370200200041186a20024108742001723602000c050b200141c0006a2903002117200141386a2903002118200141306a2903002104200141286a290300210520034180016a41206a2206200141246a28020036020020034180016a41186a22072001411c6a29020037030020034180016a41106a2208200141146a29020037030020034180016a41086a22092001410c6a29020037030020032001290204370380014102210120022d000120022d0000410047720d0320034198056a41206a200628020036020020034198056a41186a200729030037030020034198056a41106a200829030037030020034198056a41086a200929030037030020032003290380013703980520034198046a20034198056a108b02200341a0066a41086a200341a1046a290000370300200341a0066a41106a200341a9046a290000370300200341a0066a41186a200341b1046a29000037030020032003290099043703a0064101210120032d0098044101460d03200341a8016a41186a200341a0066a41186a290300370300200341a8016a41106a200341a0066a41106a290300370300200341a8016a41086a200341a0066a41086a290300370300200320032903a0063703a801200341c8016a200341a8016a108e02200341d8016a20032802c801220820032802d0012209108f0220032903d8012119200342003703d80142002004201820057c221a428080e983b1de16544100201720047c201a201854ad7c501b22011b21044200200520011b2105200341a0026a280200210a20032d00a402210b0240024020194201510d00200341a8026a41306a4200370300200341a8026a41286a4200370300200341a8026a41206a4200370300200341a8026a41186a4200370300200341a8026a41106a4200370300200341a8026a41086a4200370300200342003703a8024200211b4200211c4200211d4200211a4200211e0c010b20034190026a290300211f200341d8016a41306a2903002120200341d8016a41206a290300211c200341d8016a41186a290300211b20034198026a290300211e20032903e801211a20032903e001211d200341a8026a41206a200341d8016a41286a290300370300200341a8026a41286a2020370300200341a8026a41306a201f370300200341a8026a41106a201b3703002003201c3703c0022003201d3703a8022003201a3703b0020b4200201720011b21174200201820011b2118201d201b7c2220201d5421062005201d562004201a562004201a5122011b0d022005201d542004201a5420011b450d052003201d20057d3703e0022003201a20047d201d200554ad7d3703e8022003200341e0026a36029c0620034198056a41186a220d420037030020034198056a41106a2207420037030020034198056a41086a22024200370300200342003703980541b6fdc600ad4280808080800184221f1001220c290000211d200341c0066a41086a2201200c41086a2900003703002003201d3703c006200c103520022001290300370300200320032903c0063703980541e489c200ad4280808080d0018422211001220c290000211d2001200c41086a2900003703002003201d3703c006200c1035200720032903c006221d370300200341a0066a41086a220e2002290300370300200341a0066a41106a220f201d370300200341a0066a41186a2210200129030037030020032003290398053703a006200341e8006a200341a0066a412010d701200341e8006a41106a2903002122200329037021232003280268210c20032903e802212420032903e002211d200d420037030020074200370300200242003703002003420037039805201f1001220d290000211f2001200d41086a2900003703002003201f3703c006200d103520022001290300370300200320032903c0063703980520211001220d290000211f2001200d41086a2900003703002003201f3703c006200d1035200720032903c006221f370300200e2002290300370300200f201f3703002010200129030037030020032003290398053703a0062003420020224200200c1b221f20247d20234200200c1b2221201d54ad7d22222021201d7d221d2021562022201f562022201f511b22011b3703a00520034200201d20011b37039805200341a0066aad428080808080048420034198056aad428080808080028410020c050b200141d8006a2903002104200141d0006a290300210520034198036a41206a2206200141246a28020036020020034198036a41186a22072001411c6a29020037030020034198036a41106a2208200141146a29020037030020034198036a41086a22092001410c6a290200370300200320012902043703980320034198046a41206a200141c8006a28020036020020034198046a41186a200141c0006a29020037030020034198046a41106a200141386a29020037030020034198046a41086a200141306a2902003703002003200141286a29020037039804410221010240024020022d000120022d0000410047720d0020034198056a41206a200628020036020020034198056a41186a200729030037030020034198056a41106a200829030037030020034198056a41086a2009290300370300200320032903980337039805200341d8016a20034198056a108b024101210120032d00d8014101460d00200341d8016a41086a2d00002101200341e1016a22022f00002106200341e3016a2d00002107200341d8016a410c6a2d00002108200341e5016a2f00002109200341e7016a2d0000210a200341d8016a41106a2d0000210b200341e9016a220c2f0000210d200341eb016a2d0000210e200341d8016a41146a2d0000210f200341ed016a2f00002110200341ef016a2d00002111200341d8016a41186a2d0000211220032f00d901211320032d00db01211420032d00dc01211520032f00dd01211620032d00df0121252003200341f1016a22262900003703c002200320123a00bf02200320113a00be02200320103b01bc022003200f3a00bb022003200e3a00ba022003200d3b01b8022003200b3a00b7022003200a3a00b602200320093b01b402200320083a00b302200320073a00b202200320063b01b002200320013a00af02200320253a00ae02200320163b01ac02200320153a00ab02200320143a00aa02200320133b01a80220034198056a41206a20034198046a41206a28020036020020034198056a41186a20034198046a41186a29030037030020034198056a41106a20034198046a41106a29030037030020034198056a41086a20034198046a41086a290300370300200320032903980437039805200341d8016a20034198056a108b02200341a0066a41086a22012002290000370300200341a0066a41106a2202200c290000370300200341a0066a41186a22062026290000370300200320032900d9013703a006024020032d00d8014101460d00200341e0026a41186a2006290300370300200341e0026a41106a2002290300370300200341e0026a41086a2001290300370300200320032903a0063703e00220034198056a200341a8026a200341e0026a20052004410110e60220032d00980522014104460d0820032f00990520032d009b05411074722102200329029c0521040c020b410121010b0b200042003703082000411c6a2004370200200041186a20024108742001723602000c030b200141306a2903002104200141286a2903002105200341b8046a200141246a28020036020020034198046a41186a2001411c6a29020037030020034198046a41106a200141146a29020037030020034198046a41086a2001410c6a2902003703002003200129020437039804410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703f802200320013a00f702200320063a00f602200320073b01f402200320083a00f302200320093a00f2022003200a3b01f0022003200b3a00ef022003200c3a00ee022003200d3b01ec022003200e3a00eb022003200f3a00ea02200320103b01e802200320113a00e702200320123a00e602200320133b01e402200320143a00e302200320153a00e202200320163b01e00220034198056a41206a20034198046a41206a28020036020020034198056a41186a20034198046a41186a29030037030020034198056a41106a20034198046a41106a29030037030020034198056a41086a20034198046a41086a29030037030020032003290398043703980520034198036a20034198056a108b02200341a0066a41086a2201200341a1036a290000370300200341a0066a41106a2202200341a9036a290000370300200341a0066a41186a2206200341b1036a29000037030020032003290099033703a006024020032d0098034101460d00200341d8016a41186a2006290300370300200341d8016a41106a2002290300370300200341d8016a41086a2001290300370300200320032903a0063703d80120034198056a200341e0026a200341d8016a20052004410010e60220032d00980522014104460d0720032f00990520032d009b05411074722102200329029c0521040c020b410121010b0b200042003703082000411c6a2004370200200041186a20024108742001723602000c020b20032005201d7d3703e00220032004201a7d2005201d54ad7d3703e8022003200341e0026a36029c0620034198056a41186a220d420037030020034198056a41106a2207420037030020034198056a41086a22024200370300200342003703980541b6fdc600ad4280808080800184221d1001220c290000211f200341c0066a41086a2201200c41086a2900003703002003201f3703c006200c103520022001290300370300200320032903c0063703980541e489c200ad4280808080d00184221f1001220c29000021212001200c41086a290000370300200320213703c006200c1035200720032903c0062221370300200341a0066a41086a220e2002290300370300200341a0066a41106a220f2021370300200341a0066a41186a2210200129030037030020032003290398053703a006200341d0006a200341a0066a412010d701200341d0006a41106a2903002121200329035821222003280250210c20032903e802212320032903e0022124200d420037030020074200370300200242003703002003420037039805201d1001220d290000211d2001200d41086a2900003703002003201d3703c006200d103520022001290300370300200320032903c00637039805201f1001220d290000211d2001200d41086a2900003703002003201d3703c006200d1035200720032903c006221d370300200e2002290300370300200f201d3703002010200129030037030020032003290398053703a0062003427f202320214200200c1b221d7c202420224200200c1b221f7c2221201f542201ad7c221f2001201f201d54201f201d511b22011b3703a0052003427f202120011b37039805200341a0066aad428080808080048420034198056aad428080808080028410020c020b20004200370308200041186a20013602000b420121040c020b201a201c7c211d2006ad211f200341a8026a41106a2101024002402018201b562017201c562017201c5122021b0d002018201b542017201c5420021b450d012003201b20187d3703e0022003201c20177d201b201854ad7d3703e8022003200341e0026a36029c0620034198056a41186a220e420037030020034198056a41106a220c420037030020034198056a41086a22074200370300200342003703980541b6fdc600ad4280808080800184221b1001220d290000211c200341c0066a41086a2202200d41086a2900003703002003201c3703c006200d103520072002290300370300200320032903c0063703980541e489c200ad4280808080d0018422211001220d290000211c2002200d41086a2900003703002003201c3703c006200d1035200c20032903c006221c370300200341a0066a41086a220f2007290300370300200341a0066a41106a2210201c370300200341a0066a41186a2211200229030037030020032003290398053703a006200341386a200341a0066a412010d701200341386a41106a2903002122200329034021232003280238210d20032903e802212420032903e002211c200e4200370300200c4200370300200742003703002003420037039805201b1001220e290000211b2002200e41086a2900003703002003201b3703c006200e103520072002290300370300200320032903c0063703980520211001220e290000211b2002200e41086a2900003703002003201b3703c006200e1035200c20032903c006221b370300200f20072903003703002010201b3703002011200229030037030020032003290398053703a0062003420020224200200d1b221b20247d20234200200d1b2221201c54ad7d22222021201c7d221c2021562022201b562022201b511b22021b3703a00520034200201c20021b37039805200341a0066aad428080808080048420034198056aad428080808080028410020c010b20032018201b7d3703e00220032017201c7d2018201b54ad7d3703e8022003200341e0026a36029c0620034198056a41186a220e420037030020034198056a41106a220c420037030020034198056a41086a22074200370300200342003703980541b6fdc600ad4280808080800184221c1001220d290000211b200341c0066a41086a2202200d41086a2900003703002003201b3703c006200d103520072002290300370300200320032903c0063703980541e489c200ad4280808080d00184221b1001220d29000021212002200d41086a290000370300200320213703c006200d1035200c20032903c0062221370300200341a0066a41086a220f2007290300370300200341a0066a41106a22102021370300200341a0066a41186a2211200229030037030020032003290398053703a006200341206a200341a0066a412010d701200341206a41106a2903002121200329032821222003280220210d20032903e802212320032903e0022124200e4200370300200c4200370300200742003703002003420037039805201c1001220e290000211c2002200e41086a2900003703002003201c3703c006200e103520072002290300370300200320032903c00637039805201b1001220e290000211c2002200e41086a2900003703002003201c3703c006200e1035200c20032903c006221c370300200f20072903003703002010201c3703002011200229030037030020032003290398053703a0062003427f202320214200200d1b221c7c202420224200200d1b221b7c2221201b542202ad7c221b2002201b201c54201b201c511b22021b3703a0052003427f202120021b37039805200341a0066aad428080808080048420034198056aad428080808080028410020b201d201f7c211d200320053703a802200320173703c002200320183703b802200320043703b002200341e0026a41186a200141086a290300221c370300200341e0026a41206a2202200141106a29030037030020034188036a2207200141186a29030037030020034190036a220c200141206a290300370300200320043703e802200320053703e00220032001290300221b3703f00202400240427f2005201b7c221b201b20055422012004201c7c2001ad7c221c200454201c2004511b22011b221b428080e983b1de16544100427f201c20011b221f501b0d00200341e0026a41106a290300211b200c290300211f200729030021212002290300212220032903e802212320032903e00221244201211c20032903f80221270c010b02400240201b201f8450450d004200211c0c010b4200211c20034198056a41186a220d420037030020034198056a41106a2207420037030020034198056a41086a22024200370300200342003703980541b6fdc600ad428080808080018422211001220c2900002122200341c0066a41086a2201200c41086a290000370300200320223703c006200c103520022001290300370300200320032903c0063703980541e489c200ad4280808080d0018422221001220c29000021232001200c41086a290000370300200320233703c006200c1035200720032903c0062223370300200341a0066a41086a220e2002290300370300200341a0066a41106a220f2023370300200341a0066a41186a2210200129030037030020032003290398053703a006200341086a200341a0066a412010d701200341086a41106a2903002123200329031021242003280208210c200d42003703002007420037030020024200370300200342003703980520211001220d29000021212001200d41086a290000370300200320213703c006200d103520022001290300370300200320032903c0063703980520221001220d29000021212001200d41086a290000370300200320213703c006200d1035200720032903c0062221370300200e2002290300370300200f20213703002010200129030037030020032003290398053703a0062003420020234200200c1b2221201f7d20244200200c1b2222201b54ad7d22232022201b7d2224202256202320215620232021511b22011b3703a00520034200202420011b37039805200341a0066aad428080808080048420034198056aad42808080808002841002200341d0056a201f370300200341c8056a201b370300200241013a0000200341a1056a20032903a801370000200341a9056a200341a8016a41086a290300370000200341b1056a200341a8016a41106a290300370000200341b9056a200341a8016a41186a290300370000200341033a00980541b0b4cc00410020034198056a10d4010b0b201d201a512101201d201a54210220034180026a202237030020034188026a2021370300200341e8016a202337030020034190026a201f370300200341f0016a201b370300200320273703f8012003201e37039802200320243703e0012003200b4100201942015122071b3a00a4022003200a410020071b3602a0022003201c4201512207ad3703d8010240024020070d002009ad4220862008ad8410070c010b2003200936029c052003200836029805200341e0016a20034198056a10e7020b2006200220011b2101024020032802cc01450d00200810350b427f201d20011b211a427f202020011b211d201c420152210102400240024020194201510d0020010d004103210220034198046a21010c010b20194201522001410173720d014104210220034198036a21010b200141086a20023a0000200141096a20032903a801370000200141003a0000200141116a200341a8016a41086a290300370000200141196a200341b8016a290300370000200141216a200341c0016a29030037000041b0b4cc004100200110d4010b0240201d201a8450450d00200341d0056a2004370300200341c8056a200537030020034198056a41086a41003a0000200341a1056a20032903a801370000200341a9056a200341a8016a41086a290300370000200341b1056a200341b8016a290300370000200341b9056a200341c0016a290300370000200341033a00980541b0b4cc00410020034198056a10d4010b200341e0056a2017370300200341d8056a2018370300200341d0056a2004370300200341c8056a200537030020034198056a41086a41033a0000200341a1056a20032903a801370000200341a9056a200341a8016a41086a290300370000200341b1056a200341b8016a290300370000200341b9056a200341c0016a290300370000200341033a00980541b0b4cc00410020034198056a10d4010b42002104200042003703080b20002004370300200341d0066a24000b130020004108360204200041e0e4c2003602000b847c05057f027e107f057e037f230041e0036b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e0700010203040506000b200341d4026a4101360200200342013702c402200341e8d4ca003602c0022003410436028c022003419cd5ca0036028802200320034188026a3602d002200341c0026a41b0b4cc00104c000b200141086a280200210420012802042105410221064100210720022d00000d1920022d00014101470d19200141186a2903002108200141106a29030021092001410c6a2802002101200241196a2d00002106200241186a2d00002107200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211920032002411a6a2901003703b801200320063a00b701200320073a00b6012003200a3b01b4012003200b3a00b3012003200c3a00b2012003200d3b01b0012003200e3a00af012003200f3a00ae01200320103b01ac01200320113a00ab01200320123a00aa01200320133b01a801200320143a00a701200320153a00a601200320163b01a401200320173a00a301200320183a00a201200320193b01a00141a0e4cb00ad428080808080028410012202290000211a2002290008211b2002103541e1b8c800ad4280808080a0018410012202290000211c2002290008211d200210352003201d3701d8022003201c3701d0022003201b3701c8022003201a3701c002200341e8016a200341c0026aad4280808080800484221a100510c201024002400240024020032802e8012202450d0020032802ec0121072003200341f0016a28020036028c022003200236028802200341206a20034188026a10c4012003280220450d01410021060c020b2003420037028c02200341013602880220034188026a108a0321060c020b200328022421060b2007450d00200210350b41a0e4cb00ad428080808080028410012202290000211b2002290008211c200210354189eaca00ad4280808080f0008410012202290000211d2002290008211e200210352003201e3701d8022003201d3701d0022003201c3701c8022003201b3701c002200341e8016a201a100510c201024002400240024020032802e8012202450d0020032802ec01210a2003200341f0016a28020036028c022003200236028802200341186a20034188026a10c4012003280218450d01410021070c020b2003420037028c02200341083602880220034188026a108b0321070c020b200328021c21070b200a450d00200210350b41a0e4cb00ad428080808080028410012202290000211b2002290008211c2002103541c699c200ad428080808090018410012202290000211d2002290008211e200210352003201e3701d8022003201d3701d0022003201c3701c8022003201b3701c002200341e8016a201a100510c201024002400240024020032802e8012202450d0020032802ec01210b2003200341f0016a28020036028c022003200236028802200341106a20034188026a10c4012003280210450d014100210a0c020b2003420037028c02200341083602880220034188026a108b03210a0c020b2003280214210a0b200b450d00200210350b410c21020240200720066a200a6a22060d00418790c2002101410021070c190b0240200120064d0d0041f48fc20021014180800821070c190b0240200141104d0d0041e08fc2002101411421024180800c21070c190b024020010d00418090c2002101410721024180800421070c190b02402009428180e983b1de165441002008501b450d0041d68fc2002101410a21024180801021070c190b200341c0026a200341a0016a10e502200341086a20032802c002220620032802c80241b0b4cc0041004100108a0220032802082102024020032802c402450d00200610350b024020024101460d00200342003703f0012003428080e983b1de163703e8012003200341a0016a3602d0032003200341a0016a3602c8012003200341c8016a3602c8022003200341d0036a3602c4022003200341e8016a3602c00220034188026a200341a0016a200341c0026a108c0302402003280288024101470d0020032d008c024104460d0141c78fc2002101410f21024180801421070c1a0b20034188026a41086a2903004201520d0020034188026a41106a290300211a20032802c8012102200341f8026a20034188026a41186a290300370300200341f0026a201a370300200341c0026a41086a41003a0000200341c9026a2002290000370000200341d1026a200241086a290000370000200341d9026a200241106a290000370000200341e1026a200241186a290000370000200341033a00c00241b0b4cc004100200341c0026a10d4010b20034188026a200341a0016a108e02200341c0026a2003280288022207200328029002108f02200341d0026a290300420020032903c00242015122021b211a20032903c802420020021b211b200341e0026a290300420020021b211c200341d8026a2206290300420020021b211d0240200328028c02450d00200710350b200342f0d0c9abc6add9b1f4003703d003200341d0036a200341a0016a427f201b201d7c221d201d201b542202201a201c7c2002ad7c221b201a54201b201a511b22021b221a2009201a200954427f201b20021b221a200854201a2008511b22021b221b201a200820021b221a411e10900220062001360200200341d4026a20043602002003201a3703c8022003201b3703c002200320053602d00220034188026a200341a0016a10e502200328028802210220032003280290023602ec01200320023602e801200341c0026a200341e8016a108d030240200328028c02450d00200210350b200441ffffff3f71450d17200510350c170b41829a182101024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002104200241146a2d00002105200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703b801200320013a00b701200320063a00b601200320073b01b401200320043a00b301200320053a00b2012003200a3b01b0012003200b3a00af012003200c3a00ae012003200d3b01ac012003200e3a00ab012003200f3a00aa01200320103b01a801200320113a00a701200320123a00a601200320133b01a401200320143a00a301200320153a00a201200320163b01a001200341c0026a200341a0016a10e502200341286a20032802c002220120032802c80241b0b4cc0041004100108a0220032802282102024020032802c402450d00200110350b41839a18210120024101470d00200341c0026a200341a0016a10e50220033502c80242208620032802c0022202ad841007024020032802c402450d00200210350b200342f0d0c9abc6add9b1f4003703d00320034188026a200341a0016a10eb022003280288022113024020032802900222070d00410021070c170b200341c0036a210a4100210120132102410021060340024002400240200a2002460d00200241106a220529000020032903d003510d0020010d01410021010c020b200141016a21010c010b200620016b220420074f0d07200341c0026a41186a220b200220014105746b220441186a220c290300370300200341c0026a41106a220d200441106a220e290300370300200341c0026a41086a220f200441086a2210290300370300200320042903003703c002200241086a2211290300211a2005290300211b200241186a2212290300211c20042002290300370300200c201c370300200e201b3703002010201a3703002012200b2903003703002005200d2903003703002011200f290300370300200220032903c0023703000b200241206a21022007200641016a2206460d160c000b0b20004200370308200041206a410b3602002000411c6a41bc8fc200360200200041186a20013602004201211a0c1a0b200341c0016a200141246a280200360200200341a0016a41186a2001411c6a290200370300200341a0016a41106a200141146a290200370300200341a0016a41086a2001410c6a290200370300200320012902043703a0012002411a6a290100211a200241196a2d00002106200241186a2d00002107200241166a2f01002104200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d0000211741022101200241026a2f0100211841012105024020022d00000d0020022d000141014721050b2003201a3701d802200320063a00d702200320073a00d602200320043b01d4022003200a3a00d3022003200b3a00d2022003200c3b01d0022003200d3a00cf022003200e3a00ce022003200f3b01cc02200320103a00cb02200320113a00ca02200320123b01c802200320133a00c702200320143a00c602200320153b01c402200320163a00c302200320173a00c202200320183b01c0024100210a4100210641002102024020050d00200341c8016a41186a200341c0026a41186a2202290100370300200341c8016a41106a200341c0026a41106a2201290100370300200341c8016a41086a200341c0026a41086a2206290100370300200320032901c0023703c801200341c0026a41206a200341a0016a41206a2802003602002002200341a0016a41186a2903003703002001200341a0016a41106a2903003703002006200341a0016a41086a290300370300200320032903a0013703c00220034188026a200341c0026a108b0241012101410021064100210220032d0088024101460d0020034188026a41086a2d0000210220034191026a2f0000210120034193026a2d0000210620034194026a2d0000210720034195026a2f0000210420034197026a2d0000210520034188026a41106a2d0000210b20034199026a2f0000210c2003419b026a2d0000210d2003419c026a2d0000210e2003419d026a2f0000210f2003419f026a2d0000211020034188026a41186a2d0000211120032f008902211220032d008b02211320032d008c02211420032f008d02211520032d008f0221162003200341a1026a29000037038002200320113a00ff01200320103a00fe012003200f3b01fc012003200e3a00fb012003200d3a00fa012003200c3b01f8012003200b3a00f701200320053a00f601200320043b01f401200320073a00f301200320063a00f201200320013b01f001200320023a00ef01200320163a00ee01200320153b01ec01200320143a00eb01200320133a00ea01200320123b01e8014103210141801a21020240200341c8016a200341e8016a412010a0080d0041b28fc2002104410a21074180801c21060c010b200341c0026a200341c8016a10e502200341e8006a20032802c002220720032802c80241b0b4cc0041004100108a0220032802682106024020032802c402450d00200710350b024020064101460d0041bc8fc2002104410b21074180801821060c010b200341c0026a200341e8016a10e502200341e0006a20032802c002220120032802c80241b0b4cc0041004100108a0220032802602102024020032802c402450d00200110350b02400240024002400240024020024101470d0020034188026a200341e8016a10e502200341c0026a200328028802220120032802900210cc0220032902d402420020032802d00222021b211a2002410120021b210d0240200328028c02450d00200110350b200d201a422088a74105746a210e200341c0026a41106a2105200d210603402006200e460d020240200610e9020d00200641206a2110200341c0026a41186a220b420037030020054200370300200341c0026a41086a220a4200370300200342003703c00241a0e4cb00ad4280808080800284221c10012202290000211b200a200241086a2900003703002003201b3703c0022002103541c699c200ad428080808090018410012202290000211b200341d0036a41086a220c200241086a2900003703002003201b3703d00320021035200520032903d003370000200541086a2211200c29030037000020034188026a41086a2212200a29030037030020034188026a41106a2213200529030037030020034188026a41186a2214200b290300370300200320032903c00237038802200341c0026a20034188026a10a20220032902c402420020032802c00222021b221b422088a741306c2101410021072002410820021b220f2102024003402001450d01024020062002460d0020022006412010a0082104200741016a2107200141506a2101200241306a210220040d010b0b201ba72202450d01200241306c450d01200f10350c010b0240201ba72202450d00200241306c450d00200f10350b200b420037030020054200370300200a4200370300200342003703c002201c10012202290000211b200a200241086a2900003703002003201b3703c0022002103541e1b8c800ad4280808080a0018410012202290000211b200c200241086a2900003703002003201b3703d00320021035200520032903d0033700002011200c2903003700002012200a290300370300201320052903003703002014200b290300370300200320032903c00237038802200341c0026a20034188026a10fe0120032802c0022201410120011b210a4100210202400240024020032902c402420020011b221b422088a7220141014b0d0020010e020201020b03402001410176220720026a22042002200a20044105746a2006412010a0084101481b2102200120076b220141014b0d000b0b200a20024105746a2006412010a0084521020b0240201b42ffffff3f83500d00200a10350b201021062002450d010b0b201a42ffffff3f83500d00200d10350b200342003703d8032003428080e983b1de163703d0032003200341c8016a3602c00320034188026a200341c8016a200341d0036a200341c0036a10a802200341a8026a290300211b20032903a002211a02402003290388024201520d00200329039002211c200341f8026a20034188026a41106a290300370300200341f0026a201c370300200341c0026a41086a41003a0000200341c9026a20032903c801370000200341d1026a200341c8016a41086a290300370000200341d9026a200341c8016a41106a290300370000200341e1026a200341e0016a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b2003201a3703c0032003201b3703c803201a201b844200520d01200341c0026a41186a22044200370300200341c0026a41106a22064200370300200341c0026a41086a22014200370300200342003703c00241b6fdc600ad4280808080800184221a10012207290000211b200341d0036a41086a2202200741086a2900003703002003201b3703d0032007103520012002290300370300200320032903d0033703c00241e489c200ad4280808080d00184221b10012207290000211c2002200741086a2900003703002003201c3703d00320071035200620032903d003221c37030020034188026a41086a2205200129030037030020034188026a41106a220a201c37030020034188026a41186a220b2002290300370300200320032903c00237038802200341306a20034188026a412010d701200341306a41106a290300211c2003290338211d20032802302107200442003703002006420037030020014200370300200342003703c002201a10012204290000211a2002200441086a2900003703002003201a3703d0032004103520012002290300370300200320032903d0033703c002201b10012204290000211a2002200441086a2900003703002003201a3703d00320041035200620032903d003221a37030020052001290300370300200a201a370300200b2002290300370300200320032903c002370388022003201c420020071b3703c8022003201d420020071b3703c00220034188026aad4280808080800484200341c0026aad428080808080028410020c020b0240201a42ffffff3f83500d00200d10350b200341c0026a200341e8016a200341c8016a428080e983b1de164200410010ef0220032802c0024101460d03200341c0026a200341e8016a10e50220033502c80242208620032802c0022202ad841007024020032802c402450d00200210350b200342f0d0c9abc6add9b1f4003703d00320034188026a200341e8016a10eb02200328028802211320032802900222070d02410021070c140b2003201a3703c0032003201b3703c803200341c0026a41186a22044200370300200341c0026a41106a22064200370300200341c0026a41086a22014200370300200342003703c00241b6fdc600ad4280808080800184221c10012207290000211d200341d0036a41086a2202200741086a2900003703002003201d3703d0032007103520012002290300370300200320032903d0033703c00241e489c200ad4280808080d00184221d10012207290000211e2002200741086a2900003703002003201e3703d00320071035200620032903d003221e37030020034188026a41086a2205200129030037030020034188026a41106a220a201e37030020034188026a41186a220b2002290300370300200320032903c00237038802200341c8006a20034188026a412010d701200341c8006a41106a290300211e2003290350210820032802482107200442003703002006420037030020014200370300200342003703c002201c10012204290000211c2002200441086a2900003703002003201c3703d0032004103520012002290300370300200320032903d0033703c002201d10012204290000211c2002200441086a2900003703002003201c3703d00320041035200620032903d003221c37030020052001290300370300200a201c370300200b2002290300370300200320032903c0023703880220034200201e420020071b221c201b7d2008420020071b221b201a54ad7d221d201b201a7d221a201b56201d201c56201d201c511b22021b3703c80220034200201a20021b3703c00220034188026aad4280808080800484200341c0026aad428080808080028410020b200341c0026a200341c8016a10e50220033502c80242208620032802c0022202ad841007024020032802c402450d00200210350b200342f0d0c9abc6add9b1f4003703d00320034188026a200341c8016a10eb02410021142003280288022113410021022003280290022207450d14200341c0036a210a4100210120132102410021060340024002400240200a2002460d00200241106a220529000020032903d003510d0020010d01410021010c020b200141016a21010c010b200620016b220420074f0d09200341c0026a41186a220b200220014105746b220441186a220c290300370300200341c0026a41106a220d200441106a220e290300370300200341c0026a41086a220f200441086a2210290300370300200320042903003703c002200241086a2211290300211a2005290300211b200241186a2212290300211c20042002290300370300200c201c370300200e201b3703002010201a3703002012200b2903003703002005200d2903003703002011200f290300370300200220032903c0023703000b200241206a21022007200641016a2206460d140c000b0b200341c0036a210a4100210120132102410021060340024002400240200a2002460d00200241106a220529000020032903d003510d0020010d01410021010c020b200141016a21010c010b200620016b220420074f0d09200341c0026a41186a220b200220014105746b220441186a220c290300370300200341c0026a41106a220d200441106a220e290300370300200341c0026a41086a220f200441086a2210290300370300200320042903003703c002200241086a2211290300211a2005290300211b200241186a2212290300211c20042002290300370300200c201c370300200e201b3703002010201a3703002012200b2903003703002005200d2903003703002011200f290300370300200220032903c0023703000b200241206a21022007200641016a2206460d110c000b0b20032802c402220541ff017122014104460d16200341cc026a2802002107200341c8026a280200210420054180fe037121022005418080fc077121062005418080807871210a0b20004200370308200041206a20073602002000411c6a2004360200200041186a200a2006722002722001723602004201211a0c190b410221014100210620022d00000d0b20022d00014101470d0b200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002104200241146a2d00002105200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703b801200320013a00b701200320063a00b601200320073b01b401200320043a00b301200320053a00b2012003200a3b01b0012003200b3a00af012003200c3a00ae012003200d3b01ac012003200e3a00ab012003200f3a00aa01200320103b01a801200320113a00a701200320123a00a601200320133b01a401200320143a00a301200320153a00a201200320163b01a001200341c0026a41186a4200370300200341c0026a41106a22054200370300200341c0026a41086a22024200370300200342003703c00241a0e4cb00ad428080808080028410012201290000211a2002200141086a2900003703002003201a3703c0022001103541e1b8c800ad4280808080a0018410012201290000211a200341d0036a41086a2206200141086a2900003703002003201a3703d00320011035200520032903d003221a37030020034188026a41086a200229030037030020034188026a41106a201a37030020034188026a41186a2006290300370300200320032903c00237038802200341c0026a20034188026a10fe0120032802c0022201410120011b21044100210a41002102024020032902c402420020011b221a422088a7220141014b0d004100210b20010e020b0a0b0b03402001410176220620026a22072002200420074105746a200341a0016a412010a0084101481b2102200120066b220141014b0d000c0a0b0b410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002104200241146a2d00002105200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703b801200320013a00b701200320063a00b601200320073b01b401200320043a00b301200320053a00b2012003200a3b01b0012003200b3a00af012003200c3a00ae012003200d3b01ac012003200e3a00ab012003200f3a00aa01200320103b01a801200320113a00a701200320123a00a601200320133b01a401200320143a00a301200320153a00a201200320163b01a001200341c8016a200341a0016a108e030240024002400240024020032d00c801450d00200341c0026a41186a4200370300200341c0026a41106a22044200370300200341c0026a41086a22024200370300200342003703c00241a0e4cb00ad428080808080028410012201290000211a2002200141086a2900003703002003201a3703c0022001103541c699c200ad428080808090018410012201290000211a200341d0036a41086a2206200141086a2900003703002003201a3703d00320011035200420032903d003221a37030020034188026a41086a200229030037030020034188026a41106a201a37030020034188026a41186a2006290300370300200320032903c00237038802200341c0026a20034188026a10a20220032902c402420020032802c00222021b221a422088a7220a41306c2101410021062002410820021b22052102024003402001450d03200341a0016a2002460d01200641016a2106200141506a21012002200341a0016a412010a0082107200241306a210220070d000b20074541016a41017120066a417f6a21060b2005200641306c6a2202200241306a2006417f73200a6a41306c109e081a200342003703f00120034280809aa6eaafe3013703e8012003200341a0016a3602c80120034188026a200341a0016a200341e8016a200341c8016a10f00202402003290388024201520d00200329039002211b200341f8026a20034188026a41106a290300370300200341c0026a41306a201b370300200341c0026a41086a41003a0000200341c9026a20032903a001370000200341d1026a200341a0016a41086a290300370000200341d9026a200341a0016a41106a290300370000200341e1026a200341b8016a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b41a0e4cb00ad428080808080028410012202290000211b2002290008211c2002103541c699c200ad428080808090018410012202290000211d2002290008211e200210352003201e3701d8022003201d3701d0022003201c3701c8022003201b3701c0022003412036028c022003200341c0026a360288022005200a417f6a20034188026a10a902201aa72202450d03200241306c0d020c030b200342003703f00120034280809aa6eaafe3013703e8012003200341a0016a3602d00320034188026a200341a0016a200341e8016a200341d0036a10f00202402003290388024201520d00200329039002211a200341f8026a20034188026a41106a290300370300200341f0026a201a370300200341c0026a41086a41003a0000200341c9026a20032903a001370000200341d1026a200341a0016a41086a290300370000200341d9026a200341a0016a41106a290300370000200341e1026a200341b8016a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b200341cd026a200341a8016a290300370000200341d5026a200341b0016a290300370000200341dd026a200341b8016a290300370000200341033a00c402200341093a00c002200320032903a0013700c50241b0b4cc004100200341c0026a10d4014200211a0c050b200341c0026a41186a22064200370300200341c0026a41106a22074200370300200341c0026a41086a22024200370300200342003703c00241a0e4cb00ad428080808080028410012201290000211b2002200141086a2900003703002003201b3703c0022001103541e1b8c800ad4280808080a0018410012201290000211b200341d0036a41086a220a200141086a2900003703002003201b3703d00320011035200420032903d003370000200441086a200a29030037000020034188026a41086a200229030037030020034188026a41106a200729030037030020034188026a41186a2006290300370300200320032903c00237038802200341c0026a20034188026a10fe0120032802c0022201410120011b2104410021020240024020032902c402420020011b221b422088a7220a41014b0d00200a0e020401040b200a210103402001410176220620026a22072002200420074105746a200341a0016a412010a0084101481b2102200120066b220141014b0d000b0b200420024105746a200341a0016a412010a0080d022002200a4f0d09200420024105746a2201200141206a2002417f73200a6a410574109e081a200342003703f00120034280809aa6eaafe3013703e8012003200341a0016a3602c80120034188026a200341a0016a200341e8016a200341c8016a10f00202402003290388024201520d00200329039002211c200341f8026a20034188026a41106a290300370300200341f0026a201c370300200341c0026a41086a41003a0000200341c9026a20032903a001370000200341d1026a200341a0016a41086a290300370000200341d9026a200341a0016a41106a290300370000200341e1026a200341b8016a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b41a0e4cb00ad428080808080028410012202290000211c2002290008211d2002103541e1b8c800ad4280808080a0018410012202290000211e2002290008210820021035200320083701d8022003201e3701d0022003201d3701c8022003201c3701c0022003412036028c022003200341c0026a360288022004200a417f6a20034188026a1098020240201b42ffffff3f83500d00200410350b201aa72202450d01200241306c450d010b200510350b4200211a0c020b0240201b42ffffff3f83500d00200410350b0240201aa72202450d00200241306c450d00200510350b410321010b200041206a410d3602002000411c6a41e08ec200360200200041186a200141809a30723602004201211a0b200042003703080c170b200341a0016a41206a2207200141246a280200360200200341a0016a41186a22042001411c6a290200370300200341a0016a41106a2205200141146a290200370300200341a0016a41086a220a2001410c6a290200370300200320012902043703a001410021064102210120022d000120022d0000410047720d04200341c0026a41206a2007280200360200200341c0026a41186a2004290300370300200341c0026a41106a2005290300370300200341c0026a41086a200a290300370300200320032903a0013703c00220034188026a200341c0026a108b024101210120032d0088024101460d0420034188026a41086a2d0000210220034191026a2f0000210120034193026a2d0000210620034188026a410c6a2d0000210720034195026a2f0000210420034197026a2d0000210520034188026a41106a2d0000210a20034199026a2f0000210b2003419b026a2d0000210c20034188026a41146a2d0000210d2003419d026a2f0000210e2003419f026a2d0000210f20034188026a41186a2d0000211020032f008902211120032d008b02211220032d008c02211320032f008d02211420032d008f0221152003200341a1026a29000037038002200320103a00ff012003200f3a00fe012003200e3b01fc012003200d3a00fb012003200c3a00fa012003200b3b01f8012003200a3a00f701200320053a00f601200320043b01f401200320073a00f301200320063a00f201200320013b01f001200320023a00ef01200320153a00ee01200320143b01ec01200320133a00eb01200320123a00ea01200320113b01e801200341c0036a200341e8016a108e03024020032d00c0034101460d0020032d00c1032107200342003703d00120034280809aa6eaafe3013703c8012003200341e8016a3602d00320034188026a200341e8016a200341c8016a200341d0036a10a802200341a8026a290300211b20032903a002211a02402003290388024201520d00200329039002211c200341f8026a20034188026a41106a290300370300200341f0026a201c370300200341c0026a41086a41003a0000200341c9026a20032903e801370000200341d1026a200341e8016a41086a290300370000200341d9026a200341e8016a41106a290300370000200341e1026a20034180026a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b2003201a3703d0032003201b3703d80302400240201a201b844200520d00200341c0026a41186a22054200370300200341c0026a41106a22064200370300200341c0026a41086a22014200370300200342003703c00241b6fdc600ad4280808080800184221a10012204290000211b200341c8016a41086a2202200441086a2900003703002003201b3703c8012004103520012002290300370300200320032903c8013703c00241e489c200ad4280808080d00184221b10012204290000211c2002200441086a2900003703002003201c3703c80120041035200620032903c801221c37030020034188026a41086a220a200129030037030020034188026a41106a220b201c37030020034188026a41186a220c2002290300370300200320032903c00237038802200341f0006a20034188026a412010d701200341f0006a41106a290300211c2003290378211d20032802702104200542003703002006420037030020014200370300200342003703c002201a10012205290000211a2002200541086a2900003703002003201a3703c8012005103520012002290300370300200320032903c8013703c002201b10012205290000211a2002200541086a2900003703002003201a3703c80120051035200620032903c801221a370300200a2001290300370300200b201a370300200c2002290300370300200320032903c002370388022003201c420020041b3703c8022003201d420020041b3703c00220034188026aad4280808080800484200341c0026aad428080808080028410020c010b2003201a3703d0032003201b3703d803200341c0026a41186a22054200370300200341c0026a41106a22064200370300200341c0026a41086a22014200370300200342003703c00241b6fdc600ad4280808080800184221c10012204290000211d200341c8016a41086a2202200441086a2900003703002003201d3703c8012004103520012002290300370300200320032903c8013703c00241e489c200ad4280808080d00184221d10012204290000211e2002200441086a2900003703002003201e3703c80120041035200620032903c801221e37030020034188026a41086a220a200129030037030020034188026a41106a220b201e37030020034188026a41186a220c2002290300370300200320032903c0023703880220034188016a20034188026a412010d70120034188016a41106a290300211e20032903900121082003280288012104200542003703002006420037030020014200370300200342003703c002201c10012205290000211c2002200541086a2900003703002003201c3703c8012005103520012002290300370300200320032903c8013703c002201d10012205290000211c2002200541086a2900003703002003201c3703c80120051035200620032903c801221c370300200a2001290300370300200b201c370300200c2002290300370300200320032903c0023703880220034200201e420020041b221c201b7d2008420020041b221b201a54ad7d221d201b201a7d221a201b56201d201c56201d201c511b22021b3703c80220034200201a20021b3703c00220034188026aad4280808080800484200341c0026aad428080808080028410020b200341cd026a200341f0016a290300370000200341d5026a200341f8016a290300370000200341dd026a20034180026a290300370000200341023a00c402200341093a00c002200320032903e8013700c50241b0b4cc004100200341c0026a10d4010240200741ff01710d0010a1020b4200211a0c070b4200211a20032802c403220141ff01714104460d06200141807e712106200341c8036a290300211a0c050b2004200741f485cc001042000b2004200741f485cc001042000b2004200741f485cc001042000b2002200a104e000b0b2000411c6a201a370200200041186a2006200141ff0171723602004201211a0b200042003703080c0f0b0240200420024105746a200341a0016a412010a00822010d004101210a2002210b0c010b2001411f7620026a210b0b0240201a42ffffff3f83500d00200410350b02400240200a450d00419f8fc2002102411321074180802021060c010b410c21070240200341a0016a10e902450d0041938fc20021024180802421060c010b200341c0026a41186a22064200370300200341c0026a41106a22044200370300200341c0026a41086a22024200370300200342003703c00241a0e4cb00ad428080808080028410012201290000211a2002200141086a2900003703002003201a3703c0022001103541c699c200ad428080808090018410012201290000211a200341d0036a41086a220a200141086a2900003703002003201a3703d00320011035200520032903d003370000200541086a200a29030037000020034188026a41086a200229030037030020034188026a41106a200429030037030020034188026a41186a2006290300370300200320032903c00237038802200341c0026a20034188026a10a20220032902c402420020032802c00222021b221a422088a741306c2101410021062002410820021b220a2102024003402001450d010240200341a0016a2002460d00200641016a2106200141506a21012002200341a0016a412010a0082104200241306a210220040d010b0b41878fc2002102418080282106201aa72201450d01200141306c450d01200a10350c010b0240201aa72202450d00200241306c450d00200a10350b200342003703f00120034280809aa6eaafe3013703e8012003200341a0016a3602d0032003200341a0016a3602c8012003200341c8016a3602c8022003200341d0036a3602c4022003200341e8016a3602c00220034188026a200341a0016a200341c0026a108c03024002402003280288024101470d0020032d008c024104460d0141ed8ec2002102411a21074180802c21060c020b20034188026a41086a2903004201520d0020034188026a41106a290300211a20032802c8012102200341f8026a20034188026a41186a290300370300200341f0026a201a370300200341c0026a41086a41003a0000200341c9026a2002290000370000200341d1026a200241086a290000370000200341d9026a200241106a290000370000200341e1026a200241186a290000370000200341033a00c00241b0b4cc004100200341c0026a10d4010b20032903b801211a20032d00b701210420032d00b601210a20032f01b401210c20032d00b301210d20032d00b201210e20032f01b001210f20032d00af01211020032d00ae01211120032f01ac01211220032d00ab01211320032d00aa01211420032f01a801211520032d00a701211620032d00a601211720032f01a401211820032d00a301211920032d00a201211f20032f01a0012120200341c0026a41186a22064200370300200341c0026a41106a22074200370300200341c0026a41086a22024200370300200342003703c00241a0e4cb00ad428080808080028410012201290000211b2002200141086a2900003703002003201b3703c0022001103541e1b8c800ad4280808080a0018410012201290000211b200341d0036a41086a2221200141086a2900003703002003201b3703d00320011035200520032903d003370000200541086a202129030037000020034188026a41086a200229030037030020034188026a41106a200729030037030020034188026a41186a2006290300370300200320032903c00237038802200341c0026a20034188026a10fe010240024020032802c00222010d00410021072003410036029002200342013703880241012101410021060c010b200320032902c402221b37028c022003200136028802201b422088a72106201ba721070b02402006200b490d00024020062007470d0020034188026a20074101108a01200328028c02210720032802880221010b2001200b4105746a220241206a20022006200b6b410574109e081a2002201a370018200220043a00172002200a3a00162002200c3b00142002200d3a00132002200e3a00122002200f3b0010200220103a000f200220113a000e200220123b000c200220133a000b200220143a000a200220153b0008200220163a0007200220173a0006200220183b0004200220193a00032002201f3a0002200220203b00002003200641016a22063602900241a0e4cb00ad428080808080028410012202290000211a2002290008211b2002103541e1b8c800ad4280808080a0018410012202290000211c2002290008211d200210352003201d3701d8022003201c3701d0022003201b3701c8022003201a3701c002024020010d00200341c0026aad428080808080048410070c0c0b200341203602ec012003200341c0026a3602e80120012006200341e8016a109802200741ffffff3f71450d0b200110350c0b0b200b2006104d000b410321010c010b0b20004200370308200041206a20073602002000411c6a2002360200200041186a20064180803c7120017241801a723602004201211a0c0b0b2001417f6a20074f0d002003200720016b2207360290020b200341e8016a2013200710ec0241012114200328028c0241ffffff3f71450d02201310350c020b02402001417f6a2007490d00200721020c010b2003200720016b2202360290020b200341c8016a2013200210ec02200328028c0241ffffff3f71450d00201310350b200341cd026a200341e8016a41086a290300370000200341d5026a200341e8016a41106a290300370000200341dd026a200341e8016a41186a290300370000200341e5026a20032903c801370000200341ed026a200341c8016a41086a290300370000200341f5026a200341c8016a41106a290300370000200341fd026a200341c8016a41186a290300370000200341043a00c402200341093a00c002200320032903e8013700c50220034185036a20143a000041b0b4cc004100200341c0026a10d4010c020b2001417f6a20074f0d002003200720016b2207360290020b200341a0016a2013200710ec020240200328028c0241ffffff3f71450d00201310350b4200211a200342003703f0012003428080e983b1de163703e8012003200341a0016a3602c80120034188026a200341a0016a200341e8016a200341c8016a10f00202402003290388024201520d00200329039002211b200341f8026a20034188026a41106a290300370300200341f0026a201b370300200341c0026a41086a41003a0000200341c9026a20032903a001370000200341d1026a200341a0016a41086a290300370000200341d9026a200341a0016a41106a290300370000200341e1026a200341b8016a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b200042003703080c040b4200211a200042003703080c030b410321060c010b0b0240200441ffffff3f71450d00200510350b20004200370308200041206a20023602002000411c6a2001360200200041186a20074180801c7120067241801a723602004201211a0b2000201a370300200341e0036a24000bbb0201097f230041106b22012400024002402000280208220241ffffff3f712002470d0020024105742203417f4c0d00200028020021040240024020030d00410121050c010b200310332205450d020b41002100200141003602082001200536020020012003410576360204200141002002108a01200128020821060240024020020d00200128020021070c010b200241057421082001280200220720064105746a21090340200920006a2203200420006a2205290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a2900003700002008200041206a2200470d000b200241057441606a41057620066a41016a21060b200641057441057521000240200128020441ffffff3f71450d00200710350b200141106a240020000f0b1044000b1045000be30204027f017e037f037e230041106b220124000240024020002802082202ad42307e2203422088a70d002003a72204417f4c0d00200028020021000240024020040d00410821050c010b200410332205450d020b20014100360208200120053602002001200441306e3602042001410020021088012001280208210502400240200241306c22020d00200128020021060c010b20012802002206200541306c6a21040340200041086a2903002103200041106a2903002107200041186a290300210820002903002109200441286a200041286a290300370300200441206a200041206a290300370300200441186a2008370300200441106a2007370300200441086a200337030020042009370300200441306a2104200541016a2105200041306a2100200241506a22020d000b0b200541306c41306d2100024020012802042204450d00200441306c450d00200610350b200141106a240020000f0b1044000b1045000be61107067f027e027f0a7e037f017e047f230041d0036b22032400200228020821042002280204210520022802002106200341206a2001108e02200341a0016a2003280220220720032802282208108f0220032903a00121094200210a200342003703a001200341e8016a280200210b20032d00ec01210c02400240200942015122020d00200341306a41306a4200370300200341306a41286a4200370300200341306a41206a4200370300200341306a41186a4200370300200341c0006a4200370300200341386a4200370300200342003703304200210d4200210e4200210f420021100c010b200341d8016a2903002111200341a0016a41306a2903002112200341a0016a41206a290300210f200341a0016a41186a290300210e200341e0016a290300211020032903b001210d20032903a801210a200341306a41206a200341a0016a41286a290300370300200341306a41286a2012370300200341306a41306a2011370300200341c0006a200e3703002003200f3703482003200a3703302003200d3703380b0240024002400240200a200629030022127d2213200a56200d200641086a29030022147d200a201254ad7d2211200d562011200d511b450d0041838c0c2108419089c20021024280808080b00221120c010b200320133703302003201137033802400240200e20127c2215200e542206200f20147c2006ad7c2216200f542016200f511b450d0041838c08210841a7d6ca0021024280808080800121120c010b200341306a41186a2016370300200320153703402012201484500d02200341e8006a2005280200108e02200341a0026a200328026822052003280270108f02200341d0026a290300420020032903a00242015122061b2112200341c8026a290300420020061b21140240200328026c450d00200510350b2014201358201220115820122011511b0d0241838c04210841a389c20021024280808080d00221120b2013210a2011210d0b2002ad221142088842ff0183210f20122011428080fcff0f8384210e410121060c010b20042802002104200341e8006a41186a200341c0006a220641086a2903002212370300200341e8006a41206a2205200641106a29030037030020034190016a2217200641186a29030037030020034198016a2218200641206a2903003703002003200629030022143703782003201337036820032011370370427f200a200e7c220e200e200a542206200d200f7c2006ad7c220a200d54200a200d511b22061b427f200a20061b8450211902400240427f201320147c220a200a2013542206201120127c2006ad7c220a201154200a2011511b22061b220d428080e983b1de16544100427f200a20061b220a501b0d00200341e8006a41106a290300210a2018290300210d2017290300210f2005290300210e200329037021142003290368211642012115200329038001211a0c010b02400240200d200a8450450d00420021150c010b42002115200341a0026a41186a221b4200370300200341a0026a41106a22174200370300200341a0026a41086a22054200370300200342003703a00241b6fdc600ad4280808080800184220f100122182900002112200341c0036a41086a2206201841086a290000370300200320123703c0032018103520052006290300370300200320032903c0033703a00241e489c200ad4280808080d00184221210012218290000210e2006201841086a2900003703002003200e3703c00320181035201720032903c003220e370300200341a0036a41086a221c2005290300370300200341a0036a41106a221d200e370300200341a0036a41186a221e2006290300370300200320032903a0023703a003200341086a200341a0036a412010d701200341086a41106a290300210e2003290310211420032802082118201b42003703002017420037030020054200370300200342003703a002200f1001221b290000210f2006201b41086a2900003703002003200f3703c003201b103520052006290300370300200320032903c0033703a00220121001221b290000210f2006201b41086a2900003703002003200f3703c003201b1035201720032903c003220f370300201c2005290300370300201d200f370300201e2006290300370300200320032903a0023703a00320034200200e420020181b220f200a7d2014420020181b2212200d54ad7d220e2012200d7d2214201256200e200f56200e200f511b22061b3703a80220034200201420061b3703a002200341a0036aad4280808080800484200341a0026aad42808080808002841002200341d8026a200a370300200341d0026a200d370300200541013a0000200341a9026a2004290000370000200341b1026a200441086a290000370000200341b9026a200441106a290000370000200341c1026a200441186a290000370000200341033a00a00241b0b4cc004100200341a0026a10d4010b0b2019ad2112200341c8016a200e370300200341d0016a200f370300200341b0016a2014370300200341d8016a200d370300200341b8016a200a3703002003201a3703c001200320103703e001200320163703a8014201210f410021062003200c4100200942015122041b3a00ec012003200b410020041b3602e801200320154201512204ad3703a001024020040d002008ad4220862007ad8410074200210f2013210a2011210d4200210e0c010b200320083602a402200320073602a002200341a8016a200341a0026a10e7024200210e2013210a2011210d0b02402003280224450d00200710350b024002402006450d0020002008360204200041086a200f4208862002ad42ff018384200e84370200410121020c010b024002400240200241ff017122020d00200f4200510d0041032106200341a0026a21020c010b2002450d01200f4200520d0141042106200341a0016a21020b200241086a20063a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b200041186a200d370300200041106a200a370300200041086a2012370300410021020b20002002360200200341d0036a24000bc90301077f230041106b220224000240200041186a28020022034105744114722204417f4c0d000240200410332205450d00200520002903003700002005200041086a290300370008200241103602082002200436020420022005360200200028021021062003200210770240024020030d002002280208210320022802042104200228020021070c010b20034105742108200228020021072002280204210420022802082103034020062100024002402004200322056b4120490d00200541206a21030c010b024002400240200541206a22032005490d00200441017422062003200620034b1b22064100480d000240024020040d00024020060d00410121070c020b2006103321070c040b20042006470d020b200621040c030b103e000b200720042006103721070b2006210420070d00103c000b200041206a2106200720056a22052000290000370000200541186a200041186a290000370000200541106a200041106a290000370000200541086a200041086a290000370000200841606a22080d000b2002200436020420022003360208200220073602000b20012902002003ad4220862007ad84100202402004450d00200710350b200241106a24000f0b1045000b1044000bea1508047f017e077f027e037f017e017f037e230041d0016b22022400200241b0016a41186a4200370300200241b0016a41106a22034200370300200241b0016a41086a22044200370300200242003703b00141a0e4cb00ad42808080808002841001220529000021062004200541086a290000370300200220063703b001200510354189eaca00ad4280808080f00084100122052900002106200241f0006a41086a2207200541086a290000370300200220063703702005103520032002290370220637030020024190016a41086a200429030037030020024190016a41106a200637030020024190016a41186a2007290300370300200220022903b00137039001200241d0006a20024190016a10a202024002400240200228025022080d00410021092002410036020820024208370300410821080c010b200220022902542206370204200220083602002006a7210941002104024002402006422088a7220a41014b0d00200a0e020201020b200a210503402005410176220720046a220b20042008200b41306c6a2001412010a0084101481b2104200520076b220541014b0d000b0b2008200441306c6a2001412010a0080d0002400240024002402004200a4f0d002008200441306c6a2205200541306a200a2004417f736a41306c109e081a2002200a417f6a220c360208200241b0016a41186a220b4200370300200241b0016a41106a220d4200370300200241b0016a41086a22044200370300200242003703b00141a0e4cb00ad4280808080800284220e1001220529000021062004200541086a290000370300200220063703b0012005103541c699c200ad4280808080900184220f100122072900002106200241f0006a41086a2205200741086a290000370300200220063703702007103520032002290370370000200341086a200529030037000020024190016a41086a2203200429030037030020024190016a41106a2210200d29030037030020024190016a41186a2211200b290300370300200220022903b00137039001200241b0016a20024190016a10a20220022802b0012207410820071b21120240024020022902b401420020071b2206422088a722070d00420021130c010b200b20122007417f6a221441306c6a220741186a290300370300200d200741106a2903003703002004200741086a290300370300200220072903003703b0012014ad422086200642ffffffff0f83842106200741286a290300211520072903202116420121130b2011200b2903003703002010200d29030037030020032004290300370300200220022903b00137039001200241f0006a41186a4200370300200241f0006a41106a220342003703002005420037030020024200370370200e10012207290000210e2004200741086a2900003703002002200e3703b0012007103520052004290300370300200220022903b001370370200f10012207290000210e2004200741086a2900003703002002200e3703b00120071035200320022903b001220e370300200241d0006a41086a2005290300370300200241d0006a41106a200e370300200241d0006a41186a2004290300370300200220022903703703500240024020120d00200241d0006aad428080808080048410070c010b200241203602b4012002200241d0006a3602b00120122006422088a7200241b0016a10a9022006a72204450d00200441306c450d00201210350b200241106a41186a20024190016a41186a22042903002206370300200241106a41106a20024190016a41106a2205290300220e370300200241106a41086a20024190016a41086a2207290300220f37030020022002290390012217370310200241306a41186a220b2006370300200241306a41106a220d200e370300200241306a41086a2212200f370300200220173703300240201350450d00200c210a4100210d0c040b2004200b2903003703002005200d29030037030020072012290300370300200220022903303703900141002104024002400240200a417f6a220541014b0d0020050e020201020b200c210503402005410176220720046a220b20042008200b41306c6a20024190016a412010a0084101481b2104200520076b220541014b0d000b0b2008200441306c6a20024190016a412010a0082205450d022005411f7620046a21040b200241d0006a41186a20024190016a41186a2903002206370300200241d0006a41106a20024190016a41106a290300220e370300200241d0006a41086a20024190016a41086a290300220f37030020022002290390012213370350200241f0006a41186a2006370300200241f0006a41106a200e370300200241f0006a41086a200f37030020022013370370200241b0016a41186a2006370300200241b0016a41106a200e370300200241b0016a41086a200f370300200220133703b001200c2004490d020240200c2009470d0020022009410110880120022802042109200228020021080b2008200441306c6a220541306a2005200c20046b41306c109e081a200541286a201537030020052016370320200541186a200241b0016a41186a290300370300200541106a200241b0016a41106a290300370300200541086a200241b0016a41086a290300370300200520022903b0013703002002200a3602084101210d0c030b2004200a104e000b200241d0006a41186a20024190016a41186a290300370300200241d0006a41106a20024190016a41106a290300370300200241d0006a41086a20024190016a41086a29030037030020022002290390013703504100210d200c210a0c010b2004200c104d000b200241f0006a41186a220b4200370300200241f0006a41106a22124200370300200241f0006a41086a220542003703002002420037037041a0e4cb00ad4280808080800284100122072900002106200241b0016a41086a2204200741086a290000370300200220063703b0012007103520052004290300370300200220022903b0013703704189eaca00ad4280808080f000841001220729000021062004200741086a290000370300200220063703b00120071035200320022903b001370000200341086a2004290300370000200241d0006a41086a2005290300370300200241d0006a41106a2012290300370300200241d0006a41186a200b29030037030020022002290370370350200241203602b4012002200241d0006a3602b0012008200a200241b0016a10a902200241003602b801200242013703b001200241b0016a4100200a41306c220b41306d108a0120022802b80121070240200a450d0020022802b00120074105746a2104200821050340200541086a2900002106200541106a290000210e2005290000210f200441186a200541186a290000370000200441106a200e370000200441086a20063700002004200f370000200741016a2107200441206a2104200541306a2105200b41506a220b0d000b0b200220073602b80102402009450d00200941306c450d00200810350b20022802b401210520022802b0012104200241b0016a41186a200141186a290000370300200241b0016a41106a200141106a290000370300200241b0016a41086a200141086a290000370300200220012900003703b001200241b0016a41012004200710a7022000200d3a0001200041003a0000200041026a200229019001370100200041086a20024196016a290100370100200541ffffff3f71450d01200410350c010b200041013a00002000410c6a4109360200200041086a41f2dfca00360200200041066a410d3a0000200041046a41831a3b01002009450d00200941306c450d00200810350b200241d0016a24000bd30403067f017e037f230041306b220124000240024020002802202202450d000240034020002002417f6a36022020002802042202450d0120002802082103200028020021040240200028020c220520022f0106490d00034002400240200228020022060d002003ad2107410021060c010b200441016a210420023301044220862003ad8421070b200210352007a72103200621022007422088a7220520062f01064f0d000b200621020b200541016a21082002200541e0006c6a220541a0036a28020021092005419c036a280200210620054198036a280200210a200541e8026a290300210702402004450d00200220084102746a41880b6a2802002102410021082004417f6a2204450d00034020022802880b21022004417f6a22040d000b0b2000200836020c20002003360208200020023602042000410036020020074202510d0302400240200a0d00410021092001410036021c2001410036020c0c010b0240024020060d00200a21020c010b20062102200a2103034020032802ec0321032002417f6a22020d000b200a21020340200220022f01064102746a41ec036a28020021022006417f6a22060d000b2003210a0b2001410036022020014100360218200142003703102001200a36020c200141003602082001200236021c200120022f01063602240b20012009360228200141086a108103200028022022020d000c020b0b41958dcc00412b41c08dcc00103f000b200028020421020b02402002450d0020022802002106200210352006450d00034020062802002102200610352002210620020d000b0b200141306a24000b13002000410e360204200041cce9c2003602000bb30201027f230041206b220724002004a7210802400240024002402001a70d0020080d01427f200320067c200220057c22052002542208ad7c22022008200220035420022003511b22081b2103427f200520081b21020c020b024020084101460d00200741086a200420052006200120022003109103200741186a290300210320072903102102200729030821050c030b427f200320067c200220057c22052002542208ad7c22022008200220035420022003511b22081b2103427f200520081b2102420121050c020b02402002200556200320065620032006511b0d00200620037d2005200254ad7d2103200520027d2102420121050c020b200320067d2002200554ad7d2103200220057d21020b420021050b2000200237030820002005370300200041106a2003370300200741206a24000b130020004105360204200041b8fdc2003602000b3400200041a8fdc60036020420004100360200200041146a4101360200200041106a41a8a8c300360200200041086a42073702000bb10201057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b2003410036020820032005360200200320043602042001200310770240024020032802042206200328020822056b2001490d0020032802002104200621070c010b200520016a22042005490d03200641017422072004200720044b1b22074100480d030240024020060d00024020070d00410121040c020b2007103322040d010c060b2003280200210420062007460d0020042006200710372204450d050b20032007360204200320043602000b200420056a20002001109d081a2002290200200520016aad4220862004ad84100202402007450d00200410350b200341106a24000f0b1044000b1045000b103e000b103c000bb60201057f230041106b2203240002400240024002402001410274220441046a2205417f4c0d000240024020050d0041012106410021050c010b200510332206450d020b2003410036020820032006360200200320053602042001200310770240024020032802042207200328020822016b2004490d0020032802002105200721060c010b200120046a22052001490d03200741017422062005200620054b1b22064100480d030240024020070d00024020060d00410121050c020b2006103322050d010c060b2003280200210520072006460d0020052007200610372205450d050b20032006360204200320053602000b200520016a20002004109d081a2002290200200120046aad4220862005ad84100202402006450d00200510350b200341106a24000f0b1044000b1045000b103e000b103c000ba00402067f027e230041106b220324000240024002400240200141186c4104722204417f4c0d00200410332205450d0120034100360208200320043602042003200536020020012003107702400240200141186c22010d002003280208210120032802042104200328020021060c010b200020016a2107200328020421042003280208210103402000280200210802400240200420016b4104490d0020032802002106200421050c010b200141046a22052001490d05200441017422062005200620054b1b22054100480d050240024020040d00024020050d00410121060c020b2005103322060d010c080b2003280200210620042005460d0020062004200510372206450d070b20032005360204200320063602000b200620016a20083600002003200141046a2208360208200041106a2903002109200041086a290300210a02400240200520086b4110490d00200141146a2101200521040c010b200841106a22012008490d05200541017422042001200420014b1b22044100480d050240024020050d00024020040d00410121060c020b200410332206450d080c010b20052004460d0020062005200410372206450d070b20032004360204200320063602000b200620086a220520093700082005200a37000020032001360208200041186a22002007470d000b0b20022902002001ad4220862006ad84100202402004450d00200610350b200341106a24000f0b1044000b1045000b103e000b103c000bdf0301057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b2003410036020820032005360200200320043602042001200310770240024020032802042204200328020822066b2001490d0020032802002105200421070c010b200620016a22052006490d03200441017422072005200720054b1b22074100480d030240024020040d00024020070d00410121050c020b2007103322050d010c060b2003280200210520042007460d0020052004200710372205450d050b20032007360204200320053602000b200520066a20002001109d081a02400240200241046a2802002200200241086a28020022046b200620016a2201490d00200228020021060c010b200420016a22062004490d03200041017422042006200420064b1b22044100480d030240024020000d00024020040d00410121060c020b200410332206450d060c010b2002280200210620002004460d0020062000200410372206450d050b20022006360200200241046a2004360200200241086a28020021040b200620046a20052001109d081a200241086a200420016a36020002402007450d00200510350b200341106a24000f0b1044000b1045000b103e000b103c000bf00201057f230041206b220324000240024002400240200241046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b2003410036021820032005360210200320043602142002200341106a10770240024020032802142206200328021822056b2002490d0020032802102104200621070c010b200520026a22042005490d03200641017422072004200720044b1b22074100480d030240024020060d00024020070d00410121040c020b2007103322040d010c060b2003280210210420062007460d0020042006200710372204450d050b20032007360214200320043602100b200420056a20012002109d081a2003200520026a2202ad4220862004ad8410032205290000370308200510352003411c6a200420026a360200200320043602182003200341106a3602142003200341086a3602102000200341106a107b02402007450d00200410350b200341206a24000f0b1044000b1045000b103e000b103c000b960503037f027e057f230041106b220224002002410036020820024201370300200028021021030240410410332204450d0020024104360204200220043602002004200336000020024104360208200041146a280200210320044104410810372204450d0020024108360204200420033600042002200436020020024108360208200041086a29030021052000290300210620044108411810372204450d0020042006370008200441106a200537000020022004360200200242988080808003370204024041000d0020044118413810372204450d010b20042000290024370018200441206a2000412c6a290000370000200441286a200041346a290000370000200441306a2000413c6a29000037000020024138360204200220043602002002413836020820002802182104200041206a28020022002002107702400240024020000d002002280208210020022802042107200228020021080c010b200041057421094100200228020822006b210a2002280204210b034002400240200b200a6a4120490d0020022802002108200b21070c010b200041206a22032000490d03200b41017422082003200820034b1b22074100480d0302400240200b0d00024020070d00410121080c020b2007103322080d010c060b20022802002108200b2007460d002008200b200710372208450d050b20022007360204200220083602002007210b0b200820006a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200041206a2200360208200a41606a210a200441206a2104200941606a22090d000b0b20012902002000ad4220862008ad84100202402007450d00200810350b200241106a24000f0b103e000b103c000be20c03037f017e077f230041c0026b22022400024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41cfa2cc00412841c086cc00103f000b2001410c6a2802002204ad42b0027e2205422088a70d052005a72206417f4c0d05200141046a28020021030240024020060d00410821070c010b200610332207450d070b20024100360208200220073602002002200641b0026e3602042002410020041092012002280208210102402004450d00200441b0026c21062002280200200141b0026c6a2107200441047441706a41047621040340200241106a2003109b032007200241106a41b002109d0841b0026a2107200341b0026a2103200641d07d6a22060d000b200120046a41016a21010b200241186a20013602002002200229030022053703102000410c6a2001360200200041046a2005370200200041013a00000c040b200141026a2f0100210641b00210332203450d062003200141046a280200109c03200041046a2003360200200041026a20063b0100200041023a00000c030b2001410c6a280200220841ffffff3f712008470d0320084105742206417f4c0d03200141026a2f01002109200141046a28020021040240024020060d00410121070c010b200610332207450d050b41002103200241003602182002200736021020022006410576360214200241106a41002008108a012002280218210a02402008450d002008410574210b2002280210200a4105746a210c0340200c20036a2206200420036a2207290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200b200341206a2203470d000b200841057441606a410576200a6a41016a210a0b200241086a2206200a36020020022002290310370300200141186a2802002107200141146a28020021042001280210210b41b00210332203450d0520032001411c6a280200109c03200041026a20093b01002000411c6a2003360200200041186a2007360200200041146a2004360200200041106a200b360200200041033a0000200041046a20022903003702002000410c6a20062802003602000c020b2001412c6a280200220841ffffff3f712008470d0220084105742206417f4c0d02200141226a2f01002109200141246a28020021040240024020060d00410121070c010b200610332207450d040b41002103200241003602182002200736021020022006410576360214200241106a41002008108a012002280218210a02402008450d002008410574210b2002280210200a4105746a210c0340200c20036a2206200420036a2207290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200b200341206a2203470d000b200841057441606a410576200a6a41016a210a0b200241086a200a360200200220022903102205370300200041226a20093b0100200041246a20053702002000412c6a200a360200200041043a0000200041386a200141386a280200360200200041306a200129023037020020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c010b2001412c6a280200220841ffffff3f712008470d0120084105742206417f4c0d01200141226a2f01002109200141246a28020021040240024020060d00410121070c010b200610332207450d030b41002103200241003602182002200736021020022006410576360214200241106a41002008108a012002280218210a02402008450d002008410574210b2002280210200a4105746a210c0340200c20036a2206200420036a2207290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200b200341206a2203470d000b200841057441606a410576200a6a41016a210a0b200241086a200a360200200220022903102205370300200041226a20093b0100200041246a20053702002000412c6a200a360200200041053a0000200041306a20012902303702002000200141016a290000370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000b200241c0026a24000f0b1044000b1045000b103c000b881c04057f017e017f037e230041b0036b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c00011302030405060708090a0b0c0d0e0f1011121313131415161713000b20024180016a200141086a109d0320004100360200200041106a20024180016a41086a290300370300200041086a2002290380013703000c170b20024180016a200141046a109a03200041013602002000413c6a200241b8016a280200360200200041346a200241b0016a2903003702002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c160b20004103360200200041086a200141086a2903003703000c150b20024180016a200141046a109e03200041043602002000410c6a20024188016a28020036020020002002290380013702040c140b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b41cfa2cc00412841c086cc00103f000b200141086a2802002103410121050c030b41022105200241026a200441036a2d00003a000020024180016a41086a200141146a29020037030020024190016a2001411c6a29020037030020024198016a200141246a2d00003a0000200220042f00013b010020022001410c6a29020037038001200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b200241026a200441036a2d00003a000020024180016a41086a200141146a29020037030020024190016a2001411c6a29020037030020024198016a200141246a2d00003a0000200220042f00013b010020022001410c6a29020037038001200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01003b000520004105360200200041086a20033602002000410c6a200229038001370200200041286a2001360200200041076a200241026a2d00003a0000200041146a20024180016a41086a2903003702002000411c6a20024190016a290300370200200041246a20024198016a2802003602000c130b20024180016a200141086a108503200041086a20024180016a41e000109d081a200041063602000c120b20024180016a200141086a108702200041086a20024180016a418802109d081a200041073602000c110b02400240200128020422060d00410021030c010b20024180016a41186a200141286a29000037030020024180016a41106a200141206a29000037030020024188016a200141186a29000037030020024180016a41286a200141386a29000037030020024180016a41306a200141c0006a29000037030020024180016a41386a200141c8006a29000037030020024180016a41c8006a200141d8006a29000037030020024180016a41d0006a200141e0006a29000037030020024180016a41d8006a200141e8006a2900003703002002200141106a290000370380012002200141306a2900003703a0012002200141d0006a2900003703c00120024180016a41f8006a20014188016a29000037030020024180016a41f0006a20014180016a29000037030020024180016a41e8006a200141f8006a2900003703002002200141f0006a2900003703e0012001410c6a2802002201417f4c0d120240024020010d0041002105410121030c010b200110332203450d14200121050b0240024020052001490d00200521040c010b200541017422042001200420014b1b22044100480d15024020050d002004103322030d010c170b20052004460d0020032005200410372203450d160b200320062001109d081a200220024180016a418001109d081a2001ad4220862004ad8421070b20002003360204200041086a2007370200200041106a2002418001109d081a200041083602000c100b20024180016a200141086a10a00320004109360200200041386a20024180016a41306a290300370300200041306a20024180016a41286a290300370300200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c0f0b20024180016a200141046a10a1032000410a3602002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c0e0b20024180016a200141046a10a1032000410b3602002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c0d0b20024180016a200141086a1086032000410c360200200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c0c0b20024180016a200141046a10a203200041046a20024180016a41c400109d081a2000410d3602000c0b0b2000410e360200200020012802043602040c0a0b2001410c6a2802002203417f4c0d0a200128020421060240024020030d0041002101410121040c010b200310332204450d0c200321010b0240024020012003490d00200121050c010b200141017422052003200520034b1b22054100480d0d024020010d00200510332204450d0f0c010b20012005460d0020042001200510372204450d0e0b200420062003109d0821012000410c6a2003360200200041086a2005360200200020013602042000410f3602000c090b20024180016a200141086a10a30320004110360200200041c0006a20024180016a41386a290300370300200041386a20024180016a41306a290300370300200041306a20024180016a41286a290300370300200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c080b20024180016a200141086a10a403200041086a20024180016a419801109d081a200041113602000c070b20024180016a200141046a10a503200041123602002000412c6a200241a8016a280200360200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c060b20024180016a200141046a10de04200041046a20024180016a41e800109d081a200041133602000c050b10a703000b20024180016a200141086a10a803200041086a20024180016a41a802109d081a200041173602000c030b20024180016a200141086a10a903200041086a20024180016a41c800109d081a200041183602000c020b20024180016a200141046a10aa03200041046a20024180016a41c400109d081a200041193602000c010b0240024002400240200141086a280200417f6a220841024b0d004101210520080e03030102030b41cfa2cc00412841c086cc00103f000b41012103024002402001410c6a22052d00004101470d00200141106a28020021060c010b200241ae036a200541036a2d00003a000020024188016a2001411c6a29020037030020024180016a41106a200141246a29020037030020024198016a2001412c6a2d00003a0000200220052f00013b01ac032002200141146a29020037038001200141106a2802002106410021030b41022105200241a8036a41026a200241ac036a41026a2d00003a0000200241086a20024180016a41086a290300370300200241106a20024180016a41106a290300370300200241186a20024180016a41186a280200360200200220022f01ac033b01a80320022002290380013703000c010b41012103024002402001410c6a22052d00004101470d00200141106a28020021060c010b200241ae036a200541036a2d00003a000020024188016a2001411c6a29020037030020024180016a41106a200141246a29020037030020024198016a2001412c6a2d00003a0000200220052f00013b01ac032002200141146a29020037038001200141106a2802002106410021030b200241a8036a41026a200241ac036a41026a2d00003a0000200241086a20024180016a41086a290300370300200241106a20024180016a41106a290300370300200241186a20024180016a41186a280200360200200220022f01ac033b01a8032002200229038001370300200141c8006a2903002109200141c0006a2903002107200141386a290300210a200141d0006a28020021042001290330210b410321050b200020022f01a8033b000d200041c8006a2009370300200041c0006a2007370300200041386a200a370300200041306a200b3703002000410c6a20033a0000200041086a2005360200200041106a2006360200200041146a2002290300370200200041d0006a20043602002000410f6a200241aa036a2d00003a00002000411c6a200241086a290300370200200041246a200241106a2903003702002000412c6a200241186a2802003602002000411a3602000b200241b0036a24000f0b1044000b1045000b103e000b103c000ba91a03047f047e027f230041c0036b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c00011302030405060708090a0b0c0d0e0f1011121313131415161713000b2002200141086a109d0320004100360200200041106a200241086a290300370300200041086a20022903003703000c170b2002200141046a109a03200041013602002000413c6a200241386a280200360200200041346a200241306a2903003702002000412c6a200241286a290300370200200041246a200241206a2903003702002000411c6a200241186a290300370200200041146a200241106a2903003702002000410c6a200241086a290300370200200020022903003702040c160b20004103360200200041086a200141086a2903003703000c150b2002200141046a109e03200041043602002000410c6a200241086a280200360200200020022903003702040c140b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b41cfa2cc00412841c086cc00103f000b200141086a2802002103410121050c030b41022105200241b0026a41026a200441036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220042f00013b01b00220022001410c6a290200370300200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b200241b2026a200441036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220042f00013b01b00220022001410c6a290200370300200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01b0023b000520004105360200200041086a20033602002000410c6a2002290300370200200041286a2001360200200041076a200241b2026a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c130b2002200141086a108503200041086a200241e000109d081a200041063602000c120b2002200141086a108702200041086a2002418802109d081a200041073602000c110b024002402001280204450d00200241b0026a41186a200141286a290000370300200241b0026a41106a200141206a290000370300200241b8026a200141186a290000370300200241b0026a41286a200141386a290000370300200241b0026a41306a200141c0006a290000370300200241b0026a41386a200141c8006a290000370300200241b0026a41c8006a200141d8006a290000370300200241b0026a41d0006a200141e0006a290000370300200241b0026a41d8006a200141e8006a2900003703002002200141106a2900003703b0022002200141306a2900003703d0022002200141d0006a2900003703f002200241b0026a41f8006a20014188016a290000370300200241b0026a41f0006a20014180016a290000370300200241b0026a41e8006a200141f8006a2900003703002002200141f0006a290000370390032002200141046a109f032002410c6a200241b0026a418001109d081a0c010b200241003602000b200041046a2002418c01109d081a200041083602000c100b2002200141086a10a00320004109360200200041386a200241306a290300370300200041306a200241286a290300370300200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a290300370300200041086a20022903003703000c0f0b2002200141046a10a1032000410a3602002000412c6a200241286a290300370200200041246a200241206a2903003702002000411c6a200241186a290300370200200041146a200241106a2903003702002000410c6a200241086a290300370200200020022903003702040c0e0b2002200141046a10a1032000410b3602002000412c6a200241286a290300370200200041246a200241206a2903003702002000411c6a200241186a290300370200200041146a200241106a2903003702002000410c6a200241086a290300370200200020022903003702040c0d0b2002200141086a1086032000410c360200200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a290300370300200041086a20022903003703000c0c0b2002200141046a10a203200041046a200241c400109d081a2000410d3602000c0b0b2000410e360200200020012802043602040c0a0b2002200141046a109f032000410f3602002000410c6a200241086a280200360200200020022903003702040c090b2002200141086a10a30320004110360200200041c0006a200241386a290300370300200041386a200241306a290300370300200041306a200241286a290300370300200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a290300370300200041086a20022903003703000c080b2002200141086a10a403200041086a2002419801109d081a200041113602000c070b2002200141046a10a503200041123602002000412c6a200241286a280200360200200041246a200241206a2903003702002000411c6a200241186a290300370200200041146a200241106a2903003702002000410c6a200241086a290300370200200020022903003702040c060b200128020421032002200141086a109f03200241b0036a200141146a10a603200241146a200241b0036a41086a280200360200200220022903b00337020c200241b0026a41106a200241106a2903002206370300200241b0026a41086a200241086a29030022073703002002200229030022083703b002200141206a2902002109200141286a280200210520002003360204200041086a2008370200200041106a2007370200200041186a2006370200200041286a2005360200200041206a20093702002000412c6a2001412c6a290200370200200041346a200141346a2902003702002000413c6a2001413c6a290200370200200041c4006a200141c4006a290200370200200041cc006a200141cc006a290200370200200041d4006a200141d4006a290200370200200041dc006a200141dc006a290200370200200041e4006a200141e4006a290200370200200041133602000c050b10a703000b2002200141086a10a803200041086a200241a802109d081a200041173602000c030b2002200141086a10a903200041086a200241c800109d081a200041183602000c020b2002200141046a10aa03200041046a200241c400109d081a200041193602000c010b0240024002400240200141086a280200417f6a220a41024b0d0041012105200a0e03030102030b41cfa2cc00412841c086cc00103f000b41012103024002402001410c6a22052d00004101470d00200141106a280200210b0c010b200241b2036a200541036a2d00003a0000200241086a2001411c6a290200370300200241106a200141246a290200370300200241186a2001412c6a2d00003a0000200220052f00013b01b0032002200141146a290200370300200141106a280200210b410021030b41022105200241ac026a41026a200241b0036a41026a2d00003a0000200241b0026a41086a200241086a290300370300200241b0026a41106a200241106a290300370300200241b0026a41186a200241186a280200360200200220022f01b0033b01ac02200220022903003703b0020c010b41012103024002402001410c6a22052d00004101470d00200141106a280200210b0c010b200241b2036a200541036a2d00003a0000200241086a2001411c6a290200370300200241106a200141246a290200370300200241186a2001412c6a2d00003a0000200220052f00013b01b0032002200141146a290200370300200141106a280200210b410021030b200241ac026a41026a200241b0036a41026a2d00003a0000200241b0026a41086a200241086a290300370300200241b0026a41106a200241106a290300370300200241b0026a41186a200241186a280200360200200220022f01b0033b01ac02200220022903003703b002200141c8006a2903002107200141c0006a2903002106200141386a2903002109200141d0006a280200210420012903302108410321050b200020022f01ac023b000d200041c8006a2007370300200041c0006a2006370300200041386a2009370300200041306a20083703002000410c6a20033a0000200041086a2005360200200041106a200b360200200041146a20022903b002370200200041d0006a20043602002000410f6a200241ae026a2d00003a00002000411c6a200241b0026a41086a290300370200200041246a200241b0026a41106a2903003702002000412c6a200241c8026a2802003602002000411a3602000b200241c0036a24000bf20b03057f017e017f230041306b2202240002400240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0020030e0a0102030405060708090a010b41cfa2cc00412841c086cc00103f000b20004101360200200020012802043602040c090b2001410c6a2802002203417f4c0d09200128020421040240024020030d0041002101410121050c010b200310332205450d0b200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d0c024020010d002006103322050d010c0e0b20012006460d0020052001200610372205450d0d0b200520042003109d0821012000410c6a2003360200200041086a200636020020002001360204200041023602000c080b20004103360200200041086a200141086a2903003703000c070b2001410c6a2802002203417f4c0d07200128020421040240024020030d0041002101410121050c010b200310332205450d09200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d0a024020010d00200610332205450d0c0c010b20012006460d0020052001200610372205450d0b0b200520042003109d0821012000410c6a2003360200200041086a200636020020002001360204200041043602000c060b2001410c6a2802002203417f4c0d06200128020421040240024020030d0041002101410121050c010b200310332205450d08200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d09024020010d00200610332205450d0b0c010b20012006460d0020052001200610372205450d0a0b200520042003109d0821012000410c6a2003360200200041086a200636020020002001360204200041053602000c050b20004106360200200020012902043702042000410c6a2001410c6a2802003602000c040b2001410c6a2802002205ad42187e2207422088a70d042007a72206417f4c0d04200128020421030240024020060d00410421010c010b200610332201450d060b20024100360228200220013602202002200641186e360224200241206a410020051097012002280228210402402005450d002003200541186c6a21062002280220200441186c6a2101200541037441786a4103762108200241086a410c6a21050340200241086a2003109f0320052003410c6a109f03200141106a200241086a41106a290300370200200141086a200241086a41086a29030037020020012002290308370200200141186a2101200341186a22032006470d000b200420086a41016a21040b200241106a20043602002002200229032022073703082000410c6a200436020020002007370204200041073602000c030b2001410c6a2802002204ad420c7e2207422088a70d032007a72206417f4c0d03200128020421030240024020060d00410421010c010b200610332201450d050b200241003602282002200136022020022006410c6e360224200241206a410020041087012002280228210502402004450d002004410c6c210620022802202005410c6c6a21012004410274417c6a41027621040340200241086a2003109f03200141086a200241086a41086a280200360200200120022903083702002001410c6a21012003410c6a2103200641746a22060d000b200520046a41016a21050b200241086a41086a20053602002002200229032022073703082000410c6a200536020020002007370204200041083602000c020b2001410c6a2802002203417f4c0d02200128020421040240024020030d0041002101410121050c010b200310332205450d04200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d05024020010d00200610332205450d070c010b20012006460d0020052001200610372205450d060b200520042003109d0821012000410c6a2003360200200041086a200636020020002001360204200041093602000c010b2000410a3602000b200241306a24000f0b1044000b1045000b103e000b103c000ba10e03027f017e177f230041a0016b22022400024002400240024020012802082203ad42f0007e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410421010c010b200510332201450d020b20024100360208200220013602002002200541f0006e3602042002410020031093012002280208210502402003450d002006200341f0006c6a21072002280200200541f0006c6a21082005200341047441706a4104766a21090340200241d0006a41086a220a200641186a290000370300200241d0006a41106a220b200641206a290000370300200241d0006a41186a220c200641286a290000370300200241306a41086a220d200641386a29000037030020062900102104200241306a41106a220e200641c0006a290000370300200241306a41186a220f200641c8006a290000370300200241106a41186a2210200641e8006a290000370300200241106a41106a2211200641e0006a290000370300200241106a41086a2212200641d8006a290000370300200220043703502002200629003037033020022006290050370310200628020c2205ad42247e2204422088a70d022004a72203417f4c0d0220062802002113200628020421140240024020030d00410421010c010b200310332201450d040b20024100360278200220013602702002200341246e360274200241f0006a41002005108d012002280278211502402005450d00200541246c21162002280270201541246c6a211741002101034002400240024002400240024002400240201420016a22032d00000e06010203040500010b2003410c6a2802002218417f4c0d0b200341046a28020021190240024020180d0041002103410121050c010b201810332205450d0d201821030b0240024020032018490d002003211a0c010b2003410174221a2018201a20184b1b221a4100480d0e024020030d00201a103322050d010c100b2003201a460d0020052003201a10372205450d0f0b2002200520192018109d0836009301410521190c050b2002200341046a28000036009b012002200341016a280000360298012002200341146a290000370380012002200341196a290000370085012002200228029801360290012002200228009b0136009301200341086a280000211a2003410c6a2800002118200341106a2800002105410021190c050b200341106a2802002205417f4c0d09200341086a2802002119200341016a280000211b0240024020050d00410021034101211a0c010b20051033221a450d0b200521030b0240024020032005490d00200321180c010b200341017422182005201820054b1b22184100480d0c024020030d0020181033221a450d0e0c010b20032018460d00201a200320181037221a450d0d0b201a20192005109d081a2002201b36029001410121190c040b200341106a2802002205417f4c0d08200341086a2802002119200341016a280000211b0240024020050d00410021034101211a0c010b20051033221a450d0a200521030b0240024020032005490d00200321180c010b200341017422182005201820054b1b22184100480d0b024020030d0020181033221a450d0d0c010b20032018460d00201a200320181037221a450d0c0b201a20192005109d081a2002201b36029001410221190c030b200341106a2802002205417f4c0d07200341086a2802002119200341016a280000211b0240024020050d00410021034101211a0c010b20051033221a450d09200521030b0240024020032005490d00200321180c010b200341017422182005201820054b1b22184100480d0a024020030d0020181033221a450d0c0c010b20032018460d00201a200320181037221a450d0b0b201a20192005109d081a2002201b36029001410321190c020b410421192002200341046a280200360093012003410c6a2802002118200341086a280200211a0b0b201720016a220320193a0000200341016a200228029001360000200341046a200228009301360000200341106a20053602002003410c6a2018360200200341086a201a360200200341146a2002290380013702002003411c6a20024180016a41086a290300370200201541016a21152016200141246a2201470d000b0b20024180016a41086a2015360200200220022903702204370380012008410c6a20153602002008200437020420082002290350370210200841186a200a29030037020020082013360200200841206a200b290300370200200841286a200c29030037020020082002290330370230200841386a200d290300370200200841c0006a200e290300370200200841c8006a200f290300370200200841e8006a2010290300370200200841e0006a2011290300370200200841d8006a201229030037020020082002290310370250200841f0006a2108200641f0006a22062007470d000b200941016a21050b20002002290300370200200041086a2005360200200241a0016a24000f0b1044000b1045000b103e000b103c000bc80101047f02400240024020012802082202417f4c0d00200128020021030240024020020d0041002101410121040c010b200210332204450d02200221010b0240024020012002490d00200121050c010b02400240200141017422052002200520024b1b22054100480d00024020010d002005103322040d030c060b20012005470d01200121050c020b103e000b20042001200510372204450d030b200420032002109d0821012000200236020820002005360204200020013602000f0b1044000b1045000b103c000bc01203037f027e027f230041106b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203411c4b0d0020030e1d0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d010b41cfa2cc00412841c086cc00103f000b200041013a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c1c0b200041023a0000200041046a200141046a2802003602000c1b0b200141046a28020021044101210302400240200141086a2d00004101470d00200141286a2903002105200141206a29030021060c010b200141096a2d000041017121072001410a6a2d00002108410021030b200041033a0000200041286a2005370300200041206a2006370300200041106a20012903103703002000410a6a20083a0000200041096a20073a0000200041086a20033a0000200041046a20043602002000410b6a2002280006360000200041186a200141186a2903003703002000410f6a200241066a41046a2d00003a00000c1a0b200141046a28020021044101210302400240200141086a2d00004101470d00200141286a2903002105200141206a29030021060c010b200141096a2d000041017121072001410a6a2d00002108410021030b200041043a0000200041286a2005370300200041206a2006370300200041106a20012903103703002000410a6a20083a0000200041096a20073a0000200041086a20033a0000200041046a20043602002000410b6a200228000b360000200041186a200141186a2903003703002000410f6a2002410b6a41046a2d00003a00000c190b200041053a0000200041046a200141046a2802003602000c180b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c170b200041073a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c160b200041083a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c150b200041093a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2902003702000c140b2000410a3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c130b2000410b3a0000200041046a200141046a2802003602000c120b2000410c3a0000200041046a200141046a2802003602000c110b2000410d3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c100b2000410e3a00000c0f0b2000410f3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0e0b200041103a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c0d0b200041113a00000c0c0b200041123a00000c0b0b2001410c6a2802002203417f4c0d0b200141046a28020021070240024020030d0041002101410121080c010b200310332208450d0d200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d0e024020010d002004103322080d010c100b20012004460d0020082001200410372208450d0f0b200820072003109d0821012000410c6a2003360200200041086a2004360200200041046a2001360200200041133a00000c0a0b2001410c6a2802002203417f4c0d0a200141046a28020021070240024020030d0041002101410121080c010b200310332208450d0c200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d0d024020010d00200410332208450d0f0c010b20012004460d0020082001200410372208450d0e0b200820072003109d0821012000410c6a2003360200200041086a2004360200200041046a2001360200200041143a00000c090b200041153a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c080b200041163a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c070b200041173a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c060b200041183a0000200041046a200141046a2802003602000c050b200041193a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c040b2000411a3a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c030b2000411b3a00000c020b2000411c3a0000200041046a200141046a2802003602000c010b2000411d3a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000b200241106a24000f0b1044000b1045000b103e000b103c000bcd0601097f230041306b22022400024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41cfa2cc00412841c086cc00103f000b2001412c6a280200220441ffffff3f712004470d0520044105742205417f4c0d05200141246a28020021060240024020050d00410121070c010b200510332207450d070b41002103200241003602182002200736021020022005410576360214200241106a41002004108a012002280218210802402004450d0020044105742109200228021020084105746a210a0340200a20036a2205200620036a2207290000370000200541186a200741186a290000370000200541106a200741106a290000370000200541086a200741086a2900003700002009200341206a2203470d000b200441057441606a41057620086a41016a21080b200241086a220520083602002002200229031037030041002103024020012d00014101470d00200241286a2001411a6a290000370300200241206a200141126a290000370300200241106a41086a2001410a6a2900003703002002200141026a290000370310410121030b200020033a0001200041013a0000200041246a2002290300370200200041026a20022903103700002000412c6a20052802003602002000410a6a200241106a41086a290300370000200041126a200241206a2903003700002000411a6a200241286a2903003700000c040b41b00210332203450d062003200141046a280200109b03200041023a0000200041046a20033602000c030b200141046a280200210541b00210332203450d052003200141086a280200109b03200041086a2003360200200041046a2005360200200041033a00000c020b200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00004100473a00000c010b200041053a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000b200241306a24000f0b1044000b1045000b103c000ba60602087f017e230041206b220224000240024002400240024002400240024002400240024020012d0000417f6a220341064b0d0020030e0701020304050607010b41cfa2cc00412841c086cc00103f000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c060b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c050b200041033a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c040b2001410c6a280200220441ffffff3f712004470d0420044105742203417f4c0d04200141046a28020021050240024020030d00410121060c010b200310332206450d060b41002101200241003602182002200636021020022003410576360214200241106a41002004108a012002280218210702402004450d0020044105742108200228021020074105746a21090340200920016a2203200520016a2206290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a2900003700002008200141206a2201470d000b200441057441606a41057620076a41016a21070b200241086a200736020020022002290310220a3703002000410c6a2007360200200041046a200a370200200041043a00000c030b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c020b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c010b200041073a00000b200241206a24000f0b1044000b1045000bc30903027f027e047f230041206b220224000240024002400240024002400240024002400240024002400240024020012d0000417f6a220341074b0d0020030e080102030405060708010b41cfa2cc00412841c086cc00103f000b200141306a2903002104200141286a29030021054101210302400240200141046a2d00004101470d00200141086a28020021010c010b2002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002101410021030b200041013a0000200041306a2004370300200041286a2005370300200041046a20033a0000200041056a20022f011c3b0000200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c070b200041023a0000200041046a200141046a2802003602000c060b200041033a0000200041046a200141046a2802003602000c050b2001412c6a2802002203417f4c0d05200141246a28020021060240024020030d0041002107410121080c010b200310332208450d07200321070b0240024020072003490d00200721090c010b200741017422092003200920034b1b22094100480d08024020070d002009103322080d010c0a0b20072009460d0020082007200910372208450d090b200820062003109d0821072000412c6a2003360200200041286a2009360200200041246a2007360200200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c040b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c030b2001412c6a2802002203417f4c0d03200141246a28020021060240024020030d0041002107410121080c010b200310332208450d05200321070b0240024020072003490d00200721090c010b200741017422092003200920034b1b22094100480d06024020070d00200910332208450d080c010b20072009460d0020082007200910372208450d070b200820062003109d0821072000412c6a2003360200200041286a2009360200200041246a2007360200200041063a0000200041386a200141386a290300370300200041306a200129033037030020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c020b200041073a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c010b200041083a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000b200241206a24000f0b1044000b1045000b103e000b103c000bd20e03027f107e057f230041c0006b220224000240024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41cfa2cc00412841c086cc00103f000b20014190016a2d00002103200141086a2903002104200141106a2903002105200141186a2903002106200141206a2903002107200141286a2903002108200141306a2903002109200141386a290300210a200141c0006a290300210b200141c8006a290300210c200141d0006a290300210d200141d8006a290300210e200141e0006a290300210f200141e8006a2903002110200141f0006a2903002111200141f8006a290300211220014180016a290300211320004188016a20014188016a29030037030020004180016a2013370300200041f8006a2012370300200041f0006a2011370300200041e8006a2010370300200041e0006a200f370300200041d8006a200e370300200041d0006a200d370300200041c8006a200c370300200041c0006a200b370300200041386a200a370300200041306a2009370300200041286a2008370300200041206a2007370300200041186a2006370300200041106a2005370300200041086a200437030020004190016a20034100473a0000200041013a000020004194016a200241236a28000036000020004191016a20022800203600000c040b2001410c6a2802002203417f4c0d04200141046a28020021140240024020030d0041002101410121150c010b200310332215450d06200321010b0240024020012003490d00200121160c010b200141017422162003201620034b1b22164100480d07024020010d002016103322150d010c090b20012016460d0020152001201610372215450d080b201520142003109d0821012000410c6a2003360200200041086a2016360200200041046a2001360200200041023a00000c030b4101211502400240200141046a2d00004101470d00200141086a28020021170c010b200241026a200141076a2d00003a0000200241206a41086a200141146a290000370300200241306a2001411c6a290000370300200241386a200141246a2d00003a00002002200141056a2f00003b010020022001410c6a290000370320200141086a2800002117410021150b200141306a2802002203417f4c0d03200141c0006a29030021042001290338210520012802282118200129034821060240024020030d0041002101410121140c010b200310332214450d05200321010b0240024020012003490d00200121160c010b200141017422162003201620034b1b22164100480d06024020010d00201610332214450d080c010b20012016460d0020142001201610372214450d070b201420182003109d082101200041c0006a2004370300200041386a2005370300200041046a20153a0000200041086a2017360200200041c8006a2006370300200041306a20033602002000412c6a2016360200200041286a2001360200200041056a20022f01003b0000200041076a200241026a2d00003a00002000410c6a2002290320370200200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041033a00000c020b200141386a2903002104200141306a2903002105200141c0006a2903002106200241386a200141196a290000370300200241306a200141116a290000370300200241286a200141096a290000370300200220012900013703202001412c6a2802002203417f4c0d02200141246a28020021140240024020030d0041002101410121150c010b200310332215450d04200321010b0240024020012003490d00200121160c010b200141017422162003201620034b1b22164100480d05024020010d00201610332215450d070c010b20012016460d0020152001201610372215450d060b201520142003109d082101200041386a2004370300200041306a2005370300200041c0006a20063703002000412c6a2003360200200041286a2016360200200041246a2001360200200041043a000020002002290320370001200041096a200241286a290300370000200041116a200241306a290300370000200041196a200241386a2903003700000c010b200241186a2216200141196a290000370300200241106a2215200141116a290000370300200241086a2214200141096a29000037030020022001290001370300410021030240200141216a2d00004101470d00200241206a41186a2001413a6a290000370300200241206a41106a200141326a290000370300200241206a41086a2001412a6a2900003703002002200141226a290000370320410121030b20002002290300370001200041216a20033a0000200041226a2002290320370000200041196a2016290300370000200041116a2015290300370000200041096a20142903003700002000412a6a200241206a41086a290300370000200041326a200241206a41106a2903003700002000413a6a200241206a41186a290300370000200041053a00000b200241c0006a24000f0b1044000b1045000b103e000b103c000b890501047f230041206b220224000240024002400240024002402001280200417f6a220341024b0d0020030e03010203010b41cfa2cc00412841c086cc00103f000b41b00210332203450d032003200128020410d10620004101360200200020033602040c020b410121030240024020012d00044101470d00200141086a28020021010c010b2002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002101410021030b200020033a0004200020022f011c3b000520004102360200200041086a20013602002000410c6a2002290300370200200041076a2002411c6a41026a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c010b410121040240024020012d00044101470d00200141086a28020021050c010b2002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002105410021040b41b00210332203450d012003200128022810d106200020043a0004200041086a2005360200200041286a200336020020004103360200200020022f011c3b0005200041076a2002411e6a2d00003a00002000410c6a2002290300370200200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000b200241206a24000f0b103c000b920203027f017e037f230041206b220224000240024020012802082203ad420c7e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410421060c010b200510332206450d020b200241003602082002200636020020022005410c6e3602042002410020031087012002280208210702402003450d002003410c6c210620022802002007410c6c6a21052003410274417c6a41027621030340200241106a2001109f03200541086a200241106a41086a280200360200200520022903103702002005410c6a21052001410c6a2101200641746a22060d000b200720036a41016a21070b20002002290300370200200041086a2007360200200241206a24000f0b1044000b1045000b110041cfa2cc00412841c086cc00103f000bc95704027f017e3a7f017e230041e0036b220224000240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410a4b0d0020030e0b0102030405060708090a0b010b41cfa2cc00412841c086cc00103f000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0a0b2001410c6a2802002203ad42c8007e2204422088a70d0a2004a72205417f4c0d0a200141046a28020021060240024020050d00410421070c010b200510332207450d0c0b200241003602d003200220073602c8032002200541c8006e3602cc03200241c8036a4100200310a80120022802d003210802402003450d002006200341c8006c6a210920022802c803200841c8006c6a210a4100210703404100210b4100210c024002400240024002400240200620076a22052d00000e06050102030400050b20024188026a41086a200541186a29000037030020024188026a41106a200541206a2d00003a00002002200541036a2d00003a009a032002200541016a2f00003b0198032002200541106a290000370388022005410c6a280000210d200541086a280000210e200541046a280000210f4105210c0c040b2005410c6a280200220d417f4c0d10200541046a280200210c02400240200d0d00410021034101210f0c010b200d1033220f450d12200d21030b024002402003200d490d002003210e0c010b2003410174220e200d200e200d4b1b220e4100480d13024020030d00200e1033220f0d010c150b2003200e460d00200f2003200e1037220f450d140b200f200c200d109d081a4101210c0c030b20024188026a41086a200541186a29000037030020024188026a41106a200541206a2d00003a00002002200541036a2d00003a009a032002200541016a2f00003b0198032002200541106a290000370388022005410c6a280000210d200541086a280000210e200541046a280000210f4102210c0c020b20024188026a41086a200541186a29000037030020024188026a41106a200541206a2d00003a00004103210c2002200541036a2d00003a009a032002200541016a2f00003b0198032002200541106a290000370388022005410c6a280000210d200541086a280000210e200541046a280000210f0c010b20024188026a41086a200541186a29000037030020024188026a41106a200541206a2d00003a00002002200541036a2d00003a009a032002200541016a2f00003b0198032002200541106a290000370388022005410c6a280000210d200541086a280000210e4104210c200541046a280000210f0b024002400240024002400240200541246a2d00000e06050102030400050b200241e8026a41026a200541276a2d00003a0000200241086a41086a2005413c6a290000370300200241086a41106a200541c4006a2d00003a00002002200541256a2f00003b01e8022002200541346a290000370308200541306a28000021102005412c6a2800002111200541286a28000021124105210b0c040b200541306a2802002210417f4c0d10200541286a280200210b0240024020100d0041002103410121120c010b201010332212450d12201021030b0240024020032010490d00200321110c010b200341017422112010201120104b1b22114100480d13024020030d00201110332212450d150c010b20032011460d0020122003201110372212450d140b2012200b2010109d081a4101210b0c030b4102210b200241e8026a41026a200541276a2d00003a0000200241086a41086a2005413c6a290000370300200241086a41106a200541c4006a2d00003a00002002200541256a2f00003b01e8022002200541346a290000370308200541306a28000021102005412c6a2800002111200541286a28000021120c020b200241e8026a41026a200541276a2d00003a0000200241086a41086a2005413c6a290000370300200241086a41106a200541c4006a2d00003a00002002200541256a2f00003b01e8022002200541346a290000370308200541306a28000021102005412c6a2800002111200541286a28000021124103210b0c010b200241e8026a41026a200541276a2d00003a0000200241086a41086a2005413c6a290000370300200241086a41106a200541c4006a2d00003a00002002200541256a2f00003b01e8022002200541346a290000370308200541306a28000021102005412c6a2800002111200541286a28000021124104210b0b200a20076a2203200c3a0000200341016a20022f0198033b0000200341036a20022d009a033a00002003410c6a200d360000200341086a200e360000200341046a200f360000200341106a200229038802370000200341216a20022f0080033b0000200341186a20024188026a41086a290300370000200341206a20024188026a41106a2d00003a0000200341236a20024180036a41026a2d00003a0000200341246a200b3a0000200341286a20123600002003412c6a2011360000200341306a2010360000200341256a20022f01e8023b0000200341276a200241e8026a41026a2d00003a0000200341346a20022903083700002003413c6a200241086a41086a290300370000200341c4006a200241086a41106a2d00003a0000200341c5006a20022f00b0033b0000200341c7006a200241b0036a41026a2d00003a0000200741c8006a2107200841016a2108200541c8006a2009470d000b0b200241a8026a41086a2008360200200220022903c8033703a8024100211341002114024002400240024002400240200141106a2d00000e06050102030400050b200241cc026a200141136a2d00003a0000200241b8026a41086a200141286a290000370300200241b8026a41106a200141306a2d00003a00002002200141116a2f00003b01ca022002200141206a2900003703b8022001411c6a2800002103200141186a280000210a200141146a2800002108410521140c040b2001411c6a2802002203417f4c0d0e200141146a28020021070240024020030d0041002105410121080c010b200310332208450d10200321050b0240024020052003490d002005210a0c010b2005410174220b2003200b20034b1b220a4100480d11024020050d00200a10332208450d130c010b2005200a460d0020082005200a10372208450d120b200820072003109d081a410121140c030b41022114200241ca026a41026a200141136a2d00003a0000200241b8026a41086a200141286a290000370300200241b8026a41106a200141306a2d00003a00002002200141116a2f00003b01ca022002200141206a2900003703b8022001411c6a2800002103200141186a280000210a200141146a28000021080c020b200241cc026a200141136a2d00003a0000200241b8026a41086a200141286a290000370300200241b8026a41106a200141306a2d00003a00002002200141116a2f00003b01ca022002200141206a2900003703b8022001411c6a2800002103200141186a280000210a200141146a2800002108410321140c010b200241cc026a200141136a2d00003a0000200241b8026a41086a200141286a290000370300200241b8026a41106a200141306a2d00003a00002002200141116a2f00003b01ca022002200141206a2900003703b8022001411c6a2800002103200141186a280000210a200141146a2800002108410421140b024002400240024002400240200141346a2d00000e06050102030400050b200241e4026a200141376a2d00003a0000200241d8026a200141cc006a290000370300200241e0026a200141d4006a2d00003a00002002200141356a2f00003b01e2022002200141c4006a2900003703d002200141c0006a28000021052001413c6a2800002115200141386a280000210f410521130c040b200141c0006a2802002205417f4c0d0e200141386a280200210b0240024020050d00410021074101210f0c010b20051033220f450d10200521070b0240024020072005490d00200721150c010b2007410174220c2005200c20054b1b22154100480d11024020070d0020151033220f450d130c010b20072015460d00200f200720151037220f450d120b200f200b2005109d081a410121130c030b41022113200241e2026a41026a200141376a2d00003a0000200241d8026a200141cc006a290000370300200241e0026a200141d4006a2d00003a00002002200141356a2f00003b01e2022002200141c4006a2900003703d002200141c0006a28000021052001413c6a2800002115200141386a280000210f0c020b200241e4026a200141376a2d00003a0000200241d8026a200141cc006a290000370300200241e0026a200141d4006a2d00003a00002002200141356a2f00003b01e2022002200141c4006a2900003703d002200141c0006a28000021052001413c6a2800002115200141386a280000210f410321130c010b200241e4026a200141376a2d00003a0000200241d8026a200141cc006a290000370300200241e0026a200141d4006a2d00003a00002002200141356a2f00003b01e2022002200141c4006a2900003703d002200141c0006a28000021052001413c6a2800002115200141386a280000210f410421130b4100211641002117024002400240024002400240200141d8006a2d00000e06050102030400050b200241fc026a200141db006a2d00003a0000200241f0026a200141f0006a290000370300200241f8026a200141f8006a2d00003a00002002200141d9006a2f00003b01fa022002200141e8006a2900003703e802200141e4006a2800002107200141e0006a2800002118200141dc006a2800002112410521170c040b200141e4006a2802002207417f4c0d0e200141dc006a280200210c0240024020070d004100210b410121120c010b200710332212450d102007210b0b02400240200b2007490d00200b21180c010b200b410174220d2007200d20074b1b22184100480d110240200b0d00201810332212450d130c010b200b2018460d002012200b201810372212450d120b2012200c2007109d081a410121170c030b41022117200241fa026a41026a200141db006a2d00003a0000200241f0026a200141f0006a290000370300200241f8026a200141f8006a2d00003a00002002200141d9006a2f00003b01fa022002200141e8006a2900003703e802200141e4006a2800002107200141e0006a2800002118200141dc006a28000021120c020b200241fc026a200141db006a2d00003a0000200241f0026a200141f0006a290000370300200241f8026a200141f8006a2d00003a00002002200141d9006a2f00003b01fa022002200141e8006a2900003703e802200141e4006a2800002107200141e0006a2800002118200141dc006a2800002112410321170c010b200241fc026a200141db006a2d00003a0000200241f0026a200141f0006a290000370300200241f8026a200141f8006a2d00003a00002002200141d9006a2f00003b01fa022002200141e8006a2900003703e802200141e4006a2800002107200141e0006a2800002118200141dc006a2800002112410421170b024002400240024002400240200141fc006a2d00000e06050102030400050b20024194036a200141ff006a2d00003a000020024188036a20014194016a29000037030020024190036a2001419c016a2d00003a00002002200141fd006a2f00003b01920320022001418c016a2900003703800320014188016a280000210b20014184016a280000211920014180016a280000210e410521160c040b20014188016a280200220b417f4c0d0e20014180016a280200210d02400240200b0d004100210c4101210e0c010b200b1033220e450d10200b210c0b02400240200c200b490d00200c21190c010b200c4101742210200b2010200b4b1b22194100480d110240200c0d0020191033220e450d130c010b200c2019460d00200e200c20191037220e450d120b200e200d200b109d081a410121160c030b4102211620024192036a41026a200141ff006a2d00003a000020024188036a20014194016a29000037030020024190036a2001419c016a2d00003a00002002200141fd006a2f00003b01920320022001418c016a2900003703800320014188016a280000210b20014184016a280000211920014180016a280000210e0c020b20024194036a200141ff006a2d00003a000020024188036a20014194016a29000037030020024190036a2001419c016a2d00003a00002002200141fd006a2f00003b01920320022001418c016a2900003703800320014188016a280000210b20014184016a280000211920014180016a280000210e410321160c010b20024194036a200141ff006a2d00003a000020024188036a20014194016a29000037030020024190036a2001419c016a2d00003a00002002200141fd006a2f00003b01920320022001418c016a2900003703800320014188016a280000210b20014184016a280000211920014180016a280000210e410421160b4100211a4100211b024002400240024002400240200141a0016a2d00000e06050102030400050b200241ac036a200141a3016a2d00003a0000200241a0036a200141b8016a290000370300200241a8036a200141c0016a2d00003a00002002200141a1016a2f00003b01aa032002200141b0016a29000037039803200141ac016a280000210c200141a8016a280000211c200141a4016a28000021114105211b0c040b200141ac016a280200220c417f4c0d0e200141a4016a280200211002400240200c0d004100210d410121110c010b200c10332211450d10200c210d0b02400240200d200c490d00200d211c0c010b200d4101742206200c2006200c4b1b221c4100480d110240200d0d00201c10332211450d130c010b200d201c460d002011200d201c10372211450d120b20112010200c109d081a4101211b0c030b4102211b200241aa036a41026a200141a3016a2d00003a0000200241a0036a200141b8016a290000370300200241a8036a200141c0016a2d00003a00002002200141a1016a2f00003b01aa032002200141b0016a29000037039803200141ac016a280000210c200141a8016a280000211c200141a4016a28000021110c020b200241ac036a200141a3016a2d00003a0000200241a0036a200141b8016a290000370300200241a8036a200141c0016a2d00003a00002002200141a1016a2f00003b01aa032002200141b0016a29000037039803200141ac016a280000210c200141a8016a280000211c200141a4016a28000021114103211b0c010b200241ac036a200141a3016a2d00003a0000200241a0036a200141b8016a290000370300200241a8036a200141c0016a2d00003a00002002200141a1016a2f00003b01aa032002200141b0016a29000037039803200141ac016a280000210c200141a8016a280000211c200141a4016a28000021114104211b0b02402001418c026a2d00004101470d0020024198026a2001419d026a28000036020020024190026a20014195026a29000037030020022001418d026a290000370388024101211a0b4100211d4100211e024002400240024002400240200141c4016a2d00000e06050102030400050b200241c4036a200141c7016a2d00003a0000200241b8036a200141dc016a290000370300200241c0036a200141e4016a2d00003a00002002200141c5016a2f00003b01c2032002200141d4016a2900003703b003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021064105211e0c040b200141d0016a280200220d417f4c0d0e200141c8016a280200210902400240200d0d0041002110410121060c010b200d10332206450d10200d21100b024002402010200d490d002010211f0c010b2010410174221f200d201f200d4b1b221f4100480d11024020100d00201f10332206450d130c010b2010201f460d0020062010201f10372206450d120b20062009200d109d081a4101211e0c030b4102211e200241c2036a41026a200141c7016a2d00003a0000200241b8036a200141dc016a290000370300200241c0036a200141e4016a2d00003a00002002200141c5016a2f00003b01c2032002200141d4016a2900003703b003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021060c020b200241c4036a200141c7016a2d00003a0000200241b8036a200141dc016a290000370300200241c0036a200141e4016a2d00003a00002002200141c5016a2f00003b01c2032002200141d4016a2900003703b003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021064103211e0c010b200241c4036a200141c7016a2d00003a0000200241b8036a200141dc016a290000370300200241c0036a200141e4016a2d00003a00002002200141c5016a2f00003b01c2032002200141d4016a2900003703b003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021064104211e0b024002400240024002400240200141e8016a2d00000e06050102030400050b200241de036a200141eb016a2d00003a0000200241d0036a20014180026a290000370300200241d8036a20014188026a2d00003a00002002200141e9016a2f00003b01dc032002200141f8016a2900003703c803200141f4016a2800002110200141f0016a2800002120200141ec016a28000021094105211d0c040b200141f4016a2802002210417f4c0d0e200141ec016a280200211d0240024020100d0041002101410121090c010b201010332209450d10201021010b0240024020012010490d00200121200c010b200141017422202010202020104b1b22204100480d11024020010d00202010332209450d130c010b20012020460d0020092001202010372209450d120b2009201d2010109d081a4101211d0c030b4102211d200241dc036a41026a200141eb016a2d00003a0000200241d0036a20014180026a290000370300200241d8036a20014188026a2d00003a00002002200141e9016a2f00003b01dc032002200141f8016a2900003703c803200141f4016a2800002110200141f0016a2800002120200141ec016a28000021090c020b200241de036a200141eb016a2d00003a0000200241d0036a20014180026a290000370300200241d8036a20014188026a2d00003a00002002200141e9016a2f00003b01dc032002200141f8016a2900003703c803200141f4016a2800002110200141f0016a2800002120200141ec016a28000021094103211d0c010b200241de036a200141eb016a2d00003a0000200241d0036a20014180026a290000370300200241d8036a20014188026a2d00003a00002002200141e9016a2f00003b01dc032002200141f8016a2900003703c803200141f4016a2800002110200141f0016a2800002120200141ec016a28000021094104211d0b200241f8016a41086a2201200241a8026a41086a280200360200200241f4016a41026a2221200241ca026a41026a2d00003a0000200241e0016a41086a2222200241b8026a41086a290300370300200241e0016a41106a2223200241b8026a41106a2d00003a0000200241dc016a41026a2224200241b5026a41026a2d00003a0000200220022903a8023703f801200220022f01ca023b01f401200220022903b8023703e001200220022f00b5023b01dc01200241d8016a41026a2225200241e2026a41026a2d00003a0000200241c0016a41086a2226200241d0026a41086a290300370300200241c0016a41106a2227200241d0026a41106a2d00003a0000200241bc016a41026a2228200241cd026a41026a2d00003a0000200241b8016a41026a2229200241fa026a41026a2d00003a0000200220022f01e2023b01d801200220022903d0023703c001200220022f00cd023b01bc01200220022f01fa023b01b801200241a0016a41106a222a200241e8026a41106a2d00003a0000200241a0016a41086a222b200241e8026a41086a2903003703002002419c016a41026a222c200241e5026a41026a2d00003a000020024198016a41026a222d20024192036a41026a2d00003a000020024180016a41106a222e20024180036a41106a2d00003a000020024180016a41086a222f20024180036a41086a290300370300200220022903e8023703a001200220022f00e5023b019c01200220022f0192033b019801200220022903800337038001200241fc006a41026a2230200241fd026a41026a2d00003a0000200220022f00fd023b017c200241f8006a41026a2231200241aa036a41026a2d00003a0000200220022f01aa033b0178200241e0006a41106a223220024198036a41106a2d00003a0000200241e0006a41086a223320024198036a41086a2903003703002002200229039803370360200241dc006a41026a223420024195036a41026a2d00003a0000200220022f0095033b015c200241086a41106a223520024188026a41106a280200360200200241086a41086a223620024188026a41086a2903003703002002200229038802370308200241d8006a41026a2237200241c2036a41026a2d00003a0000200220022f01c2033b0158200241c0006a41106a2238200241b0036a41106a2d00003a0000200241c0006a41086a2239200241b0036a41086a290300370300200220022903b0033703402002413c6a41026a223a200241ad036a41026a2d00003a0000200220022f00ad033b013c200241386a41026a223b200241dc036a41026a2d00003a0000200220022f01dc033b0138200241206a41106a223c200241c8036a41106a2d00003a0000200241206a41086a223d200241c8036a41086a290300370300200220022903c8033703202002411c6a41026a223e200241c5036a41026a2d00003a0000200220022f00c5033b011c200041106a20143a00002000410c6a2001280200360200200041046a20022903f8013702002000411c6a2003360000200041186a200a360000200041146a2008360000200041116a20022f01f4013b0000200041136a20212d00003a0000200041206a20022903e001370000200041286a2022290300370000200041306a20232d00003a0000200041336a20242d00003a0000200041316a20022f01dc013b0000200041346a20133a0000200041376a20252d00003a0000200041356a20022f01d8013b0000200041c0006a20053600002000413c6a2015360000200041386a200f360000200041d4006a20272d00003a0000200041cc006a2026290300370000200041c4006a20022903c001370000200041d7006a20282d00003a0000200041d5006a20022f01bc013b0000200041d8006a20173a0000200041db006a20292d00003a0000200041d9006a20022f01b8013b0000200041e4006a2007360000200041e0006a2018360000200041dc006a2012360000200041f8006a202a2d00003a0000200041f0006a202b290300370000200041e8006a20022903a001370000200041fb006a202c2d00003a0000200041f9006a20022f019c013b0000200041fc006a20163a0000200041ff006a202d2d00003a0000200041fd006a20022f0198013b000020004188016a200b36000020004184016a201936000020004180016a200e3600002000419c016a202e2d00003a000020004194016a202f2903003700002000418c016a2002290380013700002000419f016a20302d00003a00002000419d016a20022f017c3b0000200041a0016a201b3a0000200041a3016a20312d00003a0000200041a1016a20022f01783b0000200041ac016a200c360000200041a8016a201c360000200041a4016a2011360000200041c0016a20322d00003a0000200041b8016a2033290300370000200041b0016a2002290360370000200041c3016a20342d00003a0000200041c1016a20022f015c3b0000200041c4016a201e3a0000200041c7016a20372d00003a0000200041c5016a20022f01583b0000200041d0016a200d360000200041cc016a201f360000200041c8016a2006360000200041e4016a20382d00003a0000200041dc016a2039290300370000200041d4016a2002290340370000200041e7016a203a2d00003a0000200041e5016a20022f013c3b0000200041e8016a201d3a0000200041eb016a203b2d00003a0000200041e9016a20022f01383b0000200041f4016a2010360000200041f0016a2020360000200041ec016a200936000020004188026a203c2d00003a000020004180026a203d290300370000200041f8016a20022903203700002000418b026a203e2d00003a000020004189026a20022f011c3b00002000418c026a201a3a00002000419d026a203528020036000020004195026a20362903003700002000418d026a2002290308370000200041a3026a20024188026a41026a2d00003a0000200041a1026a20022f0088023b0000200041023a00000c090b2001410c6a2802002203ad42c4007e2204422088a70d092004a72205417f4c0d09200141046a28020021060240024020050d00410421070c010b200510332207450d0b0b41002101200241003602b803200220073602b0032002200541c4006e3602b403200241b0036a41002003109f0120022802b803210b02402003450d002006200341c4006c6a210920022802b003200b41c4006c6a210a20024188026a41086a210c20024188026a41106a210d0340200c200620016a220541176a290000370300200d2005411f6a2d00003a0000200220052f01003b0198032002200541026a2d00003a009a0320022005410f6a290000370388022005410b6a2800002110200541076a2800002108200541036a280000210f41002107024002400240024002400240200541206a2d00000e06050102030400050b200241e8026a41026a200541236a2d00003a0000200241086a41086a200541386a290000370300200241086a41106a200541c0006a2d00003a00002002200541216a2f00003b01e8022002200541306a2900003703082005412c6a2800002111200541286a280000210e200541246a2800002112410521070c040b200241c8036a200541246a109f0320022802d003211120022802cc03210e20022802c8032112410121070c030b41022107200241e8026a41026a200541236a2d00003a0000200241086a41086a200541386a290000370300200241086a41106a200541c0006a2d00003a00002002200541216a2f00003b01e8022002200541306a2900003703082005412c6a2800002111200541286a280000210e200541246a28000021120c020b200241e8026a41026a200541236a2d00003a0000200241086a41086a200541386a290000370300200241086a41106a200541c0006a2d00003a00002002200541216a2f00003b01e8022002200541306a2900003703082005412c6a2800002111200541286a280000210e200541246a2800002112410321070c010b200241e8026a41026a200541236a2d00003a0000200241086a41086a200541386a290000370300200241086a41106a200541c0006a2d00003a00002002200541216a2f00003b01e8022002200541306a2900003703082005412c6a2800002111200541286a280000210e200541246a2800002112410421070b200a20016a220320022f0198033b0100200341026a20022d009a033a00002003410b6a2010360000200341076a2008360000200341036a200f3600002003410f6a200229038802370000200341176a200c2903003700002003411f6a200d2d00003a0000200341206a20073a0000200341216a20022f01e8023b0000200341236a200241e8026a41026a2d00003a00002003412c6a2011360000200341286a200e360000200341246a2012360000200341306a2002290308370000200341386a200241086a41086a290300370000200341c0006a200241086a41106a2d00003a0000200341c1006a20022f0080033b0000200341c3006a20024180036a41026a2d00003a0000200141c4006a2101200b41016a210b200541c4006a2009470d000b0b20024190026a200b360200200220022903b0032204370388022000410c6a200b360200200041046a2004370200200041033a00000c080b200041043a00000c070b200041053a0000200041106a200141106a290300370300200041086a200141086a290300370300200041046a200141046a2802003602000c060b200041063a0000200041046a200141046a2802003602000c050b200041073a0000200041106a200141106a290300370300200041086a200141086a290300370300200041046a200141046a2802003602000c040b200041083a000020002001290001370001200041246a200141246a280200360200200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c030b200041093a0000200041086a200141086a290300370300200041046a200141046a2802003602000c020b200141046a28020021054101210302400240200141086a2d00004101470d002001410c6a28020021070c010b2002410a6a2001410b6a2d00003a000020024188026a41086a200141186a29000037030020024188026a41106a200141206a29000037030020024188026a41186a200141286a2d00003a00002002200141096a2f00003b01082002200141106a290000370388022001410c6a2800002107410021030b200041086a20033a0000200041046a2005360200200041096a20022f01083b00002000410c6a2007360200200041106a2002290388023702002000410b6a2002410a6a2d00003a0000200041186a20024188026a41086a290300370200200041206a20024188026a41106a290300370200200041286a20024188026a41186a280200360200200141386a29030021042001350230213f200041c0006a200141c0006a290300370300200041386a2004370300200041306a203f3703002000410a3a00000c010b4101210302400240200141046a2d00004101470d00200141086a28020021050c010b2002410a6a200141076a2d00003a000020024188026a41086a200141146a29000037030020024198026a2001411c6a290000370300200241a0026a200141246a2d00003a00002002200141056a2f00003b010820022001410c6a29000037038802200141086a2800002105410021030b2000410b3a0000200041046a20033a0000200041056a20022f01083b0000200041086a20053602002000410c6a200229038802370200200041076a2002410a6a2d00003a0000200041146a20024188026a41086a2903003702002000411c6a20024198026a290300370200200041246a200241a0026a2802003602000b200241e0036a24000f0b1044000b1045000b103e000b103c000ba80901067f230041306b2202240002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410b4b0d0020030e0c0102030405060708090a0b0c010b41cfa2cc00412841c086cc00103f000b200041013a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0b0b200041023a0000200041046a200141046a2802003602000c0a0b200041033a000020002001290001370001200041c0006a200141c0006a290300370300200041386a200141386a290300370300200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c090b200041043a0000200041046a200141046a2802003602000c080b4101210302400240200141046a2d00004101470d00200141086a28020021040c010b2002410e6a200141076a2d00003a0000200241106a41086a200141146a290000370300200241206a2001411c6a290000370300200241286a200141246a2d00003a00002002200141056a2f00003b010c20022001410c6a290000370310200141086a2800002104410021030b200041053a0000200041046a20033a0000200041056a20022f010c3b0000200041086a20043602002000410c6a2002290310370200200041076a2002410e6a2d00003a0000200041146a200241106a41086a2903003702002000411c6a200241206a290300370200200041246a200241286a280200360200200020012d00014100473a00010c070b200041063a0000200020012d00014100473a00010c060b200041073a00000c050b200241286a200141196a290000370300200241206a200141116a290000370300200241186a200141096a29000037030020022001290001370310200141306a2802002203417f4c0d05200141286a2802002105200141246a28020021060240024020030d0041002101410121070c010b200310332207450d07200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d08024020010d002004103322070d010c0a0b20012004460d0020072001200410372207450d090b200720052003109d082101200041306a20033602002000412c6a2004360200200041286a2001360200200041246a2006360200200041083a0000200041196a200241286a290300370000200041116a200241206a290300370000200041096a200241106a41086a290300370000200020022903103700010c040b200041093a00000c030b2000410a3a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00004100473a00000c020b2000410b3a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c010b2000410c3a0000200041046a200141046a2802003602000b200241306a24000f0b1044000b1045000b103e000b103c000be90802097f017e230041306b220224000240024002400240024002400240024002400240024002400240024020012d0000417f6a220341084b0d0020030e09010203040506070809010b41cfa2cc00412841c086cc00103f000b200241186a2204200141196a290000370300200241106a2205200141116a290000370300200241086a2206200141096a2900003703002002200129000137030041b00210332203450d092003200141246a280200109b03200041246a2003360200200041013a0000200041196a2004290300370000200041116a2005290300370000200041096a2006290300370000200020022903003700010c080b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c070b2001410c6a280200220741ffffff3f712007470d0820074105742204417f4c0d08200141046a28020021060240024020040d00410121050c010b200410332205450d0a0b41002103200241003602082002200536020020022004410576360204200241002007108a012002280208210802402007450d0020074105742109200228020020084105746a210a0340200a20036a2204200620036a2205290000370000200441186a200541186a290000370000200441106a200541106a290000370000200441086a200541086a2900003700002009200341206a2203470d000b200741057441606a41057620086a41016a21080b200241286a200836020020022002290300220b370320200041046a200b3702002000410c6a2008360200200041033a0000200041106a2001280210360200200041026a20012f01023b01000c060b200041043a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c050b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c040b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c030b200041073a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c020b200041083a00000c010b200041093a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000b200241306a24000f0b103c000b1044000b1045000bda9b01070b7f017e097f027e037f017e177f230041a00a6b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341f4066a4101360200200342013702e406200341e8d4ca003602e0062003410436029c032003419cd5ca0036029803200320034198036a3602f006200341e0066a41b0b4cc00104c000b200341e8056a41026a2204200241076a2d00003a00002003200241056a2f00003b01e805200141046a28020022052001410c6a280200220641b0026c22076a2108200141086a280200210920052101024002402006450d00200241046a2d0000210a200241026a2f0100210b200241086a280200210c2002410c6a280200210d200241106a290200210e200241186a280200210f200241246a2d0000211020022d0001211120022d0000211220034198036a410272211320034198036a4105722114200741d07d6a2106200341bd036a2115200341c0066a4103722116200341e0066a41047221172002411c6a29020022184220882119200341de066a211a4100211b2005210103402001280200210220034198036a200141046a220741ac02109d081a200341e0066a200741ac02109d081a02402002411b470d00200141b0026a21010c2b0b200341e8006a200341e0066a41ac02109d081a200320023602e0062017200341e8006a41ac02109d081a024002400240024020120e03000102000b4102210202400240024020110e03000102000b410021020c010b201620032f01e8053b0000200320183e01da06201a20193d0100201641026a20042d00003a00002003200a3a00c2062003200b3b01c0062003200f3601d6062003200e3701ce062003200d3601ca062003200c3601c606410121020b201320032903c006370000201341086a200341c0066a41086a290300370000201341106a200341c0066a41106a290300370000201341186a200341c0066a41186a290300370000200320023a009903200341003a0098030c020b41022102024002400240200a0e03000102000b410021020c010b20034188066a41026a20042d00003a0000200320032f01e8053b018806410121020b201420032f0188063b0000201520032f00b8093b0000201441026a20034188066a41026a2d00003a0000201541026a200341b8096a41026a2d00003a0000200320023a009c03200320103a00bc03200320183702b4032003200f3602b0032003200e3703a8032003200d3602a4032003200c3602a003200341013a0098030c010b41022102024002400240200a0e03000102000b410021020c010b200341c4056a41026a20042d00003a0000200320032f01e8053b01c405201c41807e71201072211c410121020b201420032f01c4053b0000200341023a009803201441026a200341c4056a41026a2d00003a0000200320023a009c032003201c3602bc03200320183702b4032003200f3602b0032003200e3703a8032003200d3602a4032003200c3602a0030b20034190096a200341e0066a20034198036a10ac032003290390094201510d02201b41016a211b200641d07d6a2106200141b0026a22012008470d000b200821010b200341e0066a20034198036a41ac02109d081a0c280b20034198036a41186a200341b0096a290300220e37030020034198036a41106a20034190096a41186a290300221837030020034198036a41086a20034190096a41106a290300370300200320032903980937039803200341e0066a41086a201b360200200341ec066a2018370200200341f4066a200e3e0200200341003a00e406200341013a00e00641b0b4cc004100200341e0066a10d40102402006450d00200141b0026a21010340200110bb02200141b0026a2101200641d07d6a22060d000b0b2009450d28200941b0026c450d28200510350c280b41022106200141046a280200210820022d00000d0520022d00014101470d052002411a6a290100210e200241196a2d00002106200241186a2d00002107200241166a2f0100211b200241156a2d00002113200241146a2d00002114200241126a2f01002112200241116a2d00002117200241106a2d0000210a2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210f2002410a6a2f01002115200241096a2d0000211c200241086a2d00002110200241066a2f01002104200241056a2d00002105200241046a2d00002111200241026a2f01002102200141026a2f01002109411210332201450d03200141086a4100290085aa43370000200141002900fda94337000020014112413010372201450d042001200e370028200120063a0027200120073a00262001201b3b0024200120133a0023200120143a0022200120123b0020200120173a001f2001200a3a001e2001200c3b001c2001200d3a001b2001200f3a001a200120153b00182001201c3a0017200120103a0016200120043b0014200120053a0013200120113a0012200120023b00102001413041e00010372202450d04200220093b00302002ad4280808080a0068410092201290000210e200141086a2900002118200141106a2900002119200341c0066a41186a2206200141186a290000370300200341c0066a41106a22072019370300200341c0066a41086a221b20183703002003200e3703c0062001103520021035200341093a0080072003410a3a0080072003410b3a008007200320032f01c0063b01e006200320032801c2063601e206200320032f01c6063b01e6062003201b2f01003b01e806200320032d00ca063a00ea062003410c3a008007200320032d00cb063a00eb062003410d3a008007200320032d00cc063a00ec062003410e3a008007200320032d00cd063a00ed062003410f3a008007200320032d00ce063a00ee06200341103a008007200320032d00cf063a00ef06200341113a008007200320072d00003a00f006200320032d00d1063a00f106200341123a008007200341133a008007200320032d00d2063a00f206200341143a008007200320032d00d3063a00f306200341153a008007200320032d00d4063a00f406200341163a008007200320032d00d5063a00f506200341173a008007200320032d00d6063a00f606200341183a008007200320032d00d7063a00f706200341193a008007200320062d00003a00f806200320032d00d9063a00f9062003411a3a0080072003411b3a008007200320032d00da063a00fa062003411c3a008007200320032d00db063a00fb062003411d3a008007200320032d00dc063a00fc062003411e3a008007200320032d00dd063a00fd062003411f3a008007200320032d00de063a00fe06200341203a008007200320032d00df063a00ff0620034190096a41186a220120032903f80637030020034190096a41106a220220032903f00637030020034190096a41086a220620032903e806370300200320032903e006370390092006290300210e2002290300211820012903002119200329039009211d200341e0066a200841b002109d081a20034198036a411a6a201937010020034198036a41126a201837010020034198036a410a6a200e3701002003201d37019a0320034180023b019803200341e8006a200341e0066a20034198036a10ac030240024020032903684201520d0020032903704202520d010b200810354200210e0c260b200341e8006a411c6a2902002118200341e8006a41186a2802002106200810354200210e200641ff01714104460d25200641807e7121010c240b2001411c6a280200210841022106200141086a2802002107200141046a280200211b024020022d00000d0020022d00014101470d00200141186a280200211e200141146a280200211f200141106a2802002120200141026a2f010021062001410c6a2802002101200241196a2d00002113200241186a2d00002114200241166a2f01002112200241156a2d00002117200241146a2d0000210a200241126a2f0100210c200241116a2d0000210d200241106a2d0000210f2002410e6a2f010021152002410d6a2d0000211c2002410c6a2d000021102002410a6a2f01002104200241096a2d00002105200241086a2d00002111200241066a2f01002109200241056a2d00002116200241046a2d0000210b200241026a2f0100211a20032002411a6a2901003703e005200320133a00df05200320143a00de05200320123b01dc05200320173a00db052003200a3a00da052003200c3b01d8052003200d3a00d7052003200f3a00d605200320153b01d4052003201c3a00d305200320103a00d205200320043b01d005200320053a00cf05200320113a00ce05200320093b01cc05200320163a00cb052003200b3a00ca052003201a3b01c805200641ffff0371450d062001450d07200141e4004f0d08200320013602702003200736026c2003201b360268200341e0066a41186a200341c8056a41186a290300370300200341e0066a41106a200341c8056a41106a290300370300200341e0066a41086a2202200341c8056a41086a290300370300200320032903c8053703e00620034198036a200341e8006a200341e0066a10ad032003280298034101460d0920034198036a41086a2802002121200328029c032117200220034198036a410c6a280200360200200320063b01ec06200320173602e406200341fda9c3003602e006200341c0066a200341e0066a10ae03200341083a0080072003410b3a0080072003410c3a008007200320032f01c0063b01e006200320032801c2063601e206200320032d00c6063a00e606200320032800c7063600e706200320032d00cb063a00eb062003410d3a008007200320032d00cc063a00ec062003410e3a008007200320032d00cd063a00ed062003410f3a008007200320032d00ce063a00ee06200320032d00cf063a00ef06200341103a008007200341113a008007200320032d00d0063a00f006200341123a008007200320032d00d1063a00f106200341133a008007200320032d00d2063a00f206200341143a008007200320032d00d3063a00f306200341153a008007200320032d00d4063a00f406200341163a008007200320032d00d5063a00f506200341173a008007200320032d00d6063a00f606200320032d00d7063a00f706200341183a008007200341193a008007200320032d00d8063a00f8062003411a3a008007200320032d00d9063a00f9062003411b3a008007200320032d00da063a00fa062003411c3a008007200320032d00db063a00fb062003411d3a008007200320032d00dc063a00fc062003411e3a008007200320032d00dd063a00fd062003411f3a008007200320032d00de063a00fe06200341203a008007200320032d00df063a00ff0620034190096a41186a220220032903f80637030020034190096a41106a220720032903f00637030020034190096a41086a221b20032903e806370300200320032903e00637039009200341e8056a41186a2002290300370300200341e8056a41106a2007290300370300200341e8056a41086a201b29030037030020032003290390093703e805200341003602e806200342013703e0062008200341e0066a10af0320032802e406210720033502e80642208620032802e006221bad8410092202290018210e20022d0017210a20022d0016210c20022f0014210d20022d0013210f20022d0012211520022f0010211c20022d000f211020022d000e210420022f000c210520022d000b211120022d000a210920022f0008211620022d0007210b20022d0006211a20022f0004212220022d0003212320022d0002212420022f000021252002103502402007450d00201b10350b2003200e3703d8062003200a3a00d7062003200c3a00d6062003200d3b01d4062003200f3a00d306200320153a00d2062003201c3b01d006200320103a00cf06200320043a00ce06200320053b01cc06200320113a00cb06200320093a00ca06200320163b01c8062003200b3a00c7062003201a3a00c606200320223b01c406200320233a00c306200320243a00c206200320253b01c00620034198036a200341e8056a200341c0066a10b003200341e0066a200328029803220720032802a00310d302200341c0066a41086a221b200341e0066a41086a290300370300200341c0066a41106a2213200341e0066a41106a29030037030020034190096a41086a221420034188076a29030037030020034190096a41106a222620034190076a29030037030020034190096a41186a222720034198076a29030037030020034190096a41206a200341a0076a290300370300200320032903e0063703c0062003200341e0066a41206a2903003703900920032802fc062112024020032802f8062202450d00200341d8096a41106a2013290300370300200341d8096a41086a201b29030037030020034188066a41086a201429030037030020034188066a41106a202629030037030020034188066a41186a202729030037030020034188066a41206a20034190096a41206a290300370300200320032903c0063703d8092003200329039009370388060b0240200328029c03450d00200710350b02400240024002400240024020020d004101210720204101460d01200641ffff037141014b0d02200341e0066a200841b002109d081a200341a2036a200341f0056a290300370100200341aa036a200341e8056a41106a290300370100200341b2036a200341e8056a41186a29030037010020034180023b019803200320032903e80537019a03200341e8006a200341e0066a20034198036a10ac0320032903684201520d0320032003290081013703e006200320034188016a2800003600e706200341e8006a41186a2d00002106200341e8006a41106a290300210e20032903702218a70d042003418c016a28020021010c050b200341b4036a201236020020034198036a41206a20032903880637030020034198036a41106a200341d8096a41106a29030037030020034198036a41086a200341d8096a41086a290300370300200341c0036a20034188066a41086a290300370300200341c8036a20034188066a41106a290300370300200341d0036a20034188066a41186a290300370300200341d8036a20034188066a41206a290300370300200320032903d80937039803200320023602b0034101210702400240024002400240024020204101470d0020032802a803201f470d04200341ac036a280200201e470d0420032802b803222041014b0d014100210720200e020302030b2003410b36005f200341c8f1c20036005b20034181123b00580c280b410021072020211b0340201b410176221320076a22142007200220144105746a200341c8056a412010a0084101481b2107201b20136b221b41014b0d000b0b200220074105746a200341c8056a412010a008221b450d02201b411f7620076a21070b2006417f6a41ffff0371202041ffff03714b0d240c230b2003410e36005f200341baf1c20036005b20034181143b00580c240b200641ffff0371202041ffff03714d0d212003410f36005f200341aff2c20036005b20034181023b0058410121070c230b2003411336005f200341a7f1c20036005b20034181163b01584100211b4201211942002118410321060c250b200341186a2006ad42ffff038342004280a0e5b9c2910142001084082003200329031822194280c0dfda8ee9067c22183703682003200341186a41086a2903002018201954ad7c22193703702003200341c8056a3602b8092003200341c8056a36029009200320034190096a3602e8062003200341b8096a3602e4062003200341e8006a3602e00620034198036a200341c8056a200341e0066a108c03024002402003280298034101470d00200341a4036a280200210720034198036a41086a280200211b20032d009f03211320032d009e03211420032d009d03212020032d009c0321060c010b41042106024020034198036a41086a2903004201520d0020034198036a41106a290300211d200328029009210720034198076a20034198036a41186a29030037030020034190076a201d370300200341e0066a41086a41003a0000200341e9066a2007290000370000200341f1066a200741086a290000370000200341f9066a200741106a29000037000020034181076a200741186a290000370000200341033a00e00641b0b4cc004100200341e0066a10d4010b0b0240200641ff01714104470d0020034198036a41186a420037030020034198036a41106a2213420037030020034198036a41086a22074200370300200342003703980341d1c4c700ad4280808080e000841001221b290000211d200341e0066a41086a2206201b41086a2900003703002003201d3703e006201b103520072006290300370300200320032903e0063703980341e7c4c700ad4280808080e000841001221b290000211d2006201b41086a2900003703002003201d3703e006201b1035201320032903e006221d37030020034190096a41086a200729030037030020034190096a41106a201d37030020034190096a41186a2006290300370300200320032903980337039009200341106a20034190096a412010c001200328021421072003280210211b200341086a41c4c3c700411010c001200328020c21132003280208211420032f01c805212020032d00ca05211f20032d00cb05211e20032f01cc05212620032d00ce05212720032d00cf05212820032f01d005212920032d00d205212a20032d00d305212b20032f01d405212c20032d00d605212d20032d00d705212e20032f01d805212f20032d00da05213020032d00db05213120032f01dc05213220032d00de05213320032d00df05213420032903e005211d412010332206450d08200620032903c805370000200641186a200341c8056a41186a290300370000200641106a200341c8056a41106a290300370000200641086a200341c8056a41086a290300370000200341f4066a2013410020141b3602002003419c076a201d3702002003419b076a20343a00002003419a076a20333a000020034198076a20323b010020034197076a20313a000020034196076a20303a000020034194076a202f3b010020034193076a202e3a000020034192076a202d3a000020034190076a202c3b01002003418f076a202b3a00002003418e076a202a3a00002003418c076a20293b01002003418b076a20283a00002003418a076a20273a000020034188076a20263b010020034187076a201e3a000020034186076a201f3a0000200320193703e806200320183703e006200320074100201b1b3602f006200320203b018407200341fc066a428180808010370200200320063602f8062003200e3703d8062003200a3a00d7062003200c3a00d6062003200d3b01d4062003200f3a00d306200320153a00d2062003201c3b01d006200320103a00cf06200320043a00ce06200320053b01cc06200320113a00cb06200320093a00ca06200320163b01c8062003200b3a00c7062003201a3a00c606200320223b01c406200320233a00c306200320243a00c206200320253b01c00620034198036a200341e8056a200341c0066a10b0032003280298032106200320032802a00336026c20032006360268200341e0066a200341e8006a1099030240200328029c03450d00200610350b024020032802fc0641ffffff3f71450d0020032802f80610350b20034185076a20032903e805370000200341ed066a200341c8056a41086a290300370000200341f5066a200341c8056a41106a290300370000200341fd066a200341c8056a41186a2903003700002003418d076a200341e8056a41086a29030037000020034195076a200341e8056a41106a2903003700002003419d076a200341e8056a41186a290300370000200341023a00e40641012107200341013a00e006200320032903c8053700e506200341bd076a200e370000200341bc076a200a3a0000200341bb076a200c3a0000200341b9076a200d3b0000200341b8076a200f3a0000200341b7076a20153a0000200341b5076a201c3b0000200341b4076a20103a0000200341b3076a20043a0000200341b1076a20053b0000200341b0076a20113a0000200341af076a20093a0000200341ad076a20163b0000200341ac076a200b3a0000200341ab076a201a3a0000200341a9076a20223b0000200341a8076a20233a0000200341a7076a20243a0000200341a5076a20253b00004100211b41b0b4cc004100200341e0066a10d4012001ad4290a10f7e42c0c09bd8007c210e42002119420121180c250b2003200736005f2003201b36005b200320133a005a200320143a0059200320203a00584100211b4101210742012119420021180c240b420021190240024020032903704201510d00420021180c010b427f427f427f200341f8006a290300220e42808ece1c7c22182018200e541b220e2001ad4290a10f7e7c22182018200e541b220e42c0b2cd3b7c22182018200e541b210e420121180b0c1d0b427f427f427f200e42808ece1c7c22182018200e541b220e2001ad4290a10f7e7c22182018200e541b220e42c0b2cd3b7c22182018200e541b210e420121180b200320032800e70636005f200320032903e006370358420121190c1b0b200341023a00e006200341e0066a21010c180b200141286a2802002106200141246a28020021134102210820022d00000d1320022d00014101470d13200141196a290000210e200141186a2d0000211a200141176a2d00002120200141156a2f0000211f200141146a2d0000211e200141136a2d00002122200141116a2f00002123200141106a2d000021242001410f6a2d000021252001410d6a2f000021212001410c6a2d000021262001410b6a2d00002127200141096a2f00002128200141086a2d00002129200141076a2d0000212a200141056a2f0000212b200141046a2d0000212c200141036a2d0000212d2001412c6a2802002107200141386a2802002131200141346a2802002130200141306a280200212f200141226a2f0100211420012f0001212e200241196a2d00002101200241186a2d00002108200241166a2f0100211b200241156a2d00002112200241146a2d00002117200241126a2f0100210a200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210f2002410d6a2d000021152002410c6a2d0000211c2002410a6a2f01002110200241096a2d00002104200241086a2d00002105200241066a2f01002111200241056a2d00002109200241046a2d00002116200241026a2f0100210b20032002411a6a2901003703d009200320013a00cf09200320083a00ce092003201b3b01cc09200320123a00cb09200320173a00ca092003200a3b01c8092003200c3a00c7092003200d3a00c6092003200f3b01c409200320153a00c3092003201c3a00c209200320103b01c009200320043a00bf09200320053a00be09200320113b01bc09200320093a00bb09200320163a00ba092003200b3b01b809024020140d0041c0d7ca00211b410d210741032108410021020c150b41032108024020070d00418df2c200211b41112107410321020c150b0240200741e3004d0d0041fbf1c200211b41122107410421020c150b200320073602702003200636026c20032013360268200341e0066a41186a200341b8096a41186a290300370300200341e0066a41106a2202200341b8096a41106a290300370300200341e0066a41086a2201200341b8096a41086a290300370300200320032903b8093703e00620034198036a200341e8006a200341e0066a10ad0302402003280298034101460d0020034198036a41086a2802002112200328029c032113200120034198036a410c6a280200360200200320143b01ec06200320133602e406200341fda9c3003602e006200341c0066a200341e0066a10ae03200341083a0080072003410b3a0080072003410c3a008007200320032f01c0063b01e006200320032801c2063601e206200320032d00c6063a00e606200320032800c7063600e706200320032d00cb063a00eb062003410d3a008007200320032d00cc063a00ec062003410e3a008007200320032d00cd063a00ed062003410f3a008007200320032d00ce063a00ee06200320032d00cf063a00ef06200341103a008007200341113a008007200320032d00d0063a00f006200341123a008007200320032d00d1063a00f106200341133a008007200320032d00d2063a00f206200341143a008007200320032d00d3063a00f306200341153a008007200320032d00d4063a00f406200341163a008007200320032d00d5063a00f506200341173a008007200320032d00d6063a00f606200320032d00d7063a00f706200341183a008007200341193a008007200320032d00d8063a00f8062003411a3a008007200320032d00d9063a00f9062003411b3a008007200320032d00da063a00fa062003411c3a008007200320032d00db063a00fb062003411d3a008007200320032d00dc063a00fc062003411e3a008007200320032d00dd063a00fd062003411f3a008007200320032d00de063a00fe06200320032d00df063a00ff06200341203a00800720034190096a41186a220820032903f80637030020034190096a41106a220620032903f00637030020034190096a41086a220720032903e806370300200320032903e0063703900920034188066a41186a200829030037030020034188066a41106a200629030037030020034188066a41086a20072903003703002003200329039009370388062003200e3703d8062003201a3a00d706200320203a00d6062003201f3b01d4062003201e3a00d306200320223a00d206200320233b01d006200320243a00cf06200320253a00ce06200320213b01cc06200320263a00cb06200320273a00ca06200320283b01c806200320293a00c7062003202a3a00c6062003202b3b01c4062003202c3a00c3062003202d3a00c2062003202e3b01c00620034198036a20034188066a200341c0066a10b003200341e0066a200328029803221b20032802a00310d302200341c0066a41086a2001290300370300200341c0066a41106a2002290300370300200720034188076a290300370300200620034190076a290300370300200820034198076a29030037030020034190096a41206a2202200341a0076a290300370300200320032903e0063703c0062003200341e0066a41206a2903003703900920032802fc062106024020032802f8062201450d00200341e8056a41106a200341c0066a41106a290300370300200341e8056a41086a200341c0066a41086a290300370300200341e8006a41086a20034190096a41086a290300370300200341e8006a41106a20034190096a41106a290300370300200341e8006a41186a20034190096a41186a290300370300200341e8006a41206a2002290300370300200320032903c0063703e80520032003290390093703680b0240200328029c03450d00201b10350b0240024020010d004101210141032108201441014b0d01419ef2c200211b41112107410221020c140b200341b4036a200636020020034198036a41206a200329036837030020034198036a41106a200341e8056a41106a29030037030020034198036a41086a200341e8056a41086a290300370300200341c0036a200341e8006a41086a290300370300200341c8036a200341e8006a41106a290300370300200341d0036a200341e8006a41186a290300370300200341d8036a200341e8006a41206a290300370300200320032903e80537039803200320013602b0030240202f4101460d0041c8f1c200211b410b2107410921020c130b41baf1c200211b410e2107410a210220032802a8032030470d12200341ac036a2802002031470d12024020032802b80322172014490d00419ef2c200211b41112107410221020c130b410021020240201741014b0d00024020170e020010000b200341e0066a41186a200341b8096a41186a290300370300200341e0066a41106a200341b8096a41106a290300370300200341e0066a41086a200341b8096a41086a290300370300200320032903b8093703e00641002102200341e0066a21080c100b2017210803402008410176220720026a221b20022001201b4105746a200341b8096a412010a0084101481b2102200820076b220841014b0d000c0f0b0b410121010240202f4101470d0041a7f1c200211b41132107410b21020c130b200341386a2014ad42004280a0e5b9c2910142001084082003200329033822194280c0dfda8ee9067c2218370390092003200341386a41086a2903002018201954ad7c2219370398092003200341b8096a3602c8052003200341b8096a3602c0062003200341c0066a3602e8062003200341c8056a3602e406200320034190096a3602e00620034198036a200341b8096a200341e0066a108c03024002402003280298034101470d00200341a4036a280200210720034198036a41086a280200211b20032d009f03210620032d009e03210220032d009d03210120032d009c0321080c010b41042108024020034198036a41086a2903004201520d0020034198036a41106a290300211d20032802c006210120034198076a20034198036a41186a29030037030020034190076a201d370300200341e0066a41086a41003a0000200341e9066a2001290000370000200341f1066a200141086a290000370000200341f9066a200141106a29000037000020034181076a200141186a290000370000200341033a00e00641b0b4cc004100200341e0066a10d4010b0b200841ff01714104470d1320034198036a41186a420037030020034198036a41106a2206420037030020034198036a41086a22024200370300200342003703980341d1c4c700ad4280808080e0008410012208290000211d200341e0066a41086a2201200841086a2900003703002003201d3703e0062008103520022001290300370300200320032903e0063703980341e7c4c700ad4280808080e0008410012208290000211d2001200841086a2900003703002003201d3703e00620081035200620032903e006221d37030020034190096a41086a200229030037030020034190096a41106a201d37030020034190096a41186a2001290300370300200320032903980337039009200341306a20034190096a412010c0012003280234210220032802302108200341286a41c4c3c700411010c001200328022c21062003280228210720032f01b809211b20032d00ba09211420032d00bb09211720032f01bc09210a20032d00be09210c20032d00bf09210d20032f01c009210f20032d00c209211520032d00c309211c20032f01c409211020032d00c609210420032d00c709210520032f01c809211120032d00ca09210920032d00cb09211620032f01cc09210b20032d00ce09212f20032d00cf09213020032903d009211d412010332201450d03200120032903b809370000200141186a200341b8096a41186a290300370000200141106a200341b8096a41106a290300370000200141086a200341b8096a41086a290300370000200341f4066a2006410020071b3602002003419c076a201d3702002003419b076a20303a00002003419a076a202f3a000020034198076a200b3b010020034197076a20163a000020034196076a20093a000020034194076a20113b010020034193076a20053a000020034192076a20043a000020034190076a20103b01002003418f076a201c3a00002003418e076a20153a00002003418c076a200f3b01002003418b076a200d3a00002003418a076a200c3a000020034188076a200a3b010020034187076a20173a000020034186076a20143a0000200320193703e806200320183703e00620032002410020081b3602f0062003201b3b018407200341fc066a428180808010370200200320013602f8062003200e3703d8062003201a3a00d706200320203a00d6062003201f3b01d4062003201e3a00d306200320223a00d206200320233b01d006200320243a00cf06200320253a00ce06200320213b01cc06200320263a00cb06200320273a00ca06200320283b01c806200320293a00c7062003202a3a00c6062003202b3b01c4062003202c3a00c3062003202d3a00c2062003202e3b01c00620034198036a20034188066a200341c0066a10b0032003280298032101200320032802a003360294092003200136029009200341e0066a20034190096a1099030240200328029c03450d00200110350b024020032802fc0641ffffff3f71450d0020032802f80610350b20034185076a200329038806370000200341ed066a200341b8096a41086a290300370000200341f5066a200341b8096a41106a290300370000200341fd066a200341b8096a41186a2903003700002003418d076a20034188066a41086a29030037000020034195076a20034188066a41106a2903003700002003419d076a20034188066a41186a290300370000200341023a00e406200341013a00e006200320032903b8093700e506200341bd076a200e370000200341bc076a201a3a0000200341bb076a20203a0000200341b9076a201f3b0000200341b8076a201e3a0000200341b7076a20223a0000200341b5076a20233b0000200341b4076a20243a0000200341b3076a20253a0000200341b1076a20213b0000200341b0076a20263a0000200341af076a20273a0000200341ad076a20283b0000200341ac076a20293a0000200341ab076a202a3a0000200341a9076a202b3b0000200341a8076a202c3a0000200341a7076a202d3a0000200341a5076a202e3b000041b0b4cc004100200341e0066a10d4010c0f0b4200210e200328029c03220841ff01714104460d16200841187621062008411076210220084108762101200341a4036a280200210720034198036a41086a280200211b0c150b2001412c6a2802002106200141286a2802002108200141246a280200211b200141346a2802002114200141306a2802002113200141226a2f01002107200341e8056a41186a200141196a290000370300200341e8056a41106a200141116a290000370300200341e8056a41086a200141096a290000370300200320012900013703e8054102210120022d00000d0720022d00014101470d07200241196a2d00002101200241186a2d00002112200241166a2f01002117200241156a2d0000210a200241146a2d0000210c200241126a2f0100210d200241116a2d0000210f200241106a2d000021152002410e6a2f0100211c2002410d6a2d000021102002410c6a2d000021042002410a6a2f01002105200241096a2d00002111200241086a2d00002109200241066a2f01002116200241056a2d0000210b200241046a2d0000211a200241026a2f0100212020032002411a6a2901003703d009200320013a00cf09200320123a00ce09200320173b01cc092003200a3a00cb092003200c3a00ca092003200d3b01c8092003200f3a00c709200320153a00c6092003201c3b01c409200320103a00c309200320043a00c209200320053b01c009200320113a00bf09200320093a00be09200320163b01bc092003200b3a00bb092003201a3a00ba09200320203b01b8090240200741ffff03710d0041c0d7ca002107410d210641032101410021020c090b41032101024020060d00418df2c200210741112106410321020c090b0240200641e3004d0d0041fbf1c200210741122106410421020c090b200320063602702003200836026c2003201b360268200341e0066a41186a200341b8096a41186a290300370300200341e0066a41106a2202200341b8096a41106a290300370300200341e0066a41086a2201200341b8096a41086a290300370300200320032903b8093703e00620034198036a200341e8006a200341e0066a10ad0302402003280298034101460d0020034198036a41086a2802002112200328029c03211b200120034198036a410c6a280200360200200320073b01ec062003201b3602e406200341fda9c3003602e006200341c0066a200341e0066a10ae03200341083a0080072003410b3a0080072003410c3a008007200320032f01c0063b01e006200320032801c2063601e206200320032d00c6063a00e606200320032800c7063600e706200320032d00cb063a00eb062003410d3a008007200320032d00cc063a00ec062003410e3a008007200320032d00cd063a00ed062003410f3a008007200320032d00ce063a00ee06200320032d00cf063a00ef06200341103a008007200341113a008007200320032d00d0063a00f006200341123a008007200320032d00d1063a00f106200341133a008007200320032d00d2063a00f206200341143a008007200320032d00d3063a00f306200341153a008007200320032d00d4063a00f406200341163a008007200320032d00d5063a00f506200341173a008007200320032d00d6063a00f606200320032d00d7063a00f706200341183a008007200341193a008007200320032d00d8063a00f8062003411a3a008007200320032d00d9063a00f9062003411b3a008007200320032d00da063a00fa062003411c3a008007200320032d00db063a00fb062003411d3a008007200320032d00dc063a00fc062003411e3a008007200320032d00dd063a00fd062003411f3a008007200320032d00de063a00fe06200320032d00df063a00ff06200341203a00800720034190096a41186a220820032903f80637030020034190096a41106a220620032903f00637030020034190096a41086a220720032903e806370300200320032903e0063703900920034188066a41186a200829030037030020034188066a41106a200629030037030020034188066a41086a20072903003703002003200329039009370388062003200341e8056a41186a2903003703d8062003200341e8056a41106a2903003703d0062003200341e8056a41086a2903003703c806200320032903e8053703c006200341900a6a20034188066a200341c0066a10b003200341e0066a20032802900a221720032802980a10d302200341c0066a41086a2001290300370300200341c0066a41106a2002290300370300200720034188076a290300370300200620034190076a290300370300200820034198076a29030037030020034190096a41206a2202200341a0076a290300370300200320032903e0063703c0062003200341e0066a41206a2903003703900902400240024020032802f8062201450d0020032802fc062108200341f8096a41106a2206200341c0066a41106a290300370300200341f8096a41086a2207200341c0066a41086a290300370300200341e8006a41086a220a20034190096a41086a290300370300200341e8006a41106a220c20034190096a41106a290300370300200341e8006a41186a220d20034190096a41186a290300370300200341e8006a41206a2002290300370300200320032903c0063703f8092003200329039009370368024020032802940a450d00201710350b200341c8056a41166a2006290300220e370100410e2106200341c8056a410e6a2007290300370100200341d8096a41166a2202200e370100200341d8096a41106a200341c8056a41106a290100370300200320032903f8093701ce05200341d8096a41086a200341c8056a41086a290100370300200320032901c8053703d80920034198036a41106a2217200229010037030020034198036a41086a200341d8096a410e6a290100370300200320032901de0937039803200341b4036a2008360200200320013602b003200341d8036a200341e8006a41206a290300370300200341d0036a200d290300370300200341c8036a200c290300370300200341c0036a200a29030037030020034198036a41206a200329036837030041baf1c2002107410a2102024020172802002013470d00200341ac036a2802002014470d00200341bc036a2202200341b8096a412010a008450d0341fbb5c300210741082102410821060b200841ffffff3f71450d01200110350c010b024020032802940a450d00201710350b41d0b9c300210741082106410721020b0240201241ffffff3f71450d00201b10350b41002108418002211b410321010c0b0b200329039803210e200320034198036a41086a2903002218370398092003200e370390090240200e201884500d00200320023602c006200341e8006a200220034190096a200341c0066a10f00220032903684201520d002003290370210e20034198076a200341e8006a41106a29030037030020034190076a200e370300200341e0066a41086a41003a0000200341e9066a2002290000370000200341f1066a200241086a290000370000200341f9066a200241106a29000037000020034181076a200241186a290000370000200341033a00e00641b0b4cc004100200341e0066a10d4010b200341c0066a41186a200341e8056a41186a2201290300370300200341c0066a41106a200341e8056a41106a2202290300370300200341c0066a41086a200341e8056a41086a290300370300200320032903e8053703c006200341e0066a20034188066a200341c0066a10b00320033502e80642208620032802e0062208ad841007024020032802e406450d00200810350b20034185076a200329038806370000200341ed066a200341b8096a41086a290300370000200341f5066a200341b8096a41106a290300370000200341fd066a200341b8096a41186a2903003700002003418d076a20034188066a41086a29030037000020034195076a20034188066a41106a2903003700002003419d076a20034188066a41186a290300370000200341053a00e406200341013a00e006200320032903b8093700e506200341c8076a2013360200200341cc076a2014360200200341bd076a2001290300370000200341b5076a2002290300370000200341ad076a200341e8056a41086a290300370000200341a5076a20032903e80537000041b0b4cc004100200341e0066a10d401024020032802b40341ffffff3f71450d0020032802b00310350b0240201241ffffff3f71450d00201b10350b4200210e0c0b0b4200210e200328029c03220141ff01714104460d0a2001418080807871210820014110762102200141807e71211b200341a4036a280200210620034198036a41086a28020021070c090b1045000b103c000b200810ba0220081035410021010c1e0b200341e8066a410d360200200341c0d7ca003602e406200341003a00e20620034183023b01e006200341e0066a2101410321060c120b200341e8066a41113602002003418df2c2003602e40641032106200341033a00e20620034183023b01e006200341e0066a21010c110b200341e8066a4112360200200341fbf1c2003602e406200341043a00e20620034183023b01e006200341e0066a2101410321060c100b2003200329009d033703582003200341a4036a28000036005f20032d009c032106200810ba0220081035420021180c100b0b0240200841ffffff3f71450d00201b10350b41002108418002211b0b200041206a20063602002000411c6a2007360200200041186a2008200241ff017141107472201b4180fe037172200141ff0171723602004201210e0b2000200e370300200042003703080c1a0b0240200120024105746a200341b8096a412010a00822070d0041aff2c200211b410f2107410121020c040b200341e0066a41186a200341b8096a41186a290300370300200341e0066a41106a200341b8096a41106a290300370300200341e0066a41086a200341b8096a41086a290300370300200320032903b8093703e006200341e0066a210820172007411f7620026a2202490d020b024020172006470d0020034198036a41186a20064101108a0120032802b00321010b200120024105746a220141206a2001201720026b410574109e081a200141186a200841186a290000370000200141106a200841106a290000370000200141086a200841086a290000370000200120082900003700002003201741016a3602b803200341e0066a20034198036a41c800109d081a2003200e3703d8062003201a3a00d706200320203a00d6062003201f3b01d4062003201e3a00d306200320223a00d206200320233b01d006200320243a00cf06200320253a00ce06200320213b01cc06200320263a00cb06200320273a00ca06200320283b01c806200320293a00c7062003202a3a00c6062003202b3b01c4062003202c3a00c3062003202d3a00c2062003202e3b01c00620034190096a20034188066a200341c0066a10b003200328029009210120032003280298093602c406200320013602c006200341e0066a200341c0066a1099030240200328029409450d00200110350b0240200341fc066a28020041ffffff3f71450d0020032802f80610350b20034185076a200329038806370000200341ed066a200341b8096a41086a290300370000200341f5066a200341b8096a41106a290300370000200341fd066a200341b8096a41186a2903003700002003418d076a20034188066a41086a29030037000020034195076a20034188066a41106a2903003700002003419d076a20034188066a41186a290300370000200341033a00e406200341013a00e006200320032903b8093700e506200341cc076a2031360200200341c8076a2030360200200341bd076a200e370000200341bc076a201a3a0000200341bb076a20203a0000200341b9076a201f3b0000200341b8076a201e3a0000200341b7076a20223a0000200341b5076a20233b0000200341b4076a20243a0000200341b3076a20253a0000200341b1076a20213b0000200341b0076a20263a0000200341af076a20273a0000200341ad076a20283b0000200341ac076a20293a0000200341ab076a202a3a0000200341a9076a202b3b0000200341a8076a202c3a0000200341a7076a202d3a0000200341a5076a202e3b000041b0b4cc004100200341e0066a10d4010b0240201241ffffff3f71450d00201310350b4200210e0c070b20022017104d000b0240200641ffffff3f71450d00200110350b41032108410121010b0b201241ffffff3f71450d02201310350c020b0b410121010240200641ffffff3f710d000c010b201310350b200041206a20073602002000411c6a201b360200200041186a2006411874200241ff017141107472200141ff017141087472200841ff0171723602004201210e0b2000200e370300200042003703080c0f0b200320012900013703582003200141086a28000036005f200810ba022008103542002118200741ffffff3f71450d00201b10350b0c080b410021074100211b0c060b200341e0066a200841b002109d081a200341f2006a200341e8056a41086a290300370100200341fa006a200341f8056a29030037010020034182016a20034180066a29030037010020034180023b0168200320032903e80537016a20034190096a200341e0066a200341e8006a10ac032003290398032118200320034198036a41086a29030022193703c009200320183703b80902402018201984500d002003200341bc036a22013602c006200341e8006a2001200341b8096a200341c0066a10f00220032903684201520d002003290370211820034198076a200341e8006a41106a29030037030020034190076a2018370300200341e0066a41086a41003a0000200341e9066a2001290000370000200341f1066a200141086a290000370000200341f9066a200141106a29000037000020034181076a200141186a290000370000200341033a00e00641b0b4cc004100200341e0066a10d4010b2003200e3703d8062003200a3a00d7062003200c3a00d6062003200d3b01d4062003200f3a00d306200320153a00d2062003201c3b01d006200320103a00cf06200320043a00ce06200320053b01cc06200320113a00cb06200320093a00ca06200320163b01c8062003200b3a00c7062003201a3a00c606200320223b01c406200320233a00c306200320243a00c206200320253b01c006200341e0066a200341e8056a200341c0066a10b00320033502e80642208620032802e0062201ad841007024020032802e406450d00200110350b200341e8006a41186a200341c8056a41186a290300370300200341e8006a41106a200341c8056a41106a290300370300200341e8006a41086a200341c8056a41086a290300370300200320032903c805370368200341e0066a41186a200341e8056a41186a290300370300200341e0066a41106a200341e8056a41106a290300370300200341e0066a41086a200341e8056a41086a290300370300200320032903e8053703e00620034190096a41186a2d0000210620032903980921192003290390092118200320032900a9093703b8092003200341b0096a2800003600bf090240024020184201510d00410421010c010b200320032800bf093600ff09200320032903b8093703f8094104210120194202510d00200320032800ff093600970a200320032903f8093703900a200621010b200341b8096a41086a2206200341e8006a41086a290300370300200341b8096a41106a2207200341e8006a41106a290300370300200341b8096a41186a221b200341e8006a41186a290300370300200341c0066a41086a2213200341e0066a41086a290300370300200341c0066a41106a2214200341e0066a41106a290300370300200341c0066a41186a2220200341e0066a41186a290300370300200320032903683703b809200320032903e0063703c006200320032800970a3600b706200320032903900a3703b006200341ed066a2006290300370000200341f5066a2007290300370000200341fd066a201b29030037000020034185076a20032903c0063700002003418d076a201329030037000020034195076a20142903003700002003419d076a2020290300370000200341043a00e406200341013a00e006200320032903b8093700e506200341bd076a200e370000200341bc076a200a3a0000200341bb076a200c3a0000200341b9076a200d3b0000200341b8076a200f3a0000200341b7076a20153a0000200341b5076a201c3b0000200341b4076a20103a0000200341b3076a20043a0000200341b1076a20053b0000200341b0076a20113a0000200341af076a20093a0000200341ad076a20163b0000200341ac076a200b3a0000200341ab076a201a3a0000200341a9076a20223b0000200341a8076a20233a0000200341a7076a20243a0000200341a5076a20253b0000200341d0076a20013a0000200341cc076a201e360200200341c8076a201f360200200341c7076a200341c6056a2d00003a0000200341c5076a20032f00c4053b0000200341d8076a20032800b706360000200341d1076a20032903b0063700004100210741b0b4cc004100200341e0066a10d4014200211920032802b40321010c020b200341e0066a41186a200341c8056a41186a290300370300200341e0066a41106a200341c8056a41106a290300370300200341e0066a41086a200341c8056a41086a290300370300200320032903c8053703e006024020202007490d0020022106024020202012470d0020034198036a41186a20124101108a0120032802b00321060b200620074105746a220641206a2006202020076b410574109e081a200641186a200341e0066a41186a290300370000200641106a200341e0066a41106a290300370000200641086a200341e0066a41086a290300370000200620032903e0063700002003202041016a3602b803200341e0066a20034198036a41c800109d081a2003200e3703d8062003200a3a00d7062003200c3a00d6062003200d3b01d4062003200f3a00d306200320153a00d2062003201c3b01d006200320103a00cf06200320043a00ce06200320053b01cc06200320113a00cb06200320093a00ca06200320163b01c8062003200b3a00c7062003201a3a00c606200320223b01c406200320233a00c306200320243a00c206200320253b01c006200341e8006a200341e8056a200341c0066a10b0032003280268210620032003280270360294092003200636029009200341e0066a20034190096a1099030240200328026c450d00200610350b0240200341fc066a28020041ffffff3f71450d0020032802f80610350b20034185076a20032903e805370000200341ed066a200341c8056a41086a290300370000200341f5066a200341c8056a41106a290300370000200341fd066a200341c8056a41186a2903003700002003418d076a200341e8056a41086a29030037000020034195076a200341e8056a41106a2903003700002003419d076a200341e8056a41186a290300370000200341033a00e40641012107200341013a00e006200320032903c8053700e506200341cc076a201e360200200341c8076a201f360200200341bd076a200e370000200341bc076a200a3a0000200341bb076a200c3a0000200341b9076a200d3b0000200341b8076a200f3a0000200341b7076a20153a0000200341b5076a201c3b0000200341b4076a20103a0000200341b3076a20043a0000200341b1076a20053b0000200341b0076a20113a0000200341af076a20093a0000200341ad076a20163b0000200341ac076a200b3a0000200341ab076a201a3a0000200341a9076a20223b0000200341a8076a20233a0000200341a7076a20243a0000200341a5076a20253b000041b0b4cc004100200341e0066a10d4012001ad4290a10f7e42c0c09bd8007c210e42002119420121180c030b20072020104d000b42012119201221010b420021180240200141ffffff3f710d000c010b20032802b00310350b4101211b410321060b0b0240202141ffffff3f71450d00201710350b0240201241ffffff3f71450d00200245201b720d00200210350b02402007450d00200810ba020b20081035201950450d0020002018370308200041106a200e370300200042003703000c050b2003200328005f36004f20032003290358370348200041186a20063a0000200041106a200e3703002000201837030820002003290348370019200041206a200328004f360000200041246a2001360200200042013703000c040b2000411c6a2018370200200041186a2001200641ff0171723602004201210e0b2000200e370300200042003703080c020b024020082001460d000340200110bb022008200141b0026a2201470d000b0b02402009450d00200941b0026c450d00200510350b200341013a00e406200341013a00e00641b0b4cc004100200341e0066a10d4010b20004200370300200041086a42003703000b200341a00a6a24000bebca010a017f017e017f017e017f017e057f017e287f0c7e230041f0116b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1b010200030405060708090a0b0c0d0e0f1011121300000014151617010b000b20034198066a41086a200141106a2903003703002003200141086a29030037039806200341a80b6a41206a200241206a290200370300200341a80b6a41186a200241186a290200370300200341a80b6a41106a200241106a290200370300200341a80b6a41086a200241086a290200370300200320022902003703a80b200020034198066a200341a80b6a1085060c280b200341e00b6a2001413c6a280200360200200341d80b6a200141346a290200370300200341d00b6a2001412c6a290200370300200341a80b6a41206a200141246a290200370300200341a80b6a41186a2001411c6a290200370300200341a80b6a41106a200141146a290200370300200341a80b6a41086a2001410c6a290200370300200320012902043703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a10ab030c270b0240024020022d00000d0020022d000141ff01714102470d00200141086a2903002104200341a80b6a41186a22054200370300200341a80b6a41106a22014200370300200341a80b6a41086a22024200370300200342003703a80b41d1efcb00ad42808080809001842206100122072900002108200341a0116a41086a2209200741086a290000370300200320083703a0112007103520022009290300370300200320032903a0113703a80b41daefcb00ad42808080809001841001220a2900002108200341f8106a41086a2207200a41086a290000370300200320083703f810200a1035200120032903f810220837030020034198066a41086a220b200229030037030020034198066a41106a220c200837030020034198066a41186a220d2007290300370300200320032903a80b37039806200341186a20034198066a412041b0b4cc0041004100108a0220032802184101460d16200542003703002001420037030020024200370300200342003703a80b20061001220a29000021062009200a41086a290000370300200320063703a011200a103520022009290300370300200320032903a0113703a80b41ebc3c400ad4280808080308422061001220929000021082007200941086a290000370300200320083703f81020091035200120032903f810370000200141086a2007290300370000200b2002290300370300200c2001290300370300200d2005290300370300200320032903a80b37039806200341086a20034198066a10e1022003290310220842dc0b7c2004580d012008500d012003280208450d0141beebc40041ce0041c086cc00103f000b20004200370308200041186a4102360200200042013703000c270b200341a80b6a41186a22094200370300200341a80b6a41106a22074200370300200341a80b6a41086a22024200370300200342003703a80b41d1efcb00ad428080808090018422081001220a290000210e200341a0116a41086a2205200a41086a2900003703002003200e3703a011200a103520022005290300370300200320032903a0113703a80b20061001220b2900002106200341f8106a41086a220a200b41086a290000370300200320063703f810200b1035200120032903f810370000200141086a220c200a29030037000020034198066a41086a220d200229030037030020034198066a41106a220f200729030037030020034198066a41186a22102009290300370300200320032903a80b37039806200320043703a80b20034198066aad42808080808004842204200341a80b6aad42808080808001841002200942003703002007420037030020024200370300200342003703a80b20081001220b29000021062005200b41086a290000370300200320063703a011200b103520022005290300370300200320032903a0113703a80b41daefcb00ad4280808080900184100122052900002106200a200541086a290000370300200320063703f81020051035200120032903f810370000200c200a290300370000200d2002290300370300200f200729030037030020102009290300370300200320032903a80b37039806200341013a00d00f2004200341d00f6aad42808080801084100220004200370308200042003703000c260b200341b00b6a2001410c6a280200360200200320012902043703a80b2000200341a80b6a20022d000020022d00011086060c250b20034198066a41206a200141246a29020037030020034198066a41186a2001411c6a29020037030020034198066a41106a200141146a29020037030020034198066a41086a2001410c6a2902003703002003200129020437039806200341a80b6a41206a200241206a290200370300200341a80b6a41186a200241186a290200370300200341a80b6a41106a200241106a290200370300200341a80b6a41086a200241086a290200370300200320022902003703a80b200020034198066a200341a80b6a10b1040c240b200341a80b6a200141086a41e000109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1087030c230b200341a80b6a200141086a418802109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1089020c220b200341a80b6a200141046a418c01109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1087060c210b200341a80b6a41306a200141386a290300370300200341a80b6a41286a200141306a290300370300200341a80b6a41206a200141286a290300370300200341a80b6a41186a200141206a290300370300200341a80b6a41106a200141186a290300370300200341a80b6a41086a200141106a2903003703002003200141086a2903003703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a108b050c200b200341d00b6a2001412c6a290200370300200341a80b6a41206a200141246a290200370300200341a80b6a41186a2001411c6a290200370300200341a80b6a41106a200141146a290200370300200341a80b6a41086a2001410c6a290200370300200320012902043703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1088060c1f0b200341d00b6a2001412c6a290200370300200341a80b6a41206a200141246a290200370300200341a80b6a41186a2001411c6a290200370300200341a80b6a41106a200141146a290200370300200341a80b6a41086a2001410c6a290200370300200320012902043703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1089060c1e0b20034198066a41206a200141286a29030037030020034198066a41186a200141206a29030037030020034198066a41106a200141186a29030037030020034198066a41086a200141106a2903003703002003200141086a29030037039806200341a80b6a41206a200241206a290200370300200341a80b6a41186a200241186a290200370300200341a80b6a41106a200241106a290200370300200341a80b6a41086a200241086a290200370300200320022902003703a80b200020034198066a200341a80b6a1089030c1d0b200341a80b6a200141046a41c400109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a108a060c1c0b4102210741002109024002400240024020022d0000450d000c010b20022d000141ff01714102470d0020012802042105200341a80b6a41186a4200370300200341a80b6a41106a22074200370300200341a80b6a41086a22014200370300200342003703a80b41bee4cb00ad4280808080f00184100122092900002104200341c00a6a41086a2202200941086a290000370300200320043703c00a2009103520012002290300370300200320032903c00a3703a80b418cc0c700ad4280808080e000841001220929000021042002200941086a290000370300200320043703c00a20091035200720032903c00a2204370300200341d00f6a41086a2001290300370300200341d00f6a41106a2004370300200341d00f6a41186a2002290300370300200320032903a80b3703d00f41002109200341286a200341d00f6a412041b0b4cc0041004100108a020240024020032802284101470d00410e210541d0b8c700210a0c010b200341d8106a41186a4200370300200341d8106a41106a220a4200370300200341d8106a41086a22024200370300200342003703d81041d1c4c700ad4280808080e000841001220929000021042002200941086a290000370300200320043703d8102009103541e7c4c700ad4280808080e000841001220929000021042001200941086a290000370300200320043703a80b20091035200a20032903a80b2204370300200341b8106a41086a2002290300370300200341b8106a41106a2004370300200341b8106a41186a2001290300370300200320032903d8103703b810200341206a200341b8106a412010c0012003280224410020032802201b20054f0d024107210541e8b8c700210a4180800421090b410321070b200041206a20053602002000411c6a200a360200200041186a2009418080047120077241801e72360200420121040c010b42002104200341a80b6a41186a220a4200370300200341a80b6a41106a220b4200370300200341a80b6a41086a22024200370300200342003703a80b41bee4cb00ad4280808080f00184100122092900002106200341c00a6a41086a2201200941086a290000370300200320063703c00a2009103520022001290300370300200320032903c00a3703a80b418cc0c700ad4280808080e000841001220929000021062001200941086a290000370300200320063703c00a20091035200720032903c00a370000200741086a2001290300370000200341d00f6a41086a2002290300370300200341d00f6a41106a200b290300370300200341d00f6a41186a200a290300370300200320032903a80b3703d00f200320053602a80b200341d00f6aad4280808080800484200341a80b6aad4280808080c0008410020b20002004370300200042003703080c1b0b200141086a280200210920012802042101024020022d00000d0020022d000141ff01714101470d0002402009450d00200110350b20004200370308200042003703000c1b0b02402009450d00200110350b20004200370308200041186a4102360200200042013703000c1a0b200341a80b6a41386a200141c0006a290300370300200341a80b6a41306a200141386a290300370300200341a80b6a41286a200141306a290300370300200341a80b6a41206a200141286a290300370300200341a80b6a41186a200141206a290300370300200341a80b6a41106a200141186a290300370300200341a80b6a41086a200141106a2903003703002003200141086a2903003703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a108b060c190b20014180016a2802002111200141d0006a2903002106200141346a2d00002112200141306a2d0000210f2001412c6a2d00002113200141086a2d0000210920012f0036211420012d0035211520012f0032211020012d0031211620012f002e211720012d002d211820012f002a211920012d0029211a20034194026a41026a221b2001410b6a2d00003a000020034180026a41086a2205200141206a29000037030020034180026a41106a220a200141286a2d00003a0000200341e8016a41086a221c200141c0006a290300370300200341e8016a41106a221d200141c8006a290300370300200320012f00093b0194022003200141186a290000370380022003200141386a2903003703e8012001410c6a2800002107200141106a280000210b200141146a280000210c200341c0016a41206a221e200141f8006a290300370300200341c0016a41186a221f200141f0006a290300370300200341c0016a41106a2220200141e8006a290300370300200341c0016a41086a2221200141e0006a290300370300200341a0016a41186a22222001419c016a280200360200200341a0016a41106a222320014194016a290200370300200341a0016a41086a22242001418c016a2902003703002003200141d8006a2903003703c001200320014184016a2902003703a0012002411a6a2901002104200241196a2d00002125200241186a2d00002126200241166a2f01002127200241156a2d00002128200241146a2d00002129200241126a2f0100212a200241116a2d0000212b200241106a2d0000212c2002410e6a2f0100212d2002410d6a2d0000212e2002410c6a2d0000212f2002410a6a2f01002130200241096a2d00002131200241086a2d00002132200241066a2f01002133200241056a2d00002134200241046a2d00002135200241026a2f0100213620022d0001210d20022d0000210102400240024002400240024020090e06000102030405000b200341a80b6a41146a4101360200200342013702ac0b200341e8d4ca003602a80b2003410436029c062003419cd5ca0036029806200320034198066a3602b80b200341a80b6a41b0b4cc00104c000b200341c8046a41086a2005290300370300200341c8046a41106a200a2d00003a000020034188036a41086a201c29030037030020034188036a41106a201d29030037030020034198066a41086a202129030037030020034198066a41106a202029030037030020034198066a41186a201f29030037030020034198066a41206a201e29030037030020032003290380023703c804200320032903e80137038803200320032903c00137039806200341800e6a41186a2022280200360200200341800e6a41106a2023290300370300200341800e6a41086a2024290300370300200320032903a0013703800e024002400240200d200141ff01714100477241ff01710d00200341f0086a41186a22054200370300200341f0086a41106a22094200370300200341f0086a41086a22024200370300200342003703f00841f1d8cb00ad42808080809001842208100122072900002104200341c00a6a41086a2201200741086a290000370300200320043703c00a2007103520022001290300370300200320032903c00a3703f00841e2d8cb00ad4280808080f00184220e1001220729000021042001200741086a290000370300200320043703c00a20071035200920032903c00a2204370300200341b8026a41086a22072002290300370300200341b8026a41106a220a2004370300200341b8026a41186a220d2001290300370300200320032903f0083703b802200341a80b6a200341b8026a10da020240410020032802980c20032d00b00c4102461b2011490d0041832421010c020b200341b40b6a2011360200200341a80b6a41086a41053a00002003410d3a00a80b41b0b4cc004100200341a80b6a10d401200341a80b6a41106a200341c8046a41086a290300370300200341a80b6a41186a200341c8046a41106a2d00003a00002003200c3602ac0b2003200b3602a80b200320032903c8043703b00b200320143b01ce0b200320153a00cd0b200320123a00cc0b200320103b01ca0b200320163a00c90b2003200f3a00c80b200320173b01c60b200320183a00c50b200320133a00c40b200320193b01c20b2003201a3a00c10b200341e00b6a20034188036a41106a290300370300200341d80b6a20034188036a41086a290300370300200341f80b6a20034198066a41086a290300370300200341800c6a20034198066a41106a290300370300200341880c6a20034198066a41186a290300370300200341900c6a200341b8066a290300370300200320063703e80b200320113602980c20032003290388033703d00b20032003290398063703f00b200341b40c6a200341800e6a41186a280200360200200341ac0c6a200341800e6a41106a290300370200200341a40c6a200341800e6a41086a290300370200200320032903800e37029c0c200542003703002009420037030020024200370300200342003703f00820081001220b29000021042001200b41086a290000370300200320043703c00a200b103520022001290300370300200320032903c00a3703f008200e1001220b29000021042001200b41086a290000370300200320043703c00a200b1035200920032903c00a370000200941086a200129030037000020072002290300370300200a2009290300370300200d2005290300370300200320032903f0083703b802200341003602f808200342013703f008200341a80b6a200341f0086a10f30520032802f4082101200341b8026aad428080808080048420033502f80842208620032802f0082202ad84100202402001450d00200210350b420021040c020b41822421010b200041206a41163602002000411c6a41bcffc600360200200041186a2001360200420121040b20004200370308200020043703000c1c0b024002400240200141ff01710d00200d41ff01714101470d00200341f0086a41186a420037030041102105200341f0086a41106a220a4200370300200341f0086a41086a22024200370300200342003703f00841f1d8cb00ad4280808080900184100122092900002104200341c00a6a41086a2201200941086a290000370300200320043703c00a2009103520022001290300370300200320032903c00a3703f00841e2d8cb00ad4280808080f001841001220929000021042001200941086a290000370300200320043703c00a20091035200a20032903c00a2204370300200341b8026a41086a2002290300370300200341b8026a41106a2004370300200341b8026a41186a2001290300370300200320032903f0083703b802200341a80b6a200341b8026a10da0220032903a80b210420032903b00b210620032903b80b210820032903c00b210e20032903c80b213720032903d00b213820032903d80b213920032903e00b213a20032903e80b213b20032903f00b213c20032903f80b213d20032903800c213e20032903880c213f20032903900c214020032802980c210f200328029c0c210220032802a00c210920032802a40c211020032802a80c210a20032802ac0c210d20032d00b00c21012003200341a80b6a418c016a2800003600f308200320032800b10c3602f0080240024020014102470d0020034280c2d72f3703800720034280e1eb173703f806200342a0c21e3703f006200342a0c21e3703e806200342e0ef97203703e006200342e0c9dc293703d806200342e0ef97203703d006200342a0c21e3703c806200342a0c21e3703c006200342a0c21e3703b806200342a0c21e3703b006200342a0c21e3703a806200342a0c21e3703a006200342a0c21e370398064100210120034100360288074120210d41808001210a418080042109410421020c010b20034198066a418c016a20032800f3083600002003200f3602880720032040370380072003203f3703f8062003203e3703f0062003203d3703e8062003203c3703e0062003203b3703d8062003203a3703d006200320393703c806200320383703c006200320373703b8062003200e3703b006200320083703a806200320063703a0062003200437039806200320032802f0083600a107201021050b200320013a00a0072003200d36029c072003200a36029807200320053602940720032009360290072003200236028c07200341a80b6a2007200c20034198066a108c06024020032802a80b4101460d00200341800e6a41186a2202200341a80b6a410472220141186a280200360200200341800e6a41106a2209200141106a290200370300200341800e6a41086a220d200141086a290200370300200320012902003703800e200341c00a6a41026a220f200cad4220862007ad841009220141026a2d00003a0000200128000321052001280007210a20012f00002110200341c8046a410d6a2216200141186a290000370000200341c8046a41086a221b200141136a290000370300200320103b01c00a2003200129000b3703c80420011035200341a80b6a41186a2002280200360200200341a80b6a41106a2009290300370300200341a80b6a41086a200d290300370300200320032903800e3703a80b200341d00f6a41026a2202200f2d00003a000020034188036a41086a2209201b29030037030020034188036a410d6a220d2016290000370000200320032f01c00a3b01d00f200320032903c8043703880341f1d8cb00ad4280808080900184100122012900002104200341a0116a41086a200141086a290000370300200320043703a0112001103541a0e0c600ad4280808080b00184100122012900002104200341f8106a41086a200141086a290000370300200320043703f81020011035412010332201450d0e200120032f01d00f3b00002001200a36000720012005360003200120032903880337000b200141026a20022d00003a0000200141136a2009290300370000200141186a200d290000370000412010332202450d0e20022001290000370000200241186a2209200141186a290000370000200241106a220d200141106a290000370000200241086a220f200141086a2900003700002001103541c00010332201450d0e200120032903f810370010200120032903a011370000200141086a200341a0116a41086a290300370000200141186a200341f8106a41086a29030037000020012002290000370020200141286a200f290000370000200141306a200d290000370000200141386a20092900003700002002103520034100360290032003420137038803200341a80b6a20034188036a10e201200341a80b6a41047220034188036a10e201200341a80b6a41086a20034188036a10e201200320032d00c00b220d3a00d00f02400240200328028c032003280290032202460d0020032802880321090c010b200241016a22092002490d112002410174220d2009200d20094b1b220d4100480d110240024020020d00410021020240200d0d00410121090c020b200d103322090d010c230b20032802880321092002200d460d0020092002200d10372209450d220b2003200d36028c03200320093602880320032d00d00f210d0b200920026a200d3a00002003200241016a3602900320032802b40b2116200341bc0b6a280200220220034188036a107702400240200328028c032210200328029003220d6b2002490d0020032802880321092010210f0c010b200d20026a2209200d490d112010410174220f2009200f20094b1b220f4100480d110240024020100d000240200f0d00410121090c020b200f10332209450d230c010b20032802880321092010200f460d0020092010200f10372209450d220b2003200f36028c0320032009360288030b2009200d6a20162002109d081a2001ad4280808080800884200d20026aad4220862009ad8410020240200f450d00200910350b200110350240200341b80b6a280200450d00201610350b20034188036a41026a2202200341c00a6a41026a2d00003a0000200341a80b6a41086a2209200341c8046a41086a290300370300200341a80b6a410d6a220d200341c8046a410d6a290000370000200320032f01c00a3b018803200320032903c8043703a80b41f1d8cb00ad4280808080900184100122012900002104200341a0116a41086a200141086a290000370300200320043703a011200110354194e0c600ad4280808080c00184100122012900002104200341f8106a41086a200141086a290000370300200320043703f81020011035412010332201450d0e200120032f0188033b00002001200a36000720012005360003200120032903a80b37000b200141026a20022d00003a0000200141136a2009290300370000200141186a2209200d290000370000412010332202450d0e20022001290000370000200241186a2009290000370000200241106a2209200141106a290000370000200241086a220d200141086a2900003700002001103541c00010332201450d0e200120032903f810370010200120032903a011370000200141086a200341a0116a41086a290300370000200141186a200341f8106a41086a29030037000020012002290000370020200141286a200d290000370000200141306a2009290000370000200141386a200241186a29000037000020021035200341c0003602ac0b200320013602a80b2007200c200341a80b6a109403200110350240200b450d00200710350b200341d8106a41026a200341c00a6a41026a2d000022013a0000200341f0086a41086a2202200341c8046a41086a290300370300200341f0086a410d6a2209200341c8046a410d6a290000370000200320032f01c00a22073b01d810200320032903c8043703f008200341a80b6a41086a41043a0000200341b10b6a20073b0000200341b30b6a20013a0000200341b80b6a200a360200200341b40b6a20053602002003410d3a00a80b200341bc0b6a20032903f008370200200341c40b6a2002290300370200200341c90b6a200929000037000041b0b4cc004100200341a80b6a10d401420021040c030b200341b00b6a350200210420033502ac0b21060240200b450d00200710350b20044220862006842104410021010c010b410221010240200b450d00200710350b0b2000411c6a2004370200200041186a2001360200420121040b20004200370308200020043703000c1b0b201d290300210820032903f001210e20032802e8012109200341a0116a41106a200a2d00003a0000200341a0116a41086a200529030037030020032003290380023703a0112016410874200f72201041107472210202400240200141ff01710d00200d41ff01714101470d00200320043701e80f200320253a00e70f200320263a00e60f200320273b01e40f200320283a00e30f200320293a00e20f2003202a3b01e00f2003202b3a00df0f2003202c3a00de0f2003202d3b01dc0f2003202e3a00db0f2003202f3a00da0f200320303b01d80f200320313a00d70f200320323a00d60f200320333b01d40f200320343a00d30f200320353a00d20f200320363b01d00f200341a80b6a41086a2201200c360200200341b40b6a20032903a011370200200341bc0b6a200341a0116a41086a290300370200200341c40b6a200341a0116a41106a2d00003a0000200341ca0b6a20173b0100200341c90b6a20183a0000200341c80b6a20133a0000200341c60b6a20193b0100200341c50b6a201a3a00002003200b3602ac0b200320073602a80b20034198066a200341a80b6a108b02200341800e6a41086a2207200341a1066a290000370300200341800e6a41106a2205200341a9066a290000370300200341800e6a41186a220a200341b1066a29000037030020032003290099063703800e20032d0098064101470d01410121072015410874201272201441107472450d190c180b4102210720154108742012722014411074720d170c180b200341b8026a41086a220b2007290300370300200341b8026a41106a22072005290300370300200341b8026a41186a2205200a290300370300200320032903800e3703b8022003200637038011200320063703f810200341c8046a41186a200341d00f6a41186a290100370300200341c8046a41106a200341d00f6a41106a290100370300200341c8046a41086a200341d00f6a41086a290100370300200320032901d00f3703c80420034188036a41186a200529030037030020034188036a41106a200729030037030020034188036a41086a200b290300370300200320032903b802370388032003200341f8106a3602b805200341d8106a41186a4200370300200341d8106a41106a22074200370300200341d8106a41086a22054200370300200342003703d81041f1d8cb00ad42808080809001841001220a29000021042005200a41086a290000370300200320043703d810200a103541e2d8cb00ad4280808080f001841001220a29000021042001200a41086a290000370300200320043703a80b200a1035200720032903a80b2204370300200341b8106a41086a2005290300370300200341b8106a41106a2004370300200341b8106a41186a2001290300370300200320032903d8103703b810200341a80b6a200341b8106a10da0220032903a80b210420032903b00b210620032903b80b213720032903c00b213820032903c80b213920032903d00b213a20032903d80b213b20032903e00b213c20032903e80b213d20032903f00b213e20032903f80b213f20032903800c214020032903880c214120032903900c214220032802980c2110200328029c0c210520032802a00c210a20032802a40c210b20032802a80c210c20032802ac0c210d20032d00b00c21012003200341a80b6a418c016a2800003600f308200320032800b10c3602f0082015410874201272201441107472210f0240024020014102470d0020034280c2d72f3703e80e20034280e1eb173703e00e200342a0c21e3703d80e200342a0c21e3703d00e200342e0ef97203703c80e200342e0c9dc293703c00e200342e0ef97203703b80e200342a0c21e3703b00e200342a0c21e3703a80e200342a0c21e3703a00e200342a0c21e3703980e200342a0c21e3703900e200342a0c21e3703880e200342a0c21e3703800e41002101200341003602f00e4120210d41808001210c4110210b41808004210a410421050c010b200341800e6a418c016a20032800f308360000200320103602f00e200320423703e80e200320413703e00e200320403703d80e2003203f3703d00e2003203e3703c80e2003203d3703c00e2003203c3703b80e2003203b3703b00e2003203a3703a80e200320393703a00e200320383703980e200320373703900e200320063703880e200320043703800e200320032802f0083600890f0b200341a80f6a4200370300200341980f6a4200370300200320013a00880f2003200d3602840f2003200c3602800f2003200b3602fc0e2003200a3602f80e200320053602f40e2003428080e983b1de163703a00f2003428080e983b1de163703900f200342a08080808080103703b00f2003200341800e6a360298022003200341800e6a3602e802200341d8106a41186a220a4200370300200341d8106a41106a220b4200370300200341d8106a41086a22014200370300200342003703d81041d1efcb00ad42808080809001841001220529000021042001200541086a290000370300200320043703d8102005103541ebc3c400ad428080808030841001220c2900002104200341a80b6a41086a2205200c41086a290000370300200320043703a80b200c1035200720032903a80b370000200741086a220d2005290300370000200341b8106a41086a22102001290300370300200341b8106a41106a2216200b290300370300200341b8106a41186a221b200a290300370300200320032903d8103703b810200341386a200341b8106a10e102200329034021042003280238211c200a4200370300200b420037030020014200370300200342003703d81041d1c4c700ad4280808080e000841001220c29000021062001200c41086a290000370300200320063703d810200c103541e7c4c700ad4280808080e000841001220c29000021062005200c41086a290000370300200320063703a80b200c1035200720032903a80b370000200d2005290300370000201020012903003703002016200b290300370300201b200a290300370300200320032903d8103703b810200341306a200341b8106a412010c001200341a8096a42003703002003419c096a419494ca0036020020034198096a41b0b4cc0036020020034194096a4100360200200341c8096a200341c8046a41086a290300370300200341d0096a200341c8046a41106a290300370300200341d8096a200341c8046a41186a2903003703002003428080808080013703a0092003420037038809200342003703f808200320032903c8043703c00920032802302101200328023421072003200341e8026a3602b809200320034198026a3602b4092003200341800e6a3602b00920032007410020011b3602bc09200320044200201c1b3703f008200341a80b6a41186a20034188036a41186a290300370300200341a80b6a41106a20034188036a41106a290300370300200520034188036a41086a29030037030020032003290388033703a80b200320093602a0062003200f36029c062003200236029806200341c00a6a200341f0086a200341a80b6a200e2008200341f8106a20034198066a10ef034101210b024020032802c00a220c0d00200341c00a6a41106a2d00000d00200341a80b6a41086a20034190096a29030037030020034198066a41086a200341b40b6a28020036020020032003290388093703a80b200320032902ac0b37039806200341e8116a20034198066a10f0034100210b0b20032802a409220520032802ac09220141d8026c6a210920032802a809210a2003200341b8056a3602d81020052102024002402001450d00200341a80b6a4101722107200521010240034020012d0000210220034198066a200141016a41d702109d081a20024103460d01200320023a00a80b200720034198066a41d702109d081a200341d8106a200341a80b6a108d06200141d8026a22012009470d000c030b0b200141d8026a21020b20092002460d0003402002220141d8026a21020240024020012d0000220741014b0d000240024020070e020001000b0240200141086a28020041ffffff3f71450d00200141046a28020010350b200141106a2d00004107470d02200141386a280200450d02200141346a28020010350c020b200141286a10bb020c010b200141e8006a28020041ffffff3f71450d00200141e4006a28020010350b20092002470d000b0b0240200a450d00200a41d8026c450d00200510350b200341d40a6a290200210e200341c00a6a41106a280200210a200341c80a6a290300210820032802c40a2107024020032802fc082201450d00200341f0086a41106a280200450d00200110350b0240200b450d0002400240200328028c0922050d004100210b200341bc0b6a4100360200200341003602ac0b0c010b200328029409210b0240024020034190096a28020022020d00200521010c010b2002210120052109034020092802880b21092001417f6a22010d000b200521010340200120012f01064102746a41880b6a28020021012002417f6a22020d000b200921050b200341c40b6a20012f0106360200200341c00b6a4100360200200341bc0b6a2001360200200341003602b80b200342003703b00b200320053602ac0b200341003602a80b0b2003200b3602c80b200341a80b6a108f030b200329038011210420032903f810210602400240200c450d000240200ea7450d00200a10350b200620047d210e410121010c010b200620047d210e410021012008a7450d00200710350b42002104420121062001450d190c180b201c290300210820032903e801210e20032903f8012106200341af026a2005290300370000200341b7026a200a2d00003a00002003201b2d00003a009a02200320032f0194023b0198022003200c3600a3022003200b36009f022003200736009b0220032003290380023700a7022018410874201372201741107472210a02400240200141ff01710d00200d41ff01714101470d00200320313a00bf02200320323a00be02200320333b01bc02200320343a00bb02200320353a00ba02200320363b01b8022003202b3a00c7022003202c3a00c6022003202d3b01c4022003202e3a00c3022003202f3a00c202200320303b01c002200320253a00cf02200320263a00ce02200320273b01cc02200320283a00cb02200320293a00ca022003202a3b01c802200320043701d002200320063703e002200320063703d802200341e8026a41186a200437030041102107200341e8026a41106a20032901c802370300200341e8026a41086a20032901c002370300200320032901b8023703e802200341d8106a41186a4200370300200341d8106a41106a22024200370300200341d8106a41086a22014200370300200342003703d81041f1d8cb00ad42808080809001841001220929000021042001200941086a290000370300200320043703d8102009103541e2d8cb00ad4280808080f00184100122092900002104200341a80b6a41086a2205200941086a290000370300200320043703a80b20091035200220032903a80b2204370300200341b8106a41086a2001290300370300200341b8106a41106a2004370300200341b8106a41186a2005290300370300200320032903d8103703b810200341a80b6a200341b8106a10da0220032903a80b210420032903b00b210620032903b80b213720032903c00b213820032903c80b213920032903d00b213a20032903d80b213b20032903e00b213c20032903e80b213d20032903f00b213e20032903f80b213f20032903800c214020032903880c214120032903900c214220032802980c211b200328029c0c210920032802a00c210520032802a40c211c20032802a80c210b20032802ac0c210c20032d00b00c21012003200341a80b6a418c016a2800003600f308200320032800b10c3602f0082016410874200f72201041107472210d0240024020014102470d0020034280c2d72f3703f00320034280e1eb173703e803200342a0c21e3703e003200342a0c21e3703d803200342e0ef97203703d003200342e0c9dc293703c803200342e0ef97203703c003200342a0c21e3703b803200342a0c21e3703b003200342a0c21e3703a803200342a0c21e3703a003200342a0c21e37039803200342a0c21e37039003200342a0c21e3703880341002101200341003602f8034120210c41808001210b418080042105410421090c010b20034188036a418c016a20032800f3083600002003201b3602f803200320423703f003200320413703e803200320403703e0032003203f3703d8032003203e3703d0032003203d3703c8032003203c3703c0032003203b3703b8032003203a3703b003200320393703a803200320383703a003200320373703980320032006370390032003200437038803200320032802f00836009104201c21070b200341b0046a4200370300200341a0046a4200370300200320013a0090042003200c36028c042003200b3602880420032007360284042003200536028004200320093602fc032003428080e983b1de163703a8042003428080e983b1de1637039804200342a08080808080103703b804200320034188036a3602c004200320034188036a3602c404200341d8106a41186a22094200370300200341d8106a41106a22074200370300200341d8106a41086a22014200370300200342003703d81041d1efcb00ad42808080809001841001220529000021042001200541086a290000370300200320043703d8102005103541ebc3c400ad428080808030841001220b2900002104200341a80b6a41086a2205200b41086a290000370300200320043703a80b200b1035200220032903a80b370000200241086a220c2005290300370000200341b8106a41086a220f2001290300370300200341b8106a41106a22102007290300370300200341b8106a41186a22162009290300370300200320032903d8103703b810200341d0006a200341b8106a10e102200329035821042003280250211b200942003703002007420037030020014200370300200342003703d81041d1c4c700ad4280808080e000841001220b29000021062001200b41086a290000370300200320063703d810200b103541e7c4c700ad4280808080e000841001220b29000021062005200b41086a290000370300200320063703a80b200b1035200220032903a80b370000200c2005290300370000200f20012903003703002010200729030037030020162009290300370300200320032903d8103703b810200341c8006a200341b8106a412010c00120034180056a4200370300200341f4046a419494ca00360200200341c8046a41286a41b0b4cc00360200200341ec046a4100360200200341a0056a200341e8026a41086a290300370300200341a8056a200341e8026a41106a290300370300200341b0056a200341e8026a41186a2903003703002003428080808080013703f804200342003703e004200342003703d004200320032903e8023703980520032802482101200328024c21022003200341c4046a360290052003200341c0046a36028c05200320034188036a3602880520032002410020011b36029405200320044200201b1b3703c804200320143b01a206200320153a00a106200320123a00a0062003200d36029c062003200a36029806200341a80b6a200341c8046a200e2008200341d8026a20034198026a20034198066a10c0054101211a200341a80b6a41047221010240024020032802a80b4101470d00200341cc056a200141106a290200370200200341c4056a200141086a2902003702004101211a200341013602b805200320012902003702bc05200341b8056a410472212f0c010b200341b8056a410c6a200141286a2902003702002003200141206a2902003702bc05200341003602b805200341b8056a410472212f200341b8056a41106a2d00000d00200341a80b6a41086a200341e8046a29030037030020034198066a41086a200341a80b6a410c6a280200360200200320032903e0043703a80b200320032902ac0b37039806200341e8116a20034198066a10f0034100211a0b20032802fc042235200328028405220141d8026c6a210720032802800521362035210202402001450d00200341f10b6a211620034181106a210f200341a80b6a41017221302003419f066a2131200341a80b6a41186a211b200341b10b6a210c200341a0116a41116a211d200341a0116a410272211420034198066a41e0006a2132200341d00f6a41186a2133200341d10b6a211c200341a4106a2115200341a0116a410f6a2112200341d00f6a41116a2110200341b8106a410f6a2113200341e8066a2134203521010240034020012d00002102200341a40b6a41026a220d200141036a2d00003a00002003200141016a2f00003b01a40b200141046a2802002109200141086a28020021052001410c6a280200210a200341c00a6a200141106a41e000109d081a200141f8006a2903002104200141f0006a290300210620014180016a2903002108200341f0086a20014188016a41d001109d081a20024103460d01200341b4106a41026a220b200d2d00003a0000200320032f01a40b3b01b410200341d00f6a200341c00a6a41e000109d081a200341800e6a200341f0086a41d001109d081a024002400240024020020e03010200010b201320032900d00f370000201341086a200341d00f6a41086a2202290000370000201341106a200341d00f6a41106a220d2d00003a0000200320032f01b4103b01b8102003200a3600c310200320053600bf10200320093600bb102003200b2d00003a00ba10200341d8106a41186a2217201041186a2218290000370300200341d8106a41106a2225201041106a2226290000370300200341d8106a41086a2227201041086a2228290000370300200320102900003703d810200341f8106a41186a2229200f41186a222a290000370300200341f8106a41106a222b200f41106a222c290000370300200341f8106a41086a222d200f41086a222e2900003703002003200f2900003703f8102003200a3600ab11200320053600a711200320093600a3112003200b2d00003a00a211200320032f01b4103b01a011201220032900d00f370000201241086a2002290000370000201241106a200d2d00003a000020034198066a41186a201829000037030020034198066a41106a202629000037030020034198066a41086a20282900003703002003201029000037039806201b202a290000370300200341a80b6a41106a202c290000370300200341a80b6a41086a202e2900003703002003200f2900003703a80b200341d8116a41086a201541086a280000360200200320152900003703d811200341c8116a200341a0116a20034198066a200341a80b6a20062004200341d8116a10f10320032d00c8112102200c20032903b810370000200c41086a200341b8106a41086a290300370000200c41106a200341b8106a41106a290300370000200c41186a200341b8106a41186a290300370000201c20032903d810370000201c41086a2027290300370000201c41106a2025290300370000201c41186a2017290300370000200341033a00b00b2003410d3a00a80b200341a80b6a41f8006a2004370300201641186a2029290300370000201641106a202b290300370000201641086a202d290300370000201620032903f810370000200320063703980c200320024104463a00910c41b0b4cc004100200341a80b6a10d4010c020b2031200341d00f6a41e000109d081a2003410d3a00a80b203020034198066a41e700109d081a200341a80b6a41f0006a2004370300200320063703900c200320083703a00c2009200a200341a80b6a10d401200541ffffff3f71450d01200910350c010b200341d8116a41026a2202200b2d00003a0000200341d8106a41086a220d200341d00f6a41086a2217290000370300200341d8106a41106a2218200341d00f6a41106a22252d00003a0000200320032f01b4103b01d811200320032900d00f3703d81020034198066a203341c800109d081a20342004370300200320063703e006200320083703f0062032200341800e6a41d001109d081a200341b8106a20034198066a10d803200341a80b6a20034198066a41b002109d081a201420032f01b4103b0000201441026a200b2d00003a0000201d20032900d00f370000201d41086a2017290000370000201d41106a20252d00003a000020034180023b01a0112003200a3600ad11200320053600a911200320093600a511200341f8106a200341a80b6a200341a0116a10ac034200210402402003290380114201520d00420020032903b81022042003290388117d220620062004561b21040b2003427f20032903e002220620047c220420042006541b220420032903d802220620042006561b3703e00220032903f8102104200c20032f01d8113b0000200c41026a20022d00003a0000201b20032903d810370000201b41086a200d290300370000201b41106a20182d00003a0000200341063a00b00b2003410d3a00a80b2003200a3602bc0b200320053602b80b200320093602b40b20032004503a00d10b41b0b4cc004100200341a80b6a10d4010b200141d8026a22012007470d000b200721020c010b200141d8026a21020b024020072002460d0003402002220141d8026a21020240024020012d0000220941014b0d000240024020090e020001000b0240200141086a28020041ffffff3f71450d00200141046a28020010350b200141106a2d00004107470d02200141386a280200450d02200141346a28020010350c020b200141286a10bb020c010b200141e8006a28020041ffffff3f71450d00200141e4006a28020010350b20072002470d000b0b02402036450d00203641d8026c450d00203510350b202f290210210e202f28020c210b202f2902042104202f280200210720032802b8052105024020032802d4042201450d00200341d8046a280200450d00200110350b0240201a450d000240024020032802e404220a0d004100210c200341bc0b6a4100360200200341003602ac0b0c010b20032802ec04210c02400240200341e8046a28020022020d00200a21010c010b20022101200a2109034020092802880b21092001417f6a22010d000b200a21010340200120012f01064102746a41880b6a28020021012002417f6a22020d000b2009210a0b200341c40b6a20012f0106360200200341c00b6a4100360200200341bc0b6a2001360200200341003602b80b200342003703b00b2003200a3602ac0b200341003602a80b0b2003200c3602c80b200341a80b6a108f030b20032903e002210620032903d802210820054101470d010240200ea7450d00200b10350b200820067d2108420121060c150b420021064102210702402016410874200f722010411074720d000c150b200a10350c140b02402004a7450d00200710350b200820067d210842002104420121060c140b20032901f201210620032d00f101210220032d00f001210920032f01ee01211c20032d00ed01211d20032d00ec01211e20032f01ea01211f20032d00e901212020032d00e8012121200320032f0194023b01c00a2003200c3600cb0a2003200b3600c70a200320073600c30a2003201b2d00003a00c20a200341d70a6a2005290300370000200341df0a6a200a2d00003a000020032003290380023700cf0a200141ff01710d0f02400240201a4101710d0041022107200d41ff01714101460d010c110b41002107201c2127201f212a2014212d2010213020172133201921362013213520182134200f2132201621312012212f2015212e2021212c2020212b201e2129201d2128200921262002212520062104200d41ff01714102470d100b200320043703e80f200320253a00e70f200320263a00e60f200320273b01e40f200320283a00e30f200320293a00e20f2003202a3b01e00f2003202b3a00df0f2003202c3a00de0f2003202d3b01dc0f2003202e3a00db0f2003202f3a00da0f200320303b01d80f200320313a00d70f200320323a00d60f200320333b01d40f200320343a00d30f200320353a00d20f200320363b01d00f200341f0086a200341c00a6a10f303200341a80b6a20032802f008220220032802f80810d90220032d00a80b210120034198066a200341a80b6a41017241d700109d081a024020014102460d00200341800e6a20034198066a41d700109d081a0b024020032802f408450d00200210350b024002402001417f6a41ff01714102490d00200341f0086a200341870e6a41d000109d081a200341a80b6a41186a4200370300200341a80b6a41106a22094200370300200341a80b6a41086a22014200370300200342003703a80b41d1c4c700ad4280808080e000841001220229000021042001200241086a290000370300200320043703a80b2002103541e7c4c700ad4280808080e00084100122022900002104200341f8106a41086a2205200241086a290000370300200320043703f81020021035200920032903f810220437030020034198066a41086a200129030037030020034198066a41106a200437030020034198066a41186a2005290300370300200320032903a80b37039806200341f8006a20034198066a412010c001200341c8046a200341c00a6a200328027c410020032802781b22012007200341f0086a10f603024020032802c804417f6a41014b0d0020034198066a200341f0086a41d000109d081a20034188036a41186a200341c8046a41186a29030037030020034188036a41106a200341c8046a41106a29030037030020034188036a41086a200341c8046a41086a290300370300200320032903c80437038803200341a80b6a200341c00a6a20034198066a200120034188036a10f703024020032d00a80b0d00200341c40b6a280200450d00200341c00b6a28020010350b42002104200342003703880e200342808086bdbacdd21a3703800e2003200341d00f6a3602f00820034198066a200341d00f6a200341800e6a200341f0086a109a022003280298064101460d02200341c0066a290300210820034198066a41206a290300210e024020034198066a41086a220b2903004201520d0020034198066a41106a2903002104200341e00b6a20034198066a41186a290300370300200341d80b6a2004370300200341a80b6a41086a41003a0000200341b10b6a20032903d00f370000200341b90b6a200341d00f6a41086a290300370000200341c10b6a200341d00f6a41106a290300370000200341c90b6a200341d00f6a41186a290300370000200341033a00a80b41b0b4cc004100200341a80b6a10d4010b42002104200341a80b6a41186a22024200370300200341a80b6a41106a22074200370300200341a80b6a41086a22014200370300200342003703a80b41b6fdc600ad428080808080018422061001220a2900002137200341a0116a41086a2205200a41086a290000370300200320373703a011200a103520012005290300370300200320032903a0113703a80b41e489c200ad4280808080d0018422371001220c2900002138200341f8106a41086a220a200c41086a290000370300200320383703f810200c1035200920032903f810370000200941086a220f200a290300370000200b200129030037030020034198066a41106a2210200729030037030020034198066a41186a22162002290300370300200320032903a80b37039806200341e0006a20034198066a412010d701200341e0006a41106a2903002138200329036821392003280260210c200242003703002007420037030020014200370300200342003703a80b20061001220d29000021062005200d41086a290000370300200320063703a011200d103520012005290300370300200320032903a0113703a80b2037100122052900002106200a200541086a290000370300200320063703f81020051035200920032903f810370000200f200a290300370000200b20012903003703002010200729030037030020162002290300370300200320032903a80b370398062003427f20384200200c1b220620087c20394200200c1b2208200e7c220e2008542201ad7c22082001200820065420082006511b22011b3703b00b2003427f200e20011b3703a80b20034198066aad4280808080800484200341a80b6aad428080808080028410020c140b20034184096a280200450d0020032802800910350b420021040c120b200328029c06220141ff01714104460d112001418080807871210220014180807c712109200141807e712107200341a0066a2903002204422088a721052004a7210a0c100b200341d00b6a2001412c6a280200360200200341a80b6a41206a200141246a290200370300200341a80b6a41186a2001411c6a290200370300200341a80b6a41106a200141146a290200370300200341a80b6a41086a2001410c6a290200370300200320012902043703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a108e060c170b2001411c6a280200210d200141186a280200210f200141146a28020021102001410c6a2802002116200141086a280200211c410021094102210702400240024020022d0000450d000c010b20022d000141ff01714102470d00200141246a280200211b200141106a2802002107200341a80b6a41186a22054200370300200341a80b6a41106a22014200370300200341a80b6a41086a22024200370300200342003703a80b41a3edcb00ad4280808080f000841001220929000021042002200941086a290000370300200320043703a80b2009103541a5ebcb00ad4280808080c001841001220a2900002104200341f8106a41086a2209200a41086a290000370300200320043703f810200a1035200120032903f810220437030020034198066a41086a220b200229030037030020034198066a41106a220c200437030020034198066a41186a221d2009290300370300200320032903a80b3703980620034188016a20034198066a412010c001200341a80b6a200328028c0141002003280288011b2213201b10ba0420034180016a20032802a80b220a20032802b00b41b0b4cc0041004100108a022003280280012112024020032802ac0b450d00200a10350b200542003703002001420037030020024200370300200342003703a80b4188e8cb00ad42808080808001841001220a29000021042002200a41086a290000370300200320043703a80b200a1035418fd1cb00ad4280808080c000841001220a29000021042009200a41086a290000370300200320043703f810200a1035200120032903f810370000200141086a2009290300370000200b2002290300370300200c2001290300370300201d2005290300370300200320032903a80b37039806200341a80b6a20034198066a10d80220032802a80b2201410120011b211d20032902ac0b420020011b21040240201241014622020d00201d201b4105746a4100201b2004422088a7491b22010d020b41eec3c4004181c4c40020021b21054113410a20021b210a2002411074210941032107200442ffffff3f83500d00201d10350b02402016450d00201c10350b0240200d450d00200d410c6c21022010210103400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b0240200f450d00200f410c6c450d00201010350b20004200370308200041206a200a3602002000411c6a2005360200200041186a200920077241802872360200200042013703000c170b200141086a2900002106200141106a29000021082001290000210e20034198066a41186a200141186a290000223737030020034198066a41106a200837030020034198066a41086a20063703002003200e37039806200341b50b6a2006370000200341bd0b6a2008370000200341c50b6a2037370000200341003a00ac0b2003410f3a00a80b2003200e3700ad0b41b0b4cc004100200341a80b6a10d401200341003602b00b200342013703a80b2007200341a80b6a10770240024020032802ac0b220920032802b00b22016b2007490d0020032802a80b21020c010b200120076a22022001490d08200941017422052002200520024b1b22054100480d080240024020090d00024020050d00410121020c020b200510332202450d1a0c010b20032802a80b210220092005460d0020022009200510372202450d190b200320053602ac0b200320023602a80b0b200220016a201c2007109d081a2003200120076a3602b00b200d200341a80b6a1077200d450d062010200d410c6c6a210c2010210203402002280200210b200241086a2802002201200341a80b6a10770240024020032802ac0b220720032802b00b22096b2001490d0020032802a80b21052007210a0c010b200920016a22052009490d092007410174220a2005200a20054b1b220a4100480d090240024020070d000240200a0d00410121050c020b200a10332205450d1b0c010b20032802a80b21052007200a460d0020052007200a10372205450d1a0b2003200a3602ac0b200320053602a80b0b200520096a200b2001109d081a2003200920016a22013602b00b2002410c6a2202200c470d000c0d0b0b200341a80b6a200141086a41a802109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a10b3040c150b200341a80b6a200141086a41c800109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a108f060c140b200341a80b6a200141046a41c400109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1090060c130b200341800e6a41086a2207200141146a290200370300200341800e6a41106a22052001411c6a290200370300200341800e6a41186a220a200141246a290200370300200341800e6a41206a220b2001412c6a28020036020020032001410c6a2902003703800e2002411a6a2901002104200241196a2d0000210d200241186a2d0000210f200241166a2f01002110200241156a2d00002116200241146a2d0000211b200241126a2f0100211c200241116a2d0000211d200241106a2d000021122002410e6a2f010021132002410d6a2d000021142002410c6a2d000021152002410a6a2f01002117200241096a2d00002118200241086a2d00002125200241066a2f01002126200241056a2d00002127200241046a2d000021284102210c200241026a2f0100212920022d0001210920022d000021020240024002400240200141086a2802000e0400010203000b200341a80b6a41146a4101360200200342013702ac0b200341e8d4ca003602a80b2003410436029c062003419cd5ca0036029806200320034198066a3602b80b200341a80b6a41b0b4cc00104c000b02400240024002400240200241ff01710d00200941ff01714101460d010b200341023a0098060c010b200320043703c00b2003200d3a00bf0b2003200f3a00be0b200320103b01bc0b200320163a00bb0b2003201b3a00ba0b2003201c3b01b80b2003201d3a00b70b200320123a00b60b200320133b01b40b200320143a00b30b200320153a00b20b200320173b01b00b200320183a00af0b200320253a00ae0b200320263b01ac0b200320273a00ab0b200320283a00aa0b200320293b01a80b20034198066a200341a80b6a10890520032d0098064104460d010b20032802980621012000411c6a200329029c06370200200041186a2001360200420121040c010b420021040b200042003703080c090b20034198066a41206a200b28020036020020034198066a41186a200a29030037030020034198066a41106a200529030037030020034198066a41086a2007290300370300200320032903800e37039806200241ff01710d05200941ff01714101470d05200341a80b6a41206a20034198066a41206a280200360200200341a80b6a41186a20034198066a41186a290300370300200341a80b6a41106a20034198066a41106a290300370300200341a80b6a41086a20034198066a41086a29030037030020032003290398063703a80b200341f0086a200341a80b6a108b02024020032d00f0084101470d00200341013a00c8040c070b200341f0086a41086a2d00002101200341f9086a2f00002102200341fb086a2d00002109200341fc086a2d00002107200341fd086a2f00002105200341ff086a2d0000210a200341f0086a41106a2d0000210b20034181096a2f0000210c20034183096a2d0000210d20034184096a2d0000210f20034185096a2f0000211020034187096a2d00002116200341f0086a41186a2d0000211b20032f00f108211c20032d00f308211d20032d00f408211220032f00f508211320032d00f7082114200320034189096a2900003703a0032003201b3a009f03200320163a009e03200320103b019c032003200f3a009b032003200d3a009a032003200c3b0198032003200b3a0097032003200a3a009603200320053b019403200320073a009303200320093a009203200320023b019003200320013a008f03200320143a008e03200320133b018c03200320123a008b032003201d3a008a032003201c3b018803200341c8046a20034188036a10890520032d00c8044104470d06420021040c070b200141c8006a290300210e200141c0006a2903002137200141386a2903002106200141306a2903002108200141d0006a280200212a20034198066a41206a200b28020036020020034198066a41186a200a29030037030020034198066a41106a200529030037030020034198066a41086a2007290300370300200320032903800e37039806024002400240200241ff01710d00200941ff01714101470d00200320043703e0042003200d3a00df042003200f3a00de04200320103b01dc04200320163a00db042003201b3a00da042003201c3b01d8042003201d3a00d704200320123a00d604200320133b01d404200320143a00d304200320153a00d204200320173b01d004200320183a00cf04200320253a00ce04200320263b01cc04200320273a00cb04200320283a00ca04200320293b01c8044103210c200842808084fea6dee1115441002006501b0d00200341a80b6a41206a20034198066a41206a280200360200200341a80b6a41186a20034198066a41186a290300370300200341a80b6a41106a20034198066a41106a290300370300200341a80b6a41086a20034198066a41086a29030037030020032003290398063703a80b200341f0086a200341a80b6a108b024101210c024020032d00f0084101470d000c020b200341f0086a41086a2d00002101200341f9086a2f00002102200341fb086a2d00002109200341fc086a2d00002107200341fd086a2f00002105200341ff086a2d0000210a200341f0086a41106a2d0000210b20034181096a2f0000210c20034183096a2d0000210d20034184096a2d0000210f20034185096a2f0000211020034187096a2d00002116200341f0086a41186a2d0000211b20032f00f108211c20032d00f308211d20032d00f408211220032f00f508211320032d00f7082114200320034189096a2900003703a0032003201b3a009f03200320163a009e03200320103b019c032003200f3a009b032003200d3a009a032003200c3b0198032003200b3a0097032003200a3a009603200320053b019403200320073a009303200320093a009203200320023b019003200320013a008f03200320143a008e03200320133b018c03200320123a008b032003201d3a008a032003201c3b018803200341a80b6a20034188036a108a0520034198016a20032802a80b220120032802b00b41b0b4cc0041004100108a022003280298012102024020032802ac0b450d00200110350b41012101024020024101470d00411b21074103210c4117210941aaefc40021020c020b200341a80b6a200341c8046a20034188036a20082006410110e602024020032d00a80b220c4104460d00200341b00b6a280200210920032802ac0b210220032d00ab0b210520032d00aa0b210120032d00a90b21070c030b200341a80b6a20034188036a108a0520034190016a20032802a80b220220032802b00b41b0b4cc0041004100108a022003280290012101024020032802ac0b450d00200210350b024020014101460d00200341a80b6a20034188036a108a0520033502b00b210420032802a80b2102411010332201450d17200120083700002001200637000820014110412010372201450d1720012037370010200141186a200e3700002001412041c00010372201450d172001202a36002020044220862002ad842001ad4280808080c00484100220011035024020032802ac0b450d00200210350b200341a80b6a41186a20034188036a41186a290300370300200341a80b6a41106a20034188036a41106a290300370300200341a80b6a41086a20034188036a41086a29030037030020032003290388033703a80b200341f0086a200341a80b6a10890542002104200042003703080c0b0b200341b00b6a4117360200200341aaefc4003602ac0b200341013a00aa0b20034183363b01a80b4188bfc6004137200341a80b6a41c0bfc60041d0bfc6001046000b41022101411b21074109210941a1efc40021020b0b20004200370308200041206a20093602002000411c6a2002360200200041186a2005411874200141ff017141107472200741ff017141087472200c72360200420121040c070b418eebc400413041c086cc00103f000b1045000b20032802b00b210120032802ac0b210a20032802a80b21050c050b103e000b200341023a00c8040b20032802c80421012000411c6a20032902cc04370200200041186a2001360200420121040b200042003703080b200020043703000c0a0b200341a80b6a2013201b10ba0420032802a80b2102200320032802b00b36029c0620032002360298062005200120034198066a109403024020032802ac0b450d00200210350b0240200a450d00200510350b0240200442ffffff3f83500d00201d10350b02402016450d00201c10350b0240200d450d00200d410c6c21022010210103400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b0240200f450d00200f410c6c450d00201010350b20004200370308200042003703000c090b410021024180800421094180242107410321014115210541dcffc600210a0b200041206a20053602002000411c6a200a360200200041186a20074180fe0371200141ff0171722009418080fc077172200272360200420121040b20004200370308200020043703000c060b2000411c6a2004370200200041186a2007360200420121040b20002006370308200041106a2008370300200020043703000c040b200210350b420021060b2000411c6a2008370200200041186a2007360200420121040b20002006370308200041106a200e370300200020043703000b200341f0116a24000f0b103c000bbf0403027f017e047f230041306b22032400200341086a200141086a28020022043602002003200129020022053703002005a72106024002400240024020040d00410021070c010b200441057421084100210941002107200621010240034002402009450d0020092001412010a0084100480d00200341186a4115360200200341e6f1c200360214200341053a001220034183023b0110200341106a21010c020b0240024020012002412010a008220941004a0d0020022001460d012009450d01200741016a21070b20012109200141206a2101200841606a2208450d030c010b0b200341186a4113360200200341d3f1c200360214200341063a001220034183023b0110200341106a21010b20004101360200200020012902003702042000410c6a200141086a280200360200200328020441ffffff3f71450d01200610350c010b200341106a41186a200241186a290000370300200341106a41106a200241106a290000370300200341106a41086a200241086a2900003703002003200229000037031020042007490d01024020042003280204470d00200320044101108a01200328020021060b200620074105746a220141206a2001200420076b410574109e081a200141186a200341106a41186a290300370000200141106a200341106a41106a290300370000200141086a200341106a41086a290300370000200120032903103700002003200441016a22013602082000410c6a200136020020002003290300370204200041003602000b200341306a24000f0b20072004104d000bba0502087f037e230041106b2202240002400240200141086a28020022034105744116722204417f4c0d000240200410332205450d00200520012802002206290000370000200541086a200641086a290000370000200241103602082002200436020420022005360200200141046a280200210720032002107702400240024020030d0020022802042106200228020821040c010b20034105742108200228020021092002280204210620022802082104034020072105024002402006200422036b4120490d00200341206a21040c010b200341206a22042003490d03200641017422072004200720044b1b22074100480d03024002400240024020060d00024020070d00410121090c020b2007103321090c030b20062007470d010b200721060c020b200920062007103721090b200721062009450d060b200541206a2107200920036a22032005290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a290000370000200841606a22080d000b2002200636020420022004360208200220093602000b20012f010c210802400240200620046b4102490d00200441026a210520022802002103200621070c010b200441026a22052004490d01200641017422032005200320054b1b22074100480d010240024020060d00024020070d00410121030c020b200710332203450d060c010b2002280200210320062007460d0020032006200710372203450d050b20022007360204200220033602000b200320046a20083b00002005ad4220862003ad8410092205290000210a200541086a290000210b200541106a290000210c200041186a200541186a290000370000200041106a200c370000200041086a200b3700002000200a3700002005103502402007450d00200310350b200241106a24000f0b103e000b1045000b1044000b103c000b855802057f017e230041206b220224000240024020002802002203411b4b0d000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e1c000102030405060708090a0b0c0d0e0f101112131415161718191a1b000b200241003a00102001200241106a41011078200041086a280200417f6a220341094b0d1c024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a00042001200241046a4101107820022000410c6a2802003602102001200241106a410410780c250b200241013a00042001200241046a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c240b200241023a00042001200241046a410110782002200041106a2903003703102001200241106a410810780c230b200241033a00042001200241046a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c220b200241043a00042001200241046a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c210b200241053a00042001200241046a4101107802402000410c6a2802004101460d00200241003a00042001200241046a410110780c210b200241013a00042001200241046a410110782002200041106a2802003602102001200241106a410410782002200041146a2802003602102001200241106a410410780c200b200241063a00042001200241046a410110782000410c6a2802002103200041146a2802002200200110772000450d1f2003200041186c6a2104034020032802002100200341086a28020022052001107720012000200510782003410c6a2802002100200341146a2802002205200110772001200020051078200341186a22032004470d000c200b0b200241073a00042001200241046a410110782000410c6a2802002103200041146a2802002200200110772000450d1e20032000410c6c6a2104034020032802002100200341086a28020022052001107720012000200510782003410c6a22032004470d000c1f0b0b200241083a00042001200241046a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c1d0b200241093a00042001200241046a410110780c1c0b200241013a00102001200241106a4101107820002d0004417f6a220341044b0d1b200041046a21040240024002400240024020030e050001020304000b200241003a00042001200241046a41011078200041086a2802002103200041106a2802002200200110772000450d1f200041b0026c210003402003200110af03200341b0026a2103200041d07d6a22000d000c200b0b200241013a00042001200241046a41011078200220002f01063b01102001200241106a41021078200041086a280200200110af030c1e0b200241023a00042001200241046a41011078200220002f01063b01102001200241106a41021078200041086a2802002103200041106a28020022052001107702402005450d002005410574210503402001200341201078200341206a2103200541606a22050d000b0b0240024020002802144101460d00200241003a00042001200241046a410110780c010b200241013a00042001200241046a410110782002200041186a2802003602102001200241106a4104107820022000411c6a2802003602102001200241106a410410780b2000280220200110af030c1d0b200241033a00042001200241046a41011078200220002f01263b01102001200241106a41021078200041286a2802002103200041306a28020022052001107702402005450d002005410574210503402001200341201078200341206a2103200541606a22050d000b0b200441016a21030240024020002802344101460d00200241003a00042001200241046a410110780c010b200241013a00042001200241046a410110782002200041386a2802003602102001200241106a4104107820022000413c6a2802003602102001200241106a410410780b20012003412010780c1c0b200241043a00042001200241046a41011078200220002f01263b01102001200241106a41021078200041286a2802002103200041306a280200220520011077200441016a210402402005450d002005410574210503402001200341201078200341206a2103200541606a22050d000b0b200220002802343602102001200241106a410410782002200041386a2802003602102001200241106a4104107820012004412010780c1b0b200241023a00102001200241106a410110780c190b200241033a00102001200241106a41011078200241003a00102001200241106a41011078200041086a200110fb050c190b200241043a00102001200241106a41011078200241003a00102001200241106a41011078200028020421032000410c6a2802002200200110772000450d182003200041f0006c6a21060340412010332200450d1a20002003290010370000200041186a200341286a290000370000200041106a200341206a290000370000200041086a200341186a2900003700002001200041201078200010352003200110e201412010332200450d1a20002003290030370000200041186a200341c8006a290000370000200041106a200341c0006a290000370000200041086a200341386a290000370000200120004120107820001035412010332200450d1a200341f0006a210420002003290050370000200041186a200341e8006a290000370000200041106a200341e0006a290000370000200041086a200341d8006a29000037000020012000412010782000103520032802042100200328020c22032001107702402003450d00200341246c21030340200241106a200010c0032001200228021022052002280218107802402002280214450d00200510350b200041246a21002003415c6a22030d000b0b2004210320042006470d000c190b0b200241053a00102001200241106a4101107820002d0004417f6a220341034b0d17200041046a21050240024002400240024020030e0400010203000b200241003a00042001200241046a410110782002200041086a280200360210200241106a21000c030b200241013a00042001200241046a410110782001200541016a412010782002200041286a280200360210200241106a21000c020b200241023a00042001200241046a410110782002200041086a280200360210200241106a21000c010b200241033a00042001200241046a410110782001200541016a412010782002200041286a280200360210200241106a21000b20012000410410780c170b200241063a00102001200241106a41011078200041086a280200417f6a220341034b0d160240024002400240024020030e0400010203000b200241003a00042001200241046a410110782000410c6a200110fc05200041306a2103200221000c030b200241013a00042001200241046a410110782000410c6a200110fc052002200041306a360204200241046a200110cf01200041c0006a2103200241086a21000c020b200241023a00042001200241046a410110782000410c6a200110fc05200041306a200110fc05200041d8006a21032002410c6a21000c010b200241033a00042001200241046a410110782000410c6a200110fc05200041306a2103200241106a21000b200020033602002000200110cf010c160b200241073a00102001200241106a41011078200041086a22052d0000417f6a220341174b0d1502400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e18000102030405060708090a0b0c0d0e0f1011121314151617000b200241003a00102001200241106a410110782000410c6a200110fc052002200041306a360210200241106a200110cf0120002d0009220041024b0d2c02400240024020000e03000102000b200241003a00102001200241106a410110780c2e0b200241013a00102001200241106a410110780c2d0b200241023a00102001200241106a410110780c2c0b200241013a00102001200241106a410110782002200041106a360210200241106a200110cf010c2b0b200241023a00102001200241106a410110782002200041106a360210200241106a200110cf010c2a0b200241033a00102001200241106a410110780c290b200241043a00102001200241106a410110780240024002402000410c6a280200220341c000490d00200341808001490d012003418080808004490d02200241033a00042001200241046a410110782002200028020c3602102001200241106a410410780c2b0b200220034102743a00042001200241046a410110780c2a0b200220034102744101723b01102001200241106a410210780c290b200220034102744102723602102001200241106a410410780c280b200241053a00102001200241106a410110782000410c6a2802002103200041146a2802002200200110772000450d27200041246c210003402003200110fc05200341246a21032000415c6a22000d000c280b0b200241063a00102001200241106a410110780c260b200241073a00102001200241106a4101107820052d0001220041024b0d2502400240024020000e03000102000b200241003a00102001200241106a410110780c270b200241013a00102001200241106a410110780c260b200241023a00102001200241106a410110780c250b200241083a00102001200241106a410110782000410c6a200110fc050c240b200241093a00102001200241106a410110782000410c6a200110e2010c230b2002410a3a00102001200241106a410110780c220b2002410b3a00102001200241106a410110780c210b2002410c3a00102001200241106a410110782000410c6a2802002103200041146a2802002200200110772000450d202000410574210003402001200341201078200341206a2103200041606a22000d000c210b0b2002410d3a00102001200241106a410110782001200541016a412010780c1f0b2002410e3a00102001200241106a410110780c1e0b2002410f3a00102001200241106a4101107820022000410c6a2802003602102001200241106a41041078200041106a2802002103200041186a28020022002001107720012003200041027410780c1d0b200241103a00102001200241106a4101107820022000410c6a2802003602102001200241106a41041078200041106a2802002103200041186a2802002200200110772000450d1c2003200041246c6a2100034020012003412010782002200341206a2802003602102001200241106a410410782000200341246a2203470d000c1d0b0b200241113a00102001200241106a4101107820022000410c6a2802003602102001200241106a410410780c1b0b200241123a00102001200241106a410110782001200541016a4120107820022000412c6a2802003602102001200241106a410410780c1a0b200241133a00102001200241106a410110782002200041106a360210200241106a200110cf010c190b200241143a00102001200241106a410110782000410c6a200110e2010c180b200241153a00102001200241106a410110782001200541016a412010780c170b200241163a00102001200241106a410110782000410c6a2802002103200041146a2802002205200110772001200320054101741078200041186a200110f7012001200041e0016a413010782002200041d8016a2802003602102001200241106a410410780c160b200241173a00102001200241106a410110782000410c6a2802002103200041146a2802002205200110772001200320054101741078200041186a200110f7012001200041e0016a413010782002200041d8016a2802003602102001200241106a410410780c150b200241083a00102001200241106a4101107802402000280204450d00200241003a00042001200241046a410110782001200041106a412010782001200041306a412010782001200041d0006a412010782001200041f0006a41201078200028020421032000410c6a28020022002001107720012003200010780c150b200241013a00042001200241046a410110780c140b200241093a00102001200241106a41011078200041086a22032d0000417f6a2205411c4b0d130240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e1d000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c000b200241003a00102001200241106a41011078412010332205450d3020052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a2900003700002001200541201078200510352002200041306a360210200241106a200110cf010c2f0b200241013a00102001200241106a410110782000410c6a200110e2010c2e0b200241023a00102001200241106a410110782000410c6a200110e201200041106a200110fd050c2d0b200241033a00102001200241106a410110782000410c6a200110e201200041106a200110fd050c2c0b200241043a00102001200241106a4101107820022000410c6a2802003602102001200241106a410410780c2b0b200241053a00102001200241106a41011078412010332200450d2b20002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c2a0b200241063a00102001200241106a41011078412010332200450d2a20002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c290b200241073a00102001200241106a41011078412010332200450d2920002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c280b200241083a00102001200241106a41011078412010332205450d2820052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a29000037000020012005412010782005103520022000412c6a2802003602102001200241106a410410782002200041306a2802003602102001200241106a410410780c270b200241093a00102001200241106a41011078412010332200450d2720002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c260b2002410a3a00102001200241106a410110782000410c6a200110e2010c250b2002410b3a00102001200241106a4101107820022000410c6a2802003602102001200241106a410410780c240b2002410c3a00102001200241106a410110782001200341016a412010780c230b2002410d3a00102001200241106a410110780c220b2002410e3a00102001200241106a410110782001200341016a412010780c210b2002410f3a00102001200241106a410110782001200341016a41201078024020002d0029220341064b0d000240024002400240024002400240024020030e0700010203040506000b200241003a00040c060b200241013a00040c050b200241023a00040c040b200241033a00040c030b200241043a00040c020b200241053a00040c010b200241063a00040b2001200241046a410110780b200029033021072002200041386a290300370318200220073703102001200241106a411010780c200b200241103a00102001200241106a410110780c1f0b200241113a00102001200241106a410110780c1e0b200241123a00102001200241106a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c1d0b200241133a00102001200241106a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c1c0b200241143a00102001200241106a41011078412010332200450d1c20002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c1b0b200241153a00102001200241106a410110782001200341016a412010780c1a0b200241163a00102001200241106a410110782001200341016a412010780c190b200241173a00102001200241106a4101107820022000410c6a2802003602102001200241106a410410780c180b200241183a00102001200241106a410110782001200341016a4120107820022000412c6a2802003602102001200241106a410410780c170b200241193a00102001200241106a410110782001200341016a41201078024020002d0029220341064b0d000240024002400240024002400240024020030e0700010203040506000b200241003a00040c060b200241013a00040c050b200241023a00040c040b200241033a00040c030b200241043a00040c020b200241053a00040c010b200241063a00040b2001200241046a410110780b200029033021072002200041386a290300370318200220073703102001200241106a411010780c160b2002411a3a00102001200241106a410110780c150b2002411b3a00102001200241106a4101107820022000410c6a2802003602102001200241106a410410780c140b2002411c3a00102001200241106a41011078412010332205450d1420052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a29000037000020012005412010782005103520022000412c6a2802003602102001200241106a410410780c130b2002410a3a00102001200241106a41011078200041046a200110fe050c120b2002410b3a00102001200241106a41011078200041046a200110fe050c110b2002410c3a00102001200241106a41011078200041086a280200417f6a220341054b0d1002400240024002400240024020030e06000102030405000b200241003a00042001200241046a410110782000410c6a2802002103200041146a280200220520011077200041186a210402402005450d002005410574210003402001200341201078200341206a2103200041606a22000d000b0b20022004360210200241106a200110cf010c150b200241013a00042001200241046a410110780c140b200241023a00042001200241046a410110782000410c6a200110fc050c130b200241033a00042001200241046a410110780c120b200241043a00042001200241046a410110780c110b200241053a00042001200241046a410110782000410c6a200110fc050c100b2002410d3a00102001200241106a4101107820002d0004417f6a220341064b0d0f200041046a2105024002400240024002400240024020030e0700010203040506000b200241003a00042001200241046a410110782001200541016a412010780c150b200241013a00042001200241046a410110782001200541016a412010780c140b200241023a00042001200241046a410110782001200541016a412010782001200541216a412010780c130b200241033a00042001200241046a41011078200041086a2802002103200041106a2802002200200110772000450d122000410574210003402001200341201078200341206a2103200041606a22000d000c130b0b200241043a00042001200241046a410110782001200541016a412010780c110b200241053a00042001200241046a410110782001200541016a412010780c100b200241063a00042001200241046a410110780c0f0b2002410e3a00102001200241106a41011078200241003a00102001200241106a41011078200041046a200110e2010c0e0b2002410f3a00102001200241106a41011078200241003a00102001200241106a41011078200028020421032000410c6a28020022002001107720012003200010780c0d0b200241103a00102001200241106a41011078200041086a22032d0000417f6a220541074b0d0c0240024002400240024002400240024020050e080001020304050607000b200241003a00042001200241046a410110782002200041306a360210200241106a200110cf012000410c6a200110fc050c130b200241013a00042001200241046a410110782000410c6a200110e2010c120b200241023a00042001200241046a410110782000410c6a200110e2010c110b200241033a00042001200241046a410110782000412c6a2802002105200041346a28020022002001107720012005200010782001200341016a412010780c100b200241043a00042001200241046a41011078412010332200450d1020002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c0f0b200241053a00042001200241046a410110782000412c6a2802002105200041346a28020022042001107720012005200410782001200341016a41201078200041386a29030021072002200041c0006a290300370318200220073703102001200241106a411010780c0e0b200241063a00042001200241046a41011078412010332205450d0e20052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a290000370000200120054120107820051035200041306a29030021072002200041386a290300370318200220073703102001200241106a411010780c0d0b200241073a00042001200241046a41011078412010332200450d0d20002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c0c0b200241113a00102001200241106a41011078200041086a22032d0000417f6a220541044b0d0b0240024002400240024020050e050001020304000b200241003a00042001200241046a41011078200041106a200110f3050c0f0b200241013a00042001200241046a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c0e0b200241023a00042001200241046a410110782000410c6a200110fc052002200041c0006a360210200241106a200110cf01200041d0006a200110fb05200041306a2802002103200041386a28020022002001107720012003200010780c0d0b200241033a00042001200241046a410110782002200041386a360210200241106a200110cf01200041c8006a200110fb05412010332205450d0d20052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a2900003700002001200541201078200510352000412c6a2802002103200041346a28020022002001107720012003200010780c0c0b200241043a00042001200241046a410110782001200341016a412010780240200341216a2d00004101460d00200241003a00042001200241046a410110780c0c0b200241013a00042001200241046a410110782001200341226a412010780c0b0b200241123a00102001200241106a410110782000280204417f6a220341024b0d0a02400240024020030e03000102000b200241003a00042001200241046a41011078200041086a280200200110af030c0c0b200241013a00042001200241046a41011078200041086a200110fc050c0b0b200241023a00042001200241046a41011078200041086a200110fc052000412c6a280200200110af030c0a0b200241133a00102001200241106a41011078200241003a00102001200241106a41011078200220002802043602102001200241106a41041078200041086a2802002103200041106a2802002205200110772001200320051078200041146a28020021032000411c6a28020022052001107702402005450d0020032005410c6c6a2106034020032802002105200341086a28020022042001107720012005200410782003410c6a22032006470d000b0b2002200041206a2802003602102001200241106a410410782002200041246a2802003602102001200241106a410410782002200041286a2802003602102001200241106a4104107820012000412c6a41c00010780c090b200241143a00102001200241106a410110780c070b200241153a00102001200241106a410110780c060b200241163a00102001200241106a410110780c050b200241173a00102001200241106a41011078200041086a22052d0000417f6a2203410a4b0d050240024002400240024002400240024002400240024020030e0b000102030405060708090a000b200241003a00042001200241046a410110782001200541016a412010780c0f0b200241013a00042001200241046a410110782000410c6a200110ab040c0e0b200241023a00042001200241046a410110782000410c6a2802002103200041146a2802002200200110772000450d0d2003200041c4006c6a210503402001200341201078200241106a200341206a220010ac042001200228021022032002280218107802402002280214450d00200310350b2005200041246a2203470d000c0e0b0b200241033a00042001200241046a410110780c0c0b200241043a00042001200241046a410110782000410c6a200110e2012002200041106a360210200241106a200110cf010c0b0b200241053a00042001200241046a4101107820022000410c6a2802003602102001200241106a410410780c0a0b200241063a00042001200241046a410110782000410c6a200110e2012002200041106a360210200241106a200110cf010c090b200241073a00042001200241046a410110782000412c6a200110e2012001200541016a412010780c080b200241083a00042001200241046a410110782000410c6a200110e2012002200041106a2903003703102001200241106a410810780c070b200241093a00042001200241046a410110782000410c6a200110e201200041106a200110fc05200041386a200110aa040c060b2002410a3a00042001200241046a410110782000410c6a200110fc050c050b200241183a00102001200241106a41011078200041086a22052d0000417f6a2203410b4b0d0402400240024002400240024002400240024002400240024020030e0c000102030405060708090a0b000b200241003a00042001200241046a41011078200041106a29030021072002200041186a290300370318200220073703102001200241106a411010780c0f0b200241013a00042001200241046a4101107820022000410c6a2802003602102001200241106a410410780c0e0b200241023a00042001200241046a410110782001200541016a41201078200041306a29030021072002200041386a290300370318200220073703102001200241106a41101078200041c0006a29030021072002200041c8006a290300370318200220073703102001200241106a411010780c0d0b200241033a00042001200241046a4101107820022000410c6a2802003602102001200241106a410410780c0c0b200241043a00042001200241046a410110782000410c6a200110fc05200220002d00093a00042001200241046a410110780c0b0b200241053a00042001200241046a41011078200220052d00013a00042001200241046a410110780c0a0b200241063a00042001200241046a410110780c090b200241073a00042001200241046a410110782001200541016a4120107820022000412c6a2802003602102001200241106a41041078200041306a2802002103200041386a28020022002001107720012003200010780c080b200241083a00042001200241046a410110780c070b200241093a00042001200241046a410110782001200541016a412010782002200541216a2d00003a00042001200241046a410110780c060b2002410a3a00042001200241046a410110782001200541016a41201078200541216a2d0000220041024b0d0502400240024020000e03000102000b200241003a00042001200241046a410110780c070b200241013a00042001200241046a410110780c060b200241023a00042001200241046a410110780c050b2002410b3a00042001200241046a4101107820022000410c6a2802003602102001200241106a410410780c040b200241193a00102001200241106a4101107820002d0004417f6a220341084b0d03200041046a210502400240024002400240024002400240024020030e09000102030405060708000b200241003a00042001200241046a410110782001200541016a41201078200041286a280200200110af030c0b0b200241013a00042001200241046a410110782001200541016a412010782001200541216a412010780c0a0b200241023a00042001200241046a41011078200041086a2802002103200041106a28020022052001107702402005450d002005410574210503402001200341201078200341206a2103200541606a22050d000b0b200220002f01063b01102001200241106a41021078200220002802143602102001200241106a410410780c090b200241033a00042001200241046a410110782001200541016a412010780c080b200241043a00042001200241046a410110782001200541016a412010782001200541216a412010780c070b200241053a00042001200241046a410110782001200541016a412010780c060b200241063a00042001200241046a410110782001200541016a412010780c050b200241073a00042001200241046a410110780c040b200241083a00042001200241046a410110782001200541016a412010780c030b2002411a3a00102001200241106a41011078200041086a280200417f6a220341024b0d0202400240024020030e03000102000b200241003a00042001200241046a410110780c040b200241013a00042001200241046a410110782000410c6a200110fc050c030b200241023a00042001200241046a410110782000410c6a200110fc05200041306a29030021072002200041386a290300370318200220073703102001200241106a41101078200041c0006a29030021072002200041c8006a290300370318200220073703102001200241106a411010782002200041d0006a2802003602102001200241106a410410780c020b2002411b3a00102001200241106a410110780b200110ff050b200241206a24000f0b1045000bf30703027f017e067f230041e0006b2203240041a8fdc600ad4280808080f00084100122042900002105200341086a200441086a29000037030020032005370300200410354180a9c300ad4280808080900184100122042900002105200341106a41086a200441086a29000037030020032005370310200410350240024002400240412010332204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020032004ad42808080808004841003220129000037034020011035200341dc006a2206200441206a360200200320043602582003200341c0006a41086a3602542003200341c0006a360250200341206a200341d0006a107b20041035412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a2900003700002004ad4280808080800484100422012900002105200341c0006a41086a200141086a29000037030020032005370340200110352006200441206a360200200320043602582003200341c0006a41106a3602542003200341c0006a360250200341306a200341d0006a107b200410352003280228220741206a2206200328023822086a2201417f4c0d01200328023021092003280220210a0240024020010d004100210b410121040c010b200110332204450d012001210b0b02400240200b410f4d0d00200b21020c010b200b41017422024110200241104b1b22024100480d030240200b0d002002103322040d010c050b200b2002460d002004200b200210372204450d040b20042003290300370000200441086a200341086a2903003700000240024020024170714110460d002002210b0c010b2002410174220b4120200b41204b1b220b4100480d032002200b460d0020042002200b10372204450d040b20042003290310370010200441186a200341106a41086a29030037000002400240200b41606a2007490d00200b21020c010b2007415f4b0d03200b41017422022006200220064b1b22024100480d03200b2002460d002004200b200210372204450d040b200441206a200a2007109d081a02400240200220066b2008490d002002210b0c010b20012006490d032002410174220b2001200b20014b1b220b4100480d03024020020d000240200b0d00410121040c020b200b10332204450d050c010b2002200b460d0020042002200b10372204450d040b200420066a20092008109d081a200020013602082000200b3602042000200436020002402003280234450d00200910350b02402003280224450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000bb10101027f024020002802082201450d0020002802002100200141246c210103400240024020002d0000220241044b0d0002400240024020020e050400010204040b2000410c6a280200450d03200041086a28020010350c030b2000410c6a280200450d02200041086a28020010350c020b2000410c6a280200450d01200041086a28020010350c010b200041086a280200450d00200041046a28020010350b200041246a21002001415c6a22010d000b0b0b13002000410c36020420004190aac3003602000beb0d02097f027e230041e0006b22022400200241386a4100290288e146370300200241306a4100290280e146370300200241286a41002902f8e046370300200241206a41002902f0e046370300200241186a41002902e8e046370300200241106a41002902e0e046370300200241086a41002902d8e046370300200241002902d0e0463703002002410036024820024201370340200241d0006a200210b40320022802502103024002400240024020022802442204200228024822056b20022802582206490d00200228024021070c010b200520066a22072005490d01200441017422082007200820074b1b22084100480d010240024020040d00024020080d00410121070c020b2008103322070d010c040b2002280240210720042008460d0020072004200810372207450d030b20022008360244200220073602400b200720056a20032006109d081a2002200520066a36024802402002280254450d00200310350b200241d0006a200241106a10b403200228025021080240024020022802442204200228024822056b20022802582203490d0020022802402106200421070c010b200520036a22062005490d01200441017422072006200720064b1b22074100480d010240024020040d00024020070d00410121060c020b200710332206450d040c010b2002280240210620042007460d0020062004200710372206450d030b20022007360244200220063602400b200620056a20082003109d081a2002200520036a220336024802402002280254450d00200810350b02400240200720036b4104490d00200341046a21050c010b200341046a22052003490d01200741017422042005200420054b1b22044100480d010240024020070d00024020040d00410121060c020b200410332206450d040c010b20072004460d0020062007200410372206450d030b20022004360244200220063602400b200620036a410a3600002002200536024820022802242103024002402002280244220720056b4104490d00200228024021060c010b200541046a22062005490d01200741017422042006200420064b1b22044100480d010240024020070d00024020040d00410121060c020b200410332206450d040c010b2002280240210620072004460d0020062007200410372206450d030b20022004360244200220063602400b200620056a20033600002002200541046a220636024820022802282104024002402002280244220320066b4104490d00200228024021070c010b200641046a22072006490d01200341017422082007200820074b1b22084100480d010240024020030d00024020080d00410121070c020b200810332207450d040c010b2002280240210720032008460d0020072003200810372207450d030b20022008360244200220073602400b200720066a20043600002002200541086a360248200241306a2802002108200241386a200241346a200228022c4101461b2802002205200241c0006a1077024002402005410c6c22050d00200228024821040c010b200820056a21092002280244210620022802482104034002400240200620046b4108490d00200441086a210520022802402103200621070c010b200441086a22052004490d03200641017422072005200720054b1b22074100480d030240024020060d00024020070d00410121030c020b200710332203450d060c010b2002280240210320062007460d0020032006200710372203450d050b20022007360244200220033602400b200320046a200829000037000020022005360248200841086a280200210402400240200720056b41034d0d00200721060c010b200541046a22062005490d032007410174220a2006200a20064b1b22064100480d030240024020070d00024020060d00410121030c020b200610332203450d060c010b20072006460d0020032007200610372203450d050b20022006360244200220033602400b200320056a20043600002002200541046a22043602482008410c6a22082009470d000b0b200228023c2107024002402002280244220620046b4104490d00200228024021050c010b200441046a22052004490d01200641017422032005200320054b1b22034100480d010240024020060d00024020030d00410121050c020b200310332205450d040c010b2002280240210520062003460d0020052006200310372205450d030b20022003360244200220053602400b200520046a2007360000200441046aad210b2002350240210c02402002280200450d00200241086a280200450d00200228020410350b200b422086210b02402002280210450d00200241186a280200450d00200241146a28020010350b200b200c84210b0240200228022c450d0020022802342205450d002005410c6c450d00200228023010350b200241e0006a2400200b0f0b103e000b103c000bd80401067f20012802042102024002400240024020012802004101470d002001410c6a280200220141046a2203417f4c0d0102400240024002400240024002400240024002402003450d00200310332204450d0c200141c000490d04200141808001490d052001418080808004490d0620030d010b41012103410110332204450d07200441033a0000410521050c010b200441033a000002402003417f6a41034d0d00200321050c020b200341017422064105200641054b1b22054100480d0720032005460d010b20042003200510372204450d050b20042001360001410521060c030b024020030d0041012103410110332204450d040b200420014102743a000041012106200321050c020b02400240200341014d0d00200321050c010b200341017422064102200641024b1b2105024020030d002005103322040d010c040b20032005460d0020042003200510372204450d030b41022106200420014102744101723b00000c010b02400240200341034d0d00200321050c010b200341017422064104200641044b1b22054100480d03024020030d002005103322040d010c030b20032005460d0020042003200510372204450d020b20042001410274410272360000410421060b0240200520066b2001490d00200521030c060b200620016a22032006490d01200541017422072003200720034b1b22034100480d0120052003460d05200420052003103722040d050b103c000b103e000b20002002200141086a28020010d3030f0b1044000b1045000b200420066a20022001109d081a2000200620016a36020820002003360204200020043602000b9b1a03047f017e057f230041a00e6b22022400024002402001450d00200220003602300c010b200241b0b4cc003602300b20022001360234200241c00a6a200241306a10b60302400240024020022802c40a450d00200241386a200241c00a6a41fc00109d081a200241b8016a200241386a41fc00109d081a200241b8016a10b703024020022802b8012201450d00200241b8026a2001417f6a10b803200241c00a6a20022802b802220120022802c00210d501200241e8066a41086a2200200241c90a6a290000370300200241e8066a41106a2203200241d10a6a290000370300200241e8066a41186a2204200241d90a6a290000370300200220022900c10a3703e8060240024020022d00c00a4101460d00200241a8036a41186a4200370300200241a8036a41106a4200370300200241a8036a41086a4200370300200242003703a8030c010b200241a8036a41186a2004290300370300200241a8036a41106a2003290300370300200241a8036a41086a2000290300370300200220022903e8063703a8030b024020022802bc02450d00200110350b200241a8036a200241c8016a412010a0080d00200241b0026a280200210120022802a8022100200241003602f006200242043703e806200241e8066a4100200110870120022802f006210402402001450d00200141c8036c21032001410374210520022802e8062004410c6c6a21010340200220003602a803200241c00a6a200241a8036a10b903200141086a200241c00a6a41086a280200360200200120022903c00a3702002001410c6a2101200041c8036a2100200341b87c6a22030d000b200541786a41037620046a41016a21040b200241a8036a41086a2004360200200220022903e80622063703a803200241e8066a41086a2004360200200220063703e806200241c00a6a200241e8066a10ba03024020024188026a2201200241c00a6a412010a008450d0041ec9ccc00ad4280808080e0018410062001ad4280808080800484100a200241c00a6aad4280808080800484100a0b02402001200241c00a6a412010a0080d00100b200241ac026a280200210720022802a802210520022802b0022103200241b8026a200241b8016a41f000109d081a2005200341c8036c6a210020022802b8022108200521010240024002402003450d00200241e8066a41f0006a2104200521010240034020024180066a200141e800109d081a200141e8006a2903002106200241a8036a200141f0006a41d802109d081a20064203510d01200241e8066a20024180066a41e800109d081a200220063703d0072004200241a8036a41d802109d081a2002200241e8066a3602b00a200241c00a6a200241b00a6a10b90320022802c80a2103024020022802c40a450d0020022802c00a10350b200241c00a6a200241e8066a41c803109d081a200241003602880e200241b00a6a200241c00a6a2003200241880e6a10bb0320022d00b00a4101460d04200141c8036a22012000470d000c030b0b200141c8036a21010b20002001460d00034020014198016a10bb022000200141c8036a2201470d000b0b02402007450d00200741c8036c450d00200510350b10bc03200810bd030240100c4101470d00200241c00a6a10be03200241206a200241b8026a410472220110bf032002200228022422003602980e200241186a200241c00a6a410472220310bf032002200228021c220436029c0e20002004470d06200241106a200110bf0320022802102105200241086a200310bf03200228020c220120022802142200200020014b1b2209450d05200228020821074100210341edc5ca00ad4280808080c002842106410021040340024002400240024002400240024002400240200520036a22012d00002208200720036a22002d0000470d0002400240024002400240024020080e06000102030405000b20052007460d0d200141016a200041016a412010a0080d050c060b024020052007460d00200141016a280000200041016a280000470d050b200141106a2802002208200041106a280200470d04200141086a280200220a200041086a280200220b460d0a200a200b200810a0080d040c0a0b024020052007460d00200141016a280000200041016a280000470d040b200141106a2802002208200041106a280200470d03200141086a280200220a200041086a280200220b460d08200a200b200810a0080d030c080b024020052007460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a280200220a200041086a280200220b460d06200a200b200810a0080d020c060b200141046a2802002208200041046a280200470d012008450d04200141086a280200200041086a280200470d012001410c6a2802002000410c6a280200470d010c040b2001410c6a28020022082000410c6a280200470d00200141046a280200220a200041046a280200220b460d02200a200b200810a008450d020b20061006200241e8066a200110c00320023502f00642208620022802e8062208ad84100a024020022802ec06450d00200810350b200241e8066a200010c00320023502f00642208620022802e8062208ad84100a024020022802ec06450d00200810350b20012d000020002d00002208470d06024020080e06000605040302000b20052007460d070b200141016a200041016a412010a0080d050c060b2001410c6a28020022082000410c6a280200470d04200141046a2802002201200041046a2802002200460d0520012000200810a0080d040c050b200141046a2802002208200041046a280200470d032008450d04200141086a280200200041086a280200470d032001410c6a2802002000410c6a280200460d040c030b024020052007460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a2802002201200041086a2802002200460d0320012000200810a0080d020c030b024020052007460d00200141016a280000200041016a280000470d020b200141106a2802002208200041106a280200470d01200141086a2802002201200041086a2802002200460d0220012000200810a0080d010c020b024020052007460d00200141016a280000200041016a280000470d010b200141106a2802002208200041106a280200470d00200141086a2802002201200041086a2802002200460d0120012000200810a008450d010b4188cfc400412741c086cc00103f000b200341246a2103200441016a22042009490d000c060b0b41d7cfc400411e41c086cc00103f000b200241286a20022f00b10a20022d00b30a4110747210c1032002280228200228022c41c086cc00103f000b41dccec400412441c086cc00103f000b41c0cec400411c41c086cc00103f000b200241b4036a4104360200200241fc066a4102360200200242023702ec06200241f0b2c3003602e806200241043602ac03200241e8b2c3003602a803200241003602bc01200241b0b4cc003602b8012002200241a8036a3602f8062002200241b8016a3602b003200241e8066a4180b3c300104c000b0240200241b8026a41306a2201200241c00a6a41306a2200412010a008450d0041ec9ccc00ad4280808080e0018410062001ad4280808080800484100a2000ad4280808080800484100a0b024020012000412010a008450d0041afcfc400412841c086cc00103f000b0240200241c00a6a410c6a2802002200450d0020022802c40a2101200041246c210003400240024020012d0000220341044b0d0002400240024020030e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b0240200241c80a6a2802002201450d00200141246c450d0020022802c40a10350b0240200241b8026a410c6a2802002200450d0020022802bc022101200041246c210003400240024020012d0000220341044b0d0002400240024020030e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b0240200241c0026a2802002201450d00200141246c450d0020022802bc0210350b200241a00e6a240042010f0b200241a8036a41146a410a360200200241b4036a410c36020020024180066a41146a41033602002002200241980e6a3602880e20022002419c0e6a3602b00a200241e8066a41146a41003602002002420337028406200241a0b3cc00360280062002410c3602ac03200241b0b4cc003602f806200242013702ec0620024180cfc4003602e8062002200241a8036a360290062002200241e8066a3602b8032002200241b00a6a3602b0032002200241880e6a3602a80320024180066a41b0b4cc00104c000bc10603077f017e037f230041c00b6b22022400200241f8076a200110c4030240024020022802fc072203450d0020024184086a2802002104200228028008210520022802f8072106200241086a20024188086a41e000109d081a2002200110c40102400240024020022802000d0020022802042207200128020441c8036e2208200820074b1bad42c8037e2209422088a70d012009a7220a417f4c0d0102400240200a0d004108210b0c010b200a1033220b450d030b41002108200241003602702002200b3602682002200a41c8036e36026c024002402007450d00200241f8076a41f0006a210c0340200241f8076a200110c80320024190076a200241f8076a41e800109d081a20022903e0082109200241b8046a200c41d802109d081a20094203510d02200241d0036a20024190076a41e800109d081a200241f8006a200241b8046a41d802109d081a02402008200228026c470d00200241e8006a200810a9012002280268210b200228027021080b200b200841c8036c6a200241d0036a41e800109d08220a2009370368200a41f0006a200241f8006a41d802109d081a2002200841016a22083602702007417f6a22070d000b0b200b450d01200229026c2109200241f8076a200241086a41e000109d081a2000410c6a2004360200200020053602082000200336020420002006360200200041106a200241f8076a41e000109d081a200041f4006a2009370200200041f0006a200b3602000c050b02402008450d00200841c8036c2107200b4198016a21080340200810bb02200841c8036a2108200741b87c6a22070d000b0b200228026c2208450d00200841c8036c450d00200b10350b2000410036020402402004450d00200441246c21072003210803400240024020082d0000220141044b0d0002400240024020010e050400010204040b2008410c6a280200450d03200841086a28020010350c030b2008410c6a280200450d02200841086a28020010350c020b2008410c6a280200450d01200841086a28020010350c010b200841086a280200450d00200841046a28020010350b200841246a21082007415c6a22070d000b0b2005450d03200541246c450d03200310350c030b1044000b1045000b200041003602040b200241c00b6a24000bb83a05047f017e057f017e107f230041f01a6b22012400200141186a200010df03200141c8156a41186a4200370300200141c8156a41106a22024200370300200141c8156a41086a22034200370300200142003703c81541d1c4c700ad4280808080e000841001220429000021052003200441086a290000370300200120053703c8152004103541c8f1c700ad4280808080a00284100122042900002105200141b8106a41086a2206200441086a290000370300200120053703b81020041035200220012903b8102205370300200141a0186a41086a2003290300370300200141a0186a41106a2005370300200141a0186a41186a2006290300370300200120012903c8153703a0182001412036028c062001200141a0186a36028806200141e80d6a200141a0186aad22054280808080800484100510c20102400240024002400240024002400240024002400240024020012802e80d22040d00410221030c010b20012802ec0d21072001200141e80d6a41086a2802003602dc08200120043602d808200141106a200141d8086a10c401200128021421080240024020012802100d00200141086a200141d8086a10c40120012802080d0020012802dc082209200128020c2203490d002003417f4c0d030240024020030d0041002109410121060c010b200310392206450d09200620012802d808220a2003109d081a2001200920036b3602dc082001200a20036a3602d808200321090b2006450d002003ad4220862009ad84210b410121030c010b200141003602c010200142013703b810200141093602ac0b200120014188066a3602a80b2001200141b8106a3602b803200141dc156a4101360200200142013702cc15200141c888c2003602c8152001200141a80b6a3602d815200141b8036a41e88ac500200141c8156a10431a20013502c01042208620013502b810841006024020012802bc10450d0020012802b81010350b410221030b2007450d00200410350b02400240024002400240024020034102460d00200ba72104410121070240200841f501490d00410021080240200b422088a7200420034101461b4104470d004101210820064190e1c600460d00200628000041eede91ab064621080b200841017321070b02402004450d00200610350b2007450d010b200141c4106a41002902d8e046370200200141f5013602b810200141002902d0e0463702bc10200141c8156a41186a4200370300200141c8156a41106a22064200370300200141c8156a41086a22034200370300200142003703c81541d1c4c700ad4280808080e0008410012204290000210b2003200441086a2900003703002001200b3703c8152004103541c8f1c700ad4280808080a0028410012204290000210b200141286a41086a2208200441086a2900003703002001200b3703282004103520062001290328220b370300200141a0186a41086a2003290300370300200141a0186a41106a200b370300200141a0186a41186a2008290300370300200120012903c8153703a018200141003602f00d200142013703e80d41f501200141e80d6a1077200141c8156a200141b8106a41047210b40320012802c81521090240024020012802ec0d220720012802f00d22046b20012802d0152206490d0020012802e80d2103200721080c010b200420066a22032004490d02200741017422082003200820034b1b22084100480d020240024020070d00024020080d00410121030c020b2008103322030d010c110b20012802e80d210320072008460d0020032007200810372203450d100b200120083602ec0d200120033602e80d0b200320046a20092006109d081a2001200420066a22043602f00d024020012802cc15450d00200910350b200542808080808004842004ad4220862003ad84100202402008450d00200310350b420010c8040b2000280200200041106a200041d0006a200141186a410110e00320012000280200220c36023c2001428089fa00370340200141a0186a200c10c904200141c8156a20012802a018220020012802a818220310b8020240024020012802c815220d0d00420021054108210d0c010b2003ad4220862000ad84100720012902cc1521050b024020012802a418450d00200010350b200d2005422088a7220341d0026c22066a21042005a7210e200d21002003450d07200641b07d6a2107200141c8156a41046a210f200141a0186a41046a210a200141e80d6a41046a211041002106200141d8006a41086a2108200d210002400340200141e8006a200041bc02109d081a200041bc026a28020021032008200041c8026a2903003703002001200041c0026a290300370358024020034103470d00200041d0026a21000c0a0b2010200141e8006a41bc02109d082111200141a0186a200141e80d6a41c002109d081a20014188136a200a41bc02109d081a200141f8126a41086a22092008290300370300200120012903583703f8120240024020034102470d00410121090c010b200f20014188136a41bc02109d081a200141a80b6a200141c8156a41c002109d081a200141980b6a41086a2009290300370300200120012903f8123703980b41002109200621120b200141d8086a200141a80b6a41c002109d081a200141c8086a41086a200141980b6a41086a290300370300200120012903980b3703c8082009450d01200641016a2106200741b07d6a2107200041d0026a22002004470d000b200421000c080b200141b8036a200141d8086a41c002109d081a200141a8036a41086a2208200141c8086a41086a290300370300200120012903c8083703a803200141b8106a200141b8036a41c002109d081a200141a8106a41086a22092008290300370300200120012903a8033703a810200041d0026a210020034102460d0720014188066a200141b8106a41c002109d081a200141f8056a41086a22082009290300370300200120012903a8103703f805200141c8156a20014188066a41c002109d081a200141a0186a41086a2008290300370300200120012903f8053703a01841d80210332213450d0920132012360200201341046a200141c8156a41c002109d081a201320033602c402201320012903a0183703c802201341d0026a200141a0186a41086a290300370300200142818080801037024c20012013360248200421032007450d02200641016a2108200141b8106a41046a2109200141980b6a41086a210302400340200141b8036a200041bc02109d081a200041bc026a28020021062003200041c8026a2903003703002001200041c0026a2903003703980b024020064103470d00200041d0026a21030c050b2009200141b8036a41bc02109d081a200141a0186a200141b8106a41c002109d081a20014188136a200a41bc02109d081a200141f8126a41086a22072003290300370300200120012903980b3703f8120240024020064102470d00410121070c010b200f20014188136a41bc02109d081a200141e80d6a200141c8156a41c002109d081a200141e8006a41086a2007290300370300200120012903f81237036841002107200821100b200141a80b6a200141e80d6a41c002109d081a200141a8106a41086a200141e8006a41086a290300370300200120012903683703a8102007450d01200841016a2108200041d0026a22002004470d000b20042103410121140c040b200141d8086a200141a80b6a41c002109d081a200141c8086a41086a2209200141a8106a41086a2215290300370300200120012903a8103703c808200041d0026a21034101211420064102460d03200841016a210020014188066a200141d8086a41c002109d081a200141f8056a41086a22162009290300370300200120012903c8083703f80541012108410121140340200141c8156a20014188066a41c002109d081a200141a0186a41086a22072016290300370300200120012903f8053703a018024020142008470d00200141c8006a20084101109501200128024821130b2013201441d8026c6a22082010360200200841046a200141c8156a41c002109d081a200841c4026a2006360200200841c8026a20012903a018370300200841d0026a20072903003703002001201441016a2214360250024020032004470d00200421030c050b02400340200141e8006a200341bc02109d081a200341bc026a2802002106200141d8006a41086a2208200341c8026a2903003703002001200341c0026a290300370358024020064103470d00200341d0026a21030c070b2011200141e8006a41bc02109d081a200141a0186a200141e80d6a41c002109d081a20014188136a200a41bc02109d081a200141f8126a41086a22072008290300370300200120012903583703f8120240024020064102470d00410121080c010b200f20014188136a41bc02109d081a200141a80b6a200141c8156a41c002109d081a200141286a41086a20072903002205370300200141980b6a41086a2005370300200120012903f8122205370328200120053703980b41002108200021120b200141d8086a200141a80b6a41c002109d081a2009200141980b6a41086a290300370300200120012903980b3703c8082008450d01200041016a2100200341d0026a22032004470d000b200421030c050b200141b8036a200141d8086a41c002109d081a200141a8036a41086a22082009290300370300200120012903c8083703a803200141b8106a200141b8036a41c002109d081a20152008290300370300200120012903a8033703a81020064102460d02200341d0026a2103200041016a210020014188066a200141b8106a41c002109d081a20162015290300370300200120012903a8103703f805200128024c2108201221100c000b0b103e000b200341d0026a21030c010b410121140b024020042003460d000340200341d0026a21000240200341bc026a2802004102460d000240200341b0026a2802002206450d00200341b4026a280200450d00200610350b200310bb020b2000210320042000470d000b0b0240200e450d00200e41d0026c450d00200d10350b200128024c211720144115490d022014410176ad42d8027e2205422088a70d002005a72218417f4c0d00201810332219450d0541002100200141003602a818200142043703a018201341a87d6a211a201341c87a6a211b410421034100210f20142112034020122109410021124101210702402009417f6a220e450d000240024002400240024002402013200e41d8026c6a41d0026a2d0000200941d8026c221020136a41a07d6a2d00002206490d002009417e6a210a201b20106a2108410021124100210403400240200a2004470d00200921070c080b200441016a2104200641ff0171210720082d00002106200841a87d6a2108200720064f0d000b200441016a21072004417f7320096a21040c010b201b20106a2108200e210402400340024020044101470d00410021040c020b2004417f6a2104200641ff0171210720082d00002106200841a87d6a210820072006490d000b0b20092004490d02200920144b0d01200920046b2207410176220a450d002013200441d8026c6a2106201a20106a21080340200141c8156a200641d802109d081a2006200841d802109e0841d8026a21062008200141c8156a41d802109d0841a87d6a2108200a417f6a220a0d000b0b024020040d00200421120c050b0240200741094d0d00200421120c050b200920144b0d022013200441d8026c6a2110034020092004417f6a2212490d040240200920126b22074102490d002013200441d8026c6a220841d0026a2d00002013201241d8026c6a220641d0026a2d0000220d4f0d00200141c8156a200641d002109d081a2001200641d4026a2800003600bb102001200641d1026a2800003602b8102006200841d802109d082111024020074103490d00200e210a2010210620114180086a2d0000200d4f0d0003402006200641d8026a220841d802109d0821112004200a417f6a220a460d012008210620114180086a2d0000200d490d000b0b2008200141c8156a41d002109d08220441d0026a200d3a0000200441d1026a20012802b810360000200441d4026a20012800bb103600000b2012450d05201041a87d6a2110201221042007410a4f0d050c000b0b2009201441eccfca001058000b2004200941eccfca001059000b20092004417f6a2212490d002009201441fccfca001058000b2012200941fccfca001059000b0240200f20012802a418470d00200141a0186a200f410110900120012802a018210320012802a8182200210f0b2003200f4103746a22042007360204200420123602002001200041016a22003602a8182000210f024020004102490d000240024003400240024002400240024020032000417f6a4103746a2204280200450d00200041037420036a220741746a2802002208200428020422064b0d010b20004103490d022004280204210620032000417d6a22114103746a28020421040c010b4102210f200041024d0d0620032000417d6a22114103746a2802042204200620086a4d0d004103210f200041034d0d06200741646a280200200420086a4b0d050b20042006490d010b2000417e6a21110b02400240024002400240024002402000201141016a220d4d0d00200020114d0d0120032011410374220e6a2200280204221520002802006a22002003200d41037422166a2203280200220f490d02200020144b0d032013200f41d8026c6a220a2003280204221041d8026c22036a2106200041d8026c21072000200f6b220820106b220020104f0d0420192006200041d8026c2203109d08220820036a210420104101480d0520004101480d05201a20076a21072006210303402007200341a87d6a2206200441a87d6a2209200441786a2d0000200341786a2d00004922001b41d802109d0821072004200920001b21040240200a2006200320001b2203490d00200821000c080b200741a87d6a21072008210020082004490d000c070b0b200d2000418cd0ca001042000b20112000419cd0ca001042000b200f200041acd0ca001059000b2000201441acd0ca001058000b2019200a2003109d08220020036a2104024020104101480d00200820104c0d00201320076a210920002100200a2103034020062000200641d0026a2d0000200041d0026a2d00004922081b21072000200041d8026a20081b21002003200741d802109d0841d8026a2103200641d8026a200620081b220620094f0d03200420004b0d000c030b0b200a2103200021000c010b20062103200821000b20032000200420006b2204200441d802706b109d081a024020012802a818220020114d0d0020012802a0182203200e6a2204201520106a3602042004200f3602002000200d4d0d02200320166a2204200441086a2000200d417f736a410374109e081a20012000417f6a22003602a818200041014b0d010c030b0b2011200041bcd0ca001042000b200d2000104e000b2000210f0b2012450d020c000b0b1044000b024020012802a41841ffffffff0171450d00200310350b201841d802702100201841d802490d0220182000460d02201910350c020b20144102490d012014417f6a21032013201441d8026c6a2106410021080340024002400240201420032200417f6a2203490d00201420036b22074102490d022013200041d8026c6a220041d0026a2d00002013200341d8026c6a220441d0026a2d000022094f0d02200141c8156a200441d002109d081a2001200441d4026a2800003600bb102001200441d1026a2800003602b8102004200041d802109d08210a20074103490d012008210420062107200a4180086a2d000020094f0d0103402007220041a87d6a200041d802109d081a2004417f6a2204450d02200041d8026a2107200041a8056a2d000020094f0d020c000b0b2003201441dccfca001059000b2000200141c8156a41d002109d08220041d0026a20093a0000200041d1026a20012802b810360000200041d4026a20012800bb103600000b200841016a2108200641a87d6a210620030d000c020b0b024020042000460d000340200041d0026a21030240200041bc026a2802004102460d000240200041b0026a2802002206450d00200041b4026a280200450d00200610350b200010bb020b2003210020042003470d000b0b41002114410821130240200e450d00200e41d0026c450d00200d10350b410021170b200142003703d808200141800e6a4100360200200141fc0d6a2013201441d8026c6a360200200141f80d6a2013360200200141f40d6a2017360200200141900e6a200141d8086a3602002001418c0e6a2001413c6a360200200120133602f00d200142003703e80d2001200141c0006a3602880e200141a0186a200141e80d6a10ca04024020012802dc1a4103460d00200141c8156a200141a0186a41d002109d081a41d00210332206450d012006200141c8156a41d002109d08210020014281808080103702ac0b200120003602a80b200141b8106a41286a200141e80d6a41286a290300370300200141b8106a41206a200141e80d6a41206a290300370300200141b8106a41186a200141e80d6a41186a290300370300200141b8106a41106a2208200141e80d6a41106a290300370300200141b8106a41086a200141e80d6a41086a290300370300200120012903e80d3703b810200141a0186a200141b8106a10ca04024020012802dc1a4103470d00410121030c030b4102210341d0022100410121040340200141c8156a200141a0186a41d002109d081a02402003417f6a2004470d00200141a80b6a2004410110a70120012802a80b21060b200620006a200141c8156a41d002109d081a200120033602b00b200141a0186a200141b8106a10ca0420012802dc1a4103460d03200041d0026a2100200341016a210320012802ac0b21040c000b0b20012802fc0d20012802f80d22046b220041d8026d210302402000450d00200341d8026c2103200441bc026a2100034002402000417c6a2802002204450d002000280200450d00200410350b200041cc7d6a10bb02200041d8026a2100200341a87d6a22030d000b0b024020012802f40d2200450d00200041d8026c450d0020012802f00d10350b41082106410021080c020b1045000b200141cc106a280200200828020022086b220041d8026d210402402000450d00200441d8026c2104200841bc026a2100034002402000417c6a2802002208450d002000280200450d00200810350b200041cc7d6a10bb02200041d8026a2100200441a87d6a22040d000b0b0240200141c4106a2802002200450d00200041d8026c450d0020012802c01010350b20012802ac0b21082003450d00200128023c41016a2006200310cb04200341d0026c210320012903d80821052006210003400240200041bc026a2802004102460d000240200041b0026a2802002204450d00200041b4026a280200450d00200410350b200010bb020b200041d0026a2100200341b07d6a22030d000c020b0b20012903d80821050b02402008450d00200841d0026c450d00200610350b427f427f2005200c10cc047c220b200b2005541b22054280e497d0127c220b200b2005541b10c804200142003703e80d200141c8156a41186a22044200370300200141c8156a41106a22064200370300200141c8156a41086a22004200370300200142003703c81541d1c4c700ad4280808080e000841001220329000021052000200341086a290000370300200120053703c815200310354188f2c700ad4280808080e00184100122032900002105200141b8106a41086a2208200341086a290000370300200120053703b81020031035200220012903b810370000200241086a2008290300370000200141a0186a41086a2000290300370300200141a0186a41106a2006290300370300200141a0186a41186a2004290300370300200120012903c8153703a018200141203602cc152001200141a0186a3602c815200141e80d6a200141c8156a10cd0420012802182106024020012802202200450d00200041246c21032006210003400240024020002d0000220441044b0d0002400240024020040e050400010204040b2000410c6a280200450d03200041086a28020010350c030b2000410c6a280200450d02200041086a28020010350c020b2000410c6a280200450d01200041086a28020010350c010b200041086a280200450d00200041046a28020010350b200041246a21002003415c6a22030d000b0b0240200128021c2200450d00200041246c450d00200610350b200141f01a6a24000f0b103c000bfc0403027f017e057f230041d0006b2202240041d1c4c700ad4280808080e00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541dec4c700ad4280808080900184100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000b981103067f027e067f230041c0006b22022400024002400240024041ca0310332203450d00200241ca0336020420022003360200200341003b00002002410236020802400240200128020022032903684202520d00024020022802044102470d0020022802004102410410372201450d0620024104360204200220013602000b200228020041043a00022002200228020841016a3602080c010b024020022802044102470d0020022802004102410410372201450d0520024104360204200220013602000b20022802004184013a00022002200228020841016a3602082003200210fc05024020032d0024220141024b0d000240024002400240024020010e03000102000b410021040c020b410121040c010b41022104200241023a001041c10021050c010b200220043a001041c00021050b02400240200228020420022802082201460d00200228020021060c010b200141016a22062001490d05200141017422072006200720064b1b22074100480d050240024020010d0041002101024020070d00410121060c020b2007103322060d010c080b2002280200210620012007460d0020062001200710372206450d070b20022007360204200220063602000b200620016a20043a00002002200141016a2201360208024002402002280204220420016b2005490d00200228020021060c010b200120056a22062001490d05200441017422072006200720064b1b22074100480d050240024020040d00024020070d00410121060c020b200710332206450d080c010b2002280200210620042007460d0020062004200710372206450d070b20022007360204200220063602000b200620016a200341256a2005109d081a2002200120056a3602080b02400240200341e8006a22012903004201520d00200129031020012903082208420c882209420120094201561b8021090240024020022802042204200228020822056b4102490d00200228020021060c010b200541026a22062005490d06200441017422072006200720064b1b22074100480d060240024020040d00024020070d00410121060c020b200710332206450d090c010b2002280200210620042007460d0020062004200710372206450d080b20022007360204200220063602000b200620056a2009a741047420087aa7417f6a22064101200641014b1b2206410f2006410f491b723b0000200541026a21050c010b02400240200228020420022802082205460d00200228020021060c010b200541016a22062005490d05200541017422042006200420064b1b22044100480d050240024020050d0041002105024020040d00410121060c020b200410332206450d080c010b2002280200210620052004460d0020062005200410372206450d070b20022004360204200220063602000b200620056a41003a0000200541016a21050b20022005360208200141186a200210e2012002200141206a360210200241106a200210cf010b20034198016a200210af0320022802082103410410332201450d0020024204370214200220013602102003417e6a200241106a10772002280208220341014d0d01200228021821012002280214210a200220022802102207360224200241286a200720016a2205360200200241023602102002411c6a2002280200220641026a2204360200410021012002410036020820022003417e6a22033602142002200436021820022002360220200241246a210b0240024002402003450d0020072103034020032005460d032002200341016a360224200620016a20032d00003a00002002200228020841016a36020820014101460d02200141016a210120022802242103200228022821050c000b0b2002200b10c7050c010b024020022802282204200228022422036b2201450d00024002402002280220220641046a280200220c2002280214220d2002280210220e6a22056b2001490d00200628020021050c010b200520016a220f2005490d05200c4101742205200f2005200f4b1b220f4100480d0502400240200c0d000240200f0d00410121050c020b200f10332205450d080c010b20062802002105200c200f460d002005200c200f10372205450d070b20062005360200200641046a200f3602000b2005200e20016a22016a2005200e6a200d109e081a20022001360210200120062802082205460d00200520036a417f732004200e6a6a2101200628020020056a2105034020032004460d022002200341016a360224200520032d00003a00002006200628020841016a3602082001450d01200541016a21052001417f6a210120022802242103200228022821040c000b0b2002410036023820024201370330200241306a200b10c7052002280234210b2002280230210e024020022802382203450d00024002402002280220220641046a28020022042002280214220c200228021022056a22016b2003490d00200628020021010c010b200120036a220d2001490d0520044101742201200d2001200d4b1b220d4100480d050240024020040d000240200d0d00410121010c020b200d10332201450d080c010b200628020021012004200d460d0020012004200d10372201450d070b20062001360200200641046a200d3602000b2001200520036a22046a200120056a200c109e081a20022004360210200420062802082201460d00200120056b2104200628020020016a2101200e210503402003450d01200120052d00003a00002006200628020841016a360208200541016a2105200141016a210120042003417f6a2203470d000b0b200b450d00200e10350b02402002280218200228021c2203460d00200220033602180b024020022802142203450d000240200228021022062002280220220441086a22052802002201460d002004280200220420016a200420066a2003109e081a0b2005200320016a3602000b0240200a450d00200710350b20002002290300370200200041086a200241086a280200360200200241c0006a24000f0b1045000b41022003104f000b103e000b103c000bf104020b7f037e230041206b22022400024002400240024020012802082203410c6c41046a2204417f4c0d00200128020021050240024020040d0041012106410021040c010b200410332206450d020b2002410036020820022006360200200220043602042003200210770240024020030d002002280208210420022802042107200228020021080c010b20052003410c6c6a21092005210603402006280200210a200641086a280200220420021077024002402002280204220b2002280208220c6b2004490d0020022802002108200b21070c010b200c20046a2208200c490d05200b41017422072008200720084b1b22074100480d0502400240200b0d00024020070d00410121080c020b2007103322080d010c080b20022802002108200b2007460d002008200b200710372208450d070b20022007360204200220083602000b2008200c6a200a2004109d081a2002200c20046a22043602082006410c6a22062009470d000b0b2004ad4220862008ad8410282204290000210d200441086a290000210e200441106a290000210f200241186a2206200441186a290000370300200241106a220c200f370300200241086a220b200e3703002002200d37030020041035200041186a2006290300370000200041106a200c290300370000200041086a200b2903003700002000200229030037000002402007450d00200810350b02402003450d002003410c6c21062005210403400240200441046a280200450d00200428020010350b2004410c6a2104200641746a22060d000b0b0240200141046a2802002204450d002004410c6c450d00200510350b200241206a24000f0b1044000b1045000b103e000b103c000bdd3d04057f027e077f0b7e230041c00e6b22042400200441b8086a200141c803109d081a200441b0056a200441b8086a10d7034101210502400240024002400240024002400240024020042d00b0054101460d00200441b0026a200441b0056a41086a418003109d081a024020032802002201450d00200341086a280200210620032802042107200441a8026a41c4c3c700411010c00141002105200441b8086a20042802ac02410020042802a8021b10cb0320042802b8082108200420042802c0083602b405200420083602b00520012006200441b0056a109403024020042802bc08450d00200810350b2007450d00200110350b200441800c6a20044180036a10d803200441b8086a200441b0026a418003109d081a024002400240024020042903d80822094202520d0020042903800c220920042d00880c2206200210ce04220841ff01714102470d094200210a200441800d6a41086a22074200370300200441800d6a41106a220b4200370300200441800d6a41186a220c4200370300200442003703800d2004280288094113470d02200441b0056a2004418c096a10dd0320042d00b0054101460d01200441dc056a280200210d200441d8056a280200210e200441d4056a280200210f200441cc056a2802002110200441c8056a28020021110240200441d0056a2802002208450d002008410c6c21022011210803400240200841046a280200450d00200828020010350b2008410c6a2108200241746a22020d000b0b02402010450d002010410c6c450d00201110350b0240200d450d00200d410c6c2102200f210803400240200841046a280200450d00200828020010350b2008410c6a2108200241746a22020d000b0b200e450d02200e410c6c450d02200f10350c020b200441800d6a41186a200441b8086a41186a290300370300200441800d6a41106a200441b8086a41106a290300370300200441800d6a41086a200441b8086a41086a290300370300200420042903b8083703800d20044180096a2903002112200441f8086a290300210a200441f0086a280200210820042903e008211342002114200441900e6a41186a4200370300200441900e6a41106a220b4200370300200441900e6a41086a22064200370300200442003703900e41d1c4c700ad4280808080e000841001220729000021152006200741086a290000370300200420153703900e2007103541e7c4c700ad4280808080e00084100122072900002115200441f80d6a41086a220c200741086a290000370300200420153703f80d20071035200b20042903f80d2215370300200441b0056a41086a2006290300370300200441b0056a41106a2015370300200441b0056a41186a200c290300370300200420042903900e3703b005200441a0026a200441b0056a412010c001024020094201520d0020134200510d060b200441900e6a200441800d6a108e02200441b0056a20042802900e220720042802980e108f020240024020042903b0054201510d0041002106420021094200211542002113420021164200211742002118420021194100210b0c010b200441c0056a2903002119200441d0056a2903002117200441c8056a2903002116200441e0056a2903002113200441d8056a2903002115200441f0056a2903002109200441e8056a2903002114200441f8056a280200210620042903b805211820042802fc05210b0b024020042802940e450d00200710350b024020062008470d00200441b0056a200441800d6a108e0220043502b805211a20042802b0052107410410332206450d072006200841016a36000020064104410810372208450d072008200b3a000420084108411510372208450d07200820183700052008410d6a201937000020084115412a10372208450d07200820163700152008411d6a20173700002008412a41d40010372208450d0720082014370035200820153700252008413d6a20093700002008412d6a2013370000201a4220862007ad842008ad4280808080d00884100220081035024020042802b405450d00200710350b418012210820042d00880c22064102460d0920042903800c22092006200210ce04220841ff01714102470d0920044190026a2002200920042d00890c200a201210db0302400240200429039002221420044190026a41086a29030022158450450d00420021160c010b200441003a00a80d200420153703e80c200420143703e00c41012102200441014111200a201284501b3a008c0e2004200441800d6a3602f80d2004200441800d6a3602c00c2004200441c00c6a3602c00520042004418c0e6a3602bc052004200441f80d6a3602b8052004200441a80d6a3602b4052004200441e00c6a3602b005200441900e6a200441800d6a200441b0056a10dc030240024020042802900e4101470d004200211520042903980e21140c010b200441b80e6a2903002115200441b00e6a2903002114024020042903980e4201510d00410021020c010b200441900e6a41106a290300211320042802c00c2108200441e8056a200441900e6a41186a290300370300200441e0056a201337030041002102200441b0056a41086a41003a0000200441b9056a2008290000370000200441c1056a200841086a290000370000200441c9056a200841106a290000370000200441d1056a200841186a290000370000200441033a00b00541b0b4cc004100200441b0056a10d4010b42012116418002210820020d0a0b200441b80d6a41186a200441800d6a41186a2903002213370300200441b80d6a41106a200441800d6a41106a2903002217370300200441b80d6a41086a200441800d6a41086a2903002218370300200441d80d6a41086a2018370300200441d80d6a41106a2017370300200441d80d6a41186a2013370300200420042903800d22133703b80d200420133703d80d4101210d0c030b418006418004200620084b1b21080c080b20042d00b10522084102470d060b200441b80d6a41186a200c290300370300200441b80d6a41106a200b290300370300200441b80d6a41086a2007290300370300200420042903800d3703b80d4100210d42002112420021160b200441c00c6a41186a2210200441d80d6a41186a2208290300370300200441c00c6a41106a220f200441d80d6a41106a2202290300370300200441c00c6a41086a2211200441d80d6a41086a2207290300370300200420042903d80d3703c00c200441e00c6a41186a200441b80d6a41186a220b290300370300200441e00c6a41106a200441b80d6a41106a220c290300370300200441e00c6a41086a200441b80d6a41086a220e290300370300200420042903b80d3703e00c200441b0056a20044188096a41b002109d081a200820102903003703002002200f29030037030020072011290300370300200420042903c00c3703d80d410221100240200d450d00200b2008290300370300200c2002290300370300200e2007290300370300200420042903d80d3703b80d410121100b2004419a0e6a200e290300370100200441a20e6a200c290300370100200441aa0e6a200b290300370100200420103a00910e200420042903b80d3701920e200441003a00900e200441800d6a200441b0056a200441900e6a10ac03200441800d6a41106a290300211720042903880d2113200420042900990d3703b0052004200441a00d6a2800003600b7050240024020042903800d4201510d00410421080c010b200441800d6a41186a2d00002102200420042800b7053600970e200420042903b0053703900e4104210820134202510d00200420042800970e3600af0d200420042903900e3703a80d200221080b200441b80d6a41186a200441e00c6a41186a290300370300200441b80d6a41106a200441e00c6a41106a290300370300200441b80d6a41086a200441e00c6a41086a290300370300200420042903e00c3703b80d0240024002400240200841ff01714104460d00200641ff01714102460d010b20134201520d024200200920177d221820182009561b2219500d02200441b0056a41186a220c4200370300200441b0056a41106a22074200370300200441b0056a41086a22064200370300200442003703b00541d1c4c700ad4280808080e00084221a1001220b2900002118200441d80d6a41086a2202200b41086a290000370300200420183703d80d200b103520062002290300370300200420042903d80d3703b0054184eec700ad4280808080b00284221b1001220b29000021182002200b41086a290000370300200420183703d80d200b1035200720042903d80d2218370300200441900e6a41086a220e2006290300370300200441900e6a41106a22102018370300200441900e6a41186a220d2002290300370300200420042903b0053703900e20044180026a200441900e6a10e1022004290388022118200429038002211c200c42003703002007420037030020064200370300200442003703b005201a1001220b290000211a2002200b41086a2900003703002004201a3703d80d200b103520062002290300370300200420042903d80d3703b005201b1001220b290000211a2002200b41086a2900003703002004201a3703d80d200b1035200720042903d80d221a370300200e20062903003703002010201a370300200d2002290300370300200420042903b0053703900e201ca70d01200441900e6aad428080808080048410070c020b41801021082016500d08200441900e6a41186a220c4200370300200441900e6a41106a22074200370300200441900e6a41086a22064200370300200442003703900e41b6fdc600ad428080808080018422091001220b2900002112200441f80d6a41086a2202200b41086a290000370300200420123703f80d200b103520062002290300370300200420042903f80d3703900e41e489c200ad4280808080d0018422121001220b290000210a2002200b41086a2900003703002004200a3703f80d200b1035200720042903f80d220a370300200441b0056a41086a220e2006290300370300200441b0056a41106a2210200a370300200441b0056a41186a220d2002290300370300200420042903900e3703b005200441086a200441b0056a412010d701200441086a41106a290300210a200429031021132004280208210b200c42003703002007420037030020064200370300200442003703900e20091001220c29000021092002200c41086a290000370300200420093703f80d200c103520062002290300370300200420042903f80d3703900e20121001220c29000021092002200c41086a290000370300200420093703f80d200c1035200720042903f80d2209370300200e200629030037030020102009370300200d2002290300370300200420042903900e3703b00520044200200a4200200b1b220920157d20134200200b1b2215201454ad7d2212201520147d2214201556201220095620122009511b22021b3703980e20044200201420021b3703900e200441b0056aad4280808080800484200441900e6aad428080808080028410020c080b20044200201820197d221920192018561b3703b005200441900e6aad4280808080800484200441b0056aad428080808080018410020b200441d80d6a41186a200441b80d6a41186a290300370300200441d80d6a41106a200441b80d6a41106a290300370300200441d80d6a41086a200441b80d6a41086a290300370300200420042903b80d3703d80d02402016500d0042002116200441f0016a4200200920177d221720172009561b420020134201511b10cf0420042903f00121092004200441f0016a41086a29030022133703800e200420093703f80d02400240024002400240200920138450450d00420021090c010b2004200441d80d6a36028c0e200441900e6a200441d80d6a200441f80d6a2004418c0e6a109a0220042802900e4101460d01200441b80e6a2903002109200441b00e6a2903002116200441900e6a41086a2903004201520d00200441900e6a41106a2903002113200441e8056a200441900e6a41186a290300370300200441e0056a2013370300200441b0056a41086a41003a0000200441b9056a20042903d80d370000200441c1056a200441d80d6a41086a290300370000200441c9056a200441d80d6a41106a290300370000200441d1056a200441d80d6a41186a290300370000200441033a00b00541b0b4cc004100200441b0056a10d4010b20142016542202201520095420152009511b0d01201520097d2002ad7d2115201420167d21140b200441f0006a201220152014200a56201520125620152012511b22021b2212420042d0004200108408200441b0016a200a201420021b2209420042d000420010840820044180016a4200420020094200108408200441d0016a20042903b001200441b0016a41086a290300220a20042903702004290380017c7c221342e4004200109808200441a0016a201520127d2014200954ad7d2215420042d0004200108408200441c0016a201420097d2214420042d000420010840820044190016a4200420020144200108408200441e0016a20042903c001200441c0016a41086a290300221620042903a0012004290390017c7c221742e4004200109808427f201242dc9e8aae8f85d7c702200441d0016a41086a2903002004290378200429038801844200522013200a547222021b220a201242c2eba3e1f5d1f0fa2820042903d00120021b2213200954200a201254200a2012511b22021b22187d20092013200920021b221254ad7d220a201542dc9e8aae8f85d7c702200441e0016a41086a29030020042903a8012004290398018442005220172016547222021b2213201542c2eba3e1f5d1f0fa2820042903e00120021b2216201454201320155420132015511b22021b22137d20142016201420021b221554ad7d7c200920127d2209201420157d7c22162009542202ad7c220920022009200a542009200a511b22021b2114427f201620021b210a02400240201520127c2209201320187c2009201554ad7c2215844200520d00200441900e6a41186a220c4200370300200441900e6a41106a22074200370300200441900e6a41086a22064200370300200442003703900e41b6fdc600ad428080808080018422091001220b2900002115200441f80d6a41086a2202200b41086a290000370300200420153703f80d200b103520062002290300370300200420042903f80d3703900e41e489c200ad4280808080d0018422151001220b29000021122002200b41086a290000370300200420123703f80d200b1035200720042903f80d2212370300200441b0056a41086a220e2006290300370300200441b0056a41106a22102012370300200441b0056a41186a220d2002290300370300200420042903900e3703b005200441d8006a200441b0056a412010d701200441d8006a41106a2903002112200429036021132004280258210b200c42003703002007420037030020064200370300200442003703900e20091001220c29000021092002200c41086a290000370300200420093703f80d200c103520062002290300370300200420042903f80d3703900e20151001220c29000021092002200c41086a290000370300200420093703f80d200c1035200720042903f80d2209370300200e200629030037030020102009370300200d2002290300370300200420042903900e3703b005200420124200200b1b3703980e200420134200200b1b3703900e200441b0056aad4280808080800484200441900e6aad428080808080028410020c010b200442f0f2bda1a7ee9cb9f9003703900e200441b0056a200441900e6a10e001200441b0056a2009201510df01200441c8056a2015370300200441c0056a2009370300200441b0056a41086a41063a00002004410c3a00b00541b0b4cc004100200441b0056a10d4010b200a2014844200520d01200441900e6a41186a220c4200370300200441900e6a41106a22074200370300200441900e6a41086a22064200370300200442003703900e41b6fdc600ad428080808080018422091001220b2900002114200441f80d6a41086a2202200b41086a290000370300200420143703f80d200b103520062002290300370300200420042903f80d3703900e41e489c200ad4280808080d0018422141001220b29000021152002200b41086a290000370300200420153703f80d200b1035200720042903f80d2215370300200441b0056a41086a220e2006290300370300200441b0056a41106a22102015370300200441b0056a41186a220d2002290300370300200420042903900e3703b005200441c0006a200441b0056a412010d701200441c0006a41106a2903002115200429034821122004280240210b200c42003703002007420037030020064200370300200442003703900e20091001220c29000021092002200c41086a290000370300200420093703f80d200c103520062002290300370300200420042903f80d3703900e20141001220c29000021092002200c41086a290000370300200420093703f80d200c1035200720042903f80d2209370300200e200629030037030020102009370300200d2002290300370300200420042903900e3703b005200420154200200b1b3703980e200420124200200b1b3703900e200441b0056aad4280808080800484200441900e6aad428080808080028410020c020b200441900e6a41186a220b4200370300200441900e6a41106a22064200370300200441900e6a41086a22024200370300200442003703900e41b6fdc600ad4280808080800184221210012207290000210a200441f80d6a41086a2208200741086a2900003703002004200a3703f80d2007103520022008290300370300200420042903f80d3703900e41e489c200ad4280808080d00184220a1001220729000021132008200741086a290000370300200420133703f80d20071035200620042903f80d2213370300200441b0056a41086a220c2002290300370300200441b0056a41106a220e2013370300200441b0056a41186a22102008290300370300200420042903900e3703b005200441206a200441b0056a412010d701200441206a41106a29030021132004290328211720042802202107200b42003703002006420037030020024200370300200442003703900e20121001220b29000021122008200b41086a290000370300200420123703f80d200b103520022008290300370300200420042903f80d3703900e200a1001220b29000021122008200b41086a290000370300200420123703f80d200b1035200620042903f80d2212370300200c2002290300370300200e201237030020102008290300370300200420042903900e3703b0052004427f2013420020071b2212200920157d2016201454ad7d7c2017420020071b2209201620147d7c22142009542208ad7c22092008200920125420092012511b22081b3703980e2004427f201420081b3703900e200441b0056aad4280808080800484200441900e6aad4280808080800284100241800221080c080b200441b0056a10d004200441b0056a200a201410df010b200420042800af0d3600b70c200420042903a80d3703b00c200420042903b00c3703a00c200420042800b70c3600a70c200420083a00900c200441900c6a41086a20042800a70c360000200420042903a00c3700910c200441800d6a41086a200441800c6a41086a290300370300200420042903800c3703800d41072102410021060240200841ff01714104460d00200441900c6a10d104200441bb056a200441980c6a280200360000200420042903900c3700b30541012106410f21020b200441b0056a20026a220820042903800d370000200841086a200441800d6a41086a290300370000200441b8086a41086a20063a0000200441c1086a20042900b005370000200441c9086a200441b0056a41086a2208290000370000200441d1086a200441b0056a41106a2202290000370000200441b8086a41206a200441c7056a290000370000200441003a00b80841b0b4cc004100200441b8086a10d401200441386a41c4c3c700411010c0012004200428023c41016a410120042802381b22063602b80841c4c3c700ad4280808080800284200441b8086aad4280808080c000841002200420063602dc0d200441003602d80d200441b0056a41186a42003703002002420037030020084200370300200442003703b00541d1c4c700ad4280808080e000841001220629000021092008200641086a290000370300200420093703b005200610354188f2c700ad4280808080e00184100122062900002109200441f80d6a41086a2207200641086a290000370300200420093703f80d20061035200220042903f80d2209370300200441900e6a41086a2008290300370300200441900e6a41106a2009370300200441900e6a41186a2007290300370300200420042903b0053703900e200441203602bc082004200441900e6a3602b808200441d80d6a200441b8086a10cd042000410c6a200441900c6a41086a280200360200200041046a20042903900c370200200041003a00002001450d0820050d010c080b200020042f00b1053b0001200041013a0000200041036a20042d00b3053a000020032802002101410021000c060b200341046a280200450d06200110350c060b41809ccc004119419c9ccc00103f000b103c000b20042f01b20541087420087221080b20044188096a10ba020b200420042903b00c3703a00c200420042800b70c3600a70c200041036a20084110763a0000200020083b0001200041013a000020054521000b20000d002001450d00200341046a280200450d00200110350b200441c00e6a24000bcc0405067f017e017f017e047f230041e0006b22002400200041c4c3c700411010c001200028020421010240200028020022024101470d0041c4c3c700ad428080808080028410070b200041306a41186a22034200370300200041306a41106a22044200370300200041306a41086a220542003703002000420037033041d1c4c700ad4280808080e000842206100122072900002108200041d0006a41086a2209200741086a2900003703002000200837035020071035200520092903003703002000200029035037033041ecedc700ad4280808080e001841001220729000021082009200741086a2900003703002000200837035020071035200420002903502208370300200041106a41086a220a2005290300370300200041106a41106a220b2008370300200041106a41186a220c20092903003703002000200029033037031020002001410020021b360230200041106aad4280808080800484200041306aad4280808080c000841002200041013602082003420037030020044200370300200542003703002000420037033020061001220729000021062009200741086a290000370300200020063703502007103520052009290300370300200020002903503703304188f2c700ad4280808080e001841001220729000021062009200741086a2900003703002000200637035020071035200420002903502206370300200a2005290300370300200b2006370300200c200929030037030020002000290330370310200041203602342000200041106a360230200041086a200041306a10cd04200041e0006a24000b956808047f017e017f027e077f017e057f067e230041c0036b22012400200141a8016a41186a4200370300200141a8016a41106a22024200370300200141a8016a41086a22034200370300200142003703a80141a8e7cb00ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004103520032006290300370300200120012903c0023703a80141b697ca00ad4280808080d001841001220429000021052006200441086a290000370300200120053703c00220041035200220012903c002220537030020014190036a41086a200329030037030020014190036a41106a200537030020014190036a41186a2006290300370300200120012903a80137039003200141203602ac02200120014190036a3602a802200141c0026a20014190036aad220742808080808004842208100510c2010240024020012802c00222030d004102210620014102360284030c010b20012802c40221092001200628020022063602b402200120033602b0020240024020064104490d002001200341046a3602b00220012006417c6a22043602b40220044104490d002003280000210a2001200641786a3602b4022001200341086a3602b0022003280004210b200141a8016a200141b0026a10e80320012802a801220c450d0020012902ac012105410021060240024020012802b402220d0d000c010b2001200d417f6a220e3602b402200120012802b002220f41016a3602b0020240200f2d00004101460d000c010b200e4104490d002001200d417b6a3602b4022001200f41056a3602b002200f2800012104410121060b2001200436028803200120053702fc022001200c3602f8022001200b3602f4022001200a3602f0020c010b200141003602d802200142013703d002200141093602b4032001200141a8026a3602b0032001200141d0026a3602bc02200141bc016a4101360200200142013702ac01200141c888c2003602a8012001200141b0036a3602b801200141bc026a41e88ac500200141a8016a10431a20013502d80242208620013502d002841006024020012802d402450d0020012802d00210350b410221060b20012006360284032009450d00200310350b200141a8016a41106a2203200141f0026a41106a2209280200360200200141a8016a41086a220a200141f0026a41086a220b290300370300200120012903f0023703a8010240024002400240024002400240024020064102460d00200141d0026a41106a20032802002203360200200141d0026a41086a200a2903002210370300200120012903a80122053703d00220092003360200200b201037030020014188036a2004360200200120053703f002200120063602840302402005a722032000470d000240024020064101460d0020012802f4022106200141a8016a200141f0026a41086a10c605200141a0036a200636020020014190036a410c6a200141a8016a41086a22062802003602002001410036029003200120012903a80137029403200141a8016a20014190036a108805200141cb026a2006280200360000200120012903a8013700c302200141a8016a410c6a200141c7026a290000370000200141c6a4b9da043600a901200141023a00a801200120012900c0023700ad01200141a8016a10820420014190036a41086a2802002206450d01200641286c450d0120012802940310350c010b20012802f4022106200141a8016a200141f0026a41086a10c605200141a4036a200636020020014190036a41086a20012903a801370300200141a0036a200141a8016a41086a220628020036020020012004360294032001410136029003200141a8016a20014190036a108805200141cb026a2006280200360000200120012903a8013700c302200141a8016a410c6a200141c7026a290000370000200141c6a4b9da043600a901200141023a00a801200120012900c0023700ad01200141a8016a10820420014190036a410c6a2802002206450d00200641286c450d0020012802980310350b20012802f00221030b024020012802f40220036a2000470d002001200141f8026a220d3602ac01200141003602a80120014180036a28020041286c4105722206417f4c0d02200610332203450d03200341013a000020012006360294032001200336029003200141013602980320012802f8022106200128028003220320014190036a10770240024020030d002001280298032103200128029003210b0c010b2006200341286c6a210c20012802940321092001280298032103034002400240200920036b4120490d00200341206a2104200128029003210b2009210a0c010b200341206a22042003490d072009410174220a2004200a20044b1b220a4100480d070240024020090d000240200a0d004101210b0c020b200a1033220b0d010c0d0b200128029003210b2009200a460d00200b2009200a1037220b450d0c0b2001200a360294032001200b360290030b200b20036a22032006290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a2900003700002001200436029803200641206a290300210502400240200a20046b4108490d00200441086a2103200a21090c010b200441086a22032004490d07200a41017422092003200920034b1b22094100480d0702400240200a0d00024020090d004101210b0c020b20091033220b450d0d0c010b200a2009460d00200b200a20091037220b450d0c0b20012009360294032001200b360290030b200b20046a20053700002001200336029803200c200641286a2206470d000b0b2001280294032106419793ca00ad4280808080c002842003ad422086200bad84100202402006450d00200b10350b024020012802a801450d00200141b0016a2802002206450d00200641286c450d0020012802ac0110350b200141a8016a41086a2206200d290000370300200141a8016a41106a2204200d41086a280000360200200141003602ac012001410b3a00a80141b0b4cc004100200141a8016a10d401200141a8016a41186a220a42003703002004420037030020064200370300200142003703a80141a8e7cb00ad4280808080f00184100122092900002105200141c0026a41086a2203200941086a290000370300200120053703c0022009103520062003290300370300200120012903c0023703a80141b697ca00ad4280808080d001841001220929000021052003200941086a290000370300200120053703c00220091035200220012903c002370000200241086a200329030037000020014190036a41086a200629030037030020014190036a41106a200429030037030020014190036a41186a200a290300370300200120012903a80137039003200810070c010b200141fc026a2802002206450d00200641286c450d0020012802f80210350b200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141a8e7cb00ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004103520032006290300370300200120012903c0023703a80141c397ca00ad4280808080d000841001220429000021052006200441086a290000370300200120053703c00220041035200220012903c002370000200241086a200629030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200141203602c402200120014190036a3602c002200141d0026a2008100510c20120012802d0022206450d0520012802d4022104024002400240200141d0026a41086a2802002209450d0020062d0000220a41034b0d0041002103024002400240200a0e0405000102050b2009417f6a4108490d0220062900012105410121030c040b410221030c020b2009417f6a4108490d0020062900012105410321030c020b200141003602f802200142013703f002200141093602b4032001200141c0026a3602b0032001200141f0026a3602b002200141bc016a4101360200200142013702ac01200141c888c2003602a8012001200141b0036a3602b801200141b0026a41e88ac500200141a8016a10431a20013502f80242208620013502f002841006024020012802f402450d0020012802f00210350b410421030b0b02402004450d00200610350b2003417f6a220641024b0d0520060e03040503040b1044000b1045000b103e000b2005422088a7210602402005a722032000470d0020014104360290032001200636029403200141a8016a20014190036a108805200141cb026a200141b0016a280200360000200120012903a8013700c302200141b4016a200141c7026a290000370000200141c6a4b9da043600a901200141023a00a801200120012900c0023700ad01200141a8016a1082040b200620036a2000470d01200141003602f002200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141a8e7cb00ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004103520032006290300370300200120012903c0023703a80141c397ca00ad4280808080d000841001220429000021052006200441086a290000370300200120053703c00220041035200220012903c002370000200241086a200629030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200141a8016a200141f0026a10db06200820013502b00142208620012802a8012206ad841002024020012802ac01450d00200610350b200141023602ac012001410b3a00a80141b0b4cc004100200141a8016a10d4010c010b2005422088a7210602402005a722032000470d0020014103360290032001200636029403200141a8016a20014190036a108805200141cb026a200141b0016a280200360000200120012903a8013700c302200141b4016a200141c7026a290000370000200141c6a4b9da043600a901200141023a00a801200120012900c0023700ad01200141a8016a1082040b200620036a2000470d00200141023602f002200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141a8e7cb00ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004103520032006290300370300200120012903c0023703a80141c397ca00ad4280808080d000841001220429000021052006200441086a290000370300200120053703c00220041035200220012903c002370000200241086a200629030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200141a8016a200141f0026a10db06200820013502b00142208620012802a8012206ad841002024020012802ac01450d00200610350b200141013602ac012001410b3a00a80141b0b4cc004100200141a8016a10d4010b200141a8016a41186a22044200370300200141a8016a41106a220d4200370300200141a8016a41086a22034200370300200142003703a80141bee4cb00ad4280808080f001842205100122092900002108200141f0026a41086a2206200941086a290000370300200120083703f0022009103520032006290300370300200120012903f0023703a801418cc0c700ad4280808080e000841001220929000021082006200941086a290000370300200120083703f00220091035200d20012903f002220837030020014190036a41086a220a200329030037030020014190036a41106a220b200837030020014190036a41186a220c2006290300370300200120012903a80137039003200141a0016a20014190036a412010c00120012802a401210f024020012802a00122024101470d002007428080808080048410070b20044200370300200d420037030020034200370300200142003703a80120051001220929000021052006200941086a290000370300200120053703f0022009103520032006290300370300200120012903f0023703a80141cde4cb00ad4280808080b001841001220929000021052006200941086a290000370300200120053703f00220091035200d20012903f002370000200d41086a2006290300370000200a2003290300370300200b200d290300370300200c2004290300370300200120012903a801370390030240024020014190036a10bd02220641ff01714102460d0020064101710d010b41041033220a450d01200a4100360200200141a8016a41186a22044200370300200141a8016a41106a22094200370300200141a8016a41086a22034200370300200142003703a80141bee4cb00ad4280808080f0018422051001220b2900002108200141f0026a41086a2206200b41086a290000370300200120083703f002200b103520032006290300370300200120012903f0023703a80141b9e0c600ad4280808080b001841001220b29000021082006200b41086a290000370300200120083703f002200b1035200d20012903f002370000200d41086a220b200629030037000020014190036a41086a220c200329030037030020014190036a41106a2200200929030037030020014190036a41186a220e2004290300370300200120012903a80137039003200141203602ac01200120014190036a3602a801200a4101200141a8016a109503200a103541041033220a450d01200a4100360200200442003703002009420037030020034200370300200142003703a80120051001221129000021082006201141086a290000370300200120083703f0022011103520032006290300370300200120012903f0023703a8014192c0c700ad4280808080c001841001221129000021082006201141086a290000370300200120083703f00220111035200d20012903f002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903a80137039003200141203602ac01200120014190036a3602a801200a4101200141a8016a109503200a1035200442003703002009420037030020034200370300200142003703a80120051001220a29000021082006200a41086a290000370300200120083703f002200a103520032006290300370300200120012903f0023703a801419ec0c700ad4280808080e000841001220a29000021082006200a41086a290000370300200120083703f002200a1035200d20012903f002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903a80137039003200141003602a801200742808080808004842208200141a8016aad22104280808080c000841002200442003703002009420037030020034200370300200142003703a80120051001220a29000021052006200a41086a290000370300200120053703f002200a103520032006290300370300200120012903f0023703a80141cde4cb00ad4280808080b001841001220a29000021052006200a41086a290000370300200120053703f002200a1035200d20012903f002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903a80137039003200141013a00a801200820104280808080108410020b200141a8016a41186a4200370300200141a8016a41106a22124200370300200141a8016a41086a22064200370300200142003703a80141bee4cb00ad4280808080f001841001220329000021052006200341086a290000370300200120053703a8012003103541b9e0c600ad4280808080b00184100122032900002105200141f0026a41086a2204200341086a290000370300200120053703f00220031035201220012903f002220537030020014190036a41086a200629030037030020014190036a41106a200537030020014190036a41186a2004290300370300200120012903a80137039003200141a8016a20014190036a10c5020240024020012802a801220e0d0041002113200141003602c802200142043703c0024104210e410021110c010b200120012902ac0122053702c4022001200e3602c0022005422088a721112005a721130b200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141bee4cb00ad4280808080f00184100122042900002105200141f0026a41086a2206200441086a290000370300200120053703f0022004103520032006290300370300200120012903f0023703a8014192c0c700ad4280808080c001841001220429000021052006200441086a290000370300200120053703f00220041035200d20012903f002370000200d41086a200629030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200141a8016a20014190036a10c5020240024020012802a801220a0d0041002114200141003602d802200142043703d0024104210a4100210c0c010b200120012902ac0122053702d4022001200a3602d0022005422088a7210c2005a721140b0240024002400240024020020d002011450d012011410274200e6a417c6a280200210f0b201141002011419c7f6a22062006201141016a4b1b2215490d01200141003602c8022015450d03200e20154102746a2100200e210203402002280200210b02400240024002400240200c41014b0d0041002106200c0e020201020b41002106200c2103034020062003410176220420066a2209200b200a20094102746a280200491b2106200320046b220341014b0d000b0b200b200a200641027422036a2802002204460d022006200b20044b6a21060c010b410021060b200120063602a80141dcc0c700412e200141a8016a418cc1c700419cc1c7001046000b200c20064d0d03200a20036a2203200341046a2006417f73200c6a410274109e081a2001200c417f6a220c3602d802200241046a22022000470d000c040b0b41a4c0c700412641ccc0c7001064000b20152011104f000b2006200c104e000b410021064100210b0240201120156b2203450d0002402015450d00200e200e20154102746a2003410274109e081a0b200120033602c8022003210b0b024002400240200c41014b0d00200c0e020201020b41002106200c2103034020062003410176220420066a2209200f200a20094102746a280200491b2106200320046b220341014b0d000b0b0240200f200a20064102746a2802002203460d002006200f20034b6a21060b200c20064f0d002006200c104d000b0240200c2014470d00200141d0026a2014410110860120012802d002210a0b200a20064102746a220341046a2003200c20066b410274109e081a2003200f3602002001200c41016a22033602d8020240200b2013470d00200141c0026a2013410110860120012802c002210e20012802c802210b0b200e200b4102746a200f3602002001200b41016a220b3602c80202400240024002400240024002402003450d00200341017621062003410171450d01200320064d0d03200a20064102746a28020021000c020b41acc1c70041c30041c086cc00103f000b200320064d0d0220032006417f6a22044d0d03200a20044102746a280200200a20064102746a2802006a41017621000b20012802c4022102200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22044200370300200142003703a80141bee4cb00ad4280808080f0018422051001220c2900002108200141f0026a41086a2206200c41086a290000370300200120083703f002200c103520042006290300370300200120012903f0023703a80141b9e0c600ad4280808080b001841001220c29000021082006200c41086a290000370300200120083703f002200c1035200d20012903f002370000200d41086a220f200629030037000020014190036a41086a2211200429030037030020014190036a41106a2215200a29030037030020014190036a41186a22132009290300370300200120012903a80137039003200141203602ac01200120014190036a3602a801200e200b200141a8016a1095030240200241ffffffff0371450d00200e10350b20012802d402210e20012802d002210220094200370300200a420037030020044200370300200142003703a80120051001220c29000021052006200c41086a290000370300200120053703f002200c103520042006290300370300200120012903f0023703a8014192c0c700ad4280808080c001841001220c29000021052006200c41086a290000370300200120053703f002200c1035200d20012903f002370000200f2006290300370000201120042903003703002015200a29030037030020132009290300370300200120012903a80137039003200141203602ac01200120014190036a3602a80120022003200141a8016a1095030240200e41ffffffff0371450d00200210350b200141a8016a41186a22094200370300200141a8016a41106a22044200370300200141a8016a41086a22034200370300200142003703a80141bee4cb00ad4280808080f001841001220a2900002105200141f0026a41086a2206200a41086a290000370300200120053703f002200a103520032006290300370300200120012903f0023703a801419ec0c700ad4280808080e000841001220a29000021052006200a41086a290000370300200120053703f002200a1035200d20012903f002370000200d41086a200629030037000020014190036a41086a220a200329030037030020014190036a41106a220c200429030037030020014190036a41186a22022009290300370300200120012903a80137039003200120003602a80120074280808080800484200141a8016aad22164280808080c0008410020240200b41e500470d00200942003703002004420037030020034200370300200142003703a80141d1c4c700ad4280808080e000841001220b29000021052003200b41086a290000370300200120053703a801200b103541e7c4c700ad4280808080e000841001220b29000021052006200b41086a290000370300200120053703f002200b1035201220012903f002370000201241086a2006290300370000200a2003290300370300200c200429030037030020022009290300370300200120012903a8013703900320014198016a20014190036a412010c0010b200942003703002004420037030020034200370300200142003703a80141f7edcb00ad4280808080f0008422081001220929000021052006200941086a290000370300200120053703f0022009103520032006290300370300200120012903f0023703a80141eeedcb00ad428080808090018422101001220929000021052006200941086a290000370300200120053703f00220091035200420012903f0022205370300200a2003290300370300200c200537030020022006290300370300200120012903a80137039003200141a8016a20014190036a10ac01024020012903a801427f7c4202540d0020042903002117200141a8016a41186a220a4200370300200141a8016a41106a22094200370300200141a8016a41086a22064200370300200142003703a80141d1efcb00ad42808080809001841001220329000021052006200341086a290000370300200120053703a8012003103541ebc3c400ad428080808030841001220b2900002105200141f0026a41086a2203200b41086a290000370300200120053703f002200b1035200920012903f002220537030020014190036a41086a220c200629030037030020014190036a41106a2202200537030020014190036a41186a22002003290300370300200120012903a8013703900320014188016a20014190036a10e102200141f8006a20012903900142002001280288011b221842e807802219420042e8074200108408200a42003703002009420037030020064200370300200142003703a80120081001220b29000021052003200b41086a290000370300200120053703f002200b103520062003290300370300200120012903f0023703a80120101001220b29000021052003200b41086a290000370300200120053703f002200b1035200420012903f002370000200441086a2003290300370000200c2006290300370300200220092903003703002000200a290300370300200120012903a8013703900320012903782105200141f8006a41086a2903002108410410332206450d05200620173e000020064104410810372206450d05200641013a000420064108411010372206450d0520062005201820194298787e7c42ff07837c2210427f20082010200554ad7c501b370005200742808080808004842006ad4280808080d001841002200610350b200141a8016a41186a220b4200370300200141a8016a41106a22094200370300200141a8016a41086a22034200370300200142003703a80141e3efcb00ad4280808080a00284100122042900002105200141f0026a41086a2206200441086a290000370300200120053703f0022004103520032006290300370300200120012903f0023703a80141f5efcb00ad42808080809002841001220429000021052006200441086a290000370300200120053703f00220041035200920012903f002220537030020014190036a41086a200329030037030020014190036a41106a200537030020014190036a41186a2006290300370300200120012903a80137039003200141e0006a20014190036a10bc02200141e0006a41106a29030021172001290368211920012802602104200141f0026a41186a4200370300200141f0026a41106a220c420037030020064200370300200142003703f00241d1c4c700ad4280808080e000841001220a29000021052006200a41086a290000370300200120053703f002200a10354184eec700ad4280808080b002841001220a2900002105200141c0026a41086a2202200a41086a290000370300200120053703c002200a1035200c20012903c00222053703002003200629030037030020092005370300200b2002290300370300200120012903f0023703a801200141d0006a200141a8016a10e102200141106a2001290358420020012802501b2205428090cad2c60e2005428090cad2c60e5622061b428090cad2c60e200520061b7d420042a0c21e4200108408200141c0006a20012903102208200141106a41086a29030022102008201010dc06200141c0006a41086a290300211a2001290340211b200141306a428080aace938c0942002008201010dc06200141306a41086a290300210820012903302118200141206a428090bcfd024200201b201a10dc062017420020041b21102019420020041b2119200141206a41086a29030021172001290320211a02400240200542ff8fcad2c60e560d0042ffffffffffffffffff00428080808080808080807f201042ffffffffffffffffff00428080808080808080807f200820177d2018201a54ad7d22054200531b200541012008427f552008501b220641012017427f552017501b47200641012005427f552005501b477122061b22087d20192005423f872018201a7d20061b221754ad7d22054200531b200541012010427f552010501b220641012008427f552008501b47200641012005427f552005501b477122061b2208427f2005423f87201920177d20061b2205428080f0c4c5a9d28f72562008427f552008427f511b22061b21082005428080f0c4c5a9d28f7220061b21050c010b42ffffffffffffffffff00428080808080808080807f201042ffffffffffffffffff00428080808080808080807f200820177c2018201a7c221a201854ad7c22054200531b200541012008427f552008501b220641012017427f552017501b46200641012005427f552005501b477122061b22087c20192005423f87201a20061b7c2217201954ad7c22054200531b200541012010427f552010501b220641012008427f552008501b46200641012005427f552005501b477122061b21082005423f87201720061b21050b200141a8016a41186a220a4200370300200141a8016a41106a22044200370300200141a8016a41086a22034200370300200142003703a80141e3efcb00ad4280808080a002841001220b2900002110200141f0026a41086a2206200b41086a290000370300200120103703f002200b103520032006290300370300200120012903f0023703a80141f5efcb00ad42808080809002841001220b29000021102006200b41086a290000370300200120103703f002200b1035200920012903f002370000200941086a200629030037000020014190036a41086a2209200329030037030020014190036a41106a220b200429030037030020014190036a41186a220c200a290300370300200120012903a80137039003200120083703b001200120053703a801200742808080808004842205201642808080808002841002200a42003703002004420037030020034200370300200142003703a8014193d1cb00ad4280808080a0018422081001220229000021102006200241086a290000370300200120103703f0022002103520032006290300370300200120012903f0023703a80141d8c7ca00ad4280808080e000841001220229000021102006200241086a290000370300200120103703f00220021035200420012903f002221037030020092003290300370300200b2010370300200c2006290300370300200120012903a8013703900320051007200a42003703002004420037030020034200370300200142003703a80120081001220229000021082006200241086a290000370300200120083703f0022002103520032006290300370300200120012903f0023703a801419dd1cb00ad4280808080c001841001220229000021082006200241086a290000370300200120083703f00220021035200420012903f002220837030020092003290300370300200b2008370300200c2006290300370300200120012903a8013703900320051007200a42003703002004420037030020034200370300200142003703a80141d1efcb00ad42808080809001841001220a29000021082003200a41086a290000370300200120083703a801200a103541daefcb00ad42808080809001841001220a29000021082006200a41086a290000370300200120083703f002200a1035200420012903f002220837030020092003290300370300200b2008370300200c2006290300370300200120012903a8013703900320014190036a10bd02220641ff01714102460d03200510072006410171450d03200141a8016a41186a4200370300200141a8016a41106a22064200370300200141a8016a41086a22034200370300200142003703a80141a9d1cb00ad4280808080c000841001220429000021052003200441086a290000370300200120053703a8012004103541cde4cb00ad4280808080b00184100122042900002105200141c0026a41086a2209200441086a290000370300200120053703c00220041035200620012903c002220537030020014190036a41086a200329030037030020014190036a41106a200537030020014190036a41186a2009290300370300200120012903a80137039003200141a8016a20014190036a10b702024020012d00a80122034102460d00200742808080808004841007200141d0026a41086a200141b1016a290000370300200141d0026a41106a200141b9016a290000370300200141d0026a41186a200141c1016a290000370300200120012900a9013703d0020240200341037122034103460d0020030e03010001010b200141f0026a41186a200141d0026a41186a290300370300200141f0026a41106a200141d0026a41106a290300370300200141f0026a41086a200141d0026a41086a290300370300200120012903d0023703f002200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141a9d1cb00ad4280808080c000841001220429000021052003200441086a290000370300200120053703a8012004103541f0d1cb00ad4280808080c00184100122042900002105200141c0026a41086a220b200441086a290000370300200120053703c00220041035200620012903c002370000200641086a200b29030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200141086a20014190036a412010c00141002109200141a8016a200128020c410020012802081b220a10fe0320014190036a20012802a801220b20012802b00110c3020240024020012802900322040d00200141003602b803200142013703b00341012104410021030c010b200120012902940322053702b403200120043602b0032005422088a721032005a721090b024020012802ac01450d00200b10350b024002402003418002490d00412010332203450d07200320012903f002370000200341186a200141f0026a41186a290300370000200341106a200141f0026a41106a290300370000200341086a200141f0026a41086a290300370000200141a8016a200a41016a220910fe0320012802a8012104200120012802b0013602940320012004360290032003410120014190036a109802024020012802ac01450d00200410350b20031035200141a8016a41186a220a4200370300200141a8016a41106a220b4200370300200141a8016a41086a22034200370300200142003703a80141a9d1cb00ad4280808080c000841001220429000021052003200441086a290000370300200120053703a8012004103541f0d1cb00ad4280808080c00184100122042900002105200141c0026a41086a220c200441086a290000370300200120053703c00220041035200620012903c002370000200641086a200c29030037000020014190036a41086a200329030037030020014190036a41106a200b29030037030020014190036a41186a200a290300370300200120012903a80137039003200120093602a8012007428080808080048420164280808080c000841002200141b0036a21030c010b200141a8016a41186a220b200141f0026a41186a290300370300200141a8016a41106a220c200141f0026a41106a290300370300200141a8016a41086a2202200141f0026a41086a290300370300200120012903f0023703a801024020032009470d00200141b0036a20094101108a0120012802b003210420012802b80321030b200420034105746a220920012903a801370000200941186a200b290300370000200941106a200c290300370000200941086a20022903003700002001200341016a22093602b803200141a8016a200a10fe0320012802a8012103200120012802b0013602940320012003360290032004200920014190036a109802024020012802ac01450d00200310350b200141b0036a21030b200341046a28020041ffffff3f71450d00200328020010350b200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141a9d1cb00ad4280808080c000841001220429000021052003200441086a290000370300200120053703a801200410354199c2c300ad4280808080800184100122042900002105200141c0026a41086a220b200441086a290000370300200120053703c00220041035200620012903c002370000200641086a200b29030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200742808080808004841007200141c0036a24000f0b2006200341f0c1c7001042000b200620034180c2c7001042000b200420034190c2c7001042000b41c0c3c400412b41c086cc00103f000b103c000ba41d08047f017e017f017e047f017e047f017e230041e0016b2201240020014190016a41186a2202420037030020014190016a41106a2203420037030020014190016a41086a22044200370300200142003703900141d1c4c700ad4280808080e000842205100122062900002107200141b8016a41086a2208200641086a290000370300200120073703b8012006103520042008290300370300200120012903b801370390014188f2c700ad4280808080e001841001220629000021072008200641086a290000370300200120073703b80120061035200320012903b8012207370300200141f0006a41086a22062004290300370300200141f0006a41106a22092007370300200141f0006a41186a220a20082903003703002001200129039001370370200141f0006aad428080808080048422071007200242003703002003420037030020044200370300200142003703900120051001220b290000210c2008200b41086a2900003703002001200c3703b801200b103520042008290300370300200120012903b8013703900141ecedc700ad4280808080e001841001220b290000210c2008200b41086a2900003703002001200c3703b801200b1035200320012903b801220c370300200620042903003703002009200c370300200a2008290300370300200120012903900137037020071007200242003703002003420037030020044200370300200142003703900120051001220b290000210c2008200b41086a2900003703002001200c3703b801200b103520042008290300370300200120012903b801370390014184eec700ad4280808080b002841001220b290000210c2008200b41086a2900003703002001200c3703b801200b1035200320012903b801220c370300200620042903003703002009200c370300200a2008290300370300200120012903900137037020071007200242003703002003420037030020044200370300200142003703900120051001220b290000210c2008200b41086a2900003703002001200c3703b801200b103520042008290300370300200120012903b8013703900141b8eec700ad42808080808002841001220b290000210c2008200b41086a2900003703002001200c3703b801200b1035200320012903b801220c370300200620042903003703002009200c370300200a2008290300370300200120012903900137037020071007200242003703002003420037030020044200370300200142003703900120051001220b290000210c2008200b41086a2900003703002001200c3703b801200b103520042008290300370300200120012903b8013703900141e7c4c700ad4280808080e000841001220b290000210c2008200b41086a2900003703002001200c3703b801200b1035200320012903b801220c370300200620042903003703002009200c370300200a20082903003703002001200129039001370370200141086a200141f0006a412010c001200128020c210d02402001280208220e4101470d00200710070b200242003703002003420037030020044200370300200142003703900120051001220b29000021052008200b41086a290000370300200120053703b801200b103520042008290300370300200120012903b8013703900141edc4c700ad4280808080a001841001220b29000021052008200b41086a290000370300200120053703b801200b1035200320012903b801370000200341086a20082903003700002006200429030037030020092003290300370300200a20022903003703002001200129039001370370200141b8016a200141f0006a412010d501024002400240024020012d00b80122080d00200141a8016a200141d1016a290000370300200141a0016a200141c9016a29000037030020014198016a200141c1016a290000370300200120012900b901370390010c010b2007100720014190016a41186a2204200141d1016a29000037030020014190016a41106a2202200141c9016a29000037030020014190016a41086a2206200141c1016a290000370300200120012900b9013703900120084101460d010b200141286a4200370300200141206a4200370300200141186a4200370300200142003703100c010b200141106a41186a2004290300370300200141106a41106a2002290300370300200141106a41086a200629030037030020012001290390013703100b20014190016a41186a2206420037030020014190016a41106a2209420037030020014190016a41086a22044200370300200142003703900141d1c4c700ad4280808080e00084100122022900002105200141b8016a41086a2208200241086a290000370300200120053703b8012002103520042008290300370300200120012903b801370390014185c5c700ad4280808080e000841001220229000021052008200241086a290000370300200120053703b80120021035200320012903b801370000200341086a2008290300370000200141f0006a41086a2004290300370300200141f0006a41106a2009290300370300200141f0006a41186a20062903003703002001200129039001370370200141b8016a200141f0006a10ce020240024020012802b801220f0d004100210a20014100360238200142043703304104210f410021100c010b200710072001200f360230200120012902bc0122053702342005422088a7210a2005a721100b200d4100200e1b210620014190016a41186a2202420037030020014190016a41106a2209420037030020014190016a41086a22084200370300200142003703900141d1c4c700ad4280808080e000841001220b2900002105200141b8016a41086a2204200b41086a290000370300200120053703b801200b103520082004290300370300200120012903b8013703900141f7c4c700ad4280808080e001841001220b29000021052004200b41086a290000370300200120053703b801200b1035200320012903b801370000200341086a2004290300370000200141f0006a41086a2008290300370300200141f0006a41106a2009290300370300200141f0006a41186a20022903003703002001200129039001370370200141b8016a200141f0006a412010d501024002400240024020012d00b80122030d002002200141d1016a2900003703002009200141c9016a2900003703002008200141c1016a290000370300200120012900b901370390010c010b200710072002200141d1016a2900003703002009200141c9016a2900003703002008200141c1016a290000370300200120012900b9013703900120034101460d010b200141d8006a4200370300200141d0006a4200370300200141c8006a4200370300200142003703400c010b200141c0006a41186a20014190016a41186a290300370300200141c0006a41106a20014190016a41106a290300370300200141c0006a41086a20014190016a41086a29030037030020012001290390013703400b0240200641fb01490d00200641857e6a2208450d00200141b8016a200810b80320013502c00142208620012802b8012208ad84100720012802bc01450d00200810350b41012109024010232207422088a72202450d002007a721090b41002108200141003a00d801200921030240024002400240034020022008460d01200141b8016a20086a20032d00003a00002001200841016a22043a00d801200341016a21032004210820044120470d000b200141f0006a41186a200141b8016a41186a290300370300200141f0006a41106a200141b8016a41106a290300370300200141f0006a41086a200141b8016a41086a290300370300200120012903b80137037002402002450d00200910350b412010332208450d0220082001290310370000200841186a2204200141106a41186a290300370000200841106a2202200141106a41106a290300370000200841086a2209200141106a41086a290300370000412010332203450d0320032008290000370000200341186a2004290000370000200341106a2002290000370000200341086a200929000037000020081035200141e0006a2003ad4280808080800484102410c20120031035024020012802602204450d00200141e8006a28020021022001280264210b41002108200141003a00d801034020022008460d03200141b8016a20086a200420086a2d00003a00002001200841016a22033a00d8012003210820034120470d000b20014190016a41186a200141b8016a41186a2203290300220737030020014190016a41106a200141b8016a41106a2202290300220537030020014190016a41086a200141b8016a41086a2209290300220c370300200120012903b8012211370390012009200c3703002002200537030020032007370300200141b4016a41026a220d200141ed006a41026a2d00003a0000200120113703b801200120012f006d3b01b4010240200a2010470d00200141306a20104101108d012001280230210f2001280238210a0b200f200a41246c6a220841003a0000200820012903b80137000120032903002107200229030021052009290300210c200820012f01b4013b0021200841236a200d2d00003a0000200841096a200c370000200841116a2005370000200841196a20073700002001200a41016a360238200b450d00200410350b200020012903103700102000200636020020002001290370370030200041286a200141106a41186a290300370000200041206a200141106a41106a290300370000200041186a200141106a41086a290300370000200041386a200141f0006a41086a290300370000200041c0006a200141f0006a41106a290300370000200041c8006a200141f0006a41186a290300370000200041e8006a200141c0006a41186a290300370000200041e0006a200141c0006a41106a290300370000200041d8006a200141c0006a41086a290300370000200020012903403700502000410c6a200141306a41086a28020036020020002001290330370204200141e0016a24000f0b0240200841ff0171450d00200141003a00d8010b41b983c800412c200141b8016a41bccfc70041e883c8001046000b0240200841ff0171450d00200141003a00d8010b41b983c800412c200141b8016a41bccfc70041f883c8001046000b1045000b103c000b160020002001280208360204200020012802003602000bff1001067f230041106b22022400024002400240024002400240024002400240024020012d00000e06010402030500010b2002410036020820024201370300410110332203450d082002410136020420022003360200200341003a000020024101360208200141046a28020021042001410c6a2802002201200210770240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d08200541017422072006200720064b1b22074100480d080240024020050d00024020070d00410121060c020b2007103322060d010c0b0b2002280200210620052007460d0020062005200710372206450d0a0b20022007360204200220063602000b200620036a20042001109d081a2002200320016a3602080c050b2002410036020820024201370300410110332203450d072002410136020420022003360200200341023a000020024101360208412010332203450d0520032001290001370000200341186a200141196a290000370000200341106a200141116a290000370000200341086a200141096a2900003700000240024020022802042206417f6a4120490d00200228020021010c010b200641017422014121200141214b1b22054100480d0720022802002101024020062005460d0020012006200510372201450d090b20022005360204200220013602000b20012003290000370001200141196a200341186a290000370000200141116a200341106a290000370000200141096a200341086a29000037000020024121360208200310350c040b2002410036020820024201370300410110332203450d062002410136020420022003360200200341043a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0620022802002103024020062005460d0020032006200510372203450d080b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210770240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d06200541017422072006200720064b1b22074100480d060240024020050d00024020070d00410121060c020b200710332206450d090c010b2002280200210620052007460d0020062005200710372206450d080b20022007360204200220063602000b200620036a20042001109d081a2002200320016a3602080c030b2002410036020820024201370300410110332203450d052002410136020420022003360200200341053a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0520022802002103024020062005460d0020032006200510372203450d070b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210770240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d05200541017422072006200720064b1b22074100480d050240024020050d00024020070d00410121060c020b200710332206450d080c010b2002280200210620052007460d0020062005200710372206450d070b20022007360204200220063602000b200620036a20042001109d081a2002200320016a3602080c020b2002410036020820024201370300410110332203450d042002410136020420022003360200200341063a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0420022802002103024020062005460d0020032006200510372203450d060b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210770240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d04200541017422072006200720064b1b22074100480d040240024020050d00024020070d00410121060c020b200710332206450d070c010b2002280200210620052007460d0020062005200710372206450d060b20022007360204200220063602000b200620036a20042001109d081a2002200320016a3602080c010b2002410036020820024201370300410110332203450d032002410136020420022003360200200341073a00002002410136020820022802002103024020022802044101470d0020034101410210372203450d0420024102360204200220033602000b200341003a0001200241023602082002280200210320022802042106024020012802044101460d00024020064102470d0020034102410410372203450d0520024104360204200220033602000b200341003a0002200241033602080c010b024020064102470d0020034102410410372203450d0420024104360204200220033602000b200341013a000220024103360208200141086a28020021050240024020022802042206417d6a4104490d00200228020021030c010b200641017422034107200341074b1b22044100480d0320022802002103024020062004460d0020032006200410372203450d050b20022004360204200220033602000b20032005360003200241073602082001410c6a2802002106024002402002280204220341796a4104490d00200228020021010c010b20034101742201410b2001410b4b1b22054100480d0320022802002101024020032005460d0020012003200510372201450d050b20022005360204200220013602000b200120063600072002410b3602080b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b1045000b103e000b103c000b8f0201027f20014180feff07714108762102024002402001410171450d00411f210341b0a2cc00210102400240200241ff01710e03000103000b41c100210341efa1cc0021010c020b41c100210341aea1cc0021010c010b411f2103418fa1cc002101024002400240024002400240024002400240200241ff01710e0a00060102030405090708000b4120210341efa0cc0021010c080b41272103418fa0cc0021010c070b4117210341f89fcc0021010c060b41d99fcc0021010c050b4126210341b39fcc0021010c040b412b210341889fcc0021010c030b4139210341b6a0cc0021010c020b413b210341cd9ecc0021010c010b41d100210341fc9dcc0021010b20002003360204200020013602000bc00201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad41012001105221000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000b20024180016a240020000f0b200441800141c88bc0001059000b200441800141c88bc0001059000bb00301027f23004180026b22022400024002402001450d00200220003602000c010b200241b0b4cc003602000b20022001360204200241f8006a200210c4030240200228027c450d00200241086a200241f8006a41f000109d081a200241086a10b7030240200241086a410c6a2802002200450d00200228020c2101200041246c210003400240024020012d0000220341044b0d0002400240024020030e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b0240200241106a2802002201450d00200141246c450d00200228020c10350b20024180026a240042010f0b200241f4016a41043602002002411c6a41023602002002420237020c200241f0b2c300360208200241043602ec01200241b8b3c3003602e801200241003602fc01200241b0b4cc003602f8012002200241e8016a3602182002200241f8016a3602f001200241086a4180b3c300104c000ba00a03077f037e057f230041d0026b2202240041002103200241003a00c8022001280204417f6a210402400240024002400240024003402004417f460d01200241a8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8022004417f6a21042005210320054120470d000b200241e8006a41086a200241a8026a41086a290300370300200241e8006a41106a200241a8026a41106a290300370300200241e8006a41186a200241a8026a41186a290300370300200220022903a8023703682002200110c40120022802000d022002280204210641002104200241003a00c80220012802042107417f2103034020072004460d02200241a8026a20046a200128020022082d00003a00002001200720036a3602042001200841016a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241a8016a41086a200241a8026a41086a2903002209370300200241a8016a41106a200241a8026a41106a290300220a370300200241a8016a41186a200241a8026a41186a290300220b37030020024188016a41086a200937030020024188016a41106a200a37030020024188016a41186a200b370300200220022903a80222093703a801200220093703880141002104200241003a00c802200720056b210c200720036a21030340200c2004460d04200241a8026a20046a200820046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241e8016a41086a200241a8026a41086a2903002209370300200241e8016a41106a200241a8026a41106a290300220a370300200241e8016a41186a200241a8026a41186a290300220b370300200241c8016a41086a22042009370300200241c8016a41106a2203200a370300200241c8016a41186a2205200b370300200220022903a80222093703e801200220093703c801200241a8026a200110cf0220022802a8022201450d04200241c8006a41086a2208200241e8006a41086a290300370300200241c8006a41106a2207200241e8006a41106a290300370300200241c8006a41186a220c200241e8006a41186a290300370300200241286a41086a220d20024188016a41086a290300370300200241286a41106a220e20024188016a41106a290300370300200241286a41186a220f20024188016a41186a29030037030020022002290368370348200220022903880137032820022902ac022109200241086a41186a22102005290300370300200241086a41106a22052003290300370300200241086a41086a22032004290300370300200220022903c801370308200020093702082000200136020420002006360200200041106a2002290348370200200041186a2008290300370200200041206a2007290300370200200041286a200c290300370200200041306a2002290328370200200041386a200d290300370200200041c0006a200e290300370200200041c8006a200f290300370200200041e8006a2010290300370200200041e0006a2005290300370200200041d8006a2003290300370200200041d0006a20022903083702000c050b0240200341ff0171450d00200241003a00c8020b200041003602040c040b0240200441ff0171450d00200241003a00c8020b200041003602040c030b200041003602040c020b0240200441ff0171450d00200241003a00c8020b200041003602040c010b200041003602040b200241d0026a24000bc30202077f017e230041206b22022400200210c60302400240024002402002280208220341046a2204417f4c0d00200228020021050240024020040d0041012106410021040c010b200410332206450d020b2002410036021820022006360210200220043602142003200241106a10770240024020022802142207200228021822046b2003490d00200228021021060c010b200420036a22062004490d03200741017422082006200820064b1b22084100480d030240024020070d00024020080d00410121060c020b2008103322060d010c060b2002280210210620072008460d0020062007200810372206450d050b20022008360214200220063602100b200620046a20052003109d081a200420036aad4220862006ad84210902402002280204450d00200510350b200241206a240020090f0b1044000b1045000b103e000b103c000bbc34010f7f230041d0006b2201240020014100360238200142043703300240410810332202450d002002410c360204200241ba84c800360200200141306a41004101109001200128023020012802384103746a20022902003702002001200128023841016a36023820021035410810332202450d002002410c360204200241c684c800360200200141306a20012802384101109001200128023020012802384103746a20022902003702002001200128023841016a36023820021035410810332202450d0020024108360204200241d284c800360200200141306a20012802384101109001200128023020012802384103746a20022902003702002001200128023841016a36023820021035410810332202450d002002410a360204200241da84c800360200200141306a20012802384101109001200128023020012802384103746a20022902003702002001200128023841016a36023820021035410810332202450d002002410b360204200241e484c800360200200141306a20012802384101109001200128023020012802384103746a20022902003702002001200128023841016a36023820021035410810332202450d0020024118360204200241fcdfc600360200200141306a20012802384101109001200128023020012802384103746a200229020037020020012001280238220341016a22043602382002103520012802342105200128023021062001410036023820014204370330200141306a41002004410374220241037510870120012802382107024020042003490d00200620026a210820012802302007410c6c6a210220062104034020042802002203450d01200241086a200441046a280200360200200241046a2003360200200241003602002002410c6a2102200741016a2107200441086a22042008470d000b0b200120073602380240200541ffffffff0171450d00200610350b200128023421092001280230210a2001410036022820014201370320410410332202450d002001410436022420012002360220200241edcad18b063600002001410436022820012802202102024020012802244104470d0020024104410810372202450d0120014108360224200120023602200b2002410b3a000420014105360228411d200141206a107741ece4c600210b02400340200b2802042105200b2802082203200141206a10770240024020012802242206200128022822086b2003490d0020012802202104200621020c010b200820036a22022008490d02200641017422042002200420024b1b22024100480d020240024020060d00024020020d00410121040c020b2002103322040d010c050b2001280220210420062002460d0020042006200210372204450d040b20012002360224200120043602200b200420086a20052003109d081a2001200820036a220336022802400240200b28020c4102470d000240024020022003460d00200321020c010b200241016a22032002490d04200241017422082003200820034b1b22034100480d040240024020020d0041002102024020030d00410121040c020b200310332204450d070c010b20022003460d0020042002200310372204450d060b20012003360224200120043602200b200420026a41003a00002001200241016a22023602280c010b0240024020022003460d00200321020c010b200241016a22032002490d03200241017422082003200820034b1b22034100480d030240024020020d0041002102024020030d00410121040c020b200310332204450d060c010b20022003460d0020042002200310372204450d050b20012003360224200120043602200b200420026a41013a00002001200241016a36022802400240200b28020c4101470d00200b2802142106200b2802182202200141206a10770240024020012802242208200128022822046b2002490d00200128022021030c010b200420026a22032004490d05200841017422052003200520034b1b22054100480d050240024020080d00024020050d00410121030c020b200510332203450d080c010b2001280220210320082005460d0020032008200510372203450d070b20012005360224200120033602200b200320046a20062002109d081a2001200420026a360228200b28022021020240200b28021c4101470d002002200b280228200141206a107a0c020b2002200b41246a280200200141206a107a0c010b200141306a200b2802101103002001280234210620012802382202200141206a10770240024020012802242208200128022822046b2002490d00200128022021030c010b200420026a22032004490d04200841017422052003200520034b1b22054100480d040240024020080d00024020050d00410121030c020b200510332203450d070c010b2001280220210320082005460d0020032008200510372203450d060b20012005360224200120033602200b200320046a20062002109d081a2001200420026a360228200128024021030240200128023c4101460d0020032001280244200141206a107a0c010b200320012802482202200141206a107a02402002450d00200241d8006c21084100210403400240200320046a220241346a280200450d002002413c6a280200450d00200241386a28020010350b0240200241c4006a280200450d00200241cc006a28020041ffffffff0171450d00200241c8006a28020010350b2008200441d8006a2204470d000b0b20012802442202450d00200241d8006c450d00200310350b200128022821020b2001280224210402400240200b28022c4102470d000240024020042002460d00200128022021040c010b200241016a22042002490d04200241017422032004200320044b1b22034100480d040240024020020d0041002102024020030d00410121040c020b200310332204450d070c010b2001280220210420022003460d0020042002200310372204450d060b20012003360224200120043602200b200420026a41003a00002001200241016a22023602280c010b0240024020042002460d00200128022021040c010b200241016a22042002490d03200241017422032004200320044b1b22034100480d030240024020020d0041002102024020030d00410121040c020b200310332204450d060c010b2001280220210420022003460d0020042002200310372204450d050b20012003360224200120043602200b200420026a41013a00002001200241016a36022802400240200b28022c4101470d00200b2802302104200b2802382202200141206a10772002450d012002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d062006410174220d2008200d20084b1b220d4100480d060240024020060d000240200d0d00410121080c020b200d10332208450d090c010b200128022021082006200d460d0020082006200d10372208450d080b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a360228200241706a200141206a10792002200141206a10762002412c6a2102200541546a22050d000c020b0b200141186a200b28023011030020012802182104200128021c2202200141206a10772002450d002002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d052006410174220d2008200d20084b1b220d4100480d050240024020060d000240200d0d00410121080c020b200d10332208450d080c010b200128022021082006200d460d0020082006200d10372208450d070b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a360228200241706a200141206a10792002200141206a10762002412c6a2102200541546a22050d000b0b200128022821020b2001280224210402400240200b28023c4102470d000240024020042002460d00200128022021040c010b200241016a22042002490d04200241017422032004200320044b1b22034100480d040240024020020d0041002102024020030d00410121040c020b200310332204450d070c010b2001280220210420022003460d0020042002200310372204450d060b20012003360224200120043602200b200420026a41003a00002001200241016a3602280c010b0240024020042002460d00200128022021040c010b200241016a22042002490d03200241017422032004200320044b1b22034100480d030240024020020d0041002102024020030d00410121040c020b200310332204450d060c010b2001280220210420022003460d0020042002200310372204450d050b20012003360224200120043602200b200420026a41013a00002001200241016a3602280240200b28023c4101470d00200b2802402104200b2802482202200141206a10772002450d012002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d052006410174220d2008200d20084b1b220d4100480d050240024020060d000240200d0d00410121080c020b200d10332208450d080c010b200128022021082006200d460d0020082006200d10372208450d070b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a360228200241706a200141206a10762002200141206a10762002412c6a2102200541546a22050d000c020b0b200141106a200b2802401103002001280210210420012802142202200141206a10772002450d002002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d042006410174220d2008200d20084b1b220d4100480d040240024020060d000240200d0d00410121080c020b200d10332208450d070c010b200128022021082006200d460d0020082006200d10372208450d060b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a360228200241706a200141206a10762002200141206a10762002412c6a2102200541546a22050d000b0b02400240200b28024c4101470d00200b280250210e200b2802582202200141206a10772002450d01200241386c210f410021080340200e20086a220241046a280200210c200241086a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d052005410174220d2006200d20064b1b220d4100480d050240024020050d000240200d0d00410121060c020b200d10332206450d080c010b200128022021062005200d460d0020062005200d10372206450d070b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a360228200241106a280200210c200241146a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d052005410174220d2006200d20064b1b220d4100480d050240024020050d000240200d0d00410121060c020b200d10332206450d080c010b200128022021062005200d460d0020062005200d10372206450d070b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a36022802400240200241186a2802004101470d002002411c6a280200210c200241246a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d072005410174220d2006200d20064b1b220d4100480d070240024020050d000240200d0d00410121060c020b200d10332206450d0a0c010b200128022021062005200d460d0020062005200d10372206450d090b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a3602280c010b200141306a2002411c6a280200200241206a28020028020c1102002001280230210520012802382204200141206a1077024002402001280224220c200128022822036b2004490d00200128022021060c010b200320046a22062003490d06200c410174220d2006200d20064b1b220d4100480d0602400240200c0d000240200d0d00410121060c020b200d10332206450d090c010b20012802202106200c200d460d002006200c200d10372206450d080b2001200d360224200120063602200b200620036a20052004109d081a2001200320046a3602282001280234450d00200510350b200241286a200141206a1076200f200841386a2208470d000c020b0b200141086a200b2802501103002001280208210e200128020c2202200141206a10772002450d00200241386c210f410021080340200e20086a220241046a280200210c200241086a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d042005410174220d2006200d20064b1b220d4100480d040240024020050d000240200d0d00410121060c020b200d10332206450d070c010b200128022021062005200d460d0020062005200d10372206450d060b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a360228200241106a280200210c200241146a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d042005410174220d2006200d20064b1b220d4100480d040240024020050d000240200d0d00410121060c020b200d10332206450d070c010b200128022021062005200d460d0020062005200d10372206450d060b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a36022802400240200241186a2802004101470d002002411c6a280200210c200241246a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d062005410174220d2006200d20064b1b220d4100480d060240024020050d000240200d0d00410121060c020b200d10332206450d090c010b200128022021062005200d460d0020062005200d10372206450d080b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a3602280c010b200141306a2002411c6a280200200241206a28020028020c1102002001280230210520012802382204200141206a1077024002402001280224220c200128022822036b2004490d00200128022021060c010b200320046a22062003490d05200c410174220d2006200d20064b1b220d4100480d0502400240200c0d000240200d0d00410121060c020b200d10332206450d080c010b20012802202106200c200d460d002006200c200d10372206450d070b2001200d360224200120063602200b200620036a20052004109d081a2001200320046a3602282001280234450d00200510350b200241286a200141206a1076200f200841386a2208470d000b0b02400240200b28025c4101470d00200b2802602104200b2802682202200141206a10772002450d012002411c6c21052004410c6a21020340200241786a280200210c2002417c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d052006410174220d2008200d20084b1b220d4100480d050240024020060d000240200d0d00410121080c020b200d10332208450d080c010b200128022021082006200d460d0020082006200d10372208450d070b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a3602282002200141206a10762002411c6a2102200541646a22050d000c020b0b2001200b2802601103002001280200210420012802042202200141206a10772002450d002002411c6c21052004410c6a21020340200241786a280200210c2002417c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d042006410174220d2008200d20084b1b220d4100480d040240024020060d000240200d0d00410121080c020b200d10332208450d070c010b200128022021082006200d460d0020082006200d10372208450d060b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a3602282002200141206a10762002411c6a2102200541646a22050d000b0b200b41ec006a220b41a8fdc600470d000b02400240200128022420012802282202460d00200128022021040c010b200241016a22042002490d01200241017422032004200320044b1b22034100480d010240024020020d0041002102024020030d00410121040c020b200310332204450d040c010b2001280220210420022003460d0020042002200310372204450d030b20012003360224200120043602200b200420026a41043a00002001200241016a3602282007200141206a107702402007450d002007410c6c2105200a41086a210403402004417c6a280200210c20042802002202200141206a10770240024020012802242206200128022822036b2002490d00200128022021080c010b200320026a22082003490d032006410174220d2008200d20084b1b220d4100480d030240024020060d000240200d0d00410121080c020b200d10332208450d060c010b200128022021082006200d460d0020082006200d10372208450d050b2001200d360224200120083602200b200820036a200c2002109d081a2001200320026a3602282004410c6a2104200541746a22050d000b0b20002001290320370200200041086a200141206a41086a28020036020002402009450d002009410c6c450d00200a10350b200141d0006a24000f0b103e000b103c000bbc0602057f017e230041900b6b22022400024002402001450d00200220003602000c010b200241b0b4cc003602000b20022001360204200241b8076a200210c803024002400240024020022903a0084203510d00200241186a200241b8076a41c803109d081a200241e0036a200241186a41c803109d081a2002200241e0036a3602b807200241a8076a200241b8076a10b90320022802b0072101200241b8076a200241e0036a41c803109d081a200241880b6a20022802b007360200200220022903a8073703800b200241086a200241b8076a2001200241800b6a10bb034101410220022d000822034101461b220010332201450d01200241003602c007200220003602bc07200220013602b8070240024020034101470d00200141013a0000200241013602c007200241086a410172200241b8076a10c90320022802c00721010c010b200141003a0000200241013602c0070240024020022d000c22044104460d00200141013a000141022103200241023602c00702400240024002400240024020040e0400010203000b410021040c030b410121040c020b200241023a00e003410221040c020b200241033a00e0034104210020014102410410372201450d07200141033a0002200220013602b80720024284808080303702bc07200220022d000d22033a00e003024041010d004106210020014103410610372201450d08200241063602bc07200220013602b8070b200120033a000341042103200241043602c00720022d000e21040b200220043a00e0030b024020002003470d0041000d070240200020004101742205200041016a2206200520064b1b2205460d0020012000200510372201450d070b200220053602bc07200220013602b8070b200120036a20043a0000200341017221010c010b200141003a0001410221010b200220013602c0070b20023502b8072107200241900b6a240020072001ad422086840f0b200241246a4104360200200241f4036a4102360200200242023702e403200241f0b2c3003602e0032002410436021c200241d0b3c3003602182002410036020c200241b0b4cc003602082002200241186a3602f0032002200241086a360220200241e0036a4180b3c300104c000b1045000b103c000b103e000bfb1104047f017e037f047e230041c0086b22022400200241286a200110c401024002400240024002400240024020022802280d0020012802042203450d01200128020022042d0000210520012003417f6a3602042001200441016a360200200541ff00714104470d0220054118744118754100480d03420221060c040b200042033703680c050b200042033703680c040b200042033703680c030b20024198076a20011092060240024020022d0098074102460d00200241f0066a41206a20024198076a41206a280200360200200241f0066a41186a20024198076a41186a290300370300200241f0066a41106a20024198076a41106a290300370300200241f0066a41086a20024198076a41086a29030037030020022002290398073703f00620012802042205450d00200128020022042d0000210320012005417f6a3602042001200441016a360200200341024b0d00024002400240024002400240024020030e03000102000b41002103200241003a00f8042005417f6a2107417e21080240034020072003460d01200241b8046a20036a200420036a220941016a2d00003a00002001200520086a3602042001200941026a3602002002200341016a22093a00f8042008417f6a210820092103200941c000470d000b20024180086a41386a200241b8046a41386a290300220637030020024180086a41306a200241b8046a41306a290300220a37030020024180086a41286a200241b8046a41286a290300220b37030020024180086a41206a200241b8046a41206a290300220c37030020024180086a41186a200241b8046a41186a290300220d37030020024188026a41086a200241b8046a41086a29030037030020024188026a41106a200241b8046a41106a29030037030020024188026a41186a200d37030020024188026a41206a200c37030020024188026a41286a200b37030020024188026a41306a200a37030020024188026a41386a2006370300200220022903b804370388022009417f7320056a2105200420096a41016a2104410021030c030b200341ff0171450d06200241003a00f804420221060c070b41002103200241003a00f8042005417f6a2107417e21080240034020072003460d01200241b8046a20036a200420036a220941016a2d00003a00002001200520086a3602042001200941026a3602002002200341016a22093a00f8042008417f6a210820092103200941c000470d000b20024180086a41386a200241b8046a41386a290300220637030020024180086a41306a200241b8046a41306a290300220a37030020024180086a41286a200241b8046a41286a290300220b37030020024180086a41206a200241b8046a41206a290300220c37030020024180086a41186a200241b8046a41186a290300220d37030020024188026a41086a200241b8046a41086a29030037030020024188026a41106a200241b8046a41106a29030037030020024188026a41186a200d37030020024188026a41206a200c37030020024188026a41286a200b37030020024188026a41306a200a37030020024188026a41386a2006370300200220022903b804370388022009417f7320056a210541012103200420096a41016a21040c020b200341ff0171450d05200241003a00f804420221060c060b41002103200241003a00f9042005417f6a2107417e2108034020072003460d02200241b8046a20036a200420036a220941016a2d00003a00002001200520086a3602042001200941026a3602002002200341016a22093a00f9042008417f6a210820092103200941c100470d000b20024188026a200241b8046a41c100109d081a2009417f7320056a2105200420096a41016a2104410221030b200241bf076a20024188026a41c100109d081a2005450d032004310000210b20012005417f6a22083602042001200441016a360200200b50450d01420021060c020b200341ff0171450d02200241003a00f904420221060c030b2008450d012004310001210c20012005417e6a3602042001200441026a3602004202200b420f8386220a4204540d0142012106200c420886200b84420488200a420c88220b4201200b4201561b7e220b200a5a0d010b200241206a200110c40120022802200d0020022802242105200241086a200110f6012002290308a70d00200241086a41106a290300210d2002290310210c20024180086a41206a200241f0066a41206a28020036020020024180086a41186a200241f0066a41186a29030037030020024180086a41106a200241f0066a41106a29030037030020024180086a41086a200241f0066a41086a290300370300200220022903f00637038008200241b8046a200241bf076a41c100109d081a200220022f01ee063b0186020c010b420221060b200241e0016a41086a220420024180086a41086a290300370300200241e0016a41106a220820024180086a41106a290300370300200241e0016a41186a220920024180086a41186a290300370300200241e0016a41206a220720024180086a41206a28020036020020022002290380083703e0012002419f016a200241b8046a41c100109d081a200220022f0186023b019c0120064202510d01200241f8006a41206a2007280200360200200241f8006a41186a2009290300370300200241f8006a41106a2008290300370300200241f8006a41086a2004290300370300200220022903e001370378200241376a2002419f016a41c100109d081a200220022f019c013b01340b200241b8046a200110b90220022802b804210120024188026a200241b8046a41047241ac02109d081a02402001411b460d0020002002290378370300200020033a0024200041206a200241f8006a41206a280200360200200041186a200241f8006a41186a290300370300200041106a200241f8006a41106a290300370300200041086a200241f8006a41086a290300370300200041256a200241376a41c100109d081a200020022f01343b016620004190016a200d37030020004188016a200c37030020004198016a200136020020004180016a2005360200200041f8006a200b3703002000200a370370200020063703682000419c016a20024188026a41ac02109d081a0c020b200042033703680c010b200042033703680b200241c0086a24000bb30301027f230041106b220224000240024020002d00004101460d00200241003a000e20012002410e6a4101107820002d0001220341094b0d010240024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a000f2002410f6a21000c090b200241013a000f2002410f6a21000c080b200241023a000f2002410f6a21000c070b200241033a000f2002410f6a21000c060b200241043a000f2002410f6a21000c050b200241053a000f2002410f6a21000c040b200241063a000f2002410f6a21000c030b200241073a000f20012002410f6a410110782002200041026a2d00003a000f2002410f6a21000c020b200241083a000f2002410f6a21000c010b200241093a000f2002410f6a21000b20012000410110780c010b200241013a000e20012002410e6a4101107820002d0001220341024b0d0002400240024020030e03000102000b200241003a000e20012002410e6a410110780c020b200241013a000e20012002410e6a410110780c010b200241023a000e20012002410e6a410110782002200041026a2d00003a000e20012002410e6a410110780b200241106a24000be11305047f017e017f017e0b7f23004180026b2202240010bc03200241106a41186a22034200370300200241106a41106a22044200370300200241106a41086a220542003703002002420037031041d1c4c700ad4280808080e000842206100122072900002108200241d0016a41086a2209200741086a290000370300200220083703d0012007103520052009290300370300200220022903d00137031041e7c4c700ad4280808080e00084100122072900002108200241b0016a41086a220a200741086a290000370300200220083703b00120071035200420022903b001220837030020092005290300370300200241d0016a41106a220b2008370300200241d0016a41186a220c200a290300370300200220022903103703d001200241086a200241d0016a412010c00141002107200228020c410020022802081b10bd032003420037030020044200370300200542003703002002420037031020061001220d2900002108200241f0016a41086a220e200d41086a290000370300200220083703f001200d10352005200e290300370300200220022903f00137031041ecedc700ad4280808080e001841001220d2900002108200e200d41086a290000370300200220083703f001200d1035200420022903f001220837030020092005290300370300200b2008370300200c200e290300370300200220022903103703d0012002200241d0016a412010c0012002280204210d2002280200210f200241003602b801200242043703b001200241b0016a4100200d4100200f1b221010870120022802b801211102402010450d0020022802b0012011410c6c6a210d0340200241d0016a200710cb03200241106a20022802d001221220022802d801221310e00202402002280210220f450d002013ad4220862012ad8410070b200741016a210720022902144200200f1b2108200f4101200f1b210f024020022802d401450d00201210350b200d200f360200200d41046a2008370200200d410c6a210d20102007470d000b201120106a21110b20024180016a41086a2011360200200220022903b001220837038001200520113602002002200837031020024190016a200241106a10ba03200241b0016a41186a20024190016a41186a290300370300200241b0016a41106a20024190016a41106a290300370300200a20024190016a41086a29030037030020022002290390013703b001200342003703002004420037030020054200370300200242003703102006100122072900002108200e200741086a290000370300200220083703f001200710352005200e290300370300200220022903f00137031041f7c4c700ad4280808080e00184100122072900002108200e200741086a290000370300200220083703f00120071035200420022903f001370000200441086a200e29030037000020092005290300370300200b2004290300370300200c2003290300370300200220022903103703d001024002400240412010332207450d00200720022903b001370000200741186a200241b0016a41186a290300370000200741106a200241b0016a41106a290300370000200741086a200241b0016a41086a290300370000200241d0016aad42808080808004842007ad4280808080800484100220071035200241106a10be03200241003602b801200242013703b001412010332207450d0020072002290320370000200741186a200241386a290300370000200741106a200241106a41206a290300370000200741086a200241106a41186a29030037000041201033220d450d02200241203602b4012002200d3602b001200d2007290000370000200d41086a200741086a290000370000200d41106a200741106a290000370000200d41186a200741186a290000370000200241203602b80120071035200241106a200241b0016a10e201412010332207450d0020072002290340370000200741186a200241d8006a290300370000200741106a200241d0006a290300370000200741086a200241c8006a2903003700000240024020022802b401221020022802b80122136b4120490d00201341206a210d20022802b001210f201021120c010b201341206a220d2013490d022010410174220f200d200f200d4b1b22124100480d020240024020100d00024020120d004101210f0c020b20121033220f0d010c050b20022802b001210f20102012460d00200f201020121037220f450d040b200220123602b4012002200f3602b0010b200f20136a22132007290000370000201341186a200741186a290000370000201341106a200741106a290000370000201341086a200741086a2900003700002002200d3602b80120071035412010332207450d0020072002290360370000200741186a200241f8006a290300370000200741106a200241f0006a290300370000200741086a200241e8006a29030037000002402012200d6b411f4b0d00200d41206a2213200d490d02201241017422102013201020134b1b22134100480d020240024020120d00024020130d004101210f0c020b20131033220f450d050c010b20122013460d00200f201220131037220f450d040b200220133602b4012002200f3602b0010b200f200d6a220f2007290000370000200f41186a200741186a290000370000200f41106a200741106a290000370000200f41086a200741086a2900003700002002200d41206a3602b80120071035200228021421112002411c6a2802002209200241b0016a10770240024020090d0020022802b801210d20022802b00121050c010b200941246c210e20022802b401210f20022802b8012107201121130340200241d0016a201310c00320022802d001210402400240200f20076b20022802d8012210490d00200720106a210d20022802b0012105200f21120c010b200720106a220d2007490d04200f4101742212200d2012200d4b1b22124100480d0402400240200f0d00024020120d00410121050c020b201210332205450d070c010b20022802b0012105200f2012460d002005200f201210372205450d060b200220123602b401200220053602b0010b200520076a20042010109d081a2002200d3602b801024020022802d401450d00200410350b201341246a21132012210f200d2107200e415c6a220e0d000b0b200dad42208621082005ad210602402009450d00200941246c210d2011210703400240024020072d0000220f41044b0d00024002400240200f0e050400010204040b2007410c6a280200450d03200741086a28020010350c030b2007410c6a280200450d02200741086a28020010350c020b2007410c6a280200450d01200741086a28020010350c010b200741086a280200450d00200741046a28020010350b200741246a2107200d415c6a220d0d000b0b200820068421080240200241186a2802002207450d00200741246c450d00201110350b20024180026a240020080f0b1045000b103e000b103c000bfc0403027f017e057f230041d0006b2202240041d1c4c700ad4280808080e00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541e8eec700ad4280808080d00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000be82709017f017e017f017e017f017e0f7f017e0b7f230041b0056b22022400024002402001450d00200220003602200c010b200241b0b4cc003602200b20022001360224200241186a200241206a10c4010240024020022802180d00200228021c21012002200241206a36029005200241003a00f802200241003602a804200241003602a0042002200136025c200241003602582002200241f8026a360264200220024190056a360260200241d8006a200241a0046a10cd03200241b8036a41086a20022802a8042201360200200220022903a00422033703b80320022d00f8022100200241d8006a41086a22042001360200200220033703582000450d01200241d8006a10a0020b200241ac046a4104360200200241ec006a41023602002002420237025c200241f0b2c300360258200241043602a404200241e8b3c3003602a004200241003602bc03200241b0b4cc003602b8032002200241a0046a3602682002200241b8036a3602a804200241d8006a4180b3c300104c000b200241286a41086a20042802002201360200200220022903582203370328200241386a41086a2001360200200220033703382002410036025020024208370348200241d8006a200241386a10ce0302400240024020022802584101460d00200241d8006a41086a290300210342002105200241f8026a41186a4200370300200241f8026a41106a22064200370300200241f8026a41086a22014200370300200242003703f80241d1efcb00ad42808080809001841001220029000021072001200041086a290000370300200220073703f8022000103541ebc3c400ad4280808080308410012200290000210720024198036a41086a2204200041086a2900003703002002200737039803200010352006200229039803220737030020024190056a41086a200129030037030020024190056a41106a200737030020024190056a41186a2004290300370300200220022903f80237039005200241086a20024190056a10e1022002280208210020022903102107200241c8006a410010a901200228024822082002280250220441c8036c6a220141033602980120014202370368200141a0016a2003200742dc0b7c42dc0b20001b220720032007561b3703002002200441016a22093602504104210a02402002280238220b450d00200228023c210c200b210d0340200d41086a2100200d2f0106220e4103742101410021040240024003402001450d0141f495ca002000410810a008220f450d02200141786a2101200441016a2104200041086a2100200f417f4a0d000b2004417f6a210e0b200c450d02200c417f6a210c200d200e4102746a41e4016a280200210d0c010b0b2002200d2004410c6c6a220141e8006a2802003602a4042002200141e0006a2802003602a004200241d8006a200241a0046a10cf032002280258220a450d02200229025c21050b2005422088a7210e2005a721100c020b200241a8046a200241e4006a2902003703002002200229025c3703a0044184c8c4004128200241a0046a41ecc7c40041acc8c4001046000b4104210a4100210e410021100b200241003602b003200242043703a8030240024002400240024002400240200e450d00200241d8006a41186a220c4200370300200241d8006a41106a22114200370300200241d8006a41086a220f4200370300200242003703584193d1cb00ad4280808080a00184100122012900002103200f200141086a290000370300200220033703582001103541e0caca00ad4280808080e0008410012201290000210320024198036a41086a2200200141086a2900003703002002200337039803200110352011200229039803220337030020024190056a41086a200f29030037030020024190056a41106a200337030020024190056a41186a20002903003703002002200229035837039005200241d8006a20024190056a10b60220022802582201410420011b2112200229025c420020011b2203a721130240024002402003422088a72214450d002012201441c4006c22016a210d200141bc7f6a210420122101034020012d00002100200241d8006a200141016a41c300109d081a20004102460d01200241f8026a41186a200c290000370300200241f8026a41106a2011290000370300200241f8026a41086a200f290000370300200220022900583703f80220004101460d02200441bc7f6a2104200141c4006a2201200d470d000b0b2002410036028003200242013703f8022013450d01201341c4006c450d01201210350c010b20024190056a41086a2200200241f8026a41086a29030037030020024190056a41106a220f200241f8026a41106a29030037030020024190056a41186a220c200241f8026a41186a290300370300200220022903f80222033703b8032002200337039005412010332215450d042015200229039005370000201541186a200c290300370000201541106a200f290300370000201541086a2000290300370000200242818080801037029c03200220153602980302402004450d00200141c4006a2100201441c4006c20126a41bc7f6a211641012114034020002101034020012d00002100200241d8006a200141016a41c300109d081a20004102460d02200241f8026a41186a2204200241d8006a41186a290000370300200241f8026a41106a220f200241d8006a41106a290000370300200241f8026a41086a220c200241d8006a41086a290000370300200220022900583703f802024020004101460d00200141c4006a2201200d470d010c030b0b20024190056a41086a200c290300220337030020024190056a41106a200f290300220537030020024190056a41186a20042903002207370300200220022903f802221737039005200241b8036a41186a220f2007370300200241b8036a41106a220c2005370300200241b8036a41086a22182003370300200220173703b80302402014200228029c03470d0020024198036a20144101108a0120022802980321150b200141c4006a2100201520144105746a220420022903b803370000200441186a200f290300370000200441106a200c290300370000200441086a20182903003700002002201441016a22143602a00320162001470d000b0b02402013450d00201341c4006c450d00201210350b200241f8026a41086a20024198036a41086a28020036020020022002290398033703f8020b200a200e41f0006c6a2115200241a0046a41106a2119200241a0046a41086a211a41d1c4c700ad4280808080e0008421054104211b4104211c4104211d4100211e200a210f0340200f280204210d200f2802002104200241d8006a200f41086a41e800109d081a200f41f0006a210f200d450d02200241b8036a200241d8006a41e800109d081a2002200d3602a404200220043602a004201a200241b8036a41e800109d081a200241d8006a41186a22164200370300200241d8006a41106a22184200370300200241d8006a41086a220c4200370300200242003703582005100122012900002103200c200141086a290000370300200220033703582001103541e7c4c700ad4280808080e0008410012201290000210320024198036a41086a2200200141086a2900003703002002200337039803200110352011200229039803370000201141086a200029030037000020024190056a41086a221f200c29030037030020024190056a41106a2220201829030037030020024190056a41186a222120162903003703002002200229035837039005200220024190056a412010c001200228020021012002280204210020024190056a200241a0046a10d003024002402004417f6a220e2000410020011b22014f0d00200241d8006a200e10d103200241d8006a2019412010a0080d00200441002001417b6a2200200020014b1b490d002002280280032222410574211220024190056a20022802f802220e6b21144100210102400340024020122001470d00410021130c020b4101211320142001460d01200e20016a2100200141206a2101200020024190056a412010a0080d000b0b200241d8006a200410d103200241d8006a20024190056a412010a008210120130d002001450d0020024190056a200241a0046a10d003200241d8006a200241a0046a41f000109d081a0240201e20022802ac03470d00200241a8036a201e410110930120022802b003211e20022802a803221b211c201b211d0b201d201e41f0006c6a200241d8006a41f000109d081a2002201e41016a221e3602b0032016202129030037030020182020290300370300200c201f29030037030020022002290390053703580240202220022802fc02470d00200241f8026a20224101108a0120022802f802210e20022802800321220b200e20224105746a22012002290358370000200141186a2016290300370000200141106a2018290300370000200141086a200c2903003700002002202241016a36028003201e410a470d01410a211e0c040b024020022802ac042201450d00200141246c2100200d210103400240024020012d0000220441044b0d0002400240024020040e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b20022802a8042201450d00200141246c450d00200d10350b200f2015470d000b2015210f0c010b2010450d01201041f0006c450d01200a10350c010b02402015200f460d000340200f220141046a220010b103200141f0006a210f0240200141086a2802002201450d00200141246c450d00200028020010350b2015200f470d000b0b02402010450d00201041f0006c450d00200a10350b024020022802fc0241ffffff3f71450d0020022802f80210350b0240201e0d0020022802ac032201450d01200141f0006c450d01201b10350c010b201c450d0020022902ac03210302402009200228024c470d00200241c8006a200910a90120022802482108200228025021090b2008200941c8036c6a200241a0046a41e800109d0822014202370368200141a0016a20033703002001419c016a201c3602002001410436029801200120022903b803370370200141f8006a200241c0036a29030037030020014180016a200241c8036a29030037030020014188016a200241d0036a29030037030020014190016a200241d8036a290300370300200141a8016a200241d8006a41a002109d081a2002200941016a22093602500b0240200b450d00200228023c210d0340200b41086a2100200b2f0106220c4103742101410021040240024003402001450d0141fc95ca002000410810a008220f450d02200141786a2101200441016a2104200041086a2100200f417f4a0d000b2004417f6a210c0b200d450d02200d417f6a210d200b200c4102746a41e4016a280200210b0c010b0b200b41e0006a2004410c6c6a22012802084104490d002001280200280000210f200241f8026a41186a22044200370300200241f8026a41106a220d4200370300200241f8026a41086a22014200370300200242003703f80241bee4cb00ad4280808080f001841001220029000021032001200041086a290000370300200220033703f8022000103541b9e0c600ad4280808080b0018410012200290000210320024198036a41086a220c200041086a2900003703002002200337039803200010352006200229039803370000200641086a200c29030037000020024190056a41086a200129030037030020024190056a41106a200d29030037030020024190056a41186a2004290300370300200220022903f80237039005200241d8006a20024190056a10c50220022802582201410420011b2104410021000240200229025c420020011b2203422088a72201450d00200141027420046a417c6a2201450d002001280200200f4721000b0240200342ffffffff0383500d00200410350b2000450d0002402009200228024c470d00200241c8006a200910a90120022802482108200228025021090b2008200941c8036c6a200241a0046a41e800109d0822014202370368200120022903b803370370200141f8006a200241c0036a29030037030020014180016a200241c8036a29030037030020014188016a200241d0036a29030037030020014190016a200241d8036a2903003703002001419c016a200f3602002001410e36029801200141a8016a200241d8006a41a002109d081a2002200941016a22093602500b200228024c2114200241386a10a002200941c8036c4104722201417f4c0d01200110332200450d00200241003602a804200220013602a404200220003602a0042009200241a0046a10770240024020090d0020022802a804210020022802a004210e0c010b200941c8036c211320022802a404210420022802a80421012008210d03402002200d3602b803200241d8006a200241b8036a10b9032002280258211202400240200420016b2002280260220c490d002001200c6a210020022802a004210e2004210f0c010b2001200c6a22002001490d052004410174220f2000200f20004b1b220f4100480d050240024020040d000240200f0d004101210e0c020b200f1033220e0d010c080b20022802a004210e2004200f460d00200e2004200f1037220e450d070b2002200f3602a4042002200e3602a0040b200e20016a2012200c109d081a200220003602a8040240200228025c450d00201210350b200d41c8036a210d200f210420002101201341b87c6a22130d000b0b2000ad4220862103200ead210502402009450d00200941c8036c210020084198016a21010340200110bb02200141c8036a2101200041b87c6a22000d000b0b2003200584210302402014450d00201441c8036c450d00200810350b200241b0056a240020030f0b1045000b1044000b103e000b103c000bd40505067f017e047f017e027f23004180026b22022400024002400240024002402000280200220320002802044f0d00200028020c2104200141086a2105200241a0016a4102722106024003402000200341016a360200200241186a2000280208280200220710ee0220022d00184101460d0120022900192108200241086a200710c40120022802080d012007280204200228020c2203490d012003417f4c0d0302400240024020030d0041002107410121090c010b200310392209450d0820072802042003490d01200920072802002003109d081a2007280204220a2003490d062007200a20036b3602042007200728020020036a360200200321070b20022008370310024002402001280200220b450d002001280204210c0c010b2006410041da00109f081a200241186a4100418401109f081a41e4011033220b450d074100210c200b4100360200200b41046a200241a0016a41dc00109d081a200b41e0006a200241186a418401109d081a200141003602042001200b3602000b2003ad4220862007ad84210d024002400340200b41086a2107200b2f0106220e41037421034100210a024003402003450d01200241106a2007410810a008220f450d03200341786a2103200a41016a210a200741086a2107200f417f4a0d000b200a417f6a210e0b0240200c450d00200c417f6a210c200b200e4102746a41e4016a280200210b0c010b0b2002200837022c200220053602282002200e360224200220013602202002200b36021c200241003602182002200d3702a401200220093602a001200241186a200241a0016a1082030c010b200b200a410c6c6a220341e4006a2207280200210a2007200d370200200341e0006a22072802002103200720093602002003450d00200a450d00200310350b200028020022032000280204490d010c030b0b200910350b200441013a00000b20024180026a24000f0b1044000b2003200a41a4f0cb001059000b103c000b1045000b8c0201067f02400240024020012802002202450d00200128020421030340200241086a210420022f010622054103742101410021060240024003402001450d0141f8eecb002004410810a0082207450d02200141786a2101200641016a2106200441086a21042007417f4a0d000b2006417f6a21050b2003450d022003417f6a2103200220054102746a41e4016a28020021020c010b0b200241e0006a2006410c6c6a22012802084108490d01200041086a2001280200290000370300200041003602000f0b200041003602042000410c6a4128360200200041086a4180efcb003602000c010b200041003602042000410c6a4129360200200041086a41a8efcb003602000b200041013602000bf80303037f017e057f230041e0026b22022400200241086a200110c40102400240024002402002280208450d00200041003602000c010b200228020c2203200128020441f0006e2204200420034b1bad42f0007e2205422088a70d012005a72206417f4c0d010240024020060d00410421070c010b200610332207450d030b4100210420024100360218200220073602102002200641f0006e360214024002402003450d00200241f0016a41086a21080340200241f0016a200110c40320022802f401210620022802f001210920024188016a200841e800109d081a2006450d02200241206a20024188016a41e800109d081a024020042002280214470d00200241106a2004410110930120022802102107200228021821040b2007200441f0006c6a220a2006360204200a2009360200200a41086a200241206a41e800109d081a2002200441016a22043602182003417f6a22030d000b0b20002002290310370200200041086a200241106a41086a2802003602000c010b2000410036020002402004450d00200441f0006c2106200741046a21040340200410b1030240200441046a280200220a450d00200a41246c450d00200428020010350b200441f0006a2104200641907f6a22060d000b0b20022802142204450d00200441f0006c450d00200710350b200241e0026a24000f0b1044000b1045000b9b0902097f037e230041206b220224002002410036020820024201370300024002400240412010332203450d0020032001290010370000200341186a2204200141286a290000370000200341106a2205200141206a290000370000200341086a2206200141186a290000370000412010332207450d02200241203602042002200736020020072003290000370000200741086a2006290000370000200741106a2005290000370000200741186a200429000037000020024120360208200310352001200210e201412010332203450d0020032001290030370000200341186a200141c8006a290000370000200341106a200141c0006a290000370000200341086a200141386a2900003700000240024020022802042208200228020822066b4120490d00200641206a210720022802002104200821050c010b200641206a22072006490d02200841017422042007200420074b1b22054100480d020240024020080d00024020050d00410121040c020b2005103322040d010c050b2002280200210420082005460d0020042008200510372204450d040b20022005360204200220043602000b200420066a22062003290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a2900003700002002200736020820031035412010332203450d0020032001290050370000200341186a200141e8006a290000370000200341106a200141e0006a290000370000200341086a200141d8006a2900003700000240200520076b411f4b0d00200741206a22062007490d02200541017422082006200820064b1b22064100480d020240024020050d00024020060d00410121040c020b200610332204450d050c010b20052006460d0020042005200610372204450d040b20022006360204200220043602000b200420076a22042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a2900003700002002200741206a36020820031035200128020421052001410c6a2802002201200210770240024020010d002002280208210320022802042104200228020021080c010b200141246c210920022802042107200228020821010340200241106a200510c0032002280210210a02400240200720016b20022802182206490d00200120066a210320022802002108200721040c010b200120066a22032001490d04200741017422042003200420034b1b22044100480d040240024020070d00024020040d00410121080c020b200410332208450d070c010b2002280200210820072004460d0020082007200410372208450d060b20022004360204200220083602000b200820016a200a2006109d081a2002200336020802402002280214450d00200a10350b200541246a210520042107200321012009415c6a22090d000b0b2003ad4220862008ad8410092201290000210b200141086a290000210c200141106a290000210d200041186a200141186a290000370000200041106a200d370000200041086a200c3700002000200b3700002001103502402004450d00200810350b200241206a24000f0b1045000b103e000b103c000bb90603027f017e057f23004180016b2202240041d1c4c700ad4280808080e00084100122032900002104200241306a41086a200341086a290000370300200220043703302003103541dec4c700ad4280808080900184100122032900002104200241d0006a41086a200341086a2900003703002002200437035020031035200220013602742002200241f4006aad4280808080c000841003220329000037037820031035200241146a200241f8006a3602002002200241f8006a41086a36020c2002200241f4006a3602102002200241f8006a360208200241c0006a200241086a107b02400240024002402002280248220541206a2206417f4c0d00200228024021070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290330370000200341086a200241306a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290350370010200341186a200241d0006a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a02402002280244450d00200710350b200241086a2003200610d501200241d0006a41086a2201200241116a290000370300200241d0006a41106a2206200241196a290000370300200241d0006a41186a2205200241216a290000370300200220022900093703500240024020022d00084101460d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290350370000200041186a2005290300370000200041106a2006290300370000200041086a20012903003700000b02402008450d00200310350b20024180016a24000f0b1044000b1045000b103e000b103c000bac2508077f017e0d7f017e017f027e017f037e230041f0026b22022400024002402001450d00200220003602180c010b200241b0b4cc003602180b2002200136021c200241f8006a200241186a10b6030240024002400240024002400240200228027c2203450d00200241f0016a2802002104200241ec016a2802002105200241e8016a2802002106200241f8006a410c6a28020021072002280280012108200241106a200241186a10c4010240024020022802100d00200228021421012002200241186a360250200241003a0020200241003602980220024100360290022002200136027c200241003602782002200241206a360284012002200241d0006a36028001200241f8006a20024190026a10cd03200241e0006a41086a20022802980222013602002002200229039002220937036020022d00202100200241f8006a41086a220a2001360200200220093703782000450d01200241f8006a10a0020b20024190026a410c6a41043602002002418c016a41023602002002420237027c200241f0b2c300360278200241043602940220024184b4c3003602900220024100360264200241b0b4cc00360260200220024190026a360288012002200241e0006a36029802200241f8006a4180b3c300104c000b200241306a41086a200a2802002201360200200220022903782209370330200241c0006a41086a200136020020022009370340200241013b015c2002410036025820024100360250024002402004450d002006200441c8036c6a210b200241d0006a41086a210c200241e0006a410472210d20024190026a410272210e200241f8006a41106a210f200621100340201041e8006a2903004202520d0102400240024002400240201028029801221141034722120d00024002400240024020022802402213450d0020102903a0012109200228024421140340201341086a210020132f0106221541037421014100210a0240024003402001450d01418799cc002000410810a0082216450d02200141786a2101200a41016a210a200041086a21002016417f4a0d000b200a417f6a21150b2014450d022014417f6a2114201320154102746a41e4016a28020021130c010b0b0240201341e0006a200a410c6c6a220128020841074b0d002017428080808070834229842109418f99cc0021140c020b200942b8178020012802002900002217510d034131211841e8c1c30021140c020b201742808080807083421c84210941b899cc0021140b2009a721180b0240024020022d005d450d0041c4c6ca002101413121000c010b200241d0006a10a0022002410036025820024100360250200242e2c289abb68edbb7f40037036020024190026a410272410041da00109f081a200241f8006a4100418401109f081a41e40110332216450d1020164100360200201641046a20024190026a41dc00109d081a201641e0006a200241f8006a418401109d081a200241003602542002201636025020162f010622104103742113417f210041002101024002400340024020132001470d00201021000c020b200241e0006a201620016a41086a410810a008220a450d02200141086a2101200041016a2100200a41004e0d000b0b200242e2c289abb68edbb7f40037028c012002200c3602880120022000360284012002201636027c200241003602782002200241d0006a3602800120024190026a2014201810d303200241f8006a20024190026a10820320024180023b015c200241206a41086a200241d0006a41086a290300370300200220022903503703200c0a0b41f5c6ca002101412d21000b2002200036027c200220013602784181c6ca004122200241f8006a41a4c6ca0041b4c6ca001046000b20120d0020102903a0012109200241f8006a200241c0006a10ce03024002400240024020022802784101460d002002290380012119200241f8006a41186a220a4200370300200f4200370300200241f8006a41086a220142003703002002420037037841d1efcb00ad428080808090018410012200290000211a2001200041086a2900003703002002201a3703782000103541ebc3c400ad4280808080308410012200290000211a200241e0006a41086a2216200041086a2900003703002002201a37036020001035200f2002290360370000200f41086a201629030037000020024190026a41086a200129030037030020024190026a41106a200f29030037030020024190026a41186a200a2903003703002002200229037837039002200220024190026a10e1022009201942b0ea017c560d012009200229030842dc0b7c42dc0b20022802001b22195a0d032019422088211a420021090c020b2002290380012219422088211a200228027c221bad4220864201842109201c4280808080708320023502880184221c211d0c010b201d428080808070832018ad84211d41e9eac400ad21194225211a420121094100211b0b2002201d3703702002201a422086201942ffffffff0f8384221e3703682002201bad422086200942ffffffff0f838437036002400240024020022d005d450d0041c4c6ca002101413121000c010b0240024002402009a722154101470d00200241d0006a10a0022002410036025820024100360250200242f4d2b59bc7ae98b8303703200c010b20022802502113200242f4d2b59bc7ae98b8303703202013450d00200228025421140c010b200e410041da00109f081a200241f8006a4100418401109f081a41e40110332213450d124100211420134100360200201341046a20024190026a41dc00109d081a201341e0006a200241f8006a418401109d081a20024100360254200220133602500b2019a72112201aa7211102400340201341086a210020132f0106221841037421014100210a024003402001450d01200241206a2000410810a0082216450d03200141786a2101200a41016a210a200041086a21002016417f4a0d000b200a417f6a21180b02402014450d002014417f6a2114201320184102746a41e4016a28020021130c010b0b200242f4d2b59bc7ae98b83037028c012002200c3602880120022018360284012002201336027c200241003602782002200241d0006a360280014101103321010240201541014622160d002001450d13200141003a000020014101410910372201450d132001201e3700014109210a410921000c030b2001450d12200141013a000020024190026a200d10b40320022802900221140240024020022802980222130d004101210a201341016a21000c010b201341016a22002013490d1020004102200041024b1b220a4100480d1020014101200a10372201450d130b200141016a20142013109d081a200228029402450d02201410350c020b41f5c6ca002101412d21000b2002200036027c200220013602784181c6ca004122200241f8006a41a4c6ca0041b4c6ca001046000b20022000360298022002200a360294022002200136029002200241f8006a20024190026a108203200220093c005d200241003a005c20160d022015450d00201b450d002011450d00201210350b20102802980121110b20114104470d03201041a4016a280200410b490d032002410d36026820024192c8ca003602642002410036026020022d005d450d0141c4c6ca002101413121000c020b200241206a41086a200241d0006a41086a29030037030020022002290350370320201b450d052011450d05201210350c050b200241d0006a10a0022002410036025820024100360250200242f5dc8de3d6ec9c983037032020024190026a410272410041da00109f081a200241f8006a4100418401109f081a41e40110332216450d0b4100210120164100360200201641046a20024190026a41dc00109d081a201641e0006a200241f8006a418401109d081a200241003602542002201636025020162f010622144103742113417f2100024002400340024020132001470d00201421000c020b200241206a201620016a41086a410810a008220a450d02200141086a2101200041016a2100200a417f4a0d000b0b200242f5dc8de3d6ec9c983037028c012002200c3602880120022000360284012002201636027c200241003602782002200241d0006a36028001410110332201450d0c200141003a000020024190026a200241e0006a10b40320022802900221160240024020022802980222000d0041012113200041016a210a0c010b200041016a220a2000490d0a200a4102200a41024b1b22134100480d0a20014101201310372201450d0d0b200141016a20162000109d081a0240200228029402450d00201610350b2002200a3602880220022013360284022002200136028002200241f8006a20024180026a10820320024180023b015c200241206a41086a200241d0006a41086a290300370300200220022903503703200c050b41f5c6ca002101412d21000b2002200036027c200220013602784181c6ca004122200241f8006a41a4c6ca0041b4c6ca001046000b201041c8036a2210200b470d000b0b200241206a41086a200241d0006a41086a290300370300200220022903503703200b200241c0006a10a00202402007450d00200741246c21002003210103400240024020012d0000220a41044b0d00024002400240200a0e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b02402008450d00200841246c450d00200310350b02402004450d00200441c8036c210020064198016a21010340200110bb02200141c8036a2101200041b87c6a22000d000b0b02402005450d00200541c8036c450d00200610350b200241003602682002420137036020022d002c2100410110332201450d062002410136026420022001360260200120003a00002002410136026820022d002d210020014101410210372201450d062002410236026420022001360260200120003a00012002410236026820022802282200200241e0006a1077024020022802202201450d00024020022802242216450d002016210a20012113034020132802e4012113200a417f6a220a0d000b2001210a0340200a200a2f01064102746a41e4016a280200210a2016417f6a22160d000b200241f8006a2116201321010c030b200241f8006a21162001210a0c020b410021012002410036027c200241f8006a21160c020b200241ec006a4104360200200241a4026a41023602002002420237029402200241f0b2c300360290022002410436026420024184b4c30036026020024100360254200241b0b4cc003602502002200241e0006a3602a0022002200241d0006a36026820024190026a4180b3c300104c000b2002200a36027c20024184016a200a2f01063602002002410036028001200241003602780b20024190026a41086a201641086a29020022093703002002201629020022173703900220024190016a200937030020024200370380012002200136027c20024100360278200220173703880120022000360298012000450d01034020022000417f6a36029801200241f8006a410020011b2213280200210a20132802082114024002400240201328020c2216201328020422002f01064f0d00200021010c010b0240034020002802002201450d01200a41016a210a20002f0104211620012100201620012f0106490d020c000b0b2014ad2109410021010c010b2016ad4220862014ad8421090b2009422088a7221441016a21162009a7211802400240200a0d00200121000c010b200120164102746a41e4016a280200210041002116200a417f6a220a450d00034020002802e4012100200a417f6a220a0d000b0b2013201636020c2013201836020820132000360204201341003602000240024020022802642216200228026822006b4108490d002002280260210a0c010b200041086a220a2000490d0220164101742213200a2013200a4b1b22134100480d020240024020160d00024020130d004101210a0c020b20131033220a0d010c070b2002280260210a20162013460d00200a201620131037220a450d060b200220133602642002200a3602600b200a20006a200120144103746a41086a2900003700002002200041086a360268200141e0006a2014410c6c6a2201280200211320012802082201200241e0006a10770240024020022802642216200228026822006b2001490d002002280260210a0c010b200020016a220a2000490d0220164101742214200a2014200a4b1b22144100480d020240024020160d00024020140d004101210a0c020b20141033220a450d070c010b2002280260210a20162014460d00200a201620141037220a450d060b200220143602642002200a3602600b200a20006a20132001109d081a2002200020016a22013602682002280298012200450d03200228027c21010c000b0b103e000b200228026821012002280260210a0b200241206a10a002200241f0026a24002001ad422086200aad840f0b103c000bac0401057f024002400240200241046a2203417f4c0d0002400240024002400240024002400240024002402003450d00200310332204450d0b200241c000490d04200241808001490d052002418080808004490d0620030d010b41012103410110332204450d07200441033a0000410521050c010b200441033a000002402003417f6a41034d0d00200321050c020b200341017422064105200641054b1b22054100480d0720032005460d010b20042003200510372204450d050b20042002360001410521060c030b024020030d0041012103410110332204450d040b200420024102743a000041012106200321050c020b02400240200341014d0d00200321050c010b200341017422064102200641024b1b2105024020030d002005103322040d010c040b20032005460d0020042003200510372204450d030b41022106200420024102744101723b00000c010b02400240200341034d0d00200321050c010b200341017422064104200641044b1b22054100480d03024020030d002005103322040d010c030b20032005460d0020042003200510372204450d020b20042002410274410272360000410421060b0240200520066b2002490d00200521030c050b200620026a22032006490d01200541017422072003200720034b1b22034100480d0120052003460d04200420052003103722040d040b103c000b103e000b1044000b1045000b200420066a20012002109d081a2000200620026a36020820002003360204200020043602000bbf0101067f230041206b22022400200241b0b4cc00410010d50302400240412010332203450d0020032002290300370000200341186a2204200241186a290300370000200341106a2205200241106a290300370000200341086a2206200241086a290300370000412010332207450d0120072003290000370000200741186a2004290000370000200741106a2005290000370000200741086a200629000037000020031035200241206a24002007ad42808080808004840f0b1045000b103c000be51b06037f017e077f017e277f027e230041a00d6b220324002003200236020c20032001360208200341206a41186a22044200370300200341206a41106a22024200370300200341206a41086a220142003703002003420037032041d1c4c700ad4280808080e000841001220529000021062001200541086a290000370300200320063703202005103541e7c4c700ad4280808080e00084100122072900002106200341106a41086a2205200741086a2900003703002003200637031020071035200220032903102206370300200341800d6a41086a22082001290300370300200341800d6a41106a22092006370300200341800d6a41186a220a2005290300370300200320032903203703800d2003200341800d6a412010c0012003280204210b2003280200210c200442003703002002420037030020014200370300200342003703204182e9ca00ad42808080808003841001220729000021062001200741086a2900003703002003200637032020071035419ae9ca00ad4280808080e001841001220729000021062005200741086a29000037030020032006370310200710352002200329031022063703002008200129030037030020092006370300200a2005290300370300200320032903203703800d200341206a200341800d6a412010b50220032802202201410120011b210d0240024002402003290224420020011b220e422088a722020d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b200341206a410041e00c109f081a200b417f6a41d100704130200c1b2101200d41206a210f200d20024105746a21104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f410021204100212141002122410021234100212441002125410021264100212741002128410021294100212a4100212b4100212c4100212d4100212e4100212f4100210b200d21024100213041d1002131024003402030210720022105024002402001450d00200141016a2101200521020340024020102002470d00200d21020b2002220541206a21022001417f6a22010d000b20050d010c030b024020052010460d00200541206a21020c010b200f2102200d21050b0240024002400240200328020c220141056a2204417f4c0d00200328020821320240024020040d00410021044101210c0c010b20041033220c450d020b200341003602182003200c36021020032004360214024020040d0041011033220c450d08200341013602142003200c3602100b200c20073a0000200341013602182001200341106a10770240024020032802142233200328021822306b2001490d00200328021021042033210c0c010b203020016a22042030490d032033410174220c2004200c20044b1b220c4100480d030240024020330d000240200c0d00410121040c020b200c103322040d010c0a0b200328021021042033200c460d0020042033200c10372204450d090b2003200c360214200320043602100b200420306a20322001109d081a2003203020016a2230360218412010332201450d0120012005290000370000200141186a2232200541186a290000370000200141106a2234200541106a290000370000200141086a2235200541086a29000037000002400240200c20306b411f4d0d00200c21330c010b203041206a22052030490d03200c41017422332005203320054b1b22334100480d0302400240200c0d00024020330d00410121040c020b203310332204450d0a0c010b200c2033460d002004200c203310372204450d090b20032033360214200320043602100b200420306a22052001290000370000200541186a2032290000370000200541106a2034290000370000200541086a20352900003700002003203041206a2205360218200110352005ad4220862004ad84100922012900002106200141086a2900002136200141106a2900002137200a200141186a2900003703002009203737030020082036370300200320063703800d2001103502402033450d00200410350b2031417f6a2131200741016a2130200341206a20074103704105746a220120032903800d370000200141186a200a290300370000200141106a2009290300370000200141086a20082903003700004100210503402007200741036e2204417d6c6a4102470d04200341206a20056a220141df006a2d0000220b2001411f6a2d0000220c71200b200c722001413f6a2d000071722128200141de006a2d0000220b2001411e6a2d0000220c71200b200c722001413e6a2d000071722127200141dd006a2d0000220b2001411d6a2d0000220c71200b200c722001413d6a2d000071722126200141dc006a2d0000220b2001411c6a2d0000220c71200b200c722001413c6a2d000071722125200141db006a2d0000220b2001411b6a2d0000220c71200b200c722001413b6a2d000071722124200141da006a2d0000220b2001411a6a2d0000220c71200b200c722001413a6a2d000071722123200141d9006a2d0000220b200141196a2d0000220c71200b200c72200141396a2d000071722122200141d8006a2d0000220b200141186a2d0000220c71200b200c72200141386a2d000071722121200141d7006a2d0000220b200141176a2d0000220c71200b200c72200141376a2d000071722120200141d6006a2d0000220b200141166a2d0000220c71200b200c72200141366a2d00007172211f200141d5006a2d0000220b200141156a2d0000220c71200b200c72200141356a2d00007172211e200141d4006a2d0000220b200141146a2d0000220c71200b200c72200141346a2d00007172211d200141d3006a2d0000220b200141136a2d0000220c71200b200c72200141336a2d00007172211c200141d2006a2d0000220b200141126a2d0000220c71200b200c72200141326a2d00007172211b200141d1006a2d0000220b200141116a2d0000220c71200b200c72200141316a2d00007172211a200141d0006a2d0000220b200141106a2d0000220c71200b200c72200141306a2d000071722119200141cf006a2d0000220b2001410f6a2d0000220c71200b200c722001412f6a2d000071722118200141ce006a2d0000220b2001410e6a2d0000220c71200b200c722001412e6a2d000071722117200141cd006a2d0000220b2001410d6a2d0000220c71200b200c722001412d6a2d000071722116200141cc006a2d0000220b2001410c6a2d0000220c71200b200c722001412c6a2d000071722115200141cb006a2d0000220b2001410b6a2d0000220c71200b200c722001412b6a2d000071722114200141ca006a2d0000220b2001410a6a2d0000220c71200b200c722001412a6a2d000071722113200141c9006a2d0000220b200141096a2d0000220c71200b200c72200141296a2d000071722112200141c8006a2d0000220b200141086a2d0000220c71200b200c72200141286a2d000071722111200141c7006a2d0000220b200141076a2d0000220c71200b200c72200141276a2d000071722129200141c6006a2d0000220b200141066a2d0000220c71200b200c72200141266a2d00007172212a200141c5006a2d0000220b200141056a2d0000220c71200b200c72200141256a2d00007172212b200141c4006a2d0000220b200141046a2d0000220c71200b200c72200141246a2d00007172212c200141c3006a2d0000220b200141036a2d0000220c71200b200c72200141236a2d00007172212d200141c2006a2d0000220b200141026a2d0000220c71200b200c72200141226a2d00007172212e200141c1006a2d0000220b200141016a2d0000220c71200b200c72200141216a2d00007172212f200141c0006a2d0000220b20012d0000220c71200b200c72200141206a2d00007172210b200541800c460d04200341206a20052004410574200741096e41e0006c6b6a6a220141ff006a20283a0000200141fe006a20273a0000200141fd006a20263a0000200141fc006a20253a0000200141fb006a20243a0000200141fa006a20233a0000200141f9006a20223a0000200141f8006a20213a0000200141f7006a20203a0000200141f6006a201f3a0000200141f5006a201e3a0000200141f4006a201d3a0000200141f3006a201c3a0000200141f2006a201b3a0000200141f1006a201a3a0000200141f0006a20193a0000200141ef006a20183a0000200141ee006a20173a0000200141ed006a20163a0000200141ec006a20153a0000200141eb006a20143a0000200141ea006a20133a0000200141e9006a20123a0000200141e8006a20113a0000200141e7006a20293a0000200141e6006a202a3a0000200141e5006a202b3a0000200141e4006a202c3a0000200141e3006a202d3a0000200141e2006a202e3a0000200141e1006a202f3a0000200141e0006a200b3a000020042107200541e0006a220541e00c470d000c040b0b1044000b1045000b103e000b4100210120310d000b0b200020283a001f200020273a001e200020263a001d200020253a001c200020243a001b200020233a001a200020223a0019200020213a0018200020203a00172000201f3a00162000201e3a00152000201d3a00142000201c3a00132000201b3a00122000201a3a0011200020193a0010200020183a000f200020173a000e200020163a000d200020153a000c200020143a000b200020133a000a200020123a0009200020113a0008200020293a00072000202a3a00062000202b3a00052000202c3a00042000202d3a00032000202e3a00022000202f3a00012000200b3a00000b0240200e42ffffff3f83500d00200d10350b200341a00d6a24000f0b103c000b925303097f087e047f230041a0136b220224000240024020010d0020022001360254200241b0b4cc003602500c010b2002200136025420022001417f6a360254200220003602502002200041016a36025020002d0000220341034f0d00200241a80b6a200241d0006a10c80302400240024002400240024002400240024020022903900c4203510d0020024190016a200241a80b6a41c803109d081a200241d8046a20024190016a41c803109d081a2002200241d8046a3602a008200241a80b6a200241a0086a10b90320022802b00b2100024020022802ac0b450d0020022802a80b10350b200241a80b6a200241d8046a41c803109d081a200241a0086a200241a80b6a10d70341012101024020022d00a0084101460d00200241a80b6a200241a0086a41086a2201418003109d081a200241f00e6a200241f80b6a220410d8030240024020022903c80b4202520d00200241800f6a41206a22014200370300200241800f6a41186a22054280808080c000370300200241013a00a80f200242043703900f2002427f3703880f200242003703800f200241a0086a41206a22064200370300200241a0086a41186a22074280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a008200241e0106a200241800f6a200241a0086a10d903200241800f6a41286a2208200241e0106a41286a2903003703002001200241e0106a41206a2903003703002005200241e0106a41186a290300370300200241800f6a41106a2209200241e0106a41106a290300370300200241800f6a41086a220a200241e0106a41086a290300370300200220022903e0103703800f2006420037030020074280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a00820024190116a200241800f6a200241a0086a10d903200820024190116a41286a290300370300200120024190116a41206a290300370300200520024190116a41186a290300370300200920024190116a41106a290300370300200a20024190116a41086a29030037030020022002290390113703800f2006420037030020074280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a008200241c0116a200241800f6a200241a0086a10d9032008200241c0116a41286a2903003703002001200241c0116a41206a2903003703002005200241c0116a41186a2903003703002009200241c0116a41106a290300370300200a200241c0116a41086a290300370300200220022903c0113703800f2006420037030020074280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a008200241f0116a200241800f6a200241a0086a10d9032008200241f0116a41286a2903003703002001200241f0116a41206a2903003703002005200241f0116a41186a2903003703002009200241f0116a41106a290300370300200a200241f0116a41086a290300370300200220022903f0113703800f20022903f00e210b200241d0126a20022d00f80e2201200010da03024002400240024020022903d012220ca741ff01714101460d00200241e00f6a41186a4200370300200241e00f6a41106a22064200370300200241e00f6a41086a22004200370300200242003703e00f41d1c4c700ad4280808080e0008410012205290000210c2000200541086a2900003703002002200c3703e00f200510354184eec700ad4280808080b0028410012205290000210c20024188136a41086a2207200541086a2900003703002002200c37038813200510352006200229038813220c370300200241c00f6a41086a2000290300370300200241c00f6a41106a200c370300200241c00f6a41186a2007290300370300200220022903e00f3703c00f2002200241c00f6a10e102200228020021002002290308210d02400240200141024b0d004280b0def7d32b210c20010e03010004010b4280c0a8ca9a3a210c0b41800c2105200b42c0b2cd3b7c220e200b540d01200d420020001b220d200e7c220e200d540d01200e200c560d014200210c20024181136a21000240024020010e03000105000b200b210c0c040b427f210c0c030b200c420888a721050b20022802900f21060240200241980f6a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241940f6a2802002200450d002000410c6c450d00200610350b200228029c0f21060240200241a40f6a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241a00f6a2802002200450d002000410c6c450d00200610350b41010d030c080b4200210c20024181136a21000b200241a0086a41206a22014200370300200241a0086a41186a22054280808080c000370300200220002800003602b80f2002200041036a2800003600bb0f200241cc086a20022800bb0f360000200241013a00c808200242043703b0082002427f3703a8082002200c3703a008200220022802b80f3600c908200241a0126a200241800f6a200241a0086a10d903200241800f6a41286a200241a0126a41286a290300370300200241800f6a41206a200241a0126a41206a290300370300200241800f6a41186a200241a0126a41186a290300370300200241800f6a41106a200241a0126a41106a290300370300200241800f6a41086a200241a0126a41086a290300370300200220022903a0123703800f2001420037030020054280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a008200241d0126a200241800f6a200241a0086a10d903200241bc106a200241d0126a41086a290300370200200220022903d0123702b41041000d01200241e4126a2802002105200241d0126a41186a2802002101200241d0126a41206a2802002106200241f4126a280200210720022802e012210820022802ec12210920022903f812210b0c060b200241800f6a41206a22034200370300200241800f6a41186a22064280808080c000370300200241013a00a80f200242043703900f427f210b2002427f3703880f200242003703800f200241a0086a41206a22074200370300200241a0086a41186a22054280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a00820024180106a200241800f6a200241a0086a10d903200241800f6a41286a220820024180106a41286a290300370300200320024180106a41206a290300370300200620024180106a41186a290300370300200241800f6a41106a220920024180106a41106a290300370300200241800f6a41086a220a20024180106a41086a29030037030020022002290380103703800f2007420037030020054280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a008200241b0106a200241800f6a200241a0086a10d9032008200241b0106a41286a2903003703002003200241b0106a41206a2903003703002006200241b0106a41186a2903003703002009200241b0106a41106a290300370300200a200241b0106a41086a290300370300200220022903b0103703800f20054200370300200241a0086a41106a2206420037030020014200370300200242003703a00841d1c4c700ad4280808080e0008410012203290000210c2001200341086a2900003703002002200c3703a0082003103541e7c4c700ad4280808080e0008410012203290000210c200241a0126a41086a2208200341086a2900003703002002200c3703a01220031035200620022903a012220c370300200241d0126a41086a2001290300370300200241d0126a41106a2201200c370300200241d0126a41186a22032008290300370300200220022903a0083703d012200241c8006a200241d0126a412010c001200228024c410020022802481bad210c024020022903c80b4201520d0020022903d00b220b4200510d04200c200241d80b6a290300220d200d200c541b220e200b7c200e200d7d200b827d210b0b2007420037030020054280808080c000370300200241013a00c808200242043703b008200242003703a00820024200200b200c7d220c200c200b561b3703a808200241e0106a200241800f6a200241a0086a10d903200241d0126a41286a200241e0106a41286a290300370300200241d0126a41206a200241e0106a41206a2903003703002003200241e0106a41186a2903003703002001200241e0106a41106a290300370300200241d0126a41086a200241e0106a41086a290300370300200220022903e0103703d01220022903f00e210b20022802e00b2101200241a0126a200241a80b6a108e02200241a0086a20022802a012220520022802a812108f02200241e8086a280200410020022903a0084201511b2103024020022802a412450d00200510350b024002400240200320014b0d00410c10332206450d0d410410332205450d0b20054104412010372205450d0d200520022903a80b370000200541186a200241a80b6a41186a290300370000200541106a200241a80b6a41106a290300370000200541086a200241a80b6a41086a2903003700002005412041c00010372205450d0d20052001360020200642c0808080c004370204200620053602000240024020032001490d0041002101410421050c010b410c10332205450d0e410410332203450d0c20034104412010372203450d0e200320022903a80b370000200341186a200241a80b6a41186a290300370000200341106a200241a80b6a41106a290300370000200341086a200241a80b6a41086a2903003700002003412041c00010372203450d0e20032001417f6a360020200542c0808080c00437020420052003360200410121010b200241800f6a41206a2203428180808010370300200241800f6a41186a22072001360200200241940f6a2001360200200220022800f0113602e00f2002200241f0116a41036a2800003600e30f200241ac0f6a20022800e30f360000200241013a00a80f2002200636029c0f200220053602900f2002427f3703880f2002200b3703800f200220022802e00f3600a90f20024190116a200241d0126a200241800f6a10d903200241800f6a41286a20024190116a41286a290300370300200320024190116a41206a290300370300200720024190116a41186a290300370300200241800f6a41106a20024190116a41106a290300370300200241800f6a41086a20024190116a41086a29030037030020022002290390113703800f4180122101024020022d00f80e22054102460d00200241d0126a2005200010da03024020022903d012220ca741ff01714101460d00200241e00f6a41186a4200370300200241e00f6a41106a22064200370300200241e00f6a41086a22014200370300200242003703e00f41d1c4c700ad4280808080e0008410012203290000210c2001200341086a2900003703002002200c3703e00f200310354184eec700ad4280808080b0028410012203290000210c20024188136a41086a2207200341086a2900003703002002200c37038813200310352006200229038813220c370300200241c00f6a41086a2001290300370300200241c00f6a41106a200c370300200241c00f6a41186a2007290300370300200220022903e00f3703c00f200241386a200241c00f6a10e1020240200b42c0b2cd3b7c220c200b540d00200229034042002002290338a71b220d200c7c220c200d5a0d040b20022002280081133602b80f200220024184136a2800003600bb0f41800c21010c040b200c420888a721010b20022002280081133602b80f200220024181136a41036a2800003600bb0f0c020b200220022800f0113602e00f2002200241f3116a2800003600e30f200241003a005b20024180063b0059200241013a005820022802e01221050240200241e8126a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241e4126a2802002200450d002000410c6c450d00200510350b20022802ec1221050240200241f4126a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b200241f0126a2802002200450d082000410c6c450d08200510350c080b20022002280081133602b80f200220024184136a2800003600bb0f41800c2101200c4280c0a8ca9a3a4280b0def7d32b20051b580d050b200241013a0058200220013b0059200220014110763a005b20022802900f21050240200241980f6a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241940f6a2802002200450d002000410c6c450d00200510350b200228029c0f21050240200241a40f6a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b200241a00f6a2802002200450d062000410c6c450d06200510350c060b200241013a0058200220053b0059200220054110763a005b0c050b200220022d00a3083a005b200220022f00a1083b0059200241013a00580c050b2002419c016a4104360200200241ec046a4102360200200242023702dc04200241f0b2c3003602d80420024104360294012002419cb4c30036029001200241003602a408200241b0b4cc003602a008200220024190016a3602e8042002200241a0086a36029801200241d8046a4180b3c300104c000b41809ccc004119419c9ccc00103f000b200241a0086a41206a4200370300200241a0086a41186a4280808080c000370300200241a0086a412c6a20022800bb0f360000200241013a00c808200242043703b0082002427f3703a8082002427f200b20051b3703a008200220022802b80f3600c908200241c0116a200241800f6a200241a0086a10d903200241a0126a41286a200241c0116a41286a290300370300200241a0126a41206a200241c0116a41206a290300370300200241a0126a41186a200241c0116a41186a290300370300200241a0126a41106a200241c0116a41106a290300370300200241a0126a41086a200241c0116a41086a290300370300200220022903c0113703a012200241286a2000200b20022d00f90e20022903e80b220d200241f00b6a290300220e10db03024002402002290328220b200241286a41086a290300220c84500d0041002100200241003a00b80f2002200c3703e80f2002200b3703e00f200241014111200d200e84501b3a009f132002200241a80b6a360288132002200241a80b6a3602c00f2002200241c00f6a3602b00820022002419f136a3602ac08200220024188136a3602a8082002200241b80f6a3602a4082002200241e00f6a3602a008200241800f6a200241a80b6a200241a0086a10dc030240024020022802800f4101470d004200210e20022903880f210d410121000c010b200241a80f6a290300210e200241a00f6a290300210d20022903880f4201520d00200241800f6a41106a290300210f20022802c00f2101200241d8086a200241800f6a41186a290300370300200241d0086a200f37030041002100200241a0086a41086a41003a0000200241a9086a2001290000370000200241b1086a200141086a290000370000200241b9086a200141106a290000370000200241c1086a200141186a290000370000200241033a00a00841b0b4cc004100200241a0086a10d4010b20000d01200241e00f6a41186a22064200370300200241e00f6a41106a22054200370300200241e00f6a41086a22014200370300200242003703e00f41b6fdc600ad4280808080800184220f10012203290000211020024188136a41086a2200200341086a2900003703002002201037038813200310352001200029030037030020022002290388133703e00f41e489c200ad4280808080d0018422101001220329000021112000200341086a29000037030020022011370388132003103520052002290388132211370300200241c00f6a41086a22072001290300370300200241c00f6a41106a22082011370300200241c00f6a41186a22092000290300370300200220022903e00f3703c00f200241106a200241c00f6a412010d701200241106a41106a29030021112002290318211220022802102103200642003703002005420037030020014200370300200242003703e00f200f10012206290000210f2000200641086a2900003703002002200f37038813200610352001200029030037030020022002290388133703e00f201010012206290000210f2000200641086a2900003703002002200f37038813200610352005200229038813220f370300200720012903003703002008200f37030020092000290300370300200220022903e00f3703c00f200242002011420020031b220f200e7d2012420020031b220e200d54ad7d2210200e200d7d220d200e562010200f562010200f511b22001b3703a80820024200200d20001b3703a008200241c00f6aad4280808080800484200241a0086aad428080808080028410020b200241d0126a41206a4200370300200241d0126a41186a4280808080c000370300200241d0126a412c6a20024184136a280000360000200241013a00f812200242043703e01220022002280081133600f9122002427f3703d8122002200b427f200c501b3703d012200241f0116a200241a0126a200241d0126a10d903200241d8006a41086a20022903f011370300200241d8006a41106a200241f0116a41086a290300370300200241d8006a41186a200241f0116a41106a290300370300200241d8006a41206a200241f0116a41186a290300370300200241d8006a41286a200241f0116a41206a29030037030020024188016a200241f0116a41286a290300370300200241003a00580c020b200241003a005b20024180023b0059200241013a005820022802b01221050240200241b8126a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241b4126a2802002200450d002000410c6c450d00200510350b20022802bc1221050240200241c4126a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b200241c0126a2802002200450d012000410c6c450d01200510350c010b20024188106a200241b0106a410c6a290200370300200220022902b4103703801002400240024020022802f80b41796a2200410c4b0d000240024020000e0d00020202020202020202020201000b0240200241800c6a2d00004118460d0041002100200241003a00830f200241003b00810f200241013a00800f0c030b024020034102490d0041002100200241003a00830f200241003b00810f200241013a00800f0c030b200241a0086a41286a200241d80d6a220041286a290300370300200241a0086a41206a2203200041206a290300370300200241a0086a41186a220a200041186a290300370300200241a0086a41106a200041106a290300370300200241a0086a41086a200041086a290300370300200220002903003703a00841808eec00210002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200241a0086a20022802d00d10f101411f71417f6a0e1d0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c00010b200241d4086a410f36020020034200370300200a4280808080c000370300200241bdb5c0003602d008200241013a00c808200242043703b0082002427f3703a8082002427f20022903d80d427f200241e00d6a290300501b220c42ffffffffffffffffff007c220d200d200c541b3703a008411710332200450d22200242173702d412200220003602d012410f200241d0126a10770240024020022802d412221320022802d81222146b410f490d002014410f6a210020022802d01221032013210a0c010b2014410f6a22002014490d24201341017422032000200320004b1b220a4100480d240240024020130d000240200a0d00410121030c020b200a103322030d010c270b20022802d01221032013200a460d0020032013200a10372203450d260b2002200a3602d412200220033602d0120b200320146a221441002900bdb540370000201441076a41002900c4b540370000200220003602d81220022802d00d21140240200a20006b41034b0d00200041046a22132000490d24200a41017422152013201520134b1b22134100480d2402400240200a0d00024020130d00410121030c020b201310332203450d270c010b200a2013460d002003200a201310372203450d260b200220133602d412200220033602d0120b200241c9086a210a200320006a2014360000200041046a210320022802d012211420022802d4122113024020022802c408220020022802c008470d00200241bc086a2000410110870120022802c40821000b20022802bc082000410c6c6a220020033602082000201336020420002014360200200241d8126a2200200241a0086a41186a290300370300200220022802c40841016a3602c408200241d0126a41106a2203200241a0086a41206a290300370300200241800f6a41106a4232370300200220022903b0083703d0122002200a2900003703f0112002200a41076a2900003700f711200220022903a0083703880f200241800f6a41186a20022903d012370300200241800f6a41206a2000290300370300200241a80f6a2003290300370300200241b00f6a41003a0000200241b40f6a20022800f311360000200241b10f6a20022802f011360000200241003a00800f0c1f0b41800e21000c1a0b41808e0421000c190b41808e0821000c180b41808e0c21000c170b41808e1021000c160b41808e1421000c150b41808e1821000c140b41808e1c21000c130b41808e2021000c120b41808e2421000c110b41808e2821000c100b41808e2c21000c0f0b41808e3021000c0e0b41808e3421000c0d0b41808e3821000c0c0b41808e3c21000c0b0b41808ec00021000c0a0b41808ec40021000c090b41808ec80021000c080b41808ecc0021000c070b41808ed00021000c060b41808ed40021000c050b41808ed80021000c040b41808edc0021000c030b41808ee00021000c020b41808ee40021000c010b41808ee80021000b200241013a00800f200220003b00810f200220004110763a00830f0c020b200241800f6a200241fc0b6a10dd0320022d00800f4101470d0220022f00810f20022d00830f4110747221000c010b200241003a00830f418102210020024181023b00810f200241013a00800f0b200241013a0058200220003b0059200220004110763a005b02402001450d002001410c6c21012008210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b02402005450d002005410c6c450d00200810350b02402007450d002007410c6c21012009210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b2006450d012006410c6c450d01200910350c010b200241a0126a41286a2200200241800f6a41306a290300370300200241a0126a41206a2203200241800f6a41286a290300370300200241a0126a41186a220a200241800f6a41206a2214290300370300200241a0126a41106a2213200241800f6a41186a2215290300370300200241a0126a41086a2216200241800f6a41106a290300370300200220022903880f3703a012200241800f6a41086a20024180106a41086a290300370300200241a40f6a20073602002014200636020020152001360200200241940f6a200536020020022002290380103703800f2002200b3703a80f2002200936029c0f200220083602900f200241a0086a41286a2000290300370300200241a0086a41206a2003290300370300200241a0086a41186a200a290300370300200241a0086a41106a2013290300370300200241a0086a41086a2016290300370300200220022903a0123703a008200241d0126a200241800f6a200241a0086a10d903200241d8006a41086a20022903d012370300200241d8006a41106a200241d0126a41086a290300370300200241d8006a41186a200241d0126a41106a290300370300200241d8006a41206a200241d0126a41186a290300370300200241d8006a41286a200241d0126a41206a290300370300200241d8006a41306a200241d0126a41286a290300370300200241003a00580b200410ba0220022d005821010b410110332200450d00200242013702ac0b200220003602a80b02400240200141ff01714101470d00200041013a0000200241013602b00b200241d8006a410172200241a80b6a10c90320022802b00b21000c010b200041003a0000200241013602b00b200241e0006a290300210b024020022802ac0b2201417f6a41074b0d00200141017422054109200541094b1b22054100480d03024020012005460d0020002001200510372200450d050b200220053602ac0b200220003602a80b0b2000200b370001200241093602b00b200241f0006a2802002101200241f8006a2802002200200241a80b6a107702402000450d0020012000410c6c6a2108034020012802002106200141086a2802002200200241a80b6a10770240024020022802ac0b220420022802b00b22056b2000490d0020022802a80b21030c010b200520006a22032005490d05200441017422072003200720034b1b22074100480d050240024020040d00024020070d00410121030c020b200710332203450d080c010b20022802a80b210320042007460d0020032004200710372203450d070b200220073602ac0b200220033602a80b0b200320056a20062000109d081a2002200520006a3602b00b2001410c6a22012008470d000b0b200241fc006a280200210120024184016a2802002200200241a80b6a10770240024020000d0020022802ac0b210620022802b00b21000c010b20012000410c6c6a2108034020012802002107200141086a2802002200200241a80b6a10770240024020022802ac0b220320022802b00b22056b2000490d0020022802a80b2104200321060c010b200520006a22042005490d05200341017422062004200620044b1b22064100480d050240024020030d00024020060d00410121040c020b200610332204450d080c010b20022802a80b210420032006460d0020042003200610372204450d070b200220063602ac0b200220043602a80b0b200420056a20072000109d081a2002200520006a22003602b00b2001410c6a22012008470d000b0b200241e8006a290300210b02400240200620006b4108490d0020022802a80b2105200621010c010b200041086a22012000490d03200641017422052001200520014b1b22014100480d030240024020060d00024020010d00410121050c020b200110332205450d060c010b20022802a80b210520062001460d0020052006200110372205450d050b200220013602ac0b200220053602a80b0b200520006a200b3700002002200041086a22003602b00b20024188016a2d000021030240024020012000460d00200021010c010b200141016a22002001490d03200141017422042000200420004b1b22004100480d030240024020010d0041002101024020000d00410121050c020b200010332205450d060c010b20012000460d0020052001200010372205450d050b200220003602ac0b200220053602a80b0b200520016a20033a00002002200141016a22003602b00b0b2000ad42208620023502a80b84210b024020022d00580d000240200241f8006a2802002201450d00200241f0006a28020021002001410c6c210103400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241f4006a2802002200450d002000410c6c450d00200228027010350b024020024184016a2802002201450d00200241fc006a28020021002001410c6c210103400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b20024180016a2802002200450d002000410c6c450d00200228027c10350b200241a0136a2400200b0f0b1045000b103e000b103c000b200241e4046a4104360200200241bc0b6a4102360200200242023702ac0b200241f0b2c3003602a80b200241043602dc042002419cb4c3003602d8042002410036029401200241b0b4cc00360290012002200241d8046a3602b80b200220024190016a3602e004200241a80b6a4180b3c300104c000be82307017f027e027f017e077f017e017f230041a0116b22022400420221030240024002400240024002400240024002400240200129036822044202520d00200241186a20014198016a41b002109d081a0c010b20024196036a200141246a41c200109d081a200241d8036a41086a220520014188016a290300370300200241d8036a41106a220620014190016a290300370300200220014180016a2903003703d803200141f8006a29030021032001290370210720024190046a41206a200141206a28020036020020024190046a41186a200141186a29020037030020024190046a41106a200141106a29020037030020024190046a41086a200141086a2902003703002002200129020037039004200241c80a6a20024190046a108b0220024190086a41086a2208200241d10a6a29000037030020024190086a41106a2209200241d90a6a29000037030020024190086a41186a220a200241c80a6a41196a290000370300200220022900c90a3703900820022d00c80a4101460d02200241f0036a41186a200a290300370300200241f0036a41106a2009290300370300200241f0036a41086a200829030037030020022002290390083703f003200241800d6a20014198016a41b002109d081a200241b00f6a41106a2006290300370300200241b00f6a41086a2005290300370300200220022903d8033703b00f4100210520024190116a410010b803200241e8106a200228029011220120022802981110d501200241c8106a41086a200241f4106a290200370300200241c8106a41106a200241fc106a290200370300200241dd106a2206200241e8106a41196a290000370000200220022902ec103703c8100240024020022d00e8104101460d00200241c0106a4200370300200241b8106a4200370300200241b0106a4200370300200242003703a8100c010b20022d00eb10210520022f00e9102108200241b3106a200241d0106a290300370000200241bb106a200241c8106a41106a290300370000200241c0106a2006290000370000200220022903c8103700ab102002200820054110747222053b01a810200220054110763a00aa100b0240200228029411450d00200110350b20024188106a41086a200241b3106a220629000037030020024188106a41106a200241bb106a220829000037030020024188106a41156a200241c0106a2209290000370000200220022900ab1037038810200241c8106a41156a220a4200370000200241c8106a41106a220b4200370300200241c8106a41086a220c4200370300200242003703c81041d1c4c700ad4280808080e00084100122012f0000210d200141026a2d0000210e2002200141086a2900003700ed10200220012900033703e81020011035200220022900ed103700cd10200220022903e8103703c81041e7c4c700ad4280808080e0008410012201290000210f200241e8106a41086a2210200141086a2900003703002002200f3703e81020011035200a2010290300220f3700002009200f370000200220022903e8103700d5102006200c2903003700002008200b2903003700002002200e3a00aa102002200d3b01a810200220022903c8103700ab10200241106a200241a8106a412010c00141002101024020044201520d0020074200510d052002280214410020022802101b2106417f21012006ad220f20032003200f541b220f200f20037d2007827d220f42ffffffff0f560d00200fa721010b200241e8106a200110b803200241086a20022802e810220620022802f01041b0b4cc0041004100108a0220022802082108024020022802ec10450d00200610350b41012106024002400240024020084101470d0020024190116a200110b803200241e8106a200228029011220620022802981110d501200241c8106a41086a2208200241f4106a290200370300200241c8106a41106a2209200241fc106a290200370300200241c8106a41156a220a20024181116a290000370000200220022902ec103703c81020022d00e8104101460d01200241a8106a41156a4200370000200241a8106a41106a4200370300200241a8106a41086a4200370300200242003703a810410021010c020b0c020b20022f00e91020022d00eb10411074722101200241a8106a41156a200a290000370000200241a8106a41106a2009290300370300200241a8106a41086a2008290300370300200220022903c8103703a8100b0240200228029411450d00200610350b200241c8106a41086a200241a8106a41086a290300370300200241c8106a41106a200241a8106a41106a290300370300200241c8106a41156a200241a8106a41156a290000370000200241e8106a41086a20024188106a41086a290300370300200241e8106a41106a20024188106a41106a290300370300200241e8106a41156a20024188106a41156a290000370000200220022903a8103703c81020022002290388103703e810410021060b200241e80f6a41156a2208200241e8106a41156a290000370000200241e80f6a41106a2209200241e8106a41106a290300370300200241e80f6a41086a220a200241e8106a41086a290300370300200241c80f6a41086a220b200241c8106a41086a290300370300200241c80f6a41106a220c200241c8106a41106a290300370300200241c80f6a41156a220d200241c8106a41156a290000370000200220022903e8103703e80f200220022903c8103703c80f20060d01200241d8076a41156a22062008290000370000200241d8076a41106a22082009290300370300200241d8076a41086a2209200a290300370300200241b8076a41086a220a200b290300370300200241b8076a41106a220b200c290300370300200241b8076a41156a220c200d290000370000200220022903e80f3703d807200220022903c80f3703b807200241f8076a41106a220d200241b00f6a41106a290300370300200241f8076a41086a220e200241b00f6a41086a290300370300200220022903b00f3703f807200241c80a6a41046a200241800d6a41b002109d081a20024190086a200241c80a6a41b402109d081a20024190046a20024190086a41046a41b002109d081a200241f6066a20054110763a0000200241f4066a20053b0100200241d0066a2003370300200241c8066a2007370300200241d8066a220520022903f807370300200241e0066a2210200e290300370300200241e8066a200d290300370300200241f7066a20022903d807370000200241ff066a200929030037000020024187076a20082903003700002002418c076a2006290000370000200220043703c006200241f5013602f00620024196076a20014110763a000020024194076a20013b010020024197076a20022903b8073700002002419f076a200a290300370000200241a7076a200b290300370000200241ac076a200c290000370000410410332201450d05200242043702cc0a200220013602c80a20024190046a200241c80a6a10af030240024020022903c0064201520d0020022903d00620022903c8062203420c882204420120044201561b8021040240024020022802cc0a220820022802d00a22016b4102490d0020022802c80a21060c010b200141026a22062001490d09200841017422092006200920064b1b22094100480d090240024020080d00024020090d00410121060c020b2009103322060d010c0d0b20022802c80a210620082009460d0020062008200910372206450d0c20022802d00a21010b200220093602cc0a200220063602c80a0b200620016a2004a741047420037aa7417f6a22064101200641014b1b2206410f2006410f491b723b0000200141026a21010c010b0240024020022802cc0a20022802d00a2201460d0020022802c80a21060c010b200141016a22062001490d08200141017422082006200820064b1b22084100480d080240024020010d0041002101024020080d00410121060c020b200810332206450d0c0c010b20022802c80a210620012008460d0020062001200810372206450d0b20022802d00a21010b200220083602cc0a200220063602c80a0b200620016a41003a0000200141016a21010b200220013602d00a2005200241c80a6a10e201200220103602900820024190086a200241c80a6a10cf0120022802f00621080240024020022802cc0a220620022802d00a22016b4104490d0020022802c80a21050c010b200141046a22052001490d07200641017422092005200920054b1b22094100480d070240024020060d00024020090d00410121050c020b200910332205450d0b0c010b20022802c80a210520062009460d0020052006200910372205450d0a20022802d00a21010b200220093602cc0a200220053602c80a0b200520016a20083600002002200141046a3602d00a412010332201450d052001200241f4066a290200370000200141186a2002418c076a290200370000200141106a20024184076a290200370000200141086a200241fc066a2902003700000240024020022802cc0a220820022802d00a22056b4120490d0020022802c80a21060c010b200541206a22062005490d07200841017422092006200920064b1b22094100480d070240024020080d00024020090d00410121060c020b200910332206450d0b0c010b20022802c80a210620082009460d0020062008200910372206450d0a20022802d00a21050b200220093602cc0a200220063602c80a0b200620056a22062001290000370000200641186a200141186a290000370000200641106a200141106a290000370000200641086a200141086a2900003700002002200541206a3602d00a20011035412010332201450d05200120024194076a290200370000200141186a200241ac076a290200370000200141106a200241a4076a290200370000200141086a2002419c076a2902003700000240024020022802cc0a220820022802d00a22056b4120490d0020022802c80a21060c010b200541206a22062005490d07200841017422092006200920064b1b22094100480d070240024020080d00024020090d00410121060c020b200910332206450d0b0c010b20022802c80a210620082009460d0020062008200910372206450d0a20022802d00a21050b200220093602cc0a200220063602c80a0b200620056a22062001290000370000200641186a200141186a290000370000200641106a200141106a290000370000200641086a200141086a2900003700002002200541206a3602d00a2001103520022802cc0a210620022802c80a21010240024020022802d00a22054180024b0d0020024196036a200241f0036a2001200510f90521050c010b2005ad4220862001ad84100922052900002103200541086a2900002104200541106a2900002107200241a8106a41186a200541186a290000370300200241a8106a41106a2007370300200241a8106a41086a2004370300200220033703a8102005103520024196036a200241f0036a200241a8106a412010f90521050b02402006450d00200110350b2005450d03200241f0026a41086a200241f0036a41086a290300370300200241f0026a41106a200241f0036a41106a290300370300200241f0026a41186a200241f0036a41186a290300370300200241c8026a41086a200241d0066a290300370300200241c8026a41106a200241d8066a290300370300200241c8026a41186a200241e0066a290300370300200241e8026a200241e8066a290300370300200220022903f0033703f0022002200241c8066a2903003703c80220022903c0062103200241186a20024190046a41b002109d081a0b200041086a20022903f002370300200041286a2003370300200041306a20022903c802370300200041206a200241f0026a41186a290300370300200041186a200241f0026a41106a290300370300200041106a200241f0026a41086a290300370300200041386a200241c8026a41086a290300370300200041c0006a200241c8026a41106a290300370300200041c8006a200241c8026a41186a290300370300200041d0006a200241c8026a41206a290300370300200041d8006a200241186a41b002109d081a200041003a00000c060b200241800d6a10ba02200041036a41003a0000200041800a3b0001200041013a00000c050b200041013b0001200041013a0000200041036a41003a000020014198016a10ba020c040b20004180083b0001200041013a0000200041036a41003a000020024190046a10ba020c030b41809ccc004119419c9ccc00103f000b1045000b103e000b200241a0116a24000f0b103c000b841f05017f017e037f027e017f230041d0016b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c00011302030405060708090a0b0c0d0e0f1011121313131415161713000b420021034100210402400240024002400240024002400240200141086a2802000e0b0001070203030405050506000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b2001410c6a35020042d00f7e21030b410121040c040b41012104428084afdf0021030c030b410121044280dac40921030c020b410121040c010b4101210442c0f0f50b21030b200041003a0009200020043a0008200020033703000c170b0240024002400240024002400240024020012d00040e06000102030405000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b200141086a280200210442c0c3930721030240200141106a280200220541b0026c2206450d00200421010340200241106a200110d803427f427f200320022903107c220720072003541b220342c0843d7c220720072003541b2103200141b0026a2101200641d07d6a22060d000b0b200541b0026c21014101210603402001450d06200141d07d6a2101200241106a200410d803200441b0026a210420022d00184101460d000c050b0b200241106a200141086a280200220110d80320022903102103200241106a200110d803427f200342c08db7017c220720072003541b210320022d001821060c040b200141106a3502002107200241106a200141206a280200220110d80320022903102103200241106a200110d803427f427f427f200342808ece1c7c220820082003541b220320074290a10f7e7c220720072003541b220342c0b2cd3b7c220720072003541b210320022d001821060c030b200141306a35020042c0a9077e42c0c09bd8007c21030c010b200141306a35020042a08d067e42c093b9d3007c21030b410021060b200041003a0009200020063a0008200020033703000c160b200041023b0108200042c0cbe8cb003703000c150b200041023b0108200042003703000c140b200041003b0108200042003703000c130b42c0b2cd3b21074280e89226210302400240024002400240200141086a2802000e050004010203000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b42c09dd81021030c020b4280e59af70021070c010b42808ece1c21030b200041003b01082000200720037c3703000c120b4280cab5ee012103410021040240024002400240024002400240024002400240200141086a2d00000e1900090901010202090902030303030603040909090905060707000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b428088debe0121030c060b4280afd0e50221030c050b42c096b10221030c040b428094ebdc0321030c030b410121040c030b420021030c010b4280d0dbc3f40221030b410021040b200041003a0009200020043a0008200020033703000c110b200041003b010820004280f1a795034280c7bdbf0220012802041b3703000c100b4280e497d0122103410021040240024002400240024002400240024002400240200141086a2d00000e1e000909020201090909020203030404040505060404060604060605050607000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b410121044280cab5ee0121030c070b428084afdf0021030c050b41012104420021030c050b4280c2d72f21030c030b4280cab5ee0121030c020b420021030c010b42c099f9ebc02b21030b410021040b200041003a0009200020043a0008200020033703000c0f0b4280c2d72f2103024002400240024020012d00040e06000303010202000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b4280e497d01221030c010b428084afdf0021030b200041013b0108200020033703000c0e0b4280c2d72f2103024002400240024020012d00040e06000303010202000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b4280e497d01221030c010b428084afdf0021030b200041013b0108200020033703000c0d0b4280c2d72f210341002104024002400240024002400240200141086a2802000e0700050102030404000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b42002103410021040c030b428094ebdc032103410021040c020b4280cab5ee012103410021040c010b410121044280a8d6b90721030b200041003a0009200020043a0008200020033703000c0c0b200041003b010820004280e1eb173703000c0b0b200041023b0108200042003703000c0a0b200041003b0108200042003703000c090b42c090c1a401210341002104024002400240024002400240024002400240200141086a2d00000e09000801020308040506000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b410121044280ae99b50121030c060b410121044280bcded70021030c050b200141346a35020042a01f7e42c0cbf1c5017c21030c030b200141346a35020042a01f7e4280c2d1ae017c21030c020b4280caacf40021030c010b42a0dcc4a20221030b410021040b200041003a0009200020043a0008200020033703000c080b024002400240024002400240200141086a2d00000e06000102030405000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b200041003b0108200042003703000c0b0b200241106a41186a4200370300200241106a41106a22054200370300200241106a41086a220442003703002002420037031041f1d8cb00ad42808080809001841001220629000021032004200641086a290000370300200220033703102006103541e2d8cb00ad4280808080f00184100122062900002103200241c0016a41086a2209200641086a290000370300200220033703c00120061035200520022903c0012203370300200241a0016a41086a2004290300370300200241a0016a41106a2003370300200241a0016a41186a2009290300370300200220022903103703a001200241106a200241a0016a10da02200242a0c21e200229031020022d0098014102461b4200200141146a3502004200108408200041003b01082000427f200229030020022903084200521b3703000c0a0b200041003b01082000200141d0006a2903003703000c090b200041003b01082000200141c8006a2903003703000c080b200041003b0108200042003703000c070b42002103410021040240024002400240024020012802040e0400010402000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b200241106a200141086a280200220110d80320022903102103200241106a200110d803200241106a21010c010b200241106a2001412c6a280200220110d80320022903102103200241106a200110d803200241106a21010b20034290ce007c210320012d000821040b200041003a0009200020043a0008200020033703000c060b200041003b01082000200141286a35020042b0e32d7e2001411c6a35020042809fc9007e7c4280f797f3017c3703000c050b108406000b42c0d4e2cc002103024002400240024002400240024002400240024002400240200141086a2d00000e0c000b0102030405060708090a000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b42808c84a40121030c090b200141146a35020042a0acb9317e42c0b5b6f7267c21030c080b42808ea9da2721030c070b42c0f587ba0121030c060b42c0bda3a90121030c050b42c0ceffc30021030c040b42e0facec40021030c030b4280b4f3c30021030c020b42c0a0e2b30121030c010b42c0febdaf2821030b200041003b0108200020033703000c030b4280e1eb172103024002400240024002400240024002400240200141086a2d00000e0d00080108010203040705060807000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b4280dac40921030c060b428087a70e21030c050b4280dac40921030c040b428087a70e21030c030b4280dac40921030c020b428087a70e21030c010b420021030b200041003b0108200020033703000c020b420021034100210402400240024002400240024020012d00040e0a00010502020202030305000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b200241106a200141286a280200220110d80320022903102103200241106a200110d80320034290ce007c210320022d001821040c030b4280c2d72f21030c010b428087a70e21030b410021040b200041003a0009200020043a0008200020033703000c010b4280e59af700210342808ece1c21070240024002400240200141086a2802000e0400030102000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b42c097e8b20121030c010b42c097e8b201210342c085eb3621070b200041003b01082000200320077c3703000b200241d0016a24000bc10304017f027e067f017e230041206b22032400200229030021042001290300210520022802102106200141106a200141186a2207280200200241186a2208280200220910870120012802102007280200220a410c6c6a20062009410c6c109d081a200841003602002007200a20096a2209360200200341086a200936020020032001290210370300200228021c21082001411c6a200141246a2207280200200241246a220a2802002209108701200128021c2007280200220b410c6c6a20082009410c6c109d081a200a41003602002007200b20096a2209360200200341106a41086a20093602002003200129021c370310427f200520047c220420042005541b2105200229030822042001290308220c200c2004561b21040240024020012d0028450d004101210120022d00280d010b410021010b20002005370300200020032903003702102000200329031037021c200020013a002820002004370308200041186a200341086a280200360200200041246a200341106a41086a2802003602000240200241146a2802002201450d002001410c6c450d00200610350b0240200241206a2802002201450d002001410c6c450d00200810350b200341206a24000b920303047f017e017f230041e0006b22032400200341306a41186a4200370300200341306a41106a22044200370300200341306a41086a220542003703002003420037033041d1c4c700ad4280808080e000841001220629000021072005200641086a290000370300200320073703302006103541b8eec700ad4280808080800284100122062900002107200341d0006a41086a2208200641086a2900003703002003200737035020061035200420032903502207370300200341106a41086a2005290300370300200341106a41106a2007370300200341106a41186a200829030037030020032003290330370310200341086a200341106a412010c0014100210502400240417f200328020c410020032802081b220620026a220220022006491b22064280808080f28ba80942808080c0f588fe06200141ff01711b22072007428094ebdc038022074280ec94a37c7e7c4280cab5ee01562007a76a4b0d00200041046a20063602000c010b200041800c3b0001200041036a41003a0000410121050b200020053a0000200341e0006a24000b8b0a04027f017e017f087e230041b0026b220624000240200341ff01710d00200641b8016a2001ad42004280c8afa025420010840820064180026a41186a420037030020064180026a41106a2207420037030020064180026a41086a22034200370300200642003703800241e3efcb00ad4280808080a002841001220129000021082003200141086a29000037030020062008370380022001103541f5efcb00ad4280808080900284100122012900002108200641a0026a41086a2209200141086a290000370300200620083703a00220011035200720062903a0022208370300200641e0016a41086a2003290300370300200641e0016a41106a2008370300200641e0016a41186a200929030037030020062006290380023703e001200641b8016a41086a29030020062903b801220820024280c0a8ca9a3a20024280c0a8ca9a3a541b7c2202200854ad7c2108200641c8016a200641e0016a10bc020240024020062802c8010d00410021034200210a4200210b0c010b20062903d001220a4200522201200641c8016a41106a290300220b420055200b501b2103200b427f550d00428080808080808080807f4200200b2001ad7c7d200a200b428080808080808080807f85845022011b210b42004200200a7d20011b210a0b200641f8006a2002200842808090bbbad6adf00d4200109808200641a8016a200a200b42808090bbbad6adf00d4200109808200641e8006a2006290378220c200641f8006a41086a290300220d428080f0c4c5a9d28f72427f10840820064198016a20062903a801220b200641a8016a41086a290300220e428080f0c4c5a9d28f72427f108408200642808090bbbad6adf00d370388022006290368210f2006200a2006290398017c220a37038002200641c8006a2002200f7c42ffffffffffffffff0f83420020064180026a200a42808090bbbad6adf00d564103746a29030022104200108408200641386a2006290348220a200641c8006a41086a290300220f42808090bbbad6adf00d4200109808200641286a20062903382211200641386a41086a290300428080f0c4c5a9d28f72427f108408200641d8006a200c200d20104200108408200641186a20084200200b4200108408200641086a200e42002002420010840820064188016a20024200200b4200108408427f427f427f2008427f427f20064188016a41086a290300220b200629031820062903087c7c220c2008420052200e42005271200629032042005272200629031042005272200c200b547222011b220b200641d8006a41086a2903002006290358220e2011427f200f42808090bbbad6adf00d541b200a20062903287c220c428080c89d9deb96f80656200f200641286a41086a2903007c200c200a54ad7c220a420052200a501bad7c7c220a200e54ad7c7c427f20062903880120011b220e200a7c220f200e542201ad7c220a2001200a200b54200a200b511b22011b220e7c2002427f200f20011b220b7c220f2002542201ad7c220a2001200a200854200a2008511b22011b42002008200e7d2002200b54ad7d220a2002200b7d220b200256200a200856200a2008511b22071b20031b220a427f200f20011b4200200b20071b20031b220242c0b2cd3b7c22082002542203ad7c220b2003200b200a54200820025a1b22031b220220057c427f200820031b220820047c22042008542203ad7c22082003200820025420082002511b22031b2105427f200420031b21040b2000200437030020002005370308200641b0026a24000b8e1307077f027e037f0a7e017f037e047f230041d0036b2203240020022802102104200228020c2105200228020821062002280204210720022802002102200341206a2001108e02200341a0016a2003280220220820032802282209108f0220032903a001210a4200210b200342003703a001200341e8016a280200210c20032d00ec01210d02400240200a420151220e0d00200341306a41306a4200370300200341306a41286a4200370300200341306a41206a4200370300200341306a41186a4200370300200341c0006a4200370300200341386a4200370300200342003703304200210f4200211042002111420021120c010b200341d8016a2903002113200341a0016a41306a2903002114200341a0016a41206a290300210f200341a0016a41186a290300210b200341e0016a290300211220032903b001211120032903a8012110200341306a41206a200341a0016a41286a290300370300200341306a41286a2014370300200341306a41306a2013370300200341c0006a200b3703002003200f37034820032010370330200320113703380b02400240024002402010200229030022157d22142010562011200241086a29030022167d2010201554ad7d221320115620132011511b450d00419089c200ad4280808080b00284211141838c0c21040c010b02402010200b7c2217428080e983b1de165441002011200f7c22182017200b54ad7c501b0d002014200b7c220b42ffffe883b1de16562013200f7c200b201454ad7c220b420052200b501b0d0020072d00004101460d0041f588c200ad4280808080900184211141838c1421040c010b2015201684500d0120052d00002105200341e8006a2006280200108e02200341a0026a200328026822062003280270108f0220032903a0024201512107200341d0026a290300210f200341c8026a2903002116200341e0026a290300210b200341d8026a29030021150240200328026c450d00200610350b200b420020071b210b2015420020071b21150240200541ff01714101460d00200f420020071b210f2016420020071b2116024020054101710d0020162115200f210b0c010b200f200b2016201556200f200b56200f200b511b22071b210b2016201520071b21150b2015201458200b201358200b2013511b0d0141a389c200ad4280808080d00284211141838c0421040b20114280807c83210b201142088842ff018321102011a7210e410121020c010b2003201437033020032013370338200241086a290300210f2002290300211520042802002104200341e8006a41186a200341c0006a220241086a290300220b370300200341e8006a41206a2207200241106a29030037030020034190016a2206200241186a29030037030020034198016a2219200241206a2903003703002003201337037020032014370368200320022903002216370378427f20172017201054220220182002ad7c221020115420102011511b22021b427f201020021b8450210502400240427f201420167c2211201120145422022013200b7c2002ad7c221120135420112013511b22021b2210428080e983b1de16544100427f201120021b2211501b0d00200341e8006a41106a29030021102019290300210b2006290300211720072903002116200329037021182003290368211a4201211b200329038001211c0c010b02400240201020118450450d004200211b0c010b4200211b200341a0026a41186a221d4200370300200341a0026a41106a22064200370300200341a0026a41086a22074200370300200342003703a00241b6fdc600ad4280808080800184220b100122192900002117200341c0036a41086a2202201941086a290000370300200320173703c0032019103520072002290300370300200320032903c0033703a00241e489c200ad4280808080d0018422171001221929000021162002201941086a290000370300200320163703c00320191035200620032903c0032216370300200341a0036a41086a221e2007290300370300200341a0036a41106a221f2016370300200341a0036a41186a22202002290300370300200320032903a0023703a003200341086a200341a0036a412010d701200341086a41106a29030021162003290310211820032802082119201d42003703002006420037030020074200370300200342003703a002200b1001221d290000210b2002201d41086a2900003703002003200b3703c003201d103520072002290300370300200320032903c0033703a00220171001221d290000210b2002201d41086a2900003703002003200b3703c003201d1035200620032903c003220b370300201e2007290300370300201f200b37030020202002290300370300200320032903a0023703a003200342002016420020191b220b20117d2018420020191b2217201054ad7d2216201720107d22182017562016200b562016200b511b22021b3703a80220034200201820021b3703a002200341a0036aad4280808080800484200341a0026aad42808080808002841002200341d8026a2011370300200341d0026a2010370300200741013a0000200341a9026a2004290000370000200341b1026a200441086a290000370000200341b9026a200441106a290000370000200341c1026a200441186a290000370000200341033a00a00241b0b4cc004100200341a0026a10d4010b0b2005ad2111200341c8016a2016370300200341d0016a2017370300200341b0016a2018370300200341d8016a200b370300200341b8016a20103703002003201c3703c001200320123703e0012003201a3703a80142012110410021022003200d4100200a42015122041b3a00ec012003200c410020041b3602e8012003201b4201512204ad3703a001024020040d002009ad4220862008ad841007420021104200210b0c010b200320093602a402200320083602a002200341a8016a200341a0026a10e7024200210b0b02402003280224450d00200810350b024002402002450d0020002004360204200041086a2010420886200ead42ff018384200b84370200410121020c010b024002400240200e41ff017122020d0020104200510d004103210e200341a0026a21020c010b2002450d0120104200520d014104210e200341a0016a21020b200241086a200e3a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b200041286a200f370300200041206a2015370300200041186a2013370300200041106a2014370300200041086a2011370300410021020b20002002360200200341d0036a24000b8f1804057f017e077f017e230041f0006b2202240020012802202103200241086a41186a4200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030841a3edcb00ad4280808080f000841001220629000021072005200641086a290000370300200220073703082006103541f393ca00ad4280808080a00184100122062900002107200241e0006a41086a2208200641086a2900003703002002200737036020061035200420022903602207370300200241c0006a41086a2005290300370300200241c0006a41106a2007370300200241c0006a41186a200829030037030020022002290308370340200241086a200241c0006a10fe0120022802082205410120051b2106024002400240024002400240024002402003200229020c420020051b2207422088a7490d00200742ffffff3f83500d01200610350c010b2003200620034105746a10b90421030240200742ffffff3f83500d00200610350b20030d010b200241086a41186a22054200370300200241086a41106a22064200370300200241086a41086a220342003703002002420037030841a3edcb00ad4280808080f000841001220829000021072003200841086a290000370300200220073703082008103541a5ebcb00ad4280808080c00184100122082900002107200241e0006a41086a2209200841086a290000370300200220073703602008103520042002290360370000200441086a22082009290300370000200241c0006a41086a220a2003290300370300200241c0006a41106a220b2006290300370300200241c0006a41186a220c2005290300370300200220022903083703402002200241c0006a412010c001200128021c2002280204410020022802001b220d470d01200542003703002006420037030020034200370300200242003703084188e8cb00ad42808080808001841001220e29000021072003200e41086a29000037030020022007370308200e1035418fd1cb00ad4280808080c000841001220e29000021072009200e41086a29000037030020022007370360200e10352004200229036037000020082009290300370000200a2003290300370300200b2006290300370300200c200529030037030020022002290308370340200241086a200241c0006a10d80220022802082204410120041b210c2001280224200229020c420020041b2207422088a72205470d0202402001280220220620054f0d00200c20064105746a220e0d040b20004180083b0001200041013a0000200041036a41003a00000c040b20004180063b0001200041013a0000200041036a41003a00000c040b20004180063b0001200041013a0000200041036a41003a00000c030b200041800e3b0001200041013a0000200041036a410a3a00000c010b2002410036021020024201370308200128020021030240410410332204450d002002410436020c2002200436020820042003360000200241043602102001280204210a2001410c6a2802002204200241086a1077024002400240200228020c2209200228021022036b2004490d00200228020821080c010b200320046a22082003490d012009410174220b2008200b20084b1b220b4100480d010240024020090d000240200b0d00410121080c020b200b103322080d010c040b200228020821082009200b460d0020082009200b10372208450d030b2002200b36020c200220083602080b200820036a200a2004109d081a2002200320046a360210200141106a2802002103200141186a2802002204200241086a10770240024020040d00200228020c210920022802102104200d210b0c010b20032004410c6c6a210b03402003280200210a200341086a2802002204200241086a107702400240200228020c2206200228021022056b2004490d0020022802082108200621090c010b200520046a22082005490d03200641017422092008200920084b1b22094100480d030240024020060d00024020090d00410121080c020b200910332208450d060c010b2002280208210820062009460d0020082006200910372208450d050b2002200936020c200220083602080b200820056a200a2004109d081a2002200520046a22043602102003410c6a2203200b470d000b2001280224210520012802202106200128021c210b0b02400240200920046b4104490d00200441046a2103200228020821082009210a0c010b200441046a22032004490d01200941017422082003200820034b1b220a4100480d010240024020090d000240200a0d00410121080c020b200a10332208450d040c010b200228020821082009200a460d0020082009200a10372208450d030b2002200a36020c200220083602080b200820046a200b360000200220033602100240200a20036b41034b0d00200341046a22042003490d01200a41017422092004200920044b1b22044100480d0102400240200a0d00024020040d00410121080c020b200410332208450d040c010b200a2004460d002008200a200410372208450d030b2002200436020c200220083602080b200820036a20063600002002200341046a220636021002400240200228020c220920066b4104490d0020022802082104200921080c010b200641046a22042006490d01200941017422082004200820044b1b22084100480d010240024020090d00024020080d00410121040c020b200810332204450d040c010b2002280208210420092008460d0020042009200810372204450d030b2002200836020c200220043602080b200420066a2005360000200141286a200341086aad4220862004ad84200e1015210302402008450d00200410350b0240024020034101470d00200241086a41086a427f3703002002413c6a4108360200200241286a4200370300200241206a4280808080c0003703002002427f37030820024188e8cb00360238200241013a003020024204370318411010332204450d0120024210370244200220043602404108200241c0006a10770240024020022802442208200228024822066b4108490d00200641086a210420022802402103200821050c010b200641086a22042006490d03200841017422032004200320044b1b22054100480d030240024020080d00024020050d00410121030c020b200510332203450d060c010b2002280240210320082005460d0020032008200510372203450d050b20022005360244200220033602400b200320066a42c9dabdf2c6ad9ab7e500370000200220043602480240200520046b41034b0d00200441046a22062004490d03200541017422082006200820064b1b22064100480d030240024020050d00024020060d00410121030c020b200610332203450d060c010b20052006460d0020032005200610372203450d050b20022006360244200220033602400b200320046a200d3600002002200441046a2203360248024002402002280244220920036b4120490d00200441246a210820022802402105200921060c010b200341206a22082003490d03200941017422042008200420084b1b22064100480d030240024020090d00024020060d00410121050c020b200610332205450d060c010b2002280240210520092006460d0020052009200610372205450d050b20022006360244200220053602400b200241316a2109200520036a2204200e290000370000200441186a200e41186a290000370000200441106a200e41106a290000370000200441086a200e41086a2900003700000240200228022c22042002280228470d00200241246a20044101108701200228022c21040b20022802242004410c6c6a220420083602082004200636020420042005360200200241c0006a41086a2204200241086a41186a2903003703002002200228022c41016a36022c200241c0006a41106a2203200241086a41206a29030037030020022002290318370340200220092900003703602002200941076a2900003700672002290308210f200041106a42e400370300200041086a200f370300200041306a41013a0000200041186a2002290340370300200041206a2004290300370300200041286a2003290300370300200041003a0000200041316a2002280260360000200041346a2002280063360000200742ffffff3f83500d05200c10350c050b20004180083b0001200041013a0000200041036a41003a00000c030b1045000b103e000b103c000b200742ffffff3f83500d00200c10350b200241f0006a24000bcf3909057f017e057f017e047f017e037f017e0d7f230022022103200241c0046b41607122022400024002402001450d00200220003602400c010b200241b0b4cc003602400b20022001360244200241c0026a200241c0006a10c403024002400240024002400240024020022802c402450d00200241c8006a200241c0026a41f000109d081a200241b8016a200241c8006a10df032002280248200241d8006a20024198016a200241b8016a410010e00341004100280290b54c2201410120011b360290b54c0240200141014b0d000240024020010e020001000b410041fca1c000360298b54c410041b0b4cc00360294b54c41004102360290b54c0c010b03404100280290b54c4101460d000b0b2002410020022802482201417f6a2200200020014b1b22043602c401100d4101470d01200241c0026a41186a22054200370300200241c0026a41106a22004200370300200241c0026a41086a22014200370300200242003703c0024188e8cb00ad42808080808001841001220629000021072001200641086a290000370300200220073703c002200610354194c4c400ad4280808080e00184100122082900002107200241f0016a41086a2206200841086a290000370300200220073703f00120081035200020022903f0012207370300200241e0036a41086a22092001290300370300200241e0036a41106a220a2007370300200241e0036a41186a220b2006290300370300200220022903c0023703e003200241386a200241e0036a412010c001410021080240200228023c410020022802381b220c20044d0d00200241e0036a2100200241c8016a21010c060b200542003703002000420037030020014200370300200242003703c00241a3edcb00ad4280808080f00084220710012208290000210d2001200841086a2900003703002002200d3703c0022008103541a5ebcb00ad4280808080c0018410012208290000210d2006200841086a2900003703002002200d3703f00120081035200020022903f001220d37030020092001290300370300200a200d370300200b2006290300370300200220022903c0023703e003200241306a200241e0036a412010c0012002280234210e2002280230210f200542003703002000420037030020014200370300200242003703c00220071001220829000021072001200841086a290000370300200220073703c0022008103541f393ca00ad4280808080a001841001220829000021072006200841086a290000370300200220073703f00120081035200020022903f001220737030020092001290300370300200a2007370300200b2006290300370300200220022903c0023703e003200241c8016a200241e0036a10fe010240024020022802c80122010d00410021100c010b20022902cc012207422088a72110200742ffffff3f83500d00200110350b200241c0026a41186a22084200370300200241c0026a41106a22054200370300200241c0026a41086a22014200370300200242003703c0024188e8cb00ad42808080808001841001220629000021072001200641086a290000370300200220073703c00220061035418fd1cb00ad4280808080c00084100122062900002107200241f0016a41086a2209200641086a290000370300200220073703f00120061035200020022903f001370000200041086a2009290300370000200241e0036a41086a2001290300370300200241e0036a41106a2005290300370300200241e0036a41186a2008290300370300200220022903c0023703e003200241c0026a200241e0036a10d80220022802c002211120022902c4022112200241c0026a41e9dabdf30610e10320022802c002210820022802c402210902400240024020022802c80222000d004100211341012114410021150c010b02400240024020004105742201410575220641ffffff3f712006470d0020014100480d0020010d01410121140c020b103e000b200110332214450d020b200820016a210a2000410574210520014105762113410021010340200820016a22002900002107200041086a290000210d200041106a2900002116201420016a220641186a200041186a290000370000200641106a2016370000200641086a200d370000200620073700002005200141206a2201470d000b200a20086b41606a41057641016a21150b0240200941ffffff3f71450d00200810350b20154115490d0402404101450d0020154104744160712217417f4c0d000240201710332218450d00200241003602f801200242043703f001201441606a2119201441a07f6a211a41042106410021014100211b2015211c0340201c210b4100211c4101210a0240200b417f6a2205450d00024002400240024002400240201420054105746a200b410574221d20146a41406a412010a0084100480d00200b417e6a2109201a201d6a21004100211c410021080340024020092008470d00200b210a0c080b200841016a2108200041206a2000412010a0082105200041606a21002005417f4a0d000b200841016a210a2008417f73200b6a21050c010b201a201d6a210002400340024020054101470d00410021050c020b2005417f6a2105200041206a2000412010a0082108200041606a210020084100480d000b0b200b2005490d01200b20154b0d02200b20056b220a4101762209450d002019201d6a2100201420054105746a21080340200241e0036a41186a221d200841186a221e290000370300200241e0036a41106a221f200841106a2220290000370300200241e0036a41086a220c200841086a221c290000370300200220082900003703e003200041086a22212900002107200041106a2222290000210d200041186a2223290000211620082000290000370000201e20163700002020200d370000201c20073700002023201d2903003700002022201f2903003700002021200c290300370000200020022903e003370000200041606a2100200841206a21082009417f6a22090d000b0b024020050d002005211c0c050b0240200a41094d0d002005211c0c050b200b20154b0d02200b20056b2109201420054105746a211d0340200b2005417f6a221c490d040240200b201c6b220a4102490d00201420054105746a22002014201c4105746a2205412010a008417f4a0d00200241c0026a41186a220c200541186a2208290000370300200241c0026a41106a2221200541106a221e290000370300200241c0026a41086a2222200541086a221f290000370300200220052900003703c00220052000290000370000201f200041086a290000370000201e200041106a2900003700002008200041186a290000370000410121200240200a4103490d00200541c0006a200241c0026a412010a008417f4a0d0041022108201d210002400340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a221e29000037000020092008460d01200041c0006a211f20082120201e2100200841016a2108201f200241c0026a412010a008417f4a0d020c000b0b200821200b200520204105746a220020022903c002370000200041186a200c290300370000200041106a2021290300370000200041086a20222903003700000b201c450d05201d41606a211d200941016a2109201c2105200a410a4f0d050c000b0b2005200b41eccfca001059000b200b201541eccfca001058000b200b2005417f6a221c490d00200b201541fccfca001058000b201c200b41fccfca001059000b0240201b20022802f401470d00200241f0016a201b410110900120022802f001210620022802f8012201211b0b2006201b4103746a2200200a3602042000201c3602002002200141016a22013602f8012001211b024020014102490d000240024003400240024002400240024020062001417f6a4103746a2200280200450d00200141037420066a220941746a2802002205200028020422084b0d010b20014103490d022000280204210820062001417d6a221f4103746a28020421000c010b4102211b200141024d0d0620062001417d6a221f4103746a2802042200200820056a4d0d004103211b200141034d0d06200941646a280200200020056a4b0d050b20002008490d010b2001417e6a211f0b02400240024002400240024002402001201f41016a22204d0d002001201f4d0d012006201f41037422216a2201280204222220012802006a22012006202041037422236a2200280200220c490d02200120154b0d032014200c4105746a221d2000280204221e41057422006a2108200141057421062001200c6b2209201e6b2201201e4f0d042018200820014105742200109d08220b20006a2105201e4101480d0520014101480d05201920066a21062008210103402006200141606a2208200541606a220920092008412010a008410048220a1b2200290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a29000037000020052009200a1b21050240201d20082001200a1b2201490d00200b21000c080b200641606a2106200b2100200b2005490d000c070b0b20202001418cd0ca001042000b201f2001419cd0ca001042000b200c200141acd0ca001059000b2001201541acd0ca001058000b2018201d2000109d08220b20006a21050240201e4101480d002009201e4c0d00201420066a210a200b2100201d2101034020012008200020082000412010a00841004822091b2206290000370000200141186a200641186a290000370000200141106a200641106a290000370000200141086a200641086a2900003700002000200041206a20091b2100200141206a2101200841206a200820091b2208200a4f0d03200520004b0d000c030b0b201d2101200b21000c010b20082101200b21000b20012000200520006b416071109d081a024020022802f8012201201f4d0d0020022802f001220620216a22002022201e6a3602042000200c360200200120204d0d02200620236a2200200041086a20012020417f736a410374109e081a20022001417f6a22013602f801200141014b0d010c030b0b201f200141bcd0ca001042000b20202001104e000b2001211b0b201c450d060c000b0b1045000b1044000b103c000b200241ec036a4104360200200241dc006a41023602002002420237024c200241f0b2c300360248200241043602e403200241b8b4c3003602e003200241003602f401200241b0b4cc003602f0012002200241e0036a3602582002200241f0016a3602e803200241c8006a4180b3c300104c000b410028028cb54c4105490d042002410d3602e4032002200241c4016a3602e0034100280298b54c21014100280294b54c21004100280290b54c210620024180036a418003360200200241f8026a42b580808010370300200241f4026a4184cac400360200200241ec026a4210370200200241e8026a41f4c9c400360200200241e0026a4201370300200241d0026a4202370300200241c0026a41086a4108360200200241dc026a200241e0036a360200200241dcc9c4003602cc02200241ecc9c4003602c402200241053602c002200041aca2c000200641024622061b200241c0026a200141c4a2c00020061b2802101102000c040b024020022802f40141ffffffff0171450d00200610350b2017450d01201810350c010b20154102490d0020142015417f6a22004105746a21054101210603400240024002400240201520002201417f6a2200490d00201520006b22094102490d03201420014105746a2201201420004105746a2208412010a008417f4a0d03200241c0026a41186a221e200841186a220a290000370300200241c0026a41106a221f200841106a220b290000370300200241c0026a41086a2220200841086a221d290000370300200220082900003703c00220082001290000370000201d200141086a290000370000200b200141106a290000370000200a200141186a2900003700004101210120094103490d02200841c0006a200241c0026a412010a008417f4a0d0241002109200521010340200141186a200141386a290000370000200141106a200141306a290000370000200141086a200141286a2900003700002001200141206a220b29000037000020062009220a460d02200a417f6a2109200141c0006a211d200b2101201d200241c0026a412010a008417f4a0d020c000b0b2000201541dccfca001059000b4102200a6b21010b200820014105746a220120022903c002370000200141186a201e290300370000200141106a201f290300370000200141086a20202903003700000b200541606a21052006417f6a210620000d000b0b200220103602e801200220043602e4012002200e4100200f1b22013602e001200220153602dc01200220133602d801200220143602d401200241003602d0012002201036028004200220043602fc03200220013602f803200220153602f403200220133602f003200220143602ec03200241003602e80320022011410120111b22083602e003200220083602c801200220082012420020111b2207422088a74105746a22013602e403200220013602cc012007a7210c200241e0036a2100200241c8016a21010b20024198026a41086a2206200141086a29020037030020024198026a41106a220a200141106a29020037030020024198026a41186a220b200141186a29020037030020024198026a41206a221d200141206a280200360200200241f0016a41086a221e200241c0026a41086a2205290200370300200241f0016a41106a221f200241c0026a41106a290200370300200241f0016a41186a2220200241c0026a41186a290200370300200241f0016a41206a221c200241c0026a41206a2902003703002002200129020037039802200220022902c0023703f001200241c8016a41206a2201200241e0036a41206a290200370300200241c8016a41186a2214200241e0036a41186a290200370300200241c8016a41106a2221200241e0036a41106a290200370300200241c8016a41086a2222200241e0036a41086a290200370300200220022902e0033703c8012005200c360200200220083602c402200241013602c002200241cc026a2208200229039802370200200241d4026a22052006290300370200200241dc026a2209200a290300370200200241e4026a220a200b290300370200200241ec026a201d280200360200200241003602f002200241f4026a20022903f001370200200241fc026a201e29030037020020024184036a201f2903003702002002418c036a202029030037020020024194036a201c2903003702002002410036029c03200241c0036a2001290300370300200241b8036a2014290300370300200241b0036a2021290300370300200241a8036a2022290300370300200241a0036a20022903c80137030020024190036a211d200241f8026a21012002419c036a2114200241f0026a212020024180036a211e20024188036a211f410021060340024002402006450d00200241286a202010e3030240200228022822064108460d00200228022c211c0c020b024020022802f0022206450d00024020022802f40241ffffff3f71450d00200610350b20022802880341ffffff3f71450d0020022802840310350b20012000290200370200200141086a200041086a290200370200200141106a200041106a290200370200200141186a200041186a290200370200200141206a200041206a2802003602002002200c3602f402200241003602f0020b2009290200210d200920022903f80337020020052902002116200520022903f00337020020082902002112200820022903e803370200200241d0036a41086a220b200a41086a280200360200200241003602e0032002200a2902003703d00320022902c4022107200220022903e0033702c40202402007a72206450d00201d20022903d00337020020012012370300201e2016370300201d41086a200b280200360200201f200d370300200220073703f0020c020b0240200228029c030d00410821060c010b200241206a201410e3032002280224211c200228022021060b02400240200641796a220b41014b0d000240200b0e020200020b024020022802c002450d0020022802c4022201450d00024020022802c80241ffffff3f71450d00200110350b200241dc026a28020041ffffff3f71450d00200241d8026a28020010350b024020022802f0022201450d00024020022802f40241ffffff3f71450d00200110350b20022802880341ffffff3f71450d0020022802840310350b200228029c032201450d030240200241a0036a28020041ffffff3f71450d00200110350b200241b4036a28020041ffffff3f71450d03200241b0036a28020010350c030b2002201c3602cc03200220063602c803410028028cb54c4104490d002002410e3602dc032002410d3602d4032002200241c8036a3602d8032002200241c4016a3602d0034100280298b54c21064100280294b54c210b4100280290b54c211c200241f7023602a004200242b5808080103703980420024184cac400360294042002421037028c04200241f4c9c400360288042002420237038004200242023703f003200241ccc9c4003602ec03200241083602e803200241ecc9c4003602e403200241043602e003200641c4a2c000201c410246221c1b28021021062002200241d0036a3602fc03200b41aca2c000201c1b200241e0036a20061102000b20022802f00221060c000b0b200241e0036a41186a4200370300200241e0036a41106a22064200370300200241e0036a41086a22014200370300200242003703e00341f7edcb00ad4280808080f000841001220029000021072001200041086a290000370300200220073703e0032000103541b6aac000ad4280808080900284100122002900002107200241f0016a41086a2208200041086a290000370300200220073703f00120001035200620022903f0012207370300200241c0026a41086a2001290300370300200241c0026a41106a2007370300200241c0026a41186a2008290300370300200220022903e0033703c002200241186a200241c0026a10f201024020022802184101470d00200228021c2004470d00200241f0016a410041aeb8c300ad4280808080800384100e10c20102400240024020022802f0012201450d00200241f8016a2802004104490d0041fd93ca002100200420012800002206490d01418294ca002100200641056a20044f0d010b2002200436029802200220043602c801200241e0036a41086a200241f0016a41086a280200360200200220022903f0013703e003200241c0026a200241e0036a10e50320022802c4022101410041aeb8c300ad428080808080038420023502c80242208620022802c0022206ad84200241c8016aad4280808080c00084100f210002402001450d00200610350b024020022802e0032201450d0020022802e403450d00200110350b20004101460d010c020b024020022802f401450d00200110350b20000d010b10e6030b20022802b8012108024020022802c0012201450d00200141246c21002008210103400240024020012d0000220641044b0d0002400240024020060e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b024020022802bc012201450d00200141246c450d00200810350b0240200241c8006a410c6a2802002200450d00200228024c2101200041246c210003400240024020012d0000220641044b0d0002400240024020060e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b0240200241d0006a2802002201450d00200141246c450d00200228024c10350b2003240042010b9704010d7f230041c0006b220224002002410036021820024204370310200241086a200141046a10bf0302400240024002400240200228020c41246c2203450d002002280208210141042104410021050340024020012d00004101470d00200141106a2802002206417f4c0d03200141036a2d00002107200141016a2f00002108200141086a2802002109200141046a2d0000210a0240024020060d004100210b4101210c0c010b20061033220c450d052006210b0b02400240200b2006490d00200b210d0c010b200b410174220d2006200d20064b1b220d4100480d060240200b0d00200d1033220c0d010c080b200b200d460d00200c200b200d1037220c450d070b20082007411074722107200c20092006109d08210c200241306a41086a2208200241206a41086a29020037030020022002290220370330200e41807e71200a72210e024020052002280214470d00200241106a20054101108d0120022802102104200228021821050b2004200541246c6a220b2006360210200b200d36020c200b200c360208200b200e360204200b20073b0001200b41013a0000200b41036a20074110763a0000200b2002290330370214200b411c6a20082903003702002002200541016a22053602180b200141246a21012003415c6a22030d000b0b20002002290310370200200041086a200241106a41086a280200360200200241c0006a24000f0b1044000b1045000b103e000b103c000b931107047f017e017f017e037f017e017f230041e0006b2205240020054102360208200541306a41186a22064200370300200541306a41106a22074200370300200541306a41086a220842003703002005420037033041d1c4c700ad4280808080e0008422091001220a290000210b200541d0006a41086a220c200a41086a2900003703002005200b370350200a10352008200c290300370300200520052903503703304188f2c700ad4280808080e001841001220a290000210b200c200a41086a2900003703002005200b370350200a103520072005290350220b370300200541106a41086a220a2008290300370300200541106a41106a220d200b370300200541106a41186a220e200c29030037030020052005290330370310200541203602342005200541106a360230200541086a200541306a10cd042005410036023041c4c3c700ad4280808080800284200541306aad4280808080c00084220f100220064200370300200742003703002008420037030020054200370330200910012210290000210b200c201041086a2900003703002005200b370350201010352008200c2903003703002005200529035037033041e7c4c700ad4280808080e0008410012210290000210b200c201041086a2900003703002005200b3703502010103520072005290350220b370300200a2008290300370300200d200b370300200e200c2903003703002005200529033037031020052000360230200541106aad4280808080800484220b200f100220064200370300200742003703002008420037030020054200370330200910012210290000210f200c201041086a2900003703002005200f370350201010352008200c290300370300200520052903503703304185c5c700ad4280808080e0008410012210290000210f200c201041086a2900003703002005200f3703502010103520072005290350220f370300200a2008290300370300200d200f370300200e200c29030037030020052005290330370310200541203602342005200541106a36023020032802002003280208200541306a109606200642003703002007420037030020084200370300200542003703302009100122062900002109200c200641086a29000037030020052009370350200610352008200c2903003703002005200529035037033041edc4c700ad4280808080a00184100122062900002109200c200641086a2900003703002005200937035020061035200720052903502209370300200a2008290300370300200d2009370300200e200c29030037030020052005290330370310024041201033220c450d00200c2001290000370000200c41186a200141186a290000370000200c41106a200141106a290000370000200c41086a200141086a290000370000200b200cad42808080808004841002200c1035200541306a2000417f6a10b803200535023821092005280230210841201033220c450d00200c2001290000370000200c41186a200141186a290000370000200c41106a200141106a290000370000200c41086a200141086a29000037000020094220862008ad84200cad42808080808004841002200c103502402005280234450d00200810350b200541306a41186a22064200370300200541306a41106a220a4200370300200541306a41086a220842003703002005420037033041d1c4c700ad4280808080e00084100122012900002109200541d0006a41086a220c200141086a29000037030020052009370350200110352008200c2903003703002005200529035037033041f7c4c700ad4280808080e00184100122012900002109200c200141086a290000370300200520093703502001103520072005290350370000200741086a200c290300370000200541106a41086a2008290300370300200541106a41106a200a290300370300200541106a41186a20062903003703002005200529033037031041201033220c450d00200c2002290000370000200c41186a200241186a290000370000200c41106a200241106a290000370000200c41086a200241086a290000370000200b200cad42808080808004841002200c103502402004450d00200541306a41186a22014200370300200541306a41106a22024200370300200541306a41086a220842003703002005420037033041d1c4c700ad4280808080e00084220910012206290000210f200541d0006a41086a220c200641086a2900003703002005200f370350200610352008200c2903003703002005200529035037033041cccfc700ad4280808080e0008410012206290000210f200c200641086a2900003703002005200f3703502006103520072005290350370000200741086a2206200c290300370000200541106a41086a220a2008290300370300200541106a41106a220d2002290300370300200541106a41186a220e200129030037030020052005290330370310200b100720014200370300200242003703002008420037030020054200370330200910012203290000210f200c200341086a2900003703002005200f370350200310352008200c290300370300200520052903503703304198f0c700ad4280808080a0018410012203290000210f200c200341086a2900003703002005200f37035020031035200720052903503700002006200c290300370000200a2008290300370300200d2002290300370300200e200129030037030020052005290330370310200b1007200142003703002002420037030020084200370300200542003703302009100122032900002109200c200341086a29000037030020052009370350200310352008200c2903003703002005200529035037033041d2cfc700ad4280808080b00184100122032900002109200c200341086a2900003703002005200937035020031035200720052903503700002006200c290300370000200a2008290300370300200d2002290300370300200e200129030037030020052005290330370310200b10080b200541e0006a24000f0b1045000bf30505017f017e0a7f017e027f230041e0006b220224002002200136020c0240024002402002410c6a10312203422088a722010d0020004100360208200042013702000c010b2002200136021420022003a722043602102002200241106a10c40120022802000d0102400240024020022802042205200228021422064105762201200120054b1b22014105742207417f4c0d0002400240024020010d00410121080c010b200710332208450d010b2001ad21032005450d024100210903402006210a200241003a0058200941016a2109410021010240024002400340200a2001460d01200241386a20016a200228021022072d00003a00002002200741016a3602102002200141016a22073a00582007210120074120470d000b200241186a41186a220b200241386a41186a290300370300200241186a41106a220c200241386a41106a290300370300200241186a41086a220d200241386a41086a290300370300200220022903383703182003422088220ea722012003a7460d012001210f0c020b200241003602140240200141ff0171450d00200241003a00580b200342ffffff3f83500d08200810350c080b0240024002400240200141016a22062001490d00200ea7220f4101742210200620062010491b220641ffffff3f712006470d00200641057422064100480d00024020010d0020060d02410121080c040b2006200f4105742201460d03024020010d0020060d02410121080c040b20082001200610372208450d020c030b103e000b2006103322080d010b103c000b2006410576ad21030b200a20076b21062008200f4105746a22012002290318370000200141186a200b290300370000200141106a200c290300370000200141086a200d290300370000200342ffffffff0f83200f41016aad42208684210320092005470d000b2002200a20076b3602140c030b1045000b1044000b2008450d020b2000200337020420002008360200200410350b200241e0006a24000f0b41b89acc00412e200241386a41a89acc0041d499cc001046000bb90201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad41012001105221000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000b20024180016a240020000f0b200441800141c88bc0001059000b200441800141c88bc0001059000bc023030b7f047e0c7f230041c0066b2202240002400240024020012802082203200128020c2204460d002001200341206a220536020820012802102106200241f8026a41186a200341186a290000370300200241f8026a41106a200341106a290000370300200241f8026a41086a200341086a290000370300200220032900003703f8022001280214210702400240024002402001411c6a280200220841014b0d004100210920080e020201020b2008210a4100210903402009200a410176220b20096a220c2007200c4105746a200241f8026a412010a00841004a1b2109200a200b6b220a41014b0d000b0b200720094105746a200241f8026a412010a0080d002006210c0c010b2001200641016a220c3602104108210920052004460d020240200841014d0d0003402001200541206a2203360208200241f8026a41186a200541186a290000370300200241f8026a41106a200541106a290000370300200241f8026a41086a200541086a290000370300200220052900003703f8022008210a4100210903402009200a410176220520096a220b2007200b4105746a200241f8026a412010a00841004a1b2109200a20056b220a41014b0d000b200720094105746a200241f8026a412010a008450d022001200c41016a220c3602102003210520032004460d030c000b0b0240024020080e020100010b03402001200541206a2209360208200241f8026a41186a200541186a290000370300200241f8026a41106a200541106a290000370300200241f8026a41086a200541086a290000370300200220052900003703f80202402007200241f8026a412010a0080d00410021090c030b2001200c41016a220c3602102009210520042009460d030c000b0b2001200436020820012006200420036b41406a4105766a41026a3602100c020b024002400240024002400240024002400240200820094d0d00200241186a200720094105746a220941186a290000220d370300200241106a200941106a290000220e370300200241086a200941086a290000220f3703002002200929000022103703002001200c41016a360210200141286a2802002111200141206a2802002109200141246a280200210a200241206a41186a200d370300200241206a41106a200e370300200241206a41086a200f370300200220103703202002200a36024c200220093602482002200c360244200241f8026a41186a4200370300200241f8026a41106a22054200370300200241f8026a41086a22094200370300200242003703f80241a3edcb00ad4280808080f000841001220a290000210d2009200a41086a2900003703002002200d3703f802200a103541f393ca00ad4280808080a001841001220a290000210d200241b8026a41086a220b200a41086a2900003703002002200d3703b802200a1035200520022903b802220d370300200241d0006a41086a2009290300370300200241d0006a41106a200d370300200241d0006a41186a200b290300370300200220022903f802370350200241f8026a200241d0006a10fe0120022802f8022209410120091b210a02400240200c20022902fc02420020091b220d422088a7490d000240200d42ffffff3f83500d00200a10350b200228024421010c010b200c200a200c4105746a10b90421050240200d42ffffff3f83500d00200a10350b410221092002280244210120050d0c0b200228024c210520022802482106411b10332209450d01200941176a41002800b7cd44360000200941106a41002900b0cd44370000200941086a41002900a8cd44370000200941002900a0cd4437000041041033220a450d01200a20013600002009411b413610372208450d082008200a28000036001b200a1035200241b8026a41002008ad4280808080f00384220d100e10c2010240024002400240024020022802b8022209450d00200241c0026a280200220a4104490d00200a417c714104460d0041000d0020092800002006470d002009280004220a41036a20054b0d010b410410332209450d0c2009200636000020094104410810372209450d0c20092005360004200241d0006a41086a200241b8026a41086a280200360200200220022903b802370350200241f8026a200241d0006a10e50320022802fc02210a4100200d20023502800342208620022802f8022207ad842009ad4280808080800184100f210b0240200a450d00200710350b02402002280250220a450d002002280254450d00200a10350b2009103541042109200b4101470d01200241f8026a10bb0420022802f8022201450d072002418c036a280200211220024188036a280200211320024184036a280200211420024180036a280200211520022802fc022116200228024c211720022802482118200228024421192002410036028003200242013703f802410410332209450d0c200241043602fc02200220093602f8022009201736000020024104360280032015200241f8026a107720022802fc02220520022802800322096b2015490d0220022802f802210a0c030b024020022802bc02450d00200910350b41012109200a21050b20081035200521010c0d0b200920156a220a2009490d082005410174220b200a200b200a4b1b220b4100480d080240024020050d000240200b0d004101210a0c020b200b1033220a0d010c0b0b20022802f802210a2005200b460d00200a2005200b1037220a450d0a0b2002200b3602fc022002200a3602f8020b200a20096a20012015109d081a2002200920156a360280032012200241f8026a10772012450d0220142012410c6c6a21032014210a0340200a2802002104200a41086a2802002209200241f8026a10770240024020022802fc02220b20022802800322056b2009490d0020022802f8022107200b210c0c010b200520096a22072005490d09200b410174220c2007200c20074b1b220c4100480d0902400240200b0d000240200c0d00410121070c020b200c10332207450d0c0c010b20022802f8022107200b200c460d002007200b200c10372207450d0b0b2002200c3602fc02200220073602f8020b200720056a20042009109d081a2002200520096a220936028003200a410c6a220a2003470d000c050b0b200920084190cdc4001042000b1045000b20022802fc02210c20022802800321090c010b41012109410521170c010b02400240200c20096b4104490d0020022802f802210a200c21050c010b200941046a220a2009490d03200c4101742205200a2005200a4b1b22054100480d0302400240200c0d00024020050d004101210a0c020b20051033220a450d060c010b20022802f802210a200c2005460d00200a200c20051037220a450d050b200220053602fc022002200a3602f8020b200a20096a20183600002002200941046a220b3602800302402005200b6b41034b0d00200b41046a2207200b490d032005410174220c2007200c20074b1b22074100480d030240024020050d00024020070d004101210a0c020b20071033220a450d060c010b20052007460d00200a200520071037220a450d050b200220073602fc022002200a3602f8020b200a200b6a20193600002002200941086a2205360280030240024020022802fc02220b20056b4104490d0020022802f802210a200b21070c010b200541046a220a2005490d03200b4101742207200a2007200a4b1b22074100480d0302400240200b0d00024020070d004101210a0c020b20071033220a450d060c010b20022802f802210a200b2007460d00200a200b20071037220a450d050b200220073602fc022002200a3602f8020b200a20056a2011360000200241f8026a41e9dabdf306200241206a200a2009410c6a10bc04410121090240024020022d00f8024101460d00410321050c010b200241f6026a20022d00fb023a0000200241b8026a41086a2002418c036a290200370300200241c8026a20024194036a290200370300200241d0026a2002419c036a290200370300200241d8026a200241a4036a290200370300200241e0026a200241ac036a290200370300200241e5026a200241b1036a290000370000200220022f00f9023b01f4022002200241f8026a410c6a2902003703b802200241f8026a41086a280200210b4100210920022802fc0221050b200241b4026a41026a220c200241f4026a41026a2d00003a0000200241f8016a41086a2204200241b8026a41086a290300370300200241f8016a41106a2203200241b8026a41106a290300370300200241f8016a41186a221a200241b8026a41186a290300370300200241f8016a41206a221b200241b8026a41206a290300370300200241f8016a41286a221c200241b8026a41286a290300370300200241f8016a41306a200241b8026a41306a290300370300200220022f01f4023b01b402200220022903b8023703f801024020090d00200241f4016a41026a200c2d00003a0000200241f8026a41086a2004290300370300200241f8026a41106a2003290300370300200241f8026a41186a201a290300370300200241f8026a41206a201b290300370300200241f8026a41286a201c290300370300200241f8026a412d6a200241f8016a412d6a290000370000200220022f01b4023b01f401200220022903f8013703f80202402007450d00200a10350b200220022f01f4013b01b8022002200241f6016a2d00003a00ba02410021090c020b02402007450d00200a10350b02402016450d00200110350b02402012450d002012410c6c210a2014210903400240200941046a280200450d00200928020010350b2009410c6a2109200a41746a220a0d000b0b4101210902402013450d002013410c6c450d00201410350b20052117200b21010b0b200241b8016a41086a220a200241f8026a41086a290300370300200241b8016a41106a2207200241f8026a41106a290300370300200241b8016a41186a220c200241f8026a41186a290300370300200241b8016a41206a2204200241f8026a41206a290300370300200241b8016a41286a2203200241f8026a41286a290300370300200241b8016a412d6a221a200241f8026a412d6a290000370000200220022d00ba023a00f201200220022f01b8023b01f001200220022903f8023703b80102400240024020090d00200241d0006a41186a2012360200200241d0006a41146a2013360200200241d0006a41106a2014360200200241d0006a410c6a2015360200200241d0006a41086a2016360200200241fa006a20022d00f2013a0000200241ff006a200b360000200241fb006a200536000020024183016a20022903b8013700002002418b016a200a29030037000020024193016a20072903003700002002419b016a200c290300370000200241a3016a2004290300370000200241ab016a2003290300370000200241b0016a201a29000037000020022011360274200220193602702002201836026c2002200136025420022017360250200220022f01f0013b01780240410028028cb54c4103490d00200241b8026a411c6a410f360200200241b8026a41146a410d360200200241b8026a410c6a410d3602002002410d3602bc022002200241d0006a3602d0022002200241c8006a3602c8022002200241cc006a3602c0022002200241c4006a3602b8024100280298b54c21094100280294b54c210a4100280290b54c2105200241b8036a418104360200200241b0036a42b580808010370300200241ac036a4184cac400360200200241a4036a4210370200200241a0036a41f4c9c40036020020024198036a420437030020024188036a4204370300200241f8026a41086a4108360200200241f8026a411c6a200241b8026a360200200241bccdc40036028403200241ecc9c4003602fc02200241033602f802200a41aca2c000200541024622051b200241f8026a200941c4a2c00020051b2802101102000b2002411336029004200242023703e00320024194046a200241d0006a41e800109d081a2002200241f8026a3602f801200241b8026a200241f8016a10b90320022802b80220022802bc0220022802c00210a004210a20024190046a10ba024107210941062117200a0d010c020b4107210920174107460d010b410410332209450d022009200636000020094104410810372209450d02200941003600044100200d2009ad4280808080800184101620091035201721090b200810350c040b103e000b103c000b410821090b0b2000200136020420002009360200200241c0066a24000bef0401017f230041306b220224000240024002400240024002400240024020002802000e0701020304050600010b2001411c6a2802002100200128021821012002412c6a4100360200200241b0b4cc003602282002420137021c200241e4cac40036021820012000200241186a104321010c060b2002200041046a36020c2002410c3602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420137021c200241eccac4003602182002200241106a36022820012000200241186a104321010c050b2002200041046a36020c2002410c3602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420237021c200241f4cac4003602182002200241106a36022820012000200241186a104321010c040b2002200028020436020c200241013602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420237021c20024184cbc4003602182002200241106a36022820012000200241186a104321010c030b2001411c6a2802002100200128021821012002412c6a4100360200200241b0b4cc003602282002420137021c20024194cbc40036021820012000200241186a104321010c020b2001411c6a2802002100200128021821012002412c6a4100360200200241b0b4cc003602282002420137021c2002419ccbc40036021820012000200241186a104321010c010b2001411c6a2802002100200128021821012002412c6a4100360200200241b0b4cc003602282002420137021c200241a4cbc40036021820012000200241186a104321010b200241306a240020010ba50301067f230041106b22022400024002400240200128020022030d00410121040c010b0240200141086a28020041056a2204417f4c0d0020040d0141002104410121050c020b1044000b2004103322050d001045000b200241003602082002200536020020022004360204024002400240024020030d00024020040d00410110332205450d0420024101360204200220053602000b200541003a0000410121040c010b024020040d00410110332205450d0320024101360204200220053602000b200541013a000020024101360208200141086a2802002204200210770240024020022802042206200228020822056b2004490d00200228020021010c010b200520046a22012005490d02200641017422072001200720014b1b22074100480d020240024020060d00024020070d00410121010c020b2007103322010d010c050b2002280200210120062007460d0020012006200710372201450d040b20022007360204200220013602000b200120056a20032004109d081a200520046a21040b20002002290300370200200041086a2004360200200241106a24000f0b103e000b103c000bde940111027f017e087f017e017f027e037f017e0a7f037e087f027e017f027e037f017e187f230041c0076b22002400200041003602e805200042083703e005200041003602f805200042013703f00541f7edcb00ad4280808080f00084100122012900002102200041f0066a41086a2203200141086a290000370300200020023703f0062001103541f393ca00ad4280808080a00184100122012900002102200041a0076a41086a2204200141086a290000370300200020023703a00720011035024002400240024002400240024002400240412010332201450d00200120002903f006370000200120002903a007370010200141086a2003290300370000200141186a22052004290300370000412010332203450d0020032001290000370000200341186a2005290000370000200341106a200141106a290000370000200341086a200141086a290000370000200041b0066a41026a220420004198026a41026a2d00003a0000200020002f0098023b01b006200041d0066a41106a42a0808080800437030041002106200041003a00e806200020013602dc06200042a080808080043702d406200020033602d006200041eb066a20042d00003a0000200020002f01b0063b00e90620004198026a200041d0066a10c701024002400240024002402000280298024101470d0020004198026a410472210741012108410821094100210a034020004180066a41206a200741206a28020036020020004180066a41186a2201200741186a290200220237030020004180066a41106a2205200741106a290200220b37030020004180066a41086a220c200741086a290200220d37030020002007290200220e37038006200041f0066a41186a220f2002370300200041f0066a41106a2210200b370300200041f0066a41086a2211200d3703002000200e3703f00620004198026a41186a2203200129030037030020004198026a41106a2204200529030037030020004198026a41086a2205200c290300370300200020002903800637039802200041f0066a10c801210241201033220c450d02200c20002903f006370000200c41186a200f290300370000200c41106a2010290300370000200c41086a2011290300370000200041a0076a41086a2005290300220b370300200041a0076a41106a2004290300220d370300200041a0076a41186a2003290300220e370300200020002903980222123703a0072003200e3703002004200d3703002005200b37030020002012370398020240200a20002802e405470d00200041e0056a200a4101108b0120002802e005210920002802e805210a0b2009200a41386c6a22012002370300200529030021022004290300210b2003290300210d200029039802210e2001412c6a4281808080103702002001200c3602282001200e370308200141206a200d370300200141186a200b370300200141106a20023703002000200a41016a220a3602e8052003200f2903003703002004201029030037030020052011290300370300200020002903f006370398020240200620002802f405470d00200041f0056a20064101108a0120002802f005210820002802f80521060b200820064105746a2201200029039802370000200141186a2003290300370000200141106a2004290300370000200141086a20052903003700002000200641016a22063602f80520004198026a200041d0066a10c7012000280298024101460d000b0b024020002802d406450d0020002802d00610350b024020002802e006450d0020002802dc0610350b41f7edcb00ad4280808080f00084100122012900002102200041f0066a41086a2203200141086a290000370300200020023703f0062001103541cca9c000ad4280808080a00184100122012900002102200041a0076a41086a2204200141086a290000370300200020023703a00720011035412010332201450d04200120002903f006370000200120002903a007370010200141086a2003290300370000200141186a22052004290300370000412010332203450d0420032001290000370000200341186a2005290000370000200341106a200141106a290000370000200341086a200141086a29000037000020004188026a41026a220520004198026a41026a2d00003a0000200020002f0098023b01880220004198026a41106a220442a08080808004370300200041003a00b002200020013602a402200042a0808080800437029c022000200336029802200041b3026a20052d00003a0000200020002f0188023b00b102200041e0056a20004198026a10c90120004198026a41186a220642003703002004420037030020004198026a41086a22014200370300200042003703980241f7edcb00ad4280808080f00084220210012205290000210b200041f0066a41086a2203200541086a2900003703002000200b3703f0062005103520012003290300370300200020002903f0063703980241c1edcb00ad4280808080e001841001220c290000210b200041a0076a41086a2205200c41086a2900003703002000200b3703a007200c1035200420002903a007220b37030020004180066a41086a2207200129030037030020004180066a41106a220a200b37030020004180066a41186a220f2005290300370300200020002903980237038006200041b0016a20004180066a412010c00120002802b401211320002802b0012114200642003703002004420037030020014200370300200042003703980220021001220c29000021022003200c41086a290000370300200020023703f006200c103520012003290300370300200020002903f0063703980241cfedcb00ad4280808080d002841001220329000021022005200341086a290000370300200020023703a00720031035200420002903a007220237030020072001290300370300200a2002370300200f2005290300370300200020002903980237038006200041a8016a20004180066a412010c00120002802ac01210520002802a801210c20002802f005211520002802f405211620002802e005211720002802e405211820002802f805210120002802e8052119200041003602d801200041003602d001201920016aad42e0007e2202422088a70d052002a72203417f4c0d054108210402402003450d00200310332204450d050b20054104200c1b221a41014b211b200041003602d806200020043602d0062000200341e0006e3602d406200041003602a807200042083703a007200041a0076a410020014105742205410575109b0120002802a807210902402001450d00200541606a410576211c20002802a007200941d8006c6a210c200041c8026a2103200041c0026a210841002104201521010340200041b0066a41186a2206200141186a2207290000370300200041b0066a41106a220a200141106a220f290000370300200041b0066a41086a2210200141086a2211290000370300200020012900003703b00620004180066a41186a200729000037030020004180066a41106a200f29000037030020004180066a41086a20112900003703002000200129000037038006200041d0016a20004180066a200410840320004198026a41086a420037030020004198026a41106a420037030020004198026a41186a420037030020004198026a41206a420037030020084200370300200341186a2006290300370300200341106a200a290300370300200341086a2010290300370300200320002903b0063703002000420037039802200c20004198026a41d000109d08220c41d0006a41003a0000200c41d8006a210c200141206a2101200441016a2104200541606a22050d000b2009201c6a41016a21090b201a4101201b1b2101200020093602a8070240201641ffffff3f71450d00201510350b200041f0066a41086a200041a0076a41086a2802002203360200200020002903a0073703f0060240024020032001490d00200041d0066a20002802d806201941386c220341386d10a40120002802d006210420002802d8062101200041ac026a200041f0066a3602002000201720036a3602a402200020173602a0022000201836029c0220002017360298022000200041d0016a3602a80220004180066a41086a20013602002000200041d8066a3602840620002004200141e0006c6a3602800620004198026a20004180066a109a042013410020141b2215ad42307e2202422088a70d072002a72203417f4c0d0720002802f80621010240024020030d00410821080c010b200310332208450d070b200041003602980720002008360290072000200341306e360294072015412c6c2203417f4c0d070240024020030d00410421130c010b200310332213450d070b41002117200041003602c001200020153602bc01200020133602b801410021142001201520012015491b221c0d010c040b024020002802f4062201450d00200141d8006c450d0020002802f00610350b024020002802d8062201450d00200141e0006c210320002802d00641346a21010340024020012802002204450d00200441c8006c450d002001417c6a28020010350b200141e0006a2101200341a07f6a22030d000b0b024020002802d4062201450d00200141e0006c450d0020002802d00610350b200041d0016a10b10102402019450d00201941386c21032017412c6a210103400240200128020041ffffff3f71450d002001417c6a28020010350b200141386a2101200341486a22030d000b0b410021082018450d02201841386c450d02201710350c040b20004198026a41186a211a20004198026a41106a210920004198026a41086a211b41002116034020002802f006210402402001450d00200141d8006c21032004210103400240200141d0006a2d00000d0002400240200141206a290300220b200141286a290300220d8450450d0042002102427f210b427f210d0c010b427f210220004198016a427f427f200b200d10980820004198016a41086a290300210d200029039801210b0b2001200b3703002001200d370308200141106a2002370300200141186a20023703000b200141d8006a2101200341a87f6a22030d000b0b0240024020002802d8062201450d0020002802d0062205200141e0006c6a210a0340024020052802382201450d00200141c8006c2104200528023041206a2101034020002802f806220c200128020022034d0d04024020002802f006200341d8006c6a22032d00500d0020032903202202200341286a290300220b84500d0020004198026a2005290310200541186a2903002005290300200541086a2903002002200b109b04200320032903002202427f2002427f20002903a002200028029802410146220c1b220d7c220b200b2002542206200341086a22072903002202427f2009290300200c1b220e7c2006ad7c220b200254200b2002511b220c1b200d200e845022061b37030020072002427f200b200c1b20061b3703000b200141c8006a2101200441b87f6a22040d000b0b200541e0006a2205200a470d000b20002802f00621040b201641016a211620002802f80641d8006c2101200441a87f6a210303402001450d05200141a87f6a2101200341d8006a2103200441d0006a2105200441d8006a220c210420052d00000d000b02402001450d00200341086a2903002102200341186a290300210b200341106a290300210d2003290300210e4100210403400240200c20046a220541d0006a2d00000d00200541086a29030022122002200e2002200d200b2005290300221d2012200541106a290300221e200541186a290300221f109c0441ff017141014622061b2102201d200e20061b210e201f200b20061b210b201e200d20061b210d2005200320061b21030b2001200441d8006a2204470d000b2003450d050b200341013a0050024020002802d8062201450d0020002802d0062204200141e0006c6a21182003410c6a2110200341306a21110340200441e0006a2119024020042802382205450d0020042802302101200541c8006c210503400240024020102001460d00200141246a2011412010a0080d010b200441186a220c290300210e200341086a220629030021022004290310210d2003290300210b20032903102112200141186a200341186a2207290300370300200141106a20123703002001200242002002200e7d200b200d54ad7d2212200b200d7d221d200b56201220025620122002511b220a1b200d200e8450220f1b3703082001200b4200201d200a1b200f1b370300200629030021022007290300210b2003290300210d20042003290310370320200441286a200b3703002004200d370310200c20023703000b200141c8006a2101200541b87f6a22050d000b0b2019210420192018470d000b0b201a200341c8006a2900003703002009200341c0006a290000370300201b200341386a2900003703002000200329003037039802200341286a29030021022003290320210b02402014200028029407470d0020004190076a20144101108801200028029007210820002802980721140b2008201441306c6a2201200029039802370300201b290300210d2009290300210e201a29030021122001200b370320200141286a2002370300200141186a2012370300200141106a200e370300200141086a200d3703002000201441016a2214360298072016201c4f0d0420002802f80621010c010b0b2003200c41f4c4c8001042000b103c000b0c010b024020002802d8062201450d0020002802d0062210200141e0006c6a2115201441306c21192000418c066a221841186a2116201841106a211a201841086a211b4100211703402018201029003c3700002016201041d4006a290000370000201a201041cc006a290000370000201b201041c4006a29000037000020004100360288062000420237038006024020102802382201450d002010280230220a200141c8006c6a2111201041106a2109410021074102210f0340200a220641246a2104200641c8006a210a410021052019210320082101024003402003450d01024020042001460d0020012004412010a008210c200541016a2105200341506a2103200141306a2101200c0d010b0b41ffff032103024020092006109d040d00410021032006290310201029032085200641186a290300201041286a29030085844200520d0020004198026a42ffff0342002006290300200641086a2903002009290300200941086a290300109b04427f20002903a00220002802980241014622011b2202a7417f200242808004544100427f20004198026a41106a29030020011b501b1b21030b20004198026a41186a22042006413c6a29000037030020004198026a41106a2205200641346a29000037030020004198026a41086a220c2006412c6a290000370300200020062900243703980202402007200028028406470d0020004180066a20074101109e01200028028006210f20002802880621070b200f200741226c6a2201200029039802370100200c29030021022005290300210b2004290300210d200120033b0120200141186a200d370100200141106a200b370100200141086a20023701002000200741016a2207360288060b200a2011470d000b0240024002402007450d002007417f200741808004491b210602400240200741226c22040d00410021030c010b200f41206a2101410021030340417f2003411074220320012f01004110746a220520052003491b4110762103200141226a21012004415e6a22040d000b0b200641ffff03712201450d012003417f73220a41ffff0371220320016e210c0240200120034b0d00200f41206a210141002103034020072003460d042001417f20012f01004110742204200c4110746a220520052004491b4110763b0100200141226a21012007200341016a2203470d000b0b0240200a200c20066c6b41ffff03712205450d00410021010340200f200120077041226c6a2203417f20032f01204110742203418080046a220420042003491b4110763b0120200141016a22012005490d000b0b20004198026a41286a220320004180066a41286a28020036020020004198026a41206a220420004180066a41206a29030037030020004198026a41186a220520004180066a41186a29030037030020004198026a41106a220c20004180066a41106a29030037030020004198026a41086a220620004180066a41086a2903003703002000200029038006370398020240201720002802bc01470d00200041b8016a2017410110980120002802b801211320002802c00121170b20132017412c6c6a2201200029039802370200200141286a2003280200360200200141206a2004290300370200200141186a2005290300370200200141106a200c290300370200200141086a20062903003702002000201741016a22173602c0010c030b2000280284062201450d02200141226c450d02200f10350c020b41f0b8c80041194194c5c800103f000b200320074184c5c8001042000b201041e0006a22102015470d000b20002802bc0121150b2000280294072105024020002802f4062201450d00200141d8006c450d0020002802f00610350b024020002802d8062201450d00200141e0006c210320002802d00641346a21010340024020012802002204450d00200441c8006c450d002001417c6a28020010350b200141e0006a2101200341a07f6a22030d000b0b024020002802d4062201450d00200141e0006c450d0020002802d00610350b200041d0016a10b1010b2008450d0820004198026a41186a220c420037030020004198026a41106a2220420037030020004198026a41086a22014200370300200042003703980241f7edcb00ad4280808080f00084220b1001220329000021022001200341086a2900003703002000200237039802200310354192aac000ad4280808080a00284100122042900002102200041a0076a41086a2203200441086a290000370300200020023703a00720041035202020002903a007220237030020004180066a41086a2207200129030037030020004180066a41106a220a200237030020004180066a41186a220f2003290300370300200020002903980237038006200041f0066a20004180066a10fe0120002802f0062206450d07200020002902f406220d3702ec01200020063602e801200c420037030020204200370300200142003703002000420037039802200b1001220429000021022001200441086a29000037030020002002370398022004103541a4aac000ad4280808080a002841001220429000021022003200441086a290000370300200020023703a00720041035202020002903a007370000202041086a200329030037000020072001290300370300200a2020290300370300200f200c290300370300200020002903980237038006200041f0066a20004180066a10fe0120002802f0062201450d06200020002902f4063702fc01200020013602f801200041003602a002200042013703980220004198026a4100201441306c220441306d108a0120002802a002212102402014450d0020002802980220214105746a2101200821030340200341086a2900002102200341106a290000210b2003290000210d200141186a200341186a290000370000200141106a200b370000200141086a20023700002001200d370000202141016a2121200141206a2101200341306a2103200441506a22040d000b0b200020213602a00202402005450d00200541306c450d00200810350b200028029c0221222000280298022123200041003602a807200042043703a007200041a0076a41002017412c6c2203412c6d10980120002802a007210420002802a80721012000201320036a3602a402200020133602a0022000201536029c0220002013360298022000200041f0066a3602a80220004180066a41086a20013602002000200041a0076a41086a36028406200020042001412c6c6a3602800620004198026a20004180066a109d0220004188026a41086a220120002802a807360200200020002903a0073703880220004188026a10ab0220004198026a2023202120002802880222242001280200220110cc01200041e0056a41086a20004198026a41086a220a28020036020020002000290398023703e00510142203280000210420031035024020044106702225450d00410021260340024020010d00410021010c020b20242001412c6c6a212742002128420021290240034002400240202441086a222a28020041306c22030d004200210b420021020c010b202428020041206a21014200210b420021020340427f2002200141086a2903007c200b20012903007c220d200b542204ad7c220b2004200b200254200b2002511b22041b2102427f200d20041b210b200141306a2101200341506a22030d000b0b2000200041e0056a3602a0074200212b4200212c02400240202a28020022014102490d002024280200210802400240200141306c22050d004200210e4200210d0c010b200841206a21014200210e200521034200210d0340427f200d200141086a2903007c200e20012903007c2212200e542204ad7c220e2004200e200d54200e200d511b22041b210d427f201220041b210e200141306a2101200341506a22030d000b0b2024410c6a2106200820056a21112008210f024002400240024002400240024003400240200f220c2011470d004100212d4108212e0c020b200c41306a210f200c41206a290300200c41286a29030084500d0020002802e0052207450d0020002802e40521100340200741086a210320072f010622094105742101410021040240024003402001450d01200c2003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21090b2010450d022010417f6a2110200720094102746a41c8056a28020021070c010b0b0b200720044105746a220141f0026a2903002112200141e8026a290300211d41101033222e450d0d202e201d370300202e2012370308200042818080801037029c022000202e360298024101211902400340200f220c2011460d01200c41306a210f200c41206a290300200c41286a29030084500d0020002802a00722012802002207450d00200128020421100340200741086a210320072f010622094105742101410021040240024003402001450d01200c2003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21090b2010450d022010417f6a2110200720094102746a41c8056a28020021070c010b0b200720044105746a220141f0026a2903002112200141e8026a290300211d02402019200028029c02470d0020004198026a20194101109a01200028029802212e0b202e20194104746a220120123703082001201d3703002000201941016a22193602a0020c000b0b200028029c02212d20190d010b200b212b2002212c0c010b20194104742203450d01202e2109024020194101460d00202e41106a2101200341706a2103202e21090340200920012009290300200129030056200941086a2903002212200141086a290300221d562012201d511b1b2109200141106a2101200341706a22030d000b2009450d020b20002802a00721180240024003402008220c2011460d01200c41306a210820182802002219450d002019210720182802042217210f0340200741086a210320072f01062210410574210141002104024003402001450d01200c2003412010a0082205450d05200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d01200f417f6a210f200720104102746a41c8056a28020021070c000b0b0b41acc6c800413241e0c6c8001064000b200720044105746a220141f0026a2903002112200141e8026a290300211d024020082011460d0003402008220c41306a2108201921072017210f02400340200741086a210320072f010622104105742101410021040240024003402001450d01200c2003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d02200f417f6a210f200720104102746a41c8056a28020021070c010b0b200720044105746a220141f0026a290300221e2012201d200141e8026a290300221f562012201e562012201e511b22011b2112201f201d20011b211d0b20082011470d000b0b427f4200200941086a290300221e20127d20092903002212201d54ad7d221f2012201d7d221d201256201f201e56201f201e511b22011b221242002002200d7d200b200e54ad7d220d200b200e7d220e200b56200d200256200d2002511b22031b7c4200201d20011b220d4200200e20031b7c220e200d542201ad7c220d2001200d201254200d2012511b22011b212c427f200e20011b212b0b202428020021010240202a280200220341306c2204450d00200120046a211c03402001210c024020002802a00722012802002207450d002001280204210f0340200741086a210320072f010622104105742101410021040240024003402001450d01200c2003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d02200f417f6a210f200720104102746a41c8056a28020021070c010b0b200720044105746a220141e8026a220342002003290300220d200c29032022127d220e200e200d56200141f0026a2203290300220e200c41286a2903007d200d201254ad7d220d200e56200d200e511b22041b37030020034200200d20041b37030020014180036a222f2802002207450d00200141f8026a28020021014100210341002104034002400240024020062001460d0020012006412010a008450d0020030d01410021030c020b200341016a21030c010b200420036b220520074f0d0620004198026a41286a220f2001200341506c6a220541286a221029030037030020004198026a41206a2211200541206a220829030037030020004198026a41186a2209200541186a221929030037030020004198026a41106a2217200541106a2218290300370300200a200541086a22152903003703002000200529030037039802200141086a2216290300210d200141106a221a290300210e200141186a221b2903002112200141206a2213290300211d200141286a2214290300211e200520012903003703002010201e3703002008201d370300201920123703002018200e3703002015200d3703002014200f29030037030020132011290300370300201b2009290300370300201a20172903003703002016200a29030037030020012000290398023703000b200141306a21012007200441016a2204470d000b2003450d00202f280200200720036b2201490d00202f20013602000b200c4200370320200c41286a4200370300200c41306a2201201c470d000b202a2802002103202428020021010b2000200041a0076a36028006200020004180066a360298022001200320004198026a410041202003676b109e04202a2802002215417f6a21182024280200220c201541306c22016a2109024020010d004200210d4200210e0c040b20002802a007221728020021194200210d410021084200210e200c2107034002402019450d00201728020421102019210f0340200f41086a2103200f2f010622114105742101410021040240024003402001450d0120072003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21110b2010450d022010417f6a2110200f20114102746a41c8056a280200210f0c010b0b200041e8006a200f20044105746a220141f0026a290300223042002008ad2212420010840820004188016a200141e8026a290300221e420020124200108408200041f8006a42004200201e42001084084200427f20002903880120002903702000290380018442005220004188016a41086a2903002212200029036820002903787c7c221d2012547222011b2212200d7d221f201f201256427f201d20011b221d200e7d2012200d54ad7d2212201d562012201d511b22011b200b564200201220011b221220025620122002511b0d04427f200e20307c200d201e7c2212200d542201ad7c220d2001200d200e54200d200e511b22011b210e427f201220011b210d0b200841016a2108200741306a22072009470d000c040b0b41ecc5c8004130419cc6c8001064000b2005200741f485cc001042000b41002008417f6a2201200120084b1b21180b201520184d0d01200041386a200c201841306c6a220141286a290300221e4200201841016a2211ad22124200108408200041d8006a2001290320221d420020124200108408200041c8006a42004200201d42001084084200427f2002200e7c200b200d7c220d200b542201ad7c220b2001200b200254200b2002511b22011b2202427f200041d8006a41086a290300220b200029033820002903487c7c220e2000290340200029035084420052200e200b547222031b7d427f200d20011b220b427f200029035820031b220e54ad7d220d200b200e7d220e200b56200d200256200d2002511b22011b211f4200200e20011b2130024003402009200c460d012011417f6a2111024020002802a00722012802002207450d002001280204210f0340200741086a210320072f010622104105742101410021040240024003402001450d01200c2003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d02200f417f6a210f200720104102746a41c8056a28020021070c010b0b200041286a2030201f20124200109808200c41286a220f4200427f200041286a41086a2903002202201e7c2000290328220b201d7c220d200b542201ad7c220b2001200b200254200b2002511b22051b2202200720044105746a220141f0026a22032903007d427f200d20051b220b200141e8026a2204290300220e54ad7d220d200b200e7d220e200b56200d200256200d2002511b22051b220b370300200c4200200e20051b22023703202004427f2004290300220d20027c22022002200d54220520032903002202200b7c2005ad7c220b200254200b2002511b22051b3703002003427f200b20051b370300200041b0066a41186a2207200641186a290000370300200041b0066a41106a2210200641106a290000370300200041b0066a41086a2208200641086a290000370300200020062900003703b006200141f8026a2105200f2903002102200c290320210b024020014180036a22032802002204200141fc026a280200470d00200520044101108801200328020021040b2005280200200441306c6a220120002903b0063703002001200b370320200141186a2007290300370300200141106a2010290300370300200141086a2008290300370300200141286a20023703002003200328020041016a3602000b200c41306a210c20110d000b0b202d41ffffffff0071450d00202e10350b202c2029202b202856202c202956202c2029511b22011b2129202b202820011b21282024412c6a22242027460d020c010b0b2018201541f0c6c8001042000b02400240202641016a222620254f0d0020282029844200520d010b200028029002210120002802880221240c020b200028028802212420002802900221010c000b0b200028028c02212a200041003602f805200042043703f005200041f0056a41002001412c6c2203412c6d109801202420036a211a20002802f805211502400240024020010d002024210f0c010b20002802f0052015412c6c6a2111200041d0066a41186a211b200041d0066a41106a2113200041d0066a41086a21142024210f0340200f2802082104200f2802042116200f2802002118201b200f41246a2902003703002013200f411c6a2902003703002014200f41146a2902003703002000200f29020c3703d006200f412c6a210f2018450d01200041f0066a41186a221c201b290300370300200041f0066a41106a222f2013290300370300200041f0066a41086a222e2014290300370300200020002903d0063703f0062018200441306c22036a21050240024020030d00420021024200210b0c010b201841206a2101420021024200210b0340200141086a290300200b7c2001290300220b20027c2202200b54ad7c210b200141306a2101200341506a22030d000b0b02400240024020052018460d00200441306c2103201821010340200141286a290300210d200141206a290300210e200041b0066a41186a220c200141186a290300370300200041b0066a41106a2206200141106a290300370300200041b0066a41086a2207200141086a290300370300200020012903003703b006200e200d2002200b109f04220441ffff03710d02200141306a2101200341506a22030d000b0b4200210d410021014102211002402016450d00201641306c450d00201810354200210d0b4200211d410021050c010b200041a0076a41086a22052007290300370300200041a0076a41106a220a2006290300370300200041a0076a41186a2208200c290300370300200020002903b006220d370380062000200d3703a007412210332210450d04201020002903a007370100201020043b0120201041186a2008290300370100201041106a200a290300370100201041086a200529030037010020004281808080103702940720002010360290072004ad210d0240024020034130470d00200d42ffff0383210d4200211d410121050c010b200341a07f6a2117200d42ffff0383210e4200211d41012105410021040340200120046a220341d8006a290300210d200341d0006a2903002112200c200341c8006a2903003703002006200341c0006a2903003703002007200341386a2903003703002000200341306a2903003703b006024002402012200d2002200b109f04220a41ffff03710d00200e210d20172004460d030c010b20004180066a41086a2007290300220d37030020004180066a41106a2006290300221237030020004180066a41186a200c290300221e370300200020002903b006221f3703800620004198026a41186a2208201e37030020004198026a41106a2209201237030020004198026a41086a2219200d3703002000201f37039802200e200aad42ffff03837c220d200e54ad210e02402005200028029407470d0020004190076a20054101109e0120002802900721100b201d200e7c211d2010200541226c6a22032000290398023701002019290300210e200929030021122008290300211e2003200a3b0120200341186a201e370100200341106a2012370100200341086a200e3701002000200541016a22053602980720172004460d020b200441306a2104200d210e0c000b0b02402016450d00201641306c450d00201810350b20002802940721010b0240024042ffff03200d7d220b42ffff03564200201d200d42ffff0356ad7c7d220242005220025022031b4101470d00200d4281807c7c2202200d56201d200d42ffff0354ad7d220b201d56200d42feff03561b0d012005450d01200541226c20106a417e6a2203410020032f010041107422032002a7417f200242808004544100200b501b1b4110746b2204200420034b1b4110763b01000c010b2005450d00200541226c20106a417e6a2204417f20042f01004110742204200ba7417f200b4280800454410020031b1b4110746a220320032004491b4110763b01000b20004198026a41186a2203201c29030037030020004198026a41106a2204202f29030037030020004198026a41086a220c202e290300370300200020002903f00637039802201120013602042011200536020820112010360200201120002903980237020c201141146a200c2903003702002011411c6a2004290300370200201141246a2003290300370200201541016a21152011412c6a2111200f201a470d000b200020153602f8050c010b200020153602f805200f201a460d000340200f2201412c6a210f0240200141046a2802002203450d00200341306c450d00200128020010350b201a200f470d000b0b0240202a450d00202a412c6c450d00202410350b2015ad422c7e2202422088a70d012002a72201417f4c0d0120002802f405211720002802f00521090240024020010d00410421030c010b200110332203450d010b200041003602a807200020033602a00720002001412c6e3602a407200041a0076a4100201510980120002802a80721010240024020150d0020002802a00721080c010b20092015412c6c6a211120002802a00722082001412c6c6a210620012015410274417c6a4102766a2119200041a4026a2107200041b0066a41186a210a200041b0066a41106a210f200041b0066a41086a21102009210c0340200a200c41246a290200370300200f200c411c6a2902003703002010200c41146a2902003703002000200c29020c3703b006200c2802082203ad42227e2202422088a70d032002a72204417f4c0d03200c28020021010240024020040d00410221050c010b200410332205450d030b200c412c6a210c200041003602880620002005360280062000200441226e3602840620004180066a41002003109e01200028028806210402402003450d00200341226c2105200028028006200441226c6a21030340200141086a2901002102200141106a290100210b200141186a290100210d2001290100210e200341206a200141206a2f01003b0100200341186a200d370100200341106a200b370100200341086a20023701002003200e370100200341226a2103200441016a2104200141226a21012005415e6a22050d000b0b20004198026a41086a220120043602002000200029038006220237039802200741186a200a290300370200200741106a200f290300370200200741086a2010290300370200200720002903b006370200200641286a20004198026a41286a280200360200200641206a20004198026a41206a290300370200200641186a20004198026a41186a290300370200200641106a20004198026a41106a290300370200200641086a2001290300370200200620023702002006412c6a2106200c2011470d000b201941016a21010b20002802a407210441002103200041003602a807200042043703a007200041a0076a41002001412c6c2205412c6d10980120002802a007210c20002802a80721012000200820056a3602a402200020083602a0022000200436029c0220002008360298022000200041f0066a3602a80220004180066a41086a20013602002000200041a0076a41086a360284062000200c2001412c6c6a3602800620004198026a20004180066a109d0220002802a407211120004198026a2023202120002802a007221920002802a807220810cc0120002802a0022110200028029c02210a024002400240200028029802220f450d000240200a450d00200a2101200f2103034020032802c80521032001417f6a22010d000b200f2101200a21040340200120012f01064102746a41c8056a28020021012004417f6a22040d000b20004198026a21040c020b20004198026a2104200f2103200f21010c010b2000410036029c0220004198026a21040c010b2000200136029c02200041a4026a20012f0106360200200041003602a00220004100360298020b20004180066a41086a200441086a290200220237030020002004290200220b37038006200041b0026a200237030042002112200042003703a0022000200336029c0220004100360298022000200b3703a802200020103602b8020240024020100d00427f211d4200210d4200211e4200211f427f210e0c010b20002010417f6a3602b80220004198026a410020031b220c2802002104200c28020821060240024002400240200c28020c2205200c28020422012f01064f0d00200121030c010b034020012802002203450d02200441016a210420012f0104210520032101200520032f01064f0d000b0b2005ad4220862006ad8421020c010b2006ad2102410021030b2002422088a7220641016a21052002a721070240024020040d00200321010c010b200320054102746a41c8056a2802002101410021052004417f6a2204450d00034020012802c80521012004417f6a22040d000b0b200c200536020c200c2007360208200c2001360204200c4100360200200320064105746a41e8026a2101427f211d427f210e4200211e4200211f420021124200210d0340200041086a200141086a290300220b4200200129030022024200108408200041186a2002420020024200108408427f200d427f200041186a41086a29030022302000290308222c202c7c7c222c200b2000290310222984202984420052202c2030547222011b7c2012427f200029031820011b7c22302012542201ad7c221220012012200d542012200d511b22011b210d427f203020011b2112200b200e2002201d54200b200e54200b200e511b22011b210e2002201d20011b211d200b201f7c2002201e7c221e200254ad7c211f20002802b8022201450d0120002001417f6a3602b80220004198026a4100200028029c021b220c2802002104200c2802082106024002400240200c28020c2205200c28020422012f01064f0d00200121030c010b0240034020012802002203450d01200441016a210420012f0104210520032101200520032f0106490d020c000b0b2006ad2102410021030c010b2005ad4220862006ad8421020b2002422088a7220641016a21052002a721070240024020040d00200321010c010b200320054102746a41c8056a2802002101410021052004417f6a2204450d00034020012802c80521012004417f6a22040d000b0b200c200536020c200c2007360208200c2001360204200c4100360200200320064105746a41e8026a21010c000b0b02400240200f0d0041002110200041ac026a41003602002000410036029c020c010b02400240200a0d00200f21010c010b200a2101200f2103034020032802c80521032001417f6a22010d000b200f21010340200120012f01064102746a41c8056a2802002101200a417f6a220a0d000b2003210f0b200041b4026a20012f0106360200200041b0026a4100360200200041ac026a2001360200200041003602a802200042003703a0022000200f36029c0220004100360298020b200020103602b80220004198026a109e0202402008450d002008412c6c21032019210103400240200141046a2802002204450d00200441306c450d00200128020010350b2001412c6a2101200341546a22030d000b0b02402011450d002011412c6c450d00201910350b20002015360288062000201736028406200020093602800620004198026a20004180066a200041f8016a200041e8016a10fb0120002d0098024101460d03202120216a22012021490d012001417f4c0d01200041d8036a2802002131200041d4036a2802002107200041d0036a2802002127200041cc036a2802002132200041c8036a280200211b200041c4036a280200212f200041c0036a2802002133200041bc036a280200210a200041b8036a280200212d200041b4036a2802002134200041b0036a280200210f200041ac036a2802002126200041a8036a2802002135200041a4036a2802002110200041a0036a28020021252000419c036a280200213620004198036a280200211120004194036a280200213720004190036a28020021382000418c036a280200210820004188036a280200213920004184036a280200213a20004180036a2802002109200041fc026a280200213b200041f8026a280200213c200041f4026a2802002119200041f0026a280200213d200041ec026a280200213e200041e8026a2802002113200041e4026a280200212e200041e0026a280200213f200041dc026a2802002117200041d8026a2802002140200041d4026a2802002141200041d0026a2802002118200041cc026a2802002142200041c8026a2802002143200041c4026a2802002115200041c0026a2802002144200041bc026a2802002145200041b8026a2802002114200041b4026a2802002124200041b0026a2802002146200041ac026a2802002116200041a8026a2802002147200041a4026a2802002148200041a0026a280200211c200028029c02212a0240024020010d00410221060c010b200110332206450d010b4100210c2000410036028806200020063602800620002001410176360284062021450d02202320214105746a212120002802f001221a41057441606a41057641016a2104202321050340200541086a2900002102200541106a290000210b2005290000213020004198026a41186a200541186a29000037030020004198026a41106a200b37030020004198026a41086a20023703002000203037039802201a450d05200541206a21054100210320002802e80121010240034020004198026a2001460d01200120004198026a412010a008450d01200141206a21012004200341016a2203470d000c070b0b200341ffff034b0d050240200c200028028406470d0020004180066a200c4101108e012000280280062106200028028806210c0b2006200c4101746a20033b01002000200c41016a220c3602880620052021470d000c030b0b1045000b1044000b0240202241ffffff3f71450d00202310350b200041de016a20004188066a28020036010020002000290380063701d6010240024020002802e00522050d004100210c200041ac026a41003602002000410036029c020c010b20002802e805210c0240024020002802e40522030d00200521010c010b2003210120052104034020042802c80521042001417f6a22010d000b200521010340200120012f01064102746a41c8056a28020021012003417f6a22030d000b200421050b200041b4026a20012f0106360200200041b0026a4100360200200041ac026a2001360200200041003602a802200042003703a0022000200536029c0220004100360298020b2000200c3602b80220004198026a109e02024020002802fc0141ffffff3f71450d0020002802f80110350b024020002802ec0141ffffff3f71450d0020002802e80110350b200041b8016a41106a200041d0016a41106a2f01003b0100200041b8016a41086a200041d0016a41086a290100370300200020002901d0013703b801200041f0066a41086a2204200041c6016a280100360200200020002901be013703f00620004198026a41186a2205420037030020004198026a41106a220c420037030020004198026a41086a22014200370300200042003703980241f7edcb00ad4280808080f000841001220329000021022001200341086a29000037030020002002370398022003103541e4edcb00ad4280808080a00184100122032900002102200041a0076a41086a2206200341086a290000370300200020023703a00720031035202020002903a007370000202041086a200629030037000020004180066a41086a2203200129030037030020004180066a41106a2201200c29030037030020004180066a41186a220c2005290300370300200020002903980237038006200020004180066a412010c0012000280204210520002802002106200041a3026a2004280200360000200020002903f00637009b0220002000290098023703a007200020004198026a41076a2900003700a707200041b8056a200d370300200041b0056a2012370300200041a8056a201f370300200041a0056a201e37030020004198056a200e37030020004190056a201d370300200041b8036a41183a0000200041c0036a20002900a70737000020004188056a2005410020061b36020020004184056a203136020020004180056a2007360200200041fc046a2027360200200041f8046a2032360200200041f4046a201b360200200041f0046a202f360200200041ec046a2033360200200041e8046a200a360200200041e4046a202d360200200041e0046a2034360200200041dc046a200f360200200041d8046a2026360200200041d4046a2035360200200041d0046a2010360200200041cc046a2025360200200041c8046a2036360200200041c4046a2011360200200041c0046a2037360200200041bc046a2038360200200041b8046a2008360200200041b4046a2039360200200041b0046a203a360200200041ac046a2009360200200041a8046a203b360200200041a4046a203c360200200041a0046a20193602002000419c046a203d36020020004198046a203e36020020004194046a201336020020004190046a202e3602002000418c046a203f36020020004188046a201736020020004184046a204036020020004180046a2041360200200041fc036a2018360200200041f8036a2042360200200041f4036a2043360200200041f0036a2015360200200041ec036a2044360200200041e8036a2045360200200041e4036a2014360200200041e0036a2024360200200041dc036a2046360200200041d8036a2016360200200041d4036a2047360200200041d0036a2048360200200041cc036a201c360200200041c8036a202a360200200041073602b0032000420237038003200020002903a0073700b903200041d8056a200c290300370300200041d0056a2001290300370300200041c8056a2003290300370300200041c0056a200029038006370300200020004198026a3602d00620004180066a200041d0066a10b90320002802800620002802840620002802880610a0041a200041b0036a10ba020c050b0240024020002802e00522050d004100210c200041ac026a41003602002000410036029c020c010b20002802e805210c0240024020002802e40522030d00200521010c010b2003210120052104034020042802c80521042001417f6a22010d000b200521010340200120012f01064102746a41c8056a28020021012003417f6a22030d000b200421050b200041b4026a20012f0106360200200041b0026a4100360200200041ac026a2001360200200041003602a802200042003703a0022000200536029c0220004100360298020b2000200c3602b80220004198026a109e02202241ffffff3f71450d01202310350c010b0240202241ffffff3f71450d00202310350b024020002802840641808080807872418080808078460d00200610350b0240201c41ffffffff0171450d00202a10350b02402016450d002016410c6c450d00204710350b0240201441ffffffff0071450d00202410350b02402015450d00201541146c450d00204410350b02402018450d00201841186c450d00204210350b02402017450d002017411c6c450d00204010350b0240201341ffffff3f71450d00202e10350b02402019450d00201941246c450d00203d10350b02402009450d00200941286c450d00203b10350b02402008450d002008412c6c450d00203910350b02402011450d00201141306c450d00203710350b02402010450d00201041346c450d00202510350b0240200f450d00200f41386c450d00202610350b0240200a450d00200a413c6c450d00202d10350b0240201b41ffffff1f71450d00202f10350b02402007450d00200741c4006c450d00202710350b0240024020002802e00522050d004100210c200041ac026a41003602002000410036029c020c010b20002802e805210c0240024020002802e40522030d00200521010c010b2003210120052104034020042802c80521042001417f6a22010d000b200521010340200120012f01064102746a41c8056a28020021012003417f6a22030d000b200421050b200041b4026a20012f0106360200200041b0026a4100360200200041ac026a2001360200200041003602a802200042003703a0022000200536029c0220004100360298020b2000200c3602b80220004198026a109e020b024020002802fc0141ffffff3f71450d0020002802f80110350b20002802ec0141ffffff3f71450d0220002802e80110350c020b200d42ffffff3f83500d00200610350b02402005450d00200541306c450d00200810350b02402017450d002017412c6c21032013210103400240200141046a2802002204450d00200441226c450d00200128020010350b2001412c6a2101200341546a22030d000b0b2015450d002015412c6c450d00201310350b200041c0076a24000ba50a07027f017e047f017e017f047e027f230041e0006b220224002002411436020c2002419793ca00360208200241106a419793ca00ad4280808080c00284100510c201024002400240024002400240200228021022030d0042002104410821050c010b200228021421062002200241186a2802002207360224200220033602200240024002402007450d0020022007417f6a3602242002200341016a36022020032d00002107200241c8006a200241206a10e80320022802482208450d00200229024c2109200741ff01714101460d012009a72207450d00200741286c450d00200810350b20024100360230200242013703282002410936023c2002200241086a3602382002200241286a36024441012107200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b4102210a0c010b4101210a410021070b02402006450d00200310350b4108200820071b21054200200920071b210420070d00200a4101460d0020052802082203ad42287e2209422088a70d012009a72207417f4c0d01200528020021060240024020070d00410821050c010b200710332205450d030b02400240024002400240200741286e220820034f0d002008410174220a2003200a20034b1bad42287e2209422088a70d082009a7220a4100480d08200741274d0d01200841286c2207200a460d022007450d0120052007200a10372205450d090c020b2008ad210b20030d02420021090c030b200a10332205450d070b200a41286ead210b0b200341286c210a42002109410021080340200620086a22032903002104200341086a290300210c200341106a290300210d200341186a290300210e200520086a220741206a200341206a290300370300200741186a200e370300200741106a200d370300200741086a200c3703002007200437030020094280808080107c2109200a200841286a2208470d000b0b200b20098421040b2004422088a7220341286c4104722207417f4c0d00200710332208450d01200241003602502002200736024c200220083602482003200241c8006a10772002280250210702402003450d002005200341286c6a210f200228024c210620052103034002400240200620076b4120490d00200741206a2108200228024821102006210a0c010b200741206a22082007490d052006410174220a2008200a20084b1b220a4100480d050240024020060d000240200a0d00410121100c020b200a10332210450d080c010b200228024821102006200a460d0020102006200a10372210450d070b2002200a36024c200220103602480b201020076a22072003290000370000200741186a200341186a290000370000200741106a200341106a290000370000200741086a200341086a29000037000020022008360250200341206a290300210902400240200a20086b4108490d00200841086a2107200a21060c010b200841086a22072008490d05200a41017422062007200620074b1b22064100480d0502400240200a0d00024020060d00410121100c020b200610332210450d080c010b200a2006460d002010200a200610372210450d070b2002200636024c200220103602480b201020086a200937000020022007360250200f200341286a2203470d000b0b2007ad422086200235024884210902402004a72203450d00200341286c450d00200510350b200241e0006a240020090f0b1044000b1045000b103e000b103c000bbb0504037f017e087f037e23004180016b220224002002200110c40102400240024002402002280200450d00200041003602000c010b20022802042203200128020441286e2204200420034b1bad42287e2205422088a70d012005a72204417f4c0d010240024020040d00410821060c010b200410332206450d030b4100210720024100360210200220063602082002200441286e36020c0240024002402003450d0041002108034041002104200241003a0078200841016a210820012802042109417f210a034020092004460d03200241d8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0078200a417f6a210a200c2104200c4120470d000b200241386a41186a2204200241d8006a41186a290300370300200241386a41106a220a200241d8006a41106a290300370300200241386a41086a220d200241d8006a41086a290300370300200220022903583703382009200c6b220c4108490d03200b29000121052001200b41096a3602002001200c41786a360204200241186a41086a220c200d290300370300200241186a41106a2209200a290300370300200241186a41186a220a20042903003703002002200229033837031802402007200228020c470d00200241086a20074101108f0120022802082106200228021021070b2006200741286c6a22042002290318370300200c290300210e2009290300210f200a290300211020042005370320200441186a2010370300200441106a200f370300200441086a200e3703002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c020b200441ff0171450d00200241003a00780b20004100360200200228020c2204450d00200441286c450d00200610350b20024180016a24000f0b1044000b1045000b8c0f05047f017e017f017e077f23004190016b22022400200241c8006a41186a22034200370300200241c8006a41106a22044200370300200241c8006a41086a220542003703002002420037034841a9d1cb00ad4280808080c0008422061001220729000021082005200741086a290000370300200220083703482007103541b7d1cb00ad4280808080b00184100122092900002108200241286a41086a2207200941086a2900003703002002200837032820091035200420022903282208370300200241f0006a41086a220a2005290300370300200241f0006a41106a220b2008370300200241f0006a41186a220c200729030037030020022002290348370370200241c8006a200241f0006a10dd0220022802482109200229024c21082003420037030020044200370300200542003703002002420037034820061001220329000021062005200341086a290000370300200220063703482003103541d8d1cb00ad4280808080a001841001220329000021062007200341086a2900003703002002200637032820031035200420022903282206370300200a2005290300370300200b2006370300200c200729030037030020022002290348370370200241c8006a200241f0006a10b10220022d00482105200c200241e1006a290000370300200b200241d9006a290000370300200a200241d1006a290000370300200220022900493703700240024020054101460d00200241286a41186a4200370300200241286a41106a420037030020074200370300200242003703280c010b200241286a41186a200c290300370300200241286a41106a200b2903003703002007200a290300370300200220022903703703280b200241086a41086a200241286a41086a290300370300200241086a41106a200241286a41106a290300370300200241086a41186a200241286a41186a2903003703002002200229032837030820024100360250200242013703480240410810332205450d002002410836024c20022005360248200542b8173700002002410836025020054108411010372205450d00200542c8013700082002411036024c20022005360248200241103602500240024002404100450d00411021070c010b411041017422074118200741184b1b22074100480d010240024041100d002007103322050d010c040b41102007460d0020054110200710372205450d030b2002200736024c200220053602480b2005420137001020024118360250024020074138714118470d00200741017422044120200441204b1b22044100480d010240024020070d00200410332205450d040c010b20072004460d0020052007200410372205450d030b2002200436024c200220053602480b2009410820091b210d20054204370018200241203602502008420020091b2208422088a72205200241c8006a10772002280250210302402005450d00200d200541286c6a210e410020036b210b200228024c2104410021050340200320056a210c024002402004200b6a4120490d002002280248210a200421090c010b200c41206a2207200c490d03200441017422092007200920074b1b22094100480d030240024020040d00024020090d004101210a0c020b20091033220a450d060c010b2002280248210a20042009460d00200a200420091037220a450d050b2002200936024c2002200a3602480b200a20036a20056a2204200d20056a2207290000370000200441186a200741186a290000370000200441106a200741106a290000370000200441086a200741086a2900003700002002200c41206a2204360250200741206a2903002106024002402009200b6a41606a41074d0d00200921040c010b200441086a220f2004490d0320094101742204200f2004200f4b1b22044100480d030240024020090d00024020040d004101210a0c020b20041033220a450d060c010b20092004460d00200a200920041037220a450d050b2002200436024c2002200a3602480b200a20036a20056a41206a20063700002002200c41286a360250200b41586a210b200541286a2105200e200741286a470d000b200320056a21030b02400240200228024c220420036b4120490d0020022802482107200421050c010b200341206a22052003490d01200441017422072005200720054b1b22054100480d010240024020040d00024020050d00410121070c020b200510332207450d040c010b2002280248210720042005460d0020072004200510372207450d030b2002200536024c200220073602480b200720036a22042002290308370000200441186a200241086a41186a290300370000200441106a200241086a41106a290300370000200441086a200241086a41086a2903003700002002200341206a22043602500240024020052004460d00200421050c010b200541016a22042005490d01200541017422092004200920044b1b22044100480d010240024020050d0041002105024020040d00410121070c020b200410332207450d040c010b20052004460d0020072005200410372207450d030b2002200436024c200220073602480b200720056a41013a0000200541016aad422086200235024884210602402008a72205450d00200541286c450d00200d10350b20024190016a240020060f0b103e000b103c000b8e0406047f017e017f017e047f027e230041f0006b22022400200241c0006a41186a22034200370300200241c0006a41106a22044200370300200241c0006a41086a220542003703002002420037034041a9d1cb00ad4280808080c0008422061001220729000021082005200741086a290000370300200220083703402007103541add1cb00ad4280808080a00184100122092900002108200241e0006a41086a2207200941086a2900003703002002200837036020091035200420022903602208370300200241206a41086a220a2005290300370300200241206a41106a220b2008370300200241206a41186a220c200729030037030020022002290340370320200241106a200241206a10e102200229031821082002290310210d2003420037030020044200370300200542003703002002420037034020061001220929000021062005200941086a290000370300200220063703402009103541c2d1cb00ad4280808080b001841001220929000021062007200941086a2900003703002002200637036020091035200420022903602206370300200a2005290300370300200b2006370300200c2007290300370300200220022903403703202002200241206a10e102200229030821062002290300210e02404108103322050d001045000b200520064200200ea71b200842c8017e4200200da71b7c370000200241f0006a24002005ad42808080808001840baf0b04047f017e0a7f017e230041b0016b2202240020024188016a41186a420037030020024188016a41106a2203420037030020024188016a41086a22044200370300200242003703880141fdd0cb00ad4280808080a00284100122052900002106200241e8006a41086a2207200541086a2900003703002002200637036820051035200420072903003703002002200229036837038801418fd1cb00ad4280808080c000841001220529000021062007200541086a2900003703002002200637036820051035200320022903682206370300200241106a41086a2004290300370300200241106a41106a2006370300200241106a41186a20072903003703002002200229038801370310200241203602342002200241106a360230200241386a200241106aad4280808080800484100510c2010240024002400240200228023822080d00410021030c010b200228023c21092002200241386a41086a28020036024c20022008360248200241086a200241c8006a10c4010240024020022802080d00200228020c220a200228024c220b41057622072007200a4b1b22074105742204417f4c0d040240024020070d00410121030c010b200410332203450d040b4100210c200241003602602002200736025c2002200336025802400240200a450d004100210d0340200b210541002107200241003a00a801200d41016a210d034020052007460d0320024188016a20076a200228024822042d00003a00002002200441016a3602482002200741016a22043a00a8012004210720044120470d000b200241e8006a41186a220e20024188016a41186a290300370300200241e8006a41106a220f20024188016a41106a290300370300200241e8006a41086a221020024188016a41086a29030037030020022002290388013703680240200c200228025c470d00200241d8006a200c4101108a01200228025821032002280260210c0b200520046b210b2003200c4105746a22072002290368370000200741186a200e290300370000200741106a200f290300370000200741086a20102903003700002002200c41016a220c360260200d200a470d000b2002200520046b36024c0b200229025c21062003450d010c020b2002410036024c0240200741ff0171450d00200241003a00a8010b0240200228025c41ffffff3f71450d00200310350b0b4100210320024100360270200242013703682002410936025c2002200241306a3602582002200241e8006a3602542002419c016a41013602002002420137028c01200241c888c200360288012002200241d8006a36029801200241d4006a41e88ac50020024188016a10431a20023502704220862002350268841006200228026c450d00200228026810350b2009450d00200810350b2006420020031b2206422088a7220741057422094104722204417f4c0d01200410332205450d002003410120031b210a20024100360290012002200436028c012002200536028801200720024188016a10770240024020070d002002280290012104200228028801210d0c010b410020022802900122046b2103200228028801210d200228028c012108200a210c0340200c21070240200820036a411f4b0d00024002400240200441206a22052004490d002008410174220c2005200c20054b1b22054100480d000240024020080d00024020050d004101210d0c020b20051033210d0c040b20082005470d020b200521080c030b103e000b200d200820051037210d0b20052108200d0d00103c000b200741206a210c200d20046a22052007290000370000200541186a200741186a290000370000200541106a200741106a290000370000200541086a200741086a290000370000200341606a2103200441206a2104200941606a22090d000b2002200836028c0120022004360290012002200d360288010b2004ad422086200dad8421110240200642ffffff3f83500d00200a10350b200241b0016a240020110f0b1045000b1044000bb70302037f047e23004180016b2202240041002103200241003a0040200041b0b4cc0020011b210402400240034020012003460d01200241206a20036a200420036a2d00003a00002002200341016a22003a00402000210320004120470d000b200241186a200241206a41186a22032903002205370300200241106a200241206a41106a22002903002206370300200241086a200241206a41086a2201290300220737030020022002290320220837030020032005370300200020063703002001200737030020022008370320200241f0006a200241206a10ed03200241206a200228027022032002280278108f0220022903202105200241e8006a280200210002402002280274450d00200310350b4104103322030d011045000b0240200341ff0171450d00200241003a00400b200241346a41023602002002410c6a410436020020024202370224200241f0b2c30036022020024104360204200241d0b4c30036020020024100360274200241b0b4cc00360270200220023602302002200241f0006a360208200241206a4180b3c300104c000b20032000410020054201511b36000020024180016a24002003ad4280808080c000840bc20503027f017e047f230041d0006b2202240041d1c4c700ad4280808080e00084100122032900002104200241086a200341086a290000370300200220043703002003103541d7c4c700ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bec2d05057f047e067f017e1e7f230041900f6b22022400024020010d0041b0b4cc0021000b200220003602282002200136022c41002103200241003a00f80b2001417f6a210402400240024002400240024002400240024002400240034020012003460d01200241d80b6a20036a200020036a22052d00003a00002002200541016a3602282002200341016a22053a00f80b2002200436022c2004417f6a21042005210320054120470d000b200241306a41086a200241d80b6a41086a290300370300200241306a41106a200241d80b6a41106a290300370300200241306a41186a200241d80b6a41186a290300370300200220022903d80b37033041002103200241003a00f80b200120056b2106200020056a2100417f2101034020062003460d02200241d80b6a20036a200020036a22052d00003a00002002200420036b36022c2002200541016a3602282002200341016a22053a00f80b2001417f6a21012005210320054120470d000b200241d0006a41086a200241d80b6a41086a290300370300200241d0006a41106a200241d80b6a41106a290300370300200241d0006a41186a200241d80b6a41186a290300370300200220022903d80b370350200420056b220441016a4110490d042002200020056a220341106a3602282002200441716a220536022c20054108490d0720032900002107200341086a29000021082002200441696a36022c2002200341186a360228200341106a2900002109200241206a200241286a10c40120022802200d08200228022c220420022802242203490d082003417f4c0d0520030d0241002104410121060c030b0240200341ff0171450d00200241003a00f80b0b200241ec0b6a41023602002002418c096a4104360200200242023702dc0b200241f0b2c3003602d80b2002410436028409200241e8b4c30036028009200241003602cc06200241b0b4cc003602c806200220024180096a3602e80b2002200241c8066a36028809200241d80b6a4180b3c300104c000b0240200341ff0171450d00200241003a00f80b0b200241ec0b6a41023602002002418c096a4104360200200242023702dc0b200241f0b2c3003602d80b2002410436028409200241e8b4c30036028009200241003602cc06200241b0b4cc003602c806200220024180096a3602e80b2002200241c8066a36028809200241d80b6a4180b3c300104c000b200310392206450d032006200228022822052003109d081a2002200420036b36022c2002200520036a360228200321040b2006450d042003ad4220862004ad84210a200241f0006a41186a200241306a41186a290300370300200241f0006a41106a200241306a41106a290300370300200241f0006a41086a200241306a41086a2903003703002002200229033037037020024190016a41186a200241d0006a41186a29030037030020024190016a41106a200241d0006a41106a29030037030020024190016a41086a200241d0006a41086a2903003703002002200229035037039001200220093703b801200220093703b001200241d80b6a41186a4200370300200241d80b6a41106a22044200370300200241d80b6a41086a22034200370300200242003703d80b41f1d8cb00ad42808080809001841001220529000021092003200541086a290000370300200220093703d80b2005103541e2d8cb00ad4280808080f00184100122052900002109200241c8066a41086a2201200541086a290000370300200220093703c80620051035200420022903c806220937030020024180096a41086a200329030037030020024180096a41106a200937030020024180096a41186a2001290300370300200220022903d80b37038009200241d80b6a20024180096a10da0220022d00e00c210320024180096a200241d80b6a418801109d081a2002200241d80b6a418c016a2800003600cb06200220022800e10c3602c8060240024020034102470d002002428080818080043703c0022002428080848080023703b80220024280c2d72f3703a80220024280e1eb173703a002200242a0c21e37039802200242a0c21e37039002200242e0ef972037038802200242e0c9dc2937038002200242e0ef97203703f801200242a0c21e3703f001200242a0c21e3703e801200242a0c21e3703e001200242a0c21e3703d801200242a0c21e3703d001200242a0c21e3703c801200242a0c21e3703c00120024280808080c0003703b002410021030c010b200241c0016a20024180096a418801109d081a200241c0016a418c016a20022800cb06360000200220022802c8063600c9020b200241e8026a4200370300200241d8026a4200370300200220033a00c8022002428080e983b1de163703e0022002428080e983b1de163703d002200242a08080808080103703f0022002200241c0016a3602f8022002200241c0016a3602fc02200241d80b6a41186a22054200370300200241d80b6a41106a22014200370300200241d80b6a41086a22034200370300200242003703d80b41d1efcb00ad42808080809001841001220029000021092003200041086a290000370300200220093703d80b2000103541ebc3c400ad428080808030841001220b2900002109200241c8066a41086a2200200b41086a290000370300200220093703c806200b1035200420022903c806370000200441086a220c200029030037000020024180096a41086a220d200329030037030020024180096a41106a220e200129030037030020024180096a41186a220f2005290300370300200220022903d80b37038009200241106a20024180096a10e1022002290318210920022802102110200542003703002001420037030020034200370300200242003703d80b41d1c4c700ad4280808080e000841001220b29000021112003200b41086a290000370300200220113703d80b200b103541e7c4c700ad4280808080e000841001220b29000021112000200b41086a290000370300200220113703c806200b1035200420022903c806370000200c2000290300370000200d2003290300370300200e2001290300370300200f2005290300370300200220022903d80b37038009200241086a20024180096a412010c001200241b8036a4200370300200241ac036a419494ca00360200200241a8036a41b0b4cc00360200200241a4036a4100360200200241d8036a200241f0006a41086a290300370300200241e0036a200241f0006a41106a290300370300200241e8036a200241f0006a41186a2903003703002002428080808080013703b00320024200370398032002420037038803200220022903703703d00320022802082104200228020c21002002200241fc026a3602c8032002200241f8026a3602c4032002200241c0016a3602c00320022000410020041b3602cc0320022009420020101b37038003200520024190016a41186a290300370300200120024190016a41106a290300370300200320024190016a41086a29030037030020022002290390013703d80b2002200a370284092002200636028009200241f0036a20024180036a200241d80b6a20072008200241b0016a20024180096a10ef0341012112024020022802f00322130d00200241f0036a41106a2d00000d00200241d80b6a41086a200241a0036a29030037030020024180096a41086a200241e40b6a28020036020020022002290398033703d80b200220022902dc0b37038009200241880f6a20024180096a10f003410021120b20022802b403221420022802bc03220341d8026c6a210120022802b80321152014210402402003450d00200241a10c6a2110200241cd086a210e20024187096a2116200241d80b6a41186a210b200241e10b6a2117200241880e6a41116a2118200241880e6a41027221192002419c086a41186a211a200241810c6a211b200241f0086a211c200241970e6a211d2002419c086a41116a210f200241d80b6a410172211e20024180096a41e0006a211f200241d0096a2120201421030240034020032d00002104200241c4066a41026a220d200341036a2d00003a00002002200341016a2f00003b01c406200341046a2802002105200341086a28020021002003410c6a2802002106200241e0056a200341106a41e000109d081a200341f8006a2903002109200341f0006a290300210720034180016a290300210820024190046a20034188016a41d001109d081a20044103460d01200241fc086a41026a220c200d2d00003a0000200220022f01c4063b01fc082002419c086a200241e0056a41e000109d081a200241c8066a20024190046a41d001109d081a024002400240024020040e03010200010b200241c40e6a41026a2204200c2d00003a0000200241b00e6a41086a220d2002419c086a41086a2221290000370300200241b00e6a41106a22222002419c086a41106a22232d00003a0000200220022f01fc083b01c40e2002200229009c083703b00e200241c80e6a41186a2224200f41186a2225290000370300200241c80e6a41106a2226200f41106a2227290000370300200241c80e6a41086a2228200f41086a22292900003703002002200f2900003703c80e200241b00b6a41186a222a200e41186a222b290000370300200241b00b6a41106a222c200e41106a222d290000370300200241b00b6a41086a222e200e41086a222f2900003703002002200e2900003703b00b200220063600930e2002200036008f0e2002200536008b0e2002200c2d00003a008a0e200220022f01fc083b01880e201d200229009c08370000201d41086a2021290000370000201d41106a20232d00003a000020024180096a41186a202529000037030020024180096a41106a202729000037030020024180096a41086a20292900003703002002200f29000037038009200b202b290000370300200241d80b6a41106a202d290000370300200241d80b6a41086a202f2900003703002002200e2900003703d80b200241f80e6a41086a201c41086a2800003602002002201c2900003703f80e200241e80e6a200241880e6a20024180096a200241d80b6a20072009200241f80e6a10f10320022d00e80e210c201720022f01c40e3b0000201741026a20042d00003a0000200b20022903b00e370000200b41086a200d290300370000200b41106a20222d00003a0000200241033a00e00b2002410d3a00d80b200220063602ec0b200220003602e80b200220053602e40b201b20022903c80e370000201b41086a2028290300370000201b41106a2026290300370000201b41186a2024290300370000201041186a202a290300370000201041106a202c290300370000201041086a202e290300370000201020022903b00b370000200241d80b6a41f8006a2009370300200220073703c80c2002200c4104463a00c10c41b0b4cc004100200241d80b6a10d4010c020b20162002419c086a41e000109d081a2002410d3a00d80b201e20024180096a41e700109d081a200241d80b6a41f0006a2009370300200220073703c00c200220083703d00c20052006200241d80b6a10d401200041ffffff3f71450d01200510350c010b200241f80e6a41026a2204200c2d00003a0000200241c80e6a41086a220d2002419c086a41086a2221290000370300200241c80e6a41106a22222002419c086a41106a22232d00003a0000200220022f01fc083b01f80e2002200229009c083703c80e20024180096a201a41c800109d081a20202009370300200220073703c809200220083703d809201f200241c8066a41d001109d081a200241b00e6a20024180096a10d803200241d80b6a20024180096a41b002109d081a201920022f01fc083b0000201941026a200c2d00003a00002018200229009c08370000201841086a2021290000370000201841106a20232d00003a000020024180023b01880e200220063600950e200220003600910e2002200536008d0e200241b00b6a200241d80b6a200241880e6a10ac0342002109024020022903b80b4201520d00420020022903b00e220920022903c00b7d220720072009561b21090b2002427f20022903b801220720097c220920092007541b220920022903b001220720092007561b3703b80120022903b00b2109201720022f01f80e3b0000201741026a20042d00003a0000200b20022903c80e370000200b41086a200d290300370000200b41106a20222d00003a0000200241063a00e00b2002410d3a00d80b200220063602ec0b200220003602e80b200220053602e40b20022009503a00810c41b0b4cc004100200241d80b6a10d4010b200341d8026a22032001470d000b200121040c010b200341d8026a21040b024020012004460d0003402004220341d8026a21040240024020032d0000220541014b0d000240024020050e020001000b0240200341086a28020041ffffff3f71450d00200341046a28020010350b200341106a2d00004107470d02200341386a280200450d02200341346a28020010350c020b200341286a10bb020c010b200341e8006a28020041ffffff3f71450d00200341e4006a28020010350b20012004470d000b0b02402015450d00201541d8026c450d00201410350b20024184046a280200210d200241f0036a41106a2802002106200241fc036a2802002100200241f8036a280200210b20022802f40321010240200228028c032203450d0020024180036a41106a280200450d00200310350b02402012450d0002400240200228029c03220c0d004100210e200241ec0b6a4100360200200241003602dc0b0c010b20022802a403210e02400240200241a0036a28020022040d00200c21030c010b20042103200c2105034020052802880b21052003417f6a22030d000b200c21030340200320032f01064102746a41880b6a28020021032004417f6a22040d000b2005210c0b200241f40b6a20032f0106360200200241f00b6a4100360200200241ec0b6a2003360200200241003602e80b200242003703e00b2002200c3602dc0b200241003602d80b0b2002200e3602f80b200241d80b6a108f030b02402013450d00410021010240200d450d00200610350b0b200241003602e00b200242013703d80b410110332103024002402001450d002003450d08200341003a0000200220033602d80b20024281808080103702dc0b20034101410210372203450d08200320063a0001200220033602d80b20024282808080203702dc0b2000200241d80b6a10770240024020022802dc0b220520022802e00b22046b2000490d0020022802d80b21030c010b200420006a22032004490d08200541017422062003200620034b1b22064100480d080240024020050d00024020060d00410121030c020b2006103322030d010c0b0b20022802d80b210320052006460d0020032005200610372203450d0a0b200220063602dc0b200220033602d80b0b200320046a20012000109d081a200420006aad42208621090c010b2003450d07200341013a0000200241013602dc0b200220033602d80b42808080801021090b20092003ad84210902402001450d00200b450d00200110350b200241900f6a240020090f0b2002418c096a4104360200200241ec0b6a4102360200200242023702dc0b200241f0b2c3003602d80b2002410436028409200241e8b4c30036028009200241003602cc06200241b0b4cc003602c806200220024180096a3602e80b2002200241c8066a36028809200241d80b6a4180b3c300104c000b1044000b1045000b2002418c096a4104360200200241ec0b6a4102360200200242023702dc0b200241f0b2c3003602d80b2002410436028409200241e8b4c30036028009200241003602cc06200241b0b4cc003602c806200220024180096a3602e80b2002200241c8066a36028809200241d80b6a4180b3c300104c000b2002418c096a4104360200200241ec0b6a4102360200200242023702dc0b200241f0b2c3003602d80b2002410436028409200241e8b4c30036028009200241003602cc06200241b0b4cc003602c806200220024180096a3602e80b2002200241c8066a36028809200241d80b6a4180b3c300104c000b103e000b103c000bbf2303027f027e077f23004190056b2207240020072004370310200720033703082007200536021c02400240024002400240024002400240024002400240024002402001280230200128024022082802b001460d002005420020052903082209200841386a2903007d220a200a20095622081b37030820080d03200741f8026a200210f303200741a0016a20072802f802220820072802800310d90220072d00a0012105200741b8046a200741a0016a41017241d700109d081a024020054102460d00200741e0036a200741b8046a41d700109d081a0b024020072802fc02450d00200810350b2005417f6a41ff01714102490d01200741b8046a200741e7036a220b41d000109d081a200741a0016a41186a4200370300200741a0016a41106a220c4200370300200741a0016a41086a22054200370300200742003703a00141d1c4c700ad4280808080e000841001220829000021092005200841086a290000370300200720093703a0012008103541e7c4c700ad4280808080e00084100122082900002109200741b0026a41086a220d200841086a290000370300200720093703b00220081035200c20072903b0022209370300200741f8026a41086a22082005290300370300200741f8026a41106a22052009370300200741f8026a41186a220c200d290300370300200720072903a0013703f8022007200741f8026a412010c001200741b0026a20022007280204410020072802001b220e4100200741b8046a10f603200741a0016a200b41d000109d081a200c200741b0026a41186a2903003703002005200741b0026a41106a2903003703002008200d290300370300200720072903b0023703f802200741206a2002200741a0016a200e200741f8026a10f70320072d002021050c020b200041003a0004200041013602002000410c6a4129360200200041086a41c4baca00360200200041106a2006290200370200200041186a200641086a2802003602000c0b0b200720053a0020200741206a410172200741e0036a41d700109d081a0b200541037122084103460d0220080e03010201010b200041003a0004200041013602002000410c6a4123360200200041086a41edbaca00360200200041106a2006290200370200200041186a200641086a2802003602000c080b200741f8006a41186a200141e8006a29000037030020074188016a200141e0006a290000370300200741f8006a41086a200141d8006a2900003703002007200129005037037841002108024002400240200541ff0171220541024d0d000c010b024020050e03000102000b200741c0006a2802002205417f4c0d032007413c6a280200210e200741206a41186a280200210c0240024020050d004100210d410121080c010b200510332208450d052005210d0b02400240200d2005490d00200d210b0c010b200d410174220b2005200b20054b1b220b4100480d060240200d0d00200b103322080d010c0a0b200d200b460d002008200d200b10372208450d090b2008200c2005109d081a2005ad422086200bad842109200e450d00200c10350b200741086a41086a2903002104200729030821030b200741dc016a4100360200200741cc016a41d8b9ca00360200200741c4016a4100360200200741a0016a41106a2009370300200741f8016a200241086a29000037030020074180026a200241106a29000037030020074188026a200241186a290000370300200720013602a801200741a0016a41286a200141186a220f360200200742083702d401200742003703b801200720083602ac01200720022900003703f001200720012802483602e801200720012903403703e0012007200128023041016a3602d001200129030021092007200128024c3602ec01200720093703a00120074180046a200741f8006a41086a290300370300200741e0036a41286a200741f8006a41106a29030037030020074190046a200741f8006a41186a290300370300200741f4036a200641086a280200360200200720023602e803200720072903783703f803200720062902003702ec0320072007411c6a3602e4032007200741086a3602e003200741e0036a41186a211002400240200320048450450d00410021060c010b200741b8046a200728021c41002010200220032004200741a0016a10bf05024020072d00b8044104460d00200720072900ed033703a0022007200741f4036a2800003600a70220072d00ec03210520072902bc04210320072802b80421060c070b20072802b801210620072802e80321020b200641016a220e41004c0d042007200e3602b801024002400240200741bc016a280200220b450d00200741a0016a41206a280200210c0340200b41086a2105200b2f010622114105742106410021080240024003402006450d0120022005412010a008220d450d02200641606a2106200841016a2108200541206a2105200d417f4a0d000b2008417f6a21110b200c450d02200c417f6a210c200b20114102746a41880b6a280200210b0c010b0b200b200841e0006c6a220541e8026a210602400240200541c5036a2d00000d00200741b8046a41086a2208200641c5006a290000370300200741b8046a41106a220d200641cd006a290000370300200741b8046a41186a220b200641d5006a29000037030020072006413d6a2900003703b8044102210520062d003c4101470d01200741f8026a41186a200b290300370300200741f8026a41106a200d290300370300200741f8026a41086a2008290300370300200720072903b8043703f802410121050c010b20074180036a200641c5006a29000037030020074188036a200641cd006a29000037030020074190036a200641d5006a29000037030020072006413d6a2900003703f80220062d003c21050b200541ff01714102470d010b200741b0026a20072802c801200220072802cc0128021011040020072802b801210e20072d00b00221050c010b200741b9026a20074180036a290300370000200741c1026a20074188036a290300370000200741c9026a20074190036a290300370000200720053a00b002200720072903f8023700b1020b2007200e417f6a3602b8014101210602400240200541ff01714101470d00200741d8026a41186a200741c9026a290000370300200741d8026a41106a200741c1026a290000370300200741d8026a41086a200741b9026a290000370300200720072900b1023703d802200741b8046a200741d8026a20072802e80128020010a306024020072802b8044101470d00200720072900ed033703a0022007200741f4036a2800003600a70220072902bc04210320072d00ec032105410021060c080b200741b0036a41186a2205200741b8046a410472220641186a2802002202360200200741f8026a41106a200641086a290200370300200741f8026a41186a200641106a29020037030020074198036a2002360200200741043602fc02200741fbd5cb003602f802200720062902003703800320072802e40121062005201041186a2900002203370300200741b0036a41106a2202201041106a2900002204370300200741b0036a41086a2208201041086a2900002209370300200741e0046a2009370300200741e8046a2004370300200741f0046a20033703002007201029000022033703b003200720033703d80420072802e003220d41086a29030021032007200741a0016a3602d004200d290300210420072903a001210920072802ec01210d200720033703c004200720043703b8042007200d3602d404200720093703c804200741d0036a41086a200741ec036a220d41086a2802003602002007200d2902003703d003200741b0036a2006200741f8026a200741b8046a200741d0036a20072802e403280200109a05200720072900c1033703a003200720052800003600a7032008290300210320022d0000210520072802b4032106024020072802b0034101470d00200720072800a7033600a702200720072903a0033703a00220074190036a280200450d082007418c036a28020010350c080b200720072d00a2033a00a202200720072f01a0033b01a00220074190036a280200450d012007418c036a28020010350c010b4200210341002105200741f0036a280200450d0020072802ec0310350b200720072903a0022204370390022007419c016a41026a221120072d0092023a0000200720043d019c01200741c0016a280200210220072802dc01210d20072802d801210c20072802d401210820072802c401210e20072802bc01210b024020072802ac012210450d00200741b0016a280200450d00201010350b200741b8046a41026a20112d00003a0000200720072f019c013b01b80402400240200541ff01710d002007200e3602a801200720023602a4012007200b3602a001200f200741a0016a109504200141346a2001413c6a2205280200200d41d8026c220241d8026d220d1095012001280234200528020041d8026c6a20082002109d081a20052005280200200d6a3602000240200c450d00200c41d8026c450d00200810350b20002006360204200020072f01b8043b0011200041106a41003a0000200041086a2003370200200041136a200741ba046a2d00003a00000c010b20002006360204200020072f01b8043b0011200041106a20053a0000200041086a2003370200200041136a200741ba046a2d00003a00000240200d450d00200d41d8026c210d41002106034002400240200820066a22052d0000220141014b0d000240024020010e020001000b0240200541086a28020041ffffff3f71450d00200541046a28020010350b200541106a2d00004107470d02200541386a280200450d02200541346a28020010350c020b200541286a10bb020c010b200541e8006a28020041ffffff3f71450d00200541e4006a28020010350b200d200641d8026a2206470d000b0b0240200c450d00200c41d8026c450d00200810350b02400240200b0d004100210e200741b4016a4100360200200741003602a4010c010b0240024020020d00200b21060c010b20022106200b2105034020052802880b21052006417f6a22060d000b200b21060340200620062f01064102746a41880b6a28020021062002417f6a22020d000b2005210b0b200741bc016a20062f0106360200200741b8016a4100360200200741b4016a2006360200200741003602b001200742003703a8012007200b3602a401200741003602a0010b2007200e3602c001200741a0016a108f030b200041003602000c070b200041003a0004200041013602002000410c6a4119360200200041086a4190bbca00360200200041106a2006290200370200200041186a200641086a280200360200200541ff01710d062007413c6a280200450d06200741386a28020010350c060b1044000b1045000b103e000b41ac96cc004118200741b8046a41d8c1c30041d496cc001046000b200720072903a00237039002200720072800a70236009702200041106a20053a0000200041086a2003370200200020063602042000200729039002370011200041186a20072800970236000020004101360200024020072802ac012200450d00200741a0016a41106a280200450d00200010350b0240024020072802bc0122010d0041002102200741cc046a4100360200200741003602bc040c010b20072802c401210202400240200741c0016a28020022060d00200121000c010b2006210020012105034020052802880b21052000417f6a22000d000b200121000340200020002f01064102746a41880b6a28020021002006417f6a22060d000b200521010b200741d4046a20002f0106360200200741d0046a4100360200200741cc046a2000360200200741003602c804200742003703c004200720013602bc04200741003602b8040b200720023602d804200741b8046a108f03024020072802dc012200450d0020072802d4012101200041d8026c210241002100034002400240200120006a22062d0000220541014b0d000240024020050e020001000b0240200641086a28020041ffffff3f71450d00200641046a28020010350b200641106a2d00004107470d02200641386a280200450d02200641346a28020010350c020b200641286a10bb020c010b200641e8006a28020041ffffff3f71450d00200641e4006a28020010350b2002200041d8026a2200470d000b0b20072802d8012200450d01200041d8026c450d0120072802d40110350c010b103c000b20074190056a24000ba6480d077f017e047f067e047f047e0d7f067e107f027e057f027e0a7f230041b0056b2202240020024190016a42003703002002420037038801200242003703800102400240200128020022030d004100210141002103410021040c010b2001280208210402400240200128020422050d00200321010c010b2005210120032106034020062802880b21062001417f6a22010d000b200321010340200120012f01064102746a41880b6a28020021012005417f6a22050d000b200621030b20012f010621050b20024188016a2107200241b4016a2005360200200241b0016a4100360200200241ac016a2001360200200220043602b801200241003602a801200242003703a0012002200336029c012002410036029801024002400240024002402004450d0020022004417f6a3602b80102402003450d000240024020032f0106450d004100210841002106410021050c010b4100210641002105034002400240200328020022010d002005ad2109410021010c010b200641016a210620033301044220862005ad8421090b200310352009a72105200121032009422088a7220820012f01064f0d000b200121030b20024190056a41186a220a200320084105746a220141206a29000037030020024190056a41106a220b200141186a29000037030020024190056a41086a220c200141106a2900003703002002200141086a290000370390052003200841e0006c6a220141a4036a2d0000210d200141a0036a280200210420014198036a290300210e20014190036a290300210f20014188036a290300211020014180036a2903002111200141f8026a2903002112200141f0026a2903002113200141e8026a290300210920024180046a41186a2214200141bd036a29000037030020024180046a41106a2215200141b5036a29000037030020024180046a41086a2216200141ad036a2900003703002002200141a5036a29000037038004200841016a2108200141c5036a2d0000211702402006450d00200320084102746a41880b6a2802002103410021082006417f6a2201450d00034020032802880b21032001417f6a22010d000b0b200241e0026a41186a200a290300370300200241e0026a41106a200b290300370300200241e0026a41086a200c290300370300200241d0036a41086a2016290300370300200241d0036a41106a2015290300370300200241d0036a41186a201429030037030020022002290390053703e00220022002290380043703d003200220083602a401200220053602a0012002200336029c01200241003602980120094202510d0120024190056aad42808080808004842118200241d0036aad42808080808004842119200241e0026aad4280808080800284211a20024180046aad4280808080800484211b200241b4046a211c20024190056a41106a210820024180046a41106a211d20024189046a211e20024180046a41086a211f20024180046a412c6a2120200241e0026a412c6a2121200241e0026a41106a212220024188036a2123200241b8046a212402400340200241e0016a41186a2203200241e0026a41186a2225290300370300200241e0016a41106a22012022290300370300200241e0016a41086a2205200241e0026a41086a2226290300370300200241c0016a41086a2206200241d0036a41086a220b290300370300200241c0016a41106a220a200241d0036a41106a220c290300370300200241c0016a41186a2215200241d0036a41186a2214290300370300200220022903e0023703e001200220022903d0033703c00120024180026a41186a2216200329030037030020024180026a41106a2227200129030037030020024180026a41086a22282005290300370300200220022903e00137038002200241a0026a41186a22012015290300370300200241a0026a41106a2205200a290300370300200241a0026a41086a220a2006290300370300200220022903c0013703a00202402017ad42ff0183200920095022031b4201520d0020024200201220031b3703d80320024200201320031b3703d003200220024180026a36029005200241e0026a20024180026a200241d0036a20024190056a10880442022109024020022903e00222294202510d0020232903002113200229038003211220022903f802210920294201520d0020022903e802212920242022290300370300201e200229038002370000201e41086a2028290300370000201e41106a2027290300370000201e41186a2016290300370000200220293703b004200241003a008804200241033a00800441b0b4cc00410020024180046a10d4010b42002013200942025122031b21134200201220031b21124200200920031b2109024020030d0020024190056a41186a220642003703002008420037030020024190056a41086a22034200370300200242003703900541b6fdc600ad4280808080800184222910012215290000212a2026201541086a2900003703002002202a3703e0022015103520032026290300370300200220022903e0023703900541e489c200ad4280808080d00184222a10012215290000212b2026201541086a2900003703002002202b3703e00220151035200820022903e002370000200841086a22272026290300370000201f2003290300370300201d200829030037030020024180046a41186a22282006290300370300200220022903900537038004200241e8006a20024180046a412010d701200241e8006a41106a290300212b2002290370212c20022802682115200642003703002008420037030020034200370300200242003703900520291001221629000021292026201641086a290000370300200220293703e0022016103520032026290300370300200220022903e00237039005202a1001221629000021292026201641086a290000370300200220293703e00220161035200820022903e00237000020272026290300370000201f2003290300370300201d2008290300370300202820062903003703002002200229039005370380042002202b420020151b3703e8022002202c420020151b3703e002201b201a10020b200241d0006a20022903800120022903880120024180016a41106a22032903002009201220131091032003200241d0006a41106a290300370300200220022903583703880120022002290350370380010b200e422088210902400240024002400240024002400240024002400240024002400240200d41ff017122154101460d00201741ff01710d0020042011a772450d010b200241d0036a20024180026a10f30320024180046a20022802d003220620022802d80310d9022026201c41086a2900003703002022201c41106a2900003703002025201c41186a2900003703002002201c2900003703e002024020022d00800422034102460d00201d290300212d200229038804212e20022802b004212f20022802ac04213020022802a804213120022802a404213220022802a0042133200228029c042134200228029804213520024190056a41086a20262903003703002008202229030037030020024190056a41186a2025290300370300200220022903e0023703900520022802d40421360b024020022802d403450d00200610350b024002402003410371417f6a220641014b0d0041022137024020060e020002000b20030d0d2034450d0d203510350c0d0b200241c0026a41186a20024190056a41186a290300370300200241c0026a41106a2008290300370300200241c0026a41086a20024190056a41086a29030037030020022002290390053703c00220362138202f2139203021372031213a2032213b2033213c2034213d2035213e202e213f202d21400b4102210641022141024020374102460d00203c417f4c0d0202400240203c0d0041002103410121420c010b203c10332242450d04203c21030b024002402003203c490d00200321430c010b20034101742206203c2006203c4b1b22434100480d05024020030d002043103322420d010c070b20032043460d0020422003204310372242450d060b2042203e203c109d081a20024180046a41186a200241c0026a41186a290300370300201d200241c0026a41106a290300370300201f200241c0026a41086a290300370300200220022903c0023703800420374101462141203c214420372106203b2145203f214620402147203a2148203921490b200241b0036a41186a224a2001290300370300200241b0036a41106a224b2005290300370300200241b0036a41086a224c200a290300370300200b201f290300370300200c201d290300370300201420024180046a41186a2203290300370300200220022903a0023703b00320022002290380043703d003201741ff0171450d060c050b02400240200ea722030d0041002104200241003602940420024100360284040c010b024002402009a722050d00200321010c010b2005210620032101034020012802ec0321012006417f6a22060d000b0340200320032f01064102746a41ec036a28020021032005417f6a22050d000b0b200241003602980420024100360290042002420037038804200220013602840420024100360280042002200336029404200220032f010636029c040b200220043602a00420024180046a1081030c0b0b1044000b1045000b103e000b103c000b20414102460d010240200d4101710d0020024180046a2042204410f4032002350288044220862002280280042203ad8410110240200228028404450d00200310350b20024180046a20024180026a10f3032002350288044220862002280280042203ad8410070240200228028404450d00200310350b02402043450d00204210350b203721060c030b20024180046a2042204410f4032002350288044220862002280280042206ad8410110240200228028404450d00200610350b200241f0036a20024180026a10890420034200370300201d42003703004108211620024180046a41086a22064200370300200242003703800441d1c4c700ad4280808080e000841001221729000021122006201741086a29000037030020022012370380042017103541e7c4c700ad4280808080e0008410012217290000211220024180056a41086a220d201741086a290000370300200220123703800520171035201d200229038005370000201d41086a200d29030037000020024190056a41086a20062903003703002008201d29030037030020024190056a41186a2003290300370300200220022903800437039005200241c8006a20024190056a412010c001200228024c210620022802482117202241086a200241f0036a41086a280200360200202220022903f003370200202120022903b003370100202141086a200241b0036a41086a290300370100202141106a204b290300370100202141186a204a290300370100427f21132002427f3703e8022002427f3703e002200241083602fc0241002141200241003602840320022006410020171b224d36028003024020430d00427f21290c050b20421035427f2113427f21290c040b20414102470d020b200d410171450d00200241f0036a20024180026a10890420034200370300201d42003703004108211620024180046a41086a22064200370300200242003703800441d1c4c700ad4280808080e000841001221729000021122006201741086a29000037030020022012370380042017103541e7c4c700ad4280808080e0008410012217290000211220024180056a41086a220d201741086a290000370300200220123703800520171035201d200229038005370000201d41086a200d29030037000020024190056a41086a20062903003703002008201d29030037030020024190056a41186a2003290300370300200220022903800437039005200241c0006a20024190056a412010c0012002280244210620022802402117202241086a200241f0036a41086a280200360200202220022903f003370200202120022903b003370100202141086a200241b0036a41086a290300370100202141106a204b290300370100202141186a204a290300370100427f21132002427f3703e8022002427f3703e002200241083602fc0241002141200241003602840320022006410020171b224d36028003427f21290c020b20064102460d020240203d0d004100213d0c030b203e10350c020b202120022903d003370200202141086a200b290300370200202141106a200c290300370200202141186a2014290300370200200220463703e002200220493602880320022041360284032002204836028003200220453602fc02200220443602f802200220433602f402200220423602f002200220473703e8022048214d2046211320472129204521160b024020114201520d00200220103703e0022002200f3703e80220102113200f21290b02402015450d00202120022903a002370000202141186a2001290300370000202141106a2005290300370000202141086a200a2903003700000b200ea7210102402004450d0020034200370300201d4200370300201f4200370300200242003703800441d1c4c700ad4280808080e0008410012205290000210e201f200541086a2900003703002002200e370380042005103541e7c4c700ad4280808080e0008410012205290000210e20024180056a41086a2206200541086a2900003703002002200e3703800520051035201d200229038005370000201d41086a200629030037000020024190056a41086a201f2903003703002008201d29030037030020024190056a41186a2003290300370300200220022903800437039005200241386a20024190056a412010c0014101214120024101360284032002200228023c410020022802381b360288030b0240024020010d004100210341002101410021040c010b024002402009a722050d00200121030c010b2005210620012103034020032802ec0321032006417f6a22060d000b0340200120012f01064102746a41ec036a28020021012005417f6a22050d000b0b20012f0106214e0b200220043602a0042002204e36029c0420024100360298042002200136029404200241003602900420024200370388042002200336028404200241003602800402402004450d0020022004417f6a22153602a00402402003450d000240024020032f0106450d004100210d41002106410021050c010b4100210641002105034002400240200328020022010d002005ad2109410021010c010b200641016a210620033301044220862005ad8421090b200310352009a72105200121032009422088a7220d20012f01064f0d000b200121030b20024190056a41186a22172003200d4105746a220141206a2900003703002008200141186a29000037030020024190056a41086a220a200141106a2900003703002002200141086a29000037039005200d41016a21042003200d410c6c6a220141f0026a2802002127200141ec026a280200214f200141e8026a280200210d02402006450d00200320044102746a41ec036a2802002103410021042006417f6a2201450d00034020032802ec0321032001417f6a22010d000b0b20142017290300370300200c2008290300370300200b200a29030037030020022002290390053703d0032002200436028c0420022005360288042002200336028404200241003602800420022802f802212820022802f00221500340204a20142903002209370300204b200c290300220e370300204c200b2903002211370300200220022903d00322123703b00320142009370300200c200e370300200b2011370300200220123703d00320024180056a2050202810f40320191009220141086a2900002109200141106a290000210e200129000021112017200141186a2900003703002008200e370300200a2009370300200220113703900520011035200241f0036a2002350288054220862002280280052201ad842018101010c201024020022802f0032206450d00201620022802f8036b211620022802f403450d00200610350b0240200228028405450d00200110350b02400240200d450d0020024180056a2050202810f40320191009220141086a2900002109200141106a290000210e200129000021112017200141186a2900003703002008200e370300200a20093703002002201137039005200110352002350288054220862002280280052201ad8420182027ad422086200dad8410120240200228028405450d00200110350b201620276a2116204f450d01200d10350c010b20024180056a2050202810f40320191009220141086a2900002109200141106a290000210e200129000021112017200141186a2900003703002008200e370300200a20093703002002201137039005200110352002350288054220862002280280052201ad8420181013200228028405450d00200110350b024020150d00200220163602fc020c030b20022015417f6a22153602a00402402003450d00410021060240200420032f0106490d00034002400240200328020022010d002005ad2109410021010c010b200641016a210620033301044220862005ad8421090b200310352009a72105200121032009422088a7220420012f01064f0d000b200121030b2017200320044105746a220141206a2900003703002008200141186a290000370300200a200141106a2900003703002002200141086a29000037039005200441016a215120032004410c6c6a220141f0026a2802002127200141ec026a280200214f200141e8026a280200210d0240024020060d00205121040c010b200320514102746a41ec036a2802002103410021042006417f6a2201450d00034020032802ec0321032001417f6a22010d000b0b20142017290300370300200c2008290300370300200b200a29030037030020022002290390053703d0032002200436028c042002200536028804200220033602840420024100360280040c010b0b41958dcc00412b41c08dcc00103f000b41958dcc00412b41c08dcc00103f000b20024180046a10810320024190056a41186a2203200241c0026a41186a2903003703002008200241c0026a41106a29030037030020024190056a41086a2201200241c0026a41086a290300370300200220022903c002370390050240024020374102460d002020200229039005370200202041086a2001290300370200202041106a2008290300370200202041186a20032903003702002002203f37038004200220393602a804200220373602a4042002203a3602a0042002203b36029c042002203d360294042002203e36029004200220383602cc0420022040370388042002203c36029804410121030240203c20022802f802470d000240024020022802f0022201203e460d00203e2001203c10a0080d02203b2016470d020c010b203b2016470d010b20202021412010a0080d00203f2013852040202985844200520d00203a204d470d00024020372041470d004100210320374101470d012039200228028803460d010b410121030b0240203d450d00203e10350b20034102460d002003450d010b201f200241e0026a41d000109d081a200241003a00800420024190056a20024180026a10f303200228029005210320022002280298053602d403200220033602d00320024180046a200241d0036a108a040240200228029405450d00200310350b200228029c04450d0220022802980410350c020b20022802f402450d0120022802f00210350c010b02400240200ea722030d0041002104200241003602940420024100360284040c010b024002402009a722050d00200321010c010b2005210620032101034020012802ec0321012006417f6a22060d000b0340200320032f01064102746a41ec036a28020021032005417f6a22050d000b0b200241003602980420024100360290042002420037038804200220013602840420024100360280042002200336029404200220032f010636029c040b200220043602a00420024180046a1081030b024020022802b8012203450d0020022003417f6a3602b801200228029c012203450d0220022802a00121052002280298012106024020022802a401220420032f0106490d00034002400240200328020022010d002005ad2109410021010c010b200641016a210620033301044220862005ad8421090b200310352009a72105200121032009422088a7220420012f01064f0d000b200121030b20024190056a41186a2215200320044105746a220141206a2900003703002008200141186a29000037030020024190056a41086a2216200141106a2900003703002002200141086a29000037039005201f2003200441e0006c6a220141ad036a290000370300201d200141b5036a29000037030020024180046a41186a2227200141bd036a2900003703002002200141a5036a29000037038004200441016a210a20014190036a290300210f20014188036a2903002110200141f8026a2903002112200141f0026a2903002113200141c5036a2d00002117200141a4036a2d0000210d200141a0036a280200210420014198036a290300210e20014180036a2903002111200141e8026a290300210902402006450d002003200a4102746a41880b6a28020021034100210a2006417f6a2201450d00034020032802880b21032001417f6a22010d000b0b202520152903003703002022200829030037030020262016290300370300200b201f290300370300200c201d2903003703002014202729030037030020022002290390053703e00220022002290380043703d0032002200a3602a401200220053602a0012002200336029c01200241003602980120094202520d010b0b200229038001210920024198016a108f0320024180046a2104200950450d040c030b41958dcc00412b41c08dcc00103f000b41958dcc00412b41c08dcc00103f000b20024198016a108f030b024020022903880120024190016a29030084500d0041a1c2c300413341c086cc00103f000b200229038001500d0120024180046aad4280808080800484211b20024180046a21040b200220073602980120024190056a41186a2208420037030020024190056a41106a2205420037030020024190056a41086a22014200370300200242003703900541b6fdc600ad42808080808001842218100122062900002109200241e0026a41086a2203200641086a290000370300200220093703e0022006103520012003290300370300200220022903e0023703900541e489c200ad4280808080d0018422191001220629000021092003200641086a290000370300200220093703e00220061035200520022903e002220937030020024180046a41086a2217200129030037030020024180046a41106a220a200937030020024180046a41186a220b2003290300370300200220022903900537038004200241206a2004412010d701200241206a41106a290300210e200229032821112002280220210620024180016a41106a29030021122002290388012109200842003703002005420037030020014200370300200242003703900520181001220429000021182003200441086a290000370300200220183703e0022004103520012003290300370300200220022903e0023703900520191001220429000021182003200441086a290000370300200220183703e00220041035200520022903e002221837030020172001290300370300200a2018370300200b200329030037030020022002290390053703800420024200200e420020061b221820127d2011420020061b2219200954ad7d220e201920097d2209201956200e201856200e2018511b22031b3703e80220024200200920031b3703e002201b200241e0026aad428080808080028410020c010b200220073602980120024190056a41186a2204420037030020024190056a41106a2205420037030020024190056a41086a22014200370300200242003703900541b6fdc600ad42808080808001842209100122062900002118200241e0026a41086a2203200641086a290000370300200220183703e0022006103520012003290300370300200220022903e0023703900541e489c200ad4280808080d0018422181001220629000021192003200641086a290000370300200220193703e00220061035200520022903e002221937030020024180046a41086a2208200129030037030020024180046a41106a2217201937030020024180046a41186a220a2003290300370300200220022903900537038004200241086a20024180046a412010d701200241086a41106a29030021192002290310210e2002280208210620024180016a41106a29030021112002290388012112200442003703002005420037030020014200370300200242003703900520091001220429000021092003200441086a290000370300200220093703e0022004103520012003290300370300200220022903e0023703900520181001220429000021092003200441086a290000370300200220093703e00220041035200520022903e00222093703002008200129030037030020172009370300200a20032903003703002002200229039005370380042002427f20112019420020061b22097c2012200e420020061b22187c22192018542203ad7c22182003201820095420182009511b22031b3703e8022002427f201920031b3703e00220024180046aad4280808080800484200241e0026aad428080808080028410020b200241b0056a24000b9c3b040f7f017e017f067e230041d0046b2207240020074198026a200110f303200741d0036a200728029802220820072802a00210d902200741f8026a41086a2209200741da036a290100370300200741f8026a410e6a220a200741d0036a41106a290000370100200741a0036a41086a220b20074188046a290300370300200741a0036a41106a220c20074190046a290300370300200741a0036a41186a220d20074198046a290300370300200741a0036a41206a220e200741a0046a290300370300200720072901d2033703f8022007200741f1036a290000370390032007200741f8036a28000036009703200720074180046a2903003703a003200741d0036a41206a2d0000210f200741ec036a2802002110200741d0036a41186a28020021110240024020072d00d00322124102460d00200741fc036a2802002113200741e0026a410e6a200a290100370100200741e0026a41086a2009290300370300200741a8026a41086a200b290300370300200741a8026a41106a200c290300370300200741a8026a41186a200d290300370300200741a8026a41206a200e290300370300200720072903f8023703e00220072007290390033703d00220072007280097033600d702200720072903a0033703a8020240200728029c02450d00200810350b200741f8026a41086a200741e0026a41086a290300370300200741f8026a410e6a2209200741e0026a410e6a290100370100200741a0036a41086a220b200741a8026a41086a290300370300200741a0036a41106a220c200741a8026a41106a290300370300200741a0036a41186a220d200741a8026a41186a290300370300200741a0036a41206a220e200741a8026a41206a290300370300200720072903e0023703f802200720072903d00237039003200720072800d70236009703200720072903a8023703a003410221084102210a024020120d0020074198026a41086a2009290100370300200741d0036a41086a200b290300370300200741d0036a41106a200c290300370300200741d0036a41186a200d290300370300200741d0036a41206a200e290300370300200720072901fe0237039802200720072903900337038802200720072800970336008f02200720072903a0033703d0032013210a0b41012109200a4102460d01200741b6026a20074198026a41086a290300370100200741a0036a41086a200741d0036a41086a290300370300200741a0036a41106a200741d0036a41106a290300370300200741a0036a41186a200741d0036a41186a290300370300200741a0036a41206a200741d0036a41206a29030037030020072007290398023701ae0220072007290388023703f8022007200728008f023600ff02200720072903d0033703a00341002109200a21080c010b0240200728029c02450d00200810350b41012109410221080b200741f0016a41086a200741a8026a41086a220a290100370300200741f0016a410e6a220b200741a8026a410e6a290100370100200741b8016a41086a220c200741a0036a41086a220d290300370300200741b8016a41106a220e200741a0036a41106a2212290300370300200741b8016a41186a2213200741a0036a41186a2214290300370300200741b8016a41206a2215200741a0036a41206a290300370300200720072901a8023703f001200720072903f8023703e001200720072800ff023600e701200720072903a0033703b8010240024002400240024020090d00200741e8006a41186a200f3a0000200741fc006a2010360200200741e8006a41206a20072800e701360000200741e8006a41286a220f20072903b801370300200741e8006a41086a200b290100370300200741e8006a41306a200c290300370300200741e8006a41386a200e290300370300200741e8006a41c0006a2013290300370300200741e8006a41c8006a2015290300370300200720072901f60137036820072011360278200720072903e001370081012007200836028c01200741d0036a41186a4200370300200741d0036a41106a220c4200370300200741d0036a41086a22094200370300200742003703d00341d1c4c700ad4280808080e000841001220b29000021162009200b41086a290000370300200720163703d003200b103541e7c4c700ad4280808080e000841001220b2900002116200a200b41086a290000370300200720163703a802200b1035200c20072903a8022216370300200d2009290300370300201220163703002014200a290300370300200720072903d0033703a003200741e0006a200741a0036a412010c0012007280264410020072802601b210c20084101470d01200f280200200c470d0120004183243b0100200041086a4115360200200041046a41d880c700360200200041026a41053a00000c020b20004183243b0100200041086a4115360200200041046a41fcffc600360200200041026a41023a00000c020b200741f0016a200210f303200741d0036a20072802f001220820072802f80110d902200741f8026a41086a2209200741da036a290100370300200741f8026a410e6a220a200741d0036a41106a290000370100200741a0036a41086a200741d0036a41386a290300370300200741a0036a41106a200741d0036a41c0006a290300370300200741a0036a41186a200741d0036a41c8006a290300370300200741a0036a41206a200741a0046a290300370300200720072901d2033703f8022007200741f1036a290000370390032007200741d0036a41286a280000360097032007200741d0036a41306a2903003703a00302400240024020072d00d003220b4102460d00200741d0036a41206a2d0000210f200741ec036a280200210d200741d0036a41186a280200210e20072d00d1032110200741a8026a410e6a200a290100370100200741a8026a41086a2009290300370300200720072903f8023703a802024020072802f401450d00200810350b200741d0036a410e6a2208200741a8026a410e6a290100370100200741d0036a41086a2209200741a8026a41086a290300370300200720072903a8023703d003200b0d02200d450d01200e10350c010b20072802f401450d00200810350b20004183243b0100200041086a411a360200200041046a419c80c700360200200041026a41033a00000c010b200741e0026a410e6a220a2008290100370100200741e0026a41086a220b2009290300370300200741c1016a200b290300370000200741c7016a200a290100370000200720103a00b801200720072903d0033700b9012007200f3a00d7012007200d3600d3012007200e3600cf01200641086a2802002113200728028c01211520072802900121172007200628020022143602e00220072014201341057422096a3602e4022007200741e8006a3602e802024002400240024002400240024002402013450d002014210803402007200841206a220a3602e002200741d0036a200b200810800620072802d00322080d02200a2108200941606a22090d000b0b4104210d41002109410021110c010b200741a0036a41086a2211200741d0036a410c6a280200360200200720072902d4033703a00341101033220d450d01200d2008360200200d20072903a003370204200d410c6a201128020036020020074281808080103702fc022007200d3602f8022011200741e0026a41086a280200360200200720072903e00222163703a00302402016a7220820072802a4032209470d0041012109410121110c010b200741d0036a410472210f200941606a211241012109024003402007200841206a220a3602a003200741d0036a20112008108006024020072802d003220e0d002012200846210b200a2108200b450d010c020b200741a8026a41086a200f41086a280200220b3602002007200f29020022163703a802200741d0036a41086a2210200b360200200720163703d0030240200920072802fc02470d00200741f8026a20094101108c0120072802f802210d0b200d20094104746a220b200e360200200b20072903d003370204200b410c6a20102802003602002007200941016a2209360280032012200847210b200a2108200b0d000b0b20072802fc0221110b200741a0036a200728027820072802800110f4030240024020073502a80342208620072802a0032212ad8410212216422088a7220f0d00410121100c010b2016a721100b200741003602d803200742013703d0032010200f200741d0036a1097030240024020072802d403220b20072802d80322086b4120490d0020072802d003210a200b210e0c010b200841206a220a2008490d02200b410174220e200a200e200a4b1b220e4100480d0202400240200b0d000240200e0d004101210a0c020b200e1033220a0d010c070b20072802d003210a200b200e460d00200a200b200e1037220a450d060b2007200e3602d4032007200a3602d0030b200a20086a220b2003290000370000200b41186a200341186a290000370000200b41106a200341106a290000370000200b41086a200341086a2900003700002007200841206a22083602d8032008ad422086200aad84100922082900002116200841086a2900002118200841106a2900002119200741a8026a41186a200841186a290000370300200741a8026a41106a2019370300200741a8026a41086a2018370300200720163703a802200810350240200e450d00200a10350b0240200f450d00201010350b024020072802a403450d00201210350b0240200741a8026a200741b8016a412010a0080d000240024020090d004100210a0c010b2009410474210b200d410c6a21084100210a03402008280200200a6a210a200841106a2108200b41706a220b0d000b0b200741e8006a41106a2108200c201720131b210b4101201520131b210e2007200728028401200a6b36028401200741d0036a200110f30320073502d80342208620072802d003220aad841007024020072802d403450d00200a10350b200741d0036a41106a200537030020074180046a200b360200200741fc036a200e360200200741f8036a200c360200200741f4036a200728028401360200200741d0036a41186a2008290300370300200741f0036a200841086a28020036020020074184046a20032900003702002007418c046a200341086a29000037020020074194046a200341106a2900003702002007419c046a200341186a290000370200200720043703d803200741003a00d003200741a0036a200210f30320072802a0032108200720072802a8033602fc02200720083602f802200741d0036a200741f8026a108a04024020072802a403450d00200810350b0240200741ec036a280200450d0020072802e80310350b200741a0036a2001108e02200741d0036a20072802a003220820072802a803108f0220072903d0032105200741e0036a290300211620072903d8032118024020072802a403450d00200810350b200742003703f801200742003703f001200720013602f802200741a0036a2001200741f0016a200741f8026a1088040240024020072903a003221a4202520d00420221040c010b200741c8036a290300211b200741c0036a2903002119200741a0036a41186a2903002104201a4201520d0020072903a803211a20074188046a200741a0036a41106a29030037030020074180046a201a370300200741d0036a41086a41003a0000200741d9036a2001290000370000200741e1036a200141086a290000370000200741e9036a200141106a290000370000200741f1036a200141186a290000370000200741033a00d00341b0b4cc004100200741d0036a10d4010b200542015121014200201b200442025122081b211b4200201920081b21194200200420081b2104024020080d00200741d0036a41186a220e4200370300200741d0036a41106a220b4200370300200741d0036a41086a220a4200370300200742003703d00341b6fdc600ad428080808080018422051001220c290000211a200741e0026a41086a2208200c41086a2900003703002007201a3703e002200c1035200a2008290300370300200720072903e0023703d00341e489c200ad4280808080d00184221a1001220c290000211c2008200c41086a2900003703002007201c3703e002200c1035200b20072903e002221c370300200741a0036a41086a220f200a290300370300200741a0036a41106a2210201c370300200741a0036a41186a22122008290300370300200720072903d0033703a003200741c8006a200741a0036a412010d701200741c8006a41106a290300211c2007290350211d2007280248210c200e4200370300200b4200370300200a4200370300200742003703d00320051001220e29000021052008200e41086a290000370300200720053703e002200e1035200a2008290300370300200720072903e0023703d003201a1001220e29000021052008200e41086a290000370300200720053703e002200e1035200b20072903e0022205370300200f200a2903003703002010200537030020122008290300370300200720072903d0033703a0032007201c4200200c1b3703d8032007201d4200200c1b3703d003200741a0036aad4280808080800484200741d0036aad428080808080028410020b2016420020011b21052018420020011b2116200741f8026a41106a220b201b3703002007201937038003200720043703f802200741f8026a41086a21080240024020044200520d00200720083602f001200741d0036a41186a220e4200370300200741d0036a41106a220a4200370300200741d0036a41086a22014200370300200742003703d00341b6fdc600ad428080808080018422041001220c2900002118200741e0026a41086a2208200c41086a290000370300200720183703e002200c103520012008290300370300200720072903e0023703d00341e489c200ad4280808080d0018422181001220c29000021192008200c41086a290000370300200720193703e002200c1035200a20072903e0022219370300200741a0036a41086a220f2001290300370300200741a0036a41106a22102019370300200741a0036a41186a22122008290300370300200720072903d0033703a003200741186a200741a0036a412010d701200741186a41106a29030021192007290320211b2007280218210c200b290300211a200729038003211c200e4200370300200a420037030020014200370300200742003703d00320041001220b29000021042008200b41086a290000370300200720043703e002200b103520012008290300370300200720072903e0023703d00320181001220b29000021042008200b41086a290000370300200720043703e002200b1035200a20072903e0022204370300200f20012903003703002010200437030020122008290300370300200720072903d0033703a0032007427f201a20194200200c1b22047c201c201b4200200c1b22187c22192018542208ad7c22182008201820045420182004511b22081b3703d8032007427f201920081b3703d003200741a0036aad4280808080800484200741d0036aad428080808080028410020c010b200720083602f001200741d0036a41186a220e4200370300200741d0036a41106a220a4200370300200741d0036a41086a22014200370300200742003703d00341b6fdc600ad428080808080018422181001220c2900002104200741e0026a41086a2208200c41086a290000370300200720043703e002200c103520012008290300370300200720072903e0023703d00341e489c200ad4280808080d0018422191001220c29000021042008200c41086a290000370300200720043703e002200c1035200a20072903e0022204370300200741a0036a41086a220f2001290300370300200741a0036a41106a22102004370300200741a0036a41186a22122008290300370300200720072903d0033703a003200741306a200741a0036a412010d701200741306a41106a290300211b2007290338211a2007280230210c200b290300211c2007290380032104200e4200370300200a420037030020014200370300200742003703d00320181001220b29000021182008200b41086a290000370300200720183703e002200b103520012008290300370300200720072903e0023703d00320191001220b29000021182008200b41086a290000370300200720183703e002200b1035200a20072903e0022218370300200f20012903003703002010201837030020122008290300370300200720072903d0033703a00320074200201b4200200c1b2218201c7d201a4200200c1b2219200454ad7d221b201920047d2204201956201b201856201b2018511b22081b3703d80320074200200420081b3703d003200741a0036aad4280808080800484200741d0036aad428080808080028410020b200720163703f802200720053703800302400240201620058450450d0042002105420021160c010b200720023602e002200741a0036a2002200741f8026a200741e0026a10b002024020072903a0034201520d00200741b0036a290300211620072903a80321050c010b200741c8036a2903002116200741c0036a290300210520072903a8034201520d00200741a0036a41106a290300210420074188046a200741a0036a41186a29030037030020074180046a2004370300200741d0036a41086a41003a0000200741d9036a2002290000370000200741e1036a200241086a290000370000200741e9036a200241106a290000370000200741f1036a200241186a290000370000200741033a00d00341b0b4cc004100200741d0036a10d4010b200741d0036a41186a220c4200370300200741d0036a41106a220a4200370300200741d0036a41086a22014200370300200742003703d00341b6fdc600ad428080808080018422041001220b2900002118200741e0026a41086a2208200b41086a290000370300200720183703e002200b103520012008290300370300200720072903e0023703d00341e489c200ad4280808080d0018422181001220b29000021192008200b41086a290000370300200720193703e002200b1035200a20072903e0022219370300200741a0036a41086a220e2001290300370300200741a0036a41106a220f2019370300200741a0036a41186a22102008290300370300200720072903d0033703a0032007200741a0036a412010d701200741106a29030021192007290308211b2007280200210b200c4200370300200a420037030020014200370300200742003703d00320041001220c29000021042008200c41086a290000370300200720043703e002200c103520012008290300370300200720072903e0023703d00320181001220c29000021042008200c41086a290000370300200720043703e002200c1035200a20072903e0022204370300200e2001290300370300200f200437030020102008290300370300200720072903d0033703a0032007427f20194200200b1b220420167c201b4200200b1b221620057c22182016542208ad7c22052008200520045420052004511b22081b3703d8032007427f201820081b3703d003200741a0036aad4280808080800484200741d0036aad42808080808002841002200041043a000002402009450d0020094104742108200d41046a210003400240200041046a280200450d00200028020010350b200041106a2100200841706a22080d000b0b0240201141ffffffff0071450d00200d10350b200641046a28020041ffffff3f71450d08201410350c080b200d20094104746a210a024020090d00200d21080c030b200741d0036aad42808080808004842119200d210803400240200828020022090d00200841106a21080c040b200841086a280200210b200841046a28020021012008410c6a3502002104200741a0036a200728027820072802800110f4032009ad4280808080800484100922092900002105200941086a2900002116200941106a2900002118200741d0036a41186a200941186a290000370300200741d0036a41106a2018370300200741d0036a41086a2016370300200720053703d0032009103520073502a80342208620072802a0032209ad84201920044220862001ad841012024020072802a403450d00200910350b0240200b450d00200110350b200841106a2208200a470d000c040b0b1045000b103e000b200a2008460d000340200841106a21090240200841086a280200450d00200841046a28020010350b20092108200a2009470d000b0b0240201141ffffffff0071450d00200d10350b20004183243b0100200041086a4110360200200041046a41c080c700360200200041026a41043a00000c010b103c000b200728027c450d00200728027810350b200641046a28020041ffffff3f71450d00200628020010350b200741d0046a24000bd90e03087f037e027f23004180026b2202240041002103200241003a00b801200041b0b4cc0020011b210402400240024002400240034020012003460d0120024198016a20036a200420036a2d00003a00002002200341016a22003a00b8012000210320004120470d000b200241086a41186a20024198016a41186a290300370300200241086a41106a20024198016a41106a290300370300200241086a41086a20024198016a41086a290300370300200220022903980137030841002103200241003a00b801200420006a2104200120006b2101034020012003460d0220024198016a20036a200420036a2d00003a00002002200341016a22003a00b8012000210320004120470d000b200241286a41186a220320024198016a41186a2204290300370300200241286a41106a220020024198016a41106a290300370300200241286a41086a220120024198016a41086a2903003703002002200229039801370328200241c8006a41186a200241086a41186a290300370300200241c8006a41106a200241086a41106a290300370300200241c8006a41086a200241086a41086a29030037030020022002290308370348200241e8006a41186a2003290300370300200241e8006a41106a2000290300370300200241e8006a41086a200129030037030020022002290328370368200241f0016a200241c8006a10f30320024198016a20022802f001220020022802f80110d90220022802f401210320022d00980122014102460d02200241c4016a2802002105200241b8016a2802002106200241b4016a28020021072004280200210802402003450d00200010350b410121092001450d03410121040c040b0240200341ff0171450d00200241003a00b8010b200241ac016a4102360200200241f4006a41043602002002420237029c01200241f0b2c300360298012002410436026c200241f0b4c3003602682002410036024c200241b0b4cc003602482002200241e8006a3602a8012002200241c8006a36027020024198016a4180b3c300104c000b0240200341ff0171450d00200241003a00b8010b200241ac016a4102360200200241f4006a41043602002002420237029c01200241f0b2c300360298012002410436026c200241f0b4c3003602682002410036024c200241b0b4cc003602482002200241e8006a3602a8012002200241c8006a36027020024198016a4180b3c300104c000b02402003450d00200010350b41012104410021090c010b4101210420054102460d00200241f0016a2008200610f403200241e8006aad428080808080048410092203290000210a200341086a290000210b200341106a290000210c20024198016a41186a200341186a29000037030020024198016a41106a200c37030020024198016a41086a200b3703002002200a370398012003103520024188016a20023502f80142208620022802f0012203ad8420024198016aad4280808080800484101010c201024020022802f401450d00200310350b20024188016a41086a280200210d2002280288012101200228028c01210e4100210402402007450d00200810350b0b410121030240024002400240024002400240024020040d00200d41066a410220011b2203417f4c0d0220030d0041002103410121000c010b200310332200450d020b200241003602a00120022000360298012002200336029c0102402004450d00024020030d00410110332200450d052002410136029c0120022000360298010b200041013a0000200241013602a0012002280298012103200228029c0121000240200941ff01714101460d00024020004101470d0020034101410210372203450d062002410236029c0120022003360298010b200341003a0001200241023602a0010c060b024020004101470d0020034101410210372203450d052002410236029c0120022003360298010b200341013a0001200241023602a0010c050b024020030d00410110332200450d042002410136029c0120022000360298010b200041003a0000200241013602a0012002280298012103200228029c0121000240024020010d00024020004101470d0020034101410210372203450d062002410236029c0120022003360298010b200341003a0001200241023602a001428080808020210a0c010b024020004101470d0020034101410210372203450d052002410236029c0120022003360298010b200341013a0001200241023602a001200d20024198016a107702400240200228029c01220420022802a00122006b200d490d0020022802980121030c010b2000200d6a22032000490d04200441017422092003200920034b1b22094100480d040240024020040d00024020090d00410121030c020b2009103322030d010c070b200228029801210320042009460d0020032004200910372203450d060b2002200936029c0120022003360298010b200320006a2001200d109d081a20022000200d6a22003602a0012000ad422086210a0b200a2003ad84210a2001450d05200e450d05200110350c050b1044000b1045000b103e000b103c000b2003ad42808080802084210a0b20024180026a2400200a0bb10503027f017e047f230041d0006b2202240041f1d8cb00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541abe0c600ad4280808080e00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb30101037f02400240024002402002417f4c0d000240024020020d0041002103410121040c010b200210332204450d02200221030b0240024020032002490d00200321050c010b200341017422052002200520024b1b22054100480d03024020030d002005103322040d010c050b20032005460d0020042003200510372204450d040b200420012002109d0821032000200236020820002005360204200020033602000f0b1044000b1045000b103e000b103c000ba70c04037f047e047f037e23004190046b2202240041002103200241003a008003200041b0b4cc0020011b210402400240024002400240034020012003460d01200241e0026a20036a200420036a2d00003a00002002200341016a22003a0080032000210320004120470d000b200241386a41186a200241e0026a41186a2903002205370300200241386a41106a200241e0026a41106a2903002206370300200241386a41086a200241e0026a41086a2903002207370300200220022903e0022208370338200241d8006a41186a2005370300200241d8006a41106a2006370300200241d8006a41086a200737030020022008370358200241d0016a200241d8006a10f303200241e0026a20022802d001220020022802d80110d90220022d00e0022103200241b8036a200241e0026a41017241d700109d081a024020034102460d00200241f8006a200241b8036a41d700109d081a0b024020022802d401450d00200010350b410121002003417f6a41ff01714102490d04200241d0016a200241ff006a220941d000109d081a200241e0026a41186a220a4200370300200241e0026a41106a22044200370300200241e0026a41086a22034200370300200242003703e00241d1c4c700ad4280808080e000841001220029000021052003200041086a290000370300200220053703e0022000103541e7c4c700ad4280808080e00084100122002900002105200241c0026a41086a2201200041086a290000370300200220053703c00220001035200420022903c0022205370300200241b8036a41086a2003290300370300200241b8036a41106a220b2005370300200241b8036a41186a2001290300370300200220022903e0023703b803200241306a200241b8036a412010c001200241a0026a200241d8006a2002280234410020022802301b220c4100200241d0016a10f603200241b8036a200941d000109d081a200241c0026a41186a200241a0026a41186a290300370300200241c0026a41106a200241a0026a41106a2903003703002001200241a0026a41086a290300370300200220022903a0023703c002200241e0026a200241d8006a200241b8036a200c200241c0026a10f703410121014101210020022d00e002417f6a41ff01714102490d03200429030021082003290300210d20024184036a2802002103200241fc026a2802002104200a2802002109200241c0026a200241d8006a108e02200241b8036a20022802c002220a20022802c802108f02200b290300420020022903b80342015122001b210620022903c003420020001b2105024020022802c402450d00200a10350b200241206a20052006428080a8ec85afd1b1014200109808200241106a42002003ad22072002290320220e7d220f200f2007564200200241206a41086a2903002007200e54ad7c7d22074200522007501b22031b220e4200200720031b2207428080e983b1de164200108408200e200784500d022005428080d287e2bc2d5441002006501b0d0120022005428080aef89dc3527c2207200d200d200756200820062007200554ad7c427f7c22055620082005511b22031b2005200820031b2002290310200241106a41086a29030010980820022903002205a7417f2005428080808010544100200241086a290300501b1b210302402004450d00200910350b2003200c6a210441002101410021000c040b0240200341ff0171450d00200241003a0080030b200241f4026a4102360200200241c4036a4104360200200242023702e402200241f0b2c3003602e002200241043602bc0320024184b5c3003602b8032002410036027c200241b0b4cc003602782002200241b8036a3602f0022002200241f8006a3602c003200241e0026a4180b3c300104c000b41c780ca00419b0141e481ca001064000b410021002004450d00200910350b0b02400240410110332203450d000240024002402000450d00200341013a000020034101410210372203450d04200341013a00010c010b200341003a000020034101410210372103024020014101460d002003450d04200341003a000120034102410610372203450d04200320043600024280808080e00021050c020b2003450d03200341013a00010b42808080802021050b20024190046a240020052003ad840f0b1045000b103c000bb90504017f017e017f057e23004190016b220524000240024041004100200220036b2203200320024b1b220220042802206b2203200320024b1b22030d00420021060c010b20054180016a2001108e02200541306a2005280280012207200528028801108f0242002106200541c0006a2903004200200529033042015122021b21082005290338420020021b21090240200528028401450d00200710350b200541206a20092008428080a8ec85afd1b101420010980842002004411c6a350200220a2005290320220b7d220c200c200a564200200541286a290300200a200b54ad7c7d220a420052200a501b22021b220b4200200a20021b220a844200510d00420121062009428080d287e2bc2d5441002008501b0d00200541106a2003ad4200200b200a10840820052005290310200541106a41086a290300428080e983b1de164200108408024002402009428080aef89dc3527c22062004290300220a200a200656200441086a290300220a20082006200954ad7c427f7c220656200a2006511b22041b220b2005290300220c200b200c542006200a20041b220a200541086a290300220b54200a200b511b22041b2206200a200b20041b220a8450450d00410121020c010b42002008200a7d2009200654ad7d220b200920067d220c200956200b200856200b2008511b22021b21094200200c20021b210b20054180016a2001108e02200541306a2005280280012203200528028801108f02200541e0006a2903004200200529033042015122021b2108200541d8006a290300420020021b210c0240200528028401450d00200310350b200c200b58200820095820082009511b21020b024020040d002002450d0020002006370308200041106a200a370300420321060c010b200041186a200a370300200041106a200637030020002002ad370308420221060b2000200637030020054190016a24000bbe1d05017f037e057f037e037f230041f0026b220524000240024002400240024002400240024020042802000e0401020300010b200441106a290300210620042903082107200541e0006a2003360200200541386a41186a2002290310370300200541e4006a2002290224370200200541d8006a200241186a290300370300200541386a41346a200229022c370200200541386a413c6a200241346a290200370200200541386a41c4006a2002413c6a29020037020020054184016a200241c4006a290200370200200541386a41106a200241086a29030020067d20022903002208200754ad7d37030041002102200541003a00382005200820077d370340200541e0016a200110f30320052802e0012104200520052802e80136029c012005200436029801200541386a20054198016a10f805024020052802e401450d00200410350b200541003a00df01200541083a009701200520013602d801200520073703e002200520063703e80202400240200720068450450d0042002107420021060c010b200520013602c8012005200541c8016a3602f001200520054197016a3602ec012005200541d8016a3602e8012005200541df016a3602e4012005200541e0026a3602e00120054198016a2001200541e0016a10dc034101210202402005280298014101470d004200210620052903a00121070c010b200541c0016a2903002106200541b8016a29030021074100210220052903a0014201520d0020054198016a41106a290300210820052802c801210120054198026a20054198016a41186a29030037030020054190026a200837030041002102200541e0016a41086a41003a0000200541e9016a2001290000370000200541f1016a200141086a290000370000200541f9016a200141106a29000037000020054181026a200141186a290000370000200541033a00e00141b0b4cc004100200541e0016a10d4010b024020020d00200520073703c801200520063703d0010240024020072006844200520d002005200541c8016a3602d801200541c8016a21030c010b200520063703d001200520073703c8012005200541c8016a3602d801200541c8016a21030b200541e0016a41186a22094200370300200541e0016a41106a22044200370300200541e0016a41086a22014200370300200542003703e00141b6fdc600ad428080808080018422061001220a2900002107200541e0026a41086a2202200a41086a290000370300200520073703e002200a103520012002290300370300200520052903e0023703e00141e489c200ad4280808080d0018422081001220a29000021072002200a41086a290000370300200520073703e002200a1035200420052903e002220737030020054198016a41086a220b200129030037030020054198016a41106a220c200737030020054198016a41186a220d2002290300370300200520052903e00137039801200541206a20054198016a412010d701200541206a41106a290300210e2005290328210f2005280220210a200341086a290300211020032903002107200942003703002004420037030020014200370300200542003703e00120061001220329000021062002200341086a290000370300200520063703e0022003103520012002290300370300200520052903e0023703e00120081001220329000021062002200341086a290000370300200520063703e00220031035200420052903e0022206370300200b2001290300370300200c2006370300200d2002290300370300200520052903e0013703980120054200200e4200200a1b220620107d200f4200200a1b2208200754ad7d220e200820077d2207200856200e200656200e2006511b22021b3703e80120054200200720021b3703e00120054198016aad4280808080800484200541e0016aad428080808080028410020b2000200541386a41d800109d081a0c060b200541e7016a200241d000109d081a200041003a0000200041016a200541e0016a41d700109d081a0c050b200541e0016a200110f30320053502e80142208620052802e0012204ad841007024020052802e401450d00200410350b200541e0016a2002280210220a200241186a28020010f40320053502e80142208620052802e0012204ad841011024020052802e401450d00200410350b200541e0016a41086a41023a000020054189026a41003a0000200541e9016a2001290000370000200541f1016a200141086a290000370000200541f9016a200141106a29000037000020054181026a200141186a2900003700002005410d3a00e00141b0b4cc004100200541e0016a10d401200041023a00000c010b024020042903084201520d00200441106a2903002107200441186a290300210641002104200541003a00d801200541083a00df01200520063703a0012005200737039801200520013602c80102400240200720068450450d0042002107420021060c010b200520013602e0022005200541e0026a3602f0012005200541df016a3602ec012005200541c8016a3602e8012005200541d8016a3602e401200520054198016a3602e001200541386a2001200541e0016a10dc0341012104024020052802384101470d0042002106200529034021070c010b200541e0006a2903002106200541d8006a29030021074100210420052903404201520d00200541386a41106a290300210820052802e002210320054198026a200541386a41186a29030037030020054190026a200837030041002104200541e0016a41086a41003a0000200541e9016a2003290000370000200541f1016a200341086a290000370000200541f9016a200341106a29000037000020054181026a200341186a290000370000200541033a00e00141b0b4cc004100200541e0016a10d4010b20040d00200541e0016a41186a22094200370300200541e0016a41106a22034200370300200541e0016a41086a220a4200370300200542003703e00141b6fdc600ad4280808080800184220f1001220b2900002108200541e0026a41086a2204200b41086a290000370300200520083703e002200b1035200a2004290300370300200520052903e0023703e00141e489c200ad4280808080d0018422101001220b29000021082004200b41086a290000370300200520083703e002200b1035200320052903e002220837030020054198016a41086a220b200a29030037030020054198016a41106a220c200837030020054198016a41186a220d2004290300370300200520052903e00137039801200541086a20054198016a412010d701200541086a41106a2903004200200528020822111b21082005290310420020111b210e024020072006844200520d002009420037030020034200370300200a4200370300200542003703e001200f1001221129000021072004201141086a290000370300200520073703e00220111035200a2004290300370300200520052903e0023703e00120101001221129000021072004201141086a290000370300200520073703e00220111035200320052903e002370000200341086a2004290300370000200b200a290300370300200c2003290300370300200d2009290300370300200520052903e00137039801200520083703e8012005200e3703e00120054198016aad4280808080800484200541e0016aad428080808080028410020c010b2009420037030020034200370300200a4200370300200542003703e001200f10012211290000210f2004201141086a2900003703002005200f3703e00220111035200a2004290300370300200520052903e0023703e001201010012211290000210f2004201141086a2900003703002005200f3703e00220111035200320052903e002370000200341086a2004290300370000200b200a290300370300200c2003290300370300200d2009290300370300200520052903e0013703980120054200200820067d200e200754ad7d2206200e20077d2207200e56200620085620062008511b22041b3703e80120054200200720041b3703e00120054198016aad4280808080800484200541e0016aad428080808080028410020b200541e0016a2002280210220a200241186a280200221210f4030240024020053502e80142208620052802e0012204ad8410212207422088a7220d0d00410121110c010b2007a721110b024020052802e401450d00200410350b200541003602e801200542013703e0012011200d200541e0016a1097030240024020052802e401220b20052802e80122096b4120490d00200941206a210420052802e0012103200b210c0c010b200941206a22042009490d02200b41017422032004200320044b1b220c4100480d0202400240200b0d000240200c0d00410121030c020b200c103322030d010c050b20052802e0012103200b200c460d002003200b200c10372203450d040b2005200c3602e401200520033602e0010b200320096a22092002412c6a220b290000370000200941186a200b41186a290000370000200941106a200b41106a290000370000200941086a200b41086a290000370000200520043602e80120054198016a41186a22092004ad4220862003ad841009220441186a29000037030020054198016a41106a220b200441106a29000037030020054198016a41086a2213200441086a2900003703002005200429000037039801200410350240200c450d00200310350b200541d1006a2009290300370000200541c9006a200b290300370000200541c1006a20132903003700002005200529039801370039200541013a0038200541e0016a200110f30320052802e0012104200520052802e8013602e402200520043602e002200541386a200541e0026a10f805024020052802e401450d00200410350b200541e0016a200a201210f40320053502e80142208620052802e0012204ad841011024020052802e401450d00200410350b200541e0016a41086a41023a000020054189026a41013a0000200541e9016a2001290000370000200541f1016a200141086a290000370000200541f9016a200141106a29000037000020054181026a200141186a2900003700002005410d3a00e00141b0b4cc004100200541e0016a10d4012000200541386a41d800109d081a200d450d00201110350b200241146a280200450d02200a10350c020b103e000b103c000b200541f0026a24000ba50503027f037e027f230041c0076b22022400024002402001450d00200220003602100c010b200241b0b4cc003602100b20022001360214200241e8036a200241106a10c80302400240024020022903d0044203510d00200241186a200241e8036a41c803109d081a200228021422014104490d0120022802102200280000210320022001417c6a3602142002200041046a360210200241e8036a200241186a41c803109d081a200241b0076a20024180056a220110d8032002200320022903b007220420022d00b9074200420010db0341082100200241086a29030021052002290300210620022d00b8072103200110ba02410810332201450d022001200437000002400240200341024d0d00410821030c010b024002400240024020030e03000102000b410021030c020b410121030c010b410221030b200220033a00e8034110210020014108411010372201450d03200120033a0008410921030b200341107221070240200020036b410f4b0d002000200041017422082007200820074b1b2208460d0020012000200810372201450d030b200120036a2200200537000820002006370000200241c0076a24002007ad4220862001ad840f0b200241bc076a41043602002002412c6a41023602002002420237021c200241f0b2c300360218200241043602b4072002419cb5c3003602b007200241003602e403200241b0b4cc003602e0032002200241b0076a3602282002200241e0036a3602b807200241186a4180b3c300104c000b200241bc076a4104360200200241fc036a4102360200200242023702ec03200241f0b2c3003602e803200241043602b4072002419cb5c3003602b007200241003602e403200241b0b4cc003602e0032002200241b0076a3602f8032002200241e0036a3602b807200241e8036a4180b3c300104c000b103c000bd30f04037f017e027f017e230041a0026b220224000240024020010d002002200136020c200241b0b4cc003602080c010b20022001417f6a36020c2002200041016a36020820002d0000220041014b0d004100210102400240024002400240024020000e020100010b2002200241086a10c40120022802000d05200228020c220320022802042200490d052000417f4c0d010240024020000d0041002103410121010c010b200010392201450d032001200228020822042000109d081a2002200320006b36020c2002200420006a360208200021030b2001450d052000ad4220862003ad8421050b410021030240024020010d00410021040c010b2005422088a72200417f4c0d010240024020000d0041002106410121040c010b200010332204450d03200021060b0240024020062000490d00200621070c010b200641017422072000200720004b1b22074100480d04024020060d002007103322040d010c060b20062007460d0020042006200710372204450d050b200420012000109d081a2005428080808070832007ad8421080b200220083702142002200436021020024190016a41e7e485f306200241106a10fa030240024020010d000c010b2005422088a72200417f4c0d010240024020000d0041002104410121030c010b200010332203450d03200021040b0240024020042000490d00200421060c010b200441017422062000200620004b1b22064100480d04024020040d00200610332203450d060c010b20042006460d0020032004200610372203450d050b200320012000109d081a2005428080808070832006ad8421080b2002200837021420022003360210200241b0016a41e2c289ab06200241106a10fb03410021030240024020010d00410021040c010b2005422088a72200417f4c0d010240024020000d0041002106410121040c010b200010332204450d03200021060b0240024020062000490d00200621070c010b200641017422072000200720004b1b22074100480d04024020060d00200710332204450d060c010b20062007460d0020042006200710372204450d050b200420012000109d081a2005428080808070832007ad8421080b2002200837021420022004360210200241d0016a41e9dabdf306200241106a10fb030240024020010d000c010b2005422088a72200417f4c0d010240024020000d0041002104410121030c010b200010332203450d03200021040b0240024020042000490d00200421060c010b200441017422062000200620004b1b22064100480d04024020040d00200610332203450d060c010b20042006460d0020032004200610372203450d050b200320012000109d081a2005428080808070832006ad8421080b20022008370294022002200336029002200241f0016a41e1ea91cb0620024190026a10fb03200241106a41086a220320024190016a41086a290300370300200241106a41106a220420024190016a41106a290300370300200241106a41186a220620024190016a41186a290300370300200241386a200241b0016a41086a290300370300200241c0006a200241b0016a41106a290300370300200241c8006a200241b0016a41186a290300370300200241d8006a200241d0016a41086a290300370300200241e0006a200241d0016a41106a290300370300200241e8006a200241d0016a41186a2903003703002002200229039001370310200220022903b001370330200220022903d00137035020024188016a200241f0016a41186a29030037030020024180016a200241f0016a41106a290300370300200241f8006a200241f0016a41086a290300370300200220022903f001370370412010332200450d0320002002290310370000200041186a2006290300370000200041106a2004290300370000200041086a20032903003700002000412041c00010372200450d032000200241106a41206a2203290000370020200041386a200341186a290000370000200041306a200341106a290000370000200041286a200341086a290000370000200041c00041800110372200450d032000200241106a41c0006a22032900003700402000200241f0006a2204290000370060200041d8006a200341186a290000370000200041d0006a200341106a290000370000200041c8006a200341086a290000370000200041e8006a200441086a290000370000200041f0006a200441106a290000370000200041f8006a200441186a29000037000002402001450d002005a7450d00200110350b41840110332201450d01200242840137021420022001360210418001200241106a10770240024020022802142206200228021822036b418001490d0020034180016a2104200228021021010c010b20034180016a22042003490d03200641017422012004200120044b1b22074100480d030240024020060d00024020070d00410121010c020b200710332201450d060c010b2002280210210120062007460d0020012006200710372201450d050b20022007360214200220013602100b200120036a2000418001109d081a20001035200241a0026a24002004ad4220862001ad840f0b1044000b1045000b103e000b103c000b200241fc016a4104360200200241246a410236020020024202370214200241f0b2c300360210200241043602f401200241b0b5c3003602f001200241003602d401200241b0b4cc003602d0012002200241f0016a3602202002200241d0016a3602f801200241106a4180b3c300104c000bfa0103037f037e037f230041306b220324002003200136020c200341106a200210e503200328021421042003410c6a200335021842208620032802102205ad84102e22012900002106200141086a2900002107200141106a2900002108200341106a41186a2209200141186a290000370300200341106a41106a220a2008370300200341106a41086a220b20073703002003200637031020011035200041186a2009290300370000200041106a200a290300370000200041086a200b2903003700002000200329031037000002402004450d00200510350b024020022802002200450d00200241046a280200450d00200010350b200341306a24000bfa0103037f037e037f230041306b220324002003200136020c200341106a200210e503200328021421042003410c6a200335021842208620032802102205ad84103022012900002106200141086a2900002107200141106a2900002108200341106a41186a2209200141186a290000370300200341106a41106a220a2008370300200341106a41086a220b20073703002003200637031020011035200041186a2009290300370000200041106a200a290300370000200041086a200b2903003700002000200329031037000002402004450d00200510350b024020022802002200450d00200241046a280200450d00200010350b200341306a24000bc50c03037f017e077f230041c0026b22022400024002402001450d00200220003602080c010b200241b0b4cc003602080b2002200136020c2002200241086a10c401024002400240024020022802000d00200228020c220320022802042201490d0002402001417f4c0d000240024020010d0041002103410121000c010b200110392200450d032000200228020822042001109d081a2002200320016b36020c2002200420016a360208200121030b2000450d0120022001ad4220862003ad8422054220883e029c02200220003602980220024190016a20024198026a10c2020240024020022d0090014101470d00410021060c010b200241106a20024190016a410172418001109d081a20024190016a200241106a418001109d081a200241003602a802200242043703a002412010332201450d032001200229039001370000200141186a20024190016a41186a290300370000200141106a20024190016a41106a290300370000200141086a20024190016a41086a290300370000200241a0026a41004101108c0120022802a002220620022802a80222044104746a220341e7e485f30636020c200342a08080808004370204200320013602002002200441016a22013602a802200241b0026a20024190016a41206a10fd030240200120022802a4022207470d00200241a0026a20014101108c0120022802a402210720022802a002210620022802a80221010b200620014104746a220320022903b002370200200341e2c289ab0636020c200341086a200241b0026a41086a2802003602002002200141016a22013602a802200241b0026a200241d0016a10fd03024020012007470d00200241a0026a20074101108c0120022802a402210720022802a002210620022802a80221010b200620014104746a220320022903b002370200200241b0026a41086a22042802002108200341e9dabdf30636020c200341086a20083602002002200141016a22013602a802200241b0026a200241f0016a10fd03024020012007470d00200241a0026a20074101108c0120022802a402210720022802a002210620022802a80221010b200620014104746a220320022903b00237020020042802002104200341e1ea91cb0636020c200341086a2004360200200141016a21090b02402005a7450d00200010350b0240024020060d00410121010c010b20094104744105722201417f4c0d010b200110332200450d022002410036029801200220013602940120022000360290010240024020060d00200041003a00004101210020024101360298010c010b200041013a00002002410136029801200920024190016a1077024020090d0020022802980121000c010b200620094104746a210a2006210103402001280200210b200141086a280200220020024190016a107702400240200228029401220c20022802980122086b2000490d002002280290012103200c21040c010b200820006a22032008490d06200c41017422042003200420034b1b22044100480d0602400240200c0d00024020040d00410121030c020b2004103322030d010c090b2002280290012103200c2004460d002003200c200410372203450d080b200220043602940120022003360290010b200320086a200b2000109d081a2002200820006a2200360298010240200420006b41034b0d00200041046a22082000490d062004410174220c2008200c20084b1b22084100480d060240024020040d00024020080d00410121030c020b200810332203450d090c010b20042008460d0020032004200810372203450d080b200220083602940120022003360290010b200320006a2001410c6a2800003600002002200041046a220036029801200141106a2201200a470d000b0b2000ad42208620023502900184210502402006450d0002402009450d00200941047421002006210103400240200141046a280200450d00200128020010350b200141106a2101200041706a22000d000b0b200741ffffffff0071450d00200610350b200241c0026a240020050f0b1044000b2002411c6a4104360200200241a4016a41023602002002420237029401200241f0b2c3003602900120024104360214200241d0b5c300360210200241003602b402200241b0b4cc003602b0022002200241106a3602a0012002200241b0026a36021820024190016a4180b3c300104c000b1045000b103e000b103c000b5f01017f02404120103322020d001045000b200042a080808080043702042000200236020020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700000bfc0403027f017e057f230041d0006b2202240041a9d1cb00ad4280808080c00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541fcd1cb00ad4280808080900284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bca1d09017f017e047f017e027f037e057f047e017f230041c0046b2200240042002101200041f8016a41186a22024200370300200041f8016a41106a22034200370300200041f8016a41086a22044200370300200042003703f80141a9d1cb00ad4280808080c000841001220529000021062004200541086a290000370300200020063703f8012005103541cde4cb00ad4280808080b00184100122052900002106200041d8036a41086a2207200541086a290000370300200020063703d80320051035200320002903d803220637030020004198046a41086a200429030037030020004198046a41106a200637030020004198046a41186a2007290300370300200020002903f80137039804200041f8016a20004198046a10b70202400240024020002d00f8014102470d00200242003703002003420037030020044200370300200042003703f80141d1c4c700ad4280808080e000841001220529000021062004200541086a290000370300200020063703f801200510354185c5c700ad4280808080e0008410012205290000210620004190016a41086a2207200541086a29000037030020002006370390012005103520032000290390012206370300200041f0026a41086a2004290300370300200041f0026a41106a2006370300200041f0026a41186a2007290300370300200020002903f8013703f002200041f8016a200041f0026a10ce020240024020002802f80122080d0041042108410021040c010b20002902fc012201422088a721040b02400240200441246c2205450d002008210402400340024020042d00004101470d00200441016a2800002107200441086a28020021022000200441106a2802003602f402200020023602f002200741c28289aa04470d00200041f8016a200041f0026a10800420002903f80122064203520d020b200441246a21042005415c6a2205450d020c000b0b2000290380022109200041286a20004188026a41e800109d081a0c010b420321060b02402001422088a72204450d00200441246c21052008210403400240024020042d0000220741044b0d0002400240024020070e050400010204040b2004410c6a280200450d03200441086a28020010350c030b2004410c6a280200450d02200441086a28020010350c020b2004410c6a280200450d01200441086a28020010350c010b200441086a280200450d00200441046a28020010350b200441246a21042005415c6a22050d000b0b02402001a72204450d00200441246c450d00200810350b20004190016a200041286a41e800109d081a0240024020064203520d004100210720004198046a21080c010b200041f0026a20004190016a41e800109d081a200041f8016a41186a22054200370300200041f8016a41106a22074200370300200041f8016a41086a22044200370300200042003703f80141a9d1cb00ad4280808080c00084220a1001220229000021012004200241086a290000370300200020013703f8012002103541c2d1cb00ad4280808080b00184220b100122082900002101200041d8036a41086a2202200841086a290000370300200020013703d80320081035200320002903d803370000200341086a220c200229030037000020004198046a41086a2208200429030037030020004198046a41106a220d200729030037030020004198046a41186a220e2005290300370300200020002903f80137039804200041186a20004198046a10e102024002402000280218450d002000290320500d0020004198046aad4280808080800484210120004198046a21080c010b200542003703002007420037030020044200370300200042003703f801200a1001220f29000021012004200f41086a290000370300200020013703f801200f1035200b1001220f29000021012002200f41086a290000370300200020013703d803200f1035200320002903d803370000200c200229030037000020082004290300370300200d2007290300370300200e2005290300370300200020002903f80137039804200020093703f80120004198046aad42808080808004842201200041f8016aad42808080808001841002200542003703002007420037030020044200370300200042003703f801200a1001220f290000210b2004200f41086a2900003703002000200b3703f801200f103541b7d1cb00ad4280808080b001841001220f290000210b2002200f41086a2900003703002000200b3703d803200f1035200320002903d803370000200c200229030037000020082004290300370300200d2007290300370300200e2005290300370300200020002903f80137039804200041f8016a20004198046a10dd0220002802f801210f20002902fc01210b200542003703002007420037030020044200370300200042003703f801200a10012210290000210a2004201041086a2900003703002000200a3703f8012010103541d8d1cb00ad4280808080a0018410012210290000210a2002201041086a2900003703002000200a3703d80320101035200320002903d803370000200c200229030037000020082004290300370300200d2007290300370300200e2005290300370300200020002903f80137039804200041f8016a20004198046a10b10220002d00f8012105200e20004191026a290000370300200d20004189026a290000370300200820004181026a290000370300200020002900f90137039804200b4200200f1b210a200b428080808070834200200f1b210b200f4108200f1b21040240024020054101460d0020004190046a420037030020004188046a420037030020004180046a4200370300200042003703f8030c010b200041f8036a41186a20004198046a41186a290300370300200041f8036a41106a20004198046a41106a290300370300200041f8036a41086a20004198046a41086a29030037030020002000290398043703f8030b200041d8036a41086a200041f8036a41086a2903002211370300200041d8036a41106a200041f8036a41106a2903002212370300200041d8036a41186a200041f8036a41186a2903002213370300200020002903f80322143703d803200041f8016a41086a200b200a42ffffffff0f8384370300200041f8016a41106a2014370300200041f8016a41186a201137030020004198026a2012370300200041f8016a41286a2013370300200020043602fc01200041003602f80120004198046a200041f8016a10810420004183046a20004198046a41086a28020036000020002000290398043700fb03200041a4046a200041ff036a290000370000200041c28289aa0436009904200041023a009804200020002900f80337009d0420004198046a1082040240200aa72205450d00200541286c450d00200410350b20004198046a21080b200041f8016a41186a22054200370300200041f8016a41106a22074200370300200041f8016a41086a22044200370300200042003703f80141a9d1cb00ad4280808080c00084220a10012202290000210b2004200241086a2900003703002000200b3703f8012002103541cdd1cb00ad4280808080b00184220b1001220d2900002111200041d8036a41086a2202200d41086a290000370300200020113703d803200d1035200320002903d803370000200341086a220d200229030037000020004198046a41086a220e200429030037030020004198046a41106a220c200729030037030020004198046a41186a220f2005290300370300200020002903f80137039804200041086a20004198046a10e1022000280208211520002903102111200542003703002007420037030020044200370300200042003703f801200a1001221029000021122004201041086a290000370300200020123703f801201010354199c2c300ad42808080808001841001221029000021122002201041086a290000370300200020123703d80320101035200320002903d803370000200d2002290300370000200e2004290300370300200c2007290300370300200f2005290300370300200020002903f80137039804200042002009201142017c420120151b7d221120112009561b3e02f8012001200041f8016aad22114280808080c000841002200542003703002007420037030020044200370300200042003703f801200a10012210290000210a2004201041086a2900003703002000200a3703f80120101035200b10012210290000210a2002201041086a2900003703002000200a3703d80320101035200320002903d803370000200d2002290300370000200e2004290300370300200c2007290300370300200f2005290300370300200020002903f80137039804200020093703f80120012011428080808080018410024100210720064200520d00200041f8016a200041f0026a41e800109d081a200041f8036a41186a20004194026a290200370300200041f8036a41106a2000418c026a290200370300200041f8036a41086a20004184026a290200370300200020002902fc013703f803410121070b200041f0026a41186a200041f8036a41186a290300370300200041f0026a41106a200041f8036a41106a290300370300200041f0026a41086a200041f8036a41086a290300370300200020002903f8033703f002200041f8016a41186a22024200370300200041f8016a41106a220d4200370300200041f8016a41086a22044200370300200042003703f80141a9d1cb00ad4280808080c000841001220529000021062004200541086a290000370300200020063703f8012005103541cde4cb00ad4280808080b00184100122052900002106200041d8036a41086a220e200541086a290000370300200020063703d80320051035200320002903d803370000200341086a200e29030037000020004198046a41086a200429030037030020004198046a41106a200d29030037030020004198046a41186a2002290300370300200020002903f80137039804410110332204450d010240024020070d00200441003a000042808080801021060c010b200441013a000020044101412110372204450d03200420002903f002370001200441196a20004188036a290300370000200441116a20004180036a290300370000200441096a200041f8026a2903003700004280808080900421060b2008ad428080808080048420062004ad841002200410350b200041c0046a24000f0b1045000b103c000ba71405067f017e027f057e047f23004190036b22022400024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005417f6a220541024b0d0420050e03010203010b200042033703000c050b024020064104490d002004280001210720012003417b6a22053602042001200441056a36020020054108490d00200429000521082001200341736a36020420012004410d6a36020041002105200241003a0028410d20036b2109200341726a2106024002400340200920056a450d01200241086a20056a200420056a220a410d6a2d00003a0000200120063602042001200a410e6a3602002002200541016a220a3a00282006417f6a2106200a2105200a4120470d000b200241b0026a41086a200241086a41086a290300370300200241b0026a41106a200241086a41106a290300370300200241b0026a41186a200241086a41186a290300370300200220022903083703b00241002105200241003a00482004200a6a2109200a20036b410d6a21030340200320056a450d02200241086a20056a200920056a2204410d6a2d00003a00002001200636020420012004410e6a3602002002200541016a22043a00482006417f6a210620042105200441c000470d000b200241d0026a41386a200241086a41386a290300220b370300200241d0026a41306a200241086a41306a290300220c370300200241d0026a41286a200241086a41286a290300220d370300200241d0026a41206a200241086a41206a290300220e370300200241d0026a41186a200241086a41186a290300220f370300200241d0016a41086a2201200241086a41086a290300370300200241d0016a41106a2204200241086a41106a290300370300200241d0016a41186a2205200f370300200241d0016a41206a2206200e370300200241d0016a41286a2203200d370300200241d0016a41306a220a200c370300200241d0016a41386a2209200b370300200220022903083703d00120024190026a41186a2210200241b0026a41186a29030037030020024190026a41106a2211200241b0026a41106a29030037030020024190026a41086a2212200241b0026a41086a290300370300200220022903b00237039002200241b0016a41186a22132010290300370300200241b0016a41106a22102011290300370300200241b0016a41086a2211201229030037030020022002290390023703b001200241f0006a41386a22122009290300370300200241f0006a41306a2209200a290300370300200241f0006a41286a220a2003290300370300200241f0006a41206a22032006290300370300200241f0006a41186a22062005290300370300200241f0006a41106a22052004290300370300200241f0006a41086a22042001290300370300200220022903d001370370200041106a20073602002000200837030820004200370300200020022903b0013702142000411c6a2011290300370200200041246a20102903003702002000412c6a2013290300370200200020022903703702342000413c6a2004290300370200200041c4006a2005290300370200200041cc006a2006290300370200200041d4006a2003290300370200200041dc006a200a290300370200200041e4006a2009290300370200200041ec006a20122903003702000c070b200541ff0171450d01200241003a00280c010b200541ff0171450d00200241003a00480b200042033703000c040b024020064104490d002004280001210620012003417b6a22053602042001200441056a36020020054108490d0020004201370300200429000521082001200341736a36020420012004410d6a360200200041106a200636020020002008370308200041146a200241086a41e400109d081a0c040b200042033703000c030b20064104490d012004280001210720012003417b6a22053602042001200441056a36020020054108490d01200429000521082001200341736a36020420012004410d6a36020041002105200241003a0028410d20036b2109200341726a2106024002400340200920056a450d01200241086a20056a200420056a220a410d6a2d00003a0000200120063602042001200a410e6a3602002002200541016a220a3a00282006417f6a2106200a2105200a4120470d000b200241b0026a41086a200241086a41086a290300370300200241b0026a41106a200241086a41106a290300370300200241b0026a41186a200241086a41186a290300370300200220022903083703b00241002105200241003a00482004200a6a2109200a20036b410d6a21030340200320056a450d02200241086a20056a200920056a2204410d6a2d00003a00002001200636020420012004410e6a3602002002200541016a22043a00482006417f6a210620042105200441c000470d000b200241d0026a41386a200241086a41386a290300220b370300200241d0026a41306a200241086a41306a290300220c370300200241d0026a41286a200241086a41286a290300220d370300200241d0026a41206a200241086a41206a290300220e370300200241d0026a41186a200241086a41186a290300220f370300200241d0016a41086a2201200241086a41086a290300370300200241d0016a41106a2204200241086a41106a290300370300200241d0016a41186a2205200f370300200241d0016a41206a2206200e370300200241d0016a41286a2203200d370300200241d0016a41306a220a200c370300200241d0016a41386a2209200b370300200220022903083703d00120024190026a41186a2210200241b0026a41186a29030037030020024190026a41106a2211200241b0026a41106a29030037030020024190026a41086a2212200241b0026a41086a290300370300200220022903b00237039002200241b0016a41186a22132010290300370300200241b0016a41106a22102011290300370300200241b0016a41086a2211201229030037030020022002290390023703b001200241f0006a41386a22122009290300370300200241f0006a41306a2209200a290300370300200241f0006a41286a220a2003290300370300200241f0006a41206a22032006290300370300200241f0006a41186a22062005290300370300200241f0006a41106a22052004290300370300200241f0006a41086a22042001290300370300200220022903d001370370200041106a20073602002000200837030820004202370300200020022903b0013702142000411c6a2011290300370200200041246a20102903003702002000412c6a2013290300370200200020022903703702342000413c6a2004290300370200200041c4006a2005290300370200200041cc006a2006290300370200200041d4006a2003290300370200200041dc006a200a290300370200200041e4006a2009290300370200200041ec006a20122903003702000c040b200541ff0171450d02200241003a00280c020b200541ff0171450d01200241003a00480c010b200042033703000c010b200042033703000b20024190036a24000bd90a02087f017e230041106b220224002002410036020820024201370300024002402001280200220341024b0d0002400240024002400240024020030e03000102000b410110332203450d062002410136020420022003360200200341013a000020024101360208200128020421032001410c6a2802002204200210770240024020040d00200228020821050c010b2003200441286c6a2106200228020821050340024002402002280204220720056b4120490d00200541206a210420022802002108200721090c010b200541206a22042005490d05200741017422082004200820044b1b22094100480d050240024020070d00024020090d00410121080c020b2009103322080d010c0b0b2002280200210820072009460d0020082007200910372208450d0a0b20022009360204200220083602000b200820056a22052003290000370000200541186a200341186a290000370000200541106a200341106a290000370000200541086a200341086a29000037000020022004360208200341206a290300210a0240200920046b41074b0d00200441086a22052004490d05200941017422072005200720054b1b22054100480d050240024020090d00024020050d00410121080c020b200510332208450d0b0c010b20092005460d0020082009200510372208450d0a0b20022005360204200220083602000b200820046a200a3700002002200441086a22053602082006200341286a2203470d000b0b024002402002280204220420056b4120490d00200228020021030c010b200541206a22032005490d03200441017422082003200820034b1b22084100480d030240024020040d00024020080d00410121030c020b200810332203450d090c010b2002280200210320042008460d0020032004200810372203450d080b20022008360204200220033602000b200320056a2203200141106a2204290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200541206a3602080c050b410110332203450d052002410136020420022003360200200341023a000020024101360208200128020421080240024020022802042204417f6a4104490d00200228020021030c010b200441017422034105200341054b1b22054100480d0220022802002103024020042005460d0020032004200510372203450d070b20022005360204200220033602000b20032008360001200241053602080c040b410110332203450d042002410136020420022003360200200341033a00002002410136020820022802002103024020022802044101470d0020034101410210372203450d0520024102360204200220033602000b200341013a0001200241023602082001290308210a0240024020022802042204417e6a4108490d00200228020021030c010b20044101742203410a2003410a4b1b22084100480d0120022802002103024020042008460d0020032004200810372203450d060b20022008360204200220033602000b2003200a3700022002410a3602082001290310210a2002280204220441766a41074b0d01200441017422034112200341124b1b22084100480d0020022802002103024020042008460d0020032004200810372203450d050b2003200a37000a200220083602042002200336020020024112360208200141186a2d000021080c020b103e000b20022802002203200a37000a20024112360208200141186a2d0000210820044112470d0020034112412410372203450d0220024124360204200220033602000b200320083a0012200241133602080b20002002290300370200200041086a200241086a280200360200200241106a24000f0b103c000bd00703047f017e057f230041f0006b22012400200141c8006a41186a4200370300200141c8006a41106a22024200370300200141c8006a41086a220342003703002001420037034841d1c4c700ad4280808080e000841001220429000021052003200441086a29000037030020012005370348200410354185c5c700ad4280808080e00084100122042900002105200141386a41086a2206200441086a2900003703002001200537033820041035200220012903382205370300200141186a41086a2003290300370300200141186a41106a2005370300200141186a41186a200629030037030020012001290348370318200141c8006a200141186a10ce0202400240200128024822020d0041002106200141003602102001420437030841042102410021030c010b2001200129024c220537020c200120023602082005422088a721032005a721060b200141c8006a41206a2207200041206a280200360200200141c8006a41186a2208200041186a290200370300200141c8006a41106a2209200041106a290200370300200141c8006a41086a2204200041086a29020037030020012000290200370348024020032006470d00200141086a20034101108d01200128020c210620012802082102200128021021030b2002200341246c220a6a22002001290348370200200041206a2007280200360200200041186a2008290300370200200041106a2009290300370200200041086a20042903003702002001200341016a22003602102008420037030020094200370300200442003703002001420037034841d1c4c700ad4280808080e000841001220829000021052004200841086a29000037030020012005370348200810354185c5c700ad4280808080e00084100122082900002105200141386a41086a2207200841086a2900003703002001200537033820081035200920012903382205370300200141186a41086a2004290300370300200141186a41106a2005370300200141186a41186a2007290300370300200120012903483703182001412036024c2001200141186a36024820022000200141c8006a109606024020002003490d00200a41246a21032002210003400240024020002d0000220441044b0d0002400240024020040e050400010204040b2000410c6a280200450d03200041086a28020010350c030b2000410c6a280200450d02200041086a28020010350c020b2000410c6a280200450d01200041086a28020010350c010b200041086a280200450d00200041046a28020010350b200041246a21002003415c6a22030d000b0b02402006450d00200641246c450d00200210350b200141f0006a24000b7402027f027e230041e0006b22032400200341d0006a2002108e022003200328025022042003280258108f02200341106a2903004200200329030042015122021b21052003290308420020021b210602402003280254450d00200410350b2000200637030020002005370308200341e0006a24000bca0102017f037e230041306b220524000240024020030d00200041003602000c010b20052003280200200328020810f4032004ad4280808080800484100922032900002106200341086a2900002107200341106a2900002108200541106a41186a200341186a290000370300200541106a41106a2008370300200541106a41086a200737030020052006370310200310352000200535020842208620052802002203ad84200541106aad4280808080800484101010c2012005280204450d00200310350b200541306a24000b8505010a7f230041e0016b2203240020034198016a200210f303200341c0006a200328029801220420032802a00110d902200341a8016a41086a2205200341c0006a41286a290300370300200341a8016a41106a2206200341c0006a41306a290300370300200341a8016a41186a2207200341f8006a290300370300200341a8016a41206a220820034180016a290300370300200341a8016a41286a220920034188016a290300370300200341a8016a41306a220a20034190016a2802003602002003200341c0006a41206a2903003703a801200341dc006a280200210b200341c0006a41186a280200210c024020032d004022024102460d00200341086a41306a200a280200360200200341086a41286a2009290300370300200341086a41206a2008290300370300200341086a41186a2007290300370300200341086a41106a2006290300370300200341086a41086a2005290300370300200320032903a8013703080b0240200328029c01450d00200410350b0240024020024102470d00200041003a00000c010b200341c0006a41306a200341086a41306a280200360200200341c0006a41286a200341086a41286a290300370300200341c0006a41206a200341086a41206a290300370300200341c0006a41186a200341086a41186a290300370300200341c0006a41106a200341086a41106a290300370300200341c0006a41086a200341086a41086a2903003703002003200329030837034002402002450d00200041003a00000c010b20002003290254370001200041013a0000200041196a200341ec006a290200370000200041116a200341e4006a290200370000200041096a200341dc006a290200370000200b450d00200c10350b200341e0016a24000b5601027f230041206b22022400200241106a200110f303200241086a20022802102203200228021841b0b4cc0041004100108a022002280208210102402002280214450d00200310350b200241206a240020014101460bbc0104027f027e027f017e230041f0006b22032400200341e0006a200210f303200341086a20032802602204200328026810d902200341186a2903002105200341106a2903002106200341246a2802002107200341206a280200210820032d0008210202402003280264450d00200410350b420021090240200241ff017122044102460d00200445ad21092007450d00200241ff01710d00200810350b2000200637030820002009370300200041106a2005370300200341f0006a24000b971009037f027e027f077e047f057e017f067e047f230041d0036b2204240020032802002105200441206a2001108e02200441a0016a2004280220220320042802282206108f0220042903a001210742002108200442003703a001200441e8016a280200210920042d00ec01210a0240024020074201510d00200441306a41306a4200370300200441306a41286a4200370300200441306a41206a4200370300200441306a41186a4200370300200441c0006a4200370300200441386a4200370300200442003703304200210b4200210c4200210d4200210e0c010b200441d8016a290300210f200441a0016a41306a2903002110200441a0016a41206a290300210b200441a0016a41186a2903002108200441e0016a290300210e20042903b001210d20042903a801210c200441306a41206a200441a0016a41286a290300370300200441306a41286a2010370300200441306a41306a200f370300200441c0006a20083703002004200b3703482004200c3703302004200d3703380b427f200d200b7c200c20087c2211200c542212ad7c220f2012200f200d54200f200d511b22121b2110427f201120121b2111024002400240427f2002290300220f20087c22082008200f542212200241086a2903002208200b7c2012ad7c220b200854200b2008511b22021b42ffffe883b1de1656427f200b20021b220b420052200b501b0d002011201084500d010b2004200f37033020042008370338200441e8006a41186a200441306a41186a290300220b370300200441e8006a41206a2213200441306a41206a290300370300200441e8006a41286a2214200441306a41286a290300370300200441e8006a41306a2215200441306a41306a290300370300200420083703702004200f370368200420042903402216370378200c200f56200d200856200d2008511b21022008200d7d200f200c54ad7d2117200d20087d200c200f54ad7d2118200f200c7d2119200c200f7d211a201120108450211b02400240427f200f20167c220d200d200f5422122008200b7c2012ad7c220d200854200d2008511b22121b220c428080e983b1de16544100427f200d20121b220d501b0d00200441f8006a29030021162015290300211c2014290300211d2013290300211e2004290370211f200429036821204201211120042903800121210c010b02400240200c200d8450450d00420021110c010b42002111200441a0026a41186a22224200370300200441a0026a41106a22144200370300200441a0026a41086a22134200370300200442003703a00241b6fdc600ad4280808080800184220b100122152900002110200441c0036a41086a2212201541086a290000370300200420103703c0032015103520132012290300370300200420042903c0033703a00241e489c200ad4280808080d0018422101001221529000021162012201541086a290000370300200420163703c00320151035201420042903c0032216370300200441a0036a41086a22232013290300370300200441a0036a41106a22242016370300200441a0036a41186a22252012290300370300200420042903a0023703a003200441086a200441a0036a412010d701200441086a41106a29030021162004290310211c20042802082115202242003703002014420037030020134200370300200442003703a002200b10012222290000210b2012202241086a2900003703002004200b3703c0032022103520132012290300370300200420042903c0033703a002201010012222290000210b2012202241086a2900003703002004200b3703c00320221035201420042903c003220b370300202320132903003703002024200b37030020252012290300370300200420042903a0023703a003200442002016420020151b220b200d7d201c420020151b2210200c54ad7d22162010200c7d221c2010562016200b562016200b511b22121b3703a80220044200201c20121b3703a002200441a0036aad4280808080800484200441a0026aad42808080808002841002200441d8026a200d370300200441d0026a200c370300201341013a0000200441a9026a2005290000370000200441b1026a200541086a290000370000200441b9026a200541106a290000370000200441c1026a200541186a290000370000200441033a00a00241b0b4cc004100200441a0026a10d4010b0b2018201720021b210c201a201920021b210b2002ad2110201bad210d200441c8016a201e370300200441d0016a201d370300200441b0016a201f370300200441d8016a201c370300200441b8016a2016370300200420213703c0012004200e3703e001200420203703a801410021022004200a4100200742015122121b3a00ec0120042009410020121b3602e801200420114201512212ad3703a001024020120d002006ad4220862003ad8410070c020b200420063602a402200420033602a002200441a8016a200441a0026a10e702410121020c010b4202210d0b02402004280224450d00200310350b02400240200d4202520d00200042023703000c010b02400240024020074201510d00200241ff0171450d0041032103200441a0026a21020c010b20074201520d01200241ff01710d0141042103200441a0016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b2000200f3703082000200d370300200041286a200c370300200041206a200b370300200041106a2008370300200041186a20103703000b200441d0036a24000b9c0607047f017e017f017e017f017e047f230041e0006b22022400200241306a41186a22034200370300200241306a41106a22044200370300200241306a41086a220542003703002002420037033041f1d8cb00ad42808080809001842206100122072900002108200241d0006a41086a2209200741086a2900003703002002200837035020071035200520092903003703002002200229035037033041fad8cb00ad4280808080e00184220810012207290000210a2009200741086a2900003703002002200a3703502007103520042002290350220a370300200241106a41086a220b2005290300370300200241106a41106a220c200a370300200241106a41186a220d2009290300370300200220022903303703102002200241106a10e1022002280200210e2002290308210a2003420037030020044200370300200542003703002002420037033020061001220729000021062009200741086a2900003703002002200637035020071035200520092903003703002002200229035037033020081001220729000021062009200741086a2900003703002002200637035020071035200420022903502206370300200b2005290300370300200c2006370300200d2009290300370300200220022903303703102002200a42017c4201200e1b2206370330200241106aad4280808080800484200241306aad4280808080800184100202400240412010332209450d0020092001290000370000200941186a200141186a290000370000200941106a200141106a290000370000200941086a200141086a2900003700002009412041c00010372205450d0020052006370020200241306a41186a22012005ad42808080808005841009220941186a290000370300200241306a41106a2204200941106a290000370300200241306a41086a2207200941086a2900003703002002200929000037033020091035412010332209450d0120092002290330370000200042a0808080800437020420002009360200200941186a2001290300370000200941106a2004290300370000200941086a200729030037000020051035200241e0006a24000f0b103c000b1045000bf10203037f017e037f230041106b22022400200241003602082002420137030020002d00002103410110332104024002400240024020034101460d002004450d02200441003a0000200220043602002002428180808010370204200041086a200210f705200235020842208621052002280204452104200228020021000c010b2004450d01200441013a0000200220043602002002428180808010370204412010332203450d0220032000290001370000200341186a2206200041196a290000370000200341106a2207200041116a290000370000200341086a2208200041096a29000037000020044101412110372200450d0120002003290000370001200041096a2008290000370000200041116a2007290000370000200041196a200629000037000020022000360200200242a1808080900437020420031035410021044280808080900421050b200129020020052000ad841002024020040d00200010350b200241106a24000f0b103c000b1045000b3400200041a9d1cb0036020420004100360200200041146a410a360200200041106a41d4c2c300360200200041086a42043702000b910101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120103322060d001045000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000b130020004102360204200041c8d7c3003602000b2d01017f02404108103322020d001045000b20004288808080800137020420002002360200200242b8173700000b2d01017f02404108103322020d001045000b20004288808080800137020420002002360200200242c8013700000bee0202097f027e230041206b220324000240200128020041016a220441004c0d00200120043602000240024020012802042205450d00200141086a28020021060340200541086a210720052f0106220841057421094100210a0240024003402009450d0120022007412010a008220b450d02200941606a2109200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21080b2006450d022006417f6a2106200520084102746a41880b6a28020021050c010b0b2005200a41e0006c6a220941c5036a310000200941e8026a290300220c200c5022071ba7450d004200200941f8026a29030020071b210c4200200941f0026a29030020071b210d0c010b200341086a20012802102002200141146a28020028021c110400200341106a290300210c200128020021042003290308210d0b20012004417f6a3602002000200c3703082000200d370300200341206a24000f0b41ac96cc004118200341186a41d8c1c30041d496cc001046000ba60502097f017e230041106b220524000240024002400240024002400240024002400240200128020041016a220641004c0d002001200636020020012802042207450d07200141086a28020021080340200741086a210920072f0106220a41057421064100210b0240024003402006450d0120022009412010a008220c450d02200641606a2106200b41016a210b200941206a2109200c417f4a0d000b200b417f6a210a0b2008450d092008417f6a21082007200a4102746a41880b6a28020021070c010b0b2007200b41e0006c6a220d4198036a22062802002207450d05200628020421080340200741086a210920072f0106220a41057421064100210b0240024003402006450d0120042009412010a008220c450d02200641606a2106200b41016a210b200941206a2109200c417f4a0d000b200b417f6a210a0b2008450d072008417f6a21082007200a4102746a41ec036a28020021070c010b0b0240200741e8026a200b410c6c6a220628020022070d0041012109410021060c070b20062802082209417f4c0d010240024020090d004100210b410121060c010b200910332206450d032009210b0b02400240200b2009490d00200b210c0c010b200b410174220c2009200c20094b1b220c4100480d040240200b0d00200c103322060d010c060b200b200c460d002006200b200c10372206450d050b200620072009109d081a2009ad422086200cad84210e410121090c060b41ac96cc004118200541086a41d8c1c30041d496cc001046000b1044000b1045000b103e000b103c000b410021090b0240200d41e8026a2d005d450d002006410020091b21060c020b20090d010b20002001280210200220032004200141146a28020028020c1105000c010b2000200e370204200020063602000b20012001280200417f6a360200200541106a24000bd10401097f230041c0006b220324000240200128020041016a220441004c0d002001200436020002400240024020012802042205450d00200141086a28020021060340200541086a210720052f0106220841057421094100210a0240024003402009450d0120022007412010a008220b450d02200941606a2109200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21080b2006450d022006417f6a2106200520084102746a41880b6a28020021050c010b0b2005200a41e0006c6a220741e8026a210902400240200741c5036a2d00000d00200341206a41086a220a200941c5006a290000370300200341206a41106a220b200941cd006a290000370300200341206a41186a2205200941d5006a29000037030020032009413d6a2900003703204102210720092d003c4101470d01200341186a2005290300370300200341106a200b290300370300200341086a200a29030037030020032003290320370300410121070c010b200341086a200941c5006a290000370300200341106a200941cd006a290000370300200341186a200941d5006a29000037030020032009413d6a29000037030020092d003c21070b200741ff01714102470d010b200020012802102002200141146a280200280210110400200128020021040c010b200020073a000020002003290300370001200041096a200341086a290300370000200041116a200341106a290300370000200041196a200341186a2903003700000b20012004417f6a360200200341c0006a24000f0b41ac96cc004118200341206a41d8c1c30041d496cc001046000bbe0201097f230041106b220224000240200028020041016a220341004c0d002000200336020002400240024020002802042204450d00200041086a28020021050340200441086a210620042f010622074105742108410021090240024003402008450d0120012006412010a008220a450d02200841606a2108200941016a2109200641206a2106200a417f4a0d000b2009417f6a21070b2005450d022005417f6a2105200420074102746a41880b6a28020021040c010b0b2004200941e0006c6a220841a4036a2d000022064101410220064101461b200841c5036a2d00001b22084102470d010b20002802102001200041146a2802002802181101002108200028020021030c010b200841004721080b20002003417f6a360200200241106a240020080f0b41ac96cc004118200241086a41d8c1c30041d496cc001046000b820302097f037e230041206b220324000240200128020041016a220441004c0d00200120043602000240024020012802042205450d00200141086a28020021060340200541086a210720052f0106220841057421094100210a0240024003402009450d0120022007412010a008220b450d02200941606a2109200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21080b2006450d022006417f6a2106200520084102746a41880b6a28020021050c010b0b2005200a41e0006c6a22094190036a290300210c20094188036a290300210d20094180036a290300210e0240200941c5036a2d00000d00200ea721094201210e2009450d010c020b200e4202520d010b200320012802102002200141146a280200280214110400200341106a290300210c200128020021042003290308210d2003290300210e0b20012004417f6a360200200041106a200c3703002000200d3703082000200e370300200341206a24000f0b41ac96cc004118200341186a41d8c1c30041d496cc001046000bc82107067f017e067f057e107f047e027f230041f00c6b220224000240024002400240024020002802000d002000417f36020002400240200128020022030d004100210141002103410021040c010b2001280208210402400240200128020422050d00200321010c010b2005210120032106034020062802880b21062001417f6a22010d000b200321010340200120012f01064102746a41880b6a28020021012005417f6a22050d000b200621030b20012f010621050b2002411c6a2005360200200241186a4100360200200241146a2001360200200220043602202002410036021020024200370308200220033602042002410036020002402004450d0020022004417f6a3602202003450d020240024020032f0106450d004100210741002106410021050c010b4100210641002105034002400240200328020022010d002005ad2108410021010c010b200641016a210620033301044220862005ad8421080b200310352008a72105200121032008422088a7220720012f01064f0d000b200121030b200241d00c6a41186a2209200320074105746a220141206a290000370300200241d00c6a41106a220a200141186a290000370300200241d00c6a41086a220b200141106a2900003703002002200141086a2900003703d00c2003200741e0006c6a220441a4036a2d0000210c200441a0036a280200210d2004419c036a280200210e20044198036a280200210120044190036a290300210f20044188036a290300211020044180036a2903002111200441f8026a2903002112200441f0026a2903002113200441e8026a2903002108200241d0016a41186a2214200441bd036a290000370300200241d0016a41106a2215200441b5036a290000370300200241d0016a41086a2216200441ad036a2900003703002002200441a5036a2900003703d001200741016a2107200441c6036a2f01002117200441c5036a2d0000211802402006450d00200320074102746a41880b6a2802002103410021072006417f6a2206450d00034020032802880b21032006417f6a22060d000b0b200241f0096a41186a2009290300370300200241f0096a41106a200a290300370300200241f0096a41086a200b29030037030020024188016a41086a201629030037030020024188016a41106a201529030037030020024188016a41186a2014290300370300200220022903d00c3703f009200220022903d001370388012002200736020c20022005360208200220033602042002410036020020084202510d002000410c6a2119200041046a211a200241d0016a41206a2107200241840a6a211b200241d0016a413d6a211c200241d0016a41286a211d0340200241c8006a41186a2203200241f0096a41186a2209290300370300200241c8006a41106a2205200241f0096a41106a220a290300370300200241c8006a41086a2206200241f0096a41086a220b290300370300200241286a41086a220420024188016a41086a221e290300370300200241286a41106a221420024188016a41106a221f290300370300200241286a41186a221520024188016a41186a2220290300370300200220022903f0093703482002200229038801370328200241e8006a41186a22212015290300370300200241e8006a41106a22222014290300370300200241e8006a41086a222320042903003703002002200229032837036820202003290300370300201f2005290300370300201e2006290300370300200220022903483703880102400240201a2802002214450d00200028020821150c010b200241f0096a410041e002109f081a200241d0016a410041a008109f081a41880b10332214450d0541002115201441003b010620144100360200201441086a200241f0096a41e002109d081a201441e8026a200241d0016a41a008109d081a20004100360208200020143602040b024002400340201441086a210520142f01062216410574210341002106024003402003450d0120024188016a2005412010a0082204450d03200341606a2103200641016a2106200541206a21052004417f4a0d000b2006417f6a21160b02402015450d002015417f6a2115201420164102746a41880b6a28020021140c010b0b200241d00c6a41186a20202903002224370300200241d00c6a41106a201f2903002225370300200241d00c6a41086a201e2903002226370300200220022903880122273703d00c201b2027370200201b41086a2026370200201b41106a2025370200201b41186a2024370200200220193602800a200220163602fc092002201a3602f809200220143602f409200241003602f009201d200f370300200241d0016a41106a2012370300200220103703f001200220133703d8012002200c3a008c022002200d360288022002200e360284022002200136028002200220113703e801200220083703d001201c2002290368370000201c41086a2023290300370000201c41106a2022290300370000201c41186a2021290300370000200220173b01ae02200220183a00ad02200241f0096a200241d0016a1080031a0c010b201441e8026a200641e0006c6a2105024020184101710d0020052005290300200820085022031b37030020052005290308201320031b370308200541106a22062006290300201220031b37030020092021290300370300200a2022290300370300200b2023290300370300200220022903683703f00920052d003c2106200241d0016a41186a2218200541d5006a2204290000370300200241d0016a41106a2221200541cd006a2214290000370300200241d0016a41086a2222200541c5006a221529000037030020022005413d6a22162900003703d001201e200241f0096a200241d0016a200c41ff0171410146220c1b220341086a290000370300201f200341106a2900003703002020200341186a2900003703002002200329000037038801200541012006200c1b3a003c20162002290388013700002015201e2903003700002014201f290300370000200420202903003700002005201020052903202011a722031b370320200541286a2206200f200629030020031b37030020052011200529031820031b3703180240024020010d0041002101410021034100210d0c010b02400240200e0d00200121030c010b200e210320012106034020062802ec0321062003417f6a22030d000b200121030340200320032f01064102746a41ec036a2802002103200e417f6a220e0d000b200621010b20032f010621280b2002200d3602a801200220283602a401200241003602a0012002200336029c01200241003602980120024200370390012002200136028c0120024100360288010240200d450d002002200d417f6a22163602a8012001450d08200541306a210c4100210641002105034002400240200620012f01064f0d0020012103410021040c010b41002104034002400240200128020022030d002005ad2108410021030c010b200441016a210420013301044220862005ad8421080b200110352008a72105200321012008422088a7220620032f01064f0d000b0b200241d00c6a41186a2214200320064105746a220141206a290000370300200241d00c6a41106a220e200141186a290000370300200241d00c6a41086a2215200141106a2900003703002002200141086a2900003703d00c200241b0016a41086a220d20032006410c6c6a220141f0026a2802003602002002200141e8026a2902003703b001200641016a21060240024020040d00200321010c010b200320064102746a41ec036a2802002101410021062004417f6a2203450d00034020012802ec0321012003417f6a22030d000b0b200720022903b001370200200741086a2203200d280200360200200b2015290300370300200a200e29030037030020092014290300370300200241f0096a41206a22042007290300370300200241f0096a41286a220d201d280200360200200220022903d00c3703f009200220063602940120022005360290012002200136028c012002410036028801201d200d28020036020020072004290300370300201820092903003703002021200a2903003703002022200b290300370300200220022903f0093703d00120142009290300370300200e200a2903003703002015200b290300370300200220022903f0093703d00c200241c0016a41086a2003280200360200200220072902003703c001200241b0016a200c200241d00c6a200241c0016a108303024020022802b001450d0020022802b4012203450d0020022802b801450d00200310350b2016450d0120022016417f6a22163602a80120010d000b41958dcc00412b41c08dcc00103f000b20024188016a1081030c010b200541386a2116200541306a211502400240200528023022140d0041002129200241003602e401200241003602d4010c010b2005280238212902400240200541346a28020022060d00201421030c010b2006210320142104034020042802ec0321042003417f6a22030d000b201421030340200320032f01064102746a41ec036a28020021032006417f6a22060d000b200421140b200241003602e801200241003602e001200242003703d801200220143602d401200241003602d001200220033602e401200220032f01063602ec010b200220293602f001200241d0016a108103200541286a200f37030020052010370320200541106a20123703002005201337030820052011370318200520083703002015200e360204201520013602002016200d3602002005200c3a003c2005413d6a2002290368370000200541c5006a2023290300370000200541cd006a2022290300370000200541d5006a2021290300370000200520173b015e200520183a005d0b20022802202201450d0120022001417f6a36022020022802042203450d0620022802082105200228020021060240200228020c220420032f0106490d00034002400240200328020022010d002005ad2108410021010c010b200641016a210620033301044220862005ad8421080b200310352008a72105200121032008422088a7220420012f01064f0d000b200121030b200241d00c6a41186a2215200320044105746a220141206a290000370300200241d00c6a41106a2216200141186a290000370300200241d00c6a41086a2221200141106a2900003703002002200141086a2900003703d00c200241d0016a41086a22222003200441e0006c6a221441ad036a290000370300200241d0016a41106a2223201441b5036a290000370300200241d0016a41186a2229201441bd036a2900003703002002201441a5036a2900003703d001200441016a210420144190036a290300210f20144188036a2903002110201441f8026a2903002112201441f0026a2903002113201441c6036a2f01002117201441c5036a2d00002118201441a4036a2d0000210c201441a0036a280200210d2014419c036a280200210e20144198036a280200210120144180036a2903002111201441e8026a290300210802402006450d00200320044102746a41880b6a2802002103410021042006417f6a2206450d00034020032802880b21032006417f6a22060d000b0b20092015290300370300200a2016290300370300200b2021290300370300201e2022290300370300201f202329030037030020202029290300370300200220022903d00c3703f009200220022903d001370388012002200436020c20022005360208200220033602042002410036020020084202520d000b0b2002108f032000200028020041016a360200200241f00c6a24000f0b41a797cc004110200241d0016a41c8c1c30041c897cc001046000b41958dcc00412b41c08dcc00103f000b103c000b41958dcc00412b41c08dcc00103f000b41958dcc00412b41c08dcc00103f000b8b0503027f017e057f230041d0006b2202240041affdc600ad4280808080f00084100122032900002104200241086a200341086a290000370300200220043703002003103541adb6c300ad4280808080800184100122032900002104200241106a41086a200341086a29000037030020022004370310200310352002200136022c2002412c6aad4280808080c00084100422032900002104200241306a41086a200341086a2900003703002002200437033020031035200241cc006a200241306a3602002002200241c0006a36024420022002412c6a3602482002200241306a360240200241206a200241c0006a107b02400240024002402002280228220541206a2206417f4c0d00200228022021070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a20002006360208200020083602042000200336020002402002280224450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bc20503027f017e047f230041d0006b2202240041fafdc600ad4280808080800184100122032900002104200241086a200341086a290000370300200220043703002003103541f5bac300ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b13002000410436020420004180dec3003602000b3400200041affdc60036020420004100360200200041146a4101360200200041106a4194edc300360200200041086a42073702000baa0b080e7f017e047f017e057f027e067f017e23004180016b22022400200141086a280200210320012802042104200028020421052000280200210602400240024020002802082207200028020c2208460d00200041146a28020021092001280200210a2000280210210b200241086a210c0340200c200741106a290300370300200241106a2201200741186a290300370300200241186a220d200741206a29030037030020022007290308370300200741386a210e02402007280228220f0d00200e21070c020b200741306a2802002100200729030021102007412c6a2802002111200241206a41186a2212200d290300370300200241206a41106a22132001290300370300200241206a41086a2214200c290300370300200220022903003703202000ad42c8007e2215422088a70d032015a72207417f4c0d030240024020070d00410821160c010b200710332216450d030b200741c8006e21170240024020000d00410021180c010b200f20004105746a211941002118200f211a0340201a41086a2900002115201a41106a290000211b201a290000211c200241c0006a41186a221d201a41186a290000370300200241c0006a41106a221e201b370300200241c0006a41086a221f20153703002002201c3703400240200b2802002220450d00200b28020421210340202041086a210020202f010622224105742107410021010240024003402007450d01200241c0006a2000412010a008220d450d02200741606a2107200141016a2101200041206a2100200d417f4a0d000b2001417f6a21220b2021450d022021417f6a2121202020224102746a4194036a28020021200c010b0b0240024002402009280208220d202020014102746a41e8026a220028020022074d0d002009280200200741d8006c6a2207427f2007290320221520107c221b201b2015542201200741286a2207290300221c2001ad7c2223201c54201b20155a1b22011b3703202007427f202320011b370300200241e0006a41186a2201201d290300370300200241e0006a41106a220d201e290300370300200241e0006a41086a2220201f290300370300200220022903403703602000280200210020182017470d02024002400240201841016a22072018490d00201841017422212007202120074b1bad42c8007e2215422088a70d002015a722074100480d00024020180d0020070d02410821160c050b201841c8006c22212007460d04024020210d0020070d02410821160c050b20162021200710372216450d020c040b103e000b2007103322160d020b103c000b2007200d41a4c5ca001042000b200741c8006e21170b2016201841c8006c6a2207420037030020072000360220200741186a4200370300200741106a4200370300200741086a4200370300200720022903603702242007412c6a2020290300370200200741346a200d2903003702002007413c6a2001290300370200201841016a21180b201a41206a221a2019470d000b0b0240201141ffffff3f71450d00200f10350b200241e0006a41186a22072012290300370300200241e0006a41106a22002013290300370300200241e0006a41086a2014290300221537030020022002290320221b370360200a4200370310200a41186a4200370300200a4200370308200a2010370300200a41286a4200370300200a4201370320200a2018360238200a2017360234200a2016360230200a201b37023c200a41c4006a2015370200200a41cc006a2000290300370200200a41d4006a2007290300370200200341016a2103200a41e0006a210a200e2107200e2008470d000b200821070b20042003360200200820076b220041386d210102402000450d00200141386c21002007412c6a210703400240200728020041ffffff3f71450d002007417c6a28020010350b200741386a2107200041486a22000d000b0b02402005450d00200541386c450d00200610350b20024180016a24000f0b1045000b1044000bef3007017f017e017f027e017f027e1c7f23004180036b2207240002400240024002402001200284500d002003200484500d004201210820074198016a200320012003200156200420025620042002511b22091b220a2004200220091b220b20054201200542015620064200522006501b220c1b220520064200200c1b220610980820074188016a200729039801220d20074198016a41086a290300220e200520061084082002200420091b21022001200320091b2104200a20072903880185200b20074188016a41086a290300858450450d01200d210a200e210b420021060c020b20004100360200200041106a4200370300200041086a42003703000c020b200741f8006a2004200220052006109808200741e8006a20072903782201200741f8006a41086a2903002203200520061084084200200620042007290368852002200741e8006a41086a29030085845022091b21064201200520091b21082003200220091b21022001200420091b21040b200741386a200b420020044200108408200741c8006a20024200200a4200108408200741d8006a200a4200200442001084080240024002400240024002400240024002400240024002400240024002400240200b420052200242005271200729034042005272200729035042005272200741d8006a41086a2903002201200729033820072903487c7c2203200154724101470d00411010332209450d0d2007420437029c02200720093602980220074198026a41004104108601200741f0026a41086a220920072802a002220c41046a360200200728029802200c4102746a220c200a3e020c200c200a4220883e0208200c200b3e0204200c200b4220883e020020072007290398023703f002200741f0026a10e607200741a8016a41086a2009280200360200200720072903f0023703a80141101033220c450d0d2007420437029c022007200c3602980220074198026a41004104108601200920072802a002220c41046a360200200728029802200c4102746a220c20043e020c200c20044220883e0208200c20023e0204200c20024220883e020020072007290398023703f002200741f0026a10e607200741b8016a41086a2009280200360200200720072903f0023703b801411010332209450d0d2007420437029c02200720093602980220074198026a41004104108601200741f0026a41086a220c20072802a002220941046a36020020072802980220094102746a22092008a7220f36020c200920084220883e0208200920063e0204200920064220883e020020072007290398023703f002200741f0026a10e607200c280200211020072802f402211120072802f0022112200c200741b8016a41086a280200360200200720072903b8013703f00220074198026a41086a200741a8016a41086a280200360200200720072903a80137039802200741c8016a20074198026a200741f0026a10e807024020072802f40241ffffffff0371450d0020072802f00210350b200741c8016a10e60720104101460d0120072802cc01211320072802c80121142010450d0a2012280200450d0a024020072802d0012215450d002014280200450d0b201520104d0d0b200720103602d401201520106b221641016a22174101201741014b1b221841ffffffff03712018470d0320184102742219417f4c0d0320191039221a450d0e201041ffffffff03712010470d032010410274221b417f4c0d03201b1039221c450d0e4101210f410221092012280200220c67221d211e0240200c41ffffffff034b0d0041022109201d210c4101210f034020094101200c4101711b200f6c210f200c41034b211f200920096c2109200c410176221e210c201f0d000b0b200720153602f802200720133602f402200720143602f0024104211f41041033220c450d0f200c20094101201e4101461b200f6c220f360200200742818080801037029c022007200c36029802200741d8016a200741f0026a20074198026a10e807200c10350240201b450d00201b1033221f450d0f0b200741003602a0022007201b410276222036029c022007201f3602980220074198026a4100201010860120072802980220072802a00222094102746a20122010410274109d081a200741f8026a200920106a36020020072007290398023703f002410410332209450d0f2009200f360200200742818080801037029c022007200936029802200741e8016a200741f0026a20074198026a10e80720091035024020072802d40120176a220920072802e001220c4d0d00200741003602a002200742043703980220074198026a41002009200c6b220c10860120072802a00221090240200c450d0020072802980220094102746a4100200c410274109f081a2009200c6a21090b200741f0026a41086a220c200936020020072007290398023703f00220072802d801211f200741f0026a200920072802e001220f10860120072802f002200c28020022094102746a201f200f410274109d081a200c2009200f6a220936020020074198026a41086a220c2009360200200720072903f00237039802024020072802dc0141ffffffff0371450d0020072802d80110350b200741d8016a41086a200c28020036020020072007290398023703d8010b20194102762121200741e8016a10e607024002400240024002400240024002400240024003402007201622223602f401024020072802e001220920072802d401220c20226a220f417f736a221f2009490d00201f200941ac95cc001042000b0240024002400240024002400240024002400240024002400240024020092009200f6b220f4d0d0020072802f00122092009200c6b220c4d0d0120072802e801200c4102746a35020022024200510d02202220224100476b211620072802d8012209201f4102746a35020021012009200f4102746a3502002104200741003602f80120072004200142208684200280220137038002200741003602880220072004200120027e7d42ffffffff0f83370390022007200741f4016a3602ac022007200741d8016a3602a8022007200741d4016a3602a4022007200741e8016a3602a002200720074188026a36029c022007200741f8016a3602980220074198026a10e9071a034020072802880241016a41004c0d04024020072903900242ffffffff0f560d0020074198026a10e9070d010b0b200729038002210220072802f401210920072802d401210c200741003a00f8022007200c20096a3602f402200720093602f0022007200741d8016a3602fc02200741b0026a200741f0026a10ec0720072802f001220941ffffffff03712009470d1c2009410274220c417f4c0d1c20072802e801210f02400240200c0d004104211f0c010b200c1033221f450d280b200741003602f8022007201f3602f0022007200c4102763602f402200741f0026a4100200910860120072802f00220072802f802221f4102746a200f200c109d081a200741e0026a41086a2223201f20096a360200200720072903f0023703e002410810332209450d2820092002a72224360204200920024220883e020020074282808080203702f402200720093602f002200741c0026a200741e0026a200741f0026a10e8072009103520072802b802221920072802c8022225201920254b1b22144101201441014b1b220c41ffffffff0371200c470d1c200c4102742226417f4c0d1c20072802b402212720072802b00221280240024020260d00410421290c010b202610392229450d280b2014450d062025417f6a221b20254b211520072802c002212a2019417f6a221720194b0d04200c417f6a2109202920266a417c6a211e4100210f4200210203404100211f024020192017200f6b22134d0d004100211f201320174b0d00202820134102746a280200211f0b201fad21044100211f024020150d002025201b200f6b22134d0d002013201b4b0d00202a20134102746a280200211f0b024002402004201fad22037d22012004560d00200120027d220a2001560d00200a42ffffffff0f832104420021020c010b20044280808080108420027d20037d2104420121020b200c20094d0d09201e20043e0200201e417c6a211e2009417f6a2109200f41016a220f2014490d000c060b0b200f200941ac95cc001042000b200c200941ac95cc001042000b419095cc00411941b494cc00103f000b41ac96cc004118200741f0026a41c496cc0041d496cc001046000b200c417f6a2109202920266a417c6a211f4100211e4200210203404100210f024020150d004100210f2025201b201e6b22134d0d004100210f2013201b4b0d00202a20134102746a280200210f0b024002404200200fad22017d22044200520d00200420027d22032004560d00200342ffffffff0f832104420021020c010b428080808010200220017c7d2104420121020b200c20094d0d04201f20043e0200201f417c6a211f2009417f6a2109201e41016a221e2014490d000b0b41012113200250450d010b410021130b0240202741ffffffff0371450d00202810350b20072802d401221f20072802f401220f6a2215201f490d05200f20154f0d01200f417f7321090340200c200c200f6a20096a221e4d0d03200920072802e00122146a220f20094f0d0420072802d801200f4102746a2029201e4102746a2802003602002009417f6a210920072802f401210f201f417f6a221f0d000c050b0b2009200c41bc95cc001042000b201f450d020c030b20252019202520194b1b22074101200741014b1b200f6a20096a200c41ac95cc001042000b200f201441bc95cc001042000b200c200c2015417f7322096a200f6a220f4d0d0220072802e001220c20096a2209200c4f0d0320072802d80120094102746a2029200f4102746a28020036020020072802f401210f0b2018200f417f736a220920184f0d03201a20094102746a202436020002402013450d00201820072802f401417f736a220920184f0d05201a20094102746a22092009280200417f6a36020020072802f401210920072802d401210c200741003a00f8022007200c20096a3602f402200720093602f0022007200741d8016a3602fc02200741d0026a200741f0026a10ec0720072802f001220941ffffffff03712009470d0f2009410274220c417f4c0d0f20072802e801210f02400240200c0d004104211f0c010b200c1033221f450d1b0b200741003602f8022007201f3602f0022007200c4102763602f402200741f0026a4100200910860120072802f00220072802f802221f4102746a200f200c109d081a2023201f20096a360200200720072903f0023703e002200741f0026a200741e0026a200741d0026a10e707024020072802d401220920072802f40122146a220c2009490d00024002402014200c4f0d00200c417f73210920072802f002211320072802f802210f2014211f0340200f200f201f6a20096a221f4d0d0a200920072802e00122156a221e20094f0d0b20072802d801201e4102746a2013201f4102746a280200360200200941016a210920072802f401211f2014200c417f6a220c490d000c020b0b20090d0120072802f802210f2014211f0b201f2014417f7322096a220c200f6a221f200c4f0d0920072802e001220c20096a2209200c4f0d0a20072802d80120094102746a20072802f002201f4102746a2802003602000b024020072802f40241ffffffff0371450d0020072802f00210350b20072802d40241ffffffff0371450d0020072802d00210350b02402026450d00202910350b024020072802c40241ffffffff0371450d0020072802c00210350b20220d000b0240201d0d0020072802e001211020072802dc01212020072802d801210f201c1035410021090c130b4101210920072802d401220c4101460d114100200c6b2114201d411f7121134100201d6b411f7121152010410274201c6a417c6a210c417f210903400240200920072802e001221f6a220f2009490d00200f201f41ac95cc001042000b201f200f417f6a221e4d0d09201020096a221f20104f0d0a200c20072802d801221f201e4102746a280200201574201f200f4102746a28020020137672360200200c417c6a210c20142009417f6a2209460d110c000b0b200f200c41ac95cc001042000b2009200c41bc95cc001042000b2009201841bc95cc001042000b2009201841ac95cc001042000b201f200f41ac95cc001042000b201e201541bc95cc001042000b201f200f41ac95cc001042000b2009200c41bc95cc001042000b200f417f6a201f41ac95cc001042000b201f201041bc95cc001042000b41004100419c96cc001042000b200741286a200729035820032008200610980820004100360200200041106a200741286a41086a290300370300200041086a20072903283703000c0f0b20074198026a41086a200741c8016a41086a280200221f360200200720072903c80137039802201f4101201f41014b1b221e41ffffffff0371201e470d00201e410274221b417f4c0d0002400240201b0d00410421170c010b201b10392217450d0c0b201f450d022017201e410274201f4102746b6a210c201f417f6a2114201e201f6b2113200f4101200f41014b1bad21024200210441002109200728029802210f0340201e201320096a22154d0d02200c2004422086200f35020084220420028022013e020020142009460d03200c41046a210c200f41046a210f2004200120027e7d2104201f200941016a22094b0d000b2009201f41ac95cc001042000b1044000b2015201e41bc95cc001042000b2007201e3602f8022007201b4102763602f402200720173602f002200728029c0241ffffffff0371450d0720072802980210350c070b20072802d40121090b20072802e001220c200c20096b220f4d0d012010201020096b22094d0d02201c20094102746a20072802d801200f4102746a280200201d411f717636020041012109201c210f0b024020072802ec0141ffffffff0371450d0020072802e80110350b2009450d0320072802dc0141ffffffff0371450d0320072802d80110350c030b200f200c41ac95cc001042000b2009201041bc95cc001042000b4100211a0240201341ffffffff0371450d00201410350b0b410410332209450d022009410036020041041033220c450d02200c41003602004101211e02400240201a0d002009211a4101212141012118200c210f41012120410121100c010b20091035200c10350b2007201836028002200720213602fc012007201a3602f801200720103602a0022007202036029c022007200f3602980220074198026a10e607420021020240024020072802a00222094105744180014d0d00421d21040c010b4100211e024020090d00420021040c010b200728029802220c200941027422096a417c6a220f280200211f0240200c200f470d00201fad21040c010b200c41786a210f201fad2104200741206a211f4120210c420021020340200741186a200f20096a3502004200200c41e0007110a308201f29030020027c2007290318220220047c2204200254ad7c2102200c41206a210c2009417c6a22094104470d000b0b0240200728029c0241ffffffff0371450d0020072802980210350b201e0d030240200420084201882006423f8684562002200642018822045620022004511b450d0020074188026a41086a200741f8016a41086a280200360200200720072903f80137038802411010332209450d022007420437029c02200720093602980220074198026a41004104108601200741f0026a41086a220920072802a002220c41046a360200200728029802200c4102746a220c428080808010370208200c420037020020072007290398023703f002200741f0026a10e60720074198026a41086a2009280200360200200720072903f00237039802200741f8016a20074188026a20074198026a10e707200728029c0241ffffffff0371450d0020072802980210350b200741f0026a41086a200741f8016a41086a280200360200200720072903f8013703f0020b200741f0026a10e60720074198026a41086a2209200741f0026a41086a280200360200200720072903f0023703980220074198026a10e6074200210202400240200928020022094105744180014d0d00421d21044101211e0c010b4100211e024020090d00420021040c010b200728029802220c200941027422096a417c6a220f280200211f0240200c200f470d00201fad21040c010b200c41786a210f201fad2104200741106a211f4120210c420021020340200741086a200f20096a3502004200200c41e0007110a308201f29030020027c2007290308220220047c2204200254ad7c2102200c41206a210c2009417c6a22094104470d000b0b0240200728029c0241ffffffff0371450d0020072802980210350b02400240201e450d00200041a898cc00360204200041086a4119360200410121090c010b200041106a2002370300200041086a2004370300410021090b20002009360200201141ffffffff0371450d03201210350c030b1045000b103c000b200720043e029c02200741fc95cc003602980241d897cc00412f20074198026a418898cc00419898cc001046000b20074180036a24000b870701047f230041d0006b2208240002400240024002402002200685200320078584500d00200220038450450d01410121090c020b417f20002004852001200585844200522000200454200120055420012005511b1b21090c010b0240200620078450450d0041ff0121090c010b411010332209450d012008420437024420082009360240200841c0006a41004104108601200841306a41086a22092008280248220a41046a3602002008280240200a4102746a220a20003e020c200a20004220883e0208200a20013e0204200a20014220883e020020082008290340370330200841306a10e607200841106a41086a220b20092802003602002008200829033037031041101033220a450d01200842043702442008200a360240200841c0006a4100410410860120092008280248220a41046a3602002008280240200a4102746a220a20063e020c200a20064220883e0208200a20073e0204200a20074220883e020020082008290340370330200841306a10e607200841206a41086a200928020036020020082008290330370320200841c0006a41086a200b280200360200200820082903103703402008200841c0006a200841206a10e8070240200828022441ffffffff0371450d00200828022010350b411010332209450d012008420437024420082009360240200841c0006a41004104108601200841306a41086a22092008280248220a41046a3602002008280240200a4102746a220a20043e020c200a20044220883e0208200a20053e0204200a20054220883e020020082008290340370330200841306a10e607200841106a41086a220b20092802003602002008200829033037031041101033220a450d01200842043702442008200a360240200841c0006a4100410410860120092008280248220a41046a3602002008280240200a4102746a220a20023e020c200a20024220883e0208200a20033e0204200a20034220883e020020082008290340370330200841306a10e607200841206a41086a200928020036020020082008290330370320200841c0006a41086a200b28020036020020082008290310370340200841306a200841c0006a200841206a10e8070240200828022441ffffffff0371450d00200828022010350b2008200841306a10ea0721090240200828023441ffffffff0371450d00200828023010350b200828020441ffffffff0371450d00200828020010350b200841d0006a240020090f0b1045000bbb0703017f067e017f230041d0006b22022400024002400240200029031022032001290310220485200041186a2903002205200141186a29030022068584500d00200041086a290300210720002903002108411010332200450d022002420437024420022000360240200241c0006a41004104108601200241306a41086a22092002280248220041046a360200200228024020004102746a220020083e020c200020084220883e0208200020073e0204200020074220883e020020022002290340370330200241306a10e607200241106a41086a200928020036020020022002290330370310411010332200450d022002420437024420022000360240200241c0006a41004104108601200241306a41086a22092002280248220041046a360200200228024020004102746a220020043e020c200020044220883e0208200020063e0204200020064220883e020020022002290340370330200241306a10e607200241206a41086a200928020036020020022002290330370320200241c0006a41086a200241106a41086a280200360200200220022903103703402002200241c0006a200241206a10e8070240200228022441ffffffff0371450d00200228022010350b200141086a290300210420012903002106411010332200450d022002420437024420022000360240200241c0006a41004104108601200241306a41086a22002002280248220141046a360200200228024020014102746a220120063e020c200120064220883e0208200120043e0204200120044220883e020020022002290340370330200241306a10e607200241106a41086a2209200028020036020020022002290330370310411010332201450d022002420437024420022001360240200241c0006a4100410410860120002002280248220141046a360200200228024020014102746a220120033e020c200120034220883e0208200120053e0204200120054220883e020020022002290340370330200241306a10e607200241206a41086a200028020036020020022002290330370320200241c0006a41086a200928020036020020022002290310370340200241306a200241c0006a200241206a10e8070240200228022441ffffffff0371450d00200228022010350b2002200241306a10ea0721000240200228023441ffffffff0371450d00200228023010350b200041ff017121000240200228020441ffffffff0371450d00200228020010350b20004521000c010b2000290300200129030085200041086a290300200141086a29030085845021000b200241d0006a240020000f0b1045000bae380b147f017e017f017e017f017e017f017e017f017e0e7f23004180036b220524000240024020014115490d004101210641012107024002400240034020012108200021092006200771410173210a02400240024002400240024003400240024002402004450d00024020064101710d002000200110ff062004417f6a21040b20052002360208200520003602502005200136025420052001410276220b36020c2005200b410174220c3602102005200b41036c220d360214200541003602182005200541186a3602d8012005200541d0006a3602d4012005200541086a3602d0012005200541d0016a36021c024020014132490d002005200b417f6a3602202005200b41016a3602d0022005411c6a200541206a2005410c6a200541d0026a1080072005200c417f6a3602202005200c4101723602d0022005411c6a200541206a200541106a200541d0026a1080072005200d417f6a3602202005200d41016a3602d0022005411c6a200541206a200541146a200541d0026a1080070b2005411c6a2005410c6a200541106a200541146a1080072005280218220b410b4b0d01200b45210b2005280210210e0c020b2000200120021081070c0e0b02402005280254220c410176220d450d002005280250220b200c41306c6a41506a210c0340200541d0026a41286a220f200b41286a2210290300370300200541d0026a41206a2211200b41206a2212290300370300200541d0026a41186a220e200b41186a2213290300370300200541d0026a41106a2214200b41106a2215290300370300200541d0026a41086a2216200b41086a22172903003703002005200b2903003703d002200c41086a22182903002119200c41106a221a290300211b200c41186a221c290300211d200c41206a221e290300211f200c41286a22202903002121200b200c290300370300201020213703002012201f3703002013201d3703002015201b370300201720193703002020200f290300370300201e2011290300370300201c200e290300370300201a201429030037030020182016290300370300200c20052903d002370300200c41506a210c200b41306a210b200d417f6a220d0d000b0b20012005280210417f736a210e4101210b0b0240200b45200a724101710d002000200120021082070d0d0b02402003450d00200e20014f0d030240200228020028020028020022142802002211450d00201428020421122011211002400340201041086a210c20102f01062213410574210b4100210d024002400340200b450d012003200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21130b024020120d004200211b420021190c030b2012417f6a2112201020134102746a41c8056a28020021100c010b0b2010200d4105746a220b41f0026a2903002119200b41e8026a290300211b0b2011450d002000200e41306c6a2110201428020421120340201141086a210c20112f01062213410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21130b2012450d022012417f6a2112201120134102746a41c8056a28020021110c010b0b201b2011200d4105746a220b41e8026a290300542019200b41f0026a290300221b542019201b511b450d0020002109200121080c030b200541d0026a41286a221a200041286a2222290300370300200541d0026a41206a221c200041206a2223290300370300200541d0026a41186a221e200041186a2224290300370300200541d0026a41106a2220200041106a2207290300370300200541d0026a41086a2225200041086a2226290300370300200520002903003703d0022000200e41306c6a220b41086a220c2903002119200b41106a220d290300211b200b41186a220f290300211d200b41206a2210290300211f200b41286a221129030021212000200b290300370300202220213703002023201f3703002024201d3703002007201b370300202620193703002011201a2903003703002010201c290300370300200f201e290300370300200d2020290300370300200c2025290300370300200b20052903d002370300200541d0016a41286a22272022290300370300200541d0016a41206a22282023290300370300200541d0016a41186a22292024290300370300200541d0016a41106a222a2007290300370300200541d0016a41086a222b2026290300370300200520002903003703d001200041306a21184100210e200121140340200228020021170240200e2014417f6a22154f0d00201728020028020022162802002113034002402013450d00201628020421112013211002400340201041086a210c20102f01062212410574210b4100210d024002400340200b450d01200541d0016a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21120b024020110d004200211b420021190c030b2011417f6a2111201020124102746a41c8056a28020021100c010b0b2010200d4105746a220b41f0026a2903002119200b41e8026a290300211b0b2013450d002018200e41306c6a211020162802042112201321110340201141086a210c20112f01062214410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21140b2012450d022012417f6a2112201120144102746a41c8056a28020021110c010b0b201b2011200d4105746a220b41e8026a2903005a2019200b41f0026a290300221b5a2019201b511b450d020b200e41016a220e2015470d000b2015210e0b02400340200e201522144f0d010240201728020028020022162802002211450d002014417f6a2115201628020421122011211002400340201041086a210c20102f01062213410574210b4100210d024002400340200b450d01200541d0016a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21130b024020120d004200211b420021190c030b2012417f6a2112201020134102746a41c8056a28020021100c010b0b2010200d4105746a220b41f0026a2903002119200b41e8026a290300211b0b2011450d002000201441306c6a2110201628020421120340201141086a210c20112f01062213410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21130b2012450d022012417f6a2112201120134102746a41c8056a28020021110c010b0b201b2011200d4105746a220b41e8026a290300542019200b41f0026a290300221b542019201b511b0d010b0b201a2018200e41306c6a220b41286a220d290300370300201c200b41206a220f290300370300201e200b41186a22102903003703002020200b41106a22112903003703002025200b41086a22122903003703002005200b2903003703d0022000201441306c6a220c41086a22132903002119200c41106a2215290300211b200c41186a2216290300211d200c41206a2217290300211f200c41286a222c2903002121200b200c290300370300200d2021370300200f201f3703002010201d3703002011201b37030020122019370300202c201a2903003703002017201c2903003703002016201e2903003703002015202029030037030020132025290300370300200c20052903d002370300200e41016a210e0c010b0b200020052903d0013703002022202729030037030020232028290300370300202420292903003703002007202a2903003703002026202b2903003703002001200e41016a220b490d042000200b41306c6a21002001200b6b220141154f0d010c0c0b0b2008450d030b200e20084f0d03200541d0026a41286a2220200941286a2226290300370300200541d0026a41206a2225200941206a2227290300370300200541d0026a41186a222c200941186a2228290300370300200541d0026a41106a2222200941106a2229290300370300200541d0026a41086a2223200941086a222a290300370300200520092903003703d0022009200e41306c6a220b41086a220c2903002119200b41106a220d290300211b200b41186a220f290300211d200b41206a2210290300211f200b41286a221129030021212009200b290300370300202620213703002027201f3703002028201d3703002029201b370300202a20193703002011202029030037030020102025290300370300200f202c290300370300200d2022290300370300200c2023290300370300200b20052903d002370300200541206a41286a222b2026290300370300200541206a41206a22062027290300370300200541206a41186a220a2028290300370300200541206a41106a222d2029290300370300200541206a41086a222e202a29030037030020052009290300370320200941306a21002002280200211602402008417f6a22170d00410021240c050b2016280200280200221428020021134100212403402013450d052000202441306c6a2110201428020421122013211102400340201141086a210c20112f0106220e410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a210e0b024020120d004200211b420021190c030b2012417f6a21122011200e4102746a41c8056a28020021110c010b0b2011200d4105746a220b41f0026a2903002119200b41e8026a290300211b0b2013450d0520142802042111201321100340201041086a210c20102f01062212410574210b4100210d024002400340200b450d01200541206a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21120b2011450d072011417f6a2111201020124102746a41c8056a28020021100c010b0b201b2010200d4105746a220b41e8026a290300542019200b41f0026a290300221b542019201b511b450d05202441016a22242017470d000b201721240c040b200e200141d086cc001042000b200b200141e485cc001059000b4100410041f485cc001042000b200e2008418486cc001042000b2017210b02400340200b221420244d22070d010240024002402016280200280200221528020022120d004200211f4200211b0c010b2009201441306c6a21102015280204210e2012211102400340201141086a210c20112f01062213410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21130b0240200e0d004200211f4200211b0c030b200e417f6a210e201120134102746a41c8056a28020021110c010b0b2011200d4105746a220b41f0026a290300211b200b41e8026a290300211f0b2012450d00201528020421100340201241086a210c20122f01062211410574210b4100210d024002400340200b450d01200541206a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21110b2010450d022010417f6a2110201220114102746a41c8056a28020021120c010b0b2012200d4105746a220b41f0026a2903002119200b41e8026a290300211d0c010b4200211d420021190b2014417f6a210b201f201d5a201b20195a201b2019511b0d000b0b20142024490d0320172014490d022000201441306c6a2117418001211c410021154100211a4100211441002118418001211e2000202441306c6a222f21000340201720006b220b41306e210c0240200b41afe0004b22010d00200c41807f6a200c201a2015492018201449220d72220f1b210b0240200f450d00201e200b200d1b211e200b201c200d1b211c0c010b200b200b410176221e6b211c0b024020182014470d000240201e0d00200541d0006a221421180c010b41002113200541d0006a2114200021100340201420133a0000201341016a21130240024002402002280200280200280200221828020022120d004200211d420021190c010b2018280204210e2012211102400340201141086a210c20112f01062216410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21160b0240200e0d004200211d420021190c030b200e417f6a210e201120164102746a41c8056a28020021110c010b0b2011200d4105746a220b41f0026a2903002119200b41e8026a290300211d0b2012450d00201828020421110340201241086a210c20122f0106220e410574210b4100210d024002400340200b450d01200541206a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a210e0b2011450d022011417f6a21112012200e4102746a41c8056a28020021120c010b0b2012200d4105746a220b41f0026a290300211b200b41e8026a290300211f0c010b4200211f4200211b0b2014201d201f5a2019201b5a2019201b511b6a2114201041306a21102013201e470d000b200541d0006a21180b0240201a2015470d000240201c0d00200541d0016a2215211a0c010b41002113200541d0016a2115201721100340201520133a0000201041506a2110201341016a21130240024002402002280200280200280200221a28020022120d004200211d420021190c010b201a280204210e2012211102400340201141086a210c20112f01062216410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21160b0240200e0d004200211d420021190c030b200e417f6a210e201120164102746a41c8056a28020021110c010b0b2011200d4105746a220b41f0026a2903002119200b41e8026a290300211d0b2012450d00201a28020421110340201241086a210c20122f0106220e410574210b4100210d024002400340200b450d01200541206a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a210e0b2011450d022011417f6a21112012200e4102746a41c8056a28020021120c010b0b2012200d4105746a220b41f0026a290300211b200b41e8026a290300211f0c010b4200211f4200211b0b2015201d201f542019201b542019201b511b6a21152013201c470d000b200541d0016a211a0b02402015201a6b220b201420186b220c200c200b4b1b2211450d002020200020182d000041306c6a220b41286a2903003703002025200b41206a290300370300202c200b41186a2903003703002022200b41106a2903003703002023200b41086a2903003703002005200b2903003703d002200020182d000041306c6a220b2017201a2d0000417f7341306c6a220c290300370300200b41286a200c41286a290300370300200b41206a200c41206a290300370300200b41186a200c41186a290300370300200b41106a200c41106a290300370300200b41086a200c41086a290300370300024020114101460d004100210d03402017201a200d6a220f2d0000417f7341306c6a220b20002018200d6a41016a22102d000041306c6a220c290300370300200b41286a200c41286a290300370300200b41206a200c41206a290300370300200b41186a200c41186a290300370300200b41106a200c41106a290300370300200b41086a200c41086a290300370300200020102d000041306c6a220b2017200f41016a2d0000417f7341306c6a220c290300370300200b41286a200c41286a290300370300200b41206a200c41206a290300370300200b41186a200c41186a290300370300200b41106a200c41106a290300370300200b41086a200c41086a290300370300200d41026a210b200d41016a220c210d200b2011490d000b201a200c6a211a2018200c6a21180b2017201a2d0000417f7341306c6a220b20052903d002370300200b41286a2020290300370300200b41206a2025290300370300200b41186a202c290300370300200b41106a2022290300370300200b41086a2023290300370300201a41016a211a201841016a21180b2000201e41306c6a200020182014461b210020174100201c6b41306c6a2017201a2015461b211720010d000b02400240201820144f0d002017210b0340202020002014417f6a22142d000041306c6a220c41286a220d2903003703002025200c41206a220f290300370300202c200c41186a22102903003703002022200c41106a22112903003703002023200c41086a22122903003703002005200c2903003703d002200b41506a220b41086a220e2903002119200b41106a2213290300211b200b41186a2215290300211d200b41206a2216290300211f200b41286a22172903002121200c200b290300370300200d2021370300200f201f3703002010201d3703002011201b3703002012201937030020172020290300370300201620252903003703002015202c29030037030020132022290300370300200e2023290300370300200b20052903d00237030020182014490d000c020b0b2000210b201a20154f0d0003402015417f6a22152d0000210c2020200b41286a220d2903003703002025200b41206a220f290300370300202c200b41186a22102903003703002022200b41106a22112903003703002023200b41086a22122903003703002005200b2903003703d0022017200c417f7341306c6a220c41086a220e2903002119200c41106a2213290300211b200c41186a2214290300211d200c41206a2216290300211f200c41286a22002903002121200b200c290300370300200d2021370300200f201f3703002010201d3703002011201b3703002012201937030020002020290300370300201620252903003703002014202c29030037030020132022290300370300200e2023290300370300200c20052903d002370300200b41306a210b201a2015490d000b0b200920052903203703002026202b290300370300202720062903003703002028200a2903003703002029202d290300370300202a202e29030037030002402008200b202f6b41306e20246a22014d0d002020202629030037030020252027290300370300202c2028290300370300202220292903003703002023202a290300370300200520092903003703d0022009200141306c6a220b41086a220c2903002119200b41106a220d290300211b200b41186a220f290300211d200b41206a2210290300211f200b41286a221129030021212009200b290300370300202620213703002027201f3703002028201d3703002029201b370300202a20193703002011202029030037030020102025290300370300200f202c290300370300200d2022290300370300200c2023290300370300200b20052903d002370300200820016b220c450d02200c20012001200c4b1b210d2008410376210f200b41306a2100024002402001200c417f6a220c490d002000200c2002200b2004109e04200921000c010b20092001200220032004109e04200b2103200c21010b200d200f4f2106200141154f0d010c050b0b20012008418486cc001042000b41a486cc00411c41c086cc00103f000b20142017419486cc001058000b20242014419486cc001059000b20014102490d004101210b03402000200b41016a220b20021083072001200b470d000b0b20054180036a24000bad0302027f037e230041d0006b22042400200441386a20024201200242015620034200522003501b22051b22022003420020051b220342ffff034200109808200441286a20042903382206200441386a41086a290300220742ffff034200108408200441186a20022003200620022004290328852003200441286a41086a2903008584420052ad7c22084201200842015620072008200654ad7c22064200522006501b22051b22082006420020051b22061098080240024002402004290318220742808004544100200441186a41086a290300501b450d00200441086a200220002002200054200320015420032001511b22051b2003200120051b200820061098082004290308220342808004544100200441086a41086a290300501b450d012007a741ffff037122050d024190edc40041194180efc400103f000b2004411136024c20044190efc40036024841bcedc40041de00200441c8006a41acedc400419ceec4001046000b2004411136024c20044190efc40036024841bcedc40041de00200441c8006a41acedc40041f0eec4001046000b200441d0006a24002003a741ffff037141ffff036c20056e0b810103017f017e027f230041106b220324000240024002402002ad4220862000ad84102a2204428080808010540d00410121022004a722052d0000220641014b0d0020060e020102010b41b89acc00412e200341086a41c09bcc0041e89acc001046000b410021020b2005103502402001450d00200010350b200341106a240020020b13002000410b360204200041c4eec3003602000b3400200041fafdc60036020420004100360200200041146a4104360200200041106a41e8a9c400360200200041086a42083702000b930301027f024020002802082201450d0020002802002202200141c8006c6a21010340024020022d00004101470d00200241086a280200450d00200241046a28020010350b0240200241246a2d00004101470d002002412c6a280200450d00200241286a28020010350b200241c8006a22022001470d000b0b0240200041046a2802002202450d00200241c8006c450d00200028020010350b024020002d000c4101470d00200041146a280200450d00200041106a28020010350b024020002d00304101470d00200041386a280200450d00200041346a28020010350b024020002d00544101470d00200041dc006a280200450d00200041d8006a28020010350b024020002d00784101470d0020004180016a280200450d00200041fc006a28020010350b024020002d009c014101470d00200041a4016a280200450d00200041a0016a28020010350b024020002d00c0014101470d00200041c8016a280200450d00200041c4016a28020010350b024020002d00e4014101470d00200041ec016a280200450d00200041e8016a28020010350b0b13002000410636020420004188b3c4003602000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241143600000b2d01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241e4003600000b3901017f02404110103322020d001045000b200242003700082002428080d287e2bc2d370000200042908080808002370204200020023602000b3901017f02404110103322020d001045000b2002420037000820024280c0c6c9faeb38370000200042908080808002370204200020023602000b3a01017f02404110103322020d001045000b2002420037000820024280809aa6eaafe301370000200042908080808002370204200020023602000bde0102027f017e230041106b2202240002402000280200220341064b0d00024002400240024002400240024020030e0700010203040506000b200241003a000020012002410110780c060b200241013a00002001200241011078200029030821042002200041106a2903003703082002200437030020012002411010780c050b200241023a000020012002410110780c040b200241033a000020012002410110780c030b200241043a000020012002410110780c020b200241053a000020012002410110780c010b200241063a000020012002410110780b200241106a24000bfa0301047f230041106b2202240020002802002103200028020822042001107702402004450d002003200441c8006c6a210503402002200310ac042001200228020022042002280208107802402002280204450d00200410350b2002200341246a220310ac042001200228020022042002280208107802402002280204450d00200410350b200341246a22032005470d000b0b20022000410c6a10ac042001200228020022032002280208107802402002280204450d00200310350b2002200041306a10ac042001200228020022032002280208107802402002280204450d00200310350b2002200041d4006a10ac042001200228020022032002280208107802402002280204450d00200310350b2002200041f8006a10ac042001200228020022032002280208107802402002280204450d00200310350b20022000419c016a10ac042001200228020022032002280208107802402002280204450d00200310350b0240024020002d0088024101460d00200241003a000020012002410110780c010b200241013a00002001200241011078200120004189026a411410780b2002200041c0016a10ac042001200228020022032002280208107802402002280204450d00200310350b2002200041e4016a10ac042001200228020022032002280208107802402002280204450d00200310350b200241106a24000bd10201057f230041106b22022400024002400240024002400240024002400240024020012d00000e06010203040500010b20024181ca003b01082002200141216a3602042002200141016a3602000c050b410110392201450d062000428180808010370204200020013602000c050b2001410c6a22032802002204412020044120491b220541016a220410332206450d05200620042004109f082106200328020022032005490d06200641016a200141046a2802002005109d081a2000200436020820002004360204200020063602000c040b20024181c4003b01082002200141216a3602042002200141016a3602000c020b20024181c6003b01082002200141216a3602042002200141016a3602000c010b20024181c8003b01082002200141216a3602042002200141016a3602000b2000200210cc070b200241106a24000f0b1045000b2005200341c4e7cb001058000b8611010a7f23004180016b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a2207360200200541254b0d014100210820050e261301010101010101010101010101010101010101010101010101010101010101010102030405130b200041063a00000c130b02402005417f6a41ff01714121490d00200041063a00000c130b02402005417f6a22090d0020012006360204200120073602004101210a410021094100210b410121080c120b0240024020091039220a450d0020012802042009490d01200a20012802002009109d081a200128020422052009490d062001200520096b3602042001200128020020096a360200410121082009210b0c130b1045000b200041063a0000200a10350c120b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c100b41012101200541ff01710d040c0e0b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c0d0b41012101200541ff01710d040c0b0b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c0a0b41012101200541ff01710d040c080b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c070b41012101200541ff01710d040c050b2009200541a4f0cb001059000b200241003a00780c090b200241003a00780c060b200241003a00780c030b200241003a00780b0b2002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b012420022002290328370310410521080c070b200041063a00000c070b0b2002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b012420022002290328370310410421080c050b200041063a00000c050b0b2002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b012420022002290328370310410321080c030b200041063a00000c030b0b410221082002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b0124200220022903283703100c010b200041063a00000c010b200020083a0000200020022f01243b00012000410c6a2009360000200041086a200b360000200041046a200a360000200041106a2002290310370000200041216a20022f000d3b0000200041036a200241246a41026a2d00003a0000200041186a200241106a41086a290300370000200041206a200241106a41106a2d00003a0000200041236a2002410d6a41026a2d00003a00000b20024180016a24000be40701087f230041d00b6b22042400024020002802000d002000417f360200200441206a41186a200141186a290000370300200441206a41106a200141106a290000370300200441206a41086a200141086a2900003703002004200129000037032002400240024020002802042205450d00200041086a28020021060c010b41002106200441f0086a410041e002109f081a200441d0006a410041a008109f081a41880b10332205450d01200541003b010620054100360200200541086a200441f0086a41e002109d081a200541e8026a200441d0006a41a008109d081a200041086a4100360200200020053602040b2004200041046a22073602f808200420053602f408200420063602f008034020052f010622084105742109410021014100210a024002400240034020092001460d010240200441206a200520016a41086a412010a008220b0d00410021012006210b0c030b200141206a2101200a41016a210a200b417f4a0d000b200a417f6a21080b20060d01410121014100210b2008210a0b200441d0006a41106a200a360200200441d0006a410c6a2007360200200441d0006a41086a2005360200200420073602f808200420053602f408200420063602f0082004200b360254200420013602504101210902402001450d00200441186a200441206a41186a290300370300200441106a200441206a41106a290300370300200441086a200441206a41086a29030037030020042004290320370300410021090b0240024020090d002004418c096a200441086a29030037020020044194096a200441106a2903003702002004419c096a200441186a29030037020020042000410c6a360280092004200a3602fc08200420073602f808200420053602f4082004200b3602f0082004200429030037028409200441f0006a2004290340370300200441f8006a200441c0006a41086a29030037030020044188016a41003602002004420037036820044200370350200441003a008c0120044100360280012004418d016a200429002037000020044195016a200441206a41086a2900003700002004419d016a200441206a41106a290000370000200441a5016a200441206a41186a290000370000200441003a00ad01200441f0086a200441d0006a10800321010c010b200441e4006a410036020020044100360270200441003602542005200a41e0006c6a41e8026a2101200441d0006a1081030b200141106a200337030020012002370308200142013703002000200028020041016a360200200441d00b6a24000f0b2006417f6a2106200520084102746a41880b6a28020021050c000b0b103c000b41a797cc004110200441d0006a41c8c1c30041c897cc001046000bef0801087f230041d00b6b22042400024020002802000d002000417f360200200441206a41186a200141186a290000370300200441206a41106a200141106a290000370300200441206a41086a200141086a2900003703002004200129000037032002400240024020002802042205450d00200041086a28020021060c010b41002106200441f0086a410041e002109f081a200441d0006a410041a008109f081a41880b10332205450d01200541003b010620054100360200200541086a200441f0086a41e002109d081a200541e8026a200441d0006a41a008109d081a200041086a4100360200200020053602040b2004200041046a22073602f808200420053602f408200420063602f008034020052f010622084105742109410021014100210a024002400240034020092001460d010240200441206a200520016a41086a412010a008220b0d00410021012006210b0c030b200141206a2101200a41016a210a200b417f4a0d000b200a417f6a21080b20060d01410121014100210b2008210a0b200441d0006a41106a200a360200200441d0006a410c6a2007360200200441d0006a41086a2005360200200420073602f808200420053602f408200420063602f0082004200b360254200420013602504101210902402001450d00200441186a200441206a41186a290300370300200441106a200441206a41106a290300370300200441086a200441206a41086a29030037030020042004290320370300410021090b0240024020090d002004418c096a200441086a29030037020020044194096a200441106a2903003702002004419c096a200441186a29030037020020042000410c6a360280092004200a3602fc08200420073602f808200420053602f4082004200b3602f0082004200429030037028409200441f0006a2004290340370300200441f8006a200441c0006a41086a29030037030020044188016a41003602002004420037036820044200370350200441003a008c0120044100360280012004418d016a200429002037000020044195016a200441206a41086a2900003700002004419d016a200441206a41106a290000370000200441a5016a200441206a41186a290000370000200441003a00ad01200441f0086a200441d0006a10800321010c010b200441e4006a410036020020044100360270200441003602542005200a41e0006c6a41e8026a2101200441d0006a1081030b200441d0006a41186a200241186a290000370300200441d0006a41106a200241106a290000370300200441d0006a41086a200241086a29000037030020042002290000370350200441206a41086a200341086a28020036020020042003290200370320200441f0086a200141306a200441d0006a200441206a108303024020042802f008450d0020042802f4082201450d00200441f8086a280200450d00200110350b2000200028020041016a360200200441d00b6a24000f0b2006417f6a2106200520084102746a41880b6a28020021050c000b0b103c000b41a797cc004110200441d0006a41c8c1c30041c897cc001046000b920402087f027e230041106b22022400200241003602082002420137030020002802102103200041186a2802002204200210770240024002402004450d00200320044105746a21050340200328020021060240024020022802042207200228020822046b4104490d00200228020021080c010b200441046a22082004490d03200741017422092008200920084b1b22094100480d030240024020070d00024020090d00410121080c020b2009103322080d010c060b2002280200210820072009460d0020082007200910372208450d050b20022009360204200220083602000b200820046a20063600002002200441046a360208200341086a200210aa042005200341206a2203470d000b0b200041086a290300210a2000290300210b0240024020022802042207200228020822036b4110490d00200341106a2104200228020021080c010b200341106a22042003490d01200741017422082004200820044b1b22064100480d010240024020070d00024020060d00410121080c020b200610332208450d040c010b2002280200210820072006460d0020082007200610372208450d030b20022006360204200220083602000b200820036a2203200a3700082003200b370000200220043602082000411c6a200210ab04200228020421032001290200200235020842208620022802002204ad84100202402003450d00200410350b200241106a24000f0b103e000b103c000bdf2204137f017e017f087e230041a0026b22032400024002400240024002400240024002400240024002400240024002400240024020012d00000e050001020304000b200341b4016a4101360200200342013702a401200341e8d4ca003602a0012003410436027c2003419cd5ca003602782003200341f8006a3602b001200341a0016a41b0b4cc00104c000b4102210402400240024020022d00000d0020022d00014101470d00200141046a2802002101200241196a2d00002104200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a290100370320200320043a001f200320053a001e200320063b011c200320073a001b200320083a001a200320093b01182003200a3a00172003200b3a00162003200c3b01142003200d3a00132003200e3a00122003200f3b0110200320103a000f200320113a000e200320123b010c200320133a000b200320143a000a200320153b0108200341286a2001109604200341a0016a200328022822052003280230220b10cb02200341f8006a41086a2202200341a0016a41106a290300370300200341f8006a41106a2204200341a0016a41186a290300370300200341f8006a41186a2206200341c0016a290300370300200320032903a8013703780240024020032903a0014201520d00200341386a41186a2006290300370300200341386a41106a2004290300370300200341386a41086a200229030037030020032003290378370338410321044100210241f6b5c300210741052106410221084105210a0c010b200341386a41086a200341086a41086a290300370300200341386a41106a200341086a41106a290300370300200341386a41186a200341086a41186a29030037030020032003290308370338200342003703682003428080e983b1de163703602003200341086a36025c2003200341086a3602742003200341f4006a3602a8012003200341dc006a3602a4012003200341e0006a3602a001200341f8006a200341086a200341a0016a108c030240024020032802784101470d0020032f007d20032d007f41107472220641107621092006410876210820034184016a280200210a200341f8006a41086a280200210720032d007c210c0c010b4104210c0240200341f8006a41086a2903004201520d00200341f8006a41106a290300211620032802742102200341d8016a200341f8006a41186a290300370300200341d0016a2016370300200341a0016a41086a41003a0000200341a9016a2002290000370000200341b1016a200241086a290000370000200341b9016a200241106a290000370000200341c1016a200241186a290000370000200341033a00a00141b0b4cc004100200341a0016a10d4010b0b41042104410021020240200c41ff01714104460d00200c21040c010b200341d0016a4200370300200341c8016a428080e983b1de16370300200341a0016a41106a200341386a41086a290300370300200341a0016a41186a200341386a41106a290300370300200341c0016a200341386a41186a290300370300200342013703a001200320032903383703a8012003200b36027c20032005360278200341a0016a41086a200341f8006a10b204410121020b0240200328022c450d00200510350b20020d02200941ff0171411074200841ff017141087472200641ff0171724108742102200aad4220862007ad8421160c010b410021020b200042003703082000411c6a2016370200200041186a2002200441ff017172360200420121160c0e0b200341c8016a2001360200200341ad016a200341106a290300370000200341b5016a200341186a290300370000200341bd016a200341206a290300370000200341003a00a401200341023a00a001200320032903083700a50141b0b4cc004100200341a0016a10d401420021160c0a0b200141246a2802002105200341386a41186a200141196a290000370300200341386a41106a200141116a290000370300200341386a41086a200141096a29000037030020032001290001370338410221014100210420022d00000d0a20022d00014101470d0a200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211720032002411a6a29010037039001200320013a008f01200320063a008e01200320073b018c01200320083a008b01200320093a008a012003200a3b0188012003200b3a0087012003200c3a0086012003200d3b0184012003200e3a0083012003200f3a008201200320103b018001200320113a007f200320123a007e200320133b017c200320143a007b200320153a007a200320173b01780240200341f8006a200341386a412010a0080d0041ebb5c3002102410b21074103210141800a21064180800c21050c0c0b200341e0006a2005109604200341a0016a200328026022042003280268220910cb02410321014105210641002107024020032903a0014201510d004183b6c3002102420b2116410021080c090b200341d0016a2903002118200341c8016a2903002119200341b0016a22022903002116200341a0016a41206a290300211a20032903a801211b2002200341b8016a2903003703002003201a3703b8012003201b3703a001200320163703a801200341a0016a200341f8006a412010a0080d02200341086a200341f8006a200341386a20192018410110ef02200341086a41086a290300211b0240024020032802084101460d004200211642002018200341086a41106a2903007d2019201b54ad7d221a2019201b7d221b201956201a201856201a2018511b22021b21184200201b20021b2119200341386a41106a290300211c2003290340211d2003290338211e2003290350211a4201211b4100210741002108410021060c010b201b4220882116200328020c220141187621072001411076210820014108762106201ba72102200141ff01714104470d094200211b0b200341d0016a2018370300200341c8016a2019370300200341c0016a201a3703002003201b3703a001200341b8016a201c3703002003201e3703a8012003201d3703b00102400240201b4201510d002009ad4220862004ad8410070c010b2003200936020c20032004360208200341a8016a200341086a10b2040b410421010c080b41022104024020022d00000d0020022d00014101470d00200141046a2802002101200241196a2d00002104200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a290100370320200320043a001f200320053a001e200320063b011c200320073a001b200320083a001a200320093b01182003200a3a00172003200b3a00162003200c3b01142003200d3a00132003200e3a00122003200f3b0110200320103a000f200320113a000e200320123b010c200320133a000b200320143a000a200320153b0108200341286a2001109604200341a0016a200328022822052003280230220610cb024103210441800a2102024020032903a0014201510d004280808080b00121164183b6c30021060c060b200341d0016a2903002119200341c8016a290300211b200341a0016a41106a2903002116200341a0016a41206a290300211a20032903a8012118200341386a41106a200341b8016a2903003703002003201a3703502003201837033820032016370340200341386a200341086a412010a0080d032003201b370360200320193703680240201b201984500d002003200341086a360274200341f8006a200341086a200341e0006a200341f4006a10f00220032903784201520d002003290380012116200341d8016a200341f8006a41106a290300370300200341d0016a2016370300200341a0016a41086a41003a0000200341a9016a2003290308370000200341b1016a200341086a41086a290300370000200341b9016a200341086a41106a290300370000200341c1016a200341206a290300370000200341033a00a00141b0b4cc004100200341a0016a10d4010b2006ad4220862005ad84100741042104420021160c050b410021020c050b20022d000120022d0000410047720d02200141116a290000211a200141096a2900002118200141196a29000021192001290001211b200341e0006a200141246a2802002207109604200341a0016a200328026022022003280268220810cb02200341d0016a2101200341c8016a2104200341b8016a2105200341c0016a2106024020032903a0014201520d00200129030021162004290300211c200341a0016a41106a290300211d2006290300211e20032903a801211f200341386a41106a20052903003703002003201e3703502003201f3703382003201d3703402003201c37030820032016370310201c201684500d002003200341386a360228200341f8006a200341386a200341086a200341286a10f00220032903784201520d002003290380012116200341d8016a200341f8006a41106a290300370300200341d0016a2016370300200341a0016a41086a41003a0000200341a9016a2003290338370000200341b1016a200341386a41086a290300370000200341b9016a200341386a41106a290300370000200341c1016a200341d0006a290300370000200341033a00a00141b0b4cc004100200341a0016a10d4010b420021162001420037030020044200370300200620193703002005201a3703002003201b3703a801200342013703a001200320183703b0012003200836027c20032002360278200341a8016a200341f8006a10b20402402003280264450d00200210350b200341ad016a2018370000200341c8016a2007360200200341bd016a2019370000200341b5016a201a3700002003201b3700a501200341003a00a401200341023a00a00141b0b4cc004100200341a0016a10d4010c070b41fbb5c300210242082116410121080c050b41808a04210242808080808001211641fbb5c30021060c010b20004200370308200041186a4102360200420121160c070b0240200328022c450d00200510350b20044104460d0120162006ad8421160b200042003703082000411c6a2016370200200041186a2002200472360200420121160c050b200341a8016a2001360200200341013a00a401200341023a00a00141b0b4cc004100200341a0016a10d401420021160c010b02402003280264450d00200410350b0240200141ff01714104460d002007411874210420064108744180fe037121062008411074418080fc077121052016a721070c030b200341c8016a2005360200200341ad016a200341c0006a290300370000200341b5016a200341c8006a290300370000200341bd016a200341d0006a290300370000200341003a00a401200341023a00a001200320032903383700a50141b0b4cc004100200341a0016a10d401420021160b200020163703080c020b41002105410021060b200041206a20073602002000411c6a200236020020004200370308200041186a2004200572200672200141ff017172360200420121160b20002016370300200341a0026a24000ba90102017f027e02400240411010332202450d0020024110412010372202450d0120022000290000370000200241186a200041186a290000370000200241106a200041106a290000370000200241086a200041086a290000370000200041286a2903002103200029032021042002412041c00010372200450d0120002004370020200041286a200337000020012902002000ad42808080808006841002200010350f0b1045000b103c000b9aa90105037f017e137f077e107f230041f0126b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0c000102030405060708090a0b000b200341c4106a4101360200200342013702b410200341e8d4ca003602b0102003410436029c0b2003419cd5ca003602980b2003200341980b6a3602c010200341b0106a41b0b4cc00104c000b200241036a2d0000210420022f00012105200141196a2900002106200141186a2d00002107200141176a2d00002108200141156a2f00002109200141146a2d0000210a200141136a2d0000210b200141116a2f0000210c200141106a2d0000210d2001410f6a2d0000210e2001410d6a2f0000210f2001410c6a2d000021102001410b6a2d00002111200141096a2f00002112200141086a2d00002113200141076a2d00002114200141056a2f00002115200141046a2d00002116200141036a2d0000211720012f000121180240024002400240024020022d00002219417f6a220141024b0d00024020010e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200520044110747220194100477241ff01710d010b41fafdc600ad428080808080018410012202290000211a2002290008211b2002103541e8adc400ad4280808080a0018410012202290000211c2002290008211d200210352003201d3703b00b2003201c3703a80b2003201b3703a00b2003201a3703980b200341b0106a200341980b6a10dc020240024020032802b01022020d0041002105200341003602a00620034208370398064101210141082102410021040c010b200320032902b410221a37029c062003200236029806201a422088a722044114492101201aa721050b200320063703e008200320073a00df08200320083a00de08200320093b01dc082003200a3a00db082003200b3a00da082003200c3b01d8082003200d3a00d7082003200e3a00d6082003200f3b01d408200320103a00d308200320113a00d208200320123b01d008200320133a00cf08200320143a00ce08200320153b01cc08200320163a00cb08200320173a00ca08200320183b01c8082001450d01200341b0106a41186a2207200341c8086a41186a290300370300200341b0106a41106a2208200341c8086a41106a290300370300200341b0106a41086a2209200341c8086a41086a290300370300200320032903c8083703b010024020042005470d0020034198066a2004109401200328029c062105200328029806210220032802a00621040b200220044106746a2201420037030820014201370300200141106a4200370300200141186a4200370300200141206a20032903b010370300200141286a2009290300370300200141306a2008290300370300200141386a20072903003703002003200441016a22073602a00641fafdc600ad42808080808001841001220129000021062001290008211a2001103541e8adc400ad4280808080a0018410012201290000211b2001290008211c200110352003201c3703b00b2003201b3703a80b2003201a3703a00b200320063703980b0240024020020d00200341980b6aad428080808080048410070c010b200341b0106a2002200710b404200341980b6aad428080808080048420033502b81042208620032802b0102201ad841002024020032802b410450d00200110350b200541ffffff1f71450d00200210350b200341bc106a2004360200200341b8106a41063a0000200341113a00b01041b0b4cc004100200341b0106a10d401200041106a2007ad42f0c8217e4280a3c3c7007c37030020004201370308200042003703000c1d0b200341023a00b01020032802b01021010c010b4183b0302101200541ffffff1f71450d00200210350b200041206a41113602002000411c6a41c6b8c300360200200041186a200136020020004200370308200042013703000c1a0b200341c8086a200141046a41a002109d081a410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a2901003703a00e200320013a009f0e200320043a009e0e200320053b019c0e200320073a009b0e200320083a009a0e200320093b01980e2003200a3a00970e2003200b3a00960e2003200c3b01940e2003200d3a00930e2003200e3a00920e2003200f3b01900e200320103a008f0e200320113a008e0e200320123b018c0e200320133a008b0e200320143a008a0e200320153b01880e4103210120032802d008220241e4004b0d0020032002ad221e42004280c0c6c9faeb38420010840820034198066a200341880e6a10b504200341b0106a200328029806220220032802a00610d402200341d0036a200341b0106a41a402109d081a200341b0036a41086a2201200341dd126a290000370300200341b0036a41106a2204200341e5126a290000370300200341b0036a41176a2205200341ec126a280000360000200320032900d5123703b003200341086a290300211f2003290300211c0240024020032d00d41222074102460d0020034188016a200341d0036a41a402109d081a200341e8006a41176a2005280000360000200341e8006a41106a2004290300370300200341e8006a41086a2001290300370300200320032903b0033703680240200328029c06450d00200210350b200341b0106a20034188016a41a402109d081a200341b0106a41a4026a20073a0000200341d5126a2003290368370000200341dd126a200341e8006a41086a290300370000200341e5126a200341e8006a41106a290300370000200341ec126a200341ff006a2800003600000240200341b0106a41186a2802002208450d0020032802c010210241002101410021040340024002400240200241086a2207280200417f6a220541054b0d00024020050e06000101010100000b20010d01410021010c020b200141016a21010c010b200420016b220520084f0d1020034198066a41186a2209200220014105746b220541186a220a29030037030020034198066a41106a220b200541106a220c29030037030020034198066a41086a220d200541086a220e290300370300200320052903003703980620072903002106200241106a220f290300211a200241186a2210290300211b20052002290300370300200a201b370300200c201a370300200e200637030020102009290300370300200f200b2903003703002007200d29030037030020022003290398063703000b200241206a21022008200441016a2204470d000b2001417f6a20084f0d002003200820016b3602c8100b200341cc106a220210a3042002200341c8086a41a002109d081a200341980b6a200341b0106a41c002109d081a200341980b6a41086a290300211b20032903980b211d0c010b0240200328029c06450d00200210350b200341b00b6a41003602004200211d200342003703a00b200342003703980b200342083703a80b200341b40b6a200341c8086a41a002109d081a4200211b0b2003201c4280809aa6eaafe3017c221a3703980b2003201f201a201c54ad7c221c3703a00b0240201a201d58201c201b58201c201b5122041b0d002003201c201b7d201a201d54ad7d22063703d8032003201a201d7d221f3703d0032003200341880e6a360240201f2006844200510d002003200341880e6a36028801200320034188016a3602b8102003200341c0006a3602b4102003200341d0036a3602b01020034198066a200341880e6a200341b0106a108c03024002402003280298064101470d0020032f009d0620032d009f06411074722102200341a0066a290300210620032d009c0621010c010b41042101024020034198066a41086a2903004201520d0020034198066a41106a29030021062003280288012102200341e8106a20034198066a41186a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a2002290000370000200341c1106a200241086a290000370000200341c9106a200241106a290000370000200341d1106a200241186a290000370000200341033a00b01041b0b4cc004100200341b0106a10d4010b0b200141ff01714104460d000240200341ac0b6a28020041ffffff3f71450d0020032802a80b10350b200341b40b6a10a3040c020b0240201d201a58201b201c5820041b0d002003201b201c7d201d201a54ad7d22063703d8032003201d201a7d221a3703d003201a200684500d002003200341880e6a3602880120034198066a200341880e6a200341d0036a20034188016a10f0022003290398064201520d0020032903a0062106200341e8106a20034198066a41106a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a20032903880e370000200341c1106a200341880e6a41086a290300370000200341c9106a200341880e6a41106a290300370000200341d1106a200341a00e6a290300370000200341033a00b01041b0b4cc004100200341b0106a10d4010b200341b00b6a3502002106200341b0106a200341980b6a41c002109d081a20034198066a200341880e6a10b5042003280298062102200320032802a0063602d403200320023602d003200341b0106a200341d0036a10b0040240200328029c06450d00200210350b0240200341c4106a28020041ffffff3f71450d0020032802c01010350b200341cc106a10a304200341b0106a41086a41003a0000200341b9106a20032903880e370000200341c9106a200341880e6a41106a290300370000200341d1106a200341a00e6a290300370000200341880e6a41086a290300211a200341113a00b010200341b0106a41116a201a37000041b0b4cc004100200341b0106a10d401200041106a201e42e0c6db007e20064280b5187e7c4280c5d8d8007c37030020004201370308200042003703000c1b0b41d7b8c300ad4280808080d001842106200341c8086a10a30441981621020b200020023b00192000200637021c200042003703082000411b6a20024110763a0000200041186a20013a0000200042013703000c190b2001410c6a2802002107200141086a2802002105200141046a28020021084102210920022d00000d1620022d00014101470d16200241196a2d00002101200241186a2d00002104200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820032002411a6a2901003703e803200320013a00e703200320043a00e603200320093b01e4032003200a3a00e3032003200b3a00e2032003200c3b01e0032003200d3a00df032003200e3a00de032003200f3b01dc03200320103a00db03200320113a00da03200320123b01d803200320133a00d703200320143a00d603200320153b01d403200320163a00d303200320173a00d203200320183b01d003200341b0106a200341d0036a10b504200341206a20032802b010220120032802b81041b0b4cc0041004100108a0220032802202102024020032802b410450d00200110350b41032109024020024101460d0041d0b9c300ad4280808080800184210641980221040c180b0240200741e4004d0d0041d8b9c300ad4280808080a002842106411821040c180b200341980b6a200341d0036a10b604200341b0106a20032802980b220120032802a00b10cc02200341b0106a41086a290300420020032802c01022021b211a20032903b010420020021b211b20032902c41021060240200328029c0b450d00200110350b2006420020021b211e2002410120021b2119200341106a2007ad4200428080d287e2bc2d42001084080240201b2003290310221f5a201a200341106a41086a290300221d5a201a201d5122021b0d002003201d201a7d201f201b54ad7d22063703d0082003201f201b7d221c3703c8082003200341d0036a3602880e201c2006844200510d002003200341d0036a36029806200320034198066a3602b8102003200341880e6a3602b4102003200341c8086a3602b010200341980b6a200341d0036a200341b0106a108c030240024020032802980b4101470d0020032f009d0b20032d009f0b411074722104200341a00b6a290300210620032d009c0b21090c010b410421090240200341980b6a41086a2903004201520d00200341980b6a41106a29030021062003280298062101200341e8106a200341980b6a41186a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a2001290000370000200341c1106a200141086a290000370000200341c9106a200141106a290000370000200341d1106a200141186a290000370000200341033a00b01041b0b4cc004100200341b0106a10d4010b0b200941ff01714104460d00201e42ffffff3f83500d18201910350c180b0240201b201f58201a201d5820021b0d002003201a201d7d201b201f54ad7d22063703d0082003201b201f7d221a3703c808201a200684500d002003200341d0036a36029806200341980b6a200341d0036a200341c8086a20034198066a10f00220032903980b4201520d0020032903a00b2106200341e8106a200341980b6a41106a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a20032903d003370000200341c1106a200341d0036a41086a290300370000200341c9106a200341d0036a41106a290300370000200341d1106a200341e8036a290300370000200341033a00b01041b0b4cc004100200341b0106a10d4010b0240201e4220882220a72202450d0020024105742101201921020340200341b0106a200210970420033502b81042208620032802b0102204ad841007024020032802b410450d00200410350b200241206a2102200141606a22010d000b0b200341003602800b200342013703f80a200341f80a6a4100200741c4006c221641c4006d108a0120032802800b210d20032802f80a21180240024002402016450d00200820166a21212018200d4105746a2101200341b0106a41206a2117200341b0106a41216a2104200341980b6a411f6a210e4100210a0340200341880e6a41186a22072008200a6a220241186a290200370300200341880e6a41106a2209200241106a290200370300200341880e6a41086a220b200241086a290200370300200320022902003703880e200341980b6a41086a220c200241296a290000370300200341980b6a41106a220f200241316a290000370300200341980b6a41186a2210200241396a290000370300200e200241c0006a2800003600002003200241216a2900003703980b200241206a2d000022114106460d02200341c8086a41186a22122007290300370300200341c8086a41106a22132009290300370300200341c8086a41086a2214200b290300370300200320032903880e3703c808200341b0106a41186a2207200341d0036a41186a290300370300200341b0106a41106a2209200341d0036a41106a290300370300200341b0106a41086a2215200341d0036a41086a290300370300200320032903d0033703b010200320113a00d010200420032903980b370000200441086a200c290300370000200441106a200f290300370000200441186a20102903003700002004411f6a200e280000360000200341c0006a200341c8086a109704200335024821062003280240210b412010332202450d0d200220032903b010370000200241186a2007290300370000200241106a2009290300370000200241086a201529030037000020034188016a201710ac04200328028801210c0240024020032802900122070d00200741206a21090c010b200741206a22092007490d0f200941c000200941c0004b1b220f4100480d0f20024120200f10372202450d0e0b200241206a200c2007109d081a0240200328028c01450d00200c10350b2006422086200bad842009ad4220862002ad8410022002103502402003280244450d00200b10350b024020032d00d0104101470d0020032802d810450d0020032802d41010350b20034198066a41086a2014290300220637030020034198066a41106a2013290300221a37030020034198066a41186a2012290300221b370300200320032903c808221c37039806200141186a201b370000200141106a201a370000200141086a20063700002001201c370000200d41016a210d200141206a21012016200a41c4006a220a470d000b0b2003200d3602800b0c010b2003200d3602800b200241c4006a2021460d00200241e4006a21022016200a6b41bc7f6a21010340024020022d00004101470d00200241086a280200450d00200241046a28020010350b200241c4006a2102200141bc7f6a22010d000b0b02402005450d00200541c4006c450d00200810350b20032802fc0a2102200dad210602400240200d450d00200341c8106a200d360200200341c4106a20023602002003201f3703b010200320183602c0102003201d3703b810200341980b6a200341d0036a10b60420032802980b2101200320032802a00b3602cc08200320013602c808200341b0106a200341c8086a108d030240200328029c0b450d00200110350b0240200241ffffff3f71450d00201810350b410121010c010b200341b0106a200341d0036a10b60420033502b81042208620032802b0102201ad841007024020032802b410450d00200110350b410021010b202042c0d89e017e200642a0eae1017e7c20204280c2d72f7e7c20064280c2d72f7e7c21060240200241ffffff3f71450d0020010d00201810350b200642c0db89db007c21060240201e42ffffff3f83500d00201910350b20004201370308200041106a2006370300200042003703000c180b41022101024020022d00000d004101210520022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a290100370358200320013a0057200320043a0056200320073b0154200320083a0053200320093a00522003200a3b01502003200b3a004f2003200c3a004e2003200d3b014c2003200e3a004b2003200f3a004a200320103b0148200320113a0047200320123a0046200320133b0144200320143a0043200320153a0042200320163b0140200341980b6a200341c0006a10b604200341b0106a20032802980b220220032802a00b220110cc020240024020032802c01022040d004200211b4200211c4200211d0c010b2001ad4220862002ad841007200341b8106a290300211d20032903b010211c20032902c410211b200421050b0240200328029c0b450d00200210350b200341e80d6a200341c0006a10b504200341b0106a20032802e80d220220032802f00d220410d402024020032d00d412220941024622010d002004ad4220862002ad8410070b200341880e6a200341b0106a41a402109d081a200341f80a6a41176a2204200341ec126a280000360000200341f80a6a41106a2207200341e5126a290000370300200341f80a6a41086a2208200341dd126a290000370300200320032900d5123703f80a200341d0036a200341880e6a41a402109d081a200341b0036a41176a220a2004280000360000200341b0036a41106a22042007290300370300200341b0036a41086a22072008290300370300200320032903f80a3703b003024020010d0020034188016a200341d0036a41a402109d081a200341e8006a41176a200a280000360000200341e8006a41106a2004290300370300200341e8006a41086a2007290300370300200320032903b003370368024020032802ec0d450d00200210350b200341c8086a41066a20034188016a41a402109d081a20034198066a200341c8086a41aa02109d081a200341f8056a41176a2202200341e8006a41176a280000360000200341f8056a41106a2201200341e8006a41106a290300370300200341f8056a41086a2204200341e8006a41086a290300370300200320032903683703f805200341980b6a20034198066a41066a41a402109d081a200341980b6a41a4026a20093a0000200341bd0d6a20032903f805370000200341c50d6a2004290300370000200341cd0d6a2001290300370000200341d40d6a2002280000360000200341980b6a41086a290300211e20032903980b211f20032802a80b210702400240200341b00b6a280200220841057422010d00420021064200211a0c010b200741106a2102420021064200211a0340200241086a2903004200200241786a29030042015122041b201a7c2002290300420020041b221a20067c2206201a54ad7c211a200241206a2102200141606a22010d000b0b201e201d7c201f201c7c221c201f54ad7c201a7c201c20067c2206201c54ad7c211a0240201b422088221ca72202450d0020024105742101200521020340200341b0106a200210970420033502b81042208620032802b0102204ad841007024020032802b410450d00200410350b200241206a2102200141606a22010d000b0b20032006370398062003201a3703a00602402006201a84500d002003200341c0006a3602880e200341c8086a200341c0006a20034198066a200341880e6a10f00220032903c8084201520d0020032903d008211d200341e8106a200341c8086a41106a290300370300200341e0106a201d370300200341b0106a41086a41003a0000200341b9106a2003290340370000200341c1106a200341c0006a41086a290300370000200341c9106a200341c0006a41106a290300370000200341d1106a200341d8006a290300370000200341033a00b01041b0b4cc004100200341b0106a10d4010b200341e8106a201a370300200341e0106a2006370300200341b0106a41086a41013a0000200341b9106a2003290340370000200341c9106a200341d0006a290300370000200341d1106a200341d8006a290300370000200341c0006a41086a2903002106200341113a00b010200341b0106a41116a200637000041b0b4cc004100200341b0106a10d401201c42c0d89e017e2008ad42a09c017e7c201c4280c2d72f7e7c200341bc0b6a35020042a0f7367e7c2106200341b40b6a21020240200341ac0b6a28020041ffffff3f71450d00200710350b20064280eaee92017c2106200210a3040240201b42ffffff3f83500d00200510350b20004201370308200041106a2006370300200042003703000c190b024020032802ec0d450d00200210350b41032101201b42ffffff3f83500d00200510350b20004198043b001920004200370308200041206a41083602002000411c6a41c8b9c300360200200041186a20013a0000200042013703000c170b200141106a290300211a200141086a290300211b200141046a28020021012002411a6a2901002106200241196a2d00002105200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211741012104024020022d00000d0020022d000141014721040b200320063703e008200320053a00df08200320073a00de08200320083b01dc08200320093a00db082003200a3a00da082003200b3b01d8082003200c3a00d7082003200d3a00d6082003200e3b01d4082003200f3a00d308200320103a00d208200320113b01d008200320123a00cf08200320133a00ce08200320143b01cc08200320153a00cb08200320163a00ca08200320173b01c808024020040d00200341880e6a41186a200341c8086a41186a290300370300200341880e6a41106a200341c8086a41106a290300370300200341880e6a41086a200341c8086a41086a290300370300200320032903c8083703880e41fafdc600ad42808080808001841001220229000021062002290008211c2002103541e8adc400ad4280808080a0018410012202290000211d2002290008211f200210352003201f3703b00b2003201d3703a80b2003201c3703a00b200320063703980b200341b0106a200341980b6a10dc0220032802b0102205410820051b210741beb9c300ad4280808080a001842106419806210241032104200120032902b410420020051b221c422088a74f0d13200720014106746a2205450d13024020052903004201510d0041beb9c300ad4280808080a0018421060c140b0240200720014106746a2202290308201b58200241106a2903002206201a582006201a511b0d0041b4b9c300ad4280808080a00184210641980821020c140b200341c0006a200341880e6a10b504200341b0106a20032802402205200328024810d402200341d0036a200341b0106a41a402109d081a200341b0036a41086a200341dd126a290000370300200341b0036a41106a200341e5126a290000370300200341b0036a41176a2208200341ec126a280000360000200320032900d5123703b00302400240024002400240024020032d00d41222094102460d00200241086a210b20034188016a200341d0036a41a402109d081a200341e8006a41176a2008280000360000200341e8006a41106a2202200341b0036a41106a290300370300200341e8006a41086a2204200341b0036a41086a290300370300200320032903b00337036802402003280244450d00200510350b200341c8086a41066a20034188016a41a402109d081a20034198066a200341c8086a41aa02109d081a200341f8056a41176a2205200341e8006a41176a280000360000200341f8056a41106a22082002290300370300200341f8056a41086a22022004290300370300200320032903683703f805200341980b6a20034198066a41066a41a402109d081a200341980b6a41a4026a20093a0000200341bd0d6a20032903f805370000200341c50d6a2002290300370000200341cd0d6a2008290300370000200341d40d6a2005280000360000200b41086a290300211a200b290300211b20032802a80b210941002102200341b00b6a280200220a41014b0d01200a0e020302030b02402003280244450d00200510350b41aab9c300ad4280808080a00184210641980a21020c180b200a2104034020022004410176220520026a2208200920084105746a28020020014b1b2102200420056b220441014b0d000b0b200920024105746a220528020022042001460d01200a200220042001496a2202490d0d0b0240200a200341ac0b6a280200470d00200341980b6a41106a200a410110a10120032802a80b21090b200920024105746a220441206a2004200a20026b410574109e081a200441186a201a370300200441106a201b37030020044201370308200420013602002003200a41016a220a3602b00b0c010b200a20024d0d0c0240200920024105746a2208280208417f6a220c41054b0d00419bb9c300ad4280808080f00184210641980c210241032104200c0e06140000000014140b200841086a420137030020052001360200200841186a201a370300200841106a201b3703000b200b29030021062003200b41086a290300221a3703a00620032006370398062003200341880e6a3602880102402006201a844200510d002003200341880e6a3602d0032003200341d0036a3602b810200320034188016a3602b410200320034198066a3602b010200341c8086a200341880e6a200341b0106a108c030240024020032802c8084101470d0020032f00cd0820032d00cf08411074722102200341d0086a290300210620032d00cc0821040c010b410421040240200341c8086a41086a2903004201520d00200341c8086a41106a290300210620032802d0032102200341e8106a200341c8086a41186a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a2002290000370000200341c1106a200241086a290000370000200341c9106a200241106a290000370000200341d1106a200241186a290000370000200341033a00b01041b0b4cc004100200341b0106a10d4010b0b200441ff01714104470d130b200341bc0b6a3502002106200341b0106a200341980b6a41c002109d081a200341c8086a200341880e6a10b50420032802c8082102200320032802d00836029c062003200236029806200341b0106a20034198066a10b004024020032802cc08450d00200210350b200aad211a0240200341c4106a28020041ffffff3f71450d0020032802c01010350b200341cc106a10a304200341b0106a41086a41033a0000200341b9106a20032903880e370000200341c9106a200341880e6a41106a290300370000200341d1106a200341a00e6a290300370000200341dc106a2001360200200341880e6a41086a290300211b200341113a00b010200341b0106a41116a201b37000041b0b4cc004100200341b0106a10d401201a42b0901f7e200642a0e1e7007e7c4280b191e4007c21060240201c42ffffff1f83500d00200710350b20004201370308200041106a2006370300200042003703000c170b410221040c130b02400240024002400240024020022d00000d0020022d00014101470d00200141046a2802002107200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703a00e200320013a009f0e200320043a009e0e200320053b019c0e200320083a009b0e200320093a009a0e2003200a3b01980e2003200b3a00970e2003200c3a00960e2003200d3b01940e2003200e3a00930e2003200f3a00920e200320103b01900e200320113a008f0e200320123a008e0e200320133b018c0e200320143a008b0e200320153a008a0e200320163b01880e200341e80d6a200341880e6a10b504200341b0106a20032802e80d220220032802f00d10d402200341d0036a200341b0106a41a402109d081a200341b0036a41086a2201200341dd126a290000370300200341b0036a41106a2204200341e5126a290000370300200341b0036a41176a2205200341ec126a280000360000200320032900d5123703b003024020032d00d41222084102460d0020034188016a200341d0036a41a402109d081a200341e8006a41176a2005280000360000200341e8006a41106a2004290300370300200341e8006a41086a2001290300370300200320032903b003370368024020032802ec0d450d00200210350b200341c8086a41066a20034188016a41a402109d081a20034198066a200341c8086a41aa02109d081a200341f8056a41176a2202200341e8006a41176a280000360000200341f8056a41106a2201200341e8006a41106a2903003703004108210a200341f8056a41086a2204200341e8006a41086a290300370300200320032903683703f805200341980b6a20034198066a41066a41a402109d081a200341980b6a41a4026a20083a0000200341bd0d6a20032903f805370000200341c50d6a2004290300370000200341cd0d6a2001290300370000200341d40d6a20022800003600004101210b41d0b9c300210c20032802a80b210841002102200341b00b6a280200220941014b0d0220090e020403040b024020032802ec0d450d00200210350b2003410a360248200341aab9c300360244200341053a004220034183303b01400c040b200341023a00400c030b20092101034020022001410176220420026a2205200820054105746a28020020074b1b2102200120046b220141014b0d000b0b200820024105746a2802002007470d00200920024d0d0d200820024105746a220141186a2903002106200141106a290300211a2001290308211b2001200141206a2002417f7320096a410574109e081a20032009417f6a22023602b00b201b4201510d02418db9c300210c410e210a4107210b0b2003200a3602482003200c3602442003200b3a004220034183303b01400240200341ac0b6a28020041ffffff3f71450d00200810350b200341b40b6a10a3040b200341f80a6a41086a200341c0006a41086a290300220637030020032003290340221a3703f80a20004200370308200041186a201a370300200041206a2006370300200042013703000c160b2003201a37039806200320063703a0060240201a200684500d002003200341880e6a3602d003200341c8086a200341880e6a20034198066a200341d0036a10f00220032903c8084201520d0020032903d0082106200341e8106a200341c8086a41106a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a20032903880e370000200341c1106a200341880e6a41086a290300370000200341c9106a200341880e6a41106a290300370000200341d1106a200341a00e6a290300370000200341033a00b01041b0b4cc004100200341b0106a10d4010b200341bc0b6a3502002106200341b0106a200341980b6a41c002109d081a200341c8086a200341880e6a10b50420032802c8082101200320032802d00836029c062003200136029806200341b0106a20034198066a10b004024020032802cc08450d00200110350b2002ad211a0240200341c4106a28020041ffffff3f71450d0020032802c01010350b200341cc106a10a304200341b0106a41086a41043a0000200341b9106a20032903880e370000200341c9106a200341880e6a41106a290300370000200341d1106a200341a00e6a290300370000200341dc106a2007360200200341880e6a41086a290300211b200341113a00b010200341b0106a41116a201b37000041b0b4cc004100200341b0106a10d401200041106a201a42b0901f7e200642a0e1e7007e7c4280b191e4007c37030020004201370308200042003703000c150b200141106a2903002106200141086a290300211a200141046a280200210420032002411a6a2901003703e008410221012003200241026a2901003703c80820032002410a6a2901003703d0082003200241126a2901003703d8080240024020022d00014101470d0020022d000041ff01710d00200341b0106a41186a200341c8086a41186a290300370300200341b0106a41106a200341c8086a41106a290300370300200341b0106a41086a200341c8086a41086a290300370300200320032903c8083703b01041fafdc600ad4280808080800184221b10012202290000211c2002290008211d2002103541e8adc400ad4280808080a00184221f10012202290000211e2002290008212020021035200320203703b00b2003201e3703a80b2003201d3703a00b2003201c3703980b200341c8086a200341980b6a10dc0220032802c8082205410820051b2102410121074183b02421010240200420032902cc08420020051b221d422088a722054f0d00200220044106746a2208450d0020082903004201520d000240200220044106746a220841206a2204200341b0106a460d002004200341b0106a412010a0080d010b200841086a2201201a3703002001200637030841002107200521010b201b1001220429000021062004290008211a20041035201f10012204290000211b2004290008211c200410352003201c3703b00b2003201b3703a80b2003201a3703a00b200320063703980b0240024020020d00200341980b6aad428080808080048410070c010b200341c8086a2002200510b404200341980b6aad428080808080048420033502d00842208620032802c8082204ad841002024020032802cc08450d00200410350b201d42ffffff1f83500d00200210350b2007450d010b20004200370308200041186a20013602002000411c6a41f1b8c300ad4280808080c00184370200200042013703000c150b20004201370308200041106a2001ad42b09f1a7e4280dbf23f7c370300200042003703000c140b410221040240024020022d00000d004101210520022d00014101470d00200141196a290000211d200141186a2d00002118200141176a2d00002119200141156a2f00002121200141146a2d00002122200141136a2d00002123200141116a2f00002124200141106a2d000021252001410f6a2d000021262001410d6a2f000021272001410c6a2d000021282001410b6a2d00002129200141096a2f0000212a200141086a2d0000212b200141076a2d0000212c200141056a2f0000212d200141046a2d0000212e200141036a2d0000212f200141246a280200210820012f00012130200241196a2d00002101200241186a2d00002104200241166a2f01002107200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720032002411a6a2901003703c810200320013a00c710200320043a00c610200320073b01c410200320093a00c3102003200a3a00c2102003200b3b01c0102003200c3a00bf102003200d3a00be102003200e3b01bc102003200f3a00bb10200320103a00ba10200320113b01b810200320123a00b710200320133a00b610200320143b01b410200320153a00b310200320163a00b210200320173b01b010200341980b6a41186a22094200370300200341980b6a41106a220a4200370300200341980b6a41086a22024200370300200342003703980b41fafdc600ad4280808080800184220610012201290000211a2002200141086a2900003703002003201a3703980b2001103541e8adc400ad4280808080a00184221a10012201290008211b2001290000211c20011035200341c8086a41106a220b201c370300200341c8086a41186a220c201b370300200341c8086a41086a220d2002290300370300200320032903980b3703c808200341980b6a200341c8086a10dc0220032802980b2207410820071b21014183b024210402402008200329029c0b420020071b221b422088a7220e4f0d00200120084106746a2207450d0020072903004201520d002003201d3703e008200320183a00df08200320193a00de08200320213b01dc08200320223a00db08200320233a00da08200320243b01d808200320253a00d708200320263a00d608200320273b01d408200320283a00d308200320293a00d2082003202a3b01d0082003202b3a00cf082003202c3a00ce082003202d3b01cc082003202e3a00cb082003202f3a00ca08200320303b01c8082003201d3703b00b200320183a00af0b200320193a00ae0b200320213b01ac0b200320223a00ab0b200320233a00aa0b200320243b01a80b200320253a00a70b200320263a00a60b200320273b01a40b200320283a00a30b200320293a00a20b2003202a3b01a00b2003202b3a009f0b2003202c3a009e0b2003202d3b019c0b2003202e3a009b0b2003202f3a009a0b200320303b01980b0240200341b0106a200120084106746a41206a2207460d002007200341b0106a412010a0080d010b200720032903980b370200200741186a200341980b6a41186a290300370200200741106a200341980b6a41106a290300370200200741086a200341980b6a41086a29030037020041002105200e21040b20094200370300200a420037030020024200370300200342003703980b20061001220729000021062002200741086a290000370300200320063703980b20071035201a1001220729000821062007290000211a20071035200b201a370300200c2006370300200d2002290300370300200320032903980b3703c8080240024020010d00200341c8086aad428080808080048410070c010b200341980b6a2001200e10b404200341c8086aad428080808080048420033502a00b42208620032802980b2202ad8410020240200328029c0b450d00200210350b201b42ffffff1f83500d00200110350b2005450d010b20004200370308200041186a20043602002000411c6a41f1b8c300ad4280808080c00184370200200042013703000c140b20004201370308200041106a2004ad42c0ed1a7e42e0ecb5c0007c370300200042003703000c130b200141086a2903002106200141046a280200210420032002411a6a2901003703e008410221012003200241026a2901003703c80820032002410a6a2901003703d0082003200241126a2901003703d8080240024020022d00014101470d0020022d000041ff01710d00200341b0106a41186a200341c8086a41186a290300370300200341b0106a41106a200341c8086a41106a290300370300200341b0106a41086a200341c8086a41086a290300370300200320032903c8083703b01041fafdc600ad4280808080800184221a10012202290000211b2002290008211c2002103541e8adc400ad4280808080a00184221d10012202290000211f2002290008211e200210352003201e3702b00b2003201f3702a80b2003201c3702a00b2003201b3702980b200341c8086a200341980b6a10dc0220032802c8082205410820051b2102410121074183b02421010240200420032902cc08420020051b221f422088a722054f0d00200220044106746a2208450d0020082903004201520d000240200220044106746a220841206a2204200341b0106a460d002004200341b0106a412010a0080d010b2008200637031841002107200521010b201a1001220429000021062004290008211a20041035201d10012204290000211b2004290008211c200410352003201c3702b00b2003201b3702a80b2003201a3702a00b200320063702980b0240024020020d00200341980b6aad428080808080048410070c010b200341c8086a2002200510b404200341980b6aad428080808080048420033502d00842208620032802c8082204ad841002024020032802cc08450d00200410350b201f42ffffff1f83500d00200210350b2007450d010b20004200370308200041186a20013602002000411c6a41f1b8c300ad4280808080c00184370200200042013703000c130b20004201370308200041106a2001ad42a0d1197e4280dbf23f7c370300200042003703000c120b200141c0006a290300211a200141386a290300211b200141306a2903002106200141046a2802002107200341880e6a41206a200141286a280200360200200341880e6a41186a200141206a290200370300200341880e6a41106a200141186a290200370300200341880e6a41086a200141106a2902003703002003200141086a2902003703880e4102210120022d00000d0a20022d00014101470d0a200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703900b200320013a008f0b200320043a008e0b200320053b018c0b200320083a008b0b200320093a008a0b2003200a3b01880b2003200b3a00870b2003200c3a00860b2003200d3b01840b2003200e3a00830b2003200f3a00820b200320103b01800b200320113a00ff0a200320123a00fe0a200320133b01fc0a200320143a00fb0a200320153a00fa0a200320163b01f80a200341b0106a41206a200341880e6a41206a280200360200200341b0106a41186a200341880e6a41186a29030037030041102102200341b0106a41106a200341880e6a41106a29030037030041082104200341b0106a41086a200341880e6a41086a290300370300200320032903880e3703b010200341980b6a200341b0106a108b02200341c8086a41086a2201200341a10b6a290000370300200341c8086a41106a2205200341a90b6a290000370300200341c8086a41186a2208200341b10b6a290000370300200320032900990b3703c80820032d00980b4101460d09200341c0006a41186a2008290300370300200341c0006a41106a2005290300370300200341c0006a41086a2001290300370300200320032903c8083703404103210141fdb8c300210520064201510d0b41fafdc600ad428080808080018410012202290000211c2002290008211d2002103541e8adc400ad4280808080a0018410012202290000211f2002290008211e200210352003201e3702b00b2003201f3702a80b2003201d3702a00b2003201c3702980b200341b0106a200341980b6a10dc0220032802b0102202410820021b2108024002400240024002400240200720032902b410420020021b221c422088a74f0d00200820074106746a2202450d0020022903004201520d000240200820074106746a41206a2202200341f80a6a460d002002200341f80a6a412010a0080d010b0240201c42ffffff1f83500d00200810350b200341e80d6a200341c0006a10b504200341b0106a20032802e80d220220032802f00d10d402200341d0036a200341b0106a41a402109d081a200341b0036a41086a2204200341dd126a290000370300200341b0036a41106a2205200341e5126a290000370300200341b0036a41176a2208200341ec126a280000360000200320032900d5123703b003024020032d00d41222094102460d0020034188016a200341d0036a41a402109d081a200341e8006a41176a2008280000360000200341e8006a41106a2005290300370300200341e8006a41086a2004290300370300200320032903b003370368024020032802ec0d450d00200210350b200341c8086a41066a20034188016a41a402109d081a20034198066a200341c8086a41aa02109d081a200341f8056a41176a2202200341e8006a41176a280000360000200341f8056a41106a2201200341e8006a41106a290300370300200341f8056a41086a2204200341e8006a41086a290300370300200320032903683703f805200341980b6a20034198066a41066a41a402109d081a200341980b6a41a4026a20093a0000200341bd0d6a20032903f805370000200341c50d6a2004290300370000200341cd0d6a2001290300370000200341d40d6a200228000036000020032802a80b210841002102200341b00b6a280200220941014b0d0220090e020403040b024020032802ec0d450d00200210350b410a210441e4b8c3002105410d21020c110b4109210441f1b8c3002105410c2102201c42ffffff1f83500d10200810350c100b20092101034020022001410176220420026a2205200820054105746a28020020074b1b2102200120046b220141014b0d000b0b200820024105746a220128020022042007460d012009200220042007496a2202490d0a0b02402009200341ac0b6a280200470d00200341980b6a41106a2009410110a10120032802a80b21080b200820024105746a220141206a2001200920026b410574109e081a200141186a201a370300200141106a201b37030020012006370308200120073602002003200941016a22093602b00b0c010b200920024d0d09200820024105746a220241086a2104024020022903084201520d00200341b0106a200341c0006a200341f80a6a200241106a290300200241186a290300410010ef020b2004200637030020012007360200200241186a201a370300200241106a201b3703000b200341bc0b6a3502002106200341b0106a200341980b6a41c002109d081a200341c8086a200341c0006a10b50420032802c8082102200320032802d00836029c062003200236029806200341b0106a20034198066a10b004024020032802cc08450d00200210350b2009ad211a0240200341c4106a28020041ffffff3f71450d0020032802c01010350b200341cc106a10a304200341b0106a41086a41053a0000200341b9106a2003290340370000200341c9106a200341c0006a41106a290300370000200341d1106a200341d8006a290300370000200341dc106a2007360200200341c0006a41086a290300211b200341113a00b010200341b0106a41116a201b37000041b0b4cc004100200341b0106a10d401200041106a201a4280b5187e200642a0e1e7007e7c42c0fff1de007c37030020004201370308200042003703000c110b200341e0006a200141246a280200360200200341d8006a2001411c6a290200370300200341c0006a41106a200141146a290200370300200341c8006a2001410c6a2902003703002003200141046a29020037034041022101200241036a2d0000210520022f000121070240024002400240024002400240024020022d00002208417f6a220441024b0d00024020040e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200720054110747220084100477241ff01710d010b200341b0106a41206a200341c0006a41206a280200360200200341b0106a41186a200341c0006a41186a290300370300200341b0106a41106a200341c0006a41106a290300370300200341b0106a41086a200341c0006a41086a290300370300200320032903403703b010200341980b6a200341b0106a108b0241012105024020032d00980b4101460d00200341980b6a41086a2d00002102200341a10b6a2f00002101200341a30b6a2d00002104200341a40b6a2d00002107200341a50b6a2f00002108200341a70b6a2d00002109200341980b6a41106a2d0000210a200341a90b6a2f0000210b200341ab0b6a2d0000210c200341ac0b6a2d0000210d200341ad0b6a2f0000210e200341af0b6a2d0000210f200341980b6a41186a2d0000211020032f00990b211120032d009b0b211220032d009c0b211320032f009d0b211420032d009f0b21152003200341b10b6a2900003703900b200320103a008f0b2003200f3a008e0b2003200e3b018c0b2003200d3a008b0b2003200c3a008a0b2003200b3b01880b2003200a3a00870b200320093a00860b200320083b01840b200320073a00830b200320043a00820b200320013b01800b200320023a00ff0a200320153a00fe0a200320143b01fc0a200320133a00fb0a200320123a00fa0a200320113b01f80a200341980b6a200341f80a6a10b604200341b0106a20032802980b220220032802a00b220110cc020240024020032802c01022040d004200211b4200211c4200211d0c010b2001ad4220862002ad841007200341b8106a290300211d20032903b010211c20032902c410211b200421050b0240200328029c0b450d00200210350b200341d80d6a200341f80a6a10b504200341b0106a20032802d80d220220032802e00d220410d402024020032d00d412220941024622010d002004ad4220862002ad8410070b200341880e6a200341b0106a41a402109d081a200341e80d6a41176a2204200341ec126a280000360000200341e80d6a41106a2207200341e5126a290000370300200341e80d6a41086a2208200341dd126a290000370300200320032900d5123703e80d200341d0036a200341880e6a41a402109d081a200341b0036a41176a220a2004280000360000200341b0036a41106a22042007290300370300200341b0036a41086a22072008290300370300200320032903e80d3703b003024020010d0020034188016a200341d0036a41a402109d081a200341e8006a41176a200a280000360000200341e8006a41106a2004290300370300200341e8006a41086a2007290300370300200320032903b003370368024020032802dc0d450d00200210350b200341c8086a41066a20034188016a41a402109d081a20034198066a200341c8086a41aa02109d081a200341f8056a41176a2202200341e8006a41176a280000360000200341f8056a41106a2201200341e8006a41106a290300370300200341f8056a41086a2204200341e8006a41086a290300370300200320032903683703f805200341980b6a20034198066a41066a41a402109d081a200341980b6a41a4026a20093a0000200341bd0d6a20032903f805370000200341c50d6a2004290300370000200341cd0d6a2001290300370000200341d40d6a2002280000360000200341980b6a41086a290300211e20032903980b211f20032802a80b210702400240200341b00b6a280200220841057422010d00420021064200211a0c010b200741106a2102420021064200211a0340200241086a2903004200200241786a29030042015122041b201a7c2002290300420020041b221a20067c2206201a54ad7c211a200241206a2102200141606a22010d000b0b201e201d7c201f201c7c221c201f54ad7c201a7c201c20067c2206201c54ad7c211a0240201b422088221ca72202450d0020024105742101200521020340200341b0106a200210970420033502b81042208620032802b0102204ad841007024020032802b410450d00200410350b200241206a2102200141606a22010d000b0b20032006370398062003201a3703a0062006201a844200520d03200342003703d008200342003703c8080c040b024020032802dc0d450d00200210350b0240201b42ffffff3f83500d00200510350b410321010c010b410121010b20004198043b001920004200370308200041206a41083602002000411c6a41c8b9c300360200200041186a20013a0000420121060c040b2003200341f80a6a3602880e200341c8086a200341f80a6a20034198066a200341880e6a10a802200341e8086a290300211d20032903e008211f024020032903c8084201520d0020032903d008211e200341e8106a200341c8086a41106a290300370300200341e0106a201e370300200341b0106a41086a41003a0000200341b9106a20032903f80a370000200341c1106a200341f80a6a41086a290300370000200341c9106a200341f80a6a41106a290300370000200341d1106a200341900b6a290300370000200341033a00b01041b0b4cc004100200341b0106a10d4010b2003201f3703c8082003201d3703d008201f201d844200520d010b20034198066a41186a220a420037030020034198066a41106a2204420037030020034198066a41086a22014200370300200342003703980641b6fdc600ad4280808080800184221d10012209290000211f200341b0106a41086a2202200941086a2900003703002003201f3703b0102009103520012002290300370300200320032903b0103703980641e489c200ad4280808080d00184221f10012209290000211e2002200941086a2900003703002003201e3703b01020091035200420032903b010221e370300200341880e6a41086a220b2001290300370300200341880e6a41106a220c201e370300200341880e6a41186a220d200229030037030020032003290398063703880e200341286a200341880e6a412010d701200341286a41106a290300211e2003290330212020032802282109200a420037030020044200370300200142003703002003420037039806201d1001220a290000211d2002200a41086a2900003703002003201d3703b010200a103520012002290300370300200320032903b01037039806201f1001220a290000211d2002200a41086a2900003703002003201d3703b010200a1035200420032903b010221d370300200b2001290300370300200c201d370300200d200229030037030020032003290398063703880e2003201e420020091b3703b81020032020420020091b3703b010200341880e6aad4280808080800484200341b0106aad428080808080028410020c010b200342f0f2bda1a7ee9cb9f9003703c808200341b0106a200341c8086a10e001200341b0106a201f201d10df01200341c8106a201d370300200341c0106a201f370300200341b8106a41063a00002003410c3a00b01041b0b4cc004100200341b0106a10d4010b200341e8106a201a370300200341e0106a2006370300200341b0106a41086a41023a0000200341b9106a20032903f80a370000200341f80a6a41086a2903002106200341113a00b010200341b0106a41116a2006370000200341c9106a200341880b6a290300370000200341d1106a200341900b6a29030037000041b0b4cc004100200341b0106a10d401201c42c0d89e017e2008ad42a08d067e7c201c4280c2d72f7e7c200341bc0b6a35020042a0f7367e7c2106200341b40b6a21020240200341ac0b6a28020041ffffff3f71450d00200710350b200642c086a2e7017c2106200210a3040240201b42ffffff3f83500d00200510350b200041106a200637030020004201370308420021060b200020063703000c100b2005200841f485cc001042000b103c000b103e000b2002200a104d000b2002200a41a0bdc4001042000b20022009104e000b20022009104d000b2002200941b0bdc4001042000b410121010b0b200041206a20023602002000411c6a2005360200200020043a001a200041183a0019200041186a20013a000020004200370308200042013703000c050b0240200341ac0b6a28020041ffffff3f71450d00200910350b200341b40b6a10a3040b201c42ffffff1f83500d00200710350b200020023b00192000200637021c200042003703082000411b6a20024110763a0000200041186a20043a0000200042013703000c020b0b02402007450d00200741c4006c2101200841286a210203400240200241786a2d00004101470d002002280200450d002002417c6a28020010350b200241c4006a2102200141bc7f6a22010d000b0b02402005450d00200541c4006c450d00200810350b200020043b00192000200637021c200042003703082000411b6a20044110763a0000200041186a20093a0000200042013703000b200341f0126a24000b950202037f017e230041206b220324000240024020024106744104722204417f4c0d00200410332205450d0120034100360208200320043602042003200536020020022003107702402002450d002002410674210203400240024020012903004201510d00200341003a00102003200341106a410110780c010b200341013a00102003200341106a410110782003200141206a41201078200141086a29030021062003200141106a290300370318200320063703102003200341106a411010782003200141186a2903003703102003200341106a410810780b200141c0006a2101200241406a22020d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1044000b1045000bb10503027f017e047f230041d0006b2202240041fafdc600ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541c8acc400ad4280808080a00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041fafdc600ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541b8adc400ad4280808080e00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b13002000410d360204200041c0bdc4003602000b1f0002402000280200450d00200041086a280200450d00200028020410350b0b8c0a03047f017e047f23004190016b22022400200241d8006a41186a4200370300200241d8006a41106a22034200370300200241d8006a41086a220442003703002002420037035841a3edcb00ad4280808080f000841001220529000021062004200541086a290000370300200220063703582005103541a5ebcb00ad4280808080c00184100122052900002106200241f8006a41086a2207200541086a2900003703002002200637037820051035200320022903782206370300200241386a41086a2004290300370300200241386a41106a2006370300200241386a41186a200729030037030020022002290358370338200241106a200241386a412010c001200241d8006a2002280214410020022802101b2203200010ba04200241086a20022802582204200228026041b0b4cc0041004100108a02200228020821050240200228025c450d00200410350b410121040240024002400240024020054101460d004188e8cb00ad4280808080800184100122042900002106200241f8006a41086a200441086a290000370300200220063703782004103541f1c8c400ad4280808080e00184100122042900002106200241386a41086a200441086a2900003703002002200637033820041035200220033602282002200241286aad4280808080c00084100322042900003703880120041035200241e4006a22052002412c6a360200200220024188016a41086a220036025c2002200241286a360260200220024188016a360258200241186a200241d8006a107b412010332204450d0120042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020022004ad42808080808004841003220129000037038801200110352005200441206a360200200220043602602002200036025c200220024188016a360258200241286a200241d8006a107b200410352002280220220741206a2200200228023022086a2201417f4c0d02200228022821092002280218210a0240024020010d0041002103410121040c010b200110332204450d02200121030b024002402003410f4d0d00200321050c010b200341017422054110200541104b1b22054100480d04024020030d002005103322040d010c060b20032005460d0020042003200510372204450d050b20042002290378370000200441086a200241f8006a41086a2903003700000240024020054170714110460d00200521030c010b200541017422034120200341204b1b22034100480d0420052003460d0020042005200310372204450d050b20042002290338370010200441186a200241386a41086a29030037000002400240200341606a2007490d00200321050c010b2007415f4b0d04200341017422052000200520004b1b22054100480d0420032005460d0020042003200510372204450d050b200441206a200a2007109d081a02400240200520006b2008490d00200521030c010b20012000490d04200541017422032001200320014b1b22034100480d04024020050d00024020030d00410121040c020b200310332204450d060c010b20052003460d0020042005200310372204450d050b200420006a20092008109d081a0240200228022c450d00200910350b0240200228021c450d00200a10350b20022004200110c001200228020421012002280200210502402003450d00200410350b200141004720054100477121040b20024190016a240020040f0b1045000b1044000b103e000b103c000bf60603027f017e077f230041e0006b220324004188e8cb00ad4280808080800184100122042900002105200341086a41086a200441086a29000037030020032005370308200410354190e8cb00ad4280808080a00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a2204200341386a41046a3602002003200341c8006a41086a22013602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b200320023602442003200341c4006aad4280808080c0008410032202290000370348200210352004200341c4006a41046a360200200320013602542003200341c4006a3602582003200341c8006a360250200341386a200341d0006a107b02400240024002402003280230220641206a2207200328024022086a2202417f4c0d00200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d022002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2006490d00200b21010c010b200641206a22012006490d03200b410174220c2001200c20014b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2006109d081a02400240200120076b2008490d002001210b0c010b20022007490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420076a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1044000b1045000b103e000b103c000bae0707017f017e067f017e047f017e027f230041306b220124000240024010292202422088a722030d00410121040c010b2002a721040b2001200336022420012004360220024002400240024002402003450d0020042d0000210520012003417f6a3602242001200441016a360220200541014b0d00024020050e020004000b200141186a200141206a10c40120012802180d0020012802242206200128021c2205490d002005417f4c0d020240024020050d0042002102410121070c010b200510392207450d022007200128022022082005109d081a2001200620056b3602242001200820056a3602202005ad21020b2007450d00200141106a200141206a10c4012005ad4220862002842209a7210a024020012802100d002001280214220b2001280224410c6e22052005200b4b1bad420c7e2202422088a70d032002a72205417f4c0d030240024020050d004104210c0c010b20051033220c450d030b2005410c6ead21020240200b450d000340200141086a200141206a10c40102400240024020012802080d0020012802242206200128020c2205490d002005417f4c0d080240024020050d004100210d410121080c010b200510392208450d0820082001280220220d2005109d081a2001200620056b3602242001200d20056a3602202005210d0b2002422088220ea722062002a7470d02024002400240200641016a220f2006490d00200ea74101742210200f200f2010491bad420c7e220e422088a70d00200ea7220f4100480d00024020060d00200f0d024104210c0c050b2006410c6c2206200f460d04024020060d00200f0d024104210c0c050b200c2006200f1037220c450d020c040b103e000b200f1033220c0d020b103c000b02402002422088a72205450d002005410c6c2106200c210503400240200541046a280200450d00200528020010350b2005410c6a2105200641746a22060d000b0b2002a72205450d042005410c6c450d04200c10350c040b2002422088220ea72106200f410c6ead21020b200c2006410c6c6a22062005ad422086200dad8437020420062008360200200e422086200242ffffffff0f83844280808080107c2102200b417f6a220b0d000b0b200c450d002007450d012009422088a721050c050b200a450d00200710350b41b89acc00412e200141286a41c09bcc0041e89acc001046000b1045000b1044000b410021070b2000200a36020420002007360200200041106a20023702002000410c6a200c360200200041086a200536020002402003450d00200410350b200141306a24000b970403017f017e017f23004190016b22052400200520013602040240200541046a20022004ad4220862003ad8410322206422088a72201450d002006a722072d0000220341014b0d004100210202400240024020030e020100010b41002102200541003a008801200741016a21042001417f6a2101034020012002460d02200541c8006a20026a200420026a2d00003a00002005200241016a22033a00880120032102200341c000470d000b200541086a41386a200541c8006a41386a290300370300200541086a41306a200541c8006a41306a290300370300200541086a41286a200541c8006a41286a290300370300200541086a41206a200541c8006a41206a290300370300200541086a41186a200541c8006a41186a290300370300200541086a41106a200541c8006a41106a290300370300200541086a41086a200541c8006a41086a29030037030020052005290348370308410121020b200020023a000020002005290308370001200041096a200541106a290300370000200041116a200541186a290300370000200041196a200541206a290300370000200041216a200541286a290300370000200041296a200541306a290300370000200041316a200541386a290300370000200041396a200541c0006a2903003700002007103520054190016a24000f0b200241ff0171450d00200541003a0088010b41b89acc00412e200541c8006a41c09bcc0041e89acc001046000bac0501077f23004190016b2202240002400240024002402000410c6a2802002203417f4c0d0020002802042104200028020021050240024020030d0041002106410121070c010b200310332207450d02200321060b0240024020062003490d00200621080c010b200641017422082003200820034b1b22084100480d03024020060d002008103322070d010c050b20062008460d0020072006200810372207450d040b200720042003109d082106200241f8006a200041106a10a603200241106a410c6a2003360200200241106a41086a22032008360200200241206a2002290378370300200241286a2208200241f8006a41086a280200360200200241106a41306a200041306a290200370300200241106a41386a200041386a290200370300200241106a41c0006a200041c0006a290200370300200241106a41c8006a200041c8006a290200370300200241106a41d0006a200041d0006a290200370300200241106a41d8006a200041d8006a290200370300200241106a41e0006a200041e0006a2902003703002002200636021420022005360210200220002802243602342002200029021c37022c200220002902283703382002410c6a4110360200200241fcc7c400360200200241043602042001411c6a28020021002002200241106a360208200128021821062002418c016a41023602002002420237027c20024190cec400360278200220023602880120062000200241f8006a1043210602402003280200450d00200228021410350b024020082802002203450d00200228022021002003410c6c210303400240200041046a280200450d00200028020010350b2000410c6a2100200341746a22030d000b0b0240200241246a2802002200450d002000410c6c450d00200228022010350b20024190016a240020060f0b1044000b1045000b103e000b103c000b980201027f230041206b220224002002200128021841b0b4cc0041002001411c6a28020028020c1100003a00102002200136020841012101200241013a00112002410036020c200220003602182002200041286a36021c200241086a200241186a41a0cec400106f2002411c6a41b0cec400106f1a20022d0010210002400240200228020c22030d00200021010c010b0240200041ff01710d00024020034101470d0020022d001141ff0171450d00200228020822002d00004104710d0041012101200028021841d6a0c00041012000411c6a28020028020c1100000d010b2002280208220128021841cca6cc0041012001411c6a28020028020c11000021010b200220013a00100b200241206a2400200141ff01714100470b1c00200128021841ed9dcc00410f2001411c6a28020028020c1100000bed93010a047f017e017f017e077f017e1f7f057e047f017e230041b0066b22002400200041a0056a41186a22014200370300200041a0056a41106a22024200370300200041a0056a41086a22034200370300200042003703a00541a3edcb00ad4280808080f0008422041001220529000021062003200541086a290000370300200020063703a0052005103541a5ebcb00ad4280808080c0018410012205290000210620004180046a41086a2207200541086a29000037030020002006370380042005103520022000290380042206370300200041d0046a41086a22082003290300370300200041d0046a41106a22092006370300200041d0046a41186a220a2007290300370300200020002903a0053703d004200041206a200041d0046a412010c0012000280224210b2000280220210c200142003703002002420037030020034200370300200042003703a0054188e8cb00ad42808080808001841001220529000021062003200541086a290000370300200020063703a00520051035418fd1cb00ad4280808080c000841001220529000021062007200541086a290000370300200020063703800420051035200220002903800422063703002008200329030037030020092006370300200a2007290300370300200020002903a0053703d004200041a0056a200041d0046a10d80220002802a005210d20002902a405210e200142003703002002420037030020034200370300200042003703a00520041001220529000021042003200541086a290000370300200020043703a0052005103541f393ca00ad4280808080a001841001220529000021042007200541086a290000370300200020043703800420051035200220002903800422043703002008200329030037030020092004370300200a2007290300370300200020002903a0053703d004200041a0056a200041d0046a10fe0120002802a0052205410120051b210f20002902a405420020051b2204a72110024002400240024002400240024002402004422088a72205450d00200f200541057422116a211220004194016a2113200041d0046a41206a211420004198036a4104722115200041e0026a41047221164102210541002117034020004180026a41186a200f20176a221841186a221929000037030020004180026a41106a201841106a221a29000037030020004180026a41086a201841086a221b290000370300200020182900003703800220162018290000370000201641086a201b290000370000201641106a201a290000370000201641186a201929000037000020002005417e6a221a3602e002410021190240201a201610b9040d0020004198036a41206a200041e0026a41206a28020036020020004198036a41186a200041e0026a41186a29030037030020004198036a41106a200041e0026a41106a29030037030020004198036a41086a200041e0026a41086a290300370300200020002903e00237039803200041a0026a41186a2219201541186a221a290000370300200041a0026a41106a221b201541106a221c290000370300200041a0026a41086a221d201541086a221e290000370300200020152900003703a002200a201a2900003703002009201c2900003703002008201e290000370300200020152900003703d004200041f0006a200041d0046a108402200041c0026a41186a221a2019290300370300200041c0026a41106a221c201b290300370300200041c0026a41086a221b201d290300370300200020002903a0023703c0022000280290012219450d0020142000290370370300201441186a200041f0006a41186a290300370300201441106a200041f0006a41106a290300370300201441086a200041f0006a41086a290300370300200a201a2903003703002009201c2903003703002008201b290300370300200041a0066a41086a221a201341086a280200360200200020002903c0023703d004200020132902003703a006200041a0056a41386a221b200041d0046a41386a290300370300200041a0056a41306a221c200041d0046a41306a290300370300200041a0056a41286a221d200041d0046a41286a290300370300200041a0056a41206a221e20142903003703002001200a2903003703002002200929030037030020032008290300370300200020002903d0043703a00520004180046a41386a201b29030037030020004180046a41306a201c29030037030020004180046a41286a201d29030037030020004180046a41206a201e29030037030020004180046a41186a200129030037030020004180046a41106a200229030037030020072003290300370300200020002903a00537038004200041386a41086a201a280200360200200020002903a0063703380b200041c0036a41086a2007290300370300200041c0036a41106a20004180046a41106a290300370300200041c0036a41186a20004180046a41186a290300370300200041c0036a41206a20004180046a41206a290300370300200041c0036a41286a20004180046a41286a290300370300200041c0036a41306a20004180046a41306a290300370300200041c0036a41386a20004180046a41386a29030037030020004188036a41086a200041386a41086a28020036020020002000290380043703c003200020002903383703880320190d02200541016a21052011201741206a2217470d000b0b2000410036023020004208370328201041ffffff3f71450d01200f10350c010b200041b0016a41386a2216200041c0036a41386a290300370300200041b0016a41306a2215200041c0036a41306a290300370300200041b0016a41286a221a200041c0036a41286a290300370300200041b0016a41206a221b200041c0036a41206a290300370300200041b0016a41186a2207200041c0036a41186a290300370300200041b0016a41106a2203200041c0036a41106a290300370300200041b0016a41086a2208200041c0036a41086a290300370300200041f0016a41086a220920004188036a41086a280200360200200020002903c0033703b00120002000290388033703f001200041e0006a41086a220a2009280200360200200020002903f001370360200041a0056a41086a22092008290300370300200041a0056a41106a22082003290300370300200041a0056a41186a22032007290300370300200041a0056a41206a221c201b290300370300200041a0056a41286a221b201a290300370300200041a0056a41306a221a2015290300370300200041a0056a41386a22152016290300370300200020002903b0013703a005200041d0046a41086a2216200a280200360200200020002903603703d00441d00010332207450d01200720002903a00537030020072019360240200720002903d004370244200741386a2015290300370300200741306a201a290300370300200741286a201b290300370300200741206a201c290300370300200741186a2003290300370300200741106a2008290300370300200741086a2009290300370300200741cc006a20162802003602002000428180808010370254200020073602500240201141606a2017460d00201841206a2116201120176b41606a211b200041d4016a211c20004198036a4104722115200041e0026a4104722118034020004180026a41186a201641186a221729000037030020004180026a41106a201641106a221929000037030020004180026a41086a201641086a221a290000370300200020162900003703800220162900002104201841186a201729000037000020182004370000201841086a201a290000370000201841106a201929000037000020002005417f6a22193602e0024100211702402019201810b9040d0020004198036a41206a200041e0026a41206a28020036020020004198036a41186a200041e0026a41186a29030037030020004198036a41106a200041e0026a41106a29030037030020004198036a41086a200041e0026a41086a290300370300200020002903e00237039803200041a0026a41186a2217201541186a221a290000370300200041a0026a41106a2208201541106a2203290000370300200041a0026a41086a2209201541086a220a290000370300200020152900003703a002200041d0046a41186a2219201a290000370300200041d0046a41106a221a2003290000370300200041d0046a41086a2203200a290000370300200020152900003703d004200041b0016a200041d0046a108402200041c0026a41186a220a2017290300370300200041c0026a41106a22112008290300370300200041c0026a41086a22082009290300370300200020002903a0023703c00220002802d0012217450d00201420002903b001370300201441186a200041b0016a41186a290300370300201441106a200041b0016a41106a290300370300201441086a200041b0016a41086a2903003703002019200a290300370300201a201129030037030020032008290300370300200041a0066a41086a2208201c41086a280200360200200020002903c0023703d0042000201c2902003703a006200041a0056a41386a2209200041d0046a41386a290300370300200041a0056a41306a220a200041d0046a41306a290300370300200041a0056a41286a2211200041d0046a41286a290300370300200041a0056a41206a221d200041d0046a41206a290300370300200041a0056a41186a221e2019290300370300200041a0056a41106a2219201a290300370300200041a0056a41086a221a2003290300370300200020002903d0043703a00520004180046a41386a200929030037030020004180046a41306a200a29030037030020004180046a41286a201129030037030020004180046a41206a201d29030037030020004180046a41186a201e29030037030020004180046a41106a201929030037030020004180046a41086a201a290300370300200020002903a00537038004200041386a41086a2008280200360200200020002903a0063703380b200041c0036a41086a20004180046a41086a290300370300200041c0036a41106a20004180046a41106a290300370300200041c0036a41186a20004180046a41186a290300370300200041c0036a41206a20004180046a41206a290300370300200041c0036a41286a20004180046a41286a290300370300200041c0036a41306a20004180046a41306a290300370300200041c0036a41386a20004180046a41386a29030037030020004188036a41086a200041386a41086a28020036020020002000290380043703c0032000200029033837038803024020170d00201641206a2116200541016a2105201b41606a221b0d010c020b0b200041f0006a41386a221f200041c0036a41386a2203290300370300200041f0006a41306a2220200041c0036a41306a2208290300370300200041f0006a41286a2221200041c0036a41286a2209290300370300200041f0006a41206a2222200041c0036a41206a220a290300370300200041f0006a41186a2223200041c0036a41186a2211290300370300200041f0006a41106a2224200041c0036a41106a221c290300370300200041f0006a41086a2225200041c0036a41086a221d290300370300200041f0016a41086a222620004188036a41086a221e280200360200200020002903c00337037020002000290388033703f001200041e0006a41086a22272026280200360200200020002903f001370360201641206a2116200041d4016a212820004198036a4104722115200041e0026a410472211841012119410121290340200041b0016a41086a222a2025290300370300200041b0016a41106a222b2024290300370300200041b0016a41186a222c2023290300370300200041b0016a41206a221a2022290300370300200041b0016a41286a221b2021290300370300200041b0016a41306a22012020290300370300200041b0016a41386a2213201f290300370300200020002903703703b001200041a0056a41086a222d2027280200360200200020002903603703a005024020292019470d00200041d0006a2019410110a301200028025021070b2007202941d0006c6a221920002903b001370300202b2903002104202c2903002106201a290300212e201b290300212f2001290300213020132903002131202a290300213220192017360240201941086a2032370300201920002903a005370244201941cc006a202d280200360200201941386a2031370300201941306a2030370300201941286a202f370300201941206a202e370300201941186a2006370300201941106a20043703002000202941016a222936025820162012460d01034020004180026a41186a201641186a221729000037030020004180026a41106a201641106a221929000037030020004180026a41086a201641086a221a2900003703002000201629000037038002200020053602e002201a2900002104201929000021062016290000212e201841186a2017290000370000201841106a2006370000201841086a20043700002018202e3700004100211702402005201810b9040d0020004198036a41206a200041e0026a41206a28020036020020004198036a41186a200041e0026a41186a29030037030020004198036a41106a200041e0026a41106a29030037030020004198036a41086a200041e0026a41086a290300370300200020002903e00237039803200041a0026a41186a2217201541186a221a290000370300200041a0026a41106a2201201541106a221b290000370300200041a0026a41086a2213201541086a2233290000370300200020152900003703a002200041d0046a41186a2219201a290000370300200041d0046a41106a221a201b290000370300200041d0046a41086a221b2033290000370300200020152900003703d004200041b0016a200041d0046a108402200041c0026a41186a22332017290300370300200041c0026a41106a22342001290300370300200041c0026a41086a22012013290300370300200020002903a0023703c00220002802d0012217450d00201420002903b001370300201441186a202c290300370300201441106a202b290300370300201441086a202a29030037030020192033290300370300201a2034290300370300201b2001290300370300200041a0066a41086a2201202841086a280200360200200020002903c0023703d004200020282902003703a006200041a0056a41386a2213200041d0046a41386a290300370300200041a0056a41306a2233200041d0046a41306a290300370300200041a0056a41286a2234200041d0046a41286a290300370300200041a0056a41206a2235200041d0046a41206a290300370300200041a0056a41186a22362019290300370300200041a0056a41106a2219201a290300370300202d201b290300370300200020002903d0043703a00520004180046a41386a201329030037030020004180046a41306a203329030037030020004180046a41286a203429030037030020004180046a41206a203529030037030020004180046a41186a203629030037030020004180046a41106a201929030037030020004180046a41086a202d290300370300200020002903a00537038004200041386a41086a2001280200360200200020002903a0063703380b201d20004180046a41086a290300370300201c20004180046a41106a290300370300201120004180046a41186a290300370300200a20004180046a41206a290300370300200920004180046a41286a290300370300200820004180046a41306a290300370300200320004180046a41386a290300370300201e200041386a41086a28020036020020002000290380043703c0032000200029033837038803024020170d00200541016a21052012201641206a2216470d010c030b0b201f200329030037030020202008290300370300202120092903003703002022200a290300370300202320112903003703002024201c2903003703002025201d2903003703002026201e280200360200200020002903c00337037020002000290388033703f00120272026280200360200200020002903f001370360201641206a2116200541016a2105200028025421190c000b0b0240201041ffffff3f71450d00200f10350b200041286a41086a200041d0006a41086a280200360200200020002903503703280b200041a0056a41186a22174200370300200041a0056a41106a22154200370300200041a0056a41086a22054200370300200042003703a00541a3edcb00ad4280808080f000841001221629000021042005201641086a290000370300200020043703a0052016103541a5ebcb00ad4280808080c0018410012216290000210420004180046a41086a2218201641086a2900003703002000200437038004201610352002200029038004370000200241086a2018290300370000200041d0046a41086a22162005290300370300200041d0046a41106a2015290300370300200041d0046a41186a2017290300370300200020002903a0053703d004200041186a200041d0046a412010c001200028021c2117200028021821154188e8cb00ad42808080808001841001220529000021042018200541086a2900003703002000200437038004200510354190e8cb00ad4280808080a002841001220529000021042016200541086a290000370300200020043703d004200510354100211820002017410020151b3602702000200041f0006aad22044280808080c00084100322052900003703b00120051035200041ac056a200041f4006a3602002000200041b0016a41086a22143602a4052000200041f0006a3602a8052000200041b0016a3602a005200041c0036a200041a0056a107b20002802c803221541206a2216417f4c0d0120002802c00321190240024020160d00410121050c010b201610332205450d01201621180b024002402018410f4d0d00201821170c010b201841017422174110201741104b1b22174100480d03024020180d002017103322050d010c060b20182017460d0020052018201710372205450d050b2005200029038004370000200541086a20004180046a41086a2903003700000240024020174170714110460d00201721180c010b201741017422184120201841204b1b22184100480d0320172018460d0020052017201810372205450d050b200520002903d004370010200541186a200041d0046a41086a29030037000002400240201841606a2015490d00201821170c010b2015415f4b0d03201841017422172016201720164b1b22174100480d0320182017460d0020052018201710372205450d050b200541206a20192015109d081a024020002802c403450d00201910350b2016ad4220862005ad84100802402017450d00200510350b200041a0056a41186a22174200370300200041a0056a41106a22154200370300200041a0056a41086a22054200370300200042003703a00541a3edcb00ad4280808080f000841001221629000021062005201641086a290000370300200020063703a0052016103541a5ebcb00ad4280808080c0018410012216290000210620004180046a41086a2218201641086a2900003703002000200637038004201610352002200029038004370000200241086a2018290300370000200041d0046a41086a22162005290300370300200041d0046a41106a2015290300370300200041d0046a41186a2017290300370300200020002903a0053703d004200041106a200041d0046a412010c00120002802142117200028021021154188e8cb00ad42808080808001841001220529000021062018200541086a29000037030020002006370380042005103541f1c8c400ad4280808080e001841001220529000021062016200541086a290000370300200020063703d004200510354100211820002017410020151b360270200020044280808080c00084100322052900003703b00120051035200041ac056a200041f4006a360200200020143602a4052000200041f0006a3602a8052000200041b0016a3602a005200041c0036a200041a0056a107b20002802c803221541206a2216417f4c0d0120002802c00321190240024020160d00410121050c010b201610332205450d01201621180b024002402018410f4d0d00201821170c010b201841017422174110201741104b1b22174100480d03024020180d00201710332205450d060c010b20182017460d0020052018201710372205450d050b2005200029038004370000200541086a20004180046a41086a2903003700000240024020174170714110460d00201721180c010b201741017422184120201841204b1b22184100480d0320172018460d0020052017201810372205450d050b200520002903d004370010200541186a200041d0046a41086a29030037000002400240201841606a2015490d00201821170c010b2015415f4b0d03201841017422172016201720164b1b22174100480d0320182017460d0020052018201710372205450d050b200541206a20192015109d081a024020002802c403450d00201910350b2016ad4220862005ad84100802402017450d00200510350b200e4200200d1b210e0240024002400240024002400240024002402000280230450d00200041a0056a200041286a10c104200041db046a200041a0056a41086a280200360000200020002903a0053700d304200041ac056a200041d7046a290000370000200041023a00a4052000410f3a00a005200020002900d0043700a50541b0b4cc004100200041a0056a10d401200041c8006a200041286a41086a2802003602002000200e422088a7223536023c2000200b4100200c1b221b3602382000200029032837034020004188036a200041386a41086a10c1042000280290032114200028028c0321102000280288032128410410332205450d092005201b36000020004284808080c000370284042000200536028004200041a0056a10c204200041d0046a20002802a005221620002802a80510e00220002902d404420020002802d00422051b21042005410120051b211a024020002802a405450d00201610350b200020044220883e02c4032000201a3602c003200041086a200041c0036a10c40141002115024020002802080d00200028020c220720002802c403221841246e2205200520074b1bad42247e2206422088a70d0b2006a72205417f4c0d0b0240024020050d00410421150c010b200510332215450d0b0b41002119200041003602d804200020153602d0042000200541246e22053602d4042007450d0041002119410021020240024002400340201822034104490d02200241016a2102200020002802c003221841046a3602c0032018280000210841002105200041003a00c0052003417c6a2117034020172005460d02200041a0056a20056a201820056a221641046a2d00003a00002000201641056a3602c0032000200541016a22163a00c0052016210520164120470d000b200041c0026a41186a2209200041a0056a41186a290300370300200041c0026a41106a220a200041a0056a41106a290300370300200041c0026a41086a220f200041a0056a41086a290300370300200020002903a0053703c0020240201920002802d404470d00200041d0046a20194101108d0120002802d004211520002802d80421190b201720166b21182015201941246c6a22052008360200200520002903c0023702042005410c6a200f290300370200200541146a200a2903003702002005411c6a20092903003702002000201941016a22193602d80420022007470d000b2000200320166b417c6a3602c40320002802d40421050c030b200041003602c403200541ff0171450d01200041003a00c0050c010b200020033602c4030b024020002802d4042205450d00200541246c450d00201510350b410021150b200041a0056a20004180046a10c304200041d0046a20002802a005220720002802a80510b5022019410020151b21162005410020151b211820002902d404420020002802d00422051b21062015410420151b21172005410120051b2105024020002802a405450d00200710350b200041b8036a2016360200200041b4036a2018360200200041a8036a200637030020004198036a41086a20004180046a41086a280200360200200020002903800437039803200020173602b003200020053602a40302402004a7450d00201a10350b2014450d01200041b0036a2134200041a4036a212d2028201441d0006c6a210f200041a0056a41d0006a2133200041a0056a41306a2109200041a0056a41206a210a20004180046a41306a211120004180046a41206a211c20004180046a41c4006a211d41002112202821070340200041a0056a41386a22162007220541386a2903003703002009200541306a290300370300200041a0056a41286a2218200541286a290300370300200a200541206a290300370300200041a0056a41186a2202200541186a290300370300200041a0056a41106a2203200541106a290300370300200041a0056a41086a2208200541086a290300370300200041a0066a41086a2217200541cc006a280200360200200020052903003703a0052000200541c4006a2902003703a006200541d0006a2107200541c0006a2802002205450d03200041c0036a41386a22152016290300370300200041c0036a41306a22162009290300370300200041c0036a41286a22192018290300370300200041c0036a41206a2218200a290300370300200041c0036a41186a22142002290300370300200041c0036a41106a221a2003290300370300200041c0036a41086a221e2008290300370300200041f0016a41086a22012017280200360200200020002903a0053703c003200020002903a0063703f00120004180046a41386a20152903003703002011201629030037030020004180046a41286a2019290300370300201c201829030037030020004180046a41186a2215201429030037030020004180046a41106a2219201a29030037030020004180046a41086a221a201e290300370300200020002903c00337038004200020053602c004201d20002903f001370200201d41086a2001280200360200410410332214450d0a2014201b360000411810332205450d0a200042183702a405200020053602a005200541002902f8be46370000200541086a4100290280bf46370000200041103602a8054104200041a0056a10770240024020002802a405221720002802a80522056b4104490d0020002802a0052116201721180c010b200541046a22162005490d0d201741017422182016201820164b1b22184100480d0d0240024020170d00024020180d00410121160c020b201810332216450d110c010b20002802a005211620172018460d0020162017201810372216450d100b200020183602a405200020163602a0050b201620056a20142800003600002000200541046a22173602a8050240201820176b411f4b0d00201741206a221e2017490d0d20184101742201201e2001201e4b1b221e4100480d0d0240024020180d000240201e0d00410121160c020b201e10332216450d110c010b2018201e460d0020162018201e10372216450d100b2000201e3602a405200020163602a0050b201620176a2216200029038004370000201641186a2015290300370000201641106a2019290300370000201641086a201a2903003700002000200541246a3602a8052000201c3602d004200041d0046a200041a0056a10cf01200020113602d004200041d0046a200041a0056a10cf0120002802c004210520002802c8042216200041a0056a107702402016450d00201641306c211503400240024020002802a405221720002802a80522186b4120490d0020002802a00521160c010b201841206a22162018490d0f201741017422192016201920164b1b22194100480d0f0240024020170d00024020190d00410121160c020b201910332216450d130c010b20002802a005211620172019460d0020162017201910372216450d120b200020193602a405200020163602a0050b201620186a2216200541106a290000370000201641186a200541286a290000370000201641106a200541206a290000370000201641086a200541186a2900003700002000201841206a3602a805200020053602d004200041d0046a200041a0056a10cf01200541306a2105201541506a22150d000b0b20002802a405211620003502a80542208620002802a0052218ad84100922052900002104200541086a2900002106200541106a290000212e200041b0016a41186a221e200541186a290000370300200041b0016a41106a2201202e370300200041b0016a41086a22132006370300200020043703b0012005103502402016450d00201810350b20141035200041a0056a200041b0016a10c404200020002802a005221620002802a80541b0b4cc0041004100108a0220002802002105024020002802a405450d00201610350b024002400240024020054101460d00200041d0046a20004180046a41d000109d081a2000410036027820004201370370200041f0006a41004100108a01200041e0026a41086a22052000280278360200200020002903703703e002200041a0056a200041d0046a41d000109d081a203341086a2005280200360200203320002903e002370200200041f0006a200041b0016a10c4042000350278210420002802702112200041003602d804200042013703d004412010332205450d12200041203602d404200020053602d004200520002903a005370000200541086a2008290300370000200541106a2003290300370000200541186a2002290300370000200041203602d8042000200a3602e002200041e0026a200041d0046a10cf01200020093602e002200041e0026a200041d0046a10cf0120002802e005210520002802e8052216200041d0046a107702402016450d00201641306c211503400240024020002802d404221720002802d80422186b4120490d0020002802d00421160c010b201841206a22162018490d13201741017422192016201920164b1b22194100480d130240024020170d00024020190d00410121160c020b201910332216450d170c010b20002802d004211620172019460d0020162017201910372216450d160b200020193602d404200020163602d0040b201620186a2216200541106a290000370000201641186a200541286a290000370000201641106a200541206a290000370000201641086a200541186a2900003700002000201841206a3602d804200020053602e002200041e0026a200041d0046a10cf01200541306a2105201541506a22150d000b0b20002802f005210520002802f8052216200041d0046a10770240024020160d0020002802d804211620002802d404211420002802d00421190c010b2016410574211a410020002802d80422166b211520002802d4042117034002400240201720156a4120490d0020002802d0042119201721140c010b201641206a22182016490d13201741017422192018201920184b1b22144100480d130240024020170d00024020140d00410121190c020b201410332219450d170c010b20002802d004211920172014460d0020192017201410372219450d160b200020143602d404200020193602d004201421170b201920166a22182005290000370000201841186a200541186a290000370000201841106a200541106a290000370000201841086a200541086a2900003700002000201641206a22163602d804201541606a2115200541206a2105201a41606a221a0d000b0b20044220862012ad842016ad4220862019ad84100202402014450d00201910350b02402000280274450d00201210350b024020002802e4052205450d00200541306c450d0020002802e00510350b024020002802f40541ffffff3f71450d0020002802f00510350b200041d0046a41186a2214201e290300370300200041d0046a41106a221a2001290300370300200041d0046a41086a221e2013290300370300200020002903b0013703d00420002802b003211541002105024020002802b803221941014b0d00024020190e020003000b200220142903003703002003201a2903003703002008201e290300370300200020002903d0043703a005410021050c030b20192116034020052016410176221820056a22172015201741246c6a280200201b4b1b2105201620186b221641014b0d000c020b0b20002802c4042205450d02200541306c450d0220002802c00410350c020b02402015200541246c6a2802002216201b460d0020052016201b496a21050b200220142903003703002003201a2903003703002008201e290300370300200020002903d0043703a005201920054f0d0020052019104d000b0240201920002802b403470d00203420194101108d0120002802b00321150b2015200541246c6a221641246a2016201920056b41246c109e081a2016201b360200201620002903a0053702042016410c6a2008290300370200201641146a20032903003702002016411c6a20022903003702002000201941016a3602b803200220142903003703002003201a2903003703002008201e290300370300200020002903d0043703a005024020002802ac03220520002802a803470d00202d20054101108a0120002802ac0321050b20002802a40320054105746a221620002903a005370000201641186a2002290300370000201641106a2003290300370000201641086a2008290300370000410121122000200541016a3602ac030b2007200f470d000b200f21070c020b200041013a00a4052000410f3a00a00541b0b4cc004100200041a0056a10d401200028022c2205450d07200541d0006c450d07200028022810350c070b2010450d01201041d0006c450d01202810350c010b0240200f2007460d0003402007220541d0006a21070240200541c4006a2802002216450d00201641306c450d00200541c0006a28020010350b200f2007470d000b0b02402010450d00201041d0006c450d00202810350b2012410171450d00024020002802ac032205450d0020002802a4032118200541057441406a2116200041e4056a2105034020004180026a201810c404200041a0056a200028028002221520002802880210d70220004180046a41086a2219200041a0056a41086a29030037030020004180046a41106a2214200041a0056a41106a29030037030020004180046a41186a221a200041a0056a41186a29030037030020004180046a41206a2207200041a0056a41206a29030037030020004180046a41286a2202200041a0056a41286a29030037030020004180046a41306a2203200041a0056a41306a29030037030020004180046a41386a2208200041a0056a41386a290300370300200041e0026a41086a2209200541086a290200370300200041e0026a41106a220a200541106a290200370300200041e0026a41186a220f200541186a280200360200200020002903a00537038004200020052902003703e002024020002802e0052217450d00200041f0006a41386a2008290300370300200041f0006a41306a2003290300370300200041f0006a41286a2002290300370300200041f0006a41206a2007290300370300200041f0006a41186a201a290300370300200041f0006a41106a2014290300370300200041f0006a41086a2019290300370300200041d0046a41086a2009290300370300200041d0046a41106a200a290300370300200041d0046a41186a200f2802003602002000200029038004370370200020002903e0023703d0040b0240200028028402450d00201510350b20170d03201841206a2118201641606a22164140470d000b0b4108210a410021084100210f0c020b0240200028029c03450d0020002802980310350b024020002802a80341ffffff3f71450d0020002802a40310350b20002802b4032205450d02200541246c450d0220002802b00310350c020b200041c0036a41386a2214200041f0006a41386a290300370300200041c0036a41306a221a200041f0006a41306a290300370300200041c0036a41286a2207200041f0006a41286a290300370300200041c0036a41206a2202200041f0006a41206a290300370300200041c0036a41186a2203200041f0006a41186a290300370300200041c0036a41106a2208200041f0006a41106a290300370300200041c0036a41086a2209200041f0006a41086a290300370300200041a0026a41086a220a200041d0046a41086a2205290300370300200041a0026a41106a220f200041d0046a41106a2215290300370300200041a0026a41186a2211200041d0046a41186a2219280200360200200020002903703703c003200020002903d0043703a002200041b0016a41086a221c2009290300370300200041b0016a41106a22092008290300370300200041b0016a41186a22082003290300370300200041b0016a41206a22032002290300370300200041b0016a41286a22022007290300370300200041b0016a41306a2207201a290300370300200041b0016a41386a221a2014290300370300200041c0026a41086a2214200a290300370300200041c0026a41106a220a200f290300370300200041c0026a41186a220f2011280200360200200020002903c0033703b001200020002903a0023703c002200041a0056a41086a2211201c290300370300200041a0056a41106a221c2009290300370300200041a0056a41186a22092008290300370300200041a0056a41206a22082003290300370300200041a0056a41286a22032002290300370300200041a0056a41306a22022007290300370300200041a0056a41386a2207201a290300370300200020002903b0013703a005200520142903003703002015200a2903003703002019200f280200360200200020002903c0023703d00441e0001033220a450d04200a20002903a005370300200a2017360240200a20002903d004370244200a41386a2007290300370300200a41306a2002290300370300200a41286a2003290300370300200a41206a2008290300370300200a41186a2009290300370300200a41106a201c290300370300200a41086a2011290300370300200a41cc006a2005290300370200200a41d4006a2015290300370200200a41dc006a201928020036020020004281808080103702a4062000200a3602a006024020164160470d00410121084101210f0c010b201841206a2117200041a0056a41c4006a211841012108034020004180026a201710c404200041a0056a200028028002220520002802880210d70220004180046a41086a220f200041a0056a41086a221929030037030020004180046a41106a2211200041a0056a41106a221429030037030020004180046a41186a221c200041a0056a41186a221a29030037030020004180046a41206a221d200041a0056a41206a220729030037030020004180046a41286a221e200041a0056a41286a220229030037030020004180046a41306a2201200041a0056a41306a220329030037030020004180046a41386a2213200041a0056a41386a2209290300370300200041e0026a41086a2212201841086a290200370300200041e0026a41106a2233201841106a290200370300200041e0026a41186a2234201841186a280200360200200020002903a00537038004200020182902003703e002024020002802e0052215450d00200041d0046a41386a2013290300370300200041d0046a41306a2001290300370300200041d0046a41286a201e290300370300200041d0046a41206a201d290300370300200041d0046a41186a201c290300370300200041d0046a41106a2011290300370300200041d0046a41086a200f290300370300200041f0006a41086a2012290300370300200041f0006a41106a2033290300370300200041f0006a41186a203428020036020020002000290380043703d004200020002903e0023703700b0240200028028402450d00200510350b02400240024020150d002016450d010c020b200041c0036a41386a2205200041d0046a41386a290300370300200041c0036a41306a221d200041d0046a41306a290300370300200041c0036a41286a221e200041d0046a41286a290300370300200041c0036a41206a2201200041d0046a41206a290300370300200041c0036a41186a2213200041d0046a41186a220f290300370300200041c0036a41106a2212200041d0046a41106a2211290300370300200041c0036a41086a2233200041d0046a41086a221c290300370300200041a0026a41086a2234200041f0006a41086a290300370300200041a0026a41106a222d200041f0006a41106a290300370300200041a0026a41186a2228200041f0006a41186a280200360200200020002903d0043703c003200020002903703703a002200041b0016a41086a22102033290300370300200041b0016a41106a22332012290300370300200041b0016a41186a22122013290300370300200041b0016a41206a22132001290300370300200041b0016a41286a2201201e290300370300200041b0016a41306a221e201d290300370300200041b0016a41386a221d2005290300370300200041c0026a41086a22052034290300370300200041c0026a41106a2234202d290300370300200041c0026a41186a222d2028280200360200200020002903c0033703b001200020002903a0023703c0022019201029030037030020142033290300370300201a201229030037030020072013290300370300200220012903003703002003201e2903003703002009201d290300370300200020002903b0013703a005201c200529030037030020112034290300370300200f202d280200360200200020002903c0023703d0040240200820002802a406470d00200041a0066a2008410110a40120002802a006210a0b200a200841e0006c6a220520002903a005370300200541106a2014290300370300200541086a201929030037030020032903002104200929030021062002290300212e2007290300212f201a2903002130200541c0006a2015360200200541186a2030370300200541206a202f370300200541286a202e370300200541c4006a20002903d004370200200541386a2006370300200541306a2004370300200541cc006a201c290300370200200541d4006a2011290300370200200541dc006a200f2802003602002000200841016a22083602a80620160d010b20002802a406210f0c020b201741206a2117201641606a21160c000b0b200041a0056a41206a20004198036a41206a2802002216360200200041a0056a41106a20004198036a41106a290300370300200041a0056a41086a20004198036a41086a290300370300200041a0056a41186a20004198036a41186a290300220437030020002000290398033703a005201641246c41046a2205417f4c0d040240024020050d0041012118410021050c010b200510332218450d040b200041003602d804200020183602d004200020053602d4042016200041d0046a10770240024020160d0020002802d804211820002802d404211720002802d00421190c010b2004a72205201641246c6a2109410020002802d80422186b211420002802d404211703402005280200211602400240201720146a4104490d0020002802d0042119201721150c010b201841046a22152018490d08201741017422192015201920154b1b22154100480d080240024020170d00024020150d00410121190c020b201510332219450d0c0c010b20002802d004211920172015460d0020192017201510372219450d0b0b200020153602d404200020193602d0040b201920186a20163600002000201841046a22173602d804412010332216450d05201641186a221a2005411c6a290000370000201641106a2207200541146a290000370000201641086a22022005410c6a2900003700002016200541046a29000037000002400240201520146a417c6a411f4d0d00201521170c010b201741206a22032017490d08201541017422172003201720034b1b22174100480d080240024020150d00024020170d00410121190c020b201710332219450d0c0c010b20152017460d0020192015201710372219450d0b0b200020173602d404200020193602d0040b201920186a221541046a20162900003700002015411c6a201a290000370000201541146a20072900003700002015410c6a20022900003700002000201841246a22183602d804201610352014415c6a2114200541246a22052009470d000b0b200041d0046a10c20420002802d0042105200020002802d8043602840420002005360280042019201820004180046a109403024020002802d404450d00200510350b02402017450d00201910350b200041d0046a200041a0056a10c30420002802d0042105200020002802d80436028404200020053602800420002802ac052216200041b4056a28020020004180046a10c504024020002802d404450d00200510350b024020002802a405450d0020002802a00510350b0240200041b0056a28020041ffffff3f71450d00201610350b0240200041bc056a2802002205450d00200541246c450d0020002802b80510350b200a0d010b200028024021170240200041c8006a2802002205450d00200541d0006c2116201741c4006a21050340024020052802002218450d00201841306c450d002005417c6a28020010350b200541d0006a2105201641b07f6a22160d000b0b0240200041c4006a2802002205450d00200541d0006c450d00201710350b41eba3cc00ad4280808080c00184100641dca3cc00ad4280808080f0018410060c010b4100211802402035410a6e417f7320086a221620084b0d0020354101203541014b1b2205418094ebdc036e221820052018418094ebdc036c476a22184101201841014b1b221820054b0d0520002005201641036c221620052016491b20186ead428094ebdc037e200520186ead8042ffffffff0f834280bbb0217e428094ebdc0380a722053602a0052000418094ebdc033602a405200041a0056a2005418094ebdc034b4102746a28020021180b200041003602a805200042043703a005200041a0056a4100200810860120002802a005210720002802a805211a02400240024020080d0020002802a405211141012116200a41002007201a201b10fd010d010c020b2007201a4102746a210520082116034020052018360200200541046a21052016417f6a22160d000b20002802a405211141012116200a20082007201a20086a221a201b10fd01450d010b200041a0026a41186a4200370300200041a0026a41106a22184200370300200041a0026a41086a22054200370300200042003703a00241a2e8cb00ad42808080808001841001221629000021042005201641086a290000370300200020043703a0022016103541e6f2c400ad4280808080800284100122162900002104200041a0056a41086a2217201641086a290000370300200020043703a00520161035201820002903a005220437030020004180026a41086a200529030037030020004180026a41106a200437030020004180026a41186a2017290300370300200020002903a00237038002200041a0056a20004180026a10c6020240024020002802a00522020d0041002109200041003602b801200042043703b00141042102410021030c010b200020002902a40522043702b401200020023602b0012004422088a721032004a721090b2008ad42e0007e2204422088a70d032004a72205417f4c0d030240024020050d00410821160c010b200510332216450d030b200041003602c803200020163602c0032000200541e0006e3602c403200041c0036a4100200810a40120002802c803211c02402008450d00200a200841e0006c6a211420002802c003201c41e0006c6a2105200841057441606a410576211d200041a4056a2118200a21160340200041c0026a41086a2217201641086a290300370300200041c0026a41106a2215201641106a290300370300200041c0026a41186a2219201641186a290300370300200020162903003703c002201641206a2903002104201641286a2903002106201641306a290300212e201641386a290300212f20004180046a201641c0006a10c604200041d0046a201641d0006a10a402201841086a200041d0046a41086a280200360200201820002903d00437020020192903002130201529030021312017290300213220002903c0022137200541386a202f370300200541306a202e370300200541286a2006370300200541206a2004370300200541086a203237030020052037370300200541106a2031370300200541c0006a200029038004370300200541c8006a20004180046a41086a280200360200200541186a2030370300200541cc006a20002902a005370200200541d4006a200041a0056a41086a290200370200200541e0006a2105201641e0006a22162014470d000b201c201d6a41016a211c0b200041a8056a201c360200200020002903c0033703a005201a41ffffffff0371201a470d03201a4102742205417f4c0d030240024020050d00410421160c010b200510332216450d030b200041003602d804200020163602d004200020054102763602d404200041d0046a4100201a10860120002802d00420002802d80422054102746a2007201a410274109d081a20004180046a41086a22182005201a6a2205360200200041b4056a2005360200200020002903d0043702ac05024020032009470d00200041b0016a2009410110f90120002802b401210920002802b001210220002802b80121030b20022003411c6c6a220520002903a005370200200041a0056a41086a22162903002104200041a0056a41106a221729030021062005201b360218200541106a2006370200200541086a20043702002000200341016a22153602b801200041a0056a41186a42003703002017420037030020164200370300200042003703a00541a2e8cb00ad42808080808001841001220529000021042016200541086a290000370300200020043703a0052005103541e6f2c400ad42808080808002841001220529000021042018200541086a29000037030020002004370380042005103520172000290380042204370300200041d0046a41086a2016290300370300200041d0046a41106a2004370300200041d0046a41186a2018290300370300200020002903a0053703d0040240024020020d00200041d0046aad428080808080048410070c010b200041a0056a2002201510c704200041d0046aad428080808080048420003502a80542208620002802a0052205ad841002024020002802a405450d00200510350b2002201510c8022009450d002009411c6c450d00200210350b410021160b410410332205450d012005201b360000200041a8056a4284808080c000370300200041b8056a4100290280bf46370300200041c0056a20163a0000200041103a00a005200041a0056a41106a41002902f8be46370300200020053602a40541b0b4cc004100200041a0056a10d4010240201141ffffffff0371450d00200710350b02402008450d00200841e0006c2116200a41d4006a210503400240200541706a2802002218450d00201841306c450d002005416c6a28020010350b0240200528020041ffffff3f71450d002005417c6a28020010350b200541e0006a2105201641a07f6a22160d000b0b0240200f450d00200f41e0006c450d00200a10350b200028024021170240200041c8006a2802002205450d00200541d0006c2116201741c4006a21050340024020052802002218450d00201841306c450d002005417c6a28020010350b200541d0006a2105201641b07f6a22160d000b0b200041c4006a2802002205450d00200541d0006c450d00201710350b0240200e42ffffff3f83500d00200d4101200d1b10350b200041b0066a24000f0b1045000b1044000b103e000b4190edc40041194180efc400103f000b103c000bfe0304027f017e067f077e230041c0006b220224000240024020012802082203ad42d0007e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510332206450d020b20024100360208200220063602002002200541d0006e36020420024100200310a3012002280208210702402003450d002001200341d0006c6a21082002280200200741d0006c6a2105200341047441706a41047621090340200241206a41086a2203200141086a290300370300200241206a41106a2206200141106a290300370300200241206a41186a220a200141186a29030037030020022001290300370320200141206a2903002104200141286a290300210b200141306a290300210c200141386a290300210d200241106a200141c0006a10c604200a290300210e2006290300210f2003290300211020022903202111200541386a200d370300200541306a200c370300200541286a200b370300200541206a2004370300200541086a201037030020052011370300200541106a200f370300200541186a200e370300200541c0006a2002290310370300200541c8006a200241106a41086a280200360200200541d0006a2105200141d0006a22012008470d000b200720096a41016a21070b20002002290300370200200041086a2007360200200241c0006a24000f0b1044000b1045000b970503027f017e067f230041d0006b2201240041a2e8cb00ad4280808080800184100122022900002103200141086a41086a200241086a290000370300200120033703082002103541aae8cb00ad4280808080a00284100122022900002103200141186a41086a200241086a29000037030020012003370318200210350240024002400240411010332202450d0041002104200241086a4100290280bf46370000200241002902f8be4637000020012002ad42808080808002841003220529000037033820051035200141cc006a200241106a360200200120023602482001200141386a41086a3602442001200141386a360240200141286a200141c0006a107b200210352001280230220641206a2207417f4c0d01200128022821080240024020070d00410121020c010b200710332202450d01200721040b024002402004410f4d0d00200421050c010b200441017422054110200541104b1b22054100480d03024020040d002005103322020d010c050b20042005460d0020022004200510372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020054170714110460d00200521040c010b200541017422044120200441204b1b22044100480d0320052004460d0020022005200410372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200441606a2006490d00200421050c010b200641206a22052006490d03200441017422092005200920054b1b22054100480d0320042005460d0020022004200510372202450d040b200241206a20082006109d081a2000200736020820002005360204200020023602000240200128022c450d00200810350b200141d0006a24000f0b1045000b1044000b103e000b103c000bbd0603027f017e087f230041d0006b2202240041a2e8cb00ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541b0a5c500ad4280808080e00284100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240411010332203450d0041002105200341086a4100290280bf46370000200341002902f8be4637000020022003ad42808080808002841003220629000037033820061035200241cc006a200341106a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b20031035200241c0006a200128020020012802081098032002280230220741206a2208200228024822096a2201417f4c0d012002280240210a2002280228210b0240024020010d00410121030c010b200110332203450d01200121050b024002402005410f4d0d002005210c0c010b200541017422064110200641104b1b220c4100480d03024020050d00200c103322030d010c050b2005200c460d0020032005200c10372203450d040b20032002290308370000200341086a200241086a41086a29030037000002400240200c4170714110460d00200c21060c010b200c41017422054120200541204b1b22064100480d03200c2006460d002003200c200610372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200641606a2007490d00200621050c010b200741206a22052007490d032006410174220c2005200c20054b1b22054100480d0320062005460d0020032006200510372203450d040b200341206a200b2007109d081a02400240200520086b2009490d00200521060c010b20012008490d03200541017422062001200620014b1b22064100480d03024020050d00024020060d00410121030c020b200610332203450d050c010b20052006460d0020032005200610372203450d040b200320086a200a2009109d081a20002001360208200020063602042000200336020002402002280244450d00200a10350b0240200228022c450d00200b10350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a2e8cb00ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541dff2c400ad4280808080f00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000be503010a7f230041106b22032400024020014105744104722204417f4c0d000240200410332205450d002003410036020820032004360204200320053602002001200310770240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020052104412010332201450d0220012000290000370000200141186a2209200041186a290000370000200141106a220a200041106a290000370000200141086a220b200041086a29000037000002400240200620046b4120490d00200441206a21050c010b024002400240200441206a22052004490d002006410174220c2005200c20054b1b220c4100480d000240024020060d000240200c0d00410121070c020b200c103321070c040b2006200c470d020b200c21060c030b103e000b20072006200c103721070b200c210620070d00103c000b200041206a2100200720046a22042001290000370000200441186a2009290000370000200441106a200a290000370000200441086a200b29000037000020011035200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100202402006450d00200710350b200341106a24000f0b1045000b1044000bb10203027f017e027f230041106b220224000240024020012802082203ad42307e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510332206450d020b20024100360208200220063602002002200541306e3602042002410020031088012002280208210502402003450d002001200341306c6a21062002280200200541306c6a21030340200320012903003703002003200141086a290300370308200341106a200141106a290300370300200341186a200141186a290300370300200341206a200141206a290300370300200341286a200141286a290300370300200341306a2103200541016a2105200141306a22012006470d000b0b20002002290300370200200041086a2005360200200241106a24000f0b1044000b1045000bfe0301067f230041106b22032400024002402002411c6c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b20034100360208200320053602002003200436020420022003107702402002450d0020012002411c6c6a2106034020012802002105200128020822022003107702402002450d002005200241e0006c6a2107034020032005412010782003200541206a36020c2003410c6a200310cf012003200541306a36020c2003410c6a200310cf0120052802402102200528024822042003107702402004450d00200441306c210403402003200241106a412010782003200236020c200241306a21022003410c6a200310cf01200441506a22040d000b0b200541e0006a210820052802502102200528025822042003107702402004450d002004410574210403402003200241201078200241206a2102200441606a22040d000b0b2008210520082007470d000b0b2001411c6a2105200128020c2102200128021422042003107702402004450d002004410274210403402003200228020036020c20032003410c6a41041078200241046a21022004417c6a22040d000b0b2003200128021836020c20032003410c6a410410782005210120052006470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1044000b1045000b960407047f017e017f017e017f017e047f230041e0006b22012400200141306a41186a22024200370300200141306a41106a22034200370300200141306a41086a220442003703002001420037033041d1c4c700ad4280808080e000842205100122062900002107200141d0006a41086a2208200641086a290000370300200120073703502006103520042008290300370300200120012903503703304184eec700ad4280808080b0028422071001220629000021092008200641086a2900003703002001200937035020061035200320012903502209370300200141106a41086a220a2004290300370300200141106a41106a220b2009370300200141106a41186a220c2008290300370300200120012903303703102001200141106a10e102200129030821092001280200210d2002420037030020034200370300200442003703002001420037033020051001220629000021052008200641086a2900003703002001200537035020061035200420082903003703002001200129035037033020071001220629000021052008200641086a2900003703002001200537035020061035200320012903502205370300200a2004290300370300200b2005370300200c2008290300370300200120012903303703102001427f20094200200d1b220520007c220020002005541b370330200141106aad4280808080800484200141306aad42808080808001841002200141e0006a24000bfc0403027f017e057f230041d0006b220224004189fec600ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541e28cc500ad4280808080e00084100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bea3506207f027e027f057e027f077e230041f0106b220224000240024002400240024002400240200141106a2802002203200141146a280200460d00200241f00a6a41c0026a21042002418d0b6a2105200241e10a6a2106200241a80a6a2107200241f00a6a4105722108200241f8076a4105722109200241a00f6a210a200241c00e6a41c0006a210b200241e00e6a210c200241e8086a210d200241f00a6a410472210e200241f8076a410472210f200241f00a6a41146a2110200241f00a6a41106a2111200241f00a6a410d6a2112200241f00a6a410c6a2113200241f00a6a41086a2114200241c8086a2115200241f8076a41146a2116200241f8076a41106a2117200241f8076a410d6a2118200241a8086a2119200241f8076a410c6a211a200241f8076a41086a211b200241f8076a41c0026a211c200241f8076a41046a211d03402001200341d8026a3602102003280200211e200241186a200341046a41c002109d081a200241086a41086a221f200341d0026a2903003703002002200341c8026a290300370308200341c4026a28020022034102460d0120012802182120200241f8076a200241186a41c002109d081a200241f00a6a201d41bc02109d081a20042002290308370300200441086a2221201f290300370300200220033602ac0d200241b8056a200241f00a6a10d8032001200129030020022903b8057c2222370300200241b8056a200241f00a6a41bc02109d081a200241a8056a41086a221f2021290300370300200220042903003703a8050240024020022802ac0d22034102470d00410321030c010b200241f8076a200241b8056a41bc02109d081a201c41086a2221201f290300370300201c20022903a805370300200220033602b40a0240024020022d00c00a41c000490d002020450d0020222001280220290300560d010b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802f8070e1c00011302030405060708090a0b0c0d0e0f1011121313131415161713000b200241c00e6a201b109d03201441086a200241c00e6a41086a290300370300201420022903c00e370300200241003602f00a0c170b200241c00e6a200f109a03200e41386a200241c00e6a41386a280200360200200e41306a200241c00e6a41306a290300370200200e41286a200241c00e6a41286a290300370200200e41206a200241c00e6a41206a290300370200200e41186a200241c00e6a41186a290300370200200e41106a200241c00e6a41106a290300370200200e41086a200241c00e6a41086a290300370200200e20022903c00e370200200241013602f00a0c160b20022002290380083703f80a200241033602f00a0c150b200241c00e6a200f109e03200e41086a200241c00e6a41086a280200360200200e20022903c00e370200200241043602f00a0c140b024002400240024002400240024020022d00fc07417f6a220341034b0d0020030e0401020304010b41cfa2cc00412841c086cc00103f000b41012103200228028008211f0c040b41022103200241c00d6a41026a200941026a2d00003a0000200241c00e6a41086a201a41086a290200370300200241c00e6a41106a201a41106a290200370300200241c00e6a41186a201a41186a2d00003a0000200220092f00003b01c00d2002201a2902003703c00e0c020b41032103200228028008211f0c020b200241c00d6a41026a200941026a2d00003a0000200241c00e6a41086a201a41086a290200370300200241c00e6a41106a201a41106a290200370300200241c00e6a41186a201a41186a2d00003a0000200220092f00003b01c00d2002201a2902003703c00e410421030b200228028008211f20022802a00821210b200820022f01c00d3b0000201320022903c00e370200200841026a200241c00d6a41026a2d00003a0000201341086a200241c00e6a41086a290300370200201341106a200241c00e6a41106a290300370200201341186a200241c00e6a41186a280200360200200220033a00f40a2002201f3602f80a200220213602980b200241053602f00a0c130b024002400240024002400240200228028008417f6a220341034b0d0020030e0401020304010b41cfa2cc00412841c086cc00103f000b41012103024020022d0084084101460d00200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e410021030b2002280288082121200241e8106a41026a200241ec106a41026a2d00003a0000200241c00d6a41086a200241c00e6a41086a290300370300200241c00d6a41106a200241c00e6a41106a290300370300200241c00d6a41186a200241c00e6a41186a280200360200200220022f01ec103b01e810200220022903c00e3703c00d20022903a8082223422088a721202023420888a721242023a7211f200241b0086a2903002123410121250c030b41012103024020022d0084084101460d00200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e410021030b200228028808212141022125200241e8106a41026a200241ec106a41026a2d00003a0000200241c00d6a41086a200241c00e6a41086a290300370300200241c00d6a41106a200241c00e6a41106a290300370300200241c00d6a41186a200241c00e6a41186a280200360200200220022f01ec103b01e810200220022903c00e3703c00d20022903a8082223422088a721202023420888a721242023a7211f200241c0086a2903002126200241b0086a290300212320022903b80821270c020b41012103024020022d0084084101460d00200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e410021030b20022802880821214101211f0240024020022d00a8084101470d0020022802ac0821202028212320292127202a2126202b21240c010b202c41807e7120022d00c80872212c4100211f20022802ac08212020022903b0082223212820022903b80822272129200241c0086a2903002226212a20022f00a908200241ab086a2d0000411074722224212b0b200241e8106a41026a200241ec106a41026a2d00003a0000200241c00d6a41086a200241c00e6a41086a290300370300200241c00d6a41106a200241c00e6a41106a290300370300200241c00d6a41186a200241c00e6a41186a280200360200200220022f01ec103b01e810200220022903c00e3703c00d202d42808080807083202cad84212d200241d8086a290300212e20022903d008212f410321250c010b41012103024020022d0084084101460d00200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e410021030b2002280288082121200241e8106a41026a200241ec106a41026a2d00003a0000200241c00d6a41086a200241c00e6a41086a290300370300200241c00d6a41106a200241c00e6a41106a290300370300200241c00d6a41186a200241c00e6a41186a280200360200200220022f01ec103b01e810200220022903c00e3703c00d20022903a8082223422088a721202023420888a721242023a7211f200241b0086a2903002123410421250b201220022f01e8103b0000201241026a200241e8106a41026a2d00003a0000201020022903c00d370200201041086a200241c00d6a41086a290300370200201041106a200241c00d6a41106a290300370200201041186a200241c00d6a41186a280200360200200220033a00fc0a200220253602f80a200220213602800b200241d00b6a202e370300200241b80b6a2026370300200241a80b6a20233703002002202f3703c80b200220273703b00b20022020ad4220862024ad42ffffff078342088684201fad42ff0183843703a00b2002202d3703c00b200241063602f00a0c120b200241c00e6a201b1087022014200241c00e6a418802109d081a200241073602f00a0c110b0240024020022802fc0722240d004100211f0c010b200c2019290000370000200b2015290000370000200241c00e6a41186a201741186a290000370300200241c00e6a41106a201741106a290000370300200241c00e6a41086a201741086a290000370300200c41086a201941086a290000370000200c41106a201941106a290000370000200c41186a201941186a290000370000200b41086a201541086a290000370000200b41106a201541106a290000370000200b41186a201541186a290000370000200220172900003703c00e200a41186a200d41186a290000370000200a41106a200d41106a290000370000200a41086a200d41086a290000370000200a200d2900003700002002280284082203417f4c0d180240024020030d00410021214101211f0c010b20031033221f450d1b200321210b0240024020212003490d00202121200c010b202141017422202003202020034b1b22204100480d1a024020210d0020201033221f0d010c1d0b20212020460d00201f202120201037221f450d1c0b201f20242003109d081a200241c00d6a200241c00e6a418001109d081a2003ad4220862020ad8421300b200220303703f80a2002201f3602f40a2011200241c00d6a418001109d081a200241083602f00a0c100b200241c00e6a201b10a003201441306a200241c00e6a41306a290300370300201441286a200241c00e6a41286a290300370300201441206a200241c00e6a41206a290300370300201441186a200241c00e6a41186a290300370300201441106a200241c00e6a41106a290300370300201441086a200241c00e6a41086a290300370300201420022903c00e370300200241093602f00a0c0f0b200241c00e6a200f10a103200e41286a200241c00e6a41286a290300370200200e41206a200241c00e6a41206a290300370200200e41186a200241c00e6a41186a290300370200200e41106a200241c00e6a41106a290300370200200e41086a200241c00e6a41086a290300370200200e20022903c00e3702002002410a3602f00a0c0e0b200241c00e6a200f10a103200e41286a200241c00e6a41286a290300370200200e41206a200241c00e6a41206a290300370200200e41186a200241c00e6a41186a290300370200200e41106a200241c00e6a41106a290300370200200e41086a200241c00e6a41086a290300370200200e20022903c00e3702002002410b3602f00a0c0d0b200241c00e6a201b108603201441206a200241c00e6a41206a290300370300201441186a200241c00e6a41186a290300370300201441106a200241c00e6a41106a290300370300201441086a200241c00e6a41086a290300370300201420022903c00e3703002002410c3602f00a0c0c0b200241c00e6a200f10a203200e200241c00e6a41c400109d081a2002410d3602f00a0c0b0b200220022802fc073602f40a2002410e3602f00a0c0a0b2002280284082203417f4c0d1020022802fc0721240240024020030d004100211f410121200c010b200310332220450d132003211f0b02400240201f2003490d00201f21210c010b201f41017422212003202120034b1b22214100480d120240201f0d00202110332220450d150c010b201f2021460d002020201f202110372220450d140b202020242003109d08211f200220033602fc0a200220213602f80a2002201f3602f40a2002410f3602f00a0c090b200241c00e6a201b10a303201441386a200241c00e6a41386a290300370300201441306a200241c00e6a41306a290300370300201441286a200241c00e6a41286a290300370300201441206a200241c00e6a41206a290300370300201441186a200241c00e6a41186a290300370300201441086a200241c00e6a41086a290300370300201420022903c00e370300200241103602f00a201441106a200241c00e6a41106a2903003703000c080b200241c00e6a201b10a4032014200241c00e6a419801109d081a200241113602f00a0c070b200241c00e6a200f10a503200e41286a200241c00e6a41286a280200360200200e41206a200241c00e6a41206a290300370200200e41186a200241c00e6a41186a290300370200200e41106a200241c00e6a41106a290300370200200e41086a200241c00e6a41086a290300370200200e20022903c00e370200200241123602f00a0c060b200241c00e6a200f10de04200e200241c00e6a41e800109d081a200241133602f00a0c050b10a703000b200241c00e6a201b10a8032014200241c00e6a41a802109d081a200241173602f00a0c030b200241c00e6a201b10a9032014200241c00e6a41c800109d081a200241183602f00a0c020b200241c00e6a200f10aa03200e200241c00e6a41c400109d081a200241193602f00a0c010b02400240024002400240200228028008417f6a220341024b0d004101212120030e03040102040b41cfa2cc00412841c086cc00103f000b4101211f024020022d0084084101470d00410221212002280288082124200241ec106a2125200241c00e6a21030c020b41022121200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e4100211f2002280288082124200241ec106a2125200241c00e6a21030c010b4101211f024020022d0084084101460d00200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e4100211f0b2002280288082124200241c0086a2903002131200241b0086a290300213220022903b808212320022903a80821334103212120022802c8082120200241ec106a2125200241c00e6a21030b200241e8106a41026a202541026a2d00003a0000200241c00d6a41086a200341086a290200370300200241c00d6a41106a200341106a290200370300200241c00d6a41186a200341186a280200360200200220252f00003b01e810200220032902003703c00d0b201220022f01e8103b0000201020022903c00d370200200241b80b6a2031370300200241a80b6a2032370300201241026a200241e8106a41026a2d00003a0000201041086a200241c00d6a41086a290300370200201041106a200241c00d6a41106a290300370200201041186a200241c00d6a41186a280200360200200220233703b00b200220333703a00b2002201f3a00fc0a200220213602f80a200220243602800b200220203602c00b2002411a3602f00a0b4100211f200241003b01c00e200241c80a6a200241f00a6a200241c00e6a10ac030240024020022802a80a22240d000c010b20022802b00a2203417f4c0d070240024020030d00410021214101211f0c010b20031033221f450d0a200321210b0240024020212003490d00202121200c010b202141017422202003202020034b1b22204100480d09024020210d0020201033221f450d0c0c010b20212020460d00201f202120201037221f450d0b0b201f20242003109d081a2003ad4220862020ad8421230b410121030240024020022802b40a4101460d0020022802a80a450d01200241f00a6a200710f00420023502f80a42208620022802f00a2221ad84100720022802f40a450d01202110350c010b20022802b80a21030240024020022802bc0a222141014b0d00200241003602b40a0c010b200241013602b40a20022021417f6a3602bc0a0b200128022428020020036a2103024020022802a80a450d00200241f00a6a200310f30420022802f40a212420022802f00a2125200241f00a6a200710f00420023502f80a213120022802f00a2120410810332221450d0a2021200336000020214100202420254101461b36000420314220862020ad842021ad428080808080018410022021103520022802f40a450d00202010350b200241f00a6a200241f8076a41d002109d081a2003200241f00a6a410110cb04024020022802ac0d4102460d00024020022802a00d2203450d0020022802a40d450d00200310350b200241f00a6a10ba020b410021030b20012802242802002120200220062900003703f00a2002200641076a2800003600f70a0240024020022903c80a4201510d00410421210c010b20022d00e00a212420022903d00a2131200220022800f70a3600c70e200220022903f00a3703c00e4104212120314202510d00200220022800c70e3600f70a200220022903c00e3703f00a202421210b200220022903f00a3703c00d200220022800f70a3600c70d200520022903c00d370000200541076a20022800c70d360000200220213a008c0b200220233702840b2002201f3602800b2002201e3602fc0a200220203602f80a200241013602f40a200241153a00f00a41b0b4cc004100200241f00a6a10d40120012802282022370300024020030d00410421030c020b024020022802a80a2203450d0020022802ac0a450d00200310350b200241f8076a10ba02410421030c010b200241f00a6a200241f8076a41bc02109d081a200241c00e6a41086a221f20212903003703002002201c2903003703c00e024020034103470d00410421030c010b200241f8076a200241f00a6a41bc02109d081a200241c00d6a41086a201f290300370300200220022903c00e3703c00d0b2001200128021841016a360218200241e8026a200241f8076a41bc02109d081a200241d8026a41086a200241c00d6a41086a290300370300200220022903c00d3703d802024020034104470d00200128021022032001280214470d010c020b0b200241f00a6a200241e8026a41bc02109d081a200241f8076a41086a2201200241d8026a41086a290300370300200220022903d8023703f80720034103470d010b200041033602bc020c010b2000200241f00a6a41bc02109d08220420033602bc02200420022903f8073703c002200441c8026a20012903003703000b200241f0106a24000f0b1044000b103e000b1045000b103c000bf41503027f017e087f23004190016b220324004189fec600ad4280808080900184100122042900002105200341c0006a41086a200441086a290000370300200320053703402004103541e28cc500ad4280808080e00084100122042900002105200341d8006a41086a200441086a2900003703002003200537035820041035200320003602082003200341086aad4280808080c00084100322042900003703182004103520034184016a2003410c6a3602002003200341186a41086a36027c2003200341086a360280012003200341186a360278200341286a200341f8006a107b0240024002400240024002400240024002400240024002402003280230220641206a2207417f4c0d00200328022821080240024020070d0041002104410121090c010b200710332209450d02200721040b024002402004410f4d0d002004210a0c010b2004410174220a4110200a41104b1b220a4100480d07024020040d00200a103322090d010c0d0b2004200a460d0020092004200a10372209450d0c0b20092003290340370000200941086a200341c0006a41086a29030037000002400240200a4170714110460d00200a21040c010b200a41017422044120200441204b1b22044100480d07200a2004460d002009200a200410372209450d0c0b20092003290358370010200941186a200341d8006a41086a29030037000002400240200441606a2006490d002004210b0c010b200641206a220a2006490d072004410174220b200a200b200a4b1b220b4100480d072004200b460d0020092004200b10372209450d0c0b200941206a20082006109d081a0240200328022c450d00200810350b200341d8006a2007ad4220862009ad842205100510c2010240024020032802580d00410410332204450d032003420437027c200320043602784100200341f8006a1077200341106a200328028001360200200320032903783703080c010b200341086a41086a200341d8006a41086a280200360200200320032903583703080b200341186a41086a200341086a41086a2802002204360200200320032903083703182001200241d0026c6a210a024002402004450d00200341f8006a20032802182004200210f10420032802784101470d01200328021c450d0b200328021810350c0b0b2002200341186a1077200a2001460d08200241d0026c210720012104034002400240200441bc026a2802004102470d0002400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d0b200a41017422082006200820064b1b22084100480d0b02400240200a0d004100210a024020080d00410121060c020b200810332206450d120c010b20032802182106200a2008460d002006200a200810372206450d112003280220210a0b2003200836021c200320063602180b2006200a6a41003a00002003200a41016a3602200c010b02400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d0a200a41017422082006200820064b1b22084100480d0a02400240200a0d004100210a024020080d00410121060c020b200810332206450d110c010b20032802182106200a2008460d002006200a200810372206450d102003280220210a0b2003200836021c200320063602180b2006200a6a41013a00002003200a41016a3602202004200341186a10da040b200441d0026a2104200741b07d6a22070d000c090b0b200328027c2108024020034184016a2802002204200341f8006a41086a2802002207460d002003280220200420076b6a220620024102746a220c417f4c0d0102400240200c0d004100210c4101210d0c010b200c1033220d450d030b2003200d3602282003200c36022c200320063602302003200341286a3602782008200341f8006a200410f20420062004490d03200328023022082006490d04200328022022082007490d052003280228210c2003280218210d2003200620046b22063602382003200820076b220836023c20062008470d06200c20046a200d20076a2006109d081a0240200a2001460d00200241d0026c210720012104034002400240200441bc026a2802004102470d0002400240200328022c2003280230220a460d00200328022821060c010b200a41016a2206200a490d0c200a41017422082006200820064b1b22084100480d0c02400240200a0d004100210a024020080d00410121060c020b200810332206450d130c010b20032802282106200a2008460d002006200a200810372206450d122003280230210a0b2003200836022c200320063602280b2006200a6a41003a00002003200a41016a3602300c010b02400240200328022c2003280230220a460d00200328022821060c010b200a41016a2206200a490d0b200a41017422082006200820064b1b22084100480d0b02400240200a0d004100210a024020080d00410121060c020b200810332206450d120c010b20032802282106200a2008460d002006200a200810372206450d112003280230210a0b2003200836022c200320063602280b2006200a6a41013a00002003200a41016a3602302004200341286a10da040b200441d0026a2104200741b07d6a22070d000b0b2003280230210a200328022c210720032802282104200328021c450d09200328021810350c090b2003200341186a3602782008200341f8006a200710f204200a2001460d07200241d0026c210720012104034002400240200441bc026a2802004102470d0002400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d0a200a41017422082006200820064b1b22084100480d0a02400240200a0d004100210a024020080d00410121060c020b200810332206450d110c010b20032802182106200a2008460d002006200a200810372206450d102003280220210a0b2003200836021c200320063602180b2006200a6a41003a00002003200a41016a3602200c010b02400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d09200a41017422082006200820064b1b22084100480d0902400240200a0d004100210a024020080d00410121060c020b200810332206450d100c010b20032802182106200a2008460d002006200a200810372206450d0f2003280220210a0b2003200836021c200320063602180b2006200a6a41013a00002003200a41016a3602202004200341186a10da040b200441d0026a2104200741b07d6a2207450d080c000b0b1044000b1045000b2004200641e88cc5001059000b2006200841e88cc5001058000b2007200841f88cc5001059000b200341d8006a41146a410a360200200341e4006a410c360200200341c0006a41146a41033602002003200341386a36027020032003413c6a360274200341f8006a41146a410036020020034203370244200341a0b3cc003602402003410c36025c200341b0b4cc00360288012003420137027c200341f4b3cc003602782003200341d8006a3602502003200341f8006a3602682003200341f4006a3602602003200341f0006a360258200341c0006a41b0b4cc00104c000b103e000b2003280220210a200328021c2107200328021821040b2004450d002005200aad4220862004ad84100202402007450d00200410350b200b450d01200910350c010b0240200b450d00200910350b200341d8006a200010c9042003280258210420033502602105200341f8006a2001200210d90420054220862004ad842003350280014220862003280278220aad8410020240200328027c450d00200a10350b200328025c450d00200410350b20034190016a24000f0b103c000b81ad010a017f017e017f047e047f027e0b7f067e037f027e230041f00c6b22012400200141003602e003200142013703d803024002400240024020004180ee05700d0041a29bc800ad4280808080f00084220210012203290000210420032900082105200310354189eaca00ad4280808080f00084100122032900002106200329000821072003103520012007370288082001200637028008200120053702f807200120043702f007200141a00a6a200141f0076a10fe0120012902a40a420020012802a00a22031b21042003410120031b2103024020012802dc0341ffffff3f71450d0020012802d80310350b200120043702dc03200120033602d8032001200141d8036a3602e4032002100122032900002102200329000821042003103541ceb8c800ad42808080803084100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141c0036a200141f0076a412010d701200141c0036a41106a290300210220012903c803210420012802c0032103200141e8036a41d1b8c800411010d503200141003a00c00a2002420020031b21062004420020031b2107200141e8036a21084120210341002109024002400240024002400340200141003a00f007200141f0076a20082003410047220a109d081a024020030d00200141003a00f0070b2003200a490d01200141a00a6a20096a20012d00f0073a00002001200941016a220b3a00c00a2003200a6b21032008200a6a2108200b2109200b4120470d000b20012903a00a210420012903a80a210520012903b00a210c20012903b80a210d4100210e200141a00a6a4100418002109f081a42002102200141d00c6a4200370300200141c80c6a4200370300200141c00c6a200d370300200141b80c6a200c370300200141b00c6a2005370300200120043703a80c200141c0003602a00c4108210f024020012802e40341086a2802000d004100210a0c050b41a29bc800ad4280808080f00084100122032900002104200329000821052003103541e1b8c800ad4280808080a0018410012203290000210c2003290008210d200310352001200d370288082001200c37028008200120053702f807200120043702f007200141f0056a200141f0076a10be020240024020012802f005220a0d00410021030c010b200141f0076aad4280808080800484100720012902f4052202422088a72103200a210f0b20012802e403220a200a2802082003108a0141d1c4c700ad4280808080e00084100122032900002104200329000821052003103541e7c4c700ad4280808080e0008410012203290000210c2003290008210d200310352001200d370288082001200c37028008200120053702f807200120043702f007200141b8036a200141f0076a412010c00120012802e40341086a28020041f4036a2203450d0120012802bc03210a20012802b8032108200141e4003a00f107200141e40041d0860320036e22036b3a00f007410021102001200141f0076a200341ff017141e4004b6a2d00004180fe126c200a410020081b6a36028c04200141003602980420014201370390042001410036029c04200142003703a804200142003703a004200142003703b804200142003703b004200141e8046a2001418c046a360200200141e4046a200141b0046a360200200141c0046a41206a2001419c046a360200200141dc046a200141a0046a360200200141d8046a20014190046a360200200141d4046a200141a00a6a3602002001200f2002422088a7220341e8006c22086a3602cc042001200f3602c80420012002a722113602c4042001200f3602c0042001200141e4036a3602d0040240024002402003450d00200141f0076a410172210b200141d0046a2112200f210303402001200341e8006a22093602c80420032d0000210a200141f0056a200341016a41e700109d081a200a4102460d012001200a3a00f007200b200141f0056a41e700109d081a20014190076a2012200141f0076a10ae062001290390074201510d0220092103200841987f6a22080d000b0b4108210b02402011450d00201141e8006c450d00200f10350b410021110c010b200141d8066a41306a20014190076a41386a2903002202370300200141d8066a41286a20014190076a41306a2903002204370300200141d8066a41206a20014190076a41286a2903002205370300200141b8056a41086a220b20014190076a41106a290300370300200141b8056a41106a220920014190076a41186a290300370300200141b8056a41186a221220014190076a41206a290300370300200141b8056a41206a22082005370300200141b8056a41286a220a2004370300200141b8056a41306a2203200237030020012001290398073703b80520014180056a41306a220f200329030037030020014180056a41286a2203200a29030037030020014180056a41206a220a200829030037030020014180056a41186a2208201229030037030020014180056a41106a2212200929030037030020014180056a41086a2209200b290300370300200120012903b8053703800541381033220b450d07200b200129038005370300200b41306a200f290300370300200b41286a2003290300370300200b41206a200a290300370300200b41186a2008290300370300200b41106a2012290300370300200b41086a200929030037030020014281808080103702f4042001200b3602f0042009200141c0046a41086a29030022023703002003200141c0046a41286a280200360200200a200141c0046a41206a2903003703002008200141c0046a41186a2903003703002012200141c0046a41106a290300370300200120012903c00437038005024002402002a72203200128028c05220a470d00410121100c010b200a41987f6a210f20014190076a41086a210a200141f0076a41017221114101211003402001200341e8006a22093602880520032d00002108200141f0056a200341016a41e700109d081a20084102460d01200120083a00f0072011200141f0056a41e700109d081a20014190076a2012200141f0076a10ae0602402001290390074201510d00200f2003462108200921032008450d010c020b200141d8066a41306a200a41306a2903002202370300200141d8066a41286a200a41286a2903002204370300200141d8066a41206a200a41206a2903002205370300200141b8056a41086a2208200a41086a290300370300200141b8056a41106a2213200a41106a290300370300200141b8056a41186a2214200a41186a290300370300200141b8056a41206a22152005370300200141b8056a41286a22162004370300200141b8056a41306a221720023703002001200a2903003703b805200141f0076a41306a22182017290300370300200141f0076a41286a22172016290300370300200141f0076a41206a22162015290300370300200141f0076a41186a22152014290300370300200141f0076a41106a22142013290300370300200141f0076a41086a22132008290300370300200120012903b8053703f0070240201020012802f404470d00200141f0046a20104101108b0120012802f004210b0b200b201041386c6a220820012903f007370300200841306a2018290300370300200841286a2017290300370300200841206a2016290300370300200841186a2015290300370300200841106a2014290300370300200841086a20132903003703002001201041016a22103602f804200f20034721082009210320080d000b0b02402001280284052203450d00200341e8006c450d0020012802800510350b20012802f40421110b41a29bc800ad4280808080f00084100122032900002102200329000821042003103541b39bc800ad4280808080d000841001220329000021052003290008210c200310352001200c370288082001200537028008200120043702f807200120023702f007200141f0076aad4280808080800484220c1008024020012903a004200141a0046a41086a29030084500d00024002402001280298042203450d00200128029004210a200141a00a6a2003417f6a10af0622082003490d0120082003419cb9c8001042000b200142f0f2bd99f7edd8b4e5003703f007200141f0056a200141f0076a108106200142f0f2bd99f7edd8b4e50037039007200141f0076a20014190076a10e00120014190076a200141f0056a200141f0076a20012903a004200141a8046a290300410110e6020c010b200a20084105746a200128028c0420012903a004200141a8046a29030010b0060b024020012903b0042202200141b0046a41086a290300220484500d00200142f0f2bd99f7edd8b4e5003703f007200141f0056a200141f0076a10e001200142f0f2bd99f7edd8b4e50037039007200141f0076a20014190076a10810620014190076a200141f0056a200141f0076a20012903b004200141b8046a290300410110e6024200200620047d2007200254ad7d2204200720027d2202200756200420065620042006511b22031b21064200200220031b21070b0240024020100d004100210a0c010b201041386c210a200b41046a2109200141a00a6a200128029c04417f6a10af06210f200b2103034020092108200a450d0402402003290328200341306a29030084500d00200a41486a210a200841386a210920032802002112200341386a21032012200f4d0d010b0b200141f0056a41186a200841186a290000370300200141f0056a41106a200841106a290000370300200141f0056a41086a200841086a290000370300200120082900003703f00541002108200141003602f807200142013703f007200141f0076a4100201041386c221241386d108a0120012802f007220f20012802f80722094105746a21030340200b20086a220a41046a2902002102200a410c6a2902002104200a41146a2902002105200341186a200a411c6a290200370000200341106a2005370000200341086a200437000020032002370000200341206a2103200941016a21092012200841386a2208470d000b200120093602f80702402011450d00201141386c450d00200b10350b20012802f407210a20012802e4032203280200200328020810ac0620012802e403220328020821082003280200211241a29bc800ad4280808080f00084220210012203290000210420032900082105200310354189eaca00ad4280808080f0008410012203290000210d200329000821192003103520012019370288082001200d37028008200120053702f807200120043702f0072001200141f0076a3602900720014120360294072012200820014190076a10a8062002100122032900002102200329000821042003103541f69bc800ad4280808080c000841001220329000021052003290008210d200310352001200d370288082001200537028008200120043702f807200120023702f007412010332203450d07200320012903f005370000200341186a200141f0056a41186a2208290300370000200341106a200141f0056a41106a2212290300370000200341086a200141f0056a41086a2210290300370000200c2003ad4280808080800484100220031035200141f0076a41086a41063a0000200141f9076a20012903f00537000020014181086a201029030037000020014189086a201229030037000020014191086a2008290300370000200141a4086a2009360200200141a0086a200a3602002001419c086a200f360200200141123a00f00741b0b4cc004100200141f0076a10d4014101210a0b200142f0f2bd99f7edd8b4e5003703f007200141f0056a200141f0076a10e00120014190076a200141f0056a108e02200141f0076a2001280290072208200128029807108f0220014180086a290300420020012903f00742015122031b210220012903f807420020031b21040240200128029407450d00200810350b41a29bc800ad4280808080f000841001220329000021052003290008210d2003103541ceb8c800ad428080808030841001220329000021192003290008211a200310352001201a3702880820012019370280082001200d3702f807200120053702f00720014200200420077d22052005200456200220067d2004200754ad7d220420025620042002511b22031b4201884200200420031b2202423f8684220442808094f6c2d7e8d800200442808094f6c2d7e8d80054410020024201882202501b22031b220420077c22073703f00520012002420020031b20067c2007200454ad7c22063703f805200c200141f0056aad42808080808002841002200a201145720d03201141386c450d03200b10350c030b200a200341b89dcc001059000b41f0b8c8004119418cb9c800103f000b41b3b9c80041d700418cbac8001064000b024020012802940441ffffff3f71450d0020012802900410350b20012802e40341086a280200210a0b41a29bc800ad4280808080f000842219100122032900002102200329000821042003103541a99bc800ad4280808080a001841001220329000021052003290008210c200310352001200c370288082001200537028008200120043702f807200120023702f007200141b0036a200141f0076a412010c00102400240410020012802b403410020012802b0031b2203200a6b220a200a20034b1b2203410a2003410a491b22080d0041082111410021130c010b20191001220329000021022003290008210420031035419cbac800ad4280808080c000841001220329000021052003290008210c200310352001200c370288082001200537028008200120043702f807200120023702f007200141f0056a200141f0076a10be020240024020012802f00522180d00410821184200211b4100210a410021030c010b20012902f405221b422088a72103201ba7210a0b200141003602c005200142083703b80502400240024002402003450d000240201b422088a7220b0d00410821114100210e0c030b20032008200820034b1b210f201841286a21034100210e41082111410021174200210242002104410021124100210a4100210802400340024002402012200f4f0d00024002400240200341106a2903002205200341186a290300220c84500d00200220057c220d2007562004200c7c200d200254ad7c220420065620042006511b450d01200d21020c030b201741ff01710d02200141f0076a41186a2209200341386a290000370300200141f0076a41106a2210200341306a290000370300200141f0076a41086a2213200341286a2900003703002001200341206a2900003703f00702400240200341586a2d00004101470d002001200341596a221441036a28000036008305200341086a2903002105200341606a2215290000210c201541086a290000210d201428000021142003290300211a200141c0046a41086a200341706a221541086a2d00003a00002001201436028005200120152900003703c004410121140c010b200341606a2214290300210c201441086a290300210d410021140b200141f0056a41186a22152009290300370300200141f0056a41106a22162010290300370300200141f0056a41086a2210201329030037030020014190076a41086a2213200141c0046a41086a290300370300200120012903f0073703f00520012001280280053602b00420012001280083053600b304200120012903c004370390070240200e20012802bc05470d00200141b8056a200e410110960120012802b805211120012802c005210e0b2011200e41e8006c6a220920143a0000200941106a200d370300200941086a200c370300200920012802b004360001200941046a20012800b304360000200941206a2013290300370300200129039007210c200941c0006a420037030020094200370338200941306a2005370300200941286a201a370300200941186a200c370300200920012903f005370348200941d0006a2010290300370300200941d8006a2016290300370300200941e0006a2015290300370300410121172001200e41016a220e3602c0050c010b200141f0076a41186a2209200341386a290000370300200141f0076a41106a2210200341306a290000370300200141f0076a41086a2213200341286a2900003703002001200341206a2900003703f00702400240200341586a2d00004101470d002001200341596a221441036a28000036008305200341086a2903002102200341606a2215290000211a201541086a290000211c201428000021142003290300211d200141c0046a41086a200341706a221541086a2d00003a00002001201436028005200120152900003703c004410121140c010b200341606a2214290300211a201441086a290300211c410021140b200141d8066a41186a22152009290300370300200141d8066a41106a22162010290300370300200141d8066a41086a2210201329030037030020014190076a41086a2213200141c0046a41086a290300370300200120012903f0073703d80620012001280280053602b00420012001280083053600b304200120012903c004370390070240200e20012802bc05470d00200141b8056a200e410110960120012802b805211120012802c005210e0b2011200e41e8006c6a220920143a0000200941106a201c370300200941086a201a370300200920012802b004360001200941046a20012800b304360000200941206a2013290300370300200129039007211a200941c0006a200c37030020092005370338200941306a2002370300200941286a201d370300200941186a201a370300200920012903d806370348200941d0006a2010290300370300200941d8006a2016290300370300200941e0006a20152903003703002001200e41016a220e3602c005200d21020b200a41016a210a201241016a21120c010b0240200a0d004100210a0c010b2008200a6b2209200b4f0d02200141f0076a2003200a41987f6c6a41586a220941e800109d081a2009200341586a221041e800109e081a2010200141f0076a41e800109d081a0b200341e8006a2103200b200841016a2208460d030c000b0b2009200b41f485cc001042000b410821114100210e410021130c020b0240200a417f6a200b4f0d00201b42ffffffff0f83200b200a6bad42208684211b0b2012450d0041a29bc800ad4280808080f000841001220329000021022003290008210420031035419cbac800ad4280808080c00084100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141f0056a2018201b422088a710b106200141f0076aad428080808080048420013502f80542208620012802f005220aad841002201ba72103024020012802f405450d00200a10350b02402003450d00200341e8006c450d00201810350b20012802bc0521130c020b20012802bc052113201ba7210a0b200a450d00200a41e8006c450d00201810350b2019100122032900002102200329000821042003103541e1b8c800ad4280808080a00184100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141f0056a2011200e10b106200141f0076aad428080808080048420013502f80542208620012802f0052203ad841002024020012802f405450d00200310350b41002103024020012802e403220b41086a280200220a4102762208450d00410021032008200a460d00410021080340200841026a2103200a200841046a411e71762209450d01200321082009200a470d000b0b4100211203400240201241017422124101722208ad220220027e2202422088a70d00201220082002a7200a2003411f71764b1b21120b02402003450d0041002003417e6a2208200820034b1b21030c010b0b02402012450d0002400240200e450d00200e41e8006c210f201141c8006a21104100210e0c010b2012417f6a21080340200a450d05200141a00a6a200a417f6a10af062203200a4f0d062008450d022008417f6a210820012802e403280208210a0c000b0b0340200a450d04200b2802002108200141a00a6a200a417f6a10af062203200a4f0d05200e41016a210e200820034105746a210b200f21092010210a024002400340200141f0076a200a200b10b20620013502f807210220012802f0072108410110332203450d01200341003a000020024220862008ad842003ad42808080801084100220031035024020012802f407450d00200810350b200a41e8006a210a200941987f6a2209450d020c000b0b103c000b200e2012460d0120012802e403220b280208210a0c000b0b2013450d00201341e8006c450d00201110350b02400240024002400240024002400240024020004180a70c7022180d00024020012802e0030d0041a29bc800ad4280808080f0008410012203290000210220032900082104200310354189eaca00ad4280808080f00084100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141a00a6a200141f0076a10fe0120012902a40a420020012802a00a22031b21022003410120031b2103024020012802dc0341ffffff3f71450d0020012802d80310350b200120033602d803200120023702dc032002428080808010540d010b41a29bc800ad4280808080f00084100122032900002102200329000821042003103541ccbac800ad4280808080800184100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141a00a6a200141f0076a412010d501024020012d00a00a4101470d00200141a90a6a2800002103200141ad0a6a280000210a200141b10a6a2800002108200141b50a6a2800002109200141b90a6a280000210b20012800a10a211220012800a50a210e2001200141bd0a6a2800003602bc0a2001200b3602b80a200120093602b40a200120083602b00a2001200a3602ac0a200120033602a80a2001200e3602a40a200120123602a00a0240024020012802e003220a450d0020012802d8032103200a410574210a4100210b410021120340200141f0076a200310b30620012802f007220920012802f80710e40241ff01712108024020012802f407450d00200910350b0240024002402008417e6a220841014b0d0020080e020102010b200b41016a210b0c010b201241016a21120b200341206a2103200a41606a220a0d000b2012200b4a0d010b200141a00a6a10b40641a29bc800ad4280808080f0008410012203290000210220032900082104200310354189eaca00ad4280808080f00084100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141f0056a200141f0076a10fe0120012902f405420020012802f00522031b21022003410120031b2103024020012802dc0341ffffff3f71450d0020012802d80310350b200120023702dc03200120033602d8030b41a29bc800ad4280808080f00084100122032900002102200329000821042003103541d4bac800ad4280808080d00184100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141f0076aad428080808080048410080b024020012802e00341024d0d00200141f0056a41e1bac800411110d503200141003a00c00a200141f0056a210841202103410021090340200141003a00f007200141f0076a20082003410047220a109d081a024020030d00200141003a00f0070b2003200a490d03200141a00a6a20096a20012d00f0073a00002001200941016a220b3a00c00a2003200a6b21032008200a6a2108200b2109200b4120470d000b20012903a00a210220012903a80a210420012903b00a210520012903b80a2106200141a00a6a4100418002109f081a200141d00c6a4200370300200141c80c6a4200370300200141c00c6a2006370300200141b80c6a2005370300200141b00c6a2004370300200120023703a80c200141c0003602a00c20012802e0032203417f6a220a450d032003450d04024002402003417e6a220a450d0020012802d8032108200141a00a6a2003417d6a10af062209200a490d012009200a419cb9c8001042000b41a0bac800411c4184bbc8001064000b41a29bc800ad4280808080f00084100122032900002102200329000821042003103541ccbac800ad4280808080800184100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007412010332203450d0a2003200841206a20094105746a220a290000370000200341186a200a41186a2208290000370000200341106a200a41106a2209290000370000200341086a200a41086a220b290000370000200141f0076aad42808080808004842003ad4280808080800484100220031035200141f0076a41086a410a3a0000200141f9076a200a29000037000020014181086a200b29000037000020014189086a200929000037000020014191086a2008290000370000200141123a00f00741b0b4cc004100200141f0076a10d4010c010b41a29bc800ad4280808080f00084100122032900002102200329000821042003103541ccbac800ad4280808080800184100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141f0076aad428080808080048410070b024020012802dc0341ffffff3f71450d0020012802d80310350b200141f0076a41186a22094200370300200141f0076a41106a22034200370300200141f0076a41086a220a4200370300200142003703f00741d1c4c700ad4280808080e00084100122082900002102200a200841086a290000370300200120023703f0072008103541edc4c700ad4280808080a00184100122082900002102200141a00a6a41086a220b200841086a290000370300200120023703a00a20081035200320012903a00a2202370300200141f0056a41086a200a290300370300200141f0056a41106a2002370300200141f0056a41186a200b290300370300200120012903f0073703f005200141a00a6a200141f0056a412010d50120012d00a00a21082009200141b90a6a2900003703002003200141b10a6a290000370300200a200141a90a6a290000370300200120012900a10a3703f0070240024020084101460d0020014190076a41186a420037030020014190076a41106a420037030020014190076a41086a420037030020014200370390070c010b20014190076a41186a200929030037030020014190076a41106a200329030037030020014190076a41086a200a290300370300200120012903f007370390070b200141f0076a41186a22094200370300200141f0076a41106a220b4200370300200141f0076a41086a22084200370300200142003703f0074182e9ca00ad42808080808003841001220a29000021022008200a41086a290000370300200120023703f007200a1035419ae9ca00ad4280808080e001841001220a2900002102200141a00a6a41086a2212200a41086a290000370300200120023703a00a200a1035200320012903a00a370000200341086a2012290300370000200141f0056a41086a2008290300370300200141f0056a41106a200b290300370300200141f0056a41186a2009290300370300200120012903f0073703f005200141d8066a200141f0056a412010b502024002400240024020012802d806220a0d0041002103200141003602c005200142013703b805200920014190076a41186a290300370300200b20014190076a41106a290300370300200820014190076a41086a29030037030020012001290390073703f007200141f0076a21080c010b200120012902dc0622023702bc052001200a3602b8052002a7210b02402002422088a7220341d100490d00200141a00a6a41186a220920014190076a41186a290300370300200141a00a6a41106a221220014190076a41106a290300370300200141a00a6a41086a220e20014190076a41086a29030037030020012001290390073703a00a2000417f6a41d10070220820034f0d07200a20084105746a220820012903a00a370000200841186a2009290300370000200841106a2012290300370000200841086a200e2903003700000c030b200141f0076a41186a20014190076a41186a290300370300200141f0076a41106a20014190076a41106a290300370300200141f0076a41086a20014190076a41086a29030037030020012001290390073703f007200141f0076a21082003200b470d010b200141b8056a20034101108a0120012802bc05210b20012802b805210a20012802c00521030b200a20034105746a22092008290000370000200941186a200841186a290000370000200941106a200841106a290000370000200941086a200841086a2900003700002001200341016a22033602c0050b200141a00a6a41186a4200370300200141a00a6a41106a22124200370300200141a00a6a41086a22084200370300200142003703a00a4182e9ca00ad42808080808003841001220929000021022008200941086a290000370300200120023703a00a20091035419ae9ca00ad4280808080e00184100122092900002102200141f0056a41086a220e200941086a290000370300200120023703f00520091035201220012903f0052202370300200141f0076a41086a2008290300370300200141f0076a41106a2002370300200141f0076a41186a200e290300370300200120012903a00a3703f00702400240200a0d00200141f0076aad428080808080048410070c010b200141203602a40a2001200141f0076a3602a00a200a2003200141a00a6a10c504200b41ffffff3f71450d00200a10350b4200211e200141a00a6a41186a220b4200370300200141a00a6a41106a220a4200370300200141a00a6a41086a22034200370300200142003703a00a41f7edcb00ad4280808080f000841001220829000021022003200841086a290000370300200120023703a00a2008103541b6aac000ad4280808080900284100122082900002102200141f0056a41086a2209200841086a290000370300200120023703f00520081035200a20012903f0052202370300200141f0076a41086a22082003290300370300200141f0076a41106a22122002370300200141f0076a41186a220e2009290300370300200120012903a00a3703f007200141a8036a200141f0076a10f20120012802a803417d710d07200b4200370300200a420037030020034200370300200142003703a00a41a2e8cb00ad428080808080018422061001220f29000021022003200f41086a290000370300200120023703a00a200f103541e6f2c400ad428080808080028422071001220f29000021022009200f41086a290000370300200120023703f005200f1035200a20012903f005370000200a41086a2009290300370000200820032903003703002012200a290300370300200e200b290300370300200120012903a00a3703f007200141a00a6a200141f0076a10c602200120012802a00a2203410420031b221f3602900720012902a40a420020031b2205422088a7220e450d064100210a201f21034100210803400240024002402003280200200341086a22092802002003410c6a280200200341146a280200200341186a220b28020010fd01450d00200a0d014100210a0c020b200a41016a210a0c010b2008200a6b2212200e4f0d06200141a00a6a41186a220f2003200a41646c6a221241186a2210280200360200200141a00a6a41106a2211201241106a2213290200370300200141a00a6a41086a2214201241086a2215290200370300200120122902003703a00a20092902002102200341106a22162902002104200b280200211720122003290200370200201020173602002013200437020020152002370200200b200f2802003602002016201129030037020020092014290300370200200320012903a00a3702000b2003411c6a2103200e200841016a2208460d060c000b0b200a200341b89dcc001059000b4101410041f4bac8001059000b200a410041f4bac8001058000b2008200341f0e9ca001042000b2012200e41f485cc001042000b200a450d00200e200a490d00201f200e200a6b220e411c6c6a200a10c802200542ffffffff0f8321050b2001280290072103200141a00a6a41186a4200370300200141a00a6a41106a22094200370300200141a00a6a41086a220a4200370300200142003703a00a2006100122082900002102200a200841086a290000370300200120023703a00a200810352007100122082900002102200141f0056a41086a220b200841086a290000370300200120023703f00520081035200920012903f0052202370300200141f0076a41086a200a290300370300200141f0076a41106a2002370300200141f0076a41186a200b290300370300200120012903a00a3703f007024020030d00200141f0076aad428080808080048410070c010b2005a7210a200141a00a6a2003200e10c704200141f0076aad428080808080048420013502a80a42208620012802a00a2208ad841002024020012802a40a450d00200810350b2003200e10c802200a450d00200a411c6c450d00200310350b024020004180e101700d00200142f0f2bda1a7ee9cb9f9003703a00a200141f0076a200141a00a6a10e001200141f0056a200141f0076a108e02200141a00a6a20012802f005220a20012802f805108f02200141a00a6a41106a2217290300420020012903a00a42015122031b210420012903a80a420020031b2102024020012802f405450d00200a10350b2001420020042002428080e983b1de1654ad7d2205200242808097fccea1697c22062002562005200456200242ffffe883b1de16561b22031b22023703880520014200200620031b220437038005200141a00a6a41186a221f200237030020172004370300200141a00a6a41086a220f41013a00002001410c3a00a00a41b0b4cc004100200141a00a6a10d401200141003a00a004200142003703c005200142003703b805201f420037030020174200370300200f4200370300200142003703a00a4186f0cb00ad4280808080800184221a100122032900002102200141f0056a41086a2214200341086a290000370300200120023703f00520031035200f2014290300370300200120012903f0053703a00a419bf0cb00ad4280808080900184221c1001220329000021022014200341086a290000370300200120023703f00520031035201720012903f0052202370300200141f0076a41086a2211200f290300370300200141f0076a41106a2002370300200141f0076a41186a22162014290300370300200120012903a00a3703f007200141a00a6a200141f0076a10c50220012802a00a2203410420031b2120024020012902a40a420020031b2219422088220da72210450d00200141a90a6a210b200141b0086a211220014190086a2113200141d80a6a2115200141b8076a2121202021034100210a410021080240034020014190076a2003280200220e10b506200141a00a6a200128029007220920012802980710df0220012903a00a2104200141f0076a200f41e000109d081a42002102024020044201520d00200141f0056a200141f0076a41e000109d081a420121020b0240200128029407450d00200910350b024002400240200250450d00200a41016a210a0c010b200141f0076a200141f0056a41e000109d081a0240200129038005220520012903f007220654220920014180056a41086a2903002202201129030022045420022004511b0d002001200520067d370380052001200220047d2009ad7d37038805200141a00a6a200e10b50620013502a80a42208620012802a00a2209ad841007024020012802a40a450d00200910350b20012903800821022001201629030022043703e006200120023703d80602402002200484500d00200120133602c00420014190076a2013200141d8066a200141c0046a10f0022001290390074201520d002001290398072102201520014190076a41106a290300370300200b2013290000370000200b41086a201341086a290000370000200b41106a201341106a290000370000200b41186a201341186a290000370000200120023703d00a200141003a00a80a200141033a00a00a41b0b4cc004100200141a00a6a10d4010b20012903f00721022001201129030022043703e006200120023703d80602400240200220048450450d00420021054200210642002104420021070c010b200120123602c00420014190076a2012200141d8066a200141c0046a10b002024002402001290390074201520d0020014190076a41106a290300210720012903980721040c010b2021290300210720012903b00721042001290398074201520d0020012903a0072102201520014190076a41186a290300370300200b2012290000370000200b41086a201241086a290000370000200b41106a201241106a290000370000200b41186a201241186a290000370000200120023703d00a200141003a00a80a200141033a00a00a41b0b4cc004100200141a00a6a10d4010b2011290300210620012903f00721050b200141b8056a41086a2209427f2009290300220220077c20012903b805220720047c220c2007542209ad7c22042009200420025420042002511b22091b3703002001427f200c20091b3703b80520152006370300200b2012290000370000200b41086a201241086a290000370000200b41106a201241106a290000370000200b41186a201241186a290000370000200120053703d00a200141023a00a80a2001410c3a00a00a2001200e3602cc0a41b0b4cc004100200141a00a6a10d401200a41016a210a0c010b200141013a00a0040240200a0d004100210a0c010b2008200a6b220920104f0d012003200a4102746b2209280200210e200920032802003602002003200e3602000b200341046a21032010200841016a2208460d020c010b0b2009201041f485cc001042000b200a417f6a20104f0d00201942ffffffff0f8321192010200a6b21100b201f4200370300200141a00a6a41106a220a4200370300200f4200370300200142003703a00a201a1001220329000021022014200341086a290000370300200120023703f00520031035200f2014290300370300200120012903f0053703a00a201c1001220329000021022014200341086a290000370300200120023703f00520031035201720012903f005370000201741086a20142903003700002011200f290300370300200141f0076a41106a200a2903003703002016201f290300370300200120012903a00a3703f007200141203602a40a2001200141f0076a3602a00a20202010200141a00a6a1095030240201942ffffffff0383500d00202010350b024020012d00a0040d004200210720014198036a200129038005220220014180056a41086a2203290300220442c0843d420010980820014188036a200129039803220520014198036a41086a290300220642c0fb42427f108408200141f8026a2005200642a0c21e4200108408200320042004200141f8026a41086a29030020012903f802220520022001290388037c2206420188220ca7417f200642a0c21e7e2206428080808080c8d007541b2006200c42c0fb427e7c42a0c21e566aad7c2206200554ad7c22052006200256200520045620052004511b220a1b22057d200220022006200a1b220454ad7d3703002001200220047d3703800502400240200420058450450d004200210c0c010b200141f0076a41186a22124200370300200141f0076a41106a220a4200370300200141f0076a41086a22034200370300200142003703f00741b6fdc600ad4280808080800184220210012209290000210620014190076a41086a2208200941086a2900003703002001200637039007200910352003200829030037030020012001290390073703f00741e489c200ad4280808080d0018422061001220b2900002107200141c0046a41086a2209200b41086a290000370300200120073703c004200b1035200a20012903c0042207370300200141d8066a41086a220e2003290300370300200141d8066a41106a220f2007370300200141d8066a41186a22102009290300370300200120012903f0073703d806200141e0026a200141d8066a412010d701200141e0026a41106a290300210720012903e802210c20012802e002210b20124200370300200a420037030020034200370300200142003703f00720021001221229000021022008201241086a2900003703002001200237039007201210352003200829030037030020012001290390073703f00720061001220829000021022009200841086a290000370300200120023703c00420081035200a20012903c0042202370300200e2003290300370300200f200237030020102009290300370300200120012903f0073703d8062001420020074200200b1b220220057d200c4200200b1b2206200454ad7d2207200620047d220c200656200720025620072002511b22031b3703a80a20014200200c20031b3703a00a200141d8066aad4280808080800484200141a00a6aad428080808080028410022002200520031b210c2006200420031b21070b200141b8056a41086a2203427f20032903002202200c7c20012903b805220620077c22072006542203ad7c22062003200620025420062002511b22031b3703002001427f200720031b3703b805200141b80a6a2005370300200141b00a6a2004370300200141a00a6a41086a41043a00002001410c3a00a00a41b0b4cc004100200141a00a6a10d4010b200142f0f2bda1a7ee9cb9f9003703a00a200141f0056a200141a00a6a10e001200141c0056a290300210420012903b805210241002103200141003a00e803200141023a00b004200120043703980720012002370390072001200141f0056a3602c00402400240200220048450450d0042002105420021060c010b2001200141f0056a3602d8062001200141d8066a3602b00a2001200141b0046a3602ac0a2001200141c0046a3602a80a2001200141e8036a3602a40a200120014190076a3602a00a200141f0076a200141f0056a200141a00a6a10dc0341012103024020012802f0074101470d004200210620012903f80721050c010b20014198086a290300210620014190086a29030021054100210320012903f8074201520d00200141f0076a41106a290300210720012802d806210a200141d80a6a200141f0076a41186a290300370300200141d00a6a200737030041002103200141a00a6a41086a41003a0000200141a90a6a200a290000370000200141b10a6a200a41086a290000370000200141b90a6a200a41106a290000370000200141c10a6a200a41186a290000370000200141033a00a00a41b0b4cc004100200141a00a6a10d4010b024002400240024020030d00200141f0076a41186a220b4200370300200141f0076a41106a22034200370300200141f0076a41086a220a4200370300200142003703f00741b6fdc600ad4280808080800184221a10012209290000210720014190076a41086a2208200941086a290000370300200120073703900720091035200a200829030037030020012001290390073703f00741e489c200ad4280808080d00184221c100122122900002107200141c0046a41086a2209201241086a290000370300200120073703c00420121035200320012903c0042207370300200141d8066a41086a2212200a290300370300200141d8066a41106a220e2007370300200141d8066a41186a220f2009290300370300200120012903f0073703d806200141b0026a200141d8066a412010d701200420067d2002200554ad7d200620047d2005200254ad7d20052002582006200458200620045122101b22111b211d200220057d200520027d20111b2119200141b0026a41106a290300420020012802b00222111b210720012903b802420020111b210c2005200256200620045620101b0d01200b420037030020034200370300200a4200370300200142003703f007201a1001221029000021022008201041086a290000370300200120023703900720101035200a200829030037030020012001290390073703f007201c1001220829000021022009200841086a290000370300200120023703c00420081035200320012903c004370000200341086a20092903003700002012200a290300370300200e2003290300370300200f200b290300370300200120012903f0073703d8062001427f2007201d7c200c20197c2204200c542203ad7c22022003200220075420022007511b22031b3703a80a2001427f200420031b3703a00a200141a00a6a21030c020b4184b8c800ad4280808080a009841006200141f0076a41186a22124200370300200141f0076a41106a220a4200370300200141f0076a41086a22034200370300200142003703f00741b6fdc600ad4280808080800184220510012209290000210620014190076a41086a2208200941086a2900003703002001200637039007200910352003200829030037030020012001290390073703f00741e489c200ad4280808080d0018422061001220b2900002107200141c0046a41086a2209200b41086a290000370300200120073703c004200b1035200a20012903c0042207370300200141d8066a41086a220e2003290300370300200141d8066a41106a220f2007370300200141d8066a41186a22102009290300370300200120012903f0073703d806200141c8026a200141d8066a412010d701200141c8026a41106a290300210720012903d002210c20012802c802210b20124200370300200a420037030020034200370300200142003703f00720051001221229000021052008201241086a2900003703002001200537039007201210352003200829030037030020012001290390073703f00720061001220829000021052009200841086a290000370300200120053703c00420081035200a20012903c0042205370300200e2003290300370300200f200537030020102009290300370300200120012903f0073703d8062001427f20074200200b1b220520047c200c4200200b1b220420027c22062004542203ad7c22022003200220055420022005511b22031b3703a80a2001427f200620031b3703a00a200141d8066aad4280808080800484200141a00a6aad428080808080028410020c020b200b420037030020034200370300200a4200370300200142003703f007201a1001221029000021022008201041086a290000370300200120023703900720101035200a200829030037030020012001290390073703f007201c1001220829000021022009200841086a290000370300200120023703c00420081035200320012903c004370000200341086a20092903003700002012200a290300370300200e2003290300370300200f200b290300370300200120012903f0073703d806200142002007201d7d200c201954ad7d2202200c20197d2204200c56200220075620022007511b22031b3703a80a20014200200420031b3703a00a200141a00a6a21030b200141d8066aad42808080808004842003ad428080808080028410020b2001290380052102200141b80a6a20014180056a41086a290300370300200141b00a6a2002370300200141a00a6a41086a41053a00002001410c3a00a00a41b0b4cc004100200141a00a6a10d401200d42c097e8b2017e200d4280bfdf80017e7c4280e59af7007c211e0b024020180d0010a1020b02400240200041809c3170450d00200141a00a6a21090c010b200141f0056a41186a4200370300200141f0056a41106a22094200370300200141f0056a41086a220a4200370300200142003703f00541d9e3cb00ad428080808090018410012208290000210220014190076a41086a2203200841086a290000370300200120023703900720081035200a200329030037030020012001290390073703f00541efe3cb00ad4280808080d002841001220829000021022003200841086a29000037030020012002370390072008103520092001290390072202370300200141a00a6a41086a200a290300370300200141a00a6a41106a2002370300200141a00a6a41186a2003290300370300200120012903f0053703a00a024002400240024002400240200141a00a6a10bd02220341ff01714102460d00200141a00a6aad4280808080800484100720034101710d010b200141a00a6a200010e70420012d00a00a4104460d02200141f0076a200010ea040c010b200141a00a6a200010ea0420012d00a00a4104460d01200141f0076a200010e7040b20012d00f0074104460d01200141a00a6a411610e8040c020b200141043a00f0070b200141043a00a00a0b200141a00a6a21090b200120003602b805200141f0056a41186a22124200370300200141f0056a41106a2208420037030041082113200141f0056a41086a220a4200370300200142003703f00541d9e3cb00ad428080808090018422021001220b290000210420014190076a41086a2203200b41086a2900003703002001200437039007200b1035200a200329030037030020012001290390073703f00541e2e3cb00ad4280808080d001841001220b29000021042003200b41086a2900003703002001200437039007200b103520082001290390072204370300200141a00a6a41086a220e200a290300370300200141a00a6a41106a220f2004370300200141a00a6a41186a22102003290300370300200120012903f0053703a00a200141a8026a2009412010c00120012802ac02211120012802a80221142012420037030020084200370300200a4200370300200142003703f00520021001220b29000021022003200b41086a2900003703002001200237039007200b1035200a200329030037030020012001290390073703f00541cae3cb00ad4280808080f001841001220b29000021022003200b41086a2900003703002001200237039007200b103520082001290390072202370300200e200a290300370300200f200237030020102003290300370300200120012903f0053703a00a200141a0026a2009412010c0014100210e200120012802a402410020012802a0021b3602dc0620012011410020141b3602d8062001200141b8056a3602e006200141a00a6a200141d8066a200141d8066a41086a10b6060240024020012d00800b220a4103460d00200141f0076a200141a00a6a41e000109d081a2001200141a00a6a41e4006a2800003600b304200120012800810b3602b00441e80010332213450d022013200141f0076a41e000109d082203200a3a0060200320012802b004360061200341e4006a20012800b3043600002001428180808010370294072001200336029007200141f0056a41086a220b200141d8066a41086a280200360200200120012903d8063703f005200141a00a6a200141f0056a200b10b606024020012d00800b22094103470d004101210a4101210e0c020b41c9012108200141810b6a221241036a210f4101210e4101210a0340200141f0076a200141a00a6a41e000109d081a2001200f2800003600b304200120122800003602b004200141a00a6a200141f0076a41e000109d081a200120012800b30436008305200120012802b004360280050240200a200e470d0020014190076a200e410110960120012802900721130b201320086a2203419f7f6a200141a00a6a41e000109d081a2003417f6a20093a00002003200128028005360000200341036a2001280083053600002001200a41016a220a36029807200141a00a6a200141f0056a200b10b606200841e8006a2108200128029407210e20012d00800b22094103470d000c020b0b4100210a0b0240200a450d002013200a41e8006c6a2115200141f0076a41096a2118200141f0076a41106a2109200141a8066a2114200141a00a6a41086a2120200141a00a6a410172211f200141c9066a210f20014190076a41046a211641b6fdc600ad4280808080800184212220014198066a21172013210803402008280200210b200141a00a6a200841046a41dc00109d081a2001200841e1006a2800003602f0072001200841e4006a2800003600f307200841e0006a2d000022124103460d0120014190076a200141a00a6a41dc00109d081a200120012800f3073600eb03200120012802f0073602e803200141f0056a201641d800109d081a200f20012802e803360000200f41036a20012800eb03360000200120123a00c806200141f0076a41186a2210420037030020094200370300200141f0076a41086a22034200370300200142003703f00720221001220a29000021022003200a41086a290000370300200120023703f007200a103541e489c200ad4280808080d001841001220a2900002102200141c0046a41086a2211200a41086a290000370300200120023703c004200a1035200920012903c004370000200941086a2011290300370000200141d8066a41086a2003290300370300200141d8066a41106a2009290300370300200141d8066a41186a2010290300370300200120012903f0073703d80620014188026a200141d8066a412010d70120014188026a41106a2903002105200128028802210a2001290390022106200141f0056a41186a2903002123200141f0056a41086a290300211b41002103200129038006211d20012903f005211c0240200129039006220d4202882017290300220c423e86842202200c420288220484500d002002200d852004200c8584500d00410021030340200141f8016a200d200c200341046a41fe007110a408200341026a210320012903f8012202200141f8016a41086a290300220484500d012002200d852004200c85844200520d000b0b200841e8006a210820054200200a1b211920064200200a1b211a42002106420021040340200141d8016a20044201862006423f8884220442002006420186220642018422024200108408200141e8016a20024200200242001084080240200420012903e001220584200584420052200141e8016a41086a290300220520012903d801220720077c7c2207200554720d0020012903e8012105200141c8016a200d200c200341ff007110a40820042004200520012903c801562007200141c8016a41086a29030022055620072005511b220a1b210420062002200a1b21060b02402003450d0041002003417e6a220a200a20034b1b21030c010b0b410021030240201a4202882019423e868422022019420288220584500d002002201a85200520198584500d00410021030340200141b8016a201a2019200341046a41fe007110a408200341026a210320012903b8012202200141b8016a41086a290300220584500d012002201a852005201985844200520d000b0b4200210542002102034020014198016a20024201862005423f8884220242002005420186220542018422074200108408200141a8016a20074200200742001084080240200220012903a001220c84200c84420052200141a8016a41086a290300220c200129039801220d200d7c7c220d200c54720d0020012903a801210c20014188016a201a2019200341ff007110a40820022002200c20012903880156200d20014188016a41086a290300220c56200d200c511b220a1b210220052007200a1b21050b02402003450d0041002003417e6a220a200a20034b1b21030c010b0b024002400240024002402006200484500d0002400240024020120e03000102000b0340200141386a201d2023200620041098082005220c2002220d844200510d04200141386a41086a290300210220012903382105200141286a201c201b200c200d109808200520012903282219542002200141286a41086a290300220754200220075122031b0d062019200554200720025420031b0d03200141186a2005200220062004108408200141086a20192007200c200d108408201c200129030822027d2207201b200141086a41086a2903007d201c200254ad7d220284500d032023200141186a41086a2903007d2119201d20012903182205542103201d20057d21052006211c2004211b2007210620022104200c211d200d2123200520192003ad7d22028450450d000c060b0b0340200421072006210c20052002844200510d04200141e8006a201c201b200c2007109808200141f8006a201d2023200520021098082001290378220d2001290368221954200141f8006a41086a2903002204200141e8006a41086a290300220654200420065122031b0d052019200d54200620045420031b0d02200141d8006a200d200420052002108408200141c8006a20192006200c2007108408201c200129034822047d220d201b200141c8006a41086a2903007d201c200454ad7d220484500d022023200141d8006a41086a2903007d2119201d20012903582206542103201d20067d21062005211c2002211b200d210520042102200c211d20072123200620192003ad7d22048450450d000c050b0b201c201d56201b202356201b2023511b0d030b2001200b3602ac0a200141053a00a80a200141063a00a00a4100210341b0b4cc004100200141a00a6a10d4010c030b41d0c7c40041194194c5c800103f000b41d0c7c40041194194c5c800103f000b2001200b3602ac0a200141043a00a80a200141063a00a00a41b0b4cc004100200141a00a6a10d401024002400240024020012802a4062203450d00200141d8066a201410ee04200141a00a6a20012802d806221220012802e006221010d202200320006a210a024020012d00a00a2203410371222141034622110d00024020030e03000100000b0240024020110d0020210e03010001010b20012802c80a450d0020012802c40a10350b201f20012f00b8053b0000201f41026a200141b8056a41026a2d00003a000041002103200141003a00a00a2001200a3602a40a2020200141f0076a41c800109d081a0c020b2001200a3602d80a200141013602d40a20034102470d012010ad4220862012ad8410070c020b200141a00a6a41186a201441186a290000370300200141a00a6a41106a201441106a2900003703002020201441086a290000370300200120142900003703a00a200141f0076a200141a00a6a200b10f4040c020b200141003602f807200142013703f007200141a00a6a200141f0076a10ef0420012802f40721112010ad4220862012ad8420013502f80742208620012802f0072210ad84100202402011450d00201010350b0240200341037122034103460d0020030e03010001010b20012802c80a450d0020012802c40a10350b024020012802dc06450d00201210350b20182014290000370000201841086a201441086a290000370000201841106a201441106a290000370000201841186a201441186a2900003700002001411d3a00f8072001200b36029c08200141093602f007410c10332203450d042003200b360008200342e4cab5fbb6ccdcb0e3003700002001428c808080c0013702dc06200120033602d806200141a00a6a200141d8066a10f004200120012802a00a221020012802a80a41b0b4cc0041004100108a0220012802002112024020012802a40a450d00201010350b024020124101460d00410c10332212450d0520122003290000370000201241086a200341086a280000360000200141a00a6a200141f0076a41b002109d081a2001413f3a00e80c200141003602dc0c2001428c808080c0013702d40c200120123602d00c200a200141a00a6a410110cb04024020012802dc0c4102460d00024020012802d00c2203450d0020012802d40c450d00200310350b200141a00a6a10ba020b200141a00a6a200a10f3042001410020012802a40a417f6a20012802a00a4101461b360284052001200a36028005200141a00a6a200141d8066a10f00420012802a00a2103200120012802a80a3602bc05200120033602b80520014180056a200141b8056a10db01024020012802a40a450d00200310350b20012802dc06450d0120012802d80610350c010b20031035200141f0076a10ba0241b08cc500ad4280808080a0068410060b410121030b200120003602a40a200120033a00a10a200141013a00a00a200141f0076a200b10f50420012802f0072103200120012802f8073602f405200120033602f005200141a00a6a200141f0056a10f604024020012802f407450d00200310350b20082015470d000b0b0240200e450d00200e41e8006c450d00201310350b200010b7062102200141f00c6a2400427f201e20027c22022002201e541b0f0b1045000b41a0bac800411c41bcbac8001064000b2003200a419cb9c8001042000bc30103017f017e027f0240024002402000280200220241024d0d004101210042002103410121020c010b024002400240024020020e03000102000b410110332204450d0441002102200441003a00002000280204210520044101410510372200450d04200020053600014280808080d00021030c030b410110332200450d03200041013a00000c010b410110332200450d02200041023a00000b4100210242808080801021030b200129020020032000ad841002024020020d00200010350b0f0b103c000bd10707017f017e027f017e017f027e037f230041e0006b22032400200341306a2001200210da03024002400240024020032903302204a7220241ff01714101460d00200341306a41186a4200370300200341306a41106a22054200370300200341306a41086a220242003703002003420037033041d1c4c700ad4280808080e000841001220629000021072002200641086a29000037030020032007370330200610354184eec700ad4280808080b00284100122062900002107200341d0006a41086a2208200641086a2900003703002003200737035020061035200520032903502207370300200341106a41086a2002290300370300200341106a41106a2007370300200341106a41186a2008290300370300200320032903303703102003200341106a10e1022003290308420020032802001b210702400240200141ff0171220141024b0d004280b0def7d32b210920010e03010003010b4280c0a8ca9a3a21090b4100210141800c2102200042c0b2cd3b7c220a2000540d032007200a7c22002007540d0320002009560d030c020b200241087641ff017121012004421088a741087421020c020b427f2007427f200042c0b2cd3b7c220920092000541b7c220020002007541b21000b200341306a41186a22084200370300200341306a41106a22064200370300200341306a41086a220242003703002003420037033041d1c4c700ad4280808080e000842207100122052900002109200341d0006a41086a2201200541086a2900003703002003200937035020051035200220012903003703002003200329035037033041b8eec700ad42808080808002841001220529000021092001200541086a2900003703002003200937035020051035200620032903502209370300200341106a41086a220b2002290300370300200341106a41106a220c2009370300200341106a41186a220d20012903003703002003200329033037031020032004422088a7360230200341106aad42808080808004842204200341306aad22094280808080c0008410022008420037030020064200370300200242003703002003420037033020071001220529000021072001200541086a290000370300200320073703502005103520022001290300370300200320032903503703304184eec700ad4280808080b002841001220529000021072001200541086a2900003703002003200737035020051035200620032903502207370300200b2002290300370300200c2007370300200d20012903003703002003200329033037031020032000370330200420094280808080800184100241022101410021020b200341e0006a240020022001720bac0604047f017e017f047e230041d0016b22022400200241a0016a41186a4200370300200241a0016a41106a22034200370300200241a0016a41086a22044200370300200242003703a00141e3efcb00ad4280808080a002841001220529000021062004200541086a290000370300200220063703a0012005103541f5efcb00ad4280808080900284100122052900002106200241c0016a41086a2207200541086a290000370300200220063703c00120051035200320022903c001220637030020024180016a41086a200429030037030020024180016a41106a200637030020024180016a41186a2007290300370300200220022903a0013703800120014280c0a8ca9a3a20014280c0a8ca9a3a541b2101200241e8006a20024180016a10bc020240024020022802680d004100210442002108420021060c010b200229037022084200522205200241e8006a41106a29030022064200552006501b21042006427f550d00428080808080808080807f420020062005ad7c7d20082006428080808080808080807f85845022051b21064200420020087d20051b21080b200241d8006a2008200642808090bbbad6adf00d4200109808200241c8006a20022903582209200241d8006a41086a290300220a428080f0c4c5a9d28f72427f108408200242808090bbbad6adf00d3703a8012002200820022903487c22063703a001200241286a200241a0016a200642808090bbbad6adf00d564103746a290300420020014200108408200241186a20022903282206200241286a41086a290300220842808090bbbad6adf00d4200109808200241086a2002290318220b200241186a41086a290300428080f0c4c5a9d28f72427f108408200241386a2009200a200142001084082000200241386a41086a29030020022903382209200b200620022903087c220a428080c89d9deb96f806562008200241086a41086a2903007c200a200654ad7c22064200522006501bad7c7c2206200954ad7c2208200620017c2209200654ad7c4200420020082001200654ad7c7d2208200120067d220620015620084200522008501b22051b20041b370308200020094200200620051b20041b370300200241d0016a24000b910f05017f017e047f017e067f230041f0016b2201240042002102200141d8006a41186a22034200370300200141d8006a41106a22044200370300200141d8006a41086a22054200370300200142003703584193d1cb00ad4280808080a00184100122062900002107200141c8006a41086a2208200641086a2900003703002001200737034820061035200520082903003703002001200129034837035841d8c7ca00ad4280808080e000841001220629000021072008200641086a2900003703002001200737034820061035200420012903482207370300200141286a41086a22062005290300370300200141286a41106a2007370300200141286a41186a200829030037030020012001290358370328200141f8006a200141286a412010d50120012d00782108200320014191016a290000370300200420014189016a290000370300200520014181016a290000370300200120012900793703580240024020084101470d0020002001290358370000200041186a2003290300370000200041106a2004290300370000200041086a20052903003700000c010b200141f8006a41186a4200370300200141f8006a41106a22094200370300200141f8006a41086a220842003703002001420037037841d1c4c700ad4280808080e000841001220a29000021072008200a41086a29000037030020012007370378200a10354185c5c700ad4280808080e000841001220a29000021072006200a41086a29000037030020012007370328200a103520092001290328220737030020052008290300370300200420073703002003200629030037030020012001290378370358200141f8006a200141d8006a10ce02024002402001280278220a0d004104210a410021050c010b200129027c2202422088a721050b02400240200541246c2205450d002005415c6a2108200a210503400240024020052d00004101460d002008450d030c010b200541016a2800002103200541086a28020021062001200541106a28020036025c200120063602580240200341c28289aa04460d0020080d010c030b200141f8006a200141d8006a10800420012903784203510d02200141f8006a41106a22052802002106200141f8006a41186a420037030020054200370300200141f8006a41086a220842003703002001420037037841a3edcb00ad4280808080f000841001220329000021072008200341086a290000370300200120073703782003103541f393ca00ad4280808080a00184100122032900002107200141286a41086a2209200341086a2900003703002001200737032820031035200520012903282207370300200141d8006a41086a2008290300370300200141d8006a41106a2007370300200141d8006a41186a200929030037030020012001290378370358200141f8006a200141d8006a10fe0120012802782205410120051b21034100210802402006200129027c420020051b2207422088a74f0d00200320064105746a2205450d00200141086a41186a200541186a290000370300200141086a41106a200541106a290000370300200141086a41086a200541086a29000037030020012005290000370308410121080b0240200742ffffff3f83500d00200310350b2008450d02200141f8006a41186a2208200141086a41186a290300370300200141f8006a41106a2203200141086a41106a290300370300200141f8006a41086a2206200141086a41086a29030037030020012001290308370378200141d8006a41186a220b4200370300200141d8006a41106a220c4200370300200141d8006a41086a22094200370300200142003703584193d1cb00ad4280808080a001841001220d2900002107200141c8006a41086a2205200d41086a29000037030020012007370348200d1035200920052903003703002001200129034837035841d8c7ca00ad4280808080e000841001220d29000021072005200d41086a29000037030020012007370348200d103520042001290348370000200441086a2005290300370000200141286a41086a2009290300370300200141286a41106a200c290300370300200141286a41186a200b290300370300200120012903583703280240412010332205450d0020052001290378370000200541186a2008290300370000200541106a2003290300370000200541086a2006290300370000200141286aad42808080808004842005ad4280808080800484100220051035200041186a2008290300370000200041106a2003290300370000200041086a2006290300370000200020012903783700000c040b1045000b200541246a21052008415c6a21080c000b0b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000b02402002422088a72205450d00200541246c2108200a210503400240024020052d0000220341044b0d0002400240024020030e050400010204040b2005410c6a280200450d03200541086a28020010350c030b2005410c6a280200450d02200541086a28020010350c020b2005410c6a280200450d01200541086a28020010350c010b200541086a280200450d00200541046a28020010350b200541246a21052008415c6a22080d000b0b2002a72205450d00200541246c450d00200a10350b200141f0016a24000b8b0101017f41e09dcc00ad4280808080d001841006024002400240024020002d00000e0400010203000b200041046a29020010060f0b41d29dcc00ad4280808080e0018410060f0b41c89dcc00ad4280808080a0018410060f0b20003100011026200041026a31000010260240200041046a2802002201450d00200041086a3502004220862001ad8410060b0b130020004101360204200041a8d0c4003602000b850a03057f017e047f230041a0016b22012400200141e8006a41186a22024200370300200141e8006a41106a22034200370300200141e8006a41086a220442003703002001420037036841a3edcb00ad4280808080f000841001220529000021062004200541086a290000370300200120063703682005103541a5ebcb00ad4280808080c0018410012205290000210620014188016a41086a2207200541086a29000037030020012006370388012005103520032001290388012206370300200141c8006a41086a2004290300370300200141c8006a41106a2006370300200141c8006a41186a200729030037030020012001290368370348200141106a200141c8006a412010c00120012802142105200128021021082002200041186a2900003703002003200041106a2900003703002004200041086a290000370300200120002900003703684188e8cb00ad4280808080800184100122002900002106200141186a41086a200041086a290000370300200120063703182000103541f1c8c400ad4280808080e001841001220029000021062007200041086a29000037030020012006370388012000103520012005410020081b3602382001200141386aad4280808080c00084100322002900003703980120001035200141d4006a22052001413c6a360200200120014198016a41086a220736024c2001200141386a360250200120014198016a360248200141286a200141c8006a107b0240024002400240412010332200450d0020002001290368370000200041186a2002290300370000200041106a2003290300370000200041086a200429030037000020012000ad42808080808004841003220429000037039801200410352005200041206a360200200120003602502001200736024c200120014198016a360248200141386a200141c8006a107b200010352001280230220741206a2202200128024022086a2204417f4c0d01200128023821092001280228210a0240024020040d0041002105410121000c010b200410332200450d01200421050b024002402005410f4d0d00200521030c010b200541017422034110200341104b1b22034100480d03024020050d002003103322000d010c050b20052003460d0020002005200310372200450d040b20002001290318370000200041086a200141186a41086a2903003700000240024020034170714110460d00200321050c010b200341017422054120200541204b1b22054100480d0320032005460d0020002003200510372200450d040b2000200129038801370010200041186a20014188016a41086a29030037000002400240200541606a2007490d00200521030c010b2007415f4b0d03200541017422032002200320024b1b22034100480d0320052003460d0020002005200310372200450d040b200041206a200a2007109d081a02400240200320026b2008490d00200321050c010b20042002490d03200341017422052004200520044b1b22054100480d03024020030d00024020050d00410121000c020b200510332200450d050c010b20032005460d0020002003200510372200450d040b200020026a20092008109d081a0240200128023c450d00200910350b0240200128022c450d00200a10350b200141086a2000200410c0012001200128020c41016a410120012802081b3602682004ad4220862000ad84200141e8006aad4280808080c00084100202402005450d00200010350b200141a0016a24000f0b1045000b1044000b103e000b103c000b340020004188e8cb0036020420004100360200200041146a4104360200200041106a41f4d4c400360200200041086a42083702000b130020004101360204200041d8ddc4003602000b3400200041d1efcb0036020420004100360200200041146a4102360200200041106a4188e5c400360200200041086a42093702000b130020004101360204200041c8e7c4003602000b2d01017f02404108103322020d001045000b20004288808080800137020420002002360200200242dc0b3700000bd50101037f230041106b2203240002400240200241d0026c4104722204417f4c0d00200410332205450d0120034100360208200320043602042003200536020020022003107702402002450d00200241d0026c2102034002400240200141bc026a2802004102470d00200341003a000f20032003410f6a410110780c010b200341013a000f20032003410f6a410110782001200310da040b200141d0026a2101200241b07d6a22020d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1044000b1045000bec0101037f230041106b220224000240024020002802b00222030d00200241003a00072001200241076a41011078200241076a21030c010b200241013a00072001200241076a41011078200041b8026a2802002204200110772001200320041078200241076a21030b200220002d00c8023a000720012003410110782000200110af030240024020002802bc024101460d00200241003a000720012003410110780c010b200241013a000720012003410110782002200041c0026a2802003602082001200241086a410410782002200041c4026a28020036020c20012002410c6a410410780b200241106a24000b6401037f024041094101200128020022024101461b220310332204450d000240024020020d00200441003a0000410121010c010b200441013a000020042001290204370001410921010b2000200136020820002003360204200020043602000f0b1045000bc90202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d01200441012001105221000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000b20024180016a240020000f0b200341800141c88bc0001059000b200341800141c88bc0001059000b8b0605027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d022001410141d88bc0004102200241206a20006a41800120006b105621000c060b41272100200241186a21060340200241106a200520044290ce0042001098082002200229031022072006290300220842f0b17f427f108408200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a410174419a87c0006a2f00003b00002003417e6a200a419c7f6c20096a41ffff0371410174419a87c0006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d012001410141d88bc0004102200241206a20006a41800120006b105621000c040b200041800141c88bc0001059000b200041800141c88bc0001059000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff0371410174419a87c0006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a2009410174419a87c0006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b2001410141b0b4cc004100200241206a20006a412720006b105621000b200241a0016a240020000ba50301077f230041106b2202240002400240024002402001410c6a2802002203417f4c0d0020012802042104200128020021050240024020030d0041002106410121070c010b200310332207450d02200321060b0240024020062003490d00200621080c010b200641017422082003200820034b1b22084100480d03024020060d002008103322070d010c050b20062008460d0020072006200810372207450d040b200720042003109d0821062002200141106a10a6032000410c6a2003360200200041086a20083602002000200636020420002005360200200041106a2002290300370200200041186a200241086a280200360200200020012802243602242000200129021c37021c20002001290228370228200041306a200141306a290200370200200041386a200141386a290200370200200041c0006a200141c0006a290200370200200041c8006a200141c8006a290200370200200041d0006a200141d0006a290200370200200041d8006a200141d8006a290200370200200041e0006a200141e0006a290200370200200241106a24000f0b1044000b1045000b103e000b103c000b1300200041023602042000418cecc4003602000b0f00200028020020012002107f41000bfe0101017f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b20002002410c6a2001107f200241106a240041000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41e88ac500200241086a10432101200241206a240020010ba50502067f017e230041d0006b220424002004200136020c2004200041b0b4cc0020011b3602082004200441086a10c40102400240024002400240024020042802000d0020042802042205200428020c4104762201200120054b1b22004104742201417f4c0d030240024020000d00410821060c010b200110332206450d050b41002101200441003602182004200036021420042006360210024002402005450d00200441306a4104722107410021010340200441306a200441086a10e404200441c0006a41086a2200200741086a28020036020020042007290200370340200428023022084104460d02200441206a41086a2209200028020036020020042004290340370320024020012004280214470d00200441106a20014101109a0120042802102106200428021821010b200620014104746a22002008360200200020042903203702042000410c6a20092802003602002004200141016a22013602182005417f6a22050d000b200428021421000b2006450d01200441306a200220062001200311060020042802302105410110332201450d054201210a200442013702442004200136024020054105470d02200141013a0000200441013602480c030b200428021441ffffffff0071450d00200610350b41b08bc50041f000200441306a41908bc50041a08cc5001046000b200141003a00002004410136024820014101410210372101024020054104470d002001450d04200141003a00012004200136024020044282808080203702444202210a0c010b2001450d03200141013a0001200420013602402004428280808020370244200441306a200441c0006a10e5042004350248210a200428024021010b2001ad422086200a84210a0240200041ffffffff0071450d00200610350b200441d0006a2400200a0f0b1044000b1045000b103c000bd90202047f017e02400240024002400240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a360200200441034b0d0520040e0401020304010b200041043602000f0b024020054104490d00200041003602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b200041043602000f0b024020054108490d0020004101360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b024020054104490d00200041023602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b200041043602000f0b024020054108490d0020004103360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b200041043602000bd70101017f230041106b220224000240024002400240024020002802000e0400010203000b200241003a00082001200241086a41011078200220002802043602082001200241086a410410780c030b200241013a00082001200241086a410110782002200041086a2903003703082001200241086a410810780c020b200241023a00082001200241086a41011078200220002802043602082001200241086a410410780c010b200241033a00082001200241086a410110782002200041086a2903003703082001200241086a410810780b200241106a24000bec0201047f230041306b22042400200441a58ecc00410310500240024002400240024020020d0041002105410121060c010b200210332206450d01200221050b0240024020052002490d00200521070c010b200541017422072002200720024b1b22074100480d02024020050d002007103322060d010c040b20052007460d0020062005200710372206450d030b200620012002109d082105200441146a2002360200200441106a220220073602002004200536020c200441186a41106a22052002290300370300200441186a41086a2207200441086a29030037030020042004290300370318024020002802082202200041046a280200470d00200020024101109101200028020821020b200028020020024105746a22024100360218200220042903183702002002411c6a2003360200200241106a2005290300370200200241086a20072903003702002000200028020841016a360208200441306a24000f0b1045000b103e000b103c000bdd0505047f017e017f017e0a7f230041e0016b22022400200241c0006a41186a22034200370300200241c0006a41106a22044200370300200241c0006a41086a220542003703002002420037034041d9e3cb00ad42808080809001842206100122072900002108200241e0006a41086a2209200741086a29000037030020022008370360200710352005200929030037030020022002290360370340419c8dc500ad4280808080c001841001220729000021082009200741086a2900003703002002200837036020071035200420022903602208370300200241206a41086a22072005290300370300200241206a41106a220a2008370300200241206a41186a220b200929030037030020022002290340370320200241e0006a200241206a10c0020240024020022d008001220c4103470d002000411610e8040c010b200241206aad428080808080048422081007200241086a220d2009290300370300200241106a220e200241e0006a41106a220f290300370300200241186a2210200241e0006a41186a2211290300370300200220022903603703002003420037030020044200370300200542003703002002420037034020061001221229000021062009201241086a2900003703002002200637036020121035200520092903003703002002200229036037034041efe3cb00ad4280808080d002841001221229000021062009201241086a290000370300200220063703602012103520042002290360370000200441086a200929030037000020072005290300370300200a2004290300370300200b200329030037030020022002290340370320200241013a00602008200241e0006aad428080808010841002200941023a0000200241063a006041b0b4cc004100200241e0006a10d40120112010290300370300200f200e2903003703002009200d29030037030020022002290300370360200141809c316a200241e0006a200c4180de3410e904200041043a00000b200241e0016a24000b8e0701047f230041c0006b2202240041f6f2c4002103412421044108210502400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141ff01710e26000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425000b200241146a410136020020024201370204200241e8d4ca003602002002410436021c200241f0d5ca003602182002200241186a360210200241b0b4cc00104c000b41eaf5c400210341002104410821050c230b41d2dfca002103410f2105410121040c220b41e2f5c400210341022104410821050c210b41daf5c400210341032104410821050c200b41cbf5c4002103410f2105410421040c1f0b41e1dfca00210341112105410521040c1e0b41b8f5c400210341132105410621040c1d0b41a7f5c400210341112105410721040c1c0b419cf5c4002103410b2105410821040c1b0b4192f5c4002103410a2105410921040c1a0b4185f5c4002103410d2105410a21040c190b419bd6ca002103410c2105410b21040c180b41fbf4c4002103410a2105410c21040c170b41eff4c4002103410c2105410d21040c160b41def4c400210341112105410e21040c150b41d3f4c4002103410b2105410f21040c140b41a1dfca00210341102104410821050c130b41cbf4c400210341112104410821050c120b41bcf4c4002103410f2105411221040c110b41abf4c400210341112105411321040c100b419cf4c4002103410f2105411421040c0f0b4191f4c4002103410b2105411521040c0e0b4188f4c400210341092105411621040c0d0b41fef3c4002103410a2105411721040c0c0b41f7f3c400210341072105411821040c0b0b41eef3c400210341092105411921040c0a0b41e5f3c400210341092105411a21040c090b41ddf3c4002103411b2104410821050c080b41d1f3c4002103410c2105411c21040c070b41c0f3c400210341112105411d21040c060b41a7d6ca002103411e2104410821050c050b41b7f3c400210341092105411f21040c040b41a6f3c400210341112105412021040c030b4199f3c4002103410d2105412121040c020b418ff3c4002103410a2105412221040c010b41fef2c400210341112105412321040b20004183143b0100200041086a2005360200200041046a2003360200200041026a20043a0000200241c0006a24000b900707047f017e017f017e017f017e047f230041e0016b22042400200441d8006a41186a22054200370300200441d8006a41106a22064200370300200441d8006a41086a220742003703002004420037035841d9e3cb00ad4280808080900184220810012209290000210a200441c8006a41086a220b200941086a2900003703002004200a370348200910352007200b2903003703002004200429034837035841cae3cb00ad4280808080f00184220a10012209290000210c200b200941086a2900003703002004200c3703482009103520062004290348220c370300200441106a41086a22092007290300370300200441106a41106a220d200c370300200441106a41186a220e200b29030037030020042004290358370310200441086a200441106a412010c001200428020c210f20042802082110200542003703002006420037030020074200370300200442003703582008100122052900002108200b200541086a29000037030020042008370348200510352007200b29030037030020042004290348370358200a100122052900002108200b200541086a290000370300200420083703482005103520062004290348220837030020092007290300370300200d2008370300200e200b290300370300200420042903583703102004200f410020101b220b41016a360258200441106aad4280808080800484200441d8006aad4280808080c0008410022004413f6a4200370000200441376a42003700002004412f6a4200370000200441276a42003700002004411f6a420037000020044200370017200441e1006a22062009290000370000200441e9006a200d290000370000200441f1006a200e290000370000200441f9006a200441106a41206a29000037000020044181016a200441386a29000037000020044188016a420037000020044194016a200336020020044190016a200036020020044198016a2001290000370300200441a0016a200141086a290000370300200441a8016a200141106a290000370300200441b0016a200141186a290000370300200441003a005820042004290010370059200441b8016a20023a0000200441c8006a200b10f50420042802482101200420042802503602dc01200420013602d801200441d8006a200441d8016a10f6040240200428024c450d00200110350b200441e4006a200b360200200620023a0000200741033a0000200441063a005841b0b4cc004100200441d8006a10d401200441e0016a24000bcd1a06057f017e017f017e117f097e23002202210320024180046b4160712202240020024180016a41186a420037030020024180016a41106a2204420037030020024180016a41086a22054200370300200242003703800141d9e3cb00ad4280808080900184100122062900002107200241d8006a41086a2208200641086a290000370300200220073703582006103520052008290300370300200220022903583703800141918dc500ad4280808080b001841001220629000021072008200641086a2900003703002002200737035820061035200420022903582207370300200241386a41086a2005290300370300200241386a41106a2007370300200241386a41186a2008290300370300200220022903800137033820024120360294022002200241386a3602900220024198026a200241386aad42808080808004842209100510c20102400240024002400240200228029802220a0d004100210b0c010b200228029c02210c200220024198026a41086a2802003602ac022002200a3602a802200241306a200241a8026a10c4010240024020022802300d002002280234220d20022802ac02220e41c4006e22082008200d4b1bad42c4007e2207422088a70d042007a72208417f4c0d040240024020080d004104210b0c010b20081033220b450d040b200241003602b8022002200b3602b0022002200841c4006e3602b40202400240200d450d004100210f41002110034002400240200e4104490d00200220022802a802221141046a3602a8022011280000211241002108200241003a00a001200e417c6a21060240024002400240034020062008460d0120024180016a20086a201120086a220541046a2d00003a00002002200541056a3602a8022002200841016a22053a00a0012005210820054120470d000b200241d8006a41186a221320024180016a41186a2214290300370300200241d8006a41106a221520024180016a41106a2216290300370300200241d8006a41086a221720024180016a41086a2218290300370300200220022903800137035841002108200241003a00a001201120056a21192005200e6b41046a210e0340200e20086a450d0220024180016a20086a201920086a221141046a2d00003a00002002201141056a3602a8022002200841016a22113a00a0012006417f6a21062011210820114120470d000b200241c0036a41186a2014290300370300200241c0036a41106a2016290300370300200241c0036a41086a2018290300370300200241e0036a41086a2017290300370300200241e0036a41106a2015290300370300200241e0036a41186a201329030037030020022002290380013703c003200220022903583703e003200620056b210e410021082012211a0c050b200841ff0171450d020c010b200841ff0171450d010b200241003a00a0010b4100210e0b410121080b200241a0036a41186a2205200241e0036a41186a290300370300200241a0036a41106a2206200241e0036a41106a290300370300200241a0036a41086a2211200241e0036a41086a29030037030020024180036a41086a2219200241c0036a41086a29030037030020024180036a41106a2212200241c0036a41106a29030037030020024180036a41186a2213200241c0036a41186a290300370300200220022903e0033703a003200220022903c0033703800320080d02201041016a2110200241e0026a41186a22142005290300370300200241e0026a41106a22052006290300370300200241e0026a41086a22062011290300370300200241c0026a41086a22112019290300370300200241c0026a41106a22192012290300370300200241c0026a41186a22122013290300370300200220022903a0033703e00220022002290380033703c0020240200f20022802b402470d00200241b0026a200f4101109f0120022802b002210b20022802b802210f0b200b200f41c4006c6a2208201a360200200820022903e0023702042008410c6a2006290300370200200841146a20052903003702002008411c6a2014290300370200200820022903c0023702242008412c6a2011290300370200200841346a20192903003702002008413c6a20122903003702002002200f41016a220f3602b8022010200d470d000b2002200e3602ac020b20022902b4022107200b450d010c020b2002200e3602ac02024020022802b4022208450d00200841c4006c450d00200b10350b0b4100210b2002410036026020024201370358200241093602e403200220024190026a3602e0032002200241d8006a3602c00320024194016a41013602002002420137028401200241c888c200360280012002200241e0036a36029001200241c0036a41e88ac50020024180016a10431a20023502604220862002350258841006200228025c450d00200228025810350b200c450d00200a10350b200b4104200b1b2110024020074200200b1b221b422088a7220b450d00200241186a201028020010eb04200241186a41106a2903004200200228021822081b21072002290320420020081b211c0240200b4101470d002002201c3703800141002111200241003602900120022007370388010c040b201041c4006a2108200b41c4006c41bc7f6a210e41002111200241106a21192010210f4101210603402002200828020010eb04200720192903004200200228020022051b221d201c2002290308420020051b221e562007201d562007201d511b22051b2107201c201e20051b211c200f200820051b210f2011200620051b2111200641016a2106200841c4006a2108200e41bc7f6a220e0d000b2002201c3703800120022011360290012002200737038801200f0d030b2000411610e8040240201ba72202450d00200241c4006c450d00201010350b200324000f0b1045000b1044000b02402011200b4f0d002010201141c4006c6a220841186a2206290200211c2010200b417f6a221141c4006c6a220541c0006a280200210f200541206a290200211d200541286a290200211e200541306a290200211f200541386a29020021202005290200212120052902082107200529021021222006200541186a290200370200200829021021232008202237021020082902082122200820073702082008290200210720082021370200200841386a2020370200200841306a201f370200200841286a201e370200200841206a2205280200210b2005201d370200200841c0006a200f3602002002202337039001200220223703880120022007370380012002201c37039801200241e0036a41186a200228029c01360200200241e0036a41106a200229029401370300200241e0036a41086a200229028c0137030020022002290284013703e00320024180016a41186a220f420037030020024180016a41106a220e420037030020024180016a41086a22054200370300200242003703800141d9e3cb00ad428080808090018410012206290000211c200241d8006a41086a2208200641086a2900003703002002201c3703582006103520052008290300370300200220022903583703800141918dc500ad4280808080b0018410012206290000211c2008200641086a2900003703002002201c3703582006103520042002290358370000200441086a2008290300370000200241386a41086a2005290300370300200241386a41106a200e290300370300200241386a41186a200f290300370300200220022903800137033820024180016a2010201110ec0420092002350288014220862002280280012208ad8410020240200228028401450d00200810350b2007a7210e0240201ba72208450d00200841c4006c450d00201010350b200241d8006a200e10ed0420024180016a200228025822082002280260220510cc020240200228029001220f450d002005ad4220862008ad8410070b20024188016a290300210720024198016a2802002119200229038001211c20022802940121100240200228025c450d00200810350b0240200f450d0002402019410574450d00201c200784500d0020024189016a210520194105742106200241b8016a2111200f210803402002201c3703c003200220073703c803200220083602a003200241d8006a2008200241c0036a200241a0036a10f002024020022903584201520d002002290360211d200841186a290000211e200841106a290000211b200841086a29000021092008290000211f2011200241d8006a41106a2903003703002005201f370000200541086a2009370000200541106a201b370000200541186a201e370000200241003a008801200241033a0080012002201d3703b00141b0b4cc00410020024180016a10d4010b200841206a2108200641606a22060d000b0b200241a8016a2007370300200241a0016a201c37030020024180016a41186a2208201936020020024194016a201036020020024180016a41106a2205200f3602002002418c016a200e36020020024180016a41086a220641013a0000200241063a00800141b0b4cc00410020024180016a10d4012008200241e0036a41186a2802003602002005200241e0036a41106a2903003703002006200241e0036a41086a290300370300200220022903e003370380012002200b36029c01200141809c316a20024180016a41004180de3410e9040b200041043a0000200324000f0b2011200b104a000bcf0102037f047e230041c0006b22022400200241306a200110ed04200241106a20022802302203200228023810cc02200228023421010240024020022802202204450d00200241186a2903002105200229031021062002290224210702402001450d00200310350b20022006200520074220884200108408200241086a29030021054201210620022903002108200742ffffff3f83500d01200410350c010b02402001450d00200310350b420021060b2000200837030820002006370300200041106a2005370300200241c0006a24000bc006010a7f230041106b220324000240024002400240200241c4006c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b20034100360208200320053602002003200436020420022003107702402002450d002001200241c4006c6a2106200328020421022003280208210403402001280200210702400240200220046b4104490d0020032802002105200221080c010b200441046a22052004490d05200241017422082005200820054b1b22084100480d050240024020020d00024020080d00410121050c020b2008103322050d010c080b2003280200210520022008460d0020052002200810372205450d070b20032008360204200320053602000b200520046a20073600002003200441046a2209360208412010332202450d03200241186a220a2001411c6a290000370000200241106a220b200141146a290000370000200241086a220c2001410c6a2900003700002002200141046a29000037000002400240200820096b4120490d00200441246a2104200821070c010b200941206a22042009490d05200841017422072004200720044b1b22074100480d050240024020080d00024020070d00410121050c020b200710332205450d080c010b20082007460d0020052008200710372205450d070b20032007360204200320053602000b200520096a22082002290000370000200841186a200a290000370000200841106a200b290000370000200841086a200c290000370000200320043602082002103502400240200720046b411f4d0d00200721020c010b200441206a22022004490d05200741017422082002200820024b1b22024100480d050240024020070d00024020020d00410121050c020b200210332205450d080c010b20072002460d0020052007200210372205450d070b20032002360204200320053602000b200520046a2205200141246a290000370000200541186a2001413c6a290000370000200541106a200141346a290000370000200541086a2001412c6a2900003700002003200441206a2204360208200141c4006a22012006470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1044000b1045000b103e000b103c000bfc0403027f017e057f230041d0006b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541f2f8c400ad4280808080900184100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000b9f0303027f017e027f230041206b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003103541888dc500ad4280808080900184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b880202037f017e230041106b220224000240024020002d00004101460d00200241003a000020012002410110782002200041046a28020036020020012002410410780c010b200241013a00002001200241011078200041246a28020021032000412c6a28020022042001107720012003200410782001200041016a41201078200041c0006a29030021052002200041c8006a2903003703082002200537030020012002411010782002200041306a28020036020020012002410410780240200041346a2802004101460d00200241003a000020012002410110780c010b200241013a000020012002410110782002200041386a28020036020020012002410410780b200241106a24000ba50403027f017e057f230041306b220224004189fec600ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003103541b489c500ad4280808080e00084100122032900002104200241106a41086a200341086a2900003703002002200437031020031035200241206a2001280200200128020810980302400240024002402002280228220541206a2206417f4c0d00200228022021070240024020060d0041002103410121010c010b200610332201450d02200621030b024002402003410f4d0d00200321080c010b200341017422084110200841104b1b22084100480d03024020030d002008103322010d010c050b20032008460d0020012003200810372201450d040b20012002290300370000200141086a200241086a2903003700000240024020084170714110460d00200821030c010b200841017422034120200341204b1b22034100480d0320082003460d0020012008200310372201450d040b20012002290310370010200141186a200241106a41086a29030037000002400240200341606a2005490d00200321080c010b200541206a22082005490d03200341017422092008200920084b1b22084100480d0320032008460d0020012003200810372201450d040b200141206a20072005109d081a20002006360208200020083602042000200136020002402002280224450d00200710350b200241306a24000f0b1044000b1045000b103e000b103c000bd60201027f024002402002450d002002417f6a21040240024020012d0000220241037122054103460d0002400240024020050e03000102000b200241027621020c030b2004450d0320012d0001410874200272220241ffff0371418002490d03200241fcff037141027621020c020b20044103490d0220012f0001200141036a2d000041107472410874200272220241808004490d02200241027621020c010b200241034b0d0120044104490d0120012800012202418080808004490d010b200220036a22012002490d0141012103410121050240200241c000490d0041022105200241808001490d00410441052002418080808004491b21050b0240200141c000490d0041022103200141808001490d00410441052001418080808004491b21030b20002001360204200041003602002000410c6a2003360200200041086a20053602000f0b200041013602000f0b200041013602000ba40301027f230041e0006b22032400200341003a00050240024002400240200041c000490d00200041808001490d012000418080808004490d0241052104200341053a0005200341033a0000200320003600010c030b41012104200341013a0005200320004102743a00000c020b41022104200341023a0005200320004102744101723b01000c010b41042104200341043a0005200320004102744102723602000b024002402001280200220028020822012002490d0020002802002100200320023602082003200436020c20042002470d01200020032002109d081a200341e0006a24000f0b2002200141ccc8ca001058000b200341286a41146a410a360200200341346a410c360200200341106a41146a41033602002003200341086a36024020032003410c6a360244200341c8006a41146a410036020020034203370214200341a0b3cc003602102003410c36022c200341b0b4cc003602582003420137024c200341f4b3cc003602482003200341286a3602202003200341c8006a3602382003200341c4006a3602302003200341c0006a360228200341106a41b0b4cc00104c000bad0301087f230041c0006b22022400200241106a200110c904200241206a200235021842208620022802102203ad84100510c20102400240200228022022040d002002410036023820024208370330200241306a4100410010a701200228023841d0026c220141d0026d2105200228023421062002280230210702402001450d00200541d0026c21082007210103400240200141bc026a2802004102460d000240200141b0026a2802002209450d00200141b4026a280200450d00200910350b200110bb020b200141d0026a2101200841b07d6a22080d000b0b02402006450d00200641d0026c450d00200710350b4100210120004100360200200020053602040c010b200228022421082002200241206a41086a28020036023420022004360230200241086a200241306a10c401024002402002280208450d00200041b0b4cc00360204200041086a4100360200410121010c010b2000200228020c360204410021010b20002001360200410121012008450d00200410350b02402002280214450d00200310350b02402004410047200141017371450d002002280224450d00200410350b200241c0006a24000bd71203077f057e057f230041d0086b22032400200341e0006a200110ee04200341f0056a200328026022042003280268220510d20241022106024020032d00f005220741024622080d002005ad4220862004ad8410070b20034198036a411f6a220520034190066a28000036000020034198036a41186a220920034189066a29000037030020034198036a41106a20034181066a290000220a37030020034198036a41086a200341f9056a290000220b370300200320032900f105220c37039803200341b8066a290300210d200341b0066a290300210e20034194066a280200210f20034198066a28020021102003419c066a2802002111200341f0056a411f6a22122005280000360000200341f0056a41186a22052009290300370300200341f0056a41106a2209200a370300200341f0056a41086a2213200b3703002003200c3703f005024020080d00200341186a411f6a2012280000360000200341186a41186a2005290300370300200341186a41106a2009290300370300200341186a41086a2013290300370300200320032903f005370318200721060b02402003280264450d00200410350b0240024002400240200641037122064103460d0020060e03010001010b200341c0006a41186a200341186a41186a290300370300200341c0006a41106a200341186a41106a290300370300200341c0006a41086a200341186a41086a2903003703002003200329031837034020032011360294032003200f36029003200341e0006a20034190036a10b90202402003280260411b460d0020034198036a200341e0006a41b002109d081a2003200e3703c8052003200d3703d0050240200e200d84500d002003200341c0006a3602a408200341a8086a200341c0006a200341c8056a200341a4086a10f00220032903a8084201520d0020032903b008210a200341a8066a200341a8086a41106a290300370300200341a0066a200a370300200341f0056a41086a41003a0000200341f9056a200329034037000020034181066a200341c0006a41086a29030037000020034189066a200341c0006a41106a29030037000020034191066a200341d8006a290300370000200341033a00f00541b0b4cc004100200341f0056a10d4010b200341f0056a41086a2206410c3a000020034199066a2003290340370000200341f9056a2207200129000037000020034181066a200141086a29000037000020034189066a200141106a29000037000020034191066a200141186a290000370000200341a1066a200341c0006a41086a290300370000200341a9066a200341c0006a41106a290300370000200341b1066a200341c0006a41186a290300370000200341063a00f005200341c8066a200d370300200341c0066a200e37030041b0b4cc004100200341f0056a10d401200341f0056a20034198036a41b002109d081a200341003b01a808200341c8056a200341f0056a200341a8086a10ac0320032903c805210a200341f0056a410c6a20023602002007200a503a0000200641073a0000200341063a00f00541b0b4cc004100200341f0056a10d401200041043a000020100d020c030b2003200e3703a8082003200d3703b0080240024002400240200e200d844200520d00200342003703d005200342003703c8050c010b2003200341c0006a3602c80520034198036a200341c0006a200341a8086a200341c8056a10a802200341b8036a290300210a20032903b003210b02402003290398034201520d0020032903a003210c200341a8066a20034198036a41106a290300370300200341a0066a200c370300200341f0056a41086a41003a0000200341f9056a200329034037000020034181066a200341c0006a41086a29030037000020034189066a200341c0006a41106a29030037000020034191066a200341d8006a290300370000200341033a00f00541b0b4cc004100200341f0056a10d4010b2003200b3703c8052003200a3703d005200b200a844200520d010b200341f0056a41186a22054200370300200341f0056a41106a22044200370300200341f0056a41086a22074200370300200342003703f00541b6fdc600ad4280808080800184220a10012208290000210b200341a8086a41086a2206200841086a2900003703002003200b3703a8082008103520072006290300370300200320032903a8083703f00541e489c200ad4280808080d00184220b10012208290000210c2006200841086a2900003703002003200c3703a80820081035200420032903a808220c37030020034198036a41086a2209200729030037030020034198036a41106a2212200c37030020034198036a41186a22132006290300370300200320032903f00537039803200320034198036a412010d701200341106a290300210c2003290308210d20032802002108200542003703002004420037030020074200370300200342003703f005200a10012205290000210a2006200541086a2900003703002003200a3703a8082005103520072006290300370300200320032903a8083703f005200b10012205290000210a2006200541086a2900003703002003200a3703a80820051035200420032903a808220a370300200920072903003703002012200a37030020132006290300370300200320032903f005370398032003200c420020081b3703f8052003200d420020081b3703f00520034198036aad4280808080800484200341f0056aad428080808080028410020c010b200342f0f2bda1a7ee9cb9f90037039803200341f0056a20034198036a10e001200341f0056a200b200a10df0120034188066a200a37030020034180066a200b370300200341f8056a41063a00002003410c3a00f00541b0b4cc004100200341f0056a10d4010b200341f0056a41086a410d3a0000200341f9056a20012900003700002003419c066a200236020020034181066a200141086a29000037000020034189066a200141106a29000037000020034191066a200141186a290000370000200341063a00f00541b0b4cc004100200341f0056a10d4012000411510e80420100d010c020b200341f0056a41086a410e3a0000200341f9056a20012900003700002003419c066a200236020020034181066a200141086a29000037000020034189066a200141106a29000037000020034191066a200141186a290000370000200341063a00f00541b0b4cc004100200341f0056a10d4012000411310e8040240200741037122014103460d0020010e03020002020b2010450d010b200f10350b200341d0086a24000bfc0403027f017e057f230041d0006b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541fbf8c400ad4280808080800284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000ba60203027f017e017f230041106b22022400200241003602082002420137030002400240024020002d00004101460d00410110332203450d02200341003a0000200220033602002002428180808010370204200041086a200210a406200235020842208621042002280204452103200228020021000c010b410110332203450d01200341013a000020022003360200200242818080801037020420002d0001210520034101410210372203450d01200320053a00012002200336020020024282808080203702042000280204210520034102410610372200450d01200020053600022002200036020020024286808080e000370204410021034280808080e00021040b200129020020042000ad841002024020030d00200010350b200241106a24000f0b103c000b130020004103360204200041a88dc5003602000b340020004182fec60036020420004100360200200041146a4101360200200041106a41849fc500360200200041086a42073702000b130020004101360204200041aca0c5003602000b3a01017f02404110103322020d001045000b20024200370008200242808084fea6dee111370000200042908080808002370204200020023602000b3400200041a2e8cb0036020420004100360200200041146a4104360200200041106a41c8a1c500360200200041086a42083702000b13002000411d360204200041d8aac5003602000b3400200041d9e3cb0036020420004100360200200041146a410e360200200041106a418c95c600360200200041086a42093702000b4d01027f230041106b220224000240410110332203450d00200341003a0000200041086a4101360200200241013602042002200336020020002002290300370200200241106a24000f0b1045000b7c01017f230041f0006b22022400200241106a4200370300200241186a4200370300200241206a4200370300200241286a4200370300200241306a4200370300200241386a4200370300200241c0006a410036020020024108360204200241086a4200370300200241003a000020002002108005200241f0006a24000b8d1802097f027e230041206b220224002002410036020820024201370300024002400240024020012d00004101460d00410110332203450d032002410136020420022003360200200341003a000020024101360208200141046a28020021042001410c6a2802002203200210770240024020030d0020022802042105200228020821060c010b2004200341306c6a2107200228020421052002280208210603402004280200210802400240200520066b4104490d00200641046a2103200228020021090c010b200641046a22032006490d05200541017422092003200920034b1b220a4100480d050240024020050d000240200a0d00410121090c020b200a103322090d010c080b200228020021092005200a460d0020092005200a10372209450d070b2002200a360204200220093602000b200920066a20083600002002200336020802400240200441086a2d00004101460d00200241003a00100240024020022802042003460d00200228020021050c010b200341016a22052003490d07200341017422062005200620054b1b22064100480d070240024020030d0041002103024020060d00410121050c020b200610332205450d0a0c010b2002280200210520032006460d0020052003200610372205450d090b20022006360204200220053602000b200520036a41003a00002002200341016a22033602082002200441096a2d00004100474107742004410a6a2d00007222063a00100240024020022802042003460d00200228020021050c010b200341016a22052003490d07200341017422092005200920054b1b22094100480d070240024020030d0041002103024020090d00410121050c020b200910332205450d0a0c010b2002280200210520032009460d0020052003200910372205450d090b20022009360204200220053602000b200520036a20063a00002002200341016a2203360208200441106a290300210b2002200441186a2903003703182002200b370310200241106a2109200228020421060c010b200241013a00100240024020022802042003460d00200228020021050c010b200341016a22052003490d06200341017422062005200620054b1b22064100480d060240024020030d0041002103024020060d00410121050c020b200610332205450d090c010b2002280200210520032006460d0020052003200610372205450d080b20022006360204200220053602000b200520036a41013a00002002200341016a2205360208200441186a290300210b200441106a290300210c024002402002280204220920056b4110490d00200341116a210320022802002108200921060c010b200541106a22032005490d06200941017422062003200620034b1b22064100480d060240024020090d00024020060d00410121080c020b200610332208450d090c010b2002280200210820092006460d0020082009200610372208450d080b20022006360204200220083602000b200820056a2205200b3700082005200c37000020022003360208200441206a290300210b2002200441286a2903003703182002200b370310200241106a21090b02400240200620036b4110490d0020022802002108200621050c010b200341106a22052003490d05200641017422082005200820054b1b22054100480d050240024020060d00024020050d00410121080c020b200510332208450d080c010b2002280200210820062005460d0020082006200510372208450d070b20022005360204200220083602000b200820036a22062009290000370000200641086a200941086a2900003700002002200341106a22063602082007200441306a2204470d000b0b200141186a290300210b2001290310210c02400240200520066b4110490d0020022802002103200521040c010b200641106a22032006490d03200541017422042003200420034b1b22044100480d030240024020050d00024020040d00410121030c020b200410332203450d060c010b2002280200210320052004460d0020032005200410372203450d050b20022004360204200220033602000b200320066a2205200b3700082005200c3700002002200641106a2209360208200141286a290300210b200141206a290300210c02400240200420096b410f4d0d00200421050c010b200941106a22052009490d03200441017422082005200820054b1b22054100480d030240024020040d00024020050d00410121030c020b200510332203450d060c010b20042005460d0020032004200510372203450d050b20022005360204200220033602000b200320096a2204200b3700082004200c3700002002200641206a2204360208200141c0006a28020021090240200520046b41034b0d00200441046a22082004490d032005410174220a2008200a20084b1b22084100480d030240024020050d00024020080d00410121030c020b200810332203450d060c010b20052008460d0020032005200810372203450d050b20022008360204200220033602000b200320046a20093600002002200641246a22033602082001290330210b2002200141386a2903003703182002200b370310200241106a21040c010b410110332203450d022002410136020420022003360200200341013a000020024101360208200141306a290300210b200141286a290300210c0240024020022802042205417f6a4110490d0020022802002103200521040c010b200541017422034111200341114b1b22044100480d0220022802002103024020052004460d0020032005200410372203450d040b20022004360204200220033602000b2003200c370001200341096a200b37000020024111360208024002402004416f6a411f4d0d00200421050c010b200441017422054131200541314b1b22054100480d02024020042005460d0020032004200510372203450d040b20022005360204200220033602000b20032001290001370011200341296a200141196a290000370000200341216a200141116a290000370000200341196a200141096a2900003700004131210420024131360208024020012d0021220641064b0d000240024002400240024002400240024020060e0700010203040506000b410021040c060b410121040c050b410221040c040b410321040c030b410421040c020b410521040c010b410621040b200220043a0010024020054131470d002003413141e20010372203450d04200241e200360204200220033602000b200320043a00314132210420024132360208200228020421050b200141c0006a290300210b2001290338210c02400240200520046b4110490d0020022802002103200521060c010b20054101742203200441106a2206200320064b1b22064100480d020240024020050d00200610332203450d050c010b2002280200210320052006460d0020032005200610372203450d040b20022006360204200220033602000b200320046a2205200b3700082005200c3700002002200441106a2209360208200141d0006a290300210b200141c8006a290300210c02400240200620096b410f4d0d00200621050c010b20064101742205200441206a2208200520084b1b22054100480d020240024020060d00200510332203450d050c010b20062005460d0020032006200510372203450d040b20022005360204200220033602000b200320096a2206200b3700082006200c3700002002200441206a2206360208200141e8006a28020021090240200520066b41034b0d0020054101742208200441246a220a2008200a4b1b22084100480d020240024020050d00200810332203450d050c010b20052008460d0020032005200810372203450d040b20022008360204200220033602000b200320066a20093600002002200441246a22033602082001290358210b2002200141e0006a2903003703182002200b370310200241106a21040b024002402002280204220620036b4110490d00200228020021050c010b200341106a22052003490d01200641017422092005200920054b1b22094100480d010240024020060d00024020090d00410121050c020b200910332205450d040c010b2002280200210520062009460d0020052006200910372205450d030b20022009360204200220053602000b200520036a22052004290000370000200541086a200441086a2900003700002002200341106a2203360208200041086a200336020020002002290300370200200241206a24000f0b103e000b103c000b4d01027f230041106b2202240002404104103322030d001045000b2002420437020420022003360200410020021077200041086a200228020836020020002002290300370200200241106a24000b130020004107360204200041ccb0c6003602000b3801017f02404110103322020d001045000b2002420037000820024280a094a58d1d370000200042908080808002370204200020023602000b2e01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241809c313600000b2e01017f02404104103322020d001045000b20004284808080c0003702042000200236020020024180a3053600000b2e01017f02404104103322020d001045000b20004284808080c0003702042000200236020020024180de343600000b340020004189fec60036020420004100360200200041146a4102360200200041106a41acbbc600360200200041086a42093702000bfc0f030b7f017e017f230041106b2202240020024100360208200242013703000240024002402001280200220341044b0d000240024002400240024020030e050001020304000b410110332203450d062002410136020420022003360200200341013a000020024101360208200128020421042001410c6a2802002203200210770240024020030d00200228020821030c010b2004200341286c6a21054100200228020822066b2107410021030340200620036a2108024002402007200228020422096a4120490d002002280200210a2009210b0c010b200841206a220a2008490d082009410174220b200a200b200a4b1b220b4100480d080240024020090d000240200b0d004101210a0c020b200b1033220a0d010c0b0b2002280200210a2009200b460d00200a2009200b1037220a450d0a0b2002200b3602042002200a3602000b200a20066a20036a220c200420036a2209290000370000200c41186a200941186a290000370000200c41106a200941106a290000370000200c41086a200941086a2900003700002002200841206a220c360208200941206a290300210d0240200b20076a41606a41074b0d00200c41086a220e200c490d08200b410174220c200e200c200e4b1b220c4100480d0802400240200b0d000240200c0d004101210a0c020b200c1033220a450d0b0c010b200b200c460d00200a200b200c1037220a450d0a0b2002200c3602042002200a3602000b200a20066a20036a41206a200d3700002002200841286a360208200741586a2107200341286a21032005200941286a470d000b200620036a21030b200141106a280200210b024002402002280204220a20036b4104490d00200228020021090c010b200341046a22092003490d06200a41017422072009200720094b1b22074100480d0602400240200a0d00024020070d00410121090c020b200710332209450d090c010b20022802002109200a2007460d002009200a200710372209450d080b20022007360204200220093602000b200920036a200b3600002002200341046a3602080c040b410110332203450d052002410136020420022003360200200341023a0000200241013602082001280204210a0240024020022802042209417f6a4104490d00200228020021030c010b200941017422034105200341054b1b220b4100480d052002280200210302402009200b460d0020032009200b10372203450d070b2002200b360204200220033602000b2003200a3600012002410536020820012802082103200141106a2802002209200210770240024020090d002002280208210b0c010b2003200941286c6a210c2002280208210b03400240024020022802042208200b6b4120490d00200b41206a21092002280200210a200821070c010b200b41206a2209200b490d072008410174220a2009200a20094b1b22074100480d070240024020080d00024020070d004101210a0c020b20071033220a450d0a0c010b2002280200210a20082007460d00200a200820071037220a450d090b200220073602042002200a3602000b200a200b6a220b2003290000370000200b41186a200341186a290000370000200b41106a200341106a290000370000200b41086a200341086a29000037000020022009360208200341206a290300210d0240200720096b41074b0d00200941086a220b2009490d0720074101742208200b2008200b4b1b220b4100480d070240024020070d000240200b0d004101210a0c020b200b1033220a450d0a0c010b2007200b460d00200a2007200b1037220a450d090b2002200b3602042002200a3602000b200a20096a200d3700002002200941086a220b360208200c200341286a2203470d000b0b200141146a280200210a0240024020022802042209200b6b4104490d00200228020021030c010b200b41046a2203200b490d05200941017422072003200720034b1b22074100480d050240024020090d00024020070d00410121030c020b200710332203450d080c010b2002280200210320092007460d0020032009200710372203450d070b20022007360204200220033602000b2003200b6a200a3600002002200b41046a3602080c030b410110332203450d042002410136020420022003360200200341033a000020024101360208200141086a290300210d0240024020022802042209417f6a4108490d00200228020021030c010b200941017422034109200341094b1b220a4100480d042002280200210302402009200a460d0020032009200a10372203450d060b2002200a360204200220033602000b2003200d370001200241093602080c020b410110332203450d032002410136020420022003360200200341043a0000200241013602082001280204210a0240024020022802042209417f6a4104490d00200228020021030c010b200941017422034105200341054b1b220b4100480d032002280200210302402009200b460d0020032009200b10372203450d050b2002200b360204200220033602000b2003200a360001200241053602080c010b410110332203450d022002410136020420022003360200200341053a0000200241013602082001280204210a0240024020022802042209417f6a4104490d00200228020021030c010b200941017422034105200341054b1b220b4100480d022002280200210302402009200b460d0020032009200b10372203450d040b2002200b360204200220033602000b2003200a360001200241053602080b20002002290300370200200041086a200241086a280200360200200241106a24000f0b103e000b103c000bb70905037f017e027f047e017f230041a0026b22022400200241c8006a2001108a052002280248210320022002280250220436028c022002200336028802200241f8006a2004ad4220862003ad84100510c20102400240200228027822040d00420021050c010b200228027c2106024002400240200241f8006a41086a28020022074110490d0020074170714110460d002007417c714120470d010b20024100360260200242013703582002410936029402200220024188026a360290022002200241d8006a36029c022002419c016a41013602002002420137028c01200241c888c20036028801200220024190026a360298012002419c026a41e88ac50020024188016a10431a200235026042208620023502588410060240200228025c450d00200228025810350b420021050c010b200441086a290000210820042900002109200441186a290000210a2004290010210b20042800202107420121050b2006450d00200410350b0240200228024c450d00200310350b02400240024002402005500d0020024188016a41186a420037030020024188016a41106a2206420037030020024188016a41086a22034200370300200242003703880141d1c4c700ad4280808080e000841001220429000021052003200441086a29000037030020022005370388012004103541e7c4c700ad4280808080e00084100122042900002105200241f8006a41086a220c200441086a2900003703002002200537037820041035200620022903782205370300200241d8006a41086a2003290300370300200241d8006a41106a2005370300200241d8006a41186a200c2903003703002002200229038801370358200241306a200241d8006a412010c001200241106a200a420041002002280234410020022802301b220320076b2204200420034b1bad22054200108408200241206a20054200200b4200108408200242004200200b42001084082002290308200229031884420052200241206a41086a2903002205200229030020022903107c7c220b200554720d0142002009200229032022057d220a200a2009562008200b7d2009200554ad7d220520085620052008511b22031b220b4200200520031b220584500d01200242f6cacda397cddbb320370340200241c0006a2001200b20054106109002200241c0016a2005370300200241b8016a200b37030020024188016a41086a41003a000020024191016a200129000037000020024199016a200141086a290000370000200241a1016a200141106a290000370000200241a9016a200141186a290000370000200241143a00880120024188016a21010c020b20004183363b0100200041086a410a360200200041046a41c1efc400360200200041026a41003a00000c020b200242f6cacda397cddbb320370338200241386a200110920220024188016a2001108a052002350290014220862002280288012203ad8410070240200228028c01450d00200310350b20024188016a41086a41013a000020024191016a200129000037000020024199016a200141086a290000370000200241a1016a200141106a290000370000200241a9016a200141186a290000370000200241143a00880120024188016a21010b41b0b4cc004100200110d401200041043a00000b200241a0026a24000bbc0505017f017e017f017e047f230041d0006b220224004182fec600ad4280808080f000842203100122042900002105200241086a200441086a29000037030020022005370300200410352003100122042900002103200241106a41086a200441086a29000037030020022003370310200410350240024002400240412010332204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a2900003700002004ad4280808080800484100422012900002103200241306a41086a200141086a2900003703002002200337033020011035200241cc006a200441206a360200200220043602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200410352002280228220641206a2201417f4c0d01200228022021070240024020010d0041002108410121040c010b200110332204450d01200121080b024002402008410f4d0d00200821090c010b200841017422094110200941104b1b22094100480d03024020080d002009103322040d010c050b20082009460d0020042008200910372204450d040b20042002290300370000200441086a200241086a2903003700000240024020094170714110460d00200921080c010b200941017422084120200841204b1b22084100480d0320092008460d0020042009200810372204450d040b20042002290310370010200441186a200241106a41086a29030037000002400240200841606a2006490d00200821090c010b2006415f4b0d03200841017422092001200920014b1b22094100480d0320082009460d0020042008200910372204450d040b200441206a20072006109d081a20002001360208200020093602042000200436020002402002280224450d00200710350b200241d0006a24000f0b1045000b1044000b103e000b103c000be9800205027f037e117f057e0c7f23002203210420034180086b4160712203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e1e000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d000b20034194036a41013602002003420137028403200341e8d4ca0036028003200341043602c4052003419cd5ca003602c0052003200341c0056a3602900320034180036a41b0b4cc00104c000b200141306a2903002105200141286a290300210620034180026a41186a200141196a29000037030020034180026a41106a200141116a29000037030020034180026a41086a200141096a29000037030020032001290001370380022002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109024020022d0000450d00200320073702e407200320013a00e307200320083a00e207200320093b01e0070c500b200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820022d00012102200320073703e007200241ff01714101470d4f200320073703e006200320013a00df06200320083a00de06200320093b01dc062003200a3a00db062003200b3a00da062003200c3b01d8062003200d3a00d7062003200e3a00d6062003200f3b01d406200320103a00d306200320113a00d206200320123b01d006200320133a00cf06200320143a00ce06200320153b01cc06200320163a00cb06200320173a00ca06200320183b01c8060240200642808084fea6dee1115441002005501b0d00200320063703c001200320053703c8012003200341c8066a3602e0072003200341c8066a36028801200320034188016a360288032003200341e0076a360284032003200341c0016a36028003200341c0056a200341c8066a20034180036a108c030240024020032802c0054101470d0020032f00c50520032d00c705411074722101200341c8056a290300210720032d00c40521020c010b410421020240200341c0056a41086a2903004201520d00200341c0056a41106a29030021072003280288012101200341b8036a200341c0056a41186a290300370300200341b0036a200737030020034180036a41086a41003a000020034189036a200129000037000020034191036a200141086a29000037000020034199036a200141106a290000370000200341a1036a200141186a290000370000200341033a00800341b0b4cc00410020034180036a10d4010b0b0240200241ff01714104470d0041d9e3cb00ad428080808090018422071001220229000021192002290008211a2002103541bbe3cb00ad4280808080f00184221b10012202290000211c2002290008211d200210352003201d3701d8012003201c3701d0012003201a3701c801200320193701c001200341106a200341c0016a412010c001200328021421012003280210210820071001220229000021072002290008211920021035201b10012202290000211a2002290008211b200210352003201b3701d8012003201a3701d001200320193701c801200320073701c00120032001410020081b220841016a36028003200341c0016aad4280808080800484220720034180036aad4280808080c0008410022003200341c8066a3602c001200341c0056a200810ed0420033502c805211920032802c005210c411810332202450d4f2002200637000020022005370008200342988080808002370284032003200236028003410120034180036a107720032802c0012102200328028003210102400240200328028403220a20032802880322096b411f4d0d00200a210b0c010b200941206a220b2009490d3f200a410174220d200b200d200b4b1b220b4100480d3f0240200a0d000240200b0d00410121010c020b200b103322010d010c520b200a200b460d002001200a200b10372201450d510b200120096a220a2002290000370000200a41186a200241186a290000370000200a41106a200241106a290000370000200a41086a200241086a2900003700002019422086200cad84200941206aad4220862001ad8410020240200b450d00200110350b024020032802c405450d00200c10350b200341cc056a20034180026a41086a290300370200200341d4056a20034180026a41106a290300370200200341dc056a20034180026a41186a290300370200200341ec056a200341c8066a41086a290300370200200341f4056a200341c8066a41106a290300370200200341fc056a200341c8066a41186a290300370200200320083602c00520032003290380023702c405200320032903c8063702e4052003200341c0056a3602ac0141d9e3cb00ad42808080809001841001220229000021192002290008211a2002103541918dc500ad4280808080b0018410012202290000211b2002290008211c200210352003201c3701d8012003201b3701d0012003201a3701c801200320193701c00120034188016a2007100510c201024002402003280288010d00410410332202450d5120034204370284032003200236028003410020034180036a1077200341b8016a20032802880336020020032003290380033703b0010c010b200341b0016a41086a20034188016a41086a28020036020020032003290388013703b0010b200341b8076a41086a200341b0016a41086a2802002202360200200320032903b0013703b807024002402002450d0020034180036a20032802b80722012002410110f1042003280280034101470d0120032802bc07450d4e200110350c4e0b4101200341b8076a107720032802ac01200341b8076a108c050c4b0b200328028403210a02402003418c036a280200220120034180036a41086a2802002209460d002002200120096b6a220241046a220b417f4c0d4002400240200b0d004100210b4101210c0c010b200b1033220c450d510b2003200c3602c8072003200b3602cc07200320023602d0072003200341c8076a36028003200a20034180036a200110f20420022001490d1f20032802d007220a2002490d2020032802c007220a2009490d2120032802c807210b20032802b807210c2003200220016b22023602d8072003200a20096b220a3602dc072002200a470d22200b20016a200c20096a2002109d081a20032802ac01200341c8076a108c0520032802d007210120032802cc07210920032802c807210220032802bc07450d4c20032802b80710350c4c0b2003200341b8076a36028003200a20034180036a200910f20420032802ac01200341b8076a108c050c4a0b2003200737027c200320023a0078200320013b0079200320014110763a007b0c510b200341f8006a410110e80420032d00784104460d4c200329027c21070c500b200141046a280200211e2002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d00200320073702e407200320013a00e307200320083a00e207200320093b01e007410121020c010b20022d00012102200320073703e007200241ff017141014721020b200320073701d801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320133a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c001024002400240024020020d0020034180026a41186a200341c0016a41186a29010037030020034180026a41106a200341c0016a41106a29010037030020034180026a41086a200341c0016a41086a290100370300200320032901c00137038002200341c0016a201e10ed0420034180036a20032802c001220120032802c80110cc02200341c0056a41086a22082003419c036a28020036020020032003290294033703c00502402003280290032202450d0020034180036a41086a2903002107200329038003210520034188016a41086a2008280200360200200320032903c00537038801024020032802c401450d00200110350b200341dc066a200329038801370200200341e4066a20034190016a280200360200200320053703c806200320023602d806200320073703d006200320073703c801200320053703c001200320034180026a3602e007024020052007844200510d00200320034180026a36028801200320034188016a360288032003200341e0076a360284032003200341c0016a36028003200341c0056a20034180026a20034180036a108c030240024020032802c0054101470d0020032f00c50520032d00c705411074722108200341c8056a290300210720032d00c40521010c010b410421010240200341c0056a41086a2903004201520d00200341c0056a41106a29030021072003280288012108200341b8036a200341c0056a41186a290300370300200341b0036a200737030020034180036a41086a41003a000020034189036a200829000037000020034191036a200841086a29000037000020034199036a200841106a290000370000200341a1036a200841186a290000370000200341033a00800341b0b4cc00410020034180036a10d4010b0b200141ff01714104470d030b200329039802210720032d009702210820032d009602210920032f019402210a20032d009302210b20032d009202210c20032f019002210d20032d008f02210e20032d008e02210f20032f018c02211020032d008b02211120032d008a02211220032f018802211320032d008702211420032d008602211520032f018402211620032d008302211720032d008202211820032f018002211f0240200341c8066a41186a280200220120032802dc06470d00200341d8066a20014101108a0120032802d806210220032802e00621010b200220014105746a22022007370018200220083a0017200220093a00162002200a3b00142002200b3a00132002200c3a00122002200d3b00102002200e3a000f2002200f3a000e200220103b000c200220113a000b200220123a000a200220133b0008200220143a0007200220153a0006200220163b0004200220173a0003200220183a00022002201f3b00002003200141016a3602e00620034180036a41186a20032903e00637030020034180036a41106a200341c8066a41106a29030037030020034180036a41086a200341c8066a41086a290300370300200320032903c80637038003200341c0056a201e10ed0420032802c0052102200320032802c8053602c401200320023602c00120034180036a200341c0016a108d03024020032802c405450d00200210350b024020034194036a28020041ffffff3f71450d0020032802900310350b200341043a00c8070c500b024020032802c401450d00200110350b200341c8076a410210e80420032d00c8074104460d4f0c020b200341023a00c8070c020b200320073702cc07200320013a00c807200320083b00c907200320084110763a00cb0720032802dc0641ffffff3f71450d00200210350b20032902cc0721070b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c500b200141046a2802002108200341c0056a41206a200141286a290300370300200341c0056a41186a200141206a290300370300200341c0056a41106a200141186a290300370300200341c0056a41086a200141106a2903003703002003200141086a2903003703c0050240024002400240024020022d00000d0020022d000141ff01714101460d010b200341023a0080020c010b200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211e20032002411a6a2901003703e006200320013a00df06200320093a00de062003200a3b01dc062003200b3a00db062003200c3a00da062003200d3b01d8062003200e3a00d7062003200f3a00d606200320103b01d406200320113a00d306200320123a00d206200320133b01d006200320143a00cf06200320153a00ce06200320163b01cc06200320173a00cb06200320183a00ca062003201e3b01c80620034180036a41206a200341c0056a41206a29030037030020034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c0053703800320034180026a200341c8066a200820034180036a108d0520032d0080024104460d0120032902840221070b20032802800221032000411c6a2007370200200041186a2003360200420121070c010b420021070b200042003703080c4f0b200141046a2802002108200341c0056a41206a200141286a290300370300200341c0056a41186a200141206a290300370300200341c0056a41106a200141186a290300370300200341c0056a41086a200141106a2903003703002003200141086a2903003703c00520022d00000d1d20022d000141ff01714101470d1d2002411a6a2901002107200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c0012003200e3a00cf012003200f3a00ce01200320103b01cc01200320113a00cb01200320123a00ca01200320133b01c801200320013a00d701200320093a00d6012003200a3b01d4012003200b3a00d3012003200c3a00d2012003200d3b01d001200320073701d801200341c8066a41186a2007370300200341c8066a41106a20032901d001370300200341c8066a41086a20032901c801370300200320032901c0013703c80620034180036a200341c8066a108e050240024020032d00800322024102460d0020024101470d0020034180036a41186a2d0000210220034197036a2d0000210120034195036a2f0000210920034194036a2d0000210a20034193036a2d0000210b20034191036a2f0000210c20034180036a41106a2d0000210d2003418f036a2d0000210e2003418d036a2f0000210f2003418c036a2d000021102003418b036a2d0000211120034189036a2f0000211220034180036a41086a2d0000211320032d008703211420032f008503211520032d008403211620032d008303211720032d008203211820032d008103211e200320034199036a29000037039802200320023a009702200320013a009602200320093b0194022003200a3a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008602200320153b018402200320163a008302200320173a008202200320183a0081022003201e3a00800220034180036a41206a200341c0056a41206a29030037030020034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c0053703800320034188016a20034180026a200820034180036a108d050c010b20034188016a410310e8040b024020032d0088014104460d00200329028c0121070c440b420021070c440b0240024020022d0000417f6a220841024b0d00200141046a2802002101024020080e03000102000b200241046a2d00000d00200241086a28020041036c2002410c6a2802004101744f0d010b200341023a00e0070c420b20034188016a200110f50420034180036a200328028801220820032802900110b30220032d0080032102200341c0056a20034180036a41017241e700109d081a0240024020024102460d00200341c8066a200341c0056a41e700109d081a0240200328028c01450d00200810350b20034180036a200341c8066a41e700109d081a2002450d0120034180026a411410e8040c410b0240200328028c01450d00200810350b20034180026a411410e8040c400b20034184026a20034187036a41e000109d081a20032f01bc02210220032d00be02210820032d00bf02210920032f01c002210a20032d00c202210b20032d00c302210c20032f01c402210d20032d00c602210e20032d00c702210f20032f01c802211020032d00ca02211120032d00cb02211220032f01cc02211320032d00ce02211420032d00cf02211520032f01d002211620032d00d202211720032d00d3022118200320032902d402220737039803200320183a009703200320173a009603200320163b019403200320153a009303200320143a009203200320133b019003200320123a008f03200320113a008e03200320103b018c032003200f3a008b032003200e3a008a032003200d3b0188032003200c3a0087032003200b3a0086032003200a3b018403200320093a008303200320083a008203200320023b018003200341c0056a20034180036a108f05200341186a20032802c005221f20032802c80541b0b4cc0041004100108a022003280218211e024020032802c405450d00201f10350b0240201e4101460d002003200737039803200320183a009703200320173a009603200320163b019403200320153a009303200320143a009203200320133b019003200320123a008f03200320113a008e03200320103b018c032003200f3a008b032003200e3a008a032003200d3b0188032003200c3a0087032003200b3a0086032003200a3b018403200320093a008303200320083a008203200320023b018003200341c0056a20034180036a108f0520032802c005210220033502c8052107200341013a00800320074220862002ad8420034180036aad428080808010841002024020032802c405450d00200210350b2003418c036a200136020020034188036a41063a0000200341063a00800341b0b4cc00410020034180036a10d40120034180036a200110f5042003350288034220862003280280032202ad8410070240200328028403450d00200210350b200341043a00e0070c490b200341e0076a410510e8040c400b200341d8056a200141196a290000370300200341d0056a200141116a290000370300200341c8056a200141096a290000370300200320012900013703c00502400240024020022d0000417f6a220141024b0d00024020010e03000102000b200241086a2802004101742002410c6a280200490d00200241046a28020041ff0171450d010b200341023a0080020c010b41d9e3cb00ad4280808080900184221a1001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341286a200341c0016a412041b0b4cc0041004100108a020240024020032802284101460d0020034180036a41186a2201200341c0056a41186a29030037030020034180036a41106a2208200341c0056a41106a29030037030020034180036a41086a2209200341c0056a41086a290300370300200320032903c00537038003201a100122022d000f210a20022d000e210b20022f000c210c20022d000b210d20022d000a210e20022f0008210f20022d0007211020022d0006211120022f0004211220022d0003211320022d0002211420022f000021152002103541b8a3c600ad428080808090018410012202290008210720022d0007211620022d0006211720022f0004211820022d0003211e20022d0002211f20022f0000212020021035412010332202450d4b2002200329038003370000200241186a2001290300370000200241106a2008290300370000200241086a2009290300370000412010332201450d4b20012002290000370000200141186a2208200241186a290000370000200141106a2209200241106a290000370000200141086a2221200241086a2900003700002002103541c00010332202450d4b20022007370018200220163a0017200220173a0016200220183b00142002201e3a00132002201f3a0012200220203b00102002200a3a000f2002200b3a000e2002200c3b000c2002200d3a000b2002200e3a000a2002200f3b0008200220103a0007200220113a0006200220123b0004200220133a0003200220143a0002200220153b0000200241386a2008290000370000200241306a2009290000370000200241286a2021290000370000200220012900003700202001103520034180036a200241c00010cd022003280280032109200329038803210720032802840321012002103502402001450d0020034180036a41186a420037030020034180036a41106a220a420037030020034180036a41086a22024200370300200342003703800341d1c4c700ad4280808080e000841001220829000021052002200841086a29000037030020032005370380032008103541e7c4c700ad4280808080e00084100122082900002105200341e0076a41086a220b200841086a290000370300200320053703e00720081035200a20032903e0072205370300200341c8066a41086a2002290300370300200341c8066a41106a2005370300200341c8066a41186a200b29030037030020032003290380033703c806200341206a200341c8066a412010c00102402003280224410020032802201b20094f0d0020034180026a410710e804200742ffffff3f83500d03200110350c030b200742ffffff3f83500d00200110350b20034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c00537038003200341003a00a00341d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341203602cc062003200341c0016a3602c80620034180036a200341c8066a109005200341043a0080020c4a0b20034180026a410610e8040b20032d0080024104460d4820032902840221070b20032802800221032000411c6a2007370200200041186a200336020020004200370308420121070c4c0b200341c0056a41186a200141196a290000370300200341d0056a200141116a290000370300200341c0056a41086a200141096a290000370300200320012900013703c0050240024020022d0000417f6a220141024b0d00024020010e03000102000b200241046a2d00000d00200241086a2802004102742002410c6a28020041036c4f0d010b20004200370308200041186a4102360200420121070c4c0b20034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c00537038003200341023a00a00341d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341203602cc062003200341c0016a3602c80620034180036a200341c8066a1090050c460b200341c0056a41186a200141196a290000370300200341d0056a200141116a290000370300200341c8056a200141096a290000370300200320012900013703c0050240024020022d0000417f6a220141024b0d00024020010e03000102000b200241086a2802002002410c6a280200490d00200241046a28020041ff0171450d010b20004200370308200041186a4102360200420121070c4b0b20034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c00537038003200341013a00a00341d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341203602cc062003200341c0016a3602c80620034180036a200341c8066a1090050c450b200141286a280200210d200141246a280200210820034188016a41086a220a2002411c6a2800003602002003200241146a290000370388012002410c6a280000210b200241086a280000210c200241046a280000210920022d0000210220034198026a200141196a29000037030020034190026a200141116a29000037030020034180026a41086a200141096a29000037030020032001290001370380020240024020084180a305490d00200341e0076a41086a200a28020036020020032003290388013703e00720024102470d01200941ff01710d3941002109200c41036c200b4101744f0d3a0c380b2002417e6a220241014b0d3820020e023739370b20024103470d370c380b20034198026a200141196a29000037030020034180026a41106a200141116a29000037030020034180026a41086a200141096a290000370300200320012900013703800220022d00004102470d18200241236a2d00002108200241216a2f000021092002411f6a2d0000210a2002411d6a2f0000210b2002410f6a2d0000210c2002410d6a2f0000210d2002410b6a2d0000210e200241096a2f0000210f200241076a2d00002110200241056a2f00002111200241246a2802002112200241206a2d00002113200241116a2900002107200241106a2d000021142002410c6a2d00002115200241086a2d00002116200241046a2d000021012003200241196a2800003602e807200320073703e00720014101470d182003200920084110747222023b01dc05200341de056a20024110763a00002003200b200a4110747222023b01d805200341da056a20024110763a00002003200d200c4110747222023b01c805200341c0056a410a6a20024110763a000020032007a722023b01cc05200341ce056a20024110763a0000200320123a00df05200320133a00db05200320032902e4073703d005200320143a00cb05200320153a00c705200320163a00c305200320074218883c00cf052003200f200e4110747222023b01c405200320024110763a00c6052003201120104110747222023b01c005200320024110763a00c20541d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c00120034180036a200341c0016a10c00202400240024020032d00a0034103460d0020032903800321072003290388032105200329039003210620032003290398033703980320032006370390032003200537038803200320073703800320034180026a20034180036a412010a008450d01200341c8076a410210e8040c020b200341c8076a410a10e8040c010b200341c8066a20034180026a10910520034180036a20032802c806220220032802d00610cd022003290388032107200328028403210e024020032802cc06450d00200210350b0240200e0d004100210f200341003602900120034201370388014101210e0c330b2003200e360288012003200737028c012007a7210f41002102024002402007422088a7220a41014b0d00200a0e023401340b200a210103402001410176220820026a22092002200e20094105746a200341c0056a412010a0084101481b2102200120086b220141014b0d000b0b0240200e20024105746a200341c0056a412010a0082201450d0020034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c005370380032001411f7620026a2208200a4b0d1b20034180036a21010c340b200341c8076a410b10e804200f41ffffff3f71450d00200e10350b20032d00c8074104460d4320032902cc0721070c300b20022d000120022d0000410047720d192003418c036a200141046a280200220236020020034188036a41063a0000200341063a00800341b0b4cc00410020034180036a10d40120034180036a200210f5042003350288034220862003280280032202ad841007200328028403450d42200210350c420b20022d000120022d0000410047720d19200141046a2802002102410c10332201450d4220012002360008200142e4cab5fbb6ccdcb0e3003700004189fec600ad4280808080900184100122022900002107200341c8066a41086a200241086a290000370300200320073703c8062002103541b489c500ad4280808080e00084100122022900002107200341c0056a41086a200241086a290000370300200320073703c00520021035411010332202450d4220034210370284032003200236028003410c20034180036a107702400240200328028403220a20032802880322086b410c490d002003280280032102200a21090c010b2008410c6a22022008490d32200a41017422092002200920024b1b22094100480d3202400240200a0d00024020090d00410121020c020b200910332202450d460c010b2003280280032102200a2009460d002002200a200910372202450d450b200320093602840320032002360280030b200220086a220a2001290000370000200a41086a200141086a28000036000020032008410c6a2208ad4220862002ad841003220a29000037038801200a103520034180036a410c6a200220086a3602002003200236028803200320034188016a41086a36028403200320034188016a3602800320034180026a20034180036a107b02402009450d00200210350b200328028802220b41206a2208417f4c0d32200328028002210c0240024020080d0041002109410121020c010b200810332202450d43200821090b024002402009410f4d0d002009210a0c010b2009410174220a4110200a41104b1b220a4100480d32024020090d00200a10332202450d450c010b2009200a460d0020022009200a10372202450d440b200220032903c806370000200241086a200341c8066a41086a29030037000002400240200a4170714110460d00200a21090c010b200a41017422094120200941204b1b22094100480d32200a2009460d002002200a200910372202450d440b200220032903c005370010200241186a200341c0056a41086a29030037000002400240200941606a200b490d002009210a0c010b200b415f4b0d322009410174220a2008200a20084b1b220a4100480d322009200a460d0020022009200a10372202450d440b200241206a200c200b109d081a0240200328028402450d00200c10350b20034180036a2002200810da0141012109024002402003280280034101460d00410021090c010b2008ad4220862002ad84100720032902840321070b0240200a450d00200210350b2001103502402009450d00200341c8066a2007a710c90420034180036a20032802c806220a20032802d006220110b8022003280280032202410820021b210902402007422088a72208200329028403420020021b2207422088a722024f0d002009200841d0026c6a220b450d002009200841d0026c6a220141bc026a210a024020012802bc024102460d00024020012802b002220c450d002009200841d0026c6a41b4026a280200450d00200c10350b200b10ba020b200b20034180036a41bc02109d081a200a4102360200200141c8026a200341c8056a290300370300200120032903c0053703c00220032802d006210120032802c806210a0b0240024020090d002001ad422086200aad8410070c010b20034180036a2009200210d9042001ad422086200aad842003350288034220862003280280032201ad8410020240200328028403450d00200110350b02402002450d00200241d0026c21012009210203400240200241bc026a2802004102460d000240200241b0026a2802002208450d00200241b4026a280200450d00200810350b200210bb020b200241d0026a2102200141b07d6a22010d000b0b2007a72202450d00200241d0026c450d00200910350b024020032802cc06450d00200a10350b200341043a00c0010c420b200341c0016a410210e80420032d00c0014104460d4120032902c40121070c2d0b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a29000037030020032001290001370388012002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d00200320073702e407200320013a00e307200320083a00e207200320093b01e007410121020c010b20022d00012102200320073703e007200241ff017141014721020b200320073701d801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320133a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c00120020d19200341c0016a20034188016a10920520034180036a20032802c001221e20032802c801222010c402200341a0036a2d000021020240024020032d008003221f4102470d00200341023a0080020c010b200320032d0083033a008302200320032f0081033b0081022003200329028403370284022003201f3a008002200320034198036a2903003703980220032003418c036a29020037028c02200320034194036a280200360294020b200320013a00df06200320083a00de06200320093b01dc062003200a3a00db062003200b3a00da062003200c3b01d8062003200d3a00d7062003200e3a00d6062003200f3b01d406200320103a00d306200320113a00d206200320123b01d006200320133a00cf06200320143a00ce06200320153b01cc06200320163a00cb06200320173a00ca06200320183b01c806200320073703e00620034198036a20032903980237030020034180036a41206a20023a0000200341023a00c0052003200329039002370390032003200329038802370388032003200329038002220537038003200320032903d80537039802200320032903d00537039002200320032903c80537038802200320032903c00537038002024002402005a7410371417f6a220141014b0d0041192102024020010e020002000b410c21020c010b411a210220034180036a410172200341c8066a412010a0080d00200320032903c80637008102200341013a0080022003200341df066a290000370098022003200341d8066a290300370091022003200341d0066a290300370089022003200329039802370398032003200329039002370390032003200329038802370388032003200329038002220537038003024002402005a7220241ff01714102470d002020ad422086201ead8410070c010b410110332201450d44200120023a000020014101412110372202450d44200220032900810337000120022007423888a73a0020200241186a200329009803370000200241116a200329009103370000200241096a2003290089033700002020ad422086201ead842002ad42808080809004841002200210350b412621020b024020032802c401450d00201e10350b024020024126470d00200341043a00c8070c410b200341c8076a200210e80420032d00c8074104460d4020032902cc0721070c2b0b20022d00000d1920022d000141ff01714101470d19200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820032002411a6a2901003703d805200320013a00d705200320083a00d605200320093b01d4052003200a3a00d3052003200b3a00d2052003200c3b01d0052003200d3a00cf052003200e3a00ce052003200f3b01cc05200320103a00cb05200320113a00ca05200320123b01c805200320133a00c705200320143a00c605200320153b01c405200320163a00c305200320173a00c205200320183b01c005200341c8066a200341c0056a10920520034180036a20032802c806220220032802d006220110c402024020032d0080034102460d00200341c0056a1099020b2001ad4220862002ad84100720032802cc06450d3f200210350c3f0b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a29000037030020032001290001370388012002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d00200320073702e407200320013a00e307200320083a00e207200320093b01e007410121020c010b20022d00012102200320073703e007200241ff017141014721020b200320073701d801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320133a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c00120020d19200341c0016a20034188016a10920520034180036a20032802c001221e20032802c801222010c402200341a0036a2d000021020240024020032d008003221f4102470d00200341023a0080020c010b200320032d0083033a008302200320032f0081033b0081022003200329028403370284022003201f3a008002200320034198036a2903003703980220032003418c036a29020037028c02200320034194036a280200360294020b200320013a00df06200320083a00de06200320093b01dc062003200a3a00db062003200b3a00da062003200c3b01d8062003200d3a00d7062003200e3a00d6062003200f3b01d406200320103a00d306200320113a00d206200320123b01d006200320133a00cf06200320143a00ce06200320153b01cc06200320163a00cb06200320173a00ca06200320183b01c806200320073703e00620034198036a20032903980237030020034180036a41206a20023a0000200341023a00c0052003200329039002370390032003200329038802370388032003200329038002220537038003200320032903d80537039802200320032903d00537039002200320032903c80537038802200320032903c00537038002411b210202402005a741ff01714101470d00410d210220034180036a410172200341c8066a412010a0080d00200320032903c80637008102200341003a0080022003200341df066a290000370098022003200341d8066a290300370091022003200341d0066a290300370089022003200329039802370398032003200329039002370390032003200329038802370388032003200329038002220537038003024002402005a7220241ff01714102470d002020ad422086201ead8410070c010b410110332201450d42200120023a000020014101412110372202450d42200220032900810337000120022007423888a73a0020200241186a200329009803370000200241116a200329009103370000200241096a2003290089033700002020ad422086201ead842002ad42808080809004841002200210350b412621020b024020032802c401450d00201e10350b024020024126470d00200341043a00c8070c3f0b200341c8076a200210e80420032d00c8074104460d3e20032902cc0721070c280b200141306a2903002107200141286a2903002105200141216a2d00002108200341c8066a41186a200141196a290000370300200341c8066a41106a200141116a290000370300200341c8066a41086a200141096a290000370300200320012900013703c8060240024020022d00000d0020022d000141ff01714101470d002002411a6a2901002106200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c0012003200e3a00cf012003200f3a00ce01200320103b01cc01200320113a00cb01200320123a00ca01200320133b01c801200320013a00d701200320093a00d6012003200a3b01d4012003200b3a00d3012003200c3a00d2012003200d3b01d001200320063701d801200341c0056a41186a2006370300200341c0056a41106a20032901d001370300200341c0056a41086a20032901c801370300200320032901c0013703c00520034180036a41186a200341c8066a41186a29030037030020034180036a41106a200341c8066a41106a29030037030020034180036a41086a200341c8066a41086a290300370300200320032903c8063703800320034180026a200341c0056a20034180036a20082005200710930520032d00800222024104460d3f20032f00810220032d00830241107472210120032902840221070c010b410221020b200042003703082000411c6a2007370200200041186a2001410874200272360200420121070c420b0240024020022d00000d0020022d000141ff01714101470d002002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172003200241096a2d00003a00c701200320133a00c601200320143b01c401200320153a00c301200320163a00c201200320173b01c0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d001200320073701d80120034198036a200737030020034180036a41106a20032901d00137030020034188036a20032901c801370300200320032901c00137038003200341c0056a20034180036a10940520032d00c00522024104460d3e20032f00c10520032d00c30541107472210120032902c40521070c010b410221020b200042003703082000411c6a2007370200200041186a2001410874200272360200420121070c410b024020022d000120022d000041004772450d0020004200370308200041186a4102360200420121070c410b41d9e3cb00ad4280808080900184100122022900002107200229000821052002103541918dc500ad4280808080b001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341c0016aad428080808080048410070c3b0b200141086a2802002108200141046a280200210920022d00000d1620022d000141ff01714101470d162001410c6a2802002101200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211e200241046a2d0000211f200241026a2f0100212020032002411a6a2901003703d8012003200a3a00d7012003200b3a00d6012003200c3b01d4012003200d3a00d3012003200e3a00d2012003200f3b01d001200320103a00cf01200320113a00ce01200320123b01cc01200320133a00cb01200320143a00ca01200320153b01c801200320163a00c701200320173a00c601200320183b01c4012003201e3a00c3012003201f3a00c201200320203b01c0012001ad22194220862009ad84100922022900002107200241086a2900002105200241106a290000210620034180026a41186a200241186a29000037030020034180026a41106a200637030020034180026a41086a200537030020032007370380022002103520034180036a20034180026a10ee04200341d8006a200328028003220a20032802880341b0b4cc0041004100108a02200328025821020240200328028403450d00200a10350b20024101460d17200341c8006a201942004280a094a58d1d42001084082003200341d0006a29030022073703d0062003200329034822053703c8062003200341c0016a3602c807024002402001450d002003200341c0016a3602e0072003200341e0076a360288032003200341c8076a360284032003200341c8066a36028003200341c0056a200341c0016a20034180036a108c030240024020032802c0054101470d0020032f00c50520032d00c70541107472210a200341c8056a290300210620032d00c40521020c010b410421020240200341c0056a41086a2903004201520d00200341c0056a41106a290300210620032802e007210a200341b8036a200341c0056a41186a290300370300200341b0036a200637030020034180036a41086a41003a000020034189036a200a29000037000020034191036a200a41086a29000037000020034199036a200a41106a290000370000200341a1036a200a41186a290000370000200341033a00800341b0b4cc00410020034180036a10d4010b0b200241ff01714104470d010b20034180036a41186a420037030020034180036a41106a220b420037030020034180036a41086a22024200370300200342003703800341d1c4c700ad4280808080e000841001220a29000021062002200a41086a2900003703002003200637038003200a103541e7c4c700ad4280808080e000841001220a2900002106200341e0076a41086a220c200a41086a290000370300200320063703e007200a1035200b20032903e0072206370300200341c8066a41086a2002290300370300200341c8066a41106a2006370300200341c8066a41186a200c29030037030020032003290380033703c806200341c0006a200341c8066a412010c0012003280244210a2003280240210b200341c0056a41186a20034180026a41186a220c290300370300200341c0056a41106a20034180026a41106a220d290300370300200341c0056a41086a20034180026a41086a220e29030037030020032003290380023703c005200341c8036a2007370300200341c0036a200537030020034189036a220f200341c0016a41086a221029030037000020034191036a2211200341c0016a41106a221229030037000020034199036a2213200341c0016a41186a2214290300370000200341b4036a4100360200200341b0036a200a4100200b1b360200200341ac036a2001360200200341a8036a2008360200200341a4036a2009360200200341013a008003200320032903c00137008103200341c0056a20034180036a109505200341d8036a2007370300200341d0036a20053703002002410b3a0000200f2003290380023700002011200e2903003700002013200d290300370000200341a1036a200c290300370000200341a9036a20032903c001370000200341b1036a2010290300370000200341b9036a2012290300370000200341c1036a2014290300370000200341063a00800341b0b4cc00410020034180036a10d401200341043a0088010c3b0b2003200637028c01200320023a0088012003200a3b0089012003200a4110763a008b010c230b200141086a2802002108200141046a280200210902400240024020022d00000d0020022d000141ff01714101470d002001410c6a2802002101200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211e200241046a2d0000211f200241026a2f0100212020032002411a6a2901003701d8012003200a3a00d7012003200b3a00d6012003200c3b01d4012003200d3a00d3012003200e3a00d2012003200f3b01d001200320103a00cf01200320113a00ce01200320123b01cc01200320133a00cb01200320143a00ca01200320153b01c801200320163a00c701200320173a00c601200320183b01c4012003201e3a00c3012003201f3a00c201200320203b01c0012001ad4220862009ad84100922022900002107200241086a2900002105200241106a290000210620034180026a41186a200241186a29000037030020034180026a41106a200637030020034180026a41086a2005370300200320073703800220021035200341c0056a20034180026a10ee0420034180036a20032802c005220a20032802c80510d20220032802c4052102024002400240024020032d008003220b4102460d00200341a8036a280200210c200341a4036a280200210d200335028403210702402002450d00200a10350b200b450d014201210542801e2107200c450d02200d10350c020b02402002450d00200a10350b411021020c020b200742208642801e842107420021050b410f21022005200784a741ff01714101470d030b20034188016a200210e8040c010b200341023a0088010b02402008450d00200910350b20032d0088014104460d3a20032802880121022000411c6a200329028c01370200200041186a200236020020004200370308420121070c3f0b20034180036a41186a420037030020034180036a41106a220b420037030020034180036a41086a22024200370300200342003703800341d1c4c700ad4280808080e000841001220a29000021052002200a41086a2900003703002003200537038003200a103541e7c4c700ad4280808080e000841001220a2900002105200341e0076a41086a220c200a41086a290000370300200320053703e007200a1035200b20032903e0072205370300200341c8066a41086a2002290300370300200341c8066a41106a2005370300200341c8066a41186a200c29030037030020032003290380033703c806200341e0006a200341c8066a412010c0012003280264210a2003280260210b200341c0056a41186a20034180026a41186a220c290300370300200341c0056a41106a20034180026a41106a220d290300370300200341c0056a41086a20034180026a41086a220e29030037030020032003290380023703c005200341c8036a4200370300200341c0036a420037030020034189036a220f200341c0016a41086a221029010037000020034191036a2211200341c0016a41106a221229010037000020034199036a2213200341c0016a41186a2214290100370000200341b8036a20074220883e0200200341b4036a4101360200200341b0036a200a4100200b1b360200200341ac036a2001360200200341a8036a2008360200200341a4036a2009360200200341013a008003200320032901c00137008103200341c0056a20034180036a109505200341d8036a4200370300200341d0036a42003703002002410b3a0000200f2003290380023700002011200e2903003700002013200d290300370000200341a1036a200c290300370000200341a9036a20032901c001370000200341b1036a2010290100370000200341b9036a2012290100370000200341c1036a2014290100370000200341063a00800341b0b4cc00410020034180036a10d401200341043a0088010c390b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a29000037030020032001290001370388012002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d00200320073702e407200320013a00e307200320083a00e207200320093b01e007410121020c010b20022d00012102200320073703e007200241ff017141014721020b200320073701d801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320133a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c0010240024020020d0020034180026a41186a200341c0016a41186a29010037030020034180026a41106a200341c0016a41106a29010037030020034180026a41086a200341c0016a41086a290100370300200320032901c00137038002200341c0056a20034188016a10ee0420034180036a20032802c005220120032802c80510d20220032802c40521020240024020032d00800322084102460d00200341c8036a2903002105200341c0036a2903002106200341b8036a2802002122200341b4036a2802002121200341b0036a280200210a200341a8036a280200210b200341a4036a280200212020034199036a290000210720034180036a41186a2d0000210c20034197036a2d0000210d20034195036a2f0000210e20034194036a2d0000210f20034193036a2d0000211020034191036a2f0000211120034180036a41106a2d000021122003418f036a2d000021132003418d036a2f000021142003418c036a2d000021152003418b036a2d0000211620034189036a2f0000211720034180036a41086a2d00002118200328028403210920032d008303211e20032f008103211f02402002450d00200110350b2008450d0120094118762102200941087621010240200b450d00202010350b200320073703d8052003200c3a00d7052003200d3a00d6052003200e3b01d4052003200f3a00d305200320103a00d205200320113b01d005200320123a00cf05200320133a00ce05200320143b01cc05200320153a00cb05200320163a00ca05200320173b01c805200320183a00c705200320023a00c605200320013b01c405200320093a00c3052003201e3a00c2052003201f3b01c00520034180036a41186a420037030020034180036a41106a2208420037030020034180036a41086a22024200370300200342003703800341d1c4c700ad4280808080e000841001220129000021072002200141086a29000037030020032007370380032001103541e7c4c700ad4280808080e00084100122012900002107200341e0076a41086a2209200141086a290000370300200320073703e00720011035200820032903e0072207370300200341c8066a41086a2002290300370300200341c8066a41106a2007370300200341c8066a41186a200929030037030020032003290380033703c806200341e8006a200341c8066a412010c001411121020240200328026c410020032802681b2201200a4180de34410020034180026a200341c0056a412010a0081b6a41809c316a490d002021450d0441122102200120224b0d040b200341c8076a200210e8040c230b2002450d00200110350b200341c8076a411310e8040c210b200341023a00c8070c210b20034180036a200341c0056a20034180026a20062005410010ef0220034180036a20034188016a10ee042003350288034220862003280280032202ad8410070240200328028403450d00200210350b20034180036a41086a410f3a000020034189036a200329038801370000200341a9036a20032903c00537000020034191036a20034188016a41086a29030037000020034199036a20034188016a41106a290300370000200341a1036a20034188016a41186a290300370000200341b1036a200341c0056a41086a290300370000200341b9036a200341c0056a41106a290300370000200341c1036a200341c0056a41186a290300370000200341063a008003200341f0036a2006370300200341f8036a2005370300200341e1036a20034180026a41186a290300370000200341d9036a20034180026a41106a290300370000200341d1036a20034180026a41086a290300370000200341c9036a20032903800237000041b0b4cc00410020034180036a10d401200341043a00c8070c380b20034180026a41186a200141196a29000037030020034190026a200141116a29000037030020034188026a200141096a29000037030020032001290001370380022002411a6a2901002107024020022d0000450d00200241166a2f01002101200241186a2d00002108200241196a2d00002102200320073702e407200320023a00e307200320083a00e207200320013b01e0070c1e0b20022d00012102200320073703e007200241ff01714101470d1d200341c0016a20034180026a10960520034180036a20032802c001220920032802c801220a10c90220032d0080032102200341c8066a20034180036a41017241ef00109d081a0240024020024102470d00200341d0056a4200370300200341d8056a4200370300200341e0056a4200370300200341e8056a4200370300200341f0056a4200370300200341f8056a42003703004100210220034180066a4100360200200341083602c405200341c0056a41086a4200370300200341003a00c0050c010b200320023a00c005200341c0056a410172200341c8066a41ef00109d081a200241014621020b20034180036a41186a420037030020034180036a41106a220b420037030020034180036a41086a22014200370300200342003703800341d1c4c700ad4280808080e000841001220829000021072001200841086a29000037030020032007370380032008103541e7c4c700ad4280808080e00084100122082900002107200341e0076a41086a220c200841086a290000370300200320073703e00720081035200b20032903e0072207370300200341c8066a41086a2001290300370300200341c8066a41106a2007370300200341c8066a41186a200c29030037030020032003290380033703c806200341f0006a200341c8066a412010c001024020034198066a200341f0056a20021b22012802102003280274410020032802701b4b0d0020014200370300200141106a4100360200200141086a42003703000b024002402002450d00200341f0056a2903002106200341e8056a29030021190c010b200341f8056a290300210620032903f0052119200341cc056a28020041306c2201450d0020032802c40541206a21020340200241706a22082903002105200841086a29030021070240200241686a2d00004101470d00427f2007200241086a2903007c200520022903007c221a2005542208ad7c22052008200520075420052007511b22081b2107427f201a20081b21050b200620072005201954200720065420072006511b22081b21062019200520081b2119200241306a2102200141506a22010d000b0b20034180036a200341c0056a41f000109d081a0240024020032d00800322024102470d00200aad4220862009ad8410070c010b200341c8066a20034180036a108005200aad4220862009ad8420033502d00642208620032802c8062201ad841002024020032802cc06450d00200110350b20020d0020034188036a2802002202450d00200241306c450d0020032802840310350b024020032802c401450d00200910350b02402019200684500d00200342e4cab5fbb6ccdcb0e3003703800320034180036a20034180026a2019200641021090020c380b200342e4cab5fbb6ccdcb0e3003703800320034180036a20034180026a1092020c370b20022d00000d1420022d000141ff01714101470d14200141196a2900002105200141186a2d00002109200141176a2d0000210a200141156a2f0000210b200141146a2d0000210c200141136a2d0000210d200141116a2f0000210e200141106a2d0000210f2001410f6a2d000021102001410d6a2f000021112001410c6a2d000021122001410b6a2d00002113200141096a2f00002114200141086a2d00002115200141076a2d00002116200141056a2f00002117200141046a2d00002118200141036a2d0000211e20012f00012101200241196a3100002106200241186a3100002119200241166a330100211a200241156a310000211b200241146a310000211c200241126a330100211d200241116a2d00002108200241106a2d0000211f2002410e6a2f010021202002410d6a2d000021212002410c6a2d000021222002410a6a2f01002123200241096a2d00002124200241086a2d00002125200241066a2f01002126200241056a2d00002127200241046a2d00002128200241026a2f01002129200341de056a2002411a6a29010022074230883c0000200341ce056a201f3a0000200341ca056a20223a000020032007a722023b01d805200341da056a20024110763a0000200320203b01cc05200320233b01c805200320253a00c605200320263b01c405200320283a00c205200320293b01c005200320083a00cf05200320213a00cb05200320243a00c705200320273a00c305200320074220883d01dc05200320074238883c00df05200320074218883c00db052003201d201c42108684201b42188684201a422086842019423086842006423886843703d005200341c8066a200341c0056a10920520034180036a20032802c806220820032802d006221f10c4020240024020032d0080034102460d0020032003290081033701c001200320034199036a2900003701d801200320034189036a2900003701c801200320034191036a2900003701d00120014180fe037141087621020c010b20014180fe03714108762102200341c0056a108d020b200320153a00c701200320163a00c601200320173b01c401200320183a00c3012003201e3a00c20120032002410874200141ff0171723b01c0012003200f3a00cf01200320103a00ce01200320113b01cc01200320123a00cb01200320133a00ca01200320143b01c801200320093a00d7012003200a3a00d6012003200b3b01d4012003200c3a00d3012003200d3a00d2012003200e3b01d001200320053701d80120034198036a200537030020034190036a20032901d00137030020034180036a41086a20032901c801370300200320032901c00137038003410110332202450d38200241003a000020024101412110372202450d382002200329038003370001200241196a20034198036a290300370000200241116a20034190036a290300370000200241096a20034188036a290300370000201fad4220862008ad842002ad428080808090048410022002103520032802cc06450d36200810350c360b0240024002400240024020022d00000d0020022d000141ff01714101460d010b200341023a00c0050c010b200141046a2802002101200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211e20032002411a6a29010037039803200320083a009703200320093a0096032003200a3b0194032003200b3a0093032003200c3a0092032003200d3b0190032003200e3a008f032003200f3a008e03200320103b018c03200320113a008b03200320123a008a03200320133b018803200320143a008703200320153a008603200320163b018403200320173a008303200320183a0082032003201e3b018003200341c0056a20034180036a2001410010970520032d00c0054104460d0120032902c40521070b20032802c00521032000411c6a2007370200200041186a2003360200420121070c010b420021070b200042003703080c3a0b200141246a2802002108200341c0056a41186a200141196a290000370300200341c0056a41106a200141116a290000370300200341c0056a41086a200141096a290000370300200320012900013703c0050240024020022d00000d0020022d000141ff01714101470d00200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211e20032002411a6a29010037039803200320013a009703200320093a0096032003200a3b0194032003200b3a0093032003200c3a0092032003200d3b0190032003200e3a008f032003200f3a008e03200320103b018c03200320113a008b03200320123a008a03200320133b018803200320143a008703200320153a008603200320163b018403200320173a008303200320183a0082032003201e3b018003200341c8066a200341c0056a2008200341c0056a20034180036a412010a00841004710970520032d00c80622024104460d3620032f00c90620032d00cb0641107472210120032902cc0621070c010b410221020b200042003703082000411c6a2007370200200041186a2001410874200272360200420121070c390b200141306a2903002107200141286a2903002105200141216a2d00002108200341c8066a41186a200141196a290000370300200341c8066a41106a200141116a290000370300200341c8066a41086a200141096a290000370300200320012900013703c80620022d00000d1220022d000141ff01714101470d122002411a6a2901002106200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c0012003200e3a00cf012003200f3a00ce01200320103b01cc01200320113a00cb01200320123a00ca01200320133b01c801200320013a00d701200320093a00d6012003200a3b01d4012003200b3a00d3012003200c3a00d2012003200d3b01d001200320063701d801200341c0056a41186a2006370300200341c0056a41106a20032901d001370300200341c0056a41086a20032901c801370300200320032901c0013703c00520034180036a200341c0056a108e05024020032d00800322024102460d0020024101470d0020034180036a41186a2d0000210220034197036a2d0000210120034195036a2f0000210920034194036a2d0000210a20034193036a2d0000210b20034191036a2f0000210c20034180036a41106a2d0000210d2003418f036a2d0000210e2003418d036a2f0000210f2003418c036a2d000021102003418b036a2d0000211120034189036a2f0000211220034180036a41086a2d0000211320032d008703211420032f008503211520032d008403211620032d008303211720032d008203211820032d008103211e200320034199036a2900003703d805200320023a00d705200320013a00d605200320093b01d4052003200a3a00d3052003200b3a00d2052003200c3b01d0052003200d3a00cf052003200e3a00ce052003200f3b01cc05200320103a00cb05200320113a00ca05200320123b01c805200320133a00c705200320143a00c605200320153b01c405200320163a00c305200320173a00c205200320183a00c1052003201e3a00c00520034180036a41186a200341c8066a41186a29030037030020034180036a41106a200341c8066a41106a29030037030020034180036a41086a200341c8066a41086a290300370300200320032903c8063703800320034180026a200341c0056a20034180036a200820052007109305024020032d00800222024104470d00200341043a0088010c350b20032d008302210120032f00810221082003200329028402220737028c01200320023a0088012003200820014110747222023b008901200320024110763a008b010c190b20034188016a410310e80420032d0088014104460d33200329028c0121070c180b20022d00000d1220022d000141ff01714101470d122002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172003200241096a2d00003a00c701200320133a00c601200320143b01c401200320153a00c301200320163a00c201200320173b01c0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d001200320073701d801200341c0056a41186a2007370300200341c0056a41106a20032901d001370300200341c0056a41086a20032901c801370300200320032901c0013703c00520034180036a200341c0056a108e05024020032d00800322024102460d0020024101470d0020034180036a41186a2d0000210220034197036a2d0000210120034195036a2f0000210820034194036a2d0000210920034193036a2d0000210a20034191036a2f0000210b20034180036a41106a2d0000210c2003418f036a2d0000210d2003418d036a2f0000210e2003418c036a2d0000210f2003418b036a2d0000211020034189036a2f0000211120034180036a41086a2d0000211220032d008703211320032f008503211420032d008403211520032d008303211620032d008203211720032d0081032118200320034199036a29000037039803200320023a009703200320013a009603200320083b019403200320093a0093032003200a3a0092032003200b3b0190032003200c3a008f032003200d3a008e032003200e3b018c032003200f3a008b03200320103a008a03200320113b018803200320123a008703200320133a008603200320143b018403200320153a008303200320163a008203200320173a008103200320183a008003200341c0056a20034180036a109405024020032d00c00522024104470d00200341043a00c8060c340b20032d00c305210120032f00c1052108200320032902c40522073702cc06200320023a00c8062003200820014110747222023b00c906200320024110763a00cb060c170b200341c8066a410310e80420032d00c8064104460d3220032902cc0621070c160b20022d00000d1220022d000141ff01714101470d12200141046a28020021182002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172003200241096a2d00003a00c701200320133a00c601200320143b01c401200320153a00c301200320163a00c201200320173b01c0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d001200320073701d801200341c0056a41186a2007370300200341c0056a41106a20032901d001370300200341c0056a41086a20032901c801370300200320032901c0013703c00520034180036a200341c0056a108e050240024020032d00800322024102460d0020024101470d0020034180036a41186a2d0000210220034197036a2d0000210120034195036a2f0000210820034194036a2d0000210920034193036a2d0000210a20034191036a2f0000210b20034180036a41106a2d0000210c2003418f036a2d0000210d2003418d036a2f0000210e2003418c036a2d0000210f2003418b036a2d0000211020034189036a2f0000211120034180036a41086a2d0000211220032d008703211320032f008503211420032d008403211520032d008303211620032d008203211720032d008103211e200320034199036a2900003703e006200320023a00df06200320013a00de06200320083b01dc06200320093a00db062003200a3a00da062003200b3b01d8062003200c3a00d7062003200d3a00d6062003200e3b01d4062003200f3a00d306200320103a00d206200320113b01d006200320123a00cf06200320133a00ce06200320143b01cc06200320153a00cb06200320163a00ca06200320173a00c9062003201e3a00c80620034180026a200341c8066a201841001097050c010b20034180026a410310e8040b024020032d0080024104460d0020032902840221070c140b420021070c140b200141246a2802002108200341c0056a41186a2209200141196a290000370300200341c0056a41106a220a200141116a290000370300200341c0056a41086a220b200141096a290000370300200320012900013703c005024002400240024020022d000120022d000041004772450d00200341023a00c8060c010b20034180036a41186a200929030037030020034180036a41106a200a29030037030020034180036a41086a200b290300370300200320032903c00537038003200341c8066a20034180036a200810f40420032d00c8064104460d0120032902cc0621070b20032802c80621032000411c6a2007370200200041186a2003360200420121070c010b420021070b200042003703080c350b2001200241e88cc5001059000b2002200a41e88cc5001058000b2009200a41f88cc5001059000b20034188016a41146a410a36020020034194016a410c360200200341e0076a41146a41033602002003200341d8076a3602f8072003200341dc076a3602fc0720034180036a41146a4100360200200342033702e407200341a0b3cc003602e0072003410c36028c01200341b0b4cc00360290032003420137028403200341f4b3cc0036028003200320034188016a3602f007200320034180036a360298012003200341fc076a360290012003200341f8076a36028801200341e0076a41b0b4cc00104c000b200341023a0088010c250b200341023a00c8070c170b2008200a104d000b20004200370308200041186a4102360200420121070c2d0b200341023a00c0010c130b200341023a00c8070c110b20004200370308200041186a4102360200420121070c2a0b200341023a00c8070c0e0b200341023a0088010c0c0b20034188016a410f10e8040c0b0b20004200370308200041186a4102360200420121070c260b200341023a0088010c050b200341023a00c8060c030b200341023a0080020b20032802800221032000411c6a2007370200200041186a2003360200420121070b200042003703080c210b20032802c80621032000411c6a2007370200200041186a200336020020004200370308420121070c200b20032802880121032000411c6a2007370200200041186a200336020020004200370308420121070c1f0b200041186a410236020020004200370308420121070c1e0b20032d00c8074104460d1820032902cc0721070b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c1c0b02402008450d00200910350b20032d0088014104460d1620032802880121022000411c6a200329028c01370200200041186a200236020020004200370308420121070c1b0b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c1a0b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c190b20032802c00121032000411c6a2007370200200041186a200336020020004200370308420121070c180b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c170b20034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c005370380034100210a20034180036a2101410021080b0240200a200f470d0020034188016a200a4101108a01200328028c01210f200328028801210e0b200e20084105746a220241206a2002200a20086b410574109e081a20022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700002003200a41016a22023602900120034180036a41186a420037030020034180036a41106a2209420037030020034180036a41086a22014200370300200342003703800341d1c4c700ad4280808080e000841001220829000021072001200841086a29000037030020032007370380032008103541e7c4c700ad4280808080e00084100122082900002107200341e0076a41086a220a200841086a290000370300200320073703e00720081035200920032903e0072207370300200341c8066a41086a2001290300370300200341c8066a41106a2007370300200341c8066a41186a200a29030037030020032003290380033703c806200341386a200341c8066a412010c001200328023c21092003280238210a200341c8066a20034180026a1091052002410574220b41047241046a2201417f4c0d0120033502d006210720032802c8062110200110332208450d112008200941809c316a41809c31200a1b2211360000200341043602880320032001360284032003200836028003200220034180036a10770240024020020d0020032802880321012003280284032109200328028003210d0c010b410020032802880322016b210a200328028003210d2003280284032109200e210c0340200c210202402009200a6a411f4b0d00200141206a22082001490d032009410174220c2008200c20084b1b22084100480d03024002400240024020090d00024020080d004101210d0c020b20081033210d0c030b20092008470d010b200821090c020b200d200920081037210d0b20082109200d450d150b200241206a210c200d20016a22082002290000370000200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200a41606a210a200141206a2101200b41606a220b0d000b200320093602840320032001360288032003200d360280030b20074220862010ad842001ad422086200dad84100202402009450d00200d10350b024020032802cc06450d00201010350b0240200f41ffffff3f71450d00200e10350b20034180036a41086a410a3a000020034189036a20032903c005370000200341a9036a20032903800237000020034191036a200341c0056a41086a29030037000020034199036a200341c0056a41106a290300370000200341a1036a200341c0056a41186a290300370000200341b1036a20034180026a41086a290300370000200341b9036a20034180026a41106a290300370000200341c1036a20034180026a41186a290300370000200341063a008003200341cc036a201136020041b0b4cc00410020034180036a10d40141d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341c0016aad42808080808004841007200341043a00c8070c100b103e000b1044000b200941ff01710d00200c200b4f0d010b200341023a00c8070c010b41d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c00120034180036a200341c0016a10c0020240024020032d00a00322024103460d0020032f018003210120032d008203210920032d008303210a20032f018403210b20032d008603210c20032d008703210e20032f018803210f20032d008a03211020032d008b03211120032f018c03211220032d008e03211320032d008f03211420032f019003211520032d009203211620032d009303211720032f019403211820032d009603211e20032d009703211f20032003290398033703d8052003201f3a00d7052003201e3a00d605200320183b01d405200320173a00d305200320163a00d205200320153b01d005200320143a00cf05200320133a00ce05200320123b01cc05200320113a00cb05200320103a00ca052003200f3b01c8052003200e3a00c7052003200c3a00c6052003200b3b01c4052003200a3a00c305200320093a00c205200320013a00c00541082109200320014108763a00c10502402002450d004109210920034180026a200341c0056a412010a008450d040b200341c8076a200910e8040c010b200341c8076a410210e8040b20032d00c8074104460d0b20032902cc0721070b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c0f0b41d9e3cb00ad42808080809001841001220129000021072001290008210520011035419c8dc500ad4280808080c001841001220129000021062001290008211920011035200320193701d801200320063701d001200320053701c801200320073701c001200341c0016aad4280808080800484100720034180036a41186a220b420037030020034180036a41106a2209420037030020034180036a41086a22014200370300200342003703800341d1c4c700ad4280808080e000841001220a29000021072001200a41086a2900003703002003200737038003200a103541e7c4c700ad4280808080e000841001220a2900002107200341e0076a41086a220c200a41086a290000370300200320073703e007200a1035200920032903e0072207370300200341c8066a41086a2001290300370300200341c8066a41106a2007370300200341c8066a41186a200c29030037030020032003290380033703c806200341306a200341c8066a412010c0012003280234210a2003280230210c200b20034180026a41186a290300370300200920034180026a41106a290300370300200120034180026a41086a290300370300200320032903800237038003200a4100200c1b20086a20034180036a2002200d10e904200341043a00c8070c090b200341c0016a41086a20034180026a41086a2902002207370300200341c0016a41106a20034180026a41106a290200370300200341c0016a41186a20034180026a41186a290200370300200341c0016a41206a20034180026a41206a290200370300200341c0016a41286a20034180026a41286a290200370300200341c0016a41306a20034180026a41306a290200370300200341c0016a41386a20034180026a41386a280200360200200320032902800222053703c001200341e0076a41086a20073e0200200320053703e0070b20032d00e0074104460d0720032902e40721070b20032802e00721032000411c6a2007370200200041186a200336020020004200370308420121070c0b0b20032802880121032000411c6a2007370200200041186a2003360200420121070b200042003703080c090b20032802c007210120032802bc07210920032802b80721020b2002450d0020072001ad4220862002ad8410022009450d01200210350c010b41d9e3cb00ad42808080809001841001220229000021192002290008211a2002103541918dc500ad4280808080b0018410012202290000211b2002290008211c200210352003201c3701d8012003201b3701d0012003201a3701c801200320193701c001410810332202450d0220034208370284032003200236028003410120034180036a107720032802ac0120034180036a108c05200328028403210220072003350288034220862003280280032201ad8410022002450d00200110350b20034198036a200537030020034190036a20063703002003418c036a200836020020034188036a41003a0000200341063a00800341b0b4cc00410020034180036a10d401200341043a00780b42002107200042003703080c040b1045000b103c000b200341023a00780b200328027821032000411c6a2007370200200041186a200336020020004200370308420121070b20002007370300200424000b880101027f230041106b220224002002200028020036020c20012002410c6a4104107802404120103322030d001045000b20032000290004370000200341186a2000411c6a290000370000200341106a200041146a290000370000200341086a2000410c6a2900003700002001200341201078200310352001200041246a41201078200241106a24000bb91e06037f0d7e027f017e057f047e230041b0066b22042400200441d0036a200210f504200441d0046a20042802d003220520042802d80310b30220042d00d0042106200441e0036a200441d0046a41017241e700109d081a024002400240024020064102460d00200441c0056a200441e0036a41e700109d081a024020042802d403450d00200510350b200441e8026a200441c0056a41e700109d081a200441d0046a200441e8026a41e700109d081a2006450d01200441f8016a411410e8040c020b024020042802d403450d00200510350b200441f8016a411410e8040c010b200441fc016a200441d7046a41e000109d081a200441c8016a41206a200441cc026a2902002207370300200441c8016a41186a200441c4026a2902002208370300200441c8016a41106a200441bc026a2902002209370300200441c8016a41086a200441b4026a290200220a370300200441c8016a41286a2206200441d4026a290200370300200420042902ac02220b3703c80120044184026a290200210c20044194026a290200210d200441a4026a290200210e20042902fc01210f200429028c022110200429029c022111200441e8026a41086a200a370300200441e8026a41106a2009370300200441e8026a41186a2008370300200441e8026a41206a2007370300200441e8026a41286a20062903003703002004200b3703e802200341186a2903002112200341086a2903002108200341206a2903002113200341106a290300210720032d00002114200441e0036a2001108e02200441d0046a20042802e003221520042802e803108f02427f200720137c200820127c220a2008542206ad7c22092006200920075420092007511b22061b2007201441014622051b2109427f200a20061b200820051b210b200441d0046a41106a290300420020042903d00442015122061b210a20042903d804420020061b2116024020042802e403450d00201510350b0240024002400240024002400240024002400240200b2016562009200a562009200a511b0d00200441c8016a2001109605200441d0046a20042802c801221720042802d001221810c90220042d00d0042106200441c0056a200441d0046a41017241ef00109d081a0240024020064102470d00200441f0036a4200370300200441f8036a420037030020044180046a420037030020044188046a420037030020044190046a420037030020044198046a420037030041002106200441a0046a4100360200200441083602e403200441e0036a41086a4200370300200441003a00e0030c010b200420063a00e003200441e0036a410172200441c0056a41ef00109d081a0b411e210520060d0420042802e403211941002106024002400240024002400240200441ec036a280200221a41014b0d00201a0e020201020b201a2105034020062005410176221520066a221b2019201b41306c6a28020020024b1b2106200520156b220541014b0d000b0b2019200641306c6a28020022052002460d01200620052002496a21060b200441f4046a200341206a290200370200200441ec046a200341186a290200370200200441e4046a200341106a290200370200200441dc046a200341086a290200370200200420032902003702d404201a2006490d010240201a200441e0036a41086a280200470d00200441e0036a410472201a410110880120042802e40321190b2019200641306c6a220541306a2005201a20066b41306c109e081a20052002360200200520042902d0043702042005410c6a200441d8046a290200370200200541146a200441e0046a2902003702002005411c6a200441e8046a290200370200200541246a200441f0046a2902003702002005412c6a200441f8046a2802003602002004201a41016a3602ec030c060b201a20064d0d012019200641306c6a220641186a290300211c200641106a290300210a0240024020062d000822154101470d0041202105200441e8006a200641206a290300221d200641286a290300221e420a4200109808200441f8006a200a201c420a42001098082011200a7d221f201156200e201c7d2011200a54ad7d221c200e56201c200e511b0d08201f201d7d2216201f56201c201e7d201f201d54ad7d220a201c56200a201c511b0d08200f2004290378220e7d221f200f56200c200441f8006a41086a2903007d200f200e54ad7d221c200c56201c200c511b0d0920102004290368220e7d220f201056200d200441e8006a41086a2903007d2010200e54ad7d220c200d56200c200d511b450d010c0a0b200641096a2d0000211b024002402006410a6a2d0000220541ff0171450d00200441a8016a201c42002005ad42ff018322164200108408200441b8016a200a42002016420010840820044198016a42004200200a4200108408427f200441c0016a290300221620042903a8012004290398017c7c221f20042903b00120042903a00184420052201f2016547222051b211d427f20042903b80120051b211f0c010b20044188016a200a201c420a420010980820044190016a290300211d200429038801211f0b412021052011200a7d2216201156200e201c7d2011200a54ad7d220a200e56200a200e511b0d070240201b41ff01710d002010201f7d2211201056200d201d7d2010201f54ad7d220e200d56200e200d511b0d0920112110200e210d200f211e200c211c0c050b200f201f7d221e200f56200c201d7d200f201f54ad7d221c200c56201c200c511b450d040c080b20162111200a210e200f2110200c210d201f210f201c210c0c040b2006201a104d000b2006201a41ecc0c6001042000b2000412110e8040c0a0b0240024020150d00201b41ff01714102460d004200200a20044188046a2903007d201620044180046a290300221154ad7d220e201620117d2211201656200e200a56200e200a511b22051b210e4200201120051b2111200441f8036a290300211620042903f003210a0240201b4101710d004200200d20167d2010200a54ad7d22162010200a7d220a2010562016200d562016200d511b22051b210d4200200a20051b21100c020b4200201c20167d201e200a54ad7d2216201e200a7d220a201e562016201c562016201c511b22051b210c4200200a20051b210f0c020b20162111200a210e0b201e210f201c210c0b200641086a22062003290300370300200641206a200341206a290300370300200641186a200341186a290300370300200641106a200341106a290300370300200641086a200341086a2903003703000b0240024020144101470d00200441086a20122013420a4200109808200441186a20082007420a4200109808411f2105201120087c22082011542206200e20077c2006ad7c2207200e542007200e511b0d02200820127c22162008542206200720137c2006ad7c220a200754200a2007511b0d02200f20042903187c221f200f542206200c200441186a41086a2903007c2006ad7c221c200c54201c200c511b0d03201020042903087c22082010542206200d200441086a41086a2903007c2006ad7c2207200d542007200d511b0d040c010b20032d0001211502400240200341026a2d0000220641ff0171450d00200441c8006a200742002006ad42ff0183220a4200108408200441d8006a20084200200a4200108408200441386a4200420020084200108408427f200441e0006a290300220a200429034820042903387c7c221220042903502004290340844200522012200a547222061b2112427f200429035820061b21130c010b200441286a20082007420a4200109808200441306a2903002112200429032821130b411f2105201120087c22162011542206200e20077c2006ad7c220a200e54200a200e511b0d0102400240201541ff01710d00201020137c22082010542206200d20127c2006ad7c2207200d542007200d511b0d04200821102007210d200f211f200c211c0c010b200f20137c221f200f542206200c20127c2006ad7c221c200c54201c200c511b0d030b024020140d00201541ff01714102460d00427f200a20044188046a2903007c201620044180046a2903007c22082016542206ad7c220720062007200a542007200a511b22061b210a427f200820061b2116200441f8036a290300210720042903f0032108024020154101710d00427f200d20077c201020087c22082010542206ad7c220720062007200d542007200d511b22061b2107427f200820061b21080c020b427f201c20077c201f20087c2208201f542206ad7c220720062007201c542007201c511b22061b211c427f200820061b211f0b20102108200d21070b200441043a00f8010c040b20112116200e210a0b20102108200d2107200f211f200c211c0c010b20102108200d21070b200441f8016a200510e80420042d00f80122064104460d00200420042900f9013703c0052004200441f8016a41086a2800003600c70520042d00e0030d01200441e0036a41086a2802002203450d01200341306c450d0120042802e40310350c010b200441d0046a200441e0036a41f000109d081a0240024020042d00d00422064102470d002018ad4220862017ad8410070c010b200441c0056a200441d0046a1080052018ad4220862017ad8420043502c80542208620042802c0052203ad841002024020042802c405450d00200310350b20060d00200441d8046a2802002206450d00200641306c450d0020042802d40410350b200420042900f9013703c005200420044180026a2800003600c705410421060b024020042802cc01450d00201710350b200420042903c0053703d003200420042800c7053600d703024020064104470d00200442e4cab5fbb6ccdcb0e3003703e002200441e0026a2001200b200910ea0220044180056a200a370300200441d0046a41286a2016370300200441d0046a41206a2007370300200441d0046a41186a2008370300200441d0046a41106a201c37030020044188056a20042903e80237030020044190056a200441f0026a29030037030020044198056a200441e8026a41106a290300370300200441a0056a200441e8026a41186a290300370300200441a8056a200441e8026a41206a290300370300200441b0056a200441e8026a41286a2903003703002004201f3703d804200441003a00d004200441e0036a200210f50420042802e0032106200420042802e8033602c405200420063602c005200441d0046a200441c0056a10f604024020042802e403450d00200610350b200041043a00000c020b200020063a0000200020042903d003370001200041086a20042800d7033600000c010b20042802f8012106200041046a20042902fc01370200200020063602000b200441b0066a24000b810703047f017e027f23004180016b22022400200241186a2203200141186a290000370300200241106a2204200141106a290000370300200241086a2205200141086a2900003703002002200129000037030041d9e3cb00ad4280808080900184100122012900002106200241286a41086a200141086a290000370300200220063703282001103541e4a6cb00ad4280808080d00084100122012900002106200241386a41086a200141086a29000037030020022006370338200110350240024002400240412010332201450d0020012002290300370000200141186a2003290300370000200141106a2004290300370000200141086a200529030037000020022001ad42808080808004841003220329000037037820031035200241e4006a200141206a360200200220013602602002200241f8006a41086a36025c2002200241f8006a360258200241c8006a200241d8006a107b200110352002280250220741206a2203417f4c0d01200228024821080240024020030d0041002104410121010c010b200310332201450d01200321040b024002402004410f4d0d00200421050c010b200441017422054110200541104b1b22054100480d03024020040d002005103322010d010c050b20042005460d0020012004200510372201450d040b20012002290328370000200141086a200241286a41086a2903003700000240024020054170714110460d00200521040c010b200541017422044120200441204b1b22044100480d0320052004460d0020012005200410372201450d040b20012002290338370010200141186a200241386a41086a29030037000002400240200441606a2007490d00200421050c010b2007415f4b0d03200441017422052003200520034b1b22054100480d0320042005460d0020012004200510372201450d040b200141206a20082007109d081a0240200228024c450d00200810350b20022001200310c402200241e0006a2203200241096a290000370300200241e8006a2204200241116a290000370300200241f0006a2207200241196a290000370300200220022900013703580240024020022d000022084102470d00200041023a00000c010b200020083a000020002002290358370001200041096a2003290300370000200041116a2004290300370000200041196a20072903003700000b02402005450d00200110350b20024180016a24000f0b1045000b1044000b103e000b103c000b9f0303027f017e027f230041206b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a200341086a29000037030020022004370300200310354184a4c600ad4280808080d00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000ba10202067f017e230041106b2202240002400240412010332203450d0020032000290000370000200341186a2204200041186a290000370000200341106a2205200041106a290000370000200341086a2206200041086a290000370000412010332207450d0120072003290000370000200741186a2004290000370000200741106a2005290000370000200741086a2006290000370000200310350240024020002d0020220341024d0d004280808080800421080c010b024002400240024020030e03000102000b410021030c020b410121030c010b410221030b200220033a000f2007412041c00010372207450d02200720033a00204280808080900421080b200129020020082007ad84100220071035200241106a24000f0b1045000b103c000b9f0303027f017e027f230041206b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003103541b8a3c600ad4280808080900184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000bb10503027f017e047f230041d0006b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541e4a6cb00ad4280808080d00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bfe2208047f027e047f077e037f087e157f017e23002206210720064180056b416071220624000240024020012002460d0020012002412010a008450d00200641a0016a2001108e0220064180046a20062802a001220820062802a801108f0220064190046a290300420020062903800442015122091b210a200629038804420020091b210b024020062802a401450d00200810350b200b200454200a200554200a2005511b450d012000412110e804200724000f0b2000412510e804200724000f0b20064190016a200110960520064180046a200628029001220c200628029801220d10c90220064190036a41026a220920062d0083043a0000200641c8036a41086a220820064180046a41e0006a290300370300200641c8036a41106a220e20064180046a41e8006a290300370300200620062f0081043b019003200620064180046a41d8006a2903003703c8030240024020062d008004220f4102470d00200641a0016a41c0006a220941003602004200210b200641a0016a41106a4200370300200641a0016a41186a4200370300200641a0016a41206a4200370300200641a0016a41286a4200370300200641a0016a41306a4200370300200641a0016a41386a4200370300200641083602a401200641a0016a41086a4200370300200641003a00a001200641a0016a41d0006a2903002110200641a0016a41c8006a2903002111200929030021124200210a42002113420021140c010b20064180046a41d0006a290300211020064180046a41c8006a290300211120064180046a41386a290300211420064180046a41286a290300210a20064180046a41206a290300210b20064180046a41186a290300211520064180046a41106a290300211620064180046a41306a290300211320064180046a410c6a280200211720064180046a41086a28020021182006280284042119200641a0016a41c0006a20064180046a41c0006a2903002212370300200641a0016a41386a2014370300200641a0016a41286a200a370300200641a0016a41206a200b370300200641a0016a41186a2015370300200641a0016a41106a2016370300200641a0016a41d0006a2010370300200641a0016a41c8006a2011370300200641a0016a41306a2013370300200641a0016a410c6a2017360200200641a0016a41086a2018360200200641a0016a41d8006a20062903c803370300200641a0016a41e0006a2008290300370300200641a0016a41e8006a200e2903003703002006200f3a00a001200620062f0190033b00a101200620193602a401200620092d00003a00a3010b2006200241106a2900003700b1022006200241176a2900003700b8022006200241086a2900003700a902200620022900003700a10220062903b802211a2006200641b8016a2209290300221b3703b80220062903b002211c200620062903b001221d3703b00220062903a802211e200620062903a801221f3703a802200641013a00a00220062903a0022116200620062903a00122153703a002200231001f2120200641d8016a4200370300200641d0016a2005370300200641c8016a20043703002009201a370300200620202003ad222142ff0183420886843703c0012006201c3703b0012006201e3703a801200620163703a001200641f8016a2209290300211a20094200370300200641f0016a4200370300200641e8016a4200370300200642003703e00120064188026a2208280200210f20064180026a220e290300211c20084100360200200e420037030002400240024002400240024002402015a741ff01714101460d002015422088a7210f201fa72108201f422088a70d02200641d8016a200641b0016a2016a741ff017141014622171b220e201b370308200e201d370300200e200b370310200e41186a200a3703002009200641a0016a41306a20171b22092012a736021020092014370308200920133703002008450d01200841306c450d01200f10350c010b20064180046a41176a200641a0026a410172220841176a29000037000020064180046a41106a200841106a29000037030020064180046a41086a200841086a2900003703002006200b3c009f04200620082900003703800402400240200b420888200a42388684220ba741ff0171450d00200641e0006a20134200200b42ff0183220b4200108408200641f0006a200a4200200b4200108408200641d0006a42004200200a4200108408427f200641f8006a290300220b200629036020062903507c7c221520062903682006290358844200522015200b547222081b210b427f200629037020081b21150c010b200641c0006a200a2013420a4200109808200641c8006a290300210b200629034021150b20064180046a2015200b200a2013109805200641d8016a200641b0016a20062d00a001410146220e1b2208201137031020082012370308200841186a2010370300200820143703002009200641d0016a200e1b2209201a3703002009201c3703082009200f3602100b02400240200341ff0171450d00200641206a20054200202142ff0183220a4200108408200641306a20044200200a4200108408200641106a4200420020044200108408427f200641386a290300220a200629032020062903107c7c220b2006290328200629031884420052200b200a547222031b2121427f200629033020031b211b0c010b200620042005420a4200109808200641086a29030021212006290300211b0b200641d0026a200210960520064180046a20062802d002222220062802d802222310c90220064190036a41026a220320062d0083043a000041082124200641c8036a41086a200641e0046a290300370300200641c8036a41106a2209200641e8046a290300370300200620062f0081043b0190032006200641d8046a2903003703c803200641d0046a290300211a200641c8046a290300211f0240024020062d00800422254102470d004200211041002126410021274200211c420021114200211e4200211d4200211242002120410021250c010b200641c0046a2903002120200641b8046a2903002112200641a8046a290300211e200641a0046a290300211120064198046a290300211c20064180046a41106a2903002110200641b0046a290300211d2006418c046a280200212720064180046a41086a28020021262006280284042124200641fc026a41026a20032d00003a0000200641e0026a41086a200641c8036a41086a290300370300200641e0026a41106a2009290300370300200620062f0190033b01fc02200620062903c8033703e0020b20254101460d01427f201e20057c201120047c220b2011542203ad7c220a2003200a201e54200a201e511b22031b211e427f200b20031b2111427f201c20217c2010201b7c220b2010542203ad7c220a2003200a201c54200a201c511b22031b211c427f200b20031b2110202741306c2203450d02202420036a2119200641b8046a210920064180046a410172222841036a2129202421030340200341306a21080240200341086a2d00004101710d00200341096a2d0000212a20064180036a200328020010f50420064180046a2006280280032203200628028803222b10b302200641c8036a41086a222c200941086a222d290000370300200641c8036a41106a222e200941106a222f290000370300200641c8036a41186a2230200941186a2231290000370300200641c8036a41206a2232200941206a2233290000370300200641c8036a41286a2234200941286a2235290000370300200620282800003602f803200620292800003600fb03200620092900003703c80320064180046a41306a210e20064180046a41206a210f20064180046a41106a2117024020062d00800422184102472236450d00200e290300210a200f29030021152017290300211320062903a804210b2006290398042114200629038804211620064190036a41086a202c29030037030020064190036a41106a202e29030037030020064190036a41186a203029030037030020064190036a41206a203229030037030020064190036a41286a2034290300370300200620062800fb033600c303200620062802f8033602c003200620062903c8033703900320180d00427f200a20057c200b20047c2237200b54222cad7c220b202c200b200a54200b200a511b222c1b210a427f2037202c1b210b0240202a4101710d00427f201520217c2014201b7c2237201454222cad7c2214202c201420155420142015511b222c1b2115427f2037202c1b21140c010b427f201320217c2016201b7c2237201654222cad7c2216202c201620135420162013511b222c1b2113427f2037202c1b21160b202820062802c0033600002009200629039003370300200e200a370300200f201537030020172013370300202920062800c303360000202d20064190036a41086a290300370300202f20064190036a41106a290300370300203120064190036a41186a290300370300203320064190036a41206a290300370300203520064190036a41286a2903003703002006200b3703a80420062014370398042006201637038804200620183a0080040240024020360d00202bad4220862003ad8410070c010b2006202b3602cc03200620033602c80320064180046a200641c8036a1099050b200628028403450d00200310350b2008210320192008470d000c030b0b20064190026a412310e80402402008450d00200841306c450d00200f10350b20062d00900222034104460d0220062006290091023703c803200620064190026a41086a2800003600cf0320062d00a0010d03200641a0016a41086a2802002209450d03200941306c450d0320062802a40110350c030b427f201a20057c201f20047c220b201f542203ad7c220a2003200a201a54200a201a511b22031b211a427f200b20031b211f427f202020217c2012201b7c220b2012542203ad7c220a2003200a202054200a2020511b22031b2120427f200b20031b21120b200641d0046a201a370300200641c8046a201f370300200641c0046a2020370300200641b8046a2012370300200641a8046a201e370300200641a0046a201137030020064198046a201c37030020064180046a41106a2010370300200641b0046a201d3703002006418c046a202736020020064180046a41086a2026360200200641d8046a20062903e002370300200641e0046a200641e0026a41086a290300370300200641e8046a200641e0026a41106a290300370300200620062f01fc023b00810420062024360284042006200641fc026a41026a2d00003a008304200620253a0080040240024020254102470d002023ad4220862022ad8410070c010b200641c8036a20064180046a1080052023ad4220862022ad8420063502d00342208620062802c8032203ad841002024020062802cc03450d00200310350b20250d002026450d00202641306c450d00202410350b024020062802d402450d00202210350b200642e4cab5fbb6ccdcb0e3003703c802200641c8026a20012004200510ea02200641043a0090020b20064180046a200641a0016a41f000109d081a0240024020062d00800422034102470d00200dad422086200cad8410070c010b200641c8036a20064180046a108005200dad422086200cad8420063502d00342208620062802c8032209ad841002024020062802cc03450d00200910350b20030d0020064188046a2802002203450d00200341306c450d0020062802840410350b20062006290091023703c803200620064198026a2800003600cf03410421030b0240200628029401450d00200c10350b200620062903c80337038001200620062800cf0336008701024020034104470d0020064180046a41086a41083a000020064189046a200129000037000020064191046a200141086a29000037000020064199046a200141106a290000370000200641a1046a200141186a290000370000200641a9046a2002290000370000200641b1046a200241086a290000370000200641b9046a200241106a290000370000200641c1046a200241186a290000370000200641063a00800441b0b4cc00410020064180046a10d401200041043a0000200724000f0b200020033a00002000200629038001370001200041086a200628008701360000200724000bc90e0b057f017e017f057e027f057e017f027e017f037e017f230022022103200241e0046b41607122022400200241e0006a2001109605200241d0036a200228026022042002280268220510c90220022d00d0032106200241f0016a200241d0036a41017241ef00109d081a0240024020064102470d004200210720024180016a420037030020024188016a420037030020024190016a420037030020024198016a4200370300200241a0016a4200370300200241a8016a420037030041002108200241b0016a410036020020024108360274200241f0006a41086a4200370300200241003a007042002109410021064200210a4200210b4200210c0c010b200220063a0070200241f0006a410172200241f0016a41ef00109d081a20024190016a290300220d420888a72106200241d0016a2903002109200241a0016a290300210b20024198016a290300210a200241a8016a290300210c200241d8016a280200210e200da72108420021070b200241a8016a4200370300200241f0006a41306a420037030020024198016a420037030020024188016a220f290300210d200f42003703002002410836028403200241003a008003200241003602e00220022903800121102002420037038001200229037821112002420037037820024200370390012002200d370398032002201037039003200220113703880320022903f80221122002200241c8016a220f29030022133703f80220022903f00221142002200241c0016a221529030022163703f00220022903e80221172002200241b8016a221829030022193703e802200229038003210d200220022903702210370380032002200d37037020022903e002211a200220022903b001221b3703e002200f201237030020152014370300201820173703002002201a3703b001200da7210f0240024002402010a741ff017122154101460d00200241e0016a412210e804024020150d002011a72206450d00200641306c450d002010422088a710350b20022d00e00122064104460d01200220022900e1013703f0012002200241e8016a2800003600f701200f41ff01710d0241010d0241010d02200d422088a710350c020b200241c7036a200229009803370000200241c0036a200229009103370300200241b0036a41086a20022900890337030020022002290081033703b003200220083a00cf0302400240200641ff0171450d00200241306a200b42002006ad42ff0183220d4200108408200241c0006a200a4200200d4200108408200241206a42004200200a4200108408427f200241c8006a290300220d200229033020022903207c7c221120022903382002290328844200522011200d547222151b210d427f200229034020151b21110c010b200241106a200a200b420a4200109808200241186a290300210d200229031021110b200241b0036a2011200d200a200b109805200241d0036a41186a4200370300200241d0036a41106a22084200370300200241d0036a41086a22154200370300200242003703d00341d1c4c700ad4280808080e0008410012218290000210d2015201841086a2900003703002002200d3703d0032018103541e7c4c700ad4280808080e0008410012218290000210d200241d0046a41086a221c201841086a2900003703002002200d3703d00420181035200820022903d004220d370300200241f0016a41086a2015290300370300200241f0016a41106a200d370300200241f0016a41186a201c290300370300200220022903d0033703f001200241086a200241f0016a412010c001200228020c211520022802082118200241a8016a200241f0006a41106a200f41ff017141014622081b220f41186a2016370300200f2019370310200f201b370308200f200c370300200241c8016a200241a0016a20081b220f2007201384220d200a200d200a562009200b562009200b511b22081b370300200f2009200b20081b370308200f200e20064118744118754102744184e4cb006a2802004180de346c2015410020181b6a2206200e20064b1b360210200241043a00e0010b200241d0036a200241f0006a41f000109d081a0240024020022d00d00322064102470d002005ad4220862004ad8410070c010b200241f0016a200241d0036a1080052005ad4220862004ad8420023502f80142208620022802f001220fad841002024020022802f401450d00200f10350b20060d00200241d8036a2802002206450d00200641306c450d0020022802d40310350b200220022900e1013703f0012002200241e8016a2800003600f701410421060b02402002280264450d00200410350b200220022903f001370350200220022800f7013600570240024020064104470d00200241d0036a41086a41093a0000200241d0036a41096a2001290000370000200241e1036a200141086a290000370000200241e9036a200141106a290000370000200241f1036a200141186a290000370000200241063a00d00341b0b4cc004100200241d0036a10d4010c010b20002002290350370001200041086a20022800573600000b200020063a0000200324000bb50403047f017e017f230041c0006b22022400200241186a2203200041186a290000370300200241106a2204200041106a290000370300200241086a2205200041086a2900003703002002200029000037030041d9e3cb00ad4280808080900184100122002900002106200241206a41086a200041086a290000370300200220063703202000103541888dc500ad4280808080900184100122002900002106200241306a41086a200041086a29000037030020022006370330200010350240412010332200450d0020002002290300370000200041186a2003290300370000200041106a2004290300370000200041086a2005290300370000412010332203450d0020032000290000370000200341186a2204200041186a290000370000200341106a2205200041106a290000370000200341086a2207200041086a2900003700002000103541c00010332200450d002000200229033037001020002002290320370000200041086a200241206a41086a290300370000200041186a200241306a41086a29030037000020002003290000370020200041286a2007290000370000200041306a2005290000370000200041386a20042900003700002003103520024100360208200242013703002001200210ef04200228020421032000ad4280808080800884200235020842208620022802002204ad84100202402003450d00200410350b20001035024020012d0000450d00200141286a280200450d00200141246a28020010350b200241c0006a24000f0b1045000bb10503027f017e047f230041d0006b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541a4a1c600ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bca1c08077f067e0a7f017e017f057e017f067e23004180046b2204240020044198026a200210f504200441c8026a200428029802220520042802a00210b302200441b8036a41086a220620044188036a290300370300200441b8036a41106a220720044190036a290300370300200441b8036a41186a220820044198036a290300370300200441b8036a41206a2209200441a0036a290300370300200441b8036a41286a220a200441a8036a290300370300200420044180036a2903003703b803200441f8026a290300210b200441c8026a41286a290300210c200441c8026a41206a290300210d200441c8026a41186a290300210e200441c8026a41106a290300210f200441c8026a41086a290300211020042802cc02211120042d00c9022112024020042d00c80222134102460d00200441e8006a41286a200a290300370300200441e8006a41206a2009290300370300200441e8006a41186a2008290300370300200441e8006a41106a2007290300370300200441e8006a41086a2006290300370300200420042903b8033703680b0240200428029c02450d00200510350b20044198016a41286a2205200441e8006a41286a29030037030020044198016a41206a2206200441e8006a41206a29030037030020044198016a41186a2207200441e8006a41186a29030037030020044198016a41106a2214200441e8006a41106a29030037030020044198016a41086a2215200441e8006a41086a2903003703002004200429036837039801200441c8016a2001109605200441c8026a20042802c801221620042802d00110c90220044198026a41026a220120042d00cb023a0000200441b8036a41086a20044194036a290200370300200441b8036a41106a22172004419c036a290200370300200441b8036a41186a2218200441a4036a290200370300200441b8036a41206a2219200441ac036a290200370300200441b8036a41286a221a200441b4036a280200360200200420042f00c9023b01980220042004418c036a2902003703b8030240024020042d00c80222094102470d004200211b4100210a4100211c4200211d4200211e4200211f42002120420021214100212241082108410021090c010b20044180036a2903002121200441f8026a2903002120200441c8026a41286a290300211f200441c8026a41206a290300211e200441c8026a41186a290300211d200441c8026a41106a290300211b20044188036a2802002122200441d4026a280200211c200441c8026a41086a280200210a20042802cc02210820044184026a41026a20012d00003a0000200441d8016a41086a200441b8036a41086a290300370300200441d8016a41106a2017290300370300200441d8016a41186a2018290300370300200441d8016a41206a2019290300370300200441d8016a41286a201a280200360200200420042f0198023b018402200420042903b8033703d8010b20044198026a41286a200529030037030020044198026a41206a200629030037030020044198026a41186a200729030037030020044198026a41106a201429030037030020044198026a41086a2015290300370300200420042903980137039802024002400240024020090d00410021010240024002400240024002400240024002400240201c41014b0d00201c0e020201020b201c2105034020012005410176220620016a22072008200741306c6a28020020024b1b2101200520066b220541014b0d000b0b2008200141306c6a2802002002470d00024002402013410371417f6a220541014b0d0020050e020109010b200441b8036a41286a20044198026a41286a290300370300200441b8036a41206a20044198026a41206a290300370300200441b8036a41186a20044198026a41186a290300370300200441b8036a41106a20044198026a41106a290300370300200441b8036a41086a20044198026a41086a29030037030020042004290398023703b803411d2106024020030d00201c20014d0d032008200141306c6a220541186a2903002123200541106a2903002124024020052d000822074101470d00412021062004200541206a2903002225200541286a2903002226420a4200109808200441106a20242023420a4200109808200c20247d2227200c56200b20237d200c202454ad7d2224200b562024200b511b0d01202720257d2228202756202420267d2027202554ad7d220c202456200c2024511b0d0120102004290310220b7d2224201056200f200441106a41086a2903007d2010200b54ad7d220b200f56200b200f511b0d01200e2004290300220f7d2210200e56200d200441086a2903007d200e200f54ad7d220f200d56200f200d511b0d010c090b200541096a2d00002114024002402005410a6a2d0000220541ff0171450d00200441c0006a202342002005ad42ff018322274200108408200441d0006a2024420020274200108408200441306a4200420020244200108408427f200441d8006a2903002227200429034020042903307c7c2228200429034820042903388442005220282027547222051b2125427f200429035020051b21270c010b200441206a20242023420a4200109808200441286a2903002125200429032021270b41202106200c20247d2228200c56200b20237d200c202454ad7d220c200b56200c200b511b0d000240201441ff01710d00200e20277d2226200e56200d20257d200e202754ad7d2223200d562023200d511b0d0120102124200f210b2026210e2023210d0c080b201020277d2224201056200f20257d2010202754ad7d220b200f56200b200f511b450d070b20044188026a200610e8040c050b201c20014d0d022008200141306c6a22052d00080d07201241ff0171410047200541096a2d00004573450d07200541186a290300210c200541106a290300210f2008200141306c6a410a6a2c00002107200441c8026a41186a4200370300200441c8026a41106a22024200370300200441c8026a41086a22054200370300200442003703c80241d1c4c700ad4280808080e0008410012206290000210b2005200641086a2900003703002004200b3703c8022006103541e7c4c700ad4280808080e0008410012206290000210b200441e8036a41086a2214200641086a2900003703002004200b3703e80320061035200220042903e803220b370300200441b8036a41086a2005290300370300200441b8036a41106a200b370300200441b8036a41186a2014290300370300200420042903c8023703b803200441e0006a200441b8036a412010c0012004280264410020042802601b20074102744184e4cb006a2802004180de346c20116a22054f0d0720030d032021200c2020200f562021200c562021200c511b22061b21212020200f20061b212020222005202220054b1b21220c070b20044188026a411c10e8040c030b2001201c4194c0c6001042000b2001201c41a4c0c6001042000b20044188026a411d10e8040b20042d00880222014104460d0420042004290089023703b803200420044190026a2800003600bf03200a450d05200a41306c450d05200810350c050b024020070d00201441ff01714102460d004200200c201f7d2028201e54ad7d220f2028201e7d2210202856200f200c56200f200c511b22051b210c4200201020051b2128024020144101710d004200200d201d7d200e201b54ad7d220f200e201b7d2210200e56200f200d56200f200d511b22051b210f4200201020051b21100c020b4200200b201d7d2024201b54ad7d220f2024201b7d2210202456200f200b56200f200b511b22051b210b4200201020051b21240b200e2110200d210f0b200441f8026a200c370300200441c8026a41286a2028370300200441c8026a41206a200f370300200441c8026a41186a2010370300200441c8026a41106a200b37030020044180036a20042903b80337030020044188036a200441c0036a29030037030020044190036a200441b8036a41106a29030037030020044198036a200441b8036a41186a290300370300200441a0036a200441b8036a41206a290300370300200441a8036a200441b8036a41286a290300370300200420243703d002200441003a00c802200441e8036a200210f50420042802e8032105200420042802f0033602fc03200420053602f803200441c8026a200441f8036a10f60420042802ec03450d00200510350b201c20014d0d032008200141306c6a2205200541306a201c2001417f736a41306c109e081a201c417f6a211c0b200441043a0088020b20044180036a2021370300200441f8026a2020370300200441c8026a41286a201f370300200441c8026a41206a201e370300200441c8026a41186a201d370300200441c8026a41106a201b37030020044188036a2022360200200441d4026a201c360200200441c8026a41086a200a3602002004418c036a20042903d80137020020044194036a200441d8016a41086a2903003702002004419c036a200441d8016a41106a290300370200200441a4036a200441d8016a41186a290300370200200441ac036a200441d8016a41206a290300370200200441b4036a200441d8016a41286a280200360200200420042f0184023b00c902200420083602cc02200420044184026a41026a2d00003a00cb02200420093a00c8020240024020094102470d0020043502d00142208620042802c8012216ad8410070c010b20043502d001212120042802c8012116200441b8036a200441c8026a10800520214220862016ad8420043502c00342208620042802b8032201ad84100220042802bc03450d00200110350b0240200a450d0020090d00200a41306c450d00200810350b20042004290089023703b803200420044190026a2800003600bf03410421010b024020042802cc01450d00201610350b200420042903b8033703c802200420042800bf033600cf02024020014104460d00200020042903c802370001200041086a20042800cf023600000b200020013a000020044180046a24000f0b2001201c104e000bdb0e08057f027e017f017e027f087e157f067e230041a0026b2205240020052000109605200541306a200528020022062005280208220710c902200541b0016a41026a220020052d00333a000041082108200541e8016a41086a20054190016a290300370300200541e8016a41106a220920054198016a290300370300200520052f00313b01b001200520054188016a2903003703e80120054180016a290300210a200541f8006a290300210b0240024020052d0030220c4102470d004200210d4100210e4100210f4200211042002111420021124200211342002114420021154100210c0c010b200541f0006a2903002115200541e8006a2903002114200541d8006a2903002112200541d0006a2903002111200541c8006a2903002110200541306a41106a290300210d200541e0006a29030021132005413c6a280200210f200541306a41086a280200210e200528023421082005412c6a41026a20002d00003a0000200541106a41086a200541e8016a41086a290300370300200541106a41106a2009290300370300200520052f01b0013b012c200520052903e8013703100b02400240200c4101460d004200201220047d2011200354ad7d2216201120037d2217201156201620125620162012511b22001b21124200201720001b21114200201020027d200d200154ad7d2216200d20017d2217200d56201620105620162010511b22001b21104200201720001b210d200f41306c2200450d01200820006a2118200541e8006a2109200541306a410172221941036a211a200821000340200041306a211b0240200041086a2d00004101710d00200041096a2d0000211c200541a0016a200028020010f504200541306a20052802a001220020052802a801221d10b302200541e8016a41086a221e200941086a221f290000370300200541e8016a41106a2220200941106a2221290000370300200541e8016a41186a2222200941186a2223290000370300200541e8016a41206a2224200941206a2225290000370300200541e8016a41286a2226200941286a222729000037030020052019280000360298022005201a28000036009b02200520092900003703e801200541306a41306a2128200541306a41206a2129200541306a41106a212a024020052d0030222b410247222c450d00202829030021172029290300212d202a290300212e200529035821162005290348212f20052903382130200541b0016a41086a201e290300370300200541b0016a41106a2020290300370300200541b0016a41186a2022290300370300200541b0016a41206a2024290300370300200541b0016a41286a20262903003703002005200528009b023600e30120052005280298023602e001200520052903e8013703b001202b0d004200201720047d2016200354ad7d2231201620037d2232201656203120175620312017511b221e1b211742002032201e1b21160240201c4101710d004200202d20027d202f200154ad7d2231202f20017d2232202f562031202d562031202d511b221e1b212d42002032201e1b212f0c010b4200202e20027d2030200154ad7d2231203020017d22322030562031202e562031202e511b221e1b212e42002032201e1b21300b201920052802e001360000200920052903b001370300202820173703002029202d370300202a202e370300201a20052800e301360000201f200541b0016a41086a2903003703002021200541b0016a41106a2903003703002023200541b0016a41186a2903003703002025200541b0016a41206a2903003703002027200541b0016a41286a290300370300200520163703582005202f370348200520303703382005202b3a003002400240202c0d00201dad4220862000ad8410070c010b2005201d3602ec01200520003602e801200541306a200541e8016a1099050b20052802a401450d00200010350b201b21002018201b470d000c020b0b4200200a20047d200b200354ad7d2216200b20037d2217200b562016200a562016200a511b22001b210a4200201720001b210b4200201520027d2014200154ad7d2216201420017d2217201456201620155620162015511b22001b21154200201720001b21140b20054180016a200a370300200541f8006a200b370300200541f0006a2015370300200541e8006a2014370300200541d8006a2012370300200541d0006a2011370300200541c8006a2010370300200541306a41106a200d370300200541e0006a20133703002005413c6a200f360200200541306a41086a200e36020020054188016a200529031037030020054190016a200541106a41086a29030037030020054198016a200541106a41106a290300370300200520052f012c3b00312005200836023420052005412c6a41026a2d00003a00332005200c3a003002400240200c4102470d002007ad4220862006ad8410070c010b200541e8016a200541306a1080052007ad4220862006ad8420053502f00142208620052802e8012200ad841002024020052802ec01450d00200010350b200c0d00200e450d00200e41306c450d00200810350b02402005280204450d00200610350b200541a0026a24000ba60203027f017e017f230041106b22022400200241003602082002420137030002400240024020002d00004101460d00410110332203450d02200341003a0000200220033602002002428180808010370204200041086a200210a406200235020842208621042002280204452103200228020021000c010b410110332203450d01200341013a000020024281808080103702042002200336020020002d0001210520034101410210372203450d01200320053a00012002428280808020370204200220033602002000280204210520034102410610372200450d01200020053600022002200036020020024286808080e000370204410021034280808080e00021040b200129020020042000ad841002024020030d00200010350b200241106a24000f0b103c000bd21f04067f027e027f017e230041f0006b220624000240024002402002410c6a280200200241106a28020010172207417f460d00410c103322080d010c020b109b05000b200820073602082008428180808010370200200641186a420037030020064280808080c000370310200642043703080240024002400240024002402008280200220741016a220941014d0d00200820093602002007417e460d002008200741026a3602000240200628021c22072006280218470d00200641146a20074101108601200628021c21070b200628021420074102746a20083602002006200628021c41016a36021c2008280208210a200641d0006a41a58ecc0041031050200641206a41a9bbca0041061050200641e4006a200641206a41086a22092802003602002006200629032037025c200641206a41106a220b200641d0006a41106a2903003703002009200641d0006a41086a29030037030020062006290350370320024020062802102207200628020c470d00200641086a20074101109101200628021021070b200628020820074105746a22074101360218200720062903203702002007411c6a200a360200200741106a200b290300370200200741086a20092903003702002006200628021041016a36021020082008280200417f6a2207360200024020070d002008280208101820082008280204417f6a220736020420070d00200810350b200641086a41a88ecc004103411110e604200641086a41c6dfcb00410f411210e604200641086a41d5dfcb004111411310e604200641086a41e6dfcb00410f411410e604200641086a41f5dfcb00410c411510e604200641086a4181e0cb004108411610e604200641086a4189e0cb00410f411710e604200641086a4198e0cb00410d411810e604200641086a41a5e0cb00410a411910e604200641086a41afe0cb00410a411a10e604200641086a41b9e0cb00410b411b10e604200641086a41c4e0cb00410d411c10e604200641086a41d1e0cb00410c411d10e604200641086a41dde0cb00410b411e10e604200641086a41e8e0cb004115411f10e604200641086a41fde0cb00410a412010e604200641086a4187e1cb004107412110e604200641086a418ee1cb004113412210e604200641086a41a1e1cb004115412310e604200641086a41b6e1cb004111412410e604200641086a41c7e1cb00410e412510e604200641086a41d5e1cb004110412610e604200641086a41e5e1cb004110412710e604200641086a41f5e1cb004111412810e604200641086a4186e2cb004111412910e604200641086a4197e2cb004116412a10e604200641086a41ade2cb004112412b10e604200641086a41bfe2cb00410b412c10e604200641086a41cae2cb004110412d10e604200641086a41dae2cb004117412e10e604200641086a41f1e2cb004111412f10e604200641086a4182e3cb004113413010e604200641086a4195e3cb004113413110e604200641086a41a8e3cb004113413210e604200641206a410c6a200441086a280200360200200620033602202006410336023c20062005360238200620083602342006200429020037022420062001280200360230200628021022084105744104722204417f4c0d01200241146a350200210c2002411c6a350200210d20062802082107200410332209450d022006410036025820062004360254200620093602502008200641d0006a10770240024020080d002006280258210820062802542103200628025021090c010b200720084105746a210a034020072802002103200741086a2802002208200641d0006a10770240024020062802542201200628025822046b2008490d00200628025021090c010b200420086a22092004490d06200141017422052009200520094b1b22054100480d060240024020010d00024020050d00410121090c020b200510332209450d0b0c010b2006280250210920012005460d0020092001200510372209450d0a0b20062005360254200620093602500b200920046a20032008109d081a2006200420086a3602582007410c6a2802002105200741146a2802002209200641d0006a10770240024020062802542203200628025822016b2009490d0020062802502104200321080c010b200120096a22082001490d06200341017422042008200420084b1b22084100480d060240024020030d00024020080d00410121040c020b200810332204450d0b0c010b2006280250210420032008460d0020042003200810372204450d0a0b20062008360254200620043602500b200420016a20052009109d081a2006200120096a220936025802400240200741186a2802004101460d000240024020082009460d00200921080c010b200841016a22092008490d08200841017422012009200120094b1b22094100480d080240024020080d0041002108024020090d00410121040c020b200910332204450d0d0c010b20082009460d0020042008200910372204450d0c0b20062009360254200620043602500b200420086a41013a00002006200841016a220836025820062007411c6a2802002201360268200641e8006a21050c010b0240024020082009460d00200921080c010b200841016a22092008490d07200841017422012009200120094b1b22094100480d070240024020080d0041002108024020090d00410121040c020b200910332204450d0c0c010b20082009460d0020042008200910372204450d0b0b20062009360254200620043602500b200420086a41023a00002006200841016a220836025820062007411c6a2802002201360268200641e8006a21050b024002402006280254220420086b4104490d0020062802502109200421030c010b200841046a22092008490d06200441017422012009200120094b1b22034100480d060240024020040d00024020030d00410121090c020b200310332209450d0b0c010b2006280250210920042003460d0020092004200310372209450d0a0b2006200336025420062009360250200528020021010b200920086a20013600002006200841046a2208360258200741206a2207200a470d000b0b02400240024002400240024002404133200d422086200c842008ad4220862009ad84200641206a1019220b41036a220841024b0d004100210120080e03010002010b200628021c220741ffffffff03712007470d0720074102742204417f4c0d07200628021421080240024020040d00410421010c010b200410332201450d090b200641003602582006200136025020062004410276360254200641d0006a410020071086012006280250210e2006280258210102402007450d0020074102742105200e20014102746a210703402008280200220428020041016a220a41014d0d08200841046a21082004200a36020020072004360200200141016a2101200741046a21072005417c6a22050d000b0b2006280254210f02402003450d00200910350b2002350204210c2002350200210d2006410036025820064208370350200641d0006a41004100109a01200628025822084104744104722207417f4c0d072006280254210920062802502104200710332203450d082006410036025820062007360254200620033602502008200641d0006a107702402008450d00200841047421072004210803402008200641d0006a10e504200841106a2108200741706a22070d000b0b2006350258211020062802542103200628025021070240200941ffffffff0071450d00200410350b410a10392208450d08200b200c422086200d8420104220862007ad842008410a200641206a101a41036a220441034b0d024101210520040e0404020203040b410221010b410121054100210a02402003450d00200910350b0c090b41cfa2cc00412841c086cc00103f000b2006410936026c410121052006200841016a36026820082d0000220441014b0d01410421090240024020040e020100010b200641d0006a200641e8006a10e404200628025022094104460d022006280254210a0b410021050b200810352003450d05200710350c050b20081035024020030d000c050b200710350c040b00000b1044000b1045000b103e000b200b101b02402001450d0020014102742107200e21080340200828020022042004280200417f6a3602000240200828020022042802000d0020042802081018200828020022042004280204417f6a360204200828020022042802040d00200410350b200841046a21082007417c6a22070d000b0b0240200f41ffffffff0371450d00200e10350b410221010b200641206a410c6a290200210c200641206a41086a280200210720062802342108200628022421040240024002400240024002400240024002400240200628023c0e0403020001030b20004101360204200041086a4200370200200041106a41003a00000c030b2005450d04200041003a0004200ca72109024020010d00200041b5c1c60036020820004101360200200041186a2009360200200041146a2007360200200041106a20043602002000410c6a41103602000c060b200041c5c1c60036020820004101360200200041186a2009360200200041146a2007360200200041106a20043602002000410c6a41213602000c050b200041003a000420004101360200200041186a200c3e0200200041146a2007360200200041106a20043602002000410c6a4128360200200041086a41fcc0c6003602000c020b200041106a41003a00002000410c6a200641c8006a2802003602002000200641c0006a2903003702040b200041003602002007450d00200410350b20082008280200417f6a220736020020070d032008280208101820082008280204417f6a220736020420070d030c020b0240200941044b0d000240024020090e050102020200010b2000200436020420004100360200200041106a41003a00002000410c6a4100360200200041086a20073602000c020b2000200436020420004100360200200041106a200a3a00002000410c6a200c3e0200200041086a20073602000c010b200041003a000420004101360200200041186a200c3e0200200041146a2007360200200041106a20043602002000410c6a4111360200200041086a41a4c1c6003602000b20082008280200417f6a220736020020070d012008280208101820082008280204417f6a220736020420070d010b200810350b024020062802102207450d00200628020821082007410574210703400240200841046a280200450d00200828020010350b0240200841106a280200450d002008410c6a28020010350b200841206a2108200741606a22070d000b0b0240200628020c41ffffff3f71450d00200628020810350b0240200628021c2207450d0020062802142108200741027421070340200828020022042004280200417f6a3602000240200828020022042802000d0020042802081018200828020022042004280204417f6a360204200828020022042802040d00200410350b200841046a21082007417c6a22070d000b0b0240200628021841ffffffff0371450d00200628021410350b200641f0006a24000f0b103c000b120041b1c6c60041fc0041c086cc00103f000b7201027f230041106b22042400024002402003450d002002280200450d010b41e6c1c60041f40341dcc5c6001064000b2001280210210320012802182105200228020421022004410036020020042002360204200041054104200520032001411c6a200410be051b360200200441106a24000bcb0501067f230041f0006b22042400024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d02410521030240200241246a280200220520012802002802182802402802b4014b0d0020022802042106200241146a2802002107200441186a4200370300200441106a4200370300200441086a420037030020044200370300200128021821022001280210210820044281808080800437034041052103200220082001411c6a2209200441c0006a10be050d00024002402001280214280208200620044120101c41026a220241024b0d0020020e03020001020b41cfa2cc00412841f8a2cc00103f000b20012802102102200128021821082004410136024020042005360244200820022009200441c0006a10be050d002005417f4c0d040240024020050d0041002108410121020c010b200510392202450d06200521080b0240024002402001280214280208200720022005101c41026a220641024b0d0020060e03010002010b41cfa2cc00412841f8a2cc00103f000b2008450d01200210350c010b20012802002101200441206a41186a2206200441186a290300370300200441206a41106a2209200441106a290300370300200441206a41086a2207200441086a290300370300200420042903003703200240200128021822012802402802b40120054f0d002008450d01200210350c010b200441c0006a41186a2006290300370300200441c0006a41106a2009290300370300200441c0006a41086a20072903003703002004200429032037034020042005ad4220862008ad8437026420042002360260200141186a200141d0006a200441c0006a200441e0006a10af04410421030b20002003360200200441f0006a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b1045000b860302037f047e230041f0006b2204240002402003450d0020022802000d0020022802042105200441186a4200370300200441106a4200370300200441086a4200370300200442003703002001280218210320012802102106200442818080808004370340410521020240200320062001411c6a200441c0006a10be050d00024002402001280214280208200520044120101c41026a220341024b0d0020030e03020001020b41cfa2cc00412841f8a2cc00103f000b20012802002101200441206a41186a200441186a2903002207370300200441206a41106a200441106a2903002208370300200441206a41086a200441086a290300220937030020042004290300220a37032020012802182101200441c0006a41186a2007370300200441c0006a41106a2008370300200441c0006a41086a20093703002004200a37034020044100360260200141186a200141d0006a200441c0006a200441e0006a10af04410421020b20002002360200200441f0006a24000f0b41e6c1c60041f40341dcc5c6001064000be60201027f230041306b2204240002402003450d0020022802000d0020022802042105200441186a4200370300200441106a4200370300200441086a420037030020044200370300200128021821022001280210210320044281808080800437032002400240200220032001411c6a200441206a10be050d00024002402001280214280208200520044120101c41026a220241024b0d0020020e03020001020b41cfa2cc00412841f8a2cc00103f000b200441206a2001280200280218220241186a200241d0006a2002410c6a4100200228020c1b2004109104024002402004280220450d00200141046a21020240200141086a280200450d00200228020010350b20022004290320370200200241086a200441206a41086a280200360200410021010c010b2001410c6a4100360200410121010b20004100360200200020013602040c010b200041053602000b200441306a24000f0b41e6c1c60041f40341dcc5c6001064000bdc0802087f027e23004190016b22042400024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320022802042105200241146a2802002106200241246a2802002107200241346a28020021082001280210210220012802182103200441013602482004200636024c02400240200320022001411c6a2209200441c8006a10be050d002006417f4c0d060240024002400240024002400240024020060d004100210a4101210b02402001280214280208200541014100101c41026a220241024b0d00200141146a210520020e03090002090b41cfa2cc00412841f8a2cc00103f000b20061039220b450d04024020012802142802082005200b2006101c41026a220241024b0d00200141146a21052006210a20020e03020001020b41cfa2cc00412841f8a2cc00103f000b41002102200441003a00680240034020062002460d01200441c8006a20026a200b20026a2d00003a00002004200241016a22033a00682003210220034120470d000b200441f0006a41186a2202200441c8006a41186a290300370300200441f0006a41106a2203200441c8006a41106a290300370300200441f0006a41086a2206200441c8006a41086a290300370300200420042903483703700240200a450d00200b10350b200441086a41086a2006290300370300200441086a41106a2003290300370300200441086a41186a2002290300370300200420042903703703082001280210210220012802182103200441013602482004200836024c200320022009200441c8006a10be050d072008417f4c0d0d20080d032005280200280208200741014100101c41026a220241024b0d0220020e03070207070b0240200241ff0171450d00200441003a00680b200a450d060b200b10350c050b41cfa2cc00412841f8a2cc00103f000b200810392202450d0002402005280200280208200720022008101c41026a220341024b0d0020030e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2008410f4d0d00200241086a290000210c2002290000210d200210352001280218210320012802002802182102200441f0006a41186a200441086a41186a290300370300200441f0006a41106a200441086a41106a290300370300200441f0006a41086a200441086a41086a29030037030020042004290308370370200441c8006a41186a200241e8006a290000370300200441c8006a41106a200241e0006a290000370300200441c8006a41086a200241d8006a29000037030020042002290050370348200441286a20034100200441c8006a200441f0006a200d200c200210bf0520042d0028210220004100360200200020024104473602040c020b200210350b200041053602000b20044190016a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000bfb0e04037f017e077f047e230041a0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042105200241146a2802002106200241286a2903002107200241346a2802002108200241c4006a2802002109200241d4006a280200210a200241e4006a280200210b2001280210210220012802182103200441013602682004200636026c02400240200320022001411c6a220c200441e8006a10be050d002006417f4c0d090240024002400240024002400240024020060d004100210d4101210e02402001280214280208200541014100101c41026a220241024b0d00200141146a210520020e03090002090b41cfa2cc00412841f8a2cc00103f000b20061039220e450d04024020012802142802082005200e2006101c41026a220241024b0d00200141146a21052006210d20020e03020001020b41cfa2cc00412841f8a2cc00103f000b41002102200441003a0088010240034020062002460d01200441e8006a20026a200e20026a2d00003a00002004200241016a22033a0088012003210220034120470d000b200441c8006a41186a2202200441e8006a41186a290300370300200441c8006a41106a2203200441e8006a41106a290300370300200441c8006a41086a2206200441e8006a41086a290300370300200420042903683703480240200d450d00200e10350b200441086a41086a2006290300370300200441086a41106a2003290300370300200441086a41186a2002290300370300200420042903483703082001280210210220012802182103200441013602682004200936026c20032002200c200441e8006a10be050d072009417f4c0d1020090d032005280200280208200841014100101c41026a220241024b0d0220020e03070207070b0240200241ff0171450d00200441003a0088010b200d450d060b200e10350c050b41cfa2cc00412841f8a2cc00103f000b200910392202450d0002402005280200280208200820022009101c41026a220341024b0d0020030e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2009410f4d0d00200241086a290000210f20022900002110200210352001280210210220012802182103200441013602682004200b36026c20032002200c200441e8006a10be050d0102400240200b2001410c6a220628020022034b0d00200b21020c010b02400240200141086a280200220220036b200b20036b2205490d002001280204210e200321020c010b200320056a220e2003490d0d20024101742209200e2009200e4b1b22094100480d0d0240024020020d00024020090d004101210e0c020b20091033220e0d010c100b2001280204210e20022009460d00200e200220091037220e450d0f0b2001200e360204200141086a20093602002001410c6a28020021020b200e20026a21090240024020054102490d0020094100200b2003417f7322036a2205109f081a200e200b20026a20036a6a2109200520026a21020c010b2005450d010b200941003a0000200241016a21020b20062002360200024002402001280214280208200a20012802042002101c41026a220241024b0d0020020e03030001030b41cfa2cc00412841f8a2cc00103f000b2001410c6a220228020021094100210520024100360200200141086a280200210220012802042103200142013702042001280218220629030822112112024002402007500d00418002210e2007211220112007540d010b2006201120127d3703082004201237033020042012370328200128020041186a280200210e200441e8006a41186a200441086a41186a290300370300200441e8006a41106a200441086a41106a290300370300200441e8006a41086a200441086a41086a29030037030020042004290308370368200420093602980120042002360294012004200336029001200441c8006a200e200441e8006a2010200f200441286a20044190016a10ef03410121090240024020042802484101470d00200441c8006a41186a280200210c200441dc006a2802002102200441c8006a41106a28020021034100210e0c010b200441c8006a41106a2d0000210e200441d4006a280200210c200441d0006a280200210241002109200428024c21030b2006200429033020062903087c370308200141086a280200210602402009450d00418002210e2006450d01200128020410350c010b02402006450d00200128020410350b200c21050b200120033602042001410c6a2005360200200141086a2002360200200041003602002000200e3602040c020b200210350b200041053602000b200441a0016a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b103e000b103c000b8a1004037f017e077f047e230041b0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042105200241146a2802002106200241286a2903002107200241346a2802002108200241c4006a2802002109200241d4006a280200210a200241e4006a280200210b2001280210210220012802182103200441013602782004200636027c02400240200320022001411c6a220c200441f8006a10be050d002006417f4c0d090240024002400240024002400240024020060d004100210d4101210e02402001280214280208200541014100101c41026a220241024b0d00200141146a210520020e03090002090b41cfa2cc00412841f8a2cc00103f000b20061039220e450d04024020012802142802082005200e2006101c41026a220241024b0d00200141146a21052006210d20020e03020001020b41cfa2cc00412841f8a2cc00103f000b41002102200441003a0098010240034020062002460d01200441f8006a20026a200e20026a2d00003a00002004200241016a22033a0098012003210220034120470d000b200441c8006a41186a2202200441f8006a41186a290300370300200441c8006a41106a2203200441f8006a41106a290300370300200441c8006a41086a2206200441f8006a41086a290300370300200420042903783703480240200d450d00200e10350b200441086a41086a2006290300370300200441086a41106a2003290300370300200441086a41186a2002290300370300200420042903483703082001280210210220012802182103200441013602782004200936027c20032002200c200441f8006a10be050d072009417f4c0d1020090d032005280200280208200841014100101c41026a220241024b0d0220020e03070207070b0240200241ff0171450d00200441003a0098010b200d450d060b200e10350c050b41cfa2cc00412841f8a2cc00103f000b200910392202450d0002402005280200280208200820022009101c41026a220341024b0d0020030e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2009410f4d0d00200241086a290000210f20022900002110200210352001280210210220012802182103200441013602782004200b36027c20032002200c200441f8006a10be050d01200141046a210e02400240200b2001410c6a220628020022034b0d00200b21020c010b02400240200141086a280200220220036b200b20036b2209490d00200e2802002105200321020c010b200320096a22052003490d0d2002410174220c2005200c20054b1b220c4100480d0d0240024020020d000240200c0d00410121050c020b200c103322050d010c100b200e28020021052002200c460d0020052002200c10372205450d0f0b20012005360204200141086a200c3602002001410c6a28020021020b200520026a210c0240024020094102490d00200c4100200b2003417f7322036a2209109f081a2005200b20026a20036a6a210c200920026a21020c010b2009450d010b200c41003a0000200241016a21020b20062002360200024002402001280214280208200a20012802042002101c41026a220241024b0d0020020e03030001030b41cfa2cc00412841f8a2cc00103f000b2001410c6a2202280200210520024100360200200141086a28020021022001280204210320014201370204200128021822062903082211211202400240024002402007500d002007211220112007540d010b2006201120127d3703082004201237037020042012370368200128020041186a2802002109200420053602502004200236024c20042003360248200441f8006a20092010200f200441e8006a200441086a200441c8006a10c005410121050240024020042802784101470d00200441f8006a41186a28020021092004418c016a280200210220044188016a28020021030c010b200441c8006a41086a200441f8006a41186a290300370300200441c8006a41106a20044198016a2802003602002004200441f8006a41106a290300370348200441a8016a2d0000210c2004419c016a290200210720044184016a2802002109200441f8006a41086a280200210241002105200428027c21030b2006200429037020062903087c370308200441286a41086a2206200441c8006a41086a290300370300200441286a41106a2208200441c8006a41106a280200360200200420042903483703282005450d01200141086a280200450d00200e28020010350b200120033602042001410c6a4100360200200141086a200236020041800221020c010b2004418c016a200629030037020020044194016a200828020036020020042009360280012004200236027c2004200336027820042004290328370284010240200141086a280200450d00200e28020010350b200120073702042001410c6a4100360200200c41ff017122020d00200e200441f8006a412010780b20004100360200200020023602040c020b200210350b200041053602000b200441b0016a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b103e000b103c000bf113020b7f047e230022042105200441e00c6b41607122042400024002402003450d0020022802000d00024020034101460d0020022802100d0020022802042106200241146a28020021072001280210210220012802182103200441013602e001200420073602e401200320022001411c6a200441e0016a10be050d0202402007417f4c0d00024002400240024002400240024020070d00410021084101210902402001280214280208200641014100101c41026a220241024b0d0020020e030b00020b0b41cfa2cc00412841f8a2cc00103f000b0240200710392209450d0002402001280214280208200620092007101c41026a220241024b0d002007210820020e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b41002102200441003a0080020240034020072002460d01200441e0016a20026a200920026a2d00003a00002004200241016a22033a0080022003210220034120470d000b200441800a6a41186a2202200441e0016a41186a290300370300200441800a6a41106a2203200441e0016a41106a290300370300200441800a6a41086a2207200441e0016a41086a290300370300200420042903e0013703800a02402008450d00200910350b200441206a41086a2007290300370300200441206a41106a2003290300370300200441206a41186a2002290300370300200420042903800a3703202001280218210a200441c0006a41186a2001280200280218220641e8006a290000370300200441c0006a41106a200641e0006a290000370300200441c0006a41086a200641d8006a29000037030020042006290050370340200628021841016a220b41004c0d052006200b3602182006411c6a220c2802002208450d03200641206a280200210d0340200841086a210320082f0106220e410574210241002107024003402002450d01200441c0006a2003412010a0082209450d05200241606a2102200741016a2107200341206a21032009417f4a0d000b2007417f6a210e0b200d450d04200d417f6a210d2008200e4102746a41880b6a28020021080c000b0b0240200241ff0171450d00200441003a0080020b2008450d080b200910350c070b2008200741e0006c6a220241c5036a310000200241e8026a290300220f200f5022031ba7450d004200200241f8026a29030020031b210f4200200241f0026a29030020031b21100c010b200441106a200641286a280200200441c0006a2006412c6a28020028021c110400200441186a290300210f2006280218210b200429031021100b2006200b417f6a360218024020062802082202450d00200241d0006a2203200441c0006a460d052003200441c0006a412010a008450d05034020022802082202450d01200441c0006a200241d0006a2203460d062003200441c0006a412010a0080d000c060b0b200441e0016a200a4102200441c0006a200441206a2010200f200610bf0520042d00e0014104470d04024020062802180d002006417f360218200441003a009c0120044100360298012004410036029001200441013a007d200441c0016a41186a200441c0006a41186a290300370300200441c0016a41106a200441c0006a41106a290300370300200441c0016a41086a200441c0006a41086a290300370300200420042903403703c001024002400240200628021c2209450d00200641206a280200210d0c010b200441800a6a410041e002109f081a200441e0016a410041a008109f081a41880b10332209450d014100210d200941003b010620094100360200200941086a200441800a6a41e002109d081a200941e8026a200441e0016a41a008109d081a200641206a41003602002006200936021c0b2004200c3602880a200420093602840a2004200d3602800a034020092f0106220b41057421084100210241002103024002400240034020082002460d010240200441c0016a200920026a41086a412010a00822070d0041002102200d21070c030b200241206a2102200341016a21032007417f4a0d000b2003417f6a210b0b200d0d014101210241002107200b21030b200441e0016a41106a2003360200200441ec016a200c360200200441e0016a41086a20093602002004200c3602880a200420093602840a2004200d3602800a200420073602e401200420023602e001024002402002450d00200441a0016a41186a200441c0016a41186a290300220f370300200441a0016a41106a200441c0016a41106a2903002210370300200441a0016a41086a200441c0016a41086a2903002211370300200420042903c00122123703a0012004419c0a6a2011370200200441800a6a41246a2010370200200441ac0a6a200f3702002004200641246a3602900a2004200336028c0a2004200c3602880a200420093602840a200420073602800a200420123702940a200441e0016a41186a4200370300200442003703e00120044198026a20042903980137030020044190026a20042903900137030020044188026a20042903880137030020044180026a200429038001370300200441b8026a2004290378370300200441b0026a2004290370370300200441a8026a2004290368370300200441a0026a2004290360370300200441800a6a200441e0016a1080031a4202210f0c010b2009200341e0006c6a22024190036a20042903880137030020024188036a200429038001370300200241c0036a2004290378370000200241b8036a2004290370370000200241b0036a2004290368370000200241a8036a200429036037000020024180036a4200370300200241e8026a2203290300210f20034200370300200241a0036a22032802002108200320042903980137030020024198036a2202290300211020022004290390013703002010a721092010422088a721030b0240200f4202510d000240024020090d0041002108200441f4016a4100360200200441003602e4010c010b0240024020030d00200921020c010b2003210220092107034020072802ec0321072002417f6a22020d000b200921020340200220022f01064102746a41ec036a28020021022003417f6a22030d000b200721090b200441fc016a20022f0106360200200441f8016a4100360200200441f4016a2002360200200441003602f001200442003703e801200420093602e401200441003602e0010b2004200836028002200441e0016a1081030b2006200628021841016a3602180240200128021c0d00200141246a280200450d00200141206a28020010350b2001410236021c200141206a20042902e001370200200141286a200441e8016a2802003602000c080b200d417f6a210d2009200b4102746a41880b6a28020021090c000b0b103c000b41a797cc004110200441e0016a41c8c1c30041c897cc001046000b41ac96cc004118200441e0016a41d8c1c30041d496cc001046000b1044000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b20004105360200200524000b940501077f230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200241146a2802002102200128021021032001280218210620044103360200200420023602040240200620032001411c6a2207200410be050d0020012802102103200128021821062004410136020020042002360204200620032007200410be050d000240024020022001410c6a220728020022064b0d00200221030c010b02400240200141086a280200220320066b200220066b2208490d0020012802042109200621030c010b200620086a22092006490d052003410174220a2009200a20094b1b220a4100480d050240024020030d000240200a0d00410121090c020b200a103322090d010c080b200128020421092003200a460d0020092003200a10372209450d070b20012009360204200141086a200a3602002001410c6a28020021030b200920036a210a0240024020084102490d00200a410020022006417f7322066a2208109f081a2009200220036a20066a6a210a200820036a21030c010b2008450d010b200a41003a0000200341016a21030b20072003360200024002402001280214280208200520012802042003101c41026a220241024b0d0020020e03020001020b41cfa2cc00412841f8a2cc00103f000b2001410c6a2202280200210320024100360200200141086a280200210220012802042106200142013702040240200128021c0d00200141246a280200450d00200141206a28020010350b2001410036021c200141286a2003360200200141246a2002360200200141206a20063602000b20004105360200200441106a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b103e000b103c000b24002001410c6a4100360200200141046a200128020041206a41201078200041043602000b28002001410c6a4100360200200141046a200128020028021841d0006a41201078200041043602000b5702017f017e230041206b220424002001410c6a41003602002004420110cf04200429030021052004200441086a29030037031820042005370310200141046a200441106a4110107820004104360200200441206a24000b4001017f230041106b220424002001410c6a410036020020042001280218290308370308200141046a200441086a4108107820004104360200200441106a24000ba403020b7f027e230041206b220424002001410c6a410036020002402001280200280218220528021841016a220641004c0d00200141046a2107200541d0006a210820052006360218024002402005411c6a2802002209450d00200541206a280200210a0340200941086a210b20092f0106220c41057421014100210d0240024003402001450d012008200b412010a008220e450d02200141606a2101200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b200a450d02200a417f6a210a2009200c4102746a41880b6a28020021090c010b0b2009200d41e0006c6a220141c5036a310000200141e8026a290300220f200f50220b1ba7450d004200200141f8026a290300200b1b210f4200200141f0026a290300200b1b21100c010b2004200541286a28020020082005412c6a28020028021c110400200441086a290300210f20052802182106200429030021100b20052006417f6a3602182004200f370318200420103703102007200441106a4110107820004104360200200441206a24000f0b41ac96cc004118200441106a41d8c1c30041d496cc001046000b5202027f017e230041106b220424002001410c6a41003602002001280200220529030021062004200541086a29030037030820042006370300200141046a20044110107820004104360200200441106a24000bb60301057f230041206b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d01410521050240200241146a280200220320012802102206280284014b0d0020022802042107200128021821022004410136020020042003360204200220062001411c6a200410be050d002003417f4c0d0302400240024020030d00410021084101210602402001280214280208200741014100101c41026a220241024b0d0020020e03040002040b41cfa2cc00412841f8a2cc00103f000b200310392206450d0602402001280214280208200720062003101c41026a220241024b0d002003210820020e03020001020b41cfa2cc00412841f8a2cc00103f000b2001410c6a410036020020042006200310d503412010332202450d0520022004290300370000200241186a200441186a290300370000200241106a200441106a290300370000200241086a200441086a29030037000041042105200141046a200241201078200210352008450d010b200610350b20002005360200200441206a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b1045000b4001017f230041106b220424002001410c6a410036020020042001280200290310370308200141046a200441086a4108107820004104360200200441106a24000b5a02027f017e230041106b220424002001410c6a410036020020012802002802182802402205290390012106200420054198016a29030037030820042006370300200141046a20044110107820004104360200200441106a24000b5a02027f017e230041106b220424002001410c6a4100360200200128020028021828024022052903a00121062004200541a8016a29030037030820042006370300200141046a20044110107820004104360200200441106a24000bb00601047f230041e0096b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200241146a28020021022001280210210320012802182106200441013602a807200420023602ac07024002400240200620032001411c6a2207200441a8076a10be050d002002417f4c0d0502400240024020020d00410021064101210302402001280214280208200541014100101c41026a220541024b0d0020050e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200210392203450d0002402001280214280208200520032002101c41026a220541024b0d002002210620050e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2004200236020c20042003360208200441a8076a200441086a10b902024020042802a8072202411b460d00200441f8046a200441a8076a41047241ac02109d081a02402006450d00200310350b200441b8026a200441f8046a41ac02109d081a20042002360208200441086a410472200441b8026a41ac02109d081a200441e8046a200441086a10d8032001280210210220012802182103200420042903e8043703b007200441043602a807200320022007200441a8076a10be05450d03200441086a10ba02410521020c040b2006450d010b200310350b410521020c010b20012802002102200441f8046a200441086a41b002109d081a200441c0026a22032002280218220241d8006a290000370300200441c8026a2206200241e0006a290000370300200441d0026a2205200241e8006a290000370300200420022900503703b802200441af076a200441f8046a41b002109d081a02402002413c6a2802002201200241386a280200470d00200241346a20014101109501200228023c21010b2002280234200141d8026c6a220141013a0000200120042903b802370001200141096a2003290300370000200141116a2006290300370000200141196a2005290300370000200141216a200441a8076a41b702109d081a2002200228023c41016a36023c410421020b20002002360200200441e0096a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b9315020c7f027e230041b0036b220424000240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620034107460d0720022802700d0720022802042105200241146a2802002106200241246a2802002107200241346a2802002108200241c4006a2802002109200241d4006a280200210a200241e4006a280200210b200241f4006a280200210c2001280210210220012802182103200441013602b801200420063602bc010240024002400240024002400240200320022001411c6a220d200441b8016a10be050d002006417f4c0d0f02400240024020060d004100210e4101210f02402001280214280208200541014100101c41026a220241024b0d00200141146a210520020e03040002040b41cfa2cc00412841f8a2cc00103f000b20061039220f450d06024020012802142802082005200f2006101c41026a220241024b0d00200141146a21052006210e20020e03020001020b41cfa2cc00412841f8a2cc00103f000b41002102200441003a00d8010240034020062002460d01200441b8016a20026a200f20026a2d00003a00002004200241016a22033a00d8012003210220034120470d000b20044190036a41086a2202200441b8016a41086a29030037030020044190036a41106a2203200441b8016a41106a29030037030020044190036a41186a2206200441b8016a41186a290300370300200420042903b801370390030240200e450d00200f10350b200441086a41086a2002290300370300200441086a41106a2003290300370300200441086a41186a200629030037030020042004290390033703082001280210210220012802182103200441013602b801200420083602bc0120032002200d200441b8016a10be050d132008417f4c0d1120080d044100210f410121062005280200280208200741014100101c41026a220241024b0d0320020e03130305130b0240200241ff0171450d00200441003a00d8010b200e450d010b200f10350b200441c8006a41186a20044190036a41186a290300370300200441c8006a41106a20044190036a41106a290300370300200441c8006a41086a20044190036a41086a2903003703002004200429039003370348410521020c110b41cfa2cc00412841f8a2cc00103f000b200810392206450d0102402005280200280208200720062008101c41026a220241024b0d002008210f20020e030e00010e0b41cfa2cc00412841f8a2cc00103f000b41002102200441003a00d801024002400240034020082002460d01200441b8016a20026a200620026a2d00003a00002004200241016a22033a00d8012003210220034120470d000b20044190036a41086a2202200441b8016a41086a29030037030020044190036a41106a2203200441b8016a41106a29030037030020044190036a41186a2208200441b8016a41186a290300370300200420042903b801370390030240200f450d00200610350b200441286a41086a2002290300370300200441286a41106a2003290300370300200441286a41186a200829030037030020042004290390033703282001280210210320012802182106200441013602b8012004200a3602bc014105210220062003200d200441b8016a10be050d11200a417f4c0d0e200a0d022005280200280208200941014100101c41026a220341024b0d0120030e03110111110b0240200241ff0171450d00200441003a00d8010b200f0d0e0c0f0b41cfa2cc00412841f8a2cc00103f000b200a10392203450d000240200528020028020820092003200a101c41026a220641024b0d0020060e03020003020b41cfa2cc00412841f8a2cc00103f000b1045000b200310350c0c0b0240200a410f4b0d00200310350c0c0b200341086a2900002110200329000021112003103541002102200441003602a00120044201370398010240200c450d0020044190036a41186a210320044190036a41106a210620044190036a41086a210f4101210a03402003420037030020064200370300200f4200370300200442003703900320012802182108200128021021072004428180808080043703b8010240024020082007200d200441b8016a10be050d00024002402005280200280208200b20044190036a4120101c41026a220841024b0d0020080e03020001020b41cfa2cc00412841f8a2cc00103f000b200441b8016a41186a22072003290300370300200441b8016a41106a22092006290300370300200441b8016a41086a220e200f29030037030020042004290390033703b80102402002200428029c01470d0020044198016a20024101108a01200428029801210a20042802a00121020b200a20024105746a220820042903b801370000200841186a2007290300370000200841106a2009290300370000200841086a200e2903003700002004200241016a22023602a001200b41206a2208200b4f0d010b0240200428029c0141ffffff3f71450d00200a10350b410521020c0e0b2008210b200c417f6a220c0d000b0b200441e8006a41086a220220044198016a41086a2206280200360200200420042903980137036820062001280200280218220341d8006a29000037030020044198016a41106a2206200341e0006a29000037030020044198016a41186a2201200341e8006a2900003703002004200329005037039801200441f8006a41086a200441086a41086a290300370300200441f8006a41106a220f200441086a41106a290300370300200441f8006a41186a2208200441086a41186a2903003703002004200429030837037820044190036a41186a2205200441286a41186a29030037030020044190036a41106a220d200441286a41106a29030037030020044190036a41086a200441286a41086a2903003703002004200429032837039003200441d3006a20022802003600002004200429036837004b02402003413c6a2802002202200341386a280200470d00200341346a20024101109501200328023c21020b2003280234200241d8026c6a220241023a0000200220042903980137000120022004290378370021200241096a20044198016a41086a290300370000200241116a2006290300370000200241196a2001290300370000200241296a200441f8006a41086a290300370000200241316a200f290300370000200241396a200829030037000020022011370370200241f8006a20103703002002200429039003370041200241c9006a20044190036a41086a290300370000200241d1006a200d290300370000200241d9006a200529030037000020022004290048370061200241e8006a200441cf006a29000037000020024180016a200441b8016a41d801109d081a2003200328023c41016a36023c410421020c0b0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b200610350b410521020b20002002360200200441b0036a24000b16002000410036020020002001410c6a2802003602040ba50201067f230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d024105210302402001410c6a2802002205200241146a2802002206490d00200520066b200241246a2802002205470d00200228020421072001280204210820012802182102200128021021092004410236020020042005360204200220092001411c6a200410be050d000240024020012802142802082007200820066a2005101d41026a220241024b0d0020020e03020001020b41cfa2cc00412841cca3cc00103f000b410421030b20002003360200200441106a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b820401087f230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200241146a280200210220012802102103200128021821062004410136020020042002360204410521070240200620032001411c6a200410be050d000240024020022001410c6a220828020022064b0d00200221030c010b02400240200141086a280200220320066b200220066b2209490d002001280204210a200621030c010b200620096a220a2006490d052003410174220b200a200b200a4b1b220b4100480d050240024020030d000240200b0d004101210a0c020b200b1033220a0d010c080b2001280204210a2003200b460d00200a2003200b1037220a450d070b2001200a360204200141086a200b3602002001410c6a28020021030b200a20036a210b0240024020094102490d00200b410020022006417f7322066a2209109f081a200a200220036a20066a6a210b200920036a21030c010b2009450d010b200b41003a0000200341016a21030b20082003360200024002402001280214280208200520012802042003101c41026a220141024b0d0020010e03020001020b41cfa2cc00412841f8a2cc00103f000b410421070b20002007360200200441106a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b103e000b103c000bf90803077f017e017f230041d0026b22042400024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d03200241246a2802002105200241346a2802002106024002400240200241146a2802002203450d00200228020421072001280210210820012802182109200441013602082004200336020c41052102200920082001411c6a200441086a10be050d0a2003417f4c0d07200310392208450d08024002402001280214280208200720082003101c41026a220941024b0d0020090e03010003010b41cfa2cc00412841f8a2cc00103f000b200810350c0a0b41012107410021094100210a0c010b200420033602dc01200420083602d801200441086a200441d8016a10c301200441106a2802002109200429020c210b200428020c210a20042802082107200810352007450d082001280210280274200b422088a7490d070b20072009410041202009676b10c105024020094102490d00200721022009210303402002200241206a2208412010a008450d08200821022003417f6a220341024f0d000b0b2001280210210220012802182103200441013602082004200636020c200320022001411c6a2208200441086a10be050d062006417f4c0d040240024020060d0041002102410121030c010b200610392203450d06200621020b0240024002402001280214280208200520032006101c41026a220541024b0d0020050e03010002010b41cfa2cc00412841f8a2cc00103f000b2002450d07200310350c070b200128021021052001280218210c200441086a41086a20063602002004200936020c200441053602080240200c20052008200441086a10be05450d002002450d07200310350c070b2006ad4220862002ad84210b200441a8026a41086a2001280200280218220841d8006a290000370300200441b8026a2201200841e0006a290000370300200441c0026a2206200841e8006a290000370300200420082900503703a80202402008413c6a2802002202200841386a280200470d00200841346a20024101109501200828023c21020b2008280234200241d8026c6a220241003a0000200220042f00cd023b0001200241073a00102002200936000c2002200a36000820022007360004200220042903a802370011200241036a200441cd026a41026a2d00003a0000200241196a200441b0026a290300370000200241216a2001290300370000200241296a2006290300370000200220033600342002200b370038200220042f00a5023b0031200241336a200441a5026a41026a2d00003a0000200241c0006a200441d8016a41c800109d081a20024188016a200441086a41d001109d081a2008200828023c41016a36023c410421020c070b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b1045000b41052102200a41ffffff3f71450d00200710350b20002002360200200441d0026a24000bbd0a03047f027e037f230041d00b6b22042400024002402003450d0020022802000d00024020034101460d0020022802100d0020022802042105200241146a28020021022001280210210620012802182107200441013602502004200236025441052103200720062001411c6a200441d0006a10be050d0202402002417f4c0d00024020020d0002402001280214280208200541014100101c41026a220241024b0d0020020e03050005050b41cfa2cc00412841f8a2cc00103f000b024002400240200210392206450d0002402001280214280208200520062002101c41026a220741024b0d0020070e03020003020b41cfa2cc00412841f8a2cc00103f000b1045000b200610350c040b02402002410f4b0d00200610350c040b200641086a290000210820062900002109200610350240200128020028021822052802180d002005417f360218200441386a200541e8006a290000370300200441306a200541e0006a290000370300200441206a41086a200541d8006a290000370300200420052900503703200240024002402005411c6a220a2802002206450d00200541206a280200210b0c010b4100210b200441f0086a410041e002109f081a200441d0006a410041a008109f081a41880b10332206450d01200641003b010620064100360200200641086a200441f0086a41e002109d081a200641e8026a200441d0006a41a008109d081a200541206a41003602002005200636021c0b2004200a3602f808200420063602f4082004200b3602f008034020062f0106220c41057421074100210241002101024002400240034020072002460d010240200441206a200620026a41086a412010a00822030d0041002102200b21070c030b200241206a2102200141016a21012003417f4a0d000b2001417f6a210c0b200b0d014101210241002107200c21010b200441d0006a41106a2001360200200441dc006a200a360200200441d0006a41086a20063602002004200a3602f808200420063602f4082004200b3602f00820042007360254200420023602504101210302402002450d00200441186a200441206a41186a290300370300200441106a200441206a41106a290300370300200441086a200441206a41086a29030037030020042004290320370300410021030b0240024020030d002004418c096a200441086a29030037020020044194096a200441106a2903003702002004419c096a200441186a2903003702002004200541246a36028009200420013602fc082004200a3602f808200420063602f408200420073602f0082004200429030037028409200441f0006a2004290340370300200441f8006a200441c0006a41086a29030037030020044188016a41003602002004420037036820044200370350200441003a008c0120044100360280012004418d016a200429002037000020044195016a200441206a41086a2900003700002004419d016a200441206a41106a290000370000200441a5016a200441206a41186a290000370000200441003a00ad01200441f0086a200441d0006a10800321020c010b200441e4006a410036020020044100360270200441003602542006200141e0006c6a41e8026a2102200441d0006a1081030b200241286a2008370300200241206a2009370300200242013703182005200528021841016a360218410421030c070b200b417f6a210b2006200c4102746a41880b6a28020021060c000b0b103c000b41a797cc004110200441d0006a41c8c1c30041c897cc001046000b1044000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b20002003360200200441d00b6a24000b7d02027f017e230041306b220424002001410c6a4100360200200441086a2001280200280218220541186a200541d0006a109404200429031021062004200441086a41106a290300427f200428020822051b37032820042006427f20051b370320200141046a200441206a4110107820004104360200200441306a24000be30201047f230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200241146a280200210220012802102106200128021821072004410136020020042002360204410521030240200720062001411c6a200410be050d002002417f4c0d0302400240024020020d00410021074101210602402001280214280208200541014100101c41026a220141024b0d0020010e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200210392206450d0002402001280214280208200520062002101c41026a220141024b0d002002210720010e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2004200620021074024020042802000d00200429020410060b410421032007450d010b200610350b20002003360200200441106a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b4001017f230041106b220424002001410c6a41003602002004200128020028021c36020c200141046a2004410c6a4104107820004104360200200441106a24000bce0502087f017e230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200241146a28020021022001280210210320012802182106200441013602002004200236020402400240200620032001411c6a200410be050d00200141046a21070240024020022001410c6a220828020022064b0d00200221030c010b02400240200141086a280200220320066b200220066b2209490d002007280200210a200621030c010b200620096a220a2006490d062003410174220b200a200b200a4b1b220b4100480d060240024020030d000240200b0d004101210a0c020b200b1033220a0d010c090b2007280200210a2003200b460d00200a2003200b1037220a450d080b2001200a360204200141086a200b3602002001410c6a28020021030b200a20036a210b0240024020094102490d00200b410020022006417f7322066a2209109f081a200a200220036a20066a6a210b200920036a21030c010b2009450d010b200b41003a0000200341016a21030b20082003360200024002402001280214280208200520012802042003101c41026a220241024b0d0020020e03020001020b41cfa2cc00412841f8a2cc00103f000b2001410c6a2202350200210c20024100360200200141086a2203280200210620012802042102200142013702042004200c4220862002ad84100510c20120032802002103024002402004280200450d0002402003450d00200728020010350b20072004290300370200200741086a200441086a280200360200410021012006450d01200210350c010b02402003450d00200728020010350b200120023602042001410c6a4100360200200141086a2006360200410121010b20004100360200200020013602040c010b200041053602000b200441106a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b103e000b103c000bc70402077f037e230041306b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220022802042105200241146a2802002103200241246a280200210620012802102107200128021821082004410136020020042003360204410521020240200820072001411c6a2209200410be050d002003417f4c0d0402400240024020030d00410021084101210702402001280214280208200541014100101c41026a220a41024b0d00200141146a2105200a0e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200310392207450d0002402001280214280208200520072003101c41026a220a41024b0d00200141146a210520032108200a0e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2003ad4220862007ad84101e2203290000210b200341086a290000210c200341106a290000210d200441186a200341186a290000370300200441106a200d370300200441086a200c3703002004200b37030020031035200128021821032001280210210120044282808080800437032002400240200320012009200441206a10be050d0002402005280200280208200620044120101d41026a220141024b0d0020010e03010002010b41cfa2cc00412841cca3cc00103f000b20080d010c020b410421022008450d010b200710350b20002002360200200441306a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000bc70402077f037e230041306b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220022802042105200241146a2802002103200241246a280200210620012802102107200128021821082004410136020020042003360204410521020240200820072001411c6a2209200410be050d002003417f4c0d0402400240024020030d00410021084101210702402001280214280208200541014100101c41026a220a41024b0d00200141146a2105200a0e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200310392207450d0002402001280214280208200520072003101c41026a220a41024b0d00200141146a210520032108200a0e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2003ad4220862007ad84101f2203290000210b200341086a290000210c200341106a290000210d200441186a200341186a290000370300200441106a200d370300200441086a200c3703002004200b37030020031035200128021821032001280210210120044282808080800437032002400240200320012009200441206a10be050d0002402005280200280208200620044120101d41026a220141024b0d0020010e03010002010b41cfa2cc00412841cca3cc00103f000b20080d010c020b410421022008450d010b200710350b20002002360200200441306a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000bc70402077f037e230041306b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220022802042105200241146a2802002103200241246a280200210620012802102107200128021821082004410136020020042003360204410521020240200820072001411c6a2209200410be050d002003417f4c0d0402400240024020030d00410021084101210702402001280214280208200541014100101c41026a220a41024b0d00200141146a2105200a0e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200310392207450d0002402001280214280208200520072003101c41026a220a41024b0d00200141146a210520032108200a0e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2003ad4220862007ad8410092203290000210b200341086a290000210c200341106a290000210d200441186a200341186a290000370300200441106a200d370300200441086a200c3703002004200b37030020031035200128021821032001280210210120044282808080800437032002400240200320012009200441206a10be050d0002402005280200280208200620044120101d41026a220141024b0d0020010e03010002010b41cfa2cc00412841cca3cc00103f000b20080d010c020b410421022008450d010b200710350b20002002360200200441306a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000ba20402077f017e230041206b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220022802042105200241146a2802002103200241246a280200210620012802102107200128021821082004410136021020042003360214410521020240200820072001411c6a2209200441106a10be050d002003417f4c0d0402400240024020030d00410021084101210702402001280214280208200541014100101c41026a220a41024b0d00200141146a2105200a0e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200310392207450d0002402001280214280208200520072003101c41026a220a41024b0d00200141146a210520032108200a0e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2003ad4220862007ad8410042203290000210b200441086a200341086a2900003703002004200b37030020031035200128021821032001280210210120044282808080800237031002400240200320012009200441106a10be050d0002402005280200280208200620044110101d41026a220141024b0d0020010e03010002010b41cfa2cc00412841cca3cc00103f000b20080d010c020b410421022008450d010b200710350b20002002360200200441206a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000bc60304017f017e017f027e230041e0006b22042400200341086a2903002105200328020421060240024002400240024002400240024020032802000e06010203040005010b427f2107200520012903487c220820055a0d050c060b2006ad21080c040b2004200129035042002006ad4200108408427f210720042903084200520d04200429030021080c030b200441106a200129035842002006ad4200108408427f210720042903184200520d03200429031021080c020b200441206a200129031842002006ad4200108408427f210720042903284200520d02200429032021080c010b200441306a200129032842002006ad4200108408200441c0006a20012903204200200542ffffffff0f834200108408427f210720042903484200520d0120042903384200520d012004290340220820042903307c22052008540d01200520012903307c22082005540d010b200821070b200042002000290308220520077d220720072005561b37030841002103024020072005580d00024020022802000d00200241086a280200450d00200228020410350b4101210320024101360200200220042902543702042002410c6a200441dc006a2802003602000b200441e0006a240020030bd30e06017f017e017f017e077f067e230041e0026b2208240020014200200129030822092007280240220a41e8006a200a41e0006a200241ff01714101461b2903007d220b200b2009561b37030802400240200b2009580d00200041003a0000200041086a4122360200200041046a418496ca003602000c010b0240024002400240200728021841016a220c41004c0d00200741186a210d2007200c360218024002402007411c6a280200220e450d00200741206a280200210f0340200e41086a210a200e2f010622104105742101410021110240024003402001450d012003200a412010a0082212450d02200141606a2101201141016a2111200a41206a210a2012417f4a0d000b2011417f6a21100b200f450d02200f417f6a210f200e20104102746a41880b6a280200210e0c010b0b200e201141e0006c6a220141c5036a310000200141e8026a2903002209200950220a1ba7450d004200200141f8026a290300200a1b21094200200141f0026a290300200a1b210b0c010b200841106a200741286a28020020032007412c6a28020028021c110400200841186a29030021092007280218210c2008290310210b0b200d200c417f6a220f3602000240200b20057d2213200b56200920067d200b200554ad7d220b200956200b2009511b4101470d00200041003a0000200041086a411d360200200041046a41a696ca003602000c050b200c41004c0d012007200c36021802400240200728021c220e450d00200741206a280200210c0340200e41086a210a200e2f010622104105742101410021110240024003402001450d012004200a412010a0082212450d02200141606a2101201141016a2111200a41206a210a2012417f4a0d000b2011417f6a21100b200c450d02200c417f6a210c200e20104102746a41880b6a280200210e0c010b0b200e201141e0006c6a220141c5036a310000200141e8026a2903002209200950220a1ba7450d004200200141f8026a290300200a1b21144200200141f0026a290300200a1b21150c010b2008200741286a28020020042007412c6a28020028021c1104002007280218417f6a210f200841086a2903002114200829030021150b200d200f36020042002109024020152014844200520d00200728024022012903900120055820014198016a290300221620065820162006511b0d00200041003a0000200041086a411f360200200041046a41c396ca003602000c050b420021160240200241ff01714102460d00200728024022014198016a290300211620012903900121090b201320097d2217201356200b20167d2013200954ad7d2209200b562009200b511b0d0202402005200684500d00200841b8026a2003108e02200841206a20082802b802220a20082802c002108f02200841d0006a2903004200200829032042015122011b2116200841c8006a290300420020011b2118024020082802bc02450d00200a10350b2018201756201620095620162009511b0d040b0240201520057c22162015542201201420067c2001ad7c220920145420092014511b450d00200041003a0000200041086a412d360200200041046a418997ca003602000c050b024020032004460d0020032004412010a008450d00200d20032013200b10ae04200d20042016200910ae04200841b8026a41086a220a200341086a290000370300200841b8026a41106a2211200341106a290000370300200841b8026a41186a2212200341186a29000037030020084198026a41086a220e200441086a29000037030020084198026a41106a220c200441106a29000037030020084198026a41186a2202200441186a290000370300200820032900003703b802200820042900003703980202402007413c6a2802002201200741386a280200470d00200741346a20014101109501200728023c21010b2007280234200141d8026c6a220141003a0000200120082f00dd023b00012001420037000820014101360004200120082903b8023700112001200829039802370031200141036a200841df026a2d00003a0000200141106a41003a0000200141196a200a290300370000200141216a2011290300370000200141296a2012290300370000200141396a200e290300370000200141c1006a200c290300370000200141c9006a200229030037000020012005370358200141e0006a2006370300200141d4006a20084191026a41036a2800003600002001200828009102360051200120082903f001370368200141f0006a200841f0016a41086a290300370300200141f8006a200841f0016a41106a29030037030020014180016a200841f0016a41186a29030037030020014188016a200841206a41d001109d081a2007200728023c41016a36023c0b200041043a00000c040b41ac96cc004118200841206a41d8c1c30041d496cc001046000b41ac96cc004118200841206a41d8c1c30041d496cc001046000b200041003a0000200041086a4127360200200041046a41e296ca003602000c010b200041830c3b0100200041086a4115360000200041046a41a389c200360000200041026a41013a00000b200841e0026a24000b812f05027f027e087f037e017f230041f00d6b22072400024002400240024002400240024002402001280230200128024022082802b001460d002004420020042903082209200841c0006a2903007d220a200a20095622081b37030820080d02200741106a41186a200141e8006a290000370300200741106a41106a200141e0006a290000370300200741106a41086a200141d8006a29000037030020072001290050370310200741900b6a41186a20063502084220862006350200841009220841186a290000370300200741900b6a41106a200841106a290000370300200741900b6a41086a200841086a290000370300200720082900003703900b200810354120103322080d010c070b200041003a0004200041013602002000410c6a4129360200200041086a41aeb9ca00360200200041106a2006290200370200200041186a200641086a2802003602000c050b20082005290000370000200841186a200541186a290000370000200841106a200541106a290000370000200841086a200541086a2900003700002008412041c00010372208450d05200820072903900b370020200841386a200741900b6a41186a290300370000200841306a200741900b6a41106a290300370000200841286a200741900b6a41086a290300370000200841c00041800110372208450d0520082007290310370040200841d8006a200741106a41186a290300370000200841d0006a200741106a41106a290300370000200841c8006a200741106a41086a290300370000200741f0026a41186a220b2008ad4280808080800c841009220c41186a290000370300200741f0026a41106a220d200c41106a290000370300200741f0026a41086a220e200c41086a2900003703002007200c2900003703f002200c1035200741306a41186a220c200b290300370300200741306a41106a220b200d290300370300200741306a41086a220d200e290300370300200720072903f00237033020081035200741f0006a41d8006a200d290300370300200741d0016a200b290300370300200741d8016a200c2903003703004100210d200741ac016a41003602002007419c016a41d8b9ca0036020020074194016a410036020020072001360278200741f0006a41286a200141186a220f360200200720072903303703c001200742083702a40120074200370388012007410036027c200720012802483602b801200720012903403703b0012007200128023041016a3602a001200129030021092007200128024c3602bc0120072009370370200741f4016a41026a2208200641036a2d00003a0000200720062f00013b01f40120062d0000211020062902042109200741a8026a41186a200541186a290000370300200741a8026a41106a200541106a290000370300200741a8026a41086a200541086a290000370300200720052900003703a8022007410136028801200f200741306a10930421062007200728028801417f6a220c3602880120060d010240200c0d002007417f36028801200741f8016a41186a200741306a41186a290300370300200741f8016a41106a200741306a41106a290300370300200741f8016a41086a200741306a41086a290300370300200720072903303703f80102400240200728028c01220d450d0020074190016a280200210e0c010b4100210e200741900b6a410041e002109f081a200741f0026a410041a008109f081a41880b1033220d450d07200d41003b0106200d4100360200200d41086a200741900b6a41e002109d081a200d41e8026a200741f0026a41a008109d081a20074190016a41003602002007200d36028c010b20072007418c016a22113602980b2007200d3602940b2007200e3602900b0340200d41086a2108200d2f0106221241057421064100210c024002400240024003402006450d010240200741f8016a2008412010a008220b0d0041002106200e21080c030b200641606a2106200c41016a210c200841206a2108200b417f4a0d000b200c417f6a21120b200e0d0141012106410021082012210c0b200741f0026a41106a200c360200200741fc026a2011360200200741f0026a41086a200d360200200720113602980b2007200d3602940b2007200e3602900b200720083602f402200720063602f002024002402006450d00200741d0026a41186a200741f8016a41186a290300220a370300200741d0026a41106a200741f8016a41106a2903002213370300200741d0026a41086a200741f8016a41086a2903002214370300200720072903f80122153703d002200741ac0b6a2014370200200741900b6a41246a2013370200200741bc0b6a200a3702002007200741f0006a41246a3602a00b2007200c36029c0b200720113602980b2007200d3602940b200720083602900b200720153702a40b200741a8036a4100360200200741003a00ac03200742003703f002200741003a00cd03200741003602a0032007420037038803200741900b6a200741f0026a10800321060c010b200d200c41e0006c6a41e8026a21060b200741c0026a290300210a20064201370318200641013a003c200641286a427f370300200641206a427f3703002006413d6a20072903a802370000200641c5006a200741a8026a41086a290300370000200641cd006a200741b8026a290300370000200641d5006a200a370000200720072802880141016a36028801200741f0026a20044101200741106a200741306a20022003200741f0006a10bf05024020072d00f002220d4104460d00200741f0016a41026a20072d00f3023a0000200741ec016a41026a200741f4016a41026a2d00003a0000200720072f00f1023b01f001200720072f01f4013b01ec012009422088a72106200741f0026a41086a280200210420072802f40221052009a721010c080b200741f0026a200520072802b80128020010a306024020072802f0024101470d00200741ec016a41026a200741f4016a41026a2d00003a0000200720072f01f4013b01ec012009422088a72106200741f8026a280200210420072802f40221052009a721014100210d0c080b200741900b6a41186a200741f0026a410472220641186a2802002208360200200741f8016a41106a200641086a290200370300200741f8016a41186a200641106a29020037030020074198026a2008360200200741063602fc01200741ffd5cb003602f801200720062902003703800220072802b40121062007200741f0006a360288032007290370210a20072802bc01210820074198036a200741106a41086a290300370300200741a0036a200741106a41106a290300370300200741a8036a200741106a41186a290300370300200720033703f802200720023703f0022007200836028c032007200a370380032007200729031037039003200720103a00d002200720093702d402200720072f01f4013b00d1022007200741f4016a41026a2d00003a00d302200741900b6a2006200741f8016a200741f0026a200741d0026a2004109a05200741a8026a41026a220620072d00970b3a0000200741cc026a41026a2208200741a30b6a2d00003a0000200720072f00950b3b01a802200720072f00a10b3b01cc02200741900b6a41086a28020021052007419c0b6a280200210e200741900b6a41106a2d0000211020072d00940b2112024002400240024020072802900b4101460d00200741a4026a41026a20062d00003a0000200741a0026a41026a20082d00003a0000200720072f01a8023b01a402200720072f01cc023b01a00220072802880141016a221141004c0d05200720113602880102400240200728028c012204450d00200741f0006a41206a280200210d0340200441086a210820042f0106221641057421064100210c0240024003402006450d01200741306a2008412010a008220b450d02200641606a2106200c41016a210c200841206a2108200b417f4a0d000b200c417f6a21160b200d450d02200d417f6a210d200420164102746a41880b6a28020021040c010b0b2004200c41e0006c6a220641c5036a310000200641e8026a290300220220025022081ba7450d004200200641f8026a29030020081b21024200200641f0026a29030020081b21030c010b2007200728029801200741306a200728029c0128021c110400200741086a29030021022007290300210320072802880121110b20072011417f6a36028801200320072802b00122062903900154200220064198016a29030022035420022003511b0d01200741d0026a41086a2208200741106a41086a290300370300200741d0026a41106a220c200741106a41106a290300370300200741d0026a41186a220b200741106a41186a290300370300200741a8026a41086a2204200741306a41086a290300370300200741a8026a41106a220d200741306a41106a290300370300200741a8026a41186a2211200741306a41186a290300370300200720072903103703d002200720072903303703a802024020072802ac01220620072802a801470d00200741a4016a2006410110950120072802ac0121060b20072802a401200641d8026c6a220641003a0000200620072f00cc023b0001200641013a00102006410036000c20064201370004200620072903d002370011200620072903a802370031200641036a200741cc026a41026a2d00003a0000200641196a2008290300370000200641216a200c290300370000200641296a200b290300370000200641396a2004290300370000200641c1006a200d290300370000200641c9006a201129030037000020064180016a200741bf0b6a290000370000200641f9006a200741b80b6a290000370000200641f1006a200741900b6a41206a290000370000200641e9006a200741900b6a41186a290000370000200641e1006a200741900b6a41106a290000370000200641d9006a200741900b6a41086a290000370000200620072900900b37005120064188016a200741f0026a41d001109d081a200741f0016a41026a2208200741a4026a41026a2d00003a0000200741ec016a41026a220c200741a0026a41026a2d00003a0000200720072802ac0141016a22063602ac01200720072f01a4023b01f001200720072f01a0023b01ec010240200741f8016a41186a280200450d002007418c026a280200103520072802ac0121060b200741ec006a41026a20082d00003a0000200741e8006a41026a200c2d00003a0000200720072f01f0013b016c200720072f01ec013b0168200741f0006a41206a280200210b20072802a801211120072802a40121042007280294012116200728028c01210d0240200728027c2208450d0020074180016a280200450d00200810350b200741900b6a41026a2208200741ec006a41026a2d00003a0000200741f0006a41026a220c200741e8006a41026a2d00003a0000200720072f016c3b01900b200720072f01683b0170201041ff01710d02200720163602f8022007200b3602f4022007200d3602f002200f200741f0026a109504200141346a2001413c6a2208280200200641d8026c220641d8026d220c1095012001280234200828020041d8026c6a20042006109d081a20082008280200200c6a36020002402011450d00201141d8026c450d00200410350b200741e4006a41026a200741900b6a41026a2d00003a0000200741e0006a41026a200741f0006a41026a2d00003a0000200720072f01900b3b0164200720072f01703b01600c030b200741a40b6a2902002102200741f0016a41026a20062d00003a0000200741ec016a41026a20082d00003a0000200720072f01a8023b01f001200720072f01cc023b01ec012002422088a721062002a72101200e21042012210d0c090b200741ec016a41026a200741a4026a41026a2d00003a0000200720072f01a4023b01ec014100210d411e21042005210141fcb9ca00210520122110200e21060c080b200741e4006a41026a20082d00003a0000200741e0006a41026a200c2d00003a0000200720072f01900b3b0164200720072f01703b016002402006450d00200641d8026c210141002106034002400240200420066a22082d0000220c41014b0d0002400240200c0e020001000b0240200841086a28020041ffffff3f71450d00200841046a28020010350b200841106a2d00004107470d02200841386a280200450d02200841346a28020010350c020b200841286a10bb020c010b200841e8006a28020041ffffff3f71450d00200841e4006a28020010350b2001200641d8026a2206470d000b0b02402011450d00201141d8026c450d00200410350b02400240200d0d004100211620074184036a4100360200200741003602f4020c010b02400240200b0d00200d21060c010b200b2106200d2108034020082802880b21082006417f6a22060d000b200d21060340200620062f01064102746a41880b6a2802002106200b417f6a220b0d000b2008210d0b2007418c036a20062f010636020020074188036a410036020020074184036a20063602002007410036028003200742003703f8022007200d3602f402200741003602f0020b2007201636029003200741f0026a108f030b200741d4006a41026a2206200741e4006a41026a2d00003a0000200741d0006a41026a2208200741e0006a41026a2d00003a0000200720072f0164220c3b015c200720072f0160220b3b01582007200c3b01542007200b3b0150200041246a20123a00002000411c6a200741c8006a290300370000200041146a200741c0006a2903003700002000410c6a200741386a29030037000020002007290330370004200041306a20103a00002000412c6a200e360200200041286a2005360200200020072f01543b0025200041276a20062d00003a0000200020072f01503b0031200041336a20082d00003a0000200041003602000c080b200e417f6a210e200d20124102746a41880b6a280200210d0c010b0b41ac96cc004118200741f0026a41d8c1c30041d496cc001046000b41a797cc004110200741f0026a41c8c1c30041c897cc001046000b200041003a0004200041013602002000410c6a412a360200200041086a419abaca00360200200041106a2006290200370200200041186a200641086a2802003602000c030b200741ec016a41026a20082d00003a0000200720072f01f4013b01ec012009422088a721062009a72101419cc1c3002105412a21040c010b20074190026a280200450d002007418c026a28020010350b200741e4006a41026a200741f0016a41026a2d00003a0000200741e0006a41026a200741ec016a41026a2d00003a0000200720072f01f0013b0164200720072f01ec013b01600240200728027c2208450d0020074180016a280200450d00200810350b2006ad210202400240200728028c01220b0d004100210e20074184036a4100360200200741003602f4020c010b200728029401210e0240024020074190016a28020022080d00200b21060c010b20082106200b210c0340200c2802880b210c2006417f6a22060d000b200b21060340200620062f01064102746a41880b6a28020021062008417f6a22080d000b200c210b0b2007418c036a20062f010636020020074188036a410036020020074184036a20063602002007410036028003200742003703f8022007200b3602f402200741003602f0020b200242208621022001ad21032007200e36029003200741f0026a108f03024020072802ac012206450d0020072802a401210b200641d8026c210141002106034002400240200b20066a22082d0000220c41014b0d0002400240200c0e020001000b0240200841086a28020041ffffff3f71450d00200841046a28020010350b200841106a2d00004107470d02200841386a280200450d02200841346a28020010350c020b200841286a10bb020c010b200841e8006a28020041ffffff3f71450d00200841e4006a28020010350b2001200641d8026a2206470d000b0b20022003842102024020072802a8012206450d00200641d8026c450d0020072802a40110350b200741dc006a41026a200741e4006a41026a2d000022063a0000200741d8006a41026a2208200741e0006a41026a2d00003a0000200720072f0164220c3b015c200720072f01603b01582000200d3a00042000200c3b0005200041076a20063a0000200041106a20103a00002000410c6a2004360200200041086a2005360200200041146a200237020020004101360200200020072f01583b0011200041136a20082d00003a00000b200741f00d6a24000f0b103c000bf42003167f037e067f230041c0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110fc062003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200a200a417f6a220d2000200a4105746a2000200d4105746a412010a008220e410048220f1b2210200a41016a2211200d200a200f1b220a200020114105746a2000200a4105746a412010a00841004822111b220a2000200a4105746a200020104105746a412010a00822104100481b210a200c200c417f6a220d2000200c4105746a2000200d4105746a412010a008221241004822131b2214200c4101722215200d200c20131b220c200020154105746a2000200c4105746a412010a00822134100481b220c2000200c4105746a200020144105746a412010a00822144100481b210c200b200b417f6a220d2000200b4105746a2000200d4105746a412010a008221541004822161b2217200b41016a2218200d200b20161b220b200020184105746a2000200b4105746a412010a008220d4100481b220b2000200b4105746a200020174105746a412010a00822164100481b210b41024101200f1b200e411f7620111b2010411f766a2012411f766a2013411f766a2014411f766a2015411f766a200d411f766a2016411f766a210d0b2000200c4105746a2000200a4105746a412010a008220f411f76200d6a2000200b4105746a2000200a200c200f410048220f1b220e4105746a412010a0082210411f766a210d2000200b200e20104100481b220b4105746a2000200c200a200f1b22194105746a412010a008417f4c0d01200b21190c020b2000200110fd060c0f0b200d41016a220d410c490d0002402001410176220b450d00200020014105746a41606a210a2000210c0340200441206a41186a220d200c41186a220f290000370300200441206a41106a220e200c41106a2210290000370300200441206a41086a2211200c41086a22122900003703002004200c290000370320200a41086a2213290000211a200a41106a2214290000211b200a41186a2215290000211c200c200a290000370000200f201c3700002010201b3700002012201a3700002015200d2903003700002014200e29030037000020132011290300370000200a2004290320370000200a41606a210a200c41206a210c200b417f6a220b0d000b0b20012019417f736a21194101210a0c010b200d45210a0b0240200a452009724101710d002000200110fe060d0d0b2002450d02201920014f0d0102402002200020194105746a220a412010a00841004e0d0020002108200121070c040b200441206a41186a2212200041186a220e290000370300200441206a41106a2213200041106a2210290000370300200441206a41086a2214200041086a221129000037030020042000290000370320200a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2000200a290000370000200e201c3700002010201b3700002011201a370000200d2012290300370000200b2013290300370000200c2014290300370000200a2004290320370000200441c0016a41186a2217200e290000370300200441c0016a41106a22182010290000370300200441c0016a41086a22192011290000370300200420002900003703c001200041606a2115200041206a21164100210c2001210b03400240200c200b417f6a220d4f0d002016200c4105746a210a0340200441c0016a200a412010a008417f4c0d01200a41206a210a200d200c41016a220c470d000b200d210c0b2015200b4105746a210a02400340200c200b417f6a220b4f0d01200441c0016a200a412010a008210d200a41606a220f210a200d4100480d000b20122016200c4105746a220a41186a220d2900003703002013200a41106a221d2900003703002014200a41086a22062900003703002004200a290000370320200f41286a221e290000211a200f41306a221f290000211b200f41386a2220290000211c200a200f41206a220f290000370000200d201c370000201d201b3700002006201a37000020202012290300370000201f2013290300370000201e2014290300370000200f2004290320370000200c41016a210c0c010b0b200020042903c001370000200e2017290300370000201020182903003700002011201929030037000002402001200c41016a220a490d002000200a4105746a21002001200a6b220141154f0d010c0c0b0b200a200141e485cc001059000b2019200141d086cc001042000b2007450d010b201920074f0d01200441206a41186a2216200841186a221e290000370300200441206a41106a2217200841106a221f290000370300200441206a41086a2218200841086a222029000037030020042008290000370320200820194105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200441186a2205201e290000370300200441106a2209201f290000370300200441086a2221202029000037030020042008290000370300200841206a21014100211d2007417f6a220d450d022001210a0340200a2004412010a00841004e0d03200a41206a210a200d201d41016a221d470d000b200d211d0c020b4100410041f485cc001042000b20192007418486cc001042000b200820074105746a210c200d210b02400340200c2100200b220a201d4d22060d01200a417f6a210b200041606a220c2004412010a008417f4a0d000b0b0240200a201d490d00200d200a490d0241800121144100210f410021124100210d4100211141800121152001201d4105746a2222210103400240200020016b220a419fc0004b22190d00200a410576220a41807f6a200a2012200f492011200d49220c72220b1b210a0240200b450d002015200a200c1b2115200a2014200c1b21140c010b200a200a41017622156b21140b02402011200d470d00024020150d00200441c0006a220d21110c010b4100210a200441c0006a2211210d2001210c0340200d200a3a0000200d200c2004412010a008417f73411f766a210d200c41206a210c2015200a41016a220a470d000b0b02402012200f470d00024020140d00200441c0016a220f21120c010b200041606a210a4100210c200441c0016a2212210f0340200f200c3a0000200f200a2004412010a008411f766a210f200a41606a210a2014200c41016a220c470d000b0b0240200f20126b220a200d20116b220c200c200a4b1b2213450d002016200120112d00004105746a220a41186a2900003703002017200a41106a2900003703002018200a41086a2900003703002004200a290000370320200120112d00004105746a220a200020122d0000417f734105746a220c290000370000200a41186a200c41186a290000370000200a41106a200c41106a290000370000200a41086a200c41086a290000370000024020134101460d004100210a034020002012200a6a220e2d0000417f734105746a220c20012011200a6a41016a22102d00004105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200120102d00004105746a220c2000200e41016a2d0000417f734105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200a41026a210c200a41016a220b210a200c2013490d000b2012200b6a21122011200b6a21110b200020122d0000417f734105746a220a2004290320370000200a41186a2016290300370000200a41106a2017290300370000200a41086a2018290300370000201241016a2112201141016a21110b200020144105746b20002012200f461b2100200120154105746a20012011200d461b210120190d000b024002402011200d4f0d002000210a034020162001200d417f6a220d2d00004105746a220c41186a220b2900003703002017200c41106a220f2900003703002018200c41086a22002900003703002004200c290000370320200a41606a220a41086a220e290000211a200a41106a2210290000211b200a41186a2212290000211c200c200a290000370000200b201c370000200f201b3700002000201a3700002012201629030037000020102017290300370000200e2018290300370000200a20042903203700002011200d490d000c020b0b2001210a2012200f4f0d000340200f417f6a220f2d0000210c2016200a41186a220b2900003703002017200a41106a220d2900003703002018200a41086a22012900003703002004200a2900003703202000200c417f734105746a220c41086a220e290000211a200c41106a2210290000211b200c41186a2211290000211c200a200c290000370000200b201c370000200d201b3700002001201a3700002011201629030037000020102017290300370000200e2018290300370000200c2004290320370000200a41206a210a2012200f490d000b0b20082004290300370000201e2005290300370000201f2009290300370000202020212903003700002007200a20226b410576201d6a22014d0d032016201e2900003703002017201f2900003703002018202029000037030020042008290000370320200820014105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41206a2100024002402001200c417f6a220c490d002000200c200a200310c105200821000c010b200820012002200310c105200a2102200c21010b200b200d4f2105200141154f0d010c050b0b201d200a419486cc001059000b200a200d419486cc001058000b20012007418486cc001042000b41a486cc00411c41c086cc00103f000b20014102490d00200041606a210f4101210b0340200b410574210a200b417f6a210c200b41016a210b02402000200a6a220a2000200c4105746a220d412010a008417f4a0d00200441c0016a41186a220e200a41186a2210290000370300200441c0016a41106a2211200a41106a2212290000370300200441c0016a41086a2213200a41086a22142900003703002004200a2900003703c001200a200d2900003700002014200d41086a2900003700002012200d41106a2900003700002010200d41186a2900003700004100210d0240200c450d00200f210a03400240200441c0016a200a412010a0084100480d00200c210d0c020b200a41206a200a290000370000200a41386a200a41186a290000370000200a41306a200a41106a290000370000200a41286a200a41086a290000370000200a41606a210a200c417f6a220c0d000b0b2000200d4105746a220a20042903c001370000200a41186a200e290300370000200a41106a2011290300370000200a41086a20132903003700000b200f41206a210f200b2001470d000b0b200441c0026a24000b130020004103360204200041b0c7c6003602000b130020004125360204200041d8c9c6003602000b9e0303077f017e017f230041106b220224000240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002006450d0020042d0001210720012003417e6a22063602042001200441026a3602002006450d0020042d0002210820012003417d6a22063602042001200441036a36020020060d010b200041003602040c010b20042d0003210620012003417c6a3602042001200441046a360200200241086a200110c401024020022802080d002001280204200228020c2204490d002004417f4c0d02024002400240024020040d0042002109410121030c010b200410392203450d0120012802042004490d02200320012802002004109d081a2001280204220a2004490d062001200a20046b3602042001200128020020046a3602002004ad21090b2003450d02200020092004ad4220868437020820002003360204200020074108742005722008411074722006411874723602000c030b1045000b200310350b200041003602040b200241106a24000f0b1044000b2004200a41a4f0cb001059000bc20101047f230041106b220224002000280200220028020821032000280200210041012104200128021841d9a0c00041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d0003402002200036020c20022002410c6a41accfc70010701a200041016a21002003417f6a22030d000b20022d000421050b0240200541ff01710d002002280200220028021841d8a0c00041012000411c6a28020028020c11000021040b200241106a240020040bb70204027f017e027f037e230041106b220224000240024020012802082203ad42287e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510332206450d020b20024100360208200220063602002002200541286e360204200241002003108f012002280208210502402003450d00200341286c21062002280200200541286c6a21030340200141086a2903002104200141106a2903002107200141186a290300210820012903002109200341206a200141206a290300370300200341186a2008370300200341106a2007370300200341086a200437030020032009370300200341286a2103200541016a2105200141286a2101200641586a22060d000b0b20002002290300370200200041086a2005360200200241106a24000f0b1044000b1045000bbc0201057f024002400240200041046a2802002202200041086a28020022036b20012802042204200128020022056b22064f0d00200320066a22052003490d01200241017422042005200420054b1b22054100480d010240024020020d00024020050d00410121040c020b2005103322040d010c040b2000280200210420022005460d0020042002200510372204450d03200041086a28020021030b20002004360200200041046a200536020020012802002105200128020421040b024020052004460d00200028020021042001200541016a360200200420036a20052d00003a0000200341016a2103200128020022052001280204460d0003402001200541016a360200200420036a20052d00003a0000200341016a2103200128020022052001280204470d000b0b200041086a20033602000f0b103e000b103c000bc60303037f017e047f230041a0076b220224002002200110c40102400240024002402002280200450d00200041003602000c010b20022802042203200128020441b0026e2204200420034b1bad42b0027e2205422088a70d012005a72206417f4c0d010240024020060d00410821070c010b200610332207450d030b4100210420024100360210200220073602082002200641b0026e36020c024002402003450d00200241f0046a41047221080340200241f0046a200110b90220022802f0042106200241c4026a200841ac02109d081a2006411b460d02200241186a200241c4026a41ac02109d081a02402004200228020c470d00200241086a2004410110920120022802082107200228021021040b2007200441b0026c6a22092006360200200941046a200241186a41ac02109d081a2002200441016a22043602102003417f6a22030d000b0b20002002290308370200200041086a200241086a41086a2802003602000c010b2000410036020002402004450d00200441b0026c2106200721040340200410bb02200441b0026a2104200641d07d6a22060d000b0b200228020c2204450d00200441b0026c450d00200710350b200241a0076a24000f0b1044000b1045000ba90603067f017e047f230041f0006b22022400200241286a200141146a350200422086200135020c84102710c2010240024020022802282203450d00200241086a2104200141106a2105034002400240200141086a22062802002207200229022c2208422088a722094b0d002001280200220a2003460d01200a2003200710a008450d010b2008a7450d02200310350c020b02402005280200450d00200128020c10350b2001200336020c20052008370200200220032009109c020240024020022d00104102460d00200241186a41086a200441086a280200360200200220042902003703182002280204210b2002280200210c024020012d0018450d002001350214422086200135020c8410070b2001280214220920062802002203490d0102400240200920036b22094108490d00200941786a2107200128020c20036a41086a210a0c010b410021070240410028028cb54c0d0041b0b4cc00210a0c010b410021074100280298b54c21034100280294b54c21094100280290b54c2106200241e500360268200242b48080801037036020024187a1c00036025c20024213370254200241f4a0c0003602502002420037034841b0b4cc00210a200241b0b4cc0036024420024201370338200241eca0c00036023420024113360230200241f4a0c00036022c20024101360228200941aca2c000200641024622061b200241286a200341c4a2c00020061b2802101102000b41002103200241003a00480240034020072003460d01200241286a20036a200a20036a2d00003a00002002200341016a22093a00482009210320094120470d000b20002002290328370000200041186a200241286a41186a290300370000200041106a200241286a41106a290300370000200041086a200241286a41086a2903003700002000200b3602242000200c36022020002002290318370228200041306a200241186a41086a2802003602000c050b0240200341ff0171450d00200241003a00480b200b41ffffff3f71450d00200c10350b200241286a2001350214422086200135020c84102710c201200228022822030d010c020b0b2003200941889aca001059000b200041023a00300b200241f0006a24000bf707040c7f017e047f037e23004190016b220224000240024002400240200141086a220328020022042001410c6a2802002205460d002001280210220628020021072006280208220841014b210903402003200441206a220a360200200241f0006a41186a200441186a290000370300200241f0006a41106a200441106a290000370300200241f0006a41086a200441086a29000037030020022004290000370370410021040240024020090d0020080e020401040b2008210b0340200b410176220c20046a220d20042007200d4105746a200241f0006a412010a0084101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241f0006a412010a0080d02200a2104200a2005470d000b0b2000410036020820004201370200200128020441ffffff3f71450d01200128020010350c010b200241d0006a41086a2204200241f0006a41086a290300370300200241d0006a41106a220b200241f0006a41106a290300370300200241d0006a41186a220c200241f0006a41186a29030037030020022002290370220e3703102002200e37035041201033220f450d01200f2002290350370000200f41186a200c290300370000200f41106a200b290300370000200f41086a200429030037000020024281808080103702042002200f36020020012802042110200128020021110240200a2005460d00410121120340200628020821032006280200210702400340200241f0006a41186a2208200a41186a290000370300200241f0006a41106a2209200a41106a290000370300200241f0006a41086a2201200a41086a2900003703002002200a290000370370200a41206a210a4100210402400240200341014b0d0020030e020301030b2003210b0340200b410176220c20046a220d20042007200d4105746a200241f0006a412010a0084101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241f0006a412010a0080d01200a2005470d000c030b0b200241d0006a41086a2001290300220e370300200241d0006a41106a20092903002213370300200241d0006a41186a20082903002214370300200220022903702215370350200241106a41186a220b2014370300200241106a41106a220c2013370300200241106a41086a220d200e37030020022015370310024020122002280204470d00200220124101108a012002280200210f0b200f20124105746a22042002290310370000200441186a200b290300370000200441106a200c290300370000200441086a200d2903003700002002201241016a2212360208200a2005470d000b0b0240201041ffffff3f71450d00201110350b20002002290300370200200041086a200241086a2802003602000b20024190016a24000f0b1045000baa0704057f017e0a7f027e23004180016b22032400200341306a2001200228020c220411020002400240024002402003280230450d00200341d8006a41106a200341306a41106a290300370300200341d8006a41086a200341306a41086a290300370300200341d8006a41186a200341306a41186a290300370300200341d8006a41206a200341306a41206a280200360200200341106a41086a200341e4006a290200370300200341106a41106a200341ec006a290200370300200341106a41186a200341f4006a290200370300200320032903303703582003200329025c370310200341d8006a200120022802102205110200417f2003280258220641016a220720072006491bad42287e2208422088a70d022008a72206417f4c0d02200610332209450d032009200329031037030020094201370320200941186a200341106a41186a220a290300370300200941106a200341106a41106a220b290300370300200941086a200341106a41086a220c29030037030020034101360208200320093602002003200641286e2207360204200341306a2001200411020002402003280230450d00200341d8006a41047221064102210d41c800210e0340200341d8006a41206a200341306a41206a280200360200200341d8006a41186a220f200341306a41186a290300370300200341d8006a41106a2210200341306a41106a290300370300200341d8006a41086a2211200341306a41086a29030037030020032003290330370358200c200641086a290200370300200b200641106a290200370300200a200641186a29020037030020032006290200370310200f200a2903003703002010200b2903003703002011200c290300370300200320032903103703580240200d417f6a2007470d00200341306a2001200511020020032007417f2003280230221241016a220920092012491b108f01200328020021090b2009200e6a221241606a220720032903583703002011290300210820102903002113200f290300211420124201370300200741186a2014370300200741106a2013370300200741086a20083703002003200d360208200341306a200120041102002003280230450d01200e41286a210e200d41016a210d200328020421070c000b0b2001200228020011030002402002280204450d00200110350b20002003290300370200200041086a200341086a2802003602000c010b2000410036020820004208370200200120022802001103002002280204450d00200110350b20034180016a24000f0b1044000b1045000b1300200041053602042000418cc5c7003602000b130020004106360204200041f0f2c2003602000b130020004102360204200041b8b6c3003602000b130020004105360204200041f489c2003602000b3400200041e3efcb0036020420004100360200200041146a4101360200200041106a4198bfc700360200200041086a42123702000b130020004101360204200041f0bdc7003602000b130020004108360204200041c8aac0003602000b130020004101360204200041d0ebcb003602000b1300200041113602042000418cf9c4003602000b130020004107360204200041a0e0ca003602000b130020004105360204200041d890c2003602000b130020004106360204200041ccc9c7003602000b1300200041013602042000419cbcc7003602000b130020004102360204200041d0b9c7003602000b13002000410236020420004198b8c7003602000b130020004103360204200041d8e4cb003602000b13002000410b360204200041d4aec8003602000b3400200041f1d8cb0036020420004100360200200041146a4105360200200041106a41b8b1c700360200200041086a42093702000b130020004105360204200041a89fc7003602000b1300200041083602042000419492c7003602000b130020004108360204200041c083c7003602000b13002000410636020420004194fec6003602000b130020004103360204200041fc98c8003602000b130020004103360204200041a4c4c4003602000b130020004101360204200041bce8cb003602000b130020004107360204200041fcbac3003602000b13002000410f360204200041dc9dc8003602000b130020004106360204200041dcd8ca003602000b130020004102360204200041e8efc4003602000b130020004102360204200041bc89c5003602000b2e01017f02404104103322020d001045000b20004284808080c000370204200020023602002002418080013600000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241203600000b3a01017f02404110103322020d001045000b20024200370008200242808086bdbacdd21a370000200042908080808002370204200020023602000b3b01017f02404110103322020d001045000b200242003700082002428080a8ec85afd1b101370000200042908080808002370204200020023602000b3901017f02404110103322020d001045000b200242003700082002428080e983b1de16370000200042908080808002370204200020023602000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241083600000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241023600000b2201017f230041106b22022400200241003602002000200210e503200241106a24000bff0101017f230041a0016b22022400200241003a0088012002418080013602800120024280808480800237037820024280c2d72f37036820024280e1eb17370360200242a0c21e370358200242a0c21e370350200242e0ef9720370348200242e0c9dc29370340200242e0ef9720370338200242a0c21e370330200242a0c21e370328200242a0c21e370320200242a0c21e370318200242a0c21e370310200242a0c21e370308200242a0c21e37030020024280808080c000370370200241203602840120024100360298012002420137039001200220024190016a10f305200041086a2002280298013602002000200229039001370200200241a0016a24000bd00301017f230041106b22022400200220002802703602082001200241086a41041078200220002903003703082001200241086a41081078200220002903083703082001200241086a41081078200220002903103703082001200241086a41081078200220002903183703082001200241086a41081078200220002903203703082001200241086a41081078200220002903283703082001200241086a41081078200220002903303703082001200241086a41081078200220002903383703082001200241086a41081078200220002903403703082001200241086a41081078200220002903483703082001200241086a41081078200220002903503703082001200241086a41081078200220002903583703082001200241086a41081078200220002903603703082001200241086a41081078200220002903683703082001200241086a41081078200220002802743602082001200241086a41041078200220002802783602082001200241086a410410782002200028027c3602082001200241086a4104107820022000280280013602082001200241086a41041078200220002d0088013a00082001200241086a4101107820022000280284013602082001200241086a41041078200241106a24000b2d01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241e8073600000b2d01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241e5003600000b3701017f02404110103322020d001045000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000b960202037f017e230041106b2202240020002802102103200041186a28020022042001107720012003200410782002200028021c36020020012002410410780240412010332203450d002003200029002c370000200341186a200041c4006a290000370000200341106a2000413c6a290000370000200341086a200041346a290000370000200120034120107820031035200029030021052002200041086a2903003703082002200537030020012002411010782002200028022036020020012002410410780240024020002802244101460d00200241003a000020012002410110780c010b200241013a000020012002410110782002200041286a28020036020020012002410410780b200241106a24000f0b1045000bf10203037f017e037f230041106b22022400200241003602082002420137030020002d00002103410110332104024002400240024020034101460d002004450d02200441003a0000200220043602002002428180808010370204200041086a200210f705200235020842208621052002280204452104200228020021000c010b2004450d01200441013a0000200220043602002002428180808010370204412010332203450d0220032000290001370000200341186a2206200041196a290000370000200341106a2207200041116a290000370000200341086a2208200041096a29000037000020044101412110372200450d0120002003290000370001200041096a2008290000370000200041116a2007290000370000200041196a200629000037000020022000360200200242a1808080900437020420031035410021044280808080900421050b200129020020052000ad841002024020040d00200010350b200241106a24000f0b103c000b1045000bc90402017f037e23004190016b22042400024002400240024020002d00000e03000102000b200441206a41186a200141186a290000370300200441206a41106a200141106a290000370300200441206a41086a200141086a29000037030020042001290000370320200041016a2003ad4220862002ad84200441206a102041014621000c020b200441206a41186a200141186a290000370300200441206a41106a200141106a290000370300200441206a41086a200141086a29000037030020042001290000370320200041016a2003ad4220862002ad84200441206a101541014621000c010b2003ad4220862002ad84100922022900002105200241086a2900002106200241106a2900002107200441186a200241186a290000370300200441106a2007370300200441086a2006370300200420053703002002103541012102200441206a200041016a200410fa054100210020042d00200d00200441c8006a41206a200441c1006a2d00003a0000200441c8006a41186a200441396a290000370300200441c8006a41106a200441316a290000370300200441c8006a41086a200441296a29000037030020042004290021370348200441c8006aad4280808080900484100922002900002105200041086a2900002106200041106a2900002107200441f0006a41186a200041186a290000370300200441f0006a41106a2007370300200441f0006a41086a200637030020042005370370200010350240200441f0006a2001460d00200441f0006a2001412010a0084521020b200221000b20044190016a240020000bcf0303017f017e037f230041d0006b22032400024020012002102f2204422088a72201450d002004a722052d0000220241014b0d002001417f6a210602400240024020020e020001000b41002101200341003a0049200541016a21070240034020062001460d01200341286a20016a200720016a2d00003a00002003200141016a22023a00492002210120024121470d000b200341106a200341316a290000370300200341186a200341396a290000370300200341206a200341c1006a2900003703002003200329002937030820032d0028210241002106200341086a21010c020b200141ff0171450d02200341003a00490c020b2006450d0120052d0001220241034f0d01200341086a41186a200341286a41186a290000370300200341086a41106a200341286a41106a290000370300200341086a41086a200341286a41086a2900003703002003200329002837030841012106200341086a21010b200020023a0001200020063a0000200041026a20012900003700002000410a6a200141086a290000370000200041126a200141106a2900003700002000411a6a200141186a29000037000020051035200341d0006a24000f0b41b89acc00412e200341286a41c09bcc0041e89acc001046000bd40303017f017e027f230041e0006b22022400024002402000290300220342c000540d00024002400240200342808001540d002003428080808004540d014108200379a741037622046b4104490d022002411320044102746b3a00482001200241c8006a41011078200220002903002203370308200441786a21000340200220033c00482001200241c8006a4101107820034208882103200041016a22042000492105200421002005450d000b200220033703082003500d04200241286a41146a410a360200200241346a4134360200200241106a41146a41033602002002200241086a36024020024180caca00360244200241c8006a41146a410036020020024203370214200241a0b3cc003602102002413436022c200241b0b4cc003602582002420137024c20024188caca003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41b0b4cc00104c000b20022003a74102744101723b01482001200241c8006a410210780c030b20022003a74102744102723602482001200241c8006a410410780c020b41c6c9ca00413641c086cc00103f000b20022003a74102743a00482001200241c8006a410110780b200241e0006a24000bc30101017f230041106b2202240002400240024020002d00004101470d00200041046a280200220041ffff034b0d010240200041ef014b0d00200220003a000b20012002410b6a410110780c030b200241fc013a000b20012002410b6a41011078200220003b01082001200241086a410210780c020b200241ff013a000b20012002410b6a410110782001200041016a412010780c010b200241fd013a000b20012002410b6a410110782002200036020c20012002410c6a410410780b200241106a24000bcb0102017f017e230041106b220224000240024020002d00004101460d00200241003a00002001200241011078200220002d0001410047410774200041026a2d0000723a00002001200241011078200029030821032002200041106a290300370308200220033703000c010b200241013a00002001200241011078200029030821032002200041106a290300370308200220033703002001200241101078200041186a29030021032002200041206a290300370308200220033703000b2001200241101078200241106a24000b960401037f230041106b220224000240024020002d0000417f6a220341044b0d000240024002400240024020030e050001020304000b200241003a000f20012002410f6a41011078200041246a28020021032000412c6a28020022042001107702402004450d002004410574210403402001200341201078200341206a2103200441606a22040d000b0b024020002d00014101460d00200241003a000f20012002410f6a410110780c050b200241013a000f20012002410f6a410110782001200041026a412010780c040b200241013a000f20012002410f6a41011078200041046a280200200110af030c030b200241023a000f20012002410f6a41011078200041046a200110e201200041086a280200200110af030c020b200241033a000f20012002410f6a41011078412010332203450d0220032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a290000370000200120034120107820031035200041246a200110e2012002200041216a2d00003a000f20012002410f6a410110780c010b200241043a000f20012002410f6a41011078412010332203450d0120032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a290000370000200120034120107820031035200041246a200110e2010b200241106a24000f0b1045000b4a01037f230041106b220124002001410036020820014201370300200110ff05200128020421022000200128020022032001280208107802402002450d00200310350b200141106a24000ba50303027f047e017f230041f0006b22032400200341106a20012802002204280210200441186a28020010f4032002ad42808080808004842205100922042900002106200441086a2900002107200441106a2900002108200341206a41186a200441186a290000370300200341206a41106a2008370300200341206a41086a200737030020032006370320200410352003200335021842208620032802102209ad84200341206aad4280808080800484101010c2010240024020032802000d00200041003602000c010b200341c0006a20012802002204280210200428021810f40320051009220441086a2900002106200441106a290000210720042900002108200341d0006a41186a200441186a290000370300200341d0006a41106a2007370300200341d0006a41086a20063703002003200837035020041035200335024842208620032802402204ad84200341d0006aad4280808080800484101302402003280244450d00200410350b20002002360200200020032903003702042000410c6a200341086a2802003602000b02402003280214450d00200910350b200341f0006a24000bf80201067f230041d0006b22022400024002400240410b10332203450d00200341edde91e3063600002003410b411610372204450d0120042001290000370004200441002800acb94836000c2004410f6a41002800afb948360000200241003a00484113210320042105410021060340200241003a0008200241086a200520034100472201109d081a024020030d00200241003a00080b20032001490d03200241286a20066a20022d00083a00002002200641016a22073a0048200320016b2103200520016a21052007210620074120470d000b200241086a41186a2203200241286a41186a290300370300200241086a41106a2201200241286a41106a290300370300200241086a41086a2205200241286a41086a2903003703002002200229032837030820041035200041186a2003290300370000200041106a2001290300370000200041086a200529030037000020002002290308370000200241d0006a24000f0b1045000b103c000b2001200341b89dcc001059000b964603027f017e027f230041106b220224000240024020002d0000220341154b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e16000102030405060708090a0b0c0d0e0f101112131415000b200241003a00002001200241011078200041086a2d0000220341044b0d150240024002400240024020030e050001020304000b200241003a000020012002410110782002200041106a29030037030020012002410810780240200041186a2d0000220341024b0d00024002400240024020030e03000102000b200241003a00000c020b200241013a00000c010b200241023a00000b20012002410110780b2002200041196a2d00003a000020012002410110780c190b200241013a00002001200241011078024002400240024002402000410c6a2d00000e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101107820022000410d6a2d00003a0000200120024101107820022000410e6a2d00003a00000b20012002410110782002200029031837030020012002410810780240200041206a2d0000220341024b0d00024002400240024020030e03000102000b200241003a00000c020b200241013a00000c010b200241023a00000b20012002410110780b2002200041216a2d00003a000020012002410110780c180b200241023a000020012002410110780c170b200241033a000020012002410110782001200041096a412010780c160b200241043a000020012002410110782001200041096a412010780c150b200241013a00002001200241011078200041046a2d0000220341054b0d1402400240024002400240024020030e06000102030405000b200241003a000020012002410110782002200041086a2802003602002001200241041078024002400240024002402000410c6a2d00000e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101107820022000410d6a2d00003a0000200120024101107820022000410e6a2d00003a00000b20012002410110780c190b200241013a000020012002410110780c180b200241023a000020012002410110782001200041056a412010782001200041256a412010782001200041c5006a412010780c170b200241033a000020012002410110782001200041056a412010782002200041e8006a28020036020020012002410410782002200041ec006a28020036020020012002410410782001200041256a412010782001200041c5006a412010780c160b200241043a000020012002410110782001200041056a412010782002200041e8006a28020036020020012002410410782002200041ec006a28020036020020012002410410782001200041256a412010782001200041c5006a412010780240200041f0006a2d00004104460d00200241013a000020012002410110780240024002400240024020002d00700e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a000020012002410110782002200041f1006a2d00003a000020012002410110782002200041f2006a2d00003a00000b20012002410110780c160b200241003a000020012002410110780c150b200241053a000020012002410110782001200041056a412010782002200041e8006a28020036020020012002410410782002200041ec006a28020036020020012002410410782001200041256a412010782001200041c5006a412010780c140b200241023a000020012002410110780240200041046a2d00004101460d00200241003a000020012002410110782001200041056a412010782002200041286a28020036020020012002410410780c140b200241013a000020012002410110782002200041086a28020036020020012002410410780c130b200241033a00002001200241011078200041086a2d0000220341044b0d1202400240024002400240024020030e050001020304000b200241003a000020012002410110782001200041096a41201078200041306a29030021042002200041386a290300370308200220043703000c040b200241013a000020012002410110782001200041096a41201078200041306a29030021042002200041386a290300370308200220043703000c030b200241023a000020012002410110782001200041096a412010782001200041296a41201078200041d0006a29030021042002200041d8006a290300370308200220043703000c020b200241033a000020012002410110782001200041096a41201078200041306a29030021042002200041386a290300370308200220043703002001200241101078200041c0006a29030021042002200041c8006a290300370308200220043703000c010b200241043a000020012002410110782001200041096a41201078200041306a29030021042002200041386a290300370308200220043703000b20012002411010780c120b200241043a0000200120024101107802400240024002400240024002400240200041086a2d00000e080001020304050607000b200241003a0000200120024101107820022000410c6a2802003602002001200241041078200041106a29030021042002200041186a290300370308200220043703002001200241101078200041206a29030021042002200041286a2903003703082002200437030020012002411010780c180b200241013a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c170b200241023a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c160b200241033a0000200120024101107820022000410c6a28020036020020012002410410780c150b200241043a00002001200241011078200041096a2d0000220041024b0d1402400240024020000e03000102000b200241003a000020012002410110780c160b200241013a000020012002410110780c150b200241023a000020012002410110780c140b200241053a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c130b200241063a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c120b200241073a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c110b200241053a00002001200241011078200241003a000020012002410110782002200041046a28020036020020012002410410780c100b200241063a00002001200241011078200041086a2d0000220341104b0d0f0240024002400240024002400240024002400240024002400240024002400240024020030e11000102030405060708090a0b0c0d0e0f10000b200241003a0000200120024101107820022000410c6a2802003602002001200241041078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c1f0b200241013a0000200120024101107820022000410c6a2802003602002001200241041078200041206a29030021042002200041286a290300370308200220043703002001200241101078200041106a2802002103200041186a2802002200200110772000450d1e2000410574210003402001200341201078200341206a2103200041606a22000d000c1f0b0b200241023a000020012002410110780c1d0b200241033a0000200120024101107820022000410c6a2802003602002001200241041078200041096a2d0000220041024b0d1c02400240024020000e03000102000b200241003a000020012002410110780c1e0b200241013a000020012002410110780c1d0b200241023a000020012002410110780c1c0b200241043a0000200120024101107820022000410c6a28020036020020012002410410780c1b0b200241053a0000200120024101107820022000410c6a28020036020020012002410410780c1a0b200241063a0000200120024101107820022000410c6a28020036020020012002410410780c190b200241073a0000200120024101107820022000410c6a28020036020020012002410410782002200041096a2d00003a000020012002410110780c180b200241083a000020012002410110782001200041096a412010782001200041296a412010780c170b200241093a000020012002410110782001200041096a412010780c160b2002410a3a000020012002410110782001200041096a41201078412010332203450d16200341186a200041c1006a290000370000200341106a200041396a290000370000200341086a200041316a2900003700002003200041296a2900003700002001200341201078200310352002200041cc006a28020036020020012002410410780c150b2002410b3a00002001200241011078412010332203450d15200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310352001200041296a41201078200041d0006a29030021042002200041d8006a2903003703082002200437030020012002411010780c140b2002410c3a00002001200241011078412010332203450d14200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310352001200041296a41201078200041d0006a29030021042002200041d8006a2903003703082002200437030020012002411010780c130b2002410d3a00002001200241011078412010332203450d13200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a29000037000020012003412010782003103520022000412c6a28020036020020012002410410780c120b2002410e3a00002001200241011078412010332203450d12200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a29000037000020012003412010782003103520022000412c6a28020036020020012002410410780c110b2002410f3a00002001200241011078412010332203450d11200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310352001200041296a41201078200041f0006a29030021042002200041f8006a2903003703082002200437030020012002411010782001200041c9006a412010780c100b200241103a000020012002410110782001200041096a412010780c0f0b200241073a00002001200241011078200041046a20011083060c0e0b200241083a00002001200241011078200041046a20011083060c0d0b200241093a00002001200241011078200041046a2d0000220341044b0d0c0240024002400240024020030e050001020304000b200241003a00002001200241011078200041086a2802002103200041106a2802002200200110772000450d102003200041306c6a210003402001200341201078200341206a29030021042002200341286a2903003703082002200437030020012002411010782000200341306a2203470d000c110b0b200241013a000020012002410110780c0f0b200241023a000020012002410110782001200041056a412010780c0e0b200241033a000020012002410110782001200041056a412010780c0d0b200241043a000020012002410110782001200041056a412010782001200041256a412010782002200041c5006a2d00003a000020012002410110780c0c0b2002410a3a0000200120024101107820002d0001220041054b0d0b024002400240024002400240024020000e06000102030405000b200241003a00000c050b200241013a00000c040b200241023a00000c030b200241033a00000c020b200241043a00000c010b200241053a00000b20012002410110780c0b0b2002410b3a00002001200241011078200041046a280200220341024b0d0a02400240024020030e03000102000b200241003a00002001200241011078200041086a2802002103200041106a2802002200200110772000450d0c2003200041286c6a2100034020012003412010782002200341206a29030037030020012002410810782000200341286a2203470d000c0d0b0b200241013a000020012002410110780c0b0b200241023a000020012002410110780c0a0b2002410c3a00002001200241011078200041086a2d00002203410a4b0d090240024002400240024002400240024002400240024020030e0b000102030405060708090a000b200241003a0000200120024101107820022000410c6a28020036020020012002410410780c130b200241013a00002001200241011078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c120b200241023a0000200120024101107820022000412c6a2802003602002001200241041078200041306a29030021042002200041386a2903003703082002200437030020012002411010782001200041096a412010780c110b200241033a0000200120024101107820022000410c6a2802003602002001200241041078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c100b200241043a00002001200241011078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c0f0b200241053a00002001200241011078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c0e0b200241063a00002001200241011078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c0d0b200241073a00002001200241011078412010332203450d0d200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310350c0c0b200241083a00002001200241011078412010332203450d0c200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310350c0b0b200241093a00002001200241011078412010332203450d0b200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310352001200041296a41201078200041d0006a29030021042002200041d8006a2903003703082002200437030020012002411010780c0a0b2002410a3a00002001200241011078412010332203450d0a200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310350c090b2002410d3a0000200120024101107802400240024002400240024002400240200041086a2d00000e080001020304050607000b200241003a000020012002410110782001200041096a412010782001200041296a41201078200041d0006a29030021042002200041d8006a2903003703082002200437030020012002411010780c0f0b200241013a000020012002410110782001200041096a412010782001200041296a412010780c0e0b200241023a000020012002410110782001200041096a412010782002200041296a2d00003a000020012002410110780c0d0b200241033a000020012002410110782001200041096a412010782001200041296a41201078412010332203450d0d200341186a200041e1006a290000370000200341106a200041d9006a290000370000200341086a200041d1006a2900003700002003200041c9006a290000370000200120034120107820031035200041f0006a29030021042002200041f8006a2903003703082002200437030020012002411010782002200041e9006a2d00003a000020012002410110780c0c0b200241043a00002001200241011078412010332203450d0c200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310350c0b0b200241053a0000200120024101107820022000410c6a28020036020020012002410410780c0a0b200241063a000020012002410110782001200041096a412010782002200041296a2d00003a000020012002410110780c090b200241073a000020012002410110782001200041096a412010782000412c6a2802002103200041346a28020022002001107720012003200010780c080b2002410e3a00002001200241011078200041046a2d0000220341024b0d0702400240024020030e03000102000b200241003a000020012002410110780240200041086a2d000022034104460d00200241013a000020012002410110780240024002400240024020030e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a000020012002410110782002200041096a2d00003a0000200120024101107820022000410a6a2d00003a00000b20012002410110780c0a0b200241003a000020012002410110780c090b200241013a000020012002410110782001200041056a412010780c080b200241023a000020012002410110782002200041056a2d00003a000020012002410110780c070b2002410f3a00002001200241011078200041046a2d0000220341024b0d0602400240024020030e03000102000b200241003a000020012002410110782001200041056a412010780c080b200241013a000020012002410110780c070b200241023a00002001200241011078200041086a2802002105200041106a2802002200200110772000450d062005200041d0006c6a2106034020012005412010782002200541206a3602002002200110cf012002200541306a3602002002200110cf01200528024021002005280248220320011077200541d0006a210502402003450d00200341306c210303402001200041106a41201078200220003602002002200110cf01200041306a2100200341506a22030d000b0b20062005470d000c070b0b200241103a00002001200241011078200241003a000020012002410110782001200041106a41101078200041046a28020021032000410c6a28020022052001107720012003200510782002200041206a2d00003a000020012002410110780c050b200241113a00002001200241011078200041086a2d0000220341064b0d04024002400240024002400240024020030e0700010203040506000b200241003a000020012002410110782001200041096a412010780c0a0b200241013a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c090b200241023a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c080b200241033a000020012002410110782001200041096a4120107820022000412c6a28020036020020012002410410780c070b200241043a000020012002410110782001200041096a4120107820022000412c6a28020036020020012002410410780c060b200241053a000020012002410110782001200041096a4120107820022000412c6a28020036020020012002410410780c050b200241063a0000200120024101107820022000410c6a28020036020020012002410410780c040b200241123a00002001200241011078200041086a2d00002203410e4b0d0302400240024002400240024002400240024002400240024002400240024020030e0f000102030405060708090a0b0c0d0e000b200241003a000020012002410110782001200041096a412010780c110b200241013a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c100b200241023a000020012002410110782001200041096a41201078200041d0006a29030021042002200041d8006a2903003703082002200437030020012002411010782001200041296a412010780c0f0b200241033a000020012002410110782001200041096a412010780c0e0b200241043a000020012002410110782001200041096a412010780c0d0b200241053a000020012002410110782001200041096a412010780c0c0b200241063a000020012002410110782001200041096a412010782000412c6a2802002103200041346a2802002200200110772000450d0b2000410574210003402001200341201078200341206a2103200041606a22000d000c0c0b0b200241073a000020012002410110782001200041096a412010782002200041296a2d00003a000020012002410110780c0a0b200241083a000020012002410110782001200041096a412010780c090b200241093a000020012002410110782001200041096a412010780c080b2002410a3a000020012002410110782001200041096a412010780c070b2002410b3a000020012002410110782001200041096a412010782001200041296a412010782002200041c9006a2d00003a000020012002410110780c060b2002410c3a000020012002410110782001200041096a412010782002200041296a2d00003a000020012002410110780c050b2002410d3a0000200120024101107820022000410c6a28020036020020012002410410780c040b2002410e3a000020012002410110782001200041096a412010780c030b200241133a0000200120024101107820002d0001220341054b0d02024002400240024002400240024020030e06000102030405000b200241003a00002001200241011078200041026a21000c050b200241013a000020012002410110782001200041026a41201078200041226a21000c040b200241023a000020012002410110782001200041026a412010782001200041226a41201078200041c2006a21000c030b200241033a000020012002410110782001200041026a41201078200041226a21000c020b200241043a000020012002410110782001200041026a41201078200041226a21000c010b200241053a00002001200241011078200041026a21000b20012000412010780c020b200241143a00002001200241011078200041096a21030240200041086a2d00004101460d00200241003a000020012002410110782001200341201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c020b200241013a0000200120024101107820012003412010780c010b200241153a000020012002410110780240200041046a2802004101460d00200241003a000020012002410110782002200041086a28020036020020012002410410780c010b200241013a000020012002410110782002200041086a280200360200200120024104107820022000410c6a280200360200200120024104107802400240200041106a28020022030d00200241003a000020012002410110780c010b200241013a00002001200241011078200041186a28020022052001107720012003200510780b024020002d001c22034104460d00200241013a000020012002410110780240024002400240024020030e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101107820022000411d6a2d00003a0000200120024101107820022000411e6a2d00003a00000b20012002410110780c010b200241003a000020012002410110780b200241106a24000f0b1045000bf70701027f230041106b220224000240024020002d0000220341064b0d00024002400240024002400240024020030e0700010203040506000b200241003a000c20012002410c6a410110782001200041016a412010782002200041c4006a28020036020c20012002410c6a41041078412010332203450d07200341186a200041396a290000370000200341106a200041316a290000370000200341086a200041296a2900003700002003200041216a2900003700002001200341201078200310352002200041c8006a28020036020c20012002410c6a410410780c060b200241013a000c20012002410c6a410110782001200041016a41201078412010332203450d06200341186a200041396a290000370000200341106a200041316a290000370000200341086a200041296a2900003700002003200041216a2900003700002001200341201078200310352002200041c1006a2d00003a000c20012002410c6a410110782002200041c4006a28020036020c20012002410c6a410410782002200041c8006a28020036020c20012002410c6a410410780c050b200241023a000c20012002410c6a41011078412010332203450d0520032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201078200310350c040b200241033a000c20012002410c6a41011078412010332203450d0420032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201078200310350c030b200241043a000c20012002410c6a41011078412010332203450d0320032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201078200310352002200041216a2d00003a000c20012002410c6a410110780c020b200241053a000c20012002410c6a41011078412010332203450d0220032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201078200310352002200041216a2d00003a000c20012002410c6a410110780c010b200241063a000c20012002410c6a41011078412010332203450d0120032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201078200310352002200041246a28020036020c20012002410c6a410410782002200041286a28020036020c20012002410c6a410410780b200241106a24000f0b1045000b4d01017f230041206b22002400200041146a410136020020004201370204200041e8d4ca003602002000410436021c2000419cd5ca003602182000200041186a360210200041b0b4cc00104c000bec220a017f017e037f017e037f017e047f017e077f047e230041e0016b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280200417f6a0e0a00010203040506070809000b420021042000420037030820022d000120022d000041004772450d18200041186a41023602000c170b200141086a280200210520012802042101024020022d00000d0020022d000141ff01714101470d002005450d09200110350c090b02402005450d00200110350b20004200370308200041186a41023602000c160b024020022d000120022d0000410047720d00200141086a2903002104410810332201450d0b2001200437000041de92c800ad4280808080a001842001ad42808080808001841002200110350c080b20004200370308200041186a41023602000c150b200141086a280200210520012802042106024020022d000120022d000041004772450d00410221070c140b200341b0016a2001410c6a280200ad22044220862006ad220884102510c20120032802b0012201450d1220032802b40121022003200341b8016a2802003602ac01200320013602a801200341186a200341a8016a10c40120032802180d1120032802ac012209200328021c220a490d11200a417f4c0d0a02400240200a0d0041002109410121070c010b200a10392207450d0a200720032802a801220b200a109d081a20032009200a6b3602ac012003200b200a6a3602a801200a21090b2007450d11200341106a200341a8016a10c401200aad4220862009ad84220ca7210920032802100d0f20032802ac01220a2003280214220b490d0f200b417f4c0d0a02400240200b0d004100210b4101210d0c010b200b1039220d450d0a200d20032802a801220e200b109d081a2003200a200b6b220a3602ac012003200e200b6a3602a8010b200d450d0f02400240024002400240200a4104490d00200320032802a801220e41046a3602a8012003200a417c6a220f3602ac01200f4104490d012003200e41086a3602a801200e28000421102003200a41786a220f3602ac01200f4104490d032003200a41746a3602ac012003200e410c6a3602a801200341086a200341a8016a10c4012003280208450d020c130b0240200b450d00200d10350b20090d140c150b0240200b450d00200d10350b20090d130c140b200328020c220e20032802ac01410c6e220a200a200e4b1bad420c7e2211422088a70d0c2011a7220f417f4c0d0c02400240200f0d00410421120c010b200f10332212450d0c0b4100210a20034100360228200320123602202003200f410c6e36022402400240200e450d000340200341d0016a200341a8016a10ee0220032d00d0014101460d0220032802ac01220f4104490d0220032900d101211120032802a801221328000021142003200f417c6a3602ac012003201341046a3602a8010240200a2003280224470d00200341206a200a4101108701200328022021122003280228210a0b2012200a410c6c6a220f2014360208200f20113702002003200a41016a220a360228200e417f6a220e0d000b0b2012450d112003290224a7210e20032802ac0141044f0d020240200e450d00200e410c6c450d00201210350b0240200b450d00200d10350b2009450d140c130b2003280224220a450d10200a410c6c450d10201210350c100b0240200b450d00200d10350b20090d110c120b200c422088a7210f02402002450d00200110350b41b5c3c700210a410f210241002101200f4104470d0d024020074190e1c600460d00200728000041eede91ab06470d0e0b0240201041f6014f0d00419bc3c700210a411a2102410121010c0e0b02402009450d00200710350b0240200b450d00200d10350b0240200e450d00200e410c6c450d00201210350b41e892c800ad4280808080d0008420044220862008841002200341286a41023a0000200341003a002041b0b4cc004100200341206a10d4012005450d06200610350c060b200141086a280200210520012802042106024020022d000120022d0000410047720d0041e892c800ad4280808080d000842001410c6a3502004220862006ad841002200341206a41086a41023a0000200341003a002041b0b4cc004100200341206a10d4012005450d06200610350c060b02402005450d00200610350b20004200370308200041186a41023602000c130b20022d000120022d0000410047720d0a2001410c6a2802002105200141086a280200210702400240200128020422094101460d0041ed92c800ad4280808080d0018410070c010b410410332201450d0a2001200736000020014104410810372201450d0a2001200536000441ed92c800ad4280808080d001842001ad42808080808001841002200110350b200341206a41186a4200370300200341206a41106a22064200370300200341206a41086a220142003703002003420037032041d1c4c700ad4280808080e000841001220229000021042001200241086a29000037030020032004370320200210354185c5c700ad4280808080e00084100122022900002104200341d0016a41086a220a200241086a290000370300200320043703d00120021035200620032903d0012204370300200341b0016a41086a2001290300370300200341b0016a41106a2004370300200341b0016a41186a200a290300370300200320032903203703b001200341206a200341b0016a10ce0202400240200328022022060d004100210a200341003602d801200342043703d00141042106410021020c010b2003200329022422043702d401200320063602d0012004422088a721022004a7210a0b200341a8016a41026a220b200341a5016a41026a2d00003a0000200341206a41086a220d200341b0016a41086a290200370300200341206a41106a220e200341b0016a41106a280200360200200320032f00a5013b01a801200320032902b00137032002402002200a470d00200341d0016a200a4101108d0120032802d401210a20032802d001210620032802d80121020b2006200241246c220f6a220141043a00002001200536020c2001200736020820012009360204200141036a200b2d00003a0000200120032f01a8013b000120012003290320370210200141186a200d290300370200200141206a200e2802003602002003200241016a22013602d80141d1c4c700ad4280808080e0008410012205290000210420052900082108200510354185c5c700ad4280808080e0008410012205290000210c2005290008211120051035200320113701382003200c3701302003200837012820032004370120200341203602ac012003200341206a3602a80120062001200341a8016a109606024020012002490d00200f41246a21022006210103400240024020012d0000220541044b0d0002400240024020050e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012002415c6a22020d000b0b200a450d04200a41246c450d04200610350c040b2001410c6a2802002105200141086a28020021062001280204210a024020022d000120022d0000410047720d000240200541186c2201450d00200a20016a2102200a21010340200141086a350200422086200135020084200141146a3502004220862001410c6a350200841002200141186a22012002470d000b0b02402005450d00200541186c2102200a210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141186a2101200241686a22020d000b0b2006450d04200641186c450d04200a10350c040b02402005450d00200541186c2102200a210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141186a2101200241686a22020d000b0b02402006450d00200641186c450d00200a10350b20004200370308200041186a41023602000c110b2001410c6a2802002105200141086a28020021062001280204210a024020022d000120022d0000410047720d0002402005410c6c2201450d00200a20016a2102200a21010340200141086a35020042208620013502008410072001410c6a22012002470d000b0b02402005450d002005410c6c2102200a210103400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b2006450d032006410c6c450d03200a10350c030b02402005450d002005410c6c2102200a210103400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b02402006450d002006410c6c450d00200a10350b20004200370308200041186a41023602000c100b200141086a280200210520012802042106024020022d000120022d0000410047720d002001410c6a3502004220862006ad8410082005450d02200610350c020b02402005450d00200610350b20004200370308200041186a41023602000c0f0b4102210120022d00000d014101210520022d00014101470d012002411a6a2901002104200241196a2d00002101200241186a2d00002106200241166a2f0100210a200241156a2d00002107200241146a2d00002109200241126a2f0100210b200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021132002410c6a2d000021142002410a6a2f01002112200241086a2d00002110200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a0027200320103a0026200320153b0124200320163a0023200320173a0022200320183b01202003200d3a002f2003200e3a002e2003200f3b012c200320133a002b200320143a002a200320123b0128200320013a0037200320063a00362003200a3b0134200320073a0033200320093a00322003200b3b013020032004370138200341b0016a41186a2004370300200341b0016a41106a2003290130370300200341b8016a2003290128370300200320032901203703b001200341d0016a200341b0016a108e02200341206a20032802d001220120032802d801108f0242002104420021084200210c42002111420021194200211a4200211b4200211c024020032903204201520d0020032d006c452105200341206a41106a290300211c200341c0006a2903002108200341206a41186a2903002104200341d0006a2903002111200341c8006a290300210c200341e0006a290300211a200341d8006a29030021192003290328211b0b024020032802d401450d00200110350b024020050d0041dcc2c7002102410f2105418080102106410321010c030b0240200c200484201984201b842011200884201a84201c8484500d0041ebc2c7002102411321054180800c2106410321010c030b200341206a41186a200341b0016a41186a290300370300200341206a41106a200341b0016a41106a290300370300200341206a41086a200341b0016a41086a290300370300200320032903b001370320200341d0016a200341206a10ed0320033502d80142208620032802d0012201ad84100720032802d401450d00200110350b42002104200042003703080c0e0b410021060b20004200370308200041206a20053602002000411c6a2002360200200041186a20064180801c712001723602000c0b0b1045000b1044000b103c000b20004200370308200041186a41023602000c070b02402009450d00200710350b0240200b450d00200d10350b41032107200e450d05200e410c6c450d05201210350c050b200b450d00200d10350b2009450d010b200710350b2002450d00200110350b4103210741fec2c700210a411d2102410221010b200141ff0171411074210102402005450d00200610350b20004200370308200041206a20023602002000411c6a200a360200200041186a20012007723602000b420121040b20002004370300200341e0016a24000b971f03077f037e127f230041a0036b22042400200128020821052001280204210620012802002107410221080240024002400240024002400240200241ff01710d00200341ff01714102470d002005410a4b0d0120044188016a41186a2209420037030020044188016a41106a220a420037030020044188016a41086a2202420037030020044200370388014193d1cb00ad4280808080a00184220b10012203290000210c20044180036a41086a2201200341086a2900003703002004200c370380032003103520022001290300370300200420042903800337038801419dd1cb00ad4280808080c00184220d10012203290000210c2001200341086a2900003703002004200c3703800320031035200a200429038003220c370300200441206a41086a220e2002290300370300200441206a41106a220f200c370300200441206a41186a221020012903003703002004200429038801370320200441206a10bd02220341ff01714102460d02410321082003410171450d020b419fc8ca0021114110210f410121122005450d030c020b4192c8ca002111410d210f41032108410221120c010b20094200370300200a4200370300200242003703002004420037038801200b10012203290000210c2001200341086a2900003703002004200c370380032003103520022001290300370300200420042903800337038801200d10012203290000210c2001200341086a2900003703002004200c3703800320031035200a200429038003370000200a41086a2001290300370000200e2002290300370300200f200a290300370300201020092903003703002004200429038801370320200441013a008801200441206aad4280808080800484220d20044188016aad42808080801084100220044180036a41186a2208420037030020044180036a41106a2213420037030020014200370300200442003703800341d1c4c700ad4280808080e0008410012202290000210c2001200241086a2900003703002004200c370380032002103541e7c4c700ad4280808080e0008410012203290000210c200441f0026a41086a2202200341086a2900003703002004200c3703f00220031035201320042903f002220c370300200441d0026a41086a22092001290300370300200441d0026a41106a220e200c370300200441d0026a41186a220f200229030037030020042004290380033703d002200441086a200441d0026a412010c001200428020c2110200428020821142008420037030020134200370300200142003703002004420037038003200b10012203290000210b2001200341086a2900003703002004200b370380032003103541e0caca00ad4280808080e0008410012203290000210b2002200341086a2900003703002004200b3703f00220031035201320042903f002220b37030020092001290300370300200e200b370300200f200229030037030020042004290380033703d00220044188016a200441d0026a10b6020240024020042802880122150d0020044100360218200442043703104104211541002102410021010c010b2004200429028c01220b37021420042015360210200b422088a72102200ba721010b2010410020141b2103024020022001470d00200441106a20024101109f0120042802102115200428021821020b2015200241c4006c6a220141003a000020012003360204200141036a200441206a41026a2d00003a0000200120042f00203b00012001200429028801370208200141106a20044188016a41086a2216290200370200200141186a20044188016a41106a2217290200370200200141206a20044188016a41186a290200370200200141286a20044188016a41206a290200370200200141306a20044188016a41286a290200370200200141386a20044188016a41306a290200370200200141c0006a20044188016a41386a2802003602002004200241016a22183602182007200541f0006c22016a211902400240024020050d00200721080c010b200741f4006a2109200141907f6a210e41d1c4c700ad4280808080e00084210c20072108024003402008280204211a2008280200210320044188016a200841086a41e800109d081a200841f0006a2108201a450d02200441206a20044188016a41e800109d081a2004201a36028c0120042003360288012016200441206a41e800109d081a20044180036a41186a221b420037030020044180036a41106a221c420037030020044180036a41086a221042003703002004420037038003200c10012201290000210b2010200141086a2900003703002004200b370380032001103541e7c4c700ad4280808080e0008410012201290000210b200441f0026a41086a2202200141086a2900003703002004200b3703f00220011035201320042903f002370000201341086a2002290300370000200441d0026a41086a221d2010290300370300200441d0026a41106a221e201c290300370300200441d0026a41186a221f201b29030037030020042004290380033703d0022004200441d0026a412010c0012004280200210120042802042102200441d0026a20044188016a10d003410c210f024020030d00410321124186c8ca0021110c020b024020032002410020011b22014d0d004104211241fac7ca0021110c020b20044180036a2003417f6a10d103024020044180036a2017412010a008450d004100211241afc8ca0021114112210f0c020b0240200341002001417b6a2202200220014b1b4f0d004106211241dec7ca0021114108210f0c020b0240024020152015201841c4006c22026a460d00201541016a2101034002402001417f6a2d00004101470d0041012114200441d0026a2001460d032001200441d0026a412010a008450d030b200141c4006a2101200241bc7f6a22020d000b0b410021140b20044180036a200310d10320044180036a200441d0026a412010a00821014105211241e6c7ca0021114114210f20140d012001450d01200441f8016a41086a220f200441b0026a41086a2202290200370300200441f8016a41106a2214200441b0026a41106a22032f01003b0100200420042f018e023b018c02200420042902b0023703f80120044190026a20044188016a10d003200441b0026a41186a221142003703002003420037030020024200370300200442003703b002201f4200370300201e4200370300201d4200370300200442003703d002024041c80010332201450d0020044180036a10d004200141186a201b290300370200200141106a201c290300370200200141086a201029030037020020012004290380033702002001410236022020014101360244200120042903d0023700242001412c6a201d290300370000200141346a201e2903003700002001413c6a201f290300370000200420013602f00220044282808080203702f402200441f0026a10ab01201b2011290300370300201c200329030037030020102002290300370300200420042903b0023703800320044180036a10d304201020044190026a41086a290300370300201c20044190026a41106a290300370300201b20044190026a41186a290300370300201d200f290300370300201e20142f01003b0100200420042903900237038003200420042f018c023b01b002200420042903f8013703d002024020182004280214470d00200441106a20184101109f01200428021821180b20042802102215201841c4006c6a220141013a00002001200429038003370001200141003a0021200120042f01b0023b0022200120042903d002370030200141096a2010290300370000200141116a201c290300370000200141196a201b290300370000200141386a201d290300370000200141c0006a201e2f01003b00002004201841016a221836021802402004280294012201450d00200141246c2102201a210103400240024020012d0000220341044b0d0002400240024020030e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012002415c6a22020d000b0b02402004280290012201450d00200141246c450d00201a10350b200e41907f6a210e200941f0006a210920082019470d010c040b0b103c000b02402004280294012201450d00200141246c2102201a210103400240024020012d0000220341044b0d0002400240024020030e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012002415c6a22020d000b0b02402004280290012201450d00200141246c450d00201a10350b024020192008460d000340200910b1030240200941046a2802002201450d00200141246c450d00200928020010350b200941f0006a2109200e41907f6a220e0d000b0b02402006450d00200641f0006c450d00200710350b024020042802142201450d00200141c4006c450d00201510350b410321080c040b20192008460d002007200541f0006c6a210303402008220141046a220210b103200141f0006a21080240200141086a2802002201450d00200141246c450d00200228020010350b20032008470d000b0b02402006450d00200641f0006c450d00200710350b20044188016a41186a2208420037030020044188016a41106a2209420037030020044188016a41086a2202420037030020044200370388014193d1cb00ad4280808080a0018410012203290000210b20044180036a41086a2201200341086a2900003703002004200b37038003200310352002200129030037030020042004290380033703880141e0caca00ad4280808080e0008410012203290000210b2001200341086a2900003703002004200b3703800320031035200a200429038003370000200a41086a2001290300370000200441206a41086a2002290300370300200441206a41106a2009290300370300200441206a41186a2008290300370300200420042903880137032020044188016a2015201810e006200d2004350290014220862004280288012201ad8410020240200428028c01450d00200110350b024020042802142201450d00200141c4006c450d00201510350b4200210b0c030b200541f0006c2102200741046a21010340200110b1030240200141046a2802002203450d00200341246c450d00200128020010350b200141f0006a2101200241907f6a22020d000b0b2006450d00200641f0006c450d00200710350b200041206a200f3602002000411c6a2011360200200041186a2012411074200872418008723602004201210b0b2000200b37030020004200370308200441a0036a24000be81c041c7f017e067f017e230041e0066b220324000240024002400240024002400240024002400240024020012802002204450d0020032001410c6a418001109d0821052001280204210602400240024020022d00000d0020022d00014101460d010b02402006450d00200410350b41022105410021020c010b200241196a2d00002101200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720052002411a6a29010037039801200520013a009701200520073a009601200520083b019401200520093a0093012005200a3a0092012005200b3b0190012005200c3a008f012005200d3a008e012005200e3b018c012005200f3a008b01200520103a008a01200520113b018801200520123a008701200520133a008601200520143b018401200520153a008301200520163a008201200520173b018001200541a0016a2005418001109d081a200541c0036a41186a200529039801370300200541c0036a41106a200529039001370300200541c8036a20052903880137030020052005290380013703c003200541d8056a200541c0036a10fc010240024020052d00d8054101470d00200541ef046a2202200541f1056a290000370000200541d8046a41106a2201200541ea056a290100370300200541a9026a200541e2056a290100370000200541b1026a2001290300370000200541a0026a41186a2002290000370000200520052d00d9053a00a002200520052901da053700a102200541c0026a200541a0016a418001109d081a200541c8046a200541a0026a10dd06200541d8056a20052802c804220120052802d00410c10220052d00d8052102200541d8046a200541d8056a410172418001109d081a0240024020024101460d00200541003a00c0030c010b200541013a00c003200541c0036a410172200541d8046a418001109d081a0b024020052802cc04450d00200110350b200541c0026a41206a211820054180036a2119200541a0036a211a200541e1036a211b20054181046a211c200541a1046a211d200541c0036a410172211e4170210803404100210141b0b4cc0021070240024002400240200841c4e2c6006a280000220241e6e485f3064a220b0d00200241e2c289ab06460d01200241e1ea91cb06470d0341202101201a21070c030b200241e9dabdf306460d01200241e7e485f306470d0241202101200541c0026a21070c020b41202101201821070c010b41202101201921070b200520013602e005200520073602dc05200520023602d805200541d8046a200541d8056a10f706200541d8056a20052802d804220a20052802e00410d50120052802dc0421090240024020052d00d8054101470d0020052900f105211f20052d00f005210c20052d00ef05210d20052f00ed05210e20052d00ec05210f20052d00eb05211020052f00e905211120052d00e805211220052d00e705211320052f00e505211420052d00e405211520052d00e305211620052f00e105211720052d00e005212020052d00df05212120052f00dd05212220052d00dc05212320052d00db05212420052f00d905212502402009450d00200a10350b2005201f3703f0052005200c3a00ef052005200d3a00ee052005200e3b01ec052005200f3a00eb05200520103a00ea05200520113b01e805200520123a00e705200520133a00e605200520143b01e405200520153a00e305200520163a00e205200520173b01e005200520203a00df05200520213a00de05200520223b01dc05200520233a00db05200520243a00da05200520253b01d805200541d8056a200541a0026a412010a008450d0141b193ca00ad211f4280808080d00121264180800821050c040b2009450d00200a10350b0240024020052d00c0034101470d004100210941b0b4cc00210a0240024002400240200b0d00200241e2c289ab06460d01200241e1ea91cb06470d0341202109201d210a0c030b200241e9dabdf306460d01200241e7e485f306470d0241202109201e210a0c020b41202109201b210a0c010b41202109201c210a0b024020012009470d002007200a460d022007200a200110a008450d020b200520093602e0052005200a3602dc05200520023602d805200541d8046a200541d8056a10f70620053502e00442208620052802d8042209ad84100720052802dc04450d00200910350b200520013602e005200520073602dc05200520023602d805200541d8046a200541d8056a10f70620052802d804210120053502e004211f412010332202450d0e200220052903a002370000200241186a200541a0026a41186a290300370000200241106a200541a0026a41106a290300370000200241086a200541a0026a41086a290300370000201f4220862001ad842002ad428080808080048410022002103520052802dc04450d00200110350b200841046a22080d000b200541d8056a200541a0026a10dd0620053502e005211f20052802d8052101412010332202450d0d200220052903c002370000200241186a200541c0026a41186a290300370000200241106a200541c0026a41106a290300370000200241086a200541c0026a41086a2903003700002002412041c00010372202450d0d200220052903e002370020200241386a200541c0026a41386a290300370000200241306a200541c0026a41306a290300370000200241286a200541c0026a41286a290300370000200241c00041800110372202450d0d2002200529038003370040200241d8006a200541c0026a41d8006a290300370000200241d0006a200541c0026a41d0006a290300370000200241c8006a200541c0026a41c8006a290300370000200220052903a003370060200241e8006a200541c0026a41e8006a290300370000200241f0006a200541c0026a41f0006a290300370000200241f8006a200541c0026a41f8006a290300370000201f4220862001ad842002ad4280808080801084100220021035024020052802dc05450d00200110350b024020052d00c0030d0020054180016a108d020b2006450d04200410350c040b41be93ca00ad211f4280808080f00221264180800421050b201f42ffffffff0f83211f20054180800c71210502402006450d00200410350b2026201f84211f2005418012722102410321050b200042003703082000411c6a201f370200200041186a20022005723602000c070b4102210520022d00000d0420022d00014101470d042002411a6a290100211f200241196a2d00002105200241186a2d00002101200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d000021042002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f010021142003200241096a2d00003a0007200320103a0006200320113b0104200320123a0003200320133a0002200320143b01002003200b3a000f200320043a000e2003200c3b010c2003200d3a000b2003200e3a000a2003200f3b0108200320053a0017200320013a0016200320073b0114200320083a0013200320093a00122003200a3b01102003201f370318200341c0036a41186a201f370300200341c0036a41106a2003290310370300200341c8036a2003290308370300200320032903003703c003200341d8056a200341c0036a10fc0120032d00d8054101470d02200341ef046a2205200341f1056a290000370000200341d8046a41106a2202200341ea056a290100370300200341a9016a200341e2056a290100370000200341b1016a2002290300370000200341a0016a41186a2005290000370000200320032d00d9053a00a001200320032901da053700a101200341a0026a200341a0016a10dd06200341d8056a20032802a002220520032802a802220110c102024020032d00d8052202450d002001ad4220862005ad8410070b20032d00d9052101200341d8046a200341d8056a41027241ff00109d081a200341d8056a200341d8046a41ff00109d081a20024101470d01200341c0026a200341d8056a41ff00109d081a024020032802a402450d00200510350b200320013a00c003200341c0036a410172200341c0026a41ff00109d081a200341e0056a4120360200200341e7e485f3063602d8052003200341c0036a3602dc05200341d8046a200341d8056a10f70620033502e00442208620032802d8042205ad841007024020032802dc04450d00200510350b200341e2c289ab063602d805200341203602e0052003200341c0036a41206a3602dc05200341d8046a200341d8056a10f70620033502e00442208620032802d8042205ad841007024020032802dc04450d00200510350b200341203602e005200320034180046a3602dc05200341e9dabdf3063602d805200341d8046a200341d8056a10f70620033502e00442208620032802d8042205ad841007024020032802dc04450d00200510350b200341203602e0052003200341a0046a3602dc05200341e1ea91cb063602d805200341d8046a200341d8056a10f70620033502e00442208620032802d8042205ad841007024020032802dc04450d00200510350b20031099020b4200211f200042003703080c060b024020032802a402450d00200510350b4180920c21024280808080e000211f41ab93ca0021050c010b4180920421024280808080f002211f41be93ca0021050b201f2005ad84211f410321050c010b410021020b200042003703082000411c6a201f370200200041186a20022005723602000b4201211f0b2000201f370300200341e0066a24000f0b1045000b103c000bf75d06067f017e027f017e0d7f047e230041a0046b2203240002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341e4016a4101360200200342013702d401200341e8d4ca003602d001200341043602ac012003419cd5ca003602a8012003200341a8016a3602e001200341d0016a41b0b4cc00104c000b2001412c6a2802002104200141286a2802002105200141246a280200210620012d00012107200341e0006a41186a2001411a6a290000370300200341e0006a41106a200141126a290000370300200341e0006a41086a2001410a6a2900003703002003200141026a290000370360024020022d000120022d0000410047720d002006200410ac06200341d0016a41186a4200370300200341d0016a41106a22024200370300200341d0016a41086a22014200370300200342003703d00141dad5ca00ad4280808080b002841001220829000021092001200841086a290000370300200320093703d001200810354189eaca00ad4280808080f00084100122082900002109200341306a41086a220a200841086a290000370300200320093703302008103520022003290330220937030020034180016a41086a200129030037030020034180016a41106a200937030020034180016a41186a200a290300370300200320032903d00137038001200341d0016a20034180016a10fe01200341d0016a2006200420032802d0012201410120011b220820032902d401420020011b2209422088a710a6022002280200210220032802d401210120032802d001210a20032802dc01220b200341e4016a2802002006200410a7020240200241ffffff3f71450d00200b10350b0240200141ffffff3f71450d00200a10350b20034180046a41186a2202200341e0006a41186a29030037030020034180046a41106a2201200341e0006a41106a29030037030020034180046a41086a2204200341e0006a41086a290300370300200320032903603703800402400240200741ff01710d0020034180016a41186a420037030020034180016a41106a2207420037030020034180016a41086a22014200370300200342003703800141dad5ca00ad4280808080b0028410012204290000210c200341d0006a41086a2202200441086a2900003703002003200c37035020041035200120022903003703002003200329035037038001419cdfca00ad4280808080d0008410012204290000210c2002200441086a2900003703002003200c3703502004103520072003290350220c370300200341a8016a41086a2001290300370300200341a8016a41106a200c370300200341a8016a41186a200229030037030020032003290380013703a801200341a8016aad428080808080048410070c010b200341a8016a41186a2002290300370300200341a8016a41106a2001290300370300200341a8016a41086a200429030037030020032003290380043703a801200341306a41186a4200370300200341306a41106a22074200370300200341306a41086a220242003703002003420037033041dad5ca00ad4280808080b0028410012201290000210c200341d0016a41086a2204200141086a2900003703002003200c3703d0012001103520022004290300370300200320032903d001370330419cdfca00ad4280808080d0008410012201290000210c20034180016a41086a220a200141086a2900003703002003200c37038001200110352007200329038001220c37030020042002290300370300200341d0016a41106a200c370300200341d0016a41186a200a290300370300200320032903303703d001412010332202450d06200220032903a801370000200241186a200341a8016a41186a290300370000200241106a200341a8016a41106a290300370000200241086a200341a8016a41086a290300370000200341d0016aad42808080808004842002ad42808080808004841002200210350b0240200942ffffff3f83500d00200810350b200541ffffff3f71450d0f200610350c0f0b0240200541ffffff3f71450d00200610350b20004200370308200041186a4102360200420121090c0f0b200141046a280200210520032002411a6a290100370398012003200241026a2901003703800120032002410a6a290100370388012003200241126a290100370390010240024020022d00014101470d0020022d000041ff01710d00200341e0006a41186a20034180016a41186a2206290300370300200341e0006a41106a20034180016a41106a2204290300370300200341e0006a41086a20034180016a41086a22072903003703002003200329038001370360200341d0016a41186a4200370300200341d0016a41106a22084200370300200341d0016a41086a22024200370300200342003703d00141dad5ca00ad4280808080b002841001220129000021092002200141086a290000370300200320093703d001200110354189eaca00ad4280808080f00084100122012900002109200341306a41086a220a200141086a290000370300200320093703302001103520082003290330220937030020072002290300370300200420093703002006200a290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b2209422088a741057421012002410120021b2207210202400340024020010d00410021040c020b41012104200341e0006a2002460d01200141606a21012002200341e0006a412010a0082106200241206a210220060d000b0b0240200942ffffff3f83500d00200710350b41831621022004450d01200341003602d801200342013703d0012005200341d0016a10af0320032802d401210120034180046a41186a220620033502d80142208620032802d0012208ad841009220241186a29000037030020034180046a41106a2204200241106a29000037030020034180046a41086a2207200241086a29000037030020032002290000370380042002103502402001450d00200810350b200341d0016a200541b002109d081a200341a8016a410d6a200341e0006a41086a290300370000200341a8016a41156a200341e0006a41106a290300370000200341a8016a411d6a200341e0006a41186a290300370000200341013a00ac01200320032903603700ad01200341013a00a80120034180016a200341d0016a200341a8016a10ac032003290380012109200341d0016a410d6a2007290300370000200341d0016a41156a2004290300370000200341d0016a411d6a2006290300370000200341f5016a2009503a0000200341053a00d401200341073a00d00120032003290380043700d50141b0b4cc004100200341d0016a10d401200510350c0f0b41821621020b200510ba0220051035200041206a41093602002000411c6a41f2dfca00360200200041186a200236020020004200370308420121090c0e0b200141086a2802002105200141046a280200210d2002411a6a2901002109200241196a2d00002106200241186a2d00002104200241166a2f01002107200241156a2d00002108200241146a2d0000210a200241126a2f0100210b200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211941012101024020022d00000d0020022d000141014721010b200320093703c001200320063a00bf01200320043a00be01200320073b01bc01200320083a00bb012003200a3a00ba012003200b3b01b8012003200e3a00b7012003200f3a00b601200320103b01b401200320113a00b301200320123a00b201200320133b01b001200320143a00af01200320153a00ae01200320163b01ac01200320173a00ab01200320183a00aa01200320193b01a801024020010d00200341e0006a41186a200341a8016a41186a290300370300200341e0006a41106a200341a8016a41106a290300370300200341e0006a41086a200341a8016a41086a290300370300200320032903a801370360200341d0016a41186a4200370300200341d0016a41106a22074200370300200341d0016a41086a22024200370300200342003703d00141dad5ca00ad4280808080b002841001220129000021092002200141086a290000370300200320093703d001200110354189eaca00ad4280808080f00084100122012900002109200341306a41086a2206200141086a290000370300200320093703302001103520072003290330220937030020034180016a41086a200229030037030020034180016a41106a200937030020034180016a41186a2006290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b2209422088a741057421012002410120021b2208210202400340024020010d00410021040c020b41012104200341e0006a2002460d01200141606a21012002200341e0006a412010a0082106200241206a210220060d000b0b0240200942ffffff3f83500d00200810350b41032102024020040d0041f2dfca0021014109210641801621040c0c0b200341003602d801200342013703d0012005200341d0016a10af0320032802d401210620034180046a41186a220420033502d80142208620032802d001220bad841009220141186a29000037030020034180046a41106a2208200141106a29000037030020034180046a41086a220a200141086a29000037030020032001290000370380042001103502402006450d00200b10350b200341d0016a41186a2004290300370300200341d0016a41106a2008290300370300200341d0016a41086a200a29030037030020032003290380043703d001200341a8016a200341d0016a109907200341206a20032802a801220620032802b00141b0b4cc0041004100108a0220032802202101024020032802ac01450d00200610350b20014101460d040240200d4102490d0020034180016a41186a2208420037030020034180016a41106a2206420037030020034180016a41086a22014200370300200342003703800141dad5ca00ad4280808080b00284220910012204290000210c200341d0006a41086a2202200441086a2900003703002003200c37035020041035200120022903003703002003200329035037038001418ef0cb00ad4280808080d00184220c10012204290000211a2002200441086a2900003703002003201a3703502004103520062003290350221a370300200341306a41086a22042001290300370300200341306a41106a220a201a370300200341306a41186a220b20022903003703002003200329038001370330200341186a200341306a412010c001200328021c210f20032802182110200842003703002006420037030020014200370300200342003703800120091001220e290000211a2002200e41086a2900003703002003201a370350200e1035200120022903003703002003200329035037038001200c1001220e290000211a2002200e41086a2900003703002003201a370350200e103520062003290350221a37030020042001290300370300200a201a370300200b20022903003703002003200329038001370330200341106a200341306a412010c0012003280210211120032802142112200842003703002006420037030020014200370300200342003703800120091001220e290000211a2002200e41086a2900003703002003201a370350200e1035200120022903003703002003200329035037038001200c1001220e290000210c2002200e41086a2900003703002003200c370350200e103520062003290350220c37030020042001290300370300200a200c370300200b20022903003703002003200329038001370330410121022003201241016a410120111b3602d001200341306aad4280808080800484200341d0016aad4280808080c000841002200341d0016a41186a220e4200370300200341d0016a41106a22114200370300200341d0016a41086a220a4200370300200342003703d00120091001220b2900002109200a200b41086a290000370300200320093703d001200b10354180eaca00ad42808080809001841001220b29000021092004200b41086a29000037030020032009370330200b103520072003290330370000200741086a20042903003700002001200a290300370300200620112903003703002008200e290300370300200320032903d00137038001200341d0016a20034180016a412010b5020240024020032802d00122010d00200341003602b001200342013703a8014100210a410021060c010b200320032902d40122093702ac01200320013602a8012009422088a721062009a7210a200121020b200341306a41186a220b20034180046a41186a290300370300200341306a41106a220420034180046a41106a290300370300200341306a41086a220120034180046a41086a290300370300200320032903800437033002402006200a470d00200341a8016a200a4101108a0120032802ac01210a20032802a801210220032802b00121060b200220064105746a22082003290330370000200841186a200b290300370000200841106a2004290300370000200841086a20012903003700002003200641016a220e3602b001200b420037030020044200370300200142003703002003420037033041dad5ca00ad4280808080b00284100122082900002109200341d0006a41086a2206200841086a290000370300200320093703502008103520012006290300370300200320032903503703304180eaca00ad42808080809001841001220829000021092006200841086a290000370300200320093703502008103520042003290350220937030020034180016a41086a200129030037030020034180016a41106a200937030020034180016a41186a200629030037030020032003290330370380010240024020020d0020034180016aad428080808080048410070c010b200341203602d401200320034180016a3602d0012002200e200341d0016a10c504200a41ffffff3f71450d00200210350b200341d0016a200541b002109d081a200341a8016a41186a20034180046a41186a290300370300200341a8016a41106a20034180046a41106a290300370300200341a8016a41086a20034180046a41086a29030037030020032003290380043703a80120034180016a200341a8016a10990720032802800121022003350288012109200341003602b001200342013703a801200341d0016a200341a8016a10af0320032802ac01210120094220862002ad8420033502b00142208620032802a8012206ad84100202402001450d00200610350b0240200328028401450d00200210350b200341d0016a10ba02200341d0016a41186a22064200370300200341d0016a41106a22044200370300200341d0016a41086a22024200370300200342003703d00141d1c4c700ad4280808080e000841001220129000021092002200141086a290000370300200320093703d0012001103541e7c4c700ad4280808080e00084100122012900002109200341306a41086a2208200141086a290000370300200320093703302001103520072003290330370000200741086a200829030037000020034180016a41086a200229030037030020034180016a41106a200429030037030020034180016a41186a2006290300370300200320032903d00137038001200341086a20034180016a412010c001200328020c210120032802082106412010332202450d0620022003290360370000200241186a200341e0006a41186a290300370000200241106a200341e0006a41106a290300370000200241086a200341e0006a41086a290300370000200341ec016a4100360200200341dc016a428180808010370200200320014180e5086a4180e50820061b3602f001200342013702e401200320023602d8012003200d3602d4012003200f410020101b22063602d001200341a8016a41186a20034180046a41186a290300370300200341a8016a41106a20034180046a41106a290300370300200341a8016a41086a20034180046a41086a29030037030020032003290380043703a80120034180016a200341a8016a108c07200328028001210120032003280288013602ac01200320013602a801200341d0016a200341a8016a1092070240200328028401450d00200110350b20021035200341dd016a200341e0006a41086a290300370000200341e5016a200341e0006a41106a290300370000200341ed016a200341e0006a41186a290300370000200341f5016a200329038004370000200341fd016a20034180046a41086a29030037000020034185026a20034180046a41106a2903003700002003418d026a20034180046a41186a2903003700002003419c026a200d36020020034198026a2006360200200341003a00d401200341073a00d001200320032903603700d501200341d0016a21020c0d0b200341d0016a41186a22064200370300200341d0016a41106a22044200370300200341d0016a41086a22024200370300200342003703d00141dad5ca00ad4280808080b002841001220129000021092002200141086a290000370300200320093703d001200110354189eaca00ad4280808080f00084100122012900002109200341306a41086a2208200141086a290000370300200320093703302001103520072003290330370000200741086a200829030037000020034180016a41086a200229030037030020034180016a41106a200429030037030020034180016a41186a2006290300370300200320032903d00137038001200341a8016a20034180016a10fe010240024020032802a80122010d00410021020c010b20032902ac012209422088a72102200942ffffff3f83500d00200110350b200341d0016a200541b002109d081a200341b4016a2002360200200341a8016a41086a4101360200200341003a00ac01200341013a00a80120034180016a200341d0016a200341a8016a10ac032003290380012109200341dd016a20034180046a41086a290300370000200341e5016a20034190046a290300370000200341ed016a20034198046a290300370000200341f5016a2009503a0000200341043a00d401200341073a00d00120032003290380043700d501200341d0016a21020c0c0b4102210241801621040c0a0b200141216a2d0000210d200141246a2802002119200341e0006a41186a200141196a290000370300200341e0006a41106a200141116a290000370300200341e0006a41086a200141096a290000370300200320012900013703602002411a6a2901002109200241196a2d00002106200241186a2d00002104200241166a2f01002105200241156a2d00002107200241146a2d00002108200241126a2f0100210a200241116a2d0000210b200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211841012101024020022d00000d0020022d000141014721010b200320093703c001200320063a00bf01200320043a00be01200320053b01bc01200320073a00bb01200320083a00ba012003200a3b01b8012003200b3a00b7012003200e3a00b6012003200f3b01b401200320103a00b301200320113a00b201200320123b01b001200320133a00af01200320143a00ae01200320153b01ac01200320163a00ab01200320173a00aa01200320183b01a801024020010d0020034180046a41186a200341a8016a41186a29030037030020034180046a41106a200341a8016a41106a29030037030020034180046a41086a200341a8016a41086a290300370300200320032903a80137038004200341d0016a41186a4200370300200341d0016a41106a22054200370300200341d0016a41086a22024200370300200342003703d00141dad5ca00ad4280808080b002841001220129000021092002200141086a290000370300200320093703d001200110354189eaca00ad4280808080f00084100122012900002109200341306a41086a2206200141086a290000370300200320093703302001103520052003290330220937030020034180016a41086a200229030037030020034180016a41106a200937030020034180016a41186a2006290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b2209422088a741057421012002410120021b2207210202400340024020010d00410021040c020b4101210420034180046a2002460d01200141606a2101200220034180046a412010a0082106200241206a210220060d000b0b0240200942ffffff3f83500d00200710350b41032102024020040d004100210141f2dfca002106410921040c0a0b20034180016a200341e0006a109a07200341d0016a200328028001220620032802880110de0220032802840121010240024020032802d8012208450d00200341f0016a2802002102200341ec016a280200210b200341e8016a2802002110200341e4016a280200210f200341e0016a280200210a20032802dc01210e20032903d001210902402001450d00200610350b200341c4016a200b360200200341c0016a2010360200200341b8016a200a360200200341b4016a200e360200200320023602c8012003200f3602bc01200320083602b001200320093703a80120192009a7460d0141c8dfca002106410a21044180800c21010c0a0b02402001450d00200610350b41808008210141d2dfca002106410f21040c0a0b4100210141002106410021110240200a450d00200a410574210441002106200821020240034020034180046a2002460d012006200220034180046a412010a00822074100476a21062007450d01200241206a2102200441606a22040d000b410021110c010b410121110b410021020240200b450d00200b410574210441002101200f21020240034020034180046a2002460d012001200220034180046a412010a00822074100476a21012007450d01200241206a2102200441606a22040d000b410021020c010b410121020b024002400240200d41ff01710d002002450d010c0a0b20110d09200341306a41186a220420034180046a41186a290300370300200341306a41106a220720034180046a41106a290300370300200341306a41086a220b20034180046a41086a29030037030020032003290380043703300240200a200e470d00200341b0016a200e4101108a0120032802b801210a20032802b00121080b2008200a4105746a22062003290330370000200641186a2004290300370000200641106a2007290300370000200641086a200b2903003700002003200a41016a22073602b80120032802c40121042002450d01200420014d0d0720032802bc0122062004417f6a22044105746a220229000021092002290008210c2002290010211a200241186a290000211b200320043602c401200620014105746a220241186a201b3700002002201a3700102002200c370008200220093700000c010b20034180016a41186a220120034180046a41186a29030037030020034180016a41106a220420034180046a41106a29030037030020034180016a41086a220720034180046a41086a2903003703002003200329038004370380010240200b2010470d00200341bc016a20104101108a0120032802c401210b20032802bc01210f0b200f200b4105746a2202200329038001370000200241186a2001290300370000200241106a2004290300370000200241086a2007290300370000200320032802c40141016a22043602c40120032802b80121072011450d00200720064d0d0720032802b00122012007417f6a22074105746a220229000021092002290008210c2002290010211a200241186a290000211b200320073602b801200120064105746a220241186a201b3700002002201a3700102002200c370008200220093700000b200341f5016a2003290360370000200341dd016a20034180046a41086a290300370000200341e5016a20034180046a41106a290300370000200341ed016a20034180046a41186a290300370000200341fd016a200341e0006a41086a29030037000020034185026a200341e0006a41106a2903003700002003418d026a200341e0006a41186a290300370000200341013a00d401200341073a00d00120032003290380043700d5012003419c026a200436020020034198026a200736020020034195026a200d3a00004100210241b0b4cc004100200341d0016a10d401200341d0016a41186a22084200370300200341d0016a41106a220a4200370300200341d0016a41086a22014200370300200342003703d00141dad5ca00ad4280808080b002841001220629000021092001200641086a290000370300200320093703d001200610354189eaca00ad4280808080f00084100122062900002109200341306a41086a220b200641086a290000370300200320093703302006103520052003290330370000200541086a200b29030037000020034180016a41086a200129030037030020034180016a41106a200a29030037030020034180016a41186a2008290300370300200320032903d00137038001200341d0006a20034180016a10fe01024020032802502201450d0020032902542209422088a72102200942ffffff3f83500d00200110350b0240200720032802ac0122014f22060d004100200220046b2204200420024b1b2001490d00200341d0016a41206a200341a8016a41206a280200360200200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d00120034180016a200341e0006a109a072003280280012102200320032802880136023420032002360230200341d0016a200341306a1092070240200328028401450d00200210350b0240200341dc016a28020041ffffff3f71450d0020032802d80110350b200341e8016a28020041ffffff3f71450d0d20032802e40110350c0d0b200341d0016a41206a200341a8016a41206a280200360200200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d00120034180016a41186a200341e0006a41186a29030037030020034180016a41106a200341e0006a41106a29030037030020034180016a41086a200341e0006a41086a290300370300200320032903603703800120062002200341d0016a20034180016a109b070c0c0b41002101410221020c080b200141246a280200210620034198046a200141196a29000037030020034190046a200141116a29000037030020034188046a200141096a2900003703002003200129000137038004410221010240024002400240024020022d00000d0020022d00014101470d00200341a8016a20034180046a109a07200341d0016a20032802a801220120032802b00110de0220032802ac012102024020032802d8012205450d00200341f0016a280200210b200341ec016a280200210e200341e8016a2802002107200341e4016a280200210f200341e0016a280200210a20032802dc01210820032903d001210902402002450d00200110350b20062009a7460d0241c8dfca002106410a21024180800c21040c030b02402002450d00200110350b410321010b418080082104410f210241d2dfca0021060c020b200341d0016a41186a4200370300200341d0016a41106a2210420037030041082102200341d0016a41086a22014200370300200342003703d00141d1c4c700ad4280808080e0008410012206290000210c2001200641086a2900003703002003200c3703d0012006103541e7c4c700ad4280808080e0008410012206290000210c200341306a41086a2204200641086a2900003703002003200c3703302006103520102003290330220c37030020034180016a41086a200129030037030020034180016a41106a2201200c37030020034180016a41186a22062004290300370300200320032903d00137038001200341286a20034180016a412010c001200328022c410020032802281b200b4f0d0241a1dfca0021064180801821040b0240200841ffffff3f71450d00200510350b0240200741ffffff3f71450d00200f10350b410321010b20004200370308200041206a20023602002000411c6a2006360200200041186a20044180801c7120017241801672360200420121090c0c0b2009422088210c200642003703002001420037030020034180016a41086a22024200370300200342003703800141dad5ca00ad4280808080b0028410012211290000211a200341d0006a41086a2204201141086a2900003703002003201a37035020111035200220042903003703002003200329035037038001419cdfca00ad4280808080d0008410012211290000211a2004201141086a2900003703002003201a3703502011103520012003290350221a370300200341306a41086a2002290300370300200341306a41106a201a370300200341306a41186a20042903003703002003200329038001370330200341d0016a200341306a412010d50120032d00d00121042006200341e9016a2900003703002001200341e1016a2900003703002002200341d9016a290000370300200320032900d101370380010240024020044101460d00410021040c010b200341a8016a41186a20034180016a41186a290300221a370300200341a8016a41106a20034180016a41106a290300221b370300200341a8016a41086a2002290300221c3703002003200329038001221d3703a801200341d0016a41186a201a370300200341d0016a41106a201b370300200341d0016a41086a201c3703002003201d3703d001200a4105742101200521020340024020010d00410021040c020b41012104200341d0016a2002460d01200141606a21012002200341d0016a412010a0082106200241206a210220060d000b0b200ca72106200341d0016a41186a22114200370300200341d0016a41106a22124200370300200341d0016a41086a22024200370300200342003703d00141dad5ca00ad4280808080b0028410012201290000210c2002200141086a2900003703002003200c3703d001200110354189eaca00ad4280808080f0008410012201290000210c200341306a41086a2213200141086a2900003703002003200c3703302001103520102003290330370000201041086a201329030037000020034180016a41086a200229030037030020034180016a41106a201229030037030020034180016a41186a2011290300370300200320032903d00137038001200341a8016a20034180016a10fe010240024020032802a80122010d00410021020c010b20032902ac01220c422088a72102200c42ffffff3f83500d00200110350b200341dd016a20034180046a41086a2201290300370000200341e5016a20034180046a41106a2210290300370000200341ed016a20034180046a41186a2211290300370000200341fc016a41002002200e200a6a6b221220041b200e6a360200200341f8016a2012410020041b200a6a2204360200200341063a00d401200341073a00d00120032003290380043700d50141b0b4cc004100200341d0016a10d401200341ec016a200e360200200341d0016a41186a2007360200200341d0016a41106a200a360200200341dc016a20083602002003200b3602f0012003200f3602e401200320053602d801200320093703d001200341a8016a41186a2011290300370300200341a8016a41106a2010290300370300200341a8016a41086a200129030037030020032003290380043703a801200420064f2002200341d0016a200341a8016a109b070c0a0b1045000b41e1dfca002101411121064180960421040c060b103c000b20012004104a000b20062007104a000b41bbdfca002106410d21044180801021010b0240200e41ffffff3f71450d00200810350b0240201041ffffff3f71450d00200f10350b410321020b20004200370308200041206a20043602002000411c6a2006360200200041186a20014180801c7120027241801672360200420121090c030b200510ba0220051035200041206a20063602002000411c6a2001360200200041186a200420027236020020004200370308420121090c020b41b0b4cc004100200210d401200510350b42002109200042003703080b20002009370300200341a0046a24000bf55c04097f027e0c7f047e230041a0046b2203240002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341e4016a4101360200200342013702d401200341e8d4ca003602d001200341043602ac012003419cd5ca003602a8012003200341a8016a3602e001200341d0016a41b0b4cc00104c000b2001412c6a2802002104200141286a2802002105200141246a280200210620012d00012107200341e0006a41186a22082001411a6a290000370300200341e0006a41106a2209200141126a290000370300200341e0006a41086a220a2001410a6a2900003703002003200141026a290000370360024020022d000120022d0000410047720d002006200410ac06200341d0016a41186a4200370300200341d0016a41106a220b4200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b00284220c10012201290000210d2002200141086a2900003703002003200d3703d001200110354189eaca00ad4280808080f0008410012201290000210d200341306a41086a220e200141086a2900003703002003200d37033020011035200b2003290330220d37030020034180016a41086a200229030037030020034180016a41106a200d37030020034180016a41186a200e290300370300200320032903d00137038001200341d0016a20034180016a10fe012006200420032802d0012202410120021b220b20032902d401420020021b220d422088a710ad0620034180046a41186a200829030037030020034180046a41106a200929030037030020034180046a41086a200a290300370300200320032903603703800402400240200741ff01710d0020034180016a41186a420037030020034180016a41106a2207420037030020034180016a41086a220142003703002003420037038001200c10012204290000210c200341d0006a41086a2202200441086a2900003703002003200c37035020041035200120022903003703002003200329035037038001419cdfca00ad4280808080d0008410012204290000210c2002200441086a2900003703002003200c3703502004103520072003290350220c370300200341a8016a41086a2001290300370300200341a8016a41106a200c370300200341a8016a41186a200229030037030020032003290380013703a801200341a8016aad428080808080048410070c010b200341a8016a41186a220720034180046a41186a290300370300200341a8016a41106a220820034180046a41106a290300370300200341a8016a41086a220920034180046a41086a29030037030020032003290380043703a801200341306a41186a4200370300200341306a41106a220a4200370300200341306a41086a2202420037030020034200370330200c10012201290000210c200341d0016a41086a2204200141086a2900003703002003200c3703d0012001103520022004290300370300200320032903d001370330419cdfca00ad4280808080d0008410012201290000210c20034180016a41086a220e200141086a2900003703002003200c3703800120011035200a200329038001220c37030020042002290300370300200341d0016a41106a200c370300200341d0016a41186a200e290300370300200320032903303703d001412010332202450d06200220032903a801370000200241186a2007290300370000200241106a2008290300370000200241086a2009290300370000200341d0016aad42808080808004842002ad42808080808004841002200210350b0240200d42ffffff3f83500d00200b10350b200541ffffff3f71450d0f200610350c0f0b0240200541ffffff3f71450d00200610350b20004200370308200041186a41023602004201210c0c0f0b200141046a280200210420032002411a6a290100370398012003200241026a2901003703800120032002410a6a290100370388012003200241126a290100370390010240024020022d00014101470d0020022d000041ff01710d00200341e0006a41186a20034180016a41186a2206290300370300200341e0006a41106a20034180016a41106a2205290300370300200341e0006a41086a20034180016a41086a22072903003703002003200329038001370360200341d0016a41186a4200370300200341d0016a41106a22084200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b0028410012201290000210c2002200141086a2900003703002003200c3703d001200110354189eaca00ad4280808080f0008410012201290000210c200341306a41086a2209200141086a2900003703002003200c3703302001103520082003290330220c370300200720022903003703002005200c37030020062009290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b220c422088a741057421012002410120021b2207210202400340024020010d00410021050c020b41012105200341e0006a2002460d01200141606a21012002200341e0006a412010a0082106200241206a210220060d000b0b0240200c42ffffff3f83500d00200710350b41831821022005450d01200341003602d801200342013703d0012004200341d0016a10af0320032802d401210120034180046a41186a220620033502d80142208620032802d0012208ad841009220241186a29000037030020034180046a41106a2205200241106a29000037030020034180046a41086a2207200241086a29000037030020032002290000370380042002103502402001450d00200810350b200341d0016a200441b002109d081a200341a8016a410d6a200341e0006a41086a290300370000200341a8016a41156a200341e0006a41106a290300370000200341a8016a411d6a200341e0006a41186a290300370000200341013a00ac01200320032903603700ad01200341023a00a80120034180016a200341d0016a200341a8016a10ac03200329038001210c200341d0016a410d6a2007290300370000200341d0016a41156a2005290300370000200341d0016a411d6a2006290300370000200341f5016a200c503a0000200341053a00d401200341083a00d00120032003290380043700d50141b0b4cc004100200341d0016a10d401200410350c0f0b41821821020b200410ba0220041035200041206a41093602002000411c6a41f2dfca00360200200041186a2002360200200042003703084201210c0c0e0b200141086a2802002104200141046a280200210f2002411a6a290100210c200241196a2d00002106200241186a2d00002105200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210e2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211941012101024020022d00000d0020022d000141014721010b2003200c3703c001200320063a00bf01200320053a00be01200320073b01bc01200320083a00bb01200320093a00ba012003200a3b01b8012003200b3a00b7012003200e3a00b601200320103b01b401200320113a00b301200320123a00b201200320133b01b001200320143a00af01200320153a00ae01200320163b01ac01200320173a00ab01200320183a00aa01200320193b01a801024020010d00200341e0006a41186a200341a8016a41186a290300370300200341e0006a41106a200341a8016a41106a290300370300200341e0006a41086a200341a8016a41086a290300370300200320032903a801370360200341d0016a41186a4200370300200341d0016a41106a22074200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b0028410012201290000210c2002200141086a2900003703002003200c3703d001200110354189eaca00ad4280808080f0008410012201290000210c200341306a41086a2206200141086a2900003703002003200c3703302001103520072003290330220c37030020034180016a41086a200229030037030020034180016a41106a200c37030020034180016a41186a2006290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b220c422088a741057421012002410120021b2208210202400340024020010d00410021050c020b41012105200341e0006a2002460d01200141606a21012002200341e0006a412010a0082106200241206a210220060d000b0b0240200c42ffffff3f83500d00200810350b41032102024020050d0041f2dfca0021014109210641801821050c0c0b200341003602d801200342013703d0012004200341d0016a10af0320032802d401210620034180046a41186a220520033502d80142208620032802d001220aad841009220141186a29000037030020034180046a41106a2208200141106a29000037030020034180046a41086a2209200141086a29000037030020032001290000370380042001103502402006450d00200a10350b200341d0016a41186a2005290300370300200341d0016a41106a2008290300370300200341d0016a41086a200929030037030020032003290380043703d001200341a8016a200341d0016a109d07200341206a20032802a801220620032802b00141b0b4cc0041004100108a0220032802202101024020032802ac01450d00200610350b20014101460d040240200f4102490d0020034180016a41186a2208420037030020034180016a41106a2206420037030020034180016a41086a22014200370300200342003703800141c7d5ca00ad4280808080b00284220c10012205290000210d200341d0006a41086a2202200541086a2900003703002003200d37035020051035200120022903003703002003200329035037038001418ef0cb00ad4280808080d00184220d10012205290000211a2002200541086a2900003703002003201a3703502005103520062003290350221a370300200341306a41086a22052001290300370300200341306a41106a2209201a370300200341306a41186a220a20022903003703002003200329038001370330200341186a200341306a412010c001200328021c210e200328021821102008420037030020064200370300200142003703002003420037038001200c1001220b290000211a2002200b41086a2900003703002003201a370350200b1035200120022903003703002003200329035037038001200d1001220b290000211a2002200b41086a2900003703002003201a370350200b103520062003290350221a370300200520012903003703002009201a370300200a20022903003703002003200329038001370330200341106a200341306a412010c00120032802102111200328021421122008420037030020064200370300200142003703002003420037038001200c1001220b290000211a2002200b41086a2900003703002003201a370350200b1035200120022903003703002003200329035037038001200d1001220b290000210d2002200b41086a2900003703002003200d370350200b103520062003290350220d370300200520012903003703002009200d370300200a20022903003703002003200329038001370330410121022003201241016a410120111b3602d001200341306aad4280808080800484200341d0016aad4280808080c000841002200341d0016a41186a220b4200370300200341d0016a41106a22114200370300200341d0016a41086a22094200370300200342003703d001200c1001220a290000210c2009200a41086a2900003703002003200c3703d001200a10354180eaca00ad42808080809001841001220a290000210c2005200a41086a2900003703002003200c370330200a103520072003290330370000200741086a200529030037000020012009290300370300200620112903003703002008200b290300370300200320032903d00137038001200341d0016a20034180016a412010b5020240024020032802d00122010d00200341003602b001200342013703a80141002109410021060c010b200320032902d401220c3702ac01200320013602a801200c422088a72106200ca72109200121020b200341306a41186a220a20034180046a41186a290300370300200341306a41106a220520034180046a41106a290300370300200341306a41086a220120034180046a41086a2903003703002003200329038004370330024020062009470d00200341a8016a20094101108a0120032802ac01210920032802a801210220032802b00121060b200220064105746a22082003290330370000200841186a200a290300370000200841106a2005290300370000200841086a20012903003700002003200641016a220b3602b001200a420037030020054200370300200142003703002003420037033041c7d5ca00ad4280808080b0028410012208290000210c200341d0006a41086a2206200841086a2900003703002003200c3703502008103520012006290300370300200320032903503703304180eaca00ad428080808090018410012208290000210c2006200841086a2900003703002003200c3703502008103520052003290350220c37030020034180016a41086a200129030037030020034180016a41106a200c37030020034180016a41186a200629030037030020032003290330370380010240024020020d0020034180016aad428080808080048410070c010b200341203602d401200320034180016a3602d0012002200b200341d0016a10c504200941ffffff3f71450d00200210350b200341d0016a200441b002109d081a200341a8016a41186a20034180046a41186a290300370300200341a8016a41106a20034180046a41106a290300370300200341a8016a41086a20034180046a41086a29030037030020032003290380043703a80120034180016a200341a8016a109d072003280280012102200335028801210c200341003602b001200342013703a801200341d0016a200341a8016a10af0320032802ac012101200c4220862002ad8420033502b00142208620032802a8012206ad84100202402001450d00200610350b0240200328028401450d00200210350b200341d0016a10ba02200341d0016a41186a22064200370300200341d0016a41106a22054200370300200341d0016a41086a22024200370300200342003703d00141d1c4c700ad4280808080e0008410012201290000210c2002200141086a2900003703002003200c3703d0012001103541e7c4c700ad4280808080e0008410012201290000210c200341306a41086a2208200141086a2900003703002003200c3703302001103520072003290330370000200741086a200829030037000020034180016a41086a200229030037030020034180016a41106a200529030037030020034180016a41186a2006290300370300200320032903d00137038001200341086a20034180016a412010c001200328020c210120032802082106412010332202450d0620022003290360370000200241186a200341e0006a41186a290300370000200241106a200341e0006a41106a290300370000200241086a200341e0006a41086a290300370000200341ec016a4100360200200341dc016a428180808010370200200320014180e5086a4180e50820061b3602f001200342013702e401200320023602d8012003200f3602d4012003200e410020101b22063602d001200341a8016a41186a20034180046a41186a290300370300200341a8016a41106a20034180046a41106a290300370300200341a8016a41086a20034180046a41086a29030037030020032003290380043703a80120034180016a200341a8016a108a07200328028001210120032003280288013602ac01200320013602a801200341d0016a200341a8016a1092070240200328028401450d00200110350b20021035200341e5016a200341e0006a41106a290300370000200341ed016a200341e0006a41186a290300370000200341f5016a20032903800437000020034185026a20034180046a41106a2903003700002003418d026a20034180046a41186a2903003700002003419c026a200f36020020034198026a2006360200200341083a00d001200341dd016a200341e0006a41086a290300370000200341fd016a20034180046a41086a290300370000200341003a00d401200320032903603700d501200341d0016a21020c0d0b200341d0016a41186a22064200370300200341d0016a41106a22054200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b0028410012201290000210c2002200141086a2900003703002003200c3703d001200110354189eaca00ad4280808080f0008410012201290000210c200341306a41086a2208200141086a2900003703002003200c3703302001103520072003290330370000200741086a200829030037000020034180016a41086a200229030037030020034180016a41106a200529030037030020034180016a41186a2006290300370300200320032903d00137038001200341a8016a20034180016a10fe010240024020032802a80122010d00410021020c010b20032902ac01220c422088a72102200c42ffffff3f83500d00200110350b200341d0016a200441b002109d081a200341b4016a2002360200200341a8016a41086a4101360200200341003a00ac01200341023a00a80120034180016a200341d0016a200341a8016a10ac03200329038001210c200341dd016a20034180046a41086a290300370000200341e5016a20034190046a290300370000200341ed016a20034198046a290300370000200341f5016a200c503a0000200341043a00d401200341083a00d00120032003290380043700d501200341d0016a21020c0c0b4102210241801821050c0a0b200141216a2d0000210f200141246a2802002119200341e0006a41186a200141196a290000370300200341e0006a41106a200141116a290000370300200341e0006a41086a200141096a290000370300200320012900013703602002411a6a290100210c200241196a2d00002106200241186a2d00002105200241166a2f01002104200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210e2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211841012101024020022d00000d0020022d000141014721010b2003200c3703c001200320063a00bf01200320053a00be01200320043b01bc01200320073a00bb01200320083a00ba01200320093b01b8012003200a3a00b7012003200b3a00b6012003200e3b01b401200320103a00b301200320113a00b201200320123b01b001200320133a00af01200320143a00ae01200320153b01ac01200320163a00ab01200320173a00aa01200320183b01a801024020010d0020034180046a41186a200341a8016a41186a29030037030020034180046a41106a200341a8016a41106a29030037030020034180046a41086a200341a8016a41086a290300370300200320032903a80137038004200341d0016a41186a4200370300200341d0016a41106a22044200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b0028410012201290000210c2002200141086a2900003703002003200c3703d001200110354189eaca00ad4280808080f0008410012201290000210c200341306a41086a2206200141086a2900003703002003200c3703302001103520042003290330220c37030020034180016a41086a200229030037030020034180016a41106a200c37030020034180016a41186a2006290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b220c422088a741057421012002410120021b2207210202400340024020010d00410021050c020b4101210520034180046a2002460d01200141606a2101200220034180046a412010a0082106200241206a210220060d000b0b0240200c42ffffff3f83500d00200710350b41032102024020050d004100210141f2dfca002106410921050c0a0b20034180016a200341e0006a109e07200341d0016a200328028001220620032802880110de0220032802840121010240024020032802d8012208450d00200341f0016a2802002102200341ec016a280200210a200341e8016a2802002110200341e4016a280200210e200341e0016a280200210920032802dc01210b20032903d001210c02402001450d00200610350b200341c4016a200a360200200341c0016a2010360200200341b8016a2009360200200341b4016a200b360200200320023602c8012003200e3602bc01200320083602b0012003200c3703a8012019200ca7460d0141c8dfca002106410a21054180800c21010c0a0b02402001450d00200610350b41808008210141d2dfca002106410f21050c0a0b41002101410021064100211102402009450d002009410574210541002106200821020240034020034180046a2002460d012006200220034180046a412010a00822074100476a21062007450d01200241206a2102200541606a22050d000b410021110c010b410121110b410021020240200a450d00200a410574210541002101200e21020240034020034180046a2002460d012001200220034180046a412010a00822074100476a21012007450d01200241206a2102200541606a22050d000b410021020c010b410121020b024002400240200f41ff01710d002002450d010c0a0b20110d09200341306a41186a220520034180046a41186a290300370300200341306a41106a220720034180046a41106a290300370300200341306a41086a220a20034180046a41086a290300370300200320032903800437033002402009200b470d00200341b0016a200b4101108a0120032802b801210920032802b00121080b200820094105746a22062003290330370000200641186a2005290300370000200641106a2007290300370000200641086a200a2903003700002003200941016a22073602b80120032802c40121052002450d01200520014d0d0720032802bc0122062005417f6a22054105746a2202290000210c2002290008210d2002290010211a200241186a290000211b200320053602c401200620014105746a220241186a201b3700002002201a3700102002200d3700082002200c3700000c010b20034180016a41186a220120034180046a41186a29030037030020034180016a41106a220520034180046a41106a29030037030020034180016a41086a220720034180046a41086a2903003703002003200329038004370380010240200a2010470d00200341bc016a20104101108a0120032802c401210a20032802bc01210e0b200e200a4105746a2202200329038001370000200241186a2001290300370000200241106a2005290300370000200241086a2007290300370000200320032802c40141016a22053602c40120032802b80121072011450d00200720064d0d0720032802b00122012007417f6a22074105746a2202290000210c2002290008210d2002290010211a200241186a290000211b200320073602b801200120064105746a220241186a201b3700002002201a3700102002200d3700082002200c3700000b200341f5016a2003290360370000200341e5016a20034180046a41106a290300370000200341ed016a20034180046a41186a29030037000020034185026a200341e0006a41106a2903003700002003418d026a200341e0006a41186a290300370000200341083a00d001200341dd016a20034180046a41086a290300370000200341fd016a200341e0006a41086a290300370000200341013a00d40120032003290380043700d5012003419c026a200536020020034198026a200736020020034195026a200f3a00004100210241b0b4cc004100200341d0016a10d401200341d0016a41186a22084200370300200341d0016a41106a22094200370300200341d0016a41086a22014200370300200342003703d00141c7d5ca00ad4280808080b0028410012206290000210c2001200641086a2900003703002003200c3703d001200610354189eaca00ad4280808080f0008410012206290000210c200341306a41086a220a200641086a2900003703002003200c3703302006103520042003290330370000200441086a200a29030037000020034180016a41086a200129030037030020034180016a41106a200929030037030020034180016a41186a2008290300370300200320032903d00137038001200341d0006a20034180016a10fe01024020032802502201450d002003290254220c422088a72102200c42ffffff3f83500d00200110350b0240200720032802ac0122014f22060d004100200220056b2205200520024b1b2001490d00200341d0016a41206a200341a8016a41206a280200360200200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d00120034180016a200341e0006a109e072003280280012102200320032802880136023420032002360230200341d0016a200341306a1092070240200328028401450d00200210350b0240200341dc016a28020041ffffff3f71450d0020032802d80110350b200341e8016a28020041ffffff3f71450d0d20032802e40110350c0d0b200341d0016a41206a200341a8016a41206a280200360200200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d00120034180016a41186a200341e0006a41186a29030037030020034180016a41106a200341e0006a41106a29030037030020034180016a41086a200341e0006a41086a290300370300200320032903603703800120062002200341d0016a20034180016a109f070c0c0b41002101410221020c080b200141246a280200210620034198046a200141196a29000037030020034190046a200141116a29000037030020034188046a200141096a2900003703002003200129000137038004410221010240024002400240024020022d00000d0020022d00014101470d00200341a8016a20034180046a109e07200341d0016a20032802a801220120032802b00110de0220032802ac012102024020032802d8012204450d00200341f0016a280200210a200341ec016a280200210b200341e8016a2802002107200341e4016a280200210e200341e0016a280200210920032802dc01210820032903d001210c02402002450d00200110350b2006200ca7460d0241c8dfca002106410a21024180800c21050c030b02402002450d00200110350b410321010b418080082105410f210241d2dfca0021060c020b200341d0016a41186a4200370300200341d0016a41106a2210420037030041082102200341d0016a41086a22014200370300200342003703d00141d1c4c700ad4280808080e0008410012206290000210d2001200641086a2900003703002003200d3703d0012006103541e7c4c700ad4280808080e0008410012206290000210d200341306a41086a2205200641086a2900003703002003200d3703302006103520102003290330220d37030020034180016a41086a200129030037030020034180016a41106a2201200d37030020034180016a41186a22062005290300370300200320032903d00137038001200341286a20034180016a412010c001200328022c410020032802281b200a4f0d0241a1dfca0021064180801821050b0240200841ffffff3f71450d00200410350b0240200741ffffff3f71450d00200e10350b410321010b20004200370308200041206a20023602002000411c6a2006360200200041186a20054180801c71200172418018723602004201210c0c0c0b200c422088210d200642003703002001420037030020034180016a41086a22024200370300200342003703800141c7d5ca00ad4280808080b0028410012211290000211a200341d0006a41086a2205201141086a2900003703002003201a37035020111035200220052903003703002003200329035037038001419cdfca00ad4280808080d0008410012211290000211a2005201141086a2900003703002003201a3703502011103520012003290350221a370300200341306a41086a2002290300370300200341306a41106a201a370300200341306a41186a20052903003703002003200329038001370330200341d0016a200341306a412010d50120032d00d00121052006200341e9016a2900003703002001200341e1016a2900003703002002200341d9016a290000370300200320032900d101370380010240024020054101460d00410021050c010b200341a8016a41186a20034180016a41186a290300221a370300200341a8016a41106a20034180016a41106a290300221b370300200341a8016a41086a2002290300221c3703002003200329038001221d3703a801200341d0016a41186a201a370300200341d0016a41106a201b370300200341d0016a41086a201c3703002003201d3703d00120094105742101200421020340024020010d00410021050c020b41012105200341d0016a2002460d01200141606a21012002200341d0016a412010a0082106200241206a210220060d000b0b200da72106200341d0016a41186a22114200370300200341d0016a41106a22124200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b0028410012201290000210d2002200141086a2900003703002003200d3703d001200110354189eaca00ad4280808080f0008410012201290000210d200341306a41086a2213200141086a2900003703002003200d3703302001103520102003290330370000201041086a201329030037000020034180016a41086a200229030037030020034180016a41106a201229030037030020034180016a41186a2011290300370300200320032903d00137038001200341a8016a20034180016a10fe010240024020032802a80122010d00410021020c010b20032902ac01220d422088a72102200d42ffffff3f83500d00200110350b200341e5016a20034180046a41106a2201290300370000200341ed016a20034180046a41186a2210290300370000200341083a00d001200341dd016a20034180046a41086a2211290300370000200341fc016a41002002200b20096a6b221220051b200b6a360200200341f8016a2012410020051b20096a2205360200200341063a00d40120032003290380043700d50141b0b4cc004100200341d0016a10d401200341ec016a200b360200200341d0016a41186a2007360200200341d0016a41106a2009360200200341dc016a20083602002003200a3602f0012003200e3602e401200320043602d8012003200c3703d001200341a8016a41186a2010290300370300200341a8016a41106a2001290300370300200341a8016a41086a201129030037030020032003290380043703a801200520064f2002200341d0016a200341a8016a109f070c0a0b1045000b41e1dfca002101411121064180980421050c060b103c000b20012005104a000b20062007104a000b41bbdfca002106410d21054180801021010b0240200b41ffffff3f71450d00200810350b0240201041ffffff3f71450d00200e10350b410321020b20004200370308200041206a20053602002000411c6a2006360200200041186a20014180801c71200272418018723602004201210c0c030b200410ba0220041035200041206a20063602002000411c6a2001360200200041186a2005200272360200200042003703084201210c0c020b41b0b4cc004100200210d401200410350b4200210c200042003703080b2000200c370300200341a0046a24000bb65d07047f017e037f027e017f027e097f23004180036b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e080001020304050607000b20034194026a41013602002003420137028402200341e8d4ca0036028002200341043602dc012003419cd5ca003602d8012003200341d8016a3602900220034180026a41b0b4cc00104c000b200341d0016a200141196a290000370300200341b8016a41106a200141116a290000370300200341c0016a200141096a290000370300200320012900013703b801200241036a2d0000210420022f000121050240024020022d00002206417f6a220141024b0d00024020010e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200641004720052004411074727241ff01710d070b20034180026a41186a420037030020034180026a41106a2204420037030020034180026a41086a22014200370300200342003703800241fb8fc800ad4280808080b002841001220229000021072001200241086a2900003703002003200737038002200210354189eaca00ad4280808080f0008410012202290000210720034198016a41086a2205200241086a29000037030020032007370398012002103520042003290398012207370300200341d8016a41086a2001290300370300200341d8016a41106a2007370300200341d8016a41186a200529030037030020032003290380023703d801200341f8006a200341d8016a10fe010240200328027822060d00410021082003410036023020034201370328410121060c170b2003200329027c220737022c200320063602282007a7210841002101024002402007422088a7220941014b0d0020090e021801180b2009210203402002410176220420016a22052001200620054105746a200341b8016a412010a0084101481b2101200220046b220241014b0d000b0b0240200620014105746a200341b8016a412010a0082202450d0020034180026a41186a200341b8016a41186a29030037030020034180026a41106a200341b8016a41106a29030037030020034180026a41086a200341b8016a41086a290300370300200320032903b801370380022002411f7620016a220420094b0d0820034180026a21020c180b02402008450d00200841ffffff3f71450d00200610350b41831c21010c150b200341c0006a200141196a290000370300200341286a41106a200141116a290000370300200341306a200141096a2900003703002003200129000137032841022101200241036a2d0000210520022f0001210602400240024020022d00002209417f6a220441024b0d00024020040e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200941004720062005411074727241ff01710d010b20034180026a41186a420037030020034180026a41106a2204420037030020034180026a41086a22014200370300200342003703800241fb8fc800ad4280808080b002841001220229000021072001200241086a2900003703002003200737038002200210354189eaca00ad4280808080f0008410012202290000210720034198016a41086a2205200241086a29000037030020032007370398012002103520042003290398012207370300200341d8016a41086a2001290300370300200341d8016a41106a2007370300200341d8016a41186a200529030037030020032003290380023703d80120034180026a200341d8016a10fe012003280280022202410120021b210641002101024002400240200329028402420020021b2207422088a7220941014b0d0020090e020201020b2009210203402002410176220420016a22052001200620054105746a200341286a412010a0084101481b2101200220046b220241014b0d000b0b200620014105746a200341286a412010a0080d00200120094f0d09200620014105746a2202200241206a2001417f7320096a410574109e081a20034180026a41186a220a420037030020034180026a41106a2208420037030020034180026a41086a22054200370300200342003703800241fb8fc800ad4280808080b00284220b10012201290000210c20034198016a41086a2202200141086a2900003703002003200c3703980120011035200520022903003703002003200329039801370380024189eaca00ad4280808080f0008410012201290000210c2002200141086a2900003703002003200c37039801200110352008200329039801220c370300200341b8016a41086a22042005290300370300200341b8016a41106a200c370300200341b8016a41186a200229030037030020032003290380023703b80120034120360284022003200341b8016a3602800220062009417f6a220120034180026a109802200a200341286a41186a2903003703002008200341286a41106a2903003703002005200341286a41086a290300370300200320032903283703800220034180026a41012006200110aa06200341d8016a41186a220d4200370300200341d8016a41106a22084200370300200341d8016a41086a22054200370300200342003703d801200b1001220a290000210b2004200a41086a2900003703002003200b3703b801200a103520052004290300370300200320032903b8013703d801419cdfca00ad4280808080d000841001220a290000210b2004200a41086a2900003703002003200b3703b801200a1035200820032903b801220b3703002002200529030037030020034198016a41106a200b37030020034198016a41186a2004290300370300200320032903d8013703980120034180026a20034198016a412010d50120032d0080022102200d20034199026a290000370300200820034191026a290000370300200520034189026a29000037030020032003290081023703d801024020024101470d00200341f8006a41186a200d290300220b370300200341f8006a41106a2008290300220c370300200341f8006a41086a2005290300220e370300200320032903d801220f370378200d200b3703002008200c3703002005200e3703002003200f3703d8014100210202400240024002402009417f6a220441014b0d0020040e020201020b03402001410176220420026a22052002200620054105746a200341d8016a412010a0084101481b2102200120046b220141014b0d000b0b200620024105746a200341d8016a412010a008450d010b20034198016a41186a420037030020034198016a41106a2205420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012204290000210b200341e8006a41086a2201200441086a2900003703002003200b37036820041035200220012903003703002003200329036837039801419cdfca00ad4280808080d0008410012204290000210b2001200441086a2900003703002003200b3703682004103520052003290368220b370300200341c8006a41086a2002290300370300200341c8006a41106a200b370300200341c8006a41186a20012903003703002003200329039801370348200341c8006aad428080808080048410070c010b20034199026a200341f0016a29030037000020034191026a200341e8016a29030037000020034189026a200341e0016a290300370000200320032903d80137008102200341013a00800220034180026a10ab060b2003418a023b01800241b0b4cc00410020034180026a10d401200742ffffff3f83500d15200610350c150b02402007a72201450d00200141ffffff3f71450d00200610350b410321010b20004200370308200041206a41093602002000411c6a41f2dfca00360200200041186a200141809c0472360200420121070c180b200341086a41186a200141196a290000370300200341086a41106a200141116a290000370300200341086a41086a200141096a29000037030020032001290001370308200341286a41186a200141396a290000370300200341286a41106a200141316a290000370300200341286a41086a200141296a2900003703002003200141216a29000037032841022101200241036a2d0000210520022f000121060240024020022d00002209417f6a220441024b0d00024020040e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200941004720062005411074727241ff0171450d000c110b200341086a200341286a412010a008450d1220034180026a41186a420037030020034180026a41106a2204420037030020034180026a41086a22014200370300200342003703800241fb8fc800ad4280808080b002841001220229000021072001200241086a2900003703002003200737038002200210354189eaca00ad4280808080f0008410012202290000210720034198016a41086a2205200241086a29000037030020032007370398012002103520042003290398012207370300200341d8016a41086a2001290300370300200341d8016a41106a2007370300200341d8016a41186a200529030037030020032003290380023703d80120034180026a200341d8016a10fe014101210d2003280280022202410120021b210641f2dfca0021084109210a4100210102400240200329028402420020021b2207422088a7220941014b0d0020090e021101110b2009210203402002410176220420016a22052001200620054105746a200341086a412010a0084101481b2101200220046b220241014b0d000b0b200620014105746a2210200341086a412010a0080d0f410021020240200941014b0d0020090e02120f120b2009210403402004410176220520026a22082002200620084105746a200341286a412010a0084101481b2102200420056b220441014b0d000c0f0b0b200241036a2d0000210520022f000121062001410c6a2802002109200141086a280200210d200141046a280200210402400240024020022d00002208417f6a220141024b0d00024020010e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200841004720062005411074727241ff01710d010b2004200910ac0620034180026a41186a420037030020034180026a41106a2205420037030020034180026a41086a22024200370300200342003703800241fb8fc800ad4280808080b00284220710012201290000210b2002200141086a2900003703002003200b37038002200110354189eaca00ad4280808080f0008410012201290000210b20034198016a41086a2208200141086a2900003703002003200b37039801200110352005200329039801220b370300200341d8016a41086a22012002290300370300200341d8016a41106a2202200b370300200341d8016a41186a2205200829030037030020032003290380023703d80120034180026a200341d8016a10fe01200420092003280280022206410120061b2210200329028402420020061b220b422088a710ad06200542003703002002420037030020014200370300200342003703d80120071001220a2900002107200341b8016a41086a2206200a41086a290000370300200320073703b801200a103520012006290300370300200320032903b8013703d801419cdfca00ad4280808080d000841001220a29000021072006200a41086a290000370300200320073703b801200a1035200220032903b80122073703002008200129030037030020034198016a41106a200737030020034198016a41186a2006290300370300200320032903d8013703980120034180026a20034198016a412010d50120032d0080022106200520034199026a290000370300200220034191026a290000370300200120034189026a29000037030020032003290081023703d801024020064101470d00200341f8006a41186a20052903002207370300200341f8006a41106a2002290300220c370300200341f8006a41086a2001290300220e370300200320032903d801220f370378200520073703002002200c3703002001200e3703002003200f3703d801410021010240024002400240200941014b0d0020090e020201020b2009210203402002410176220520016a22062001200420064105746a200341d8016a412010a0084101481b2101200220056b220241014b0d000b0b200420014105746a200341d8016a412010a008450d010b20034198016a41186a420037030020034198016a41106a2206420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b00284100122052900002107200341e8006a41086a2201200541086a2900003703002003200737036820051035200220012903003703002003200329036837039801419cdfca00ad4280808080d000841001220529000021072001200541086a2900003703002003200737036820051035200620032903682207370300200341c8006a41086a2002290300370300200341c8006a41106a2007370300200341c8006a41186a20012903003703002003200329039801370348200341c8006aad428080808080048410070c010b20034199026a200341f0016a29030037000020034191026a200341e8016a29030037000020034189026a200341e0016a290300370000200320032903d80137008102200341013a00800220034180026a10ab060b0240200b42ffffff3f83500d00201010350b4200210720034198016a41186a420037030020034198016a41106a2206420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012205290000210b200341e8006a41086a2201200541086a2900003703002003200b370368200510352002200129030037030020032003290368370398014189eaca00ad4280808080f0008410012205290000210b2001200541086a2900003703002003200b3703682005103520062003290368220b370300200341c8006a41086a2002290300370300200341c8006a41106a200b370300200341c8006a41186a2001290300370300200320032903980137034820034120360284022003200341c8006a360280022004200920034180026a1098020240200d41ffffff3f71450d00200410350b2003418a063b01800241b0b4cc00410020034180026a10d4010c160b0240200d41ffffff3f71450d00200410350b20004200370308200041186a4102360200420121070c160b200341286a41186a200141196a290000370300200341286a41106a200141116a290000370300200341286a41086a200141096a2900003703002003200129000137032841022101024020022d00000d0020022d00014101470d002002411a6a2901002107200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002109200241126a2f01002108200241116a2d0000210a200241106a2d0000210d2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a009f01200320143a009e01200320153b019c01200320163a009b01200320173a009a01200320183b0198012003200a3a00a7012003200d3a00a601200320103b01a401200320113a00a301200320123a00a201200320133b01a001200320013a00af01200320043a00ae01200320053b01ac01200320063a00ab01200320093a00aa01200320083b01a801200320073701b001200341f8006a41186a22012007370300200341f8006a41106a220220032901a801370300200341f8006a41086a220420032901a0013703002003200329019801370378200341b8016a41186a2001290300370300200341b8016a41106a2002290300370300200341b8016a41086a2004290300370300200320032903783703b801200341b8016a200341286a412010a008450d0920034180026a41186a420037030020034180026a41106a2204420037030020034180026a41086a22014200370300200342003703800241fb8fc800ad4280808080b002841001220229000021072001200241086a2900003703002003200737038002200210354189eaca00ad4280808080f0008410012202290000210720034198016a41086a2205200241086a29000037030020032007370398012002103520042003290398012207370300200341d8016a41086a2001290300370300200341d8016a41106a2007370300200341d8016a41186a200529030037030020032003290380023703d80120034180026a200341d8016a10fe01410121092003280280022202410120021b210641f2dfca0021084109210a4100210102400240200329028402420020021b2207422088a7220d41014b0d00200d0e020901090b200d210203402002410176220420016a22052001200620054105746a200341b8016a412010a0084101481b2101200220046b220241014b0d000b0b200620014105746a2210200341b8016a412010a0080d07410021020240200d41014b0d00200d0e020907090b200d210403402004410176220520026a22092002200620094105746a200341286a412010a0084101481b2102200420056b220441014b0d000c070b0b0c090b200341d0016a200141196a290000370300200341b8016a41106a200141116a290000370300200341c0016a200141096a290000370300200320012900013703b80141022101200241036a2d0000210520022f0001210602400240024020022d00002209417f6a220441024b0d00024020040e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200941004720062005411074727241ff01710d010b20034180026a41186a420037030020034180026a41106a2204420037030020034180026a41086a22014200370300200342003703800241fb8fc800ad4280808080b002841001220229000021072001200241086a2900003703002003200737038002200210354189eaca00ad4280808080f0008410012202290000210720034198016a41086a2205200241086a29000037030020032007370398012002103520042003290398012207370300200341d8016a41086a2001290300370300200341d8016a41106a2007370300200341d8016a41186a200529030037030020032003290380023703d80120034180026a200341d8016a10fe012003280280022202410120021b210641002101024002400240200329028402420020021b2207422088a7220241014b0d0020020e020201020b03402002410176220420016a22052001200620054105746a200341b8016a412010a0084101481b2101200220046b220241014b0d000b0b200620014105746a200341b8016a412010a0080d000240200742ffffff3f83500d00200610350b4200210720034198016a41186a420037030020034198016a41106a2205420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012204290000210b200341e8006a41086a2201200441086a2900003703002003200b37036820041035200220012903003703002003200329036837039801419cdfca00ad4280808080d0008410012204290000210b2001200441086a2900003703002003200b3703682004103520052003290368220b370300200341c8006a41086a2002290300370300200341c8006a41106a200b370300200341c8006a41186a20012903003703002003200329039801370348412010332201450d0c200120032903b801370000200141186a200341b8016a41186a2202290300370000200141106a200341b8016a41106a2204290300370000200141086a200341b8016a41086a2205290300370000200341c8006aad42808080808004842001ad428080808080048410022001103520034199026a200229030037000020034191026a200429030037000020034189026a2005290300370000200320032903b80137008102200341013a00800220034180026a10ab060c150b02402007a72201450d00200141ffffff3f71450d00200610350b410321010b20004200370308200041206a41093602002000411c6a41f2dfca00360200200041186a200141809c0472360200420121070c140b200241036a2d0000210420022f000121050240024020022d00002206417f6a220141024b0d00024020010e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200641004720052004411074727241ff0171450d0020004200370308200041186a4102360200420121070c140b4200210720034198016a41186a420037030020034198016a41106a2205420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012204290000210b200341e8006a41086a2201200441086a2900003703002003200b37036820041035200220012903003703002003200329036837039801419cdfca00ad4280808080d0008410012204290000210b2001200441086a2900003703002003200b3703682004103520052003290368220b370300200341c8006a41086a2002290300370300200341c8006a41106a200b370300200341c8006a41186a20012903003703002003200329039801370348200341c8006aad42808080808004841007200341003a00800220034180026a10ab060c120b41821c21010c0e0b20042009104d000b20012009104e000b200620024105746a200341286a412010a0080d0141ce9cc8002108410d210a410021090b02402007a722010d00410321010c030b0240200141ffffff3f71450d00200610350b410321010c020b200341d8016a41186a2202200341286a41186a290300370300200341d8016a41106a2204200341286a41106a290300370300200341d8016a41086a2205200341286a41086a290300370300200320032903283703d8012001200d4f0d02201020032903d801370000201041186a2002290300370000201041106a2004290300370000201041086a20052903003700002006200d10ac0620034198016a41186a2205420037030020034198016a41106a2204420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b00284220b10012209290000210c200341e8006a41086a2201200941086a2900003703002003200c370368200910352002200129030037030020032003290368370398014189eaca00ad4280808080f0008410012209290000210c2001200941086a2900003703002003200c3703682009103520042003290368220c370300200341c8006a41086a220a2002290300370300200341c8006a41106a2210200c370300200341c8006a41186a22112001290300370300200320032903980137034820034120360284022003200341c8006a360280022006200d20034180026a10980220034180026a41186a200341b8016a41186a29030037030020034180026a41106a200341b8016a41106a29030037030020034180026a41086a200341b8016a41086a290300370300200320032903b801370380024101210820034180026a41012006200d10aa062005420037030020044200370300200242003703002003420037039801200b10012209290000210b2001200941086a2900003703002003200b37036820091035200220012903003703002003200329036837039801419cdfca00ad4280808080d0008410012209290000210b2001200941086a2900003703002003200b3703682009103520042003290368220b370300200a20022903003703002010200b37030020112001290300370300200320032903980137034820034180026a200341c8006a412010d50120032d0080022101200520034180026a41196a290000370300200420034180026a41116a290000370300200220034180026a41096a2900003703002003200329008102370398010240024020014101460d0041002108200341003a00d8010c010b200341d8016a41096a200341a0016a290300370000200341d8016a41116a200341a8016a290300370000200341d8016a41196a200341b0016a290300370000200341013a00d80120032003290398013700d9010b20034199026a200341d0016a29030037000020034191026a200341c8016a29030037000020034189026a200341c0016a290300370000200320032903b80137008102200341013a00800202402008450d00200341d8016a41017220034180026a410172412010a0080d0020034198016a41186a2209420037030020034198016a41106a2208420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012205290000210b200341e8006a41086a2201200541086a2900003703002003200b37036820051035200220012903003703002003200329036837039801419cdfca00ad4280808080d0008410012205290000210b2001200541086a2900003703002003200b3703682005103520042003290368370000200441086a2001290300370000200341c8006a41086a2002290300370300200341c8006a41106a2008290300370300200341c8006a41186a20092903003703002003200329039801370348412010332201450d0420012003290328370000200141186a200341286a41186a2202290300370000200141106a200341286a41106a2204290300370000200141086a200341286a41086a2205290300370000200341c8006aad42808080808004842001ad428080808080048410022001103520034199026a200229030037000020034191026a200429030037000020034189026a20052903003700002003200329032837008102200341013a00800220034180026a10ab060b200742ffffff3f83500d00200610350b2003418a083b01800241b0b4cc00410020034180026a10d401420021070c0b0b20004200370308200041206a200a3602002000411c6a2008360200200041186a200941ff017141107420017241801c72360200420121070c0b0b2001200d419898c8001042000b1045000b200620024105746a200341286a412010a0080d0241ce9cc8002108410d210a4100210d0b02402007a72201450d00200141ffffff3f71450d00200610350b410321010b20004200370308200041206a200a3602002000411c6a2008360200200041186a200d41ff017141107420017241801c72360200420121070c060b20034180026a41186a2205200341286a41186a29030037030020034180026a41106a2208200341286a41106a29030037030020034180026a41086a220a200341286a41086a29030037030020032003290328370380020240200120094f0d002010200329038002370000201041186a2005290300370000201041106a2008290300370000201041086a200a2903003700002006200910ac06200341d8016a41186a4200370300200341d8016a41106a220d4200370300200341d8016a41086a22044200370300200342003703d80141fb8fc800ad4280808080b00284220b10012201290000210c200341b8016a41086a2202200141086a2900003703002003200c3703b8012001103520042002290300370300200320032903b8013703d8014189eaca00ad4280808080f0008410012201290000210c2002200141086a2900003703002003200c3703b80120011035200d20032903b801220c37030020034198016a41086a2201200429030037030020034198016a41106a2204200c37030020034198016a41186a220d2002290300370300200320032903d801370398012003412036028402200320034198016a360280022006200920034180026a1098022005200341086a41186a2903003703002008200341086a41106a290300370300200a200341086a41086a290300370300200320032903083703800220034180026a41012006200910aa06200d420037030020044200370300200142003703002003420037039801200b10012205290000210b200341e8006a41086a2202200541086a2900003703002003200b37036820051035200120022903003703002003200329036837039801419cdfca00ad4280808080d0008410012205290000210b2002200541086a2900003703002003200b3703682005103520042003290368220b370300200341c8006a41086a2001290300370300200341c8006a41106a200b370300200341c8006a41186a2002290300370300200320032903980137034820034180026a200341c8006a412010d50120032d0080022102200d20034199026a290000370300200420034191026a290000370300200120034189026a290000370300200320032900810237039801024020024101470d00200341b8016a41186a20034198016a41186a290300220b370300200341b8016a41106a20034198016a41106a290300220c370300200341b8016a41086a20034198016a41086a290300220e3703002003200329039801220f3703b801200341d8016a41186a200b370300200341d8016a41106a200c370300200341d8016a41086a200e3703002003200f3703d80141002101024020094101460d004100210103402009410176220220016a22042001200620044105746a200341d8016a412010a0084101481b2101200920026b220941014b0d000b0b0240200620014105746a200341d8016a412010a008450d00200341f8006a41186a4200370300200341f8006a41106a22054200370300200341f8006a41086a220242003703002003420037037841fb8fc800ad4280808080b0028410012204290000210b20034198016a41086a2201200441086a2900003703002003200b3703980120041035200220012903003703002003200329039801370378419cdfca00ad4280808080d0008410012204290000210b2001200441086a2900003703002003200b37039801200410352005200329039801220b37030020034180026a41086a200229030037030020034180026a41106a200b37030020034180026a41186a2001290300370300200320032903783703800220034180026aad428080808080048410070c010b20034199026a200341f0016a29030037000020034191026a200341e8016a29030037000020034189026a200341e0016a290300370000200320032903d80137008102200341013a00800220034180026a10ab060b2003418a043b01800241b0b4cc00410020034180026a10d401200742ffffff3f83500d0120061035420021070c050b20012009418898c8001042000b420021070c030b20004200370308200041206a410d3602002000411c6a41ce9cc800360200200041186a2001360200420121070c030b20034180026a41186a200341b8016a41186a29030037030020034180026a41106a200341b8016a41106a29030037030020034180026a41086a200341b8016a41086a290300370300200320032903b801370380024100210920034180026a2102410021040b024020092008470d00200341286a20094101108a01200328022c2108200328022821060b200620044105746a220141206a2001200920046b410574109e081a20012002290000370000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a2900003700002003200941016a3602304200210720034198016a41186a420037030020034198016a41106a2205420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012204290000210b200341e8006a41086a2201200441086a2900003703002003200b370368200410352002200129030037030020032003290368370398014189eaca00ad4280808080f0008410012204290000210b2001200441086a2900003703002003200b3703682004103520052003290368220b370300200341c8006a41086a2002290300370300200341c8006a41106a200b370300200341c8006a41186a2001290300370300200320032903980137034820034120360284022003200341c8006a360280022003280228200328023020034180026a10980220034180026a41186a200341b8016a41186a29030037030020034180026a41106a200341b8016a41106a29030037030020034180026a41086a200341b8016a41086a290300370300200320032903b8013703800241b0b4cc00410020032802282201200328023010aa062003410a3b01800241b0b4cc00410020034180026a10d401200841ffffff3f71450d00200110350b200020073703080b2000200737030020034180036a24000b8b970107017f027e117f017e027f087e1d7f230041d0086b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0900010203040506070a000b200341d4076a4101360200200342013702c407200341e8d4ca003602c007200341043602b4062003419cd5ca003602b0062003200341b0066a3602d007200341c0076a41b0b4cc00104c000b200141306a2903002104200141286a2903002105200341b0066a41206a200141246a280200360200200341b0066a41186a2001411c6a290200370300200341b0066a41106a200141146a290200370300200341b0066a41086a2001410c6a2902003703002003200141046a2902003703b006418222210102400240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a29010037038804200320013a008704200320063a008604200320073b018404200320083a008304200320093a0082042003200a3b0180042003200b3a00ff032003200c3a00fe032003200d3b01fc032003200e3a00fb032003200f3a00fa03200320103b01f803200320113a00f703200320123a00f603200320133b01f403200320143a00f303200320153a00f203200320163b01f003200341c0076a41206a200341b0066a41206a280200360200200341c0076a41186a200341b0066a41186a290300370300200341c0076a41106a200341b0066a41106a290300370300200341c0076a41086a200341b0066a41086a290300370300200320032903b0063703c007200341f8046a200341c0076a108b02418122210120032d00f8044101460d00200341f8046a41086a2d0000210720034181056a2f0000210820034183056a2d0000210920034184056a2d0000210a20034185056a2f0000210b20034187056a2d0000210c200341f8046a41106a2d0000210d20034189056a2f0000210e2003418b056a2d0000210f2003418c056a2d000021102003418d056a2f000021112003418f056a2d00002112200341f8046a41186a2d0000211320034191056a290000211720032f00f904211420032d00fb04211520032d00fc04211620032f00fd04211820032d00ff042119200341286a2005200442c0843d4200109808200341186a2003290328221a200341286a41086a290300221b42c0fb42427f108408200341086a201a201b42d0860342001084082003200341086a41086a2903002003290308221b200520032903187c221a421480221ca7417f201a42d086037e221a428080808080c8d007541b201a201c42c0fb427e7c42a0c21e566aad7c221a201b54ad7c221b4200201a428080e983b1de1656201b420052201b501b22011b221b3703f0022003201a428080e983b1de1620011b221a3703e8022003200341f0036a360280062003200341f0036a3602e0012003200341e0016a3602c807200320034180066a3602c4072003200341e8026a3602c007200341f8046a200341f0036a200341c0076a108c0320032802f8044101470d01418322210120032d00fc044104460d020b200041206a411c3602002000411c6a41e3adc800360200200041186a200136020020004200370308420121050c160b200341f8046a41086a2903004201520d00200341f8046a41106a290300211c20032802e0012101200341f8076a200341f8046a41186a290300370300200341f0076a201c370300200341c0076a41086a41003a0000200341c9076a2001290000370000200341d1076a200141086a290000370000200341d9076a200141106a290000370000200341e1076a200141186a290000370000200341033a00c00741b0b4cc004100200341c0076a10d4010b4186f0cb00ad4280808080800184221c10012201290000211d2001290008211e20011035418ef0cb00ad4280808080d00184221f1001220129000021202001290008212120011035200320213703900520032020370388052003201e370380052003201d3703f8042003200341f8046a412010c0012003280204210220032802002106201c10012201290000211c2001290008211d20011035201f10012201290000211e2001290008211f200110352003201f370390052003201e370388052003201d370380052003201c3703f80420032002410020061b220241016a3602c007200341f8046aad4280808080800484200341c0076aad4280808080c000841002200341c0076a41186a2222200341f0036a41186a290300370300200341c0076a41106a2223200341f0036a41106a290300370300200341c0076a41086a2224200341f0036a41086a290300370300200320032903f0033703c007200341f8046a200210b506200335028005211c20032802f8042106412010332201450d15200120032903c007370000200141186a2022290300370000200141106a2023290300370000200141086a20242903003700002001412041c00010372201450d1520012005370020200141286a2004370000200141c00041800110372201450d152001201a37005020012017370048200120133a0047200120123a0046200120113b0044200120103a00432001200f3a00422001200e3b00402001200d3a003f2001200c3a003e2001200b3b003c2001200a3a003b200120093a003a200120083b0038200120073a0037200120193a0036200120183b0034200120163a0033200120153a0032200120143b0030200141d8006a201b370000201c4220862006ad842001ad4280808080800c84100220011035024020032802fc04450d00200610350b200341c8076a41003a00002003410c3a00c007200341c0076a410c6a200236020041b0b4cc004100200341c0076a10d4010c120b200241036a2d0000210620022f00012107200141046a28020021090240024002400240024020022d00002208417f6a220141024b0d00024020010e03000102000b200241086a2802004102490d00200241046a28020041ff0171450d010b4182a2042101200720064110747220084100477241ff01710d010b4186f0cb00ad4280808080800184100122012d000f210b20012d000e210c20012f000c210d20012d000b210e20012d000a210f20012f0008211020012d0007211120012d0006211220012f0004211320012d0003211420012d0002211520012f00002116200110354180eaca00ad428080808090018410012201290008210520012d0007211820012d0006211920012f0004212220012d0003212320012d0002212420012f0000212520011035200320093602c0012003200341c0016aad4280808080c00084100322012900003703800620011035200341cc076a200341c4016a360200200320034188066a3602c4072003200341c0016a3602c807200320034180066a3602c007200341f0036a200341c0076a107b20032802f803220841206a2202417f4c0d0c20032802f003210a0240024020020d0041002106410121010c010b200210332201450d0c200221060b024002402006410f4d0d00200621070c010b200641017422074110200741104b1b22074100480d0a024020060d002007103322010d010c190b20062007460d0020012006200710372201450d180b2001200b3a000f2001200c3a000e2001200d3b000c2001200e3a000b2001200f3a000a200120103b0008200120113a0007200120123a0006200120133b0004200120143a0003200120153a0002200120163b00000240024020074170714110460d00200721060c010b200741017422064120200641204b1b22064100480d0a20072006460d0020012007200610372201450d180b20012005370018200120183a0017200120193a0016200120223b0014200120233a0013200120243a0012200120253b001002400240200641606a2008490d00200621070c010b2008415f4b0d0a200641017422072002200720024b1b22074100480d0a20062007460d0020012006200710372201450d180b200141206a200a2008109d081a024020032802f403450d00200a10350b200341c0076a2001200210df02024020032903c00742015222060d002002ad4220862001ad8410070b200341f0036a200341c8076a41e000109d081a200341c0076a200341f0036a41e000109d081a024020060d00200341e8026a200341c0076a41e000109d081a02402007450d00200110350b200341b0066a41066a200341e8026a41e000109d081a200341f8046a200341b0066a41e600109d081a200341e0016a200341f8046a41066a41e000109d081a20032903f00121042003200341f8016a290300221a37038005200320043703f804024002402004201a844200520d00200342003703f803200342003703f0030c010b2003200341e0016a41206a22013602f003200341b0066a2001200341f8046a200341f0036a10a802200341b0066a41206a290300210520032903c806211b024020032903b0064201520d0020032903b806211c200341f8076a200341b0066a41106a290300370300200341f0076a201c370300200341c0076a41086a41003a0000200341c9076a2001290000370000200341d1076a200141086a290000370000200341d9076a200141106a290000370000200341e1076a200141186a290000370000200341033a00c00741b0b4cc004100200341c0076a10d4010b2003201b3703f003200320053703f803201b2005844200520d030b2003200341f0036a36028006200341f0036a21080c030b02402007450d00200110350b4183a20421010b20004200370308200041206a41143602002000411c6a41cfadc800360200200041186a2001360200420121050c150b200320053703f8032003201b3703f0032003200341f0036a36028006200341f0036a21080b42002105200341f8046a41186a220e4200370300200341f8046a41106a22024200370300200341f8046a41086a22014200370300200342003703f80441b6fdc600ad4280808080800184221c10012207290000211b200341b0066a41086a2206200741086a2900003703002003201b3703b0062007103520012006290300370300200320032903b0063703f80441e489c200ad4280808080d0018422171001220a290000211b200341e8026a41086a2207200a41086a2900003703002003201b3703e802200a1035200220032903e802221b370300200341c0076a41086a220a2001290300370300200341c0076a41106a220b201b370300200341c0076a41186a220c2007290300370300200320032903f8043703c007200341386a200341c0076a412010d701200341386a41106a290300211d2003290340211e2003280238210d200841086a290300211f2008290300211b200e42003703002002420037030020014200370300200342003703f804201c10012208290000211c2006200841086a2900003703002003201c3703b0062008103520012006290300370300200320032903b0063703f804201710012206290000211c2007200641086a2900003703002003201c3703e80220061035200220032903e802221c370300200a2001290300370300200b201c370300200c2007290300370300200320032903f8043703c00720034200201d4200200d1b221c201f7d201e4200200d1b2217201b54ad7d221d2017201b7d221b201756201d201c56201d201c511b22011b3703b80620034200201b20011b3703b006200341c0076aad4280808080800484200341b0066aad42808080808002841002200c201a370300200b2004370300200a41033a00002003410c3a00c007200341c0076a410c6a200936020041b0b4cc004100200341c0076a10d4010c120b200241036a2d0000210720022f00012108200141046a28020021010240024020022d00002209417f6a220641024b0d00024020060e03000102000b200241086a2802004104490d00200241046a28020041ff0171450d010b4182a2042102200820074110747220094100477241ff01710d050b200341c0076a200110b506200341d0006a20032802c007220220032802c80741b0b4cc0041004100108a0220032802502106024020032802c407450d00200210350b4183a204210220064101470d044186f0cb00ad42808080808001841001220229000021052002290008210420021035419bf0cb00ad428080808090018410012202290000211a2002290008211b200210352003201b370390052003201a370388052003200437038005200320053703f804200341c0076a200341f8046a10c50202400240024020032802c00722020d0041002107200341003602b806200342043703b0060c010b20032902c4072105200320023602b006200320053702b4062005422088a722062005a72207470d010b200341b0066a2007410110860120032802b406210720032802b006210220032802b80621060b200220064102746a20013602002003200641016a22063602b8064186f0cb00ad42808080808001841001220129000021052001290008210420011035419bf0cb00ad428080808090018410012201290000211a2001290008211b200110352003201b370390052003201a370388052003200437038005200320053703f804024020020d00200341f8046aad428080808080048410070c110b200341203602c4072003200341f8046a3602c00720022006200341c0076a109503200741ffffffff0371450d10200210350c100b2001412c6a280200210c200141286a2802002106200141246a280200210b200341e0016a41186a200141196a290000370300200341e0016a41106a200141116a290000370300200341e0016a41086a200141096a290000370300200320012900013703e0014102210120022d00000d0d20022d00014101470d0d200241196a2d00002101200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002118200241046a2d00002119200241026a2f0100212220032002411a6a29010037038003200320013a00ff02200320073a00fe02200320083b01fc02200320093a00fb022003200a3a00fa022003200d3b01f8022003200e3a00f7022003200f3a00f602200320103b01f402200320113a00f302200320123a00f202200320133b01f002200320143a00ef02200320153a00ee02200320163b01ec02200320183a00eb02200320193a00ea02200320223b01e8020240200c41818001490d0041c3adc800210a410c21094103210141112108410221070c0f0b200cad221b422086200bad84100922012900002105200141086a2900002104200141106a290000211a200341f0036a41186a200141186a290000370300200341f0036a41106a201a370300200341f0036a41086a2004370300200320053703f00320011035200341c0076a200341f0036a10d206200341f0006a20032802c007220220032802c80741b0b4cc0041004100108a0220032802702101024020032802c407450d00200210350b20014101460d0c2003200341e0016a3602c4072003200341f0036a3602c007200341f8046a200341c0076a10a706200341c0076a200341f8046a10d306200341e8006a20032802c007220220032802c80741b0b4cc0041004100108a0220032802682101024020032802c407450d00200210350b20014101460d0c200341d8006a201b42004280a094a58d1d4200108408200320032903582204428080e983b1de167c2205370380062003200341d8006a41086a2903002005200454ad7c2204370388062003200341e8026a3602a0062003200341e8026a3602c0012003200341c0016a3602c8072003200341a0066a3602c407200320034180066a3602c007200341b0066a200341e8026a200341c0076a108c030240024020032802b0064101470d00200341bc066a2802002109200341b0066a41086a280200210a20032d00b706210220032d00b606210720032d00b506210820032d00b40621010c010b410421010240200341b0066a41086a2903004201520d00200341b0066a41106a290300211a20032802c0012102200341f8076a200341b0066a41186a290300370300200341f0076a201a370300200341c0076a41086a41003a0000200341c9076a2002290000370000200341d1076a200241086a290000370000200341d9076a200241106a290000370000200341e1076a200241186a290000370000200341033a00c00741b0b4cc004100200341c0076a10d4010b0b200141ff01714104470d0e200341c0076a200341f0036a10d20620032802c0072101200320032802c8073602b406200320013602b006200b200c200341b0066a109403024020032802c407450d00200110350b200341f0076a2004370300200341e8076a200537030020034188086a4100360200200341c0076a41106a200341e8026a41086a290300370300200341c0076a41186a200341e8026a41106a290300370300200341e0076a200341e8026a41186a29030037030020034194086a200341f0036a41086a2903003702002003419c086a200341f0036a41106a290300370200200341a4086a200341f0036a41186a290300370200200342013703c007200320032903e8023703c8072003420837038008200341003602f807200320032903f00337028c08200341c4086a200341e0016a41186a290300370200200341bc086a200341e0016a41106a290300370200200341b4086a200341e0016a41086a290300370200200320032903e0013702ac08200341b0066a200341f8046a10d30620032802b0062101200320032802b806360284062003200136028006200341c0076a20034180066a10cd06024020032802b406450d00200110350b200341c0076a41086a41073a0000200341c9076a20032903f804370000200341d1076a200341f8046a41086a290300370000200341d9076a200341f8046a41106a290300370000200341e1076a200341f8046a41186a2903003700002003410c3a00c00741b0b4cc004100200341c0076a10d4012006450d0f200b10350c0f0b200341c0016a41186a200141196a290000370300200341c0016a41106a200141116a290000370300200341c0016a41086a200141096a290000370300200320012900013703c00141022101024002400240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a29010037039806200320013a009706200320063a009606200320073b019406200320083a009306200320093a0092062003200a3b0190062003200b3a008f062003200c3a008e062003200d3b018c062003200e3a008b062003200f3a008a06200320103b018806200320113a008706200320123a008606200320133b018406200320143a008306200320153a008206200320163b018006200341a0066a200341c0016a10d306200341c0076a20032802a006220120032802a80610b20220032903c0072105200341f8046a200341c8076a418801109d081a024020054202510d00200341f0036a200341f8046a418801109d081a024020032802a406450d00200110350b200341e8026a200341f0036a418801109d081a200341e0016a200341e8026a418801109d081a200320053703b006200341b0066a41086a200341e0016a418801109d081a200341f0036a41186a2201200341b0066a41206a290300370300200341f0036a41106a2202200341b0066a41186a290300370300200341f0036a41086a2206200341b0066a41106a290300370300200320032903b8063703f00320054201520d02200341e0066a2903002104200341d8066a290300211a200341c0076a410e6a2006290300370100200341c0076a41166a2002290300370100200341c0076a411e6a20012903002205370100200341f8046a411e6a22072005370100200320032903f0033701c607200341f8046a41086a200341c0076a41086a290100370300200341f8046a41106a200341c0076a41106a290100370300200341f8046a41186a200341c0076a41186a290100370300200320032901c0073703f804200120072901003703002002200341f8046a41166a2901003703002006200341f8046a410e6a290100370300200320032901fe043703f003200341f0036a20034180066a412010a0080d02200341c0076a200341fc066a10d20620033502c80742208620032802c0072201ad841007024020032802c407450d00200110350b200341c0076a200341c0016a10d30620033502c80742208620032802c0072201ad841007024020032802c407450d00200110350b2003201a3703e802200320043703f0020240201a200484500d00200320034180066a3602e001200341f8046a20034180066a200341e8026a200341e0016a10f00220032903f8044201520d002003290380052105200341f8076a200341f8046a41106a290300370300200341f0076a2005370300200341c0076a41086a41003a0000200341c9076a200329038006370000200341d1076a20034180066a41086a290300370000200341d9076a20034180066a41106a290300370000200341e1076a20034198066a290300370000200341033a00c00741b0b4cc004100200341c0076a10d4010b200341c0076a41086a410a3a0000200341c9076a20032903c001370000200341d1076a200341c0016a41086a290300370000200341d9076a200341d0016a290300370000200341e1076a200341d8016a2903003700002003410c3a00c00741b0b4cc004100200341c0076a10d401200341f4066a2802002201450d13200141306c450d1320032802f00610350c130b024020032802a406450d00200110350b41adadc8002102410a21064180801021070c020b410021070c020b41a4adc800210241092106418080142107200341f4066a2802002201450d00200141306c450d0020032802f00610350b410321010b20004200370308200041206a20063602002000411c6a2002360200200041186a20074180801c7120017241802272360200420121050c100b200141386a2903002105200141306a29030021042001412c6a2802002108200141286a2802002106200141246a280200210720034180036a200141196a290000370300200341f8026a200141116a290000370300200341f0026a200141096a290000370300200320012900013703e80220032002411a6a290100370390052003200241026a2901003703f80420032002410a6a290100370380052003200241126a290100370388050240024020022d00014101470d0020022d000041ff01710d00200341f0036a41186a200341f8046a41186a2202290300370300200341f0036a41106a200341f8046a41106a2209290300370300200341f0036a41086a200341f8046a41086a220a290300370300200320032903f8043703f0034182a20c2101200341f0036a10e902450d0b2008ad4220862007ad8410092201290000211a200141086a290000211b200141106a290000211c2002200141186a2900003703002009201c370300200a201b3703002003201a3703f80420011035200341c0076a200341f8046a10d206200341f8006a20032802c007220220032802c80741b0b4cc0041004100108a0220032802782101024020032802c407450d00200210350b20014101460d012003200341e8026a3602c4072003200341f8046a3602c007200341b0066a200341c0076a10a706200341c0076a200341f8046a10d20620032802c0072101200320032802c8073602e401200320013602e00120072008200341e0016a109403024020032802c407450d00200110350b20032903b006211a20032903b806211b20032903c006211c200341e1076a20032903c806370000200341d9076a201c370000200341d1076a201b370000200341c9076a201a370000200341c0076a41086a41073a00002003410c3a00c00741b0b4cc004100200341c0076a10d401413010332201450d1220012004370320200120032903f003370000200141286a2005370300200141186a200341f0036a41186a290300370000200141106a200341f0036a41106a290300370000200141086a200341f0036a41086a29030037000020034184086a42818080801037020020034194086a200341f8046a41086a2903003702002003419c086a200341f8046a41106a290300370200200341a4086a200341f8046a41186a2903003702002003200136028008200341003602f807200342003703c007200320032903f80437028c08200341b4086a200341e8026a41086a290300370200200341bc086a200341e8026a41106a290300370200200341c4086a200341e8026a41186a290300370200200320032903e8023702ac08200341e0016a200341b0066a10d30620032802e0012102200320032802e801360284062003200236028006200341c0076a20034180066a10cd06024020032802e401450d00200210350b200110352006450d0f200710350c0f0b4182a20c21010c0a0b4183a20c21010c090b200141306a2903002105200141286a2903002104200341c0016a41186a200141196a290000370300200341c0016a41106a200141116a290000370300200341c0016a41086a200141096a290000370300200320012900013703c0014182a21021010240024002400240024002400240024020022d00000d0020022d00014101470d00200241196a2d00002106200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211820032002411a6a29010037039806200320063a009706200320073a009606200320083b019406200320093a0093062003200a3a0092062003200b3b0190062003200c3a008f062003200d3a008e062003200e3b018c062003200f3a008b06200320103a008a06200320113b018806200320123a008706200320133a008606200320143b018406200320153a008306200320163a008206200320183b01800620034180066a10e902450d00200341f8046a41186a200341c0016a41186a290300370300200341f8046a41106a200341c0016a41106a290300370300200341f8046a41086a200341c0016a41086a290300370300200320032903c0013703f804200341a0066a200341f8046a10d406200341c0076a20032802a006220120032802a80610b20220032903c007211a200341f8046a200341c0076a41086a418801109d081a0240201a4202510d00200341f0036a200341f8046a418801109d081a024020032802a406450d00200110350b200341e8026a200341f0036a418801109d081a200341e0016a200341e8026a418801109d081a2003201a3703b006200341b0066a41086a200341e0016a418801109d081a200341f0036a41186a20034180066a41186a290300370300200341f0036a41106a20034180066a41106a290300370300200341f0036a41086a20034180066a41086a29030037030020032003290380063703f00320032802f006210841002101200341f8066a280200220d41014b0d020240200d0e020004000b200341c0076a41186a200341f0036a41186a290300370300200341c0076a41106a200341f0036a41106a290300370300200341c0076a41086a200341f0036a41086a290300370300200320032903f0033703c00741002106200341c0076a21020c040b024020032802a406450d00200110350b4183a21021010b200041206a410a3602002000411c6a41adadc800360200200041186a200136020020004200370308420121050c150b200d210203402002410176220620016a220720012008200741306c6a200341f0036a412010a0084101481b2101200220066b220241014b0d000b0b2008200141306c6a2202200341f0036a412010a0082206450d01200341c0076a41186a200341f0036a41186a290300370300200341c0076a41106a200341f0036a41106a290300370300200341c0076a41086a200341f0036a41086a290300370300200320032903f0033703c007200341c0076a2102200d2006411f7620016a2206490d040b0240200d200341f4066a280200470d00200341f0066a200d410110880120032802f00621080b2008200641306c6a220141306a2001200d20066b41306c109e081a200141286a200537030020012004370320200141186a200241186a290300370300200141106a200241106a290300370300200141086a200241086a290300370300200120022903003703002003200d41016a220d3602f8060c010b200d20014d0d0120032901f203211a20032901fa03211b200328018204210620032f0186042107200329038804211c200220032f01f0033b01002008200141306c6a220120043703202001201c370318200120073b0116200120063601122001201b37010a2001201a370102200141286a20053703000b200341c0076a10e80220032802c00721250240200d450d00202520032802c80722014105746a210920032802f006210e2025410020011b2102202541206a202520011b21014100210c4100210a0340200a220b41016a210a200e200b41306c6a2108024002400340024020020d00410021020c020b20022008412010a008220641004a0d0141002001200120094622071b21022001200141206a20071b2207210120064100480d000b024002400240200c0d004100210c0c010b200b200c6b2201200d4f0d01200341f8046a41286a2206200e200141306c6a220141286a220b290300370300200341f8046a41206a220f200141206a2210290300370300200341f8046a41186a2211200141186a2212290300370300200341f8046a41106a2213200141106a2214290300370300200341f8046a41086a2215200141086a2216290300370300200320012903003703f804200841086a22182903002105200841106a22192903002104200841186a2222290300211a200841206a2223290300211b2008290300211c200b200841286a22242903003703002010201b3703002012201a37030020142004370300201620053703002001201c370300202420062903003703002023200f290300370300202220112903003703002019201329030037030020182015290300370300200820032903f8043703000b200721010c020b2001200d41f485cc001042000b200c41016a210c0b200a200d470d000b200c417f6a200d4f0d002003200d200c6b3602f8060b024020032802c40741ffffff3f71450d00202510350b200341f8046a41186a4200370300200341f8046a41106a22064200370300200341f8046a41086a22014200370300200342003703f80441a0e4cb00ad42808080808002841001220229000021052001200241086a290000370300200320053703f804200210354189eaca00ad4280808080f00084100122022900002105200341e8026a41086a2207200241086a290000370300200320053703e80220021035200620032903e8022205370300200341c0076a41086a2001290300370300200341c0076a41106a2005370300200341c0076a41186a2007290300370300200320032903f8043703c007200341f8046a200341c0076a10a20220032802f804210120032902fc042105200341003602c807200342013703c007200341c0076a41002005420020011b2205422088a7220241306c220741306d108a012005a721082001410820011b210920032802c807210602402002450d0020032802c00720064105746a2101200921020340200241086a2900002105200241106a29000021042002290000211a200141186a200241186a290000370000200141106a2004370000200141086a20053700002001201a370000200641016a2106200141206a2101200241306a2102200741506a22070d000b0b200320063602c80702402008450d00200841306c450d00200910350b024020032802c40741ffffff3f71450d0020032802c00710350b024020032802f806200641016a410176490d0020032802e8064101460d00200341c0076a41186a4200370300200341c0076a41106a22064200370300200341c0076a41086a22014200370300200342003703c00741d1c4c700ad4280808080e000841001220229000021052001200241086a290000370300200320053703c0072002103541e7c4c700ad4280808080e00084100122022900002105200341e8026a41086a2207200241086a290000370300200320053703e80220021035200620032903e8022205370300200341f8046a41086a22022001290300370300200341f8046a41106a22062005370300200341f8046a41186a22082007290300370300200320032903c0073703f80420034180016a200341f8046a412010c001200341ec066a2003280284014180e1016a4180e1012003280280011b360200200341013602e8062008200341c0016a41186a22072903003703002006200341c0016a41106a22082903003703002002200341c0016a41086a2206290300370300200320032903c0013703f804200141083a00002003410c3a00c007200341c9076a20032903c001370000200341d1076a2006290300370000200341d9076a2008290300370000200341e1076a200729030037000041b0b4cc004100200341c0076a10d4010b200341c0076a200341b0066a419001109d081a200341f8046a200341c0016a10d30620032802f804210120032003280280053602f403200320013602f003200341c0076a200341f0036a10cd06024020032802fc04450d00200110350b20034184086a2802002201450d0e200141306c450d0e20032802800810350c0e0b2001200d41bc82ca001042000b2006200d104d000b20004200370308200041206a41143602002000411c6a41cfadc800360200200041186a2002360200420121050c0d0b103e000b4104210741adadc8002108410a2109410221060240024020022d00000d0020022d00014101470d00200141186a2d00002126200141176a2d00002127200141156a2f00002128200141146a2d00002129200141136a2d0000212a200141116a2f0000212b200141106a2d0000212c2001410f6a2d0000212d2001410d6a2f0000212e2001410c6a2d0000212f2001410b6a2d00002130200141096a2f00002131200141086a2d00002132200141076a2d00002133200141056a2f00002134200141046a2d00002135200141036a2d0000213620012f000121372003200141196a290000221737039005200320263a008f05200320273a008e05200320283b018c05200320293a008b052003202a3a008a052003202b3b0188052003202c3a0087052003202d3a0086052003202e3b0184052003202f3a008305200320303a008205200320313b018005200320323a00ff04200320333a00fe04200320343b01fc04200320353a00fb04200320363a00fa04200320373b01f80420034180066a200341f8046a10d406200341c0076a200328028006220120032802880610b20220032903c0072105200341f8046a200341c8076a418801109d081a024002400240024020054202510d00200341f0036a200341f8046a418801109d081a0240200328028406450d00200110350b200341e8026a200341f0036a418801109d081a200341e0016a200341e8026a418801109d081a200320053703b006200341b0066a41086a200341e0016a418801109d081a20032802e8064101460d01419badc8002108410621070c020b200328028406450d02200110350c020b200341c0076a41186a4200370300200341c0076a41106a22064200370300200341c0076a41086a22014200370300200342003703c00741d1c4c700ad4280808080e000841001220229000021052001200241086a290000370300200320053703c0072002103541e7c4c700ad4280808080e00084100122022900002105200341e8026a41086a2207200241086a290000370300200320053703e80220021035200620032903e8022205370300200341f8046a41086a2001290300370300200341f8046a41106a2005370300200341f8046a41186a2007290300370300200320032903c0073703f804200341b8016a200341f8046a412010c00120032802bc01410020032802b8011b200341ec066a2802004f0d034192adc8002108410721070b0240200341f4066a2802002201450d00200141306c450d0020032802f00610350b410921090b410321060b20004200370308200041206a20093602002000411c6a2008360200200041186a200741107420067241802272360200420121050c0c0b200341c0076a200341fc066a10d20620033502c80742208620032802c0072201ad841007024020032802c407450d00200110350b200320173703d807200320263a00d707200320273a00d607200320283b01d407200320293a00d3072003202a3a00d2072003202b3b01d0072003202c3a00cf072003202d3a00ce072003202e3b01cc072003202f3a00cb07200320303a00ca07200320313b01c807200320323a00c707200320333a00c607200320343b01c407200320353a00c307200320363a00c207200320373b01c007200341f8046a200341c0076a10d40620033502800542208620032802f8042201ad841007024020032802fc04450d00200110350b200341c0076a200341b0066a419001109d081a20034188086a280200211620034184086a28020021382003280280082112200341f0036a10e80220032802f00321250240024020160d00410021160c010b202520032802f80322014105746a21092025410020011b2102202541206a202520011b21014100210c4100210a0340200a220b41016a210a2012200b41306c6a2108024002400340024020020d00410021020c020b20022008412010a008220641004a0d0141002001200120094622071b21022001200141206a20071b2207210120064100480d000b024002400240200c0d004100210c0c010b200b200c6b220120164f0d01200341f8046a41286a22062012200141306c6a220141286a220b290300370300200341f8046a41206a220d200141206a220e290300370300200341f8046a41186a220f200141186a2210290300370300200341f8046a41106a2211200141106a2213290300370300200341f8046a41086a2214200141086a2215290300370300200320012903003703f804200841086a22182903002105200841106a22192903002104200841186a2222290300211a200841206a2223290300211b2008290300211c200b200841286a2224290300370300200e201b3703002010201a37030020132004370300201520053703002001201c370300202420062903003703002023200d2903003703002022200f2903003703002019201129030037030020182014290300370300200820032903f8043703000b200721010c020b2001201641f485cc001042000b200c41016a210c0b200a2016470d000b200c450d0020162016200c6b220120162001491b21160b024020032802f40341ffffff3f71450d00202510350b20164115490d032016410176ad42307e2205422088a70d012005a72239417f4c0d0120391033223a450d0041002102200341003602f803200342043703f003201241506a213b201241907f6a213c410421064100213d20162111034020112109410021114101210a02402009417f6a223e450d000240024002400240024002402012203e41306c6a220141206a290300200941306c220820126a41406a2207290300220454200141286a290300221a200741086a290300220554201a2005511b0d002009417e6a210c203c20086a2101410021114100210703400240200c2007470d002009210a0c080b20042001290300221b5a21082005200141086a290300221a51210a2005201a5a210b200141506a2101200741016a2107201b2104201a21052008200b200a1b0d000b200741016a210a2007417f7320096a21080c010b203c200941066c410374220c6a2101203e210802400340024020084101470d00410021080c020b20042001290300221b5421072005200141086a290300221a51210a2005201a54210b200141506a21012008417f6a2108201b2104201a21052007200b200a1b0d000b0b20092008490d02200920164b0d01200920086b220a410176220b450d00203b200c6a21012012200841306c6a21070340200341f8046a41286a220c200741286a220d290300370300200341f8046a41206a220e200741206a220f290300370300200341f8046a41186a2210200741186a2211290300370300200341f8046a41106a2213200741106a2214290300370300200341f8046a41086a2215200741086a2218290300370300200320072903003703f804200141086a22192903002105200141106a22222903002104200141186a2223290300211a200141206a2224290300211b200141286a2225290300211c20072001290300370300200d201c370300200f201b3703002011201a37030020142004370300201820053703002025200c2903003703002024200e290300370300202320102903003703002022201329030037030020192015290300370300200120032903f804370300200141506a2101200741306a2107200b417f6a220b0d000b0b024020080d00200821110c050b0240200a41094d0d00200821110c050b200920164b0d022012200841306c6a210d034020092008417f6a2211490d040240200920116b220a4102490d002012200841306c6a220141206a220b2903002012201141306c6a220741206a220c290300221a5a200141286a220e2903002204200741286a220f29030022055a20042005511b0d002007290300210420072001290300370300200341f8046a41186a2210200741186a2213290300370300200341f8046a41106a2214200741106a2215290300370300200341f8046a41086a2218200741086a22192903003703002019200141086a2903003703002015200141106a2903003703002013200141186a290300370300200c200b290300370300200f200e290300370300200320043703f8040240200a4103490d00203e210b200d210c20074180016a290300201a5a20074188016a290300220420055a20042005511b0d0002400340200c220141286a200141d8006a290300370300200141206a200141d0006a290300370300200141186a200141c8006a290300370300200141106a200141c0006a290300370300200141086a200141386a2903003703002001200141306a220c2903003703002008200b417f6a220b460d0120014180016a290300201a5a20014188016a290300220420055a20042005511b450d000b0b200141306a21010b2001201a370320200120032903f804370300200141286a2005370300200141186a2010290300370300200141106a2014290300370300200141086a20182903003703000b2011450d05200d41506a210d20112108200a410a4f0d050c000b0b2009201641eccfca001058000b2008200941eccfca001059000b20092008417f6a2211490d002009201641fccfca001058000b2011200941fccfca001059000b0240203d20032802f403470d00200341f0036a203d410110900120032802f003210620032802f8032202213d0b2006203d4103746a2201200a360204200120113602002003200241016a22023602f8032002213d024020024102490d000240024003400240024002400240024020062002417f6a4103746a2201280200450d00200241037420066a220941746a2802002208200128020422074b0d010b20024103490d022001280204210720062002417d6a220e4103746a28020421010c010b4102213d200241024d0d0620062002417d6a220e4103746a2802042201200720086a4d0d004103213d200241034d0d06200941646a280200200120086a4b0d050b20012007490d010b2002417e6a210e0b02400240024002400240024002402002200e41016a220f4d0d002002200e4d0d012006200e41037422136a2201280204221420012802006a22012006200f41037422156a22022802002210490d02200120164b0d032012201041306c6a220c2002280204220d41306c22026a2107200141306c2106200120106b2209200d6b2201200d4f0d04203a2007200141306c2202109d08220920026a2108200d4101480d0520014101480d05203b20066a21062007210103402006200141506a220a200841506a220b200841706a2202290300200141706a220729030054200241086a2903002205200741086a29030022045420052004511b22071b2202290300370300200641086a200241086a290300370300200641106a200241106a290300370300200641186a200241186a290300370300200641206a200241206a290300370300200641286a200241286a2903003703002008200b20071b21080240200c200a200120071b2201490d00200921020c080b200641506a21062009210220092008490d000c070b0b200f2002418cd0ca001042000b200e2002419cd0ca001042000b2010200141acd0ca001059000b2001201641acd0ca001058000b203a200c2002109d08220b20026a21080240200d4101480d002009200d4c0d00201220066a210a200b2102200c21010340200120072002200741206a290300200241206a29030054200741286a2903002205200241286a29030022045420052004511b22091b2206290300370300200141086a200641086a290300370300200141106a200641106a290300370300200141186a200641186a290300370300200141206a200641206a290300370300200141286a200641286a2903003703002002200241306a20091b2102200141306a2101200741306a200720091b2207200a4f0d03200820024b0d000c030b0b200c2101200b21020c010b20072101200921020b20012002200820026b220620064130706b109d081a024020032802f8032201200e4d0d0020032802f003220620136a22022014200d6a360204200220103602002001200f4d0d02200620156a2202200241086a2001200f417f736a410374109e081a20032001417f6a22023602f803200241014b0d010c030b0b200e200141bcd0ca001042000b200f2001104e000b2002213d0b2011450d030c000b0b1045000b1044000b024020032802f40341ffffffff0171450d00200610350b2039413070210120394130490d0120392001460d01203a10350c010b20164102490d002016417f6a21062012201641306c6a2108410021090340024002400240201620062201417f6a2206490d00201620066b22074102490d022012200141306c6a220141206a220a2903002012200641306c6a220241206a220b290300221a5a200141286a220c2903002204200241286a220d29030022055a20042005511b0d022002290300210420022001290300370300200341f8046a41186a220e200241186a220f290300370300200341f8046a41106a2210200241106a2211290300370300200341f8046a41086a2213200241086a22142903003703002014200141086a2903003703002011200141106a290300370300200f200141186a290300370300200b200a290300370300200d200c290300370300200320043703f80420074103490d01200921072008210a20024180016a290300201a5a20024188016a290300220420055a20042005511b0d010340200a220141506a22022001290300370300200241286a200141286a290300370300200241206a200141206a290300370300200241186a200141186a290300370300200241106a200141106a290300370300200241086a200141086a2903003703002007417f6a2207450d02200141306a210a200141d0006a290300201a5a200141d8006a290300220420055a20042005511b0d020c000b0b2006201641dccfca001059000b2001201a370320200120032903f804370300200141286a2005370300200141186a200e290300370300200141106a2010290300370300200141086a20132903003703000b200941016a2109200841506a210820060d000b0b200342f0f2bda1a7ee9cb9f9003703f804200341e0016a200341f8046a10e001200342f0f2bda1a7ee9cb9f9003703f804200341f0036a200341f8046a10e001200341e8026a200341f0036a108e02200341f8046a20032802e802220120032802f002108f0220032903f804210520034188056a2903002104200329038005211a024020032802ec02450d00200110350b02402016201641017622014d0d00420020044200200542015122021b2204201a420020021b2205428080e983b1de1654ad7d221a200542808097fccea1697c221b200556201a200456200542ffffe883b1de16561b22021b22052012200141306c6a220141286a29030022042001290320221a4200201b20021b221b56200420055620042005511b22011b2104201b201a20011b2105024020032903c0074201520d00200341e8026a41186a200341c0076a41206a290300370300200341e8026a41106a200341c0076a41186a290300370300200341f0026a200341c0076a41106a290300370300200320032903c8073703e802200341c0076a41286a290300211a2003200341c0076a41306a290300221b370388062003201a370380060240201a201b84500d002003200341e8026a3602c001200341f0036a200341e8026a20034180066a200341c0016a10f00220032903f0034201520d0020032903f803211a200341b0056a200341f0036a41106a290300370300200341a8056a201a370300200341f8046a41086a41003a000020034181056a20032903e80237000020034189056a200341e8026a41086a29030037000020034191056a200341e8026a41106a29030037000020034199056a20034180036a290300370000200341033a00f80441b0b4cc004100200341f8046a10d4010b200341e8026a200341ac086a412010a008450d00200341a8016a2005200442e400420010980820034198016a20032903a801221a200341a8016a41086a290300221b429c7f427f10840820034188016a201a201b42144200108408200341f8046a200341e0016a200341e8026a200329038801221b20052003290398017ca741ff0071220141056e2202200141146c2002419c7f6c6a41fcff037141324b6aad7c221a20034188016a41086a290300201a201b54ad7c221b410010e6022004201b7d2005201a54ad7d21042005201a7d21050b200341f8046a200341e0016a200341ac086a20052004410010e60220034199056a201737000020034198056a20263a000020034197056a20273a000020034195056a20283b000020034194056a20293a000020034193056a202a3a000020034191056a202b3b000020034190056a202c3a00002003418f056a202d3a00002003418d056a202e3b00002003418c056a202f3a00002003418b056a20303a000020034189056a20313b000020034188056a20323a000020034187056a20333a000020034185056a20343b000020034183056a20363a0000200341f8046a41096a20373b000020034180056a41093a00002003410c3a00f804200341f8046a410c6a20353a0000200341c8056a2005370300200341d0056a2004370300200341b9056a200341c4086a290200370000200341b1056a200341bc086a290200370000200341a9056a200341b4086a290200370000200341a1056a20032902ac0837000041b0b4cc004100200341f8046a10d4012038450d05203841306c450d05201210350c050b2001201641cc82ca001042000b02402006450d00200710350b20004200370308200041206a410c3602002000411c6a41b7adc800360200200041186a2001360200420121050c050b41b7adc800210a410c21094111210841032107410321010c010b0b02402006450d00200b10350b20004200370308200041206a20093602002000411c6a200a360200200041186a2002411874200741ff017141107472200841ff017141087472200141ff017172360200420121050c020b420021050b200020053703080b20002005370300200341d0086a24000f0b103c000bbd930106147f027e0c7f017e027f017e230041e0046b22042400200441c0036a20012002200310ed06200441c0036a41086a280200210520042802c40321060240024002400240024020042802c0034101460d00200441d4036a280200220741306c2108200441d8036a2802002109200441d0036a280200210a200441cc036a280200210b4100210c4100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004102470d000b200441d8006a200b200d6a41546a10bf032004280258210c200428025c21010b4100210e20014100200c1b210f200741306c2108200c41b0b4cc00200c1b21104100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004108470d000b200441d0006a200b200d6a41546a10bf032004280250210e200428025421010b4100211120014100200e1b2112200741306c2108200e41b0b4cc00200e1b210c4100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004104470d000b200441c8006a200b200d6a41546a10bf0320042802482111200428024c21010b4100210e2001410020111b2113200741306c2108201141b0b4cc0020111b21114100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004103470d000b200441c0006a200b200d6a41546a10bf032004280240210e200428024421010b41002102024020014100200e1b2201450d00200141286c2108200e41b0b4cc00200e1b41186a2101410021020340200220012d0000456a2102200141286a2101200841586a22080d000b0b024020120d00411e210120004185d6cb003602040c030b200c201241146c6a211241002114410021150240034041a3d6cb00210841382101200c41086a280200417c6a220e41024b0d01200c280200210d024002400240200e0e03000401000b41012115200d41fbd5cb00460d01200d28000041e3c2b1e306460d010c030b41012114200d41ffd5cb00460d00200d41ffd5cb00410610a0080d020b0240200c410c6a280200450d0041132101200041a1d7cb003602040c050b0240200c41106a280200220120026b220d20014d0d00412a2101200041b4d7cb003602040c050b41fbd6cb002108412621012013200d4d0d012011200d4102746a220d450d0141dbd6cb00210841202101200f200d280200220d4d0d012010200d4104746a220d450d0141ded7cb002108411f2101200d2802080d01200d2d000d220d41077141044b0d010240200d0e050002020200000b200c41146a220c2012470d000b20142015714101710d02411c411e201441017122021b2101200041fdd7cb004185d6cb0020021b3602040c030b200020083602040c020b2000200636020420004101360200200041086a20053602000c030b200741306c2108410021010240024002400240034020082001460d01200b20016a2102200141306a220d210120022d00004106470d000b200441386a200b200d6a41546a10bf03200428023c0d010b200741306c2108200328028001210c410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004105470d000b200441306a200b200d6a41546a220110bf030240200428023441014d0d0041182101200041e8d3cb003602040c050b200441286a200110bf03200428022c450d0020042802282201450d002001280200200c4d0d004122210120004180d4cb003602040c040b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004107470d000b200441206a200b200d6a41546a10bf032004280220220120042802244104746a2108034020012008460d012001450d012001410c6a2102200141106a210120022d0000410271450d000b413221012000418cd5cb003602040c040b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d0000410c470d000b200b200d6a2201415c6a2802002202450d00200141546a280200220d200241186c6a210c0340200d220241186a210d2002280208410374210120022802002102024003402001450d01200141786a210120022d00042108200241086a21022008410271450d000b41312101200041dbd4cb003602040c060b200d200c470d000b0b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004102470d000b200441186a200b200d6a41546a10bf03200428021c2201450d002004280218220220014104746a210e03402002450d01200241106a210c200420022d000d22083a00c0032002280200220120022802086a210d4100200441c0036a20084104461b210802400340024002402001450d00200d2001460d0020012102200141016a21010c010b2008450d024100210120082102410021080b20022d0000410271450d000b41392101200041a2d4cb003602040c060b200c2102200c200e470d000b0b200741306c21084100210c4100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004102470d000b200441106a200b200d6a41546a10bf032004280210210c200428021421010b4100210e20014100200c1b2110200741306c2108200c41b0b4cc00200c1b21124100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004103470d000b200441086a200b200d6a41546a10bf032004280208210e200428020c21010b200e41b0b4cc00200e1b220220014100200e1b41286c6a210d41002113034002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002200d460d00412d210141ecbcca00210820022802084103470d0902402002280200220c41a58ecc00460d00200c41a58ecc00410310a0080d0a0b200241286a21114115210c41e5bbca00210e4114210141d8bcca0021080240024020022d00180e04010b0022010b412f21014199bdca00210820022802144106470d0a0240200228020c220c41a9bbca00460d00200c41a9bbca00410610a0080d0b0b2013450d02411f2101200041c8bdca003602040c270b4136210c41afbbca00210e2010200228021c22014d0d20201220014104746a220f450d202002280214210c200228020c2102024020092d0088010d00200c410b470d004138210141a0bcca002108200241bfe2cb00460d0a200241bfe2cb00410b10a008450d0a0c200b4126210141fabbca002108200c417d6a220c41144b0d09024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c0e15003030301208300d46060b160118031f1430101d21000b200241a88ecc00460d2f200241a88ecc00410310a008450d2f41a88ecc002002410310a0080d2f41011033220e0d010c4d0b200241c6dfcb00460d0241c6dfcb002002410f10a008450d02200241e6dfcb00460d0541e6dfcb002002410f10a008450d05024020024189e0cb00460d004189e0cb002002410f10a0080d2f0b41071033220e450d4c200e4100360003200e41013a0002200e41003b0000200f2d000c41e000460d0a0c430b200e41003a0000200f2d000c41e000470d41200f2802084101470d410240200f2802002214200e460d0041002102034020024101460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d430c000b0b200f2d000d4104470d41200e1035201121020c460b200241d5dfcb00460d0141d5dfcb002002411110a008450d01200241b6e1cb00460d1341b6e1cb002002411110a008450d13200241f5e1cb00460d1841f5e1cb002002411110a008450d1820024186e2cb00460d1a4186e2cb002002411110a008450d1a0240200241f1e2cb00460d0041f1e2cb002002411110a0080d2d0b41031033220e450d4a200e41003a0002200e41003b0000200f2d000c41e000460d1f0c3f0b41031033220e450d49200e41003a0002200e41003b0000200f2d000c41e000470d3d200f2802084103470d3d0240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d3f0c000b0b200f2d000d4104470d3d200e1035201121020c440b41011033220e450d48200e41003a0000200f2d000c41e000470d3b200f2802084101470d3b0240200f2802002214200e460d0041002102034020024101460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d3d0c000b0b200f2d000d4104470d3b200e1035201121020c430b200241f5dfcb00460d0241f5dfcb002002410c10a008450d020240200241d1e0cb00460d0041d1e0cb002002410c10a0080d2a0b4126210c41fabbca00210e200f2d000c41e000470d40200f2802080d4020112102200f2d000d4104460d420c400b41011033220e450d46200e41003a0000200f2d000c41e000470d38200f2802084101470d38200f2802002214200e460d3741002102034020024101460d38200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d390c000b0b024020024181e0cb00460d00200229000042e5f0d1fbb5ac98b6ec00520d280b41071033220e450d45200e4100360003200e41013a0002200e41003b0000200f2d000c41e000460d010c350b41041033220e450d44200e4100360000200f2d000c41e000470d33200f2802084104470d33200f2802002214200e460d3241002102034020024104460d33200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d340c000b0b200f2802084107470d33200f2802002214200e460d3041002102034020024107460d31200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d340c000b0b20024198e0cb00460d024198e0cb002002410d10a008450d020240200241c4e0cb00460d0041c4e0cb002002410d10a0080d250b4126210c41fabbca00210e200f2d000c41e000470d3b200f2802080d3b20112102200f2d000d4104460d3d0c3b0b200f2802084107470d38200f2802002214200e460d2d41002102034020024107460d2e200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d390c000b0b200241a5e0cb00460d0141a5e0cb002002410a10a008450d010240200241afe0cb00460d0041afe0cb002002410a10a0080d040b4126210c41fabbca00210e200f2d000c41e000470d39200f2802080d3920112102200f2d000d4104460d3b0c390b41021033220e450d3f200e41003b0000200f2d000c41e000470d2a200f2802084102470d2a0240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d2c0c000b0b200f2d000d4104470d2a200e1035201121020c3a0b41021033220e450d3e200e41003b0000200f2d000c41e000470d28200f2802084102470d280240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d2a0c000b0b200f2d000d4104470d28200e1035201121020c390b0240200241e8e0cb00460d0041e8e0cb002002411510a0080d050b4126210c41fabbca00210e200f2d000c41e000470d36200f2802080d3620112102200f2d000d4104460d380c360b0240200241fde0cb00460d0041fde0cb002002410a10a0080d1f0b41021033220e450d3c200e41003b0000200f2d000c41e000460d010c250b024020024187e1cb00460d004187e1cb002002410710a0080d1e0b4126210c41fabbca00210e200f2d000c41e000470d34200f2802080d3420112102200f2d000d4104460d360c340b200f2802084102470d230240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d250c000b0b200f2d000d4104470d23200e1035201121020c350b02402002418ee1cb00460d00418ee1cb002002411310a0080d0e0b4126210c41fabbca00210e200f2d000c41e000470d32200f2802080d3220112102200f2d000d4104460d340c320b0240200241a1e1cb00460d0041a1e1cb002002411510a0080d1b0b4126210c41fabbca00210e200f2d000c41e000470d31200f2802080d3120112102200f2d000d4104460d330c310b0240200241c7e1cb00460d0041c7e1cb002002410e10a0080d1a0b41081033220e450d37200e4200370000200f2d000c41e000460d020c1f0b41021033220e450d36200e41003b0000200f2d000c41e000470d1d200f2802084102470d1d0240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1f0c000b0b200f2d000d4104470d1d200e1035201121020c310b200241d5e1cb00460d0141d5e1cb002002411010a008450d01200241e5e1cb00460d0241e5e1cb002002411010a008450d020240200241cae2cb00460d0041cae2cb002002411010a0080d180b4126210c41fabbca00210e200f2d000c41e000470d2e200f2802080d2e20112102200f2d000d4104460d300c2e0b200f2802084108470d1c0240200f2802002214200e460d0041002102034020024108460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1e0c000b0b200f2d000d4104470d1c200e1035201121020c2f0b4126210c41fabbca00210e200f2d000c41e000470d2c200f2802080d2c200f2d000d22014104460d2c20112102200141fb0171450d2e0c2c0b41031033220e450d32200e41003a0002200e41003b0000200f2d000c41e000470d18200f2802084103470d180240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1a0c000b0b200f2d000d4104470d18200e1035201121020c2d0b41021033220e450d31200e41003b0000200f2d000c41e000470d16200f2802084102470d160240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d180c000b0b200f2d000d4104470d16200e1035201121020c2c0b024020024197e2cb00460d004197e2cb002002411610a0080d130b41021033220e450d30200e41003b0000200f2d000c41e000460d020c140b41041033220e450d2f200e4100360000200f2d000c41e000470d12200f2802084104470d120240200f2802002214200e460d0041002102034020024104460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d140c000b0b200f2d000d4104470d12200e1035201121020c2a0b0240200241ade2cb00460d0041ade2cb002002411210a0080d110b4126210c41fabbca00210e200f2d000c41e000470d27200f2802080d2720112102200f2d000d4104460d290c270b200f2802084102470d110240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d130c000b0b200f2d000d4104470d11200e1035201121020c280b0240200241dae2cb00460d0041dae2cb002002411710a0080d0f0b410210332214450d2c201441003b0000200f2d000c41e000470d0d200f2802084102470d0d200f28020022152014460d0c41002102034020024102460d0d201420026a210c201520026a210e200241016a2102200e2d0000200c2d0000470d0e0c000b0b20024182e3cb00460d014182e3cb002002411310a008450d0120024195e3cb00460d024195e3cb002002411310a008450d020240200241a8e3cb00460d0041a8e3cb002002411310a0080d0e0b41031033220e450d2b200e41003a0002200e41003b0000200f2d000c41e000460d030c0a0b200f2802084103470d1f0240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d210c000b0b200f2d000d4104470d1f200e1035201121020c250b41031033220e450d29200e41003a0002200e41003b0000200f2d000c41e000470d07200f2802084103470d070240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d090c000b0b200f2d000d4104470d07200e1035201121020c240b41031033220e450d28200e41003a0002200e41003b0000200f2d000c41e000470d05200f2802084103470d050240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d070c000b0b200f2d000d4104470d05200e1035201121020c230b200f2802084103470d060240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d080c000b0b200f2d000d4104470d06200e1035201121020c220b410021164100211720130d010c020b2002411c6a2113201121020c200b024020132802040d00200041e7bdca00360204413221010c240b024020132802002216201341086a28020022174d0d0020004199beca0036020441c90021010c240b2017200328027c4d0d00200041e2beca0036020441c10021010c230b20092903082118200441c0036a410c6a22024100360200200441003602c4032009290310211920042018a7417f2018428080808010541b3602d00320042019a7417f2019428080808010541b3602c003200441c0036a4104722201410d10ee062001410c10ee062001410710ee062001410f10ee06200420042802c003360264200441c8036a220828020021122002280200211a20042802c403211320042802d003211b200441d0036a220d20073602002002200a3602002004200b3602c803200420053602c403200420063602c003200441e8006a200441c0036a10ef06410110332201450d23200141003a0000200420042f01c00322023b019002200d41e0083b01002008428180808010370300200420013602c403200441013602c003200420023b01d203200441e8006a200441c0036a10f006210c02400240410310332202450d00200241026a41002d00a78e4c3a0000200241002f00a58e4c3b0000410310332208450d00200841026a41002d00aa8e4c3a0000200841002f00a88e4c3b000020044190026a41026a200441c0036a41026a220b2d000022073a0000200420042f00c003220e3b019002200441fc006a280200210d200441e8006a41106a2802002101200b20073a00002004200e3b01c00302400240200d2001470d00200141016a220d2001490d012001410174220b200d200b200d4b1bad42287e2218422088a70d012018a7220d4100480d0102400240024020010d00200d0d014104210b0c020b2004280274210b200141286c2201200d460d01024020010d00200d0d014104210b0c020b200b2001200d1037220b450d290c010b200d1033220b450d280b2004200b3602742004200d41286e360278200428027c210d0b2004280274200d41286c6a220141003a00182001200836020c200142838080803037020420012002360200200141106a428380808030370200200141196a20042f01c0033b00002001411b6a200441c2036a2d00003a00002001411c6a200c3602002004200428027c41016a36027c200441c0036a200441e8006a418c01109d081a200441f8016a200441c0036a10f106200441f8016a41106a280200220e41306c2101200428028002220b41546a210202400340410021082001450d01200141506a21012002412c6a210d200241306a220c2102200d2d00004103470d000b200c41086a2802002201450d00200141286c2102200c28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b200e41306c2101200b41546a21022008417f6a210d02400340410021082001450d01200141506a21012002412c6a210c200241306a22072102200c2d00004103470d000b200741086a2802002201450d00200141286c2102200728020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b200e41306c2101200b415c6a21020240034041002111024020010d00410021010c020b200141506a2101200241246a210c200241306a22072102200c2d00004104470d000b200728020021010b0240024002400240200e450d00200120086a211c200b200e41306c6a2115200441a0036a410c6a211d200441bc036a41046a211e200441a0036a41146a211f410021204100212103400240200b2d000041786a220141044b0d000240024002400240024020010e050301020500030b200b28020c2201450d04200b280204220c200141186c6a2122202021010340200121200240200c22082802144104742202450d00200828020c21010340024020012d0000410b470d00200141046a220c2802002207200d490d00200c200741016a3602000b200141106a2101200241706a22020d000b0b2008410c6a2106200442003703b00320044280808080c0003703a803200442043703a003200441a0036a41004101108c0120042802a00320042802a8034104746a22014200370200200141056a4200370000200420042802a80341016a3602a8030240024002400240024020082802142201450d002001ad21194200211803402018a721140240024002400240024002400240024020182001ad5a0d004110210202400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402006280200222320144104746a2d000022240eac010001020202020202020202020202020303030404050506060707080809090a0a0b0b0c0d0d0e0e0f0f1010111213131414151516161717181819191a1a1b1b1c1c1d1d1e1e1f1f2020212122222323242425252627272828292a2a2b2b2c2d2d2e2e2f2f303031313232333434353536363737383839393a3a3b3b3c3c3d3d3e3e3f3f40404141424243434444454546464747484a4a4a4a49494a4a4a4a4a4a4a4a4a4a4a4a4a4a4b4b4b4b000b411121020c4a0b411221020c490b410a21020c480b410821020c470b410821020c460b410421020c450b410421020c440b410421020c430b410421020c420b410421020c410b410421020c400b410421020c3f0b410521020c3e0b410521020c3d0b410521020c3c0b410521020c3b0b410521020c3a0b411321020c390b411421020c380b410621020c370b410721020c360b410b21020c350b410b21020c340b410b21020c330b410b21020c320b410b21020c310b410b21020c300b410b21020c2f0b410b21020c2e0b410b21020c2d0b410b21020c2c0b410b21020c2b0b410c21020c2a0b410c21020c290b410c21020c280b410c21020c270b410c21020c260b410c21020c250b410021020c240b410021020c230b410121020c220b410221020c210b410321020c200b410321020c1f0b410021020c1e0b410021020c1d0b410021020c1c0b410021020c1b0b410021020c1a0b410021020c190b410121020c180b410221020c170b410321020c160b410321020c150b410021020c140b410021020c130b410021020c120b410021020c110b410d21020c100b410d21020c0f0b410d21020c0e0b410d21020c0d0b410d21020c0c0b410d21020c0b0b410d21020c0a0b410d21020c090b410d21020c080b410d21020c070b410d21020c060b410d21020c050b410d21020c040b410d21020c030b410e21020c020b410e21020c010b410f21020b200441e4006a212502402013450d0020132107201221050340200741086a211020072f010621114100210c4100210102400240034020112001460d01201020016a210f200c41086a210c200141016a210102404100417f4101200f2d0000220f20024b1b200f2002461b41016a0e03000301000b0b2001417f6a21110b2005450d022005417f6a2105200720114102746a41ec006a28020021070c010b0b02402007200c6a2201410c6a2802000e0401140001010b200141106a21250b201842017c2118202528020021020240024002400240024002400240024002402024417e6a220141084b0d0020010e09010302050406060708010b20042802a8032201450d1a200141047420042802a0036a41786a220c280200220120026a22022001490d1a200c20023602000c0f0b20042802a8032201450d19200141047420042802a0036a41786a220c280200220120026a22022001490d19200c200236020020042802a8032202450d19200241047420042802a00322016a41746a28020021072002210c0240200220042802a403470d00200441a0036a20024101108c0120042802a803210c20042802a00321010b2001200c4104746a2201200e3b000d200141003a000c20012007360204200120023602002001410f6a200e4110763a0000200141086a4100360200200420042802a80341016a3602a8030c0e0b20042802a8032201450d18200141047420042802a0036a41786a220c280200220120026a22022001490d18200c200236020020042802a803220221010240200220042802a403470d00200441a0036a20024101108c0120042802a80321010b20042802a00320014104746a2201200e3b000d200141003a000c200120183e0204200120023602002001410f6a200e4110763a0000200141086a4100360200200420042802a80341016a3602a8030c0d0b20042802a8032201450d17200141047420042802a0036a41786a220c280200220120026a22022001490d17200c200236020020042802a803220221010240200220042802a403470d00200441a0036a20024101108c0120042802a80321010b20042802a00320014104746a2201200e3b000d200141013a000c200120183e0204200120023602002001410f6a200e4110763a0000200141086a4100360200200420042802a80341016a3602a8030c0c0b20042802a8032201450d16200141047420042802a0036a41746a22012902002126200120183702002026a7210c2026422088a7210202400240024020042802a80322014101460d002001450d0820042802a0032001417e6a4104746a2207280204200c470d00200741086a21010c010b2002450d01024020042802b403220120042802b003470d00201d2001410110900120042802b40321010b20042802ac0320014103746a220120023602042001200c36020041012102201f21010b2001200128020020026a36020020042802a8032201450d170b20042001417f6a22023602a80320042802a003220c20024104746a22072d000c4102460d162002450d0b2001410474200c6a41606a220c20072802002201200c280200220c200c20014b1b360200200120024f0d0b20042802a8032201450d16200141047420042802a0036a41746a22012902002126200120183702002026a7210c2026422088a72101024020042802a80322024101460d002002450d0720042802a0032002417e6a4104746a2202280204200c470d002002200228020820016a3602080c0c0b2001450d0b024020042802b403220220042802b003470d00201d2002410110900120042802b40321020b20042802ac0320024103746a220220013602042002200c360200200420042802b40341016a3602b4030c0b0b20042802a8032201450d15200141047420042802a0036a41746a22012902002126200120183702002026a7210c2026422088a72101024020042802a80322024101460d002002450d0720042802a0032002417e6a4104746a2202280204200c470d002002200228020820016a3602080c0b0b2001450d0a024020042802b403220220042802b003470d00201d2002410110900120042802b40321020b20042802ac0320024103746a220220013602042002200c360200200420042802b40341016a3602b4030c0a0b20042802a8032201450d14200141047420042802a0036a41786a220c280200220120026a22022001490d14202320144104746a41046a2802002107200c200236020020042802a8032201417f6a220c20014b0d14200c20076b2202200c4b0d14200141047420042802a0036a41746a22012902002126200120183702002026a721072026422088a7210c02400240024020042802a80322014101460d002001450d0920042802a0032001417e6a4104746a22112802042007470d00201141086a21010c010b200c450d01024020042802b403220120042802b003470d00201d2001410110900120042802b40321010b20042802ac0320014103746a2201200c360204200120073602004101210c201f21010b20012001280200200c6a36020020042802a80321010b200120024d0d1420042802a003220c20024104746a2d000c0d092001410474200c6a41706a2201200220012802002201200120024b1b3602000c090b20042802a8032201450d13200141047420042802a0036a41786a220c280200220120026a22022001490d13200c200236020020042802a8032202417f6a220120024b0d13200420013602b8032004202320144104746a41046a2202280200280208220c3602bc0320022802002207280200210220072802042107200441003a00cf042004200220074102746a36029c0220042002360298022004201e360294022004200441bc036a360290022004200441bc036a41046a360290022004200441cf046a3602a4022004200441b8036a3602a00202402001200c6b220220014d0d00200441013a00cf040c140b410410332201450d1b2001200236020020044281808080103702d404200420013602d004200441c0036a41106a20044190026a41106a290300370300200441c0036a41086a20044190026a41086a290300370300200420042903900222263703c00320042802d4032102024002402026a72201450d00024020042802c4032001460d002004200141046a3602c00320042802d003280200220720012802006b220c20074d0d02200241013a00000c0a0b200441003602c0030b20042802c8032201450d0820042802cc032001460d082004200141046a3602c80341012107024020042802d003280200221120012802006b220c20114d0d00200241013a0000410021070b2007417d71450d080b4101210220042802cc03211020042802d003211120042802c403210f20042802d4032105410121010340024020012002470d00200441d0046a200241011086010b20042802d00420014102746a200c3602002004200141016a3602d8040240024020042802c0032201450d000240200f2001460d002004200141046a3602c0032011280200220220012802006b220c20024d0d02200541013a00000c0b0b200441003602c0030b20042802c8032201450d0920102001460d092004200141046a3602c8034101210202402011280200220720012802006b220c20074d0d00200541013a0000410021020b2002417d71450d090b20042802d404210220042802d80421010c000b0b20042802a8032201450d12200141047420042802a0036a41786a220c280200220120026a22022001490d12200c200236020020042802a8032201450d12200141047420042802a0036a41746a22012902002126200120183702002026a7210c2026422088a7210102400240024020042802a80322024101460d002002450d0820042802a0032002417e6a4104746a2207280204200c470d00200741086a21020c010b2001450d01024020042802b403220220042802b003470d00201d2002410110900120042802b40321020b20042802ac0320024103746a220220013602042002200c36020041012101201f21020b2002200228020020016a36020020042802a8032202450d130b20042802a00322012d000c0d07200241047420016a41706a41003602000c070b2014200141fc8ecc001042000b41ab8ecc00413f41ec8ecc001064000b41ab8ecc00413f41ec8ecc001064000b41ab8ecc00413f41ec8ecc001064000b41ab8ecc00413f41ec8ecc001064000b41ab8ecc00413f41ec8ecc001064000b20042802d004210f20042802d4042105024020042d00cf04450d00200541ffffffff0371450d0c200f10350c0c0b200f450d0b0240024020042802a80322010d00410121100c010b20042802d8042102200141047420042802a0036a41746a22012902002126200120183702002026a721072026422088a7210102400240024020042802a803220c4101460d00200c450d0720042802a003200c417e6a4104746a220c2802042007470d00200c41086a210c0c010b2001450d01024020042802b403220c20042802b003470d00201d200c410110900120042802b403210c0b20042802ac03200c4103746a220c2001360204200c200736020041012101201f210c0b200c200c28020020016a3602000b410021102002450d002002410274210c200f21010340024020042802a8032207200128020022024b0d00410121100c020b024020042802a003221120024104746a2d000c0d00200741047420116a41706a2207200220072802002207200720024b1b3602000b200141046a2101200c417c6a220c0d000b0b0240200541ffffffff0371450d00200f10350b20100d0b0b20182019510d01200828021421010c000b0b20042802ac0320042802b4032201410041202001676b10f20620042903b003212620042802ac032124024020042802a40341ffffffff0071450d0020042802a00310350b024020240d00410121210c0a0b200828021422012026422088a7220c4101746a220241ffffffff00712002470d0120024104742202417f4c0d010240024020020d00410821070c010b200210332207450d11200828021421010b20084100360214200828020c21232008200736020c200841106a220f2802002127200f2002410476360200202320014104746a21112024200c4103746a212541022107024020010d0020242114202321010c030b41002102202421144100210c202321010340200141016a2f0000200141036a2d000041107472210e024020012d0000221041ac01470d00200141106a21010c040b200141086a2900002118200141046a28000021050240024020074102470d00024020142025470d0041002107202521140c020b20142902002219422088a721282019a7210a41012107201441086a21140b20074101470d00200c200a470d0002402002200f280200470d00200620024101109a01200828021421020b200828020c20024104746a220220042f00c0033b00012002412d3a000020022028360204200241036a200441c0036a41026a2d00003a00002008200828021441016a220236021402402002200f280200470d00200620024101109a01200828021421020b200828020c20024104746a220220042f00c0033b00012002410b3a00002002200d36020441022107200241036a200441c0036a41026a2d00003a00002008200828021441016a2202360214200c210a0b02402002200f280200470d00200620024101109a01200828021421020b200c41016a210c200828020c20024104746a22022018370308200220053602042002200e3b0001200220103a0000200241036a200e4110763a00002008200828021441016a2202360214200141106a22012011470d000c040b0b41ab8ecc00413f41ec8ecc001064000b1044000b20112001460d000340200141106a2102024020012d00004109470d000240200141046a220c280200220128020441ffffffff0371450d0020012802001035200c28020021010b200110350b2002210120112002470d000b0b0240202741ffffffff0071450d00202310350b2014202547200720074102461b21010240202642ffffffff0183500d00202410350b024020014101470d00410121210c060b200841186a210c02400240201b450d0020082802142202450d00200828020c210120024104742102410021080340024020012d0000412c470d002001410b3a0000200141046a201c360200200841016a21080b200141106a2101200241706a22020d000b4101210120080d010b202021010b200c2022470d000b200121200c040b200b2802042201200d490d03200b200141016a3602040c030b200b28020c2201450d02200b280204220c2001411c6c6a21070340200c2201411c6a210c024020012802182202450d0020012802102101200241027421020340024020012802002208200d490d002001200841016a3602000b200141046a21012002417c6a22020d000b0b200c2007460d030c000b0b200b28020c2201450d01200141146c2102200b28020441106a2101034002402001417c6a2802000d0020012802002208200d490d002001200841016a3602000b200141146a21012002416c6a22020d000c020b0b024020042802a40341ffffffff0071450d0020042802a00310350b024020042802b00341ffffffff0171450d0020042802ac0310350b410121210b200b41306a220b2015470d000b4101210f20214101710d0220204101710d012004280288022111200428028002210b0b20044184026a280200211020042802fc01210520042802f80121064100210f0c020b200441c0036a41106a200441f8016a41106a280200360200200441c0036a41086a200441f8016a41086a290300370300200420042903f8013703c00320044190026a200441c0036a10ef06411010332202450d28200241063a0000410110332201450d28200141003a000041011033220c450d28200c20012d00003a000020011035411010332208450d28200841063a000041f00010332201450d28200141063a00602001412c3b01502001200d3602442001410b3a0040200141d8003a00302001201b3602242001412d3a0020200141003602142001410f3a0010200141003602042001410f3a0000024020082d00004109470d0002402008280204220d28020441ffffffff0371450d00200d28020010352008280204210d0b200d10350b20081035024020022d00004109470d0002402002280204220828020441ffffffff0371450d0020082802001035200228020421080b200810350b20021035200441e4036a4287808080f000370200200441e0036a2001360200200441dc036a4100360200200441c0036a410c6a4281808080800c370200200441c8036a4101360200200441003602ec03200442043702d4032004200c3602c403200441013602c00320044190026a200441c0036a10f306200441c0036a20044190026a418c01109d081a200441a0036a200441c0036a10f106200441a0036a410c6a2802002110200441b0036a280200211120042802a003210620042802a403210520042802a803210b4100210f0c010b20044184026a2802002110200428028002220b200428028802221110f406411a210541bed5cb00210602402010450d00201041306c450d00200b10350b0b41002108410021014100210c02402013450d0002402012450d000340201328026c21132012417f6a22120d000b0b20132101201a210c0b024002400340200c450d012001450d024100210d02400240200820012f01064f0d00200121020c010b4100210d034002400240200128020022020d0041002108410021020c010b200d41016a210d20012f010421080b2001103520022101200820022f01064f0d000b0b200841016a2107200220084103746a41146a280200210e02400240200d0d0020022101200721080c010b200220074102746a41ec006a280200210141002108200d417f6a2202450d000340200128026c21012002417f6a22020d000b0b200c417f6a210c200e4103470d000b0b02402001450d0020012802002102200110352002450d00034020022802002101200210352001210220010d000b0b02400240200f0d0020044190026a41106a201136020020044190026a410c6a20103602002004200b3602980220042005360294022004200636029002200441c0036a20044190026a200928027810f50620042802c0034101470d010240200441c0036a41086a280200450d0020042802c40310350b200041d8d5cb0036020420004101360200200041086a41233602000c2a0b2000200636020420004101360200200041086a20053602000c290b200441d4036a2802002102200441c0036a41106a2802002110200441c0036a410c6a280200210f200441c8036a280200210c20042802c403210820032802702105200441003602a803200442013703a003410410332201450d27200441043602a403200420013602a00320012008360000200441043602a8030240024020042802a403220d417c714104460d004104210120042802a00321080c010b200d41017422014108200141084b1b220b4100480d0202400240200d0d0041042101200b10332208450d2a0c010b4104210120042802a0032108200d200b460d002008200d200b10372208450d2920042802a80321010b2004200b3602a403200420083602a0030b200820016a200c3600002004200141046a3602a803200f200241306c6a2113024020020d00200f21010c040b200441c0036a4101722102200441c0036a41276a210d200441c0036a41206a210c200441c0036a41186a210b200441c0036a41086a2107200f21010240034020012d00002108200d200141286a290000370000200c200141216a290000370300200b200141196a290000370300200441c0036a41106a220e200141116a2900003703002007200141096a2900003703002004200141016a2900003703c003024020084110470d00200141306a21010c060b20044190026a41276a2211200d29000037000020044190026a41206a2203200c29030037030020044190026a41186a200b290300221837030020044190026a41106a200e290300221937030020044190026a41086a20072903002226370300200420042903c00322293703900220022029370000200241086a2026370000200241106a2019370000200241186a2018370000200241206a2003290300370000200241276a2011290000370000200420083a00c003200441e8006a200441c0036a200441a0036a10f60620042d00682208411f470d01200141306a22012013470d000b201321010c040b200428026c210d20042802702102200141306a2201201320016b41306d10f40602402010450d00201041306c450d00200f10350b024020042802a403450d0020042802a00310350b024020084105470d002002450d00200d10350b20004199d8cb0036020420004101360200200041086a41253602000c280b41958dcc00412b41c08dcc00103f000b103e000b1045000b2001201320016b41306d10f40602402010450d00201041306c450d00200f10350b20042802a003210120042902a40321182000411c6a41003a0000200041146a2018370200200041106a20013602002000410c6a2017360200200041086a2016360200200020053602042000411d6a20042f00f8013b0000200041003602002000411f6a200441fa016a2d00003a00000c240b200e1035200041fabbca003602040c210b200e1035200041fabbca003602040c200b200e1035200041fabbca003602040c1f0b200f2d000d22024104460d00200241fb01710d0020141035201121020c1a0b201410350b200020083602040c1c0b200e1035200041fabbca003602040c1b0b200e1035200041fabbca003602040c1a0b200e1035200041fabbca003602040c190b200e1035200041fabbca003602040c180b200e1035200041fabbca003602040c170b200e1035200041fabbca003602040c160b200e1035200041fabbca003602040c150b200e1035200041fabbca003602040c140b200e1035200041fabbca003602040c130b200f2d000d22024104460d0a200241fb01710d0a200e1035201121020c0e0b200f2d000d22024104460d02200241fb01710d02200e1035201121020c0d0b200f2d000d22024104460d00200241fb01710d00200e1035201121020c0c0b200e1035200041fabbca003602040c0f0b200e1035200041fabbca003602040c0e0b200f2d000d22024104460d00200241fb01710d00200e1035201121020c090b200e1035200041fabbca003602040c0c0b200e1035200041fabbca003602040c0b0b200e1035200041fabbca003602040c0a0b200e1035200041fabbca003602040c090b200e1035200041fabbca003602040c080b200e1035200041fabbca003602040c070b02400240200241b9e0cb00460d0041b9e0cb002002410b10a0080d010b4126210c41fabbca00210e200f2d000c41e000470d01200f2802080d0120112102200f2d000d4104460d030c010b0240200241dde0cb00460d0041dde0cb002002410b10a0080d020b4126210c41fabbca00210e200f2d000c41e000470d00200f2802080d0020112102200f2d000d4104460d020b200c21012000200e3602040c050b0240200241bfe2cb00460d0041bfe2cb002002410b10a0080d040b41021033220c450d05200c41003b0000200f2d000c41e000470d02200f2802084102470d020240200f280200220e200c460d0041002101034020014102460d01200c20016a2102200e20016a2108200141016a210120082d000020022d0000470d040c000b0b200f2d000d4104470d02200c1035201121020c000b0b200041c9d3cb00360204411f21010c020b200c10350b41262101200041fabbca003602040b20004101360200200041086a200136020002402007450d00200b200741306c6a2111200b210703402007220041306a21070240024020002d00002201410e4b0d00024002400240024002400240024002400240024002400240024020010e0f0001020304050607080e090e0a0b0c000b200041086a280200450d0d200041046a28020010350c0d0b0240200041086a280200450d00200041046a28020010350b200041146a280200450d0c200041106a28020010350c0c0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d00200128020010350b200141106a2101200241706a22020d000b0b200041086a28020041ffffffff0071450d0b200028020410350c0b0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101200241586a22020d000b0b200041086a2802002201450d0a200141286c450d0a200028020410350c0a0b200041086a28020041ffffffff0371450d09200041046a28020010350c090b200041086a2802002201450d082001410c6c450d08200041046a28020010350c080b200041086a2802002201450d072001410c6c450d07200041046a28020010350c070b02402000410c6a2802002201450d00200041046a280200220c20014104746a210e03400240200c2802082202450d00200c2802002101200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d0020082802001035200d28020021080b200810350b200141106a2101200241706a22020d000b0b200c41106a21010240200c41046a28020041ffffffff0071450d00200c28020010350b2001210c2001200e470d000b0b200041086a28020041ffffffff0071450d06200028020410350c060b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d00200128020010350b200141146a21012002416c6a22020d000b0b200041086a2802002201450d05200141146c450d05200028020410350c050b02402000410c6a2802002201450d00200041046a280200220c2001411c6c6a210e03400240200c2802042201450d000240200c410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d0020082802001035200d28020021080b200810350b200141106a2101200241706a22020d000b0b200c41086a28020041ffffffff0071450d00200c28020410350b200c411c6a21010240200c41146a28020041ffffffff0371450d00200c28021010350b2001210c2001200e470d000b0b200041086a2802002201450d042001411c6c450d04200028020410350c040b02402000410c6a2802002201450d00200041046a280200220c200141186c6a210e03400240200c41046a28020041ffffffff0171450d00200c28020010350b0240200c41146a2802002202450d00200c28020c2101200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d0020082802001035200d28020021080b200810350b200141106a2101200241706a22020d000b0b200c41186a21010240200c41106a28020041ffffffff0071450d00200c28020c10350b2001210c2001200e470d000b0b200041086a2802002201450d03200141186c450d03200028020410350c030b02402000410c6a2802002201450d00200041046a280200220c2001411c6c6a210e03400240200c2802042201450d000240200c410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d0020082802001035200d28020021080b200810350b200141106a2101200241706a22020d000b0b200c41086a28020041ffffffff0071450d00200c28020410350b200c411c6a21010240200c41146a280200450d00200c28021010350b2001210c2001200e470d000b0b200041086a2802002201450d022001411c6c450d02200028020410350c020b0240200041046a2802002201450d00200041086a280200450d00200110350b0240200041146a2802002201450d0002402000411c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101200241746a22020d000b0b200041186a2802002201450d002001410c6c450d00200028021410350b200041246a280200220c450d0102402000412c6a2802002201450d00200c20014104746a210e0340200c220d41106a210c0240200d2802042201450d000240200d410c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101200241746a22020d000b0b200d41086a2802002201450d002001410c6c450d00200d28020410350b200c200e470d000b0b200041286a28020041ffffffff0071450d01200028022410350c010b0240200041086a280200450d00200041046a28020010350b0240200041146a2802002201450d00200041186a280200450d00200110350b200041246a28020041ffffffff0071450d00200041206a28020010350b20072011470d000b0b200a450d01200a41306c450d01200b10350c010b103c000b200441e0046a24000bf70a02147f027e23004190066b22022400024002400240024020012d00000e03010200010b200241b0056a41186a2203200141196a2200290000370300200241b0056a41106a2204200141116a2205290000370300200241b0056a41086a2206200141096a2207290000370300200220012900013703b005200241d0056a41186a2208200141396a2209290000370300200241d0056a41106a220a200141316a220b290000370300200241d0056a41086a220c200141296a220d2900003703002002200141216a220e2900003703d005200241b0026a41186a220f200141d9006a2210290000370300200241b0026a41106a2211200141d1006a2212290000370300200241b0026a41086a2213200141c9006a22142900003703002002200141c1006a22152900003703b002200141f8006a2903002116200141f0006a290300211720024188056a41186a200029000037030020024188056a41106a200529000037030020024188056a41086a20072900003703002002200129000137038805200241186a2009290000370300200241106a200b290000370300200241086a200d2900003703002002200e290000370300200241d8026a41186a2010290000370300200241d8026a41106a2012290000370300200241d8026a41086a22002014290000370300200220152900003703d80220024180066a41086a200141ec006a2802003602002002200141e4006a29020037038006200241f0056a20024188056a2002200241d8026a2017201620024180066a10f10320022d00f0052101200041033a0000200241d8026a41096a20022903b005370000200241d8026a41116a2006290300370000200241d8026a41196a2004290300370000200241d8026a41216a2003290300370000200241d8026a41296a20022903d005370000200241d8026a41316a200c290300370000200241d8026a41396a200a290300370000200241d8026a41c1006a20082903003700002002410d3a00d802200241d8026a41f8006a2016370300200241d8026a41f0006a2017370300200241c1036a20014104463a0000200241b9036a200f290300370000200241d8026a41d9006a2011290300370000200241d8026a41d1006a2013290300370000200241d8026a41c9006a20022903b00237000041b0b4cc004100200241d8026a10d4010c020b200141086a28020021002001410c6a2802002104200141046a2802002103200241076a200141106a41f800109d081a2002410d3a00d802200241d8026a410172200241ff00109d081a20032004200241d8026a10d401200041ffffff3f71450d01200310350c010b200241e8056a2204200141196a2205290000370300200241d0056a41106a2206200141116a2207290000370300200241d0056a41086a2208200141096a2209290000370300200220012900013703d0052002200141286a41b002109d08220341b0056a200310d803200341d8026a200341b002109d081a20034192056a20092900003701002003419a056a2007290000370100200341a2056a200529000037010020034180023b0188052003200129000137018a05200341b0026a200341d8026a20034188056a10ac032000280200280200210142002116024020032903b8024201520d00420020032903b0052216200341b0026a41106a2903007d221720172016561b21160b2001427f2001290308221720167c221620162017541b22162001290300221720162017561b37030820032903b0022116200341d8026a41086a41063a0000200341d8026a41096a20032903d005370000200341d8026a41116a2008290300370000200341d8026a41196a2006290300370000200341f9026a200429030037000020034181036a2016503a00002003410d3a00d80241b0b4cc004100200341d8026a10d4010b20024190066a24000bb22402137f067e23004190046b22032400024002400240024002400240024002400240024002400240024020012802000e0400010203000b200341cc016a4101360200200342013702bc01200341e8d4ca003602b801200341043602ec032003419cd5ca003602e8032003200341e8036a3602c801200341b8016a41b0b4cc00104c000b20012802042101418226210420022d00000d0420022d00014101470d04200241196a2d00002104200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a290100370320200320043a001f200320053a001e200320063b011c200320073a001b200320083a001a200320093b01182003200a3a00172003200b3a00162003200c3b01142003200d3a00132003200e3a00122003200f3b0110200320103a000f200320113a000e200320123b010c200320133a000b200320143a000a200320153b010841d5c3c800ad4280808080c00084100122022900002116200229000821172002103541b4c4c800ad428080808030841001220229000021182002290008211920021035200320193701a801200320183701a00120032017370198012003201637019001200341b8016a20034190016a412010d5010240024020032d00b8014101460d0020034180046a4200370300200341f8036a4200370300200341f0036a4200370300200342003703e8030c010b200320032900b9013703e8032003200341d1016a290000370380042003200341c1016a2900003703f0032003200341c9016a2900003703f8030b4183262104200341086a200341e8036a412010a0080d04200341b8016a200141b002109d081a200341003b01e80320034190016a200341b8016a200341e8036a10ac03200320032900a9013703b801200320034190016a41206a2800003600bf01024002402003290390014201510d00410421020c010b200341a8016a2d000021042003290398012116200320032800bf013600ef03200320032903b8013703e8034104210220164202510d00200320032800ef033600bf01200320032903e8033703b801200421020b200320032903b801370370200320032800bf01360077200341b8016a41086a20023a0000200341c1016a2003290370370000200341b8016a41106a2003280077360000200341003a00bc012003410e3a00b801200320032f00503b00bd012003200341d2006a2d00003a00bf01200341cc016a20032902e803370200200341d4016a200341e8036a41086a290200370200200341dc016a200341e8036a41106a28020036020041b0b4cc004100200341b8016a10d401200110350c020b200341e8036a41206a200141246a280200360200200341e8036a41186a2001411c6a290200370300200341e8036a41106a200141146a290200370300200341e8036a41086a2001410c6a290200370300200320012902043703e8034182262101024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a290100370348200320013a0047200320043a0046200320053b0144200320063a0043200320073a0042200320083b0140200320093a003f2003200a3a003e2003200b3b013c2003200c3a003b2003200d3a003a2003200e3b01382003200f3a0037200320103a0036200320113b0134200320123a0033200320133a0032200320143b013041d5c3c800ad4280808080c00084100122012900002116200129000821172001103541b4c4c800ad428080808030841001220129000021182001290008211920011035200320193701a801200320183701a00120032017370198012003201637019001200341b8016a20034190016a412010d5010240024020032d00b8014101460d00200341a8016a4200370300200341a0016a420037030020034198016a420037030020034200370390010c010b200320032900b901370390012003200341d1016a2900003703a8012003200341c1016a290000370398012003200341c9016a2900003703a0010b4183262101200341306a20034190016a412010a0080d00200341b8016a41206a200341e8036a41206a280200360200200341b8016a41186a200341e8036a41186a290300370300200341b8016a41106a200341e8036a41106a290300370300200341b8016a41086a200341e8036a41086a290300370300200320032903e8033703b80120034190016a200341b8016a108b02200341086a41086a220120034199016a290000370300200341086a41106a2202200341a1016a290000370300200341086a41186a2204200341a9016a2900003703002003200329009101370308024020032d0090014101460d00200341f0006a41186a2004290300370300200341f0006a41106a2002290300370300200341f0006a41086a20012903003703002003200329030837037041d5c3c800ad4280808080c000842216100122012900002117200129000821182001103541b4c4c800ad42808080803084221910012201290000211a2001290008211b200110352003201b3701a8012003201a3701a00120032018370198012003201737019001200341b8016a20034190016a412010d5010240024020032d00b8014101460d004200211741002101410021024100210441002105410021064100210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f410021104100211141002112410021130c010b200341c0016a2d0000210e200341c1016a2f0000210d200341c3016a2d0000210c200341c4016a2d0000210b200341c5016a2f0000210a200341c7016a2d00002109200341c8016a2d00002108200341c9016a2f00002107200341cb016a2d00002106200341cc016a2d00002105200341cd016a2f00002104200341cf016a2d00002102200341d0016a2d00002101200341d1016a290000211720032f00b901211320032d00bb01211220032d00bc01211120032f00bd01211020032d00bf01210f0b200341d5016a2017370000200341d4016a20013a0000200341d3016a20023a0000200341d1016a20043b0000200341b8016a41186a220220053a0000200341cf016a20063a0000200341cd016a20073b0000200341cc016a20083a0000200341cb016a20093a0000200341c9016a200a3b0000200341b8016a41106a2204200b3a0000200341c7016a200c3a0000200341c5016a200d3b0000200341c4016a200e3a0000200341c3016a200f3a0000200341c1016a20103b0000200341b8016a41086a220520113a0000200320123a00bf01200320133b00bd01200341013a00bc012003410e3a00b80141b0b4cc004100200341b8016a10d4012002200341f0006a41186a2903003703002004200341f0006a41106a2903003703002005200341f0006a41086a290300370300200320032903703703b801201610012201290000211620012900082117200110352019100122012900002118200129000821192001103520032019370168200320183701602003201737015820032016370150412010332201450d06200120032903b801370000200141186a2002290300370000200141106a2004290300370000200141086a2005290300370000200341d0006aad42808080808004842001ad42808080808004841002200110350c030b41812621010b200041206a410b3602002000411c6a41de98c800360200200041186a2001360200200042003703080c080b200141286a2802002104200341286a200141246a280200360200200341086a41186a2001411c6a290200370300200341086a41106a200141146a290200370300200341086a41086a2001410c6a290200370300200320012902043703084102210120022d00000d0420022d00014101470d04200241196a2d00002101200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a29010037038801200320013a008701200320053a008601200320063b018401200320073a008301200320083a008201200320093b0180012003200a3a007f2003200b3a007e2003200c3b017c2003200d3a007b2003200e3a007a2003200f3b0178200320103a0077200320113a0076200320123b0174200320133a0073200320143a0072200320153b017041d5c3c800ad4280808080c00084100122012900002116200129000821172001103541b4c4c800ad428080808030841001220129000021182001290008211920011035200320193701a801200320183701a00120032017370198012003201637019001200341b8016a20034190016a412010d5010240024020032d00b8014101460d0020034180046a4200370300200341f8036a4200370300200341f0036a4200370300200342003703e8030c010b200320032900b9013703e8032003200341d1016a290000370380042003200341c1016a2900003703f0032003200341c9016a2900003703f8030b200341f0006a200341e8036a412010a0080d05200341b8016a41206a200341086a41206a280200360200200341b8016a41186a200341086a41186a290300370300200341b8016a41106a200341086a41106a290300370300200341b8016a41086a200341086a41086a290300370300200320032903083703b801200341e8036a200341b8016a108b024101210120032d00e8034101460d01200341e8036a41086a2d00002102200341f1036a2f00002105200341f3036a2d00002106200341f4036a2d00002107200341f5036a2f00002108200341f7036a2d00002109200341e8036a41106a2d0000210a200341f9036a2f0000210b200341fb036a2d0000210c200341fc036a2d0000210d200341fd036a2f0000210e200341ff036a2d0000210f200341e8036a41186a2d0000211020032f00e903211120032d00eb03211220032d00ec03211320032f00ed03211420032d00ef032115200320034181046a290000370168200320103a00672003200f3a00662003200e3b01642003200d3a00632003200c3a00622003200b3b01602003200a3a005f200320093a005e200320083b015c200320073a005b200320063a005a200320053b0158200320023a0057200320153a0056200320143b0154200320133a0053200320123a0052200320113b0150200341b8016a200441b002109d081a200341f2036a2003290158370100200341fa036a200329016037010020034182046a200329016837010020034180023b01e803200320032901503701ea0320034190016a200341b8016a200341e8036a10ac0302402003290390014201520d00200341b8016a41186a200341b0016a290300370300200341b8016a41106a220120034190016a41186a290300370300200341c0016a20034190016a41106a29030037030020032003290398013703b801200110d10441c4e0c600ad4280808080a001841006419ea2c000ad4280808080e0018410060240024020032903b8014201510d004194a2c000ad4280808080a0018410060c010b20032903c00110260b410021010b200320013a00bd01200341023a00bc012003410e3a00b80141b0b4cc004100200341b8016a10d401200410350b42002116200042003703080c070b200410ba0220041035410121010c040b200110ba0220011035200041206a410b3602002000411c6a41de98c800360200200041186a2004360200200042003703080c040b1045000b200410ba02200410350c010b200410ba0220041035410321010b20004200370308200041206a410b3602002000411c6a41de98c800360200200041186a2001418026723602000b420121160b2000201637030020034190046a24000bb8c20105017f037e127f087e087f23004180046b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0d00011a13120c0b0a0605040302000b20034184036a4101360200200342013702f402200341e8d4ca003602f002200341043602b4012003419cd5ca003602b0012003200341b0016a36028003200341f0026a41b0b4cc00104c000b200141106a2903002104200141086a29030021052002411a6a2901002106200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211841012101024020022d00000d0020022d000141014721010b2003200637038001200320073a007f200320083a007e200320093b017c2003200a3a007b2003200b3a007a2003200c3b01782003200d3a00772003200e3a00762003200f3b0174200320103a0073200320113a0072200320123b0170200320133a006f200320143a006e200320153b016c200320163a006b200320173a006a200320183b016820010d1920034188016a41186a200341e8006a41186a29030037030020034188016a41106a200341e8006a41106a29030037030020034188016a41086a200341e8006a41086a2903003703002003200329036837038801200341f0026a20034188016a10cf06200341106a20032802f002220120032802f80241b0b4cc0041004100108a0220032802102102024020032802f402450d00200110350b4103210720024101460d1a200341f0026a20034188016a10b906200341086a20032802f002220120032802f80241b0b4cc0041004100108a0220032802082102024020032802f402450d00200110350b20024101460d1a200341f0026a41186a4200370300200341f0026a41106a220e4200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f000841001220129000021062002200141086a290000370300200320063703f00220011035419cbac800ad4280808080c00084100122012900002106200341e8006a41086a2207200141086a2900003703002003200637036820011035200e20032903682206370300200341c8026a41086a2002290300370300200341c8026a41106a2006370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b220f20032902f402420020021b2206422088a741e8006c6a210d200f210202400340024002402002200d460d0041e59bc8002108410a2109410321074119210a410c210b20034188016a200241c8006a2201470d010c030b200341f0026a41186a22074200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f000841001220129000021192002200141086a290000370300200320193703f0022001103541e1b8c800ad4280808080a00184100122012900002119200341e8006a41086a2209200141086a2900003703002003201937036820011035200e2003290368370000200e41086a2009290300370000200341c8026a41086a2002290300370300200341c8026a41106a2008290300370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b221020032902f402420020021b2219422088a741e8006c6a210d20102102024002400240024002400340024002402002200d460d0041d59bc800210841102109410321074119210a410d210b20034188016a200241c8006a2201470d010c070b200341f0026a41186a22074200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008410012201290000211a2002200141086a2900003703002003201a3703f002200110354189eaca00ad4280808080f0008410012201290000211a200341e8006a41086a2209200141086a2900003703002003201a37036820011035200e2003290368370000200e41086a2009290300370000200341c8026a41086a2002290300370300200341c8026a41106a2008290300370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10fe0120032802f0022201410120011b210d41002102024020032902f402420020011b221a422088a7220141014b0d0020010e020403040b03402001410176220720026a22082002200d20084105746a20034188016a412010a0084101481b2102200120076b220141014b0d000c030b0b200141206a2102200120034188016a412010a0080d000c050b0b200d20024105746a20034188016a412010a0080d0041ce9cc8002108410d2109410321074119210a4102210b0c010b200342003703d00220034280809aa6eaafe3013703c802200320034188016a360268200320034188016a36028002200320034180026a3602f8022003200341e8006a3602f4022003200341c8026a3602f002200341b0016a20034188016a200341f0026a108c030240024020032802b0014101470d00200341bc016a2802002109200341b8016a280200210820032d00b701210c20032d00b601210b20032d00b501210a20032d00b40121070c010b410421070240200341b0016a41086a2903004201520d00200341b0016a41106a290300211b2003280280022102200341a8036a200341b0016a41186a290300370300200341a0036a201b370300200341f0026a41086a41003a0000200341f9026a200229000037000020034181036a200241086a29000037000020034189036a200241106a29000037000020034191036a200241186a290000370000200341033a00f00241b0b4cc004100200341f0026a10d4010b0b200741ff01714104460d010b201a42ffffff3f83500d01200d10350c010b200320063702b4012003200f3602b001200341f0026a41106a4200370300200341f0026a41086a22024280809aa6eaafe301370300200341003a00f002200341b0016a20034188016a20052004200341f0026a10d606200341a8036a2004370300200341a0036a2005370300200241013a0000200341f9026a20032903880137000020034181036a20034188016a41086a29030037000020034189036a20034188016a41106a29030037000020034191036a200341a0016a290300370000200341123a00f00241b0b4cc004100200341f0026a10d4010240201a42ffffff3f83500d00200d10350b02402019a72202450d00200241e8006c450d00201010350b420021060c200b2019a72202450d02200241e8006c450d02201010350c020b200141206a2102200120034188016a412010a0080d000b0b2006a72202450d1b200241e8006c450d1b200f10350c1b0b4182b23c21070240024020022d000120022d0000410047720d004183b23c2107200141046a280200220241014b0d010b20004200370308200041206a410a3602002000411c6a41a99bc800360200200041186a2007360200420121060c1d0b42002106200341e8006a41186a4200370300200341e8006a41106a22094200370300200341e8006a41086a220742003703002003420037036841a29bc800ad4280808080f0008410012208290000210420034180026a41086a2201200841086a29000037030020032004370380022008103520072001290300370300200320032903800237036841a99bc800ad4280808080a001841001220829000021042001200841086a29000037030020032004370380022008103520092003290380022204370300200341c8026a41086a2007290300370300200341c8026a41106a2004370300200341c8026a41186a2001290300370300200320032903683703c802200320023602f002200341c8026aad4280808080800484200341f0026aad4280808080c000841002200341fc026a2002360200200341f0026a41086a410d3a0000200341123a00f00241b0b4cc004100200341f0026a10d4010c0b0b200141216a2d0000210820034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a2900003703002003200129000137038801200341f0026a41206a200241206a290200370300200341f0026a41186a200241186a290200370300200341f0026a41106a200241106a290200370300200341f0026a41086a200241086a290200370300200320022902003703f002200341b0016a200341f0026a10d70602400240024020032d00b0014101460d00200341e8006a20034188016a10cf06200328026821022003200328027022013602bc02200320023602b802200341c8026a2001ad4220862002ad84100510c2010240024020032802c80222070d00410221010c010b20032802cc0221092003200341c8026a41086a280200220136028402200320073602800202400240024020014110490d002003200141706a360284022003200741106a36028002200741086a290000210620072900002104200341f0026a20034180026a10bf0220032d00f00222014102470d010b200341003602b801200342013703b001200341093602f4032003200341b8026a3602f0032003200341b0016a3602fc0320034184036a4101360200200342013702f402200341c888c2003602f0022003200341f0036a36028003200341fc036a41e88ac500200341f0026a10431a20033502b80142208620033502b001841006024020032802b401450d0020032802b00110350b410221010c010b200341b0016a41086a20034190036a290300370300200320032800f4023600f303200320032800f1023602f003200320034188036a2903003703b00120034180036a2903002119200341f0026a41086a2903002105200341a0036a290300211a20034198036a290300211b0b2009450d00200710350b20034180026a41086a2207200341b0016a41086a290300370300200320032802f0033602f002200320032800f3033600f302200320032903b00137038002024020014102460d00200341a0026a41086a2007290300370300200320032800f3023600b302200320032802f0023602b00220032003290380023703a0020b0240200328026c450d00200210350b20014102470d0141b99cc8002101410c21074103210241192108410421090c020b410221020c010b200341b8026a41086a2207200341a0026a41086a290300370300200320032802b0023602f003200320032800b3023600f303200320032903a0023703b80241032102024002400240024002400240024020084103710e03000201000b200341f0026a41186a220a4200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008410012209290000211c2002200941086a2900003703002003201c3703f00220091035419cbac800ad4280808080c0008410012209290000211c200341e8006a41086a220b200941086a2900003703002003201c3703682009103520082003290368221c370300200341c8026a41086a2002290300370300200341c8026a41106a201c370300200341c8026a41186a200b290300370300200320032903f0023703c802200341f0026a200341c8026a10be02200320032902f402420020032802f00222091b3702b40120032009410820091b3602b0012008201937030020022005370300200341a0036a201a37030020034198036a201b370300200a20032903b80237030020034190036a2007290300370300200320013a00f002200320032802f0033600f102200320032800f3033600f402200341b0016a20034188016a20042006200341f0026a10d6060c020b200341e8006a41186a4200370300200341e8006a41106a4200370300200341e8006a41086a220742003703002003420037036841a29bc800ad4280808080f0008410012208290000211c20034180026a41086a2209200841086a2900003703002003201c370380022008103520072009290300370300200320032903800237036841ceb8c800ad428080808030841001220841086a290000211c2008290000211d20081035200341c8026a41106a201d370300200341c8026a41186a201c370300200341c8026a41086a2007290300370300200320032903683703c802200341d0006a200341c8026a412010d701024020032903584200200328025022071b221d2004542208200341d0006a41106a290300420020071b221c200654201c2006511b450d0041949cc8002101410f210741192108410721090c060b200341f0026a20034188016a10d806200341f0026a41086a2107024020032d00f00222024104460d002007280200210720032802f402210120032d00f302210a20032d00f202210920032d00f10221080c060b200341e8006a41186a4200370300200341e8006a41106a4200370300200341e8006a41086a220242003703002003420037036841a29bc800ad4280808080f00084221e10012209290000211f20034180026a41086a220a200941086a2900003703002003201f37038002200910352002200a290300370300200320032903800237036841ceb8c800ad428080808030841001220941086a290000211f2009290000212020091035200341c8026a41106a22092020370300200341c8026a41186a220a201f370300200341c8026a41086a220b2002290300370300200320032903683703c8022003201c20067d2008ad7d3703f8022003201d20047d3703f002200341c8026aad4280808080800484200341f0026aad42808080808002841002200341f0026a41186a220d4200370300200341f0026a41106a2208420037030020074200370300200342003703f00241d1c4c700ad4280808080e000841001220c290000211c2007200c41086a2900003703002003201c3703f002200c103541e7c4c700ad4280808080e000841001220c290000211c2002200c41086a2900003703002003201c370368200c103520082003290368221c370300200b20072903003703002009201c370300200a2002290300370300200320032903f0023703c802200341c8006a200341c8026a412010c001200328024c210e2003280248210f200d42003703002008420037030020074200370300200342003703f002201e1001220c290000211c2007200c41086a2900003703002003201c3703f002200c10354189eaca00ad4280808080f000841001220c290000211c2002200c41086a2900003703002003201c370368200c103520082003290368221c370300200b20072903003703002009201c370300200a2002290300370300200320032903f0023703c802200341f0026a200341c8026a10fe0120032902f402420020032802f00222021b221c422088a741f4036a2207450d02200341e4003a00f102200341e40041d0860320076e22076b3a00f002200e4100200f1b2108200341f0026a200741ff017141e4004b6a2d00004180fe126c21070240201c42ffffff3f83500d002002410120021b10350b200720086a210220034180026a41086a2207200341b8026a41086a290300370300200320032802f003360268200320032800f30336006b200320032903b802370380020240024020014101470d00200341ff026a20193700002003418f036a20072d00003a0000200320053700f7022003200328006b3600f302200320032802683602f002200320032903800237008703200341b0016a200341f0026a10d006024020032802b001220120032802b801220810d10241ff017122074102460d002008ad4220862001ad8410070b024020032802b401450d00200110350b20070d01200341f0026a20022004201b2004201b5422012006201a542006201a511b22071b2006201a20071b10b00642002006201a7d2001ad7d22052004201b7d2219200456200520065620052006511b22011b21064200201920011b21040c010b200320053703c802200320193703d0022005201984500d00200320034188016a3602fc03200341b0016a20034188016a200341c8026a200341fc036a10f00220032903b0014201520d0020032903b8012105200341a8036a200341b0016a41106a290300370300200341a0036a2005370300200341f0026a41086a41003a0000200341f9026a20032903880137000020034181036a20034188016a41086a29030037000020034189036a20034188016a41106a29030037000020034191036a200341a0016a290300370000200341033a00f00241b0b4cc004100200341f0026a10d4010b20034188016a20022004200610b0060c010b02402001410171450d00200341ff026a20193700002003418f036a200341c0026a2d00003a0000200320053700f702200320032800f3033600f302200320032802f0033602f002200320032903b80237008703200341b0016a200341f0026a10d00620033502b801210620032802b0012101410110332202450d16200241013a000020064220862001ad842002ad4280808080108410022002103520032802b401450d01200110350c010b200342f0f2bd99f7edd8b4e5003703b001200341f0026a200341b0016a10e001200341b0016a20034188016a200341f0026a20052019410010ef020b200341f0026a41186a220120034188016a41186a290300370300200341f0026a41106a220720034188016a41106a290300370300200341f0026a41086a220820034188016a41086a29030037030020032003290388013703f00241a29bc800ad4280808080f0008410012202290000210620034180026a41086a200241086a29000037030020032006370380022002103541e0aec900ad4280808080b00284100122022900002106200241086a290000210420021035412010332202450d07200220032903f002370000200241186a2001290300370000200241106a2007290300370000200241086a200829030037000020032002ad42808080808004841003220129000037036820011035200341bc016a200241206a360200200320023602b8012003200341e8006a41086a3602b4012003200341e8006a3602b001200341c8026a200341b0016a107b2002103520032802d002220941206a2201417f4c0d0120032802c802210a0240024020010d0041002107410121020c010b200110332202450d08200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322020d010c160b20072008460d0020022007200810372202450d150b2002200329038002370000200241086a20034180026a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020022008200710372202450d150b20022006370010200241186a200437000002400240200741606a2009490d00200721080c010b2009415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020022007200810372202450d150b200241206a200a2009109d081a024020032802cc02450d00200a10350b2001ad4220862002ad8410072008450d0d20021035420021060c0e0b41f0b8c8004119418cb9c800103f000b1044000b103e000b20004200370308200041206a20073602002000411c6a2001360200200041186a200a411874200941ff017141107472200841ff017141087472200272360200420121060c1b0b200141216a2d0000210720034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a2900003703002003200129000137038801200341f0026a41206a200241206a290200370300200341f0026a41186a200241186a290200370300200341f0026a41106a200241106a290200370300200341f0026a41086a200241086a290200370300200320022902003703f002200341b0016a200341f0026a10d706410221020240024020032d00b0014101460d00200341f0026a20034188016a10b906200341c0006a20032802f002220220032802f80241b0b4cc0041004100108a0220032802402101024020032802f402450d00200210350b4103210220014101470d000240024002400240200741ff01710d00200341f0026a20034188016a10b80620033502f80242208620032802f0022202ad841007024020032802f402450d00200210350b200341f0026a20034188016a10ba0620033502f80242208620032802f0022202ad841007024020032802f402450d00200210350b200341f0026a20034188016a10d006024020032802f002220220032802f802220810d10241ff017122014102460d002008ad4220862002ad8410070b024020032802f402450d00200210350b20010d03200341f0026a41186a4200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008422041001220129000021062002200141086a290000370300200320063703f00220011035419cbac800ad4280808080c000842205100122012900002106200341e8006a41086a220d200141086a2900003703002003200637036820011035200820032903682206370300200341c8026a41086a220c2002290300370300200341c8026a41106a220e2006370300200341c8026a41186a220f200d290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b210920032902f402420020021b2206422088a72210450d02201041037441786a41037641016a210a2009417f7320034188016a6a210b410021024100210103400240200920026a22082d0000450d00200b2002460d03200841016a20034188016a412010a008450d030b200241e8006a2102200a200141016a2201470d000c030b0b200341f0026a20034188016a10d80620032d00f00222024104460d02200341f0026a41086a280200210120032802f402210720032d00f102410874210820032d00f202411074210920032d00f302411874210a0c040b200341f0026a200841e800109d081a2008200841e8006a201041e8006c20026b41987f6a109e081a200341e0026a200341d0036a2903002219370300200341d8026a200341c8036a290300221a370300200341c8026a41086a200341c0036a290300221b370300200320032903b803221c3703c802200341f0026a41086a41053a0000200341f9026a201c37000020034181036a201b37000020034189036a201a37000020034191036a2019370000200341123a00f00241b0b4cc004100200341f0026a10d40120064280808080707c21060b200f4200370300200e4200370300200c4200370300200342003703c802200410012201290000210420034180026a41086a2202200141086a290000370300200320043703800220011035200c200229030037030020032003290380023703c80220051001220129000021042002200141086a290000370300200320043703800220011035200e2003290380022204370300200d200c290300370300200341e8006a41106a2004370300200341e8006a41186a2002290300370300200320032903c802370368024020090d00200341e8006aad428080808080048410070c010b200341f0026a20092006422088a710b106200341e8006aad428080808080048420033502f80242208620032802f0022202ad841002024020032802f402450d00200210350b2006a72202450d00200241e8006c450d00200910350b200341f0026a20034188016a10b90620033502f80242208620032802f0022202ad841007024020032802f402450d00200210350b200341f0026a41086a41073a0000200341f9026a20032903880137000020034199036a20073a000020034181036a20034188016a41086a29030037000020034189036a20034198016a29030037000020034191036a200341a0016a290300370000200341123a00f00241b0b4cc004100200341f0026a10d401420021060c0b0b41b99cc8002107410c210141803221084180801021094100210a0b20004200370308200041206a20013602002000411c6a2007360200200041186a200a200972200872200272360200420121060c1a0b4102210141803221070240024020022d00000d0020022d00014101470d002002411a6a2901002104200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d00002121200241046a2d00002122200241026a2f01002123200341e8006a41186a22094200370300200341e8006a41106a22074200370300200341e8006a41086a220242003703002003420037036841a29bc800ad4280808080f0008410012208290000210620034180026a41086a2201200841086a29000037030020032006370380022008103520022001290300370300200320032903800237036841ef9bc800ad4280808080f000841001220829000021062001200841086a29000037030020032006370380022008103520072003290380022206370300200341c8026a41086a2002290300370300200341c8026a41106a2006370300200341c8026a41186a2001290300370300200320032903683703c802200341f0026a200341c8026a412010d50120032d00f00221012009200341f0026a41196a2900003703002007200341f0026a41116a2900003703002002200341f0026a41096a290000370300200320032900f1023703680240024020014101460d0041002102200341003a00b0010c010b200341b0016a41096a2002290300370000200341b0016a41116a2007290300370000200341b0016a41196a200929030037000041012102200341013a00b001200320032903683700b1010b20034189036a200437000020034188036a200a3a000020034187036a200b3a000020034185036a200c3b000020034184036a200d3a000020034183036a200e3a000020034181036a200f3b000020034180036a20103a0000200341ff026a20113a0000200341fd026a20123b0000200341fc026a20133a0000200341fb026a20143a0000200341f9026a20153b0000200341f8026a20163a0000200320173a00f702200320183b00f502200320213a00f402200320223a00f302200320233b00f102200341013a00f002024020020d0041bf9bc8002108410a2102410321014180b2c00021070c020b410321010240200341b0016a410172200341f0026a410172412010a008450d0041bf9bc8002108410a21024180b2c00021070c020b200341e8006a41186a22094200370300200341e8006a41106a22244200370300200341e8006a41086a220242003703002003420037036841a29bc800ad4280808080f0008410012225290000210620034180026a41086a2208202541086a29000037030020032006370380022025103520022008290300370300200320032903800237036841f69bc800ad4280808080c000841001222529000021062008202541086a2900003703002003200637038002202510352007200329038002370000200741086a2008290300370000200341c8026a41086a2002290300370300200341c8026a41106a2024290300370300200341c8026a41186a2009290300370300200320032903683703c802200341f0026a200341c8026a412010d50120032d00f00221252009200341f0026a41196a2900003703002024200341f0026a41116a2900003703002002200341f0026a41096a290000370300200320032900f102370368410121080240024020254101460d0041002108200341003a00b0010c010b200341b0016a41096a2002290300370000200341b0016a41116a2024290300370000200341b0016a41196a2009290300370000200341013a00b001200320032903683700b1010b20034189036a200437000020034188036a200a3a000020034187036a200b3a000020034185036a200c3b000020034184036a200d3a000020034183036a200e3a000020034181036a200f3b000020034180036a20103a0000200341ff026a20113a0000200341fd026a20123b0000200341fc026a20133a0000200341fb026a20143a0000200341f9026a20153b0000200341f8026a20163a0000200320173a00f702200320183b00f502200320213a00f402200320223a00f302200320233b00f102200341013a00f002024002402008450d00200341b0016a410172200341f0026a410172412010a008450d010b41b89bc8002108410721024180b2c40021070c020b42002106200341e8006a41186a22084200370300200341e8006a41106a22094200370300200341e8006a41086a220142003703002003420037036841a29bc800ad4280808080f00084220510012224290000211920034180026a41086a2202202441086a2900003703002003201937038002202410352001200229030037030020032003290380023703684189eaca00ad4280808080f000841001222429000021192002202441086a2900003703002003201937038002202410352007200329038002370000200741086a22242002290300370000200341c8026a41086a22252001290300370300200341c8026a41106a22262009290300370300200341c8026a41186a22272008290300370300200320032903683703c802200341c8026aad42808080808004842219100720084200370300200942003703002001420037030020034200370368200510012228290000211a2002202841086a2900003703002003201a370380022028103520012002290300370300200320032903800237036841f69bc800ad4280808080c0008410012228290000211a2002202841086a2900003703002003201a3703800220281035200720032903800237000020242002290300370000202520012903003703002026200929030037030020272008290300370300200320032903683703c8022019100720084200370300200942003703002001420037030020034200370368200510012228290000211a2002202841086a2900003703002003201a370380022028103520012002290300370300200320032903800237036841ef9bc800ad4280808080f0008410012228290000211a2002202841086a2900003703002003201a3703800220281035200720032903800237000020242002290300370000202520012903003703002026200929030037030020272008290300370300200320032903683703c8022019100720084200370300200942003703002001420037030020034200370368200510012228290000211a2002202841086a2900003703002003201a37038002202810352001200229030037030020032003290380023703684188aec900ad4280808080d0008410012228290000211a2002202841086a2900003703002003201a3703800220281035200720032903800237000020242002290300370000202520012903003703002026200929030037030020272008290300370300200320032903683703c8022019100720084200370300200942003703002001420037030020034200370368200510012228290000211a2002202841086a2900003703002003201a370380022028103520012002290300370300200320032903800237036841e1b8c800ad4280808080a0018410012228290000211a2002202841086a2900003703002003201a3703800220281035200720032903800237000020242002290300370000202520012903003703002026200929030037030020272008290300370300200320032903683703c802201910072008420037030020094200370300200142003703002003420037036820051001222829000021052002202841086a29000037030020032005370380022028103520012002290300370300200320032903800237036841e0aec900ad4280808080b002841001222829000021052002202841086a290000370300200320053703800220281035200720032903800237000020242002290300370000202520012903003703002026200929030037030020272008290300370300200320032903683703c8022019100820034191036a2004370000200341f0026a41206a200a3a00002003418f036a200b3a00002003418d036a200c3b00002003418c036a200d3a00002003418b036a200e3a000020034189036a200f3b0000200341f0026a41186a20103a000020034187036a20113a000020034185036a20123b000020034184036a20133a000020034183036a20143a000020034181036a20153b0000200341f0026a41106a20163a0000200341ff026a20173a0000200341fd026a20183b0000200341fc026a20213a0000200341fb026a20223a0000200341f9026a20233b0000200341f0026a41086a410e3a0000200341123a00f00241b0b4cc004100200341f0026a10d4010c0a0b0b20004200370308200041206a20023602002000411c6a2008360200200041186a2007200172360200420121060c190b200141246a280200210f200341c8016a200141196a290000370300200341c0016a200141116a290000370300200341b8016a200141096a290000370300200320012900013703b0014102210a2001412c6a280200210c200141286a280200210e4100210b20022d0000417f6a220d41024b0d01200141306a3502002104410021094100210102400240200d0e03000401000b200241086a2802004101742002410c6a2802004d0d024100210941002101200241046a28020041ff01710d030b200341e8006a41186a4200370300200341e8006a41106a22074200370300200341e8006a41086a220142003703002003420037036841a29bc800ad4280808080f0008410012208290000210620034180026a41086a2202200841086a29000037030020032006370380022008103520012002290300370300200320032903800237036841f69bc800ad4280808080c000841001220829000021062002200841086a29000037030020032006370380022008103520072003290380022206370300200341c8026a41086a2001290300370300200341c8026a41106a2006370300200341c8026a41186a2002290300370300200320032903683703c8024100210b200341386a200341c8026a412041b0b4cc0041004100108a024103210a4180322101024020032802384101470d0041a39cc8002108410e21074180801821090c030b0240200f41024f0d0041a99bc8002108410a21074180803c21090c030b200341e8006a41186a22084200370300200341e8006a41106a22094200370300200341e8006a41086a220142003703002003420037036841a29bc800ad4280808080f0008422051001220a290000210620034180026a41086a2202200a41086a2900003703002003200637038002200a103520012002290300370300200320032903800237036841a99bc800ad4280808080a001841001220a29000021062002200a41086a2900003703002003200637038002200a10352007200329038002370000200741086a220b2002290300370000200341c8026a41086a220d2001290300370300200341c8026a41106a22102009290300370300200341c8026a41186a22112008290300370300200320032903683703c8022003200f3602f002200341c8026aad42808080808004842206200341f0026aad4280808080c000841002200341f0026a200341b0016a10d806024020032d00f002220a4104470d002008420037030020094200370300200142003703002003420037036820051001220a29000021052002200a41086a2900003703002003200537038002200a103520012002290300370300200320032903800237036841f69bc800ad4280808080c000841001220a29000021052002200a41086a2900003703002003200537038002200a10352007200329038002370000200b2002290300370000200d20012903003703002010200929030037030020112008290300370300200320032903683703c802412010332202450d01200220032903b001370000200241186a200341b0016a41186a220b290300370000200241106a200341b0016a41106a220d290300370000200241086a200341b0016a41086a220f29030037000020062002ad4280808080800484100220021035200341e8006a41186a22094200370300200341e8006a41106a220a4200370300200341e8006a41086a220842003703002003420037036841a29bc800ad4280808080f00084220510012201290000211920034180026a41086a2202200141086a29000037030020032019370380022001103520082002290300370300200320032903800237036841ef9bc800ad4280808080f000841001220129000021192002200141086a2900003703002003201937038002200110352007200329038002370000200741086a22102002290300370000200341c8026a41086a22112008290300370300200341c8026a41106a2212200a290300370300200341c8026a41186a22132009290300370300200320032903683703c802412010332201450d01200120032903b001370000200141186a200b290300370000200141106a200d290300370000200141086a200f29030037000020062001ad4280808080800484100220011035200341f0026a41186a2004422086200ead841009220141186a290000370300200341f0026a41106a200141106a290000370300200341f0026a41086a200141086a290000370300200320012900003703f0022001103520094200370300200a4200370300200842003703002003420037036820051001220129000021042002200141086a2900003703002003200437038002200110352008200229030037030020032003290380023703684188aec900ad4280808080d000841001220129000021042002200141086a290000370300200320043703800220011035200720032903800237000020102002290300370000201120082903003703002012200a29030037030020132009290300370300200320032903683703c802412010332202450d01200220032903f002370000200241186a200341f0026a41186a290300370000200241106a200341f0026a41106a290300370000200241086a200341f0026a41086a220129030037000020062002ad4280808080800484100220021035200141003a0000200341f9026a20032903b00137000020034181036a200341b0016a41086a29030037000020034189036a200341b0016a41106a29030037000020034191036a200341b0016a41186a290300370000200341123a00f00241b0b4cc004100200341f0026a10d401200c450d07200e1035420021060c080b200341f0026a41086a280200210720032802f402210820032d00f102410874210120032d00f202411074210920032d00f302411874210b0c020b1045000b41002109410021010b0240200c450d00200e10350b20004200370308200041206a20073602002000411c6a2008360200200041186a200b200972200172200a72360200420121060c150b20032002411a6a290100370380014102210a2003200241026a29010037036820032002410a6a2901003703702003200241126a2901003703784101210b410021010240024002400240024020022d000041004720022d0001410147720d00200341b0016a41186a200341e8006a41186a290300370300200341b0016a41106a200341e8006a41106a290300370300200341b0016a41086a200341e8006a41086a2202290300370300200320032903683703b001200341f0026a41186a4200370300200341f0026a41106a220f4200370300200341f0026a41086a22074200370300200342003703f00241a29bc800ad4280808080f000841001220829000021062007200841086a290000370300200320063703f002200810354189eaca00ad4280808080f000841001220829000021062002200841086a2900003703002003200637036820081035200f20032903682206370300200341c8026a41086a2007290300370300200341c8026a41106a2006370300200341c8026a41186a2002290300370300200320032903f0023703c802200341f0026a200341c8026a10fe0120032802f0022202410120021b210941f2dfca00210c4109210d4103210a4119210e0240024020032902f402420020021b2206422088a7220241014b0d0020020e020401040b4100210103402002410176220720016a22082001200920084105746a200341b0016a412010a0084101481b2101200220076b220241014b0d000b0b200920014105746a200341b0016a412010a0080d02200341f0026a200341b0016a10b806200341c8026a20032802f002220720032802f80210b40220032902cc02210420032802c8022201410820011b2102024020032802f402450d00200710350b2004420020011b210402402002450d002004422088a72210450d00200341f0026a41186a22084200370300200341f0026a41106a220a4200370300200341f0026a41086a22014200370300200342003703f00241d1c4c700ad4280808080e000841001220729000021052001200741086a290000370300200320053703f0022007103541e7c4c700ad4280808080e00084100122072900002105200341e8006a41086a220b200741086a2900003703002003200537036820071035200f2003290368370000200f41086a200b290300370000200341c8026a41086a22072001290300370300200341c8026a41106a200a290300370300200341c8026a41186a2008290300370300200320032903f0023703c802200341306a200341c8026a412010c00120022802002003280234410020032802301b4b0d00200342f0f2bd99f7edd8b4e5003703c802200341f0026a200341c8026a108106200341c8026a200341f0026a200341b0016a2002290308200241106a290300410110e6022007280200210d20032802cc02210c20032d00cb02210720032d00ca02210b20032d00c902210e024020032d00c802220a4104470d002002200241186a2010417f6a220141186c109e08210802402001450d00200341f0026a200341b0016a10b80620032802f0022102200320032802f8023602cc02200320023602c80220082001200341c8026a109603024020032802f402450d00200210350b4104210a2004a72202450d04200241186c450d04200810350c040b200341f0026a200341b0016a10b80620033502f80242208620032802f0022201ad841007024020032802f402450d00200110350b200442ffffffff0f8321044104210a0b2004a72201450d03200141186c450d03200210350c030b02402004a72201450d00200141186c450d00200210350b0240200642ffffff3f83500d00200910350b41b19cc800210c4108210d4103210a4119210e4105210b0c030b0c020b0b0240200642ffffff3f83500d00200910350b42002106200a4104460d010b200041206a200d3602002000411c6a200c360200200041186a2007411874200b41ff017141107472200e41ff017141087472200a72360200420121060b200042003703080c140b20012d0001210a20032002411a6a29010037038001410221012003200241026a29010037036820032002410a6a2901003703702003200241126a29010037037802400240024020022d00014101470d0020022d000041ff01710d00200341b0016a41186a200341e8006a41186a290300370300200341b0016a41106a200341e8006a41106a290300370300200341b0016a41086a200341e8006a41086a2202290300370300200320032903683703b001200341f0026a41186a4200370300200341f0026a41106a22084200370300200341f0026a41086a22014200370300200342003703f00241a29bc800ad4280808080f000841001220729000021062001200741086a290000370300200320063703f002200710354189eaca00ad4280808080f000841001220729000021062002200741086a2900003703002003200637036820071035200820032903682206370300200341c8026a41086a2001290300370300200341c8026a41106a2006370300200341c8026a41186a2002290300370300200320032903f0023703c802200341f0026a200341c8026a10fe0120032802f0022201410120011b21094100210202400240024020032902f402420020011b2206422088a7220141014b0d0020010e020201020b03402001410176220720026a22082002200920084105746a200341b0016a412010a0084101481b2102200120076b220141014b0d000b0b200920024105746a200341b0016a412010a0080d00200a41ff01710d02200341013a00c802200341f0026a200341b0016a10b30620033502f802210420032802f0022101410110332202450d0c200241013a000020044220862001ad842002ad4280808080108410022002103520032802f402450d03200110350c030b02402006a72202450d00200241ffffff3f71450d00200910350b410321010b20004200370308200041206a41093602002000411c6a41f2dfca00360200200041186a20014180b20472360200420121060c150b200341023a00c802200341f0026a200341b0016a10b30620033502f802210420032802f0022101410110332202450d09200241023a000020044220862001ad842002ad4280808080108410022002103520032802f402450d00200110350b200341f0026a41086a410c3a0000200341f9026a20032903b00137000020034181036a200341b0016a41086a29030037000020034189036a200341c0016a29030037000020034191036a200341c8016a29030037000020034199036a200a3a0000200341123a00f00241b0b4cc004100200341f0026a10d401200642ffffff3f83500d0120091035420021060c020b20012d0001210c200341b0016a41206a2208200141246a280200360200200341b0016a41186a22092001411c6a290200370300200341b0016a41106a220a200141146a290200370300200341b0016a41086a220b2001410c6a2902003703002003200141046a2902003703b00120032002411a6a2901003703e002410221012003200241026a2901003703c80220032002410a6a2901003703d0022003200241126a2901003703d80241002107024020022d000041004720022d000141014772450d000c050b20034180026a41186a200341c8026a41186a29030037030020034180026a41106a200341c8026a41106a29030037030020034180026a41086a200341c8026a41086a290300370300200320032903c80237038002200341f0026a41206a2008280200360200200341f0026a41186a2009290300370300200341f0026a41106a200a290300370300200341f0026a41086a200b290300370300200320032903b0013703f002200341c8026a200341f0026a108b02200341e8006a41086a200341d1026a290000370300200341e8006a41106a200341d9026a290000370300200341e8006a41186a200341e1026a290000370300200320032900c90237036820032d00c8024101460d0220034188016a41186a200341e8006a41186a29030037030020034188016a41106a200341e8006a41106a29030037030020034188016a41086a200341e8006a41086a22022903003703002003200329036837038801200341f0026a41186a4200370300200341f0026a41106a22084200370300200341f0026a41086a22014200370300200342003703f00241a29bc800ad4280808080f000841001220729000021062001200741086a290000370300200320063703f0022007103541e1b8c800ad4280808080a001841001220729000021062002200741086a2900003703002003200637036820071035200820032903682206370300200341c8026a41086a2001290300370300200341c8026a41106a2006370300200341c8026a41186a2002290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b220a20032902f402420020021b2206422088a741e8006c6a2107200a21020340024020022007470d0041c99bc8002108410c21024180803821070c050b024020034188016a200241c8006a2201460d00200141206a2102200120034188016a412010a0080d010b0b200341f0026a41186a22074200370300200341f0026a41106a22094200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f000841001220129000021042002200141086a290000370300200320043703f002200110354189eaca00ad4280808080f00084100122012900002104200341e8006a41086a220b200141086a290000370300200320043703682001103520082003290368370000200841086a200b290300370000200341c8026a41086a2002290300370300200341c8026a41106a2009290300370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10fe0120032802f0022201410120011b2109410021020240024002400240024020032902f402420020011b2204422088a7220141014b0d0020010e020201020b03402001410176220720026a22082002200920084105746a20034180026a412010a0084101481b2102200120076b220141014b0d000b0b200920024105746a20034180026a412010a0080d00200c41ff01710d01200341013a00c802200341f0026a20034188016a20034180026a10b20620033502f802210520032802f0022101410110332202450d0a200241013a000020054220862001ad842002ad4280808080108410022002103520032802f402450d02200110350c020b41f2dfca00210841092102418080042107200442ffffff3f83500d05200910350c050b200341023a00c802200341f0026a20034188016a20034180026a10b20620033502f802210520032802f0022101410110332202450d08200241023a000020054220862001ad842002ad4280808080108410022002103520032802f402450d00200110350b200341f0026a41086a410b3a0000200341f9026a20032903880137000020034181036a20034188016a41086a29030037000020034189036a20034188016a41106a29030037000020034191036a20034188016a41186a29030037000020034199036a200329038002370000200341a1036a20034180026a41086a290300370000200341a9036a20034180026a41106a290300370000200341b1036a20034180026a41186a290300370000200341123a00f002200341b9036a200c3a000041b0b4cc004100200341f0026a10d4010240200442ffffff3f83500d00200910350b2006a72202450d00200241e8006c450d00200a10350b420021060b200020063703080c100b410121010c010b410321012006a72209450d00200941e8006c450d00200a10350b200041206a20023602002000411c6a2008360200200041186a20074180803c712001724180327236020020004200370308420121060c0d0b4102210702400240024020022d00000d0020022d00014101470d00200141046a2802002118200241196a2d00002101200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720032002411a6a2901003703c801200320013a00c701200320073a00c601200320083b01c401200320093a00c3012003200a3a00c2012003200b3b01c0012003200c3a00bf012003200d3a00be012003200e3b01bc012003200f3a00bb01200320103a00ba01200320113b01b801200320123a00b701200320133a00b601200320143b01b401200320153a00b301200320163a00b201200320173b01b001200341f0026a200341b0016a10d00620032802f002220120032802f80210d10241ff01712102024020032802f402450d00200110350b4103210720020d00200341f0026a41186a4200370300200341f0026a41106a22074200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008422041001220129000021062002200141086a290000370300200320063703f00220011035419cbac800ad4280808080c000842205100122012900002106200341e8006a41086a220b200141086a2900003703002003200637036820011035200720032903682206370300200341c8026a41086a22082002290300370300200341c8026a41106a220c2006370300200341c8026a41186a2209200b290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022201410820011b210a410b210202400240201820032902f402420020011b2206422088a72201490d0041db9cc800210141833221070c010b41803221070240200a201841e8006c6a220d2d00000d0041e683ca0021010c010b0240200341b0016a200d41016a2202460d002002200341b0016a412010a008450d0041d483ca002101411221020c010b200341f0026a200341b0016a10d00620033502f80242208620032802f0022202ad841007024020032802f402450d00200210350b200341f0026a200a201841e8006c6a220241e800109d081a2002200241e8006a20012018417f736a41e8006c109e081a200341e0026a200341d0036a2903002219370300200341d8026a200341c8036a290300221a370300200341c8026a41086a200341c0036a290300221b370300200320032903b803221c3703c802200341f0026a41086a41053a0000200341f9026a201c37000020034181036a201b37000020034189036a201a37000020034191036a2019370000200341123a00f00241b0b4cc004100200341f0026a10d40120064280808080707c210641843221070b20094200370300200c420037030020084200370300200342003703c80220041001220d290000210420034180026a41086a2209200d41086a2900003703002003200437038002200d10352008200929030037030020032003290380023703c80220051001220d29000021042009200d41086a2900003703002003200437038002200d1035200c2003290380022204370300200b2008290300370300200341e8006a41106a2004370300200341e8006a41186a2009290300370300200320032903c80237036802400240200a0d00200341e8006aad428080808080048410070c010b200341f0026a200a2006422088a710b106200341e8006aad428080808080048420033502f80242208620032802f0022208ad841002024020032802f402450d00200810350b2006a72208450d00200841e8006c450d00200a10350b4180322108420021062007418432460d020c010b41fa9bc8002101410b21024180b22421080b200041206a20023602002000411c6a2001360200200041186a2008200741ff017172360200420121060b200042003703080c0c0b200141c0006a2903002119200141386a290300211a200141306a2903002104200141286a290300210520034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a29000037030020032001290001370388012002411a6a2901002106200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211841012101024020022d00000d0020022d000141014721010b2003200637038001200320073a007f200320083a007e200320093b017c2003200a3a007b2003200b3a007a2003200c3b01782003200d3a00772003200e3a00762003200f3b0174200320103a0073200320113a0072200320123b0170200320133a006f200320143a006e200320153b016c200320163a006b200320173a006a200320183b016802400240024020010d00200341b0016a41186a200341e8006a41186a290300370300200341b0016a41106a200341e8006a41106a290300370300200341b0016a41086a200341e8006a41086a290300370300200320032903683703b001200341f0026a20034188016a10cf06200341286a20032802f002220220032802f80241b0b4cc0041004100108a0220032802282101024020032802f402450d00200210350b4103210220014101460d01200341f0026a20034188016a10b906200341206a20032802f002220720032802f80241b0b4cc0041004100108a0220032802202101024020032802f402450d00200710350b20014101460d01200341f0026a41186a4200370300200341f0026a41106a220b4200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f000841001220129000021062002200141086a290000370300200320063703f00220011035419cbac800ad4280808080c00084100122012900002106200341e8006a41086a2207200141086a2900003703002003200637036820011035200b20032903682206370300200341c8026a41086a2002290300370300200341c8026a41106a2006370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b220c20032902f402420020021b2206422088a741e8006c6a210a200c2102024003402002200a460d0141e59bc8002108410a2109410c210720034188016a200241c8006a2201460d08200141206a2102200120034188016a412010a0080d000c080b0b200341f0026a41186a22074200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008410012201290000211b2002200141086a2900003703002003201b3703f0022001103541e1b8c800ad4280808080a0018410012201290000211b200341e8006a41086a2209200141086a2900003703002003201b37036820011035200b2003290368370000200b41086a2009290300370000200341c8026a41086a2002290300370300200341c8026a41106a2008290300370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b220e20032902f402420020021b221b422088a741e8006c6a210a200e2102024003402002200a460d0141d59bc800210841102109410d210720034188016a200241c8006a2201460d07200141206a2102200120034188016a412010a0080d000c070b0b200341f0026a41186a22074200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008410012201290000211c2002200141086a2900003703002003201c3703f002200110354189eaca00ad4280808080f0008410012201290000211c200341e8006a41086a2209200141086a2900003703002003201c37036820011035200b2003290368370000200b41086a2009290300370000200341c8026a41086a2002290300370300200341c8026a41106a2008290300370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10fe014101210720032802f0022201410120011b210b41f2dfca0021084109210941002102024020032902f402420020011b221c422088a7220d41014b0d00200d0e020503050b200d210103402001410176220720026a220a2002200b200a4105746a20034188016a412010a0084101481b2102200120076b220141014b0d000c030b0b410221020b41c59cc800210841092109410321070c050b0240200b20024105746a20034188016a412010a0080d0041ce9cc8002108410d2109410221070c020b410121074100210202400240200d41014b0d00200d0e020301030b0340200d410176220120026a220a2002200b200a4105746a200341b0016a412010a0084101481b2102200d20016b220d41014b0d000b0b200b20024105746a200341b0016a412010a0080d01200341f0026a200341b0016a10d006200341186a20032802f002220120032802f80241b0b4cc0041004100108a0220032802182102024020032802f402450d00200110350b024020024101470d0041859cc8002108410f2109410821070c020b200341f0026a200341b0016a10d00620033502f802211d20032802f0022101410110332202450d00200241003a0000201d4220862001ad842002ad42808080801084100220021035024020032802f402450d00200110350b200320063702cc022003200c3602c802200341a0036a201937030020034189036a2202200341b0016a41186a220129030037000020034181036a2207200341b0016a41106a2208290300370000200341f9026a2209200341b0016a41086a220a2903003700002003201a37039803200320032903b0013700f102200341013a00f002200341c8026a20034188016a20052004200341f0026a10d606200341c8036a2004370300200341c0036a2005370300200341f0026a41086a41023a00002009200329038801370000200720034188016a41086a290300370000200220034188016a41106a29030037000020034191036a20034188016a41186a29030037000020034199036a20032903b001370000200341a1036a200a290300370000200341a9036a2008290300370000200341b1036a2001290300370000200341123a00f00241b0b4cc004100200341f0026a10d4010240201c42ffffff3f83500d00200b10350b0240201ba72202450d00200241e8006c450d00200e10350b420021060c050b103c000b201c42ffffff3f83500d00200b10350b201ba72202450d00200241e8006c450d00200e10350b02402006a72202450d00200241e8006c450d00200c10350b410321020b200041206a20093602002000411c6a2008360200200041186a200741107420027241803272360200420121060b200042003703080c050b410221070240024020022d00000d0020022d00014101470d002002411a6a2901002106200241196a2d00002108200241186a2d0000210a200241166a2f0100210b200241156a2d0000210c200241146a2d0000210d200241126a2f0100210e200241116a2d0000210f200241106a2d000021102002410e6a2f010021112002410d6a2d000021122002410c6a2d000021132002410a6a2f01002114200241096a2d00002115200241086a2d00002116200241066a2f01002117200241056a2d00002118200241046a2d00002121200241026a2f010021222003200141046a28020022093602a002200341f0026a41186a4200370300200341f0026a41106a22234200370300200341f0026a41086a22014200370300200342003703f00241a29bc800ad4280808080f0008422041001220229000021052001200241086a290000370300200320053703f00220021035419cbac800ad4280808080c000842205100122072900002119200341e8006a41086a2202200741086a2900003703002003201937036820071035202320032903682219370300200341c8026a41086a22232001290300370300200341c8026a41106a22242019370300200341c8026a41186a22252002290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f002210120032902f4022119200341a4016a2006370200200341a3016a20083a0000200341a2016a200a3a000020034188016a41186a200b3b01002003419f016a200c3a00002003419e016a200d3a00002003419c016a200e3b01002003419b016a200f3a00002003419a016a20103a000020034188016a41106a20113b010020034197016a20123a000020034196016a20133a000020034194016a20143b010020034193016a20153a000020034192016a20163a000020034188016a41086a20173b0100200320183a008f01200320213a008e01200320223b018c012001410820011b21082003200341a0026a360288014183322107024020092019420020011b2206422088a7220a4f0d0002402008200941e8006c6a220141c8006a220c20034188016a410472220b460d00200c200b412010a0080d010b20012d00002107200320012800013602682003200141046a28000036006b200141106a2903002119200141086a290300211a200341b0016a200141186a41d000109d081a2001200141e8006a2009417f73200a6a41e8006c109e081a0240024020074101470d00200341ff026a20193700002003418f036a200341b0016a41086a2d00003a00002003201a3700f7022003200328006b3600f302200320032802683602f002200320032903b00137008703200341c8026a200341f0026a10d00620033502d00242208620032802c8022201ad84100720032802cc02450d01200110350c010b2003201a370380022003201937038802201a201984500d002003200b3602b802200341c8026a200b20034180026a200341b8026a10f00220032903c8024201520d0020032903d0022119200341a8036a200341c8026a41106a290300370300200341a0036a2019370300200341f0026a41086a41003a0000200341f9026a200b29000037000020034181036a200b41086a29000037000020034189036a200b41106a29000037000020034191036a200b41186a290000370000200341033a00f00241b0b4cc004100200341f0026a10d4010b20064280808080707c2106200341f8026a41043a0000200341f9026a200329028c0137000020034181036a20034194016a29020037000020034189036a2003419c016a29020037000020034191036a200341a4016a290200370000200341123a00f00241b0b4cc004100200341f0026a10d40141843221070b200341e8006a41186a4200370300200341e8006a41106a220a42003703002002420037030020034200370368200410012209290000210420034180026a41086a2201200941086a29000037030020032004370380022009103520022001290300370300200320032903800237036820051001220929000021042001200941086a290000370300200320043703800220091035200a2003290380022204370300202320022903003703002024200437030020252001290300370300200320032903683703c8020240024020080d00200341c8026aad428080808080048410070c010b200341f0026a20082006422088a710b106200341c8026aad428080808080048420033502f80242208620032802f0022202ad841002024020032802f402450d00200210350b2006a72202450d00200241e8006c450d00200810350b420021062007418432460d010b2000411c6a41db9cc800ad4280808080b00184370200200041186a200741ff017141803272360200420121060b200042003703080c040b410221070b41c59cc8002108410921094119210a4103210b0b200041206a20093602002000411c6a2008360200200041186a200c411874200b41ff017141107472200a41ff017141087472200741ff017172360200420121060b200042003703080b2000200637030020034180046a24000bbb6504147f017e037f027e230041c0046b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0a00010203040506070809000b200341e4016a4101360200200342013702d401200341e8d4ca003602d00120034104360284042003419cd5ca0036028004200320034180046a3602e001200341d0016a41b0b4cc00104c000b200141246a2802002104200341c8006a41186a200141196a290000370300200341c8006a41106a200141116a290000370300200341c8006a41086a200141096a29000037030020032001290001370348410a2105410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a29010037038001200320013a007f200320063a007e200320073b017c200320083a007b200320093a007a2003200a3b01782003200b3a00772003200c3a00762003200d3b01742003200e3a00732003200f3a0072200320103b0170200320113a006f200320123a006e200320133b016c200320143a006b200320153a006a200320163b0168200341a8046a200341e8006a109507200341d0016a20032802a804220120032802b00410d50120034180046a41086a2202200341da016a29010037030020034180046a41106a2206200341e2016a29010037030020034180046a41176a2207200341e9016a290000370000200320032901d201370380040240024020032d00d0014101470d0020032d00d1012108200341a8016a41176a2007290000370000200341a8016a41106a2006290300370300200341a8016a41086a200229030037030020032003290380043703a801024020032802ac04450d00200110350b20034191016a200341a8016a41086a29030037000020034199016a200341a8016a41106a29030037000020034188016a41186a200341bf016a290000370000200320083a008801200320032903a8013700890120034188016a200341c8006a412010a0080d01200341d0016a200441b002109d081a2003418a046a200341c8006a41086a29030037010020034192046a200341c8006a41106a2903003701002003419a046a200341c8006a41186a29030037010020034180023b0180042003200329034837018204200341a8016a200341d0016a20034180046a10ac0320032903a8014201510d030c250b20032802ac04450d00200110350b410321010b200410ba0241cdd7ca002108418034210741002102410021060c230b20032903b0014202510d21200341c8016a2802002105200341c4016a2802002108200341c0016a2802002201418080807871210220014180807c712106200141807e7121070c220b200341a8016a41186a200141196a290000370300200341a8016a41106a200141116a290000370300200341a8016a41086a200141096a290000370300200320012900013703a80120034180046a41186a200141396a29000037030020034180046a41106a200141316a29000037030020034180046a41086a200141296a2900003703002003200141216a2900003703800420022d000120022d0000410047720d08200341d0016a20034180046a10950720033502d801211720032802d0012102412010332201450d07200120032903a801370000200141186a200341a8016a41186a2204290300370000200141106a200341a8016a41106a2205290300370000200141086a200341a8016a41086a220629030037000020174220862002ad842001ad4280808080800484100220011035024020032802d401450d00200210350b200341f2016a200329038004370100200341da016a2006290300370100200341e2016a2005290300370100200341ea016a2004290300370100200341fa016a20034180046a41086a29030037010020034182026a20034180046a41106a2903003701002003418a026a20034180046a41186a29030037010020034193083b01d001200320032903a8013701d20141b0b4cc004100200341d0016a10d4010c150b200141086a2802002107200141046a28020021094102210520022d00000d1d20022d00014101470d1d2001410c6a2802002118200141106a2802002119200141026a2f0100211a200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002108200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703c001200320013a00bf01200320043a00be01200320053b01bc01200320063a00bb01200320083a00ba012003200a3b01b8012003200b3a00b7012003200c3a00b6012003200d3b01b4012003200e3a00b3012003200f3a00b201200320103b01b001200320113a00af01200320123a00ae01200320133b01ac01200320143a00ab01200320153a00aa01200320163b01a801200341d0016a200341a8016a109607200341186a20032802d001220120032802d80141b0b4cc0041004100108a0220032802182102024020032802d401450d00200110350b4101210141032105411a2106024020024101470d0041fdd6ca00210441122102410621010c1f0b0240201a0d0041c0d7ca002104410d21020c1f0b41b0d7ca0021044110210241022101024020180d000c1f0b02402018201a4f0d000c1f0b410321050240201841094d0d0041a6d7ca002104410a2102410321010c1f0b201841016a210a2009210802400340200a417f6a220a4102490d012008200841206a220b412010a008210c419dd7ca0021044109210241042101200b2108200c4100480d000b0c1f0b200341086a2018ad42004280c0f4c198af0b420010840820032003290308221b4280808d93f5d7f1007c2217370388012003200341086a41086a2903002017201b54ad7c221b370390012003200341a8016a3602482003200341a8016a3602682003200341e8006a3602d8012003200341c8006a3602d401200320034188016a3602d00120034180046a200341a8016a200341d0016a108c03024002402003280280044101470d002003418c046a280200210220034180046a41086a280200210420032d008704210820032d008604210120032d008504210620032d00840421050c010b41042105024020034180046a41086a2903004201520d0020034180046a41106a290300211c2003280268210120034188026a20034180046a41186a29030037030020034180026a201c370300200341d0016a41086a41003a0000200341d9016a2001290000370000200341e1016a200141086a290000370000200341e9016a200141106a290000370000200341f1016a200141186a290000370000200341033a00d00141b0b4cc004100200341d0016a10d4010b0b200541ff01714104470d1e20034180046a200341a8016a109607200335028804211c200328028004210e200341003602d801200342013703d001410410332201450d1c200341043602d401200320013602d00120012019360000200341043602d80120014104411410372201450d1c200120173700042001410c6a201b370000200320013602d00120034294808080c0023702d4012018200341d0016a10772018410574210c410020032802d801220b6b210d20032802d401210541002106410021010340200b20016a210802400240200d20056a20066a4120490d0020032802d00121022005210a0c010b200841206a22022008490d0b200541017422042002200420024b1b220a4100480d0b0240024020050d000240200a0d00410121020c020b200a103322020d010c200b20032802d00121022005200a460d0020022005200a10372202450d1f0b2003200a3602d401200320023602d001200a21050b2002200b6a20016a2202200920016a2204290000370000200241186a200441186a290000370000200241106a200441106a290000370000200241086a200441086a2900003700002003200841206a3602d801200641606a2106200c200141206a2201470d000b200b20016a210502400240200a200b6b20016b4102490d0020032802d0012102200a21040c010b200541026a22022005490d0a200a41017422042002200420024b1b22044100480d0a02400240200a0d00024020040d00410121020c020b200410332202450d1f0c010b20032802d0012102200a2004460d002002200a200410372202450d1e0b200320043602d401200320023602d0010b2002200b6a20016a201a3b0000201c422086200ead84200541026aad4220862002ad84100202402004450d00200210350b0240200328028404450d00200e10350b0240200741ffffff3f71450d00200910350b200341da016a200341b0016a290300370100200341e2016a200341b8016a290300370100200341ea016a200341c0016a290300370100200341133b01d001200320032903a8013701d20141b0b4cc004100200341d0016a10d4010c140b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a29000037030020032001290001370388014102210120022d00000d1920022d00014101470d19200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703c001200320013a00bf01200320043a00be01200320053b01bc01200320063a00bb01200320073a00ba01200320083b01b801200320093a00b7012003200a3a00b6012003200b3b01b4012003200c3a00b3012003200d3a00b2012003200e3b01b0012003200f3a00af01200320103a00ae01200320113b01ac01200320123a00ab01200320133a00aa01200320143b01a801200341d0016a20034188016a109607200341306a20032802d001220120032802d80141b0b4cc0041004100108a0220032802302105024020032802d401450d00200110350b410e210441032101411a2102024020054101460d00418fd7ca002107410521060c1b0b200341d0016a20034188016a200341a8016a109707200341286a20032802d001220620032802d80141b0b4cc0041004100108a0220032802282105024020032802d401450d00200610350b024020054101470d0041efd6ca002107410721060c1b0b2003420037037020034280808d93f5d7f1003703682003200341a8016a3602a8042003200341a8016a3602482003200341c8006a3602d8012003200341a8046a3602d4012003200341e8006a3602d00120034180046a200341a8016a200341d0016a108c03024002402003280280044101470d002003418c046a280200210420034188046a280200210720032d008704210520032d008604210620032d008504210220032d00840421010c010b41042101024020034180046a41086a2903004201520d0020034180046a41106a29030021172003280248210220034188026a20034180046a41186a29030037030020034180026a2017370300200341d0016a41086a41003a0000200341d9016a2002290000370000200341e1016a200241086a290000370000200341e9016a200241106a290000370000200341f1016a200241186a290000370000200341033a00d00141b0b4cc004100200341d0016a10d4010b0b200141ff01714104470d1a42002117200341d0016a41186a4200370300200341d0016a41106a22044200370300200341d0016a41086a22014200370300200342003703d00141d1c4c700ad4280808080e0008410012202290000211b2001200241086a2900003703002003201b3703d0012002103541e7c4c700ad4280808080e0008410012202290000211b200341e8006a41086a2205200241086a2900003703002003201b3703682002103520042003290368221b37030020034180046a41086a200129030037030020034180046a41106a201b37030020034180046a41186a2005290300370300200320032903d00137038004200341206a20034180046a412010c0012003280224210120032802202102200341ec016a4100360200200342003703d80120034280808d93f5d7f1003703d001200342013702e40120032001410020021b3602e00120034180046a20034188016a200341a8016a1097072003280280042101200320032802880436026c20032001360268200341d0016a200341e8006a1094070240200328028404450d00200110350b200341da016a20034188016a41086a290300370100200341e2016a20034188016a41106a290300370100200341ea016a20034188016a41186a290300370100200341f2016a20032903a801370100200341fa016a200341a8016a41086a29030037010020034182026a200341a8016a41106a2903003701002003418a026a200341a8016a41186a29030037010020034193023b01d00120032003290388013701d20141b0b4cc004100200341d0016a10d4010c140b200341e8006a41186a200141196a290000370300200341e8006a41106a200141116a290000370300200341e8006a41086a200141096a2900003703002003200129000137036820034188016a41186a200141396a29000037030020034188016a41106a200141316a29000037030020034188016a41086a200141296a2900003703002003200141216a290000370388014102210120022d00000d1620022d00014101470d16200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703c001200320013a00bf01200320043a00be01200320053b01bc01200320063a00bb01200320073a00ba01200320083b01b801200320093a00b7012003200a3a00b6012003200b3b01b4012003200c3a00b3012003200d3a00b2012003200e3b01b0012003200f3a00af01200320103a00ae01200320113b01ac01200320123a00ab01200320133a00aa01200320143b01a80120034180046a200341e8006a109607200341d0016a200328028004220420032802880410e20220032802840421020240024020032802e4012207450d00200341ec016a280200210120032802e801210902402002450d00200410350b200341c8006a200341e8006a20034188016a109707200341d0016a20032802482202200328025010d00241082104200341d0016a41086a290300211b20032903d001211c20032903e801211720032802e401210820032802e00121050240200328024c450d00200210350b20080d0141e5d6ca002106410a21050c170b02402002450d00200410350b418fd7ca002106410e210541032101410521040c180b20034198046a20173703002003201c37038004200320083602940420032005360290042003201b370388042017a7210a41dcd6ca0021064100210202400240200141014b0d00410921044109210520010e021101110b03402001410176220420026a22052002200720054105746a200341a8016a412010a0084101481b2102200120046b220141014b0d000b0b4109210441092105200720024105746a200341a8016a412010a0080d0f4100210102402017422088a7220641014b0d00024020060e020010000b200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d00141002104200341d0016a21020c120b2006210203402002410176220420016a22052001200820054105746a200341a8016a412010a0084101481b2101200220046b220241014b0d000c0f0b0b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a2900003703002003200129000137038801410e210441052105410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703c001200320013a00bf01200320063a00be01200320073b01bc01200320083a00bb01200320093a00ba012003200a3b01b8012003200b3a00b7012003200c3a00b6012003200d3b01b4012003200e3a00b3012003200f3a00b201200320103b01b001200320113a00af01200320123a00ae01200320133b01ac01200320143a00ab01200320153a00aa01200320163b01a80120034180046a20034188016a109607200341d0016a200328028004220220032802880410e2022003280284042101024020032802e4012206450d00200341f0016a2f0100210920032802e801210720032802e001210802402001450d00200210350b20034180046a20034188016a200341a8016a109707200341d0016a200328028004220220032802880410d00220032903e801211720032802e401210120032802e00121050240200328028404450d00200210350b20010d0241e5d6ca002102410a2104410821050c0e0b02402001450d00200210350b410321010b418fd7ca0021020c0d0b200341d0016a200341a8016a109507200341c0006a20032802d001220420032802d80141b0b4cc0041004100108a0220032802402102024020032802d401450d00200410350b024020024101470d00419bd6ca002102410c2104410f21050c0b0b200341d0016a41186a4200370300200341d0016a41106a220b420037030041082104200341d0016a41086a22024200370300200342003703d00141d1c4c700ad4280808080e000841001220a290000211b2002200a41086a2900003703002003201b3703d001200a103541e7c4c700ad4280808080e000841001220a290000211b200341e8006a41086a220c200a41086a2900003703002003201b370368200a1035200b2003290368221b37030020034180046a41086a200229030037030020034180046a41106a201b37030020034180046a41186a200c290300370300200320032903d00137038004200341386a20034180046a412010c0010240200520086a220220054f0d0041a7d6ca002102410e21050c0b0b02402002200328023c410020032802381b4d0d0041d1d6ca002102410b2104410a21050c0b0b02402017422088a720094f0d0041bad6ca00210241092104410c21050c0b0b200341d0016a200341a8016a10950720033502d801211b20032802d0012104412010332202450d032002200329038801370000200241186a20034188016a41186a2205290300370000200241106a20034188016a41106a2208290300370000200241086a20034188016a41086a2209290300370000201b4220862004ad842002ad4280808080800484100220021035024020032802d401450d00200410350b200341a8016a108d02200341da016a2009290300370100200341e2016a2008290300370100200341ea016a2005290300370100200341f2016a20032903a801370100200341fa016a200341a8016a41086a29030037010020034182026a200341a8016a41106a2903003701002003418a026a200341a8016a41186a29030037010020034193083b01d00120032003290388013701d20141b0b4cc004100200341d0016a10d4010240201742ffffff3f83500d00200110350b200741ffffff3f71450d11200610350c110b200341a8016a41186a200141196a290000370300200341a8016a41106a200141116a290000370300200341a8016a41086a200141096a290000370300200320012900013703a8014182b4202101024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a29010037039804200320013a009704200320043a009604200320053b019404200320063a009304200320073a009204200320083b019004200320093a008f042003200a3a008e042003200b3b018c042003200c3a008b042003200d3a008a042003200e3b0188042003200f3a008704200320103a008604200320113b018404200320123a008304200320133a008204200320143b01800420034188016a20034180046a200341a8016a109707200341d0016a2003280288012201200328029001220210d002024020032802e4012204450d002002ad4220862001ad841007200341d0016a41086a290300211720032903d001211b20032903e801211c0240200328028c01450d00200110350b200341d0016a200341a8016a20034180046a201b2017410010ef02200341da016a20034180046a41086a290300370100200341e2016a20034180046a41106a290300370100200341ea016a20034180046a41186a290300370100200341f2016a20032903a801370100200341fa016a200341a8016a41086a29030037010020034182026a200341a8016a41106a2903003701002003418a026a200341a8016a41186a29030037010020034193063b01d00120032003290380043701d20141b0b4cc004100200341d0016a10d401201c42ffffff3f83500d12200410350c120b0240200328028c01450d00200110350b4183b42021010b200041206a410a3602002000411c6a41e5d6ca00360200200041186a200136020020004200370308420121170c1d0b4102210120022d00000d0520022d00014101470d05200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703c001200320013a00bf01200320043a00be01200320053b01bc01200320063a00bb01200320073a00ba01200320083b01b801200320093a00b7012003200a3a00b6012003200b3b01b4012003200c3a00b3012003200d3a00b2012003200e3b01b0012003200f3a00af01200320103a00ae01200320113b01ac01200320123a00ab01200320133a00aa01200320143b01a80141f8a2cb00ad428080808080018410012201290000211720034180046a41086a200141086a29000037030020032017370380042001103541e8a5cb00ad428080808080028410012201280004210820012800002109200341ac046a2001410e6a2f00003b01002003200128000a3602a80420012f0008210a20011035412010332201450d01200120032903a801370000200141186a200341a8016a41186a290300370000200141106a200341a8016a41106a290300370000200141086a200341a8016a41086a29030037000020032001ad42808080808004841003220229000037034820021035200341dc016a200141206a360200200320013602d8012003200341c8006a41086a3602d4012003200341c8006a3602d001200341e8006a200341d0016a107b200110352003280270220641206a2202417f4c0d03200328026821070240024020020d0041002104410121010c010b200210332201450d02200221040b024002402004410f4d0d00200421050c010b200441017422054110200541104b1b22054100480d05024020040d00200510332201450d190c010b20042005460d0020012004200510372201450d180b2001200329038004370000200141086a20034180046a41086a2903003700000240024020054170714110460d00200521040c010b200541017422044120200441204b1b22044100480d0520052004460d0020012005200410372201450d180b2001200a3b00182001200836001420012009360010200120032802a80436001a2001411e6a200341ac046a2f01003b000002400240200441606a2006490d00200421050c010b2006415f4b0d05200441017422052002200520024b1b22054100480d0520042005460d0020012004200510372201450d180b200141206a20072006109d081a0240200328026c450d00200710350b0240024020020d0041002104410121070c010b200210332207450d02200221040b0240024020042002490d00200421060c010b200441017422062002200620024b1b22064100480d05024020040d00200610332207450d190c010b20042006460d0020072004200610372207450d180b200720012002109d0821042003419c016a200236020020034198016a2005360200200320013602940120032002360290012003200636028c012003200436028801200341d0016a2002ad4220862001ad84102710c20102400240024020032802d0012201450d0020032802d401210202400240200341d8016a28020022042003280290012205490d0020032802880122062001460d0120062001200510a008450d010b2002450d01200110350c010b20034194016a2105200320043602b004200320023602ac04200320013602a804200341d0016a2001200410d002024020032802e40122010d002003410036025020034201370348200341f4006a4135360200200320053602b4042003413536026c2003200341b8046a3602702003200341b4046a3602682003200341a8046a3602b8042003200341c8006a3602bc0420034194046a4102360200200342023702840420034180c9c400360280042003200341e8006a36029004200341bc046a41e88ac50020034180046a10431a20033502504220862003350248841006200328024c450d00200328024810350b20034180046a41086a2202200341a8046a41086a280200360200200320032903a804370380040240200328029801450d0020032802940110350b2005200329038004370200200541086a200228020036020020010d010b20034180046a200341a8016a109607200341d0016a2003280280042202200328028804220410e202024020032802e4012201450d002004ad4220862002ad8410070b200328028404210402402001450d00200341d8016a290300211720032903d001211b20032802e801210502402004450d00200210350b2003201b370368200320173703700240201b201784500d002003200341a8016a36024820034180046a200341a8016a200341e8006a200341c8006a10f0022003290380044201520d00200329038804211720034188026a20034180046a41106a29030037030020034180026a2017370300200341d0016a41086a41003a0000200341d9016a20032903a801370000200341e1016a200341a8016a41086a290300370000200341e9016a200341a8016a41106a290300370000200341f1016a200341c0016a290300370000200341033a00d00141b0b4cc004100200341d0016a10d4010b200341da016a200341b0016a290300370100200341e2016a200341b8016a290300370100200341ea016a200341c0016a290300370100200341930a3b01d001200320032903a8013701d20141b0b4cc004100200341d0016a10d4010240200541ffffff3f71450d00200110350b0240200328028c01450d0020032802880110350b200328029801450d1220032802940110350c120b02402004450d00200210350b418fd7ca002102410e21044180801421050c010b41afd6ca002102410b210441808034210520032802e80141ffffff3f71450d00200110350b0240200328028c01450d0020032802880110350b0240200328029801450d0020032802940110350b410321010c070b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a2900003703002003200129000137038801418234210120022d00000d0520022d00014101470d05200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703c001200320013a00bf01200320043a00be01200320053b01bc01200320063a00bb01200320073a00ba01200320083b01b801200320093a00b7012003200a3a00b6012003200b3b01b4012003200c3a00b3012003200d3a00b2012003200e3b01b0012003200f3a00af01200320103a00ae01200320113b01ac01200320123a00ab01200320133a00aa01200320143b01a801200341e8006a200341a8016a109507200341d0016a20032802682202200328027010d5010240024020032d00d0014101460d0041002101200341003a0080040c010b20034180046a41196a200341d0016a41196a29000037000020034180046a41096a200341d0016a41096a29000037000020034180046a41116a200341d0016a41116a29000037000041012101200341013a008004200320032900d101370081040b0240200328026c450d00200210350b200341e9016a200341a0016a290300370000200341e1016a20034198016a290300370000200341d9016a20034190016a29030037000020032003290388013700d101200341013a00d001024020010d0041833421010c060b418334210120034180046a410172200341d0016a410172412010a0080d05200341d0016a200341a8016a10950720033502d80142208620032802d0012201ad841007024020032802d401450d00200110350b200341a8016a1099020c0e0b1045000b200041186a410236020020004200370308420121170c190b1044000b103e000b410021050c010b200041206a410a3602002000411c6a41cdd7ca00360200200041186a200136020020004200370308420121170c150b20004200370308200041206a20043602002000411c6a2002360200200041186a20054180803c7120017241803472360200420121170c140b201742ffffff3f83500d00200110350b0240200741ffffff3f71450d00200610350b410321010b20004200370308200041206a20043602002000411c6a2002360200200041186a200541107420017241803472360200420121170c110b200820014105746a200341a8016a412010a00822040d0141c3d6ca002106410e2105410b21040b200a41ffffff3f71450d05200810350c050b200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d001200341d0016a21022004411f7620016a220420064b0d030b02402006200a470d0020034194046a20064101108a0120032802940421080b200820044105746a220141206a2001200620046b410574109e081a200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200120022900003700002003200641016a36029c04200341d0016a41186a220220034180046a41186a290300370300200341d0016a41106a20034180046a41106a290300370300200341d0016a41086a20034180046a41086a29030037030020032003290380043703d001200341c8006a200341e8006a20034188016a10970720032802482101200320032802503602ac04200320013602a804200341d0016a200341a8046a1094070240200328024c450d00200110350b0240200228020041ffffff3f71450d0020032802e40110350b200341f2016a200329038801370100200341da016a200341e8006a41086a290300370100200341e2016a200341e8006a41106a290300370100200341ea016a200341e8006a41186a290300370100200341fa016a20034188016a41086a29030037010020034182026a20034188016a41106a2903003701002003418a026a20034188016a41186a29030037010020034193043b01d001200320032903683701d201200341aa026a200341a8016a41186a290300370100200341a2026a200341a8016a41106a2903003701002003419a026a200341a8016a41086a29030037010020034192026a20032903a80137010041b0b4cc004100200341d0016a10d401200941ffffff3f71450d00200710350b420021170b200020173703080c0b0b20042006104d000b41032101200941ffffff3f71450d01200710350c010b0b200041206a20053602002000411c6a200636020020004200370308200041186a200441ff017141107420017241803472360200420121170c070b0b200041206a20043602002000411c6a200736020020004200370308200041186a2005411874200641ff017141107472200241ff017141087472200141ff017172360200420121170c050b103c000b0b0240200741ffffff3f71450d00200910350b20004200370308200041206a20023602002000411c6a2004360200200041186a2008411874200141ff017141107472200641ff017141087472200541ff017172360200420121170c020b410421014100210241002106410021070b20041035420021170240200141ff017122014104460d00200041206a20053602002000411c6a2008360200200041186a20022006418080fc07717220074180fe037172200172360200420121170b200042003703080b20002017370300200341c0046a24000bb50404057f017e017f017e0240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602000240200441037122064103460d00024002400240024020060e03000102000b2004410276ad21070c020b41012106024020050d000c050b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d04200141fcff0371410276ad21070c010b410121060240200541034f0d000c040b200341036a2d0000210520032f0001210820012002417c6a3602042001200341046a3602002008200541107472410874200472220141808004490d032001410276ad21070b410021060c020b02402004410276220841044b0d000240024020080e050002020201000b20054104490d022003350001210720012002417b6a3602042001200341056a36020020074280808080045421060c030b20054108490d01200329000121072001200241776a3602042001200341096a3602002007428080808080808080015421060c020b200841046a220541084b0d002002417e6a2102200341026a2103410021044200210741012106034002402002417f470d000c030b2003417f6a310000210920012002360204200120033602002002417f6a2102200341016a210320092004410374413871ad862007842107200441016a220441ff01712005490d000b2007427f412820084103746b413871ad885821060c010b410121060b2000200737030820002006ad3703000bf30601067f230041f0006b2102024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a2206360204410121072001200441016a360200200541f001490d06200541847e6a220541034b0d0120050e0402030405020b200041023a00000f0b200041023a00000f0b20064102490d0420042f0001210520012003417d6a3602042001200441036a3602000240200541ef014d0d00410121070c040b200041023a00000f0b20064104490d042004280001210520012003417b6a3602042001200441056a36020041012107200541ffff034b0d02200041023a00000f0b024020064104490d00200041023a000020012003417b6a3602042001200441056a3602000f0b200041023a00000f0b41002105200241003a00682003417f6a21062003417e6a210302400240034020062005460d01200241c8006a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00682003417f6a21032007210520074120470d000b200241c6006a20022d004a3a0000200241306a200241d7006a290000370300200241386a200241df006a290000370300200241c0006a200241e7006a2d00003a0000200220022f01483b01442002200229004f370328200228004b2105410021010c010b0240200541ff0171450d00200241003a00680b410121010b200241246a41026a2203200241c4006a41026a2d00003a0000200241086a41086a2207200241286a41086a290300370300200241086a41106a2204200241286a41106a290300370300200241086a41186a2206200241286a41186a2d00003a0000200220022f01443b01242002200229032837030820010d03200241286a41026a20032d00003a0000200241c8006a41086a2007290300370300200241c8006a41106a2004290300370300200241c8006a41186a20062d00003a0000200220022f01243b012820022002290308370348410021070b200020073a0000200020022f01283b0001200041046a2005360200200041086a2002290348370200200041036a2002412a6a2d00003a0000200041106a200241c8006a41086a290300370200200041186a200241c8006a41106a290300370200200041206a200241c8006a41186a2802003602000f0b200041023a00000f0b200041023a00000f0b200041023a00000b9f1002097f047e230041d0056b220224000240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541044b0d0620050e050102030405010b200041063a00000c090b200241a0036a200110c301024020022802a0032206450d0020022802a4032107024020012802042203450d00200241a8036a2802002108200128020022042d0000210520012003417f6a3602042001200441016a360200200541014b0d004100210902400240024020050e020100010b41002105200241003a00c0032003417f6a210a2003417e6a21030340200a2005460d02200241a0036a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00c0032003417f6a21032009210520094120470d000b200241f0006a41186a200241a0036a41186a290300370300200241f0006a41106a200241a0036a41106a290300370300200241f0006a41086a200241a0036a41086a290300370300200220022903a003370370410121090b200241206a41186a200241f0006a41186a290300220b370300200241206a41106a200241f0006a41106a290300220c370300200241206a41086a200241f0006a41086a290300220d37030020022002290370220e370320200020093a0001200041013a0000200041026a200e3700002000410a6a200d370000200041126a200c3700002000411a6a200b3700002000412c6a2008360100200041286a2007360100200041246a20063601000c0b0b200541ff0171450d00200241003a00c0030b200041063a0000200741ffffff3f71450d09200610350c090b200041063a00000c080b200241a0036a200110b90220022802a0032101200241f0006a200241a0036a41047241ac02109d081a024002402001411b460d00200241a0036a200241f0006a41ac02109d081a41b002103322050d010c080b200041063a00000c080b20052001360200200541046a200241a0036a41ac02109d081a200041023a0000200020022f00503b0001200041036a200241d0006a41026a2d00003a0000200041046a2005360200200041086a2002290220370200200041106a200241206a41086a290200370200200041186a200241206a41106a290200370200200041206a200241206a41186a290200370200200041286a200241206a41206a2902003702000c070b200241086a200110c401024020022802080d00200228020c2103200241a0036a200110b90220022802a0032101200241f0006a200241a0036a41047241ac02109d081a2001411b460d00200241a0036a200241f0006a41ac02109d081a41b00210332205450d0620052001360200200541046a200241a0036a41ac02109d081a200041033a0000200020022f00503b0001200041036a200241d2006a2d00003a0000200041086a2005360200200041046a20033602002000410c6a2002290220370200200041146a200241206a41086a2902003702002000411c6a200241306a290200370200200041246a200241386a2902003702002000412c6a200241c0006a2802003602000c070b200041063a00000c060b41002105200241003a00c0032003417f6a210a2003417e6a210302400240024002400340200a2005460d01200241a0036a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00c0032003417f6a21032009210520094120470d000b200241206a41086a200241a0036a41086a290300370300200241206a41106a200241a0036a41106a290300370300200241206a41186a200241a0036a41186a290300370300200220022903a003370320200241106a200110c40120022802100d0120012802042203450d0120022802142104200128020022092d0000210520012003417f6a3602042001200941016a360200200541014b0d014100210120050e020302030b200541ff0171450d00200241003a00c0030b200041063a00000c070b410121010b200241d0006a41186a200241206a41186a290300220b370300200241d0006a41106a200241206a41106a290300220c370300200241d0006a41086a200241206a41086a290300220d37030020022002290320220e370350200041043a00002000200e370001200041096a200d370000200041116a200c370000200041196a200b370000200041246a2004360200200041216a20013a00000c050b41002105200241003a00c0032003417f6a210a2003417e6a210302400340200a2005460d01200241a0036a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00c0032003417f6a21032009210520094120470d000b200241206a41086a2205200241a0036a41086a290300370300200241206a41106a2203200241a0036a41106a290300370300200241206a41186a2209200241a0036a41186a290300370300200220022903a003370320200241186a200110c4012002280218450d020c030b200541ff0171450d02200241003a00c0030c020b200041063a00000c030b200228021c2101200241d0006a41186a2009290300220b370300200241d0006a41106a2003290300220c370300200241d0006a41086a2005290300220d37030020022002290320220e370350200041053a00002000200e370001200041096a200d370000200041116a200c370000200041196a200b370000200041216a20022f004d3b0000200041236a200241cf006a2d00003a0000200041246a20013602000c020b200041063a00000c010b103c000b200241d0056a24000bc60702047f047e230041b0056b22022400024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541024b0d0320050e03010204010b200041043602000c050b20024180036a200110b9022002280280032101200241d0006a20024180036a41047241ac02109d081a024002402001411b460d0020024180036a200241d0006a41ac02109d081a41b002103322050d010c050b200041043602000c050b20052001360200200541046a20024180036a41ac02109d081a2000200536020420004101360200200041086a2002290228370200200041106a200241286a41086a290200370200200041186a200241286a41106a290200370200200041206a200241286a41186a290200370200200041286a200241286a41206a2802003602000c040b20024180036a2001109206024020022d0080034102460d00200241d0006a41206a20024180036a41206a2802002201360200200241d0006a41186a20024180036a41186a2903002206370300200241d0006a41106a20024180036a41106a2903002207370300200241d0006a41086a20024180036a41086a29030022083703002002200229038003220937035020004102360200200020093702042000410c6a2008370200200041146a20073702002000411c6a2006370200200041246a20013602000c040b200041043602000c030b200041043602000c020b20024180036a2001109206024020022d0080034102470d00200041043602000c020b200241286a41206a20024180036a41206a280200360200200241286a41186a20024180036a41186a290300370300200241286a41106a20024180036a41106a290300370300200241286a41086a20024180036a41086a290300370300200220022903800337032820024180036a200110b9022002280280032101200241d0006a20024180036a41047241ac02109d081a02402001411b460d0020024180036a200241d0006a41ac02109d081a41b00210332205450d0120052001360200200541046a20024180036a41ac02109d081a200241206a200241286a41206a2802002201360200200241186a200241286a41186a2903002206370300200241106a200241286a41106a2903002207370300200241086a200241286a41086a290300220837030020022002290328220937030020004103360200200020093702042000410c6a2008370200200041146a20073702002000411c6a2006370200200041246a2001360200200041286a20053602000c020b200041043602000c010b103c000b200241b0056a24000bbc1e03077f047e017f230041e0056b2202240002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541084b0d0a20050e09010203040506070809010b2000410a3a00000c0a0b41002105200241003a00d0032003417f6a21062003417e6a2107024002400240034020062005460d01200241b0036a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00d0032007417f6a21072008210520084120470d000b200241c0006a41086a200241b0036a41086a290300370300200241c0006a41106a200241b0036a41106a290300370300200241c0006a41186a200241b0036a41186a290300370300200220022903b003370340200241b0036a200110b90220022802b003210120024180016a200241b0036a41047241ac02109d081a2001411b460d01200241b0036a20024180016a41ac02109d081a41b002103322040d02103c000b200541ff0171450d00200241003a00d0030b2000410a3a00000c0a0b20042001360200200441046a200241b0036a41ac02109d081a200241206a41186a200241c0006a41186a2903002209370300200241206a41106a200241c0006a41106a290300220a370300200241206a41086a200241c0006a41086a290300220b37030020022002290340220c370320200041013a00002000200c370001200041096a200b370000200041116a200a370000200041196a2009370000200041216a20022f001d3b0000200041236a2002411f6a2d00003a0000200041246a2004360200200041286a2002290200370200200041306a200241086a290200370200200041386a200241106a290200370200200041c0006a200241186a2802003602000c090b41002105200241003a00d003410120036b21062003417e6a21070240024002400340200620056a450d01200241b0036a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00d0032007417f6a21072008210520084120470d000b20024180016a41086a200241b0036a41086a29030037030020024180016a41106a200241b0036a41106a29030037030020024180016a41186a200241b0036a41186a290300370300200220022903b0033703800141002105200241003a00d003200420086a2106200820036b41016a21080340200820056a450d02200241b0036a20056a200620056a220441016a2d00003a0000200120073602042001200441026a3602002002200541016a22043a00d0032007417f6a21072004210520044120470d000b200241206a41086a2201200241b0036a41086a290300370300200241206a41106a2204200241b0036a41106a290300370300200241206a41186a2205200241b0036a41186a290300370300200241c0006a41086a220720024180016a41086a290300370300200241c0006a41106a220820024180016a41106a290300370300200241c0006a41186a220320024180016a41186a290300370300200220022903b0033703202002200229038001370340200041023a000020002002290340370001200041096a2007290300370000200041116a2008290300370000200041196a2003290300370000200041216a2002290320370000200041296a2001290300370000200041316a2004290300370000200041396a2005290300370000200041c1006a20022f00003b0000200041c3006a200241026a2d00003a00000c0b0b200541ff0171450d01200241003a00d0030c010b200541ff0171450d00200241003a00d0030b2000410a3a00000c080b20024180016a200110c3010240024002402002280280012204450d002002280284012105200128020422074102490d0120024188016a2802002106200128020022082f0000210d20012007417e6a22033602042001200841026a36020020034104490d022008280002210320012007417a6a3602042001200841066a360200200041106a20033602002000410c6a2006360200200041086a2005360200200041046a2004360200200041026a200d3b0100200041033a0000200041146a20022902b0033702002000411c6a200241b0036a41086a290200370200200041246a200241b0036a41106a2902003702002000412c6a200241c8036a290200370200200041346a200241d0036a2902003702002000413c6a200241d8036a2902003702000c0a0b2000410a3a00000c090b2000410a3a0000200541ffffff3f71450d08200410350c080b2000410a3a0000200541ffffff3f71450d07200410350c070b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041043a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c070b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c060b41002105200241003a00d003410120036b21062003417e6a21070240024002400340200620056a450d01200241b0036a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00d0032007417f6a21072008210520084120470d000b20024180016a41086a200241b0036a41086a29030037030020024180016a41106a200241b0036a41106a29030037030020024180016a41186a200241b0036a41186a290300370300200220022903b0033703800141002105200241003a00d003200420086a2106200820036b41016a21080340200820056a450d02200241b0036a20056a200620056a220441016a2d00003a0000200120073602042001200441026a3602002002200541016a22043a00d0032007417f6a21072004210520044120470d000b200241206a41086a2201200241b0036a41086a290300370300200241206a41106a2204200241b0036a41106a290300370300200241206a41186a2205200241b0036a41186a290300370300200241c0006a41086a220720024180016a41086a290300370300200241c0006a41106a220820024180016a41106a290300370300200241c0006a41186a220320024180016a41186a290300370300200220022903b0033703202002200229038001370340200041053a000020002002290340370001200041096a2007290300370000200041116a2008290300370000200041196a2003290300370000200041216a2002290320370000200041296a2001290300370000200041316a2004290300370000200041396a2005290300370000200041c1006a20022f00003b0000200041c3006a200241026a2d00003a00000c080b200541ff0171450d01200241003a00d0030c010b200541ff0171450d00200241003a00d0030b2000410a3a00000c050b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041063a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c050b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c040b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041073a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c040b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c030b200041083a00000c020b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041093a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c020b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c010b2000410a3a00000b200241e0056a24000bab0301087f230041206b220324000240024002400240200141246c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b2003410036020820032005360200200320043602042001200310770240024020010d002003280208210420032802042106200328020021070c010b200141246c210820032802042105200328020821010340200341106a200010c0032003280210210902400240200520016b2003280218220a490d002001200a6a210420032802002107200521060c010b2001200a6a22042001490d05200541017422062004200620044b1b22064100480d050240024020050d00024020060d00410121070c020b2006103322070d010c080b2003280200210720052006460d0020072005200610372207450d070b20032006360204200320073602000b200720016a2009200a109d081a2003200436020802402003280214450d00200910350b200041246a210020062105200421012008415c6a22080d000b0b20022902002004ad4220862007ad84100202402006450d00200710350b200341206a24000f0b1044000b1045000b103e000b103c000bd20301037f0240024020002d0000220141144b0d00024002400240024002400240024020010e15080808080808000808010802080308040508060808080b200041086a2d00004101470d07200041146a28020041ffffff3f71450d07200041106a28020010350f0b200041046a2d00000d062000410c6a2802002201450d06200141306c450d06200041086a28020010350f0b200041046a2802000d052000410c6a2802002201450d05200141286c450d05200041086a28020010350f0b200041086a2d00004107470d04200041306a280200450d042000412c6a28020010350f0b200041046a2d00004102490d030240200041106a2802002201450d00200141d0006c2102200041086a28020041c4006a21010340024020012802002203450d00200341306c450d002001417c6a28020010350b200141d0006a2101200241b07f6a22020d000b0b2000410c6a2802002201450d03200141d0006c450d03200028020810350f0b200041086a280200450d02200041046a28020010350f0b200041086a2d00004106470d01200041306a28020041ffffff3f71450d012000412c6a28020010350c010b200041046a280200450d00200041106a2802002201450d00200041146a280200450d00200110350f0b0b13002000410a360204200041e0cfc7003602000b3400200041d1c4c70036020420004100360200200041146a410f360200200041106a4184e3c700360200200041086a42063702000b2b01017f02404101103322020d001045000b200042818080801037020420002002360200200241003a00000be00101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002400240412010332206450d0020062002290300370000200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000412010332203450d0120032006290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a29000037000020061035200042a0808080800437020420002003360200200241206a24000f0b1045000b103c000bae0101017f0240410410332202450d002002410036000020024104410810372202450d00200241003a000420024108411510372202450d00200242003700052002410d6a420037000020024115412a10372202450d00200242003700152002411d6a42003700002002412a41d40010372202450d002002420037003520024200370025200042d4808080d008370204200020023602002002413d6a42003700002002412d6a42003700000f0b103c000b13002000410536020420004184fdc7003602000b2f01017f02404104103322020d001045000b20004284808080c000370204200020023602002002418080c0023600000b2f01017f02404108103322020d001045000b20004288808080800137020420002002360200200242c0b2cd3b3700000b3001017f02404108103322020d001045000b2000428880808080013702042000200236020020024280e497d0123700000b4801017f0240410810332202450d00200242c0f0f50b37000020024108411010372202450d002000429080808080023702042000200236020020024280c2d72f3700080f0b103c000b3101017f02404108103322020d001045000b2000428880808080013702042000200236020020024280c0a8ca9a3a3700000b861603027f017e0a7f230041b0016b2203240041f1d8cb00ad4280808080900184100122042900002105200341c8006a41086a200441086a290000370300200320053703482004103541a0e0c600ad4280808080b00184100122042900002105200341e8006a41086a200441086a29000037030020032005370368200410350240024002400240024002400240412010332204450d0020042001290000370000200441186a2206200141186a290000370000200441106a2207200141106a290000370000200441086a200141086a290000370000412010332208450d0020082004290000370000200841186a2006290000370000200841106a2007290000370000200841086a2206200441086a2900003700002004103541c00010332204450d002004200329036837001020042003290348370000200441086a200341c8006a41086a290300370000200441186a200341e8006a41086a29030037000020042008290000370020200441286a2006290000370000200441306a200841106a290000370000200441386a200841186a29000037000020081035200341c000360294012003200436029001200341206a2004ad4280808080800884100510c20102400240200328022022070d00410221080c010b200328022421092003200341286a28020036029c012003200736029801200341186a20034198016a10c40102400240024020032802180d00200328021c2106200341106a20034198016a10c40120032802100d002003280214210a200341086a20034198016a10c40120032802080d00200328029c012208450d00200328020c210b20032008417f6a36029c012003200328029801220841016a3602980120082d0000220c41014b0d004100210802400240200c0e020100010b410121080b200320034198016a10c40120032802000d00200328029c01220d2003280204220e490d00200e417f4c0d0502400240200e0d004100210d4101210c0c010b200e1039220c450d05200c200328029801220f200e109d081a2003200d200e6b36029c012003200f200e6a36029801200e210d0b200c0d010b2003410036025020034201370348200341093602a401200320034190016a3602a0012003200341c8006a3602ac01200341fc006a41013602002003420137026c200341c888c2003602682003200341a0016a360278200341ac016a41e88ac500200341e8006a10431a200335025042208620033502488410060240200328024c450d00200328024810350b410221080c010b200ead422086200dad8421052003418c016a41026a200341e8006a41026a2d00003a0000200320032f00683b018c010b2009450d00200710350b200341e8006a41026a2003418c016a41026a2d00003a0000200320032f018c013b01680240024020084102460d00200341c4006a41026a2207200341e8006a41026a2d00003a0000200320032f01683b014420041035200341c0006a41026a20072d000022043a0000200341306a220920053703002003413b6a20043a0000200320032f014422043b0140200320083a00382003200c36022c2003200b3602282003200a360224200320043b003920032006360220200341206a41086a2107200228027020064b0d010c070b20041035200041086a4111360200200041ef84c800360204200041013602000c070b41f1d8cb00ad4280808080900184100122042900002105200341c8006a41086a200441086a29000037030020032005370348200410354194e0c600ad4280808080c00184100122042900002105200341e8006a41086a200441086a2900003703002003200537036820041035412010332204450d0020042001290000370000200441186a2206200141186a290000370000200441106a220a200141106a290000370000200441086a220b200141086a290000370000412010332208450d0020082004290000370000200841186a2006290000370000200841106a200a290000370000200841086a200b2900003700002004103541c00010332204450d002004200329036837001020042003290348370000200441086a200341c8006a41086a290300370000200441186a200341e8006a41086a29030037000020042008290000370020200441286a200841086a290000370000200441306a200841106a290000370000200441386a200841186a29000037000020081035200341e8006a200441c00010e002200329026c2105200328026821062004103502400240024002402006450d00200341e8006a20062005422088a72002108c062005a7210220032802684101460d03200341c8006a41186a220a200341e8006a410472220441186a280200360200200341c8006a41106a220b200441106a290200370300200341c8006a41086a2208200441086a2902003703002003200429020037034802402003280230450d00200328022c10350b200341206a41186a200a280200360200200341206a41106a200b290300370300200341206a41086a20082903003703002003200329034837032041f1d8cb00ad42808080809001841001220429000021052008200441086a290000370300200320053703482004103541a0e0c600ad4280808080b00184100122042900002105200341e8006a41086a200441086a2900003703002003200537036820041035412010332204450d0420042001290000370000200441186a220a200141186a290000370000200441106a220b200141106a290000370000200441086a220c200141086a290000370000412010332208450d0420082004290000370000200841186a200a290000370000200841106a200b290000370000200841086a200c2900003700002004103541c00010332204450d042004200329036837001020042003290348370000200441086a200341c8006a41086a290300370000200441186a200341e8006a41086a29030037000020042008290000370020200441286a200841086a290000370000200441306a200841106a290000370000200441386a200841186a290000370000200810352003410036027020034201370368200341206a200341e8006a10e201200341206a410472200341e8006a10e2012007200341e8006a10e20120032d0038210a200328026c20032802702208460d01200328026821010c020b2000418085c80036020420004101360200200041086a411a3602000c070b200841016a22012008490d042008410174220b2001200b20014b1b220b4100480d040240024020080d00410021080240200b0d00410121010c020b200b103322010d010c070b200328026821012008200b460d0020012008200b10372201450d060b2003200b36026c200320013602680b200120086a200a3a00002003200841016a360270200328022c210e200341346a2802002208200341e8006a107702400240200328026c220c2003280270220a6b2008490d0020032802682101200c210b0c010b200a20086a2201200a490d04200c410174220b2001200b20014b1b220b4100480d0402400240200c0d000240200b0d00410121010c020b200b10332201450d070c010b20032802682101200c200b460d002001200c200b10372201450d060b2003200b36026c200320013602680b2001200a6a200e2008109d081a2004ad4280808080800884200a20086aad4220862001ad8410020240200b450d00200110350b200410352002450d06200610350c060b2000200329026c370204200041013602002002450d04200610350c040b1045000b1044000b103e000b103c000b2003280230450d01200328022c10350c010b20002003290320370204200041003602002000411c6a200341386a280200360200200041146a20092903003702002000410c6a20072903003702000b200341b0016a24000bc00202027f017e230041106b220224002002200028023036020020012002410410780240412010332203450d0020032000290038370000200341186a200041d0006a290000370000200341106a200041c8006a290000370000200341086a200041c0006a290000370000200120034120107820031035024020002d0058220341024b0d00024002400240024020030e03000102000b200241003a00000c020b200241013a00000c010b200241023a00000b20012002410110780b200220002802343602002001200241041078200029030021042002200041086a290300370308200220043703002001200241101078200029031021042002200041186a290300370308200220043703002001200241101078200029032021042002200041286a290300370308200220043703002001200241101078200241106a24000f0b1045000b1300200041073602042000419c85c8003602000b3400200041fb8fc80036020420004100360200200041146a4102360200200041106a419090c800360200200041086a42133702000bcb0202057f037e2001280200210202400240412010332203450d0020032002290000370000200341186a2204200241186a290000370000200341106a2205200241106a290000370000200341086a2206200241086a290000370000412010332202450d0120022003290000370000200241186a2004290000370000200241106a2005290000370000200241086a200629000037000020031035200128020421012002412041c00010372203450d0120032001290000370020200341386a200141186a290000370000200341306a200141106a290000370000200341286a200141086a2900003700002003ad4280808080800884100922022900002107200241086a2900002108200241106a2900002109200041186a200241186a290000370000200041106a2009370000200041086a20083700002000200737000020021035200310350f0b1045000b103c000ba30301067f230041106b22032400024020014105744104722204417f4c0d000240200410332205450d002003410036020820032004360204200320053602002001200310770240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020002101024002402006200522046b4120490d00200441206a21050c010b024002400240200441206a22052004490d00200641017422002005200020054b1b22004100480d000240024020060d00024020000d00410121070c020b2000103321070c040b20062000470d020b200021060c030b103e000b200720062000103721070b2000210620070d00103c000b200141206a2100200720046a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100202402006450d00200710350b200341106a24000f0b1045000b1044000b130020004105360204200041fc92c8003602000be80f06087f017e047f017e057f077e230022042105200441a0016b41607122042400024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610332207450d020b41002108200441003602282004200736022020042006410576360224200441206a41002001108a012004280228210902402001450d002001410574210a200428022020094105746a210b0340200b20086a2206200020086a2207290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200a200841206a2208470d000b200141057441606a41057620096a41016a21090b200441086a200936020020042004290320220c370300200ca72009410041202009676b10c105200441206a41186a22014200370300200441206a41106a220d4200370300200441206a41086a220e42003703002004420037032041c7d5ca00ad4280808080b0028410012208290000210c200e200841086a2900003703002004200c370320200810354180eaca00ad428080808090018410012208290000210c200441e8006a41086a220f200841086a2900003703002004200c37036820081035200d2004290368220c37030020044180016a41086a200e29030037030020044180016a41106a200c37030020044180016a41186a200f2903003703002004200429032037038001200441206a20044180016a412010b50220042802202208410120081b21102004290224420020081b2211422088a72208450d022008410574210920044180016a410c722112200441206a410c6a2100200441206a4114722113200441206a41087221142010210803402001200841186a290000370300200d200841106a290000370300200e200841086a29000037030020042008290000370320200441106a200441206a108a07200441206a2004280210220b2004280218221510de02200f200041086a290200370300200441e8006a41106a220a200041106a2802003602002004200029020037036820042802402106024020042802282207450d002004290320210c20122004290368370200201241086a200f290300370200201241106a200a2802003602002004200c37038001200621160b200420073602880120044100360228200429039801211720042004290338221837039801200429039001211920042004290330221a37039001200429038001211b20042004290320221c37038001200429038801210c20042004290328221d37038801201da7210702400240200ca7220a0d00201d210c201a211920182117201621060c010b2004201b3703202004200c37032820042019370330200420173703382004200a2019a74105746a3602742004200a3602702004200c422088a736026c2004200a36026820042004360278200441d8006a200441e8006a10ca05201441086a200441d8006a41086a22162802003602002014200429035837020020042019422088a7220a2017422088a74105746a3602742004200a36027020042017a736026c2004200a36026820042004360278200441d8006a200441e8006a10ca05201341086a2016280200360200201320042903583702002004290328210c2004290320211c200429033821172004290330211902402007450d002018a7210a0240201d422088a741ffffff3f71450d00200710350b200a41ffffff3f71450d00201a422088a710350b2004201c370380012004200c3703880120042019370390012004201737039801200ca721070b2004200c37032820042019370330200120173703002004201c37032020042006360240200ca7210a0240024020070d002015ad422086200bad8410070c010b2004201536026c2004200b360268200441206a200441e8006a108b070b0240200a450d002017a721070240200c422088a741ffffff3f71450d00200a10350b200741ffffff3f71450d002019422088a710350b02402004280214450d00200b10350b200841206a210820062116200941606a22090d000c030b0b1044000b1045000b0240201142ffffff3f83500d00201010350b200441206a41186a220a4200370300200441206a41106a22074200370300200441206a41086a220642003703002004420037032041c7d5ca00ad4280808080b00284220c10012200290000211c200441e8006a41086a2208200041086a2900003703002004201c3703682000103520062008290300370300200420042903683703204189eaca00ad4280808080f0008410012200290000211c2008200041086a2900003703002004201c3703682000103520072004290368221c37030020044180016a41086a220b200629030037030020044180016a41106a2201201c37030020044180016a41186a22092008290300370300200420042903203703800120044120360224200420044180016a36022020022003200441206a10a806200a4200370300200742003703002006420037030020044200370320200c10012200290000210c2008200041086a2900003703002004200c370368200010352006200829030037030020042004290368370320419cdfca00ad4280808080d0008410012200290000210c2008200041086a2900003703002004200c3703682000103520072004290368220c370300200b20062903003703002001200c37030020092008290300370300200420042903203703800120044180016aad428080808080048410070240200428020441ffffff3f71450d00200428020010350b200524000bec0502057f017e23004190016b2201240020002d00002102200141186a2203200041196a290000370300200141106a2204200041116a290000370300200141086a2205200041096a2900003703002001200029000137030002400240024020020d00200141f0006a41186a4200370300200141f0006a41106a22034200370300200141f0006a41086a220042003703002001420037037041c7d5ca00ad4280808080b002841001220229000021062000200241086a2900003703002001200637037020021035419cdfca00ad4280808080d00084100122022900002106200141206a41086a2204200241086a2900003703002001200637032020021035200320012903202206370300200141c0006a41086a2000290300370300200141c0006a41106a2006370300200141c0006a41186a200429030037030020012001290370370340200141c0006aad428080808080048410070c010b200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a200529030037030020012001290300370320200141f0006a41186a4200370300200141f0006a41106a22034200370300200141f0006a41086a220042003703002001420037037041c7d5ca00ad4280808080b002841001220229000021062000200241086a2900003703002001200637037020021035419cdfca00ad4280808080d00084100122022900002106200141e0006a41086a2204200241086a2900003703002001200637036020021035200320012903602206370300200141c0006a41086a2000290300370300200141c0006a41106a2006370300200141c0006a41186a200429030037030020012001290370370340412010332200450d0120002001290320370000200041186a200141206a41186a290300370000200041106a200141206a41106a290300370000200041086a200141206a41086a290300370000200141c0006aad42808080808004842000ad42808080808004841002200010350b20014190016a24000f0b1045000bf61407157f017e017f017e017f017e017f230041306b220224000240024020014115490d00024002402001410176220341ffffff3f712003470d0020034105742204417f4c0d000240200410332205450d002002410036020820024204370300200041606a2106200041a07f6a210741042108410021094100210a2001210b0340200b210c4100210b4101210d0240200c417f6a220e450d000240024002400240024002402000200e4105746a200c410574220f20006a41406a412010a0084100480d004102200c6b210e2007200f6a21034101210d03400240200e200d6a4101470d004100210b200c210d0c080b200d41016a210d200341206a2003412010a0082110200341606a21032010417f4a0d000b200c200d6b210e0c010b2007200f6a2103024003400240200e4101470d004100210e0c020b200e417f6a210e200341206a2003412010a0082110200341606a210320104100480d000b0b200c200e490d01200c20014b0d02200c200e6b220d4101762211450d002006200f6a21032000200e4105746a21100340200241106a41186a220f201041186a2212290000370300200241106a41106a2213201041106a2214290000370300200241106a41086a2215201041086a221629000037030020022010290000370310200341086a220b2900002117200341106a22182900002119200341186a221a290000211b201020032900003700002012201b3700002014201937000020162017370000201a200f29030037000020182013290300370000200b201529030037000020032002290310370000200341606a2103201041206a21102011417f6a22110d000b0b0240200e0d00200e210b0c050b0240200d41094d0d00200e210b0c050b200c20014b0d02200c200e6b21112000200e4105746a210f0340200c200e417f6a220b490d040240200c200b6b220d4102490d002000200e4105746a22032000200b4105746a220e412010a008417f4a0d00200e2900002117200e2003290000370000200241106a41186a2215200e41186a2210290000370300200241106a41106a2216200e41106a2212290000370300200241106a41086a2218200e41086a22132900003703002013200341086a2900003700002012200341106a2900003700002010200341186a29000037000020022017370310410121140240200d4103490d00200e41c0006a200241106a412010a008417f4a0d0041022110200f210302400340200341186a200341386a290000370000200341106a200341306a290000370000200341086a200341286a2900003700002003200341206a221229000037000020112010460d01200341c0006a21132010211420122103201041016a21102013200241106a412010a008417f4a0d020c000b0b201021140b200e20144105746a22032002290310370000200341186a2015290300370000200341106a2016290300370000200341086a20182903003700000b200b450d05200f41606a210f201141016a2111200b210e200d410a4f0d050c000b0b200e200c41eccfca001059000b200c200141eccfca001058000b200c200e417f6a220b490d00200c200141fccfca001058000b200b200c41fccfca001059000b0240200a2002280204470d002002200a41011090012002280200210820022802082209210a0b2008200a4103746a2203200d3602042003200b3602002002200941016a22093602082009210a024020094102490d00034002400240024002400240200820092214417f6a22094103746a2203280200450d00201441037420086a221141746a280200220d200328020422104b0d010b20144103490d022003280204211020082014417d6a22034103746a280204210e0c010b4102210a0240201441024b0d0020142109200b450d090c060b20082014417d6a22034103746a280204220e2010200d6a4d0d004103210a0240201441034b0d0020142109200b450d090c060b201141646a280200200e200d6a4d0d00201421092014210a0c040b200e2010490d010b2014417e6a21030b02400240024002400240024002402014200341016a22184d0d00201420034d0d0120082003410374221a6a2203280204220a20032802006a220320082018410374221c6a22102802002216490d02200320014b0d03200020164105746a22132010280204221541057422106a210d2003410574210e200320166b220c20156b220320154f0d042005200d20034105742210109d08221220106a211120154101480d0520034101480d052006200e6a210e200d21030340200e200341606a220d201141606a220c200c200d412010a008410048220f1b2210290000370000200e41186a201041186a290000370000200e41106a201041106a290000370000200e41086a201041086a2900003700002011200c200f1b211102402013200d2003200f1b2203490d00201221100c080b200e41606a210e2012211020122011490d000c070b0b20182014418cd0ca001042000b20032014419cd0ca001042000b2016200341acd0ca001059000b2003200141acd0ca001058000b200520132010109d08221220106a2111024020154101480d00200c20154c0d002000200e6a210f201221102013210303402003200d2010200d2010412010a008410048220c1b220e290000370000200341186a200e41186a290000370000200341106a200e41106a290000370000200341086a200e41086a2900003700002010201041206a200c1b2110200341206a2103200d41206a200d200c1b220d200f4f0d03201120104b0d000c030b0b20132103201221100c010b200d2103201221100b20032010201120106b416071109d081a2008201a6a2203200a20156a360204200320163602002008201c6a2203200341086a20142018417f736a410374109e081a20022009360208200941014b0d000b2009210a200b450d040c010b200b450d030c000b0b1045000b1044000b0240200228020441ffffffff0171450d00200810350b2004450d01200510350c010b20014102490d002001417f6a2110200141057420006a41206a210f410121110340024002400240024020102203417f6a221020014b0d00200120106b220e4102490d03200020034105746a2203200020104105746a220c412010a008417f4a0d03200c2900002117200c2003290000370000200241106a41186a2213200c41186a220d290000370300200241106a41106a2214200c41106a2212290000370300200241106a41086a2208200c41086a22152900003703002015200341086a2900003700002012200341106a290000370000200d200341186a2900003700002002201737031041012103200e4103490d02200c41c0006a200241106a412010a008417f4a0d0241002112200f21030340200341406a220e200341606a220d290000370000200e41186a200d41186a290000370000200e41106a200d41106a290000370000200e41086a200d41086a29000037000020112012220e460d02200e417f6a21122003200241106a412010a008210d200341206a2103200d417f4a0d020c000b0b2010200141dccfca001059000b4102200e6b21030b200c20034105746a22032002290310370000200341186a2013290300370000200341106a2014290300370000200341086a20082903003700000b200f41606a210f2011417f6a211120100d000b0b200241306a24000bfc0701137f230041c0006b22042400200441003602082004420137030020044100360218200442013703102002410020031b21052000410020011b2106200241206a200220031b2107200041206a200020011b2108200020014105746a2109200220034105746a210a4101210b4101210c4100210d4101210e4101210f410021100340200b2111200e2112201021132007210320052102024002400340024020020d00410021052006450d020c030b02402006450d000240024020022006460d0020022006412010a00822140d010b2003200341206a2003200a4622021b210741002008200820094622141b21064100200320021b21052011210b2012210e201321102008200841206a20141b21080c050b02402014417f4c0d00200221050c040b200441206a41186a2214200241186a290000370300200441206a41106a2215200241106a290000370300200441206a41086a2216200241086a29000037030020042002290000370320024020132004280214470d00200441106a20134101108a01200428021821132004280210221121122011210f0b200f20134105746a22022004290320370000200241186a2014290300370000200241106a2015290300370000200241086a20162903003700002004201341016a2213360218410020032003200a4622141b21022003200341206a20141b21030c010b0b200441206a41186a2203200541186a290000370300200441206a41106a2213200541106a290000370300200441206a41086a2206200541086a29000037030020042005290000370320024020102004280214470d00200441106a20104101108a01200428021821102004280210220b210e0b200e20104105746a22022004290320370000200241186a2003290300370000200241106a2013290300370000200241086a20062903003700002004201041016a221036021841002106410020072007200a4622021b2105200e210f2007200741206a20021b21070c020b2004280204210220042802142103201120132000200110aa060240200341ffffff3f71450d00201110350b0240200241ffffff3f71450d00200c10350b200441c0006a24000f0b200441206a41186a2214200641186a290000370300200441206a41106a2215200641106a290000370300200441206a41086a2216200641086a290000370300200420062900003703200240200d2004280204470d002004200d4101108a012004280200210c2004280208210d0b200c200d4105746a22022004290320370000200241186a2014290300370000200241106a2015290300370000200241086a20162903003700002004200d41016a220d36020841002008200820094622021b21062011210b2012210e201321102008200841206a20021b2108200321070c000b0bee1604017f067e0e7f027e230041d0026b22032400200241c0006a2903002104200241306a2903002105200241286a2903002106200241106a2903002107200241086a29030021082002290338210920022d0000210a200341086a41186a200241e0006a290000370300200341086a41106a200241d8006a290000370300200341086a41086a200241d0006a29000037030020032002290048370308200341286a41086a200241206a290300370300200320022800013602382003200241046a28000036003b2003200241186a29030037032820012802002802002202280208220b410574210c2002280200210d024002400240200b0d0041032102200d210e0c010b200c210f200d210202400340200341a8016a200341086a2002220b10b20620032802a801220e20032802b00110e40241ff01712102024020032802ac01450d00200e10350b024020024103470d00200b41206a2102200f41606a220f450d020c010b0b200b41206a210e0c020b200b41206a210e410321020b0b4101211002400240024002400240024002400240200241ff0171417e6a220f41014b0d000240200f0e020200020b4100210f410421114100210b410021100c020b410021100b410810332211450d03200d200c6a210c2011200b360204201120023a000020034281808080103702840120032011360280014101210b034002400240200c200e2202470d002002210e4103210f0c010b200341a8016a200341086a200210b20620032802a801220e20032802b00110e40241ff0171210f024020032802ac01450d00200e10350b200241206a210e200f4103460d010b024002400240200f41ff0171220d4102470d00201041016a21100c010b200d4103460d010b0240200b200328028401470d0020034180016a200b410110900120032802800121110b2011200b4103746a220d2002360204200d200f3a00002003200b41016a220b360288010c010b0b200328028401210f200b450d002001280204200b417f6a10af062202200b4f0d04201120024103746a2d000022024103470d010b410121024100210d0c010b410241012002410246220d1b21020b200320023a003f2001280208210e200341c0026a200128020c360200200341bc026a200341c8026a36020020032011200b4103746a22023602b402200320113602b0022003200f3602ac02200320113602a80220032003413f6a3602b8022003200341b8026a220b3602a8010240034020112002460d012003201141086a3602b0022011280200220241ff01714103460d010240200b2002201128020410ce0622020d0020032802b402210220032802b00221110c010b0b20034180016a41086a2211200241086a29000037030020034180016a41106a220c200241106a29000037030020034180016a41186a2212200241186a2900003703002003200229000037038001200e41046a21130340200341a8016a41186a22142012290300370300200341a8016a41106a2215200c290300370300200341a8016a41086a2216201129030037030020032003290380013703a8010240200e41086a2217280200220f2013280200470d00200e200f4101108a010b200e280200200f4105746a220220032903a801370000200241186a2014290300370000200241106a2015290300370000200241086a20162903003700002017200f41016a3602002003200b3602a801034020032802b002220220032802b402460d022003200241086a3602b0022002280200220f41ff01714103460d02200b200f200228020410ce062202450d000b2011200241086a290000370300200c200241106a2900003703002012200241186a29000037030020032002290000370380010c000b0b024020032802ac0241ffffffff0171450d0020032802a80210350b02400240200d0d0020034180016a41086a200341286a41086a290300370300200320032802383602402003200328003b3600432003200329032837038001200341a8026a200341086a10cf0620033502b002211820032802a8022111411010332202450d0220022009370000200220043700082002411041201037210202400240200a41ff01714101460d002002450d06200241003a0010200320073703b001200320083703a801200341a8016a210e4111210b4120210f0c010b2002450d05200241013a001041c000210f2002412041c00010372202450d0520022008370018200220032802403600112002200329038001370028200241206a2007370000200241146a2003280043360000200241306a20034188016a2d00003a0000200320053703b001200320063703a801200341a8016a210e4131210b0b0240200f200b6b410f470d00200f200f410174220d200b41106a220c200d200c4b1b220d460d002002200f200d10372202450d050b2002200b6a220f200e290000370000200f41086a200e41086a29000037000020184220862011ad84200b41106aad4220862002ad84100220021035024020032802ac02450d00201110350b200341a8016a41086a41083a0000200341b1016a2003290308370000200341b9016a200341086a41086a290300370000200341c1016a200341086a41106a290300370000200341c9016a200341206a290300370000200341123a00a80141b0b4cc004100200341a8016a10d401200042003703000c010b20012802102202200228020020106a360200200128021422022002290300221820097c2219370300200241086a2202200229030020047c2019201854ad7c37030020012802002802002102200341a8016a41186a220f200341086a41186a290300370300200341a8016a41106a220e200341086a41106a290300370300200341a8016a41086a2211200341086a41086a290300370300200320032903083703a80102402002280208220b200241046a280200470d002002200b4101108a012002280208210b0b2002280200200b4105746a220b20032903a801370000200b41186a200f290300370000200b41106a200e290300370000200b41086a20112903003700002002200228020841016a360208200320032802383602502003200328003b360053200341c0006a41086a200341286a41086a290300370300200320032903283703402001280218280200210202400240200a41ff01714101470d00200341b7016a2007370000200341c7016a200341c8006a2d00003a0000200320083700af01200320032800533600ab01200320032802503602a801200320032903403700bf0120034180016a200341a8016a10d0060240200328028001220b200328028801220e10d10241ff0171220f4102460d00200ead422086200bad8410070b0240200328028401450d00200b10350b2009210720042108200f0d01200341a8016a2002200920062009200654220b200420055420042005511b220f1b20042005200f1b10b0064200200420057d200bad7d2207200920067d2205200956200720045620072004511b220b1b210842002005200b1b21070c010b200320083703a802200320073703b00202402008200784500d002003200341086a36027c20034180016a200341086a200341a8026a200341fc006a10f0022003290380014201520d002003290388012107200341e0016a20034180016a41106a290300370300200341d8016a2007370300200341a8016a41086a41003a0000200341b1016a2003290308370000200341b9016a200341086a41086a290300370000200341c1016a200341086a41106a290300370000200341c9016a200341206a290300370000200341033a00a80141b0b4cc004100200341a8016a10d4010b20092107200421080b200341086a20022007200810b006200041386a2004370300200041306a20093703002000410c6a2003290308370200200041146a200341106a2903003702002000411c6a200341186a290300370200200041246a200341206a29030037020020004201370300200020012802102802003602080b200341d0026a24000f0b1045000b2002200b419cb9c8001042000b103c000b992209027f017e027f017e2f7f017e1e7f077e017f0240200028028002220241c000490d00200041a0026a22032903002204a7210520004198026a22062903002207a721082004422088a721092007422088a7210a41e5f0c18b06210b41eec8819903210c41b2da88cb07210d41f4ca81d906210e410a21022006280200220f21102000419c026a28020022112112200328020022132114200041a4026a28020022152116200f211720112118201321192015211a200f211b2011211c2013211d2015211e20004194026a280200221f210320004190026a280200222021062000418c026a2802002221212220002802880222232124201f2125202021262021212720232128201f21292020212a2021212b2023212c201f212d2020212e2021212f20232130200041b0026a2903002204422088a7223121322004a722332134200041ac026a2802002235ad422086200041a8026a2802002236ad84223742037c2204422088a7223821392004a7223a213b2031213c2033213d203742027c2204422088a7223e213f2004a7224021412031214220332143203742017c2204422088a7224421452004a722462147203121482033214941f4ca81d906214a41b2da88cb07214b41eec8819903214c41e5f0c18b06214d41f4ca81d906214e41b2da88cb07214f41eec8819903215041e5f0c18b06215141f4ca81d906215241e5f0c18b06215341eec8819903215441b2da88cb0721550340200c20226a220cad422086200b20246a220bad842039ad422086203bad84852204a74110772239201b6a221bad2004422088a7411077223b201c6a221cad422086842022ad4220862024ad84852204a7410c772222200b6a2224ad2004422088a7410c77220b200c6a220cad422086842039ad203bad42208684852204a7410877223b201b6a221bad2004422088a74108772239201c6a221cad422086842022ad200bad42208684852204a74107772222200d20066a220bad200e20036a220dad422086842034ad2032ad42208684852207a7411077220e201d6a221dad2007422088a74110772232201e6a221ead422086842006ad2003ad42208684852207422088a7410c772203200d6a22066a2234ad4220862007a7410c77220d200b6a220bad2006ad42208684200ead2032ad42208684852207a74108772206201d6a221dad2007422088a74108772232201e6a221ead42208684200dad2003ad42208684852207422088a74107772203200b6a220bad842039ad2006ad42208684852256a74110772206201b6a221bad2056422088a74110772239201c6a221cad422086842022ad4220862003ad84852256a7410c772203200b6a220dad2056422088a7410c77222220346a220ead422086842006ad2039ad42208684852256a74108772239201b6a221bad2056422088a74108772234201c6a221cad422086842003ad2022ad42208684852256a741077721032004422088a7410777220620246a2222ad2007a74107772224200c6a220cad42208684203bad4220862032ad84852204a74110772232201d6a221dad2004422088a7411077223b201e6a221ead422086842006ad2024ad42208684852204a7410c77220620226a220bad2004422088a7410c772222200c6a220cad422086842032ad203bad42208684852204a74108772232201d6a221dad2004422088a7410877223b201e6a221ead422086842006ad2022ad42208684852204a74107772122204c20276a2206ad422086204d20286a2224ad84203fad4220862041ad84852207a7411077223f20176a2217ad2007422088a7411077224120186a2218ad422086842027ad4220862028ad84852207a7410c77222720246a2224ad2007422088a7410c77222820066a2206ad42208684203fad2041ad42208684852207a7410877224120176a2217ad2007422088a7410877223f20186a2218ad422086842027ad2028ad42208684852207a74107772227204b20266a2228ad204a20256a224aad42208684203dad203cad42208684852257a7411077223c20196a2219ad2057422088a7411077223d201a6a221aad422086842026ad2025ad42208684852257422088a7410c772225204a6a22266a224aad4220862057a7410c77224b20286a2228ad2026ad42208684203cad203dad42208684852257a7410877222620196a2219ad2057422088a7410877223c201a6a221aad42208684204bad2025ad42208684852257422088a7410777222520286a2228ad84203fad2026ad42208684852258a7411077222620176a2217ad2058422088a7411077223d20186a2218ad422086842027ad4220862025ad84852258a7410c77222520286a224bad2058422088a7410c772227204a6a224aad422086842026ad203dad42208684852258a7410877223f20176a2217ad2058422088a7410877223d20186a2218ad422086842025ad2027ad42208684852258a741077721252007422088a7410777222620246a2224ad2057a7410777222720066a2206ad422086842041ad422086203cad84852207a7411077222820196a2219ad2007422088a7411077223c201a6a221aad422086842026ad2027ad42208684852207a7410c77222620246a224dad2007422088a7410c77222420066a224cad422086842028ad203cad42208684852207a7410877223c20196a2219ad2007422088a74108772241201a6a221aad422086842026ad2024ad42208684852207a741077721272050202b6a2206ad4220862051202c6a2224ad842045ad4220862047ad84852257a7411077222620106a2228ad2057422088a7411077221020126a2212ad42208684202bad422086202cad84852257a7410c77222b20246a2224ad2057422088a7410c77222c20066a2206ad422086842026ad2010ad42208684852257a7410877222620286a2228ad2057422088a7410877221020126a2212ad42208684202bad202cad42208684852257a7410777222b204f202a6a222cad204e20296a2245ad422086842043ad2042ad42208684852259a7411077224220146a2214ad2059422088a7411077224320166a2216ad42208684202aad2029ad42208684852259422088a7410c77222920456a222a6a2245ad4220862059a7410c772247202c6a222cad202aad422086842042ad2043ad42208684852259a7410877222a20146a2214ad2059422088a7410877224220166a2216ad422086842047ad2029ad42208684852259422088a74107772229202c6a222cad842010ad202aad4220868485225aa7411077222a20286a2228ad205a422088a7411077221020126a2212ad42208684202bad4220862029ad8485225aa7410c772229202c6a224fad205a422088a7410c77222b20456a224ead42208684202aad2010ad4220868485225aa7410877224520286a2210ad205a422088a7410877224320126a2212ad422086842029ad202bad4220868485225aa741077721292057422088a7410777222820246a2224ad2059a7410777222a20066a2206ad422086842026ad4220862042ad84852257a7411077222620146a222bad2057422088a7411077222c20166a2216ad422086842028ad202aad42208684852257a7410c77222820246a2251ad2057422088a7410c77222420066a2250ad422086842026ad202cad42208684852257a74108772242202b6a2214ad2057422088a7410877224720166a2216ad422086842028ad2024ad42208684852257a7410777212b205320306a2206ad2054202f6a2224ad422086842035ad4220862036ad84852259a7411077222620086a2228ad2059422088a7411077222a200a6a222cad42208684202fad4220862030ad84852259a7410c77222f20066a2206ad2059422088a7410c77223020246a2224ad422086842026ad202aad42208684852259a7410877222620286a2228ad2059422088a7410877222a202c6a222cad42208684202fad2030ad42208684852259a7410777222f2052202d6a2230ad4220862055202e6a2208ad842049ad2048ad4220868485225ba7411077220a20056a2205ad205b422088a7411077223520096a2209ad42208684202ead202dad4220868485225b422088a7410c77222d20306a222e6a2230ad422086205ba7410c77223620086a2208ad202ead42208684200aad2035ad4220868485225ba7410877222e20056a2205ad205b422088a7410877224820096a2209ad422086842036ad202dad4220868485225b422088a7410777222d20086a2208ad84202aad202ead4220868485225ca7411077222a20286a2228ad205c422088a7411077222e202c6a222cad42208684202fad422086202dad8485225ca7410c77222d20086a2255ad205c422088a7410c77222f20306a2252ad42208684202aad202ead4220868485225ca7410877223520286a2208ad205c422088a74108772249202c6a220aad42208684202dad202fad4220868485225ca7410777212d2059422088a7410777222820066a2206ad205ba7410777222a20246a2224ad422086842026ad4220862048ad84852259a7411077222620056a222cad2059422088a7411077222e20096a222fad422086842028ad202aad42208684852259a7410c77222820066a2253ad2059422088a7410c77220620246a2254ad422086842026ad202ead42208684852259a74108772248202c6a2205ad2059422088a74108772236202f6a2209ad422086842028ad2006ad42208684852259a7410777212f2056422088a741077721242004422088a741077721062058422088a741077721282007422088a74107772126205a422088a7410777212c2057422088a7410777212a205c422088a741077721302059422088a7410777212e2002417f6a22020d000b41002102200041003602800220002802a802215d2000203742047c22043e02a8022000203220316a3602fc012000203420336a3602f8012000203920386a3602f4012000203b203a6a3602f0012000201e20156a3602ec012000201d20136a3602e8012000201c20116a3602e4012000201b200f6a3602e00120002003201f6a3602dc012000200620206a3602d8012000202220216a3602d4012000202420236a3602d0012000200e41f4ca81d9066a3602cc012000200d41b2da88cb076a3602c8012000200c41eec88199036a3602c4012000200b41e5f0c18b066a3602c0012000203c20316a3602bc012000203d20336a3602b8012000203f203e6a3602b4012000204120406a3602b0012000201a20156a3602ac012000201920136a3602a8012000201820116a3602a40120002017200f6a3602a00120002025201f6a36029c012000202620206a360298012000202720216a360294012000202820236a360290012000204a41f4ca81d9066a36028c012000204b41b2da88cb076a360288012000204c41eec88199036a360284012000204d41e5f0c18b066a360280012000204220316a36027c2000204320336a3602782000204520446a3602742000204720466a3602702000201620156a36026c2000201420136a3602682000201220116a36026420002010200f6a36026020002029201f6a36025c2000202a20206a3602582000202b20216a3602542000202c20236a3602502000204e41f4ca81d9066a36024c2000204f41b2da88cb076a3602482000205041eec88199036a3602442000205141e5f0c18b066a3602402000200920156a36022c2000200520136a3602282000200a20116a36022420002008200f6a3602202000202d201f6a36021c2000202e20206a3602182000202f20216a3602142000203020236a3602102000205241f4ca81d9066a36020c2000205541b2da88cb076a3602082000205441eec88199036a3602042000205341e5f0c18b066a36020020002802ac022103200020044220883e02ac02200020002802b40220486a36023c200020002802b00220496a3602382000200320356a3602342000205d20366a3602300b200020024102746a28020021032000200241016a360280020240200141016a220620014f0d004180bcc800413941bcbcc800103f000b20032006700bfb0303057f017e047f230041306b220424000240024002402002200384500d002004200010b806200441206a200428020022052004280208220610b402024002400240024002400240200428022022070d00410021002004410036021820044208370310410021080c010b200420042902242209370214200420073602102009a7210a410021000240024002402009422088a7220841014b0d0020080e020201020b2008210b03402000200b410176220c20006a220d2007200d41186c6a28020020014b1b2100200b200c6b220b41014b0d000b0b2007200041186c6a280200220b2001460d032000200b2001496a220020084b0d070b2008200a470d010b200441106a20084101109c012004280214210a200428021021070b2007200041186c6a220b41186a200b200820006b41186c109e081a200b41106a2003370300200b2002370308200b20013602002004200841016a220836021820070d012006ad4220862005ad8410070c020b200020084f0d042007200041186c6a22002000290308220920027c2202370308200041106a2200200029030020037c2002200954ad7c3703000b200420063602242004200536022020072008200441206a109603200a450d00200a41186c450d00200710350b2004280204450d00200510350b200441306a24000f0b20002008104d000b2000200841e0bbc8001042000be30202047f017e230041206b2203240002400240200241e8006c4104722204417f4c0d00200410332205450d0120034100360208200320043602042003200536020020022003107702402002450d00200241e8006c21064100210403402003200120046a220241c8006a412010780240024020022d00004101460d00200341003a00102003200341106a41011078200241086a29030021072003200241106a29030037031820032007370310200341106a21050c010b200341013a00102003200341106a410110782003200241016a41201078200241286a29030021072003200241306a29030037031820032007370310200341106a21050b2003200541101078200241386a29030021072003200241c0006a290300370318200320073703102003200341106a411010782006200441e8006a2204470d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1044000b1045000bdc0703027f017e067f230041e0006b2203240041a29bc800ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541b39bc800ad4280808080d00084100122042900002105200341186a41086a200441086a29000037030020032005370318200410350240024002400240412010332204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020032004ad42808080808004841003220129000037034820011035200341dc006a2201200441206a360200200320043602582003200341c8006a41086a22063602542003200341c8006a360250200341286a200341d0006a107b20041035412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2201417f4c0d01200328023821092003280228210a0240024020010d004100210b410121040c010b200110332204450d012001210b0b02400240200b410f4d0d00200b21020c010b200b41017422024110200241104b1b22024100480d030240200b0d002002103322040d010c050b200b2002460d002004200b200210372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020024170714110460d002002210b0c010b2002410174220b4120200b41204b1b220b4100480d032002200b460d0020042002200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21020c010b2007415f4b0d03200b41017422022006200220064b1b22024100480d03200b2002460d002004200b200210372204450d040b200441206a200a2007109d081a02400240200220066b2008490d002002210b0c010b20012006490d032002410174220b2001200b20014b1b220b4100480d03024020020d000240200b0d00410121040c020b200b10332204450d050c010b2002200b460d0020042002200b10372204450d040b200420066a20092008109d081a200020013602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541d4bac800ad4280808080d00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b8c1004057f017e047f017e230041f0016b22012400200141d0006a41186a22024200370300200141d0006a41106a22034200370300200141d0006a41086a220442003703002001420037035041a29bc800ad4280808080f00084100122052900002106200141f0006a41086a2207200541086a2900003703002001200637037020051035200420072903003703002001200129037037035041f69bc800ad4280808080c000841001220529000021062007200541086a2900003703002001200637037020051035200320012903702206370300200141306a41086a2004290300370300200141306a41106a2006370300200141306a41186a200729030037030020012001290350370330200141f0006a200141306a412010d50120012d007021052002200141f0006a41196a2900003703002003200141f0006a41116a2900003703002004200141f0006a41096a29000037030020012001290071370350410121070240024020054101460d0041002107200141003a00080c010b200141086a41096a2004290300370000200141086a41116a2003290300370000200141086a41196a2002290300370000200141013a0008200120012903503700090b20014189016a200041186a29000037000020014181016a200041106a290000370000200141f9006a200041086a29000037000020012000290000370071200141013a00700240024002402007450d00200141086a410172200141f0006a410172412010a008450d010b200141d0006a41186a22054200370300200141d0006a41106a22024200370300200141d0006a41086a220442003703002001420037035041a29bc800ad4280808080f00084100122082900002106200141f0006a41086a2207200841086a2900003703002001200637037020081035200420072903003703002001200129037037035041ef9bc800ad4280808080f000841001220829000021062007200841086a290000370300200120063703702008103520032001290370370000200341086a2007290300370000200141306a41086a2004290300370300200141306a41106a2002290300370300200141306a41186a200529030037030020012001290350370330200141f0006a200141306a412010d50120012d007021082005200141f0006a41196a2900003703002002200141f0006a41116a2900003703002004200141f0006a41096a29000037030020012001290071370350410121070240024020084101460d0041002107200141003a00080c010b200141086a41096a2004290300370000200141086a41116a2002290300370000200141086a41196a2005290300370000200141013a0008200120012903503700090b20014189016a200041186a29000037000020014181016a200041106a290000370000200141f9006a200041086a29000037000020012000290000370071200141013a007002402007450d00200141086a410172200141f0006a410172412010a008450d010b200141f0006a41186a4200370300200141f0006a41106a22054200370300200141f0006a41086a220442003703002001420037037041a29bc800ad4280808080f000841001220729000021062004200741086a29000037030020012006370370200710354189eaca00ad4280808080f00084100122072900002106200141d0006a41086a2202200741086a2900003703002001200637035020071035200520012903502206370300200141086a41086a2004290300370300200141086a41106a2006370300200141086a41186a200229030037030020012001290370370308200141f0006a200141086a10fe0120012802702207410120071b21084100210402400240024002402001290274420020071b2206422088a7220941014b0d0020090e020201020b2009210703402007410176220520046a22022004200820024105746a2000412010a0084101481b2104200720056b220741014b0d000b0b200820044105746a2000412010a008450d010b200642ffffff3f83500d01200810350c010b200420094f0d01200820044105746a2207200741206a2004417f7320096a410574109e081a200141d0006a41186a22024200370300200141d0006a41106a220a4200370300200141d0006a41086a220742003703002001420037035041a29bc800ad4280808080f0008410012205290000210b200141f0006a41086a2204200541086a2900003703002001200b3703702005103520072004290300370300200120012903703703504189eaca00ad4280808080f0008410012205290000210b2004200541086a2900003703002001200b3703702005103520032001290370370000200341086a2004290300370000200141306a41086a2007290300370300200141306a41106a200a290300370300200141306a41186a200229030037030020012001290350370330200141203602742001200141306a36027020082009417f6a200141f0006a1098020240200642ffffff3f83500d00200810350b200141f0006a200010b9062001280270210420013502782106200141013a000820064220862004ad84200141086aad42808080801084100202402001280274450d00200410350b200141f0006a200010ba06200135027842208620012802702204ad84100702402001280274450d00200410350b200141f0006a41086a41093a0000200141f0006a41096a200029000037000020014181016a200041086a29000037000020014189016a200041106a29000037000020014191016a200041186a290000370000200141123a007041b0b4cc004100200141f0006a10d4010b200141f0016a24000f0b20042009104e000bfc0403027f017e057f230041d0006b220224004186f0cb00ad4280808080800184100122032900002104200241086a41086a200341086a29000037030020022004370308200310354180eaca00ad4280808080900184100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bf21201277f230041f0046b220324000240024002402001280200220420012802044f0d00200341d7036a210520034184026a21062003418c046a2107200341d0036a4101722108200341b1046a220941036a210a03402001200441016a360200200341c0026a200410f504200341d0036a20032802c002220b20032802c80210b302200341b8046a41086a220c200841086a290000370300200341b8046a41106a220d200841106a290000370300200341b8046a41186a220e200841186a290000370300200341b8046a41206a220f200841206a290000370300200341b8046a41286a2210200841286a290000370300200341b8046a412f6a22112008412f6a290000370000200341e8026a41086a2212200741086a290000370300200341e8026a41106a2213200741106a290000370300200341e8026a41186a2214200741186a290000370300200341e8026a41206a2215200741206a280000360200200320082900003703b804200320072900003703e802200328028804211620032d00d0032117200320092800003602d8012003200a2800003600db010240201741024622180d0020032d00b004211920034180026a412f6a201129000037000020034180026a41286a201029030037030020034180026a41206a200f29030037030020034180026a41186a200e29030037030020034180026a41106a200d29030037030020034180026a41086a200c290300370300200341a8036a41086a2012290300370300200341a8036a41106a2013290300370300200341a8036a41186a2014290300370300200341a8036a41206a2015280200360200200320032903b80437038002200320032903e8023703a803200320032800db013600a303200320032802d8013602a0032016211a0b024020032802c402450d00200b10350b200c20034180026a41086a221b290300370300200d20034180026a41106a221c290300370300200e20034180026a41186a221d290300370300200f20034180026a41206a221e290300370300201020034180026a41286a221f290300370300201120034180026a412f6a290000370000200341d8016a41086a2220200341a8036a41086a220b290300370300200341d8016a41106a2221200341a8036a41106a2216290300370300200341d8016a41186a2222200341a8036a41186a2223290300370300200341d8016a41206a2224200341a8036a41206a222528020036020020032003290380023703b804200320032903a8033703d801200320032800a3033600d301200320032802a0033602d001200341d0036a41086a2226200c290300370300200341d0036a41106a2227200d290300370300200341d0036a41186a220d200e290300370300200341d0036a41206a220e200f290300370300200341d0036a41286a220f2010290300370300200341d0036a412f6a2011290000370000200320032903b8043703d003200b2020290300370300201620212903003703002023202229030037030020252024280200360200200320032903d8013703a803200320032800d3013600a303200320032802d0013602a00302400240024020180d002017410171450d010b4103210c0c010b20062005290000370000200641286a200541286a290000370000200641206a200541206a290000370000200641186a200541186a290000370000200641106a200541106a290000370000200641086a200541086a290000370000200341c0026a41086a2210200b290300370300200341c0026a41106a22112016290300370300200341c0026a41186a22172023290300370300200341c0026a41206a220b2025280200360200200320032903a8033703c0022012201b2902003703002013201c2902003703002014201d2902003703002015201e290200370300200341e8026a41286a2216201f290200370300200341e8026a41306a222320034180026a41306a280200360200200320032800a3033600bb02200320032802a0033602b80220032003290280023703e8024103210c201941ff01714103460d002026201229030037030020272013290300370300200d2014290300370300200e2015290300370300200f2016290300370300200341d0036a41306a22162023280200360200201b2010290300370300201c2011290300370300201d2017290300370300201e200b280200360200200320032903e8023703d003200320032903c00237038002200320032800bb023600ab03200320032802b8023602a8034103210c201a2002280200280200470d0020034198016a41306a201628020036020020034198016a41286a200f29030037030020034198016a41206a200e29030037030020034198016a41186a200d29030037030020034198016a41106a202729030037030020034198016a41086a2026290300370300200341f0006a41086a201b290300370300200341f0006a41106a201c290300370300200341f0006a41186a201d290300370300200341f0006a41206a201e280200360200200320032903d003370398012003200329038002370370200320032800ab0336006b200320032802a80336026820042128201a21292019210c0b200c41ff01714103470d02200128020022042001280204490d000b0b200041033a00600c010b200341306a41306a220820034198016a41306a280200360200200341306a41286a220720034198016a41286a290300370300200341306a41206a220d20034198016a41206a290300370300200341306a41186a220e20034198016a41186a290300370300200341306a41106a220f20034198016a41106a290300370300200341306a41086a221020034198016a41086a290300370300200341086a41086a2211200341f0006a41086a290300370300200341086a41106a2201200341f0006a41106a290300370300200341086a41186a2204200341f0006a41186a290300370300200341086a41206a2205200341f0006a41206a2802003602002003200329039801370330200320032903703703082003200328006b3600032003200328026836020020002028360200200020032903303702042000410c6a2010290300370200200041146a200f2903003702002000411c6a200e290300370200200041246a200d2903003702002000412c6a2007290300370200200041346a2008280200360200200020293602382000200329030837023c200041c4006a2011290300370200200041cc006a2001290300370200200041d4006a2004290300370200200041dc006a20052802003602002000200c3a0060200041e4006a2003280003360000200020032802003600610b200341f0046a24000b81fc010d017f017e037f017e017f017e027f017e057f017e067f067e0b7f230041f00b6b2201240010ff0342d0a1f10221020240024002400240024002400240024020004101460d00200141c8056a41186a22034200370300200141c8056a41106a22044200370300200141c8056a41086a22054200370300200142003703c80541a9d1cb00ad4280808080c0008422061001220729000021082005200741086a290000370300200120083703c8052007103541cdd1cb00ad4280808080b0018410012207290000210820014198076a41086a2209200741086a29000037030020012008370398072007103520042001290398072208370300200141a8056a41086a2005290300370300200141a8056a41106a2008370300200141a8056a41186a2009290300370300200120012903c8053703a80520014188056a200141a8056a10e1022001290390052108200128028805210a200342003703002004420037030020054200370300200142003703c805200610012207290000210b2005200741086a2900003703002001200b3703c8052007103541add1cb00ad4280808080a001841001220c290000210b200141e8056a41086a2207200c41086a2900003703002001200b3703e805200c1035200420012903e805220b370300200141a0096a41086a220c2005290300370300200141a0096a41106a220d200b370300200141a0096a41186a220e2007290300370300200120012903c8053703a009200141f8046a200141a0096a10e10220012802f804210f200129038005210b200342003703002004420037030020054200370300200142003703c80520061001220329000021062005200341086a290000370300200120063703c8052003103541c2d1cb00ad4280808080b001841001220329000021062007200341086a290000370300200120063703e80520031035200420012903e8052206370300200c2005290300370300200d2006370300200e2007290300370300200120012903c8053703a009200141e8046a200141a0096a10e102420020084200200a1b220620012903f004420020012802e8041b200b42c8017e4200200f1b7c7d220820082006561b42c801540d00200141a00a6a41186a220a4200370300200141a00a6a41106a22104200370300200141a00a6a41086a22074200370300200142003703a00a41a3edcb00ad4280808080f000842211100122032900002102200141f8056a41086a2205200341086a290000370300200120023703f8052003103520072005290300370300200120012903f8053703a00a41a5ebcb00ad4280808080c001841001220329000021022005200341086a290000370300200120023703f80520031035201020012903f8052202370300200c2007290300370300200d2002370300200e2005290300370300200120012903a00a3703a009200141e0046a200141a0096a412010c00120012802e404210f20012802e0042112200a42003703002010420037030020074200370300200142003703a00a20111001220329000021022005200341086a290000370300200120023703f8052003103520072005290300370300200120012903f8053703a00a41b1ebcb00ad4280808080d001841001220329000021022005200341086a290000370300200120023703f80520031035201020012903f8052202370300200c2007290300370300200d2002370300200e2005290300370300200120012903a00a3703a009200141a0096a10bd02210310c00420014198076a41186a420037030020014198076a41106a2213420037030020094200370300200142003703980741f7edcb00ad4280808080f000841001220729000021022009200741086a29000037030020012002370398072007103541eeedcb00ad4280808080900184100122072900002102200c200741086a290000370300200120023703a00920071035201320012903a009220237030020052009290300370300200141f8056a41106a2002370300200141f8056a41186a200c29030037030020012001290398073703f8054100210c200f410020121b210f200141a00a6a200141f8056a10ac01024020012903a00a22024202510d0020012903a80a2106200141a00a6a2010280200220d41016a10b801200141d8046a20012802a00a220720012802a80a10c00120012802dc04210920012802d8042105024020012802a40a450d00200710350b20054101470d002009200f41016a470d0020024201520d00200141c8056a41186a22074200370300200141c8056a41106a22094200370300200141c8056a41086a22054200370300200142003703c80541d1efcb00ad42808080809001841001220e29000021022005200e41086a290000370300200120023703c805200e103541ebc3c400ad428080808030841001220a2900002102200141f8056a41086a220e200a41086a290000370300200120023703f805200a1035200420012903f805370000200441086a2212200e290300370000200141a8056a41086a22142005290300370300200141a8056a41106a22152009290300370300200141a8056a41186a22162007290300370300200120012903c8053703a805200141c8046a200141a8056a10e102200141a0046a20012903d004420020012802c8041b220242e807802208420042e8074200108408200141a00a6a200d10bd01200141b0046a20012802a00a221720012802a80a10d70120012903a004220b200220084298787e7c42ff07837c2202427f200141a0046a41086a2903002002200b54ad7c501b20067d2118200141b0046a41106a290300420020012802b004220a1b210220012903b8044200200a1b210b024020012802a40a450d00201710350b200742003703002009420037030020054200370300200142003703c80541b6fdc600ad42808080808001841001220a29000021062005200a41086a290000370300200120063703c805200a103541e489c200ad4280808080d001841001220a2900002106200e200a41086a290000370300200120063703f805200a1035200420012903f8053700002012200e290300370000201420052903003703002015200929030037030020162007290300370300200120012903c8053703a80520014188046a200141a8056a412010d701200141f8036a200129039004420020012802880422051b220620014188046a41106a290300420020051b2208428094ebdc034200109808200141e8036a20012903f8032219200141f8036a41086a290300221a4280ec94a37c427f10840820082002200b200656200220085620022008511b22051b21022006200b20051b210b20012903e80320067c211b2018428086ebc7f5002018428086ebc7f500541b42058842ffffffff0f83428094ebdc037e4298ac9fd60380211c4100210741d87d2105024002400340200141d8036a2019201a200541ece4c6006a350200220642001084082007200b20012903d80322082006201b7e2206428094ebdc03802218a7417f2006428080808080c0b2cd3b541b200620184280ec94a37c7e7c4280cab5ee01566aad7c22065a2002200141d8036a41086a2903002006200854ad7c22085a200220085122091b6a2107200b200654200220085420091b0d01200541086a22050d000b200141c8036a2019201a42e8aafa0b4200108408200141d0036a29030020012903c8032206201b42e8aafa0b7e2202428094ebdc03802208a7417f2002428080808080c0b2cd3b541b200220084280ec94a37c7e7c4280cab5ee01566aad7c2202200654ad7c21060c010b02402007417f6a220520074d0d00200141c8026a2019201a42c0f0f50b4200108408200141d0026a29030020012903c8022206201b4228802202a7417f201b42c0f0f50b7e2208428080808080c0b2cd3b541b200820024280ec94a37c7e7c4280cab5ee01566aad7c2202200654ad7c21060c010b02400240200541244b0d00200141b8036a2019201a2005410374220941c4e2c6006a280200220ead2206420010840820014198036a200b20012903b80322082006201b7e2206428094ebdc03802218a7417f2006428080808080c0b2cd3b541b200620184280ec94a37c7e7c4280cab5ee01566aad7c2206200b2006562002200141b8036a41086a2903002006200854ad7c22085620022008511b22051b22182006200b20051b22067d220b2002200820051b2008200220051b7d2018200654ad7d41002007410374220a41c4e2c6006a2802002207200e6b220e200e20074b1b22074101200741014b1bad2202420010980820014188036a200129039803220620014198036a41086a290300221820024200108408200141a8036a2019201a200941c8e2c6006a2802002207ad221d4200108408200141d8026a20184200200a41c8e2c6006a28020022092007200920074b220e1b20072009200e1b6bad22084200108408200141f8026a2006420020084200108408200141e8026a4200420020064200108408427f427f200141f8026a41086a290300220620012903d80220012903e8027c7c221820012903e00220012903f00284420052201820065472220e1b2218427f20012903f802200e1b2206200b2001290388037d20087e2002807c2202200654220ead7c2208200e2008201854200220065a1b220e1b210b427f2002200e1b2108200141a8036a41086a29030020012903a8032218201d201b7e2202428094ebdc03802206a7417f2002428080808080c0b2cd3b541b200220064280ec94a37c7e7c4280cab5ee01566aad7c2206201854ad7c2102200920074d2005730d0142002002200b7d2006200854ad7d220b200620087d2208200656200b200256200b2002511b22051b21064200200820051b21020c020b2005412541e4b8ca001042000b427f2002200b7c200620087c22082006542205ad7c22062005200620025420062002511b22051b2106427f200820051b21020b20014188026a2019201a4280c2d72f4200108408200141b8026a20022006428094ebdc034200109808200141f8016a2001290388022208201b420a802206a7417f201b4280c2d72f7e220b428080808080c0b2cd3b541b200b20064280ec94a37c7e7c4280cab5ee01566aad7c220620014188026a41086a2903002006200854ad7c428094ebdc034200109808200141a8026a20012903b8022208200141b8026a41086a290300220b4280ec94a37c427f10840820014198026a2008200b201c4200108408200141e8016a20012903f8012208200141f8016a41086a290300220b4280ec94a37c427f108408200141d8016a2008200b201c4200108408200141ac0a6a200d360200200141a00a6a41086a41003a0000200141b00a6a2001290398022208201c200220012903a8027c7e2202428094ebdc0380220ba7417f2002428080808080c0b2cd3b541b2002200b4280ec94a37c7e7c4280cab5ee01566aad7c2202370300200141b80a6a20014198026a41086a2903002002200854ad7c220b370300200141c80a6a4200200141d8016a41086a29030020012903d8012208201c200620012903e8017c7e2206428094ebdc03802218a7417f2006428080808080c0b2cd3b541b200620184280ec94a37c7e7c4280cab5ee01566aad7c2206200854ad7c2208200b7d2006200254ad7d2218200620027d221b200656201820085620182008511b22051b2206370300200141c00a6a4200201b20051b2208370300200141043a00a00a41b0b4cc004100200141a00a6a10d401200141f8056a200d10be0120012802f805210520013502800621182001200b3703a80a200120023703a00a20184220862005ad84200141a00a6aad220b42808080808002841002024020012802fc05450d00200510350b02400240024020082006844200520d002001420037038006200142003703f805200141a0096aad428080808080048421180c010b200141c8056a41186a22074200370300200141c8056a41106a22094200370300200141c8056a41086a22054200370300200142003703c80541b6fdc600ad428080808080018422021001220e290000211820014198076a41086a220d200e41086a2900003703002001201837039807200e10352005200d29030037030020012001290398073703c80541e489c200ad4280808080d0018422181001220a290000211b200141e8056a41086a220e200a41086a2900003703002001201b3703e805200a1035200420012903e805370000200441086a2214200e290300370000200141a0096a41086a22152005290300370300200141a0096a41106a22162009290300370300200141a0096a41186a22172007290300370300200120012903c8053703a009200141c0016a200141a0096a412010d701200141c0016a41106a290300211b20012903c801211920012802c001210a200742003703002009420037030020054200370300200142003703c8052002100122122900002102200d201241086a2900003703002001200237039807201210352005200d29030037030020012001290398073703c80520181001220d2900002102200e200d41086a290000370300200120023703e805200d1035200420012903e8053700002014200e290300370000201520052903003703002016200929030037030020172007290300370300200120012903c8053703a0092001427f201b4200200a1b220220067c20194200200a1b221b20087c2219201b542205ad7c22182005201820025420182002511b22051b3703a80a2001427f201920051b3703a00a200141a0096aad42808080808004842218200b42808080808002841002024020050d00200120083703f80520012006370380060c020b2001201b427f8522083703f80520012002427f85220637038006201b200283427f520d010b200141c8056a41186a22074200370300200141c8056a41106a22094200370300200141c8056a41086a22054200370300200142003703c80541b6fdc600ad428080808080018422021001220e290000210620014198076a41086a220d200e41086a2900003703002001200637039807200e10352005200d29030037030020012001290398073703c80541e489c200ad4280808080d0018422061001220a2900002108200141e8056a41086a220e200a41086a290000370300200120083703e805200a1035200420012903e805370000200441086a2214200e290300370000200141a0096a41086a22152005290300370300200141a0096a41106a22162009290300370300200141a0096a41186a22172007290300370300200120012903c8053703a009200141a8016a200141a0096a412010d701200141a8016a41106a290300210820012903b001211b20012802a801210a200742003703002009420037030020054200370300200142003703c8052002100122122900002102200d201241086a2900003703002001200237039807201210352005200d29030037030020012001290398073703c80520061001220d2900002102200e200d41086a290000370300200120023703e805200d1035200420012903e8053700002014200e290300370000201520052903003703002016200929030037030020172007290300370300200120012903c8053703a009200120084200200a1b3703a80a2001201b4200200a1b3703a00a2018200b428080808080028410020c010b200142f0f2bda1a7ee9cb9f9003703f805200141a00a6a200141f8056a10e001200141a00a6a2008200610df01200141b80a6a2006370300200141b00a6a2008370300200141a80a6a41063a00002001410c3a00a00a41b0b4cc004100200141a00a6a10d4010b200141a00a6a41186a220d4200370300200141a00a6a41106a220e4200370300200141a00a6a41086a22074200370300200142003703a00a2011100122092900002102200141f8056a41086a2205200941086a290000370300200120023703f8052009103520072005290300370300200120012903f8053703a00a41c897ca00ad4280808080a001841001220929000021022005200941086a290000370300200120023703f80520091035201020012903f805370000201041086a2005290300370000200141a0096a41086a2007290300370300200141a0096a41106a200e290300370300200141a0096a41186a200d290300370300200120012903a00a3703a009200141203602e40b2001200141a0096a3602e00b200141a8056a200141a0096aad221b42808080808004842211100510c2010240024020012802a805220d0d000c010b20012802ac05210e2001200141a8056a41086a2802003602ec052001200d3602e805200141a0016a200141e8056a10c4010240024020012802a0010d0020012802a401220a20012802ec05220941a0016e22052005200a4b1bad42a0017e2202422088a70d072002a72205417f4c0d070240024020050d004101210c0c010b20051033220c450d090b200141003602a8082001200c3602a0082001200541a0016e3602a4080240200a450d00200141a00a6a41206a211520014198076a410172211641002114410021120240034041002105200141003a00b807201241016a211202400340200141003a00d00b20092005460d0120014198076a20056a20012802e80522072d00003a00002001200741016a3602e8052001200541016a22073a00b8072007210520074120470d000b200141c8056a41086a220520014198076a41086a290300370300200141c8056a41106a221720014198076a41106a290300370300200141c8056a41186a221e20014198076a41186a29030037030020012001290398073703c8052001200920076b3602ec0520014198076a200141e8056a10c20220012d0098074101460d02200141a00a6a41186a201e290300370300200141a00a6a41106a2017290300370300200141a00a6a41086a2005290300370300200120012903c8053703a00a20152016418001109d081a200141f8056a200141a00a6a41a001109d081a0240201420012802a408470d00200141a0086a2014410110a00120012802a008210c20012802a80821140b200c201441a0016c6a200141f8056a41a001109d081a2001201441016a22143602a8082012200a460d0320012802ec0521090c010b0b200141003602ec05200541ff0171450d00200141003a00b8070b024020012802a4082205450d00200541a0016c450d00200c10350b0c010b20012902a4082102200c0d010b4100210c2001410036028006200142013703f8052001410936029c072001200141e00b6a360298072001200141f8056a3602a008200141b40a6a4101360200200142013702a40a200141c888c2003602a00a200120014198076a3602b00a200141a0086a41e88ac500200141a00a6a10431a20013502800642208620013502f80584100620012802fc05450d0020012802f80510350b200e450d00200d10350b2003200341ff017141024771211f200141003602a80a200142013703a00a200141a00a6a410020024200200c1b2219422088a7222041a0016c221241a0016e108a01200c4101200c1b211620012802a80a210c20012802a00a212102402020450d002021200c4105746a21052012210920162107034020052007290000370000200541186a200741186a290000370000200541106a200741106a290000370000200541086a200741086a290000370000200c41016a210c200541206a2105200741a0016a2107200941e07e6a22090d000b0b20012802a40a2122200141a00a6a41186a22034200370300200141a00a6a41106a22094200370300200141a00a6a41086a22074200370300200142003703a00a41a3edcb00ad4280808080f0008422021001220d2900002106200141f8056a41086a2205200d41086a290000370300200120063703f805200d103520072005290300370300200120012903f8053703a00a41f393ca00ad4280808080a001841001220d29000021062005200d41086a290000370300200120063703f805200d1035201020012903f805370000201041086a22142005290300370000200141a0096a41086a220d2007290300370300200141a0096a41106a220e2009290300370300200141a0096a41186a220a2003290300370300200120012903a00a3703a009200141203602a40a2001200141a0096a3602a00a2021200c200141a00a6a1098020240201f450d00200342003703002009420037030020074200370300200142003703a00a20021001220c29000021062005200c41086a290000370300200120063703f805200c103520072005290300370300200120012903f8053703a00a41beebcb00ad4280808080a002841001220c29000021062005200c41086a290000370300200120063703f805200c1035201020012903f80537000020142005290300370000200d2007290300370300200e2009290300370300200a2003290300370300200120012903a00a3703a009200141a00a6a200141a0096a10c50220012802a00a220c450d002011100720012902a40a42ffffffff0383500d00200c10350b200342003703002009420037030020074200370300200142003703a00a20021001220c29000021022005200c41086a290000370300200120023703f805200c103520072005290300370300200120012903f8053703a00a41a5ebcb00ad4280808080c001841001220c29000021022005200c41086a290000370300200120023703f805200c1035201020012903f80537000020142005290300370000200d2007290300370300200e2009290300370300200a2003290300370300200120012903a00a3703a0092001200f41016a22153602a00a2011200141a00a6aad22184280808080c000841002200141c8056a41186a220c4200370300200141c8056a41106a22034200370300200141c8056a41086a22054200370300200142003703c80541f7edcb00ad4280808080f000841001220729000021022005200741086a290000370300200120023703c8052007103541eeedcb00ad4280808080900184100122072900002102200141e8056a41086a2214200741086a290000370300200120023703e80520071035200420012903e805370000200441086a2014290300370000200d2005290300370300200e2003290300370300200a200c290300370300200120012903c8053703a009200141a00a6a200141a0096a10ac01200141a00a6a4100200928020041016a20012903a00a4202511b10b80120014198016a20012802a00a220c20012802a80a10c001200128029c0121072001280298012105024020012802a40a450d00200c10350b024020054101470d00024020072015460d00200720154f0d0141c3a6c000ad428080808080068410060b201510d8010b200141c8056a41186a220c4200370300200141c8056a41106a22094200370300200141c8056a41086a22054200370300200142003703c80541f7edcb00ad4280808080f0008410012207290000210220014198076a41086a2203200741086a2900003703002001200237039807200710352005200329030037030020012001290398073703c80541e4edcb00ad4280808080a00184100122072900002102200141e8056a41086a2203200741086a290000370300200120023703e80520071035200420012903e805370000200441086a2003290300370000200141a0096a41086a2005290300370300200141a0096a41106a2009290300370300200141a0096a41186a200c290300370300200120012903c8053703a00920014190016a200141a0096a412010c001200f41026a2105024002402001280290014101460d0020014198056a200510bf010c010b200141a00a6a20012802940110b80120014188016a20012802a00a220c20012802a80a10c001200128028c0121092001280288012107024020012802a40a450d00200c10350b024020070d0041fdb5c000ad4280808080e006841006410021090b200141c8056a41186a22034200370300200141c8056a41106a220d4200370300200141c8056a41086a22074200370300200142003703c80541f7edcb00ad4280808080f000841001220c290000210220014198076a41086a220e200c41086a2900003703002001200237039807200c10352007200e29030037030020012001290398073703c8054193eecb00ad42808080808001841001220c2900002102200141e8056a41086a220e200c41086a290000370300200120023703e805200c1035200420012903e805370000200441086a200e290300370000200141a0096a41086a2007290300370300200141a0096a41106a200d290300370300200141a0096a41186a2003290300370300200120012903c8053703a0094100200520096b2207200720054b1b210c0240024002404100200141a0096a10e5012207200741ff01714104461b41ff0171220741034b0d00024020070e0400020103000b200c41064f0d020b0240200c41016a4106490d00200141c8056a41186a220c4200370300200141c8056a41106a22094200370300200141c8056a41086a22054200370300200142003703c80541f7edcb00ad4280808080f0008410012207290000210220014198076a41086a2203200741086a2900003703002001200237039807200710352005200329030037030020012001290398073703c80541d9eecb00ad4280808080d00284100122072900002102200141e8056a41086a2203200741086a290000370300200120023703e80520071035200420012903e805370000200441086a2003290300370000200141a0096a41086a2005290300370300200141a0096a41106a2009290300370300200141a0096a41186a200c290300370300200120012903c8053703a009200141013a00d00b201b4280808080800484200141d00b6aad4280808080108410020b20014100360298050c020b200141c8056a41186a22094200370300200141c8056a41106a22034200370300200141c8056a41086a22074200370300200142003703c80541f7edcb00ad4280808080f000841001220c290000210220014198076a41086a220d200c41086a2900003703002001200237039807200c10352007200d29030037030020012001290398073703c8054193eecb00ad42808080808001841001220c2900002102200141e8056a41086a220d200c41086a290000370300200120023703e805200c1035200420012903e805370000200441086a200d290300370000200141a0096a41086a2007290300370300200141a0096a41106a2003290300370300200141a0096a41186a2009290300370300200120012903c8053703a009201b428080808080048410070b200141c8056a41186a22094200370300200141c8056a41106a22034200370300200141c8056a41086a22074200370300200142003703c80541f7edcb00ad4280808080f000841001220c290000210220014198076a41086a220d200c41086a2900003703002001200237039807200c10352007200d29030037030020012001290398073703c80541d9eecb00ad4280808080d002841001220c2900002102200141e8056a41086a220d200c41086a290000370300200120023703e805200c1035200420012903e805370000200441086a200d290300370000200141a0096a41086a2007290300370300200141a0096a41106a2003290300370300200141a0096a41186a2009290300370300200120012903c8053703a009200141003a00d00b201b4280808080800484200141d00b6aad42808080801084100220014198056a200510bf010b201620126a211e0240024020012802980522230d00200141a00a6a41186a4200370300200141a00a6a41106a220c4200370300200141a00a6a41086a22054200370300200142003703a00a41a3edcb00ad4280808080f000841001220729000021022005200741086a290000370300200120023703a00a2007103541f393ca00ad4280808080a0018410012207290000210220014198076a41086a2209200741086a290000370300200120023703980720071035200c2001290398072202370300200141f8056a41086a2005290300370300200141f8056a41106a2002370300200141f8056a41186a2009290300370300200120012903a00a3703f805200141a00a6a200141f8056a10fe0120012902a40a420020012802a00a22051b21022005410120051b2124410021250c010b41012125200129029c052102202321240b200120253a00c00b2001201e3602d40b200120163602d00b2001200141d00b6a3602e40b2001200141c00b6a3602e00b200141003602f005200142013703e805200141e8056a41002002422088a72205410574220741057510a00120012802f005211420012802e805211702402005450d002017201441a0016c6a210c2014200741606a4105766a2126200141a00a6a41206a210a200141a0086a41e0006a2127200141a0086a41c0006a2114200141a0086a41206a2112200141f8056a410172210f202421050340200141c8056a41186a2209200541186a290000370300200141c8056a41106a2204200541106a290000370300200141c8056a41086a2203200541086a290000370300200120052900003703c805200141a8056a200141c8056a10dd06200141f8056a20012802a805220e20012802b00510c10220012d00f805210d20014198076a200f418001109d081a02400240200d4101470d00200141a0096a20014198076a418001109d081a024020012802ac05450d00200e10350b200141a0086a200141a0096a418001109d081a0c010b024020012802ac05450d00200e10350b200141a0086a4100418001109f081a0b024020012802e00b2d00000d0020012802e40b220e280200220d200e280204460d00200e200d41a0016a36020002400240200141a0086a200d41206a220e460d00200e200141a0086a412010a0080d010b02402012200d41c0006a220e460d00200e2012412010a0080d010b02402014200d41e0006a220e460d00200e2014412010a0080d010b2027200d4180016a220d460d01200d2027412010a008450d010b20012802e00b41013a00000b200541206a2105200141a00a6a41186a2009290300370300200141a00a6a41106a2004290300370300200141a00a6a41086a2003290300370300200120012903c8053703a00a200a200141a0086a418001109d081a200c200141a00a6a41a001109d0841a0016a210c200741606a22070d000b202641016a21140b200120143602f0050240200242ffffff3f83500d00202410350b2014ad42a0017e2202422088a70d042002a72205417f4c0d0420012802ec05212820012d00c00b21240240024020050d00410121070c010b200510332207450d060b2001410036028006200120073602f8052001200541a0016e3602fc05200141f8056a4100201410a00120012802800621030240024020140d0020012802f805210f0c010b2017201441a0016c6a210e20012802f805220f200341a0016c6a210d200141a00a6a4180016a2107200141a00a6a41e0006a210c200141a00a6a41c0006a2109200141a00a6a41206a2104201721050340200141a00a6a41186a200541186a290000370300200141a00a6a41106a200541106a290000370300200141a00a6a41086a200541086a290000370300200120052900003703a00a200441186a200541386a290000370000200441106a200541306a290000370000200441086a200541286a2900003700002004200541206a2900003700002009200541c0006a290000370000200941086a200541c8006a290000370000200941106a200541d0006a290000370000200941186a200541d8006a290000370000200c200541e0006a290000370000200c41086a200541e8006a290000370000200c41106a200541f0006a290000370000200c41186a200541f8006a290000370000200720054180016a290000370000200741086a20054188016a290000370000200741106a20054190016a290000370000200741186a20054198016a290000370000200341016a2103200d200141a00a6a41a001109d0841a0016a210d200541a0016a2205200e470d000b0b20012802fc052127200141a00a6a41186a22094200370300200141a00a6a41106a22044200370300200141a00a6a41086a22074200370300200142003703a00a41a3edcb00ad4280808080f000841001220c2900002102200141f8056a41086a2205200c41086a290000370300200120023703f805200c103520072005290300370300200120012903f8053703a00a41c897ca00ad4280808080a001841001220c29000021022005200c41086a290000370300200120023703f805200c1035201020012903f805370000201041086a2005290300370000200141a0096a41086a2007290300370300200141a0096a41106a2004290300370300200141a0096a41186a2009290300370300200120012903a00a3703a009200341a0016c4104722205417f4c0d04200510332207450d05200141003602a80a200120053602a40a200120073602a00a2003200141a00a6a10770240024020030d0020012802a80a210520012802a40a210d20012802a00a21070c010b200f200341a0016c6a2112410020012802a80a22036b210920012802a40a210d4100210c03402003200c6a210402400240200d20096a4120490d0020012802a00a2107200d210e0c010b200441206a22052004490d04200d41017422072005200720054b1b220e4100480d0402400240200d0d000240200e0d00410121070c020b200e103322070d010c0c0b20012802a00a2107200d200e460d002007200d200e10372207450d0b0b2001200e3602a40a200120073602a00a0b200720036a200c6a220d200f200c6a2205290000370000200d41186a200541186a290000370000200d41106a200541106a290000370000200d41086a200541086a2900003700002001200441206a220d3602a80a02400240200e20096a41606a411f4d0d00200e210d0c010b200d41206a220a200d490d04200e410174220d200a200d200a4b1b220d4100480d0402400240200e0d000240200d0d00410121070c020b200d10332207450d0c0c010b200e200d460d002007200e200d10372207450d0b0b2001200d3602a40a200120073602a00a0b200720036a200c6a220e41206a200541206a290000370000200e41386a200541386a290000370000200e41306a200541306a290000370000200e41286a200541286a2900003700002001200441c0006a220e3602a80a02400240200d20096a41406a411f4d0d00200d210e0c010b200e41206a220a200e490d04200d410174220e200a200e200a4b1b220e4100480d0402400240200d0d000240200e0d00410121070c020b200e10332207450d0c0c010b200d200e460d002007200d200e10372207450d0b0b2001200e3602a40a200120073602a00a0b200720036a200c6a220d41c0006a200541c0006a290000370000200d41d8006a200541d8006a290000370000200d41d0006a200541d0006a290000370000200d41c8006a200541c8006a2900003700002001200441e0006a220d3602a80a02400240200e20096a41a07f6a411f4d0d00200e210a0c010b200d41206a220a200d490d04200e410174220d200a200d200a4b1b220a4100480d0402400240200e0d000240200a0d00410121070c020b200a10332207450d0c0c010b200e200a460d002007200e200a10372207450d0b0b2001200a3602a40a200120073602a00a0b200720036a200c6a220d41e0006a200541e0006a290000370000200d41f8006a200541f8006a290000370000200d41f0006a200541f0006a290000370000200d41e8006a200541e8006a290000370000200120044180016a220d3602a80a02400240200a20096a41807f6a411f4d0d00200a210d0c010b200d41206a220e200d490d04200a410174220d200e200d200e4b1b220d4100480d0402400240200a0d000240200d0d00410121070c020b200d10332207450d0c0c010b200a200d460d002007200a200d10372207450d0b0b2001200d3602a40a200120073602a00a0b200720036a200c6a220e4180016a20054180016a290000370000200e4198016a20054198016a290000370000200e4190016a20054190016a290000370000200e4188016a20054188016a2900003700002001200441a0016a3602a80a200941e07e6a2109200c41a0016a210c200541a0016a2012470d000b2003200c6a21050b20112005ad4220862007ad8410020240200d450d00200710350b02402027450d00202741a0016c450d00200f10350b200141a00a6a41186a22094200370300200141a00a6a41106a22044200370300200141a00a6a41086a22074200370300200142003703a00a41a3edcb00ad4280808080f000841001220c2900002102200141f8056a41086a2205200c41086a290000370300200120023703f805200c103520072005290300370300200120012903f8053703a00a41b1ebcb00ad4280808080d001841001220c29000021022005200c41086a290000370300200120023703f805200c1035201020012903f805370000201041086a2005290300370000200141a0096a41086a2007290300370300200141a0096a41106a2004290300370300200141a0096a41186a2009290300370300200120012903a00a3703a009200120243a00a00a20112018428080808010841002200120153602a40a200141053a00a00a41b0b4cc004100200141a00a6a10d40141081033220c450d07200c201e360204200c201636020002400240201f0d00200141a00a6a41186a22094200370300200141a00a6a41106a22044200370300200141a00a6a41086a22074200370300200142003703a00a41a8e7cb00ad4280808080f00184100122032900002102200141f8056a41086a2205200341086a290000370300200120023703f8052003103520072005290300370300200120012903f8053703a00a419ce7cb00ad4280808080c001841001220329000021022005200341086a290000370300200120023703f80520031035201020012903f805370000201041086a220d2005290300370000200141a0096a41086a220e2007290300370300200141a0096a41106a220a2004290300370300200141a0096a41186a220f2009290300370300200120012903a00a3703a009200141f8006a200141a0096a10e102200129038001210220012802782112200942003703002004420037030020074200370300200142003703a00a41a3edcb00ad4280808080f000841001220329000021062005200341086a290000370300200120063703f8052003103520072005290300370300200120012903f8053703a00a41a5ebcb00ad4280808080c001841001220329000021062005200341086a290000370300200120063703f80520031035201020012903f805370000200d2005290300370000200e2007290300370300200a2004290300370300200f2009290300370300200120012903a00a3703a009200141f0006a200141a0096a412010c0012002420020121b2001280274410020012802701b10de06200c10350c010b0240024002402020450d00200c201641a0016a360200200141003a00c00a201641206a2107410021050340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141f8056a41086a2205200141a00a6a41086a290300370300200141f8056a41106a2207200141a00a6a41106a290300370300200141f8056a41186a2209200141a00a6a41186a290300370300200120012903a00a22023703a009200120023703f8052016450d0020014198076a41186a200929030037030020014198076a41106a200729030037030020014198076a41086a2005290300370300200120012903f80537039807200c280204200c2802006b41a0016e41286c41286a2205417f4c0d08200510332204450d09200420012903980737030020044201370320200441186a20014198076a41186a290300370300200441106a20014198076a41106a290300370300200441086a20014198076a41086a29030037030041012109200141013602a808200120043602a0082001200541286e22073602a408200c2802002205200c280204460d01200c200541a0016a360200200141003a00c00a200541206a2109410021050340200141003a00d00b200141a00a6a20056a200920056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141a0096a41086a2215200141a00a6a41086a22272903002202370300200141f8056a41186a2203200141a00a6a41186a2220290300370300200141f8056a41106a220d200141a00a6a41106a2224290300370300200141f8056a41086a220e2002370300200120012903a00a22023703a009200120023703f80541012109034020014198076a41186a2003290300220237030020014198076a41106a200d290300220637030020014198076a41086a200e2903002208370300200120012903f805220b37039807200141c8056a41186a220a2002370300200141c8056a41106a220f2006370300200141c8056a41086a221220083703002001200b3703c805024020092007470d00200141a0086a2007200c280204200c2802006b41a0016e41016a108f0120012802a00821040b2004200941286c6a220520012903c80537030020122903002102200f2903002106200a290300210820054201370320200541186a2008370300200541106a2006370300200541086a20023703002001200941016a22093602a8080240200c2802002207200c280204470d0020012802a40821070c030b200c200741a0016a36020041002105200141003a00c00a200741206a21070340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b20152027290300220237030020032020290300370300200d2024290300370300200e2002370300200120012903a00a22023703a009200120023703f80520012802a40821070c000b0b200c10354108210441002109410021070c010b200c10350b200141a00a6a41186a220d4200370300200141a00a6a41106a220e4200370300200141a00a6a41086a220c4200370300200142003703a00a41a8e7cb00ad4280808080f00184100122032900002102200141f8056a41086a2205200341086a290000370300200120023703f80520031035200c2005290300370300200120012903f8053703a00a41d297ca00ad4280808080f000841001220329000021022005200341086a290000370300200120023703f80520031035201020012903f805370000201041086a2005290300370000200141a0096a41086a200c290300370300200141a0096a41106a200e290300370300200141a0096a41186a200d290300370300200120012903a00a3703a009200141a00a6a200141a0096a412010da010240024020012802a00a4101460d00200120093602a80a200120073602a40a200120043602a00a200141f8056a200141a00a6a41004100200110df060c010b2011100720012902a40a2102200120093602a80a200120073602a40a200120043602a00a200141f8056a200141a00a6a2002a741012002422088a710df060b200141a00a6a41186a220c4200370300200141a00a6a41106a22094200370300200141a00a6a41086a22074200370300200142003703a00a41a8e7cb00ad4280808080f001842202100122042900002106200141f8056a41086a2205200441086a290000370300200120063703f8052004103520072005290300370300200120012903f8053703a00a419ce7cb00ad4280808080c0018422061001220429000021082005200441086a290000370300200120083703f80520041035201020012903f805370000201041086a22042005290300370000200141a0096a41086a22032007290300370300200141a0096a41106a220d2009290300370300200141a0096a41186a220e200c290300370300200120012903a00a3703a009200141e0006a200141a0096a10e1022001280260210f20012903682108200c42003703002009420037030020074200370300200142003703a00a20021001220a29000021022005200a41086a290000370300200120023703f805200a103520072005290300370300200120012903f8053703a00a20061001220a29000021022005200a41086a290000370300200120023703f805200a1035201020012903f8053700002004200529030037000020032007290300370300200d2009290300370300200e200c290300370300200120012903a00a3703a0092001200842017c4201200f1b22023703a00a2011201842808080808001841002200c42003703002009420037030020074200370300200142003703a00a41a3edcb00ad4280808080f000841001220a29000021062005200a41086a290000370300200120063703f805200a103520072005290300370300200120012903f8053703a00a41a5ebcb00ad4280808080c001841001220a29000021062005200a41086a290000370300200120063703f805200a1035201020012903f8053700002004200529030037000020032007290300370300200d2009290300370300200e200c290300370300200120012903a00a3703a009200141d8006a200141a0096a412010c0012002200128025c410020012802581b10de060b410810332205450d072005201e36020420052016360200410810332207450d0720072017201441a0016c6a222436020420072017360200200141c00b6a200541dc97ca0010cb05200141d00b6a200741dc97ca0010cb0520012802c80b210420012802c40b211220012802c00b2110200141e00b6a41086a200141d00b6a41086a280200360200200120012903d00b3703e00b20014198076a41186a2207420037030020014198076a41106a220c420037030020014198076a41086a22054200370300200142003703980741a9d1cb00ad4280808080c0008422021001220929000021062005200941086a29000037030020012006370398072009103541add1cb00ad4280808080a001842206100122032900002108200141e8056a41086a2209200341086a290000370300200120083703e80520031035201320012903e805370000201341086a22032009290300370000200141f8056a41086a220d2005290300370300200141f8056a41106a220e200c290300370300200141f8056a41186a220a200729030037030020012001290398073703f805200141c8006a200141f8056a10e10202400240024002402001290350420020012802481b220b42017c2208200b540d0020074200370300200c420037030020054200370300200142003703980720021001220f290000210b2005200f41086a2900003703002001200b37039807200f103520061001220f29000021062009200f41086a290000370300200120063703e805200f1035201320012903e80537000020032009290300370000200d2005290300370300200e200c290300370300200a200729030037030020012001290398073703f805200120083703a00a200141f8056aad4280808080800484220620184280808080800184100220074200370300200c420037030020054200370300200142003703980720021001220f29000021022005200f41086a2900003703002001200237039807200f103541b7d1cb00ad4280808080b001841001220f29000021022009200f41086a290000370300200120023703e805200f1035201320012903e80537000020032009290300370000200d2005290300370300200e200c290300370300200a200729030037030020012001290398073703f805200441286c4104722205417f4c0d08200510332207450d09200141003602a80a200120053602a40a200120073602a00a2004200141a00a6a10770240024020040d0020012802a80a210520012802a00a21040c010b2010200441286c6a210d20012802a40a210c20012802a80a210520102107034002400240200c20056b4120490d0020012802a00a2104200c21090c010b200541206a22092005490d08200c41017422042009200420094b1b22094100480d0802400240200c0d00024020090d00410121040c020b200910332204450d100c010b20012802a00a2104200c2009460d002004200c200910372204450d0f0b200120093602a40a200120043602a00a0b200420056a220c2007290000370000200c41186a200741186a290000370000200c41106a200741106a290000370000200c41086a200741086a2900003700002001200541206a22033602a80a200741206a290300210202400240200920036b4108490d00200541286a21052009210c0c010b200341086a22052003490d082009410174220c2005200c20054b1b220c4100480d080240024020090d000240200c0d00410121040c020b200c10332204450d100c010b2009200c460d0020042009200c10372204450d0f0b2001200c3602a40a200120043602a00a0b200420036a2002370000200120053602a80a200d200741286a2207470d000b0b20012802a40a210720062005ad4220862004ad84100202402007450d00200410350b02402012450d00201241286c450d00201010350b200842017c22022008540d0120014198076a41186a220c420037030020014198076a41106a2209420037030020014198076a41086a22054200370300200142003703980741a9d1cb00ad4280808080c000841001220729000021082005200741086a29000037030020012008370398072007103541e2d1cb00ad4280808080e00184100122072900002108200141e8056a41086a2204200741086a290000370300200120083703e80520071035201320012903e805370000201341086a2004290300370000200141f8056a41086a2005290300370300200141f8056a41106a2009290300370300200141f8056a41186a200c29030037030020012001290398073703f805200141a00a6a200141f8056a10b10220012d00a00a2105200141c8056a41186a2207200141b90a6a290000370300200141c8056a41106a220c200141b10a6a290000370300200141c8056a41086a2209200141a90a6a290000370300200120012900a10a3703c8050240024020054101460d00200141a8056a41186a4200370300200141a8056a41106a4200370300200141a8056a41086a4200370300200142003703a8050c010b200141a8056a41186a2007290300370300200141a8056a41106a200c290300370300200141a8056a41086a2009290300370300200120012903c8053703a8050b20014198076a41186a2207420037030020014198076a41106a220c420037030020014198076a41086a22054200370300200142003703980741a9d1cb00ad4280808080c00084220810012209290000210b2005200941086a2900003703002001200b370398072009103541f0d1cb00ad4280808080c00184220b100122042900002111200141e8056a41086a2209200441086a290000370300200120113703e80520041035201320012903e805370000201341086a22032009290300370000200141f8056a41086a220d2005290300370300200141f8056a41106a220e200c290300370300200141f8056a41186a220a200729030037030020012001290398073703f805200141c0006a200141f8056a412010c0012001280244210f2001280240211220074200370300200c420037030020054200370300200142003703980720081001220429000021082005200441086a290000370300200120083703980720041035200b1001220429000021082009200441086a290000370300200120083703e80520041035201320012903e80537000020032009290300370000200d2005290300370300200e200c290300370300200a200729030037030020012001290398073703f805200141003602a00a200620184280808080c000841002200141a0096a41186a200141a8056a41186a290300370300200141a0096a41106a200141a8056a41106a290300370300200141a0096a41086a200141a8056a41086a290300370300200120012903a8053703a009417f200f410020121b220341016a220520052003491b410d74412872220a417f4c0d08200a1033220d450d09200d20012903a009370000200d2002370020200d41186a200141a0096a41186a290300370000200d41106a200141a0096a41106a290300370000200d41086a200141a0096a41086a2903003700004128210e410021074100210502400340024002402005450d00200c2009470d01200441ffffff3f71450d00200510350b200720034f0d02200141e8056a200710fe03200141a00a6a20012802e805220c20012802f005220910c302024020012802a00a2205450d002009ad422086200cad8410070b20012902a40a420020051b21022005410120051b2105024020012802ec05450d00200c10350b200741016a210720052002422088a74105746a21092002a721042005210c0c010b20014198076a41186a200c41186a220f29000037030020014198076a41106a200c41106a221229000037030020014198076a41086a200c41086a22102900003703002001200c290000370398072010290000210220122900002108200c290000210b200141f8056a41186a2212200f290000370300200141f8056a41106a220f2008370300200141f8056a41086a221020023703002001200b3703f805200141a00a6a41186a22142012290300370300200141a00a6a41106a2212200f290300370300200141a00a6a41086a22152010290300370300200120012903f8053703a00a0240200a200e6b411f4b0d00200e41206a220f200e490d08200a4101742210200f2010200f4b1b220f4100480d0802400240200a0d000240200f0d004101210d0c020b200f1033220d450d100c010b200a200f460d00200d200a200f1037220d450d0f0b200f210a0b200c41206a210c200d200e6a220f20012903a00a370000200f41186a2014290300370000200f41106a2012290300370000200f41086a2015290300370000200e41206a210e0c000b0b200ead422086200dad84100922052900002102200541086a2900002108200541106a290000210b200141c8056a41186a200541186a290000370300200141c8056a41106a200b370300200141c8056a41086a2008370300200120023703c805200510350240200a450d00200d10350b20014198076a41186a220c420037030020014198076a41106a2209420037030020014198076a41086a22054200370300200142003703980741a9d1cb00ad4280808080c0008422021001220729000021082005200741086a29000037030020012008370398072007103541e2d1cb00ad4280808080e00184100122072900002108200141e8056a41086a2204200741086a290000370300200120083703e80520071035201320012903e805370000201341086a2004290300370000200141f8056a41086a2005290300370300200141f8056a41106a2009290300370300200141f8056a41186a200c29030037030020012001290398073703f805412010332205450d09200520012903c805370000200541186a200141c8056a41186a2203290300370000200541106a200141c8056a41106a220d290300370000200541086a200141c8056a41086a220e29030037000020062005ad4280808080800484100220051035200141a0086a41186a200141a8056a41186a2903002208370300200141a0086a41106a200141a8056a41106a290300220b370300200141a0086a41086a200141a8056a41086a2903002211370300200120012903a805221a3703a008200141a00a6a41186a220a2008370300200141a00a6a41106a220f200b370300200141a00a6a41086a221220113703002001201a3703a00a20014198076a41186a220c420037030020014198076a41106a2209420037030020014198076a41086a22074200370300200142003703980720021001220529000021022007200541086a29000037030020012002370398072005103541d8d1cb00ad4280808080a00184100122052900002102200141e8056a41086a2204200541086a290000370300200120023703e80520051035201320012903e805370000201341086a22102004290300370000200141f8056a41086a22142007290300370300200141f8056a41106a22152009290300370300200141f8056a41186a2227200c29030037030020012001290398073703f805412010332205450d09200520012903a00a370000200541186a200a290300370000200541106a200f290300370000200541086a201229030037000020062005ad4280808080800484100220051035200c42003703002009420037030020074200370300200142003703980741a9d1cb00ad4280808080c000841001220529000021022007200541086a29000037030020012002370398072005103541e2d1cb00ad4280808080e001841001220529000021022004200541086a290000370300200120023703e80520051035201320012903e8053700002010200429030037000020142007290300370300201520092903003703002027200c29030037030020012001290398073703f805200141a00a6a200141f8056a10b10220012d00a00a21052003200141b90a6a290000370300200d200141b10a6a290000370300200e200141a90a6a290000370300200120012900a10a3703c8050240024020054101460d00200141b8096a4200370300200141b0096a4200370300200141a8096a4200370300200142003703a0090c010b200141a0096a41186a200141c8056a41186a290300370300200141a0096a41106a200141c8056a41106a290300370300200141a0096a41086a200141c8056a41086a290300370300200120012903c8053703a0090b200141f8056a41086a2205200141e00b6a41086a280200360200200141f8056a41246a200141a0096a41186a290300370200200141f8056a411c6a200141a0096a41106a290300370200200141f8056a41146a200141a0096a41086a290300370200200120012903e00b22023703f805200120012903a00937028406200141cc0a6a200141f8056a41286a280200360200200141a00a6a41246a20014198066a290300370200200141a00a6a411c6a200141f8056a41186a290300370200200141a00a6a41146a200141f8056a41106a290300370200200141a00a6a410c6a2005290300370200200120023702a40a200141003602a00a20014198076a200141a00a6a108104200141d3056a20014198076a41086a28020036000020012001290398073700cb0520014198076a410c6a200141cf056a290000370000200141c28289aa0436009907200141023a009807200120012900c80537009d0720014198076a1082040240200141a00a6a41086a2802002205450d00200541286c450d0020012802a40a10350b41081033220c450d0b200c201e360204200c2016360200410810332227450d0b2027202436020420272017360200200141f8056a41186a4200370300200141f8056a41106a22264200370300200141f8056a41086a22054200370300200142003703f80541d1c4c700ad4280808080e000841001220729000021022005200741086a290000370300200120023703f8052007103541e7c4c700ad4280808080e00084100122072900002102200141e8056a41086a2209200741086a290000370300200120023703e80520071035202620012903e8052202370300200141a0096a41086a2005290300370300200141a0096a41106a2002370300200141a0096a41186a2009290300370300200120012903f8053703a009200141386a200141a0096a412010c00120012802382104200128023c2103200141a00a6a41186a4200370300200141a00a6a41106a22204200370300200141a00a6a41086a22074200370300200142003703a00a4188e8cb00ad42808080808001841001220929000021022005200941086a290000370300200120023703f8052009103520072005290300370300200120012903f8053703a00a4194c4c400ad4280808080e0018410012205290000210220014198076a41086a2209200541086a29000037030020012002370398072005103520202001290398072202370300200141a0086a41086a2007290300370300200141a0086a41106a2002370300200141a0086a41186a2009290300370300200120012903a00a3703a0082001200341e4006a41e40020041b3602a00a200141a0086aad4280808080800484221120184280808080c0008410020240200c2802002205200c280204460d00200c200541a0016a360200200141003a00c00a200541e0006a2107410021050340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141f8056a41086a200141a00a6a41086a290300220237030020014198076a41186a2205200141a00a6a41186a29030037030020014198076a41106a2207200141a00a6a41106a29030037030020014198076a41086a22092002370300200120012903a00a22023703f8052001200237039807200c280204200c2802006b41a0016e41057441206a220410332212450d0a2012200129039807370000201241186a2005290300370000201241106a2007290300370000201241086a200929030037000041012109200141013602a808200120123602a00820012004410576220a3602a408200c2802002205200c280204460d03200c200541a0016a360200200141003a00c00a200541e0006a2107410021050340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141a0096a41086a2210200141a00a6a41086a22132903002202370300200141f8056a41186a2204200141a00a6a41186a2214290300370300200141f8056a41106a2203200141a00a6a41106a2215290300370300200141f8056a41086a220d2002370300200120012903a00a22023703a009200120023703f805410121090340200141a8056a41186a20042903002202370300200141a8056a41106a20032903002206370300200141a8056a41086a200d2903002208370300200120012903f805220b3703a805200141c8056a41186a22072002370300200141c8056a41106a220e2006370300200141c8056a41086a220f20083703002001200b3703c80502402009200a470d00200141a0086a200a200c280204200c2802006b41a0016e41016a108a0120012802a00821120b201220094105746a220520012903c805370000200541186a2007290300370000200541106a200e290300370000200541086a200f2903003700002001200941016a22093602a8080240200c2802002207200c280204470d0020012802a408210a0c050b200c200741a0016a36020041002105200141003a00c00a200741e0006a21070340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b2010201329030022023703002004201429030037030020032015290300370300200d2002370300200120012903a00a22023703a009200120023703f80520012802a408210a0c000b0b200c10354100210a41012112410021090c030b41e6dcc30041c90041b0ddc3001064000b41e6dcc30041c90041c0ddc3001064000b200c10350b200141a00a6a41186a220c4200370300200141a00a6a41106a22044200370300200141a00a6a41086a22054200370300200142003703a00a4188e8cb00ad4280808080800184100122072900002102200141f8056a41086a2203200741086a290000370300200120023703f8052007103520052003290300370300200120012903f8053703a00a418fd1cb00ad4280808080c0008410012207290000210220014198076a41086a2203200741086a2900003703002001200237039807200710352020200129039807370000202041086a2003290300370000200141a0086a41086a2005290300370300200141a0086a41106a2004290300370300200141a0086a41186a200c290300370300200120012903a00a3703a008200941057422034104722205417f4c0d04200510332207450d05200141003602a80a200120053602a40a200120073602a00a2009200141a00a6a10770240024020090d0020012802a80a210720012802a40a210920012802a00a210e0c010b410020012802a80a22076b210420012802a00a210e20012802a40a21092012210d0340200d21050240200920046a411f4b0d00200741206a220c2007490d042009410174220d200c200d200c4b1b220c4100480d04024002400240024020090d000240200c0d004101210e0c020b200c1033210e0c030b2009200c470d010b200c21090c020b200e2009200c1037210e0b200c2109200e450d0a0b200541206a210d200e20076a220c2005290000370000200c41186a200541186a290000370000200c41106a200541106a290000370000200c41086a200541086a290000370000200441606a2104200741206a2107200341606a22030d000b200120093602a40a200120073602a80a2001200e3602a00a0b20112007ad422086200ead84100202402009450d00200e10350b0240200a41ffffff3f71450d00201210350b2027103541081033220c450d07200c201e360204200c201636020041081033221e450d07201e2024360204201e20173602000240024002400240201f450d000240200c2802002205200c280204460d00200c200541a0016a360200200141003a00c00a20054180016a2107410021050340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141f8056a41086a200141a00a6a41086a290300220237030020014198076a41186a2205200141a00a6a41186a29030037030020014198076a41106a2207200141a00a6a41106a29030037030020014198076a41086a22092002370300200120012903a00a22023703f8052001200237039807200c280204200c2802006b41a0016e41057441206a220410332212450d0a2012200129039807370000201241186a2005290300370000201241106a2007290300370000201241086a200929030037000041012109200141013602a808200120123602a00820012004410576220a3602a408200c2802002205200c280204460d02200c200541a0016a360200200141003a00c00a20054180016a2107410021050340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141a0096a41086a2210200141a00a6a41086a22132903002202370300200141f8056a41186a2204200141a00a6a41186a2214290300370300200141f8056a41106a2203200141a00a6a41106a2215290300370300200141f8056a41086a220d2002370300200120012903a00a22023703a009200120023703f805410121090340200141a8056a41186a20042903002202370300200141a8056a41106a20032903002206370300200141a8056a41086a200d2903002208370300200120012903f805220b3703a805200141c8056a41186a22072002370300200141c8056a41106a220e2006370300200141c8056a41086a220f20083703002001200b3703c80502402009200a470d00200141a0086a200a200c280204200c2802006b41a0016e41016a108a0120012802a00821120b201220094105746a220520012903c805370000200541186a2007290300370000200541106a200e290300370000200541086a200f2903003700002001200941016a22093602a8080240200c2802002207200c280204470d0020012802a408210a0c040b200c200741a0016a36020041002105200141003a00c00a20074180016a21070340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b2010201329030022023703002004201429030037030020032015290300370300200d2002370300200120012903a00a22023703a009200120023703f80520012802a408210a0c000b0b200c10354100210a41012112410021090c020b201e1035200c10350c020b200c10350b200141f8056a41186a220c4200370300200141f8056a41106a22044200370300200141f8056a41086a22054200370300200142003703f80541fdd0cb00ad4280808080a002841001220729000021022005200741086a290000370300200120023703f80520071035418fd1cb00ad4280808080c00084100122072900002102200141e8056a41086a2203200741086a290000370300200120023703e80520071035202620012903e805370000202641086a2003290300370000200141a0096a41086a2005290300370300200141a0096a41106a2004290300370300200141a0096a41186a200c290300370300200120012903f8053703a009200941057422034104722205417f4c0d05200510332207450d06200141003602a80a200120053602a40a200120073602a00a2009200141a00a6a10770240024020090d0020012802a80a210720012802a40a210920012802a00a210e0c010b410020012802a80a22076b210420012802a00a210e20012802a40a21092012210d0340200d21050240200920046a411f4b0d00200741206a220c2007490d052009410174220d200c200d200c4b1b220c4100480d05024002400240024020090d000240200c0d004101210e0c020b200c1033210e0c030b2009200c470d010b200c21090c020b200e2009200c1037210e0b200c2109200e450d0b0b200541206a210d200e20076a220c2005290000370000200c41186a200541186a290000370000200c41106a200541106a290000370000200c41086a200541086a290000370000200441606a2104200741206a2107200341606a22030d000b200120093602a40a200120073602a80a2001200e3602a00a0b201b42808080808004842007ad422086200ead84100202402009450d00200e10350b0240200a41ffffff3f71450d00201210350b201e10350b02402028450d00202841a0016c450d00201710350b02402025202345720d00200128029c0541ffffff3f71450d00202310350b0240202241ffffff3f71450d00202110350b42d0e199cd9a3a21022019a72205450d00200541a0016c450d00201610350b20014198076a41186a2203420037030020014198076a41106a2207420037030020014198076a41086a22054200370300200142003703980741f7edcb00ad4280808080f0008422081001220c2900002106200141a00a6a41086a2209200c41086a290000370300200120063703a00a200c103520052009290300370300200120012903a00a3703980741b6aac000ad42808080809002841001220c2900002106200141a0096a41086a2204200c41086a290000370300200120063703a009200c1035200720012903a0092206370300200141f8056a41086a220c2005290300370300200141f8056a41106a220d2006370300200141f8056a41186a220e200429030037030020012001290398073703f805200141306a200141f8056a10f2012001280230417d710d02200342003703002007420037030020054200370300200142003703980720081001220a29000021062009200a41086a290000370300200120063703a00a200a103520052009290300370300200120012903a00a3703980741d9eecb00ad4280808080d002841001220929000021062004200941086a290000370300200120063703a00920091035200720012903a009370000200741086a2004290300370000200c2005290300370300200d2007290300370300200e200329030037030020012001290398073703f8050240200141f8056a10bd02220541ff01714102460d0020054101710d020b20014198076a41186a2209420037030020014198076a41106a2204420037030020014198076a41086a22054200370300200142003703980741f7edcb00ad4280808080f000841001220c2900002106200141a00a6a41086a2203200c41086a290000370300200120063703a00a200c103520052003290300370300200120012903a00a370398074193eecb00ad42808080808001841001220c2900002106200141a0096a41086a2203200c41086a290000370300200120063703a009200c1035200720012903a009370000200741086a2003290300370000200141f8056a41086a2005290300370300200141f8056a41106a2004290300370300200141f8056a41186a200929030037030020012001290398073703f8054100200141f8056a10e5012205200541ff01714104461b41ff01710e0402010201020b103e000b200141c8056a41186a22044200370300200141c8056a41106a220c4200370300200141c8056a41086a22054200370300200142003703c80541a9d1cb00ad4280808080c0008422061001220929000021082005200941086a290000370300200120083703c8052009103541add1cb00ad4280808080a0018410012203290000210820014198076a41086a2209200341086a290000370300200120083703980720031035200c2001290398072208370300200141a0096a41086a220d2005290300370300200141a0096a41106a220e2008370300200141a0096a41186a220a2009290300370300200120012903c8053703a009200141206a200141a0096a10e1022001280220210f2001290328210820044200370300200c420037030020054200370300200142003703c805200610012203290000210b2005200341086a2900003703002001200b3703c8052003103541c2d1cb00ad4280808080b0018410012203290000210b2009200341086a2900003703002001200b3703980720031035200c200129039807220b370300200d2005290300370300200e200b370300200a2009290300370300200120012903c8053703a009200141106a200141a0096a10e1022001290318210b2001280210210320044200370300200c420037030020054200370300200142003703c80520061001220929000021062005200941086a290000370300200120063703c8052009103541cdd1cb00ad4280808080b00184100122092900002106200141f8056a41086a2204200941086a290000370300200120063703f80520091035200c20012903f8052206370300200141a8056a41086a2005290300370300200141a8056a41106a2006370300200141a8056a41186a2004290300370300200120012903c8053703a8052001200141a8056a10e102427f200b420020031b200842c8017e4200200f1b7c220642c8017c220820082006541b22062001290308420020012802001b7d22082006560d00417f20002008a7417f2008428080808010541b6a220520052000491b220520006b220c20054b0d00200c417f6a41314b0d0041f7edcb00ad4280808080f00084100122052900002106200141a00a6a41086a220c200541086a290000370300200120063703a00a2005103541f393ca00ad4280808080a00184100122052900002106200141a0096a41086a2209200541086a290000370300200120063703a00920051035412010332205450d02200520012903a00a370000200520012903a009370010200541086a200c290300370000200541186a2204200929030037000041201033220c450d02200c2005290000370000200c41186a2004290000370000200c41106a200541106a290000370000200c41086a200541086a290000370000200141a8056a41026a2209200141a00a6a41026a2d00003a0000200120012f00a00a3b01a80520014198076a41106a42a08080808004370300200141003a00b007200120053602a407200142a0808080800437029c072001200c36029807200141b3076a20092d00003a0000200120012f01a8053b00b107200141a00a6a20014198076a10c7010240024020012802a00a4101470d00200141c8056a41186a2205200141bc0a6a290200370300200141c8056a41106a200141b40a6a290200370300200141c8056a41086a200141ac0a6a290200370300200120012902a40a3703c805412010332203450d04200320012903c805370000200341186a2005290300370000200341106a200141c8056a41106a220d290300370000200341086a200141c8056a41086a220e29030037000020014281808080103702a408200120033602a008200141f8056a41186a20014198076a41186a280200360200200141f8056a41106a20014198076a41106a290300370300200141f8056a41086a20014198076a41086a29030037030020012001290398073703f805200141a00a6a200141f8056a10c70141012109024020012802a00a4101470d00200141a00a6a410472210541022109412021044101210c0340200141a0096a41186a200541186a2902002206370300200141a0096a41106a200541106a2902002208370300200141a0096a41086a200541086a290200220b3703002001200529020022183703a009200141c8056a41186a220a2006370300200d2008370300200e200b370300200120183703c80502402009417f6a200c470d00200141a0086a200c4101108a0120012802a00821030b200320046a220c20012903c805370000200c41186a200a290300370000200c41106a200d290300370000200c41086a200e290300370000200120093602a808200141a00a6a200141f8056a10c70120012802a00a4101470d01200441206a2104200941016a210920012802a408210c0c000b0b024020012802fc05450d0020012802f80510350b024020014188066a280200450d0020012802840610350b20012802a40841ffffff3f7121130c010b0240200128029c07450d0020012802980710350b4100211341012103024020012802a807450d0020012802a40710350b410021090b41f7edcb00ad4280808080f00084100122052900002106200141a00a6a41086a220c200541086a290000370300200120063703a00a2005103541cca9c000ad4280808080a00184100122052900002106200141a0096a41086a2204200541086a290000370300200120063703a00920051035412010332205450d02200520012903a00a370000200520012903a009370010200541086a200c290300370000200541186a220d200429030037000041201033220c450d02200c2005290000370000200c41186a200d290000370000200c41106a200541106a290000370000200c41086a200541086a290000370000200141e8056a41026a2204200141a00a6a41026a2d00003a0000200120012f00a00a3b01e80520014198076a41106a42a08080808004370300200141003a00b007200120053602a407200142a0808080800437029c072001200c36029807200141b3076a20042d00003a0000200120012f01e8053b00b107200141a00a6a20014198076a10c9050240024020012d00d00a4102460d00200141c8056a41186a200141a00a6a41186a290300370300200141c8056a41106a200141a00a6a41106a290300370300200141c8056a41086a200141a00a6a41086a290300370300200120012903a00a3703c805024020012802c40a41ffffff3f71450d0020012802c00a10350b412010332210450d04201020012903c805370000201041186a200141c8056a41186a220d290300370000201041106a200141c8056a41106a220e290300370000201041086a200141c8056a41086a220a29030037000020014281808080103702a408200120103602a008200141f8056a41186a20014198076a41186a280200360200200141f8056a41106a20014198076a41106a290300370300200141f8056a41086a20014198076a41086a29030037030020012001290398073703f805200141a00a6a200141f8056a10c905024020012d00d00a4102460d00412021044101210c0340200141a0096a41186a2205200141a00a6a41186a290300370300200141a0096a41106a220f200141a00a6a41106a290300370300200141a0096a41086a2212200141a00a6a41086a290300370300200120012903a00a3703a009024020012802c40a41ffffff3f71450d0020012802c00a10350b200d2005290300370300200e200f290300370300200a2012290300370300200120012903a0093703c8050240200c20012802a408470d00200141a0086a200c4101108a0120012802a00821100b201020046a220520012903c805370000200541186a200d290300370000200541106a200e290300370000200541086a200a2903003700002001200c41016a220c3602a808200441206a2104200141a00a6a200141f8056a10c90520012d00d00a4102470d000b0b024020012802fc05450d0020012802f80510350b024020014188066a280200450d0020012802840610350b200141a8056a41086a200141a0086a41086a280200360200200120012903a0083703a8050c010b200141003602b005200142013703a8050240200128029c07450d0020012802980710350b20012802a807450d0020012802a40710350b0240200941808004490d00024020012802ac0541ffffff3f71450d0020012802a80510350b2013450d01200310350c010b20094105742205417f4c0d010240024020090d00200141003602a80a200142013703a00a200141a00a6a41004100108a0120012802a80a210c20012802a00a210d0c010b200510332205450d03200141003602a80a200120093602a40a200120053602a00a200141a00a6a41002009108a012009410574210420012802a00a220d20012802a80a220e4105746a21052003210c03402005200c290000370000200541186a200c41186a290000370000200541106a200c41106a290000370000200541086a200c41086a290000370000200541206a2105200c41206a210c200441606a22040d000b2001200941057441606a410576200e6a41016a220c3602a80a0b20012802a40a2105200141a8056a20012802b005200c410574220c4105752204108a0120012802a805220f20012802b005220e4105746a200d200c109d081a2001200e20046a22123602b0050240200541ffffff3f71450d00200d10350b20014198076a41186a220c420037030020014198076a41106a2204420037030020014198076a41086a22054200370300200142003703980741f7edcb00ad4280808080f0008422061001220e2900002108200141a00a6a41086a220d200e41086a290000370300200120083703a00a200e10352005200d290300370300200120012903a00a370398074192aac000ad4280808080a002841001220a2900002108200141a0096a41086a220e200a41086a290000370300200120083703a009200a1035200720012903a009370000200741086a220a200e290300370000200141f8056a41086a22102005290300370300200141f8056a41106a22142004290300370300200141f8056a41186a2215200c29030037030020012001290398073703f805200141203602a40a2001200141f8056a3602a00a20032009200141a00a6a10980202402013450d00200310350b20012802ac052103200c4200370300200442003703002005420037030020014200370398072006100122092900002106200d200941086a290000370300200120063703a00a200910352005200d290300370300200120012903a00a3703980741a4aac000ad4280808080a00284100122092900002106200e200941086a290000370300200120063703a00920091035200720012903a009370000200a200e29030037000020102005290300370300201420042903003703002015200c29030037030020012001290398073703f805200141203602a40a2001200141f8056a3602a00a200f2012200141a00a6a1098020240200341ffffff3f71450d00200f10350b20014198076a41186a2209420037030020014198076a41106a2204420037030020014198076a41086a22054200370300200142003703980741f7edcb00ad4280808080f000841001220c2900002106200141a00a6a41086a2203200c41086a290000370300200120063703a00a200c103520052003290300370300200120012903a00a3703980741b6aac000ad42808080809002841001220c2900002106200141a0096a41086a2203200c41086a290000370300200120063703a009200c1035200720012903a009370000200741086a2003290300370000200141f8056a41086a2005290300370300200141f8056a41106a2004290300370300200141f8056a41186a200929030037030020012001290398073703f805410110332205450d04200541013a000020054101410510372205450d0420052000360001200141f8056aad42808080808004842005ad4280808080d000841002200510350b02400240200041044b0d00200141a8056a21030c010b200141c8056a41186a4200370300200141c8056a41106a220c4200370300200141c8056a41086a22054200370300200142003703c8054193d1cb00ad4280808080a001841001220729000021062005200741086a290000370300200120063703c8052007103541e0caca00ad4280808080e0008410012207290000210620014198076a41086a2209200741086a290000370300200120063703980720071035200c2001290398072206370300200141a0096a41086a2005290300370300200141a0096a41106a2006370300200141a0096a41186a2009290300370300200120012903c8053703a009200141a00a6a200141a0096a10b60220012802a00a2205410420051b210d0240024020012902a40a420020051b2206422088a7220941c4006c22050d00410021040c010b2000417b6a210c200d20056a210741002104200d210502400340024020052d00004101460d00200541046a280200200c4f0d020b200441016a21042007200541c4006a2205470d000b0b200420094b0d040b200920046b210e200642ffffffff0f832106200d200441c4006c22076a2103200d210c02400340024020070d00200321050c020b200741bc7f6a2107200c2d00002109200c41c4006a2205210c20094102470d000b0b0240034020032005460d0120052d00002107200541c4006a210520074102470d000b0b0240200e450d0002402004450d00200d200d200441c4006c6a200e41c4006c109e081a0b200ead42208620068421060b200141c8056a41186a4200370300200141c8056a41106a220c4200370300200141c8056a41086a22054200370300200142003703c8054193d1cb00ad4280808080a00184100122072900002108200141e8056a41086a2209200741086a290000370300200120083703e8052007103520052009290300370300200120012903e8053703c80541e0caca00ad4280808080e00084100122072900002108200141f8056a41086a2209200741086a290000370300200120083703f80520071035200c20012903f8052208370300200141a8056a41086a2005290300370300200141a8056a41106a2008370300200141a8056a41186a2009290300370300200120012903c8053703a805200141a00a6a200d2006422088a710e006200141a8056aad428080808080048420013502a80a42208620012802a00a2207ad8410022006a72105024020012802a40a450d00200710350b200141a8056a21032005450d00200541c4006c450d00200d10350b200141c8056a41186a22044200370300200141c8056a41106a220c4200370300200141c8056a41086a22074200370300200142003703c8054193d1cb00ad4280808080a00184100122052900002106200141e8056a41086a2209200541086a290000370300200120063703e8052005103520072009290300370300200120012903e8053703c805419dd1cb00ad4280808080c00184100122052900002106200141f8056a41086a2209200541086a290000370300200120063703f80520051035200c20012903f8052206370300200141a8056a41086a2007290300370300200141a8056a41106a2006370300200141a8056a41186a2009290300370300200120012903c8053703a805200141003a00d00b2003ad4280808080800484200141d00b6aad428080808010841002200141f8056a10d0042004200141f8056a41186a2203290300370300200c200141f8056a41106a220d29030037030020072009290300370300200120012903f8053703c805412410332205450d03200520012903c80537000020054114360220200541186a2004290300370000200541106a200c290300370000200541086a200729030037000020014281808080103702a40a200120053602a00a200141a00a6a10ab01200141a00a6a41186a2003290300370300200141a00a6a41106a200d290300370300200141a00a6a41086a2009290300370300200120012903f8053703a00a200141a00a6a10d30410ff03200141f00b6a240020020f0b1044000b1045000b20042009104f000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541f0bbc800ad4280808080f00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541cebbc800ad4280808080800284100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541c7bbc800ad4280808080f00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b130020004103360204200041ccbcc8003602000b3400200041d5c3c80036020420004100360200200041146a4101360200200041106a41dcc3c800360200200041086a42043702000b910101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120103322060d001045000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000b13002000410c36020420004180c7c8003602000b3400200041a29bc80036020420004100360200200041146a4110360200200041106a4180a3c900360200200041086a42073702000b130020004107360204200041c8b8c9003602000b3501017f02404108103322020d001045000b20004288808080800137020420002002360200200242f0f2bd99f7edd8b4e5003700000b2e01017f02404104103322020d001045000b20004284808080c0003702042000200236020020024180ee053600000b3b01017f02404110103322020d001045000b20024200370008200242808094f6c2d7e8d800370000200042908080808002370204200020023602000b2c01017f02404104103322020d001045000b20004284808080c000370204200020023602002002410a3600000b13002000410836020420004188c2c9003602000b340020004186f0cb0036020420004100360200200041146a4105360200200041106a41a0ebc900360200200041086a42083702000b130020004109360204200041e0f4c9003602000b3501017f02404108103322020d001045000b20004288808080800137020420002002360200200242f0f2bda1a7ee9cb9f9003700000b2b01017f02404101103322020d001045000b200042818080801037020420002002360200200241143a00000b2e01017f02404104103322020d001045000b20004284808080c0003702042000200236020020024180e1013600000b2e01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241a0c21e3600000b2e01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241d086033600000b900a030a7f027e017f230041106b220224002002410036020820024201370300024002400240412010332203450d002003200029004c370000200341186a2204200041e4006a290000370000200341106a2205200041dc006a290000370000200341086a2206200041d4006a290000370000412010332207450d02200241203602042002200736020020072003290000370000200741086a2006290000370000200741106a2005290000370000200741186a200429000037000020024120360208200310352007412041c00010372203450d022003200029006c370020200341286a200041f4006a290000370000200341306a200041fc006a290000370000200341386a20004184016a29000037000020022003360200200242c080808080083702040240024020002903004201510d00200341c00041800110372203450d04200341003a004020024180013602042002200336020041c10021070c010b200341c00041800110372203450d03200341013a00402003200041086a2207290000370041200341e9006a200041306a2903003700002003200041286a290300370061200341c9006a200741086a290000370000200341d1006a200741106a290000370000200341d9006a200741186a2900003700002002200336020020024280818080900c37020441f10021070b200220073602080240024020002802384101460d00200320076a41003a0000200741016a21030c010b200320076a41013a00002002200741016a22033602082000413c6a2802002106024002402002280204220520036b4104490d00200228020021040c010b41000d0320054101742204200341046a2208200420084b1b22084100480d030240024020050d002008103322040d010c060b2002280200210420052008460d0020042005200810372204450d050b20022008360204200220043602000b200420036a2006360000200741056a21030b2002200336020820002802402109200041c8006a2802002200200210770240024020000d002002280208210020022802042107200228020021050c010b2009200041306c6a210a41002002280208220b6b210620022802042107410021030340200b20036a210802400240200720066a4120490d0020022802002105200721040c010b200841206a22002008490d04200741017422042000200420004b1b22044100480d040240024020070d00024020040d00410121050c020b200410332205450d070c010b2002280200210520072004460d0020052007200410372205450d060b20022004360204200220053602000b2005200b6a20036a2207200920036a2200290000370000200741186a200041186a290000370000200741106a200041106a290000370000200741086a200041086a2900003700002002200841206a2207360208200041286a290300210c200041206a290300210d02400240200420066a41606a410f4d0d00200421070c010b200741106a220e2007490d0420044101742207200e2007200e4b1b22074100480d040240024020040d00024020070d00410121050c020b200710332205450d070c010b20042007460d0020052004200710372205450d060b20022007360204200220053602000b2005200b6a20036a220441286a200c370000200441206a200d3700002002200841306a360208200641506a2106200341306a2103200a200041306a470d000b200b20036a21000b20012902002000ad4220862005ad84100202402007450d00200510350b200241106a24000f0b1045000b103e000b103c000b990907027f027e017f017e027f047e047f230041306b2203240002400240024002400240024020002802002d0000200141ff0171460d0020002802082104200341206a200210b806200341106a20032802202201200328022810b4024200210520032902144200200328021022001b210602402003280224450d00200110350b2000410820001b2107428080d287e2bc2d210802402006422088a72209450d0002400240200941186c22000d0042002105428080d287e2bc2d2108410021010c010b200720006a210a4200210b428080d287e2bc2d210c4100210120072100024003400240200c200041086a290300220d7d2208200c56200b200041106a290300220e7d200c200d54ad7d2205200b562005200b511b450d00200041086a200d200c7d370300200041106a200e200b7d200d200c54ad7d37030042002108420021050c020b200141016a21012008210c2005210b200a200041186a2200470d000b0b200120094b0d030b200341106a200210b806200920016b220a41186c4104722200417f4c0d032003350218210d2003280210210f200010332210450d04200341003602282003200036022420032010360220200a200341206a10770240024020012009470d002003280228210020032802242101200328022021090c010b2007200141186c6a21102007200941186c6a2111200328022421012003280228210003402010280200211202400240200120006b4104490d00200328022021092001210a0c010b200041046a220a2000490d0820014101742209200a2009200a4b1b220a4100480d080240024020010d000240200a0d00410121090c020b200a103322090d010c0b0b200328022021092001200a460d0020092001200a10372209450d0a0b2003200a360224200320093602200b200920006a20123600002003200041046a2212360228201041106a290300210c201041086a290300210b02400240200a20126b4110490d00200041146a2100200a21010c010b201241106a22002012490d08200a41017422012000200120004b1b22014100480d0802400240200a0d00024020010d00410121090c020b200110332209450d0b0c010b200a2001460d002009200a200110372209450d0a0b20032001360224200320093602200b200920126a220a200c370008200a200b37000020032000360228201041186a22102011470d000b0b200d422086200fad842000ad4220862009ad84100202402001450d00200910350b2003280214450d00200f10350b2008428080d287e2bc2d56ad210c02402006a72200450d00200041186c450d00200710350b2005200c7c210b200341206a200210ba06200341086a200328022022002003280228220110c0012003200328020c41016a410120032802081b220a3602102001ad4220862000ad84200341106aad4280808080c00084100202402003280224450d00200010350b428080d287e2bc2d20087d210c4200200b7d210b0240200a410a490d00200210b4060b2004200c20042903007c2205370300200441086a2200200b20002903007c2005200c54ad7c370300410021020b200341306a240020020f0b2001200941ac82ca001059000b1044000b1045000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541e0aec900ad4280808080b00284100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541acb0c900ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b802304057f017e037f037e230041c0036b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c00011302030405060708090a0b0c0d0e0f1011121313131415161713000b20024180016a200141086a109d0320004100360200200041106a20024180016a41086a290300370300200041086a2002290380013703000c170b20024180016a200141046a109a03200041013602002000413c6a200241b8016a280200360200200041346a200241b0016a2903003702002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c160b20004103360200200041086a200141086a2903003703000c150b20024180016a200141046a109e03200041043602002000410c6a20024188016a28020036020020002002290380013702040c140b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b41cfa2cc00412841c086cc00103f000b200141086a2802002103410121050c030b41022105200241026a200441036a2d00003a000020024180016a41086a200141146a29020037030020024190016a2001411c6a29020037030020024198016a200141246a2d00003a0000200220042f00013b010020022001410c6a29020037038001200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b200241026a200441036a2d00003a000020024180016a41086a200141146a29020037030020024190016a2001411c6a29020037030020024198016a200141246a2d00003a0000200220042f00013b010020022001410c6a29020037038001200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01003b000520004105360200200041086a20033602002000410c6a200229038001370200200041286a2001360200200041076a200241026a2d00003a0000200041146a20024180016a41086a2903003702002000411c6a20024190016a290300370200200041246a20024198016a2802003602000c130b20024180016a200141086a108503200041086a20024180016a41e000109d081a200041063602000c120b20024180016a200141086a108702200041086a20024180016a418802109d081a200041073602000c110b02400240200128020422060d00410021030c010b20024180016a41186a200141286a29000037030020024180016a41106a200141206a29000037030020024188016a200141186a29000037030020024180016a41286a200141386a29000037030020024180016a41306a200141c0006a29000037030020024180016a41386a200141c8006a29000037030020024180016a41c8006a200141d8006a29000037030020024180016a41d0006a200141e0006a29000037030020024180016a41d8006a200141e8006a2900003703002002200141106a290000370380012002200141306a2900003703a0012002200141d0006a2900003703c00120024180016a41f8006a20014188016a29000037030020024180016a41f0006a20014180016a29000037030020024180016a41e8006a200141f8006a2900003703002002200141f0006a2900003703e0012001410c6a2802002201417f4c0d120240024020010d0041002105410121030c010b200110332203450d14200121050b0240024020052001490d00200521040c010b200541017422042001200420014b1b22044100480d15024020050d002004103322030d010c170b20052004460d0020032005200410372203450d160b200320062001109d081a200220024180016a418001109d081a2001ad4220862004ad8421070b20002003360204200041086a2007370200200041106a2002418001109d081a200041083602000c100b20024180016a200141086a10a00320004109360200200041386a20024180016a41306a290300370300200041306a20024180016a41286a290300370300200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c0f0b20024180016a200141046a10a1032000410a3602002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c0e0b20024180016a200141046a10a1032000410b3602002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c0d0b20024180016a200141086a1086032000410c360200200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c0c0b0240024002400240024002400240024020012d0004417f6a220441064b0d00200141046a21034107210520040e0701020304050607010b41cfa2cc00412841c086cc00103f000b20024198016a200341196a29000037030020024190016a200341116a29000037030020024188016a200341096a2900003703002002200329000137038001410121050c050b20024198016a200341196a29000037030020024190016a200341116a29000037030020024188016a200341096a2900003703002002200329000137038001410221050c040b20024180016a41186a200341196a29000037030020024180016a41106a200341116a29000037030020024180016a41086a200341096a290000370300200241086a200341296a290000370300200241106a200341316a290000370300200241186a200341396a29000037030020022003290001370380012002200341216a290000370300410321050c030b200141106a280200220841ffffff3f712008470d0f20084105742203417f4c0d0f200141086a28020021040240024020030d00410121050c010b200310332205450d110b41002101200241003602082002200536020020022003410576360204200241002008108a012002280208210902402008450d0020084105742106200228020020094105746a210a0340200a20016a2203200420016a2205290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a2900003700002006200141206a2201470d000b200841057441606a41057620096a41016a21090b2002418b016a20093600002002200229030037008301410421050c020b20024198016a200341196a29000037030020024190016a200341116a29000037030020024188016a200341096a2900003703002002200329000137038001410521050c010b20024198016a200341196a29000037030020024190016a200341116a29000037030020024188016a200341096a2900003703002002200329000137038001410621050b200020053a0004200020022903800137000520002002290300370025200020022f00bc033b00452000410d6a20024180016a41086a290300370000200041156a20024180016a41106a2903003700002000411d6a20024180016a41186a2903003700002000412d6a200241086a290300370000200041356a200241106a2903003700002000413d6a200241186a290300370000200041c7006a200241be036a2d00003a00002000410d3602000c0b0b2000410e360200200020012802043602040c0a0b2001410c6a2802002203417f4c0d0a200128020421060240024020030d0041002101410121040c010b200310332204450d0c200321010b0240024020012003490d00200121050c010b200141017422052003200520034b1b22054100480d0d024020010d00200510332204450d0f0c010b20012005460d0020042001200510372204450d0e0b200420062003109d0821012000410c6a2003360200200041086a2005360200200020013602042000410f3602000c090b20024180016a200141086a10a30320004110360200200041c0006a20024180016a41386a290300370300200041386a20024180016a41306a290300370300200041306a20024180016a41286a290300370300200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c080b20024180016a200141086a10a403200041086a20024180016a419801109d081a200041113602000c070b20024180016a200141046a10a503200041123602002000412c6a200241a8016a280200360200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c060b20024180016a200141046a10de04200041046a20024180016a41e800109d081a200041133602000c050b10a703000b20024180016a200141086a10a803200041086a20024180016a41a802109d081a200041173602000c030b20024180016a200141086a10a903200041086a20024180016a41c800109d081a200041183602000c020b20024180016a200141046a10aa03200041046a20024180016a41c400109d081a200041193602000c010b0240024002400240200141086a280200417f6a220a41024b0d0041012105200a0e03030102030b41cfa2cc00412841c086cc00103f000b41012103024002402001410c6a22052d00004101470d00200141106a28020021060c010b200241be036a200541036a2d00003a000020024188016a2001411c6a29020037030020024180016a41106a200141246a29020037030020024198016a2001412c6a2d00003a0000200220052f00013b01bc032002200141146a29020037038001200141106a2802002106410021030b41022105200241ac036a41026a200241bc036a41026a2d00003a0000200241086a20024180016a41086a290300370300200241106a20024180016a41106a290300370300200241186a20024180016a41186a280200360200200220022f01bc033b01ac0320022002290380013703000c010b41012103024002402001410c6a22052d00004101470d00200141106a28020021060c010b200241be036a200541036a2d00003a000020024188016a2001411c6a29020037030020024180016a41106a200141246a29020037030020024198016a2001412c6a2d00003a0000200220052f00013b01bc032002200141146a29020037038001200141106a2802002106410021030b200241ac036a41026a200241bc036a41026a2d00003a0000200241086a20024180016a41086a290300370300200241106a20024180016a41106a290300370300200241186a20024180016a41186a280200360200200220022f01bc033b01ac032002200229038001370300200141c8006a290300210b200141c0006a2903002107200141386a290300210c200141d0006a28020021042001290330210d410321050b200020022f01ac033b000d200041c8006a200b370300200041c0006a2007370300200041386a200c370300200041306a200d3703002000410c6a20033a0000200041086a2005360200200041106a2006360200200041146a2002290300370200200041d0006a20043602002000410f6a200241ae036a2d00003a00002000411c6a200241086a290300370200200041246a200241106a2903003702002000412c6a200241186a2802003602002000411a3602000b200241c0036a24000f0b1044000b1045000b103e000b103c000b9f0303027f017e027f230041206b220224004186f0cb00ad4280808080800184100122032900002104200241086a200341086a290000370300200220043703002003103541c0f0c900ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000bb10503027f017e047f230041d0006b220224004186f0cb00ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541d8efc900ad4280808080c00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b220224004186f0cb00ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541d8efc900ad4280808080c00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b1300200041013602042000419083ca003602000bb31903077f027e067f230041a0026b22052400200028020021064100210702400240024002400240024002400240200041086a280200220841014b0d0020080e020201020b20082109034020072009410176220a20076a220b2006200b41e8006c6a220b41386a290300200256200b41c0006a290300220c200356200c2003511b1b21072009200a6b220941014b0d000b0b2006200741e8006c6a220941386a290300220d200285200941c0006a290300220c20038584500d012007200d200254200c200354200c2003511b6a21070b200541a0016a41086a200441086a290300370300200541a0016a41106a200441106a290300370300200541a0016a41186a200441186a290300370300200541a0016a41206a200441206a290300370300200541a0016a41286a200441286a290300370300200541a0016a41306a200441306a290300370300200541286a41086a200141086a290000370300200541286a41106a200141106a290000370300200541286a41186a200141186a290000370300200520042903003703a0012005200129000037032820082007490d0302402008200041046a280200470d00200020084101109601200028020021060b2006200741e8006c6a220941e8006a2009200820076b41e8006c109e081a200941c0006a200337030020092002370338200941306a200541a0016a41306a290300370300200941286a200541a0016a41286a290300370300200941206a200541a0016a41206a290300370300200941186a200541a0016a41186a290300370300200941106a200541a0016a41106a290300370300200941086a200541a0016a41086a290300370300200920052903a00137030020092005290328370348200941d0006a200541286a41086a290300370300200941d8006a200541286a41106a290300370300200941e0006a200541286a41186a290300370300200041086a200841016a22093602000c010b0240024002400240024020070d002006210a0c010b20082007417f6a22094d0d012006200941e8006c6a41e8006a210a0b200a2006200841e8006c6a460d00200820074d0d04200a290338200256200a41c0006a290300220c200356200c2003511b0d01200a41e8006a2109200841e8006c20066a200a6b41987f6a210a0340200a450d01200741016a21072009290338210c200941c0006a210b200a41987f6a210a200941e8006a2109200c200256200b290300220c200356200c2003511b0d020c000b0b200541286a41186a2209200141186a290000370300200541286a41106a220a200141106a290000370300200541286a41086a220b200141086a290000370300200541a0016a41086a220e200441086a290300370300200541a0016a41106a220f200441106a290300370300200541a0016a41186a2210200441186a290300370300200541a0016a41206a2211200441206a290300370300200541a0016a41286a2212200441286a290300370300200541a0016a41306a2213200441306a29030037030020052001290000370328200520042903003703a00102402008200041046a280200470d00200020084101109601200041086a2802002108200028020021060b2006200841e8006c6a22072002370338200720052903a00137030020072005290328370348200741c0006a2003370300200741306a2013290300370300200741286a2012290300370300200741206a2011290300370300200741186a2010290300370300200741106a200f290300370300200741086a200e290300370300200741d0006a200b290300370300200741d8006a200a290300370300200741e0006a20092903003703000c010b200541a0016a41086a200441086a290300370300200541a0016a41106a200441106a290300370300200541a0016a41186a200441186a290300370300200541a0016a41206a200441206a290300370300200541a0016a41286a200441286a290300370300200541a0016a41306a200441306a290300370300200541286a41086a200141086a290000370300200541286a41106a200141106a290000370300200541286a41186a200141186a290000370300200520042903003703a0012005200129000037032820082007490d0302402008200041046a280200470d00200020084101109601200028020021060b2006200741e8006c6a220941e8006a2009200820076b41e8006c109e081a200941c0006a200337030020092002370338200941306a200541a0016a41306a290300370300200941286a200541a0016a41286a290300370300200941206a200541a0016a41206a290300370300200941186a200541a0016a41186a290300370300200941106a200541a0016a41106a290300370300200941086a200541a0016a41086a290300370300200920052903a00137030020092005290328370348200941d0006a200541286a41086a290300370300200941d8006a200541286a41106a290300370300200941e0006a200541286a41186a2903003703000b200041086a200841016a22093602000b0240200941e907490d00200041086a2009417f6a22093602002006200941e8006c6a220741106a2903002103200741086a290300210c20072d0000210a20072800012101200741046a280000210e20054180016a41186a220b200741306a29030037030020054180016a41106a2204200741286a29030037030020054180016a41086a2208200741206a290300370300200741186a2903002102200541a0016a41286a220f200741e0006a290300370300200541a0016a41206a2210200741d8006a2903003703002005200237038001200541a0016a41186a2211200741d0006a290300370300200541a0016a41106a2212200741c8006a290300370300200541a0016a41086a2213200741c0006a2903003703002005200e36000320052001360200200520072903383703a001200a4102460d03200541d8006a41086a22072008290300370300200541d8006a41106a22012004290300370300200541d8006a41186a220e200b290300370300200541286a41086a2013290300370300200541286a41106a22132012290300370300200541286a41186a22122011290300370300200541286a41206a22112010290300370300200541286a41286a2210200f2903003703002005200528000336007b200520052802003602782005200529038001370358200520052903a001370328200541186a2010290300370300200541106a2011290300370300200541086a201229030037030020052013290300370300200520052802783602202005200528007b3600232008200729030037030020042001290300370300200b200e290300370300200520052903583703800102400240200a410171450d00200541af016a2003370000200541bf016a20054188016a2d00003a00002005200c3700a701200520052800233600a301200520052802203602a00120052005290380013700b701200541286a200541a0016a10d006200535023042208620052802282207ad841007200528022c450d01200710350c010b2005200c37035820052003370360200c200384500d0020052005360278200541286a2005200541d8006a200541f8006a10f00220052903284201520d0020052903302103200541d8016a200541286a41106a290300370300200541d0016a2003370300200541a0016a41086a41003a0000200541a9016a2005290300370000200541b1016a200541086a290300370000200541b9016a200541106a290300370000200541c1016a200541186a290300370000200541033a00a00141b0b4cc004100200541a0016a10d4010b200541a0016a41086a41033a0000200541a9016a2005290300370000200541b1016a200541086a290300370000200541b9016a200541106a290300370000200541c1016a200541186a290300370000200541123a00a00141b0b4cc004100200541a0016a10d4010b2000280204210b200541a0016a41186a4200370300200541a0016a41106a22044200370300200541a0016a41086a22074200370300200542003703a00141a29bc800ad4280808080f000841001220a29000021032007200a41086a290000370300200520033703a001200a1035419cbac800ad4280808080c000841001220a290000210320054180016a41086a2200200a41086a2900003703002005200337038001200a103520042005290380012203370300200541286a41086a2007290300370300200541286a41106a2003370300200541286a41186a2000290300370300200520052903a001370328200541a0016a2006200910b106200541286aad428080808080048420053502a80142208620052802a0012207ad841002024020052802a401450d00200710350b0240200b450d00200b41e8006c450d00200610350b200541a0026a24000f0b2007200841f483ca001042000b20072008104d000b418484ca004113419884ca001064000b810b031d7f017e017f230041b0016b2202240041012103024020012d00000d002001411d6a2d000021042001411c6a2d000021052001411a6a2f00002106200141196a2d00002107200141186a2d00002108200141166a2f00002109200141156a2d0000210a200141146a2d0000210b200141126a2f0000210c200141116a2d0000210d200141106a2d0000210e2001410e6a2f0000210f2001410d6a2d000021102001410c6a2d000021112001410a6a2f00002112200141096a2d00002113200141086a2d00002114200141066a2f00002115200141056a2d00002116200141046a2d00002117200141026a2f0000211820012d00012103200141206a2d00002119200141216a2d0000211a2001411e6a2f0000211b20024190016a41186a221c420037030020024190016a41106a221d420037030020024190016a41086a22014200370300200242003703900141a29bc800ad4280808080f000841001221e290000211f2001201e41086a2900003703002002201f37039001201e103541ef9bc800ad4280808080f000841001221e290000211f200241c8006a41086a2220201e41086a2900003703002002201f370348201e1035201d2002290348221f370300200241f0006a41086a2001290300370300200241f0006a41106a201f370300200241f0006a41186a20202903003703002002200229039001370370200241c8006a200241f0006a412010d50120022d0048211e201c200241c8006a41196a290000370300201d200241c8006a41116a2900003703002001200241c8006a41096a2900003703002002200229004937039001410021010240201e4101470d00200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a2903003703002002200229039001370370410121010b200241206a201a3a00002002411f6a20193a00002002411d6a201b3b00002002411c6a20043a00002002411b6a20053a0000200241196a20063b0000200241186a20073a0000200241176a20083a0000200241156a20093b0000200241146a200a3a0000200241136a200b3a0000200241116a200c3b0000200241106a200d3a00002002410f6a200e3a00002002410d6a200f3b00002002410c6a20103a00002002410b6a20113a0000200241096a20123b0000200241086a20133a0000200220013a0021200220143a0007200220153b0005200220163a0004200220173a0003200220183b0001200220033a00002002413a6a200241f0006a41186a290300370100200241326a200241f0006a41106a2903003701002002412a6a200241f0006a41086a290300370100200241226a221d20022903703701000240200341ff01714101470d002001450d0020024101722201201d412010a0080d00200241c8006a41026a200141026a2d000022033a0000200220012f000022013b01482002410a6a2f0100211d2002410e6a2f0100211e200241126a2f01002105200241166a2f010021082002411a6a2f0100210b2002411e6a2f0100210e20022f01062111200041036a20033a0000200020013b0001200041206a201a3a00002000411e6a200e3b00002000411d6a201b3a00002000411c6a20043a00002000411a6a200b3b0000200041196a20063a0000200041186a20073a0000200041166a20083b0000200041156a20093a0000200041146a200a3a0000200041126a20053b0000200041116a200c3a0000200041106a200d3a00002000410e6a201e3b00002000410d6a200f3a00002000410c6a20103a00002000410a6a201d3b0000200041096a20123a0000200041086a20133a0000200041066a20113b0000200041056a20153a0000200041046a20163a0000410021030c010b410121030b200020033a0000200241b0016a24000bba0a03047f017e057f230041f0006b22022400200241c0006a41186a4200370300200241c0006a41106a22034200370300200241c0006a41086a220442003703002002420037034041a29bc800ad4280808080f000841001220529000021062004200541086a29000037030020022006370340200510354189eaca00ad4280808080f00084100122052900002106200241e0006a41086a2207200541086a2900003703002002200637036020051035200320022903602206370300200241206a41086a2004290300370300200241206a41106a2006370300200241206a41186a200729030037030020022002290340370320200241c0006a200241206a10fe0102400240200228024022080d00410021092002410036021820024201370310410121084100210a0c010b200220022902442206370214200220083602102006422088a7210a2006a721090b200241c0006a41186a4200370300200241c0006a41106a220b4200370300200241c0006a41086a220542003703002002420037034041a29bc800ad4280808080f00084100122032900002106200241e0006a41086a2204200341086a2900003703002002200637036020031035200520042903003703002002200229036037034041a99bc800ad4280808080a001841001220329000021062004200341086a2900003703002002200637036020031035200b20022903602206370300200241206a41086a2005290300370300200241206a41106a2006370300200241206a41186a200429030037030020022002290340370320200241086a200241206a412010c00141002104024002400240024002400240200a200228020c410020022802081b4f0d00024002400240200a41014b0d00200a0e020201020b41002104200a210503402005410176220320046a22072004200820074105746a2001412010a0084101481b2104200520036b220541014b0d000b0b200820044105746a2001412010a0082205450d022005411f7620046a21040b200241c0006a41186a200141186a290000370300200241c0006a41106a200141106a290000370300200241c0006a41086a200141086a29000037030020022001290000370340200a2004490d040240200a2009470d00200241106a20094101108a0120022802142109200228021021080b200820044105746a220541206a2005200a20046b410574109e081a20052002290340370000200541186a200241c0006a41186a2203290300370000200541106a200241c0006a41106a2207290300370000200541086a200241c0006a41086a22042903003700002002200a41016a220a3602182003420037030020074200370300200442003703002002420037034041a29bc800ad4280808080f00084100122012900002106200241e0006a41086a2205200141086a290000370300200220063703602001103520042005290300370300200220022903603703404189eaca00ad4280808080f000841001220129000021062005200141086a2900003703002002200637036020011035200b2002290360370000200b41086a2005290300370000200241206a41086a2004290300370300200241206a41106a2007290300370300200241206a41186a200329030037030020022002290340370320200241203602442002200241206a3602402008200a200241c0006a109802200941ffffff3f710d020c030b20004183323b0100200041086a410a360200200041046a41a99bc800360200200041026a410f3a0000200941ffffff3f71450d04200810350c040b200941ffffff3f71450d010b200810350b200041043a00000c010b2004200a104d000b200241f0006a24000b130020004108360204200041a884ca003602000b130020004112360204200041c089ca003602000b8c0201037f024002400240024002400240024020012802000e0400010203000b41012102410110332201450d05200141003a0000410121030c040b410110332202450d04200241013a00002001280204210320024101410510372202450d042002200336000120012802082104410a210320024105410a10372201450d04200120043600050c020b41012102410110332201450d03200141023a0000410121030c020b410110332202450d02200241033a00002001280204210320024101410510372202450d022002200336000120012802082104410a210320024105410a10372201450d02200120043600050b410921020b2000200236020820002003360204200020013602000f0b103c000bf33010017f017e017f027e097f017e027f017e037f057e017f017e017f047e017f027e230041d0046b22052400200541d8016a4201427f420020032004844200521b2206200342005220044200552004501b22071b4200200620071b4201427f420020012002844200521b2206200142005220024200552002501b22071b4200200620071b108408200541d8016a41086a290300210820052903d801210902402002427f550d00200541003602d401200541c0016a20012002427f427f200541d4016a10850842ffffffffffffffffff00200541c0016a41086a29030020052802d40122071b2102427f20052903c00120071b21010b02402004427f550d00200541003602bc01200541a8016a20032004427f427f200541bc016a10850842ffffffffffffffffff00200541b0016a29030020052802bc0122071b2104427f20052903a80120071b21030b0240024002400240024002400240024002400240024002402002427f570d002004427f570d01200541f8006a2003420020014200108408200541e8006a200342002002420010840820054198016a200442002001420010840820054188016a20044200200242001084082005290388012204200529039801220220052903682203200541f8006a41086a2903007c22017c2206200254ad20054198016a41086a2903007c22022001200354ad200541e8006a41086a2903007c7c22037c2201200454ad20054188016a41086a2903007c22042003200254ad7c22022004540d0a2005290378210320054198026a4200370300200541a0026a42003703002005420037039002200542808090bbbad6adf00d37038802410021070340200741086a220a4128460d0b20054188026a20076a210b200a2107200b290300500d000b200520023703c002200520013703b802200520063703b002200520033703a802200541c8026a41186a20054188026a41186a290300370300200541c8026a41106a20054188026a41106a290300370300200541c8026a41086a20054188026a41086a29030037030020052005290388023703c802200541a8026a41186a2107200541a8026a41086a210c41c002210a024003400240200a41406a220a41c000470d002003210441c000210a0c020b20072903002104200741786a21072004500d000b0b200a200479a76b210b200541e0026a210741c002210a024002400340200a41406a220a41c000460d0120072903002104200741786a21072004500d000c020b0b41c000210a20052903c80221040b200a200479a76b2207450d02200b2007490d030240200741c100490d00200541e8026a41106a200c41106a290300370300200541e8026a41086a200c41086a2903003703002005200c2903003703e80220054180036a41186a220a200541c8026a41186a29030037030020054180036a41106a220c200541c8026a41106a29030037030020054180036a41086a220d200541c8026a41086a290300370300200520052903c802370380032007417f6a220e410676210f02400240024002400240200e41ff014b0d00200b417f6a4106762210200f6b210b200f41016a211120054180036a200f4103746a22122903002104200541a0036a41186a200a290300370300200541a0036a41106a200c290300370300200541a0036a41086a200d29030037030020052005290380033703a003200541e8036a41106a4200370300200541e8036a41186a4200370300200542003703f003200520047922133703e8032013a72114200541e8036a41086a210d4100210702400340200741086a220a4120460d01200d20076a210c200a2107200c290300500d000b418b80cc00412641dc80cc00103f000b200541a8046a4200370300200541a0046a420037030020054190046a41086a420037030020054200370390042014410676220d41037421072014413f71220cad2104200541a0036a210a034020054190046a20076a200a290300200486370300200a41086a210a200741086a22074120470d000b0240200c450d00200d4103742107420020137d423f83210420054190046a41086a210d200541a0036a210a0340200d20076a220c200c290300200a2903002004887c370300200a41086a210a200741086a22074118470d000b0b20054180036a41186a20054190046a41186a29030037030020054180036a41106a20054190046a41106a29030037030020054180036a41086a20054190046a41086a290300370300200520052903900437038003200541b0046a41106a200541e8026a41086a290300370300200541b0046a41186a200541e8026a41106a290300370300200520052903e8023703b804200520033703b004200541e8036a41106a4200370300200541e8036a41186a4200370300200542003703f003200541c00020146b2215ad22013703e80320032013423f832216862102200541e8036a41086a210d4100210702400340200741086a220a4120460d01200d20076a210c200a2107200c290300500d000b418b80cc00412641dc80cc00103f000b200541a8046a4200370300200541a0046a420037030020054190046a41086a420037030020054200370390042015413f71210c2015410676210d0240201541ff014b0d00200d4103742107200cad210420054190046a210a0340200a200541b0046a20076a290300200488370300200a41086a210a200741086a22074120470d000b0b0240200c450d00200d41016a41034b0d00200d410374210a420020017d423f832104200541b0046a41086a210c20054190046a2107034020072007290300200c200a6a2903002004867c370300200741086a2107200a41086a220a4118470d000b0b200520052903a8043703c003200520052903a0043703b80320052005290398043703b00320052005290390043703a803200520023703a003200541e0036a4200370300200541c8036a41106a4200370300200541c8036a41086a4200370300200542003703c803200f417f6a220741034b0d01200f41026a2117200541a0036a2010200f6b4103746a221841086a21192012290300221a201a792204423f83221b86221c42ffffffff0f83211d201c422088210120054180036a20074103746a290300211e41c0002004a76b221f413f71ad2120200541e8036a41106a21212005290398032122200529039003212320052903880321242005290380032125200e4180024921260340200b221520116a220741054f0d03427f21020240200541a0036a20074103746a22122903002204201a5a0d002015200f6a220a41044b0d052001500d0c200541a0036a200a4103746a2903002202201b86220342ffffffff0f8321062003422088210342002002202088201f413f4b1b2004201b868422272027200180220220017e7d2104024003400240200242ffffffff0f560d002002201d7e2004422086200384580d020b2002427f7c2102200420017c2204428080808010540d000b0b20274220862003842002201c7e7d22272027200180220320017e7d2104024003400240200342ffffffff0f560d002003201d7e2004422086200684580d020b2003427f7c2103200420017c220442ffffffff0f580d000b0b2007417e6a220741044b0d0d20274220862006842003201c7e7d201b882104200320024220867c2102200541a0036a20074103746a29030021060340200541d8006a20024200201e4200108408200620052903585a2004200541d8006a41086a29030022035a20042003511b0d012002427f7c21022004201a7c22032004542107200321042007450d000b0b200541c8006a2025420020024200108408200541386a2024420020024200108408200541286a2023420020024200108408200541186a20224200200242001084082005200529034822283703e803200520052903382203200541c8006a41086a2903007c22043703f003200520052903282206200541386a41086a2903002004200354ad7c7c22033703f803200520052903182227200541286a41086a2903002003200654ad7c7c2203370380042005200541186a41086a2903002003202754ad7c37038804201541064f0d0d2026450d0e024020174128201541037422106b410376220e200e20174b1b220d450d00200541a0036a20106a22072007290300220320287d22063703002006200356210c0240200d4101460d004102210a2021210b2019210703402007200729030022032004200cad4201837c22067d22273703002006200454202720035672210c200a200d4f0d01200a41016a210a200741086a2107200b2903002104200b41086a210b0c000b0b200c450d004100210b02402011200e200e20114b1b220d450d0020054180036a210a201821074100210c0340200720072903002204200a2903002203200bad42ff01837c22067c22273703002006200354202720045472210b200741086a2107200a41086a210a200c41016a220c200d490d000b0b2002427f7c210220122012290300200bad7c3703000b201541034b0d05201520154100476b210b200541c8036a20106a2002370300201841786a2118201941786a21192015450d0f0c000b0b200f410441dc80cc001042000b2007410441dc80cc001042000b2007410541dc80cc001042000b200a410541dc80cc001042000b2015410441dc80cc001042000b200541e8036a41186a200541a8026a41186a290300370300200541e8036a41106a200541a8026a41106a290300370300200541e8036a41086a200541a8026a41086a290300370300200520052903a8023703e80302400240024020052903c80222042004792203423f83221e86221a4220882204500d00201a42ffffffff0f832102200529038004210641c0002003a76b220741c000490d012004422086211d2006201e86220342ffffffff0f8321282003422088211b42002103420021064200212742002101024003400240200142ffffffff0f560d0020032006201b84580d020b200320027d21032006201d7c21062001427f7c2101202720047c2227428080808010540d000b0b201b2001201a7e7d22272027200480220320047e7d2106024003400240200342ffffffff0f560d00200320027e2006422086202884580d020b2003427f7c2103200620047c2206428080808010540d000b0b2005200320014220867c37038004427f201e8620274220862028842003201a7e7d83221d201d200480220320047e7d210120052903f803201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b2006201d422086842003201a7e7d221d201d200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703f803427f201e86201d4220862027842001201a7e7d83221d201d200480220320047e7d210120052903f003201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b2006201d422086842003201a7e7d221d201d200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703f003427f201e86201d4220862027842001201a7e7d83221d201d200480220320047e7d210120052903e803201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b2006201d422086842003201a7e7d22012001200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703e8030c020b41d0fecb00411941dc80cc00103f000b20062007413f71ad221d8822282028200480220320047e7d21012006201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b20284220862006842003201a7e7d22282028200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703800420052903f8032206201d88427f201e8620284220862027842001201a7e7d838422282028200480220320047e7d21012006201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b20284220862006842003201a7e7d22282028200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703f80320052903f0032206201d88427f201e8620284220862027842001201a7e7d838422282028200480220320047e7d21012006201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b20284220862006842003201a7e7d22282028200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703f00320052903e8032206201d88427f201e8620284220862027842001201a7e7d8384221d201d200480220320047e7d21012006201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b201d4220862006842003201a7e7d22012001200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703e8030b20054190046a41186a200541e8036a41186a29030037030020054190046a41106a200541e8036a41106a29030037030020054190046a41086a200541e8036a41086a290300370300200520052903e803370390040c090b41e9fecb00413541dc80cc00103f000b41e9fecb00413541dc80cc00103f000b41fbffcb00411041dc80cc00103f000b200541a8046a4200370300200541a0046a420037030020054198046a420037030020054200370390040c050b41c080cc00411941dc80cc00103f000b2007410541dc80cc001042000b2015410541dc80cc001059000b2017410541dc80cc001058000b200541e8036a41206a200541a0036a41206a290300370300200541e8036a41186a200541a0036a41186a2903002204370300200541e8036a41106a200541a0036a41106a2903002202370300200541e8036a41086a200541a0036a41086a2903002203370300200520052903a00322013703e803200520012016883703b004200520032016883703b804200520022016883703c004200520042016883703c804024002402014450d00420020137d423f8321044101210703402007417f6a220a41034b0d02200541b0046a200a4103746a220a200a290300200541e8036a20074103746a29030020048684370300200720074104496a220a41044b0d01200741034b210b200a2107200b450d000b0b20054190046a41086a200541c8036a41086a29030037030020054190046a41106a200541c8036a41106a29030037030020054190046a41186a200541c8036a41186a290300370300200520052903c803370390040c010b200a410441dc80cc001042000b200541e8016a41086a20054190046a41086a2903002204370300200541e8016a41106a20054190046a41106a2903002202370300200541e8016a41186a20054190046a41186a2903002203370300200520052903900422013703e801200541e8036a41186a2003370300200541e8036a41106a220c2002370300200541e8036a41086a2004370300200520013703e8034100210702400340200741086a220a4118460d01200c20076a210b200a2107200b290300500d000c020b0b200541086a20092008422520052903e80320052903f003220442005322071b4200200420071b1084082004427f570d00200541106a2903002104200529030821020c010b428080808080808080807f42ffffffffffffffffff00200842005322071b21044200427f20071b21020b2000200237030020002004370308200541d0046a24000bb10503027f017e047f230041d0006b2202240041a3edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541fe99ca00ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b920503027f017e067f230041d0006b2202240041a8e7cb00ad4280808080f00184100122032900002104200241086a200341086a290000370300200220043703002003103541b7e7cb00ad4280808080c00184100122032900002104200241106a41086a200341086a2900003703002002200437031020031035200220003703302002200241306aad42808080808001841003220329000037033820031035200241cc006a200241306a41086a3602002002200241386a41086a3602442002200241306a3602482002200241386a360240200241206a200241c0006a107b02400240024002402002280228220541206a2206417f4c0d00200228022021070240024020060d0041002108410121030c010b200610332203450d02200621080b024002402008410f4d0d00200821090c010b200841017422094110200941104b1b22094100480d03024020080d002009103322030d010c050b20082009460d0020032008200910372203450d040b20032002290300370000200341086a200241086a2903003700000240024020094170714110460d00200921080c010b200941017422084120200841204b1b22084100480d0320092008460d0020032009200810372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821090c010b200541206a22092005490d032008410174220a2009200a20094b1b22094100480d0320082009460d0020032008200910372203450d040b200341206a20072005109d081a02402002280224450d00200710350b200220013602402006ad4220862003ad84200241c0006aad4280808080c00084100202402009450d00200310350b200241d0006a24000f0b1044000b1045000b103e000b103c000be91305057f017e047f027e037f230041f0006b22052400200541c0006a41186a22064200370300200541c0006a41106a22074200370300200541c0006a41086a220842003703002005420037034041a8e7cb00ad4280808080f0018410012209290000210a200541e0006a41086a220b200941086a2900003703002005200a370360200910352008200b2903003703002005200529036037034041b697ca00ad4280808080d0018410012209290000210a200b200941086a2900003703002005200a3703602009103520072005290360220a370300200541206a41086a22092008290300370300200541206a41106a220c200a370300200541206a41186a220d200b29030037030020052005290340370320200541186a200541206a412041b0b4cc0041004100108a02024002400240024002400240024020052802184101470d0041e192ca00210b410d2108410221070c010b2006420037030020074200370300200842003703002005420037034041d1c4c700ad4280808080e0008410012206290000210a2008200641086a2900003703002005200a3703402006103541e7c4c700ad4280808080e0008410012206290000210a200b200641086a2900003703002005200a3703602006103520072005290360220a37030020092008290300370300200c200a370300200d200b29030037030020052005290340370320200541106a200541206a412010c0012005280214410020052802101b2109024020034101460d00200541206a210e0c030b200541c0006a41186a22064200370300200541c0006a41106a220c4200370300200541c0006a41086a220842003703002005420037034041a8e7cb00ad4280808080f00184220f1001220d290000210a200541e0006a41086a220b200d41086a2900003703002005200a370360200d10352008200b2903003703002005200529036037034041f499ca00ad4280808080a0018422101001220d290000210a200b200d41086a2900003703002005200a370360200d103520072005290360370000200741086a220d200b290300370000200541206a41086a220e2008290300370300200541206a41106a2211200c290300370300200541206a41186a2212200629030037030020052005290340370320200541086a200541206a412010c0012005280208450d01200528020c20094d0d0141da92ca00210b41072108410321070b20004183203b0100200041086a2008360200200041046a200b360200200041026a20073a0000200141046a280200220b450d02200b41286c450d02200128020010350c020b20064200370300200c42003703002008420037030020054200370340200f10012213290000210a200b201341086a2900003703002005200a370360201310352008200b29030037030020052005290360370340201010012213290000210a200b201341086a2900003703002005200a3703602013103520072005290360370000200d200b290300370000200e20082903003703002011200c29030037030020122006290300370300200520052903403703202005200920024101746a360240200541206aad4280808080800484200541c0006aad4280808080c000841002200541206a210e0b200128020821082001280204210c2001280200210d200541c0006a41186a22114200370300200541c0006a41106a22124200370300200541c0006a41086a220142003703002005420037034041a8e7cb00ad4280808080f0018410012206290000210a200541e0006a41086a220b200641086a2900003703002005200a370360200610352001200b2903003703002005200529036037034041b697ca00ad4280808080d0018410012206290000210a200b200641086a2900003703002005200a3703602006103520072005290360370000200741086a200b290300370000200541206a41086a2001290300370300200541206a41106a2012290300370300200541206a41186a201129030037030020052005290340370320200541003602482005420137034041041033220b450d02200541043602442005200b360240200b200936000020054104360248200b410441081037220b450d0220054108360244200b20023600042005200b360240200541083602482008200541c0006a10772005280248210702402008450d00200d200841286c6a2106200d210b0340024002402005280244220220076b4120490d00200741206a210820052802402101200221090c010b200741206a22082007490d04200241017422012008200120084b1b22094100480d040240024020020d00024020090d00410121010c020b2009103322010d010c070b2005280240210120022009460d0020012002200910372201450d060b20052009360244200520013602400b200120076a2207200b290000370000200741186a200b41186a290000370000200741106a200b41106a290000370000200741086a200b41086a29000037000020052008360248200b41206a290300210a0240200920086b41074b0d00200841086a22072008490d04200941017422022007200220074b1b22074100480d040240024020090d00024020070d00410121010c020b200710332201450d070c010b20092007460d0020012009200710372201450d060b20052007360244200520013602400b200120086a200a3700002005200841086a22073602482006200b41286a220b470d000b0b2005280244210b0240024020034101460d0002400240200b2007460d00200528024021080c010b200741016a220b2007490d0420074101742208200b2008200b4b1b220b4100480d040240024020070d00410021070240200b0d00410121080c020b200b10332208450d070c010b200528024021082007200b460d0020082007200b10372208450d060b2005200b360244200520083602400b200820076a41003a00002005200741016a22073602480c010b02400240200b2007460d00200528024021080c010b200741016a220b2007490d0320074101742208200b2008200b4b1b220b4100480d030240024020070d00410021070240200b0d00410121080c020b200b10332208450d060c010b200528024021082007200b460d0020082007200b10372208450d050b2005200b360244200520083602400b200820076a41013a00002005200741016a22013602480240200b20016b41034b0d00200141046a22092001490d03200b41017422022009200220094b1b22094100480d0302400240200b0d00024020090d00410121080c020b200910332208450d060c010b200b2009460d002008200b200910372208450d050b20052009360244200520083602400b200820016a20043600002005200741056a22073602482005280244210b200528024021080b200ead42808080808004842007ad4220862008ad8410020240200b450d00200810350b0240200c450d00200c41286c450d00200d10350b200041043a00000b200541f0006a24000f0b103e000b103c000bff0201037f230041206b2203240002400240200241c4006c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b20034100360208200320053602002003200436020420022003107702402002450d00200241c4006c210203400240024020012d00004101460d00200341003a00102003200341106a410110782003200141046a2802003602102003200341106a410410780c010b200341013a00102003200341106a41011078412010332204450d042003422037021420032004360210200341106a200141016a41201078200328021421042003200328021022052003280218107802402004450d00200510350b0240200141216a2d00004101460d00200341003a00102003200341106a410110780c010b200341013a00102003200341106a410110782003200141226a412010780b200141c4006a2101200241bc7f6a22020d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1044000b1045000b290020004101360204200041086a200128020420012802006b41a0016e2201360200200020013602000ba50201057f230041d0006b21020240200128020022032001280204470d00200041003602000f0b2001200341a0016a3602002002200329004237012a2002200329004a370132200241086a41086a220120022903303703002002200329005237013a200241086a41106a220420022903383703002002200328005a360142200220032f005e3b0146200241086a41186a22052002290340370300200220032f00403b012820022002290328370308200241286a41186a22062005290300370300200241286a41106a22052004290300370300200241286a41086a220420012903003703002002200229030837032820002003360200200020022903283702042000410c6a2004290300370200200041146a20052903003702002000411c6a20062903003702000bf30801087f230041f0006b2103024002402001280200220420012802042205460d00200241016a210603402001200441a0016a2202360200200341003a0068200441c0006a2d00002107200341013a0068200320073a0048200441c1006a2d00002107200341023a0068200320073a0049200441c2006a2d00002107200341033a0068200320073a004a200441c3006a2d00002107200341043a0068200320073a004b200441c4006a2d00002107200341053a0068200320073a004c200441c5006a2d00002107200341063a0068200320073a004d200441c6006a2d00002107200341073a0068200320073a004e2003200441c7006a2d00003a004f200341083a0068200441c8006a2d00002107200341093a0068200320073a0050200441c9006a2d000021072003410a3a0068200320073a0051200441ca006a2d000021072003410b3a0068200320073a0052200441cb006a2d000021072003410c3a0068200320073a0053200441cc006a2d000021072003410d3a0068200320073a0054200441cd006a2d000021072003410e3a0068200320073a0055200441ce006a2d000021072003410f3a0068200320073a00562003200441cf006a2d00003a0057200341103a0068200441d0006a2d00002107200341113a0068200320073a0058200441d1006a2d00002107200341123a0068200320073a0059200441d2006a2d00002107200341133a0068200320073a005a200441d3006a2d00002107200341143a0068200320073a005b200441d4006a2d00002107200341153a0068200320073a005c200441d5006a2d00002107200341163a0068200320073a005d200441d6006a2d00002107200341173a0068200320073a005e2003200441d7006a2d00003a005f200341183a0068200441d8006a2d00002107200341193a0068200320073a0060200441d9006a2d000021072003411a3a0068200320073a0061200441da006a2d000021072003411b3a0068200320073a0062200441db006a2d000021072003411c3a0068200320073a0063200441dc006a2d000021072003411d3a0068200320073a0064200441dd006a2d000021072003411e3a0068200320073a0065200441de006a2d000021072003411f3a0068200320073a0066200441df006a2d00002107200341203a0068200320073a0067200341286a41086a22072003290350370300200341286a41106a22082003290358370300200341286a41186a2209200329036037030020032003290348370328200341086a41086a220a2007290300370300200341086a41106a22072008290300370300200341086a41186a2208200929030037030020032003290328370308200341c8006a41186a2008290300370300200341c8006a41106a2007290300370300200341c8006a41086a200a290300370300200320032903083703482006417f6a2206450d022002210420052002470d000b0b200041003602000f0b20002004360200200020032903483702042000410c6a200341d0006a290300370200200041146a200341d8006a2903003702002000411c6a200341e0006a2903003702000b130020004101360204200041e09aca003602000b3400200041a8e7cb0036020420004100360200200041146a4106360200200041106a41d49bca00360200200041086a420f3702000b2c01017f02404108103322020d001045000b20004288808080800137020420002002360200200242003700000b2201017f230041106b22022400200241003602002000200210db04200241106a24000b2201017f230041106b22022400200241003602002000200210db06200241106a24000b130020004102360204200041eca4ca003602000b3400200041a3edcb0036020420004100360200200041146a4107360200200041106a41b8adca00360200200041086a42073702000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241003600000bec0101057f230041306b2201240002400240200028020422020d00410021032001411c6a41003602002001410036020c0c010b2000410c6a280200210302400240200041086a28020022040d00200221000c010b2004210020022105034020052802880b21052000417f6a22000d000b200221000340200020002f01064102746a41880b6a28020021002004417f6a22040d000b200521020b200141246a20002f0106360200200141206a41003602002001411c6a200036020020014100360218200142003703102001200236020c200141003602080b20012003360228200141086a108f03200141306a24000bd564030d7f017e0c7f230041d0036b220424004100210520044100360280012004200236027c200420013602784104210602400240024002400240024002400240024002400240024002400240024002400240024002400240024020024104490d00200441043602800120012800004180c2cdeb06460d0141012101410021070c030b200441013a00b801200441a4036a41013602002004420137029403200441acfdcb0036029003200441363602ec022004200441e8026a3602a0032004200441b8016a3602e80220044180026a20044190036a10410c010b4104210602400240024002402002417c714104460d00200241074d0d0220044108360280010240200128000422084101460d004102210141042106410021070c060b20044190036a200441f8006a10b107410421062004280290034101470d0141002105410021070c030b200441013a00b801200441a4036a41013602002004420137029403200441acfdcb0036029003200441363602ec022004200441e8026a3602a0032004200441b8016a3602e80220044180026a20044190036a10410c030b20044190036a4104722101410021094100210a41002105410021074100210b0340200441b8016a41286a220c200141286a290200370300200441b8016a41206a220d200141206a290200370300200441b8016a41186a220e200141186a290200370300200441b8016a41106a220f200141106a290200370300200441b8016a41086a2210200141086a2902003703002004200129020022113703b80102402011a741ff01712212417e6a410c4f0d0041002108024002400240024002400240024002400240024002400240024020120e100c0c000102030405060708090a0b0c0c0c0b410121080c0b0b410221080c0a0b410321080c090b410421080c080b410521080c070b410621080c060b410721080c050b410821080c040b410921080c030b410a21080c020b410b21080c010b410c21080b024002400240200b41ff0171221320084d0d00411321010c010b41002108024002400240024002400240024002400240024002400240024020120e100c0c000102030405060708090a0b0c0c0c0b410121080c0b0b410221080c0a0b410321080c090b410421080c080b410521080c070b410621080c060b410721080c050b410821080c040b410921080c030b410a21080c020b410b21080c010b410c21080b20132008470d01411421010b024002402012410e4b0d00024002400240024002400240024002400240024002400240024020120e0f0001020304050607080e090e0a0b0c000b200441c0016a280200450d0d20042802bc0110350c140b0240200441c0016a280200450d0020042802bc0110350b200441cc016a280200450d0c200441c8016a28020010350c130b20042802bc0121090240200441c4016a2802002212450d002012410474210a2009211203400240201241046a280200450d00201228020010350b201241106a2112200a41706a220a0d000b0b200441c0016a28020041ffffffff0071450d0b200910350c120b20042802bc0121090240200441b8016a410c6a2802002212450d00201241286c210a2009211203400240201241046a280200450d00201228020010350b0240201241106a280200450d002012410c6a28020010350b201241286a2112200a41586a220a0d000b0b200441c0016a2802002212450d0a201241286c450d0a200910350c110b200441c0016a28020041ffffffff0371450d0920042802bc0110350c100b200441c0016a2802002212450d082012410c6c450d0820042802bc0110350c0f0b200441c0016a2802002212450d072012410c6c450d0720042802bc0110350c0e0b20042802bc01210f0240200441c4016a2802002212450d00200f20124104746a210e200f210d03400240200d280208220a450d00200d2802002112200a410474210a0340024020122d00004109470d000240201241046a220c280200220928020441ffffffff0371450d0020092802001035200c28020021090b200910350b201241106a2112200a41706a220a0d000b0b200d41106a21120240200d41046a28020041ffffffff0071450d00200d28020010350b2012210d2012200e470d000b0b200441c0016a28020041ffffffff0071450d06200f10350c0d0b20042802bc0121090240200441c4016a2802002212450d00201241146c210a2009211203400240201241046a280200450d00201228020010350b201241146a2112200a416c6a220a0d000b0b200441c0016a2802002212450d05201241146c450d05200910350c0c0b200441b8016a41047210b207200441c0016a2802002212450d042012411c6c450d0420042802bc0110350c0b0b200441b8016a41047210b307200441c0016a2802002212450d03201241186c450d0320042802bc0110350c0a0b200441b8016a41047210b407200441c0016a2802002212450d022012411c6c450d0220042802bc0110350c090b024020042802bc012212450d00200441c0016a280200450d00201210350b0240200441cc016a280200220c450d000240200441d4016a2802002212450d002012410c6c210a200c21120340024020122802002209450d00201241046a280200450d00200910350b2012410c6a2112200a41746a220a0d000b0b200441d0016a2802002212450d002012410c6c450d00200c10350b200441dc016a280200220f450d010240200441e4016a2802002212450d00200f20124104746a210e200f210d0340200d220c41106a210d0240200c2802042212450d000240200c410c6a280200220a450d00200a410c6c210a0340024020122802002209450d00201241046a280200450d00200910350b2012410c6a2112200a41746a220a0d000b0b200c41086a2802002212450d002012410c6c450d00200c28020410350b200d200e470d000b0b200441e0016a28020041ffffffff0071450d01200f10350c080b0240200441c0016a280200450d0020042802bc0110350b0240200441cc016a2802002212450d00200441d0016a280200450d00201210350b200441dc016a28020041ffffffff0071450d00200441d8016a28020010350b0c060b4100210b02400240024002400240024002400240024002400240024020120e100c0c000102030405060708090a0b0c0c0c0b4101210b0c0b0b4102210b0c0a0b4103210b0c090b4104210b0c080b4105210b0c070b4106210b0c060b4107210b0c050b4108210b0c040b4109210b0c030b410a210b0c020b410b210b0c010b410c210b0b20044180026a41286a2208200c29030037030020044180026a41206a220c200d29030037030020044180026a41186a220d200e29030037030020044180026a41106a220e200f29030037030020044180026a41086a220f2010290300370300200420042903b80137038002024020052007470d00200541016a22122005490d0720092012200920124b1bad42307e2211422088a70d072011a722124100480d0702400240024020050d0020120d01410421060c020b200a2012460d010240200a0d0020120d01410421060c020b2006200a201210372206450d180c010b201210332206450d170b201241306e21070b2006200a6a2212200429038002370200201241286a2008290300370200201241206a200c290300370200201241186a200d290300370200201241106a200e290300370200201241086a200f290300370200200941026a2109200a41306a210a200541016a210520044190036a200441f8006a10b1072004280290034101460d020c000b0b4108200241c0fdcb001058000b0240024020042d0094030d002006200541306c6a210b20062101024003400240200b2001470d00410021090c020b20012d00002112200141306a220a21012012410c470d000b200a415c6a28020021090b2006200541306c6a210b20062101024003400240200b2001470d00410021010c020b20012d00002112200141306a220a210120124104470d000b200441f0006a200a41546a10bf03200428027421010b024020092001470d00410021014101210841e100210b41f3da01210a410021120c050b2006200510f40641012112411a21012007450d01200741306c450d01200610350c040b2004280294032201411076210a2001410876210b20044190036a41106a28020021092004419c036a280200210c20044190036a41086a28020021080c020b0c020b2004280280022108200428028402210c20042802880221094105210141002105410021074100210a4100210b0b2006200510f4064101211202402007450d00200741306c450d00200610350b20092107200c21060b200a411074200b41ff017141087472200141ff01717221100240024002402012450d00200621020c010b2004280280012002460d01200441003a00b801200441a4036a41013602002004420137029403200441acfdcb0036029003200441363602ec022004200441e8026a3602a0032004200441b8016a3602e80220044180026a20044190036a1041200428028002210820042802840221022006200510f406410521102007450d00200741306c450d00200610350b02402002450d00201041ff01714105470d00200810350b200041a0d3cb0036020420004101360200200041086a41163602000c0f0b4100210a200441b0016a4100360200200441a0016a420037030020044198016a4280808080c00037030020044188016a4200370300200442043703a801200442013703900120044280808080c0003703800120044204370378200541306c211241002102024002400340024020122002470d00410421124100210b0c020b200620026a2101200241306a220b210220012d00004102470d000b200441e8006a2006200b6a41546a10bf032004280268210b200428026c21012004410036029803200442043703900320044190036a41002001108c012004280290032102200428029803210c02402001450d002001410474210d2002200c4104746a21020340200b221241086a2802002201417f4c0d032012410c6a2d0000210e2012280200210f0240024020010d004100210b410121090c010b200110332209450d082001210b0b02400240200b2001490d00200b210a0c010b200b410174220a2001200a20014b1b220a4100480d050240200b0d00200a10332209450d150c010b0240200b200a470d00200b210a0c010b2009200b200a10372209450d140b201241106a210b2009200f2001109d0821092002410d6a2012410d6a2d00003a00002002410c6a200e3a0000200241086a2001360200200241046a200a360200200220093602002002410e6a20042f0180023b0100200241106a2102200c41016a210c200d41706a220d0d000b20042802900321020b200428029403410020021b210b200c410020021b210a2002410420021b21120b024020042802a4012201450d00200428029c0121022001410474210103400240200241046a280200450d00200228020010350b200241106a2102200141706a22010d000b0b024020042802a00141ffffffff0071450d00200428029c0110350b2004200a3602a4012004200b3602a0012004201236029c01200541306c2112410021094100210203404101210b20122002460d03200620026a2101200241306a220a210220012d00004103470d000b200441e0006a2006200a6a41546a10bf0320042802602202450d024100210f20042802642201450d03200141286c21012002411c6a2102200441f8006a410c6a2113410021094100210f4101210b034002400240024002400240024002402002417c6a2d00000e0401020300010b200441f8006a2002417d6a22122d00002002417e6a220a2d000041017110b507200a2d0000210a20122d0000210c2009200f470d04200941016a22122009490d082009410174220d2012200d20124b1b220e200e6a2212200e490d0820124100480d080240024020090d0020120d014101210b0c050b200d2012460d040240200d0d0020120d014101210b0c050b200b200d20121037220b450d180c040b20121033220b450d170c030b200441f8006a200228020010b6070c040b20044190036a41086a220a200241086a28020036020020042002290200370390030240200428028c012212200428028801470d00201320124101108701200428028c0121120b2004280284012012410c6c6a2212200429039003370200201241086a200a2802003602002004200428028c0141016a36028c010c030b20044190036a41086a220a200241086a280200360200200420022902003703900302402004280280012212200428027c470d00200441f8006a2012410110870120042802800121120b20042802782012410c6c6a2212200429039003370200201241086a200a280200360200200420042802800141016a360280010c020b2012410176210f0b200b20094101746a2212200a4101713a00012012200c3a0000200941016a21090b200241286a2102200141586a2201450d040c000b0b1044000b103e000b4100210f0b200541306c2112410021020240034020122002460d01200620026a2101200241306a220a210220012d00004104470d000b200441d8006a2006200a6a41546a10bf03200428025c2201450d0020042802582102200141027421010340200441f8006a200228020010b607200241046a21022001417c6a22010d000b0b200541306c2112410021020240034020122002460d01200620026a2101200241306a220a210220012d00004105470d000b200441d0006a2006200a6a41546a10bf032004280254410c6c2212450d0020042802502102200441f8006a410c6a210d0340200241086a2101024002400240200241046a2802004101470d0020042001280200220a3602e8022002280200220c200a4b0d010b200441003602b8010c010b200441023602a4032004420237029403200441d0aacc00360290032004410136028c0220044101360284022004200c3602f802200420044180026a3602a0032004200441f8026a360288022004200441e8026a36028002200441b8016a20044190036a104120042802b801450d00200441b8016a21020c0b0b2002290200211120044190036a41086a220a200128020036020020042011370390030240200428028c012201200428028801470d00200d20014101108701200428028c0121010b2002410c6a21022004280284012001410c6c6a2201200429039003370200200141086a200a2802003602002004200428028c0141016a36028c01201241746a22120d000b0b200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d00004106470d000b200441c8006a200a10bf03200428024c2201450d00200428024821022001410c6c2112034020044190036a200210b7070240200428029003450d0020044190036a21020c0b0b2002290200211120044190036a41086a220a200241086a280200360200200420113703900302402004280280012201200428027c470d00200441f8006a2001410110870120042802800121010b2002410c6a210220042802782001410c6c6a2201200429039003370200200141086a200a280200360200200420042802800141016a36028001201241746a22120d000b0b200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d00004107470d000b200441c0006a200a10bf0320042802442201450d002004280240220220014104746a210a20044190036a4104722112034020044190036a2002200b200910b80702400240024020042d0090034101460d00200420042d00910322013a00e802024020012002410c6a2d0000220c470d00200441003602b8010c030b200441023602a4032004420237029403200441e4abcc00360290032004413736028c0220044137360284022004200c3a00f802200420044180026a3602a0032004200441e8026a360288022004200441f8026a36028002200441b8016a20044190036a10410c010b200441b8016a41086a201241086a280200360200200420122902003703b8010b024020042802b801450d00200441b8016a21020c0c0b2002410c6a2d000021010b200441f8006a20012002410d6a2d000041017110b507200241106a2202200a470d000b0b20044190036a41386a2202200441f8006a41386a28020036020020044190036a41306a2201200441f8006a41306a29030037030020044190036a41286a200441f8006a41286a29030037030020044190036a41206a2212200441f8006a41206a29030037030020044190036a41186a220a200441f8006a41186a29030037030020044190036a41106a200441f8006a41106a29030037030020044190036a41086a200441f8006a41086a22092903003703002004200429037837039003200441b8016a41086a2009280200360200200420042903783703b801200441b8016a41146a20044190036a41146a2802003602002004200429029c033702c401200441b8016a41206a20122802003602002004200a2903003703d001200441b8016a412c6a20044190036a412c6a280200360200200420042902b4033702dc01200441b8016a41386a2002280200360200200420012903003703e801200541306c2102200641546a210102400340024020020d00410021090c020b200241506a21022001412c6a2112200141306a220a210120122d00004104470d000b200441386a200a10bf03200428023c21090b200420093602f401200541306c21022006415c6a210102400340024020020d00410021020c020b200241506a2102200141246a2112200141306a220a210120122d0000410c470d000b200a28020021020b200420023602f80120092002470d050240024002400240024002402009450d00200541306c2102200641546a210103402002450d04200241506a21022001412c6a2112200141306a220a210120122d00004104470d000b200541306c2102200641546a210103402002450d03200241506a21022001412c6a2112200141306a220c210120122d0000410c470d000b200441306a200a10bf0320042802342202450d002004280230220e20024102746a211420044190036a41286a2115200c41086a2113200441b0026a2116200441b8026a21174100210d03402004200d3602fc0120132802002102200c2802002101200442013702940320044198dbcb0036029003200441013602fc02200441013602a4032004200441f8026a3602a0032004200441fc016a3602f80220044180026a20044190036a1041200428028002211220042902840221112002200d4d0d0e02402011a7450d00201210350b2004200e28020022023602e802024002400240024020042802e40120024d0d000240024002402001200d41186c6a22012802142218450d0020042802dc0120024104746a22122d000d21192012280200211a200128020c21022001280200211b2012280208221c210a024002402001280208221d450d00201d4103742109201c2101201b21120340200120122802006a220a2001490d02201241086a2112200a2101200941786a22090d000b0b200420193a00c803200442808080808080103703c003200442043703b803200442808080808080103703b003200442013703a8032004201a360294032004200aad422086201dad843703a0032004201bad422086201cad84370398032004200441b8016a36029003410021012015410010ba0720042802b80320042802c00322124103746a2019ad42ff018342288637020020044180026a41086a20042903980337030020044180026a41106a20042903a00337030020044180026a41186a20042903a80337030020044180026a41206a20042903b00337030020044180026a41286a20042903b8033703002004201241016a3602c003201620042903c003370300201720042802c803360200200420042903900337038002201841047421120340200420013602c002200420023602c402200441c8026a20044180026a200210bb07024020042802c802450d00200441e8026a41086a200441c8026a41086a280200360200200420042903c8023703e8022004410336028c03200442033702fc02200441c4d2cb003602f802200441383602a4032004410136029c032004413936029403200420044190036a360288032004200441e8026a3602a0032004200441c0026a360298032004200441c4026a36029003200441d8026a200441f8026a1041024020042802ec02450d0020042802e80210350b20042802d802220a0d040b200241106a2102200141016a2101201241706a22120d000b20042802b0020d030240200428029c02450d0020042802980210350b20042802ac0241ffffffff0171450d0720042802a80210350c070b41201033220a450d0e200a41186a41002900c0b24c370000200a41106a41002900b8b24c370000200a41086a41002900b0b24c370000200a41002900a8b24c37000042a0808080800421110c040b41201033220a450d0d200a41186a41002900bad24b370000200a41106a41002900b2d24b370000200a41086a41002900aad24b370000200a41002900a2d24b37000042a0808080800421110c030b20042902dc0221110240200428029c02450d0020042802980210350b20042802ac0241ffffffff0171450d0320042802a80210350c030b41dcd2cb00413041c086cc00103f000b200441013602a4032004420237029403200441f0aecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a1041200428028002210a20042902840221110b200a450d010b200420113702fc022004200a3602f8022004200441f8026a3602d802200441023602a4032004420237029403200441a0dbcb00360290032004413a36028c022004410136028402200420044180026a3602a0032004200441d8026a360288022004200441fc016a36028002200441e8026a20044190036a1041024020042802fc02450d0020042802f80210350b20042802e80222120d030b200d41016a210d200e41046a220e2014470d000b0b200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d00004109470d000b2004200a28020022023602d80202400240200441f0016a28020020024d0d00200420042802e80120024102746a28020022023602e802200441e4016a28020020024b0d01200441a4036a41013602002004420237029403200441f0aecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c090b200441a4036a41013602002004420237029403200441ccaecc0036029003200441013602fc022004200441f8026a3602a0032004200441d8026a3602f80220044180026a20044190036a10410c080b20042802dc0120024104746a220231000d4220862002350208844280808080c000510d00412d10332212450d06201241256a41002900d5db4b370000201241206a41002900d0db4b370000201241186a41002900c8db4b370000201241106a41002900c0db4b370000201241086a41002900b8db4b370000201241002900b0db4b37000042ad808080d00521110c0d0b200541306c2102200641546a210103402002450d05200241506a21022001412c6a2112200141306a220a210120122d00004108470d000b200441286a200a10bf0320042802282102200428022c21122004410036029803200442043703900320044190036a41002012109001200428029803210c200428029003210e02402012450d002002201241146c6a2109200e200c4103746a21012012410274417c6a410276210d034020022802002112200141046a200241086a28020036020020012012360200200141086a2101200241146a22022009470d000b200c200d6a41016a210c0b2004280294032113200e200c20044190036a41004120200c676b10be070240200c450d00200e200c4103746a210941012112200e2102200e21010340024002402012450d00200920026b41037620124d0d03200220124103746a21020c010b20092002460d020b200420013602e8020240200141046a2802002212200241046a280200470d002001280200220c2002280200220d460d0a200c200d201210a008450d0a0b200241086a210241002112200141086a22012009470d000b0b200441206a200a10bf0320042802242202450d03200241146c2101200428022041106a210203400240024002400240024002402002417c6a2802000e0400030201000b2004200228020022123602d802024020042802f00120124d0d00200420042802e80120124102746a28020022123602e80220042802e40120124b0d05200441013602a4032004420237029403200441f0aecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c0f0b200441a4036a41013602002004420237029403200441ccaecc0036029003200441013602fc022004200441f8026a3602a0032004200441d8026a3602f80220044180026a20044190036a10410c0e0b2004200228020022123602d80220042802d80120124d0d0220042802d00120124101746a2d0001450d03200441a4036a41013602002004420237029403200441b0afcc0036029003200441013602fc022004200441f8026a3602a0032004200441d8026a3602f80220044180026a20044190036a10410c0d0b2004200228020022123602e80220042802c00120124b0d02200441013602a4032004420237029403200441fcadcc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a104120042802800222120d0d0c020b2004200228020022123602e80220042802cc0120124b0d01200441a4036a41013602002004420237029403200441acaecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c0b0b200441a4036a4101360200200442023702940320044190afcc0036029003200441013602fc022004200441f8026a3602a0032004200441d8026a3602f80220044180026a20044190036a10410c0a0b200241146a21022001416c6a22010d000c040b0b20042902ec0221110c0b0b41c0dacb0041c8004188dbcb001064000b4190dacb00411e41b0dacb001064000b201341ffffffff0171450d00200e10350b200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d00004103470d000b200441186a200a10bf03200428021c2202450d002004280218210a200241286c210941002102034002400240024002400240200a20026a220141186a2d00000e0401000302010b200141206a2802004101470d032001411c6a28020021122004200141246a28020022013602d802201220014d0d03200441023602a4032004420237029403200441d0aacc00360290032004410136028c022004410136028402200420123602e802200420044180026a3602a0032004200441e8026a360288022004200441d8026a36028002200441f8026a20044190036a104120042802f80222120d0c0c030b20042001411c6a28020022013602e80220042802e40120014b0d02200441a4036a41013602002004420237029403200441f0aecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c060b2001411a6a2d0000450d012001410c6a2802002102200141146a280200210120044190036a41146a4101360200200420013602fc02200420023602f802200441043602ec022004420137029403200441e8dbcb00360290032004200441f8026a3602e8022004200441e8026a3602a00320044180026a20044190036a10410c050b20044190036a2001411c6a10b7072004280290032212450d0020042902940321110c0a0b2009200241286a2202470d000b0b024002400240200441b8016a41146a280200220241014b0d0020042802c001220241014b0d01200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d0000410d470d000b200441106a200a10bf03200428021022022004280214411c6c6a210a0240024003402002200a460d032004200228020022013602e802024020042802c00120014b0d00200441013602a4032004420237029403200441fcadcc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10412004280280022212450d0020042902840221110c0f0b200241046a2202280200450d0120044190036a200220042802d00120042802d80110b80720042d0090034101460d02200241186a210220042d009103450d000b412010332212450d06201241186a41002900c1dc4b370000201241106a41002900b9dc4b370000201241086a41002900b1dc4b370000201241002900a9dc4b37000042a0808080800421110c0d0b412910332212450d05201241286a41002d00a8dc4b3a0000201241206a41002900a0dc4b370000201241186a4100290098dc4b370000201241106a4100290090dc4b370000201241086a4100290088dc4b37000020124100290080dc4b37000042a9808080900521110c0c0b20044198036a290300211120042802940321120c0b0b200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d0000410a470d000b200441086a200a10bf03200428020c2202450d00200428020822092002411c6c6a210c024002400240024003402009450d052004200928020022023602e80220042802cc0120024d0d082009280204450d0120044190036a200941046a20042802d00120042802d80110b80720042d0090034101460d0220042d0091030d032004200910bf070240024020042802042202450d00200428020021012002410274211220042802f001210a03402004200128020022023602d802200a20024d0d07200420042802e80120024102746a28020022023602e80220042802e40120024d0d02200141046a21012012417c6a22120d000b0b2009411c6a2209200c460d060c010b0b200441013602a4032004420237029403200441f0aecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c090b412a10332212450d07201241286a41002f00f1dc4b3b0000201241206a41002900e9dc4b370000201241186a41002900e1dc4b370000201241106a41002900d9dc4b370000201241086a41002900d1dc4b370000201241002900c9dc4b37000042aa808080a00521110c0e0b20044198036a290300211120042802940321120c0d0b412010332212450d05201241186a41002900c1dc4b370000201241106a41002900b9dc4b370000201241086a41002900b1dc4b370000201241002900a9dc4b37000042a0808080800421110c0c0b200441a4036a41013602002004420237029403200441ccaecc0036029003200441013602fc022004200441f8026a3602a0032004200441d8026a3602f80220044180026a20044190036a10410c050b024020042802bc012202450d002002410c6c450d0020042802b80110350b0240200441c8016a2802002202450d002002410c6c450d0020042802c40110350b0240200441d4016a28020041808080807872418080808078460d0020042802d00110350b0240200441e4016a2802002201450d0020042802dc0121022001410474210103400240200241046a280200450d00200228020010350b200241106a2102200141706a22010d000b0b0240200441e0016a28020041ffffffff0071450d0020042802dc0110350b0240200441ec016a28020041ffffffff0371450d0020042802e80110350b200f41808080807872418080808078460d0d200b10350c0d0b20044190036a41146a41013602002004420137029403200441f0dbcb0036029003200441013602fc02200420023602e8022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c030b200441a4036a41013602002004420137029403200441f8dbcb0036029003200441013602fc02200420023602e8022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c020b200441a4036a41013602002004420237029403200441acaecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c010b1045000b200428028002211220042902840221110c050b200441a4036a41013602002004420137029403200441e0dbcb00360290032004413b3602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410b20042802800221120b2004290284022111201341ffffffff0171450d02200e10350c020b200441a4036a41023602002004418c026a4101360200200442023702940320044180dacb00360290032004410136028402200420044180026a3602a0032004200441f8016a360288022004200441f4016a36028002200441f8026a20044190036a104120042802f80221120b20042902fc0221110b024020042802bc012202450d002002410c6c450d0020042802b80110350b0240200441c8016a2802002202450d002002410c6c450d0020042802c40110350b0240200441d4016a28020041808080807872418080808078460d0020042802d00110350b0240200441e4016a2802002201450d0020042802dc0121022001410474210103400240200241046a280200450d00200228020010350b200241106a2102200141706a22010d000b0b0240200441e0016a28020041ffffffff0071450d0020042802dc0110350b0240200441ec016a28020041ffffffff0371450d0020042802e80110350b200f41808080807872418080808078460d01200b10350c010b20022902042111200228020021120240200f41808080807872418080808078460d00200b10350b0240200428027c2202450d002002410c6c450d00200428027810350b02402004280288012202450d002002410c6c450d0020042802840110350b024020042802940141808080807872418080808078460d0020042802900110350b024020042802a4012201450d00200428029c0121022001410474210103400240200241046a280200450d00200228020010350b200241106a2102200141706a22010d000b0b024020042802a00141ffffffff0071450d00200428029c0110350b20042802ac0141ffffffff0371450d0020042802a80110350b2012450d0002402011a7450d00201210350b200041b6d3cb0036020420004101360200200041086a41133602002006200510f4062007450d01200741306c450d01200610350c010b2000201036020420004100360200200041186a2003360200200041146a2005360200200041106a20073602002000410c6a2006360200200041086a20083602000b200441d0036a24000f0b103c000bc31401187f23004190026b220224000240024002400240024020002802002203450d00200028020421040c010b41002104200241216a410041d800109f081a200241076a220542003700002002420037010241ec0010332203450d0120034100360200200320022902003702042003410b6a2005290000370000200341136a200241206a41d900109d081a20004100360204200020033602000b200220003602282002200336022420022004360220200141ff017121060240024002400340200341066a210720032f01062108410c2109410021050240034020082005460d01200320056a210a200941086a2109200541016a210502404100417f4101200a41086a2d0000220a20064b1b200a2006461b41016a0e03000401000b0b2005417f6a21080b02402004450d002004417f6a2104200320084102746a41ec006a28020021030c010b0b200241c0016a2008360200200241bc016a2000360200200241b0016a41086a20033602002002200036022820022003360224200241003602b4012000200028020841016a36020802400240024020032f01062205410b490d00200241206a41016a410041d800109f081a200241003a001141ec0010332206450d06200641003602002006410036000f20064200370007200620022f01103b0005200641136a200241206a41d900109d081a2003410e6a2d0000210b2003280248210c2003280244210d200641086a2003410f6a20032f010641796a2205109d082109200641146a200341cc006a2005410374109d082104200341063b0106200620053b010620084107490d0120092008417a6a220a6a2009200841796a22086a2209200541ffff037120086b109e081a200920013a00002004200a4103746a200420084103746a2205200641066a22072f010020086b410374109e081a2005410136020020072f010021050c020b200341086a2209200841016a22066a200920086a2209200520086b2200109e081a200920013a0000200341146a220920064103746a200920084103746a22092000410374109e081a200941013602002003200541016a3b01060c040b200341086a2205200841016a22096a200520086a220420072f0100220520086b220a109e081a200420013a0000200341146a220420094103746a200420084103746a2209200a410374109e081a200941013602000b2007200541016a3b01000240200328020022050d00410021010c020b200241206a41016a210e200241a8016a210f200241a0016a211020024198016a211120024190016a211220024180016a41086a211341002101034020062114200c2115200d2116200b211720032f01042104024002400240200522032f01062205410b490d00200e410041d800109f081a200241003a0011200220022f01103b0100200241b0016a200241206a41d900109d081a200f4200370300201042003703002011420037030020124200370300201342003703002002420037038001419c0110332206450d07200641003602002006410036000f20064200370007200620022f01003b0005200641136a200241b0016a41d900109d081a20064194016a200f2903003702002006418c016a201029030037020020064184016a2011290300370200200641fc006a2012290300370200200641f4006a2013290300370200200620022903800137026c2003410e6a2d0000210b2003280248210c2003280244210d200641086a2003410f6a20032f0106220941796a2205109d082118200641146a200341cc006a2005410374109d082119200641ec006a20034188016a2009417a6a220a410274109d082107200341063b0106200620053b01060240200a450d00410021052007210903402009280200220820053b010420082006360200200941046a2109200a200541016a2205470d000b0b20044107490d0120182004417a6a22096a2018200441796a22056a220820062f010620056b109e081a200820173a0000201920094103746a201920054103746a220820062f010620056b410374109e081a2008201636020020082015360204200620062f010641016a22083b01062004410274221520076a416c6a200720094102746a220a200841ffff0371220420096b410274109e081a200a201436020020042009490d02200620156a41d4006a2109034020092802002208200541016a22053b010420082006360200200941046a210920052004490d000c030b0b200341086a2206200441016a22096a200620046a2206200520046b2208109e081a200620173a0000200341146a220620094103746a200620044103746a22062008410374109e081a20062016360200200620153602042003200541016a22053b01062004410274200341ec006a22066a41086a200620094102746a2206200541ffff0371220820096b410274109e081a20062014360200200420084f0d0520032009417f6a22054102746a41f0006a2109034020092802002206200541016a22053b010420062003360200200941046a210920052008490d000c060b0b200341086a2209200441016a22056a200920046a220920032f0106220820046b220a109e081a200920173a0000200341146a220920054103746a200920044103746a2209200a410374109e081a20092016360200200920153602042003200841016a22093b010620044102742207200341ec006a22086a41086a200820054102746a220a200941ffff0371220820056b410274109e081a200a2014360200200420084f0d00200320076a41f0006a2105034020052802002209200441016a22043b010420092003360200200541046a210520082004470d000b0b200141016a210120032802002205450d020c000b0b200241c0016a2005417f6a360200200241bc016a2000360200200241b8016a20033602002002200036022820022003360224200220043602b401200320096a42013702000c010b200241206a41016a410041d800109f081a200241076a22034200370000200242003701022002200229020037031020022003290000370017200241b0016a200241206a41d900109d081a200241a8016a22054200370300200241a0016a2209420037030020024198016a2208420037030020024190016a2204420037030020024188016a220a42003703002002420037038001419c0110332203450d0120034100360200200320022903103702042003410b6a2002290017370000200341136a200241b0016a41d900109d081a20034194016a20052903003702002003418c016a200929030037020020034184016a2008290300370200200341fc006a2004290300370200200341f4006a200a290300370200200320022903800137026c20032000280200220536026c2000200336020020002000280204220941016a360204200541003b01042005200336020020092001470d0220032f01062205410a4b0d03200320054103746a220941186a200c360200200941146a200d360200200320056a41086a200b3a00002003200541016a22054102746a41ec006a2006360200200320053b0106200620053b0104200620033602000b20024190026a24000f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000bf42a11017f017e097f017e017f017e037f017e017f017e017f017e017f017e0c7f037e017f230041b0026b220224004200210320024184016a4200370200200241fc006a4280808080c000370200200241ec006a4200370200200241e4006a4280808080c000370200200241d0006a4200370300200241c0006a4200370300200241386a4280808080c000370300200241286a4200370300200241206a4280808080c000370300200241106a4200370300200242043702742002420437025c20024204370348200242043703302002420437031820024280808080c00037030820024204370300200141106a28020021042001410c6a280200210520012802082106410021072002410036029001200241003602a001200241003602b0010240024020040d004104210841002101410021094100210a4100210b4104210c4200210d4104210e4200210f41042110410021114100210441042112420021134104211442002115410421164200211741042118420021190c010b200241f0016a410172211a200241f0016a410472211b200241c0016a41086a2109200241c0016a41186a210a200241c0016a41206a210b200241c0016a41276a211c4100211d4100211e4100211f4100212041002121410021224100211102400340200920062004417f6a220441306c6a220141096a290000370300200241c0016a41106a2223200141116a290000370300200a200141196a290000370300200b200141216a290000370300201c200141286a290000370000200220012900013703c00120012d000022014110460d01201a20022903c001370000201a41086a2009290300370000201a41106a2023290300370000201a41186a200a290300370000201a41206a200b290300370000201a41276a201c290000370000200220013a00f001410121160240024002400240024002400240024002402001417e6a2214410b4d0d00410121120c010b410121124101210e410121104101210c410121244101210141012123410121084101212502400240024002400240024002400240024002400240024002400240024002400240024020140e0c000102030405060a07190809000b20022903f801211520022802f40121082022450d1002402026422088a72201450d00200141047421232022210103400240200141046a280200450d00200128020010350b200141106a2101202341706a22230d000b0b202642ffffffff0083500d10202210350c100b4100212520022903f801211520022802f40121082021450d0e02402027422088a72201450d00200141286c21232021210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101202341586a22230d000b0b2027a72201450d0e200141286c450d0e202110350c0e0b4100211220022903f801211520022802f40121012020450d0c200f42ffffffff0383500d0c202010350c0c0b4100210e20022903f801211520022802f4012101201f450d0a2013a72223450d0a2023410c6c450d0a201f10350c0a0b4100211020022903f801211520022802f4012101201e450d08200da72223450d082023410c6c450d08201e10350c080b4100210c20022903f801211520022802f4012110201d450d0602402028422088a72201450d00201d20014104746a210e201d21240340024020242802082223450d0020242802002101202341047421230340024020012d00004109470d000240200141046a2225280200220828020441ffffffff0371450d0020082802001035202528020021080b200810350b200141106a2101202341706a22230d000b0b202441106a21010240202441046a28020041ffffffff0071450d00202428020010350b200121242001200e470d000b0b202842ffffffff0083500d06201d10350c060b4100212420022903f801211520022802f40121082007450d0402402003422088a72201450d00200141146c21232007210103400240200141046a280200450d00200128020010350b200141146a21012023416c6a22230d000b0b2003a72201450d04200141146c450d04200710350c040b200241a0026a41086a2201201b41086a2802003602002002201b2902003703a00202402002280290012223450d0020024190016a10b2072002280294012208450d002008411c6c450d00202310350b20024190016a41086a2001280200360200200220022903a0023703900141002101410121124101210e410121104101210c410121240c0f0b200241a0026a41086a2201201b41086a2802003602002002201b2902003703a002024020022802a0012223450d00200241a0016a10b30720022802a4012208450d00200841186c450d00202310350b200241a0016a41086a2001280200360200200220022903a0023703a00141002123410121124101210e410121104101210c41012124410121010c0f0b200241a0026a41086a2201201b41086a2802003602002002201b2902003703a002024020022802b0012223450d00200241b0016a10b40720022802b4012208450d002008411c6c450d00202310350b200241b0016a41086a2001280200360200200220022903a0023703b00141002108410121124101210e410121104101210c410121244101210141012123410121250c0f0b4101211220022802f40121294101210e410121104101210c410121244101210141012123410121084101212541012116410121110c0e0b2015210320082107410121124101210e410121104101210c0c0a0b201521282010211d410121124101210e410121100c080b2015210d2001211e410121124101210e0c060b201521132001211f410121120c040b2015210f200121200c020b2015212720082121410121124101210e410121104101210c410121244101210141012123410121080c080b2015212620082122410121124101210e410121104101210c4101212441012101410121234101210841012125410021160c070b4101210e0b410121100b4101210c0b410121240b410121010b410121230b41012108410121250b02400240024002400240024002400240024002400240024020022d00f0012218417e6a2214410b4b0d0020140e0c0a09080706050400030002010a0b02402018410e4b0d00024002400240024002400240024002400240024002400240024020180e0f0001020304050607081809180a0b0c000b20022802f801450d1720022802f40110350c170b024020022802f801450d0020022802f40110350b200228028402450d1620022802800210350c160b20022802f4012108024020022802fc012201450d00200141047421232008210103400240200141046a280200450d00200128020010350b200141106a2101202341706a22230d000b0b20022802f80141ffffffff0071450d15200810350c150b20022802f4012108024020022802fc012201450d00200141286c21232008210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101202341586a22230d000b0b20022802f8012201450d14200141286c450d14200810350c140b20022802f80141ffffffff0371450d1320022802f40110350c130b20022802f8012201450d122001410c6c450d1220022802f40110350c120b20022802f8012201450d112001410c6c450d1120022802f40110350c110b20022802f401210e024020022802fc012201450d00200e20014104746a210c200e21240340024020242802082223450d0020242802002101202341047421230340024020012d00004109470d000240200141046a2225280200220828020441ffffffff0371450d0020082802001035202528020021080b200810350b200141106a2101202341706a22230d000b0b202441106a21010240202441046a28020041ffffffff0071450d00202428020010350b200121242001200c470d000b0b20022802f80141ffffffff0071450d10200e10350c100b20022802f4012108024020022802fc012201450d00200141146c21232008210103400240200141046a280200450d00200128020010350b200141146a21012023416c6a22230d000b0b20022802f8012201450d0f200141146c450d0f200810350c0f0b201b10b20720022802f8012201450d0e2001411c6c450d0e20022802f40110350c0e0b201b10b30720022802f8012201450d0d200141186c450d0d20022802f40110350c0d0b201b10b40720022802f8012201450d0c2001411c6c450d0c20022802f40110350c0c0b024020022802f4012201450d0020022802f801450d00200110350b02402002280284022225450d000240200228028c022201450d002001410c6c2123202521010340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101202341746a22230d000b0b2002280288022201450d002001410c6c450d00202510350b200228029402220e450d0b0240200228029c022201450d00200e20014104746a210c200e212403402024222541106a2124024020252802042201450d0002402025410c6a2802002223450d002023410c6c21230340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101202341746a22230d000b0b202541086a2802002201450d002001410c6c450d00202528020410350b2024200c470d000b0b20022802980241ffffffff0071450d0b200e10350c0b0b024020022802f801450d0020022802f40110350b02402002280284022201450d00200228028802450d00200110350b20022802940241ffffffff0071450d0a20022802900210350c0a0b2008450d09201b10b40720022802f8012201450d092001411c6c450d0920022802f40110350c090b2023450d08201b10b30720022802f8012201450d08200141186c450d0820022802f40110350c080b2001450d07201b10b20720022802f8012201450d072001411c6c450d0720022802f40110350c070b2024450d0620022802f4012108024020022802fc012201450d00200141146c21232008210103400240200141046a280200450d00200128020010350b200141146a21012023416c6a22230d000b0b20022802f8012201450d06200141146c450d06200810350c060b200c450d0520022802f401210e024020022802fc012201450d00200e20014104746a210c200e21240340024020242802082223450d0020242802002101202341047421230340024020012d00004109470d000240200141046a2225280200220828020441ffffffff0371450d0020082802001035202528020021080b200810350b200141106a2101202341706a22230d000b0b202441106a21010240202441046a28020041ffffffff0071450d00202428020010350b200121242001200c470d000b0b20022802f80141ffffffff0071450d05200e10350c050b2010450d0420022802f8012201450d042001410c6c450d0420022802f40110350c040b200e450d0320022802f8012201450d032001410c6c450d0320022802f40110350c030b2012450d0220022802f80141ffffffff0371450d0220022802f40110350c020b2025450d0120022802f4012108024020022802fc012201450d00200141286c21232008210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101202341586a22230d000b0b20022802f8012201450d01200141286c450d01200810350c010b2016450d0020022802f4012108024020022802fc012201450d00200141047421232008210103400240200141046a280200450d00200128020010350b200141106a2101202341706a22230d000b0b20022802f80141ffffffff0071450d00200810350b20040d000b410021040b2003420020071b211920284200201d1b2103200d4200201e1b211720134200201f1b210d200f420020201b21152027420020211b210f2026420020221b21132007410420071b2118201d4104201d1b210c201e4104201e1b2116201f4104201f1b210e2020410420201b21142021410420211b21102022410420221b2112200228020821012002280200210820022902b401212820022802b001210920022902a401212720022802a001210a2002290294012126200228029001210b0b02402001450d00200141047421232008210103400240200141046a280200450d00200128020010350b200141106a2101202341706a22230d000b0b0240200228020441ffffffff0071450d00200810350b200228020c2108024020022802142201450d00200141286c21232008210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101202341586a22230d000b0b024020022802102201450d00200141286c450d00200810350b0240200228021c41ffffffff0371450d00200228021810350b024020022802282201450d002001410c6c450d00200228022410350b024020022802342201450d002001410c6c450d00200228023010350b200228023c211c024020022802442201450d00201c20014104746a2124201c211a03400240201a2802082223450d00201a2802002101202341047421230340024020012d00004109470d000240200141046a2225280200220828020441ffffffff0371450d0020082802001035202528020021080b200810350b200141106a2101202341706a22230d000b0b201a41106a21010240201a41046a28020041ffffffff0071450d00201a28020010350b2001211a20012024470d000b0b0240200228024041ffffffff0071450d00201c10350b20022802482108024020022802502201450d00200141146c21232008210103400240200141046a280200450d00200128020010350b200141146a21012023416c6a22230d000b0b0240200228024c2201450d00200141146c450d00200810350b200241dc006a10b207024020022802602201450d002001411c6c450d00200228025c10350b200241e8006a10b3070240200228026c2201450d00200141186c450d00200228026810350b200241f4006a10b407024020022802782201450d002001411c6c450d00200228027410350b2028420020091b212820274200200a1b212720264200200b1b21262009410420091b2101200a4104200a1b2123200b4104200b1b2108200228028001221a20022802880110f40602402002280284012225450d00202541306c450d00201a10350b200241d8006a202936020020022004360288012002200536028401200220063602800120022028370378200220013602742002202737026c20022023360268200220263703602002200836025c200220113602542002201937024c20022018360248200220033703402002200c36023c20022017370234200220163602302002200d3703282002200e3602242002201537021c200220143602182002200f3703102002201036020c200220133702042002201236020020002002418c01109d081a200241b0026a24000bd60401107f230041106b220224000240024020012802004101460d00200128020421030c010b200141106a2d000021042001410c6a2802002105200141086a280200210620012f0112210720012d0011210820012802042109200241086a200010bf0302400240200228020c220a450d0020022802082101200a41047441706a410476210b0240200841ff0171220c4104460d004100210a200441ff0171210d0340200a2103024020012d000c200d470d0020012802082005470d0002402001280200220a2009460d002005210e2009210f0340200e450d01200e417f6a210e200f2d00002110200a2d00002111200f41016a210f200a41016a210a20112010460d000c020b0b20012d000d220a200c470d00200a4104470d040b200141106a2101200341016a210a2003200b470d000c020b0b4100210a200441ff0171210d0340200a2103024020012d000c200d470d0020012802082005470d0002402001280200220a2009460d002005210e2009210f0340200e450d01200e417f6a210e200f2d00002110200a2d00002111200f41016a210f200a41016a210a20112010460d000c020b0b20012d000d4104460d030b200141106a2101200341016a210a2003200b470d000b0b024020002802082201200041046a280200470d00200020014101108c01200028020821010b200028020020014104746a220120073b010e200120083a000d200120043a000c2001200536020820012006360204200120093602002000200028020841016a3602082002200010bf032002280204417f6a21030c010b2006450d00200910350b200241106a240020030b9d1901217f23004180016b2202240041002103200241003602102002420437030820012802042104200128020021054101210641012107024020012802082208450d0041002107200241086a410041011089012002280208200228021041306c6a2203200836000c2003200436000820032005360004200341023a00002002200228021041016a22033602100b200141106a2802002109200128020c210a0240200141146a280200220b450d0002402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341033a00002003200b36000c200320093600082003200a36000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241206a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a2203360210410021060b2001411c6a280200210c2001280218210d4100210e02400240200141206a280200220f0d00410021100c010b02402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341043a00002003200f36000c2003200c3600082003200d36000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241206a290200370200200341206a200241286a290200370200200341286a200241186a41186a290200370200410121102002200228021041016a22033602100b200141286a28020021112001280224211202402001412c6a280200220f450d0002402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341053a00002003200f36000c200320113600082003201236000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241206a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702004101210e2002200228021041016a22033602100b200141346a28020021132001280230211402400240200141386a280200220f0d00410021150c010b02402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341063a00002003200f36000c200320133600082003201436000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241206a290200370200200341206a200241286a290200370200200341286a200241186a41186a290200370200410121152002200228021041016a22033602100b200141c0006a2802002116200128023c21174101211802400240200141c4006a28020022190d004101211a0c010b02402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341073a00002003201936000c200320163600082003201736000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241206a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a22033602104100211a0b200141cc006a280200211b2001280248211c0240200141d0006a280200221d450d0002402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341083a00002003201d36000c2003201b3600082003201c36000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241186a41086a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a2203360210410021180b4101211e024020012802544101470d00200141d8006a280200210f02402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341093a00002003200f36020420032002290218370208200341036a200241f3006a2d00003a0000200341106a200241206a290200370200200341186a200241186a41106a290200370200200341206a200241186a41186a290200370200200341286a200241186a41206a2902003702002002200228021041016a22033602100b200241c0006a41086a221f200141e4006a280200220f3602002002200129025c3703400240200f450d00200241fc006a201f2802003600002002200229034037007402402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022900713700012003410a3a000020032002290218370210200341086a200241f8006a290000370000200341186a200241186a41086a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a22033602104100211e0b200241d0006a41086a200141f0006a280200220f3602002002200129026837035002400240200f0d00410121200c010b200241fc006a200241d0006a41086a2802003600002002200229035037007402402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022900713700012003410c3a000020032002290218370210200341086a200241f8006a290000370000200341186a200241186a41086a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a2203360210410021200b200241e8006a221f200141fc006a280200220f3602002002200129027437036002400240200f0d00410121210c010b200241fc006a201f2802003600002002200229036037007402402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022900713700012003410d3a000020032002290218370210200341086a200241f8006a290000370000200341186a200241186a41086a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a2203360210410021210b20014184016a280200210f200128028001211f200241086a200320014188016a28020041306c220141306d222210890120022802082002280210220341306c6a201f2001109d081a2002200320226a3602100240200f450d00200f41306c450d00201f10350b200241186a41086a2201200241086a41086a280200360200200220022903083703180240024041800610332203450d0020004280c2cdeb1637020020002002290318370208200041106a2001280200360200200310352021450d01200241e0006a10b40720022802642201450d012001411c6c450d01200228026010350c010b1045000b02402020450d00200241d0006a10b30720022802542201450d00200141186c450d00200228025010350b0240201e450d00200241c0006a10b20720022802442201450d002001411c6c450d00200228024010350b02402018450d000240201d450d00201d41146c2103201c210103400240200141046a280200450d00200128020010350b200141146a21012003416c6a22030d000b0b201b450d00201b41146c450d00201c10350b0240201a450d0002402019450d00201720194104746a211e201721180340024020182802082203450d0020182802002101200341047421030340024020012d00004109470d000240200141046a220f280200220028020441ffffffff0371450d0020002802001035200f28020021000b200010350b200141106a2101200341706a22030d000b0b201841106a21010240201841046a28020041ffffffff0071450d00201828020010350b200121182001201e470d000b0b201641ffffffff0071450d00201710350b02402013452015720d002013410c6c450d00201410350b0240201145200e720d002011410c6c450d00201210350b0240200c41ffffffff0371410047201041017371450d00200d10350b02402006450d000240200b450d00200b41286c2103200a210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101200341586a22030d000b0b2009450d00200941286c450d00200a10350b02402007450d0002402008450d00200841047421032005210103400240200141046a280200450d00200128020010350b200141106a2101200341706a22030d000b0b200441ffffffff0071450d00200510350b20024180016a24000ba01302147f027e23004180026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110c8072003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200b200b417f6a220d2000200b4103746a280200220e2000200d4103746a280200220f4922101b2211200b41016a2212200d200b20101b200020124103746a280200220b200f200e20101b220d49220f1b200b200d200f1b200020114103746a2802004922131b210b200c200c417f6a220d2000200c4103746a28020022112000200d4103746a280200221249220e1b2214200c4101722206200d200c200e1b200020064103746a280200220c20122011200e1b220d4922111b200c200d20111b200020144103746a2802004922141b210c200a200a417f6a22122000200a4103746a2802002206200020124103746a280200221549220d1b2216200a41016a22172012200a200d1b200020174103746a280200220a20152006200d1b22064922121b200a200620121b200020164103746a2802004922061b210a41024101200d1b200d20121b20066a200e6a20116a20146a20106a200f6a20136a210d0b200d2000200c4103746a280200220e2000200a4103746a280200220f4922106a2000200b4103746a280200220d200f200e20101b221149220f6a210e200d2011200f1b2000200c200a20101b220d4103746a280200490d01200b200a200c20101b200f1b210d0c020b2000200110d9070c0f0b200e41016a220e410c490d0002402001410176220b450d00200020014103746a41786a210a2000210c0340200c2902002118200c200a290200370200200a2018370200200c41086a210c200a41786a210a200b417f6a220b0d000b0b2001200d417f736a210d4101210a0c010b200e45210a0b0240200a452009724101710d002000200110da070d0d0b2002450d02200d20014f0d01024020022802002000200d4103746a220a2802004f0d0020002108200121070c040b200029020021182000200a290200370200200a2018370200200041786a210f200041086a211120002902002218a721104100210c2001210b03400240200c200b417f6a220d4f0d002011200c4103746a210a0340200a28020020104b0d01200a41086a210a200d200c41016a220c470d000b200d210c0b200f200b4103746a210a02400340200c200b417f6a220b4f0d01200a280200210d200a41786a220e210a200d20104b0d000b2011200c4103746a220a2902002119200a200e41086a220d290200370200200d2019370200200c41016a210c0c010b0b2000201837020002402001200c41016a220a490d002000200a4103746a21002001200a6b220141154f0d010c0c0b0b200a200141e485cc001059000b200d200141d086cc001042000b2007450d010b200d20074f0d012008290200211820082008200d4103746a220a290200370200200a2018370200200841086a210e20082902002219a72111410021142007417f6a2210450d02200e210a0340200a28020020114f0d03200a41086a210a2010201441016a2214470d000b201021140c020b4100410041f485cc001042000b200d2007418486cc001042000b200820074103746a210c2010210b02400340200c210d200b220a20144d22060d01200a417f6a210b200d41786a220c28020020114f0d000b0b0240200a2014490d002010200a490d0241800121054100210b410021014100210c4100210f4180012109200e20144103746a2215211003400240200d20106b220a4187104b22130d00200a410376220a41807f6a200a2001200b49200f200c49220e7222001b210a02402000450d002009200a200e1b2109200a2005200e1b21050c010b200a200a41017622096b21050b0240200f200c470d00024020090d002004220c210f0c010b4100210a2004220f210c2010210e0340200c200a3a0000200c200e28020020114f6a210c200e41086a210e2009200a41016a220a470d000b0b02402001200b470d00024020050d0020044180016a220b21010c010b200d41786a210a4100210e20044180016a2201210b0340200b200e3a0000200b200a2802002011496a210b200a41786a210a2005200e41016a220e470d000b0b0240200b20016b220a200c200f6b220e200e200a4b1b2212450d002010200f2d00004103746a220a2902002118200a200d20012d0000417f734103746a290200370200024020124101460d004100210a0340200d2001200a6a220e2d0000417f734103746a2010200f200a6a41016a22002d00004103746a290200370200201020002d00004103746a200d200e41016a2d0000417f734103746a290200370200200a41026a210e200a41016a2200210a200e2012490d000b200120006a2101200f20006a210f0b200d20012d0000417f734103746a2018370200200141016a2101200f41016a210f0b200d20054103746b200d2001200b461b210d201020094103746a2010200f200c461b211020130d000b02400240200f200c4f0d00200d210a03402010200c417f6a220c2d00004103746a220b2902002118200b200a41786a220a290200370200200a2018370200200f200c490d000c020b0b2010210a2001200b4f0d000340200a2902002118200a200d200b417f6a220b2d0000417f734103746a220c290200370200200c2018370200200a41086a210a2001200b490d000b0b200820193702002007200a20156b41037620146a22014d0d032008200820014103746a220a290200370200200a2019370200200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41086a2100024002402001200c417f6a220c490d002000200c200a200310f206200821000c010b200820012002200310f206200a2102200c21010b200b200d4f2105200141154f0d010c050b0b2014200a419486cc001059000b200a2010419486cc001058000b20012007418486cc001042000b41a486cc00411c41c086cc00103f000b20014102490d00200041786a21104100210e4101210b0340200b410374210c200b417f6a210a200b41016a210b02402000200c6a220d2802002000200a4103746a220f2802004f0d00200d2902002118200d200f2902003702000240200a450d00200e210c2010210a200d41706a2802002018a7220d4d0d00024002400340200a41086a200a290200370200200c4101460d01200c417f6a210c200a41786a220a280200200d4b0d000c020b0b4100210c0b2000200c4103746a210f0b200f20183702000b200e41016a210e201041086a2110200b2001470d000b0b20044180026a24000b9c0402077f017e230041306b22022400200241106a2203200141246a290200370300200241086a22042001411c6a29020037030020022001290214370300200241186a41106a2205200141106a280200360200200241186a41086a2206200141086a290200370300200220012902003703182000200241186a10f00621070240200041206a28020022082000411c6a280200470d00200041186a20084101108601200028022021080b200028021820084102746a20073602002000200028022041016a3602202005200329030037030020062004290300370300200220022903003703180240200041f0006a22032802002208200041ec006a280200470d000240024002400240200841016a22042008490d00200841017422052004200520044b1bad42187e2209422088a70d002009a722044100480d00024020080d0020040d02410421050c040b20002802682105200841186c22082004460d03024020080d0020040d02410421050c040b20052008200410372205450d020c030b103e000b2004103322050d010b103c000b20002005360268200041ec006a200441186e360200200041f0006a28020021080b2000280268200841186c6a22082002290318370200200841106a200241186a41106a290300370200200841086a200241186a41086a29030037020020032003280200220841016a360200024020012d002c450d0020004101360254200041d8006a20083602000b200241306a24000bcf0f01077f02402001450d002000200141306c6a210203402000220341306a21000240024020032d00002201410e4b0d00024002400240024002400240024002400240024002400240024020010e0f0001020304050607080e090e0a0b0c000b200341086a280200450d0d200341046a28020010350c0d0b0240200341086a280200450d00200341046a28020010350b200341146a280200450d0c200341106a28020010350c0c0b02402003410c6a2802002204450d00200341046a28020021012004410474210403400240200141046a280200450d00200128020010350b200141106a2101200441706a22040d000b0b200341086a28020041ffffffff0071450d0b200328020410350c0b0b02402003410c6a2802002204450d00200341046a2802002101200441286c210403400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101200441586a22040d000b0b200341086a2802002201450d0a200141286c450d0a200328020410350c0a0b200341086a28020041ffffffff0371450d09200341046a28020010350c090b200341086a2802002201450d082001410c6c450d08200341046a28020010350c080b200341086a2802002201450d072001410c6c450d07200341046a28020010350c070b02402003410c6a2802002201450d00200341046a280200220520014104746a21060340024020052802082204450d0020052802002101200441047421040340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d0020082802001035200728020021080b200810350b200141106a2101200441706a22040d000b0b200541106a21010240200541046a28020041ffffffff0071450d00200528020010350b2001210520012006470d000b0b200341086a28020041ffffffff0071450d06200328020410350c060b02402003410c6a2802002204450d00200341046a2802002101200441146c210403400240200141046a280200450d00200128020010350b200141146a21012004416c6a22040d000b0b200341086a2802002201450d05200141146c450d05200328020410350c050b02402003410c6a2802002201450d00200341046a28020022052001411c6c6a21060340024020052802042201450d0002402005410c6a2802002204450d00200441047421040340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d0020082802001035200728020021080b200810350b200141106a2101200441706a22040d000b0b200541086a28020041ffffffff0071450d00200528020410350b2005411c6a21010240200541146a28020041ffffffff0371450d00200528021010350b2001210520012006470d000b0b200341086a2802002201450d042001411c6c450d04200328020410350c040b02402003410c6a2802002201450d00200341046a2802002205200141186c6a210603400240200541046a28020041ffffffff0171450d00200528020010350b0240200541146a2802002204450d00200528020c2101200441047421040340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d0020082802001035200728020021080b200810350b200141106a2101200441706a22040d000b0b200541186a21010240200541106a28020041ffffffff0071450d00200528020c10350b2001210520012006470d000b0b200341086a2802002201450d03200141186c450d03200328020410350c030b02402003410c6a2802002201450d00200341046a28020022052001411c6c6a21060340024020052802042201450d0002402005410c6a2802002204450d00200441047421040340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d0020082802001035200728020021080b200810350b200141106a2101200441706a22040d000b0b200541086a28020041ffffffff0071450d00200528020410350b2005411c6a21010240200541146a280200450d00200528021010350b2001210520012006470d000b0b200341086a2802002201450d022001411c6c450d02200328020410350c020b0240200341046a2802002201450d00200341086a280200450d00200110350b0240200341146a2802002201450d0002402003411c6a2802002204450d002004410c6c21040340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101200441746a22040d000b0b200341186a2802002201450d002001410c6c450d00200328021410350b200341246a2802002205450d0102402003412c6a2802002201450d00200520014104746a210603402005220741106a2105024020072802042201450d0002402007410c6a2802002204450d002004410c6c21040340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101200441746a22040d000b0b200741086a2802002201450d002001410c6c450d00200728020410350b20052006470d000b0b200341286a28020041ffffffff0071450d01200328022410350c010b0240200341086a280200450d00200341046a28020010350b0240200341146a2802002201450d00200341186a280200450d00200110350b200341246a28020041ffffffff0071450d00200341206a28020010350b20002002470d000b0b0b8f7205077f017e277f047e077f23002203210420034180096b416071220324000240411010332205450d00200541063a0000412010332206450d00200641063a001020064100360204200620032f00e0043b00012006412d3a0000200641036a200341e2046a2d00003a0000024020052d00004109470d0002402005280204220728020441ffffffff0371450d0020072802001035200528020421070b200710350b20051035200141106a28020041306c2105200128020841546a21070240024002400240024002400240024002400340024020050d00411010332207450d0b20074180023b010c200742828080802037020420072006360200200720032f01d0033b010e200128021022052001410c6a280200470d03200541016a22082005490d05200541017422092008200920084b1bad42307e220a422088a70d05200aa722084100480d050240024020050d0020080d01410421090c040b20012802082109200541306c22052008460d03024020050d0020080d01410421090c040b20092005200810372209450d0c0c030b2008103322090d020c0b0b200541506a21052007412c6a2108200741306a2209210720082d00004107470d000b200320032f01d0033b01e0040240200941086a22072802002205200941046a280200470d00200920054101108c01200728020021050b200928020020054104746a22054180023b010c200542828080802037020420052006360200200520032f01e0043b010e2007200728020041016a360200200341306a200910bf032003280234417f6a210b2001280210210c0c020b200120093602082001410c6a200841306e360200200128021021050b2001280208200541306c6a220520032f00f0073b0001200541073a0000200542818080801037000820052007360004200520032902e004370210200541036a200341f2076a2d00003a0000200541186a200341e8046a290200370200200541206a200341f0046a290200370200200541286a200341e0046a41186a2902003702002001200128021041016a220c3602104100210b0b200c41306c21052001280208220d41546a210702400340410021082005450d01200541506a21052007412c6a2109200741306a2206210720092d00004103470d000b200641086a2802002205450d00200541286c2107200628020041186a2105410021080340200820052d0000456a2108200541286a2105200741586a22070d000b0b200c41306c2105200d41546a210702400340410021092005450d01200541506a21052007412c6a2106200741306a220e210720062d00004103470d000b200e41086a2802002205450d00200541286c2107200e28020041186a2105410021090340200920052d0000456a2109200541286a2105200741586a22070d000b0b200c41306c2105200d415c6a210702400340024020050d00410021050c020b200541506a2105200741246a2106200741306a220e210720062d00004104470d000b200e28020021050b200341003602d00302400240200520096a220d0d004104210f41002110410021110c010b0240024002402008450d00200342003703e004410021050c010b200341e0046a4100200110e40720032802e404210520032802e0044101470d00200341e8046a290300210a024020032802d0032207450d0020032802d403450d00200710350b2003200a3702d403200320053602d003410021114104210f410021100c010b41041033220c450d07200c200536020020034281808080103702f4072003200c3602f0070240200d4102490d0002400240024020084102490d00200342003703e0044100210e0c010b200341e0046a4101200110e40720032802e404210e20032802e0044101470d00200341e8046a290300210a024020032802d003450d0020032802d403450d0020032802d00310350b2003200a3702d4030c010b4104210941012106410121070340200741016a2105024020072006470d00200341f0076a2006410110860120032802f007210c0b200c20096a200e360200200320053602f8072005200d4f0d0202400240200820054d0d00200342003703e0044100210e0c010b200341e0046a2005200110e40720032802e404210e20032802e0044101470d0020032903e804210a024020032802d003450d0020032802d403450d0020032802d00310350b2003200a3702d4030c020b200941046a210920032802f4072106200521070c000b0b2003200e3602d0030b20032802d003210520032802f807211020032802f407211120032802f007210f0b2005450d0020032902d403210a0240201141ffffffff0371450d00200f10350b2000200536020420004101360200200041086a200a3702000c040b024020012802102205450d0020012802082212200541306c6a2113200341e0046a41106a2114200341d0066a210e20034184056a211520034194056a2116200341a4056a2117200341b4056a2118200341c4056a2119200341d4056a211a200341e4056a211b200341f4056a211c20034184066a211d20034194066a211e200341a4066a211f200341b4066a2120200341c4066a21210340024020122d0000410c470d00201228020c2205450d0020122802042206200541186c6a212203400240200641146a22232802002205450d002006410c6a21244100210c034002400240024002400240200c20054f0d00410121052024280200200c410474220d6a22072d0000410b470d042003200741046a22073602c0022007280200220720104f0d01200f20074102746a2802002208450d042003200b3602c406200341133a00c006200341d7003a00b006200320083602a4062003412d3a00a0062003200b36029406200341123a00900620032007360284062003410b3a008006200341063a00f005200341003a00e00520034184083b01d005200341373a00c005200320023602b4052003412d3a00b0052003200b3602a405200341123a00a0052003200b36029405200341133a009005200341d6003a008005200320083602f4042003412d3a00f0042003200b3602e404200341123a00e004200c41016a212520232802002226200c4d0d022023200c360200200628020c2205202541047422276a2108024002402005200d6a22282d0000220941ac01470d00202841106a21090c010b4100210502400340202820056a21070240200941ff01714109470d000240200741046a280200220928020441ffffffff0371450d00200928020010350b200910350b2005450d01200541106a2105200741106a2d0000220941ac01470d000b202820056a41106a21090c010b200741106a21090b202620256b212920082107024020092008460d0002400340200922052d0000220741ac01460d01024020074109470d000240200541046a280200220728020441ffffffff0371450d00200728020010350b200710350b200541106a22092008470d000b0b200541106a21070b02400240024002402029450d00200341e0046a21050240202520062802142209460d00200d200941047422056b41106a210d200628020c20056a2109200341e0046a21050340200341f0076a41002005200e200546222a1b10e30720032d00f00741ac01460d052005200541106a202a1b2105200920032903f007370300200941086a200341f0076a41086a2903003703002006200628021441016a360214200941106a2109200d41706a220d0d000b0b200e20056b220d41047621090240200d450d00202420262009109a01200628020c222a202520096a22254104746a202a20276a2029410474109e081a20252006280214222a460d00200c200d4104766a410474202a41047422096b41106a210d200628020c20096a21090340200341f0076a41002005200e200546222a1b10e30720032d00f00741ac01460d052005200541106a202a1b2105200920032903f007370300200941086a200341f0076a41086a2903003703002006200628021441016a360214200941106a2109200d41706a220d0d000b200e20056b41047621090b200341003602d803200342083703d003200341d0036a41002009109a0120032802d803210d20032802d003212b200341f0076a41002005200e20054622091b10e307024020032d00f00741ac01460d002005200541106a20091b2105202b200d4104746a21090340200920032903f007370300200941086a200341f0076a41086a290300370300200341f0076a41002005200e200546222a1b10e3072005200541106a202a1b2105200d41016a210d200941106a210920032d00f00741ac01470d000b0b202b200d41047422266a212a20032802d403212c200d0d01202b21050c020b20242023280200410f109a012023280200210d200628020c2105200341f0076a200341e0046a10e307024020032d00f00741ac01460d002005200d4104746a2109201421050340200920032903f007370300200941086a200341f0076a41086a290300370300200341f0076a41002005200e200546222a1b10e3072005200541106a202a1b2105200d41016a210d200941106a210920032d00f00741ac01470d000b0b2023200d3602000c020b2024202920256a20264104752205109a0120254104742109200628020c220d202520056a222541047422056a200d20096a2029410474109e081a0240202520062802142209470d00202b21050c010b200628020c220d20056a212d200d20094104746a210d202b21090340024020260d00202a21050c020b200341f0076a41026a2205200941036a2d00003a0000200320092f00013b01f007024020092d0000222741ac01470d00200941106a21050c020b200941046a280200212e200941086a290300210a200d20273a0000200d41086a200a370300200d41046a202e36020020032f01f0072127200d41036a20052d00003a0000200d41016a20273b00002006200628021441016a360214202641706a2126200941106a22052109200d41106a220d202d470d000b0b0240202a2005460d000340200541106a2109024020052d00004109470d000240200541046a220d280200220528020441ffffffff0371450d0020052802001035200d28020021050b200510350b20092105202a2009470d000b0b202c41ffffffff0071450d00202b10350b20072008460d0303400240024020072d000022054109460d00200541ac01470d0120282007460d06200741106a2105034020052d0000220741ac01460d07024020074109470d000240200541046a280200220728020441ffffffff0371450d00200728020010350b200710350b200541106a22052008470d000c070b0b0240200741046a280200220528020441ffffffff0371450d00200528020010350b200510350b200741106a22072008470d000c040b0b200c2005418490cc001042000b200341013602f404200342013702e4042003419490cc003602e0042003413c3602d4032003200341d0036a3602f0042003200341c0026a3602d003200341f0076a200341e0046a104120032802f0072205450d0420032902f407210a2000200536020420004101360200200041086a200a370200201141ffffffff0371450d0c200f10350c0c0b20252026104f000b02402029450d000240202520232802002205460d002024280200220720054104746a200720254104746a2029410474109e081a0b2023202920056a3602000b024020032d00e0044109470d00024020032802e404220528020441ffffffff0371450d002005280200103520032802e40421050b200510350b024020032d00f0044109470d000240200341e0046a41146a280200220528020441ffffffff0371450d002005280200103520032802f40421050b200510350b024020032d0080054109470d0002402015280200220528020441ffffffff0371450d002005280200103520032802840521050b200510350b024020032d0090054109470d0002402016280200220528020441ffffffff0371450d002005280200103520032802940521050b200510350b024020032d00a0054109470d0002402017280200220528020441ffffffff0371450d002005280200103520032802a40521050b200510350b024020032d00b0054109470d0002402018280200220528020441ffffffff0371450d002005280200103520032802b40521050b200510350b024020032d00c0054109470d0002402019280200220528020441ffffffff0371450d002005280200103520032802c40521050b200510350b024020032d00d0054109470d000240201a280200220528020441ffffffff0371450d002005280200103520032802d40521050b200510350b024020032d00e0054109470d000240201b280200220528020441ffffffff0371450d002005280200103520032802e40521050b200510350b024020032d00f0054109470d000240201c280200220528020441ffffffff0371450d002005280200103520032802f40521050b200510350b024020032d0080064109470d000240201d280200220528020441ffffffff0371450d002005280200103520032802840621050b200510350b024020032d0090064109470d000240201e280200220528020441ffffffff0371450d002005280200103520032802940621050b200510350b024020032d00a0064109470d000240201f280200220528020441ffffffff0371450d002005280200103520032802a40621050b200510350b024020032d00b0064109470d0002402020280200220528020441ffffffff0371450d002005280200103520032802b40621050b200510350b024020032d00c0064109470d0002402021280200220528020441ffffffff0371450d002005280200103520032802c40621050b200510350b410f21050b2005200c6a220c20232802002205490d000b0b200641186a22062022470d000b0b201241306a22122013470d000b0b200341386a41106a200141106a280200220c360200200341386a41086a200141086a290200220a37030020032001290200370338410021062003410036025820034204370350200c41306c2105200aa7220d41546a210702400340024020050d000c020b200541506a21052007412c6a2108200741306a2209210720082d00004108470d000b200341286a200910bf0320032802282106200328022c21050b4100210e2005410020061b212a200c41306c2105200d41546a2108200641b0b4cc0020061b210702400340024020050d000c020b200541506a21052008412c6a2109200841306a2206210820092d0000410a470d000b200341206a200610bf032003280220210e200328022421050b20054100200e1b2128200c41306c2105200d41546a2109200e41b0b4cc00200e1b210802400340024020050d004200210a0c020b200541506a21052009412c6a2106200941306a220e210920062d00004109470d000b200e28020021054201210a0b20034100360278200341003602702007202a41146c6a212520082028411c6c6a21242005ad422086200a84210a200341f0076a410272221541266a2116201541206a2117201541186a2118201541106a2119201541086a211a200341f0076a41286a211b4100212a410121260240024003400240024002400240024020264102460d000240024002402007450d0020252007460d000340200741146a21092007410c6a280200450d022009210720252009470d000b0b4100210720264101470d02202a2105034002402005450d004100212a20052028460d00200541046a212a410121264100210720050d030c040b20242008460d03200341186a200810bf072008411c6a210820032802182205450d032005200328021c4102746a21282005212a0c000b0b200741106a2105200921070b200528020021050c010b0240200aa722054102460d002005450d00200a422088a721054200210a410221260c010b200341e0006a41086a200341f0006a41086a280200360200200320032903703703602003280248220e41306c21052003280240220c41546a210702400340410021082005450d01200541506a21052007412c6a2109200741306a2206210720092d00004103470d000b200641086a2802002205450d00200541286c2107200628020041186a2105410021080340200820052d0000456a2108200541286a2105200741586a22070d000b0b200e41306c2105200c415c6a210702400340024020050d00410021050c020b200541506a2105200741246a2109200741306a2206210720092d00004104470d000b200628020021050b200341e0046a41106a2229200341386a41106a280200360200200341e0046a41086a200341386a41086a290300370300200320032903383703e004200341b0016a200341e0046a10ef062003280250212f20032802542130024020032802582207450d00202f20074102746a2124200520086a212a200341e0046a41e0016a2126200341e0046a41d0016a2127200341e0046a41c0016a212e200341e0046a41b0016a2110200341e0046a41a0016a212b200341e0046a4190016a212d200341e0046a4180016a212c200341e0046a41f0006a2115200341e0046a41e0006a2116200341e0046a41d0006a2117200341e0046a41c0006a2118200341e0046a41306a2119200341e0046a41206a211a200341f7076a211b20034194056a211c200341a4056a211d200341b4056a211e200341c4056a211f200341d4056a2120200341e4056a2121200341f4056a212220034184066a211420034194066a2112200341a4066a2101200341b4066a2113200341c4066a2131202f21050240034020032802602207450d01200541046a2123200528020021062003280264210d034020072f01062225410274210c41002109417f210841002105024003400240200c2005470d00202521080c020b200720056a210e200841016a2108200941206a2109200541046a21050240417f200e41086a280200220e200647200e20064b1b41016a0e03020001020b0b200720096a220e412c6a2802002107200e41306a28020021052003200b3602c406200341133a00c006200341d7003a00b006200320053602a4062003412d3a00a0062003200b36029406200341123a00900620032007360284062003410b3a008006200341063a00f005200341003a00e00520034184083b01d005200341373a00c005200320023602b4052003412d3a00b0052003200b3602a405200341123a00a0052003200b36029405200341133a009005200341d6003a008005200320053602f4042003412d3a00f0042003200b3602e404200341123a00e004200e411c6a220c280200220841106a220541ffffffff00712005470d0620054104742207417f4c0d060240024020070d00410821090c010b200710332209450d12200c28020021080b41002105200341003602880120032009360280012003200741047622073602840102402008450d002008417f6a210641002105410021080340024020052007470d0020034180016a20074101109a01200328028001210920032802880121050b200920054104746a2207410f3a000020072008360204200720032f01f0073b0001200741036a200341f0076a41026a2d00003a00002003200541016a22053602880120062008460d01200841016a210820032802840121070c000b0b20034180016a2005410f109a0120032802880121092003280280012108200341f0076a200341e0046a10d707200820094104746a220541086a200341f0076a41086a2207290300370300200520032903f007370300200341f0076a202910d707200541186a2007290300370300200520032903f007370310200341f0076a201a10d707200541286a2007290300370300200541206a20032903f007370300200341f0076a201910d707200541386a2007290300370300200541306a20032903f007370300200341f0076a201810d707200541c8006a2007290300370300200541c0006a20032903f007370300200341f0076a201710d707200541d8006a2007290300370300200541d0006a20032903f007370300200341f0076a201610d707200541e8006a2007290300370300200541e0006a20032903f007370300200341f0076a201510d707200541f8006a2007290300370300200541f0006a20032903f007370300200341f0076a202c10d70720054188016a200729030037030020054180016a20032903f007370300200341f0076a202d10d70720054198016a200729030037030020054190016a20032903f007370300200341f0076a202b10d707200541a8016a2007290300370300200541a0016a20032903f007370300200341f0076a201010d707200541b8016a2007290300370300200541b0016a20032903f007370300200341f0076a202e10d707200541c8016a2007290300370300200541c0016a20032903f007370300200341f0076a202710d707200541d8016a2007290300370300200541d0016a20032903f007370300200341f0076a202610d707200541e0016a20032903f007370300200541e8016a200729030037030020032009410f6a22053602880102402005200328028401470d0020034180016a20054101109a01200328028001210820032802880121050b200820054104746a220720032900f007370001200741063a0000200741086a201b2900003700002003200541016a36028801200341f0076a200341b0016a418c01109d081a411010332207450d12200741063a0000200341d0036a200341f0076a418c01109d081a200c2802002205417f4c0d06200e41146a280200210c0240024020050d0041002108410121060c010b200510332206450d12200521080b0240024020082005490d00200821090c010b200841017422092005200920054b1b22094100480d0d024020080d00200910332206450d140c010b20082009460d0020062008200910372206450d130b2006200c2005109d0821080240024020050d00410021064101210c0c010b20051033220c450d13200521060b200c20082005109d08210c02402009450d00200810350b200341c0026a200341d0036a418c01109d081a200e41216a3100002132200341f0076a200341c0026a418c01109d081a200341d0036a200341f0076a418c01109d081a411010332208450d12202841807e712128200a428080808080804083220a2005ad842032422886844280808080800c842132200841063a000020032802880121052003280284012109200328028001210d20081035200341c0026a200341d0036a418c01109d081a200341f0076a200341c0026a418c01109d081a024020072d00004109470d0002402007280204220828020441ffffffff0371450d0020082802001035200728020421080b200810350b20071035200341d0036a200341f0076a418c01109d081a200341f0076a200341d0036a418c01109d081a200320283602ec02200320053602e802200320093602e4022003200d3602e002200341003602dc02200342043702d402200320323702cc02200320063602c8022003200c3602c402200341013602c002200341f0076a200341c0026a10f306200341b0016a200341f0076a418c01109d081a200e41286a202a360200200e41246a4101360200024020032d00e0044109470d00024020032802e404220528020441ffffffff0371450d002005280200103520032802e40421050b200510350b024020032d00f0044109470d000240200341e0046a41146a280200220528020441ffffffff0371450d002005280200103520032802f40421050b200510350b024020032d0080054109470d000240200341e0046a41246a280200220528020441ffffffff0371450d002005280200103520032802840521050b200510350b024020032d0090054109470d000240201c280200220528020441ffffffff0371450d002005280200103520032802940521050b200510350b024020032d00a0054109470d000240201d280200220528020441ffffffff0371450d002005280200103520032802a40521050b200510350b024020032d00b0054109470d000240201e280200220528020441ffffffff0371450d002005280200103520032802b40521050b200510350b024020032d00c0054109470d000240201f280200220528020441ffffffff0371450d002005280200103520032802c40521050b200510350b024020032d00d0054109470d0002402020280200220528020441ffffffff0371450d002005280200103520032802d40521050b200510350b024020032d00e0054109470d0002402021280200220528020441ffffffff0371450d002005280200103520032802e40521050b200510350b024020032d00f0054109470d0002402022280200220528020441ffffffff0371450d002005280200103520032802f40521050b200510350b024020032d0080064109470d0002402014280200220528020441ffffffff0371450d002005280200103520032802840621050b200510350b024020032d0090064109470d0002402012280200220528020441ffffffff0371450d002005280200103520032802940621050b200510350b024020032d00a0064109470d0002402001280200220528020441ffffffff0371450d002005280200103520032802a40621050b200510350b024020032d00b0064109470d0002402013280200220528020441ffffffff0371450d002005280200103520032802b40621050b200510350b024020032d00c0064109470d0002402031280200220528020441ffffffff0371450d002005280200103520032802c40621050b200510350b200a4280808080808c0184210a202a41016a212a2023210520232024470d020c040b200d450d02200d417f6a210d200720084102746a4194036a28020021070c000b0b0b41a081cc0041800141a082cc001064000b0240203041ffffffff0371450d00202f10350b200341e0046a200341b0016a418c01109d081a200341f0076a200341e0046a10f106024020034180086a2802002205450d0020032802f8072226200541306c6a21272003280264210b200328026021280340024020262d000041786a220541024b0d0002400240024020050e03000102000b202628020c2207450d0220262802042205200741146c6a212a03400240200528020c0d002028450d002005280210210d20282106200b21230340200641286a2109200641086a210820062f010622254102742107417f210e02400340024020070d002025210e0c020b2008280200210c200e41016a210e200941206a21092007417c6a2107200841046a21080240417f200c200d47200c200d4b1b41016a0e03020001020b0b02402009417c6a280200450d00200520092802003602100c030b41b082cc00413541e882cc001064000b2023450d012023417f6a21232006200e4102746a4194036a28020021060c000b0b200541146a2205202a470d000c030b0b2028450d012026280204210c20282109200b210d0340200941286a2108200941086a210720092f0106222a4102742105417f210602400340024020050d00202a21060c020b2007280200210e200641016a2106200841206a21082005417c6a2105200741046a21070240417f200e200c47200e200c4b1b41016a0e03020001020b0b02402008417c6a280200450d00202620082802003602040c040b41b082cc00413541e882cc001064000b200d450d02200d417f6a210d200920064102746a4194036a28020021090c000b0b202628020c2205450d00202628020422292005411c6c6a21240340024020292802182205450d002029280210220d20054102746a2125034002402028450d00200d280200210c20282109200b212a0340200941286a2108200941086a210720092f010622234102742105417f210602400340024020050d00202321060c020b2007280200210e200641016a2106200841206a21082005417c6a2105200741046a21070240417f200e200c47200e200c4b1b41016a0e03020001020b0b02402008417c6a280200450d00200d20082802003602000c030b41b082cc00413541e882cc001064000b202a450d01202a417f6a212a200920064102746a4194036a28020021090c000b0b200d41046a220d2025470d000b0b2029411c6a22292024470d000b0b202641306a22262027470d000b0b20032902f4072232422088a72105200341fc076a290200210a20032802f0072129200341e0006a10e1072032a7212b410021070c090b2003200536027c0240024002400240200520104f0d00200f20054102746a280200220e450d070240200328025822092003280254470d00200341d0006a20094101108601200328025821090b200328025020094102746a20053602002003200941016a360258200341e0046a200328027c2223200341386a10e00720032802e804212b20032802e404212920032802e004222c4101460d0320292802082205417f4c0d042029280200210d20292d000c212720050d01410021094101210c0c020b200341013602f404200342023702e4042003419081cc003602e004200341013602d4032003200341d0036a3602f0042003200341fc006a3602d003200341f0076a200341e0046a104120032902f407220a422088a7210520032802f0072129200aa7212b0c0a0b20051033220c450d0d200521090b0240024020092005490d00200921060c010b200941017422062005200620054b1b22064100480d08024020090d0020061033220c450d0f0c010b024020092006470d00200921060c010b200c200920061037220c450d0e0b200c200d2005109d082109200320273a008c01200320053602880120032006360284012003200936028001200320292d000d3a008d012003200e36029c012003200328027c360298012003410036029001200320032f01f0073b018e010240024020032802702205450d00200328027421270c010b20164200370100201742003701002018420037010020194200370100201a420037010020154200370100200341e0046a410041e002109f081a41940310332205450d0e4100212720054100360200200520032903f0073702042005410c6a200341f0076a41086a290300370200200541146a200341f0076a41106a2903003702002005411c6a200341f0076a41186a290300370200200541246a200341f0076a41206a2903003702002005412c6a201b290300370200200541346a200341e0046a41e002109d081a20034100360274200320053602700b0340200541146a2109200541086a210e200541066a212d20052f0106222e4102742106417f210c02400340024020060d00202e210c0c020b200e280200210d200c41016a210c200941206a21092006417c6a2106200e41046a210e0240417f200d202347200d20234b1b41016a0e03020001020b0b200929020021322009200329038001370200200941186a200329039801370200200941106a220529020021332005200329039001370200200941086a200329038801370200203342ffffffff0f83420285500d05203242808080807083500d052032a710350c050b02402027450d002027417f6a21272005200c4102746a4194036a28020021050c010b0b2003200328027841016a36027820032903980121322003290390012133200329038801213420032903800121350240202d2f01002206410b490d0020164200370100201742003701002018420037010020194200370100201a420037010020154200370100200341e0046a410041e002109f081a41940310332209450d0e20094100360200200920032903f0073702042009410c6a200341f0076a41086a221e290300370200200941146a200341f0076a41106a221f2903003702002009411c6a200341f0076a41186a2220290300370200200941246a200341f0076a41206a22362903003702002009412c6a201b290300370200200941346a200341e0046a41e002109d08210e200341e0046a41086a2227200541fc016a290200370300200341e0046a41106a222e20054184026a290200370300200341e0046a41186a221c2005418c026a290200370300200320052902f4013703e00420052802202112200941086a200541246a20052f010641796a2206410274109d08210d200e20054194026a2006410574109d08210e200541063b0106200920063b01062020201c290300370300201f202e290300370300201e2027290300370300200320032903e0043703f00702400240200c4107490d00200d200c417a6a222d4102746a200d200c41796a220c4102746a220d200641ffff0371200c6b410274109e081a200d2023360200200e202d4105746a200e200c4105746a2206200941066a222d2f0100200c6b410574109e081a200641186a2032370200200620333702102006203437020820062035370200202d2f0100210e0c010b200541086a2206200c41016a220d4102746a2006200c4102746a2206202d2f0100220e200c6b221d410274109e081a20062023360200200541346a2206200d4105746a2006200c4105746a2206201d410574109e081a200641186a20323702002006203337021020062034370208200620353702000b202d200e41016a3b0100200341d0036a41186a222120202903002232370300200341d0036a41106a2222201f2903002233370300200341d0036a41086a2214201e2903002234370300200341b0016a41186a22012032370300200341b0016a41106a22132033370300200341b0016a41086a22312034370300200320032903f00722323703d003200320323703b00102402005280200220d0d004100212f200921060c040b20052f0104212d4100212f200921300340200341c0026a41186a22372001290300370300200341c0026a41106a22382013290300370300200341c0026a41086a22392031290300370300200320032903b0013703c002202d41ffff0371210c024002400240200d2f01062205410b490d0020164200370100201742003701002018420037010020194200370100201a4200370100201542003701002014201e2903003703002022201f29030037030020212020290300370300200341d0036a41206a22052036290300370300200341d0036a41286a2209201b290300370300200320032903f0073703d003200341e0046a4100419003109f081a41c40310332206450d1220064100360200200620032903d0033702042006410c6a2014290300370200200641146a20222903003702002006411c6a2021290300370200200641246a20052903003702002006412c6a2009290300370200200641346a200341e0046a419003109d082109200d280220213a201c200d418c026a290200370300202e200d4184026a2902003703002027200d41fc016a2902003703002003200d2902f4013703e004200641086a200d41246a200d2f0106220e41796a2205410274109d08213b2009200d4194026a2005410574109d08213c20064194036a200d41b0036a200e417a6a2223410274109d08211d200d41063b0106200620053b010602402023450d0041002105201d210903402009280200220e20053b0104200e2006360200200941046a21092023200541016a2205470d000b0b2020201c2903002232370300201f202e2903002233370300201e20272903002234370300200320032903e00422353703f007201c2032370300202e203337030020272034370300200320353703e004202d41ffff037122094107490d01203b200c417a6a220e41027422236a203b200c41796a22054102746a220920062f010620056b410274109e081a20092012360200203c200e4105746a203c20054105746a220920062f010620056b410574109e081a200941186a2037290300370200200941106a2038290300370200200941086a2039290300370200200920032903c002370200200620062f010641016a22093b0106200c410274222d201d6a416c6a201d20236a2223200941ffff0371220c200e6b410274109e081a20232030360200200c200e490d022006202d6a41fc026a210903402009280200220e200541016a22053b0104200e2006360200200941046a21092005200c490d000c030b0b200d41086a2209200c41016a2206410274220e6a2009200c41027422236a22092005200c6b2227410274109e081a20092012360200200d41346a220920064105746a2009200c4105746a22092027410574109e081a200941186a2037290300370200200941106a2038290300370200200941086a2039290300370200200920032903c002370200200d200541016a22053b01062023200d4194036a22096a41086a2009200e6a2209200541ffff0371220e20066b410274109e081a20092030360200200c200e4f0d07200d2006417f6a22054102746a4198036a2109034020092802002206200541016a22053b01042006200d360200200941046a21092005200e490d000c080b0b200d41086a2205200c41016a2223410274220e6a2005200c410274222d6a2205200d2f0106221d200c6b223b410274109e081a20052012360200200d41346a220520234105746a2005200c4105746a2205203b410574109e081a200541186a2037290300370200200541106a2038290300370200200541086a2039290300370200200520032903c002370200200d201d41016a22053b0106202d200d4194036a221d6a41086a201d200e6a221d200541ffff0371220e20236b410274109e081a201d20303602002009200e4f0d00200d202d6a4198036a2105034020052802002209200c41016a220c3b01042009200d360200200541046a2105200e200c470d000b0b202f41016a212f2001201c2903003703002013202e29030037030020312027290300370300200320032903e0043703b0010240200d28020022050d00203a21120c050b200d2f0104212d2005210d203a2112200621300c000b0b200541086a2209200c41016a220e4102746a2009200c4102746a22092006200c6b220d410274109e081a20092023360200200541346a2209200e4105746a2009200c4105746a2209200d410574109e081a200941186a20323702002009203337021020092034370208200920353702002005200641016a3b01060c030b20032802ec0421050c070b1044000b20164200370100201742003701002018420037010020194200370100201a4200370100201542003701002014201e2903003703002022201f29030037030020212020290300370300200341d0036a41206a22092036290300370300200341d0036a41286a220e201b290300370300200320032903f0073703d003200341e0046a4100419003109f081a41c40310332205450d0a20054100360200200520032903d0033702042005410c6a2014290300370200200541146a20222903003702002005411c6a2021290300370200200541246a20092903003702002005412c6a200e290300370200200541346a200341e0046a419003109d08210e2005200328027022093602940320032003280274220c41016a360274200941003b01042003200536027020092005360200201c2001290300370300202e201329030037030020272031290300370300200320032903b0013703e004200c202f470d0220052f01062209410a4b0d03200e20094105746a220e20032903e004370200200e41086a2027290300370200200e41106a202e290300370200200e41186a201c290300370200200520094102746a41086a20123602002005200941016a22094102746a4194036a2006360200200520093b0106200620093b0104200620053602000b202c450d00202b450d00202910350c000b0b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b103e000b200341f0006a10e1070240200328025441ffffffff0371450d00200328025010350b20032802402208200328024810f406410121070240200341c4006a2802002203450d00200341306c450d00200810350b0b20002029360204200041086a2005ad422086202bad843702000240024020070d0020004100360200200041106a200a370200201141ffffffff03710d010c030b20004101360200201141ffffffff0371450d020b200f10350c010b2001280208200128021010f4062001410c6a2802002203450d00200341306c450d0020012802081035200424000f0b200424000f0b1045000b103c000bf6c70103017f037e1b7f230041e0006b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e10010002161514131211100e0f0d0c0403010b200141046a29020021042001410c6a2902002105200141146a2902002106200341003a00002002200341011078200341106a20063703002003200537030820032004370300200341d0006a2003200210c10720032d0050411f460d1c20002003290350370200200041086a200341d0006a41086a2903003702000c1d0b200141086a28020021072001410c6a2802002108200141046a2802002109200320012d00013a0000200220034101107820022009200810782007450d1b200910350c1b0b200141086a280200210a200141046a280200210b2001410c6a280200210c200341013a00002002200341011078200b200c4104746a210d41002107410021094101210e200c210803400240024020072009460d00200921010c010b200941016a22012009490d162009410174220f2001200f20014b1b22014100480d160240024020090d00024020010d004101210e0c020b20011033220e0d010c200b20092001460d00200e200920011037220e450d1f0b200121090b200e20076a200841807f72200841ff00712008410776220f1b3a0000200741016a2107200f2108200f0d000b0240200c0d00200b21100c190b200b21090340200941106a211020092d000d22114105460d1920092d000c2108200928020821122009280204211320092802002114024020012007470d00200741016a22012007490d16200741017422092001200920014b1b22014100480d16024020070d00024020010d004101210e0c020b20011033220e450d1f0c010b20072001460d00200e200720011037220e450d1e0b200e20076a20083a0000200741016a2109200741017441046a21152012210703402015210c0240024020092001460d002001210f0c010b200141016a22082001490d172001410174220f2008200f20084b1b220f4100480d170240024020010d000240200f0d004101210e0c020b200f1033220e450d210c010b2001200f460d00200e2001200f1037220e450d200b200f21010b200e20096a200741807f72200741ff0071200741077622081b3a0000200c41026a2115200941016a21092008210720080d000b0240024020120d00200921070c010b410021010340200920016a210741fc0021080240024002400240201420016a2d00000e050200010305020b41fe0021080c020b41fd0021080c010b41ff0021080b200320083a000002402007200f470d00200741016a220f2007490d18200c200f200c200f4b1b220f4100480d18024020070d000240200f0d004101210e0c020b200f1033220e450d210c010b2007200f460d00200e2007200f1037220e450d200b200e20096a20016a20083a0000200c41026a210c2012200141016a2201470d000b200920016a21070b02402013450d00201410350b41002109024020114104460d000240200f2007470d00200741016a22012007490d17200741017422092001200920014b1b220f4100480d17024020070d000240200f0d004101210e0c020b200f1033220e450d200c010b2007200f460d00200e2007200f1037220e450d1f0b200e20076a41013a0000200741016a2107201141077141ff007321090b02400240200f2007460d00200f21010c010b200741016a22012007490d16200741017422082001200820014b1b22014100480d16024020070d00024020010d004101210e0c020b20011033220e450d1f0c010b20072001460d00200e200720011037220e450d1e0b200e20076a20093a0000200741016a2107201021092010200d470d000c1a0b0b200141286a2802002112200141246a280200210a200141206a280200210d2001411c6a2802002114200141186a2802002113200141146a2802002110200141086a280200210b200141046a28020021112001410c6a2902002104200341003a00002002200341011078200341d0006a410c6a410036020020034201370254200320023602502004a7221541017441026a21092004422088a7210f41002107410021012015210803400240024020012007460d002003280254210c0c010b200741016a220c2007490d032007410174220e200c200e200c4b1b220e4100480d030240024020070d000240200e0d004101210c0c020b200e1033220c450d0b0c010b2003280254210c2007200e460d00200c2007200e1037220c450d0a0b2003200e3602582003200c3602540b200c20016a200841807f72200841ff00712008410776220c1b3a00002003200141016a220136025c200941026a210920032802582107200c2108200c0d000b02400240200720016b2015490d002003280254210c200721080c010b200120156a22082001490d022007410174220c2008200c20084b1b22084100480d020240024020070d00024020080d004101210c0c020b20081033220c450d0a0c010b2003280254210c20072008460d00200c200720081037220c450d090b200320083602582003200c3602540b200c20016a20112015109d081a2003201520016a36025c0240200b450d00201110350b034002400240201520016a220c2008460d00200328025421070c010b200841016a22072008490d032008410174220e2007200e20074b1b220e4100480d030240024020080d000240200e0d00410121070c020b200e10332207450d0b0c010b200328025421072008200e460d0020072008200e10372207450d0a0b2003200e360258200320073602540b200720156a20016a200f41807f72200f41ff0071200f41077622071b3a00002003200c41016a36025c02402007450d00200941026a2109200141016a2101200328025821082007210f0c010b0b0240024020100d00200c41016a2101410121020c010b2015417f732102201541016a210c20142107034002400240200c20016a22082003280258460d002003280254210f0c010b200841016a220f2008490d042009200f2009200f4b1b220e4100480d040240024020022001470d000240200e0d004101210f0c020b200e1033220f450d0c0c010b2003280254210f2008200e460d00200f2008200e1037220f450d0b0b2003200e3602582003200f3602540b200f200c6a20016a200741807f72200741ff00712007410776220f1b3a00002003200841016a36025c200941026a2109200141016a2101200f2107200f0d000b024002402001417f732003280258220720156b6a2014490d00200328025421090c010b201520016a41016a220820146a22092008490d03200741017422082009200820094b1b22084100480d030240024020070d00024020080d00410121090c020b200810332209450d0b0c010b2003280254210920072008460d0020092007200810372209450d0a0b20032008360258200320093602540b201520096a20016a41016a20102014109d081a2003201420156a20016a41016a220136025c410021022013450d00201010350b20014101742107200d20124104746a210e2012210903400240024020012003280258460d00200328025421080c010b200141016a22082001490d0320072008200720084b1b220f4100480d030240024020010d000240200f0d00410121080c020b200f10332208450d0b0c010b200328025421082001200f460d0020082001200f10372208450d0a0b2003200f360258200320083602540b200820016a200941807f72200941ff0071200941077622081b3a00002003200141016a220136025c200741026a21072008210920080d000b024002402012450d00200d210c0340200c410c6a2802002115200c41086a2802002101200c28020421090240024002400240024002400240024002400240200c2802000e0900010203040506070b000b200341003a0000024002402003280258200328025c2207460d004100210f200328025421080c010b200741016a22082007490d0e2007410174220f2008200f20084b1b220f4100480d0e0240024020070d000240200f0d00410121080c020b200f10332208450d160c010b200328025421082007200f460d0020082007200f10372208450d150b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0f2007410174220f2009200f20094b1b220f4100480d0f0240024020070d000240200f0d00410121090c020b200f10332209450d170c010b200328025421092007200f460d0020092007200f10372209450d160b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0f200741017422082001200820014b1b22084100480d0f0240024020070d00024020080d00410121010c020b200810332201450d170c010b2003280254210120072008460d0020012007200810372201450d160b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c2009210120090d000c090b0b200341013a0000024002402003280258200328025c2207460d004101210f200328025421080c010b200741016a22082007490d0d2007410174220f2008200f20084b1b220f4100480d0d0240024020070d000240200f0d00410121080c020b200f10332208450d150c010b200328025421082007200f460d0020082007200f10372208450d140b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0e2007410174220f2009200f20094b1b220f4100480d0e0240024020070d000240200f0d00410121090c020b200f10332209450d160c010b200328025421092007200f460d0020092007200f10372209450d150b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0e200741017422082001200820014b1b22084100480d0e0240024020070d00024020080d00410121010c020b200810332201450d160c010b2003280254210120072008460d0020012007200810372201450d150b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c200921012009450d080c000b0b200341023a0000024002402003280258200328025c2207460d004102210f200328025421080c010b200741016a22082007490d0c2007410174220f2008200f20084b1b220f4100480d0c0240024020070d000240200f0d00410121080c020b200f10332208450d140c010b200328025421082007200f460d0020082007200f10372208450d130b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0d2007410174220f2009200f20094b1b220f4100480d0d0240024020070d000240200f0d00410121090c020b200f10332209450d150c010b200328025421092007200f460d0020092007200f10372209450d140b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0d200741017422082001200820014b1b22084100480d0d0240024020070d00024020080d00410121010c020b200810332201450d150c010b2003280254210120072008460d0020012007200810372201450d140b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c200921012009450d070c000b0b200341033a0000024002402003280258200328025c2207460d004103210f200328025421080c010b200741016a22082007490d0b2007410174220f2008200f20084b1b220f4100480d0b0240024020070d000240200f0d00410121080c020b200f10332208450d130c010b200328025421082007200f460d0020082007200f10372208450d120b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0c2007410174220f2009200f20094b1b220f4100480d0c0240024020070d000240200f0d00410121090c020b200f10332209450d140c010b200328025421092007200f460d0020092007200f10372209450d130b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0c200741017422082001200820014b1b22084100480d0c0240024020070d00024020080d00410121010c020b200810332201450d140c010b2003280254210120072008460d0020012007200810372201450d130b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c2009210120090d000b20032015200341d0006a10a50720032d00002201411f460d0520032f000120032d00034110747221090c040b200341043a0000024002402003280258200328025c2207460d004104210f200328025421080c010b200741016a22082007490d0a2007410174220f2008200f20084b1b220f4100480d0a0240024020070d000240200f0d00410121080c020b200f10332208450d120c010b200328025421082007200f460d0020082007200f10372208450d110b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0b2007410174220f2009200f20094b1b220f4100480d0b0240024020070d000240200f0d00410121090c020b200f10332209450d130c010b200328025421092007200f460d0020092007200f10372209450d120b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0b200741017422082001200820014b1b22084100480d0b0240024020070d00024020080d00410121010c020b200810332201450d130c010b2003280254210120072008460d0020012007200810372201450d120b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c2009210120090d000b20032015200341d0006a10a50720032d00002201411f460d0420032f000120032d00034110747221090c030b200341053a0000024002402003280258200328025c2207460d004105210f200328025421080c010b200741016a22082007490d092007410174220f2008200f20084b1b220f4100480d090240024020070d000240200f0d00410121080c020b200f10332208450d110c010b200328025421082007200f460d0020082007200f10372208450d100b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0a2007410174220f2009200f20094b1b220f4100480d0a0240024020070d000240200f0d00410121090c020b200f10332209450d120c010b200328025421092007200f460d0020092007200f10372209450d110b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0a200741017422082001200820014b1b22084100480d0a0240024020070d00024020080d00410121010c020b200810332201450d120c010b2003280254210120072008460d0020012007200810372201450d110b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c2009210120090d000b20032015200341d0006a10a50720032d00002201411f460d0320032f000120032d00034110747221090c020b200341063a0000024002402003280258200328025c2207460d004106210f200328025421080c010b200741016a22082007490d082007410174220f2008200f20084b1b220f4100480d080240024020070d000240200f0d00410121080c020b200f10332208450d100c010b200328025421082007200f460d0020082007200f10372208450d0f0b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d092007410174220f2009200f20094b1b220f4100480d090240024020070d000240200f0d00410121090c020b200f10332209450d110c010b200328025421092007200f460d0020092007200f10372209450d100b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d09200741017422082001200820014b1b22084100480d090240024020070d00024020080d00410121010c020b200810332201450d110c010b2003280254210120072008460d0020012007200810372201450d100b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c200921012009450d030c000b0b200341073a0000024002402003280258200328025c2207460d004107210f200328025421080c010b200741016a22082007490d072007410174220f2008200f20084b1b220f4100480d070240024020070d000240200f0d00410121080c020b200f10332208450d0f0c010b200328025421082007200f460d0020082007200f10372208450d0e0b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d082007410174220f2009200f20094b1b220f4100480d080240024020070d000240200f0d00410121090c020b200f10332209450d100c010b200328025421092007200f460d0020092007200f10372209450d0f0b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d08200741017422082001200820014b1b22084100480d080240024020070d00024020080d00410121010c020b200810332201450d100c010b2003280254210120072008460d0020012007200810372201450d0f0b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c200921012009450d020c000b0b200328020c210f20032802082108200328020421070240200a41ffffffff0071450d00200d10350b2003280258450d03200328025410350c030b200c41106a220c200e470d000b0b0240200a41ffffffff0071450d00200d10350b200328025c21082003280258210c2003280254210f20032802502107200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f200810780240200c450d00200f10350b2010450d1a2002450d1a2013450d1a201010350c1a0b02402010450d002002450d002013450d00201010350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a200f360000200041086a2008360000200041046a20073600000c1a0b2001412c6a2802002116200141286a2802002117200141246a280200210d200141206a28020021182001411c6a2802002119200141186a280200211a200141146a280200210b2001410c6a2902002104200141086a280200211b200141046a280200211341002112200341003a000041012108200220034101107802400240024041041033220a450d00200a41eec2b5ab06360000024020130d00410021114100211c0c030b200341003a00004101210c41002101410021092004a72215210703402003200741807f72200741ff0071200741077622081b22073a00000240024020012009460d002001210f0c010b200141016a22092001490d172001410174220f2009200f20094b1b220f4100480d170240024020010d00410021090240200f0d004101210c0c020b200f1033220c450d210c010b02402001200f470d00200121090c010b20012109200c2001200f1037220c450d200b200f21010b200c20096a20073a0000200941016a21092008210720080d000b02400240200f20096b2015490d00200f21100c010b200920156a22012009490d04200f41017422072001200720014b1b22104100480d040240200f0d00024020100d004101210c0c020b20101033220c450d1f0c010b200f2010460d00200c200f20101037220c450d0a0b200c20096a20132015109d081a0240201b450d00201310350b200341003a0000410110332208450d09200841003a0000200341003a0000410121014101210f200920156a220e210903402003200941807f72200941ff0071200941077622071b22093a00000240200f2001470d00200141016a220f2001490d0520014101742215200f2015200f4b1b220f4100480d05024020010d00410021010240200f0d00410121080c020b200f103322080d010c0c0b2001200f460d0020082001200f10372208450d0b0b200820016a20093a0000200141016a21012007210920070d000b0240200f20016b200e490d00200f21110c020b2001200e6a22092001490d03200f41017422072009200720094b1b22114100480d030240200f0d00024020110d00410121080c030b201110332208450d0a0c020b200f2011460d012008200f201110372208450d090c010b1045000b200820016a200c200e109d081a2001200e6a21124101211c2010450d00200c10350b02400240200b0d004101211d0c010b4100211d20034100360240200342013703382003410c6a2019360200200341086a201a3602002003200b360204200320044220883e0200200341d0006a2003200341386a10c20720032d0050411f470d04200341013a00000240024020112012460d002011210f0c010b201241016a22012012490d02201241017422092001200920014b1b220f4100480d02024020120d00410021120240200f0d00410121080c020b200f10332208450d090c010b2012200f460d0020082012200f10372208450d080b200820126a41013a000020032802402115200341003a0000201241016a21012015210903402003200941807f72200941ff0071200941077622071b22093a00000240200f2001470d00200141016a220f2001490d032001410174220c200f200c200f4b1b220f4100480d03024020010d00410021010240200f0d00410121080c020b200f10332208450d0a0c010b2001200f460d0020082001200f10372208450d090b200820016a20093a0000200141016a21012007210920070d000b2003280238210902400240200f20016b2015490d00200f21110c010b200120156a22072001490d02200f410174220c2007200c20074b1b22114100480d020240200f0d00024020110d00410121080c020b201110332208450d090c010b200f2011460d002008200f201110372208450d080b200820016a20092015109d081a0240200328023c450d00200910350b200120156a21124100211d0b0240200d0d004100210f0c030b2003410036024020034201370338200341003a00004101210c41002109410021012018210703402003200741807f72200741ff00712007410776220f1b22153a0000024020092001470d00200941016a22012009490d02200941017422072001200720014b1b22074100480d020240024020090d0041002101024020070d004101210c0c020b20071033220c450d0a0c010b024020092007470d00200921010c010b20092101200c200920071037220c450d090b2003200736023c2003200c360238200721090b200c20016a20153a00002003200141016a2201360240200f2107200f0d000b200d20164104746a211002400240024020160d00200d210c0c010b200d210c2018450d00201041706a211e41002101200d211f02400340201f210f02400340200f41046a28020022140d01200141016a21012010200f41106a220f470d000c050b0b200f41086a2902002104200f2802002120200341003a0000200f41106a211f200141016a21212018417f6a2118200328023c21072003280240210903402003200141807f72200141ff00712001410776220c1b220e3a00000240024020072009460d00200328023821010c010b200741016a22012007490d06200741017422092001200920014b1b22154100480d060240024020070d0041002109024020150d00410121010c020b201510332201450d0e0c010b20032802382101024020072015470d00200721090c010b2007210920012007201510372201450d0d0b2003201536023c20032001360238201521070b200120096a200e3a00002003200941016a2209360240200c2101200c0d000b200320043703082003201436020420032020360200200341d0006a2003200341386a10c207024020032d0050220e411f470d00201e200f460d022021210120180d010c020b0b20032d0053211520032f005121202003280254211f20032802582118200328025c21140240201041706a200f460d00200f41106a210c0340200c220f41106a210c0240200f2802042201450d000240200f410c6a2802002209450d002009410c6c21090340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b200f41086a2802002201450d002001410c6c450d00200f28020410350b200c2010470d000b0b201541107421010240201741ffffffff0071450d00200d10350b202020017221104101210f200328023c450d07200328023810350c070b200f41106a210c0b2010200c460d000340200c220f41106a210c0240200f2802042201450d000240200f410c6a2802002209450d002009410c6c21090340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b200f41086a2802002201450d002001410c6c450d00200f28020410350b200c2010470d000b0b0240201741ffffffff0071450d00200d10350b200341023a00000240024020112012460d002011210f0c010b201241016a22012012490d01201241017422092001200920014b1b220f4100480d01024020120d00410021120240200f0d00410121080c020b200f10332208450d080c010b2012200f460d0020082012200f10372208450d070b200820126a41023a000020032802402115200341003a0000201241016a21012015210903402003200941807f72200941ff0071200941077622071b22093a00000240200f2001470d00200141016a220f2001490d022001410174220c200f200c200f4b1b220f4100480d02024020010d00410021010240200f0d00410121080c020b200f10332208450d090c010b2001200f460d0020082001200f10372208450d080b200820016a20093a0000200141016a21012007210920070d000b200328023821090240200f20016b2015490d00200f21110c020b200120156a22072001490d00200f410174220c2007200c20074b1b22114100480d000240200f0d00024020110d00410121080c030b201110332208450d070c020b200f2011460d012008200f201110372208450d060c010b103e000b200820016a20092015109d081a0240200328023c450d00200910350b200120156a21124101210f0b0240201345201c720d00201b450d00201310350b0240200b450d00201d4101730d0002402019450d002019410c6c2109200b21010340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b201a450d00201a410c6c450d00200b10350b200d45200f720d0202402016450d00200d20164104746a2115200d210c0340200c220f41106a210c0240200f2802042201450d000240200f410c6a2802002209450d002009410c6c21090340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b200f41086a2802002201450d002001410c6c450d00200f28020410350b200c2015470d000b0b201741ffffffff0071450d02200d10350c020b2003280250220e4108762110200341d0006a410c6a2802002114200341d0006a41086a28020021182003280254211f0240200328023c450d00200328023810350b4100210f0b0240201c201345720d00201b450d00201310350b0240200b450d00201d4101730d0002402019450d002019410c6c2109200b21010340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b201a450d00201a410c6c450d00200b10350b0240200d45200f720d0002402016450d00200d20164104746a2115200d210c0340200c220f41106a210c0240200f2802042201450d000240200f410c6a2802002209450d002009410c6c21090340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b200f41086a2802002201450d002001410c6c450d00200f28020410350b200c2015470d000b0b201741ffffffff0071450d00200d10350b200e41ff01712201411f460d002010410874200172210102402011450d00200810350b200020013602002000410c6a2014360200200041086a2018360200200041046a201f360200200a10350c140b200341146a2012360200200341106a20113602002003200836020c20034284808080c0003702042003200a360200200341d0006a2003200210c10720032d0050411f460d1220002003290350370200200041086a200341d0006a41086a2903003702000c130b103c000b200141086a280200210e200141046a28020021152001410c6a280200210c2003410b3a00002002200341011078200341386a410c6a41003602002003420137023c200320023602382015200c411c6c6a210d4100210141002109200c210703400240024020092001460d00200328023c21080c010b200141016a22082001490d0c2001410174220f2008200f20084b1b220f4100480d0c0240024020010d000240200f0d00410121080c020b200f10332208450d160c010b200328023c21082001200f460d0020082001200f10372208450d150b2003200f3602402003200836023c0b200820096a200741807f72200741ff0071200741077622071b3a00002003200941016a220936024402402007450d0020032802402101200721070c010b0b2003200d36025c200320153602582003200e360254200320153602500240200c450d000340200320152201411c6a22153602582001280210220e450d012001410c6a2802002102200141086a28020021102001280204210c200141146a290200210420012802002109200341003a00002003280244210103402003200941807f72200941ff0071200941077622071b22083a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0e200141017422082009200820094b1b22084100480d0e0240024020010d00024020080d00410121090c020b200810332209450d180c010b200328023c210920012008460d0020092001200810372209450d170b200320083602402003200936023c20032d00002108200328024421010b200920016a20083a00002003200141016a22013602442007210920070d000b024002400240200c0d00410121140c010b200320023602302003201036022c2003200c3602282003200341286a200341386a10a20720032d00002201411f470d0141002114200328024421010b200341003a00002004a721122004422088a7220f210903402003200941807f72200941ff0071200941077622071b22083a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0f200141017422082009200820094b1b22084100480d0f0240024020010d00024020080d00410121090c020b200810332209450d190c010b200328023c210920012008460d0020092001200810372209450d180b200320083602402003200936023c20032d00002108200328024421010b200920016a20083a00002003200141016a22013602442007210920070d000b024002402003280240220720016b200f490d00200328023c21090c010b2001200f6a22092001490d0e200741017422012009200120094b1b22014100480d0e0240024020070d00024020010d00410121090c020b200110332209450d180c010b200328023c210920072001460d0020092007200110372209450d170b200320013602402003200936023c200328024421010b200920016a200e200f109d081a20032001200f6a36024402402012450d00200e10350b0240200c450d002014450d0002402002450d0020024104742109200c21010340024020012d00004109470d000240200141046a2208280200220728020441ffffffff0371450d0020072802001035200828020021070b200710350b200141106a2101200941706a22090d000b0b201041ffffffff0071450d00200c10350b2015200d470d010c020b0b20032d0003411074210920032f00012107200328020c21082003280208210f2003280204210c02402004a7450d00200e10350b20072009722109200341d0006a10c30702402003280240450d00200328023c10350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a2008360000200041086a200f360000200041046a200c3600000c120b200341d0006a10c30720032802382107200328023c210f2003280240210c20032802442108200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d10200f10350c100b200141086a280200210e200141046a280200210f2001410c6a28020021152003410a3a00002002200341011078200341186a410c6a41003602002003420137021c20032002360218200f201541186c6a210b41002101410021092015210703400240024020092001460d00200328021c21080c010b200141016a22082001490d0b2001410174220c2008200c20084b1b220c4100480d0b0240024020010d000240200c0d00410121080c020b200c10332208450d150c010b200328021c21082001200c460d0020082001200c10372208450d140b2003200c3602202003200836021c0b200820096a200741807f72200741ff0071200741077622071b3a00002003200941016a220936022402402007450d0020032802202101200721070c010b0b2003200b3602342003200f3602302003200e36022c2003200f36022802402015450d0020034101722102200341026a210e03402003200f41186a2214360230200f2802002210450d01200f41146a280200210d200f41106a2802002111200f28020c2112200f2802082107200f280204211341002109200341003602442003420137023c201020074103746a21152003200341186a3602384100210103400240024020092001460d00200328023c21080c010b200941016a22012009490d0d200941017422082001200820014b1b22014100480d0d0240024020090d00024020010d00410121080c020b200110332208450d170c010b200328023c210820092001460d0020082009200110372208450d160b200320013602402003200836023c200328024421010b200820016a200741807f72200741ff0071200741077622071b3a00002003200141016a220136024402402007450d0020032802402109200721070c010b0b024020152010460d002010210f0340200f2902002204422088a7220941ff01714104460d01200f41086a210f2009411874411875210c200341003a00002004a7210903402003200941807f72200941ff0071200941077622071b22083a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0f200141017422082009200820094b1b22084100480d0f0240024020010d00024020080d00410121090c020b200810332209450d190c010b200328023c210920012008460d0020092001200810372209450d180b200320083602402003200936023c20032d00002108200328024421010b200920016a20083a00002003200141016a22013602442007210920070d000b2003200c417f732209413f7141c000722009200c417f4a1b22073a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0e200141017422072009200720094b1b22074100480d0e0240024020010d00024020070d00410121090c020b200710332209450d180c010b200328023c210920012007460d0020092001200710372209450d170b200320073602402003200936023c20032d00002107200328024421010b200920016a20073a00002003200141016a2201360244200f2015470d000b0b0240201341ffffffff0171450d00201010350b2012200d41047422016a21070240024002400240200d0d00201221010c010b200141706a210820122101034020012d00002109200e200141036a2d00003a00002003200141016a2f00003b01000240200941ac01470d00200141106a21010c020b200341cc006a41026a200e2d0000220f3a0000200320032f0100220c3b014c200141046a2802002115200141086a29030021042002200c3b0000200241026a200f3a0000200320093a00002003200437030820032015360204200341d0006a2003200341386a10ac07024020032d0050220c411f47220f0d00200841706a2108200141106a22012007470d010c030b0b20032d0053211020032f0051210d200328025421132003280258210a200328025c211602402008450d004100210903400240200120096a220741106a2d00004109470d000240200741146a2215280200220728020441ffffffff0371450d0020072802001035201528020021070b200710350b2008200941106a2209470d000b0b0240201141ffffffff0071450d00201210350b02402003280240450d00200328023c10350b200f450d02200d2010411074722101200341286a10c40702402003280220450d00200328021c10350b200020013b00012000200c3a0000200041036a20014110763a00002000410c6a2016360000200041086a200a360000200041046a20133600000c150b20072001460d000340200141106a2109024020012d00004109470d000240200141046a2208280200220128020441ffffffff0371450d0020012802001035200828020021010b200110350b2009210120072009470d000b0b0240201141ffffffff0071450d00201210350b200328024421102003280240210d200328023c21122003280238210f200341003a0000200f410c6a220c28020021012010210903402003200941807f72200941ff0071200941077622071b22083a000002400240200f41086a22152802002001460d00200f28020421090c010b200141016a22092001490d0e200141017422082009200820094b1b22084100480d0e0240024020010d00024020080d00410121090c020b200810332209450d180c010b200f280204210920012008460d0020092001200810372209450d170b200f200936020420152008360200200c280200210120032d000021080b200920016a20083a0000200c200141016a22013602002007210920070d000b024002402015280200220720016b2010490d00200f28020421090c010b200120106a22092001490d0d200741017422012009200120094b1b22014100480d0d0240024020070d00024020010d00410121090c020b200110332209450d170c010b200f280204210920072001460d0020092007200110372209450d160b200f200936020420152001360200200c28020021010b200920016a20122010109d081a200c200120106a360200200d450d00201210350b2014210f2014200b470d000b0b200341286a10c40720032802182107200328021c210f2003280220210c20032802242108200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d0f200f10350c0f0b200141086a2802002115200141046a28020021102001410c6a280200210c200341093a00002002200341011078200341386a410c6a41003602002003420137023c200320023602382010200c411c6c6a210d4100210141002109200c210703400240024020092001460d00200328023c21080c010b200141016a22082001490d0a2001410174220f2008200f20084b1b220f4100480d0a0240024020010d000240200f0d00410121080c020b200f10332208450d140c010b200328023c21082001200f460d0020082001200f10372208450d130b2003200f3602402003200836023c0b200820096a200741807f72200741ff0071200741077622071b3a00002003200941016a220936024402402007450d0020032802402101200721070c010b0b2003200d36025c2003201036025820032015360254200320103602500240200c450d000340200320102201411c6a221036025820012802102215450d012001410c6a2802002102200141086a28020021122001280204210e200141146a2902002104200128020021092003280244210103400240024020032802402001460d00200328023c21070c010b200141016a22072001490d0c200141017422082007200820074b1b22084100480d0c0240024020010d00024020080d00410121070c020b200810332207450d160c010b200328023c210720012008460d0020072001200810372207450d150b200320083602402003200736023c200328024421010b200720016a200941807f72200941ff0071200941077622071b3a00002003200141016a22013602442007210920070d000b024002400240200e0d00410121140c010b200320023602302003201236022c2003200e3602282003200341286a200341386a10a20720032d00002201411f470d0141002114200328024421010b200341003a000020152004422088a722094102746a210c03402003200941807f72200941ff0071200941077622071b22083a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0d200141017422082009200820094b1b22084100480d0d0240024020010d00024020080d00410121090c020b200810332209450d170c010b200328023c210920012008460d0020092001200810372209450d160b200320083602402003200936023c20032d00002108200328024421010b200920016a20083a00002003200141016a22013602442007210920070d000b0240200c2015460d002015210f0340200f2802002109200341003a000003402003200941807f72200941ff0071200941077622071b22083a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0f200141017422082009200820094b1b22084100480d0f0240024020010d00024020080d00410121090c020b200810332209450d190c010b200328023c210920012008460d0020092001200810372209450d180b200320083602402003200936023c20032d00002108200328024421010b200920016a20083a00002003200141016a22013602442007210920070d000b200f41046a220f200c470d000b0b0240200442ffffffff0383500d00201510350b0240200e450d002014450d0002402002450d0020024104742109200e21010340024020012d00004109470d000240200141046a2208280200220728020441ffffffff0371450d0020072802001035200828020021070b200710350b200141106a2101200941706a22090d000b0b201241ffffffff0071450d00200e10350b2010200d470d010c020b0b20032d0003411074210920032f00012107200328020c21082003280208210f2003280204210c0240200442ffffffff0383500d00201510350b20072009722109200341d0006a10c50702402003280240450d00200328023c10350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a2008360000200041086a200f360000200041046a200c3600000c100b200341d0006a10c50720032802382107200328023c210f2003280240210c20032802442108200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d0e200f10350c0e0b200141046a28020021072003410c3a00002002200341011078200341003a000041002109410021014101210c03402003200741807f72200741ff0071200741077622081b22073a00000240024020092001460d002001210f0c010b200141016a220f2001490d0920014101742215200f2015200f4b1b220f4100480d090240024020010d000240200f0d004101210c0c020b200f1033220c450d130c010b2001200f460d00200c2001200f1037220c450d120b200f21010b200c20096a20073a0000200941016a21092008210720080d000b200341003a00002009210103402003200141800172200141ff0071200141077622071b3a000020022003410110782007210120070d000b2002200c20091078200f450d0d200c10350c0d0b200141046a2802002107200341083a00002002200341011078200341003a000041002109410021014101210c03402003200741807f72200741ff0071200741077622081b22073a00000240024020092001460d002001210f0c010b200141016a220f2001490d0820014101742215200f2015200f4b1b220f4100480d080240024020010d000240200f0d004101210c0c020b200f1033220c450d120c010b2001200f460d00200c2001200f1037220c450d110b200f21010b200c20096a20073a0000200941016a21092008210720080d000b200341003a00002009210103402003200141800172200141ff0071200141077622071b3a000020022003410110782007210120070d000b2002200c20091078200f450d0c200c10350c0c0b200141086a280200210b200141046a28020021132001410c6a280200210e200341073a00002002200341011078200341003a00002013200e41146c6a211441002101410021074101210f200e210803402003200841807f72200841ff00712008410776220c1b22083a00000240024020012007460d00200721090c010b200741016a22092007490d07200741017422152009201520094b1b22094100480d070240024020070d00024020090d004101210f0c020b20091033220f450d110c010b20072009460d00200f200720091037220f450d100b200921070b200f20016a20083a0000200141016a2101200c2108200c0d000b024002400240200e0d002013210e0c010b201321070340200741146a210e200728020c220d4104460d0120072802042111200741106a28020021082007280200211220072802082210210703400240024020012009460d00200921150c010b200941016a220c2009490d0a20094101742215200c2015200c4b1b22154100480d0a0240024020090d00024020150d004101210f0c020b20151033220f450d140c010b20092015460d00200f200920151037220f450d130b201521090b200f20016a200741807f72200741ff00712007410776220c1b3a0000200141016a2101200c2107200c0d000b02400240201520016b2010490d00201521090c010b200120106a22092001490d09201541017422072009200720094b1b22094100480d09024020150d00024020090d004101210f0c020b20091033220f450d120c010b20152009460d00200f201520091037220f450d110b200f20016a20122010109d081a201020096b20016a210702402011450d00201210350b024002402007450d00200921070c010b200941016a22072009490d092009410174220c2007200c20074b1b22074100480d09024020090d00024020070d004101210f0c020b20071033220f450d120c010b20092007460d00200f200920071037220f450d110b200f20106a20016a200d3a0000201020016a41016a210103400240024020012007460d00200721090c010b200741016a22092007490d0a2007410174220c2009200c20094b1b22094100480d0a0240024020070d00024020090d004101210f0c020b20091033220f450d140c010b20072009460d00200f200720091037220f450d130b200921070b200f20016a200841807f72200841ff00712008410776220c1b3a0000200141016a2101200c2108200c0d000b200e2107200e2014470d000c020b0b2014200e460d000340200e41146a21070240200e41046a280200450d00200e28020010350b2007210e20142007470d000b0b0240200b450d00200b41146c450d00201310350b200341003a00002001210703402003200741800172200741ff0071200741077622081b3a000020022003410110782008210720080d000b2002200f200110782009450d0b200f10350c0b0b200141086a280200210e200141046a280200210c2001410c6a2802002115200341063a00002002200341011078200341386a410c6a41003602002003420137023c20032002360238200c20154104746a210241002101410021092015210703400240024020092001460d00200328023c21080c010b200141016a22082001490d062001410174220f2008200f20084b1b220f4100480d060240024020010d000240200f0d00410121080c020b200f10332208450d100c010b200328023c21082001200f460d0020082001200f10372208450d0f0b2003200f3602402003200836023c0b200820096a200741807f72200741ff0071200741077622071b3a00002003200941016a220936024402402007450d0020032802402101200721070c010b0b2003200236025c2003200c3602582003200e3602542003200c36025002402015450d00024003400240200c410d6a2d000022094102470d00200c41106a21020c020b200c41086a280200210f200c41046a2802002115200c280200210e2003200c410c6a2d000041ff007322083a000002400240200328024020032802442201460d00200328023c21070c010b200141016a22072001490d08200141017422082007200820074b1b22084100480d080240024020010d00024020080d00410121070c020b200810332207450d120c010b200328023c210720012008460d0020072001200810372207450d110b200320083602402003200736023c20032d00002108200328024421010b200720016a20083a00002003200141016a2201360244200320093a00000240024020032802402001460d00200328023c21070c010b200141016a22092001490d08200141017422072009200720094b1b22094100480d080240024020010d00024020090d00410121070c020b200910332207450d120c010b200328023c210720012009460d0020072001200910372207450d110b200320093602402003200736023c20032d00002109200328024421010b200720016a20093a00002003200141016a3602442003200f3602302003201536022c2003200e3602282003200341286a200341386a10a207024020032d00002201411f470d00200c41106a220c2002470d010c020b0b20032f000120032d00034110747221092003280204210720032802082108200328020c210f2003200c41106a360258200341d0006a10c60702402003280240450d00200328023c10350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a200f360000200041086a2008360000200041046a20073600000c0d0b200320023602580b200341d0006a10c60720032802382107200328023c210f2003280240210c20032802442108200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d0a200f10350c0a0b2001410c6a2802002110200141086a2802002112200141046a280200210e200341053a00002002200341011078200341d0006a410c6a41003602002003420137025420032002360250200341003a0000410021014101210f4100210920102107034020032007220741807f72200741ff0071200741077622071b22083a0000024020012009470d00200941016a220c2009490d0520094101742215200c2015200c4b1b220c4100480d05024002400240024020090d000240200c0d004101210f0c020b200c1033210f0c030b2009200c470d010b200c21090c020b200f2009200c1037210f0b200c2109200f450d0d0b200f20016a20083a0000200141016a210120070d000b2003200136025c2003200f36025420032009360258024002402010450d002010410c6c2108410021010340200e20016a220941046a28020022074102460d01200320092802002007200941086a280200200341d0006a10af0720032d00002209411f470d0220082001410c6a2201470d000b0b02402012450d002012410c6c450d00200e10350b200328025c21082003280258210c2003280254210f20032802502107200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d0a200f10350c0a0b20032d0003411074210120032f00012107200328020c21082003280208210f2003280204210c02402012450d002012410c6c450d00200e10350b2007200172210102402003280258450d00200328025410350b200020013b0001200020093a0000200041036a20014110763a00002000410c6a2008360000200041086a200f360000200041046a200c3600000c0a0b2001410c6a2802002115200141086a2802002110200141046a280200210e200341043a00002002200341011078200341d0006a410c6a4100360200200342013702542003200236025041002101410121084100210920152107034020072107024020012009470d00200941016a220f2009490d042009410174220c200f200c200f4b1b220f4100480d04024002400240024020090d000240200f0d00410121080c020b200f103321080c030b2009200f470d010b200f21090c020b20082009200f103721080b200f21092008450d0c0b200820016a200741807f72200741ff0071200741077622071b3a0000200141016a210120070d000b2003200136025c2003200836025420032009360258024002402015450d002015410c6c2102410021090340200e20096a220141046a28020022084102460d012001280200210f200141086a280200210c200341f0003a0000024002402003280258200328025c2201460d0041f0002115200328025421070c010b200141016a22072001490d06200141017422152007201520074b1b22154100480d060240024020010d00024020150d00410121070c020b201510332207450d100c010b2003280254210720012015460d0020072001201510372207450d0f0b200320153602582003200736025420032d000021150b200720016a20153a00002003200141016a36025c2003200f2008200c200341d0006a10af0720032d00002201411f470d0220022009410c6a2209470d000b0b02402010450d002010410c6c450d00200e10350b200328025c21082003280258210c2003280254210f20032802502107200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d09200f10350c090b20032d0003411074210920032f00012107200328020c21082003280208210f2003280204210c02402010450d002010410c6c450d00200e10350b2007200972210902402003280258450d00200328025410350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a2008360000200041086a200f360000200041046a200c3600000c090b200141086a2802002114200141046a28020021122001410c6a280200210e200341033a00002002200341011078200341003a00002012200e4102746a211041002109410021074101210c200e210803402003200841807f72200841ff00712008410776220f1b22083a00000240024020092007460d00200721010c010b200741016a22012007490d03200741017422152001201520014b1b22014100480d030240024020070d00024020010d004101210c0c020b20011033220c450d0d0c010b20072001460d00200c200720011037220c450d0c0b200121070b200c20096a20083a0000200941016a2109200f2108200f0d000b02400240200e0d002001210f0c010b2012210e0340200e2802002107200341003a000003402003200741807f72200741ff0071200741077622081b22073a00000240024020092001460d002001210f0c010b200141016a220f2001490d0520014101742215200f2015200f4b1b220f4100480d050240024020010d000240200f0d004101210c0c020b200f1033220c450d0f0c010b2001200f460d00200c2001200f1037220c450d0e0b200f21010b200c20096a20073a0000200941016a21092008210720080d000b200f2101200e41046a220e2010470d000b0b0240201441ffffffff0371450d00201210350b200341003a00002009210103402003200141800172200141ff0071200141077622071b3a000020022003410110782007210120070d000b2002200c20091078200f450d07200c10350c070b200141086a280200211a200141046a28020021162001410c6a2802002115200341023a00002002200341011078200341d0006a410c6a410036020020034201370254200320023602502016201541286c6a210241002101410021092015210703400240024020092001460d00200328025421080c010b200141016a22082001490d022001410174220f2008200f20084b1b220f4100480d020240024020010d000240200f0d00410121080c020b200f10332208450d0c0c010b200328025421082001200f460d0020082001200f10372208450d0b0b2003200f360258200320083602540b200820096a200741807f72200741ff0071200741077622071b3a00002003200941016a220936025c02402007450d0020032802582101200721070c010b0b2016210c2015450d02201541286c41586a21102016210c0340200c220941286a210c20092d0018220d4104460d03200941206a29000021042009411c6a280000210f2009411a6a2d0000210a200941196a2c0000210b200941146a2802002115200941106a2802002111200928020c21122009280204211320092802002114200328025c21012009280208220e210903400240024020032802582001460d00200328025421070c010b200141016a22072001490d03200141017422082007200820074b1b22084100480d030240024020010d00024020080d00410121070c020b200810332207450d0d0c010b2003280254210720012008460d0020072001200810372207450d0c0b2003200836025820032007360254200328025c21010b200720016a200941807f72200941ff0071200941077622071b3a00002003200141016a220136025c2007210920070d000b024002402003280258220720016b200e490d00200328025421090c010b2001200e6a22092001490d02200741017422012009200120094b1b22014100480d020240024020070d00024020010d00410121090c020b200110332209450d0c0c010b2003280254210920072001460d0020092007200110372209450d0b0b2003200136025820032009360254200328025c21010b200920016a2014200e109d081a20032001200e6a220136025c02402013450d0020141035200328025c21010b2015210903400240024020032802582001460d00200328025421070c010b200141016a22072001490d03200141017422082007200820074b1b22084100480d030240024020010d00024020080d00410121070c020b200810332207450d0d0c010b2003280254210720012008460d0020072001200810372207450d0c0b2003200836025820032007360254200328025c21010b200720016a200941807f72200941ff0071200941077622071b3a00002003200141016a220136025c2007210920070d000b024002402003280258220720016b2015490d00200328025421090c010b200120156a22092001490d02200741017422012009200120094b1b22014100480d020240024020070d00024020010d00410121090c020b200110332209450d0c0c010b2003280254210920072001460d0020092007200110372209450d0b0b2003200136025820032009360254200328025c21010b200920016a20122015109d081a2003200120156a36025c02402011450d00201210350b02400240024002400240200d0e0400010203000b200341003a0000024002402003280258200328025c2201460d0041002107200328025421090c010b200141016a22092001490d06200141017422072009200720094b1b22074100480d060240024020010d00024020070d00410121090c020b200710332209450d100c010b2003280254210920012007460d0020092001200710372209450d0f0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a220136025c200341003a000003402003200f41807f72200f41ff0071200f41077622091b22083a00000240024020032802582001460d00200328025421070c010b200141016a22072001490d07200141017422082007200820074b1b22084100480d070240024020010d00024020080d00410121070c020b200810332207450d110c010b2003280254210720012008460d0020072001200810372207450d100b200320083602582003200736025420032d00002108200328025c21010b200720016a20083a00002003200141016a220136025c2009210f20090d000c040b0b200341013a0000024002402003280258200328025c2201460d0041012107200328025421090c010b200141016a22092001490d05200141017422072009200720094b1b22074100480d050240024020010d00024020070d00410121090c020b200710332209450d0f0c010b2003280254210920012007460d0020092001200710372209450d0e0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a220136025c200341f0003a00000240024020032802582001460d0041f0002107200328025421090c010b200141016a22092001490d05200141017422072009200720094b1b22074100480d050240024020010d00024020070d00410121090c020b200710332209450d0f0c010b2003280254210920012007460d0020092001200710372209450d0e0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a36025c2003200f2004a72004422088a7200341d0006a10af0720032d00002201411f460d0220032f000120032d00034110747221090c050b200341023a0000024002402003280258200328025c2201460d0041022107200328025421090c010b200141016a22092001490d04200141017422072009200720094b1b22074100480d040240024020010d00024020070d00410121090c020b200710332209450d0e0c010b2003280254210920012007460d0020092001200710372209450d0d0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a36025c2003200f2004a72004422088a7200341d0006a10af0720032d00002201411f460d0120032f000120032d00034110747221090c040b200341033a0000024002402003280258200328025c2201460d0041032107200328025421090c010b200141016a22092001490d03200141017422072009200720094b1b22074100480d030240024020010d00024020070d00410121090c020b200710332209450d0d0c010b2003280254210920012007460d0020092001200710372209450d0c0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a220136025c2003200b417f732209413f7141c000722009200b417f4a1b22073a00000240024020032802582001460d00200328025421090c010b200141016a22092001490d03200141017422072009200720094b1b22074100480d030240024020010d00024020070d00410121090c020b200710332209450d0d0c010b2003280254210920012007460d0020092001200710372209450d0c0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a220136025c2003200a41ff017141004722073a00000240024020032802582001460d00200328025421090c010b200141016a22092001490d03200141017422072009200720094b1b22074100480d030240024020010d00024020070d00410121090c020b200710332209450d0d0c010b2003280254210920012007460d0020092001200710372209450d0c0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a36025c0b201041586a2110200c2002470d000c040b0b103e000b200328020c2107200328020821082003280204210f02402002200c460d0003400240200c41046a280200450d00200c28020010350b0240200c41106a280200450d00200c410c6a28020010350b200c41286a210c201041586a22100d000b0b0240201a450d00201a41286c450d00201610350b02402003280258450d00200328025410350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a2007360000200041086a2008360000200041046a200f3600000c050b2002200c460d0003400240200c41046a280200450d00200c28020010350b200c41286a21010240200c41106a280200450d00200c410c6a28020010350b2001210c20022001470d000b0b0240201a450d00201a41286c450d00201610350b200328025c21082003280258210c2003280254210f20032802502107200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d02200f10350c020b200d2010460d000340201041106a21090240201041046a280200450d00201028020010350b20092110200d2009470d000b0b0240200a41ffffffff0071450d00200b10350b200341003a00002007210903402003200941800172200941ff0071200941077622081b3a000020022003410110782008210920080d000b2002200e200710782001450d00200e10350b2000411f3a00000b200341e0006a24000f0b103c000be60703027f017e057f230041d0006b2202240041a3edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a2900003703002002200437030820031035419cb4ca00ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240200141086a28020041046a2203417f4c0d000240024020030d0041012105410021030c010b200310332205450d020b2002410036024820022005360240200220033602440240200341034b0d00200341017422064104200641044b1b22064100480d030240024020030d002006103322050d010c060b20032006460d0020052003200610372205450d050b20022006360244200220053602400b2005200128000036000020024104360248200141046a2802002107200141086a2802002201200241c0006a10770240024020022802442208200228024822056b2001490d0020022802402103200821060c010b200520016a22032005490d03200841017422062003200620034b1b22064100480d030240024020080d00024020060d00410121030c020b200610332203450d060c010b2002280240210320082006460d0020032008200610372203450d050b20022006360244200220033602400b200320056a20072001109d081a2002200520016a2201ad4220862003ad841003220529000037033820051035200241cc006a200320016a360200200220033602482002200241c0006a3602442002200241386a360240200241286a200241c0006a107b02402006450d00200310350b2002280230220841206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121050c010b200141017422054110200541104b1b22054100480d03024020010d00200510332203450d050c010b20012005460d0020032001200510372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020054170714110460d00200521010c010b200541017422014120200141204b1b22014100480d0320052001460d0020032005200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2008490d00200121050c010b200841206a22052008490d03200141017422092005200920054b1b22054100480d0320012005460d0020032001200510372203450d040b200341206a20072008109d081a2000200636020820002005360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000b130020004104360204200041a4bfca003602000b1300200041043602042000418cc3ca003602000b130020004101360204200041e8caca003602000b340020004193d1cb0036020420004100360200200041146a4103360200200041106a41e8cbca00360200200041086a420a3702000beb050a067f017e017f017e017f017e017f017e017f017e230041206b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200020044105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c37000020052008370000024020032001490d00200321040c030b2006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d01200020034105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c370000200520083700002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200020044105746a22012900002108200020054105746a220041086a2205290000210a200041106a2204290000210c200041186a2203290000210e20012000290000370000200141186a220629000021102006200e370000200141106a2206290000210e2006200c370000200141086a2201290000210c2001200a370000200320103700002004200e3700002005200c370000200020083700000b200241206a24000f0b20052001418486cc001042000b2004200141f485cc001042000be90609067f017e017f017e017f027e017f017e027f230041206b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d0220052006200020064105746a200020054105746a412010a0084100481b21060b200620014f0d03200420014f0d02200020044105746a2204200020064105746a2205412010a00841004e0d03200541086a22072900002108200541106a2209290000210a200541186a220b290000210c2004290000210d20042005290000370000200441186a220e290000210f200e200c370000200441106a220e290000210c200e200a370000200441086a2204290000210a20042008370000200b200f3700002009200c3700002007200a3700002005200d370000200621040c000b0b2006200141f487cc001042000b20042001418488cc001042000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241186a2209200041186a2204290000370300200241106a220b200041106a2205290000370300200241086a220e200041086a2203290000370300200020074105746a220641086a2900002108200641106a290000210a200641186a290000210c2000290000210d200020062900003700002004200c3700002005200a370000200320083700002002200d37030041002105024002400240034020062002290300370000200641186a2009290300370000200641106a200b290300370000200641086a200e2903003700002005410174220641017221040240200641026a220620074f0d00200420074f0d0220062004200020044105746a200020064105746a412010a0084100481b21040b200420074f0d03200520074f0d02200020054105746a2205200020044105746a2206412010a00841004e0d032009200541186a2203290000370300200b200541106a2210290000370300200e200541086a2211290000370300200641086a2900002108200641106a290000210a200641186a290000210c2005290000210d200520062900003700002003200c3700002010200a370000201120083700002002200d370300200421050c000b0b2004200741f487cc001042000b20052007418488cc001042000b200741014b0d000b0b200241206a24000f0b20072001418486cc001042000bdb08030a7f017e0a7f230041c0006b22022400200041a07f6a21032001417f6a2104200141324921054101210641002107024003400240024020062001490d00410021080c010b41012108200020064105746a2209200941606a412010a0084100480d0003404101210a20042006460d03200641016a2106200941206a220a2009412010a0082108200a21092008417f4a0d000b200620014921080b2006200146210a20050d0120062001460d0102400240024002402006417f6a220920014f0d002008450d0120002006410574220b6a220a290000210c200a200020094105746a22092900003700002009200c370000200a41086a220d290000210c200d200941086a220e290000370000200e200c370000200a41106a220f290000210c200f200941106a22102900003700002010200c370000200a41186a2211290000210c2011200941186a22122900003700002012200c37000020064102490d03200920002006417e6a22084105746a2213412010a008417f4a0d032009290000210c20092013290000370000200241206a41186a22142012290000370300200241206a41106a22152010290000370300200241206a41086a2216200e290000370300200e201341086a2900003700002010201341106a2900003700002012201341186a2900003700002002200c3703204100210e2008450d022003200b6a210903400240200241206a2009412010a0084100480d002008210e0c040b200941206a2009290000370000200941386a200941186a290000370000200941306a200941106a290000370000200941286a200941086a290000370000200941606a21092008417f6a22080d000c030b0b2009200141f485cc001042000b20062001418486cc001042000b2000200e4105746a22092002290320370000200941186a2014290300370000200941106a2015290300370000200941086a20162903003700000b200741016a21070240200120066b22104102490d00200a41206a2209200a412010a008417f4a0d00200a290000210c200a2009290000370000200241206a41186a22122011290000370300200241206a41106a2213200f290000370300200241206a41086a220b200d290000370300200d200941086a290000370000200f200941106a2900003700002011200941186a2900003700002002200c3703204101210d024020104103490d00200a41c0006a200241206a412010a008417f4a0d00410321084102210e0340200a200e4105746a220941606a220d2009290000370000200d41186a200941186a290000370000200d41106a200941106a290000370000200d41086a200941086a290000370000024020082010490d00200e210d0c020b20084105742109200e210d2008210e200841016a2108200a20096a200241206a412010a0084100480d000b0b200a200d4105746a22092002290320370000200941186a2012290300370000200941106a2013290300370000200941086a200b2903003700000b20074105470d000b4100210a0b200241c0006a2400200a0b88090b107f017e017f017e017f017e017f017e017f017e017f230041306b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200241286a22082000200441306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e2903003703002013201029030037030020052002290300370300024020032001490d00200321040c030b2006410d7420067322044111762004732204410574200473220620077122044100200120042001491b6b220520014f0d01200241286a22082000200341306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e29030037030020132010290300370300200520022903003703002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200241286a22032000200441306c6a220141286a2204290300370300200241206a2206200141206a2207290300370300200241186a2208200141186a2209290300370300200241106a220a200141106a220b290300370300200241086a220c200141086a220d290300370300200220012903003703002000200541306c6a22002903002112200041086a22052903002114200041106a220e2903002116200041186a220f2903002118200041206a2210290300211a2004200041286a22112903003703002007201a37030020092018370300200b2016370300200d2014370300200120123703002011200329030037030020102006290300370300200f2008290300370300200e200a2903003703002005200c290300370300200020022903003703000b200241306a24000f0b20052001418486cc001042000b2004200141f485cc001042000bf30a020e7f027e02402000280200220428020028020028020028020028020022052802002206450d0020012802002107200428020428020022082002280200220941306c6a210a2005280204210b2006210c02400340200c41086a210d200c2f0106220e410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210e0b0240200b0d0042002112420021130c030b200b417f6a210b200c200e4102746a41c8056a280200210c0c010b0b200c20104105746a220f41f0026a2903002113200f41e8026a29030021120b2006450d002008200741306c6a210a2005280204210b2006210c02400340200c41086a210d200c2f0106220e410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210e0b200b450d02200b417f6a210b200c200e4102746a41c8056a280200210c0c010b0b2012200c20104105746a220f41e8026a2903005a2013200f41f0026a29030022125a20132012511b0d0020012009360200200220073602002004280208220f200f28020041016a360200200228020021092000280200220428020428020021082004280200280200280200280200280200220528020021060b2006450d0020082003280200220741306c6a210a2005280204210b2006210c02400340200c41086a210d200c2f0106220e410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210e0b0240200b0d0042002112420021130c030b200b417f6a210b200c200e4102746a41c8056a280200210c0c010b0b200c20104105746a220f41f0026a2903002113200f41e8026a29030021120b2006450d002008200941306c6a210a2005280204210b2006210c02400340200c41086a210d200c2f0106220e410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210e0b200b450d02200b417f6a210b200c200e4102746a41c8056a280200210c0c010b0b2012200c20104105746a220f41e8026a2903005a2013200f41f0026a29030022125a20132012511b0d0020022007360200200320093602002004280208220f200f28020041016a360200200228020021092000280200220428020428020021082004280200280200280200280200280200220528020021060b2006450d00200128020021002008200941306c6a210a2005280204210b2006210c02400340200c41086a210d200c2f0106220e410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210e0b0240200b0d0042002112420021130c030b200b417f6a210b200c200e4102746a41c8056a280200210c0c010b0b200c20104105746a220f41f0026a2903002113200f41e8026a29030021120b2006450d002008200041306c6a210a2005280204210c0340200641086a210d20062f0106220b410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210b0b200c450d02200c417f6a210c2006200b4102746a41c8056a28020021060c010b0b2012200620104105746a220f41e8026a2903005a2013200f41f0026a29030022125a20132012511b0d0020012009360200200220003602002004280208220f200f28020041016a3602000b0bfe030a0d7f017e017f017e017f017e017f017e017f017e230041c0006b22032400200320023602082003200341086a36020c024020014101762202450d002003410c6a200020012002417f6a1084072002417e6a210203402002417f460d012003410c6a2000200120021084072002417f6a21020c000b0b0240024020014102490d00200141306c20006a41506a21022001210403402004417f6a220520014f0d02200341106a41286a2204200041286a2206290300370300200341106a41206a2207200041206a2208290300370300200341106a41186a2209200041186a220a290300370300200341106a41106a220b200041106a220c290300370300200341106a41086a220d200041086a220e29030037030020032000290300370310200241086a220f2903002110200241106a22112903002112200241186a22132903002114200241206a22152903002116200241286a22172903002118200020022903003703002006201837030020082016370300200a2014370300200c2012370300200e20103703002017200429030037030020152007290300370300201320092903003703002011200b290300370300200f200d290300370300200220032903103703002003410c6a200020054100108407200241506a210220052104200541014b0d000b0b200341c0006a24000f0b2004417f6a2001418486cc001042000bf20f03107f027e0a7f230041306b22032400410021042001413249210541012106024003400240024020062001490d00410021070c010b20022802002802002802002208280200210941012107034002402009450d002006417f6a210a2000200641306c6a210b2008280204210c2009210d02400340200d41086a210e200d2f0106220f4105742110410021110240024003402010450d01200b200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a210f0b0240200c0d0042002113420021140c030b200c417f6a210c200d200f4102746a41c8056a280200210d0c010b0b200d20114105746a221041f0026a2903002114201041e8026a29030021130b2009450d002000200a41306c6a210b2008280204210c2009210d0340200d41086a210e200d2f0106220f4105742110410021110240024003402010450d01200b200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a210f0b200c450d02200c417f6a210c200d200f4102746a41c8056a280200210d0c010b0b2013200d20114105746a221041e8026a2903005a2014201041f0026a29030022135a20142013511b450d020b41012110200641016a2206200149210720062001470d000c030b0b2006200146211020050d0120062001460d0102400240024002402006417f6a221020014f0d002007410171450d01200441016a21042000201041306c6a2210290300211420102000200641306c6a220b290300370300200341286a2209201041286a220e290300370300200341206a2207201041206a2211290300370300200341186a2208201041186a2212290300370300200341106a220a201041106a220d290300370300200341086a2215201041086a22102903003703002010200b41086a2216290300370300200d200b41106a22172903003703002012200b41186a22182903003703002011200b41206a2219290300370300200e200b41286a221a29030037030020032014370300200b2003290300370300201a200929030037030020192007290300370300201820082903003703002017200a29030037030020162015290300370300200020062002108307200120066b221b4102490d032002280200280200280200221c280200220f450d03200b41306a210d201c280204211d200f210c02400340200c41086a210e200c2f0106221e4105742110410021110240024003402010450d01200d200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a211e0b0240201d0d0042002113420021140c030b201d417f6a211d200c201e4102746a41c8056a280200210c0c010b0b200c20114105746a221041f0026a2903002114201041e8026a29030021130b200f450d03201c280204210c0340200f41086a210e200f2f0106221d4105742110410021110240024003402010450d01200b200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a211d0b200c450d05200c417f6a210c200f201d4102746a41c8056a280200210f0c010b0b2013200f20114105746a221041e8026a2903005a2014201041f0026a29030022135a20142013511b0d03200b2903002114200b200d2903003703002009201a2903003703002007201929030037030020082018290300370300200a2017290300370300201520162903003703002016200d41086a2903003703002017200d41106a2903003703002018200d41186a2903003703002019200d41206a290300370300201a200d41286a290300370300200320143703004101211e201b4103490d02410321184102211a4101211e034020022802002802002802002219280200220c450d03200b201a41306c6a210d2018211d20192802042116200c210f02400340200f41086a210e200f2f010622174105742110410021110240024003402010450d01200d200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21170b024020160d0042002113420021140c030b2016417f6a2116200f20174102746a41c8056a280200210f0c010b0b200f20114105746a221041f0026a2903002114201041e8026a29030021130b200c450d032019280204210f0340200c41086a210e200c2f010622164105742110410021110240024003402010450d012003200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21160b200f450d05200f417f6a210f200c20164102746a41c8056a280200210c0c010b0b2013200c20114105746a221041e8026a290300542014201041f0026a29030022135420142013511b450d03200d41506a2210200d290300370300201041286a200d41286a290300370300201041206a200d41206a290300370300201041186a200d41186a290300370300201041106a200d41106a290300370300201041086a200d41086a29030037030002402018201b4f0d00201841016a2118201a211e201d211a0c010b0b201a211e0c020b2010200141f485cc001042000b20062001418486cc001042000b200b201e41306c6a22102003290300370300201041286a2009290300370300201041206a2007290300370300201041186a2008290300370300201041106a200a290300370300201041086a20152903003703000b20044105470d000b410021100b200341306a240020100bc709030c7f027e057f230041306b22032400024020014102490d00200228020028020028020022042802002205450d002001417e6a2106200141306c20006a220141a07f6a2107200141506a2108200428020421092005210a02400340200a41086a210b200a2f0106220c41057421014100210d0240024003402001450d012008200b412010a008220e450d02200141606a2101200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b024020090d004200210f420021100c030b2009417f6a2109200a200c4102746a41c8056a280200210a0c010b0b200a200d4105746a220141f0026a2903002110200141e8026a290300210f0b2005450d002004280204210a0340200541086a210b20052f0106220941057421014100210d0240024003402001450d012007200b412010a008220e450d02200141606a2101200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a21090b200a450d02200a417f6a210a200520094102746a41c8056a28020021050c010b0b200f2005200d4105746a220141e8026a2903005a2010200141f0026a290300220f5a2010200f511b0d002008290300211020082007290300370300200341286a2211200841286a2201290300370300200341206a2212200841206a220b290300370300200341186a2213200841186a220d290300370300200341106a2214200841106a220e290300370300200341086a2215200841086a22082903003703002008200741086a290300370300200e200741106a290300370300200d200741186a290300370300200b200741206a2903003703002001200741286a290300370300200320103703000240024020060d00410021060c010b03402002280200280200280200220c2802002207450d0120002006417f6a220441306c6a2108200c28020421052007210a02400340200a41086a210b200a2f0106220941057421014100210d0240024003402001450d012003200b412010a008220e450d02200141606a2101200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a21090b024020050d004200210f420021100c030b2005417f6a2105200a20094102746a41c8056a280200210a0c010b0b200a200d4105746a220141f0026a2903002110200141e8026a290300210f0b2007450d01200c280204210a0340200741086a210b20072f0106220541057421014100210d0240024003402001450d012008200b412010a008220e450d02200141606a2101200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a21050b200a450d03200a417f6a210a200720054102746a41c8056a28020021070c010b0b200f2007200d4105746a220141e8026a290300542010200141f0026a290300220f542010200f511b450d012000200641306c6a22012008290300370300200141286a200841286a290300370300200141206a200841206a290300370300200141186a200841186a290300370300200141106a200841106a290300370300200141086a200841086a2903003703002004210620040d000b410021060b2000200641306c6a22012003290300370300200141286a2011290300370300200141206a2012290300370300200141186a2013290300370300200141106a2014290300370300200141086a20152903003703000b200341306a24000bd20907067f027e077f027e047f017e017f230041306b2204240003402003410174220541017221060240200541026a220720024f0d00024002400240200620024f0d0002402000280200280200280200280200280200220828020022090d004200210a4200210b0c020b2001200641306c6a210c2008280204210d2009210e02400340200e41086a210f200e2f010622104105742105410021110240024003402005450d01200c200f412010a0082212450d02200541606a2105201141016a2111200f41206a210f2012417f4a0d000b2011417f6a21100b0240200d0d004200210a4200210b0c030b200d417f6a210d200e20104102746a41c8056a280200210e0c010b0b200e20114105746a220541f0026a290300210b200541e8026a290300210a0b2009450d012001200741306c6a210c2008280204210e0340200941086a210f20092f0106220d4105742105410021110240024003402005450d01200c200f412010a0082212450d02200541606a2105201141016a2111200f41206a210f2012417f4a0d000b2011417f6a210d0b200e450d03200e417f6a210e2009200d4102746a41c8056a28020021090c010b0b200920114105746a220541f0026a2903002113200541e8026a29030021140c020b2006200241f487cc001042000b42002114420021130b20072006200a201454200b201354200b2013511b1b21060b024002400240200620024f0d00200320024f0d0120002802002802002802002802002802002210280200220e450d002001200341306c6a210c20102802042109200e210302400340200341086a210f20032f0106220d4105742105410021110240024003402005450d01200c200f412010a0082212450d02200541606a2105201141016a2111200f41206a210f2012417f4a0d000b2011417f6a210d0b024020090d00420021134200210b0c030b2009417f6a21092003200d4102746a41c8056a28020021030c010b0b200320114105746a220541f0026a290300210b200541e8026a29030021130b200e450d002001200641306c6a2103201028020421090340200e41086a210f200e2f0106220d4105742105410021110240024003402005450d012003200f412010a0082212450d02200541606a2105201141016a2111200f41206a210f2012417f4a0d000b2011417f6a210d0b2009450d022009417f6a2109200e200d4102746a41c8056a280200210e0c010b0b2013200e20114105746a220541e8026a29030054200b200541f0026a290300221354200b2013511b0d020b200441306a24000f0b20032002418488cc001042000b200441286a2205200c41286a220f290300370300200441206a2211200c41206a2212290300370300200441186a220e200c41186a2209290300370300200441106a220d200c41106a2210290300370300200441086a2207200c41086a22082903003703002004200c2903003703002003290300210b200341086a22152903002113200341106a2216290300210a200341186a22172903002114200341206a22182903002119200f200341286a221a29030037030020122019370300200920143703002010200a37030020082013370300200c200b370300201a2005290300370300201820112903003703002017200e2903003703002016200d2903003703002015200729030037030020032004290300370300200621030c000b0b88090b107f017e017f017e017f017e017f017e017f017e017f230041306b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200241286a22082000200441306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e2903003703002013201029030037030020052002290300370300024020032001490d00200321040c030b2006410d7420067322044111762004732204410574200473220620077122044100200120042001491b6b220520014f0d01200241286a22082000200341306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e29030037030020132010290300370300200520022903003703002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200241286a22032000200441306c6a220141286a2204290300370300200241206a2206200141206a2207290300370300200241186a2208200141186a2209290300370300200241106a220a200141106a220b290300370300200241086a220c200141086a220d290300370300200220012903003703002000200541306c6a22002903002112200041086a22052903002114200041106a220e2903002116200041186a220f2903002118200041206a2210290300211a2004200041286a22112903003703002007201a37030020092018370300200b2016370300200d2014370300200120123703002011200329030037030020102006290300370300200f2008290300370300200e200a2903003703002005200c290300370300200020022903003703000b200241306a24000f0b20052001418486cc001042000b2004200141f485cc001042000bf20907077f027e0b7f017e017f027e017f230041306b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d02200520062000200641306c6a22072903002000200541306c6a220829030056200741086a2903002209200841086a290300220a562009200a511b1b21060b200620014f0d03200420014f0d022000200441306c6a22042903002000200641306c6a220529030056200441086a22072903002209200541086a2208290300220a562009200a511b450d03200241286a220b200441286a220c290300370300200241206a220d200441206a220e290300370300200241186a220f200441186a2210290300370300200241106a2211200441106a2212290300370300200241086a221320072903003703002002200429030037030020082903002109200541106a2214290300210a200541186a22152903002116200541206a2217290300211820052903002119200c200541286a221a290300370300200e2018370300201020163703002012200a3703002007200937030020042019370300201a200b2903003703002017200d2903003703002015200f290300370300201420112903003703002008201329030037030020052002290300370300200621040c000b0b2006200141f487cc001042000b20042001418488cc001042000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241286a220b200041286a2205290300370300200241206a220c200041206a2206290300370300200241186a220d200041186a2208290300370300200241106a220e200041106a2210290300370300200241086a220f200041086a2211290300370300200220002903003703002000200741306c6a22042903002109200441086a290300210a200441106a2903002116200441186a2903002118200441206a29030021192005200441286a2903003703002006201937030020082018370300201020163703002011200a3703002000200937030041002105024002400240034020042002290300370300200441286a200b290300370300200441206a200c290300370300200441186a200d290300370300200441106a200e290300370300200441086a200f2903003703002005410174220441017221060240200441026a220420074f0d00200620074f0d02200420062000200641306c6a22082903002000200441306c6a221029030056200841086a2903002209201041086a290300220a562009200a511b1b21060b200620074f0d03200520074f0d022000200541306c6a22052903002000200641306c6a220429030056200541086a22082903002209200441086a2210290300220a562009200a511b450d03200b200541286a2211290300370300200c200541206a2212290300370300200d200541186a2213290300370300200e200541106a2214290300370300200f20082903003703002002200529030037030020102903002109200441106a290300210a200441186a2903002116200441206a2903002118200429030021192011200441286a29030037030020122018370300201320163703002014200a3703002008200937030020052019370300200621050c000b0b2006200741f487cc001042000b20052007418488cc001042000b200741014b0d000b0b200241306a24000f0b20072001418486cc001042000bb80c050a7f017e017f037e0f7f230041306b22022400200041c07e6a21032001417f6a2104200041306a2105410021062001413249210741012108024003400240024020082001490d00410021090c010b410121092000200841306c220a6a220b290300220c200b41506a220d29030056200b41086a290300220e200d41086a290300220f56200e200f511b0d002005200a6a210903404101210b20042008460d03200841016a210820092903002210200c58210b200941086a290300220f200e51210d200f200e58210a200941306a21092010210c200f210e200b200a200d1b0d000b200820014921090b2008200146210b20070d0120082001460d010240024002400240024002402008417f6a220b20014f0d002009450d012000200b41306c6a2209290300210e20092000200841306c22116a220b290300370300200241286a220a200941286a2212290300370300200241206a2213200941206a2214290300370300200241186a2215200941186a2216290300370300200241106a2217200941106a2218290300370300200241086a2219200941086a220d290300370300200d200b41086a221a2903003703002018200b41106a221b2903003703002016200b41186a221c2903003703002014200b41206a221d2903003703002012200b41286a221e2903003703002002200e370300200b2002290300370300201e200a290300370300201d2013290300370300201c2015290300370300201b2017290300370300201a201929030037030020084102490d052009290300220c20002008417e6a221341306c6a220a29030058200d290300220e200a41086a221f290300220f58200e200f511b0d052009200a290300370300200d201f2903003703002009290310210f2018200a41106a2903003703002015201229030037030020172014290300370300201920162903003703002016200a41186a2903003703002014200a41206a2903003703002012200a41286a2903003703002002200f370300024020130d00410021130c050b200c20002008417d6a220d41306c6a220929030058200e200941086a290300220f58200e200f511b0d04200320116a2109034020094188016a200941d8006a29030037030020094180016a200941d0006a290300370300200941f8006a200941c8006a290300370300200941f0006a200941c0006a290300370300200941e8006a200941386a290300370300200941e0006a200941306a290300370300200d450d032009290300210f200941086a210a200941506a2109200d417f6a210d200c200f56200e200a290300220f56200e200f511b0d000b200d41016a21130c030b200b200141f485cc001042000b20082001418486cc001042000b410021130b2000201341306c6a210a0b200a200c370300200a200e3703082000201341306c6a22092002290300370310200941286a2015290300370300200941206a2017290300370300200941186a20192903003703000b200641016a21060240200120086b22144102490d00200b290330200b290300220c58200b41386a290300220f201a290300220e58200f200e511b0d00200b200b41306a2212290300370300201a201241086a290300370300200b290310210f201b201241106a2903003703002015201e2903003703002017201d2903003703002019201c290300370300201c201241186a290300370300201d201241206a290300370300201e201241286a2903003703002002200f3703004101211a024020144103490d00200b290360200c58200b41e8006a290300220f200e58200f200e511b0d00200b41e0006a21094103210a4102210d0340200d221a41306c200b6a221241506a220d2009290300370300200d41286a200941286a290300370300200d41206a200941206a290300370300200d41186a200941186a290300370300200d41106a200941106a290300370300200d41086a200941086a290300370300200a20144f0d01200a41306c2109200a210d200a41016a210a200b20096a2209290300200c56200941086a290300220f200e56200f200e511b0d000b0b2012200c3703002012200e370308200b201a41306c6a22092002290300370310200941286a2015290300370300200941206a2017290300370300200941186a20192903003703000b20064105470d000b4100210b0b200241306a2400200b0b13002000410736020420004194d1ca003602000b130020004100360204200041b0b4cc003602000b9f0303027f017e027f230041206b2202240041c7d5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354190eaca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000ba10701087f230041106b220224002002410036020820024201370300200028020021030240410410332204450d00200241043602042002200436020020042003360000200241043602082000280204210320044104410810372204450d002002410836020420042003360004200220043602002002410836020820002802082104200041106a280200220320021077024002402003450d00200341057421052002280204210620022802082103034002400240200620036b4120490d00200341206a2107200228020021080c010b200341206a22072003490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009103322080d010c060b2002280200210820062009460d0020082006200910372208450d050b2002200936020420022008360200200921060b200820036a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200736020820072103200441206a2104200541606a22050d000b0b200028021421042000411c6a2802002203200210770240024020030d0020022802042109200228020821030c010b200341057421054100200228020822036b210820022802042106034002400240200620086a4120490d0020022802002107200621090c010b200341206a22072003490d03200641017422092007200920074b1b22094100480d030240024020060d00024020090d00410121070c020b200910332207450d060c010b2002280200210720062009460d0020072006200910372207450d050b2002200936020420022007360200200921060b200720036a22072004290000370000200741186a200441186a290000370000200741106a200441106a290000370000200741086a200441086a2900003700002002200341206a2203360208200841606a2108200441206a2104200541606a22050d000b0b2000280220210602400240200920036b4104490d0020022802002104200921070c010b200341046a22042003490d01200941017422072004200720044b1b22074100480d010240024020090d00024020070d00410121040c020b200710332204450d040c010b2002280200210420092007460d0020042009200710372204450d030b20022007360204200220043602000b200420036a20063600002001290200200341046aad4220862004ad84100202402007450d00200410350b200241106a24000f0b103e000b103c000b9f0303027f017e027f230041206b2202240041dad5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354190eaca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b130020004109360204200041a8eaca003602000b3400200041f8a2cb0036020420004100360200200041146a4103360200200041106a4180a3cb00360200200041086a42083702000b130020004105360204200041b4a9cb003602000b3400200041c7d5ca0036020420004100360200200041146a4106360200200041106a41f8bbcb00360200200041086a42133702000b3400200041dad5ca0036020420004100360200200041146a4106360200200041106a41f8bbcb00360200200041086a42133702000ba10701087f230041106b220224002002410036020820024201370300200028020021030240410410332204450d00200241043602042002200436020020042003360000200241043602082000280204210320044104410810372204450d002002410836020420042003360004200220043602002002410836020820002802082104200041106a280200220320021077024002402003450d00200341057421052002280204210620022802082103034002400240200620036b4120490d00200341206a2107200228020021080c010b200341206a22072003490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009103322080d010c060b2002280200210820062009460d0020082006200910372208450d050b2002200936020420022008360200200921060b200820036a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200736020820072103200441206a2104200541606a22050d000b0b200028021421042000411c6a2802002203200210770240024020030d0020022802042109200228020821030c010b200341057421054100200228020822036b210820022802042106034002400240200620086a4120490d0020022802002107200621090c010b200341206a22072003490d03200641017422092007200920074b1b22094100480d030240024020060d00024020090d00410121070c020b200910332207450d060c010b2002280200210720062009460d0020072006200910372207450d050b2002200936020420022007360200200921060b200720036a22072004290000370000200741186a200441186a290000370000200741106a200441106a290000370000200741086a200441086a2900003700002002200341206a2203360208200841606a2108200441206a2104200541606a22050d000b0b2000280220210602400240200920036b4104490d0020022802002104200921070c010b200341046a22042003490d01200941017422072004200720044b1b22074100480d010240024020090d00024020070d00410121040c020b200710332204450d040c010b2002280200210420092007460d0020042009200710372204450d030b20022007360204200220043602000b200420036a20063600002001290200200341046aad4220862004ad84100202402007450d00200410350b200241106a24000f0b103e000b103c000b340020004182e9ca0036020420004100360200200041146a4101360200200041106a41b8c0cb00360200200041086a42183702000bfd0303037f027e047f230041106b220224002002410036020820024201370300200028021021030240410410332204450d0020024104360204200220043602002004200336000020024104360208200041086a29030021052000290300210620044104411410372204450d00200420063700042004410c6a200537000020024294808080c00237020420022004360200200028021421072000411c6a2802002200200210770240024020000d002002280208210320022802042108200228020021090c010b2000410574210a200228020021092002280204210820022802082103034020072100024002402008200322046b4120490d00200441206a21030c010b024002400240200441206a22032004490d00200841017422072003200720034b1b22074100480d000240024020080d00024020070d00410121090c020b2007103321090c040b20082007470d020b200721080c030b103e000b200920082007103721090b200721082009450d030b200041206a2107200920046a22042000290000370000200441186a200041186a290000370000200441106a200041106a290000370000200441086a200041086a290000370000200a41606a220a0d000b2002200836020420022003360208200220093602000b20012902002003ad4220862009ad84100202402008450d00200910350b200241106a24000f0b103c000bc20503027f017e047f230041d0006b2202240041f8a2cb00ad4280808080800184100122032900002104200241086a200341086a290000370300200220043703002003103541e4a6cb00ad4280808080d00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041f8a2cb00ad4280808080800184100122032900002104200241086a41086a200341086a29000037030020022004370308200310354188a5cb00ad4280808080b00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bdc0703027f017e067f230041e0006b2203240041f8a2cb00ad4280808080800184100122042900002105200341086a41086a200441086a290000370300200320053703082004103541e8a5cb00ad4280808080800284100122042900002105200341186a41086a200441086a29000037030020032005370318200410350240024002400240412010332204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020032004ad42808080808004841003220129000037034820011035200341dc006a2201200441206a360200200320043602582003200341c8006a41086a22063602542003200341c8006a360250200341286a200341d0006a107b20041035412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2201417f4c0d01200328023821092003280228210a0240024020010d004100210b410121040c010b200110332204450d012001210b0b02400240200b410f4d0d00200b21020c010b200b41017422024110200241104b1b22024100480d030240200b0d002002103322040d010c050b200b2002460d002004200b200210372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020024170714110460d002002210b0c010b2002410174220b4120200b41204b1b220b4100480d032002200b460d0020042002200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21020c010b2007415f4b0d03200b41017422022006200220064b1b22024100480d03200b2002460d002004200b200210372204450d040b200441206a200a2007109d081a02400240200220066b2008490d002002210b0c010b20012006490d032002410174220b2001200b20014b1b220b4100480d03024020020d000240200b0d00410121040c020b200b10332204450d050c010b2002200b460d0020042002200b10372204450d040b200420066a20092008109d081a200020013602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000b130020004110360204200041fcc2cb003602000b9f0303027f017e027f230041206b2202240041dad5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354188b8cb00ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b9f0303027f017e027f230041206b2202240041dad5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354190eaca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b9b0c08057f037e057f017e077f017e017f017e230041c0076b220424000240024020000d00200441e0026a2003109c0720043502e80242208620042802e0022200ad841007024020042802e402450d00200010350b200441ed026a200341086a290000370000200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441033a00e402200441073a00e002200420032900003700e50241b0b4cc004100200441e0026a10d4010c010b200441ed026a200341086a290000370000200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441023a00e402200441073a00e002200420032900003700e50241b0b4cc004100200441e0026a10d401200441b8026a2003109c07200441e0026a20042802b802220520042802c00210e30220042802e002210020044190056a200441e0026a41047241ac02109d081a02402000411b470d0020042802bc02450d01200510350c010b200441086a20044190056a41ac02109d081a024020042802bc02450d00200510350b20022802042105200420003602e002200441e0026a410472200441086a41ac02109d081a2004419c056a200136020020044190056a41086a2005360200200441003a009405200441013a009005200441b8026a200441e0026a20044190056a10ac0320044185036a20042903b802503a0000200441ed026a200341086a290000370000200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441043a00e402200441073a00e002200420032900003700e50241b0b4cc004100200441e0026a10d4010b200441e0026a2003109a0720043502e80242208620042802e0022200ad841007024020042802e402450d00200010350b20044190056a41186a2206420037030020044190056a41106a2207420037030020044190056a41086a22084200370300200442003703900541dad5ca00ad4280808080b00284220910012200290000210a2008200041086a2900003703002004200a37039005200010354180eaca00ad4280808080900184220b10012200290000210a200441086a41086a220c200041086a2900003703002004200a3703082000103520072004290308220a370300200441e0026a41086a220d2008290300370300200441e0026a41106a220e200a370300200441e0026a41186a220f200c29030037030020042004290390053703e00220044190056a200441e0026a412010b5022004280290052200410120001b21100240200429029405420020001b2211422088a72212450d0041002101201021004100210502400240034002400240024020032000460d0020002003412010a008450d0020010d01410021010c020b200141016a21010c010b200520016b221320124f0d022006200020014105746b221341186a22142900003703002007201341106a22152900003703002008201341086a22162900003703002004201329000037039005200041086a2217290000210a200041106a22182900002119200041186a221a290000211b201320002900003700002014201b370000201520193700002016200a370000201a2006290300370000201820072903003700002017200829030037000020002004290390053700000b200041206a21002012200541016a2205460d020c000b0b2013201241f485cc001042000b2001417f6a20124f0d00201220016bad422086201142ffffffff0f838421110b200f4200370300200e4200370300200d4200370300200442003703e002200910012200290000210a200d200041086a2900003703002004200a3703e00220001035200b10012200290000210a200c200041086a2900003703002004200a37030820001035200e2004290308220a3703002008200d2903003703002007200a3703002006200c290300370300200420042903e002370390050240024020100d0020044190056aad428080808080048410070c010b200441203602e402200420044190056a3602e00220102011422088a7200441e0026a10c504201142ffffff3f83500d00201010350b02402002410c6a28020041ffffff3f71450d00200228020810350b0240200241186a28020041ffffff3f71450d00200228021410350b200441c0076a24000b9f0303027f017e027f230041206b2202240041dad5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354188b8cb00ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b9f0303027f017e027f230041206b2202240041c7d5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354188b8cb00ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b9f0303027f017e027f230041206b2202240041c7d5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354190eaca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b9b0c08057f037e057f017e077f017e017f017e230041c0076b220424000240024020000d00200441e0026a200310a00720043502e80242208620042802e0022200ad841007024020042802e402450d00200010350b200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441083a00e002200441ed026a200341086a290000370000200441033a00e402200420032900003700e50241b0b4cc004100200441e0026a10d4010c010b200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441083a00e002200441ed026a200341086a290000370000200441023a00e402200420032900003700e50241b0b4cc004100200441e0026a10d401200441b8026a200310a007200441e0026a20042802b802220520042802c00210e30220042802e002210020044190056a200441e0026a41047241ac02109d081a02402000411b470d0020042802bc02450d01200510350c010b200441086a20044190056a41ac02109d081a024020042802bc02450d00200510350b20022802042105200420003602e002200441e0026a410472200441086a41ac02109d081a2004419c056a200136020020044190056a41086a2005360200200441003a009405200441023a009005200441b8026a200441e0026a20044190056a10ac0320044185036a20042903b802503a0000200441ed026a200341086a290000370000200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441043a00e402200441083a00e002200420032900003700e50241b0b4cc004100200441e0026a10d4010b200441e0026a2003109e0720043502e80242208620042802e0022200ad841007024020042802e402450d00200010350b20044190056a41186a2206420037030020044190056a41106a2207420037030020044190056a41086a22084200370300200442003703900541c7d5ca00ad4280808080b00284220910012200290000210a2008200041086a2900003703002004200a37039005200010354180eaca00ad4280808080900184220b10012200290000210a200441086a41086a220c200041086a2900003703002004200a3703082000103520072004290308220a370300200441e0026a41086a220d2008290300370300200441e0026a41106a220e200a370300200441e0026a41186a220f200c29030037030020042004290390053703e00220044190056a200441e0026a412010b5022004280290052200410120001b21100240200429029405420020001b2211422088a72212450d0041002101201021004100210502400240034002400240024020032000460d0020002003412010a008450d0020010d01410021010c020b200141016a21010c010b200520016b221320124f0d022006200020014105746b221341186a22142900003703002007201341106a22152900003703002008201341086a22162900003703002004201329000037039005200041086a2217290000210a200041106a22182900002119200041186a221a290000211b201320002900003700002014201b370000201520193700002016200a370000201a2006290300370000201820072903003700002017200829030037000020002004290390053700000b200041206a21002012200541016a2205460d020c000b0b2013201241f485cc001042000b2001417f6a20124f0d00201220016bad422086201142ffffffff0f838421110b200f4200370300200e4200370300200d4200370300200442003703e002200910012200290000210a200d200041086a2900003703002004200a3703e00220001035200b10012200290000210a200c200041086a2900003703002004200a37030820001035200e2004290308220a3703002008200d2903003703002007200a3703002006200c290300370300200420042903e002370390050240024020100d0020044190056aad428080808080048410070c010b200441203602e402200420044190056a3602e00220102011422088a7200441e0026a10c504201142ffffff3f83500d00201010350b02402002410c6a28020041ffffff3f71450d00200228020810350b0240200241186a28020041ffffff3f71450d00200228021410350b200441c0076a24000b9f0303027f017e027f230041206b2202240041c7d5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354188b8cb00ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b130020004107360204200041accdcb003602000bcc04020d7f017e230041c0006b22032400200128020822044104742105200128020421062001280200220721010240024002402004450d00200341306a410172210841002104200341306a41026a2109200341206a410172220a41076a210b03402009200720046a220141036a2d00003a00002003200141016a2f00003b0130024020012d0000220c41ac01470d00200141106a21010c020b2003410c6a41026a20092d0000220d3a0000200320032f0130220e3b010c200141046a280200210f200141086a29030021102008200e3b0000200841026a200d3a00002003200c3a0030200320103703382003200f360234200341206a200341306a200210a3072003200a2900003703102003200b290000370017024020032d0020220c411f470d002005200441106a2204470d010c030b0b2000200c3a000020002003290310370001200041086a20032900173700000240200541706a2004460d00200141146a2101200520046b41706a2104034002402001417c6a2d00004109470d0002402001280200220928020441ffffffff0371450d0020092802001035200128020021090b200910350b200141106a2101200441706a22040d000b0b200641ffffffff0071450d02200710350c020b200720056a22092001460d000340200141106a2104024020012d00004109470d000240200141046a2208280200220128020441ffffffff0371450d0020012802001035200828020021010b200110350b2004210120092004470d000b0b0240200641ffffffff0071450d00200710350b2000411f3a00000b200341c0006a24000b9bee0202097f017e230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad01200441017422062005200620054b1b22064100480dad010240024020040d00024020060d00410121050c020b2006103322050d010cb9010b2002280204210520042006460d0020052004200610372205450db8010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41003a00002002410c6a200441016a3602000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac01200441017422062005200620054b1b22064100480dac010240024020040d00024020060d00410121050c020b200610332205450db8010c010b2002280204210520042006460d0020052004200610372205450db7010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41013a00002002410c6a200441016a3602000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490dab01200441017422082005200820054b1b22084100480dab010240024020040d00024020080d00410121050c020b200810332205450db7010c010b2006280200210520042008460d0020052004200810372205450db6010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41023a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490dab01200441017422082005200820054b1b22084100480dab010240024020040d00024020080d00410121050c020b200810332205450db7010c010b2006280200210520042008460d0020052004200810372205450db6010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490daa01200441017422082005200820054b1b22084100480daa010240024020040d00024020080d00410121050c020b200810332205450db6010c010b2006280200210520042008460d0020052004200810372205450db5010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41033a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490daa01200441017422082005200820054b1b22084100480daa010240024020040d00024020080d00410121050c020b200810332205450db6010c010b2006280200210520042008460d0020052004200810372205450db5010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490da901200441017422082005200820054b1b22084100480da9010240024020040d00024020080d00410121050c020b200810332205450db5010c010b2006280200210520042008460d0020052004200810372205450db4010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41043a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490da901200441017422082005200820054b1b22084100480da9010240024020040d00024020080d00410121050c020b200810332205450db5010c010b2006280200210520042008460d0020052004200810372205450db4010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da801200441017422062005200620054b1b22064100480da8010240024020040d00024020060d00410121050c020b200610332205450db4010c010b2002280204210520042006460d0020052004200610372205450db3010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41053a00002002410c6a200441016a3602000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da701200441017422062005200620054b1b22064100480da7010240024020040d00024020060d00410121050c020b200610332205450db3010c010b2002280204210520042006460d0020052004200610372205450db2010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410b3a00002002410c6a200441016a3602000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da601200441017422072006200720064b1b22074100480da6010240024020040d00024020070d00410121060c020b200710332206450db2010c010b2009280200210620042007460d0020062004200710372206450db1010b20022006360204200241086a20073602002002410c6a28020021040b200620046a410c3a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da701200441017422072006200720064b1b22074100480da7010240024020040d00024020070d00410121060c020b200710332206450db3010c010b2009280200210620042007460d0020062004200710372206450db2010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da501200441017422072006200720064b1b22074100480da5010240024020040d00024020070d00410121060c020b200710332206450db1010c010b2009280200210620042007460d0020062004200710372206450db0010b20022006360204200241086a20073602002002410c6a28020021040b200620046a410d3a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da601200441017422072006200720064b1b22074100480da6010240024020040d00024020070d00410121060c020b200710332206450db2010c010b2009280200210620042007460d0020062004200710372206450db1010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca4010b0b200241046a210902400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490da401200441017422062005200620054b1b22064100480da4010240024020040d00024020060d00410121050c020b200610332205450db0010c010b2009280200210520042006460d0020052004200610372205450daf010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410e3a00002002410c6a2208200441016a360200200320012802042204280204220520042802002204200420054102746a200210a4072003210420032d0000411f470dab012008280200210420012802042802082105200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da501200441017422072006200720064b1b22074100480da5010240024020040d00024020070d00410121060c020b200710332206450db1010c010b2009280200210620042007460d0020062004200710372206450db0010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca3010b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da301200441017422062005200620054b1b22064100480da3010240024020040d00024020060d00410121050c020b200610332205450daf010c010b2002280204210520042006460d0020052004200610372205450dae010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410f3a00002002410c6a200441016a3602000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da201200441017422072006200720064b1b22074100480da2010240024020040d00024020070d00410121060c020b200710332206450dae010c010b2009280200210620042007460d0020062004200710372206450dad010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41103a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da301200441017422072006200720064b1b22074100480da3010240024020040d00024020070d00410121060c020b200710332206450daf010c010b2009280200210620042007460d0020062004200710372206450dae010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da101200441017422072006200720064b1b22074100480da1010240024020040d00024020070d00410121060c020b200710332206450dad010c010b2009280200210620042007460d0020062004200710372206450dac010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41113a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da201200441017422072006200720064b1b22074100480da2010240024020040d00024020070d00410121060c020b200710332206450dae010c010b2009280200210620042007460d0020062004200710372206450dad010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000b02400240200241086a2802002004460d00200928020021050c010b200441016a22052004490da101200441017422062005200620054b1b22064100480da1010240024020040d00024020060d00410121050c020b200610332205450dad010c010b2009280200210520042006460d0020052004200610372205450dac010b20022005360204200241086a20063602002002410c6a28020021040b200520046a200b3a00002002410c6a200441016a3602000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da001200441017422062005200620054b1b22064100480da0010240024020040d00024020060d00410121050c020b200610332205450dac010c010b2002280204210520042006460d0020052004200610372205450dab010b20022005360204200241086a20063602002002410c6a28020021040b200520046a411a3a00002002410c6a200441016a3602000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f01200441017422062005200620054b1b22064100480d9f010240024020040d00024020060d00410121050c020b200610332205450dab010c010b2002280204210520042006460d0020052004200610372205450daa010b20022005360204200241086a20063602002002410c6a28020021040b200520046a411b3a00002002410c6a200441016a3602000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9e01200441017422072006200720064b1b22074100480d9e010240024020040d00024020070d00410121060c020b200710332206450daa010c010b2009280200210620042007460d0020062004200710372206450da9010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41203a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9f01200441017422072006200720064b1b22074100480d9f010240024020040d00024020070d00410121060c020b200710332206450dab010c010b2009280200210620042007460d0020062004200710372206450daa010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9d01200441017422072006200720064b1b22074100480d9d010240024020040d00024020070d00410121060c020b200710332206450da9010c010b2009280200210620042007460d0020062004200710372206450da8010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41213a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9e01200441017422072006200720064b1b22074100480d9e010240024020040d00024020070d00410121060c020b200710332206450daa010c010b2009280200210620042007460d0020062004200710372206450da9010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9c01200441017422072006200720064b1b22074100480d9c010240024020040d00024020070d00410121060c020b200710332206450da8010c010b2009280200210620042007460d0020062004200710372206450da7010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41223a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9d01200441017422072006200720064b1b22074100480d9d010240024020040d00024020070d00410121060c020b200710332206450da9010c010b2009280200210620042007460d0020062004200710372206450da8010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9b01200441017422072006200720064b1b22074100480d9b010240024020040d00024020070d00410121060c020b200710332206450da7010c010b2009280200210620042007460d0020062004200710372206450da6010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41233a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9c01200441017422072006200720064b1b22074100480d9c010240024020040d00024020070d00410121060c020b200710332206450da8010c010b2009280200210620042007460d0020062004200710372206450da7010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9a01200441017422072006200720064b1b22074100480d9a010240024020040d00024020070d00410121060c020b200710332206450da6010c010b2009280200210620042007460d0020062004200710372206450da5010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41243a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9b01200441017422072006200720064b1b22074100480d9b010240024020040d00024020070d00410121060c020b200710332206450da7010c010b2009280200210620042007460d0020062004200710372206450da6010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c99010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9901200441017422082007200820074b1b22084100480d99010240024020040d00024020080d00410121070c020b200810332207450da5010c010b200a280200210720042008460d0020072004200810372207450da4010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41283a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9a01200441017422082007200820074b1b22084100480d9a010240024020040d00024020080d00410121070c020b200810332207450da6010c010b200a280200210720042008460d0020072004200810372207450da5010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9a01200441017422072005200720054b1b22074100480d9a010240024020040d00024020070d00410121050c020b200710332205450da6010c010b200a280200210520042007460d0020052004200710372205450da5010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9801200441017422082007200820074b1b22084100480d98010240024020040d00024020080d00410121070c020b200810332207450da4010c010b200a280200210720042008460d0020072004200810372207450da3010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41293a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9901200441017422082007200820074b1b22084100480d99010240024020040d00024020080d00410121070c020b200810332207450da5010c010b200a280200210720042008460d0020072004200810372207450da4010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9901200441017422072006200720064b1b22074100480d99010240024020040d00024020070d00410121060c020b200710332206450da5010c010b200a280200210620042007460d0020062004200710372206450da4010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9701200441017422082007200820074b1b22084100480d97010240024020040d00024020080d00410121070c020b200810332207450da3010c010b200a280200210720042008460d0020072004200810372207450da2010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412a3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9801200441017422082007200820074b1b22084100480d98010240024020040d00024020080d00410121070c020b200810332207450da4010c010b200a280200210720042008460d0020072004200810372207450da3010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9801200441017422072006200720064b1b22074100480d98010240024020040d00024020070d00410121060c020b200710332206450da4010c010b200a280200210620042007460d0020062004200710372206450da3010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c96010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b200810332207450da2010c010b200a280200210720042008460d0020072004200810372207450da1010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412b3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9701200441017422082007200820074b1b22084100480d97010240024020040d00024020080d00410121070c020b200810332207450da3010c010b200a280200210720042008460d0020072004200810372207450da2010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9701200441017422072005200720054b1b22074100480d97010240024020040d00024020070d00410121050c020b200710332205450da3010c010b200a280200210520042007460d0020052004200710372205450da2010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b200810332207450da1010c010b200a280200210720042008460d0020072004200810372207450da0010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412c3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b200810332207450da2010c010b200a280200210720042008460d0020072004200810372207450da1010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9601200441017422072006200720064b1b22074100480d96010240024020040d00024020070d00410121060c020b200710332206450da2010c010b200a280200210620042007460d0020062004200710372206450da1010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b200810332207450da0010c010b200a280200210720042008460d0020072004200810372207450d9f010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412d3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b2008103322070d010c9e010b200a280200210720042008460d0020072004200810372207450d9c010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9601200441017422072006200720064b1b22074100480d96010240024020040d00024020070d00410121060c020b2007103322060d010c9e010b200a280200210620042007460d0020062004200710372206450d9c010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9401200441017422082007200820074b1b22084100480d94010240024020040d00024020080d00410121070c020b2008103322070d010c9c010b200a280200210720042008460d0020072004200810372207450d9a010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412e3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b2008103322070d010c9d010b200a280200210720042008460d0020072004200810372207450d9b010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9501200441017422072006200720064b1b22074100480d95010240024020040d00024020070d00410121060c020b2007103322060d010c9d010b200a280200210620042007460d0020062004200710372206450d9b010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9301200441017422082007200820074b1b22084100480d93010240024020040d00024020080d00410121070c020b2008103322070d010c9b010b200a280200210720042008460d0020072004200810372207450d99010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412f3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9401200441017422082007200820074b1b22084100480d94010240024020040d00024020080d00410121070c020b2008103322070d010c9c010b200a280200210720042008460d0020072004200810372207450d9a010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9401200441017422072006200720064b1b22074100480d94010240024020040d00024020070d00410121060c020b2007103322060d010c9c010b200a280200210620042007460d0020062004200710372206450d9a010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c91010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9201200441017422082007200820074b1b22084100480d92010240024020040d00024020080d00410121070c020b2008103322070d010c9a010b200a280200210720042008460d0020072004200810372207450d98010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41303a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9301200441017422082007200820074b1b22084100480d93010240024020040d00024020080d00410121070c020b2008103322070d010c9b010b200a280200210720042008460d0020072004200810372207450d99010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9301200441017422072005200720054b1b22074100480d93010240024020040d00024020070d00410121050c020b2007103322050d010c9b010b200a280200210520042007460d0020052004200710372205450d99010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9101200441017422082007200820074b1b22084100480d91010240024020040d00024020080d00410121070c020b2008103322070d010c99010b200a280200210720042008460d0020072004200810372207450d97010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41313a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9201200441017422082007200820074b1b22084100480d92010240024020040d00024020080d00410121070c020b2008103322070d010c9a010b200a280200210720042008460d0020072004200810372207450d98010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9201200441017422072006200720064b1b22074100480d92010240024020040d00024020070d00410121060c020b2007103322060d010c9a010b200a280200210620042007460d0020062004200710372206450d98010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9001200441017422082007200820074b1b22084100480d90010240024020040d00024020080d00410121070c020b2008103322070d010c98010b200a280200210720042008460d0020072004200810372207450d96010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41323a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9101200441017422082007200820074b1b22084100480d91010240024020040d00024020080d00410121070c020b2008103322070d010c99010b200a280200210720042008460d0020072004200810372207450d97010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9101200441017422072006200720064b1b22074100480d91010240024020040d00024020070d00410121060c020b2007103322060d010c99010b200a280200210620042007460d0020062004200710372206450d97010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8f01200441017422082007200820074b1b22084100480d8f010240024020040d00024020080d00410121070c020b2008103322070d010c97010b200a280200210720042008460d0020072004200810372207450d95010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41333a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9001200441017422082007200820074b1b22084100480d90010240024020040d00024020080d00410121070c020b2008103322070d010c98010b200a280200210720042008460d0020072004200810372207450d96010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9001200441017422072006200720064b1b22074100480d90010240024020040d00024020070d00410121060c020b2007103322060d010c98010b200a280200210620042007460d0020062004200710372206450d96010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8d010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8e01200441017422082007200820074b1b22084100480d8e010240024020040d00024020080d00410121070c020b2008103322070d010c96010b200a280200210720042008460d0020072004200810372207450d94010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41343a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8f01200441017422082007200820074b1b22084100480d8f010240024020040d00024020080d00410121070c020b2008103322070d010c97010b200a280200210720042008460d0020072004200810372207450d95010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8f01200441017422072005200720054b1b22074100480d8f010240024020040d00024020070d00410121050c020b2007103322050d010c97010b200a280200210520042007460d0020052004200710372205450d95010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8d01200441017422082007200820074b1b22084100480d8d010240024020040d00024020080d00410121070c020b2008103322070d010c95010b200a280200210720042008460d0020072004200810372207450d93010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41353a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8e01200441017422082007200820074b1b22084100480d8e010240024020040d00024020080d00410121070c020b2008103322070d010c96010b200a280200210720042008460d0020072004200810372207450d94010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8e01200441017422072006200720064b1b22074100480d8e010240024020040d00024020070d00410121060c020b2007103322060d010c96010b200a280200210620042007460d0020062004200710372206450d94010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8b010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8c01200441017422082007200820074b1b22084100480d8c010240024020040d00024020080d00410121070c020b2008103322070d010c94010b200a280200210720042008460d0020072004200810372207450d92010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41363a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8d01200441017422082007200820074b1b22084100480d8d010240024020040d00024020080d00410121070c020b2008103322070d010c95010b200a280200210720042008460d0020072004200810372207450d93010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8d01200441017422072005200720054b1b22074100480d8d010240024020040d00024020070d00410121050c020b2007103322050d010c95010b200a280200210520042007460d0020052004200710372205450d93010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8b01200441017422082007200820074b1b22084100480d8b010240024020040d00024020080d00410121070c020b2008103322070d010c93010b200a280200210720042008460d0020072004200810372207450d91010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41373a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8c01200441017422082007200820074b1b22084100480d8c010240024020040d00024020080d00410121070c020b2008103322070d010c94010b200a280200210720042008460d0020072004200810372207450d92010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8c01200441017422072006200720064b1b22074100480d8c010240024020040d00024020070d00410121060c020b2007103322060d010c94010b200a280200210620042007460d0020062004200710372206450d92010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c89010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8a01200441017422082007200820074b1b22084100480d8a010240024020040d00024020080d00410121070c020b2008103322070d010c92010b200a280200210720042008460d0020072004200810372207450d90010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41383a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8b01200441017422082007200820074b1b22084100480d8b010240024020040d00024020080d00410121070c020b2008103322070d010c93010b200a280200210720042008460d0020072004200810372207450d91010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8b01200441017422072005200720054b1b22074100480d8b010240024020040d00024020070d00410121050c020b2007103322050d010c93010b200a280200210520042007460d0020052004200710372205450d91010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8901200441017422082007200820074b1b22084100480d89010240024020040d00024020080d00410121070c020b2008103322070d010c91010b200a280200210720042008460d0020072004200810372207450d8f010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41393a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8a01200441017422082007200820074b1b22084100480d8a010240024020040d00024020080d00410121070c020b2008103322070d010c92010b200a280200210720042008460d0020072004200810372207450d90010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8a01200441017422072006200720064b1b22074100480d8a010240024020040d00024020070d00410121060c020b2007103322060d010c92010b200a280200210620042007460d0020062004200710372206450d90010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8801200441017422082007200820074b1b22084100480d88010240024020040d00024020080d00410121070c020b2008103322070d010c90010b200a280200210720042008460d0020072004200810372207450d8e010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413a3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8901200441017422082007200820074b1b22084100480d89010240024020040d00024020080d00410121070c020b2008103322070d010c91010b200a280200210720042008460d0020072004200810372207450d8f010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8901200441017422072006200720064b1b22074100480d89010240024020040d00024020070d00410121060c020b2007103322060d010c91010b200a280200210620042007460d0020062004200710372206450d8f010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8701200441017422082007200820074b1b22084100480d87010240024020040d00024020080d00410121070c020b2008103322070d010c8f010b200a280200210720042008460d0020072004200810372207450d8d010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413b3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8801200441017422082007200820074b1b22084100480d88010240024020040d00024020080d00410121070c020b2008103322070d010c90010b200a280200210720042008460d0020072004200810372207450d8e010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8801200441017422072006200720064b1b22074100480d88010240024020040d00024020070d00410121060c020b2007103322060d010c90010b200a280200210620042007460d0020062004200710372206450d8e010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c85010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8601200441017422082007200820074b1b22084100480d86010240024020040d00024020080d00410121070c020b2008103322070d010c8e010b200a280200210720042008460d0020072004200810372207450d8c010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413c3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8701200441017422082007200820074b1b22084100480d87010240024020040d00024020080d00410121070c020b2008103322070d010c8f010b200a280200210720042008460d0020072004200810372207450d8d010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8701200441017422072006200720064b1b22074100480d87010240024020040d00024020070d00410121060c020b2007103322060d010c8f010b200a280200210620042007460d0020062004200710372206450d8d010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c84010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8501200441017422082007200820074b1b22084100480d85010240024020040d00024020080d00410121070c020b2008103322070d010c8d010b200a280200210720042008460d0020072004200810372207450d8b010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413d3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8601200441017422082007200820074b1b22084100480d86010240024020040d00024020080d00410121070c020b2008103322070d010c8e010b200a280200210720042008460d0020072004200810372207450d8c010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8601200441017422072005200720054b1b22074100480d86010240024020040d00024020070d00410121050c020b2007103322050d010c8e010b200a280200210520042007460d0020052004200710372205450d8c010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c83010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8401200441017422082007200820074b1b22084100480d84010240024020040d00024020080d00410121070c020b2008103322070d010c8c010b200a280200210720042008460d0020072004200810372207450d8a010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413e3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8501200441017422082007200820074b1b22084100480d85010240024020040d00024020080d00410121070c020b2008103322070d010c8d010b200a280200210720042008460d0020072004200810372207450d8b010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8501200441017422072005200720054b1b22074100480d85010240024020040d00024020070d00410121050c020b2007103322050d010c8d010b200a280200210520042007460d0020052004200710372205450d8b010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8b010b2006280200210520042008460d0020052004200810372205450d89010b20022005360204200241086a20083602002002410c6a28020021040b200520046a413f3a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8b010b2006280200210520042008460d0020052004200810372205450d89010b20022005360204200241086a20083602002002410c6a28020021040b200520046a20073a00002002410c6a200441016a3602000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8201200441017422082005200820054b1b22084100480d82010240024020040d00024020080d00410121050c020b2008103322050d010c8a010b2006280200210520042008460d0020052004200810372205450d88010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41c0003a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8a010b2006280200210520042008460d0020052004200810372205450d88010b20022005360204200241086a20083602002002410c6a28020021040b200520046a20073a00002002410c6a200441016a3602000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8201200441017422072005200720054b1b22074100480d82010240024020040d00024020070d00410121050c020b2007103322050d010c89010b2002280204210520042007460d0020052004200710372205450d84010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c1003a00002002410c6a200441016a36020020032006200210a5072003210420032d0000411f470d87010c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8101200441017422062005200620054b1b22064100480d81010240024020040d00024020060d00410121050c020b2006103322050d010c88010b2002280204210520042006460d0020052004200610372205450d83010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c2003a00002002410c6a200441016a3602002003200c200210a6072003210420032d0000411f470d86010c7d0b200241046a2106200141046a280200210802400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8001200441017422072005200720054b1b22074100480d80010240024020040d00024020070d00410121050c020b2007103322050d010c87010b2006280200210520042007460d0020052004200710372205450d82010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c3003a00002002410c6a200441016a220436020002400240200241086a280200220720046b4104490d00200628020021050c010b200441046a22052004490d8001200741017422042005200420054b1b22044100480d80010240024020070d00024020040d00410121050c020b2004103322050d010c87010b2006280200210520072004460d0020052007200410372205450d82010b20022005360204200241086a20043602002002410c6a28020021040b200520046a20083600002002410c6a200441046a3602000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d7f200441017422072005200720054b1b22074100480d7f0240024020040d00024020070d00410121050c020b2007103322050d010c86010b2006280200210520042007460d0020052004200710372205450d81010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c4003a00002002410c6a200441016a220436020002400240200241086a280200220720046b4108490d00200628020021050c010b200441086a22052004490d7f200741017422042005200420054b1b22044100480d7f0240024020070d00024020040d00410121050c020b2004103322050d010c86010b2006280200210520072004460d0020052007200410372205450d81010b20022005360204200241086a20043602002002410c6a28020021040b200520046a200c3700002002410c6a200441086a3602000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7e200441017422062005200620054b1b22064100480d7e0240024020040d00024020060d00410121050c020b2006103322050d010c85010b2002280204210520042006460d0020052004200610372205450d80010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c5003a00002002410c6a200441016a3602000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7d200441017422062005200620054b1b22064100480d7d0240024020040d00024020060d00410121050c020b2006103322050d010c84010b2002280204210520042006460d0020052004200610372205450d7f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c6003a00002002410c6a200441016a3602000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7c200441017422062005200620054b1b22064100480d7c0240024020040d00024020060d00410121050c020b2006103322050d010c83010b2002280204210520042006460d0020052004200610372205450d7e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c7003a00002002410c6a200441016a3602000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7b200441017422062005200620054b1b22064100480d7b0240024020040d00024020060d00410121050c020b2006103322050d010c82010b2002280204210520042006460d0020052004200610372205450d7d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c8003a00002002410c6a200441016a3602000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7a200441017422062005200620054b1b22064100480d7a0240024020040d00024020060d00410121050c020b2006103322050d010c81010b2002280204210520042006460d0020052004200610372205450d7c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c9003a00002002410c6a200441016a3602000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d79200441017422062005200620054b1b22064100480d790240024020040d00024020060d00410121050c020b2006103322050d010c80010b2002280204210520042006460d0020052004200610372205450d7b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ca003a00002002410c6a200441016a3602000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d78200441017422062005200620054b1b22064100480d780240024020040d00024020060d00410121050c020b2006103322050d010c7f0b2002280204210520042006460d0020052004200610372205450d7a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cb003a00002002410c6a200441016a3602000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d77200441017422062005200620054b1b22064100480d770240024020040d00024020060d00410121050c020b2006103322050d010c7e0b2002280204210520042006460d0020052004200610372205450d790b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cc003a00002002410c6a200441016a3602000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d76200441017422062005200620054b1b22064100480d760240024020040d00024020060d00410121050c020b2006103322050d010c7d0b2002280204210520042006460d0020052004200610372205450d780b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cd003a00002002410c6a200441016a3602000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d75200441017422062005200620054b1b22064100480d750240024020040d00024020060d00410121050c020b2006103322050d010c7c0b2002280204210520042006460d0020052004200610372205450d770b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ce003a00002002410c6a200441016a3602000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d74200441017422062005200620054b1b22064100480d740240024020040d00024020060d00410121050c020b2006103322050d010c7b0b2002280204210520042006460d0020052004200610372205450d760b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cf003a00002002410c6a200441016a3602000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d73200441017422062005200620054b1b22064100480d730240024020040d00024020060d00410121050c020b2006103322050d010c7a0b2002280204210520042006460d0020052004200610372205450d750b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d0003a00002002410c6a200441016a3602000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d72200441017422062005200620054b1b22064100480d720240024020040d00024020060d00410121050c020b2006103322050d010c790b2002280204210520042006460d0020052004200610372205450d740b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d1003a00002002410c6a200441016a3602000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d71200441017422062005200620054b1b22064100480d710240024020040d00024020060d00410121050c020b2006103322050d010c780b2002280204210520042006460d0020052004200610372205450d730b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d2003a00002002410c6a200441016a3602000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d70200441017422062005200620054b1b22064100480d700240024020040d00024020060d00410121050c020b2006103322050d010c770b2002280204210520042006460d0020052004200610372205450d720b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d3003a00002002410c6a200441016a3602000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6f200441017422062005200620054b1b22064100480d6f0240024020040d00024020060d00410121050c020b2006103322050d010c760b2002280204210520042006460d0020052004200610372205450d710b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d4003a00002002410c6a200441016a3602000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6e200441017422062005200620054b1b22064100480d6e0240024020040d00024020060d00410121050c020b2006103322050d010c750b2002280204210520042006460d0020052004200610372205450d700b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d5003a00002002410c6a200441016a3602000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6d200441017422062005200620054b1b22064100480d6d0240024020040d00024020060d00410121050c020b2006103322050d010c740b2002280204210520042006460d0020052004200610372205450d6f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d6003a00002002410c6a200441016a3602000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6c200441017422062005200620054b1b22064100480d6c0240024020040d00024020060d00410121050c020b2006103322050d010c730b2002280204210520042006460d0020052004200610372205450d6e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d7003a00002002410c6a200441016a3602000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6b200441017422062005200620054b1b22064100480d6b0240024020040d00024020060d00410121050c020b2006103322050d010c720b2002280204210520042006460d0020052004200610372205450d6d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d8003a00002002410c6a200441016a3602000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6a200441017422062005200620054b1b22064100480d6a0240024020040d00024020060d00410121050c020b2006103322050d010c710b2002280204210520042006460d0020052004200610372205450d6c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d9003a00002002410c6a200441016a3602000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d69200441017422062005200620054b1b22064100480d690240024020040d00024020060d00410121050c020b2006103322050d010c700b2002280204210520042006460d0020052004200610372205450d6b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41da003a00002002410c6a200441016a3602000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d68200441017422062005200620054b1b22064100480d680240024020040d00024020060d00410121050c020b2006103322050d010c6f0b2002280204210520042006460d0020052004200610372205450d6a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41db003a00002002410c6a200441016a3602000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d67200441017422062005200620054b1b22064100480d670240024020040d00024020060d00410121050c020b2006103322050d010c6e0b2002280204210520042006460d0020052004200610372205450d690b20022005360204200241086a20063602002002410c6a28020021040b200520046a41dc003a00002002410c6a200441016a3602000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d66200441017422062005200620054b1b22064100480d660240024020040d00024020060d00410121050c020b2006103322050d010c6d0b2002280204210520042006460d0020052004200610372205450d680b20022005360204200241086a20063602002002410c6a28020021040b200520046a41dd003a00002002410c6a200441016a3602000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d65200441017422062005200620054b1b22064100480d650240024020040d00024020060d00410121050c020b2006103322050d010c6c0b2002280204210520042006460d0020052004200610372205450d670b20022005360204200241086a20063602002002410c6a28020021040b200520046a41de003a00002002410c6a200441016a3602000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d64200441017422062005200620054b1b22064100480d640240024020040d00024020060d00410121050c020b2006103322050d010c6b0b2002280204210520042006460d0020052004200610372205450d660b20022005360204200241086a20063602002002410c6a28020021040b200520046a41df003a00002002410c6a200441016a3602000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d63200441017422062005200620054b1b22064100480d630240024020040d00024020060d00410121050c020b2006103322050d010c6a0b2002280204210520042006460d0020052004200610372205450d650b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e0003a00002002410c6a200441016a3602000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d62200441017422062005200620054b1b22064100480d620240024020040d00024020060d00410121050c020b2006103322050d010c690b2002280204210520042006460d0020052004200610372205450d640b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e1003a00002002410c6a200441016a3602000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d61200441017422062005200620054b1b22064100480d610240024020040d00024020060d00410121050c020b2006103322050d010c680b2002280204210520042006460d0020052004200610372205450d630b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e2003a00002002410c6a200441016a3602000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d60200441017422062005200620054b1b22064100480d600240024020040d00024020060d00410121050c020b2006103322050d010c670b2002280204210520042006460d0020052004200610372205450d620b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e3003a00002002410c6a200441016a3602000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5f200441017422062005200620054b1b22064100480d5f0240024020040d00024020060d00410121050c020b2006103322050d010c660b2002280204210520042006460d0020052004200610372205450d610b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e4003a00002002410c6a200441016a3602000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5e200441017422062005200620054b1b22064100480d5e0240024020040d00024020060d00410121050c020b2006103322050d010c650b2002280204210520042006460d0020052004200610372205450d600b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e5003a00002002410c6a200441016a3602000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5d200441017422062005200620054b1b22064100480d5d0240024020040d00024020060d00410121050c020b2006103322050d010c640b2002280204210520042006460d0020052004200610372205450d5f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e6003a00002002410c6a200441016a3602000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5c200441017422062005200620054b1b22064100480d5c0240024020040d00024020060d00410121050c020b2006103322050d010c630b2002280204210520042006460d0020052004200610372205450d5e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e7003a00002002410c6a200441016a3602000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5b200441017422062005200620054b1b22064100480d5b0240024020040d00024020060d00410121050c020b2006103322050d010c620b2002280204210520042006460d0020052004200610372205450d5d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e8003a00002002410c6a200441016a3602000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5a200441017422062005200620054b1b22064100480d5a0240024020040d00024020060d00410121050c020b2006103322050d010c610b2002280204210520042006460d0020052004200610372205450d5c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e9003a00002002410c6a200441016a3602000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d59200441017422062005200620054b1b22064100480d590240024020040d00024020060d00410121050c020b2006103322050d010c600b2002280204210520042006460d0020052004200610372205450d5b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ea003a00002002410c6a200441016a3602000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d58200441017422062005200620054b1b22064100480d580240024020040d00024020060d00410121050c020b2006103322050d010c5f0b2002280204210520042006460d0020052004200610372205450d5a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41eb003a00002002410c6a200441016a3602000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d57200441017422062005200620054b1b22064100480d570240024020040d00024020060d00410121050c020b2006103322050d010c5e0b2002280204210520042006460d0020052004200610372205450d590b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ec003a00002002410c6a200441016a3602000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d56200441017422062005200620054b1b22064100480d560240024020040d00024020060d00410121050c020b2006103322050d010c5d0b2002280204210520042006460d0020052004200610372205450d580b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ed003a00002002410c6a200441016a3602000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d55200441017422062005200620054b1b22064100480d550240024020040d00024020060d00410121050c020b2006103322050d010c5c0b2002280204210520042006460d0020052004200610372205450d570b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ee003a00002002410c6a200441016a3602000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d54200441017422062005200620054b1b22064100480d540240024020040d00024020060d00410121050c020b2006103322050d010c5b0b2002280204210520042006460d0020052004200610372205450d560b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ef003a00002002410c6a200441016a3602000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d53200441017422062005200620054b1b22064100480d530240024020040d00024020060d00410121050c020b2006103322050d010c5a0b2002280204210520042006460d0020052004200610372205450d550b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f0003a00002002410c6a200441016a3602000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d52200441017422062005200620054b1b22064100480d520240024020040d00024020060d00410121050c020b2006103322050d010c590b2002280204210520042006460d0020052004200610372205450d540b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f1003a00002002410c6a200441016a3602000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d51200441017422062005200620054b1b22064100480d510240024020040d00024020060d00410121050c020b2006103322050d010c580b2002280204210520042006460d0020052004200610372205450d530b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f2003a00002002410c6a200441016a3602000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d50200441017422062005200620054b1b22064100480d500240024020040d00024020060d00410121050c020b2006103322050d010c570b2002280204210520042006460d0020052004200610372205450d520b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f3003a00002002410c6a200441016a3602000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4f200441017422062005200620054b1b22064100480d4f0240024020040d00024020060d00410121050c020b2006103322050d010c560b2002280204210520042006460d0020052004200610372205450d510b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f4003a00002002410c6a200441016a3602000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4e200441017422062005200620054b1b22064100480d4e0240024020040d00024020060d00410121050c020b2006103322050d010c550b2002280204210520042006460d0020052004200610372205450d500b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f5003a00002002410c6a200441016a3602000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4d200441017422062005200620054b1b22064100480d4d0240024020040d00024020060d00410121050c020b2006103322050d010c540b2002280204210520042006460d0020052004200610372205450d4f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f6003a00002002410c6a200441016a3602000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4c200441017422062005200620054b1b22064100480d4c0240024020040d00024020060d00410121050c020b2006103322050d010c530b2002280204210520042006460d0020052004200610372205450d4e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f7003a00002002410c6a200441016a3602000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4b200441017422062005200620054b1b22064100480d4b0240024020040d00024020060d00410121050c020b2006103322050d010c520b2002280204210520042006460d0020052004200610372205450d4d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f8003a00002002410c6a200441016a3602000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4a200441017422062005200620054b1b22064100480d4a0240024020040d00024020060d00410121050c020b2006103322050d010c510b2002280204210520042006460d0020052004200610372205450d4c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f9003a00002002410c6a200441016a3602000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d49200441017422062005200620054b1b22064100480d490240024020040d00024020060d00410121050c020b2006103322050d010c500b2002280204210520042006460d0020052004200610372205450d4b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fa003a00002002410c6a200441016a3602000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d48200441017422062005200620054b1b22064100480d480240024020040d00024020060d00410121050c020b2006103322050d010c4f0b2002280204210520042006460d0020052004200610372205450d4a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fb003a00002002410c6a200441016a3602000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d47200441017422062005200620054b1b22064100480d470240024020040d00024020060d00410121050c020b2006103322050d010c4e0b2002280204210520042006460d0020052004200610372205450d490b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fc003a00002002410c6a200441016a3602000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d46200441017422062005200620054b1b22064100480d460240024020040d00024020060d00410121050c020b2006103322050d010c4d0b2002280204210520042006460d0020052004200610372205450d480b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fd003a00002002410c6a200441016a3602000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d45200441017422062005200620054b1b22064100480d450240024020040d00024020060d00410121050c020b2006103322050d010c4c0b2002280204210520042006460d0020052004200610372205450d470b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fe003a00002002410c6a200441016a3602000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d44200441017422062005200620054b1b22064100480d440240024020040d00024020060d00410121050c020b2006103322050d010c4b0b2002280204210520042006460d0020052004200610372205450d460b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ff003a00002002410c6a200441016a3602000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d43200441017422062005200620054b1b22064100480d430240024020040d00024020060d00410121050c020b2006103322050d010c4a0b2002280204210520042006460d0020052004200610372205450d450b20022005360204200241086a20063602002002410c6a28020021040b200520046a4180013a00002002410c6a200441016a3602000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d42200441017422062005200620054b1b22064100480d420240024020040d00024020060d00410121050c020b2006103322050d010c490b2002280204210520042006460d0020052004200610372205450d440b20022005360204200241086a20063602002002410c6a28020021040b200520046a4181013a00002002410c6a200441016a3602000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d41200441017422062005200620054b1b22064100480d410240024020040d00024020060d00410121050c020b2006103322050d010c480b2002280204210520042006460d0020052004200610372205450d430b20022005360204200241086a20063602002002410c6a28020021040b200520046a4182013a00002002410c6a200441016a3602000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d40200441017422062005200620054b1b22064100480d400240024020040d00024020060d00410121050c020b2006103322050d010c470b2002280204210520042006460d0020052004200610372205450d420b20022005360204200241086a20063602002002410c6a28020021040b200520046a4183013a00002002410c6a200441016a3602000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3f200441017422062005200620054b1b22064100480d3f0240024020040d00024020060d00410121050c020b2006103322050d010c460b2002280204210520042006460d0020052004200610372205450d410b20022005360204200241086a20063602002002410c6a28020021040b200520046a4184013a00002002410c6a200441016a3602000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3e200441017422062005200620054b1b22064100480d3e0240024020040d00024020060d00410121050c020b2006103322050d010c450b2002280204210520042006460d0020052004200610372205450d400b20022005360204200241086a20063602002002410c6a28020021040b200520046a4185013a00002002410c6a200441016a3602000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3d200441017422062005200620054b1b22064100480d3d0240024020040d00024020060d00410121050c020b2006103322050d010c440b2002280204210520042006460d0020052004200610372205450d3f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4186013a00002002410c6a200441016a3602000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3c200441017422062005200620054b1b22064100480d3c0240024020040d00024020060d00410121050c020b2006103322050d010c430b2002280204210520042006460d0020052004200610372205450d3e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4187013a00002002410c6a200441016a3602000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3b200441017422062005200620054b1b22064100480d3b0240024020040d00024020060d00410121050c020b2006103322050d010c420b2002280204210520042006460d0020052004200610372205450d3d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4188013a00002002410c6a200441016a3602000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3d200441017422062005200620054b1b22064100480d3d0240024020040d00024020060d00410121050c020b2006103322050d010c410b2002280204210520042006460d0020052004200610372205450d3c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4189013a00002002410c6a200441016a3602000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3c200441017422062005200620054b1b22064100480d3c0240024020040d00024020060d00410121050c020b2006103322050d010c400b2002280204210520042006460d0020052004200610372205450d3c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418a013a00002002410c6a200441016a3602000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3b200441017422062005200620054b1b22064100480d3b0240024020040d00024020060d00410121050c020b2006103322050d010c3f0b2002280204210520042006460d0020052004200610372205450d3b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418b013a00002002410c6a200441016a3602000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3a200441017422062005200620054b1b22064100480d3a0240024020040d00024020060d00410121050c020b2006103322050d010c3e0b2002280204210520042006460d0020052004200610372205450d3a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418c013a00002002410c6a200441016a3602000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d39200441017422062005200620054b1b22064100480d390240024020040d00024020060d00410121050c020b2006103322050d010c3d0b2002280204210520042006460d0020052004200610372205450d390b20022005360204200241086a20063602002002410c6a28020021040b200520046a418d013a00002002410c6a200441016a3602000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d38200441017422062005200620054b1b22064100480d380240024020040d00024020060d00410121050c020b2006103322050d010c3c0b2002280204210520042006460d0020052004200610372205450d380b20022005360204200241086a20063602002002410c6a28020021040b200520046a418e013a00002002410c6a200441016a3602000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d37200441017422062005200620054b1b22064100480d370240024020040d00024020060d00410121050c020b2006103322050d010c3b0b2002280204210520042006460d0020052004200610372205450d370b20022005360204200241086a20063602002002410c6a28020021040b200520046a418f013a00002002410c6a200441016a3602000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d36200441017422062005200620054b1b22064100480d360240024020040d00024020060d00410121050c020b2006103322050d010c3a0b2002280204210520042006460d0020052004200610372205450d360b20022005360204200241086a20063602002002410c6a28020021040b200520046a4190013a00002002410c6a200441016a3602000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d35200441017422062005200620054b1b22064100480d350240024020040d00024020060d00410121050c020b2006103322050d010c390b2002280204210520042006460d0020052004200610372205450d350b20022005360204200241086a20063602002002410c6a28020021040b200520046a4191013a00002002410c6a200441016a3602000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d34200441017422062005200620054b1b22064100480d340240024020040d00024020060d00410121050c020b2006103322050d010c380b2002280204210520042006460d0020052004200610372205450d340b20022005360204200241086a20063602002002410c6a28020021040b200520046a4192013a00002002410c6a200441016a3602000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d33200441017422062005200620054b1b22064100480d330240024020040d00024020060d00410121050c020b2006103322050d010c370b2002280204210520042006460d0020052004200610372205450d330b20022005360204200241086a20063602002002410c6a28020021040b200520046a4193013a00002002410c6a200441016a3602000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d32200441017422062005200620054b1b22064100480d320240024020040d00024020060d00410121050c020b2006103322050d010c360b2002280204210520042006460d0020052004200610372205450d320b20022005360204200241086a20063602002002410c6a28020021040b200520046a4194013a00002002410c6a200441016a3602000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d31200441017422062005200620054b1b22064100480d310240024020040d00024020060d00410121050c020b2006103322050d010c350b2002280204210520042006460d0020052004200610372205450d310b20022005360204200241086a20063602002002410c6a28020021040b200520046a4195013a00002002410c6a200441016a3602000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d30200441017422062005200620054b1b22064100480d300240024020040d00024020060d00410121050c020b2006103322050d010c340b2002280204210520042006460d0020052004200610372205450d300b20022005360204200241086a20063602002002410c6a28020021040b200520046a4196013a00002002410c6a200441016a3602000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2f200441017422062005200620054b1b22064100480d2f0240024020040d00024020060d00410121050c020b2006103322050d010c330b2002280204210520042006460d0020052004200610372205450d2f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4197013a00002002410c6a200441016a3602000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2e200441017422062005200620054b1b22064100480d2e0240024020040d00024020060d00410121050c020b2006103322050d010c320b2002280204210520042006460d0020052004200610372205450d2e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4198013a00002002410c6a200441016a3602000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2d200441017422062005200620054b1b22064100480d2d0240024020040d00024020060d00410121050c020b2006103322050d010c310b2002280204210520042006460d0020052004200610372205450d2d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4199013a00002002410c6a200441016a3602000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2c200441017422062005200620054b1b22064100480d2c0240024020040d00024020060d00410121050c020b2006103322050d010c300b2002280204210520042006460d0020052004200610372205450d2c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419a013a00002002410c6a200441016a3602000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2b200441017422062005200620054b1b22064100480d2b0240024020040d00024020060d00410121050c020b2006103322050d010c2f0b2002280204210520042006460d0020052004200610372205450d2b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419b013a00002002410c6a200441016a3602000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2a200441017422062005200620054b1b22064100480d2a0240024020040d00024020060d00410121050c020b2006103322050d010c2d0b2002280204210520042006460d0020052004200610372205450d2a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419c013a00002002410c6a200441016a3602000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d29200441017422062005200620054b1b22064100480d290240024020040d00024020060d00410121050c020b200610332205450d2c0c010b2002280204210520042006460d0020052004200610372205450d290b20022005360204200241086a20063602002002410c6a28020021040b200520046a419d013a00002002410c6a200441016a3602000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d28200441017422062005200620054b1b22064100480d280240024020040d00024020060d00410121050c020b200610332205450d2b0c010b2002280204210520042006460d0020052004200610372205450d280b20022005360204200241086a20063602002002410c6a28020021040b200520046a419e013a00002002410c6a200441016a3602000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d27200441017422062005200620054b1b22064100480d270240024020040d00024020060d00410121050c020b200610332205450d2a0c010b2002280204210520042006460d0020052004200610372205450d270b20022005360204200241086a20063602002002410c6a28020021040b200520046a419f013a00002002410c6a200441016a3602000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d26200441017422062005200620054b1b22064100480d260240024020040d00024020060d00410121050c020b200610332205450d290c010b2002280204210520042006460d0020052004200610372205450d260b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a0013a00002002410c6a200441016a3602000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d25200441017422062005200620054b1b22064100480d250240024020040d00024020060d00410121050c020b200610332205450d280c010b2002280204210520042006460d0020052004200610372205450d250b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a1013a00002002410c6a200441016a3602000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d24200441017422062005200620054b1b22064100480d240240024020040d00024020060d00410121050c020b200610332205450d270c010b2002280204210520042006460d0020052004200610372205450d240b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a2013a00002002410c6a200441016a3602000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d23200441017422062005200620054b1b22064100480d230240024020040d00024020060d00410121050c020b200610332205450d260c010b2002280204210520042006460d0020052004200610372205450d230b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a3013a00002002410c6a200441016a3602000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d22200441017422062005200620054b1b22064100480d220240024020040d00024020060d00410121050c020b200610332205450d250c010b2002280204210520042006460d0020052004200610372205450d220b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a4013a00002002410c6a200441016a3602000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d00024020060d00410121050c020b200610332205450d240c010b2002280204210520042006460d0020052004200610372205450d210b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a5013a00002002410c6a200441016a3602000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d20200441017422062005200620054b1b22064100480d200240024020040d00024020060d00410121050c020b200610332205450d230c010b2002280204210520042006460d0020052004200610372205450d200b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a6013a00002002410c6a200441016a3602000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1f200441017422062005200620054b1b22064100480d1f0240024020040d00024020060d00410121050c020b200610332205450d220c010b2002280204210520042006460d0020052004200610372205450d1f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a7013a00002002410c6a200441016a3602000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1e200441017422062005200620054b1b22064100480d1e0240024020040d00024020060d00410121050c020b200610332205450d210c010b2002280204210520042006460d0020052004200610372205450d1e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a8013a00002002410c6a200441016a3602000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1d200441017422062005200620054b1b22064100480d1d0240024020040d00024020060d00410121050c020b200610332205450d200c010b2002280204210520042006460d0020052004200610372205450d1d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a9013a00002002410c6a200441016a3602000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1c200441017422062005200620054b1b22064100480d1c0240024020040d00024020060d00410121050c020b200610332205450d1f0c010b2002280204210520042006460d0020052004200610372205450d1c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41aa013a00002002410c6a200441016a3602000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1b200441017422062005200620054b1b22064100480d1b0240024020040d00024020060d00410121050c020b200610332205450d1e0c010b2002280204210520042006460d0020052004200610372205450d1b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ab013a00002002410c6a200441016a3602000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1a200441017422062005200620054b1b22064100480d1a0240024020040d00024020060d00410121050c020b200610332205450d1d0c010b2002280204210520042006460d0020052004200610372205450d1a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ac013a00002002410c6a200441016a3602000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d19200441017422062005200620054b1b22064100480d190240024020040d00024020060d00410121050c020b200610332205450d1c0c010b2002280204210520042006460d0020052004200610372205450d190b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ad013a00002002410c6a200441016a3602000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d18200441017422062005200620054b1b22064100480d180240024020040d00024020060d00410121050c020b200610332205450d1b0c010b2002280204210520042006460d0020052004200610372205450d180b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ae013a00002002410c6a200441016a3602000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d17200441017422062005200620054b1b22064100480d170240024020040d00024020060d00410121050c020b200610332205450d1a0c010b2002280204210520042006460d0020052004200610372205450d170b20022005360204200241086a20063602002002410c6a28020021040b200520046a41af013a00002002410c6a200441016a3602000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d16200441017422062005200620054b1b22064100480d160240024020040d00024020060d00410121050c020b200610332205450d190c010b2002280204210520042006460d0020052004200610372205450d160b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b0013a00002002410c6a200441016a3602000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d15200441017422062005200620054b1b22064100480d150240024020040d00024020060d00410121050c020b200610332205450d180c010b2002280204210520042006460d0020052004200610372205450d150b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b1013a00002002410c6a200441016a3602000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d14200441017422062005200620054b1b22064100480d140240024020040d00024020060d00410121050c020b200610332205450d170c010b2002280204210520042006460d0020052004200610372205450d140b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b2013a00002002410c6a200441016a3602000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d13200441017422062005200620054b1b22064100480d130240024020040d00024020060d00410121050c020b200610332205450d160c010b2002280204210520042006460d0020052004200610372205450d130b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b3013a00002002410c6a200441016a3602000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d12200441017422062005200620054b1b22064100480d120240024020040d00024020060d00410121050c020b200610332205450d150c010b2002280204210520042006460d0020052004200610372205450d120b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b4013a00002002410c6a200441016a3602000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d11200441017422062005200620054b1b22064100480d110240024020040d00024020060d00410121050c020b200610332205450d140c010b2002280204210520042006460d0020052004200610372205450d110b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b5013a00002002410c6a200441016a3602000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d10200441017422062005200620054b1b22064100480d100240024020040d00024020060d00410121050c020b200610332205450d130c010b2002280204210520042006460d0020052004200610372205450d100b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b6013a00002002410c6a200441016a3602000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0f200441017422062005200620054b1b22064100480d0f0240024020040d00024020060d00410121050c020b200610332205450d120c010b2002280204210520042006460d0020052004200610372205450d0f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b7013a00002002410c6a200441016a3602000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0e200441017422062005200620054b1b22064100480d0e0240024020040d00024020060d00410121050c020b200610332205450d110c010b2002280204210520042006460d0020052004200610372205450d0e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b8013a00002002410c6a200441016a3602000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0d200441017422062005200620054b1b22064100480d0d0240024020040d00024020060d00410121050c020b200610332205450d100c010b2002280204210520042006460d0020052004200610372205450d0d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b9013a00002002410c6a200441016a3602000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0c200441017422062005200620054b1b22064100480d0c0240024020040d00024020060d00410121050c020b200610332205450d0f0c010b2002280204210520042006460d0020052004200610372205450d0c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ba013a00002002410c6a200441016a3602000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0b200441017422062005200620054b1b22064100480d0b0240024020040d00024020060d00410121050c020b200610332205450d0e0c010b2002280204210520042006460d0020052004200610372205450d0b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bb013a00002002410c6a200441016a3602000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0a200441017422062005200620054b1b22064100480d0a0240024020040d00024020060d00410121050c020b200610332205450d0d0c010b2002280204210520042006460d0020052004200610372205450d0a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bc013a00002002410c6a200441016a3602000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d09200441017422062005200620054b1b22064100480d090240024020040d00024020060d00410121050c020b200610332205450d0c0c010b2002280204210520042006460d0020052004200610372205450d090b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bd013a00002002410c6a200441016a3602000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d08200441017422062005200620054b1b22064100480d080240024020040d00024020060d00410121050c020b200610332205450d0b0c010b2002280204210520042006460d0020052004200610372205450d080b20022005360204200241086a20063602002002410c6a28020021040b200520046a41be013a00002002410c6a200441016a3602000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d07200441017422062005200620054b1b22064100480d070240024020040d00024020060d00410121050c020b200610332205450d0a0c010b2002280204210520042006460d0020052004200610372205450d070b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bf013a00002002410c6a200441016a3602000b2000411f3a000020012d00004109470d090240200141046a280200220228020441ffffffff0371450d0020022802001035200128020421020b200210350c090b103e000b103e000b103e000b103c000b103c000b103e000b103c000b103c000b20002004290200370200200041086a200441086a29020037020020012d00004109470d000240200141046a280200220228020441ffffffff0371450d0020022802001035200128020421020b200210350b200341106a24000f0b103c000bd80301057f2004410c6a22052802002106200441086a21070240024003400240024020072802002006460d00200428020421080c010b200641016a22082006490d02200641017422092008200920084b1b22094100480d020240024020060d00024020090d00410121080c020b2009103322080d010c050b2004280204210820062009460d0020082006200910372208450d040b2004200836020420072009360200200528020021060b200820066a200141807f72200141ff0071200141077622081b3a00002005200641016a22063602002008210120080d000b024020022003460d00200441086a21052004410c6a210703402002280200210103400240024020052802002006460d00200428020421080c010b200641016a22082006490d04200641017422092008200920084b1b22094100480d040240024020060d00024020090d00410121080c020b200910332208450d070c010b2004280204210820062009460d0020082006200910372208450d060b2004200836020420052009360200200728020021060b200820066a200141807f72200141ff0071200141077622081b3a00002007200641016a22063602002008210120080d000b200241046a22022003470d000b0b2000411f3a00000f0b103e000b103c000bdb0301067f024002400240024020014107752203200141c00071220472452003417f4720044572470d002002410c6a28020021040c010b2002410c6a22052802002104200241086a210603400240024020062802002004460d00200228020421070c010b200441016a22072004490d03200441017422082007200820074b1b22084100480d030240024020040d00024020080d00410121070c020b2008103322070d010c060b2002280204210720042008460d0020072004200810372207450d050b2002200736020420062008360200200528020021040b200720046a200141807f723a00002005200441016a2204360200200341c000712107200321012003410775220821032008200772452008417f4720074572470d000b0b02400240200241086a2802002004460d00200228020421030c010b200441016a22032004490d01200441017422072003200720034b1b22074100480d010240024020040d00024020070d00410121030c020b200710332203450d040c010b2002280204210320042007460d0020032004200710372203450d030b20022003360204200241086a20073602002002410c6a28020021040b200320046a200141ff00713a00002000411f3a00002002410c6a200441016a3602000f0b103e000b103c000bdf0302017e067f024002400240024020014207872203502001a7220441c00071452205712003427f52200572470d002002410c6a28020021050c010b2002410c6a22062802002105200241086a210703400240024020072802002005460d00200228020421080c010b200541016a22082005490d03200541017422092008200920084b1b22094100480d030240024020050d00024020090d00410121080c020b2009103322080d010c060b2002280204210820052009460d0020082005200910372208450d050b2002200836020420072009360200200628020021050b200820056a200441807f723a00002006200541016a22053602002003a72104200342078722012103200150200441c00071452208712001427f52200872470d000b0b02400240200241086a2802002005460d00200228020421080c010b200541016a22082005490d01200541017422092008200920084b1b22094100480d010240024020050d00024020090d00410121080c020b200910332208450d040c010b2002280204210820052009460d0020082005200910372208450d030b20022008360204200241086a20093602002002410c6a28020021050b200820056a200441ff00713a00002000411f3a00002002410c6a200541016a3602000f0b103e000b103c000bc40301077f230041d0006b22022400410021032002410036021020024208370308200241c1006a220441076a210541082106024002400340200241386a200110a807200220042900003703282002200529000037002f20022d0040210720022802384101460d012002200229002f37001f200220022903283703182002200229001f37003f2002200229031837033802402003200228020c470d00200241086a200310a90720022802082106200228021021030b200620034104746a220820073a000020082002290338370001200841086a200229003f3700002002200341016a2203360210200741ff01714106470d000b20002002290308370204200041003602002000410c6a200241106a2802003602000c010b2000200228023c3602042000200229032837000920004101360200200041086a20073a0000200041106a200228002f36000002402003450d0020034104742107200621030340024020032d00004109470d000240200341046a2201280200220828020441ffffffff0371450d0020082802001035200128020021080b200810350b200341106a2103200741706a22070d000b0b200228020c41ffffffff0071450d00200610350b200241d0006a24000bc1ba0102097f017e230041f0006b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490dab0120032005490dac012001280200220620046a2d000021072001410c6a22082005360200200741bf014b0d0120070ec001b402b402020304b402010101010105060708090a0b01010101010101010c0d010101010e0f101112010101131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01b4020b200241013a0048200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1041200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000cb6020b2000410b3a000420004101360200200041056a20073a00000cb5020b024002400240024002400240024020032005460d00200441026a21092005417f460db10120032009490db201200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410221070cb9020b20090e0405040306050b200241013a0047200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1041200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cb8020b4101210a410221070cb4020b4102210a410221070cb3020b4103210a0b410221070cb1020b024002400240024002400240024020032005460d00200441026a21092005417f460db20120032009490db301200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410321070cb8020b20090e0405040306050b200241013a0047200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1041200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cb7020b4101210a410321070cb3020b4102210a410321070cb2020b4103210a0b410321070cb0020b024002400240024002400240024020032005460d00200441026a21092005417f460db30120032009490db401200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410421070cb7020b20090e0405040306050b200241013a0047200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1041200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cb6020b4101210a410421070cb2020b4102210a410421070cb1020b4103210a0b410421070caf020b410621070cae020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460daf012003200541016a2207490df701200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b410721070caf020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000cb0020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460daf012003200541016a2207490df701200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b410821070cae020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000caf020b200241d8006a200110ab07200241d8006a410c6a2802002109200241d8006a41086a2802002107200228025c210420022802584101460daf012002410036026020024204370358200241d8006a4100200941027422034102751086012002280260210602402009450d002003417c6a410276210a200228025820064102746a210920042105034020092005280200360200200941046a2109200541046a21052003417c6a22030d000b2006200a6a41016a21060b200220063602600240200741ffffffff0371450d00200410350b2002280258210a0240200228025c22092006460d0020092006490dad012009450d002009410274220520064102742209460d00024020090d00024020050d004104210a0c020b200a10354104210a0c010b200a200520091037220a450dae010b410021094100210402400240034002402009411f4d0d00410f21010c030b20012802082207200128020c2205460d01200541016a22032005490db10120072003490df701200128020020056a2d0000210520082003360200200541ff00712009411f71742004722104200941076a21092005418001710d000b024020094120490d00410d21012005410f4b0d020b410c10332209450daf0120092004360208200920063602042009200a360200410921070cad020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a280200360200200641ffffffff0371450dae02200a10350cae020b410a21070caa020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db1012003200541016a2207490df601200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b410b21070cab020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000cac020b410021014100210902400240024002400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db4012003200541016a2204490df901200620056a2d0000210720082004360200200741ff00712001411f71742009722109200141076a2101200421052007418001710d000b024020014120490d00410d21012007410f4b0d020b20032004460d03200441016a22012004490db401200320014f0d022001200341c0fdcb001058000b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000cae020b200620046a2d000021052008200136020020050d01410c21074100210a0caa020b200241013a0048200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1041200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000cac020b200041163a000420004101360200200041056a20053a00000cab020b410d21070ca7020b410e21070ca6020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db0012003200541016a2207490df401200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b410f21070ca7020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca8020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db0012003200541016a2207490df401200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b411021070ca6020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca7020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db0012003200541016a2207490df401200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b411121070ca5020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca6020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db0012003200541016a2207490df401200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b411221070ca4020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca5020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db0012003200541016a2207490df401200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b411321070ca3020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca4020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db20120032001490df601200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db3012003200141016a2207490df701200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411421070ca4020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca5020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca3020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db30120032001490df701200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db4012003200141016a2207490df801200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411521070ca3020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca4020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca2020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db40120032001490df801200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db5012003200141016a2207490df901200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411621070ca2020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca3020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca1020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db50120032001490df901200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db6012003200141016a2207490dfa01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411721070ca1020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca2020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca0020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db60120032001490dfa01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db7012003200141016a2207490dfb01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411821070ca0020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca1020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9f020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db70120032001490dfb01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db8012003200141016a2207490dfc01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411921070c9f020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca0020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9e020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db80120032001490dfc01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db9012003200141016a2207490dfd01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411a21070c9e020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000c9f020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9d020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db90120032001490dfd01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dba012003200141016a2207490dfe01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411b21070c9d020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000c9e020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9c020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dba0120032001490dfe01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dbb012003200141016a2207490dff01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411c21070c9c020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000c9d020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9b020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dbb0120032001490dff01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dbc012003200141016a2207490d8002200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411d21070c9b020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000c9c020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9a020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dbc0120032001490d8002200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dbd012003200141016a2207490d8102200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411e21070c9a020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9b020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c99020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dbd0120032001490d8102200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dbe012003200141016a2207490d8202200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411f21070c99020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9a020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c98020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dbe0120032001490d8202200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dbf012003200141016a2207490d8302200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b41202107024020054120490d00410d21012004410f4b0d040b200aad210b0c98020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c99020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c97020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dbf0120032001490d8302200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc0012003200141016a2207490d8402200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412121070c97020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c98020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c96020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc00120032001490d8402200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc1012003200141016a2207490d8502200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412221070c96020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c97020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c95020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc10120032001490d8502200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc2012003200141016a2207490d8602200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412321070c95020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c96020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c94020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc20120032001490d8602200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc3012003200141016a2207490d8702200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412421070c94020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c95020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c93020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc30120032001490d8702200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc4012003200141016a2207490d8802200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412521070c93020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c94020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c92020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc40120032001490d8802200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc5012003200141016a2207490d8902200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412621070c92020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c93020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c91020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc50120032001490d8902200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc6012003200141016a2207490d8a02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412721070c91020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c92020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c90020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc60120032001490d8a02200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc7012003200141016a2207490d8b02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412821070c90020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c91020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c8f020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc70120032001490d8b02200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc8012003200141016a2207490d8c02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412921070c8f020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c90020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c8e020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc80120032001490d8c02200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc9012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412a21070c8e020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c8f020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c8d020b0240024020032005460d00200441026a21012005417f460dc60120032001490dc701200620056a2d000021092008200136020020090d01412b21074100210a0c8b020b200241013a0048200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1041200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c8d020b200041153a000420004101360200200041056a20093a00000c8c020b0240024020032005460d00200441026a21012005417f460dc70120032001490dc801200620056a2d000021092008200136020020090d01412c21074100210a0c8a020b200241013a0048200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1041200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c8c020b200041153a000420004101360200200041056a20093a00000c8b020b4100210141002109024002400340410d210a2001411f4b0d0220032005460d012005417f460dc9012003200541016a2207490d8902200620056a2c0000210420082007360200200441ff00712001411f71742009722109200141076a21012007210520044100480d000b200441c00071210502402001411f4b0d0020050dca010b02400240024020014120490d0020050d010b200441ff01714108490d0120014120490d0120050d010c030b20044180017241ff017141f801490d020b412d21070c89020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a10414105210a0b2000200a36020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c8a020b4200210b4100210102400340410e21072001413f4b0d890220032005460d012005417f460dc9012003200541016a2209490dca01200620056a2d0000210420082009360200200441ff0071220aad2001413f71ad86200b84210b200141076a21012009210520044118744118752209417f4c0d000b200941c0007121050240024002402001413f4b0d0020050d010b02400240200141c000490d0020050d010b200141c000490d022009450d020c8b020b200a41ff00470d8a020c010b200b428080808080808080807f427f2001413f712201ad862001413f461b84210b0b412e21070c87020b200241013a0008200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241086a360238200241286a200241d8006a10412002290328210b20022802302101410521070c88020b0240200320056b4104490d00200441056a21012005417b4b0dc90120032001490dca01200620056a280000210920082001360200412f21070c86020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120004281808080d000370300200041086a2002290328370200200041106a200241286a41086a2802003602000c88020b0240200320056b4108490d00200441096a2101200541774b0dca0120032001490dcb01200620056a290000210b20082001360200413021070c85020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a10412002290328210b200041106a2002280230360200200041086a200b37020020004281808080d0003703000c87020b413121070c83020b413221070c82020b413321070c81020b413421070c80020b413521070cff010b413621070cfe010b413721070cfd010b413821070cfc010b413921070cfb010b413a21070cfa010b413b21070cf9010b413c21070cf8010b413d21070cf7010b413e21070cf6010b413f21070cf5010b41c00021070cf4010b41c10021070cf3010b41c20021070cf2010b41c30021070cf1010b41c40021070cf0010b41c50021070cef010b41c60021070cee010b41c70021070ced010b41c80021070cec010b41c90021070ceb010b41ca0021070cea010b41cb0021070ce9010b41cc0021070ce8010b41cd0021070ce7010b41ce0021070ce6010b41cf0021070ce5010b41d00021070ce4010b41d10021070ce3010b41d20021070ce2010b41d30021070ce1010b41d40021070ce0010b41d50021070cdf010b41d60021070cde010b41d70021070cdd010b41d80021070cdc010b41d90021070cdb010b41da0021070cda010b41db0021070cd9010b41dc0021070cd8010b41dd0021070cd7010b41de0021070cd6010b41df0021070cd5010b41e00021070cd4010b41e10021070cd3010b41e20021070cd2010b41e30021070cd1010b41e40021070cd0010b41e50021070ccf010b41e60021070cce010b41e70021070ccd010b41e80021070ccc010b41e90021070ccb010b41ea0021070cca010b41eb0021070cc9010b41ec0021070cc8010b41ed0021070cc7010b41ee0021070cc6010b41ef0021070cc5010b41f00021070cc4010b41f10021070cc3010b41f20021070cc2010b41f30021070cc1010b41f40021070cc0010b41f50021070cbf010b41f60021070cbe010b41f70021070cbd010b41f80021070cbc010b41f90021070cbb010b41fa0021070cba010b41fb0021070cb9010b41fc0021070cb8010b41fd0021070cb7010b41fe0021070cb6010b41ff0021070cb5010b41800121070cb4010b41810121070cb3010b41820121070cb2010b41830121070cb1010b41840121070cb0010b41850121070caf010b41860121070cae010b41870121070cad010b41880121070cac010b41890121070cab010b418a0121070caa010b418b0121070ca9010b418c0121070ca8010b418d0121070ca7010b418e0121070ca6010b418f0121070ca5010b41900121070ca4010b41910121070ca3010b41920121070ca2010b41930121070ca1010b41940121070ca0010b41950121070c9f010b41960121070c9e010b41970121070c9d010b41980121070c9c010b41990121070c9b010b419a0121070c9a010b419b0121070c99010b419c0121070c98010b419d0121070c97010b419e0121070c96010b419f0121070c95010b41a00121070c94010b41a10121070c93010b41a20121070c92010b41a30121070c91010b41a40121070c90010b41a50121070c8f010b41a60121070c8e010b41a70121070c8d010b41a80121070c8c010b41a90121070c8b010b41aa0121070c8a010b41ab0121070c89010b417f200541c0fdcb001059000b2005200341c0fdcb001058000b417f200941c0fdcb001059000b2009200341c0fdcb001058000b417f200941c0fdcb001059000b2009200341c0fdcb001058000b417f200941c0fdcb001059000b2009200341c0fdcb001058000b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b41ec80cc00412441c086cc00103f000b103c000b417f200341c0fdcb001059000b200241d8006a41106a28020021012000200436020420004101360200200041106a20013602002000410c6a2009360200200041086a20073602000c7e0b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b2001200341c0fdcb001058000b417f200141c0fdcb001059000b2001200341c0fdcb001058000b417f200541016a41c0fdcb001059000b2009417f2001411f7174722109412d21070c3f0b417f200541016a41c0fdcb001059000b200541016a200341c0fdcb001058000b2005200141c0fdcb001059000b2001200341c0fdcb001058000b2005200141c0fdcb001059000b2001200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b2003200741c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b20004100360200200041106a200b3703002000410c6a2009360200200041096a200a3a0000200041086a20073a00000c020b0b200020073a0004200020022f00183b000520004101360200200041106a2001360200200041086a200b370200200041076a2002411a6a2d00003a00000b200241f0006a24000bbb0101027f0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1b220241ffffffff00712002470d00200241047422024100480d00024020010d0020020d02410821030c040b20002802002103200141047422012002460d03024020010d0020020d02410821030c040b20032001200210372203450d020c030b103e000b2002103322030d010b103c000b20002003360200200041046a20024104763602000b0bd30101017f230041106b22022400024002400240024020002d00000e03010200010b2002200128021841a9fecb00410b2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c020b2002200128021841b4fecb00410c2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b2002200128021841c0fecb00410d2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040b200241106a240020000bff06020c7f017e230041e0006b220224004100210341002104024002400240024002400240034002402003411f4d0d00410f21030c060b20012802082205200128020c2206460d04200641016a22072006490d0120052007490d03200128020020066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b024020034120490d00410d21032006410f4b0d050b410021082002410036021020024204370308024002402004450d00410421094100210a0340200a41016a210a4100210341002105024003404101210b02402003411f4d0d00410f21030c020b024002402001280208220c200128020c2206460d00200641016a22072006490d08200c20074f0d012007200c41c0fdcb001058000b4101210b200241013a00472002410136025c2002420137024c200241acfdcb003602482002413636023c2002200241386a3602582002200241c7006a360238200241286a200241c8006a10414100210d410521030c020b200128020020066a2d000021062001200736020c200641ff00712003411f71742005722105200341076a21032006418001710d000b024020034120490d00410d21032006410f4b0d010b2005410876210d4100210b200521030b200241186a41086a200241286a41086a28020036020020022002290328370318200d410874200341ff0171722103200b0d0202402008200228020c470d00200241086a2008410110860120022802082109200228021021080b200920084102746a20033602002002200841016a2208360210200a2004470d000b0b20002002290308370204200041003602002000410c6a200241106a2802003602000c060b2000200336020420004101360200200041086a2002290318370200200041106a200241186a41086a280200360200200228020c41ffffffff0371450d05200910350c050b417f200741c0fdcb001059000b417f200741c0fdcb001059000b2007200541c0fdcb001058000b200241013a0008200241dc006a41013602002002420137024c200241acfdcb003602482002413636023c2002200241386a3602582002200241086a360238200241286a200241c8006a1041410521030b200241186a41086a200241286a41086a280200220136020020022002290328220e37031820002003360204200041086a200e370200200041106a2001360200200041013602000b200241e0006a24000b9bee0202097f017e230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad01200441017422062005200620054b1b22064100480dad010240024020040d00024020060d00410121050c020b2006103322050d010cb9010b2002280204210520042006460d0020052004200610372205450db8010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41003a00002002410c6a200441016a3602000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac01200441017422062005200620054b1b22064100480dac010240024020040d00024020060d00410121050c020b200610332205450db8010c010b2002280204210520042006460d0020052004200610372205450db7010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41013a00002002410c6a200441016a3602000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490dab01200441017422082005200820054b1b22084100480dab010240024020040d00024020080d00410121050c020b200810332205450db7010c010b2006280200210520042008460d0020052004200810372205450db6010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41023a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490dab01200441017422082005200820054b1b22084100480dab010240024020040d00024020080d00410121050c020b200810332205450db7010c010b2006280200210520042008460d0020052004200810372205450db6010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490daa01200441017422082005200820054b1b22084100480daa010240024020040d00024020080d00410121050c020b200810332205450db6010c010b2006280200210520042008460d0020052004200810372205450db5010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41033a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490daa01200441017422082005200820054b1b22084100480daa010240024020040d00024020080d00410121050c020b200810332205450db6010c010b2006280200210520042008460d0020052004200810372205450db5010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490da901200441017422082005200820054b1b22084100480da9010240024020040d00024020080d00410121050c020b200810332205450db5010c010b2006280200210520042008460d0020052004200810372205450db4010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41043a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490da901200441017422082005200820054b1b22084100480da9010240024020040d00024020080d00410121050c020b200810332205450db5010c010b2006280200210520042008460d0020052004200810372205450db4010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da801200441017422062005200620054b1b22064100480da8010240024020040d00024020060d00410121050c020b200610332205450db4010c010b2002280204210520042006460d0020052004200610372205450db3010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41053a00002002410c6a200441016a3602000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da701200441017422062005200620054b1b22064100480da7010240024020040d00024020060d00410121050c020b200610332205450db3010c010b2002280204210520042006460d0020052004200610372205450db2010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410b3a00002002410c6a200441016a3602000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da601200441017422072006200720064b1b22074100480da6010240024020040d00024020070d00410121060c020b200710332206450db2010c010b2009280200210620042007460d0020062004200710372206450db1010b20022006360204200241086a20073602002002410c6a28020021040b200620046a410c3a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da701200441017422072006200720064b1b22074100480da7010240024020040d00024020070d00410121060c020b200710332206450db3010c010b2009280200210620042007460d0020062004200710372206450db2010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da501200441017422072006200720064b1b22074100480da5010240024020040d00024020070d00410121060c020b200710332206450db1010c010b2009280200210620042007460d0020062004200710372206450db0010b20022006360204200241086a20073602002002410c6a28020021040b200620046a410d3a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da601200441017422072006200720064b1b22074100480da6010240024020040d00024020070d00410121060c020b200710332206450db2010c010b2009280200210620042007460d0020062004200710372206450db1010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca4010b0b200241046a210902400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490da401200441017422062005200620054b1b22064100480da4010240024020040d00024020060d00410121050c020b200610332205450db0010c010b2009280200210520042006460d0020052004200610372205450daf010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410e3a00002002410c6a2208200441016a360200200320012802042204280204220520042802002204200420054102746a200210a4072003210420032d0000411f470dab012008280200210420012802042802082105200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da501200441017422072006200720064b1b22074100480da5010240024020040d00024020070d00410121060c020b200710332206450db1010c010b2009280200210620042007460d0020062004200710372206450db0010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca3010b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da301200441017422062005200620054b1b22064100480da3010240024020040d00024020060d00410121050c020b200610332205450daf010c010b2002280204210520042006460d0020052004200610372205450dae010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410f3a00002002410c6a200441016a3602000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da201200441017422072006200720064b1b22074100480da2010240024020040d00024020070d00410121060c020b200710332206450dae010c010b2009280200210620042007460d0020062004200710372206450dad010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41103a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da301200441017422072006200720064b1b22074100480da3010240024020040d00024020070d00410121060c020b200710332206450daf010c010b2009280200210620042007460d0020062004200710372206450dae010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da101200441017422072006200720064b1b22074100480da1010240024020040d00024020070d00410121060c020b200710332206450dad010c010b2009280200210620042007460d0020062004200710372206450dac010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41113a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da201200441017422072006200720064b1b22074100480da2010240024020040d00024020070d00410121060c020b200710332206450dae010c010b2009280200210620042007460d0020062004200710372206450dad010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000b02400240200241086a2802002004460d00200928020021050c010b200441016a22052004490da101200441017422062005200620054b1b22064100480da1010240024020040d00024020060d00410121050c020b200610332205450dad010c010b2009280200210520042006460d0020052004200610372205450dac010b20022005360204200241086a20063602002002410c6a28020021040b200520046a200b3a00002002410c6a200441016a3602000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da001200441017422062005200620054b1b22064100480da0010240024020040d00024020060d00410121050c020b200610332205450dac010c010b2002280204210520042006460d0020052004200610372205450dab010b20022005360204200241086a20063602002002410c6a28020021040b200520046a411a3a00002002410c6a200441016a3602000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f01200441017422062005200620054b1b22064100480d9f010240024020040d00024020060d00410121050c020b200610332205450dab010c010b2002280204210520042006460d0020052004200610372205450daa010b20022005360204200241086a20063602002002410c6a28020021040b200520046a411b3a00002002410c6a200441016a3602000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9e01200441017422072006200720064b1b22074100480d9e010240024020040d00024020070d00410121060c020b200710332206450daa010c010b2009280200210620042007460d0020062004200710372206450da9010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41203a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9f01200441017422072006200720064b1b22074100480d9f010240024020040d00024020070d00410121060c020b200710332206450dab010c010b2009280200210620042007460d0020062004200710372206450daa010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9d01200441017422072006200720064b1b22074100480d9d010240024020040d00024020070d00410121060c020b200710332206450da9010c010b2009280200210620042007460d0020062004200710372206450da8010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41213a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9e01200441017422072006200720064b1b22074100480d9e010240024020040d00024020070d00410121060c020b200710332206450daa010c010b2009280200210620042007460d0020062004200710372206450da9010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9c01200441017422072006200720064b1b22074100480d9c010240024020040d00024020070d00410121060c020b200710332206450da8010c010b2009280200210620042007460d0020062004200710372206450da7010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41223a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9d01200441017422072006200720064b1b22074100480d9d010240024020040d00024020070d00410121060c020b200710332206450da9010c010b2009280200210620042007460d0020062004200710372206450da8010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9b01200441017422072006200720064b1b22074100480d9b010240024020040d00024020070d00410121060c020b200710332206450da7010c010b2009280200210620042007460d0020062004200710372206450da6010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41233a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9c01200441017422072006200720064b1b22074100480d9c010240024020040d00024020070d00410121060c020b200710332206450da8010c010b2009280200210620042007460d0020062004200710372206450da7010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9a01200441017422072006200720064b1b22074100480d9a010240024020040d00024020070d00410121060c020b200710332206450da6010c010b2009280200210620042007460d0020062004200710372206450da5010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41243a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9b01200441017422072006200720064b1b22074100480d9b010240024020040d00024020070d00410121060c020b200710332206450da7010c010b2009280200210620042007460d0020062004200710372206450da6010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c99010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9901200441017422082007200820074b1b22084100480d99010240024020040d00024020080d00410121070c020b200810332207450da5010c010b200a280200210720042008460d0020072004200810372207450da4010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41283a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9a01200441017422082007200820074b1b22084100480d9a010240024020040d00024020080d00410121070c020b200810332207450da6010c010b200a280200210720042008460d0020072004200810372207450da5010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9a01200441017422072005200720054b1b22074100480d9a010240024020040d00024020070d00410121050c020b200710332205450da6010c010b200a280200210520042007460d0020052004200710372205450da5010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9801200441017422082007200820074b1b22084100480d98010240024020040d00024020080d00410121070c020b200810332207450da4010c010b200a280200210720042008460d0020072004200810372207450da3010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41293a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9901200441017422082007200820074b1b22084100480d99010240024020040d00024020080d00410121070c020b200810332207450da5010c010b200a280200210720042008460d0020072004200810372207450da4010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9901200441017422072006200720064b1b22074100480d99010240024020040d00024020070d00410121060c020b200710332206450da5010c010b200a280200210620042007460d0020062004200710372206450da4010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9701200441017422082007200820074b1b22084100480d97010240024020040d00024020080d00410121070c020b200810332207450da3010c010b200a280200210720042008460d0020072004200810372207450da2010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412a3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9801200441017422082007200820074b1b22084100480d98010240024020040d00024020080d00410121070c020b200810332207450da4010c010b200a280200210720042008460d0020072004200810372207450da3010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9801200441017422072006200720064b1b22074100480d98010240024020040d00024020070d00410121060c020b200710332206450da4010c010b200a280200210620042007460d0020062004200710372206450da3010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c96010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b200810332207450da2010c010b200a280200210720042008460d0020072004200810372207450da1010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412b3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9701200441017422082007200820074b1b22084100480d97010240024020040d00024020080d00410121070c020b200810332207450da3010c010b200a280200210720042008460d0020072004200810372207450da2010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9701200441017422072005200720054b1b22074100480d97010240024020040d00024020070d00410121050c020b200710332205450da3010c010b200a280200210520042007460d0020052004200710372205450da2010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b200810332207450da1010c010b200a280200210720042008460d0020072004200810372207450da0010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412c3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b200810332207450da2010c010b200a280200210720042008460d0020072004200810372207450da1010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9601200441017422072006200720064b1b22074100480d96010240024020040d00024020070d00410121060c020b200710332206450da2010c010b200a280200210620042007460d0020062004200710372206450da1010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b200810332207450da0010c010b200a280200210720042008460d0020072004200810372207450d9f010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412d3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b2008103322070d010c9e010b200a280200210720042008460d0020072004200810372207450d9c010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9601200441017422072006200720064b1b22074100480d96010240024020040d00024020070d00410121060c020b2007103322060d010c9e010b200a280200210620042007460d0020062004200710372206450d9c010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9401200441017422082007200820074b1b22084100480d94010240024020040d00024020080d00410121070c020b2008103322070d010c9c010b200a280200210720042008460d0020072004200810372207450d9a010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412e3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b2008103322070d010c9d010b200a280200210720042008460d0020072004200810372207450d9b010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9501200441017422072006200720064b1b22074100480d95010240024020040d00024020070d00410121060c020b2007103322060d010c9d010b200a280200210620042007460d0020062004200710372206450d9b010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9301200441017422082007200820074b1b22084100480d93010240024020040d00024020080d00410121070c020b2008103322070d010c9b010b200a280200210720042008460d0020072004200810372207450d99010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412f3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9401200441017422082007200820074b1b22084100480d94010240024020040d00024020080d00410121070c020b2008103322070d010c9c010b200a280200210720042008460d0020072004200810372207450d9a010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9401200441017422072006200720064b1b22074100480d94010240024020040d00024020070d00410121060c020b2007103322060d010c9c010b200a280200210620042007460d0020062004200710372206450d9a010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c91010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9201200441017422082007200820074b1b22084100480d92010240024020040d00024020080d00410121070c020b2008103322070d010c9a010b200a280200210720042008460d0020072004200810372207450d98010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41303a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9301200441017422082007200820074b1b22084100480d93010240024020040d00024020080d00410121070c020b2008103322070d010c9b010b200a280200210720042008460d0020072004200810372207450d99010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9301200441017422072005200720054b1b22074100480d93010240024020040d00024020070d00410121050c020b2007103322050d010c9b010b200a280200210520042007460d0020052004200710372205450d99010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9101200441017422082007200820074b1b22084100480d91010240024020040d00024020080d00410121070c020b2008103322070d010c99010b200a280200210720042008460d0020072004200810372207450d97010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41313a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9201200441017422082007200820074b1b22084100480d92010240024020040d00024020080d00410121070c020b2008103322070d010c9a010b200a280200210720042008460d0020072004200810372207450d98010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9201200441017422072006200720064b1b22074100480d92010240024020040d00024020070d00410121060c020b2007103322060d010c9a010b200a280200210620042007460d0020062004200710372206450d98010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9001200441017422082007200820074b1b22084100480d90010240024020040d00024020080d00410121070c020b2008103322070d010c98010b200a280200210720042008460d0020072004200810372207450d96010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41323a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9101200441017422082007200820074b1b22084100480d91010240024020040d00024020080d00410121070c020b2008103322070d010c99010b200a280200210720042008460d0020072004200810372207450d97010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9101200441017422072006200720064b1b22074100480d91010240024020040d00024020070d00410121060c020b2007103322060d010c99010b200a280200210620042007460d0020062004200710372206450d97010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8f01200441017422082007200820074b1b22084100480d8f010240024020040d00024020080d00410121070c020b2008103322070d010c97010b200a280200210720042008460d0020072004200810372207450d95010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41333a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9001200441017422082007200820074b1b22084100480d90010240024020040d00024020080d00410121070c020b2008103322070d010c98010b200a280200210720042008460d0020072004200810372207450d96010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9001200441017422072006200720064b1b22074100480d90010240024020040d00024020070d00410121060c020b2007103322060d010c98010b200a280200210620042007460d0020062004200710372206450d96010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8d010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8e01200441017422082007200820074b1b22084100480d8e010240024020040d00024020080d00410121070c020b2008103322070d010c96010b200a280200210720042008460d0020072004200810372207450d94010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41343a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8f01200441017422082007200820074b1b22084100480d8f010240024020040d00024020080d00410121070c020b2008103322070d010c97010b200a280200210720042008460d0020072004200810372207450d95010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8f01200441017422072005200720054b1b22074100480d8f010240024020040d00024020070d00410121050c020b2007103322050d010c97010b200a280200210520042007460d0020052004200710372205450d95010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8d01200441017422082007200820074b1b22084100480d8d010240024020040d00024020080d00410121070c020b2008103322070d010c95010b200a280200210720042008460d0020072004200810372207450d93010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41353a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8e01200441017422082007200820074b1b22084100480d8e010240024020040d00024020080d00410121070c020b2008103322070d010c96010b200a280200210720042008460d0020072004200810372207450d94010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8e01200441017422072006200720064b1b22074100480d8e010240024020040d00024020070d00410121060c020b2007103322060d010c96010b200a280200210620042007460d0020062004200710372206450d94010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8b010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8c01200441017422082007200820074b1b22084100480d8c010240024020040d00024020080d00410121070c020b2008103322070d010c94010b200a280200210720042008460d0020072004200810372207450d92010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41363a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8d01200441017422082007200820074b1b22084100480d8d010240024020040d00024020080d00410121070c020b2008103322070d010c95010b200a280200210720042008460d0020072004200810372207450d93010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8d01200441017422072005200720054b1b22074100480d8d010240024020040d00024020070d00410121050c020b2007103322050d010c95010b200a280200210520042007460d0020052004200710372205450d93010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8b01200441017422082007200820074b1b22084100480d8b010240024020040d00024020080d00410121070c020b2008103322070d010c93010b200a280200210720042008460d0020072004200810372207450d91010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41373a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8c01200441017422082007200820074b1b22084100480d8c010240024020040d00024020080d00410121070c020b2008103322070d010c94010b200a280200210720042008460d0020072004200810372207450d92010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8c01200441017422072006200720064b1b22074100480d8c010240024020040d00024020070d00410121060c020b2007103322060d010c94010b200a280200210620042007460d0020062004200710372206450d92010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c89010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8a01200441017422082007200820074b1b22084100480d8a010240024020040d00024020080d00410121070c020b2008103322070d010c92010b200a280200210720042008460d0020072004200810372207450d90010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41383a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8b01200441017422082007200820074b1b22084100480d8b010240024020040d00024020080d00410121070c020b2008103322070d010c93010b200a280200210720042008460d0020072004200810372207450d91010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8b01200441017422072005200720054b1b22074100480d8b010240024020040d00024020070d00410121050c020b2007103322050d010c93010b200a280200210520042007460d0020052004200710372205450d91010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8901200441017422082007200820074b1b22084100480d89010240024020040d00024020080d00410121070c020b2008103322070d010c91010b200a280200210720042008460d0020072004200810372207450d8f010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41393a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8a01200441017422082007200820074b1b22084100480d8a010240024020040d00024020080d00410121070c020b2008103322070d010c92010b200a280200210720042008460d0020072004200810372207450d90010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8a01200441017422072006200720064b1b22074100480d8a010240024020040d00024020070d00410121060c020b2007103322060d010c92010b200a280200210620042007460d0020062004200710372206450d90010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8801200441017422082007200820074b1b22084100480d88010240024020040d00024020080d00410121070c020b2008103322070d010c90010b200a280200210720042008460d0020072004200810372207450d8e010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413a3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8901200441017422082007200820074b1b22084100480d89010240024020040d00024020080d00410121070c020b2008103322070d010c91010b200a280200210720042008460d0020072004200810372207450d8f010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8901200441017422072006200720064b1b22074100480d89010240024020040d00024020070d00410121060c020b2007103322060d010c91010b200a280200210620042007460d0020062004200710372206450d8f010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8701200441017422082007200820074b1b22084100480d87010240024020040d00024020080d00410121070c020b2008103322070d010c8f010b200a280200210720042008460d0020072004200810372207450d8d010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413b3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8801200441017422082007200820074b1b22084100480d88010240024020040d00024020080d00410121070c020b2008103322070d010c90010b200a280200210720042008460d0020072004200810372207450d8e010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8801200441017422072006200720064b1b22074100480d88010240024020040d00024020070d00410121060c020b2007103322060d010c90010b200a280200210620042007460d0020062004200710372206450d8e010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c85010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8601200441017422082007200820074b1b22084100480d86010240024020040d00024020080d00410121070c020b2008103322070d010c8e010b200a280200210720042008460d0020072004200810372207450d8c010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413c3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8701200441017422082007200820074b1b22084100480d87010240024020040d00024020080d00410121070c020b2008103322070d010c8f010b200a280200210720042008460d0020072004200810372207450d8d010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8701200441017422072006200720064b1b22074100480d87010240024020040d00024020070d00410121060c020b2007103322060d010c8f010b200a280200210620042007460d0020062004200710372206450d8d010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c84010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8501200441017422082007200820074b1b22084100480d85010240024020040d00024020080d00410121070c020b2008103322070d010c8d010b200a280200210720042008460d0020072004200810372207450d8b010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413d3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8601200441017422082007200820074b1b22084100480d86010240024020040d00024020080d00410121070c020b2008103322070d010c8e010b200a280200210720042008460d0020072004200810372207450d8c010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8601200441017422072005200720054b1b22074100480d86010240024020040d00024020070d00410121050c020b2007103322050d010c8e010b200a280200210520042007460d0020052004200710372205450d8c010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c83010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8401200441017422082007200820074b1b22084100480d84010240024020040d00024020080d00410121070c020b2008103322070d010c8c010b200a280200210720042008460d0020072004200810372207450d8a010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413e3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8501200441017422082007200820074b1b22084100480d85010240024020040d00024020080d00410121070c020b2008103322070d010c8d010b200a280200210720042008460d0020072004200810372207450d8b010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8501200441017422072005200720054b1b22074100480d85010240024020040d00024020070d00410121050c020b2007103322050d010c8d010b200a280200210520042007460d0020052004200710372205450d8b010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8b010b2006280200210520042008460d0020052004200810372205450d89010b20022005360204200241086a20083602002002410c6a28020021040b200520046a413f3a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8b010b2006280200210520042008460d0020052004200810372205450d89010b20022005360204200241086a20083602002002410c6a28020021040b200520046a20073a00002002410c6a200441016a3602000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8201200441017422082005200820054b1b22084100480d82010240024020040d00024020080d00410121050c020b2008103322050d010c8a010b2006280200210520042008460d0020052004200810372205450d88010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41c0003a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8a010b2006280200210520042008460d0020052004200810372205450d88010b20022005360204200241086a20083602002002410c6a28020021040b200520046a20073a00002002410c6a200441016a3602000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8201200441017422072005200720054b1b22074100480d82010240024020040d00024020070d00410121050c020b2007103322050d010c89010b2002280204210520042007460d0020052004200710372205450d84010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c1003a00002002410c6a200441016a36020020032006200210a5072003210420032d0000411f470d87010c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8101200441017422062005200620054b1b22064100480d81010240024020040d00024020060d00410121050c020b2006103322050d010c88010b2002280204210520042006460d0020052004200610372205450d83010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c2003a00002002410c6a200441016a3602002003200c200210a6072003210420032d0000411f470d86010c7d0b200241046a2106200141046a280200210802400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8001200441017422072005200720054b1b22074100480d80010240024020040d00024020070d00410121050c020b2007103322050d010c87010b2006280200210520042007460d0020052004200710372205450d82010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c3003a00002002410c6a200441016a220436020002400240200241086a280200220720046b4104490d00200628020021050c010b200441046a22052004490d8001200741017422042005200420054b1b22044100480d80010240024020070d00024020040d00410121050c020b2004103322050d010c87010b2006280200210520072004460d0020052007200410372205450d82010b20022005360204200241086a20043602002002410c6a28020021040b200520046a20083600002002410c6a200441046a3602000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d7f200441017422072005200720054b1b22074100480d7f0240024020040d00024020070d00410121050c020b2007103322050d010c86010b2006280200210520042007460d0020052004200710372205450d81010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c4003a00002002410c6a200441016a220436020002400240200241086a280200220720046b4108490d00200628020021050c010b200441086a22052004490d7f200741017422042005200420054b1b22044100480d7f0240024020070d00024020040d00410121050c020b2004103322050d010c86010b2006280200210520072004460d0020052007200410372205450d81010b20022005360204200241086a20043602002002410c6a28020021040b200520046a200c3700002002410c6a200441086a3602000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7e200441017422062005200620054b1b22064100480d7e0240024020040d00024020060d00410121050c020b2006103322050d010c85010b2002280204210520042006460d0020052004200610372205450d80010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c5003a00002002410c6a200441016a3602000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7d200441017422062005200620054b1b22064100480d7d0240024020040d00024020060d00410121050c020b2006103322050d010c84010b2002280204210520042006460d0020052004200610372205450d7f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c6003a00002002410c6a200441016a3602000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7c200441017422062005200620054b1b22064100480d7c0240024020040d00024020060d00410121050c020b2006103322050d010c83010b2002280204210520042006460d0020052004200610372205450d7e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c7003a00002002410c6a200441016a3602000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7b200441017422062005200620054b1b22064100480d7b0240024020040d00024020060d00410121050c020b2006103322050d010c82010b2002280204210520042006460d0020052004200610372205450d7d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c8003a00002002410c6a200441016a3602000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7a200441017422062005200620054b1b22064100480d7a0240024020040d00024020060d00410121050c020b2006103322050d010c81010b2002280204210520042006460d0020052004200610372205450d7c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c9003a00002002410c6a200441016a3602000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d79200441017422062005200620054b1b22064100480d790240024020040d00024020060d00410121050c020b2006103322050d010c80010b2002280204210520042006460d0020052004200610372205450d7b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ca003a00002002410c6a200441016a3602000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d78200441017422062005200620054b1b22064100480d780240024020040d00024020060d00410121050c020b2006103322050d010c7f0b2002280204210520042006460d0020052004200610372205450d7a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cb003a00002002410c6a200441016a3602000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d77200441017422062005200620054b1b22064100480d770240024020040d00024020060d00410121050c020b2006103322050d010c7e0b2002280204210520042006460d0020052004200610372205450d790b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cc003a00002002410c6a200441016a3602000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d76200441017422062005200620054b1b22064100480d760240024020040d00024020060d00410121050c020b2006103322050d010c7d0b2002280204210520042006460d0020052004200610372205450d780b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cd003a00002002410c6a200441016a3602000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d75200441017422062005200620054b1b22064100480d750240024020040d00024020060d00410121050c020b2006103322050d010c7c0b2002280204210520042006460d0020052004200610372205450d770b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ce003a00002002410c6a200441016a3602000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d74200441017422062005200620054b1b22064100480d740240024020040d00024020060d00410121050c020b2006103322050d010c7b0b2002280204210520042006460d0020052004200610372205450d760b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cf003a00002002410c6a200441016a3602000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d73200441017422062005200620054b1b22064100480d730240024020040d00024020060d00410121050c020b2006103322050d010c7a0b2002280204210520042006460d0020052004200610372205450d750b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d0003a00002002410c6a200441016a3602000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d72200441017422062005200620054b1b22064100480d720240024020040d00024020060d00410121050c020b2006103322050d010c790b2002280204210520042006460d0020052004200610372205450d740b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d1003a00002002410c6a200441016a3602000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d71200441017422062005200620054b1b22064100480d710240024020040d00024020060d00410121050c020b2006103322050d010c780b2002280204210520042006460d0020052004200610372205450d730b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d2003a00002002410c6a200441016a3602000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d70200441017422062005200620054b1b22064100480d700240024020040d00024020060d00410121050c020b2006103322050d010c770b2002280204210520042006460d0020052004200610372205450d720b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d3003a00002002410c6a200441016a3602000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6f200441017422062005200620054b1b22064100480d6f0240024020040d00024020060d00410121050c020b2006103322050d010c760b2002280204210520042006460d0020052004200610372205450d710b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d4003a00002002410c6a200441016a3602000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6e200441017422062005200620054b1b22064100480d6e0240024020040d00024020060d00410121050c020b2006103322050d010c750b2002280204210520042006460d0020052004200610372205450d700b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d5003a00002002410c6a200441016a3602000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6d200441017422062005200620054b1b22064100480d6d0240024020040d00024020060d00410121050c020b2006103322050d010c740b2002280204210520042006460d0020052004200610372205450d6f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d6003a00002002410c6a200441016a3602000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6c200441017422062005200620054b1b22064100480d6c0240024020040d00024020060d00410121050c020b2006103322050d010c730b2002280204210520042006460d0020052004200610372205450d6e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d7003a00002002410c6a200441016a3602000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6b200441017422062005200620054b1b22064100480d6b0240024020040d00024020060d00410121050c020b2006103322050d010c720b2002280204210520042006460d0020052004200610372205450d6d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d8003a00002002410c6a200441016a3602000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6a200441017422062005200620054b1b22064100480d6a0240024020040d00024020060d00410121050c020b2006103322050d010c710b2002280204210520042006460d0020052004200610372205450d6c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d9003a00002002410c6a200441016a3602000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d69200441017422062005200620054b1b22064100480d690240024020040d00024020060d00410121050c020b2006103322050d010c700b2002280204210520042006460d0020052004200610372205450d6b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41da003a00002002410c6a200441016a3602000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d68200441017422062005200620054b1b22064100480d680240024020040d00024020060d00410121050c020b2006103322050d010c6f0b2002280204210520042006460d0020052004200610372205450d6a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41db003a00002002410c6a200441016a3602000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d67200441017422062005200620054b1b22064100480d670240024020040d00024020060d00410121050c020b2006103322050d010c6e0b2002280204210520042006460d0020052004200610372205450d690b20022005360204200241086a20063602002002410c6a28020021040b200520046a41dc003a00002002410c6a200441016a3602000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d66200441017422062005200620054b1b22064100480d660240024020040d00024020060d00410121050c020b2006103322050d010c6d0b2002280204210520042006460d0020052004200610372205450d680b20022005360204200241086a20063602002002410c6a28020021040b200520046a41dd003a00002002410c6a200441016a3602000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d65200441017422062005200620054b1b22064100480d650240024020040d00024020060d00410121050c020b2006103322050d010c6c0b2002280204210520042006460d0020052004200610372205450d670b20022005360204200241086a20063602002002410c6a28020021040b200520046a41de003a00002002410c6a200441016a3602000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d64200441017422062005200620054b1b22064100480d640240024020040d00024020060d00410121050c020b2006103322050d010c6b0b2002280204210520042006460d0020052004200610372205450d660b20022005360204200241086a20063602002002410c6a28020021040b200520046a41df003a00002002410c6a200441016a3602000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d63200441017422062005200620054b1b22064100480d630240024020040d00024020060d00410121050c020b2006103322050d010c6a0b2002280204210520042006460d0020052004200610372205450d650b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e0003a00002002410c6a200441016a3602000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d62200441017422062005200620054b1b22064100480d620240024020040d00024020060d00410121050c020b2006103322050d010c690b2002280204210520042006460d0020052004200610372205450d640b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e1003a00002002410c6a200441016a3602000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d61200441017422062005200620054b1b22064100480d610240024020040d00024020060d00410121050c020b2006103322050d010c680b2002280204210520042006460d0020052004200610372205450d630b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e2003a00002002410c6a200441016a3602000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d60200441017422062005200620054b1b22064100480d600240024020040d00024020060d00410121050c020b2006103322050d010c670b2002280204210520042006460d0020052004200610372205450d620b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e3003a00002002410c6a200441016a3602000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5f200441017422062005200620054b1b22064100480d5f0240024020040d00024020060d00410121050c020b2006103322050d010c660b2002280204210520042006460d0020052004200610372205450d610b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e4003a00002002410c6a200441016a3602000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5e200441017422062005200620054b1b22064100480d5e0240024020040d00024020060d00410121050c020b2006103322050d010c650b2002280204210520042006460d0020052004200610372205450d600b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e5003a00002002410c6a200441016a3602000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5d200441017422062005200620054b1b22064100480d5d0240024020040d00024020060d00410121050c020b2006103322050d010c640b2002280204210520042006460d0020052004200610372205450d5f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e6003a00002002410c6a200441016a3602000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5c200441017422062005200620054b1b22064100480d5c0240024020040d00024020060d00410121050c020b2006103322050d010c630b2002280204210520042006460d0020052004200610372205450d5e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e7003a00002002410c6a200441016a3602000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5b200441017422062005200620054b1b22064100480d5b0240024020040d00024020060d00410121050c020b2006103322050d010c620b2002280204210520042006460d0020052004200610372205450d5d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e8003a00002002410c6a200441016a3602000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5a200441017422062005200620054b1b22064100480d5a0240024020040d00024020060d00410121050c020b2006103322050d010c610b2002280204210520042006460d0020052004200610372205450d5c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e9003a00002002410c6a200441016a3602000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d59200441017422062005200620054b1b22064100480d590240024020040d00024020060d00410121050c020b2006103322050d010c600b2002280204210520042006460d0020052004200610372205450d5b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ea003a00002002410c6a200441016a3602000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d58200441017422062005200620054b1b22064100480d580240024020040d00024020060d00410121050c020b2006103322050d010c5f0b2002280204210520042006460d0020052004200610372205450d5a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41eb003a00002002410c6a200441016a3602000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d57200441017422062005200620054b1b22064100480d570240024020040d00024020060d00410121050c020b2006103322050d010c5e0b2002280204210520042006460d0020052004200610372205450d590b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ec003a00002002410c6a200441016a3602000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d56200441017422062005200620054b1b22064100480d560240024020040d00024020060d00410121050c020b2006103322050d010c5d0b2002280204210520042006460d0020052004200610372205450d580b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ed003a00002002410c6a200441016a3602000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d55200441017422062005200620054b1b22064100480d550240024020040d00024020060d00410121050c020b2006103322050d010c5c0b2002280204210520042006460d0020052004200610372205450d570b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ee003a00002002410c6a200441016a3602000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d54200441017422062005200620054b1b22064100480d540240024020040d00024020060d00410121050c020b2006103322050d010c5b0b2002280204210520042006460d0020052004200610372205450d560b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ef003a00002002410c6a200441016a3602000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d53200441017422062005200620054b1b22064100480d530240024020040d00024020060d00410121050c020b2006103322050d010c5a0b2002280204210520042006460d0020052004200610372205450d550b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f0003a00002002410c6a200441016a3602000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d52200441017422062005200620054b1b22064100480d520240024020040d00024020060d00410121050c020b2006103322050d010c590b2002280204210520042006460d0020052004200610372205450d540b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f1003a00002002410c6a200441016a3602000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d51200441017422062005200620054b1b22064100480d510240024020040d00024020060d00410121050c020b2006103322050d010c580b2002280204210520042006460d0020052004200610372205450d530b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f2003a00002002410c6a200441016a3602000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d50200441017422062005200620054b1b22064100480d500240024020040d00024020060d00410121050c020b2006103322050d010c570b2002280204210520042006460d0020052004200610372205450d520b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f3003a00002002410c6a200441016a3602000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4f200441017422062005200620054b1b22064100480d4f0240024020040d00024020060d00410121050c020b2006103322050d010c560b2002280204210520042006460d0020052004200610372205450d510b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f4003a00002002410c6a200441016a3602000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4e200441017422062005200620054b1b22064100480d4e0240024020040d00024020060d00410121050c020b2006103322050d010c550b2002280204210520042006460d0020052004200610372205450d500b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f5003a00002002410c6a200441016a3602000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4d200441017422062005200620054b1b22064100480d4d0240024020040d00024020060d00410121050c020b2006103322050d010c540b2002280204210520042006460d0020052004200610372205450d4f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f6003a00002002410c6a200441016a3602000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4c200441017422062005200620054b1b22064100480d4c0240024020040d00024020060d00410121050c020b2006103322050d010c530b2002280204210520042006460d0020052004200610372205450d4e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f7003a00002002410c6a200441016a3602000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4b200441017422062005200620054b1b22064100480d4b0240024020040d00024020060d00410121050c020b2006103322050d010c520b2002280204210520042006460d0020052004200610372205450d4d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f8003a00002002410c6a200441016a3602000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4a200441017422062005200620054b1b22064100480d4a0240024020040d00024020060d00410121050c020b2006103322050d010c510b2002280204210520042006460d0020052004200610372205450d4c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f9003a00002002410c6a200441016a3602000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d49200441017422062005200620054b1b22064100480d490240024020040d00024020060d00410121050c020b2006103322050d010c500b2002280204210520042006460d0020052004200610372205450d4b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fa003a00002002410c6a200441016a3602000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d48200441017422062005200620054b1b22064100480d480240024020040d00024020060d00410121050c020b2006103322050d010c4f0b2002280204210520042006460d0020052004200610372205450d4a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fb003a00002002410c6a200441016a3602000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d47200441017422062005200620054b1b22064100480d470240024020040d00024020060d00410121050c020b2006103322050d010c4e0b2002280204210520042006460d0020052004200610372205450d490b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fc003a00002002410c6a200441016a3602000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d46200441017422062005200620054b1b22064100480d460240024020040d00024020060d00410121050c020b2006103322050d010c4d0b2002280204210520042006460d0020052004200610372205450d480b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fd003a00002002410c6a200441016a3602000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d45200441017422062005200620054b1b22064100480d450240024020040d00024020060d00410121050c020b2006103322050d010c4c0b2002280204210520042006460d0020052004200610372205450d470b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fe003a00002002410c6a200441016a3602000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d44200441017422062005200620054b1b22064100480d440240024020040d00024020060d00410121050c020b2006103322050d010c4b0b2002280204210520042006460d0020052004200610372205450d460b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ff003a00002002410c6a200441016a3602000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d43200441017422062005200620054b1b22064100480d430240024020040d00024020060d00410121050c020b2006103322050d010c4a0b2002280204210520042006460d0020052004200610372205450d450b20022005360204200241086a20063602002002410c6a28020021040b200520046a4180013a00002002410c6a200441016a3602000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d42200441017422062005200620054b1b22064100480d420240024020040d00024020060d00410121050c020b2006103322050d010c490b2002280204210520042006460d0020052004200610372205450d440b20022005360204200241086a20063602002002410c6a28020021040b200520046a4181013a00002002410c6a200441016a3602000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d41200441017422062005200620054b1b22064100480d410240024020040d00024020060d00410121050c020b2006103322050d010c480b2002280204210520042006460d0020052004200610372205450d430b20022005360204200241086a20063602002002410c6a28020021040b200520046a4182013a00002002410c6a200441016a3602000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d40200441017422062005200620054b1b22064100480d400240024020040d00024020060d00410121050c020b2006103322050d010c470b2002280204210520042006460d0020052004200610372205450d420b20022005360204200241086a20063602002002410c6a28020021040b200520046a4183013a00002002410c6a200441016a3602000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3f200441017422062005200620054b1b22064100480d3f0240024020040d00024020060d00410121050c020b2006103322050d010c460b2002280204210520042006460d0020052004200610372205450d410b20022005360204200241086a20063602002002410c6a28020021040b200520046a4184013a00002002410c6a200441016a3602000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3e200441017422062005200620054b1b22064100480d3e0240024020040d00024020060d00410121050c020b2006103322050d010c450b2002280204210520042006460d0020052004200610372205450d400b20022005360204200241086a20063602002002410c6a28020021040b200520046a4185013a00002002410c6a200441016a3602000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3d200441017422062005200620054b1b22064100480d3d0240024020040d00024020060d00410121050c020b2006103322050d010c440b2002280204210520042006460d0020052004200610372205450d3f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4186013a00002002410c6a200441016a3602000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3c200441017422062005200620054b1b22064100480d3c0240024020040d00024020060d00410121050c020b2006103322050d010c430b2002280204210520042006460d0020052004200610372205450d3e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4187013a00002002410c6a200441016a3602000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3b200441017422062005200620054b1b22064100480d3b0240024020040d00024020060d00410121050c020b2006103322050d010c420b2002280204210520042006460d0020052004200610372205450d3d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4188013a00002002410c6a200441016a3602000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3d200441017422062005200620054b1b22064100480d3d0240024020040d00024020060d00410121050c020b2006103322050d010c410b2002280204210520042006460d0020052004200610372205450d3c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4189013a00002002410c6a200441016a3602000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3c200441017422062005200620054b1b22064100480d3c0240024020040d00024020060d00410121050c020b2006103322050d010c400b2002280204210520042006460d0020052004200610372205450d3c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418a013a00002002410c6a200441016a3602000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3b200441017422062005200620054b1b22064100480d3b0240024020040d00024020060d00410121050c020b2006103322050d010c3f0b2002280204210520042006460d0020052004200610372205450d3b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418b013a00002002410c6a200441016a3602000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3a200441017422062005200620054b1b22064100480d3a0240024020040d00024020060d00410121050c020b2006103322050d010c3e0b2002280204210520042006460d0020052004200610372205450d3a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418c013a00002002410c6a200441016a3602000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d39200441017422062005200620054b1b22064100480d390240024020040d00024020060d00410121050c020b2006103322050d010c3d0b2002280204210520042006460d0020052004200610372205450d390b20022005360204200241086a20063602002002410c6a28020021040b200520046a418d013a00002002410c6a200441016a3602000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d38200441017422062005200620054b1b22064100480d380240024020040d00024020060d00410121050c020b2006103322050d010c3c0b2002280204210520042006460d0020052004200610372205450d380b20022005360204200241086a20063602002002410c6a28020021040b200520046a418e013a00002002410c6a200441016a3602000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d37200441017422062005200620054b1b22064100480d370240024020040d00024020060d00410121050c020b2006103322050d010c3b0b2002280204210520042006460d0020052004200610372205450d370b20022005360204200241086a20063602002002410c6a28020021040b200520046a418f013a00002002410c6a200441016a3602000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d36200441017422062005200620054b1b22064100480d360240024020040d00024020060d00410121050c020b2006103322050d010c3a0b2002280204210520042006460d0020052004200610372205450d360b20022005360204200241086a20063602002002410c6a28020021040b200520046a4190013a00002002410c6a200441016a3602000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d35200441017422062005200620054b1b22064100480d350240024020040d00024020060d00410121050c020b2006103322050d010c390b2002280204210520042006460d0020052004200610372205450d350b20022005360204200241086a20063602002002410c6a28020021040b200520046a4191013a00002002410c6a200441016a3602000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d34200441017422062005200620054b1b22064100480d340240024020040d00024020060d00410121050c020b2006103322050d010c380b2002280204210520042006460d0020052004200610372205450d340b20022005360204200241086a20063602002002410c6a28020021040b200520046a4192013a00002002410c6a200441016a3602000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d33200441017422062005200620054b1b22064100480d330240024020040d00024020060d00410121050c020b2006103322050d010c370b2002280204210520042006460d0020052004200610372205450d330b20022005360204200241086a20063602002002410c6a28020021040b200520046a4193013a00002002410c6a200441016a3602000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d32200441017422062005200620054b1b22064100480d320240024020040d00024020060d00410121050c020b2006103322050d010c360b2002280204210520042006460d0020052004200610372205450d320b20022005360204200241086a20063602002002410c6a28020021040b200520046a4194013a00002002410c6a200441016a3602000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d31200441017422062005200620054b1b22064100480d310240024020040d00024020060d00410121050c020b2006103322050d010c350b2002280204210520042006460d0020052004200610372205450d310b20022005360204200241086a20063602002002410c6a28020021040b200520046a4195013a00002002410c6a200441016a3602000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d30200441017422062005200620054b1b22064100480d300240024020040d00024020060d00410121050c020b2006103322050d010c340b2002280204210520042006460d0020052004200610372205450d300b20022005360204200241086a20063602002002410c6a28020021040b200520046a4196013a00002002410c6a200441016a3602000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2f200441017422062005200620054b1b22064100480d2f0240024020040d00024020060d00410121050c020b2006103322050d010c330b2002280204210520042006460d0020052004200610372205450d2f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4197013a00002002410c6a200441016a3602000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2e200441017422062005200620054b1b22064100480d2e0240024020040d00024020060d00410121050c020b2006103322050d010c320b2002280204210520042006460d0020052004200610372205450d2e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4198013a00002002410c6a200441016a3602000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2d200441017422062005200620054b1b22064100480d2d0240024020040d00024020060d00410121050c020b2006103322050d010c310b2002280204210520042006460d0020052004200610372205450d2d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4199013a00002002410c6a200441016a3602000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2c200441017422062005200620054b1b22064100480d2c0240024020040d00024020060d00410121050c020b2006103322050d010c300b2002280204210520042006460d0020052004200610372205450d2c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419a013a00002002410c6a200441016a3602000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2b200441017422062005200620054b1b22064100480d2b0240024020040d00024020060d00410121050c020b2006103322050d010c2f0b2002280204210520042006460d0020052004200610372205450d2b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419b013a00002002410c6a200441016a3602000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2a200441017422062005200620054b1b22064100480d2a0240024020040d00024020060d00410121050c020b2006103322050d010c2d0b2002280204210520042006460d0020052004200610372205450d2a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419c013a00002002410c6a200441016a3602000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d29200441017422062005200620054b1b22064100480d290240024020040d00024020060d00410121050c020b200610332205450d2c0c010b2002280204210520042006460d0020052004200610372205450d290b20022005360204200241086a20063602002002410c6a28020021040b200520046a419d013a00002002410c6a200441016a3602000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d28200441017422062005200620054b1b22064100480d280240024020040d00024020060d00410121050c020b200610332205450d2b0c010b2002280204210520042006460d0020052004200610372205450d280b20022005360204200241086a20063602002002410c6a28020021040b200520046a419e013a00002002410c6a200441016a3602000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d27200441017422062005200620054b1b22064100480d270240024020040d00024020060d00410121050c020b200610332205450d2a0c010b2002280204210520042006460d0020052004200610372205450d270b20022005360204200241086a20063602002002410c6a28020021040b200520046a419f013a00002002410c6a200441016a3602000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d26200441017422062005200620054b1b22064100480d260240024020040d00024020060d00410121050c020b200610332205450d290c010b2002280204210520042006460d0020052004200610372205450d260b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a0013a00002002410c6a200441016a3602000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d25200441017422062005200620054b1b22064100480d250240024020040d00024020060d00410121050c020b200610332205450d280c010b2002280204210520042006460d0020052004200610372205450d250b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a1013a00002002410c6a200441016a3602000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d24200441017422062005200620054b1b22064100480d240240024020040d00024020060d00410121050c020b200610332205450d270c010b2002280204210520042006460d0020052004200610372205450d240b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a2013a00002002410c6a200441016a3602000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d23200441017422062005200620054b1b22064100480d230240024020040d00024020060d00410121050c020b200610332205450d260c010b2002280204210520042006460d0020052004200610372205450d230b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a3013a00002002410c6a200441016a3602000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d22200441017422062005200620054b1b22064100480d220240024020040d00024020060d00410121050c020b200610332205450d250c010b2002280204210520042006460d0020052004200610372205450d220b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a4013a00002002410c6a200441016a3602000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d00024020060d00410121050c020b200610332205450d240c010b2002280204210520042006460d0020052004200610372205450d210b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a5013a00002002410c6a200441016a3602000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d20200441017422062005200620054b1b22064100480d200240024020040d00024020060d00410121050c020b200610332205450d230c010b2002280204210520042006460d0020052004200610372205450d200b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a6013a00002002410c6a200441016a3602000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1f200441017422062005200620054b1b22064100480d1f0240024020040d00024020060d00410121050c020b200610332205450d220c010b2002280204210520042006460d0020052004200610372205450d1f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a7013a00002002410c6a200441016a3602000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1e200441017422062005200620054b1b22064100480d1e0240024020040d00024020060d00410121050c020b200610332205450d210c010b2002280204210520042006460d0020052004200610372205450d1e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a8013a00002002410c6a200441016a3602000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1d200441017422062005200620054b1b22064100480d1d0240024020040d00024020060d00410121050c020b200610332205450d200c010b2002280204210520042006460d0020052004200610372205450d1d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a9013a00002002410c6a200441016a3602000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1c200441017422062005200620054b1b22064100480d1c0240024020040d00024020060d00410121050c020b200610332205450d1f0c010b2002280204210520042006460d0020052004200610372205450d1c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41aa013a00002002410c6a200441016a3602000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1b200441017422062005200620054b1b22064100480d1b0240024020040d00024020060d00410121050c020b200610332205450d1e0c010b2002280204210520042006460d0020052004200610372205450d1b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ab013a00002002410c6a200441016a3602000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1a200441017422062005200620054b1b22064100480d1a0240024020040d00024020060d00410121050c020b200610332205450d1d0c010b2002280204210520042006460d0020052004200610372205450d1a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ac013a00002002410c6a200441016a3602000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d19200441017422062005200620054b1b22064100480d190240024020040d00024020060d00410121050c020b200610332205450d1c0c010b2002280204210520042006460d0020052004200610372205450d190b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ad013a00002002410c6a200441016a3602000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d18200441017422062005200620054b1b22064100480d180240024020040d00024020060d00410121050c020b200610332205450d1b0c010b2002280204210520042006460d0020052004200610372205450d180b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ae013a00002002410c6a200441016a3602000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d17200441017422062005200620054b1b22064100480d170240024020040d00024020060d00410121050c020b200610332205450d1a0c010b2002280204210520042006460d0020052004200610372205450d170b20022005360204200241086a20063602002002410c6a28020021040b200520046a41af013a00002002410c6a200441016a3602000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d16200441017422062005200620054b1b22064100480d160240024020040d00024020060d00410121050c020b200610332205450d190c010b2002280204210520042006460d0020052004200610372205450d160b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b0013a00002002410c6a200441016a3602000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d15200441017422062005200620054b1b22064100480d150240024020040d00024020060d00410121050c020b200610332205450d180c010b2002280204210520042006460d0020052004200610372205450d150b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b1013a00002002410c6a200441016a3602000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d14200441017422062005200620054b1b22064100480d140240024020040d00024020060d00410121050c020b200610332205450d170c010b2002280204210520042006460d0020052004200610372205450d140b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b2013a00002002410c6a200441016a3602000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d13200441017422062005200620054b1b22064100480d130240024020040d00024020060d00410121050c020b200610332205450d160c010b2002280204210520042006460d0020052004200610372205450d130b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b3013a00002002410c6a200441016a3602000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d12200441017422062005200620054b1b22064100480d120240024020040d00024020060d00410121050c020b200610332205450d150c010b2002280204210520042006460d0020052004200610372205450d120b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b4013a00002002410c6a200441016a3602000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d11200441017422062005200620054b1b22064100480d110240024020040d00024020060d00410121050c020b200610332205450d140c010b2002280204210520042006460d0020052004200610372205450d110b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b5013a00002002410c6a200441016a3602000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d10200441017422062005200620054b1b22064100480d100240024020040d00024020060d00410121050c020b200610332205450d130c010b2002280204210520042006460d0020052004200610372205450d100b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b6013a00002002410c6a200441016a3602000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0f200441017422062005200620054b1b22064100480d0f0240024020040d00024020060d00410121050c020b200610332205450d120c010b2002280204210520042006460d0020052004200610372205450d0f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b7013a00002002410c6a200441016a3602000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0e200441017422062005200620054b1b22064100480d0e0240024020040d00024020060d00410121050c020b200610332205450d110c010b2002280204210520042006460d0020052004200610372205450d0e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b8013a00002002410c6a200441016a3602000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0d200441017422062005200620054b1b22064100480d0d0240024020040d00024020060d00410121050c020b200610332205450d100c010b2002280204210520042006460d0020052004200610372205450d0d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b9013a00002002410c6a200441016a3602000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0c200441017422062005200620054b1b22064100480d0c0240024020040d00024020060d00410121050c020b200610332205450d0f0c010b2002280204210520042006460d0020052004200610372205450d0c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ba013a00002002410c6a200441016a3602000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0b200441017422062005200620054b1b22064100480d0b0240024020040d00024020060d00410121050c020b200610332205450d0e0c010b2002280204210520042006460d0020052004200610372205450d0b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bb013a00002002410c6a200441016a3602000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0a200441017422062005200620054b1b22064100480d0a0240024020040d00024020060d00410121050c020b200610332205450d0d0c010b2002280204210520042006460d0020052004200610372205450d0a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bc013a00002002410c6a200441016a3602000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d09200441017422062005200620054b1b22064100480d090240024020040d00024020060d00410121050c020b200610332205450d0c0c010b2002280204210520042006460d0020052004200610372205450d090b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bd013a00002002410c6a200441016a3602000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d08200441017422062005200620054b1b22064100480d080240024020040d00024020060d00410121050c020b200610332205450d0b0c010b2002280204210520042006460d0020052004200610372205450d080b20022005360204200241086a20063602002002410c6a28020021040b200520046a41be013a00002002410c6a200441016a3602000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d07200441017422062005200620054b1b22064100480d070240024020040d00024020060d00410121050c020b200610332205450d0a0c010b2002280204210520042006460d0020052004200610372205450d070b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bf013a00002002410c6a200441016a3602000b2000411f3a000020012d00004109470d090240200141046a280200220228020441ffffffff0371450d0020022802001035200128020421020b200210350c090b103e000b103e000b103e000b103c000b103c000b103e000b103c000b103c000b20002004290200370200200041086a200441086a29020037020020012d00004109470d000240200141046a280200220228020441ffffffff0371450d0020022802001035200128020421020b200210350b200341106a24000f0b103c000ba907010c7f230041d0086b22022400410021034100210402400240024002400240024002400240024002400240034002402003411f4d0d00410f21030c030b20012802082205200128020c2206460d01200641016a22072006490d0420052007490d082001280200220820066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b024020034120490d00410d21032006410f4b0d020b20040d022000428080808010370200200041086a42003702000c0a0b200241013a0089082002411c6a41013602002002420137020c200241acfdcb003602082002413636029c08200220024198086a360218200220024189086a36029808200241b8086a200241086a1041410521030b2000200336020420004101360200200041086a20022903b808370200200041106a200241b8086a41086a2802003602000c080b200241086a4100418008109f081a41002106410021094101210a4100210b02400340200520076b2004200b6b22034180082003418008491b2203490d01200720036a220c2007490d032005200c490d04200241086a200820076a2003109d081a2001200c36020c02400240200920066b2003490d00200620036a210c2009210d0c010b200620036a220c2006490d0620094101742207200c2007200c4b1b220d4100480d06024020090d000240200d0d004101210a0c020b200d1033220a0d010c090b2009200d460d00200a2009200d1037220a450d080b200a20066a200241086a2003109d081a20042003200b6a220b4d0d08200128020c21072001280208210520012802002108200c2106200d21090c000b0b200241013a00a708200241cc086a4101360200200242013702bc08200241acfdcb003602b8082002413636029c08200220024198086a3602c8082002200241a7086a36029808200241a8086a200241b8086a104120024194086a200241b0086a280200360000200220022903a80837008c08200041053a000420002002290089083700052000410c6a20024190086a290000370000200041013602002009450d07200a10350c070b417f200741c0fdcb001059000b2007200c41c0fdcb001059000b200c200541c0fdcb001058000b103e000b2007200541c0fdcb001058000b103c000b200241086a200a200c1074024020022802084101470d000240200d450d00200a10350b200041083a0004200041013602000c010b2000200a3602042000410c6a200c360200200041086a200d360200200041003602000b200241d0086a24000b15002001200028020022002802002000280208105a0bf90401067f200441046a21050240024002400240200441086a2802002004410c6a2802002206460d00200528020021070c010b200641016a22072006490d01200641017422082007200820074b1b22084100480d010240024020060d00024020080d00410121070c020b2008103322070d010c040b2005280200210720062008460d0020072006200810372207450d030b20042007360204200441086a20083602002004410c6a28020021060b200720066a20024101463a00002004410c6a2209200641016a2206360200200441086a210a034002400240200a2802002006460d00200528020021070c010b200641016a22072006490d02200641017422082007200820074b1b22084100480d020240024020060d00024020080d00410121070c020b200810332207450d050c010b2005280200210720062008460d0020072006200810372207450d040b20042007360204200a2008360200200928020021060b200720066a200141807f72200141ff0071200141077622071b3a00002009200641016a22063602002007210120070d000b024020024101470d00200441086a21082004410c6a210903400240024020082802002006460d00200528020021010c010b200641016a22012006490d03200641017422072001200720014b1b22074100480d030240024020060d00024020070d00410121010c020b200710332201450d060c010b2005280200210120062007460d0020012006200710372201450d050b2004200136020420082007360200200928020021060b200120066a200341807f72200341ff0071200341077622011b3a00002009200641016a22063602002001210320010d000b0b2000411f3a00000f0b103e000b103c000bc807010a7f230041d0006b220224000240024002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d0220032005490d032001280200220620046a2d000021072001200536020c20074102490d01200041173a000420004101360200200041056a20073a00000c0a0b200241013a001f200241cc006a41013602002002420137023c200241acfdcb00360238200241363602342002200241306a36024820022002411f6a360230200241206a200241386a10412002411b6a200241286a28020036000020022002290320370013200220022900103703002002200241176a290000370007200041053a0004200020022903003700052000410c6a2002290007370000200041013602000c090b410120036b2108200441026a21044100210541002109034002402005411f4d0d00410f21050c090b200820046a4102460d072004450d0320032004490d05200620046a417f6a2d0000210a2001200436020c200a41ff00712005411f71742009722109200441016a2104200541076a2105200a418001710d000b024020054120490d00410d2105200a410f4b0d080b410021050240024002402007410171450d002004417f6a2104410021054100210b034002402005411f4d0d00410f21040c040b20032004460d022004417f460d072003200441016a2208490d09200620046a2d0000210a2001200836020c200a41ff00712005411f7174200b72210b200541076a210520082104200a418001710d000b024020054120490d00410d2104200a410f4b0d030b410121050b20002009360204200041003602002000410c6a200b360200200041086a20053602000c0a0b200241013a0000200241cc006a41013602002002420137023c200241acfdcb00360238200241363602342002200241306a36024820022002360230200241106a200241386a1041410521040b2000200436020420004101360200200041086a2002290310370200200041106a200241106a41086a2802003602000c080b417f200541c0fdcb001059000b2005200341c0fdcb001058000b417f200441c0fdcb001059000b417f200441016a41c0fdcb001059000b2004200341c0fdcb001058000b200441016a200341c0fdcb001058000b200241013a0000200241cc006a41013602002002420137023c200241acfdcb00360238200241363602342002200241306a36024820022002360230200241106a200241386a1041410521050b2000200536020420004101360200200041086a2002290310370200200041106a200241106a41086a2802003602000b200241d0006a24000bc4c901040b7f027e147f017e230041e081046b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280204220320012802082204460d00200441016a22052004490d0720032005490d06200128020020046a2d00002104200120053602082004410c4b0d0120040e0d02031211100f0e0d0c0b0a0908020b200241013a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022802c88104210420022802cc8104210120004101360200200041003a00042001450d1c200410350c1c0b200041123a000420004101360200200041056a20043a00000c1b0b200241b8016a200110c0074101210620022802bc012107024020022802b8014101460d0041002108200241b8016a410041808001109f081a41002103410021092007450d13410021054100210a410121064100210b024003402001280204220c200128020822036b2007200b6b220441808001200441808001491b2204490d01200320046a22092003490d05200c2009490d04200241b8016a200128020020036a2004109d081a2001200936020802400240200a20056b2004490d00200520046a2103200a21090c010b200520046a22032005490d19200a41017422092003200920034b1b22094100480d1902400240200a0d00024020090d00410121060c020b200910332206450d1f0c010b200a2009460d002006200a200910372206450d1e0b2009210a0b200620056a200241b8016a2004109d081a2003210520072004200b6a220b4b0d000c150b0b200241013a00b88104200241dc81046a4101360200200242013702cc8104200241acfdcb003602c881042002413636022c2002200241286a3602d881042002200241b881046a360228200241e0006a200241c881046a10412002290360210d2002280268210141052107200a450d15200610350c150b200241c8016a2802002101200241c0016a290300210d0c140b200241b8016a200110c707200241b8016a41086a290300220d422088210e200241c8016a280200210120022802bc01210a20022802b8014101460d0f200ea72103200241cc016a280200210f200da72110410021044100210b024002400240024002400240024002400240034002402004411f4d0d00410f21090c030b20032001460d012001417f460d09200141016a220820034b0d08200a20016a2d0000220541ff00712004411f7174200b72210b200441076a2104200821012005418001710d000b024020044120490d00410d21092005410f4b0d020b200241003602c08104200242043703b88104200b0d02410421040c030b200241013a00c88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241c881046a36022820024198016a200241b8016a1041410521090b20024188016a41086a20024198016a41086a28020022013602002002200229039801220d370388010c030b410020036b21114104210441002112410021130340024002400240024002400240024002400240024002400240024020082003460d00200841016a22052008490d01200520034b0d020240200a20086a2d0000220741e000460d004118211441002115200521080c0c0b200841036a2107410021084100210602400240024003402007210902402008411f4d0d00410f21140c030b20032005460d012005417f460d07200541016a220c20034b0d09200a20056a2d0000221641ff00712008411f71742006722106200941016a2107200841076a2108200c21052016418001710d000b024020084120490d00410d21142016410f4d0d00200c21050c020b41002117200241003602682002420137036020060d02410121144100211841002116200c21050c0c0b200241013a0060200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a1041200241306a41086a200241c881046a41086a280200360200200220022903c8810437033041052114200321050b200241c0006a41086a200241306a41086a280200221936020020022002290330220d370340200da72116410021074101211720022802442118410021150c0b0b200a200c6a211a2011200c6a211b410021164101211441002115410021180240034020162108201b201822056a450d012009450d060240200920034d0d002009200341c0fdcb001058000b0240201a20056a2c0000220741004e0d004119211c201d2116201e2118201f21190c0a0b4106211c200741c00071450d08200741807f72220741ff017141fc01490d080240024020052015460d00200821160c010b024020082015460d0020082116200821150c010b200841016a22162008490d2b200841017422182016201820164b1b22164100480d2b0240024020080d00024020160d00410121140c020b201610332214450d310c010b20082016460d0020142008201610372214450d300b2002201636026420022014360260201621150b201420056a2007417f733a00002002200541016a2218360268200941016a210920062018460d0a0c000b0b200241013a00a801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241a8016a360228200241c881046a200241b8016a10414105211c20022802c881042216211d20022802cc81042218211e20022802d081042219211f200321090c070b200241013a0060200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022802c88104211620022802cc8104211820022d00d08104210920022d00d18104210620022f01d2810421014105211441002115200321080c0a0b417f200541c0fdcb001059000b2005200341c0fdcb001058000b417f200541016a41c0fdcb001059000b417f200941c0fdcb001059000b200541016a200341c0fdcb001058000b2020211620212118202221190b410021154101211702402008450d00201410350b201c2114201621202018212120192122200921050c020b200c20186a21050b20144110762115201441087621070b0240024002400240024002400240024020170d002015411074200741ff017141087472201441ff017172211b410021174100210941002106034002402009411f4d0d00410f21140c080b0240024020032005460d002005417f460d05200541016a220820034d0d01200541016a200341c0fdcb001058000b200241013a0060200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022802c88104210720022802cc8104211820022d00d08104210920022d00d18104210620022f01d28104210141052114200321050c090b200a20056a2d0000220c41ff00712009411f71742006722106200941076a210920082105200c418001710d000b20094120490d01200c410f4d0d0120082105410d21140c060b201941107621012019410876210620052108201921090c070b024002400240200641014b0d00024020060e020002000b410421090c020b4104211441bed8cb00210741242118200821050c060b0240024020032008460d00200841016a22052008490d04200520034b0d05200a20086a2c0000221741004e0d01411921140c070b200241013a0060200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022802c88104210720022802cc8104211820022d00d08104210920022d00d18104210620022f01d28104210141052114200321050c070b201741c00071450d04201741807f72221741ff017141fc01490d042017417f732109200521080b20014180807c71200941ff01714108747241e000722101410021050c070b417f200541016a41c0fdcb001059000b417f200841016a41c0fdcb001059000b200841016a200341c0fdcb001058000b410621140b0b4100211502402016450d00201b10350b2005210820072116201721070b200641ff0171410874200941ff0171722001411074722101410121050b2015411074200741ff017141087472201441ff01717221092018ad4220862016ad84210d20050d02201341016a21130240201220022802bc8104470d00200241b881046a20124101108c0120022802b88104210420022802c0810421120b200420124104746a2205200136020c2005200d370204200520093602002002201241016a22123602c081042013200b470d000b0b2008200f46210120022902bc8104212302402010450d00200a10350b410221032001450d020c170b02402012450d00201241047421052004210303400240200341046a280200450d00200328020010350b200341106a2103200541706a22050d000b0b20022802bc810441ffffffff0071450d00200410350b200d422088210e20094108762103024020100d002009210a0c140b200a10352009210a0c130b20024103410220011b3a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022903c88104210d20022802d08104210102402023422088a72203450d00200341047421052004210303400240200341046a280200450d00200328020010350b200341106a2103200541706a22050d000b0b200d422088210e4105210a41002103202342ffffffff0083500d12200410350c120b200141016a200341c0fdcb001058000b417f200141016a41c0fdcb001059000b2009200c41c0fdcb001058000b2003200941c0fdcb001059000b2005200341c0fdcb001058000b417f200541c0fdcb001059000b200241b8016a200110c707200241b8016a41106a2802002101200241b8016a410c6a2802002105200241b8016a41086a280200210920022802bc01210b0240024020022802b8014101460d00200241cc016a280200210641002103410021040240024002400240034002402003411f4d0d00410f21010c030b20052001460d012001417f460d042005200141016a220a490d06200b20016a2d0000220841ff00712003411f71742004722104200341076a2103200a21012008418001710d000b024020034120490d00410d21012008410f4b0d020b2006200a46210102402009450d00200b10350b2001450d02410b21030c130b200241013a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a1041410521010b2000200136020420004101360200200041086a20022903c88104370200200041106a200241c881046a41086a2802003602002009450d18200b10350c180b20024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241d381046a200241e8006a280200360000200220022903603700cb8104200041053a0004200020022900c881043700052000410c6a200241cf81046a290000370000200041013602000c170b417f200141016a41c0fdcb001059000b2000200b36020420004101360200200041106a20013602002000410c6a2005360200200041086a20093602000c150b200141016a200541c0fdcb001058000b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b024002400240024020022802b8014101460d002002200241cc016a2802003602702002200136026c2002200b3602602002200d370264200d422088a72108410021044100210a02400240024002400240034002402004411f4d0d00410f210b0c030b20082001460d012001417f460d05200141016a220520084b0d04200b20016a2d000021032002200536026c200341ff00712004411f7174200a72210a200441076a2104200521012003418001710d000b024020044120490d00410d210b2003410f4b0d020b200241003602800120024204370378200a0d02410421040c070b200241013a00c88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241c881046a36022820024198016a200241b8016a10414105210b0b20024188016a41086a20024198016a41086a28020022013602002002200229039801220d370388010c040b410021070340200741016a21074100210141002105024002400240024002400240024002400240034002402001411f4d0d00410f210b0c030b20022802682208200228026c2204460d01200441016a22032004490d0520082003490d06200228026020046a2d000021042002200336026c200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d022004410f4d0d02410d210b0c010b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a1041200241c0006a41086a200241c881046a41086a280200360200200220022903c88104220d370340200da7210a4105210b0b20022802482101200228024421090c010b200241b8016a200241e0006a10a70720022802c401211820022802c001211520022802bc01211420022802b8014101470d0320022802c80121012014210b2015210a201821090b200241d0006a41086a20024198016a41086a28020036020020022002290398013703500c030b417f200341c0fdcb001059000b2003200841c0fdcb001058000b410021044100210b02400240024002400240024002400240034002402004411f4d0d00410f210b0c030b20022802682208200228026c2203460d01200341016a22012003490d0420082001490d072002280260220920036a2d000021032002200136026c200341ff00712004411f7174200b72210b200441076a21042003418001710d000b024020044120490d002003410f4d0d00410d210b0c020b41002112200241b8016a410041808004109f081a200b0d02410121134100210c0c090b200241013a00b88104200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a1041200241306a41086a200241c881046a41086a280200360200200220022903c88104220d370330200da7210a4105210b0b20022802382101200228023421090c050b4100210641012113410021034100211602400340200820016b200b20166b220441808004200441808004491b2204490d01200120046a220c2001490d032008200c490d04200241b8016a200920016a2004109d081a2002200c36026c02400240200620036b2004490d00200320046a210c200621120c010b200320046a220c2003490d1f20064101742201200c2001200c4b1b22124100480d1f024020060d00024020120d00410121130c020b201210332213450d240c010b20062012460d0020132006201210372213450d230b201320036a200241b8016a2004109d081a200b200420166a22164d0d08200228026c2101200228026821082002280260210920122106200c21030c000b0b200241013a0040200241013602dc8104200242013702cc8104200241acfdcb003602c881042002413636022c2002200241286a3602d881042002200241c0006a360228200241b881046a200241c881046a104120022802b88104210a20022802bc8104210920022802c0810421014105210b2006450d04201310350c040b417f200141c0fdcb001059000b2001200c41c0fdcb001059000b200c200841c0fdcb001058000b2001200841c0fdcb001058000b02402018450d0020184104742103201421040340024020042d00004109470d000240200441046a2208280200220528020441ffffffff0371450d0020052802001035200828020021050b200510350b200441106a2104200341706a22030d000b0b0240201541ffffffff0071450d00201410350b200241d0006a41086a20024198016a41086a28020036020020022002290398013703500b2009ad422086200aad84210d200241f8006a10b407200228027c2204450d052004411c6c450d05200228027810350c050b200241d0006a41086a200c36020020024188016a41086a2208200c360200200220123602ac01200220133602a801200220022903a801220d3703502002200d370388012015ad4220862014ad84210d02402002280280012203200228027c470d00200241f8006a2003410110f90120022802800121030b200228027822042003411c6c6a2201200d3702042001200536020020012002290388013702102001410c6a2018360200200141186a20082802003602002002200341016a360280012007200a460d050c000b0b200141016a200841c0fdcb001058000b417f200141016a41c0fdcb001059000b200d422088210e200b41087621040c020b200d422088210e200b41087621042002280264450d01200228026010350c010b2002200229027c222337021c20022004360218200228026c200228027046210102402002280264450d00200228026010350b024020010d0020024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a104120022903c88104210d20022802d081042101200241186a10b40702402023a72203450d002003411c6c450d00200410350b200d422088210e4105210b410021040c010b410d21030c0d0b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002004410874200b41ff0171723602040c130b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b0240024002400240024002400240024002400240024002400240024020022802b8014101460d00200241cc016a2802002112200d422088a72105200da72106410021044100210802400240024002400240034002402004411f4d0d00410f21090c030b20052001460d012001417f460d05200141016a220320054b0d04200b20016a2d0000220a41ff00712004411f71742008722108200441076a210420032101200a418001710d000b024020044120490d00410d2109200a410f4b0d020b200241003602b001200242043703a80120080d02410421040c110b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a1041410521090b200241e0006a41086a200241c881046a41086a2802002201360200200220022903c88104220d3703600c0e0b410021150340201541016a2115410021014100210a024002400240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f210920022802a00121010c1d0b20052003460d012003417f460d04200341016a220420054b0d0b200b20036a2d0000220941ff00712001411f7174200a72210a200141076a2101200421032009418001710d000b024020014120490d002009410f4d0d00410d210920022802a00121010c1c0b4100210c200241b8016a410041808001109f081a200a0d01410121182004210341002114410021090c020b200241013a00c88104200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241c881046a36022820024198016a200241b8016a104141052109200229039801210d20022802a00121010c1a0b410021164101211841002107410021130340200520046b200a20136b220141808001200141808001491b2201490d19200420016a22032004490d03200320054b0d04200241b8016a200b20046a2001109d081a02400240201620076b2001490d00200720016a2109201621140c010b200720016a22092007490d2d201641017422042009200420094b1b22144100480d2d0240024020160d00024020140d00410121180c020b201410332218450d330c010b20162014460d0020182016201410372218450d320b201421160b201820076a200241b8016a2001109d081a2003210420092107200a200120136a22134b0d000b0b200220093602702002410036026c2002201836026020022009ad4220862014ad84370264410021014100210702400240024002400240024002400240034002402001411f4d0d00410f21090c030b2009200c460d01200c417f460d0c200c41016a220a20094b0d112018200c6a2d000021042002200a36026c200441ff00712001411f71742007722107200141076a2101200a210c2004418001710d000b024020014120490d002004410f4d0d00410d21090c020b4100210c200241003602c08104200242043703b8810420070d024104211441002110410021180c030b200241013a00b88104200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a1041200241306a41086a200241c881046a41086a280200360200200220022903c88104370330410521090b200241c0006a41086a200241306a41086a280200220136020020022002290330220d370340200da722044108762105200228024421030c1b0b4100211041042114410021190340201941016a21194100210141002116034002402001411f4d0d00410f21090c050b20022802682213200228026c2204460d03200441016a220a2004490d0b2013200a490d102002280260221820046a2d000021092002200a36026c200941ff00712001411f71742016722116200141076a21012009418001710d000b024020014120490d002009410f4d0d00410d21090c040b2013200a460d04200441026a2101200a417f460d0b20132001490d0c2018200a6a2c0000210a2002200136026c0240200a41004e0d00411921090c1a0b41062109200a41c00071450d18200a41807f72220a41ff017141fb014d0d18200a417f7321010240201020022802bc8104470d00200241b881046a2010410110900120022802b88104211420022802c0810421100b201420104103746a220420013a0004200420163602002002201041016a22103602c0810420192007470d000b20022802bc810421180b201420104103746a210920142101034020092001460d04200c20012802006a2204200c49210a200141086a21012004210c200a450d000b200229038801220d422088a7210320024190016a2802002101200da72104411c21090c150b200241013a00c88104200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241c881046a36022820024198016a200241b8016a10414105210920022802980121040b2004410876210520022802a0012101200228029c0121034100210a0c160b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241c881046a200241b8016a104120022802c88104210420022802cc8104210320022802d081042101410521090c140b4100210a200241003602d08104200242083703c881044101210c410821130340200241b8016a200241e0006a10a80720022802c001210420022903c801210d20022802c4012116024002400240024020022802b8014101460d00200441ff017122014106460d022001417e6a41034f0d03200c41016a2201200c4f21092001210c20090d03200441ff0171210141152103418dd2cb0021044104210920014109460d010c150b20022802bc012109200da72101201621030c140b0240201628020441ffffffff0371450d00201628020010350b201610350c130b200c417f6a210c0b2004410876210702400240200a20022802cc8104460d00200a21090c010b200241c881046a200a10a90720022802c88104211320022802d0810421090b201320094104746a2201200d37030820012016360204200120073b0001200120043a0000200141036a20074110763a00002002200941016a220a3602d08104200c0d000b200228026c200228027046210120022802cc8104210702402002280264450d00200228026010350b024020010d0020024103410220011b3a00b88104200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a104120022903c88104210d20022802d0810421010240200a450d00200941047441106a2103201321040340024020042d00004109470d000240200441046a2208280200220528020441ffffffff0371450d0020052802001035200828020021050b200510350b200441106a2104200341706a22030d000b0b200d422088210e0240200741ffffffff0071450d00201310350b200ea72103200da7210441052109201841ffffffff0171450d1a201410350c1a0b20022802b001220120022802ac01470d0b200141016a22042001490d2a200141017422092004200920044b1bad42187e220d422088a70d2a200da722044100480d2a0240024020010d0020040d01410421090c0c0b20022802a8012109200141186c220c2004460d0b0240200c0d0020040d01410421090c0c0b2009200c200410372209450d2f0c0b0b200410332209450d2e0c0a0b417f200341016a41c0fdcb001059000b2004200341c0fdcb001059000b2003200541c0fdcb001058000b417f200c41016a41c0fdcb001059000b417f200a41c0fdcb001059000b417f200141c0fdcb001059000b2001201341c0fdcb001058000b200341016a200541c0fdcb001058000b200c41016a200941c0fdcb001058000b200a201341c0fdcb001058000b200220093602a8012002200441186e3602ac010b20022802a8012204200141186c6a2209201336020c20092010ad4220862018ad8437020420092014360200200941106a200aad4220862007ad843702002002200141016a3602b00120152008460d0f0c000b0b200141016a200541c0fdcb001058000b417f200141016a41c0fdcb001059000b200d422088210e200b41087621040c0c0b0240200a450d00200a4104742108201321050340024020052d00004109470d000240200541046a2207280200220a28020441ffffffff0371450d00200a28020010352007280200210a0b200a10350b200541106a2105200841706a22080d000b0b20022802cc810441ffffffff0071450d00201310350b201841ffffffff0171450d04201410350c040b0b200441087621050b200a41ff0171410874200972210920022802bc810441ffffffff0171450d00201410350b2005410874200441ff01717221040b2002280264450d02200228026010350c020b200241013a009801200241013602dc8104200242013702cc8104200241acfdcb003602c881042002413636022c2002200241286a3602d88104200220024198016a360228200241b881046a200241c881046a104120022903b88104210d20022802c081042101410521092016450d00201810350b200d422088a72103200da721040b200241a8016a10b3072003ad4220862004ad84210d20022802ac012204450d00200441186c450d0020022802a80110350b200d422088210e20094108762104024020060d002009210b0c020b200b10352009210b0c010b200220022902ac01222337027c200220043602782003201246210102402006450d00200b10350b024020010d0020024103410220011b3a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022903c88104210d20022802d081042101200241f8006a10b30702402023a72203450d00200341186c450d00200410350b200d422088210e4105210b410021040c010b410c21030c0c0b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002004410874200b41ff0171723602040c120b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b02400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d481042002200b3602c881042002200d3702cc8104200d422088a72108410021044100210a024002400240024002400240034002402004411f4d0d00410f210b0c030b20082001460d012001417f460d06200141016a220520084b0d05200b20016a2d00002103200220053602d48104200341ff00712004411f7174200a72210a200441076a2104200521012003418001710d000b024020044120490d00410d210b2003410f4b0d020b200241003602a0012002420437039801200a0d02410421040c030b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241c0006a41086a200241e0006a41086a280200360200200220022903603703404105210b0b20024198016a41086a200241c0006a41086a280200220136020020022002290340220d370398010c050b41042104410021090340200941016a21094100210141002108024002400240024002400240024002400240034002402001411f4d0d00410f210b0c030b20022802d08104220b20022802d481042203460d01200341016a22052003490d07200b2005490d0820022802c8810420036a2d00002103200220053602d48104200341ff00712001411f71742008722108200141076a21012003418001710d000b20014120490d022003410f4d0d02410d210b0c010b200241013a0078200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241f8006a360228200241e0006a200241b8016a1041200241306a41086a200241e0006a41086a28020036020020022002290360220d370330200da721064105210b0b20022802382101200228023421030c010b200241b8016a200241c881046a10a70720022802c401210c20022802c001211220022802bc01211620022802b8014101470d0120022802c80121012016210b20122106200c21030b200241d0006a41086a200241b881046a41086a280200360200200220022903b881043703500c010b200241b8016a200241c881046a10ab0720022802c401210320022802c001210620022802bc01210b20022802b8014101470d0320022802c80121010240200c450d00200c4104742108201621050340024020052d00004109470d000240200541046a2209280200220a28020441ffffffff0371450d00200a28020010352009280200210a0b200a10350b200541106a2105200841706a22080d000b0b0240201241ffffffff0071450d00201610350b200241d0006a41086a200241b881046a41086a280200360200200220022903b881043703500b2003ad4220862006ad84210d20024198016a10b207200228029c012203450d082003411c6c450d08200410350c080b417f200541c0fdcb001059000b2005200b41c0fdcb001058000b200241003602c001200242043703b801200241b8016a41002003410274220541027510860120022802c001210702402003450d002005417c6a410276211320022802b80120074102746a2101200b2103034020012003280200360200200141046a2101200341046a21032005417c6a22050d000b200720136a41016a21070b200220073602c0010240200641ffffffff0371450d00200b10350b200241d0006a41086a200241b8016a41086a2802002201360200200241a8016a41086a22052001360200200220022903b801220d3703502002200d3703a8012012ad4220862016ad84210d024020022802a0012203200228029c01470d0020024198016a2003410110f901200228029801210420022802a00121030b20042003411c6c6a2201200d370204200120083602002001410c6a200c360200200120022903a801370210200141186a20052802003602002002200341016a3602a0012009200a470d000b0b2002200229029c01222337028c01200220043602880120022802d4810420022802d88104462101024020022802cc8104450d0020022802c8810410350b024020010d0020024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360210d2002280268210120024188016a10b20702402023a72203450d002003411c6c450d00200410350b200d422088210e4105210b410021040c050b410a21030c0f0b200141016a200841c0fdcb001058000b417f200141016a41c0fdcb001059000b200d422088210e200b41087621040c010b200d422088210e200b410876210420022802cc8104450d0020022802c8810410350b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002004410874200b41ff0171723602040c110b200241b8016a200110c707200241b8016a41106a2802002101200241b8016a410c6a2802002105200241b8016a41086a280200210920022802bc01210b0240024020022802b8014101460d00200241cc016a280200210641002103410021040240024002400240034002402003411f4d0d00410f21010c030b20052001460d012001417f460d042005200141016a220a490d06200b20016a2d0000220841ff00712003411f71742004722104200341076a2103200a21012008418001710d000b024020034120490d00410d21012008410f4b0d020b2006200a46210102402009450d00200b10350b2001450d02410921030c0f0b200241013a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a1041410521010b2000200136020420004101360200200041086a20022903c88104370200200041106a200241c881046a41086a2802003602002009450d14200b10350c140b20024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241d381046a200241e8006a280200360000200220022903603700cb8104200041053a0004200020022900c881043700052000410c6a200241cf81046a290000370000200041013602000c130b417f200141016a41c0fdcb001059000b2000200b36020420004101360200200041106a20013602002000410c6a2005360200200041086a20093602000c110b200141016a200541c0fdcb001058000b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b02400240024002400240024002400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d481042002200b3602c881042002200d3702cc8104200d422088a72108410021044100210a024002400240024002400240034002402004411f4d0d00410f210b0c030b20082001460d012001417f460d06200141016a220520084b0d05200b20016a2d00002103200220053602d48104200341ff00712004411f7174200a72210a200441076a2104200521012003418001710d000b024020044120490d00410d210b2003410f4b0d020b200241003602b001200242043703a801200a0d02410421040c030b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241306a41086a200241e0006a41086a280200360200200220022903603703304105210b0b200241c0006a41086a200241306a41086a280200220136020020022002290330220d3703400c0b0b410021070340200241b8016a200241c881046a10ad0720022802c401211620022802c001210c20022802bc01210b0240024002400240024002400240024002400240024020022802b8014101460d0002400240024002400240024020022802d08104220420022802d481042203460d00200341016a22012003490d0920042001490d0a20022802c88104220520036a2d00002103200220013602d48104200341034b0d0720030e0401020304010b200220073602b001200241013a009801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c180b410021084100210303402008411f4b0d150240024020042001460d002001417f460d0c2004200141016a22064f0d01200141016a200441c0fdcb001058000b200220073602b001200241013a009801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c190b200520016a2d00002109200220063602d48104200941ff00712008411f71742003722103200841076a2108200621012009418001710d000b4100210420084120490d032009410f4d0d030c150b410021084100210303402008411f4b0d140240024020042001460d002001417f460d0c2004200141016a22064f0d01200141016a200441c0fdcb001058000b200220073602b001200241013a009801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c180b200520016a2d00002109200220063602d48104200941ff00712008411f71742003722103200841076a2108200621012009418001710d000b4101210420084120490d022009410f4b0d140c020b410021084100210303402008411f4b0d130240024020042001460d002001417f460d0c2004200141016a22064f0d01200141016a200441c0fdcb001058000b200220073602b001200241013a009801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c170b200520016a2d00002109200220063602d48104200941ff00712008411f71742003722103200841076a2108200621012009418001710d000b4102210420084120490d012009410f4b0d130c010b410021084100210303402008411f4b0d120240024020042001460d002001417f460d0c2004200141016a22064f0d01200141016a200441c0fdcb001058000b200220073602b001200241013a009801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c160b200520016a2d00002109200220063602d48104200941ff00712008411f71742003722103200841076a2108200621012009418001710d000b4103210420084120490d002009410f4b0d120b200220163602bc81042002200c3602b8810420022903b88104210d200720022802ac01470d0a20074101742201200741016a2205200120054b1bad42147e220e422088a70d22200ea7220141004e0d020c220b200220022802c80122013602c08104200220163602bc81042002200c3602b88104200220073602b0010c140b200220073602b00120034108742103410a21040c100b0240024020070d0020010d01410421050c080b20022802a8012105200741146c22082001460d07024020080d0020010d01410421050c080b20052008200110372205450d240c070b200110332205450d230c060b417f200141c0fdcb001059000b2001200441c0fdcb001058000b417f200141016a41c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141016a41c0fdcb001059000b200220053602a8012002200141146e3602ac010b20022802a801200741146c6a2201200436020c2001200d3702042001200b360200200141106a2003360200200741016a220121072001200a470d000b200220013602b00120022802a80121040b20022802d4810420022802d8810446210120022902ac012123024020022802cc8104450d0020022802c8810410350b024020010d002023a7210820024103410220011b3a00b88104200241b8016a41146a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360210d2002280268210102402023422088a72203450d00200341146c21052004210303400240200341046a280200450d00200328020010350b200341146a21032005416c6a22050d000b0b200d422088210e4105210b410021032008450d0b200841146c450d0b200410350c0b0b410821030c130b200141016a200841c0fdcb001058000b417f200141016a41c0fdcb001059000b200d422088210e200b41087621030c070b200220073602b001410f2104410021030c010b200220073602b001410d2104410021030b0c010b200228026021012002290264210d41052104410021030b200220013602b881042002200d3702bc8104200d422088210d0240200c450d00200b10350b2004200372210b200da7210120022802b00121070b20022903b88104210d02402007450d0020022802a8012104200741146c210303400240200441046a280200450d00200428020010350b200441146a21042003416c6a22030d000b0b20022802ac012204450d00200441146c450d0020022802a80110350b200d422088210e200b410876210320022802cc8104450d0020022802c8810410350b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200b41ff0171723602040c0f0b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b0240024002400240024002400240024002400240024002400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d481042002200b3602c881042002200d3702cc8104200d422088a72108410021044100210a024002400240034002402004411f4d0d00410f21040c030b20082001460d012001417f460d05200141016a220320084b0d0a200b20016a2d00002105200220033602d48104200541ff00712004411f7174200a72210a200441076a2104200321012005418001710d000b024020044120490d00410d21042005410f4b0d020b200241003602b001200242043703a801200a0d02410421040c0f0b200241013a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a36022820024188016a200241b8016a1041410521040b200241b881046a41086a20024188016a41086a28020022013602002002200229038801220d3703b881040c0c0b200a417f6a2106200241b8016a410472210741042104410421124104210a4100210903400240024020082003460d00200341016a22052003490d0520082005490d06200b20036a2c00002101200220053602d48104200141004e0d01411921160c0a0b200241013a008801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024188016a360228200241e0006a200241b8016a10410c0a0b41062116200141c00071450d080240200141807f72220c41ff017141fc014f0d00200c21010c090b02400240024020082005460d00200341026a21032005417f460d0820082003490d09200b20056a2d00002101200220033602d481040240200141014d0d00410c21160c0c0b4100210320010e020201020b200241013a008801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024188016a360228200241e0006a200241b8016a10410c0b0b410121030b200241b8016a200241c881046a10a707200241306a41086a200741086a2802002201360200200241c0006a41086a2205200136020020022007290200370340024020022802b8014101470d0020022d00c801210420022d00c901210320022f01ca0121010c0c0b200c417f73210820024198016a41086a20052802002201360200200241b881046a41086a2205200136020020022002290340220d370398012002200d3703b881040240200920022802ac01470d00200241a8016a20094101108c0120022802b001210920022802a801220421122004210a0b2005280200210520022903b88104210d200a20094104746a220120083a000c2001200d3702002001410d6a20033a0000200141086a20053602002002200941016a22093602b0012006450d0d2006417f6a210620022802d48104210320022802d08104210820022802c88104210b0c000b0b200d422088210e200b41087621030c0c0b417f200141016a41c0fdcb001059000b417f200541c0fdcb001059000b2005200841c0fdcb001058000b417f200341c0fdcb001059000b2003200841c0fdcb001058000b200141016a200841c0fdcb001058000b0c010b200228026021032002280264210520022802682104410521160b2002200536024820022003360244200220013a0041200220163a004020044110762101200441087621030b20024198016a41086a200241c0006a41086a28020036020020022002290340220e37039801200341ff0171410874200441ff017172210b20014110742106200229029c01210d02402009450d00200a20094104746a210803400240200a2802082204450d00200a2802002101200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d0020032802001035200528020021030b200310350b200141106a2101200441706a22040d000b0b200a41106a21010240200a41046a28020041ffffffff0071450d00200a28020010350b2001210a20012008470d000b0b200b2006722101200ea7210420022802ac0141ffffffff0071450d00201210350b200d422088210e20044108762103024020022802cc81040d002004210b0c020b20022802c8810410352004210b0c010b20022802d4810420022802d8810446210120022902ac012123024020022802cc8104450d0020022802c8810410350b024020010d0020024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360210d2002280268210102402023422088a72203450d00200420034104746a21092004210b03400240200b2802082205450d00200b2802002103200541047421050340024020032d00004109470d000240200341046a220a280200220828020441ffffffff0371450d0020082802001035200a28020021080b200810350b200341106a2103200541706a22050d000b0b200b41106a21030240200b41046a28020041ffffffff0071450d00200b28020010350b2003210b20032009470d000b0b200d422088210e4105210b41002103202342ffffffff0083500d01200410350c010b410721030c080b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200b41ff0171723602040c0e0b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210802400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d48104200220083602c881042002200d3702cc8104200d422088a7210541002104410021030240024002400240024003402004411f4b0d010240024020052001460d002001417f460d0a200141016a220a20054d0d01200141016a200541c0fdcb001058000b200220053602d48104200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241306a41086a200241e0006a41086a28020036020020022002290360370330410521080c030b200820016a2d0000220b41ff00712004411f71742003722103200441076a2104200a2101200b418001710d000b2002200a3602d48104024020044120490d00410d2108200b410f4b0d020b4100210120024100360268200242043703604104210402402003450d000340200241b8016a200241c881046a10b00720022903c001210d20022802bc01210820022802b8014101460d04024020012002280264470d00200241e0006a2001410110870120022802602104200228026821010b20042001410c6c6a2205200d370204200520083602002002200141016a22013602682003417f6a22030d000b0b20022802d4810420022802d8810446210120022902642123024020022802cc8104450d0020022802c8810410350b20010d0420024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360220d422088210e2002280268210141052108410021032023a72205450d062005410c6c450d06200410350c060b200220013602d48104410f21080b200241c0006a41086a200241306a41086a280200220136020020022002290330220d3703400c010b200241c8016a280200210120022802642203450d002003410c6c450d00200410350b200d422088210e2008410876210320022802cc8104450d0220022802c8810410350c020b410621030c090b200d422088210e200841087621030b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200841ff0171723602040c0e0b417f200141016a41c0fdcb001059000b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b02400240024002400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d481042002200b3602c881042002200d3702cc8104200d422088a721034100210441002108024002400240024003402004411f4b0d010240024020032001460d002001417f460d08200141016a220520034d0d01200141016a200341c0fdcb001058000b200220033602d48104200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241306a41086a200241e0006a41086a28020036020020022002290360370330410521090c030b200b20016a2d0000220a41ff00712004411f71742008722108200441076a210420052101200a418001710d000b200220053602d48104024020044120490d00410d2109200a410f4b0d020b4100210a200241003602c08104200242043703b8810420080d02410421040c080b200220013602d48104410f21090b200241c0006a41086a200241306a41086a280200220136020020022002290330220d3703400c010b2008417f6a21084104210402400240034020032005460d01200541016a22012005490d0620032001490d07200b20056a2c00002103200220013602d48104410021090240200341004e0d00411921060c030b410721060240200341c000710d000c030b200341807f7222034170470d02200241b8016a200241c881046a10b00720022802bc012101024020022802b8014101470d00200141ff0171210620014180807c7121092001410876210320022903c001220d422088a7210b200241c8016a2802002101200da721050c030b20022903c001210d0240200a20022802bc8104470d00200241b881046a200a410110870120022802b88104210420022802c08104210a0b2004200a410c6c6a2203200d370204200320013602002002200a41016a220a3602c081042008450d082008417f6a210820022802d48104210520022802d08104210320022802c88104210b0c000b0b200241013a00a801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241a8016a360228200241e0006a200241b8016a1041200228026021052002280264210b2002280268210141002109410521060b200bad4220862005ad84210d2009200341ff017141087472200672210920022802bc81042203450d002003410c6c450d00200410350b200d422088210e20094108762103024020022802cc81040d002009210b0c060b20022802c8810410352009210b0c050b200d422088210e200b41087621030c040b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b2001200341c0fdcb001058000b20022802d4810420022802d8810446210120022902bc81042123024020022802cc8104450d0020022802c8810410350b024020010d0020024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360220d422088210e200228026821014105210b410021032023a72205450d012005410c6c450d01200410350c010b410521030c060b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200b41ff0171723602040c0c0b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b024002400240024002400240024002400240024020022802b8014101460d00200241cc016a280200210c200d422088a72103200da721074100210441002108034002402004411f4d0d00410f21090c090b20032001460d072001417f460d03200141016a220520034b0d05200b20016a2d0000220a41ff00712004411f71742008722108200441076a210420052101200a418001710d000b024020044120490d00410d2109200a410f4b0d080b410021122002410036026820024204370360410421040240024002402008450d00410021160340201641016a21164100210a200521014100210903400240200a411f4d0d00410f21090c050b20032001460d032001417f460d08200141016a220520034b0d0a200b20016a2d0000220641ff0071200a411f71742009722109200a41076a210a200521012006418001710d000b0240200a4120490d002006410f4d0d00410d21090c040b20024198016a41086a200241c0006a41086a2802003602002002200229034037039801024020122002280264470d00200241e0006a2012410110860120022802602104200228026821120b200420124102746a20093602002002201241016a221236026820162008470d000b0b2005200c4621012002290264212302402007450d00200b10350b2001450d03410421030c100b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a1041200241306a41086a200241c881046a41086a280200360200200220022903c88104370330410521090b200241386a28020021012002290330210d200228026441ffffffff0371450d08200410350c080b200d422088210e200b41087621030c080b20024103410220011b3a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022903c88104220d422088210e20022802d0810421014105210b41002103202342ffffffff0383500d07200410350c070b417f200141016a41c0fdcb001059000b417f200141016a41c0fdcb001059000b200141016a200341c0fdcb001058000b200141016a200341c0fdcb001058000b200241013a00c88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241c881046a36022820024188016a200241b8016a1041410521090b200241b881046a41086a20024188016a41086a28020022013602002002200229038801220d3703b881040b200d422088210e41002103024020070d002009210b0c010b200b10352009210b0b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200b41ff0171723602040c0b0b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b024002400240024002400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d481042002200b3602c881042002200d3702cc8104200d422088a7210a4100210441002108024002400240024002400240034002402004411f4d0d00410f210b0c030b200a2001460d012001417f460d06200141016a2205200a4b0d05200b20016a2d00002103200220053602d48104200341ff00712004411f71742008722108200441076a2104200521012003418001710d000b024020044120490d00410d210b2003410f4b0d020b200241003602b001200242043703a80120080d02410421040c030b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241306a41086a200241e0006a41086a280200360200200220022903603703304105210b0b200241c0006a41086a200241306a41086a280200220136020020022002290330220d3703400c090b20022802ac01210620022802b001210c410021150340200241b8016a200241c881046a10ad0720022802c401211420022802c001211320022802bc01210b024002400240024002400240024002400240024002400240024002400240024002400240024020022802b8014101460d00200241b8016a200241c881046a10ad0720022802c401211020022802c001211820022802bc012116024002400240024020022802b8014101460d000240024002400240024020022802d08104220320022802d481042205460d00200541016a22012005490d0a20032001490d0b20022802c88104220720056a2d00002104200220013602d481040240200441034d0d00410921090c230b20040e0401020304010b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c200b410021124100210441002109034002402004411f4d0d00410f2109410021040c080b20032001460d062001417f460d0b2003200141016a220a490d12200720016a2d000021052002200a3602d48104200541ff00712004411f71742009722109200441076a2104200a21012005418001710d000b4100211220044120490d172005410f4d0d17410d2109410021040c060b0240024020032001460d00200541026a21042001417f460d0c20032004490d0d200720016a2c00002101200220043602d4810402402001417f4a0d00411921030c160b200141c00071450d14200141807f7222014170470d14200241b8016a200241c881046a10b00720022903c001210d20022802bc01210920022802b8014101470d0120022802c80121040c160b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10412002290360210d20022802682104410521030c140b410121120c180b200241b8016a200241c881046a10b00720022903c001210d20022802bc012109024020022802b8014101460d00410221120c180b200220022802c8013602c0012009411876210320094110762112200941087621040c140b0240024020032001460d00200541026a210a2001417f460d0c2003200a490d0d200720016a2c000021042002200a3602d481040240200441004e0d0041192109410021030c200b200441c000710d010c110b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a1041410521092002290264210e20022802602101410021030c1e0b200441807f72220441ff017141fb014d0d0f02402003200a460d00200541036a2101200a417f460d0d20032001490d0e2007200a6a2d00002105200220013602d481040240200541014d0d00410c2109200521040c1f0b2004417f73210a410321124100210320050e021702170b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c1c0b200220022802c80122013602c08104200220103602bc8104200220183602b881042016411876210320164110762112201641087621040c1d0b410121030c130b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a1041200228026021012002290264210e41052109410021040b410021030c190b20022802c8012101200220143602bc8104200220133602b88104200220063602ac012002200c3602b0010c1a0b417f200141c0fdcb001059000b2001200341c0fdcb001058000b417f200141016a41c0fdcb001059000b417f200441c0fdcb001059000b2004200341c0fdcb001058000b417f200a41c0fdcb001059000b200a200341c0fdcb001058000b417f200141c0fdcb001059000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b410621090c0d0b410721030b200141ff017141087420037221090b200220043602c0012009411876210320094110762112200941087621040b2002200d3703b80120022902bc01210e200da721010c090b0b0b200220143602bc8104200220133602b8810420022903b88104210e02400240200c2006460d0020062105200c21060c010b200641016a22012006490d11200641017422042001200420014b1bad42287e2223422088a70d112023a722014100480d1102400240024020060d0020010d01410421040c020b20022802a8012104200641286c22052001460d01024020050d0020010d01410421040c020b20042005200110372204450d170c010b200110332204450d160b200220043602a801200141286e21050b20022802a8012204200641286c6a220120123a00182001201636020c2001200e3702042001200b360200200141206a200d3702002001411c6a20093602002001411a6a20033a0000200141196a200a3a0000200141146a2010360200200141106a2018360200200641016a210c20052106201541016a22152008470d000b200220053602ac012002200c3602b0010b20022802d4810420022802d8810446210120022902ac012123024020022802cc8104450d0020022802c8810410350b024020010d002023a7210820024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360210d2002280268210102402023422088a72203450d00200341286c21052004210303400240200341046a280200450d00200328020010350b0240200341106a280200450d002003410c6a28020010350b200341286a2103200541586a22050d000b0b200d422088210e4105210b410021032008450d09200841286c450d09200410350c090b410321030c0c0b200141016a200a41c0fdcb001058000b417f200141016a41c0fdcb001059000b200d422088210e200b41087621030c050b200228026021012002290264210e410521090b200220013602b881042002200e3702bc8104200e422088a72101024020180d00200921160c010b20161035200921160b02402013450d00200b10350b2002200c3602b001200220063602ac012003411874201241ff017141107472200441ff017141087472201641ff017172210b0b20022903b88104210d20022802a80121050240200c450d00200c41286c21032005210403400240200441046a280200450d00200428020010350b0240200441106a280200450d002004410c6a28020010350b200441286a2104200341586a22030d000b0b2006450d00200641286c450d00200510350b200d422088210e200b410876210320022802cc8104450d0020022802c8810410350b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200b41ff0171723602040c0a0b200a41087621030b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200a41ff0171723602040c080b4100210141002104024002400240024002400240024002400340024020084105470d00410f21070c030b20032008460d01200320084d0d04200620086a2d0000220541ff00712001411f71742004722104200141076a2101200841016a220a21082005418001710d000b024020014120490d002005410f4d0d00410d21070c020b20040d024101211641002107410021054100210b0c070b200241013a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a1041200241306a41086a200241c881046a41086a280200360200200220022903c88104220d370330410521070b200d422088a7210520022802382101200da7210b0c030b200241b8016a4100418008109f081a4100210541002108410121164100210702400240024003402003200a6b200420076b22014180082001418008491b2201490d01200a20016a220c200a490d022003200c490d03200241b8016a2006200a6a2001109d081a02400240200820056b2001490d002008210b0c010b200520016a220a2005490d0c2008410174220b200a200b200a4b1b220b4100480d0c0240024020080d000240200b0d00410121160c020b200b103322160d010c120b2008200b460d0020162008200b10372216450d110b200b21080b201620056a200241b8016a2001109d081a200520016a2105200c210a2004200120076a22074d0d050c000b0b200241013a00b88104200241dc81046a4101360200200242013702cc8104200241acfdcb003602c881042002413636022c2002200241286a3602d881042002200241b881046a360228200241e0006a200241c881046a10412002290360220d422088a7210520022802682101200da7210b410521072008450d04201610350c040b200a200c41c0fdcb001059000b200c200341c0fdcb001058000b200841016a200341c0fdcb001058000b200241b8016a20162005107420022802b8014101470d01410821070240200b450d00201610350b0b2005ad422086200bad84210d2009450d03200610350c030b201641807e712107200c210a0b2003200a490d052003200a6b2203417f4c0d030240024020030d0041002104410121010c010b200310332201450d05200321040b0240024020042003490d00200421080c010b200441017422082003200820034b1b22084100480d03024020040d00200810332201450d080c010b20042008460d0020012004200810372201450d070b2007201641ff01717221042005ad422086200bad84212320012006200a6a2003109d081a2003ad4220862008ad84210d410121032009450d00200610350b200020033a000420004100360200200041056a20022f00153b0000200041186a200d370200200041146a20013602002000410c6a2023370200200041086a2004360200200041206a2002290200370200200041076a200241176a2d00003a0000200041286a200241086a290200370200200041306a200241106a2802003602000c060b2000200736020420004101360200200041106a2001360200200041086a200d3702000c050b103e000b1044000b1045000b200a20034188d9cb001059000b103c000b200241e081046a24000bdc0101057f024020002802082201450d00200028020022022001411c6c6a21030340024020022802042200450d0002402002410c6a2802002201450d00200141047421010340024020002d00004109470d000240200041046a2204280200220528020441ffffffff0371450d0020052802001035200428020021050b200510350b200041106a2100200141706a22010d000b0b200241086a28020041ffffffff0071450d00200228020410350b2002411c6a21000240200241146a28020041ffffffff0371450d00200228021010350b2000210220002003470d000b0b0bd90101057f024020002802082201450d0020002802002202200141186c6a210303400240200241046a28020041ffffffff0171450d00200228020010350b0240200241146a2802002201450d00200228020c2100200141047421010340024020002d00004109470d000240200041046a2204280200220528020441ffffffff0371450d0020052802001035200428020021050b200510350b200041106a2100200141706a22010d000b0b200241186a21000240200241106a28020041ffffffff0071450d00200228020c10350b2000210220002003470d000b0b0bd50101057f024020002802082201450d00200028020022022001411c6c6a21030340024020022802042200450d0002402002410c6a2802002201450d00200141047421010340024020002d00004109470d000240200041046a2204280200220528020441ffffffff0371450d0020052802001035200428020021050b200510350b200041106a2100200141706a22010d000b0b200241086a28020041ffffffff0071450d00200228020410350b2002411c6a21000240200241146a280200450d00200228021010350b2000210220002003470d000b0b0be40101047f0240200041206a28020022032000411c6a280200470d000240024002400240200341016a22042003490d00200341017422052004200520044b1b220620066a22042006490d0020044100480d00024020030d0020040d02410121030c040b2000280218210320052004460d03024020050d0020040d02410121030c040b20032005200410372203450d020c030b103e000b2004103322030d010b103c000b200020033602182000411c6a2004410176360200200028022021030b200028021820034101746a220320023a0001200320013a00002000200028022041016a3602200be70101037f0240200041386a2802002202200041346a280200470d000240024002400240200241016a22032002490d00200241017422042003200420034b1b220341ffffffff03712003470d00200341027422034100480d00024020020d0020030d02410421040c040b20002802302104200241027422022003460d03024020020d0020030d02410421040c040b20042002200310372204450d020c030b103e000b2003103322040d010b103c000b20002004360230200041346a2003410276360200200028023821020b200028023020024102746a20013602002000200028023841016a3602380b8d0302037f017e230041c0006b22022400200141086a28020021032001280204210420022001280200220136020002400240024002402001418080044b0d002004450d022002200336020402400240200120034b0d002003418080044d0d042002413c6a41013602002002420237022c200241e0aacc003602282002410136020c200241bcaacc003602082002200241086a360238200241186a200241286a1041200241186a21010c010b2002413c6a4102360200200241246a41013602002002420237022c200241d0aacc003602282002410136021c2002200241186a360238200220023602202002200241046a360218200241086a200241286a1041200241086a21010b20012902042105200128020021010c010b2002413c6a41013602002002420237022c200241c0aacc003602282002410136020c200241bcaacc003602082002200241086a360238200241186a200241286a104120022802182101200229021c21050b2001450d0020002005370204200020013602000c010b200041003602000b200241c0006a24000be00501037f230041f0006b2204240002400240024020012802084102460d00412e10332201450d01200041013a0000200141266a41002900d4ac4c370000200141206a41002900ceac4c370000200141186a41002900c6ac4c370000200141106a41002900beac4c370000200141086a41002900b6ac4c370000200141002900aeac4c370000200041086a42ae808080e005370200200041046a20013602000c020b0240024002400240024002400240200128020022052d0000416e6a2201411e4b0d004100210620010e1f03000000000000000000000000000000000000000000000000000006040102030b412010332201450d06200041013a0000200141186a41002900f4ac4c370000200141106a41002900ecac4c370000200141086a41002900e4ac4c370000200141002900dcac4c370000200041086a42a08080808004370200200041046a20013602000c070b410221060c040b410321060c030b20042005280204220136020c0240024020012003490d0041fcaccc002105200441e8006a2103200441d0006a2101200441c0006a21020c010b200220014101746a22012d0001450d02418cadcc002105200441386a2103200441206a2101200441106a21020b20034101360204200141146a410136020020012003360210200142023702042001200536020020032004410c6a360200200220011041200041013a00002000410c6a200241086a280200360200200041046a20022902003702000c040b410121060c010b20012d000021060b0240200541106a2d00004106470d00200041003a0000200020063a00010c020b412910332201450d00200041013a0000200141286a41002d00c4ad4c3a0000200141206a41002900bcad4c370000200141186a41002900b4ad4c370000200141106a41002900acad4c370000200141086a41002900a4ad4c3700002001410029009cad4c370000200041086a42a98080809005370200200041046a20013602000c010b1045000b200441f0006a24000b8f0201017f230041106b220224000240024002400240024020002d00000e0401020300010b200220012802184180fdcb0041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c030b200220012802184183fdcb0041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c020b200220012802184186fdcb0041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b200220012802184189fdcb0041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040b200241106a240020000bbb0101027f0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1b220241ffffffff01712002470d00200241037422024100480d00024020010d0020020d02410421030c040b20002802002103200141037422012002460d03024020010d0020020d02410421030c040b20032001200210372203450d020c030b103e000b2002103322030d010b103c000b20002003360200200041046a20024103763602000b0bbbcb0203047f017e057f230041a0016b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000eac0101cc0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa0100010b20034188016a200141186a2204200141286a410110f207024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dcb01200241017422062005200620054b1b22054100480dcb010240024020020d002005103322040d010cd2010b2004280200210420022005460d0020042002200510372204450dd1010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000ccd010b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450dcc012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dcc010ccb010b200328028c012201450dcb0120034190016a29030021070cca010b200141306a2802002202450da90102400240200241037420012802286a41786a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220820026b200420026b2209490d002001280218210a200221010c010b200220096a220a2002490dc9012008410174220b200a200b200a4b1b220b4100480dc9010240024020080d000240200b0d004101210a0c020b200b1033220a450dd0010c010b2001280218210a2008200b460d00200a2008200b1037220a450dcf010b2001200a3602182001411c6a200b360200200141206a28020021010b200a20016a21080240024020094102490d002008410420042002417f736a2202109f081a200a200220016a22016a21080c010b2009450d010b200841043a0000200141016a21010b20062001360200200541013a00060cca010b0240200141306a2802002204200141346a22052802004f0d002002310001422886200141206a350200842107024020042001412c6a280200470d00200141286a200410ba07200141306a28020021040b200128022820044103746a2007370200200141306a2201200128020041016a3602000cca010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc9012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dc90120002007370204200020013602000cca010b0240200141306a2802002204200141346a22052802004f0d002002310001422886200141206a35020084428080808030842107024020042001412c6a280200470d00200141286a200410ba07200141306a28020021040b200128022820044103746a2007370200200141306a2201200128020041016a3602000cc9010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc8012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dc80120002007370204200020013602000cc9010b2002310001210720034188016a200141186a200141286a2204410010f20720032d0088014101460da7010240200141306a2802002202200141346a22052802004f0d002007422886200141206a35020084428080808010842107024020022001412c6a280200470d002004200210ba07200141306a28020021020b200128022820024103746a2007370200200141306a2201200128020041016a3602000cc8010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc7012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dc70120002007370204200020013602000cc8010b200141306a2802002202450da70102400240200141286a22042802002002417f6a4103746a22022d00044101470d002002310005210720034188016a200141186a200410f307200328028801450d012000200329038801370200200041086a20034188016a41086a2802003602000cc9010b411a10332201450da901200141186a41002f00b0a54c3b0000200141106a41002900a8a54c370000200141086a41002900a0a54c37000020014100290098a54c3700002000429a808080a003370204200020013602000cc8010b0240200141306a2802002202200141346a22052802004f0d002007422886200141206a35020084428080808020842107024020022001412c6a280200470d002004200210ba07200141306a28020021020b200128022820024103746a2007370200200141306a2201200128020041016a3602000cc7010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc6012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dc60120002007370204200020013602000cc7010b200141306a2802002202450da8012002410374200141286a22062802006a2204417d6a220a2d0000210502402004417c6a2d00004101470d00200541ff01714104470daa010b02400240024002400240024020024101460d0020034188016a200141186a2202200610f3072003280288010d01200541ff01714104460dcb01200141206a2802002204200141246a22062802004f0d0520042001411c6a280200470d04200441016a22062004490dc8012004410174220a2006200a20064b1b22064100480dc80120040d02200610332202450dcd010c030b024020012d003822024104460d0020034188016a200141186a2006200210f407200328028801450d002000200329038801370200200041086a20034188016a41086a2802003602000ccc010b20034188016a200141186a200610f307200328028801450dca012000200329038801370200200041086a20034188016a41086a2802003602000ccb010b2000200329038801370200200041086a20034188016a41086a2802003602000cca010b2002280200210220042006460d0020022004200610372202450dca010b200120023602182001411c6a2006360200200141206a28020021040b200128021820046a20053a0000200141206a2201200128020041016a3602000cc6010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320063602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc5012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dc50120002007370204200020013602000cc6010b2003200241046a2802002202360278024002400240200141306a280200220420024d0d0020042002417f736a220220044f0dac01200141286a220428020020024103746a22022d00044103460d0220022d0005220241ff01714104460d0220034188016a200141186a2004200210f4072003280288012202450d02200329028c0121070c010b2003419c016a22024102360200200341cc006a41013602002003420237028c0120034198b0cc003602880120034101360244200320043602302003200341c0006a360298012003200341306a3602482003200341f8006a360240200341e8006a20034188016a1041200328026821042003200329026c37026c20032004360268200241013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402102200329024421070240200328026c450d00200328026810350b2002450d010b20002007370204200020023602000cc6010b200141306a2802002202450daa0102400240200241037420012802286a41786a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220820026b200420026b2209490d002001280218210a200221010c010b200220096a220a2002490dc3012008410174220b200a200b200a4b1b220b4100480dc3010240024020080d000240200b0d004101210a0c020b200b1033220a450dca010c010b2001280218210a2008200b460d00200a2008200b1037220a450dc9010b2001200a3602182001411c6a200b360200200141206a28020021010b200a20016a21080240024020094102490d002008410420042002417f736a2202109f081a200a200220016a22016a21080c010b2009450d010b200841043a0000200141016a21010b20062001360200200541013a00060cc4010b200241046a280200210220034188016a200141186a2205200141286a2204410010f20702400240024020032d0088014101460d00200141306a2802002101200320023602780240200120024d0d0020012002417f736a220220014f0db401200428020020024103746a22012d00044103460dc70120012d0005220141ff01714104460dc70120034188016a20052004200110f4072003280288012201450dc701200329028c0121070c030b2003419c016a22024102360200200341cc006a41013602002003420237028c0120034198b0cc003602880120034101360244200320013602302003200341c0006a360298012003200341306a3602482003200341f8006a360240200341e8006a20034188016a1041200328026821012003200329026c37026c20032001360268200241013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a10412003280240210120032902442107200328026c450d01200328026810350c010b20034190016a2903002107200328028c0121010b2001450dc4010b20002007370204200020013602000cc4010b200241046a2802002202280204210620022802002104200320022802082205360278200141306a280200220220054d0dbd0120022005417f736a220520024f0da901410421080240200141286a220c280200220a20054103746a22052d00044103460d0020052d000521080b200320083a00602006450db701200841ff0171220b4104460db601200641027421060340200320042802002205360278200220054d0db90120022005417f736a220520024f0dc101200a20054103746a22052d00044103460dba0120052d000522094104460dba01200b2009470dba01200441046a21042006417c6a22060d000cb8010b0b024020012d003822024104460d0020034188016a200141186a200141286a200210f407200328028801450d002000200329038801370200200041086a20034188016a41086a2802003602000cc3010b200141306a2802002202450da90102400240200241037420012802286a41786a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220820026b200420026b2209490d002001280218210a200221010c010b200220096a220a2002490dc0012008410174220b200a200b200a4b1b220b4100480dc0010240024020080d000240200b0d004101210a0c020b200b1033220a450dc7010c010b2001280218210a2008200b460d00200a2008200b1037220a450dc6010b2001200a3602182001411c6a200b360200200141206a28020021010b200a20016a21080240024020094102490d002008410420042002417f736a2202109f081a200a200220016a22016a21080c010b2009450d010b200841043a0000200141016a21010b20062001360200200541013a00060cc1010b200128020021042003200241046a280200220236028401024002400240024002400240024002400240200441386a28020020024d0d002003200428023020024102746a2802002202360230024002402004412c6a28020020024d0d00200341cc006a200428022420024104746a22042d000d220a3a0000200341c8006a2004280208220236020020042802002104410021050c010b410121052003419c016a41013602002003420237028c01200341f0aecc00360288012003410136027c2003200341f8006a360298012003200341306a360278200341e8006a20034188016a1041200341c8006a200329026c22073703002007422088a7210a200328026821042007a721020b200320053602402003200436024420050d0102402002450d002004417f6a2104200141286a2105200141186a2106034020034188016a20062005200420026a2d000010f20720032d0088014101460d082002417f6a22020d000b0b200a41ff01714104460dc901200141206a2802002202200141246a22042802004f0d0520022001411c6a280200470d04200241016a22042002490dc601200241017422052004200520044b1b22044100480dc60120020d02200410332205450dcb010c030b2003419c016a41013602002003420237028c01200341ccaecc0036028801200341013602642003200341e0006a36029801200320034184016a360260200341e8006a20034188016a1041200341c8006a200329026c370300200341013602402003200328026822043602440b200341c8006a21010c050b2001280218210520022004460d0020052002200410372205450dc8010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a200a3a0000200141206a2201200128020041016a3602000cc4010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc3012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402104200329024421070240200328026c450d00200328026810350b20040d020cc3010b20034190016a2101200328028c0121040b2004450dc101200129020021070b20002007370204200020043602000cc1010b200241046a28020021062001280200210220034100360268200241146a280200450da80120034188016a200141186a2204200141286a2205410010f20720032d0088014101460da9012001280200220a412c6a28020021022003200636026802400240024002400240200220064d0d00200a28022420064104746a22062d000d210a024020062802082202450d002006280200417f6a2106034020034188016a20042005200620026a2d000010f20720032d0088014101460db1012002417f6a22020d000b0b200a41ff01714104460dc401200141206a2802002202200141246a22052802004f0d0420022001411c6a280200470d03200241016a22052002490dc101200241017422062005200620054b1b22054100480dc10120020d01200510332204450dc6010c020b2003419c016a41013602002003420237028c01200341f0aecc0036028801200341013602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a10410cb5010b2004280200210420022005460d0020042002200510372204450dc4010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a200a3a0000200141206a2201200128020041016a3602000cc0010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dbf012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a10412003280240210120032902442107200328026c450db201200328026810350cb2010b20034188016a200141186a200141286a410410f20720032d0088014101470dbe01200328028c012201450dbe01200020034190016a290300370204200020013602000cbf010b20034188016a200141186a2204200141286a2205410010f20720034188016a21020240024020032d0088014101460d0020034188016a20042005410410f20720034188016a210220032d0088014101460d0020034188016a2004200520032d008901220610f20720034188016a210220032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dbe012002410174220a2005200a20054b1b22054100480dbe010240024020020d00200510332204450dc5010c010b2004280200210420022005460d0020042002200510372204450dc4010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a20063a0000200141206a2201200128020041016a3602000cc0010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dbf012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010cbf010b200241046a2802002201450dbe01200241086a29020021070b20002007370204200020013602000cbe010b20034188016a200141046a200241046a28020010f5070240024020032d0088014101460d000240200141206a2802002202200141246a22042802004f0d0020032d0089012104024020022001411c6a280200470d00200241016a22052002490dbd01200241017422062005200620054b1b22054100480dbd010240024020020d00200510332206450dc4010c010b2001280218210620022005460d0020062002200510372206450dc3010b200120063602182001411c6a2005360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cbf010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450dbe012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010cbe010b200328028c012201450dbd0120034190016a29030021070b20002007370204200020013602000cbd010b2003200241046a280200220236023020034188016a200141046a200210f5070240024020032d0088014101460d00200320032d00890122023a006020034188016a200141186a200141286a410410f2070240024020032d0088014101460d00200320032d00890122013a007820014104460dbf01200241ff01712001460dbf01200341c0006a41146a413d360200200341cc006a413736020020034188016a41146a41033602002003420337028c01200341d4a5cc0036028801200341013602442003200341c0006a360298012003200341f8006a3602502003200341e0006a3602482003200341306a360240200341e8006a20034188016a10410c010b200341f0006a20034194016a2802003602002003200329028c013703680b200329026c2107200328026821010c010b2003200328028c012201360268200320034190016a290300220737026c0b2001450dbb0120002007370204200020013602000cbc010b20034188016a200141046a200241046a28020010f5070240024020032d0088014101460d0020034188016a200141186a200141286a20032d00890110f4072003280288012201450dbc01200329028c0121070c010b200328028c012201450dbb0120034190016a29030021070b20002007370204200020013602000cbb010b200128020021042003200241046a280200220236026802400240200441206a28020020024d0d000240200141206a2802002205200141246a22062802004f0d00200428021820024101746a2d00002102024020052001411c6a280200470d00200541016a22042005490dba01200541017422062004200620044b1b22044100480dba010240024020050d00200410332206450dc1010c010b2001280218210620052004460d0020062005200410372206450dc0010b200120063602182001411c6a2004360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000cbc010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320063602302003200341306a36029801200341c0006a20034188016a104120032802402202450dbb012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010cbb010b2003419c016a41013602002003420237028c0120034190afcc00360288012003410136027c2003200341f8006a360298012003200341e8006a360278200341c0006a20034188016a104120032802402201450dba01200329024421070b20002007370204200020013602000cba010b2003200241046a2802002202360258200128020021042003200236028401024002400240200441206a28020020024d0d00200428021820024101746a22022d00010d022003419c016a41013602002003420237028c01200341a0afcc0036028801200341013602342003200341306a36029801200320034184016a360230200341c0006a20034188016a10410c010b2003419c016a41013602002003420237028c0120034190afcc00360288012003410136027c2003200341f8006a36029801200320034184016a360278200341c0006a20034188016a10410b2003280240210120032003290244220737026c200320013602680caa010b200320022d000022023a005f20034188016a200141186a200141286a410410f20720032d0088014101470da701200341f0006a20034194016a2802003602002003200329028c013703680ca8010b20034188016a2001200241046a2802004104410010f707200328028801450db7012000200329038801370200200041086a20034188016a41086a2802003602000cb8010b20034188016a2001200241046a2802004108410110f707200328028801450db6012000200329038801370200200041086a20034188016a41086a2802003602000cb7010b20034188016a2001200241046a2802004104410210f707200328028801450db5012000200329038801370200200041086a20034188016a41086a2802003602000cb6010b20034188016a2001200241046a2802004108410310f707200328028801450db4012000200329038801370200200041086a20034188016a41086a2802003602000cb5010b20034188016a2001200241046a2802004101410010f707200328028801450db3012000200329038801370200200041086a20034188016a41086a2802003602000cb4010b20034188016a2001200241046a2802004101410010f707200328028801450db2012000200329038801370200200041086a20034188016a41086a2802003602000cb3010b20034188016a2001200241046a2802004102410010f707200328028801450db1012000200329038801370200200041086a20034188016a41086a2802003602000cb2010b20034188016a2001200241046a2802004102410010f707200328028801450db0012000200329038801370200200041086a20034188016a41086a2802003602000cb1010b20034188016a2001200241046a2802004101410110f707200328028801450daf012000200329038801370200200041086a20034188016a41086a2802003602000cb0010b20034188016a2001200241046a2802004101410110f707200328028801450dae012000200329038801370200200041086a20034188016a41086a2802003602000caf010b20034188016a2001200241046a2802004102410110f707200328028801450dad012000200329038801370200200041086a20034188016a41086a2802003602000cae010b20034188016a2001200241046a2802004102410110f707200328028801450dac012000200329038801370200200041086a20034188016a41086a2802003602000cad010b20034188016a2001200241046a2802004104410110f707200328028801450dab012000200329038801370200200041086a20034188016a41086a2802003602000cac010b20034188016a2001200241046a2802004104410110f707200328028801450daa012000200329038801370200200041086a20034188016a41086a2802003602000cab010b20034188016a2001200241046a2802004104410010f807200328028801450da9012000200329038801370200200041086a20034188016a41086a2802003602000caa010b20034188016a2001200241046a2802004108410110f807200328028801450da8012000200329038801370200200041086a20034188016a41086a2802003602000ca9010b20034188016a2001200241046a2802004104410210f807200328028801450da7012000200329038801370200200041086a20034188016a41086a2802003602000ca8010b20034188016a2001200241046a2802004108410310f807200328028801450da6012000200329038801370200200041086a20034188016a41086a2802003602000ca7010b20034188016a2001200241046a2802004101410010f807200328028801450da5012000200329038801370200200041086a20034188016a41086a2802003602000ca6010b20034188016a2001200241046a2802004102410010f807200328028801450da4012000200329038801370200200041086a20034188016a41086a2802003602000ca5010b20034188016a2001200241046a2802004101410110f807200328028801450da3012000200329038801370200200041086a20034188016a41086a2802003602000ca4010b20034188016a2001200241046a2802004102410110f807200328028801450da2012000200329038801370200200041086a20034188016a41086a2802003602000ca3010b20034188016a2001200241046a2802004104410110f807200328028801450da1012000200329038801370200200041086a20034188016a41086a2802003602000ca2010b20012802002102200341003602680240024020022802080d002003419c016a41013602002003420237028c01200341fcadcc0036028801200341013602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402202450d00200329024421070c010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490da001200241017422052004200520044b1b22044100480da0010240024020020d00200410332205450da7010c010b2001280218210520022004460d0020052002200410372205450da6010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000ca2010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450da1012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402102200329024421070240200328026c450d00200328026810350b2002450da1010b20002007370204200020023602000ca1010b20012802002102200341003602680240024020022802080d002003419c016a41013602002003420237028c01200341fcadcc0036028801200341013602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402202450d00200329024421070c010b20034188016a200141186a2204200141286a410010f207024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490da001200241017422062005200620054b1b22054100480da0010240024020020d00200510332204450da7010c010b2004280200210420022005460d0020042002200510372204450da6010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000ca2010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450da1012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402102200329024421070240200328026c450d00200328026810350b20020d010ca1010b200328028c012202450da00120034190016a29030021070b20002007370204200020023602000ca0010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490d9d01200241017422052004200520044b1b22044100480d9d010240024020020d00200410332205450da4010c010b2001280218210520022004460d0020052002200410372205450da3010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c9f010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450d9e012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450d9e0120002007370204200020013602000c9f010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490d9c01200241017422052004200520044b1b22044100480d9c010240024020020d00200410332205450da3010c010b2001280218210520022004460d0020052002200410372205450da2010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c9e010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450d9d012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450d9d0120002007370204200020013602000c9e010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490d9b01200241017422052004200520044b1b22044100480d9b010240024020020d00200410332205450da2010c010b2001280218210520022004460d0020052002200410372205450da1010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c9d010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450d9c012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450d9c0120002007370204200020013602000c9d010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490d9a01200241017422052004200520044b1b22044100480d9a010240024020020d00200410332205450da1010c010b2001280218210520022004460d0020052002200410372205450da0010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c9c010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450d9b012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450d9b0120002007370204200020013602000c9c010b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d9b01200241017422062005200620054b1b22054100480d9b010240024020020d00200510332204450da2010c010b2004280200210420022005460d0020042002200510372204450da1010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c9d010b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d9c012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c9c010b200328028c012201450d9b0120034190016a29030021070b20002007370204200020013602000c9b010b20034188016a2001410010f907200328028801450d99012000200329038801370200200041086a20034188016a41086a2802003602000c9a010b20034188016a2001410010f907200328028801450d98012000200329038801370200200041086a20034188016a41086a2802003602000c99010b20034188016a2001410010f907200328028801450d97012000200329038801370200200041086a20034188016a41086a2802003602000c98010b20034188016a2001410010f907200328028801450d96012000200329038801370200200041086a20034188016a41086a2802003602000c97010b20034188016a2001410010f907200328028801450d95012000200329038801370200200041086a20034188016a41086a2802003602000c96010b20034188016a2001410010f907200328028801450d94012000200329038801370200200041086a20034188016a41086a2802003602000c95010b20034188016a2001410010f907200328028801450d93012000200329038801370200200041086a20034188016a41086a2802003602000c94010b20034188016a2001410010f907200328028801450d92012000200329038801370200200041086a20034188016a41086a2802003602000c93010b20034188016a2001410010f907200328028801450d91012000200329038801370200200041086a20034188016a41086a2802003602000c92010b20034188016a2001410010f907200328028801450d90012000200329038801370200200041086a20034188016a41086a2802003602000c91010b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d9001200241017422062005200620054b1b22054100480d90010240024020020d00200510332204450d97010c010b2004280200210420022005460d0020042002200510372204450d96010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c92010b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d91012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c91010b200328028c012201450d900120034190016a29030021070b20002007370204200020013602000c90010b20034188016a2001410110f907200328028801450d8e012000200329038801370200200041086a20034188016a41086a2802003602000c8f010b20034188016a2001410110f907200328028801450d8d012000200329038801370200200041086a20034188016a41086a2802003602000c8e010b20034188016a2001410110f907200328028801450d8c012000200329038801370200200041086a20034188016a41086a2802003602000c8d010b20034188016a2001410110f907200328028801450d8b012000200329038801370200200041086a20034188016a41086a2802003602000c8c010b20034188016a2001410110f907200328028801450d8a012000200329038801370200200041086a20034188016a41086a2802003602000c8b010b20034188016a2001410110f907200328028801450d89012000200329038801370200200041086a20034188016a41086a2802003602000c8a010b20034188016a2001410110f907200328028801450d88012000200329038801370200200041086a20034188016a41086a2802003602000c89010b20034188016a2001410110f907200328028801450d87012000200329038801370200200041086a20034188016a41086a2802003602000c88010b20034188016a2001410110f907200328028801450d86012000200329038801370200200041086a20034188016a41086a2802003602000c87010b20034188016a2001410110f907200328028801450d85012000200329038801370200200041086a20034188016a41086a2802003602000c86010b20034188016a2001410210f907200328028801450d84012000200329038801370200200041086a20034188016a41086a2802003602000c85010b20034188016a2001410210f907200328028801450d83012000200329038801370200200041086a20034188016a41086a2802003602000c84010b20034188016a2001410210f907200328028801450d82012000200329038801370200200041086a20034188016a41086a2802003602000c83010b20034188016a2001410210f907200328028801450d81012000200329038801370200200041086a20034188016a41086a2802003602000c82010b20034188016a2001410210f907200328028801450d80012000200329038801370200200041086a20034188016a41086a2802003602000c81010b20034188016a2001410210f907200328028801450d7f2000200329038801370200200041086a20034188016a41086a2802003602000c80010b20034188016a2001410310f907200328028801450d7e2000200329038801370200200041086a20034188016a41086a2802003602000c7f0b20034188016a2001410310f907200328028801450d7d2000200329038801370200200041086a20034188016a41086a2802003602000c7e0b20034188016a2001410310f907200328028801450d7c2000200329038801370200200041086a20034188016a41086a2802003602000c7d0b20034188016a2001410310f907200328028801450d7b2000200329038801370200200041086a20034188016a41086a2802003602000c7c0b20034188016a2001410310f907200328028801450d7a2000200329038801370200200041086a20034188016a41086a2802003602000c7b0b20034188016a2001410310f907200328028801450d792000200329038801370200200041086a20034188016a41086a2802003602000c7a0b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d79200241017422062005200620054b1b22054100480d790240024020020d00200510332204450d80010c010b2004280200210420022005460d0020042002200510372204450d7f0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c7b0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d7a2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c7a0b200328028c012201450d7920034190016a29030021070b20002007370204200020013602000c790b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d78200241017422062005200620054b1b22054100480d780240024020020d00200510332204450d7f0c010b2004280200210420022005460d0020042002200510372204450d7e0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c7a0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d792003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c790b200328028c012201450d7820034190016a29030021070b20002007370204200020013602000c780b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d77200241017422062005200620054b1b22054100480d770240024020020d00200510332204450d7e0c010b2004280200210420022005460d0020042002200510372204450d7d0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c790b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d782003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c780b200328028c012201450d7720034190016a29030021070b20002007370204200020013602000c770b20034188016a2001410010fa07200328028801450d752000200329038801370200200041086a20034188016a41086a2802003602000c760b20034188016a2001410010fa07200328028801450d742000200329038801370200200041086a20034188016a41086a2802003602000c750b20034188016a2001410010fa07200328028801450d732000200329038801370200200041086a20034188016a41086a2802003602000c740b20034188016a2001410010fa07200328028801450d722000200329038801370200200041086a20034188016a41086a2802003602000c730b20034188016a2001410010fa07200328028801450d712000200329038801370200200041086a20034188016a41086a2802003602000c720b20034188016a2001410010fa07200328028801450d702000200329038801370200200041086a20034188016a41086a2802003602000c710b20034188016a2001410010fa07200328028801450d6f2000200329038801370200200041086a20034188016a41086a2802003602000c700b20034188016a2001410010fa07200328028801450d6e2000200329038801370200200041086a20034188016a41086a2802003602000c6f0b20034188016a2001410010fa07200328028801450d6d2000200329038801370200200041086a20034188016a41086a2802003602000c6e0b20034188016a2001410010fa07200328028801450d6c2000200329038801370200200041086a20034188016a41086a2802003602000c6d0b20034188016a2001410010fa07200328028801450d6b2000200329038801370200200041086a20034188016a41086a2802003602000c6c0b20034188016a2001410010fa07200328028801450d6a2000200329038801370200200041086a20034188016a41086a2802003602000c6b0b20034188016a2001410010fa07200328028801450d692000200329038801370200200041086a20034188016a41086a2802003602000c6a0b20034188016a2001410010fa07200328028801450d682000200329038801370200200041086a20034188016a41086a2802003602000c690b20034188016a2001410010fa07200328028801450d672000200329038801370200200041086a20034188016a41086a2802003602000c680b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d67200241017422062005200620054b1b22054100480d670240024020020d00200510332204450d6e0c010b2004280200210420022005460d0020042002200510372204450d6d0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c690b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d682003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c680b200328028c012201450d6720034190016a29030021070b20002007370204200020013602000c670b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d66200241017422062005200620054b1b22054100480d660240024020020d00200510332204450d6d0c010b2004280200210420022005460d0020042002200510372204450d6c0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c680b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d672003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c670b200328028c012201450d6620034190016a29030021070b20002007370204200020013602000c660b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d65200241017422062005200620054b1b22054100480d650240024020020d00200510332204450d6c0c010b2004280200210420022005460d0020042002200510372204450d6b0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c670b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d662003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c660b200328028c012201450d6520034190016a29030021070b20002007370204200020013602000c650b20034188016a2001410110fa07200328028801450d632000200329038801370200200041086a20034188016a41086a2802003602000c640b20034188016a2001410110fa07200328028801450d622000200329038801370200200041086a20034188016a41086a2802003602000c630b20034188016a2001410110fa07200328028801450d612000200329038801370200200041086a20034188016a41086a2802003602000c620b20034188016a2001410110fa07200328028801450d602000200329038801370200200041086a20034188016a41086a2802003602000c610b20034188016a2001410110fa07200328028801450d5f2000200329038801370200200041086a20034188016a41086a2802003602000c600b20034188016a2001410110fa07200328028801450d5e2000200329038801370200200041086a20034188016a41086a2802003602000c5f0b20034188016a2001410110fa07200328028801450d5d2000200329038801370200200041086a20034188016a41086a2802003602000c5e0b20034188016a2001410110fa07200328028801450d5c2000200329038801370200200041086a20034188016a41086a2802003602000c5d0b20034188016a2001410110fa07200328028801450d5b2000200329038801370200200041086a20034188016a41086a2802003602000c5c0b20034188016a2001410110fa07200328028801450d5a2000200329038801370200200041086a20034188016a41086a2802003602000c5b0b20034188016a2001410110fa07200328028801450d592000200329038801370200200041086a20034188016a41086a2802003602000c5a0b20034188016a2001410110fa07200328028801450d582000200329038801370200200041086a20034188016a41086a2802003602000c590b20034188016a2001410110fa07200328028801450d572000200329038801370200200041086a20034188016a41086a2802003602000c580b20034188016a2001410110fa07200328028801450d562000200329038801370200200041086a20034188016a41086a2802003602000c570b20034188016a2001410110fa07200328028801450d552000200329038801370200200041086a20034188016a41086a2802003602000c560b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d55200241017422062005200620054b1b22054100480d550240024020020d00200510332204450d5c0c010b2004280200210420022005460d0020042002200510372204450d5b0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c570b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d562003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c560b200328028c012201450d5520034190016a29030021070b20002007370204200020013602000c550b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d54200241017422062005200620054b1b22054100480d540240024020020d00200510332204450d5b0c010b2004280200210420022005460d0020042002200510372204450d5a0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c560b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d552003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c550b200328028c012201450d5420034190016a29030021070b20002007370204200020013602000c540b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d53200241017422062005200620054b1b22054100480d530240024020020d00200510332204450d5a0c010b2004280200210420022005460d0020042002200510372204450d590b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c550b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d542003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c540b200328028c012201450d5320034190016a29030021070b20002007370204200020013602000c530b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d52200241017422062005200620054b1b22054100480d520240024020020d00200510332204450d590c010b2004280200210420022005460d0020042002200510372204450d580b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c540b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d532003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c530b200328028c012201450d5220034190016a29030021070b20002007370204200020013602000c520b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d51200241017422062005200620054b1b22054100480d510240024020020d00200510332204450d580c010b2004280200210420022005460d0020042002200510372204450d570b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c530b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d522003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c520b200328028c012201450d5120034190016a29030021070b20002007370204200020013602000c510b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d50200241017422062005200620054b1b22054100480d500240024020020d00200510332204450d570c010b2004280200210420022005460d0020042002200510372204450d560b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c520b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d512003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c510b200328028c012201450d5020034190016a29030021070b20002007370204200020013602000c500b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d4f200241017422062005200620054b1b22054100480d4f0240024020020d00200510332204450d560c010b2004280200210420022005460d0020042002200510372204450d550b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c510b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d502003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c500b200328028c012201450d4f20034190016a29030021070b20002007370204200020013602000c4f0b20034188016a2001410210fa07200328028801450d4d2000200329038801370200200041086a20034188016a41086a2802003602000c4e0b20034188016a2001410210fa07200328028801450d4c2000200329038801370200200041086a20034188016a41086a2802003602000c4d0b20034188016a2001410210fa07200328028801450d4b2000200329038801370200200041086a20034188016a41086a2802003602000c4c0b20034188016a2001410210fa07200328028801450d4a2000200329038801370200200041086a20034188016a41086a2802003602000c4b0b20034188016a2001410210fa07200328028801450d492000200329038801370200200041086a20034188016a41086a2802003602000c4a0b20034188016a2001410210fa07200328028801450d482000200329038801370200200041086a20034188016a41086a2802003602000c490b20034188016a2001410210fa07200328028801450d472000200329038801370200200041086a20034188016a41086a2802003602000c480b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d47200241017422062005200620054b1b22054100480d470240024020020d00200510332204450d4e0c010b2004280200210420022005460d0020042002200510372204450d4d0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c490b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d482003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c480b200328028c012201450d4720034190016a29030021070b20002007370204200020013602000c470b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d46200241017422062005200620054b1b22054100480d460240024020020d00200510332204450d4d0c010b2004280200210420022005460d0020042002200510372204450d4c0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c480b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d472003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c470b200328028c012201450d4620034190016a29030021070b20002007370204200020013602000c460b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d45200241017422062005200620054b1b22054100480d450240024020020d00200510332204450d4c0c010b2004280200210420022005460d0020042002200510372204450d4b0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c470b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d462003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c460b200328028c012201450d4520034190016a29030021070b20002007370204200020013602000c450b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d44200241017422062005200620054b1b22054100480d440240024020020d00200510332204450d4b0c010b2004280200210420022005460d0020042002200510372204450d4a0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c460b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d452003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c450b200328028c012201450d4420034190016a29030021070b20002007370204200020013602000c440b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d43200241017422062005200620054b1b22054100480d430240024020020d00200510332204450d4a0c010b2004280200210420022005460d0020042002200510372204450d490b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c450b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d442003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c440b200328028c012201450d4320034190016a29030021070b20002007370204200020013602000c430b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d42200241017422062005200620054b1b22054100480d420240024020020d00200510332204450d490c010b2004280200210420022005460d0020042002200510372204450d480b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c440b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d432003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c430b200328028c012201450d4220034190016a29030021070b20002007370204200020013602000c420b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d41200241017422062005200620054b1b22054100480d410240024020020d00200510332204450d480c010b2004280200210420022005460d0020042002200510372204450d470b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c430b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d422003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c420b200328028c012201450d4120034190016a29030021070b20002007370204200020013602000c410b20034188016a2001410310fa07200328028801450d3f2000200329038801370200200041086a20034188016a41086a2802003602000c400b20034188016a2001410310fa07200328028801450d3e2000200329038801370200200041086a20034188016a41086a2802003602000c3f0b20034188016a2001410310fa07200328028801450d3d2000200329038801370200200041086a20034188016a41086a2802003602000c3e0b20034188016a2001410310fa07200328028801450d3c2000200329038801370200200041086a20034188016a41086a2802003602000c3d0b20034188016a2001410310fa07200328028801450d3b2000200329038801370200200041086a20034188016a41086a2802003602000c3c0b20034188016a2001410310fa07200328028801450d3a2000200329038801370200200041086a20034188016a41086a2802003602000c3b0b20034188016a2001410310fa07200328028801450d392000200329038801370200200041086a20034188016a41086a2802003602000c3a0b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d39200241017422062005200620054b1b22054100480d390240024020020d00200510332204450d400c010b2004280200210420022005460d0020042002200510372204450d3f0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c3b0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d3a2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c3a0b200328028c012201450d3920034190016a29030021070b20002007370204200020013602000c390b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d38200241017422062005200620054b1b22054100480d380240024020020d00200510332204450d3f0c010b2004280200210420022005460d0020042002200510372204450d3e0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c3a0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d392003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c390b200328028c012201450d3820034190016a29030021070b20002007370204200020013602000c380b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d37200241017422062005200620054b1b22054100480d370240024020020d00200510332204450d3e0c010b2004280200210420022005460d0020042002200510372204450d3d0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c390b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d382003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c380b200328028c012201450d3720034190016a29030021070b20002007370204200020013602000c370b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d36200241017422062005200620054b1b22054100480d360240024020020d00200510332204450d3d0c010b2004280200210420022005460d0020042002200510372204450d3c0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c380b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d372003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c370b200328028c012201450d3620034190016a29030021070b20002007370204200020013602000c360b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d35200241017422062005200620054b1b22054100480d350240024020020d00200510332204450d3c0c010b2004280200210420022005460d0020042002200510372204450d3b0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c370b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d362003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c360b200328028c012201450d3520034190016a29030021070b20002007370204200020013602000c350b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d34200241017422062005200620054b1b22054100480d340240024020020d00200510332204450d3b0c010b2004280200210420022005460d0020042002200510372204450d3a0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c360b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d352003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c350b200328028c012201450d3420034190016a29030021070b20002007370204200020013602000c340b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d33200241017422062005200620054b1b22054100480d330240024020020d00200510332204450d3a0c010b2004280200210420022005460d0020042002200510372204450d390b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c350b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d342003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c340b200328028c012201450d3320034190016a29030021070b20002007370204200020013602000c330b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d21200241017422062005200620054b1b22054100480d210240024020020d002005103322040d010c250b2004280200210420022005460d0020042002200510372204450d240b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c340b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d332003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c330b200328028c012201450d3220034190016a29030021070b20002007370204200020013602000c320b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d20200241017422062005200620054b1b22054100480d200240024020020d00200510332204450d240c010b2004280200210420022005460d0020042002200510372204450d230b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c330b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d322003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c320b200328028c012201450d3120034190016a29030021070b20002007370204200020013602000c310b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1f200241017422062005200620054b1b22054100480d1f0240024020020d00200510332204450d230c010b2004280200210420022005460d0020042002200510372204450d220b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c320b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d312003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c310b200328028c012201450d3020034190016a29030021070b20002007370204200020013602000c300b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1e200241017422062005200620054b1b22054100480d1e0240024020020d00200510332204450d220c010b2004280200210420022005460d0020042002200510372204450d210b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c310b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d302003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c300b200328028c012201450d2f20034190016a29030021070b20002007370204200020013602000c2f0b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1d200241017422062005200620054b1b22054100480d1d0240024020020d00200510332204450d210c010b2004280200210420022005460d0020042002200510372204450d200b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c300b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2f2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2f0b200328028c012201450d2e20034190016a29030021070b20002007370204200020013602000c2e0b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1c200241017422062005200620054b1b22054100480d1c0240024020020d00200510332204450d200c010b2004280200210420022005460d0020042002200510372204450d1f0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c2f0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2e2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2e0b200328028c012201450d2d20034190016a29030021070b20002007370204200020013602000c2d0b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1b200241017422062005200620054b1b22054100480d1b0240024020020d00200510332204450d1f0c010b2004280200210420022005460d0020042002200510372204450d1e0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c2e0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2d2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2d0b200328028c012201450d2c20034190016a29030021070b20002007370204200020013602000c2c0b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1a200241017422062005200620054b1b22054100480d1a0240024020020d00200510332204450d1e0c010b2004280200210420022005460d0020042002200510372204450d1d0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c2d0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2c2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2c0b200328028c012201450d2b20034190016a29030021070b20002007370204200020013602000c2b0b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d19200241017422062005200620054b1b22054100480d190240024020020d00200510332204450d1d0c010b2004280200210420022005460d0020042002200510372204450d1c0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c2c0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2b2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2b0b200328028c012201450d2a20034190016a29030021070b20002007370204200020013602000c2a0b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d18200241017422062005200620054b1b22054100480d180240024020020d00200510332204450d1c0c010b2004280200210420022005460d0020042002200510372204450d1b0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c2b0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2a2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2a0b200328028c012201450d2920034190016a29030021070b20002007370204200020013602000c290b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d17200241017422062005200620054b1b22054100480d170240024020020d00200510332204450d1b0c010b2004280200210420022005460d0020042002200510372204450d1a0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c2a0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d292003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c290b200328028c012201450d2820034190016a29030021070b20002007370204200020013602000c280b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d16200241017422062005200620054b1b22054100480d160240024020020d00200510332204450d1a0c010b2004280200210420022005460d0020042002200510372204450d190b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c290b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d282003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c280b200328028c012201450d2720034190016a29030021070b20002007370204200020013602000c270b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d15200241017422062005200620054b1b22054100480d150240024020020d00200510332204450d190c010b2004280200210420022005460d0020042002200510372204450d180b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c280b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d272003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c270b200328028c012201450d2620034190016a29030021070b20002007370204200020013602000c260b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d14200241017422062005200620054b1b22054100480d140240024020020d00200510332204450d180c010b2004280200210420022005460d0020042002200510372204450d170b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c270b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d262003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c260b200328028c012201450d2520034190016a29030021070b20002007370204200020013602000c250b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d13200241017422062005200620054b1b22054100480d130240024020020d00200510332204450d170c010b2004280200210420022005460d0020042002200510372204450d160b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c260b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d252003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c250b200328028c012201450d2420034190016a29030021070b20002007370204200020013602000c240b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d12200241017422062005200620054b1b22054100480d120240024020020d00200510332204450d160c010b2004280200210420022005460d0020042002200510372204450d150b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c250b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d242003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c240b200328028c012201450d2320034190016a29030021070b20002007370204200020013602000c230b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d11200241017422062005200620054b1b22054100480d110240024020020d00200510332204450d150c010b2004280200210420022005460d0020042002200510372204450d140b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c240b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d232003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c230b200328028c012201450d2220034190016a29030021070b20002007370204200020013602000c220b2003411810fb072003410036029001200320032903003703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141f7a3cc00413b20034188016a41b4a4cc0041c4a4cc001046000b2000200329028c01370200200041086a20034194016a2802003602000c200b200341086a411810fb072003410036029001200320032903083703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141d4a4cc00413420034188016a41b4a4cc004188a5cc001046000b1045000b200341106a411810fb072003410036029001200320032903103703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141d4a4cc00413420034188016a41b4a4cc004188a5cc001046000b2003419c016a41013602002003420237028c01200341b4a5cc00360288012003413e36026c2003200a3602682003200341e8006a36029801200341c0006a20034188016a1041200041086a200341c0006a41086a280200360200200020032903403702000c1c0b41dab0cc00411d41f8b0cc001064000b200341186a411810fb072003410036029001200320032903183703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141f7a3cc00413b20034188016a41b4a4cc0041c4a4cc001046000b41dab0cc00411d41f8b0cc001064000b200341286a411810fb072003410036029001200320032903283703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141f7a3cc00413b20034188016a41b4a4cc0041c4a4cc001046000b20034188016a41146a41013602002003420237028c01200341acaecc0036028801200341013602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a10410c080b20034190016a2903002107200328028c0121010c080b20034190016a2903002107200328028c0121010c070b103e000b41dab0cc00411d41f8b0cc001064000b103c000b200320032d00890122013a00302001200241ff0171460d1020014104460d10200341c0006a41146a413d360200200341cc006a413d36020020034188016a41146a41033602002003420337028c01200341eca5cc0036028801200341013602442003200341c0006a360298012003200341306a3602502003200341df006a3602482003200341d8006a360240200341e8006a20034188016a10410b200329026c2107200328026821010b2001450d0e20002007370204200020013602000c0f0b20032802402101200329024421070b2001450d0c20002007370204200020013602000c0d0b200641027421060340200320042802002205360278200220054d0d0220022005417f736a220520024f0d0a0240200a20054103746a22052d00044103460d0020052d00054104470d040b200441046a21042006417c6a22060d000b410421080b20034188016a200141186a2202200c410010f20720032d0088014101460d02200841ff01714104470d030c040b2003419c016a22044102360200200341cc006a41013602002003420237028c0120034198b0cc003602880120034101360244200320023602302003200341c0006a360298012003200341306a3602482003200341f8006a360240200341e8006a20034188016a1041200328026821022003200329026c37026c20032002360268200441013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402102200329024421070240200328026c450d00200328026810350b20032007370234200320023602300c050b200341cc006a413e3602002003419c016a41023602002003420237028c01200341c4a5cc00360288012003200541056a3602482003413e3602442003200341c0006a360298012003200341e0006a360240200341306a20034188016a10410c040b200341386a20034194016a2802003602002003200329028c013703300c030b20034188016a2002200c200810f407200328028801450d00200341306a41086a20034188016a41086a28020036020020032003290388013703300c020b200341003602300c010b2003419c016a22044102360200200341cc006a41013602002003420237028c0120034198b0cc003602880120034101360244200320023602302003200341c0006a360298012003200341306a3602482003200341f8006a360240200341e8006a20034188016a1041200328026821022003200329026c37026c20032002360268200441013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402102200329024421070240200328026c450d00200328026810350b20032007370234200320023602300b02400240200328023022020d00200141306a2802002202450d0102400240200241037420012802286a41786a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220820026b200420026b2209490d002001280218210a200221010c010b200220096a220a2002490d042008410174220b200a200b200a4b1b220b4100480d040240024020080d000240200b0d004101210a0c020b200b1033220a450d0b0c010b2001280218210a2008200b460d00200a2008200b1037220a450d0a0b2001200a3602182001411c6a200b360200200141206a28020021010b200a20016a21080240024020094102490d002008410420042002417f736a2202109f081a200a200220016a22016a21080c010b2009450d010b200841043a0000200141016a21010b20062001360200200541013a00060c050b20002003290234370204200020023602000c050b200341206a411810fb072003410036029001200320032903203703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141f7a3cc00413b20034188016a41b4a4cc0041c4a4cc001046000b103e000b41dab0cc00411d41f8b0cc001064000b20002007370204200020013602000c010b200041003602000b200341a0016a24000f0b103c000b6401017f230041206b220224002002413f360204200220003602002001411c6a2802002100200128021821012002411c6a41013602002002420137020c20024188b2cc003602082002200236021820012000200241086a10432101200241206a240020010b0c002000280200200110cd070b8f1f03127f017e037f23004180026b220524000240024020014115490d00410121064101210702400240034020012108200021092006200771410173210a024002400240034002400240024002402004450d00024020064101710d002000200110c8072004417f6a21040b2001410276220741036c210b2007410174210c4100210d20014132490d03200741016a210e200020074103746a220f28020020002007417f6a220d4103746a2210280200201041046a2802002210200f41046a280200220f200f20104b1b10a0082211450d01417f410120114100481b21100c020b2000200110c9070c0b0b417f200f201047200f2010491b21100b2007200d2010417f4622101b210f024002402000200e4103746a22112802002000200d200720101b22124103746a2207280200200741046a2802002207201141046a280200220d200d20074b1b10a0082211450d00417f410120114100481b21070c010b417f200d200747200d2007491b21070b4102410120101b20102007417f4622071b210d024002402000200e201220071b22114103746a22102802002000200f4103746a2207280200200741046a2802002207201041046a2802002210201020074b1b10a008220e450d00417f4101200e4100481b21100c010b417f201020074720102007491b21100b200c4101722107200d2010417f4622126a2113024002402000200c4103746a220d2802002000200c417f6a22104103746a220e280200200e41046a280200220e200d41046a280200220d200d200e4b1b10a0082214450d00417f410120144100481b210e0c010b417f200d200e47200d200e491b210e0b200c2010200e417f46220e1b210d2013200e6a211302400240200020074103746a221428020020002010200c200e1b220e4103746a220c280200200c41046a280200220c201441046a28020022102010200c4b1b10a0082214450d00417f410120144100481b210c0c010b417f2010200c472010200c491b210c0b2013200c417f46220c6a21100240024020002007200e200c1b22134103746a220c2802002000200d4103746a2207280200200741046a2802002207200c41046a280200220c200c20074b1b10a008220e450d00417f4101200e4100481b210c0c010b417f200c200747200c2007491b210c0b200b41016a21072010200c417f4622146a2115024002402000200b4103746a220e2802002000200b417f6a220c4103746a2210280200201041046a2802002210200e41046a280200220e200e20104b1b10a0082216450d00417f410120164100481b21100c010b417f200e201047200e2010491b21100b200b200c2010417f4622101b210e201520106a211502400240200020074103746a22162802002000200c200b20101b22104103746a220c280200200c41046a280200220c201641046a280200220b200b200c4b1b10a0082216450d00417f410120164100481b210c0c010b417f200b200c47200b200c491b210c0b2015200c417f46220c6a211502400240200020072010200c1b220b4103746a220c2802002000200e4103746a2207280200200741046a2802002207200c41046a280200220c200c20074b1b10a0082210450d00417f410120104100481b21100c010b417f200c200747200c2007491b21100b200f201120121b2107200d201320141b210c200e200b2010417f4622101b210b201520106a210d0b024002402000200c4103746a220e280200200020074103746a2210280200201041046a2802002210200e41046a280200220e200e20104b1b10a008220f450d00417f4101200f4100481b21100c010b417f200e201047200e2010491b21100b200c20072010417f46220e1b2110200d200e6a210d024002402000200b4103746a220f28020020002007200c200e1b220e4103746a2207280200200741046a2802002207200f41046a280200220c200c20074b1b10a008220f450d00417f4101200f4100481b21070c010b417f200c200747200c2007491b21070b200d2007417f46220c6a2107024002400240024002402000200b200e200c1b220d4103746a220b280200200020104103746a220c280200200c41046a280200220c200b41046a280200220b200b200c4b1b10a008220e450d00200e4100480d010c020b200b200c4f0d010b200741016a2207410c490d0102402001410176220b450d00200020014103746a41786a21072000210c0340200c2902002117200c200729020037020020072017370200200c41086a210c200741786a2107200b417f6a220b0d000b0b20012010417f736a2110410121070c020b200d21100b20074521070b0240200745200a724101710d002000200110ca070d090b2003450d010240201020014f0d00024002402003280200200020104103746a2207280200200741046a280200220c200341046a280200220b200b200c4b1b10a008220e450d00200e41004e0d010c050b200b200c490d040b200029020021172000200729020037020020072017370200200041786a21122000410c6a2113200041086a2114200028020421072000280200210d4100210b2001210e0340024002400240200b200e417f6a22114f0d002013200b4103746a210c034002400240200d200c417c6a280200200c28020022102007200720104b1b10a008220f450d00200f4100480d030c010b20072010490d020b200c41086a210c2011200b41016a220b470d000c020b0b0240200b20114f0d002012200e4103746a210c2011210e034002400240200d200c280200200c41046a28020022102007200720104b1b10a008220f450d00200f4100480d010c050b200720104f0d040b200c41786a210c200b200e417f6a220e490d000b0b200b21110b200020073602042000200d36020002402001201141016a2207490d00200020074103746a2100200120076b220141154f0d040c0b0b2007200141e485cc001059000b2014200b4103746a221029020021172010200c290200370200200c2017370200200b41016a210b0c000b0b0b2010200141d086cc001042000b20080d014100410041f485cc001042000b20002109200121080b201020084f0d02200929020021172009200920104103746a2207290200370200200720173702002009280204210c200928020021124100210e410021184100211902402008417f6a2200450d002009410c6a21074100211803400240024002402007417c6a2802002012200c2007280200220b200b200c4b1b10a0082210450d00201041004e0d010c020b200b200c490d010b200021190240200020184d0d00200920084103746a41786a21072000211903400240024020072802002012200c200741046a280200220b200b200c4b1b10a0082210450d00201041004e0d010c030b200b200c490d020b200741786a21072019417f6a221920184b0d000b0b0240024020192018490d0020002019490d010c040b20182019419486cc001059000b20192000419486cc001058000b200741086a21072000201841016a2218470d000b20002118200021190b200941086a220720194103746a210041800121144100211141002110410021014180012106200720184103746a221a210d034002402000200d6b22074187104b220a0d002007410376220741807f6a20072011200e492001201049220b72220f1b21070240200f450d0020062007200b1b210620072014200b1b21140c010b2007200741017622066b21140b024020012010470d00024020060d002005221021010c010b4100210720052110200d210b0340201020073a0000200741016a210702400240200b2802002012200c200b41046a280200220f200f200c4b1b10a0082201450d00417f410120014100481b210f0c010b417f200f200c47200f200c491b210f0b200b41086a210b2010200f417f476a211020062007470d000b200521010b02402011200e470d00024020140d0020054180016a220e21110c010b200041786a21074100210b20054180016a210e0340200e200b3a0000200b41016a210b0240024020072802002012200c200741046a280200220f200f200c4b1b10a0082211450d00417f410120114100481b210f0c010b417f200f200c47200f200c491b210f0b200741786a2107200e200f417f466a210e2014200b470d000b20054180016a21110b0240200e20116b2207201020016b220b200b20074b1b2213450d00200d20012d00004103746a22072802042115200728020021162007200020112d0000417f734103746a290200370200024020134101460d004100210703402000201120076a220b2d0000417f734103746a200d200120076a41016a220f2d00004103746a290200370200200d200f2d00004103746a2000200b41016a2d0000417f734103746a290200370200200741026a210b200741016a220f2107200b2013490d000b2011200f6a21112001200f6a21010b200020112d0000417f734103746a2207201536020420072016360200201141016a2111200141016a21010b200020144103746b20002011200e461b2100200d20064103746a200d20012010461b210d200a0d000b02400240200120104f0d00200021070340200d2010417f6a22102d00004103746a220b2902002117200b200741786a22072902003702002007201737020020012010490d000c020b0b200d21072011200e4f0d0003402007290200211720072000200e417f6a220e2d0000417f734103746a220b290200370200200b2017370200200741086a21072011200e490d000b0b2009200c36020420092012360200024020082007201a6b41037620186a22014d0d00200929020021172009200920014103746a220729020037020020072017370200200820016b220c450d02200c20012001200c4b1b210b20084103762110200741086a2100024002402001200c417f6a220c490d002000200c20022007200410be07200921000c010b2009200120022003200410be0720072103200c21010b200b20104f2106201920184d2107200141154f0d010c040b0b20012008418486cc001042000b41a486cc00411c41c086cc00103f000b20102008418486cc001042000b20014102490d00200041786a2111410021124101210f0340200f4103742107200f417f6a210c200f41016a210f024002400240200020076a2210280200220d2000200c4103746a2207280200200741046a280200220e201041046a280200220b200b200e4b1b10a0082213450d0020134100480d010c020b200b200e4f0d010b201020072902003702000240200c450d002012210c201121070240034002400240200d2007280200200741046a2802002210200b200b20104b1b10a008220e450d00200e41004e0d030c010b200b20104f0d020b200741086a2007290200370200200741786a2107200c41016a2210200c49210e2010210c200e450d000b0b200741086a21070b2007200d3602002007200b3602040b2012417f6a2112201141086a2111200f2001470d000b0b20054180026a24000b19002000200141186a280200360204200020012802103602000bf80201067f230041c0006b2202240041002103410021040240024003400240024002402003411f4b0d002001280204220520012802082206460d01200641016a22072006490d04200520074f0d022007200541c0fdcb001058000b200041013602002000410f3a00040c040b200241013a000f200241346a410136020020024201370224200241acfdcb003602202002413636023c2002200241386a36023020022002410f6a360238200241106a200241206a10412002410b6a200241186a28020036000020022002290310370003200041053a0004200020022900003700052000410c6a200241076a290000370000200041013602000c030b200128020020066a2d0000210620012007360208200641ff00712003411f71742004722104200341076a21032006418001710d000b0240024020034120490d002006410f4b0d010b20004100360200200020043602040c020b200041013602002000410d3a00040c010b417f200741c0fdcb001059000b200241c0006a24000be704010a7f230041106b22032400200128020421042001280200210541002106410121074100210820012802082209210a0240024003400240024020082006460d002006210b0c010b200641016a220c2006490d022006410174220b200c200b200c4b1b220b4100480d020240024020060d000240200b0d00410121070c020b200b103322070d010c050b2006200b460d0020072006200b10372207450d040b200b21060b200720086a200a41807f72200a41ff0071200a410776220c1b3a0000200841016a2108200c210a200c0d000b02400240200b20086b2009490d00200b21060c010b200820096a22062008490d01200b410174220a2006200a20064b1b22064100480d010240200b0d00024020060d00410121070c020b200610332207450d030c010b200b2006460d002007200b200610372207450d020b200720086a20052009109d081a02402004450d00200510350b200128020c210502400240200620096b20086b200141146a280200220c490d002009200c6a20086a210a2006210b0c010b200920086a220b200c6a220a200b490d012006410174220b200a200b200a4b1b220b4100480d01024020060d000240200b0d00410121070c020b200b10332207450d030c010b2006200b460d0020072006200b10372207450d020b200720096a20086a2005200c109d081a200341003a000f200a210603402003200641800172200641ff0071200641077622081b3a000f20022003410f6a410110782008210620080d000b20022007200a10780240200b450d00200710350b2000411f3a00000240200141106a280200450d00200510350b200341106a24000f0b103e000b103c000bde03030a7f017e027f230041106b2203240020012802002104200341003a000e2004210503402003200541800172200541ff0071200541077622061b3a000e20022003410e6a410110782006210520060d000b200128020422072001410c6a2802002206410c6c6a2108200141086a280200210920072105024002402006450d00200721052004450d00200841746a210a410021052007210b0340200b2106024003402006280200220c0d01200541016a210520082006410c6a2206470d000c040b0b200641046a290200210d200341003a000e2006410c6a210b200541016a210e03402003200541800172200541ff0071200541077622011b3a000e20022003410e6a410110782001210520010d000b200341003a000f200d422088a7220f210503402003200541800172200541ff0071200541077622011b3a000f20022003410f6a410110782001210520010d000b2002200c200f10780240200da7450d00200c10350b0240200a2006460d00200e21052004417f6a22040d010b0b2006410c6a21050b20082005460d00034020052206410c6a2105024020062802002202450d00200641046a280200450d00200210350b20082005470d000b0b02402009450d002009410c6c450d00200710350b2000411f3a0000200341106a24000bfe0101067f2000410c6a280200200028020822016b2202411c6d210302402002450d0020012003411c6c6a21040340024020012802042202450d0002402001410c6a2802002203450d00200341047421030340024020022d00004109470d000240200241046a2205280200220628020441ffffffff0371450d0020062802001035200528020021060b200610350b200241106a2102200341706a22030d000b0b200141086a28020041ffffffff0071450d00200128020410350b2001411c6a21020240200141146a280200450d00200128021010350b2002210120022004470d000b0b024020002802042202450d002002411c6c450d00200028020010350b0b820201067f2000410c6a280200200028020822016b220241186d210302402002450d002001200341186c6a210403400240200141046a28020041ffffffff0171450d00200128020010350b0240200141146a2802002203450d00200128020c2102200341047421030340024020022d00004109470d000240200241046a2205280200220628020441ffffffff0371450d0020062802001035200528020021060b200610350b200241106a2102200341706a22030d000b0b200141186a21020240200141106a28020041ffffffff0071450d00200128020c10350b2002210120022004470d000b0b024020002802042202450d00200241186c450d00200028020010350b0b850201067f2000410c6a280200200028020822016b2202411c6d210302402002450d0020012003411c6c6a21040340024020012802042202450d0002402001410c6a2802002203450d00200341047421030340024020022d00004109470d000240200241046a2205280200220628020441ffffffff0371450d0020062802001035200528020021060b200610350b200241106a2102200341706a22030d000b0b200141086a28020041ffffffff0071450d00200128020410350b2001411c6a21020240200141146a28020041ffffffff0371450d00200128021010350b2002210120022004470d000b0b024020002802042202450d002002411c6c450d00200028020010350b0bcf0101067f02402000410c6a2802002201200028020822026b450d000340024020022802082203450d0020022802002104200341047421030340024020042d00004109470d000240200441046a2205280200220628020441ffffffff0371450d0020062802001035200528020021060b200610350b200441106a2104200341706a22030d000b0b200241106a21040240200241046a28020041ffffffff0071450d00200228020010350b2004210220042001470d000b0b0240200028020441ffffffff0071450d00200028020010350b0b8f05010b7f230041c080016b220224002002200110c007410121030240024020022802004101460d00200228020421042002410041808001109f08210541002106410021070240024002400240024002402004450d004100210841002109410121034100210a03402001280204220b200128020822076b2004200a6b220c41808001200c41808001491b220c490d022007200c6a22062007490d03200b2006490d042005200128020020076a200c109d08210b2001200636020802400240200920086b200c490d002008200c6a2107200921060c010b2008200c6a22072008490d06200941017422062007200620074b1b22064100480d060240024020090d00024020060d00410121030c020b2006103322030d010c090b20092006460d0020032009200610372203450d080b200621090b200320086a200b200c109d081a200721082004200c200a6a220a4b0d000b0b2000200336020420004100360200200041146a2007360200200041106a41003602002000410c6a2007360200200041086a20063602000c060b200541013a008f8001200541b480016a4101360200200542013702a48001200541acfdcb003602a08001200541363602bc80012005200541b880016a3602b0800120052005418f80016a3602b880012005419080016a200541a080016a10412005418b80016a2005419880016a2802003600002005200529039080013700838001200041053a00042000200529008080013700052000410c6a2005418780016a290000370000200041013602002009450d05200310350c050b2007200641c0fdcb001059000b2006200b41c0fdcb001058000b103e000b103c000b20002002290204370204200041013602002000410c6a2002410c6a2902003702000b200241c080016a24000bf50202057f017e02400240024020014108490d00200141017641feffffff07712202417f6a220320014f0d022001410d74200173220441117620047322044105742004732205417f2001417f6a677622067122044100200120042001491b6b220420014f0d01200020034103746a220329020021072003200020044103746a220429020037020020042007370200024020022001490d00200221030c030b2005410d7420057322044111762004732204410574200473220520067122044100200120042001491b6b220420014f0d01200020024103746a220329020021072003200020044103746a2204290200370200200420073702002002410172220320014f0d022005410d742005732204411176200473220441057420047320067122044100200120042001491b6b220420014f0d01200020034103746a220129020021072001200020044103746a2200290200370200200020073702000b0f0b20042001418486cc001042000b2003200141f485cc001042000bb20102037f017e024020014101762202450d00200020012002417f6a10cb072002417e6a210203402002417f460d0120002001200210cb072002417f6a21020c000b0b0240024020014102490d00200141037420006a41786a21022001210303402003417f6a220420014f0d0220002902002105200020022902003702002002200537020020002004410010cb07200241786a210220042103200441014b0d000b0b0f0b2003417f6a2001418486cc001042000b8f06050a7f017e017f017e037f200041686a2102200041786a210320014132492104410121054100210602400240024003400240024020052001490d00410021070c010b200320054103746a210841012107034002400240200841086a22092802002008280200200841046a280200220a2008410c6a28020022082008200a4b1b10a008220b450d00200b4100480d030c010b2008200a490d020b4101210a200541016a220520014921072009210820012005470d000c030b0b2005200146210a20040d0120052001460d012005417f6a220820014f0d032007410171450d02200020084103746a2208290200210c200820002005410374220d6a2209290200220e3702002009200c370200024020054102490d0002400240200ea7220f20002005417e6a22074103746a220b280200200b41046a2802002210200841046a280200220a200a20104b1b10a0082211450d0020114100480d010c020b200a20104f0d010b2008200b29020037020002402007450d002002200d6a21080240034002400240200f2008280200200841046a280200220b200a200a200b4b1b10a0082210450d00201041004e0d030c010b200a200b4f0d020b200841086a2008290200370200200841786a21082007417f6a22070d000b0b200841086a210b0b200b200f360200200b200a3602040b200641016a21060240200120056b220f4102490d000240024020092802082009280200220d200941046a280200220b2009410c6a28020022082008200b4b1b10a008220a450d00200a4100480d010c020b2008200b4f0d010b200941086a2111200920092902083702000240200f4103490d004103210a41022107034002400240200920074103746a2208280200200d200b200841046a28020022072007200b4b1b10a0082210450d00201041004e0d030c010b2007200b4f0d020b200841786a20082902003702000240200a200f4f0d00200a2107200a41016a210a200821110c010b0b200821110b2011200d3602002011200b3602040b20064105470d000b4100210a0b200a0f0b20052001418486cc001042000b2008200141f485cc001042000bb60202057f017e03402002410174220341017221040240024002400240200341026a220320014f0d00200420014f0d0102400240200020044103746a2205280200200020034103746a2206280200200641046a2802002206200541046a2802002205200520064b1b10a0082207450d00417f410120074100481b21060c010b417f200520064720052006491b21060b200320042006417f461b21040b0240200420014f0d00200220014f0d020240200020024103746a2202280200200020044103746a2203280200200341046a2802002206200241046a2802002205200520064b1b10a0082207450d00200741004e0d010c040b20052006490d030b0f0b2004200141f487cc001042000b20022001418488cc001042000b200229020021082002200329020037020020032008370200200421020c000b0b830401097f200141096a2d0000210220012802042103200128020021040240024002400240024002400240024020012d000822014102470d0020040d010c050b20014101462105024020040d00200521060c020b2005200320046b6a220620054f0d01410021074100210541002106410121080340024002400240200141ff01714102470d00200221090c010b410021092001410171450d00410021010c010b2004450d0820042003460d0820042d0000210241022101200441016a21040b024020052006470d002005417f200320046b410020041b220641016a220a200a2006491b6a22062005490d0420072006200720064b1b22064100480d04024020050d00024020060d00410121080c020b2006103322080d010c060b20052006460d0020082005200610372208450d050b200820056a20023a0000200741026a2107200541016a2105200921020c000b0b200320046b21060b2006450d0220064100480d00200610332208450d010c030b103e000b103c000b41012108410021060b02400240200141037122074103460d00410021052008210120070e03010001010b200820023a000041012105200841016a21010b2004450d0020032004460d00200421020340200120022d00003a0000200141016a21012003200241016a2202470d000b2003200520046b6a21050b2000200536020820002006360204200020083602000bc76501037f230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000eac010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab0100010b2002200128021841cff1cb0041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000cab010b2002200128021841e0f1cb00410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000caa010b2002200128021841ebf1cb0041032001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca9010b2002200128021841eef1cb0041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41f4f1cb00106f21000ca8010b200220012802184184f2cb0041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41f4f1cb00106f21000ca7010b200220012802184188f2cb0041022001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41f4f1cb00106f21000ca6010b20022001280218418af2cb0041042001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca5010b20022001280218418ef2cb0041032001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca4010b200220012802184191f2cb0041022001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000ca3010b200220012802184193f2cb0041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000ca2010b200220012802184197f2cb0041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0f2cb00106f21000ca1010b2002200128021841b0f2cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca0010b2002200128021841b6f2cb0041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c9f010b2002200128021841baf2cb00410c2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041016a36020c20012002410c6a41c8f2cb00106f21000c9e010b2002200128021841d8f2cb0041042001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c9d010b2002200128021841dcf2cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c9c010b2002200128021841e2f2cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c9b010b2002200128021841eaf2cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c9a010b2002200128021841f2f2cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c99010b2002200128021841faf2cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c98010b200220012802184183f3cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c97010b20022001280218418cf3cb0041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c96010b200220012802184193f3cb0041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c95010b20022001280218419af3cb0041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c94010b2002200128021841a1f3cb0041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c93010b2002200128021841a8f3cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c92010b2002200128021841b1f3cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c91010b2002200128021841baf3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c90010b2002200128021841c4f3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8f010b2002200128021841cef3cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8e010b2002200128021841d7f3cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8d010b2002200128021841e0f3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8c010b2002200128021841eaf3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8b010b2002200128021841f4f3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8a010b2002200128021841fef3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c89010b200220012802184188f4cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c88010b200220012802184190f4cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c87010b200220012802184198f4cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c86010b2002200128021841a0f4cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c85010b2002200128021841a8f4cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c84010b2002200128021841b1f4cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c83010b2002200128021841bbf4cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c82010b2002200128021841c4f4cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c81010b2002200128021841cef4cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c80010b2002200128021841d8f4cb00410d2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41c8f2cb00106f21000c7f0b2002200128021841e5f4cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41c8f2cb00106f21000c7e0b2002200128021841eff4cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41f8f4cb00106f21000c7d0b200220012802184188f5cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a4190f5cb00106f21000c7c0b2002200128021841a0f5cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c7b0b2002200128021841a8f5cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41b0f5cb00106f21000c7a0b2002200128021841c0f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c790b2002200128021841c6f5cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c780b2002200128021841cbf5cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c770b2002200128021841d0f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c760b2002200128021841d6f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c750b2002200128021841dcf5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c740b2002200128021841e2f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c730b2002200128021841e8f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c720b2002200128021841eef5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c710b2002200128021841f4f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c700b2002200128021841faf5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6f0b200220012802184180f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6e0b200220012802184186f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6d0b20022001280218418bf6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6c0b200220012802184190f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6b0b200220012802184196f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6a0b20022001280218419cf6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c690b2002200128021841a2f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c680b2002200128021841a8f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c670b2002200128021841aef6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c660b2002200128021841b4f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c650b2002200128021841baf6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c640b2002200128021841c0f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c630b2002200128021841c5f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c620b2002200128021841caf6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c610b2002200128021841cff6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c600b2002200128021841d4f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5f0b2002200128021841d9f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5e0b2002200128021841def6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5d0b2002200128021841e3f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5c0b2002200128021841e8f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5b0b2002200128021841edf6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5a0b2002200128021841f2f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c590b2002200128021841f7f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c580b2002200128021841fcf6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c570b200220012802184182f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c560b200220012802184188f7cb0041092001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c550b200220012802184191f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c540b200220012802184197f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c530b20022001280218419df7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c520b2002200128021841a3f7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c510b2002200128021841aaf7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c500b2002200128021841b1f7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4f0b2002200128021841b8f7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4e0b2002200128021841bff7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4d0b2002200128021841c5f7cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4c0b2002200128021841caf7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4b0b2002200128021841d0f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4a0b2002200128021841d6f7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c490b2002200128021841ddf7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c480b2002200128021841e4f7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c470b2002200128021841ebf7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c460b2002200128021841f2f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c450b2002200128021841f8f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c440b2002200128021841fef7cb0041092001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c430b200220012802184187f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c420b20022001280218418df8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c410b200220012802184193f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c400b200220012802184199f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3f0b2002200128021841a0f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3e0b2002200128021841a7f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3d0b2002200128021841aef8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3c0b2002200128021841b5f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3b0b2002200128021841bbf8cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3a0b2002200128021841c0f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c390b2002200128021841c6f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c380b2002200128021841ccf8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c370b2002200128021841d3f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c360b2002200128021841daf8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c350b2002200128021841e1f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c340b2002200128021841e8f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c330b2002200128021841eef8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c320b2002200128021841f4f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c310b2002200128021841fbf8cb0041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c300b200220012802184183f9cb0041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2f0b20022001280218418bf9cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2e0b200220012802184195f9cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2d0b20022001280218419cf9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2c0b2002200128021841a2f9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2b0b2002200128021841a8f9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2a0b2002200128021841aef9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c290b2002200128021841b4f9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c280b2002200128021841baf9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c270b2002200128021841c0f9cb00410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c260b2002200128021841cbf9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c250b2002200128021841d1f9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c240b2002200128021841d7f9cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c230b2002200128021841def9cb0041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c220b2002200128021841e6f9cb0041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c210b2002200128021841eef9cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c200b2002200128021841f8f9cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1f0b2002200128021841fff9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1e0b200220012802184185facb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1d0b20022001280218418bfacb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1c0b200220012802184191facb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1b0b200220012802184197facb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1a0b20022001280218419dfacb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c190b2002200128021841a3facb00410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c180b2002200128021841aefacb00410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c170b2002200128021841b8facb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c160b2002200128021841c4facb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c150b2002200128021841d0facb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c140b2002200128021841dcfacb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c130b2002200128021841e8facb00410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c120b2002200128021841f5facb00410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c110b200220012802184182fbcb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c100b20022001280218418efbcb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0f0b20022001280218419afbcb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0e0b2002200128021841a6fbcb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0d0b2002200128021841b2fbcb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0c0b2002200128021841c0fbcb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0b0b2002200128021841cefbcb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0a0b2002200128021841dcfbcb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c090b2002200128021841eafbcb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c080b2002200128021841f6fbcb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c070b200220012802184184fccb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c060b200220012802184192fccb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c050b2002200128021841a0fccb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c040b2002200128021841aefccb00410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c030b2002200128021841bbfccb0041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c020b2002200128021841ccfccb0041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c010b2002200128021841ddfccb0041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000b20002d00082101024020002802042203450d00200141ff0171210441012101024020040d00024020034101470d0020002d0009450d00200028020022042d00004104710d0041012101200428021841d6a0c00041012004411c6a28020028020c1100000d010b2000280200220128021841cca6cc0041012001411c6a28020028020c11000021010b200020013a00080b200241206a2400200141ff01714100470bcc0101047f230041106b220224002000280200220041046a28020021032000280200210041012104200128021841d9a0c00041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d002003410274210103402002200036020c20022002410c6a41f0fccb0010701a200041046a21002001417c6a22010d000b20022d000421050b0240200541ff01710d002002280200220028021841d8a0c00041012000411c6a28020028020c11000021040b200241106a240020040b8a0201027f230041106b2202240020002802002802002100200128021841a8f1cb00410b2001411c6a28020028020c1100002103200241003a0005200220033a0004200220013602002002200036020c200241b3f1cb0041052002410c6a41b8f1cb00106921012002200041086a36020c200141c8f1cb0041072002410c6a4198f1cb0010691a20022d00042101024020022d0005450d00200141ff0171210041012101024020000d0020022802002201411c6a28020028020c210020012802182103024020012d00004104710d00200341d0a0c0004102200011000021010c010b200341d2a0c0004101200011000021010b200220013a00040b200241106a2400200141ff01714100470b0c002000280200200110b9070bc50201037f230041206b2202240002400240200028020022002d00004104470d0020022001280218419cfdcb0041082001411c6a28020028020c11000022003a001820022001360210200241003a0019200241003602140c010b2002200128021841a4fdcb0041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a418cfdcb00106f210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841d6a0c00041012004411c6a28020028020c1100000d010b2001280200220028021841cca6cc0041012000411c6a28020028020c11000021000b200120003a00080b200241206a2400200041ff01714100470bc00201037f230041206b220224000240024020002d00004104470d0020022001280218419cfdcb0041082001411c6a28020028020c11000022003a001820022001360210200241003a0019200241003602140c010b2002200128021841a4fdcb0041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a418cfdcb00106f210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841d6a0c00041012004411c6a28020028020c1100000d010b2001280200220028021841cca6cc0041012000411c6a28020028020c11000021000b200120003a00080b200241206a2400200041ff01714100470bd70203027f017e017f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210020034120710d012000ac22042004423f8722047c2004852000417f73411f762001105221000c020b20002802002103410021000340200220006a41ff006a2003410f712205413072200541d7006a2005410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021030340200220036a41ff006a2000410f712205413072200541376a2005410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141d88bc0004102200220036a4180016a410020036b105621000b20024180016a240020000f0b200341800141c88bc0001059000b200041800141c88bc0001059000bca0201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff018341012001105221000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000b20024180016a240020000f0b200441800141c88bc0001059000b200441800141c88bc0001059000bd70202027f027e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042004423f8722057c2005852004427f552001105221000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000b20024180016a240020000f0b200341800141c88bc0001059000b200341800141c88bc0001059000b940201047f230041106b220324000240024002400240200241ffffffff03712002470d0020024102742204417f4c0d000240024020040d00410421050c010b200410332205450d020b20034100360208200320053602002003200441027636020420034100200210860120032802002205200328020822064102746a20012002410274109d081a024020032802042204200620026a2202460d0020042002490d032004450d002004410274220120024102742204460d00024020040d00024020010d00410421050c020b20051035410421050c010b20052001200410372205450d040b2000200236020420002005360200200341106a24000f0b1044000b1045000b41ec80cc00412441c086cc00103f000b103c000bab0902027f017e230041106b220224000240024020012d00002203414f6a41fb00490d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e312a2a0001022a2a0304052a06072a2a08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a0b200020012d00013a0001410221030c290b200020012d00013a0001410321030c280b200020012d00013a0001410421030c270b200041046a200141046a280200360200410721030c260b200041046a200141046a280200360200410821030c250b200141046a2802002103410c10332201450d25200241086a2003280200200341046a28020010d607200229030821042001200328020836020820012004370200200041046a2001360200410921030c240b200041046a200141046a280200360200410b21030c230b200020012d00013a0001200041046a200141046a280200360200410c21030c220b200041046a200141046a280200360200410f21030c210b200041046a200141046a280200360200411021030c200b200041046a200141046a280200360200411121030c1f0b200041046a200141046a280200360200411221030c1e0b200041046a200141046a280200360200411321030c1d0b200041046a200141046a290200370200411421030c1c0b200041046a200141046a290200370200411521030c1b0b200041046a200141046a290200370200411621030c1a0b200041046a200141046a290200370200411721030c190b200041046a200141046a290200370200411821030c180b200041046a200141046a290200370200411921030c170b200041046a200141046a290200370200411a21030c160b200041046a200141046a290200370200411b21030c150b200041046a200141046a290200370200411c21030c140b200041046a200141046a290200370200411d21030c130b200041046a200141046a290200370200411e21030c120b200041046a200141046a290200370200411f21030c110b200041046a200141046a290200370200412021030c100b200041046a200141046a290200370200412121030c0f0b200041046a200141046a290200370200412221030c0e0b200041046a200141046a290200370200412321030c0d0b200041046a200141046a290200370200412421030c0c0b200041046a200141046a290200370200412521030c0b0b200041046a200141046a290200370200412621030c0a0b200041046a200141046a290200370200412721030c090b200041046a200141046a290200370200412821030c080b200041046a200141046a290200370200412921030c070b200041046a200141046a290200370200412a21030c060b200020012d00013a0001412b21030c050b200020012d00013a0001412c21030c040b200041046a200141046a280200360200412d21030c030b200041086a200141086a290300370300412e21030c020b200041046a200141046a280200360200412f21030c010b200041086a200141086a290300370300413021030b200020033a0000200241106a24000f0b103c000bcc0201027f230041106b22022400200028020028020021002001280218418b85cc0041052001411c6a28020028020c1100002103200241003a0005200220033a00042002200136020020022000410c6a36020c2002419085cc00410e2002410c6a41a085cc00106921012002200036020c200141b085cc0041092002410c6a41bc85cc00106921012002200041046a36020c200141cc85cc00410c2002410c6a41bc85cc00106921012002200041086a36020c200141d885cc00410c2002410c6a41bc85cc0010691a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341d0a0c0004102200111000021000c010b200341d2a0c0004101200111000021000b200220003a00040b200241106a2400200041ff01714100470bd50302047f017e024020014101762202450d0003402002417f6a2202210302400240024003402003410174220441017221050240200441026a220420014f0d00200520014f0d0220042005200020054103746a280200200020044103746a280200491b21050b200520014f0d03200320014f0d02200020034103746a2203280200200020054103746a22042802004f0d03200329020021062003200429020037020020042006370200200521030c000b0b2005200141f487cc001042000b20032001418488cc001042000b20020d000b0b0240024020014102490d002001210403402004417f6a220420014f0d02200029020021062000200020044103746a2205290200370200200520063702004100210302400240024003402003410174220241017221050240200241026a220220044f0d00200520044f0d0220022005200020054103746a280200200020024103746a280200491b21050b200520044f0d03200320044f0d02200020034103746a2203280200200020054103746a22022802004f0d03200329020021062003200229020037020020022006370200200521030c000b0b2005200441f487cc001042000b20032004418488cc001042000b200441014b0d000b0b0f0b20042001418486cc001042000bea04050a7f017e017f017e027f200041686a21022001417f6a2103200041086a2104410021052001413249210641012107024003400240024020072001490d00410021080c010b410121082000200741037422096a220a280200220b200a41786a280200490d00200420096a210803404101210a20032007460d03200741016a21072008280200220a200b4f2109200841086a2108200a210b20090d000b200720014921080b2007200146210a20060d0120072001460d010240024002400240024002402007417f6a220b20014f0d002008450d012000200b4103746a220b290200210c200b20002007410374220d6a2208290200220e3702002008200c37020020074102490d0520002007417e6a220a4103746a220f280200200ea722094d0d05200b200f290200370200200a450d0420002007417d6a220a4103746a28020020094d0d042002200d6a210b0340200b41086a200b290200370200200a450d03200a417f6a210a200b41786a220b28020020094b0d000b200a41016a210b0c030b200b200141f485cc001042000b20072001418486cc001042000b4100210b0b2000200b4103746a210f0b200f200e3702000b200541016a21050240200120076b220a4102490d00200828020820082802004f0d002008290200210c20082008290208370200200841086a210f0240200a4103490d002008280210200ca722104f0d00200841106a21094103210b4102210d0340200d41037420086a220f41786a2009290200370200200b200a4f0d01200b4103742109200b210d200b41016a210b200820096a22092802002010490d000b0b200f200c3702000b20054105470d000b4100210a0b200a0bcc5e010c7f230041a0016b22032400200320013602242002280208220441546a2105200241106a280200220641306c21010240024002400240024002400240024002400240024003402001450d01200141506a21012005412c6a2107200541306a2208210520072d00004104470d000b200641306c2101200441546a210503402001450d02200141506a21012005412c6a2107200541306a2209210520072d0000410c470d000b200641306c2101200441546a210503402001450d03200141506a21012005412c6a2107200541306a2204210520072d00004102470d000b0240410028028cb54c4105490d00200341013602442003200341246a3602404100280298b54c21014100280294b54c21054100280290b54c210720034198016a41980136020020034190016a42ee808080103703002003418c016a41b88acc0036020020034184016a422537020020034180016a41ee8bcc00360200200341f8006a4201370300200341e8006a4201370300200341e0006a410a360200200341f4006a200341c0006a360200200341c888cc00360264200341e48bcc0036025c20034105360258200541aca2c000200741024622071b200341d8006a200141c4a2c00020071b2802101102000b200341186a200810bf03200328021c200328022422014d0d03200328021820014102746a2201450d03200341106a200410bf032003280214200128020022014d0d04200328021020014104746a2201450d04200941086a280200200328022422054d0d0820092802002109200341286a41086a420037030020034280808080c00037032820012d000d2101410021072003410036024820032001410447220a3602442003200a360240200341003a004c410028028cb54c41044b0d05200341d8006a41086a200341c0006a41086a29030037030020032003290340370358200341286a410472210b200341d8006a21010c060b411310332201450d082001410f6a41002800a3884c360000200141086a410029009c884c37000020014100290094884c370000200041086a4293808080b00237020020002001360204200041013602000c090b410f10332201450d07200141076a41002900ae884c370000200141002900a7884c370000200041086a428f808080f00137020020002001360204200041013602000c080b410f10332201450d06200141076a41002900bd884c370000200141002900b6884c370000200041086a428f808080f00137020020002001360204200041013602000c070b412510332201450d052001411d6a41002900ed884c370000200141186a41002900e8884c370000200141106a41002900e0884c370000200141086a41002900d8884c370000200141002900d0884c370000200041086a42a5808080d00437020020002001360204200041013602000c060b412510332201450d042001411d6a41002900ed884c370000200141186a41002900e8884c370000200141106a41002900e0884c370000200141086a41002900d8884c370000200141002900d0884c370000200041086a42a5808080d00437020020002001360204200041013602000c050b200341c0003602542003200341c0006a3602504100280298b54c21014100280294b54c21074100280290b54c210820034198016a41cb0036020020034190016a42ee808080103703002003418c016a41b88acc0036020020034184016a422537020020034180016a41ee8bcc00360200200341f8006a4201370300200341e8006a4201370300200341d8006a41086a2206410a360200200341f4006a200341d0006a360200200341f888cc00360264200341e48bcc0036025c20034105360258200741aca2c000200841024622081b200341d8006a200141c4a2c00020081b28021011020020032802342108200328023021072006200341c0006a41086a29030037030020032003290340370358200341286a410472210b200341d8006a210120082007470d010b200b20074101108c01200328023421080b200b28020020084104746a22072001290200370200200741086a200141086a2902003702002003200328023441016a3602344100210702402009200541186c6a2201280214450d002009200541186c6a410c6a2109200141146a2108200341d8006a410472210c41002107410021010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240034002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200328022820074d0d00200341d8006a200341286a410010dd0720032802584101460d0120072003280228200328025c2d000c1b21070b2001200828020022054f0d1e2003200928020020014104746a220536023c0240410028028cb54c4105490d002003413936024420032003413c6a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341c90136029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc0036028001200342013703782003420137036820034188b2cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328023c21050b20052d000022060eac01031b0101011b020405060708090a0b0c0d0e0f10111111111111111111111111111112121212121212121213141515151516171717171717171717171617171717171717171717171717171717171717171717181818191919191919191919191919191919181818191919191919191919191919191919181818181818181919191919191918181818181818191919191919191a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a030b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c340b20052d000121052003200328022836024820032005410447220536024020032006410347200571360244200341003a004c0240410028028cb54c4105490d00200341c0003602542003200341c0006a3602504100280298b54c21054100280294b54c21064100280290b54c210d200341cb0036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341f888cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341d0006a360274200641aca2c000200d1b200341d8006a20051102000b200341d8006a41086a2206200341c0006a41086a290300370300200320032903403703580240200328023422052003280230470d00200b20054101108c01200328023421050b200b28020020054104746a22052003290358370200200541086a20062903003702002003200328023441016a3602340c190b0240410028028cb54c4105490d00200b2802002105200341c10036025420032005200328023422064104746a41706a410020061b3602402003200341c0006a3602504100280298b54c21054100280294b54c21064100280290b54c210d200341d30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341a889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341d0006a360274200641aca2c000200d1b200341d8006a20051102000b024020032802342205450d0020032005417f6a2205360234200b28020020054104746a22052d000c4102460d00200528020021062003200528020822053602400240410028028cb54c4105490d00200341013602542003200341c0006a3602504100280298b54c21054100280294b54c210d4100280290b54c210e200341db0036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b089cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200e410246220e1b28021021052003200341d0006a360274200d41aca2c000200e1b200341d8006a2005110200200328024021050b20032005360228200320063602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a200511020020032802282105200328025021060b0240200520066a22062005490d00200320063602280c1a0b410e10332201450d36200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c330b411710332201450d352001410f6a41002900dd894c370000200141086a41002900d6894c370000200141002900ce894c370000200041086a4297808080f00237020020002001360204200041013602000c320b0240410028028cb54c4105490d004100280298b54c21054100280294b54c21064100280290b54c210d200341c10036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc003602800120034200370378200341b0b4cc0036027420034201370368200341e889cc003602642003410a360260200341e48bcc0036025c20034105360258200641aca2c000200d410246220d1b200341d8006a200541c4a2c000200d1b2802101102000b024020032802342205450d002005410474200b2802006a417c6a41013a00000c180b411710332201450d342001410f6a41002900dd894c370000200141086a41002900d6894c370000200141002900ce894c370000200041086a4297808080f00237020020002001360204200041013602000c310b200341d8006a200341286a200541046a28020010dd0720032802584101460d1a200341d8006a200341286a200328025c28020410df0720032802580d1b0240410028028cb54c4105490d004100280298b54c21054100280294b54c21064100280290b54c210d200341c10036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc003602800120034200370378200341b0b4cc0036027420034201370368200341e889cc003602642003410a360260200341e48bcc0036025c20034105360258200641aca2c000200d410246220d1b200341d8006a200541c4a2c000200d1b2802101102000b024020032802342205450d002005410474200b2802006a417c6a41013a00000c170b411710332201450d332001410f6a41002900dd894c370000200141086a41002900d6894c370000200141002900ce894c370000200041086a4297808080f00237020020002001360204200041013602000c300b200341d8006a200341286a200541046a28020010dd0720032802584101460d1b200341d8006a200341286a200328025c280204220510df0720032802580d1c200341d8006a200341286a410110df0720032802580d1d200320053602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c160b410e10332201450d32200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c2f0b200341d8006a200341286a200541046a28020028020810dd0720032802584101460d1d200328025c280204210d2005280204220628020441027421052006280200210602400340024020050d00200341d8006a200341286a200d10df0720032802580d220240410028028cb54c4105490d004100280298b54c21054100280294b54c21064100280290b54c210d200341c10036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc003602800120034200370378200341b0b4cc0036027420034201370368200341e889cc003602642003410a360260200341e48bcc0036025c20034105360258200641aca2c000200d410246220d1b200341d8006a200541c4a2c000200d1b2802101102000b20032802342205450d022005410474200b2802006a417c6a41013a00000c170b200341d8006a200341286a200628020010dd0720032802584101460d202005417c6a2105200641046a2106200328025c280204200d460d000b412710332201450d322001411f6a410029008f8a4c370000200141186a41002900888a4c370000200141106a41002900808a4c370000200141086a41002900f8894c370000200141002900f0894c370000200041086a42a7808080f00437020020002001360204200041013602000c2f0b411710332201450d312001410f6a41002900dd894c370000200141086a41002900d6894c370000200141002900ce894c370000200041086a4297808080f00237020020002001360204200041013602000c2e0b200341d8006a200341286a200a10df0720032802580d1f0240410028028cb54c4105490d004100280298b54c21054100280294b54c21064100280290b54c210d200341c10036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc003602800120034200370378200341b0b4cc0036027420034201370368200341e889cc003602642003410a360260200341e48bcc0036025c20034105360258200641aca2c000200d410246220d1b200341d8006a200541c4a2c000200d1b2802101102000b024020032802342205450d002005410474200b2802006a417c6a41013a00000c140b411710332201450d302001410f6a41002900dd894c370000200141086a41002900d6894c370000200141002900ce894c370000200041086a4297808080f00237020020002001360204200041013602000c2d0b200341d8006a200541046a280200200210e00720032802584101460d1f200341d8006a200341286a200328025c220528020810df0720032802580d20200320052d000d41044722053602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c130b410e10332201450d2f200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c2c0b200341086a200410bf0302400240200328020c200541046a28020022054d0d002003280208220620054104746a220d450d00200341d8006a200341286a200620054104746a28020810df0720032802580d222003200d2d000d41044722053602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b2003280228220620056a22052006490d01200320053602280c130b410e10332201450d2f200141066a410029009d8a4c370000200141002900978a4c370000200041086a428e808080e00137020020002001360204200041013602000c2c0b410e10332201450d2e200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c2b0b200341d8006a200341286a410110df072003280258450d1020002003290358370204200041013602002000410c6a200341e0006a2802003602000c2a0b200341d8006a200341286a410210df0720032802580d1f41012105200341d8006a200341286a410110df0720032802580d20200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c100b410e10332201450d2c200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c290b41012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c0f0b410e10332201450d2b200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c280b200341d8006a200341286a410110df072003280258450d0d20002003290358370204200041013602002000410c6a200341e0006a2802003602000c270b41012105200341d8006a200341286a410110df0720032802580d1e200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c0d0b410e10332201450d29200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c260b41012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c0c0b410e10332201450d28200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c250b200341d8006a200341286a410110df072003280258450d0a20002003290358370204200041013602002000410c6a200341e0006a2802003602000c240b41012105200341d8006a200341286a410110df0720032802580d1c200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c0a0b410e10332201450d26200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c230b200341d8006a200341286a410210df072003280258450d0820002003290358370204200041013602002000410c6a200341e0006a2802003602000c220b41012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c080b410e10332201450d24200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c210b41012105200341d8006a200341286a410110df0720032802580d1a200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c070b410e10332201450d23200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c200b41012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c060b410e10332201450d22200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c1f0b41012105200341d8006a200341286a410110df0720032802580d19200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c050b410e10332201450d21200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c1e0b200341d8006a200341286a410210df0720032802580d1941012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c040b410e10332201450d20200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c1d0b41012105200341d8006a200341286a410110df0720032802580d19200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c030b410e10332201450d1f200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c1c0b200341d8006a200341286a410210df0720032802580d1941012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c020b410e10332201450d1e200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c1b0b41012105200341d8006a200341286a410110df0720032802580d19200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b2003280228220620056a22052006490d02200320053602280b200141016a22012008280200490d000c1a0b0b410e10332201450d1a200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c170b2001200541a88acc001042000b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c150b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c140b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c130b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c120b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c110b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c100b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c0f0b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c0e0b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c0d0b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c0c0b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c0b0b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c0a0b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c090b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c080b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c070b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c060b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c050b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c040b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c030b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c020b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c010b20002003290358370204200041013602002000410c6a200341e0006a2802003602000b200328023041ffffffff0071450d03200b28020010350c030b2000410036020020002007360204200328023041ffffffff0071450d02200b28020010350c020b412710332201450d002001411f6a410029009f894c370000200141186a4100290098894c370000200141106a4100290090894c370000200141086a4100290088894c37000020014100290080894c370000200041086a42a7808080f00437020020002001360204200041013602000c010b1045000b200341a0016a24000bc20201027f230041106b220224002001280218418b85cc0041052001411c6a28020028020c1100002103200241003a0005200220033a00042002200136020020022000410c6a36020c2002419085cc00410e2002410c6a41a085cc00106921012002200036020c200141b085cc0041092002410c6a41bc85cc00106921012002200041046a36020c200141cc85cc00410c2002410c6a41bc85cc00106921012002200041086a36020c200141d885cc00410c2002410c6a41bc85cc0010691a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341d0a0c0004102200111000021000c010b200341d2a0c0004101200111000021000b200220003a00040b200241106a2400200041ff01714100470b8d0201027f024002400240024002402001410c6a2802002203417f6a220420034b0d00200420026b220220044b0d01200320024d0d032000200128020420024104746a360204200041003602000f0b411610332201450d01200020013602042001410e6a41002900c98c4c370000200141086a41002900c38c4c370000200141002900bb8c4c370000200041086a4296808080e0023702000c030b411b10332201450d0020002001360204200141176a41002800fb8c4c360000200141106a41002900f48c4c370000200141086a41002900ec8c4c370000200141002900e48c4c370000200041086a429b808080b0033702000c020b1045000b2002200341d48ccc001042000b200041013602000bba0201037f230041106b220224000240024020002802000d002002200128021841ee8fcc0041042001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b2002200128021841ea8fcc0041042001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41f48fcc00106f210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841d6a0c00041012004411c6a28020028020c1100000d010b2001280200220028021841cca6cc0041012000411c6a28020028020c11000021000b200120003a00080b200241106a2400200041ff01714100470bcd0401037f230041e0006b220324002003200236020c0240410028028cb54c4105490d002003410136021420032003410c6a3602104100280298b54c21024100280294b54c21044100280290b54c2105200341d8006a41ef00360200200341d0006a42ee80808010370300200341cc006a41b88acc00360200200341c4006a4225370200200341c0006a41ee8bcc00360200200341386a4201370300200341286a4201370300200341206a410a360200200341346a200341106a360200200341a88bcc00360224200341e48bcc0036021c20034105360218200441aca2c000200541024622051b200341186a200241c4a2c00020051b280210110200200328020c21020b0240024002400240024002402002450d00200341186a2001410010dd0720032802184101460d0120012802002202200328021c2204280208460d022002200328020c6b220420024b0d0320004100360200200120043602000c050b200041003602000c040b2000200341186a4104722202290200370200200041086a200241086a2802003602000c030b024020042d000c0d00412510332202450d02200042a5808080d004370204200020023602002002411d6a41002900cd8b4c370000200241186a41002900c88b4c370000200241106a41002900c08b4c370000200241086a41002900b88b4c370000200241002900b08b4c3700000c030b200041003602000c020b410f10332202450d002000428f808080f00137020420002002360200200241076a41002900dc8b4c370000200241002900d58b4c3700000c010b1045000b200341e0006a24000bb107010a7f230041e0006b22032400200320013602202002280208220441546a2105200241106a280200220641306c210202400340024020020d00410021070c020b200241506a21022005412c6a2107200541306a2208210520072d00004102470d000b200341186a200810bf0320032802182107200328021c21020b2002410020071b2109200641306c2102200441546a2105200741b0b4cc0020071b210a02400340024020020d004100210b0c020b200241506a21022005412c6a2107200541306a2208210520072d00004104470d000b200341106a200810bf032003280210210b2003280214210c0b200641306c2102200441546a210502400240024002400240024002400240024003402002450d01200241506a21022005412c6a2107200541306a2208210520072d00004103470d000b200841086a2802002202450d00200241286c2107200828020041186a2102410021050340200520022d0000456a2105200241286a2102200741586a22070d000b200520014d0d01200641306c2102200441546a210503402002450d07200241506a21022005412c6a2107200541306a2208210520072d00004103470d000b200341086a200810bf03200328020c220441286c210520032802082206210703402005450d08200541586a2105200741186a2108200741286a2202210720082d00000d000b20010d02200241586a21020c030b410021050b0240200c4100200b1b200120056b22024d0d00200b41b0b4cc00200b1b20024102746a22020d030b200341dc006a41013602002003420237024c200341d093cc003602482003410136022c2003200341286a3602582003200341206a360228200341386a200341c8006a1041200341386a21020c030b2006200441286c6a210803402001417f6a2101034020082002460d06200241186a2105200241286a2207210220052d00000d000b2007210220010d000b200741586a21020b2002411c6a21020b2003200228020022023602240240200920024d0d00200a20024104746a2202450d0020002002360204410021020c040b200341dc006a4102360200200341c4006a41013602002003420337024c200341e093cc003602482003410136023c2003200341386a3602582003200341206a3602402003200341246a360238200341286a200341c8006a1041200341286a21020b20022802002105200041086a200229020437020020002005360204410121020c020b419e92cc0041c20041e092cc001064000b41f092cc0041dd0041e092cc001064000b20002002360200200341e0006a24000bec0201087f024020002802002201450d0020002802082102024020002802042200450d00034020012802940321012000417f6a22000d000b0b02402002450d0041002103024003402001450d01410021040240200320012f0106490d00034002400240200128020022000d0041002103410021000c010b200441016a210420012f010421030b2001103520002101200320002f01064f0d000b200021010b200341016a2105200120034105746a220041c4006a2802002106200041386a2802002107200041346a28020021080240024020040d00200521030c010b200120054102746a4194036a2802002101410021032004417f6a2200450d00034020012802940321012000417f6a22000d000b0b20064102460d022002417f6a210202402007450d00200810350b20020d000c020b0b41958dcc00412b41c08dcc00103f000b2001450d0020012802002100200110352000450d00034020002802002101200010352001210020010d000b0b0b2600024020002802002d00000d002001419d9fc0004105105a0f0b200141a29fc0004104105a0b8c0902047f017e230041106b2202240002400240024020010d00200041ac013a00000c010b024002400240024020012d00002203414f6a41fb004f0d000c010b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e312c2c0001022c2c0304052c06072c2c08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292c0b20012d00012104410221030c2b0b20012d00012104410321030c2a0b20012d00012104410421030c290b200141046a2802002105410721030c270b200141046a2802002105410821030c260b200141046a2802002101410c10332205450d28200241086a2001280200200141046a28020010d607200229030821062005200128020836020820052006370200410921030c250b200141046a2802002105410b21030c240b200141046a280200210520012d00012104410c21030c240b200141046a2802002105410f21030c220b200141046a2802002105411021030c210b200141046a2802002105411121030c200b200141046a2802002105411221030c1f0b200141046a2802002105411321030c1e0b200141046a280200210520013502082106411421030c1d0b200141046a280200210520013502082106411521030c1c0b200141046a280200210520013502082106411621030c1b0b200141046a280200210520013502082106411721030c1a0b200141046a280200210520013502082106411821030c190b200141046a280200210520013502082106411921030c180b200141046a280200210520013502082106411a21030c170b200141046a280200210520013502082106411b21030c160b200141046a280200210520013502082106411c21030c150b200141046a280200210520013502082106411d21030c140b200141046a280200210520013502082106411e21030c130b200141046a280200210520013502082106411f21030c120b200141046a280200210520013502082106412021030c110b200141046a280200210520013502082106412121030c100b200141046a280200210520013502082106412221030c0f0b200141046a280200210520013502082106412321030c0e0b200141046a280200210520013502082106412421030c0d0b200141046a280200210520013502082106412521030c0c0b200141046a280200210520013502082106412621030c0b0b200141046a280200210520013502082106412721030c0a0b200141046a280200210520013502082106412821030c090b200141046a280200210520013502082106412921030c080b200141046a280200210520013502082106412a21030c070b20012d00012104412b21030c070b20012d00012104412c21030c060b200141046a2802002105412d21030c040b20012903082106412e21030c020b200141046a2802002105412f21030c020b20012903082106413021030b0b0b200020043a0001200020033a0000200041086a2006370300200041046a20053602000b200241106a24000f0b103c000bc60501087f230041106b220324002002280208220441546a2105200241106a280200220641306c210702400340410021082007450d01200741506a21072005412c6a2109200541306a220a210520092d00004103470d000b200a41086a2802002207450d00200741286c2105200a28020041186a2107410021080340200820072d0000456a2108200741286a2107200541586a22050d000b0b024002400240024002400240200120086b220a20014b0d00200641306c2107200441546a210503402007450d02200741506a21072005412c6a2108200541306a2209210520082d0000410c470d000b200941086a280200200a4b0d03411e10332207450d052000200736020420004101360200200741166a4100290096924c370000200741106a4100290090924c370000200741086a4100290088924c37000020074100290080924c370000200041086a429e808080e0033702000c040b412c103322070d010c040b412c10332207450d032000200736020420004101360200200741286a41002800fc914c360000200741206a41002900f4914c370000200741186a41002900ec914c370000200741106a41002900e4914c370000200741086a41002900dc914c370000200741002900d4914c370000200041086a42ac808080c0053702000c020b2000200736020420004101360200200741286a41002800d0914c360000200741206a41002900c8914c370000200741186a41002900c0914c370000200741106a41002900b8914c370000200741086a41002900b0914c370000200741002900a8914c370000200041086a42ac808080c0053702000c010b2009280200200a41186c6a28020821072003200a200210db07024020032802004101470d0020002003290204370204200041013602002000410c6a2003410c6a2802003602000c010b20032802042105200041003602002000200520076a3602040b200341106a24000f0b1045000b100020002802003502004101200110520b8903010a7f230041206b220124000240024002400240200041086a2802002202450d00410020024102746b2103417f210420002802002205210603402003450d01200441016a2104200341046a210320062802002107200641046a21062007450d000b4100200741004741016a41017122066b2004460d002002200620046a2208490d012002200741004741016a4101716b20046b220641ffffffff03712006470d0220064102742209417f4c0d024104210a02402009450d0020091033220a450d040b200141003602182001200a36021020012009410276360214200141106a410020061086012001280210200128021822064102746a200520084102746a4104200741004741016a410171220741027420036a6b109d081a200141086a22032002200620076b6a20046b360200200120012903103703000240200041046a28020041ffffffff0371450d00200028020010350b20002001290300370200200041086a20032802003602000b200141206a24000f0b2008200241cc95cc001059000b1044000b1045000bb90403077f017e097f02400240024002400240200141086a2802002203200241086a2802002204200320044b1b220541016a22064101200641014b1b220741ffffffff03712007470d0020074102742208417f4c0d00200810392209450d01024020050d004200210a0c040b2004417f6a220b20044b210c2002280200210d2003417f6a220e20034b0d022001280200210f2007417f6a2102200820096a417c6a2110410021064200210a03404100211102402003200e20066b22124d0d00410021112012200e4b0d00200f20124102746a28020021110b410021120240200c0d002004200b20066b22134d0d002013200b4b0d00200d20134102746a28020021120b200720024d0d052010200a2011ad7c2012ad7c220a3e02002010417c6a21102002417f6a2102200a422088210a200641016a22062005490d000c040b0b1044000b1045000b2007417f6a2102200820096a417c6a2111410021104200210a0340410021060240200c0d00410021062004200b20106b22124d0d00410021062012200b4b0d00200d20124102746a28020021060b200720024d0d022011200a2006ad7c220a3e02002011417c6a21112002417f6a2102200a422088210a201041016a22102005490d000b0b024020072005417f736a220220074f0d00200020073602082000200841027636020420002009360200200920024102746a200a3e02000240200141046a28020041ffffffff0371450d00200128020010350b0f0b2002200741bc95cc001042000b2002200741bc95cc001042000bb404030e7f017e017f02400240200241086a2802002203200141086a28020022046a22054101200541014b1b220641ffffffff03712006470d0020064102742207417f4c0d000240200710392208450d002004450d022001280200210902400240024020030d002006417f6a2105200720086a417c6a210a20092004417f6a22024102746a21030340200420024d0d0302402003280200450d00200620054d0d03200a41003602000b2003417c6a2103200a417c6a210a2005417f6a21052002417f6a2202417f470d000c060b0b200720086a417c6a210b200341027420022802006a417c6a210c4100210d2006210e03402004200d417f736a220220044f0d020240200920024102746a220f2802002210450d0042002111417f2102200b2105200c210a024003402006200e20026a22124d0d012005200a3502002010ad7e20117c20053502007c22113e0200201142208821110240200320026a0d002006200d20036a417f736a220520064f0d05200820054102746a20113e02000c030b2005417c6a2105200a417c6a210a200f280200211020032002417f6a22026a22122003490d000b2012200341ac95cc001042000b2012200641ac95cc001042000b200b417c6a210b200e417f6a210e200d41016a220d2004460d050c000b0b2005200641bc95cc001042000b2002200441ac95cc001042000b1045000b1044000b2000200636020820002007410276360204200020083602000240200141046a28020041ffffffff0371450d00200128020010350b0bca0302097f017e230041106b2201240002400240024002400240024002402000280200220228020041016a41004c0d002000280204220328020041016a41004c0d012000280208220441086a28020022054101200028020c22062802006b22076a220820054f0d02200720002802142802006b22052000280210220741086a28020022006a220920054f0d03024002402002290308220a42ffffffff0f560d0041002100200a200428020020084102746a3502007e2003290308422086200728020020094102746a35020084580d010b20022802000d052002410036020020022002290308427f7c370308200441086a2802002200200020062802006b22024d0d0620032802000d07200428020020024102746a350200210a200341003602002003200a20032903087c370308410121000b200141106a240020000f0b41ac96cc004118200141086a41c496cc0041d496cc001046000b41ac96cc004118200141086a41c496cc0041d496cc001046000b2008200541ac95cc001042000b2009200041ac95cc001042000b41a797cc004110200141086a41b897cc0041c897cc001046000b2002200041ac95cc001042000b41a797cc004110200141086a41b897cc0041c897cc001046000ba80301087f200028020822024102742103410021042000280200220521000240024003402003450d012004417f6a21042003417c6a210320002802002106200041046a21002006450d000b410121072004417f73200641004741016a4101716a21080c010b41002107410020046b21080b200128020822094102742103410021042001280200220121000240024003402003450d012004417f6a21042003417c6a210320002802002106200041046a21002006450d000b410021032004417f73200641004741016a4101716a21000c010b410020046b2100410121030b024020070d00410020034101736b0f0b4101210402400240024020030d0020022008490d0120092000490d02417f200220086b2203200920006b22064720032006491b22040d0020062003200320064b1b2107200120004102746a2103200520084102746a2100417f210103400240200141016a22012007490d0041000f0b2003280200210420002802002106200341046a2103200041046a2100417f200620044720062004491b2204450d000b0b20040f0b2008200241dc95cc001059000b2000200941ec95cc001059000b100020002802002000280204200110720bcd04010a7f230041106b220224002002410036020820024204370300200128000c2103410021040240024002400240024002400240024020012802042205200128020022064920012d00084100477222010d004100200520066b2204200420054b1b220741016a220420074f0d00200341086a21084100210441042109410021010340200828020022072005417f736a220a20074f0d02200620054f2107200520062005496b21052003280200200a4102746a280200210a024020012002280204470d0020022001417f41004100417f4100200520066b2209200920054b1b220941016a220b200b2009491b20071b20052006491b220941016a220b200b2009491b108601200228020021090b200920046a200a3602002002200141016a2201360208200441046a21042005200649200772450d000c070b0b2002410020041086012002280208210b20010d042002280200200b4102746a2104200520064d0d012005417f732101200341086a21092005210703402001200928020022086a220a20014f0d0320042003280200200a4102746a280200360200200141016a2101200441046a210420062007417f6a2207490d000b200520066b200b6a210b0c030b200a200741ac95cc001042000b20052006460d010c020b200a200841ac95cc001042000b200341086a28020022052006417f736a220620054f0d022004200328020020064102746a280200360200200b41016a210b0b2002200b3602080b20002002290300370200200041086a200241086a280200360200200241106a24000f0b2006200541ac95cc001042000b1c00200128021841ed9dcc00410f2001411c6a28020028020c1100000bb00301047f230041c0006b2202240020002802002103410121000240200128021841e29ec000410c2001411c6a28020028020c1100000d0002400240200328020822000d0020032802002200200328020428020c11070042e4aec285979ba58811520d012002200036020c2002413b36021420022002410c6a36021020012802182104200128021c2105410121002002413c6a41013602002002420237022c200241f09ec0003602282002200241106a36023820042005200241286a10430d020c010b2002200036020c2002410836021420022002410c6a36021020012802182104200128021c2105410121002002413c6a41013602002002420237022c200241f09ec0003602282002200241106a36023820042005200241286a10430d010b200328020c2100200241106a41146a4101360200200241106a410c6a410136020020022000410c6a3602202002200041086a360218200241043602142002200036021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241809fc0003602282002200241106a36023820002001200241286a104321000b200241c0006a240020000b21002000417f6a41ff01712002ad4220862001ad842004ad4220862003ad8410000b1c00200128021841ed9dcc00410f2001411c6a28020028020c1100000b1c00200128021841ed9dcc00410f2001411c6a28020028020c1100000b9a0601037f230041d0006b22042400200420033a000f02400240024020022802082205450d00200141086a2802002106200541037420022802006a41786a220528020021020240024020052d0006450d0020062002460d010b024002400240200620024d0d00200141086a2006417f6a2202360200200128020020026a2d00002201417c6a220241014b0d0220020e020301030b412b10332202450d04200041013a0000200241276a41002800e5a94c360000200241206a41002900dea94c370000200241186a41002900d6a94c370000200241106a41002900cea94c370000200241086a41002900c6a94c370000200241002900bea94c370000200041086a42ab808080b005370200200041046a20023602000c050b411810332202450d03200241106a410029008eb04c370000200241086a4100290086b04c370000200241002900feaf4c37000020044298808080800337022420042002360220200441c4006a410136020020044201370234200441acaacc003602302004413836024c2004200441c8006a3602402004200441206a360248200441106a200441306a104102402004280224450d00200428022010350b200041013a0000200041046a20042903103702002000410c6a200441106a41086a2802003602000c040b02400240200341ff017122024104460d0020012002470d010b200041003a0000200020013a00010c040b200420013a0048200441c4006a4102360200200441206a410c6a413d36020020044202370234200441eca9cc003602302004413d3602242004200441206a3602402004200441c8006a36022820042004410f6a360220200441106a200441306a10412000410c6a200441186a280200360200200041046a2004290310370200200041013a00000c030b20004180083b01000c020b2004411810fb072004410036023820042004290300370330200441306a4100411810fc0720042802302202200428023822006a411841feafcc00411810fd072004200041186a360238200420042902343702342004200236023041d4a4cc004134200441306a41b4a4cc004188a5cc001046000b1045000b200441d0006a24000be40502047f017e230041d0006b220324000240024002400240024002400240200241086a2802002204450d00200228020022052004417f6a22044103746a2d000522064104460d02200341386a20012002200610f20720032d00384101470d012000200329023c370200200041086a200341c4006a2802003602000c060b411810332202450d04200241106a410029008eb04c370000200241086a4100290086b04c370000200241002900feaf4c37000020034298808080800337021420032002360210200341cc006a41013602002003420137023c200341acaacc00360238200341383602342003200341306a3602482003200341106a360230200341206a200341386a1041200041086a200341206a41086a280200360200200020032903203702002003280214450d05200328021010350c050b200241086a2802002204450d012004417f6a2104200228020021050b200241086a2004360200200520044103746a290200220742808080808080c0ff0083428080808080808001510d00200141086a28020021022003200737030820022007a7470d01200041003602000c030b411810332202450d01200241106a410029008eb04c370000200241086a4100290086b04c370000200241002900feaf4c37000020034298808080800337021420032002360210200341cc006a41013602002003420137023c200341acaacc00360238200341383602342003200341306a3602482003200341106a360230200341206a200341386a1041200041086a200341206a41086a280200360200200020032903203702002003280214450d02200328021010350c020b200341cc006a41023602002003412c6a41013602002003420237023c200341aca8cc0036023820034101360224200320023602302003200341206a3602482003200341086a3602282003200341306a360220200341106a200341386a1041200041086a200341106a41086a280200360200200020032903103702000c010b1045000b200341d0006a24000bef0302037f017e230041c0006b22042400200441286a20012002200310f2070240024002400240024020042d00284101460d0002400240200141086a2802002202200128020c4f0d0002402002200141046a280200470d00200241016a22052002490d05200241017422062005200620054b1b22054100480d050240024020020d002005103322060d010c090b2001280200210620022005460d0020062002200510372206450d080b20012006360200200141046a2005360200200141086a28020021020b200128020020026a20033a0000200141086a2201200128020041016a3602000c010b2004413c6a220341013602002004420137022c200441e8b1cc003602282004410136021420042001410c6a3602102004200441106a360238200441186a200441286a104120042802182201450d002004200429021c37020420042001360200200341013602002004420137022c200441acaacc00360228200441383602142004200441106a36023820042004360210200441186a200441286a104120042802182101200429021c210702402004280204450d00200428020010350b20010d020b200041003602000c030b2000200429022c370200200041086a200441346a2802003602000c020b20002007370204200020013602000c010b103e000b200441c0006a24000f0b103c000ba80301057f230041c0006b2203240020032002360200024002402001280204220420024b0d002001280208417c6a21052001410c6a280200410374210102400340024020010d00200320043602042003412c6a4102360200200341306a410c6a41013602002003420337021c200341c8b2cc00360218200341013602342003200341306a3602282003200341046a36023820032003360230200341086a200341186a10412000410c6a200341106a280200360200200041046a2003290308370200200041013a00000c040b2004200541046a2802006a22062004490d01200141786a2101200541086a2105200420024b21072006210420070d0020062104200620024d0d000b20052d00002104200041003a0000200020043a00010c020b0240412010332204450d00200041013a0000200441186a41002900c0b24c370000200441106a41002900b8b24c370000200441086a41002900b0b24c370000200441002900a8b24c370000200041086a42a08080808004370200200041046a20043602000c020b1045000b200041003a00002000200128020020026a2d00003a00010b200341c0006a24000bbd0201037f230041106b220224000240024020002d00004104470d002002200128021841a0a7cc0041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b200220012802184185a7cc0041082001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a4190a7cc00106f210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841d6a0c00041012004411c6a28020028020c1100000d010b2001280200220028021841cca6cc0041012000411c6a28020028020c11000021000b200120003a00080b200241106a2400200041ff01714100470b930602037f017e230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200541386a200141186a2203200141286a410010f20720052d00384101470d012000200529023c370200200041086a200541c4006a2802003602000c020b200541cc006a41023602002005411c6a41013602002005420337023c20054184a6cc00360238200541013602142005200541106a36024820052005410c6a3602182005200541086a360210200541206a200541386a1041200041086a200541206a41086a280200360200200020052903203702000c010b200128020021022005410036022002400240024020022802080d00200541cc006a41013602002005420237023c200541fcadcc00360238200541013602342005200541306a3602482005200541206a360230200541106a200541386a1041200528021022020d010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d04200241017422072006200720064b1b22064100480d040240024020020d002006103322030d010c080b2003280200210320022006460d0020032002200610372203450d070b200120033602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2202200228020041016a3602000c010b200541cc006a220241013602002005420137023c200541e8b1cc0036023820054101360234200520063602302005200541306a360248200541106a200541386a104120052802102201450d002005200529021437022420052001360220200241013602002005420137023c200541acaacc00360238200541383602342005200541306a3602482005200541206a360230200541106a200541386a1041200528021021022005290214210802402005280224450d00200528022010350b20020d010b200041003602000c040b20002008370204200020023602000c030b103e000b20002005290214370204200020023602000c010b103c000b200541d0006a24000bb00301017f230041d0006b22052400200520023602082005200336020c02400240024002400240417f41012002411f71742002411f4b1b20034b0d002001280200210220054100360234024020022802080d00200541cc006a41013602002005420237023c200541fcadcc00360238200541013602142005200541106a3602482005200541346a360210200541206a200541386a1041200528022022020d020b200541386a200141186a2202200141286a2203200410f20720052d00384101460d02200541386a20022003410010f20720052d00384101460d03200041003602000c040b200541cc006a41023602002005412c6a41013602002005420337023c20054184a6cc00360238200541013602242005200541206a36024820052005410c6a3602282005200541086a360220200541106a200541386a1041200041086a200541106a41086a280200360200200020052903103702000c030b20002005290224370204200020023602000c020b2000200529023c370200200041086a200541c4006a2802003602000c010b2000200529023c370200200041086a200541c4006a2802003602000b200541d0006a24000bb10402047f017e230041c0006b22032400200341286a200141186a2204200141286a2205200210f20702400240024020032d00284101460d00200341286a20042005200210f20720032d00284101470d012000200329022c370200200041086a200341346a2802003602000c020b2000200329022c370200200041086a200341346a2802003602000c010b02400240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d04200241017422062005200620054b1b22054100480d040240024020020d002005103322040d010c070b2004280200210420022005460d0020042002200510372204450d060b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c010b2003413c6a220141013602002003420137022c200341e8b1cc0036022820034101360214200320053602102003200341106a360238200341186a200341286a104120032802182202450d002003200329021c37020420032002360200200141013602002003420137022c200341acaacc00360228200341383602142003200341106a36023820032003360210200341186a200341286a104120032802182101200329021c210702402003280204450d00200328020010350b20010d010b200041003602000c030b20002007370204200020013602000c020b103e000b103c000b200341c0006a24000bb10402057f017e230041c0006b22032400200341286a200141186a2204200141286a2205200210f20702400240024020032d00284101460d00200341286a20042005200210f20720032d00284101470d012000200329022c370200200041086a200341346a2802003602000c020b2000200329022c370200200041086a200341346a2802003602000c010b02400240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d04200541017422072006200720064b1b22064100480d040240024020050d002006103322040d010c070b2004280200210420052006460d0020042005200610372204450d060b200120043602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c010b2003413c6a220141013602002003420137022c200341e8b1cc0036022820034101360214200320063602102003200341106a360238200341186a200341286a104120032802182202450d002003200329021c37020420032002360200200141013602002003420137022c200341acaacc00360228200341383602142003200341106a36023820032003360210200341186a200341286a104120032802182101200329021c210802402003280204450d00200328020010350b20010d010b200041003602000c030b20002008370204200020013602000c020b103e000b103c000b200341c0006a24000b3101017f0240024020010d0041002101410121020c010b2001103322020d001045000b20002002360200200020013602040b950101017f024002400240200041046a280200220320016b20024f0d00200120026a22022001490d01200341017422012002200120024b1b22014100480d010240024020030d00024020010d00410121020c020b2001103322020d010c040b2000280200210220032001460d0020022003200110372202450d030b20002002360200200041046a20013602000b0f0b103e000b103c000bea0101017f230041e0006b22042400200420013602082004200336020c024020012003470d00200020022001109d081a200441e0006a24000f0b200441286a41146a410a360200200441346a410c360200200441106a41146a41033602002004200441086a36024020042004410c6a360244200441c8006a41146a410036020020044203370214200441a0b3cc003602102004410c36022c200441b0b4cc003602582004420137024c200441f4b3cc003602482004200441286a3602202004200441c8006a3602382004200441c4006a3602302004200441c0006a360228200441106a41b0b4cc00104c000b17000240200041046a280200450d00200028020010350b0b1500200028020022002802002000280208200110720b1000200120002802002000280208105a0bfb0101027f230041106b22022400200220012802184190b2cc0041052001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a4198b2cc00106f1a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d0041012101200028021841d6a0c00041012000411c6a28020028020c1100000d010b2002280200220128021841cca6cc0041012001411c6a28020028020c11000021010b200220013a00080b200241106a2400200141ff01714100470b8a0202017f037e230041106b220524002001200210950842ffffffff0f832003200410950842ffffffff0f83108d082106200120021095084220882003200410950842ffffffff0f83108d0820064220887c220742208810890821082005200320041095084220882001200210950842ffffffff0f83108d08200742ffffffff0f837c2207422086200642ffffffff0f8384200820074220881089087c2001200210950842208820032004109508422088108d081089087c2001200210960820032004109508108908108d08108c082001200210950810890820032004109608108d08108c08109708200529030021032000200541086a29030037030820002003370300200541106a24000bdc0302017f057e230041f0006b2206240020054100360200200641e0006a2001200220032004109208200641e0006a41086a290300210720062903602108200641d0006a10910802400240024002402006290350200185200641d0006a41086a29030020028584500d00200641c0006a1091082006290340200385200641c0006a41086a29030020048584500d012002423f872209200185220120097d220a420254200920028520097d2001200954ad7d22014200532001501b0d032004423f872202200385220320027d220b420254200220048520027d2003200254ad7d22044200532004501b0d0320092002852202200284500d02200641306a109108200641206a2006290330200641306a41086a2903004200200b7d42002004200b420052ad7c7d109408200a2006290320562001200641206a41086a29030022025520012002511b450d03200541013602000c030b200342025441002004501b0d02200541013602000c020b200142025441002002501b0d01200541013602000c010b200641106a10900820062006290310200641106a41086a290300200b2004109408200a2006290300582001200641086a29030022025720012002511b0d00200541013602000b2000200837030020002007370308200641f0006a24000b3c01017f230041106b2205240020052001200220032004108208200529030021012000200541086a29030037030820002001370300200541106a24000b3e01017f230041106b22062400200620012002200320042005108308200629030021012000200641086a29030037030820002001370300200641106a24000b3c01017f230041106b2205240020052001200220032004109b08200529030021012000200541086a29030037030820002001370300200541106a24000b040000000b8c0202017f027e230041e0006b22052400200541d0006a2002423f872206200185200620028520062006109308200541d0006a41086a290300210120052903502107200541c0006a2004423f872202200385200220048520022002109308200541c0006a41086a290300210420052903402103200541306a20072001108e08200541306a41086a290300210120052903302107200541206a20032004108e08200541106a200720012005290320200541206a41086a290300108f0820052005290310200541106a41086a290300108e08200541086a2903002104200020052903002002200685220685220220067d3703002000200420068520067d2002200654ad7d370308200541e0006a24000b040020000b1500024020014200520d00108708000b20002001800b1500024020014200520d00108708000b20002001820b0700200120007c0b0700200120007e0b100020002002370308200020013703000b4901017f230041106b22052400024020032004844200520d00108708000b200520012002200320041098082000200541086a29030037030820002005290300370300200541106a24000b1900200042ffffffffffffffffff003703082000427f3703000b19002000428080808080808080807f370308200042003703000b3801017f230041106b22052400200520032004200120021084082000200541086a29030037030820002005290300370300200541106a24000b1d002000200120037d3703002000200220047d2001200354ad7d3703080b6a01017f230041106b22052400024002402003200484500d0020012002428080808080808080807f85844200520d012003200483427f520d010b108708000b20052001200220032004109c082000200541086a29030037030820002005290300370300200541106a24000b040020000b040020010b100020002002370308200020013703000b3c01017f230041106b2205240020052001200220032004109908200529030021012000200541086a29030037030820002001370300200541106a24000b3e01017f230041106b22052400200520012002200320044100109a08200529030021012000200541086a29030037030820002001370300200541106a24000bc00704017f027e027f047e230041d0006b22062400024002400240024002400240024002400240024020012002109608500d002003200410950821072003200410960821082007500d012008500d022003200410960879a72001200210960879a76b2209413f4b0d0341ff0020096b210a200941016a21090c080b024020032004109608500d0020050d040c060b02402005450d002001200210950820032004109508108b08210720054200370308200520073703000b2001200210950820032004109508108a0821010c060b2008500d0302400240024020012002109508500d00200320041096087b4201510d012003200410960879a72001200210960879a76b2209413e4b0d0241ff0020096b210a200941016a21090c090b02402005450d00200642002001200210960820032004109608108b08109708200629030021072005200641086a290300370308200520073703000b2001200210960820032004109608108a0821010c070b02402005450d00200641106a200120021095082001200210960820032004109608427f7c83109708200629031021072005200641186a290300370308200520073703000b20012002109608200320041096087a423f838821010c060b2005450d040c020b0240200320041095087b4201510d0041bf7f2003200410950879a72001200210960879a76b22096b210a200941c1006a21090c060b02402005450d0020012002109508210720032004109508210820054200370308200520072008427f7c833703000b200320041095084201510d06200641c0006a20012002200320041095087aa710a408200641c8006a2903002102200629034021010c060b2005450d020b2005200137030020052002370308420021010c020b108708000b420021010b420021020c010b200641206a20012002200a41ff007110a308200641306a20012002200941ff007110a408200641206a41086a2903002102200641306a41086a290300210b20062903202101200629033021070240024020090d00420021084200210c0c010b4200210c4200210d0340200b4201862007423f888422082008427f8520047c20074201862002423f88842207427f85220820037c200854ad7c423f8722082004837d20072008200383220e54ad7d210b2007200e7d2107420020024201862001423f8884842102200d200142018684210120084201832208210d2009417f6a22090d000b0b02402005450d00200520073703002005200b3703080b200c20024201862001423f8884842102200820014201868421010b2000200137030020002002370308200641d0006a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a109a08200529031021012000200529031837030820002001370300200541206a24000b3c01017f230041106b2205240020052001200220032004108808200529030021012000200541086a29030037030820002001370300200541106a24000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200041016a2100200141016a21012002417f6a2202450d020c000b0b200420056b21030b20030bac0102017f037e230041206b2204240002400240200341c000710d002003450d01200120021095082105200120021096082106200420052003413f71ad22078620012002109508410020036b413f71ad88200620078684109708200441086a2903002102200429030021010c010b200441106a4200200120021095082003413f71ad86109708200441186a2903002102200429031021010b2000200137030020002002370308200441206a24000b9e0102017f027e230041106b22042400024002400240200341c000710d002003450d02200120021096082105200120021095082003413f71ad2206882005410020036b413f71ad868421052001200210960820068821010c010b200120021096082003413f71ad882105420021010b200420052001109708200441086a2903002102200429030021010b2000200137030020002002370308200441106a24000b3a01017f230041106b22042400200420012002200310a108200429030021012000200441086a29030037030820002001370300200441106a24000b3a01017f230041106b22042400200420012002200310a208200429030021012000200441086a29030037030820002001370300200441106a24000b0bb4b50c0300418080c0000b89b50c6361706163697479206f766572666c6f7700000024001000170000006e020000050000007372632f6c6962616c6c6f632f7261775f7665632e727300cb0010004600000068010000130000004200000004000000040000004300000044000000450000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f720042000000000000000100000046000000b8001000130000004a020000050000007372632f6c6962616c6c6f632f666d742e72732f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f666d742f6d6f642e72730000004f0110001600000065011000160000004c131300010000003c01100013000000ca0300000d0000007372632f6c6962616c6c6f632f7665632e7273737761705f72656d6f766520696e6465782028697320292073686f756c64206265203c206c656e202869732000a401100014000000b8011000170000004c131300010000003c01100013000000f10300000d000000696e73657274696f6e20696e6465782028697320292073686f756c64206265203c3d206c656e202869732000f80110001200000065011000160000004c131300010000003c01100013000000210400000d00000072656d6f76616c20696e646578202869732000003402100014000000b8011000170000004c131300010000003c01100013000000330500000d000000656e6420647261696e20696e6465782028697320010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202020202020202020202020202020202020202020203030303030303030303030303030303040404040400000000000000000000006803100020000000880310001200000042000000000000000100000047000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e646578206973203030303130323033303430353036303730383039313031313132313331343135313631373138313932303231323232333234323532363237323832393330333133323333333433353336333733383339343034313432343334343435343634373438343935303531353235333534353535363537353835393630363136323633363436353636363736383639373037313732373337343735373637373738373938303831383238333834383538363837383838393930393139323933393439353936393739383939000074041000060000007a04100022000000696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820ac04100016000000c20410000d000000736c69636520696e64657820737461727473206174202062757420656e64732061742000330f100016000000040800002f0000005b2e2e2e5d000000480510000b0000001d0f1000160000008705100001000000fb0e10000e000000090f1000040000000d0f1000100000008705100001000000480510000b00000053051000260000007905100008000000810510000600000087051000010000006279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f66206060c605100002000000b0051000160000005604000024000000b0051000160000004c040000110000007372632f6c6962636f72652f666d742f6d6f642e72732e2eda05100016000000540000001400000030787372632f6c6962636f72652f666d742f6e756d2e727300010305050606030706080809110a1c0b190c140d100e0d0f0410031212130916011705180219031a071c021d011f1620032b032c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f00d11454964658084b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f7475962f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab35280b80e003190801042f043404070301070607110a500f1207550703041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a06213f4c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b32d740c80d61a0c0580ff0580df0cee0d03848d033709815c1480b80880cb2a38030a06380846080c06740b1e035a0459098083181c0a16094c04808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b020e041001110212051311140115021702190d1c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f802f902fa02fb010c273b3e4e4f8f9e9e9f060709363d3e56f3d0d1041418363756577faaaeafbd35e01287898e9e040d0e11122931343a4546494a4e4f64655cb6b71b1c07080a0b141736393aa8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d0aeaf79cc6e6f935e227b0503042d036603012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a8126524e28082a561c1417094e041e0f430e19070a0648082709750b3f412a063b050a0651060105100305808b621e48080a80a65e22450b0a060d1339070a362c041080c03c64530c48090a46451b4808531d398107460a1d03474937030e080a0639070a81361980b7010f320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140050b020e97f80884d62a09a2f7811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a80ae381d0d2c040907020e06809a83d8080d030d03740c59070c140c0438080a062808224e81540c15030305070919070709030d072980cb250a840600580b1000200000000a0000001c000000580b1000200000001a000000280000007372632f6c6962636f72652f756e69636f64652f7072696e7461626c652e72730003000083042000910560005d13a0001217a01e0c20e01eef2c202b2a30a02b6fa6602c02a8e02c1efbe02d00fea0359effe035fd016136010aa136240d6137ab0ee1382f182139301c6146f31ea14af06a614e4f6fa14e9dbc214f65d1e14f00da215000e0e15130e16153ece2a154d0e8e15420002e55f001bf55d80e100023000000520000003e00000000700007002d0101010201020101480b30151001650702060202010423011e1b5b0b3a09090118040109010301052b03770f0120370101010408040103070a021d013a0101010204080109010a021a010202390104020402020303011e0203010b0239010405010204011402160601013a0101020104080107030a021e013b0101010c0109012801030139030503010407020b021d013a01020102010301050207020b021c02390201010204080109010a021d0148010401020301010801510102070c08620102090b064a021b0101010101370e01050102050b0124090166040106010202021902040310040d01020206010f01000300031d031d021e02400201070801020b09012d03770222017603040209010603db0202013a010107010101010208060a020130113f0430070101050128090c0220040202010338010102030101033a0802029803010d0107040106010302c63a01050001c32100038d016020000669020004010a200250020001030104011902050197021a120d012608190b2e0330010204020227014306020202020c0108012f01330101030202050201012a020801ee010201040100010010101000020001e201950500030102050428030401a50200040002990bb001360f3803310402024503240501083e010c0234090a0402015f03020101020601a0010308150239020101010116010e070305c308020301011701510102060101020101020102eb010204060201021b025508020101026a0101010206010165030204010500090102f5010a0201010401900402020401200a280602040801090602032e0d010200070106010152160207010201027a060301010201070101480203010101000200053b0700013f0451010002000101030405080802071e0494030037043208010e011605010f000701110207010201050007000400076d07006080f000000000d80e1000230000004b00000028000000d80e10002300000057000000160000007372632f6c6962636f72652f756e69636f64652f756e69636f64655f646174612e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f6620607372632f6c6962636f72652f7374722f6d6f642e7273426f72726f774572726f72426f72726f774d75744572726f7270616e69636b6564206174200000990f1000010000009a0f100003000000301a130000000000980f100001000000980f1000010000003a27272c2066616c736574727565202020200000cc0f10001a0000008b01000026000000330f100016000000c30700002f0000007372632f6c6962636f72652f7374722f7061747465726e2e72730000f80f10001b00000052000000050000007372632f6c6962636f72652f736c6963652f6d656d6368722e7273207b202c20207b0a00420000000c0000000400000048000000490000004a0000002c0a00004200000004000000040000004b0000004c0000004d000000207d7d28280a2c0a5d5b0000330f100016000000800700002f000000bb101000260000006672616d655f737570706f72743a3a686173682f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f737570706f72742f7372632f686173682e7273496e76616c696420726576657273653a2068617368206c656e67746820746f6f2073686f72740000004200000004000000040000004e0000004f000000500000004200000000000000010000005100000052000000530000006d61782d77656967687461637475616c5f7765696768743d42000000000000000100000054000000550000005300000042000000000000000100000054000000550000005300000043616c6c4e6f74416c6c6f77656450687261676d656e426f67757353636f726550687261676d656e426f6775734564676550687261676d656e426f67757353656c66566f746550687261676d656e536c61736865644e6f6d696e6174696f6e50687261676d656e426f6775734e6f6d696e6174696f6e50687261676d656e426f6775734e6f6d696e61746f7250687261676d656e426f677573436f6d7061637450687261676d656e426f67757357696e6e657250687261676d656e426f67757357696e6e6572436f756e74536e617073686f74556e617661696c61626c6550687261676d656e5765616b5375626d697373696f6e50687261676d656e4561726c795375626d697373696f6e416c7265616479436c61696d65644e6f74536f72746564416e64556e69717565496e76616c69644e756d6265724f664e6f6d696e6174696f6e73496e76616c6964457261546f52657761726446756e6465645461726765744e6f556e6c6f636b4368756e6b4e6f4d6f72654368756e6b73496e73756666696369656e7456616c7565496e76616c6964536c617368496e6465784475706c6963617465496e646578456d70747954617267657473416c7265616479506169726564416c7265616479426f6e6465644e6f7453746173684e6f74436f6e74726f6c6c65725761726e696e673a20412073657373696f6e206170706561727320746f2068617665206265656e20736b69707065642e626f6e64626f6e645f6578747261756e626f6e6477697468647261775f756e626f6e64656476616c69646174656e6f6d696e6174656368696c6c7365745f70617965657365745f636f6e74726f6c6c65727365745f76616c696461746f725f636f756e74666f7263655f6e6f5f65726173666f7263655f6e65775f6572617365745f696e76756c6e657261626c6573666f7263655f756e7374616b65666f7263655f6e65775f6572615f616c7761797363616e63656c5f64656665727265645f736c6173687061796f75745f6e6f6d696e61746f727061796f75745f76616c696461746f727061796f75745f7374616b6572737265626f6e647365745f686973746f72795f6465707468726561705f73746173687375626d69745f656c656374696f6e5f736f6c7574696f6e7375626d69745f656c656374696f6e5f736f6c7574696f6e5f756e7369676e6564426f6e6465644c65646765724e6f6d696e61746f727356616c696461746f72536c617368496e4572614e6f6d696e61746f72536c617368496e457261536c617368696e675370616e735370616e536c617368536e617073686f7456616c696461746f7273536e617073686f744e6f6d696e61746f7273457261456c656374696f6e5374617475730000000000a81610000900000000000000b4161000030000000000000000000000cc161000020000000000000000000000dc161000060000000000000084111200020000000000000000000000e4161000010000000000000000000000ec161000050000000000000084111200020000000000000000000000f4161000010000000000000000000000fc1610001a0000000000000008f6120001000000000000000000000018171000020000000000000000000000281710000f000000000000003817100001000000000000000000000040171000010000000000000000000000c0141000060000000000000084111200020000000000000000000000481710000400000000000000000000006817100008000000000000008411120002000000000000000000000070171000010000000000000000000000781710000900000000000000841112000200000000000000000000008417100002000000000000004572615061796f7574000000b51a100008000000f615120007000000f6151200070000002e1a100056000000841a1000310000005265776172640000df1910004f000000536c61736800000096191000490000004f6c64536c617368696e675265706f727444697363617264656400003d1910004700000084191000120000005374616b696e67456c656374696f6e002e1910000f000000ea181000440000002a18100023000000301a1300000000004d18100054000000a118100049000000556e626f6e646564051810002500000057697468647261776e0000009417100057000000eb1710001a00000020416e206163636f756e74206861732063616c6c6564206077697468647261775f756e626f6e6465646020616e642072656d6f76656420756e626f6e64696e67206368756e6b7320776f727468206042616c616e6365602066726f6d2074686520756e6c6f636b696e672071756575652e20416e206163636f756e742068617320756e626f6e646564207468697320616d6f756e742e20416e206163636f756e742068617320626f6e646564207468697320616d6f756e742e204e4f54453a2054686973206576656e74206973206f6e6c7920656d6974746564207768656e2066756e64732061726520626f6e64656420766961206120646973706174636861626c652e204e6f7461626c792c2069742077696c6c206e6f7420626520656d697474656420666f72207374616b696e672072657761726473207768656e20746865792061726520616464656420746f207374616b652e2041206e657720736574206f66207374616b6572732077617320656c656374656420776974682074686520676976656e20636f6d7075746174696f6e206d6574686f642e456c656374696f6e436f6d7075746520416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64206e6f742062652070726f6365737365642e204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e20546865207374616b657220686173206265656e207265776172646564206279207468697320616d6f756e742e20604163636f756e7449646020697320746865207374617368206163636f756e742e2054686520657261207061796f757420686173206265656e207365743b207468652066697273742062616c616e6365206973207468652076616c696461746f722d7061796f75743b20746865207365636f6e64206973207468652072656d61696e6465722066726f6d20746865206d6178696d756d20616d6f756e74206f66207265776172642e457261496e6465785374616b696e674f6666636861696e45726173526577617264506f696e74734572617356616c696461746f7252657761726445726173546f74616c5374616b654572726f723a2073746172745f73657373696f6e5f696e646578206d7573742062652073657420666f722063757272656e745f657261517565756564456c65637465644572617356616c696461746f725072656673457261735374616b657273436c6970706564457261735374616b657273556e6170706c696564536c61736865730000000000731310000400000000000000a01f1000030000000000000000000000e81f1000110000000000000000000000771310000a00000000000000702010000100000000000000000000008820100011000000000000000000000081131000060000000000000010211000010000000000000000000000282110001b0000000000000000000000871310001100000000000000301a13000000000000000000000000000022100013000000000000000000000098131000080000000000000098221000010000000000000000000000b02210000c0000000000000000000000a0131000080000000000000010231000010000000000000000000000282310000d0000000000000000000000a81310000500000000000000301a1300000000000000000000000000902310000c0000000000000000000000ad1310000900000000000000f0231000010000000000000000000000082410000b0000000000000000000000b61310000e0000000000000060241000010000000000000000000000782410000b0000000000000000000000c41310001300000000000000d0241000010000000000000000000000e8241000010000000000000000000000d71310000d00000000000000301a1300000000000000000000000000f0241000050000000000000000000000e41310000d00000000000000301a130000000000000000000000000018251000060000000000000000000000f113100011000000000000004825100001000000000000000000000060251000010000000000000000000000021410000d0000000000000068251000010000000000000000000000802510000100000000000000000000000f1410001400000000000000301a130000000000000000000000000088251000050000000000000000000000231410001500000000000000b0251000020000000000000000000000e025100007000000000000000000000038141000100000000000000018261000020000000000000000000000482610001e00000000000000000000004814100010000000000000003827100001000000000000000000000050271000130000000000000000000000581410000e00000000000000e8271000020000000000000000000000182810000f000000000000000000000066141000060000000000000010211000010000000000000000000000902810000900000000000000000000006c1410001100000000000000d8281000010000000000000000000000f02810000300000000000000000000007d1410000a00000000000000682510000100000000000000000000000829100007000000000000000000000087141000180000000000000040291000040000000000000000000000a02910004a00000000000000000000009f141000210000000000000040291000040000000000000000000000f02b1000050000000000000000000000674810000a00000000000000f32012002300000000000000aa4d12000500000000000000807512001500000000000000f44810000500000000000000f94810001100000038531000590000009153100021000000301a130000000000b25310004c000000301a130000000000fe53100049000000301a1300000000001a53100010000000301a130000000000f5bd12000b000000475410003500000085201200080000007c5410001a000000301a1300000000009654100054000000ea5410005000000044be12000c000000000000002a5310000e0000000000000080751200150000005e51100059000000b75110000d000000301a130000000000c45110005400000018521000590000007152100013000000301a1300000000008452100058000000dc5210003e000000301a1300000000001a53100010000000301a130000000000f5bd12000b000000d54710003a0000008520120008000000ee8811001000000044be12000c00000000000000aa4d1200050000000000000080751200150000006f4d100055000000c44d100040000000044e100049000000301a1300000000004d4e1000520000009f4e100030000000301a130000000000cf4e10004f0000001e4f10004f0000006d4f10003f000000301a1300000000009f481000550000003c49100043000000301a130000000000ac4f100012000000301a130000000000be4f100026000000301a130000000000f5bd12000b000000e44f1000500000000f4810002600000034501000590000008d5010005c000000e9501000540000003d51100017000000ee88110010000000545110000a000000554b10004b000000301a130000000000a04b10004d000000ed4b100013000000301a1300000000009f481000550000003c49100043000000301a130000000000004c100013000000301a130000000000134c10001b000000301a130000000000f5bd12000b0000002e4c100055000000834c100051000000d44c10003d000000114d10005e000000354810003200000044be12000c00000000000000424b10000500000000000000474b10000e000000084b10003a000000301a1300000000004947100037000000301a1300000000009f481000550000003c49100043000000301a130000000000f5bd12000b000000d54710003a0000000f48100026000000354810003200000044be12000c00000000000000d94a10000700000000000000e04a1000280000009449100044000000301a130000000000d849100054000000233b100023000000301a1300000000009f481000550000003c49100043000000301a130000000000f5bd12000b0000002c4a100049000000754a10002e000000a34a10003600000044be12000c0000000a49100032000000301a1300000000004947100037000000301a1300000000009f481000550000003c49100043000000301a130000000000f5bd12000b000000d54710003a0000007f49100015000000354810003200000044be12000c00000000000000f44810000500000000000000f948100011000000714810002e000000301a1300000000004947100037000000301a1300000000009f48100055000000301a130000000000f5bd12000b000000d54710003a0000000f48100026000000354810003200000044be12000c00000000000000674810000a00000000000000f3201200230000002547100024000000301a1300000000004947100037000000301a1300000000008047100055000000301a130000000000f5bd12000b000000d54710003a0000000f48100026000000354810003200000044be12000c00000000000000842112000300000000000000194710000c000000f946100020000000cd4610002c000000301a130000000000f5bd12000b000000bd4610001000000044be12000c00000042461000530000009546100028000000301a130000000000f5bd12000b000000bd4610001000000044be12000c00000000000000804410000a00000000000000ddce1200110000000f46100033000000000000000a46100005000000000000007ac312000c000000c7451000430000007245100041000000301a130000000000f5bd12000b000000b34510001400000044be12000c00000000000000093910000300000000000000b51a10000800000000000000654510000d00000000000000c499120008000000a244100051000000f34410001c0000000f45100041000000301a130000000000f5bd12000b000000504510001500000044be12000c00000000000000093910000300000000000000b51a10000800000000000000804410000a000000000000008a44100018000000f03d100058000000483e1000570000009f3e100031000000301a130000000000ac40100029000000301a130000000000d54010003f000000383f100059000000913f10004c00000014411000560000006a41100049000000b341100022000000d54110004200000017421000480000005f42100028000000301a130000000000dd3f100057000000344010000e000000301a1300000000004240100051000000301a130000000000f5bd12000b0000008742100057000000de42100027000000054310004e00000053431000370000008a43100050000000da431000520000002c4410005400000044be12000c00000000000000093910000300000000000000b51a100008000000f03d100058000000483e1000570000009f3e100031000000301a130000000000d03e100029000000301a130000000000f93e10003f000000383f100059000000913f10004c000000301a130000000000dd3f100057000000344010000e000000301a1300000000004240100051000000301a130000000000f5bd12000b00000093401000190000009f9510003100000044be12000c00000000000000e13d10000f000000000000007ac312000c00000000000000093910000300000000000000b51a100008000000bf3b100044000000301a130000000000033c100053000000563c10004a000000a03c10004d000000301a130000000000ed3c100056000000433d10001e000000301a130000000000613d100040000000301a130000000000f5bd12000b000000a13d1000400000009f9510003100000044be12000c000000963a100038000000301a130000000000ce3a100055000000233b100023000000301a130000000000f5bd12000b000000463b10003c000000823b10003d00000044be12000c00000000000000743a10001100000000000000853a100011000000463a100019000000301a1300000000005f3a1000150000000c3910004e0000005a39100058000000b239100030000000301a130000000000e239100024000000301a130000000000063a10004000000000000000b83810000700000000000000bf3810001300000000000000d23810001300000000000000e53810001200000000000000f73810000500000000000000fc3810000d00000000000000093910000300000000000000b51a100008000000112d100038000000301a130000000000492d10000d000000562d100045000000301a1300000000009b2d100021000000301a130000000000bc2d10002b000000301a130000000000e72d10003d000000242e100054000000782e10000c000000301a130000000000842e10004a000000301a130000000000ce2e10002a000000301a130000000000f82e100032000000301a1300000000002a2f1000530000007d2f100047000000c42f10004c00000010301000540000006430100058000000bc30100026000000301a130000000000e230100018000000301a130000000000fa30100039000000333110003e000000713110002b0000009c31100055000000f131100057000000483210001000000058321000430000009b3210001b000000301a130000000000b632100030000000301a130000000000e6321000590000003f331000590000009833100050000000e833100027000000301a130000000000f5bd12000b0000000f341000590000006834100039000000301a130000000000a134100059000000fa34100052000000301a1300000000004c35100038000000301a1300000000008435100027000000ab35100026000000d135100027000000f835100037000000301a1300000000002f36100045000000743610003f000000b336100042000000f536100045000000301a1300000000003a3710004f000000893710005a000000301a130000000000e3371000230000000638100022000000301a130000000000283810002b0000005338100027000000301a1300000000007a3810003e00000044be12000c000000182c100030000000301a130000000000482c1000570000009f2c100058000000f72c10001a00000020556e7369676e65642076657273696f6e206f6620607375626d69745f656c656374696f6e5f736f6c7574696f6e602e204e6f746520746861742074686973206d757374207061737320746865205b6056616c6964617465556e7369676e6564605d20636865636b207768696368206f6e6c7920616c6c6f7773207472616e73616374696f6e732066726f6d20746865206c6f63616c206e6f646520746f20626520696e636c756465642e20496e206f7468657220776f7264732c206f6e6c792074686520626c6f636b20617574686f722063616e20696e636c7564652061207472616e73616374696f6e20696e2074686520626c6f636b2e205375626d697420612070687261676d656e20726573756c7420746f2074686520636861696e2e2049662074686520736f6c7574696f6e3a20312e2069732076616c69642e20322e206861732061206265747465722073636f7265207468616e206120706f74656e7469616c6c79206578697374696e6720736f6c7574696f6e206f6e20636861696e2e207468656e2c2069742077696c6c206265205f7075745f206f6e20636861696e2e204120736f6c7574696f6e20636f6e7369737473206f662074776f20706965636573206f6620646174613a20312e206077696e6e657273603a206120666c617420766563746f72206f6620616c6c207468652077696e6e657273206f662074686520726f756e642e20322e206061737369676e6d656e7473603a2074686520636f6d706163742076657273696f6e206f6620616e2061737369676e6d656e7420766563746f72207468617420656e636f64657320746865206564676520202020776569676874732e20426f7468206f66207768696368206d617920626520636f6d7075746564207573696e67205b6070687261676d656e605d2c206f7220616e79206f7468657220616c676f726974686d2e204164646974696f6e616c6c792c20746865207375626d6974746572206d7573742070726f766964653a202d20546865206073636f7265602074686174207468657920636c61696d20746865697220736f6c7574696f6e206861732e20426f74682076616c696461746f727320616e64206e6f6d696e61746f72732077696c6c20626520726570726573656e74656420627920696e646963657320696e2074686520736f6c7574696f6e2e2054686520696e64696365732073686f756c6420726573706563742074686520636f72726573706f6e64696e6720747970657320285b6056616c696461746f72496e646578605d20616e64205b604e6f6d696e61746f72496e646578605d292e204d6f72656f7665722c20746865792073686f756c642062652076616c6964207768656e207573656420746f20696e64657820696e746f205b60536e617073686f7456616c696461746f7273605d20616e64205b60536e617073686f744e6f6d696e61746f7273605d2e20416e7920696e76616c696420696e6465782077696c6c2063617573652074686520736f6c7574696f6e20746f2062652072656a65637465642e2054686573652074776f2073746f72616765206974656d73206172652073657420647572696e672074686520656c656374696f6e2077696e646f7720616e64206d6179206265207573656420746f2064657465726d696e652074686520696e64696365732e204120736f6c7574696f6e2069732076616c69642069663a20302e204974206973207375626d6974746564207768656e205b60457261456c656374696f6e537461747573605d20697320604f70656e602e20312e2049747320636c61696d65642073636f726520697320657175616c20746f207468652073636f726520636f6d7075746564206f6e2d636861696e2e20322e2050726573656e74732074686520636f7272656374206e756d626572206f662077696e6e6572732e20332e20416c6c20696e6465786573206d7573742062652076616c7565206163636f7264696e6720746f2074686520736e617073686f7420766563746f72732e20416c6c20656467652076616c756573206d75737420202020616c736f20626520636f727265637420616e642073686f756c64206e6f74206f766572666c6f7720746865206772616e756c6172697479206f662074686520726174696f20747970652028692e652e20323536202020206f722062696c6c696f6e292e20342e20466f72206561636820656467652c20616c6c2074617267657473206172652061637475616c6c79206e6f6d696e617465642062792074686520766f7465722e20352e2048617320636f72726563742073656c662d766f7465732e204120736f6c7574696f6e732073636f726520697320636f6e736973746564206f66203320706172616d65746572733a20312e20606d696e207b20737570706f72742e746f74616c207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265206d6178696d697a65642e20322e206073756d207b20737570706f72742e746f74616c207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265206d696e696d697a65642e20332e206073756d207b20737570706f72742e746f74616c5e32207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265202020206d696e696d697a65642028746f20656e73757265206c6573732076617269616e63652920453a206e756d626572206f662065646765732e206d3a2073697a65206f662077696e6e657220636f6d6d69747465652e206e3a206e756d626572206f66206e6f6d696e61746f72732e20643a2065646765206465677265652028313620666f72206e6f772920763a206e756d626572206f66206f6e2d636861696e2076616c696461746f722063616e646964617465732e204e4f54453a20676976656e206120736f6c7574696f6e20776869636820697320726564756365642c2077652063616e20656e61626c652061206e657720636865636b2074686520656e7375726520607c457c203c206e202b206d602e20576520646f6e277420646f2074686973205f7965745f2c20627574206f7572206f6666636861696e20776f726b657220636f6465206578656375746573206974206e6f6e657468656c6573732e206d616a6f722073746570732028616c6c20646f6e6520696e2060636865636b5f616e645f7265706c6163655f736f6c7574696f6e60293a202d2053746f726167653a204f28312920726561642060456c656374696f6e537461747573602e202d2053746f726167653a204f2831292072656164206050687261676d656e53636f7265602e202d2053746f726167653a204f2831292072656164206056616c696461746f72436f756e74602e202d2053746f726167653a204f283129206c656e67746820726561642066726f6d2060536e617073686f7456616c696461746f7273602e202d2053746f726167653a204f287629207265616473206f6620604163636f756e7449646020746f2066657463682060736e617073686f745f76616c696461746f7273602e202d204d656d6f72793a204f286d2920697465726174696f6e7320746f206d61702077696e6e657220696e64657820746f2076616c696461746f722069642e202d2053746f726167653a204f286e2920726561647320604163636f756e7449646020746f2066657463682060736e617073686f745f6e6f6d696e61746f7273602e202d204d656d6f72793a204f286e202b206d2920726561647320746f206d617020696e64657820746f20604163636f756e7449646020666f7220756e2d636f6d706163742e202d2053746f726167653a204f286529206163636f756e7469642072656164732066726f6d20604e6f6d696e6174696f6e6020746f207265616420636f7272656374206e6f6d696e6174696f6e732e202d2053746f726167653a204f2865292063616c6c7320696e746f2060736c61736861626c655f62616c616e63655f6f665f766f74655f7765696768746020746f20636f6e7665727420726174696f20746f207374616b65642e202d204d656d6f72793a206275696c645f737570706f72745f6d61702e204f2865292e202d204d656d6f72793a206576616c756174655f737570706f72743a204f2845292e202d2053746f726167653a204f2865292077726974657320746f2060517565756564456c6563746564602e202d2053746f726167653a204f28312920777269746520746f206051756575656453636f7265602054686520776569676874206f6620746869732063616c6c20697320312f31307468206f662074686520626c6f636b7320746f74616c207765696768742e77696e6e6572735665633c56616c696461746f72496e6465783e636f6d706163745f61737369676e6d656e7473436f6d7061637441737369676e6d656e747373636f726550687261676d656e53636f72656572612052656d6f766520616c6c20646174612073747275637475726520636f6e6365726e696e672061207374616b65722f7374617368206f6e6365206974732062616c616e6365206973207a65726f2e205468697320697320657373656e7469616c6c79206571756976616c656e7420746f206077697468647261775f756e626f6e64656460206578636570742069742063616e2062652063616c6c656420627920616e796f6e6520616e6420746865207461726765742060737461736860206d7573742068617665206e6f2066756e6473206c6566742e20546869732063616e2062652063616c6c65642066726f6d20616e79206f726967696e2e202d20607374617368603a20546865207374617368206163636f756e7420746f20726561702e204974732062616c616e6365206d757374206265207a65726f2e2053657420686973746f72795f64657074682076616c75652e204f726967696e206d75737420626520726f6f742e6e65775f686973746f72795f6465707468436f6d706163743c457261496e6465783e205265626f6e64206120706f7274696f6e206f6620746865207374617368207363686564756c656420746f20626520756e6c6f636b65642e20546865206469737061746368206f726967696e206d757374206265207369676e65642062792074686520636f6e74726f6c6c65722c20616e642069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d2054696d6520636f6d706c65786974793a204f2831292e20426f756e64656420627920604d41585f554e4c4f434b494e475f4348554e4b53602e202d2053746f72616765206368616e6765733a2043616e277420696e6372656173652073746f726167652c206f6e6c792064656372656173652069742e20506179206f757420616c6c20746865207374616b65727320626568696e6420612073696e676c652076616c696461746f7220666f7220612073696e676c65206572612e202d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e205468656972206e6f6d696e61746f72732c20757020746f20202060543a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602c2077696c6c20616c736f207265636569766520746865697220726577617264732e202d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e20546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966206974206973206e6f74206f6e65206f6620746865207374616b6572732e20546869732063616e206f6e6c792062652063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d2054696d6520636f6d706c65786974793a206174206d6f7374204f284d61784e6f6d696e61746f72526577617264656450657256616c696461746f72292e76616c696461746f725f7374617368202a2a546869732065787472696e7369632077696c6c2062652072656d6f76656420616674657220604d6967726174696f6e457261202b20486973746f727944657074686020686173207061737365642c20676976696e67206f70706f7274756e69747920666f7220757365727320746f20636c61696d20616c6c2072657761726473206265666f7265206d6f76696e6720746f2053696d706c65205061796f7574732e20416674657220746869732074696d652c20796f752073686f756c642075736520607061796f75745f7374616b6572736020696e73746561642e2a2a204d616b65206f6e652076616c696461746f722773207061796f757420666f72206f6e65206572612e202d206077686f602069732074686520636f6e74726f6c6c6572206163636f756e74206f66207468652076616c696461746f7220746f20706179206f75742e202d206065726160206d6179206e6f74206265206c6f776572207468616e206f6e6520666f6c6c6f77696e6720746865206d6f737420726563656e746c792070616964206572612e204966206974206973206869676865722c2020207468656e20697420696e6469636174657320616e20696e737472756374696f6e20746f20736b697020746865207061796f7574206f6620616c6c2070726576696f757320657261732e205741524e494e473a206f6e636520616e2065726120697320706179656420666f7220612076616c696461746f7220737563682076616c696461746f722063616e277420636c61696d20746865207061796f7574206f662070726576696f7573206572612e205741524e494e473a20496e636f727265637420617267756d656e747320686572652063616e20726573756c7420696e206c6f7373206f66207061796f75742e2042652076657279206361726566756c2e202d2054696d6520636f6d706c65786974793a204f2831292e204d616b65206f6e65206e6f6d696e61746f722773207061796f757420666f72206f6e65206572612e202d206077686f602069732074686520636f6e74726f6c6c6572206163636f756e74206f6620746865206e6f6d696e61746f7220746f20706179206f75742e202d206076616c696461746f72736020697320746865206c697374206f6620616c6c2076616c696461746f72732074686174206077686f6020686164206578706f7375726520746f20647572696e672060657261602c202020616c6f6e67736964652074686520696e646578206f66206077686f6020696e2074686520636c6970706564206578706f73757265206f66207468652076616c696461746f722e202020492e652e206561636820656c656d656e742069732061207475706c65206f66202020602876616c696461746f722c20696e646578206f66206077686f6020696e20636c6970706564206578706f73757265206f662076616c696461746f7229602e202020496620697420697320696e636f6d706c6574652c207468656e206c657373207468616e207468652066756c6c207265776172642077696c6c2062652070616964206f75742e2020204974206d757374206e6f742065786365656420604d41585f4e4f4d494e4154494f4e53602e202d204e756d626572206f662073746f726167652072656164206f6620604f2876616c696461746f727329603b206076616c696461746f7273602069732074686520617267756d656e74206f66207468652063616c6c2c202020616e6420697320626f756e64656420627920604d41585f4e4f4d494e4154494f4e53602e202d20456163682073746f72616765207265616420697320604f284e29602073697a6520616e64206465636f646520636f6d706c65786974793b20604e602069732074686520206d6178696d756d2020206e6f6d696e6174696f6e7320746861742063616e20626520676976656e20746f20612073696e676c652076616c696461746f722e202d20436f6d7075746174696f6e20636f6d706c65786974793a20604f284d41585f4e4f4d494e4154494f4e53202a206c6f674e29603b20604d41585f4e4f4d494e4154494f4e5360206973207468652020206d6178696d756d206e756d626572206f662076616c696461746f72732074686174206d6179206265206e6f6d696e6174656420627920612073696e676c65206e6f6d696e61746f722c206974206973202020626f756e646564206f6e6c792065636f6e6f6d6963616c6c792028616c6c206e6f6d696e61746f72732061726520726571756972656420746f20706c6163652061206d696e696d756d207374616b65292e76616c696461746f72735665633c28543a3a4163636f756e7449642c20753332293e2043616e63656c20656e6163746d656e74206f66206120646566657272656420736c6173682e2043616e2062652063616c6c6564206279206569746865722074686520726f6f74206f726967696e206f72207468652060543a3a536c61736843616e63656c4f726967696e602e2070617373696e67207468652065726120616e6420696e6469636573206f662074686520736c617368657320666f7220746861742065726120746f206b696c6c2e202d204f6e652073746f726167652077726974652e736c6173685f696e646963657320466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f662073657373696f6e7320696e646566696e6974656c792e202d204f6e652073746f7261676520777269746520466f72636520612063757272656e74207374616b657220746f206265636f6d6520636f6d706c6574656c7920756e7374616b65642c20696d6d6564696174656c792e737461736820536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e20466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e202d204e6f20617267756d656e74732e20466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e2054686520696465616c206e756d626572206f662076616c696461746f72732e436f6d706163743c7533323e202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e636f6e74726f6c6c6572202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e20416e642c2069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d20436f6e7461696e73206f6e6520726561642e204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546869732063616e206f6e6c792062652063616c6c6564207768656e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f66206074617267657473602c2077686963682069732063617070656420617420436f6d7061637441737369676e6d656e74733a3a4c494d49542e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e707265667356616c696461746f7250726566732052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e20456d697473206057697468647261776e602e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e20456d6974732060556e626f6e646564602e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c6564207669612020206077697468647261775f756e626f6e646564602e203c2f7765696768743e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c657220616e642069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e20456d6974732060426f6e646564602e6d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e000000000000b5f612000c000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a13009c6110000000000000000000ac61100007000000000000000100000000000000c1f612000e000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a1300e46110000000000000000000f461100001000000000000000100000000000000cff6120015000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a1300fc61100000000000000000000c62100001000000000000000100000000000000146210000d0000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a13002462100000000000000000003462100003000000000000000100000000000000c01410000600000001050000000000007ac312000c000000000000007ac312000c00000000000000000000000000000000000000301a13002067100000000000000000004c62100001000000000000000000000000000000c61410000600000001020000000000007ac312000c00000000000000546210002900000000000000000000000000000000000000301a13002067100000000000000000008062100001000000000000000000000000000000886210000500000001050000000000007ac312000c00000000000000f94810001100000000000000000000000000000000000000301a1300906210000000000000000000a062100001000000000000000100000000000000f38912000a00000001050000000000007ac312000c00000000000000474b10000e00000000000000000000000000000000000000301a1300086410000000000000000000a862100001000000000000000100000000000000cc1410000a00000001050000000000007ac312000c00000000000000b06210001900000000000000000000000000000000000000301a1300cc6210000000000000000000dc62100001000000000000000000000000000000e4f612000a0000000000000000000000b51a10000800000000000000000000000000000000000000000000000000000000000000301a1300c86710000000000000000000e462100004000000000000000000000000000000eef61200090000000000000000000000046310000d00000000000000000000000000000000000000000000000000000000000000301a13001463100000000000000000002463100004000000000000000000000000000000fef61200150000000105000000000000b51a1000080000000000000097f612000c00000000000000000000000000000000000000301a1300c867100000000000000000004463100001000000000000000000000000000000641b10000b0000000205050000000000b51a100008000000000000007ac312000c000000000000004c6310002400000000000000301a1300a063100000000000000000007063100006000000000000000100000000000000521b1000120000000205050000000000b51a100008000000000000007ac312000c000000000000004c6310002400000000000000301a1300a06310000000000000000000b06310000b000000000000000100000000000000401b1000120000000205050000000000b51a100008000000000000007ac312000c00000000000000474b10000e00000000000000301a13000864100000000000000000001864100005000000000000000100000000000000dc1a1000130000000105000000000000b51a10000800000000000000b66c12000c00000000000000000000000000000000000000301a1300f465100000000000000000004064100003000000000000000000000000000000cc1a1000100000000105000000000000b51a10000800000000000000586410001d00000000000000000000000000000000000000301a13007864100000000000000000008864100002000000000000000100000000000000ef1a10000e0000000105000000000000b51a10000800000000000000b66c12000c00000000000000000000000000000000000000301a1300046510000000000000000000986410000200000000000000010000000000000013f71200080000000000000000000000a86410000700000000000000000000000000000000000000000000000000000000000000301a1300b06410000000000000000000c0641000010000000000000001000000000000001bf712001300000000000000000000007df111000700000000000000000000000000000000000000000000000000000000000000301a1300c86410000000000000000000d864100003000000000000000100000000000000f0641000130000000000000000000000b66c12000c00000000000000000000000000000000000000000000000000000000000000301a130004651000000000000000000014651000020000000000000001000000000000006f1b1000100000000105000000000000b51a10000800000000000000246510002f00000000000000000000000000000000000000301a130054651000000000000000000064651000010000000000000001000000000000002ef712000a00000000000000000000006c6510001d00000000000000000000000000000000000000000000000000000000000000301a13008c65100000000000000000009c65100004000000000000000100000000000000d6141000130000000205050000000000b51a100008000000000000007ac312000c00000000000000bc6510001700000000000000301a1300d46510000000000000000000e465100002000000000000000000000000000000e9141000130000000205050000000000b51a100008000000000000007ac312000c00000000000000b66c12000c00000000000000301a1300f465100000000000000000000466100001000000000000000000000000000000fc1410000d00000001050000000000007ac312000c000000000000000c6610001700000000000000000000000000000000000000301a13002466100000000000000000003466100001000000000000000000000000000000091510000900000001050000000000003c66100023000000000000005f6610002200000000000000000000000000000000000000301a1300846610000000000000000000946610000200000000000000010000000000000038f71200160000000000000000000000b51a10000800000000000000000000000000000000000000000000000000000000000000301a1300c86710000000000000000000a46610000100000000000000000000000000000012151000120000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a1300bc6610000000000000000000ac6610000200000000000000000000000000000024151000120000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a1300bc6610000000000000000000cc66100002000000000000000000000000000000331b10000d0000000000000000000000dc6610002a00000000000000000000000000000000000000000000000000000000000000301a130020671000000000000000000008671000030000000000000000000000000000004ef712000b0000000000000000000000fc3810000d00000000000000000000000000000000000000000000000000000000000000301a1300206710000000000000000000306710000100000000000000000000000000000036151000110000000000000000000000386710001e00000000000000000000000000000000000000000000000000000000000000301a1300586710000000000000000000686710000200000000000000010000000000000059f71200150000000000000000000000a1f512000400000000000000000000000000000000000000000000000000000000000000301a130078671000000000000000000088671000020000000000000001000000000000005c9d10000e00000000000000000000006a9d10000800000000000000000000000000000000000000000000000000000000000000301a1300986710000000000000000000a8671000040000000000000001000000000000006ef712000a0000000000000000000000b51a10000800000000000000000000000000000000000000000000000000000000000000301a1300c86710000000000000000000d8671000010000000000000000000000420000000000000001000000560000004b77100023000000301a1300000000006e7710004e000000301a130000000000bc77100043000000ff7710002b0000002a7810004400000042000000000000000100000057000000217710002a00000042000000000000000100000058000000d176100050000000496e76756c6e657261626c657300000042000000000000000100000059000000fd751000560000005376100053000000a67610002b000000bd751000400000005374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e0000006c7510005100000050617965650000004200000000000000010000005a0000003375100039000000e2741000510000004e6f6d696e6174696f6e733c543a3a4163636f756e7449643e0000004200000000000000010000005b0000008974100059000000f973100017000000301a13000000000010741000590000006974100020000000416374697665457261496e666f0000004200000000000000010000005b0000004a73100036000000301a130000000000807310002e000000ae7310004b000000fe7210004c0000004578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3ee07210001e000000301a1300000000008070100058000000301a130000000000d87010002a00000090721000500000004200000000000000010000005c0000000271100026000000301a13000000000028711000560000007e71100037000000b571100047000000fc7110003d000000301a1300000000003972100057000000301a130000000000d87010002a00000090721000500000004200000000000000010000005d0000003c70100044000000301a1300000000008070100058000000301a130000000000d87010002a000000b26f100042000000301a130000000000f46f100048000000457261526577617264506f696e74733c543a3a4163636f756e7449643e0000004200000000000000010000005e0000003e6f10002b000000696f100049000000bc6e10003b000000f76e100047000000466f7263696e67004200000000000000010000005a000000a76e10001500000042000000000000000100000057000000306e10003e000000301a1300000000006e6e10003900000043616e63656c6564536c6173685061796f7574004200000000000000010000005f000000b06d100045000000f56d10003b0000005665633c556e6170706c696564536c6173683c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3e00420000000000000001000000590000007f6d1000310000005665633c28457261496e6465782c2053657373696f6e496e646578293e00000042000000000000000100000059000000d56c100049000000301a1300000000001e6d100032000000506d10002f0000002850657262696c6c2c2042616c616e63654f663c543e29004200000000000000010000005b000000686c100051000000b96c10001c0000004200000000000000010000005b000000106c100058000000736c617368696e673a3a536c617368696e675370616e73004200000000000000010000005b000000ed6b10002300000028543a3a4163636f756e7449642c20736c617368696e673a3a5370616e496e64657829736c617368696e673a3a5370616e5265636f72643c42616c616e63654f663c543e3e00000042000000000000000100000060000000706b10004f000000bf6b10002e000000316b10003f000000d86a100059000000926a1000460000004200000000000000010000005b000000396a100059000000926a100046000000456c656374696f6e526573756c743c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00007b69100059000000d4691000580000002c6a10000d0000004200000000000000010000005b0000004f6910002c000000456c656374696f6e5374617475733c543a3a426c6f636b4e756d6265723e00004200000000000000010000005a000000e268100052000000346910001b0000004200000000000000010000005b0000007968100053000000cc68100016000000420000000000000001000000610000001e681000330000009c9d10001f000000301a13000000000051681000280000004200000000000000010000005b000000e06710003e0000002054686520657261207768657265207765206d696772617465642066726f6d204c617a79205061796f75747320746f2053696d706c65205061796f7574732054727565206966206e6574776f726b20686173206265656e20757067726164656420746f20746869732076657273696f6e2e20546869732069732073657420746f2076332e302e3020666f72206e6577206e6574776f726b732e2054727565206966207468652063757272656e74202a2a706c616e6e65642a2a2073657373696f6e2069732066696e616c2e204e6f74652074686174207468697320646f6573206e6f742074616b652065726120666f7263696e6720696e746f206163636f756e742e20466c616720746f20636f6e74726f6c2074686520657865637574696f6e206f6620746865206f6666636861696e20656c656374696f6e2e205768656e20604f70656e285f29602c2077652061636365707420736f6c7574696f6e7320746f206265207375626d69747465642e205468652073636f7265206f66207468652063757272656e74205b60517565756564456c6563746564605d2e20546865206e6578742076616c696461746f72207365742e2041742074686520656e64206f6620616e206572612c206966207468697320697320617661696c61626c652028706f74656e7469616c6c792066726f6d2074686520726573756c74206f6620616e206f6666636861696e20776f726b6572292c20697420697320696d6d6564696174656c7920757365642e204f74686572776973652c20746865206f6e2d636861696e20656c656374696f6e2069732065786563757465642e20536e617073686f74206f66206e6f6d696e61746f72732061742074686520626567696e6e696e67206f66207468652063757272656e7420656c656374696f6e2077696e646f772e20546869732073686f756c64206f6e6c79206861766520612076616c7565207768656e205b60457261456c656374696f6e537461747573605d203d3d2060456c656374696f6e5374617475733a3a4f70656e285f29602e20536e617073686f74206f662076616c696461746f72732061742074686520626567696e6e696e67206f66207468652063757272656e7420656c656374696f6e2077696e646f772e20546869732073686f756c64206f6e6c7920546865206561726c696573742065726120666f72207768696368207765206861766520612070656e64696e672c20756e6170706c69656420736c6173682e205265636f72647320696e666f726d6174696f6e2061626f757420746865206d6178696d756d20736c617368206f6620612073746173682077697468696e206120736c617368696e67207370616e2c2061732077656c6c20617320686f77206d7563682072657761726420686173206265656e2070616964206f75742e20536c617368696e67207370616e7320666f72207374617368206163636f756e74732e20416c6c20736c617368696e67206576656e7473206f6e206e6f6d696e61746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682076616c7565206f6620746865206572612e20416c6c20736c617368696e67206576656e7473206f6e2076616c696461746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682070726f706f7274696f6e20616e6420736c6173682076616c7565206f6620746865206572612e2041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e204d75737420636f6e7461696e7320696e666f726d6174696f6e20666f72206572617320666f72207468652072616e67653a20605b6163746976655f657261202d20626f756e64696e675f6475726174696f6e3b206163746976655f6572615d6020416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e2054686520616d6f756e74206f662063757272656e637920676976656e20746f207265706f7274657273206f66206120736c617368206576656e74207768696368207761732063616e63656c65642062792065787472616f7264696e6172792063697263756d7374616e6365732028652e672e20676f7665726e616e6365292e205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e204d6f6465206f662065726120666f7263696e672e2054686520746f74616c20616d6f756e74207374616b656420666f7220746865206c6173742060484953544f52595f44455054486020657261732e20496620746f74616c206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207374616b652069732072657475726e65642e205265776172647320666f7220746865206c6173742060484953544f52595f44455054486020657261732e20496620726577617264206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207265776172642069732072657475726e65642e2054686520746f74616c2076616c696461746f7220657261207061796f757420666f7220746865206c6173742060484953544f52595f44455054486020657261732e2045726173207468617420686176656e27742066696e697368656420796574206f7220686173206265656e2072656d6f76656420646f65736e27742068617665207265776172642e2053696d696c617220746f2060457261735374616b657273602c207468697320686f6c64732074686520707265666572656e636573206f662076616c696461746f72732e2054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e2049732069742072656d6f7665642061667465722060484953544f52595f44455054486020657261732e20436c6970706564204578706f73757265206f662076616c696461746f72206174206572612e20546869732069732073696d696c617220746f205b60457261735374616b657273605d20627574206e756d626572206f66206e6f6d696e61746f7273206578706f736564206973207265647563656420746f207468652060543a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602062696767657374207374616b6572732e20284e6f74653a20746865206669656c642060746f74616c6020616e6420606f776e60206f6620746865206578706f737572652072656d61696e7320756e6368616e676564292e2054686973206973207573656420746f206c696d69742074686520692f6f20636f737420666f7220746865206e6f6d696e61746f72207061796f75742e2054686973206973206b657965642066697374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e204578706f73757265206f662076616c696461746f72206174206572612e205468652073657373696f6e20696e646578206174207768696368207468652065726120737461727420666f7220746865206c6173742060484953544f52595f44455054486020657261732e20546865206163746976652065726120696e666f726d6174696f6e2c20697420686f6c647320696e64657820616e642073746172742e20546865206163746976652065726120697320746865206572612063757272656e746c792072657761726465642e2056616c696461746f7220736574206f66207468697320657261206d75737420626520657175616c20746f206053657373696f6e496e746572666163653a3a76616c696461746f7273602e205468652063757272656e742065726120696e6465782e205468697320697320746865206c617465737420706c616e6e6564206572612c20646570656e64696e67206f6e20686f77207468652053657373696f6e2070616c6c657420717565756573207468652076616c696461746f72207365742c206974206d6967687420626520616374697665206f72206e6f742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e204e756d626572206f66206572617320746f206b65657020696e20686973746f72792e20496e666f726d6174696f6e206973206b65707420666f72206572617320696e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e204d757374206265206d6f7265207468616e20746865206e756d626572206f6620657261732064656c617965642062792073657373696f6e206f74686572776973652e20492e652e2061637469766520657261206d75737420616c7761797320626520696e20686973746f72792e20492e652e20606163746976655f657261203e2063757272656e745f657261202d20686973746f72795f646570746860206d7573742062652067756172616e746565642e000000000000e07810000e0000000000000097f612000c00000000000000301a1300f0781000000000000000000000791000010000000000000000000000087910000f00000000000000b51a10000800000000000000301a130018791000000000000000000028791000010000000000000053657373696f6e73506572457261000042000000000000000100000062000000697910001c000000426f6e64696e674475726174696f6e00420000000000000001000000630000003079100039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e65786163746c79206f6e65206f6620606d617962655f76616c696461746f726020616e6420606d617962655f6e6f6d696e6174696f6e2e69735f736f6d656020697320747275652e2069735f76616c696461746f722069732066616c73653b206d617962655f6e6f6d696e6174696f6e20697320736f6d653b207165640000147a1000330000005c090000220000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f7374616b696e672f7372632f6c69622e72730000000000361310000d00000000000000587d10000100000000000000000000002e1310000800000000000000607d1000010000000000000000000000211310000d00000000000000687d1000010000000000000000000000141310000d00000000000000707d1000010000000000000000000000081310000c00000000000000787d1000010000000000000000000000fa1210000e00000000000000807d1000010000000000000000000000e91210001100000000000000887d1000010000000000000000000000d81210001100000000000000907d1000010000000000000000000000cc1210000c00000000000000987d1000010000000000000000000000bf1210000d00000000000000a07d1000010000000000000000000000b31210000c00000000000000a87d1000010000000000000000000000a11210001200000000000000b07d1000010000000000000000000000871210001a00000000000000b87d1000010000000000000000000000751210001200000000000000c07d1000010000000000000000000000671210000e00000000000000c87d1000010000000000000000000000501210001700000000000000d07d10000100000000000000000000003a1210001600000000000000d87d1000010000000000000000000000271210001300000000000000e07d10000100000000000000000000000f1210001800000000000000e87d1000010000000000000000000000fc1110001300000000000000f07d1000020000000000000000000000e81110001400000000000000007e1000020000000000000000000000d21110001600000000000000107e1000010000000000000000000000bb1110001700000000000000187e1000010000000000000000000000a21110001900000000000000207e10000200000000000000000000008d1110001500000000000000307e10000100000000000000000000007c1110001100000000000000387e10000100000000000000000000006a1110001200000000000000407e10000100000000000000000000005c1110000e00000000000000487e100001000000000000002d8410001a0000001884100015000000ff83100019000000e18310001e000000c883100019000000b783100011000000958310002200000062831000330000003d831000250000001483100029000000e182100033000000ca82100017000000ab8210001f0000008a8210002100000047821000430000000e82100039000000ce811000400000009a811000340000006e8110002c0000000881100058000000608110000e0000008780100057000000de8010002a0000004280100045000000ef7f100053000000827f100058000000da7f100015000000397f100049000000e87e100051000000a27e100046000000507e100052000000205468652063616c6c206973206e6f7420616c6c6f7765642061742074686520676976656e2074696d652064756520746f207265737472696374696f6e73206f6620656c656374696f6e20706572696f642e2054686520636c61696d65642073636f726520646f6573206e6f74206d61746368207769746820746865206f6e6520636f6d70757465642066726f6d2074686520646174612e20546865207375626d697474656420726573756c742068617320756e6b6e6f776e206564676573207468617420617265206e6f7420616d6f6e67207468652070726573656e7465642077696e6e6572732e20412073656c6620766f7465206d757374206f6e6c79206265206f726967696e617465642066726f6d20612076616c696461746f7220746f204f4e4c59207468656d73656c7665732e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f72732068617320616e2065646765207768696368206973207375626d6974746564206265666f726520746865206c617374206e6f6e2d7a65726f20736c617368206f6620746865207461726765742e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f72732068617320616e206564676520746f20776869636820746865792068617665206e6f7420766f746564206f6e20636861696e2e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f7273206973206e6f7420616e20616374697665206e6f6d696e61746f72206f6e20636861696e2e204572726f72207768696c65206275696c64696e67207468652061737369676e6d656e7420747970652066726f6d2074686520636f6d706163742e20546869732063616e2068617070656e20696620616e20696e64657820697320696e76616c69642c206f72206966207468652077656967687473205f6f766572666c6f775f2e204f6e65206f6620746865207375626d69747465642077696e6e657273206973206e6f7420616e206163746976652063616e646964617465206f6e20636861696e2028696e646578206973206f7574206f662072616e676520696e20736e617073686f74292e20496e636f7272656374206e756d626572206f662077696e6e65727320776572652070726573656e7465642e2054686520736e617073686f742064617461206f66207468652063757272656e742077696e646f77206973206d697373696e672e20546865207375626d697474656420726573756c74206973206e6f7420617320676f6f6420617320746865206f6e652073746f726564206f6e20636861696e2e20546865207375626d697474656420726573756c74206973207265636569766564206f7574206f6620746865206f70656e2077696e646f772e205265776172647320666f72207468697320657261206861766520616c7265616479206265656e20636c61696d656420666f7220746869732076616c696461746f722e204974656d7320617265206e6f7420736f7274656420616e6420756e697175652e20496e76616c6964206e756d626572206f66206e6f6d696e6174696f6e732e20496e76616c69642065726120746f207265776172642e20417474656d7074696e6720746f2074617267657420612073746173682074686174207374696c6c206861732066756e64732e2043616e206e6f74207265626f6e6420776974686f757420756e6c6f636b696e67206368756e6b732e2043616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b732e2043616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e63652e20536c617368207265636f726420696e646578206f7574206f6620626f756e64732e204475706c696361746520696e6465782e20546172676574732063616e6e6f7420626520656d7074792e20436f6e74726f6c6c657220697320616c7265616479207061697265642e20537461736820697320616c726561647920626f6e6465642e204e6f742061207374617368206163636f756e742e204e6f74206120636f6e74726f6c6c6572206163636f756e742e00508410001a0000004552524f523a20436f7272757074656420737461746520617420446561644163636f756e744b656570416c6976654578697374656e7469616c4465706f736974496e73756666696369656e7442616c616e63654c69717569646974795265737472696374696f6e7356657374696e6742616c616e63657365745f62616c616e63657472616e736665725f6b6565705f616c697665546f74616c49737375616e636500000000000000d0851000070000000000000084111200020000000000000000000000d8851000010000000000000000000000e0851000080000000000000084111200020000000000000000000000e885100002000000000000000000000074ca110008000000000000007cca1100030000000000000000000000f8851000010000000000000000000000008610000a000000000000000c86100003000000000000000000000024861000010000000000000000000000c81912000700000000000000841112000200000000000000000000002c8610000100000000000000456e646f77656400318710002f000000447573744c6f7374c286100050000000128710001f0000009c8610002600000042616c616e6365536574000020af120009000000f615120007000000f6151200070000006b86100031000000348610003700000020536f6d6520616d6f756e7420776173206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e20412062616c616e6365207761732073657420627920726f6f74202877686f2c20667265652c207265736572766564292e205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c7565292e20416e206163636f756e74207761732072656d6f7665642077686f73652062616c616e636520776173206e6f6e2d7a65726f206275742062656c6f77204578697374656e7469616c4465706f7369742c20726573756c74696e6720696e20616e206f75747269676874206c6f73732e20416e206163636f756e74207761732063726561746564207769746820736f6d6520667265652062616c616e63652e496e76616c69644f726967696e496e73756666696369656e7443616e64696461746546756e647352756e6e65725375626d69744d656d6265725375626d69744475706c69636174656443616e6469646174655265706f727453656c664d7573744265566f746572556e61626c65546f506179426f6e644c6f7742616c616e63654d6178696d756d566f7465734578636565646564546f6f4d616e79566f7465734e6f566f746573556e61626c65546f566f746572656d6f76655f766f7465727265706f72745f646566756e63745f766f7465727375626d69745f63616e64696461637972656e6f756e63655f63616e646964616379000000000000003489100007000000000000003c89100001000000000000000000000044891000040000000000000000000000648910000900000000000000301a130000000000000000000000000070891000020000000000000000000000808910000c0000000000000074ad12000100000000000000000000008c8910000200000000000000000000009c8910000f0000000000000074ad1200010000000000000000000000ac891000010000000000000000000000b48910000d00000000000000ac121200030000000000000000000000c489100002000000000000004e65775465726d00ad8c100019000000538b100056000000a98b100056000000ff8b100058000000578c100056000000456d7074795465726d000000d58a10004d000000228b1000310000004d656d6265724b69636b6564778a100051000000c88a10000d0000004d656d62657252656e6f756e636564004f8a100028000000566f7465725265706f72746564000000d4891000580000002c8a100023000000204120766f7465722028666972737420656c656d656e742920776173207265706f72746564202862797420746865207365636f6e6420656c656d656e742920776974682074686520746865207265706f7274206265696e67207375636365737366756c206f72206e6f742028746869726420656c656d656e74292e2041206d656d626572206861732072656e6f756e6365642074686569722063616e6469646163792e2041206d656d62657220686173206265656e2072656d6f7665642e20546869732073686f756c6420616c7761797320626520666f6c6c6f7765642062792065697468657220604e65775465726d60206f742060456d7074795465726d602e204e6f20286f72206e6f7420656e6f756768292063616e64696461746573206578697374656420666f72207468697320726f756e642e205468697320697320646966666572656e742066726f6d20604e65775465726d285b5d29602e2053656520746865206465736372697074696f6e206f6620604e65775465726d602e2041206e6577207465726d2077697468206e6577206d656d626572732e205468697320696e64696361746573207468617420656e6f7567682063616e64696461746573206578697374656420746f2072756e2074686520656c656374696f6e2c206e6f74207468617420656e6f756768206861766520686173206265656e20656c65637465642e2054686520696e6e65722076616c7565206d757374206265206578616d696e656420666f72207468697320707572706f73652e204120604e65775465726d285b5d296020696e64696361746573207468617420736f6d652063616e6469646174657320676f7420746865697220626f6e6420736c617368656420616e64206e6f6e65207765726520656c65637465642c207768696c73742060456d7074795465726d60206d65616e732074686174206e6f2063616e64696461746573206578697374656420746f20626567696e20776974682e5665633c284163636f756e7449642c2042616c616e6365293e52756e6e657273557000a48a12003e00000003030000190000003c8e10003c00000071000000130000003c8e10003c00000088000000180000003c8e10003c000000b4000000190000003c8e10003c000000ff000000420000003c8e10003c00000013010000420000004475706c696361746520766f74657220286f72206f7468657220636f727275707420696e707574292e0000003c8e10003c00000057010000150000003c8e10003c0000005c0100001e000000420000000000000001000000640000003c8e10003c0000005f0000001a0000003c8e10003c0000005f0000002c0000003c8e10003c000000cc010000240000003c8e10003c000000cd010000240000003c8e10003c000000f3010000240000003c8e10003c00000020020000240000003c8e10003c00000043020000350000003c8e10003c000000580200002b0000003c8e10003c00000059020000280000003c8e10003c000000630200002b0000003c8e10003c00000064020000280000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f70687261676d656e2f7372632f7265647563652e72730000000013db10000800000000000000288f1000020000000000000000000000588f10001b0000000000000000000000c68410000b0000000000000030901000030000000000000000000000789010001000000000000000000000001fdb10000e00000000000000f890100003000000000000000000000040911000060000000000000000000000d18410001300000000000000288f1000020000000000000000000000709110000b0000000000000000000000b2d311000400000000000000f32012002300000000000000aa4d120005000000000000000a941000130000003896100036000000301a1300000000006e96100042000000b096100048000000f8961000450000003d9710002d000000301a1300000000006a97100046000000301a130000000000f5bd12000b000000b09710004c000000fc971000330000002f9810005a000000301a1300000000008998100013000000301a1300000000009c98100054000000f09810004b0000003b991000350000007099100058000000c8991000520000001a9a10003e000000589a1000220000007a9a10004e000000c89a100037000000ff9a10004500000044be12000c00000000000000f02012000300000000000000f320120023000000000000002496100008000000000000000a94100013000000000000002c9610000c000000000000000a941000130000001d94100025000000301a13000000000042941000480000008a94100042000000cc941000460000001295100040000000301a130000000000529510002d000000301a130000000000f5bd12000b0000007f951000200000009f95100031000000d095100016000000e695100018000000fe9510002600000044be12000c00000000000000049410000600000000000000f32012002300000000000000b2d311000400000000000000f32012002300000000000000aa4d120005000000000000000a941000130000003193100054000000859310000b000000f5bd12000b0000009093100050000000e09310002400000044be12000c000000c8911000540000001c92100010000000301a1300000000002c9210002f000000301a1300000000005b92100031000000f5bd12000b0000008c9210003a000000c692100019000000df92100047000000269310000b0000002053616d6520617320746865205b607472616e73666572605d2063616c6c2c206275742077697468206120636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e20393925206f66207468652074696d6520796f752077616e74205b607472616e73666572605d20696e73746561642e205b607472616e73666572605d3a207374727563742e4d6f64756c652e68746d6c236d6574686f642e7472616e73666572202d2043686561706572207468616e207472616e736665722062656361757365206163636f756e742063616e6e6f74206265206b696c6c65642e202d2042617365205765696768743a2035372e333620c2b573202d204442205765696768743a2031205265616420616e64203120577269746520746f2064657374202873656e64657220697320696e206f7665726c617920616c72656164792920233c2f7765696768743e2045786163746c7920617320607472616e73666572602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74206d6179206265207370656369666965642e202d2053616d65206173207472616e736665722c20627574206164646974696f6e616c207265616420616e6420777269746520626563617573652074686520736f75726365206163636f756e742069732020206e6f7420617373756d656420746f20626520696e20746865206f7665726c61792e736f75726365436f6d706163743c543a3a42616c616e63653e20536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e63652028606672616d655f73797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a2033322e3620c2b573202d204442205765696768743a203120526561642c203120577269746520746f206077686f606e65775f667265656e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c20747269676765722060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e636564602e2020202d20607472616e736665725f6b6565705f616c6976656020776f726b73207468652073616d652077617920617320607472616e73666572602c206275742068617320616e206164646974696f6e616c2020202020636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a20383020c2b5732c20776f7273742063617365207363656e6172696f20286163636f756e7420637265617465642c206163636f756e742072656d6f76656429202d204442205765696768743a2031205265616420616e64203120577269746520746f2064657374696e6174696f6e206163636f756e74202d204f726967696e206163636f756e7420697320616c726561647920696e206d656d6f72792c20736f206e6f204442206f7065726174696f6e7320666f72207468656d2e00000000e48410000d0000000000000000000000a49c10000a00000000000000000000000000000000000000000000000000000000000000301a1300b09c10000000000000000000c09c10000100000000000000010000000000000057e211000700000001020000000000007ac312000c00000000000000c89c10001700000000000000000000000000000000000000301a1300e09c10000000000000000000f09c100006000000000000000100000000000000389111000500000001020000000000007ac312000c00000000000000209d10001c00000000000000000000000000000000000000301a13003c9d100000000000000000004c9d1000020000000000000001000000000000005c9d10000e00000000000000000000006a9d10000800000000000000000000000000000000000000000000000000000000000000301a1300749d10000000000000000000849d1000030000000000000001000000543a3a42616c616e636500004200000000000000010000005f0000004b9f1000260000004163636f756e74446174613c543a3a42616c616e63653e00420000000000000001000000650000005a9e10001b000000301a130000000000759e100056000000cb9e100030000000301a130000000000fb9e1000500000005665633c42616c616e63654c6f636b3c543a3a42616c616e63653e3e42000000000000000100000059000000e39d10002e000000119e10004900000053746f7261676556657273696f6e52656c656173657300004200000000000000010000005a0000009c9d10001f000000301a130000000000bb9d1000280000002053746f726167652076657273696f6e206f66207468652070616c6c65742e20546869732069732073657420746f2076322e302e3020666f72206e6577206e6574776f726b732e20416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e204e4f54453a2053686f756c64206f6e6c79206265206163636573736564207768656e2073657474696e672c206368616e67696e6720616e642066726565696e672061206c6f636b2e205468652062616c616e6365206f6620616e206163636f756e742e204e4f54453a2054484953204d4159204e4556455220424520494e204558495354454e434520414e4420594554204841564520412060746f74616c28292e69735f7a65726f2829602e2049662074686520746f74616c2069732065766572207a65726f2c207468656e2074686520656e747279202a4d5553542a2062652072656d6f7665642e204e4f54453a2054686973206973206f6e6c79207573656420696e20746865206361736520746861742074686973206d6f64756c65206973207573656420746f2073746f72652062616c616e6365732e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e000000000000007e8410001200000000000000a49c10000a00000000000000301a1300d4b110000000000000000000ac9f10000100000000000000b49f10003500000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e0000000000000014b012000400000000000000f4a0100002000000000000000000000024a110000f0000000000000000000000138810000c00000000000000301a13000000000000000000000000009ca110000700000000000000000000001f8810001400000000000000b4471100010000000000000000000000d4a110000d0000000000000000000000338810001000000000000000301a13000000000000000000000000003ca210000d0000000000000000000000438810001200000000000000301a1300000000000000000000000000a4a2100009000000000000000000000087e411000d00000000000000eca2100001000000000000000000000004a310000d000000000000000000000052ac10000500000000000000ddce12001100000000000000aa4d120005000000000000008075120015000000b8aa100041000000301a130000000000f9aa1000140000000dab1000120000001fab10002b000000301a1300000000004aab100057000000a1ab100057000000f8ab100028000000301a130000000000f5bd12000b000000c7a410000b000000acaa10000c00000020ac10003200000044be12000c00000064aa100048000000301a130000000000f5bd12000b000000c7a410000b000000acaa10000c000000aba810000d00000044be12000c000000b8a81000570000000fa910005700000066a9100017000000301a1300000000007da91000220000009fa9100053000000f2a910002d000000301a130000000000f5bd12000b000000c7a410000b0000001faa100045000000aba810000d00000044be12000c00000069a710001e000000301a13000000000087a7100019000000a0a710003b000000dba710004b00000026a81000550000007ba810000d000000301a130000000000f5bd12000b000000c7a410000b00000088a8100023000000aba810000d00000044be12000c000000ffa410005400000053a510001000000063a5100050000000b3a510003d000000f0a510005600000046a610002100000067a6100053000000baa610005600000010a710005900000000000000f02012000300000000000000f3201200230000006ca3100057000000c3a3100020000000301a130000000000e3a310005600000039a410003d000000301a13000000000076a4100051000000301a130000000000f5bd12000b000000c7a410000b000000d2a4100016000000e8a410001700000044be12000c0000002052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c7920616e642074686520626f6e64206f6620746865206f7574676f696e67206d656d62657220697320736c61736865642e20496620612072756e6e65722d757020697320617661696c61626c652c207468656e2074686520626573742072756e6e65722d75702077696c6c2062652072656d6f76656420616e64207265706c6163657320746865206f7574676f696e67206d656d6265722e204f74686572776973652c2061206e65772070687261676d656e20726f756e6420697320737461727465642e204e6f74652074686174207468697320646f6573206e6f7420616666656374207468652064657369676e6174656420626c6f636b206e756d626572206f6620746865206e65787420656c656374696f6e2e20232323232053746174652052656164733a204f28646f5f70687261676d656e29205772697465733a204f28646f5f70687261676d656e292052656e6f756e6365206f6e65277320696e74656e74696f6e20746f20626520612063616e64696461746520666f7220746865206e65787420656c656374696f6e20726f756e642e203320706f74656e7469616c206f7574636f6d65732065786973743a202d20606f726967696e6020697320612063616e64696461746520616e64206e6f7420656c656374656420696e20616e79207365742e20496e207468697320636173652c2074686520626f6e64206973202020756e72657365727665642c2072657475726e656420616e64206f726967696e2069732072656d6f76656420617320612063616e6469646174652e202d20606f726967696e6020697320612063757272656e742072756e6e65722075702e20496e207468697320636173652c2074686520626f6e6420697320756e72657365727665642c2072657475726e656420616e642020206f726967696e2069732072656d6f76656420617320612072756e6e65722e202d20606f726967696e6020697320612063757272656e74206d656d6265722e20496e207468697320636173652c2074686520626f6e6420697320756e726573657276656420616e64206f726967696e20697320202072656d6f7665642061732061206d656d6265722c20636f6e73657175656e746c79206e6f74206265696e6720612063616e64696461746520666f7220746865206e65787420726f756e6420616e796d6f72652e20202053696d696c617220746f205b6072656d6f76655f766f746572605d2c206966207265706c6163656d656e742072756e6e657273206578697374732c20746865792061726520696d6d6564696174656c7920757365642e205375626d6974206f6e6573656c6620666f722063616e6469646163792e20412063616e6469646174652077696c6c206569746865723a2020202d204c6f73652061742074686520656e64206f6620746865207465726d20616e6420666f7266656974207468656972206465706f7369742e2020202d2057696e20616e64206265636f6d652061206d656d6265722e204d656d626572732077696c6c206576656e7475616c6c7920676574207468656972207374617368206261636b2e2020202d204265636f6d6520612072756e6e65722d75702e2052756e6e6572732d75707320617265207265736572766564206d656d6265727320696e2063617365206f6e65206765747320666f72636566756c6c79202020202072656d6f7665642e2052656164733a204f284c6f674e2920476976656e204e2063616e646964617465732e205772697465733a204f283129205265706f727420607461726765746020666f72206265696e6720616e20646566756e637420766f7465722e20496e2063617365206f6620612076616c6964207265706f72742c20746865207265706f727465722069732072657761726465642062792074686520626f6e6420616d6f756e74206f662060746172676574602e204f74686572776973652c20746865207265706f7274657220697473656c662069732072656d6f76656420616e6420746865697220626f6e6420697320736c61736865642e204120646566756e637420766f74657220697320646566696e656420746f2062653a2020202d206120766f7465722077686f73652063757272656e74207375626d697474656420766f7465732061726520616c6c20696e76616c69642e20692e652e20616c6c206f66207468656d20617265206e6f20202020206c6f6e67657220612063616e646964617465206e6f7220616e20616374697665206d656d6265722e2052656164733a204f284e4c6f674d2920676976656e204d2063757272656e742063616e6469646174657320616e64204e20766f74657320666f722060746172676574602e2052656d6f766520606f726967696e60206173206120766f7465722e20546869732072656d6f76657320746865206c6f636b20616e642072657475726e732074686520626f6e642e2052656164733a204f28312920566f746520666f72206120736574206f662063616e6469646174657320666f7220746865207570636f6d696e6720726f756e64206f6620656c656374696f6e2e205468652060766f746573602073686f756c643a2020202d206e6f7420626520656d7074792e2020202d206265206c657373207468616e20746865206e756d626572206f662063616e646964617465732e2055706f6e20766f74696e672c206076616c75656020756e697473206f66206077686f6027732062616c616e6365206973206c6f636b656420616e64206120626f6e6420616d6f756e742069732072657365727665642e2049742069732074686520726573706f6e736962696c697479206f66207468652063616c6c657220746f206e6f7420706c61636520616c6c206f662074686569722062616c616e636520696e746f20746865206c6f636b20616e64206b65657020736f6d6520666f722066757274686572207472616e73616374696f6e732e205772697465733a204f28562920676976656e2060566020766f7465732e205620697320626f756e6465642062792031362e766f746573000000000009b5120007000000000000000000000010ae10002100000000000000000000000000000000000000000000000000000000000000301a13003cae1000000000000000000034ae100001000000000000000100000000000000c68c100009000000000000000000000010ae10002100000000000000000000000000000000000000000000000000000000000000301a13003cae100000000000000000004cae10000100000000000000010000000000000030f212000e000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a130054ae1000000000000000000064ae10000100000000000000010000000000000010b512000600000001050000000000007ac312000c00000000000000a48f11002100000000000000000000000000000000000000301a13006cae100000000000000000007cae100001000000000000000100000000000000611c12000a0000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a130084ae1000000000000000000094ae10000200000000000000010000005665633c28543a3a4163636f756e7449642c2042616c616e63654f663c543e293e0000001ab010003c00000042000000000000000100000059000000c8af1000520000004200000000000000010000005700000078af100050000000420000000000000001000000660000004aaf10002e00000042000000000000000100000059000000a4ae100056000000faae100050000000205468652070726573656e742063616e646964617465206c6973742e20536f72746564206261736564206f6e206163636f756e742d69642e20412063757272656e74206d656d626572206f722072756e6e65722d75702063616e206e6576657220656e746572207468697320766563746f7220616e6420697320616c7761797320696d706c696369746c7920617373756d656420746f20626520612063616e6469646174652e20566f74657320616e64206c6f636b6564207374616b65206f66206120706172746963756c617220766f7465722e2054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e65642c206578636c7564696e6720746865207570636f6d696e67206f6e652e205468652063757272656e742072756e6e6572735f75702e20536f72746564206261736564206f6e206c6f7720746f2068696768206d657269742028776f72736520746f20626573742072756e6e6572292e205468652063757272656e7420656c6563746564206d656d626572736869702e20536f72746564206261736564206f6e206163636f756e742069642e000000000000a8b110000d00000000000000b66c12000c00000000000000301a1300b8b110000000000000000000301a1300000000000000000000000000c8b110000a00000000000000b66c12000c00000000000000301a1300d4b110000000000000000000301a1300000000000000000000000000e4b110000e0000000000000060dc12000300000000000000301a1300f4b110000000000000000000301a130000000000000000000000000004b21000100000000000000060dc12000300000000000000301a130014b210000000000000000000301a130000000000000000000000000024b210000c0000000000000006cf12000e00000000000000301a130030b210000000000000000000301a1300000000000000000000000000cc5e1200080000000000000040b210000e00000000000000301a130050b210000000000000000000301a1300000000000000000043616e646964616379426f6e6400000042000000000000000100000067000000566f74696e67426f6e64000042000000000000000100000068000000446573697265644d656d626572730000420000000000000001000000690000004465736972656452756e6e65727355704200000000000000010000006a0000005465726d4475726174696f6e4200000000000000010000006b0000004c6f636b4964656e74696669657200004200000000000000010000006c00000000000000b88410000e0000000000000040b31000010000000000000000000000a3841000150000000000000048b3100001000000000000000000000027ab1200080000000000000050b3100001000000000000000000000090841000130000000000000058b310000100000000000000000000007e841000120000000000000060b3100001000000000000000000000075841000090000000000000068b31000010000000000000000000000aa371100170000000000000070b310000100000000000000000000006a8410000b0000000000000078b310000100000000000000a2b410002700000070b410003200000053b410001d00000035b410001e000000fab310003b000000d6b3100024000000a3b310003300000080b31000230000002042656e6566696369617279206163636f756e74206d757374207072652d657869737420412076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e74205472616e736665722f7061796d656e7420776f756c64206b696c6c206163636f756e742056616c756520746f6f206c6f7720746f20637265617465206163636f756e742064756520746f206578697374656e7469616c206465706f7369742042616c616e636520746f6f206c6f7720746f2073656e642076616c756520476f7420616e206f766572666c6f7720616674657220616464696e67204163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c2056657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c756500000000000000078810000c0000000000000054b610000100000000000000000000000088100007000000000000005cb61000010000000000000000000000f48710000c0000000000000064b61000010000000000000000000000e087100014000000000000006cb61000010000000000000000000000d68710000a0000000000000074b61000010000000000000000000000c78710000f000000000000007cb61000010000000000000000000000bc8710000b0000000000000084b61000010000000000000000000000b28710000a000000000000008cb610000100000000000000000000009f871000130000000000000094b61000010000000000000000000000938710000c000000000000009cb61000010000000000000000000000878710000c00000000000000a4b610000100000000000000000000006d8710001a00000000000000acb61000010000000000000000000000608710000d00000000000000b4b61000010000000000000000000000f2af12000900000000000000bcb61000010000000000000076b810003100000050b81000260000002eb810002200000007b8100027000000d5b7100032000000b6b710001f000000a5b710001100000091b710001400000070b71000210000004db71000230000002ab710002300000004b7100026000000d2b6100032000000c4b610000e000000204e6f742061206d656d6265722e204f726967696e206973206e6f7420612063616e6469646174652c206d656d626572206f7220612072756e6e65722075702e2043616e64696461746520646f6573206e6f74206861766520656e6f7567682066756e64732e2052756e6e65722063616e6e6f742072652d7375626d69742063616e6469646163792e204d656d6265722063616e6e6f742072652d7375626d69742063616e6469646163792e204475706c6963617465642063616e646964617465207375626d697373696f6e2e2043616e6e6f74207265706f72742073656c662e204d757374206265206120766f7465722e20566f7465722063616e206e6f742070617920766f74696e6720626f6e642e2043616e6e6f7420766f74652077697468207374616b65206c657373207468616e206d696e696d756d2062616c616e63652e2043616e6e6f7420766f7465206d6f7265207468616e206d6178696d756d20616c6c6f7765642e2043616e6e6f7420766f7465206d6f7265207468616e2063616e646964617465732e204d75737420766f746520666f72206174206c65617374206f6e652063616e6469646174652e2043616e6e6f7420766f7465207768656e206e6f2063616e64696461746573206f72206d656d626572732065786973742e556e657870656374656454696d65706f696e7457726f6e6754696d65706f696e744e6f54696d65706f696e7453656e646572496e5369676e61746f726965735369676e61746f726965734f75744f664f72646572546f6f4d616e795369676e61746f72696573546f6f4665775369676e61746f726965734e6f417070726f76616c734e6565646564416c7265616479417070726f766564626174636861735f73756261735f6d756c7469617070726f76655f61735f6d756c746963616e63656c5f61735f6d756c74690000000078ba1000100000000000000088ba100002000000000000000000000098ba1000020000000000000000000000a8ba10000e00000000000000301a1300000000000000000000000000b8ba1000010000000000000000000000c0ba10000b00000000000000ccba1000030000000000000000000000e4ba1000020000000000000000000000f4ba1000100000000000000004bb100004000000000000000000000024bb100002000000000000000000000034bb1000100000000000000044bb10000500000000000000000000006cbb10000200000000000000000000007cbb1000110000000000000004bb100004000000000000000000000090bb100002000000000000004261746368496e74657272757074656460dc120003000000e00e13000d0000004dbe100056000000a3be1000130000004261746368436f6d706c6574656400001abe1000330000004e65774d756c74697369670020af12000900000020af120009000000e9bc1000080000008dbd100052000000dfbd10003b0000004d756c7469736967417070726f76616c20af120009000000d3bc10001600000020af120009000000e9bc100008000000f1bc10005600000047bd1000460000004d756c7469736967457865637574656420af120009000000d3bc10001600000020af120009000000e9bc100008000000940d12000e00000033bc10004b0000007ebc1000550000004d756c746973696743616e63656c6c6564000000a0bb10004c000000ecbb1000470000002041206d756c7469736967206f7065726174696f6e20686173206265656e2063616e63656c6c65642e20466972737420706172616d20697320746865206163636f756e7420746861742069732063616e63656c6c696e672c20746869726420697320746865206d756c7469736967206163636f756e742c20666f757274682069732068617368206f66207468652063616c6c2e2041206d756c7469736967206f7065726174696f6e20686173206265656e2065786563757465642e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c20746869726420697320746865206d756c7469736967206163636f756e742c20666f757274682069732068617368206f66207468652063616c6c20746f2062652065786563757465642e54696d65706f696e743c426c6f636b4e756d6265723e43616c6c486173682041206d756c7469736967206f7065726174696f6e20686173206265656e20617070726f76656420627920736f6d656f6e652e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c20746869726420697320746865206d756c7469736967206163636f756e742c20666f757274682069732068617368206f66207468652063616c6c2e2041206e6577206d756c7469736967206f7065726174696f6e2068617320626567756e2e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c207365636f6e6420697320746865206d756c7469736967206163636f756e742c2074686972642069732068617368206f66207468652063616c6c2e204261746368206f66206469737061746368657320636f6d706c657465642066756c6c792077697468206e6f206572726f722e204261746368206f66206469737061746368657320646964206e6f7420636f6d706c6574652066756c6c792e20496e646578206f66206669727374206661696c696e6720646973706174636820676976656e2c2061732077656c6c20617320746865206572726f722e0000000000003eb91000050000000000000094bf1000010000000000000000000000acbf100013000000000000000000000043b91000060000000000000044c0100002000000000000000000000074c0100008000000000000000000000049b910000800000000000000b4c0100004000000000000000000000014c1100032000000000000000000000051b910001000000000000000a4c2100004000000000000000000000004c3100027000000000000000000000061b910000f000000000000003cc410000400000000000000000000009cc410001b00000000000000000000000bd41000050000000000000010d410001700000071d1100020000000301a13000000000091d110003b000000301a130000000000ccd110001f000000301a130000000000ebd110003c000000301a130000000000f5bd12000b00000027d21000240000004bd210002e00000079d210003100000044be12000c000000301a130000000000aad210005600000000d310004d0000004dd3100056000000a3d3100054000000f7d31000140000000000000098d912000500000000000000f7ce12000300000000000000fbea1200040000000000000061d112001700000000d1100038000000301a13000000000098c9120034000000301a130000000000f5bd12000b00000038d110001900000051d110002000000044be12000c00000000000000eece12000900000000000000f7ce120003000000000000005ec910001100000000000000ddce1200110000000000000092cd10000f00000000000000a1cd10002100000000000000fbea1200040000000000000061d1120017000000a2c9100056000000f8c910003f000000301a130000000000c2cd10002d000000301a13000000000037ca1000540000008bca100058000000e3ca10000e000000301a13000000000098c9120034000000301a130000000000fcc510005600000052c6100051000000a3c610001c000000f1ca10005700000048cb1000550000009dcb100036000000efcd100023000000301a13000000000012ce1000480000005ace100047000000301a130000000000a1ce100057000000f8ce1000560000004ecf100038000000301a130000000000f5bd12000b00000086cf1000150000006ac71000340000009ec7100050000000eec71000520000009bcf10004900000040c810003000000021cc10003600000057cc10003f0000002bc112000d000000e4cf10001c00000096cc10004c000000e2cc10002400000006cd10003d00000000d010002000000043cd10000f00000020d010002300000043d010002400000067d0100025000000f2c810000d0000008cd0100030000000bcd0100031000000edd010001300000044be12000c00000000000000eece12000900000000000000f7ce120003000000000000005ec910001100000000000000ddce1200110000000000000092cd10000f00000000000000a1cd1000210000000000000091c9100009000000000000009ac9100008000000a2c9100056000000f8c910003f000000301a13000000000037ca1000540000008bca100058000000e3ca10000e000000301a13000000000098c9120034000000301a130000000000fcc510005600000052c6100051000000a3c610001c000000f1ca10005700000048cb1000550000009dcb10003600000036c7100034000000301a130000000000d3cb10004e000000301a130000000000f5bd12000b000000af8811000a0000006ac71000340000009ec7100050000000eec710005200000040c810003000000021cc10003600000057cc10003f0000002bc112000d00000096cc10004c000000e2cc10002400000006cd10003d000000afc810002300000043cd10000f00000052cd10001f00000071cd100021000000f2c810000d000000ffc810002f0000002ec910003000000044be12000c00000000000000eece12000900000000000000f7ce120003000000000000005ec910001100000000000000ddce120011000000000000006fc91000090000000000000078c91000190000000000000091c9100009000000000000009ac910000800000074c5100056000000cac5100032000000301a13000000000098c9120034000000301a130000000000fcc510005600000052c6100051000000a3c610001c000000bfc610005800000017c710001f00000036c7100034000000301a130000000000f5bd12000b000000af8811000a0000006ac71000340000009ec7100050000000eec710005200000040c81000300000002bc112000d00000070c810002200000092c810001d000000afc8100023000000d2c8100020000000f2c810000d000000ffc810002f0000002ec910003000000044be12000c0000002043616e63656c2061207072652d6578697374696e672c206f6e2d676f696e67206d756c7469736967207472616e73616374696f6e2e20416e79206465706f7369742072657365727665642070726576696f75736c7920666f722074686973206f7065726174696f6e2077696c6c20626520756e7265736572766564206f6e20737563636573732e202d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e202d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869732064697370617463682e204d6179206e6f7420626520656d7074792e202d206074696d65706f696e74603a205468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e20666f7220746869732064697370617463682e202d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e202d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e202d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f662020207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2e202d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602e202d20492f4f3a2031207265616420604f285329602c206f6e652072656d6f76652e202d2053746f726167653a2072656d6f766573206f6e65206974656d2e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a2034362e3731202b20302e3039202a2053202d204442205765696768743a20202020202d20526561643a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d20202020202d2057726974653a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d6f746865725f7369676e61746f7269657374696d65706f696e7454696d65706f696e743c543a3a426c6f636b4e756d6265723e63616c6c5f686173685b75383b2033325d20526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e7420696620617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e205061796d656e743a20604d756c74697369674465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c757320607468726573686f6c64602074696d657320604d756c74697369674465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f722069732063616e63656c6c65642e202d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e204966206974206973206e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2e204e4f54453a2049662074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2077616e7420746f20757365206061735f6d756c74696020696e73746561642e202d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292e202d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e202d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c207769746820612020206465706f7369742074616b656e20666f7220697473206c69666574696d65206f66202020604d756c74697369674465706f73697442617365202b207468726573686f6c64202a204d756c74697369674465706f736974466163746f72602e202d2042617365205765696768743a20202020202d204372656174653a2035362e33202b20302e313037202a205320202020202d20417070726f76653a2033392e3235202b20302e313231202a20536d617962655f74696d65706f696e744f7074696f6e3c54696d65706f696e743c543a3a426c6f636b4e756d6265723e3e2049662074686572652061726520656e6f7567682c207468656e206469737061746368207468652063616c6c2e202d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e204e4f54453a20556e6c6573732074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2067656e6572616c6c792077616e7420746f207573652060617070726f76655f61735f6d756c74696020696e73746561642c2073696e6365206974206f6e6c7920726571756972657320612068617368206f66207468652063616c6c2e20526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c7420696620607468726573686f6c64602069732065786163746c79206031602e204f7468657277697365206f6e20737563636573732c20726573756c7420697320604f6b6020616e642074686520726573756c742066726f6d2074686520696e746572696f722063616c6c2c206966206974207761732065786563757465642c206d617920626520666f756e6420696e20746865206465706f736974656420604d756c7469736967457865637574656460206576656e742e202d20604f2853202b205a202b2043616c6c29602e202d204f6e652063616c6c20656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285a296020776865726520605a602069732074782d6c656e2e202d2054686520776569676874206f6620746865206063616c6c602e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d20202020202d204372656174653a2035392e32202b20302e303936202a205320c2b57320202020202d20417070726f76653a2034322e3237202b202e313136202a205320c2b57320202020202d20436f6d706c6574653a2035302e3931202b202e323332202a205320c2b57320202020202d2052656164733a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d20202020202d205772697465733a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d202d20506c75732043616c6c205765696768742053656e6420612063616c6c207468726f75676820616e20696e64657865642070736575646f6e796d206f66207468652073656e6465722e202d2042617365207765696768743a20322e38363320c2b573202d20506c75732074686520776569676874206f6620746865206063616c6c602053656e642061206261746368206f662064697370617463682063616c6c732e20546869732077696c6c206578656375746520756e74696c20746865206669727374206f6e65206661696c7320616e64207468656e2073746f702e204d61792062652063616c6c65642066726f6d20616e79206f726967696e2e202d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e202d2042617365207765696768743a2031352e3634202b202e393837202a206320c2b573202d20506c7573207468652073756d206f66207468652077656967687473206f6620746865206063616c6c73602e202d20506c7573206f6e65206164646974696f6e616c206576656e742e202872657065617420726561642f77726974652920546869732077696c6c2072657475726e20604f6b6020696e20616c6c2063697263756d7374616e6365732e20546f2064657465726d696e65207468652073756363657373206f66207468652062617463682c20616e206576656e74206973206465706f73697465642e20496620612063616c6c206661696c656420616e64207468652062617463682077617320696e7465727275707465642c207468656e2074686520604261746368496e74657272757074656460206576656e74206973206465706f73697465642c20616c6f6e67207769746820746865206e756d626572206f66207375636365737366756c2063616c6c73206d61646520616e6420746865206572726f72206f6620746865206661696c65642063616c6c2e20496620616c6c2077657265207375636365737366756c2c207468656e2074686520604261746368436f6d706c6574656460206576656e74206973206465706f73697465642e63616c6c735665633c3c542061732054726169743e3a3a43616c6c3e000000000080d410000900000002050200000000007ac312000c000000000000009ac91000080000000000000089d410003400000000000000301a1300c0d410000000000000000000d0d410000100000000000000000000004d756c7469736967734d756c74697369673c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e0000004200000000000000010000005b000000d8d41000250000002054686520736574206f66206f70656e206d756c7469736967206f7065726174696f6e732e6d6f646c70792f7574696c697375626100000000000000c0ab12000d0000000000000060d610000100000000000000000000002fb910000f0000000000000068d610000100000000000000000000001eb91000110000000000000070d610000100000000000000000000000db91000110000000000000078d61000010000000000000000000000fbb81000120000000000000080d61000010000000000000000000000e6b81000150000000000000088d61000010000000000000000000000d3b81000130000000000000090d61000010000000000000000000000d0dc1000080000000000000098d61000010000000000000000000000fbda10000800000000000000a0d61000010000000000000000000000c8b810000b00000000000000a8d61000010000000000000000000000bab810000e00000000000000b0d61000010000000000000000000000a7b810001300000000000000b8d61000010000000000000049d910001d0000001dd910002c000000f5d8100028000000cad810002b0000009ed810002c0000005ad810004400000016d8100044000000ded710003800000092d710004c0000004ad7100048000000fed610004c000000c0d610003e00000020412074696d65706f696e742077617320676976656e2c20796574206e6f206d756c7469736967206f7065726174696f6e20697320756e6465727761792e204120646966666572656e742074696d65706f696e742077617320676976656e20746f20746865206d756c7469736967206f7065726174696f6e207468617420697320756e6465727761792e204e6f2074696d65706f696e742077617320676976656e2c2079657420746865206d756c7469736967206f7065726174696f6e20697320616c726561647920756e6465727761792e204f6e6c7920746865206163636f756e742074686174206f726967696e616c6c79206372656174656420746865206d756c74697369672069732061626c6520746f2063616e63656c2069742e204d756c7469736967206f7065726174696f6e206e6f7420666f756e64207768656e20617474656d7074696e6720746f2063616e63656c2e205468652073656e6465722077617320636f6e7461696e656420696e20746865206f74686572207369676e61746f726965733b2069742073686f756c646e27742062652e20546865207369676e61746f7269657320776572652070726f7669646564206f7574206f66206f726465723b20746865792073686f756c64206265206f7264657265642e2054686572652061726520746f6f206d616e79207369676e61746f7269657320696e20746865206c6973742e2054686572652061726520746f6f20666577207369676e61746f7269657320696e20746865206c6973742e2043616c6c20646f65736e2774206e65656420616e7920286d6f72652920617070726f76616c732e2043616c6c20697320616c726561647920617070726f7665642062792074686973207369676e61746f72792e205468726573686f6c6420697320746f6f206c6f7720287a65726f292e0000abd910000d00000090d910001b0000005c09120002000000a2a3120036000000e20200000100000042616420696e70757420646174612070726f766964656420746f20657865637574655f626c6f636bc0d9100010000000696e697469616c697a655f626c6f636bd8d910000f0000006170706c795f65787472696e73696300f0d9100013000000696e686572656e745f65787472696e73696373000cda10000f000000636865636b5f696e686572656e74730024da10001400000076616c69646174655f7472616e73616374696f6e40da10000f0000006f6666636861696e5f776f726b65720058da10000d0000006163636f756e745f6e6f6e6365000000fbea12000400000078da10000b0000006765745f73746f72616765008cda10000f00000072656e745f70726f6a656374696f6e00a4da10000a00000071756572795f696e666f0000b8da10001500000067656e65726174655f73657373696f6e5f6b657973000000d8da1000130000006465636f64655f73657373696f6e5f6b6579734e6f745472616e73666572496e5573654e6f744f776e65724e6f7441737369676e6564636c61696d7472616e7366657266726565666f7263655f7472616e736665724163636f756e74730000000000000090db10000d00000000000000a0db1000020000000000000000000000b0db1000010000000000000000000000b8db10000a00000000000000c4db1000010000000000000000000000ccdb10000100000000000000496e64657841737369676e656400000020af12000900000004dc10000c00000010dc10001e000000496e6465784672656564000004dc10000c000000d4db1000300000002041206163636f756e7420696e64657820686173206265656e2066726565642075702028756e61737369676e6564292e4163636f756e74496e6465782041206163636f756e7420696e646578207761732061737369676e65642e7061726974792f7374616b696e672d656c656374696f6e2f546f6f4d616e7952656769737472617273546f6f4d616e794669656c6473496e76616c6964546172676574496e76616c6964496e646578496e76616c69644a756467656d656e744a756467656d656e74476976656e537469636b794a756467656d656e744e6f4964656e746974794665654368616e676564456d707479496e6465784e6f744e616d65644e6f74466f756e64546f6f4d616e795375624163636f756e74736164645f7265676973747261727365745f6964656e746974797365745f73756273636c6561725f6964656e74697479726571756573745f6a756467656d656e7463616e63656c5f726571756573747365745f6665657365745f6163636f756e745f69647365745f6669656c647370726f766964655f6a756467656d656e746b696c6c5f6964656e7469747953757065724f6600000000b0de10000b0000000000000074ad1200010000000000000000000000bcde1000010000000000000000000000c4de10000f0000000000000084111200020000000000000000000000d4de1000010000000000000000000000dcde10000e0000000000000084111200020000000000000000000000ecde1000010000000000000000000000f4de1000120000000000000008df100002000000000000000000000018df100001000000000000000000000020df1000140000000000000008df100002000000000000000000000034df10000100000000000000000000008ddc10000e0000000000000008df10000200000000000000000000003cdf100001000000000000000000000044df10000e0000000000000054df10000100000000000000000000005cdf100001000000000000004964656e746974795365740060e010003c0000004964656e74697479436c6561726564002ce01000340000004964656e746974794b696c6c65640000fadf1000320000004a756467656d656e74526571756573746564000020af1200090000007bdf10000e000000d2df1000280000004a756467656d656e74556e726571756573746564afdf10002300000089df100026000000526567697374726172416464656400007bdf10000e00000064df100017000000204120726567697374726172207761732061646465642e526567697374726172496e6465782041206a756467656d656e742077617320676976656e2062792061207265676973747261722e2041206a756467656d656e74207265717565737420776173207265747261637465642e2041206a756467656d656e74207761732061736b65642066726f6d2061207265676973747261722e2041206e616d65207761732072656d6f76656420616e642074686520676976656e2062616c616e636520736c61736865642e2041206e616d652077617320636c65617265642c20616e642074686520676976656e2062616c616e63652072657475726e65642e2041206e616d652077617320736574206f72207265736574202877686963682077696c6c2072656d6f766520616c6c206a756467656d656e7473292e416c69766520636f6e7472616374206f7220746f6d6273746f6e6520616c72656164792065786973747300004200000000000000010000006d0000004200000000000000010000006400000074696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c4c6174656e657373636f6e74726163742073756273797374656d20726573756c74696e6720696e20706f73697469766520696d62616c616e63652100000000ade812000a000000000000000000000010f111000300000000000000000000000000000000000000000000000000000000000000301a13001ce510000000000000000000c4e4100001000000000000000100000000000000b7e812000b0000000000000000000000cce410002700000000000000000000000000000000000000000000000000000000000000301a1300f4e41000000000000000000004e5100001000000000000000100000000000000c2e812000b000000000000000000000010f111000300000000000000000000000000000000000000000000000000000000000000301a13001ce5100000000000000000000ce5100002000000000000000100000000000000cde812000b000000000000000000000010f111000300000000000000000000000000000000000000000000000000000000000000301a13001ce5100000000000000000002ce5100001000000000000000100000000000000d8e812000a000000000000000000000034e510001600000000000000000000000000000000000000000000000000000000000000301a13009ce5100000000000000000004ce510000a000000000000000100000000000000e2e812000e000000000000000000000034e510001600000000000000000000000000000000000000000000000000000000000000301a13009ce510000000000000000000ace5100001000000000000000100000000000000f0e812000c000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a130054e610000000000000000000b4e5100009000000000000000100000000000000fce8120011000000010500000000000060dc12000300000000000000fce510001d00000000000000000000000000000000000000301a13001ce610000000000000000000301a1300000000000000000001000000000000004df212000b00000000000000000000002ce610000800000000000000000000000000000000000000000000000000000000000000301a130034e61000000000000000000044e610000200000000000000000000000000000019e1100008000000000000000000000006cf12000e00000000000000000000000000000000000000000000000000000000000000301a130054e61000000000000000000064e61000050000000000000001000000b2eb1000150000005665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e004200000000000000010000005900000097eb10001b00000035eb10003e00000073eb1000240000004200000000000000010000006e00000020eb1000150000007363686e6f72726b656c3a3a52616e646f6d6e65737300005ae910002e000000301a13000000000088e910000b000000301a13000000000093e9100041000000d4e910003e00000012ea10004500000057ea1000450000009cea100041000000ddea1000430000004200000000000000010000006f00000043e9100017000000fee710001f000000301a1300000000001de810003d0000005ae81000400000009ae8100025000000301a130000000000bfe810003b000000fae81000420000003ce91000070000005665633c7363686e6f72726b656c3a3a5261775652464f75747075743e000000420000000000000001000000590000004d617962655672664200000000000000010000005b00000077e7100040000000b7e7100047000000420000000000000001000000570000008ce6100036000000301a130000000000c2e610004500000007e71000440000004be710002c00000020486f77206c617465207468652063757272656e7420626c6f636b20697320636f6d706172656420746f2069747320706172656e742e205468697320656e74727920697320706f70756c617465642061732070617274206f6620626c6f636b20657865637574696f6e20616e6420697320636c65616e6564207570206f6e20626c6f636b2066696e616c697a6174696f6e2e205175657279696e6720746869732073746f7261676520656e747279206f757473696465206f6620626c6f636b20657865637574696f6e20636f6e746578742073686f756c6420616c77617973207969656c64207a65726f2e2054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d6560206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f63682072616e646f6d6e6573732e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2043757272656e7420736c6f74206e756d6265722e2054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e2054686973206973203020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e000000000038ec10000d0000000000000010f111000300000000000000301a130048ec1000000000000000000058ec100002000000000000000000000068ec10001100000000000000383311000900000000000000301a13007cec100000000000000000008cec1000050000000000000045706f63684475726174696f6e00000042000000000000000100000070000000e4ed10004300000027ee10003f0000004578706563746564426c6f636b54696d6500000042000000000000000100000071000000b4ec100041000000f5ec10004400000039ed1000410000007aed100042000000bced10002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e65706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b2071656400d0ee100030000000790100001b000000d0ee10003000000081010000200000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f626162652f7372632f6c69622e7273000000000edb10000500000000000000b0ef1000010000000000000000000000c8ef100010000000000000000000000013db1000080000000000000048f0100002000000000000000000000078f010001000000000000000000000001bdb10000400000000000000b0ef1000010000000000000000000000f8f010001000000000000000000000001fdb10000e0000000000000048f0100002000000000000000000000078f1100010000000000000000000000098d912000500000000000000e6f510000f000000f5f5100027000000301a1300000000001cf6100038000000301a13000000000098c9120034000000301a13000000000054f610003d000000301a1300000000003df3100025000000301a130000000000f5bd12000b000000184a11000a00000062f3100027000000e2f41000190000002bc112000d00000044be12000c000000000000008421120003000000000000007ac312000c0000000000000098d912000500000000000000e6f510000f000000fbf410005800000053f510002f000000301a13000000000098c9120034000000301a13000000000082f510004a000000e5f2100058000000301a1300000000003df3100025000000301a130000000000f5bd12000b000000184a11000a00000062f3100027000000ccf510001a0000002bc112000d00000044be12000c000000a8f3100026000000301a130000000000cef3100058000000301a13000000000026f4100056000000301a1300000000007cf4100044000000301a130000000000c0f4100022000000301a130000000000f5bd12000b000000184a11000a00000062f3100027000000e2f41000190000002bc112000d00000044be12000c000000f8f11000560000004ef210003b000000301a13000000000089f2100032000000301a130000000000bbf210002a000000e5f2100058000000301a1300000000003df3100025000000301a130000000000f5bd12000b000000184a11000a00000062f310002700000089f310001f0000002bc112000d00000044be12000c00000020466f72636520616e20696e64657820746f20616e206163636f756e742e205468697320646f65736e277420726571756972652061206465706f7369742e2049662074686520696e64657820697320616c72656164792068656c642c207468656e20616e79206465706f736974206973207265696d62757273656420746f206974732063757272656e74206f776e65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e202d2060696e646578603a2074686520696e64657820746f206265202872652d2961737369676e65642e202d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e20456d6974732060496e64657841737369676e656460206966207375636365737366756c2e202d204f6e652073746f72616765206d75746174696f6e2028636f64656320604f28312960292e202d20557020746f206f6e652072657365727665206f7065726174696f6e2e204672656520757020616e20696e646578206f776e6564206279207468652073656e6465722e205061796d656e743a20416e792070726576696f7573206465706f73697420706c6163656420666f722074686520696e64657820697320756e726573657276656420696e207468652073656e646572206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206f776e2074686520696e6465782e202d2060696e646578603a2074686520696e64657820746f2062652066726565642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e20456d6974732060496e646578467265656460206966207375636365737366756c2e202d204f6e652072657365727665206f7065726174696f6e2e2041737369676e20616e20696e64657820616c7265616479206f776e6564206279207468652073656e64657220746f20616e6f74686572206163636f756e742e205468652062616c616e6365207265736572766174696f6e206973206566666563746976656c79207472616e7366657272656420746f20746865206e6577206163636f756e742e202d2060696e646578603a2074686520696e64657820746f2062652072652d61737369676e65642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e202d204f6e65207472616e73666572206f7065726174696f6e2e543a3a4163636f756e74496e6465782041737369676e20616e2070726576696f75736c7920756e61737369676e656420696e6465782e205061796d656e743a20604465706f736974602069732072657365727665642066726f6d207468652073656e646572206163636f756e742e202d2060696e646578603a2074686520696e64657820746f20626520636c61696d65642e2054686973206d757374206e6f7420626520696e207573652e000000000000002ddb1000080000000102000000000000e6f510000f00000000000000ecf610001c00000000000000000000000000000000000000301a130008f71000000000000000000018f7100001000000000000000000000028543a3a4163636f756e7449642c2042616c616e63654f663c543e294200000000000000010000005b00000020f710002200000020546865206c6f6f6b75702066726f6d20696e64657820746f206163636f756e742e000000000000eadc10000d0000000000000004b9120001000000000000000000000028f910000e0000000000000000000000f7dc10000c0000000000000098f91000010000000000000000000000b0f9100014000000000000000000000003dd1000080000000000000050fa100001000000000000000000000068fa10001600000000000000000000000bdd10000e00000000000000301a130000000000000000000000000018fb100015000000000000000000000019dd10001100000000000000c0fb1000020000000000000000000000f0fb10001800000000000000000000002add10000e00000000000000b0fc1000010000000000000000000000c8fc100012000000000000000000000038dd1000070000000000000058fd100002000000000000000000000088fd10000d00000000000000000000003fdd10000e00000000000000f0fd100002000000000000000000000020fe10000d00000000000000000000004ddd10000a0000000000000088fe1000020000000000000000000000b8fe10000d000000000000000000000057dd1000110000000000000020ff100003000000000000000000000068ff100014000000000000000000000068dd10000d00000000000000b4471100010000000000000000000000080011001400000000000000841311001f000000301a130000000000a313110047000000301a130000000000ea1311002b000000301a1300000000001514110026000000301a130000000000f5bd12000b0000003b1411004a00000085141100270000002bc112000d000000ac1411003900000044be12000c00000000000000741311000400000000000000781311000c000000341111004b000000301a1300000000007f11110056000000d511110015000000301a13000000000098c9120034000000301a130000000000ea11110024000000301a1300000000000e12110023000000301a130000000000f5bd12000b000000311211001200000043121100480000008b12110039000000c412110021000000e5121100490000002bc112000d0000002e1311004600000044be12000c000000000000001711110004000000000000001b11110019000000a10e110024000000301a130000000000c50e1100560000001b0f11004c000000301a1300000000005b0c110059000000b40c11000a000000301a130000000000670f11002d000000301a130000000000f5bd12000b000000940f11000d000000a10f11003a0000002a0d110036000000db0f110022000000fd0f11000600000003101100380000003b101100300000006b101100310000009c10110035000000d11011004600000044be12000c000000d00b11004f000000301a1300000000001f0c11003c000000301a1300000000005b0c110059000000b40c11000a000000301a130000000000be0c110027000000301a130000000000f5bd12000b000000e50c110011000000f60c1100340000002a0d110036000000600d110049000000a90d110023000000cc0d1100330000002bc112000d000000ff0d11000e0000000d0e11004b000000580e11004900000044be12000c000000000000008c0511000900000000000000950511001700000000000000c90b110007000000000000008075120015000000cb09110026000000301a130000000000f109110056000000470a110007000000301a130000000000810811004e000000cf08110015000000301a1300000000004e0a110048000000960a110056000000301a130000000000ec0a11000d000000f90a11002f000000280b110004000000301a1300000000002c0b11002a000000301a130000000000f5bd12000b000000c10411000e000000bd02110021000000560b11002f0000002bc112000d000000850b11004400000044be12000c000000000000008c05110009000000000000007bdf10000e000000270811001b000000301a130000000000420811003f000000301a130000000000810811004e000000cf08110015000000301a130000000000e408110052000000301a130000000000360911002c000000301a130000000000f5bd12000b000000c10411000e000000bd0211002100000062091100230000002bc112000d000000850911004600000044be12000c0000000000000098d91200050000000000000095051100170000000000000024081100030000000000000080751200150000008d07110047000000301a1300000000007c03110056000000ee05110029000000301a130000000000170611003e000000d407110016000000301a130000000000f5bd12000b0000006c8711000a000000990611001f000000ea0711003a00000044be12000c0000000000000098d9120005000000000000009505110017000000000000008421120003000000000000007ac312000c0000000607110030000000301a1300000000007c03110056000000ee05110029000000301a130000000000170611003e000000360711001d000000301a130000000000f5bd12000b0000006c8711000a000000990611001f000000530711003a00000044be12000c0000000000000098d912000500000000000000950511001700000000000000f20611000600000000000000f80611000e000000c30511002b000000301a1300000000007c03110056000000ee05110029000000301a130000000000170611003e0000005506110044000000301a130000000000f5bd12000b0000006c8711000a000000990611001f000000b80611003a00000044be12000c000000000000008c0511000900000000000000950511001700000000000000834b11000600000000000000f320120023000000000000004e3712000900000000000000ac051100170000004d0311002f000000301a1300000000007c03110056000000d20311002d000000301a130000000000ff031100490000001102110056000000670211001e0000004804110053000000301a1300000000009b04110026000000301a130000000000f5bd12000b000000c10411000e000000cf04110022000000f104110026000000170511002f0000002bc112000d000000460511004600000044be12000c000000a800110051000000301a130000000000f9001100590000005201110052000000a401110021000000301a130000000000c50111004c000000301a1300000000001102110056000000670211001e000000301a1300000000008502110026000000301a130000000000f5bd12000b000000ab02110012000000bd02110021000000de0211001d0000002bc112000d000000fb0211005200000044be12000c0000002052656d6f766520616e206163636f756e742773206964656e7469747920616e64207375622d6163636f756e7420696e666f726d6174696f6e20616e6420736c61736820746865206465706f736974732e205061796d656e743a2052657365727665642062616c616e6365732066726f6d20607365745f737562736020616e6420607365745f6964656e74697479602061726520736c617368656420616e642068616e646c65642062792060536c617368602e20566572696669636174696f6e2072657175657374206465706f7369747320617265206e6f742072657475726e65643b20746865792073686f756c642062652063616e63656c6c6564206d616e75616c6c79207573696e67206063616e63656c5f72657175657374602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f206f72206d617463682060543a3a466f7263654f726967696e602e202d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e742020207769746820612072656769737465726564206964656e746974792e20456d69747320604964656e746974794b696c6c656460206966207375636365737366756c2e202d20604f2852202b2053202b205829602e202d204f6e652062616c616e63652d72657365727665206f7065726174696f6e2e202d206053202b2032602073746f72616765206d75746174696f6e732e202d2042656e63686d61726b3a203130312e39202b2052202a20302e303931202b2053202a20322e353839202b2058202a20302e38373120c2b57320286d696e207371756172657320616e616c79736973292050726f766964652061206a756467656d656e7420666f7220616e206163636f756e742773206964656e746974792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74206f6620746865207265676973747261722077686f736520696e64657820697320607265675f696e646578602e202d20607265675f696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206265696e67206d6164652e202d20606a756467656d656e74603a20746865206a756467656d656e74206f662074686520726567697374726172206f6620696e64657820607265675f696e646578602061626f75742060746172676574602e20456d69747320604a756467656d656e74476976656e60206966207375636365737366756c2e202d20604f2852202b205829602e202d204f6e652062616c616e63652d7472616e73666572206f7065726174696f6e2e202d20557020746f206f6e65206163636f756e742d6c6f6f6b7570206f7065726174696f6e2e202d2053746f726167653a2031207265616420604f285229602c2031206d757461746520604f2852202b205829602e202d2042656e63686d61726b3a2034372e3737202b2052202a20302e333336202b2058202a20312e36363420c2b57320286d696e207371756172657320616e616c79736973297265675f696e646578436f6d706163743c526567697374726172496e6465783e4a756467656d656e743c42616c616e63654f663c543e3e2053657420746865206669656c6420696e666f726d6174696f6e20666f722061207265676973747261722e206f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e202d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e202d20606669656c6473603a20746865206669656c64732074686174207468652072656769737472617220636f6e6365726e73207468656d73656c76657320776974682e202d204f6e652073746f72616765206d75746174696f6e20604f285229602e202d2042656e63686d61726b3a20382e393835202b2052202a20302e34313320c2b57320286d696e207371756172657320616e616c79736973296669656c64734964656e746974794669656c6473204368616e676520746865206163636f756e74206173736f63696174656420776974682061207265676973747261722e202d20606e6577603a20746865206e6577206163636f756e742049442e202d2042656e63686d61726b3a2031302e3035202b2052202a20302e34333820c2b57320286d696e207371756172657320616e616c797369732920536574207468652066656520726571756972656420666f722061206a756467656d656e7420746f206265207265717565737465642066726f6d2061207265676973747261722e202d2060666565603a20746865206e6577206665652e202d2042656e63686d61726b3a20382e383438202b2052202a20302e34323520c2b57320286d696e207371756172657320616e616c79736973296665652043616e63656c20612070726576696f757320726571756573742e205061796d656e743a20412070726576696f75736c79207265736572766564206465706f7369742069732072657475726e6564206f6e20737563636573732e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564206964656e746974792e202d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206e6f206c6f6e676572207265717565737465642e20456d69747320604a756467656d656e74556e72657175657374656460206966207375636365737366756c2e202d204f6e652073746f72616765206d75746174696f6e20604f2852202b205829602e202d2042656e63686d61726b3a2035302e3035202b2052202a20302e333231202b2058202a20312e36383820c2b57320286d696e207371756172657320616e616c797369732920526571756573742061206a756467656d656e742066726f6d2061207265676973747261722e205061796d656e743a204174206d6f737420606d61785f666565602077696c6c20626520726573657276656420666f72207061796d656e7420746f2074686520726567697374726172206966206a756467656d656e7420676976656e2e202d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973207265717565737465642e202d20606d61785f666565603a20546865206d6178696d756d206665652074686174206d617920626520706169642e20546869732073686f756c64206a757374206265206175746f2d706f70756c617465642061733a206060606e6f636f6d70696c652053656c663a3a7265676973747261727328292e676574287265675f696e646578292e756e7772617028292e6665652060606020456d69747320604a756467656d656e7452657175657374656460206966207375636365737366756c2e202d2053746f726167653a2031207265616420604f285229602c2031206d757461746520604f2858202b205229602e202d2042656e63686d61726b3a2035392e3032202b2052202a20302e343838202b2058202a20312e3720c2b57320286d696e207371756172657320616e616c79736973296d61785f66656520436c65617220616e206163636f756e742773206964656e7469747920696e666f20616e6420616c6c207375622d6163636f756e747320616e642072657475726e20616c6c206465706f736974732e205061796d656e743a20416c6c2072657365727665642062616c616e636573206f6e20746865206163636f756e74206172652072657475726e65642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564206964656e746974792e20456d69747320604964656e74697479436c656172656460206966207375636365737366756c2e202d20604f2852202b2053202b205829602020202d20776865726520605260207265676973747261722d636f756e742028676f7665726e616e63652d626f756e646564292e2020202d2077686572652060536020737562732d636f756e742028686172642d20616e64206465706f7369742d626f756e646564292e2020202d20776865726520605860206164646974696f6e616c2d6669656c642d636f756e7420286465706f7369742d626f756e64656420616e6420636f64652d626f756e646564292e202d204f6e652062616c616e63652d756e72657365727665206f7065726174696f6e2e202d206032602073746f7261676520726561647320616e64206053202b2032602073746f726167652064656c6574696f6e732e202d2042656e63686d61726b733a2020202d2035372e3336202b2052202a20302e303139202b2053202a20322e353737202b2058202a20302e38373420c2b57320286d656469616e20736c6f70657320616e616c79736973292020202d2035372e3036202b2052202a20302e303036202b2053202a20322e353739202b2058202a20302e38373820c2b57320286d696e207371756172657320616e616c79736973292053657420746865207375622d6163636f756e7473206f66207468652073656e6465722e205061796d656e743a20416e79206167677265676174652062616c616e63652072657365727665642062792070726576696f757320607365745f73756273602063616c6c732077696c6c2062652072657475726e656420616e6420616e20616d6f756e7420605375624163636f756e744465706f736974602077696c6c20626520726573657276656420666f722065616368206974656d20696e206073756273602e202d206073756273603a20546865206964656e74697479277320286e657729207375622d6163636f756e74732e202d20604f2850202b205329602020202d20776865726520605060206f6c642d737562732d636f756e742028686172642d20616e64206465706f7369742d626f756e646564292e202d204174206d6f7374206f6e652062616c616e6365206f7065726174696f6e732e202d2044423a2020202d206050202b2053602073746f72616765206d75746174696f6e732028636f64656320636f6d706c657869747920604f28312960292020202d204f6e652073746f7261676520726561642028636f64656320636f6d706c657869747920604f28502960292e2020202d204f6e652073746f726167652077726974652028636f64656320636f6d706c657869747920604f28532960292e2020202d204f6e652073746f726167652d6578697374732028604964656e746974794f663a3a636f6e7461696e735f6b657960292e202d2042656e63686d61726b3a2033392e3433202b2050202a20322e353232202b2053202a20332e36393820c2b57320286d696e207371756172657320616e616c7973697329737562735665633c28543a3a4163636f756e7449642c2044617461293e2053657420616e206163636f756e742773206964656e7469747920696e666f726d6174696f6e20616e6420726573657276652074686520617070726f707269617465206465706f7369742e20496620746865206163636f756e7420616c726561647920686173206964656e7469747920696e666f726d6174696f6e2c20746865206465706f7369742069732074616b656e2061732070617274207061796d656e7420666f7220746865206e6577206465706f7369742e202d2060696e666f603a20546865206964656e7469747920696e666f726d6174696f6e2e20456d69747320604964656e7469747953657460206966207375636365737366756c2e202d20604f2858202b205827202b205229602020202d20776865726520605860206164646974696f6e616c2d6669656c642d636f756e7420286465706f7369742d626f756e64656420616e6420636f64652d626f756e646564292020202d20776865726520605260206a756467656d656e74732d636f756e7420287265676973747261722d636f756e742d626f756e64656429202d204f6e652062616c616e63652072657365727665206f7065726174696f6e2e202d204f6e652073746f72616765206d75746174696f6e2028636f6465632d7265616420604f285827202b205229602c20636f6465632d777269746520604f2858202b20522960292e202d2042656e63686d61726b3a2035392e3434202b2052202a20302e333839202b2058202a20312e34333420c2b57320286d696e207371756172657320616e616c7973697329696e666f4964656e74697479496e666f2041646420612072656769737472617220746f207468652073797374656d2e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605265676973747261724f726967696e60206f722060526f6f74602e202d20606163636f756e74603a20746865206163636f756e74206f6620746865207265676973747261722e20456d6974732060526567697374726172416464656460206966207375636365737366756c2e202d20604f2852296020776865726520605260207265676973747261722d636f756e742028676f7665726e616e63652d626f756e64656420616e6420636f64652d626f756e646564292e202d204f6e652073746f72616765206d75746174696f6e2028636f64656320604f28522960292e202d2042656e63686d61726b3a2032342e3633202b2052202a20302e353320c2b57320286d696e207371756172657320616e616c797369732900000000000000481611000a00000001050000000000007ac312000c00000000000000521611001a00000000000000000000000000000000000000301a13006c16110000000000000000007c1611000100000000000000000000000000000075dd10000700000001020000000000007ac312000c00000000000000841611001400000000000000000000000000000000000000301a1300981611000000000000000000a816110002000000000000000000000000000000b81611000600000001050000000000007ac312000c00000000000000a48f11002100000000000000000000000000000000000000301a1300c01611000000000000000000d016110003000000000000000100000000000000e81611000a0000000000000000000000f21611003600000000000000000000000000000000000000000000000000000000000000301a1300281711000000000000000000381711000400000000000000010000004964656e746974794f66526567697374726174696f6e3c42616c616e63654f663c543e3e4200000000000000010000005b000000401911004800000028543a3a4163636f756e7449642c2044617461294200000000000000010000005b0000009418110058000000ec18110054000000537562734f660000420000000000000001000000660000001f1811002e000000301a1300000000004d18110047000000526567697374726172735665633c4f7074696f6e3c526567697374726172496e666f3c42616c616e63654f663c543e2c20543a3a4163636f756e7449643e3e3e420000000000000001000000590000005817110053000000ab1711002a000000301a130000000000d51711004a0000002054686520736574206f6620726567697374726172732e204e6f7420657870656374656420746f206765742076657279206269672061732063616e206f6e6c79206265206164646564207468726f7567682061207370656369616c206f726967696e20286c696b656c79206120636f756e63696c206d6f74696f6e292e2054686520696e64657820696e746f20746869732063616e206265206361737420746f2060526567697374726172496e6465786020746f2067657420612076616c69642076616c75652e20416c7465726e6174697665202273756222206964656e746974696573206f662074686973206163636f756e742e20546865206669727374206974656d20697320746865206465706f7369742c20746865207365636f6e64206973206120766563746f72206f6620746865206163636f756e74732e205468652073757065722d6964656e74697479206f6620616e20616c7465726e6174697665202273756222206964656e7469747920746f676574686572207769746820697473206e616d652c2077697468696e207468617420636f6e746578742e20496620746865206163636f756e74206973206e6f7420736f6d65206f74686572206163636f756e742773207375622d6964656e746974792c207468656e206a75737420604e6f6e65602e20496e666f726d6174696f6e20746861742069732070657274696e656e7420746f206964656e746966792074686520656e7469747920626568696e6420616e206163636f756e742e00000000d81a11000c00000000000000b66c12000c00000000000000301a1300e41a11000000000000000000f41a1100010000000000000000000000fc1a11000c00000000000000b66c12000c00000000000000301a1300081b11000000000000000000181b1100010000000000000000000000201b11001100000000000000b66c12000c00000000000000301a1300341b11000000000000000000441b11000300000000000000000000005c1b11000e0000000000000060dc12000300000000000000301a1300881b110000000000000000006c1b1100010000000000000000000000741b1100130000000000000060dc12000300000000000000301a1300881b11000000000000000000981b1100020000000000000000000000a81b11000d0000000000000060dc12000300000000000000301a1300b81b11000000000000000000c81b1100020000000000000042617369634465706f73697442000000000000000100000067000000691e1100360000004669656c644465706f736974420000000000000001000000720000001e1e11004b0000005375624163636f756e744465706f736974000000420000000000000001000000730000001f1d110059000000781d11005c000000d41d11004a0000004d61785375624163636f756e74730000dc1c1100430000004d61784164646974696f6e616c4669656c647300420000000000000001000000740000004b1c110059000000a41c1100380000004d61785265676973747261727300000042000000000000000100000075000000d81b1100540000002c1c11001f000000204d61786d696d756d206e756d626572206f66207265676973747261727320616c6c6f77656420696e207468652073797374656d2e204e656564656420746f20626f756e642074686520636f6d706c6578697479206f662c20652e672e2c207570646174696e67206a756467656d656e74732e204d6178696d756d206e756d626572206f66206164646974696f6e616c206669656c64732074686174206d61792062652073746f72656420696e20616e2049442e204e656564656420746f20626f756e642074686520492f4f20726571756972656420746f2061636365737320616e206964656e746974792c206275742063616e2062652070726574747920686967682e20546865206d6178696d756d206e756d626572206f66207375622d6163636f756e747320616c6c6f77656420706572206964656e746966696564206163636f756e742e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564207375626163636f756e742e20546869732073686f756c64206163636f756e7420666f722074686520666163742074686174206f6e652073746f72616765206974656d27732076616c75652077696c6c20696e637265617365206279207468652073697a65206f6620616e206163636f756e742049442c20616e642074686572652077696c6c20626520616e6f746865722074726965206974656d2077686f73652076616c7565206973207468652073697a65206f6620616e206163636f756e7420494420706c75732033322062797465732e2054686520616d6f756e742068656c64206f6e206465706f73697420706572206164646974696f6e616c206669656c6420666f7220612072656769737465726564206964656e746974792e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564206964656e746974792e00d4f31200340000004a0300001d000000d4f31200340000001e0400003600000000000000d8dc100012000000000000002c201100010000000000000000000000d0dc1000080000000000000034201100010000000000000000000000c8dc100008000000000000003c201100010000000000000000000000bedc10000a0000000000000044201100010000000000000000000000b4dc10000a000000000000004c201100010000000000000000000000aadc10000a00000000000000542011000100000000000000000000009bdc10000f000000000000005c2011000100000000000000000000008ddc10000e00000000000000642011000100000000000000000000007ddc100010000000000000006c20110001000000000000000000000071dc10000c000000000000007420110001000000000000000000000064dc10000d000000000000007c20110001000000000000000000000057dc10000d000000000000008420110001000000000000000000000046dc100011000000000000008c2011000100000000000000a82111001800000093211100150000007e21110015000000712111000d00000061211100100000004e211100130000003c211100120000002b2111001100000018211100130000000221110016000000eb20110017000000cf2011001c000000942011003b000000204d6178696d756d20616d6f756e74206f66207265676973747261727320726561636865642e2043616e6e6f742061646420616e79206d6f72652e20546f6f206d616e79206164646974696f6e616c206669656c64732e205468652074617267657420697320696e76616c69642e2054686520696e64657820697320696e76616c69642e20496e76616c6964206a756467656d656e742e204a756467656d656e7420676976656e2e20537469636b79206a756467656d656e742e204e6f206964656e7469747920666f756e642e20466565206973206368616e6765642e20456d70747920696e6465782e204163636f756e742069736e2774206e616d65642e204163636f756e742069736e277420666f756e642e20546f6f206d616e7920737562732d6163636f756e74732e54696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b4e6f774475706c696361746564486561727462656174496e76616c69644b65796865617274626561744865617274626561744166746572000000000000a82211001100000000000000bc221100010000000000000000000000c4221100010000000000000000000000cc2211000700000000000000301a1300000000000000000000000000d4221100010000000000000000000000dc2211000b00000000000000e8221100010000000000000000000000f022110001000000000000004865617274626561745265636569766564000000c12311000b0000009123110030000000416c6c476f6f64005c23110035000000536f6d654f66666c696e65004423110018000000f82211004c0000002041742074686520656e64206f66207468652073657373696f6e2c206174206c65617374206f6e63652076616c696461746f722077617320666f756e6420746f206265206f66666c696e652e5665633c4964656e74696669636174696f6e5475706c653e2041742074686520656e64206f66207468652073657373696f6e2c206e6f206f6666656e63652077617320636f6d6d69747465642e2041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460417574686f72697479496473657400617474656d707420746f20646976696465206279207a65726f000000760000001000000004000000770000000b221100090000004765747320616e64206465636f6465732074696d657374616d7020696e686572656e7420646174613c24110035000000e80000001f0000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f74696d657374616d702f7372632f6c69622e7273417574686f726564426c6f636b7300902411002e000000be2411000d0000004552524f523a2072657475726e6564206e6578745f6b657920686173206e6f2076616c75653a0a6b6579206973200a6e6578745f6b6579206973200039251100160000005c0912000200000039251100160000004f25110012000000696d6f6e6c696e6570616c6c65745f696d5f6f6e6c696e652f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f696d2d6f6e6c696e652f7372632f6c69622e7273536b697070696e6720686561727462656174206174202e204e6f7420612076616c696461746f722e000000732611001c000000452611002e000000132611001a0000002d26110018000000f72511000a0000000126110012000000df25110018000000c925110016000000ac2511001d0000004661696c656420746f206665746368206e6574776f726b2073746174654661696c656420746f2061637175697265206c6f636b4661696c656420746f207369676e20686561727462656174417574686f726974792020697320616c7265616479206f6e6c696e6548656172746265617420616c72656164792073656e74206174202e2057616974696e6720666f7220696e636c7573696f6e2e546f6f206561726c7920746f2073656e64206865617274626561742c206e657874206578706563746564206174204661696c656420746f207375626d6974207472616e73616374696f6e00042511003500000026020000340000007061726974792f696d2d6f6e6c696e652d6865617274626561742f00dc26110008000000e426110020000000042711000b0000009de91200030000005b696e6465783a205d205265706f7274696e6720696d2d6f6e6c696e6520617420626c6f636b3a20202873657373696f6e3a2000301a130000000000301a1300000000004200000004000000040000007800000042000000040000000400000078000000506172656e7420686173682073686f756c642062652076616c69642e5472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642ef527110032000000446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e53746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e5369676e617475726520766572696669636174696f6e206661696c65642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e00000000000b221100090000000000000054281100020000000000000000000000842811000a00000000000000000000000b22110009000000000000001f2a11001900000000000000382a11000a00000000000000422a11002f000000f5bd12000b000000d4281100480000001c2911002d000000301a13000000000049291100230000006c2911002c000000982911004f000000e729110017000000fe2911002100000044be12000c000000202d20436f6d706c65786974793a20604f284b202b20452960207768657265204b206973206c656e677468206f6620604b6579736020616e642045206973206c656e677468206f66202020604865617274626561742e6e6574776f726b5f73746174652e65787465726e616c5f61646472657373602020202d20604f284b29603a206465636f64696e67206f66206c656e67746820604b602020202d20604f284529603a206465636f64696e672f656e636f64696e67206f66206c656e67746820604560202d20446252656164733a2070616c6c65745f73657373696f6e206056616c696461746f7273602c2070616c6c65745f73657373696f6e206043757272656e74496e646578602c20604b657973602c2020206052656365697665644865617274626561747360202d2044625772697465733a2060526563656976656448656172746265617473604865617274626561743c543a3a426c6f636b4e756d6265723e5f7369676e61747572653c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e617475726500000000000000142211000e000000000000000000000006cf12000e00000000000000000000000000000000000000000000000000000000000000301a13005c2c11000000000000000000d42b1100060000000000000001000000000000008fe81200040000000000000000000000042c11001300000000000000000000000000000000000000000000000000000000000000301a1300182c11000000000000000000282c11000100000000000000010000000000000010f4120012000000020505000000000097f612000c00000000000000302c11000900000000000000cc8d12000700000000000000301a13003c2c110000000000000000004c2c110002000000000000000000000000000000712411000e000000020505000000000097f612000c00000000000000f49912000e0000000000000060dc12000300000000000000301a13005c2c110000000000000000006c2c1100020000000000000001000000832d11004c000000301a130000000000cf2d110044000000132e110034000000472e110040000000872e11004e0000005665633c543a3a417574686f7269747949643e00420000000000000001000000590000004f2d11003400000041757468496e6465780000004200000000000000010000005b000000f32c11003c0000002f2d110020000000420000000000000001000000570000007c2c110045000000c12c11003200000020466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f662060543a3a56616c696461746f7249646020746f20746865206e756d626572206f6620626c6f636b7320617574686f7265642062792074686520676976656e20617574686f726974792e20466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206041757468496e6465786020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d6265722061667465722077686963682069742773206f6b20746f2073656e64206865617274626561747320696e2063757272656e742073657373696f6e2e2041742074686520626567696e6e696e67206f6620656163682073657373696f6e20776520736574207468697320746f20612076616c756520746861742073686f756c642066616c6c20726f7567686c7920696e20746865206d6964646c65206f66207468652073657373696f6e206475726174696f6e2e20546865206964656120697320746f206669727374207761697420666f72207468652076616c696461746f727320746f2070726f64756365206120626c6f636b20696e207468652063757272656e742073657373696f6e2c20736f20746861742074686520686561727462656174206c61746572206f6e2077696c6c206e6f74206265206e65636573736172792e00000000000000cc2311000300000000000000042f11000100000000000000000000001c2f11001200000000000000000000007232110003000000000000007532110012000000ac2f110016000000301a130000000000c22f1100560000001830110036000000301a1300000000004e301100510000009f30110011000000301a130000000000b030110036000000301a130000000000f5bd12000b000000e6301100340000001a31110068000000823111002d000000af3111002a000000d931110060000000393211003900000044be12000c00000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e202d20604f285429602077686572652060546020636f6d706c6578697479206f6620606f6e5f74696d657374616d705f73657460202d20312073746f72616765207265616420616e6420312073746f72616765206d75746174696f6e2028636f64656320604f28312960292e202862656361757365206f6620604469645570646174653a3a74616b656020696e20606f6e5f66696e616c697a656029202d2031206576656e742068616e646c657220606f6e5f74696d657374616d705f7365746020604f285429602e202d2042656e63686d61726b3a20382e35323320286d696e207371756172657320616e616c79736973292020202d204e4f54453a20546869732062656e63686d61726b2077617320646f6e6520666f7220612072756e74696d65207769746820696e7369676e69666963616e7420606f6e5f74696d657374616d705f736574602068616e646c6572732e20202020204e65772062656e63686d61726b696e67206973206e6565646564207768656e20616464696e67206e65772068616e646c6572732e6e6f77436f6d706163743c543a3a4d6f6d656e743e0000000000eb211100030000000000000000000000383311000900000000000000000000000000000000000000000000000000000000000000301a13004433110000000000000000005433110001000000000000000100000000000000daf71200090000000000000000000000a1f512000400000000000000000000000000000000000000000000000000000000000000301a13005c33110000000000000000006c331100010000000000000001000000543a3a4d6f6d656e740000004200000000000000010000006e000000a1331100240000004200000000000000010000005b000000743311002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e00000000000000003411000d00000000000000383311000900000000000000301a13001034110000000000000000002034110004000000000000004d696e696d756d506572696f6400000042000000000000000100000079000000403411005a0000009a3411005a000000f4341100590000004d3511001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e54696d657374616d7020746f6f2066617220696e2066757475726520746f2061636365707454696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b54696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b7300000000012211000a0000000000000044361100010000000000000000000000ee21110013000000000000004c36110001000000000000006a361100190000005436110016000000204475706c696361746564206865617274626561742e204e6f6e206578697374656e74207075626c6963206b65792e00000000000000000000000000617474656d707420746f20646976696465206279207a65726f0000004200000008000000040000007a00000071202f206365696c28712f246d617829203c20246d61782e204d6163726f2070726576656e747320616e792074797065206265696e672063726561746564207468617420646f6573206e6f74207361746973667920746869733b2071656400002c3711004200000064010000270000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f61726974686d657469632f7372632f7065725f7468696e67732e727300002c371100420000006b010000270000002c3711004200000076010000210000004661696c656420746f20636f6e76657274416d6f756e744c6f774578697374696e6756657374696e675363686564756c654e6f7456657374696e6776657374766573745f6f746865727665737465645f7472616e7366657200000000403811000e00000000000000841112000200000000000000000000005038110002000000000000000000000060381100100000000000000074ad120001000000000000000000000070381100010000000000000056657374696e67557064617465640000c338110056000000193911004600000056657374696e67436f6d706c65746564783811004b00000020416e206163636f756e742028676976656e2920686173206265636f6d652066756c6c79207665737465642e204e6f20667572746865722076657374696e672063616e2068617070656e2e2054686520616d6f756e742076657374656420686173206265656e20757064617465642e205468697320636f756c6420696e646963617465206d6f72652066756e64732061726520617661696c61626c652e205468652062616c616e636520676976656e2069732074686520616d6f756e74207768696368206973206c65667420756e7665737465642028616e642074687573206c6f636b6564292e5265706f72747344656665727265644f6666656e6365734e6f6e73656e7365496e7374616e744e6f74416c6c6f776564566f74657345786973744e6f7444656c65676174696e67496e73756666696369656e7446756e6473556e646572666c6f77416c726561647944656c65676174696e674e6f5065726d697373696f6e4e6f74566f7465724e6f7441637469766557726f6e674f70656e4e6f744f70656e4e6f74457870697265644e6f744c6f636b65644e6f6e6557616974696e67507265696d616765496e76616c69645265666572656e64756d496e76616c6964507265696d6167654d697373696e67496d6d696e656e744e6f74496d6d696e656e744475706c6963617465507265696d6167654e6f7444656c65676174656457726f6e6750726f7879416c72656164795665746f65644e6f50726f706f73616c496e76616c6964486173684e6f7453696d706c654d616a6f7269747950726f706f73616c426c61636b6c6973746564416c726561647943616e63656c6564426164496e6465784e6f7450726f787956616c75654c6f777365636f6e6470726f78795f766f7465656d657267656e63795f63616e63656c65787465726e616c5f70726f706f736565787465726e616c5f70726f706f73655f6d616a6f7269747965787465726e616c5f70726f706f73655f64656661756c74666173745f747261636b7665746f5f65787465726e616c63616e63656c5f7265666572656e64756d63616e63656c5f71756575656461637469766174655f70726f7879636c6f73655f70726f7879646561637469766174655f70726f787964656c6567617465756e64656c6567617465636c6561725f7075626c69635f70726f706f73616c736e6f74655f707265696d6167656e6f74655f696d6d696e656e745f707265696d616765726561705f707265696d616765756e6c6f636b6f70656e5f70726f787972656d6f76655f766f746572656d6f76655f6f746865725f766f746570726f78795f64656c656761746570726f78795f756e64656c656761746570726f78795f72656d6f76655f766f7465656e6163745f70726f706f73616c4465706f7369744f665265666572656e64756d496e666f4f66000000000054b112000800000000000000783f1100020000000000000000000000883f1100010000000000000000000000903f11000600000000000000983f1100030000000000000000000000b03f1100010000000000000000000000b83f11000e00000000000000301a1300000000000000000000000000c83f1100010000000000000000000000d03f11000700000000000000d83f1100020000000000000000000000e83f1100010000000000000000000000f03f11000600000000000000f83f110001000000000000000000000000401100010000000000000000000000084011000900000000000000f83f1100010000000000000000000000144011000100000000000000000000001c4011000900000000000000f83f110001000000000000000000000028401100010000000000000000000000f8b112000800000000000000304011000200000000000000000000004040110001000000000000000000000048401100090000000000000098ad1200020000000000000000000000544011000100000000000000000000005c4011000b0000000000000074ad1200010000000000000000000000684011000100000000000000000000007040110006000000000000007840110003000000000000000000000090401100010000000000000000000000984011000d00000000000000081a1200030000000000000000000000a8401100010000000000000000000000b04011000c00000000000000081a1200030000000000000000000000bc4011000100000000000000000000001c3a11000f00000000000000c4401100020000000000000000000000d44011000100000000000000000000003c3a11000f00000000000000c4401100020000000000000000000000dc401100010000000000000000000000e44011000e00000000000000f4401100040000000000000000000000144111000100000000000000000000001c411100080000000000000074ad12000100000000000000000000002441110001000000000000007b44110009000000f61512000700000084441100300000005461626c656400007b44110009000000f615120007000000a81412000e000000444411003700000045787465726e616c5461626c656400001e441100260000005374617274656400344211000f000000114411000d000000f9431100180000005061737365640000344211000f000000cd4311002c0000004e6f74506173736564000000a14311002c00000043616e63656c6c65640000008043110021000000344211000f000000a1f5120004000000634311001d00000044656c6567617465640000002b43110038000000556e64656c65676174656400f14211003a0000005665746f6564000020af12000900000089b2120004000000e64211000b000000c042110026000000507265696d6167654e6f7465640000008842110038000000507265696d61676555736564434211004500000089b2120004000000344211000f000000f141110043000000ae41110043000000507265696d616765526561706564000089b212000400000020af120009000000f61512000700000020af1200090000005741110057000000556e6c6f636b65642c4111002b00000020416e206163636f756e7420686173206265656e20756e6c6f636b6564207375636365737366756c6c792e2041207265676973746572656420707265696d616765207761732072656d6f76656420616e6420746865206465706f73697420636f6c6c6563746564206279207468652072656170657220286c617374206974656d292e20412070726f706f73616c20636f756c64206e6f7420626520657865637574656420626563617573652069747320707265696d61676520776173206d697373696e672e20412070726f706f73616c20636f756c64206e6f7420626520657865637574656420626563617573652069747320707265696d6167652077617320696e76616c69642e5265666572656e64756d496e64657820412070726f706f73616c20707265696d616765207761732072656d6f76656420616e6420757365642028746865206465706f736974207761732072657475726e6564292e20412070726f706f73616c277320707265696d61676520776173206e6f7465642c20616e6420746865206465706f7369742074616b656e2e20416e2065787465726e616c2070726f706f73616c20686173206265656e207665746f65642e426c6f636b4e756d62657220416e206163636f756e74206861732063616e63656c6c656420612070726576696f75732064656c65676174696f6e206f7065726174696f6e2e20416e206163636f756e74206861732064656c65676174656420746865697220766f746520746f20616e6f74686572206163636f756e742e20412070726f706f73616c20686173206265656e20656e61637465642e2041207265666572656e64756d20686173206265656e2063616e63656c6c65642e20412070726f706f73616c20686173206265656e2072656a6563746564206279207265666572656e64756d2e20412070726f706f73616c20686173206265656e20617070726f766564206279207265666572656e64756d2e2041207265666572656e64756d2068617320626567756e2e566f74655468726573686f6c6420416e2065787465726e616c2070726f706f73616c20686173206265656e207461626c65642e2041207075626c69632070726f706f73616c20686173206265656e207461626c656420666f72207265666572656e64756d20766f74652e50726f70496e6465782041206d6f74696f6e20686173206265656e2070726f706f7365642062792061207075626c6963206163636f756e742e4c6f6f6b757000000000000014451100090000000000000020451100010000000000000000000000301a13000000000000000000000000008ccb11000a0000000000000028451100030000000000000000000000301a130000000000000000005363686564756c6564000000e64211000b0000004045110018000000584511000f000000940d12000e0000005461736b416464726573733c426c6f636b4e756d6265723e4f7074696f6e3c5665633c75383e3e004200000004000000040000007b0000007c0000007d00000042000000000000000100000064000000420000000000000001000000460000004200000000000000010000006d00000073657269616c697a656420617267732073686f756c642062652070726f7669646564206279207468652072756e74696d653b0a090909636f72726563746c792073657269616c697a656420646174612073686f756c6420626520646573657269616c697a61626c653b0a0909097165648811130043000000ba000000100000004c4f474943204552524f523a2062616b655f7265666572656e64756d2f7363686564756c655f6e616d6564206661696c65644167656e64615ca412006a000000a7000000090000005ca412006a000000a700000035000000507265696d616765735075626c696350726f70734e65787445787465726e616c00000000cb3711000400000000000000301a13000000000000000000000000002c471100110000000000000000000000cf3711000a00000000000000b4471100010000000000000000000000cc471100130000000000000000000000d93711000f0000000000000064481100020000000000000000000000944811001200000000000000ec4d11002f000000301a1300000000001b4e110058000000364c11001a000000301a130000000000504c110035000000301a130000000000f5bd12000b000000184a11000a000000734e11001e000000914e11003f000000d04e110040000000004d11000d000000104f11003a0000004a4f110039000000814d11006b00000044be12000c00000000000000834b11000600000000000000f320120023000000b24b11002f000000301a13000000000098c9120034000000301a130000000000e14b110055000000364c11001a000000301a130000000000504c110035000000301a130000000000f5bd12000b000000184a11000a000000224a11001e000000854c11003d000000c24c11003e000000004d11000d0000000d4d11003b000000484d110039000000814d11006b00000044be12000c00000000000000834b11000600000000000000f32012002300000000000000a8d811000800000000000000894b110029000000244911001a000000301a13000000000098c9120034000000301a1300000000003e491100450000008349110040000000c34911003d000000301a130000000000004a110018000000301a130000000000f5bd12000b000000184a11000a000000224a11001e000000404a11004f0000008f4a110050000000df4a110038000000174b11006c00000044be12000c00000020437265617465206120766573746564207472616e736665722e202d2060746172676574603a20546865206163636f756e7420746861742073686f756c64206265207472616e7366657272656420746865207665737465642066756e64732e202d2060616d6f756e74603a2054686520616d6f756e74206f662066756e647320746f207472616e7366657220616e642077696c6c206265207665737465642e202d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e20456d697473206056657374696e6743726561746564602e202d20604f283129602e202d2044625765696768743a20332052656164732c20332057726974657320202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e742c205b53656e646572204163636f756e745d20202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e742c205b53656e646572204163636f756e745d202d2042656e63686d61726b3a203131312e34202b202e333435202a206c20c2b57320286d696e2073717561726520616e616c7973697329202d205573696e672031313520c2b5732066697865642e20417373756d696e67206c657373207468616e203530206c6f636b73206f6e20616e7920757365722c20656c7365207765206d61792077616e7420666163746f7220696e206e756d626572206f66206c6f636b732e74617267657456657374696e67496e666f3c42616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265723e20556e6c6f636b20616e79207665737465642066756e6473206f662061206074617267657460206163636f756e742e202d2060746172676574603a20546865206163636f756e742077686f7365207665737465642066756e64732073686f756c6420626520756e6c6f636b65642e204d75737420686176652066756e6473207374696c6c206c6f636b656420756e6465722074686973206d6f64756c652e20456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e20202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e7420202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e74202d2042656e63686d61726b3a20202020202d20556e6c6f636b65643a2035382e3039202b202e313034202a206c20c2b57320286d696e2073717561726520616e616c797369732920202020202d204c6f636b65643a2035352e3335202b202e323535202a206c20c2b57320286d696e2073717561726520616e616c7973697329202d205573696e6720363020c2b5732066697865642e20417373756d696e67206c657373207468616e203530206c6f636b73206f6e20616e7920757365722c20656c7365207765206d61792077616e7420666163746f7220696e206e756d626572206f66206c6f636b732e20556e6c6f636b20616e79207665737465642066756e6473206f66207468652073656e646572206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e6473207374696c6c202d2044625765696768743a20322052656164732c20322057726974657320202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c205b53656e646572204163636f756e745d20202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c205b53656e646572204163636f756e745d20202020202d20556e6c6f636b65643a2035362e31202b202e303938202a206c20c2b57320286d696e2073717561726520616e616c797369732920202020202d204c6f636b65643a2035342e3337202b202e323534202a206c20c2b57320286d696e2073717561726520616e616c7973697329000000000002bf11000700000001020000000000007ac312000c00000000000000894b11002900000000000000000000000000000000000000301a1300dc4f11000000000000000000ec4f11000100000000000000000000004200000000000000010000005b000000f44f11003600000020496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e000000000000645011001100000000000000b66c12000c00000000000000301a1300549a110000000000000000007850110001000000000000004d696e5665737465645472616e73666572000000805011004700000020546865206d696e696d756d20616d6f756e7420746f206265207472616e7366657272656420746f206372656174652061206e65772076657374696e67207363686564756c652e00000000005f391100070000000105000000000000285211000d00000000000000355211003400000000000000000000000000000000000000301a13008891110000000000000000006c5211000100000000000000000000000000000066391100100000000000000000000000745211001900000000000000000000000000000000000000000000000000000000000000301a1300905211000000000000000000a052110002000000000000000100000000000000b05211001600000002050500000000008ff51200040000000000000093f512000e00000000000000c65211001200000000000000301a1300d85211000000000000000000e8521100010000000000000001000000000000002af412001200000001050000000000008ff512000400000000000000cc8d12000700000000000000000000000000000000000000301a1300f05211000000000000000000005311000600000000000000010000005265706f727449644f663c543e4f6666656e636544657461696c733c543a3a4163636f756e7449642c20543a3a4964656e74696669636174696f6e5475706c653e00000003551100520000005665633c44656665727265644f6666656e63654f663c543e3e000000420000000000000001000000590000009954110059000000f254110011000000436f6e63757272656e745265706f727473496e6465785665633c5265706f727449644f663c543e3e420000000000000001000000590000004f5411004a000000420000000000000001000000590000003053110044000000301a130000000000745311002f000000301a130000000000a353110052000000f55311005a00000020456e756d65726174657320616c6c207265706f727473206f662061206b696e6420616c6f6e672077697468207468652074696d6520746865792068617070656e65642e20416c6c207265706f7274732061726520736f72746564206279207468652074696d65206f66206f6666656e63652e204e6f74652074686174207468652061637475616c2074797065206f662074686973206d617070696e6720697320605665633c75383e602c207468697320697320626563617573652076616c756573206f6620646966666572656e7420747970657320617265206e6f7420737570706f7274656420617420746865206d6f6d656e7420736f2077652061726520646f696e6720746865206d616e75616c2073657269616c697a6174696f6e2e204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e204465666572726564207265706f72747320746861742068617665206265656e2072656a656374656420627920746865206f6666656e63652068616e646c657220616e64206e65656420746f206265207375626d69747465642061742061206c617465722074696d652e20546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e000000000000000db012000700000000000000545a1100020000000000000000000000845a11000f0000000000000000000000f23a11000600000000000000fc5a1100010000000000000000000000145b11000c000000000000000000000014b012000400000000000000745b1100020000000000000000000000a45b11000d0000000000000000000000f83a11000a00000000000000745b11000200000000000000000000000c5c11000c0000000000000000000000023b110010000000000000006c5c1100010000000000000000000000845c11000a0000000000000000000000123b11001000000000000000d45c1100010000000000000000000000ec5c11000b0000000000000000000000223b11001900000000000000d45c1100010000000000000000000000445d11000e00000000000000000000003b3b11001800000000000000d45c1100010000000000000000000000b45d11000e0000000000000000000000533b11000a00000000000000245e11000300000000000000000000006c5e11001300000000000000000000005d3b11000d00000000000000d45c1100010000000000000000000000045f11000f00000000000000000000006a3b110011000000000000007c5f1100010000000000000000000000945f11000900000000000000000000007b3b11000d00000000000000dc5f1100010000000000000000000000f45f11000a0000000000000000000000883b11000e00000000000000446011000100000000000000000000005c6011000b0000000000000000000000963b11000b00000000000000301a1300000000000000000000000000b4601100090000000000000000000000a13b1100100000000000000044601100010000000000000000000000fc6011000d0000000000000000000000b13b1100080000000000000064611100030000000000000000000000ac611100140000000000000000000000b93b11000a00000000000000301a13000000000000000000000000004c6211000d0000000000000000000000c33b11001600000000000000301a1300000000000000000000000000b4621100080000000000000000000000d93b11000d00000000000000f46211000100000000000000000000000c6311000d0000000000000000000000e63b11001600000000000000f4621100010000000000000000000000746311000c0000000000000000000000fc3b11000d00000000000000d45c1100010000000000000000000000d46311000f0000000000000000000000093c110006000000000000004c641100010000000000000000000000646411000900000000000000000000000f3c11000a000000000000004c641100010000000000000000000000ac6411000d0000000000000000000000193c11000b00000000000000146511000100000000000000000000002c6511001c0000000000000000000000243c110011000000000000000c6611000200000000000000000000003c661100100000000000000000000000353c11000e0000000000000064611100030000000000000000000000bc661100170000000000000000000000433c11001000000000000000301a1300000000000000000000000000746711000d0000000000000000000000533c1100110000000000000014651100010000000000000000000000dc6711000d0000000000000000000000643c11000e000000000000004468110002000000000000000000000074681100010000000000000000000000d06811000d0000000000000091d912000700000000000000aa4d1200050000000000000080751200150000001089110028000000301a13000000000038891100460000007e89110021000000301a1300000000009f89110036000000d589110046000000301a1300000000001b8a110012000000301a130000000000f5bd12000b0000002d8a110009000000368a1100360000006c8a11002000000044be12000c0000000000000089d912000800000000000000fe88110012000000c88711002e000000301a130000000000f6871100410000003788110045000000301a1300000000007c88110033000000301a130000000000f5bd12000b000000af8811000a000000b988110035000000ee8811001000000044be12000c000000000000004f7e11000900000000000000587e1100180000000000000014b012000400000000000000af87110019000000b88611004d000000058711002f000000301a130000000000f370110033000000301a13000000000034871100380000007786110022000000301a130000000000f5bd12000b0000006c8711000a0000007687110039000000998611001f00000044be12000c000000a885110054000000fc8511003d000000301a130000000000f370110033000000301a130000000000398611003e0000007786110022000000301a130000000000f5bd12000b000000184a11000a000000998611001f00000044be12000c000000000000004f7e11000900000000000000344211000f000000e084110054000000998411000c000000301a130000000000348511003f000000301a1300000000007385110035000000301a130000000000f5bd12000b000000184a11000a00000044be12000c00000000000000d06811000d0000000000000091d91200070000004d8411004c000000998411000c000000301a130000000000a58411003b000000301a130000000000f382110036000000301a130000000000f5bd12000b000000184a11000a000000732112001100000044be12000c000000a383110056000000f983110018000000301a130000000000118411003c000000301a130000000000f382110036000000301a13000000000029831100530000007c83110027000000301a130000000000f5bd12000b000000184a11000a000000732112001100000044be12000c00000045821100520000009782110021000000301a130000000000b88211003b000000301a130000000000f382110036000000301a13000000000029831100530000007c83110027000000301a130000000000f5bd12000b000000184a11000a000000732112001100000044be12000c00000000000000d06811000d0000000000000091d912000700000000000000338211000d0000000000000006cf12000e0000000000000040821100050000000000000006cf12000e000000c57f1100540000001980110059000000728011003b000000301a130000000000ad80110035000000301a130000000000e28011003e000000208111005800000078811100260000009e81110055000000f38111002f000000301a1300000000002282110011000000301a130000000000f5bd12000b000000db7711001000000073211200110000000d7611001600000044be12000c000000707e11002f000000301a1300000000009f7e110037000000301a130000000000d67e11004c000000301a130000000000227f110010000000301a130000000000f5bd12000b000000327f110012000000db77110010000000447f110042000000867f110011000000977f11002e00000044be12000c000000000000004f7e11000900000000000000587e110018000000047e110015000000301a130000000000217a110031000000301a130000000000197e110036000000301a130000000000f5bd12000b000000184a11000a00000044be12000c00000000000000ff7d11000500000000000000344211000f000000727d110028000000301a130000000000217a110031000000301a1300000000009a7d110032000000301a130000000000f5bd12000b0000007321120011000000cc7d11003300000044be12000c000000000000006d7d110005000000000000007ac312000c000000cf7c110041000000301a130000000000107d110025000000301a130000000000f370110033000000301a130000000000357d110038000000301a130000000000f5bd12000b0000000d7611001600000044be12000c000000817c110026000000301a130000000000a77c110028000000301a130000000000f370110033000000301a130000000000f5bd12000b000000db7711001000000044be12000c000000b27b11004b000000301a130000000000fd7b110022000000301a1300000000001f7c110028000000301a130000000000f370110033000000301a130000000000477c11003a000000301a130000000000f5bd12000b000000db7711001000000044be12000c00000000000000957b110002000000000000007ac312000c00000000000000977b11000a00000000000000a17b11000a00000000000000ab7b11000700000000000000b66c12000c000000ee7a11004f000000301a1300000000000a6c110056000000606c110033000000301a1300000000003d7b110058000000886d11001e000000a66d110057000000fd6d110026000000301a130000000000236e110052000000756e110056000000cb6e1100510000001c6f110055000000716f110032000000301a130000000000a36f110013000000301a130000000000f5bd12000b00000044be12000c000000527a110034000000301a130000000000dc6a110058000000346b110038000000301a130000000000867a110052000000d87a110016000000301a130000000000a86b110015000000301a130000000000f5bd12000b000000852012000800000044be12000c000000047a11001d000000301a130000000000217a110031000000301a130000000000f5bd12000b000000184a11000a000000db7711001000000044be12000c00000000000000f47911001000000000000000cc8d120007000000fe781100580000005679110049000000301a130000000000f370110033000000301a1300000000006978110032000000301a1300000000009b78110017000000301a130000000000f5bd12000b0000009f79110041000000e07911001400000044be12000c000000eb771100510000003c7811002d000000301a130000000000f370110033000000301a1300000000006978110032000000301a1300000000009b78110017000000301a130000000000f5bd12000b000000b27811004c00000044be12000c0000007b7611003d000000301a130000000000f370110033000000301a130000000000b876110034000000301a130000000000ec761100540000004077110057000000977711002c000000301a130000000000c377110018000000301a130000000000f5bd12000b000000db7711001000000044be12000c00000000000000834b110006000000000000007ac312000c0000002376110029000000301a130000000000f370110033000000301a1300000000004c7611002f000000301a130000000000f5bd12000b000000184a11000a00000044be12000c0000003075110010000000301a1300000000004075110037000000301a1300000000007775110019000000301a130000000000907511003b000000301a130000000000cb75110042000000301a130000000000f5bd12000b0000000d7611001600000044be12000c0000000000000098d912000500000000000000344211000f000000b66f110020000000301a13000000000090711100040000009471110023000000b771110020000000d771110025000000fc711100400000003c7211003600000072721100220000009472110058000000ec72110017000000301a130000000000037311002b0000002e7311003c0000006a73110038000000a273110030000000d2731100570000002974110057000000807411003a000000301a130000000000ba741100530000000d75110023000000301a1300000000001c6a11003e000000301a130000000000f5bd12000b0000005a6a11005000000044be12000c00000000000000834b110006000000000000007ac312000c0000000000000098d912000500000000000000344211000f000000b66f110020000000301a130000000000d66f1100540000002a7011004c0000007670110056000000cc70110027000000301a130000000000f370110033000000301a13000000000026711100540000007a711100160000001c6a11003e000000301a130000000000f5bd12000b0000005a6a11005000000044be12000c000000bd6b11004d000000301a1300000000000a6c110056000000606c110033000000301a130000000000936c110055000000e86c11002c000000301a130000000000146d1100580000006c6d11001c000000886d11001e000000a66d110057000000fd6d110026000000236e110052000000756e110056000000cb6e1100510000001c6f110055000000716f110032000000301a130000000000a36f110013000000301a130000000000f5bd12000b00000044be12000c000000aa6a110032000000301a130000000000dc6a110058000000346b110038000000301a13000000000070691100540000006c6b11003c000000301a130000000000a86b110015000000301a130000000000f5bd12000b000000852012000800000044be12000c000000dd68110028000000301a13000000000005691100540000005969110017000000301a1300000000007069110054000000c469110058000000301a1300000000001c6a11003e000000301a130000000000f5bd12000b0000005a6a11005000000044be12000c00000000000000d06811000d0000000000000091d91200070000000000000098d912000500000000000000344211000f0000007c6811005400000020456e61637420612070726f706f73616c2066726f6d2061207265666572656e64756d2e20466f72206e6f77207765206a757374206d616b65207468652077656967687420626520746865206d6178696d756d2e70726f706f73616c5f686173682052656d6f766520612070726f7869656420766f746520666f722061207265666572656e64756d2e2045786163746c79206571756976616c656e7420746f206072656d6f76655f766f746560206578636570742074686174206974206f70657261746573206f6e20746865206163636f756e742074686174207468652073656e64657220697320612070726f787920666f722e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d75737420626520612070726f787920666f7220736f6d65206f74686572206163636f756e74207768696368206861732061207265676973746572656420766f746520666f7220746865207265666572656e64756d206f662060696e646578602e202d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e202d20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2e20556e64656c65676174652074686520766f74696e6720706f776572206f6620612070726f78696564206163636f756e742e20546f6b656e73206d617920626520756e6c6f636b656420666f6c6c6f77696e67206f6e636520616e20616d6f756e74206f662074696d6520636f6e73697374656e74207769746820746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e2077697468207768696368207468652064656c65676174696f6e20776173206973737565642e2070726f787920666f7220736f6d65206f74686572206163636f756e742077686963682069732063757272656e746c792064656c65676174696e672e20456d6974732060556e64656c656761746564602e2044656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f6620612070726f78696564206163636f756e742e205468652062616c616e63652064656c656761746564206973206c6f636b656420666f72206173206c6f6e6720617320697427732064656c6567617465642c20616e64207468657265616674657220666f72207468652074696d6520617070726f70726961746520666f722074686520636f6e76696374696f6e2773206c6f636b20706572696f642e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d7573742068617665206265656e20736574206173207468652070726f7879206163636f756e7420666f722060746172676574602e202d2060746172676574603a20546865206163636f756e742077686f6c6520766f74696e6720706f776572207368616c6c2062652064656c65676174656420616e642077686f73652062616c616e6365206c6f636b65642e20202054686973206163636f756e74206d757374206569746865723a2020202d2062652064656c65676174696e6720616c72656164793b206f722020202d2068617665206e6f20766f74696e67206163746976697479202869662074686572652069732c207468656e2069742077696c6c206e65656420746f2062652072656d6f7665642f636f6e736f6c69646174656420202020207468726f7567682060726561705f766f746560206f722060756e766f746560292e202d2060746f603a20546865206163636f756e742077686f736520766f74696e6720746865206074617267657460206163636f756e74277320766f74696e6720706f7765722077696c6c20666f6c6c6f772e202d2060636f6e76696374696f6e603a2054686520636f6e76696374696f6e20746861742077696c6c20626520617474616368656420746f207468652064656c65676174656420766f7465732e205768656e207468652020206163636f756e7420697320756e64656c6567617465642c207468652066756e64732077696c6c206265206c6f636b656420666f722074686520636f72726573706f6e64696e6720706572696f642e202d206062616c616e6365603a2054686520616d6f756e74206f6620746865206163636f756e7427732062616c616e636520746f206265207573656420696e2064656c65676174696e672e2054686973206d7573742020206e6f74206265206d6f7265207468616e20746865206163636f756e7427732063757272656e742062616c616e63652e20456d697473206044656c656761746564602e2052656d6f7665206120766f746520666f722061207265666572656e64756d2e2049662074686520607461726765746020697320657175616c20746f20746865207369676e65722c207468656e20746869732066756e6374696f6e2069732065786163746c79206571756976616c656e7420746f206072656d6f76655f766f7465602e204966206e6f7420657175616c20746f20746865207369676e65722c207468656e2074686520766f7465206d757374206861766520657870697265642c20656974686572206265636175736520746865207265666572656e64756d207761732063616e63656c6c65642c20626563617573652074686520766f746572206c6f737420746865207265666572656e64756d206f7220626563617573652074686520636f6e76696374696f6e20706572696f64206973206f7665722e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e202d2060746172676574603a20546865206163636f756e74206f662074686520766f746520746f2062652072656d6f7665643b2074686973206163636f756e74206d757374206861766520766f74656420666f722020207265666572656e64756d2060696e646578602e2049663a202d20746865207265666572656e64756d207761732063616e63656c6c65642c206f72202d20746865207265666572656e64756d206973206f6e676f696e672c206f72202d20746865207265666572656e64756d2068617320656e646564207375636820746861742020202d2074686520766f7465206f6620746865206163636f756e742077617320696e206f70706f736974696f6e20746f2074686520726573756c743b206f722020202d20746865726520776173206e6f20636f6e76696374696f6e20746f20746865206163636f756e74277320766f74653b206f722020202d20746865206163636f756e74206d61646520612073706c697420766f7465202e2e2e7468656e2074686520766f74652069732072656d6f76656420636c65616e6c7920616e64206120666f6c6c6f77696e672063616c6c20746f2060756e6c6f636b60206d617920726573756c7420696e206d6f72652066756e6473206265696e6720617661696c61626c652e2049662c20686f77657665722c20746865207265666572656e64756d2068617320656e64656420616e643a202d2069742066696e697368656420636f72726573706f6e64696e6720746f2074686520766f7465206f6620746865206163636f756e742c20616e64202d20746865206163636f756e74206d6164652061207374616e6461726420766f7465207769746820636f6e76696374696f6e2c20616e64202d20746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e206973206e6f74206f766572202e2e2e7468656e20746865206c6f636b2077696c6c206265206167677265676174656420696e746f20746865206f766572616c6c206163636f756e742773206c6f636b2c207768696368206d617920696e766f6c7665202a6f7665726c6f636b696e672a20287768657265207468652074776f206c6f636b732061726520636f6d62696e656420696e746f20612073696e676c65206c6f636b207468617420697320746865206d6178696d756d206f6620626f74682074686520616d6f756e74206c6f636b656420616e64207468652074696d65206973206974206c6f636b656420666f72292e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e6572206d7573742068617665206120766f7465207265676973746572656420666f72207265666572656e64756d2060696e646578602e204265636f6d6520612070726f78792e2054686973206d7573742062652063616c6c6564207072696f7220746f2061206c61746572206061637469766174655f70726f7879602e204f726967696e206d7573742062652061205369676e65642e202d2060746172676574603a20546865206163636f756e742077686f736520766f7465732077696c6c206c617465722062652070726f786965642e2060636c6f73655f70726f787960206d7573742062652063616c6c6564206265666f726520746865206163636f756e742063616e2062652064657374726f7965642e202d204f6e6520657874726120444220656e7472792e20556e6c6f636b20746f6b656e732074686174206861766520616e2065787069726564206c6f636b2e202d2060746172676574603a20546865206163636f756e7420746f2072656d6f766520746865206c6f636b206f6e2e2052656d6f766520616e20657870697265642070726f706f73616c20707265696d61676520616e6420636f6c6c65637420746865206465706f7369742e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f6620612070726f706f73616c2e20546869732077696c6c206f6e6c7920776f726b2061667465722060566f74696e67506572696f646020626c6f636b732066726f6d207468652074696d6520746861742074686520707265696d61676520776173206e6f7465642c2069662069742773207468652073616d65206163636f756e7420646f696e672069742e2049662069742773206120646966666572656e74206163636f756e742c207468656e206974276c6c206f6e6c7920776f726b20616e206164646974696f6e616c2060456e6163746d656e74506572696f6460206c617465722e20456d6974732060507265696d616765526561706564602e202d204f6e6520444220636c6561722e2052656769737465722074686520707265696d61676520666f7220616e207570636f6d696e672070726f706f73616c2e2054686973207265717569726573207468652070726f706f73616c20746f20626520696e207468652064697370617463682071756575652e204e6f206465706f736974206973206e65656465642e202d2060656e636f6465645f70726f706f73616c603a2054686520707265696d616765206f6620612070726f706f73616c2e20456d6974732060507265696d6167654e6f746564602e202d20446570656e64656e74206f6e207468652073697a65206f662060656e636f6465645f70726f706f73616c6020616e64206c656e677468206f662064697370617463682071756575652e2052656769737465722074686520707265696d61676520666f7220616e207570636f6d696e672070726f706f73616c2e205468697320646f65736e27742072657175697265207468652070726f706f73616c20746f20626520696e207468652064697370617463682071756575652062757420646f657320726571756972652061206465706f7369742c2072657475726e6564206f6e636520656e61637465642e202d20446570656e64656e74206f6e207468652073697a65206f662060656e636f6465645f70726f706f73616c60206275742070726f74656374656420627920612020207265717569726564206465706f7369742e656e636f6465645f70726f706f73616c20436c6561727320616c6c207075626c69632070726f706f73616c732e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e20556e64656c65676174652074686520766f74696e6720706f776572206f66207468652073656e64696e67206163636f756e742e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062652063757272656e746c792064656c65676174696e672e2044656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f66207468652073656e64696e67206163636f756e742e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d757374206569746865723a746f636f6e76696374696f6e436f6e76696374696f6e62616c616e63652044656163746976617465207468652070726f78792c20627574206c65617665206f70656e20746f2074686973206163636f756e742e2043616c6c6564206279207468652073746173682e205468652070726f7879206d75737420616c7265616479206265206163746976652e204e4f54453a205573656420746f2062652063616c6c6564206072656d6f76655f70726f7879602e202d206070726f7879603a20546865206163636f756e7420746861742077696c6c2062652064656163746976617465642061732070726f78792e20436c656172207468652070726f78792e2043616c6c6564206279207468652070726f78792e204e4f54453a205573656420746f2062652063616c6c6564206072657369676e5f70726f7879602e205370656369667920612070726f7879207468617420697320616c7265616479206f70656e20746f2075732e2043616c6c6564206279207468652073746173682e204e4f54453a205573656420746f2062652063616c6c656420607365745f70726f7879602e202d206070726f7879603a20546865206163636f756e7420746861742077696c6c206265206163746976617465642061732070726f78792e70726f78792043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e202d20607768696368603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e202d204f286429207768657265206420697320746865206974656d7320696e207468652064697370617463682071756575652e77686963682052656d6f76652061207265666572656e64756d2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e7265665f696e646578436f6d706163743c5265666572656e64756d496e6465783e205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520605665746f4f726967696e602e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c20746f207665746f20616e6420626c61636b6c6973742e20456d69747320605665746f6564602e202d2054776f20444220656e74726965732e202d20506572666f726d7320612062696e61727920736561726368206f6e20606578697374696e675f7665746f657273602077686963682073686f756c64206e6f7420202062652076657279206c617267652e202d204f286c6f672076292c2076206973206e756d626572206f6620606578697374696e675f7665746f65727360205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e20546865206469737061746368206f6620746869732063616c6c206d757374206265206046617374547261636b4f726967696e602e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e20496e6372656173656420746f2020206046617374547261636b566f74696e67506572696f646020696620746f6f206c6f772e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e205468697320646f65736e277420686176652061206d696e696d756d20616d6f756e742e20456d697473206053746172746564602e766f74696e675f706572696f6464656c6179205363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c44656661756c744f726967696e602e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e20556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061207072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c4d616a6f726974794f726967696e602e205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206045787465726e616c4f726967696e602e205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d6520546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c6c6174696f6e4f726967696e602e202d607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e20566f746520696e2061207265666572656e64756d206f6e20626568616c66206f6620612073746173682e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2070726f787920766f746520666f722e202d2060766f7465603a2054686520766f746520636f6e66696775726174696f6e2e202d204f6e65204442206368616e67652c206f6e6520444220656e7472792e20566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f20766f746520666f722e202d20604f285229602e202d205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722068617320766f746564206f6e2e4163636f756e74566f74653c42616c616e63654f663c543e3e205369676e616c732061677265656d656e742077697468206120706172746963756c61722070726f706f73616c2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e647320746f20636f76657220746865206465706f7369742c20657175616c20746f20746865206f726967696e616c206465706f7369742e202d206070726f706f73616c603a2054686520696e646578206f66207468652070726f706f73616c20746f207365636f6e642e202d20604f285329602e202d205320697320746865206e756d626572206f66207365636f6e647320612070726f706f73616c20616c7265616479206861732e202d204f6e6520444220656e7472792e436f6d706163743c50726f70496e6465783e2050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e647320746f20636f76657220746865206465706f7369742e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20707265696d6167652e202d206076616c7565603a2054686520616d6f756e74206f66206465706f73697420286d757374206265206174206c6561737420604d696e696d756d4465706f73697460292e20456d697473206050726f706f736564602e202d20604f28502960202d205020697320746865206e756d6265722070726f706f73616c7320696e2074686520605075626c696350726f707360207665632e202d2054776f204442206368616e6765732c206f6e6520444220656e7472792e00000000bbf112000f00000000000000000000007b4411000900000000000000000000000000000000000000000000000000000000000000301a13003490110000000000000000005c8f110001000000000000000100000000000000914611000b0000000000000000000000648f11002700000000000000000000000000000000000000000000000000000000000000301a13008c8f110000000000000000009c8f110001000000000000000100000000000000723c11000900000001050000000000007b4411000900000000000000a48f11002100000000000000000000000000000000000000301a1300c88f11000000000000000000d88f1100010000000000000000000000000000008846110009000000010600000000000091d912000700000000000000e08f11003a00000000000000000000000000000000000000301a13008891110000000000000000001c90110002000000000000000000000000000000caf112000f0000000000000000000000344211000f00000000000000000000000000000000000000000000000000000000000000301a13003490110000000000000000002c90110001000000000000000100000000000000e2f112000d0000000000000000000000344211000f00000000000000000000000000000000000000000000000000000000000000301a130034901100000000000000000044901100020000000000000001000000000000007b3c1100100000000105000000000000344211000f00000000000000549011003500000000000000000000000000000000000000301a13008c90110000000000000000009c90110001000000000000000000000000000000a49011000800000001050000000000007ac312000c00000000000000ac9011003200000000000000000000000000000000000000301a1300e09011000000000000000000f09011000200000000000000010000000000000064d312000500000001050000000000007ac312000c00000000000000009111001800000000000000000000000000000000000000301a13001891110000000000000000002891110002000000000000000000000000000000389111000500000001050000000000007ac312000c0000000000000006cf12000e00000000000000000000000000000000000000301a13004091110000000000000000005091110002000000000000000000000000000000eff11200150000000000000000000000a1f512000400000000000000000000000000000000000000000000000000000000000000301a130014921100000000000000000060911100020000000000000001000000000000009c4611000c0000000000000000000000709111001800000000000000000000000000000000000000000000000000000000000000301a13008891110000000000000000009891110004000000000000000000000000000000b891110009000000010600000000000091d912000700000000000000c19111002300000000000000000000000000000000000000301a1300e49111000000000000000000f491110002000000000000000000000000000000049211000d000000010600000000000091d912000700000000000000a1f512000400000000000000000000000000000000000000301a1300149211000000000000000000249211000100000000000000010000000c9811003d0000005665633c2850726f70496e6465782c20543a3a486173682c20543a3a4163636f756e744964293e0042000000000000000100000059000000c4971100480000002842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e290000004200000000000000010000007e000000a397110021000000507265696d6167655374617475733c543a3a4163636f756e7449642c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265723e000012971100580000006a97110039000000c69611004c0000004200000000000000010000005700000046961100490000008f961100370000005265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a486173682c2042616c616e63654f663c543e3e0000004200000000000000010000005b000000199611002d000000566f74696e674f66566f74696e673c42616c616e63654f663c543e2c20543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265723e00004200000000000000010000007f0000006b95110057000000c29511005700000050726f787953746174653c543a3a4163636f756e7449643e4200000000000000010000005b000000fd9411004c00000049951100220000004c6f636b730000004200000000000000010000005b0000005294110057000000a994110054000000f293110056000000489411000a00000028543a3a486173682c20566f74655468726573686f6c64294200000000000000010000005b00000004931100560000005a93110055000000af93110029000000d89311001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e294200000000000000010000007e0000007692110054000000ca9211003a00000043616e63656c6c6174696f6e730000004200000000000000010000005b0000002c9211004a000000205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e204163636f756e747320666f7220776869636820746865726520617265206c6f636b7320696e20616374696f6e207768696368206d61792062652072656d6f76656420617420736f6d6520706f696e7420696e20746865206675747572652e205468652076616c75652069732074686520626c6f636b206e756d62657220617420776869636820746865206c6f636b206578706972657320616e64206d61792062652072656d6f7665642e2057686f2069732061626c6520746f20766f746520666f722077686f6d2e2056616c7565206973207468652066756e642d686f6c64696e67206163636f756e742c206b65792069732074686520766f74652d7472616e73616374696f6e2d73656e64696e67206163636f756e742e20416c6c20766f74657320666f72206120706172746963756c617220766f7465722e2057652073746f7265207468652062616c616e636520666f7220746865206e756d626572206f6620766f74657320746861742077652068617665207265636f726465642e20546865207365636f6e64206974656d2069732074686520746f74616c20616d6f756e74206f662064656c65676174696f6e732c20746861742077696c6c2062652061646465642e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e20546865206c6f77657374207265666572656e64756d20696e64657820726570726573656e74696e6720616e20756e62616b6564207265666572656e64756d2e20457175616c20746f20605265666572656e64756d436f756e74602069662074686572652069736e2774206120756e62616b6564207265666572656e64756d2e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e204d6170206f662068617368657320746f207468652070726f706f73616c20707265696d6167652c20616c6f6e6720776974682077686f207265676973746572656420697420616e64207468656972206465706f7369742e2054686520626c6f636b206e756d6265722069732074686520626c6f636b20617420776869636820697420776173206465706f73697465642e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865207365636f6e64206974656d206973207468652070726f706f73616c277320686173682e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e00000000000000d49911000f0000000000000006cf12000e00000000000000301a1300e49911000000000000000000f49911000500000000000000000000001c9a11000c0000000000000006cf12000e00000000000000301a1300ac9a11000000000000000000289a1100010000000000000000000000309a11000c0000000000000006cf12000e00000000000000301a1300ac9a110000000000000000003c9a1100010000000000000000000000449a11000e00000000000000b66c12000c00000000000000301a1300549a11000000000000000000649a11000100000000000000000000006c9a1100150000000000000006cf12000e00000000000000301a1300849a11000000000000000000949a11000100000000000000000000009c9a11000d0000000000000006cf12000e00000000000000301a1300ac9a11000000000000000000bc9a1100010000000000000000000000c49a11001300000000000000b66c12000c00000000000000301a1300d89a11000000000000000000e89a11000100000000000000456e6163746d656e74506572696f640042000000000000000100000080000000819c11005c000000301a130000000000dd9c11004c000000299d11005a000000839d1100270000004c61756e6368506572696f64489c110039000000566f74696e67506572696f641a9c11002e0000004d696e696d756d4465706f736974000042000000000000000100000081000000cd9b11004d00000046617374547261636b566f74696e67506572696f6400000042000000000000000100000082000000929b11003b000000436f6f6c6f6666506572696f64000000420000000000000001000000830000003a9b110058000000507265696d616765427974654465706f7369740042000000000000000100000084000000f09a11004a0000002054686520616d6f756e74206f662062616c616e63652074686174206d757374206265206465706f7369746564207065722062797465206f6620707265696d6167652073746f7265642e20506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e0000000000006246110006000000010500000000000006cf12000e000000000000005c9e11003a00000000000000000000000000000000000000301a1300989e11000000000000000000a89e110001000000000000000100000000000000b4441100060000000105000000000000cc8d12000700000000000000b09e11001b00000000000000000000000000000000000000301a1300cc9e11000000000000000000dc9e11000100000000000000000000005665633c4f7074696f6e3c5363686564756c65643c3c542061732054726169743e3a3a43616c6c2c20543a3a426c6f636b4e756d6265723e3e3e000042000000000000000100000059000000249f1100530000005461736b416464726573733c543a3a426c6f636b4e756d6265723e0042000000000000000100000085000000e49e110040000000204c6f6f6b75702066726f6d206964656e7469747920746f2074686520626c6f636b206e756d62657220616e6420696e646578206f6620746865207461736b2e204974656d7320746f2062652065786563757465642c20696e64657865642062792074686520626c6f636b206e756d626572207468617420746865792073686f756c64206265206578656375746564206f6e2e00696d2d6f6e6c696e653a6f66666c696e7573657220646f6573206e6f74206861766520616e206578697374696e672076657374696e67207363686564756c653b20712e652e642e00420000000c0000000400000086000000e09f110033000000080100000d0000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f76657374696e672f7372632f6c69622e72730034a0110035000000730500002d00000034a01100350000007a050000400000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f64656d6f63726163792f7372632f6c69622e727300000034a0110035000000460500002d00000072616e206f7574206f662067617320647572696e6720636f6e747261637420657865637574696f6e72657475726e2074797065206572726f7276616c69646174696f6e206572726f72636f6e7472616374207472617070656420647572696e6720657865637574696f6e707265636f6e646974696f6e3a20616c6c20696d706f7274732073686f756c6420626520636865636b656420616761696e737420746865207369676e617475726573206f6620636f72726573706f6e64696e670a09090909090966756e6374696f6e7320646566696e65642062792060646566696e655f656e762160206d6163726f206279207468652075736572206f6620746865206d6163726f3b0a0909090909097369676e617475726573206f662074686573652066756e6374696f6e7320646566696e6564206279206024706172616d73603b0a09090909090963616c6c7320616c77617973206d616465207769746820617267756d656e7473207479706573206f662077686963682061726520646566696e65642062792074686520636f72726573706f6e64696e6720696d706f7274733b0a09090909090974687573207479706573206f6620617267756d656e74732073686f756c6420626520657175616c20746f2074797065206c69737420696e206024706172616d736020616e640a0909090909096c656e677468206f6620617267756d656e74206c69737420616e642024706172616d732073686f756c6420626520657175616c3b0a0909090909097468757320746869732063616e206e6576657220626520604e6f6e65603b0a0909090909097165643b0a0909090909090000eca211004500000046000000110000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f636f6e7472616374732f7372632f7761736d2f656e765f6465662f6d6163726f732e7273657865632e7072656661625f6d6f64756c652e696e697469616c2063616e27742062652067726561746572207468616e20657865632e7072656661625f6d6f64756c652e6d6178696d756d3b0a09090909090974687573204d656d6f72793a3a6e6577206d757374206e6f74206661696c3b0a09090909090971656400000000000000c13711000a0000000000000004a41100010000000000000000000000aa37110017000000000000000ca41100010000000000000000000000a1371100090000000000000014a411000100000000000000b5a41100220000005ea41100570000001ca411004200000020416d6f756e74206265696e67207472616e7366657272656420697320746f6f206c6f7720746f2063726561746520612076657374696e67207363686564756c652e20416e206578697374696e672076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e7420746861742063616e6e6f7420626520636c6f6262657265642e20546865206163636f756e7420676976656e206973206e6f742076657374696e672e0000000000ea3a11000800000000000000e4a81100010000000000000000000000d2af12000f00000000000000eca81100010000000000000000000000e23a11000800000000000000f4a81100010000000000000000000000da3a11000800000000000000fca81100010000000000000000000000cb3a11000f0000000000000004a91100010000000000000000000000e1af120011000000000000000ca91100010000000000000000000000b83a1100130000000000000014a91100010000000000000000000000a73a110011000000000000001ca911000100000000000000000000009c3a11000b0000000000000024a91100010000000000000000000000923a11000a000000000000002ca91100010000000000000000000000853a11000d0000000000000034a911000100000000000000000000001bab12000c000000000000003ca911000100000000000000000000007b3a11000a0000000000000044a911000100000000000000000000006f3a11000c000000000000004ca911000100000000000000000000005e3a1100110000000000000054a91100010000000000000000000000533a11000b000000000000005ca91100010000000000000000000000a1af1200080000000000000064a911000100000000000000000000004b3a110008000000000000006ca911000100000000000000000000003c3a11000f0000000000000074a911000100000000000000000000002b3a110011000000000000007ca911000100000000000000000000001c3a11000f0000000000000084a91100010000000000000000000000113a11000b000000000000008ca91100010000000000000000000000083a1100090000000000000094a91100010000000000000000000000fe3911000a000000000000009ca91100010000000000000000000000f73911000700000000000000a4a91100010000000000000000000000ee3911000900000000000000aca91100010000000000000000000000e53911000900000000000000b4a91100010000000000000000000000dd3911000800000000000000bca91100010000000000000000000000d13911000c00000000000000c4a91100010000000000000000000000c03911001100000000000000cca9110001000000000000000000000027ab12000800000000000000d4a91100010000000000000000000000b73911000900000000000000dca91100010000000000000000000000a63911001100000000000000e4a91100010000000000000000000000993911000d00000000000000eca911000100000000000000000000008f3911000a00000000000000f4a911000200000000000000000000007e391100110000000000000004aa11000100000000000000000000007639110008000000000000000caa1100010000000000000035af11000e0000001daf11001800000011af11000c00000003af11000e000000ddae110026000000c7ae110016000000acae11001b00000081ae11002b00000074ae11000d0000005fae11001500000038ae11002700000028ae1100100000001cae11000c0000000eae11000e000000f7ad110017000000eaad11000d000000e0ad11000a000000d7ad110009000000c4ad110013000000a2ad11002200000091ad1100110000007cad11001500000053ad11002900000017ad11003c000000d8ac11003f0000008aac11004e00000046ac11004400000014ac110032000000e1ab110033000000beab11002300000095ab1100290000006bab11002a0000002bab11004000000002ab11002900000071aa110056000000c7aa11003b0000003aaa11003700000014aa1100260000002044656c65676174696f6e20746f206f6e6573656c66206d616b6573206e6f2073656e73652e2054686520696e7374616e74207265666572656e64756d206f726967696e2069732063757272656e746c7920646973616c6c6f7765642e20546865206163636f756e742063757272656e746c792068617320766f74657320617474616368656420746f20697420616e6420746865206f7065726174696f6e2063616e6e6f74207375636365656420756e74696c207468657365206172652072656d6f7665642c20656974686572207468726f7567682060756e766f746560206f722060726561705f766f7465602e20546865206163636f756e74206973206e6f742063757272656e746c792064656c65676174696e672e20546f6f206869676820612062616c616e6365207761732070726f7669646564207468617420746865206163636f756e742063616e6e6f74206166666f72642e20416e20756e657870656374656420696e746567657220756e646572666c6f77206f636375727265642e20416e20756e657870656374656420696e7465676572206f766572666c6f77206f636375727265642e20546865206163636f756e7420697320616c72656164792064656c65676174696e672e20546865206163746f7220686173206e6f207065726d697373696f6e20746f20636f6e647563742074686520616374696f6e2e2054686520676976656e206163636f756e7420646964206e6f7420766f7465206f6e20746865207265666572656e64756d2e20412070726f78792d64652d70616972696e672077617320617474656d7074656420746f20616e206163636f756e74207468617420776173206e6f74206163746976652e20412070726f78792d70616972696e672077617320617474656d7074656420746f20616e206163636f756e74207468617420776173206f70656e20746f20616e6f74686572206163636f756e742e20412070726f78792d70616972696e672077617320617474656d7074656420746f20616e206163636f756e74207468617420776173206e6f74206f70656e2e20546865206c6f636b206f6e20746865206163636f756e7420746f20626520756e6c6f636b656420686173206e6f742079657420657870697265642e2054686520746172676574206163636f756e7420646f6573206e6f7420686176652061206c6f636b2e204e6f2070726f706f73616c732077616974696e6720496e76616c696420707265696d61676520566f746520676976656e20666f7220696e76616c6964207265666572656e64756d20507265696d616765206e6f7420666f756e6420496d6d696e656e7420546f6f206561726c79204e6f7420696d6d696e656e7420507265696d61676520616c7265616479206e6f746564204e6f742064656c6567617465642057726f6e672070726f787920416c726561647920612070726f7879204964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365204e6f2065787465726e616c2070726f706f73616c20496e76616c69642068617368204e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974792050726f706f73616c207374696c6c20626c61636b6c69737465642050726f706f73616c20616c7265616479206d6164652043616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636520556e6b6e6f776e20696e646578204e6f7420612070726f78792050726f706f73616c20646f6573206e6f742065786973742056616c756520746f6f206c6f77617373657274696f6e206661696c65643a2073656c662e686569676874203e2030617373657274696f6e206661696c65643a2073656c662e6c656e2829203e203094af110056000000a5040000520000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962616c6c6f632f636f6c6c656374696f6e732f62747265652f6e6f64652e7273000094af110056000000b60400004c0000004368617267655472616e73616374696f6e5061796d656e745072697374696e65436f6465436f646553746f72616765436f6e7472616374496e666f4f66526563656e7448696e7473506f7374496e666f3a2000000000000090b0110004000000000000000000000094b011000e000000000000000a000000f50000000300000000000000a4b011000c00000000000000010000006e6f64657375627374726174652d6e6f64650000df6acb689907609b0300000037e397fc7c91f5e40100000040fe3ad401f8959a04000000d2bc9897eed08f1502000000f78b278be53f454c02000000ed99c5acb25eedf502000000cbca25e39f14238702000000687ad44ad37f03c201000000bc9d89904f5b923f0100000068b66ba122c93fa70100000037c8bb1350a9a2a801000000ab3c0572291feb8b010000006772616e62616265696d6f6e617564690000000040787d010065cd1d00e1f505d85aae1ec0542205b0508f1f38e4750488467020d853e903603c5121d0bf760338323222a8591903402013236039cd02480ef423a82a8f0268f8d42470955c02b8dab525c05a3302d8c4962648bd1102e0b27727a855f601e8a05828e8fedf0180773929c0cacd01586d1a2af8f1be019053fb2a50d8b201d00edc2be0fca80138edbc2c48f2a001e06d9d2d80669a01c80d7e2e500f9501c0575e2f08b6900140323f30e0278d0148202031b0418a0108a3ff3120e8870120bedf32f0fb85013856c03398698401f0fda03478218301b8d87f35d8178201d8c26036183d8101b8223e37508d800188d21c38c8fc7f0168b5f93898877f01a829d139d8297f0120d6ab3ab8db7e0168ae803b389d7e0100ca9a3b68957e010000000051e211000600000000000000870000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000890000000000000000000000000000008a0000000000000000000000000000008b000000000000000000000000000000a8be110007000000000000008c000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000008e0000000000000000000000000000008f00000000000000000000000000000090000000000000000000000000000000a9e81200040000000000000091000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000200000000000000000000000000000000000000920000000000000000000000000000008f000000000000000000000000000000d1f71200090000000000000093000000000000000000000000000000000000000000000000000000000000009400000000000000000000000200000000000000000000000000000000000000950000000000000000000000000000008f00000000000000000000000000000093e812000a00000000000000960000000000000000000000000000000000000000000000000000000000000097000000000000000000000002000000000000000000000000000000000000008f00000000000000000000000000000098000000000000000000000000000000afbe1100070000000000000099000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000009b0000000000000000000000000000008f0000000000000000000000000000008f000000000000000000000000000000b6be110008000000000000009c000000000000000000000000000000000000000000000000000000000000009d0000000000000000000000000000009e0000000000000000000000000000009f000000000000000000000000000000a0000000000000000000000000000000e3f712001200000000000000a1000000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000000000000000000000000000000a20000000000000000000000000000008f000000000000000000000000000000f7f612000700000000000000a300000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000a5000000000000000000000000000000a6000000000000000000000000000000a7000000000000000000000000000000a3f612000700000000000000a800000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000aa0000000000000000000000000000008f000000000000000000000000000000ab000000000000000000000000000000d9f112000900000000000000ac00000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000ae000000000000000000000000000000af000000000000000000000000000000b0000000000000000000000000000000bebe11000700000000000000b100000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000b30000000000000000000000000000008f000000000000000000000000000000b4000000000000000000000000000000c5be11001200000000000000b500000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000b30000000000000000000000000000008f000000000000000000000000000000b4000000000000000000000000000000d7be11000900000000000000b600000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000b8000000000000000000000000000000b9000000000000000000000000000000ba000000000000000000000000000000e0be11001300000000000000bb00000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000bd0000000000000000000000000000008f0000000000000000000000000000008f0000000000000000000000000000003ef212000f000000020000000000000000000000000000000000000000000000000000000000000000000000be00000000000000000000000200000000000000000000000000000000000000bf000000000000000000000000000000c0000000000000000000000000000000f3be11000700000000000000c100000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000c30000000000000000000000000000008f000000000000000000000000000000c400000000000000000000000000000006f812000800000000000000c500000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000c7000000000000000000000000000000c8000000000000000000000000000000c900000000000000000000000000000071ec12000900000000000000ca00000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000cc000000000000000000000000000000cd000000000000000000000000000000ce000000000000000000000000000000d52112000400000000000000cf00000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000d10000000000000000000000000000008f000000000000000000000000000000d200000000000000000000000000000008f412000800000000000000d300000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000d50000000000000000000000000000008f000000000000000000000000000000d60000000000000000000000000000007de81200120000000200000000000000000000000000000000000000000000000000000000000000000000008f000000000000000000000002000000000000000000000000000000000000008f0000000000000000000000000000008f00000000000000000000000000000022f412000800000000000000d7000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000d80000000000000000000000000000008f0000000000000000000000000000008f00000000000000000000000000000082b412001800000000000000d9000000000000000000000000000000000000000000000000000000000000008f000000000000000000000002000000000000000000000000000000000000008f0000000000000000000000000000008f000000000000000000000000000000fabe11000800000000000000da00000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000dc000000000000000000000000000000dd000000000000000000000000000000de000000000000000000000000000000a20d12000700000000000000df00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000e1000000000000000000000000000000e2000000000000000000000000000000e300000000000000000000000000000078d112000800000000000000e400000000000000000000000000000000000000000000000000000000000000e5000000000000000000000000000000e60000000000000000000000000000008f000000000000000000000000000000e700000000000000000000000000000002bf11000700000000000000e800000000000000000000000000000000000000000000000000000000000000e9000000000000000000000000000000ea000000000000000000000000000000eb000000000000000000000000000000ec00000000000000000000000000000009bf11000900000000000000ed000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000ee0000000000000000000000000000008f0000000000000000000000000000008f00000000000000000000005574696c697479496e646963657342616c616e636573436f756e63696c546563686e6963616c436f6d6d6974746565456c656374696f6e73546563686e6963616c4d656d626572736869704772616e6470614964656e7469747956657374696e675363686564756c6572000000000000bcbf11001600000000000000d4bf1100010000000000000000000000dcbf11001500000000000000f4bf1100010000000000000000000000fcbf1100150000000000000014c011000100000000000000000000001cc011001a0000000000000038c0110001000000000000000000000040c01100100000000000000050c0110001000000000000000000000058c01100150000000000000070c011000100000000000000496e76616c69645363686564756c6556657273696f6e00007cc1110041000000496e76616c6964537572636861726765436c61696d00000027c1110055000000496e76616c6964536f75726365436f6e7472616374000000f0c0110037000000496e76616c696444657374696e6174696f6e436f6e74726163740000bfc0110031000000496e76616c6964546f6d6273746f6e65a7c0110018000000496e76616c6964436f6e74726163744f726967696e00000078c011002f00000020416e206f726967696e20547269654964207772697474656e20696e207468652063757272656e7420626c6f636b2e20546f6d6273746f6e657320646f6e2774206d617463682e2043616e6e6f7420726573746f726520746f206e6f6e6578697374696e67206f7220616c69766520636f6e74726163742e2043616e6e6f7420726573746f72652066726f6d206e6f6e6578697374696e67206f7220746f6d6273746f6e6520636f6e74726163742e20416e206f726967696e206d757374206265207369676e6564206f7220696e686572656e7420616e6420617578696c696172792073656e646572206f6e6c792070726f7669646564206f6e20696e686572656e742e2041206e6577207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e207468652063757272656e74206f6e652e0000000000000080c31100130000000000000006cf12000e00000000000000301a130094c311000000000000000000a4c31100040000000000000000000000c4c311001000000000000000b66c12000c00000000000000301a13001cc411000000000000000000d4c31100010000000000000000000000dcc31100110000000000000060dc12000300000000000000301a1300f0c31100000000000000000000c4110002000000000000000000000010c411000b00000000000000b66c12000c00000000000000301a13001cc4110000000000000000002cc4110001000000000000000000000034c411001100000000000000b66c12000c00000000000000301a130048c41100000000000000000058c4110007000000000000000000000090c411000f00000000000000b66c12000c00000000000000301a1300a0c411000000000000000000b0c41100020000000000000000000000c0c41100080000000000000060dc12000300000000000000301a1300c8c411000000000000000000d8c41100020000000000000000000000e8c411000c0000000000000060dc12000300000000000000301a1300f4c41100000000000000000004c5110001000000000000005369676e6564436c61696d48616e646963617000420000000000000001000000ef0000007fc8110038000000301a130000000000b7c8110043000000fac811001a000000546f6d6273746f6e654465706f7369744ac811003500000053746f7261676553697a654f6666736574000000420000000000000001000000f0000000ccc711005500000021c811002900000052656e744279746546656500420000000000000001000000680000007fc711004d00000052656e744465706f7369744f6666736574000000420000000000000001000000f100000007c611004100000048c6110016000000301a1300000000005ec611005a000000b8c61100560000000ec711005300000061c711001e00000053757263686172676552657761726400420000000000000001000000f2000000b4c5110039000000edc511001a0000004d61784465707468420000000000000001000000f30000005ac511004c000000a6c511000e0000004d617856616c756553697a65420000000000000001000000f40000000cc511004e00000020546865206d6178696d756d2073697a65206f6620612073746f726167652076616c756520696e2062797465732e204120726561736f6e61626c652064656661756c74206973203136204b69422e20546865206d6178696d756d206e657374696e67206c6576656c206f6620612063616c6c2f696e7374616e746961746520737461636b2e204120726561736f6e61626c652064656661756c742076616c7565206973203130302e205265776172642074686174206973207265636569766564206279207468652070617274792077686f736520746f75636820686173206c656420746f2072656d6f76616c206f66206120636f6e74726163742e2054686520616d6f756e74206f662066756e6473206120636f6e74726163742073686f756c64206465706f73697420696e206f7264657220746f206f66667365742074686520636f7374206f66206f6e6520627974652e204c6574277320737570706f736520746865206465706f73697420697320312c303030204255202862616c616e636520756e697473292f6279746520616e64207468652072656e7420697320312042552f627974652f6461792c207468656e206120636f6e7472616374207769746820312c3030302c3030302042552074686174207573657320312c303030206279746573206f662073746f7261676520776f756c6420706179206e6f2072656e742e20427574206966207468652062616c616e6365207265647563656420746f203530302c30303020425520616e64207468652073746f7261676520737461796564207468652073616d6520617420312c3030302c207468656e20697420776f756c6420706179203530302042552f6461792e205072696365206f6620612062797465206f662073746f7261676520706572206f6e6520626c6f636b20696e74657276616c2e2053686f756c642062652067726561746572207468616e20302e2053697a65206f66206120636f6e7472616374206174207468652074696d65206f6620696e7374616e74696174696f6e2e205468697320697320612073696d706c652077617920746f20656e73757265207468617420656d70747920636f6e747261637473206576656e7475616c6c7920676574732064656c657465642e20546865206d696e696d756d20616d6f756e7420726571756972656420746f2067656e6572617465206120746f6d6273746f6e652e204e756d626572206f6620626c6f636b2064656c617920616e2065787472696e73696320636c61696d20737572636861726765206861732e205768656e20636c61696d207375726368617267652069732063616c6c656420627920616e2065787472696e736963207468652072656e7420697320636865636b656420666f722063757272656e745f626c6f636b202d2064656c61790000000074ca110008000000000000007cca110003000000000000000000000094ca11000100000000000000000000009cca11000c0000000000000098ad1200020000000000000000000000a8ca1100010000000000000000000000b0ca1100070000000000000048121200020000000000000000000000b8ca1100060000000000000000000000e8ca11000800000000000000f0ca110005000000000000000000000018cb110009000000000000000000000060cb11000a00000000000000d4b112000100000000000000000000006ccb110001000000000000000000000074cb11000f00000000000000f012120001000000000000000000000084cb11000100000000000000000000008ccb11000a000000000000004812120002000000000000000000000098cb1100020000000000000000000000a8cb11001100000000000000bccb1100020000000000000000000000cccb110001000000000000005472616e7366657220af12000900000020af120009000000f6151200070000004bcf11005a000000496e7374616e74696174656414cf11003700000045766963746564004bce110039000000301a1300000000000ecd110009000000301a13000000000084ce110043000000c7ce11004d000000526573746f72656420af12000900000020af12000900000089b2120004000000f615120007000000a1f5120004000000dfcc11002f000000301a1300000000000ecd110009000000301a13000000000017cd11003d00000054cd11003b0000008fcd11003a000000c9cd1100460000000fce11003c000000436f646553746f7265640000b1cc11002e0000005363686564756c65557064617465640081cc11003000000044697370617463686564000016cc11004e00000064cc11001d000000436f6e7472616374457865637574696f6e00000020af120009000000cc8d120007000000d4cb11004200000020416e206576656e74206465706f73697465642075706f6e20657865637574696f6e206f66206120636f6e74726163742066726f6d20746865206163636f756e742e20412063616c6c2077617320646973706174636865642066726f6d2074686520676976656e206163636f756e742e2054686520626f6f6c207369676e616c73207768657468657220697420776173207375636365737366756c20657865637574696f6e206f72206e6f742e20547269676765726564207768656e207468652063757272656e74207363686564756c6520697320757064617465642e20436f646520776974682074686520737065636966696564206861736820686173206265656e2073746f7265642e20526573746f726174696f6e20666f72206120636f6e747261637420686173206265656e20696e697469617465642e202320506172616d73202d2060646f6e6f72603a20604163636f756e744964603a204163636f756e74204944206f662074686520726573746f72696e6720636f6e7472616374202d206064657374603a20604163636f756e744964603a204163636f756e74204944206f662074686520726573746f72656420636f6e7472616374202d2060636f64655f68617368603a206048617368603a20436f64652068617368206f662074686520726573746f72656420636f6e7472616374202d206072656e745f616c6c6f77616e63653a206042616c616e6365603a2052656e7420616c6c6f77616e6365206f662074686520726573746f72656420636f6e7472616374202d206073756363657373603a2060626f6f6c603a20547275652069662074686520726573746f726174696f6e20776173207375636365737366756c20436f6e747261637420686173206265656e206576696374656420616e64206973206e6f7720696e20746f6d6273746f6e652073746174652e202d2060636f6e7472616374603a20604163636f756e744964603a20546865206163636f756e74204944206f6620746865206576696374656420636f6e74726163742e202d2060746f6d6273746f6e65603a2060626f6f6c603a205472756520696620746865206576696374656420636f6e7472616374206c65667420626568696e64206120746f6d6273746f6e652e20436f6e7472616374206465706c6f7965642062792061646472657373206174207468652073706563696669656420616464726573732e205472616e736665722068617070656e6564206066726f6d6020746f2060746f60207769746820676976656e206076616c7565602061732070617274206f662061206063616c6c60206f722060696e7374616e7469617465602e0000000000000084d011000f0000000000000094d01100010000000000000000000000acd01100030000000000000000000000c4d01100080000000000000040ea1100010000000000000000000000ccd01100020000000000000000000000fbea12000400000000000000dcd011000400000000000000000000003cd1110007000000000000000000000074d111000b0000000000000080d11100040000000000000000000000e0d111000a000000000000000000000030d211000f0000000000000040d2110002000000000000000000000070d2110005000000000000007570646174655f7363686564756c650000000000a8d811000800000000000000b0d811000800000038d811002d000000301a13000000000065d81100430000007075745f636f6465acd711005700000003d811003500000000000000b2d311000400000000000000f32012002300000000000000aa4d12000500000000000000807512001500000000000000ead511000900000000000000f3d511000c0000000000000013d611000400000000000000cc8d12000700000017d6110042000000301a13000000000059d611004a000000a3d611002c000000cfd611004600000015d711005200000067d7110045000000696e7374616e74696174650000000000e1d511000900000000000000807512001500000000000000ead511000900000000000000f3d511000c00000000000000ffd51100090000000000000008d611000b0000000000000013d611000400000000000000cc8d120007000000c0d311006f000000301a1300000000002fd4110026000000301a13000000000055d4110050000000a5d4110041000000e6d411005b00000041d511005700000098d511002a000000c2d511001f000000636c61696d5f7375726368617267650000000000b2d3110004000000000000007ac312000c00000000000000b6d311000a00000000000000dddb12001400000098d211005c000000f4d2110045000000301a13000000000039d311004e00000087d311002b00000020416c6c6f777320626c6f636b2070726f64756365727320746f20636c61696d206120736d616c6c2072657761726420666f72206576696374696e67206120636f6e74726163742e204966206120626c6f636b2070726f6475636572206661696c7320746f20646f20736f2c206120726567756c61722075736572732077696c6c20626520616c6c6f77656420746f20636c61696d20746865207265776172642e20496620636f6e7472616374206973206e6f742065766963746564206173206120726573756c74206f6620746869732063616c6c2c206e6f20616374696f6e73206172652074616b656e20616e64207468652073656e646572206973206e6f7420656c696769626c6520666f7220746865207265776172642e646573746175785f73656e64657220496e7374616e7469617465732061206e657720636f6e74726163742066726f6d207468652060636f646568617368602067656e65726174656420627920607075745f636f6465602c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e20496e7374616e74696174696f6e20697320657865637574656420617320666f6c6c6f77733a202d205468652064657374696e6174696f6e206164647265737320697320636f6d7075746564206261736564206f6e207468652073656e64657220616e642068617368206f662074686520636f64652e202d2054686520736d6172742d636f6e7472616374206163636f756e7420697320637265617465642061742074686520636f6d707574656420616464726573732e202d20546865206063746f725f636f64656020697320657865637574656420696e2074686520636f6e74657874206f6620746865206e65776c792d63726561746564206163636f756e742e204275666665722072657475726e656420202061667465722074686520657865637574696f6e206973207361766564206173207468652060636f646560206f6620746865206163636f756e742e205468617420636f64652077696c6c20626520696e766f6b656420202075706f6e20616e792063616c6c2072656365697665642062792074686973206163636f756e742e202d2054686520636f6e747261637420697320696e697469616c697a65642e656e646f776d656e746761735f6c696d6974436f6d706163743c4761733e636f64655f68617368436f6465486173683c543e64617461204d616b657320612063616c6c20746f20616e206163636f756e742c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e202a20496620746865206163636f756e74206973206120736d6172742d636f6e7472616374206163636f756e742c20746865206173736f63696174656420636f64652077696c6c20626520657865637574656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e202a20496620746865206163636f756e74206973206120726567756c6172206163636f756e742c20616e792076616c75652077696c6c206265207472616e736665727265642e202a204966206e6f206163636f756e742065786973747320616e64207468652063616c6c2076616c7565206973206e6f74206c657373207468616e20606578697374656e7469616c5f6465706f736974602c206120726567756c6172206163636f756e742077696c6c206265206372656174656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e2053746f7265732074686520676976656e2062696e617279205761736d20636f646520696e746f2074686520636861696e27732073746f7261676520616e642072657475726e73206974732060636f646568617368602e20596f752063616e20696e7374616e746961746520636f6e747261637473206f6e6c7920776974682073746f72656420636f64652e205570646174657320746865207363686564756c6520666f72206d65746572696e6720636f6e7472616374732e20546865207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e207468652073746f726564207363686564756c652e7363686564756c655363686564756c650000000062ec12000f0000000000000000000000b0d811000800000000000000000000000000000000000000000000000000000000000000301a130070da1100000000000000000080da11000100000000000000010000000000000014b011000c000000010600000000000008d611000b00000000000000cc8d12000700000000000000000000000000000000000000301a130088da1100000000000000000098da11000100000000000000000000000000000020b011000b000000010600000000000008d611000b00000000000000a0da11001600000000000000000000000000000000000000301a1300e8da11000000000000000000b8da1100010000000000000000000000000000007aec12000e000000000000000000000010f111000300000000000000000000000000000000000000000000000000000000000000301a1300c0da11000000000000000000d0da1100010000000000000001000000000000002bb011000e00000001050000000000007ac312000c00000000000000d8da11000f00000000000000000000000000000000000000301a1300e8da11000000000000000000f8da1100010000000000000000000000420000000000000001000000f5000000f1db110025000000420000000000000001000000f600000098db1100590000007761736d3a3a5072656661625761736d4d6f64756c6500003fdb1100590000004200000000000000010000006e0000002adb110015000000436f6e7472616374496e666f3c543e004200000000000000010000005b00000000db11002a0000002054686520636f6465206173736f6369617465642077697468206120676976656e206163636f756e742e20546865207375627472696520636f756e7465722e2041206d617070696e67206265747765656e20616e206f726967696e616c20636f6465206861736820616e6420696e737472756d656e746564207761736d20636f64652c20726561647920666f7220657865637574696f6e2e2041206d617070696e672066726f6d20616e206f726967696e616c20636f6465206861736820746f20746865206f726967696e616c20636f64652c20756e746f756368656420627920696e737472756d656e746174696f6e2e2043757272656e7420636f7374207363686564756c6520666f7220636f6e7472616374732e00000000000050dc11000e0000000000000060dc110001000000000000000000000068dc1100070000000000000070dc11000100000000000000416c72656164795570646174656400009cdc11003200000042616448696e740078dc1100240000002046696e616c697a6564206865696768742061626f766520626c6f636b206e756d6265722046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b00000000000040dd11000a0000000000000006cf12000e00000000000000301a13004cdd110000000000000000005cdd110001000000000000000000000064dd11000d0000000000000006cf12000e00000000000000301a130074dd1100000000000000000084dd1100010000000000000057696e646f7753697a650000420000000000000001000000f7000000d3dd1100460000005265706f72744c6174656e6379000000420000000000000001000000f80000008cdd110047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e0000000000000048de11000a0000000000000054de11000100000000000000000000006cde1100020000000000000066696e616c5f68696e74000000000000d4de11000400000000000000d8de1100170000007cde11003d000000b9de11001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e68696e74436f6d706163743c543a3a426c6f636b4e756d6265723e000000000028df11001200000000000000b66c12000c00000000000000301a13003cdf110000000000000000004cdf110001000000000000005472616e73616374696f6e427974654665650000420000000000000001000000f900000054df110043000000205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e0000000000f5f71200110000000000000000000000f0df11000a00000000000000000000000000000000000000000000000000000000000000301a1300fcdf11000000000000000000301a13000000000000000000010000004d756c7469706c69657200004200000000000000010000005f0000005570646174654f72646572656448696e74734d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b20716564000020e111003c0000006f0000002b000000726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b2071656400004200000004000000040000000d00000020e111003c0000007a0000001b0000007072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b207165640020e111003c000000950000001100000020e111003c0000008f0000001900000020e111003c00000090000000190000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f66696e616c6974792d747261636b65722f7372632f6c69622e72734e6f6e5a65726f526566436f756e744e6f6e44656661756c74436f6d706f736974654661696c6564546f4578747261637452756e74696d6556657273696f6e5370656356657273696f6e4e65656473546f496e637265617365496e76616c6964537065634e616d653a65787472696e7369635f696e64657866696c6c5f626c6f636b72656d61726b7365745f686561705f70616765737365745f636f64657365745f636f64655f776974686f75745f636865636b737365745f6368616e6765735f747269655f636f6e6669677365745f73746f726167656b696c6c5f73746f726167656b696c6c5f7072656669787375696369646553797374656d4163636f756e74426c6f636b486173684e756d626572506172656e744861736845787472696e73696373526f6f74446967657374000000000068e31100100000000000000078e3110001000000000000000000000080e3110001000000000000000000000088e311000f0000000000000098e31100020000000000000000000000a8e31100010000000000000000000000b0e311000b00000000000000301a1300000000000000000000000000bce31100010000000000000000000000c4e311000a0000000000000074ad1200010000000000000000000000d0e31100010000000000000000000000d8e311000d0000000000000074ad1200010000000000000000000000e8e31100010000000000000045787472696e736963537563636573734ce411000c00000058e411002500000045787472696e7369634661696c656400e00e13000d0000004ce411000c00000037e4110015000000436f6465557064617465640022e41100150000004e65774163636f756e74000007e411001b0000004b696c6c65644163636f756e74000000f0e311001700000020416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e20603a636f6465602077617320757064617465642e20416e2065787472696e736963206661696c65642e4469737061746368496e666f20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e6164645f6d656d62657272656d6f76655f6d656d626572737761705f6d656d62657272657365745f6d656d626572736368616e67655f6b65797365745f7072696d65636c6561725f7072696d65000000000000d4e511000b00000000000000301a1300000000000000000000000000e0e51100010000000000000000000000e8e511000d00000000000000301a1300000000000000000000000000f8e5110001000000000000000000000000e611000e00000000000000301a130000000000000000000000000010e6110001000000000000000000000018e611000c00000000000000301a130000000000000000000000000024e61100010000000000000000000000180d12000a00000000000000301a13000000000000000000000000002ce6110001000000000000000000000034e6110005000000000000003ce6110001000000000000000000000044e6110001000000000000004d656d62657241646465640071e71100390000004d656d62657252656d6f76656400000036e711003b0000004d656d62657273537761707065640000ffe61100370000004d656d626572735265736574b9e611004600000097e611002200000044756d6d7900000068e611002f0000004ce611001c000000205068616e746f6d206d656d6265722c206e6576657220757365642e73705f7374643a3a6d61726b65723a3a5068616e746f6d446174613c284163636f756e7449642c204576656e74293e204f6e65206f6620746865206d656d6265727327206b657973206368616e6765642e20546865206d656d62657273686970207761732072657365743b2073656520746865207472616e73616374696f6e20666f722077686f20746865206e6577207365742069732e2054776f206d656d62657273207765726520737761707065643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732072656d6f7665643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732061646465643b2073656520746865207472616e73616374696f6e20666f722077686f2e0000420000000400000004000000fa000000420000000000000001000000460000004576656e74734576656e74546f7069637300000000000000d4e111000a0000000000000098e91100010000000000000000000000b0e91100010000000000000000000000dee111000600000000000000b8e91100010000000000000000000000d0e91100050000000000000000000000e4e111000e00000000000000f8e9110001000000000000000000000010ea1100060000000000000000000000f2e11100080000000000000040ea110001000000000000000000000058ea1100080000000000000000000000fae11100170000000000000040ea110001000000000000000000000098ea110007000000000000000000000011e211001700000000000000d0ea1100010000000000000000000000e8ea110007000000000000000000000028e211000b0000000000000020eb110001000000000000000000000038eb110006000000000000000000000033e211000c0000000000000068eb110001000000000000000000000080eb11000600000000000000000000003fe211000b00000000000000b0eb1100010000000000000000000000c8eb11000600000000000000000000004ae211000700000000000000301a1300000000000000000000000000f8eb110007000000000000000000000077f1110006000000000000007df111000700000035f1110042000000000000002ef111000700000000000000cc8d12000700000013f111001b000000301a130000000000f5bd12000b000000adec11000900000044be12000c000000000000000bf11100050000000000000010f1110003000000b9f011003f000000301a130000000000f5bd12000b000000adec110009000000f8f011001300000044be12000c00000000000000b5f011000400000000000000cc8d120007000000f0ef11001a000000301a130000000000f5bd12000b0000000af011004d000000c3ef11002200000057f011005e000000e5ef11000b00000044be12000c00000058ef110047000000301a130000000000f5bd12000b0000009fef110024000000c3ef110022000000e5ef11000b00000044be12000c0000000000000025ef1100130000000000000038ef1100200000005fee110028000000301a130000000000f5bd12000b00000087ee110026000000adee11002c000000d9ee11004c00000044be12000c000000000000004dee1100050000000000000052ee11000d000000eeed11001b000000301a130000000000f5bd12000b00000009ee1100250000002eee11001f00000044be12000c00000000000000a79612000400000000000000e6ed11000800000070ed11001e000000301a130000000000f5bd12000b0000008eed11003f000000cded11001900000044be12000c000000000000006aed110006000000000000003422120003000000d5ec110045000000301a130000000000f5bd12000b0000001aed11003700000051ed11001900000044be12000c00000030ec11005900000089ec110024000000301a130000000000f5bd12000b000000adec110009000000b6ec11001f00000044be12000c000000204b696c6c207468652073656e64696e67206163636f756e742c20617373756d696e6720746865726520617265206e6f207265666572656e636573206f75747374616e64696e6720616e642074686520636f6d706f73697465206461746120697320657175616c20746f206974732064656661756c742076616c75652e202d20604f28312960202d20312073746f72616765207265616420616e642064656c6574696f6e2e204b696c6c20616c6c2073746f72616765206974656d7320776974682061206b657920746861742073746172747320776974682074686520676976656e207072656669782e202d20604f285029602077686572652060506020616d6f756e74206f66206b657973207769746820707265666978206070726566697860202d206050602073746f726167652064656c6574696f6e732e707265666978204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e202d20604f28564b296020776865726520605660206c656e677468206f6620606b6579736020616e6420604b60206c656e677468206f66206f6e65206b6579202d206056602073746f726167652064656c6574696f6e732e5665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e202d20604f2849296020776865726520604960206c656e677468206f6620606974656d7360202d206049602073746f72616765207772697465732028604f28312960292e6974656d735665633c4b657956616c75653e2053657420746865206e6577206368616e676573207472696520636f6e66696775726174696f6e2e202d20604f2844296020776865726520604460206c656e677468206f66206044696765737460202d20312073746f72616765207772697465206f722064656c6574652028636f64656320604f28312960292e202d20312063616c6c20746f20606465706f7369745f6c6f67603a20604f284429602028776869636820646570656e6473206f6e20746865206c656e677468206f66206044696765737460296368616e6765735f747269655f636f6e6669674f7074696f6e3c4368616e67657354726965436f6e66696775726174696f6e3e2053657420746865206e65772072756e74696d6520636f646520776974686f757420646f696e6720616e7920636865636b73206f662074686520676976656e2060636f6465602e202d20604f2843296020776865726520604360206c656e677468206f662060636f646560202d20312073746f726167652077726974652028636f64656320604f28432960292e202d2031206576656e742e2053657420746865206e65772072756e74696d6520636f64652e202d20604f2843202b2053296020776865726520604360206c656e677468206f662060636f64656020616e642060536020636f6d706c6578697479206f66206063616e5f7365745f636f646560202d20312063616c6c20746f206063616e5f7365745f636f6465603a20604f28532960202863616c6c73206073705f696f3a3a6d6973633a3a72756e74696d655f76657273696f6e6020776869636820697320657870656e73697665292e636f64652053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e202d20312073746f726167652077726974652e7061676573753634204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b204120646973706174636820746861742077696c6c2066696c6c2074686520626c6f636b2077656967687420757020746f2074686520676976656e20726174696f2e5f726174696f50657262696c6c0000000057e211000700000001020000000000007ac312000c00000000000000acf611002500000000000000000000000000000000000000301a1300d4f611000000000000000000e4f6110001000000000000000100000000000000ecf611000e000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a130048f711000000000000000000fcf611000100000000000000000000000000000004f7110013000000000000000000000017f711000600000000000000000000000000000000000000000000000000000000000000301a130020f71100000000000000000030f711000100000000000000000000000000000038f7110010000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a130048f71100000000000000000058f71100010000000000000000000000000000005ee2110009000000010500000000000006cf12000e0000000000000091d912000700000000000000000000000000000000000000301a1300a0f71100000000000000000060f711000100000000000000010000000000000068f711000d000000010500000000000060dc12000300000000000000cc8d12000700000000000000000000000000000000000000301a130078f71100000000000000000088f711000100000000000000010000000000000067e2110006000000000000000000000006cf12000e00000000000000000000000000000000000000000000000000000000000000301a13002cf81100000000000000000090f71100010000000000000001000000000000006de211000a000000000000000000000091d912000700000000000000000000000000000000000000000000000000000000000000301a1300a0f71100000000000000000098f711000100000000000000010000000000000077e211000e000000000000000000000091d912000700000000000000000000000000000000000000000000000000000000000000301a1300a0f711000000000000000000b0f711000100000000000000010000000000000085e21100060000000000000000000000b8f711000b00000000000000000000000000000000000000000000000000000000000000301a1300c4f711000000000000000000d4f7110001000000000000000100000000000000cce71100060000000000000000000000dcf711002300000000000000000000000000000000000000000000000000000000000000301a130000f81100000000000000000010f811000100000000000000010000000000000018f811000a000000000000000000000022f811000a00000000000000000000000000000000000000000000000000000000000000301a13002cf8110000000000000000003cf8110001000000000000000100000000000000d2e711000b000000010200000000000091d91200070000000000000044f811002100000000000000000000000000000000000000301a130068f81100000000000000000078f811000a000000000000000100000000000000c8f81100120000000000000000000000daf811001600000000000000000000000000000000000000000000000000000000000000301a1300f0f81100000000000000000000f911000100000000000000000000000000000008f911000e000000000000000000000016f911000500000000000000000000000000000000000000000000000000000000000000301a13001cf9110000000000000000002cf911000100000000000000000000004163636f756e74496e666f3c543a3a496e6465782c20543a3a4163636f756e74446174613e000000420000000000000001000000fb0000004afe11003a00000045787472696e736963436f756e7400001cfe11002e000000416c6c45787472696e736963735765696768745765696768740000004200000000000000010000005b000000d7fd110045000000416c6c45787472696e736963734c656e4200000000000000010000005b00000087fd11005000000061fd11002600000045787472696e736963446174610000004200000000000000010000005900000012fd11004f000000d0fc110042000000b4fc11001c000000420000000000000001000000fc0000006ffc1100450000004469676573744f663c543e004200000000000000010000005900000033fc11003c0000005665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e00420000000000000001000000590000000bfc1100280000004576656e74436f756e744576656e74496e64657842000000000000000100000057000000ddfb11002e0000005665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e00000042000000000000000100000059000000abf9110049000000f4f9110025000000301a13000000000019fa1100540000006dfa110051000000befa110039000000301a130000000000f7fa1100530000004afb1100530000009dfb1100400000004c61737452756e74696d65557067726164654c61737452756e74696d6555706772616465496e666f4200000000000000010000005b00000056f9110055000000457865637574696f6e50686173655068617365004200000000000000010000005b00000034f91100220000002054686520657865637574696f6e207068617365206f662074686520626c6f636b2e2053746f726573207468652060737065635f76657273696f6e6020616e642060737065635f6e616d6560206f66207768656e20746865206c6173742072756e74696d6520757067726164652068617070656e65642e204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2077656967687420666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e205468652066756c6c206163636f756e7420696e666f726d6174696f6e20666f72206120706172746963756c6172206163636f756e742049442e000000009cff1100120000000000000017f711000600000000000000301a1300b0ff11000000000000000000c0ff1100010000000000000000000000c8ff11000800000000000000d0ff11000f00000000000000301a1300e0ff11000000000000000000f0ff1100010000000000000000000000f8ff1100140000000000000017f711000600000000000000301a13000c00120000000000000000001c00120001000000000000000000000024001200130000000000000017f711000600000000000000301a13003800120000000000000000004800120001000000000000000000000050001200120000000000000060dc12000300000000000000301a13006400120000000000000000007400120001000000000000004d6178696d756d426c6f636b5765696768740000420000000000000001000000fd0000009a0112001f000000446257656967687452756e74696d65446257656967687400420000000000000001000000fe0000005801120042000000426c6f636b457865637574696f6e576569676874420000000000000001000000ff000000040112005400000045787472696e736963426173655765696768740042000000000000000100000000010000a60012005e0000004d6178696d756d426c6f636b4c656e6774680000420000000000000001000000010100007c0012002a00000020546865206d6178696d756d206c656e677468206f66206120626c6f636b2028696e206279746573292e20546865206261736520776569676874206f6620616e2045787472696e73696320696e2074686520626c6f636b2c20696e646570656e64656e74206f6620746865206f662065787472696e736963206265696e672065786563757465642e20546865206261736520776569676874206f6620657865637574696e67206120626c6f636b2c20696e646570656e64656e74206f6620746865207472616e73616374696f6e7320696e2074686520626c6f636b2e2054686520776569676874206f662072756e74696d65206461746162617365206f7065726174696f6e73207468652072756e74696d652063616e20696e766f6b652e20546865206d6178696d756d20776569676874206f66206120626c6f636b2e4e6f646520697320636f6e6669677572656420746f20757365207468652073616d6520686173683b207165640000000802120032000000ce0300001c0000000802120032000000d6030000110000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f73797374656d2f7372632f6c69622e7273436865636b56657273696f6e436865636b47656e65736973436865636b457261436865636b4e6f6e6365436865636b576569676874636f6465206973206e6f7420666f756e647072697374696e6520636f6465206973206e6f7420666f756e640000000000007de411000a00000000000000d0031200010000000000000000000000e803120003000000000000000000000087e411000d00000000000000d00312000100000000000000000000000004120003000000000000000000000094e411000b0000000000000018041200020000000000000000000000480412000500000000000000000000009fe411000d000000000000007004120001000000000000000000000088041200040000000000000000000000ace411000a00000000000000a8041200010000000000000000000000c0041200050000000000000000000000b6e411000900000000000000d0031200010000000000000000000000e8041200010000000000000000000000bfe411000b00000000000000301a1300000000000000000000000000f0041200010000000000000000000000f020120003000000000000007ac312000c000000af0712001f000000301a130000000000ce0712002d0000005b07120024000000301a1300000000007f07120030000000000000005207120006000000000000007ac312000c000000000000005807120003000000000000007ac312000c000000b006120030000000301a130000000000e00612002e000000301a1300000000000e0712004400000000000000a90612000700000000000000ddce12001100000009061200560000005f0612001b000000301a1300000000007a0612002f000000000000008421120003000000000000007ac312000c0000004e05120036000000301a130000000000840512003d000000301a130000000000c1051200480000001e05120030000000f8041200260000002052656d6f766520746865207072696d65206d656d626572206966206974206578697374732e2053657420746865207072696d65206d656d6265722e204d75737420626520612063757272656e74206d656d6265722e2053776170206f7574207468652073656e64696e67206d656d62657220666f7220736f6d65206f74686572206b657920606e6577602e204d6179206f6e6c792062652063616c6c65642066726f6d20605369676e656460206f726967696e206f6620612063757272656e74206d656d6265722e205072696d65206d656d62657273686970206973207061737365642066726f6d20746865206f726967696e206163636f756e7420746f20606e6577602c20696620657874616e742e204368616e676520746865206d656d6265727368697020746f2061206e6577207365742c20646973726567617264696e6720746865206578697374696e67206d656d626572736869702e204265206e69636520616e64207061737320606d656d6265727360207072652d736f727465642e204d6179206f6e6c792062652063616c6c65642066726f6d206052657365744f726967696e60206f7220726f6f742e6d656d626572732053776170206f7574206f6e65206d656d626572206072656d6f76656020666f7220616e6f746865722060616464602e204d6179206f6e6c792062652063616c6c65642066726f6d2060537761704f726967696e60206f7220726f6f742e205072696d65206d656d62657273686970206973202a6e6f742a207061737365642066726f6d206072656d6f76656020746f2060616464602c20696620657874616e742e72656d6f76656164642052656d6f76652061206d656d626572206077686f602066726f6d20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d206052656d6f76654f726967696e60206f7220726f6f742e204164642061206d656d626572206077686f6020746f20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d20604164644f726967696e60206f7220726f6f742e496e7374616e6365314d656d6265727368697000000000000009b51200070000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a1300c00812000000000000000000d0081200010000000000000001000000000000009caf12000500000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a1300d80812000000000000000000e80812000100000000000000000000004200000000000000010000005900000019091200320000004200000000000000010000005b000000f008120029000000205468652063757272656e74207072696d65206d656d6265722c206966206f6e65206578697374732e205468652063757272656e74206d656d626572736869702c2073746f72656420617320616e206f726465726564205665632e00301a1300000000005c091200020000003a203a6865617070616765733a636f64653a6368616e6765735f74726965000000000000b5e111000f00000000000000080a12000200000000000000000000009be111001a00000000000000180a12000200000000000000000000007ee111001d00000000000000280a12000300000000000000000000006be111001300000000000000400a12000100000000000000000000005ce111000f00000000000000480a12000100000000000000c30b120045000000ae0b1200150000005d0b120051000000ae0b120015000000de0a12003c000000301a1300000000001a0b1200430000009e0a120040000000500a12004e0000002054686572652069732061206e6f6e2d7a65726f207265666572656e636520636f756e742070726576656e74696e6720746865206163636f756e742066726f6d206265696e67207075726765642e20537569636964652063616c6c6564207768656e20746865206163636f756e7420686173206e6f6e2d64656661756c7420636f6d706f7369746520646174612e204661696c656420746f2065787472616374207468652072756e74696d652076657273696f6e2066726f6d20746865206e65772072756e74696d652e204569746865722063616c6c696e672060436f72655f76657273696f6e60206f72206465636f64696e67206052756e74696d6556657273696f6e60206661696c65642e205468652073706563696669636174696f6e2076657273696f6e206973206e6f7420616c6c6f77656420746f206465637265617365206265747765656e207468652063757272656e742072756e74696d6520616e6420746865206e65772072756e74696d652e20546865206e616d65206f662073706563696669636174696f6e20646f6573206e6f74206d61746368206265747765656e207468652063757272656e742072756e74696d65280c120036000000ac0000000d000000280c120036000000dd000000110000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f6d656d626572736869702f7372632f6c69622e7273526571756972655375646f7375646f7365745f6b65797375646f5f61730000000000000d12000500000000000000080d1200010000000000000000000000100d1200010000000000000000000000180d12000a0000000000000074ad1200010000000000000000000000240d12000100000000000000000000002c0d12000a00000000000000380d1200010000000000000000000000100d120001000000000000005375646964000000940d12000e0000007c0d1200180000004b65794368616e6765640000400d12003c0000005375646f4173446f6e650000a1f512000400000020546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e4469737061746368526573756c74536f63696574794d61784d656d62657273566f7465734e6f74486561644e6f74466f756e6465724e6f7443616e646964617465416c726561647943616e646964617465416c7265616479426964466f756e646572486561644e6f74566f756368696e67416c7265616479566f756368696e67496e73756666696369656e74506f74416c7265616479466f756e6465644e6f5061796f75744e6f7453757370656e64656453757370656e646564416c72656164794d656d626572426164506f736974696f6e626964756e626964766f756368746970756e766f756368646566656e6465725f766f74657061796f7574666f756e64756e666f756e646a756467655f73757370656e6465645f6d656d6265726a756467655f73757370656e6465645f63616e6469646174657365745f6d61785f6d656d6265727300000000000070111200070000000000000074ad1200010000000000000000000000781112000100000000000000000000008011120003000000000000008411120002000000000000000000000094111200020000000000000000000000a41112000500000000000000ac111200030000000000000000000000c4111200020000000000000000000000d4111200090000000000000074ad1200010000000000000000000000e0111200010000000000000000000000e8111200050000000000000074ad1200010000000000000000000000f0111200010000000000000000000000f8111200070000000000000074ad1200010000000000000000000000001212000100000000000000000000000812120008000000000000001012120002000000000000000000000020121200020000000000000000000000301212001800000000000000481212000200000000000000000000005812120001000000000000000000000060121200120000000000000074ad1200010000000000000000000000741212000100000000000000000000007c1212000f0000000000000074ad12000100000000000000000000008c121200010000000000000000000000941212000a0000000000000074ad1200010000000000000000000000a0121200010000000000000000000000a81212000400000000000000ac121200030000000000000000000000c4121200010000000000000000000000cc1212000c0000000000000048121200020000000000000000000000d8121200010000000000000000000000e01212000d00000000000000f0121200010000000000000000000000f812120001000000000000000000000000131200090000000000000074ad12000100000000000000000000000c1312000100000000000000466f756e64656400641612002e0000004269640020af120009000000f615120007000000fd15120058000000551612000f000000566f75636800000020af120009000000f61512000700000020af1200090000006215120058000000ba1512003c0000004175746f556e6269640000002015120042000000556e626964000000f41412002c000000556e766f75636800b61412003e000000496e64756374656420af120009000000a81412000e00000035141200560000008b1412001d00000053757370656e6465644d656d6265724a756467656d656e7420af120009000000a1f5120004000000121412002300000043616e64696461746553757370656e6465640000f31312001f0000004d656d62657253757370656e64656400d71312001c0000004368616c6c656e6765640000ba1312001d000000566f746520af12000900000020af120009000000a1f51200040000008a13120030000000446566656e646572566f74654e1312003c0000004e65774d61784d656d6265727300000060dc1200030000002a13120024000000556e666f756e646564000000141312001600000020536f636965747920697320756e666f756e6465642e2041206e6577206d6178206d656d62657220636f756e7420686173206265656e20736574204120766f746520686173206265656e20706c6163656420666f72206120646566656e64696e67206d656d6265722028766f7465722c20766f746529204120766f746520686173206265656e20706c61636564202863616e6469646174652c20766f7465722c20766f7465292041206d656d62657220686173206265656e206368616c6c656e6765642041206d656d62657220686173206265656e2073757370656e64656420412063616e64696461746520686173206265656e2073757370656e64656420412073757370656e646564206d656d62657220686173206265656e206a756467656420412067726f7570206f662063616e646964617465732068617665206265656e20696e6475637465642e205468652062617463682773207072696d617279206973207468652066697273742076616c75652c2074686520626174636820696e2066756c6c20697320746865207365636f6e642e5665633c4163636f756e7449643e20412063616e646964617465207761732064726f70706564202862792072657175657374206f662077686f20766f756368656420666f72207468656d292e20412063616e646964617465207761732064726f70706564202862792074686569722072657175657374292e20412063616e646964617465207761732064726f70706564202864756520746f20616e20657863657373206f66206269647320696e207468652073797374656d292e2041206d656d6265727368697020626964206a7573742068617070656e656420627920766f756368696e672e2054686520676976656e206163636f756e74206973207468652063616e646964617465277320494420616e64207468656972206f6666657220697320746865207365636f6e642e2054686520766f756368696e67207061727479206973207468652074686972642e42616c616e63652041206d656d6265727368697020626964206a7573742068617070656e65642e2054686520676976656e206163636f756e74206973207468652063616e646964617465277320494420616e64207468656972206f6666657220697320746865207365636f6e642e2054686520736f636965747920697320666f756e6465642062792074686520676976656e206964656e746974792e5072656d61747572655374696c6c4f70656e4e6f7446696e646572556e6b6e6f776e546970416c72656164794b6e6f776e526561736f6e546f6f426967496e76616c696450726f706f73616c496e646578496e73756666696369656e7450726f706f7365727342616c616e636570726f706f73655f7370656e6472656a6563745f70726f706f73616c617070726f76655f70726f706f73616c7265706f72745f617765736f6d65726574726163745f7469707469705f6e6577636c6f73655f7469700000000054b11200080000000000000038191200010000000000000000000000401912000100000000000000000000004819120008000000000000005019120001000000000000000000000058191200010000000000000000000000601912000700000000000000681912000300000000000000000000008019120001000000000000000000000088191200080000000000000090191200020000000000000000000000a0191200010000000000000000000000a8191200050000000000000050191200010000000000000000000000b0191200010000000000000000000000b8191200080000000000000050191200010000000000000000000000c0191200010000000000000000000000c8191200070000000000000050191200010000000000000000000000d0191200010000000000000000000000d81912000600000000000000d4b11200010000000000000000000000e0191200010000000000000000000000e81912000a00000000000000d4b11200010000000000000000000000f4191200010000000000000000000000fc1912000900000000000000081a1200030000000000000000000000201a1200010000000000000000000000281a12000c00000000000000d4b11200010000000000000000000000341a1200010000000000000075b412000d000000f61b12000e0000005370656e64696e67f615120007000000bc1b12003a000000417761726465640075b412000d000000f61512000700000020af1200090000009c1b12002000000052656a656374656475b412000d000000f6151200070000006f1b12002d0000004275726e740000004c1b120023000000526f6c6c6f766572001b12004c0000004465706f73697400e01a1200200000004e65775469700000ba1a120026000000546970436c6f73696e670000831a120037000000546970436c6f73656400000089b212000400000020af120009000000f615120007000000611a1200220000005469705265747261637465643c1a1200250000002041207469702073756767657374696f6e20686173206265656e207265747261637465642e2041207469702073756767657374696f6e20686173206265656e20636c6f7365642e2041207469702073756767657374696f6e206861732072656163686564207468726573686f6c6420616e6420697320636c6f73696e672e2041206e6577207469702073756767657374696f6e20686173206265656e206f70656e65642e20536f6d652066756e64732068617665206265656e206465706f73697465642e205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20412070726f706f73616c207761732072656a65637465643b2066756e6473207765726520736c61736865642e20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e74206279207472656173757279506f74736f63696574795f726f746174696f6e43616e646964617465730000000000617474656d707420746f20646976696465206279207a65726f000000941d120033000000390600001d000000941d1200330000008d0400000f0000007061796f757473652e31206f662066696e616c206974656d203d3d20746f74616c5f617070726f76616c733b20776f72737420636173652066696e642077696c6c20616c776179732072657475726e2074686174206974656d3b207165640000941d120033000000840500001f00000042696473657869746564206966206d656d6265727320656d7074793b20716564941d120033000000a30500001f000000446566656e646572446566656e646572566f746573736f63696574795f6368616c6c656e67650000941d1200330000001a06000033000000941d1200330000001a0600001e0000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f736f63696574792f7372632f6c69622e7273537472696b657353757370656e6465644d656d626572730000941d120033000000c60500001e0000005061796f757473000000000000000000617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f000000941d120033000000940400000500000000000000690c12000400000000000000d01e1200010000000000000000000000e81e12000a00000000000000000000006d0c12000700000000000000381f1200010000000000000000000000501f1200090000000000000000000000740c12000700000000000000981f1200020000000000000000000000c81f12000b0000000000000000000000fbea1200040000000000000061d1120017000000872112004e000000301a13000000000098c9120034000000301a130000000000f5bd12000b00000085201200080000008d20120019000000a620120018000000be2012003200000044be12000c00000000000000842112000300000000000000f320120023000000162112005d000000301a13000000000098c9120034000000301a130000000000f5bd12000b00000085201200080000008d20120019000000732112001100000044be12000c00000000000000f02012000300000000000000f32012002300000000000000fbea1200040000000000000061d112001700000020201200540000007420120011000000301a13000000000098c9120034000000301a130000000000f5bd12000b00000085201200080000008d20120019000000a620120018000000be2012003200000044be12000c0000002041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d206120676976656e206163636f756e742e202d204f2831292e202d204c696d697465642073746f726167652072656164732e202d204f6e6520444220777269746520286576656e74292e202d20576569676874206f662064657269766174697665206063616c6c6020657865637574696f6e202b2031302c3030302e77686f3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263652041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e202d204f6e65204442206368616e67652e6e65772041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e5375646f00000000000000342212000300000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a1300382212000000000000000000482212000100000000000000010000004b6579004200000000000000010000000201000050221200210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e000000b4a21200390000009d0100001e000000b4a2120039000000fb01000029000000a422120048000000bb0100002d0000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f6f70732f61726974682e7273766563746f72207769746820706f736974697665206c656e6774682077696c6c20686176652061206d61783b20716564b4a2120039000000c5020000190000006974657261746f72207769746820706f736974697665206c656e6774682077696c6c20686176652061206d696e3b207165640000b4a2120039000000c902000019000000b4a2120039000000f40200001600000000000000660e1200030000000000000090251200010000000000000000000000a8251200210000000000000000000000690e12000500000000000000b0261200010000000000000000000000c82612001300000000000000000000006e0e1200050000000000000060271200030000000000000000000000a82712002c0000000000000000000000760e12000700000000000000b02612000100000000000000000000000829120011000000000000000000000014b01200040000000000000090291200020000000000000000000000c02912001300000000000000000000007d0e12000d00000000000000582a1200010000000000000000000000702a12001000000000000000000000008a0e12000600000000000000301a1300000000000000000000000000f02a1200140000000000000000000000900e12000500000000000000902b1200030000000000000000000000d82b1200130000000000000000000000950e12000700000000000000301a1300000000000000000000000000702c12000d00000000000000000000009c0e12001600000000000000d82c1200020000000000000000000000082d12001b0000000000000000000000b20e12001900000000000000e02d1200020000000000000000000000102e1200280000000000000000000000cb0e12000f00000000000000502f1200010000000000000000000000682f12000e0000000000000000000000aa4d12000500000000000000af4d12000f000000f94f120038000000301a130000000000315012004e0000007f5012003c000000301a13000000000098c9120034000000301a130000000000a3bd12000c000000bb50120056000000301a130000000000f5bd12000b00000011511200550000006749120011000000ec4912003b000000274a1200380000005f4a120037000000964a12003d0000007849120032000000d34a120012000000284b120060000000884b120040000000c84b1200170000000f4c12004b0000005a4c1200310000008b4c12001e000000a94c120027000000d04c120048000000184d12000a000000665112001a0000003a4d12003f000000301a130000000000794d12003100000044be12000c00000000000000f64f1200030000000000000060dc120003000000be4d120036000000f44d120040000000344e120021000000301a130000000000554e12003f000000301a130000000000944e120041000000301a130000000000a3bd12000c000000d54e120046000000301a130000000000f5bd12000b0000001b4f12002c000000474f1200430000008a4f1200510000002bc112000d000000301a130000000000db4f12001b00000044be12000c00000000000000f020120003000000000000007ac312000c00000000000000aa4d12000500000000000000af4d12000f00000000000000730e12000300000000000000af4d12000f000000f945120051000000301a1300000000004a461200550000009f46120057000000f646120050000000301a13000000000046471200560000009c47120054000000301a1300000000007b41120041000000301a130000000000a3bd12000c000000f047120033000000234812005400000077481200190000009048120052000000e248120045000000301a130000000000f5bd12000b000000274912004000000067491200110000007849120032000000aa49120042000000ec4912003b000000274a1200380000005f4a120037000000964a12003d000000d34a120012000000e54a120043000000284b120060000000884b120040000000c84b120017000000df4b1200300000000f4c12004b0000005a4c1200310000008b4c12001e000000a94c120027000000d04c120048000000184d12000a000000224d1200180000003a4d12003f000000301a130000000000794d12003100000044be12000c000000264412004b0000007144120025000000301a130000000000964412004a000000301a130000000000a3bd12000c000000e04412004b000000301a130000000000f5bd12000b0000002b451200150000004045120042000000824512003b000000bd451200250000002bc112000d000000301a130000000000e24512001700000044be12000c000000000000001d4412000900000000000000f320120023000000000000002bda12000700000000000000a1f5120004000000d042120022000000301a1300000000007b41120041000000301a130000000000a3bd12000c000000f242120043000000bc4112003d0000003543120036000000301a130000000000f5bd12000b0000006b4312002f0000003c421200470000009a43120016000000b04312004b000000834212002f0000002bc112000d000000301a130000000000fb4312002200000044be12000c000000000000002bda12000700000000000000a1f51200040000005841120023000000301a1300000000007b41120041000000301a130000000000a3bd12000c000000bc4112003d000000f941120029000000301a130000000000f5bd12000b000000224212001a0000003c42120047000000834212002f0000002bc112000d000000301a130000000000b24212001e00000044be12000c000000603e120051000000301a130000000000b13e12005a000000301a1300000000000b3f120048000000533f12001e000000301a130000000000713f120045000000b63f120013000000301a130000000000f5bd12000b000000c93f120047000000104012004900000059401200390000009240120039000000cb40120023000000ee40120044000000301a130000000000324112002600000044be12000c00000000000000493e120007000000000000007ac312000c00000000000000503e12000b0000000000000060dc120003000000000000005b3e12000500000000000000cc8d120007000000303c120013000000301a130000000000433c12003c0000007f3c120046000000301a130000000000c53c120047000000301a130000000000a3bd12000c0000000c3d120046000000523d120045000000973d12003d000000301a130000000000f5bd12000b000000d43d1200380000000c3e12003d0000002bc112000d000000301a130000000000e83012001700000044be12000c000000203b120023000000301a130000000000433b1200570000009a3b120056000000f03b120008000000301a130000000000f5bd12000b000000f83b12001a000000123c12001e0000002bc112000d000000301a130000000000e83012001700000044be12000c00000000000000f020120003000000000000007ac312000c00000000000000193b12000700000000000000a1f5120004000000603712004b000000301a130000000000ab371200560000000138120033000000301a13000000000034381200520000008638120040000000301a130000000000d832120050000000301a130000000000a3bd12000c000000c63812002d000000f33812004d0000004039120049000000301a130000000000f5bd12000b0000008939120029000000b23912003e000000f03912005c0000004c3a12003e0000008a3a120051000000bd36120035000000db3a12001c000000093712001f000000301a130000000000f73a12002200000044be12000c00000000000000f020120003000000000000007ac312000c000000000000004e37120009000000000000005737120009000000023112004d000000301a1300000000004f31120057000000a63112001d000000301a130000000000c3311200550000001832120044000000301a1300000000005c32120057000000b332120025000000301a130000000000d832120050000000301a130000000000a3bd12000c00000028331200300000005833120031000000301a130000000000f5bd12000b000000893312003d000000c63312003c0000000234120032000000343412001000000044341200450000008934120037000000c03412003a000000fa3412002d00000027351200280000004f3512002c0000007b35120053000000ce3512000f000000dd35120037000000143612004b0000005f3612000e0000006d36120050000000bd36120035000000f236120017000000093712001f000000301a130000000000283712002600000044be12000c00000000000000ff301200030000000000000060dc120003000000d82f1200470000001f3012002d000000301a1300000000004c30120037000000301a130000000000a3bd12000c0000008330120039000000301a130000000000f5bd12000b000000bc3012002c0000002bc112000d000000301a130000000000e83012001700000044be12000c00000020416c6c6f777320726f6f74206f726967696e20746f206368616e676520746865206d6178696d756d206e756d626572206f66206d656d6265727320696e20736f63696574792e204d6178206d656d6265727368697020636f756e74206d7573742062652067726561746572207468616e20312e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652066726f6d205f524f4f545f2e202d20606d617860202d20546865206d6178696d756d206e756d626572206f66206d656d6265727320666f722074686520736f63696574792e202d204f6e652073746f7261676520777269746520746f2075706461746520746865206d61782e204f28312920546f74616c20436f6d706c65786974793a204f2831296d617820416c6c6f772073757370656e646564206a756467656d656e74206f726967696e20746f206d616b65206a756467656d656e74206f6e20612073757370656e6465642063616e6469646174652e20496620746865206a756467656d656e742069732060417070726f7665602c20776520616464207468656d20746f20736f63696574792061732061206d656d62657220776974682074686520617070726f707269617465207061796d656e7420666f72206a6f696e696e6720736f63696574792e20496620746865206a756467656d656e74206973206052656a656374602c2077652065697468657220736c61736820746865206465706f736974206f6620746865206269642c20676976696e67206974206261636b20746f2074686520736f63696574792074726561737572792c206f722077652062616e2074686520766f75636865722066726f6d20766f756368696e6720616761696e2e20496620746865206a756467656d656e7420697320605265626964602c20776520707574207468652063616e646964617465206261636b20696e207468652062696420706f6f6c20616e64206c6574207468656d20676f207468726f7567682074686520696e64756374696f6e2070726f6365737320616761696e2e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652066726f6d20746865205f53757370656e73696f6e4a756467656d656e744f726967696e5f2e202d206077686f60202d205468652073757370656e6465642063616e64696461746520746f206265206a75646765642e202d20606a756467656d656e7460202d2060417070726f7665602c206052656a656374602c206f7220605265626964602e204b65793a204220286c656e206f662062696473292c204d20286c656e206f66206d656d62657273292c2058202862616c616e636520616374696f6e29202d204f6e652073746f72616765207265616420746f20636865636b206077686f6020697320612073757370656e6465642063616e6469646174652e202d204f6e652073746f726167652072656d6f76616c206f66207468652073757370656e6465642063616e6469646174652e202d20417070726f7665204c6f67696320092d204f6e652073746f72616765207265616420746f206765742074686520617661696c61626c6520706f7420746f2070617920757365727320776974682e204f28312920092d204f6e652073746f7261676520777269746520746f207570646174652074686520617661696c61626c6520706f742e204f28312920092d204f6e652073746f72616765207265616420746f20676574207468652063757272656e7420626c6f636b206e756d6265722e204f28312920092d204f6e652073746f72616765207265616420746f2067657420616c6c206d656d626572732e204f284d2920092d20557020746f206f6e6520756e726573657276652063757272656e637920616374696f6e2e20092d20557020746f2074776f206e65772073746f726167652077726974657320746f207061796f7574732e20092d20557020746f206f6e652073746f726167652077726974652077697468204f286c6f67204d292062696e6172792073656172636820746f206164642061206d656d62657220746f20736f63696574792e202d2052656a656374204c6f67696320092d20557020746f206f6e6520726570617472696174652072657365727665642063757272656e637920616374696f6e2e204f28582920092d20557020746f206f6e652073746f7261676520777269746520746f2062616e2074686520766f756368696e67206d656d6265722066726f6d20766f756368696e6720616761696e2e202d205265626964204c6f67696320092d2053746f72616765206d75746174652077697468204f286c6f672042292062696e6172792073656172636820746f20706c616365207468652075736572206261636b20696e746f20626964732e202d20557020746f206f6e65206164646974696f6e616c206576656e7420696620756e766f7563682074616b657320706c6163652e202d204f6e652073746f726167652072656d6f76616c2e202d204f6e65206576656e7420666f7220746865206a756467656d656e742e20546f74616c20436f6d706c65786974793a204f284d202b206c6f674d202b2042202b2058296a756467656d656e744a756467656d656e7420416c6c6f772073757370656e73696f6e206a756467656d656e74206f726967696e20746f206d616b65206a756467656d656e74206f6e20612073757370656e646564206d656d6265722e20496620612073757370656e646564206d656d62657220697320666f72676976656e2c2077652073696d706c7920616464207468656d206261636b2061732061206d656d6265722c206e6f7420616666656374696e6720616e79206f6620746865206578697374696e672073746f72616765206974656d7320666f722074686174206d656d6265722e20496620612073757370656e646564206d656d6265722069732072656a65637465642c2072656d6f766520616c6c206173736f6369617465642073746f72616765206974656d732c20696e636c7564696e67207468656972207061796f7574732c20616e642072656d6f766520616e7920766f7563686564206269647320746865792063757272656e746c7920686176652e202d206077686f60202d205468652073757370656e646564206d656d62657220746f206265206a75646765642e202d2060666f726769766560202d204120626f6f6c65616e20726570726573656e74696e672077686574686572207468652073757370656e73696f6e206a756467656d656e74206f726967696e202020202020202020202020202020666f726769766573202860747275656029206f722072656a6563747320286066616c7365602920612073757370656e646564206d656d6265722e204b65793a204220286c656e206f662062696473292c204d20286c656e206f66206d656d6265727329202d204f6e652073746f72616765207265616420746f20636865636b206077686f6020697320612073757370656e646564206d656d6265722e204f283129202d20557020746f206f6e652073746f72616765207772697465204f284d292077697468204f286c6f67204d292062696e6172792073656172636820746f206164642061206d656d626572206261636b20746f20736f63696574792e202d20557020746f20332073746f726167652072656d6f76616c73204f28312920746f20636c65616e20757020612072656d6f766564206d656d6265722e202d20557020746f206f6e652073746f72616765207772697465204f2842292077697468204f2842292073656172636820746f2072656d6f766520766f7563686564206269642066726f6d20626964732e202d204f6e652073746f726167652072656d6f76616c2e204f28312920546f74616c20436f6d706c65786974793a204f284d202b206c6f674d202b204229666f726769766520416e6e756c2074686520666f756e64696e67206f662074686520736f63696574792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205369676e65642c20616e6420746865207369676e696e67206163636f756e74206d75737420626520626f7468207468652060466f756e6465726020616e6420746865206048656164602e205468697320696d706c6965732074686174206974206d6179206f6e6c7920626520646f6e65207768656e207468657265206973206f6e65206d656d6265722e202d2054776f2073746f72616765207265616473204f2831292e202d20466f75722073746f726167652072656d6f76616c73204f2831292e20466f756e642074686520736f63696574792e205468697320697320646f6e65206173206120646973637265746520616374696f6e20696e206f7264657220746f20616c6c6f7720666f7220746865206d6f64756c6520746f20626520696e636c7564656420696e746f20612072756e6e696e6720636861696e20616e642063616e206f6e6c7920626520646f6e65206f6e63652e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652066726f6d20746865205f466f756e6465725365744f726967696e5f2e202d2060666f756e64657260202d20546865206669727374206d656d62657220616e642068656164206f6620746865206e65776c7920666f756e64656420736f63696574792e202d20606d61785f6d656d6265727360202d2054686520696e697469616c206d6178206e756d626572206f66206d656d6265727320666f722074686520736f63696574792e202d206072756c657360202d205468652072756c6573206f66207468697320736f636965747920636f6e6365726e696e67206d656d626572736869702e202d2054776f2073746f72616765206d75746174657320746f207365742060486561646020616e642060466f756e646572602e204f283129202d204f6e652073746f7261676520777269746520746f2061646420746865206669727374206d656d62657220746f20736f63696574792e204f283129666f756e6465726d61785f6d656d6265727372756c6573205472616e7366657220746865206669727374206d617475726564207061796f757420666f72207468652073656e64657220616e642072656d6f76652069742066726f6d20746865207265636f7264732e204e4f54453a20546869732065787472696e736963206e6565647320746f2062652063616c6c6564206d756c7469706c652074696d657320746f20636c61696d206d756c7469706c65206d617475726564207061796f7574732e205061796d656e743a20546865206d656d6265722077696c6c20726563656976652061207061796d656e7420657175616c20746f207468656972206669727374206d617475726564207061796f757420746f20746865697220667265652062616c616e63652e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642061206d656d6265722077697468207061796f7574732072656d61696e696e672e204b65793a204d20286c656e206f66206d656d62657273292c205020286e756d626572206f66207061796f75747320666f72206120706172746963756c6172206d656d62657229202d204f6e652073746f726167652072656164204f284d2920616e64204f286c6f67204d292073656172636820746f20636865636b207369676e65722069732061206d656d6265722e202d204f6e652073746f726167652072656164204f28502920746f2067657420616c6c207061796f75747320666f722061206d656d6265722e202d204f6e652073746f726167652072656164204f28312920746f20676574207468652063757272656e7420626c6f636b206e756d6265722e202d204f6e652063757272656e6379207472616e736665722063616c6c2e204f285829202d204f6e652073746f72616765207772697465206f722072656d6f76616c20746f2075706461746520746865206d656d6265722773207061796f7574732e204f28502920546f74616c20436f6d706c65786974793a204f284d202b206c6f674d202b2050202b2058292041732061206d656d6265722c20766f7465206f6e2074686520646566656e6465722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642061206d656d6265722e202d2060617070726f7665603a204120626f6f6c65616e2077686963682073617973206966207468652063616e6469646174652073686f756c6420626520617070726f766564202860747275656029206f722072656a656374656420286066616c736560292e202d204b65793a204d20286c656e206f66206d656d6265727329202d204f6e652073746f726167652072656164204f284d2920616e64204f286c6f67204d292073656172636820746f20636865636b20757365722069732061206d656d6265722e202d204f6e652073746f7261676520777269746520746f2061646420766f746520746f20766f7465732e204f28312920546f74616c20436f6d706c65786974793a204f284d202b206c6f674d292041732061206d656d6265722c20766f7465206f6e20612063616e6469646174652e202d206063616e646964617465603a205468652063616e646964617465207468617420746865206d656d62657220776f756c64206c696b6520746f20626964206f6e2e2020202020202020202020202020617070726f766564202860747275656029206f722072656a656374656420286066616c736560292e204b65793a204320286c656e206f662063616e64696461746573292c204d20286c656e206f66206d656d6265727329202d204f6e65206163636f756e74206c6f6f6b75702e202d204f6e652073746f726167652072656164204f28432920616e64204f2843292073656172636820746f20636865636b2074686174207573657220697320612063616e6469646174652e20546f74616c20436f6d706c65786974793a204f284d202b206c6f674d202b20432963616e646964617465204173206120766f756368696e67206d656d6265722c20756e766f7563682061206269642e2054686973206f6e6c7920776f726b73207768696c6520766f75636865642075736572206973206f6e6c792061206269646465722028616e64206e6f7420612063616e646964617465292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206120766f756368696e67206d656d6265722e202d2060706f73603a20506f736974696f6e20696e207468652060426964736020766563746f72206f6620746865206269642077686f2073686f756c6420626520756e766f75636865642e204b65793a204220286c656e206f66206269647329202d204f6e652073746f726167652072656164204f28312920746f20636865636b20746865207369676e6572206973206120766f756368696e67206d656d6265722e202d204f6e652073746f72616765206d757461746520746f20726574726965766520616e64207570646174652074686520626964732e204f284229202d204f6e6520766f756368696e672073746f726167652072656d6f76616c2e204f28312920546f74616c20436f6d706c65786974793a204f2842292041732061206d656d6265722c20766f75636820666f7220736f6d656f6e6520746f206a6f696e20736f636965747920627920706c6163696e67206120626964206f6e20746865697220626568616c662e205468657265206973206e6f206465706f73697420726571756972656420746f20766f75636820666f722061206e6577206269642c206275742061206d656d6265722063616e206f6e6c7920766f75636820666f72206f6e652062696420617420612074696d652e2049662074686520626964206265636f6d657320612073757370656e6465642063616e64696461746520616e6420756c74696d6174656c792072656a6563746564206279207468652073757370656e73696f6e206a756467656d656e74206f726967696e2c20746865206d656d6265722077696c6c2062652062616e6e65642066726f6d20766f756368696e6720616761696e2e204173206120766f756368696e67206d656d6265722c20796f752063616e20636c61696d206120746970206966207468652063616e6469646174652069732061636365707465642e2054686973207469702077696c6c2062652070616964206173206120706f7274696f6e206f66207468652072657761726420746865206d656d6265722077696c6c207265636569766520666f72206a6f696e696e672074686520736f63696574792e202d206077686f603a2054686520757365722077686f20796f7520776f756c64206c696b6520746f20766f75636820666f722e202d206076616c7565603a2054686520746f74616c2072657761726420746f2062652070616964206265747765656e20796f7520616e64207468652063616e6469646174652069662074686579206265636f6d652061206d656d62657220696e2074686520736f63696574792e202d2060746970603a20596f757220637574206f662074686520746f74616c206076616c756560207061796f7574207768656e207468652063616e64696461746520697320696e64756374656420696e746f2074686520736f63696574792e2054697073206c6172676572207468616e206076616c7565602077696c6c206265207361747572617465642075706f6e207061796f75742e204b65793a204220286c656e206f662062696473292c204320286c656e206f662063616e64696461746573292c204d20286c656e206f66206d656d6265727329202d2053746f726167652052656164733a20092d204f6e652073746f72616765207265616420746f20726574726965766520616c6c206d656d626572732e204f284d2920092d204f6e652073746f72616765207265616420746f20636865636b206d656d626572206973206e6f7420616c726561647920766f756368696e672e204f28312920092d204f6e652073746f72616765207265616420746f20636865636b20666f722073757370656e6465642063616e6469646174652e204f28312920092d204f6e652073746f72616765207265616420746f20636865636b20666f722073757370656e646564206d656d6265722e204f28312920092d204f6e652073746f72616765207265616420746f20726574726965766520616c6c2063757272656e7420626964732e204f28422920092d204f6e652073746f72616765207265616420746f20726574726965766520616c6c2063757272656e742063616e646964617465732e204f284329202d2053746f72616765205772697465733a20092d204f6e652073746f7261676520777269746520746f20696e7365727420766f756368696e672073746174757320746f20746865206d656d6265722e204f28312920092d204f6e652073746f72616765206d757461746520746f206164642061206e65772062696420746f2074686520766563746f72204f2842292028544f444f3a20706f737369626c65206f7074696d697a6174696f6e20772f20726561642920092d20557020746f206f6e652073746f726167652072656d6f76616c206966206269642e6c656e2829203e204d41585f4249445f434f554e542e204f283129202d204e6f7461626c6520436f6d7075746174696f6e3a20092d204f286c6f67204d292073656172636820746f20636865636b2073656e6465722069732061206d656d6265722e20092d204f2842202b2043202b206c6f67204d292073656172636820746f20636865636b2075736572206973206e6f7420616c726561647920612070617274206f6620736f63696574792e20092d204f286c6f672042292073656172636820746f20696e7365727420746865206e65772062696420736f727465642e202d2045787465726e616c204d6f64756c65204f7065726174696f6e733a20092d204f6e652062616c616e63652072657365727665206f7065726174696f6e2e204f28582920092d20557020746f206f6e652062616c616e636520756e72657365727665206f7065726174696f6e20696620626964732e6c656e2829203e204d41585f4249445f434f554e542e202d204576656e74733a20092d204f6e65206576656e7420666f7220766f7563682e20092d20557020746f206f6e65206576656e7420666f72204175746f556e626964206966206269642e6c656e2829203e204d41585f4249445f434f554e542e20546f74616c20436f6d706c65786974793a204f284d202b2042202b2043202b206c6f674d202b206c6f6742202b20582976616c756542616c616e63654f663c542c20493e2041206269646465722063616e2072656d6f76652074686569722062696420666f7220656e74727920696e746f20736f63696574792e20427920646f696e6720736f2c20746865792077696c6c20686176652074686569722063616e646964617465206465706f7369742072657475726e6564206f7220746865792077696c6c20756e766f75636820746865697220766f75636865722e205061796d656e743a2054686520626964206465706f73697420697320756e7265736572766564206966207468652075736572206d6164652061206269642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642061206269646465722e202d2060706f73603a20506f736974696f6e20696e207468652060426964736020766563746f72206f6620746865206269642077686f2077616e747320746f20756e6269642e204b65793a204220286c656e206f662062696473292c2058202862616c616e636520756e7265736572766529202d204f6e652073746f72616765207265616420616e6420777269746520746f20726574726965766520616e64207570646174652074686520626964732e204f284229202d20456974686572206f6e6520756e726573657276652062616c616e636520616374696f6e204f285829206f72206f6e6520766f756368696e672073746f726167652072656d6f76616c2e204f28312920546f74616c20436f6d706c65786974793a204f2842202b205829706f7320412075736572206f757473696465206f662074686520736f63696574792063616e206d616b6520612062696420666f7220656e7472792e205061796d656e743a206043616e6469646174654465706f736974602077696c6c20626520726573657276656420666f72206d616b696e672061206269642e2049742069732072657475726e6564207768656e2074686520626964206265636f6d65732061206d656d6265722c206f7220696620746865206269642063616c6c732060756e626964602e202d206076616c7565603a2041206f6e652074696d65207061796d656e74207468652062696420776f756c64206c696b6520746f2072656365697665207768656e206a6f696e696e672074686520736f63696574792e204b65793a204220286c656e206f662062696473292c204320286c656e206f662063616e64696461746573292c204d20286c656e206f66206d656d62657273292c2058202862616c616e636520726573657276652920092d204f6e65206576656e7420666f72206e6577206269642e00000000ef0d12000700000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a130018781200000000000000000000571200010000000000000000000000000000000857120005000000000000000000000091d912000700000000000000000000000000000000000000000000000000000000000000301a13001057120000000000000000002057120002000000000000000000000000000000611c12000a0000000000000000000000305712002700000000000000000000000000000000000000000000000000000000000000301a13001458120000000000000000005857120001000000000000000100000000000000605712001300000001050000000000007ac312000c00000000000000735712003900000000000000000000000000000000000000301a1300ac5712000000000000000000bc571200010000000000000000000000000000004e1c1200030000000000000000000000af4d12000f00000000000000000000000000000000000000000000000000000000000000301a1300c45712000000000000000000d457120001000000000000000100000000000000f60d12000400000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a1300187812000000000000000000dc5712000100000000000000000000000000000009b51200070000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a1300e45712000000000000000000f457120001000000000000000100000000000000ce1d12001000000001050000000000007ac312000c00000000000000a1f512000400000000000000000000000000000000000000301a1300fc57120000000000000000000c581200010000000000000001000000000000001c1d1200040000000000000000000000305712002700000000000000000000000000000000000000000000000000000000000000301a130014581200000000000000000024581200010000000000000001000000000000002c5812000800000001050000000000007ac312000c00000000000000345812000e00000000000000000000000000000000000000301a13004458120000000000000000005458120001000000000000000000000000000000f01d12000700000001050000000000007ac312000c000000000000005c5812002600000000000000000000000000000000000000301a13008458120000000000000000009458120001000000000000000100000000000000c71d12000700000001050000000000007ac312000c000000000000009c5812000b00000000000000000000000000000000000000301a1300587712000000000000000000a858120001000000000000000100000000000000b30d12000500000002050500000000007ac312000c000000000000007ac312000c00000000000000a81212000400000000000000301a1300c05812000000000000000000b0581200010000000000000000000000000000004c1d12000800000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a1300187812000000000000000000b858120001000000000000000000000000000000541d12000d00000001050000000000007ac312000c00000000000000a81212000400000000000000000000000000000000000000301a1300c05812000000000000000000d058120001000000000000000000000000000000a90d12000a000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a1300587712000000000000000000d8581200010000000000000001000000365c12001200000052756c65730000004200000000000000010000005b000000cd5b120054000000215c1200150000005665633c4269643c543a3a4163636f756e7449642c2042616c616e63654f663c542c20493e3e3e007f5b12004e00000053757370656e64656443616e646964617465732842616c616e63654f663c542c20493e2c204269644b696e643c543a3a4163636f756e7449642c2042616c616e63654f663c542c20493e3e294200000000000000010000005b0000005e5b1200210000004200000000000000010000005f0000000e5b120050000000d45a12003a00000042000000000000000100000059000000af5a1200250000004200000000000000010000005b000000915a12001e00000042000000000000000100000059000000575a12003a000000566f756368696e67566f756368696e6753746174757300004200000000000000010000005b0000001e5a1200390000005665633c28543a3a426c6f636b4e756d6265722c2042616c616e63654f663c542c20493e293e000042000000000000000100000059000000cb59120053000000537472696b65436f756e7400945912003700000060591200340000002f591200310000004200000000000000010000005b0000001759120018000000e05812003700000020546865206d6178206e756d626572206f66206d656d6265727320666f722074686520736f6369657479206174206f6e652074696d652e20566f74657320666f722074686520646566656e6465722e2054686520646566656e64696e67206d656d6265722063757272656e746c79206265696e67206368616c6c656e6765642e20446f75626c65206d61702066726f6d2043616e646964617465202d3e20566f746572202d3e20284d617962652920566f74652e20546865206f6e676f696e67206e756d626572206f66206c6f73696e6720766f746573206361737420627920746865206d656d6265722e2050656e64696e67207061796f7574733b206f72646572656420627920626c6f636b206e756d6265722c20776974682074686520616d6f756e7420746861742073686f756c642062652070616964206f75742e204d656d626572732063757272656e746c7920766f756368696e67206f722062616e6e65642066726f6d20766f756368696e6720616761696e205468652063757272656e7420626964732c2073746f726564206f726465726564206279207468652076616c7565206f6620746865206269642e2054686520736574206f662073757370656e646564206d656d626572732e205468652063757272656e7420736574206f66206d656d626572732c206f7264657265642e20546865206d6f7374207072696d6172792066726f6d20746865206d6f737420726563656e746c7920617070726f766564206d656d626572732e20416d6f756e74206f66206f7572206163636f756e742062616c616e63652074686174206973207370656369666963616c6c7920666f7220746865206e65787420726f756e642773206269642873292e2054686520736574206f662073757370656e6465642063616e646964617465732e205468652063757272656e7420736574206f662063616e646964617465733b206269646465727320746861742061726520617474656d7074696e6720746f206265636f6d65206d656d626572732e20412068617368206f66207468652072756c6573206f66207468697320736f636965747920636f6e6365726e696e67206d656d626572736869702e2043616e206f6e6c7920626520736574206f6e636520616e64206f6e6c792062792074686520666f756e6465722e20546865206669727374206d656d6265722e00000000d05d12001000000000000000af4d12000f00000000000000301a1300e05d12000000000000000000f05d1200010000000000000000000000f85d12001200000000000000af4d12000f00000000000000301a13000c5e120000000000000000001c5e12000200000000000000000000002c5e12000a0000000000000060dc12000300000000000000301a1300385e12000000000000000000485e1200020000000000000000000000585e12000b00000000000000af4d12000f00000000000000301a1300645e12000000000000000000745e12000100000000000000000000007c5e12000e0000000000000006cf12000e00000000000000301a13008c5e120000000000000000009c5e1200010000000000000000000000a45e12000f0000000000000006cf12000e00000000000000301a1300b45e12000000000000000000c45e1200010000000000000000000000cc5e12000800000000000000cc5e12000800000000000000301a1300d45e12000000000000000000e45e1200010000000000000043616e6469646174654465706f73697442000000000000000100000067000000c96012003f00000057726f6e6753696465446564756374696f6e000042000000000000000100000073000000446012005500000099601200300000004d6178537472696b6573000042000000000000000100000003010000c95f12005d000000266012001e000000506572696f645370656e6400420000000000000001000000040100007e5f12004b000000526f746174696f6e506572696f640000420000000000000001000000050100003a5f1200440000004368616c6c656e6765506572696f64004200000000000000010000006b000000065f1200340000004d6f64756c65496442000000000000000100000006010000ec5e12001a0000002054686520736f636965746965732773206d6f64756c6520696420546865206e756d626572206f6620626c6f636b73206265747765656e206d656d62657273686970206368616c6c656e6765732e20546865206e756d626572206f6620626c6f636b73206265747765656e2063616e6469646174652f6d656d6265727368697020726f746174696f6e20706572696f64732e2054686520616d6f756e74206f6620696e63656e7469766520706169642077697468696e206561636820706572696f642e20446f65736e277420696e636c75646520566f7465725469702e20546865206e756d626572206f662074696d65732061206d656d626572206d617920766f7465207468652077726f6e672077617920286f72206e6f7420617420616c6c2c207768656e207468657920617265206120736b657074696329206265666f72652074686579206265636f6d652073757370656e6465642e2054686520616d6f756e74206f662074686520756e70616964207265776172642074686174206765747320646564756374656420696e207468652063617365207468617420656974686572206120736b657074696320646f65736e277420766f7465206f7220736f6d656f6e6520766f74657320696e207468652077726f6e67207761792e20546865206d696e696d756d20616d6f756e74206f662061206465706f73697420726571756972656420666f7220612062696420746f206265206d6164652e00000000ff1612000d0000000000000068621200020000000000000000000000986212000900000000000000000000000c1712000f00000000000000e0621200010000000000000000000000f86212000700000000000000000000001b1712001000000000000000e0621200010000000000000000000000306312000800000000000000000000002b1712000e0000000000000070631200020000000000000000000000a0631200130000000000000000000000391712000b000000000000003864120001000000000000000000000050641200130000000000000000000000441712000700000000000000e864120003000000000000000000000030651200160000000000000000000000730e12000300000000000000e0651200020000000000000000000000106612001900000000000000000000004b171200090000000000000038641200010000000000000000000000d8661200110000000000000000000000aa4d12000500000000000000807512001500000000000000957512000b00000000000000f3201200230000006b7412004b000000b67412004d0000000375120015000000301a130000000000f5bd12000b000000e473120013000000187512002d000000457512003b00000044be12000c00000000000000607412000b000000000000009dd9120016000000a57312003f000000301a130000000000f5bd12000b000000e473120013000000f7731200340000002b7412003500000044be12000c000000d4721200570000002b7312002b000000301a130000000000f5bd12000b00000056731200140000006a731200240000008e7312001700000044be12000c00000000000000486f12000600000000000000cc8d12000700000000000000f020120003000000000000007ac312000c0000004371120057000000301a13000000000098c9120034000000301a1300000000009a71120055000000ef71120035000000301a130000000000ff6c120058000000576d1200170000006e6d12003b000000301a130000000000a96d12001e000000301a130000000000f5bd12000b000000247212003300000057721200250000007c72120031000000ad7212002700000044be12000c00000000000000a96c1200040000000000000091d91200070000004e6f120055000000301a130000000000a36f120038000000301a130000000000db6f1200540000002f701200510000008070120014000000301a130000000000be671200590000001768120058000000301a1300000000009470120024000000301a130000000000f5bd12000b000000ea95120015000000b870120037000000ef70120024000000137112003000000044be12000c00000000000000486f12000600000000000000cc8d12000700000000000000f020120003000000000000007ac312000c00000000000000ad6c12000900000000000000b66c12000c000000c26c12003d000000301a130000000000df69120055000000346a12001d000000301a130000000000ff6c120058000000576d1200170000006e6d12003b000000b76a1200540000000b6b120036000000301a130000000000a96d12001e000000301a130000000000f5bd12000b000000c76d1200550000001c6e1200300000004c6e1200420000008e6e120043000000d16e1200390000000a6f1200200000002a6f12001e00000044be12000c00000000000000a96c1200040000000000000091d912000700000000000000ad6c12000900000000000000b66c12000c000000b26912002d000000301a130000000000df69120055000000346a12001d000000301a130000000000be67120059000000516a120058000000a96a12000e000000b76a1200540000000b6b120036000000301a130000000000416b1200590000009a6b12000d000000301a130000000000f5bd12000b0000006f68120039000000a76b120045000000cf681200400000000f69120041000000301a130000000000ec6b120058000000446c120035000000796c12001d000000966c12001300000044be12000c0000006067120018000000301a13000000000098c9120034000000301a1300000000007867120046000000301a130000000000be671200590000001768120058000000301a130000000000f5bd12000b0000006f68120039000000a868120027000000cf681200400000000f69120041000000506912002b0000007b6912003700000044be12000c00000020436c6f736520616e64207061796f75742061207469702e2054686520746970206964656e74696669656420627920606861736860206d75737420686176652066696e69736865642069747320636f756e74646f776e20706572696f642e202d206068617368603a20546865206964656e74697479206f6620746865206f70656e2074697020666f722077686963682061207469702076616c7565206973206465636c617265642e205468697320697320666f726d65642020206173207468652068617368206f6620746865207475706c65206f6620746865206f726967696e616c207469702060726561736f6e6020616e64207468652062656e6566696369617279206163636f756e742049442e202d20436f6d706c65786974793a20604f285429602077686572652060546020697320746865206e756d626572206f6620746970706572732e2020206465636f64696e6720605469707065726020766563206f66206c656e677468206054602e202020605460206973206368617267656420617320757070657220626f756e6420676976656e2062792060436f6e7461696e734c656e677468426f756e64602e2020205468652061637475616c20636f737420646570656e6473206f6e2074686520696d706c656d656e746174696f6e206f662060543a3a54697070657273602e202d20446252656164733a206054697073602c206054697070657273602c20607469702066696e64657260202d2044625772697465733a2060526561736f6e73602c206054697073602c206054697070657273602c20607469702066696e64657260204465636c6172652061207469702076616c756520666f7220616e20616c72656164792d6f70656e207469702e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062652061206d656d626572206f662074686520605469707065727360207365742e2020206173207468652068617368206f6620746865207475706c65206f66207468652068617368206f6620746865206f726967696e616c207469702060726561736f6e6020616e64207468652062656e65666963696172792020206163636f756e742049442e202d20607469705f76616c7565603a2054686520616d6f756e74206f66207469702074686174207468652073656e64657220776f756c64206c696b6520746f20676976652e20546865206d656469616e2074697020202076616c7565206f662061637469766520746970706572732077696c6c20626520676976656e20746f20746865206077686f602e20456d6974732060546970436c6f73696e676020696620746865207468726573686f6c64206f66207469707065727320686173206265656e207265616368656420616e642074686520636f756e74646f776e20706572696f642068617320737461727465642e2020206465636f64696e6720605469707065726020766563206f66206c656e677468206054602c20696e736572742074697020616e6420636865636b20636c6f73696e672c20202041637475616c6c792077656967687420636f756c64206265206c6f77657220617320697420646570656e6473206f6e20686f77206d616e7920746970732061726520696e20604f70656e5469706020627574206974202020697320776569676874656420617320696620616c6d6f73742066756c6c20692e65206f66206c656e6774682060542d31602e202d20446252656164733a206054697070657273602c20605469707360202d2044625772697465733a20605469707360686173687469705f76616c756542616c616e63654f663c543e204769766520612074697020666f7220736f6d657468696e67206e65773b206e6f2066696e6465722773206665652077696c6c2062652074616b656e2e202d2060726561736f6e603a2054686520726561736f6e20666f722c206f7220746865207468696e6720746861742064657365727665732c20746865207469703b2067656e6572616c6c7920746869732077696c6c20626520202061205554462d382d656e636f6465642055524c2e202d206077686f603a20546865206163636f756e742077686963682073686f756c6420626520637265646974656420666f7220746865207469702e20456d69747320604e657754697060206966207375636365737366756c2e202d20436f6d706c65786974793a20604f2852202b2054296020776865726520605260206c656e677468206f662060726561736f6e602c2060546020697320746865206e756d626572206f6620746970706572732e2020202d20604f285429603a206465636f64696e6720605469707065726020766563206f66206c656e677468206054602020202020605460206973206368617267656420617320757070657220626f756e6420676976656e2062792060436f6e7461696e734c656e677468426f756e64602e20202020205468652061637475616c20636f737420646570656e6473206f6e2074686520696d706c656d656e746174696f6e206f662060543a3a54697070657273602e2020202d20604f285229603a2068617368696e6720616e6420656e636f64696e67206f6620726561736f6e206f66206c656e67746820605260202d20446252656164733a206054697070657273602c2060526561736f6e7360202d2044625772697465733a2060526561736f6e73602c20605469707360726561736f6e20526574726163742061207072696f72207469702d7265706f72742066726f6d20607265706f72745f617765736f6d65602c20616e642063616e63656c207468652070726f63657373206f662074697070696e672e204966207375636365737366756c2c20746865206f726967696e616c206465706f7369742077696c6c20626520756e72657365727665642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642074686520746970206964656e74696669656420627920606861736860206d7573742068617665206265656e207265706f7274656420627920746865207369676e696e67206163636f756e74207468726f75676820607265706f72745f617765736f6d65602028616e64206e6f74207468726f75676820607469705f6e657760292e20456d697473206054697052657472616374656460206966207375636365737366756c2e2020202d20446570656e6473206f6e20746865206c656e677468206f662060543a3a48617368602077686963682069732066697865642e202d20446252656164733a206054697073602c20606f726967696e206163636f756e7460202d2044625772697465733a2060526561736f6e73602c206054697073602c20606f726967696e206163636f756e7460205265706f727420736f6d657468696e672060726561736f6e60207468617420646573657276657320612074697020616e6420636c61696d20616e79206576656e7475616c207468652066696e6465722773206665652e205061796d656e743a20605469705265706f72744465706f73697442617365602077696c6c2062652072657365727665642066726f6d20746865206f726967696e206163636f756e742c2061732077656c6c20617320605469705265706f72744465706f736974506572427974656020666f722065616368206279746520696e2060726561736f6e602e202d20436f6d706c65786974793a20604f2852296020776865726520605260206c656e677468206f662060726561736f6e602e2020202d20656e636f64696e6720616e642068617368696e67206f662027726561736f6e27202d20446252656164733a2060526561736f6e73602c206054697073602c206077686f206163636f756e74206461746160202d2044625772697465733a206054697073602c206077686f206163636f756e7420646174616020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e202d20436f6d706c65786974793a204f2831292e202d20446252656164733a206050726f706f73616c73602c2060417070726f76616c7360202d20446257726974653a2060417070726f76616c73602052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e202d20436f6d706c65786974793a204f283129202d20446252656164733a206050726f706f73616c73602c206072656a65637465642070726f706f736572206163636f756e7460202d2044625772697465733a206050726f706f73616c73602c206072656a65637465642070726f706f736572206163636f756e746070726f706f73616c5f69642050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d20446252656164733a206050726f706f73616c436f756e74602c20606f726967696e206163636f756e7460202d2044625772697465733a206050726f706f73616c436f756e74602c206050726f706f73616c73602c20606f726967696e206163636f756e7460436f6d706163743c42616c616e63654f663c543e3e62656e6566696369617279000000000ef812000d000000000000000000000075b412000d00000000000000000000000000000000000000000000000000000000000000301a1300587712000000000000000000687712000100000000000000010000000000000000b5120009000000010500000000000075b412000d00000000000000707712002400000000000000000000000000000000000000301a1300947712000000000000000000a4771200010000000000000000000000000000001bf81200090000000000000000000000ac7712001200000000000000000000000000000000000000000000000000000000000000301a1300c07712000000000000000000d077120001000000000000000100000000000000d877120004000000010500000000000091d912000700000000000000dc7712003c00000000000000000000000000000000000000301a130018781200000000000000000028781200030000000000000000000000000000004078120007000000010600000000000091d912000700000000000000cc8d12000700000000000000000000000000000000000000301a13004878120000000000000000005878120002000000000000000000000042000000000000000100000057000000347a12002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e4200000000000000010000005b000000157a12001f0000005665633c50726f706f73616c496e6465783e000042000000000000000100000059000000d77912003e000000546970734f70656e5469703c543a3a4163636f756e7449642c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265722c20543a3a486173683e4200000000000000010000005b0000001279120056000000687912004f000000b779120020000000526561736f6e7300420000000000000001000000f60000006878120052000000ba781200580000002053696d706c6520707265696d616765206c6f6f6b75702066726f6d2074686520726561736f6e2773206861736820746f20746865206f726967696e616c20646174612e20416761696e2c2068617320616e20696e73656375726520656e756d657261626c6520686173682073696e636520746865206b65792069732067756172616e7465656420746f2062652074686520726573756c74206f6620612073656375726520686173682e2054697073207468617420617265206e6f742079657420636f6d706c657465642e204b65796564206279207468652068617368206f66206028726561736f6e2c2077686f29602066726f6d207468652076616c75652e2054686973206861732074686520696e73656375726520656e756d657261626c6520686173682066756e6374696f6e2073696e636520746865206b657920697473656c6620697320616c72656164792067756172616e7465656420746f20626520612073656375726520686173682e2050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e00000000000000587c12000c00000000000000647c12000700000000000000301a13006c7c120000000000000000007c7c12000200000000000000000000008c7c12001300000000000000b66c12000c00000000000000301a13003c7d12000000000000000000a07c1200010000000000000000000000a87c12000b0000000000000006cf12000e00000000000000301a1300e47c12000000000000000000b47c1200010000000000000000000000bc7c12000400000000000000647c12000700000000000000301a1300c07c12000000000000000000d07c1200010000000000000000000000d87c12000c0000000000000006cf12000e00000000000000301a1300e47c12000000000000000000f47c1200010000000000000000000000fc7c12000d00000000000000097d12000700000000000000301a1300107d12000000000000000000207d1200010000000000000000000000287d12001400000000000000b66c12000c00000000000000301a13003c7d120000000000000000004c7d1200010000000000000000000000547d12001700000000000000b66c12000c00000000000000301a13006c7d120000000000000000007c7d1200010000000000000000000000cc5e12000800000000000000cc5e12000800000000000000301a1300847d12000000000000000000947d1200010000000000000050726f706f73616c426f6e645065726d696c6c0042000000000000000100000007010000ae7f120055000000038012004400000050726f706f73616c426f6e644d696e696d756d005c7f1200520000005370656e64506572696f64003a7f1200220000004275726e42000000000000000100000008010000f67e120044000000546970436f756e74646f776e42000000000000000100000009010000a57e12005100000054697046696e6465727346656550657263656e744200000000000000010000000a010000597e12004c0000005469705265706f72744465706f7369744261736542000000000000000100000068000000247e1200350000005469705265706f72744465706f736974506572427974650042000000000000000100000084000000e27d1200420000004200000000000000010000000b0100009c7d120046000000205468652074726561737572792773206d6f64756c652069642c207573656420666f72206465726976696e672069747320736f7665726569676e206163636f756e742049442e2054686520616d6f756e742068656c64206f6e206465706f7369742070657220627974652077697468696e2074686520746970207265706f727420726561736f6e2e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220706c6163696e67206120746970207265706f72742e2054686520616d6f756e74206f66207468652066696e616c2074697020776869636820676f657320746f20746865206f726967696e616c207265706f72746572206f6620746865207469702e2054686520706572696f6420666f722077686963682061207469702072656d61696e73206f70656e20616674657220697320686173206163686965766564207468726573686f6c6420746970706572732e2050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e74686520636f6e74726163742065786973747320616e6420696e2074686520616c6976652073746174653b0a090974686520757064617465642062616c616e6365206d7573742062652067726561746572207468616e2073756273697374656e6365206465706f7369743b0a0909746869732066756e6374696f6e20646f65736e27742072657475726e20604e6f6e65603b0a09097165640a09090000f48012003600000074010000170000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f636f6e7472616374732f7372632f72656e742e72730000941d120033000000bd0500002b0000005c8112003400000070020000180000005c811200340000009c0200001a0000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f74726561737572792f7372632f6c69622e7273000000005e0c12000b00000000000000ac8112000100000000000000b4811200200000002053656e646572206d75737420626520746865205375646f206163636f756e74696e636f7272656374206964656e746974796e6f7420766f7563686564000000941d120033000000ac04000035000000622e6c656e2829203e20313030303b2071656400941d120033000000c80400003100000000000000e31612001c0000000000000008831200010000000000000000000000cf161200140000000000000010831200010000000000000000000000c31612000c0000000000000018831200010000000000000000000000b71612000c0000000000000020831200010000000000000000000000ad1612000a0000000000000028831200010000000000000000000000a41612000900000000000000308312000100000000000000000000009b161200090000000000000038831200010000000000000000000000921612000900000000000000408312000100000000000000a18412001f000000868412001b000000648412002200000041841200230000002884120019000000e083120048000000958312004b000000488312004d00000020546865207469702063616e6e6f7420626520636c61696d65642f636c6f73656420626563617573652069742773207374696c6c20696e2074686520636f756e74646f776e20706572696f642e20546865207469702063616e6e6f7420626520636c61696d65642f636c6f736564206265636175736520746865726520617265206e6f7420656e6f7567682074697070657273207965742e20546865206163636f756e7420617474656d7074696e6720746f20726574726163742074686520746970206973206e6f74207468652066696e646572206f6620746865207469702e2054686520746970206861736820697320756e6b6e6f776e2e20546865207469702077617320616c726561647920666f756e642f737461727465642e2054686520726561736f6e20676976656e206973206a75737420746f6f206269672e204e6f2070726f706f73616c206174207468617420696e6465782e2050726f706f73657227732062616c616e636520697320746f6f206c6f772e000000005b0e12000b00000000000000b8861200010000000000000000000000f2af12000900000000000000c08612000100000000000000000000004e0e12000d00000000000000c8861200010000000000000000000000450e12000900000000000000d0861200010000000000000000000000390e12000c00000000000000d8861200010000000000000000000000310e12000800000000000000e0861200010000000000000000000000230e12000e00000000000000e8861200010000000000000000000000140e12000f00000000000000f0861200010000000000000000000000050e12000f00000000000000f8861200010000000000000000000000fa0d12000b0000000000000000871200010000000000000000000000f60d1200040000000000000008871200010000000000000000000000ef0d1200070000000000000010871200010000000000000000000000e50d12000a0000000000000018871200010000000000000000000000d50d1200100000000000000020871200010000000000000000000000c90d12000c0000000000000028871200010000000000000000000000a90d12000a0000000000000030871200010000000000000000000000bf0d12000a0000000000000038871200010000000000000000000000b80d1200070000000000000040871200010000000000000036891200240000002089120016000000068912001a000000f388120013000000dc88120017000000c988120013000000b08812001900000089881200270000004f8812003a00000037881200180000001288120025000000f78712001b000000da8712001d000000bd8712001d000000a4871200190000008387120021000000648712001f000000488712001c000000205468652063616c6c6572206973206e6f742074686520686561642e205468652063616c6c6572206973206e6f742074686520666f756e6465722e20546f6f206d616e79206d656d6265727320696e2074686520736f63696574792e2055736572206973206e6f7420612063616e6469646174652e205573657220697320616c726561647920612063616e6469646174652e20557365722068617320616c7265616479206d6164652061206269642e2043616e6e6f742072656d6f76652074686520666f756e6465722e2043616e6e6f742072656d6f7665207468652068656164206f662074686520636861696e2e204d656d626572206973206e6f7420766f756368696e672e204d656d62657220697320616c726561647920766f756368696e67206f722062616e6e65642066726f6d20766f756368696e6720616761696e2e204e6f7420656e6f75676820696e20706f7420746f206163636570742063616e6469646174652e20536f636965747920616c726561647920666f756e6465642e204e6f7468696e6720746f207061796f75742e2055736572206973206e6f742073757370656e6465642e20557365722069732073757370656e6465642e205573657220697320616c72656164792061206d656d6265722e2055736572206973206e6f742061206d656d6265722e20416e20696e636f727265637420706f736974696f6e207761732070726f76696465642e546f6f536f6f6e4368616e676550656e64696e67526573756d654661696c656450617573654661696c65647265706f72745f6d69736265686176696f723a6772616e6470615f617574686f7269746965734e6f4b6579734475706c6963617465644b65794e6f4173736f63696174656456616c696461746f724964496e76616c696450726f6f667365745f6b65797370757267655f6b65797356616c696461746f7273666f726b2e726563656e746c792065786563757465642e4200000000000000010000000c0100000d0100000e0100000f0100001001000011010000656e74697265206e65775f7365742077617320676976656e20746f206275696c645f737570706f72745f6d61703b20656e20656e747279206d757374206265206372656174656420666f722065616368206974656d3b207165640000a48a12003e000000eb020000230000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f656c656374696f6e732d70687261676d656e2f7372632f6c69622e7273000042000000000000000100000064000000756e636c6573303066696e616c6e756d6e6f7420656e6f7567682067617320746f20706179207472616e736665722066656562616c616e636520746f6f206c6f7720746f2073656e642076616c756576616c756520746f6f206c6f7720746f20637265617465206163636f756e746272696e67732073656e6465722062656c6f77206578697374656e7469616c206465706f73697464657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c756550656e64696e674368616e676553746174655175657565644b6579735374616c6c6564000000420000000800000004000000120100001301000000000000000000001401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e657874466f726365644e6578744b6579730000188d12004500000075000000450000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f737570706f72742f7372632f73746f726167652f67656e657261746f722f6d61702e7273000000000000008589120012000000000000008c8d1200010000000000000000000000a48d1200010000000000000000000000c58d12000700000000000000cc8d120007000000ac8d120019000000205265706f727420736f6d65206d69736265686176696f722e5f7265706f72745665633c75383e0000000000c38b1200050000000000000000000000e48f12001b00000000000000000000000000000000000000000000000000000000000000301a13000090120000000000000000001090120001000000000000000100000000000000b68b12000d0000000000000000000000189012002300000000000000000000000000000000000000000000000000000000000000301a1300389a120000000000000000003c90120001000000000000000000000000000000f48c12000a000000000000000000000006cf12000e00000000000000000000000000000000000000000000000000000000000000301a1300ac90120000000000000000004490120001000000000000000000000000000000d28b12000700000000000000000000004c9012002000000000000000000000000000000000000000000000000000000000000000301a13006c90120000000000000000007c901200010000000000000000000000000000009cf312000c0000000000000000000000849012000500000000000000000000000000000000000000000000000000000000000000301a13008c90120000000000000000009c90120002000000000000000100000000000000b7f312000c000000010500000000000084901200050000000000000097f612000c00000000000000000000000000000000000000301a1300ac9012000000000000000000bc90120002000000000000000000000053746f72656453746174653c543a3a426c6f636b4e756d6265723e0042000000000000000100000015010000489212002400000053746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723e001792120031000000e89112002f00000028543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d6265722942000000000000000100000085000000c49112002400000053657449640000004200000000000000010000006e0000003c9112005700000093911200310000004200000000000000010000005b000000cc90120056000000229112001a0000002041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f7220776869636820697473206d656d62657273207765726520726573706f6e7369626c652e20546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c69746965732920696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e20607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e00000000e18912000800000000000000c4921200020000000000000000000000f49212000e0000000000000000000000e98912000a00000000000000301a1300000000000000000000000000649312000c0000000000000000000000a79612000400000000000000ab9612000700000000000000b29612000500000000000000cc8d120007000000689512003a000000a295120048000000f793120031000000301a1300000000002894120035000000301a130000000000f5bd12000b000000ea951200150000008a94120056000000ff9512003c0000003b961200290000006496120021000000859612002200000044be12000c000000c493120033000000f793120031000000301a1300000000002894120035000000301a130000000000f5bd12000b0000005d9412002d0000008a94120056000000e09412003c0000001c95120029000000459512002300000044be12000c0000002052656d6f76657320616e792073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c65722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d20436f6d706c65786974793a20604f2831296020696e206e756d626572206f66206b65792074797065732e20202041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f662060543a3a4b6579733a3a6b65795f6964732829602077686963682069732066697865642e202d20446252656164733a2060543a3a56616c696461746f7249644f66602c20604e6578744b657973602c20606f726967696e206163636f756e7460202d2044625772697465733a20604e6578744b657973602c20606f726967696e206163636f756e7460202d20446257726974657320706572206b65792069643a20604b65794f776e646572602053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b657973602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e202d20436f6d706c65786974793a20604f28312960202d20446252656164733a20606f726967696e206163636f756e74602c2060543a3a56616c696461746f7249644f66602c20604e6578744b65797360202d2044625772697465733a20606f726967696e206163636f756e74602c20604e6578744b65797360202d204462526561647320706572206b65792069643a20604b65794f776e657260202d20446257726974657320706572206b65792069643a20604b65794f776e6572606b657973543a3a4b65797370726f6f660000000000f38912000a0000000000000000000000209912001300000000000000000000000000000000000000000000000000000000000000301a13003499120000000000000000004499120001000000000000000100000000000000a5f512000c000000000000000000000097f612000c00000000000000000000000000000000000000000000000000000000000000301a13004c99120000000000000000005c99120001000000000000000100000000000000b1f512000d0000000000000000000000a1f512000400000000000000000000000000000000000000000000000000000000000000301a13006499120000000000000000007499120002000000000000000100000000000000c88b12000a0000000000000000000000849912001e00000000000000000000000000000000000000000000000000000000000000301a1300a49912000000000000000000b499120002000000000000000100000000000000bef51200120000000000000000000000c49912000800000000000000000000000000000000000000000000000000000000000000301a1300cc9912000000000000000000dc99120003000000000000000100000000000000fe8c1200080000000105000000000000f49912000e00000000000000ab9612000700000000000000000000000000000000000000301a1300049a12000000000000000000149a1200010000000000000000000000000000001c9a1200080000000105000000000000249a12001400000000000000f49912000e00000000000000000000000000000000000000301a1300389a12000000000000000000489a12000100000000000000000000005665633c543a3a56616c696461746f7249643e0042000000000000000100000059000000429c12001f00000042000000000000000100000057000000249c12001e0000004200000000000000010000005b000000ad9b12004e000000fb9b1200290000005665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e000042000000000000000100000059000000269b12004f000000759b1200380000005665633c7533323e42000000000000000100000059000000b99a120020000000301a130000000000d99a12004d000000543a3a56616c696461746f72496400004200000000000000010000005b000000929a1200270000004b65794f776e6572284b65795479706549642c205665633c75383e294200000000000000010000005b000000509a12004200000020546865206f776e6572206f662061206b65792e20546865206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e20496e6469636573206f662064697361626c65642076616c696461746f72732e205468652073657420697320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e732061206e657720736574206f66206964656e7469746965732e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f727320686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e000000749c12003a00000033000000120000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f72756e74696d652f7372632f63757276652e727372656163686564206d6178696d756d2064657074682c2063616e6e6f7420696e7374616e7469617465001601000018000000040000001701000018010000190100001a0100001b0100001c010000696e73756666696369656e742072656d61696e696e672062616c616e63656e6f7420656e6f7567682067617320746f20706179206261736520696e7374616e74696174652066656572656163686564206d6178696d756d2064657074682c2063616e6e6f74206d616b6520612063616c6c6e6f7420656e6f7567682067617320746f2070617920626173652063616c6c20666565636f6e747261637420686173206265656e20657669637465646d656d6f727976616c69646174696f6e3a20696d706f727420656e74727920706f696e747320746f2061206e6f6e2d6578697374656e74207479706543616e6e6f7420696d706f727420676c6f62616c736d6f64756c6520696d706f7274732061206e6f6e2d6578697374656e742066756e6374696f6e6d6f64756c6520696d706f72747320606578745f7072696e746c6e60206275742064656275672066656174757265732064697361626c656443616e6e6f7420696d706f7274207461626c65736d6f64756c652068617320696d706f7274732066726f6d2061206e6f6e2d27656e7627206e616d6573706163654d656d6f727920696d706f7274206d757374206861766520746865206669656c64206e616d6520276d656d6f7279274d756c7469706c65206d656d6f727920696d706f72747320646566696e65644d6178696d756d206e756d626572206f662070616765732073686f756c6420626520616c77617973206465636c617265642e52657175657374656420696e697469616c206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520726571756573746564206d6178696d756d4d6178696d756d206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520636f6e66696775726564206d6178696d756d2e00000000007a8912000b0000000000000014a012000200000000000000000000006e8912000c0000000000000024a01200020000000000000000000000618912000d0000000000000034a012000100000000000000000000005a89120007000000000000003ca0120001000000000000001da11200420000005fa112002a000000afa0120045000000f4a012002900000074a012003b00000044a01200300000002043616e6e6f74207369676e616c20666f72636564206368616e676520736f20736f6f6e206166746572206c6173742e20417474656d707420746f207369676e616c204752414e445041206368616e67652077697468206f6e6520616c72656164792070656e64696e672e20417474656d707420746f207369676e616c204752414e44504120726573756d65207768656e2074686520617574686f72697479207365742069736e2774207061757365642028656974686572206c697665206f7220616c72656164792070656e64696e6720726573756d65292e20417474656d707420746f207369676e616c204752414e445041207061757365207768656e2074686520617574686f72697479207365742069736e2774206c697665202865697468657220706175736564206f7220616c72656164792070656e64696e67207061757365292e00000000000000d58912000c00000000000000fca11200010000000000000000000000be891200170000000000000004a21200010000000000000000000000b18912000d000000000000000ca21200010000000000000000000000ab891200060000000000000014a21200010000000000000088a212001900000060a212002800000046a212001a0000001ca212002a000000204e6f206b65797320617265206173736f63696174656420776974682074686973206163636f756e742e2052656769737465726564206475706c6963617465206b65792e204e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e20496e76616c6964206f776e6572736869702070726f6f662e000000b4a212003900000077010000330000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f70687261676d656e2f7372632f6c69622e72734469676573744974656d206e6f7420657175616c5468657265206973206f6e6c79206f6e6520666174616c206572726f723b20716564004200000008000000040000001d010000a2a3120036000000a0020000010000004e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f7221496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473212f686f6d652f6461766964642f6465762f7375627374726174652f62696e2f6e6f64652f72756e74696d652f7372632f6c69622e7273417574686f724f6c64556e636c65556e636c65416c7265616479496e636c75646564546f6f48696768556e636c6547656e65736973556e636c65546f6f4d616e79556e636c6573556e636c6573416c7265616479536574496e76616c6964556e636c65506172656e747365745f756e636c6573005ca412006a000000910000000d0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e332e302f7372632f656e636f64655f617070656e642e727350726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b2071656400000000000000000000000010a512003d000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656400000000000000000000000000000000000000556e636c657300000000000041a412000a0000000000000094a51200010000000000000000000000aca51200010000000000000000000000cda512000a00000000000000d7a512000e000000b4a51200190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e0000000000000060a51200060000000000000000000000f0a612003a00000000000000000000000000000000000000000000000000000000000000301a13002ca7120000000000000000003ca7120001000000000000000100000000000000d8a312000600000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a130044a71200000000000000000054a71200010000000000000000000000000000009de812000c0000000000000000000000a1f512000400000000000000000000000000000000000000000000000000000000000000301a13005ca7120000000000000000006ca712000100000000000000010000005665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e000042000000000000000100000059000000bca71200070000004200000000000000010000005b000000a3a71200190000004200000000000000010000005b00000074a712002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c6573000100000001000000000000000000000000000000010000004ca8120045000000c1030000220000004ca8120045000000dd030000150000004ca8120045000000eb0300001e0000004ca8120045000000f4030000180000004ca8120045000000f5030000190000004ca8120045000000f80300001a0000004ca8120045000000fe0300000d0000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962616c6c6f632f736c6963652e7273000000000000002fa41200120000000000000058a912000100000000000000000000001fa41200100000000000000060a9120001000000000000000000000012a412000d0000000000000068a9120001000000000000000000000006a412000c0000000000000070a91200010000000000000000000000faa312000c0000000000000078a91200010000000000000000000000e6a31200140000000000000080a91200010000000000000000000000dea31200080000000000000088a91200010000000000000045aa12002300000024aa12002100000013aa120011000000fda9120016000000dda9120020000000bea912001f00000090a912002e0000002054686520756e636c652069736e277420726563656e7420656e6f75676820746f20626520696e636c756465642e2054686520756e636c6520697320616c726561647920696e636c756465642e2054686520756e636c6520697320746f6f206869676820696e20636861696e2e2054686520756e636c652069732067656e657369732e20546f6f206d616e7920756e636c65732e20556e636c657320616c72656164792073657420696e2074686520626c6f636b2e2054686520756e636c6520706172656e74206e6f7420696e2074686520636861696e2e70aa12002a000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a200000a4aa1200230000005f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e496e7374616e636532436f6c6c656374697665496e7374616e636531436f6c6c656374697665000000f8aa120023000000605f5f49676e6f7265602063616e206e6576657220626520636f6e7374727563746564416c726561647950726f78794f766572666c6f775374696c6c4163746976655468726573686f6c64416c7265616479566f756368656444656c6179506572696f644e6f74467269656e644e6f7453746172746564416c726561647953746172746564416c72656164795265636f76657261626c654e6f745265636f76657261626c654e6f74536f727465644d6178467269656e64734e6f74456e6f756768467269656e64735a65726f5468726573686f6c644e6f74416c6c6f77656461735f7265636f76657265647365745f7265636f76657265646372656174655f7265636f76657279696e6974696174655f7265636f76657279766f7563685f7265636f76657279636c61696d5f7265636f76657279636c6f73655f7265636f7665727972656d6f76655f7265636f7665727963616e63656c5f7265636f76657265640000000000000064ad12000f0000000000000074ad12000100000000000000000000007cad120001000000000000000000000084ad1200110000000000000098ad1200020000000000000000000000a8ad1200010000000000000000000000b0ad12000f00000000000000c0ad1200030000000000000000000000d8ad1200010000000000000000000000e0ad12000e0000000000000098ad1200020000000000000000000000f0ad1200010000000000000000000000f8ad1200100000000000000098ad120002000000000000000000000008ae120001000000000000000000000010ae12000f0000000000000074ad120001000000000000000000000020ae120001000000000000005265636f76657279437265617465640020af1200090000006aaf1200320000005265636f76657279496e6974696174656400000020af12000900000020af12000900000029af1200410000005265636f76657279566f75636865640020af12000900000020af12000900000020af120009000000d0ae1200500000005265636f76657279436c6f736564000092ae12003e0000004163636f756e745265636f76657265645bae1200370000005265636f7665727952656d6f7665640028ae1200330000002041207265636f766572792070726f6365737320686173206265656e2072656d6f76656420666f7220616e206163636f756e74204163636f756e745f3120686173206265656e207375636365737366756c6c79207265636f7665726564206279206163636f756e745f322041207265636f766572792070726f6365737320666f72206163636f756e745f31206279206163636f756e745f3220686173206265656e20636c6f7365642041207265636f766572792070726f6365737320666f72206163636f756e745f31206279206163636f756e745f3220686173206265656e20766f756368656420666f72206279206163636f756e745f334163636f756e7449642041207265636f766572792070726f6365737320686173206265656e20696e6974696174656420666f72206163636f756e745f31206279206163636f756e745f322041207265636f766572792070726f6365737320686173206265656e2073657420757020666f7220616e206163636f756e745072696d65546f6f4561726c79416c7265616479496e697469616c697a65644475706c6963617465566f746557726f6e67496e64657850726f706f73616c4d697373696e674475706c696361746550726f706f73616c4e6f744d656d6265727365745f6d656d626572736578656375746570726f706f7365766f7465636c6f73650000000000000054b1120008000000000000005cb112000400000000000000000000007cb112000200000000000000000000008cb11200050000000000000094b11200050000000000000000000000bcb11200020000000000000000000000ccb112000800000000000000d4b11200010000000000000000000000dcb11200010000000000000000000000e4b112000b00000000000000d4b11200010000000000000000000000f0b11200010000000000000000000000f8b11200080000000000000000b2120002000000000000000000000010b2120001000000000000000000000018b212000e0000000000000000b2120002000000000000000000000028b2120001000000000000000000000030b21200060000000000000038b2120003000000000000000000000050b21200010000000000000050726f706f73656420af12000900000075b412000d00000089b21200040000008db212000b00000012b412005300000065b4120010000000566f74656400000020af12000900000089b2120004000000a1f51200040000008db212000b0000008db212000b0000008ab3120042000000ccb3120046000000417070726f76656489b212000400000059b3120031000000446973617070726f7665640024b3120035000000457865637574656489b2120004000000a1f5120004000000e3b21200410000004d656d6265724578656375746564000098b212004b000000436c6f736564000089b21200040000008db212000b0000008db212000b00000058b212003100000020412070726f706f73616c2077617320636c6f73656420616674657220697473206475726174696f6e207761732075702e486173684d656d626572436f756e7420412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e2041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e50726f706f73616c496e64657852616e646f6d6e657373436f6c6c656374697665466c697052616e646f6d4d6174657269616c2f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f72616e646f6d6e6573732d636f6c6c6563746976652d666c69702f7372632f6c69622e72730000a8b4120046000000540000001100000050726f706f73616c734d656d62657273566f74696e67486973746f726963616c53657373696f6e7300000000d7ab12000c00000000000000b4b61200020000000000000000000000e4b612000d0000000000000000000000e3ab12000d000000000000004cb712000200000000000000000000007cb712000d0000000000000000000000f0ab12000f00000000000000e4b712000300000000000000000000002cb812001b0000000000000000000000ffab1200110000000000000004b912000100000000000000000000001cb9120016000000000000000000000010ac12000e000000000000004cb71200020000000000000000000000ccb912001900000000000000000000001eac12000e0000000000000004b9120001000000000000000000000094ba12001400000000000000000000002cac12000e0000000000000034bb12000100000000000000000000004cbb12001400000000000000000000003aac12000f00000000000000301a1300000000000000000000000000ecbb120015000000000000000000000049ac1200100000000000000004b9120001000000000000000000000094bc12000b000000000000000000000025cb120007000000000000007ac312000c00000000000000fbea1200040000000000000061d112001700000048d0120029000000301a13000000000024bd12004500000069bd12003a000000301a130000000000a3bd12000c00000071d0120049000000bad0120040000000301a130000000000f5bd12000b000000fad01200250000001fd112004200000044be12000c0000000000000044d0120004000000000000007ac312000c0000000000000073c3120007000000000000007ac312000c00000014cf1200470000005bcf12001d000000301a13000000000078cf120032000000301a130000000000a3bd12000c000000aacf12002e000000d8cf120047000000301a130000000000f5bd12000b0000001fd012001900000038d012000c00000044be12000c00000000000000d6ce12000700000000000000ddce12001100000000000000eece12000900000000000000f7ce12000300000000000000face12000c0000000000000006cf12000e0000002ccb120057000000301a13000000000083cb12004c000000cfcb12005200000021cc12002f000000301a13000000000098c9120034000000301a130000000000a3bd12000c00000050cc12004900000099cc120035000000cecc12004c0000001acd12004700000061cd12002500000086cd12004f000000d5cd12003a000000301a130000000000f5bd12000b0000000fce12001a00000029ce12004b00000074ce12003b000000e3ca120027000000afce1200270000002bc112000d000000301a13000000000038c112001b00000044be12000c0000000000000025cb120007000000000000007ac312000c0000009fc812003b000000301a130000000000dac812004700000021c91200490000006ac912002e000000301a13000000000098c9120034000000301a130000000000a3bd12000c000000ccc912004500000011ca120040000000301a130000000000f5bd12000b00000051ca12003e0000008fca120054000000e3ca120027000000cec51200390000000acb12001b0000002bc112000d000000301a13000000000038c112001b00000044be12000c00000049c612004a00000093c612001a000000301a130000000000adc612004a000000f7c612001d000000301a130000000000a3bd12000c00000014c712003500000049c71200440000008dc7120015000000301a130000000000a2c7120049000000ebc7120009000000301a130000000000f5bd12000b00000000c512003f0000003fc512004700000086c5120048000000f4c712003b0000002fc812004700000007c61200270000002bc112000d000000301a13000000000076c812002900000044be12000c00000086c312003d000000301a130000000000c3c312004b0000000ec412004700000055c412004c000000301a130000000000a3bd12000c000000a1c412004b000000ecc4120014000000301a130000000000f5bd12000b00000000c512003f0000003fc512004700000086c5120048000000cec512003900000007c61200270000002bc112000d000000301a1300000000002ec612001b00000044be12000c0000000000000073c3120007000000000000007ac312000c00000053c112004500000098c112001a000000301a130000000000b2c1120048000000fac112003e000000301a130000000000dabf12004100000038c212003c000000301a130000000000a3bd12000c00000074c2120044000000301a130000000000f5bd12000b000000b8c2120021000000d9c212004f00000028c31200300000002bc112000d000000301a13000000000058c312001b00000044be12000c00000050be120057000000301a130000000000a7be120045000000ecbe120042000000301a1300000000002ebf12004900000077bf1200260000009dbf12003d000000301a130000000000dabf1200410000001bc0120039000000301a130000000000f5bd12000b00000054c01200180000006cc012004a000000b6c012004e00000004c11200270000002bc112000d000000301a13000000000038c112001b00000044be12000c000000ecbc120038000000301a13000000000024bd12004500000069bd12003a000000301a130000000000a3bd12000c000000afbd120046000000301a130000000000f5bd12000b00000000be12004400000044be12000c0000002043616e63656c20746865206162696c69747920746f20757365206061735f7265636f76657265646020666f7220606163636f756e74602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207265676973746572656420746f2062652061626c6520746f206d616b652063616c6c73206f6e20626568616c66206f6620746865207265636f7665726564206163636f756e742e20506172616d65746572733a202d20606163636f756e74603a20546865207265636f7665726564206163636f756e7420796f75206172652061626c6520746f2063616c6c206f6e2d626568616c662d6f662e2023203c7765696768743e202d204f6e652073746f72616765206d75746174696f6e20746f20636865636b206163636f756e74206973207265636f7665726564206279206077686f602e204f2831292023203c2f7765696768743e2052656d6f766520746865207265636f766572792070726f6365737320666f7220796f7572206163636f756e742e205265636f7665726564206163636f756e747320617265207374696c6c2061636365737369626c652e204e4f54453a205468652075736572206d757374206d616b65207375726520746f2063616c6c2060636c6f73655f7265636f7665727960206f6e20616c6c20616374697665207265636f7665727920617474656d707473206265666f72652063616c6c696e6720746869732066756e6374696f6e20656c73652069742077696c6c206661696c2e205061796d656e743a2042792063616c6c696e6720746869732066756e6374696f6e20746865207265636f76657261626c65206163636f756e742077696c6c20756e72657365727665207468656972207265636f7665727920636f6e66696775726174696f6e206465706f7369742e202860436f6e6669674465706f7369744261736560202b2060467269656e644465706f736974466163746f7260202a20235f6f665f667269656e64732920546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206d7573742062652061207265636f76657261626c65206163636f756e742028692e652e206861732061207265636f7665727920636f6e66696775726174696f6e292e204b65793a204620286c656e206f6620667269656e647329202d204f6e652073746f72616765207265616420746f206765742074686520707265666978206974657261746f7220666f7220616374697665207265636f7665726965732e204f283129202d204f6e652073746f7261676520726561642f72656d6f766520746f2067657420746865207265636f7665727920636f6e66696775726174696f6e2e204f2831292c20436f646563204f284629202d204f6e652062616c616e63652063616c6c20746f20756e72657365727665642e204f285829202d204f6e65206576656e742e20546f74616c20436f6d706c65786974793a204f2846202b2058292041732074686520636f6e74726f6c6c6572206f662061207265636f76657261626c65206163636f756e742c20636c6f736520616e20616374697665207265636f766572792070726f6365737320666f7220796f7572206163636f756e742e205061796d656e743a2042792063616c6c696e6720746869732066756e6374696f6e2c20746865207265636f76657261626c65206163636f756e742077696c6c207265636569766520746865207265636f76657279206465706f73697420605265636f766572794465706f7369746020706c616365642062792074686520726573637565722e207265636f76657261626c65206163636f756e74207769746820616e20616374697665207265636f766572792070726f6365737320666f722069742e202d206072657363756572603a20546865206163636f756e7420747279696e6720746f207265736375652074686973207265636f76657261626c65206163636f756e742e204b65793a205620286c656e206f6620766f756368696e6720667269656e647329202d204f6e652073746f7261676520726561642f72656d6f766520746f206765742074686520616374697665207265636f766572792070726f636573732e204f2831292c20436f646563204f285629202d204f6e652062616c616e63652063616c6c20746f20726570617472696174652072657365727665642e204f28582920546f74616c20436f6d706c65786974793a204f2856202b20582972657363756572543a3a4163636f756e74496420416c6c6f772061207375636365737366756c207265736375657220746f20636c61696d207468656972207265636f7665726564206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206d7573742062652061202272657363756572222077686f20686173207375636365737366756c6c7920636f6d706c6574656420746865206163636f756e74207265636f766572792070726f636573733a20636f6c6c656374656420607468726573686f6c6460206f72206d6f726520766f75636865732c20776169746564206064656c61795f706572696f646020626c6f636b732073696e636520696e6974696174696f6e2e202d20606163636f756e74603a20546865206c6f7374206163636f756e74207468617420796f752077616e7420746f20636c61696d20686173206265656e207375636365737366756c6c792020207265636f766572656420627920796f752e204b65793a204620286c656e206f6620667269656e647320696e20636f6e666967292c205620286c656e206f6620766f756368696e6720667269656e647329202d204f6e652073746f72616765207265616420746f2067657420746865207265636f7665727920636f6e66696775726174696f6e2e204f2831292c20436f646563204f284629202d204f6e652073746f72616765207265616420746f206765742074686520616374697665207265636f766572792070726f636573732e204f2831292c20436f646563204f285629202d204f6e652073746f72616765207265616420746f20676574207468652063757272656e7420626c6f636b206e756d6265722e204f283129202d204f6e652073746f726167652077726974652e204f2831292c20436f646563204f2856292e20546f74616c20436f6d706c65786974793a204f2846202b20562920416c6c6f7720612022667269656e6422206f662061207265636f76657261626c65206163636f756e7420746f20766f75636820666f7220616e20616374697665207265636f766572792070726f6365737320666f722074686174206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206d75737420626520612022667269656e642220666f7220746865207265636f76657261626c65206163636f756e742e202d20606c6f7374603a20546865206c6f7374206163636f756e74207468617420796f752077616e7420746f207265636f7665722e202d206072657363756572603a20546865206163636f756e7420747279696e6720746f2072657363756520746865206c6f7374206163636f756e74207468617420796f7520202077616e7420746f20766f75636820666f722e2054686520636f6d62696e6174696f6e206f662074686573652074776f20706172616d6574657273206d75737420706f696e7420746f20616e20616374697665207265636f766572792070726f636573732e202d204f6e652062696e6172792073656172636820746f20636f6e6669726d2063616c6c6572206973206120667269656e642e204f286c6f674629202d204f6e652062696e6172792073656172636820746f20636f6e6669726d2063616c6c657220686173206e6f7420616c726561647920766f75636865642e204f286c6f67562920546f74616c20436f6d706c65786974793a204f2846202b206c6f6746202b2056202b206c6f67562920496e697469617465207468652070726f6365737320666f72207265636f766572696e672061207265636f76657261626c65206163636f756e742e205061796d656e743a20605265636f766572794465706f736974602062616c616e63652077696c6c20626520726573657276656420666f7220696e6974696174696e6720746865207265636f766572792070726f636573732e2054686973206465706f7369742077696c6c20616c7761797320626520726570617472696174656420746f20746865206163636f756e7420747279696e6720746f206265207265636f76657265642e205365652060636c6f73655f7265636f76657279602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e202d20606163636f756e74603a20546865206c6f7374206163636f756e74207468617420796f752077616e7420746f207265636f7665722e2054686973206163636f756e742020206e6565647320746f206265207265636f76657261626c652028692e652e20686176652061207265636f7665727920636f6e66696775726174696f6e292e202d204f6e652073746f72616765207265616420746f20636865636b2074686174206163636f756e74206973207265636f76657261626c652e204f284629202d204f6e652073746f72616765207265616420746f20636865636b20746861742074686973207265636f766572792070726f63657373206861736e277420616c726561647920737461727465642e204f283129202d204f6e652063757272656e63792072657365727665206f7065726174696f6e2e204f285829202d204f6e652073746f726167652077726974652e204f2831292e6163636f756e74204372656174652061207265636f7665727920636f6e66696775726174696f6e20666f7220796f7572206163636f756e742e2054686973206d616b657320796f7572206163636f756e74207265636f76657261626c652e205061796d656e743a2060436f6e6669674465706f7369744261736560202b2060467269656e644465706f736974466163746f7260202a20235f6f665f667269656e64732062616c616e63652077696c6c20626520726573657276656420666f722073746f72696e6720746865207265636f7665727920636f6e66696775726174696f6e2e2054686973206465706f7369742069732072657475726e656420696e2066756c6c207768656e2074686520757365722063616c6c73206072656d6f76655f7265636f76657279602e202d2060667269656e6473603a2041206c697374206f6620667269656e647320796f7520747275737420746f20766f75636820666f72207265636f7665727920617474656d7074732e20202053686f756c64206265206f72646572656420616e6420636f6e7461696e206e6f206475706c69636174652076616c7565732e202d20607468726573686f6c64603a20546865206e756d626572206f6620667269656e64732074686174206d75737420766f75636820666f722061207265636f7665727920617474656d70742020206265666f726520746865206163636f756e742063616e206265207265636f76657265642e2053686f756c64206265206c657373207468616e206f7220657175616c20746f202020746865206c656e677468206f6620746865206c697374206f6620667269656e64732e202d206064656c61795f706572696f64603a20546865206e756d626572206f6620626c6f636b732061667465722061207265636f7665727920617474656d707420697320696e697469616c697a656420202074686174206e6565647320746f2070617373206265666f726520746865206163636f756e742063616e206265207265636f76657265642e202d204b65793a204620286c656e206f6620667269656e647329202d204f6e652073746f72616765207265616420746f20636865636b2074686174206163636f756e74206973206e6f7420616c7265616479207265636f76657261626c652e204f2831292e202d204120636865636b20746861742074686520667269656e6473206c69737420697320736f7274656420616e6420756e697175652e204f284629202d204f6e652073746f726167652077726974652e204f2831292e20436f646563204f2846292e667269656e64735665633c543a3a4163636f756e7449643e7468726573686f6c6475313664656c61795f706572696f64543a3a426c6f636b4e756d62657220416c6c6f7720524f4f5420746f2062797061737320746865207265636f766572792070726f6365737320616e642073657420616e20612072657363756572206163636f756e7420666f722061206c6f7374206163636f756e74206469726563746c792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f524f4f545f2e202d20606c6f7374603a2054686520226c6f7374206163636f756e742220746f206265207265636f76657265642e202d206072657363756572603a20546865202272657363756572206163636f756e74222077686963682063616e2063616c6c20617320746865206c6f7374206163636f756e742e202d204f6e652073746f72616765207772697465204f283129202d204f6e65206576656e746c6f73742053656e6420612063616c6c207468726f7567682061207265636f7665726564206163636f756e742e202d20606163636f756e74603a20546865207265636f7665726564206163636f756e7420796f752077616e7420746f206d616b6520612063616c6c206f6e2d626568616c662d6f662e202d206063616c6c603a205468652063616c6c20796f752077616e7420746f206d616b65207769746820746865207265636f7665726564206163636f756e742e202d2054686520776569676874206f6620746865206063616c6c60202b2031302c3030302e202d204f6e652073746f72616765206c6f6f6b757020746f20636865636b206163636f756e74206973207265636f7665726564206279206077686f602e204f283129426f783c3c542061732054726169743e3a3a43616c6c3e5265636f766572790000000088d212000b00000001050000000000007ac312000c0000000000000093d212003a00000000000000000000000000000000000000301a1300d0d212000000000000000000e0d2120001000000000000000000000000000000e8d212001000000002050500000000007ac312000c000000000000007ac312000c00000000000000f8d212003a00000000000000301a130034d31200000000000000000044d312000400000000000000000000000000000064d312000500000001020000000000007ac312000c000000000000007ac312000c00000000000000000000000000000000000000301a130028e0120000000000000000006cd312000300000000000000000000005265636f76657261626c655265636f76657279436f6e6669673c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e0000004200000000000000010000005b00000070d41200420000004163746976655265636f7665726965734163746976655265636f766572793c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e00004200000000000000010000005b000000e6d312001a000000301a13000000000000d412004500000045d412002b00000050726f787900000084d3120024000000301a130000000000a8d312003e00000020546865206c697374206f6620616c6c6f7765642070726f7879206163636f756e74732e204d61702066726f6d2074686520757365722077686f2063616e2061636365737320697420746f20746865207265636f7665726564206163636f756e742e20416374697665207265636f7665727920617474656d7074732e204669727374206163636f756e7420697320746865206163636f756e7420746f206265207265636f76657265642c20616e6420746865207365636f6e64206163636f756e7420697320746865207573657220747279696e6720746f207265636f76657220746865206163636f756e742e2054686520736574206f66207265636f76657261626c65206163636f756e747320616e64207468656972207265636f7665727920636f6e66696775726174696f6e2e000000000000fbaf12000b0000000000000090d51200020000000000000000000000c0d5120006000000000000000000000006b012000700000000000000f0d5120001000000000000000000000008d612000300000000000000000000000db01200070000000000000020d6120002000000000000000000000050d6120004000000000000000000000014b01200040000000000000070d61200030000000000000000000000b8d6120004000000000000000000000018b012000500000000000000d8d6120002000000000000000000000008d712000d0000000000000000000000cddb12000b00000000000000ddce12001100000000000000d8db12000500000000000000dddb1200140000001edb120021000000301a1300000000003fdb12003f0000007edb120039000000301a130000000000b7db1200160000000000000089d91200080000000000000098da12001e000000b6da12003d000000301a130000000000f3da12002b00000000000000eece1200090000000000000084da1200140000000000000089d91200080000000000000098da12001e000000f5bd12000b00000032da12002400000056da12002e00000044be12000c0000000000000089d91200080000000000000091d91200070000000000000098d9120005000000000000009dd9120016000000000000002bda12000700000000000000a1f5120004000000f5bd12000b000000b3d9120023000000d6d912005500000044be12000c0000000000000089d91200080000000000000091d91200070000000000000098d9120005000000000000009dd912001600000070d7120054000000c4d7120026000000301a130000000000ead712005700000041d8120019000000301a1300000000005ad81200250000007fd81200200000009fd8120043000000e2d812002c0000000ed912001e0000002cd912002700000053d9120036000000204d61792062652063616c6c656420627920616e79207369676e6564206163636f756e742061667465722074686520766f74696e67206475726174696f6e2068617320656e64656420696e206f7264657220746f2066696e69736820766f74696e6720616e6420636c6f7365207468652070726f706f73616c2e2041627374656e74696f6e732061726520636f756e7465642061732072656a656374696f6e7320756e6c6573732074686572652069732061207072696d65206d656d6265722073657420616e6420746865207072696d65206d656d626572206361737420616e20617070726f76616c2e202d2074686520776569676874206f66206070726f706f73616c6020707265696d6167652e202d20757020746f207468726565206576656e7473206465706f73697465642e202d206f6e6520726561642c2074776f2072656d6f76616c732c206f6e65206d75746174696f6e2e2028706c7573207468726565207374617469632072656164732e29202d20636f6d7075746174696f6e20616e6420692f6f20604f2850202b204c202b204d29602077686572653a2020202d20604d60206973206e756d626572206f66206d656d626572732c2020202d20605060206973206e756d626572206f66206163746976652070726f706f73616c732c2020202d20604c602069732074686520656e636f646564206c656e677468206f66206070726f706f73616c6020707265696d6167652e70726f706f73616c543a3a48617368696e646578436f6d706163743c50726f706f73616c496e6465783e202d20426f756e6465642073746f72616765207265616420616e64207772697465732e202d2057696c6c20626520736c696768746c792068656176696572206966207468652070726f706f73616c20697320617070726f766564202f20646973617070726f7665642061667465722074686520766f74652e617070726f7665202d20426f756e6465642073746f7261676520726561647320616e64207772697465732e202d20417267756d656e7420607468726573686f6c6460206861732062656172696e67206f6e207765696768742e436f6d706163743c4d656d626572436f756e743e426f783c3c542061732054726169743c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e205365742074686520636f6c6c6563746976652773206d656d626572736869702e202d20606e65775f6d656d62657273603a20546865206e6577206d656d626572206c6973742e204265206e69636520746f2074686520636861696e20616e64202d20607072696d65603a20546865207072696d65206d656d6265722077686f736520766f74652073657473207468652064656661756c742e20526571756972657320726f6f74206f726967696e2e6e65775f6d656d626572737072696d654f7074696f6e3c543a3a4163636f756e7449643e5665633c543a3a486173683e000000d4dd12002400000050726f706f73616c4f663c542061732054726169743c493e3e3a3a50726f706f73616c00a1dd120033000000566f7465733c543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265723e0074dd12002d0000007533320062dd12001200000014dd12004e00000084dc120057000000dbdc12003900000020546865206d656d6265722077686f2070726f7669646573207468652064656661756c7420766f746520666f7220616e79206f74686572206d656d62657273207468617420646f206e6f7420766f7465206265666f7265207468652074696d656f75742e204966204e6f6e652c207468656e206e6f206d656d6265722068617320746861742070726976696c6567652e205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e0000000000b51200090000000000000000000000f1db12000c00000000000000000000000000000000000000000000000000000000000000301a130090e01200000000000000000000dc12000100000000000000010000000000000008dc12000a000000010600000000000091d91200070000000000000012dc12001900000000000000000000000000000000000000301a130028e0120000000000000000002cdc12000100000000000000000000000000000010b5120006000000010600000000000091d91200070000000000000034dc12002300000000000000000000000000000000000000301a130028e01200000000000000000058dc1200010000000000000000000000000000000ef812000d000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a130008e01200000000000000000064dc12000100000000000000010000000000000009b51200070000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a130018e0120000000000000000006cdc1200010000000000000001000000000000009caf12000500000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a130028e01200000000000000000074dc120002000000000000000000000042000000000000000100000057000000420000000000000001000000590000004200000000000000010000005b000000000000009ab412000e0000000000000000000000f1db12000c00000000000000000000000000000000000000000000000000000000000000301a130090e012000000000000000000a0e0120003000000000000000100000042000000000000000100000059000000b8e012005800000010e112005800000068e112001100000020536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e672062756666657220776974682060626c6f636b5f6e756d626572202520383160206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e00000000000000cdab12000a000000000000003ce31200010000000000000000000000c0ab12000d0000000000000044e31200010000000000000000000000b0ab120010000000000000004ce31200010000000000000000000000a6ab12000a0000000000000054e312000100000000000000000000009dab120009000000000000005ce312000100000000000000000000008fab12000e0000000000000064e312000100000000000000000000007dab120012000000000000006ce312000100000000000000000000006fab12000e0000000000000074e3120001000000000000000000000065ab12000a000000000000007ce312000100000000000000000000005cab1200090000000000000084e3120001000000000000000000000051ab12000b000000000000008ce3120001000000000000000000000043ab12000e0000000000000094e312000100000000000000000000003aab120009000000000000009ce312000100000000000000000000002fab12000b00000000000000a4e3120001000000000000000000000027ab12000800000000000000ace312000100000000000000000000001bab12000c000000000000006ce3120001000000000000006fe612003d0000004be612002400000016e6120035000000ebe512002b000000b8e512003300000090e512002800000064e512002c0000002ce5120038000000f8e4120034000000cde412002b00000086e412004700000056e41200300000001be412003b000000dbe3120040000000b4e31200270000002054686572652077617320616e206f766572666c6f7720696e20612063616c63756c6174696f6e20546865726520617265207374696c6c20616374697665207265636f7665727920617474656d7074732074686174206e65656420746f20626520636c6f73656420546865207468726573686f6c6420666f72207265636f766572696e672074686973206163636f756e7420686173206e6f74206265656e206d6574205468697320757365722068617320616c726561647920766f756368656420666f722074686973207265636f766572792054686520667269656e64206d757374207761697420756e74696c207468652064656c617920706572696f6420746f20766f75636820666f722074686973207265636f766572792054686973206163636f756e74206973206e6f74206120667269656e642077686f2063616e20766f7563682041207265636f766572792070726f6365737320686173206e6f74207374617274656420666f72207468697320726573637565722041207265636f766572792070726f636573732068617320616c7265616479207374617274656420666f722074686973206163636f756e742054686973206163636f756e7420697320616c72656164792073657420757020666f72207265636f766572792054686973206163636f756e74206973206e6f742073657420757020666f72207265636f7665727920467269656e6473206c697374206d75737420626520736f7274656420616e642066726565206f66206475706c69636174657320467269656e6473206c697374206d757374206265206c657373207468616e206d617820667269656e647320467269656e6473206c697374206d7573742062652067726561746572207468616e207a65726f20616e64207468726573686f6c64205468726573686f6c64206d7573742062652067726561746572207468616e207a65726f2055736572206973206e6f7420616c6c6f77656420746f206d616b6520612063616c6c206f6e20626568616c66206f662074686973206163636f756e7400000000f2af1200090000000000000070e71200010000000000000000000000e1af1200110000000000000078e71200010000000000000000000000d2af12000f0000000000000080e71200010000000000000000000000c8af12000a0000000000000088e71200010000000000000000000000bbaf12000d0000000000000090e71200010000000000000000000000a9af1200120000000000000098e71200010000000000000000000000a1af12000800000000000000a0e71200010000000000000065e812001800000045e812002000000031e812001400000020e812001100000009e8120017000000e8e7120021000000a8e71200400000002054686520636c6f73652063616c6c206973206d61646520746f6f206561726c792c206265666f72652074686520656e64206f662074686520766f74696e672e204d656d626572732061726520616c726561647920696e697469616c697a656421204475706c696361746520766f74652069676e6f726564204d69736d61746368656420696e6465782050726f706f73616c206d757374206578697374204475706c69636174652070726f706f73616c73206e6f7420616c6c6f776564204163636f756e74206973206e6f742061206d656d626572417574686f72697479446973636f766572794b657973417574686f7273686970446964536574556e636c65734261626545706f6368496e646578417574686f72697469657347656e65736973536c6f7443757272656e74536c6f7452616e646f6d6e6573734e65787452616e646f6d6e6573735365676d656e74496e646578556e646572436f6e737472756374696f6e746f6f206d616e7920696e737472756374696f6e734e6f6e2d656d7074792066756e6374696f6e20626f647920657870656374656400008ce912000f0000009be91200020000009de9120003000000617373657274696f6e206661696c65643a20636f6e746578742e6672616d655f737461636b2e69735f656d7074792829417420696e737472756374696f6e202840293a2043616e2774206465636f6465207761736d20636f64654d6f64756c65206973206e6f742076616c69646d6f64756c65206465636c6172657320696e7465726e616c206d656d6f72796d756c7469706c65207461626c6573206465636c617265647461626c652065786365656473206d6178696d756d2073697a6520616c6c6f776564757365206f6620666c6f6174696e6720706f696e74207479706520696e2066756e6374696f6e20747970657320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e206c6f63616c7320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e20676c6f62616c7320697320666f7262696464656e67617320696e737472756d656e746174696f6e206661696c6564737461636b2068656967687420696e737472756d656e746174696f6e206661696c656463616c6c6465706c6f796465706c6f792066756e6374696f6e2069736e2774206578706f72746564756e6b6e6f776e206578706f72743a20657870656374696e67206f6e6c79206465706c6f7920616e642063616c6c2066756e6374696f6e7366756e6374696f6e206861732061206e6f6e2d6578697374656e7420747970656578706f72742072656665727320746f206e6f6e2d6578697374656e742066756e6374696f6e657870656374656420612066756e6374696f6e656e74727920706f696e7420706f696e747320746f20616e20696d706f727465642066756e6374696f6e656e74727920706f696e74206861732077726f6e67207369676e617475726563616c6c2066756e6374696f6e2069736e2774206578706f727465646572726f722073657269616c697a696e6720696e737472756d656e746564206d6f64756c6552657475726e207479706573206c656e6774682073686f756c642062652030206f72203143757272656e745363686564756c65436f6e7472616374734163636f756e74436f756e74657298ec12006700000051010000170000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7761736d2d302e34312e302f7372632f656c656d656e74732f73656374696f6e2e72730089ef12001e000000a7ef12001f00000066756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2071656400002bef12005e000000d10000002000000066756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2066756e6374696f6e5f73656374696f6e5f6c656e203d3d20636f64655f73656374696f6e5f6c656e3b207165642bef12005e000000d40000001c00000011ef12001a000000ecee12000a000000f6ee12001b00000073746172742066756e6374696f6e20657870656374656420746f20686176652074797065205b5d202d3e205b5d000000dbee120011000000bbee1200200000009bee12002000000073ee12002800000070617373697665206d656d6f7279207365676d656e747320617265206e6f7420737570706f727465647365676d656e74206f66667365742073686f756c642072657475726e204933327061737369766520656c656d656e74207365676d656e747320617265206e6f7420737570706f72746564746f6f206d616e79206d656d6f727920726567696f6e7320696e20696e6465782073706163653a20746f6f206d616e79207461626c657320696e20696e6465782073706163653a20747279696e6720746f20696d706f7274206d757461626c6520676c6f62616c206475706c6963617465206578706f72742046756e6374696f6e20232072656164696e672f76616c69646174696f6e206572726f723a204d697373696e6720626f647920666f722066756e6374696f6e202f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e332e302f7372632f6c69622e72736c656e677468206f662066756e6374696f6e2073656374696f6e206973202c207768696c65206c656e206f6620636f64652073656374696f6e206973206578745f7365745f73746f726167656578745f636c6561725f73746f726167656578745f6765745f73746f726167656578745f7472616e736665726578745f63616c6c6578745f696e7374616e74696174656578745f7465726d696e6174656578745f72657475726e6578745f63616c6c65726578745f616464726573736578745f6761735f70726963656578745f6761735f6c6566746578745f62616c616e63656578745f76616c75655f7472616e736665727265646578745f72616e646f6d6578745f6e6f776578745f6d696e696d756d5f62616c616e63656578745f746f6d6273746f6e655f6465706f7369746578745f64697370617463685f63616c6c6578745f726573746f72655f746f6578745f736372617463685f73697a656578745f736372617463685f726561646578745f736372617463685f77726974656578745f6465706f7369745f6576656e746578745f7365745f72656e745f616c6c6f77616e63656578745f72656e745f616c6c6f77616e63656578745f7072696e746c6e6578745f626c6f636b5f6e756d6265726578745f6765745f72756e74696d655f73746f726167656578745f686173685f736861325f3235366578745f686173685f6b656363616b5f3235366578745f686173685f626c616b65325f3235366578745f686173685f626c616b65325f3132385075626c696350726f70436f756e745265666572656e64756d436f756e7444656d6f63726163794c6f77657374556e62616b65644c6173745461626c656457617345787465726e616c0000000001000000020000000400000008000000100000002000000050687261676d656e456c656374696f6e456c656374696f6e526f756e647346696e616c697479547261636b6572496e697469616c697a656400000000dcf212000e00000000000000ecf21200010000000000000000000000f4f21200010000000000000000000000fcf212000600000000000000301a130000000000000000000000000004f312000100000000000000000000000cf312000700000000000000301a130000000000000000000000000014f3120001000000000000004e6577417574686f72697469657300008ff312000d0000006bf3120024000000506175736564000044f3120027000000526573756d6564001cf31200280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e417574686f726974794c69737443757272656e7453657449644772616e64706146696e616c697479536574496453657373696f6e00d4f3120034000000b00000002e0000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f6964656e746974792f7372632f6c69622e7273496d4f6e6c696e655265636569766564486561727462656174734f6666656e6365735265706f72747342794b696e64496e6465780000000068f41200070000000000000070f4120003000000000000000000000088f4120003000000000000004f6666656e6365008ff512000400000093f512000e000000a1f5120004000000a0f4120055000000f5f412005300000048f512004700000020546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e6420286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e206c61737420656c656d656e7420696e64696361746573206f6620746865206f6666656e636520776173206170706c69656420287472756529206f7220717565756564202866616c7365292e4b696e644f706171756554696d65536c6f74626f6f6c43757272656e74496e6465785175657565644368616e67656444697361626c656456616c696461746f727300000000fcf512000a0000000000000008f6120001000000000000000000000010f6120002000000000000004e657753657373696f6e000097f612000c00000020f612005500000075f6120022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e53657373696f6e496e64657853657373696f6e53746f72656452616e6765486973746f7279446570746856616c696461746f72436f756e744d696e696d756d56616c696461746f72436f756e7443757272656e744572614163746976654572615374616b696e6745726173537461727453657373696f6e496e646578466f726365457261536c6173685265776172644672616374696f6e426f6e646564457261734561726c69657374556e6170706c696564536c61736851756575656453636f7265497343757272656e7453657373696f6e46696e616c4d69677261746545726174696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e54696d657374616d704469645570646174655472616e73616374696f6e5061796d656e744e6578744665654d756c7469706c696572547265617375727950726f706f73616c436f756e74417070726f76616c7334f812006200000088000000120000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e332e302f7372632f636f6465632e727300004200000004000000040000000c00000042725461626c65446174617461626c654200000004000000040000001e01000064656661756c744636345265696e74657270726574493634556e726561636861626c654e6f70426c6f636b004200000004000000040000001f0100004c6f6f704966456c7365456e6442724272496642725461626c6500004200000004000000040000002001000052657475726e43616c6c43616c6c496e6469726563740000420000000400000004000000fa00000044726f7053656c6563744765744c6f63616c5365744c6f63616c5465654c6f63616c476574476c6f62616c536574476c6f62616c4933324c6f61644936344c6f61644633324c6f61644636344c6f61644933324c6f616438534933324c6f616438554933324c6f61643136534933324c6f61643136554936344c6f616438534936344c6f616438554936344c6f61643136534936344c6f61643136554936344c6f61643332534936344c6f616433325549333253746f726549363453746f726546333253746f726546363453746f726549333253746f72653849333253746f7265313649363453746f72653849363453746f7265313649363453746f7265333243757272656e744d656d6f727947726f774d656d6f7279493332436f6e73740042000000040000000400000021010000493634436f6e737442000000040000000400000022010000463332436f6e7374463634436f6e73744200000004000000040000003400000049333245717a49333245714933324e654933324c74534933324c74554933324774534933324774554933324c65534933324c655549333247655349333247655549363445717a49363445714936344e654936344c74534936344c74554936344774534936344774554936344c65534936344c655549363447655349363447655546333245714633324e654633324c7446333247744633324c65463332476546363445714636344e654636344c7446363447744636344c654636344765493332436c7a49333243747a493332506f70636e744933324164644933325375624933324d756c493332446976534933324469765549333252656d5349333252656d55493332416e644933324f72493332586f7249333253686c4933325368725349333253687255493332526f746c493332526f7472493634436c7a49363443747a493634506f70636e744936344164644936345375624936344d756c493634446976534936344469765549363452656d5349363452656d55493634416e644936344f72493634586f7249363453686c4936345368725349363453687255493634526f746c493634526f74724633324162734633324e65674633324365696c463332466c6f6f724633325472756e634633324e656172657374463332537172744633324164644633325375624633324d756c4633324469764633324d696e4633324d6178463332436f70797369676e4636344162734636344e65674636344365696c463634466c6f6f724636345472756e634636344e656172657374463634537172744636344164644636345375624636344d756c4636344469764636344d696e4636344d6178463634436f70797369676e493332577261704936344933325472756e63534633324933325472756e63554633324933325472756e63534636344933325472756e6355463634493634457874656e6453493332493634457874656e64554933324936345472756e63534633324936345472756e63554633324936345472756e63534636344936345472756e6355463634463332436f6e7665727453493332463332436f6e7665727455493332463332436f6e7665727453493634463332436f6e766572745549363446333244656d6f7465463634463634436f6e7665727453493332463634436f6e7665727455493332463634436f6e7665727453493634463634436f6e766572745549363446363450726f6d6f74654633324933325265696e746572707265744633324936345265696e746572707265744636344633325265696e7465727072657449333200004200000004000000040000000c000000463634493332493634463332420000000400000004000000230100004e6f526573756c7456616c7565000000b4fe12000b000000492f4f204572726f723a2000d0fe120059000000450000001e0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7761736d2d302e34312e302f7372632f696f2e7273496e76616c696444617461547261696c696e6744617461556e6578706563746564456f66000000617474656d707420746f20646976696465206279207a65726f556e7369676e656420696e74656765722063616e277420626520637265617465642066726f6d206e656761746976652076616c75652f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7072696d69746976652d74797065732d302e372e302f7372632f6c69622e72736469766973696f6e206279207a65726f496e7465676572206f766572666c6f77207768656e2063617374696e6720746f207573697a65000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f0000009eff12005d0000002000000001000000547269656420746f20736872696e6b20746f2061206c6172676572206361706163697479e101130012000000f30113000c0000006066756e635f696478602073686f756c6420636f6d652066726f6d20606e6565645f7468756e6b73603b0a09090909606e6565645f7468756e6b736020697320706f70756c617465642077697468207468652073616d65206974656d73207468617420696e20607265706c6163656d656e745f6d6170603b0a09090909716564780113006900000050000000190000004174207468697320706f696e7420616e20696e646578206d7573742062652061737369676e656420746f2065616368207468756e6b0000007801130069000000890000001d0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31322e302f7372632f737461636b5f6865696768742f7468756e6b2e727366756e6374696f6e207769746820696478202069736e277420666f756e64617373657274696f6e206661696c65643a20656467652e686569676874203d3d2073656c662e686569676874202d2031617373657274696f6e206661696c65643a2073656c662e6c656e2829203c204341504143495459617373657274696f6e206661696c65643a20656467652e686569676874203d3d2073656c662e6e6f64652e686569676874202d20314672616d6569735f706f6c796d6f7270686963000042000000040000000400000024010000656e645f61726974790000004200000004000000040000000c0000006272616e63685f617269747973746172745f6865696768746003130049000000920200001a000000a9031300480000000002000023000000a90313004800000001020000230000006003130049000000a301000027000000617373657274696f6e206661696c65643a206d6964203c3d206c656e401a1300490000000a0000000900000060031300490000008e0200001d0000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f736c6963652f736f72742e72732f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f736c6963652f6d6f642e72730000006003130049000000a1000000300000006003130049000000a4000000300000004e6f2066756e6374696f6e2073656374696f6e4e6f20636f64652073656374696f6e4e6f20747970652073656374696f6e0000008b0613000a00000046756e6374696f6e206973206e6f7420666f756e6420696e2066756e632073656374696f6e0000007f0613000c00000046756e6374696f6e20626f647920666f722074686520696e6465782069736e277420666f756e6400300613000b00000029061300070000002306130006000000737461636b206f766572666c6f77737461636b206d757374206265206e6f6e2d656d707479000000180613000b0000004172697479206f6620616c6c206a756d702d74617267657473206d75737420626520657175616c54797065206e6f7420666f756e64000000380513006e000000c8000000170000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31322e302f7372632f737461636b5f6865696768742f6d61785f6865696768742e727300001306130005000000747279696e6720746f20706f70206d6f72652076616c756573207468616e20707573686564737461636b20756e646572666c6f776d61785f686569676874707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f686569676874706f703a20756e726561636861626c65707573683a207472756e633a20706f705f6672616d653a20636f6e74726f6c20737461636b20697320656d707479000000380513006e0000003a0000000d000000636f6e74726f6c20737461636b206f75742d6f662d626f756e6473707573685f6672616d653a2066756e635f6964783a2063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565d006130055000000480600001b0000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962616c6c6f632f636f6c6c656374696f6e732f62747265652f6d61702e7273656e766761736c6173745f696e6465782069732067726561746572207468616e20303b206c6173745f696e64657820697320737461636b2073697a65202d20313b2071656400008c0713005e000000a6000000260000008c0713005e000000120100001c0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31322e302f7372632f6761732f6d6f642e7273536f6d654e6f6e65000042000000040000000400000025010000410813006700000010010000200000001c0813002500000043616c6c20746f2066756e6374696f6e2074686174206f75742d6f662d626f756e64733a202f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31322e302f7372632f737461636b5f6865696768742f6d6f642e7273546869732073686f756c64206265206120696e646578206f66206120646566696e65642066756e6374696f6e44756520746f2076616c69646174696f6e20636f64652073656374696f6e2073686f756c642065786973747346756e6374696f6e20626f6479206973206f7574206f6620626f756e647366756e6374696f6e20696d706f727420636f756e74206973206e6f74207a65726f3b20696d706f72742073656374696f6e206d757374206578697374733b207165644108130067000000590100000900000066756e635f696478206973206c657373207468616e2066756e6374696f6e20696d706f72747320636f756e743b0a090909096e74682066756e6374696f6e20696d706f7274206d7573742062652060536f6d65603b0a090909097165640000005c17130012000000250a13000f000000f80913000a000000020a130014000000160a13000f0000005369676e61747572652020287370656369666965642062792066756e6320292069736e277420646566696e6564206973206e6f7420646566696e6564440a13003f000000440000000d0000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f61726974686d657469632f7372632f62696775696e742e727300000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000440a13003f0000006d00000009000000440a13003f0000007e00000009000000440a13003f0000009c0000001b000000440a13003f000000d40100001c000000440a13003f000000d50100001c00000063616e6e6f74206669742061206e756d62657220696e746f2075313238000000440a13003f0000009000000009000000616c7265616479206d757461626c7920626f72726f77656442000000000000000100000064000000640b1300430000001e030000090000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f63656c6c2e7273616c726561647920626f72726f776564004200000000000000010000006d000000640b1300430000006e0300000900000072656d696e646572206f6620646976206279206320697320616c77617973206c657373207468616e20633b20716564004200000008000000040000007a000000410c130046000000680000001b000000726573756c742063616e6e6f742066697420696e20753132382f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f61726974686d657469632f7372632f68656c706572735f3132386269742e727362616265736c6f74436f756c64206e6f74206465636f64652072657175657374656420696e686572656e742074797065214241424520696e686572656e742064617461206e6f7420666f756e64e40c130044000000cd0000000d0000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f72756e74696d652d696e746572666163652f7372632f696d706c732e727342000000000000000100000046000000486f737420746f207761736d2076616c7565732061726520656e636f64656420636f72726563746c793b207165640000780d13004600000008010000090000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f72756e74696d652d696e746572666163652f7372632f706173735f62792e727300004200000000000000010000004600000072756e74696d6552756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e6700000000000000617474656d707420746f20646976696465206279207a65726f0000002c0e1300400000005f0000002b0000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f72756e74696d652f7372632f67656e657269632f6572612e727348617368206e6f7420657175616c2f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f72756e74696d652f7372632f7472616974732e72730000007a0e13003b0000000504000013000000426164206f726967696e43616e206e6f74206c6f6f6b757044697370617463684572726f723c7761736d3a73747269707065643e5472616e616374696f6e206469737061746368206973206d616e6461746f72793b207472616e73616374696f6e73206d6179206e6f742068617665206d616e6461746f727920646973706174636865732e412063616c6c20776173206c6162656c6c6564206173206d616e6461746f72792c2062757420726573756c74656420696e20616e204572726f722e5472616e73616374696f6e20776f756c642065786861757374732074686520626c6f636b206c696d6974735472616e73616374696f6e2068617320616e20616e6369656e7420626972746820626c6f636b5472616e73616374696f6e20686173206120626164207369676e61747572655472616e73616374696f6e206973206f757464617465645472616e73616374696f6e2077696c6c2062652076616c696420696e2074686520667574757265496e6162696c69747920746f2070617920736f6d6520666565732028652e672e206163636f756e742062616c616e636520746f6f206c6f77295472616e73616374696f6e2063616c6c206973206e6f74206578706563746564496e76616c69645472616e73616374696f6e20637573746f6d206572726f72436f756c64206e6f742066696e6420616e20756e7369676e65642076616c696461746f7220666f722074686520756e7369676e6564207472616e73616374696f6e436f756c64206e6f74206c6f6f6b757020696e666f726d6174696f6e20726571756972656420746f2076616c696461746520746865207472616e73616374696f6e556e6b6e6f776e5472616e73616374696f6e20637573746f6d206572726f72696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64650088111300430000005a000000120000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f73616e64626f782f7372632f2e2e2f776974686f75745f7374642e727300881113004300000068000000120000004475706c69636174655265706f72744f6666656e63654572726f726d616b655f746f705f6672616d655f706f6c796d6f72706869632069732063616c6c6564207769746820656d707479206672616d6520737461636b0000260100000c00000004000000270100005f1413005f0000004204000011000000746869732066756e6374696f6e2063616e27742062652063616c6c6564207769746820656d707479206672616d6520737461636b5f1413005f000000b2040000050000004d6973706c6163656420656c736520696e737472756374696f6e0000df131300470000002614130005000000a313130037000000da131300050000006e1313001700000065131300090000001a161300140000004d1313001800000065131300090000001a161300140000001c1313001d00000039131300130000004c13130001000000546f6f206c61726765206d656d6f727920616c69676e6d656e7420325e20286578706563746564206174206d6f73742029547279696e6720746f2075706461746520676c6f62616c20206f66207479706520547279696e6720746f20757064617465206c6f63616c20537065636966696300000042000000040000000400000023010000416e794c6162656c7320696e2062725f7461626c6520706f696e747320746f20626c6f636b206f6620646966666572656e742074797065733a2020616e6420496620626c6f636b20776974686f757420656c736520726571756972656420746f2068617665204e6f526573756c7420626c6f636b20747970652e2042757420697420686173202074797065003c14130018000000541413000b000000556e657870656374656420737461636b20686569676874202c206578706563746564202f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e332e302f7372632f66756e632e7273547279696e6720746f2061636365737320706172656e74206672616d6520737461636b2076616c7565732e000000fc14130017000000131513001600000045787065637465642076616c7565206f66207479706520206f6e20746f70206f6620737461636b2e20476f74200000003415130007000000537461636b3a200000000100be1513002400000094151300060000009a1513000e000000a815130016000000701513002400000094151300060000006d6178696d756d206d656d6f72792073697a65206d757374206265206174206d6f7374202070616765736d6178696d756d206c696d697420206973206c657373207468616e206d696e696d756d20696e697469616c206d656d6f72792073697a65206d757374206265206174206d6f7374200000f4151300260000001a16130014000000547279696e6720746f20696e697469616c697a65207661726961626c65206f6620747970652020776974682076616c7565206f66207479706520496e69742065787072657373696f6e2073686f756c6420616c776179732062652077697468206c656e67746820324e6f6e20636f6e7374616e74206f70636f646520696e20696e69742065787072c516130007000000d716130022000000c516130007000000cc1613000b00000045787072657373696f6e20646f65736e277420656e647320776974682060656e6460206f70636f6465476c6f62616c20206973206d757461626c6520646f65736e277420657869737473206f72206e6f742079657420646566696e65640000000c171300100000001c1713000f0000004d656d6f727920617420696e6465782020646f65736e277420657869737473003c1713000f0000001c1713000f0000005461626c6520617420696e64657820005c171300120000001c1713000f00000046756e6374696f6e20617420696e646578200000801713000e0000001c1713000f0000005479706520617420696e646578200000ee171300100000001c1713000f000000c017130010000000e01713000e000000c017130010000000d017130010000000457870656374656420676c6f62616c2020746f20626520696d6d757461626c6520746f206265206d757461626c65476c6f62616c20617420696e646578206e6f6e2d656d70747920737461636b206578706563746564000028181300200000004818130012000000747279696e6720746f206765742076616c756520617420706f736974696f6e20206f6e20737461636b206f662073697a6520636865636b656420636f75706c65206f66206c696e65732061626f76650088181300600000004b0000000c0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e332e302f7372632f737461636b2e7273f018130015000000657863656564656420737461636b206c696d697420000000301a1300000000004572726f72000000420000000400000004000000280100004c6f63616c732072616e6765206e6f7420696e2033322d6269742072616e6765601913002200000082191300150000009719130007000000547279696e6720746f20616363657373206c6f63616c207769746820696e64657820207768656e20746865726520617265206f6e6c7920206c6f63616c730000b81913002d000000e51913000c000000f119130003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20fc1913003400000064657374696e6174696f6e20616e6420736f7572636520736c69636573206861766520646966666572656e74206c656e67746873401a13004900000010000000090000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f6d6163726f732f6d6f642e727300418cb5cc000b080000000000000000004194b5cc000b082c1110002c11100000e1b605046e616d6501d8b605a50800196578745f6c6f6767696e675f6c6f675f76657273696f6e5f31011e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f3102196578745f73746f726167655f7365745f76657273696f6e5f31031d6578745f68617368696e675f74776f785f36345f76657273696f6e5f3104206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f3105196578745f73746f726167655f6765745f76657273696f6e5f31061d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f31071b6578745f73746f726167655f636c6561725f76657273696f6e5f3108226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f3109206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f310a1c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f310b276578745f63727970746f5f73746172745f62617463685f7665726966795f76657273696f6e5f310c286578745f63727970746f5f66696e6973685f62617463685f7665726966795f76657273696f6e5f310d236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f310e286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f310f346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f3110276578745f64656661756c745f6368696c645f73746f726167655f6765745f76657273696f6e5f3111306578745f64656661756c745f6368696c645f73746f726167655f73746f726167655f6b696c6c5f76657273696f6e5f3112276578745f64656661756c745f6368696c645f73746f726167655f7365745f76657273696f6e5f3113296578745f64656661756c745f6368696c645f73746f726167655f636c6561725f76657273696f6e5f3114226578745f6f6666636861696e5f72616e646f6d5f736565645f76657273696f6e5f3115236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f3216286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f3117206578745f73616e64626f785f6d656d6f72795f6e65775f76657273696f6e5f3118256578745f73616e64626f785f6d656d6f72795f74656172646f776e5f76657273696f6e5f3119216578745f73616e64626f785f696e7374616e74696174655f76657273696f6e5f311a1c6578745f73616e64626f785f696e766f6b655f76657273696f6e5f311b276578745f73616e64626f785f696e7374616e63655f74656172646f776e5f76657273696f6e5f311c206578745f73616e64626f785f6d656d6f72795f6765745f76657273696f6e5f311d206578745f73616e64626f785f6d656d6f72795f7365745f76657273696f6e5f311e1e6578745f68617368696e675f736861325f3235365f76657273696f6e5f311f206578745f68617368696e675f6b656363616b5f3235365f76657273696f6e5f3120236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f3121286578745f64656661756c745f6368696c645f73746f726167655f726f6f745f76657273696f6e5f31221c6578745f73746f726167655f617070656e645f76657273696f6e5f31231a6578745f73746f726167655f726f6f745f76657273696f6e5f3124226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f3125226578745f6d6973635f72756e74696d655f76657273696f6e5f76657273696f6e5f31261c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f31271e6578745f73746f726167655f6e6578745f6b65795f76657273696f6e5f31282a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f3129246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f312a296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f312b1a6578745f73746f726167655f726561645f76657273696f6e5f312c1e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f312d1c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f312e256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f312f376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f3130256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f3131286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f3132216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f31330c5f5f727573745f616c6c6f63340a5f5f72675f616c6c6f63350e5f5f727573745f6465616c6c6f63360c5f5f72675f6465616c6c6f63370e5f5f727573745f7265616c6c6f63380c5f5f72675f7265616c6c6f6339135f5f727573745f616c6c6f635f7a65726f65643a115f5f72675f616c6c6f635f7a65726f65643b09686173685f746573743c33616c6c6f633a3a616c6c6f633a3a68616e646c655f616c6c6f635f6572726f723a3a68353163623932333763613366353463663d08727573745f6f6f6d3e34616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68636633313064393836323166623433303f29636f72653a3a70616e69636b696e673a3a70616e69633a3a683030363437306536303862656439353040673c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c26542c636f72653a3a736c6963653a3a497465723c543e3e3e3a3a737065635f657874656e643a3a68663630333566303732643235353538394125616c6c6f633a3a666d743a3a666f726d61743a3a68353162646564663733633836333235354236636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a68393562303464643938363539313862364323636f72653a3a666d743a3a77726974653a3a68303831356161306566383061653962354448616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303037343834663462386361636666364548616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303135633362643336363064376362304633636f72653a3a6f7074696f6e3a3a6578706563745f6e6f6e655f6661696c65643a3a6836383432633035363039613131616134473a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6862356535663530653539386135316130483b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6834383533323037383764313363643164493a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68323565373337646265363866313463314a41616c6c6f633a3a7665633a3a5665633c543e3a3a737761705f72656d6f76653a3a6173736572745f6661696c65643a3a68633031623332663963663337653963314b4e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a68663135303861353562323463646664644c2d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a68313231656364656237656134313664664d3c616c6c6f633a3a7665633a3a5665633c543e3a3a696e736572743a3a6173736572745f6661696c65643a3a68613934373131623037663536363065634e3c616c6c6f633a3a7665633a3a5665633c543e3a3a72656d6f76653a3a6173736572745f6661696c65643a3a68303739623034626265643466336234324f3f616c6c6f633a3a7665633a3a5665633c543e3a3a647261696e3a3a656e645f6173736572745f6661696c65643a3a6835643131373130356238363638376435504b3c616c6c6f633a3a7665633a3a5665633c75383e20617320636f72653a3a636f6e766572743a3a46726f6d3c267374723e3e3a3a66726f6d3a3a68386463303336393566373236363031305139636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63653a3a6862393936313139646531313231346565522f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a68366533616365353734346466643033645311727573745f626567696e5f756e77696e64542b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a683031343036616161383432343565306555313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a68303661353130333961616237383235345635636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a68653932373262646363616336306465615743636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a68643738323237356538303230633037345834636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68313938373562666436383834646638635936636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a68316465333637626133373764636538645a2c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a68313636656363363539373163643363635b2e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a68623233363366646233303032316536665c323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68383435353735636630376666363164325d4a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68353536393033316138643865383531325e323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68376161336631343238396430386261365f47636f72653a3a756e69636f64653a3a756e69636f64655f646174613a3a6772617068656d655f657874656e643a3a6c6f6f6b75703a3a68613835323132396535396333363565616032636f72653a3a756e69636f64653a3a7072696e7461626c653a3a636865636b3a3a68393165333839386434396631656236396149636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a683236383537666231363037623539353362453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683065623838643135356633303964303763483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862333335646536383631323063633233642e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a683633646465376666396462376438623465303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686230333265336361626166646339613166323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683061643362663132396338323533363767533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6836306236656363373161626162353536682e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a6832336130393365346464623739333531693a636f72653a3a666d743a3a6275696c646572733a3a44656275675374727563743a3a6669656c643a3a68663330616534613631356331363839626a2f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a68356261336366363138313565373762666b2e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a68663435363732306637616333343265356c3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68383834636237333035363965623265616d3b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a68656433643766613065316262373331326e3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68666434323965346239656338393933366f39636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a68613533333665666163353734656238627037636f72653a3a666d743a3a6275696c646572733a3a44656275675365743a3a656e7472793a3a686637353538653961373662616632373071443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683362303935626162663933396632636272313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862306565323536613538376662373638738001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a68376438313835366161663932613237397427636f72653a3a7374723a3a66726f6d5f757466383a3a6830613066313562666632633634383831753e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686130313939333562376233613364346576693c6672616d655f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6836633839313338393962326465613731776c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683131636162386431306239626630303878493c616c6c6f633a3a7665633a3a5665633c75383e206173207061726974795f7761736d3a3a696f3a3a57726974653e3a3a77726974653a3a686538303463366336346431303063636479693c6672616d655f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68326335306536343564623663653564667a483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68633561613262653264646332633533397b513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68366331646231303461373464363865327c3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68336662333236333863616364353236377d3b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a68363239653634316237613866396631307e3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68653539373662636463313735623361617f503c6672616d655f737570706f72743a3a64656275673a3a57726974657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a683864616337306630633162323838346580014d3c6672616d655f737570706f72743a3a64656275673a3a52756e74696d654c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a68386236316431323364646263636566388101493c6672616d655f737570706f72743a3a64656275673a3a52756e74696d654c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a68353338633737353131616136353964338201323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68333439613737636530353865613237308301383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a68633239643832333162626531343461648401343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a68373561656236636535666332353064388501363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a6832333664393961633239333539356465860137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830306233616230316365303566353762870137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830313138336261353330663735376166880137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830313539356333616532386461336132890137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68303938313666656635363836373464348a0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306130376261626533643332346335328b0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306233646536613136313166646435308c0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306265633839663034633230333335368d0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306565346266623164666664633131398e0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68313833636462623733303532343237358f0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831633138383230343530626239653433900137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831636632633661666363653535343962910137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831643436663636626232336533383666920137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832303637333966373536346132336662930137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832346536633636363337653535393631940137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832616634616331623438646438396664950137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832653933356538333434386234303034960137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6833383237316431623266633831663666970137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6834303333643664613139306665626463980137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6834383232383630643736613163353732990137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68346362313561313938626162373534339a0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68353937376632376461343466386164359b0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68356561396138313961356231613439619c0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68363439363836303666353664613035669d0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68373535626135646537663936313539659e0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68383365633066633261353739653164329f0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6838363836623239313566613066333130a00137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6839353032353630636139636166623661a10137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6839383265313132666366646234303661a20137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6862363539333836366361323837653837a30137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6862383861646232303966323232656231a40137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6864616238346263393430363538613437a50137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6865623161653131333435316565643934a60137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6865663038666639336337353237303066a70137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6866303862623863643834643632396636a80137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6866306631373136336237626238303865a90137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6866363864656237353365313461663162aa0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6866663363303663636265343764333434ab013b70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a6864636139643036343738323164633830ac01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834313139373062343437616531373362ad015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833333833633533663066646563643133ae01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862353832613638383661383164353732af014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6839663061363539663838363338616262b001723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6865323164343931373636326632646637b101613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6861356134346131616263636163636231b201706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6863663737636432363464396364633937b301706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6866346136633935396164626166363165b4015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831653164393839653161396135636530b5015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831666665373833303935306535353935b6015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832366334363936643039313539383762b7015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839396664303737346630666363383262b8015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862363264353235666237303932376562b9015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864376231326534373839353535313930ba015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864643435393335393231646238356666bb01746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6866303330336532366636323661626533bc01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864616163323265636339303261363938bd015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831343835353666343531396234366532be015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863366366353362303065386236633237bf013570616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6e65775f6572613a3a6838363865613135646461396139356263c001386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831663165396231656266303064373036c1014370616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a636c6561725f6572615f696e666f726d6174696f6e3a3a6864633566356431343030633634663137c2017c3c73705f72756e74696d655f696e746572666163653a3a706173735f62793a3a436f6465633c543e2061732073705f72756e74696d655f696e746572666163653a3a706173735f62793a3a506173734279496d706c3c543e3e3a3a66726f6d5f6666695f76616c75653a3a6838333637393936366666373735343431c301543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6833643235366261663161383635393630c4016b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6835626539633733323632656564623437c501860170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7374616b696e673a3a4578706f737572653c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6862373263363130643764383364653562c601303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830356263646666653963363038383638c7018b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835343634353665383630663135313332c8014e70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a736c61736861626c655f62616c616e63655f6f665f766f74655f7765696768743a3a6834313166656532323136366431613466c901533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6837623066653764653564346663623934ca012573705f70687261676d656e3a3a656c6563743a3a6866333332326333306366633538383839cb014473705f70687261676d656e3a3a41737369676e6d656e743c4163636f756e7449642c543e3a3a696e746f5f7374616b65643a3a6830373431333861393335346132663361cc013173705f70687261676d656e3a3a6275696c645f737570706f72745f6d61703a3a6861333435313631653635393138303863cd01513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6839353934343839393133303633336265ce01706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6832353738303831353236383565323662cf01723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6833386432653937633831393637393337d0012d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6865623630613835366464666230666437d101706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6834613934623137323135656561356361d201386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833386539373537643037376334383863d301706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6837316633396462396563613464666338d401416672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a6835346130353631613439363261623365d501386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830306464643131313032633630666435d601386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839393762383537626662636237363433d701386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862333265356161663330663030663162d8013770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746172745f6572613a3a6862363233363862303235626162646133d901386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839303237343363373866363065363637da01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862303837626538313962323139383562db014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6865363264373431313561666261666230dc015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833316130313665656135376230336162dd01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863373031383135303633303237353534de013570616c6c65745f7374616b696e673a3a736c617368696e673a3a646f5f736c6173683a3a6839316164393039633461386266393130df01446672616d655f737570706f72743a3a7472616974733a3a43757272656e63793a3a7265736f6c76655f6372656174696e673a3a6837366665613630346362386236313466e0014873705f72756e74696d653a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a6830633633383531633435626139366235e1014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6833653833343163646234376638656165e201713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6837303032646133353961356264666234e3013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6834643530636536383061383537613339e4013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a656e737572655f6e65775f6572613a3a6830393732666433646632643436643261e501386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831356536346137356531373461323034e6013e70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863363264663833376135313732656632e701723c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637453746f7261676556657273696f6e3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833336135666263633530626133303430e801753c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374457261456c656374696f6e5374617475733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862333831326230663835386563666334e9016d3c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563745370616e536c6173683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865346430383431333761653038643161ea013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6866383035616566303437346163313730eb01723c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637445726173546f74616c5374616b653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835326435363136643765613563383631ec01743c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637445726173526577617264506f696e74733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836653530663432343764373132653937ed01763c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563744572617356616c696461746f7250726566733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835323234373938363964373462356662ee01763c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374457261735374616b657273436c69707065643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863303930616637366532613763363534ef01793c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862343734326261636139373865353332f001703c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374486973746f727944657074683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834376231663234316131333837383530f1014170616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7072655f64697370617463685f636865636b733a3a6830376139616237313539316231303132f201386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861653030333130303931663063613330f3014770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6866333435643531316437306262313931f4019b013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862333038356136333062623933653730f5019a013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53657373696f6e7350657245726144656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861303430396462303330346461356163f6016c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6864363635653835623335616132663537f7018e0170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e3e3a3a656e636f64655f746f3a3a6837313136666235333362323266656661f8018b0170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e3e3a3a6465636f64653a3a6863353762383663653866656635353130f90137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831353437633033383734353136373230fa012b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6830343835653435366166613339343432fb015b70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c41636375726163793e3a3a66726f6d5f61737369676e6d656e743a3a6838383732373863613233333934396261fc01ba013c70616c6c65745f7374616b696e673a3a53746173684f663c543e2061732073705f72756e74696d653a3a7472616974733a3a436f6e766572743c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a636f6e766572743a3a6830616638363432323131623162326637fd01f3013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e2061732073705f7374616b696e673a3a6f6666656e63653a3a4f6e4f6666656e636548616e646c65723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c283c542061732070616c6c65745f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249642c3c542061732070616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a54726169743e3a3a46756c6c4964656e74696669636174696f6e293e3e3a3a6f6e5f6f6666656e63653a3a6832656633633339663131363538393637fe01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863346231663334366631316233376163ff014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a683330303135333935663033353664653280024970616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a6572615f7370616e3a3a686637666534373739663439626634366481024470616c6c65745f7374616b696e673a3a736c617368696e673a3a536c617368696e675370616e733a3a656e645f7370616e3a3a686131613338303033663362343434323582023570616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a64697361626c653a3a683662663838313764666333626235666183025e70616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a636f6d706172655f616e645f7570646174655f7370616e5f736c6173683a3a68356662646462613166316638626462648402d3023c70616c6c65745f7374616b696e673a3a4578706f737572654f663c543e2061732073705f72756e74696d653a3a7472616974733a3a436f6e766572743c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c70616c6c65745f7374616b696e673a3a4578706f737572653c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c3c542061732070616c6c65745f7374616b696e673a3a54726169743e3a3a43757272656e6379206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3e3a3a636f6e766572743a3a68366165633732636137343538356537328502386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686561373263643463313939383833653786026a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a68646461313137386666616564376263308702493c70616c6c65745f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68643538653432356363326333303736388802623c70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686230643338376132663535346235633589025a3c70616c6c65745f7374616b696e673a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68376139646535393235356236623761378a024373705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a726561643a3a68356631316666663034633234346237368b025a3c70616c6c65745f696e64696365733a3a4d6f64756c653c543e2061732073705f72756e74696d653a3a7472616974733a3a5374617469634c6f6f6b75703e3a3a6c6f6f6b75703a3a68363637616632356366663931613162338c025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68383836343239393966323134653135358d02336672616d655f73797374656d3a3a4d6f64756c653c543e3a3a696e635f7265663a3a68306235396665366132366334643530398e025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68643639653335623838326465313837368f02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683133333464633934343966353631313390028d013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a683337623739646161613263303430633691023870616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a6864326365663735666432363461363533920290013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a72656d6f76655f6c6f636b3a3a683739616636313835633566656230373793024870616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a636865636b5f616e645f7265706c6163655f736f6c7574696f6e3a3a68303831346461353136633534306661369402746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a683132666433336539326564633833363395025273705f61726974686d657469633a3a7065725f7468696e67733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a686630666536323262646132323831626696023970616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a68303632316136623964616133663734649702386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68383837653464393332303634306330329802437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68373261376638666436643338303831359902336672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465635f7265663a3a68373363386664363463323763653433389a02b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a68343864623564623262323538663163329b025b70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c41636375726163793e3a3a696e746f5f61737369676e6d656e743a3a68633432613962666466633334363131399c02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68363663616538386266323333613932329d02633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a68663239656236333235643336633234649e02613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68623532636466636630306166373430639f025f3c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6831316434303430363132373532383830a002613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6839396432663639626232396434363662a1024470616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a646f5f70687261676d656e3a3a6832313836663665366438613036636565a202386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865363430383138323931386434353163a3028b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6839343366613839663730633763623066a402443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830646335343235663931366265336535a502633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a6838363764336163343130306534396663a6024d6672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a636f6d707574655f6d656d626572735f646966663a3a6839353666666563636639663165616533a70299013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6834656335643432313562353635623333a802b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6831373338623865633332343562373765a902437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830396535326137613665323663643336aa02543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6831663262353933303961386238636532ab022e73705f70687261676d656e3a3a7265647563653a3a7265647563653a3a6866613839333933386335633064303363ac0248616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a456e7472793c4b2c563e3a3a6f725f696e736572743a3a6832363936366166363363626338383663ad023373705f70687261676d656e3a3a6e6f64653a3a4e6f64653c413e3a3a726f6f743a3a6832313162326230633165643831393031ae022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6837646430346163656532393739306635af023b73705f70687261676d656e3a3a6e6f64653a3a4e6f64653c413e3a3a69735f706172656e745f6f663a3a6838656537333833373639333435636461b002b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6866633538393636646663356335623934b102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830303663376135636264323163623164b202386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830346365656166336533313736373839b302386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830396164366265643431623365333866b402386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831326238663365323232373534313765b502386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831353138626163323830343836383939b602386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831626530663065356638343261306131b702386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831666234306230623362313530353464b802386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832383436613537373538383536313062b9026b6e6f64655f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a6833303331316332393734623531313537ba022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6837626530343537633261323562366639bb022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6837626530343537633261323562366639bc02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832653466383037646162323536646363bd02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833326362393833393534356432663763be02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833353064666630323434646466666339bf02850170616c6c65745f736f63696574793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f736f63696574793a3a4269644b696e643c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6866313235363563313165623962613634c002386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833626365633832626135653635626530c102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833666539333037396566343139363235c202726e6f64655f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a6839353939313966326534633236316632c302386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834336466636238346637343730653239c402386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834623236373432613535373633633038c502386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835343638336563333961313639613737c602386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835346432346363353461363437383562c702960173705f7374616b696e673a3a6f6666656e63653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f7374616b696e673a3a6f6666656e63653a3a4f6666656e636544657461696c733c5265706f727465722c4f6666656e6465723e3e3a3a6465636f64653a3a6831653765323661336635613461383461c8022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6836646335333530646333613065383137c902386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836353263323130333635656163303636ca028f0170616c6c65745f64656d6f63726163793a3a766f74653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f64656d6f63726163793a3a766f74653a3a4163636f756e74566f74653c42616c616e63653e3e3a3a6465636f64653a3a6861633539363439666333356636393939cb02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836363464646364623162396564333038cc02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836623833306538313430383264633566cd02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837363362306534326565313733363539ce02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838316166653732346534303035396535cf02543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6866306166393161396338646231373539d002386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838336538616661363836613730363065d102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838613564366633633165316665663834d202386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839313063323861313964653537386663d302386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839396663356535633130633832633832d402386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861393462353839616266346234666435d5026b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6833336365616132373739326638656135d602573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861333165363237333335636235633762d702386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862373538343730653262376463373837d802386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862373632303636666338356631393438d902386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863303639643361393036623066636437da02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863306130653734346233653862646133db027770616c6c65745f636f6e7472616374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f636f6e7472616374733a3a5363686564756c653e3a3a6465636f64653a3a6863336630356437396561363133623233dc02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863373162373832383237366363303838dd02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863376530396264636637353036363634de02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863643332333865303439386236333131df02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864323832313030306333376432366536e002386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864613738363534623466316330353965e102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864626232653333663964366537343837e202386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866633435643532643461343937393632e302396672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6832386461633638616133626338393631e402396672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6835343632383862373566316635383163e5025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839323562306339353930386331613735e60285013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7472616e736665723a3a6864343663333266353861633533633431e7024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6835343932373162623464663939613461e80293013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a436f6e7461696e733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736f727465645f6d656d626572733a3a6838383335633266313832663030666466e9024270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a69735f6d656d6265723a3a6838643735333232303465643539303231ea0290013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a657874656e645f6c6f636b3a3a6834623132343665623938396134326233eb023670616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6c6f636b733a3a6862303366643032636131623430623863ec023d70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7570646174655f6c6f636b733a3a6836613463346231616439316536393666ed025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864303533343130383539663065303032ee02483c5b543b20385d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6832666363313466303830323838336630ef029a013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726570617472696174655f72657365727665643a3a6863333161396136356539393537383538f002b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6862616238343766663637326630623339f1023f70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6866326461336234333831366166653936f2024170616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6837646666346166316365353262303238f3026e3c70616c6c65745f62616c616e6365733a3a5f5f476574427974655374727563744163636f756e743c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836323038326136323863393464373639f4024a70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6863343165313633613436316538663061f5024770616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835346438633035363837303735643862f6024970616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6836396330346162666638316161386364f702753c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a5f5f47657442797465537472756374566f74696e673c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865626363316535343431303637353433f8023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6837383031373637633031366335316135f9025270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6838313061353662383030333963326362fa029f013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6f64756c65496444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865303833336237356336313633386666fb02a3013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5465726d4475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864326263376435386134663365643564fc02a7013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4465736972656452756e6e657273557044656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866343038326364626630333661633336fd02a5013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a446573697265644d656d6265727344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830313564663038333234636630656564fe02fa01616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a48616e646c653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4e6f64655265663c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4d75742c4b2c562c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4c6561663e2c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a456467653e3a3a696e736572743a3a6862306530653564613066326339353763ff02fe01616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a48616e646c653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4e6f64655265663c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4d75742c4b2c562c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a496e7465726e616c3e2c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a456467653e3a3a696e736572743a3a683566643663326365336639623734356380034b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a68393330616266633430343738623461348103613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a686462393761386332663332663562333282034b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6837653937333561643437646535376431830348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6836643136353039383966373231353561840348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a686632643433303933666533653030626385034c3c70616c6c65745f62616c616e6365733a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68386130383931393238383833643463618603543c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686139666231633135666162666562653987035d3c70616c6c65745f62616c616e6365733a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68613035613537306163393530303263358803623c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68626136396533323639643933633430328903653c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68356432326632396564343834633936378a03393c54206173206672616d655f737570706f72743a3a7472616974733a3a4c656e3e3a3a6c656e3a3a68396633306466656136386663646331328b03393c54206173206672616d655f737570706f72743a3a7472616974733a3a4c656e3e3a3a6c656e3a3a68613034306564333636643737613766338c03b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a68303235326339343361363263386331338d03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68353335303433356532306162393531398e035270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a72656d6f76655f616e645f7265706c6163655f6d656d6265723a3a68323036303636626432356466343566348f03613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a683236656435323766326637666531656590036a3c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68343737393833333664393536623737639103456672616d655f737570706f72743a3a7472616974733a3a5369676e6564496d62616c616e63653c422c503e3a3a6d657267653a3a683565373432613166323763623765333592033c70616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683165373139393235373033613539363593033e70616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68366264613134316162616566633165619403437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68303962653065306334356236326338349503437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68313632316364613131363533373363309603437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68326333323665666639333932303766349703437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68383731393832336466356432353338329803437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a686131346166366162663430333231363999034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68366631633135393734643031633335389a03493c70616c6c65745f7574696c6974793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663462306134316331353163626234619b03493c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68333736613635376637383866316639642e323036329c03443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68333736613635376637383866316639649d03473c6672616d655f73797374656d3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663532646138393065373263323462399e03443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68633634343962653363613331313336399f03443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6864323032313031353031396634303934a0034b3c70616c6c65745f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838666336653532613337343966636361a1034e3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6861623763636361336138303334346538a2034e3c70616c6c65745f6d656d626572736869703a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832636337346331373936626566666335a3034a3c70616c6c65745f74726561737572793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6863623639343032643235386531626236a4034b3c70616c6c65745f636f6e7472616374733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6834346537393330616533373636613663a503463c70616c6c65745f7375646f3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6864353065613531666464656538623564a603443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836306663313039343964343862333534a703463c70616c6c65745f626162653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836623738656336353333316431343666a8034a3c70616c6c65745f6964656e746974793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836623362396564656461313531303039a9034b3c70616c6c65745f736f63696574793a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831633536343162356636303762326231aa034a3c70616c6c65745f7265636f766572793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836336537623530653866326531366634ab035a3c70616c6c65745f7574696c6974793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6832653138653265666336356565663837ac03553c6e6f64655f72756e74696d653a3a43616c6c2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6830386530613933623532393731393261ad034670616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a656e737572655f736f727465645f616e645f696e736572743a3a6835383039313964346538363430666266ae03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6861613162323539663533333232333564af036e6e6f64655f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6839326661326535376432653361363236b003706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6834353039326334313066366132323361b103463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6832353936316464316532343531396566b2035f3c70616c6c65745f7574696c6974793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6863653832363264636461653031313665b3030c436f72655f76657273696f6eb4036b3c73705f72756e74696d653a3a72756e74696d655f737472696e673a3a52756e74696d65537472696e67206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6830353936316638653965663866343037b50312436f72655f657865637574655f626c6f636bb6039a0173705f72756e74696d653a3a67656e657269633a3a626c6f636b3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f72756e74696d653a3a67656e657269633a3a626c6f636b3a3a426c6f636b3c4865616465722c45787472696e7369633e3e3a3a6465636f64653a3a6836633664366533643238323565383166b70384016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65732c434f6e52756e74696d65557067726164653e3a3a696e697469616c697a655f626c6f636b3a3a6838393534336262666334333534303062b8035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838636465383435303864653034626362b9033e73705f72756e74696d653a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6836616639306563633236343262396566ba035373705f696f3a3a747269653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a626c616b65325f3235365f6f7264657265645f726f6f743a3a6838626166303166646138346239643638bb038c016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65732c434f6e52756e74696d65557067726164653e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a6837626533313430336232346436353961bc03446672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6e6f74655f66696e69736865645f65787472696e736963733a3a6834663565633735623365366462643935bd03713c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a6837356431383837323432663037626232be03346672616d655f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a6834306363643339316338633733393866bf03467061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a436f646553656374696f6e3a3a626f646965733a3a6865666236393637346665636463336532c0036f3c73705f72756e74696d653a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6861653631333134316431633734656430c103363c5420617320636f72653a3a636f6e766572743a3a496e746f3c553e3e3a3a696e746f3a3a6831653531663063306165653439623266c203303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832333239626366396430636261636135c30315436f72655f696e697469616c697a655f626c6f636bc403723c73705f72756e74696d653a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6836353732656635373330626338323535c503114d657461646174615f6d65746164617461c603d9053c6e6f64655f72756e74696d653a3a52756e74696d652061732073705f6170693a3a72756e74696d655f6465636c5f666f725f4d657461646174613a3a4d657461646174613c73705f72756e74696d653a3a67656e657269633a3a626c6f636b3a3a426c6f636b3c73705f72756e74696d653a3a67656e657269633a3a6865616465723a3a4865616465723c7533322c73705f72756e74696d653a3a7472616974733a3a426c616b6554776f3235363e2c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c3c70616c6c65745f696e64696365733a3a4d6f64756c653c6e6f64655f72756e74696d653a3a52756e74696d653e2061732073705f72756e74696d653a3a7472616974733a3a5374617469634c6f6f6b75703e3a3a536f757263652c6e6f64655f72756e74696d653a3a43616c6c2c73705f72756e74696d653a3a4d756c74695369676e61747572652c286672616d655f73797374656d3a3a436865636b56657273696f6e3c6e6f64655f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b47656e657369733c6e6f64655f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b4572613c6e6f64655f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b4e6f6e63653c6e6f64655f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b5765696768743c6e6f64655f72756e74696d653a3a52756e74696d653e2c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4368617267655472616e73616374696f6e5061796d656e743c6e6f64655f72756e74696d653a3a52756e74696d653e293e3e3e3e3a3a6d657461646174613a3a6839373832303465333938323838636637c7031c426c6f636b4275696c6465725f6170706c795f65787472696e736963c8039c013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838633366316637643336313964326631c903aa0173705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5472616e73616374696f6e56616c69646974794572726f723e3a3a656e636f64655f746f3a3a6837616630643436316630373732653336ca031b426c6f636b4275696c6465725f66696e616c697a655f626c6f636bcb035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864666365313231316532383232373936cc0320426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373cd036f3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a6837383030326161646637346638343330ce033a70616c6c65745f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a6831316537336434343339363134626430cf03543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837393561656339316661343637336666d003437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6862316366653033333662363463663133d103366672616d655f73797374656d3a3a4d6f64756c653c543e3a3a626c6f636b5f686173683a3a6834616266626433393131633436333032d2031c426c6f636b4275696c6465725f636865636b5f696e686572656e7473d303453c737472206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6866613461623063393161366331636337d40318426c6f636b4275696c6465725f72616e646f6d5f73656564d50390013c70616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a52616e646f6d6e6573733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a486173683e3e3a3a72616e646f6d3a3a6830663032613736303538393733646663d6032b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6ed7039f013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073705f72756e74696d653a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a6832323837393033373663643437333663d803653c6e6f64655f72756e74696d653a3a43616c6c206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6834646464643866306463633231393133d9035373705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a6835303633363533356261326534313839da03436672616d655f73797374656d3a3a436865636b5765696768743c543e3a3a636865636b5f626c6f636b5f6c656e6774683a3a6839616436343133613033373137376362db034570616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a636f6d707574655f6665653a3a6866373362323964633264663765616638dc03b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6863313236303339373534623933336233dd036b3c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e2061732073705f72756e74696d653a3a7472616974733a3a56616c6964617465556e7369676e65643e3a3a76616c69646174655f756e7369676e65643a3a6837336534646664383430316138633162de03214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572df0386016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65732c434f6e52756e74696d65557067726164653e3a3a657874726163745f7072655f6469676573743a3a6833633036653934333837323364316438e003366672616d655f73797374656d3a3a4d6f64756c653c543e3a3a696e697469616c697a653a3a6862353039623233376562656265333134e1035173705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7075626c69635f6b6579733a3a6836343533373533326262646661653531e20347636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207533323e3a3a666d743a3a6831633835623037353066633565353230e303633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6862353438336361646236356530656662e403583c70616c6c65745f696d5f6f6e6c696e653a3a4f6666636861696e4572723c426c6f636b4e756d6265723e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863623733323834383634623336613164e5033c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6830336530383365663037633565323135e6034f70616c6c65745f7374616b696e673a3a6f6666636861696e5f656c656374696f6e3a3a636f6d707574655f6f6666636861696e5f656c656374696f6e3a3a6837366430386564363432653765616166e7031e4772616e6470614170695f6772616e6470615f617574686f726974696573e803543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838616534643735326134636663633836e90315426162654170695f636f6e66696775726174696f6eea031b426162654170695f63757272656e745f65706f63685f7374617274eb0321417574686f72697479446973636f766572794170695f617574686f726974696573ec031d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e6365ed035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838333634626337663438643432626536ee0311436f6e7472616374734170695f63616c6cef034870616c6c65745f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a63616c6c3a3a6830366364393161376464663131303334f003783c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6865373930646264376132643939306532f1033a70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a726573746f72655f746f3a3a6835323066363264363537326337656139f20318436f6e7472616374734170695f6765745f73746f72616765f3035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837346439313964636132303135343433f4033470616c6c65745f636f6e7472616374733a3a6368696c645f747269655f696e666f3a3a6832613034653636333861626539363636f5031c436f6e7472616374734170695f72656e745f70726f6a656374696f6ef6033870616c6c65745f636f6e7472616374733a3a72656e743a3a636f6e73696465725f636173653a3a6830303562333937373330646164633432f7033870616c6c65745f636f6e7472616374733a3a72656e743a3a656e6163745f766572646963743a3a6864643361303261343738326136646332f803205472616e73616374696f6e5061796d656e744170695f71756572795f696e666ff9032153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b657973fa034e73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a656432353531395f67656e65726174653a3a6861663766653465303739306335326632fb034e73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f67656e65726174653a3a6864343036646464383438353830636663fc031f53657373696f6e4b6579735f6465636f64655f73657373696f6e5f6b657973fd038f0173705f6170706c69636174696f6e5f63727970746f3a3a737232353531393a3a3c696d706c2073705f6170706c69636174696f6e5f63727970746f3a3a7472616974733a3a52756e74696d655075626c696320666f722073705f636f72653a3a737232353531393a3a5075626c69633e3a3a746f5f7261775f7665633a3a6834313030303530383533656362626532fe035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831393936653735363032656131383631ff033870616c6c65745f626162653a3a4d6f64756c653c543e3a3a646f5f696e697469616c697a653a3a68633338386661663832363234383361628004a30173705f636f6e73656e7375735f626162653a3a646967657374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f636f6e73656e7375735f626162653a3a646967657374733a3a5261775072654469676573743c5652464f75747075742c56524650726f6f663e3e3a3a6465636f64653a3a686130646632326430623236643163656481043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68313165336635633266343039316364398204376672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a686630363362653331366338626237333883047d3c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a686564363866316535633066653734663984047d3c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a683938306661326366633937353864356285047f3c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6833613766373162343832633964306361860481013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6864313439303833363664313538303233870484013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a68623766623738363236663665613963358804b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6865333236306265366637666530353662890496013c70616c6c65745f636f6e7472616374733a3a54726965496446726f6d506172656e74436f756e7465723c543e2061732070616c6c65745f636f6e7472616374733a3a54726965496447656e657261746f723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a747269655f69643a3a68306430306531353533613839656338638a04437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68663833616235613935626232353935328b043b70616c6c65745f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68373736396466303265633361353862368c046b3c70616c6c65745f626162653a3a5f5f4765744279746553747275637452616e646f6d6e6573733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68643037353937653665626139643666318d044470616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68613465636330363035336538613934648e049a013c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68663132623135316637333065646564318f0496013c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864303939323866636538356432363165900481013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6835346134663936366639613335613333910481013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6831333761343332373762393038393930920483013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6863363330343066363363346238383664930485013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6861613235386264623031366636323334940488013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a683465633732623862343635643365356195047c3c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a686139353036663666623136363539363896045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683232353165633664623062396134326397045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683763613265633161393362616636613198043c70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683730393262316634353134333762346199043e70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68663735376536623033353530613163659a04633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a68333033316564326565666233343036329b044673705f61726974686d657469633a3a68656c706572735f3132386269743a3a6d756c7469706c795f62795f726174696f6e616c3a3a68393031626331333565356638666566329c04533c73705f61726974686d657469633a3a726174696f6e616c3132383a3a526174696f6e616c31323820617320636f72653a3a636d703a3a4f72643e3a3a636d703a3a68616362613234623435383430376330329d04583c73705f61726974686d657469633a3a726174696f6e616c3132383a3a526174696f6e616c31323820617320636f72653a3a636d703a3a5061727469616c45713e3a3a65713a3a68343232666636626366653836633466619e042d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a68396534323465363362383761366161669f047a3c73705f61726974686d657469633a3a7065725f7468696e67733a3a5065725531362061732073705f61726974686d657469633a3a7065725f7468696e67733a3a5065725468696e673e3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a6861383037316235323863656163643538a0045273705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7375626d69745f7472616e73616374696f6e3a3a6834363464333661636234303335376461a1043d70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6861396537356666336265643832313831a2043f70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865616338323362343237373934623033a3042b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6832393232323238633938316134356636a4044870616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839326137653733326333633064323064a5049a013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d61785265676973747261727344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861326337656361656162356462383565a6049b013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d61785375624163636f756e747344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838666537313832346431326331663036a7049e013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5375624163636f756e744465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838633039343264643061663732613163a80499013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4669656c644465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863663461663934613235356665303065a90499013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a42617369634465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864333333633633656637633635306135aa04820170616c6c65745f6964656e746974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f6964656e746974793a3a4a756467656d656e743c42616c616e63653e3e3a3a656e636f64655f746f3a3a6862343963306633303230306635653635ab047c70616c6c65745f6964656e746974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f6964656e746974793a3a4964656e74697479496e666f3e3a3a656e636f64655f746f3a3a6832323837376662666234346564353236ac04573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6837616237303239366439623865346535ad04573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6836373039623532623961643239646633ae045170616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e3a3a7365745f62616c616e63653a3a6863386335363437633837386434663335af045170616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e3a3a7365745f73746f726167653a3a6834343931643963656639383037386463b004437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6839646263306437626664393831653038b1045a3c70616c6c65745f696e64696365733a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6830326163366530316334613661303063b2044a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6832326565616262356163633664323730b3045b3c70616c6c65745f6964656e746974793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6866633337643032386261626630633739b4043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6837383037623265343638316565666461b5045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865343462623363643664396463353034b6045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862313338636132333030313665643536b704603c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6835383261646132356362633639623135b8042b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6837356239656266393732333739373237b9043d70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a69735f6f6e6c696e655f6175783a3a6833633636653065386335386366303261ba04706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6865393964373537383363333162663138bb044d73705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6e6574776f726b5f73746174653a3a6864363436393861636139303262366232bc044a73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7369676e3a3a6838643263316630613033363163383862bd04473c70616c6c65745f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839636435616364366236316564356130be04373c285431302c5431312920617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833323134383937343237336366333637bf04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830363734343637326239636663623838c00496013c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e2061732070616c6c65745f73657373696f6e3a3a4f6e6553657373696f6e48616e646c65723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6265666f72655f73657373696f6e5f656e64696e673a3a6862396661323234346664313931633363c104443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865653039373465616162386365386134c2045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834316463613531376539363937633637c304706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6864666564653639646361353935623239c4045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833383837656164613662646236373964c504437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6865376337336564626436393965356639c604443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6835643031373934636661633266383865c7043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6833333966366463656630356665663331c8044b6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a72656769737465725f65787472615f7765696768745f756e636865636b65643a3a6830363637653030653263383333383865c9045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833303063393962386634303565353535ca04693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6866343130663637613761373036356665cb0481016672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a617070656e645f6f725f696e736572743a3a6831343462303635666137353430356262cc04753c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6865353261323135343036663731653664cd04437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830363561373534326135373733623533ce04406672616d655f73797374656d3a3a436865636b5765696768743c543e3a3a646f5f7072655f64697370617463683a3a6863646164363235623432616530386333cf045770616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a7765696768745f746f5f6665655f776974685f61646a7573746d656e743a3a6864313735373932323233353063623536d0043770616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a6866393463636564386561313039646364d104563c73705f72756e74696d653a3a44697370617463684572726f722061732073705f72756e74696d653a3a7472616974733a3a5072696e7461626c653e3a3a7072696e743a3a6863346566383637626639386531386236d2043e70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6837626466653761376130393937323932d3043f70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a6e6f74655f617574686f72736869703a3a6836383334633136353461333264623062d4044070616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861653831363333396361316265383064d5043e70616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835393730656335653436363337613935d6044070616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865353864396564363730396166666565d7044970616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6862336631393833396163353133663035d8049b013c70616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833616533613339373230373764306237d9043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6834643932316134343239626133323166da048d0170616c6c65745f7363686564756c65723a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f7363686564756c65723a3a5363686564756c65643c43616c6c2c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6863646237646465323139356636646462db043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6831306436353761386661656266653430dc04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831643133313534366161663930316465dd04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832356635323932333764633036323530de044b3c70616c6c65745f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832303562383065666232313537653534df04613c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6866356637323433663232336634336536e0043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6831616635653663383338626233653235e1043b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6861643534346239663235663461656264e2043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6835366534336430616634633936666337e3043273705f73616e64626f783a3a696d703a3a64697370617463685f7468756e6b3a3a6866376564613431343138656534343638e4047673705f7761736d5f696e746572666163653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f7761736d5f696e746572666163653a3a56616c75653e3a3a6465636f64653a3a6835393366313463636336656639626339e5047973705f7761736d5f696e746572666163653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f7761736d5f696e746572666163653a3a56616c75653e3a3a656e636f64655f746f3a3a6839313534646335623637376664313034e6045273705f73616e64626f783a3a696d703a3a456e7669726f6e6d656e74446566696e6974696f6e4275696c6465723c543e3a3a6164645f686f73745f66756e633a3a6838373336363164663163303463316637e7043f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a6836643536353630643663653737303936e8047f70616c6c65745f64656d6f63726163793a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f64656d6f63726163793a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6835326237626330383633613465643362e9044170616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a6834623037666463353162383939383938ea043d70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a6833633034346631383532336235666139eb043b70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6261636b696e675f666f723a3a6864386130376463356365613739663666ec043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6863373565363961353434643862303132ed045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6830353866623530366539396665336136ee045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6836323630376138623937616561333436ef049f0170616c6c65745f64656d6f63726163793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a507265696d6167655374617475733c4163636f756e7449642c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6833643935623264323734656539306466f0045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865353132616361303662316134313330f104497061726974795f7363616c655f636f6465633a3a656e636f64655f617070656e643a3a657874726163745f6c656e6774685f646174613a3a6831623937383962616439613065656536f204703c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6830626465626632353966633031623962f3047b6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6465636f64655f6c656e3a3a6833336433396564623631626530643738f4044170616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f656e6163745f70726f706f73616c3a3a6864633334633535663465646232656166f5045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837653263386666386330663931376132f604437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830313931363539336464323665303865f7043c70616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6838663561313062313565616238386461f8043e70616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6839613731373863376632353762646634f9044770616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864363630313832323364363538663163fa049c013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839653936343061373563363536663035fb043f70616c6c65745f6f6666656e6365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6833306633643931663932353732613065fc043e70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830343063663230333563633164666362fd044070616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6831663536323832656232656537376239fe046f3c70616c6c65745f64656d6f63726163793a3a5f5f47657442797465537472756374426c61636b6c6973743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864306132616435366164656331653433ff046e3c70616c6c65745f64656d6f63726163793a3a5f5f47657442797465537472756374566f74696e674f663c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686333323734333335646336633331373180053c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68396131393765386363666230363339338105713c70616c6c65745f64656d6f63726163793a3a5f5f476574427974655374727563745075626c696350726f70733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683033343339626338313964326538326282054970616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68393236393765383731653465663431618305a1013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a507265696d616765427974654465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686132326330646635646132663032313884059a013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68393231633964636166666239653732398505a3013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a46617374547261636b566f74696e67506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683639393965326138316466656531623586059d013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456e6163746d656e74506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683965633966363866326532613463643387054070616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a683931643066343566313138646535643488053c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a683165633030613065306137323031356189053970616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a7570646174655f6c6f636b3a3a68306237323332303437353837333333328a055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68353736613565353061386434623762368b055c3c70616c6c65745f64656d6f63726163793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68303234626133366332633361613636348c0582017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202850302c51302c5230293e3a3a656e636f64655f746f3a3a68393135336435643966623834353661618d053870616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f766f74653a3a68313064326433636461376361613330618e053570616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a70726f78793a3a68323739353238313538613963653139648f055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68376562323737656265643432336362659005437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683433656363366261643662646365333291055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683635663434326137303864373762616592055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a686131373466313939383037313862396593053c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f64656c65676174653a3a683038363531333431346631363130326194053e70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f756e64656c65676174653a3a68306339343637393337616166396437329505776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a686335346231616266633734653139383896055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683638323938316364336131643631353897053f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f72656d6f76655f766f74653a3a686565663931356636626466383631656198054a70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265647563655f757073747265616d5f64656c65676174696f6e3a3a683064643061373065313139336239386499054a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68363162616132623433303539393361669a055d3c70616c6c65745f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732070616c6c65745f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a68376233376537336562663732363061359b056a3c70616c6c65745f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732070616c6c65745f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a7b7b636c6f737572657d7d3a3a68383534646339396665386631643930339c0581013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6761733a3a68303335303838633964666332303034319d058d013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f73746f726167653a3a68656662643636666432363932376636379e058f013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f636c6561725f73746f726167653a3a68626363646632316562636235653533399f058d013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6765745f73746f726167653a3a6837356265373535653466313263373765a0058a013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7472616e736665723a3a6830643733383935356564303664316230a10586013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c3a3a6862313262663739333865353762393637a2058d013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f696e7374616e74696174653a3a6839656562636264333262376438373839a3058b013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7465726d696e6174653a3a6830373334386163386135373838386364a40588013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72657475726e3a3a6863363638623230373537623538373562a50588013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c65723a3a6865386461323932333434376432393864a60589013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f616464726573733a3a6834373335333764656535303064663730a7058b013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f70726963653a3a6836616461373632366133643864306266a8058a013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f6c6566743a3a6833666430316438366336393639306664a90589013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f62616c616e63653a3a6830336533383862613463396637636132aa0593013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f76616c75655f7472616e736665727265643a3a6834646462653665616561396438313866ab0588013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72616e646f6d3a3a6835303266313663336230376132646362ac0585013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6e6f773a3a6863353638323331646463336533373936ad0591013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6d696e696d756d5f62616c616e63653a3a6839326561396436653266353635663632ae0593013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f746f6d6273746f6e655f6465706f7369743a3a6839653962666535396261383662303930af058f013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f64697370617463685f63616c6c3a3a6863643336353634643830633133376164b0058c013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f726573746f72655f746f3a3a6838386534336132646530336464623934b1058e013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f73697a653a3a6837303139636333623961353864393633b2058e013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f726561643a3a6835343832623336393563373937303134b3058f013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f77726974653a3a6839633461373430343739393032623836b4058f013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6465706f7369745f6576656e743a3a6866333961343935306630386338323034b50594013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f72656e745f616c6c6f77616e63653a3a6864306636613538623864636264666338b60590013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72656e745f616c6c6f77616e63653a3a6838353134653630343839393530346161b70589013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7072696e746c6e3a3a6862303738623262643435383035343662b8058e013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f626c6f636b5f6e756d6265723a3a6861356662313538373065386461313535b90595013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6765745f72756e74696d655f73746f726167653a3a6830623930616465383335616464646463ba058f013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f686173685f736861325f3235363a3a6866356635646634623262393263656439bb0591013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f686173685f6b656363616b5f3235363a3a6837666539323932666233353837643334bc0591013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f686173685f626c616b65325f3235363a3a6832366432373238613734623064663831bd0591013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f686173685f626c616b65325f3132383a3a6836353664656638373130303166336330be053e70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a6368617267655f6761733a3a6833343264326238626337633764303261bf053370616c6c65745f636f6e7472616374733a3a657865633a3a7472616e736665723a3a6839353065616664303466613631633736c0054f70616c6c65745f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a696e7374616e74696174653a3a6837326333393439373130303337383537c1052d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6833303639646365353332316537326664c2055f3c70616c6c65745f76657374696e673a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6836396637383763643730633564646231c305613c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6863343035386338336531623237393362c4057c7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c5230293e3a3a6465636f64653a3a6837613662633666663530623563616432c505303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838363134356262326635306231306634c605443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6866643934383032333264636662306439c705533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6863653938353838666331663533653265c805543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861643939656561356336613366313236c9058b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835333064343834303262373132633962ca05513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6830316233366132363737356365623639cb05513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6864316636633833373835616238313737cc05466e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6672616d655f73797374656d3a3a6865623161613639353762323132663936cd05486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7574696c6974793a3a6863616530373132333564336166616335ce05486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f696e64696365733a3a6865323739323066323238376263366633cf05496e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f62616c616e6365733a3a6863383661383130666332396536643662d0054a70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6834666639316130643838646266343337d1055370616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839333563346561333134323263623932d205486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7374616b696e673a3a6864316365643130336365643636363531d305486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f73657373696f6e3a3a6839333339383162343430633764326435d4054a6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f64656d6f63726163793a3a6839656639373339613833636639623831d505556e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f636f6c6c6563746976655f496e7374616e6365313a3a6833643664373237376330363634393766d605536e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f656c656374696f6e735f70687261676d656e3a3a6834336130633465666138323766343239d705556e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6d656d626572736869705f496e7374616e6365313a3a6834656264313639383432376235313532d8054570616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6866656531656332393265316135633063d9055070616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6836393634623035643963626363323166da05683c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6835323637386639303932326239343030db05486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6772616e6470613a3a6830656631386162363435316532383066dc05496e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f74726561737572793a3a6838386238326464633734636436303838dd054070616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863363536326163326638616465363566de053e70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832646562663438626638656135663734df054a6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f636f6e7472616374733a3a6830643036326139336330303036323732e0054970616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6861376639386461353463316338356335e105613c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6832323661383965343737646336663631e205456e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7375646f3a3a6865376131336161623435313138323466e3054a6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f696d5f6f6e6c696e653a3a6864623130613939343133383966393236e405496e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6f6666656e6365733a3a6861333137626439666532363932363063e505496e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6964656e746974793a3a6831633965636538353139383065633563e605486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f736f63696574793a3a6837366239313665353030366435376633e705496e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7265636f766572793a3a6831396435633835636466346536663032e805486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f76657374696e673a3a6836303936386161396662336636653962e9054a6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7363686564756c65723a3a6863346264306238656532396239353963ea059a013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d617856616c756553697a6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863393438343731653466633666303030eb0596013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178446570746844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830333864356532323234303632323362ec059d013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53757263686172676552657761726444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836343830653436366165336364303937ed059f013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744465706f7369744f666673657444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839626530363830656562376135663336ee0599013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744279746546656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836663961393366386466613437636564ef059f013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53746f7261676553697a654f666673657444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838643633303139303332616634633336f005a1013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5369676e6564436c61696d48616e646963617044656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863346466383466376635316164343366f105723c70616c6c65745f636f6e7472616374733a3a5f5f476574427974655374727563745072697374696e65436f64653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839393763623030653134396439313736f205753c70616c6c65745f636f6e7472616374733a3a5f5f4765744279746553747275637443757272656e745363686564756c653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866393832333137383262633461326433f3057a70616c6c65745f636f6e7472616374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6e7472616374733a3a5363686564756c653e3a3a656e636f64655f746f3a3a6832376466393964366137383130313132f405a2013c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5265706f72744c6174656e637944656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833393932333966643833396664313862f5059f013c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862306365323463633437653563363365f605aa013c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862656437356130663137626439343838f705a40170616c6c65745f636f6e7472616374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6e7472616374733a3a526177416c697665436f6e7472616374496e666f3c436f6465486173682c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6834393036313261313163303935356662f8054a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6830343339333663613334336566363630f905ac013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073705f72756e74696d653a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a7b7b636c6f737572657d7d3a3a6835313732306465363738346439346362fa056073705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a736563703235366b315f65636473615f7265636f7665725f636f6d707265737365643a3a6830303331353463306265636239363333fb05713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6834343239616463383933393563666663fc057d3c70616c6c65745f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6863303838393935643661633831383431fd05920170616c6c65745f64656d6f63726163793a3a766f74653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a766f74653a3a4163636f756e74566f74653c42616c616e63653e3e3a3a656e636f64655f746f3a3a6865666438373135663161313033393764fe057d70616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a656e636f64655f746f3a3a6833383035363664353437343365656365ff053f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6831303138393062613431346139333432800668636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a68616431343631393831616133613130348106573c49642061732073705f72756e74696d653a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3c543e3e3a3a696e746f5f7375625f6163636f756e743a3a686563316364626431313036666232653882066f6e6f64655f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a686636653666393138643662376334356183068e0170616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6c6c6563746976653a3a5261774576656e743c486173682c4163636f756e7449642c493e3e3a3a656e636f64655f746f3a3a68326331303235313933333662396166628406763c70616c6c65745f617574686f726974795f646973636f766572793a3a43616c6c3c543e206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a68376239316539663635616365623730398506583c6672616d655f73797374656d3a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a686631356263383935616364623033363486065d3c70616c6c65745f617574686f72736869703a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683365336433353465333864363733333187065a3c70616c6c65745f73657373696f6e3a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683361336639313562353663343735356388065f3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683131393766356464313431393763363989065f3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68363561363031306463626432333664398a065f3c70616c6c65745f6d656d626572736869703a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68333831376537613764316438393663348b065b3c70616c6c65745f74726561737572793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68646136656437623533653762383937338c064470616c6c65745f636f6e7472616374733a3a7761736d3a3a707265706172653a3a707265706172655f636f6e74726163743a3a68306562636136353464356463346135368d064970616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a657865637574655f7761736d3a3a7b7b636c6f737572657d7d3a3a68613037633433343761656339663165378e06573c70616c6c65745f7375646f3a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68656235333666653835313961623535398f065c3c70616c6c65745f736f63696574793a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683837643638326638366266643433353990065b3c70616c6c65745f7265636f766572793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683737626163353439376530613934346491066b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686435323433616462323264653362616692067a3c70616c6c65745f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683334613364393661333031323938636293067a70616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a686464386233316238633161316437383894066c70616c6c65745f7375646f3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7375646f3a3a43616c6c3c543e3e3a3a6465636f64653a3a686665366230643061623361653539363295067470616c6c65745f7265636f766572793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7265636f766572793a3a43616c6c3c543e3e3a3a6465636f64653a3a68343130636536643031343038393037649606437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830383438343261386137346565316564970630636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a68646563306531626466306138343965312e3130373098063a6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683831376537383834613661633166386599063c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68336531316630613964306364333663369a06703c6672616d655f73797374656d3a3a5f5f47657442797465537472756374457865637574696f6e50686173653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68323138303262393830623333346530639b06703c6672616d655f73797374656d3a3a5f5f4765744279746553747275637445787472696e73696373526f6f743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68333131373865326139303164306635309c06693c6672616d655f73797374656d3a3a5f5f476574427974655374727563744163636f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68386561313265336264626535636137369d06456672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68626466626630333830376631616636319e069c013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178696d756d426c6f636b4c656e67746844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68303265663366653630333561346535669f069d013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45787472696e7369634261736557656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835623934353064346537323130363635a0069e013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b457865637574696f6e57656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839613765386561316361323764343865a10692013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a446257656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866653034303734613637623134663162a2069c013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178696d756d426c6f636b57656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832663333303361336535396365363436a3063b70616c6c65745f636f6e7472616374733a3a7761736d3a3a636f64655f63616368653a3a6c6f61643a3a6831393939343334323732646361353233a406aa0170616c6c65745f64656d6f63726163793a3a74797065733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a74797065733a3a5265666572656e64756d5374617475733c426c6f636b4e756d6265722c486173682c42616c616e63653e3e3a3a656e636f64655f746f3a3a6862393137323034313462313038366635a5064170616c6c65745f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6866323964663330623038633836633037a6064370616c6c65745f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6835646331333063393561653063356366a706437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6836633466633039653364333864663661a8064a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6835613261613431373162653338663437a9065d3c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6833643662316337306335303231333962aa0699013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6830353935366365616662323934356336ab068d013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f7072696d653a3a6838336566366439663836303137343563ac062b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a6833636639313337393965633965353439ad064b6672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a7365745f6d656d626572735f736f727465643a3a6839383135333962646438623262626161ae0668636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6862356630623138363637326365383565af062d70616c6c65745f736f63696574793a3a7069636b5f7573697a653a3a6837343739633461336232356230643737b0063b70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a62756d705f7061796f75743a3a6839386439353436356264363863616235b1063c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6866373338333839346538386334323162b206706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6838363237653065643430373430393730b3065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863353830363663306264623464396537b4063e70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a73757370656e645f6d656d6265723a3a6866616665343765383366306564653932b5065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831346538303361656533666439616162b606673c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a6832316461383965366161383535393933b706753c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6830333761643364346366353234343365b8065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863346639373934393861633137303563b9065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834373166333530323666396361386231ba065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837313634653061663836396463356234bb063970616c6c65745f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862643838643265303762666533626239bc063b70616c6c65745f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866323765373566346433356638666136bd06643c70616c6c65745f7375646f3a3a5f5f476574427974655374727563744b65793c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835666533643339363864366535653732be063e70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6838626439623466356662663865626466bf064070616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6831396166623964653934306131636366c0064970616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6833323064366162653830343462633962c10698013c70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6f64756c65496444656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834346566393263616134313163623830c2069e013c70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a526f746174696f6e506572696f6444656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837353731653665353963383161313438c3069b013c70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a506572696f645370656e6444656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839616536316237323166633131323063c4069a013c70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178537472696b657344656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831626131666433373163303130343862c5063d70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6834316666376337643464373064633863c6063f70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835623335363464653439663666616133c7064870616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6831303639633234303865653738333566c80695013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6f64756c65496444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839363964343463333261636534356236c9069a013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a54697046696e6465727346656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863383661336631343061643137663666ca0698013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838343566613030653932383065336130cb0691013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837313762333438363361383631316565cc0699013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862373065636235383833306666313033cd06437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6835383338386439623264613665653565ce0668636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6837326264323932386338376534363531cf065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833373163313531376437393539666637d0065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832323739653231343262613366333463d106493c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68333736613635376637383866316639642e31353034d2065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865653138306264333033636130313663d3065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6866616135386431363235396463666462d4065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6866306235363637663762346264343139d5065c3c70616c6c65745f7375646f3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6831376166616136333265626637393833d6063770616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a7075745f6269643a3a6831643330373763313363393765653438d706456672616d655f737570706f72743a3a7472616974733a3a456e737572654f726967696e3a3a656e737572655f6f726967696e3a3a6831663836393939653965313464616335d8063a70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6164645f6d656d6265723a3a6861333839393863343961623430386131d906603c70616c6c65745f74726561737572793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6864336431366161363130356134326138da06613c70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6864363964616136336130306665386264db063c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6834653362623736613863613666363331dc066b3c73705f61726974686d657469633a3a66697865643132383a3a46697865643132382061732073705f61726974686d657469633a3a7472616974733a3a53617475726174696e673e3a3a73617475726174696e675f6d756c3a3a6831613530653032346332353132376262dd065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832613534656366653262383037666630de06776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6837346164333837356264353232303437df063d70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a7363686564756c655f6368616e67653a3a6866646636343030336636613135643862e0063c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6862616535666330343739363465313432e106683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6831396666356430383165346638376231e206633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835383638636236336632353930666135e3063e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6835326166653137346365323438663833e4063c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832306435616365333761663234623235e5063e70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832396166353464643230343034646563e606703c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637443757272656e7453657449643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838376431323432303135393731343235e7066b3c70616c6c65745f6772616e6470613a3a5f5f476574427974655374727563745374616c6c65643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831376438303138616533323166373233e806693c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832363230386139336637396338633139e9063c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863656665363931333838306262303962ea063e70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6830373865323861366264386533333737eb06703c70616c6c65745f73657373696f6e3a3a5f5f4765744279746553747275637443757272656e74496e6465783c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865336438313432316530386163313232ec062b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6839343863336665383135653764663132ed064770616c6c65745f636f6e7472616374733a3a7761736d3a3a707265706172653a3a436f6e74726163744d6f64756c653a3a6e65773a3a6861623435626538366235333337643233ee0648616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6866623430333137376534626538373836ef063c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a66726f6d5f6d6f64756c653a3a6866333834373962663335336136613366f006537061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a7265736f6c76655f747970655f7265663a3a6834633266623438353162383736646366f106a9017061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c6553636166666f6c643e20666f72207061726974795f7761736d3a3a656c656d656e74733a3a6d6f64756c653a3a4d6f64756c653e3a3a66726f6d3a3a6835306361373739666538313464623463f2062d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6834313530386166653865623432633038f306507061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a707573685f66756e6374696f6e3a3a6866363462363133383937383334613137f4062b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6833616534653964353339636535333539f5063c707761736d5f7574696c733a3a737461636b5f6865696768743a3a696e6a6563745f6c696d697465723a3a6839636130333231656531386331363338f6066b3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6862313134326534323564636135643531f7065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865326666353434643965303731393036f8065f3c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6837663863363935396266643331333939f9065f3c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6835373864323439636139613137316632fa063f70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832363535616164383839393866646332fb064170616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862366162333363643165613139343731fc0634636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6835363762363965366331393861366138fd062e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6862383736626461613861633862333565fe063c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6832393836656661313337343830313433ff0634636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a686138323232383231313635343238376680073f636f72653a3a736c6963653a3a736f72743a3a63686f6f73655f7069766f743a3a7b7b636c6f737572657d7d3a3a683738333761396232663631653834326481072e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a686362653437326364636564643931663782073c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6831643439353266326632616633653931830730636f72653a3a736c6963653a3a736f72743a3a73686966745f7461696c3a3a686562373833323164356566366339326284073b636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a7b7b636c6f737572657d7d3a3a6839663264373835626337393261303131850734636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a683566333032363664303130323665396486072e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a683263353261363266333433633333343987073c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a68373133646261306637393639363532668807623c70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68616432623466393161303466386438658907753c70616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a43616c6c3c543e206173206672616d655f737570706f72743a3a7472616974733a3a47657443616c6c4e616d653e3a3a6765745f63616c6c5f6e616d65733a3a68323961313231653735316234333562318a075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68643034313164373637326466303531658b074a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68383632383539636661633837343062328c075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68613735376630303463336164346130378d073d70616c6c65745f7265636f766572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68623832396330383263663265353362628e073f70616c6c65745f7265636f766572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68303165333565646537383863616465628f074170616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a683464613663376338666466336334666290074370616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a683033613166343366313736636537356691074370616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a68663934633434326563663936303038619207437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683536663833303332356336626564383693075170616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a683535303335613465326161353865656494074a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a683534323939643736623963323661616595075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a686263376264306561336335376635623796075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68626236373865393432336631613237339707706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a68613234653662393932343462623763629807603c70616c6c65745f7265636f766572793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a683533643035366435643235326332366399075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68623435343038346265653437316436649a075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68643535393733393936323038653838659b074470616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a66696e616c697a655f70726f706f73616c3a3a68616436343066333133306630313965359c075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68663838336661643664393038326338389d075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68356535616238393063626561343132399e075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68626662363364353833396563376539619f074470616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a66696e616c697a655f70726f706f73616c3a3a6866643633623434313664643633303236a0075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861663736336438386137366332316438a107643c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6831343061333461373132356364386363a207683c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6834633439393331653735616331303138a3076b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6864356135626266333165343636323863a4077d3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973745772697465723c492c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6831666265366561303230383136373939a5076f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6862386538363632373939653530373036a6076f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743634206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6831363563383135396232653962303266a7076c3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6837303733363332303830643532303037a8076f3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6863656638303132636264353065663931a90737616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6865643330346464376366633233646363aa07443c7061726974795f7761736d3a3a696f3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830363338666230393435646262316335ab07793c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973743c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6862363633343636326632653739666337ac076b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6833326532316261643239303066363766ad0786017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a646573657269616c697a653a3a6863353961393931616461356430623731ae07323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6834666334636132316331623933643033af07783c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6832643663653261356166653563383933b0077c3c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6838626232643362346332336531633565b1076f3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6837663765346430383832396631323139b207463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6833376132336136316462616631363131b307463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6863643738643132376462383834626331b407463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6834663939323932346130383535613964b5074f7761736d695f76616c69646174696f6e3a3a636f6e746578743a3a4d6f64756c65436f6e746578744275696c6465723a3a707573685f676c6f62616c3a3a6862636338656463363736323264336163b607587761736d695f76616c69646174696f6e3a3a636f6e746578743a3a4d6f64756c65436f6e746578744275696c6465723a3a707573685f66756e635f747970655f696e6465783a3a6861356466303736306130303135376138b707397761736d695f76616c69646174696f6e3a3a76616c69646174655f6d656d6f72795f747970653a3a6831383633306138366563393738353763b807347761736d695f76616c69646174696f6e3a3a657870725f636f6e73745f747970653a3a6833613736663931623637613733323066b907553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861643864386337663861313638323138ba0737616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6839613162383130373666393532313831bb074a7761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a737465703a3a6837376339326138323465313365383937bc07473c7761736d695f76616c69646174696f6e3a3a4572726f7220617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6864656161653436366361623262613537bd07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830613238336532663738663661326566be072d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6831363439613438666466323361333234bf07457061726974795f7761736d3a3a656c656d656e74733a3a7365676d656e743a3a446174615365676d656e743a3a76616c75653a3a6866626639333864636633313437393639c007743c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a56617255696e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6833623230373765376464326631363864c107713c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a437573746f6d53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6864663763623061633039343731666132c207713c7061726974795f7761736d3a3a656c656d656e74733a3a696e6465785f6d61703a3a496e6465784d61703c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6864666232373762626563613239623830c3074b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6865633837386535616238626531386461c4074b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6865656338373534646334383636656137c5074b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6839313737336537633930356339383138c6074b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6833333565616231613531386161623564c707457061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e5265616465723a3a6e65773a3a6832623264323232373937343937323061c80734636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6836343538633738383030373433303233c9072e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6831306338313934323835623434626230ca073c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6864613432613230353866666131383664cb073b636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a7b7b636c6f737572657d7d3a3a6835383437313839323762303531653533cc07513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6832663135653939656239653139333630cd07553c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832303532316635393734663134313935ce07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863383639356162343734343836336363cf07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864613136343061353937346565313763d007303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830353832373464653465663439383937d107303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865396662333236613732333063383332d207553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a426c6f636b5479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837323362653966316562343863383163d307303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835366339366664633833326565393861d407303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835666561393361383663313330373437d507303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6866636266616465653635666130653233d607483c616c6c6f633a3a626f7865643a3a426f783c5b545d3e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6863633537623165633463306466373734d707593c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831323935353262336336633161383561d807303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863373464613163386662353263386639d9072e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6863663136636133313038386537343636da073c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6831313032373164326234386463616666db0741707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a636f6d707574653a3a6837656330646464396561363763366134dc075a3c707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a4672616d6520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831643937376433336462393035613166dd0746707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a6672616d653a3a6831636263656662616631333631356230de07453c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864626634366461626130636234616438df074b707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a706f705f76616c7565733a3a6863356261643934666164326137633337e0073f707761736d5f7574696c733a3a737461636b5f6865696768743a3a7265736f6c76655f66756e635f747970653a3a6835623034396663666265376561646530e107613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6835373163636462353465633063306339e207303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834373738326234376365343162386331e30733636f72653a3a6f7074696f6e3a3a4f7074696f6e3c26543e3a3a636c6f6e65643a3a6833623861386631386663366664343632e40740707761736d5f7574696c733a3a737461636b5f6865696768743a3a636f6d707574655f737461636b5f636f73743a3a6861323533626530386134336531623837e507323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6837613135656265343936356665396133e6073a73705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6c73747269703a3a6836646436653963623432323733363663e7073773705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6164643a3a6830316434306537663531376362383139e8073773705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6d756c3a3a6866643130333939633138306330393161e9074473705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6469763a3a7b7b636c6f737572657d7d3a3a6866383462626664386539613033646631ea074b3c73705f61726974686d657469633a3a62696775696e743a3a42696755696e7420617320636f72653a3a636d703a3a4f72643e3a3a636d703a3a6834343461643533633863373732383630eb07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837333938323135383866653231386330ec07513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6861616431376235343262386136333034ed07413c73705f696e686572656e74733a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6866646363643030363831623962623332ee07323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6834386262343837633064373131326537ef074273705f696f3a3a6c6f6767696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6c6f673a3a6866343962313237633262386461396133f007573c73705f72756e74696d653a3a72756e74696d655f737472696e673a3a52756e74696d65537472696e6720617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839343732383631363335666331333066f107473c73705f72756e74696d653a3a44697370617463684572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839393631343466363366333061303337f207347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f76616c75653a3a6838613630623536373166386263396664f307347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f6c6162656c3a3a6865333162373732616530303563363736f407347761736d695f76616c69646174696f6e3a3a66756e633a3a7465655f76616c75653a3a6837646138326332343962306562633331f507407761736d695f76616c69646174696f6e3a3a7574696c3a3a4c6f63616c733a3a747970655f6f665f6c6f63616c3a3a6838636138323766646134356339313330f607543c7761736d695f76616c69646174696f6e3a3a66756e633a3a537461636b56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835353532326133316636303964363937f707537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6c6f61643a3a6830376132393432636464306365343338f807547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f73746f72653a3a6831323764353062613862376333643439f907547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f72656c6f703a3a6861343966626334643365306136373739fa07547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f62696e6f703a3a6838656230653936636235643135343234fb073b616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a6831363031666261373561616639383461fc0737616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830313230663136306336333962303561fd073b636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f70795f66726f6d5f736c6963653a3a6862656366363865633237636235336665fe072b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6861626461346364333962343639396563ff07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68323235343564613034363464666239398008453c616c6c6f633a3a737472696e673a3a537472696e6720617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683430363536353032386339373630633381084c3c7761736d695f76616c69646174696f6e3a3a737461636b3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861313263303261643833303862306162820838636f6d70696c65725f6275696c74696e733a3a696e743a3a6d756c3a3a5f5f6d756c7469333a3a6839373632626331636361303166383364830839636f6d70696c65725f6275696c74696e733a3a696e743a3a6d756c3a3a5f5f6d756c6f7469343a3a68323735656632666138626166616237318408085f5f6d756c7469338508095f5f6d756c6f7469348608095f5f756d6f6474693387082b636f6d70696c65725f6275696c74696e733a3a61626f72743a3a6837373662356362633663393964313163880839636f6d70696c65725f6275696c74696e733a3a696e743a3a736469763a3a5f5f6469767469333a3a68353431303861623133616630373236328908463c69363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a66726f6d5f756e7369676e65643a3a68623233353336366166363766393733388a08453c75363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a61626f7274696e675f6469763a3a68353339326136663336363336656339308b08453c75363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a61626f7274696e675f72656d3a3a68636165613162386434353561363334398c08453c69363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a7772617070696e675f6164643a3a68356438303838653933313037343366398d08453c69363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a7772617070696e675f6d756c3a3a68616366346631393365666533333565668e08473c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a66726f6d5f756e7369676e65643a3a68396361396438643435306530333130398f08463c7531323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a61626f7274696e675f6469763a3a68646461633866376335323365633534389008433c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a6d61785f76616c75653a3a68313965366462646366643839343564339108433c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a6d696e5f76616c75653a3a68396138626366656461353838656165339208463c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a7772617070696e675f6d756c3a3a68663762643232353766633537633430369308463c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a7772617070696e675f7375623a3a68323165393061666464326361353338329408463c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a61626f7274696e675f6469763a3a68313361346530633765653064303163399508423c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a4c61726765496e743e3a3a6c6f773a3a68633539396133336534633865356161339608433c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a4c61726765496e743e3a3a686967683a3a68666365633135386664353336366161629708493c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a4c61726765496e743e3a3a66726f6d5f70617274733a3a68646135326234366661633734663438379808095f5f7564697674693399083a636f6d70696c65725f6275696c74696e733a3a696e743a3a756469763a3a5f5f756469767469333a3a68316538396139356663646439323031339a083d636f6d70696c65725f6275696c74696e733a3a696e743a3a756469763a3a5f5f756469766d6f647469343a3a68633262343431643430303733343161669b083a636f6d70696c65725f6275696c74696e733a3a696e743a3a756469763a3a5f5f756d6f647469333a3a68653963366462306266373836386263319c08085f5f6469767469339d08066d656d6370799e08076d656d6d6f76659f08066d656d736574a0080462636d70a1083b636f6d70696c65725f6275696c74696e733a3a696e743a3a73686966743a3a5f5f6173686c7469333a3a6838656231636163626365343565313733a2083b636f6d70696c65725f6275696c74696e733a3a696e743a3a73686966743a3a5f5f6c7368727469333a3a6861613765666137333665663233346637a308095f5f6173686c746933a408095f5f6c73687274693300550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e34352e302d6e696768746c79202866613531663831306520323032302d30342d323929", - "0x5f3e4907f716ac89b6347d15ececedcaa141c4fe67c2d11f4a10c6aca7a79a04b4def25cfda6ef3a00000000": "0xd8ff03bfc91b8e000000000000000000", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d49dd691c4fe7bf66772616e803919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x5f3e4907f716ac89b6347d15ececedcab49a2738eeb30896aacb8b3fb46471bd": "0x04000000", "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a000000007441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x00", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195081918b9c078ba64f696d6f6e8000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade987441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x00", + "0x426e15054d267946093858132eb537f1a47a9ff5cd5bf4d848a80a0b1a947dc3": "0x00000000000000000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca487df464e44a534ba6b0cbb32407b587": "0x0000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950d49dd691c4fe7bf66772616e803919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a00000000c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195018823a93d5cac7d062616265806e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb3c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950f05c8ba6ac2a99ca6175646980482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc47bd1e6299d2e71c4c848a957ae243d7b9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d650f0000c16ff286230f0000c16ff286230000", - "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a0000000079091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x0ff6ffc06ff286230ff6ffc06ff2862300", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195090ae3b675fd0a89f6175646980482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc469a5ec1b3cb6032ce536e31d5679de28c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde780f0000c16ff286230f0000c16ff286230000", - "0xe2e62dd81c48a88f73b6f6463555fd8e71cd3068e6118bfb392b798317f63a89d28ebd9aad2de6179ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809": "0x0000c16ff28623000000000000000000049ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", - "0x5f3e4907f716ac89b6347d15ececedcae1791577e4efcb083fdc3cb21e85b2e4": "0x00", - "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", - "0xe2e62dd81c48a88f73b6f6463555fd8eba7fb8745735dc3be2a2c61a72c39e78": "0x049ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e3180973474718090000c16ff28623000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950a7c05e469443baab617564698000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6a8d6d78917f3d243ed0a3d1dfb3878099c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x047374616b696e67200000c16ff2862300000000000000000002", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe707441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e169037441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x00", "0x2099d7f109d6e535fb000bba623fd4409f99a2ce711f3a31b2fc05604c93f179": "0x106e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f910600299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", - "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a0000000079091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x0ff6ffc06ff286230ff6ffc06ff2862300", - "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade987441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x00", - "0x2371e21684d2fae99bcb4d579242f74a8a2d09463effcc78a22d75b9cb87dffc": "0x0000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b2a4e124620611833d1b252494468c2a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x00000000030000c16ff28623000000000000000000000000000000000000000000000000000000c16ff286230000000000000000000000c16ff28623000000000000000000", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950606e9687c0a4d75f696d6f6e80482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0xd503106e6f6465", - "0x5f3e4907f716ac89b6347d15ececedcaea07de2b8f010516dca3f7ef52f7ac5a": "0x040000000000000000", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195003e77b7332307fb461756469806e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195050b3bd0c839f9eac6772616e807932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a0000000079091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x00", - "0xcec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903": "0x109c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x2b06af9719ac64d755623cda8ddd9b949f99a2ce711f3a31b2fc05604c93f179": "0x106e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f910600299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e", + "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0x9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc40a81aa5d99517e5635e7865ccd909c4066bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c26630f0000c16ff286230f0000c16ff286230000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9bed2903186223711a06d85784e730efd547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x00000000030000c16ff28623000000000000000000000000000000000000000000000000000000c16ff286230000000000000000000000c16ff28623000000000000000000", + "0x2371e21684d2fae99bcb4d579242f74a8a2d09463effcc78a22d75b9cb87dffc": "0x0000000000000000", + "0x426e15054d267946093858132eb537f1d0b4a3f7631f0c0e761898fe198211de": "0xe7030000", "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", - "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe7054352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9a8d6d78917f3d243ed0a3d1dfb3878099c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x00000000030000c16ff28623000000000000000000000000000000000000000000000000000000c16ff286230000000000000000000000c16ff28623000000000000000000", - "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a0000000054352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x0ff6ffc06ff286230ff6ffc06ff2862300", - "0x5f3e4907f716ac89b6347d15ececedcab49a2738eeb30896aacb8b3fb46471bd": "0x04000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950414ee903f38cbde66772616e805633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb379091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a", "0x5f3e4907f716ac89b6347d15ececedca308ce9615de0775a82f8a94dc3d285a1": "0x02", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195082c7c7fe191a6e68696d6f6e80482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6bed2903186223711a06d85784e730efd547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x047374616b696e67200000c16ff2862300000000000000000002", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc469a5ec1b3cb6032ce536e31d5679de28c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde780f0000c16ff286230f0000c16ff286230000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6b2a4e124620611833d1b252494468c2a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x047374616b696e67200000c16ff2862300000000000000000002", + "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc47bd1e6299d2e71c4c848a957ae243d7b9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d650f0000c16ff286230f0000c16ff286230000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9a831cc69a96025a90c389ecb19a25ff29ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809": "0x000000000100405f2954c5c535360000000000000000c040b571e8030000000000000000000000c16ff2862300000000000000000000000000000000000000000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195057479bdad16c7a386261626580482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade9854352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x00", + "0x3a6772616e6470615f617574686f726974696573": "0x01109becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe969933201000000000000003919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef01000000000000005633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce44001000000000000007932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f0100000000000000", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950dd81945454d561f36261626580482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", + "0x11f3ba2e1cdd6d62f2ff9b5589e7ff81ba7fb8745735dc3be2a2c61a72c39e78": "0x049ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", + "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000": "0x4545454545454545454545454545454545454545454545454545454545454545", "0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x106e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106010000000000000000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f43780100000000000000482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a0100000000000000482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e0100000000000000", - "0x5c0d1176a568c1f92944340dbfed9e9c530ebca703c85910e7164cb7d1c9e47b": "0x9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", + "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade9879091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x00", + "0x8985776095addd4789fccbce8ca77b23ba7fb8745735dc3be2a2c61a72c39e78": "0x049ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", + "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", + "0x426e15054d267946093858132eb537f105fe52c2045750c3c492ccdcf62e2b9c": "0x9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", + "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e1690379091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x00", + "0x5f3e4907f716ac89b6347d15ececedcaea07de2b8f010516dca3f7ef52f7ac5a": "0x040000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe7054352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276", "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe70c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0xc8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e", - "0x3a6772616e6470615f617574686f726974696573": "0x01109becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe969933201000000000000003919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef01000000000000005633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce44001000000000000007932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f0100000000000000", - "0x5f3e4907f716ac89b6347d15ececedca682db92dde20a10d96d00ff0e9e221c0b4def25cfda6ef3a0000000054352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x00", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195088c3e18f0a370f936772616e809becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x426e15054d267946093858132eb537f195999521c6c89cd80b677e53ce20f98c": "0x9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", + "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6a831cc69a96025a90c389ecb19a25ff29ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809": "0x04706872656c6563740000c16ff2862300000000000000000001", + "0x3a636f6465": "0x0061736d01000000018e033760037f7f7f017f60027f7f017f60027f7f0060017f0060037f7f7f0060057f7f7f7f7f0060047f7f7f7f0060017f017e60037f7e7e0060017e017f60027e7e0060017e017e60017e006000006000017f60027f7e017e60047f7e7e7e017f60027e7e017e60037e7e7e0060037f7e7f017f60047f7e7e7f017f60067f7e7e7f7f7f017f60047f7f7f7f017f6000017e60037e7e7f017e60017f017f60027f7e017f60027f7f017e60037f7f7e017e60037e7f7f017f60067f7f7f7f7f7f017f60077f7f7f7f7f7f7f017f60057f7f7f7f7f017f60027f7e0060047f7f7e7e0060057f7e7e7f7f0060057f7f7f7e7e0060067f7f7f7f7f7f0060057f7f7e7e7f0060047e7e7e7e017f60067f7f7f7e7e7f0060077f7e7e7e7e7e7e0060067f7f7e7f7e7e0060077f7f7f7e7e7f7f0060077f7f7f7f7e7e7f0060087e7e7e7e7e7e7e7e017f60047f7f7f7f017e60067f7f7f7f7e7e0060057f7e7e7e7e0060087f7f7f7f7f7e7e7f0060077f7f7e7e7f7f7f0060027e7f0060037f7e7f0060067f7e7e7e7e7f0060047f7e7e7f0002cd103403656e76066d656d6f727902001403656e76196578745f6c6f6767696e675f6c6f675f76657273696f6e5f31000803656e761e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f31000903656e76196578745f73746f726167655f7365745f76657273696f6e5f31000a03656e761d6578745f68617368696e675f74776f785f36345f76657273696f6e5f31000903656e76206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f31000903656e76196578745f73746f726167655f6765745f76657273696f6e5f31000b03656e761d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f31000c03656e761b6578745f73746f726167655f636c6561725f76657273696f6e5f31000c03656e76226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f31000c03656e76206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f31000903656e761c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f31000c03656e76276578745f63727970746f5f73746172745f62617463685f7665726966795f76657273696f6e5f31000d03656e76286578745f63727970746f5f66696e6973685f62617463685f7665726966795f76657273696f6e5f31000e03656e76236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f31000e03656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f31000f03656e76346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f31001003656e76276578745f64656661756c745f6368696c645f73746f726167655f6765745f76657273696f6e5f31001103656e76306578745f64656661756c745f6368696c645f73746f726167655f73746f726167655f6b696c6c5f76657273696f6e5f31000c03656e76276578745f64656661756c745f6368696c645f73746f726167655f7365745f76657273696f6e5f31001203656e76296578745f64656661756c745f6368696c645f73746f726167655f636c6561725f76657273696f6e5f31000a03656e76226578745f6f6666636861696e5f72616e646f6d5f736565645f76657273696f6e5f31000e03656e76236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f32001303656e76286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f31000803656e76206578745f73616e64626f785f6d656d6f72795f6e65775f76657273696f6e5f31000103656e76256578745f73616e64626f785f6d656d6f72795f74656172646f776e5f76657273696f6e5f31000303656e76216578745f73616e64626f785f696e7374616e74696174655f76657273696f6e5f31001403656e761c6578745f73616e64626f785f696e766f6b655f76657273696f6e5f31001503656e76276578745f73616e64626f785f696e7374616e63655f74656172646f776e5f76657273696f6e5f31000303656e76206578745f73616e64626f785f6d656d6f72795f6765745f76657273696f6e5f31001603656e76206578745f73616e64626f785f6d656d6f72795f7365745f76657273696f6e5f31001603656e761e6578745f68617368696e675f736861325f3235365f76657273696f6e5f31000903656e76206578745f68617368696e675f6b656363616b5f3235365f76657273696f6e5f31000903656e76236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f31001303656e76286578745f64656661756c745f6368696c645f73746f726167655f726f6f745f76657273696f6e5f31000b03656e761c6578745f73746f726167655f617070656e645f76657273696f6e5f31000a03656e761a6578745f73746f726167655f726f6f745f76657273696f6e5f31001703656e76226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f31000b03656e76226578745f6d6973635f72756e74696d655f76657273696f6e5f76657273696f6e5f31000b03656e761c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f31000c03656e761e6578745f73746f726167655f6e6578745f6b65795f76657273696f6e5f31000b03656e762a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f31000903656e76246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f31001703656e76296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f31000b03656e761a6578745f73746f726167655f726561645f76657273696f6e5f31001803656e761e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f31001903656e761c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f31000303656e76256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f31001a03656e76376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f31001b03656e76256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f31001a03656e76286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f31000703656e76216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f31001c03f407f20719190303000019191b0d0d0d04040204000d0d0500010102010202020204011d0303071e1604040005010101191f01010104010100062001010001010000010003040102020402040200010104010201010203040404040404040404040404040402040404040404040404040404040404040404040402040302020401020304040202020202020202040202020403210202020102070205220502040206040404040404040302040202042308020202030d1903020202040202020202020102030202020202040306022002020401192402040402020425020203020426020220022722010403060604020303030d020202020506060402030102030106020404040402020402030302190202020402040402020202040204040402020401040404020204020402020202040404020404010228020319220204020228060303020303030202030202020206250103020604020204030419190402020303290303040404040402020202020202020202020202020d02020204040402020403031b021b0203020202060d0303020202011b021b031b02021b021b02020202021b041b041b020204042a04021b020502010201020d1b021b1b1b1b021b2b022c1b02041b05051b1b04041b02020d020203040504010406020203020302020405040104020202030302292d01052700030303030202020202020202022206020402040402020303010403050101010d020302020402040c02020407021d21030303030303030302040202010102030001012e02020602020602020402020202060402040202030303020303030202020203020202020302020204020602020202022f020202063002250d06060606060606060606060606060606060606060606060606060606060606060606163132060303020102020202020403030303030303030303030303030303030303030303030303030303030302020202020202020202020202020216040202020203040202020d0406040404040406020404040202020202040303030202020302020202020402030302040306030206040122040402030204070202020303020303030202020203030302020202020200020202020202032602020303023002330504020204030302020203030203060202010206020204040203030303020201020604000406020201030302020203030303030203020202040302020602020206020304040504340202020102040201050202030303040202060102040101050202040403030303020202010402010101010101010101040201020104010401040403010204010304041901010201010501010604060401050504040204060301010130353035300d300b1111111108300303303030111108303035303000000000363636360407017001a902a9020619037f01418080c0000b7f00419cb5cc000b7f00419cb5cc000b07e8051a195f5f696e6469726563745f66756e6374696f6e5f7461626c65010009686173685f74657374003b0c436f72655f76657273696f6e00b30312436f72655f657865637574655f626c6f636b00b50315436f72655f696e697469616c697a655f626c6f636b00c303114d657461646174615f6d6574616461746100c5031c426c6f636b4275696c6465725f6170706c795f65787472696e73696300c7031b426c6f636b4275696c6465725f66696e616c697a655f626c6f636b00ca0320426c6f636b4275696c6465725f696e686572656e745f65787472696e7369637300cc031c426c6f636b4275696c6465725f636865636b5f696e686572656e747300d20318426c6f636b4275696c6465725f72616e646f6d5f7365656400d4032b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6e00d603214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b657200de031e4772616e6470614170695f6772616e6470615f617574686f72697469657300e70315426162654170695f636f6e66696775726174696f6e00e9031b426162654170695f63757272656e745f65706f63685f737461727400ea0321417574686f72697479446973636f766572794170695f617574686f72697469657300eb031d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e636500ec0311436f6e7472616374734170695f63616c6c00ee0318436f6e7472616374734170695f6765745f73746f7261676500f2031c436f6e7472616374734170695f72656e745f70726f6a656374696f6e00f503205472616e73616374696f6e5061796d656e744170695f71756572795f696e666f00f8032153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b65797300f9031f53657373696f6e4b6579735f6465636f64655f73657373696f6e5f6b65797300fc030a5f5f646174615f656e6403010b5f5f686561705f62617365030209be04010041010ba8024b51655cee075d5e8201c60171dd04c203e203e403bd04be049c059d059e059f05a005a105a205a305a405a505a605a705a805a905aa05ab05ac05ad05ae05af05b005b105b205b305b405b505b605b705b805b905ba05bb05bc05bd05e304dc04c505aa07b907bc07bd07ae0766e507f607d2078008dc07de07544748497555676a6b6c6d6e7c7d7e80018101850183018401f001eb06ef018105e8019a06ee01ed01ec01eb01e901e701f501f40162f302f702a904ee05fd02fc02fb02fa0263e6068c048f048e04a804a704a604a504b804f007bf04d804eb07e004e104e204fe04ff048605fa04850584058305e706f10799069806cc059d06a90693039203cd058907b2038b048d04d604d504d704fb06fa06880799049804ce05f202f102cf05f4028803d005d105e601e301d205f3019f02ea06e906d305f906fd04fc04d4058205c30591078f07d505a1079007f602f502d605f9029003a606a506d705d805d905da05e506e406db05f806c606c506dc05c706d906dd05de05df05e005e105bc06bb06e205d506d404d204e305df04fb04e4059307a204a104e505a404b704bf06be06e605c006da068e078d07e7059807f804f704e805f904c2058705e905f005ef05ed05ec05eb05ea05f205f105f505f405f605d4079c069b06a206a106a0069f069e06bd06c406c306c206c106cc06cb06ca06c906c80684048504870486048304f003e206e106e306e806ec06910492049404930490049504ed07ce07d107cf07d307d507d007e207d807fe078108ff070a9ca066f2070600200010340b06002000102c0b0600200010360b06002000102d0b0a0020002001200210380b2801017f02402002102c2203450d002003200020022001200120024b1b109d081a2000102d0b20030b06002000103a0b1c01017f02402000102c2201450d00200141002000109f081a0b20010bff0202017f037e230041206b220224002001ad42adfed5e4d485fda8d8007e42b9e0007c210302400240024002400240200141084b0d00200141014b0d0120010d02420021040c030b0240200141104b0d00200241106a2000290000200385420042adfed5e4d485fda8d8004200108408200241186a29030020022903107c200120006a41786a2900008521040c040b200120006a41786a2900002105200321040340200029000020048542adfed5e4d485fda8d8007e42178942adfed5e4d485fda8d8007e2003852103200041086a2100200442cf829ebbefefde82147c2104200141786a220141084b0d000b200320058521040c030b0240200141034b0d00200120006a417e6a33000042108620003300008420038521040c030b200120006a417c6a35000042208620003500008420038521040c020b200031000021040b200420038521040b20022004420042adfed5e4d485fda8d8004200108408200241086a290300210420022903002103200241206a2400200420037c42c300850b0500103d000b2400410041d09bcc00ad4280808080f0008441d79bcc00ad4280808080a00484100000000b1100418080c0004111419480c000103f000b4701017f230041206b22032400200341146a4100360200200341b0b4cc00360210200342013702042003200136021c200320003602182003200341186a36020020032002104c000bdd0101047f0240024002400240200041046a2802002203200041086a28020022046b200220016b2202490d00200028020021050c010b200420026a22052004490d01200341017422062005200620054b1b22064100480d010240024002402003450d00200028020022050d010b024020060d00410121050c020b2006103322050d010c040b024020032006460d00200520032006103721050b2005450d03200041086a28020021040b20002005360200200041046a20063602000b200520046a20012002109d081a200041086a200420026a3602000f0b103e000b103c000b8b0301067f230041306b2202240020012802002103024002402001280204220441037422050d00410021060c010b200341046a2107410021060340200728020020066a2106200741086a2107200541786a22050d000b0b024002400240024002400240200141146a2802000d00200621070c010b024020040d004100410041bc80c0001042000b024002402006410f4b0d00200341046a280200450d010b200620066a220720064f0d010b4100210741012105200241086a21060c010b2007417f4c0d01200241086a2106024020070d0041002107410121050c010b200710332205450d020b20024100360210200220053602082002200736020c2002200241086a360214200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318200241146a41cc80c000200241186a10430d0220002006290200370200200041086a200641086a280200360200200241306a24000f0b1044000b1045000b41e480c0004133200241186a419881c00041a881c0001046000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341c886c000360208200341013602242003200341206a360218200320033602282003200341046a360220200341086a2002104c000bba06010a7f230041306b22032400200341246a2001360200200341033a002820034280808080800437030820032000360220410021042003410036021820034100360210024002400240024020022802082205450d0020022802002106200228020422072002410c6a2802002208200820074b1b2209450d01200241146a280200210a2002280210210b41012108200020062802002006280204200128020c1100000d03200541106a2102200641086a2100410121040240024003402003200241746a28020036020c20032002410c6a2d00003a00282003200241786a280200360208200241086a28020021084100210541002101024002400240200241046a2802000e03010002010b2008200a4f0d032008410374210c41002101200b200c6a220c2802044102470d01200c28020028020021080b410121010b2003200836021420032001360210200228020021080240024002402002417c6a2802000e03010002010b2008200a4f0d0420084103742101200b20016a22012802044102470d01200128020028020021080b410121050b2003200836021c200320053602180240200241706a2802002208200a4f0d00200b20084103746a2208280200200341086a20082802041101000d06200420094f0d05200041046a210120002802002105200241206a2102200041086a210041012108200441016a2104200328022020052001280200200328022428020c110000450d010c070b0b2008200a41a08bc0001042000b2008200a41908bc0001042000b2008200a41908bc0001042000b2002280200210620022802042207200241146a2802002208200820074b1b220a450d002002280210210241012108200020062802002006280204200128020c1100000d02200641086a21004101210403402002280200200341086a200241046a2802001101000d022004200a4f0d01200041046a210120002802002105200241086a2102200041086a210041012108200441016a2104200328022020052001280200200328022428020c110000450d000c030b0b0240200720044d0d00410121082003280220200620044103746a22022802002002280204200328022428020c1100000d020b410021080c010b410121080b200341306a240020080b0500103e000b0500103c000b7e01017f230041c0006b220524002005200136020c2005200036020820052003360214200520023602102005412c6a41023602002005413c6a41033602002005420237021c200541cc92c800360218200541043602342005200541306a3602282005200541106a3602382005200541086a360230200541186a2004104c000b120020002802002001200120026a104041000bcb0301047f230041106b22022400200028020021000240024002400240024002402001418001490d002002410036020c2001418010490d012002410c6a210302402001418080044f0d0020022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c050b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010c040b0240024020002802082203200041046a280200460d00200028020021040c010b200341016a22042003490d02200341017422052004200520044b1b22054100480d020240024002402003450d00200028020022040d010b024020050d00410121040c020b2005103322040d010c050b024020032005460d00200420032005103721040b2004450d04200028020821030b20002004360200200041046a20053602000b200420036a20013a00002000200028020841016a3602080c040b20022001413f71418001723a000d20022001410676411f7141c001723a000c2002410c6a2103410221010c020b103e000b103c000b20002003200320016a10400b200241106a240041000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41cc80c000200241086a10432101200241206a240020010b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c2002419482c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41ac82c000104c000b0d0020003502004101200110520b3401017f230041106b220224002002200136020c20022000360208200241d886c000360204200241b0b4cc0036020020021053000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241fc82c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a419483c000104c000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c200241d083c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41e883c000104c000b6f01017f230041306b2202240020022001360204200220003602002002411c6a41023602002002412c6a41013602002002420337020c2002418c84c000360208200241013602242002200241206a3602182002200241046a36022820022002360220200241086a41a484c000104c000bc40101037f0240024002402002417f4c0d000240024020020d0041002103410121040c010b20022103200210332204450d020b0240024020032002490d00200321050c010b02400240200341017422052002200520024b1b22054100480d00024002402003450d0020040d010b2005103322040d030c060b20032005470d01200321050c020b103e000b20042003200510372204450d030b200420012002109d0821032000200236020820002005360204200020033602000f0b1044000b1045000b103c000b0d0020002802001a037f0c000b0bd40203027f017e037f230041306b22032400412721040240024020004290ce005a0d00200021050c010b412721040340200341096a20046a2206417c6a200020004290ce0080220542f0b17f7e7ca7220741ffff037141e4006e2208410174419a87c0006a2f00003b00002006417e6a2008419c7f6c20076a41ffff0371410174419a87c0006a2f00003b00002004417c6a2104200042ffc1d72f5621062005210020060d000b0b02402005a7220641e3004c0d00200341096a2004417e6a22046a2005a7220741ffff037141e4006e2206419c7f6c20076a41ffff0371410174419a87c0006a2f00003b00000b024002402006410a480d00200341096a2004417e6a22046a2006410174419a87c0006a2f00003b00000c010b200341096a2004417f6a22046a200641306a3a00000b2002200141b0b4cc004100200341096a20046a412720046b10562104200341306a240020040b6f01017f230041c0006b220124002001200036020c200141346a41013602002001420137022420014188b2cc003602202001410536023c2001200141386a36023020012001410c6a360238200141106a200141206a1041410141d09bcc0041072001280210200128021810ef0700000b02000b0d0042a98089cda5ebd0e9ae7f0b830601067f024002402001450d00412b418080c4002000280200220641017122011b2107200120056a21080c010b200541016a210820002802002106412d21070b0240024020064104710d00410021020c010b4100210902402003450d002003210a200221010340200920012d000041c00171418001466a2109200141016a2101200a417f6a220a0d000b0b200820036a20096b21080b410121010240024020002802084101460d00200020072002200310570d012000280218200420052000411c6a28020028020c11000021010c010b02402000410c6a280200220920084b0d00200020072002200310570d012000280218200420052000411c6a28020028020c1100000f0b0240024020064108710d0041002101200920086b22092108024002400240410120002d0020220a200a4103461b0e0402010001020b20094101762101200941016a41017621080c010b41002108200921010b200141016a210103402001417f6a2201450d0220002802182000280204200028021c280210110100450d000b41010f0b200028020421062000413036020420002d0020210b41012101200041013a0020200020072002200310570d0141002101200920086b220a2103024002400240410120002d0020220920094103461b0e0402010001020b200a4101762101200a41016a41017621030c010b41002103200a21010b200141016a2101024003402001417f6a2201450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210a41012101200028021820042005200028021c28020c1100000d01200341016a2109200028021c210320002802182102024003402009417f6a2209450d01410121012002200a20032802101101000d030c000b0b2000200b3a00202000200636020441000f0b2000280204210a41012101200020072002200310570d00200028021820042005200028021c28020c1100000d00200841016a2109200028021c210320002802182100034002402009417f6a22090d0041000f0b410121012000200a2003280210110100450d000b0b20010b5401017f024002402001418080c400460d0041012104200028021820012000411c6a2802002802101101000d010b024020020d0041000f0b2000280218200220032000411c6a28020028020c11000021040b20040b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c200341e488c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002104c000b6c01017f230041306b2203240020032001360204200320003602002003411c6a41023602002003412c6a41013602002003420237020c2003419c89c000360208200341013602242003200341206a3602182003200341046a36022820032003360220200341086a2002104c000b9307010c7f200041106a28020021030240024002400240200041086a28020022044101460d0020034101460d012000280218200120022000411c6a28020028020c11000021030c030b20034101470d010b0240024020020d00410021020c010b200120026a2105200041146a28020041016a21064100210720012103200121080340200341016a210902400240024020032c0000220a417f4a0d000240024020092005470d004100210b200521030c010b20032d0001413f71210b200341026a220921030b200a411f71210c0240200a41ff0171220a41df014b0d00200b200c41067472210a0c020b0240024020032005470d004100210d2005210e0c010b20032d0000413f71210d200341016a2209210e0b200d200b41067472210b0240200a41f0014f0d00200b200c410c7472210a0c020b02400240200e2005470d004100210a200921030c010b200e41016a2103200e2d0000413f71210a0b200b410674200c411274418080f0007172200a72220a418080c400470d020c040b200a41ff0171210a0b200921030b02402006417f6a2206450d00200720086b20036a21072003210820052003470d010c020b0b200a418080c400460d00024002402007450d0020072002460d0041002103200720024f0d01200120076a2c00004140480d010b200121030b2007200220031b21022003200120031b21010b20044101460d002000280218200120022000411c6a28020028020c1100000f0b4100210902402002450d002002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b0240200220096b200028020c2206490d002000280218200120022000411c6a28020028020c1100000f0b410021074100210902402002450d00410021092002210a200121030340200920032d000041c00171418001466a2109200341016a2103200a417f6a220a0d000b0b200920026b20066a2209210a024002400240410020002d0020220320034103461b0e0402010001020b20094101762107200941016a410176210a0c010b4100210a200921070b200741016a2103024003402003417f6a2203450d0120002802182000280204200028021c280210110100450d000b41010f0b2000280204210941012103200028021820012002200028021c28020c1100000d00200a41016a2103200028021c210a20002802182100034002402003417f6a22030d0041000f0b20002009200a280210110100450d000b41010f0b20030bc80801067f230041f0006b220524002005200336020c20052002360208410121062001210702402001418102490d00410020016b2108418002210903400240200920014f0d00200020096a2c000041bf7f4c0d0041002106200921070c020b2009417f6a21074100210620094101460d01200820096a210a20072109200a4101470d000b0b200520073602142005200036021020054100410520061b36021c200541b0b4cc0041e089c00020061b3602180240024002400240200220014b22090d00200320014b0d00200220034b0d01024002402002450d0020012002460d00200120024d0d01200020026a2c00004140480d010b200321020b200520023602202002450d0220022001460d02200141016a210a03400240200220014f0d00200020026a2c000041404e0d040b2002417f6a210920024101460d04200a2002462107200921022007450d000c040b0b20052002200320091b360228200541306a41146a4103360200200541c8006a41146a4104360200200541d4006a410436020020054203370234200541e889c0003602302005410136024c2005200541c8006a3602402005200541186a3602582005200541106a3602502005200541286a360248200541306a2004104c000b200541e4006a4104360200200541c8006a41146a4104360200200541d4006a4101360200200541306a41146a410436020020054204370234200541808ac0003602302005410136024c2005200541c8006a3602402005200541186a3602602005200541106a36025820052005410c6a3602502005200541086a360248200541306a2004104c000b200221090b024020092001460d00410121070240024002400240200020096a220a2c00002202417f4a0d0041002106200020016a220721010240200a41016a2007460d00200a41026a2101200a2d0001413f7121060b2002411f71210a200241ff017141df014b0d012006200a4106747221010c020b2005200241ff0171360224200541286a21020c020b4100210020072108024020012007460d00200141016a210820012d0000413f7121000b200020064106747221010240200241ff017141f0014f0d002001200a410c747221010c010b41002102024020082007460d0020082d0000413f7121020b2001410674200a411274418080f00071722002722201418080c400460d020b2005200136022441012107200541286a21022001418001490d00410221072001418010490d0041034104200141808004491b21070b200520093602282005200720096a36022c200541306a41146a4105360200200541ec006a4104360200200541e4006a4104360200200541c8006a41146a4106360200200541d4006a410736020020054205370234200541a08ac000360230200520023602582005410136024c2005200541c8006a3602402005200541186a3602682005200541106a3602602005200541246a3602502005200541206a360248200541306a2004104c000b41958dcc00412b2004103f000b1000200120002802002000280204105a0b800101037f230041206b22022400024002402000280200200110610d002001411c6a2802002103200128021821042002411c6a4100360200200241b0b4cc003602182002420137020c200241888bc00036020820042003200241086a1043450d010b200241206a240041010f0b2000280204200110612101200241206a240020010bdd0502047f017e410121020240200128021841272001411c6a2802002802101101000d0041022103024002400240024002402000280200220041776a2204411e4d0d00200041dc00470d010c020b41f40021050240024020040e1f05010202000202020202020202020202020202020202020202030202020203050b41f20021050c040b41ee0021050c030b0240024002402000105f0d00024002400240200041808004490d00200041808008490d0120004190fc476a4190fc0b490d02200041b5d9736a41b5db2b490d02200041e28b746a41e20b490d022000419fa8746a419f18490d02200041dee2746a410e490d02200041feffff0071419ef00a460d02200041a2b2756a4122490d02200041cb91756a410a4b0d050c020b200041f08bc000412941c28cc00041a20241e48ec00041b5021060450d010c040b2000419991c000412641e591c00041af01419493c00041a30310600d030b200041017267410276410773ad4280808080d0008421060c010b200041017267410276410773ad4280808080d0008421060b410321030c020b410121030c010b0b200021050b03402003210441dc002100410121024101210302400240024002400240024020040e0402010500020b02400240024002402006422088a741ff01710e06050302010006050b200642ffffffff8f608342808080803084210641f50021000c060b200642ffffffff8f608342808080802084210641fb0021000c050b20052006a72204410274411c7176410f712203413072200341d7006a2003410a491b210002402004450d002006427f7c42ffffffff0f832006428080808070838421060c050b200642ffffffff8f60834280808080108421060c040b200642ffffffff8f6083210641fd0021000c030b41002103200521000c030b20012802184127200128021c2802101101000f0b200642ffffffff8f60834280808080c0008421060b410321030b20012802182000200128021c280210110100450d000b0b20020b9d0301057f0240024002404100410f200041a49a04491b2201200141086a2201200141027441f896c0006a280200410b742000410b7422014b1b2202200241046a2202200241027441f896c0006a280200410b7420014b1b2202200241026a2202200241027441f896c0006a280200410b7420014b1b2202200241016a2202200241027441f896c0006a280200410b7420014b1b220241027441f896c0006a280200410b74220320014620032001496a20026a2201411e4b0d002001410274210241b105210302402001411e460d00200241fc96c0006a2204450d00200428020041157621030b4100210402402001417f6a220520014b0d002005411f4f0d03200541027441f896c0006a28020041ffffff007121040b02402003200241f896c0006a280200411576220141016a460d00200020046b21022003417f6a2103410021000340200141b0054b0d0320002001418498c0006a2d00006a220020024b0d012003200141016a2201470d000b0b20014101710f0b2001411f41b89dc0001042000b200141b10541c89dc0001042000b2005411f41f497c0001042000bea0201067f200120024101746a210720004180fe0371410876210841002109200041ff0171210a0240024002400340200141026a210b200920012d000122026a210c024020012d000022012008460d00200120084b0d03200c2109200b2101200b2007470d010c030b0240200c2009490d00200c20044b0d02200320096a2101024003402002450d012002417f6a210220012d00002109200141016a21012009200a470d000b410021020c050b200c2109200b2101200b2007470d010c030b0b2009200c41b896c0001059000b200c200441b896c0001058000b200041ffff03712109200520066a210c4101210202400340200541016a210a0240024020052d00002201411874411875220b4100480d00200a21050c010b200a200c460d02200b41ff007141087420052d0001722101200541026a21050b200920016b22094100480d02200241017321022005200c470d000c020b0b41958dcc00412b41c896c000103f000b20024101710bab0201037f23004180016b2202240002400240024002400240200128020022034110710d0020034120710d012000ad41012001105221000c020b410021030340200220036a41ff006a2000410f712204413072200441d7006a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141d88bc0004102200220036a4180016a410020036b105621000c010b410021030340200220036a41ff006a2000410f712204413072200441376a2004410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141d88bc0004102200220036a4180016a410020036b105621000b20024180016a240020000f0b200041800141c88bc0001059000b200041800141c88bc0001059000b1c00200128021841c99ec000410b2001411c6a28020028020c1100000b1c00200128021841d49ec000410e2001411c6a28020028020c1100000b5b01017f230041306b220324002003200136020c20032000360208200341246a41013602002003420137021420034188b2cc003602102003410436022c2003200341286a3602202003200341086a360228200341106a2002104c000b140020002802002001200028020428020c1101000b15002001200028020022002802002000280204105a0bb10401077f230041306b220324000240024020020d00410021040c010b200341286a210502400240024002400340024020002802082d0000450d00200028020041a69fc0004104200028020428020c1100000d050b2003410a3602282003428a808080103703202003200236021c200341003602182003200236021420032001360210200341086a410a200120021068024002400240024020032802084101470d00200328020c210403402003200420032802186a41016a2204360218024002402004200328022422064f0d00200328021421070c010b200328021422072004490d00200641054f0d072003280210200420066b22086a22092005460d0420092005200610a008450d040b200328021c22092004490d0220072009490d0220032006200341106a6a41176a2d0000200328021020046a200920046b10682003280204210420032802004101460d000b0b2003200328021c3602180b200028020841003a0000200221040c010b200028020841013a0000200841016a21040b2000280204210920002802002106024020044520022004467222070d00200220044d0d03200120046a2c000041bf7f4c0d030b200620012004200928020c1100000d04024020070d00200220044d0d04200120046a2c000041bf7f4c0d040b200120046a2101200220046b22020d000b410021040c040b2006410441ac9fc0001058000b200120024100200441bc9fc000105b000b200120022004200241d089c000105b000b410121040b200341306a240020040bf80201067f410021040240024020024103712205450d00410420056b2205450d0020032005200520034b1b210441002105200141ff01712106034020042005460d01200220056a2107200541016a210520072d000022072006470d000b410121032007200141ff01714641016a41017120056a417f6a21050c010b200141ff017121060240024020034108490d002004200341786a22084b0d00200641818284086c210502400340200220046a220741046a2802002005732209417f73200941fffdfb776a7120072802002005732207417f73200741fffdfb776a7172418081828478710d01200441086a220420084d0d000b0b200420034b0d010b200220046a2109200320046b210241002103410021050240034020022005460d01200920056a2107200541016a210520072d000022072006470d000b410121032007200141ff01714641016a41017120056a417f6a21050b200520046a21050c010b2004200341e89fc0001059000b20002005360204200020033602000bbb0302047f027e230041c0006b2205240041012106024020002d00040d0020002d000521070240200028020022082d00004104710d004101210620082802184196a0c0004193a0c000200741ff017122071b4102410320071b2008411c6a28020028020c1100000d014101210620002802002208280218200120022008411c6a28020028020c1100000d01410121062000280200220828021841dc92c80041022008411c6a28020028020c1100000d0120032000280200200428020c11010021060c010b0240200741ff01710d004101210620082802184198a0c00041032008411c6a28020028020c1100000d01200028020021080b41012106200541013a0017200541346a419ca0c000360200200520082902183703082005200541176a360210200829020821092008290210210a200520082d00203a00382005200a37032820052009370320200520082902003703182005200541086a360230200541086a2001200210670d00200541086a41dc92c800410210670d002003200541186a200428020c1101000d00200528023041b4a0c0004102200528023428020c11000021060b200041013a0005200020063a0004200541c0006a240020000b8b0201027f230041106b220224002002410036020c02400240024002402001418001490d002001418010490d012002410c6a21032001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c2002410c6a2103410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c2002410c6a2103410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b20002003200110672101200241106a240020010b6001017f230041206b2202240020022000360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41b8a0c000200241086a10432101200241206a240020010b0d0020002802002001200210670b0b0020002802002001106a0b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41b8a0c000200241086a10432101200241206a240020010bd30202047f027e230041c0006b2203240041012104024020002d00080d00200028020421050240200028020022062d00004104710d004101210420062802184196a0c00041d3a0c00020051b4102410120051b2006411c6a28020028020c1100000d0120012000280200200228020c11010021040c010b024020050d0041012104200628021841d4a0c00041022006411c6a28020028020c1100000d01200028020021060b41012104200341013a0017200341346a419ca0c000360200200320062902183703082003200341176a3602102006290208210720062902102108200320062d00203a00382003200837032820032007370320200320062902003703182003200341086a3602302001200341186a200228020c1101000d00200328023041b4a0c0004102200328023428020c11000021040b200020043a00082000200028020441016a360204200341c0006a240020000bd40202037f027e230041c0006b2203240041012104024020002d00040d0020002d000521040240200028020022052d00004104710d000240200441ff0171450d004101210420052802184196a0c00041022005411c6a28020028020c1100000d02200028020021050b20012005200228020c11010021040c010b0240200441ff01710d0041012104200528021841d7a0c00041012005411c6a28020028020c1100000d01200028020021050b41012104200341013a0017200341346a419ca0c000360200200320052902183703082003200341176a3602102005290208210620052902102107200320052d00203a00382003200737032820032006370320200320052902003703182003200341086a3602302001200341186a200228020c1101000d00200328023041b4a0c0004102200328023428020c11000021040b200041013a0005200020043a0004200341c0006a240020000b6401027f230041206b220224002001411c6a280200210320012802182101200241086a41106a200041106a290200370300200241086a41086a200041086a2902003703002002200029020037030820012003200241086a10432100200241206a240020000bd70a020c7f017e230041206b220324004101210402400240200228021841222002411c6a2802002802101101000d000240024020010d00410021050c010b200020016a21064100210520002107410021080240034020072109200741016a210a02400240024020072c0000220b417f4a0d0002400240200a2006470d004100210c200621070c010b20072d0001413f71210c200741026a220a21070b200b411f7121040240200b41ff0171220b41df014b0d00200c200441067472210c0c020b0240024020072006470d004100210d2006210e0c010b20072d0000413f71210d200741016a220a210e0b200d200c41067472210c0240200b41f0014f0d00200c2004410c7472210c0c020b02400240200e2006470d004100210b200a21070c010b200e41016a2107200e2d0000413f71210b0b200c4106742004411274418080f0007172200b72220c418080c400470d020c040b200b41ff0171210c0b200a21070b4102210a024002400240024002400240200c41776a220b411e4d0d00200c41dc00470d010c020b41f400210e02400240200b0e1f05010202000202020202020202020202020202020202020202030202020203050b41f200210e0c040b41ee00210e0c030b0240200c105f0d0002400240200c41808004490d00200c41808008490d01200c4190fc476a4190fc0b490d02200c41b5d9736a41b5db2b490d02200c41e28b746a41e20b490d02200c419fa8746a419f18490d02200c41dee2746a410e490d02200c41feffff0071419ef00a460d02200c41a2b2756a4122490d02200c41cb91756a410a4d0d020c060b200c41f08bc000412941c28cc00041a20241e48ec00041b5021060450d010c050b200c419991c000412641e591c00041af01419493c00041a30310600d040b200c41017267410276410773ad4280808080d00084210f4103210a0c010b0b200c210e0b2003200136020420032000360200200320053602082003200836020c0240024020082005490d0002402005450d0020052001460d00200520014f0d01200020056a2c000041bf7f4c0d010b02402008450d0020082001460d00200820014f0d01200020086a2c000041bf7f4c0d010b2002280218200020056a200820056b200228021c28020c110000450d01410121040c060b20032003410c6a3602182003200341086a36021420032003360210200341106a1073000b0340200a210b4101210441dc0021054101210a024002400240024002400240200b0e0402010500020b0240024002400240200f422088a741ff01710e06050302010006050b200f42ffffffff8f608342808080803084210f4103210a41f50021050c070b200f42ffffffff8f608342808080802084210f4103210a41fb0021050c060b200e200fa7220b410274411c7176410f71220a413072200a41d7006a200a410a491b21050240200b450d00200f427f7c42ffffffff0f83200f4280808080708384210f0c050b200f42ffffffff8f608342808080801084210f0c040b200f42ffffffff8f6083210f4103210a41fd0021050c040b4100210a200e21050c030b4101210a0240200c418001490d004102210a200c418010490d0041034104200c41808004491b210a0b200a20086a21050c040b200f42ffffffff8f60834280808080c00084210f0b4103210a0b20022802182005200228021c280210110100450d000c050b0b200820096b20076a210820062007470d000b0b2005450d0020052001460d00200520014f0d02200020056a2c000041bf7f4c0d020b410121042002280218200020056a200120056b200228021c28020c1100000d0020022802184122200228021c28021011010021040b200341206a240020040f0b200020012005200141d089c000105b000b2b01017f2000280200220128020020012802042000280204280200200028020828020041dca0c000105b000bee0704057f017e017f017e02400240024002402002450d00410020016b410020014103711b2103200241796a4100200241074b1b210441002105034002400240200120056a2d000022064118744118752207417f4a0d004280808080802021080240200641c884c0006a2d0000417e6a220941024d0d00428080808010210a0c070b0240024002400240024020090e03000102000b200541016a22062002490d024200210a0c090b4200210a200541016a220920024f0d08200120096a2d0000210902400240200641a07e6a2206410d4b0d000240024020060e0e0002020202020202020202020201000b200941e0017141a001460d02428080808010210a0c0c0b02402009411874411875417f4c0d00428080808010210a0c0c0b200941ff017141a001490d01428080808010210a0c0b0b02402007411f6a41ff0171410b4b0d0002402009411874411875417f4c0d00428080808010210a0c0c0b200941ff017141c001490d01428080808010210a0c0b0b0240200941ff017141bf014d0d00428080808010210a0c0b0b0240200741fe017141ee01460d00428080808010210a0c0b0b2009411874411875417f4c0d00428080808010210a0c0a0b42002108200541026a220620024f0d09200120066a2d000041c00171418001460d020c070b4200210a200541016a220920024f0d07200120096a2d0000210902400240200641907e6a220641044b0d000240024020060e050002020201000b200941f0006a41ff01714130490d02428080808010210a0c0b0b02402009411874411875417f4c0d00428080808010210a0c0b0b200941ff0171419001490d01428080808010210a0c0a0b0240200941ff017141bf014d0d00428080808010210a0c0a0b02402007410f6a41ff017141024d0d00428080808010210a0c0a0b2009411874411875417f4c0d00428080808010210a0c090b200541026a220620024f0d07200120066a2d000041c00171418001470d0642002108200541036a220620024f0d08200120066a2d000041c00171418001460d01428080808080e0002108428080808010210a0c080b428080808010210a200120066a2d000041c00171418001470d070b200641016a21050c010b0240200320056b4103710d000240200520044f0d000340200120056a220641046a280200200628020072418081828478710d01200541086a22052004490d000b0b200520024f0d010340200120056a2c00004100480d022002200541016a2205470d000c040b0b200541016a21050b20052002490d000b0b20002001360204200041086a2002360200200041003602000f0b428080808080c0002108428080808010210a0c010b420021080b2000200a2005ad84200884370204200041013602000b1c0020012802184190b2cc0041052001411c6a28020028020c1100000bb30101037f200028020421020240024020002802004101470d002000410c6a28020022002001107720004103742200450d01200220006a2103034020022802002100200241046a2802002204200110772001200020041078200241086a22022003470d000c020b0b200041086a28020022002001107720004103742200450d00200220006a2103034020022802002100200241046a2802002204200110772001200020041078200241086a22022003470d000b0b0bab0101017f230041106b220224000240024002400240200041c000490d00200041808001490d012000418080808004490d02200241033a00032001200241036a41011078200220003602042001200241046a410410780c030b200220004102743a00032001200241036a410110780c020b200220004102744101723b010a20012002410a6a410210780c010b2002200041027441027236020c20012002410c6a410410780b200241106a24000bcd0101047f0240024002400240200041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422062005200620054b1b22064100480d010240024020030d00024020060d00410121050c020b2006103322050d010c040b2000280200210520032006460d0020052003200610372205450d03200041086a28020021040b20002005360200200041046a20063602000b200520046a20012002109d081a200041086a200420026a3602000f0b103e000b103c000bff0101037f200028020421020240024020002802004101470d002000410c6a2802002200200110772000450d01200041186c2103200241146a21000340200041706a2802002102200041746a28020022042001107720012002200410782000417c6a280200210220002802002204200110772001200220041078200041186a2100200341686a22030d000c020b0b200041086a2802002200200110772000450d00200041186c2103200241146a21000340200041706a2802002102200041746a28020022042001107720012002200410782000417c6a280200210220002802002204200110772001200220041078200041186a2100200341686a22030d000b0b0ba90701057f230041206b2203240020012002107702402001450d00200141d8006c2104410021050340200020056a220141046a2802002106200141086a28020022072002107720022006200710782003200141d4006a2d00003a000d20022003410d6a4101107802402001410c6a2d0000220641024b0d0002400240024020060e03000102000b200341003a000e20022003410e6a41011078200141146a2802002106200141186a28020022072002107720022006200710780c020b200341013a000e20022003410e6a4101107802402001410d6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110780b200141146a2802002106200141186a2802002207200210772002200620071078200141206a2802002106200141246a280200220720021077200220062007107820032001410e6a2d00003a000e20022003410e6a410110780c010b200341023a000e20022003410e6a4101107802402001410d6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110780b200141146a2802002106200141186a2802002207200210772002200620071078200141206a2802002106200141246a28020022072002107720022006200710782001412c6a2802002106200141306a28020022072002107720022006200710782001410e6a2d0000220641064b0d000240024002400240024002400240024020060e0700010203040506000b200341003a000f0c060b200341013a000f0c050b200341023a000f0c040b200341033a000f0c030b200341043a000f0c020b200341053a000f0c010b200341063a000f0b20022003410f6a410110780b02400240200141346a2802004101470d00200141386a2802002106200141c0006a28020022072002107720022006200710780c010b200341106a200141386a2802002001413c6a28020028020c11020020032802102106200328021822072002107720022006200710782003280214450d00200610350b200141c4006a200210762004200541d8006a2205470d000b0b200341206a24000b8605010e7f2001410c6a2802002102200128020821032001280204210402400240024002400240024002400240200128020022050d0020030d010c060b200420056b2101024020030d00200121060c020b2001200220036b6a220620014f0d010240024020042005460d00200541016a21070c010b20022003460d064100210720032105200341016a21030b4100210841002106410121090340200420076b210a2008410174210b20022003220c6b210d410021010340200720016a210e20052d000021030240200820016a22052006470d002005417f417f2004200e6b2206200d6a220f200f2006491b200d200e1b220641016a220f200f2006491b6a22062005490d06200b2006200b20064b1b22064100480d06024020050d00024020060d00410121090c020b2006103322090d010c080b20052006460d0020092005200610372209450d070b200920086a20016a20033a00000240200e450d00200a2001460d00200b41026a210b200141016a2101200e21050c010b0b200c2002460d03200541016a2108200c41016a210341002107200c21050c000b0b200220036b21060b0240024020060d00410121090c010b20064100480d02200610332209450d030b4100210b0240024020050d00200921010c010b024020042005470d00200921010c010b200921012005210e03402001200e2d00003a0000200141016a21012004200e41016a220e470d000b200420056b210b0b2003450d0420022003460d042003210e03402001200e2d00003a0000200141016a21012002200e41016a220e470d000b2002200b20036b6a210b0c040b200541016a210b0c030b103e000b103c000b410121094100210b410021060b2000200b36020820002006360204200020093602000bd40101037f02400240024002402000280200220041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004103322050d010c040b2000280200210520032004460d0020052003200410372205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a20012002109d081a200041086a200420026a36020041000f0b103e000b103c000bbf0301047f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b0240024002400240200041046a2802002203200041086a28020022046b2001490d00200028020021050c010b200420016a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004103322050d010c040b2000280200210520032004460d0020052003200410372205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a2002410c6a2001109d081a200041086a200420016a360200200241106a240041000f0b103e000b103c000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41e4a1c000200241086a10432101200241206a240020010bcd0101037f0240024002400240200041046a2802002203200041086a28020022046b2002490d00200028020021050c010b200420026a22052004490d01200341017422042005200420054b1b22044100480d010240024020030d00024020040d00410121050c020b2004103322050d010c040b2000280200210520032004460d0020052003200410372205450d030b20002005360200200041046a2004360200200041086a28020021040b200520046a20012002109d081a200041086a200420026a3602000f0b103e000b103c000b040041010bb60101017f230041c0006b2202240020024100360210200242013703082002410836021c20022001410c6a3602202002200241206a3602182002200241086a3602242002413c6a41013602002002420137022c20024188b2cc003602282002200241186a360238200241246a41e4a1c000200241286a10431a20012d0000417f6a41ff0171200141046a290200200235021042208620023502088410000240200228020c450d00200228020810350b200241c0006a24000b6901037f230041206b220224002001411c6a280200210320012802182104200241086a41106a2000280200220141106a290200370300200241086a41086a200141086a2902003703002002200129020037030820042003200241086a10432101200241206a240020010b040041000b02000b02000bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff03712001470d00200141027422014100480d00024020030d0020010d02410421020c040b20002802002102200341027422032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014102763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad420c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003410c6c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a2001410c6e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42307e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341306c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141306e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42307e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341306c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141306e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410121020c040b20002802002102200341057422032001460d03024020030d0020010d02410121020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014105763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42387e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341386c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141386e3602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff00712001470d00200141047422014100480d00024020030d0020010d02410421020c040b20002802002102200341047422032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014104763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42247e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341246c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141246e3602000b0bb40101027f0240200041046a280200220320016b20024f0d000240024002400240200120026a22042001490d00200341017422022004200220044b1b220420046a22012004490d0020014100480d00024020030d0020010d02410221030c040b2000280200210320022001460d03024020020d0020010d02410221030c040b20032002200110372203450d020c030b103e000b2001103322030d010b103c000b20002003360200200041046a20014101763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42287e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341286c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141286e3602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff01712001470d00200141037422014100480d00024020030d0020010d02410421020c040b20002802002102200341037422032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014103763602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410421020c040b20002802002102200341057422032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014105763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42b0027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341b0026c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141b0026e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42f0007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341f0006c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141f0006e3602000b0bba0101027f0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1b220241ffffff1f712002470d00200241067422024100480d00024020010d0020020d02410821030c040b20002802002103200141067422012002460d03024020010d0020020d02410821030c040b20032001200210372203450d020c030b103e000b2002103322030d010b103c000b20002003360200200041046a20024106763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d8027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d8026c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141d8026e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42e8007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341e8006c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141e8006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42187e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341186c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141186e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad422c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003412c6c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a2001412c6e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42147e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341146c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141146e3602000b0bc00101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffffff00712001470d00200141047422014100480d00024020030d0020010d02410821020c040b20002802002102200341047422032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014104763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d8007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d8006c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141d8006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42187e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341186c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141186e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42287e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341286c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141286e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42227e2204422088a70d002004a722014100480d00024020030d0020010d02410221020c040b20002802002102200341226c22032001460d03024020030d0020010d02410221020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141226e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c4007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341c4006c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141c4006e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42a0017e2204422088a70d002004a722014100480d00024020030d0020010d02410121020c040b20002802002102200341a0016c22032001460d03024020030d0020010d02410121020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141a0016e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff3f712001470d00200141057422014100480d00024020030d0020010d02410821020c040b20002802002102200341057422032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014105763602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42387e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341386c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141386e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d0007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d0006c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141d0006e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42e0007e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341e0006c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141e0006e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42347e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341346c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141346e3602000b0bbf0101017f0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1b220141ffffff1f712001470d00200141067422014100480d00024020030d0020010d02410421020c040b20002802002102200341067422032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a20014106763602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42d0027e2204422088a70d002004a722014100480d00024020030d0020010d02410821020c040b20002802002102200341d0026c22032001460d03024020030d0020010d02410821020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141d0026e3602000b0bc10102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad42c8007e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b20002802002102200341c8006c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a200141c8006e3602000b0bbc0102027f017e0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1bad42c8037e2204422088a70d002004a722024100480d00024020010d0020020d02410821030c040b20002802002103200141c8036c22012002460d03024020010d0020020d02410821030c040b20032001200210372203450d020c030b103e000b2002103322030d010b103c000b20002003360200200041046a200241c8036e3602000b0bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad423c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003413c6c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a2001413c6e3602000b0b800b04047f017e127f037e230041d0036b22012400200141f0006a41186a4200370300200141f0006a41106a22024200370300200141f0006a41086a220342003703002001420037037041f7edcb00ad4280808080f000841001220429000021052003200441086a290000370300200120053703702004103541eeedcb00ad4280808080900184100122042900002105200141206a41086a2206200441086a2900003703002001200537032020041035200220012903202205370300200141c0006a41086a22042003290300370300200141c0006a41106a2005370300200141c0006a41186a200629030037030020012001290370370340200141f0006a200141c0006a10ac0102400240024020012903704202510d002000280208210320002802042107200028020021082001200228020010ad01200141f0006a200128020022092001280208220a10ae012004200141f0006a410c6a290200370300200120012902743703400240024020012802704101460d00200141106a410c6a4100360200200142003703100c010b200141106a41086a200141c0006a41086a290300370300200120012903403703100b02402003450d002008200341246c6a210b20014184016a210c2001411c6a210d200141106a410472210e200141e8006a210f200141c0006a41206a211020082111034020112802202112200141206a41186a2213201141186a290000370300200141206a41106a2214201141106a290000370300200141206a41086a2215201141086a290000370300200120112900003703200240024020012802142206450d00200128021821160c010b200141f0006a410041e002109f081a200f410036020020104200370300200141c0006a41186a22004200370300200141c0006a41106a22034200370300200141c0006a41086a220442003703002001420037034041940310332206450d0541002116200641003b010620064100360200200641086a200141f0006a41e002109d081a20064190036a200f28020036020020064188036a201029030037020020064180036a2000290300370200200641f8026a2003290300370200200641f0026a2004290300370200200620012903403702e80220014100360218200120063602140b201141246a2111024002400340200641086a210320062f01062217410574210041002104024003402000450d01200141206a2003412010a0082202450d03200041606a2100200441016a2104200341206a21032002417f4a0d000b2004417f6a21170b02402016450d002016417f6a2116200620174102746a4194036a28020021060c010b0b200141c0006a41186a20132903002205370300200141c0006a41106a20142903002218370300200141c0006a41086a2015290300221937030020012001290320221a370340200c201a370200200c41086a2019370200200c41106a2018370200200c41186a20053702002001200d360280012001201736027c2001200e3602782001200636027420014100360270200141f0006a410010af0121000c010b200620044102746a41e8026a21000b2000200028020020126a3602002001200128021020126a3602102011200b470d000b0b02402007450d00200741246c450d00200810350b200141fc006a200141106a41086a290300370200200120012903102205370274200141013602702001410036024820014201370340410410332200450d0220002005a73600002001200036024020014284808080c000370244200141f0006a41086a2200200141c0006a10b00120012802442103200aad4220862009ad84200135024842208620012802402204ad84100202402003450d00200410350b200010b1012001280204450d01200910350c010b200041046a2802002203450d00200341246c450d00200028020010350b200141d0036a24000f0b103c000bd60202057f027e230041d0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822010d00200042023703000c010b200228020c210302400240200241106a28020022044104490d0020044104460d0020012d0004220541014b0d0020012800002106420021070240024020050e020100010b2004417b6a4108490d0120012900052108420121070b20002008370308200041106a20063602000c010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b420221070b200020073703002003450d00200110350b200241d0006a24000bfc0403027f017e057f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541ccb5c000ad4280808080800284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bcd0b030e7f047e087f230041a0046b220324002003200236021420032001360210200341186a2002ad4220862001ad84100510c20102400240200328021822040d00200041003602000c010b200328021c21052003200341206a280200220136022c2003200436022802400240024020014104490d0020032001417c6a36022c2003200441046a36022820042800002106200341086a200341286a10c40120032802080d00200328020c21072003410036024820034100360240200341c0006a41086a210802400240024002402007450d00200341d4016a2109200328022c210a200341b8016a210b4100210c034041002101200341003a00e001200c41016a210c024002400340200a2001460d01200341c0016a20016a2003280228220d2d00003a00002003200d41016a3602282003200141016a22023a00e0012002210120024120470d000b20034190016a41086a220e200341c0016a41086a29030037030020034190016a41106a220f200341c0016a41106a29030037030020034190016a41186a2210200341c0016a41186a290300370300200320032903c001370390012003200a20026b220136022c200141044f0d010c050b2003410036022c200141ff0171450d04200341003a00e001410021010c050b200341d0006a41086a200e2903002211370300200341d0006a41106a200f2903002212370300200341d0006a41186a20102903002213370300200320032903900122143703502003200d41056a36022820032001417c6a220a36022c200d2800012115200341f0006a41186a22162013370300200341f0006a41106a22172012370300200341f0006a41086a22182011370300200320143703700240024020032802402219450d002003280244211a0c010b200341c0016a410041e002109f081a200b410036020020034190016a41206a2201420037030020104200370300200f4200370300200e4200370300200342003703900141940310332219450d034100211a201941003b010620194100360200201941086a200341c0016a41e002109d081a20194190036a200b28020036020020194188036a200129030037020020194180036a2010290300370200201941f8026a200f290300370200201941f0026a200e29030037020020192003290390013702e80220034100360244200320193602400b024002400340201941086a210220192f0106221b41057421014100210d024003402001450d01200341f0006a2002412010a008221c450d03200141606a2101200d41016a210d200241206a2102201c417f4a0d000b200d417f6a211b0b0240201a450d00201a417f6a211a2019201b4102746a4194036a28020021190c010b0b201020162903002211370300200f20172903002212370300200e201829030022133703002003200329037022143703900120092014370200200941086a2013370200200941106a2012370200200941186a2011370200200320083602d0012003201b3602cc01200320193602c401200341003602c0012003200341c0006a3602c801200341c0016a201510af011a0c010b2019200d4102746a41e8026a20153602000b200c2007470d000b0b410121010c020b103c000b410021010b200341306a41086a20082802002202360200200320032903402211370330200341c0016a41086a2002360200200320113703c00120010d01200341c0016a10b1010b4100210120034100360298012003420137039001200341093602742003200341106a360270200320034190016a360250200341d4016a4101360200200342013702c401200341c888c2003602c0012003200341f0006a3602d001200341d0006a41e88ac500200341c0016a10431a200335029801422086200335029001841006200328029401450d0120032802900110350c010b20034190016a41086a200341c0016a41086a2802002201360200200320032903c00122113703900120002006360204200041086a2011370200200041106a2001360200410121010b200020013602002005450d00200410350b200341a0046a24000bed0701087f23004190046b2202240020002802102203200328020041016a360200200241086a2203200041086a29020037030020022000290200370300200241306a41186a2000412c6a290000370300200241306a41106a200041246a290000370300200241306a41086a2000411c6a29000037030020022000290014370330200241d0006a2002200241306a200110fe0202400240024020022d00504101470d002003200241d9006a290000370300200241106a200241e1006a290000370300200241186a200241e9006a29000037030020022002290051370300200241d0006a412c6a280200210120024188016a280200210420024184016a280200210320024180016a2802002105200228028c012106200241f8006a28020022002802002207450d0120002f01042108200241f4006a2802002109200241d0006a410172210003402002200841ffff037136022c20022001360228200220073602242002200941016a360220200241306a41186a200241186a2201290300370300200241306a41106a200241106a2207290300370300200241306a41086a200241086a220829030037030020022002290300370330200241d0006a200241206a200241306a20052003200410ff0220022d00504101470d032008200041086a2900003703002007200041106a2900003703002001200041186a29000037030020022000290000370300200228027c2101200228028801210420022802840121032002280280012105200228027822082802002207450d0220082f01042108200228027421090c000b0b200241d0006a41086a280200200241d0006a41106a2802004102746a41e8026a21060c010b200241d0006a410272410041be03109f081a02400240024041c40310332200450d0020004100360200200041046a200241d0006a41c003109d081a200020012802002207360294032001200036020020012001280204220841016a360204200741003b010420072000360200200241d0006a41186a200241186a290300370300200241d0006a41106a200241106a290300370300200241d0006a41086a200241086a2903003703002002200229030037035020082004470d0120002f01062201410a4b0d02200020014105746a220441206a200241d0006a41186a290300370000200441186a200241d0006a41106a290300370000200441106a200241d0006a41086a290300370000200441086a2002290350370000200020014102746a41e8026a20053602002000200141016a22014102746a4194036a2003360200200020013b0106200320013b0104200320003602000c030b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b20024190046a240020060bef0403057f027e027f230041c0006b22022400200041086a28020022032001107702400240024020002802002204450d00024020002802042205450d002005210020042106034020062802940321062000417f6a22000d000b200421000340200020002f01064102746a4194036a28020021002005417f6a22050d000b200241186a2105200621040c020b200241186a2105200421000c010b410021042002410036021c200241186a21050c010b2002200036021c200241246a20002f010636020020024100360220200241003602180b200241086a41086a200541086a2902002207370300200220052902002208370308200241306a2007370300200242003703202002200436021c20024100360218200220083703282002200336023802402003450d00034020022003417f6a360238200241186a410020041b2206280200210020062802082109024002400240200628020c2205200628020422032f01064f0d00200321040c010b0240034020032802002204450d01200041016a210020032f0104210520042103200520042f0106490d020c000b0b2009ad2107410021040c010b2005ad4220862009ad8421070b2007422088a7220941016a21052007a7210a0240024020000d00200421030c010b200420054102746a4194036a2802002103410021052000417f6a2200450d00034020032802940321032000417f6a22000d000b0b2006200536020c2006200a36020820062003360204200641003602002001200420094105746a41086a412010782002200420094102746a41e8026a28020036023c20012002413c6a4104107820022802382203450d01200228021c21040c000b0b200241c0006a24000bb50201047f024020002802002201450d0020002802082102024020002802042200450d00034020012802940321012000417f6a22000d000b0b02402002450d004100210303400240024002402001450d002002417f6a2102200320012f0106490d0141002104034002400240200128020022000d0041002103410021000c010b200441016a210420012f010421030b2001103520002101200320002f01064f0d000b200341016a2103024020040d00200021010c030b200020034102746a4194036a2802002101410021032004417f6a2200450d02034020012802940321012000417f6a22000d000c030b0b41958dcc00412b41c08dcc00103f000b200341016a21030b20020d000b0b2001450d0020012802002100200110352000450d00034020002802002101200010352001210020010d000b0b0ba20703027f017e067f230041e0006b2203240041f7edcb00ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541d6a9c000ad4280808080b00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b0240024002400240412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2007109d081a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420066a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000ba20703027f017e067f230041e0006b2203240041f7edcb00ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541e9a9c000ad4280808080b00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b0240024002400240412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2007109d081a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420066a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541c0a9c000ad4280808080e00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541f393ca00ad4280808080a00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bda0503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a29000037030020022004370308200310354189aac000ad4280808080900184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240410410332203450d0020034104412010372203450d0320032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200128022021052003412041c00010372201450d032001200536002020022001ad4280808080c004841003220329000037033820031035200241cc006a200141246a360200200220013602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200110352002280230220641206a2203417f4c0d01200228022821070240024020030d0041002105410121010c010b200310332201450d01200321050b024002402005410f4d0d00200521080c010b200541017422084110200841104b1b22084100480d03024020050d002008103322010d010c050b20052008460d0020012005200810372201450d040b20012002290308370000200141086a200241086a41086a2903003700000240024020084170714110460d00200821050c010b200841017422054120200541204b1b22054100480d0320082005460d0020012008200510372201450d040b20012002290318370010200141186a200241186a41086a29030037000002400240200541606a2006490d00200521080c010b2006415f4b0d03200541017422082003200820034b1b22084100480d0320052008460d0020012005200810372201450d040b200141206a20072006109d081a2000200336020820002008360204200020013602000240200228022c450d00200710350b200241d0006a24000f0b1045000b1044000b103e000b103c000bc20503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a200341086a290000370300200220043703002003103541c6a9c000ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bfc0403027f017e057f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541feedcb00ad4280808080d00284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bb10503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541cca9c000ad4280808080a00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541fca9c000ad4280808080d00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b890603027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241186a41086a200341086a290000370300200220043703182003103541fca9c000ad4280808080d00184100122032900002104200241286a41086a200341086a2900003703002002200437032820031035200128020021010240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad428080808080048410032201290000370348200110352002410c6a200341206a360200200220033602082002200241c8006a41086a3602042002200241c8006a360200200241386a2002107b200310352002280240220541206a2201417f4c0d01200228023821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290318370000200341086a200241186a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290328370010200341186a200241286a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a0240200228023c450d00200610350b20022003200110bc01200241286a41086a2207200241086a280200360200200220022903003703280240200228020c2201450d002000200229032837020020002002290310370210200041086a20072802003602000b2000200136020c02402008450d00200310350b200241d0006a24000f0b1045000b1044000b103e000b103c000ba20503067f017e027f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d002000410036020c0c010b200328021421042003200341186a2802002202360224200320013602200240024020024104490d002003200141046a36022020032002417c6a220536022420054104490d00200128000021062003200141086a3602202003200241786a220536022420054104490d00200128000421052003200241746a36022420032001410c6a360220200128000821072003200341206a10c40120032802000d002003280224220820032802044102742202490d0002400240024002402002417f4c0d000240024020020d00420021094101210a0c010b20021039220a450d02200a2003280220220b2002109d081a2003200820026b3602242003200b20026a3602202002ad21090b200a450d04024020092002ad422086842209422088a722020d002009a721020c030b0240200a2002724103710d002009a722024103710d0020024102762208450d032009422288a7210b0c040b2009a7450d04200a10350c040b1044000b1045000b4100210b02402002450d00200a10350b410021084104210a0b41000d00200a450d00200020083602102000200a36020c200020073602082000200536020420002006360200200041146a200b3602000c010b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b2000410036020c0b2004450d00200110350b200341e0006a24000bfc0403027f017e057f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541efb5c000ad4280808080e00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bfc0403027f017e057f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541dcb5c000ad4280808080b00284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000b9b540f047f017e017f017e027f017e067f027e017f017e037f017e087f047e047f230041c0046b22022400200241d0006a41186a22034200370300200241d0006a41106a22044200370300200241d0006a41086a220542003703002002420037035041f7edcb00ad4280808080f000842206100122072900002108200241e0026a41086a2209200741086a290000370300200220083703e0022007103520052009290300370300200220022903e00237035041e4edcb00ad4280808080a0018422081001220a290000210b200241b0036a41086a2207200a41086a2900003703002002200b3703b003200a1035200420022903b003220b37030020024190046a41086a220c200529030037030020024190046a41106a220d200b37030020024190046a41186a220e20072903003703002002200229035037039004200241286a20024190046a412010c0012002280228210f200228022c21102003420037030020044200370300200542003703002002420037035020061001220a290000210b2009200a41086a2900003703002002200b3703e002200a103520052009290300370300200220022903e00237035020081001220a29000021082007200a41086a290000370300200220083703b003200a1035200420022903b0032208370300200c2005290300370300200d2008370300200e20072903003703002002200229035037039004410121054100210a2002201041016a4100200f1b221136025020024190046aad42808080808004842212200241d0006aad22134280808080c00084100220061001220329000021062009200341086a290000370300200220063703e0022003103541feedcb00ad4280808080d002841001220929000021062007200941086a290000370300200220063703b00320091035200220113602f0032002200241f0036aad4280808080c00084100322092900003703900420091035200241dc006a200241f4036a3602002002200c3602542002200241f0036a360258200220024190046a36025020024190026a200241d0006a107b024002400240024002400240024002400240024002400240024002400240200228029802220341206a220c417f4c0d00200228029002210d0240200c450d00200c10332205450d07200c210a0b02400240200a410f4d0d00200a21070c010b200a41017422094110200941104b1b22074100480d0b0240200a0d002007103322050d010c100b200a2007460d002005200a200710372205450d0f0b200520022903e002370000200541086a200241e0026a41086a2903003700000240024020074170714110460d00200721090c010b200741017422094120200941204b1b22094100480d0b20072009460d0020052007200910372205450d0f0b200520022903b003370010200541186a200241b0036a41086a29030037000002400240200941606a2003490d00200921070c010b200341206a22072003490d0b2009410174220a2007200a20074b1b22074100480d0b20092007460d0020052009200710372205450d0f0b200541206a200d2003109d081a0240200228029402450d00200d10350b20022001360250200cad4220862005ad8420134280808080c00084100202402007450d00200510350b200241d0006a41186a220a4200370300200241d0006a41106a22144200370300200241d0006a41086a220542003703002002420037035041f7edcb00ad4280808080f000842206100122072900002108200241e0026a41086a2209200741086a290000370300200220083703e0022007103520052009290300370300200220022903e00237035041b5edcb00ad4280808080c001841001220c2900002108200241b0036a41086a2207200c41086a290000370300200220083703b003200c1035200420022903b003370000200441086a200729030037000020024190046a41086a200529030037030020024190046a41106a201429030037030020024190046a41186a200a2903003703002002200229035037039004200241206a20024190046a412010c00102402011200228022441016a41d50020022802201b6b220c20114b0d00200c10c1010b200a420037030020144200370300200542003703002002420037035020061001220a29000021062009200a41086a290000370300200220063703e002200a103520052009290300370300200220022903e00237035041b3b6c000ad4280808080d001841001220929000021062007200941086a290000370300200220063703b00320091035201420022903b0032206370300200241306a41086a2005290300370300200241306a41106a2006370300200241306a41186a200729030037030020022002290350370330200241203602d4012002200241306a3602d001200241d8016a200241306aad42808080808004842215100510c20120022802d8012216450d0520022802dc0121172002200241d8016a41086a2802003602ec01200220163602e801200241d0006a200241e8016a10c30120022802502218450d03200241d0006a41086a35020021192002280254211a200241186a200241e8016a10c40120022802180d01200228021c221b20022802ec01220741d0006e22052005201b4b1bad42d0007e2206422088a70d002006a72205417f4c0d000240024020050d004108211c0c010b20051033221c450d070b4100210a200241003602f8012002201c3602f0012002200541d0006e221d3602f4010240201b450d00200241b4046a211e200241d0006a41206a211f4100210a4100210c02400340200241003a00d003200c41016a210c41002105024002400240034020072005460d01200241b0036a20056a20022802e80122092d00003a00002002200941016a3602e8012002200541016a22093a00d0032009210520094120470d000b200241f0036a41086a2205200241b0036a41086a2203290300370300200241f0036a41106a220d200241b0036a41106a2201290300370300200241f0036a41186a220e200241b0036a41186a220f290300370300200220022903b0033703f0032002200720096b3602ec0120024190046a200241e8016a10c50120022802b00422090d01410021090c020b200241003602ec010240200541ff0171450d00200241003a00d0030b410021090c010b201f200229039004370300200241d0006a41186a2207200e290300370300200241d0006a41106a220e200d290300370300200241d0006a41086a220d2005290300370300201f41086a20024190046a41086a290300370300201f41106a20024190046a41106a290300370300201f41186a20024190046a41186a290300370300200241a0036a41086a201e41086a280200360200200220022903f0033703502002201e2902003703a003200241b0036a41386a200241d0006a41386a290300370300200241b0036a41306a200241d0006a41306a290300370300200241b0036a41286a200241d0006a41286a290300370300200241b0036a41206a201f290300370300200f20072903003703002001200e2903003703002003200d290300370300200220022903503703b0030b200241e0026a41386a2205200241b0036a41386a290300370300200241e0026a41306a2207200241b0036a41306a290300370300200241e0026a41286a2203200241b0036a41286a290300370300200241e0026a41206a220d200241b0036a41206a290300370300200241e0026a41186a2201200241b0036a41186a290300370300200241e0026a41106a220e200241b0036a41106a290300370300200241e0026a41086a220f200241b0036a41086a290300370300200241d0026a41086a2210200241a0036a41086a280200360200200220022903b0033703e002200220022903a0033703d00202402009450d0020024190026a41386a2220200529030037030020024190026a41306a2221200729030037030020024190026a41286a2207200329030037030020024190026a41206a2203200d29030037030020024190026a41186a220d200129030037030020024190026a41106a2201200e29030037030020024190026a41086a220e200f29030037030020024180026a41086a220f2010280200360200200220022903e00237039002200220022903d002370380020240200a20022802f401470d00200241f0016a200a410110a30120022802f001211c20022802f801210a0b201c200a41d0006c6a220520022903900237030020012903002106200d29030021082003290300210b200729030021222021290300212320202903002124200e290300212520052009360240200541086a20253703002005200229038002370244200541cc006a200f280200360200200541386a2024370300200541306a2023370300200541286a2022370300200541206a200b370300200541186a2008370300200541106a20063703002002200a41016a220a3602f801200c201b460d0220022802ec0121070c010b0b0240200a450d00200a41d0006c2109201c41c4006a21050340024020052802002207450d00200741306c450d002005417c6a28020010350b200541d0006a2105200941b07f6a22090d000b0b20022802f4012205450d03200541d0006c450d03201c10350c030b20022802f401211d0b201c450d010240024020022802ec012205450d0020022005417f6a3602ec01200220022802e801220541016a3602e80120052d000022264103490d010b0240200a450d00200a41d0006c2109201c41c4006a21050340024020052802002207450d00200741306c450d002005417c6a28020010350b200541d0006a2105200941b07f6a22090d000b0b0240201d450d00201d41d0006c450d00201c10350b201a41ffffff3f71450d040c030b2019422086201aad8421240c040b1044000b201a41ffffff3f71450d010b201810350b200241003602b803200242013703b003200241093602e4022002200241d0016a3602e0022002200241b0036a36029002200241e4006a410136020020024201370254200241c888c2003602502002200241e0026a36026020024190026a41e88ac500200241d0006a10431a20023502b80342208620023502b003841006024020022802b403450d0020022802b00310350b410321260b02402017450d00201610350b20264103460d00201510070c040b200241003602d802200242083703d002200241003602a803200242013703a00341f7edcb00ad4280808080f00084100122052900002106200241e0026a41086a2209200541086a290000370300200220063703e0022005103541f393ca00ad4280808080a00184100122052900002106200241b0036a41086a2207200541086a290000370300200220063703b00320051035412010332205450d00200520022903e002370000200520022903b003370010200541086a2009290300370000200541186a220a2007290300370000412010332209450d0020092005290000370000200941186a200a290000370000200941106a200541106a290000370000200941086a200541086a290000370000200241306a41026a220a200241d0006a41026a2d00003a0000200220022f00503b0130200241f0036a41106a42a0808080800437030041002107200241003a008804200220053602fc03200242a080808080043702f403200220093602f0032002418b046a200a2d00003a0000200220022f01303b008904200241d0006a200241f0036a10c701024020022802504101470d00200241d0006a410472210a410121164108211b4100210c0340200241b0036a41206a200a41206a280200360200200241b0036a41186a2205200a41186a2902002206370300200241b0036a41106a2209200a41106a2902002208370300200241b0036a41086a2220200a41086a290200220b3703002002200a29020022223703b00320024190026a41186a220e200637030020024190026a41106a220f200837030020024190026a41086a2210200b3703002002202237039002200241d0006a41186a22032005290300370300200241d0006a41106a220d2009290300370300200241d0006a41086a22012020290300370300200220022903b00337035020024190026a10c8012106412010332209450d0a2009200229039002370000200941186a200e290300370000200941106a200f290300370000200941086a2010290300370000200241e0026a41086a20012903002208370300200241e0026a41106a200d290300220b370300200241e0026a41186a200329030022223703002002200229035022233703e00220024190046a41186a2220202237030020024190046a41106a2221200b37030020024190046a41086a221f200837030020022023370390040240200c20022802d402470d00200241d0026a200c4101108b0120022802d002211b20022802d802210c0b201b200c41386c6a22052006370300201f2903002106202129030021082020290300210b20022903900421222005412c6a4281808080103702002005200936022820052022370308200541206a200b370300200541186a2008370300200541106a20063703002002200c41016a220c3602d8022003200e290300370300200d200f2903003703002001201029030037030020022002290390023703500240200720022802a403470d00200241a0036a20074101108a0120022802a003211620022802a80321070b201620074105746a22052002290350370000200541186a2003290300370000200541106a200d290300370000200541086a20012903003700002002200741016a22073602a803200241d0006a200241f0036a10c70120022802504101460d000b0b024020022802f403450d0020022802f00310350b0240200228028004450d0020022802fc0310350b41f7edcb00ad4280808080f00084100122052900002106200241e0026a41086a2209200541086a290000370300200220063703e0022005103541cca9c000ad4280808080a00184100122052900002106200241b0036a41086a2207200541086a290000370300200220063703b00320051035412010332205450d00200520022903e002370000200520022903b003370010200541086a2009290300370000200541186a220a2007290300370000412010332209450d0020092005290000370000200941186a200a290000370000200941106a200541106a290000370000200941086a200541086a29000037000020024190026a41026a220a200241d0006a41026a2d00003a0000200220022f00503b019002200241d0006a41106a220742a080808080043703002002200536025c200242a0808080800437025420022009360250200241003a0068200241eb006a200a2d00003a0000200220022f0190023b0069200241d0026a200241d0006a10c901200241d0006a41186a220a420037030020074200370300200241d0006a41086a220542003703002002420037035041f7edcb00ad4280808080f000842206100122092900002108200241e0026a41086a220c200941086a290000370300200220083703e002200910352005200c290300370300200220022903e00237035041c1edcb00ad4280808080e00184100122032900002108200241b0036a41086a2209200341086a290000370300200220083703b00320031035201420022903b003370000201441086a220d2009290300370000200241306a41086a22012005290300370300200241306a41106a220e2007290300370300200241306a41186a220f200a29030037030020022002290350370330200241106a200241306a412010c0012002280214211020022802102120200a42003703002007420037030020054200370300200242003703502006100122032900002106200c200341086a290000370300200220063703e002200310352005200c290300370300200220022903e00237035041cfedcb00ad4280808080d002841001220c29000021062009200c41086a290000370300200220063703b003200c1035201420022903b003370000200d200929030037000020012005290300370300200e2007290300370300200f200a29030037030020022002290350370330200241086a200241306a412010c001200228020c21072002280208210a2009200241a0036a41086a280200360200200220022903a0033703b0032005200241d0026a41086a280200360200200220022903d00237035020024190046a2010410020201b20074104200a1b22054101200541014b1b200241b0036a200241d0006a10ca01024020022802900422170d00410321260c040b200241a4046a280200210c20024190046a41106a28020021162002419c046a280200211f20024190046a41086a2802002105200228029404211b2002410036025820024201370350200241d0006a4100200541306c220741306e108a012002280258210a0240024020070d00200228025021180c010b20022802502218200a4105746a210520172109034020052009290000370000200541186a200941186a290000370000200541106a200941106a290000370000200541086a200941086a290000370000200a41016a210a200541206a2105200941306a2109200741506a22070d000b0b20023502542108200241003602f803200242043703f003200241f0036a4100200c412c6c2205412c6d109801201f20056a210d20022802f803210320022802f00321210240200c0d00201f21050c020b200241b0036a410c6a212020212003412c6c6a2109200241b0036a410472210720024190026a41206a210120024190026a41186a210e20024190026a41106a210f20024190026a41086a2110201f210503402005280200210c2001200541246a290200370300200e2005411c6a290200370300200f200541146a29020037030020102005410c6a2902003703002002200541046a290200370390020240200c0d002005412c6a21050c030b2007200229039002370200200741086a2010290300370200200741106a200f290300370200200741186a200e290300370200200741206a20012903003702002002200c3602b003202010c8012106200241d0006a41286a200241b0036a41286a280200360200200241d0006a41206a200241b0036a41206a290300370300200241d0006a41186a200241b0036a41186a290300370300200241d0006a41106a200241b0036a41106a290300370300200241d0006a41086a200241b0036a41086a290300370300200220022903b003370350200241e0026a200241d0006a2006420010cb01200941286a200241e0026a41286a280200360200200941206a200241e0026a41206a290300370200200941186a200241e0026a41186a290300370200200941106a200241e0026a41106a290300370200200941086a200241e0026a41086a290300370200200920022903e002370200200341016a21032009412c6a21092005412c6a2205200d470d000b200220033602f8030c020b1045000b200220033602f8032005200d460d00034020052209412c6a21050240200941046a2802002207450d00200741246c450d00200928020010350b200d2005470d000b0b02402016450d002016412c6c450d00201f10350b20022802f403210d200241d0006a2018200a2021200310cc01024002402002280250220c0d00410021054100210c410021010c010b2002280258210102400240200228025422090d00200c21050c010b20092105200c2107034020072802c80521072005417f6a22050d000b200c21050340200520052f01064102746a41c8056a28020021052009417f6a22090d000b2007210c0b20052f010621090b200241ec006a2009360200200241e8006a4100360200200241e4006a20053602002002200136027020024100360260200242003703582002200c36025420024100360250200aad21062002200241306a360274200241b0036a200241d0006a10cd0120022802b003211c20022802b403211d20022802b803210a02402003450d002003412c6c21092021210503400240200541046a2802002207450d00200741306c450d00200528020010350b2005412c6a2105200941546a22090d000b0b200642208621060240200d450d00200d412c6c450d00202110350b2006200884212441002126201b450d00201b41306c450d00201710350b200241d0006a41186a22094200370300200241d0006a41106a22074200370300200241d0006a41086a220542003703002002420037035041f7edcb00ad4280808080f0008422081001220c2900002106200241e0026a41086a2203200c41086a290000370300200220063703e002200c103520052003290300370300200220022903e00237035041ceeecb00ad4280808080b001841001220c2900002106200241b0036a41086a220d200c41086a290000370300200220063703b003200c1035201420022903b003370000201441086a200d290300370000200241306a41086a2005290300370300200241306a41106a2007290300370300200241306a41186a200929030037030020022002290350370330201510074100210c20264103460d032009420037030020074200370300200542003703002002420037035020081001220c29000021062003200c41086a290000370300200220063703e002200c103520052003290300370300200220022903e00237035041b6aac000ad42808080809002841001220c2900002106200d200c41086a290000370300200220063703b003200c1035200420022903b003370000200441086a200d29030037000020024190046a41086a200529030037030020024190046a41106a200729030037030020024190046a41186a20092903003703002002200229035037039004410110332205450d04200541003a000020122005ad4280808080108410022005103542002108200241d0006a41186a22274200370300200241d0006a41106a22284200370300200241d0006a41086a221a42003703002002420037035041f7edcb00ad4280808080f00084220610012205290000210b200241e0026a41086a2229200541086a2900003703002002200b3703e00220051035201a2029290300370300200220022903e0023703504192aac000ad4280808080a0028410012205290000210b200241b0036a41086a220e200541086a2900003703002002200b3703b00320051035200420022903b003370000200441086a2209200e29030037000020024190046a41086a2221201a29030037030020024190046a41106a221f202829030037030020024190046a41186a221620272903003703002002200229035037039004201210072027420037030020284200370300201a42003703002002420037035020061001220529000021062029200541086a290000370300200220063703e00220051035201a2029290300370300200220022903e00237035041a4aac000ad4280808080a00284100122052900002106200e200541086a290000370300200220063703b00320051035200420022903b0033700002009200e2903003700002021201a290300370300201f202829030037030020162027290300370300200220022903503703900420121007201c200a41d0006c6a21200240200a0d00201c210d420021060c020b200241e0026a41106a211b20024190026a41106a210f200241b4026a2104200241d0006a41206a21014200210842002106201c210d0340200241b0036a41386a220a200d220541386a290300370300200241b0036a41306a220c200541306a290300370300200241b0036a41286a2203200541286a290300370300200241b0036a41206a2210200541206a290300370300200241b0036a41186a2209200541186a290300370300200241b0036a41106a2207200541106a290300370300200e200541086a2903003703002005290300210b200241d0026a41086a2214200541cc006a2802003602002002200b3703b0032002200541c4006a2902003703d002200541d0006a210d200541c0006a2802002205450d02200241d0006a41386a200a290300370300200241d0006a41306a200c290300370300200241d0006a41286a2003290300370300200120102903003703002027200929030037030020282007290300370300201a200e290300370300200220022903b003370350200241f0036a41186a2009290300370300200241f0036a41106a2007290300370300200241f0036a41086a200e290300370300200220022903b0033703f00320024190026a41186a2217200141186a290300370300200f200141106a29030037030020024190026a41086a221e200141086a290300220b370300200220053602b00220022001290300222237039002200420022903d002370200200441086a201428020036020020024190046a2011200241f0036a10ce0120023502980421232002280290042110200241003602e802200242013703e002200220024190026a360230200241306a200241e0026a10cf012002200f360230200241306a200241e0026a10cf0120022802b002210520022802b8022209200241e0026a107702402009450d00200941306c210c03400240024020022802e402220a20022802e80222096b4120490d0020022802e00221070c010b200941206a22072009490d04200a41017422032007200320074b1b22034100480d0402400240200a0d00024020030d00410121070c020b200310332207450d0a0c010b20022802e0022107200a2003460d002007200a200310372207450d090b200220033602e402200220073602e0020b200720096a2207200541106a290000370000200741186a200541286a290000370000200741106a200541206a290000370000200741086a200541186a2900003700002002200941206a3602e80220022005360230200241306a200241e0026a10cf01200541306a2105200c41506a220c0d000b0b20022802e402210520234220862010ad8420023502e80242208620022802e0022209ad84100202402005450d00200910350b0240200228029404450d00201010350b20162017290300370300201f200f2903003703002021201e29030037030020022002290390023703900420022802bc02210720022802b402210a20022802b0022109024020022802b802220541c100490d0020092005410041202005676b10d00141c00021050b200241e0026a41186a2016290300370300201b201f2903003703002029202129030037030020022002290390043703e0022002200736028c0320022005360288032002200a360284032002200936028003200241a0036a2011200241f0036a10d10120023502a803212320022802a003211020024100360238200242013703302002200241e0026a3602800220024180026a200241306a10cf012002201b3602800220024180026a200241306a10cf0120022802800321052002280288032209200241306a107702402009450d00200941306c210c0340024002402002280234220a200228023822096b4120490d00200228023021070c010b200941206a22072009490d04200a41017422032007200320074b1b22034100480d0402400240200a0d00024020030d00410121070c020b200310332207450d0a0c010b20022802302107200a2003460d002007200a200310372207450d090b20022003360234200220073602300b200720096a2207200541106a290000370000200741186a200541286a290000370000200741106a200541206a290000370000200741086a200541186a2900003700002002200941206a360238200220053602800220024180026a200241306a10cf01200541306a2105200c41506a220c0d000b0b2006200b7c200820227c220b2008542205ad7c21082002280234210920234220862010ad84200235023842208620022802302207ad84100202402009450d00200710350b2008200651210920082006542107024020022802a403450d00201010350b2005200720091b210502402002280284032209450d00200941306c450d0020022802800310350b427f200820051b2106427f200b20051b2108200d2020470d000c030b0b103e000b2020200d460d000340200d220541d0006a210d0240200541c4006a2802002209450d00200941306c450d00200541c0006a28020010350b2020200d470d000b0b0240201d450d00201d41d0006c450d00201c10350b200241b0036a201110bd0120022802b003210520023502b803210b2002200637035820022008370350200b4220862005ad84201342808080808002841002024020022802b403450d00200510350b02402024422088a7410574220a450d00200241b0036aad210b201821050340200241d0006a200510b501200220022802502207200228025810d2012002280204410020022802001b210902402002280254450d00200710350b200241d0006a2011200510d3012002350258210620022802502107200241003a00b5030240024002400240200941c000490d00200941808001490d012009418080808004490d02200241053a00b503200241033a00b003200220093600b1034280808080d00021080c030b200241013a00b503200220094102743a00b00342808080801021080c020b200241023a00b503200220094102744101723b01b00342808080802021080c010b200241043a00b503200220094102744102723602b0034280808080c00021080b20064220862007ad842008200b841002024020022d00b503450d00200241003a00b5030b02402002280254450d00200710350b200541206a2105200a41606a220a0d000b0b200241d9006a20263a0000200241d8006a41043a0000200241043a005041b0b4cc004100200241d0006a10d4012018210c0b200020243702042000200c360200200241c0046a24000f0b103c000b8f0201037f230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822040d00410021010c010b200328020c210502400240200341106a2802004104490d0020042800002102410121010c010b4100210120034100360220200342013703182003410936022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341c888c2003602382003200341286a360248200341346a41e88ac500200341386a10431a200335022042208620033502188410060240200328021c450d00200328021810350b0b2005450d00200410350b2000200236020420002001360200200341d0006a24000bd71704027f017e077f017e230041d0006b2201240041f7edcb00ad4280808080f00084100122022900002103200141086a41086a200241086a290000370300200120033703082002103541e4b6c000ad4280808080b00184100122022900002103200141186a41086a200241086a2900003703002001200337031820021035200120003602342001200141346aad22034280808080c000841003220229000037033820021035200141cc006a200141386a3602002001200141386a41086a22043602442001200141346a3602482001200141386a360240200141286a200141c0006a107b02400240024002402001280230220541206a2206417f4c0d00200128022821070240024020060d0041002108410121020c010b200610332202450d02200621080b024002402008410f4d0d00200821090c010b200841017422094110200941104b1b22094100480d03024020080d002009103322020d010c050b20082009460d0020022008200910372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020094170714110460d00200921080c010b200941017422084120200841204b1b22084100480d0320092008460d0020022009200810372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200841606a2005490d00200821090c010b200541206a22092005490d032008410174220a2009200a20094b1b22094100480d0320082009460d0020022008200910372202450d040b200241206a20072005109d081a0240200128022c450d00200710350b2006ad4220862002ad84100802402009450d00200210350b41f7edcb00ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002103541d2b6c000ad4280808080a0028410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002103520012000360234200120034280808080c000841003220229000037033820021035200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a107b2001280230220541206a2208417f4c0d00200128022821070240024020080d0041002109410121020c010b200810332202450d02200821090b024002402009410f4d0d00200921060c010b200941017422064110200641104b1b22064100480d03024020090d00200610332202450d050c010b20092006460d0020022009200610372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020064170714110460d00200621090c010b200641017422094120200941204b1b22094100480d0320062009460d0020022006200910372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200941606a2005490d00200921060c010b2005415f4b0d03200941017422062008200620084b1b22064100480d0320092006460d0020022009200610372202450d040b200241206a20072005109d081a0240200128022c450d00200710350b2008ad4220862002ad84100802402006450d00200210350b41f7edcb00ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002103541c0b6c000ad4280808080a0028410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002103520012000360234200120034280808080c000841003220229000037033820021035200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a107b2001280230220541206a2208417f4c0d00200128022821070240024020080d0041002109410121020c010b200810332202450d02200821090b024002402009410f4d0d00200921060c010b200941017422064110200641104b1b22064100480d03024020090d00200610332202450d050c010b20092006460d0020022009200610372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020064170714110460d00200621090c010b200641017422094120200941204b1b22094100480d0320062009460d0020022006200910372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200941606a2005490d00200921060c010b2005415f4b0d03200941017422062008200620084b1b22064100480d0320092006460d0020022009200610372202450d040b200241206a20072005109d081a0240200128022c450d00200710350b2008ad4220862002ad84100802402006450d00200210350b41f7edcb00ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002103541dcb5c000ad4280808080b0028410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002103520012000360234200120034280808080c000841003220229000037033820021035200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a107b2001280230220541206a2208417f4c0d00200128022821070240024020080d0041002109410121020c010b200810332202450d02200821090b024002402009410f4d0d00200921060c010b200941017422064110200641104b1b22064100480d03024020090d00200610332202450d050c010b20092006460d0020022009200610372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020064170714110460d00200621090c010b200641017422094120200941204b1b22094100480d0320062009460d0020022006200910372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200941606a2005490d00200921060c010b2005415f4b0d03200941017422062008200620084b1b22064100480d0320092006460d0020022009200610372202450d040b200241206a20072005109d081a0240200128022c450d00200710350b2008ad4220862002ad84100702402006450d00200210350b200141c0006a200010ad01200135024842208620012802402202ad84100702402001280244450d00200210350b41f7edcb00ad4280808080f0008410012202290000210b200141086a41086a200241086a2900003703002001200b3703082002103541efb5c000ad4280808080e0018410012202290000210b200141186a41086a200241086a2900003703002001200b3703182002103520012000360234200120034280808080c000841003220229000037033820021035200141cc006a200141386a360200200120043602442001200141346a3602482001200141386a360240200141286a200141c0006a107b2001280230220641206a2208417f4c0d00200128022821050240024020080d0041002104410121020c010b200810332202450d02200821040b024002402004410f4d0d00200421090c010b200441017422094110200941104b1b22094100480d03024020040d00200910332202450d050c010b20042009460d0020022004200910372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020094170714110460d00200921040c010b200941017422044120200441204b1b22044100480d0320092004460d0020022009200410372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200441606a2006490d00200421090c010b2006415f4b0d03200441017422092008200920084b1b22094100480d0320042009460d0020022004200910372202450d040b200241206a20052006109d081a0240200128022c450d00200510350b2008ad4220862002ad84100702402009450d00200210350b200141c0006a200010b801200135024842208620012802402202ad84100702402001280244450d00200210350b200141d0006a24000f0b1044000b1045000b103e000b103c000bb10201067f230041206b22022400024002402001422088a722030d00410121040c010b2001a721040b200220033602142002200436021002402003450d0020042d0000210520022003417f6a3602142002200441016a360210200541014b0d0041002106024002400240024020050e020100010b200241086a200241106a10c40120022802080d0320022802142205200228020c2203490d032003417f4c0d010240024020030d0042002101410121060c010b200310392206450d032006200228021022072003109d081a2002200520036b3602142002200720036a3602102003ad21010b2006450d0320012003ad4220868421010b200020013702042000200636020020041035200241206a24000f0b1044000b1045000b41b89acc00412e200241186a41c09bcc0041e89acc001046000ba20401097f230041e0006b220224002002200110c40102400240024002402002280200450d00200041003602000c010b2002280204220320012802044105762204200420034b1b22044105742205417f4c0d010240024020040d00410121060c010b200510332206450d030b41002107200241003602102002200436020c20022006360208024002402003450d0041002108034041002105200241003a0058200841016a21082001280204417f6a210403402004417f460d03200241386a20056a200128020022092d00003a0000200120043602042001200941016a3602002002200541016a22093a00582004417f6a21042009210520094120470d000b200241186a41186a2205200241386a41186a290300370300200241186a41106a2209200241386a41106a290300370300200241186a41086a220a200241386a41086a2903003703002002200229033837031802402007200228020c470d00200241086a20074101108a0120022802082106200228021021070b200620074105746a22042002290318370000200441186a2005290300370000200441106a2009290300370000200441086a200a2903003700002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c010b0240200541ff0171450d00200241003a00580b20004100360200200228020c41ffffff3f71450d00200610350b200241e0006a24000f0b1044000b1045000bcf0201067f0240024020012802042202450d00200128020022032d0000210420012002417f6a2205360204410121062001200341016a3602000240200441037122074103460d0002400240024020070e03000102000b20044102762107410021060c040b41012106024020050d000c040b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d03200141fcff03714102762107410021060c030b20054103490d01200341036a2d0000210620032f0001210720012002417c6a3602042001200341046a3602002007200641107472410874200472220141808004492106200141027621070c020b0240200441034d0d000c020b20054104490d012003280001210720012002417b6a3602042001200341056a36020020074180808080044921060c010b410121060b20002007360204200020063602000b990707017f047e027f017e057f047e017f23004190026b22022400200241c0006a200110f60102400240024002400240024002402002290340a70d00200241c0006a41106a290300210320022903482104200241286a200110f6012002290328a70d03200241286a41106a290300210520022903302106200241206a200110c40120022802200d0220022802242207200128020441306e2208200820074b1bad42307e2209422088a7450d010c060b200041003602200c040b2009a72208417f4c0d040240024020080d004108210a0c010b20081033220a450d030b4100210b200241003602602002200a3602582002200841306e36025c0240024002402007450d004100210c03404100210d200241003a008802200c41016a210c2001280204417f6a210803402008417f460d03200241e8016a200d6a2001280200220e2d00003a0000200120083602042001200e41016a3602002002200d41016a220e3a0088022008417f6a2108200e210d200e4120470d000b200241c8016a41186a2208200241e8016a41186a290300370300200241c8016a41106a220d200241e8016a41106a290300370300200241c8016a41086a220e200241e8016a41086a290300370300200220022903e8013703c801200241086a200110f6012002290308a70d03200241086a41106a29030021092002290310210f20024188016a41086a200e290300221037030020024188016a41106a200d290300221137030020024188016a41186a20082903002212370300200241e8006a41086a220d2010370300200241e8006a41106a220e2011370300200241e8006a41186a22132012370300200220022903c801221037038801200220103703680240200b200228025c470d00200241d8006a200b41011088012002280258210a2002280260210b0b200a200b41306c6a220820093703082008200f37030020082002290368370310200841186a200d290300370300200841206a200e290300370300200841286a20132903003703002002200b41016a220b360260200c2007470d000b0b200a450d02200229025c210920002004370300200020093702242000200a3602202000200637031020002003370308200041186a20053703000c050b200d41ff0171450d00200241003a0088020b20024188016a41086a200241a8016a41086a290300370300200228025c2201450d00200141306c450d00200a10350b200041003602200c020b200041003602200c010b1045000b20024190026a24000f0b1044000bbd0101047f230041106b22022400200028020421032000280200210041012104200128021841d9a0c00041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d0003402002200036020c20022002410c6a41accfc70010701a200041016a21002003417f6a22030d000b20022d000421050b0240200541ff01710d002002280200220028021841d8a0c00041012000411c6a28020028020c11000021040b200241106a240020040b8a0604057f017e047f037e230041f0006b22022400200241286a200141146a350200422086200135020c84102710c2010240024020022802282203450d00200141086a2104200141106a210503400240024020042802002206200229022c2207422088a722084b0d00200128020022092003460d0120092003200610a008450d010b2007a7450d02200310350c020b02402005280200450d00200128020c10350b2001200336020c2005200737020020022003200810d201024002402002280200450d002002280204210a024020012d0018450d002001350214422086200135020c8410070b2001280214220820042802002203490d0102400240200820036b22084108490d00200841786a2106200128020c20036a41086a21090c010b410021060240410028028cb54c0d0041b0b4cc0021090c010b410021064100280298b54c21034100280294b54c21084100280290b54c210b200241e500360268200242b48080801037036020024187a1c00036025c20024213370254200241f4a0c0003602502002420037034841b0b4cc002109200241b0b4cc0036024420024201370338200241eca0c00036023420024113360230200241f4a0c00036022c20024101360228200841aca2c000200b410246220b1b200241286a200341c4a2c000200b1b2802101102000b41002103200241003a00480240034020062003460d01200241286a20036a200920036a2d00003a00002002200341016a22083a00482008210320084120470d000b200241086a41186a200241286a41186a2903002207370300200241086a41106a200241286a41106a290300220c370300200241086a41086a200241286a41086a290300220d37030020022002290328220e3703082000411c6a2007370000200041146a200c3700002000410c6a200d3700002000200e370004200041246a200a360200200041013602000c050b200341ff0171450d00200241003a00480b200241286a2001350214422086200135020c84102710c201200228022822030d010c020b0b2003200841889aca001059000b200041003602000b200241f0006a24000bda0b04047f017e027f027e23004190026b2201240020014180026a200010b401200141d8006a200128028002220020012802880210d501200141e0016a41086a2202200141e1006a290000370300200141e0016a41106a2203200141e9006a290000370300200141e0016a41186a2204200141f1006a290000370300200120012900593703e0010240024002400240024002400240024020012d00584101470d00200141386a41186a2004290300370300200141386a41106a2003290300370300200141386a41086a2002290300370300200120012903e0013703380240200128028402450d00200010350b200141d8006a41186a2202200141386a41186a290300370300200141d8006a41106a2203200141386a41106a290300370300200141d8006a41086a2204200141386a41086a2903003703002001200129033837035841f7edcb00ad4280808080f00084100122002900002105200141b0016a41086a200041086a290000370300200120053703b0012000103541c6a9c000ad4280808080e00084100122002900002105200141c0016a41086a200041086a290000370300200120053703c00120001035412010332200450d0420002001290358370000200041186a2002290300370000200041106a2003290300370000200041086a20042903003700002000ad428080808080048410042202290000210520014180026a41086a200241086a290000370300200120053703800220021035200141ec016a200041206a360200200120003602e801200120014180026a41106a3602e401200120014180026a3602e001200141d0016a200141e0016a107b2000103520012802d801220641206a2202417f4c0d0520012802d00121070240024020020d0041002103410121000c010b200210332200450d05200221030b024002402003410f4d0d00200321040c010b200341017422044110200441104b1b22044100480d07024020030d002004103322000d010c090b20032004460d0020002003200410372200450d080b200020012903b001370000200041086a200141b0016a41086a2903003700000240024020044170714110460d00200421030c010b200441017422034120200341204b1b22034100480d0720042003460d0020002004200310372200450d080b200020012903c001370010200041186a200141c0016a41086a29030037000002400240200341606a2006490d00200321040c010b2006415f4b0d07200341017422042002200420024b1b22044100480d0720032004460d0020002003200410372200450d080b200041206a20072006109d081a024020012802d401450d00200710350b200141d8006a2000200210d60120012802782203450d01200141f0006a290300210820014188016a280200210620014184016a280200210720012903682109200128027c210202402004450d00200010350b02402002450d00200241186c450d00200310350b200641ffffffff0371450d03200710350c030b200128028402450d01200010350c010b2004450d00200010350b42002109420021080b200141d8006a41186a4200370300200141d8006a41106a22034200370300200141d8006a41086a220042003703002001420037035841b6fdc600ad42808080808001841001220229000021052000200241086a290000370300200120053703582002103541e489c200ad4280808080d00184100122022900002105200141386a41086a2204200241086a2900003703002001200537033820021035200320012903382205370300200141e0016a41086a2000290300370300200141e0016a41106a2005370300200141e0016a41186a2004290300370300200120012903583703e001200141206a200141e0016a412010d701200141106a2001290328200141206a41106a290300427f420010980820012009200820012903104200200128022022001b220542012005420156200141106a41086a290300420020001b22054200522005501b22001b2005420020001b1098082001290300210520014190026a240020050f0b1045000b1044000b103e000b103c000be80808097f017e0c7f017e017f017e017f037e230041f0016b22022400200241086a41186a200141186a280200360200200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241e8006a200241086a10c905024020022d0098014102460d00200041046a21030340200241a0016a41286a200241e8006a41286a280200360200200241a0016a41206a200241e8006a41206a2201290300370300200241a0016a41186a2204200241e8006a41186a2205290300370300200241a0016a41106a2206200241e8006a41106a2207290300370300200241a0016a41086a2208200241e8006a41086a2209290300370300200220022903683703a0012001280200210a0240200229028c01220b422088a7220c450d00200228029401210d4100210e200a21014100210f024002400340200220013602cc01200241d0016a200241cc016a10bb01024002400240024020022802dc012210450d0020022802d8012111024020022802e00141ffffffff0371450d00201010350b2011200d4b0d010b200e0d014100210e0c020b200e41016a210e0c010b200f200e6b2210200c4f0d02200241d0016a41186a22112001200e4105746b221041186a2212290000370300200241d0016a41106a2213201041106a2214290000370300200241d0016a41086a2215201041086a2216290000370300200220102900003703d001200141086a22172900002118200141106a2219290000211a200141186a221b290000211c201020012900003700002012201c3700002014201a37000020162018370000201b20112903003700002019201329030037000020172015290300370000200120022903d0013700000b200141206a2101200c200f41016a220f460d020c000b0b2010200c41f485cc001042000b200e417f6a200c4f0d00200b42ffffffff0f83200c200e6bad42208684210b0b200241c8006a41186a22012004290300370300200241c8006a41106a220e2006290300370300200241c8006a41086a220f2008290300370300200220022903a001370348200a450d01200520012903003703002007200e2903003703002009200f29030037030020022002290348370368200241e8006a10c8012118200241286a41186a2001290300221a370300200241286a41106a200e290300221c370300200241286a41086a200f290300221d37030020022002290348221e3703282005201a3703002007201c3703002009201d3703002002201e3703680240200041086a220f280200220e2003280200470d002000200e4101108b010b2000280200200e41386c6a22012002290368370308200120183703002001200a360228200141106a2009290300370300200141186a2007290300370300200141206a20052903003703002001412c6a200b370200200f200e41016a360200200241e8006a200241086a10c90520022d0098014102470d000b0b0240200228020c450d00200228020810350b0240200241186a280200450d00200228021410350b200241f0016a24000bab2104027f017e107f077e23004190026b2205240020054100360238200541003602300240024002400240200441086a280200200341086a28020022066aad42e0007e2207422088a70d002007a72208417f4c0d0041082109024002402008450d00200810332209450d010b20054100360248200520093602402005200841e0006e3602442003280204210a2003280200210b2005410036029801200542083703900120054190016a410020064105742209410575109b01200528029801210c02402006450d00200941606a410576210d200528029001200c41d8006c6a210e200541f0016a2108200541e8016a210f41002106200b21030340200541a0016a41186a2210200341186a2211290000370300200541a0016a41106a2212200341106a2213290000370300200541a0016a41086a2214200341086a2215290000370300200520032900003703a001200541e0006a41186a2011290000370300200541e0006a41106a2013290000370300200541e0006a41086a201529000037030020052003290000370360200541306a200541e0006a2006108403200541c0016a41086a4200370300200541c0016a41106a4200370300200541c0016a41186a4200370300200541c0016a41206a4200370300200f4200370300200841186a2010290300370000200841106a2012290300370000200841086a2014290300370000200820052903a001370000200542003703c001200e200541c0016a41d000109d08220e41d0006a41003a0000200e41d8006a210e200341206a2103200641016a2106200941606a22090d000b200c200d6a41016a210c0b2005200c360298010240200a41ffffff3f71450d00200b10350b200541d0006a41086a20054190016a41086a2802002203360200200520052903900137035020032002490d032004280204210620042802002103200541c0006a2005280248200441086a28020041386c220941386d10a4012005280240210e20052802482108200541d4016a200541d0006a3602002005200320096a3602cc01200520033602c801200520063602c401200520033602c0012005200541306a3602d001200541e0006a41086a20083602002005200541c8006a3602642005200e200841e0006c6a360260200541c0016a200541e0006a109a042001ad42307e2207422088a70d012007a72208417f4c0d01200528025821030240024020080d00410821040c010b200810332204450d010b20054100360218200520043602102005200841306e3602142001412c6c2208417f4c0d010240024020080d00410421160c010b200810332216450d010b4100210b2005410036022820052001360224200520163602202003200120032001491b2217450d024100210b200541c0016a41186a210a200541c0016a41106a210f200541c0016a41086a210d4100210203402005280250210602402003450d00200341d8006c21082006210303400240200341d0006a2d00000d0002400240200341206a2903002218200341286a29030022198450450d0042002107427f2118427f21190c010b427f21072005427f427f20182019109808200541086a2903002119200529030021180b2003201837030020032019370308200341106a2007370300200341186a20073703000b200341d8006a2103200841a87f6a22080d000b0b0240024020052802482203450d0020052802402209200341e0006c6a21120340024020092802382203450d00200341c8006c2106200928023041206a210303402005280258220e200328020022084d0d0402402005280250200841d8006c6a22082d00500d0020082903202207200841286a290300221884500d00200541c0016a2009290310200941186a2903002009290300200941086a29030020072018109b04200820082903002207427f2007427f20052903c80120052802c001410146220e1b22197c221820182007542210200841086a22112903002207427f200f290300200e1b221a7c2010ad7c221820075420182007511b220e1b2019201a845022101b37030020112007427f2018200e1b20101b3703000b200341c8006a2103200641b87f6a22060d000b0b200941e0006a22092012470d000b200528025021060b200241016a2102200528025841d8006c2103200641a87f6a210803402003450d05200341a87f6a2103200841d8006a2108200641d0006a2109200641d8006a220e210620092d00000d000b02402003450d00200841086a2903002107200841186a2903002118200841106a29030021192008290300211a4100210603400240200e20066a220941d0006a2d00000d00200941086a290300221b2007201a2007201920182009290300221c201b200941106a290300221d200941186a290300221e109c0441ff017141014622101b2107201c201a20101b211a201e201820101b2118201d201920101b21192009200820101b21080b2003200641d8006a2206470d000b2008450d050b200841013a0050024020052802482203450d0020052802402206200341e0006c6a21012008410c6a2114200841306a21150340200641e0006a210c024020062802382209450d0020062802302103200941c8006c210903400240024020142003460d00200341246a2015412010a0080d010b200641186a220e290300211a200841086a2210290300210720062903102119200829030021182008290310211b200341186a200841186a2211290300370300200341106a201b3703002003200742002007201a7d2018201954ad7d221b201820197d221c201856201b200756201b2007511b22121b2019201a845022131b370308200320184200201c20121b20131b37030020102903002107201129030021182008290300211920062008290310370320200641286a201837030020062019370310200e20073703000b200341c8006a2103200941b87f6a22090d000b0b200c2106200c2001470d000b0b200a200841c8006a290000370300200f200841c0006a290000370300200d200841386a290000370300200520082900303703c001200841286a2903002107200829032021180240200b2005280214470d00200541106a200b4101108801200528021021042005280218210b0b2004200b41306c6a220320052903c001370300200d2903002119200f290300211a200a290300211b20032018370320200341286a2007370300200341186a201b370300200341106a201a370300200341086a20193703002005200b41016a220b360218200220174f0d04200528025821030c010b0b2008200e41f4c4c8001042000b1045000b1044000b024020052802482203450d0020052802402214200341e0006c6a2102200b41306c210c200541ec006a220b41186a210a200b41106a210d200b41086a2117410021010340200b201429003c370000200a201441d4006a290000370000200d201441cc006a2900003700002017201441c4006a2900003700002005410036026820054204370360024020142802382203450d0020142802302212200341c8006c6a2115201441106a210f410021114104211303402012221041246a2106201041c8006a211241002109200c210820042103024003402008450d01024020062003460d0020032006412010a008210e200941016a2109200841506a2108200341306a2103200e0d010b0b418094ebdc0321080240200f2010109d040d004100210302402010290310201429032085201041186a290300201441286a29030085844200520d00200541c0016a428094ebdc0342002010290300201041086a290300200f290300200f41086a290300109b04427f20052903c80120052802c00141014622031b221842ffffffff0f56427f200541c0016a41106a29030020031b22074200522007501b0d012018a7220341ff93ebdc034b0d010b200321080b200541c0016a41186a22062010413c6a290000370300200541c0016a41106a2209201041346a290000370300200541c0016a41086a220e2010412c6a290000370300200520102900243703c001024020112005280264470d00200541e0006a20114101108d0120052802602113200528026821110b2013201141246c6a220320052903c001370200200e2903002107200929030021182006290300211920032008360220200341186a2019370200200341106a2018370200200341086a20073702002005201141016a22113602680b20122015470d000b024002402011450d0002400240201141246c22060d00410021030c010b201341206a2108410021030340417f200320082802006a220920092003491b2103200841246a21082006415c6a22060d000b0b02404100418094ebdc0320036b22032003418094ebdc034b1b221020116e2203418094ebdc032003418094ebdc03491b220e450d00201341206a210341002108034020112008460d032005417f20032802002206200e6a220920092006491b22063602c0012005418094ebdc033602c4012003200541c0016a2006418094ebdc034b4102746a280200360200200341246a21032011200841016a2208470d000b0b02402010200e20116c6b220e450d004100210303402005417f2013200320117041246c6a2208280220220641016a220920092006491b22063602c0012005418094ebdc033602c4012008200541c0016a2006418094ebdc034b4102746a280200360220200341016a2203200e490d000b0b200541c0016a41286a2208200541e0006a41286a280200360200200541c0016a41206a2206200541e0006a41206a290300370300200541c0016a41186a2209200541e0006a41186a290300370300200541c0016a41106a220e200541e0006a41106a290300370300200541c0016a41086a2210200541e0006a41086a290300370300200520052903603703c001024020012005280224470d00200541206a2001410110980120052802202116200528022821010b20162001412c6c6a220320052903c001370200200341286a2008280200360200200341206a2006290300370200200341186a2009290300370200200341106a200e290300370200200341086a20102903003702002005200141016a22013602280c020b20052802642203450d01200341246c450d01201310350c010b200820114184c5c8001042000b201441e0006a22142002470d000b0b200541c0016a41086a2203200541106a41086a280200360200200541d4016a200541206a41086a28020036020020002005290310370200200520052903203702cc01200041086a2003290300370200200041106a200541c0016a41106a290300370200024020052802542203450d00200341d8006c450d00200528025010350b024020052802482203450d00200341e0006c2108200528024041346a21030340024020032802002206450d00200641c8006c450d002003417c6a28020010350b200341e0006a2103200841a07f6a22080d000b0b024020052802442203450d00200341e0006c450d00200528024010350b200541306a10b1010c010b20004100360200024020052802542203450d00200341d8006c450d00200528025010350b024020052802482203450d00200341e0006c2108200528024041346a21030340024020032802002206450d00200641c8006c450d002003417c6a28020010350b200341e0006a2103200841a07f6a22080d000b0b024020052802442203450d00200341e0006c450d00200528024010350b200541306a10b101200428020021060240200441086a2802002203450d00200341386c21082006412c6a210303400240200328020041ffffff3f71450d002003417c6a28020010350b200341386a2103200841486a22080d000b0b200441046a2802002203450d00200341386c450d00200610350b20054190026a24000be80b08077f017e017f037e027f037e027f037e230041d0016b22042400200128020421052001280200210602400240024020012802082207450d00200741246c2108410021090340200620096a220741206a280200210a200441b0016a41186a200741186a290000370300200441b0016a41106a200741106a290000370300200441b0016a41086a200741086a290000370300200420072900003703b001200a0d022008200941246a2209470d000b0b4200210b4108210c4100210902402005450d00200541246c450d00200610354200210b0b4200210d410021070c010b200441306a20022003428094ebdc034200109808200441206a2004290330220e200441306a41086a290300220f4280ec94a37c427f108408200441106a200e200f200aad220d4200108408200441d0006a41086a220a200441b0016a41086a290300370300200441d0006a41106a2210200441b0016a41106a290300370300200441d0006a41186a2211200441b0016a41186a290300370300200420042903b001220b3703702004200b370350200d200429032020027c22127e220d428094ebdc0380210b20042903102113200441106a41086a29030021140240024041301033220c450d00200c2013200ba7417f200d428080808080c0b2cd3b541b200d200b4280ec94a37c7e7c4280cab5ee01566aad7c220b370320200c2004290350370300200c41286a2014200b201354ad7c220d370300200c41186a2011290300370300200c41106a2010290300370300200c41086a200a29030037030020044281808080103702442004200c36024002402008415c6a2009470d00410121090c020b200741c4006a210a200820096b41b87f6a2108410121090340200a2802002115200441b0016a41186a2210200a41606a220741186a290000370300200441b0016a41106a2211200741106a290000370300200441b0016a41086a2216200741086a290000370300200420072900003703b0010240024020150d002008450d040c010b2004200e200f2015ad22134200108408200441f0006a41086a20162903002214370300200441f0006a41106a20112903002217370300200441f0006a41186a20102903002218370300200420042903b0012219370370201020183703002011201737030020162014370300200420193703b001200b20042903002214201320127e2213428094ebdc03802217a7417f2013428080808080c0b2cd3b541b201320174280ec94a37c7e7c4280cab5ee01566aad7c22137c2217200b542207200d200441086a2903002013201454ad7c22147c2007ad7c220b200d54200b200d511b2107024020092004280244470d00200441c0006a200941011088012004280240210c0b427f200b20071b210d427f201720071b210b200c200941306c6a220720042903b00137030020162903002117201129030021182010290300211920072013370320200741286a2014370300200741186a2019370300200741106a2018370300200741086a20173703002004200941016a22093602482008450d030b2008415c6a2108200a41246a210a0c000b0b1045000b02402005450d00200541246c450d00200610350b200428024421070b024002402002200b7d22142002562003200d7d2002200b54ad7d221320035620132003511b4101470d00200b20027d2213200b56200d20037d200b200254ad7d220b200d56200b200d511b0d012009450d01200941306c200c6a41706a220a4200200a290300220d20137d22142014200d56200a41086a220a2903002214200b7d200d201354ad7d220d201456200d2014511b22081b370300200a4200200d20081b3703000c010b2009450d00200941306c200c6a41706a220a427f200a290300220d20147c220b200b200d542208200a41086a220a290300220d20137c2008ad7c220b200d54200b200d511b22081b370300200a427f200b20081b3703000b20002009360208200020073602042000200c3602002000200129020c37020c200041146a200141146a2902003702002000411c6a2001411c6a290200370200200041246a200141246a290200370200200441d0016a24000ba028030f7f047e1b7f230022052106200541e00b6b41607122072400200741003602182007410036021002400240024002402002450d00200120024105746a2108200741e0056a41027221094100210a034020074200370348200742003703402007410036025820074208370350200741a8026a41186a220b200141186a290000370300200741a8026a41106a220c200141106a290000370300200741a8026a41086a220d200141086a290000370300200720012900003703a80202400240200a450d002007280214210e0c010b200741e0056a410041e002109f081a200741f8026a410041e002109f081a41c8051033220a450d054100210e200a41003b0106200a4100360200200a41086a200741e0056a41e002109d081a200a41e8026a200741f8026a41e002109d081a200741003602142007200a3602100b200141206a21010240024002400240024002400340200a41066a210f200a2f01062210410574210241002111200a41086a22122105024003402002450d01200741a8026a2005412010a0082213450d03200241606a2102201141016a2111200541206a21052013417f4a0d000b2011417f6a21100b0240200e450d00200e417f6a210e200a20104102746a41c8056a280200210a0c010b0b200741f0006a41186a2202200b290300370300200741f0006a41106a200c2903002214370300200741f0006a41086a200d2903002215370300200720072903a80222163703702007200728021841016a360218200c2014370300200d2015370300200b2002290300370300200720163703a80220072903582114200729035021152007290348211620072903402117200f2f01002205410b490d01200741e0056a410041e002109f081a200741f8026a410041e002109f081a41c80510332218450d0a201841003b010620184100360200201841086a200741e0056a41e002109d082105201841e8026a200741f8026a41e002109d082111200741e0056a41086a2219200a41b0046a290300370300200741e0056a41106a221a200a41b8046a290300370300200741e0056a41186a221b200a41c0046a2903003703002007200a41db016a2900003703e0022007200a41e0016a2900003700e5022007200a41a8046a2903003703e0052007200a41c8016a2f00003b01f4022007200a41ca016a2d00003a00f602200a41cb016a280000211c200a41cf016a280000211d200a41d3016a280000211e200a41d7016a280000211f2005200a41e8016a200a2f010641796a22024105742213109d0821052011200a41c8046a2013109d082111200a41063b0106201820023b0106200720072f01f4023b01dc02200720072d00f6023a00de02200720072903e0023703c802200720072900e5023700cd02200741f8026a41186a2220201b290300370300200741f8026a41106a2221201a290300370300200741f8026a41086a22222019290300370300200720072903e0053703f8020240024020104107490d002005201041057441c07e6a220e6a2005201041796a221341057422106a2205200241ffff037120136b410574109e081a200541186a200b290300370000200541106a200c290300370000200541086a200d290300370000200520072903a8023700002011200e6a201120106a2202201841066a220f2f010020136b410574109e081a200241186a20143703002002201537031020022016370308200220173703000c010b20122010410574220541206a22116a201220056a2202200f2f010020106b410574109e081a200241186a200b290300370000200241106a200c290300370000200241086a200d290300370000200220072903a802370000200a41e8026a220220116a200220056a2202200f2f010020106b410574109e081a200241186a20143703002002201537031020022016370308200220173703000b200f200f2f010041016a3b010020074190026a41026a220220072d00de023a0000200741d8016a41086a22232022290300370300200741d8016a41106a22242021290300370300200741d8016a41186a22252020290300370300200720072f01dc023b019002200720072903c8023703c801200720072900cd023700cd01200720072903f8023703d801200741a4016a41026a222620022d00003a0000200720072f0190023b01a401200720072900cd0137009501200720072903c80137039001200741a8016a41186a22272025290300370300200741a8016a41106a22282024290300370300200741a8016a41086a22292023290300370300200720072903d8013703a8010240200a280200220e0d004100212a200741106a21020c040b200a2f0104210f4100212a0340200741a4026a41026a222b20262d00003a0000200720072f01a4013b01a402200720072903900137039002200720072900950137009502200b2027290300370300200c2028290300370300200d2029290300370300200720072903a8013703a80241000d03200f41ffff0371210a024002400240200e2f01062202410b490d002009410041f205109f081a41f80510332213450d0e20134100360200201341046a200741e0056a41f405109d081a2007200e2f00c8013b01f4022007200e41ca016a2d00003a00f6022007200e41db016a2900003703e0022007200e41e0016a2900003700e502200e41cb016a280000212c200e41cf016a280000212d200e41d3016a280000212e200e41d7016a280000212f201b200e41c0046a290300370300201a200e41b8046a2903003703002019200e41b0046a2903003703002007200e2903a8043703e005201341086a200e41e8016a200e2f0106220241796a22054105742211109d082130201341e8026a200e41c8046a2011109d082131201341c8056a200e41e4056a2002417a6a2210410274109d082112200e41063b0106201320053b010602402010450d00410021022012210503402005280200221120023b010420112013360200200541046a21052010200241016a2202470d000b0b2020201b2903003703002021201a29030037030020222019290300370300200720072903e0053703f802200720072f01f4023b01dc02200720072d00f6023a00de02200720072903e0023703c802200720072900e5023700cd02200741dc056a41026a221020072d00de023a0000200720072f01dc023b01dc05200720072903c8023703c801200720072900cd023700cd01201b2020290300370300201a202129030037030020192022290300370300200720072903f8023703e005200f41ffff037122054107490d012030200a417a6a2211410574220f6a2030200a41796a220241057422326a220520132f010620026b410574109e081a200541186a2007290095023700002005201f36000f2005201e36000b2005201d3600072005201c360003200541026a202b2d00003a0000200520072f01a4023b000020052007290390023700132031200f6a203120326a220520132f0106220f20026b410574109e081a200541186a200b290300370300200541106a200c290300370300200541086a200d290300370300200520072903a8023703002013200f41016a22053b0106200a410274221c20126a416c6a201220114102746a220f200541ffff0371220a20116b410274109e081a200f2018360200200a2011490d022013201c6a41b0056a2105034020052802002211200241016a22023b010420112013360200200541046a21052002200a490d000c030b0b200e41086a2205200a41016a221141057422136a2005200a41057422106a22052002200a6b410574220f109e081a2005201f36000f2005201e36000b2005201d3600072005201c360003200541026a202b2d00003a0000200520072f01a4023b00002005200729039002370013200541186a200729009502370000200e41e8026a220520136a200520106a2205200f109e081a200541186a200b290300370300200541106a200c290300370300200541086a200d290300370300200520072903a802370300200e200241016a22023b0106200a410274200e41c8056a22056a41086a200520114102746a2205200241ffff037120116b410274109e081a20052018360200200a200e2f010622024f0d07201820113b01042018200e360200201120024f0d072002417f6a2113200e2011417f6a22024102746a41d0056a2105034020052802002211200241026a3b01042011200e360200200541046a21052013200241016a2202470d000c080b0b200e41086a2202200a41016a2211410574220f6a2002200a41057422126a2202200e2f01062230200a6b4105742231109e081a2002201f36000f2002201e36000b2002201d3600072002201c360003200241026a202b2d00003a0000200220072f01a4023b00002002200729039002370013200241186a200729009502370000200e41e8026a2202200f6a200220126a22022031109e081a200241186a200b290300370300200241106a200c290300370300200241086a200d290300370300200220072903a802370300200e203041016a22023b0106200a4102742212200e41c8056a220f6a41086a200f20114102746a220f200241ffff037120116b410274109e081a200f20183602002005200e2f010622114f0d00200e20126a41cc056a2102034020022802002205200a41016a220a3b01042005200e360200200241046a21022011200a470d000b0b202a41016a212a2007418c026a41026a220220102d00003a0000202320192903003703002024201a2903003703002025201b290300370300200720072f01dc053b018c02200720072903c8013703f801200720072900cd013700fd01200720072903e0053703d801202620022d00003a0000200720072f018c023b01a401200720072900fd0137009501200720072903f80137039001202720252903003703002028202429030037030020292023290300370300200720072903d8013703a8010240200e28020022020d00200741106a2102202c211c202f211f202e211e202d211d201321180c050b200e2f0104210f202c211c202f211f202e211e202d211d2002210e201321180c000b0b200a20114105746a22024180036a2205290300211520052007290358370300200241f8026a2205290300211420052007290350370300200241f0026a2205290300211620052007290348370300200241e8026a2202290300211720022007290340370300200720153703f805200720143703f005200720163703e805200720173703e0052014a72202450d0420072802f4052205450d04200541306c450d04200210350c040b20122010410574221141206a22136a201220116a2202200520106b410574109e081a200241186a200b290300370000200241106a200c290300370000200241086a200d290300370000200220072903a802370000200a41e8026a220220136a200220116a2202200a2f010620106b410574109e081a200241186a2014370300200220153703102002201637030820022017370300200a200a2f010641016a3b0106200741003602f0050c030b41d684cc00413541c086cc00103f000b2009410041f205109f081a41f80510332205450d0620054100360200200541046a200741e0056a41f405109d081a2005200228020022113602c8052002200536020020022002280204221341016a360204201141003b010420112005360200200741a8026a41026a220a20262d00003a0000200720072f01a4013b01a80220072007290390013703f80220072007290095013700fd02201b2027290300370300201a202829030037030020192029290300370300200720072903a8013703e0052013202a470d0520052f01062211410a4b0d04200520114105746a2202410a6a200a2d00003a0000200241086a20072f01a8023b0000200241176a201f360000200241136a201e3600002002410f6a201d3600002002410b6a201c3600002002411b6a20072903f802370000200241206a20072900fd02370000200241e8026a20072903e005370300200241f0026a2019290300370300200241f8026a201a29030037030020024180036a201b2903003703002005201141016a22024102746a41c8056a2018360200200520023b0106201820023b0104201820053602000b200741003602f0050b20012008460d012007280210210a0c000b0b0240024020040d004100210b0c010b20032004412c6c6a210d4100210b034020032202412c6a21030240200228020841306c2205450d002002280200220a20056a210c2002410c6a21120340200a41306a210f0240024002402007280210220e450d00200728021421010340200e41086a2105200e2f01062210410574210241002111024003402002450d01200a2005412010a0082213450d04200241606a2102201141016a2111200541206a21052013417f4a0d000b2011417f6a21100b2001450d012001417f6a2101200e20104102746a41c8056a280200210e0c000b0b417f200b41016a22022002200b491b210b0c010b200e20114105746a220241e8026a2205427f20052903002214200a2903207c221520152014542205200241f0026a22112903002214200a41286a22132903007c2005ad7c221520145420152014511b22051b3703002011427f201520051b37030020122900002114200741e0056a41086a220e201241086a290000370300200741e0056a41106a2201201241106a290000370300200741e0056a41186a2210201241186a290000370300200720143703e00520132903002114200a2903202115200241f8026a2113024020024180036a22052802002211200241fc026a280200470d00201320114101108801200528020021110b2013280200201141306c6a220220072903e00537030020022015370320200241186a2010290300370300200241106a2001290300370300200241086a200e290300370300200241286a20143703002005200528020041016a3602000b200f210a200f200c470d000b0b2003200d470d000b0b200020072903103702002000200b36020c200041086a200741106a41086a280200360200200624000f0b41af84cc00412741c086cc00103f000b41ff83cc00413041c086cc00103f000b103c000be91105077f017e047f017e097f230041a0026b2202240002400240024002400240024002400240024020012802202203450d0020012003417f6a220436022020012802042203450d02200128020821052001280200210602402001410c6a280200220720032f0106490d00034002400240200328020022080d002005ad2109410021080c010b200641016a210620033301044220862005ad8421090b200310352009a72105200821032009422088a7220720082f01064f0d000b200821030b20024190016a41186a220a200320074105746a220841206a29000037030020024190016a41106a220b200841186a29000037030020024190016a41086a220c200841106a2900003703002002200841086a29000037039001200241f0016a41086a220d20084184036a2802003602002002200841fc026a2902003703f001200741016a2107200841f0026a2903002109200841e8026a290300210e200841f8026a280200210f02402006450d00200320074102746a41c8056a2802002103410021072006417f6a2208450d00034020032802c80521032008417f6a22080d000b0b200241186a41186a200a290300370300200241186a41106a200b290300370300200241186a41086a200c29030037030020024190026a41086a200d2802003602002002200229039001370318200220022903f001370390022001200736020c200120053602082001200336020420014100360200200f0d010b20024180016a41003602000c060b200241b8016a2009370300200241c0016a200f360200200241c4016a20022903900237020020024190016a41186a200241186a41186a29030037030020024190016a41106a200241186a41106a29030037030020024190016a41086a200241186a41086a290300370300200241cc016a20024190026a41086a2802003602002002200e3703b0012002200229031837039001200241c0006a200141246a20024190016a10860220024180016a280200450d0520024190016a200241c0006a41d000109d081a417f200441016a220320032004491bad42d0007e2209422088a70d012009a72203417f4c0d01200310332210450d02201020024190016a41d000109d082108200241013602102002200341d0006e36020c20022008360208200241186a41206a200141206a2902002209370300200241186a41186a200141186a290200370300200241186a41106a200141106a290200370300200241186a41086a200141086a29020037030020022001290200370318024002402009a72203450d0020022003417f6a220f360238200228021c2203450d0520022802202105200228021821070240200241246a280200220620032f0106490d00034002400240200328020022080d002005ad2109410021080c010b200741016a210720033301044220862005ad8421090b200310352009a72105200821032009422088a7220620082f01064f0d000b200821030b20024190016a41186a2201200320064105746a220841206a29000037030020024190016a41106a220b200841186a29000037030020024190016a41086a220c200841106a2900003703002002200841086a2900003703900120024190026a41086a220d20084184036a2802003602002002200841fc026a29020037039002200641016a2106200841f0026a2903002109200841e8026a290300210e200841f8026a280200210a02402007450d00200320064102746a41c8056a2802002103410021062007417f6a2208450d00034020032802c80521032008417f6a22080d000b0b200241f0016a41186a2001290300370300200241f0016a41106a200b290300370300200241f0016a41086a200c290300370300200241e0016a41086a200d28020036020020022002290390013703f00120022002290390023703e00120022006360224200220053602202002200336021c20024100360218200a450d002002413c6a2111200241c4016a2104200241b8016a2112410121010340200420022903e0013702002012200937030020024190016a41186a220b200241f0016a41186a221329030037030020024190016a41106a220c200241f0016a41106a221429030037030020024190016a41086a220d200241f0016a41086a2215290300370300200441086a200241e0016a41086a22162802003602002002200e3703b001200220022903f001370390012002200a3602c001200241c0006a201120024190016a108602200228028001450d0220024190016a200241c0006a41d000109d081a02402001200228020c470d00200241086a2001417f200f41016a22082008200f491b10a301200228020821100b2010200141d0006c6a20024190016a41d000109d081a2002200141016a2201360210200f450d012002200f417f6a220f3602382003450d07410021070240200620032f0106490d00034002400240200328020022080d002005ad2109410021080c010b200741016a210720033301044220862005ad8421090b200310352009a72105200821032009422088a7220620082f01064f0d000b200821030b200b200320064105746a220841206a290000370300200c200841186a290000370300200d200841106a2900003703002002200841086a29000037039001200841f8026a280200210a20024190026a41086a221720084184036a2802003602002002200841fc026a29020037039002200641016a2106200841f0026a2903002109200841e8026a290300210e02402007450d00200320064102746a41c8056a2802002103410021062007417f6a2208450d00034020032802c80521032008417f6a22080d000b0b2013200b2903003703002014200c2903003703002015200d2903003703002016201728020036020020022002290390013703f00120022002290390023703e00120022006360224200220053602202002200336021c20024100360218200a0d000b0b20024100360280010b200241186a109e02200041086a200241086a41086a280200360200200020022903083702000c060b41958dcc00412b41c08dcc00103f000b1044000b1045000b41958dcc00412b41c08dcc00103f000b41958dcc00412b41c08dcc00103f000b20004100360208200042083702002001109e020b200241a0026a24000ba20703027f017e067f230041e0006b2203240041f7edcb00ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541e4b6c000ad4280808080b00184100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b0240024002400240412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2007109d081a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420066a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000ba50403017f027e027f230041e0006b220224000240024020002802002200290300220342c000544100200041086a29030022045022051b0d0002400240024020034280800154410020051b0d00200342808080800454410020051b0d01411020047920037942c0007c20044200521ba741037622056b4104490d022002413320054102746b3a00482001200241c8006a41011078200029030021032002200041086a290300220437030820022003370300200541706a21000340200220033c00482001200241c8006a410110782003420888200442388684210320044208882104200041016a22052000492106200521002006450d000b20022003370300200220043703082003200484500d04200241286a41146a410a360200200241346a410b360200200241106a41146a410336020020022002360240200241d0caca00360244200241c8006a41146a410036020020024203370214200241a0b3cc003602102002410b36022c200241b0b4cc003602582002420137024c20024188caca003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41b0b4cc00104c000b20022003a74102744101723b01482001200241c8006a410210780c030b20022003a74102744102723602482001200241c8006a410410780c020b41c6c9ca00413641c086cc00103f000b20022003a74102743a00482001200241c8006a410110780b200241e0006a24000bf12c080a7f017e017f047e147f017e017f017e230041d0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d00200020011085072003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00410241012000200a41306c6a220d290300220e200d41506a220f290300221056200d41086a2903002211200f41086a29030022125620112012511b220f1b200f200d41306a29030022132010200e200f1b221056200d41386a290300220e20122011200f1b221156200e2011511b22141b2013201020141b2000200a200a417f6a2215200f1b221641306c6a220d29030056200e201120141b2211200d41086a29030022125620112012511b22176a2000200c41306c6a220d290300220e200d41506a2218290300221056200d41086a2903002211201841086a29030022125620112012511b22186a2000200c410172221941306c6a220d29030022132010200e20181b221056200d41086a290300220e2012201120181b221156200e2011511b221a6a20132010201a1b2000200c200c417f6a221b20181b221c41306c6a220d29030056200e2011201a1b2211200d41086a29030022125620112012511b221d6a2000200b41306c6a220d290300220e200d41506a221e290300221056200d41086a2903002211201e41086a29030022125620112012511b221e6a200d41306a29030022132010200e201e1b221056200d41386a290300220e20122011201e1b221156200e2011511b221f6a20132010201f1b2000200b200b417f6a2220201e1b222141306c6a220d29030056200e2011201f1b2211200d41086a29030022125620112012511b22066a210d2021200b41016a2020200b201e1b201f1b20061b210b201c2019201b200c20181b201a1b201d1b210c2016200a41016a2015200a200f1b20141b20171b210a0b200d2000200c41306c6a220f290300220e2000200a41306c6a2218290300221056200f41086a2903002211201841086a29030022125620112012511b220f6a2000200b41306c6a220d29030022132010200e200f1b221056200d41086a290300220e20122011200f1b221156200e2011511b220d6a211820132010200d1b2000200c200a200f1b222141306c6a221e29030058200e2011200d1b2211201e41086a29030022125820112012511b450d01200b200a200c200f1b200d1b21210c020b200020011086070c0f0b201841016a2218410c490d0002402001410176220b450d002000200141306c6a41506a210a2000210c0340200441a0026a41286a220f200c41286a220d290300370300200441a0026a41206a2218200c41206a221e290300370300200441a0026a41186a2214200c41186a221a290300370300200441a0026a41106a221f200c41106a2215290300370300200441a0026a41086a2216200c41086a22172903003703002004200c2903003703a002200a41086a22192903002111200a41106a221b2903002112200a41186a221c290300210e200a41206a221d2903002110200a41286a22202903002113200c200a290300370300200d2013370300201e2010370300201a200e37030020152012370300201720113703002020200f290300370300201d2018290300370300201c2014290300370300201b201f29030037030020192016290300370300200a20042903a002370300200c41306a210c200a41506a210a200b417f6a220b0d000b0b20012021417f736a21214101210a0c010b201845210a0b0240200a452009724101710d00200020011087070d0d0b2002450d02202120014f0d01024020022903002000202141306c6a220a29030056200241086a2903002211200a41086a220c29030022125620112012511b450d0020002108200121070c040b200441a0026a41286a221a200041286a2218290300370300200441a0026a41206a221f200041206a221e290300370300200441a0026a41186a2215200041186a2214290300370300200441a0026a41106a2216200041106a220b290300370300200441a0026a41086a2217200041086a220f290300370300200420002903003703a002200c2903002111200a41106a220d2903002112200a41186a2219290300210e200a41206a221b2903002110200a41286a221c29030021132000200a29030037030020182013370300201e20103703002014200e370300200b2012370300200f2011370300201c201a290300370300201b201f29030037030020192015290300370300200d2016290300370300200c2017290300370300200a20042903a002370300200f29030021112000290300210e200441186a221c2018290300370300200441106a221d201e290300370300200441086a222020142903003703002004200b290300370300200041506a2119200041306a211b4100210c2001210b03400240200c200b417f6a220f4f0d00201b200c41306c6a210a0340200e200a290300582011200a41086a29030022125820112012511b450d01200a41306a210a200f200c41016a220c470d000b200f210c0b2019200b41306c6a210a02400340200c200b417f6a220b4f0d01200a2903002112200a41086a210f200a41506a220d210a200e2012562011200f29030022125620112012511b0d000b201a201b200c41306c6a220a41286a220f290300370300201f200a41206a22212903003703002015200a41186a22062903003703002016200a41106a22222903003703002017200a41086a22232903003703002004200a2903003703a002200d41386a22242903002112200d41c0006a22252903002110200d41c8006a22262903002113200d41d0006a22272903002128200d41d8006a2229290300212a200a200d41306a220d290300370300200f202a370300202120283703002006201337030020222010370300202320123703002029201a2903003703002027201f290300370300202620152903003703002025201629030037030020242017290300370300200d20042903a002370300200c41016a210c0c010b0b2000200e370300200020113703082000200429030037031020142020290300370300201e201d2903003703002018201c29030037030002402001200c41016a220a490d002000200a41306c6a21002001200a6b220141154f0d010c0c0b0b200a200141e485cc001059000b2021200141d086cc001042000b2007450d010b202120074f0d01200441a0026a41286a2217200841286a2222290300370300200441a0026a41206a2219200841206a2223290300370300200441a0026a41186a221b200841186a2224290300370300200441a0026a41106a221c200841106a2225290300370300200441a0026a41086a221d200841086a2226290300370300200420082903003703a0022008202141306c6a220a41086a220c2903002111200a41106a220b2903002112200a41186a220f290300210e200a41206a220d2903002110200a41286a220029030021132008200a29030037030020222013370300202320103703002024200e370300202520123703002026201137030020002017290300370300200d2019290300370300200f201b290300370300200b201c290300370300200c201d290300370300200a20042903a0023703002026290300211120082903002112200441186a22272022290300370300200441106a22292023290300370300200441086a2205202429030037030020042025290300370300200841306a2101410021212007417f6a220f450d022001210a0340200a290300201256200a41086a290300220e201156200e2011511b450d03200a41306a210a200f202141016a2221470d000b200f21210c020b4100410041f485cc001042000b20212007418486cc001042000b2008200741306c6a210a200f210b02400340200a2100200b220c20214d22060d01200c417f6a210b200041506a220a290300201258200a41086a290300220e201158200e2011511b0d000b0b0240200c2021490d00200f200c490d0241800121154100210d4100211a4100210f4100211441800121162001202141306c6a220921010340200020016b220a41306e210c0240200a41afe0004b22200d00200c41807f6a200c201a200d492014200f49220b7222181b210a02402018450d002016200a200b1b2116200a2015200b1b21150c010b200a200a41017622166b21150b02402014200f470d00024020160d00200441206a220f21140c010b4100210c200441206a2214210f2001210a0340200f200c3a0000200f410041014102200a2903002210201285200a41086a290300220e20118584501b2010201254200e201154200e2011511b1b41027441c4cfca006a2802006a210f200a41306a210a2016200c41016a220c470d000b0b0240201a200d470d00024020150d00200441a0016a220d211a0c010b200041506a210a4100210c200441a0016a221a210d0340200d200c3a0000200d410041014102200a2903002210201285200a41086a290300220e20118584501b2010201254200e201154200e2011511b1b41027441d0cfca006a2802006a210d200a41506a210a2015200c41016a220c470d000b0b0240200d201a6b220a200f20146b220c200c200a4b1b221f450d002017200120142d000041306c6a220a41286a2903003703002019200a41206a290300370300201b200a41186a290300370300201c200a41106a290300370300201d200a41086a2903003703002004200a2903003703a002200120142d000041306c6a220a2000201a2d0000417f7341306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a2903003703000240201f4101460d004100210b03402000201a200b6a22182d0000417f7341306c6a220a20012014200b6a41016a221e2d000041306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a2903003703002001201e2d000041306c6a220a2000201841016a2d0000417f7341306c6a220c290300370300200a41286a200c41286a290300370300200a41206a200c41206a290300370300200a41186a200c41186a290300370300200a41106a200c41106a290300370300200a41086a200c41086a290300370300200b41026a210a200b41016a220c210b200a201f490d000b201a200c6a211a2014200c6a21140b2000201a2d0000417f7341306c6a220a20042903a002370300200a41286a2017290300370300200a41206a2019290300370300200a41186a201b290300370300200a41106a201c290300370300200a41086a201d290300370300201a41016a211a201441016a21140b2001201641306c6a20012014200f461b21012000410020156b41306c6a2000201a200d461b210020200d000b024002402014200f4f0d002000210a034020172001200f417f6a220f2d000041306c6a220c41286a220b2903003703002019200c41206a220d290300370300201b200c41186a2200290300370300201c200c41106a2218290300370300201d200c41086a221e2903003703002004200c2903003703a002200a41506a220a41086a221a290300210e200a41106a221f2903002110200a41186a22152903002113200a41206a22162903002128200a41286a2220290300212a200c200a290300370300200b202a370300200d20283703002000201337030020182010370300201e200e37030020202017290300370300201620192903003703002015201b290300370300201f201c290300370300201a201d290300370300200a20042903a0023703002014200f490d000c020b0b2001210a201a200d4f0d000340200d417f6a220d2d0000210c2017200a41286a220b2903003703002019200a41206a220f290300370300201b200a41186a2201290300370300201c200a41106a2218290300370300201d200a41086a221e2903003703002004200a2903003703a0022000200c417f7341306c6a220c41086a2214290300210e200c41106a221f2903002110200c41186a22152903002113200c41206a22162903002128200c41286a2220290300212a200a200c290300370300200b202a370300200f20283703002001201337030020182010370300201e200e37030020202017290300370300201620192903003703002015201b290300370300201f201c2903003703002014201d290300370300200c20042903a002370300200a41306a210a201a200d490d000b0b2008201137030820082012370300200820042903003703102024200529030037030020232029290300370300202220272903003703002007200a20096b41306e20216a22014d0d032017202229030037030020192023290300370300201b2024290300370300201c2025290300370300201d2026290300370300200420082903003703a0022008200141306c6a220a41086a220c2903002111200a41106a220b2903002112200a41186a220f290300210e200a41206a220d2903002110200a41286a220029030021132008200a29030037030020222013370300202320103703002024200e370300202520123703002026201137030020002017290300370300200d2019290300370300200f201b290300370300200b201c290300370300200c201d290300370300200a20042903a002370300200720016b220c450d04200c20012001200c4b1b210b2007410376210f200a41306a2100024002402001200c417f6a220c490d002000200c200a200310d001200821000c010b200820012002200310d001200a2102200c21010b200b200f4f2105200141154f0d010c050b0b2021200c419486cc001059000b200c200f419486cc001058000b20012007418486cc001042000b41a486cc00411c41c086cc00103f000b20014102490d00200041a07f6a210d410021184101210c0340200c41016a210f02402000200c41306c6a220b290300220e200b41506a220a29030058200b41086a221e2903002211200a41086a221429030022125820112012511b0d00200441186a221a200b41286a221f290300370300200441106a2215200b41206a2216290300370300200441086a2217200b41186a22192903003703002004200b290310370300200b200a290300370300201e2014290300370300200b41106a200a41106a2903003703002019200a41186a2903003703002016200a41206a290300370300201f200a41286a2903003703002000200c417f6a221e41306c6a211402400240201e0d004100211e0c010b2018210c200d210a200e200b41a07f6a220b290300582011200b41086a29030022125820112012511b0d00024002400340200a4188016a200a41d8006a290300370300200a4180016a200a41d0006a290300370300200a41f8006a200a41c8006a290300370300200a41f0006a200a41c0006a290300370300200a41e8006a200a41386a290300370300200a41e0006a200a41306a290300370300200c4101460d01200a2903002112200a41086a210b200c417f6a210c200a41506a210a200e2012562011200b29030022125620112012511b0d000c020b0b4100210c0b2000200c41306c6a2114200c211e0b2014200e370300201420113703082000201e41306c6a220a41286a201a290300370300200a41206a2015290300370300200a41186a2017290300370300200a20042903003703100b201841016a2118200d41306a210d200f210c200f2001470d000b0b200441d0026a24000ba20703027f017e067f230041e0006b2203240041f7edcb00ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541d2b6c000ad4280808080a00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b0240024002400240412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2007109d081a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420066a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000bac0201037f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00410021020c010b200328021421042003200341186a280200360224200320013602202003200341206a10c4010240024020032802000d0020032802042105410121020c010b4100210220034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b0b2004450d00200110350b2000200536020420002002360200200341e0006a24000ba20703027f017e067f230041e0006b2203240041f7edcb00ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541c0b6c000ad4280808080a00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a22012003413c6a3602002003200341c8006a41086a22063602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b0240024002400240412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2202417f4c0d01200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d012002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21010c010b2007415f4b0d03200b41017422012006200120064b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2007109d081a02400240200120066b2008490d002001210b0c010b20022006490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420066a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000bf52a07047f017e047f027e017f027e057f230041c0026b22032400200341c8016a41186a4200370300200341c8016a41106a22044200370300200341c8016a41086a22054200370300200342003703c80141d1c4c700ad4280808080e00084100122062900002107200341e8016a41086a2208200641086a290000370300200320073703e8012006103520052008290300370300200320032903e8013703c80141e7c4c700ad4280808080e00084100122062900002107200341a0026a41086a2208200641086a290000370300200320073703a00220061035200420032903a0022207370300200341a8016a41086a2005290300370300200341a8016a41106a2007370300200341a8016a41186a2008290300370300200320032903c8013703a801200341086a200341a8016a412010c001024002400240024002402003280208450d00200328020c2209450d00200341c8016a41186a220a4200370300200341c8016a41106a220b4200370300200341c8016a41086a22054200370300200342003703c80141d1c4c700ad4280808080e00084100122062900002107200341e8016a41086a2208200641086a290000370300200320073703e8012006103520052008290300370300200320032903e8013703c8014188f2c700ad4280808080e00184100122062900002107200341a0026a41086a2208200641086a290000370300200320073703a00220061035200420032903a002370000200441086a2008290300370000200341a8016a41086a2005290300370300200341a8016a41106a200b290300370300200341a8016a41186a200a290300370300200320032903c8013703a8012003412036028c022003200341a8016a36028802200341a0026a200341a8016aad220c4280808080800484220d100510c2010240024020032802a00222060d00410321050c010b20032802a402210b02400240024020082802002208450d0020062d0000220e41024b0d004101210502400240200e0e03000401000b2008417f6a4104490d012006280001210a410021050c030b410221050c010b200341003602d001200342013703c801200341093602ec01200320034188026a3602e8012003200341c8016a3602f801200341246a410136020020034201370214200341c888c2003602102003200341e8016a360220200341f8016a41e88ac500200341106a10431a20033502d00142208620033502c801841006024020032802cc01450d0020032802c80110350b410321050b0b200b450d00200610350b200341003602d001200342013703c801200341c8016a41002001108a014102200520054103461b210b20032802d001210602402001450d0020032802c80120064105746a210520062001410574220841606a4105766a210e20002106034020052006290000370000200541086a200641086a290000370000200541106a200641106a290000370000200541186a200641186a290000370000200541206a2105200641206a2106200841606a22080d000b200e41016a21060b200341a8016a41086a2208200636020020034194016a200a360200200320032903c8013703a8012003200b36029001200341106a2002418001109d081a200341a0016a2008280200360200200320032903a80137039801200341c8016a41186a22064200370300200341c8016a41106a22024200370300200341c8016a41086a22054200370300200342003703c80141d1c4c700ad4280808080e00084220f1001220a2900002107200341e8016a41086a220b200a41086a290000370300200320073703e801200a10352005200b290300370300200320032903e8013703c8014198f0c700ad4280808080a0018422101001220a2900002107200341a0026a41086a220e200a41086a290000370300200320073703a002200a1035200420032903a002370000200441086a220a200e29030037000020082005290300370300200341a8016a41106a22112002290300370300200341a8016a41186a22122006290300370300200320032903c8013703a8012003200341a8016a412010c00102402003280204410020032802001b221341016a221420134f0d00200341106a21060c040b200642003703002002420037030020054200370300200342003703c801200f100122152900002107200b201541086a290000370300200320073703e801201510352005200b290300370300200320032903e8013703c80120101001220b2900002107200e200b41086a290000370300200320073703a002200b1035200420032903a002370000200a200e290300370000200820052903003703002011200229030037030020122006290300370300200320032903c8013703a801200320143602c801200d200341c8016aad4280808080c000841002200341003602d001200342013703c801024002400240200328029001220541024b0d0002400240024020050e03000102000b410110332205450d07200341013602cc01200320053602c801200541003a0000200341013602d00120032802940121020240024020032802cc012208417f6a4104490d004101210520032802c80121060c010b41012105200841017422064105200641054b1b220a4100480d0420032802c801210602402008200a460d0020062008200a10372206450d0920032802d00121050b2003200a3602cc01200320063602c8010b200620056a20023600002003200541046a3602d0010c020b410110332205450d06200341013602cc01200320053602c801200541013a0000200341013602d0010c010b410110332205450d05200341013602cc01200320053602c801200541023a0000200341013602d0010b200341106a200341c8016a1082062003280298012106200341a0016a2802002205200341c8016a107702402005450d002005410574210b0340412010332205450d0320052006290000370000200541186a220e200641186a290000370000200541106a2211200641106a290000370000200541086a2212200641086a2900003700000240024020032802cc01220a20032802d00122086b4120490d0020032802c80121020c010b200841206a22022008490d03200a41017422142002201420024b1b22144100480d0302400240200a0d00024020140d00410121020c020b2014103322020d010c090b20032802c8012102200a2014460d002002200a201410372202450d0820032802d00121080b200320143602cc01200320023602c8010b200641206a2106200220086a22022005290000370000200241186a200e290000370000200241106a2011290000370000200241086a20122900003700002003200841206a3602d00120051035200b41606a220b0d000b0b20032802cc01210220032802c801210820033502d0012107200341c8016a41186a220a4200370300200341c8016a41106a220b4200370300200341c8016a41086a22054200370300200342003703c80141d1c4c700ad4280808080e0008410012206290000210d200341e8016a41086a220e200641086a2900003703002003200d3703e801200610352005200e290300370300200320032903e8013703c80141cccfc700ad4280808080e0008410012206290000210d200341a0026a41086a220e200641086a2900003703002003200d3703a00220061035200420032903a002370000200441086a200e290300370000200341a8016a41086a2005290300370300200341a8016a41106a200b290300370300200341a8016a41186a200a290300370300200320032903c8013703a801200c428080808080048420074220862008ad84102202402002450d00200810350b2001450d0320014105742112200341a8016a41106a210441d1c4c700ad4280808080e00084210c41d2cfc700ad4280808080b00184210d0340200c100122052900002107200341e8016a41086a220e200541086a290000370300200320073703e80120051035200d100122052900002107200341a0026a41086a2211200541086a290000370300200320073703a00220051035412010332205450d0220052000290000370000200541186a200041186a290000370000200541106a200041106a290000370000200541086a200041086a2900003700002005ad4280808080800484100422062900002107200341a8016a41086a2214200641086a290000370300200320073703a801200610352003200541206a3602d401200320053602d001200320043602cc012003200341a8016a3602c80120034188026a200341c8016a107b2005103502400240024002400240024002400240200328029002220a41206a2206417f4c0d00200328028802210b0240024020060d0041002108410121050c010b200610332205450d0b200621080b024002402008410f4d0d00200821020c010b200841017422024110200241104b1b22024100480d0a024020080d00200210332205450d0f0c010b20082002460d0020052008200210372205450d0e0b200520032903e801370000200541086a200e2903003700000240024020024170714110460d00200221080c010b200241017422084120200841204b1b22084100480d0a20022008460d0020052002200810372205450d0e0b200520032903a002370010200541186a201129030037000002400240200841606a200a490d00200821020c010b200a415f4b0d0a200841017422022006200220064b1b22024100480d0a20082002460d0020052008200210372205450d0e0b200541206a200b200a109d081a0240200328028c02450d00200b10350b200341a8016a2006ad4220862005ad842207100510c2010240024020032802a801450d00200341f8016a41086a2014280200360200200320032903a8013703f8010c010b410410332206450d0b200342043702cc01200320063602c8014100200341c8016a1077200341f8016a41086a20032802d001360200200320032903c8013703f8010b20034188026a41086a200341f8016a41086a2802002206360200200320032903f80137038802024002400240024002402006450d00200341c8016a2003280288022006410110f10420032802c8014101460d0420032802cc01210b20032802d401220820032802d001220a460d0320062008200a6b6a220641046a220e417f4c0d05200e0d014100210e410121110c020b410120034188026a107702400240200328028c02220a20032802900222066b4104490d0020032802880221080c010b200641046a22082006490d0e200a410174220b2008200b20084b1b220b4100480d0e02400240200a0d000240200b0d00410121080c020b200b10332208450d140c010b2003280288022108200a200b460d002008200a200b10372208450d1320032802900221060b2003200b36028c0220032008360288020b200820066a20093600002003200641046a22063602900202400240200328028c02220a20066b4104490d0020032802880221080c010b200641046a22082006490d0e200a410174220b2008200b20084b1b220b4100480d0e02400240200a0d000240200b0d00410121080c020b200b10332208450d140c010b2003280288022108200a200b460d002008200a200b10372208450d1320032802900221060b2003200b36028c0220032008360288020b200820066a2013360000200641046a21080c090b200e10332211450d0d0b200320113602e8012003200e3602ec01200320063602f0012003200341e8016a3602c801200b200341c8016a200810f20420062008490d0320032802f001220b2006490d04200328029002220b200a490d0520032802e801210e20032802880221112003200620086b2206360298022003200b200a6b220b36029c022006200b470d06200e20086a2011200a6a2006109d081a0240024020032802ec01220a20032802f00122066b4104490d0020032802e80121080c010b200641046a22082006490d0c200a410174220b2008200b20084b1b220b4100480d0c02400240200a0d000240200b0d00410121080c020b200b10332208450d120c010b20032802e8012108200a200b460d002008200a200b10372208450d1120032802f00121060b2003200b3602ec01200320083602e8010b200820066a20093600002003200641046a22063602f0010240024020032802ec01220a20066b4104490d0020032802e80121080c010b200641046a22082006490d0c200a410174220b2008200b20084b1b220b4100480d0c02400240200a0d000240200b0d00410121080c020b200b10332208450d120c010b20032802e8012108200a200b460d002008200a200b10372208450d1120032802f00121060b2003200b3602ec01200320083602e8010b200820066a2013360000200641046a210820032802e801210620032802ec01210a200328028c02450d0820032802880210350c080b200320034188026a3602c801200b200341c8016a200a10f20402400240200328028c02220a20032802900222066b4104490d0020032802880221080c010b200641046a22082006490d0b200a410174220b2008200b20084b1b220b4100480d0b02400240200a0d000240200b0d00410121080c020b200b10332208450d110c010b2003280288022108200a200b460d002008200a200b10372208450d1020032802900221060b2003200b36028c0220032008360288020b200820066a20093600002003200641046a22063602900202400240200328028c02220a20066b4104490d0020032802880221080c010b200641046a22082006490d0b200a410174220b2008200b20084b1b220b4100480d0b02400240200a0d000240200b0d00410121080c020b200b10332208450d110c010b2003280288022108200a200b460d002008200a200b10372208450d1020032802900221060b2003200b36028c0220032008360288020b200820066a2013360000200641046a21080c060b200328028c02450d0720032802880210350c070b1044000b2008200641e88cc5001059000b2006200b41e88cc5001058000b200a200b41f88cc5001059000b200341a8016a41146a410a360200200341b4016a410c360200200341a0026a41146a4103360200200320034198026a3602b80220032003419c026a3602bc02200341c8016a41146a4100360200200342033702a402200341a0b3cc003602a0022003410c3602ac01200341b0b4cc003602d801200342013702cc01200341f4b3cc003602c8012003200341a8016a3602b0022003200341c8016a3602b8012003200341bc026a3602b0012003200341b8026a3602a801200341a0026a41b0b4cc00104c000b2003200836029002200328028c02210a20032802880221060b2006450d0020072008ad4220862006ad8410020240200a450d00200610350b02402002450d00200510350b200041206a2100201241606a22120d010c050b0b200341106a21062002450d05200510350c050b103e000b1045000b20021097060c030b200341106a1097062003419c016a28020041ffffff3f71450d0220032802980110350c020b103c000b20061097062003419c016a28020041ffffff3f71450d0020032802980110350b200341c0026a24000bd50302047f047e230041f0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022040d00200041003a00000c010b200341186a28020021052003280214210641002101200341003a006802400240034020052001460d01200341c8006a20016a200420016a2d00003a00002003200141016a22023a00682002210120024120470d000b200341206a41186a200341c8006a41186a2903002207370300200341206a41106a200341c8006a41106a2903002208370300200341206a41086a200341c8006a41086a290300220937030020032003290348220a370320200041196a2007370000200041116a2008370000200041096a20093700002000200a370001410121010c010b0240200141ff0171450d00200341003a00680b410021012003410036022820034201370320200341093602442003200341086a3602402003200341206a36026c200341dc006a41013602002003420137024c200341c888c2003602482003200341c0006a360258200341ec006a41e88ac500200341c8006a10431a200335022842208620033502208410062003280224450d00200328022010350b200020013a00002006450d00200410350b200341f0006a24000b970b06047f057e027f017e027f027e230041f0016b220324002003200236026420032001360260200341e8006a2002ad4220862001ad84100510c201024002400240200328026822040d00200041003602200c010b200328026c21052003200341f0006a280200220636029c01200320043602980141002101200341003a00e8010240024002400240034020062001460d01200341c8016a20016a200420016a22022d00003a00002003200241016a360298012003200141016a22023a00e8012002210120024120470d000b200341a8016a41086a200341c8016a41086a290300370300200341a8016a41106a200341c8016a41106a290300370300200341a8016a41186a200341c8016a41186a290300370300200320032903c8013703a8012003200620026b36029c01200341c8006a20034198016a10f6012003290348a70d02200341c8006a41106a290300210720032903502108200341306a20034198016a10f6012003290330a70d02200341306a41106a29030021092003290338210a200341286a20034198016a10c40120032802280d02200328022c2206200328029c0141186e2201200120064b1bad42187e220b422088a7450d010c050b2003410036029c01200141ff0171450d01200341003a00e8010c010b200ba72202417f4c0d03024002400240024002400240024020020d004108210c0c010b20021033220c450d010b41002101200341003602d0012003200c3602c8012003200241186e22023602cc0102400240024002402006450d0041002101200341206a210d0340200341106a20034198016a10f6012003290310a70d02200d290300210b2003290318210e200341086a20034198016a10c40120032802080d02200328020c210f0240200120032802cc01470d00200341c8016a20014101109c0120032802c801210c20032802d00121010b200c200141186c6a2202200f3602102002200b3703082002200e3703002003200141016a22013602d0012006417f6a22060d000b20032802cc0121020b200c450d08200320034198016a10c40120032802000d06200328029c01220d20032802044102742206490d062006417f4c0d0b20060d014200210b4101210f0c020b20032802cc012201450d07200141186c0d060c070b20061039220f450d01200f20032802980122102006109d081a2003200d20066b36029c012003201020066a360298012006ad210b0b200f450d030240200b2006ad42208684220b422088a722060d00200ba721060c020b0240200f2006724103710d00200ba722064103710d002006410276220d450d02200b422288a721100c030b200ba7450d03200f10350c030b1045000b4100211002402006450d00200f10350b4100210d4104210f0b41000d00200f450d00200341f8006a41186a200341a8016a41186a290300220b370300200341f8006a41106a200341a8016a41106a290300220e370300200341f8006a41086a200341a8016a41086a2903002211370300200320032903a8012212370378200041186a20093703002000200a3703102000200737030820002008370300200041346a2010360200200041306a200d3602002000412c6a200f360200200041286a2001360200200020023602242000200c360220200041386a2012370300200041c0006a2011370300200041c8006a200e370300200041d0006a200b3703000c030b2002450d01200241186c450d010b200c10350b200341003602b001200342013703a8012003410936027c2003200341e0006a3602782003200341a8016a3602a401200341dc016a4101360200200342013702cc01200341c888c2003602c8012003200341f8006a3602d801200341a4016a41e88ac500200341c8016a10431a20033502b00142208620033502a801841006024020032802ac01450d0020032802a80110350b200041003602200b2005450d00200410350b200341f0016a24000f0b1044000ba80202017f037e230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822010d00420021040c010b200328020c210202400240200341086a41086a2802004110490d00200141086a290000210520012900002106420121040c010b20034100360220200342013703182003410936022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341c888c2003602382003200341286a360248200341346a41e88ac500200341386a10431a200335022042208620033502188410060240200328021c450d00200328021810350b420021040b2002450d00200110350b2000200637030820002004370300200041106a2005370300200341d0006a24000b9f4014047f017e017f017e017f017e057f017e087f017e037f017e017f017e077f027e037f017e037f067e230041e0036b22012400200141e0026a41186a22024200370300200141e0026a41106a22034200370300200141e0026a41086a22044200370300200142003703e00241f7edcb00ad4280808080f000842205100122062900002107200141d0006a41086a2208200641086a290000370300200120073703502006103520042008290300370300200120012903503703e00241eeedcb00ad428080808090018422071001220629000021092008200641086a2900003703002001200937035020061035200320012903502209370300200141a8016a41086a220a2004290300370300200141a8016a41106a220b2009370300200141a8016a41186a220c2008290300370300200120012903e0023703a801200141e0026a200141a8016a10ac012003280200210d20012903e0022109200242003703002003420037030020044200370300200142003703e00220051001220629000021052008200641086a290000370300200120053703502006103520042008290300370300200120012903503703e00220071001220629000021052008200641086a2900003703002001200537035020061035200320012903502205370300200a2004290300370300200b2005370300200c2008290300370300200120012903e0023703a80102400240410410332208450d0020084100200d41016a20094202511b220e36000020084104410810372208450d0041002102200841003a0004200141a8016aad220f42808080808004842008ad4280808080d00084100220081035200141e0026a41186a220a4200370300200141e0026a41106a220b4200370300200141e0026a41086a22044200370300200142003703e00241f7edcb00ad4280808080f00084100122062900002105200141d0006a41086a2208200641086a290000370300200120053703502006103520042008290300370300200120012903503703e00241aeeecb00ad4280808080a001841001220629000021052008200641086a290000370300200120053703502006103520032001290350370000200341086a2008290300370000200141a8016a41086a2004290300370300200141a8016a41106a200b290300370300200141a8016a41186a200a290300370300200120012903e0023703a801200141a0026a200141a8016a10d90102400240024020012802a00222100d00200141003602900120014204370388010c010b20012902a402210520012010360288012001200537028c012005422088a722082005a72202470d010b20014188016a20024101109001200128028801211020012802900121080b201020084103746a220420003602042004200e3602002001200841016a2211360290010240024002400240200e41a1054f0d00201121120c010b024020110d004100211220014100360290010c010b200e41e07a6a2104200841ffffffff017141016a2106410021132010210802400340200828020020044f0d01200841086a21082006201341016a2213470d000b0b0240024020112013490d004100211220014100360290012013450d0120134103742114200141a0026aad4280808080c000842105200141a4026a2115200141d0006a41086a21162010210c0340200c280200210d41f7edcb00ad4280808080f00084220710012208290000210920014180026a41086a2200200841086a29000037030020012009370380022008103541d6a9c000ad4280808080b0028410012208290000210920014190026a41086a220a200841086a2900003703002001200937039002200810352001200d3602a002200120051003220829000037035020081035200120153602ec02200120163602e4022001200141a0026a3602e8022001200141d0006a3602e002200141a8016a200141e0026a107b20012802b001220b41206a2204417f4c0d0720012802a80121170240024020040d0041002106410121080c010b200410332208450d06200421060b024002402006410f4d0d00200621020c010b200641017422024110200241104b1b22024100480d05024020060d002002103322080d010c080b20062002460d0020082006200210372208450d070b2008200129038002370000200841086a20002903003700000240024020024170714110460d00200221060c010b200241017422064120200641204b1b22064100480d0520022006460d0020082002200610372208450d070b2008200129039002370010200841186a200a29030037000002400240200641606a200b490d00200621020c010b2004200b490d05200641017422022004200220044b1b22024100480d0520062002460d0020082006200210372208450d070b200841206a2017200b109d081a024020012802ac01450d00201710350b2004ad4220862008ad84100802402002450d00200810350b20071001220829000021072000200841086a29000037030020012007370380022008103541e9a9c000ad4280808080b00284100122082900002107200a200841086a2900003703002001200737039002200810352001200d3602a002200120051003220829000037035020081035200120153602ec02200120163602e4022001200141a0026a3602e8022001200141d0006a3602e002200141a8016a200141e0026a107b20012802b001220b41206a2204417f4c0d0720012802a801210d0240024020040d0041002106410121080c010b200410332208450d06200421060b024002402006410f4d0d00200621020c010b200641017422024110200241104b1b22024100480d05024020060d00200210332208450d080c010b20062002460d0020082006200210372208450d070b2008200129038002370000200841086a20002903003700000240024020024170714110460d00200221060c010b200241017422064120200641204b1b22064100480d0520022006460d0020082002200610372208450d070b2008200129039002370010200841186a200a29030037000002400240200641606a200b490d00200621020c010b200b415f4b0d05200641017422022004200220044b1b22024100480d0520062002460d0020082006200210372208450d070b200841206a200d200b109d081a024020012802ac01450d00200d10350b2004ad4220862008ad84100802402002450d00200810350b200c41086a210c201441786a22140d000c020b0b20132011104f000b201120136b2214450d0002402013450d002010201020134103746a2014410374109e081a0b200120143602900120102802042112200141e0026a41186a4200370300200141e0026a41106a22134200370300200141e0026a41086a22084200370300200142003703e00241a3edcb00ad4280808080f0008410012204290000210520014180026a41086a2206200441086a2900003703002001200537038002200410352008200629030037030020012001290380023703e00241aaedcb00ad4280808080b0018410012204290000210520014190026a41086a2206200441086a29000037030020012005370390022004103520132001290390022205370300200141a0026a41086a2008290300370300200141a0026a41106a2005370300200141a0026a41186a2006290300370300200120012903e0023703a002200141e0026a200141a0026a412010da014101210820012902e40221180240024020012802e00222044101460d00200441014621080c010b2018422088a722112012201220114b1b22172018a72200490d000240201720004d0d00200141a0026aad4280808080c000842107200141a4026a2115200141d0006a41086a211641a3edcb00ad4280808080f0008421090340200910012208290000210520014180026a41086a220c200841086a2900003703002001200537038002200810354196eaca00ad4280808080a0028410012208290000210520014190026a41086a220d200841086a290000370300200120053703900220081035200120003602a002200120071003220829000037035020081035200120153602ec02200120163602e4022001200141a0026a3602e8022001200141d0006a3602e002200141a8016a200141e0026a107b20012802b001220a41206a2204417f4c0d0720012802a801210b0240024020040d0041002106410121080c010b200410332208450d06200421060b024002402006410f4d0d00200621020c010b200641017422024110200241104b1b22024100480d05024020060d00200210332208450d080c010b20062002460d0020082006200210372208450d070b2008200129038002370000200841086a200c2903003700000240024020024170714110460d00200221060c010b200241017422064120200641204b1b22064100480d0520022006460d0020082002200610372208450d070b2008200129039002370010200841186a200d29030037000002400240200641606a200a490d00200621020c010b200a415f4b0d05200641017422022004200220044b1b22024100480d0520062002460d0020082006200210372208450d070b200841206a200b200a109d081a024020012802ac01450d00200b10350b200041016a21002004ad4220862008ad84100702402002450d00200810350b20172000470d000b0b201220114921082018428080808070832017ad8421180b200120183702ac01200120083602a8010240024020080d00200141e0026a41186a22064200370300200141e0026a41106a22024200370300200141e0026a41086a22084200370300200142003703e00241a3edcb00ad4280808080f0008410012204290000210520014180026a41086a2200200441086a2900003703002001200537038002200410352008200029030037030020012001290380023703e00241aaedcb00ad4280808080b0018410012204290000210520014190026a41086a2200200441086a2900003703002001200537039002200410352013200129039002370000201341086a2000290300370000200141a0026a41086a2008290300370300200141a0026a41106a2002290300370300200141a0026a41186a2006290300370300200120012903e0023703a002200141a0026aad428080808080048410070c010b200141e0026a41186a22064200370300200141e0026a41106a22024200370300200141e0026a41086a22084200370300200142003703e00241a3edcb00ad4280808080f0008410012204290000210520014180026a41086a2200200441086a2900003703002001200537038002200410352008200029030037030020012001290380023703e00241aaedcb00ad4280808080b0018410012204290000210520014190026a41086a2200200441086a2900003703002001200537039002200410352013200129039002370000201341086a2000290300370000200141a0026a41086a2008290300370300200141a0026a41106a2002290300370300200141a0026a41186a2006290300370300200120012903e0023703a002200141203602e4022001200141a0026a3602e002200141a8016a410472200141e0026a10db010b201421120b200128028c012115200141e0026a41186a22024200370300200141e0026a41106a22004200370300200141e0026a41086a22044200370300200142003703e00241f7edcb00ad4280808080f00084100122062900002105200141d0006a41086a2208200641086a290000370300200120053703502006103520042008290300370300200120012903503703e00241aeeecb00ad4280808080a001841001220629000021052008200641086a290000370300200120053703502006103520032001290350370000200341086a2008290300370000200141a8016a41086a2004290300370300200141a8016a41106a2000290300370300200141a8016a41186a2002290300370300200120012903e0023703a8010240024020100d00200f428080808080048410070c010b20124103744104722208417f4c0d04200810332204450d02200141003602e802200120083602e402200120043602e0022012200141e0026a10770240024020120d0020012802e802210820012802e00221020c010b201020124103746a2114410020012802e802220b6b210020012802e4022104410021080340200b20086a210a201020086a220c280200210d02400240200420006a4104490d0020012802e0022102200421060c010b200a41046a2206200a490d04200441017422022006200220064b1b22064100480d040240024020040d00024020060d00410121020c020b200610332202450d080c010b20012802e002210220042006460d0020022004200610372202450d070b200120063602e402200120023602e0020b2002200b6a20086a200d3600002001200a41046a22043602e802200c41046a280200210d02400240200620006a417c6a41034d0d00200621040c010b200441046a22172004490d04200641017422042017200420174b1b22044100480d040240024020060d00024020040d00410121020c020b200410332202450d080c010b20062004460d0020022006200410372202450d070b200120043602e402200120023602e0020b2002200b6a20086a41046a200d3600002001200a41086a3602e802200041786a2100200841086a2108200c41086a2014470d000b200b20086a21080b20012802e4022104200f42808080808004842008ad4220862002ad84100202402004450d00200210350b201541ffffffff0171450d00201010350b200141e0026a41186a22194200370300200141e0026a41106a221a4200370300200141e0026a41086a221b4200370300200142003703e00241f7edcb00ad4280808080f00084221c100122082900002105200141d0006a41086a221d200841086a2900003703002001200537035020081035201b201d290300370300200120012903503703e00241b8eecb00ad4280808080e00284221e100122082900002105201d200841086a290000370300200120053703502008103520032001290350370000200341086a221f201d290300370000200141a8016a41086a2220201b290300370300200141a8016a41106a2221201a290300370300200141a8016a41186a22222019290300370300200120012903e0023703a801200141c8006a200141a8016a412010c001200128024c21230240200128024822244101470d00024020234100200e41d87e6a22082008200e4b1b22254f0d00200141e0026aad42808080808002842126200141a0026aad42808080808004842127200141e0026a41106a210a200141e0016a2128200141a8016a41246a2100200141e0026a41286a2114202321290340200141a8016a202910dc01200141e0026a20012802a801220820012802b001220410dd010240024020012802e002222a0d004200212b4108212a0c010b2004ad4220862008ad84100720012902e402212b0b024020012802ac01450d00200810350b202a202b422088a7220841d8006c6a2117202a210202402008450d000340200141a8016a41186a2208200241186a290300370300200141a8016a41106a2204200241106a290300370300200141a8016a41086a2206200241086a2903003703002002280220210c20022903002105200141e0026a41206a2210200241c4006a2902003703002014200241cc006a290200370300200141e0026a41306a2215200241d4006a280200360200200141e0026a41086a220b2002412c6a290200370300200a200241346a290200370300200141e0026a41186a220d2002413c6a290200370300200120053703a8012001200241246a2902003703e002200241d8006a2102200c450d0120014188016a41186a2216200829030037030020014188016a41106a2213200429030037030020014188016a41086a220e2006290300370300200141d0006a41086a2212200b290300370300200141d0006a41106a2211200a290300370300200141d0006a41186a222c200d290300370300200141d0006a41206a222d2010290300370300200141d0006a41286a22102014290300370300200141d0006a41306a222e2015280200360200200120012903a80137038801200120012903e00237035020082016290300370300200420132903003703002006200e29030037030020002001290350370200200041086a2012290300370200200041106a2011290300370200200041186a202c290300370200200041206a202d290300370200200041286a2010290300370200200041306a202e28020036020020012001290388013703a8012001200c3602c801200142003703c802200142003703c002200120082903003703d802200120042903003703d002202820012903a8012006290300200141d0026a200141c0026a10de01024020012802d0012208450d00200841306c2104200c210803402008200841206a290300200841286a290300200141d0026a200141c0026a10de01200841306a2108200441506a22040d000b0b200141c0026a41086a290300212f20012903c002213020012802d4012110024002400240024020012903d0022207200141d0026a41086a290300220584500d0020012802dc012208450d00200141386a203020072030200754202f200554202f2005511b22041b2231202f200520041b22322008ad420010980820084105742104200141386a41086a29030021092001290338213320312105203221072010210803402008203320052005203356200720095620072009511b22061b22182009200720061b223410df01200720347d2005201854ad7d2107200520187d2105200841206a2108200441606a22040d000b427f203020317d220920057c220520052009542208202f20327d2030203154ad7d220520077c2008ad7c220720055420072005511b22081b2205427f200720081b2207844200520d01200d4200370300200a4200370300200b4200370300200142003703e00241b6fdc600ad4280808080800184220510012204290000210720014180026a41086a2208200441086a290000370300200120073703800220041035200b200829030037030020012001290380023703e00241e489c200ad4280808080d00184220710012206290000210920014190026a41086a2204200641086a290000370300200120093703900220061035200a200129039002370000200a41086a22162004290300370000200141a0026a41086a2213200b290300370300200141a0026a41106a220e200a290300370300200141a0026a41186a2212200d290300370300200120012903e0023703a002200141206a200141a0026a412010d701200141206a41106a29030021092001290328211820012802202106200d4200370300200a4200370300200b4200370300200142003703e00220051001221529000021052008201541086a290000370300200120053703800220151035200b200829030037030020012001290380023703e00220071001220829000021052004200841086a290000370300200120053703900220081035200a200129039002370000201620042903003700002013200b290300370300200e200a2903003703002012200d290300370300200120012903e0023703a00220012009420020061b3703e80220012018420020061b3703e0022027202610020c030b2030202f844200520d01200d4200370300200a4200370300200b4200370300200142003703e00241b6fdc600ad4280808080800184220510012204290000210720014180026a41086a2208200441086a290000370300200120073703800220041035200b200829030037030020012001290380023703e00241e489c200ad4280808080d00184220710012206290000210920014190026a41086a2204200641086a290000370300200120093703900220061035200a200129039002370000200a41086a22162004290300370000200141a0026a41086a2213200b290300370300200141a0026a41106a220e200a290300370300200141a0026a41186a2212200d290300370300200120012903e0023703a002200141086a200141a0026a412010d701200141086a41106a29030021092001290310211820012802082106200d4200370300200a4200370300200b4200370300200142003703e00220051001221529000021052008201541086a290000370300200120053703800220151035200b200829030037030020012001290380023703e00220071001220829000021052004200841086a290000370300200120053703900220081035200a200129039002370000201620042903003700002013200b290300370300200e200a2903003703002012200d290300370300200120012903e0023703a00220012009420020061b3703e80220012018420020061b3703e0022027202610020c020b200142f0f2bda1a7ee9cb9f9003703a002200141e0026a200141a0026a10e001200141e0026a2005200710df01200d2007370300200120053703f002200141063a00e8022001410c3a00e00241b0b4cc004100200141e0026a10d4010c010b200142f0f2bda1a7ee9cb9f9003703a002200141e0026a200141a0026a10e001200141e0026a2030202f10df01200d202f370300200120303703f002200141063a00e8022001410c3a00e00241b0b4cc004100200141e0026a10d4010b024020012802cc012208450d00200841306c450d00200c10350b024020012802d80141ffffff3f71450d00201010350b20022017470d000b201721020b202ba72104024020172002460d0003400240200241246a2802002208450d00200841306c450d00200241206a28020010350b200241d8006a21080240200241306a28020041ffffff3f71450d002002412c6a28020010350b2008210220172008470d000b0b202941016a212902402004450d00200441d8006c450d00202a10350b20292025470d000b0b20232025202320254b1b21230b20194200370300201a4200370300201b4200370300200142003703e002201c100122082900002105201d200841086a2900003703002001200537035020081035201b201d290300370300200120012903503703e002201e100122082900002105201d200841086a290000370300200120053703502008103520032001290350370000201f201d2903003700002020201b2903003703002021201a29030037030020222019290300370300200120012903e0023703a8010240024020240d00200f428080808080048410070c010b200120233602e002200f4280808080800484200141e0026aad4280808080c0008410020b200141e0036a24000f0b103e000b1045000b103c000b1044000bed0401097f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c2010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c4010240024020022802000d0020022802042205200228022422064103762201200120054b1b22014103742207417f4c0d030240024020010d00410421080c010b200710332208450d050b200241003602502002200136024c200220083602480240024002402005450d004100210103402002410036022820064104490d0320022002280220220741046a36022020072800002109200241003602282006417c6a4104490d022002200741086a3602202007280004210702402001200228024c470d00200241c8006a2001410110900120022802482108200228025021010b200641786a2106200820014103746a220a2007360204200a20093602002002200141016a22013602502005417f6a22050d000b200220063602240b2008450d022000200229024c370204200020083602000c030b2006417c6a21060b20022006360224200228024c41ffffffff0171450d00200810350b20024100360230200242013703282002410936023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b200041003602000b2004450d00200310350b200241e0006a24000f0b1044000b1045000bbb0201037f230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822010d00200041003602000c010b200341106a2802002102200328020c2104200341003602380240024020024104490d0020012800002105200341003602382002417c714104460d00200041086a200128000436020020002005360204410121020c010b20034100360220200342013703182003410936022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341c888c2003602382003200341286a360248200341346a41e88ac500200341386a10431a200335022042208620033502188410060240200328021c450d00200328021810350b410021020b200020023602002004450d00200110350b200341d0006a24000b3c01017f02404108103322020d001045000b200220002802003600002002200028020436000420012902002002ad42808080808001841002200210350bfc0403027f017e057f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541efb6c000ad4280808080800284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000b800b06057f017e077f017e037f037e230041e0016b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c2010240024002400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360224200320043602202003200341206a10c40102400240024020032802000d00200328020422062003280224220741d8006e2201200120064b1bad42d8007e2208422088a70d042008a72201417f4c0d040240024020010d00410821090c010b200110332209450d060b4100210a20034100360230200320093602282003200141d8006e36022c02402006450d004100210b034041002101200341003a00d801200b41016a210b02400240024002400240034020072001460d01200341b8016a20016a2003280220220c2d00003a00002003200c41016a3602202003200141016a22023a00d8012002210120024120470d000b20034198016a41086a220d200341b8016a41086a29030037030020034198016a41106a220e200341b8016a41106a29030037030020034198016a41186a220f200341b8016a41186a290300370300200320032903b801370398012003200720026b220136022420014110490d032003200c41116a3602202003200141706a360224200c41096a2900002108200c2900012110200341b8016a200341206a10aa0220032802b801220c450d0320032802c001211120032802bc012102200341b8016a200341206a10c30120032802b80122070d012002450d03200241306c0d020c030b20034100360224200141ff0171450d02200341003a00d8010c020b20032802bc01211220032802242201410f4b0d020240201241ffffff3f71450d00200710350b2002450d01200241306c450d010b200c10350b200341d8006a41086a200341f8006a41086a2903003703000240200a450d00200a41d8006c2102200941306a210103400240200141746a280200220c450d00200c41306c450d00200141706a28020010350b0240200128020041ffffff3f71450d002001417c6a28020010350b200141d8006a2101200241a87f6a22020d000b0b200328022c2201450d03200141d8006c450d03200910350c030b20032802c0012113200341d8006a41086a200d2903002214370300200341d8006a41106a200e2903002215370300200341d8006a41186a200f2903002216370300200341386a41186a220d2016370300200341386a41106a220e2015370300200341386a41086a220f20143703002003200141706a36022420032003280220220141106a3602202003200329039801221437035820032014370338200141086a2900002114200129000021150240200a200328022c470d00200341286a200a4101109b01200328022821092003280230210a0b2009200a41d8006c6a2201201537031020012008370308200120103703002001200c360220200141186a2014370300200141346a2013360200200141306a20123602002001412c6a2007360200200141286a2011360200200141246a2002360200200141386a2003290338370200200141c0006a200f290300370200200141c8006a200e290300370200200141d0006a200d2903003702002003200a41016a220a360230200b2006460d01200328022421070c000b0b20090d010b200341003602a00120034201370398012003410936027c2003200341086a360278200320034198016a360258200341cc016a4101360200200342013702bc01200341c888c2003602b8012003200341f8006a3602c801200341d8006a41e88ac500200341b8016a10431a20033502a0014220862003350298018410060240200328029c01450d0020032802980110350b200041003602000c010b2000200329022c370204200020093602000b2005450d00200410350b200341e0016a24000f0b1044000b1045000b8d22020f7f137e23004190066b22052400200541386a200010b401200541e0046a20052802382206200528024010d501200541e0036a41086a2207200541e9046a290000370300200541e0036a41106a2208200541f1046a290000370300200541e0036a41186a2209200541f9046a290000370300200520052900e1043703e0034100210a024020052d00e0044101470d00200541e0026a41186a2009290300370300200541e0026a41106a2008290300370300200541e0026a41086a2007290300370300200520052903e0033703e0024101210a0b0240200528023c450d00200610350b02400240200a450d00200541186a41186a200541e0026a41186a2206290300370300200541186a41106a200541e0026a41106a2207290300370300200541186a41086a200541e0026a41086a2208290300370300200520052903e002370318200541f0016a200541186a10b701200541e0046a20052802f001220920052802f80110d601200541a0016a41086a220b200541e0046a41086a290300370300200541a0016a41106a220c200541e0046a41106a290300370300200541a0016a41186a220d200541e0046a41186a290300370300200541e0036a41086a220e2005418c056a290200370300200541e0036a41106a220f20054194056a290200370300200541e0036a41186a22102005419c056a290200370300200541e0036a41206a2211200541a4056a290200370300200541e0036a41286a2212200541ac056a290200370300200541e0036a41306a2213200541b4056a280200360200200520052903e0043703a00120052005290284053703e0030240200528028005220a450d00200541a8026a41186a200d290300370300200541a8026a41106a200c290300370300200541a8026a41086a200b2903003703002008200e2903003703002007200f29030037030020062010290300370300200541e0026a41206a2011290300370300200541e0026a41286a2012290300370300200541e0026a41306a2013280200360200200520052903a0013703a802200520052903e0033703e0020b024020052802f401450d00200910350b200a450d00200541dc006a20052903e002370200200541386a41186a2206200541a8026a41186a290300370300200541386a41106a2207200541a8026a41106a290300370300200541386a41086a2208200541a8026a41086a290300370300200541e4006a200541e0026a41086a290300370200200541ec006a200541e0026a41106a290300370200200541f4006a200541e0026a41186a290300370200200541fc006a20054180036a29030037020020054184016a200541e0026a41286a2903003702002005418c016a20054190036a280200360200200520052903a8023703382005200a36025820082903002114200529033821150240024020072903002216200120162001542006290300221720025420172002511b22071b22182017200220071b22198450450d002015211a2014211b0c010b2006201720197d2016201854ad7d221c3703002005201620187d221a37034802400240201a428080e983b1de1656201c420052201c501b450d0020182116201921170c010b200541d0006a420037030020054200370348201c20027c201a20017c2201201a54ad7c21020b20054200201420177d2015201654ad7d2218201520167d221c201556201820145620182014511b22061b221b37034020054200201c20061b221a370338200220177d2001201654ad7d2102200120167d21010b02400240200541386a41286a28020022060d004100210a410021060c010b200641186c21084100210603400240200a2903002216200120012016562002200a41086a220929030022175620022017511b22071b22182017200220071b221984500d00200a201620187d221a370300200a201720197d2016201854ad7d221c37030802400240201a428080e983b1de1656201c420052201c501b450d002001211c20182116201921170c010b200a4200370308200a42003703002002201c7c2001201a7c221c200154ad7c21020b200541386a41086a220742002007290300220120177d20052903382218201654ad7d2219201820167d221a201856201920015620192001511b22071b221b37030020054200201a20071b221a370338200220177d201c201654ad7d2102201c20167d210120092903002117200a29030021160b024020162017844200520d00200a41186a210a200641016a2106200841686a22080d010b0b2005280260220a2006490d020b200541003602600240200a20066b220a450d0002402006450d00200528025822072007200641186c6a200a41186c109e081a0b2005200a3602600b024042002015201a7d221620162015562014201b7d2015201a54ad7d221620145620162014511b220a1b220242002016200a1b220184500d0020054190016a2000108e02200541a0016a20052802900122062005280298012208108f0220052903a001211b200542003703a001200541e8016a280200210920052d00ec01210b02400240201b4201510d004200211c200541f0016a41306a4200370300200541f0016a41286a4200370300200541f0016a41206a4200370300200541f0016a41186a420037030020054180026a4200370300200541f8016a4200370300200542003703f0014200211942002117420021164200211d0c010b200541d8016a2903002118200541a0016a41306a290300211a200541a0016a41206a2903002119200541a0016a41186a290300211c200541e0016a290300211d20052903b001211620052903a8012117200541f0016a41206a200541a0016a41286a290300370300200541f0016a41286a201a370300200541f0016a41306a201837030020054180026a201c3703002005201937038802200520173703f001200520163703f8010b20052017200220172017200256201620015620162001511b220a1b221a7d22143703f0012005201620012016200a1b221e7d2017201a54ad7d22183703f801201620197c211f2017201c7c2220201754220cad2121200541f0016a41106a210a024002402002201a7d22152001201e7d2002201a54ad7d22228450450d004200211c420021222002211e200121230c010b20054188026a201920222019201c201556201920225620192022511b22071b22237d201c2015201c20071b221754ad7d3703002005201c20177d37038002202220237d2015201754ad7d21222023201e7c2017201a7c221e201754ad7c2123201520177d211c0b201f20217c2117200541a8026a41186a200a41086a2903002219370300200541a8026a41206a2207200a41106a290300370300200541d0026a220d200a41186a290300370300200541d8026a220e200a41206a2903003703002005200a290300221a3703b802200520143703a802200520183703b00202400240427f2014201a7c221a201a201454220a201820197c200aad7c221920185420192018511b220a1b221a428080e983b1de16544100427f2019200a1b2215501b0d00200541b8026a290300211a200e2903002115200d290300211f2007290300212120052903b002212420052903a80221254201211920052903c00221260c010b02400240201a20158450450d00420021190c010b42002119200541e0046a41186a220f4200370300200541e0046a41106a220d4200370300200541e0046a41086a22074200370300200542003703e00441b6fdc600ad4280808080800184221f1001220e290000212120054180066a41086a220a200e41086a2900003703002005202137038006200e10352007200a29030037030020052005290380063703e00441e489c200ad4280808080d0018422211001220e2900002124200a200e41086a2900003703002005202437038006200e1035200d2005290380062224370300200541e0056a41086a22102007290300370300200541e0056a41106a22112024370300200541e0056a41186a2212200a290300370300200520052903e0043703e0052005200541e0056a412010d701200541106a2903002124200529030821252005280200210e200f4200370300200d420037030020074200370300200542003703e004201f1001220f290000211f200a200f41086a2900003703002005201f37038006200f10352007200a29030037030020052005290380063703e00420211001220f290000211f200a200f41086a2900003703002005201f37038006200f1035200d200529038006221f370300201020072903003703002011201f3703002012200a290300370300200520052903e0043703e0052005420020244200200e1b221f20157d20254200200e1b2221201a54ad7d22242021201a7d22252021562024201f562024201f511b220a1b3703e804200542002025200a1b3703e004200541e0056aad4280808080800484200541e0046aad4280808080800284100220054198056a201537030020054190056a201a370300200741013a0000200541e9046a2000290000370000200541f1046a200041086a290000370000200541f9046a200041106a29000037000020054181056a200041186a290000370000200541033a00e00441b0b4cc004100200541e0046a10d4010b0b2017201651210a20172016542107200541c8016a2021370300200541d0016a201f370300200541b0016a2024370300200541d8016a2015370300200541b8016a201a370300200520263703c0012005201d3703e001200520253703a8012005200b4100201b420151220d1b3a00ec01200520094100200d1b3602e801200520194201512209ad3703a0010240024020090d002008ad4220862006ad8410070c010b200520083602e404200520063602e004200541a8016a200541e0046a10e7020b200c2007200a1b210a0240200528029401450d00200610350b427f2017200a1b2116427f2020200a1b21172019420152210a024002400240201b4201510d00200a0d0041032106200541e0036a210a0c010b201b420152200a410173720d0141042106200541e0026a210a0b200a41086a20063a0000200a41003a0000200a41096a2000290000370000200a41116a200041086a290000370000200a41196a200041106a290000370000200a41216a200041186a29000037000041b0b4cc004100200a10d4010b024020172016844200520d0020054198056a201837030020054190056a2014370300200541e0046a41086a41003a0000200541e9046a2000290000370000200541f1046a200041086a290000370000200541f9046a200041106a29000037000020054181056a200041186a290000370000200541033a00e00441b0b4cc004100200541e0046a10d4010b2004427f20042903002216201e7c22172017201654220a200441086a2206290300221620237c200aad7c221720165420172016511b220a1b3703002006427f2017200a1b3703000240201c202284500d002003420020032903002216201c7d22172017201656200341086a220a290300221720227d2016201c54ad7d221620175620162017511b22061b370300200a4200201620061b3703000b200542f3e885db96cddbb3203703e002200541e0026a200541386a41386a2005290338200541386a41086a290300411f109002200541e0046a200541186a10b70120052802e004210a200520052802e8043602e4032005200a3602e003200541386a200541e0036a10e101024020052802e404450d00200a10350b200541e0046a41386a200137030020054190056a2002370300200541e0046a41086a41023a0000200541e9046a2000290000370000200541f1046a200041086a290000370000200541f9046a200041106a29000037000020054181056a200041186a290000370000200541043a00e00441b0b4cc004100200541e0046a10d4010b0240200528025c220a450d00200a41186c450d00200528025810350b200541e8006a28020041ffffffff0371450d00200528026410350b20054190066a24000f0b2006200a104f000bbf0908017f037e037f017e017f017e047f037e230041e0016b22032400200320023703582003200137035002400240200120028450450d0042002104420021050c010b2003200036021c200341206a2000200341d0006a2003411c6a10b002024020032903204201520d00200341306a2903002105200329032821040c010b200341c8006a2903002105200341c0006a290300210420032903284201520d00200341206a41106a290300210620034198016a200341206a41186a29030037030020034190016a2006370300200341e0006a41086a41003a0000200341e9006a2000290000370000200341f1006a200041086a290000370000200341f9006a200041106a29000037000020034181016a200041186a290000370000200341033a006041b0b4cc004100200341e0006a10d4010b200341e0006a41186a22074200370300200341e0006a41106a22084200370300200341e0006a41086a220942003703002003420037036041b6fdc600ad4280808080800184220a1001220b2900002106200341d0006a41086a2200200b41086a29000037030020032006370350200b1035200920002903003703002003200329035037036041e489c200ad4280808080d00184220c1001220b29000021062000200b41086a29000037030020032006370350200b1035200820032903502206370300200341206a41086a220d2009290300370300200341206a41106a220e2006370300200341206a41186a220f2000290300370300200320032903603703202003200341206a412010d701200220057d2001200454ad7d200520027d2004200154ad7d200420015820052002582005200251220b1b22101b2111200120047d200420017d20101b2112200341106a2903004200200328020022101b21062003290308420020101b21130240024020042001562005200256200b1b0d0020074200370300200842003703002009420037030020034200370360200a1001220b29000021012000200b41086a29000037030020032001370350200b10352009200029030037030020032003290350370360200c1001220b29000021012000200b41086a29000037030020032001370350200b103520082003290350370000200841086a2000290300370000200d2009290300370300200e2008290300370300200f20072903003703002003200329036037032020034200200620117d2013201254ad7d2201201320127d2202201356200120065620012006511b22001b37036820034200200220001b370360200341e0006a21000c010b20074200370300200842003703002009420037030020034200370360200a1001220b29000021012000200b41086a29000037030020032001370350200b10352009200029030037030020032003290350370360200c1001220b29000021012000200b41086a29000037030020032001370350200b103520082003290350370000200841086a2000290300370000200d2009290300370300200e2008290300370300200f2007290300370300200320032903603703202003427f200620117c201320127c22022013542200ad7c22012000200120065420012006511b22001b3703682003427f200220001b370360200341e0006a21000b200341206aad42808080808004842000ad42808080808002841002200341e0016a24000bdd0201067f230041d0006b22022400024002400240410410332203450d00200341edde91e306360000410c210420034104410c10372205450d0120052001290000370004200241003a004820052101410021060340200241003a0008200241086a200120044100472203109d081a024020040d00200241003a00080b20042003490d03200241286a20066a20022d00083a00002002200641016a22073a0048200420036b2104200120036a21012007210620074120470d000b200241086a41186a2204200241286a41186a290300370300200241086a41106a2203200241286a41106a290300370300200241086a41086a2201200241286a41086a2903003703002002200229032837030820051035200041186a2004290300370000200041106a2003290300370000200041086a200129030037000020002002290308370000200241d0006a24000f0b1045000b103c000b2003200441b89dcc001059000bd80301067f230041106b2202240020024100360208200242013703000240412010332203450d0020032000290038370000200341086a200041c0006a290000370000200341106a200041c8006a290000370000200341186a200041d0006a29000037000020022003360200200242a080808080043702042002200036020c2002410c6a200210cf012002200041106a36020c2002410c6a200210cf0120002802202103200041286a28020022042002107702402004450d002003200441186c6a210403402002200336020c2002410c6a200210cf01200341106a200210e2012004200341186a2203470d000b0b200028022c2105200041346a28020022032002107702400240024020022802042206200228020822046b20034102742200490d0020022802002103200621070c010b200420006a22032004490d01200641017422072003200720034b1b22074100480d010240024020060d00024020070d00410121030c020b2007103322030d010c040b2002280200210320062007460d0020032006200710372203450d030b20022007360204200220033602000b200320046a20052000109d081a2001290200200420006aad4220862003ad84100202402007450d00200310350b200241106a24000f0b103e000b103c000bb30101027f230041106b2202240002400240024002402000280200220341c000490d00200341808001490d012003418080808004490d02200241033a00032001200241036a41011078200220002802003602042001200241046a410410780c030b200220034102743a00032001200241036a410110780c020b200220034102744101723b010a20012002410a6a410210780c010b2002200341027441027236020c20012002410c6a410410780b200241106a24000b13002000411836020420004180b7c0003602000bab0407047f017e017f017e017f017e037f230041d0006b22002400200041206a41186a22014200370300200041206a41106a22024200370300200041206a41086a220342003703002000420037032041f7edcb00ad4280808080f000842204100122052900002106200041c0006a41086a2207200541086a290000370300200020063703402005103520032007290300370300200020002903403703204193eecb00ad428080808080018422081001220529000021062007200541086a2900003703002000200637034020051035200220002903402206370300200041086a22092003290300370300200041106a220a2006370300200041186a220b2007290300370300200020002903203703000240024002404100200010e5012205200541ff01714104461b41ff0171417f6a220541024b0d0020050e03010001010b2001420037030020024200370300200342003703002000420037032020041001220529000021062007200541086a2900003703002000200637034020051035200320072903003703002000200029034037032020081001220529000021062007200541086a290000370300200020063703402005103520022000290340370000200241086a200729030037000020092003290300370300200a2002290300370300200b200129030037030020002000290320370300410110332207450d01200741013a00002000ad42808080808004842007ad428080808010841002200710350b200041d0006a24000f0b103c000b810201037f230041d0006b220124002001412036020420012000360200200141086a2000ad4280808080800484100510c20102400240200128020822020d00410421000c010b200128020c210302400240200141106a280200450d0020022d000022004104490d010b20014100360220200142013703182001410936022c200120013602282001200141186a360234200141cc006a41013602002001420137023c200141c888c2003602382001200141286a360248200141346a41e88ac500200141386a10431a200135022042208620013502188410060240200128021c450d00200128021810350b410421000b2003450d00200210350b200141d0006a240020000b3400200041f7edcb0036020420004100360200200041146a4124360200200041106a41bcaac100360200200041086a42073702000b2b01017f02404101103322020d00103c000b200042818080801037020420002002360200200241023a00000b2b01017f02404101103322020d00103c000b200042818080801037020420002002360200200241003a00000b5301017f0240411010332202450d00200242003700082002420037000020024110412010372202450d0020024200370010200042a0808080800437020420002002360200200241186a42003700000f0b103c000b940302047f017e230041206b2203240002400240200241d8006c4104722204417f4c0d00200410332205450d0120034100360208200320043602042003200536020020022003107702402002450d002001200241d8006c6a210603402003200141386a41201078200129030021072003200141086a290300370318200320073703102003200341106a4110107820012802202102200128022822042003107702402004450d002002200441306c6a210403402003200241201078200241206a29030021072003200241286a290300370318200320073703102003200341106a411010782004200241306a2202470d000b0b200141d8006a2105200128022c2102200141346a28020022042003107702402004450d002004410574210403402003200241201078200241206a2102200441606a22040d000b0b200129031021072003200141186a290300370318200320073703102003200341106a411010782005210120052006470d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1044000b1045000b3301017f02404110103322020d001045000b2002420037000820024200370000200042908080808002370204200020023602000b860101027f230041206b220224002002410c6a410036020020024200370300200241003602182002420137031002404104103322030d00103c000b200341003600002002200336021020024284808080c00037021420024104722203200241106a10b001200041086a200228021836020020002002290310370200200310b101200241206a24000be90101047f230041106b220224002002410036020c02400240410110332203450d000240024002400240200228020c220441c000490d00200441808001490d012004418080808004490d02200341033a0000200228020c21044105210520034101410510372203450d05200320043600010c030b200320044102743a0000410121050c020b4102210520034101410210372203450d03200320044102744101723b00000c010b4104210520034101410410372203450d02200320044102744102723600000b200020053602082000200536020420002003360200200241106a24000f0b1045000b103c000bf60301087f230041c0006b22022400200241186a4200370300200241106a22034200370300200241086a4200370300200241286a22044100360200200242003703002002420837032020024100360238200242013703302002200236023c2002413c6a200241306a10cf012002200336023c2002413c6a200241306a10cf012002280220210320042802002204200241306a10770240024002402004450d00200441306c210503400240024020022802342206200228023822046b4120490d00200441206a2107200228023021080c010b200441206a22072004490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009103322080d010c060b2002280230210820062009460d0020082006200910372208450d050b20022009360234200220083602300b200820046a2204200341106a290000370000200441186a200341286a290000370000200441106a200341206a290000370000200441086a200341186a290000370000200220073602382002200336023c2002413c6a200241306a10cf01200341306a2103200541506a22050d000b0b20002002290330370200200041086a200241306a41086a280200360200024020022802242203450d00200341306c450d00200228022010350b200241c0006a24000f0b103e000b103c000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241043600000b2d01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241d4003600000b820b06057f017e017f017e047f0a7e23004190016b22022400200241386a41186a2203420037030041102104200241386a41106a22054200370300200241386a41086a220642003703002002420037033841f7edcb00ad4280808080f000842207100122082900002109200241d8006a41086a220a200841086a29000037030020022009370358200810352006200a2903003703002002200229035837033841b6aac000ad4280808080900284100122082900002109200a200841086a2900003703002002200937035820081035200520022903582209370300200241186a41086a220b2006290300370300200241186a41106a2009370300200241186a41186a220c200a29030037030020022002290338370318200241106a200241186a10f20102402002280210417d71450d002003420037030041102104200241386a41106a220d420037030020064200370300200242003703382007100122082900002109200a200841086a29000037030020022009370358200810352006200a2903003703002002200229035837033841e4edcb00ad4280808080a00184100122082900002109200a200841086a290000370300200220093703582008103520052002290358370000200541086a200a290300370000200b2006290300370300200241186a41106a200d290300370300200c200329030037030020022002290338370318200241086a200241186a412010c001024020022802084101470d00200228020c2001470d010b42002109200241386a41186a22044200370300200241386a41106a22034200370300200241386a41086a220642003703002002420037033841f7edcb00ad4280808080f00084100122082900002107200241d8006a41086a220a200841086a29000037030020022007370358200810352006200a2903003703002002200229035837033841ceeecb00ad4280808080b00184100122082900002107200a200841086a290000370300200220073703582008103520052002290358370000200541086a200a290300370000200241186a41086a2006290300370300200241186a41106a2003290300370300200241186a41186a2004290300370300200220022903383703182002412036026c2002200241186a360268200241f0006a200241186aad4280808080800484100510c201024002402002280270220a0d000c010b20022802742106024002400240200241f0006a41086a28020022054110490d00200541707122054110460d0020054120470d010b200241003602602002420137035820024109360284012002200241e8006a360280012002200241d8006a36028c01200241cc006a41013602002002420137023c200241c888c200360238200220024180016a3602482002418c016a41e88ac500200241386a10431a200235026042208620023502588410060240200228025c450d00200228025810350b420021090c010b200a41086a290000210e200a290000210f200a41286a2900002107200a41186a2900002110200a2900202111200a2900102112420121090b2006450d00200a10350b0240024002402009500d00200041286a2903002109200041186a2903002113200041086a290300211420002903202115200029031021162000290300211741031033220a450d01200a417f20152011852009200785844200522015201154200920075420092007511b22081b3a0002200a417f20162012852013201085844200522016201254201320105420132010511b1b22053a0001200a417f2017200f852014200e85844200522017200f542014200e542014200e511b1b22063a0000200641014b0d020240024020060e020001000b200541014b0d03024020050e020001000b200a1035411121042008450d040c010b200a10350b411d21040c020b103c000b200a1035411121040b20024190016a240020040bb40201067f230041d0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822030d00410221010c010b200228020c210402400240200241106a2802002205450d0020032d0000220641014b0d0041002101024020060e020200020b2005417f6a4104490d0020032800012107410121010c010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b410221010b2004450d00200310350b2000200736020420002001360200200241d0006a24000b130020004102360204200041f0f0c1003602000b2d01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241a0053600000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241063600000bde0506067f017e017f017e017f017e230041206b220224000240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200024002400240200541037122074103460d0002400240024020070e03000102000b2005410276ad21080c040b410121072006450d0220042d0001210620012003417e6a3602042001200441026a3602002006410874200572220141ffff0371418002490d02200141fcff0371410276ad21080c030b4101210720064103490d01200441036a2d0000210620042f0001210920012003417c6a3602042001200441046a3602002009200641107472410874200572220141808004490d012001410276ad21080c020b024020054102762209410c4b0d0002400240024020090e0d00030303010303030303030302000b20064104490d052004350001210820012003417b6a3602042001200441056a36020020084280808080045421074200210a0c060b20064108490d04200429000121082001200341776a3602042001200441096a3602002008428080808080808080015421074200210a0c050b20064110490d03200441096a290000210a2004290001210820012003416f6a3602042001200441116a360200200a428080808080808080015421070c040b200941046a220641104b0d022003417e6a2103200441026a21044100210541012107200241186a210b420021084200210a03402003417f460d01200241106a2004417f6a3100004200200541037441f8007110a30820012003360204200120043602002003417f6a2103200441016a2104200b290300200a84210a20022903102008842108200541016a220541ff01712006490d000b2002427f427f41e80020094103746b41f8007110a4082008200229030058200a200241086a290300220c58200a200c511b21070c030b0c020b4200210a410021070c010b410121070b20002008370308200041106a200a37030020002007ad370300200241206a24000bd53901037f230041106b2202240020002802002103200028020822042001107702402004450d00200320044103746a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a41021078200341086a22032004470d000b0b200028020c2103200041146a28020022042001107702402004450d0020032004410c6c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a410210782003410c6a22032004470d000b0b20002802182103200041206a28020022042001107702402004450d00200320044104746a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a41021078200341106a22032004470d000b0b200028022421032000412c6a28020022042001107702402004450d002003200441146c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a41021078200341146a22032004470d000b0b20002802302103200041386a28020022042001107702402004450d002003200441186c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a41021078200341186a22032004470d000b0b200028023c2103200041c4006a28020022042001107702402004450d0020032004411c6c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a410210782003411c6a22032004470d000b0b20002802482103200041d0006a28020022042001107702402004450d00200320044105746a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a41021078200341206a22032004470d000b0b20002802542103200041dc006a28020022042001107702402004450d002003200441246c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a41021078200341246a22032004470d000b0b20002802602103200041e8006a28020022042001107702402004450d002003200441286c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a41021078200341286a22032004470d000b0b200028026c2103200041f4006a28020022042001107702402004450d0020032004412c6c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a410210782003412c6a22032004470d000b0b2000280278210320004180016a28020022042001107702402004450d002003200441306c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a41021078200341306a22032004470d000b0b20002802840121032000418c016a28020022042001107702402004450d002003200441346c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a4102107820022003412e6a2f01003b010c20012002410c6a410210782002200341306a2f01003b010c20012002410c6a41021078200341346a22032004470d000b0b200028029001210320004198016a28020022042001107702402004450d002003200441386c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a4102107820022003412e6a2f01003b010c20012002410c6a410210782002200341306a2f01003b010c20012002410c6a410210782002200341326a2f01003b010c20012002410c6a410210782002200341346a2f01003b010c20012002410c6a41021078200341386a22032004470d000b0b200028029c012103200041a4016a28020022042001107702402004450d0020032004413c6c6a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a4102107820022003412e6a2f01003b010c20012002410c6a410210782002200341306a2f01003b010c20012002410c6a410210782002200341326a2f01003b010c20012002410c6a410210782002200341346a2f01003b010c20012002410c6a410210782002200341366a2f01003b010c20012002410c6a410210782002200341386a2f01003b010c20012002410c6a410210782003413c6a22032004470d000b0b20002802a8012103200041b0016a28020022042001107702402004450d00200320044106746a210403402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a4102107820022003412e6a2f01003b010c20012002410c6a410210782002200341306a2f01003b010c20012002410c6a410210782002200341326a2f01003b010c20012002410c6a410210782002200341346a2f01003b010c20012002410c6a410210782002200341366a2f01003b010c20012002410c6a410210782002200341386a2f01003b010c20012002410c6a4102107820022003413a6a2f01003b010c20012002410c6a4102107820022003413c6a2f01003b010c20012002410c6a41021078200341c0006a22032004470d000b0b20002802b4012103200041bc016a28020022002001107702402000450d002003200041c4006c6a210003402002200328020036020c20012002410c6a410410782002200341046a2f01003b010c20012002410c6a410210782002200341066a2f01003b010c20012002410c6a410210782002200341086a2f01003b010c20012002410c6a4102107820022003410a6a2f01003b010c20012002410c6a4102107820022003410c6a2f01003b010c20012002410c6a4102107820022003410e6a2f01003b010c20012002410c6a410210782002200341106a2f01003b010c20012002410c6a410210782002200341126a2f01003b010c20012002410c6a410210782002200341146a2f01003b010c20012002410c6a410210782002200341166a2f01003b010c20012002410c6a410210782002200341186a2f01003b010c20012002410c6a4102107820022003411a6a2f01003b010c20012002410c6a4102107820022003411c6a2f01003b010c20012002410c6a4102107820022003411e6a2f01003b010c20012002410c6a410210782002200341206a2f01003b010c20012002410c6a410210782002200341226a2f01003b010c20012002410c6a410210782002200341246a2f01003b010c20012002410c6a410210782002200341266a2f01003b010c20012002410c6a410210782002200341286a2f01003b010c20012002410c6a4102107820022003412a6a2f01003b010c20012002410c6a4102107820022003412c6a2f01003b010c20012002410c6a4102107820022003412e6a2f01003b010c20012002410c6a410210782002200341306a2f01003b010c20012002410c6a410210782002200341326a2f01003b010c20012002410c6a410210782002200341346a2f01003b010c20012002410c6a410210782002200341366a2f01003b010c20012002410c6a410210782002200341386a2f01003b010c20012002410c6a4102107820022003413a6a2f01003b010c20012002410c6a4102107820022003413c6a2f01003b010c20012002410c6a4102107820022003413e6a2f01003b010c20012002410c6a410210782002200341c0006a2f01003b010c20012002410c6a41021078200341c4006a22032000470d000b0b200241106a24000bd2ae0109097f017e067f037e217f027e0b7f017e047f23004190046b22022400200241f8006a200110c4010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802780d00200228027c220320012802044103762204200420034b1b22054103742204417f4c0d020240024020050d00410421060c010b200410332206450d040b41002104200241003602980320022005360294032002200636029003024002402003450d00410021040340200128020422054104490d0220012802002207280000210820012005417c6a22093602042001200741046a220736020020094102490d0220072f0000210920012005417a6a3602042001200741026a36020002402004200228029403470d0020024190036a20044101109001200228029003210620022802980321040b200620044103746a220520093b0104200520083602002002200441016a2204360298032003417f6a22030d000b20022802940321050b2006450d01200241f0006a200110c4012002280270450d020c180b20022802940341ffffffff0171450d00200610350b200041003602000c180b2002280274220a2001280204410c6e22072007200a4b1bad420c7e220b422088a70d00200ba72203417f4c0d000240024020030d004104210c0c010b20031033220c450d020b4100210720024100360298032002200c3602900320022003410c6e220d36029403024002400240200a450d00410021070340200128020422034104490d0220012802002209280000210e20012003417c6a220d3602042001200941046a2208360200200d4102490d0220082f0000210f20012003417a6a220d3602042001200841026a360200200d4102490d0220092f0006210d2001200341786a22083602042001200941086a220936020020084102490d0220092f000021082001200341766a3602042001200941026a36020002402007200228029403470d0020024190036a20074101108701200228029003210c20022802980321070b200c2007410c6c6a220320083b01082003200f3b01042003200e360200200341066a200d3b01002002200741016a220736029803200a417f6a220a0d000b200228029403210d0b200c450d17200241e8006a200110c4012002280268450d010c160b2002280294032201450d162001410c6c450d16200c10350c160b4104210f200228026c220e200128020441047622032003200e4b1b22034104742209417f4c0d0002402003450d0020091033220f450d020b41002108200241003602980320022003360294032002200f36029003024002400240200e450d00410021080340200128020422034104490d0220012802002209280000211020012003417c6a22113602042001200941046a220a36020020114102490d02200a330000210b20012003417a6a22113602042001200a41026a36020020114102490d02200933000621122001200341786a22113602042001200941086a220a36020020114102490d02200a33000021132001200341766a22113602042001200a41026a36020020114102490d02200933000a21142001200341746a220a36020420012009410c6a2209360200200a4102490d0220092f0000210a2001200341726a3602042001200941026a3602002014423086201342208684201242108684200b84210b02402008200228029403470d0020024190036a20084101108c01200228029003210f20022802980321080b200f20084104746a2203200a3b010c2003200b370204200320103602002002200841016a220836029803200e417f6a220e0d000b20022802940321030b200f450d16200241e0006a200110c4012002280260450d010c150b20022802940341ffffffff0071450d15200f10350c150b20022802642210200128020441146e2209200920104b1bad42147e220b422088a70d00200ba72209417f4c0d000240024020090d00410421150c010b200910332215450d020b4100210e200241003602980320022015360290032002200941146e2211360294030240024002402010450d004100210e0340200128020422094104490d022001280200220a280000211620012009417c6a22173602042001200a41046a221136020020174102490d0220112f0000211820012009417a6a22173602042001201141026a36020020174102490d02200a2f000621192001200941786a22173602042001200a41086a221136020020174102490d0220112f0000211a2001200941766a22173602042001201141026a36020020174102490d02200a2f000a211b2001200941746a22173602042001200a410c6a221136020020174102490d0220112f0000211c2001200941726a22173602042001201141026a36020020174102490d02200a2f000e21172001200941706a22113602042001200a41106a220a36020020114102490d02200a2f0000211120012009416e6a3602042001200a41026a3602000240200e200228029403470d0020024190036a200e41011099012002280290032115200228029803210e0b2015200e41146c6a220920113b0110200920183b0104200920163602002009410e6a20173b01002009410c6a201c3b01002009410a6a201b3b0100200941086a201a3b0100200941066a20193b01002002200e41016a220e360298032010417f6a22100d000b20022802940321110b2015450d15200241d8006a200110c4012002280258450d010c140b2002280294032201450d14200141146c450d14201510350c140b200228025c2217200128020441186e2209200920174b1bad42187e220b422088a70d00200ba72209417f4c0d000240024020090d00410421180c010b200910332218450d020b41002110200241003602980320022018360290032002200941186e2216360294030240024002402017450d00410021100340200128020422094104490d022001280200220a280000211a20012009417c6a22193602042001200a41046a221636020020194102490d0220162f0000211b20012009417a6a22193602042001201641026a36020020194102490d02200a2f0006211c2001200941786a22193602042001200a41086a221636020020194102490d0220162f0000211d2001200941766a22193602042001201641026a36020020194102490d02200a2f000a211e2001200941746a22193602042001200a410c6a221636020020194102490d0220162f0000211f2001200941726a22193602042001201641026a36020020194102490d02200a2f000e21202001200941706a22193602042001200a41106a221636020020194102490d0220162f0000212120012009416e6a22193602042001201641026a36020020194102490d02200a2f0012211920012009416c6a22163602042001200a41146a220a36020020164102490d02200a2f0000211620012009416a6a3602042001200a41026a36020002402010200228029403470d0020024190036a20104101109701200228029003211820022802980321100b2018201041186c6a220920163b01142009201b3b01042009201a360200200941126a20193b0100200941106a20213b01002009410e6a20203b01002009410c6a201f3b01002009410a6a201e3b0100200941086a201d3b0100200941066a201c3b01002002201041016a2210360298032017417f6a22170d000b20022802940321160b2018450d14200241d0006a200110c4012002280250450d010c130b2002280294032201450d13200141186c450d13201810350c130b200228025422192001280204411c6e2209200920194b1bad421c7e220b422088a70d00200ba72209417f4c0d000240024020090d004104211b0c010b20091033221b450d020b4100211720024100360298032002201b3602900320022009411c6e221a360294030240024002402019450d00410021170340200128020422094104490d022001280200220a280000211d20012009417c6a221c3602042001200a41046a221a360200201c4102490d02201a2f0000211e20012009417a6a221c3602042001201a41026a360200201c4102490d02200a2f0006211f2001200941786a221c3602042001200a41086a221a360200201c4102490d02201a2f000021202001200941766a221c3602042001201a41026a360200201c4102490d02200a2f000a21212001200941746a221c3602042001200a410c6a221a360200201c4102490d02201a2f000021222001200941726a221c3602042001201a41026a360200201c4102490d02200a2f000e21232001200941706a221c3602042001200a41106a221a360200201c4102490d02201a2f0000212420012009416e6a221c3602042001201a41026a360200201c4102490d02200a2f0012212520012009416c6a221c3602042001200a41146a221a360200201c4102490d02201a2f0000212620012009416a6a221c3602042001201a41026a360200201c4102490d02200a2f0016211c2001200941686a221a3602042001200a41186a220a360200201a4102490d02200a2f0000211a2001200941666a3602042001200a41026a36020002402017200228029403470d0020024190036a2017410110f901200228029003211b20022802980321170b201b2017411c6c6a2209201a3b01182009201e3b01042009201d360200200941166a201c3b0100200941146a20263b0100200941126a20253b0100200941106a20243b01002009410e6a20233b01002009410c6a20223b01002009410a6a20213b0100200941086a20203b0100200941066a201f3b01002002201741016a2217360298032019417f6a22190d000b200228029403211a0b201b450d13200241c8006a200110c4012002280248450d010c120b2002280294032201450d122001411c6c450d12201b10350c120b200228024c221c200128020441057622092009201c4b1b2209410574220a417f4c0d000240024020090d004104211e0c010b200a1033221e450d020b41002119200241003602980320022009360294032002201e36029003024002400240201c450d00410021190340200128020422094104490d022001280200220a280000212020012009417c6a221f3602042001200a41046a221d360200201f4102490d02201d2f0000212120012009417a6a221f3602042001201d41026a360200201f4102490d02200a2f000621222001200941786a221f3602042001200a41086a221d360200201f4102490d02201d2f000021232001200941766a221f3602042001201d41026a360200201f4102490d02200a2f000a21242001200941746a221f3602042001200a410c6a221d360200201f4102490d02201d2f000021252001200941726a221f3602042001201d41026a360200201f4102490d02200a2f000e21262001200941706a221f3602042001200a41106a221d360200201f4102490d02201d2f0000212720012009416e6a221f3602042001201d41026a360200201f4102490d02200a2f0012212820012009416c6a221f3602042001200a41146a221d360200201f4102490d02201d2f0000212920012009416a6a221f3602042001201d41026a360200201f4102490d02200a2f0016212a2001200941686a221f3602042001200a41186a221d360200201f4102490d02201d2f0000212b2001200941666a221f3602042001201d41026a360200201f4102490d02200a2f001a211f2001200941646a221d3602042001200a411c6a220a360200201d4102490d02200a2f0000211d2001200941626a3602042001200a41026a36020002402019200228029403470d0020024190036a20194101109101200228029003211e20022802980321190b201e20194105746a2209201d3b011c200920213b0104200920203602002009411a6a201f3b0100200941186a202b3b0100200941166a202a3b0100200941146a20293b0100200941126a20283b0100200941106a20273b01002009410e6a20263b01002009410c6a20253b01002009410a6a20243b0100200941086a20233b0100200941066a20223b01002002201941016a221936029803201c417f6a221c0d000b20022802940321090b201e450d12200241c0006a200110c4012002280240450d010c110b20022802940341ffffff3f71450d11201e10350c110b2002280244221f200128020441246e220a200a201f4b1bad42247e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421210c010b200a10332221450d020b4100211d200241003602980320022021360290032002200a41246e222036029403024002400240201f450d004100211d03402001280204220a4104490d022001280200221c28000021232001200a417c6a22223602042001201c41046a222036020020224102490d0220202f000021242001200a417a6a22223602042001202041026a36020020224102490d02201c2f000621252001200a41786a22223602042001201c41086a222036020020224102490d0220202f000021262001200a41766a22223602042001202041026a36020020224102490d02201c2f000a21272001200a41746a22223602042001201c410c6a222036020020224102490d0220202f000021282001200a41726a22223602042001202041026a36020020224102490d02201c2f000e21292001200a41706a22223602042001201c41106a222036020020224102490d0220202f0000212a2001200a416e6a22223602042001202041026a36020020224102490d02201c2f0012212b2001200a416c6a22223602042001201c41146a222036020020224102490d0220202f0000212c2001200a416a6a22223602042001202041026a36020020224102490d02201c2f0016212d2001200a41686a22223602042001201c41186a222036020020224102490d0220202f0000212e2001200a41666a22223602042001202041026a36020020224102490d02201c2f001a212f2001200a41646a22223602042001201c411c6a222036020020224102490d0220202f000021302001200a41626a22223602042001202041026a36020020224102490d02201c2f001e21222001200a41606a22203602042001201c41206a221c36020020204102490d02201c2f000021202001200a415e6a3602042001201c41026a3602000240201d200228029403470d0020024190036a201d4101108d012002280290032121200228029803211d0b2021201d41246c6a220a20203b0120200a20243b0104200a2023360200200a411e6a20223b0100200a411c6a20303b0100200a411a6a202f3b0100200a41186a202e3b0100200a41166a202d3b0100200a41146a202c3b0100200a41126a202b3b0100200a41106a202a3b0100200a410e6a20293b0100200a410c6a20283b0100200a410a6a20273b0100200a41086a20263b0100200a41066a20253b01002002201d41016a221d36029803201f417f6a221f0d000b20022802940321200b2021450d11200241386a200110c4012002280238450d010c100b2002280294032201450d10200141246c450d10202110350c100b200228023c2222200128020441286e220a200a20224b1bad42287e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421230c010b200a10332223450d020b4100211f200241003602980320022023360290032002200a41286e2224360294030240024002402022450d004100211f03402001280204220a4104490d022001280200221c28000021262001200a417c6a22253602042001201c41046a222436020020254102490d0220242f000021272001200a417a6a22253602042001202441026a36020020254102490d02201c2f000621282001200a41786a22253602042001201c41086a222436020020254102490d0220242f000021292001200a41766a22253602042001202441026a36020020254102490d02201c2f000a212a2001200a41746a22253602042001201c410c6a222436020020254102490d0220242f0000212b2001200a41726a22253602042001202441026a36020020254102490d02201c2f000e212c2001200a41706a22253602042001201c41106a222436020020254102490d0220242f0000212d2001200a416e6a22253602042001202441026a36020020254102490d02201c2f0012212e2001200a416c6a22253602042001201c41146a222436020020254102490d0220242f0000212f2001200a416a6a22253602042001202441026a36020020254102490d02201c2f001621302001200a41686a22253602042001201c41186a222436020020254102490d0220242f000021312001200a41666a22253602042001202441026a36020020254102490d02201c2f001a21322001200a41646a22253602042001201c411c6a222436020020254102490d0220242f000021332001200a41626a22253602042001202441026a36020020254102490d02201c2f001e21342001200a41606a22253602042001201c41206a222436020020254102490d0220242f000021352001200a415e6a22253602042001202441026a36020020254102490d02201c2f002221252001200a415c6a22243602042001201c41246a221c36020020244102490d02201c2f000021242001200a415a6a3602042001201c41026a3602000240201f200228029403470d0020024190036a201f4101109d012002280290032123200228029803211f0b2023201f41286c6a220a20243b0124200a20273b0104200a2026360200200a41226a20253b0100200a41206a20353b0100200a411e6a20343b0100200a411c6a20333b0100200a411a6a20323b0100200a41186a20313b0100200a41166a20303b0100200a41146a202f3b0100200a41126a202e3b0100200a41106a202d3b0100200a410e6a202c3b0100200a410c6a202b3b0100200a410a6a202a3b0100200a41086a20293b0100200a41066a20283b01002002201f41016a221f360298032022417f6a22220d000b20022802940321240b2023450d10200241306a200110c4012002280230450d010c0f0b2002280294032201450d0f200141286c450d0f202310350c0f0b200228023422252001280204412c6e220a200a20254b1bad422c7e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421260c010b200a10332226450d020b41002122200241003602880120022026360280012002200a412c6e22273602840102402025450d004100212203402001280204220a4104490d0e2001280200221c280000212b2001200a417c6a22283602042001201c41046a2227360200200241003a00b403200241003b01d00320284102490d0e20272f000021292001200a417a6a22283602042001202741026a360200200241003b01d00320284102490d0e201c2f000621282001200a41786a222a3602042001201c41086a2227360200200220293b019003200241013a00b403200220283b019203200241003b01d003202a4102490d0d20272f000021292001200a41766a22283602042001202741026a360200200241003b01d003202841014d0d0d201c2f000a21282001200a41746a222a3602042001201c410c6a2227360200200220293b019403200220283b019603200241023a00b403200241003b01d003202a4102490d0d20272f000021292001200a41726a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f000e21282001200a41706a222a3602042001201c41106a2227360200200220293b019803200241033a00b403200220283b019a03200241003b01d003202a4102490d0d20272f000021292001200a416e6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001221282001200a416c6a222a3602042001201c41146a2227360200200220293b019c03200241043a00b403200220283b019e03200241003b01d003202a4102490d0d20272f000021292001200a416a6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001621282001200a41686a222a3602042001201c41186a2227360200200220293b01a003200241053a00b403200220283b01a203200241003b01d003202a4102490d0d20272f000021292001200a41666a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001a21282001200a41646a222a3602042001201c411c6a2227360200200220293b01a403200241063a00b403200220283b01a603200241003b01d003202a4102490d0d20272f000021292001200a41626a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f001e21282001200a41606a222a3602042001201c41206a2227360200200220293b01a803200241073a00b403200220283b01aa03200241003b01d003202a4102490d0d20272f000021292001200a415e6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f002221282001200a415c6a222a3602042001201c41246a2227360200200220293b01ac03200241083a00b403200220283b01ae03200241003b01d003202a4102490d0d20272f000021292001200a415a6a22283602042001202741026a360200200241003b01d00320284102490d0d201c2f002621272001200a41586a22283602042001201c41286a221c360200200220293b01b003200241093a00b403200220273b01b203200241d0036a41206a20022802b0032227360200200241d0036a41186a20024190036a41186a290300220b370300200241d0036a41106a20024190036a41106a2903002212370300200241d0036a41086a20024190036a41086a2903002213370300200220022903900322143703d003200241d0026a41206a22292027360200200241d0026a41186a2227200b370300200241d0026a41106a222a2012370300200241d0026a41086a222c2013370300200220143703d00220284102490d0e201c2f000021282001200a41566a3602042001201c41026a36020020024190026a41106a202a290300220b370300200241d0016a41086a202c2903002212370300200241d0016a41106a200b370300200241d0016a41186a20272903002213370300200241d0016a41206a2029280200220a360200200220022903d00222143703d00120024190016a41206a221c200a36020020024190016a41186a2227201337030020024190016a41106a2229200b37030020024190016a41086a222a2012370300200220143703900102402022200228028401470d0020024180016a20224101109801200228028001212620022802880121220b20262022412c6c6a220a202b360200200a200229039001370204201c280200211c2027290300210b20292903002112202a2903002113200a20283b0128200a410c6a2013370200200a41146a2012370200200a411c6a200b370200200a41246a201c3602002002202241016a2222360288012025417f6a22250d000b20022802840121270b2026450d0d200241286a200110c40120022802280d0a200228022c2228200128020441306e220a200a20284b1bad42307e220b422088a70d00200ba7220a417f4c0d0002400240200a0d00410421290c010b200a10332229450d020b41002125200241003602880120022029360280012002200a41306e222a3602840102402028450d004100212503402001280204220a4104490d0b2001280200221c280000212e2001200a417c6a222b3602042001201c41046a222a360200200241003a00b803200241003b01d003202b4102490d0b202a2f0000212c2001200a417a6a222b3602042001202a41026a360200200241003b01d003202b4102490d0b201c2f0006212b2001200a41786a222d3602042001201c41086a222a3602002002202c3b019003200241013a00b8032002202b3b019203200241003b01d003202d4102490d0a202a2f0000212c2001200a41766a222b3602042001202a41026a360200200241003b01d003202b41014d0d0a201c2f000a212b2001200a41746a222d3602042001201c410c6a222a3602002002202c3b0194032002202b3b019603200241023a00b803200241003b01d003202d4102490d0a202a2f0000212c2001200a41726a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f000e212b2001200a41706a222d3602042001201c41106a222a3602002002202c3b019803200241033a00b8032002202b3b019a03200241003b01d003202d4102490d0a202a2f0000212c2001200a416e6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0012212b2001200a416c6a222d3602042001201c41146a222a3602002002202c3b019c03200241043a00b8032002202b3b019e03200241003b01d003202d4102490d0a202a2f0000212c2001200a416a6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0016212b2001200a41686a222d3602042001201c41186a222a3602002002202c3b01a003200241053a00b8032002202b3b01a203200241003b01d003202d4102490d0a202a2f0000212c2001200a41666a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f001a212b2001200a41646a222d3602042001201c411c6a222a3602002002202c3b01a403200241063a00b8032002202b3b01a603200241003b01d003202d4102490d0a202a2f0000212c2001200a41626a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f001e212b2001200a41606a222d3602042001201c41206a222a3602002002202c3b01a803200241073a00b8032002202b3b01aa03200241003b01d003202d4102490d0a202a2f0000212c2001200a415e6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0022212b2001200a415c6a222d3602042001201c41246a222a3602002002202c3b01ac03200241083a00b8032002202b3b01ae03200241003b01d003202d4102490d0a202a2f0000212c2001200a415a6a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f0026212b2001200a41586a222d3602042001201c41286a222a3602002002202c3b01b003200241093a00b8032002202b3b01b203200241003b01d003202d4102490d0a202a2f0000212c2001200a41566a222b3602042001202a41026a360200200241003b01d003202b4102490d0a201c2f002a212a2001200a41546a222b3602042001201c412c6a221c3602002002202c3b01b4032002410a3a00b8032002202a3b01b603200241d0036a41206a20024190036a41206a290300220b370300200241d0036a41186a20024190036a41186a2903002212370300200241d0036a41106a20024190036a41106a2903002213370300200241d0036a41086a20024190036a41086a2903002214370300200220022903900322363703d003200241d0026a41206a222a200b370300200241d0026a41186a222c2012370300200241d0026a41106a222d2013370300200241d0026a41086a222f2014370300200220363703d002202b4102490d0b201c2f0000212b2001200a41526a3602042001201c41026a36020020024190026a41106a202d290300220b370300200241d0016a41086a202f2903002212370300200241d0016a41106a200b370300200241d0016a41186a202c2903002213370300200241d0016a41206a202a2903002214370300200220022903d00222363703d00120024190016a41206a221c201437030020024190016a41186a222a201337030020024190016a41106a222c200b37030020024190016a41086a222d2012370300200220363703900102402025200228028401470d0020024180016a20254101108901200228028001212920022802880121250b2029202541306c6a220a202e360200200a200229039001370204201c290300210b202a2903002112202c2903002113202d2903002114200a202b3b012c200a410c6a2014370200200a41146a2013370200200a411c6a2012370200200a41246a200b3702002002202541016a2225360288012028417f6a22280d000b200228028401212a0b2029450d0a200241206a200110c40120022802200d072002280224222b200128020441346e220a200a202b4b1bad42347e220b422088a70d00200ba7220a417f4c0d0002400240200a0d004104212c0c010b200a1033222c450d020b4100212820024100360288012002202c360280012002200a41346e222d360284010240202b450d004100212803402001280204220a4104490d082001280200221c28000021312001200a417c6a222e3602042001201c41046a222d360200200241003a00bc03200241003b01d003202e4102490d08202d2f0000212f2001200a417a6a222e3602042001202d41026a360200200241003b01d003202e4102490d08201c2f0006212e2001200a41786a22303602042001201c41086a222d3602002002202f3b019003200241013a00bc032002202e3b019203200241003b01d00320304102490d07202d2f0000212f2001200a41766a222e3602042001202d41026a360200200241003b01d003202e41014d0d07201c2f000a212e2001200a41746a22303602042001201c410c6a222d3602002002202f3b0194032002202e3b019603200241023a00bc03200241003b01d00320304102490d07202d2f0000212f2001200a41726a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f000e212e2001200a41706a22303602042001201c41106a222d3602002002202f3b019803200241033a00bc032002202e3b019a03200241003b01d00320304102490d07202d2f0000212f2001200a416e6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0012212e2001200a416c6a22303602042001201c41146a222d3602002002202f3b019c03200241043a00bc032002202e3b019e03200241003b01d00320304102490d07202d2f0000212f2001200a416a6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0016212e2001200a41686a22303602042001201c41186a222d3602002002202f3b01a003200241053a00bc032002202e3b01a203200241003b01d00320304102490d07202d2f0000212f2001200a41666a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f001a212e2001200a41646a22303602042001201c411c6a222d3602002002202f3b01a403200241063a00bc032002202e3b01a603200241003b01d00320304102490d07202d2f0000212f2001200a41626a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f001e212e2001200a41606a22303602042001201c41206a222d3602002002202f3b01a803200241073a00bc032002202e3b01aa03200241003b01d00320304102490d07202d2f0000212f2001200a415e6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0022212e2001200a415c6a22303602042001201c41246a222d3602002002202f3b01ac03200241083a00bc032002202e3b01ae03200241003b01d00320304102490d07202d2f0000212f2001200a415a6a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f0026212e2001200a41586a22303602042001201c41286a222d3602002002202f3b01b003200241093a00bc032002202e3b01b203200241003b01d00320304102490d07202d2f0000212f2001200a41566a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f002a212e2001200a41546a22303602042001201c412c6a222d3602002002202f3b01b4032002410a3a00bc032002202e3b01b603200241003b01d00320304102490d07202d2f0000212f2001200a41526a222e3602042001202d41026a360200200241003b01d003202e4102490d07201c2f002e212d2001200a41506a222e3602042001201c41306a221c3602002002202f3b01b8032002410b3a00bc032002202d3b01ba03200241d0036a41286a20022802b803222d360200200241d0036a41206a20024190036a41206a290300220b370300200241d0036a41186a20024190036a41186a2903002212370300200241d0036a41106a20024190036a41106a2903002213370300200241d0036a41086a20024190036a41086a2903002214370300200220022903900322363703d003200241d0026a41286a222f202d360200200241d0026a41206a222d200b370300200241d0026a41186a22302012370300200241d0026a41106a22322013370300200241d0026a41086a22332014370300200220363703d002202e4102490d08201c2f0000212e2001200a414e6a3602042001201c41026a36020020024190026a41106a2032290300220b37030020024190026a41186a20302903002212370300200241d0016a41086a220a2033290300370300200241d0016a41106a221c200b370300200241d0016a41186a22302012370300200241d0016a41206a2232202d290300370300200241d0016a41286a222d202f280200360200200220022903d0023703d00120024190016a41286a222f202d28020036020020024190016a41206a222d203229030037030020024190016a41186a2232203029030037030020024190016a41106a2230201c29030037030020024190016a41086a221c200a290300370300200220022903d0013703900102402028200228028401470d0020024180016a2028410110a501200228028001212c20022802880121280b202c202841346c6a220a2031360200200a200229039001370204202f280200212f202d290300210b2032290300211220302903002113201c2903002114200a202e3b0130200a410c6a2014370200200a41146a2013370200200a411c6a2012370200200a41246a200b370200200a412c6a202f3602002002202841016a222836028801202b417f6a222b0d000b200228028401212d0b202c450d07200241186a200110c40120022802180d04200228021c222e200128020441386e220a200a202e4b1bad42387e220b422088a70d00200ba7220a417f4c0d0002400240200a0d004104212f0c010b200a1033222f450d020b4100212b20024100360288012002202f360280012002200a41386e2234360284010240202e450d004100212b03402001280204220a4104490d052001280200221c28000021342001200a417c6a22313602042001201c41046a2230360200200241003a00c003200241003b01d00320314102490d0520302f000021322001200a417a6a22313602042001203041026a360200200241003b01d00320314102490d05201c2f000621312001200a41786a22333602042001201c41086a2230360200200220323b019003200241013a00c003200220313b019203200241003b01d00320334102490d0420302f000021322001200a41766a22313602042001203041026a360200200241003b01d003203141014d0d04201c2f000a21312001200a41746a22333602042001201c410c6a2230360200200220323b019403200220313b019603200241023a00c003200241003b01d00320334102490d0420302f000021322001200a41726a22313602042001203041026a360200200241003b01d00320314102490d04201c2f000e21312001200a41706a22333602042001201c41106a2230360200200220323b019803200241033a00c003200220313b019a03200241003b01d00320334102490d0420302f000021322001200a416e6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001221312001200a416c6a22333602042001201c41146a2230360200200220323b019c03200241043a00c003200220313b019e03200241003b01d00320334102490d0420302f000021322001200a416a6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001621312001200a41686a22333602042001201c41186a2230360200200220323b01a003200241053a00c003200220313b01a203200241003b01d00320334102490d0420302f000021322001200a41666a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001a21312001200a41646a22333602042001201c411c6a2230360200200220323b01a403200241063a00c003200220313b01a603200241003b01d00320334102490d0420302f000021322001200a41626a22313602042001203041026a360200200241003b01d00320314102490d04201c2f001e21312001200a41606a22333602042001201c41206a2230360200200220323b01a803200241073a00c003200220313b01aa03200241003b01d00320334102490d0420302f000021322001200a415e6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002221312001200a415c6a22333602042001201c41246a2230360200200220323b01ac03200241083a00c003200220313b01ae03200241003b01d00320334102490d0420302f000021322001200a415a6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002621312001200a41586a22333602042001201c41286a2230360200200220323b01b003200241093a00c003200220313b01b203200241003b01d00320334102490d0420302f000021322001200a41566a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002a21312001200a41546a22333602042001201c412c6a2230360200200220323b01b4032002410a3a00c003200220313b01b603200241003b01d00320334102490d0420302f000021322001200a41526a22313602042001203041026a360200200241003b01d00320314102490d04201c2f002e21312001200a41506a22333602042001201c41306a2230360200200220323b01b8032002410b3a00c003200220313b01ba03200241003b01d00320334102490d0420302f000021322001200a414e6a22313602042001203041026a360200200241003b01d00320314102490d04201c2f003221302001200a414c6a22313602042001201c41346a221c360200200220323b01bc032002410c3a00c003200220303b01be03200241d0036a41286a20024190036a41286a290300220b370300200241d0036a41206a20024190036a41206a2903002212370300200241d0036a41186a20024190036a41186a2903002213370300200241d0036a41106a20024190036a41106a2903002214370300200241d0036a41086a20024190036a41086a2903002236370300200220022903900322373703d003200241d0026a41286a2230200b370300200241d0026a41206a22322012370300200241d0026a41186a22332013370300200241d0026a41106a22352014370300200241d0026a41086a22382036370300200220373703d00220314102490d05201c2f000021312001200a414a6a3602042001201c41026a36020020024190026a41106a2035290300220b37030020024190026a41186a20332903002212370300200241d0016a41086a220a2038290300370300200241d0016a41106a221c200b370300200241d0016a41186a22332012370300200241d0016a41206a22352032290300370300200241d0016a41286a22322030290300370300200220022903d0023703d00120024190016a41286a2230203229030037030020024190016a41206a2232203529030037030020024190016a41186a2235203329030037030020024190016a41106a2233201c29030037030020024190016a41086a221c200a290300370300200220022903d001370390010240202b200228028401470d0020024180016a202b410110a201200228028001212f200228028801212b0b202f202b41386c6a220a2034360200200a2002290390013702042030290300210b203229030021122035290300211320332903002114201c2903002136200a20313b0134200a410c6a2036370200200a41146a2014370200200a411c6a2013370200200a41246a2012370200200a412c6a200b3702002002202b41016a222b36028801202e417f6a222e0d000b20022802840121340b202f450d04200241106a200110c401024002400240024002400240024020022802100d00200228021422392001280204413c6e220a200a20394b1bad423c7e220b422088a70d07200ba7220a417f4c0d0702400240200a0d004104213a0c010b200a1033223a450d090b4100213b20024100360288012002203a360280012002200a413c6e2235360284010240024002402039450d004100213b4100213c0340200128020422354104490d03203c41016a213c417c211c20012802002238280000213d20012035417c6a3602042001203841046a3602004100210a200241003a00c403410021310340200241003b01d0032035201c6a222e4102490d032038200a6a223041046a2f000021322001202e417e6a222e3602042001203041066a2230360200200241003b01d003202e4102490d0320024190036a200a6a223320323b0100203341026a20302f00003b01002001202e417e6a3602042001203041026a3602002002203141016a22313a00c403201c417c6a211c200a41046a220a4134470d000b200241d0036a41306a222e20024190036a41306a280200360200200241d0036a41286a223020024190036a41286a290300370300200241d0036a41206a223220024190036a41206a290300370300200241d0036a41186a223320024190036a41186a290300370300200241d0036a41106a223e20024190036a41106a290300370300200241d0036a41086a223f20024190036a41086a29030037030020022002290390033703d003203141ff0171410d490d03200241d0026a41306a2231202e280200360200200241d0026a41286a222e2030290300370300200241d0026a41206a22302032290300370300200241d0026a41186a22322033290300370300200241d0026a41106a2233203e290300370300200241d0026a41086a223e203f290300370300200220022903d0033703d0022035201c6a41014d0d032038200a6a221c41046a2f0000213820012035200a6b417a6a3602042001201c41066a36020020024190026a41086a203e290300220b37030020024190026a41106a2033290300221237030020024190026a41186a2032290300221337030020024190026a41206a2030290300221437030020024190026a41286a202e290300223637030020024190026a41306a2031280200220a360200200220022903d002223737039002200241d0016a41306a221c200a360200200241d0016a41286a220a2036370300200241d0016a41206a222e2014370300200241d0016a41186a22302013370300200241d0016a41106a22312012370300200241d0016a41086a2232200b370300200220373703d00120024190016a41306a2233201c28020036020020024190016a41286a221c200a29030037030020024190016a41206a2235202e29030037030020024190016a41186a222e203029030037030020024190016a41106a2230203129030037030020024190016a41086a22312032290300370300200220022903d001370390010240203b200228028401470d0020024180016a203b410110aa01200228028001213a200228028801213b0b203a203b413c6c6a220a203d360200200a20022903900137020420332802002132201c290300210b20352903002112202e29030021132030290300211420312903002136200a20383b0138200a410c6a2036370200200a41146a2014370200200a411c6a2013370200200a41246a2012370200200a412c6a200b370200200a41346a20323602002002203b41016a223b36028801203c2039470d000b20022802840121350b203a450d02200241086a200110c40120022802080d05200228020c223d2001280204410676220a200a203d4b1b221c410674220a417f4c0d09201c0d034104213c0c040b203141ff0171450d00200241003a00c4030b200241d0016a41306a20024190026a41306a280200360200200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d002001413c6c450d00203a10350b2000410036020002402034450d00203441386c450d00202f10350b0240202d450d00202d41346c450d00202c10350b0240202a450d00202a41306c450d00202910350b02402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d1c0c1d0b200a1033223c450d060b4100213e20024100360288012002201c360284012002203c36028001024002400240203d450d004100213e4100213f0340200128020422384104490d03203f41016a213f417c211c20012802002239280000214020012038417c6a3602042001203941046a3602004100210a200241003a00c803410021310340200241003b01d0032038201c6a222e4102490d032039200a6a223041046a2f000021322001202e417e6a222e3602042001203041066a2230360200200241003b01d003202e4102490d0320024190036a200a6a223320323b0100203341026a20302f00003b01002001202e417e6a3602042001203041026a3602002002203141016a22313a00c803201c417c6a211c200a41046a220a4138470d000b200241d0036a41306a222e20024190036a41306a290300370300200241d0036a41286a223020024190036a41286a290300370300200241d0036a41206a223220024190036a41206a290300370300200241d0036a41186a223320024190036a41186a290300370300200241d0036a41106a224120024190036a41106a290300370300200241d0036a41086a224220024190036a41086a29030037030020022002290390033703d003203141ff0171410e490d03200241d0026a41306a2231202e290300370300200241d0026a41286a222e2030290300370300200241d0026a41206a22302032290300370300200241d0026a41186a22322033290300370300200241d0026a41106a22332041290300370300200241d0026a41086a22412042290300370300200220022903d0033703d0022038201c6a41014d0d032039200a6a221c41046a2f0000213920012038200a6b417a6a3602042001201c41066a36020020024190026a41086a2041290300220b37030020024190026a41106a2033290300221237030020024190026a41186a2032290300221337030020024190026a41206a2030290300221437030020024190026a41286a202e290300223637030020024190026a41306a20312903002237370300200220022903d002224337039002200241d0016a41306a220a2037370300200241d0016a41286a221c2036370300200241d0016a41206a222e2014370300200241d0016a41186a22302013370300200241d0016a41106a22312012370300200241d0016a41086a2232200b370300200220433703d00120024190016a41306a2233200a29030037030020024190016a41286a2238201c29030037030020024190016a41206a221c202e29030037030020024190016a41186a222e203029030037030020024190016a41106a2230203129030037030020024190016a41086a22312032290300370300200220022903d001370390010240203e200228028401470d0020024180016a203e410110a601200228028001213c200228028801213e0b203c203e4106746a220a2040360200200a2002290390013702042033290300210b20382903002112201c2903002113202e29030021142030290300213620312903002137200a20393b013c200a410c6a2037370200200a41146a2036370200200a411c6a2014370200200a41246a2013370200200a412c6a2012370200200a41346a200b3702002002203e41016a223e36028801203f203d470d000b200228028401211c0b203c450d022002200110c40120022802000d0520022802042240200128020441c4006e220a200a20404b1bad42c4007e220b422088a70d06200ba7220a417f4c0d06200a0d034104213f0c040b203141ff0171450d00200241003a00c8030b200241d0016a41306a20024190026a41306a290300370300200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a29030037030020022802840141ffffff1f71450d00203c10350b2000410036020002402035450d002035413c6c450d00203a10350b02402034450d00203441386c450d00202f10350b0240202d450d00202d41346c450d00202c10350b0240202a450d00202a41306c450d00202910350b02402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d190c1a0b200a1033223f450d030b20024100360288012002203f360280012002200a41c4006e360284010240024002402040450d0041002142410021410340200128020422394104490d03204141016a2141417c212e2001280200223d280000214420012039417c6a3602042001203d41046a3602004100210a200241003a00cc03410021320340200241003b01d0032039202e6a22304102490d03203d200a6a223141046a2f0000213320012030417e6a22303602042001203141066a2231360200200241003b01d00320304102490d0320024190036a200a6a223820333b0100203841026a20312f00003b010020012030417e6a3602042001203141026a3602002002203241016a22323a00cc03202e417c6a212e200a41046a220a413c470d000b200241d0036a41386a223020024190036a41386a280200360200200241d0036a41306a223120024190036a41306a290300370300200241d0036a41286a223320024190036a41286a290300370300200241d0036a41206a223820024190036a41206a290300370300200241d0036a41186a224520024190036a41186a290300370300200241d0036a41106a224620024190036a41106a290300370300200241d0036a41086a224720024190036a41086a29030037030020022002290390033703d003203241ff0171410f490d03200241d0026a41386a22322030280200360200200241d0026a41306a22302031290300370300200241d0026a41286a22312033290300370300200241d0026a41206a22332038290300370300200241d0026a41186a22382045290300370300200241d0026a41106a22452046290300370300200241d0026a41086a22462047290300370300200220022903d0033703d0022039202e6a41014d0d03203d200a6a222e41046a2f0000213d20012039200a6b417a6a3602042001202e41066a36020020024190026a41086a220a204629030037030020024190026a41106a222e204529030037030020024190026a41186a2239203829030037030020024190026a41206a2238203329030037030020024190026a41286a2233203129030037030020024190026a41306a2231203029030037030020024190026a41386a22302032280200360200200220022903d00237039002200241d0016a41086a200a290300220b370300200241d0016a41106a202e2903002212370300200241d0016a41186a20392903002213370300200241d0016a41206a20382903002214370300200241d0016a41286a20332903002236370300200241d0016a41306a20312903002237370300200241d0016a41386a2030280200220a36020020024190016a41086a222e200b37030020024190016a41106a2230201237030020024190016a41186a2231201337030020024190016a41206a2232201437030020024190016a41286a2233203637030020024190016a41306a2238203737030020024190016a41386a2239200a3602002002200229039002220b3703d0012002200b3703900102402042200228028401470d0020024180016a20424101109f01200228028001213f20022802880121420b203f204241c4006c6a220a2044360200200a200229039001370204203928020021392038290300210b20332903002112203229030021132031290300211420302903002136202e2903002137200a203d3b0140200a410c6a2037370200200a41146a2036370200200a411c6a2014370200200a41246a2013370200200a412c6a2012370200200a41346a200b370200200a413c6a20393602002002204241016a22423602880120412040470d000b0b203f450d02200229028401210b2000200536020420002006360200200041b8016a200b370200200041b4016a203f360200200041b0016a203e360200200041ac016a201c360200200041a8016a203c360200200041a4016a203b360200200041a0016a20353602002000419c016a203a36020020004198016a202b36020020004194016a203436020020004190016a202f3602002000418c016a202836020020004188016a202d36020020004184016a202c36020020004180016a2025360200200041fc006a202a360200200041f8006a2029360200200041f4006a2022360200200041f0006a2027360200200041ec006a2026360200200041e8006a201f360200200041e4006a2024360200200041e0006a2023360200200041dc006a201d360200200041d8006a2020360200200041d4006a2021360200200041d0006a2019360200200041cc006a2009360200200041c8006a201e360200200041c4006a2017360200200041c0006a201a3602002000413c6a201b360200200041386a2010360200200041346a2016360200200041306a20183602002000412c6a200e360200200041286a2011360200200041246a2015360200200041206a20083602002000411c6a2003360200200041186a200f360200200041146a2007360200200041106a200d3602002000410c6a200c360200200041086a20043602000c1a0b203241ff0171450d00200241003a00cc030b200241d0016a41386a20024190026a41386a280200360200200241d0016a41306a20024190026a41306a290300370300200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141c4006c450d00203f10350b200041003602000240201c41ffffff1f71450d00203c10350b02402035450d002035413c6c450d00203a10350b02402034450d00203441386c450d00202f10350b0240202d450d00202d41346c450d00202c10350b0240202a450d00202a41306c450d00202910350b02402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff0171450d170c160b1044000b1045000b200241003a00c0030b200241d0016a41286a20024190026a41286a290300370300200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141386c450d00202f10350b200041003602000240202d450d00202d41346c450d00202c10350b0240202a450d00202a41306c450d00202910350b02402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d110c120b200241003a00bc030b200241d0016a41286a20024190026a41286a280200360200200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141346c450d00202c10350b200041003602000240202a450d00202a41306c450d00202910350b02402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d0e0c0f0b200241003a00b8030b200241d0016a41206a20024190026a41206a290300370300200241d0016a41186a20024190026a41186a2903003703002002280284012201450d00200141306c450d00202910350b2000410036020002402027450d002027412c6c450d00202610350b02402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d0b0c0c0b200241003a00b4030b200241d0016a41206a20024190026a41206a280200360200200241d0016a41186a20024190026a41186a2903003703002002280284012201450d002001412c6c450d00202610350b2000410036020002402024450d00202441286c450d00202310350b02402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d080c090b2000410036020002402020450d00202041246c450d00202110350b0240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d070c080b200041003602000240200941ffffff3f71450d00201e10350b0240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d060c070b200041003602000240201a450d00201a411c6c450d00201b10350b02402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d050c060b2000410036020002402016450d00201641186c450d00201810350b02402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d040c050b2000410036020002402011450d00201141146c450d00201510350b0240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d030c040b200041003602000240200341ffffffff0071450d00200f10350b0240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d020c030b200041003602000240200d450d00200d410c6c450d00200c10350b200541ffffffff01710d010c020b20004100360200200541ffffffff0171450d010b200610350b20024190046a24000bbe0102017f017e0240200041046a280200220320016b20024f0d000240024002400240200120026a22022001490d00200341017422012002200120024b1bad421c7e2204422088a70d002004a722014100480d00024020030d0020010d02410421020c040b200028020021022003411c6c22032001460d03024020030d0020010d02410421020c040b20022003200110372202450d020c030b103e000b2001103322020d010b103c000b20002002360200200041046a2001411c6e3602000b0bf70301017f0240200041046a28020041ffffffff0171450d00200028020010350b0240200041106a2802002201450d002001410c6c450d00200028020c10350b02402000411c6a28020041ffffffff0071450d00200028021810350b0240200041286a2802002201450d00200141146c450d00200028022410350b0240200041346a2802002201450d00200141186c450d00200028023010350b0240200041c0006a2802002201450d002001411c6c450d00200028023c10350b0240200041cc006a28020041ffffff3f71450d00200028024810350b0240200041d8006a2802002201450d00200141246c450d00200028025410350b0240200041e4006a2802002201450d00200141286c450d00200028026010350b0240200041f0006a2802002201450d002001412c6c450d00200028026c10350b0240200041fc006a2802002201450d00200141306c450d00200028027810350b024020004188016a2802002201450d00200141346c450d0020002802840110350b024020004194016a2802002201450d00200141386c450d0020002802900110350b0240200041a0016a2802002201450d002001413c6c450d00200028029c0110350b0240200041ac016a28020041ffffff1f71450d0020002802a80110350b0240200041b8016a2802002201450d00200141c4006c450d0020002802b40110350b0be49301032a7f047e247f23004180026b22042400200441b8016a4200370300200441b0016a22054280808080c000370300200441a0016a420037030020044198016a22064280808080c00037030020044188016a420037030020044180016a22074280808080c000370300200441f0006a4200370300200441e8006a22084280808080c000370300200441d8006a4200370300200441d0006a22094280808080c000370300200441c0006a4200370300200441386a220a4280808080c000370300200441286a4200370300200441206a220b4280808080c000370300200441106a4200370300200442043703a8012004420437039001200442043703782004420437036020044204370348200442043703302004420437031820044280808080c000370308200442043703002001280200220c2001280208220d412c6c220e6a210f20012802042110200c2101024002400240200d450d00200441bc016a2111200441b4016a2112200441a8016a2113200441a4016a21142004419c016a211520044190016a21162004418c016a211720044184016a2118200441f8006a2119200441f4006a211a200441ec006a211b200441e0006a211c200441dc006a211d200441d4006a211e200441c8006a211f200441c4006a21202004413c6a2121200441306a21222004412c6a2123200441246a2124200441186a2125200441146a21262004410c6a2127200441086a2128200e41546a210d200441e0016a41086a2129200441e0016a41106a212a200441e0016a41186a212b200c210e0340200e280208212c200e280204212d2029200e41146a290200370300202a200e411c6a290200370300202b200e41246a2902003703002004200e29020c3703e001200e412c6a2101200e280200220e450d01200441c0016a41186a202b290300222e370300200441c0016a41106a202a290300222f370300200441c0016a41086a20292903002230370300200420042903e00122313703c001202b202e370300202a202f37030020292030370300200420313703e001024002400240202c41104d0d00410121320c010b024002400240024002400240024002400240024002400240024002400240024002400240202c0e11000102030405060708090a0b0c0d0e0f10000b0240202d450d00202d41226c450d00200e10350b2001200f460d150c120b4102213220022802082233450d102002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c120b0b20032802082234450d102003280200212c203441057421354100213402400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c120b0b2034418080044f0d1002402004280208222c2004280204470d002004202c41011090012004280208212c0b2004280200202c4103746a222c20343b0104202c20333602002028212c0c0f0b4102213220022802082233450d0f2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c110b0b2003280208222c450d0f41002135202c4105742237213620032802002234212c02400340200e202c460d012035202c200e412010a00822384100476a21352038450d01202c41206a212c203641606a22360d000c110b0b203541ffff034b0d0f200e41226a2136200e2f012021394100212c0240034020362034460d01202c20342036412010a00822384100476a212c2038450d01203441206a2134203741606a22370d000c110b0b202c41ffff034b0d0f0240200428021422322004280210470d00202720324101108701200428021421320b200428020c2032410c6c6a2232202c3b0108203220353b010420322033360200203241066a20393b01002026212c0c0e0b4102213220022802082233450d0e2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c100b0b2003280208222c450d0e41002134202c410574223a213520032802002238212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c100b0b203441ffff034b0d0e200e41226a2136200e2f0120213b41002135203a21372038212c024003402036202c460d012035202c2036412010a00822394100476a21352039450d01202c41206a212c203741606a22370d000c100b0b203541ffff034b0d0e200e41c4006a2136200e41c2006a2f010021394100212c0240034020362038460d01202c20382036412010a00822374100476a212c2037450d01203841206a2138203a41606a223a0d000c100b0b202c41ffff034b0d0e024020042802202232200428021c470d00202520324101108c01200428022021320b200428021820324104746a2232202c3b010c203220343b0104203220333602002032410a6a20393b0100203241086a20353b0100203241066a203b3b0100200b212c0c0d0b4102213220022802082233450d0d2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0f0b0b2003280208222c450d0d41002134202c410574223b213520032802002237212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0f0b0b203441ffff034b0d0d200e41226a2136200e2f0120213c41002135203b21382037212c024003402036202c460d012035202c2036412010a00822394100476a21352039450d01202c41206a212c203841606a22380d000c0f0b0b203541ffff034b0d0d200e41c4006a2138200e41c2006a2f0100213d41002136203b21392037212c024003402038202c460d012036202c2038412010a008223a4100476a2136203a450d01202c41206a212c203941606a22390d000c0f0b0b203641ffff034b0d0d200e41e6006a2138200e41e4006a2f0100213a4100212c0240034020382037460d01202c20372038412010a00822394100476a212c2039450d01203741206a2137203b41606a223b0d000c0f0b0b202c41ffff034b0d0d0240200428022c22322004280228470d00202420324101109901200428022c21320b2004280224203241146c6a2232202c3b0110203220343b0104203220333602002032410e6a203a3b01002032410c6a20363b01002032410a6a203d3b0100203241086a20353b0100203241066a203c3b01002023212c0c0c0b4102213220022802082233450d0c2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0e0b0b2003280208222c450d0c41002134202c410574223b213520032802002239212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0e0b0b203441ffff034b0d0c200e41226a2136200e2f0120213d41002135203b21382039212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c0e0b0b203541ffff034b0d0c200e41c4006a2138200e41c2006a2f0100213e41002136203b21372039212c024003402038202c460d012036202c2038412010a008223a4100476a2136203a450d01202c41206a212c203741606a22370d000c0e0b0b203641ffff034b0d0c200e41e6006a2137200e41e4006a2f0100213f41002138203b213a2039212c024003402037202c460d012038202c2037412010a008223c4100476a2138203c450d01202c41206a212c203a41606a223a0d000c0e0b0b203841ffff034b0d0c200e4188016a2137200e4186016a2f0100213c4100212c0240034020372039460d01202c20392037412010a008223a4100476a212c203a450d01203941206a2139203b41606a223b0d000c0e0b0b202c41ffff034b0d0c0240200428023822322004280234470d00202220324101109701200428023821320b2004280230203241186c6a2232202c3b0114203220343b010420322033360200203241126a203c3b0100203241106a20383b01002032410e6a203f3b01002032410c6a20363b01002032410a6a203e3b0100203241086a20353b0100203241066a203d3b0100200a212c0c0b0b4102213220022802082233450d0b2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0d0b0b2003280208222c450d0b41002134202c410574223c21352003280200223a212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0d0b0b203441ffff034b0d0b200e41226a2136200e2f0120213e41002135203c2138203a212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c0d0b0b203541ffff034b0d0b200e41c4006a2138200e41c2006a2f0100213f41002136203c2137203a212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c0d0b0b203641ffff034b0d0b200e41e6006a2137200e41e4006a2f0100214041002138203c2139203a212c024003402037202c460d012038202c2037412010a008223b4100476a2138203b450d01202c41206a212c203941606a22390d000c0d0b0b203841ffff034b0d0b200e4188016a2139200e4186016a2f0100214141002137203c213b203a212c024003402039202c460d012037202c2039412010a008223d4100476a2137203d450d01202c41206a212c203b41606a223b0d000c0d0b0b203741ffff034b0d0b200e41aa016a2139200e41a8016a2f0100213d4100212c024003402039203a460d01202c203a2039412010a008223b4100476a212c203b450d01203a41206a213a203c41606a223c0d000c0d0b0b202c41ffff034b0d0b0240200428024422322004280240470d0020212032410110f901200428024421320b200428023c2032411c6c6a2232202c3b0118203220343b010420322033360200203241166a203d3b0100203241146a20373b0100203241126a20413b0100203241106a20383b01002032410e6a20403b01002032410c6a20363b01002032410a6a203f3b0100203241086a20353b0100203241066a203e3b01002020212c0c0a0b4102213220022802082233450d0a2002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0c0b0b2003280208222c450d0a41002134202c410574223c21352003280200223a212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0c0b0b203441ffff034b0d0a200e41226a2136200e2f0120213f41002135203c2138203a212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c0c0b0b203541ffff034b0d0a200e41c4006a2138200e41c2006a2f0100214041002136203c2137203a212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c0c0b0b203641ffff034b0d0a200e41e6006a2137200e41e4006a2f0100214141002138203c2139203a212c024003402037202c460d012038202c2037412010a008223b4100476a2138203b450d01202c41206a212c203941606a22390d000c0c0b0b203841ffff034b0d0a200e4188016a2139200e4186016a2f0100214241002137203c213b203a212c024003402039202c460d012037202c2039412010a008223d4100476a2137203d450d01202c41206a212c203b41606a223b0d000c0c0b0b203741ffff034b0d0a200e41aa016a213b200e41a8016a2f0100214341002139203c213d203a212c02400340203b202c460d012039202c203b412010a008223e4100476a2139203e450d01202c41206a212c203d41606a223d0d000c0c0b0b203941ffff034b0d0a200e41cc016a213b200e41ca016a2f0100213e4100212c02400340203b203a460d01202c203a203b412010a008223d4100476a212c203d450d01203a41206a213a203c41606a223c0d000c0c0b0b202c41ffff034b0d0a024020042802502232200428024c470d00201f20324101109101200428025021320b200428024820324105746a2232202c3b011c203220343b0104203220333602002032411a6a203e3b0100203241186a20393b0100203241166a20433b0100203241146a20373b0100203241126a20423b0100203241106a20383b01002032410e6a20413b01002032410c6a20363b01002032410a6a20403b0100203241086a20353b0100203241066a203f3b01002009212c0c090b4102213220022802082233450d092002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0b0b0b2003280208222c450d0941002134202c410574223d21352003280200223b212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0b0b0b203441ffff034b0d09200e41226a2136200e2f0120214041002135203d2138203b212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c0b0b0b203541ffff034b0d09200e41c4006a2138200e41c2006a2f0100214141002136203d2137203b212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c0b0b0b203641ffff034b0d09200e41e6006a2137200e41e4006a2f0100214241002138203d2139203b212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a22390d000c0b0b0b203841ffff034b0d09200e4188016a2139200e4186016a2f0100214341002137203d213a203b212c024003402039202c460d012037202c2039412010a008223c4100476a2137203c450d01202c41206a212c203a41606a223a0d000c0b0b0b203741ffff034b0d09200e41aa016a213a200e41a8016a2f0100214441002139203d213c203b212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203c41606a223c0d000c0b0b0b203941ffff034b0d09200e41cc016a213c200e41ca016a2f010021454100213a203d213e203b212c02400340203c202c460d01203a202c203c412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c0b0b0b203a41ffff034b0d09200e41ee016a213c200e41ec016a2f0100213f4100212c02400340203c203b460d01202c203b203c412010a008223e4100476a212c203e450d01203b41206a213b203d41606a223d0d000c0b0b0b202c41ffff034b0d090240200428025c22322004280258470d00201e20324101108d01200428025c21320b2004280254203241246c6a2232202c3b0120203220343b0104203220333602002032411e6a203f3b01002032411c6a203a3b01002032411a6a20453b0100203241186a20393b0100203241166a20443b0100203241146a20373b0100203241126a20433b0100203241106a20383b01002032410e6a20423b01002032410c6a20363b01002032410a6a20413b0100203241086a20353b0100203241066a20403b0100201d212c0c080b4102213220022802082233450d082002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c0a0b0b2003280208222c450d0841002134202c410574223d21352003280200223b212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c0a0b0b203441ffff034b0d08200e41226a2136200e2f0120214141002135203d2138203b212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c0a0b0b203541ffff034b0d08200e41c4006a2138200e41c2006a2f0100214241002136203d2137203b212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c0a0b0b203641ffff034b0d08200e41e6006a2137200e41e4006a2f0100214341002138203d2139203b212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a22390d000c0a0b0b203841ffff034b0d08200e4188016a2139200e4186016a2f0100214441002137203d213a203b212c024003402039202c460d012037202c2039412010a008223c4100476a2137203c450d01202c41206a212c203a41606a223a0d000c0a0b0b203741ffff034b0d08200e41aa016a213a200e41a8016a2f0100214541002139203d213c203b212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203c41606a223c0d000c0a0b0b203941ffff034b0d08200e41cc016a213c200e41ca016a2f010021464100213a203d213e203b212c02400340203c202c460d01203a202c203c412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c0a0b0b203a41ffff034b0d08200e41ee016a213e200e41ec016a2f010021474100213c203d213f203b212c02400340203e202c460d01203c202c203e412010a00822404100476a213c2040450d01202c41206a212c203f41606a223f0d000c0a0b0b203c41ffff034b0d08200e4190026a213e200e418e026a2f010021404100212c02400340203e203b460d01202c203b203e412010a008223f4100476a212c203f450d01203b41206a213b203d41606a223d0d000c0a0b0b202c41ffff034b0d080240200428026822322004280264470d00201c20324101109d01200428026821320b2004280260203241286c6a2232202c3b0124203220343b010420322033360200203241226a20403b0100203241206a203c3b01002032411e6a20473b01002032411c6a203a3b01002032411a6a20463b0100203241186a20393b0100203241166a20453b0100203241146a20373b0100203241126a20443b0100203241106a20383b01002032410e6a20433b01002032410c6a20363b01002032410a6a20423b0100203241086a20353b0100203241066a20413b01002008212c0c070b4102213220022802082233450d072002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c090b0b2003280208222c450d0741002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c090b0b203441ffff034b0d07200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c090b0b203541ffff034b0d07200e41c4006a2138200e41c2006a2f0100214341002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c090b0b203641ffff034b0d07200e41e6006a2137200e41e4006a2f0100214441002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a22390d000c090b0b203841ffff034b0d07200e4188016a2139200e4186016a2f0100214541002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a0d000c090b0b203741ffff034b0d07200e41aa016a213a200e41a8016a2f0100214641002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b0d000c090b0b203941ffff034b0d07200e41cc016a213b200e41ca016a2f010021474100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c090b0b203a41ffff034b0d07200e41ee016a213e200e41ec016a2f010021484100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f0d000c090b0b203b41ffff034b0d07200e4190026a213f200e418e026a2f010021494100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a22400d000c090b0b203e41ffff034b0d07200e41b2026a213f200e41b0026a2f010021414100212c02400340203f203c460d01202c203c203f412010a00822404100476a212c2040450d01203c41206a213c203d41606a223d0d000c090b0b202c41ffff034b0d070240200428027422322004280270470d00201b20324101109801200428027421320b200428026c2032412c6c6a2232202c3b0128203220343b010420322033360200203241266a20413b0100203241246a203e3b0100203241226a20493b0100203241206a203b3b01002032411e6a20483b01002032411c6a203a3b01002032411a6a20473b0100203241186a20393b0100203241166a20463b0100203241146a20373b0100203241126a20453b0100203241106a20383b01002032410e6a20443b01002032410c6a20363b01002032410a6a20433b0100203241086a20353b0100203241066a20423b0100201a212c0c060b4102213220022802082233450d062002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a22340d000c080b0b2003280208222c450d0641002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a22350d000c080b0b203441ffff034b0d06200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a22380d000c080b0b203541ffff034b0d06200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a22370d000c080b0b203641ffff034b0d06200e41e6006a2137200e41e4006a2f0100214541002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a22390d000c080b0b203841ffff034b0d06200e4188016a2139200e4186016a2f0100214641002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a0d000c080b0b203741ffff034b0d06200e41aa016a213a200e41a8016a2f0100214741002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b0d000c080b0b203941ffff034b0d06200e41cc016a213b200e41ca016a2f010021484100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e0d000c080b0b203a41ffff034b0d06200e41ee016a213e200e41ec016a2f010021494100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f0d000c080b0b203b41ffff034b0d06200e4190026a213f200e418e026a2f0100214a4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a22400d000c080b0b203e41ffff034b0d06200e41b2026a2140200e41b0026a2f0100214b4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d080c000b0b203f41ffff034b0d06200e41d4026a2140200e41d2026a2f010021434100212c024003402040203c460d01202c203c2040412010a00822414100476a212c2041450d01203c41206a213c203d41606a223d450d080c000b0b202c41ffff034b0d0602402004280280012232200428027c470d0020192032410110890120042802800121320b2004280278203241306c6a2232202c3b012c203220343b0104203220333602002032412a6a20433b0100203241286a203f3b0100203241266a204b3b0100203241246a203e3b0100203241226a204a3b0100203241206a203b3b01002032411e6a20493b01002032411c6a203a3b01002032411a6a20483b0100203241186a20393b0100203241166a20473b0100203241146a20373b0100203241126a20463b0100203241106a20383b01002032410e6a20453b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002007212c0c050b4102213220022802082233450d052002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a2234450d070c000b0b2003280208222c450d0541002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a2235450d070c000b0b203441ffff034b0d05200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a2238450d070c000b0b203541ffff034b0d05200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a2237450d070c000b0b203641ffff034b0d05200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a2239450d070c000b0b203841ffff034b0d05200e4188016a2139200e4186016a2f0100214741002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a450d070c000b0b203741ffff034b0d05200e41aa016a213a200e41a8016a2f0100214841002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b450d070c000b0b203941ffff034b0d05200e41cc016a213b200e41ca016a2f010021494100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e450d070c000b0b203a41ffff034b0d05200e41ee016a213e200e41ec016a2f0100214a4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f450d070c000b0b203b41ffff034b0d05200e4190026a213f200e418e026a2f0100214b4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a2240450d070c000b0b203e41ffff034b0d05200e41b2026a2140200e41b0026a2f0100214c4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d070c000b0b203f41ffff034b0d05200e41d4026a2141200e41d2026a2f0100214d41002140203d2143203c212c024003402041202c460d012040202c2041412010a00822454100476a21402045450d01202c41206a212c204341606a2243450d070c000b0b204041ffff034b0d05200e41f6026a2141200e41f4026a2f010021454100212c024003402041203c460d01202c203c2041412010a00822434100476a212c2043450d01203c41206a213c203d41606a223d450d070c000b0b202c41ffff034b0d050240200428028c012232200428028801470d0020182032410110a501200428028c0121320b200428028401203241346c6a2232202c3b0130203220343b0104203220333602002032412e6a20453b01002032412c6a20403b01002032412a6a204d3b0100203241286a203f3b0100203241266a204c3b0100203241246a203e3b0100203241226a204b3b0100203241206a203b3b01002032411e6a204a3b01002032411c6a203a3b01002032411a6a20493b0100203241186a20393b0100203241166a20483b0100203241146a20373b0100203241126a20473b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002017212c0c040b4102213220022802082233450d042002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a2234450d060c000b0b2003280208222c450d0441002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a2235450d060c000b0b203441ffff034b0d04200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a2238450d060c000b0b203541ffff034b0d04200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a2237450d060c000b0b203641ffff034b0d04200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a2239450d060c000b0b203841ffff034b0d04200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a450d060c000b0b203741ffff034b0d04200e41aa016a213a200e41a8016a2f0100214941002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b450d060c000b0b203941ffff034b0d04200e41cc016a213b200e41ca016a2f0100214a4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e450d060c000b0b203a41ffff034b0d04200e41ee016a213e200e41ec016a2f0100214b4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f450d060c000b0b203b41ffff034b0d04200e4190026a213f200e418e026a2f0100214c4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a2240450d060c000b0b203e41ffff034b0d04200e41b2026a2140200e41b0026a2f0100214d4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d060c000b0b203f41ffff034b0d04200e41d4026a2141200e41d2026a2f0100214e41002140203d2143203c212c024003402041202c460d012040202c2041412010a00822454100476a21402045450d01202c41206a212c204341606a2243450d060c000b0b204041ffff034b0d04200e41f6026a2143200e41f4026a2f0100214f41002141203d2145203c212c024003402043202c460d012041202c2043412010a00822474100476a21412047450d01202c41206a212c204541606a2245450d060c000b0b204141ffff034b0d04200e4198036a2143200e4196036a2f010021474100212c024003402043203c460d01202c203c2043412010a00822454100476a212c2045450d01203c41206a213c203d41606a223d450d060c000b0b202c41ffff034b0d0402402004280298012232200428029401470d0020162032410110a20120042802980121320b200428029001203241386c6a2232202c3b0134203220343b010420322033360200203241326a20473b0100203241306a20413b01002032412e6a204f3b01002032412c6a20403b01002032412a6a204e3b0100203241286a203f3b0100203241266a204d3b0100203241246a203e3b0100203241226a204c3b0100203241206a203b3b01002032411e6a204b3b01002032411c6a203a3b01002032411a6a204a3b0100203241186a20393b0100203241166a20493b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002006212c0c030b4102213220022802082233450d032002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a2234450d050c000b0b2003280208222c450d0341002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a2235450d050c000b0b203441ffff034b0d03200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a2238450d050c000b0b203541ffff034b0d03200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a2237450d050c000b0b203641ffff034b0d03200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a2239450d050c000b0b203841ffff034b0d03200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a450d050c000b0b203741ffff034b0d03200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b450d050c000b0b203941ffff034b0d03200e41cc016a213b200e41ca016a2f0100214b4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e450d050c000b0b203a41ffff034b0d03200e41ee016a213e200e41ec016a2f0100214c4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f450d050c000b0b203b41ffff034b0d03200e4190026a213f200e418e026a2f0100214d4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a2240450d050c000b0b203e41ffff034b0d03200e41b2026a2140200e41b0026a2f0100214e4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d050c000b0b203f41ffff034b0d03200e41d4026a2141200e41d2026a2f0100214f41002140203d2143203c212c024003402041202c460d012040202c2041412010a00822454100476a21402045450d01202c41206a212c204341606a2243450d050c000b0b204041ffff034b0d03200e41f6026a2143200e41f4026a2f0100215041002141203d2145203c212c024003402043202c460d012041202c2043412010a00822474100476a21412047450d01202c41206a212c204541606a2245450d050c000b0b204141ffff034b0d03200e4198036a2145200e4196036a2f0100215141002143203d2147203c212c024003402045202c460d012043202c2045412010a00822494100476a21432049450d01202c41206a212c204741606a2247450d050c000b0b204341ffff034b0d03200e41ba036a2145200e41b8036a2f010021494100212c024003402045203c460d01202c203c2045412010a00822474100476a212c2047450d01203c41206a213c203d41606a223d450d050c000b0b202c41ffff034b0d03024020042802a401223220042802a001470d0020152032410110aa0120042802a40121320b200428029c012032413c6c6a2232202c3b0138203220343b010420322033360200203241366a20493b0100203241346a20433b0100203241326a20513b0100203241306a20413b01002032412e6a20503b01002032412c6a20403b01002032412a6a204f3b0100203241286a203f3b0100203241266a204e3b0100203241246a203e3b0100203241226a204d3b0100203241206a203b3b01002032411e6a204c3b01002032411c6a203a3b01002032411a6a204b3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002014212c0c020b4102213220022802082233450d022002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a2234450d040c000b0b2003280208222c450d0241002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a2235450d040c000b0b203441ffff034b0d02200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a2238450d040c000b0b203541ffff034b0d02200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a2237450d040c000b0b203641ffff034b0d02200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a2239450d040c000b0b203841ffff034b0d02200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a450d040c000b0b203741ffff034b0d02200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b450d040c000b0b203941ffff034b0d02200e41cc016a213b200e41ca016a2f0100214c4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e450d040c000b0b203a41ffff034b0d02200e41ee016a213e200e41ec016a2f0100214d4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f450d040c000b0b203b41ffff034b0d02200e4190026a213f200e418e026a2f0100214e4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a2240450d040c000b0b203e41ffff034b0d02200e41b2026a2140200e41b0026a2f0100214f4100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d040c000b0b203f41ffff034b0d02200e41d4026a2141200e41d2026a2f0100215041002140203d2143203c212c024003402041202c460d012040202c2041412010a00822454100476a21402045450d01202c41206a212c204341606a2243450d040c000b0b204041ffff034b0d02200e41f6026a2143200e41f4026a2f0100215141002141203d2145203c212c024003402043202c460d012041202c2043412010a00822474100476a21412047450d01202c41206a212c204541606a2245450d040c000b0b204141ffff034b0d02200e4198036a2145200e4196036a2f0100215241002143203d2147203c212c024003402045202c460d012043202c2045412010a00822494100476a21432049450d01202c41206a212c204741606a2247450d040c000b0b204341ffff034b0d02200e41ba036a2147200e41b8036a2f0100215341002145203d2149203c212c024003402047202c460d012045202c2047412010a008224b4100476a2145204b450d01202c41206a212c204941606a2249450d040c000b0b204541ffff034b0d02200e41dc036a2147200e41da036a2f0100214b4100212c024003402047203c460d01202c203c2047412010a00822494100476a212c2049450d01203c41206a213c203d41606a223d450d040c000b0b202c41ffff034b0d02024020042802b001223220042802ac01470d0020132032410110a60120042802b00121320b20042802a80120324106746a2232202c3b013c203220343b0104203220333602002032413a6a204b3b0100203241386a20453b0100203241366a20533b0100203241346a20433b0100203241326a20523b0100203241306a20413b01002032412e6a20513b01002032412c6a20403b01002032412a6a20503b0100203241286a203f3b0100203241266a204f3b0100203241246a203e3b0100203241226a204e3b0100203241206a203b3b01002032411e6a204d3b01002032411c6a203a3b01002032411a6a204c3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002005212c0c010b4102213220022802082233450d012002280200212c203341057421344100213302400340200441e0016a202c460d012033202c200441e0016a412010a00822354100476a21332035450d01202c41206a212c203441606a2234450d030c000b0b2003280208222c450d0141002134202c410574223d21352003280200223c212c02400340200e202c460d012034202c200e412010a00822364100476a21342036450d01202c41206a212c203541606a2235450d030c000b0b203441ffff034b0d01200e41226a2136200e2f0120214241002135203d2138203c212c024003402036202c460d012035202c2036412010a00822374100476a21352037450d01202c41206a212c203841606a2238450d030c000b0b203541ffff034b0d01200e41c4006a2138200e41c2006a2f0100214441002136203d2137203c212c024003402038202c460d012036202c2038412010a00822394100476a21362039450d01202c41206a212c203741606a2237450d030c000b0b203641ffff034b0d01200e41e6006a2137200e41e4006a2f0100214641002138203d2139203c212c024003402037202c460d012038202c2037412010a008223a4100476a2138203a450d01202c41206a212c203941606a2239450d030c000b0b203841ffff034b0d01200e4188016a2139200e4186016a2f0100214841002137203d213a203c212c024003402039202c460d012037202c2039412010a008223b4100476a2137203b450d01202c41206a212c203a41606a223a450d030c000b0b203741ffff034b0d01200e41aa016a213a200e41a8016a2f0100214a41002139203d213b203c212c02400340203a202c460d012039202c203a412010a008223e4100476a2139203e450d01202c41206a212c203b41606a223b450d030c000b0b203941ffff034b0d01200e41cc016a213b200e41ca016a2f0100214c4100213a203d213e203c212c02400340203b202c460d01203a202c203b412010a008223f4100476a213a203f450d01202c41206a212c203e41606a223e450d030c000b0b203a41ffff034b0d01200e41ee016a213e200e41ec016a2f0100214e4100213b203d213f203c212c02400340203e202c460d01203b202c203e412010a00822404100476a213b2040450d01202c41206a212c203f41606a223f450d030c000b0b203b41ffff034b0d01200e4190026a213f200e418e026a2f0100214f4100213e203d2140203c212c02400340203f202c460d01203e202c203f412010a00822414100476a213e2041450d01202c41206a212c204041606a2240450d030c000b0b203e41ffff034b0d01200e41b2026a2140200e41b0026a2f010021504100213f203d2141203c212c024003402040202c460d01203f202c2040412010a00822434100476a213f2043450d01202c41206a212c204141606a2241450d030c000b0b203f41ffff034b0d01200e41d4026a2141200e41d2026a2f0100215141002140203d2143203c212c024003402041202c460d012040202c2041412010a00822454100476a21402045450d01202c41206a212c204341606a2243450d030c000b0b204041ffff034b0d01200e41f6026a2143200e41f4026a2f0100215241002141203d2145203c212c024003402043202c460d012041202c2043412010a00822474100476a21412047450d01202c41206a212c204541606a2245450d030c000b0b204141ffff034b0d01200e4198036a2145200e4196036a2f0100215341002143203d2147203c212c024003402045202c460d012043202c2045412010a00822494100476a21432049450d01202c41206a212c204741606a2247450d030c000b0b204341ffff034b0d01200e41ba036a2147200e41b8036a2f0100215441002145203d2149203c212c024003402047202c460d012045202c2047412010a008224b4100476a2145204b450d01202c41206a212c204941606a2249450d030c000b0b204541ffff034b0d01200e41dc036a2149200e41da036a2f0100215541002147203d214b203c212c024003402049202c460d012047202c2049412010a008224d4100476a2147204d450d01202c41206a212c204b41606a224b450d030c000b0b204741ffff034b0d01200e41fe036a2149200e41fc036a2f0100214d4100212c024003402049203c460d01202c203c2049412010a008224b4100476a212c204b450d01203c41206a213c203d41606a223d450d030c000b0b202c41ffff034b0d01024020042802bc01223220042802b801470d00201220324101109f0120042802bc0121320b20042802b401203241c4006c6a2232202c3b0140203220343b0104203220333602002032413e6a204d3b01002032413c6a20473b01002032413a6a20553b0100203241386a20453b0100203241366a20543b0100203241346a20433b0100203241326a20533b0100203241306a20413b01002032412e6a20523b01002032412c6a20403b01002032412a6a20513b0100203241286a203f3b0100203241266a20503b0100203241246a203e3b0100203241226a204f3b0100203241206a203b3b01002032411e6a204e3b01002032411c6a203a3b01002032411a6a204c3b0100203241186a20393b0100203241166a204a3b0100203241146a20373b0100203241126a20483b0100203241106a20383b01002032410e6a20463b01002032410c6a20363b01002032410a6a20443b0100203241086a20353b0100203241066a20423b01002011212c0b202c202c28020041016a3602000240202d450d00202d41226c450d00200e10350b2001200f460d040c010b200041013a0000200020323a00010240202d450d00202d41226c450d00200e10350b0240200f2001460d0003400240200141046a280200220e450d00200e41226c450d00200128020010350b2001412c6a2101200d41546a220d0d000b0b02402010450d002010412c6c450d00200c10350b200410fa010c040b200d41546a210d2001210e0c000b0b200f2001460d0003402001220d412c6a21010240200d41046a280200220e450d00200e41226c450d00200d28020010350b200f2001470d000b0b02402010450d002010412c6c450d00200c10350b200041046a200441c001109d081a200041003a00000b20044180026a24000bdb0401097f230041c0016b2202240020024188016a200110b701200241306a200228028801220320022802900110d60120024198016a41086a2204200241ec006a29020037030020024198016a41106a2205200241f4006a29020037030020024198016a41186a2206200241fc006a29020037030020024198016a41206a220720024184016a2802003602002002200241e4006a290200370398010240024020022802502208450d00200241e0006a2802002109200241dc006a280200210a20022802542101200241086a41206a2007280200360200200241086a41186a2006290300370300200241086a41106a2005290300370300200241086a41086a200429030037030020022002290398013703080240200228028c01450d00200310350b200241306a41106a200241086a41106a290300370300200241306a41086a200241086a41086a290300370300200241306a41186a200241086a41186a290300370300200241306a41206a200241086a41206a28020036020020024198016a41086a2002413c6a29020037030020024198016a41106a200241c4006a29020037030020024198016a41186a200241cc006a29020037030020022002290308370330200220022902343703980102402001450d00200141186c450d00200810350b0240200941ffffffff0371450d00200a10350b2000200229039801370001200041196a200241b0016a290300370000200041116a200241a8016a290300370000200041096a200241a0016a290300370000410121010c010b0240200228028c01450d00200310350b410021010b200020013a0000200241c0016a24000bea4711047f017e017f017e0c7f017e017f017e067f027e027f037e017f017e047f017e017f23004180046b22052400200541f8026a41186a22064200370300200541f8026a41106a22074200370300200541f8026a41086a22084200370300200542003703f80241f7edcb00ad4280808080f0008422091001220a290000210b200541a8026a41086a220c200a41086a2900003703002005200b3703a802200a10352008200c290300370300200520052903a8023703f80241b6aac000ad42808080809002841001220a290000210b200541b8026a41086a220d200a41086a2900003703002005200b3703b802200a1035200720052903b802220b370300200541b8036a41086a220a2008290300370300200541b8036a41106a220e200b370300200541b8036a41186a220f200d290300370300200520052903f8023703b803200541e0016a200541b8036a10f20141012110024020052802e001417d710d00200642003703002007420037030020084200370300200542003703f802200910012210290000210b200c201041086a2900003703002005200b3703a802201010352008200c290300370300200520052903a8023703f802419beecb00ad4280808080b002841001220c290000210b200d200c41086a2900003703002005200b3703b802200c1035200720052903b802370000200741086a200d290300370000200a2008290300370300200e2007290300370300200f2006290300370300200520052903f8023703b803200541203602bc022005200541b8036a3602b802200541e8016a200541b8036aad42808080808004842209100510c201410021100240024020052802e80122080d00410021110c010b20052802ec01210a02400240200541f0016a2802004104490d00410121112008280000220f418194ebdc03490d010b4100211120054100360290022005420137038802200541093602e4032005200541b8026a3602e003200520054188026a3602a8022005418c036a4101360200200542013702fc02200541c888c2003602f8022005200541e0036a36028803200541a8026a41e88ac500200541f8026a10431a200535029002422086200535028802841006200528028c02450d0020052802880210350b200a450d00200810350b200541f8026a41186a220d4200370300200541f8026a41106a220c4200370300200541f8026a41086a22084200370300200542003703f80241f7edcb00ad4280808080f000841001220a290000210b200541a8026a41086a2206200a41086a2900003703002005200b3703a802200a103520082006290300370300200520052903a8023703f80241eeedcb00ad42808080809001841001220a290000210b200541b8026a41086a2206200a41086a2900003703002005200b3703b802200a1035200720052903b802370000200741086a2006290300370000200541b8036a41086a2008290300370300200541b8036a41106a200c290300370300200541b8036a41186a200d290300370300200520052903f8023703b803200541f8026a200541b8036a10ac0120052903f8024202510d00200541f8026a200c280200221210b801200541d8016a20052802f802220a20052802800310c00120052802dc01210c20052802d8012108024020052802fc02450d00200a10350b02400240024020080d0041fdb5c000ad4280808080e0068410064100201241e07a6a2208200820124b1b2113201221140c010b4100201241e07a6a2208200820124b1b21130240200c20044b0d00201221140c010b200541f8026a41186a220c4200370300200541f8026a41106a220d4200370300200541f8026a41086a22084200370300200542003703f80241f7edcb00ad4280808080f000841001220a290000210b200541a8026a41086a2206200a41086a2900003703002005200b3703a802200a103520082006290300370300200520052903a8023703f80241aeeecb00ad4280808080a001841001220a290000210b200541b8026a41086a2206200a41086a2900003703002005200b3703b802200a1035200720052903b802370000200741086a2006290300370000200541b8036a41086a2008290300370300200541b8036a41106a200d290300370300200541b8036a41186a200c290300370300200520052903f8023703b803200541f8026a200541b8036a10d90120052802f8022208410420081b220d20052902fc02420020081b220b422088a741037422086a210a03402008450d02200841786a2108200a417c6a210c200a41786a210a200c28020020044b0d000b200d20086a2802002114200b42ffffffff0183500d00200d10350b200541f8026a41186a22154200370300200541f8026a41106a22164200370300200541f8026a41086a22174200370300200542003703f80241f7edcb00ad4280808080f00084221810012208290000210b200541a8026a41086a2219200841086a2900003703002005200b3703a8022008103520172019290300370300200520052903a8023703f80241b8eecb00ad4280808080e00284220b10012208290000211a200541b8026a41086a221b200841086a2900003703002005201a3703b80220081035200720052903b802370000200741086a221c201b290300370000200541b8036a41086a220e2017290300370300200541b8036a41106a221d2016290300370300200541b8036a41186a221e2015290300370300200520052903f8023703b803200541d0016a200541b8036a412010c00120052802d401210a20052802d001210c201542003703002016420037030020174200370300200542003703f802201810012208290000211a2019200841086a2900003703002005201a3703a8022008103520172019290300370300200520052903a8023703f802200b10012208290000210b201b200841086a2900003703002005200b3703b80220081035200720052903b802370000201c201b290300370000200e2017290300370300201d2016290300370300201e2015290300370300200520052903f8023703b8032005200a2012200c4101461b3602f8022009200541f8026aad220b4280808080c00084100220032001200120034b1b221f450d01200f410020111b2120200541a8036aad4280808080c000842121200b42808080808002842122200541a8036a41046a2123200541e0036a41086a2111200021034100212402400240024002400340201542003703002016420037030020174200370300200542003703f802201810012208290000210b2019200841086a2900003703002005200b3703a8022008103520172019290300370300200520052903a8023703f8024194c4c100ad4280808080d0018410012208290000210b201b200841086a2900003703002005200b3703b80220081035200720052903b802370000201c201b290300370000200e2017290300370300201d2016290300370300201e2015290300370300200520052903f8023703b803200541f8026a200541b8036a10fe0120052902fc02420020052802f80222081b220b422088a7410574210a2024220c41016a21242002200c4102746a21042000200c41e0006c6a210f2008410120081b22102108024003400240200a0d004100210d0c020b4101210d20032008460d012008200f412010a008210c200a41606a210a200841206a2108200c0d000b0b0240200b42ffffff3f83500d00201010350b0240200d0d0020042802002108200542003703b002200542003703a802200541c0016a200f290320220b200f41286a290300428094ebdc034200109808200541a0016a200f2903302209200f41386a290300428094ebdc034200109808200541b0016a20052903c001221a200541c0016a41086a29030022254280ec94a37c427f108408200541f0006a201a20252008ad2226420010840820054190016a20052903a001221a200541a0016a41086a29030022254280ec94a37c427f10840820054180016a201a202520264200108408200542003703c002200542003703b802202620092005290390017c7e221a428094ebdc0380212502400240200529037042002026200b20052903b0017c7e220b428094ebdc03802209a7417f200b428080808080c0b2cd3b541b200b20094280ec94a37c7e7c4280cab5ee01566a220aad7d85200541f0006a41086a2903004200200a410047ad7d8584500d00200529038001210920054180016a41086a2903002127200541e8016a2014200f10b20120052802e801210a200520052802f001220c3602f4032005200a3602f00320054188026a200cad422086200aad84100510c20102400240200528028802220c0d004200210b0c010b200528028c0221100240024020052802900222044104490d00200c280000220d418094ebdc034b0d004201210b2004417c6a410f4b0d010b200541003602c003200542013703b803200541093602e4032005200541f0036a3602e0032005200541b8036a3602a8032005410136028c03200542013702fc02200541c888c2003602f8022005200541e0036a36028803200541a8036a41e88ac500200541f8026a10431a20053502c00342208620053502b803841006024020052802bc03450d0020052802b80310350b4200210b2028210d0b02402010450d00200c10350b200d21280b024020052802ec01450d00200a10350b200820284100200b4200521b22064d0d02200541f8026a2014200f10b201200535028003212920052802f802210c41101033220a0d010c070b200542003703f001200542003703e80120054200370390022005420037038802200541f0036a200f10ba01200541b8036a20052802f003220a20052802f80310bc012011200e280200360200200520052903b8033703e003024020052802c4032208450d00200541a8036a41086a2011280200360200200520052903e0033703a80320052903c803210b0b024020052802f403450d00200a10350b0240024020080d00200542003703c80320054280808080c0003703c003200520133602bc03200541003602b803200541f0036a200f10ba0120052802f0032108200520052802f8033602e403200520083602e003200541b8036a200541e0036a10ff01024020052802f403450d00200810350b2011200e280200360200200520052903b8033703e00320052903c803210b410421080c010b2011200541a8036a41086a280200360200200520052903a8033703e0030b201720052903e003370200201741086a2011280200360200200541003a00a4032005200f3602fc02200520133602f802200520203602a0032005200b370390032005200836028c03200520054188026a36029c032005200541e8016a36029803200541b8036a200541f8026a2014108002024020052802c0034102460d0020052802b803200528028003470d002017201210810221082005410120052d00a40320081b22083a00a403200541b8036a200f10b50120053502c00342208620052802b803220aad841007024020052802bc03450d00200a10350b200541b8036a200f10b90120053502c00342208620052802b803220aad841007024020052802bc03450d00200a10350b0240200f10820241ff0171220a4102460d00200a410171450d0010e4010b200841ff0171450d00200528029403220f41027421084101210d200528028c03210a200528028003210120052802f80221042005280284032206210c02400340024020080d00200520062004200620044b1b360284030c020b200d417f6a210d2008417c6a2108200c20044b2110200c200a2802006b210c200a41046a210a20100d000b200f21080240200f2010200d6b220a490d002005200a36029403200a21080b200520062004200620044b1b3602840341000d002001200f6b220a200120086b4f0d00200f20086b210c20052802fc0221080340201e200841186a290000370300201d200841106a290000370300200e200841086a290000370300200520082900003703b8032005200a3602d803200541f0036a200541b8036a10b60120053502f80342208620052802f003220dad841007024020052802f403450d00200d10350b200a41016a210a200c417f6a220c0d000b0b200541b8036a20052802fc0210ba0120052802b8032108200520052802c0033602f403200520083602f0032017200541f0036a10ff0120052802bc03450d00200810350b20052802900341ffffffff0371450d01200528028c0310350c010b200a2008360000200a4110412010372208450d04200820092025a7417f201a428080808080c0b2cd3b541b201a20254280ec94a37c7e7c4280cab5ee01566aad7c220b3700042008410c6a2027200b200954ad7c221a3700002029422086200cad842008ad4280808080c00284100220081035024020052802fc02450d00200c10350b20054188026a200f10ba01200541b8036a200528028802220a20052802900210bc012011200e280200360200200520052903b8033703e003024020052802c4032208450d00200541e8016a41086a2011280200360200200520052903e0033703e80120052903c80321090b0240200528028c02450d00200a10350b0240024020080d00200542003703c80320054280808080c0003703c003200520133602bc03200541003602b80320054188026a200f10ba01200528028802210820052005280290023602f403200520083602f003200541b8036a200541f0036a10ff010240200528028c02450d00200810350b200541f0036a41086a200e280200360200200520052903b8033703f00320052903c8032109410421080c010b200541f0036a41086a200541e8016a41086a280200360200200520052903e8013703f0030b201720052903f003370200201741086a222a200541f0036a41086a280200360200200541003a00a4032005200f3602fc02200520133602f802200520203602a00320052009370390032005200836028c032005200541b8026a36029c032005200541a8026a36029803200541e8006a200541f8026a2014200b201a10830202400240024020052802684101470d00200528026c200528028003460d010b20052d00a40321080c010b2017201210810221082005410120052d00a40320081b22083a00a403200541b8036a200f10b50120053502c00342208620052802b803220aad841007024020052802bc03450d00200a10350b200541b8036a200f10b90120053502c00342208620052802b803220aad841007024020052802bc03450d00200a10350b200f10820241ff0171220a4102460d00200a410171450d0010e4010b0240200841ff0171450d00200528029403222b41027421084101210d200528028c03210a200528028003212c20052802f80221042005280284032201210c02400340024020080d00200520012004200120044b1b360284030c020b200d417f6a210d2008417c6a2108200c20044b2110200c200a2802006b210c200a41046a210a20100d000b202b21080240202b2010200d6b220a490d002005200a36029403200a21080b200520012004200120044b1b3602840341000d00202c202b6b220a202c20086b4f0d00202b20086b210c20052802fc0221080340201e200841186a290000370300201d200841106a290000370300200e200841086a290000370300200520082900003703b8032005200a3602d80320054188026a200541b8036a10b601200535029002422086200528028802220dad8410070240200528028c02450d00200d10350b200a41016a210a200c417f6a220c0d000b0b200541b8036a20052802fc0210ba0120052802b8032108200520052802c00336028c022005200836028802201720054188026a10ff0120052802bc03450d00200810350b024020052802900341ffffffff0371450d00200528028c0310350b200541003602d002200542083703c802200542003703f001200542003703e801200541c8026a4100200f41c8006a220828020010880102400240200828020022080d004200210920052802c802210d4200211a0c010b200f2802402201200841306c6a212d2006ad2127034020054200370390022005420037038802200541c0006a2001290300221a200141086a290300428094ebdc034200109808200541306a2005290340220b200541c0006a41086a29030022094280ec94a37c427f108408200541206a200b200920274200108408200541106a200b200920264200108408200541f8026a2014200141106a220610b301200541d0006a20052802f802220a20052802800310d7014200200541106a41086a290300200529031022092026201a20052903307c221a7e220b428094ebdc03802225a7417f200b428080808080c0b2cd3b541b200b20254280ec94a37c7e7c4280cab5ee01566aad7c220b200954ad7c2209200541206a41086a290300200529032022252027201a7e221a428094ebdc03802229a7417f201a428080808080c0b2cd3b541b201a20294280ec94a37c7e7c4280cab5ee01566aad7c221a202554ad7c7d200b201a54ad7d2225200b201a7d221a200b56202520095620252009511b22081b21094200201a20081b210b200541d0006a41106a290300211a2005290358212520052802502108024020052802fc02450d00200a10350b200541b8036a2014200610b30120052802b803210a20053502c003212920052025420020081b2225200b7c220b3703f8022005201a420020081b20097c200b202554ad7c2209370380032029422086200aad8420221002024020052802bc03450d00200a10350b200541f0036a200610ba01200541b8036a20052802f003220a20052802f80310bc012011200e280200360200200520052903b8033703e003024020052802c4032208450d00200541a8036a41086a2011280200360200200520052903e0033703a80320052903c803212e0b024020052802f403450d00200a10350b0240024020080d00200542003703c80320054280808080c0003703c003200520133602bc03200541003602b803200541f0036a200610ba0120052802f0032108200520052802f8033602e403200520083602e003200541b8036a200541e0036a10ff01024020052802f403450d00200810350b2011200e280200360200200520052903b8033703e00320052903c803211a410421080c010b2011200541a8036a41086a280200360200200520052903a8033703e003202e211a0b201720052903e003370200202a2011280200360200200541003a00a403200520063602fc02200520133602f802200520203602a0032005201a370390032005200836028c03200520054188026a36029c032005200541e8016a36029803200541086a200541f8026a2014200b20091083020240024020052802084101470d00200528020c200528028003470d002017201210810221082005410120052d00a40320081b22083a00a4030c010b20052d00a40321080b0240200841ff0171450d00200528029403222c41027421084101210d200528028c03210a200528028003212f20052802f8022104200528028403222b210c02400340024020080d002005202b2004202b20044b1b360284030c020b200d417f6a210d2008417c6a2108200c20044b2110200c200a2802006b210c200a41046a210a20100d000b202c21080240202c2010200d6b220a490d002005200a36029403200a21080b2005202b2004202b20044b1b3602840341000d00202f202c6b220a202f20086b4f0d00202c20086b210c20052802fc0221080340201e200841186a290000370300201d200841106a290000370300200e200841086a290000370300200520082900003703b8032005200a3602d803200541f0036a200541b8036a10b60120053502f80342208620052802f003220dad841007024020052802f403450d00200d10350b200a41016a210a200c417f6a220c0d000b0b200541b8036a20052802fc0210ba0120052802b8032108200520052802c0033602f403200520083602f0032017200541f0036a10ff0120052802bc03450d00200810350b024020052802900341ffffffff0371450d00200528028c0310350b200141306a2101200641086a290000210b200629000021092015200641186a2900003703002016200641106a2900003703002017200b370300200520093703f80220054188026a41086a290300210b2005290388022109024020052802d002220a20052802cc02470d00200541c8026a200a410110880120052802d002210a0b20052802c802220d200a41306c6a22082009370320200820052903f802370300200841286a200b370300200841086a2017290300370300200841106a2016290300370300200841186a20152903003703002005200a41016a3602d0022001202d470d000b200541e8016a41086a290300211a20052903e80121090b2019290300212520052903a802210b200541e8016a41086a2208200f41086a290300370300200541e8016a41106a220a200f41106a290300370300200541e8016a41186a220c200f41186a2903003703002005200f2903003703e801200d450d00201b290300212620052903b802212720052902cc02212920054188026a41186a2204200c29030037030020054188026a41106a2201200a29030037030020054188026a41086a222b2008290300370300200520052903e80137038802200f280258221041ffffff3f712010470d022010410574220c417f4c0d02200f280250210802400240200c0d004101210a0c010b200c1033220a450d060b20054100360280032005200a3602f8022005200c4105763602fc02200541f8026a41002010108a0120052802800321060240024020100d0020052802f802212c0c010b20052802f802222c20064105746a210a0340200a2008290000370000200a41186a200841186a290000370000200a41106a200841106a290000370000200a41086a200841086a290000370000200a41206a210a200841206a2108200c41606a220c0d000b201041057441606a41057620066a41016a21060b20052802fc02212f201e2004290300370300201d2001290300370300200e202b29030037030020052005290388023703b803201810012208290000212e2019200841086a2900003703002005202e3703a8022008103541efb6c000ad428080808080028410012208290000212e201b200841086a2900003703002005202e3703b80220081035200520123602a80320052021100322082900003703e003200810352005202336028403200520113602fc022005200541a8036a360280032005200541e0036a3602f802200541f0036a200541f8026a107b20052802f803220441206a220a417f4c0d0220052802f003210f02400240200a0d0041002108410121100c010b200a10332210450d06200a21080b024002402008410f4d0d002008210c0c010b2008410174220c4110200c41104b1b220c4100480d04024020080d00200c103322100d010c060b2008200c460d0020102008200c10372210450d050b201020052903a802370000201041086a201929030037000002400240200c4170714110460d00200c21080c010b200c41017422084120200841204b1b22084100480d04200c2008460d002010200c200810372210450d050b201020052903b802370010201041186a201b29030037000002400240200841606a2004490d00200821010c010b2004415f4b0d042008410174220c200a200c200a4b1b22014100480d0420082001460d0020102008200110372210450d050b200b20097c2209200b542108201041206a200f2004109d081a024020052802f403450d00200f10350b2025201a7c210b2008ad211a200541f8026a2010200a10dd010240024020052802f80222040d004100210f200541003602c002200542083703b802410821044100210c0c010b200520052902fc0222253702bc02200520043602b8022025422088a7210c2025a7210f0b200b201a7c210b2015201e2903003703002016201d2903003703002017200e290300370300200520052903b8033703f8020240200c200f470d00200541b8026a200c4101109b0120052802bc02210f20052802b802210420052802c002210c0b2004200c41d8006c222b6a2208200937031020082026370308200820273703002008202c36022c2008200d360220200841186a200b370300200841346a2006360200200841306a202f360200200841246a2029370200200820052903f802370338200841c0006a2017290300370300200841c8006a2016290300370300200841d0006a20152903003703002005200c41016a22083602c0020240024020040d00200aad4220862010ad8410070c010b200541f8026a2004200810ea01200aad4220862010ad8420053502800342208620052802f802220aad841002024020052802fc02450d00200a10350b02402008450d00200441306a2108202b41d8006a210a03400240200841746a280200220c450d00200c41306c450d00200841706a28020010350b0240200828020041ffffff3f71450d002008417c6a28020010350b200841d8006a2108200a41a87f6a220a0d000b0b200f450d00200f41d8006c450d00200410350b2001450d00201010350b200341e0006a21032024201f490d000b410021100c050b1044000b103e000b103c000b1045000b41002110200b42ffffffff0183500d00200d10350b20054180046a240020100bbf0201027f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a10c3010240024020022802480d0020024100360230200242013703282002410936023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b200041003602000c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2003450d00200110350b200241e0006a24000b8f0301067f230041106b220224002002410036020820024201370300200028020021030240410410332204450d002004200336000020024284808080c000370204200220043602002000280204210320044104410810372204450d0020042003360004200242888080808001370204200220043602002000280208210320044108411010372204450d002004200336000820024290808080c00137020420022004360200200028020c2105200041146a28020022002002107702400240024020022802042206200228020822046b20004102742203490d0020022802002100200621070c010b200420036a22002004490d01200641017422072000200720004b1b22074100480d010240024020060d00024020070d00410121000c020b2007103322000d010c040b2002280200210020062007460d0020002006200710372200450d030b20022007360204200220003602000b200020046a20052003109d081a2001290200200420036aad4220862000ad84100202402007450d00200010350b200241106a24000f0b103e000b103c000bbd0101057f2001280208210302402001410c6a280200220420024b0d002000410036020820002004ad4220862003ad843702000f0b024002402001411c6a2802002205450d00200141146a2802002101200541027421062003417f6a2103034002402004200128020022076b220520024b0d00200420024b0d030b200141046a21012003417f6a2103200521042006417c6a22060d000b0b200041023602080f0b2000200736020c2000410136020820002005ad4220862003ad843702000ba00201067f410021020240200141016a2203200028020422044d0d000240200041146a22052802002201200041106a280200470d000240024002400240200141016a22022001490d00200141017422062002200620024b1b220241ffffffff03712002470d00200241027422024100480d00024020010d0020020d02410421060c040b200028020c2106200141027422072002460d03024020070d0020020d02410421060c040b20062007200210372206450d020c030b103e000b2002103322060d010b103c000b2000200636020c200041106a20024102763602000b200028020c220241046a20022001410274109e081a2002200320046b36020020002003360204410121022005200141016a3602002000200028020041016a3602000b20020bd20f07047f017e047f017e047f017e017f23004190016b22012400200141386a41186a4200370300200141386a41106a22024200370300200141386a41086a220342003703002001420037033841a3edcb00ad4280808080f000841001220429000021052003200441086a290000370300200120053703382004103541f393ca00ad4280808080a00184100122042900002105200141286a41086a2206200441086a2900003703002001200537032820041035200220012903282205370300200141e8006a41086a2003290300370300200141e8006a41106a2005370300200141e8006a41186a200629030037030020012001290338370368200141386a200141e8006a10fe0120012802382203410120031b21074102210802400240200129023c420020031b2205422088a72203450d002003410574210241002104200721030240034020002003460d01200420032000412010a00822064100476a21042006450d01200341206a2103200241606a22020d000c020b0b200141386a41186a4200370300200141386a41106a22094200370300200141386a41086a220042003703002001420037033841a3edcb00ad4280808080f0008410012202290000210a200141286a41086a2203200241086a2900003703002001200a37032820021035200020032903003703002001200129032837033841beebcb00ad4280808080a0028410012202290000210a2003200241086a2900003703002001200a3703282002103520092001290328220a370300200141e8006a41086a2000290300370300200141e8006a41106a200a370300200141e8006a41186a200329030037030020012001290338370368200141186a200141e8006a10c5020240024002402001280218220b0d004100210c20014100360210200142043703084104210b4100210d410021030c010b200129021c210a2001200b3602082001200a37020c200aa7210d4100210302400240200a422088a7220c41014b0d00200c0e020201020b200c2100034020032000410176220220036a22062004200b20064102746a280200491b2103200020026b220041014b0d000b0b4100210802402004200b20034102746a2802002200470d00410021060c020b2003200420004b6a21030b200141386a41186a22084200370300200141386a41106a220e4200370300200141386a41086a220242003703002001420037033841a3edcb00ad4280808080f0008410012206290000210a200141286a41086a2200200641086a2900003703002001200a37032820061035200220002903003703002001200129032837033841f393ca00ad4280808080a0018410012206290000210a2000200641086a2900003703002001200a3703282006103520092001290328370000200941086a2000290300370000200141e8006a41086a2002290300370300200141e8006a41106a200e290300370300200141e8006a41186a200829030037030020012001290338370368200141286a200141e8006aad4280808080800484100510c201024002400240024020012802282202450d00200128022c21062001200028020036023c200120023602382001200141386a10c4012001280200450d01410021000c020b2001420037023c20014101360238200141386a108a0321000c020b200128020421000b2006450d00200210350b20002000418094ebdc036e22024180ec94a37c6c6aad4280fd87d1007e220f428094ebdc0380210a200c2003490d0220024180fd87d1006c200f200a4280ec94a37c7e7c4280cab5ee015672200aa76a21020240200c200d470d00200141086a200d4101108601200128020c210d2001280208210b0b200b20034102746a220041046a2000200c20036b410274109e081a20002004360200410121062001200c41016a220c360210200c20024b21080b200141386a41186a220e4200370300200141386a41106a22104200370300200141386a41086a220042003703002001420037033841a3edcb00ad4280808080f0008410012202290000210a200141286a41086a2203200241086a2900003703002001200a37032820021035200020032903003703002001200129032837033841beebcb00ad4280808080a0028410012202290000210a2003200241086a2900003703002001200a3703282002103520092001290328370000200941086a2003290300370000200141e8006a41086a2000290300370300200141e8006a41106a2010290300370300200141e8006a41186a200e2903003703002001200129033837036802400240200b0d00200141e8006aad428080808080048410070c010b2001412036023c2001200141e8006a360238200b200c200141386a109503200d41ffffffff0371450d00200b10350b2006450d00200141e8006a41086a22032004ad37030020014102360268200141386a200141e8006a108805200141336a2200200141386a41086a2802003600002001200129033837002b200141386a410c6a2001412f6a2202290000370000200141c6a4b9da04360039200141023a00382001200129002837003d200141386a108204200141013602382001200436023c200141e8006a200141386a108104200020032802003600002001200129036837002b200141e8006a410c6a2002290000370000200141c28289aa04360069200141023a00682001200129002837006d200141e8006a1082040b0240200542ffffff3f83500d00200710350b20014190016a240020080f0b2003200c104d000b9a0d04047f017e027f067e230041d0026b22052400200541c8016a2001200210800202400240024002400240024020052802d0014102460d0020052802c8012106200541c8016a41086a2001280204220741086a290000370300200541c8016a41106a200741106a290000370300200541c8016a41186a200741186a290000370300200520063602e801200520072900003703c801200541f0016a200541c8016a10b60120052802f0012108200520052802f801220736028402200520083602800220054188026a2007ad4220862008ad84100510c2010240024020052802880222070d00420021090c010b200528028c02210a02400240024020054188026a41086a280200220b4110490d00200b4170714110470d010b200541003602a0022005420137039802200541093602ac02200520054180026a3602a802200520054198026a3602b402200541cc026a4101360200200542013702bc02200541c888c2003602b8022005200541a8026a3602c802200541b4026a41e88ac500200541b8026a10431a20053502a0024220862005350298028410060240200528029c02450d0020052802980210350b420021090c010b200741186a290000210c200741086a290000210d2007290010210e2007290000210f420121090b200a450d00200710350b200d4200200942005222071b210d200f420020071b210f024020052802f401450d00200810350b200c420020071b210c200e420020071b210e200f200354200d200454200d2004511b0d01200f200385200d2004858450450d03200541b8016a20032004428094ebdc034200109808200541a8016a20052903b801220d200541b8016a41086a290300220f4280ec94a37c427f10840820054198016a200d200f20013502282209420010840820054188016a4200200529039801220f200920052903a80120037c7e220d428094ebdc03802209a7417f200d428080808080c0b2cd3b541b200d20094280ec94a37c7e7c4280cab5ee01566aad7c220d200e7d22092009200d5620054198016a41086a290300200d200f54ad7c220f200c7d200d200e54ad7d220d200f56200d200f511b22021b220f4200200d20021b428094ebdc034200109808200541f8006a200529038801220d20054188016a41086a29030022094280ec94a37c427f108408200541e8006a200d20094280cab5ee014200108408200541e8006a41086a29030020052903682209200f20052903787c220d420188220fa7417f200d4280cab5ee017e220d428080808080c0b2cd3b541b200d200f4280ec94a37c7e7c4280cab5ee01566aad7c220d200954ad7c210f410021020c020b410021010c040b200541c8006a20032004428094ebdc034200109808200541d8006a20032004428094ebdc034200108608200541386a2005290348200541c8006a41086a290300200135022822094200108408200541286a420020052903382210200920052903587e2209428094ebdc03802211a7417f2009428080808080c0b2cd3b541b200920114280ec94a37c7e7c4280cab5ee01566aad7c2209200e7d22112011200956200541386a41086a2903002009201054ad7c2210200c7d2009200e54ad7d220920105620092010511b22071b22104200200920071b428094ebdc034200109808200541186a20052903282209200541286a41086a29030022114280ec94a37c427f108408200541086a200920114280cab5ee014200108408200128022422072003200f7d220920072903007c2211370300200741086a22072004200d7d2003200f54ad7d20072903007c2011200954ad7c370300200141106a2207200728020022072002200720024b1b360200200541086a41086a2903002005290308220f201020052903187c220d4201882209a7417f200d4280cab5ee017e220d428080808080c0b2cd3b541b200d20094280ec94a37c7e7c4280cab5ee01566aad7c220d200f54ad7c210f410121020b02400240200d200f84500d002001280220220220022903002209200d7c2210370300200241086a22022002290300200f7c2010200954ad7c370300200c200f7c200e200d7c220d200e54ad7c210c200d210e0c010b2002450d010b200141013a002c200541b8026a200541c8016a10b60120053502c002210d20052802b8022102411010332201450d01200120033700002001200437000820014110412010372201450d012001200e370010200141186a200c370000200d4220862002ad842001ad428080808080048410022001103520052802bc02450d00200210350b410121010c010b103c000b2000200636020420002001360200200541d0026a24000be70403057f017e037f23004180016b22022400200241206a41186a22034200370300200241206a41106a22044200370300200241206a41086a220542003703002002420037032041f7edcb00ad4280808080f000841001220629000021072005200641086a290000370300200220073703202006103541eeedcb00ad4280808080900184100122062900002107200241086a2208200641086a2900003703002002200737030020061035200420022903002207370300200241e0006a41086a22062005290300370300200241e0006a41106a22092007370300200241e0006a41186a220a200829030037030020022002290320370360200241206a200241e0006a10ac010240024020022903204202520d00200041003602200c010b200241d0006a2004280200200110ce01200241206a200228025022082002280258108502200a2003290300370300200920042903003703002006200529030037030020022002290320370360200241cc006a280200210402400240200228024022050d0042002107200241186a4200370300200241106a420037030041082105200241086a4200370300200242003703000c010b200241086a200241e0006a41086a290300370300200241106a200241e0006a41106a290300370300200241186a200241e0006a41186a29030037030020022002290360370300200229024421070b02402002280254450d00200810350b2000200229030037030020002007370224200020053602202000412c6a2004360200200041186a200241186a290300370300200041106a200241106a290300370300200041086a200241086a2903003703000b20024180016a24000b860301017f230041f0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822010d00200041003602200c010b200328020c21022003200341086a41086a28020036024c20032001360248200341186a200341c8006a10c5010240024020032802380d00200341003602582003420137035020034109360264200320033602602003200341d0006a36026c2003412c6a41013602002003420137021c200341c888c2003602182003200341e0006a360228200341ec006a41e88ac500200341186a10431a2003350258422086200335025084100602402003280254450d00200328025010350b200041003602200c010b20002003290318370300200041286a200341186a41286a290300370300200041206a200341186a41206a290300370300200041186a200341186a41186a290300370300200041106a200341186a41106a290300370300200041086a200341186a41086a2903003703000b2002450d00200110350b200341f0006a24000bc00908057f047e027f027e067f017e037f017e230041e0016b22032400200241386a2802002104200241346a2802002105200241306a2802002106200341c0006a41186a200241186a290000370300200341c0006a41106a200241106a290000370300200341c0006a41086a200241086a290000370300200320022900003703404100210720034100360268200342083703600240024020040d0042002108420021094200210a4200210b0c010b200441306c210c200341b0016a41106a21044108210d42002108420021094200210a4200210b200621020340200241286a290300210e200241206a290300210f200341f0006a41186a2210200241186a290300370300200341f0006a41106a2211200241106a290300370300200341f0006a41086a2212200241086a29030037030020032002290300370370200341b0016a41186a2213420037030020044200370300200341b0016a41086a22144200370300200342003703b00141b6fdc600ad42808080808001841001221529000021162014201541086a290000370300200320163703b0012015103541e489c200ad4280808080d00184100122152900002116200341d0016a41086a2217201541086a290000370300200320163703d00120151035200420032903d001370000200441086a201729030037000020034190016a41086a2215201429030037030020034190016a41106a2217200429030037030020034190016a41186a22182013290300370300200320032903b00137039001200341286a20034190016a412010d701200341186a2003290330200341286a41106a290300427f4200109808200341086a20032903184200200328022822191b221642012016420156200341186a41086a290300420020191b22164200522016501b22191b2016420020191b200f200e1084082018201029030037030020172011290300370300201520122903003703002003200329037037039001200341086a41086a29030021162003290308210e0240024020034190016a200341c0006a412010a008450d0020132018290300370300200420172903003703002014201529030037030020032003290390013703b001024020072003280264470d00200341e0006a200741011088012003280260210d200328026821070b200d200741306c6a221520163703082015200e370300201520032903b001370310201541186a2014290300370300201541206a2004290300370300201541286a20132903003703002003200741016a22073602680c010b427f200920167c2008200e7c221a2008542214ad7c220f2014200f200954200f2009511b22141b2109427f201a20141b21080b200241306a2102427f200b20167c200a200e7c2216200a542214ad7c220a2014200a200b54200a200b511b22141b210b427f201620141b210a200c41506a220c0d000b0b02402005450d00200541306c450d00200610350b2000200a37032020002003290340370000200041386a2009370300200041306a2008370300200041286a200b370300200041c0006a2003290360370200200041186a200341c0006a41186a290300370000200041106a200341c0006a41106a290300370000200041086a200341c0006a41086a290300370000200041c8006a200341e0006a41086a280200360200200341e0016a24000ba21904047f017e047f037e230041d0016b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a220341174b0d0020030e180102030405060708090a0b0c0d0e0f101112131415161718010b41cfa2cc00412841c086cc00103f000b4101210302400240200141046a2d00004101470d00200141086a28020021040c010b200241c2016a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b01c00120022001410c6a290000370300200141086a2800002104410021030b200041286a2001290328370300200041046a20033a0000200041056a20022f01c0013b0000200041086a20043602002000410c6a2002290300370200200041306a200141306a290300370300200041076a200241c2016a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a28020036020020012d00012101200041013a0000200020013a00010c170b200041023a0000200041106a200141106a290300370300200041086a200141086a2903003703000c160b200041033a0000200041106a200141106a290300370300200041086a200141086a2903003703000c150b200041043a00000c140b200041053a0000200041046a200141046a2802003602000c130b2001410c6a2802002205ad42247e2206422088a70d132006a72204417f4c0d13200141046a28020021030240024020040d00410421010c010b200410332201450d150b200241003602c801200220013602c0012002200441246e3602c401200241c0016a41002005108d0120022802c801210402402005450d00200541246c210520022802c001200441246c6a2101200241ce016a210703400240024020032d00004101470d00200341046a2802002108410121090c010b2007200341036a2d00003a0000200341046a2800002108200341016a2f00002109200241086a200341106a290000370300200241106a200341186a290000370300200241186a200341206a2d00003a0000200220093b01cc012002200341086a290000370300410021090b200341246a2103200120093a0000200141046a2008360200200141016a20022f01cc013b0000200141036a20072d00003a0000200141086a2002290300370200200141106a200241086a290300370200200141186a200241106a290300370200200141206a200241186a280200360200200141246a2101200441016a21042005415c6a22050d000b0b200241086a2004360200200220022903c00122063703002000410c6a2004360200200041046a2006370200200041063a00000c120b200041073a00000c110b200041083a0000200020012d00013a00010c100b4101210302400240200141046a2d00004101470d00200141086a28020021010c010b200241c2016a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b01c00120022001410c6a290000370300200141086a2800002101410021030b200041093a0000200041046a20033a0000200041056a20022f01c0013b0000200041086a20013602002000410c6a2002290300370200200041076a200241c2016a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c0f0b2000410a3a0000200041046a200141046a2802003602000c0e0b2000410b3a00000c0d0b2000410c3a00000c0c0b2001410c6a280200220741ffffff3f712007470d0c20074105742203417f4c0d0c200141046a28020021050240024020030d00410121040c010b200310332204450d0e0b41002101200241003602082002200436020020022003410576360204200241002007108a012002280208210a02402007450d00200741057421082002280200200a4105746a21090340200920016a2203200520016a2204290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002008200141206a2201470d000b200741057441606a410576200a6a41016a210a0b200241c8016a200a3602002002200229030022063703c0012000410c6a200a360200200041046a20063702002000410d3a00000c0b0b2000410e3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0a0b2000410f3a00000c090b200141106a280200220341ffffffff03712003470d0920034102742204417f4c0d09200141046a2802002105200141086a28020021084104210102402004450d00200410332201450d0b0b2002410036020820022001360200200220044102763602042002410020031086012002280200200228020822014102746a20082003410274109d081a200241c0016a41086a200120036a22013602002002200229030022063703c001200041046a2005360200200041086a2006370200200041106a2001360200200041103a00000c080b200141106a2802002203ad42247e2206422088a70d082006a72204417f4c0d08200141046a2802002108200141086a28020021010240024020040d00410421050c010b200410332205450d0a0b20024100360208200220053602002002200441246e360204200241002003108d012002280208210402402003450d00200341246c21052002280200200441246c6a21030340200141086a2902002106200141106a290200210b200141186a290200210c2001290200210d200341206a200141206a280200360200200341186a200c370200200341106a200b370200200341086a20063702002003200d370200200341246a2103200441016a2104200141246a21012005415c6a22050d000b0b200241c0016a41086a20043602002002200229030022063703c001200041046a2008360200200041086a2006370200200041106a2004360200200041113a00000c070b200041123a0000200041046a200141046a2802003602000c060b200041133a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c050b200041143a0000200041106a200141106a290300370300200041086a200141086a2903003703000c040b200041153a0000200041046a200141046a2802003602000c030b200041163a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c020b2001410c6a280200220320036a22042003490d022004417f4c0d02200141046a28020021050240024020040d00410221080c010b200410332208450d040b200241003602082002200836020020022004410176360204200241002003108e012002280200200228020822044101746a20052003410174109d081a200241c0016a41086a2205200420036a360200200220022903003703c0012002200141106a108802200041046a20022903c0013702002000410c6a200528020036020020012802d0012103200041106a200241c001109d081a200041d0016a2003360200200041173a000020004180026a200141d8016a220141286a290300370300200041f8016a200141206a290300370300200041f0016a200141186a290300370300200041e8016a200141106a290300370300200041e0016a200141086a290300370300200041d8016a20012903003703000c010b2001410c6a280200220320036a22042003490d012004417f4c0d01200141046a28020021050240024020040d00410221080c010b200410332208450d030b200241003602082002200836020020022004410176360204200241002003108e012002280200200228020822044101746a20052003410174109d081a200241c0016a41086a2205200420036a360200200220022903003703c0012002200141106a108802200041046a20022903c0013702002000410c6a200528020036020020012802d0012103200041106a200241c001109d081a200041d0016a2003360200200041183a000020004180026a200141d8016a220141286a290300370300200041f8016a200141206a290300370300200041f0016a200141186a290300370300200041e8016a200141106a290300370300200041e0016a200141086a290300370300200041d8016a20012903003703000b200241d0016a24000f0b1044000b1045000bc11702057f017e23004180026b22022400024002402001280208220341ffffffff01712003470d0020034103742204417f4c0d00200128020021050240024020040d00410421060c010b200410332206450d020b200241003602f801200220063602f001200220044103763602f401200241f0016a4100200310900120022802f00120022802f80122044103746a20052003410374109d081a200041086a200420036a360200200020022903f001370200200141146a2802002204ad420c7e2207422088a70d002007a72203417f4c0d00200128020c21064104210502402003450d00200310332205450d020b200241003602f801200220053602f00120022003410c6e3602f401200241f0016a4100200410870120022802f00120022802f8012205410c6c6a20062003109d081a200241086a200520046a360200200220022903f001370300200141206a280200220341ffffffff00712003470d0020034104742204417f4c0d00200128021821064104210502402004450d00200410332205450d020b200241003602f801200220053602f001200220044104763602f401200241f0016a41002003108c0120022802f00120022802f80122044104746a20062003410474109d081a200241186a200420036a360200200220022903f0013703102001412c6a2802002204ad42147e2207422088a70d002007a72203417f4c0d00200128022421050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341146e3602f401200241f0016a4100200410990120022802f00120022802f801220641146c6a20052003109d081a200241286a200620046a360200200220022903f001370320200141386a2802002204ad42187e2207422088a70d002007a72203417f4c0d00200128023021050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341186e3602f401200241f0016a4100200410970120022802f00120022802f801220641186c6a20052003109d081a200241386a200620046a360200200220022903f001370330200141c4006a2802002204ad421c7e2207422088a70d002007a72203417f4c0d00200128023c21050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f00120022003411c6e3602f401200241f0016a4100200410f90120022802f00120022802f8012206411c6c6a20052003109d081a200241c8006a200620046a360200200220022903f001370340200141d0006a280200220341ffffff3f712003470d0020034105742204417f4c0d00200128024821050240024020040d00410421060c010b200410332206450d020b200241003602f801200220063602f001200220044105763602f401200241f0016a4100200310910120022802f00120022802f80122044105746a20052003410574109d081a200241d8006a200420036a360200200220022903f001370350200141dc006a2802002204ad42247e2207422088a70d002007a72203417f4c0d00200128025421050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341246e3602f401200241f0016a41002004108d0120022802f00120022802f801220641246c6a20052003109d081a200241e8006a200620046a360200200220022903f001370360200141e8006a2802002204ad42287e2207422088a70d002007a72203417f4c0d00200128026021050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341286e3602f401200241f0016a41002004109d0120022802f00120022802f801220641286c6a20052003109d081a200241f8006a200620046a360200200220022903f001370370200141f4006a2802002204ad422c7e2207422088a70d002007a72203417f4c0d00200128026c21050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f00120022003412c6e3602f401200241f0016a4100200410980120022802f00120022802f8012206412c6c6a20052003109d081a20024188016a200620046a360200200220022903f0013703800120014180016a2802002204ad42307e2207422088a70d002007a72203417f4c0d00200128027821050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341306e3602f401200241f0016a4100200410890120022802f00120022802f801220641306c6a20052003109d081a20024198016a200620046a360200200220022903f001370390012001418c016a2802002204ad42347e2207422088a70d002007a72203417f4c0d0020012802840121050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341346e3602f401200241f0016a4100200410a50120022802f00120022802f801220641346c6a20052003109d081a200241a8016a200620046a360200200220022903f0013703a00120014198016a2802002204ad42387e2207422088a70d002007a72203417f4c0d0020012802900121050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f0012002200341386e3602f401200241f0016a4100200410a20120022802f00120022802f801220641386c6a20052003109d081a200241b8016a200620046a360200200220022903f0013703b001200141a4016a2802002204ad423c7e2207422088a70d002007a72203417f4c0d00200128029c0121050240024020030d00410421060c010b200310332206450d020b200241003602f801200220063602f00120022003413c6e3602f401200241f0016a4100200410aa0120022802f00120022802f8012206413c6c6a20052003109d081a200241c8016a200620046a360200200220022903f0013703c001200141b0016a280200220341ffffff1f712003470d0020034106742204417f4c0d0020012802a80121050240024020040d00410421060c010b200410332206450d020b200241003602f801200220063602f001200220044106763602f401200241f0016a4100200310a60120022802f00120022802f80122044106746a20052003410674109d081a200241d8016a200420036a360200200220022903f0013703d001200141bc016a2802002204ad42c4007e2207422088a70d002007a72203417f4c0d0020012802b40121010240024020030d00410421050c010b200310332205450d020b200241003602f801200220053602f0012002200341c4006e3602f401200241f0016a41002004109f0120022802f00120022802f801220541c4006c6a20012003109d081a200241e0016a41086a2201200520046a360200200220022903f0013703e001200041146a200241086a2802003602002000200229030037020c20002002290310370218200041206a200241106a41086a280200360200200020022903203702242000412c6a200241206a41086a28020036020020002002290330370230200041386a200241306a41086a280200360200200041c4006a200241c0006a41086a2802003602002000200229034037023c200041d0006a200241d0006a41086a28020036020020002002290350370248200041dc006a200241e0006a41086a28020036020020002002290360370254200041e8006a200241f0006a41086a28020036020020002002290370370260200041f4006a20024180016a41086a280200360200200020022903800137026c20004180016a20024190016a41086a28020036020020002002290390013702782000418c016a200241a0016a41086a280200360200200020022903a0013702840120004198016a200241b0016a41086a280200360200200020022903b00137029001200041a4016a200241c0016a41086a280200360200200020022903c00137029c01200041b0016a200241d0016a41086a280200360200200020022903d0013702a801200041bc016a2001280200360200200020022903e0013702b40120024180026a24000f0b1044000b1045000b89f0020a017f027e017f017e127f037e037f037e067f047e230041900c6b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e19000102030405061a1917161514131211100f0e0d0c0b0a0908000b200341940a6a4101360200200342013702840a200341e8d4ca003602800a200341043602f4062003419cd5ca003602f0062003200341f0066a3602900a200341800a6a41b0b4cc00104c000b200141306a2903002104200141286a290300210520012d0001210620034190076a200141246a280200360200200341f0066a41186a2001411c6a290200370300200341f0066a41106a200141146a290200370300200341f0066a41086a2001410c6a2902003703002003200141046a2902003703f0062002411a6a2901002107200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211941012101024020022d00000d0020022d000141014721010b200320073701e80b200320083a00e70b200320093a00e60b2003200a3b01e40b2003200b3a00e30b2003200c3a00e20b2003200d3b01e00b2003200e3a00df0b2003200f3a00de0b200320103b01dc0b200320113a00db0b200320123a00da0b200320133b01d80b200320143a00d70b200320153a00d60b200320163b01d40b200320173a00d30b200320183a00d20b200320193b01d00b0240024020010d00200341e0086a41186a200341d00b6a41186a290100370300200341e0086a41106a200341d00b6a41106a290100370300200341e0086a41086a200341d00b6a41086a290100370300200320032901d00b3703e008200341800a6a200341e0086a10b401200341206a20032802800a220220032802880a41b0b4cc0041004100108a0220032802202101024020032802840a450d00200210350b4103210220014101470d0141a1a6c0002101410d21084180800821090c260b41022102410021090c250b200341800a6a41206a200341f0066a41206a280200360200200341800a6a41186a200341f0066a41186a290300370300200341800a6a41106a200341f0066a41106a290300370300200341800a6a41086a200341f0066a41086a290300370300200320032903f0063703800a200341d0096a200341800a6a108b0220032d00d0094101460d05200341d0096a41086a2d00002101200341d9096a2f00002108200341db096a2d00002109200341dc096a2d0000210a200341dd096a2f0000210b200341df096a2d0000210c200341d0096a41106a2d0000210d200341e1096a2f0000210e200341e3096a2d0000210f200341e4096a2d00002110200341e5096a2f00002111200341e7096a2d00002112200341d0096a41186a2d0000211320032d00d109211420032d00d209211520032d00d309211620032d00d409211720032f00d509211820032d00d70921192003200341e9096a2900003703a009200320133a009f09200320123a009e09200320113b019c09200320103a009b092003200f3a009a092003200e3b0198092003200d3a0097092003200c3a0096092003200b3b0194092003200a3a009309200320093a009209200320083b019009200320013a008f09200320193a008e09200320183b018c09200320173a008b09200320163a008a09200320153a008909200320143a008809200341800a6a20034188096a10b701200341186a20032802800a220820032802880a41b0b4cc0041004100108a0220032802182101024020032802840a450d00200810350b024020014101470d004194a6c0002101410d21084180800c21090c250b02402005428080e983b1de165441002004501b450d0041d8a5c0002101411121084180801c21090c250b200341800a6a200341e0086a10b40120033502880a210720032802800a2101412010332202450d162002200329038809370000200241186a20034188096a41186a290300370000200241106a20034188096a41106a290300370000200241086a20034188096a41086a29030037000020074220862001ad842002ad4280808080800484100220021035024020032802840a450d00200110350b200341800a6a200341e0086a108c0220033502880a210720032802800a210102400240200641037122024103470d00410121024200211a410121080c010b024002400240024020020e03000102000b410021080c020b410121080c010b410221080b200320083a00f00b410110332202450d22200220083a000041002108428080808010211a0b20074220862001ad84201a2002ad841002024020080d00200210350b024020032802840a450d00200110350b200341e0086a108d0241f7edcb00ad4280808080f0008422071001220228000021012002290004211a200228000c21082002103541e4edcb00ad4280808080a0018410012202290000211b2002290008211c200210352003201c3701c8082003201b3701c008200320083601bc082003201a3701b408200320013601b008200341106a200341b0086a412010c0012003280214210120032802102108200710012202280000210920022900042107200228000c210a2002103541b5edcb00ad4280808080c0018410012202290000211a2002290008211b200210352003201b3701c8082003201a3701c0082003200a3601bc08200320073701b408200320093601b008200341086a200341b0086a412010c001200328020c210220032802082109200341d0096a200341e0086a108e02200341800a6a20032802d009220a20032802d809108f0241002001410020081b2208200241d40020091b6b2202200220084b1b2102200341800a6a41106a290300420020032903800a42015122011b210720032903880a420020011b211a024020032802d409450d00200a10350b200341800a6a41086a41053a0000200341890a6a20032903e008370000200341910a6a200341e0086a41086a2201290300370000200341990a6a200341e0086a41106a2209290300370000200341a10a6a200341e0086a41186a220a290300370000200341b80a6a220b20072004201a200554200720045420072004511b220c1b2207370300200341b00a6a201a2005200c1b2204370300200341043a00800a41b0b4cc004100200341800a6a10d40120012f0100210c20092f0100210d200a290300210520032f01e008210e20032d00e208210f20032d00e308211020032f01e408211120032d00e608211220032d00e708211320032d00ea08211420032d00eb08211520032f01ec08211620032d00ee08211720032d00ef08211820032d00f208211920032d00f308210620032f01f408211d20032d00f608211e20032d00f708211f200341003602d809200342043703d009200341d0096a41004100200820026b220a200a20084b1b10860120032802d80921090240200820024d0d0020032802d00920094102746a2101034020012002360200200141046a21012008200241016a2202470d000b200a20096a21090b200341b0086a41086a22022009360200200341d00a6a2005370300200341cf0a6a201f3a0000200341ce0a6a201e3a0000200341cc0a6a201d3b0100200341cb0a6a20063a0000200341ca0a6a20193a0000200341c80a6a200d3b0100200341c70a6a20183a0000200341c60a6a20173a0000200341c40a6a20163b0100200341c30a6a20153a0000200341c20a6a20143a0000200341c00a6a200c3b0100200341bf0a6a20133a0000200341be0a6a20123a0000200341bc0a6a20113b0100200341bb0a6a20103a0000200341ba0a6a200f3a0000200320032903d0093703b0082003200e3b01b80a200341800a6a41186a2007370300200341a80a6a4100360200200341b40a6a2002280200360200200320043703900a200320073703880a200320043703800a200342083703a00a200320032903b0083702ac0a200342f3e885db96cddbb3203703f00b200341f00b6a200b20042007411f109002200341d0096a20034188096a10b70120032802d0092102200320032802d8093602b408200320023602b008200341800a6a200341b0086a10e101024020032802d409450d00200210350b024020032802a40a2202450d00200241186c450d0020032802a00a10350b200341b00a6a28020041ffffffff0371450d2320032802ac0a10350c230b200141106a290300211b200141086a290300211c2002411a6a290100211a200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113410e21012002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d00002118200241086a2d00002119200241066a2f01002106200241056a2d0000211d200241046a2d0000211e200241026a2f0100211f20022d0001210b20022d0000210a41f7edcb00ad4280808080f0008410012202280000210820022900042107200228000c21092002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320083601b008200341286a200341b0086a10f2014103210202402003280228417d71450d0041dca2c0002108418080ec0021090c220b02400240200a41ff01710d00200b41ff01714101470d002003201a3703880c2003200c3a00870c2003200d3a00860c2003200e3b01840c2003200f3a00830c200320103a00820c200320113b01800c200320123a00ff0b200320133a00fe0b200320143b01fc0b200320153a00fb0b200320163a00fa0b200320173b01f80b200320183a00f70b200320193a00f60b200320063b01f40b2003201d3a00f30b2003201e3a00f20b2003201f3b01f00b200341f0066a200341f00b6a10b401200341800a6a20032802f006220920032802f80610d501200341990a6a2900002107200341980a6a2d0000210a200341970a6a2d0000210b200341950a6a2f0000210c200341940a6a2d0000210d200341930a6a2d0000210e200341910a6a2f0000210f200341900a6a2d000021102003418f0a6a2d000021112003418d0a6a2f000021122003418c0a6a2d000021132003418b0a6a2d00002114200341890a6a2f0000211541082101200341800a6a41086a2d0000211620032d00870a211720032f00850a211820032d00840a211920032d00830a210620032d00820a211d20032d00810a211e20032d00800a2108024020032802f406450d00200910350b200841ff01714101460d0141aea6c00021084180800421090c230b41022102410021090c220b200320073703e8092003200a3a00e7092003200b3a00e6092003200c3b01e4092003200d3a00e3092003200e3a00e2092003200f3b01e009200320103a00df09200320113a00de09200320123b01dc09200320133a00db09200320143a00da09200320153b01d809200320163a00d709200320173a00d609200320183b01d409200320193a00d309200320063a00d2092003201d3a00d1092003201e3a00d009200341d00b6a200341d0096a10b701200341800a6a20032802d00b220120032802d80b10d601200341b0086a41086a2208200341bc0a6a290200370300200341b0086a41106a2209200341c40a6a290200370300200341b0086a41186a220a200341cc0a6a290200370300200341b0086a41206a220b200341d40a6a2802003602002003200341b40a6a2902003703b0080240024020032802a00a220c450d00200341800a6a41186a2903002105200341800a6a41086a2903002104200341b00a6a2802002102200341ac0a6a280200210d200341a80a6a280200210e20032903900a211a20032903800a210720032802a40a210f20034188096a41206a200b28020036020020034188096a41186a200a29030037030020034188096a41106a200929030037030020034188096a41086a2008290300370300200320032903b00837038809024020032802d40b450d00200110350b200341e0086a41086a220120034188096a41086a290300370300200341e0086a41106a220820034188096a41106a290300370300200341e0086a41186a220920034188096a41186a290300370300200341e0086a41206a220a20034188096a41206a280200360200200341f0066a41186a2005370300200341a0076a200236020020034198076a200e36020020034194076a200f36020020032003290388093703e0082003201a37038007200320073703f0062003200d36029c072003200c36029007200320043703f806200341c4076a200a280200360200200341bc076a2009290300370200200341b4076a2008290300370200200341ac076a2001290300370200200341a4076a20032903e008370200200341b0086a200341f00b6a108e02200341800a6a20032802b008220120032802b808108f02200341800a6a41106a290300420020032903800a42015122021b210520032903880a420020021b211a024020032802b408450d0020011035200341f0066a41086a290300210420032903f00621070b201a20077d2220201a56200520047d201a200754ad7d221a200556201a2005511b0d01200341f0066a41186a2202290300212120032003290380072222201c20202020201c56201a201b56201a201b511b22011b22057c221c3703800720022021201b201a20011b221a7c201c202254ad7c3703002003200520077c22073703f0062003201a20047c2007200554ad7c22043703f806200341800a6a41386a201a370300200341b00a6a2005370300200341800a6a41086a41053a0000200341890a6a20032903f00b370000200341910a6a200341f00b6a41086a290300370000200341990a6a200341800c6a290300370000200341a10a6a200341f00b6a41186a290300370000200341043a00800a41b0b4cc004100200341800a6a10d401200342f3e885db96cddbb3203703880920034188096a200341f0066a41386a20072004411f109002200341800a6a200341d0096a10b70120032802800a2102200320032802880a3602b408200320023602b008200341f0066a200341b0086a10e101024020032802840a450d00200210350b02402003280294072202450d00200241186c450d0020032802900710350b20032802a00741ffffffff0371450d24200328029c0710350c240b024020032802d40b450d00200110350b41b6a6c0002108410d2101410021090c220b02402003280294072202450d00200241186c450d0020032802900710350b20032802a00741ffffffff0371450d22200328029c0710350c220b200141106a290300211b200141086a290300211c2002411a6a290100211a200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113410e21012002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d00002118200241086a2d00002119200241066a2f01002106200241056a2d0000211d200241046a2d0000211e200241026a2f0100211f20022d0001210b20022d0000210a41f7edcb00ad4280808080f0008410012202280000210820022900042107200228000c21092002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320083601b008200341386a200341b0086a10f201410321020240024002402003280238417d71450d0041dca2c0002108418090ec0021090c010b0240200a41ff01710d00200b41ff01714101470d002003201a3703e8092003200c3a00e7092003200d3a00e6092003200e3b01e4092003200f3a00e309200320103a00e209200320113b01e009200320123a00df09200320133a00de09200320143b01dc09200320153a00db09200320163a00da09200320173b01d809200320183a00d709200320193a00d609200320063b01d4092003201d3a00d3092003201e3a00d2092003201f3b01d009200341f00b6a200341d0096a10b701200341800a6a20032802f00b220b20032802f80b10d601200341b0086a41086a220c200341bc0a6a290200370300200341b0086a41106a220d200341c40a6a290200370300200341b0086a41186a220e200341cc0a6a290200370300200341b0086a41206a220f200341d40a6a2802003602002003200341b40a6a2902003703b008024020032802a00a2209450d00200341800a6a41186a2903002107200341800a6a41086a2903002105200341b00a6a280200210a200341ac0a6a2802002110200341a80a6a280200210120032903900a210420032903800a211a20032802a40a210820034188096a41206a200f28020036020020034188096a41186a200e29030037030020034188096a41106a200d29030037030020034188096a41086a200c290300370300200320032903b00837038809024020032802f40b450d00200b10350b200341e0086a41086a220b20034188096a41086a290300370300200341e0086a41106a220c20034188096a41106a290300370300200341e0086a41186a220d20034188096a41186a290300370300200341e0086a41206a220e20034188096a41206a280200360200200341f0066a41186a2007370300200341a0076a200a36020020034198076a200136020020034194076a200836020020032003290388093703e00820032004370380072003201a3703f0062003201036029c072003200936029007200320053703f806200341c4076a200e280200360200200341bc076a200d290300370200200341b4076a200c290300370200200341ac076a200b290300370200200341a4076a20032903e0083702002001411f4d0d0302402008450d00200841186c450d002009103520032802a007210a0b0240200a41ffffffff0371450d00200328029c0710350b41cca5c0002108410c21014180902021090c020b024020032802f40b450d00200b10350b41b6a6c0002108410d210141801021090c010b4102210241801021090b20004200370308200041206a20013602002000411c6a2008360200200041186a20092002723602000c240b200341f0066a41206a210202402004201c2004201c542007201b542007201b511b220a1b22052007201b200a1b221a844200510d00200341f0066a41186a42002007201a7d2004200554ad7d221b200420057d221c428080e983b1de16544100201b501b220a1b37030020034200201c200a1b3703800741f7edcb00ad4280808080f000841001220b280000210c200b290004211b200b28000c210d200b103541e4edcb00ad4280808080a001841001220b290000211c200b2900082120200b1035200320203701c8082003201c3701c0082003200d3601bc082003201b3701b4082003200c3601b008200341306a200341b0086a412010c0012007201a200a1b210720042005200a1b2104200328023441a0056a41a00520032802301b210a024020012008470d00200220084101109c01200328029807210120032802900721090b2009200141186c6a22012007370308200120043703002001200a360210200320032802980741016a36029807200342f3e885db96cddbb3203703880920034188096a200341f0066a41386a20032903f006200341f0066a41086a290300411f109002200341800a6a200341d0096a10b70120032802800a2101200320032802880a3602b408200320013602b008200341f0066a200341b0086a10e101024020032802840a450d00200110350b200341800a6a41386a2007370300200341b00a6a2004370300200341800a6a41086a41063a0000200341890a6a20032903a807370000200341910a6a200341b0076a290300370000200341990a6a200341b8076a290300370000200341a10a6a200341c0076a290300370000200341043a00800a41b0b4cc004100200341800a6a10d4010b0240200241046a2802002201450d00200141186c450d00200228020010350b20032802a00741ffffffff0371450d21200328029c0710350c210b2002411a6a290100211a200241196a2d0000210e200241186a2d0000210f200241166a2f01002110200241156a2d00002111200241146a2d00002112200241126a2f01002113200241116a2d00002114200241106a2d00002115410e21082002410e6a2f010021162002410d6a2d000021172002410c6a2d000021182002410a6a2f01002119200241096a2d0000210641082101200241086a2d0000211d200241066a2f0100211e200241056a2d0000211f200241046a2d00002123200241026a2f0100210b20022d0001210d20022d0000210c41f7edcb00ad4280808080f0008410012202280000210920022900042107200228000c210a2002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c0082003200a3601bc08200320073701b408200320093601b008200341c8006a200341b0086a10f20141032102024002402003280248417d710d000240200c41ff01710d00200d41ff01714101470d002003201a3703880c2003200e3a00870c2003200f3a00860c200320103b01840c200320113a00830c200320123a00820c200320133b01800c200320143a00ff0b200320153a00fe0b200320163b01fc0b200320173a00fb0b200320183a00fa0b200320193b01f80b200320063a00f70b2003201d3a00f60b2003201e3b01f40b2003201f3a00f30b200320233a00f20b2003200b3a00f00b2003200b4108763a00f10b200341d0096a200341f00b6a10b701200341800a6a20032802d009220220032802d80910d601200341b0086a41086a2201200341bc0a6a290200370300200341b0086a41106a2208200341c40a6a290200370300200341b0086a41186a2209200341cc0a6a290200370300200341b0086a41206a220a200341d40a6a2802003602002003200341b40a6a2902003703b00802400240024020032802a00a220b450d00200341800a6a41186a2903002107200341800a6a41086a290300211b200341b00a6a280200210c200341ac0a6a280200210d200341a80a6a280200210e20032903900a210420032903800a211c20032802a40a210f20034188096a41206a200a28020036020020034188096a41186a200929030037030020034188096a41106a200829030037030020034188096a41086a2001290300370300200320032903b00837038809024020032802d409450d00200210350b200341e0086a41086a220220034188096a41086a290300370300200341e0086a41106a220120034188096a41106a290300370300200341e0086a41186a220820034188096a41186a290300370300200341e0086a41206a220920034188096a41206a280200360200200341f0066a41186a220a2007370300200341a0076a200c36020020034198076a200e36020020034194076a200f36020020032003290388093703e00820032004370380072003201c3703f0062003200d36029c072003200b360290072003201b3703f806200341c4076a2009280200360200200341bc076a220c2008290300370200200341b4076a220d2001290300370200200341ac076a220e2002290300370200200341a4076a20032903e008370200200341d0096a41186a200341c0076a220f290300370300200341d0096a41106a200341b8076a2210290300370300200341d0096a41086a200341b0076a2211290300370300200320032903a8073703d00941f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21082002103541e4edcb00ad4280808080a001841001220229000021042002290008210520021035200320053701c808200320043701c008200320083601bc08200320073701b408200320013601b008200341c0006a200341b0086a412010c00120032802404101460d01200a2903002120200329038007212120032802980721080c020b024020032802d409450d00200210350b41b6a6c0002109410d210841032102410821014100210a4100210b0c040b20032802442109200341b0086a41086a2003419c076a220b41086a2802003602002003200b2902003703b0082003280290072112200a2903002120200341aa076a2d00002113200341ab076a2d00002114200e2f01002115200341ae076a2d00002116200341af076a2d0000211720112f01002111200341b2076a2d00002118200341b3076a2d00002119200d2f01002106200341b6076a2d0000211d200341b7076a2d0000211e20102f01002110200341ba076a2d0000211f200341bb076a2d00002123200c2f01002124200341be076a2d00002125200341bf076a2d00002126200f2903002122200329038007212120032f01a807210f200328029407210d201c2107201b2104024002400240200328029807220e450d002012200e41186c6a210a200e41186c41686a2101201c2107201b2104201221020340200241086a290300211a200229030021052009200241106a2802002208490d0242002004201a7d2007200554ad7d221a200720057d2205200756201a200456201a2004511b22081b21044200200520081b2107200141686a2101200241186a2202200a470d000b0b4108210c410021080240200d450d00200d41186c450d00201210350b410021020c010b41181033220c450d18200c2005370300200c2008360210200c201a37030820034281808080103702840a2003200c3602800a0240024020010d00410121080c010b200241186a2127200e41186c20126a41686a21284101210803402027210202400340200241086a290300211a200229030021052009200241106a2802002201490d0142002004201a7d2007200554ad7d221a200720057d2205200756201a200456201a2004511b22011b21044200200520011b2107200241186a2202200a470d000c030b0b0240200820032802840a470d00200341800a6a20084101109c0120032802800a210c0b200241186a2127200c200841186c6a220e2001360210200e201a370308200e20053703002003200841016a22083602880a20282002470d000b0b0240200d450d00200d41186c450d00201210350b20032802840a21020b200b20032903b00837020020034188076a2020370300200b41086a200341b0086a41086a2802003602002003202137038007200320073703f006200320083602980720032002360294072003200c36029007200320223703c007200320263a00bf07200320253a00be07200320243b01bc07200320233a00bb072003201f3a00ba07200320103b01b8072003201e3a00b7072003201d3a00b607200320063b01b407200320193a00b307200320183a00b207200320113b01b007200320173a00af07200320163a00ae07200320153b01ac07200320143a00ab07200320133a00aa072003200f3b01a807200320043703f8060b024002400240024020080d002021202084500d010b200342f3e885db96cddbb3203703880920034188096a200341a8076a20032903f006200341f8066a290300411f109002200341800a6a200341f00b6a10b70120032802800a2102200320032802880a3602b408200320023602b008200341f0066a200341b0086a10e10120032802840a450d01200210350c010b200341800a6a200341d0096a10910220032d00800a22024104470d01200342f3e885db96cddbb3203703d00b200341d00b6a200341d0096a1092020b0240201c20032903f006220458201b200341f0066a41086a290300220758201b2007511b0d00200341b00a6a201c20047d370300200341800a6a41086a41073a0000200341890a6a20032903d009370000200341910a6a200341d0096a41086a290300370000200341990a6a200341e0096a290300370000200341a10a6a200341e8096a290300370000200341b80a6a201b20077d201c200454ad7d370300200341043a00800a41b0b4cc004100200341800a6a10d4010b02402003280294072202450d00200241186c450d0020032802900710350b20032802a00741ffffffff0371450d24200328029c0710350c240b20032d00830a411074210120032f00810a210820032902840a210702402003280294072209450d00200941186c450d0020032802900710350b2008200172210120074220882104024020032802a00741ffffffff0371450d00200328029c0710350b2001411076210a2001410876210b2004a721082007a721090c020b410221020b41dca2c0002109411b210b4100210a0b20004200370308200041206a20083602002000411c6a2009360200200041186a200a411874200b411074418080fc07717220014108744180fe0371722002723602000c220b2002411a6a290100211a200241196a2d0000210d200241186a2d0000210e200241166a2f0100210f200241156a2d00002110200241146a2d00002111200241126a2f01002112200241116a2d00002113200241106a2d00002114410e21082002410e6a2f010021152002410d6a2d000021162002410c6a2d000021172002410a6a2f01002118200241096a2d00002119200241086a2d00002106200241066a2f0100211d200241056a2d0000211e200241046a2d0000211f200241026a2f01002123200141046a280200210b20022d0001210c20022d0000210a41f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21092002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320013601b008200341d0006a200341b0086a10f20141032102024002402003280250417d71450d0041dca2c0002101418090ec0021090c010b0240200a41ff01710d00200c41ff01714101470d002003201a3703e8092003200d3a00e7092003200e3a00e6092003200f3b01e409200320103a00e309200320113a00e209200320123b01e009200320133a00df09200320143a00de09200320153b01dc09200320163a00db09200320173a00da09200320183b01d809200320193a00d709200320063a00d6092003201d3b01d4092003201e3a00d3092003201f3a00d209200320233b01d009200341f00b6a200341d0096a10b701200341800a6a20032802f00b220a20032802f80b10d601200341b0086a41086a220c200341bc0a6a290200370300200341b0086a41106a220d200341c40a6a290200370300200341b0086a41186a220e200341cc0a6a290200370300200341b0086a41206a220f200341d40a6a2802003602002003200341b40a6a2902003703b008024020032802a00a2201450d00200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a2802002108200341ac0a6a2802002109200341a80a6a280200211020032903900a210520032903800a211a20032802a40a210220034188096a41206a200f28020036020020034188096a41186a200e29030037030020034188096a41106a200d29030037030020034188096a41086a200c290300370300200320032903b00837038809024020032802f40b450d00200a10350b200341e0086a41086a220a20034188096a41086a290300370300200341e0086a41106a220c20034188096a41106a290300370300200341e0086a41186a220d20034188096a41186a290300370300200341e0086a41206a220e20034188096a41206a280200360200200341f0066a41186a2007370300200341a0076a200836020020034198076a201036020020034194076a200236020020032003290388093703e00820032005370380072003201a3703f0062003200936029c072003200136029007200320043703f806200341c4076a200e280200360200200341bc076a200d290300370200200341b4076a200c290300370200200341ac076a200a290300370200200341a4076a20032903e008370200200341800a6a200341a8076a220a10b90120033502880a42208620032802800a220cad841007024020032802840a450d00200c10350b200341800a6a200a10b50120033502880a210720032802800a210a200341003a00b5080240024002400240200b41c000490d00200b41808001490d01200b418080808004490d02200341053a00b508200341033a00b0082003200b3600b1084280808080d00021040c030b200341013a00b5082003200b4102743a00b00842808080801021040c020b200341023a00b5082003200b4102744101723b01b00842808080802021040c010b200341043a00b5082003200b4102744102723602b0084280808080c00021040b2007422086200aad842004200341b0086aad841002024020032d00b508450d00200341003a00b5080b024020032802840a450d00200a10350b02402002450d00200241186c450d00200110350b200841ffffffff0371450d22200910350c220b024020032802f40b450d00200a10350b41b6a6c0002101410d210841801021090c010b4102210241801021090b20004200370308200041206a20083602002000411c6a2001360200200041186a20092002723602000c210b2001410c6a280200210e200141086a2802002108200141046a280200210b2002411a6a290100211a200241196a2d0000210f200241186a2d00002110200241166a2f01002111200241156a2d00002112200241146a2d00002113200241126a2f01002114200241116a2d00002115200241106a2d00002116410e21012002410e6a2f010021172002410d6a2d000021182002410c6a2d000021192002410a6a2f01002106200241096a2d0000211d200241086a2d0000211e200241066a2f0100211f200241056a2d00002123200241046a2d00002124200241026a2f0100212520022d0001210d20022d0000210c41f7edcb00ad4280808080f0008410012202280000210920022900042107200228000c210a2002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c0082003200a3601bc08200320073701b408200320093601b008200341e0006a200341b0086a10f2014103210202402003280260417d71450d0041dca2c0002109411b210a0c170b200c41ff01710d14200d41ff01714101470d142003201a3703c8092003200f3a00c709200320103a00c609200320113b01c409200320123a00c309200320133a00c209200320143b01c009200320153a00bf09200320163a00be09200320173b01bc09200320183a00bb09200320193a00ba09200320063b01b8092003201d3a00b7092003201e3a00b6092003201f3b01b409200320233a00b309200320243a00b209200320253b01b009200341d0096a200341b0096a10b701200341800a6a20032802d009220c20032802d80910d601200341b0086a41086a220d200341bc0a6a290200370300200341b0086a41106a220f200341c40a6a290200370300200341b0086a41186a2210200341cc0a6a290200370300200341b0086a41206a2211200341d40a6a2802003602002003200341b40a6a2902003703b008024002400240024020032802a00a2209450d00200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a280200210a200341ac0a6a2802002112200341a80a6a280200211320032903900a210520032903800a211a20032802a40a210120034188096a41206a201128020036020020034188096a41186a201029030037030020034188096a41106a200f29030037030020034188096a41086a200d290300370300200320032903b00837038809024020032802d409450d00200c10350b200341e0086a41086a220c20034188096a41086a290300370300200341e0086a41106a220d20034188096a41106a290300370300200341e0086a41186a220f20034188096a41186a290300370300200341e0086a41206a221020034188096a41206a280200360200200341f0066a41186a2007370300200341a0076a200a36020020034198076a2013360200200341f0066a41246a200136020020032003290388093703e00820032005370380072003201a3703f0062003201236029c072003200936029007200320043703f806200341c4076a2010280200360200200341bc076a200f290300370200200341b4076a200d290300370200200341ac076a200c290300370200200341a4076a20032903e008370200200e450d190240200e41246c2202450d00200341d0096a41086a220c200b41096a290000370300200341d0096a41106a220d200b41116a290000370300200341d0096a41186a220f200b41196a290000370300200341ef096a2210200b41206a2800003600002003200b2900013703d009200b2d000022114102470d020b4100210c0c020b024020032802d409450d00200c10350b41b6a6c0002109410d21014100210a0c190b200341800a6a41096a200c290300370000200341800a6a41116a200d290300370000200341800a6a41196a200f290300370000200341800a6a41206a2010280000360000200320113a00800a200320032903d0093700810a200341b0086a200341800a6a108b0220034188096a41086a200341b0086a41096a29000037030020034188096a41106a200341b0086a41116a29000037030020034188096a41186a200341b0086a41196a290000370300200320032900b108370388094101210c20032d00b0084101470d01200341f00b6a41086a200341e0086a41086a290300370300200341f00b6a41106a200341e0086a41106a290300370300200341f00b6a41186a200341e0086a41186a290300370300200320032903e0083703f00b0b4100210e4101210f02402008450d00200841246c450d00200b10350b410021020c190b200341d00b6a41086a220c20034188096a41086a290300370300200341d00b6a41106a220d20034188096a41106a290300370300200341d00b6a41186a221020034188096a41186a290300370300200320032903880922073703f00b200320073703d00b41201033220f450d11200f20032903d00b370000200f41186a2010290300370000200f41106a200d290300370000200f41086a200c29030037000020034281808080103702c40b2003200f3602c00b02400240200b20026a200b41246a460d00200341d0096a41086a2202200b412d6a290000370300200341d0096a41106a220c200b41356a290000370300200341d0096a41186a220d200b413d6a290000370300200341ef096a2210200b41c4006a2800003600002003200b2900253703d009200b2d002422114102460d00200341800a6a41096a2002290300370000200341800a6a41116a200c290300370000200341800a6a41196a200d290300370000200341800a6a41206a2010280000360000200320113a00800a200320032903d0093700810a200341b0086a200341800a6a108b0220034188096a41086a200341b0086a41096a29000037030020034188096a41106a200341b0086a41116a29000037030020034188096a41186a200341b0086a41196a290000370300200320032900b1083703880920032d00b0084101470d01200341f00b6a41086a200341e0086a41086a290300370300200341f00b6a41106a200341e0086a41106a290300370300200341f00b6a41186a200341e0086a41186a290300370300200320032903e0083703f00b4101210c410121020c190b4100210c410121020c180b200b41c8006a210d200341f00b6a41086a222420034188096a41086a221d2903002207370300200341d00b6a41186a221420034188096a41186a221e290300370300200341d00b6a41106a221520034188096a41106a221f290300370300200341d00b6a41086a22162007370300200320032903880922073703f00b200320073703d00b200e41246c41b87f6a2113200341b0086a4101722110200341800a6a410172210e200341d0096a411f6a210641202111410221024101210c0340200341800a6a41186a22172014290300370300200341800a6a41106a22182015290300370300200341800a6a41086a22192016290300370300200320032903d00b3703800a02402002417f6a200c470d00200341c00b6a200c4101108a0120032802c00b210f0b200f20116a220c20032903800a370000200c41186a2017290300370000200c41106a2018290300370000200c41086a2019290300370000200320023602c80b4100210c20024110460d182013450d18200341d0096a41086a2217200d41096a290000370300200341d0096a41106a2218200d41116a290000370300200341d0096a41186a2219200d41196a2900003703002006200d41206a2800003600002003200d2900013703d009200d2d000022234102460d18200e20032903d009370000200e41086a2017290300370000200e41106a2018290300370000200e41186a2019290300370000200e411f6a2006280000360000200320233a00800a200341b0086a200341800a6a108b02201d201041086a290000370300201f201041106a290000370300201e201041186a2900003703002003201029000037038809024020032d00b0084101470d00200341f00b6a41086a200341e0086a41086a290300370300200341f00b6a41106a200341e0086a41106a290300370300200341f00b6a41186a200341e0086a41186a290300370300200320032903e0083703f00b4101210c0c190b200d41246a210d2024201d29030022073703002014201e2903003703002015201f29030037030020162007370300200320032903880922073703f00b200320073703d00b201141206a2111200241016a21022013415c6a211320032802c40b210c0c000b0b41012102410021090c1e0b2001410c6a280200210a200141086a2802002108200141046a2802002109200141d0016a280200210b200341f0066a200141106a41c001109d081a200341d8086a20014180026a290300370300200341d0086a200141f8016a290300370300200341c8086a200141f0016a290300370300200341b0086a41106a200141e8016a290300370300200341b0086a41086a200141e0016a2903003703002003200141d8016a2903003703b0080240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000d0020022d000141ff01714102470d002003200a360290092003200836028c092003200936028809200341800a6a200341f0066a41c001109d081a200341d0096a41286a200341b0086a41286a290300370300200341d0096a41206a200341b0086a41206a290300370300200341d0096a41186a200341b0086a41186a290300370300200341d0096a41106a200341b0086a41106a290300370300200341d0096a41086a200341b0086a41086a290300370300200320032903b0083703d00920034188096a200341800a6a4102200341d0096a200b109302220941ff0171411d460d3c41dca2c0002102410e2108418080ec0021012009411f710e1d0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d010b200341f0066a10fa012008450d1d200841ffffffff0771450d1d200910350c1d0b200341940a6a4101360200200342013702840a200341e8d4ca003602800a200341043602d409200341f0d5ca003602d0092003200341d0096a3602900a200341800a6a41b0b4cc00104c000b41b6a6c0002102410d2108410021010c1a0b41aea6c0002102410821084180800421010c190b41a1a6c0002102410d21084180800821010c180b4194a6c0002102410d21084180800c21010c170b4188a6c0002102410c21084180801021010c160b41faa5c00021024180801421010c150b41e9a5c0002102411121084180801821010c140b41d8a5c0002102411121084180801c21010c130b41cca5c0002102410c21084180802021010c120b41bfa5c0002102410d21084180802421010c110b41b3a5c0002102410c21084180802821010c100b41a1a5c0002102411221084180802c21010c0f0b4187a5c0002102411a21084180803021010c0e0b41f5a4c0002102411221084180803421010c0d0b41e7a4c00021024180803821010c0c0b41d0a4c0002102411721084180803c21010c0b0b41baa4c000210241162108418080c00021010c0a0b41a7a4c000210241132108418080c40021010c090b418fa4c000210241182108418080c80021010c080b41fca3c000210241132108418080cc0021010c070b41e8a3c000210241142108418080d00021010c060b41d2a3c000210241162108418080d40021010c050b41bba3c000210241172108418080d80021010c040b41a2a3c000210241192108418080dc0021010c030b418da3c000210241152108418080e00021010c020b41fca2c000210241112108418080e40021010c010b41eaa2c000210241122108418080e80021010b410321090c010b41022109410021010b20004200370308200041206a20083602002000411c6a2002360200200041186a2001418080fc0071200972418010723602000c1e0b2001410c6a280200210a200141086a2802002108200141046a2802002109200141d0016a280200210b200341f0066a200141106a41c001109d081a200341d8086a20014180026a290300370300200341d0086a200141f8016a290300370300200341c8086a200141f0016a290300370300200341b0086a41106a200141e8016a290300370300200341b0086a41086a200141e0016a2903003703002003200141d8016a2903003703b0080240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000d0020022d00014101470d002003200a360290092003200836028c092003200936028809200341800a6a200341f0066a41c001109d081a200341d0096a41286a200341b0086a41286a290300370300200341d0096a41206a200341b0086a41206a290300370300200341d0096a41186a200341b0086a41186a290300370300200341d0096a41106a200341b0086a41106a290300370300200341d0096a41086a200341b0086a41086a290300370300200320032903b0083703d00920034188096a200341800a6a4101200341d0096a200b109302220941ff0171411d460d3b41dca2c0002102410e2108418080ec0021012009411f710e1d0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d010b200341f0066a10fa012008450d1d200841ffffffff0771450d1d200910350c1d0b200341940a6a4101360200200342013702840a200341e8d4ca003602800a200341043602d409200341f0d5ca003602d0092003200341d0096a3602900a200341800a6a41b0b4cc00104c000b41b6a6c0002102410d2108410021010c1a0b41aea6c0002102410821084180800421010c190b41a1a6c0002102410d21084180800821010c180b4194a6c0002102410d21084180800c21010c170b4188a6c0002102410c21084180801021010c160b41faa5c00021024180801421010c150b41e9a5c0002102411121084180801821010c140b41d8a5c0002102411121084180801c21010c130b41cca5c0002102410c21084180802021010c120b41bfa5c0002102410d21084180802421010c110b41b3a5c0002102410c21084180802821010c100b41a1a5c0002102411221084180802c21010c0f0b4187a5c0002102411a21084180803021010c0e0b41f5a4c0002102411221084180803421010c0d0b41e7a4c00021024180803821010c0c0b41d0a4c0002102411721084180803c21010c0b0b41baa4c000210241162108418080c00021010c0a0b41a7a4c000210241132108418080c40021010c090b418fa4c000210241182108418080c80021010c080b41fca3c000210241132108418080cc0021010c070b41e8a3c000210241142108418080d00021010c060b41d2a3c000210241162108418080d40021010c050b41bba3c000210241172108418080d80021010c040b41a2a3c000210241192108418080dc0021010c030b418da3c000210241152108418080e00021010c020b41fca2c000210241112108418080e40021010c010b41eaa2c000210241122108418080e80021010b410321090c010b41022109410021010b20004200370308200041206a20083602002000411c6a2002360200200041186a2001418080fc0071200972418010723602000c1d0b200341f0066a41186a200141196a290000370300200341f0066a41106a200141116a290000370300200341f8066a200141096a290000370300200320012900013703f006200341d0096a200341f0066a108e02200341800a6a20032802d009220120032802d809108f02200341800a6a41106a290300420020032903800a42015122021b210720032903880a420020021b2104200341a00a6a290300420020021b2105200341800a6a41186a290300420020021b211a024020032802d409450d00200110350b024002400240427f2004201a7c221a201a2004542202200720057c2002ad7c220420075420042007511b22021b427f200420021b844200520d00200341800a6a200341f0066a10910220032d00800a22024104460d0220032f00810a20032d00830a4110747241087422094180fe037121012009418080fc077121082009418080807871210920032902840a2207422088a7210a2007a7210b0c010b41b3a5c000210b410c210a410321024180102101418080282108410021090b20004200370308200041206a200a3602002000411c6a200b360200200041186a20092008722001722002723602000c1d0b200342f3e885db96cddbb3203703b008200341b0086a200341f0066a1092020c1a0b024020022d000120022d0000410047720d00200141046a280200210841f7edcb00ad4280808080f00084221a10012202280000210120022900042107200228000c21092002103541e4edcb00ad4280808080a001841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320013601b008200341e8066a200341b0086a412010c00120032802e8064101470d1a20032802ec062101201a10012202280000210920022900042107200228000c210a2002103541b5edcb00ad4280808080c0018422041001220229000021052002290008211a200210352003201a3701c808200320053701c0082003200a3601bc08200320073701b408200320093601b008200341e0066a200341b0086a412010c00102404100200120032802e40641d40020032802e0061b6b2202200220014b1b22024100200120086b2209200920014b1b22014f0d000340200210c1012001200241016a2202470d000b0b41f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21092002103520041001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320013601b008200320083602800a200341b0086aad4280808080800484200341800a6aad4280808080c0008410020c1a0b20004200370308200041186a41023602000c1b0b200141106a2903002107200141086a290300211b2002411a6a290100211c200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113410e21012002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d00002118200241086a2d00002119200241066a2f01002106200241056a2d0000211d200241046a2d0000211e200241026a2f0100211f20022d0001210b20022d0000210a41f7edcb00ad4280808080f0008410012202280000210820022900042104200228000c21092002103541b6aac000ad42808080809002841001220229000021052002290008211a200210352003201a3701c808200320053701c008200320093601bc08200320043701b408200320083601b008200341d8066a200341b0086a10f201410321020240024020032802d806417d71450d0041dca2c0002108418090ec0021090c010b02400240200a41ff01710d00200b41ff01714101470d002003201c3703880c2003200c3a00870c2003200d3a00860c2003200e3b01840c2003200f3a00830c200320103a00820c200320113b01800c200320123a00ff0b200320133a00fe0b200320143b01fc0b200320153a00fb0b200320163a00fa0b200320173b01f80b200320183a00f70b200320193a00f60b200320063b01f40b2003201d3a00f30b2003201e3a00f20b2003201f3b01f00b200341f0066a200341f00b6a10b701200341800a6a20032802f006220820032802f80610d601200341b0086a41086a220a200341bc0a6a290200370300200341b0086a41106a220b200341c40a6a290200370300200341b0086a41186a220c200341cc0a6a290200370300200341b0086a41206a220d200341d40a6a2802003602002003200341b40a6a2902003703b00820032802a00a2209450d01200341800a6a41186a290300211c200341800a6a41086a2903002129200341b00a6a280200210f200341ac0a6a2802002110200341a80a6a280200210120032903900a212020032903800a212a20032802a40a210e20034188096a41206a200d28020036020020034188096a41186a200c29030037030020034188096a41106a200b29030037030020034188096a41086a200a290300370300200320032903b00837038809024020032802f406450d00200810350b200341e0086a41106a20034188096a41106a2903002204370300200341d0096a41086a220820034188096a41086a290300370300200341d0096a41106a220a2004370300200341d0096a41186a220b20034188096a41186a290300370300200341d0096a41206a220c20034188096a41206a28020036020020032003290388093703d00902402001450d00200341f0066a41206a200c280200360200200341f0066a41186a200b290300370300200341f0066a41106a200a290300370300200341f0066a41086a2008290300370300200320032903d0093703f006200141186c20096a41686a2102420021214200212202400340024020010d00410021010c020b02402002290300220420217c2205201b58200241086a290300222b20227c2005200454ad7c221a200758201a20075122081b0d0020022004201b20217d22057d3703002002202b200720227d201b202154ad7d22077d2004200554ad7d3703082007201c7c200520207c2220200554ad7c211c0c020b2001417f6a2101202b201c7c200420207c2220200454ad7c211c200241686a210220052121201a21222005201b54201a20075420081b0d000b0b200341800a6a41186a201c370300200341b00a6a200f360200200341a80a6a2001360200200341a40a6a200e360200200341b40a6a20032903f006370200200341bc0a6a200341f8066a290300370200200341c40a6a20034180076a290300370200200341cc0a6a200341f0066a41186a290300370200200341d40a6a20034190076a280200360200200320203703900a2003202a3703800a200320103602ac0a200320093602a00a200320293703880a200342f3e885db96cddbb3203703880920034188096a200341b80a6a202a2029411f109002200341f0066a200341f00b6a10b70120032802f0062102200320032802f8063602b408200320023602b008200341800a6a200341b0086a10e101024020032802f406450d00200210350b024020032802a40a2202450d00200241186c450d0020032802a00a10350b20032802b00a41ffffffff0371450d1c20032802ac0a10350c1c0b0240200e450d00200e41186c450d00200910350b0240200f41ffffffff0371450d00201010350b41bfa5c0002108410d21014180902421090c020b4102210241801021090c010b024020032802f406450d00200810350b41b6a6c0002108410d210141801021090b20004200370308200041206a20013602002000411c6a2008360200200041186a20092002723602000c1a0b200141246a280200210a20022d0001210b20022d00002109200341c8096a200141196a290000370300200341c0096a200141116a290000370300200341b8096a200141096a290000370300200320012900013703b00941f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21082002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701e80b200320043701e00b200320083601dc0b200320073701d40b200320013601d00b200341d0066a200341d00b6a10f201410321020240024002400240024002400240024002400240024020032802d006417d710d0041022102200941ff01710d00200b41ff01714101470d00200341f00b6a41186a200341b0096a41186a290300370300200341f00b6a41106a200341b0096a41106a290300370300200341f00b6a41086a200341b0096a41086a290300370300200320032903b0093703f00b41f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21082002103541e4edcb00ad4280808080a001841001220229000021042002290008210520021035200320053701e80b200320043701e00b200320083601dc0b200320073701d40b200320013601d00b200341c8066a200341d00b6a412010c00141a1a5c0002101411221084180802c210920032802c806450d0220032802cc06220b200a490d0241f7edcb00ad4280808080f00084221a10012202280000210c20022900042107200228000c210d2002103541b5edcb00ad4280808080c001841001220229000021042002290008210520021035200320053701e80b200320043701e00b2003200d3601dc0b200320073701d40b2003200c3601d00b200341c0066a200341d00b6a412010c001200a4100200b20032802c40641d40020032802c0061b6b22022002200b4b1b220b490d02201a10012202280000210c20022900042107200228000c210d2002103541eeeecb00ad4280808080a001841001220229000021042002290008210520021035200320053701e80b200320043701e00b2003200d3601dc0b200320073701d40b2003200c3601d00b200341b8066a200341d00b6a412010c001024020032802b8064101470d0020032802bc06200a4b0d030b200341800a6a200a10be01200341a0066a20032802800a220c20032802880a10d701200341b0066a290300210420032903a806210720032802a0062102024020032802840a450d00200c10350b2002450d02200341f0066a200341f00b6a10b401200341800a6a20032802f006220120032802f80610d501200341990a6a2900002105200341980a6a2d00002108200341970a6a2d00002109200341950a6a2f0000210c200341940a6a2d0000210d200341930a6a2d0000210e200341910a6a2f0000210f200341900a6a2d000021102003418f0a6a2d000021112003418d0a6a2f000021122003418c0a6a2d000021132003418b0a6a2d00002114200341890a6a2f00002115200341880a6a2d0000211620032d00870a211720032f00850a211820032d00840a211920032d00830a210620032d00820a211d20032d00810a211e20032d00800a2102024020032802f406450d00200110350b200241ff01714101470d01200320053703e809200320083a00e709200320093a00e6092003200c3b01e4092003200d3a00e3092003200e3a00e2092003200f3b01e009200320103a00df09200320113a00de09200320123b01dc09200320133a00db09200320143a00da09200320153b01d809200320163a00d709200320173a00d609200320183b01d409200320193a00d309200320063a00d2092003201d3a00d1092003201e3a00d009200341e0086a200341d0096a10b701200341800a6a20032802e008220220032802e80810d601200341b0086a41086a2208200341bc0a6a290200370300200341b0086a41106a2209200341c40a6a290200370300200341b0086a41186a220c200341cc0a6a290200370300200341b0086a41206a220d200341d40a6a2802003602002003200341b40a6a2902003703b00802400240024020032802a00a220e450d00200341800a6a41186a2903002105200341800a6a41086a290300211a200341b00a6a280200210f200341ac0a6a2802002101200341a80a6a280200211020032903900a211b20032903800a211c20032802a40a211120034188096a41206a200d28020036020020034188096a41186a200c29030037030020034188096a41106a200929030037030020034188096a41086a2008290300370300200320032903b00837038809024020032802e408450d00200210350b200341f0066a41186a2005370300200341a0076a200f36020020034198076a201036020020034194076a2011360200200341a4076a2202200329038809370200200341ac076a20034190096a290300370200200341b4076a20034198096a290300370200200341bc076a20034188096a41186a290300370200200341c4076a200341a8096a2802003602002003201b370380072003201c3703f0062003200136029c072003200e360290072003201a3703f8060240200228020022090d0041002108410021020c030b41002102410021080340024002400240200b2001280200220c4b0d0020020d01410021020c020b200241016a21020c010b200820026b220d20094f0d08200120024102746b220d280200210e200d200c3602002001200e3602000b200141046a21012009200841016a2208470d000b024002402002450d0020032802a407220c200920026b2202490d01200320023602a4072002210c0c010b20032802a407210c0b200328029c0721014100210802400240200c41014b0d0041002102200c0e020401040b200c2102034020082002410176220920086a220b200a2001200b4102746a280200491b2108200220096b220241014b0d000b0b41032102200a200120084102746a2802002209470d010c0a0b024020032802e408450d00200210350b41b6a6c0002101410d210841032102410021090c0a0b200c2008200a20094b6a2208490d05200c21020b0240200220032802a007470d002003419c076a20024101108601200328029c0721010b200120084102746a220141046a2001200220086b410274109e081a2001200a3602002003200241016a3602a407200341b0086a200a200341a8076a220c10d101200341800a6a20032802b008220220032802b8081085020240024020032802a00a22160d00420021054100211541082116410021104200211a4200211c420021200c010b200341880a6a2903002120200341980a6a290300211a200341a80a6a280200211020032903800a211c20032903900a210520032802a40a21150b024020032802b408450d00200210350b200341800a6a200341d0096a10b70120032802800a2102200320032802880a3602b408200320023602b008200341f0066a200341b0086a10e101024020032802840a450d00200210350b200341d00b6a200a10940241042102200341d00b6a41047221170240024020032802d40b220d450d0020032802d00b2111200341d00b6a41086a280200210e0340200d41086a2108200d2f0106220f4105742101410021090240024003402001450d01200c2008412010a008220b450d02200141606a2101200941016a2109200841206a2108200b417f4a0d000b2009417f6a210f0b200e450d02200e417f6a210e200d200f4102746a4194036a280200210d0c010b0b200d20094102746a41e8026a2802002201450d0020114101201141014b1b2202418094ebdc036e220820022008418094ebdc036c476a22084101200841014b1b220820024b0d0720034188066a20072004428094ebdc034200109808200341f8056a200329038806220420034188066a41086a290300221b4280ec94a37c427f108408200341e8056a2004201b2002200120022001491b20086ead428094ebdc037e200220086ead8042ffffffff0f8322214200108408200341800a6a200a200341f00b6a10d30120034198066a20032802800a220120032802880a10d201200341e8056a41086a29030020032903e80522042021200720032903f8057c7e2207428094ebdc0380221ba7417f2007428080808080c0b2cd3b541b2007201b4280ec94a37c7e7c4280cab5ee01566aad7c2207200454ad7c211b200328029c0641002003280298061b2102024020032802840a450d00200110350b200341c0056a2007201b428094ebdc034200109808200341b0056a20032903c0052204200341c0056a41086a29030022214280ec94a37c427f108408200341a0056a200420212002ad2222420010840820034190056a200720032903a00522212022200720032903b0057c7e2204428094ebdc03802222a7417f2004428080808080c0b2cd3b541b200420224280ec94a37c7e7c4280cab5ee01566aad7c22047d222b201b200341a0056a41086a2903002004202154ad7c22297d2007200454ad7d428094ebdc03420010980820034180056a200329039005222120034190056a41086a29030022224280ec94a37c427f108408200341f0046a202120222005201a201c2020109502ad22054200108408200341d0056a200c20032903f004221a20047c2207202b2003290380057c222b20057e2204428094ebdc03802205a7417f2004428080808080c0b2cd3b541b200420054280ec94a37c7e7c4280cab5ee01566aad7c2204200341f0046a41086a29030020297c2007201a54ad7c2004200754ad7c109602200341d0056a41106a290300210720032903d805210420032903d0052205a74101470d01200341b0076a2903002105200341b8076a290300211a200341c0076a290300211b20032903a8072129200341b80a6a2007370300200341b00a6a2004370300200341a10a6a201b370000200341990a6a201a370000200341910a6a2005370000200341890a6a2029370000200341800a6a41086a220241013a0000200341043a00800a41b0b4cc004100200341800a6a10d40120034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a2002200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e008200341c0046a200341e0086a412010d701200341c0046a41106a290300211b20032903c804212920032802c0042109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c2029420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020c080b201710b1012015450d08201541306c450d08201610350c080b20054201520d0620034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a200341800a6a41086a2202200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e008200341d8046a200341e0086a412010d701200341d8046a41106a290300211b20032903e004212920032802d8042109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c2029420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020c060b41dca2c0002101410e2108418080ec0021090c080b41aea6c0002101410821084180800421090b410321020c060b200d200941f485cc001042000b2008200c104d000b4190edc40041194180efc400103f000b0240201041306c2202450d00201620026a210f201641286a2102200341800a6aad4280808080800284212a200341e0086aad4280808080800484212c20034188096a41106a2101200341890a6a210b200341b80a6a2114034020034198046a20212022200241586a2208290300200841086a290300201c2020109502ad22074200108408200341a8046a200241686a220a20032903980422042007202b7e2207428094ebdc03802205a7417f2007428080808080c0b2cd3b541b200720054280ec94a37c7e7c4280cab5ee01566aad7c220720034198046a41086a2903002007200454ad7c109602200341a8046a41106a290300210720032903b004210402400240024020032903a8042205a74101470d00200241786a2900002105200a290000211a2002290000211b2003200241706a29000022293701b8082003201a3701b008200320053701c0082003201b3701c808200b201a370000200b41086a2029370000200b41106a2005370000200b41186a201b370000200320043703b00a20142007370300200341013a00880a200341043a00800a41b0b4cc004100200341800a6a10d40120034188096a41186a220c42003703002001420037030020034188096a41086a22094200370300200342003703880941b6fdc600ad428080808080018422051001220d290000211a200341800a6a41086a2208200d41086a2900003703002003201a3703800a200d103520092008290300370300200320032903800a3703880941e489c200ad4280808080d00184221a1001220d290000211b2008200d41086a2900003703002003201b3703800a200d1035200120032903800a370000200141086a22102008290300370000200341e0086a41086a22112009290300370300200341e0086a41106a22122001290300370300200341e0086a41186a2213200c29030037030020032003290388093703e008200341e8036a200341e0086a412010d701200341e8036a41106a290300211b20032903f003212920032802e803210d200c42003703002001420037030020094200370300200342003703880920051001220e29000021052008200e41086a290000370300200320053703800a200e103520092008290300370300200320032903800a37038809201a1001220e29000021052008200e41086a290000370300200320053703800a200e1035200120032903800a3700002010200829030037000020112009290300370300201220012903003703002013200c29030037030020032003290388093703e0082003427f201b4200200d1b220520077c20294200200d1b220720047c22042007542208ad7c22072008200720055420072005511b22081b3703880a2003427f200420081b3703800a0c010b20054201520d0120034188096a41186a220c42003703002001420037030020034188096a41086a22094200370300200342003703880941b6fdc600ad428080808080018422051001220d290000211a200341800a6a41086a2208200d41086a2900003703002003201a3703800a200d103520092008290300370300200320032903800a3703880941e489c200ad4280808080d00184221a1001220d290000211b2008200d41086a2900003703002003201b3703800a200d1035200120032903800a370000200141086a22102008290300370000200341e0086a41086a22112009290300370300200341e0086a41106a22122001290300370300200341e0086a41186a2213200c29030037030020032003290388093703e00820034180046a200341e0086a412010d70120034180046a41106a290300211b2003290388042129200328028004210d200c42003703002001420037030020094200370300200342003703880920051001220e29000021052008200e41086a290000370300200320053703800a200e103520092008290300370300200320032903800a37038809201a1001220e29000021052008200e41086a290000370300200320053703800a200e1035200120032903800a3700002010200829030037000020112009290300370300201220012903003703002013200c29030037030020032003290388093703e0082003427f201b4200200d1b220520077c20294200200d1b220720047c22042007542208ad7c22072008200720055420072005511b22081b3703880a2003427f200420081b3703800a0b202c202a10020b200241306a2102200a41206a200f470d000b0b201710b10102402015450d00201541306c450d00201610350b02402003280294072202450d00200241186c450d0020032802900710350b024020032802a00741ffffffff0371450d00200328029c0710350b420021070c030b02402003280294072201450d00200141186c450d0020032802900710350b41e7a4c0002101410e210841808038210920032802a00741ffffffff0371450d00200328029c0710350b4200210720024104460d010b200041206a20083602002000411c6a2001360200200041186a2009418080fc007120027241801072360200420121070b200042003703080c1a0b4102210802400240024002400240024002400240024002400240024020022d00000d0020022d00014101470d00200141046a28020021082002411a6a2901002107200241196a2d00002109200241186a2d0000210a200241166a2f0100210b200241156a2d0000210c200241146a2d0000210d200241126a2f0100210e200241116a2d0000210f200241106a2d000021102002410e6a2f010021112002410d6a2d000021122002410c6a2d000021132002410a6a2f01002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f010021012003200241096a2d00003a00d70b200320153a00d60b200320163b01d40b200320173a00d30b200320183a00d20b200320013a00d00b200320014108763a00d10b2003200f3a00df0b200320103a00de0b200320113b01dc0b200320123a00db0b200320133a00da0b200320143b01d80b200320093a00e70b2003200a3a00e60b2003200b3b01e40b2003200c3a00e30b2003200d3a00e20b2003200e3b01e00b200320073701e80b200341e8096a2007370300200341e0096a20032901e00b370300200341d0096a41086a20032901d80b370300200320032901d00b3703d00941f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c21092002103541eeeecb00ad4280808080a001841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320013601b008200341e0036a200341b0086a412010c00141a1a5c0002102411221094180802c210120032802e003450d0420032802e40320084d0d0441f7edcb00ad4280808080f000841001220a280000210b200a2900042107200a28000c210c200a103541e4edcb00ad4280808080a001841001220a2900002104200a2900082105200a1035200320053701c808200320043701c0082003200c3601bc08200320073701b4082003200b3601b008200341d8036a200341b0086a412010c00120032802d803450d0420032802dc03220b2008490d0441f7edcb00ad4280808080f000841001220a280000210c200a2900042107200a28000c210d200a103541b5edcb00ad4280808080c001841001220a2900002104200a2900082105200a1035200320053701c808200320043701c0082003200d3601bc08200320073701b4082003200c3601b008200341d0036a200341b0086a412010c0014100200b20032802d40341d40020032802d0031b6b220a200a200b4b1b220a20084b0d04200341800a6a200810be01200341b8036a20032802800a220c20032802880a10d701200341c8036a290300210420032903c003210720032802b803210b024020032802840a450d00200c10350b200b450d04200341e0086a200341d0096a10b701200341800a6a20032802e008220220032802e80810d601200341b0086a41086a2201200341bc0a6a290200370300200341b0086a41106a2209200341c40a6a290200370300200341b0086a41186a220b200341cc0a6a290200370300200341b0086a41206a220c200341d40a6a2802003602002003200341b40a6a2902003703b0080240024020032802a00a220d450d00200341800a6a41186a2903002105200341800a6a41086a290300211a200341b00a6a280200210e200341ac0a6a280200210f200341a80a6a280200211020032903900a211b20032903800a211c20032802a40a211120034188096a41206a200c28020036020020034188096a41186a200b29030037030020034188096a41106a200929030037030020034188096a41086a2001290300370300200320032903b00837038809024020032802e408450d00200210350b200341f0066a41186a2005370300200341a0076a200e36020020034198076a201036020020034194076a2011360200200341a4076a200329038809370200200341ac076a20034190096a290300370200200341b4076a20034198096a290300370200200341bc076a20034188096a41186a290300370200200341c4076a200341a8096a2802003602002003201b370380072003201c3703f0062003200f36029c072003200d360290072003201a3703f80641f7edcb00ad4280808080f0008410012202280000210120022900042105200228000c21092002103541b6aac000ad428080808090028410012202290000211a2002290008211b200210352003201b3701c8082003201a3701c008200320093601bc08200320053701b408200320013601b008200341b0036a200341b0086a10f20120032802b003417d71450d01200341800a6a200341a8076a108c0220032802800a220220032802880a10970241ff01712109024020032802840a450d00200210350b200941034b0d0141dca2c0002102418080ec00210120090e0405010105050b024020032802e408450d00200210350b41b6a6c0002102410d210941002101410321080c080b200328029c072102024020032802a407220b0d0041002101410021090c070b41002101410021090340024002400240200a2002280200220c4b0d0020010d01410021010c020b200141016a21010c010b200920016b220d200b4f0d03200220014102746b220d280200210e200d200c3602002002200e3602000b200241046a2102200b200941016a2209470d000b024002402001450d0020032802a407220c200b20016b2202490d01200320023602a4072002210c0c010b20032802a407210c0b200328029c072102410021010240200c41014b0d0041002109200c0e020703070b200c2109034020012009410176220a20016a220b20082002200b4102746a280200491b21012009200a6b220941014b0d000c030b0b410021010c060b200d200b41f485cc001042000b2008200220014102746a2802002209470d0241e7a4c00021024180803821010b02402003280294072208450d00200841186c450d0020032802900710350b024020032802a00741ffffffff0371450d00200328029c0710350b410e21090b410321080c020b200c2001200820094b6a2201490d02200c21090b0240200920032802a007470d002003419c076a20094101108601200328029c0721020b200220014102746a220241046a2002200920016b410274109e081a200220083602002003200941016a3602a407200341800a6a200341d0096a10b70120032802800a2102200320032802880a3602b408200320023602b008200341f0066a200341b0086a10e101024020032802840a450d00200210350b200341b0086a2008109402200341800a6a2008200341a8076a220a10d301200341a8036a20032802800a220220032802880a10d20120032802a803210f20032802ac032110024020032802840a450d00200210350b20034188096a2008200a10d101200341800a6a20032802880922022003280290091085020240024020032802a00a22120d0042002105410821124100210e4200211a4200211b4200211c0c010b200341880a6a290300211a200341980a6a290300211c20032903800a210520032903900a211b20032802a40a210e0b0240200328028c09450d00200210350b201b201c2005201a10950221110240024020032802b408220b0d00410021010c010b200341b0086a41086a280200210c0340200b41086a2101200b2f0106220d4105742102410021080240024003402002450d01200a2001412010a0082209450d02200241606a2102200841016a2108200141206a21012009417f4a0d000b2008417f6a210d0b0240200c0d00410021010c030b200c417f6a210c200b200d4102746a4194036a280200210b0c010b0b200b20084102746a41e8026a28020021010b20032802b00822024101200241014b1b2202418094ebdc036e220820022008418094ebdc036c476a22084101200841014b1b220820024b0d0220034180036a20072004428094ebdc034200109808200341f0026a200329038003220420034180036a41086a29030022054280ec94a37c427f1084082003418094ebdc033602840a20032011ad4100418094ebdc0320104100200f1b22096b220b200b418094ebdc034b1bad7e428094ebdc0380a7220b3602800a200341800a6a200b418094ebdc034b4102746a280200210b2003418094ebdc033602840a2003417f2009200b6a220b200b2009491b22093602800a200341800a6a2009418094ebdc034b4102746a350200211a2003418094ebdc033602840a2003201a2002200120022001491b20086ead428094ebdc037e200220086ead8042ffffffff0f837e428094ebdc0380a722023602800a200341e0026a20042005200341800a6a2002418094ebdc034b4102746a350200221a420010840820034190036a200a20032903e0022204201a200720032903f0027c7e2207428094ebdc03802205a7417f2007428080808080c0b2cd3b541b200720054280ec94a37c7e7c4280cab5ee01566aad7c2207200341e0026a41086a2903002007200454ad7c10960220034190036a41106a2903002107200329039803210402402003290390032205a74101470d0020032903d009210520032903d809211a20032903e009211b20032903e809211c200341b80a6a2007370300200341b00a6a2004370300200341a10a6a201c370000200341990a6a201b370000200341910a6a201a370000200341890a6a2005370000200341800a6a41086a220241013a0000200341043a00800a41b0b4cc004100200341800a6a10d40120034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a2002200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e008200341b0026a200341e0086a412010d701200341b0026a41106a290300211b20032903b802211c20032802b0022109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c201c420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020c040b20054201520d0320034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a200341800a6a41086a2202200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e008200341c8026a200341e0086a412010d701200341c8026a41106a290300211b20032903d002211c20032802c8022109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c201c420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020c030b200041206a20093602002000411c6a2002360200200041186a2001418080fc007120087241801072360200420121070c030b2001200c104d000b4190edc40041194180efc400103f000b200341b0086a41047221020240200e450d00200e41306c450d00201210350b200210b10102402003280294072202450d00200241186c450d0020032802900710350b024020032802a00741ffffffff0371450d00200328029c0710350b420021070b200042003703080c190b2001410c6a2802002108200141086a280200210b41022109024002400240024002400240024002400240024002400240024020022d00000d0020022d00014101470d00200141106a280200210c200141046a28020021092002411a6a2901002107200241196a2d0000210a200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d000021132002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241086a2d00002118200241066a2f01002119200241056a2d00002106200241046a2d0000211d200241026a2f010021012003200241096a2d00003a00d70b200320183a00d60b200320193b01d40b200320063a00d30b2003201d3a00d20b200320013a00d00b200320014108763a00d10b200320123a00df0b200320133a00de0b200320143b01dc0b200320153a00db0b200320163a00da0b200320173b01d80b2003200a3a00e70b2003200d3a00e60b2003200e3b01e40b2003200f3a00e30b200320103a00e20b200320113b01e00b200320073701e80b200341880c6a2007370300200341f00b6a41106a20032901e00b370300200341f00b6a41086a20032901d80b370300200320032901d00b3703f00b0240200c41104d0d004187a5c0002102411a210a410c21010c0b0b41f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c210a2002103541eeeecb00ad4280808080a001841001220229000021042002290008210520021035200320053701c808200320043701c0082003200a3601bc08200320073701b408200320013601b008200341a8026a200341b0086a412010c00141a1a5c00021024112210a410b210120032802a802450d0a200920032802ac024f0d0a41f7edcb00ad4280808080f000841001220d280000210e200d2900042107200d28000c210f200d103541e4edcb00ad4280808080a001841001220d2900002104200d2900082105200d1035200320053701c808200320043701c0082003200f3601bc08200320073701b4082003200e3601b008200341a0026a200341b0086a412010c00120032802a002450d0a200920032802a402220e4b0d0a41f7edcb00ad4280808080f000841001220d280000210f200d2900042107200d28000c2110200d103541b5edcb00ad4280808080c001841001220d2900002104200d2900082105200d1035200320053701c808200320043701c008200320103601bc08200320073701b4082003200f3601b00820034198026a200341b0086a412010c00120094100200e200328029c0241d4002003280298021b6b220d200d200e4b1b220d490d0a200341800a6a200910be0120034180026a20032802800a220f20032802880a10d70120034190026a290300211a2003290388022105200328028002210e024020032802840a450d00200f10350b200e450d0a200341d0096a200341f00b6a10b701200341800a6a20032802d009220220032802d80910d601200341b0086a41086a2201200341bc0a6a290200370300200341b0086a41106a220a200341c40a6a290200370300200341b0086a41186a220e200341cc0a6a290200370300200341b0086a41206a220f200341d40a6a2802003602002003200341b40a6a2902003703b0080240024020032802a00a2210450d00200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a2802002111200341ac0a6a2802002112200341a80a6a280200211320032903900a211b20032903800a211c20032802a40a211420034188096a41206a200f28020036020020034188096a41186a200e29030037030020034188096a41106a200a29030037030020034188096a41086a2001290300370300200320032903b00837038809024020032802d409450d00200210350b200341f0066a41186a2007370300200341a0076a201136020020034198076a201336020020034194076a2014360200200341a4076a200329038809370200200341ac076a20034190096a290300370200200341b4076a20034198096a290300370200200341bc076a20034188096a41186a290300370200200341c4076a200341a8096a2802003602002003201b370380072003201c3703f0062003201236029c072003201036029007200320043703f80641f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c210a2002103541b6aac000ad42808080809002841001220229000021042002290008211b200210352003201b3701c808200320043701c0082003200a3601bc08200320073701b408200320013601b008200341f8016a200341b0086a10f20120032802f801417d71450d01200341800a6a200341a8076a108c0220032802800a220220032802880a10970241ff0171210a024020032802840a450d00200210350b200a41034b0d0141dca2c0002102411b2101200a0e0406010106060b024020032802d409450d00200210350b41b6a6c0002102410d210a410021010c0b0b200328029c072102024020032802a407220e0d00410021014100210a0c070b410021014100210a0340024002400240200d2002280200220f4b0d0020010d01410021010c020b200141016a21010c010b200a20016b2210200e4f0d03200220014102746b221028020021112010200f360200200220113602000b200241046a2102200e200a41016a220a470d000b024002402001450d0020032802a407220f200e20016b2202490d01200320023602a4072002210f0c010b20032802a407210f0b200328029c072102410021010240200f41014b0d004100210a200f0e020704070b200f210a03402001200a410176220d20016a220e20092002200e4102746a280200491b2101200a200d6b220a41014b0d000c040b0b2008450d01200841246c450d01200b10350c0a0b2010200e41f485cc001042000b0c080b2009200220014102746a280200220a470d0141e7a4c0002102410e21010b02402003280294072209450d00200941186c450d0020032802900710350b024020032802a00741ffffffff0371450d00200328029c0710350b410e210a0c050b200f20012009200a4b6a2201490d01200f210a0b0240200a20032802a007470d002003419c076a200a4101108601200328029c0721020b200220014102746a220241046a2002200a20016b410274109e081a200220093602002003200a41016a3602a407200341800a6a200341f00b6a10b70120032802800a2102200320032802880a3602d409200320023602d009200341f0066a200341d0096a10e101024020032802840a450d00200210350b200341b0086a20091094020240200c41246c22020d00410021150c030b200b20026a2213415c6a2118200341a8076a2110200b2101410021150340200121020340200241206a2802002101200341d0096a41186a200241186a290000370300200341d0096a41106a200241106a290000370300200341d0096a41086a200241086a290000370300200320022900003703d009200341800a6a2009200341d0096a10d301200341f0016a20032802800a220a20032802880a10d20120032802f001211120032802f4012112024020032802840a450d00200a10350b20034188096a2009200341d0096a10d101200341800a6a200328028809220e2003280290091085020240024020032802a00a220c0d00420021074100210d4108210c4100210a420021040c010b200341800a6a41086a290300210420032903800a210720032802a40a210d20032802a80a210a0b0240200328028c09450d00200e10350b02400240200a20014d0d00200c200141306c6a2201450d0002402010200141106a220a460d00200a2010412010a0080d020b2001290300200141086a2903002007200410950221190240024020032802b40822140d004100210a0c010b20032802b80821160340201441086a210a20142f0106221741057421014100210e0240024003402001450d01200341d0096a200a412010a008220f450d02200141606a2101200e41016a210e200a41206a210a200f417f4a0d000b200e417f6a21170b024020160d004100210a0c030b2016417f6a2116201420174102746a4194036a28020021140c010b0b2014200e4102746a41e8026a280200210a0b20032802b00822014101200141014b1b2201418094ebdc036e220e2001200e418094ebdc036c476a220e4101200e41014b1b220e20014b0d052003418094ebdc033602840a20032001200a2001200a491b200e6ead428094ebdc037e2001200e6ead8042ffffffff0f834100418094ebdc032012410020111b6b22012001418094ebdc034b1bad7e428094ebdc0380a722013602800a200341800a6a2001418094ebdc034b4102746a35020021072003418094ebdc033602840a200320072019ad7e428094ebdc0380a722013602800a200341800a6a2001418094ebdc034b4102746a28020021012003418094ebdc033602840a2003417f201520016a220120012015491b22013602800a200341800a6a2001418094ebdc034b4102746a28020021150b0240200d450d00200d41306c450d00200c10350b200241246a210120182002460d050c020b200241246a21020240200d450d00200d41306c450d00200c10350b20132002460d040c000b0b0b2001200f104d000b4190edc40041194180efc400103f000b02402008450d00200841246c450d00200b10350b200341c8016a2005201a428094ebdc034200109808200341b8016a20032903c8012207200341c8016a41086a29030022044280ec94a37c427f108408200341a8016a200720042015ad221a4200108408200341d8016a200341f0066a41386a20032903a8012204201a200520032903b8017c7e2207428094ebdc03802205a7417f2007428080808080c0b2cd3b541b200720054280ec94a37c7e7c4280cab5ee01566aad7c2207200341a8016a41086a2903002007200454ad7c109602200341d8016a41106a290300210720032903e00121040240024020032903d8012205a74101470d0020032903f00b210520032903f80b211a20032903800c211b20032903880c211c200341800a6a41386a2007370300200341b00a6a2004370300200341a10a6a201c370000200341990a6a201b370000200341910a6a201a370000200341890a6a2005370000200341800a6a41086a220241013a0000200341043a00800a41b0b4cc004100200341800a6a10d40120034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a2002200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e008200341f8006a200341e0086a412010d701200341f8006a41106a290300211b200329038001211c20032802782109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c201c420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020c010b20054201520d0020034188096a41186a220a420037030020034188096a41106a2208420037030020034188096a41086a22014200370300200342003703880941b6fdc600ad4280808080800184220510012209290000211a200341800a6a41086a2202200941086a2900003703002003201a3703800a2009103520012002290300370300200320032903800a3703880941e489c200ad4280808080d00184221a10012209290000211b2002200941086a2900003703002003201b3703800a20091035200820032903800a221b370300200341e0086a41086a220b2001290300370300200341e0086a41106a220c201b370300200341e0086a41186a220d200229030037030020032003290388093703e00820034190016a200341e0086a412010d70120034190016a41106a290300211b200329039801211c2003280290012109200a42003703002008420037030020014200370300200342003703880920051001220a29000021052002200a41086a290000370300200320053703800a200a103520012002290300370300200320032903800a37038809201a1001220a29000021052002200a41086a290000370300200320053703800a200a1035200820032903800a2205370300200b2001290300370300200c2005370300200d200229030037030020032003290388093703e0082003427f201b420020091b220520077c201c420020091b220720047c22042007542202ad7c22072002200720055420072005511b22021b3703880a2003427f200420021b3703800a200341e0086aad4280808080800484200341800a6aad428080808080028410020b200341b0086a41047210b10102402003280294072202450d00200241186c450d0020032802900710350b024020032802a00741ffffffff0371450d00200328029c0710350b420021070c020b02402008450d00200841246c450d00200b10350b410321090b200041206a200a3602002000411c6a2002360200200041186a200141ff017141107420097241801072360200420121070b200042003703080c180b4102210a200241036a2d0000210820022f00012109200141106a280200210b2001410c6a2802002113200141086a2802002112200141046a280200211402400240024020022d0000220c417f6a220141024b0d00024020010e03000102000b200241046a2d00000d00200241086a2802004102742002410c6a28020041036c4f0d010b2009200841107472200c4100477241ff0171450d0041801021020c010b4103210a0240200b0d004188a6c0002108410c21014180901021020c010b200b41016a210120122102024003402001417f6a22014102490d01200241046a210820022802002109200241046a210220092008280200490d000b41f5a4c0002108411221014180903421020c010b200341800a6a201410dc01200341f0066a20032802800a220120032802880a10dd0120032902f406420020032802f00622021b2107024020032802840a450d00200110350b2002410820021b211102400240200b410274220b20126a417c6a2802002007422088a722024f0d0041002101417f210820122109034020012009280200220c6a22022007422088a7220d4f0d022011200241d8006c6a220228022c210f20022802202110200241306a280200210e200241246a280200210a2002200241d8006a2008200d6a200c6b41d8006c109e081a0240200a450d00200a41306c450d00201010350b0240200e41ffffff3f71450d00200f10350b200941046a210920074280808080707c2107200841016a21082001417f6a2101200b417c6a220b0d000b0240201341ffffffff0371450d00201210350b200341f0066a201410dc0120032802f006210220033502f8062104200341800a6a20112007422088a7220110ea0120044220862002ad8420033502880a42208620032802800a2208ad841002024020032802840a450d00200810350b024020032802f406450d00200210350b02402001450d00201141306a21022007422088a741d8006c210103400240200241746a2802002208450d00200841306c450d00200241706a28020010350b0240200228020041ffffff3f71450d002002417c6a28020010350b200241d8006a2102200141a87f6a22010d000b0b2007a72202450d17200241d8006c450d17201110350c170b02402002450d00200241d8006c2101201141306a210203400240200241746a2802002208450d00200841306c450d00200241706a28020010350b0240200228020041ffffff3f71450d002002417c6a28020010350b200241d8006a2102200141a87f6a22010d000b0b41e9a5c0002108411121014180901821022007a72209450d01200941d8006c450d01201110350c010b2002200d104e000b0240201341ffffffff0371450d00201210350b20004200370308200041206a20013602002000411c6a2008360200200041186a2002200a723602000c160b024020022d000120022d0000410047720d0041f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c2108200210354193eecb00ad42808080808001841001220229000021042002290008210520021035200320053701c808200320043701c008200320083601bc08200320073701b408200320013601b008200341033a00f00b410110332202450d12200220032d00f00b3a0000200341b0086aad42808080808004842002ad428080808010841002200210350c140b20004200370308200041186a41023602000c150b200341980a6a200141196a290000370300200341800a6a41106a200141116a290000370300200341880a6a200141096a290000370300200320012900013703800a4100210102400240024020022d000120022d0000410047720d00200341f0066a200341800a6a10910220032d00f00622024104460d0220032902f406210720032f00f10620032d00f3064110747241087421010c010b410221020b200042003703082000411c6a2007370200200041186a20012002723602000c150b200342f3e885db96cddbb3203703d009200341d0096a200341800a6a1092020c120b200141086a2802002108200141046a2802002109024020022d000120022d0000410047720d002001410c6a280200210141f7edcb00ad4280808080f0008410012202280000210a20022900042107200228000c210b200210354194c4c100ad4280808080d001841001220229000021042002290008210520021035200320053701c808200320043701c0082003200b3601bc08200320073701b4082003200a3601b008200341203602840a2003200341b0086a3602800a20092001200341800a6a109802200841ffffff3f71450d12200910350c120b0240200841ffffff3f71450d00200910350b20004200370308200041186a41023602000c130b024020022d000120022d0000410047720d0041f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c2108200210354193eecb00ad42808080808001841001220229000021042002290008210520021035200320053701c808200320043701c008200320083601bc08200320073701b408200320013601b008200341013a00f00b410110332202450d0f200220032d00f00b3a0000200341b0086aad42808080808004842002ad428080808010841002200210350c110b20004200370308200041186a41023602000c120b024020022d000120022d0000410047720d0041f7edcb00ad4280808080f0008410012202280000210120022900042107200228000c2108200210354193eecb00ad42808080808001841001220229000021042002290008210520021035200320053701c808200320043701c008200320083601bc08200320073701b408200320013601b008200341023a00f00b410110332202450d0e200220032d00f00b3a0000200341b0086aad42808080808004842002ad428080808010841002200210350c100b20004200370308200041186a41023602000c110b024020022d000120022d000041004772450d0020004200370308200041186a41023602000c110b200141046a280200210141f7edcb00ad4280808080f0008410012202280000210820022900042107200228000c21092002103541c1edcb00ad4280808080e001841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320083601b008200320013602800a200341b0086aad4280808080800484200341800a6aad4280808080c0008410020c0e0b200341a8096a200141246a28020036020020034188096a41186a2001411c6a29020037030020034188096a41106a200141146a29020037030020034188096a41086a2001410c6a2902003703002003200141046a290200370388092002411a6a2901002107200241196a2d00002109200241186a2d0000210a200241166a2f0100210b200241156a2d0000210c200241146a2d0000210d200241126a2f0100210e200241116a2d0000210f200241106a2d000021102002410e6a2f010021112002410d6a2d000021122002410c6a2d000021132002410a6a2f01002114200241096a2d00002115200241086a2d00002116200241066a2f01002117200241056a2d00002118200241046a2d0000211941022101200241026a2f0100210641012108024020022d00000d0020022d000141014721080b200320073701c808200320093a00c7082003200a3a00c6082003200b3b01c4082003200c3a00c3082003200d3a00c2082003200e3b01c0082003200f3a00bf08200320103a00be08200320113b01bc08200320123a00bb08200320133a00ba08200320143b01b808200320153a00b708200320163a00b608200320173b01b408200320183a00b308200320193a00b208200320063b01b0080240024002402008450d0041801021080c010b200341d00b6a41186a200341b0086a41186a290100370300200341d00b6a41106a200341b0086a41106a290100370300200341d00b6a41086a200341b0086a41086a290100370300200320032901b0083703d00b200341f0066a200341d00b6a10b401200341800a6a20032802f006220120032802f80610d50120032802f4062102024020032d00800a4101470d00200341990a6a2900002107200341800a6a41186a2d00002108200341970a6a2d00002109200341950a6a2f0000210a200341940a6a2d0000210b200341930a6a2d0000210c200341910a6a2f0000210d200341800a6a41106a2d0000210e2003418f0a6a2d0000210f2003418d0a6a2f000021102003418c0a6a2d000021112003418b0a6a2d00002112200341890a6a2f00002113200341800a6a41086a2d0000211420032d00870a211520032f00850a211620032d00840a211720032d00830a211820032d00820a211920032d00810a210602402002450d00200110350b200320073703880c200320083a00870c200320093a00860c2003200a3b01840c2003200b3a00830c2003200c3a00820c2003200d3b01800c2003200e3a00ff0b2003200f3a00fe0b200320103b01fc0b200320113a00fb0b200320123a00fa0b200320133b01f80b200320143a00f70b200320153a00f60b200320163b01f40b200320173a00f30b200320183a00f20b200320193a00f10b200320063a00f00b200341800a6a41206a20034188096a41206a280200360200200341800a6a41186a20034188096a41186a290300370300200341800a6a41106a20034188096a41106a290300370300200341800a6a41086a20034188096a41086a29030037030020032003290388093703800a200341f0066a200341800a6a108b0241012101410d2102024020032d00f0064101460d00200341f0066a41086a2d00002101200341f9066a2f00002108200341fb066a2d00002109200341fc066a2d0000210a200341f0066a410d6a2f0000210b200341ff066a2d0000210c200341f0066a41106a2d0000210d20034181076a2f0000210e20034183076a2d0000210f20034184076a2d0000211020034185076a2f0000211120034187076a2d00002112200341f0066a41186a2d0000211320032d00f106211420032d00f206211520032d00f306211620032d00f406211720032f00f506211820032d00f7062119200320034189076a2900003703f808200320133a00f708200320123a00f608200320113b01f408200320103a00f3082003200f3a00f2082003200e3b01f0082003200d3a00ef082003200c3a00ee082003200b3b01ec082003200a3a00eb08200320093a00ea08200320083b01e808200320013a00e708200320193a00e608200320183b01e408200320173a00e308200320163a00e208200320153a00e108200320143a00e008200341800a6a200341e0086a10b701200341f0006a20032802800a220120032802880a41b0b4cc0041004100108a0220032802702108024020032802840a450d00200110350b4103210120084101470d030b4194a6c00021094180900c21080c010b02402002450d00200110350b41aea6c000210941082102410321014180900421080b200041206a20023602002000411c6a2009360200200041186a2008200172360200200042003703080c100b200341e0086a200341f00b6a412010a008450d0d200341800a6a200341d00b6a10b40120033502880a210720032802800a2101412010332202450d00200220032903e008370000200241186a200341e0086a41186a290300370000200241106a200341e0086a41106a290300370000200241086a200341e0086a41086a29030037000020074220862001ad842002ad4280808080800484100220021035024020032802840a450d00200110350b200341b0096a200341f00b6a10b701200341800a6a20032802b009220120032802b809220810d601024020032802a00a2202450d002008ad4220862001ad8410070b200341f0066a41086a2208200341bc0a6a290200370300200341f0066a41106a2209200341c40a6a290200370300200341f0066a41186a220a200341cc0a6a290200370300200341f0066a41206a220b200341d40a6a2802003602002003200341b40a6a2902003703f006200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a280200210c200341ac0a6a280200210d200341a80a6a280200210e20032903900a210520032903800a211a20032802a40a210f200341b0086a41206a2210200b280200360200200341b0086a41186a220b200a290300370300200341b0086a41106a220a2009290300370300200341b0086a41086a22092008290300370300200320032903f0063703b00802402002450d00200341d0096a41206a2010280200360200200341d0096a41186a200b290300370300200341d0096a41106a200a290300370300200341d0096a41086a2009290300370300200320032903b0083703d009024020032802b409450d00200110350b200341800a6a41186a2007370300200341b00a6a200c360200200341a80a6a200e360200200341a40a6a200f360200200341b40a6a20032903d009370200200341bc0a6a200341d0096a41086a290300370200200341c40a6a200341d0096a41106a290300370200200341cc0a6a200341d0096a41186a290300370200200341d40a6a200341d0096a41206a280200360200200320053703900a200320043703880a2003201a3703800a2003200d3602ac0a200320023602a00a200341b0086a200341e0086a10b70120033502b808210720032802b008210b200341003602f806200342013703f006412010332202450d0c200220032903b80a370000200241086a200341c00a6a290300370000200241106a200341c80a6a290300370000200241186a200341d00a6a290300370000200320023602f006200342a080808080043702f4062003200341800a6a3602b009200341b0096a200341f0066a10cf012003200341800a6a41106a3602b009200341b0096a200341f0066a10cf0120032802a00a210220032802a80a2201200341f0066a107702402001450d002002200141186c6a21010340200320023602b009200341b0096a200341f0066a10cf01200241106a200341f0066a10e2012001200241186a2202470d000b0b20032802ac0a210c20032802b40a2202200341f0066a10770240024020032802f406220a20032802f80622016b20024102742208490d0020032802f0062102200a21090c010b200120086a22022001490d0c200a41017422092002200920024b1b22094100480d0c02400240200a0d00024020090d00410121020c020b200910332202450d0f0c010b20032802f0062102200a2009460d002002200a200910372202450d0e0b200320093602f406200320023602f0060b200220016a200c2008109d081a2007422086200bad84200120086aad4220862002ad84100202402009450d00200210350b024020032802b408450d00200b10350b024020032802a40a2202450d00200241186c450d0020032802a00a10350b20032802b00a41ffffffff0371450d0e20032802ac0a10350c0e0b20032802b409450d0d200110350c0d0b1045000b4182102108024020022d00000d0020022d00014101470d0020012d00012119200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100210120032002411a6a2901003703e809200320083a00e709200320093a00e6092003200a3b01e4092003200b3a00e3092003200c3a00e2092003200d3b01e0092003200e3a00df092003200f3a00de09200320103b01dc09200320113a00db09200320123a00da09200320133b01d809200320143a00d709200320153a00d609200320163b01d409200320173a00d309200320183a00d209200320013a00d009200320014108763a00d109200341f00b6a200341d0096a10b701200341800a6a20032802f00b220120032802f80b10d601200341b0086a41086a220b200341bc0a6a290200370300200341b0086a41106a220c200341c40a6a290200370300200341b0086a41186a220d200341cc0a6a290200370300200341b0086a41206a220e200341d40a6a2802003602002003200341b40a6a2902003703b008024020032802a00a2208450d00200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a2802002109200341ac0a6a280200210a200341a80a6a280200210f20032903900a210520032903800a211a20032802a40a210220034188096a41206a200e28020036020020034188096a41186a200d29030037030020034188096a41106a200c29030037030020034188096a41086a200b290300370300200320032903b00837038809024020032802f40b450d00200110350b200341e0086a41086a220120034188096a41086a290300370300200341e0086a41106a220b20034188096a41106a290300370300200341e0086a41186a220c20034188096a41186a290300370300200341e0086a41206a220d20034188096a41206a280200360200200341f0066a41186a2007370300200341a0076a200936020020034198076a200f36020020034194076a200236020020032003290388093703e00820032005370380072003201a3703f0062003200a36029c072003200836029007200320043703f806200341c4076a200d280200360200200341bc076a200c290300370200200341b4076a200b290300370200200341ac076a2001290300370200200341a4076a20032903e008370200200341800a6a200341a8076a108c0220033502880a210720032802800a210b02400240201941037122014103470d0041012101420021044101210c0c010b024002400240024020010e03000102000b4100210c0c020b4101210c0c010b4102210c0b2003200c3a00f00b410110332201450d0c2001200c3a00004100210c42808080801021040b2007422086200bad8420042001ad8410020240200c0d00200110350b024020032802840a450d00200b10350b02402002450d00200241186c450d00200810350b200941ffffffff0371450d0d200a10350c0d0b024020032802f40b450d00200110350b41831021080b20004200370308200041206a410d3602002000411c6a41b6a6c000360200200041186a20083602000c0d0b2002411a6a290100211a200241196a2d0000210c200241186a2d0000210d200241166a2f0100210e200241156a2d0000210f200241146a2d00002110200241126a2f01002111200241116a2d00002112200241106a2d00002113410e21012002410e6a2f010021142002410d6a2d000021152002410c6a2d000021162002410a6a2f01002117200241096a2d00002118200241086a2d00002119200241066a2f01002106200241056a2d0000211d200241046a2d0000211e200241026a2f0100211f20022d0001210b20022d0000210a41f7edcb00ad4280808080f0008410012202280000210820022900042107200228000c21092002103541b6aac000ad42808080809002841001220229000021042002290008210520021035200320053701c808200320043701c008200320093601bc08200320073701b408200320083601b008200341e8006a200341b0086a10f20141032102024002402003280268417d71450d0041dca2c0002108418090ec0021090c010b0240200a41ff01710d00200b41ff01714101470d002003201a3703e8092003200c3a00e7092003200d3a00e6092003200e3b01e4092003200f3a00e309200320103a00e209200320113b01e009200320123a00df09200320133a00de09200320143b01dc09200320153a00db09200320163a00da09200320173b01d809200320183a00d709200320193a00d609200320063b01d4092003201d3a00d3092003201e3a00d2092003201f3b01d009200341f00b6a200341d0096a10b701200341800a6a20032802f00b220a20032802f80b10d601200341b0086a41086a220b200341bc0a6a290200370300200341b0086a41106a220c200341c40a6a290200370300200341b0086a41186a220d200341cc0a6a290200370300200341b0086a41206a220e200341d40a6a2802003602002003200341b40a6a2902003703b008024020032802a00a2201450d00200341800a6a41186a2903002107200341800a6a41086a2903002104200341b00a6a2802002108200341ac0a6a2802002109200341a80a6a280200210f20032903900a210520032903800a211a20032802a40a210220034188096a41206a200e28020036020020034188096a41186a200d29030037030020034188096a41106a200c29030037030020034188096a41086a200b290300370300200320032903b00837038809024020032802f40b450d00200a10350b200341e0086a41086a220a20034188096a41086a290300370300200341e0086a41106a220b20034188096a41106a290300370300200341e0086a41186a220c20034188096a41186a290300370300200341e0086a41206a220d20034188096a41206a280200360200200341f0066a41186a2007370300200341a0076a200836020020034198076a200f36020020034194076a200236020020032003290388093703e00820032005370380072003201a3703f0062003200936029c072003200136029007200320043703f806200341c4076a200d280200360200200341bc076a200c290300370200200341b4076a200b290300370200200341ac076a200a290300370200200341a4076a20032903e008370200200341800a6a200341a8076a220a10b50120033502880a42208620032802800a220bad841007024020032802840a450d00200b10350b200341800a6a200a10b90120033502880a42208620032802800a220aad841007024020032802840a450d00200a10350b02402002450d00200241186c450d00200110350b200841ffffffff0371450d0d200910350c0d0b024020032802f40b450d00200a10350b41b6a6c0002108410d210141801021090c010b4102210241801021090b20004200370308200041206a20013602002000411c6a2008360200200041186a20092002723602000c0c0b410221020c010b02402001450d00200141186c450d00200910350b0240200a41ffffffff0371450d00201210350b4188a6c0002109410c21014104210a0b2008450d02200841246c450d02200b10350c020b02402008450d00200841246c450d00200b10350b20032802c40b41ffffff3f71210e0b02400240200c450d00200e450d01200f10350c010b200f0d020b02402001450d00200141186c450d00200910350b0240200a41ffffffff0371450d00201210350b410121020b20004200370308200041206a20013602002000411c6a2009360200200041186a200a41ff0171411074200272418010723602000c060b41f7edcb00ad4280808080f0008410012201280000210820012900042107200128000c21092001103541e4edcb00ad4280808080a001841001220129000021042001290008210520011035200320053701c808200320043701c008200320093601bc08200320073701b408200320083601b008200341d8006a200341b0086a412010c001200328025c211120032802582112200341800a6a200341a8076a220110b50120033502880a42208620032802800a2208ad841007024020032802840a450d00200810350b200341d0096a200110b90120033502d809210720032802d0092110200341003602880a200342013703800a2002200341800a6a10770240024020020d0020032802840a210920032802880a21010c010b2002410574210b410020032802880a22016b210a20032802800a210d20032802840a2109200f210c0340200c210202402009200a6a411f4b0d00200141206a22082001490d032009410174220c2008200c20084b1b22084100480d03024002400240024020090d00024020080d004101210d0c020b20081033210d0c030b20092008470d010b200821090c020b200d200920081037210d0b20082109200d450d040b200241206a210c200d20016a22082002290000370000200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200a41606a210a200141206a2101200b41606a220b0d000b200320093602840a200320013602880a2003200d3602800a0b02400240200920016b4104490d0020032802800a2108200921020c010b200141046a22022001490d01200941017422082002200820024b1b22024100480d010240024020090d00024020020d00410121080c020b200210332208450d040c010b20032802800a210820092002460d0020082009200210372208450d030b200320023602840a200320083602800a0b200820016a2011410020121b3600002003200141046a22013602880a41002109200341003a00f00b0240024020022001460d00200121020c010b200241016a22012002490d01200241017422092001200920014b1b22014100480d010240024020020d0041002102024020010d00410121080c020b200110332208450d040c010b20022001460d0020082002200110372208450d030b200320013602840a200320083602800a20032d00f00b21090b200820026a20093a000020032802840a210120074220862010ad84200241016aad42208620032802800a2202ad84100202402001450d00200210350b024020032802d409450d00201010350b0240200e450d00200f10350b02402003280294072202450d00200241186c450d0020032802900710350b20032802a00741ffffffff0371450d03200328029c0710350c030b103e000b103c000b20004200370308200041206a20013602002000411c6a2008360200200041186a2009418080fc0071200272418010723602000c020b42002107200042003703080c020b200041206a20083602002000411c6a200136020020004200370308200041186a20094180801c71200272418010723602000b420121070b20002007370300200341900c6a24000b9d0102017f017e230041106b2206240002402002ad4220862001ad842004ad4220862003ad842005102b2207422088a72204450d002007a722052d0000220341014b0d00410021010240024020030e020100010b2004417f6a4104490d0120052800012102410121010b200510352000200236020420002001360200200641106a24000f0b41b89acc00412e200641086a41c09bcc0041e89acc001046000b850501067f230041c0016b22022400200241ce006a2203200141036a2d00003a0000200241306a41086a2204200141106a290200370300200241306a41106a2205200141186a290200370300200241306a41186a2206200141206a280200360200200220012f00013b014c2002200141086a290200370330200141046a280200210702400240024020012d00004101470d0020024188016a2007109604200241d0006a200228028801220120022802900110cb0220024198016a41086a200241e7006a29000037030020024198016a41106a200241ef006a29000037030020024198016a41186a200241f7006a2d00003a0000200220022f01583b01b8012002200241da006a2d00003a00ba012002200229005f37039801024020022903504201520d00200241db006a2800002107200241086a41086a20024198016a41086a290300370300200241086a41106a20024198016a41106a290300370300200241086a41186a20024198016a41186a2d00003a0000200220022d00ba013a002a200220022f01b8013b01282002200229039801370308200228028c01450d02200110350c020b0240200228028c01450d00200110350b410121010c020b200241086a41086a2004290300370300200241086a41106a2005290300370300200241086a41186a20062d00003a0000200220022f014c3b012820022002290330370308200220032d00003a002a0b200041036a20022d002a3a0000200020022f01283b0001200041046a2007360000200041086a2002290308370000200041106a200241086a41086a290300370000200041186a200241086a41106a290300370000200041206a200241086a41186a2d00003a0000410021010b200020013a0000200241c0016a24000bb10503027f017e047f230041d0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a29000037030020022004370308200310354188c5c100ad4280808080d00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bce0203027f017e037f23004180026b22012400200141086a2000108e02200141e0006a2001280208220020012802102202108f0220012903602103200141b8016a200141e8006a41c400109d081a200141b4016a41026a2204200141af016a2d00003a0000200120012f00ad013b01b4010240024020034201510d0041002105200141186a410041c400109f081a0c010b20012d00ac012105200141186a200141b8016a41c400109d081a200141146a41026a20042d00003a0000200120012f01b4013b01140b200141e8006a200141186a41c400109d082104200141af016a200141166a2d00003a0000200142013703602001417f2005411874220541808080086a220620062005491b4118763a00ac01200120012f01143b00ad01200120023602bc01200120003602b8012004200141b8016a10e7020240200128020c450d00200010350b20014180026a24000bc20503027f017e047f230041d0006b2202240041d1c4c700ad4280808080e00084100122032900002104200241086a200341086a290000370300200220043703002003103541d7c4c700ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000baa0406027f017e017f037e017f037e230041d0006b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822010d00200042003703000c010b200328020c2102024002400240200341106a28020022044104490d0020044104460d002004417b6a4110490d002004416b6a4110490d002004415b6a4110490d002004414b6a410f4b0d010b20034100360220200342013703182003410936022c200320033602282003200341186a360234200341cc006a41013602002003420137023c200341c888c2003602382003200341286a360248200341346a41e88ac500200341386a10431a200335022042208620033502188410060240200328021c450d00200328021810350b420021050c010b2001280000210420012d000421062001410d6a2900002105200129000521072001411d6a290000210820012900152109200341286a41026a220a200341386a41026a2d00003a0000200320032f00383b01282001412d6a290000210b2001290025210c2001290035210d200041c0006a2001413d6a290000370300200041386a200d370300200041306a200b370300200041286a200c370300200041206a2008370300200041186a2009370300200041106a200537030020002007370308200020063a004c200041c8006a2004360200200020032f01283b004d200041cf006a200a2d00003a0000420121050b200020053703002002450d00200110350b200341d0006a24000be80e03037f017e0d7f230022052106200541e0016b41607122052400024002402002200384500d00200441ff01712207450d002000290000210841002109024020074101460d004102410120044101711b21090b20052002370300200520093a00182005200837031020052003370308200541c0016a200110eb0220052802c001210a20052802c401210b02400240024020052802c801220c450d00200a200c41057422046a210d200441606a210e200541a0016a411072210f200541a0016a4119722110200a21040340200541e8006a41106a2211200441106a290300370300200541e8006a41086a2212200441086a29030037030020052004290300370368200441186a2d000021072005200441196a28000036023820052004411c6a28000036003b20074103460d0120102005280238360000201041036a200528003b360000200520112903003703b001200520122903003703a801200520052903683703a001200520073a00b80102400240200f2000460d00200f2900002000290000510d00200520052903b801220237039801200520052903b00137039001200520052903a80137038801200520052903a001370380010c010b200541033a00d80120052005290318220237039801200520052903103703900120052005290308370388012005200529030037038001200520052903d001370310200520052903c801370308200520052903c001370300200520052903d80122033703182003a721090b2002a7220741ff01714103470d02200e41606a210e200441206a2204200d470d000b0b200541003602a801200542083703a001200b41ffffff3f71450d01200a10350c010b200541d0006a41106a2210200529039001370300200541d0006a41086a22112005290388013703002005200528009c0136004320052005280099013602402005200529038001370350200520052802403602482005200528004336004b41201033220f450d02200f2005290350370300200f20073a0018200f2005280248360019200f411c6a200528004b360000200f41106a2010290300370300200f41086a2011290300370300200542818080801037022c2005200f3602280240200e450d00200441206a210e200c410574200a6a41606a211320054180016a4119722114200541a0016a4110722112200541a0016a41197221104101210c0340200e21040340200541e8006a41106a220e200441106a290300370300200541e8006a41086a2211200441086a29030037030020052004290300370368200441186a2d000021072005200441196a28000036023820052004411c6a28000036003b20074103460d0220102005280238360000201041036a200528003b3600002005200e2903003703b001200520112903003703a801200520052903683703a001200520073a00b8010240024020122000460d0020122900002000290000510d00200520052903b801220237039801200520052903b00137039001200520052903a80137038801200520052903a001370380010c010b200541033a00d80120052005290318220237039801200520052903103703900120052005290308370388012005200529030037038001200520052903d001370310200520052903c801370308200520052903c001370300200520052903d80122033703182003a721090b02402002a7220741ff01714103470d00200441206a2204200d470d010c030b0b200541d0006a41106a220e200529039001370300200541d0006a41086a2211200529038801370300200520142800003602402005201441036a2800003600432005200529038001370350200520052802403602482005200528004336004b200541c0016a41086a22152011290300370300200541c0016a41106a2211200e290300370300200520052903503703c001200520052802483602a0012005200528004b3600a3010240200c200528022c470d00200541286a200c410110a1012005280228210f0b200441206a210e201529030021022011290300210320052903c0012108200f200c4105746a221120073a001820112008370300201120052802a0013600192011411c6a20052800a301360000201141106a2003370300201141086a20023703002005200c41016a220c36023020132004470d000b0b0240200b41ffffff3f71450d00200a10350b200541a0016a41086a200541286a41086a280200360200200520052903283703a0010b02400240200941ff01714103470d0020052802a801210420052802a0012107200541a0016a21050c010b200541c0016a41186a22102005290318370300200541c0016a41106a220e2005290310370300200541c0016a41086a22112005290308370300200520052903003703c001024020052802a801220420052802a401470d00200541a0016a2004410110a10120052802a80121040b20052802a001220720044105746a220020052903c001370300200041086a2011290300370300200041106a200e290300370300200041186a20102903003703002005200441016a22043602a801200541a0016a21050b20012007200410ec02200541046a28020041ffffff3f71450d00200528020010350b200624000f0b1045000bf90703057f027e037f230041a0016b22022400200241e8006a200110b401200241f8006a200228026822032002280270220410d501024020022d00782205450d002004ad4220862003ad8410070b200241086a41176a220420024191016a290000370000200241086a41106a22062002418a016a290100370300200241086a41086a20024182016a29010022073703002002200229017a220837030820022d00792109200241f8006a41176a220a2004290000370000200241f8006a41106a22042006290300370300200241f8006a41086a22062007370300200220083703780240024020054101470d00200241c8006a41176a200a290000370000200241c8006a41106a2004290300370300200241c8006a41086a2006290300370300200220022903783703480240200228026c450d00200310350b200241286a41176a2203200241c8006a41176a290000370000200241286a41106a2205200241c8006a41106a290300370300200241116a200241d0006a290300370000200241196a2005290300370000200241206a2003290000370000200220093a000820022002290348370009200241f8006a200241086a10b70120023502800142208620022802782203ad8410070240200228027c450d00200310350b200241f8006a2001108c0220023502800142208620022802782203ad8410070240200228027c450d00200310350b200241f8006a200110b50120023502800142208620022802782203ad8410070240200228027c450d00200310350b200241f8006a200110b90120023502800142208620022802782203ad8410070240200228027c450d00200310350b200241c8006a200110ba01200241f8006a200228024822032002280250220510bc010240200228028401220b450d002005ad4220862003ad8410070b2002290388012107200228027821090240200228024c450d00200310350b0240200b450d00200b2007422088a74102746a210a41002103200b21052009210602400340024002402003417e714102460d0041022103200921040c010b2005450d02200a2005460d02200541046a2105410321032006417f6a220621040b200241f8006a41186a200141186a290000370300200241f8006a41106a200141106a290000370300200241f8006a41086a200141086a290000370300200220043602980120022001290000370378200241c8006a200241f8006a10b601200235025042208620022802482204ad841007200228024c450d00200410350c000b0b200742ffffffff0383500d00200b10350b2001109902200041043a00000c010b0240200228026c450d00200310350b200041086a4108360200200041046a41aea6c000360200200041026a41013a000020004183103b01000b200241a0016a24000bac0304107f027e017f017e230041306b220224002002200110eb022002280200210302400240200228020822040d00410021040c010b200041706a210541002106200321074100210802400240034002400240024020052007460d00200741106a22092900002000290000510d0020060d01410021060c020b200641016a21060c010b200820066b220a20044f0d02200241106a41186a220b200720064105746b220a41186a220c290300370300200241106a41106a220d200a41106a220e290300370300200241106a41086a220f200a41086a22102903003703002002200a290300370310200741086a2211290300211220092903002113200741186a22142903002115200a2007290300370300200c2015370300200e2013370300201020123703002014200b2903003703002009200d2903003703002011200f290300370300200720022903103703000b200741206a21072004200841016a2208460d020c000b0b200a200441f485cc001042000b2006417f6a20044f0d002002200420066b22043602080b20012003200410ec020240200228020441ffffff3f71450d00200310350b200241306a24000bcb3e0a027f017e017f027e017f017e117f017e077f077e230041a0036b22052400200541e0006a41286a200341286a290300370300200541e0006a41206a200341206a290300370300200541e0006a41186a200341186a290300370300200541e0006a41106a200341106a290300370300200541e0006a41086a200341086a290300370300200520032903003703600240024002400240024002400240024002400240024002400240024002400240024002400240200541e0006a200410f101220441ff0171411d470d0020054180036a41086a22044200370300200542003703800341f7edcb00ad4280808080f0008410012206290000210720054190036a41086a2208200641086a290000370300200520073703900320061035200420082903003703002005200529039003370380034192aac000ad4280808080a002841001220629000021072006290008210920061035200541e0026a41086a2004290300370300200520093703f802200520073703f00220052005290380033703e002200541e0006a200541e0026aad4280808080800484220a100510c2010240024020052802602204450d00200528026421062005200541e8006a2802003602a402200520043602a002200541386a200541a0026a10c401024002402005280238450d004101210b41b0b4cc0021080c010b200528023c21084100210b0b02402006450d00200410350b41122104200b450d010c020b410021080b20054180036a41086a22064200370300200542003703800341f7edcb00ad4280808080f00084220c10012204290000210720054190036a41086a220b200441086a2900003703002005200737039003200410352006200b29030037030020052005290390033703800341c1edcb00ad4280808080e001841001220429000021072004290008210920041035200541e0026a41086a220d2006290300370300200520093703f802200520073703f00220052005290380033703e002200541306a200541e0026a412010c00141132104200041086a28020020082005280234410020052802301b220e200e20084b1b2208470d00200642003703002005420037038003200c100122042900002107200b200441086a2900003703002005200737039003200410352006200b2903003703002005200529039003370380034192aac000ad4280808080a002841001220429000021072004290008210920041035200d2006290300370300200520093703f802200520073703f00220052005290380033703e002200541e0006a200541e0026a10fe01024020052802602206450d00200520052902642207370244200520063602402000280200210f20002802042110024020080d00411d21040c050b411421042007422088a7200f2f010022004d0d04200541e8006a220b200620004105746a220441096a290000370300200541f0006a2200200441116a290000370300200541f7006a2206200441186a2900003700002005200429000137036020042d0000210441201033220e450d06200e20043a0000200e2005290360370001200e41096a200b290300370000200e41116a2000290300370000200e41186a200629000037000020054281808080103702e4022005200e3602e0024101210b411d210420084101460d032005280248200f2f010222004d0d02200541a0026a41086a2211200528024020004105746a220041096a290000370300200541a0026a41106a2212200041116a290000370300200541a0026a41176a2213200041186a290000370000200520002900013703a002200f41046a210d2008410174417c6a210820002d00002114412121064102210b410121000340200541e0006a41176a22152013290000370000200541e0006a41106a22162012290300370300200541e0006a41086a22172011290300370300200520052903a0023703600240200b417f6a2000470d00200541e0026a20004101108a0120052802e002210e0b200e20066a2200417f6a20143a000020002005290360370000200041086a2017290300370000200041106a2016290300370000200041176a20152900003700002005200b3602e8022008450d042005280248200d2f010022004d0d032011200528024020004105746a220041096a2900003703002012200041116a2900003703002013200041186a290000370000200520002900013703a0022008417e6a2108200d41026a210d200641206a2106200b41016a210b20002d0000211420052802e40221000c000b0b411221040b200110fa01200041046a28020041808080807872418080808078460d11200028020010350c110b411421040b0240201041808080807872418080808078460d00200f10350b20052802e40241ffffff3f7121110c010b410021114101210e0240201041808080807872418080808078460d00200f10350b4100210b0b02402004411d460d00410121032011450d0d0c0c0b20054180036a41086a22044200370300200542003703800341f7edcb00ad4280808080f0008410012200290000210720054190036a41086a2206200041086a2900003703002005200737039003200010352004200629030037030020052005290390033703800341a4aac000ad4280808080a002841001220029000021072000290008210920001035200541e0026a41086a2004290300370300200520093703f802200520073703f00220052005290380033703e002200541e0006a200541e0026a10fe0120052802602214450d0820052005290264220737025420052014360250200541e0006a200141c001109d081a200541a0026a200541e0006a200541d0006a200541c0006a109b022007a7211720052d00a0024101460d0620052802a4022218200541a0026a410c6a2802002219412c6c221a6a211b200541a0026a41086a221c280200211d0240201a450d00200541e0026a41086a210f41f7edcb00ad4280808080f00084210741f393ca00ad4280808080a00184211e201821120340200710012204290000210920054190036a41086a2213200441086a290000370300200520093703900320041035201e1001220429000821092004280004211f2004280000212020041035412010332204450d0220042012410c6a2200290000370000200441186a200041186a2221290000370000200441106a200041106a2222290000370000200441086a200041086a222329000037000020052004ad4280808080800484100322062900003703e002200610352005200441206a36026c200520043602682005200f3602642005200541e0026a360260200541a0026a200541e0006a107b2004103520052802a802221541206a2206417f4c0d0c20052802a00221160240024020060d0041002108410121040c010b200610332204450d03200621080b024002402008410f4d0d002008210d0c010b2008410174220d4110200d41104b1b220d4100480d04024020080d00200d103322040d010c090b2008200d460d0020042008200d10372204450d080b2004200529039003370000200441086a201329030037000002400240200d4170714110460d00200d21080c010b200d41017422084120200841204b1b22084100480d04200d2008460d002004200d200810372204450d080b200420093700182004201f3600142004202036001002400240200841606a2015490d002008210d0c010b2015415f4b0d042008410174220d2006200d20064b1b220d4100480d042008200d460d0020042008200d10372204450d080b200441206a20162015109d081a024020052802a402450d00201610350b200541286a2004200641b0b4cc0041004100108a022005280228211f0240200d450d00200410350b20071001220429000021092013200441086a29000037030020052009370390032004103541cca9c000ad4280808080a00184100122042900082109200428000421202004280000212420041035412010332204450d0220042000290000370000200441186a2021290000370000200441106a2022290000370000200441086a202329000037000020052004ad4280808080800484100322062900003703e002200610352005200441206a36026c200520043602682005200f3602642005200541e0026a360260200541a0026a200541e0006a107b2004103520052802a802221541206a2206417f4c0d0c20052802a00221160240024020060d0041002108410121040c010b200610332204450d03200621080b024002402008410f4d0d002008210d0c010b2008410174220d4110200d41104b1b220d4100480d04024020080d00200d10332204450d090c010b2008200d460d0020042008200d10372204450d080b2004200529039003370000200441086a201329030037000002400240200d4170714110460d00200d21080c010b200d41017422084120200841204b1b22084100480d04200d2008460d002004200d200810372204450d080b20042009370018200420203600142004202436001002400240200841606a2015490d002008210d0c010b2015415f4b0d042008410174220d2006200d20064b1b220d4100480d042008200d460d0020042008200d10372204450d080b200441206a20162015109d081a024020052802a402450d00201610350b200541e0006a20042006109c02024020052d0070220641024622130d0020052802602110200528026421252005290368210c0b0240200d450d00200410350b02400240024002400240201f410146220420064102472208460d002004450d010240201241086a2802004101470d000240201228020022042000460d0020042000412010a0080d010b20042f012041ffff03460d030b4119210420064102460d0b202541ffffff3f710d0a0c0b0b4116210420064102460d0a202541ffffff3f71450d0a0c090b02402008450d00024020122802082204450d002012280200220d200441226c6a2115200c422088a72116200ca7410574211303402005200d22063602a002200641226a210d20132100201021040340024020000d00411721040c0c0b024020062004460d0020042006412010a0082108200041606a2100200441206a210420080d010b0b200541e0006a200541a0026a10bb010240200528026c2204450d00200528026821000240200528027041ffffffff0371450d00200410350b200020164d0d00411821040c0b0b200d2015470d000b0b202541ffffff3f71450d030c020b4185f3c10041fd004184f4c1001064000b20130d01202541ffffff3f71450d010b201010350b2012412c6a2212201b470d000b0b200541003602e802200542043703e002200541e0026a4100201a412c6d10980120052802e002210020052802e80221042005201b36026c200520183602682005201d36026420052018360260200520054190036a360270201c20043602002005200541e0026a41086a3602a402200520002004412c6c6a3602a002200541e0006a200541a0026a109d0220052802e4022110200541e0006a200e200b20052802e002222020052802e802221f10cc012005280268210f2005280264211220052802602116411a21040240200528026c0d000240024002402016450d0002402012450d002012210420162100034020002802c80521002004417f6a22040d000b20162104201221060340200420042f01064102746a41c8056a28020021042006417f6a22060d000b200541e0006a21060c020b200541e0006a210620162100201621040c010b4100210020054100360264200541e0006a21060c010b20052004360264200541ec006a20042f010636020020054100360268200541003602600b200541e0026a41086a200641086a29020022073703002005200629020022093703e002200541e0006a41186a200737030042002126200542003703682005200036026420054100360260200520093703702005200f3602800102400240200f0d00427f21274200210c4200212842002129427f211e0c010b2005200f417f6a36028001200541e0006a410020001b220d2802002106200d28020821130240024002400240200d28020c2208200d28020422042f01064f0d00200421000c010b034020042802002200450d02200641016a210620042f0104210820002104200820002f01064f0d000b0b2008ad4220862013ad8421070c010b2013ad2107410021000b2007422088a7221341016a21082007a721150240024020060d00200021040c010b200020084102746a41c8056a2802002104410021082006417f6a2206450d00034020042802c80521042006417f6a22060d000b0b200d200836020c200d2015360208200d2004360204200d4100360200200020134105746a41e8026a2104427f2127427f211e4200212842002129420021264200210c0340200541086a200441086a29030022094200200429030022074200108408200541186a2007420020074200108408427f200c427f200541186a41086a290300222a2005290308222b202b7c7c222b20092005290310222c84202c84420052202b202a547222041b7c2026427f200529031820041b7c222a2026542204ad7c222620042026200c542026200c511b22041b210c427f202a20041b21262009201e20072027542009201e542009201e511b22041b211e2007202720041b2127200920297c200720287c2228200754ad7c21292005280280012204450d0120052004417f6a36028001200541e0006a410020052802641b220d2802002106200d2802082113024002400240200d28020c2208200d28020422042f01064f0d00200421000c010b0240034020042802002200450d01200641016a210620042f0104210820002104200820002f0106490d020c000b0b2013ad2107410021000c010b2008ad4220862013ad8421070b2007422088a7221341016a21082007a721150240024020060d00200021040c010b200020084102746a41c8056a2802002104410021082006417f6a2206450d00034020042802c80521042006417f6a22060d000b0b200d200836020c200d2015360208200d2004360204200d4100360200200020134105746a41e8026a21040c000b0b200541c8026a200c370300200541a0026a41186a2029370300200520263703c002200520283703b002200520273703a0022005201e3703a80202400240200541a0026a2003460d00200541a0026a2003413010a0080d010b0240024020160d0041002116410021034100210f0c010b0240024020120d00201621030c010b2012210320162104034020042802c80521042003417f6a22030d000b201621030340200320032f01064102746a41c8056a28020021032012417f6a22120d000b200421160b20032f010621040b200541fc006a2004360200200541e0006a41186a4100360200200541f4006a20033602002005200f3602800120054100360270200542003703682005201636026420054100360260200520054190036a36028401200541d0026a200541e0006a10cd0120052802d002211320052802d402211520052802d802211220054180036a41086a22034200370300200542003703800341f7edcb00ad4280808080f0008410012204290000210720054190036a41086a2200200441086a2900003703002005200737039003200410352003200029030037030020052005290390033703800341b3b6c000ad4280808080d001841001220429000021072004290008210920041035200541e0026a41086a2003290300370300200520093703f802200520073703f00220052005290380033703e0022005410036026820054201370360200b200541e0006a10770240200b450d00200b410574210b4100200528026822046b210120052802642106200e2103034002400240200620016a4120490d00200528026021000c010b200441206a22002004490d06200641017422082000200820004b1b22084100480d060240024020060d00024020080d00410121000c020b200810332200450d0c0c010b2005280260210020062008460d0020002006200810372200450d0b0b2005200836026420052000360260200821060b200020046a22002003290000370000200041186a200341186a290000370000200041106a200341106a290000370000200041086a200341086a2900003700002005200441206a2204360268200141606a2101200341206a2103200b41606a220b0d000b0b2012200541e0006a107702402012450d002013201241d0006c6a210d2013210b03400240024020052802642200200528026822036b4120490d00200528026021040c010b200341206a22042003490d06200041017422012004200120044b1b22014100480d060240024020000d00024020010d00410121040c020b200110332204450d0c0c010b2005280260210420002001460d0020042000200110372204450d0b0b20052001360264200520043602600b200420036a2204200b290000370000200441186a200b41186a290000370000200441106a200b41106a290000370000200441086a200b41086a2900003700002005200341206a3602682005200b41206a3602900320054190036a200541e0006a10cf012005200b41306a3602900320054190036a200541e0006a10cf01200b2802402103200b2802482204200541e0006a107702402004450d00200441306c210603400240024020052802642201200528026822046b4120490d00200528026021000c010b200441206a22002004490d08200141017422082000200820004b1b22084100480d080240024020010d00024020080d00410121000c020b200810332200450d0e0c010b2005280260210020012008460d0020002001200810372200450d0d0b20052008360264200520003602600b200020046a2200200341106a290000370000200041186a200341286a290000370000200041106a200341206a290000370000200041086a200341186a2900003700002005200441206a360268200520033602900320054190036a200541e0006a10cf01200341306a2103200641506a22060d000b0b200d200b41d0006a220b470d000b0b024002400240024002400240200241ff0171220341024b0d0020030e03010203010b2005280268210320052802642100200528026021040c040b410021010c020b410121010c010b410221010b200520013a009003024002402005280264220020052802682203460d00200528026021040c010b200341016a22042003490d05200341017422002004200020044b1b22004100480d050240024020030d0041002103024020000d00410121040c020b200010332204450d0b0c010b2005280260210420032000460d0020042003200010372204450d0a0b20052000360264200520043602600b200420036a20013a00002005200341016a22033602680b200a2003ad4220862004ad84100202402000450d00200410350b02402011450d00200e10350b02402012450d00201241d0006c2104201341c4006a21030340024020032802002200450d00200041306c450d002003417c6a28020010350b200341d0006a2103200441b07f6a22040d000b0b02402015450d00201541d0006c450d00201310350b200541e0006a41286a2200200541a0026a41286a290300370300200541e0006a41206a2201200541a0026a41206a290300370300200541e0006a41186a2206200541a0026a41186a290300370300200541e0006a41106a2208200541a0026a41106a290300370300200541e0006a41086a220b200541a0026a41086a290300370300200520052903a00237036020054180036a41086a22034200370300200542003703800341f7edcb00ad4280808080f0008410012204290000210720054190036a41086a2202200441086a2900003703002005200737039003200410352003200229030037030020052005290390033703800341ceeecb00ad4280808080b001841001220429000021072004290008210920041035200541e0026a41086a2003290300370300200520093703f802200520073703f00220052005290380033703e002413010332203450d0220032005290360370000200341286a2000290300370000200341206a2001290300370000200341186a2006290300370000200341106a2008290300370000200341086a200b290300370000200a2003ad42808080808006841002200310350240201f450d00201f412c6c21042020210303400240200341046a2802002200450d00200041306c450d00200328020010350b2003412c6a2103200441546a22040d000b0b02402010450d002010412c6c450d00202010350b0240201741ffffff3f71450d00201410350b0240200528024441ffffff3f71450d00200528024010350b411d21040c0f0b411b21040b0240024020160d004100210f200541f4006a4100360200200541003602640c010b0240024020120d00201621030c010b2012210320162100034020002802c80521002003417f6a22030d000b201621030340200320032f01064102746a41c8056a28020021032012417f6a22120d000b200021160b200541fc006a20032f0106360200200541f8006a4100360200200541f4006a2003360200200541003602702005420037036820052016360264200541003602600b2005200f36028001200541e0006a109e020240201f450d00201f412c6c21002020210303400240200341046a2802002206450d00200641306c450d00200328020010350b2003412c6a2103200041546a22000d000b0b2010450d072010412c6c450d07202010350c070b1045000b103e000b202541ffffff3f71450d010b201010350b02402019450d002019412c6c21002018210303400240200341046a2802002206450d00200641226c450d00200328020010350b2003412c6a2103200041546a22000d000b0b201d450d02201d412c6c450d02201810350c020b103c000b411521040b41002103201741ffffff3f71450d012014103520110d030c040b41122104410121030b20110d010c020b1044000b200e10350b0240200528024441ffffff3f71450d00200528024010350b2003450d00200110fa010b200541a0036a240020040be10503027f017e057f230041e0006b2202240041f7edcb00ad4280808080f00084100122032900002104200241206a41086a200341086a290000370300200220043703202003103541ccb5c000ad4280808080800284100122032900002104200241c0006a41086a200341086a2900003703002002200437034020031035200220013602542002200241d4006aad4280808080c000841003220329000037035820031035200241146a200241d8006a3602002002200241d8006a41086a36020c2002200241d4006a3602102002200241d8006a360208200241306a200241086a107b02400240024002402002280238220541206a2206417f4c0d00200228023021070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290320370000200341086a200241206a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290340370010200341186a200241c0006a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a02402002280234450d00200710350b200241086a2003200610ae01200241c0006a41086a2201200241086a410c6a2902003703002002200229020c3703400240024020022802084101460d00200042003702002000410c6a41003602000c010b20002002290340370200200041086a20012903003702000b02402008450d00200310350b200241e0006a24000f0b1044000b1045000b103e000b103c000bbb0302027f037e230041d0006b22042400200441386a20024201200242015620034200522003501b22051b22022003420020051b2203428094ebdc034200109808200441286a20042903382206200441386a41086a2903002207428094ebdc034200108408200441186a20022003200620022004290328852003200441286a41086a2903008584420052ad7c22084201200842015620072008200654ad7c22064200522006501b22051b22082006420020051b220710980802400240024020042903182206428080808010544100200441186a41086a290300501b450d00200441086a200220002002200054200320015420032001511b22051b2003200120051b2008200710980820042903082203428080808010544100200441086a41086a290300501b450d012006a7450d02200441d0006a2400200342ffffffff0f83428094ebdc037e200642ffffffff0f8380a70f0b2004411136024c20044190efc40036024841bcedc40041de00200441c8006a41acedc400419ceec4001046000b2004411136024c20044190efc40036024841bcedc40041de00200441c8006a41acedc40041f0eec4001046000b4190edc40041194180efc400103f000bf619020c7f087e23004190046b2204240020044190036a2001108c024100200428029003220520042802980310970241ff0171220620064103461b21060240200428029403450d00200510350b0240024002400240024020060e03000201000b200441a0016a200110b40120044190036a20042802a001220620042802a80110d50120044180026a41086a220520044199036a29000037030020044180026a41106a2207200441a1036a29000037030020044180026a41186a2208200441a9036a29000037030020042004290091033703800202400240024020042d0090034101470d0020044180016a41186a200829030037030020044180016a41106a200729030037030020044180016a41086a2005290300370300200420042903800237038001024020042802a401450d00200610350b200441e0016a41186a20044180016a41186a290300370300200441e0016a41106a20044180016a41106a290300370300200441e0016a41086a20044180016a41086a29030037030020042004290380013703e001200441c0006a200441e0016a10b70120044190036a20042802402209200428024810d601200441a0016a41086a220520044190036a41086a290300370300200441a0016a41106a220720044190036a41106a290300370300200441a0016a41186a220820044190036a41186a29030037030020044180026a41086a220a200441bc036a29020037030020044180026a41106a220b200441c4036a29020037030020044180026a41186a220c200441cc036a29020037030020044180026a41206a220d200441d4036a29020037030020044180026a41286a220e200441dc036a29020037030020044180026a41306a220f200441e4036a28020036020020042004290390033703a001200420042902b4033703800220042802b0032206450d01200441e0026a41186a2008290300370300200441e0026a41106a2007290300370300200441e0026a41086a2005290300370300200441086a41086a200a290300370300200441086a41106a200b290300370300200441086a41186a200c290300370300200441086a41206a200d290300370300200441086a41286a200e290300370300200441086a41306a200f280200360200200420042903a0013703e002200420042903800237030802402004280244450d00200910350b20044180026a41186a200441e0016a41186a290300221037030020044180026a41106a200441e0016a41106a290300221137030020044180026a41086a200441e0016a41086a2903002212370300200420042903e00122133703800220044190036a41186a201037030020044190036a41106a201137030020044190036a41086a201237030020044190036a41286a200441e0026a41086a290300221437030020044190036a41306a200441e0026a41106a290300221537030020044190036a41386a200441e0026a41186a29030022163703002004201337039003200420042903e00222173703b003200441c0006a41386a2016370300200441c0006a41306a2015370300200441c0006a41286a2014370300200441e0006a2017370300200441c0006a41186a2010370300200441c0006a41106a2011370300200441c0006a41086a2012370300200420133703400c020b20042802a401450d04200610350c040b02402004280244450d00200910350b20044180026a41186a200441e0016a41186a29030037030020044180026a41106a200441e0016a41106a29030037030020044180026a41086a200441e0016a41086a290300370300200420042903e001370380020b2006450d02200441a0016a41386a2207200441c0006a41386a290300370300200441a0016a41306a2208200441c0006a41306a290300370300200441a0016a41286a220a200441c0006a41286a290300370300200441a0016a41206a220b200441c0006a41206a290300370300200441a0016a41186a200441c0006a41186a2205290300370300200441a0016a41106a200441c0006a41106a220c290300370300200441a0016a41086a200441c0006a41086a220d290300370300200420042903403703a001200441e0016a41186a2005290300370300200441e0016a41106a200c290300370300200441e0016a41086a200d290300370300200420042903403703e00120044180026a41186a2205200729030037030020044180026a41106a2207200829030037030020044180026a41086a2208200a290300370300200420063602a0022004200b29030037038002200441a4026a2004290308370200200441ac026a200441086a41086a290300370200200441b4026a200441086a41106a290300370200200441bc026a200441086a41186a290300370200200441c4026a200441086a41206a290300370200200441cc026a200441086a41286a290300370200200441d4026a200441086a41306a2802003602002005290300211020072007290300221120027c22123703002005201020037c2012201154ad7c3703002008200829030020037c200429038002221020027c2211201054ad7c221237030020042011370380022004200337038801200420023703800102400240200220038450450d004200210342002110420021020c010b200420013602dc02200441e0026a200120044180016a200441dc026a109a02024020042802e0024101470d004200211020042903e8022103420121020c010b20044188036a290300211020044180036a29030021034200210220042903e8024201520d00200441e0026a41106a2903002113200441c8036a200441e0026a41186a290300370300200441c0036a201337030020044190036a41086a41003a000020044199036a2001290000370000200441a1036a200141086a290000370000200441a9036a200141106a290000370000200441b1036a200141186a290000370000200441033a00900341b0b4cc00410020044190036a10d4010b200442f3e885db96cddbb3203703800120044180016a20044180026a41386a20112012411f10900220044190036a200441e0016a10b701200428029003210120042004280298033602e402200420013602e00220044180026a200441e0026a10e1010240200428029403450d00200110350b024020042802a4022201450d00200141186c450d0020042802a00210350b0240200441b0026a28020041ffffffff0371450d0020042802ac0210350b200242018521020c030b200441a0016a200110b40120044190036a20042802a001220120042802a80110d50120044180026a41086a220620044199036a29000037030020044180026a41106a2205200441a1036a29000037030020044180026a41186a2207200441a9036a290000370300200420042900910337038002024020042d0090034101470d00200441c0006a41186a2007290300370300200441c0006a41106a2005290300370300200441c0006a41086a20062903003703002004200429038002370340024020042802a401450d00200110350b200441a0016a41186a200441c0006a41186a290300370300200441a0016a41106a200441c0006a41106a290300370300200441a0016a41086a200441c0006a41086a290300370300200420042903403703a001200420023703082004200337031002400240200220038450450d004200210242002103420021100c010b2004200441a0016a3602e00220044180026a200441a0016a200441086a200441e0026a109a0202402004280280024101470d00420021102004290388022103420121020c010b200441a8026a2903002110200441a0026a2903002103420021022004290388024201520d0020044180026a41106a2903002111200441c8036a20044180026a41186a290300370300200441c0036a201137030020044190036a41086a41003a000020044199036a20042903a001370000200441a1036a200441a0016a41086a290300370000200441a9036a200441a0016a41106a290300370000200441b1036a200441a0016a41186a290300370000200441033a00900341b0b4cc00410020044190036a10d4010b200242018521020c030b20042802a401450d0120011035420021020c020b200420023703a001200420033703a80102400240200220038450450d004200210342002110420021020c010b2004200136024020044180026a2001200441a0016a200441c0006a109a0202402004280280024101470d00420021102004290388022103420121020c010b200441a8026a2903002110200441a0026a2903002103420021022004290388024201520d0020044180026a41106a2903002111200441c8036a20044180026a41186a290300370300200441c0036a201137030020044190036a41086a41003a000020044199036a2001290000370000200441a1036a200141086a290000370000200441a9036a200141106a290000370000200441b1036a200141186a290000370000200441033a00900341b0b4cc00410020044190036a10d4010b200242018521020c010b420021020b2000200337030820002002370300200041106a201037030020044190046a24000b800201027f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad84100510c20102400240200228020822010d00410321000c010b200228020c210302400240200241106a280200450d0020012d000022004103490d010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b410321000b2003450d00200110350b200241d0006a240020000ba30301067f230041106b22032400024020014105744104722204417f4c0d000240200410332205450d002003410036020820032004360204200320053602002001200310770240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020002101024002402006200522046b4120490d00200441206a21050c010b024002400240200441206a22052004490d00200641017422002005200020054b1b22004100480d000240024020060d00024020000d00410121070c020b2000103321070c040b20062000470d020b200021060c030b103e000b200720062000103721070b2000210620070d00103c000b200141206a2100200720046a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100202402006450d00200710350b200341106a24000f0b1045000b1044000bce0203027f017e037f23004180026b22012400200141086a2000108e02200141e0006a2001280208220020012802102202108f0220012903602103200141b8016a200141e8006a41c400109d081a200141b4016a41026a2204200141af016a2d00003a0000200120012f00ad013b01b4010240024020034201510d0041002105200141186a410041c400109f081a0c010b20012d00ac012105200141186a200141b8016a41c400109d081a200141146a41026a20042d00003a0000200120012f01b4013b01140b200141e8006a200141186a41c400109d082104200141af016a200141166a2d00003a000020014201370360200141002005411874220541808080786a2206200620054b1b4118763a00ac01200120012f01143b00ad01200120023602bc01200120003602b8012004200141b8016a10e7020240200128020c450d00200010350b20014180026a24000bbe1007047f027e027f067e037f067e047f230041d0036b2204240020032802002105200441206a2001108e02200441a0016a2004280220220620042802282207108f0220042903a001210842002109200442003703a001200441e8016a280200210a20042d00ec01210b02400240200842015122030d00200441306a41306a4200370300200441306a41286a4200370300200441306a41206a4200370300200441306a41186a4200370300200441c0006a4200370300200441386a4200370300200442003703304200210c4200210d4200210e4200210f0c010b200441d8016a2903002110200441a0016a41306a2903002111200441a0016a41206a290300210c200441a0016a41186a2903002109200441e0016a290300210f20042903b001210e20042903a801210d200441306a41206a200441a0016a41286a290300370300200441306a41286a2011370300200441306a41306a2010370300200441c0006a20093703002004200c3703482004200d3703302004200e3703380b024002400240427f200d20097c22092009200d542212200e200c7c2012ad7c2209200e542009200e511b22121b427f200920121b84500d000240200d2002290300220c7c2209200d542212200e200241086a29030022107c2012ad7c220d200e54200d200e511b450d00200441a0026a41086a4108360200200441a7d6ca003602a402200441023a00a202200441830c3b01a002200441a0026a21020c020b200420093703302004200d370338200441e8006a41186a200441c0006a220241086a290300220e370300200441e8006a41206a2212200241106a29030037030020044190016a2213200241186a29030037030020044198016a2214200241206a2903003703002004200d3703702004200937036820042002290300221137037802400240427f200920117c221120112009542202200d200e7c2002ad7c220e200d54200e200d511b22021b2211428080e983b1de16544100427f200e20021b220e501b0d00200441e8006a41106a290300210e201429030021112013290300211520122903002116200429037021172004290368211842012119200429038001211a0c010b024002402011200e8450450d00420021190c010b42002119200441a0026a41186a221b4200370300200441a0026a41106a22134200370300200441a0026a41086a22124200370300200442003703a00241b6fdc600ad42808080808001842215100122142900002116200441c0036a41086a2202201441086a290000370300200420163703c0032014103520122002290300370300200420042903c0033703a00241e489c200ad4280808080d0018422161001221429000021172002201441086a290000370300200420173703c00320141035201320042903c0032217370300200441a0036a41086a221c2012290300370300200441a0036a41106a221d2017370300200441a0036a41186a221e2002290300370300200420042903a0023703a003200441086a200441a0036a412010d701200441086a41106a29030021172004290310211820042802082114201b42003703002013420037030020124200370300200442003703a00220151001221b29000021152002201b41086a290000370300200420153703c003201b103520122002290300370300200420042903c0033703a00220161001221b29000021152002201b41086a290000370300200420153703c003201b1035201320042903c0032215370300201c2012290300370300201d2015370300201e2002290300370300200420042903a0023703a003200442002017420020141b2215200e7d2018420020141b2216201154ad7d2217201620117d2218201656201720155620172015511b22021b3703a80220044200201820021b3703a002200441a0036aad4280808080800484200441a0026aad42808080808002841002200441d8026a200e370300200441d0026a2011370300201241013a0000200441a9026a2005290000370000200441b1026a200541086a290000370000200441b9026a200541106a290000370000200441c1026a200541186a290000370000200441033a00a00241b0b4cc004100200441a0026a10d4010b0b200441c8016a2016370300200441d0016a2015370300200441b0016a2017370300200441d8016a2011370300200441b8016a200e3703002004201a3703c0012004200f3703e001200420183703a8014201210e410021022004200b4100200842015122121b3a00ec012004200a410020121b3602e801200420194201512212ad3703a001024020120d002007ad4220862006ad8410074200210e420021080c030b200420073602a402200420063602a002200441a8016a200441a0026a10e702420021080c020b200441a8026a410b360200200441ea88c2003602a402200441073a00a202200441830c3b01a002200441a0026a21020b200241046a290200220d4280807c832108200d42088842ff0183210e200da7210320022802002112410121020b02402004280224450d00200610350b024002402002450d0020002012360204200041086a200e4208862003ad42ff018384200884370200410121010c010b024002400240200341ff017122030d00200e4200510d0041032102200441a0026a21030c010b2003450d01200e4200520d0141042102200441a0016a21030b200341086a20023a0000200341003a0000200341096a2001290000370000200341116a200141086a290000370000200341196a200141106a290000370000200341216a200141186a29000037000041b0b4cc004100200310d4010b200041286a2010370300200041206a200c370300200041186a200d370300200041106a2009370300200041086a4200370300410021010b20002001360200200441d0036a24000bf6c8010e077f017e057f017e0b7f017e037f017e017f017e017f017e017f017e230041d0016b220424002004200336020c20044100360218200442043703102001280204210520012802002106024002400240024002400240024002400240024020012802082203450d0020034103742107200441b0016a41106a2108200441b0016a41176a21092006210a03402002280208200a290200220ba722034d0d07200441b0016a41086a220c200228020020034105746a220341096a2900003703002008200341116a2900003703002009200341186a290000370000200420032900013703b00120032d0000210d412210332203450d02200428020c220e280208200b422088a741ffff0371220f4d0d06200441c0006a41106a2210200e280200200f4105746a220e41116a290000370300200441c0006a41176a220f200e41186a290000370000200441c0006a41086a200e41096a2900002211370300200e290001210b2003200e2d00003a00002003200b370001200341096a2011370000200341ffff033b0120200341116a2010290300370000200341186a200f2900003700002004200b37034020044190016a41176a220f200929000037000020044190016a41106a2210200829030037030020044190016a41086a2212200c290300370300200420042903b0013703900102402004280218220e2004280214470d00200441106a200e41011098012004280218210e0b200a41086a210a2004280210200e412c6c6a220e200d3a000c200e428180808010370204200e2003360200200e410d6a200429039001370000200e41156a2012290300370000200e411d6a2010290300370000200e41246a200f2900003700002004200428021841016a360218200741786a22070d000b0b0240200541ffffffff0171450d00200610350b200128020c2113200141106a2802002114200141146a2802002203450d0320132003410c6c6a211520044190016a41106a210720044190016a41176a210c2013210a034002400240200a41066a2f0100220841ffff03460d002002280208200a28020022034b0d0120004181043b01000c050b200041013b01000c040b200a41086a2f01002109200a41046a2f0100210e20044190016a41086a2210200228020020034105746a220341096a2900003703002007200341116a290000370300200c200341186a290000370000200420032900013703900120032d0000211241c40010332203450d01200428020c220d280208220f200e4d0d02200441b0016a41086a2206200d280200220d200e4105746a220e41096a290000370300200441b0016a41106a2205200e41116a290000370300200441b0016a41176a2216200e41186a2900003700002004200e2900013703b0010240200f20094d0d00200e2d0000210f200441c0006a41086a2217200d20094105746a220e41096a290000370300200441c0006a41106a2209200e41116a290000370300200441c0006a41176a220d200e41186a290000370000200e290001210b200e2d0000210e2003200f3a0000200320042903b001370001200341096a2006290300370000200341116a2005290300370000200341186a20162900003700002003200e3a0022200320083b01202004200b370340200320042903403700232003412b6a2017290300370000200341336a20092903003700002003413a6a200d29000037000020032008417f733b0142200441206a41176a2208200c290000370000200441206a41106a22092007290300370300200441206a41086a220d2010290300370300200420042903900137032002402004280218220e2004280214470d00200441106a200e41011098012004280218210e0b2004280210200e412c6c6a220e20123a000c200e428280808020370204200e2003360200200e410d6a2004290320370000200e41156a200d290300370000200e411d6a2009290300370000200e41246a20082900003700002004200428021841016a360218200a410c6a220a2015470d010c050b0b20004181043b0100200310350c020b103c000b20004181043b0100200310350b4100210641012102200441106a210802402014450d002014410c6c450d00201310350b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f4101211041012112410121140c040b02402014450d002014410c6c450d00201310350b200128021821172001411c6a28020021150240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141206a2802002203450d00201720034104746a2116200441c0006a41086a210e200441c0006a41106a210a200441c0006a41176a2108201721090240024003402009410c6a2f0100210c2009280200210d2004200941046a290200220b3703800102400240200428020c2203280208200ba741ffff037122074d0d00200e200328020020074105746a220341096a290000370300200a200341116a2900003703002008200341186a2900003700002004200329000137034020032d00002107412210332203450d06200320073a0000200320042903403700012003200b421088a722123b0120200341096a200e290300370000200341116a200a290300370000200341186a20082900003700002004428180808010370294012004200336029001200428020c220f28020820042f01840122104b0d0141000d004122450d00200310350b20004181043b01000c3a0b20042f0186012107200441b0016a41176a2206200f28020020104105746a220341186a290000370000200441b0016a41106a2210200341116a290000370300200441b0016a41086a220f200341096a290000220b3703002004200329000122113703b00120032d0000210520082006290000370000200a2010290300370300200e200b3703002004201137034020044190016a41014101109e01200428029001220320053a0022200341236a20042903403700002003412b6a200e290300370000200341336a200a2903003700002003413a6a2008290000370000200341c2006a20073b01002004410236022820042004280294012210360224200420033602200240417f2012411074221220074110746a220720072012491b411076220741ffff03470d00200041013b01000c030b200428020c2212280208200c4d0d012007417f732106200e2012280200200c4105746a220741096a290000370300200a200741116a2900003703002008200741186a290000370000200420072900013703404102210c20072d00002107024020104102470d00200441206a41024101109e01200428022021032004280228210c0b2003200c41226c6a220320073a000020032004290340370001200320063b0120200341096a200e290300370000200341116a200a290300370000200341186a20082900003700002004200428022841016a36022802402002280208200d4d0d0020022802002103200f200441206a41086a280200360200200e2003200d4105746a220341096a290000370300200a200341116a2900003703002008200341186a290000370000200420042903203703b0012004200329000137034020032d000021070240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b001370200200320073a000c200341086a200f2802003602002003410d6a2004290340370000200341156a200e2903003700002003411d6a200a290300370000200341246a20082900003700002004200428021841016a360218200941106a22092016470d010c040b0b20004181043b0100200428022421100c010b20004181043b01000b2010450d36201041226c450d36200428022010350c360b0240201541ffffffff0071450d00201710350b20012802242118200141286a280200211902402001412c6a2802002203450d002018200341146c6a211a2004418a016a211b20044180016a41086a211c200441c0006a41106a2107200441c0006a41176a210c20182115024002400240034020152f01102114201528020021132015290104210b201c2015410c6a2801003602002004200b3703800102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f018201210e200441c0006a41086a220d2003280200200a4105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d0000210341221033220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200d290300370000200f41116a2007290300370000200f41186a200c2900003700002004428180808010370294012004200f360290010240200428020c220328020820042f018401220a4b0d00410221034101210a0c390b201541146a2115417f200e411074220e20042f01860122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201b21080340200c201629000037000020072005290300370300200d2012290300370300200420042903b0013703400240200e417f6a2003470d0020044190016a20034101109e01200428029001210f0b200f200a6a220941606a20173a0000200941616a22032004290340370000200c290000210b20072903002111200d290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e360298010240200a41e400470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d0000211720042802940121030c000b0b410221030c380b200428029401210a20034103470d362004200e3602282004200a3602242004200f3602200240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200d200328020020144105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d000021090240200a200e470d00200441206a200e4101109e012004280220210f2004280228210e0b200f200e41226c6a220320093a000020032004290340370001200c290000210b20072903002111200d290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b3700002004200428022841016a360228200228020820134d0d03200228020021032012200441206a41086a280200360200200d200320134105746a220341096a2900003703002007200341116a290000370300200c200341186a290000370000200420042903203703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200d2903003700002003411d6a2007290300370000200341246a200c2900003700002004200428021841016a3602182015201a470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b01002004280224210a0b200a450d34200a41226c450d34200428022010350c340b02402019450d00201941146c450d00201810350b20012802302118200141346a28020021190240200141386a2802002203450d002018200341186c6a211a2004419a016a211b20044190016a41086a211c200441c0006a41106a2107200441c0006a41176a210c20182115024002400240034020152f01142114201528020021132015290104210b201c2015410c6a2901003703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220d2003280200200a4105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d0000210341221033220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200d290300370000200f41116a2007290300370000200f41186a200c29000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c350b201541186a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201b21080340200c201629000037000020072005290300370300200d2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a22032004290340370000200c290000210b20072903002111200d290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a418601470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c340b2004280224210a20034103470d322004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200d200328020020144105746a220341096a2900003703002007200341116a290000370300200c200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a000020032004290340370001200c290000210b20072903002111200d290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200d200320134105746a220341096a2900003703002007200341116a290000370300200c200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200d2903003700002003411d6a2007290300370000200341246a200c2900003700002004200428021841016a3602182015201a470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d30200a41226c450d3020042802800110350c300b02402019450d00201941186c450d00201810350b200128023c2119200141c0006a280200211e0240200141c4006a2802002203450d0020192003411c6c6a21182004419a016a211a20044190016a41106a211c20044190016a41086a211b200441c0006a41176a210720192115024002400240034020152f01182114201528020021132015410c6a29010021112015290104210b201c201541146a280100360200201b20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221033220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c310b2015411c6a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201a2108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41a801470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c300b2004280224210a20034103470d2e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152018470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d2c200a41226c450d2c20042802800110350c2c0b0240201e450d00201e411c6c450d00201910350b20012802482119200141cc006a280200211e0240200141d0006a2802002203450d00201920034105746a21182004419a016a211a20044190016a41106a211c20044190016a41086a211b200441c0006a41176a210720192115024002400240034020152f011c2114201528020021132015410c6a29010021112015290104210b201c201541146a290100370300201b20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221033220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c2d0b201541206a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e201a2108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41ca01470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c2c0b2004280224210a20034103470d2a2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152018470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d28200a41226c450d2820042802800110350c280b0240201e41ffffff3f71450d00201910350b2001280254211f200141d8006a280200211e0240200141dc006a2802002203450d00201f200341246c6a21192004419a016a211820044190016a41186a211c20044190016a41106a211b20044190016a41086a211a200441c0006a41176a2107201f2115024002400240034020152f01202114201528020021132015410c6a2901002111201541146a290100211d2015290104210b201c2015411c6a280100360200201b201d370300201a20113703002004200b3703900102400240200428020c2203280208200ba741ffff0371220a4d0d0020042f019201210e200441c0006a41086a220c2003280200200a4105746a220341096a290000370300200441c0006a41106a220d200341116a2900003703002007200341186a2900003700002004200329000137034020032d0000210341221033220f450d07200f20033a0000200f2004290340370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f019401220a4b0d00410221034101210a0c290b201541246a2115417f200e411074220e20042f01960122064110746a22082008200e491b4110762110200441b0016a41086a22122003280200200a4105746a220341096a290000370300200441b0016a41106a2205200341116a290000370300200441b0016a41176a2216200341186a290000370000200420032900013703b00120032d000021174101210341c200210a4102210e20182108034020072016290000370000200d2005290300370300200c2012290300370300200420042903b0013703400240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903403700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41ec01470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a290000370000200420032900013703b001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c280b2004280224210a20034103470d262004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a2900003700002004200329000137034020032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903403700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a29000037000020042004290380013703b0012004200329000137034020032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a220320042903b0013702002003200e3a000c200341086a20122802003602002003410d6a2004290340370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152019470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d24200a41226c450d2420042802800110350c240b0240201e450d00201e41246c450d00201f10350b2001280260211f200141e4006a280200211e0240200141e8006a2802002203450d00201f200341286c6a2119200441ca006a2118200441c0006a41186a211c200441c0006a41106a211b200441c0006a41086a211a200441b0016a41176a2107201f2115024002400240034020152f01242114201528020021132015410c6a2901002111201541146a290100211d2015290104210b201c2015411c6a290100370300201b201d370300201a20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c250b201541286a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20182108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a418e02470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c240b2004280224210a20034103470d222004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152019470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d20200a41226c450d2020042802800110350c200b0240201e450d00201e41286c450d00201f10350b200128026c211f200141f0006a28020021200240200141f4006a2802002203450d00201f2003412c6c6a211e200441ca006a2119200441e0006a211c200441c0006a41186a211b200441c0006a41106a211a200441c0006a41086a2118200441b0016a41176a2107201f2115024002400240034020152f01282114201528020021132015410c6a2901002111201541146a290100211d2015411c6a29010021212015290104210b201c201541246a280100360200201b2021370300201a201d370300201820113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c210b2015412c6a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20192108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41b002470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c200b2004280224210a20034103470d1e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201e470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d1c200a41226c450d1c20042802800110350c1c0b02402020450d002020412c6c450d00201f10350b20012802782120200141fc006a280200211f024020014180016a2802002203450d002020200341306c6a211e200441ca006a2119200441e0006a211c200441c0006a41186a211b200441c0006a41106a211a200441c0006a41086a2118200441b0016a41176a210720202115024002400240034020152f012c2114201528020021132015410c6a2901002111201541146a290100211d2015411c6a29010021212015290104210b201c201541246a290100370300201b2021370300201a201d370300201820113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c1d0b201541306a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20192108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41d202470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c1c0b2004280224210a20034103470d1a2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201e470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d18200a41226c450d1820042802800110350c180b0240201f450d00201f41306c450d00202010350b200128028401212020014188016a280200212202402001418c016a2802002203450d002020200341346c6a211f200441ca006a211e200441e8006a211c200441e0006a211b200441c0006a41186a211a200441c0006a41106a2118200441c0006a41086a2119200441b0016a41176a210720202115024002400240034020152f01302114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015290104210b201c2015412c6a280100360200201b2023370300201a20213703002018201d370300201920113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c190b201541346a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201e2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41f402470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c180b2004280224210a20034103470d162004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201f470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d14200a41226c450d1420042802800110350c140b02402022450d00202241346c450d00202010350b200128029001212020014194016a2802002122024020014198016a2802002203450d002020200341386c6a211f200441ca006a211e200441e8006a211c200441e0006a211b200441c0006a41186a211a200441c0006a41106a2118200441c0006a41086a2119200441b0016a41176a210720202115024002400240034020152f01342114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015290104210b201c2015412c6a290100370300201b2023370300201a20213703002018201d370300201920113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c150b201541386a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201e2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a419603470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c140b2004280224210a20034103470d122004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a3602182015201f470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d10200a41226c450d1020042802800110350c100b02402022450d00202241386c450d00202010350b200128029c012124200141a0016a28020021220240200141a4016a2802002203450d0020242003413c6c6a2120200441ca006a211f200441f0006a211c200441e8006a211b200441e0006a211a200441c0006a41186a2118200441c0006a41106a2119200441c0006a41086a211e200441b0016a41176a210720242115024002400240034020152f01382114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015412c6a29010021252015290104210b201c201541346a280100360200201b2025370300201a2023370300201820213703002019201d370300201e20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c110b2015413c6a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201f2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41b803470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c100b2004280224210a20034103470d0e2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152020470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d0c200a41226c450d0c20042802800110350c0c0b02402022450d002022413c6c450d00202410350b20012802a8012122200141ac016a28020021240240200141b0016a2802002203450d00202220034106746a2120200441ca006a211f200441f0006a211c200441e8006a211b200441e0006a211a200441c0006a41186a2118200441c0006a41106a2119200441c0006a41086a211e200441b0016a41176a210720222115024002400240034020152f013c2114201528020021132015410c6a2901002111201541146a290100211d2015411c6a2901002121201541246a29010021232015412c6a29010021252015290104210b201c201541346a290100370300201b2025370300201a2023370300201820213703002019201d370300201e20113703002004200b37034002400240200428020c2203280208200ba741ffff0371220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d07200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c0e0b201541c0006a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e201f2108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41da03470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c0d0b2004280224210a20034103470d0b2004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152020470d010c050b0b200041013b01000c020b20004181043b01000c010b20004181043b0100200428028401210a0b200a450d09200a41226c450d0920042802800110350c090b0240202441ffffff1f71450d00202210350b20012802b4012126200141b8016a2802002124200141bc016a2802002203450d022026200341c4006c6a2122200441ca006a2120200441f8006a211c200441f0006a211b200441e8006a211a200441e0006a2118200441c0006a41186a2119200441c0006a41106a211e200441c0006a41086a211f200441b0016a41176a21072026211502400240034020152f01402114201528020021132015410c6a290100210b201541146a29010021112015411c6a290100211d201541246a29010021212015412c6a2901002123201541346a290100212520152901042127201c2015413c6a280100360200201b2025370300201a2023370300201820213703002019201d370300201e2011370300201f200b3703002004202737034002400240200428020c220328020820042f0140220a4d0d0020042f0142210e200441b0016a41086a220c2003280200200a4105746a220341096a290000370300200441b0016a41106a220d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d0000210341221033220f450d05200f20033a0000200f20042903b001370001200f200e3b0120200f41096a200c290300370000200f41116a200d290300370000200f41186a200729000037000020044281808080103702242004200f3602200240200428020c220328020820042f0144220a4b0d00410221034101210a0c090b201541c4006a2115417f200e411074220e20042f014622064110746a22082008200e491b411076211020044190016a41086a22122003280200200a4105746a220341096a29000037030020044190016a41106a2205200341116a29000037030020044190016a41176a2216200341186a290000370000200420032900013703900120032d000021174101210341c200210a4102210e20202108034020072016290000370000200d2005290300370300200c201229030037030020042004290390013703b0010240200e417f6a2003470d00200441206a20034101109e012004280220210f0b200f200a6a220941606a20173a0000200941616a220320042903b0013700002007290000210b200d2903002111200c290300211d200920063b0100200341086a201d370000200341106a2011370000200341176a200b3700002004200e3602280240200a41fc03470d00410321030c030b417f2010411074220320082f010022064110746a220920092003491b41107621100240200428020c22032802082008417e6a2f010022094b0d00410221030c030b2012200328020020094105746a220341096a2900003703002005200341116a2900003703002016200341186a2900003700002004200329000137039001200e41016a210e200a41226a210a200841046a210820032d00002117200428022421030c000b0b410221030c080b2004280224210a20034103470d062004200e360288012004200a360284012004200f360280010240201041ffff037141ffff03460d00200428020c220328020820144d0d022010417f732108200c200328020020144105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420032900013703b00120032d000021090240200a200e470d0020044180016a200e4101109e01200428028001210f200428028801210e0b200f200e41226c6a220320093a0000200320042903b0013700012007290000210b200d2903002111200c290300211d200320083b0120200341096a201d370000200341116a2011370000200341186a200b370000200420042802880141016a36028801200228020820134d0d0320022802002103201220044180016a41086a280200360200200c200320134105746a220341096a290000370300200d200341116a2900003703002007200341186a290000370000200420042903800137039001200420032900013703b00120032d0000210e0240200428021822032004280214470d00200441106a20034101109801200428021821030b20042802102003412c6c6a22032004290390013702002003200e3a000c200341086a20122802003602002003410d6a20042903b001370000200341156a200c2903003700002003411d6a200d290300370000200341246a20072900003700002004200428021841016a36021820152022470d010c060b0b200041013b01000c030b20004181043b01000c020b20004181043b0100200428028401210a0c010b1045000b200a450d03200a41226c450d0320042802800110350c030b02402024450d00202441c4006c450d00202610350b200041003a0000200041046a20042903103702002000410c6a200441186a2802003602000c370b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b41002102200441106a210802402024450d00202441c4006c450d00202610350b41002109410021050c060b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210941012102200441106a21080240202441ffffff1f710d00410021050c040b20221035410021050c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210541012102200441106a210802402022450d002022413c6c450d00202410350b410121090b410021160c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100211641012102200441106a210802402022450d00202241386c450d00202010350b41012109410121050b410021170c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100211741012102200441106a210802402022450d00202241346c450d00202010350b4101210941012105410121160b410021150c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100211541012102200441106a21080240201f450d00201f41306c450d00202010350b410121094101210541012116410121170b410021070c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210741012102200441106a210802402020450d002020412c6c450d00201f10350b41012109410121054101211641012117410121150b4100210c0c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210c41012102200441106a21080240201e450d00201e41286c450d00201f10350b4101210941012105410121164101211741012115410121070b410021000c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210041012102200441106a21080240201e450d00201e41246c450d00201f10350b4101210941012105410121164101211741012115410121074101210c0b4100210d0c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210d41012102200441106a21080240201e41ffffff3f71450d00201910350b4101210941012105410121164101211741012115410121074101210c410121000b4100210f0c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100210f41012102200441106a21080240201e450d00201e411c6c450d00201910350b4101210941012105410121164101211741012115410121074101210c410121004101210d0b410021100c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100211041012102200441106a210802402019450d00201941186c450d00201810350b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f0b410021120c030b200a450d00200a41226c450d00200f10350b200041013a0000200020033a00010b4100211241012102200441106a210802402019450d00201941146c450d00201810350b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f410121100b41002114410021060c040b4100211441012102200441106a21080240201541ffffffff0071450d00201710350b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f4101211041012112410021060c030b20004181043b0100200310350c010b20004181043b01000b41012102200441106a21080240200541ffffffff0171450d00200610350b4101210941012105410121164101211741012115410121074101210c410121004101210d4101210f410121104101211241012114410121060b02402004280218220e450d0020042802102103200e412c6c210e03400240200341046a280200220a450d00200a41226c450d00200328020010350b2003412c6a2103200e41546a220e0d000b0b0240200841046a2802002203450d002003412c6c450d00200828020010350b02402006450d00200141106a2802002203450d002003410c6c450d00200128020c10350b02402014450d002001411c6a28020041ffffffff0071450d00200128021810350b02402012450d00200141286a2802002203450d00200341146c450d00200128022410350b02402010450d00200141346a2802002203450d00200341186c450d00200128023010350b0240200f450d00200141c0006a2802002203450d002003411c6c450d00200128023c10350b0240200d450d00200141cc006a28020041ffffff3f71450d00200128024810350b02402000450d00200141d8006a2802002203450d00200341246c450d00200128025410350b0240200c450d00200141e4006a2802002203450d00200341286c450d00200128026010350b02402007450d00200141f0006a2802002203450d002003412c6c450d00200128026c10350b02402015450d00200141fc006a2802002203450d00200341306c450d00200128027810350b02402017450d0020014188016a2802002203450d00200341346c450d0020012802840110350b02402016450d0020014194016a2802002203450d00200341386c450d0020012802900110350b02402005450d00200141a0016a2802002203450d002003413c6c450d00200128029c0110350b02402009450d00200141ac016a28020041ffffff1f71450d0020012802a80110350b2002450d00200141b8016a2802002203450d00200341c4006c450d0020012802b40110350b200441d0016a24000bb00401087f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041023a00100c010b200328021421042003200341106a41086a28020036022420032001360220200341c8006a200341206a10c301024002400240024020032802482205450d00200328024c2106024002400240200328022422024104490d00200341c8006a41086a280200210720032002417c6a220836022420032003280220220941046a220a3602202008450d012009280000210920032002417b6a3602242003200a41016a360220200a2d0000220a41014b0d0141002102200a0e020504050b200641ffffff3f710d010c020b200641ffffff3f71450d010b200510350b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b410221020c020b410121020b200341386a41026a200341286a41026a2d0000220a3a0000200341c8006a41026a200a3a0000200320032f002822083b01382000200936020c200020073602082000200636020420002005360200200320083b0148200041136a200a3a0000200020083b00110b200020023a00102004450d00200110350b200341e0006a24000bcb0f0a0f7f017e087f017e017f017e017f027e047f057e230041d0026b22022400200141086a2802002103200128020421042000280204210520002802002106024020002802082207200028020c2208460d0020012802002109200241f0006a410c6a210a200241f0006a410472210b200241c8006a41086a210c200241c8006a41106a210d200241c8006a41186a210e200241c8006a41206a210f0340200c20072200410c6a290200370300200d200041146a290200370300200e2000411c6a290200370300200f200041246a290200370300200220002902043703482000412c6a210720002802002210450d01200b2002290348370200200b41086a200c290300370200200b41106a200d290300370200200b41186a200e290300370200200b41206a200f29030037020020022010360270200a10c8012111200241a0016a41086a2212200a41086a290200370300200241a0016a41106a2213200a41106a290200370300200241a0016a41186a2214200a41186a2902003703002002200a2902003703a00120022802742115024002400240200228027841226c2201450d00201021000340200041206a2f01002116200241b0026a41186a2217200041186a290000370300200241b0026a41106a2218200041106a290000370300200241b0026a41086a2219200041086a290000370300200220002900003703b00220160d02200041226a21002001415e6a22010d000b0b4200211a4108211b4100210002402015450d00201541226c450d00201010354200211a0b4200211c4100211d0c010b200241386a2011420042ffff034200109808200241286a2002290338221e200241386a41086a290300221f4281807c427f108408200241186a201e201f2016ad4200108408200241d0016a41086a22202019290300370300200241d0016a41106a22212018290300370300200241d0016a41186a22222017290300370300200220022903b002221c3703f0012002201c3703d0012016200229032820117ca722236c221641ffff036e211d2002290318211c200241186a41086a29030021240240024041301033221b450d00201b201c201d417f20164180807c491b2016201d4181807c6c6a41ffff014b6aad42ffff03837c221a370320201b20022903d001370300201b41286a2024201a201c54ad7c221c370300201b41186a2022290300370300201b41106a2021290300370300201b41086a202029030037030020024281808080103702c4012002201b3602c001024020014122470d004101211d0c020b200141bc7f6a21214101211d410021160340200020166a220141c2006a2f0100212020172001413a6a2900003703002018200141326a29000037030020192001412a6a2900003703002002200141226a2900003703b0020240024020200d0020212016460d040c010b200241086a201e201f2020ad4200108408200241f0016a41086a20192903002224370300200241f0016a41106a20182903002225370300200241f0016a41186a20172903002226370300200220022903b00222273703f001201720263703002018202537030020192024370300200220273703b002201a20022903082225202020236c220141ffff036e2220417f20014180807c491b200120204181807c6c6a41ffff014b6aad42ffff03837c22247c2226201a542201201c200241086a41086a2903002024202554ad7c22257c2001ad7c221a201c54201a201c511b21010240201d20022802c401470d00200241c0016a201d410110880120022802c001211b0b427f201a20011b211c427f202620011b211a201b201d41306c6a220120022903b00237030020192903002126201829030021272017290300212820012024370320200141286a2025370300200141186a2028370300200141106a2027370300200141086a20263703002002201d41016a221d3602c80120212016460d030b201641226a21160c000b0b1045000b02402015450d00201541226c450d00201010350b20022802c40121000b024002402011201a7d22252011564200201c2011201a54ad7c7d22244200522024501b4101470d00201a20117d2224201a56201c201a201154ad7d2225201c56201a20115a1b0d01201d450d01201d41306c201b6a41706a220142002001290300221c20247d221a201a201c56200141086a2201290300221a20257d201c202454ad7d221c201a56201c201a511b22171b37030020014200201c20171b3703000c010b201d450d00201d41306c201b6a41706a2201427f2001290300221c20257c221a201a201c542217200141086a2201290300221c20247c2017ad7c221a201c54201a201c511b22171b3703002001427f201a20171b3703000b200241b0026a41186a22012014290300370300200241b0026a41106a22172013290300370300200241b0026a41086a22182012290300370300200220022903a0013703b002200920003602042009201d3602082009201b360200200920022903b00237020c200941146a20182903003702002009411c6a2017290300370200200941246a2001290300370200200341016a21032009412c6a210920072008470d000b200821070b20042003360200200820076b2200412c6d210102402000450d002001412c6c210003400240200741046a2802002201450d00200141226c450d00200728020010350b2007412c6a2107200041546a22000d000b0b02402005450d002005412c6c450d00200610350b200241d0026a24000b880303057f017e027f02400240024020002802202201450d00034020002001417f6a36022020002802042201450d0320002802082102200028020021030240200028020c220420012f0106490d00034002400240200128020022050d002002ad2106410021050c010b200341016a210320013301044220862002ad8421060b200110352006a72102200521012006422088a7220420052f01064f0d000b200521010b200441016a2107200120044105746a220541fc026a2802002104200541f8026a280200210802402003450d00200120074102746a41c8056a2802002101410021072003417f6a2205450d00034020012802c80521012005417f6a22050d000b0b2000200736020c2000200236020820002001360204200041003602002008450d0202402004450d00200441306c450d00200810350b200028022022010d000b0b200028020421010b02402001450d0020012802002105200110352005450d00034020052802002101200510352001210520010d000b0b0f0b41958dcc00412b41c08dcc00103f000b13002000411c360204200041c8f4c1003602000be60203047f017e017f024020002802002201450d0020002802082102024020002802042200450d00034020012802e40121012000417f6a22000d000b0b02402002450d0041002103024003402001450d01410021040240200320012f0106490d00034002400240200128020022000d0041002103410021000c010b200441016a210420012f010421030b2001103520002101200320002f01064f0d000b200021010b200341016a210020012003410c6c6a220341e4006a2902002105200341e0006a28020021060240024020040d00200021030c010b200120004102746a41e4016a2802002101410021032004417f6a2200450d00034020012802e40121012000417f6a22000d000b0b2006450d022002417f6a210202402005a7450d00200610350b20020d000c020b0b41958dcc00412b41c08dcc00103f000b2001450d0020012802002100200110352000450d00034020002802002101200010352001210020010d000b0b0b9a9e0106047f017e087f047e287f037e230041c0056b22002400200041b0036a41186a4200370300200041b0036a41106a22014200370300200041b0036a41086a22024200370300200042003703b00341a0e4cb00ad42808080808002841001220329000021042002200341086a290000370300200020043703b0032003103541e1b8c800ad4280808080a0018410012203290000210420004190056a41086a2205200341086a29000037030020002004370390052003103520012000290390052204370300200041f8026a41086a2002290300370300200041f8026a41106a2004370300200041f8026a41186a2005290300370300200020002903b0033703f802200041b0036a200041f8026a10fe010240024020002802b00322020d004100210620004100360298022000420137039002410121020c010b200020002902b40322043702940220002002360290022004422088a721060b024002400240200641ffffff3f712006470d0020064105742203417f4c0d000240024020030d00410121050c010b200310332205450d020b200041003602b803200020053602b003200020034105763602b403200041b0036a41002006108a0120002802b80321070240024020060d0020002802b00321080c010b2006410574210520002802b003220820074105746a2103034020032002290000370000200341186a200241186a290000370000200341106a200241106a290000370000200341086a200241086a290000370000200341206a2103200241206a2102200541606a22050d000b200641057441606a41057620076a41016a21070b20002802b4032109200041b0036a41186a22054200370300200041b0036a41106a220a4200370300200041b0036a41086a22024200370300200042003703b00341a0e4cb00ad42808080808002841001220329000021042002200341086a290000370300200020043703b003200310354189eaca00ad4280808080f0008410012203290000210420004190056a41086a220b200341086a2900003703002000200437039005200310352001200029039005370000200141086a200b290300370000200041f8026a41086a2002290300370300200041f8026a41106a200a290300370300200041f8026a41186a2005290300370300200020002903b0033703f802200041b0036a200041f8026a10a20220002802b003210220002902b4032104200041003602b803200042013703b003200041b0036a41002004420020021b2204422088a7220341306c220a41306d108a012004a7210b2002410820021b210c20002802b803210502402003450d0020002802b00320054105746a2102200c21030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000200541016a2105200241206a2102200341306a2103200a41506a220a0d000b0b200020053602b8030240200b450d00200b41306c450d00200c10350b20002802b403210320002802b003210220004190026a20062005108a01200028029002200028029802220a4105746a20022005410574109d081a2000200a20056a220b360298020240200341ffffff3f71450d00200210350b200041b0036a41186a22054200370300200041b0036a41106a220a4200370300200041b0036a41086a22024200370300200042003703b00341a0e4cb00ad42808080808002841001220329000021042002200341086a290000370300200020043703b0032003103541c699c200ad428080808090018410012203290000210420004190056a41086a2206200341086a2900003703002000200437039005200310352001200029039005370000200141086a2006290300370000200041f8026a41086a2002290300370300200041f8026a41106a200a290300370300200041f8026a41186a2005290300370300200020002903b0033703f802200041b0036a200041f8026a10a20220002802b003210220002902b4032104200041003602b803200042013703b003200041b0036a41002004420020021b2204422088a7220341306c220a41306d108a012004a721062002410820021b210120002802b803210502402003450d0020002802b00320054105746a2102200121030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000200541016a2105200241206a2102200341306a2103200a41506a220a0d000b0b200020053602b80302402006450d00200641306c450d00200110350b20002802b403210320002802b003210220004190026a200b2005108a01200028029002200028029802220a4105746a20022005410574109d081a2000200a20056a360298020240200341ffffff3f71450d00200210350b41a0e4cb00ad4280808080800284100122022900002104200041f0046a41086a2203200241086a290000370300200020043703f004200210354190eaca00ad4280808080e0008410012202290000210420004190056a41086a2205200241086a290000370300200020043703900520021035412010332202450d01200220002903f0043700002002200029039005370010200241086a2003290300370000200241186a220a2005290300370000412010332203450d0120032002290000370000200341186a200a290000370000200341106a200241106a290000370000200341086a200241086a290000370000200041b8026a41026a2205200041b0036a41026a2d00003a0000200020002f00b0033b01b802200041d8026a41106a42a08080808004370300200041003a00f002200020023602e402200042a080808080043702dc02200020033602d802200041f3026a20052d00003a0000200020002f01b8023b00f102200020004190056a3602f402200041b0036a200041d8026a10a3020240024020002802e0032205450d00200041f0046a41186a220a200041b0036a41186a290300370300200041f0046a41106a2206200041b0036a41106a290300370300200041f0046a41086a220b200041b0036a41086a290300370300200020002903b0033703f004200041d8036a290300210d20002903d003210e20002902e403210f200041f8026a41186a4200370300200041f8026a41106a22014200370300200041f8026a41086a22024200370300200042003703f80241b6fdc600ad42808080808001841001220329000021042002200341086a290000370300200020043703f8022003103541e489c200ad4280808080d00184100122032900002104200041b0056a41086a220c200341086a290000370300200020043703b00520031035200120002903b005220437030020004190056a41086a200229030037030020004190056a41106a200437030020004190056a41186a200c290300370300200020002903f80237039005200041f8016a20004190056a412010d701200041e8016a200029038002200041f8016a41106a290300427f420010980820002802f8012102200041b0046a41186a2203200a290300370300200041b0046a41106a2006290300370300200041b0046a41086a200b290300370300200020002903f0043703b004200041e8016a41086a290300210420002903e8012110413810332211450d03200041d8016a200e200d2010420020021b2210420120104201562004420020021b22044200522004501b22021b2004420020021b109808201120002903b0043703082011200f37022c20112005360228201141106a200041b0046a41086a2202290300370300201141186a200041b0046a41106a2205290300370300201141206a2003290300370300201120002903d80137030020004281808080103702a402200020113602a0022003200041d8026a41186a2903003703002005200041d8026a41106a2903003703002002200041d8026a41086a290300370300200020002903d8023703b004200041b0036a200041b0046a10a3020240024020002802e003220b0d00410121120c010b200041b0036a41286a21134138210a41012106410121030340200041d0046a41186a220c200041b0036a41186a290300370300200041d0046a41106a2214200041b0036a41106a290300370300200041d0046a41086a2215200041b0036a41086a290300370300200020002903b0033703d0042013290300210d20002902e403210e20002903d003210f200041f8026a41186a22164200370300200041f8026a41106a22174200370300200041f8026a41086a22024200370300200042003703f80241b6fdc600ad42808080808001841001220529000021042002200541086a290000370300200020043703f8022005103541e489c200ad4280808080d00184100122052900002104200041b0056a41086a2218200541086a290000370300200020043703b00520051035200120002903b005370000200141086a201829030037000020004190056a41086a200229030037030020004190056a41106a201729030037030020004190056a41186a2016290300370300200020002903f80237039005200041c0016a20004190056a412010d701200041b0016a20002903c801200041c0016a41106a290300427f4200109808200041a0016a200f200d20002903b001420020002802c00122021b220442012004420156200041b0016a41086a290300420020021b22044200522004501b22021b2004420020021b109808200041f0046a41186a2205200c290300370300200041f0046a41106a220c2014290300370300200041f0046a41086a22142015290300370300200020002903d0043703f00420002903a0012104024020032006470d00200041a0026a20064101108b0120002802a00221110b2011200a6a22022004370300200241086a20002903f00437030020052903002104200c290300210d2014290300210f2002412c6a200e370200200241286a200b360200200241106a200f370300200241186a200d370300200241206a20043703002000200341016a22023602a802200041b0036a200041b0046a10a302024020002802e003220b450d00200a41386a210a20002802a4022106200221030c010b0b200341016a21120b024020002802b404450d0020002802b00410350b0240200041c0046a280200450d0020002802bc0410350b20002802a40221190c010b024020002802dc02450d0020002802d80210350b4108211141002112024020002802e802450d0020002802e40210350b410021190b20004190056a41086a20004190026a41086a2802003602002000200029039002370390052012ad42387e2204422088a70d002004a72202417f4c0d000240024020020d00410821030c010b200210332203450d020b2000410036028003200020033602f8022000200241386e3602fc02200041f8026a41002012108b01200028028003210102402012450d00201241386c210a20002802f802200141386c6a2102201241037441786a410376210b200041b0036a41286a2106200041b0036a41086a2105201121030340200541186a200341206a290300370300200541106a200341186a290300370300200541086a200341106a2903003703002005200341086a290300370300200020032903003703b0032006200341286a10a402200241306a200041b0036a41306a290300370300200241286a2006290300370300200241206a200041b0036a41206a290300370300200241186a200041b0036a41186a290300370300200241106a200041b0036a41106a290300370300200241086a2005290300370300200220002903b003370300200241386a2102200341386a2103200a41486a220a0d000b2001200b6a41016a21010b4108210a200041b0036a41086a22022001360200200020002903f8023703b003200041a0026a4114410020004190056a200041b0036a10ca010240024020002802a002220c0d0041012118200041013a00b403200041093a00b00341b0b4cc004100200041b0036a10d401200041f8026a2101200041b0036a21060c010b200041a0026a41146a2802002115200041a0026a41106a2802002116200041ac026a2802002101200041a0026a41086a280200210b20002802a402211442002104200041b0036a41186a4200370300200041b0036a41106a221a420037030020024200370300200042003703b00341a0e4cb00ad428080808080028410012203290000210d200041f0046a41086a2205200341086a2900003703002000200d3703f0042003103520022005290300370300200020002903f0043703b0034189eaca00ad4280808080f0008410012203290000210d20004190056a41086a2205200341086a2900003703002000200d3703900520031035201a200029039005220d370300200041f8026a41086a2002290300370300200041f8026a41106a200d370300200041f8026a41186a2005290300370300200020002903b0033703f802200041b0036a200041f8026a10a202024020002802b0032202450d00200041f8026aad4280808080800484100720002902b40321042002210a0b200041003602b803200042013703b003200041b0036a41002004422088a7220241306c220541306d108a012004a7210620002802b803211b02402002450d0020002802b003201b4105746a2102200a21030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000201b41016a211b200241206a2102200341306a2103200541506a22050d000b0b2000201b3602b80302402006450d00200641306c450d00200a10350b20002802b403211c20002802b003211d42002104200041b0036a41186a22054200370300200041b0036a41106a220642003703004108210a200041b0036a41086a22024200370300200042003703b00341a0e4cb00ad428080808080028410012203290000210d200041f0046a41086a2217200341086a2900003703002000200d3703f0042003103520022017290300370300200020002903f0043703b00341c699c200ad428080808090018410012203290000210d20004190056a41086a2217200341086a2900003703002000200d3703900520031035201a200029039005370000201a41086a2017290300370000200041f8026a41086a2002290300370300200041f8026a41106a2006290300370300200041f8026a41186a2005290300370300200020002903b0033703f802200041b0036a200041f8026a10a202024020002802b0032202450d00200041f8026aad4280808080800484100720002902b40321042002210a0b200041003602b803200042013703b003200041b0036a41002004422088a7220241306c220541306d108a012004a7210620002802b803211e02402002450d0020002802b003201e4105746a2102200a21030340200341086a2900002104200341106a290000210d2003290000210e200241186a200341186a290000370000200241106a200d370000200241086a20043700002002200e370000201e41016a211e200241206a2102200341306a2103200541506a22050d000b0b2000201e3602b80302402006450d00200641306c450d00200a10350b20002802b403211f20002802b0032120024002400240200b41306c2203450d00200c21020340200241286a2903002104200241206a290300210d200041f8026a41186a200241186a290000370300200041f8026a41106a200241106a290000370300200041f8026a41086a200241086a290000370300200020022900003703f802200d2004844200520d02200241306a2102200341506a22030d000b0b410121214100210b02402014450d00201441306c450d00200c10350b410021220c010b200041b0046a41086a2205200041f8026a41086a290300370300200041b0046a41106a220a200041f8026a41106a290300370300200041b0046a41186a2206200041f8026a41186a290300370300200020002903f80222043703d004200020043703b004412010332221450d03202120002903b004370000202141186a2006290300370000202141106a200a290300370000202141086a200529030037000020004281808080103702b403200020213602b0030240024020034130470d004101210b0c010b200241306a2105200c200b41306c6a220641506a21174101210b03402005210202400340200241286a2903002104200241206a290300210d200041f8026a41186a2203200241186a290000370300200041f8026a41106a2205200241106a290000370300200041f8026a41086a220a200241086a290000370300200020022900003703f802200d2004844200520d012006200241306a2202470d000c030b0b20004190056a41086a200a290300220437030020004190056a41106a2005290300220d37030020004190056a41186a2003290300220e370300200020002903f802220f37039005200041d0046a41186a220a200e370300200041d0046a41106a2218200d370300200041d0046a41086a221320043703002000200f3703d0040240200b20002802b403470d00200041b0036a200b4101108a0120002802b00321210b200241306a21052021200b4105746a220320002903d004370000200341186a200a290300370000200341106a2018290300370000200341086a20132903003700002000200b41016a220b3602b80320172002470d000b0b02402014450d00201441306c450d00200c10350b20002802b40321220b200020004190056a3602f0042000410036029805200042043703900520004190056a41002015412c6c2203412c6d109801200028029005210520002802980521022000200120036a3602bc03200020013602b803200020163602b403200020013602b0032000200041f0046a3602c003200041f8026a41086a22162002360200200020004190056a41086a22233602fc02200020052002412c6c6a3602f802200041b0036a200041f8026a10a5022000280294052124200041b0036a2021200b2000280290052225200028029805222610cc01200041b8026a41086a200041b0036a41086a2217280200360200200020002903b0033703b802200041003602d804200042083703d004200041d0046a4100200b410574220241057510880120002802d804212720002802d004212802402002450d00202120026a21292028202741306c6a2101200041f8026a41106a211541b6fdc600ad4280808080800184210f2021210b0340200b41086a2900002104200b41106a290000210d200b290000210e200041b0036a41186a2218200b41186a290000370300200041b0036a41106a2213200d370300201720043703002000200e3703b0030240024020002802b8022206450d00200b41206a210b20002802bc02210c0340200641086a210320062f01062214410574210241002105024003402002450d01200041b0036a2003412010a008220a450d04200241606a2102200541016a2105200341206a2103200a417f4a0d000b2005417f6a21140b200c450d01200c417f6a210c200620144102746a41c8056a28020021060c000b0b41b894ca0041da00419495ca001064000b200041f0046a41186a22032018290300370300200041f0046a41106a220a2013290300370300200041f0046a41086a220c2017290300370300200020002903b0033703f004200620054105746a220241f0026a290300210d200241e8026a290300210e200041f8026a41186a220542003703002015420037030020164200370300200042003703f802200f1001220229000021042016200241086a290000370300200020043703f8022002103541e489c200ad4280808080d00184100122022900002104200041b0056a41086a2206200241086a290000370300200020043703b00520021035201520002903b005370000201541086a20062903003700002023201629030037030020004190056a41106a201529030037030020004190056a41186a2005290300370300200020002903f8023703900520004188016a20004190056a412010d701200041f8006a20002903900120004188016a41106a290300427f4200109808200041e8006a2000290378420020002802880122021b220442012004420156200041f8006a41086a290300420020021b22044200522004501b22021b2004420020021b200e200d108408200141186a2003290300370300200141106a200a290300370300200141086a200c290300370300200120002903f004370300200141286a200041e8006a41086a29030037030020012000290368370320202741016a2127200141306a2101200b2029470d000b0b200020273602d8040240202241ffffff3f71450d00202110350b20002802d404212a024002402027410d2027410d491b222b0d00200041003602b803200042083703b003200041b0036a4100410010880120002802b80321290c010b202b41306c220510332202450d03200041003602b8032000202b3602b403200020023602b003200041b0036a4100202b10880120002802b00320002802b803222941306c6a2102202821030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102202941016a2129200341306a2103200541506a22050d000b200020293602b8030b20002802b403212c20002802b00321170240024020294115490d002029410176ad42307e2204422088a70d032004a7222d417f4c0d03202d1033222e450d042000410036028003200042043703f802201741506a212f201741f07e6a21304104210541002103410021312029212303402023210b410021234101210c0240200b417f6a2206450d000240024002400240024002402017200641306c6a200b41306c220220176a41a07f6a412010a0084100480d00200b417e6a2101203020026a2102410021234100210a034002402001200a470d00200b210c0c080b200a41016a210a200241306a2002412010a0082106200241506a21022006417f4a0d000b200a41016a210c200a417f73200b6a21060c010b2030200b41066c41037422146a210202400340024020064101470d00410021060c020b2006417f6a2106200241306a2002412010a008210a200241506a2102200a4100480d000b0b200b2006490d01200b20294b0d02200b20066b220c4101762201450d00202f20146a21022017200641306c6a210a0340200041b0036a41286a2214200a41286a2215290300370300200041b0036a41206a2216200a41206a2218290300370300200041b0036a41186a2213200a41186a2223290300370300200041b0036a41106a2221200a41106a2222290300370300200041b0036a41086a2232200a41086a22332903003703002000200a2903003703b003200241086a22342903002104200241106a2235290300210d200241186a2236290300210e200241206a2237290300210f200241286a22382903002110200a2002290300370300201520103703002018200f3703002023200e3703002022200d370300203320043703002038201429030037030020372016290300370300203620132903003703002035202129030037030020342032290300370300200220002903b003370300200241506a2102200a41306a210a2001417f6a22010d000b0b024020060d00200621230c050b0240200c41094d0d00200621230c050b200b20294b0d02200b20066b21012017200641306c6a21140340200b2006417f6a2223490d040240200b20236b220c4102490d002017200641306c6a22022017202341306c6a2206412010a008417f4a0d002006290300210420062002290300370300200041b0036a41286a2213200641286a220a290300370300200041b0036a41206a2221200641206a2215290300370300200041b0036a41186a2222200641186a2216290300370300200041b0036a41106a2232200641106a2218290300370300200041b0036a41086a2233200641086a22342903003703002034200241086a2903003703002018200241106a2903003703002016200241186a2903003703002015200241206a290300370300200a200241286a290300370300200020043703b003410121180240200c4103490d00200641e0006a200041b0036a412010a008417f4a0d004102210a2014210202400340200241286a200241d8006a290300370300200241206a200241d0006a290300370300200241186a200241c8006a290300370300200241106a200241c0006a290300370300200241086a200241386a2903003703002002200241306a22152903003703002001200a460d01200241e0006a2116200a211820152102200a41016a210a2016200041b0036a412010a008417f4a0d020c000b0b200a21180b2006201841306c6a220220002903b003370300200241286a2013290300370300200241206a2021290300370300200241186a2022290300370300200241106a2032290300370300200241086a20332903003703000b2023450d05201441506a2114200141016a210120232106200c410a4f0d050c000b0b2006200b41eccfca001059000b200b202941eccfca001058000b200b2006417f6a2223490d00200b202941fccfca001058000b2023200b41fccfca001059000b0240203120002802fc02470d00200041f8026a2031410110900120002802f8022105200028028003220321310b200520314103746a2202200c360204200220233602002000200341016a22033602800320032131024020034102490d000240024003400240024002400240024020052003417f6a4103746a2202280200450d00200341037420056a220141746a28020022062002280204220a4b0d010b20034103490d022002280204210a20052003417d6a22164103746a28020421020c010b41022131200341024d0d0620052003417d6a22164103746a2802042202200a20066a4d0d0041032131200341034d0d06200141646a280200200220066a4b0d050b2002200a490d010b2003417e6a21160b02400240024002400240024002402003201641016a22184d0d00200320164d0d012005201641037422216a2202280204222220022802006a22022005201841037422326a22032802002213490d02200220294b0d032017201341306c6a22142003280204221541306c22036a210a200241306c2105200220136b220120156b220220154f0d04202e200a200241306c2203109d08220c20036a210620154101480d0520024101480d05202f20056a2103200a210203402003200241506a220a200641506a22012001200a412010a008410048220b1b2205290300370300200341286a200541286a290300370300200341206a200541206a290300370300200341186a200541186a290300370300200341106a200541106a290300370300200341086a200541086a29030037030020062001200b1b210602402014200a2002200b1b2202490d00200c21050c080b200341506a2103200c2105200c2006490d000c070b0b20182003418cd0ca001042000b20162003419cd0ca001042000b2013200241acd0ca001059000b2002202941acd0ca001058000b202e20142003109d08220c20036a2106024020154101480d00200120154c0d00201720056a210b200c21052014210203402002200a2005200a2005412010a00841004822011b2203290300370300200241286a200341286a290300370300200241206a200341206a290300370300200241186a200341186a290300370300200241106a200341106a290300370300200241086a200341086a2903003703002005200541306a20011b2105200241306a2102200a41306a200a20011b220a200b4f0d03200620054b0d000c030b0b20142102200c21050c010b200a2102200c21050b20022005200620056b220320034130706b109d081a0240200028028003220220164d0d0020002802f802220520216a2203202220156a36020420032013360200200220184d0d02200520326a2203200341086a20022018417f736a410374109e081a20002002417f6a220336028003200341014b0d010c030b0b2016200241bcd0ca001042000b20182002104e000b200321310b20230d000b024020002802fc0241ffffffff0171450d00200510350b202d4130702102202d4130490d01202d2002460d01202e10350c010b20294102490d002029417f6a2103202941306c20176a41506a21064101210503400240024002400240202920032202417f6a2203490d00202920036b22014102490d032017200241306c6a22022017200341306c6a220a412010a008417f4a0d03200a2903002104200a2002290300370300200041b0036a41286a2215200a41286a220b290300370300200041b0036a41206a2216200a41206a220c290300370300200041b0036a41186a2218200a41186a2214290300370300200041b0036a41106a2213200a41106a2223290300370300200041b0036a41086a2221200a41086a22222903003703002022200241086a2903003703002023200241106a2903003703002014200241186a290300370300200c200241206a290300370300200b200241286a290300370300200020043703b0034101210220014103490d02200a41e0006a200041b0036a412010a008417f4a0d0241002101200621020340200241286a200241d8006a290300370300200241206a200241d0006a290300370300200241186a200241c8006a290300370300200241106a200241c0006a290300370300200241086a200241386a2903003703002002200241306a220c29030037030020052001220b460d02200b417f6a2101200241e0006a2114200c21022014200041b0036a412010a008417f4a0d020c000b0b2003202941dccfca001059000b4102200b6b21020b200a200241306c6a220220002903b003370300200241286a2015290300370300200241206a2016290300370300200241186a2018290300370300200241106a2013290300370300200241086a20212903003703000b200641506a21062005417f6a210520030d000b0b200041003602b803200042083703b003200041b0036a4100202941306c221341306e2223109a0120002802b803210b0240024020130d0020002802b00321010c010b20002802b0032201200b4104746a21022013210520172103034020022003360200200241086a4200370300200241106a2102200b41016a210b200341306a2103200541506a22050d000b0b2011201241386c6a211520002802b403212102400240024020120d002011210c0c010b200b41014b2118201121020340200241386a210c20022802282216450d0102402002412c6a290200220e422088a74105742203450d002002290300210d024020180d000240200b0e020200020b2001280200210542102104201621020340024020052002412010a0080d0020012001290308200d200442ffffffff0f837e7c3703080b200241206a21022004427f7c2104200341606a22030d000c020b0b201620036a21144200210420162106024003400240200b450d0041002102200b210303402003410176220520026a220a20022001200a4104746a2802002006412010a0084101481b2102200320056b220341014b0d000b200120024104746a22032802002006412010a0080d00200b20024d0d0220032003290308200d421020047d42ffffffff0f837e7c3703080b200442017c21042014200641206a2206460d020c000b0b2002200b41d099c2001042000b0240200e42ffffff3f83500d00201610350b200c2102200c2015470d000c020b0b2015200c460d000340200c41386a21020240200c412c6a28020041ffffff3f71450d00200c41286a28020010350b2002210c20152002470d000b0b02402019450d00201941386c450d00201110350b201720136a210c024002400240200b450d0020012802002203450d000240200b4101460d002001200b4104746a2106200141106a210220012903082104034020022802002205450d012004200241086a290300220d2004200d56220a1b210420032005200a1b2103200241106a22022006470d000b0b0240202141ffffffff0071450d00200110350b20030d01410021160c020b41002116202141ffffffff0071450d01200110350c010b200041d8026a41186a200341186a290000370300200041d8026a41106a200341106a290000370300200041d8026a41086a200341086a290000370300200020032900003703d802410121160b200041003602b803200042013703b003200041b0036a41002023108a0120002802b8032105024002402017200c4722310d0020002802b00321340c010b202941306c210a20002802b003223420054105746a210220172103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200541016a2105200241206a2102200341306a2103200a41506a220a0d000b0b20002802b403212f200041003602b803200042083703b003200041b0036a41002028202741306c22026a22032028202b41306c220a6a6b41306e10880120002802b8032115024002402027410d4b0d0020002802b00321360c010b200a20026b210a20002802b0032236201541306c6a2102200341506a21030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102200341506a2103201541016a2115200a41306a220a0d000b0b20002802b4032137200041003602b803200042013703b003200041b0036a41002015108a0120002802b803210a02400240201541306c22060d0020002802b00321210c010b20002802b0032221200a4105746a210220362103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200a41016a210a200241206a2102200341306a2103200641506a22060d000b0b20002802b4032127200041b0036a20342005201d201b10a602200041c4036a280200220b41ffffff3f71200b470d01200b4105742201417f4c0d01200041c0036a280200211b20002802bc03212220002802b403213020002802b003212b0240024020010d00410121020c010b200110332202450d030b200041003602b803200020023602b0032000200141057622183602b403200041b0036a4100200b108a0120002802b803210c02400240200b0d0020002802b00321140c010b200b410574210620002802b0032214200c4105746a210220222103034020022003290000370000200241186a200341186a290000370000200241106a200341106a290000370000200241086a200341086a290000370000200241206a2102200341206a2103200641606a22060d000b200b41057441606a410576200c6a41016a210c0b20002802b40321022014200c2034200510a7020240200241ffffff3f71450d00201410350b200041b0046a41186a2202200041d8026a41186a290300370300200041b0046a41106a2203200041d8026a41106a290300370300200041b0046a41086a2205200041d8026a41086a290300370300200020002903d8023703b0040240024020160d00200041f8026a41186a4200370300200041f8026a41106a22054200370300200041f8026a41086a22024200370300200042003703f80241dad5ca00ad4280808080b002841001220329000021042002200341086a290000370300200020043703f80220031035419cdfca00ad4280808080d00084100122032900002104200041b0056a41086a2206200341086a290000370300200020043703b00520031035200520002903b0052204370300200041f0046a41086a2002290300370300200041f0046a41106a2004370300200041f0046a41186a2006290300370300200020002903f8023703f004200041f0046aad428080808080048410070c010b200041b0036a41186a2002290300370300200041b0036a41106a2003290300370300200041b0036a41086a2005290300370300200020002903b0043703b00320004190056a41186a420037030020004190056a41106a2205420037030020004190056a41086a22024200370300200042003703900541dad5ca00ad4280808080b002841001220329000021042002200341086a290000370300200020043703900520031035419cdfca00ad4280808080d00084100122032900002104200041f8026a41086a2206200341086a290000370300200020043703f80220031035200520002903f8022204370300200041d0046a41086a2002290300370300200041d0046a41106a2004370300200041d0046a41186a200629030037030020002000290390053703d004412010332202450d03200220002903b003370000200241186a200041b0036a41186a290300370000200241106a200041b0036a41106a290300370000200241086a200041b0036a41086a290300370000200041d0046aad42808080808004842002ad42808080808004841002200210350b0240024020010d00410121030c010b200110332203450d030b41002102200041003602b803200020183602b403200020033602b003200041b0036a4100200b108a0120002802b803210c0240200b450d00200b410574210620002802b003200c4105746a21010340200120026a2203202220026a2205290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a2900003700002006200241206a2202470d000b200b41057441606a410576200c6a41016a210c0b200041b8046a200c360200200020002903b0033703b004200041b0036a2021200a2020201e10a602200041c4036a2802002103200041c0036a280200210520002802bc032102024020002802b40341ffffff3f71450d0020002802b00310350b200041b0046a20002802b804200341057422034105752206108a0120002802b004222e20002802b80422014105746a20022003109d081a2000200120066a22383602b8040240200541ffffff3f71450d00200210350b02402007450d00200820074105746a2118200a4105742113200041b0036aad42808080808002842139200041f8026aad4280808080800484213a200041b0036a41106a2101200041b9036a2132202941014b2123200041e8036a21352008210b0340200b41086a2900002104200b41106a290000210d200b290000210e20004190056a41186a220c200b41186a29000037030020004190056a41106a2214200d37030020004190056a41086a221620043703002000200e37039005200b41206a210b410021030240024002400240024020230d0020290e020201020b202921050340200041b0036a41186a20172005410176220a20036a220641306c6a220241186a2900003703002001200241106a290000370300200041b0036a41086a200241086a290000370300200020022900003703b00320062003200041b0036a20004190056a412010a0084101481b21032005200a6b220541014b0d000b0b200041b0036a41186a2017200341306c6a220241186a2900003703002001200241106a290000370300200041b0036a41086a200241086a290000370300200020022900003703b0032013210320212102200041b0036a20004190056a412010a0080d010c020b20132103202121020b024003402003450d0120004190056a2002460d02200341606a2103200220004190056a412010a0082105200241206a210220050d000c020b0b200042003703f80420004280809aa6eaafe3013703f004200020004190056a3602d004200041f8026a20004190056a200041f0046a200041d0046a10a802200041f8026a41206a290300210d2000290390032104024020002903f8024201520d00200029038003210e2035200041f8026a41106a2903003703002032200029039005370000203241086a2016290300370000203241106a2014290300370000203241186a200c2903003700002000200e3703e003200041003a00b803200041033a00b00341b0b4cc004100200041b0036a10d4010b200020043703d0042000200d3703d804024002402004200d844200520d00200041b0036a41186a2205420037030020014200370300200041b0036a41086a22034200370300200042003703b00341b6fdc600ad428080808080018422041001220a290000210d200041f0046a41086a2202200a41086a2900003703002000200d3703f004200a103520032002290300370300200020002903f0043703b00341e489c200ad4280808080d00184220d1001220a290000210e2002200a41086a2900003703002000200e3703f004200a1035200120002903f004370000200141086a220c2002290300370000200041f8026a41086a22142003290300370300200041f8026a41106a22162001290300370300200041f8026a41186a22332005290300370300200020002903b0033703f802200041386a200041f8026a412010d701200041386a41106a290300210e2000290340210f2000280238210a200542003703002001420037030020034200370300200042003703b00320041001220629000021042002200641086a290000370300200020043703f0042006103520032002290300370300200020002903f0043703b003200d1001220629000021042002200641086a290000370300200020043703f00420061035200120002903f004370000200c2002290300370000201420032903003703002016200129030037030020332005290300370300200020002903b0033703f8022000200e4200200a1b3703b8032000200f4200200a1b3703b0030c010b200020043703d0042000200d3703d804200041b0036a41186a2205420037030020014200370300200041b0036a41086a22034200370300200042003703b00341b6fdc600ad4280808080800184220e1001220a290000210f200041f0046a41086a2202200a41086a2900003703002000200f3703f004200a103520032002290300370300200020002903f0043703b00341e489c200ad4280808080d00184220f1001220a29000021102002200a41086a290000370300200020103703f004200a1035200120002903f004370000200141086a220c2002290300370000200041f8026a41086a22142003290300370300200041f8026a41106a22162001290300370300200041f8026a41186a22332005290300370300200020002903b0033703f802200041d0006a200041f8026a412010d701200041d0006a41106a29030021102000290358213b2000280250210a200542003703002001420037030020034200370300200042003703b003200e10012206290000210e2002200641086a2900003703002000200e3703f0042006103520032002290300370300200020002903f0043703b003200f10012206290000210e2002200641086a2900003703002000200e3703f00420061035200120002903f004370000200c2002290300370000201420032903003703002016200129030037030020332005290300370300200020002903b0033703f8022000420020104200200a1b220e200d7d203b4200200a1b220d200454ad7d220f200d20047d2204200d56200f200e56200f200e511b22021b3703b80320004200200420021b3703b0030b203a203910020b200b2018470d000b0b0240200941ffffff3f71450d00200810350b20002802b404213302402038450d0020384105742101200041b0036aad42808080808002842139200041f8026aad4280808080800484213a200041b0036a41106a2102200041b9036a210b200041e8036a2132202e21030340200341086a2900002104200341106a290000210d2003290000210e20004190056a41186a2205200341186a29000037030020004190056a41106a220a200d37030020004190056a41086a220620043703002000200e37039005200042003703f80420004280809aa6eaafe3013703f004200020004190056a3602d004200041f8026a20004190056a200041f0046a200041d0046a10a802200041f8026a41206a290300210d2000290390032104024020002903f8024201520d00200029038003210e2032200041f8026a41106a290300370300200b200029039005370000200b41086a2006290300370000200b41106a200a290300370000200b41186a20052903003700002000200e3703e003200041003a00b803200041033a00b00341b0b4cc004100200041b0036a10d4010b200020043703d0042000200d3703d804024002402004200d844200520d00200041b0036a41186a2206420037030020024200370300200041b0036a41086a220a4200370300200042003703b00341b6fdc600ad428080808080018422041001220c290000210d200041f0046a41086a2205200c41086a2900003703002000200d3703f004200c1035200a2005290300370300200020002903f0043703b00341e489c200ad4280808080d00184220d1001220c290000210e2005200c41086a2900003703002000200e3703f004200c1035200220002903f004370000200241086a22162005290300370000200041f8026a41086a2218200a290300370300200041f8026a41106a22132002290300370300200041f8026a41186a22232006290300370300200020002903b0033703f802200041086a200041f8026a412010d701200041086a41106a290300210e2000290310210f2000280208210c2006420037030020024200370300200a4200370300200042003703b00320041001221429000021042005201441086a290000370300200020043703f00420141035200a2005290300370300200020002903f0043703b003200d1001221429000021042005201441086a290000370300200020043703f00420141035200220002903f004370000201620052903003700002018200a2903003703002013200229030037030020232006290300370300200020002903b0033703f8022000200e4200200c1b3703b8032000200f4200200c1b3703b0030c010b200020043703d0042000200d3703d804200041b0036a41186a2206420037030020024200370300200041b0036a41086a220a4200370300200042003703b00341b6fdc600ad4280808080800184220e1001220c290000210f200041f0046a41086a2205200c41086a2900003703002000200f3703f004200c1035200a2005290300370300200020002903f0043703b00341e489c200ad4280808080d00184220f1001220c29000021102005200c41086a290000370300200020103703f004200c1035200220002903f004370000200241086a22162005290300370000200041f8026a41086a2218200a290300370300200041f8026a41106a22132002290300370300200041f8026a41186a22232006290300370300200020002903b0033703f802200041206a200041f8026a412010d701200041206a41106a29030021102000290328213b2000280220210c2006420037030020024200370300200a4200370300200042003703b003200e10012214290000210e2005201441086a2900003703002000200e3703f00420141035200a2005290300370300200020002903f0043703b003200f10012214290000210e2005201441086a2900003703002000200e3703f00420141035200220002903f004370000201620052903003700002018200a2903003703002013200229030037030020232006290300370300200020002903b0033703f8022000420020104200200c1b220e200d7d203b4200200c1b220d200454ad7d220f200d20047d2204200d56200f200e56200f200e511b22051b3703b80320004200200420051b3703b0030b203a20391002200341206a2103200141606a22010d000b0b0240203341ffffff3f71450d00202e10350b200041b0036a41186a22034200370300200041b0036a41106a22054200370300200041b0036a41086a22024200370300200042003703b00341a0e4cb00ad4280808080800284220410012206290000210d200041f0046a41086a220a200641086a2900003703002000200d3703f004200610352002200a290300370300200020002903f0043703b0034189eaca00ad4280808080f0008410012201290000210d20004190056a41086a2206200141086a2900003703002000200d3703900520011035201a200029039005370000201a41086a220b2006290300370000200041f8026a41086a220c2002290300370300200041f8026a41106a22142005290300370300200041f8026a41186a22162003290300370300200020002903b0033703f802200041203602b4032000200041f8026a3602b00320172029200041b0036a10a902200342003703002005420037030020024200370300200042003703b0032004100122012900002104200a200141086a290000370300200020043703f004200110352002200a290300370300200020002903f0043703b00341c699c200ad42808080809001841001220a29000021042006200a41086a2900003703002000200437039005200a1035201a200029039005370000200b2006290300370000200c20022903003703002014200529030037030020162003290300370300200020002903b0033703f802200041203602b4032000200041f8026a3602b00320362015200041b0036a10a9022029ad42307e2204422088a70d012004a72202417f4c0d010240024020020d00410821030c010b200210332203450d030b200041003602b803200020033602b0032000200241306e3602b403200041b0036a4100202910880120002802b80321050240024020310d0020002802b00321010c010b202941306c210a20002802b0032201200541306c6a2102201721030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102200541016a2105200341306a2103200a41506a220a0d000b0b2005ad42307e2204422088a70d012004a72202417f4c0d0120002802b40321060240024020020d00410821030c010b200210332203450d030b200041003602b803200020033602b0032000200241306e3602b403200041b0036a4100200510880120002802b803210a0240200541306c2205450d0020002802b003200a41306c6a2102200121030340200341086a2903002104200341106a290300210d200341186a290300210e2003290300210f200241286a200341286a290300370300200241206a200341206a290300370300200241186a200e370300200241106a200d370300200241086a20043703002002200f370300200241306a2102200a41016a210a200341306a2103200541506a22050d000b0b20004183036a200a360000200020002903b0033700fb02200041bc036a200041ff026a290000370000200041003a00b403200041093a00b003200020002900f8023700b50341b0b4cc004100200041b0036a10d40102402006450d00200641306c450d00200110350b0240201b41ffffff3f71450d00202210350b0240203041ffffff3f71450d00202b10350b0240202741ffffff3f71450d00202110350b02402037450d00203741306c450d00203610350b0240202f41ffffff3f71450d00203410350b0240202c450d00202c41306c450d00201710350b0240202a450d00202a41306c450d00202810350b0240024020002802b802220a0d0041002106200041c4036a4100360200200041003602b4030c010b20002802c00221060240024020002802bc0222030d00200a21020c010b20032102200a2105034020052802c80521052002417f6a22020d000b200a21020340200220022f01064102746a41c8056a28020021022003417f6a22030d000b2005210a0b200041cc036a20022f0106360200200041c8036a4100360200200041c4036a2002360200200041003602c003200042003703b8032000200a3602b403200041003602b0030b200020063602d003200041b0036a109e0202402026450d002026412c6c21032025210203400240200241046a2802002205450d00200541306c450d00200228020010350b2002412c6a2102200341546a22030d000b0b02402024450d002024412c6c450d00202510350b0240201f41ffffff3f71450d00202010350b41002118200041b0036a2106200041f8026a2101201c41ffffff3f71450d00201d10350b200041b0036a41186a220b4200370300200041b0036a41106a22024200370300200041b0036a41086a22034200370300200042003703b00341a0e4cb00ad428080808080028422041001220a290000210d200041f0046a41086a2205200a41086a2900003703002000200d3703f004200a1035200641086a220c2005290300370000200620002903f00437000041e1b8c800ad4280808080a0018410012214290000210d20004190056a41086a220a201441086a2900003703002000200d37039005201410352002200029039005220d370300200041f8026a41086a22142003290300370300200041f8026a41106a2215200d370300200041f8026a41186a2216200a290300370300200020002903b0033703f8022001ad42808080808004841007200b42003703002002420037030020034200370300200042003703b003200410012217290000210d2005201741086a2900003703002000200d3703f00420171035200c2005290300370000200620002903f00437000041b0e4cb00ad4280808080e00184220d10012217290000210e200a201741086a2900003703002000200e37039005201710352002200029039005220e370300201420032903003703002015200e3703002016200a290300370300200020002903b0033703f80220002001412010c0012000280200211720002802042113200b42003703002002420037030020034200370300200042003703b00320041001220129000021042005200141086a290000370300200020043703f00420011035200c2005290300370000200620002903f004370000200d100122052900002104200a200541086a2900003703002000200437039005200510352002200029039005220437030020142003290300370300201520043703002016200a290300370300200020002903b0033703f8022000201341016a410120171b3602b003200041f8026aad4280808080800484200041b0036aad4280808080c0008410020240024020002802a00222020d0020180d010c040b2018450d03024020002802a4022203450d00200341306c450d00200210350b200041ac026a280200210a0240200041b4026a2802002202450d002002412c6c2103200a210203400240200241046a2802002205450d00200541246c450d00200228020010350b2002412c6a2102200341546a22030d000b0b200041b0026a2802002202450d002002412c6c450d00200a10350b02402012450d00201241386c21032011412c6a210203400240200228020041ffffff3f71450d002002417c6a28020010350b200241386a2102200341486a22030d000b0b02402019450d00201941386c450d00201110350b200941ffffff3f71450d02200810350c020b1044000b1045000b200041c0056a24000bbf0201027f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022010d00200041003602000c010b200228021421032002200241106a41086a28020036022420022001360220200241c8006a200241206a10aa020240024020022802480d0020024100360230200242013703282002410936023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b200041003602000c010b20002002290348370200200041086a200241c8006a41086a2802003602000b2003450d00200110350b200241e0006a24000ba00605057f017e037f027e027f230041f0006b22022400200241286a200141146a350200422086200135020c84102710c2010240024020022802282203450d00200141086a2104200141106a210503400240024020042802002206200229022c2207422088a722084b0d00200128020022092003460d0120092003200610a008450d010b2007a7450d02200310350c020b02402005280200450d00200128020c10350b2001200336020c20052007370200200241086a2003200810cc02024002402002280218220a450d00200241086a41086a29030021072002290308210b2002290320210c200228021c210d024020012d0018450d002001350214422086200135020c8410070b2001280214220820042802002203490d0102400240200820036b22084108490d00200841786a2106200128020c20036a41086a21090c010b410021060240410028028cb54c0d0041b0b4cc0021090c010b410021064100280298b54c21034100280294b54c21084100280290b54c210e200241e500360268200242b48080801037036020024187a1c00036025c20024213370254200241f4a0c0003602502002420037034841b0b4cc002109200241b0b4cc0036024420024201370338200241eca0c00036023420024113360230200241f4a0c00036022c20024101360228200841aca2c000200e410246220e1b200241286a200341c4a2c000200e1b2802101102000b41002103200241003a00480240034020062003460d01200241286a20036a200920036a2d00003a00002002200341016a22083a00482008210320084120470d000b20002002290328370000200041186a200241286a41186a290300370000200041106a200241286a41106a290300370000200041086a200241286a41086a290300370000200041286a20073703002000200b370320200041386a200c3703002000200d3602342000200a3602300c050b0240200341ff0171450d00200241003a00480b200d41ffffff3f71450d00200a10350b200241286a2001350214422086200135020c84102710c201200228022822030d010c020b0b2003200841889aca001059000b200041003602300b200241f0006a24000ba10201087f230041106b22022400024002402001280208220341ffffff3f712003470d0020034105742204417f4c0d00200128020021050240024020040d00410121060c010b200410332206450d020b41002101200241003602082002200636020020022004410576360204200241002003108a012002280208210702402003450d0020034105742108200228020020074105746a21090340200920016a2204200520016a2206290000370000200441186a200641186a290000370000200441106a200641106a290000370000200441086a200641086a2900003700002008200141206a2201470d000b200341057441606a41057620076a41016a21070b20002002290300370200200041086a2007360200200241106a24000f0b1044000b1045000b8509050f7f027e017f017e027f23004180026b22022400200141086a2802002103200128020421042000280204210520002802002106024020002802082207200028020c2208460d002001280200210020024190016a410c6a2109200241c0016a41106a210120024190016a410472210a200241386a41206a210b200241386a41186a210c200241386a41086a210d024003402007280200210e200b200741246a290200370300200c2007411c6a290200370300200241386a41106a220f200741146a290200370300200d2007410c6a2902003703002002200741046a290200370338200e450d01200a2002290338370200200a41086a200d290300370200200a41106a200f290300370200200a41186a200c290300370200200a41206a200b2903003702002002200e36029001200241e0006a200910e502200241c0016a20022802602210200228026810cc02200241c0016a41086a220e290300211120022802d001210f20022903c001211220022802d401211302402002280264450d00201010350b20114200200f1b211420124200200f1b21120240200f450d00201341ffffff3f71450d00200f4101200f1b10350b200241c0016a41186a220f420037030020014200370300200e4200370300200242003703c00141b6fdc600ad4280808080800184100122132900002111200e201341086a290000370300200220113703c0012013103541e489c200ad4280808080d00184100122132900002111200241f0016a41086a2210201341086a290000370300200220113703f00120131035200120022903f001370000200141086a2010290300370000200241e0006a41086a2213200e290300370300200241e0006a41106a22102001290300370300200241e0006a41186a2215200f290300370300200220022903c001370360200241206a200241e0006a412010d701200241106a2002290328200241206a41106a290300427f420010980820022012201420022903104200200228022022161b221142012011420156200241106a41086a290300420020161b22114200522011501b22161b2011420020161b109808200241c0016a41286a20024190016a41286a280200360200200241c0016a41206a20024190016a41206a290300370300200f20024190016a41186a290300370300200120024190016a41106a290300370300200e20024190016a41086a29030037030020022002290390013703c001200241e0006a200241c0016a2002290300420010cb01200041286a200241e0006a41286a280200360200200041206a200241e0006a41206a290300370200200041186a2015290300370200200041106a2010290300370200200041086a201329030037020020002002290360370200200341016a21032000412c6a21002007412c6a22072008470d000b200821070c010b2007412c6a21070b20042003360200200820076b2200412c6d210102402000450d002001412c6c210003400240200741046a2802002201450d00200141246c450d00200728020010350b2007412c6a2107200041546a22000d000b0b02402005450d002005412c6c450d00200610350b20024180026a24000bd907010f7f230041c0006b22052400200541003602082005420137030020054100360218200542013703102003410020041b21062001410020021b2107200341206a200320041b2108200141206a200120021b2109200120024105746a210a200320044105746a210b4101210c4100210d4101210e4101210f410021100340200e211120102102200821032006210102400340024020010d004100210620070d02200020052903003702002000200529031037020c200041086a200541086a280200360200200041146a200541106a41086a280200360200200541c0006a24000f0b024020070d00200541206a41186a2203200641186a290000370300200541206a41106a2202200641106a290000370300200541206a41086a2207200641086a29000037030020052006290000370320024020102005280214470d00200541106a20104101108a012005280210210e200528021821100b200e20104105746a22012005290320370000200141186a2003290300370000200141106a2002290300370000200141086a20072903003700002005201041016a221036021841002107410020082008200b4622011b2106200e210f2008200841206a20011b21080c030b0240024020012007460d0020012007412010a00822040d010b2003200341206a2003200b4622011b2108410020092009200a4622041b21074100200320011b21062011210e200221102009200941206a20041b21090c030b02402004417f4c0d00200121060c020b200541206a41186a2204200141186a290000370300200541206a41106a2212200141106a290000370300200541206a41086a2213200141086a29000037030020052001290000370320024020022005280214470d00200541106a20024101108a012005280218210220052802102211210f0b200f20024105746a22012005290320370000200141186a2004290300370000200141106a2012290300370000200141086a20132903003700002005200241016a2202360218410020032003200b4622041b21012003200341206a20041b21030c000b0b200541206a41186a2204200741186a290000370300200541206a41106a2212200741106a290000370300200541206a41086a2213200741086a290000370300200520072900003703200240200d2005280204470d002005200d4101108a012005280200210c2005280208210d0b200c200d4105746a22012005290320370000200141186a2004290300370000200141106a2012290300370000200141086a20132903003700002005200d41016a220d360208410020092009200a4622011b21072011210e200221102009200941206a20011b2109200321080c000b0be80f06087f017e047f017e057f077e230022042105200441a0016b41607122042400024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610332207450d020b41002108200441003602282004200736022020042006410576360224200441206a41002001108a012004280228210902402001450d002001410574210a200428022020094105746a210b0340200b20086a2206200020086a2207290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200a200841206a2208470d000b200141057441606a41057620096a41016a21090b200441086a200936020020042004290320220c370300200ca72009410041202009676b10c105200441206a41186a22014200370300200441206a41106a220d4200370300200441206a41086a220e42003703002004420037032041dad5ca00ad4280808080b0028410012208290000210c200e200841086a2900003703002004200c370320200810354180eaca00ad428080808090018410012208290000210c200441e8006a41086a220f200841086a2900003703002004200c37036820081035200d2004290368220c37030020044180016a41086a200e29030037030020044180016a41106a200c37030020044180016a41186a200f2903003703002004200429032037038001200441206a20044180016a412010b50220042802202208410120081b21102004290224420020081b2211422088a72208450d022008410574210920044180016a410c722112200441206a410c6a2100200441206a4114722113200441206a41087221142010210803402001200841186a290000370300200d200841106a290000370300200e200841086a29000037030020042008290000370320200441106a200441206a108c07200441206a2004280210220b2004280218221510de02200f200041086a290200370300200441e8006a41106a220a200041106a2802003602002004200029020037036820042802402106024020042802282207450d002004290320210c20122004290368370200201241086a200f290300370200201241106a200a2802003602002004200c37038001200621160b200420073602880120044100360228200429039801211720042004290338221837039801200429039001211920042004290330221a37039001200429038001211b20042004290320221c37038001200429038801210c20042004290328221d37038801201da7210702400240200ca7220a0d00201d210c201a211920182117201621060c010b2004201b3703202004200c37032820042019370330200420173703382004200a2019a74105746a3602742004200a3602702004200c422088a736026c2004200a36026820042004360278200441d8006a200441e8006a10ca05201441086a200441d8006a41086a22162802003602002014200429035837020020042019422088a7220a2017422088a74105746a3602742004200a36027020042017a736026c2004200a36026820042004360278200441d8006a200441e8006a10ca05201341086a2016280200360200201320042903583702002004290328210c2004290320211c200429033821172004290330211902402007450d002018a7210a0240201d422088a741ffffff3f71450d00200710350b200a41ffffff3f71450d00201a422088a710350b2004201c370380012004200c3703880120042019370390012004201737039801200ca721070b2004200c37032820042019370330200120173703002004201c37032020042006360240200ca7210a0240024020070d002015ad422086200bad8410070c010b2004201536026c2004200b360268200441206a200441e8006a108b070b0240200a450d002017a721070240200c422088a741ffffff3f71450d00200a10350b200741ffffff3f71450d002019422088a710350b02402004280214450d00200b10350b200841206a210820062116200941606a22090d000c030b0b1044000b1045000b0240201142ffffff3f83500d00201010350b200441206a41186a220a4200370300200441206a41106a22074200370300200441206a41086a220642003703002004420037032041dad5ca00ad4280808080b00284220c10012200290000211c200441e8006a41086a2208200041086a2900003703002004201c3703682000103520062008290300370300200420042903683703204189eaca00ad4280808080f0008410012200290000211c2008200041086a2900003703002004201c3703682000103520072004290368221c37030020044180016a41086a220b200629030037030020044180016a41106a2201201c37030020044180016a41186a22092008290300370300200420042903203703800120044120360224200420044180016a36022020022003200441206a10a806200a4200370300200742003703002006420037030020044200370320200c10012200290000210c2008200041086a2900003703002004200c370368200010352006200829030037030020042004290368370320419cdfca00ad4280808080d0008410012200290000210c2008200041086a2900003703002004200c3703682000103520072004290368220c370300200b20062903003703002001200c37030020092008290300370300200420042903203703800120044180016aad428080808080048410070240200428020441ffffff3f71450d00200428020010350b200524000b9d0f07037f027e027f0a7e037f067e047f230041d0036b2204240020032802002105200441206a2001108e02200441a0016a2004280220220320042802282206108f0220042903a001210742002108200442003703a001200441e8016a280200210920042d00ec01210a0240024020074201510d00200441306a41306a4200370300200441306a41286a4200370300200441306a41206a4200370300200441306a41186a4200370300200441c0006a4200370300200441386a4200370300200442003703304200210b4200210c4200210d4200210e0c010b200441d8016a290300210f200441a0016a41306a2903002110200441a0016a41206a290300210b200441a0016a41186a2903002108200441e0016a290300210e20042903b001210d20042903a801210c200441306a41206a200441a0016a41286a290300370300200441306a41286a2010370300200441306a41306a200f370300200441c0006a20083703002004200b3703482004200c3703302004200d3703380b200441306a41186a200b200241086a2903002210200b20082002290300221156200b201056200b2010511b22021b22127d20082011200820021b220f54ad7d221337030020042008200f7d2214370340200441e8006a41186a2013370300200441e8006a41206a2215200441306a41206a290300370300200441e8006a41286a2216200441306a41286a290300370300200441e8006a41306a2217200441306a41306a290300370300200420143703782004200c3703682004200d370370427f200d200b7c200c20087c220b200c542202ad7c220820022008200d542008200d511b22021b2118427f200b20021b211902400240427f200c20147c22082008200c542202200d20137c2002ad7c2208200d542008200d511b22021b220b428080e983b1de16544100427f200820021b2213501b0d00200441f8006a290300210b20172903002113201629030021142015290300211a2004290370211b2004290368211c42012108200429038001211d0c010b02400240200b20138450450d00420021080c010b42002108200441a0026a41186a221e4200370300200441a0026a41106a22164200370300200441a0026a41086a22154200370300200442003703a00241b6fdc600ad4280808080800184221410012217290000211a200441c0036a41086a2202201741086a2900003703002004201a3703c0032017103520152002290300370300200420042903c0033703a00241e489c200ad4280808080d00184221a10012217290000211b2002201741086a2900003703002004201b3703c00320171035201620042903c003221b370300200441a0036a41086a221f2015290300370300200441a0036a41106a2220201b370300200441a0036a41186a22212002290300370300200420042903a0023703a003200441086a200441a0036a412010d701200441086a41106a290300211b2004290310211c20042802082117201e42003703002016420037030020154200370300200442003703a00220141001221e29000021142002201e41086a290000370300200420143703c003201e103520152002290300370300200420042903c0033703a002201a1001221e29000021142002201e41086a290000370300200420143703c003201e1035201620042903c0032214370300201f20152903003703002020201437030020212002290300370300200420042903a0023703a00320044200201b420020171b221420137d201c420020171b221a200b54ad7d221b201a200b7d221c201a56201b201456201b2014511b22021b3703a80220044200201c20021b3703a002200441a0036aad4280808080800484200441a0026aad42808080808002841002200441d8026a2013370300200441d0026a200b370300201541013a0000200441a9026a2005290000370000200441b1026a200541086a290000370000200441b9026a200541106a290000370000200441c1026a200541186a290000370000200441033a00a00241b0b4cc004100200441a0026a10d4010b0b2011200f54210220192018842118200441c8016a201a370300200441d0016a2014370300200441b0016a201b370300200441d8016a2013370300200441b8016a200b3703002004201d3703c0012004200e3703e0012004201c3703a8012004200a4100200742015122051b3a00ec0120042009410020051b3602e801200420084201512205ad3703a0010240024020050d002006ad4220862003ad8410070c010b200420063602a402200420033602a002200441a8016a200441a0026a10e7020b201020127d210b2002ad2110201850210202402004280224450d00200310350b200b20107d210b2002ad21102011200f7d21112008420152210202400240024020074201510d0020020d0041032103200441a0026a21020c010b20074201522002410173720d0141042103200441a0016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b2000200f3703182000200c37030820002010370300200041306a200b370300200041286a2011370300200041206a2012370300200041106a200d370300200441d0036a24000bac0402067f027e230041106b220324000240024002400240200141306c4104722204417f4c0d00200410332205450d012003410036020820032004360204200320053602002001200310770240024020010d002003280208210120032802042105200328020021060c010b2000200141306c6a2107200328020021062003280204210520032802082101034002400240200520016b4120490d00200141206a2104200521080c010b200141206a22042001490d05200541017422082004200820044b1b22084100480d05024020050d00024020080d00410121060c020b2008103322060d010c070b20052008460d0020062005200810372206450d060b200620016a22012000290000370000200141186a200041186a290000370000200141106a200041106a290000370000200141086a200041086a290000370000200041286a2903002109200041206a290300210a02400240200820046b4110490d00200441106a2101200821050c010b200441106a22012004490d05200841017422052001200520014b1b22054100480d05024020080d00024020050d00410121060c020b200510332206450d070c010b20082005460d0020062008200510372206450d060b200620046a220420093700082004200a3700002007200041306a2200470d000b2003200536020420032001360208200320063602000b20022902002001ad4220862006ad84100202402005450d00200610350b200341106a24000f0b1044000b1045000b103e000b103c000bcf0504037f017e087f047e23004180016b220224002002200110c40102400240024002402002280200450d00200041003602000c010b20022802042203200128020441306e2204200420034b1bad42307e2205422088a70d012005a72204417f4c0d010240024020040d00410821060c010b200410332206450d030b4100210720024100360210200220063602082002200441306e36020c0240024002402003450d0041002108034041002104200241003a0078200841016a210820012802042109417f210a034020092004460d03200241d8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0078200a417f6a210a200c2104200c4120470d000b200241386a41186a2204200241d8006a41186a290300370300200241386a41106a220a200241d8006a41106a290300370300200241386a41086a220d200241d8006a41086a290300370300200220022903583703382009200c6b220c4110490d03200b41096a2900002105200b290001210e2001200c41706a3602042001200b41116a360200200241186a41086a220c200d290300370300200241186a41106a2209200a290300370300200241186a41186a220a20042903003703002002200229033837031802402007200228020c470d00200241086a2007410110880120022802082106200228021021070b2006200741306c6a22042002290318370300200c290300210f20092903002110200a29030021112004200e370320200441286a2005370300200441186a2011370300200441106a2010370300200441086a200f3703002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c020b200441ff0171450d00200241003a00780b20004100360200200228020c2204450d00200441306c450d00200610350b20024180016a24000f0b1044000b1045000bcaf80102517f0d7e230041d0106b2201240020014100360210200141003602080240024002400240024002400240200041086a22022802002203450d00200141f8076a4102722104200141fd026a2105200141d0026a41206a2106200141386a41206a2107200141f8076a41206a2108200141186a41186a2109200141186a41106a210a4100210b034002402002280200220c200b4b0d00200b200c41e099c2001042000b20092000280200200b412c6c220d6a220e41246a290000370300200a200e411c6a290000370300200141186a41086a220f200e41146a2900003703002001200e29000c370318200e280200210c200e280208210e2001410036028008200142013703f807200141f8076a4100200e108a01200128028008211002400240200e41306c22110d0020012802f80721120c010b20012802f807221220104105746a210e0340200e200c290000370000200e41186a200c41186a290000370000200e41106a200c41106a290000370000200e41086a200c41086a290000370000201041016a2110200e41206a210e200c41306a210c201141506a22110d000b0b20012802fc072113024020104102490d00024002402010417f6a221420106c410176220c41ffffff1f71200c470d00200c410674220c417f4c0d00024002400240200c0d00410121150c010b200c10332215450d010b201241206a2116200c4106762117410021184100210c03400240200c41016a221920104f0d002012200c4105746a21112014211a2016210e0340200141f8076a41086a221b201141086a290000370300200141f8076a41106a221c201141106a290000370300200141f8076a41186a221d201141186a290000370300200120112900003703f8072008200e290000370000200841086a200e41086a290000370000200841106a200e41106a290000370000200841186a200e41186a290000370000024020182017470d00024002400240201741016a220c2017490d002017410174221e200c201e200c4b1b220c41ffffff1f71200c470d00200c410674220c4100480d00024020170d00200c0d02410121150c030b20174106742217200c460d02024020170d00200c0d02410121150c030b20152017200c10372215450d120c020b103e000b200c10332215450d100b200c41067621170b201520184106746a220c20012903f807370000200c41386a200141f8076a41386a290300370000200c41306a200141f8076a41306a290300370000200c41286a200141f8076a41286a290300370000200c41206a2008290300370000200c41186a201d290300370000200c41106a201c290300370000200c41086a201b290300370000200e41206a210e201841016a2118201a417f6a221a0d000b0b2014417f6a2114201641206a21162019210c20192010470d000b2018450d02201520184106746a211f2015211e02400340200141386a41386a201e41386a290000370300200141386a41306a201e41306a290000370300200141386a41286a201e41286a2900003703002007201e41206a290000370300200141386a41186a201e41186a220c290000370300200141386a41106a201e41106a220e290000370300200141386a41086a201e41086a22112900003703002001201e290000370338200141f8006a41186a2218200c290000370300200141f8006a41106a220c200e290000370300200141f8006a41086a220e20112900003703002001201e29000037037820014198016a41186a200741186a221129000037030020014198016a41106a200741106a221a29000037030020014198016a41086a200741086a221b2900003703002001200729000037039801200141d0026a41186a22202018290300370300200141d0026a41106a2221200c290300370300200141d0026a41086a2222200e29030037030020062007290000370000200641086a201b290000370000200641106a201a290000370000200641186a2011290000370000200120012903783703d002024002402001280208221b450d00200128020c211c0c010b200141f8076a410041c005109f081a200141e8046a410041e002109f081a41a8081033221b450d0e4100211c201b41003b0106201b4100360200201b41086a200141f8076a41c005109d081a201b41c8056a200141e8046a41e002109d081a2001410036020c2001201b3602080b201e41c0006a211e024002400240024002400240024002400240024002400240024003400240201b2f0106221a410674220e450d00201b41286a210c41002111034002400240200141d0026a200c41606a412010a0082218450d00201841004e0d012011211a0c030b2006200c412010a0082218450d04201841004e0d002011211a0c020b201141016a2111200c41c0006a210c200e41406a220e0d000b0b201c450d02201c417f6a211c201b201a4102746a41a8086a280200211b0c000b0b20022802002219200b4d0d032000280200221d200d6a220c28020841306c221a450d0a201b201141057422236a41c8056a2110200c280200210c4100211803404101210e0240200141f8006a200c460d00200c200141f8006a412010a008450d00024020014198016a200c470d004101210e0c010b200c20014198016a412010a00845210e0b200c41306a210c200e20186a2118201a41506a221a0d000b20184102470d0a2019412c6c210e0340201d210c200e450d0b0240200c410c6a22182010460d00200e41546a210e200c412c6a211d20182010412010a0080d010b0b0240200c41086a280200220e450d00200e41306c211a200141f8006a200c28020022186b211d20014198016a20186b21194100210c0340201d200c460d032018200c6a220e200141f8006a412010a008450d032019200c460d03200e20014198016a412010a008450d03201a200c41306a220c470d000b0b41082124410021250c070b200141b8016a41386a220c200141d0026a41386a290300370300200141b8016a41306a220e200141d0026a41306a290300370300200141b8016a41286a2211200141d0026a41286a290300370300200141b8016a41206a22182006290300370300200141b8016a41186a221c2020290300370300200141b8016a41106a221d2021290300370300200141b8016a41086a22102022290300370300200120012903d0023703b8012001200128021041016a360210200141a0036a41386a2226200c290300370300200141a0036a41306a2227200e290300370300200141a0036a41286a22282011290300370300200141a0036a41206a22242018290300370300200141a0036a41186a2223201c290300370300200141a0036a41106a2225201d290300370300200141a0036a41086a22292010290300370300200120012903b8013703a003200141d0076a41186a222a2009290300370300200141d0076a41106a222b200a290300370300200141d0076a41086a222c200f290300370300200120012903183703d0070240201b2f0106220e410b490d00200141f8076a410041c005109f081a200141e8046a410041e002109f081a41a8081033220c450d19200c41003b0106200c4100360200200c41086a200141f8076a41c005109d08210e200c41c8056a200141e8046a41e002109d082118200141f8076a41086a2210201b41a3036a290000370300200141f8076a41106a2219201b41ab036a290000370300200141f8076a41186a2214201b41b3036a2900003703002008201b41bb036a290000370300200141f8076a41256a2216201b41c0036a2900003700002001201b4188036a2f00003b0188042001201b418a036a2d00003a008a042001201b419b036a2900003703f807201b418b036a280000212d201b418f036a280000212e201b4193036a280000212f201b4197036a2800002130200141c8046a41186a2231201b41a0076a290000370300200141c8046a41106a2232201b4198076a290000370300200141c8046a41086a2233201b4190076a2900003703002001201b290088073703c804200e201b41c8036a201b2f010641796a2211410674109d08210e2018201b41a8076a2011410574109d082118201b41063b0106200c20113b0106200141e0036a41026a221c20012d008a043a0000200141e8046a41086a22342010290300370300200141e8046a41106a22352019290300370300200141e8046a41186a22362014290300370300200141e8046a41206a22372008290300370300200141e8046a41256a22382016290000370000200120012f0188043b01e003200120012903f8073703e804200141a8046a41186a22392031290300370300200141a8046a41106a223a2032290300370300200141a8046a41086a223b2033290300370300200120012903c8043703a80402400240201a4107490d00200e201a417a6a221d4106746a200e201a41796a221a4106746a220e201141ffff0371201a6b410674109e081a200e41386a2026290300370000200e41306a2027290300370000200e41286a2028290300370000200e41206a2024290300370000200e41186a2023290300370000200e41106a2025290300370000200e41086a2029290300370000200e20012903a0033700002018201d4105746a2018201a4105746a220e200c2f0106201a6b410574109e081a200e41186a202a290300370000200e41106a202b290300370000200e41086a202c290300370000200e20012903d007370000200c200c2f010641016a3b01060c010b201b41086a220e201a41016a22114106746a200e201a4106746a220e201b2f0106201a6b410674109e081a200e41386a2026290300370000200e41306a2027290300370000200e41286a2028290300370000200e41206a2024290300370000200e41186a2023290300370000200e41106a2025290300370000200e41086a2029290300370000200e20012903a003370000201b41c8056a220e20114105746a200e201a4105746a220e201b2f0106201a6b410574109e081a200e41186a202a290300370000200e41106a202b290300370000200e41086a202c290300370000200e20012903d007370000201b201b2f010641016a3b01060b200520012903a804370000200141f4076a41026a220e201c2d00003a000020222034290300370300202120352903003703002020203629030037030020062037290300370300200141d0026a41256a22282038290000370000200541086a2211203b290300370000200541106a2218203a290300370000200541186a221a2039290300370000200120012f01e0033b01f407200120012903e8043703d002200141cc026a41026a223c200e2d00003a000020014198026a41086a223d202229030037030020014198026a41106a223e202129030037030020014198026a41186a223f202029030037030020014198026a41206a2240200629030037030020014198026a41256a22412028290000370000200120012f01f4073b01cc02200120012903d00237039802200141f8016a41186a2242201a290000370300200141f8016a41106a22432018290000370300200141f8016a41086a22442011290000370300200120052900003703f8010240201b28020022180d004100211d200141086a210e200c21110c0a0b201b2f0104212641002145200c2146034020014184046a41026a2247203c2d00003a00002022203d2903003703002021203e2903003703002020203f2903003703002006204029030037030020282041290000370000200120012f01cc023b01840420012001290398023703d00220014188046a41186a2248204229030037030020014188046a41106a2249204329030037030020014188046a41086a224a2044290300370300200120012903f8013703880441000d03202641ffff0371211c02400240024020182f0106220c410b490d002004410041d208109f081a41d8081033221a450d1d201a4100360200201a41046a200141f8076a41d408109d081a200141d0076a41026a224b2018418a036a2d00003a00002010201841a3036a2900003703002019201841ab036a2900003703002014201841b3036a2900003703002008201841bb036a2900003703002016201841c0036a290000370000200120184188036a2f00003b01d00720012018419b036a2900003703f8072018418b036a280000214c2018418f036a280000214d20184193036a280000214e20184197036a280000214f2031201841a0076a290000370300203220184198076a290000370300203320184190076a29000037030020012018290088073703c804201a41086a201841c8036a20182f0106220e41796a220c410674109d082150201a41c8056a201841a8076a200c410574109d082151201a41a8086a201841c4086a200e417a6a221d410274109d082127201841063b0106201a200c3b01060240201d450d004100210c2027210e0340200e2802002211200c3b01042011201a360200200e41046a210e201d200c41016a220c470d000b0b2034201029030037030020352019290300370300203620142903003703002037200829030037030020382016290000370000203b2033290300370300203a203229030037030020392031290300370300200120012f01d0073b01f407200120012903f8073703e804200120012903c8043703a8042001204b2d00003a00f607200141cc076a41026a221d20012d00f6073a00002010203429030037030020192035290300370300201420362903003703002008203729030037030020162038290000370000200120012f01f4073b01cc07200120012903e8043703f807202a2039290300370300202b203a290300370300202c203b290300370300200120012903a8043703d007202641ffff037122264107490d012050201c417a6a22114106746a2050201c41796a220c4106746a220e201a2f0106200c6b410674109e081a200e203036000f200e202f36000b200e202e360007200e202d360003200e41026a20472d00003a0000200e20012f0184043b0000200e20012903d002370013200e411b6a2022290300370000200e41236a2021290300370000200e412b6a2020290300370000200e41336a2006290300370000200e41386a2028290000370000205120114105746a2051200c4105746a220e201a2f01062226200c6b410574109e081a200e41186a2048290300370000200e41106a2049290300370000200e41086a204a290300370000200e200129038804370000201a202641016a220e3b0106201c410274222620276a416c6a202720114102746a221c200e41ffff037120116b410274109e081a201c20463602002011201a2f0106221c4b0d02201a20266a4190086a210e0340200e2802002211200c41016a220c3b01042011201a360200200e41046a210e200c201c490d000c030b0b201841086a220e201c41016a22114106746a200e201c4106746a220e200c201c6b410674109e081a200e203036000f200e202f36000b200e202e360007200e202d360003200e41026a20472d00003a0000200e20012f0184043b0000200e20012903d002370013200e411b6a2022290300370000200e41236a2021290300370000200e412b6a2020290300370000200e41336a2006290300370000200e41386a2028290000370000201841c8056a220c20114105746a200c201c4105746a220c20182f0106220e201c6b410574109e081a200c41186a2048290300370000200c41106a2049290300370000200c41086a204a290300370000200c2001290388043700002018200e41016a220c3b0106201c410274201841a8086a220e6a41086a200e20114102746a220e200c41ffff037120116b410274109e081a200e20463602000240201c20182f0106221a4f0d0020182011417f6a220c4102746a41ac086a210e0340200e2802002211200c41016a220c3b010420112018360200200e41046a210e200c201a490d000b0b41001a200141086a1a201b1a0c0d0b201841086a220c201c41016a220e4106746a200c201c4106746a220c20182f0106201c6b410674109e081a200c203036000f200c202f36000b200c202e360007200c202d360003200c41026a20472d00003a0000200c20012f0184043b0000200c20012903d002370013200c411b6a2022290300370000200c41236a2021290300370000200c412b6a2020290300370000200c41336a2006290300370000200c41386a2028290000370000201841c8056a220c200e4105746a200c201c4105746a220c20182f01062211201c6b410574109e081a200c41186a2048290300370000200c41106a2049290300370000200c41086a204a290300370000200c2001290388043700002018201141016a220c3b0106201c4102742227201841a8086a22116a41086a2011200e4102746a2211200c41ffff0371200e6b410274109e081a20112046360200202620182f010622114f0d00201820276a41ac086a210c0340200c280200220e201c41016a221c3b0104200e2018360200200c41046a210c2011201c470d000b0b204541016a210c20014180046a41026a220e201d2d00003a000020292010290300370300202520192903003703002023201429030037030020242008290300370300200141a0036a41256a22112016290000370000200141e0036a41086a221c202c290300370300200141e0036a41106a221d202b290300370300200141e0036a41186a2226202a290300370300200120012f01cc073b018004200120012903f8073703a003200120012903d0073703e003203c200e2d00003a0000203d2029290300370300203e2025290300370300203f20232903003703002040202429030037030020412011290000370000200120012f0180043b01cc02200120012903a00337039802204220262903003703002043201d2903003703002044201c290300370300200120012903e0033703f80102402018280200220e0d00204c212d200141086a220e1a20181a204f2130204e212f204d212e200c211d201a21110c0b0b20182f01042126200141086a1a204c212d20181a204f2130204e212f204d212e200e2118201a2146200c21450c000b0b201b41086a220c201a41016a22114106746a200c201a4106746a220c200e201a6b410674109e081a200c41386a2026290300370000200c41306a2027290300370000200c41286a2028290300370000200c41206a2024290300370000200c41186a2023290300370000200c41106a2025290300370000200c41086a2029290300370000200c20012903a003370000201b41c8056a220c20114105746a200c201a4105746a220c201b2f0106201a6b410574109e081a200c41186a202a290300370000200c41106a202b290300370000200c41086a202c290300370000200c20012903d007370000201b201b2f010641016a3b01060c090b200141f8076a41086a22292018200c6a220e41086a290300370300200141f8076a41106a222a200e41106a290300370300200141f8076a41186a222b200e41186a2903003703002001200e2903003703f807200e41286a2903002152200e41206a2903002153413010332224450d0c20242053370320202420012903f807370300202441286a2052370300202441186a202b290300370300202441106a202a290300370300202441086a202929030037030020014281808080103702ec04200120243602e8040240201a41506a200c470d0020012802ec0421250c060b200e41306a211d2018201a6a220e41506a21204101211a0340201d210c024002400340200141f8006a200c460d01200c200141f8006a412010a008450d0120014198016a200c460d01200c20014198016a412010a008450d01200e200c41306a220c470d000c020b0b200c41286a2903002152200c41206a2903002153200141c8046a41186a2219200c41186a290300370300200141c8046a41106a2214200c41106a290300370300200141c8046a41086a2216200c41086a2903003703002001200c2903003703c8040240201a20012802ec04470d00200141e8046a201a410110880120012802e80421240b200c41306a211d2024201a41306c6a221820012903c80437030020162903002154201429030021552019290300215620182053370320201841286a2052370300201841186a2056370300201841106a2055370300201841086a20543703002001201a41016a221a3602f0042020200c470d010b0b20012802ec042125201a4102490d05201a4102470d0441e0001033221d450d0c2001420237029c022001201d3602980202402002280200220c200b4d0d000240024002402000280200200d6a220c28020841306c221a0d004102210c0c010b200c280200210c41002118034002400240200141f8006a200c460d00200c200141f8006a412010a008210e20014198016a200c460d00200e450d00200c20014198016a412010a0080d010b200141f8016a41186a2219200c41186a290300370300200141f8016a41106a2214200c41106a290300370300200141f8016a41086a2216200c41086a2903003703002001200c2903003703f801200c41286a2903002152200c41206a290300215302402018200128029c02470d0020014198026a20184101108801200128029802211d20012802a00221180b201d201841306c6a220e20012903f801370300201629030021542014290300215520192903002156200e2053370320200e41286a2052370300200e41186a2056370300200e41106a2055370300200e41086a20543703002001201841016a22183602a0020b200c41306a210c201a41506a221a0d000b20184102460d01200128029c02210c0b200c450d08200c41306c450d08201d10350c080b0240201d2024460d002024201d412010a008450d00200141f8076a41286a220c202441286a220e2903003703002008202441206a2218290300370300202b202441186a221a290300370300202a202441106a22192903003703002029202441086a2214290300370300200120242903003703f807200e202441d8006a22162903003703002018202441d0006a220e290300370300201a202441c8006a22182903003703002019202441c0006a221a2903003703002014202441386a2219290300370300202420242903303703002016200c290300370300200e20082903003703002018202b290300370300201a202a29030037030020192029290300370300202420012903f8073703300b2001427f3703f0042001427f3703e8044100211a200141003602d0072001410036028008200142083703f807200141f8076a4100410410880120012802f8072235200128028008221641306c6a210c0240201d450d00200141e8046a41086a290300215420012903e8042157410021194100211a03400240201d20196a220e41206a2903002253205756200e41286a290300225220545620522054511b0d00200120533703e8042001201a3602d007200120523703f00420532157205221540b200c20196a2218200e290300370300200e41086a2903002155200e41106a2903002156200e41186a2903002158201841286a2052370300201841206a2053370300201841186a2058370300201841106a2056370300201841086a2055370300201a41016a211a201941306a221941e000470d000b2016201a6a2116200c20196a210c0b02402024450d00202441e0006a221d2024460d00200141e8046a41086a290300215420012903e80421572024210e0340200e41306a21180240200e41206a2903002253205756200e41286a290300225220545620522054511b0d00200120533703e8042001201a3602d007200120523703f00420532157205221540b200c200e290300370300200e41086a2903002155200e41106a2903002156200e41186a2903002158200c41286a2052370300200c41206a2053370300200c41186a2058370300200c41106a2056370300200c41086a2055370300200c41306a210c201a41016a211a201641016a21162018210e201d2018470d000b0b20012802fc072131200141003602c001200142043703b801200141003602a803200142043703a00320012802d007210c200141a0036a4100410110860120012802a003222820012802a803220e4102746a200c3602002001200e41016a220c3602a80302400240024020012802d00722184102490d00200141b8016a4100410110860120012802b80120012802c001220e4102746a201841017141037322183602002001200e41016a220e3602c0012018417e6a21180240200c20012802a403470d00200141a0036a200c410110860120012802a003212820012802a803210c0b2028200c4102746a20183602002001200c41016a22343602a80320012802d007417e6a210c200e20012802bc01470d02200141b8016a200e41011086010c010b200141b8016a4100410110860120012802b80120012802c001220e4102746a410120186b3602002001200e41016a220e3602c001410320186b21180240200c20012802a403470d00200141a0036a200c410110860120012802a003212820012802a803210c0b2028200c4102746a20183602002001200c41016a22343602a80320012802d00741026a210c200e20012802bc01470d01200141b8016a200e41011086010b20012802c001210e0b20012802b8012227200e4102746a200c3602002001200e41016a220c3602c00141041033222c450d0d200142013702d4022001202c3602d00220012802bc0121360240200c450d002027200c4102746a212620272122034002400240202228020022214102490d00202b201041186a290000370300202a201041106a2900003703002029201041086a290000370300200120102900003703f8070c010b202b2009290300370300202a200a2903003703002029200f290300370300200120012903183703f8070b02402002280200220c450d0020002802002219200c412c6c6a21142035202141306c6a211a034002400240200141f8076a2019410c6a220c460d00200c200141f8076a412010a0080d010b2019280208210c0240201620214d0d00200c41306c210e4100211820192802002220210c02400340200e450d03201a200c460d01200c201a412010a008211d201841016a2118200e41506a210e200c41306a210c201d0d000b201d4541016a41017120186a417f6a21180b2020201841306c6a220c427f200c290320225220012903e8047c22532053205254220e200c41286a220c2903002252200141e8046a41086a2903007c200ead7c225320525420532052511b220e1b370320200c427f2053200e1b3703000c010b200c450d002021201641909ac2001042000b2019412c6a22192014470d000b0b202241046a22222026470d000b0b0240203641ffffffff0371450d00202710350b20012802a40321320240024020340d00410021270c010b202820344102746a21364100212720282134034002400240203428020022224102490d00202b201041186a290000370300202a201041106a2900003703002029201041086a290000370300200120102900003703f8070c010b202b2009290300370300202a200a2903003703002029200f290300370300200120012903183703f8070b02402002280200220c450d0020002802002219200c412c6c6a21202035202241306c6a211a034002400240200141f8076a2019410c6a220c460d00200c200141f8076a412010a0080d010b201941086a2226280200211402400240201620224d0d00201441306c210e4100211820192802002221210c02400340200e450d04201a200c460d01200c201a412010a008211d201841016a2118200e41506a210e200c41306a210c201d0d000b201d4541016a41017120186a417f6a21180b42002021201841306c6a220c290320225220012903e80422547d22532053205256200c41286a2903002253200141e8046a41086a2903007d2052205454ad7d225220535620522053511b220e1b225342002052200e1b225284500d01200c41206a220c2053370300200c20523703080c020b2014450d012022201641a09ac2001042000b200c200c41306a20142018417f736a41306c109e081a20262014417f6a3602000240202720012802d402470d00200141d0026a2027410110860120012802d80221270b20012802d002222c20274102746a20223602002001202741016a22273602d8020b2019412c6a22192020470d000b0b203441046a22342036470d000b0b0240203241ffffffff0371450d00202810350b202c417c6a21182027410274220c210e024003400240200e0d00410021180c020b200e417c6a210e201841046a221828020041014b0d000b0b20012802d402211d202c210e024003400240200c0d004100210c0c020b200c417c6a210c200e280200211a200e41046a210e201a4102490d000b4101210c0b0240201d41ffffffff0371450d00202c10350b0240024020180d00200c450d0120102001290318370000201041186a2009290300370000201041106a200a290300370000201041086a200f2903003700000c060b200c450d0520012001280210417f6a360210201b41086a210c02400240201c450d00201c417f6a210e200c20114106746a2118201b20114102746a41a8086a280200210c02400340200c2f01062111200e450d01200e417f6a210e200c20114102746a41a8086a280200210c0c000b0b200c410020111b221b41086a220e2011417f6a410020111b22114106746a220c2900002152200c2900082153200c2900102154200c41186a2900002155200c2900202156200c41286a2900002158200c41306a2900002157200c41386a290000215941012137200c200e201141016a221a4106746a2011417f73220e201b2f01066a410674109e081a201b41c8056a221c20114105746a220c290000215a200c290008215b200c290010215c200c41186a290000215d200c201c201a4105746a200e201b2f01066a410574109e081a201b201b2f0106417f6a3b0106201841386a2059370000201841306a2057370000201841286a205837000020182056370020201841186a2055370000201820543700102018205337000820182052370000201041186a205d3700002010205c3700102010205b3700082010205a370000201b2f0106210c0c010b200c20114106746a200c201141016a220e4106746a2011417f73220c201b2f01066a410674109e081a201b41c8056a221820236a2018200e4105746a200c201b2f01066a410574109e081a201b201b2f0106417f6a220c3b0106410021370b200c41ffff037141044b0d0441002122200141086a210e201b210c410021200240024002400240024002400240024002400240024002400240024002400340200c280200221a450d1402400240200c33010422524200520d0041002121201a4100201a2f0106220c1b211a42002052422086200c1b200ead8421520c010b2052422086200ead844280808080707c2152410121210b02400240201a41a8086a220e2052422088a7221841016a220c41027422276a221c28020022192f01062210200e201841027422236a2226280200221d2f010622146a2233410b490d0020210d052010450d01201941c0006a2900002152201941386a2900002153201941306a2900002154201941286a2900002155201941206a2900002156201941186a2900002158201941106a290000215720192900082159201941086a201941c8006a201041067441406a109e081a201941e0056a290000215a201941d8056a290000215b201941d0056a290000215c20192900c805215d201941c8056a201941e8056a201041057441606a109e081a20200d034100211d0c040b202041016a2120201a2f01062116200141f8076a41386a222c201a41086a223420184106746a220e41386a290000370300200141f8076a41306a2236200e41306a290000370300200141f8076a41286a2228200e41286a2900003703002008200e41206a290000370300202b200e41186a290000370300202a200e41106a2900003703002029200e41086a2900003703002001200e2900003703f807200e2034200c4106746a20162018417f7322346a410674109e081a201d41086a223220144106746a220e41386a202c290300370000200e41306a2036290300370000200e41286a2028290300370000200e41206a2008290300370000200e41186a202b290300370000200e41106a202a290300370000200e41086a2029290300370000200e20012903f8073700002032201441016a22164106746a201941086a2010410674109d081a201a2f0106212c200141c8046a41186a2236201a41c8056a222820184105746a220e41186a290000370300200141c8046a41106a2218200e41106a290000370300200141c8046a41086a2232200e41086a2900003703002001200e2900003703c804200e2028200c4105746a2034202c6a410574109e081a201d41c8056a222c20144105746a220e41186a2036290300370000200e41106a2018290300370000200e41086a2032290300370000200e20012903c804370000202c20164105746a201941c8056a2010410574109d081a201c202641086a412c20276b109e081a0240200c201a2f0106221c4f0d00201a20236a41ac086a210e0340200e2802002218200c3b01042018201a360200200e41046a210e201c200c41016a220c470d000b201a2f0106211c0b201a201c417f6a3b0106201d2010201d2f01066a41016a3b0106024020204102490d00201d20164102746a41a8086a201941a8086a201041027441046a109d081a2016203341026a4f0d00201041016a2118201d20144102746a41ac086a210c2016210e0340200c280200221c200e3b0104201c201d360200200c41046a210c200e41016a210e2018417f6a22180d000b0b20191035024020222021417f73724101710d0020204101470d102016410020211b20116a2111201a20236a41a8086a280200211b0b2052a7210e201a220c2f01062218450d064101212220184105490d010c150b0b41e4dec600412041c086cc00103f000b20192802a808211d201941a8086a220c201941ac086a2010410274109e081a4100210e201d41003602000340200c280200221c200e3b0104201c2019360200200c41046a210c2010200e41016a220e470d000b2020417f6a211c20192f010621100b20192010417f6a3b0106201a20184106746a220c41206a220e290000215e200e2056370000200c41186a220e2900002156200e2058370000200c41106a220e2900002158200e2057370000200c41086a220e2900002157200e2059370000200c41c0006a220e2900002159200e2052370000200c41386a220e2900002152200e2053370000200c41306a220e2900002153200e2054370000200c41286a220c2900002154200c2055370000201a20184105746a220c41d8056a220e2900002155200e205b370000200c41d0056a220e290000215b200e205c370000200c41c8056a220e290000215c200e205d370000200c41e0056a220c290000215d200c205a3700002026280200210c02402020450d00201d450d052020417f6a201c470d06200c2f01062218410a4b0d07200c20184106746a220e41c0006a2059370000200e41386a2052370000200e41306a2053370000200e41286a2054370000200e41206a205e370000200e41186a2056370000200e41106a2058370000200e41086a2057370000200c20184105746a220e41e0056a205d370000200e41d8056a2055370000200e41d0056a205b370000200e41c8056a205c370000200c201841016a220e4102746a41a8086a2218201d360200200c200c2f010641016a3b010620182802002218200e3b01042018200c3602000c020b200c2f01062218410b4f0d07200c20184106746a220e41c0006a2059370000200e41386a2052370000200e41306a2053370000200e41286a2054370000200e41206a205e370000200e41186a2056370000200e41106a2058370000200e41086a2057370000200c20184105746a220e41d8056a2055370000200e41d0056a205b370000200e41c8056a205c370000200e41e0056a205d370000200c200c2f010641016a3b01060c010b0240024002402014450d00201d2014417f6a220e4105746a220c41e0056a2900002152200c41d8056a2900002153200c41d0056a2900002154200c41c8056a2900002155201d200e4106746a220c41c0006a2900002156200c41386a2900002158200c41306a2900002157200c41286a2900002159200c41206a290000215a200c41186a290000215b200c41106a290000215c200c41086a290000215d20200d014100210e0c020b41e4dec600412041c086cc00103f000b201d20144102746a41a8086a280200220e41003602002020417f6a2110201d2f010621140b201d2014417f6a3b0106201a20184106746a220c41206a221d290000215e201d205a370000200c41186a221d290000215a201d205b370000200c41106a221d290000215b201d205c370000200c41086a221d290000215c201d205d370000200c41c0006a221d290000215d201d2056370000200c41386a221d2900002156201d2058370000200c41306a221d2900002158201d2057370000200c41286a220c2900002157200c2059370000201a20184105746a220c41d8056a2218290000215920182053370000200c41d0056a2218290000215320182054370000200c41c8056a2218290000215420182055370000200c41e0056a220c2900002155200c2052370000201c280200211802402020450d00200e450d082020417f6a2010470d09024020182f0106220c410a4b0d00201841c8006a201841086a200c410674109e081a201841386a2056370000201841306a2058370000201841286a2057370000201841186a205a370000201841106a205b3700002018205c370008201841c0006a205d370000201841206a205e370000201841e8056a201841c8056a200c410574109e081a201841e0056a2055370000201841d8056a2059370000201841d0056a2053370000201820543700c805201841ac086a201841a8086a220c20182f010641027441046a109e081a2018200e3602a808201820182f010641016a220e3b0106200e41ffff037141016a211c4100210e0340200c280200221a200e3b0104201a2018360200200c41046a210c201c200e41016a220e470d000c030b0b41af84cc00412741c086cc00103f000b20182f0106220c410b4f0d09201841c8006a201841086a200c410674109e081a201841386a2056370000201841306a2058370000201841286a2057370000201841186a205a370000201841106a205b3700002018205c370008201841c0006a205d370000201841206a205e370000201841e8056a201841c8056a200c410574109e081a201841e0056a2055370000201841d8056a2059370000201841d0056a2053370000201820543700c805201820182f010641016a3b01060b2022417f732021710d010c0f0b0240200e2802042218450d00200e280200221a2802a808210c200e2018417f6a360204200e200c360200200c4100360200201a10350c0f0b41c3dec600412141c086cc00103f000b2011201b2f0106490d084100210e024003400240201b280200220c0d00410021114100210c0c020b200e41016a210e201b2f01042111200c211b2011200c2f01064f0d000b0b201141016a21110240200e0d00200c211b0c0e0b200c20114102746a41a8086a280200211b41002111200e417f6a220c450d0d0340201b2802a808211b200c417f6a220c0d000c0e0b0b41958dcc00412b41ecdfc600103f000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b41af84cc00412741c086cc00103f000b41958dcc00412b4184dfc600103f000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b41cfa2cc00412841c086cc00103f000b201141016a21110c040b41b09ac200412941c086cc00103f000b200b200c41809ac2001042000b41d684cc00413541c086cc00103f000b200b201941f099c2001042000b2037450d002011201b2f0106490d000340201b280200220c450d01201b2f0104210e200c211b200e200c2f01064f0d000b0b02402031450d00203141306c450d00203510350b200128029c02220c450d00200c41306c450d0020012802980210350b2025450d03202541306c450d03202410350c030b20102001290318370000201041186a2009290300370000201041106a200a290300370000201041086a200f2903003700000b2025450d01202541306c450d01202410350c010b2004410041d208109f081a41d8081033220c450d0f200c4100360200200c41046a200141f8076a41d408109d081a200c200e28020022183602a808200e200c360200200e200e280204221a41016a360204201841003b01042018200c360200200141d0026a41026a221c203c2d00003a00002010203d2903003703002019203e2903003703002014203f2903003703002008204029030037030020162041290000370000200120012f01cc023b01d00220012001290398023703f807203620422903003703002035204329030037030020342044290300370300200120012903f8013703e804201a201d470d01200c2f01062218410a4b0d03200c20184106746a220e410a6a201c2d00003a0000200e41086a20012f01d0023b0000200e41176a2030360000200e41136a202f360000200e410f6a202e360000200e410b6a202d360000200e41c0006a2016290000370000200e413b6a2008290300370000200e41236a2010290300370000200e411b6a20012903f807370000200e41336a2014290300370000200e412b6a2019290300370000200c20184105746a220e41e0056a2036290300370000200e41d8056a2035290300370000200e41d0056a2034290300370000200e41c8056a20012903e804370000200c201841016a220e4102746a41a8086a2011360200200c200e3b01062011200c3602002011200e3b010441001a201b1a0b201e201f470d010c050b0b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b1045000b1044000b201741ffffff1f71450d00201510350b200b41016a210b0240201341ffffff3f71450d00201210350b200b2003470d000b2001280208220c0d010b2001418c086a41003602002001410036029808200141003602fc070c010b2001280210211702400240200128020c22110d00200c210e0c010b2011210e200c2108034020082802a8082108200e417f6a220e0d000b200c210e0340200e200e2f01064102746a41a8086a280200210e2011417f6a22110d000b2008210c0b20014194086a200e2f0106360200200141f8076a41186a41003602002001418c086a200e3602002001201736029808200141003602f807200141003602880820014200370380082001200c3602fc0702402017450d00200141a0036a41186a211a200141b0036a211b200141a8036a211c4100211841002111034020012017417f6a221736029808200c450d034100210802402018200c2f0106490d00034002400240200c280200220e0d002011ad21524100210e0c010b200841016a2108200c3301044220862011ad8421520b200c10352052a72111200e210c2052422088a72218200e2f01064f0d000b200e210c0b201a200c20184105746a220e41e0056a290000370300201b200e41d8056a290000370300201c200e41d0056a2900003703002001200e41c8056a2900003703a003201841016a211802402008450d00200c20184102746a41a8086a280200210c410021182008417f6a220e450d000340200c2802a808210c200e417f6a220e0d000b0b200120183602840820012011360280082001200c3602fc07200141003602f80720170d000b0b200c450d00200c280200210e200c1035200e450d000340200e280200210c200e1035200c210e200c0d000b0b200141003602d004200141003602c80402400240200041086a22322802002204450d00200141c8046a41086a21412000280200210c200141e8046a41186a2139200141d0076a41106a2146200141d0076a41086a2147200141d0026a41016a222e41286a2149202e41206a214a200141f5026a21452004210e4100212303400240200e20234b0d002023200e41dc9ac2001042000b200141d0076a41186a2248200c2023412c6c22406a221141246a29000037030020462011411c6a2900003703002047201141146a2900003703002001201129000c3703d00702402011280208450d00410021370340200c20406a280200210c200141386a41186a22152048290300370300200141386a41106a22062046290300370300200141386a41086a221e2047290300370300200120012903d007370338200141003a0058200141b8016a41186a2210200c203741306c6a220c41186a290000370300200141b8016a41106a2219200c41106a290000370300200141b8016a41086a2207200c41086a2900003703004101211d200141013a00d8012001200c2900003703b8010240024020012802c80422170d004100210c410021140c010b2017211a20012802cc04221b211c02400340201a41286a210c201a2f0106221d41216c210e41002108024002400340200821110240200e0d00201d21110c020b02400240200141386a200c41606a412010a0082208450d0041012118200841004e0d010c030b200c2d00002208450d03417f410120081b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201c0d004101211d0c030b201c417f6a211c201a20114102746a41a0036a280200211a0c010b0b4100211d0b2017211a02400340201a41286a210c201a2f0106221c41216c210e41002108024002400340200821110240200e0d00201c21110c020b02400240200141b8016a200c41606a412010a0082208450d0041012118200841004e0d010c030b200c2d000022084101460d03417f4101200841014b1b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201b0d00410021140c030b201b417f6a211b201a20114102746a41a0036a280200211a0c010b0b201a20114102746a41f4026a21140b2017210c0b200141a0036a41186a223a2015290300370300200141a0036a41106a223b2006290300370300200141a0036a41086a222d201e290300370300200120012903383703a003200141003a00c00302400240200c450d0020012802cc04211a0c010b200141f8076a410041eb02109f081a20494100360000204a4200370000202e41186a4200370000202e41106a4200370000202e41086a4200370000202e420037000041a00310332217450d094100211a201741003b010620174100360200201741086a200141f8076a41eb02109d081a20174198036a204529000037000020174193036a200141d0026a41206a2900003700002017418b036a200141d0026a41186a29000037000020174183036a200141d0026a41106a290000370000201741fb026a200141d0026a41086a290000370000201720012900d0023700f302200141003602cc04200120173602c8040b024002400340201741286a210c20172f0106221b41216c210e4100210802400340200821110240200e0d00201b21110c020b02400240200141a0036a200c41606a412010a0082208450d0041012118200841004e0d010c030b200c2d00002208450d04417f410120081b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201a450d00201a417f6a211a201720114102746a41a0036a28020021170c010b0b203920012903a003370000203941086a202d290300370000203941106a203b290300370000203941186a203a290300370000203941206a200141a0036a41206a2d00003a0000200120413602fc04200120113602f804200120173602f0044100210c200141003602ec042001200141c8046a3602f4040c010b200120413602fc04200120113602f804200120173602f0042001201a3602ec042001200141c8046a3602f4044101210c0b2001200c3602e804200141f8076a41086a2234201e290300370300200141f8076a41106a22352006290300370300200141f8076a41186a22362015290300370300200141f8076a41206a221c200141386a41206a2d00003a0000200120012903383703f80741341033220c450d08200c4200370208200c428180808010370200200c20012903f807370210200c20012f00d0023b0031200c41186a2034290300370200200c41206a2035290300370200200c41286a2036290300370200200c41306a201c2d00003a0000200c41336a200141d0026a41026a22152d00003a000002400240024002400240024002400240200141e8046a200c10ac02280200222628020041016a220c41014d0d002026200c360200203a2010290300370300203b2019290300370300202d2007290300370300200120012903b8013703a003200141013a00c0030240024020012802c8042217450d0020012802cc04211a0c010b200141f8076a410041eb02109f081a20494100360000204a4200370000202e41186a4200370000202e41106a4200370000202e41086a4200370000202e420037000041a00310332217450d114100211a201741003b010620174100360200201741086a200141f8076a41eb02109d081a20174198036a204529000037000020174193036a200141d0026a41206a2900003700002017418b036a200141d0026a41186a29000037000020174183036a200141d0026a41106a290000370000201741fb026a200141d0026a41086a290000370000201720012900d0023700f302200141003602cc04200120173602c8040b024002400340201741286a210c20172f0106221b41216c210e4100210802400340200821110240200e0d00201b21110c020b02400240200141a0036a200c41606a412010a0082208450d0041012118200841004e0d010c030b200c2d000022084101460d04417f4101200841014b1b21180b201141016a2108200e415f6a210e200c41216a210c2018417f470d000b0b0240201a450d00201a417f6a211a201720114102746a41a0036a28020021170c010b0b203920012903a003370000203941086a202d290300370000203941106a203b290300370000203941186a203a290300370000203941206a200141a0036a41206a2d00003a0000200120413602fc04200120113602f804200120173602f0044100210c200141003602ec042001200141c8046a3602f4040c010b200120413602fc04200120113602f804200120173602f0042001201a3602ec042001200141c8046a3602f4044101210c0b2001200c3602e804203420072903003703002035201929030037030020362010290300370300201c200141b8016a41206a2d00003a0000200120012903b8013703f80741341033220c450d10200c4200370208200c428180808010370200200c20012903f807370210200c20012f00d0023b0031200c41186a2034290300370200200c41206a2035290300370200200c41286a2036290300370200200c41306a201c2d00003a0000200c41336a20152d00003a0000200141e8046a200c10ac022802002227280200220e41016a220c41014d0d002027200c360200024002400240024002400240024002400240024002400240024002400240024002400240201d450d0020140d03202628020041016a220c41014d0d122026200c36020020272802080d0b2027417f360208202728020c220c0d014100210c0c020b2014450d03200141f8076a202610ad022001280284082144200128028008214e20012802fc07213820012802f807212f200141f8076a202710ad022001280284082142200128028008214f20012802fc0721300240202f20012802f807223e460d00202f28020841016a220c41004c0d0d202f200c360208203e280208220c41016a220e41004c0d0c203e200e360208202f41106a203e41106a412010a0080d0e202f2d0030203e2d0030470d0e203e200c360208202f202f280208417f6a3602080b20302042410274222b6a211c20382044410274222a6a2111202a0d04410021170c050b200c200c280200417f6a3602000240202728020c220c2802000d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10ae02200c28020c210e0b200e200e280204417f6a360204200c28020c220c2802040d00200c10350b202728020c220c200c280204417f6a360204202728020c220c2802040d00200c10350b202728020841016a210c0b2027200c3602080c130b200e417e4f0d0e2027200e41026a36020020262802080d062026417f36020802400240202628020c220c0d004100210c0c010b200c200c280200417f6a3602000240202628020c220c2802000d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10ae02200c28020c210e0b200e200e280204417f6a360204200c28020c220c2802040d00200c10350b202628020c220c200c280204417f6a360204202628020c220c2802040d00200c10350b202628020841016a210c0b2026200c3602082026202736020c0c130b202628020041016a220c41014d0d0d2026200c36020020272802080d042027417f3602080240202728020c220c0d00202741003602080c120b200c200c280200417f6a3602000240202728020c220c2802000d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10ae02200c28020c210e0b200e200e280204417f6a360204200c28020c220c2802040d00200c10350b202728020c220c200c280204417f6a360204202728020c220c2802040d00200c10350b2027202728020841016a3602080c110b41002117201c210820112118034020302008460d01024002402018417c6a2218280200220c2008417c6a2208280200220e460d00200c28020841016a221a41004c0d05200c201a360208200e280208221a41016a221b41004c0d04200e201b360208200c41106a200e41106a412010a0080d01200c2d0030200e2d0030470d01200e201a360208200c200c280208417f6a3602080b201741016a211720382018470d010c020b0b200e201a360208200c200c280208417f6a3602080b2001410036028008200142043703f807204420176b211a204220176b220b41016a210e024020300d004100210c2038450d0a201a450d0a201a201120386b410276220c200c201a4b1b210c0c0a0b2038450d084100210c410021080240200e450d00200e201c20306b41027622082008200e4b1b21080b0240201a450d00201a201120386b410276220c200c201a4b1b210c0b2008200c6a220c20084f0d09410421144100211841002115203021080340024002402008450d000240200e0d004100210e0c010b200e417f6a210e201c2008460d002008280200220c28020041016a221741014d0d0e200c2017360200200c450d00200841046a21080c010b201a450d0c201120386b410276220c4100200c201a6b22082008200c4b1b220c4d0d0c2011200c4102746b417c6a2211280200220c28020041016a220841014d0d0d200c2008360200200c450d0c201a417f6a211a410021080b0240201520012802fc07470d0002400240024020080d00201a0d01410021170c020b4100211b410021170240200e450d00200e201c20086b41027622172017200e4b1b21170b0240201a450d00201a201120386b410276221b201b201a4b1b211b0b417f2017201b6a221b201b2017491b21170c010b201a201120386b41027622172017201a4b1b21170b200141f8076a2015417f201741016a221b201b2017491b10860120012802f80721140b201420186a200c3602002001201541016a221536028008201841046a21180c000b0b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b203e200c360208202f202f280208417f6a360208204fad4220862030ad842252204ead4220862038ad842253204420424b22151b2254a7211d02400240024002402042204420151b2206410274220e450d00201d200e6a211c41012118201d2111201d21080340024002402018450d00201c20116b41027620184d0d03201120184102746a21110c010b201c2011460d020b2008280200221728020041016a220c41014d0d082017200c3602002011280200220c2802080d02200841046a2108200c417f360208410021184100211a0240200c28020c221b450d00201b201b280200417f6a3602000240200c28020c221a2802000d000240201a28020c221b450d00201b201b280200417f6a360200201a28020c221b2802000d000240201b28020c450d00201b410c6a10ae02201a28020c211b0b201b201b280204417f6a360204201a28020c221a2802040d00201a10350b200c28020c221a201a280204417f6a360204200c28020c221a2802040d00201a10350b200c28020841016a211a0b201141046a2111200c201a360208200c201736020c201c2008470d000b0b2006450d0102402044204220151b22180d0041004100419c9bc2001042000b2053205220151b2252a72217280200221128020041016a220c41014d0d062011200c360200201d280200220c2802080d02200c417f36020802400240200c28020c22080d00410021080c010b20082008280200417f6a3602000240200c28020c22082802000d000240200828020c221a450d00201a201a280200417f6a360200200828020c221a2802000d000240201a28020c450d00201a410c6a10ae02200828020c211a0b201a201a280204417f6a360204200828020c22082802040d00200810350b200c28020c22082008280204417f6a360204200c28020c22082802040d00200810350b200c28020841016a21080b2052422088215220544220882153200c2008360208200c201136020c201841027421112017210c0340200c28020022082008280200417f6a3602000240200c28020022082802000d000240200828020c2218450d0020182018280200417f6a360200200828020c22182802000d000240201828020c450d002018410c6a10ae02200828020c21180b20182018280204417f6a360204200828020c22082802040d00200810350b200c28020022082008280204417f6a360204200c28020022082802040d00200810350b200c41046a210c2011417c6a22110d000b02402052500d002052a7410274450d00201710350b201d210c0340200c28020022112011280200417f6a3602000240200c28020022112802000d000240201128020c2208450d0020082008280200417f6a360200201128020c22082802000d000240200828020c450d002008410c6a10ae02201128020c21080b20082008280204417f6a360204201128020c22112802040d00201110350b200c28020022112011280204417f6a360204200c28020022112802040d00201110350b200c41046a210c200e417c6a220e0d000b02402053500d002053a7410274450d00201d10350b203e203e280200417f6a220c360200203741016a2137200c0d090240203e28020c220c450d00200c200c280200417f6a360200203e28020c220c2802000d000240200c28020c450d00200c410c6a10ae02203e28020c210c0b200c200c280204417f6a360204203e28020c220c2802040d00200c10350b203e203e280204417f6a220c360204200c0d09203e10350c090b41a797cc004110200141a8046a41a08bc50041c897cc001046000b41004100418c9bc2001042000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b0240200e0d004100210c0c010b200e201c20306b410276220c200c200e4b1b210c0b200141f8076a4100200c10860120012802f807221420012802800822154102746a210c02402030450d00200e450d00203020424102746a211b2042417f7320176a21082030210e0340201b200e460d01200e280200221828020041016a221741014d0d0320182017360200200c2018360200201541016a2115200c41046a210c200e41046a210e200841016a221820084f21172018210820170d000b0b02402038450d00201a450d000240201120386b410276220e201a4d0d00200e201a417f736a2208200e4f0d01201120084102746b417c6a21110b20112038460d0003402011417c6a2211280200220e28020041016a220841014d0d03200e2008360200200c200e360200201541016a2115200c41046a210c20382011470d000b0b20012015360280080b20012802fc07215120014198026a41186a224b420037030020014198026a41106a224c420037030020014198026a41086a224d42003703002001420037039802203a4200370300203b4200370300202d4200370300200142003703a0034100211e0240024020150d00427f2152427f2153410021074100212c410021250c010b2015417f6a2116427f215241002107427f21534100212c41002125427f2155427f21544100211a0240024002400240024003402014201a4102746a280200220c28020841016a220e41004c0d01201a41016a211b0240200c2d00300d00200c200e360208200141d0026a41186a221c200c41286a290000370300200141d0026a41106a221d200c41206a290000370300200141d0026a41086a2206200c41186a290000370300200c200c280208417f6a3602082001200c2900103703d0022015201b41002016201a4b1b220c4d0d032014200c4102746a280200220c28020841016a220e41004c0d04200c200e3602082039200c41286a290000370300200141e8046a41106a2210200c41206a290000370300200141e8046a41086a2219200c41186a290000370300200c200c280208417f6a3602082001200c2900103703e8042015201a2015201a1b417f6a220c4d0d052014200c4102746a280200220c28020841016a220e41004c0d06200c200e3602082036200c41286a2900003703002035200c41206a2900003703002034200c41186a290000370300200c200c280208417f6a3602082001200c2900103703f8072032280200412c6c220e2111200028020022082118024003402018210c2011450d010240200141d0026a200c410c6a2217460d00201141546a2111200c412c6a21182017200141d0026a412010a0080d010b0b200c41086a28020041306c2111200c280200211803402018210c2011450d010240200141e8046a200c460d00201141506a2111200c41306a2118200c200141e8046a412010a0080d010b0b2052200c41206a2903002258582054200c41286a29030022565820542056511b0d00204b2039290300370300204c2010290300370300204d2019290300370300202d2006290300370300203b201d290300370300203a201c290300370300200120012903e80437039802200120012903d0023703a0034101212c2058215220562153201a2107201a212520562155205621540b03402008210c200e450d010240200141d0026a200c410c6a2211460d00200e41546a210e200c412c6a21082011200141d0026a412010a0080d010b0b200c41086a28020041306c210e200c280200211103402011210c200e450d010240200141f8076a200c460d00200e41506a210e200c41306a2111200c200141f8076a412010a0080d010b0b205521542052200c41206a2903002258582055200c41286a29030022565820552056511b0d00204b2036290300370300204c2035290300370300204d2034290300370300202d2006290300370300203b201d290300370300203a201c290300370300200120012903f80737039802200120012903d0023703a0034100212c2058215220562153201a2107201a212520562155205621540b201b211a201b2015460d060c000b0b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b200c201541ac9bc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b200c201541bc9bc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b200141003602d802200142043703d0022025202c6a21500240024020150d0041012119417f213f0c010b2015417f6a213f41012119205041017121434100211e202c212041002106024003400240024002400240024002400240201420064102746a2229280200221028020841016a220c41004c0d00200641016a21222010200c36020820102d00300d0620152006201520061b417f6a220c4d0d012014200c4102746a2233280200222828020841016a220c41004c0d022028200c36020802402032280200220c0d002022210c2006211b0c060b20002802002217200c412c6c6a211d202841106a210e201041106a211a202c45200620074671213120430d034100211c2006211b034002400240201a2017410c6a220c460d00200c201a412010a0080d010b201741086a2224280200222141306c21114100210820172802002216210c024003402011450d02200e200c460d01200c200e412010a0082118200841016a2108201141506a2111200c41306a210c20180d000b20184541016a41017120086a417f6a21080b0240427f2016200841306c6a220c290320225520527c225420542055542211200c41286a290300225420537c2011ad7c225620545420562054511b22111b4200205520527d22582058205556205420537d2055205254ad7d225520545620552054511b22181b201b41017122161b2254427f205620111b4200205520181b20161b225584500d00200c41206a220c2054370300200c20553703080c010b200c200c41306a20212008417f736a41306c109e081a20242021417f6a36020041002120410020192023201c461b211902402031450d00200721252007211b0c010b2029280200220c28020041016a221141014d0d0c200c20113602002033280200221128020041016a220841014d0d0c201120083602000240201e20012802d402470d00200141d0026a201e410110900120012802d802211e0b20012802d002201e4103746a220820113602042008200c3602002001201e41016a221e3602d802202c2120200721252006211b0b201c41016a211c2017412c6a2217201d470d000c050b0b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b200c201541cc9bc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b4100211c2006211b034002400240201a2017410c6a220c460d00200c201a412010a0080d010b201741086a2224280200222141306c21114100210820172802002216210c024003402011450d02200e200c460d01200c200e412010a0082118200841016a2108201141506a2111200c41306a210c20180d000b20184541016a41017120086a417f6a21080b024042002016200841306c6a220c290320225520527d22542054205556200c41286a290300225420537d2055205254ad7d225620545620562054511b22111b427f205520527c225820582055542218205420537c2018ad7c225520545420552054511b22181b201b41017122161b22544200205620111b427f205520181b20161b225584500d00200c41206a220c2054370300200c20553703080c010b200c200c41306a20212008417f736a41306c109e081a20242021417f6a36020041002120410020192023201c461b211902402031450d00200721252007211b0c010b2029280200220c28020041016a22114102490d08200c20113602002033280200221128020041016a22084102490d08201120083602000240201e20012802d402470d00200141d0026a201e410110900120012802d802211e0b20012802d002201e4103746a220820113602042008200c3602002001201e41016a221e3602d802202c2120200721252006211b0b201c41016a211c2017412c6a2217201d470d000b0b201b41016a210c0b024002400240024002402015200c4100203f201b4b1b220c4d0d002014200c4102746a280200223128020841016a220c41004c0d012031200c3602082032280200220e450d0420002802002217200e412c6c6a211d202c4101462006200746712133203141106a210e201041106a211a201420224100203f20064b1b223c4102746a213d20430d024100211c034002400240201a2017410c6a220c460d00200c201a412010a0080d010b201741086a2224280200222141306c21114100210820172802002216210c024003402011450d02200e200c460d01200c200e412010a0082118200841016a2108201141506a2111200c41306a210c20180d000b20184541016a41017120086a417f6a21080b024042002016200841306c6a220c290320225520527d22542054205556200c41286a290300225420537d2055205254ad7d225620545620562054511b22111b427f205520527c225820582055542218205420537c2018ad7c225520545420552054511b22181b201b41017122161b22544200205620111b427f205520181b20161b225584500d00200c41206a220c2054370300200c20553703080c010b200c200c41306a20212008417f736a41306c109e081a20242021417f6a360200410020192023201c461b21194101212002402033450d00200721252007211b0c010b2029280200220c28020041016a221141014d0d0b200c20113602002015203c4d0d09203d280200221128020041016a220841014d0d0b201120083602000240201e20012802d402470d00200141d0026a201e410110900120012802d802211e0b20012802d002201e4103746a220820113602042008200c3602002001201e41016a221e3602d802202c2120200721252006211b0b201c41016a211c2017412c6a2217201d470d000c040b0b200c201541dc9bc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b4100211c034002400240201a2017410c6a220c460d00200c201a412010a0080d010b201741086a2224280200222141306c21114100210820172802002216210c024003402011450d02200e200c460d01200c200e412010a0082118200841016a2108201141506a2111200c41306a210c20180d000b20184541016a41017120086a417f6a21080b0240427f2016200841306c6a220c290320225520527c225420542055542211200c41286a290300225420537c2011ad7c225620545420562054511b22111b4200205520527d22582058205556205420537d2055205254ad7d225520545620552054511b22181b201b41017122161b2254427f205620111b4200205520181b20161b225584500d00200c41206a220c2054370300200c20553703080c010b200c200c41306a20212008417f736a41306c109e081a20242021417f6a360200410020192023201c461b21194101212002402033450d00200721252007211b0c010b2029280200220c28020041016a22114102490d08200c20113602002015203c4d0d06203d280200221128020041016a22084102490d08201120083602000240201e20012802d402470d00200141d0026a201e410110900120012802d802211e0b20012802d002201e4103746a220820113602042008200c3602002001201e41016a221e3602d802202c2120200721252006211b0b201c41016a211c2017412c6a2217201d470d000b0b2031280208210c0b2031200c417f6a36020820282028280208417f6a3602082010280208210c0b2010200c417f6a3602082022210620222015470d000b2020212c0c010b203c201541ec9bc2001042000b0240202c4101470d002025203f460d030b41c0001033220e450d10200e20012903a003370000200e200129039802370020200e41186a203a290300370000200e41106a203b290300370000200e41086a202d290300370000200e41286a204d290300370000200e41306a204c290300370000200e41386a204b290300370000024002402050200b4b0d002042417f6a221b450d014100210802400240024002400240034020082042460d01203020084102746a2217280200220c280200221141016a221841014d0d08200c2018360200200c28020841016a41004c0d02200c20113602002039200c41286a290000370300200141e8046a41106a200c41206a290000370300200141e8046a41086a200c41186a2900003703002001200c2900103703e8042042200841016a22084d0d03203020084102746a221a280200220c280200221141016a221841014d0d08200c2018360200200c28020841016a41004c0d04200c20113602002036200c41286a2900003703002035200c41206a2900003703002034200c41186a2900003703002001200c2900103703f8074100210c02400340200c41c000460d01200e200c6a2111200c41206a210c2011200141e8046a412010a0080d000b4100210c0340200c41c000460d01200e200c6a2111200c41206a210c2011200141f8076a412010a0080d000c090b0b2017280200221128020041016a220c41014d0d082011200c360200201a280200220c2802080d05200c417f36020802400240200c28020c22180d00410021180c010b20182018280200417f6a3602000240200c28020c22182802000d000240201828020c2217450d0020172017280200417f6a360200201828020c22172802000d000240201728020c450d002017410c6a10ae02201828020c21170b20172017280204417f6a360204201828020c22182802040d00201810350b200c28020c22182018280204417f6a360204200c28020c22182802040d00201810350b200c28020841016a21180b200c2018360208200c201136020c2008201b470d000c070b0b20422042419c9cc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b2008204241ac9cc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b02402044417f6a221b450d004100210802400240024002400240034020082044460d01203820084102746a2217280200220c280200221141016a221841014d0d08200c2018360200200c28020841016a41004c0d02200c20113602002039200c41286a290000370300200141e8046a41106a200c41206a290000370300200141e8046a41086a200c41186a2900003703002001200c2900103703e8042044200841016a22084d0d03203820084102746a221a280200220c280200221141016a221841014d0d08200c2018360200200c28020841016a41004c0d04200c20113602002036200c41286a2900003703002035200c41206a2900003703002034200c41186a2900003703002001200c2900103703f8074100210c02400340200c41c000460d01200e200c6a2111200c41206a210c2011200141e8046a412010a0080d000b4100210c0340200c41c000460d01200e200c6a2111200c41206a210c2011200141f8076a412010a0080d000c080b0b2017280200221128020041016a220c41014d0d082011200c360200201a280200220c2802080d05200c417f36020802400240200c28020c22180d00410021180c010b20182018280200417f6a3602000240200c28020c22182802000d000240201828020c2217450d0020172017280200417f6a360200201828020c22172802000d000240201728020c450d002017410c6a10ae02201828020c21170b20172017280204417f6a360204201828020c22182802040d00201810350b200c28020c22182018280204417f6a360204200c28020c22182802040d00201810350b200c28020841016a21180b200c2018360208200c201136020c2008201b470d000c060b0b2044204441fc9bc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b20082044418c9cc2001042000b41ac96cc004118200141a8046a41fc9ac20041d496cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b202728020041016a220c41014d0d012027200c360200024020262802080d002026417f36020802400240202628020c220c0d004100210c0c010b200c200c280200417f6a3602000240202628020c220c2802000d000240200c28020c2211450d0020112011280200417f6a360200200c28020c22112802000d000240201128020c450d002011410c6a10ae02200c28020c21110b20112011280204417f6a360204200c28020c220c2802040d00200c10350b202628020c220c200c280204417f6a360204202628020c220c2802040d00200c10350b202628020841016a210c0b2026200c3602082026202736020c200e10350c040b41a797cc004110200141a8046a41a08bc50041c897cc001046000b202628020041016a220c41014d0d002026200c36020020272802080d012027417f36020802400240202728020c220c0d004100210c0c010b200c200c280200417f6a3602000240202728020c220c2802000d000240200c28020c2211450d0020112011280200417f6a360200200c28020c22112802000d000240201128020c450d002011410c6a10ae02200c28020c21110b20112011280204417f6a360204200c28020c220c2802040d00200c10350b202728020c220c200c280204417f6a360204202728020c220c2802040d00200c10350b202728020841016a210c0b2027200c3602082027202636020c200e10350c020b00000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b20012802d0022217201e4103746a210820012802d402211b2017210e0240024002400240201e450d0020172111024003402011280200220c450d010240024002400240200c201141046a280200220e10af020d00200e200c10af02450d03200e2802080d09200e417f360208200e28020c22180d01410021180c020b200c2802080d07200c417f36020802400240200c28020c22180d00410021180c010b20182018280200417f6a3602000240200c28020c22182802000d000240201828020c221a450d00201a201a280200417f6a360200201828020c221a2802000d000240201a28020c450d00201a410c6a10ae02201828020c211a0b201a201a280204417f6a360204201828020c22182802040d00201810350b200c28020c22182018280204417f6a360204200c28020c22182802040d00201810350b200c28020841016a21180b200c2018360208200c410036020c0c020b20182018280200417f6a3602000240200e28020c22182802000d000240201828020c221a450d00201a201a280200417f6a360200201828020c221a2802000d000240201a28020c450d00201a410c6a10ae02201828020c211a0b201a201a280204417f6a360204201828020c22182802040d00201810350b200e28020c22182018280204417f6a360204200e28020c22182802040d00201810350b200e28020841016a21180b200e2018360208200e410036020c0b200e200e280200417f6a2218360200024020180d000240200e28020c2218450d0020182018280200417f6a360200200e28020c22182802000d000240201828020c450d002018410c6a10ae02200e28020c21180b20182018280204417f6a360204200e28020c22182802040d00201810350b200e200e280204417f6a221836020420180d00200e10350b200c200c280200417f6a220e3602000240200e0d000240200c28020c220e450d00200e200e280200417f6a360200200c28020c220e2802000d000240200e28020c450d00200e410c6a10ae02200c28020c210e0b200e200e280204417f6a360204200c28020c220e2802040d00200e10350b200c200c280204417f6a220e360204200e0d00200c10350b201141086a22112008470d000c030b0b201141086a210e0b2008200e460d000340200e220c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2211450d0020112011280200417f6a360200200e28020c22112802000d000240201128020c450d002011410c6a10ae02200e28020c21110b20112011280204417f6a360204200e28020c220e2802040d00200e10350b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10350b200c41086a210e200c41046a220c28020022112011280200417f6a3602000240200c28020022112802000d000240201128020c2218450d0020182018280200417f6a360200201128020c22182802000d000240201828020c450d002018410c6a10ae02201128020c21180b20182018280204417f6a360204201128020c22112802040d00201110350b200c28020022112011280204417f6a360204200c280200220c2802040d00200c10350b2008200e470d000b0b0240201b41ffffffff0171450d00201710350b02402015450d002015410274210e2014210c0340200c28020022112011280200417f6a3602000240200c28020022112802000d000240201128020c2208450d0020082008280200417f6a360200201128020c22082802000d000240200828020c450d002008410c6a10ae02201128020c21080b20082008280204417f6a360204201128020c22112802040d00201110350b200c28020022112011280204417f6a360204200c28020022112802040d00201110350b200c41046a210c200e417c6a220e0d000b0b0240205141ffffffff0371450d00201410350b02402042450d002030210c0340200c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2211450d0020112011280200417f6a360200200e28020c22112802000d000240201128020c450d002011410c6a10ae02200e28020c21110b20112011280204417f6a360204200e28020c220e2802040d00200e10350b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10350b200c41046a210c202b417c6a222b0d000b0b0240204f41ffffffff0371450d00203010350b203e203e280200417f6a220c3602000240200c0d000240203e28020c220c450d00200c200c280200417f6a360200203e28020c220c2802000d000240200c28020c450d00200c410c6a10ae02203e28020c210c0b200c200c280204417f6a360204203e28020c220c2802040d00200c10350b203e203e280204417f6a220c360204200c0d00203e10350b201941ff0171210802402044450d002038210c0340200c280200220e200e280200417f6a3602000240200c280200220e2802000d000240200e28020c2211450d0020112011280200417f6a360200200e28020c22112802000d000240201128020c450d002011410c6a10ae02200e28020c21110b20112011280204417f6a360204200e28020c220e2802040d00200e10350b200c280200220e200e280204417f6a360204200c280200220e2802040d00200e10350b200c41046a210c202a417c6a222a0d000b0b203720086a2137204e41ffffffff0371450d02203810350c020b41a797cc004110200141a8046a41a08bc50041c897cc001046000b41a797cc004110200141a8046a41a08bc50041c897cc001046000b202f202f280200417f6a220c3602000240200c0d000240202f28020c220c450d00200c200c280200417f6a360200202f28020c220c2802000d000240200c28020c450d00200c410c6a10ae02202f28020c210c0b200c200c280204417f6a360204202f28020c220c2802040d00200c10350b202f202f280204417f6a220c360204200c0d00202f10350b20272027280200417f6a220c3602000240200c0d000240202728020c220c450d00200c200c280200417f6a360200202728020c220c2802000d000240200c28020c450d00200c410c6a10ae02202728020c210c0b200c200c280204417f6a360204202728020c220c2802040d00200c10350b20272027280204417f6a220c360204200c0d00202710350b20262026280200417f6a220c360200200c0d030240202628020c220c450d00200c200c280200417f6a360200202628020c220c2802000d000240200c28020c450d00200c410c6a10ae02202628020c210c0b200c200c280204417f6a360204202628020c220c2802040d00200c10350b20262026280204417f6a220c360204200c0d030c020b2027202636020c0b20272027280200417f6a220c3602000240200c0d000240202728020c220c450d00200c200c280200417f6a360200202728020c220c2802000d000240200c28020c450d00200c410c6a10ae02202728020c210c0b200c200c280204417f6a360204202728020c220c2802040d00200c10350b20272027280204417f6a220c360204200c0d00202710350b203741016a213720262026280200417f6a220c360200200c0d010240202628020c220c450d00200c200c280200417f6a360200202628020c220c2802000d000240200c28020c450d00200c410c6a10ae02202628020c210c0b200c200c280204417f6a360204202628020c220c2802040d00200c10350b20262026280204417f6a220c360204200c0d010b202610350b02402032280200220e20234d0d002000280200220c20406a28020820374d0d020c010b0b2023200e41ec9ac2001042000b202341016a22232004470d000b20012802c804220c0d010b2001418c086a41003602002001410036029808200141003602fc070c030b20012802d004211a0240024020012802cc0422110d00200c210e0c010b2011210e200c2108034020082802a0032108200e417f6a220e0d000b200c210e0340200e200e2f01064102746a41a0036a280200210e2011417f6a22110d000b2008210c0b20014194086a200e2f010636020020014190086a41003602002001418c086a200e3602002001201a36029808200141003602f807200141003602880820014200370380082001200c3602fc07201a450d014100211841002111024003402001201a417f6a221a36029808200c450d014100210802402018200c2f0106490d00034002400240200c280200220e0d002011ad21524100210e0c010b200841016a2108200c3301044220862011ad8421520b200c10352052a72111200e210c2052422088a72218200e2f01064f0d000b200e210c0b201841016a210e200c20184102746a41f4026a2802002117200c201841216c6a41286a2d0000211b0240024020080d00200e21180c010b200c200e4102746a41a0036a280200210c410021182008417f6a220e450d000340200c2802a003210c200e417f6a220e0d000b0b200120183602840820012011360280082001200c3602fc07200141003602f807201b41ff01714102460d0320172017280200417f6a220e3602000240200e0d000240201728020c220e450d00200e200e280200417f6a360200201728020c220e2802000d000240200e28020c450d00200e410c6a10ae02201728020c210e0b200e200e280204417f6a360204201728020c220e2802040d00200e10350b20172017280204417f6a220e360204200e0d00201710350b201a0d000c030b0b41958dcc00412b41c08dcc00103f000b41958dcc00412b41c08dcc00103f000b200c450d00200c280200210e200c1035200e450d000340200e280200210c200e1035200c210e200c0d000b0b200141d0106a24000f0b103c000bdb21011d7f230041b0046b220224000240024002400240024002400240024020002802004101460d00200041146a2802002203200328020041016a360200200041106a28020021042000410c6a2802002105200041086a280200210320002802042106200241e0006a41206a2207200041386a2d00003a0000200241e0006a41186a2208200041306a290000370300200241e0006a41106a2209200041286a290000370300200241e0006a41086a220a200041206a2900003703002002200041186a29000037036020032f0106220b410b490d01200241c0016a410041eb02109f081a200241d9006a4100360000200241306a41216a4200370000200241c9006a4200370000200241c1006a4200370000200241396a42003700002002420037003141a0031033220c450d05200c41003b0106200c4100360200200c41086a200241c0016a41eb02109d082107200c4198036a200241d5006a290000370000200c4193036a200241306a41206a290000370000200c418b036a200241306a41186a290000370000200c4183036a200241306a41106a290000370000200c41fb026a200241306a41086a290000370000200c20022900303700f3022002200341ce016a2f00003b01182002200341d0016a2d00003a001a200341d1016a280000210d200341d5016a280000210e200341d9016a280000210f200341dd016a28000021102002200341e7016a2900003701c6012002200341e1016a2900003703c001200328028c0321112007200341ef016a20032f010641796a220041216c109d082107200c41f4026a20034190036a2000410274109d082108200341063b0106200c20003b01062002412c6a41026a20022d001a3a0000200220022f01183b012c200220022903c001370330200220022901c6013701360240024020044107490d00200441216c20076a220741ba7e6a200741997e6a2207200041ffff0371200441796a22096b41216c109e081a200741206a200241e0006a41206a2d00003a0000200741186a200241e0006a41186a290300370000200741106a200241e0006a41106a290300370000200741086a200241e0006a41086a29030037000020072002290360370000200441027420086a41686a2107200820094102746a2112200c41066a22002f010020096b21040c010b200341086a200441216c6a220741216a2007200341066a22002f010020046b41216c109e081a200741206a200241e0006a41206a2d00003a0000200741186a200241e0006a41186a290300370000200741106a200241e0006a41106a290300370000200741086a200241e0006a41086a29030037000020072002290360370000200341f4026a20044102746a221241046a210720002f010020046b21040b200720122004410274109e081a20122001360200200241146a41026a2002412c6a41026a22132d000022013a0000200020002f010041016a3b0100200241106a41026a221420013a000020022002290136370196012002200229033037039001200220022f012c22003b0114200220003b0110200220022903900137030020022002290196013701060240200328020022070d00410021000c040b20032f01042115200241c0016a4102722116200241306a41016a210a410021000340201320142d00003a0000200220022f01103b012c200220022903003703182002200229010637011e20062000470d03201541ffff0371210802400240024020072f01062200410b490d00200a41286a4100360000200a41206a4200370000200a41186a4200370000200a41106a4200370000200a41086a4200370000200a42003700002016410041ed02109f081a200241e0006a41086a22004200370300200241e0006a41106a22034200370300200241e0006a41186a22044200370300200241e0006a41206a22094200370300200241e0006a41286a220b420037030020024190016a41256a2217200241306a41256a29000037000020024190016a41206a2218200241306a41206a29000037030020024190016a41186a2219200241306a41186a29000037030020024190016a41106a221a200241306a41106a29000037030020024190016a41086a221b200241306a41086a29000037030020024200370360200220022900303703900141d00310332201450d0920014100360200200141046a200241c0016a41ef02109d081a20014198036a201729000037000020014193036a20182903003700002001418b036a201929030037000020014183036a201a290300370000200141fb026a201b29030037000020012002290390013700f302200120022903603702a003200141a8036a2000290300370200200141b0036a2003290300370200200141b8036a2004290300370200200141c0036a2009290300370200200141c8036a200b29030037020020024190016a41026a220b200741d0016a2d00003a00002002200741ce016a2f00003b0190012002200741e1016a2900003703c0012002200741e7016a2900003701c601200741d1016a2800002118200741d5016a2800002119200741d9016a280000211a200741dd016a280000211b200728028c03211c200141086a200741ef016a20072f0106220341796a220041216c109d08211d200141f4026a20074190036a2000410274109d08211e200141a0036a200741bc036a2003417a6a2209410274109d082117200741063b0106200120003b010602402009450d00410021002017210303402003280200220420003b010420042001360200200341046a21032009200041016a2200470d000b0b200220022f01900122003b0130200220022903c001370360200220022901c6013701662002200b2d000022033a0032200b20033a0000200220003b019001200220022903603703c001200220022901663701c601201541ffff037122034107490d01200841216c201d6a220041ba7e6a200041997e6a220320012f0106200841796a22006b41216c109e081a2003201036000f2003200f36000b2003200e3600072003200d360003200341026a20132d00003a0000200320022f012c3b000020032002290318370013200341196a200229011e370000201e2008417a6a220341027422046a201e20004102746a220920012f0106221520006b410274109e081a200920113602002001201541016a22093b01062008410274221520176a416c6a201720046a2204200941ffff0371220820036b410274109e081a2004200c36020020082003490d02200120156a4188036a2103034020032802002204200041016a22003b010420042001360200200341046a210320002008490d000c030b0b2007200841216c6a220341296a200341086a2201200020086b41216c109e081a200341176a2010360000200341136a200f3600002003410f6a200e3600002003410b6a200d3600002003410a6a2002412c6a41026a2d00003a0000200120022f012c3b00002003411b6a2002290318370000200341216a200229011e370000200741f4026a2203200841016a220041027422016a2003200841027422046a220320072f0106220920086b410274109e081a200320113602002007200941016a22033b01062004200741a0036a22086a41086a200820016a2201200341ffff0371220420006b410274109e081a2001200c360200201541ffff037120044f0d0720072000417f6a22004102746a41a4036a2103034020032802002201200041016a22003b010420012007360200200341046a210320002004490d000c080b0b200741086a200841216c6a220041216a200020072f010620086b41216c109e081a2000201036000f2000200f36000b2000200e3600072000200d360003200041026a20132d00003a0000200020022f012c3b000020002002290318370013200041196a200229011e370000200741f4026a2204200841016a220941027422156a2004200841027422006a220420072f0106221720086b410274109e081a200420113602002007201741016a22043b01062000200741a0036a22176a41086a201720156a2215200441ffff0371220420096b410274109e081a2015200c360200200320044f0d00200720006a41a4036a2100034020002802002203200841016a22083b010420032007360200200041046a210020042008470d000b0b200641016a21002014200b2d00003a0000200220022f0190013b0110200220022903c001370300200220022901c6013701060240200728020022030d002018210d201b2110201a210f2019210e2001210c201c21110c050b20072f010421152018210d201b2110201a210f2019210e20032107201c21112001210c200021060c000b0b20012001280200417f6a2203360200200041086a280200200041106a2802004102746a41f4026a211220030d030240200128020c2200450d0020002000280200417f6a360200200128020c22002802000d000240200028020c450d002000410c6a10ae02200128020c21000b20002000280204417f6a360204200128020c22002802040d00200010350b20012001280204417f6a220036020420000d03200110350c030b2003200441216c6a220041296a200041086a220c200b20046b41216c109e081a200041286a20072d00003a0000200041206a2008290300370000200041186a2009290300370000200041106a200a290300370000200c2002290360370000200320044102746a220041f8026a200041f4026a221220032f010620046b410274109e081a20122001360200200320032f010641016a3b01060c020b41d684cc00413541c086cc00103f000b200241b9016a4100360000200241b1016a4200370000200241a9016a4200370000200241a1016a420037000020024199016a42003700002002420037009101200241c0016a410272410041ed02109f081a200241e0006a41086a22014200370300200241e0006a41106a22044200370300200241e0006a41186a22074200370300200241e0006a41206a2208420037030020024188016a22094200370300200241306a41256a220a20024190016a41256a290000370000200241306a41206a220b20024190016a41206a290000370300200241306a41186a220620024190016a41186a290000370300200241306a41106a221520024190016a41106a290000370300200241306a41086a221720024190016a41086a29000037030020024200370360200220022900900137033041d00310332203450d0120034100360200200341046a200241c0016a41ef02109d081a20034198036a200a29000037000020034193036a200b2903003700002003418b036a200629030037000020034183036a2015290300370000200341fb026a2017290300370000200320022903303700f302200320022903603702a003200341a8036a2001290300370200200341b0036a2004290300370200200341b8036a2007290300370200200341c0036a2008290300370200200341c8036a20092903003702002003200528020022013602a0032005200336020020052005280204220441016a360204200141003b010420012003360200200241e0006a41026a200241106a41026a2d00003a0000200220022f01103b0160200220022903003703c001200220022901063701c60120042000470d0220032f01062201410a4b0d032003200141216c6a2200410a6a200241e0006a41026a2d00003a0000200041086a20022f01603b0000200041176a2010360000200041136a200f3600002000410f6a200e3600002000410b6a200d3600002000411b6a20022903c001370000200041216a20022901c6013700002003200141016a22004102746a41a0036a200c360200200320014102746a41f4026a2011360200200320003b0106200c20003b0104200c20033602000b200241b0046a240020120f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000baf0b010c7f230041306b220224002002410036021020024204370308200241003602202002420437031802400240024002400240200128020041016a220341014d0d0020012003360200200241086a4100410110860120022802082204200228021022034102746a20013602002002200341016a22053602102001280200220341016a41014d0d002001200341016a360200200241186a4100410110860120022802182206200228022022034102746a20013602002002200341016a2207360220200128020041016a220841014d0d00200120083602000340200841016a220341014d0d0120012003360200200128020841016a220941004c0d0220012009360208200128020c2208450d0502402007450d002007410274210a200841106a210b20062109034002400240200928020022032008460d00200328020841016a220c41004c0d072003200c3602082008280208220c41016a220d41004c0d082008200d360208200341106a200b412010a0080d0120032d003020082d0030470d012008200c36020820032003280208417f6a3602080b20012802002103200128020821090c080b200941046a21092008200c36020820032003280208417f6a360208200a417c6a220a0d000b200128020c21080b200828020041016a220341014d0d012008200336020002402005200228020c470d00200241086a2005410110860120022802082104200228021021050b200420054102746a20083602002002200541016a2205360210200128020c220328020041016a220841014d0d012003200836020020012001280200417f6a2208360200024020080d000240200128020c2208450d0020082008280200417f6a360200200128020c22082802000d000240200828020c450d002008410c6a10ae02200128020c21080b20082008280204417f6a360204200128020c22082802040d00200810350b20012001280204417f6a220836020420080d00200110350b200328020041016a220841014d0d012003200836020002402007200228021c470d00200241186a2007410110860120022802182106200228022021070b200620074102746a200336020020012001280208417f6a36020820012001280200417f6a22083602002002200741016a2207360220024020080d000240200128020c2208450d0020082008280200417f6a360200200128020c22082802000d000240200828020c450d002008410c6a10ae02200128020c21080b20082008280204417f6a360204200128020c22082802040d00200810350b20012001280204417f6a220836020420080d00200110350b20032802002108200321010c000b0b00000b41ac96cc004118200241286a41808bc50041d496cc001046000b41ac96cc004118200241286a41e495ca0041d496cc001046000b41ac96cc004118200241286a41e495ca0041d496cc001046000b20012003417f6a220336020020012009417f6a360208024020030d000240200128020c2203450d0020032003280200417f6a360200200128020c22032802000d000240200328020c450d002003410c6a10ae02200128020c21030b20032003280204417f6a360204200128020c22032802040d00200310350b20012001280204417f6a220336020420030d00200110350b20002001360200200020022903083702042000410c6a200241106a28020036020002402007450d0020074102742108200621030340200328020022092009280200417f6a3602000240200328020022092802000d000240200928020c2201450d0020012001280200417f6a360200200928020c22012802000d000240200128020c450d002001410c6a10ae02200928020c21010b20012001280204417f6a360204200928020c22092802040d00200910350b200328020022092009280204417f6a360204200328020022092802040d00200910350b200341046a21032008417c6a22080d000b0b0240200228021c41ffffffff0371450d00200610350b200241306a24000b5c01017f200028020022012001280200417f6a3602000240200028020022012802000d000240200128020c450d002001410c6a10ae02200028020021010b20012001280204417f6a360204200028020022002802040d00200010350b0ba50201047f230041106b22022400410021030240024002400240024002400240200028020841016a220441004c0d00200028020c2205450d0620002004360208024020052001470d00410121030c060b200528020841016a220341004c0d01200520033602082001280208220441016a220341004c0d0220012003360208200541106a200141106a412010a0080d034101210320052d003020012d0030470d030c040b41ac96cc004118200241086a41808bc50041d496cc001046000b41ac96cc004118200241086a41808bc50041d496cc001046000b41ac96cc004118200241086a41808bc50041d496cc001046000b410021030b2001200436020820052005280208417f6a360208200028020821040b20002004417f6a3602080b200241106a240020030b80150c047f027e027f067e017f037e037f027e037f037e037f017e230041e0036b2204240020032802002105200441306a2001108e02200441b0016a2004280230220620042802382207108f0220042903b001210842002109200442003703b001200441f8016a280200210a20042d00fc01210b02400240200842015122030d00200441c0006a41306a4200370300200441c0006a41286a4200370300200441c0006a41206a4200370300200441c0006a41186a4200370300200441d0006a4200370300200441c8006a4200370300200442003703404200210c4200210d4200210e4200210f0c010b200441e8016a2903002110200441b0016a41306a2903002111200441b0016a41206a290300210c200441b0016a41186a2903002109200441f0016a290300210f20042903c001210e20042903b801210d200441c0006a41206a200441b0016a41286a290300370300200441c0006a41286a2011370300200441c0006a41306a2010370300200441d0006a20093703002004200c3703582004200d3703402004200e3703480b427f200e200c7c200d20097c220c200d542212ad7c220920122009200e542009200e511b22121b2113427f200c20121b21144200210c024002402002290300221542ffffe883b1de1656200241086a29030022094200522009501b0d00201420138450450d0041002103410021124200210e410121020c010b4200200e20097c200d20157c2210200d542202ad7c220d2002200d200e54200d200e511b22021b210e4200201020021b2111024020024101470d002011421088200e42308684210c200e421088210e2011420888a721122011a72103410121020c010b200441b0026a41186a22164200370300200441b0026a41106a22174200370300200441b0026a41086a22124200370300200442003703b00241b6fdc600ad4280808080800184220c100122182900002119200441d0036a41086a2202201841086a290000370300200420193703d0032018103520122002290300370300200420042903d0033703b00241e489c200ad4280808080d00184221910012218290000211a2002201841086a2900003703002004201a3703d00320181035201720042903d003221a370300200441b0036a41086a221b2012290300370300200441b0036a41106a221c201a370300200441b0036a41186a221d2002290300370300200420042903b0023703b003200441186a200441b0036a412010d701200441186a41106a290300211a2004290320211e20042802182118201642003703002017420037030020124200370300200442003703b002200c10012216290000210c2002201641086a2900003703002004200c3703d0032016103520122002290300370300200420042903d0033703b002201910012216290000210c2002201641086a2900003703002004200c3703d00320161035201720042903d003220c370300201b2012290300370300201c200c370300201d2002290300370300200420042903b0023703b0032004201a420020181b3703b8022004201e420020181b3703b002200441b0036aad4280808080800484221a200441b0026aad221e428080808080028410022004200e37034820042011370340200441f8006a41186a200441d0006a220241086a290300220c370300200441f8006a41206a2212200241106a290300370300200441a0016a2218200241186a290300370300200441a8016a2216200241206a2903003703002004200e37038001200420113703782004200229030022193703880102400240427f201120197c221920192011542202200e200c7c2002ad7c220c200e54200c200e511b22021b220e428080e983b1de16544100427f200c20021b220c501b0d00200441f8006a41106a290300210e2016290300210c2018290300211120122903002119200429038001211a2004290378211e4201211f20042903900121200c010b02400240200e200c8450450d004200211f0c010b4200211f200441b0026a41186a22184200370300200441b0026a41106a22164200370300200441b0026a41086a22124200370300200442003703b00241b6fdc600ad428080808080018422111001221b2900002119200441d0036a41086a2202201b41086a290000370300200420193703d003201b103520122002290300370300200420042903d0033703b00241e489c200ad4280808080d0018422191001221b29000021202002201b41086a290000370300200420203703d003201b1035201720042903d003370000201741086a221d2002290300370000200441b0036a41086a22212012290300370300200441b0036a41106a22222016290300370300200441b0036a41186a22232018290300370300200420042903b0023703b0032004200441b0036a412010d701200441106a2903002120200429030821242004280200211b201842003703002016420037030020124200370300200442003703b00220111001221c29000021112002201c41086a290000370300200420113703d003201c103520122002290300370300200420042903d0033703b00220191001221c29000021112002201c41086a290000370300200420113703d003201c1035201720042903d003370000201d2002290300370000202120122903003703002022201629030037030020232018290300370300200420042903b0023703b0032004420020204200201b1b2211200c7d20244200201b1b2219200e54ad7d22202019200e7d2224201956202020115620202011511b22021b3703b80220044200202420021b3703b002201a201e42808080808002841002200441e8026a200c370300200441e0026a200e370300201241013a0000200441b9026a2005290000370000200441c1026a200541086a290000370000200441c9026a200541106a290000370000200441d1026a200541186a290000370000200441033a00b00241b0b4cc004100200441b0026a10d4010b0b200441d8016a2019370300200441e0016a2011370300200441c0016a201a370300200441e8016a200c370300200441c8016a200e370300200420203703d0012004200f3703f0012004201e3703b801410021022004200b4100200842015122121b3a00fc012004200a410020121b3602f8012004201f4201512212ad3703b001201420138450ad423086210c4200210e024020120d002007ad4220862006ad841007410021120c010b200420073602b402200420063602b002200441b8016a200441b0026a10e70241012112410021020b02402004280234450d00200610350b024002402002450d00200041106a200e421086200c4230888437030020002012ad42ff01834208862003ad42ff018384200c421086843703084201210e0c010b200c423088200e42108684210e024002400240200341ff017122020d00201241ff0171450d0041032103200441b0026a21020c010b2002450d01201241ff01710d0141042103200441b0016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b2000200e370308200041286a2009370300200041206a2015370300200041186a200d370300200041106a20103703004200210e0b2000200e370300200441e0036a24000bd60302057f047e230041f0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022030d00200041003a00000c010b200241186a28020021042002280214210541002101200241003a006802400240034020042001460d01200241c8006a20016a200320016a2d00003a00002002200141016a22063a00682006210120064120470d000b200241206a41186a200241c8006a41186a2903002207370300200241206a41106a200241c8006a41106a2903002208370300200241206a41086a200241c8006a41086a290300220937030020022002290348220a370320200041196a2007370000200041116a2008370000200041096a20093700002000200a370001410121010c010b0240200141ff0171450d00200241003a00680b410021012002410036022820024201370320200241093602442002200241086a3602402002200241206a36026c200241dc006a41013602002002420137024c200241c888c2003602482002200241c0006a360258200241ec006a41e88ac500200241c8006a10431a200235022842208620023502208410062002280224450d00200228022010350b200020013a00002005450d00200310350b200241f0006a24000ba11005097f037e027f037e037f230041f0026b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022040d00200042023703000c010b200328021421052003200341186a28020022063602a401200320043602a00141002107200341003a00e8022004210220062101024002400240024002400240024002400340200721082001450d01200341c8026a20086a20022d00003a000020032001417f6a22013602a4012003200241016a22023602a0012003200841016a22073a00e80220074120470d000b200341a8016a41086a200341c8026a41086a290300370300200341a8016a41106a200341c8026a41106a290300370300200341a8016a41186a200341c8026a41186a290300370300200320032903c8023703a80141002107200341003a00e802200620086b417e6a2108034020012007460d02200341c8026a20076a200220076a22062d00003a00002003200641016a3602a0012003200741016a22063a00e802200320083602a4012008417f6a21082006210720064120470d000b200341c8016a41086a200341c8026a41086a290300370300200341c8016a41106a200341c8026a41106a290300370300200341c8016a41186a200341c8026a41186a290300370300200320032903c8023703c80120012006460d05200220066a22092d00002102200320083602a4012003200941016a22073602a001200241014b0d0520020e020302030b200841ff0171450d04200341003a00e8020c040b200741ff0171450d03200341003a00e8020c030b200941116a210741002102200341003a00e802200120066b416f6a21010240034020082002460d01200341c8026a20026a200920026a41016a2d00003a000020032001410f6a3602a4012003200741716a3602a0012003200241016a22063a00e8022001417f6a2101200741016a21072006210220064120470d000b200341a8026a41186a2202200341c8026a41186a290300370300200341a8026a41106a220a200341c8026a41106a290300370300200341a8026a41086a220b200341c8026a41086a290300370300200320032903c8023703a802200820066b4110490d03200920066a220841096a290000210c200841016a290000210d20034188026a41086a200b29030037030020034188026a41106a200a29030037030020034188026a41186a2002290300370300200320013602a401200320073602a001200320032903a802370388024201210e200121080c020b200241ff0171450d02200341003a00e8020c020b4200210e0b200341e8016a41186a20034188026a41186a290300370300200341e8016a41106a20034188026a41106a290300370300200341e8016a41086a20034188026a41086a29030037030020032003290388023703e8012008450d0020072d0000210120032008417f6a22023602a4012003200741016a3602a001200141014b0d00410021060240024020010e020100010b20024104490d012007280001210920032008417b6a3602a4012003200741056a3602a001410121060b200341c8026a200341a0016a10aa0220032802c8020d010b200341003602b002200342013703a8022003410936028c022003200341086a360288022003200341a8026a3602e801200341dc026a4101360200200342013702cc02200341c888c2003602c802200320034188026a3602d802200341e8016a41e88ac500200341c8026a10431a20033502b00242208620033502a802841006024020032802ac02450d0020032802a80210350b4202210e0c010b200341f0006a41086a2202200341c8026a41086a2201280200360200200341d0006a41086a2207200341a8016a41086a290300370300200341d0006a41106a2208200341a8016a41106a290300370300200341d0006a41186a220a200341a8016a41186a290300370300200341306a41086a220b200341c8016a41086a290300370300200341306a41106a220f200341c8016a41106a290300370300200341306a41186a2210200341c8016a41186a290300370300200320032903c802370370200320032903a801370350200320032903c80137033020034180016a41186a200341e8016a41186a290300221137030020034180016a41106a200341e8016a41106a290300221237030020034180016a41086a200341e8016a41086a290300221337030020012013370300200341c8026a41106a22142012370300200341c8026a41186a22152011370300200341206a41086a22162002280200360200200320032903e801221137038001200320113703c80220032003290370370320200341a8026a41186a2202200a290300370300200341a8026a41106a220a2008290300370300200341a8026a41086a22082007290300370300200320032903503703a80220034188026a41186a2207201029030037030020034188026a41106a2210200f29030037030020034188026a41086a220f200b2903003703002003200329033037038802200041306a200c370300200041286a200d3703002000413c6a2009360200200041386a2006360200200041206a2015290300370300200041186a2014290300370300200041106a2001290300370300200020032903c802370308200041c0006a2003290320370300200041c8006a2016280200360200200020032903a80237024c200041d4006a2008290300370200200041dc006a200a290300370200200041e4006a200229030037020020004184016a2007290300370200200041fc006a2010290300370200200041f4006a200f290300370200200020032903880237026c0b2000200e3703002005450d00200410350b200341f0026a24000be00903067f067e057f230041a0016b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022040d00200041023a00000c010b2003280214210502400240200341186a2802002206450d0020042d0000220141014b0d002006417f6a210202400240024020010e020001000b20024104490d022004280001210741002101200341003a0098012006417b6a21080240034020082001460d01200341f8006a20016a200420016a41056a2d00003a00002003200141016a22023a0098012002210120024120470d000b200341d8006a41186a200341f8006a41186a290300370300200341d8006a41106a200341f8006a41106a290300370300200341d8006a41086a200341f8006a41086a290300370300200320032903783703582006417b6a2002460d03200420026a220141056a2d0000220841034f0d03200620026b2202417a6a4104490d03200241766a4110490d03200241666a4110490d03200241566a4110490d03200141066a2800002106200141126a29000021092001410a6a290000210a200341286a41086a200341d8006a41086a290300370300200341286a41106a200341d8006a41106a290300370300200341286a41186a200341d8006a41186a29030037030020032003290358370328200320032800503602202003200341d3006a280000360023200141326a290000210b2001412a6a290000210c200141226a290000210d2001411a6a290000210e200320032f014e3b014c410021010c020b200141ff0171450d02200341003a0098010c020b2002450d0120042d0001220141014b0d012006417e6a2108410021020240024020010e020100010b410121020b200841034d0d01200341286a41086a200341f8006a41086a290300370300200341286a41106a200341f8006a41106a290300370300200341286a41186a200341f8006a41186a29030037030020032003290378370328200320032800583602202003200341d8006a41036a2800003600232004280002210f410121010b200341f8006a41086a2210200341286a41086a290300370300200341f8006a41106a2211200341286a41106a290300370300200341f8006a41186a2212200341286a41186a290300370300200320032f014c22133b015020032003290328370378200320032802203602582003200328002336005b200041306a200b370000200041286a200c370000200041206a200d370000200041186a200e370000200041106a2009370000200041086a200a370000200020023a00012000413c6a2006360000200041386a2007360000200041046a200f360000200041026a20133b0000200041e0006a20083a0000200041c0006a2003290378370000200041c8006a2010290300370000200041d0006a2011290300370000200041d8006a2012290300370000200041e1006a2003280258360000200041e4006a200328005b3600000c010b20034100360260200342013703582003410936022c2003200341086a3602282003200341d8006a3602502003418c016a41013602002003420137027c200341c888c2003602782003200341286a36028801200341d0006a41e88ac500200341f8006a10431a200335026042208620033502588410060240200328025c450d00200328025810350b410221010b200020013a00002005450d00200410350b200341a0016a24000b880504057f017e027f017e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c2010240024002400240200328021022040d00200041003602000c010b200328021421052003200341186a280200360224200320043602202003200341206a10c4010240024020032802000d00200328020422062003280224220741186e2201200120064b1bad42187e2208422088a70d032008a72202417f4c0d030240024020020d00410821090c010b200210332209450d050b4100210120034100360250200320093602482003200241186e36024c0240024002402006450d00034020074104490d0320032003280220220241046a3602202007417c6a4110490d022002280000210a2003200241146a3602202002410c6a29000021082002290004210b02402001200328024c470d00200341c8006a20014101109c0120032802482109200328025021010b2007416c6a21072009200141186c6a2202200a3602002002200b370308200241106a20083703002003200141016a22013602502006417f6a22060d000b200320073602240b2009450d022000200329024c370204200020093602000c030b2007417c6a21070b20032007360224200328024c2201450d00200141186c450d00200910350b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602000b2005450d00200410350b200341e0006a24000f0b1044000b1045000bbe0201017f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602000c010b200328021421022003200341106a41086a28020036022420032001360220200341c8006a200341206a10c3010240024020032802480d0020034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602000c010b20002003290348370200200041086a200341c8006a41086a2802003602000b2002450d00200110350b200341e0006a24000b901304057f017e107f027e230041e0026b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c2010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c4010240024020022802000d00200228020422052002280224220641c4006e2201200120054b1bad42c4007e2207422088a70d032007a72201417f4c0d030240024020010d00410421080c010b200110332208450d050b20024100360230200220083602282002200141c4006e36022c0240024002402005450d00200241b8026a41077221094100210a4100210b03402006450d0220022006417f6a220c36022420022002280220220d41016a360220200d2d0000220141014b0d0202400240024020010e020001000b200c4104490d04200241f4016a41026a200241f8016a41026a2d00003a0000200241d8016a41086a20024198026a41086a290200370300200241d8016a41106a20024198026a41106a290200370300200241d8016a41186a20024198026a41186a2d00003a0000200241b8016a41086a200241b8026a41086a290100370300200241b8016a41106a200241b8026a41106a290100370300200241b8016a41186a200241b8026a41186a290100370300200220022f00f8013b01f40120022002290298023703d801200220022901b8023703b80120022006417b6a220e3602242002200d41056a360220200d280001210f200220022f0194023b01b601410021100c010b41002111200241003a00d8022006417e6a2110024002400240024002400340200c20112201460d01200241b8026a20016a200d20016a221141016a2d00003a00002002201141026a3602202002200141016a22113a00d802200220103602242010417f6a211020114120470d000b20024194026a41026a221220022d00ba023a0000200241f8016a41086a2213200941086a290000370300200241f8016a41106a2214200941106a290000370300200241f8016a41186a2215200941186a2d00003a0000200220022f01b8023b019402200220092900003703f8014100210e200c2011460d0220022800bb022116200220103602242002200d20116a220c41026a360220200c41016a2d0000221141014d0d012010210e410221100c050b0240200141ff0171450d00200241003a00d8020b4100210e410221100c040b024020110e020200020b41002111200241003a00d802200620016b417c6a21010240034020102011460d01200241b8026a20116a200c20116a220d41026a2d00003a00002002200d41036a3602202002201141016a220d3a00d802200220013602242001417f6a2101200d2111200d4120470d000b20024198026a41186a200241b8026a41186a29030037030020024198026a41106a200241b8026a41106a29030037030020024198026a41086a200241b8026a41086a290300370300200220022903b802370398022010200d6b210e410121170c030b0240201141ff0171450d00200241003a00d8020b4100210e0b410221100c020b410021172010210e0b200241b8016a41186a20024198026a41186a290300370300200241b8016a41106a20024198026a41106a290300370300200241b8016a41086a20024198026a41086a290300370300200241f4016a41026a20122d00003a0000200241d8016a41086a2013290300370300200241d8016a41106a2014290300370300200241d8016a41186a20152d00003a000020022002290398023703b801200220022f0194023b01f401200220022903f8013703d801410121102016210f0b200241b2016a41026a2201200241f4016a41026a2d00003a000020024198016a41086a2211200241d8016a41086a29030037030020024198016a41106a220d200241d8016a41106a29030037030020024198016a41186a220c200241d8016a41186a2d00003a0000200241f8006a41086a2206200241b8016a41086a290300370300200241f8006a41106a2212200241b8016a41106a290300370300200241f8006a41186a2213200241b8016a41186a290300370300200220022f01f4013b01b201200220022903d80137039801200220022903b801370378200220022f01b6013b017620104102460d03200b41016a210b200241f2006a41026a221420012d00003a0000200241d8006a41086a22152011290300370300200241d8006a41106a2211200d290300370300200241d8006a41186a220d200c2d00003a0000200241386a41086a220c2006290300370300200241386a41106a22062012290300370300200241386a41186a22122013290300370300200220022f01b2013b0172200220022903980137035820022002290378370338200220022f01763b01360240200a200228022c470d00200241286a200a4101109f01200228022821082002280230210a0b2008200a41c4006c6a220120103a00002001200f360004200141036a20142d00003a0000200120022f01723b0001200d2d00002110201129030021072015290300211820022903582119200120173a002120012019370008200141106a2018370000200141186a2007370000200141206a20103a000020012002290338370022200c29030021072006290300211820122903002119200120022f01363b00422001413a6a2019370000200141326a20183700002001412a6a20073700002002200a41016a220a360230200e2106200b2005470d000b0b2008450d022000200229022c370204200020083602000c030b200241b2016a41026a200241f4016a41026a2d00003a000020024198016a41086a200241d8016a41086a29030037030020024198016a41106a200241d8016a41106a29030037030020024198016a41186a200241d8016a41186a2d00003a0000200241f8006a41086a200241b8016a41086a290300370300200241f8006a41106a200241b8016a41106a290300370300200241f8006a41186a200241b8016a41186a290300370300200220022f01f4013b01b201200220022903d80137039801200220022903b801370378200220022f01b6013b01760b200228022c2201450d00200141c4006c450d00200810350b200241003602a0022002420137039802200241093602bc012002200241086a3602b801200220024198026a360278200241cc026a4101360200200242013702bc02200241c888c2003602b8022002200241b8016a3602c802200241f8006a41e88ac500200241b8026a10431a20023502a0024220862002350298028410060240200228029c02450d0020022802980210350b200041003602000b2004450d00200310350b200241e0026a24000f0b1044000b1045000bd20402067f047e230041f0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822030d00200041023a00000c010b200228020c210402400240200241106a2802002205450d0020032d0000220641014b0d004100210102400240024020060e020100010b41002101200241003a0068200341016a21072005417f6a2106034020062001460d02200241c8006a20016a200720016a2d00003a00002002200141016a22053a00682005210120054120470d000b200241186a41186a200241c8006a41186a290300370300200241186a41106a200241c8006a41106a290300370300200241186a41086a200241c8006a41086a29030037030020022002290348370318410121010b200241c8006a41186a200241186a41186a2903002208370300200241c8006a41106a200241186a41106a2903002209370300200241c8006a41086a200241186a41086a290300220a37030020022002290318220b370348200041196a2008370000200041116a2009370000200041096a200a3700002000200b3700010c020b200141ff0171450d00200241003a00680b20024100360220200242013703182002410936023c200220023602382002200241186a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235022042208620023502188410060240200228021c450d00200228021810350b410221010b200020013a00002004450d00200310350b200241f0006a24000ba90d03047f017e147f230041e00c6b220324002003200236021c20032001360218200341206a2002ad4220862001ad84100510c2010240024002400240200328022022040d00200041003602000c010b200328022421052003200341286a28020036023420032004360230200341106a200341306a10c40102400240024020032802100d00200328021422062003280234220141d0026e2202200220064b1bad42d0027e2207422088a70d052007a72208417f4c0d050240024020080d00410821090c010b200810332209450d050b4100210220034100360240200320093602382003200841d0026e36023c02402006450d002006417f6a21080340024002402001450d002003280230220a2d0000210b20032001417f6a220c3602342003200a41016a360230200b41014b0d00410221060240200b0e020200020b024002400240200c0d00410221060c010b200a2d0001210b20032001417e6a220c360234410221062003200a41026a36023002400240200b41014b0d0041002101024002400240200b0e020100010b200341086a200341306a10c40120032802080d022003280234200328020c220b490d02200b417f4c0d0f02400240200b0d004100210a410121010c010b200b10392201450d0f2003280234200b490d0220012003280230200b109d081a2003280234220a200b490d042003200a200b6b36023420032003280230200b6a360230200b210a0b2001450d02200bad422086200aad8421072003280234210c0b2007a7210b02400240024002400240200c450d002003280230220d2d0000210a2003200c417f6a3602342003200d41016a360230200341b00a6a200341306a10b90220032802b00a411b460d0320034180086a200341b00a6a41b002109d081a2003280234220c450d042003280230220e2d0000210d2003200c417f6a220f3602342003200e41016a360230200d41014b0d0441002106200d0e020201020b2001450d07200b450d070c040b200f4104490d02200e280001210d2003200e41056a3602302003200c417b6a220636023420064104490d02200e28000521102003200c41776a3602342003200e41096a36023041012106200d21110b2007422088a72112200341b00a6a20034180086a41b002109d081a200320032800f9073602f0072003200341f9076a41036a2800003600f3070c060b2001450d04200b450d040c010b20034180086a10ba022001450d01200b450d010b200110350b2013210a2014210b20152101410221060c020b200b200a41a4f0cb001059000b2013210a2014210b201521010b200341c0056a200341b00a6a41b002109d081a200320032800f3073600bb05200320032802f0073602b805024020064102460d00200341b00a6a200341c0056a41b002109d081a200320032800bb0536008308200320032802b8053602800820012116200b211720122118200a21192010211a2011211b200a2113200b2114200121150c020b200a2113200b2114200121150b410321060b20034188036a200341b00a6a41b002109d081a200320032800830836008303200320032802800836028003024020064103460d00200341d0006a20034188036a41b002109d081a200320032800830336004b200320032802800336024802402002200328023c470d00200341386a2002410110a70120032802382109200328024021020b2009200241d0026c6a200341d0006a41b002109d08220141c8026a20193a0000200141c4026a201a3602002001201b3602c002200120063602bc02200120183602b802200120173602b402200120163602b002200141c9026a2003280248360000200141cc026a200328004b3600002003200241016a22023602402008450d022008417f6a2108200328023421010c010b0b02402002450d00200241d0026c21022009210103400240200141bc026a2802004102460d000240200141b0026a2802002206450d00200141b4026a280200450d00200610350b200110bb020b200141d0026a2101200241b07d6a22020d000b0b200328023c2201450d01200141d0026c450d01200910350c010b20090d010b20034100360288082003420137038008200341093602c4052003200341186a3602c005200320034180086a36028803200341c40a6a4101360200200342013702b40a200341c888c2003602b00a2003200341c0056a3602c00a20034188036a41e88ac500200341b00a6a10431a2003350288084220862003350280088410060240200328028408450d0020032802800810350b200041003602000c010b2000200329023c370204200020093602000b2005450d00200410350b200341e00c6a24000f0b1045000b1044000bd2870307087f027e0b7f087e057f027e1b7f23004190116b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005411b4b0d25200141046a210720050e1c0102030405060708090a0b0c0d0e0f10111213141516171819222324010b2000411b3602000c600b2006450d5e20042d0001210520012003417e6a22083602042001200441026a360200200541094b0d5e410a2109024002400240024002400240024002400240024020050e0a00010203040506070809000b20084104490d672004280002210620012003417a6a3602042001200441066a3602002006418194ebdc034f0d67410121090c080b2002200110c40120022802000d66200728020020022802042204490d662004417f4c0d2c0240024020040d004200210a410121060c010b200410392206450d2120072802002004490d66200620012802002004109d081a200128020422032004490d2e2001200320046b3602042001200128020020046a3602002004ad210a0b2006450d66200a2004ad42208684210a410221090c070b20084108490d652004290002210a2001200341766a36020420012004410a6a360200410321090c060b200241086a200110c40120022802080d642007280200200228020c2204490d642004417f4c0d2a0240024020040d004200210a410121060c010b200410392206450d1f20072802002004490d64200620012802002004109d081a200128020422032004490d2d2001200320046b3602042001200128020020046a3602002004ad210a0b2006450d64200a2004ad42208684210a410421090c050b200241106a200110c40120022802100d63200728020020022802142204490d632004417f4c0d290240024020040d004200210a410121060c010b200410392206450d1e20072802002004490d63200620012802002004109d081a200128020422032004490d2d2001200320046b3602042001200128020020046a3602002004ad210a0b2006450d63200a2004ad42208684210a410521090c040b2008450d6220042d0002210520012003417d6a22073602042001200441036a360200200541014b0d624106210941002106024020050e020400040b20074104490d622004350003210a2001200341796a22053602042001200441076a36020020054104490d622004350007210b2001200341756a36020420012004410b6a360200200b422086200a84210a410121060c030b200241286a200110c40120022802280d61200228022c2209200728020041186e2204200420094b1bad42187e220a422088a70d27200aa72204417f4c0d270240024020040d00410421060c010b200410332206450d1c0b41002105200241003602b80c200220063602b00c2002200441186e3602b40c024002400240024002402009450d000340200241206a200110c40120022802200d05200728020020022802242204490d052004417f4c0d2d0240024020040d004100210c410121080c010b200410392208450d2220072802002004490d05200820012802002004109d081a200128020422032004490d322001200320046b3602042001200128020020046a3602002004210c0b200241186a200110c40120022802180d032007280200200228021c2203490d032003417f4c0d2d0240024020030d004100210d4101210e0c010b20031039220e450d2220072802002003490d03200e20012802002003109d081a2001280204220d2003490d332001200d20036b3602042001200128020020036a3602002003210d0b2004ad422086200cad84210a2003ad422086200dad84210b0240200520022802b40c470d00200241b00c6a2005410110970120022802b00c210620022802b80c21050b2006200541186c6a2204200e36020c2004200a37020420042008360200200441106a200b3702002002200541016a22053602b80c2009417f6a22090d000b0b2006450d6520022902b40c210a410721090c060b200e10350b200c450d010b200810350b02402005450d00200541186c21042006210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141186a2101200441686a22040d000b0b20022802b40c2201450d61200141186c450d610c600b200241386a200110c40120022802380d60200228023c22092007280200410c6e2204200420094b1bad420c7e220a422088a70d26200aa72204417f4c0d260240024020040d00410421060c010b200410332206450d1b0b41002103200241003602b80c200220063602b00c20022004410c6e3602b40c0240024002402009450d000340200241306a200110c40120022802300d03200728020020022802342204490d032004417f4c0d2a0240024020040d0041002108410121050c010b200410392205450d1f20072802002004490d03200520012802002004109d081a200128020422082004490d312001200820046b3602042001200128020020046a360200200421080b2004ad4220862008ad84210a0240200320022802b40c470d00200241b00c6a2003410110870120022802b00c210620022802b80c21030b20062003410c6c6a2204200a370204200420053602002002200341016a22033602b80c2009417f6a22090d000b0b2006450d6220022902b40c210a410821090c030b200510350b02402003450d002003410c6c21042006210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b20022802b40c2201450d602001410c6c0d5f0c600b200241c0006a200110c40120022802400d5f200728020020022802442204490d5f2004417f4c0d250240024020040d004200210a410121060c010b200410392206450d1a20072802002004490d5f200620012802002004109d081a200128020422032004490d2d2001200320046b3602042001200128020020046a3602002004ad210a0b2006450d5f200a2004ad42208684210a410921090b20004100360200200041106a200a3702002000410c6a2006360200200041086a2009360200200041186a200241e00e6a419802109d081a0c5f0b2006450d5a20042d0001210520012003417e6a22063602042001200441026a360200200541044b0d5a02400240024002400240024002400240024020050e050001020304000b200241e00e6a200110c80520022802e00e2204450d622004411876210f20022902e40e220aa722034118762110200a422088a7210d41012111410021120c050b20064102490d6120042f0002210520012003417c6a3602042001200441046a360200200241e00e6a200110b90220022802e00e2101200241b00c6a200241e00e6a41047241ac02109d081a2001411b460d61200241e00e6a200241b00c6a41ac02109d081a41b002103322040d030c620b20064102490d6020042f0002210520012003417c6a3602042001200441046a360200200241e00e6a200110c30120022802e00e2204450d6020022802e40e2103024020072802002206450d00200241e80e6a280200210d200128020022092d0000210720012006417f6a22083602042001200941016a360200200741014b0d004200210a4100210e0240024020070e020100010b20084104490d012009350001210a20012006417b6a22073602042001200941056a36020020074104490d01200928000521132001200641776a3602042001200941096a360200200a422086210a4101210e0b200241e00e6a200110b90220022802e00e2106200241b00c6a200241e00e6a41047241ac02109d081a2006411b460d06200241e00e6a200241b00c6a41ac02109d081a41b00210332201450d62200a200ead84210a20012006360200200141046a200241e00e6a41ac02109d081a200341187621102004411876210f20054180fe03714108762112410321110c040b200341ffffff3f71450d600c5f0b20064102490d5f20042f0002210820012003417c6a3602042001200441046a360200200241e00e6a200110c30120022802e00e2206450d5f20022802e40e2109024020072802002204450d00200241e80e6a2802002107200128020022052d0000210320012004417f6a220d3602042001200541016a360200200341014b0d004100210e0240024020030e020100010b200d4104490d012005280001210c20012004417b6a22033602042001200541056a36020020034104490d01200528000521142001200441776a220d3602042001200541096a3602004101210e0b41002103200241003a00800f200d417f6a2104024003402004417f460d01200241e00e6a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00800f2004417f6a21042005210320054120470d000b200220022800e30e3600c30b200220022802e00e22153602c00b20022900e70e220aa72203411876211020022800c30b2204411876210f20022f00c10b2205410876211220022900f70e220b422088a72101200a422088a7210d200241ef0e6a290000210a200241ff0e6a2d00002116200ba72113410421110c050b0240200341ff0171450d00200241003a00800f0b200941ffffff3f71450d60200610350c600b200941ffffff3f71450d5f200610350c5f0b20064102490d5e20042f0002210820012003417c6a3602042001200441046a360200200241e00e6a200110c30120022802e00e2206450d5e20022802e40e21090240200728020022034104490d00200241e80e6a28020021072001280200220d280000210e20012003417c6a22043602042001200d41046a36020020044104490d00200d280004210c2001200341786a22143602042001200d41086a36020041002104200241003a00800f200341776a21030240034020142004460d01200241e00e6a20046a200d20046a220541086a2d00003a0000200120033602042001200541096a3602002002200441016a22053a00800f2003417f6a21032005210420054120470d000b200220022800e30e3600c30b200220022802e00e22153602c00b20022801c20b2212410876210420022900f70e2217422088a7210120022900e70e220b422088a7210d200b421888a72110200241ef0e6a290000210a200241ff0e6a2d0000211620022d00c10b210520022d00c60b210f2017a72113200ba72103410521110c040b0240200441ff0171450d00200241003a00800f0b200941ffffff3f71450d5f200610350c5f0b200941ffffff3f71450d5e200610350c5e0b20042001360200200441046a200241e00e6a41ac02109d081a2004411876210f20054180fe037141087621122002280288092113200228028408210c200228028808211441022111410021100b0b200020153a0005200020113a0004200041013602002000413c6a2014360200200041386a200c360200200041346a200e360200200041306a20073602002000412c6a2009360200200041286a2006360200200041266a20083b0100200041246a20163a0000200041206a20013602002000411c6a2013360200200041146a200a370200200041106a200d3602002000410c6a2010411874200341ffffff077172360200200041086a200f411874200441ffffff077172360200200041066a2012410874200541ff0171723b0100200041c0006a20024190066a41f001109d081a0c5f0b200341ffffff3f710d590c5a0b02402006450d0020012003417e6a3602042001200441026a3602000b2000411b3602000c5d0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241c8006a20011091062002290348a70d002002290350210a20004103360200200041086a200a370300200041106a200241e00e6a41a002109d081a0c5d0b2000411b3602000c5c0b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241b00c6a200110cf0320022802b00c2201450d00200041086a20022902b40c3702002000200136020420004104360200200041106a200241e00e6a41a002109d081a0c5c0b2000411b3602000c5b0b02402006450d0020042d0001210520012003417e6a22063602042001200441026a360200200541034b0d00024002400240024020050e0400010203000b20064104490d032004280002210920012003417a6a3602042001200441066a3602004200210a410121060c570b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200220022800b30c3600c30b200220022802b00c22053602c00b200320076b2203417e6a4104490d03200241b00c6a410f6a290000210b200241cf0c6a310000211820022900b70c211720022900c70c210a20022f00c10b210820022800c30b210941022106200420076a220441026a280000210e20012003417a6a3602042001200441066a36020020022017370380082002200b370388082002200a37039008200a423888201842ff018342088684a721042017421888a721012017420888a7210320024180086a410f6a290000210b200229008708210a2017a721070c580b200541ff0171450d02200241003a00d00c0c020b20064104490d012004280002210920012003417a6a3602042001200441066a3602004200210a410321060c550b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200241e80b6a41106a200241b00c6a410f6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022800b30c3600c30b200220022802b00c22053602c00b200220022d00c60b3a00e80b200220022900b70c220ba722063b00e90b200220064110763a00eb0b2002200b421888200a422886843702ec0b41042106200320076b2203417e6a4104490d01200241cf0c6a310000210b20022900c70c210a20022d00c10b210c20022801c20b2108200420076a220441026a280000210e20012003417a6a3602042001200441066a36020020024180096a41086a200241e80b6a410172220141086a2900003703002002200129000022173703800920022d00e80b41187420084108767221092002200a37039009200a423888200b42ff018342088684a72104200c200841087472210820024180096a410f6a290000210b200228008309210120022f0081092103200229008709210a2017a721070c560b200541ff0171450d00200241003a00d00c0b2000411b3602000c5a0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541034b0d00024002400240024020050e0400010203000b200241b00c6a200110920620022d00b00c4102460d03200241c40c6a290200210a200241bc0c6a290200210b200241cc0c6a2902002117200241b80c6a280200210420022802b40c210320022802b00c2105200241d8006a200110f60120022802580d03200241e8006a290300211841012101200229036021190c550b200241b00c6a200110920620022d00b00c4102460d02200241c40c6a290200210a200241bc0c6a290200210b200241cc0c6a2902002117200241b80c6a280200210420022802b40c210320022802b00c210520024188016a200110f601200229038801a70d0220024188016a41106a29030021182002290390012119200241f0006a200110f6012002290370a70d02200241f0006a41106a290300211a2002290378211b410221010c540b200241b00c6a200110920620022d00b00c4102460d01200241c40c6a290200210a200241bc0c6a290200210b200241cc0c6a2902002117200241b00c6a41086a2206280200210420022802b40c210320022802b00c2105200241b00c6a200110920620022d00b00c4102460d0120024190066a41206a2207200241b00c6a41206a28020036020020024190066a41186a2209200241b00c6a41186a29030037030020024190066a41106a2208200241b00c6a41106a29030037030020024190066a41086a2006290300370300200220022903b00c37039006200241a0016a200110f60120022903a001a70d01200241a0016a41106a290300211c20022903a801211d2009290300211a2008290300211b20024198066a29030021182007350200211e2002290390062119410321010c530b200241b00c6a200110920620022d00b00c4102460d00200241c40c6a290200210a200241bc0c6a290200210b200241cc0c6a2902002117200241b80c6a280200210420022802b40c210320022802b00c2105200241b8016a200110f60120022802b8010d00200241c8016a29030021184104210120022903c00121190c520b2000411b3602000c590b2006450d4d20042d0001210520012003417e6a221f3602042001200441026a360200200541174b0d4d4104210d02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e1800010267030405060708090a0b0c0d0e0f10111213151617000b200241e00e6a200110920620022d00e00e4102460d64200241fc0e6a290200210b200241f40e6a290200210a200241ec0e6a290200211920022902e40e211e20022802e00e2109200241d0016a200110f60120022903d001a70d6420072802002204450d64200241e0016a290300211820022903d8012117200128020022032d0000210e20012004417f6a3602044101210d2001200341016a360200200e41024b0d64200241a80b6a41106a200241b00c6a41106a290200370300200241a80b6a41086a200241b00c6a41086a290200370300200241900b6a41086a20024180096a41086a290300370300200241900b6a41106a20024180096a41106a290300370300200241f80a6a41086a20024180086a41086a290200370300200241f80a6a41106a20024180086a41106a290200370300200220022902b00c3703a80b20022002290380093703900b20022002290280083703f80a200241e00a6a41106a200241980c6a41106a290300370300200241e00a6a41086a200241980c6a41086a290300370300200220022903980c3703e00a201e422088a72106200b422088a7210f200b421088a72120200b420888a721212019422088a72114201ea721082019a7210c0c660b200241e8016a200110f60120022903e801a70d63200241e8016a41106a290300210a20022903f001210b200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a200b422088a72106200a422088a72114200ba72108200aa7210c4102210d0c650b20024180026a200110f601200229038002a70d6220024180026a41106a290300210a200229038802210b200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a200b422088a72106200a422088a72114200ba72108200aa7210c4103210d0c640b20024198026a200110c4012002280298020d61200228029c022109200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a4105210d0c620b200241a0026a200110c40120022802a0020d6020022802a4022203200728020041246e2204200420034b1bad42247e220a422088a70d30200aa72204417f4c0d300240024020040d00410421090c010b200410332209450d250b41002106200241003602880c200220093602800c2002200441246e22083602840c024002402003450d0041002106200241e00e6a41206a2114200241e00e6a41106a21130340200241e00e6a200110920620022802840c210420022d00e00e22054102460d022014310000210a2013290300210b20022903f80e211720022903e80e211820022f01820f210720022d00810f210820022802e40e210e20022f01e20e210c20022d00e10e210d024020062004470d00200241800c6a20064101108d0120022802800c210920022802880c21060b2009200641246c6a220420073b0022200420083a0021200420173700182004200e3600042004200c3b00022004200d3a0001200420053a0000200441206a200a3c000020042018370008200441106a200b3700002002200641016a22063602880c2003417f6a22030d000b20022802840c21080b2009450d61200241a80b6a41106a200241b00c6a41106a290200370300200241a80b6a41086a200241b00c6a41086a290200370300200241900b6a41086a20024180096a41086a290300370300200241900b6a41106a20024180096a41106a290300370300200241f80a6a41086a20024180086a41086a290200370300200241f80a6a41106a20024180086a41106a290200370300200220022902b00c3703a80b20022002290380093703900b20022002290280083703f80a200241e00a6a41106a200241980c6a41106a290300370300200241e00a6a41086a200241980c6a41086a290300370300200220022903980c3703e00a4106210d0c630b2004450d60200441246c0d5d0c600b4107210d0c610b201f450d5e20042d0002210e20012003417d6a3602042001200441036a360200200e41024b0d5e200241a80b6a41106a200241e00e6a41106a2901003703004108210d200241a80b6a41086a200241e00e6a41086a290100370300200241900b6a41086a200241b00c6a41086a290100370300200241900b6a41106a200241b00c6a41106a290100370300200241f80a6a41086a20024180096a41086a290100370300200241f80a6a41106a20024180096a41106a290100370300200220022901e00e3703a80b200220022901b00c3703900b20022002290180093703f80a200241e00a6a41106a20024180086a41106a290100370300200241e00a6a41086a20024180086a41086a29010037030020022002290180083703e00a410021144100210c410021060c600b200241e00e6a200110920620022d00e00e4102460d5d200241d00b6a41086a2201200241fc0e6a280200360200200241a80b6a41086a200241b00c6a41086a290200370300200241a80b6a41106a200241b00c6a41106a2902003703002002200241f40e6a290200220a3703d00b200220022902b00c3703a80b200241800f6a280200210f200241ec0e6a290200211720022802e00e210920022902e40e21182001310000210b20022f01da0b212020022d00d90b2121200241900b6a41106a20024180096a41106a290300370300200241900b6a41086a20024180096a41086a29030037030020022002290380093703900b200241f80a6a41106a20024180086a41106a290200370300200241f80a6a41086a20024180086a41086a29020037030020022002290280083703f80a200241e00a6a41106a200241980c6a41106a290300370300200241e00a6a41086a200241980c6a41086a290300370300200220022903980c3703e00a2018422088a721062017422088a721142018a721082017a7210c4109210d0c5f0b200241a8026a200110c40120022802a8020d5c20022802ac022109200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a410a210d0c5d0b410b210d0c5d0b410c210d0c5c0b200241980c6a200110c30120022802980c2209450d59200241a80b6a41086a200241e00e6a41086a290200370300200241a80b6a41106a200241e00e6a41106a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200229029c0c210a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a200a422088a72106200aa72108410d210d0c5b0b41002105200241003a00800f2003417e6a21072003417d6a21030240034020072005460d01200241e00e6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00800f2003417f6a21032006210520064120470d000b20024198096a2201200241ff0e6a2d00003a000020024180096a41106a200241f70e6a290000220a370300200241a80b6a41086a200241b00c6a41086a290000370300200241a80b6a41106a200241b00c6a41106a290000370300200220022900b00c3703a80b200241ef0e6a290000211720022800e30e210920022f00e10e212220022d00e00e210e20022900e70e21182001310000210b200241900b6a41106a20024180086a41106a290000370300200241900b6a41086a20024180086a41086a29000037030020022002290080083703900b200241f80a6a41106a200241980c6a41106a290000370300200241f80a6a41086a200241980c6a41086a290000370300200220022900980c3703f80a200241e00a6a41106a200241800c6a41106a290000370300200241e00a6a41086a200241800c6a41086a290000370300200220022900800c3703e00a2018422088a721062017422088a721142018a721082017a7210c410e210d0c5b0b200541ff0171450d58200241003a00800f0c580b410f210d0c590b201f4104490d562004280002210920012003417a6a3602042001200441066a360200200241b0026a200110c40120022802b0020d56200728020020022802b4024102742204490d562004417f4c0d260240024020040d004200210a410121080c010b200410392208450d1b20072802002004490d30200820012802002004109d081a200128020422032004490d2f2001200320046b3602042001200128020020046a3602002004ad210a0b2008450d560240200a2004ad42208684220a422088a722010d00200aa721010c550b024020082001724103710d00200aa722014103710d0020014102762206450d55200a422288a7210c0c560b200aa7450d56200810350c560b201f4104490d552004280002210920012003417a6a3602042001200441066a360200200241b8026a200110c40120022802b8020d5520022802bc02220d200728020041246e22042004200d4b1bad42247e220a422088a70d25200aa72204417f4c0d250240024020040d00410421080c010b200410332208450d1a0b4100210c200241003602880c200220083602800c2002200441246e22063602840c024002400240200d450d00200241ef0e6a2113200241e00e6a411f6a210f200241f40b6a2110200241f00b6a21114100210c410021140340200241003a00800f201441016a211420072802002106417f210341002104034020062004460d03200241e00e6a20046a2001280200220e2d00003a00002001200620036a3602042001200e41016a3602002002200441016a22053a00800f2003417f6a21032005210420054120470d000b200220022800e30e3600c30b200220022802e00e3602c00b200620056b22044104490d032013290000210a200f310000211720022900e70e210b20022900f70e2118200e28000121032001200e41056a36020020012004417c6a360204200241e80b6a41106a2205200a4238883c00002010200a4218883e0200200220022d00c60b3a00e80b2002200ba722043b00e90b200220044110763a00eb0b2002200b421888200a422886843702ec0b20022d00c00b210620022d00c10b210e20022801c20b21120240200c20022802840c470d00200241800c6a200c4101108d0120022802800c210820022802880c210c0b2008200c41246c6a220420123601022004200e3a0001200420063a000020052d000021052011290200210a20022902e80b210b2004411f6a20173c0000200420183700172004200b370106200420033602202004410e6a200a370100200441166a20053a00002002200c41016a220c3602880c2014200d470d000b20022802840c21060b2008450d57200241a80b6a41106a200241b00c6a41106a290200370300200241a80b6a41086a200241b00c6a41086a290200370300200241900b6a41086a20024180096a41086a290200370300200241900b6a41106a20024180096a41106a290200370300200241f80a6a41086a20024180086a41086a290200370300200241f80a6a41106a20024180086a41106a290200370300200220022902b00c3703a80b20022002290280093703900b20022002290280083703f80a200241e00a6a41106a200241980c6a41106a290200370300200241e00a6a41086a200241980c6a41086a290200370300200220022902980c3703e00a4111210d0c590b200441ff0171450d00200241003a00800f0b20022802840c2201450d55200141246c450d55200810350c550b201f4104490d542004280002210920012003417a6a3602042001200441066a360200200241a80b6a41086a20024180096a41086a290200370300200241a80b6a41106a20024180096a41106a290200370300200241900b6a41086a200241980c6a41086a290300370300200241900b6a41106a200241980c6a41106a29030037030020022002290280093703a80b200220022903980c3703900b20022d00d90b212120022f01da0b212020022802dc0b210f200241f80a6a41106a200241800c6a41106a290200370300200241f80a6a41086a200241800c6a41086a290200370300200241e00a6a41086a200241e80b6a41086a290300370300200241e00a6a41106a200241e80b6a41106a290300370300200220022902800c3703f80a200220022903e80b3703e00a200241c80c6a290300211a20022903c00c211b4112210d0c030b41002105200241003a00800f2003417e6a2109417d21060240034020092005460d01200241e00e6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00800f2006417f6a21062007210520074120470d000b20024180096a41186a2205200241ff0e6a2d00003a000020024180096a41106a200241f70e6a290000220a370300200320076b2203417e6a4104490d54200241ef0e6a290000211720022800e30e210920022f00e10e212220022d00e00e210e20022900e70e21182005310000210b200420076a220441026a280000210f20012003417a6a3602042001200441066a360200200241a80b6a41086a200241980c6a41086a290200370300200241a80b6a41106a200241980c6a41106a290200370300200241900b6a41086a200241800c6a41086a290300370300200241900b6a41106a200241800c6a41106a290300370300200241f80a6a41086a200241e80b6a41086a290200370300200241f80a6a41106a200241e80b6a41106a290200370300200220022902980c3703a80b200220022903800c3703900b200220022902e80b3703f80a200241e00a6a41106a200241d00b6a41106a290300370300200241e00a6a41086a200241d00b6a41086a290300370300200220022903d00b3703e00a2018422088a721062017422088a72114200241b00c6a41186a290300211a20022903c00c211b2018a721082017a7210c4113210d0c560b200541ff0171450d53200241003a00800f0c530b200241c0026a200110f60120022903c002a70d52200241c0026a41106a290300210a20022903c802210b200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290300370300200241e00a6a41086a20024180086a41086a29030037030020022002290380083703e00a200b422088a72106200a422088a72114200ba72108200aa7210c4114210d0c540b200241d8026a200110c40120022802d8020d5120022802dc022109200241a80b6a41086a20024180096a41086a290200370300200241a80b6a41106a20024180096a41106a290200370300200241900b6a41086a20024180086a41086a290300370300200241900b6a41106a20024180086a41106a290300370300200241f80a6a41086a200241980c6a41086a290200370300200241f80a6a41106a200241980c6a41106a29020037030020022002290280093703a80b20022002290380083703900b200220022902980c3703f80a20022802f40b210f20022f01f20b212020022d00f10b2121200241e00a6a41106a200241800c6a41106a290300370300200241e00a6a41086a200241800c6a41086a290300370300200220022903800c3703e00a200241c80c6a290300211a20022903c00c211b4115210d0b410021144100210c41002106410021080c520b41002105200241003a00800f2003417e6a21072003417d6a21030240034020072005460d01200241e00e6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00800f2003417f6a21032006210520064120470d000b20024198096a2201200241ff0e6a2d00003a000020024180096a41106a200241f70e6a290000220a370300200241a80b6a41086a200241b00c6a41086a290000370300200241a80b6a41106a200241b00c6a41106a290000370300200220022900b00c3703a80b200241ef0e6a290000211720022800e30e210920022f00e10e212220022d00e00e210e20022900e70e21182001310000210b200241900b6a41106a20024180086a41106a290000370300200241900b6a41086a20024180086a41086a29000037030020022002290080083703900b200241f80a6a41106a200241980c6a41106a290000370300200241f80a6a41086a200241980c6a41086a290000370300200220022900980c3703f80a200241e00a6a41106a200241800c6a41106a290000370300200241e00a6a41086a200241800c6a41086a290000370300200220022900800c3703e00a2018422088a721062017422088a721142018a721082017a7210c4116210d0c520b200541ff0171450d4f200241003a00800f0c4f0b200241e0026a200110c40120022802e0020d4e200728020020022802e4024101742204490d4e2004417f4c0d1e0240024020040d004200210a410121090c010b200410392209450d1320072802002004490d4c200920012802002004109d081a200128020422032004490d292001200320046b3602042001200128020020046a3602002004ad210a0b2009450d4e02402004ad422086200a84220a422088a722040d00200aa721040c4a0b024020092004724101710d00200aa722044101710d0020044101762208450d4a200a422188a721060c4b0b200aa70d4b0c4e0b200241e8026a200110c40120022802e8020d4d200728020020022802ec024101742204490d4d2004417f4c0d1d0240024020040d004200210a410121090c010b200410392209450d1220072802002004490d4b200920012802002004109d081a200128020422032004490d292001200320046b3602042001200128020020046a3602002004ad210a0b2009450d4d02402004ad422086200a84220a422088a722040d00200aa721040c470b024020092004724101710d00200aa722044101710d0020044101762208450d47200a422188a721060c480b200aa70d4a0c4d0b2006450d2a20042d0001210520012003417e6a3602042001200441026a360200200541014b0d2a410021040240024020050e020001000b200241b00c6a200110c20220022d00b00c4101460d2b20024190066a200241b00c6a410172418001109d081a200241f0026a200110c40120022802f0020d2b200728020020022802f4022203490d2b2003417f4c0d1d0240024020030d004200210a410121040c010b200310392204450d1220072802002003490d2b200420012802002003109d081a200128020422052003490d2a2001200520036b3602042001200128020020036a3602002003ad210a0b2004450d2b200a2003ad42208684210a20024180096a20024190066a418001109d081a0b20024180086a20024180096a418001109d081a200041086a200a3702002000200436020420004108360200200041106a20024180086a418001109d081a20004190016a200241e00e6a41a001109d081a0c570b02402006450d0020042d0001210520012003417e6a22233602042001200441026a3602002005411c4b0d00410e2113410021090240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e1d000102030405060708090a0b0c610d0e0f101112131415161718191a1b000b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b200241bf0c6a2900002119200241cf0c6a310000210a20022900b70c210b20022900c70c211e200241c50b6a2d0000210420022d00c10b210820022d00c20b210e20022d00c60b210d20022f00c30b2103200241f8026a200110f60120022903f802a70d1d200241f8026a41106a29030021182002290380032117201e422088200a42ff018342208684210a200320044110747241ffffff077121092019420888a721122019421088a7210f2019422088a72111201ea721102019a72116410121130c610b200541ff0171450d1c200241003a00d00c0c1c0b20024190036a200110c4012002280290030d1b2002280294032209411876210d410221130c5d0b20024198036a200110c4012002280298030d1a200228029c032109200241b00c6a200110ca0220022d00b00c4102460d1a2009411876210d200241c40c6a350200200241b00c6a41186a31000042208684210a200241d00c6a2903002117200241cc0c6a2802002114200241ca0c6a2f01002115200241c90c6a2d0000210c200241c00c6a2802002110200241bc0c6a2802002111200241ba0c6a2f0100210f200241b90c6a2d00002112200241b80c6a2d0000211620022903b00c210b42002118410321134100210e0c5e0b200241a0036a200110c40120022802a0030d1920022802a4032109200241b00c6a200110ca0220022d00b00c4102460d192009411876210d200241c40c6a350200200241b00c6a41186a31000042208684210a200241d00c6a2903002117200241cc0c6a2802002114200241ca0c6a2f01002115200241c90c6a2d0000210c200241c00c6a2802002110200241bc0c6a2802002111200241ba0c6a2f0100210f200241b90c6a2d00002112200241b80c6a2d0000211620022903b00c210b42002118410421134100210e0c5d0b20234104490d182004280002210920012003417a6a3602042001200441066a3602002009411876210d410521130c5a0b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116410621130c5c0b200541ff0171450d17200241003a00d00c0c170b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116410721130c5b0b200541ff0171450d16200241003a00d00c0c160b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116410821130c5a0b200541ff0171450d15200241003a00d00c0c150b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b200320076b2203417e6a4104490d15200241c50b6a2d0000210920022f00c30b210c200241bf0c6a290000210a200241cf0c6a310000211920022900b70c210b20022900c70c211820022d00c10b210820022d00c20b210e20022d00c60b210d200420076a220441026a280000211420012003417a6a22053602042001200441066a220736020020054104490d15200a422088a72111200a421088a7210f200a420888a72112200aa72116200735000021172001200341766a36020420012004410a6a3602002018422088201942ff018342208684210a200c20094110747241ffffff077121092018a7211042002118410921130c590b200541ff0171450d14200241003a00d00c0c140b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116410a21130c580b200541ff0171450d13200241003a00d00c0c130b200241a8036a200110c40120022802a8030d1220022802ac032209411876210d410b21130c540b20234104490d112004280002210920012003417a6a3602042001200441066a3602002009411876210d410c21130c530b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116410d21130c550b200541ff0171450d10200241003a00d00c0c100b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109410f2113200241b00c6a410f6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a721160c540b200541ff0171450d0f200241003a00d00c0c0f0b41002105200241003a00d00c2003417e6a2108417d21070240034020082005460d01200241b00c6a20056a200420056a220641026a2d00003a00002001200320076a3602042001200641036a3602002002200541016a22093a00d00c2007417f6a21072009210520094120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b2003417e6a2009460d0f200241c50b6a2d0000211420022f00c30b2110200241bf0c6a290000210a200241cf0c6a310000211e20022900b70c210b20022900c70c211920022d00c10b210820022d00c20b210e20022d00c60b210d200420096a220441026a2d0000210c2001200320076a22053602042001200441036a360200200c41064b0d0f4110211320054110490d0f200a422088a72111200a421088a7210f200a420888a72112200aa721162004410b6a2900002118200441036a29000021172001200320096b416d6a3602042001200441136a3602002019422088201e42ff018342208684210a201020144110747241ffffff077121092019a721100c530b200541ff0171450d0e200241003a00d00c0c0e0b411121130c500b411221130c4f0b200241b0036a200110c40120022802b0030d0b200728020020022802b4032204490d0b2004417f4c0d270240024020040d004200210a410121090c010b200410392209450d1c20072802002004490d0b200920012802002004109d081a200128020422032004490d372001200320046b3602042001200128020020046a3602002004ad210a0b2009450d0b200a2004ad42208684210b2009411876210d411321134100210e0c4f0b200241b8036a200110c40120022802b8030d0a200728020020022802bc032204490d0a2004417f4c0d260240024020040d004200210a410121090c010b200410392209450d1b20072802002004490d0a200920012802002004109d081a200128020422032004490d372001200320046b3602042001200128020020046a3602002004ad210a0b2009450d0a200a2004ad42208684210b2009411876210d411421134100210e0c4e0b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022f00c30b200241c50b6a2d0000411074722109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c10b210820022d00c20b210e20022d00c60b210d2018a721102017a72116411521130c4e0b200541ff0171450d09200241003a00d00c0c090b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20022800c30b2209411876210d20022f00c10b2208410876210e200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b2018a721102017a72116411621130c4d0b200541ff0171450d08200241003a00d00c0c080b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b20022900c70c2218422088200241cf0c6a31000042208684210a20064180fe0371410876210820022801c20b220e4108762109200241bf0c6a2900002217422088a721112017421088a7210f2017420888a7211220022900b70c210b20022d00c60b210d2018a721102017a72116411721130c4c0b200541ff0171450d07200241003a00d00c0c070b20234104490d062004280002210920012003417a6a3602042001200441066a360200411821132009411876210d0c480b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b20024198086a200241cf0c6a310000220a3c0000200220022800b30c3600c30b200220022802b00c22063602c00b200220022900c70c221837039008200220022900b70c220b370380082002200241bf0c6a290000221737038808200320076b2203417e6a4104490d06200241c50b6a2d0000210520022f00c30b210920022d00c10b210820022d00c20b210e20022d00c60b210d200420076a220441026a280000211420012003417a6a3602042001200441066a3602002018422088200a42ff018342208684210a200920054110747241ffffff077121092017422088a72111201742ffffffff0f832219421088a7210f2019420888a721122018a721102017a72116411921130c4a0b200541ff0171450d05200241003a00d00c0c050b41002105200241003a00d00c2003417e6a2109417d21070240034020092005460d01200241b00c6a20056a200420056a220641026a2d00003a00002001200320076a3602042001200641036a3602002002200541016a220e3a00d00c2007417f6a2107200e2105200e4120470d000b200220022800b30c3600c30b200220022802b00c22063602c00b2003417e6a200e460d05200241bf0c6a2900002119200241cf0c6a310000210a20022900b70c210b20022900c70c211e20022f00c10b210820022800c30b21092004200e6a220441026a2d0000210c2001200320076a22053602042001200441036a360200200c41064b0d0520054110490d052004410b6a2900002118200441036a290000211720012003200e6b416d6a3602042001200441136a360200201e422088200a42ff018342208684210a2009411876210d20084180fe0371410876210e2019422088a721112019421088a7210f2019420888a72112201ea721102019a72116411a21130c490b200541ff0171450d04200241003a00d00c0c040b411b21130c460b20234104490d022004280002210920012003417a6a3602042001200441066a3602002009411876210d411c21130c440b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200241e80b6a41106a200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022800b30c3600c30b200220022802b00c22063602c00b200220022d00c60b3a00e80b200220022900b70c220ba722053b00e90b200220054110763a00eb0b2002200b421888200a422886843702ec0b200320076b2203417e6a4104490d02200241cf0c6a310000210a20022900c70c211720022d00c10b210820022801c20b210e200420076a220441026a280000211420012003417a6a3602042001200441066a36020020024180096a41086a200241e80b6a410172220141086a290000220b3703002017422088200a42ff018342208684210a200e4108762109200ba721162001290000210b20022d00e80b210d20022d008909211220022f018a09210f200228028c0921112017a72110411d21130c460b200541ff0171450d01200241003a00d00c0c010b200910350b2000411b3602000c560b200241b00c6a2001109306024020022d00b00c4106460d0020024190066a41286a200241b00c6a41286a290300220a37030020024190066a41206a200241b00c6a41206a290300220b37030020024190066a41186a200241b00c6a41186a290300221737030020024190066a41106a200241b00c6a41106a290300221837030020024190066a41086a200241b00c6a41086a2903002219370300200220022903b00c221e370390062000410a3602002000201e3702042000410c6a2019370200200041146a20183702002000411c6a2017370200200041246a200b3702002000412c6a200a370200200041346a200241e00e6a41fc01109d081a0c560b2000411b3602000c550b200241b00c6a2001109306024020022d00b00c4106460d0020024190066a41286a200241b00c6a41286a290300220a37030020024190066a41206a200241b00c6a41206a290300220b37030020024190066a41186a200241b00c6a41186a290300221737030020024190066a41106a200241b00c6a41106a290300221837030020024190066a41086a200241b00c6a41086a2903002219370300200220022903b00c221e370390062000410b3602002000201e3702042000410c6a2019370200200041146a20183702002000411c6a2017370200200041246a200b3702002000412c6a200a370200200041346a200241e00e6a41fc01109d081a0c550b2000411b3602000c540b2006450d3d20042d0001210520012003417e6a360204410221032001200441026a360200200541054b0d3d02400240024002400240024020050e06000501020304000b200241b00c6a200110c30120022802b00c2204450d42200241b80c6a280200210720022802b40c2106200241c0036a200110f601024020022903c003a70d00200241d0036a290300211720022903c803210b410121030c050b200641ffffff3f71450d42200410350c420b200241b00c6a200110920620022d00b00c4102460d41200241c40c6a2902002117200241bc0c6a290200210b200241cc0c6a290200210a200241b80c6a280200210720022802b40c210620022802b00c2104410321030c030b410421030c020b410521030c010b200241b00c6a200110920620022d00b00c4102460d3e200241c40c6a2902002117200241bc0c6a290200210b200241cc0c6a290200210a200241b80c6a280200210720022802b40c210620022802b00c2104410621030b2000410c360200200041206a2017370200200041186a200b370200200041286a200a370200200041146a2007360200200041106a20063602002000410c6a2004360200200041086a2003360200200041306a200241e00e6a418002109d081a0c530b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541064b0d004200211941072106410021074200211c4200211b4200211a4200210b420021244200212502400240024002400240024020050e0700010203040542000b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200241e80b6a41106a200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022800b30c3600c30b200220022802b00c22083602c00b200220022900b70c220ba722013b00e90b200220014110763a00eb0b2002200b421888200a422886843702ec0b20022900c70c220b422088200241cf0c6a31000042208684210a20022801c20b2209410876210720022d00c10b210e20022d00c60b210c200241f10b6a290000211820022900e90b2117200ba7211142002119410121060c400b200541ff0171450d05200241003a00d00c0c050b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200241e80b6a41106a2201200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e020020024190066a41106a20012d00003a0000200220022900b70c220b421888200a422886843702ec0b20024190066a41086a200241e80b6a41086a290200370300200220022800b30c3600c30b200220022d00c60b3a00e80b2002200ba722013b00e90b200220014110763a00eb0b200220022802b00c22083602c00b200220022902e80b3703900620022d00c10b210e20022801c20b210920022900c70c210b200241a9066a200241cf0c6a310000220a3c00002002200b3700a106200b422088200a42208684210a2009410876210720024199066a2900002118200229009106211720022d009006210c200ba7211142002119410221060c3f0b200541ff0171450d04200241003a00d00c0c040b41002105200241003a00d00c410220036b21092003417d6a2106024002400340200920056a450d01200241b00c6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200241e80b6a41106a200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022802b00c22083602c00b200220022800b30c3600c30b200220022900b70c220ba722053b00e90b200220054110763a00eb0b2002200b421888200a422886843702ec0b200241cf0c6a310000210a20022900c70c210b20022d00c10b210e20022d00c60b210c20022801c20b2109200241f10b6a290000211820022900e90b211741002105200241003a00d00c200420076a210d200720036b41026a2103200941087621070340200320056a450d02200241b00c6a20056a200d20056a220441026a2d00003a0000200120063602042001200441036a3602002002200541016a22043a00d00c2006417f6a21062004210520044120470d000b200241e80b6a41106a200241bf0c6a29000022194238883c0000200241f40b6a20194218883e0200200220022800b30c3600c30b200220022802b00c22103602c00b200220022900b70c221ea722013b00e90b200220014110763a00eb0b2002201e4218882019422886843702ec0b20022d00c60b41187420022801c20b2201410876722113200b422088200a42ff018342208684210a200141087420022d00c10b72210f20022900e90b221e42ffffffff0f832119201e42808080807083211b200241f10b6a290000221e42ffffffff0f832124201e428080808070832125200241cf0c6a310000211d20022900c70c211e200ba721114200211c410321064200211a4200210b0c410b200541ff0171450d04200241003a00d00c0c040b200541ff0171450d03200241003a00d00c0c030b200241b00c6a200110c30120022802b00c2207450d022007411876210c20023502840920024188096a31000042208684210a20022902b40c211720022d008909211020022f018a09210f20022d008908210d20022f018a082114420021184104210641002109420021190c3d0b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22083602c00b20022900c70c220b422088200241cf0c6a31000042208684210a20022801c20b22094108762107200241bf0c6a290000211820022900b70c211720022d00c10b210e20022d00c60b210c200ba7211142002119410521060c3c0b200541ff0171450d01200241003a00d00c0c010b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200241e80b6a41106a200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022900b70c220b421888200a422886843702ec0b20024180096a41086a2201200241f10b6a290000370300200220022800b30c3600c30b2002200ba722043b00e90b200220044110763a00eb0b200220022802b00c22083602c00b200220022d00c60b220c3a00e80b200220022900e90b3703800920022d00c10b210e20022801c20b210920022900c70c210b20024198096a200241cf0c6a310000220a3c00002002200b37039009200b422088200a42208684210a20094108762107200129030021182002290380092117200ba7211142002119410621060c3b0b200541ff0171450d00200241003a00d00c0b2000411b3602000c520b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241d8036a200110c40120022802d8030d0020022802dc0321012000410e36020020002001360204200041086a200241e00e6a41a802109d081a0c520b2000411b3602000c510b02402006450d0020042d0001210520012003417e6a3602042001200441026a36020020050d00200241e0036a200110c40120022802e0030d00200728020020022802e4032204490d002004417f4c0d1602400240024020040d004200210a410121030c010b200410392203450d0c20072802002004490d01200320012802002004109d081a200128020422052004490d292001200520046b3602042001200128020020046a3602002004ad210a0b2003450d01200020033602042000410f360200200041086a200a2004ad42208684370200200041106a200241e00e6a41a002109d081a0c520b200310350b2000411b3602000c500b2006450d3320042d0001210520012003417e6a3602042001200441026a360200200541074b0d3302400240024002400240024002400240024020050e080001020304050607000b200241e8036a200110f60120022903e803a70d3b200241f8036a290300210a20022903f003210b200241b00c6a200110920620022d00b00c4102460d3b200241d80b6a2205200241cc0c6a2802003602002002200b3703980c2002200a3703a00c20022902b40c2219421888200241bc0c6a290200220b42288684210a20022802b00c22034118762101200b4218882118200241c40c6a290200210b200241d00c6a28020021042005310000211720022f01da0b210720022d00d90b21092019a721084101210e4100210c0c3d0b20024180046a200110c4012002280280040d3a2002280284042103200241980c6a41106a200241b00c6a41106a290300370300200241980c6a41086a200241b00c6a41086a290300370300200220022903b00c3703980c200341187621014200210a4102210e0c3b0b20024188046a200110c4012002280288040d39200228028c042103200241980c6a41106a200241b00c6a41106a290300370300200241980c6a41086a200241b00c6a41086a290300370300200220022903b00c3703980c200341187621014200210a4103210e0c3a0b20024190046a200110c4012002280290040d3820072802002002280294042206490d382006417f4c0d1902400240024020060d004200210a410121040c010b200610392204450d0f20072802002006490d01200420012802002006109d081a200128020422032006490d2d2001200320066b3602042001200128020020066a3602002006ad210a0b2004450d3941002105200241003a00d00c2007280200417f6a2103200a2006ad42208684220a422088a72109200aa72107024003402003417f460d01200241b00c6a20056a200128020022062d00003a0000200120033602042001200641016a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200220022800b30c3600c30b200220022802b00c22053602c00b2002200936029c0c200220073602980c20022900b70c2219421888200241bf0c6a290000220b42288684210a20054180fe03714108762106200b421888211820022801c20b220c4108762103200241cf0c6a310000211720022900c70c210b20022d00c60b21012019a721084104210e0c3c0b0240200541ff0171450d00200241003a00d00c0b2007450d390b200410350c380b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b200241980c6a41086a20024190066a41086a290000370300200241980c6a41106a20024190066a41106a290000370300200220022800b30c3600c30b200220022802b00c22053602c00b20022002290090063703980c20022900b70c2219421888200241bf0c6a290000220b42288684210a200b421888211820022800c30b2203411876210120022f00c10b2206410876210c200241cf0c6a310000211720022900c70c210b2019a721084105210e0c3a0b200541ff0171450d37200241003a00d00c0c370b20024198046a200110c4012002280298040d362007280200200228029c042205490d362005417f4c0d170240024020050d004200210a410121040c010b200510392204450d0c20072802002005490d36200420012802002005109d081a200128020422032005490d2b2001200320056b3602042001200128020020056a3602002005ad210a0b2004450d3641002103200241003a00d00c200a2005ad42208684220a422088a7210e200aa7210820072802002107417f21050240034020072003460d01200241b00c6a20036a200128020022092d00003a00002001200720056a3602042001200941016a3602002002200341016a22063a00d00c2005417f6a21052006210320064120470d000b200220022800b30c3600c30b200220022802b00c22053602c00b200720066b22074110490d03200241bf0c6a2900002118200241cf0c6a310000211720022900b70c211920022900c70c210b20022f00c10b210620022800c30b2103200241980c6a41106a200941096a2900003703002009290001210a2001200741706a3602042001200941116a3602002002200e36029c0c200220083602980c2002200a3703a00c2019421888201842288684210a200341187621012018421888211820064180fe0371410876210c2019a721084106210e0c390b0240200341ff0171450d00200241003a00d00c0b2008450d360c350b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b20024180096a41186a200241cf0c6a31000022173c0000200220022800b30c3600c30b200220022802b00c22053602c00b200220022900c70c220b37039009200220022900b70c2219370380092002200241bf0c6a290000221837038809200320076b2209417e6a4110490d3620022f00c10b210620022800c30b2103200420076a220441026a290000210a2004410a6a290000211e20012009416e6a3602042001200441126a3602002002201e3703a00c2002200a3703980c2019421888201842288684210a200341187621012018421888211820064180fe0371410876210c2019a721084107210e0c380b200541ff0171450d35200241003a00d00c0c350b41002105200241003a00d00c2003417e6a21072003417d6a21030240034020072005460d01200241b00c6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00d00c2003417f6a21032006210520064120470d000b4108210e200241980c6a41086a20024190066a41086a290000370300200241980c6a41106a20024190066a41106a290000370300200220022800b30c3600c30b200220022802b00c22053602c00b200220022900b70c220aa722084110763a00eb0b20022002290090063703980c200a421888200241bf0c6a290000220b42288684210a200b421888211820022801c20b220c4108762103200241cf0c6a310000211720022900c70c210b20022d00c10b210620022d00c60b21010c370b200541ff0171450d34200241003a00d00c0c340b20080d320c330b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541044b0d0002400240024002400240024002400240024020050e050001020304000b200241e00e6a200110db0220022d00e80f4102460d08200241a80b6a41086a200241e00e6a41106a290300370300200241a80b6a41106a200241f80e6a2d00003a0000200241980c6a41086a200241900f6a290300370300200241980c6a41106a200241980f6a290300370300200220022903e80e3703a80b200220022903880f3703980c200241fc0e6a2802002104200241840f6a280200210c20022903e00e210a20022d00f90e210520022d00fa0e210620022d00fb0e210820022802800f210d20022903a00f210b20024190066a200241e00e6a41c8006a41c800109d081a200241b00a6a41026a20024180086a41026a2d00003a0000200220022f0080083b01b00a410121010c050b200241a0046a200110c40120022802a0040d07200728020020022802a4042204490d072004417f4c0d1b02400240024020040d004200210a410121090c010b200410392209450d1120072802002004490d01200920012802002004109d081a200128020422032004490d312001200320046b3602042001200128020020046a3602002004ad210a0b2009450d08200a2004ad42208684210a41022101200241b00a6a41026a200241d00b6a41026a2d00003a0000200241a80b6a41086a200241e80b6a41086a290300370300200241a80b6a41106a200241e80b6a41106a2d00003a0000200241980c6a41086a20024180086a41086a290300370300200241980c6a41106a20024180086a41106a290300370300200220022f00d00b3b01b00a200220022903e80b3703a80b20022002290380083703980c20024190066a200241e00e6a41c800109d081a0c040b200910350c070b20024180086a200110920620022d0080084102460d06200241f00b6a20024194086a290200370300200241e80b6a41106a2002419c086a2d00003a000020022002418c086a2902003703e80b2002419d086a2d000021052002419e086a2d000021062002419f086a2d00002108200241a0086a2802002104200229028408210a2002280280082109200241c0046a200110f60120022903c004a70d06200241c0046a41106a290300211720022903c8042118200241b0046a200110910620022903b004a70d0620022903b804210b200241a8046a200110c40120022802a8040d06200728020020022802ac042203490d062003417f4c0d1a0240024020030d00420021194101210d0c010b20031039220d450d0f20072802002003490d06200d20012802002003109d081a200128020422072003490d302001200720036b3602042001200128020020036a3602002003ad21190b200d450d06200241a80b6a41106a200241e80b6a41106a2d00003a0000200241a80b6a41086a200241e80b6a41086a290300370300200241980c6a41106a2017370300200241b00a6a41026a200241d00b6a41026a2d00003a0000200220022903e80b3703a80b200220183703a00c200220022f00d00b3b01b00a200220192003ad4220868422174220883e02980c20024190066a200241e00e6a41c800109d081a2017a7210c410321010c030b200241f0046a200110f60120022903f004a70d0520024180056a290300210b20022903f8042117200241e0046a200110910620022903e004a70d0520022903e804211841002103200241003a00a0082007280200417f6a2104024002400240024003402004417f460d0120024180086a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00a0082004417f6a21042005210320054120470d000b200241e20a6a20022d0082083a0000200241e00b6a2002419f086a2d00003a0000200241d80b6a20024197086a2900003703002002200229008f08220a3703e80b200220022f0180083b01e00a2002200a3703d00b200229008708210a2002280083082109200241d8046a200110c40120022802d8040d09200728020020022802dc04220c490d09200c417f4c0d1d200c0d01410121044101450d094100210d0c020b200341ff0171450d08200241003a00a0080c080b200c10392204450d0f2007280200200c490d0120042001280200200c109d08210320012802042205200c490d3120012005200c6b36020420012001280200200c6a3602002003450d07200c210d0b200241b00a6a41026a200241e00a6a41026a2d00003a0000200241a80b6a41086a200241d00b6a41086a290300370300200241a80b6a41106a200241d00b6a41106a2d00003a0000200220022f01e00a3b01b00a200220022903d00b3703a80b200220173703980c200220183703a80c2002200b3703a00c20024190066a200241e00e6a41c800109d081a410421010c020b200410350c050b41002105200241003a00a0082003417e6a21092003417d6a2106024002400240034020092005460d0120024180086a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00a0082006417f6a21062007210520074120470d000b200241c80a6a41026a20022d0082083a0000200241e00b6a2002419f086a2d00003a0000200241d80b6a20024197086a2900003703002002200229008f08220a3703e80b200220022f0180083b01c80a2002200a3703d00b2003417e6a2007460d07200229008708210a2002280083082109200420076a220e41026a2d00002114200120063602042001200e41036a360200201441014b0d074100210520140e020201020b200541ff0171450d06200241003a00a0080c060b41002104200241003a00a008200720036b41036a2106200320076b417c6a21030340200620046a450d0420024180086a20046a200e20046a220541036a2d00003a0000200120033602042001200541046a3602002002200441016a22053a00a0082003417f6a21032005210420054120470d000b200241e80b6a41106a22012002418f086a290000220b4238883c0000200241f40b6a200b4218883e020020022002280083083600c30b200220022802800822063602c00b200220022d00c60b3a00e80b20022002290087082217a722043b00e90b200220044110763a00eb0b200220174218882218200b422886843702ec0b2002419f086a3100002117200229009708210b20022d00c10b210820022801c20b210420022802e80b210d200241800b6a20012d00003a0000200220022902f00b3703f80a2018a7210c410121050b200241a90c6a20173c0000200241980c6a41086a200241f80a6a41086a2d00003a0000200241b00a6a41026a200241c80a6a41026a2d00003a0000200241a80b6a41086a200241d00b6a41086a290300370300200241a80b6a41106a200241d00b6a41106a2d00003a00002002200b3700a10c200220022903f80a3703980c200220022f01c80a3b01b00a200220022903d00b3703a80b200241ae0c6a200241e40a6a2f01003b0100200220022801e00a3601aa0c20024190066a200241e00e6a41c800109d081a410521010b0b200241980a6a41026a2203200241b00a6a41026a2d00003a0000200241900b6a41086a2207200241a80b6a41086a290300370300200241900b6a41106a220e200241a80b6a41106a2d00003a0000200241800c6a41086a2214200241980c6a41086a290300370300200241800c6a41106a2213200241980c6a41106a290300370300200220022f01b00a3b01980a200220022903a80b3703900b200220022903980c3703800c20024180096a20024190066a41c800109d081a200041086a20013a000020004111360200200020022f01980a3b00092000410b6a20032d00003a0000200041106a200a3702002000410c6a2009360200200041186a20022903900b370000200041206a2007290300370000200041286a200e2d00003a0000200041346a200c360200200041306a200d3602002000412c6a2004360200200020083a002b200020063a002a200020053a0029200041d0006a200b370200200041c8006a2013290300370200200041c0006a2014290300370200200041386a20022903800c370200200041d8006a20024180096a41c800109d081a200041a0016a200241b00c6a419001109d081a0c510b200441ff0171450d01200241003a00a0080c010b200d10350b2000411b3602000c4e0b200241b00c6a2001109406024020022802b00c4104460d0020024190066a41286a200241b00c6a41286a280200220136020020024190066a41206a200241b00c6a41206a290300220a37030020024190066a41186a200241b00c6a41186a290300220b37030020024190066a41106a200241b00c6a41106a290300221737030020024190066a41086a200241b00c6a41086a2903002218370300200220022903b00c22193703900620004112360200200020193702042000410c6a2018370200200041146a20173702002000411c6a200b370200200041246a200a3702002000412c6a2001360200200041306a200241e00e6a418002109d081a0c4e0b2000411b3602000c4d0b02402006450d0020042d0001210520012003417e6a22063602042001200441026a36020020050d0020064104490d002004280002210520012003417a6a3602042001200441066a36020020024198056a200110c4012002280298050d002007280200200228029c052204490d002004417f4c0d1202400240024002400240024002400240024020040d0041002103410121060c010b200410392206450d0e20072802002004490d01200620012802002004109d081a200128020422032004490d312001200320046b3602042001200128020020046a360200200421030b2006450d0720024190056a200110c4012004ad4220862003ad84220ba7210d02402002280290050d0020022802940522082007280200410c6e2204200420084b1bad420c7e220a422088a70d1a200aa72204417f4c0d1a0240024020040d004104210e0c010b20041033220e450d0f0b41002103200241003602b80c2002200e3602b00c20022004410c6e22093602b40c0240024002402008450d0041002103034020024188056a200110c4012002280288050d032007280200200228028c052204490d032004417f4c0d1e0240024020040d004100210c410121090c010b200410392209450d1320072802002004490d03200920012802002004109d081a2001280204220c2004490d372001200c20046b3602042001200128020020046a3602002004210c0b2004ad422086200cad84210a0240200320022802b40c470d00200241b00c6a2003410110870120022802b00c210e20022802b80c21030b200e2003410c6c6a2204200a370204200420093602002002200341016a22033602b80c2008417f6a22080d000b20022802b40c21090b200e450d022006450d0a200728020022074104490d042001280200220c280000211320012007417c6a22043602042001200c41046a36020020044104490d05200c280004210f2001200741786a22043602042001200c41086a36020020044104490d06200b422088a72110200c28000821112001200741746a22143602042001200c410c6a36020041002104200241003a00f00c200741736a2107034020142004460d08200241b00c6a20046a200c20046a2208410c6a2d00003a00002001200736020420012008410d6a3602002002200441016a22083a00f00c2007417f6a210720082104200841c000470d000b200841ff017141c000490d082006450d0a200241e80c6a290300210a200241b80c6a290300210b20022903e00c211720022903b00c211820022802dc0c210120022902d40c211920022802d00c210420022802cc0c210720022f01ca0c210820022d00c80c210c20022903c00c211e200020022d00c90c3a00452000200536020420004113360200200041e4006a200a370200200041dc006a2017370200200041346a200b3702002000412c6a2018370200200041d8006a2001360200200041d0006a2019370200200041cc006a2004360200200041c8006a2007360200200041c6006a20083b0100200041c4006a200c3a00002000413c6a201e370200200041286a2011360200200041246a200f360200200041206a20133602002000411c6a2003360200200041186a2009360200200041146a200e360200200041106a20103602002000410c6a200d360200200041086a2006360200200041ec006a200241e00e6a41c401109d081a0c570b200910350b02402003450d002003410c6c2104200e210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b20022802b40c2201450d002001410c6c450d00200e10350b200d450d070b200610350c060b0240200d450d00200610350b02402003450d002003410c6c2104200e210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b2009450d052009410c6c0d040c050b0240200d450d00200610350b02402003450d002003410c6c2104200e210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b2009450d042009410c6c0d030c040b0240200d450d00200610350b02402003450d002003410c6c2104200e210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b2009450d032009410c6c0d020c030b200441ff0171450d00200241003a00f00c0b0240200d450d00200610350b02402003450d002003410c6c2104200e210103400240200141046a280200450d00200128020010350b2001410c6a2101200441746a22040d000b0b2009450d012009410c6c450d010b200e10350b2000411b3602000c4c0b02402006450d0020012003417e6a3602042001200441026a3602000b2000411b3602000c4b0b02402006450d0020012003417e6a3602042001200441026a3602000b2000411b3602000c4a0b02402006450d0020012003417e6a3602042001200441026a3602000b2000411b3602000c490b2006450d2a20042d0001210620012003417e6a22263602042001200441026a3602002006410a4b0d2a410421274200212402400240024002400240024002400240024002400240024020060e0b0001020b03040506070809000b41002105200241003a00800f2003417e6a21072003417d6a21030240034020072005460d01200241e00e6a20056a200420056a220641026a2d00003a0000200120033602042001200641036a3602002002200541016a22063a00800f2003417f6a21032006210520064120470d000b200241a80b6a41086a200241b00c6a41086a290000370300200241a80b6a41106a200241b00c6a41106a290000370300200241900b6a41086a20024190066a41086a290000370300200241900b6a41106a20024190066a41106a290000370300200220022900b00c3703a80b20022002290090063703900b200241ef0e6a290000210b200241ff0e6a310000210a20022800e30e210920022f00e10e212820022d00e00e212920022900e70e211720022900f70e2118200241f80a6a41106a20024180096a41106a290000370300200241f80a6a41086a20024180096a41086a29000037030020022002290080093703f80a200241e00a6a41106a20024180086a41106a290000370300200241e00a6a41086a20024180086a41086a29000037030020022002290080083703e00a2018422088200a42208684210a2017422088a72105200b422088a7210f200b4280feffff0f83420888a7212a2018a721142017a72108200ba7210c41012127410021100c0b0b200541ff0171450d35200241003a00800f0c350b200241a0056a200110c40120022802a0050d3420022802a4052206200728020041c8006e2204200420064b1bad42c8007e220a422088a70d17200aa72204417f4c0d170240024020040d00410421090c010b200410332209450d0c0b41002105200241003602c80b200220093602c00b2002200441c8006e22083602c40b0240024002402006450d00200241b00c6a410c6a2110410021050340200241b00c6a200110ad040240024020022d00b00c22034106470d00410621030c010b200241980c6a41086a220e201041086a290200370300200241980c6a41106a220c201041106a290200370300200220102902003703980c20022802b80c210420022802b40c210820022f01b20c210d20022d00b10c2114200241e00e6a200110ad04024020022d00e00e4106470d00024020034101470d002004450d00200810350b410621030c010b200241800c6a41106a200c290300370300200241800c6a41086a200e29030037030020024190066a41086a200241e00e6a41086a29030037030020024190066a41106a200241e00e6a41106a29030037030020024190066a41186a200241e00e6a41186a29030037030020024190066a41206a200241e00e6a41206a280200360200200220022903980c3703800c200220022903e00e37039006200d21112014211220042116200821150b200241e80b6a41086a2204200241800c6a41086a290300370300200241e80b6a41106a2208200241800c6a41106a29030037030020024180096a41086a220e20024190066a41086a29030037030020024180096a41106a220c20024190066a41106a29030037030020024180096a41186a220d20024190066a41186a29030037030020024180096a41206a221420024190066a41206a280200360200200220022903800c3703e80b20022002290390063703800920034106460d02200241d00b6a41106a22132008290300370300200241d00b6a41086a2208200429030037030020024180086a41086a220f200e29030037030020024180086a41106a220e200c29030037030020024180086a41186a220c200d29030037030020024180086a41206a220d2014280200360200200220022903e80b3703d00b2002200229038009370380080240200520022802c40b470d00200241c00b6a2005410110a80120022802c00b210920022802c80b21050b2009200541c8006c6a220420123a0001200420033a0000200441086a2016360000200441046a2015360000200441026a20113b00002004410c6a20022903d00b370000200441146a20082903003700002004411c6a2013290300370000200441246a2002290380083700002004412c6a200f290300370000200441346a200e2903003700002004413c6a200c290300370000200441c4006a200d2802003600002002200541016a22053602c80b2006417f6a22060d000b20022802c40b21080b20090d010c360b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b20022802c40b2201450d35200141c8006c450d35200910350c350b200241e00e6a200110ad0402400240024002400240024002400240024020022d00e00e220c4106460d00200241800f6a280200210d200241f80e6a290300210b200241f40e6a2204280200210e200241ec0e6a2203290200210a200241e80e6a2206280200211420022802e40e210f20022f01e20e212720022d00e10e2128200241e00e6a200110ad0420022d00e00e22104106460d01200241fc0e6a2216290200211920042902002118200329020021172006280200211120022802e40e211320023301e20e212420023100e10e2125200241e00e6a200110ad0420022d00e00e22124106460d0220024180086a41086a200241f40e6a220429020037030020024180086a41106a20162902003703002002200241ec0e6a220329020037038008200241e00e6a41086a2206280200211620022802e40e211520022f01e20e212b20022d00e10e212c200241e00e6a200110ad0420022d00e00e22234106460d0320024180096a41086a200429020037030020024180096a41106a200241fc0e6a220429020037030020022003290200370380092006280200212d20022802e40e212e20022f01e20e212020022d00e10e212f200241e00e6a200110ad0420022d00e00e22304106460d0620024190066a41086a200241f40e6a290200370300200241a0066a20042902003703002002200241ec0e6a29020037039006200241e00e6a41086a280200212220022802e40e212120072802002204450d0720022f01e20e213120022d00e10e2132200128020022032d0000210620012004417f6a22073602042001200341016a360200200641014b0d074200211e410021334200211d20060e020504050b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d3c200841c8006c450d3c200910350c3c0b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d3b200841c8006c450d3b200910350c3b0b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d3a200841c8006c450d3a200910350c3a0b024020124101470d002016450d00201510350b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d39200841c8006c450d39200910350c390b2007450d0220032d0001213420012004417e6a22063602042001200341026a3602002006450d0220032d0002210720012004417d6a22063602042001200341036a3602002006450d0220032d0003213520012004417c6a22063602042001200341046a3602002006450d0220032d0004213620012004417b6a22063602042001200341056a3602002006450d0220032d0005213320012004417a6a22063602042001200341066a3602002006450d0220032d000621372001200441796a22063602042001200341076a3602002006450d0220032d000721382001200441786a22063602042001200341086a3602002006450d0220032d0008211f2001200441776a22063602042001200341096a3602002006450d0220032d000921392001200441766a220636020420012003410a6a3602002006450d0220032d000a213a2001200441756a220636020420012003410b6a3602002006450d0220032d000b21292001200441746a220636020420012003410c6a3602002006450d0220032d000c213b2001200441736a220636020420012003410d6a3602002006450d0220032d000d213c2001200441726a220636020420012003410e6a3602002006450d0220032d000e213d2001200441716a220636020420012003410f6a3602002006450d0220032d000f212a2001200441706a22063602042001200341106a3602002006450d0220032d0010213e20012004416f6a22063602042001200341116a3602002006450d0220032d0011212620012004416e6a22063602042001200341126a3602002006450d0220032d0012213f20012004416d6a22063602042001200341136a3602002006450d0220032d0013214020012004416c6a22063602042001200341146a3602002006450d022003310014211e20012004416b6a3602042001200341156a3602002002203641187420354110747220074108747222042034723602e00e2002203bad4238862029ad42ff018342308684203aad42ff0183422886842039ad42ff018342208684201fad42ff018342188684221d2038ad42ff0183421086842037ad42ff0183420886842033ad42ff0183843702e40e201d421888201e4238862040ad42ff018342308684203fad42ff0183422886842026ad42ff018342208684203ead42ff018342188684202aad42ff018342108684203dad42ff018342088684203cad42ff018384221d42288684211e20044108762135201d421888211d20022800e30e2136410121330b200241e00e6a200110ad0420022d00e00e22374106460d02200241b00c6a41086a2204200241f40e6a290200370300200241b00c6a41106a2203200241fc0e6a2902003703002002200241ec0e6a22062902003703b00c200241e00e6a41086a2207280200213820022802e40e211f20022f01e20e213a20022d00e10e2139200241e00e6a200110ad0420022d00e00e4106470d0b024020374101470d002038450d00201f10350b024020304101470d002022450d00202110350b024020234101470d00202d450d00202e10350b024020124101470d002016450d00201510350b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d37200841c8006c450d37200910350c370b024020234101470d00202d450d00202e10350b024020124101470d002016450d00201510350b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d36200841c8006c450d36200910350c360b024020304101470d002022450d00202110350b024020234101470d00202d450d00202e10350b024020124101470d002016450d00201510350b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d35200841c8006c450d35200910350c350b024020304101470d002022450d00202110350b024020234101470d00202d450d00202e10350b024020124101470d002016450d00201510350b024020104101470d002011450d00201310350b0240200c4101470d002014450d00200f10350b02402005450d002009200541c8006c6a2104200921010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012004470d000b0b2008450d34200841c8006c450d34200910350c340b200241a8056a200110c40120022802a8050d3320022802ac052215200728020041c4006e2204200420154b1bad42c4007e220a422088a70d16200aa72204417f4c0d160240024020040d00410421090c010b200410332209450d0b0b200241003602880c200220093602800c2002200441c4006e3602840c024002402015450d00200241e80b6a410172210c20024180096a41186a2123200241f40b6a212c4100210641002108034041002103200241003a00800f200841016a21082007280200417f6a210402400240024003402004417f460d01200241e00e6a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00800f2004417f6a21042005210320054120470d000b200220022800e30e3600c30b200220022802e00e3602c00b200241e00e6a410f6a2900002117200241e00e6a411f6a310000211b20022900e70e211820022900f70e211a200241e00e6a200110ad0420022d00e00e22034106470d01410621030c020b0240200341ff0171450d00200241003a00800f0b410621030c010b200241e80b6a41106a20174238883c0000202c20174218883e0200200220022d00c60b3a00e80b20022018a722043b00e90b200220044110763a00eb0b200220184218882017422886843702ec0b200241e00e6a41106a290300211e200241e00e6a41206a310000211c20022903e80e211920022903f80e211d20022801c20b210e20022d00c10b211420022d00c00b211320022d00e10e210f20022f01e20e211020022802e40e211120022d00810f211220022f01820f2116201a210a201b210b0b2023200b3c000020024180096a41086a2204200c41086a2900003703002002200a370390092002200c2900003703800920034106460d0220022d00e80b2105200e410876210d2004290300211720022903800921180240200620022802840c470d00200241800c6a20064101109f0120022802800c210920022802880c21060b2009200641c4006c6a220420163b0042200420123a00412004201d37003820042011360024200420103b00222004200f3a0021200420033a00202004200a37001720042005411874200d723600032004200e410874201441ff0171723b0001200420133a0000200441c0006a201c3c00002004411f6a200b3c00002004201937002820042018370007200441306a201e3700002004410f6a20173700002002200641016a22063602880c20082015470d000b0b2009450d3420022902840c210a200241a80b6a41106a200241b00c6a41106a290200370300200241a80b6a41086a200241b00c6a41086a290200370300200241900b6a41086a20024190066a41086a290300370300200241900b6a41106a20024190066a41106a290300370300200241f80a6a41086a20024180086a41086a290200370300200241f80a6a41106a20024180086a41106a290200370300200220022902b00c3703a80b20022002290390063703900b20022002290280083703f80a200241e00a6a41106a200241980c6a41106a290300370300200241e00a6a41086a200241980c6a41086a290300370300200220022903980c3703e00a200a422088a72105200aa7210841032127410021100c090b02402006450d00200641c4006c2104200941286a210103400240200141786a2d00004101470d002001280200450d002001417c6a28020010350b200141c4006a2101200441bc7f6a22040d000b0b20022802840c2201450d33200141c4006c450d33200910350c330b200241c8056a200110c40120022802c8050d3220022802cc052109200241b0056a200110f60120022903b005a70d32200241b0056a41106a290300210a20022903b805210b200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024190066a41086a290200370300200241f80a6a41106a20024190066a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290290063703f80a200241e00a6a41106a20024180096a41106a290300370300200241e00a6a41086a20024180096a41086a29030037030020022002290380093703e00a200b422088a72105200a422088a7210f200a4280feffff0f83420888a7212a200ba72108200aa7210c41052127410021100c070b20264104490d312004280002210920012003417a6a360204410621272001200441066a360200200241a80b6a41086a200241e00e6a41086a290200370300200241a80b6a41106a200241e00e6a41106a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024190066a41086a290200370300200241f80a6a41106a20024190066a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290290063703f80a200241e00a6a41106a20024180096a41106a290300370300200241e00a6a41086a20024180096a41086a29030037030020022002290380093703e00a410021054100212a4100210c410021100c060b200241e8056a200110c40120022802e8050d3020022802ec052109200241d0056a200110f60120022903d005a70d30200241d0056a41106a290300210a20022903d805210b200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024190066a41086a290200370300200241f80a6a41106a20024190066a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290290063703f80a200241e00a6a41106a20024180096a41106a290300370300200241e00a6a41086a20024180096a41086a29030037030020022002290380093703e00a200b422088a72105200a422088a7210f200a4280feffff0f83420888a7212a200ba72108200aa7210c41072127410021100c050b200241f0056a200110c40120022802f0050d2f20022802f405210e41002103200241003a00800f2007280200417f6a2104024003402004417f460d01200241e00e6a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00800f2004417f6a21042005210320054120470d000b41082127200241a80b6a41086a20024180096a41086a290200370300200241a80b6a41106a20024180096a41106a290200370300200241900b6a41086a200241980c6a41086a290300370300200241900b6a41106a200241980c6a41106a29030037030020022002290280093703a80b200220022903980c3703900b200241ef0e6a290000210b200241ff0e6a310000210a20022800e30e210920022f00e10e212820022d00e00e212920022900e70e211820022900f70e211920022802d40b211120022903d80b2117200241f80a6a41106a200241800c6a41106a290200370300200241f80a6a41086a200241800c6a41086a290200370300200220022902800c3703f80a200241e00a6a41106a200241e80b6a41106a290300370300200241e00a6a41086a200241e80b6a41086a290300370300200220022903e80b3703e00a2019422088200a42208684210a2018422088a72105200b422088a7210f200b4280feffff0f83420888a7212a200241c40c6a290200211d20022902bc0c211e20022802cc0c213e20022802b80c213620022f01b60c213520022d00b50c213420022d00b40c213320022802b00c213d2019a721142018a72108200ba7210c410021100c050b200341ff0171450d2f200241003a00800f0c2f0b200241f8056a200110c40120022802f8050d2e200728020022044108490d2e20022802fc05210920012802002203290000210a2001200441786a3602042001200341086a360200200a4280025a0d2e200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290300370300200241900b6a41106a200241b00c6a41106a290300370300200241f80a6a41086a20024190066a41086a290200370300200241f80a6a41106a20024190066a41106a290200370300200220022902e00e3703a80b200220022903b00c3703900b20022002290290063703f80a200241e00a6a41106a20024180096a41106a290300370300200241e00a6a41086a20024180096a41086a29030037030020022002290380093703e00a200a422088a72105200aa7210841092127410021100c030b20024180066a200110c4012002280280060d2d2002280284062109200241e00e6a200110920620022d00e00e4102460d2d20072802002203450d2d200241e80e6a3502002118200241800f6a350200210b200241fc0e6a280200210e200241f40e6a290200210a200241f00e6a2802002114200241ec0e6a280200210f20022903e00e2119200128020022052d0000210420012003417f6a22063602042001200541016a360200200441064b0d2d42002117410021114100210d0240024002400240024002400240024020040e0707000501020304070b20064110490d34200541096a29000021172005290001211e20012003416f6a3602042001200541116a360200201e422088a72111201ea721134101210d0c060b4103210d0c040b4104210d0c030b4105210d0c020b4106210d0c010b4102210d0b0b200241a80b6a41106a200241980c6a41106a290200370300200241a80b6a41086a200241980c6a41086a290200370300200241900b6a41086a200241800c6a41086a290300370300200241900b6a41106a200241800c6a41106a290300370300200241f80a6a41086a200241e80b6a41086a290200370300200241f80a6a41106a200241e80b6a41106a290200370300200220022902980c3703a80b200220022903800c3703900b200220022902e80b3703f80a200241e00a6a41106a200241d00b6a41106a290300370300200241e00a6a41086a200241d00b6a41086a290300370300200220022903d00b3703e00a2019422088a7210520184280feffff0f83420888a7212a200241c40c6a290200211d20022802b80c213620022802cc0c213e20022902bc0c211e20022f01b60c213520022d00b50c213420022d00b40c21332019a721082018a7210c410a212741002110420021240c020b200241e00e6a200110920620022d00e00e4102460d2c200241d00b6a41086a200241fc0e6a280200360200200241a80b6a41086a20024180096a41086a290200370300200241a80b6a41106a20024180096a41106a2902003703002002200241e00e6a41146a29020022193703d00b20022002290280093703a80b200241800f6a280200210e200241ec0e6a290200210b20022802e00e210920022902e40e211820022802ec0b211120022903f00b211720022902d40b210a200241900b6a41106a20024180086a41106a290300370300200241900b6a41086a20024180086a41086a29030037030020022002290380083703900b200241f80a6a41106a200241980c6a41106a290200370300200241f80a6a41086a200241980c6a41086a290200370300200220022902980c3703f80a200241e00a6a41106a200241800c6a41106a290300370300200241e00a6a41086a200241800c6a41086a290300370300200220022903800c3703e00a2018422088a72105200b422088a7210f200b4280feffff0f83420888a7212a200241b00c6a41146a290200211d20022902bc0c211e20022802cc0c213e20022802b80c213620022f01b60c213520022d00b50c213420022d00b40c21332018a721082019a72114200ba7210c410b2127410021100c010b200241a80b6a41086a20024180086a41086a290300370300200241a80b6a41106a20024180086a41106a290300370300200241900b6a41086a20024180096a41086a290300370300200241900b6a41106a20024180096a41106a29030037030020022002290380083703a80b20022002290380093703900b200241f80e6a290300211a200241e00e6a41106a290300211b200241800f6a280200213d2006280200213c2007280200213b20022903e00e211c200241f80a6a41106a20024190066a41106a290300370300200241f80a6a41086a20024190066a41086a29030037030020022002290390063703f80a200241e00a6a41106a2003290300370300200241e00a6a41086a2004290300370300200220022903b00c3703e00a2027410874202841ff017172212a20244208862025842124410221270b200241c80a6a41106a2201200241a80b6a41106a290300370300200241c80a6a41086a2204200241a80b6a41086a290300370300200241b00a6a41086a2203200241900b6a41086a290300370300200241b00a6a41106a2206200241900b6a41106a290300370300200241980a6a41086a2207200241f80a6a41086a290300370300200241980a6a41106a2226200241f80a6a41106a290300370300200220022903a80b3703c80a200220022903900b3703b00a200220022903f80a3703980a200241800a6a41106a223f200241e00a6a41106a290300370300200241800a6a41086a2240200241e00a6a41086a290300370300200220022903e00a3703800a200041d8006a2019370200200041d0006a2018370200200041186a202a410874ad200cad42ff0183843e0200200041106a2005ad4220862008ad84370200200041e8006a2016360200200041e4006a20153602002000202b3b00622000202c3a0061200041e0006a20123a0000200041c8006a2017370200200041c4006a2011360200200041c0006a2013360200200041386a20244228862010ad42ff018342208684200dad84370200200041306a200b3702002000412c6a200e360200200041246a200a370200200041206a20143602002000411c6a200f3602002000410c6a2009360200200020283b000a200020293a0009200041086a20273a00002000411736020020004188016a202e3602002000418c016a202d360200200020203b0086012000202f3a00850120004184016a20233a0000200041a8016a20303a0000200020323a00a901200020313b00aa01200041b0016a2022360200200041ac016a2021360200200041fc006a2001290300370200200041f4006a2004290300370200200041ec006a20022903c80a37020020004190016a20022903b00a37020020004198016a2003290300370200200041a0016a2006290300370200200041cc016a20373a0000200020393a00cd012000203a3b00ce01200041d4016a2038360200200041d0016a201f360200200041a4026a201d3700002000419c026a201e37000020004188026a201a37020020004180026a201b37020020004194026a20333a0000200020343a009502200020353b009602200041ac026a203e36020020004198026a203636000020004190026a203d360200200041fc016a203c360200200041f8016a203b360200200041f0016a201c370200200041c4016a2026290300370200200041bc016a2007290300370200200041b4016a20022903980a370200200041d8016a20022903800a370200200041e0016a2040290300370200200041e8016a203f2903003702000c480b2006450d0720042d0001210520012003417e6a22123602042001200441026a3602002005410b4b0d074107210d4200211d4100211141002106024002400240024002400240024020050e0c0001020304052f0608090a0b000b20124110490d0d2004410a6a29000021172004290002210b20012003416e6a3602042001200441126a3602004101210d4200211e410021064200211d0c2e0b20124104490d0c2004280002210c20012003417a6a3602042001200441066a3602004102210d0c2c0b41002105200241003a00d00c2003417e6a2109417d21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a00002001200320066a3602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200220022800b30c3600c30b200220022802b00c22083602c00b200320076b2203417e6a4110490d0c200241bf0c6a2900002117200241cf0c6a310000211c20022900b70c210b20022900c70c210a20022f00c10b211420022800c30b210c200420076a2204410e6a2800002113200441066a290000211d200441026a280000210620012003416e6a22053602042001200441126a220736020020054110490d0c2004411a6a29000021192007290000211820012003415e6a3602042001200441226a360200201d421088211e20064180807c712111201ca741ff017121104103210d0c2d0b200541ff0171450d0b200241003a00d00c0c0b0b4104210d20124104490d0a2004280002210c20012003417a6a3602042001200441066a3602000c2a0b200241b00c6a200110920620022d00b00c4102460d0920072802002203450d09200241bc0c6a2902002117200241d00c6a280200210e200241ce0c6a2f0100210f200241cd0c6a2d00002109200241cc0c6a2d00002110200241c40c6a290200210a20022902b40c210b20022802b00c210c200128020022052d0000210420012003417f6a3602042001200541016a360200200441014b0d09410021080240024020040e020100010b410121080b20023502900620023301940642208684211e200241a2066a2901002119200229019a06211820022801960621134105210d41002111410021060c2a0b2012450d0820042d0002210520012003417d6a3602042001200441036a360200200541014b0d084106210d410021114200211e410021064200211d4100210820050e022906290b41002105200241003a00d00c2003417e6a2108417d2106024002400240034020082005460d01200241b00c6a20056a200420056a220941026a2d00003a00002001200320066a3602042001200941036a3602002002200541016a22093a00d00c2006417f6a21062009210520094120470d000b20024198086a200241cf0c6a31000022183c0000200220022800b30c3600c30b200220022802b00c22083602c00b200220022900c70c220a37039008200220022900b70c220b370380082002200241bf0c6a290000221737038808200320096b2203417e6a4104490d0a200241c50b6a2d0000210520022f00c30b210c20022d00c10b211420022d00c20b211320022d00c60b210d200420096a220441026a280000210e20012003417a6a3602042001200441066a36020020024188066a200110c4012002280288060d0a2007280200200228028c062204490d0a2004417f4c0d0f20040d0142002119410121060c020b200541ff0171450d09200241003a00d00c0c090b200410392206450d0120072802002004490d07200620012802002004109d081a200128020422032004490d262001200320046b3602042001200128020020046a3602002004ad21190b2006450d07200d411874200c20054110747241ffffff077172210c20192004ad42208684221d421088211e20064180807c7121114108210d201341087420147221142018a741ff017121100c280b1045000b4109210d410021060c260b41002105200241003a00d00c2003417e6a21092003417d6a2106024002400240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200220022800b30c3600c30b200220022802b00c22083602c00b2003417e6a2007460d07200241bf0c6a2900002117200241cf0c6a310000211820022900b70c210b20022900c70c210a20022f00c10b211420022800c30b210c200420076a220341026a2d00002104200120063602042001200341036a360200200441014b0d074100210920040e020201020b200541ff0171450d06200241003a00d00c0c060b410121090b2018a741ff01712110410a210d0c230b41002105200241003a00d00c2003417e6a21092003417d6a21060240034020092005460d01200241b00c6a20056a200420056a220741026a2d00003a0000200120063602042001200741036a3602002002200541016a22073a00d00c2006417f6a21062007210520074120470d000b200241e80b6a41106a200241bf0c6a290000220a4238883c0000200241f40b6a200a4218883e0200200220022800b30c3600c30b200220022802b00c22083602c00b200220022d00c60b3a00e80b200220022900b70c220ba722053b00e90b200220054110763a00eb0b2002200b421888200a422886843702ec0b2003417e6a2007460d04200241cf0c6a310000210b20022900c70c210a20022d00c10b210520022801c20b2103200420076a220441026a2d00002109200120063602042001200441036a360200200941034f0d0420022d00e80b411874200341087672210c20034108742005722114200ba741ff01712110200241e80b6a410172220141086a29000021172001290000210b410b210d0c230b200541ff0171450d03200241003a00d00c0c030b20124104490d022004280002210c20012003417a6a3602042001200441066a360200410c210d0c220b410121084200211e41002111410021064200211d0c220b200610350b2000411b3602000c3f0b200241b00c6a2001109506024020022d00b00c410a460d0020024190066a200241b00c6a41c400109d081a20004119360200200041046a20024190066a41c400109d081a200041c8006a200241e00e6a41e801109d081a0c3f0b2000411b3602000c3e0b02402006450d0020042d0001210520012003417e6a3602042001200441026a360200200541024b0d004101210402400240024020050e03020001020b200241b00c6a20011092064102210420022d00b00c4102460d02200241c40c6a2902002117200241bc0c6a290200210b200241cc0c6a290200210a200241b80c6a280200210320022802b40c210620022802b00c21090c010b200241b00c6a200110920620022d00b00c4102460d01200728020022054110490d01200241c40c6a2902002117200241bc0c6a290200210b200241cc0c6a290200210a200241b00c6a41086a280200210320022802b40c210620022802b00c21092001280200220441086a2900002119200429000021182001200441106a3602002001200541706a220736020420074110490d01200441186a290000211d2004290010211e2001200541606a22073602042001200441206a36020020074104490d012004280020210820012005415c6a3602042001200441246a360200410321040b2000411a360200200041c8006a201d370200200041c0006a201e370200200041386a2019370200200041306a2018370200200041206a2017370200200041186a200b370200200041d0006a2008360200200041286a200a370200200041146a2003360200200041106a20063602002000410c6a2009360200200041086a2004360200200041d8006a200241e00e6a41d801109d081a0c3e0b2000411b3602000c3d0b02402006450d0020012003417e6a3602042001200441026a3602000b2000411b3602000c3c0b2000411b3602000c3b0b1044000b2004200341a4f0cb001059000b2004200341a4f0cb001059000b2004200341a4f0cb001059000b2004200341a4f0cb001059000b2003200d41a4f0cb001059000b2004200841a4f0cb001059000b2004200341a4f0cb001059000b2004200341a4f0cb001059000b200810350c260b2004200341a4f0cb001059000b2004200341a4f0cb001059000b2003200541a4f0cb001059000b200410350b2000411b3602000c2c0b2004200341a4f0cb001059000b2004200341a4f0cb001059000b2004200541a4f0cb001059000b2006200341a4f0cb001059000b2005200341a4f0cb001059000b2004200341a4f0cb001059000b2003200741a4f0cb001059000b200c200541a4f0cb001059000b2004200341a4f0cb001059000b2004200c41a4f0cb001059000b2004200341a4f0cb001059000b4200211e41002111410021064200211d0c010b4200211e410021064200211d0b2000200f3b012a200020093a0029200020143b010a200020083a000920004118360200200041c8006a2019370200200041c0006a2018370200200041186a2017370200200041106a200b3702002000413c6a20133602002000412c6a200e360200200041286a20103a0000200041206a200a3702002000410c6a200c360200200041086a200d3a0000200041346a201e421086201d42ffff038384370200200041306a2011200641ffff037172360200200041d0006a200241e00e6a41e001109d081a0c1e0b2000411b3602000c1d0b200410350b2000411b3602000c1b0b4100210c420021180b200241800c6a41106a200241980c6a41106a2903002219370300200241800c6a41086a200241980c6a41086a290300221e370300200220022903980c221d3703800c200041286a20173c0000200041206a200b370200200041186a2018421886200a42288884370200200041106a200a4218862008ad42ffffff0783843702002000412c6a20043602002000412a6a20073b0100200020093a00292000410c6a2001411874200341ffffff0771723602002000200c410874200641ff0171723b000a200020053a0009200041086a200e3a000020004110360200200041306a201d370200200041386a201e370200200041c0006a2019370200200041c8006a200241e00e6a41e801109d081a0c190b0b4200211c4200211b4200211a4200210b42002124420021250b200020143b00462000200d3a00452000200f3b0026200020103a0025200020083a0005200020063a00042000410d360200200041246a200a4220883c0000200041206a200a3e0000200041c4006a201d3c00002000413c6a201e370000200041146a20183700002000410c6a2017370000200041286a20133600002000411c6a2011360000200041086a200c411874200741ffffff07717236000020002009410874200e41ff0171723b00062000412c6a200b200b84201b84201984370000200041346a2025202484201a84201c84370000200041c8006a200241e00e6a41e801109d081a0c160b2000411b3602000c150b4100210e0b0b200020153b012a2000200c3a00292000200f3b011a200020123a0019200020063a000920004109360200200041286a200a4220883c0000200041246a200a3e0200200041386a2018370200200041306a20173702002000412c6a2014360200200041206a20103602002000411c6a2011360200200041186a20163a0000200041106a200b370200200041086a20133a00002000410c6a200d411874200941ffffff0771723602002000200e410874200841ff0171723b000a200041c0006a200241e00e6a41f001109d081a0c120b4100210802402004450d00200910350b41022109410021060b41000d052009450d05200241e00e6a200110f80102400240024020022802e00e450d00200241b00c6a200241e00e6a41c001109d081a200728020022034110490d012001280200220441086a290000211e200429000021192001200441106a3602002001200341706a220536020420054110490d01200441186a290000211c2004290010211d2001200341606a22053602042001200441206a36020020054110490d01200441286a290000211a2004290020211b2001200341506a22053602042001200441306a36020020054104490d022004280030211320012003414c6a3602042001200441346a360200200241a80b6a41086a200241ec0c6a290200370300200241a80b6a41106a200241f40c6a2902003703002002200241b00c6a41346a2902003703a80b200241b00c6a41106a310000210b200241d00c6a2903002118200241c40c6a280200210f200241b00c6a41286a2d00002110200241dc0c6a280200211120022903b80c210a20022903c80c211720022802b00c210c20022802b40c211420022d00c10c212120022f01c20c212020022d00d90c213220022f01da0c213120022802e00c2112200241900b6a41086a200241900d6a290300370300200241900b6a41106a200241980d6a290300370300200241f80a6a41086a200241b40d6a290200370300200241f80a6a41106a200241bc0d6a2902003703002002200241880d6a2903003703900b2002200241ac0d6a2902003703f80a200241800d6a2802002115200241fc0c6a2d00002116200241a40d6a280200212b200241a00d6a2d0000212c20022802840d212320022f01fe0c213520022d00fd0c213420022802a80d212d20022f01a20d213320022d00a10d2136200241e00a6a41106a200241e00d6a290300370300200241e00a6a41086a200241d80d6a2903003703002002200241d00d6a2903003703e00a200241c80d6a2802002130200241c40d6a2d0000212e200241e80d6a290300212420022802cc0d212f20022f01c60d213820022d00c50d21374118210d0c0a0b20080d040c070b200241b00c6a10fa01200841808080807872418080808078470d030c060b200241b00c6a10fa012008450d050c020b4100210802402004450d00200910350b41022109410021060b41000d032009450d03200241e00e6a200110f80102400240024020022802e00e450d00200241b00c6a200241e00e6a41c001109d081a200728020022034110490d012001280200220441086a290000211e200429000021192001200441106a3602002001200341706a220536020420054110490d01200441186a290000211c2004290010211d2001200341606a22053602042001200441206a36020020054110490d01200441286a290000211a2004290020211b2001200341506a22053602042001200441306a36020020054104490d022004280030211320012003414c6a3602042001200441346a360200200241a80b6a41086a200241ec0c6a290200370300200241a80b6a41106a200241f40c6a2902003703002002200241b00c6a41346a2902003703a80b200241b00c6a41106a310000210b200241d00c6a2903002118200241c40c6a280200210f200241b00c6a41286a2d00002110200241dc0c6a280200211120022903b80c210a20022903c80c211720022802b00c210c20022802b40c211420022d00c10c212120022f01c20c212020022d00d90c213220022f01da0c213120022802e00c2112200241900b6a41086a200241900d6a290300370300200241900b6a41106a200241980d6a290300370300200241f80a6a41086a200241b40d6a290200370300200241f80a6a41106a200241bc0d6a2902003703002002200241880d6a2903003703900b2002200241ac0d6a2902003703f80a200241800d6a2802002115200241fc0c6a2d00002116200241a40d6a280200212b200241a00d6a2d0000212c20022802840d212320022f01fe0c213520022d00fd0c213420022802a80d212d20022f01a20d213320022d00a10d2136200241e00a6a41106a200241e00d6a290300370300200241e00a6a41086a200241d80d6a2903003703002002200241d00d6a2903003703e00a200241c80d6a2802002130200241c40d6a2d0000212e200241e80d6a290300212420022802cc0d212f20022f01c60d213820022d00c50d21374117210d0c080b20080d020c050b200241b00c6a10fa01200841808080807872418080808078470d010c040b200241b00c6a10fa012008450d030b200910350c020b4100210602402001450d00200810350b410421084100210c0b41000d002008450d004110210d200241a80b6a41106a200241e00e6a41106a290200370300200241a80b6a41086a200241e00e6a41086a290200370300200241900b6a41086a200241b00c6a41086a290200370300200241900b6a41106a200241b00c6a41106a290200370300200241f80a6a41086a20024180096a41086a290200370300200241f80a6a41106a20024180096a41106a290200370300200220022902e00e3703a80b200220022902b00c3703900b20022002290280093703f80a200241e00a6a41106a20024180086a41106a290200370300200241e00a6a41086a20024180086a41086a29020037030020022002290280083703e00a0c020b2000411b3602000c0a0b410021144100210c410021060b200241c80a6a41106a2201200241a80b6a41106a290300370300200241c80a6a41086a2204200241a80b6a41086a290300370300200241b00a6a41086a2203200241900b6a41086a290300370300200241b00a6a41106a2205200241900b6a41106a290300370300200241980a6a41086a2207200241f80a6a41086a290300370300200241980a6a41106a221f200241f80a6a41106a290300370300200220022903a80b3703c80a200220022903900b3703b00a200220022903f80a3703980a200241800a6a41106a2239200241e00a6a41106a290300370300200241800a6a41086a223a200241e00a6a41086a290300370300200220022903e00a3703800a200041386a2018370200200041306a2017370200200041286a200b3c0000200041206a200a370200200041186a2014ad422086200cad84370200200041106a2006ad4220862008ad84370200200041c8006a2012360200200041c4006a2011360200200020313b0042200020323a0041200041c0006a20103a00002000412c6a200f360200200020203b012a200020213a00292000410c6a2009360200200020223b010a2000200e3a0009200041086a200d3a000020004107360200200041e8006a2015360200200041ec006a2023360200200020353b0066200020343a0065200041e4006a20163a0000200041cc006a20022903c80a370200200041d4006a2004290300370200200041dc006a20012903003702002000418c016a202b36020020004190016a202d360200200020333b008a01200020363a00890120004188016a202c3a0000200041f0006a20022903b00a370200200041f8006a200329030037020020004180016a2005290300370200200041a4016a201f2903003702002000419c016a200729030037020020004194016a20022903980a370200200041b4016a202f360200200041b0016a2030360200200020383b00ae01200020373a00ad01200041ac016a202e3a0000200041c8016a2039290300370200200041c0016a203a290300370200200041b8016a20022903800a37020020004188026a201a37020020004180026a201b370200200041f8016a201c370200200041f0016a201d370200200041e8016a201e370200200041e0016a2019370200200041d8016a2013360200200041d0016a2024370200200041a8026a20024190066a41186a290300370300200041a0026a20024190066a41106a29030037030020004198026a20024190066a41086a29030037030020004190026a2002290390063703000c080b20004106360200200041e0006a201c370200200041d8006a201d370200200041c8006a201a370200200041c0006a201b370200200041386a2018370200200041306a2019370200200041206a200a370200200041186a200b370200200041d0006a201e370200200041286a2017370200200041146a2004360200200041106a20033602002000410c6a2005360200200041086a2001360200200041e8006a200241e00e6a41c801109d081a0c070b410021014200210b410021034100210e0b200041003a0025200020043b0023200020083b0006200020053a0005200020063a0004200041053602002000411b6a200b370000200041136a200a370000200041286a200e360200200041266a41003b01002000410f6a20013600002000410d6a20033b00002000410c6a20073a0000200041086a20093602002000412c6a200241e00e6a418402109d081a0c050b200410350b2000411b3602000c030b103c000b200610350b2000411b3602000b20024190116a24000b9d1401037f02402000280200220141194b0d0002400240024002400240024002400240024002400240024002400240024002400240024020010e1a0001121202121203040506070809120a0b0c0d0e1212120f1011000b200041086a280200417e6a220141074b0d1102400240024002400240024020010e080017010217030405000b200041106a280200450d162000410c6a28020010350f0b200041106a280200450d152000410c6a28020010350f0b200041106a280200450d142000410c6a28020010350f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141186a2101200241686a22020d000b0b200041106a2802002201450d13200141186c450d13200028020c10350f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d122001410c6c450d12200028020c10350f0b200041106a280200450d112000410c6a28020010350f0b024020002d0004220141044b0d00024002400240024020010e051500010203150b0240200041106a2802002202450d00200041086a2802002101200241b0026c21020340200110bb02200141b0026a2101200241d07d6a22020d000b0b2000410c6a2802002201450d14200141b0026c450d14200028020810350f0b200041086a220128020010ba02200128020010350f0b02402000410c6a28020041ffffff3f71450d00200041086a28020010350b200041206a220128020010ba02200128020010350f0b2000412c6a28020041ffffff3f71450d11200041286a28020010350f0b2000412c6a28020041ffffff3f71450d10200041286a28020010350f0b02402000410c6a2802002201450d00200141f0006c2102200028020441046a21010340200110b1030240200141046a2802002203450d00200341246c450d00200128020010350b200141f0006a2101200241907f6a22020d000b0b200041086a2802002201450d0f200141f0006c450d0f200028020410350f0b0240200041086a2d0000220141174b0d000240024002400240024020010e18141414141414001414141414140114140203141414141404140b200041106a2802002201450d13200141246c450d132000410c6a28020010350f0b200041106a28020041ffffff3f71450d122000410c6a28020010350f0b200041146a28020041ffffffff0371450d11200041106a28020010350f0b200041146a2802002201450d10200141246c450d10200041106a28020010350f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010350b200041186a10fa010f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010350b200041186a10fa010f0b20002802042201450d0d200041086a280200450d0d200110350f0b200041086a2d0000416d6a220141014b0d0c0240024020010e020001000b200041106a280200450d0d2000410c6a28020010350f0b200041106a280200450d0c2000410c6a28020010350f0b20002d0004417f6a220141024b0d0b02400240024020010e03000102000b2000412c6a28020041ffffff3f71450d0d200041286a28020010350f0b200041086a220128020010ba02200128020010350f0b2000410c6a220128020010ba02200128020010350f0b20002d0004417f6a220141024b0d0a02400240024020010e03000102000b2000412c6a28020041ffffff3f71450d0c200041286a28020010350f0b200041086a220128020010ba02200128020010350f0b2000410c6a220128020010ba02200128020010350f0b200041086a2802004101470d09200041106a28020041ffffff3f71450d092000410c6a28020010350f0b20002d00044104470d082000410c6a28020041ffffff3f71450d08200041086a28020010350f0b200041086a280200450d07200028020410350f0b200041086a2d0000417c6a220141024b0d060240024020010e03000801000b200041306a280200450d072000412c6a28020010350f0b200041306a280200450d062000412c6a28020010350f0b200041086a2d0000417e6a220141024b0d0502400240024020010e03000102000b200041106a280200450d072000410c6a28020010350c070b200041346a280200450d06200041306a28020010350f0b200041306a280200450d052000412c6a28020010350f0b02402000280204220141024b0d00024020010e03060006060b200041086a220128020010ba02200128020010350f0b2000412c6a220128020010ba02200128020010350f0b02402000410c6a280200450d00200041086a28020010350b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b200041186a2802002201450d032001410c6c450d03200028021410350f0b200041086a2d0000417e6a220141014b0d020240024020010e020001000b0240200041146a2802002202450d002000410c6a2802002201200241c8006c6a21020340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b0240200041106a2802002201450d00200141c8006c450d00200028020c10350b0240200041186a2d00004101470d00200041206a280200450d002000411c6a28020010350b02402000413c6a2d00004101470d00200041c4006a280200450d00200041c0006a28020010350b0240200041e0006a2d00004101470d00200041e8006a280200450d00200041e4006a28020010350b024020004184016a2d00004101470d002000418c016a280200450d0020004188016a28020010350b0240200041a8016a2d00004101470d00200041b0016a280200450d00200041ac016a28020010350b0240200041cc016a2d00004101470d00200041d4016a280200450d00200041d0016a28020010350b200041f0016a2d00004101470d03200041f8016a280200450d03200041f4016a28020010350f0b0240200041146a2802002201450d00200141c4006c21022000410c6a28020041286a210103400240200141786a2d00004101470d002001280200450d002001417c6a28020010350b200141c4006a2101200241bc7f6a22020d000b0b200041106a2802002201450d02200141c4006c450d02200028020c10350f0b200041086a2d00004108470d01200041346a280200450d01200041306a28020010350f0b20002d0004417f6a220141024b0d000240024020010e03000201000b200041286a220128020010ba02200128020010350f0b2000410c6a28020041ffffff3f71450d00200041086a28020010350f0b0b9d1401037f02402000280200220141194b0d0002400240024002400240024002400240024002400240024002400240024002400240024020010e1a0001121202121203040506070809120a0b0c0d0e1212120f1011000b200041086a280200417e6a220141074b0d1102400240024002400240024020010e080017010217030405000b200041106a280200450d162000410c6a28020010350f0b200041106a280200450d152000410c6a28020010350f0b200041106a280200450d142000410c6a28020010350f0b0240200041146a2802002202450d002000410c6a2802002101200241186c210203400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141186a2101200241686a22020d000b0b200041106a2802002201450d13200141186c450d13200028020c10350f0b0240200041146a2802002202450d002000410c6a28020021012002410c6c210203400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b200041106a2802002201450d122001410c6c450d12200028020c10350f0b200041106a280200450d112000410c6a28020010350f0b024020002d0004220141044b0d00024002400240024020010e051500010203150b0240200041106a2802002202450d00200041086a2802002101200241b0026c21020340200110bb02200141b0026a2101200241d07d6a22020d000b0b2000410c6a2802002201450d14200141b0026c450d14200028020810350f0b200041086a220128020010bb02200128020010350f0b02402000410c6a28020041ffffff3f71450d00200041086a28020010350b200041206a220128020010bb02200128020010350f0b2000412c6a28020041ffffff3f71450d11200041286a28020010350f0b2000412c6a28020041ffffff3f71450d10200041286a28020010350f0b02402000410c6a2802002201450d00200141f0006c2102200028020441046a21010340200110b1030240200141046a2802002203450d00200341246c450d00200128020010350b200141f0006a2101200241907f6a22020d000b0b200041086a2802002201450d0f200141f0006c450d0f200028020410350f0b0240200041086a2d0000220141174b0d000240024002400240024020010e18141414141414001414141414140114140203141414141404140b200041106a2802002201450d13200141246c450d132000410c6a28020010350f0b200041106a28020041ffffff3f71450d122000410c6a28020010350f0b200041146a28020041ffffffff0371450d11200041106a28020010350f0b200041146a2802002201450d10200141246c450d10200041106a28020010350f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010350b200041186a10fa010f0b0240200041106a28020041808080807872418080808078460d002000410c6a28020010350b200041186a10fa010f0b20002802042201450d0d200041086a280200450d0d200110350f0b200041086a2d0000416d6a220141014b0d0c0240024020010e020001000b200041106a280200450d0d2000410c6a28020010350f0b200041106a280200450d0c2000410c6a28020010350f0b20002d0004417f6a220141024b0d0b02400240024020010e03000102000b2000412c6a28020041ffffff3f71450d0d200041286a28020010350f0b200041086a220128020010bb02200128020010350f0b2000410c6a220128020010bb02200128020010350f0b20002d0004417f6a220141024b0d0a02400240024020010e03000102000b2000412c6a28020041ffffff3f71450d0c200041286a28020010350f0b200041086a220128020010bb02200128020010350f0b2000410c6a220128020010bb02200128020010350f0b200041086a2802004101470d09200041106a28020041ffffff3f71450d092000410c6a28020010350f0b20002d00044104470d082000410c6a28020041ffffff3f71450d08200041086a28020010350f0b200041086a280200450d07200028020410350f0b200041086a2d0000417c6a220141024b0d060240024020010e03000801000b200041306a280200450d072000412c6a28020010350f0b200041306a280200450d062000412c6a28020010350f0b200041086a2d0000417e6a220141024b0d0502400240024020010e03000102000b200041106a280200450d072000410c6a28020010350c070b200041346a280200450d06200041306a28020010350f0b200041306a280200450d052000412c6a28020010350f0b02402000280204220141024b0d00024020010e03060006060b200041086a220128020010bb02200128020010350f0b2000412c6a220128020010bb02200128020010350f0b02402000410c6a280200450d00200041086a28020010350b02402000411c6a2802002202450d00200041146a28020021012002410c6c210203400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b200041186a2802002201450d032001410c6c450d03200028021410350f0b200041086a2d0000417e6a220141014b0d020240024020010e020001000b0240200041146a2802002202450d002000410c6a2802002201200241c8006c6a21020340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b0240200041106a2802002201450d00200141c8006c450d00200028020c10350b0240200041186a2d00004101470d00200041206a280200450d002000411c6a28020010350b02402000413c6a2d00004101470d00200041c4006a280200450d00200041c0006a28020010350b0240200041e0006a2d00004101470d00200041e8006a280200450d00200041e4006a28020010350b024020004184016a2d00004101470d002000418c016a280200450d0020004188016a28020010350b0240200041a8016a2d00004101470d00200041b0016a280200450d00200041ac016a28020010350b0240200041cc016a2d00004101470d00200041d4016a280200450d00200041d0016a28020010350b200041f0016a2d00004101470d03200041f8016a280200450d03200041f4016a28020010350f0b0240200041146a2802002201450d00200141c4006c21022000410c6a28020041286a210103400240200141786a2d00004101470d002001280200450d002001417c6a28020010350b200141c4006a2101200241bc7f6a22020d000b0b200041106a2802002201450d02200141c4006c450d02200028020c10350f0b200041086a2d00004108470d01200041346a280200450d01200041306a28020010350f0b20002d0004417f6a220141024b0d000240024020010e03000201000b200041286a220128020010bb02200128020010350f0b2000410c6a28020041ffffff3f71450d00200041086a28020010350f0b0bad0204017f017e017f027e230041d0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822010d00420021030c010b200228020c210402400240200241086a41086a2802004110490d00200141086a290000210520012900002106420121030c010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b420021030b2004450d00200110350b2000200637030820002003370300200041106a2005370300200241d0006a24000b950201047f230041d0006b220124002001412036020420012000360200200141086a2000ad4280808080800484100510c20102400240200128020822020d00410221000c010b200128020c210302400240200141106a280200450d0020022d0000220441014b0d0041002100024020040e020200020b410121000c010b20014100360220200142013703182001410936022c200120013602282001200141186a360234200141cc006a41013602002001420137023c200141c888c2003602382001200141286a360248200141346a41e88ac500200141386a10431a200135022042208620013502188410060240200128021c450d00200128021810350b410221000b2003450d00200210350b200141d0006a240020000bad0e04057f017e107f047e230041a0036b220224002002412036021420022001360210200241186a2001ad4280808080800484100510c2010240024002400240200228021822030d00200041003602000c010b200228021c21042002200241206a28020036022c20022003360228200241086a200241286a10c40102400240024020022802080d00200228020c2205200228022c220641e8006e2201200120054b1bad42e8007e2207422088a70d052007a72201417f4c0d050240024020010d00410821080c010b200110332208450d050b20024100360238200220083602302002200141e8006e36023402402005450d00200241e8026a41017221094100210a4100210b034041002101200241003a008803200b41016a210b0240024002400240034020062001460d01200241e8026a20016a2002280228220c2d00003a00002002200c41016a3602282002200141016a220c3a008803200c2101200c4120470d000b20024190026a41086a2201200241e8026a41086a220d29030037030020024190026a41106a220e200241e8026a41106a220f29030037030020024190026a41186a2210200241e8026a41186a2211290300370300200220022903e8023703900220022006200c6b36022c200241e8026a200241286a10bf0220022d00e802220c4102470d010c020b2002410036022c200141ff0171450d01200241003a0088034102210c0c020b200241b0026a412f6a22062009412f6a290000370000200241b0026a41286a2212200941286a290000370300200241b0026a41206a2213200941206a290000370300200241b0026a41186a2214200941186a290000370300200241b0026a41106a2215200941106a290000370300200241b0026a41086a2216200941086a290000370300200220092900003703b002200228022c22174110490d00200241f0016a41086a2001290300370300200241f0016a41106a200e290300370300200241f0016a41186a2010290300370300200d2016290300370300200f201529030037030020112014290300370300200241e8026a41206a2013290300370300200241e8026a41286a2012290300370300200241e8026a412f6a200629000037000020022002290390023703f001200220022903b0023703e8022002201741706a36022c20022002280228220141106a360228200141086a2900002118200129000021190c010b4102210c0b200241b8016a412f6a2201200241e8026a412f6a290000370000200241b8016a41286a2206200241e8026a41286a290300370300200241b8016a41206a220d200241e8026a41206a290300370300200241b8016a41186a220e200241e8026a41186a290300370300200241b8016a41106a220f200241e8026a41106a290300370300200241b8016a41086a2210200241e8026a41086a29030037030020024198016a41086a2211200241f0016a41086a29030037030020024198016a41106a2212200241f0016a41106a29030037030020024198016a41186a2213200241f0016a41186a290300370300200220022903e8023703b801200220022903f001370398010240200c4102460d00200241e0006a412f6a22142001290000370000200241e0006a41286a22152006290300370300200241e0006a41206a2206200d290300370300200241e0006a41186a220d200e290300370300200241e0006a41106a220e200f290300370300200241e0006a41086a220f2010290300370300200241c0006a41086a22102011290300370300200241c0006a41106a22112012290300370300200241c0006a41186a22122013290300370300200220022903b80137036020022002290398013703400240200a2002280234470d00200241306a200a4101109601200228023021082002280238210a0b2008200a41e8006c6a2201200c3a0000200141196a200d290300370000200141116a200e290300370000200141096a200f29030037000020012002290360370001201429000021072015290300211a2006290300211b200141c0006a2018370000200141386a2019370000200141216a201b370000200141296a201a370000200141306a2007370000200141c8006a2002290340370000200141d0006a2010290300370000200141d8006a2011290300370000200141e0006a20122903003700002002200a41016a220a360238200b2005460d02200228022c21060c010b0b20022802342201450d01200141e8006c450d01200810350c010b20080d010b200241003602b802200242013703b002200241093602bc012002200241106a3602b8012002200241b0026a360260200241fc026a4101360200200242013702ec02200241c888c2003602e8022002200241b8016a3602f802200241e0006a41e88ac500200241e8026a10431a20023502b80242208620023502b002841006024020022802b402450d0020022802b00210350b200041003602000c010b20002002290234370204200020083602000b2004450d00200310350b200241a0036a24000f0b1045000b1044000bcc0502077f067e230041f0006b2102024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a360200200541014b0d0320050e020102010b200041023a00000f0b024020064110490d00200041003a000020002002280028360001200041086a2004290001370300200041186a2002290348370300200041106a200441096a29000037030020012003416f6a3602042001200441116a360200200041046a2002412b6a280000360000200041206a200241c8006a41086a290300370300200041286a200241c8006a41106a290300370300200041306a200241c8006a41186a2903003703000f0b200041023a00000f0b41002105200241003a00682003417f6a2107417e210602400240034020072005460d01200241c8006a20056a200420056a220841016a2d00003a00002001200320066a3602042001200841026a3602002002200541016a22083a00682006417f6a21062008210520084120470d000b200241286a41186a2205200241c8006a41186a290300370300200241286a41106a2206200241c8006a41106a290300370300200241286a41086a2207200241c8006a41086a290300370300200220022903483703282008417f7320036a4110490d01200241086a41086a20072903002209370300200241086a41106a2006290300220a370300200241086a41186a2005290300220b370300200420086a220541016a290000210c200541096a290000210d2001200320086b416f6a3602042001200541116a36020020022002290328220e370308200041013a00002000200e370001200041096a2009370000200041116a200a370000200041196a200b370000200041306a200d370300200041286a200c370300200041216a2002280001360000200041246a200241046a2800003600000f0b200541ff0171450d00200241003a00680b200041023a00000f0b200041023a00000bfe0301057f230041f0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022030d00200041033a00200c010b200241186a28020021042002280214210541002101200241003a0068024002400240034020042001460d01200241c8006a20016a200320016a2d00003a00002002200141016a22063a00682006210120064120470d000b200241286a41186a200241c8006a41186a290300370300200241286a41106a200241c8006a41106a290300370300200241286a41086a200241c8006a41086a2903003703002002200229034837032820042006460d01200320066a2d0000220141034f0d0120002002290328370000200041186a200241286a41186a290300370000200041106a200241286a41106a290300370000200041086a200241286a41086a2903003700000c020b200141ff0171450d00200241003a00680b2002410036023020024201370328200241093602242002200241086a3602202002200241286a36026c200241dc006a41013602002002420137024c200241c888c2003602482002200241206a360258200241ec006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b410321010b200020013a00202005450d00200310350b200241f0006a24000bd60201027f230041c0026b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003a00000c010b200328021421042003200341186a2802003602ac02200320013602a802200341a0016a200341a8026a10c202410121020240024020032d00a0014101470d00410021022003410036022820034201370320200341093602b4022003200341086a3602b0022003200341206a3602bc02200341b4016a4101360200200342013702a401200341c888c2003602a0012003200341b0026a3602b001200341bc026a41e88ac500200341a0016a10431a200335022842208620033502208410062003280224450d01200328022010350c010b200341206a200341a0016a410172418001109d081a200041016a200341206a418001109d081a0b200020023a00002004450d00200110350b200341c0026a24000ba60901077f230041d0026b2202240041002103200241003a002820012802042104417f210502400240024002400240034020042003460d01200241086a20036a200128020022062d00003a00002001200420056a3602042001200641016a3602002002200341016a22073a00282005417f6a21052007210320074120470d000b20024188016a41086a200241086a41086a29030037030020024188016a41106a200241086a41106a29030037030020024188016a41186a200241086a41186a290300370300200220022903083703880141002108200241003a0028200420076b2107200420056a2103034020072008460d02200241086a20086a200620086a220541016a2d00003a0000200120033602042001200541026a3602002002200841016a22053a00282003417f6a21032005210820054120470d000b200241a8016a41086a200241086a41086a290300370300200241a8016a41106a200241086a41106a290300370300200241a8016a41186a200241086a41186a290300370300200220022903083703a80141002107200241003a0028200620056a210803402003417f460d03200241086a20076a200820076a220541016a2d00003a0000200120033602042001200541026a3602002002200741016a22053a00282003417f6a21032005210720054120470d000b200241c8016a41086a200241086a41086a290300370300200241c8016a41106a200241086a41106a290300370300200241c8016a41186a200241086a41186a290300370300200220022903083703c80141002107200241003a00c802200820056a41016a210503402003417f460d04200241a8026a20076a20052d00003a0000200120033602042001200541016a22053602002002200741016a22083a00c8022003417f6a21032008210720084120470d000b200241e8016a41086a2201200241a8026a41086a290300370300200241e8016a41106a2203200241a8026a41106a290300370300200241e8016a41186a2205200241a8026a41186a290300370300200241086a41086a20024188016a41086a290300370300200241086a41106a20024188016a41106a290300370300200241086a41186a20024188016a41186a290300370300200220022903a8023703e8012002200229038801370308200241c0006a200241a8016a41186a290300370300200241386a200241a8016a41106a290300370300200241306a200241a8016a41086a290300370300200220022903a801370328200241e0006a200241c8016a41186a290300370300200241d8006a200241c8016a41106a290300370300200241d0006a200241c8016a41086a290300370300200220022903c80137034820024180016a2005290300370300200241f8006a2003290300370300200241f0006a2001290300370300200220022903e801370368200041016a200241086a418001109d081a200041003a00000c040b0240200341ff0171450d00200241003a00280b200041013a00000c030b0240200841ff0171450d00200241003a00280b200041013a00000c020b0240200741ff0171450d00200241003a00280b200041013a00000c010b0240200741ff0171450d00200241003a00c8020b200041013a00000b200241d0026a24000b8a06010c7f23004190016b220324002003200236021420032001360210200341186a2002ad4220862001ad84100510c2010240024002400240200328021822040d00200041003602000c010b200328021c21052003200341206a28020036022c20032004360228200341086a200341286a10c4010240024020032802080d00200328020c2206200328022c22074105762201200120064b1b22014105742202417f4c0d030240024020010d00410121080c010b200210332208450d050b41002109200341003602402003200136023c20032008360238024002402006450d004100210a03402007210b41002101200341003a008801200a41016a210a0340200b2001460d03200341e8006a20016a200328022822022d00003a00002003200241016a3602282003200141016a22023a0088012002210120024120470d000b200341c8006a41186a220c200341e8006a41186a290300370300200341c8006a41106a220d200341e8006a41106a290300370300200341c8006a41086a220e200341e8006a41086a2903003703002003200329036837034802402009200328023c470d00200341386a20094101108a0120032802382108200328024021090b200b20026b2107200820094105746a22012003290348370000200141186a200c290300370000200141106a200d290300370000200141086a200e2903003700002003200941016a2209360240200a2006470d000b2003200b20026b36022c0b2008450d012000200329023c370204200020083602000c020b2003410036022c0240200141ff0171450d00200341003a0088010b200328023c41ffffff3f71450d00200810350b20034100360250200342013703482003410936023c2003200341106a3602382003200341c8006a360234200341fc006a41013602002003420137026c200341c888c2003602682003200341386a360278200341346a41e88ac500200341e8006a10431a200335025042208620033502488410060240200328024c450d00200328024810350b200041003602000b2005450d00200410350b20034190016a24000f0b1044000b1045000bab0602057f047e23004190016b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022040d00200041023a00000c010b2003280214210502400240200341186a2802002201450d0020042d0000220241014b0d002001417f6a2106024002400240024020020e020001000b41002101200341003a008801200441016a21070240034020062001460d01200341e8006a20016a200720016a2d00003a00002003200141016a22023a0088012002210120024120470d000b200341c8006a41186a200341e8006a41186a2903002208370300200341206a41086a200341e8006a41086a290300370300200341206a41106a200341e8006a41106a290300370300200341206a41186a200837030020032003290368370320410021010c020b200141ff0171450d03200341003a0088010c030b41002101200341003a008801200441016a2107034020062001460d02200341e8006a20016a200720016a2d00003a00002003200141016a22023a0088012002210120024120470d000b200341c8006a41186a200341e8006a41186a2903002208370300200341206a41086a200341e8006a41086a290300370300200341206a41106a200341e8006a41106a290300370300200341206a41186a200837030020032003290368370320410121010b200341e8006a41186a200341206a41186a2903002208370300200341e8006a41106a200341206a41106a2903002209370300200341e8006a41086a200341206a41086a290300220a37030020032003290320220b370368200041196a2008370000200041116a2009370000200041096a200a3700002000200b3700010c020b200141ff0171450d00200341003a0088010b2003410036025020034201370348200341093602242003200341086a3602202003200341c8006a360244200341fc006a41013602002003420137026c200341c888c2003602682003200341206a360278200341c4006a41e88ac500200341e8006a10431a200335025042208620033502488410060240200328024c450d00200328024810350b410221010b200020013a00002005450d00200410350b20034190016a24000ba20403047f017e027f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022010d00200041003602000c010b200228021421032002200241186a280200360224200220013602202002200241206a10c4010240024020022802000d002002280224220420022802044102742205490d0002400240024002402005417f4c0d000240024020050d0042002106410121070c010b200510392207450d022007200228022022082005109d081a2002200420056b3602242002200820056a3602202005ad21060b2007450d04024020062005ad422086842206422088a722050d002006a721050c030b024020072005724103710d002006a722054103710d0020054102762204450d032006422288a721080c040b2006a7450d04200710350c040b1044000b1045000b4100210802402005450d00200710350b41002104410421070b41000d002007450d002000200436020420002007360200200041086a20083602000c010b20024100360230200242013703282002410936023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b200041003602000b2003450d00200110350b200241e0006a24000bef1104047f017e137f047e23004180036b220224002002412036022420022001360220200241286a2001ad4280808080800484100510c2010240024002400240200228022822030d00200041003602000c010b200228022c21042002200241306a28020036023c20022003360238200241186a200241386a10c4010240024020022802180d00200228021c2205200228023c411c6e2201200120054b1bad421c7e2206422088a70d032006a72201417f4c0d030240024020010d00410421070c010b200110332207450d050b200241003602482002200736024020022001411c6e36024402400240024002400240024002402005450d00200241a0026a41c4006a2108410021094100210a0340200241106a200241386a10c40120022802100d072002280214220b200228023c41e0006e22012001200b4b1bad42e0007e2206422088a70d0b2006a72201417f4c0d0b0240024020010d004108210c0c010b20011033220c450d0d0b200241003602582002200c3602502002200141e0006e3602540240024002400240200b450d004100210d0340200241a0026a200241386a10c702200241e0016a41386a2201200241a0026a41386a290300370300200241e0016a41306a220e200241a0026a41306a290300370300200241e0016a41286a220f200241a0026a41286a290300370300200241e0016a41206a2210200241a0026a41206a290300370300200241e0016a41186a2211200241a0026a41186a290300370300200241e0016a41106a2212200241a0026a41106a290300370300200241e0016a41086a2213200241a0026a41086a290300370300200241c0016a41086a2214200841086a290200370300200241c0016a41106a2215200841106a290200370300200241c0016a41186a2216200841186a280200360200200220022903a0023703e001200220082902003703c00120022802e0022217450d0220024180016a41386a2218200129030037030020024180016a41306a2219200e29030037030020024180016a41286a220e200f29030037030020024180016a41206a220f201029030037030020024180016a41186a2210201129030037030020024180016a41106a2211201229030037030020024180016a41086a22122013290300370300200241e0006a41086a22132014290300370300200241e0006a41106a22142015290300370300200241e0006a41186a22152016280200360200200220022903e00137038001200220022903c0013703600240200d2002280254470d00200241d0006a200d410110a4012002280250210c2002280258210d0b200c200d41e0006c6a2201200229038001370300200141106a2011290300370300200141086a2012290300370300201929030021062018290300211a200e290300211b200f290300211c2010290300211d200141c0006a2017360200200141186a201d370300200141206a201c370300200141286a201b370300200141c4006a2002290360370200200141386a201a370300200141306a2006370300200141cc006a2013290300370200200141d4006a2014290300370200200141dc006a20152802003602002002200d41016a220d360258200b417f6a220b0d000b0b200c450d0a20022902542106200241086a200241386a10c40120022802080d07200228020c220b200228023c220d41027622012001200b4b1b2201410274220e417f4c0d0e20010d014104210f0c020b0240200d450d00200d41e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010350b0240200128020041ffffff3f71450d002001417c6a28020010350b200141e0006a2101200d41a07f6a220d0d000b0b20022802542201450d09200141e0006c0d080c090b200e1033220f450d0d0b200241003602a802200220013602a4022002200f3602a0020240200b450d00410021010340200d4104490d0520022002280238220e41046a360238200e280000220e418094ebdc034b0d040240200120022802a402470d00200241a0026a2001410110860120022802a002210f20022802a80221010b200d417c6a210d200f20014102746a200e3602002002200141016a22013602a802200b417f6a220b0d000b2002200d36023c0b200f450d0420022902a402211a200d4104490d05200a41016a210a2002200d417c6a36023c20022002280238220141046a3602382001280000210d024020092002280244470d00200241c0006a2009410110f90120022802402107200228024821090b20072009411c6c6a2201200d360218200120063702042001200c360200200141106a201a3702002001410c6a200f3602002002200941016a2209360248200a2005470d000b0b2007450d0620002002290244370204200020073602000c070b200d417c6a210d0b2002200d36023c20022802a40241ffffffff0371450d00200f10350b02402006422088a72201450d00200141e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010350b0240200128020041ffffff3f71450d002001417c6a28020010350b200141e0006a2101200d41a07f6a220d0d000b0b2006a72201450d02200141e0006c0d010c020b0240201a42ffffffff0383500d00200f10350b02402006422088a72201450d00200141e0006c210d200c41d4006a210103400240200141706a2802002208450d00200841306c450d002001416c6a28020010350b0240200128020041ffffff3f71450d002001417c6a28020010350b200141e0006a2101200d41a07f6a220d0d000b0b2006a72201450d01200141e0006c450d010b200c10350b2007200910c80220022802442201450d002001411c6c450d00200710350b200241003602e801200242013703e00120024109360284012002200241206a360280012002200241e0016a3602c001200241b4026a4101360200200242013702a402200241c888c2003602a002200220024180016a3602b002200241c0016a41e88ac500200241a0026a10431a20023502e80142208620023502e001841006024020022802e401450d0020022802e00110350b200041003602000b2004450d00200310350b20024180036a24000f0b1044000b1045000b9e06020a7f017e230041d0016b2202240041002103200241003a00c0012001280204417f6a2104024002400240024003402004417f460d01200241a0016a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c0012004417f6a21042005210320054120470d000b20024180016a41186a2204200241a0016a41186a220329030037030020024180016a41106a2205200241a0016a41106a220629030037030020024180016a41086a2207200241a0016a41086a2208290300370300200220022903a00137038001200241a0016a200110c50120022802c0012209450d01200241c0006a41186a220a2004290300370300200241c0006a41106a220b2005290300370300200241c0006a41086a22052007290300370300200241c0006a41286a22072008290300370300200241c0006a41306a22082006290300370300200241c0006a41386a220620032903003703002002200229038001370340200220022903a001370360200241c4016a2802002104200241a0016a41286a290300210c200241086a2005290300370300200241106a200b290300370300200241186a200a290300370300200241206a22032002290360370300200241286a22052007290300370300200241306a22072008290300370300200241386a2208200629030037030020022002290340370300200241c0006a200110c3012002280240450d02200241a0016a41086a2201200241c0006a41086a280200360200200220022903403703a001200041386a2008290300370300200041306a2007290300370300200041286a2005290300370300200041206a2003290300370300200041186a200241186a290300370300200041106a200241106a290300370300200041086a200241086a29030037030020002002290300370300200041c8006a200c3703002000200436024420002009360240200041d0006a20022903a001370300200041d8006a20012802003602000c030b200341ff0171450d00200241003a00c0010b200041003602400c010b200041003602402004450d00200441306c450d00200910350b200241d0016a24000bd90101037f02402001450d0020002001411c6c6a21020340024020002802082201450d00200141e0006c2103200028020041d4006a210103400240200141706a2802002204450d00200441306c450d002001416c6a28020010350b0240200128020041ffffff3f71450d002001417c6a28020010350b200141e0006a2101200341a07f6a22030d000b0b0240200041046a2802002201450d00200141e0006c450d00200028020010350b2000411c6a21010240200041106a28020041ffffffff0371450d00200028020c10350b2001210020012002470d000b0b0bbb1005057f017e067f077e017f230041c0016b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c2010240024002400240200328021022020d00200041023a00000c010b200328021421042003200341186a280200220536025420032002360250024002402005450d0020022d0000210120032005417f6a22063602542003200241016a360250200141014b0d00024002400240024020010e020001000b2003200341d0006a10c40120032802000d03200328020422062003280254220141306e2207200720064b1bad42307e2208422088a70d062008a72207417f4c0d060240024020070d00410821090c010b200710332209450d080b4100210a20034100360268200320093602602003200741306e220b36026402402006450d002006417f6a210720034198016a41017221064100210a02400240034020014104490d0120032802502205350000210820032001417c6a3602542003200541046a36025020034198016a200341d0006a10ca0220032d00980122054102460d01200341f0006a411f6a220b2006411f6a290000370000200341f0006a41186a220c200641186a290000370300200341f0006a41106a220d200641106a290000370300200341f0006a41086a220e200641086a290000370300200320062900003703700240200a2003280264470d00200341e0006a200a4101108801200328026021092003280268210a0b2009200a41306c6a220120053a000820012008370300200141096a2003290370370000200141116a200e290300370000200141196a200d290300370000200141216a200c290300370000200141286a200b2900003700002003200a41016a220a3602682007450d022007417f6a2107200328025421010c000b0b20032802642201450d05200141306c450d05200910350c050b2003280264210b0b2009450d0302400240200328025422014110490d0020032003280250220641106a3602502003200141706a220736025420074110490d00200641086a290000210f200629000021102003200641206a3602502003200141606a220736025420074104490d01200641186a2900002108200629001021112003200641246a36025020032001415c6a220736025420074110490d0120062800202107200341386a2006412c6a290000370300200341cc006a41026a200341dd006a41026a2d00003a000020032011370320200320032f005d3b014c20032007360240200320062900243703302003200837032820032001414c6a3602542003200641346a360250410021010c030b200b450d04200b41306c450d04200910350c040b200b450d03200b41306c450d03200910350c030b20064110490d0220032005416f6a220a3602542003200241116a360250200241096a29000021082002290001211141002101200341003a00b801416e21060340200a2001460d0220034198016a20016a200220016a220741116a2d00003a00002003200520066a3602542003200741126a3602502003200141016a22073a00b8012006417f6a21062007210120074120470d000b200341e2006a20032d009a013a0000200320032f0198013b01602005416f6a2007460d02200341af016a290000210f20032900a7012110200328009b012109200328009f01210b20032800a301210a20032d00b701210d200220076a220141116a2d0000210c2003200520066a22063602542003200141126a360250200c41074f0d0220064110490d022003200141226a220e3602502003200520076b2207415e6a220636025420064110490d022001411a6a2900002112200141126a29000021132003200141326a220536025020032007414e6a220636025420064104490d022001412a6a2900002114200e2900002115200528000021062003200141366a220e36025020032007414a6a220536025420054110490d02200341cc006a41026a200341e0006a41026a2d00003a0000200341c0006a2012370300200341206a41106a2008370300200320032f01603b014c2003200741ba7f6a3602542003200141c6006a36025020032013370338200320113703282003200c3a00212003200d3a0020200320032801703601222003200341f4006a2f01003b01262001413e6a2900002111200e2900002108410121010b200341f0006a41026a200341cc006a41026a2d000022073a000020034198016a41086a2205200341206a41086a29030037030020034198016a41106a220c200341206a41106a29030037030020034198016a41186a220d200341206a41186a29030037030020034198016a41206a220e200341206a41206a290300370300200320032f014c22163b01702003200329032037039801200041186a200f370000200041106a2010370000200041036a20073a0000200020163b00012000410c6a200a360000200041086a200b360000200041046a2009360000200041e8006a2006360000200041e0006a2011370000200041d8006a2008370000200041d0006a2014370000200041c8006a2015370000200041206a200329039801370000200041286a2005290300370000200041306a200c290300370000200041386a200d290300370000200041c0006a200e2903003700000c020b200141ff0171450d00200341003a00b8010b2003410036022820034201370320200341093602742003200341086a3602702003200341206a360260200341ac016a41013602002003420137029c01200341c888c200360298012003200341f0006a3602a801200341e0006a41e88ac50020034198016a10431a2003350228422086200335022084100602402003280224450d00200328022010350b410221010b200020013a00002004450d00200210350b200341c0016a24000f0b1044000b1045000b840402067f047e230041206b21020240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a2207360200200541014b0d0320050e020102010b200041023a00000f0b02402006450d0020042d0001210520012003417e6a22063602042001200441026a360200200541ff0071220741064b0d0020064110490d00200041003a0000200041086a2004290002370300200041026a20073a0000200020054107763a0001200041036a2002280009360000200041186a2002290310370300200041106a2004410a6a29000037030020012003416e6a3602042001200441126a360200200041076a2002410d6a2d00003a0000200041206a200241106a41086a2903003703000f0b200041023a00000f0b200241106a41086a220542003703002002420037031020064110490d01200741086a29000021082007290000210920012003416f6a22063602042001200441116a2207360200200542003703002002420037031020064110490d01200741086a290000210a2007290000210b20012003415f6a3602042001200441216a360200200041206a200a370300200041186a200b370300200041106a2008370300200041086a2009370300200041013a000020002002280009360001200041046a2002410c6a2800003600000f0b200041023a00000f0b200041023a00000bbb0402097f057e230041f0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022040d00200042003703000c010b200341186a28020021052003280214210641002101200341003a0068024002400240034020052001460d01200341c8006a20016a200420016a2d00003a00002003200141016a22023a00682002210120024120470d000b200341286a41186a2201200341c8006a41186a2207290300370300200341286a41106a2208200341c8006a41106a2209290300370300200341286a41086a220a200341c8006a41086a220b29030037030020032003290348370328200520026b410f4d0d01200b200a290300220c37030020092008290300220d37030020072001290300220e37030020032003290328220f370348200420026a22012900002110200041306a200141086a290000370300200041286a2010370300200041206a200e370300200041186a200d370300200041106a200c3703002000200f3703084201210c0c020b200141ff0171450d00200341003a00680b2003410036023020034201370328200341093602242003200341086a3602202003200341286a36026c200341dc006a41013602002003420137024c200341c888c2003602482003200341206a360258200341ec006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b4200210c0b2000200c3703002006450d00200410350b200341f0006a24000bf80202027f037e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602100c010b200328021421042003200341106a41086a28020022023602242003200136022002400240024020024110490d002003200241706a3602242003200141106a360220200141086a290000210520012900002106200341c8006a200341206a10c301200328024822020d010b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602100c010b200329024c2107200020053703082000200637030020002007370214200020023602100b2004450d00200110350b200341e0006a24000bde0201037f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602040c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d0020032002417c6a3602242003200141046a36022020012800002102200341c8006a200341206a10c301200328024822050d010b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602040c010b2000200329024c37020820002005360204200020023602000b2004450d00200110350b200341e0006a24000bb10201037f230041e0006b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c20102400240200228021022010d00200041003602000c010b200228021421032002200241186a28020036022420022001360220200241c8006a200241206a10cf0202400240200228024822040d0020024100360230200242013703282002410936023c2002200241086a3602382002200241286a360244200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b200041003602000c010b2000200229024c370204200020043602000b2003450d00200110350b200241e0006a24000b8f0d05037f017e0a7f017e047f23004180016b22022400200241086a200110c40102400240024002402002280208450d00200041003602000c010b200228020c2203200128020441246e2204200420034b1bad42247e2205422088a70d022005a72204417f4c0d020240024020040d00410421060c010b200410332206450d020b4100210720024100360218200220063602102002200441246e36021402402003450d00200241cd006a2108200241eb006a220941056a210a4100210b0340024002400240024002402001280204220c450d002001280200220d2d000021042001200c417f6a220e3602042001200d41016a360200200441074b0d00024002400240024002400240024020040e080007010703040205000b2002200110c40120022802000d06200128020420022802042204490d062004417f4c0d0f024020040d004101210f4101450d074100210d0c090b20041039220f450d0e20012802042004490d05200f20012802002004109d08210c2001280204220d2004490d072001200d20046b3602042001200128020020046a360200200c450d062004210d0c080b41002104200241003a0078200c417e6a210c02400340200e2004460d01200241d8006a20046a200d20046a220f41016a2d00003a00002001200c3602042001200f41026a3602002002200441016a220f3a0078200c417f6a210c200f2104200f4120470d000b200220092900003703402002200a290000370045200228005f210d20022f0158210420022d005a210c200228005b210f20022900632110200841026a200241d5006a41026a2d00003a0000200820022f00553b00002010428080808070832105200f41087621112004200c41107472210c2010a721044100210e0c0a0b200441ff0171450d05200241003a00780c050b200241d8006a200110c405200228025c220d450d0420022f015820022d005a41107472210c20022d005b210f200229036022104280808080708321052010a721044101210e0c080b200241d8006a200110c405200228025c220d450d0320022f015820022d005a41107472210c20022d005b210f200229036022104280808080708321052010a721044102210e0c070b200241d8006a200110c405200228025c220d450d0220022f015820022d005a41107472210c20022d005b210f200229036022104280808080708321052010a721044103210e0c060b200e450d01200d2d000121042001200c417e6a220f3602042001200d41026a36020020040d01200f450d01200d2d000221042001200c417d6a220e3602042001200d41036a360200200441014b0d014100210f0240024020040e020100010b200e4104490d02200d28000321122001200c41796a22043602042001200d41076a36020020044104490d02200d28000721132001200c41756a3602042001200d410b6a3602004101210f0b200241c0006a41086a200241d8006a41086a290200370300200220022902583703404104210e4200210541002111201321042012210d0c040b200f10350b200241306a41086a200241c0006a41086a290300370300200220022903403703302000410036020002402007450d00200741246c21042006210103400240024020012d0000220c41044b0d00024002400240200c0e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012004415c6a22040d000b0b20022802142201450d06200141246c450d06200610350c060b2004200d41a4f0cb001059000b200241c0006a41086a200241d8006a41086a29020037030020022002290258370340200f41087621114105210e420021050b0b200b41016a210b200241306a41086a200241c0006a41086a2903002210370300200241206a41086a22142010370300200220022903402210370330200220103703202011410874200f41ff017172210f20052004ad842105024020072002280214470d00200241106a20074101108d0120022802102106200228021821070b2006200741246c6a2204200537000c2004200d3600082004200f3600042004200c3b00012004200e3a0000200441036a200c4110763a0000200420022903203700142004411c6a20142903003700002002200741016a2207360218200b2003470d000b0b20002002290310370200200041086a200241106a41086a2802003602000b20024180016a24000f0b1045000b1044000ba00302037f037e230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602140c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d002003200141046a36022020032002417c6a220536022420054110490d002001280000210520032002416c6a3602242003200141146a3602202001410c6a290000210620012900042107200341c8006a200341206a10c301200328024822020d010b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602140c010b200329024c210820002006370308200020073703002000200837031820002002360214200020053602100b2004450d00200110350b200341e0006a24000b940201037f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad84100510c20102400240200228020822010d00410221000c010b200228020c210302400240200241106a280200450d0020012d0000220441014b0d0041002100024020040e020200020b410121000c010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b410221000b2003450d00200110350b200241d0006a240020000bd70b06057f017e057f017e027f037e230041a0016b220324002003200236021420032001360210200341186a2002ad4220862001ad84100510c2010240024002400240200328021822010d00200041023a00000c010b200328021c21042003200341206a280200220236024c20032001360248024002402002450d0020012d0000210520032002417f6a220636024c2003200141016a360248200541014b0d000240024002400240024020050e020001000b20064104490d04200341c4006a41026a200341d8006a41026a2d00003a0000200341286a41086a200341f8006a41086a290300370300200341286a41106a200341f8006a41106a290300370300200341286a41186a200341f8006a41186a280200360200200320032f00583b0144200320032903783703282001280001210520032002417b6a36024c2003200141056a360248410021020c010b200341086a200341c8006a10c40120032802080d03200328024c2207200328020c2205490d032005417f4c0d060240024020050d0042002108410121090c010b200510392209450d082009200328024822022005109d081a2003200720056b220736024c2003200220056a3602482005ad21080b2009450d0341002102200341003a0098012005ad4220862008842208422088a7210a2008a7210b417f21050240024002400240034020072002460d01200341f8006a20026a2003280248220c2d00003a00002003200720056a36024c2003200c41016a3602482003200241016a22063a0098012005417f6a21052006210220064120470d000b200341d2006a20032d007a3a0000200341e0006a20034187016a290000370300200341d8006a41106a2003418f016a290000370300200341f0006a20034197016a2d00003a0000200320032f01783b01502003200329007f370358200720066b22024110490d01200328007b21052003200c41116a3602482003200241706a220d36024c200d4104490d05200c41096a290000210e200c29000121082003200c41156a36024820032002416c6a36024c2007416c6a2006460d05200c28001121062003200c41166a36024820032002416b6a220f36024c200c2d0015221041014b0d054100210d20100e020302030b200241ff0171450d00200341003a0098010b200b0d040c050b200f4104490d022003200c411a6a3602482003200241676a36024c200c28001621074101210d0b200341c4006a41026a200341d0006a41026a2d00003a0000200341286a41086a200341d8006a41086a290300370300200341286a41106a200341d8006a41106a290300370300200341286a41186a200341d8006a41186a2d00003a0000200341c3006a200341d5006a41026a2d00003a0000200320032f01503b014420032003290358370328200320032f00553b0041410121020b200341d8006a41026a200341c4006a41026a2d0000220c3a0000200341f8006a41086a200341286a41086a2903002211370300200341f8006a41106a200341286a41106a2903002212370300200341f8006a41186a200341286a41186a2802002210360200200320032f0144220f3b0158200320032903282213370378200041036a200c3a00002000200f3b0001200041046a2005360000200041c8006a200e370000200041c0006a2008370000200041086a2013370000200041106a2011370000200041186a2012370000200041206a2010360000200041386a2007360000200041346a200d360000200041306a20063600002000412c6a200a360000200041286a200b360000200041246a20093600000c030b200b450d010b200910350b20034100360230200342013703282003410936025c2003200341106a3602582003200341286a3602502003418c016a41013602002003420137027c200341c888c2003602782003200341d8006a36028801200341d0006a41e88ac500200341f8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b410221020b200020023a00002004450d00200110350b200341a0016a24000f0b1044000b1045000b850604067f027e027f057e23004190016b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822020d00200041003602180c010b200328020c21042003200341106a280200220136023c200320023602380240024020014104490d002003200241046a36023820032001417c6a220536023c20054104490d00200228000021062003200241086a3602382003200141786a220536023c20054110490d00200228000421072003200141686a220836023c2003200241186a360238200241106a29000021092002290008210a41002101200341003a0088010240034020082001460d01200341e8006a20016a200220016a220541186a2d00003a00002003200541196a3602382003200141016a22053a0088012005210120054120470d000b200341c8006a41086a2201200341e8006a41086a290300370300200341c8006a41106a220b200341e8006a41106a290300370300200341c8006a41186a220c200341e8006a41186a290300370300200320032903683703482003200820056b36023c200341e8006a200341386a10c30120032802682205450d01200341186a41086a2001290300220d370300200341186a41106a200b290300220e370300200341186a41186a200c290300220f370300200320032903482210370318200329026c2111200020093703082000200a3703002000201137021c200020053602182000200736021420002006360210200041246a20103702002000412c6a200d370200200041346a200e3702002000413c6a200f3702000c020b2003410036023c200141ff0171450d00200341003a0088010b20034100360250200342013703482003410936021c200320033602182003200341c8006a360244200341fc006a41013602002003420137026c200341c888c2003602682003200341186a360278200341c4006a41e88ac500200341e8006a10431a200335025042208620033502488410060240200328024c450d00200328024810350b200041003602180b2004450d00200210350b20034190016a24000bfa4f07087f017e017f017e017f027e4f7f230041d0086b220324002003200236021420032001360210200341186a2002ad4220862001ad84100510c20102400240200328021822040d00200041023a00a4020c010b200328021c21052003200341186a41086a280200360294022003200436029002200320034190026a36028804200341086a20034188046a10d5020240024020032802080d004108210602400240200328020c22074180012007418001491b2201450d00200141057410332206450d010b2003410036028808200320013602840820032006360280080240024002400240024002402007450d00200341b0086a2108410021010340200341003602a808200341a8086a20032802900222092003280294022202410420024104491b220a109d081a20032002200a6b3602940220032009200a6a360290020240200241034b0d00200341a8086a200a6a41004104200a6b109f081a0b20033502a808210b200341003a00a80820032802940222022002410047220a490d02200341a8086a2003280290022209200a109d081a20032002200a6b220c3602940220032009200a6a220a3602900202400240024020020d004200210d0c010b20032d00a808220241064b0d044200210d02400240024002400240024020020e0707000102030405070b200341a8086a200c4110200c4110491b22026a41004100411020026b22092002410f4b1b109f08210e200341a8086a200a2002109d081a2003200c20026b360294022003200a20026a360290020240200c410f4b0d00200e41002009109f081a0b2008290300210f20032903a80821104201210d0c060b4202210d0c040b4203210d0c030b4204210d0c020b4205210d0c010b4206210d0b0b02402001200328028408470d0020034180086a2001410110a101200328028008210620032802880821010b200620014105746a2202200d3703082002200b370300200241186a200f370300200241106a20103703002003200141016a2201360288082007417f6a22070d000b0b2006450d06200329028408210d200341b0086a220a4200370300200342003703a808200341a8086a20032802900222072003280294022201411020014110491b2202109d081a2003200120026b360294022003200720026a3602900202402001410f4b0d00200341a8086a20026a4100411020026b109f081a0b200a290300210f20032903a8082110200320034188046a10d50220032802000d0320032802042209413820094138491b22070d014104210a0c020b20032802840841ffffff3f71450d0520061035410221010c060b200741c8006c1033220a450d030b410021022003410036028006200320073602fc052003200a3602f805024002400240024002400240024002402009450d0020034180086a410c6a211120034180086a410172211241002102034020034180086a20034188046a10d6020240024020032d00800822074106470d00410621070c010b200341fc076a41026a2208201241026a2d00003a0000200341e0076a41086a220e201141086a290200370300200341e0076a41106a2213201141106a290200370300200320122f00003b01fc07200320112902003703e007200328028408210c2003280288082101200341a8086a20034188046a10d602024020032d00a8084106470d00024020074101470d002001450d00200c10350b410621070c010b200341dc076a41026a20082d00003a0000200341c0076a41086a200e290300370300200341c0076a41106a201329030037030020034198076a41086a200341a8086a41086a29030037030020034198076a41106a200341a8086a41106a29030037030020034198076a41186a200341a8086a41186a29030037030020034198076a41206a200341a8086a41206a280200360200200320032f01fc073b01dc07200320032903e0073703c007200320032903a8083703980720012114200c21150b20034194076a41026a2201200341dc076a41026a2d00003a0000200341f8066a41086a220c200341c0076a41086a290300370300200341f8066a41106a2208200341c0076a41106a290300370300200341d0066a41086a220e20034198076a41086a290300370300200341d0066a41106a221320034198076a41106a290300370300200341d0066a41186a221620034198076a41186a290300370300200341d0066a41206a221720034198076a41206a280200360200200320032f01dc073b019407200320032903c0073703f80620032003290398073703d00620074106460d02200341cc066a41026a221820012d00003a0000200341b0066a41086a2219200c290300370300200341b0066a41106a220c200829030037030020034188066a41086a2208200e29030037030020034188066a41106a220e201329030037030020034188066a41186a2213201629030037030020034188066a41206a22162017280200360200200320032f0194073b01cc06200320032903f8063703b006200320032903d006370388060240200220032802fc05470d00200341f8056a2002410110a80120032802f805210a20032802800621020b200a200241c8006c6a220120073a0000200141086a2014360000200141046a2015360000200141036a20182d00003a0000200120032f01cc063b0001200141146a20192903003700002001411c6a200c2903003700002001410c6a20032903b006370000200141246a200329038806370000200141346a200e2903003700002001412c6a20082903003700002001413c6a2013290300370000200141c4006a20162802003600002003200241016a2202360280062009417f6a22090d000b20032802fc0521070b200a450d07200341a8086a20034188046a10d60220032d00a80822094106460d0120034194076a41026a20032d00ab083a0000200341c0076a41086a200341bc086a2201290200370300200341c0076a41106a200341c4086a2213290200370300200320032f00a9083b0194072003200341b4086a22162902003703c007200341a8086a41086a2217280200210c20032802ac082108200341a8086a20034188046a10d60220032d00a808220e4106460d02200341dc076a41026a20032d00ab083a0000200341e0076a41086a2001290200370300200341e0076a41106a2013290200370300200320032f00a9083b01dc07200320162902003703e0072017280200211320032802ac082116200341a8086a20034188046a10d60220032d00a80822174106460d03200341fc076a41026a20032d00ab083a000020034188066a41086a200341bc086a220129020037030020034188066a41106a200341c4086a2214290200370300200320032f00a9083b01fc072003200341b4086a221529020037038806200341a8086a41086a2212280200211820032802ac082119200341a8086a20034188046a10d60220032d00a80822114106460d04200341f8056a41026a20032d00ab083a0000200341d0066a41086a2001290200370300200341d0066a41106a2014290200370300200320032f00a9083b01f805200320152902003703d0062012280200211420032802ac082115200341a8086a20034188046a10d60220032d00a80822124106470d05024020114101470d002014450d00201510350b024020174101470d002018450d00201910350b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d07200741c8006c0d060c070b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b20032802fc052201450d06200141c8006c0d050c060b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d05200741c8006c0d040c050b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d04200741c8006c0d030c040b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d03200741c8006c0d020c030b024020174101470d002018450d00201910350b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d02200741c8006c0d010c020b200341b2066a20032d00ab083a000020034198076a41086a200341bc086a290200370300200341a8076a200341c4086a290200370300200320032f00a9083b01b0062003200341b4086a29020037039807200341a8086a41086a280200211a20032802ac08211b200341003a00a8080240024020032802940222012001410047221c490d00200341a8086a200328029002221d201c109d081a20032001201c6b221e360294022003201d201c6a221f360290020240024020010d00410021010c010b20032d00a808222041014b0d0141002101024020200e020100010b200341003a00a808201e201e4100472201490d01200341a8086a201f2001109d081a2003201e20016b221d360294022003201f20016a22213602900202400240201e450d0020032d00a808211c0c010b4100211c200341003a00a8080b200341003a00a808201d201d4100472201490d01200341a8086a20212001109d081a2003201d20016b2222360294022003202120016a22213602900202400240201d450d0020032d00a808211d0c010b4100211d200341003a00a8080b200341003a00a808202220224100472201490d01200341a8086a20212001109d081a2003202220016b2223360294022003202120016a222436029002024002402022450d0020032d00a80821210c010b41002121200341003a00a8080b200341003a00a808202320234100472201490d01200341a8086a20242001109d081a2003202320016b2225360294022003202420016a222436029002024002402023450d0020032d00a80821220c010b41002122200341003a00a8080b200341003a00a808202520254100472201490d01200341a8086a20242001109d081a2003202520016b2226360294022003202420016a222436029002024002402025450d0020032d00a80821230c010b41002123200341003a00a8080b200341003a00a808202620264100472201490d01200341a8086a20242001109d081a2003202620016b2225360294022003202420016a222736029002024002402026450d0020032d00a80821240c010b41002124200341003a00a8080b200341003a00a808202520254100472201490d01200341a8086a20272001109d081a2003202520016b2226360294022003202720016a222736029002024002402025450d0020032d00a80821250c010b41002125200341003a00a8080b200341003a00a808202620264100472201490d01200341a8086a20272001109d081a2003202620016b2228360294022003202720016a222736029002024002402026450d0020032d00a80821260c010b41002126200341003a00a8080b200341003a00a808202820284100472201490d01200341a8086a20272001109d081a2003202820016b2229360294022003202720016a222a36029002024002402028450d0020032d00a80821270c010b41002127200341003a00a8080b200341003a00a808202920294100472201490d01200341a8086a202a2001109d081a2003202920016b222b360294022003202a20016a222a36029002024002402029450d0020032d00a80821280c010b41002128200341003a00a8080b200341003a00a808202b202b4100472201490d01200341a8086a202a2001109d081a2003202b20016b222c360294022003202a20016a222a3602900202400240202b450d0020032d00a80821290c010b41002129200341003a00a8080b200341003a00a808202c202c4100472201490d01200341a8086a202a2001109d081a2003202c20016b222b360294022003202a20016a222d3602900202400240202c450d0020032d00a808212a0c010b4100212a200341003a00a8080b200341003a00a808202b202b4100472201490d01200341a8086a202d2001109d081a2003202b20016b222c360294022003202d20016a222d3602900202400240202b450d0020032d00a808212b0c010b4100212b200341003a00a8080b200341003a00a808202c202c4100472201490d01200341a8086a202d2001109d081a2003202c20016b222e360294022003202d20016a222d3602900202400240202c450d0020032d00a808212c0c010b4100212c200341003a00a8080b200341003a00a808202e202e4100472201490d01200341a8086a202d2001109d081a2003202e20016b222f360294022003202d20016a22303602900202400240202e450d0020032d00a808212d0c010b4100212d200341003a00a8080b200341003a00a808202f202f4100472201490d01200341a8086a20302001109d081a2003202f20016b2231360294022003203020016a22303602900202400240202f450d0020032d00a808212e0c010b4100212e200341003a00a8080b200341003a00a808203120314100472201490d01200341a8086a20302001109d081a2003203120016b2232360294022003203020016a223036029002024002402031450d0020032d00a808212f0c010b4100212f200341003a00a8080b200341003a00a808203220324100472201490d01200341a8086a20302001109d081a2003203220016b2231360294022003203020016a221e36029002024002402032450d0020032d00a80821300c010b41002130200341003a00a8080b200341003a00a808203120314100472201490d01200341a8086a201e2001109d081a2003203120016b2232360294022003201e20016a221e36029002024002402031450d0020032d00a80821310c010b41002131200341003a00a8080b200341003a00a808203220324100472201490d01200341a8086a201e2001109d081a2003203220016b360294022003201e20016a36029002024002402032450d0020032d00a80821320c010b41002132200341003a00a8080b410121010b200341a8086a20034188046a10d60220032d00a808221e4106460d01200341f8066a41026a223320032d00ab083a000020034180086a41086a2234200341bc086a29020037030020034180086a41106a2235200341c4086a290200370300200320032f00a9083b01f8062003200341b4086a29020037038008200341a8086a41086a2236280200211f20032802ac082120200341a8086a20034188046a10d60220032d00a8084106470d040240201e4101470d00201f450d00202010350b024020124101470d00201a450d00201b10350b024020114101470d002014450d00201510350b024020174101470d002018450d00201910350b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d03200741c8006c0d020c030b024020124101470d00201a450d00201b10350b024020114101470d002014450d00201510350b024020174101470d002018450d00201910350b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d02200741c8006c0d010c020b024020124101470d00201a450d00201b10350b024020114101470d002014450d00201510350b024020174101470d002018450d00201910350b0240200e4101470d002013450d00201610350b024020094101470d00200c450d00200810350b02402002450d00200a200241c8006c6a2102200a21010340024020012d00004101470d00200141086a280200450d00200141046a28020010350b0240200141246a2d00004101470d002001412c6a280200450d00200141286a28020010350b200141c8006a22012002470d000b0b2007450d01200741c8006c450d010b200a10350b200d42ffffff3f83500d0220061035410221010c030b20034190046a41206a2237200341a8086a41206a223828020036020020034190046a41186a2239200341a8086a41186a223a29030037030020034190046a41106a223b200341a8086a41106a223c29030037030020034190046a41086a223d2036290300370300200341f2056a41026a223e20034194076a41026a223f2d00003a0000200341d8056a41086a2240200341c0076a41086a2241290300370300200341d8056a41106a2242200341c0076a41106a2243290300370300200320032903a80837039004200320032f0194073b01f205200320032903c0073703d805200341d4056a41026a2244200341dc076a41026a22452d00003a0000200320032f01dc073b01d405200341b8056a41106a2246200341e0076a41106a2247290300370300200341b8056a41086a2248200341e0076a41086a2249290300370300200320032903e0073703b805200341b4056a41026a224a200341fc076a41026a224b2d00003a0000200320032f01fc073b01b40520034198056a41106a224c20034188066a41106a224d29030037030020034198056a41086a224e20034188066a41086a224f29030037030020032003290388063703980520034194056a41026a2250200341f8056a41026a22512d00003a0000200320032f01f8053b019405200341f8046a41106a2252200341d0066a41106a2253290300370300200341f8046a41086a2254200341d0066a41086a2255290300370300200320032903d0063703f804200341f4046a41026a2256200341b0066a41026a22572d00003a0000200320032f01b0063b01f404200341d8046a41106a225820034198076a41106a2259290300370300200341d8046a41086a225a20034198076a41086a225b29030037030020032003290398073703d804200341d4046a41026a225c20332d00003a0000200320032f01f8063b01d404200341b8046a41106a225d2035290300370300200341b8046a41086a225e203429030037030020032003290380083703b8042003418c046a41026a225f200341f5056a41026a2d00003a0000200320032f00f5053b018c042033203e2d00003a0000200320032f01f2053b01f8062035204229030037030020342040290300370300200320032903d80537038008205720442d00003a0000200320032f01d4053b01b00620592046290300370300205b2048290300370300200320032903b805370398072051204a2d00003a0000200320032f01b4053b01f8052053204c2903003703002055204e29030037030020032003290398053703d006204b20502d00003a0000200320032f0194053b01fc07204d2052290300370300204f2054290300370300200320032903f80437038806204520562d00003a0000200320032f01f4043b01dc07204720582903003703002049205a290300370300200320032903d8043703e007203f205c2d00003a0000200320032f01d4043b0194072043205d2903003703002041205e290300370300200320032903b8043703c00720382037280200360200203a2039290300370300203c203b2903003703002036203d29030037030020032003290390043703a808200341cc066a41026a205f2d00003a0000200320032f018c043b01cc060c020b1045000b410221010b20034184046a41026a200341f8066a41026a2d00003a0000200341e8036a41086a20034180086a41086a290300370300200341e8036a41106a223320034180086a41106a290300370300200341e4036a41026a200341b0066a41026a2d00003a0000200341c8036a41086a20034198076a41086a290300370300200341c8036a41106a223420034198076a41106a290300370300200320032f01f8063b01840420032003290380083703e803200320032f01b0063b01e40320032003290398073703c803200341c4036a41026a200341f8056a41026a2d00003a0000200341a8036a41086a200341d0066a41086a290300370300200341a8036a41106a2235200341d0066a41106a290300370300200341a4036a41026a200341fc076a41026a2d00003a000020034188036a41086a20034188066a41086a29030037030020034188036a41106a223620034188066a41106a290300370300200320032f01f8053b01c403200320032903d0063703a803200320032f01fc073b01a40320032003290388063703880320034184036a41026a200341dc076a41026a2d00003a0000200341e8026a41106a2237200341e0076a41106a290300370300200341e8026a41086a200341e0076a41086a290300370300200341e4026a41026a20034194076a41026a2d00003a0000200341c8026a41106a2238200341c0076a41106a290300370300200341c8026a41086a200341c0076a41086a290300370300200320032f01dc073b018403200320032903e0073703e802200320032f0194073b01e402200320032903c0073703c802200341a0026a41206a2239200341a8086a41206a280200360200200341a0026a41186a223a200341a8086a41186a290300370300200341a0026a41106a223b200341a8086a41106a290300370300200341a0026a41086a200341a8086a41086a290300370300200320032903a8083703a0022003419c026a41026a200341cc066a41026a2d00003a0000200320032f01cc063b019c020240024020014102470d00200341003602880820034201370380082003410936029c072003200341106a36029807200320034180086a3602d006200341bc086a4101360200200342013702ac08200341c888c2003602a808200320034198076a3602b808200341d0066a41e88ac500200341a8086a10431a200335028808422086200335028008841006200328028408450d0120032802800810350c010b2003418c026a41026a223c20034184046a41026a2d00003a0000200341f0016a41086a223d200341e8036a41086a290300370300200341f0016a41106a223e2033290300370300200341ec016a41026a2233200341e4036a41026a2d00003a0000200341d0016a41086a223f200341c8036a41086a290300370300200341d0016a41106a22402034290300370300200320032f0184043b018c02200320032903e8033703f001200320032f01e4033b01ec01200320032903c8033703d001200341cc016a41026a2234200341c4036a41026a2d00003a0000200341b0016a41086a2241200341a8036a41086a290300370300200341b0016a41106a22422035290300370300200341ac016a41026a2235200341a4036a41026a2d00003a000020034190016a41086a224320034188036a41086a29030037030020034190016a41106a22442036290300370300200320032f01c4033b01cc01200320032903a8033703b001200320032f01a4033b01ac012003200329038803370390012003418c016a41026a223620034184036a41026a2d00003a0000200341f0006a41106a22452037290300370300200341f0006a41086a2237200341e8026a41086a290300370300200341ec006a41026a2246200341e4026a41026a2d00003a0000200341d0006a41106a22472038290300370300200341d0006a41086a2238200341c8026a41086a290300370300200320032f0184033b018c01200320032903e802370370200320032f01e4023b016c200320032903c802370350200341286a41206a22482039280200360200200341286a41186a2239203a290300370300200341286a41106a223a203b290300370300200341286a41086a223b200341a0026a41086a290300370300200320032903a002370328200341a8086a41026a22492003419c026a41026a2d00003a0000200320032f019c023b01a8082000200f37030820002010370300200020093a002820002002360224200020073602202000200a36021c2000200d370214200020063602102000200c3602302000200836022c200020032f018c023b00292000412b6a203c2d00003a0000200020032903f0013702342000413c6a203d290300370200200041c4006a203e2903003702002000200e3a004c200041cf006a20332d00003a0000200020032f01ec013b004d2000201336025420002016360250200041e8006a2040290300370200200041e0006a203f290300370200200020032903d001370258200020173a0070200041f3006a20342d00003a0000200020032f01cc013b007120002018360278200020193602742000418c016a204229030037020020004184016a2041290300370200200020032903b00137027c200020113a00940120004197016a20352d00003a0000200020032f01ac013b0095012000201436029c012000201536029801200041b0016a2044290300370200200041a8016a204329030037020020002003290390013702a001200020123a00b801200041bb016a20362d00003a0000200020032f018c013b00b9012000201a3602c0012000201b3602bc01200041d4016a2045290300370200200041cc016a2037290300370200200020032903703702c4012000201e3a00dc01200041df016a20462d00003a0000200020032f016c3b00dd012000201f3602e401200020203602e001200041f8016a2047290300370200200041f0016a2038290300370200200020032903503702e801200041a0026a204828020036020020004198026a203929030037020020004190026a203a29030037020020004188026a203b2903003702002000200329032837028002200041b8026a20323a0000200041b7026a20313a0000200041b6026a20303a0000200041b5026a202f3a0000200041b4026a202e3a0000200041b3026a202d3a0000200041b2026a202c3a0000200041b1026a202b3a0000200041b0026a202a3a0000200041af026a20293a0000200041ae026a20283a0000200041ad026a20273a0000200041ac026a20263a0000200041ab026a20253a0000200041aa026a20243a0000200041a9026a20233a0000200041a8026a20223a0000200041a7026a20213a0000200041a6026a201d3a00002000201c3a00a502200041bb026a20492d00003a0000200041b9026a20032f01a8083b00000b200020013a00a4022005450d00200410350b200341d0086a24000bd90401057f230041106b22022400200241003a000502400240024002400240024020012802002203280204220420044100472205490d00200241056a200328020022062005109d081a2003200420056b3602042003200620056a360200024020040d00410021040c050b024020022d0005220441037122034103460d000240024020030e03070001070b200241003b0106200220043a00064101210420012802002201280204220320034100472205490d04200241066a410172200128020022042005109d0821062001200320056b3602042001200420056a360200024020030d00200620056a22044100200241066a20046b41026a109f081a0b20022f0106220441ff014d0d0220044102762103410021040c070b20024100360208200220043a0008200241086a4101722001280200220428020020042802042205410320054103491b2203109d082106200428020422012003490d042004200120036b3602042004200428020020036a3602000240200541024b0d00200620036a22044100200241086a20046b41046a109f081a0b2002280208220341808004492104200341027621030c060b200441034d0d010b410121040c040b2002410036020c2002410c6a20012802002204280200220120042802042203410420034104491b2205109d081a2004200320056b3602042004200120056a3602000240200341034b0d002002410c6a20056a4100410420056b109f081a0b200228020c22034180808080044921040c030b0c020b2003200141a4f0cb001059000b20044102762103410021040b2000200336020420002004360200200241106a24000b8913010b7f23004180016b22022400200241003a004002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802002203280204220420044100472205490d00200241c0006a200328020022062005109d081a2003200420056b3602042003200620056a360200024020040d00410021062002410d6a2107200241106a2108200241246a21090c140b2002410d6a2107200241106a2108200241246a210920022d0040220a41254b0d0141002106200a0e261301010101010101010101010101010101010101010101010101010101010101010102030405130b200041063a00000c130b0240200a417f6a220441ff01714121490d00200041063a00000c130b024020040d00410121034100210441002105410121060c120b0240200410392203450d002003200128020022012802002001280204220a2004200a2004491b2205109d08210b200128020422062005490d052001200620056b3602042001200128020020056a360200410121060240200a20044f0d00200b20056a22014100200b20046a20016b109f081a0b200421050c120b1045000b200241003a00784100210a02400340200241003a004020012802002203280204220420044100472205490d01200a41016a2106200241c0006a2003280200220b2005109d081a2003200420056b3602042003200b20056a360200024002402004450d0020022d004021040c010b41002104200241003a00400b200241d8006a200a6a20043a0000200220063a00782006210a20064120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c100b41012101200a41ff01710d040c0e0b200241003a00784100210a02400340200241003a004020012802002203280204220420044100472205490d01200a41016a2106200241c0006a2003280200220b2005109d081a2003200420056b3602042003200b20056a360200024002402004450d0020022d004021040c010b41002104200241003a00400b200241d8006a200a6a20043a0000200220063a00782006210a20064120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c0d0b41012101200a41ff01710d040c0b0b200241003a00784100210a02400340200241003a004020012802002203280204220420044100472205490d01200a41016a2106200241c0006a2003280200220b2005109d081a2003200420056b3602042003200b20056a360200024002402004450d0020022d004021040c010b41002104200241003a00400b200241d8006a200a6a20043a0000200220063a00782006210a20064120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c0a0b41012101200a41ff01710d040c080b200241003a00784100210a02400340200241003a004020012802002203280204220420044100472205490d01200a41016a2106200241c0006a2003280200220b2005109d081a2003200420056b3602042003200b20056a360200024002402004450d0020022d004021040c010b41002104200241003a00400b200241d8006a200a6a20043a0000200220063a00782006210a20064120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632104200228005f2105200228005b21030c070b41012101200a41ff01710d040c050b2005200641a4f0cb001059000b200241003a00780c090b200241003a00780c060b200241003a00780c030b200241003a00780b0b2002413c6a41026a2206200241d4006a41026a2d00003a0000200241286a41086a220a200241c0006a41086a290300370300200241286a41106a220b200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20062d00003a0000200241106a41086a200a290300370300200241106a41106a200b2d00003a0000200220022f013c3b012420022002290328370310410521060c070b200041063a00000c070b0b2002413c6a41026a2206200241d4006a41026a2d00003a0000200241286a41086a220a200241c0006a41086a290300370300200241286a41106a220b200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20062d00003a0000200241106a41086a200a290300370300200241106a41106a200b2d00003a0000200220022f013c3b012420022002290328370310410421060c050b200041063a00000c050b0b2002413c6a41026a2206200241d4006a41026a2d00003a0000200241286a41086a220a200241c0006a41086a290300370300200241286a41106a220b200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20062d00003a0000200241106a41086a200a290300370300200241106a41106a200b2d00003a0000200220022f013c3b012420022002290328370310410321060c030b200041063a00000c030b0b410221062002413c6a41026a220a200241d4006a41026a2d00003a0000200241286a41086a220b200241c0006a41086a290300370300200241286a41106a220c200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a200a2d00003a0000200241106a41086a200b290300370300200241106a41106a200c2d00003a0000200220022f013c3b0124200220022903283703100c010b200041063a00000c010b200020063a0000200020092f00003b00012000410c6a2004360000200041086a2005360000200041046a2003360000200041106a2008290000370000200041216a20072f00003b0000200041036a200941026a2d00003a0000200041186a200841086a290000370000200041206a200841106a2d00003a0000200041236a200741026a2d00003a00000b20024180016a24000bb10201017f230041a0016b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822010d00200041003602400c010b200328020c21022003200341106a28020036027c20032001360278200341186a200341f8006a10c7020240024020032802580d002003410036028801200342013703800120034109360294012003200336029001200320034180016a36029c012003412c6a41013602002003420137021c200341c888c200360218200320034190016a3602282003419c016a41e88ac500200341186a10431a2003350288014220862003350280018410060240200328028401450d0020032802800110350b200041003602400c010b2000200341186a41e000109d081a0b2002450d00200110350b200341a0016a24000b8b06010d7f23004190016b220224002002412036021420022001360210200241186a2001ad4280808080800484100510c2010240024002400240200228021822030d00200041003602000c010b200228021c21042002200241206a28020036022c20022003360228200241086a200241286a10c4010240024020022802080d00200228020c2205200228022c22064105762201200120054b1b22014105742207417f4c0d030240024020010d00410121080c010b200710332208450d050b41002109200241003602402002200136023c20022008360238024002402005450d004100210a03402006210b41002101200241003a008801200a41016a210a0340200b2001460d03200241e8006a20016a200228022822072d00003a00002002200741016a3602282002200141016a22073a0088012007210120074120470d000b200241c8006a41186a220c200241e8006a41186a290300370300200241c8006a41106a220d200241e8006a41106a290300370300200241c8006a41086a220e200241e8006a41086a2903003703002002200229036837034802402009200228023c470d00200241386a20094101108a0120022802382108200228024021090b200b20076b2106200820094105746a22012002290348370000200141186a200c290300370000200141106a200d290300370000200141086a200e2903003700002002200941016a2209360240200a2005470d000b2002200b20076b36022c0b2008450d012000200229023c370204200020083602000c020b2002410036022c0240200141ff0171450d00200241003a0088010b200228023c41ffffff3f71450d00200810350b20024100360250200242013703482002410936023c2002200241106a3602382002200241c8006a360234200241fc006a41013602002002420137026c200241c888c2003602682002200241386a360278200241346a41e88ac500200241e8006a10431a200235025042208620023502488410060240200228024c450d00200228024810350b200041003602000b2004450d00200310350b20024190016a24000f0b1044000b1045000bb80c07057f017e067f017e037f027e017f23004190016b220324002003200236021420032001360210200341186a2002ad4220862001ad84100510c20102400240200328021822040d00200041023a00000c010b200328021c21052003200341206a280200220236023c20032004360238024002402002450d0020042d0000210120032002417f6a36023c2003200441016a360238200141014b0d00024002400240024002400240024020010e020001000b200341086a200341386a10c40120032802080d06200328023c2206200328020c2201490d062001417f4c0d030240024020010d0041002102410121070c010b200110392207450d052007200328023822022001109d081a2003200620016b220636023c2003200220016a360238200121020b2007450d062001ad4220862002ad842208a7210902400240024002400240024020064104490d002008422088a7210a2003280238220b280000210c20032006417c6a220d36023c2003200b41046a36023841002101200341003a008801417b210202400340200d2001460d01200341e8006a20016a200b20016a220e41046a2d00003a00002003200620026a36023c2003200e41056a3602382003200141016a220e3a0088012002417f6a2102200e2101200e4120470d000b2003200328006b3600432003200328026836024020032003280240360250200320032800433600532006200e6b2201417c6a4110490d06200341f7006a2900002108200329006f210f200328007f2102200328008301210d20032d00870121102003200b200e6a221141146a221236023820032001416c6a220b36023c200b4104490d042011410c6a2900002113201141046a29000021142012280000210b2003200141686a36023c2003201141186a2212360238200641686a200e460d0520122d000021122003200141676a221536023c2003201141196a360238201241014b0d054100210e20120e020302030b0240200141ff0171450d00200341003a0088010b2009450d0c0c0b0b2009450d0b200710350c0b0b20154104490d02201141196a28000021062003200141636a36023c20032011411d6a3602384101210e0b2003200328005336006320032003280250360260200320032802603602282003200328006336002b200320032800593602302003200341dc006a280000360033410021010c040b2009450d08200710350c080b2009450d07200710350c070b20090d050c060b41002101200341003a0088012002417f6a21062002417e6a2102034020062001460d02200341e8006a20016a200420016a220e41016a2d00003a00002003200e41026a3602382003200141016a220e3a0088012003200236023c2002417f6a2102200e2101200e4120470d000b2003200328006b3600432003200328026836024020032003280043360053200320032802403602502003200328025036026020032003280053360063200341f7006a2900002113200329006f2114200328007f2107200328008301210920032d008701210a20032003280063360033200320032802603602302003200341dc006a28000036002b20032003280059360228410121010b2003200328003336006b20032003280230360268200320032802283602402003200328002b360043200041106a2013370000200041086a2014370000200041046a200328006b36000020002003280268360001200041306a20063600002000412c6a200e360000200041286a200b360000200041246a200c360000200041206a200a3600002000411c6a2009360000200041186a2007360000200041c3006a20083700002000413b6a200f370000200041d3006a20103a0000200041cf006a200d360000200041cb006a2002360000200041346a2003280240360000200041376a20032800433600000c050b200141ff0171450d03200341003a0088010c030b1044000b1045000b200710350b2003410036024820034201370340200341093602542003200341106a3602502003200341c0006a360260200341fc006a41013602002003420137026c200341c888c2003602682003200341d0006a360278200341e0006a41e88ac500200341e8006a10431a2003350248422086200335024084100602402003280244450d00200328024010350b410221010b200020013a00002005450d00200410350b20034190016a24000bf30201047f230041d0016b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822010d00200041023a0088010c010b200228020c21032002200241106a2802003602ac01200220013602a801200241186a200241a8016a10db020240024020022d00a00122044102470d00200241003602b801200242013703b001200241093602c401200220023602c0012002200241b0016a3602cc012002412c6a41013602002002420137021c200241c888c2003602182002200241c0016a360228200241cc016a41e88ac500200241186a10431a20023502b80142208620023502b00184100620022802b401450d0120022802b00110350c010b2000200241186a418801109d0821052002200241186a418c016a2800003600b301200220022800a1013602b0012005418c016a20022800b301360000200520022802b001360089010b200020043a0088012003450d00200110350b200241d0016a24000bfe0703057f0e7e067f230041106b21020240200128020422034104490d0020012802002204280000210520012003417c6a22063602042001200441046a36020020064108490d00200429000421072001200341746a220636020420012004410c6a36020020064108490d00200429000c210820012003416c6a22063602042001200441146a36020020064108490d00200429001421092001200341646a220636020420012004411c6a36020020064108490d00200429001c210a20012003415c6a22063602042001200441246a36020020064108490d002004290024210b2001200341546a220636020420012004412c6a36020020064108490d00200429002c210c20012003414c6a22063602042001200441346a36020020064108490d002004290034210d2001200341446a220636020420012004413c6a36020020064108490d00200429003c210e2001200341bc7f6a22063602042001200441c4006a36020020064108490d002004290044210f2001200341b47f6a22063602042001200441cc006a36020020064108490d00200429004c21102001200341ac7f6a22063602042001200441d4006a36020020064108490d00200429005421112001200341a47f6a22063602042001200441dc006a36020020064108490d00200429005c211220012003419c7f6a22063602042001200441e4006a36020020064108490d00200429006421132001200341947f6a22063602042001200441ec006a36020020064108490d00200429006c211420012003418c7f6a22063602042001200441f4006a36020020064104490d00200428007421152001200341887f6a22063602042001200441f8006a36020020064104490d00200428007821162001200341847f6a22063602042001200441fc006a36020020064104490d00200428007c21172001200341807f6a2206360204200120044180016a36020020064104490d0020042800800121182001200341fc7e6a2206360204200120044184016a22043602002006450d0020042d000021062001200341fb7e6a22193602042001200441016a360200200641014b0d004100211a0240024020060e020100010b4101211a0b20194104490d00200428000121062001200341f77e6a3602042001200441056a3602002000201a3a008801200020063602840120002018360280012000201736027c20002016360278200020153602742000200536027020002014370368200020133703602000201237035820002011370350200020103703482000200f3703402000200e3703382000200d3703302000200c3703282000200b3703202000200a3703182000200937031020002008370308200020073703002000418c016a2002410c6a28000036000020002002280009360089010f0b200041023a0088010b8b0a040a7f017e037f037e23004180026b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c2010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c4010240024020022802000d0020022802042205200228022422064106762201200120054b1b22014106742207417f4c0d030240024020010d00410821080c010b200710332208450d050b41002109200241003602302002200136022c200220083602280240024002402005450d004100210a03400240024002402006450d0020022002280220220b41016a3602202006417f6a2107200b2d0000220141014b0d054200210c20010e020201020b200241003602240c050b41002101200241003a00f8012006417f6a210d024002400240024002400340200d2001460d01200241d8016a20016a200b20016a220741016a2d00003a00002002200741026a3602202002200141016a22073a00f8012007210120074120470d000b200241b8016a41186a220d200241d8016a41186a290300370300200241b8016a41106a220e200241d8016a41106a290300370300200241b8016a41086a220f200241d8016a41086a290300370300200220022903d8013703b8012007417f7320066a4110490d022002200b20076a220141116a220b360220200620076b2207416f6a41074b0d012007416f6a21010c030b0240200141ff0171450d00200241003a00f8010b410021010c020b200141096a2900002110200141016a29000021112002200141196a360220200b2900002212428002540d02200741676a21010c010b2007417f7320066a21010b200241f8006a41086a20024198016a41086a290300370300200241f8006a41106a20024198016a41106a2903003703002002200229039801370378200220013602240c050b200741676a2107200241f8006a41086a200f290300220c370300200241d8006a41186a200d290300370300200241d8006a41106a200e290300370300200241d8006a41086a200c370300200220022903b801220c3703782002200c3703584201210c0b200a41016a210a200241386a41186a220b200241d8006a41186a290300370300200241386a41106a220d200241d8006a41106a290300370300200241386a41086a2206200241d8006a41086a2903003703002002200229035837033802402009200228022c470d00200241286a200910940120022802282108200228023021090b200820094106746a220120113703082001200c370300200141106a2010370300200141186a2012370300200141206a2002290338370300200141286a2006290300370300200141306a200d290300370300200141386a200b2903003703002002200941016a220936023020072106200a2005470d000b200220073602240b2008450d022000200229022c370204200020083602000c030b200220073602240b200228022c41ffffff1f71450d00200810350b200241003602c001200242013703b8012002410936029c012002200241086a360298012002200241b8016a360278200241ec016a4101360200200242013702dc01200241c888c2003602d801200220024198016a3602e801200241f8006a41e88ac500200241d8016a10431a20023502c00142208620023502b801841006024020022802bc01450d0020022802b80110350b200041003602000b2004450d00200310350b20024180026a24000f0b1044000b1045000b980704057f017e087f037e230041a0016b220224002002412036020c20022001360208200241106a2001ad4280808080800484100510c2010240024002400240200228021022030d00200041003602000c010b200228021421042002200241186a280200360224200220033602202002200241206a10c4010240024020022802000d00200228020422052002280224220641286e2201200120054b1bad42287e2207422088a70d032007a72201417f4c0d030240024020010d00410821080c010b200110332208450d050b4100210920024100360230200220083602282002200141286e36022c02400240024002402005450d004100210a034041002101200241003a009801200a41016a210a034020062001460d03200241f8006a20016a2002280220220b2d00003a00002002200b41016a3602202002200141016a220c3a009801200c2101200c4120470d000b200241d8006a41186a2201200241f8006a41186a290300370300200241d8006a41106a220d200241f8006a41106a290300370300200241d8006a41086a220e200241f8006a41086a290300370300200220022903783703582006200c6b220c4108490d03200241386a41086a220f200e290300370300200241386a41106a220e200d290300370300200241386a41186a220d2001290300370300200220022903583703382002200b41096a360220200b290001210702402009200228022c470d00200241286a20094101108f0120022802282108200228023021090b200c41786a21062008200941286c6a22012002290338370300200f2903002110200e2903002111200d290300211220012007370320200141186a2012370300200141106a2011370300200141086a20103703002002200941016a2209360230200a2005470d000b2002200c41786a3602240b2008450d032000200229022c370204200020083602000c040b20024100360224200141ff0171450d01200241003a0098010c010b2002200c3602240b200228022c2201450d00200141286c450d00200810350b20024100360260200242013703582002410936023c2002200241086a3602382002200241d8006a3602282002418c016a41013602002002420137027c200241c888c2003602782002200241386a36028801200241286a41e88ac500200241f8006a10431a200235026042208620023502588410060240200228025c450d00200228025810350b200041003602000b2004450d00200310350b200241a0016a24000f0b1044000b1045000bd304010a7f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602080c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d002003200141046a36022020032002417c6a220536022420054104490d00200128000021062003200241786a3602242003200141086a36022020012800042107200341c8006a200341206a10c30120032802482202450d00200341c8006a41086a2802002108200328024c2105200341c8006a200341206a10c3010240024020032802482209450d00200328024c210a2003280224220b41044f0d030240200a41ffffff3f71450d00200910350b200541ffffff3f710d010c020b200541ffffff3f71450d010b200210350b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602080c010b200341d0006a280200210c2000200536020c200020023602082000200736020420002006360200200041206a200328022022022800003602002000411c6a200c360200200041186a200a360200200041146a2009360200200041106a20083602002003200b417c6a3602242003200241046a3602200b2004450d00200110350b200341e0006a24000be70804067f027e077f027e230041e0016b220324002003200236020420032001360200200341086a2002ad4220862001ad84100510c20102400240200328020822040d00200042003703000c010b200341106a2802002105200328020c210641002101200341003a00d801200541706a21070240024002400240034020052001460d01200341b8016a20016a200420016a2d00003a00002003200141016a22023a00d8012007417f6a21072002210120024120470d000b200341d8006a41086a200341b8016a41086a290300370300200341d8006a41106a200341b8016a41106a290300370300200341d8006a41186a200341b8016a41186a290300370300200320032903b801370358200520026b22084110490d02200420026a22052900002109200541086a290000210a41002101200341003a00d801200841706a2108034020082001460d02200341b8016a20016a200520016a41106a2d00003a00002003200141016a22023a00d8012002210120024120470d000b200341f8006a41086a220b200341b8016a41086a2201290300370300200341f8006a41106a220c200341b8016a41106a2208290300370300200341f8006a41186a220d200341b8016a41186a220e290300370300200320032903b801370378200720026b410f4d0d02200341386a41086a2207200341d8006a41086a290300370300200341386a41106a220f200341d8006a41106a290300370300200341386a41186a2210200341d8006a41186a290300370300200341186a41086a2211200b290300370300200341186a41106a220b200c290300370300200341186a41186a220c200d2903003703002003200329035837033820032003290378370318200520026a220241106a2900002112200241186a2900002113200120072903003703002008200f290300370300200e201029030037030020034198016a41086a2202201129030037030020034198016a41106a2207200b29030037030020034198016a41186a2205200c290300370300200320032903383703b8012003200329031837039801200041206a2013370300200041186a2012370300200041106a200a37030020002009370308200041286a20032903b801370300200041306a2001290300370300200041386a2008290300370300200041c0006a200e290300370300200041c8006a200329039801370300200041d0006a2002290300370300200041d8006a2007290300370300200041e0006a2005290300370300420121090c030b200141ff0171450d01200341003a00d8010c010b200141ff0171450d00200341003a00d8010b200341003602a00120034201370398012003410936027c20032003360278200320034198016a360258200341cc016a4101360200200342013702bc01200341c888c2003602b8012003200341f8006a3602c801200341d8006a41e88ac500200341b8016a10431a20033502a0014220862003350298018410060240200328029c01450d0020032802980110350b420021090b200020093703002006450d00200410350b200341e0016a24000ba30303037f017e027f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c2010240024002400240200328021022010d00200041003602000c010b200328021421022003200341186a280200360224200320013602202003200341206a10c40102400240024020032802000d002003280224220420032802042205490d002005417f4c0d040240024020050d0042002106410121070c010b200510392207450d062007200328022022082005109d081a2003200420056b3602242003200820056a3602202005ad21060b20070d010b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602000c010b200020062005ad42208684370204200020073602000b2002450d00200110350b200341e0006a24000f0b1044000b1045000b990204017f017e017f017e230041d0006b220224002002412036020420022001360200200241086a2001ad4280808080800484100510c20102400240200228020822010d00420021030c010b200228020c210402400240200241086a41086a2802004108490d0020012900002105420121030c010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b420021030b2004450d00200110350b2000200537030820002003370300200241d0006a24000bb20403037f027e057f230041e0006b220324002003200236020c20032001360208200341106a2002ad4220862001ad84100510c20102400240200328021022010d00200041003602140c010b200328021421042003200341186a28020022023602242003200136022002400240024020024104490d002003200141046a36022020032002417c6a220536022420054110490d002001280000210520032002416c6a3602242003200141146a3602202001410c6a290000210620012900042107200341c8006a200341206a10c30120032802482202450d00200328024c21082003280224220941024f0d01200841ffffff3f71450d00200210350b20034100360230200342013703282003410936023c2003200341086a3602382003200341286a360244200341dc006a41013602002003420137024c200341c888c2003602482003200341386a360258200341c4006a41e88ac500200341c8006a10431a200335023042208620033502288410060240200328022c450d00200328022810350b200041003602140c010b200341d0006a280200210a200341386a41046a200341286a41046a2f0100220b3b010020032003280128220c36023820032009417e6a36022420032003280220220941026a36022020092f000021092000200637030820002007370300200041206a20093b01002000411c6a200a3602002000200836021820002002360214200020053602102000200c360122200041266a200b3b01000b2004450d00200110350b200341e0006a24000be70203017f017e017f23004190056b22032400200320023602b402200320013602b002200341b8026a2002ad4220862001ad842204100510c2010240024020032802b80222010d00411b21010c010b20032802bc0221052003200341c0026a2802003602fc04200320013602f804200341c8026a200341f8046a10b9020240024020032802c8022202411b470d00200341003602082003420137030020034109360284052003200341b0026a360280052003200336028c05200341dc026a4101360200200342013702cc02200341c888c2003602c802200320034180056a3602d8022003418c056a41e88ac500200341c8026a10431a200335020842208620033502008410062003280204450d01200328020010350c010b2003200341c8026a41047241ac02109d081a0b02402005450d00200110350b411b21012002411b460d0020041007200221010b20002001360200200041046a200341ac02109d081a20034190056a24000b9b0203017f017e017f230041d0006b220224002002200136020420022000360200200241086a2001ad4220862000ad842203100510c20102400240200228020822010d00410321000c010b200228020c210402400240200241106a280200450d0020012d000022004103490d010b20024100360220200242013703182002410936022c200220023602282002200241186a360234200241cc006a41013602002002420137023c200241c888c2003602382002200241286a360248200241346a41e88ac500200241386a10431a200235022042208620023502188410060240200228021c450d00200228021810350b02402004450d00200110350b410321000c010b02402004450d00200110350b200310070b200241d0006a240020000bb10503027f017e047f230041d0006b2202240041a0e4cb00ad4280808080800284100122032900002104200241086a41086a200341086a29000037030020022004370308200310354190eaca00ad4280808080e00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b8e280b037f027e037f047e027f017e027f087e017f027e087f230041f0086b22062400200620043703402006200337033820062001360234200620053a004f024002400240024020012002460d002003200484500d0020012002412010a008450d00200641d0006a2002108e02200641e0006a2006280250220720062802582208108f02200629036021094200210a20064200370360200641a8016a280200210b20062d00ac01210c024002402009420151220d0d00200641b0016a41386a4200370300200641b0016a41306a4200370300200641b0016a41286a4200370300200641d0016a4200370300200641b0016a41186a4200370300200641c0016a4200370300200641b8016a4200370300200642003703b0014200210e4200210f420021100c010b200641e0006a41386a2903002103200641e0006a41306a2903002104200641e0006a41206a290300210e200641e0006a41186a290300210a200641a0016a2903002111200629037021102006290368210f200641d0016a200641e0006a41286a290300370300200641b0016a41286a2004370300200641b0016a41306a2003370300200641c0016a200a3703002006200e3703c801200620113703e8012006200f3703b001200620103703b8010b200641f0036a20062802342212108e0220064180046a20062802f003221320062802f8032201108f022006290380042114420021032006420037038004200641c8046a280200211520062d00cc04211602400240201442015122050d00200641d0046a41306a4200370300200641d0046a41286a4200370300200641d0046a41206a4200370300200641d0046a41186a4200370300200641d0046a41106a4200370300200641d8046a4200370300200642003703d004420021044200211742002118420021190c010b200641b8046a290300211120064180046a41306a290300211a20064180046a41206a290300211820064180046a41186a2903002117200641c0046a290300211920062903900421042006290388042103200641d0046a41206a20064180046a41286a290300370300200641d0046a41286a201a370300200641d0046a41306a2011370300200641d0046a41106a2017370300200620183703e804200620033703d004200620043703d8040b0240024020032006290338221b7d221a2003562004200641386a41086a290300221c7d2003201b54ad7d221120045620112004511b450d00419089c20021054280808080b00221114180800c21010c010b2006201a3703d004200620113703d804024020062903b001221d201b7c221e201d54221f200641b0016a41086a2903002220201c7c201fad7c221d202054201d2020511b450d0041a7d6ca0021054280808080800121114180800821010c010b2006201e3703b001200641c8016a29030021202006201d3703b8010240427f201e20062903c0017c22212021201e54221f201d20207c201fad7c2220201d542020201d511b221f1b428080e983b1de16544100427f2020201f1b501b450d0041fe88c20021054280808080a00221114180801021010c010b0240201b201c84500d0020064188056a2006280234108e02200641c0076a2006280288052222200628029005108f02200641f0076a290300420020062903c007420151221f1b211b200641e8076a2903004200201f1b211d0240200628028c05450d00202210350b201d201a56201b201156201b2011511b450d004180800421014280808080d002211141a389c20021050c010b0240024020062d004f4101460d00201a428080e983b1de165441002011501b0d010c040b20064188056a2006280234108e02200641c0076a200628028805221f200628029005108f0220062d008c08212220062903c007211b0240200628028c05450d00201f10350b201a42ffffe883b1de165620114200522011501b0d03201b4201520d03202241ff0171450d030b41f588c20021054280808080900121114180801421010b20014180801c7141830c7221152005ad220342088842ff018321042011200384428080fcffff0383211b4101211f0c020b200041043a00000c020b20064188056a41186a200641d0046a41186a290300221b37030020064188056a41206a2222200641d0046a41206a29030037030020064188056a41286a2223200641d0046a41286a29030037030020064188056a41306a2224200641d0046a41306a290300370300200620062903e004221d370398052006201a370388052006201137039005427f200320177c221c201c200354221f200420187c201fad7c220320045420032004511b221f1b427f2003201f1b8450212502400240427f201a201d7c22032003201a54221f2011201b7c201fad7c220320115420032011511b221f1b2204428080e983b1de16544100427f2003201f1b2203501b0d0020064198056a29030021042024290300211d2023290300211c20222903002117200629039005211820062903880521204201211b20062903a005211e0c010b02400240200420038450450d004200211b0c010b4200211b200641c0076a41186a22264200370300200641c0076a41106a22234200370300200641c0076a41086a22224200370300200642003703c00741b6fdc600ad4280808080800184221d10012224290000211c200641e0086a41086a221f202441086a2900003703002006201c3703e008202410352022201f290300370300200620062903e0083703c00741e489c200ad4280808080d00184221c100122242900002117201f202441086a290000370300200620173703e00820241035202320062903e0082217370300200641c0086a41086a22272022290300370300200641c0086a41106a22282017370300200641c0086a41186a2229201f290300370300200620062903c0073703c008200641186a200641c0086a412010d701200641186a41106a29030021172006290320211820062802182124202642003703002023420037030020224200370300200642003703c007201d10012226290000211d201f202641086a2900003703002006201d3703e008202610352022201f290300370300200620062903e0083703c007201c10012226290000211d201f202641086a2900003703002006201d3703e00820261035202320062903e008221d370300202720222903003703002028201d3703002029201f290300370300200620062903c0073703c008200642002017420020241b221d20037d2018420020241b221c200454ad7d2217201c20047d2218201c562017201d562017201d511b221f1b3703c807200642002018201f1b3703c007200641c0086aad4280808080800484200641c0076aad42808080808002841002200641f8076a2003370300200641f0076a2004370300202241013a0000200641c9076a2012290000370000200641d1076a201241086a290000370000200641d9076a201241106a290000370000200641e1076a201241186a290000370000200641033a00c00741b0b4cc004100200641c0076a10d4010b0b2025ad2103200641a8046a2017370300200641b0046a201c37030020064190046a2018370300200641b8046a201d37030020064198046a20043703002006201e3703a004200620193703c0042006202037038804420121044100211f200620164100201442015122221b3a00cc0420062015410020221b3602c8042006201b4201512215ad37038004024020150d002001ad4220862013ad841007420021044200211b0c010b200620013602c407200620133602c00720064188046a200641c0076a10e7024200211b0b024020062802f403450d00201310350b200641b0016a41106a210102400240201f0d00024002400240200541ff017122050d0020044200510d0041032115200641c0066a21050c010b2005450d0120044200520d0141042115200641c0056a21050b200541086a20153a0000200541003a0000200541096a2012290000370000200541116a201241086a290000370000200541196a201241106a290000370000200541216a201241186a29000037000041b0b4cc004100200510d4010b410421154100210520034201520d01200641f8076a2011370300200641f0076a201a37030041002105200641c0076a41086a41003a0000200641c9076a2012290000370000200641d1076a201241086a290000370000200641d9076a201241106a290000370000200641e1076a201241186a290000370000200641033a00c00741b0b4cc004100200641c0076a10d4010c010b20044208862005ad42ff018384201b842103201541807e7121050b200641c0056a41086a2212200141086a290300370300200641c0056a41106a221f200141106a290300370300200641c0056a41186a2213200141186a290300370300200641c0056a41206a2216200141206a290300370300200620012903003703c005200641b0016a41086a290300210420062903b001211102400240201541ff017122014104460d0020034280807c83211a200342088842ff01832110200520017221012003a7210d410121050c010b20062903e801211a200641c0066a41186a2012290300221b370300200641c0066a41206a201f290300370300200641e8066a22052013290300370300200641f0066a22152016290300370300200620062903c00522143703d006200620113703c006200620043703c806427f200f200a7c22032003200f5422012010200e7c2001ad7c220320105420032010511b22011b427f200320011b8450211202400240427f201120147c2203200320115422012004201b7c2001ad7c220320045420032004511b22011b2210428080e983b1de16544100427f200320011b2203501b0d00200641d0066a29030021102015290300211b2005290300210a200641e0066a290300210f20062903c806211420062903c006210e4201211d20062903d806211c0c010b02400240201020038450450d004200211d0c010b4200211d200641c0076a41186a22134200370300200641c0076a41106a22154200370300200641c0076a41086a22054200370300200642003703c00741b6fdc600ad4280808080800184221b1001221f290000210a200641e0086a41086a2201201f41086a2900003703002006200a3703e008201f103520052001290300370300200620062903e0083703c00741e489c200ad4280808080d00184220a1001221f290000210f2001201f41086a2900003703002006200f3703e008201f1035201520062903e008220f370300200641c0086a41086a22162005290300370300200641c0086a41106a2222200f370300200641c0086a41186a22252001290300370300200620062903c0073703c0082006200641c0086a412010d701200641106a290300210f200629030821142006280200211f201342003703002015420037030020054200370300200642003703c007201b10012213290000211b2001201341086a2900003703002006201b3703e0082013103520052001290300370300200620062903e0083703c007200a10012213290000211b2001201341086a2900003703002006201b3703e00820131035201520062903e008221b370300201620052903003703002022201b37030020252001290300370300200620062903c0073703c00820064200200f4200201f1b221b20037d20144200201f1b220a201054ad7d220f200a20107d2214200a56200f201b56200f201b511b22011b3703c80720064200201420011b3703c007200641c0086aad4280808080800484200641c0076aad42808080808002841002200641f8076a2003370300200641f0076a2010370300200541013a0000200641c9076a2002290000370000200641d1076a200241086a290000370000200641d9076a200241106a290000370000200641e1076a200241186a290000370000200641033a00c00741b0b4cc004100200641c0076a10d4010b0b2012ad210320064188016a200f37030020064190016a200a370300200641f0006a201437030020064198016a201b370300200641f8006a20103703002006201c370380012006201a3703a0012006200e37036842012110410021052006200c4100200942015122011b3a00ac012006200b410020011b3602a8012006201d4201512201ad370360024020010d002008ad4220862007ad841007420021104200211a0c010b200620083602c407200620073602c007200641e8006a200641c0076a10e7024200211a0b02402006280254450d00200710350b02400240024020050d00024002400240200d41ff017122010d0020104200510d0041032105200641f0026a21010c010b2001450d0120104200520d0141042105200641f0016a21010b200141086a20053a0000200141003a0000200141096a2002290000370000200141116a200241086a290000370000200141196a200241106a290000370000200141216a200241186a29000037000041b0b4cc004100200110d4010b20034201520d01200641f8076a2004370300200641f0076a2011370300200641c0076a41086a41003a0000200641c9076a2002290000370000200641d1076a200241086a290000370000200641d9076a200241106a290000370000200641e1076a200241186a290000370000200641033a00c00741b0b4cc004100200641c0076a10d4010c010b200141ff01714104470d010b200628023421012006290338210320064198086a200641386a41086a29030037030020064190086a2003370300200641c0076a41086a41023a0000200641c9076a2001290000370000200641d1076a200141086a290000370000200641d9076a200141106a290000370000200641e1076a200141186a290000370000200641e9076a2002290000370000200641f1076a200241086a290000370000200641f9076a200241106a29000037000020064181086a200241186a290000370000200641033a00c00741b0b4cc004100200641c0076a10d401200041043a00000c010b2000200141087622023b0001200020013a0000200041036a20024110763a0000200041046a2010420886200dad42ff018384201a843700000b200641f0086a24000bfd0102027f027e200028024021020240410410332203450d002003200236000020002d0044210220034104410810372203450d00200320023a0004200041086a29030021042000290300210520034108411510372203450d00200320053700052003410d6a2004370000200041186a29030021042000290310210520034115412a10372203450d00200320053700152003411d6a2004370000200041286a2903002104200029032021052003412a41d40010372203450d00200320053700252003412d6a2004370000200320002903303700352003413d6a200041386a29030037000020012902002003ad4280808080d008841002200310350f0b103c000b830404047f017e037f027e230041d0006b22012400200141206a41186a4200370300200141206a41106a22024200370300200141206a41086a220342003703002001420037032041a0e4cb00ad42808080808002841001220429000021052003200441086a29000037030020012005370320200410354189eaca00ad4280808080f00084100122042900002105200141c0006a41086a2206200441086a2900003703002001200537034020041035200220012903402205370300200141086a2003290300370300200141106a2005370300200141186a200629030037030020012001290320370300200141206a200110a20220012802202103200129022421052001410036022820014201370320200141206a41002005420020031b2205422088a7220441306c220641306d108a012005a721072003410820031b21082001280228210202402004450d00200128022020024105746a2103200821040340200441086a2900002105200441106a29000021092004290000210a200341186a200441186a290000370000200341106a2009370000200341086a20053700002003200a370000200241016a2102200341206a2103200441306a2104200641506a22060d000b0b2001200236022802402007450d00200741306c450d00200810350b20002001290320370200200041086a200141206a41086a280200360200200141d0006a24000b8d0303047f017e027f230041d0006b22012400200141206a41186a4200370300200141206a41106a22024200370300200141206a41086a220342003703002001420037032041a0e4cb00ad42808080808002841001220429000021052003200441086a29000037030020012005370320200410354189eaca00ad4280808080f00084100122042900002105200141c0006a41086a2206200441086a2900003703002001200537034020041035200220012903402205370300200141086a2003290300370300200141106a2005370300200141186a200629030037030020012001290320370300200141206a200110a20220012802202204410820041b2107410021030240024002402001290224420020041b2205422088a7220441014b0d0020040e020201020b03402004410176220220036a220620032007200641306c6a2000412010a0084101481b2103200420026b220441014b0d000b0b2007200341306c6a2000412010a0084521030b02402005a72204450d00200441306c450d00200710350b200141d0006a240020030bc00c07027f017e027f017e087f057e017f230022042105200441a0016b4160712204240002402002200384500d002000290000210620044180016a200110eb022004280280012107200428028401210842012109024002400240200428028801220a450d002007200a410574220a6a210b200a41406a210c200441e0006a41106a210d200441e0006a41196a210e2007210a02400340200441c0006a41106a220f200a41106a290300370300200441c0006a41086a2210200a41086a2903003703002004200a290300370340200a41186a2d000021112004200a41196a2800003602282004200a411c6a28000036002b20114103460d02200d200f290300370300200441e0006a41086a2010290300370300200e2004280228360000200e41036a200428002b36000020042004290340370360200420113a00780240024002400240200d2000460d00200d2900002000290000510d002004200e2800003602582004200e41036a28000036005b200441e8006a290300211220042903602113200429037021140c010b2009a7210f200441033a0098012004290390012106200429038001211520042903880121162004290398012109200f41ff01714103460d01200441e8006a2903002212200320042903602213200256201220035620122003511b220d1b211220132002200d1b2113201141022011200f41ff0171461b21112004290370211420152102201621030b2004200428005b36003320042004280258360230200420042802303602382004200428003336003b0240412010332217450d0020172013370300201720113a00182017201437031020172004280238360019201720123703082017411c6a200428003b360000200442818080801037021c20042017360218200c4160460d02200a41206a210a200441e0006a41106a210f200441e0006a41196a21104101210e0340200441c0006a41106a220d200a41106a290300370300200441c0006a41086a220b200a41086a2903003703002004200a290300370340200a41186a2d000021112004200a41196a2800003602282004200a411c6a28000036002b20114103460d03200f200d290300370300200441e0006a41086a220d200b29030037030020102004280228360000201041036a220b200428002b36000020042004290340370360200420113a0078024002400240200f2000460d00200f2900002000290000510d00200420102800003602582004200b28000036005b200d2903002112200429036021132004290370211420022115200321160c010b2009a7210b200441033a00980120042903900121062004290380012115200429038801211620042903980121090240200b41ff0171220b4103460d00200d2903002212200320042903602213200256201220035620122003511b220d1b211220132002200d1b2113201141022011200b461b2111200429037021140c010b200c450d070c010b2004200428005b36003320042004280258360230200420042802303602382004200428003336003b2004200428003b3600830120042004280238360280010240200e200428021c470d00200441186a200e410110a101200428021821170b2017200e4105746a220d20113a0018200d2014370310200d200428028001360019200d411c6a200428008301360000200d2012370308200d20133703002004200e41016a220e360220200c450d060b200a41206a210a200c41606a210c20152102201621030c000b0b1045000b200c41606a210c2015210220162103200a41206a220a200b470d010c040b0b20022115200321160b0240200841ffffff3f71450d00200710350b20044180016a41086a200441186a41086a28020036020020042004290318370380010c020b20022115200321160b20044100360288012004420837038001200841ffffff3f71450d00200710350b02400240200942ff01834203854200520d00200428028801210a200428028001210c20044180016a21040c010b0240200428028801220a200428028401470d0020044180016a200a410110a101200428028801210a0b200428028001220c200a4105746a221120063703102011201637030820112015370300201141186a20093703002004200a41016a220a3602880120044180016a21040b2001200c200a10ec02200441046a28020041ffffff3f71450d00200428020010350b200524000ba70704087f017e027f057e23004190016b22022400200241106a200110ed022002280210210320022002280218220136022420022003360220200241286a2001ad4220862003ad84100510c2010240024002400240024020022802282204450d00200228022c21052002200241306a28020036023c20022004360238200241086a200241386a10c40102400240024002402002280208450d0041002106200241003602400c010b200228020c2207200228023c4105762201200120074b1b22014105742206417f4c0d070240024020010d00410821080c010b200610332208450d070b41002106200241003602582002200136025420022008360250024002402007450d00034020024180016a200241386a10ee020240024020022d0080014101460d0041032109200228023c22014110490d01200229008101210a2002200141706a220b36023c20022002280238220c41106a360238200b450d01200c41086a290000210d200c290000210e20022001416f6a36023c2002200c41116a36023841032109200c2d0010220141034f0d012002200228008001360278200220024180016a41036a28000036007b200a210f200e2110200d2111200121090c010b410321090b200220022802783602702002200228007b36007320094103460d022002200228007336006b20022002280270360268024020062002280254470d00200241d0006a2006410110a10120022802502108200228025821060b200820064105746a220120093a00182001200f370310200120022802683600192001411c6a200228006b36000020012011370308200120103703002002200641016a22063602582007417f6a22070d000b0b200241c0006a41086a200241d0006a41086a28020036020020022002290350220f370340200fa722064521012006450d022002290244210f0c030b4100210620024100360240200228025441ffffff3f71450d00200810350b410121010b200241003602482002420137034020024109360284012002200241206a360280012002200241c0006a360278200241e4006a410136020020024201370254200241c888c200360250200220024180016a360260200241f8006a41e88ac500200241d0006a10431a2002350248422086200235024084100602402002280244450d00200228024010350b0b02402005450d00200410350b2001450d010b20004100360208200042083702000c010b2000200f370204200020063602000b02402002280214450d00200310350b20024190016a24000f0b1045000b1044000bb0180d037f027e027f067e027f027e017f017e027f017e037f027e017f230041b0056b22032400200341286a2000108e02200341386a2003280228220420032802302205108f0220032903382106420021072003420037033820034180016a280200210820032d00840121090240024020064201510d0020034188016a41386a420037030020034188016a41306a420037030020034188016a41286a420037030020034188016a41206a420037030020034188016a41186a420037030020034198016a420037030020034190016a420037030020034200370388014200210a4200210b4200210c0c010b200341386a41386a290300210d200341386a41306a290300210e200341386a41206a290300210a200341386a41186a2903002107200341f8006a290300210f2003290348210c2003290340210b20034188016a41206a200341386a41286a29030037030020034188016a41286a200e37030020034188016a41306a200d37030020034198016a20073703002003200a3703a0012003200f3703c0012003200b370388012003200c370390010b4200210d200341c0016a2210420037030020034188016a41306a420037030020034188016a41286a22114200370300200342003703a801200c200a7c2112200b20077c2213200b542214ad211520034188016a41106a211602402002450d00200241057421174200210d4200210f420021184200210e200121190340024002400240201941186a221a2d0000221b417f6a41ff017141014b0d002011200e201941086a290300220720182019290300220a56200e200756200e2007511b221b1b220e37030020032018200a201b1b22183703a801201a2d0000221b4102460d010b201b41ff01710d01201941086a29030021072019290300210a0b2010200d2007200f200a56200d200756200d2007511b221b1b220d3703002003200f200a201b1b220f3703b8010b201941206a2119201741606a22170d000b0b201220157c2107200341c8016a41186a201641086a290300220a370300200341c8016a41206a221b201641106a290300370300200341c8016a41286a201641186a290300370300200341c8016a41306a201641206a29030037030020032016290300220e3703d8012003200b3703c8012003200c3703d00102400240427f200b200e7c220e200e200b542219200c200a7c2019ad7c220a200c54200a200c511b22191b220e428080e983b1de16544100427f200a20191b220f501b0d00200341d8016a290300210e200341f8016a290300210f200341f0016a2903002118201b290300211220032903d001211520032903c801211c4201210a20032903e001211d0c010b02400240200e200f8450450d004200210a0c010b4200210a20034180046a41186a2210420037030020034180046a41106a2217420037030020034180046a41086a221b4200370300200342003703800441b6fdc600ad428080808080018422181001221a2900002112200341a0056a41086a2219201a41086a290000370300200320123703a005201a1035201b2019290300370300200320032903a0053703800441e489c200ad4280808080d0018422121001221a29000021152019201a41086a290000370300200320153703a005201a1035201720032903a005221537030020034180056a41086a2211201b29030037030020034180056a41106a2216201537030020034180056a41186a221e2019290300370300200320032903800437038005200341106a20034180056a412010d701200341106a41106a29030021152003290318211c2003280210211a2010420037030020174200370300201b4200370300200342003703800420181001221029000021182019201041086a290000370300200320183703a00520101035201b2019290300370300200320032903a0053703800420121001221029000021182019201041086a290000370300200320183703a00520101035201720032903a00522183703002011201b29030037030020162018370300201e20192903003703002003200329038004370380052003420020154200201a1b2218200f7d201c4200201a1b2212200e54ad7d22152012200e7d221c201256201520185620152018511b22191b3703880420034200201c20191b3703800420034180056aad428080808080048420034180046aad42808080808002841002200341b8046a200f370300200341b0046a200e370300201b41013a000020034189046a200029000037000020034191046a200041086a29000037000020034199046a200041106a290000370000200341a1046a200041186a290000370000200341033a00800441b0b4cc00410020034180046a10d4010b0b2007200c5121192007200c54211b200341e0006a2012370300200341e8006a2018370300200341c8006a2015370300200341f0006a200f370300200341d0006a200e3703002003201d3703582003200d3703782003201c370340200320094100200642015122171b3a00840120032008410020171b360280012003200a4201512217ad3703380240024020170d002005ad4220862004ad8410070c010b20032005360284042003200436028004200341c0006a20034180046a10e7020b2014201b20191b21190240200328022c450d00200410350b427f200720191b2107427f201320191b210d200a420152211902400240024020064201510d0020190d004103211b20034180036a21190c010b20064201522019410173720d014104211b20034180026a21190b201941086a201b3a0000201941003a0000201941096a2000290000370000201941116a200041086a290000370000201941196a200041106a290000370000201941216a200041186a29000037000041b0b4cc004100201910d4010b0240200d2007844200520d00200341b8046a200c370300200341b0046a200b37030020034180046a41086a41003a000020034189046a200029000037000020034191046a200041086a29000037000020034199046a200041106a290000370000200341a1046a200041186a290000370000200341033a00800441b0b4cc00410020034180046a10d4010b20034180046a200010ed02200341086a200328028004221920032802880441b0b4cc0041004100108a02200328020821040240200328028404450d00201910350b0240024002400240024002402002450d0020034180036a200010ed0220024105744104722219417f4c0d02200335028803210d200328028003210520191033221b450d03200341003602880420032019360284042003201b36028004200220034180046a107720024105742111200328028404211a2003280288042117034002400240201a20176b4108490d00200328028004211b201a21100c010b201741086a22192017490d06201a410174221b2019201b20194b1b22104100480d0602400240201a0d00024020100d004101211b0c020b20101033221b0d010c090b200328028004211b201a2010460d00201b201a20101037221b450d080b20032010360284042003201b360280040b201b20176a200141106a2900003700002003201741086a221a36028804200141086a29030021072001290300210a024002402010201a6b410f4d0d00201021190c010b201a41106a2219201a490d06201041017422162019201620194b1b22194100480d060240024020100d00024020190d004101211b0c020b20191033221b450d090c010b20102019460d00201b201020191037221b450d080b20032019360284042003201b360280040b201b201a6a221a2007370008201a200a3700002003201741186a221736028804200141186a2d000021100240024020192017460d002019211a201721190c010b201941016a22172019490d062019410174221a2017201a20174b1b221a4100480d060240024020190d00410021190240201a0d004101211b0c020b201a1033221b450d090c010b2019201a460d00201b2019201a1037221b450d080b2003201a360284042003201b360280040b200141206a2101201b20196a20103a00002003201941016a221736028804201141606a22110d000b2003280284042119200d4220862005ad842017ad422086200328028004221bad84100202402019450d00201b10350b0240200328028403450d00200510350b20044101460d012000108d020c010b20034180046a200010ed022003350288044220862003280280042219ad8410070240200328028404450d00201910350b20044101470d0020001099020b200341b0056a24000f0b1044000b1045000b103e000b103c000bc20503027f017e047f230041d0006b2202240041b6fdc600ad4280808080800184100122032900002104200241086a200341086a290000370300200220043703002003103541b8a2c600ad4280808080d00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bf00204027f017e017f077e0240024020012802042202450d0020012802002203310000210420012002417f6a22053602042001200341016a3602002005450d012003310001210620012002417e6a22053602042001200341026a3602002005450d012003310002210720012002417d6a22053602042001200341036a3602002005450d012003310003210820012002417c6a22053602042001200341046a3602002005450d012003310004210920012002417b6a22053602042001200341056a3602002005450d012003310005210a20012002417a6a22053602042001200341066a3602002005450d012003310006210b2001200241796a22053602042001200341076a3602002005450d01200041003a00002003310007210c2001200241786a3602042001200341086a3602002000200c423886200b42308684200a422886842009422086842008421886842007421086842006420886842004843700010f0b200041013a00000f0b200041013a00000bb3270f037f017e037f057e037f017e037f027e017f027e017f017e027f047e047f230041900a6b220624002006200437034020062003370338200620053a004f024002400240024002400240024002400240024002402003200484500d0020012002460d0320012002412010a008450d03200641d0016a2002108e02200641e0016a20062802d001220720062802d8012208108f0220062903e001210942002104200642003703e001200641a8026a280200210a20062d00ac02210b2009420151220c0d01200641b0026a41386a4200370300200641b0026a41306a4200370300200641b0026a41286a4200370300200641d0026a4200370300200641b0026a41186a4200370300200641c0026a4200370300200641b8026a4200370300200642003703b002420021034200210d4200210e0c020b20004100360200200041106a4200370300200041086a42003703000c090b200641e0016a41386a290300210f200641e0016a41306a2903002110200641e0016a41206a290300210e200641e0016a41186a290300210d200641a0026a290300211120062903f001210320062903e8012104200641d0026a200641e0016a41286a290300370300200641b0026a41286a2010370300200641b0026a41306a200f370300200641c0026a200d3703002006200e3703c802200620113703e802200620043703b002200620033703b8020b200641b0026a41106a2105427f2004200d7c220d200d20045422122003200e7c2012ad7c220420035420042003511b22121b427f200420121b84500d01200641f0046a2001108e0220064180056a20062802f004221320062802f8042214108f022006290380052115420021032006420037038005200641c8056a280200211620062d00cc05211702400240201542015122180d00200641d0056a41306a4200370300200641d0056a41286a4200370300200641d0056a41206a4200370300200641d0056a41186a4200370300200641e0056a4200370300200641d8056a4200370300200642003703d005420021044200210e4200210d420021190c010b200641b8056a290300210f20064180056a41306a290300211020064180056a41206a290300210420064180056a41186a2903002103200641c0056a2903002119200629039005210d200629038805210e200641d0056a41206a20064180056a41286a290300370300200641d0056a41286a2010370300200641d0056a41306a200f370300200641e0056a2003370300200620043703e8052006200e3703d0052006200d3703d8050b200641386a41086a2903002210200420032006290338221156200420105620042010511b22121b211a2011200320121b210f0240024020062d004f4101470d00200641d0066a21122005211b20062903c002221c200f7c221d201c54221e200641c8026a290300221f201a7c201ead7c221c201f54201c201f511b0d010c040b200641c0066a2112200641b0026a211b20062903b002221c200f7c221d201c54221e200641b0026a41086a290300221f201a7c201ead7c221c201f54201c201f511b4101470d030b201241086a4108360200201241046a221841a7d6ca00360200201241026a41023a0000201241830c3b0100201829020022034280807c83210f200342088842ff018321042003a721182012280200211b410121120c030b02402005450d00200641e0076a2001108e02200641e0086a20062802e007220220062802e807108f0220064180096a290300420020062903e00842015122011b210e200641f8086a290300420020011b210d024020062802e407450d00200210350b20004100360200200041106a42002004200e7d2003200d54ad7d220e2003200d7d220d200356200e200456200e2004511b22011b370300200041086a4200200d20011b3703000c070b200620033703e006200620043703e806200620013602f003200641e0076a2001200641e0066a200641f0036a10f00220064180086a290300210320062903f8072104024020062903e0074201520d0020062903e807210d20064198096a200641e0076a41106a29030037030020064190096a200d370300200641e0086a41086a41003a0000200641e9086a2001290000370000200641f1086a200141086a290000370000200641f9086a200141106a29000037000020064181096a200141186a290000370000200641033a00e00841b0b4cc004100200641e0086a10d4010b200041106a2003370300200041086a2004370300200041003602000c060b200641e0066a41206a200541206a290300370300200641e0066a41186a200541186a290300370300200641e0066a41106a200541106a290300370300200641e0066a41086a200541086a290300370300200620052903003703e00641ea88c200ad4280808080b0018421034200211041838c1c211b0c020b201b201d370300201b201c370308200641d0056a41186a2004201a7d2003200f54ad7d37030020062003200f7d3703e00520064188066a41186a200641e0056a221241086a290300221c37030020064188066a41206a221b201241106a290300370300200641b0066a2220201241186a290300370300200641b8066a2221201241206a29030037030020062012290300221d370398062006200e370388062006200d370390062010201a7d21102011200f54ad211a427f200e20037c22032003200e542212200d20047c2012ad7c2203200d542003200d511b22121b427f200320121b8450211e02400240427f200e201d7c22032003200e542212200d201c7c2012ad7c2203200d542003200d511b22121b2204428080e983b1de16544100427f200320121b2203501b0d0020064188066a41106a29030021042021290300211c2020290300211d201b290300211f200629039006212220062903880621234201212420062903a00621250c010b02400240200420038450450d00420021240c010b42002124200641e0086a41186a22264200370300200641e0086a41106a22204200370300200641e0086a41086a221b4200370300200642003703e00841b6fdc600ad4280808080800184221c10012221290000211d200641800a6a41086a2212202141086a2900003703002006201d3703800a20211035201b2012290300370300200620062903800a3703e00841e489c200ad4280808080d00184221d10012221290000211f2012202141086a2900003703002006201f3703800a20211035202020062903800a221f370300200641e0096a41086a2227201b290300370300200641e0096a41106a2228201f370300200641e0096a41186a22292012290300370300200620062903e0083703e009200641206a200641e0096a412010d701200641206a41106a290300211f20062903282122200628022021212026420037030020204200370300201b4200370300200642003703e008201c10012226290000211c2012202641086a2900003703002006201c3703800a20261035201b2012290300370300200620062903800a3703e008201d10012226290000211c2012202641086a2900003703002006201c3703800a20261035202020062903800a221c3703002027201b2903003703002028201c37030020292012290300370300200620062903e0083703e00920064200201f420020211b221c20037d2022420020211b221d200454ad7d221f201d20047d2222201d56201f201c56201f201c511b22121b3703e80820064200202220121b3703e008200641e0096aad4280808080800484200641e0086aad4280808080800284100220064198096a200337030020064190096a2004370300201b41013a0000200641e9086a2001290000370000200641f1086a200141086a290000370000200641f9086a200141106a29000037000020064181096a200141186a290000370000200641033a00e00841b0b4cc004100200641e0086a10d4010b0b2010201a7d21102011200f7d2111201ead2103200641a8056a201f370300200641b0056a201d37030020064190056a2022370300200641b8056a201c37030020064198056a2004370300200620253703a005200620193703c005200620233703880542012104410021122006201741002015420151221b1b3a00cc05200620164100201b1b3602c80520062024420151221bad370380050240201b0d002014ad4220862013ad841007420021044200210f0c010b200620143602e408200620133602e00820064188056a200641e0086a10e7024200210f0b024020062802f404450d00201310350b024002402012450d0020044208862018ad42ff018384200f842103410121180c010b02400240201841ff017122120d0020044200510d0041032118200641e0076a21120c010b410021182012450d0120044200520d0141042118200641e0066a21120b201241086a20183a000041002118201241003a0000201241096a2001290000370000201241116a200141086a290000370000201241196a200141106a290000370000201241216a200141186a29000037000041b0b4cc004100201210d4010b024002402018450d0042002110410121120c010b41002112024020034201520d0020064198096a200d37030020064190096a200e37030041002112200641e0086a41086a41003a0000200641e9086a2001290000370000200641f1086a200141086a290000370000200641f9086a200141106a29000037000020064181096a200141186a290000370000200641033a00e00841b0b4cc004100200641e0086a10d4010b201121030b200641b0026a41086a290300210420062903b002210d20062903e802210e200641e0066a41206a2201200541206a290300370300200641e0066a41186a2218200541186a290300370300200641e0066a41106a2213200541106a290300370300200641e0066a41086a2216200541086a290300370300200620052903003703e0062012450d010b20034280807c83210d200342088842ff018321042003a7210c410121010c010b200641e0076a41186a2016290300220f370300200641e0076a41206a201329030037030020064188086a2205201829030037030020064190086a22122001290300370300200620062903e00622113703f0072006200d3703e007200620043703e80702400240427f200d20117c22112011200d5422012004200f7c2001ad7c220d200454200d2004511b22011b2204428080e983b1de16544100427f200d20011b220d501b0d00200641f0076a29030021042012290300210d2005290300210f20064180086a290300211120062903e807211a20062903e00721154201211c20062903f80721190c010b024002402004200d8450450d004200211c0c010b4200211c200641e0086a41186a22134200370300200641e0086a41106a22124200370300200641e0086a41086a22054200370300200642003703e00841b6fdc600ad4280808080800184220f100122182900002111200641800a6a41086a2201201841086a290000370300200620113703800a2018103520052001290300370300200620062903800a3703e00841e489c200ad4280808080d00184221110012218290000211a2001201841086a2900003703002006201a3703800a20181035201220062903800a221a370300200641e0096a41086a22162005290300370300200641e0096a41106a2217201a370300200641e0096a41186a22142001290300370300200620062903e0083703e009200641086a200641e0096a412010d701200641086a41106a290300211a2006290310211520062802082118201342003703002012420037030020054200370300200642003703e008200f10012213290000210f2001201341086a2900003703002006200f3703800a2013103520052001290300370300200620062903800a3703e008201110012213290000210f2001201341086a2900003703002006200f3703800a20131035201220062903800a220f370300201620052903003703002017200f37030020142001290300370300200620062903e0083703e00920064200201a420020181b220f200d7d2015420020181b2211200454ad7d221a201120047d2215201156201a200f56201a200f511b22011b3703e80820064200201520011b3703e008200641e0096aad4280808080800484200641e0086aad4280808080800284100220064198096a200d37030020064190096a2004370300200541013a0000200641e9086a2002290000370000200641f1086a200241086a290000370000200641f9086a200241106a29000037000020064181096a200241186a290000370000200641033a00e00841b0b4cc004100200641e0086a10d4010b0b20064188026a201137030020064190026a200f370300200641f0016a201a37030020064198026a200d370300200641f8016a200437030020062019370380022006200e3703a002200620153703e80142012104410021012006200b4100200942015122051b3a00ac022006200a410020051b3602a8022006201c4201512205ad3703e0010240024020050d002008ad4220862007ad841007420021040c010b200620083602e408200620073602e008200641e8016a200641e0086a10e7020b4200210d0b024020062802d401450d00200710350b024020010d00024002400240200c41ff017122010d0020044200510d0041032105200641f0036a21010c010b2001450d0120044200520d0141042105200641f0026a21010b200141086a20053a0000200141003a0000200141096a2002290000370000200141116a200241086a290000370000200141196a200241106a290000370000200141216a200241186a29000037000041b0b4cc004100200110d4010b200041106a2010370300200041086a2003370300200041003602000c010b2000201b360204200041086a2004420886200cad42ff018384200d84370200200041013602000b200641900a6a24000bc50f07037f027e027f0c7e037f047e047f230041d0036b2204240020032802002105200441206a2001108e02200441a0016a2004280220220320042802282206108f0220042903a001210742002108200442003703a001200441e8016a280200210920042d00ec01210a0240024020074201510d00200441306a41306a4200370300200441306a41286a4200370300200441306a41206a4200370300200441306a41186a4200370300200441c0006a4200370300200441386a4200370300200442003703304200210b4200210c4200210d4200210e0c010b200441d8016a290300210f200441a0016a41306a2903002110200441a0016a41206a290300210b200441a0016a41186a2903002108200441e0016a290300210e20042903b001210d20042903a801210c200441306a41206a200441a0016a41286a290300370300200441306a41286a2010370300200441306a41306a200f370300200441c0006a20083703002004200b3703482004200c3703302004200d3703380b200441306a41186a200b200241086a2903002211200b20082002290300221256200b201156200b2011511b22021b22137d20082012200820021b221054ad7d22143703002004200820107d22153703402004427f200d20137c200c20107c2216200c542202ad7c220f2002200f200d54200f200d511b22021b220f3703382004427f201620021b2216370330200441e8006a41186a2014370300200441e8006a41206a2217200441306a41206a290300370300200441e8006a41286a2218200441306a41286a290300370300200441e8006a41306a2219200441306a41306a2903003703002004200f3703702004201637036820042015370378427f200d200b7c200c20087c220b200c542202ad7c220820022008200d542008200d511b22021b210c427f200b20021b211a02400240427f201620157c220d200d2016542202200f20147c2002ad7c220d200f54200d200f511b22021b2208428080e983b1de16544100427f200d20021b220b501b0d00200441f8006a29030021082019290300210b20182903002114201729030021152004290370211b2004290368211c4201210d200429038001211d0c010b024002402008200b8450450d004200210d0c010b4200210d200441a0026a41186a221e4200370300200441a0026a41106a22184200370300200441a0026a41086a22174200370300200442003703a00241b6fdc600ad42808080808001842214100122192900002115200441c0036a41086a2202201941086a290000370300200420153703c0032019103520172002290300370300200420042903c0033703a00241e489c200ad4280808080d00184221510012219290000211b2002201941086a2900003703002004201b3703c00320191035201820042903c003221b370300200441a0036a41086a221f2017290300370300200441a0036a41106a2220201b370300200441a0036a41186a22212002290300370300200420042903a0023703a003200441086a200441a0036a412010d701200441086a41106a290300211b2004290310211c20042802082119201e42003703002018420037030020174200370300200442003703a00220141001221e29000021142002201e41086a290000370300200420143703c003201e103520172002290300370300200420042903c0033703a00220151001221e29000021142002201e41086a290000370300200420143703c003201e1035201820042903c0032214370300201f20172903003703002020201437030020212002290300370300200420042903a0023703a00320044200201b420020191b2214200b7d201c420020191b2215200854ad7d221b201520087d221c201556201b201456201b2014511b22021b3703a80220044200201c20021b3703a002200441a0036aad4280808080800484200441a0026aad42808080808002841002200441d8026a200b370300200441d0026a2008370300201741013a0000200441a9026a2005290000370000200441b1026a200541086a290000370000200441b9026a200541106a290000370000200441c1026a200541186a290000370000200441033a00a00241b0b4cc004100200441a0026a10d4010b0b20122010542102201a200c84210c200441c8016a2015370300200441d0016a2014370300200441b0016a201b370300200441d8016a200b370300200441b8016a20083703002004201d3703c0012004200e3703e0012004201c3703a8012004200a4100200742015122051b3a00ec0120042009410020051b3602e8012004200d4201512205ad3703a0010240024020050d002006ad4220862003ad8410070c010b200420063602a402200420033602a002200441a8016a200441a0026a10e7020b201120137d21082002ad210b200c50210202402004280224450d00200310350b2008200b7d21082002ad210b201220107d210c200d420152210202400240024020074201510d0020020d0041032103200441a0026a21020c010b20074201522002410173720d0141042103200441a0016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b2000200c370318200020163703082000200b370300200041206a2008370300200041106a200f370300200441d0036a24000b130020004104360204200041f89cc2003602000b3400200041b6fdc60036020420004100360200200041146a4104360200200041106a41c4b6c200360200200041086a42083702000b830101017f0240411010332202450d00200242003700082002420037000020024110412010372202450d0020024200370010200241186a42003700002002412041c00010372202450d002002420037003020024200370020200042c0808080800837020420002002360200200241386a4200370000200241286a42003700000f0b103c000b130020004101360204200041f4bec2003602000b130020004106360204200041ecbfc2003602000b3400200041a0e4cb0036020420004100360200200041146a4105360200200041106a41d8d8c200360200200041086a42103702000b3a01017f230041206b22022400200241186a41003602002002420037030820024200370300200242013703102000200210f802200241206a24000bad0301077f230041106b220224000240200141186a28020022034105744114722204417f4c0d000240200410332205450d00200520012903003700002005200141086a2903003700082002411036020820022004360204200220053602002001280210210620032002107702402003450d0020034105742107200228020021082002280204210420022802082103034020062101024002402004200322056b4120490d00200541206a21030c010b024002400240200541206a22032005490d00200441017422062003200620034b1b22064100480d000240024020040d00024020060d00410121080c020b2006103321080c040b20042006470d020b200621040c030b103e000b200820042006103721080b2006210420080d00103c000b200141206a2106200820056a22052001290000370000200541186a200141186a290000370000200541106a200141106a290000370000200541086a200141086a290000370000200741606a22070d000b2002200436020420022003360208200220083602000b20002002290300370200200041086a200241086a280200360200200241106a24000f0b1045000b1044000b130020004106360204200041d8e0c2003602000b3501017f02404108103322020d001045000b20004288808080800137020420002002360200200242f0d0c9abc6add9b1f4003700000b2e01017f02404104103322020d001045000b20004284808080c0003702042000200236020020024180a70c3600000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241073600000b2c01017f02404104103322020d001045000b20004284808080c000370204200020023602002002410d3600000b8709010f7f23004190036b2204240002400240200141046a28020022052f01062206410b490d002001280208210720012802002108200441306a410041e002109f081a200441286a22064100360200200441206a22094200370300200441186a220a4200370300200441106a220b4200370300200441086a220c42003703002004420037030002404194031033220d450d00200d41003b0106200d4100360200200d41086a200441306a41e002109d08210e200d4190036a2006280200360200200d4188036a2009290300370200200d4180036a200a290300370200200d41f8026a200b290300370200200d41f0026a200c290300370200200d20042903003702e802200441306a41086a2209200541d0016a290000370300200441306a41106a220f200541d8016a290000370300200441306a41186a2210200541e0016a290000370300200420052900c8013703302005280280032111200e200541e8016a20052f010641796a2206410574109d08210e200d41e8026a20054184036a2006410274109d082112200541063b0106200d20063b0106200a2010290300370300200b200f290300370300200c20092903003703002004200429033037030002400240200128020c22014107490d00200d41066a210a200e2001417a6a220c4105746a200e200141796a22014105746a220b200641ffff037120016b410574109e081a200b41186a200241186a290000370000200b41106a200241106a290000370000200b41086a200241086a290000370000200b20022900003700002012200c4102746a2106201220014102746a21020c010b200541086a220a200141016a220b4105746a200a20014105746a2206200541066a220a2f010020016b410574109e081a200641186a200241186a290000370000200641106a200241106a290000370000200641086a200241086a29000037000020062002290000370000200541e8026a220620014102746a21022006200b4102746a2106200121010b20062002200a2f010020016b410274109e081a20022003360200200041013a00002000200236023c200041386a4100360200200041346a200d360200200041306a20113602002000412c6a2007360000200041286a2005360000200041246a200836000020002004290300370001200041096a200441086a290300370000200041116a200441106a290300370000200041196a200441186a290300370000200a200a2f010041016a3b01000c020b103c000b200541086a220a200128020c220d41016a220b4105746a200a200d4105746a220a2006200d6b410574109e081a200a41186a200241186a290000370000200a41106a200241106a290000370000200a41086a200241086a290000370000200a2002290000370000200541e8026a2202200b4102746a2002200d4102746a220220052f0106200d6b410274109e081a20022003360200200520052f010641016a3b0106200441306a410b6a200141086a280000360000200041003a00002000200236023c200041106a200d3600002004200129000037003320002004290030370001200041086a200441376a2900003700000b20044190036a24000be60b020f7f047e23004180046b220624000240024020012802002207417f6a2005470d000240024002400240200141046a28020022082f01062209410b490d002001280208210a200641c0006a410272410041be03109f081a41c4031033220b450d05200b4100360200200b41046a200641c0006a41c003109d081a200641c0006a41186a220c200841e0016a290000370300200641c0006a41106a220d200841d8016a290000370300200641c0006a41086a220e200841d0016a290000370300200620082900c801370340200828028003210f200b41086a200841e8016a20082f0106221041796a2205410574109d082111200b41e8026a20084184036a2005410274109d082112200b4194036a200841b0036a2010417a6a2213410274109d082114200841063b0106200b20053b010602402013450d00410021052014211003402010280200220920053b01042009200b360200201041046a21102013200541016a2205470d000b0b200641206a41186a200c2903002215370300200641206a41106a200d2903002216370300200641206a41086a200e2903002217370300200620062903402218370320200641186a2015370300200641106a2016370300200641086a201737030020062018370300200128020c22054107490d0120112005417a6a22014105746a2011200541796a22104105746a2209200b2f010620106b410574109e081a200941186a200241186a290000370000200941106a200241106a290000370000200941086a200241086a290000370000200920022900003700002012200141027422096a201220104102746a2213200b2f010620106b410274109e081a20132003360200200b200b2f010641016a22133b01062005410274220220146a416c6a201420096a2205201341ffff037120016b410274109e081a200520043602002001200b2f010622134b0d022002200b6a41fc026a2105034020052802002209201041016a22103b01042009200b360200200541046a210520102013490d000c030b0b200841086a2205200128020c221341016a22104105746a200520134105746a2205200920136b410574109e081a200541186a200241186a290000370000200541106a200241106a290000370000200541086a200241086a29000037000020052002290000370000200841e8026a22092010410274220b6a2009201341027422056a220920082f010620136b410274109e081a20092003360200200820082f010641016a22093b0106200520084194036a22026a41086a2002200b6a220b200941ffff037120106b410274109e081a200b20043602000240201020082f0106220b4b0d00200820056a4198036a210520132110034020052802002209201041016a22103b010420092008360200200541046a21052010200b490d000b0b200041003a0000200041046a2001290200370200200041106a20133602002000410c6a200141086a2802003602000c020b200841086a2210200541016a22094105746a201020054105746a221020082f010620056b410574109e081a201041186a200241186a290000370000201041106a200241106a290000370000201041086a200241086a29000037000020102002290000370000200841e8026a2213200941027422016a2013200541027422106a221320082f010620056b410274109e081a20132003360200200820082f010641016a22133b0106201020084194036a22026a41086a200220016a2201201341ffff037120096b410274109e081a20012004360200200520082f010622134f0d00200820106a4198036a2110034020102802002209200541016a22053b010420092008360200201041046a211020132005470d000b0b20002006290300370001200041013a00002000412c6a200a360200200041286a2008360200200041246a2007360200200041386a2007360200200041346a200b360200200041306a200f360200200041096a200641086a290300370000200041116a200641106a290300370000200041196a200641186a2903003700000b20064180046a24000f0b41d684cc00413541c086cc00103f000b103c000bb71a01197f230041d0116b2202240020002802102203200328020041016a360200200028020c2104200028020821052000280200210620002802042103200241206a41186a22072000412c6a290000370300200241206a41106a2208200041246a290000370300200241206a41086a22092000411c6a29000037030020022000290014370320200241a0026a200141e000109d081a024002400240024002400240024020032f01062201410b490d00200241b0036a410041e002109f081a20024198066a410041a008109f081a41880b1033220a450d04200a41003b0106200a4100360200200a41086a200241b0036a41e002109d082101200a41e8026a20024198066a41a008109d0821072002200341c8016a2f00003b01ac032002200341ca016a2d00003a00ae032002200341db016a290000370398032002200341e0016a29000037009d03200341cb016a280000210b200341cf016a280000210c200341d3016a280000210d200341d7016a280000210e20024198066a200341a8076a41e000109d081a2001200341e8016a20032f010641796a2200410574109d082101200720034188086a200041e0006c109d082107200341063b0106200a20003b0106200220022f01ac033b019403200220022d00ae033a0096032002200229039803370380032002200229009d0337008503200241b0036a20024198066a41e000109d081a0240024020044107490d00200441057420016a41c07e6a2001200441796a22084105746a2201200041ffff037120086b410574109e081a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200441e0006c20076a220041c07b6a200041e07a6a220f200a41066a22002f010020086b41e0006c109e081a200f200241a0026a41e000109d081a0c010b200341086a20044105746a220141206a2001200341066a22002f010020046b410574109e081a200141186a200241206a41186a290300370000200141106a200241206a41106a290300370000200141086a200241206a41086a29030037000020012002290320370000200341e8026a200441e0006c6a220f41e0006a200f20002f010020046b41e0006c109e081a200f200241a0026a41e000109d081a0b20024188026a41026a220420022d0096033a0000200020002f010041016a3b0100200220022f0194033b01880220022002290380033703800120022002290085033700850120024190016a200241b0036a41e000109d081a2002411c6a41026a221020042d00003a0000200220022f0188023b011c2002200229038001370308200220022900850137000d200241206a20024190016a41e000109d081a200328020022070d01410021030c020b200320044105746a220041286a200041086a2206200120046b410574109e081a200041206a2007290300370000200041186a2008290300370000200041106a2009290300370000200620022903203700002003200441e0006c6a220041c8036a200041e8026a220f20032f010620046b41e0006c109e081a200f200241a0026a41e000109d081a200320032f010641016a3b01060c020b20032f0104211120024198066a410272211241002103024003402002419c026a41026a221320102d00003a0000200220022f011c3b019c0220022002290308370388022002200229000d37008d02200241a0026a200241206a41e000109d081a20062003470d01201141ffff0371210802400240024020072f01062203410b490d002012410041b20b109f081a41b80b10332201450d0720014100360200200141046a20024198066a41b40b109d081a200220072f00c8013b01ac032002200741ca016a2d00003a00ae032002200741db016a290000370398032002200741e0016a29000037009d03200741cb016a2800002114200741cf016a2800002115200741d3016a2800002116200741d7016a280000211720024198066a200741a8076a41e000109d081a200141086a200741e8016a20072f0106220041796a2203410574109d082118200141e8026a20074188086a200341e0006c109d082119200141880b6a200741a40b6a2000417a6a2209410274109d08211a200741063b0106200120033b010602402009450d0041002103201a210003402000280200220420033b010420042001360200200041046a21002009200341016a2203470d000b0b200241b0036a20024198066a41e000109d081a200220022d00ae0322033a009603200220022f01ac0322003b0194032002200229009d033700850320022002290398033703800320024194066a41026a220920033a0000200220003b01940620022002290380033703800120022002290085033700850120024198066a200241b0036a41e000109d081a201141ffff037122004107490d0120182008417a6a22044105746a2018200841796a22034105746a220020012f010620036b410574109e081a200041186a200229008d023700002000200e36000f2000200d36000b2000200c3600072000200b360003200041026a20132d00003a0000200020022f019c023b00002000200229038802370013200841e0006c20196a220041c07b6a200041e07a6a220020012f010620036b41e0006c109e081a2000200241a0026a41e000109d081a200120012f010641016a22003b01062008410274220b201a6a416c6a201a20044102746a2211200041ffff0371220820046b410274109e081a2011200a36020020082004490d022001200b6a41f00a6a2100034020002802002204200341016a22033b010420042001360200200041046a210020032008490d000c030b0b200741086a2200200841016a22044105746a200020084105746a2200200320086b2201410574109e081a2000200e36000f2000200d36000b2000200c3600072000200b360003200041026a2002419c026a41026a2d00003a0000200020022f019c023b00002000200229038802370013200041186a200229008d023700002007200841e0006c6a220041c8036a200041e8026a2200200141e0006c109e081a2000200241a0026a41e000109d081a2007200341016a22033b01062008410274200741880b6a22006a41086a200020044102746a2200200341ffff037120046b410274109e081a2000200a360200201141ffff037120072f010622034f0d05200a20043b0104200a2007360200200420034f0d052003417f6a210120072004417f6a22034102746a41900b6a2100034020002802002204200341026a3b010420042007360200200041046a21002001200341016a2203470d000c060b0b200741086a2203200841016a22044105746a200320084105746a220320072f0106221120086b221a410574109e081a2003200e36000f2003200d36000b2003200c3600072003200b360003200341026a20132d00003a0000200320022f019c023b00002003200229038802370013200341186a200229008d02370000200741e8026a200841e0006c6a220341e0006a2003201a41e0006c109e081a2003200241a0026a41e000109d081a2007201141016a22033b01062008410274221a200741880b6a22116a41086a201120044102746a2211200341ffff037120046b410274109e081a2011200a360200200020072f010622044f0d002007201a6a418c0b6a2103034020032802002200200841016a22083b010420002007360200200341046a210320042008470d000b0b200641016a210320024184026a41026a220020092d00003a0000200220022f0194063b01840220022002290380013703f00120022002290085013700f50120024190016a20024198066a41e000109d081a201020002d00003a0000200220022f0184023b011c200220022903f001370308200220022900f50137000d200241206a20024190016a41e000109d081a0240200728020022000d002014210b2017210e2016210d2015210c2001210a0c030b20072f010421112014210b2017210e2016210d2015210c200021072001210a200321060c000b0b41d684cc00413541c086cc00103f000b20024198066a410272410041b20b109f081a41b80b10332200450d0120004100360200200041046a20024198066a41b40b109d081a2000200528020022043602880b2005200036020020052005280204220141016a360204200441003b010420042000360200200241a0026a41026a2002411c6a41026a2d00003a0000200220022f011c3b01a002200220022903083703b0032002200229000d3700b50320024198066a200241206a41e000109d081a20012003470d0220002f01062204410a4b0d03200020044105746a2203410a6a200241a0026a41026a2d00003a0000200341086a20022f01a0023b0000200341176a200e360000200341136a200d3600002003410f6a200c3600002003410b6a200b3600002003411b6a20022903b003370000200341206a20022900b5033700002000200441e0006c6a41e8026a20024198066a41e000109d081a2000200441016a22034102746a41880b6a200a360200200020033b0106200a20033b0104200a20003602000b200241d0116a2400200f0f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000bfb0203057f017e027f0240024020002802202201450d00034020002001417f6a36022020002802042201450d0220002802082102200028020021030240200028020c220420012f0106490d00034002400240200128020022050d002002ad2106410021050c010b200341016a210320013301044220862002ad8421060b200110352006a72102200521012006422088a7220420052f01064f0d000b200521010b200441016a210720012004410c6c6a220541ec026a2802002108200541e8026a280200210402402003450d00200120074102746a41ec036a2802002101410021072003417f6a2205450d00034020012802ec0321012005417f6a22050d000b0b2000200736020c20002002360208200020013602042000410036020002402004450d002008450d00200410350b200028022022010d000b0b024020002802042205450d0020052802002101200510352001450d00034020012802002105200110352005210120050d000b0b0f0b41958dcc00412b41c08dcc00103f000bc91305027f017e067f037e0a7f230041b0036b2202240020002802102203200328020041016a36020020002902142104200028020c2105200028020821062000280200210320002802042100200241f0016a41086a2207200141086a280200360200200220012902003703f001024002400240024002400240024020002f01062201410b490d00200241d0026a410272410041da00109f081a200241386a4100418401109f081a41e40110332208450d0420084100360200200841046a200241d0026a41dc00109d081a200841e0006a200241386a418401109d082107200241386a41086a2209200041b0016a280200360200200220002902a8013703382000413f6a2d0000210a200041386a350000210b2000413c6a330000210c2000413e6a310000210d200841086a200041c0006a20002f010641796a2201410374109d08210e2007200041b4016a2001410c6c109d082107200041063b0106200820013b0106200241d0026a41086a2009280200360200200220022903383703d002200b200c200d4210868442208684210b0240024020054107490d002005410374200e6a41506a200e200541796a22094103746a220e200141ffff037120096b410374109e081a200e20043700002005410c6c20076a220541b87f6a200541ac7f6a2205200841066a22012f010020096b410c6c109e081a200541086a200241f0016a41086a280200360200200520022903f0013702000c010b200041086a20054103746a220741086a2007200041066a22012f010020056b410374109e081a20072004370000200041e0006a2005410c6c6a2207410c6a200720012f010020056b410c6c109e081a200741086a200241f0016a41086a280200360200200720022903f0013702000b200120012f010041016a3b0100200241286a41086a220f200241d0026a41086a22102802002205360200200241086a221120053602002002200a3a0017200220022903d00222043703282002200b3e02102002200b4230883c00162002200b4220883d01142002200437030020022903102104200028020022090d01410021120c020b200020054103746a220341106a200341086a2203200120056b410374109e081a2003200437000020002005410c6c6a220341ec006a200341e0006a220120002f010620056b410c6c109e081a200341e8006a2007280200360200200120022903f001370200200020002f010641016a3b01060c020b20002f01042113200241d0026a41027221144100210002400340200220093602242002200341016a2212360220200f20112802003602002002200229030037032820032000470d01201341ffff0371210702400240024020092f01062203410b490d002014410041da00109f081a200241f0016a200241d0026a41dc00109d081a200241386a410041b401109f081a41940210332201450d0720014100360200200141046a200241f0016a41dc00109d081a200141e0006a200241386a41b401109d0821002009290038210b200241386a41086a220e200941b0016a280200360200200220092902a801370338200141086a200941c0006a20092f0106220541796a2203410374109d0821152000200941b4016a2003410c6c109d082116200141e4016a20094180026a2005417a6a220a410274109d082117200941063b0106200120033b01060240200a450d00410021032017210003402000280200220520033b010420052001360200200041046a2100200a200341016a2203470d000b0b2010200e280200220336020020022002290338220c3703d002200e20033602002002200c370338201341ffff037122004107490d0120152007417a6a22004103746a2015200741796a22034103746a220520012f010620036b410374109e081a200520043700002007410c6c20166a220541b87f6a200541ac7f6a220520012f0106220a20036b410c6c109e081a200541086a200f280200360200200520022903283702002001200a41016a22053b01062007410274221320176a416c6a201720004102746a220a200541ffff0371220720006b410274109e081a200a200836020020072000490d02200120136a41cc016a2100034020002802002205200341016a22033b010420052001360200200041046a210020032007490d000c030b0b200941086a2205200741016a22004103746a200520074103746a2205200320076b2201410374109e081a2005200437000020092007410c6c6a220541ec006a200541e0006a220a2001410c6c109e081a200541e8006a200241286a41086a280200360200200a20022903283702002009200341016a22033b01062007410274200941e4016a22056a41086a200520004102746a2205200341ffff0371220120006b410274109e081a20052008360200201341ffff037120014f0d0520092000417f6a22034102746a41e8016a2100034020002802002205200341016a22033b010420052009360200200041046a210020032001490d000c060b0b200941086a2203200741016a220a4103746a200320074103746a220320092f0106220520076b2213410374109e081a20032004370000200941e0006a2007410c6c6a2203410c6a20032013410c6c109e081a200341086a200f280200360200200320022903283702002009200541016a22033b010620074102742217200941e4016a22056a41086a2005200a4102746a2213200341ffff03712205200a6b410274109e081a20132008360200200020054f0d00200920176a41e8016a2103034020032802002200200741016a22073b010420002009360200200341046a210320052007470d000b0b200241106a41086a200e280200220336020020112003360200200220022903382204370310200220043703000240200928020022030d0020012108200b21040c030b20092f0104211320032109200b21042001210820122100201221030c000b0b41d684cc00413541c086cc00103f000b200241d0026a410272410041da00109f081a200241f0016a200241d0026a41dc00109d081a200241386a410041b401109f081a41940210332203450d0120034100360200200341046a200241f0016a41dc00109d081a200341e0006a200241386a41b401109d0821052003200628020022003602e4012006200336020020062006280204220141016a360204200041003b010420002003360200200241386a41086a200241086a2802003602002002200229030037033820012012470d0220032f01062200410a4b0d0320052000410c6c6a22052002290338370200200320004103746a41086a2004370000200541086a200241386a41086a2802003602002003200041016a22004102746a41e4016a2008360200200320003b0106200820003b0104200820033602000b200241b0036a24000f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000bfa20021b7f017e23004180076b22042400200441e0006a41186a200241186a290000370300200441e0006a41106a200241106a290000370300200441e0006a41086a200241086a290000370300200420022900003703600240024002400240024020012802002205450d00200128020421060c010b41002106200441e8026a410041e002109f081a200441c0016a4100418401109f081a41ec0310332205450d01200541003b010620054100360200200541086a200441e8026a41e002109d081a200541e8026a200441c0016a418401109d081a20014100360204200120053602000b200420013602c801200420053602c401200420063602c00102400240024002400340200541086a2107200541066a210820052f0106220941057421024100210a024002400240024003402002450d010240200441e0006a2007412010a008220b0d00410021022006210c0c030b200241606a2102200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21090b20060d01410121024100210c2009210a0b200441e8026a41106a200a360200200441e8026a410c6a2001360200200441e8026a41086a22072005360200200420013602c801200420053602c401200420063602c0012004200c3602ec02200420023602e80202402002450d00200441086a41186a2207200441e0006a41186a2202290300370300200441086a41106a220b200441e0006a41106a2206290300370300200441086a41086a2209200441e0006a41086a220d290300370300200420042903603703082001200128020841016a360208200220072903003703002006200b290300370300200d200929030037030020042004290308370360200441d8026a41086a200341086a280200360200200420032902003703d80220082f0100220b410b490d02200441e8026a410041e002109f081a200441c0016a4100418401109f081a41ec0310332203450d08200341003b010620034100360200200341086a200441e8026a41e002109d082107200341e8026a200441c0016a418401109d08210b200441e8026a41086a2206200541b8036a2802003602002004200541db016a2900003703a8012004200541e0016a2900003700ad01200420052902b0033703e8022004200541c8016a2f00003b01bc012004200541ca016a2d00003a00be01200541cb016a280000210e200541cf016a280000210f200541d3016a2800002110200541d7016a28000021112007200541e8016a20052f010641796a2202410574109d082107200b200541bc036a2002410c6c109d08210b200541063b0106200320023b0106200420042f01bc013b01a401200420042d00be013a00a601200420042903a8013703c001200420042900ad013700c501200441286a41086a2006280200360200200420042903e80237032802400240200a4107490d00200a41057420076a41c07e6a2007200a41796a22064105746a2207200241ffff037120066b410574109e081a200741186a200441e0006a41186a290300370000200741106a200441e0006a41106a290300370000200741086a200441e0006a41086a29030037000020072004290360370000200a410c6c200b6a220241b87f6a200241ac7f6a2202200341066a22082f010020066b410c6c109e081a200241086a200441d8026a41086a280200360200200220042903d8023702000c010b200541086a200a4105746a220241206a200220082f0100200a6b410574109e081a200241186a200441e0006a41186a290300370000200241106a200441e0006a41106a290300370000200241086a200441e0006a41086a29030037000020022004290360370000200541e8026a200a410c6c6a2202410c6a200220082f0100200a6b410c6c109e081a200241086a200441d8026a41086a280200360200200220042903d8023702000b200820082f010041016a3b010020044198016a41026a220220042d00a6013a0000200441c8026a41086a2212200441286a41086a280200360200200420042f01a4013b019801200420042903c001370350200420042900c501370055200420042903283703c8022004413c6a41026a221320022d00003a0000200420042f0198013b013c2004200429005537002d20042004290350370328200441c0006a41086a22142012280200360200200420042903c8023703400240200528020022060d00410021020c060b20052f01042108200441e8026a410272211541002102034020044194016a41026a221620132d00003a0000200420042f013c3b019401200420042903283703602004200429002d37006520044198016a41086a221720142802003602002004200429034037039801200c2002470d05200841ffff0371210502400240024020062f01062202410b490d0020154100419604109f081a419c041033220b450d0c200b4100360200200b41046a200441e8026a419804109d081a2004200641c8016a2f00003b01bc012004200641ca016a2d00003a00be012004200641db016a2900003703a8012004200641e0016a2900003700ad01200641cb016a2800002118200641cf016a2800002119200641d3016a280000211a200641d7016a280000211b200441e8026a41086a221c200641b8036a280200360200200420062902b0033703e802200b41086a200641e8016a20062f0106220741796a2202410574109d08211d200b41e8026a200641bc036a2002410c6c109d08211e200b41ec036a20064188046a2007417a6a2209410274109d08210d200641063b0106200b20023b010602402009450d0041002102200d210703402007280200220a20023b0104200a200b360200200741046a21072009200241016a2202470d000b0b200441d8026a41086a2202201c280200360200200420042d00be0122073a00a601200420042f01bc01220a3b01a401200420042903a8013703c001200420042900ad013700c501200420042903e8023703d802200441c4026a41026a220920073a00002004200a3b01c402200420042903c0013703e802200420042900c5013700ed0220122002280200360200200420042903d8023703c802200841ffff037122074107490d01201d2005417a6a220a4105746a201d200541796a22024105746a2207200b2f010620026b410574109e081a200741186a20042900653700002007201136000f2007201036000b2007200f3600072007200e360003200741026a20162d00003a0000200720042f0194013b0000200720042903603700132005410c6c201e6a220741b87f6a200741ac7f6a2207200b2f0106220820026b410c6c109e081a200741086a20172802003602002007200429039801370200200b200841016a22073b01062005410274220e200d6a416c6a200d200a4102746a2208200741ffff03712205200a6b410274109e081a200820033602002005200a490d02200b200e6a41d4036a210703402007280200220a200241016a22023b0104200a200b360200200741046a210720022005490d000c030b0b200641086a2207200541016a220a4105746a200720054105746a2207200220056b410574109e081a200741186a20042900653700002007201136000f2007201036000b2007200f3600072007200e360003200741026a20044194016a41026a2d00003a0000200720042f0194013b00002007200429036037001320062005410c6c6a220241f4026a200241e8026a220720062f0106220b20056b410c6c109e081a200241f0026a20044198016a41086a28020036020020072004290398013702002006200b41016a22023b01062005410274200641ec036a22076a41086a2007200a4102746a2207200241ffff0371220b200a6b410274109e081a20072003360200200841ffff0371200b4f0d092006200a417f6a22024102746a41f0036a210703402007280200220a200241016a22023b0104200a2006360200200741046a21072002200b490d000c0a0b0b200641086a2202200541016a22084105746a200220054105746a220220062f010620056b410574109e081a200241186a20042900653700002002201136000f2002201036000b2002200f3600072002200e360003200241026a20162d00003a0000200220042f0194013b000020022004290360370013200641e8026a2005410c6c6a2202410c6a200220062f0106220a20056b410c6c109e081a200241086a201728020036020020022004290398013702002006200a41016a22023b01062005410274220e200641ec036a220a6a41086a200a20084102746a220d200241ffff0371220a20086b410274109e081a200d20033602002007200a4f0d002006200e6a41f0036a2102034020022802002207200541016a22053b010420072006360200200241046a2102200a2005470d000b0b200c41016a210220044190016a41026a220720092d00003a000020044180016a41086a220a2012280200360200200420042f01c40222053b019001200420042903e802370350200420042900ed02370055200420042903c80237038001201320072d00003a0000200420053b013c2004200429005537002d200420042903503703282014200a28020036020020042004290380013703400240200628020022070d002018210e201b2111201a21102019210f200b21030c070b20062f010421082018210e201b2111201a21102019210f20072106200b21032002210c0c000b0b20072005200a410c6c6a220241f0026a220a2802003602002004200241e8026a22022902003703e80220022003290200370200200a200341086a280200360200200441c0016a41086a20072802002202360200200420042903e802221f3703c0012000410c6a20023602002000201f370204200041013602000c060b2006417f6a2106200520094102746a41ec036a28020021050c010b0b2005200a4105746a220741286a200741086a2206200b200a6b410574109e081a200741206a2002290300370000200741186a200441e0006a41106a290300370000200741106a200441e0006a41086a290300370000200620042903603700002005200a410c6c6a220241f4026a200241e8026a220720052f0106200a6b410c6c109e081a200241f0026a200441d8026a41086a280200360200200720042903d802370200200520052f010641016a3b01060c020b41d684cc00413541c086cc00103f000b200441e8026a4102724100419604109f081a419c0410332207450d0220074100360200200741046a200441e8026a419804109d081a20072001280200220a3602ec032001200736020020012001280204220b41016a360204200a41003b0104200a2007360200200441e0006a41026a2004413c6a41026a2d00003a0000200420042f013c3b0160200420042903283703e8022004200429002d3700ed02200441c0016a41086a200441c0006a41086a280200360200200420042903403703c001200b2002470d0320072f0106220a410a4b0d042007200a4105746a2202410a6a200441e0006a41026a2d00003a0000200241086a20042f01603b0000200241176a2011360000200241136a20103600002002410f6a200f3600002002410b6a200e3600002002411b6a20042903e802370000200241206a20042900ed023700002007200a410c6c6a220241f0026a200441c0016a41086a280200360200200241e8026a20042903c0013702002007200a41016a22024102746a41ec036a2003360200200720023b0106200320023b0104200320073602000b200041003602000b20044180076a24000f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000bf70c01087f230041c0046b22032400200341206a41186a200141186a290000370300200341206a41106a200141106a290000370300200341206a41086a200141086a290000370300200320012900003703200240024002400240024020002802002204450d00200028020421050c010b4100210520034180016a410041e002109f081a200341f8006a22014100360200200341f0006a22064200370300200341d0006a41186a4200370300200341d0006a41106a4200370300200341d0006a41086a42003703002003420037035041940310332204450d01200441003b010620044100360200200441086a20034180016a41e002109d081a20044190036a200128020036020020044188036a200629030037020020044180036a200341e8006a290300370200200441f8026a200341e0006a290300370200200441f0026a200341d0006a41086a290300370200200420032903503702e80220004100360204200020043602000b2003200036025820032004360254200320053602500240034020042f01062207410574210841002101410021060240024002400240034020082001460d010240200341206a200420016a41086a412010a00822090d0041002101200521090c030b200141206a2101200641016a21062009417f4a0d000b2006417f6a21070b20050d014101210141002109200721060b20034180016a41106a20063602002003418c016a200036020020034180016a41086a20043602002003200036025820032004360254200320053602502003200936028401200320013602800102402001450d00200341186a2201200341206a41186a2207290300370300200341106a2208200341206a41106a290300370300200341086a2205200341206a41086a290300370300200320032903203703002000200028020841016a3602082003200636024c200320003602482003200436024420032009360240200341d0006a41186a2001290300370300200341d0006a41106a2008290300370300200341d0006a41086a20052903003703002003200329030037035020034180016a200341c0006a200341d0006a200210fe0220032d0080014101470d04200341206a41086a220520034189016a290000370300200341206a41106a220020034191016a290000370300200720034199016a2900003703002003200329008101370320200341ac016a2802002106200341b8016a2802002108200341b4016a2802002109200341b0016a2802002104200341a8016a28020022012802002207450d0220012f01042102200341a4016a280200210a20034180016a410172210103402003200241ffff037136024c20032006360248200320073602442003200a41016a360240200341d0006a41186a200341206a41186a2206290300370300200341d0006a41106a2000290300370300200341d0006a41086a20052903003703002003200329032037035020034180016a200341c0006a200341d0006a20042009200810ff0220032d0080014101470d052005200141086a2900003703002000200141106a2900003703002006200141186a2900003703002003200129000037032020032802ac01210620032802b801210820032802b401210920032802b001210420032802a80122022802002207450d0320022f0104210220032802a401210a0c000b0b200420064102746a41e8026a20023602000c030b2005417f6a2105200420074102746a4194036a28020021040c010b0b20034180016a410272410041be03109f081a41c40310332201450d0120014100360200200141046a20034180016a41c003109d081a200120062802002205360294032006200136020020062006280204220041016a360204200541003b01042005200136020020034180016a41186a200341206a41186a29030037030020034180016a41106a200341206a41106a29030037030020034180016a41086a200341206a41086a290300370300200320032903203703800120002008470d0220012f01062206410a4b0d03200120064105746a220841206a20034180016a41186a290300370000200841186a20034180016a41106a290300370000200841106a20034180016a41086a290300370000200841086a200329038001370000200120064102746a41e8026a20043602002001200641016a22064102746a4194036a2009360200200120063b0106200920063b0104200920013602000b200341c0046a24000f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b920c02057f027e230041d0006b220224000240024002400240024002402001280200417f6a220341034b0d0020030e0401020304010b41cfa2cc00412841c086cc00103f000b410121030240024020012d00044101470d00200141086a28020021040c010b2002410a6a200141046a220341036a2d00003a0000200241306a41086a200141146a290200370300200241c0006a2001411c6a290200370300200241c8006a200141246a2d00003a0000200220032f00013b010820022001410c6a290200370330200141086a2802002104410021030b200020033a0004200020022f01083b000520004101360200200041286a2001290328370300200041086a20043602002000410c6a2002290330370200200041306a200141306a290300370300200041076a2002410a6a2d00003a0000200041146a200241306a41086a2903003702002000411c6a200241c0006a290300370200200041246a200241c8006a2802003602000c030b410121030240024020012d00044101470d00200141086a28020021040c010b2002410a6a200141046a220341036a2d00003a0000200241306a41086a200141146a290200370300200241c0006a2001411c6a290200370300200241c8006a200141246a2d00003a0000200220032f00013b010820022001410c6a290200370330200141086a2802002104410021030b200020033a0004200020022f01083b0005200041286a2001290328370300200041386a2001290338370300200041086a20043602002000410c6a2002290330370200200041306a200141306a290300370300200041c0006a200141c0006a290300370300200041076a200241086a41026a2d00003a0000200041146a200241306a41086a2903003702002000411c6a200241c0006a290300370200200041246a200241c8006a280200360200200041023602000c020b200141286a2103410121040240024020012d00044101470d00200141086a28020021050c010b2002412a6a200141046a220441036a2d00003a0000200241086a41086a200141146a290200370300200241186a2001411c6a290200370300200241206a200141246a2d00003a0000200220042f00013b012820022001410c6a290200370308200141086a2802002105410021040b410121060240024020032d00004101470d002001412c6a28020021030c010b2002412e6a200341036a2d00003a0000200241386a200141386a290200370300200241c0006a200141c0006a290200370300200241c8006a200141c8006a2d00003a0000200220032f00013b012c2002200141306a2902003703302001412c6a2802002103410021060b200020043a0004200020022f01283b0005200020022f012c3b0029200041086a20053602002000410c6a2002290308370200200041286a20063a0000200041076a200241286a41026a2d00003a0000200041146a200241086a41086a2903003702002000411c6a200241086a41106a290300370200200041246a200241086a41186a2802003602002000412b6a2002412c6a41026a2d00003a0000200141d8006a2903002107200129035021082000412c6a2003360200200041d0006a2008370300200041d8006a200737030020004103360200200041306a2002290330370200200041386a200241306a41086a290300370200200041c0006a200241306a41106a290300370200200041c8006a200241306a41186a2802003602000c010b410121030240024020012d00044101470d00200141086a28020021040c010b2002410a6a200141046a220341036a2d00003a0000200241306a41086a200141146a290200370300200241c0006a2001411c6a290200370300200241c8006a200141246a2d00003a0000200220032f00013b010820022001410c6a290200370330200141086a2802002104410021030b200020033a0004200020022f01083b000520004104360200200041286a2001290328370300200041086a20043602002000410c6a2002290330370200200041306a200141306a290300370300200041076a2002410a6a2d00003a0000200041146a200241306a41086a2903003702002000411c6a200241c0006a290300370200200041246a200241c8006a2802003602000b200241d0006a24000bbe0702097f017e230041306b2202240002400240024002400240024002400240024002402001280200417f6a220341054b0d0020030e06010203040506010b41cfa2cc00412841c086cc00103f000b2001410c6a280200220441ffffff3f712004470d0620044105742205417f4c0d06200128020421060240024020050d00410121070c010b200510332207450d080b41002103200241003602182002200736021020022005410576360214200241106a41002004108a012002280218210802402004450d0020044105742109200228021020084105746a210a0340200a20036a2205200620036a2207290000370000200541186a200741186a290000370000200541106a200741106a290000370000200541086a200741086a2900003700002009200341206a2203470d000b200441057441606a41057620086a41016a21080b200241086a200836020020022002290310220b3703002000200b3702042000410c6a200836020020004101360200200041186a200141186a290300370300200041106a20012903103703000c050b200041023602000c040b410121030240024020012d00044101470d00200141086a28020021050c010b200241026a200141046a220341036a2d00003a0000200241106a41086a200141146a290200370300200241206a2001411c6a290200370300200241286a200141246a2d00003a0000200220032f00013b010020022001410c6a290200370310200141086a2802002105410021030b200020033a0004200020022f01003b000520004103360200200041086a20053602002000410c6a2002290310370200200041076a200241026a2d00003a0000200041146a200241106a41086a2903003702002000411c6a200241206a290300370200200041246a200241286a2802003602000c030b200041043602000c020b200041053602000c010b410121030240024020012d00044101470d00200141086a28020021050c010b200241026a200141046a220341036a2d00003a0000200241106a41086a200141146a290200370300200241206a2001411c6a290200370300200241286a200141246a2d00003a0000200220032f00013b010020022001410c6a290200370310200141086a2802002105410021030b200020033a0004200020022f01003b000520004106360200200041086a20053602002000410c6a2002290310370200200041076a200241026a2d00003a0000200041146a200241106a41086a2903003702002000411c6a200241206a290300370200200041246a200241286a2802003602000b200241306a24000f0b1044000b1045000bf64006017f027e117f0e7e027f017e230041d0066b220324000240024002400240024002400240024002400240024020012802000e050001020304000b200341ac056a41013602002003420137029c05200341e8d4ca00360298052003410436029c042003419cd5ca0036029804200320034198046a3602a80520034198056a41b0b4cc00104c000b200141306a2903002104200141286a2903002105200341b8046a200141246a28020036020020034198046a41186a2001411c6a29020037030020034198046a41106a200141146a29020037030020034198046a41086a2001410c6a2902003703002003200129020437039804410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703f802200320013a00f702200320063a00f602200320073b01f402200320083a00f302200320093a00f2022003200a3b01f0022003200b3a00ef022003200c3a00ee022003200d3b01ec022003200e3a00eb022003200f3a00ea02200320103b01e802200320113a00e702200320123a00e602200320133b01e402200320143a00e302200320153a00e202200320163b01e00220034198056a41206a20034198046a41206a28020036020020034198056a41186a20034198046a41186a29030037030020034198056a41106a20034198046a41106a29030037030020034198056a41086a20034198046a41086a29030037030020032003290398043703980520034198036a20034198056a108b02200341a0066a41086a2201200341a1036a290000370300200341a0066a41106a2202200341a9036a290000370300200341a0066a41186a2206200341b1036a29000037030020032003290099033703a006024020032d0098034101460d00200341d8016a41186a2006290300370300200341d8016a41106a2002290300370300200341d8016a41086a2001290300370300200320032903a0063703d80120034198056a200341e0026a200341d8016a20052004410110e60220032d00980522014104460d0a20032f00990520032d009b05411074722102200329029c0521040c020b410121010b0b200042003703082000411c6a2004370200200041186a20024108742001723602000c050b200141c0006a2903002117200141386a2903002118200141306a2903002104200141286a290300210520034180016a41206a2206200141246a28020036020020034180016a41186a22072001411c6a29020037030020034180016a41106a2208200141146a29020037030020034180016a41086a22092001410c6a29020037030020032001290204370380014102210120022d000120022d0000410047720d0320034198056a41206a200628020036020020034198056a41186a200729030037030020034198056a41106a200829030037030020034198056a41086a200929030037030020032003290380013703980520034198046a20034198056a108b02200341a0066a41086a200341a1046a290000370300200341a0066a41106a200341a9046a290000370300200341a0066a41186a200341b1046a29000037030020032003290099043703a0064101210120032d0098044101460d03200341a8016a41186a200341a0066a41186a290300370300200341a8016a41106a200341a0066a41106a290300370300200341a8016a41086a200341a0066a41086a290300370300200320032903a0063703a801200341c8016a200341a8016a108e02200341d8016a20032802c801220820032802d0012209108f0220032903d8012119200342003703d80142002004201820057c221a428080e983b1de16544100201720047c201a201854ad7c501b22011b21044200200520011b2105200341a0026a280200210a20032d00a402210b0240024020194201510d00200341a8026a41306a4200370300200341a8026a41286a4200370300200341a8026a41206a4200370300200341a8026a41186a4200370300200341a8026a41106a4200370300200341a8026a41086a4200370300200342003703a8024200211b4200211c4200211d4200211a4200211e0c010b20034190026a290300211f200341d8016a41306a2903002120200341d8016a41206a290300211c200341d8016a41186a290300211b20034198026a290300211e20032903e801211a20032903e001211d200341a8026a41206a200341d8016a41286a290300370300200341a8026a41286a2020370300200341a8026a41306a201f370300200341a8026a41106a201b3703002003201c3703c0022003201d3703a8022003201a3703b0020b4200201720011b21174200201820011b2118201d201b7c2220201d5421062005201d562004201a562004201a5122011b0d022005201d542004201a5420011b450d052003201d20057d3703e0022003201a20047d201d200554ad7d3703e8022003200341e0026a36029c0620034198056a41186a220d420037030020034198056a41106a2207420037030020034198056a41086a22024200370300200342003703980541b6fdc600ad4280808080800184221f1001220c290000211d200341c0066a41086a2201200c41086a2900003703002003201d3703c006200c103520022001290300370300200320032903c0063703980541e489c200ad4280808080d0018422211001220c290000211d2001200c41086a2900003703002003201d3703c006200c1035200720032903c006221d370300200341a0066a41086a220e2002290300370300200341a0066a41106a220f201d370300200341a0066a41186a2210200129030037030020032003290398053703a006200341e8006a200341a0066a412010d701200341e8006a41106a2903002122200329037021232003280268210c20032903e802212420032903e002211d200d420037030020074200370300200242003703002003420037039805201f1001220d290000211f2001200d41086a2900003703002003201f3703c006200d103520022001290300370300200320032903c0063703980520211001220d290000211f2001200d41086a2900003703002003201f3703c006200d1035200720032903c006221f370300200e2002290300370300200f201f3703002010200129030037030020032003290398053703a0062003420020224200200c1b221f20247d20234200200c1b2221201d54ad7d22222021201d7d221d2021562022201f562022201f511b22011b3703a00520034200201d20011b37039805200341a0066aad428080808080048420034198056aad428080808080028410020c050b200141d8006a2903002104200141d0006a290300210520034198036a41206a2206200141246a28020036020020034198036a41186a22072001411c6a29020037030020034198036a41106a2208200141146a29020037030020034198036a41086a22092001410c6a290200370300200320012902043703980320034198046a41206a200141c8006a28020036020020034198046a41186a200141c0006a29020037030020034198046a41106a200141386a29020037030020034198046a41086a200141306a2902003703002003200141286a29020037039804410221010240024020022d000120022d0000410047720d0020034198056a41206a200628020036020020034198056a41186a200729030037030020034198056a41106a200829030037030020034198056a41086a2009290300370300200320032903980337039805200341d8016a20034198056a108b024101210120032d00d8014101460d00200341d8016a41086a2d00002101200341e1016a22022f00002106200341e3016a2d00002107200341d8016a410c6a2d00002108200341e5016a2f00002109200341e7016a2d0000210a200341d8016a41106a2d0000210b200341e9016a220c2f0000210d200341eb016a2d0000210e200341d8016a41146a2d0000210f200341ed016a2f00002110200341ef016a2d00002111200341d8016a41186a2d0000211220032f00d901211320032d00db01211420032d00dc01211520032f00dd01211620032d00df0121252003200341f1016a22262900003703c002200320123a00bf02200320113a00be02200320103b01bc022003200f3a00bb022003200e3a00ba022003200d3b01b8022003200b3a00b7022003200a3a00b602200320093b01b402200320083a00b302200320073a00b202200320063b01b002200320013a00af02200320253a00ae02200320163b01ac02200320153a00ab02200320143a00aa02200320133b01a80220034198056a41206a20034198046a41206a28020036020020034198056a41186a20034198046a41186a29030037030020034198056a41106a20034198046a41106a29030037030020034198056a41086a20034198046a41086a290300370300200320032903980437039805200341d8016a20034198056a108b02200341a0066a41086a22012002290000370300200341a0066a41106a2202200c290000370300200341a0066a41186a22062026290000370300200320032900d9013703a006024020032d00d8014101460d00200341e0026a41186a2006290300370300200341e0026a41106a2002290300370300200341e0026a41086a2001290300370300200320032903a0063703e00220034198056a200341a8026a200341e0026a20052004410110e60220032d00980522014104460d0820032f00990520032d009b05411074722102200329029c0521040c020b410121010b0b200042003703082000411c6a2004370200200041186a20024108742001723602000c030b200141306a2903002104200141286a2903002105200341b8046a200141246a28020036020020034198046a41186a2001411c6a29020037030020034198046a41106a200141146a29020037030020034198046a41086a2001410c6a2902003703002003200129020437039804410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703f802200320013a00f702200320063a00f602200320073b01f402200320083a00f302200320093a00f2022003200a3b01f0022003200b3a00ef022003200c3a00ee022003200d3b01ec022003200e3a00eb022003200f3a00ea02200320103b01e802200320113a00e702200320123a00e602200320133b01e402200320143a00e302200320153a00e202200320163b01e00220034198056a41206a20034198046a41206a28020036020020034198056a41186a20034198046a41186a29030037030020034198056a41106a20034198046a41106a29030037030020034198056a41086a20034198046a41086a29030037030020032003290398043703980520034198036a20034198056a108b02200341a0066a41086a2201200341a1036a290000370300200341a0066a41106a2202200341a9036a290000370300200341a0066a41186a2206200341b1036a29000037030020032003290099033703a006024020032d0098034101460d00200341d8016a41186a2006290300370300200341d8016a41106a2002290300370300200341d8016a41086a2001290300370300200320032903a0063703d80120034198056a200341e0026a200341d8016a20052004410010e60220032d00980522014104460d0720032f00990520032d009b05411074722102200329029c0521040c020b410121010b0b200042003703082000411c6a2004370200200041186a20024108742001723602000c020b20032005201d7d3703e00220032004201a7d2005201d54ad7d3703e8022003200341e0026a36029c0620034198056a41186a220d420037030020034198056a41106a2207420037030020034198056a41086a22024200370300200342003703980541b6fdc600ad4280808080800184221d1001220c290000211f200341c0066a41086a2201200c41086a2900003703002003201f3703c006200c103520022001290300370300200320032903c0063703980541e489c200ad4280808080d00184221f1001220c29000021212001200c41086a290000370300200320213703c006200c1035200720032903c0062221370300200341a0066a41086a220e2002290300370300200341a0066a41106a220f2021370300200341a0066a41186a2210200129030037030020032003290398053703a006200341d0006a200341a0066a412010d701200341d0006a41106a2903002121200329035821222003280250210c20032903e802212320032903e0022124200d420037030020074200370300200242003703002003420037039805201d1001220d290000211d2001200d41086a2900003703002003201d3703c006200d103520022001290300370300200320032903c00637039805201f1001220d290000211d2001200d41086a2900003703002003201d3703c006200d1035200720032903c006221d370300200e2002290300370300200f201d3703002010200129030037030020032003290398053703a0062003427f202320214200200c1b221d7c202420224200200c1b221f7c2221201f542201ad7c221f2001201f201d54201f201d511b22011b3703a0052003427f202120011b37039805200341a0066aad428080808080048420034198056aad428080808080028410020c020b20004200370308200041186a20013602000b420121040c020b201a201c7c211d2006ad211f200341a8026a41106a2101024002402018201b562017201c562017201c5122021b0d002018201b542017201c5420021b450d012003201b20187d3703e0022003201c20177d201b201854ad7d3703e8022003200341e0026a36029c0620034198056a41186a220e420037030020034198056a41106a220c420037030020034198056a41086a22074200370300200342003703980541b6fdc600ad4280808080800184221b1001220d290000211c200341c0066a41086a2202200d41086a2900003703002003201c3703c006200d103520072002290300370300200320032903c0063703980541e489c200ad4280808080d0018422211001220d290000211c2002200d41086a2900003703002003201c3703c006200d1035200c20032903c006221c370300200341a0066a41086a220f2007290300370300200341a0066a41106a2210201c370300200341a0066a41186a2211200229030037030020032003290398053703a006200341386a200341a0066a412010d701200341386a41106a2903002122200329034021232003280238210d20032903e802212420032903e002211c200e4200370300200c4200370300200742003703002003420037039805201b1001220e290000211b2002200e41086a2900003703002003201b3703c006200e103520072002290300370300200320032903c0063703980520211001220e290000211b2002200e41086a2900003703002003201b3703c006200e1035200c20032903c006221b370300200f20072903003703002010201b3703002011200229030037030020032003290398053703a0062003420020224200200d1b221b20247d20234200200d1b2221201c54ad7d22222021201c7d221c2021562022201b562022201b511b22021b3703a00520034200201c20021b37039805200341a0066aad428080808080048420034198056aad428080808080028410020c010b20032018201b7d3703e00220032017201c7d2018201b54ad7d3703e8022003200341e0026a36029c0620034198056a41186a220e420037030020034198056a41106a220c420037030020034198056a41086a22074200370300200342003703980541b6fdc600ad4280808080800184221c1001220d290000211b200341c0066a41086a2202200d41086a2900003703002003201b3703c006200d103520072002290300370300200320032903c0063703980541e489c200ad4280808080d00184221b1001220d29000021212002200d41086a290000370300200320213703c006200d1035200c20032903c0062221370300200341a0066a41086a220f2007290300370300200341a0066a41106a22102021370300200341a0066a41186a2211200229030037030020032003290398053703a006200341206a200341a0066a412010d701200341206a41106a2903002121200329032821222003280220210d20032903e802212320032903e0022124200e4200370300200c4200370300200742003703002003420037039805201c1001220e290000211c2002200e41086a2900003703002003201c3703c006200e103520072002290300370300200320032903c00637039805201b1001220e290000211c2002200e41086a2900003703002003201c3703c006200e1035200c20032903c006221c370300200f20072903003703002010201c3703002011200229030037030020032003290398053703a0062003427f202320214200200d1b221c7c202420224200200d1b221b7c2221201b542202ad7c221b2002201b201c54201b201c511b22021b3703a0052003427f202120021b37039805200341a0066aad428080808080048420034198056aad428080808080028410020b201d201f7c211d200320053703a802200320173703c002200320183703b802200320043703b002200341e0026a41186a200141086a290300221c370300200341e0026a41206a2202200141106a29030037030020034188036a2207200141186a29030037030020034190036a220c200141206a290300370300200320043703e802200320053703e00220032001290300221b3703f00202400240427f2005201b7c221b201b20055422012004201c7c2001ad7c221c200454201c2004511b22011b221b428080e983b1de16544100427f201c20011b221f501b0d00200341e0026a41106a290300211b200c290300211f200729030021212002290300212220032903e802212320032903e00221244201211c20032903f80221270c010b02400240201b201f8450450d004200211c0c010b4200211c20034198056a41186a220d420037030020034198056a41106a2207420037030020034198056a41086a22024200370300200342003703980541b6fdc600ad428080808080018422211001220c2900002122200341c0066a41086a2201200c41086a290000370300200320223703c006200c103520022001290300370300200320032903c0063703980541e489c200ad4280808080d0018422221001220c29000021232001200c41086a290000370300200320233703c006200c1035200720032903c0062223370300200341a0066a41086a220e2002290300370300200341a0066a41106a220f2023370300200341a0066a41186a2210200129030037030020032003290398053703a006200341086a200341a0066a412010d701200341086a41106a2903002123200329031021242003280208210c200d42003703002007420037030020024200370300200342003703980520211001220d29000021212001200d41086a290000370300200320213703c006200d103520022001290300370300200320032903c0063703980520221001220d29000021212001200d41086a290000370300200320213703c006200d1035200720032903c0062221370300200e2002290300370300200f20213703002010200129030037030020032003290398053703a0062003420020234200200c1b2221201f7d20244200200c1b2222201b54ad7d22232022201b7d2224202256202320215620232021511b22011b3703a00520034200202420011b37039805200341a0066aad428080808080048420034198056aad42808080808002841002200341d0056a201f370300200341c8056a201b370300200241013a0000200341a1056a20032903a801370000200341a9056a200341a8016a41086a290300370000200341b1056a200341a8016a41106a290300370000200341b9056a200341a8016a41186a290300370000200341033a00980541b0b4cc00410020034198056a10d4010b0b201d201a512101201d201a54210220034180026a202237030020034188026a2021370300200341e8016a202337030020034190026a201f370300200341f0016a201b370300200320273703f8012003201e37039802200320243703e0012003200b4100201942015122071b3a00a4022003200a410020071b3602a0022003201c4201512207ad3703d8010240024020070d002009ad4220862008ad8410070c010b2003200936029c052003200836029805200341e0016a20034198056a10e7020b2006200220011b2101024020032802cc01450d00200810350b427f201d20011b211a427f202020011b211d201c420152210102400240024020194201510d0020010d004103210220034198046a21010c010b20194201522001410173720d014104210220034198036a21010b200141086a20023a0000200141096a20032903a801370000200141003a0000200141116a200341a8016a41086a290300370000200141196a200341b8016a290300370000200141216a200341c0016a29030037000041b0b4cc004100200110d4010b0240201d201a8450450d00200341d0056a2004370300200341c8056a200537030020034198056a41086a41003a0000200341a1056a20032903a801370000200341a9056a200341a8016a41086a290300370000200341b1056a200341b8016a290300370000200341b9056a200341c0016a290300370000200341033a00980541b0b4cc00410020034198056a10d4010b200341e0056a2017370300200341d8056a2018370300200341d0056a2004370300200341c8056a200537030020034198056a41086a41033a0000200341a1056a20032903a801370000200341a9056a200341a8016a41086a290300370000200341b1056a200341b8016a290300370000200341b9056a200341c0016a290300370000200341033a00980541b0b4cc00410020034198056a10d4010b42002104200042003703080b20002004370300200341d0066a24000b130020004108360204200041e0e4c2003602000b847c05057f027e107f057e037f230041e0036b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e0700010203040506000b200341d4026a4101360200200342013702c402200341e8d4ca003602c0022003410436028c022003419cd5ca0036028802200320034188026a3602d002200341c0026a41b0b4cc00104c000b200141086a280200210420012802042105410221064100210720022d00000d1920022d00014101470d19200141186a2903002108200141106a29030021092001410c6a2802002101200241196a2d00002106200241186a2d00002107200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211920032002411a6a2901003703b801200320063a00b701200320073a00b6012003200a3b01b4012003200b3a00b3012003200c3a00b2012003200d3b01b0012003200e3a00af012003200f3a00ae01200320103b01ac01200320113a00ab01200320123a00aa01200320133b01a801200320143a00a701200320153a00a601200320163b01a401200320173a00a301200320183a00a201200320193b01a00141a0e4cb00ad428080808080028410012202290000211a2002290008211b2002103541e1b8c800ad4280808080a0018410012202290000211c2002290008211d200210352003201d3701d8022003201c3701d0022003201b3701c8022003201a3701c002200341e8016a200341c0026aad4280808080800484221a100510c201024002400240024020032802e8012202450d0020032802ec0121072003200341f0016a28020036028c022003200236028802200341206a20034188026a10c4012003280220450d01410021060c020b2003420037028c02200341013602880220034188026a108a0321060c020b200328022421060b2007450d00200210350b41a0e4cb00ad428080808080028410012202290000211b2002290008211c200210354189eaca00ad4280808080f0008410012202290000211d2002290008211e200210352003201e3701d8022003201d3701d0022003201c3701c8022003201b3701c002200341e8016a201a100510c201024002400240024020032802e8012202450d0020032802ec01210a2003200341f0016a28020036028c022003200236028802200341186a20034188026a10c4012003280218450d01410021070c020b2003420037028c02200341083602880220034188026a108b0321070c020b200328021c21070b200a450d00200210350b41a0e4cb00ad428080808080028410012202290000211b2002290008211c2002103541c699c200ad428080808090018410012202290000211d2002290008211e200210352003201e3701d8022003201d3701d0022003201c3701c8022003201b3701c002200341e8016a201a100510c201024002400240024020032802e8012202450d0020032802ec01210b2003200341f0016a28020036028c022003200236028802200341106a20034188026a10c4012003280210450d014100210a0c020b2003420037028c02200341083602880220034188026a108b03210a0c020b2003280214210a0b200b450d00200210350b410c21020240200720066a200a6a22060d00418790c2002101410021070c190b0240200120064d0d0041f48fc20021014180800821070c190b0240200141104d0d0041e08fc2002101411421024180800c21070c190b024020010d00418090c2002101410721024180800421070c190b02402009428180e983b1de165441002008501b450d0041d68fc2002101410a21024180801021070c190b200341c0026a200341a0016a10e502200341086a20032802c002220620032802c80241b0b4cc0041004100108a0220032802082102024020032802c402450d00200610350b024020024101460d00200342003703f0012003428080e983b1de163703e8012003200341a0016a3602d0032003200341a0016a3602c8012003200341c8016a3602c8022003200341d0036a3602c4022003200341e8016a3602c00220034188026a200341a0016a200341c0026a108c0302402003280288024101470d0020032d008c024104460d0141c78fc2002101410f21024180801421070c1a0b20034188026a41086a2903004201520d0020034188026a41106a290300211a20032802c8012102200341f8026a20034188026a41186a290300370300200341f0026a201a370300200341c0026a41086a41003a0000200341c9026a2002290000370000200341d1026a200241086a290000370000200341d9026a200241106a290000370000200341e1026a200241186a290000370000200341033a00c00241b0b4cc004100200341c0026a10d4010b20034188026a200341a0016a108e02200341c0026a2003280288022207200328029002108f02200341d0026a290300420020032903c00242015122021b211a20032903c802420020021b211b200341e0026a290300420020021b211c200341d8026a2206290300420020021b211d0240200328028c02450d00200710350b200342f0d0c9abc6add9b1f4003703d003200341d0036a200341a0016a427f201b201d7c221d201d201b542202201a201c7c2002ad7c221b201a54201b201a511b22021b221a2009201a200954427f201b20021b221a200854201a2008511b22021b221b201a200820021b221a411e10900220062001360200200341d4026a20043602002003201a3703c8022003201b3703c002200320053602d00220034188026a200341a0016a10e502200328028802210220032003280290023602ec01200320023602e801200341c0026a200341e8016a108d030240200328028c02450d00200210350b200441ffffff3f71450d17200510350c170b41829a182101024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002104200241146a2d00002105200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703b801200320013a00b701200320063a00b601200320073b01b401200320043a00b301200320053a00b2012003200a3b01b0012003200b3a00af012003200c3a00ae012003200d3b01ac012003200e3a00ab012003200f3a00aa01200320103b01a801200320113a00a701200320123a00a601200320133b01a401200320143a00a301200320153a00a201200320163b01a001200341c0026a200341a0016a10e502200341286a20032802c002220120032802c80241b0b4cc0041004100108a0220032802282102024020032802c402450d00200110350b41839a18210120024101470d00200341c0026a200341a0016a10e50220033502c80242208620032802c0022202ad841007024020032802c402450d00200210350b200342f0d0c9abc6add9b1f4003703d00320034188026a200341a0016a10eb022003280288022113024020032802900222070d00410021070c170b200341c0036a210a4100210120132102410021060340024002400240200a2002460d00200241106a220529000020032903d003510d0020010d01410021010c020b200141016a21010c010b200620016b220420074f0d07200341c0026a41186a220b200220014105746b220441186a220c290300370300200341c0026a41106a220d200441106a220e290300370300200341c0026a41086a220f200441086a2210290300370300200320042903003703c002200241086a2211290300211a2005290300211b200241186a2212290300211c20042002290300370300200c201c370300200e201b3703002010201a3703002012200b2903003703002005200d2903003703002011200f290300370300200220032903c0023703000b200241206a21022007200641016a2206460d160c000b0b20004200370308200041206a410b3602002000411c6a41bc8fc200360200200041186a20013602004201211a0c1a0b200341c0016a200141246a280200360200200341a0016a41186a2001411c6a290200370300200341a0016a41106a200141146a290200370300200341a0016a41086a2001410c6a290200370300200320012902043703a0012002411a6a290100211a200241196a2d00002106200241186a2d00002107200241166a2f01002104200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d0000211741022101200241026a2f0100211841012105024020022d00000d0020022d000141014721050b2003201a3701d802200320063a00d702200320073a00d602200320043b01d4022003200a3a00d3022003200b3a00d2022003200c3b01d0022003200d3a00cf022003200e3a00ce022003200f3b01cc02200320103a00cb02200320113a00ca02200320123b01c802200320133a00c702200320143a00c602200320153b01c402200320163a00c302200320173a00c202200320183b01c0024100210a4100210641002102024020050d00200341c8016a41186a200341c0026a41186a2202290100370300200341c8016a41106a200341c0026a41106a2201290100370300200341c8016a41086a200341c0026a41086a2206290100370300200320032901c0023703c801200341c0026a41206a200341a0016a41206a2802003602002002200341a0016a41186a2903003703002001200341a0016a41106a2903003703002006200341a0016a41086a290300370300200320032903a0013703c00220034188026a200341c0026a108b0241012101410021064100210220032d0088024101460d0020034188026a41086a2d0000210220034191026a2f0000210120034193026a2d0000210620034194026a2d0000210720034195026a2f0000210420034197026a2d0000210520034188026a41106a2d0000210b20034199026a2f0000210c2003419b026a2d0000210d2003419c026a2d0000210e2003419d026a2f0000210f2003419f026a2d0000211020034188026a41186a2d0000211120032f008902211220032d008b02211320032d008c02211420032f008d02211520032d008f0221162003200341a1026a29000037038002200320113a00ff01200320103a00fe012003200f3b01fc012003200e3a00fb012003200d3a00fa012003200c3b01f8012003200b3a00f701200320053a00f601200320043b01f401200320073a00f301200320063a00f201200320013b01f001200320023a00ef01200320163a00ee01200320153b01ec01200320143a00eb01200320133a00ea01200320123b01e8014103210141801a21020240200341c8016a200341e8016a412010a0080d0041b28fc2002104410a21074180801c21060c010b200341c0026a200341c8016a10e502200341e8006a20032802c002220720032802c80241b0b4cc0041004100108a0220032802682106024020032802c402450d00200710350b024020064101460d0041bc8fc2002104410b21074180801821060c010b200341c0026a200341e8016a10e502200341e0006a20032802c002220120032802c80241b0b4cc0041004100108a0220032802602102024020032802c402450d00200110350b02400240024002400240024020024101470d0020034188026a200341e8016a10e502200341c0026a200328028802220120032802900210cc0220032902d402420020032802d00222021b211a2002410120021b210d0240200328028c02450d00200110350b200d201a422088a74105746a210e200341c0026a41106a2105200d210603402006200e460d020240200610e9020d00200641206a2110200341c0026a41186a220b420037030020054200370300200341c0026a41086a220a4200370300200342003703c00241a0e4cb00ad4280808080800284221c10012202290000211b200a200241086a2900003703002003201b3703c0022002103541c699c200ad428080808090018410012202290000211b200341d0036a41086a220c200241086a2900003703002003201b3703d00320021035200520032903d003370000200541086a2211200c29030037000020034188026a41086a2212200a29030037030020034188026a41106a2213200529030037030020034188026a41186a2214200b290300370300200320032903c00237038802200341c0026a20034188026a10a20220032902c402420020032802c00222021b221b422088a741306c2101410021072002410820021b220f2102024003402001450d01024020062002460d0020022006412010a0082104200741016a2107200141506a2101200241306a210220040d010b0b201ba72202450d01200241306c450d01200f10350c010b0240201ba72202450d00200241306c450d00200f10350b200b420037030020054200370300200a4200370300200342003703c002201c10012202290000211b200a200241086a2900003703002003201b3703c0022002103541e1b8c800ad4280808080a0018410012202290000211b200c200241086a2900003703002003201b3703d00320021035200520032903d0033700002011200c2903003700002012200a290300370300201320052903003703002014200b290300370300200320032903c00237038802200341c0026a20034188026a10fe0120032802c0022201410120011b210a4100210202400240024020032902c402420020011b221b422088a7220141014b0d0020010e020201020b03402001410176220720026a22042002200a20044105746a2006412010a0084101481b2102200120076b220141014b0d000b0b200a20024105746a2006412010a0084521020b0240201b42ffffff3f83500d00200a10350b201021062002450d010b0b201a42ffffff3f83500d00200d10350b200342003703d8032003428080e983b1de163703d0032003200341c8016a3602c00320034188026a200341c8016a200341d0036a200341c0036a10a802200341a8026a290300211b20032903a002211a02402003290388024201520d00200329039002211c200341f8026a20034188026a41106a290300370300200341f0026a201c370300200341c0026a41086a41003a0000200341c9026a20032903c801370000200341d1026a200341c8016a41086a290300370000200341d9026a200341c8016a41106a290300370000200341e1026a200341e0016a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b2003201a3703c0032003201b3703c803201a201b844200520d01200341c0026a41186a22044200370300200341c0026a41106a22064200370300200341c0026a41086a22014200370300200342003703c00241b6fdc600ad4280808080800184221a10012207290000211b200341d0036a41086a2202200741086a2900003703002003201b3703d0032007103520012002290300370300200320032903d0033703c00241e489c200ad4280808080d00184221b10012207290000211c2002200741086a2900003703002003201c3703d00320071035200620032903d003221c37030020034188026a41086a2205200129030037030020034188026a41106a220a201c37030020034188026a41186a220b2002290300370300200320032903c00237038802200341306a20034188026a412010d701200341306a41106a290300211c2003290338211d20032802302107200442003703002006420037030020014200370300200342003703c002201a10012204290000211a2002200441086a2900003703002003201a3703d0032004103520012002290300370300200320032903d0033703c002201b10012204290000211a2002200441086a2900003703002003201a3703d00320041035200620032903d003221a37030020052001290300370300200a201a370300200b2002290300370300200320032903c002370388022003201c420020071b3703c8022003201d420020071b3703c00220034188026aad4280808080800484200341c0026aad428080808080028410020c020b0240201a42ffffff3f83500d00200d10350b200341c0026a200341e8016a200341c8016a428080e983b1de164200410010ef0220032802c0024101460d03200341c0026a200341e8016a10e50220033502c80242208620032802c0022202ad841007024020032802c402450d00200210350b200342f0d0c9abc6add9b1f4003703d00320034188026a200341e8016a10eb02200328028802211320032802900222070d02410021070c140b2003201a3703c0032003201b3703c803200341c0026a41186a22044200370300200341c0026a41106a22064200370300200341c0026a41086a22014200370300200342003703c00241b6fdc600ad4280808080800184221c10012207290000211d200341d0036a41086a2202200741086a2900003703002003201d3703d0032007103520012002290300370300200320032903d0033703c00241e489c200ad4280808080d00184221d10012207290000211e2002200741086a2900003703002003201e3703d00320071035200620032903d003221e37030020034188026a41086a2205200129030037030020034188026a41106a220a201e37030020034188026a41186a220b2002290300370300200320032903c00237038802200341c8006a20034188026a412010d701200341c8006a41106a290300211e2003290350210820032802482107200442003703002006420037030020014200370300200342003703c002201c10012204290000211c2002200441086a2900003703002003201c3703d0032004103520012002290300370300200320032903d0033703c002201d10012204290000211c2002200441086a2900003703002003201c3703d00320041035200620032903d003221c37030020052001290300370300200a201c370300200b2002290300370300200320032903c0023703880220034200201e420020071b221c201b7d2008420020071b221b201a54ad7d221d201b201a7d221a201b56201d201c56201d201c511b22021b3703c80220034200201a20021b3703c00220034188026aad4280808080800484200341c0026aad428080808080028410020b200341c0026a200341c8016a10e50220033502c80242208620032802c0022202ad841007024020032802c402450d00200210350b200342f0d0c9abc6add9b1f4003703d00320034188026a200341c8016a10eb02410021142003280288022113410021022003280290022207450d14200341c0036a210a4100210120132102410021060340024002400240200a2002460d00200241106a220529000020032903d003510d0020010d01410021010c020b200141016a21010c010b200620016b220420074f0d09200341c0026a41186a220b200220014105746b220441186a220c290300370300200341c0026a41106a220d200441106a220e290300370300200341c0026a41086a220f200441086a2210290300370300200320042903003703c002200241086a2211290300211a2005290300211b200241186a2212290300211c20042002290300370300200c201c370300200e201b3703002010201a3703002012200b2903003703002005200d2903003703002011200f290300370300200220032903c0023703000b200241206a21022007200641016a2206460d140c000b0b200341c0036a210a4100210120132102410021060340024002400240200a2002460d00200241106a220529000020032903d003510d0020010d01410021010c020b200141016a21010c010b200620016b220420074f0d09200341c0026a41186a220b200220014105746b220441186a220c290300370300200341c0026a41106a220d200441106a220e290300370300200341c0026a41086a220f200441086a2210290300370300200320042903003703c002200241086a2211290300211a2005290300211b200241186a2212290300211c20042002290300370300200c201c370300200e201b3703002010201a3703002012200b2903003703002005200d2903003703002011200f290300370300200220032903c0023703000b200241206a21022007200641016a2206460d110c000b0b20032802c402220541ff017122014104460d16200341cc026a2802002107200341c8026a280200210420054180fe037121022005418080fc077121062005418080807871210a0b20004200370308200041206a20073602002000411c6a2004360200200041186a200a2006722002722001723602004201211a0c190b410221014100210620022d00000d0b20022d00014101470d0b200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002104200241146a2d00002105200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703b801200320013a00b701200320063a00b601200320073b01b401200320043a00b301200320053a00b2012003200a3b01b0012003200b3a00af012003200c3a00ae012003200d3b01ac012003200e3a00ab012003200f3a00aa01200320103b01a801200320113a00a701200320123a00a601200320133b01a401200320143a00a301200320153a00a201200320163b01a001200341c0026a41186a4200370300200341c0026a41106a22054200370300200341c0026a41086a22024200370300200342003703c00241a0e4cb00ad428080808080028410012201290000211a2002200141086a2900003703002003201a3703c0022001103541e1b8c800ad4280808080a0018410012201290000211a200341d0036a41086a2206200141086a2900003703002003201a3703d00320011035200520032903d003221a37030020034188026a41086a200229030037030020034188026a41106a201a37030020034188026a41186a2006290300370300200320032903c00237038802200341c0026a20034188026a10fe0120032802c0022201410120011b21044100210a41002102024020032902c402420020011b221a422088a7220141014b0d004100210b20010e020b0a0b0b03402001410176220620026a22072002200420074105746a200341a0016a412010a0084101481b2102200120066b220141014b0d000c0a0b0b410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002104200241146a2d00002105200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703b801200320013a00b701200320063a00b601200320073b01b401200320043a00b301200320053a00b2012003200a3b01b0012003200b3a00af012003200c3a00ae012003200d3b01ac012003200e3a00ab012003200f3a00aa01200320103b01a801200320113a00a701200320123a00a601200320133b01a401200320143a00a301200320153a00a201200320163b01a001200341c8016a200341a0016a108e030240024002400240024020032d00c801450d00200341c0026a41186a4200370300200341c0026a41106a22044200370300200341c0026a41086a22024200370300200342003703c00241a0e4cb00ad428080808080028410012201290000211a2002200141086a2900003703002003201a3703c0022001103541c699c200ad428080808090018410012201290000211a200341d0036a41086a2206200141086a2900003703002003201a3703d00320011035200420032903d003221a37030020034188026a41086a200229030037030020034188026a41106a201a37030020034188026a41186a2006290300370300200320032903c00237038802200341c0026a20034188026a10a20220032902c402420020032802c00222021b221a422088a7220a41306c2101410021062002410820021b22052102024003402001450d03200341a0016a2002460d01200641016a2106200141506a21012002200341a0016a412010a0082107200241306a210220070d000b20074541016a41017120066a417f6a21060b2005200641306c6a2202200241306a2006417f73200a6a41306c109e081a200342003703f00120034280809aa6eaafe3013703e8012003200341a0016a3602c80120034188026a200341a0016a200341e8016a200341c8016a10f00202402003290388024201520d00200329039002211b200341f8026a20034188026a41106a290300370300200341c0026a41306a201b370300200341c0026a41086a41003a0000200341c9026a20032903a001370000200341d1026a200341a0016a41086a290300370000200341d9026a200341a0016a41106a290300370000200341e1026a200341b8016a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b41a0e4cb00ad428080808080028410012202290000211b2002290008211c2002103541c699c200ad428080808090018410012202290000211d2002290008211e200210352003201e3701d8022003201d3701d0022003201c3701c8022003201b3701c0022003412036028c022003200341c0026a360288022005200a417f6a20034188026a10a902201aa72202450d03200241306c0d020c030b200342003703f00120034280809aa6eaafe3013703e8012003200341a0016a3602d00320034188026a200341a0016a200341e8016a200341d0036a10f00202402003290388024201520d00200329039002211a200341f8026a20034188026a41106a290300370300200341f0026a201a370300200341c0026a41086a41003a0000200341c9026a20032903a001370000200341d1026a200341a0016a41086a290300370000200341d9026a200341a0016a41106a290300370000200341e1026a200341b8016a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b200341cd026a200341a8016a290300370000200341d5026a200341b0016a290300370000200341dd026a200341b8016a290300370000200341033a00c402200341093a00c002200320032903a0013700c50241b0b4cc004100200341c0026a10d4014200211a0c050b200341c0026a41186a22064200370300200341c0026a41106a22074200370300200341c0026a41086a22024200370300200342003703c00241a0e4cb00ad428080808080028410012201290000211b2002200141086a2900003703002003201b3703c0022001103541e1b8c800ad4280808080a0018410012201290000211b200341d0036a41086a220a200141086a2900003703002003201b3703d00320011035200420032903d003370000200441086a200a29030037000020034188026a41086a200229030037030020034188026a41106a200729030037030020034188026a41186a2006290300370300200320032903c00237038802200341c0026a20034188026a10fe0120032802c0022201410120011b2104410021020240024020032902c402420020011b221b422088a7220a41014b0d00200a0e020401040b200a210103402001410176220620026a22072002200420074105746a200341a0016a412010a0084101481b2102200120066b220141014b0d000b0b200420024105746a200341a0016a412010a0080d022002200a4f0d09200420024105746a2201200141206a2002417f73200a6a410574109e081a200342003703f00120034280809aa6eaafe3013703e8012003200341a0016a3602c80120034188026a200341a0016a200341e8016a200341c8016a10f00202402003290388024201520d00200329039002211c200341f8026a20034188026a41106a290300370300200341f0026a201c370300200341c0026a41086a41003a0000200341c9026a20032903a001370000200341d1026a200341a0016a41086a290300370000200341d9026a200341a0016a41106a290300370000200341e1026a200341b8016a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b41a0e4cb00ad428080808080028410012202290000211c2002290008211d2002103541e1b8c800ad4280808080a0018410012202290000211e2002290008210820021035200320083701d8022003201e3701d0022003201d3701c8022003201c3701c0022003412036028c022003200341c0026a360288022004200a417f6a20034188026a1098020240201b42ffffff3f83500d00200410350b201aa72202450d01200241306c450d010b200510350b4200211a0c020b0240201b42ffffff3f83500d00200410350b0240201aa72202450d00200241306c450d00200510350b410321010b200041206a410d3602002000411c6a41e08ec200360200200041186a200141809a30723602004201211a0b200042003703080c170b200341a0016a41206a2207200141246a280200360200200341a0016a41186a22042001411c6a290200370300200341a0016a41106a2205200141146a290200370300200341a0016a41086a220a2001410c6a290200370300200320012902043703a001410021064102210120022d000120022d0000410047720d04200341c0026a41206a2007280200360200200341c0026a41186a2004290300370300200341c0026a41106a2005290300370300200341c0026a41086a200a290300370300200320032903a0013703c00220034188026a200341c0026a108b024101210120032d0088024101460d0420034188026a41086a2d0000210220034191026a2f0000210120034193026a2d0000210620034188026a410c6a2d0000210720034195026a2f0000210420034197026a2d0000210520034188026a41106a2d0000210a20034199026a2f0000210b2003419b026a2d0000210c20034188026a41146a2d0000210d2003419d026a2f0000210e2003419f026a2d0000210f20034188026a41186a2d0000211020032f008902211120032d008b02211220032d008c02211320032f008d02211420032d008f0221152003200341a1026a29000037038002200320103a00ff012003200f3a00fe012003200e3b01fc012003200d3a00fb012003200c3a00fa012003200b3b01f8012003200a3a00f701200320053a00f601200320043b01f401200320073a00f301200320063a00f201200320013b01f001200320023a00ef01200320153a00ee01200320143b01ec01200320133a00eb01200320123a00ea01200320113b01e801200341c0036a200341e8016a108e03024020032d00c0034101460d0020032d00c1032107200342003703d00120034280809aa6eaafe3013703c8012003200341e8016a3602d00320034188026a200341e8016a200341c8016a200341d0036a10a802200341a8026a290300211b20032903a002211a02402003290388024201520d00200329039002211c200341f8026a20034188026a41106a290300370300200341f0026a201c370300200341c0026a41086a41003a0000200341c9026a20032903e801370000200341d1026a200341e8016a41086a290300370000200341d9026a200341e8016a41106a290300370000200341e1026a20034180026a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b2003201a3703d0032003201b3703d80302400240201a201b844200520d00200341c0026a41186a22054200370300200341c0026a41106a22064200370300200341c0026a41086a22014200370300200342003703c00241b6fdc600ad4280808080800184221a10012204290000211b200341c8016a41086a2202200441086a2900003703002003201b3703c8012004103520012002290300370300200320032903c8013703c00241e489c200ad4280808080d00184221b10012204290000211c2002200441086a2900003703002003201c3703c80120041035200620032903c801221c37030020034188026a41086a220a200129030037030020034188026a41106a220b201c37030020034188026a41186a220c2002290300370300200320032903c00237038802200341f0006a20034188026a412010d701200341f0006a41106a290300211c2003290378211d20032802702104200542003703002006420037030020014200370300200342003703c002201a10012205290000211a2002200541086a2900003703002003201a3703c8012005103520012002290300370300200320032903c8013703c002201b10012205290000211a2002200541086a2900003703002003201a3703c80120051035200620032903c801221a370300200a2001290300370300200b201a370300200c2002290300370300200320032903c002370388022003201c420020041b3703c8022003201d420020041b3703c00220034188026aad4280808080800484200341c0026aad428080808080028410020c010b2003201a3703d0032003201b3703d803200341c0026a41186a22054200370300200341c0026a41106a22064200370300200341c0026a41086a22014200370300200342003703c00241b6fdc600ad4280808080800184221c10012204290000211d200341c8016a41086a2202200441086a2900003703002003201d3703c8012004103520012002290300370300200320032903c8013703c00241e489c200ad4280808080d00184221d10012204290000211e2002200441086a2900003703002003201e3703c80120041035200620032903c801221e37030020034188026a41086a220a200129030037030020034188026a41106a220b201e37030020034188026a41186a220c2002290300370300200320032903c0023703880220034188016a20034188026a412010d70120034188016a41106a290300211e20032903900121082003280288012104200542003703002006420037030020014200370300200342003703c002201c10012205290000211c2002200541086a2900003703002003201c3703c8012005103520012002290300370300200320032903c8013703c002201d10012205290000211c2002200541086a2900003703002003201c3703c80120051035200620032903c801221c370300200a2001290300370300200b201c370300200c2002290300370300200320032903c0023703880220034200201e420020041b221c201b7d2008420020041b221b201a54ad7d221d201b201a7d221a201b56201d201c56201d201c511b22021b3703c80220034200201a20021b3703c00220034188026aad4280808080800484200341c0026aad428080808080028410020b200341cd026a200341f0016a290300370000200341d5026a200341f8016a290300370000200341dd026a20034180026a290300370000200341023a00c402200341093a00c002200320032903e8013700c50241b0b4cc004100200341c0026a10d4010240200741ff01710d0010a1020b4200211a0c070b4200211a20032802c403220141ff01714104460d06200141807e712106200341c8036a290300211a0c050b2004200741f485cc001042000b2004200741f485cc001042000b2004200741f485cc001042000b2002200a104e000b0b2000411c6a201a370200200041186a2006200141ff0171723602004201211a0b200042003703080c0f0b0240200420024105746a200341a0016a412010a00822010d004101210a2002210b0c010b2001411f7620026a210b0b0240201a42ffffff3f83500d00200410350b02400240200a450d00419f8fc2002102411321074180802021060c010b410c21070240200341a0016a10e902450d0041938fc20021024180802421060c010b200341c0026a41186a22064200370300200341c0026a41106a22044200370300200341c0026a41086a22024200370300200342003703c00241a0e4cb00ad428080808080028410012201290000211a2002200141086a2900003703002003201a3703c0022001103541c699c200ad428080808090018410012201290000211a200341d0036a41086a220a200141086a2900003703002003201a3703d00320011035200520032903d003370000200541086a200a29030037000020034188026a41086a200229030037030020034188026a41106a200429030037030020034188026a41186a2006290300370300200320032903c00237038802200341c0026a20034188026a10a20220032902c402420020032802c00222021b221a422088a741306c2101410021062002410820021b220a2102024003402001450d010240200341a0016a2002460d00200641016a2106200141506a21012002200341a0016a412010a0082104200241306a210220040d010b0b41878fc2002102418080282106201aa72201450d01200141306c450d01200a10350c010b0240201aa72202450d00200241306c450d00200a10350b200342003703f00120034280809aa6eaafe3013703e8012003200341a0016a3602d0032003200341a0016a3602c8012003200341c8016a3602c8022003200341d0036a3602c4022003200341e8016a3602c00220034188026a200341a0016a200341c0026a108c03024002402003280288024101470d0020032d008c024104460d0141ed8ec2002102411a21074180802c21060c020b20034188026a41086a2903004201520d0020034188026a41106a290300211a20032802c8012102200341f8026a20034188026a41186a290300370300200341f0026a201a370300200341c0026a41086a41003a0000200341c9026a2002290000370000200341d1026a200241086a290000370000200341d9026a200241106a290000370000200341e1026a200241186a290000370000200341033a00c00241b0b4cc004100200341c0026a10d4010b20032903b801211a20032d00b701210420032d00b601210a20032f01b401210c20032d00b301210d20032d00b201210e20032f01b001210f20032d00af01211020032d00ae01211120032f01ac01211220032d00ab01211320032d00aa01211420032f01a801211520032d00a701211620032d00a601211720032f01a401211820032d00a301211920032d00a201211f20032f01a0012120200341c0026a41186a22064200370300200341c0026a41106a22074200370300200341c0026a41086a22024200370300200342003703c00241a0e4cb00ad428080808080028410012201290000211b2002200141086a2900003703002003201b3703c0022001103541e1b8c800ad4280808080a0018410012201290000211b200341d0036a41086a2221200141086a2900003703002003201b3703d00320011035200520032903d003370000200541086a202129030037000020034188026a41086a200229030037030020034188026a41106a200729030037030020034188026a41186a2006290300370300200320032903c00237038802200341c0026a20034188026a10fe010240024020032802c00222010d00410021072003410036029002200342013703880241012101410021060c010b200320032902c402221b37028c022003200136028802201b422088a72106201ba721070b02402006200b490d00024020062007470d0020034188026a20074101108a01200328028c02210720032802880221010b2001200b4105746a220241206a20022006200b6b410574109e081a2002201a370018200220043a00172002200a3a00162002200c3b00142002200d3a00132002200e3a00122002200f3b0010200220103a000f200220113a000e200220123b000c200220133a000b200220143a000a200220153b0008200220163a0007200220173a0006200220183b0004200220193a00032002201f3a0002200220203b00002003200641016a22063602900241a0e4cb00ad428080808080028410012202290000211a2002290008211b2002103541e1b8c800ad4280808080a0018410012202290000211c2002290008211d200210352003201d3701d8022003201c3701d0022003201b3701c8022003201a3701c002024020010d00200341c0026aad428080808080048410070c0c0b200341203602ec012003200341c0026a3602e80120012006200341e8016a109802200741ffffff3f71450d0b200110350c0b0b200b2006104d000b410321010c010b0b20004200370308200041206a20073602002000411c6a2002360200200041186a20064180803c7120017241801a723602004201211a0c0b0b2001417f6a20074f0d002003200720016b2207360290020b200341e8016a2013200710ec0241012114200328028c0241ffffff3f71450d02201310350c020b02402001417f6a2007490d00200721020c010b2003200720016b2202360290020b200341c8016a2013200210ec02200328028c0241ffffff3f71450d00201310350b200341cd026a200341e8016a41086a290300370000200341d5026a200341e8016a41106a290300370000200341dd026a200341e8016a41186a290300370000200341e5026a20032903c801370000200341ed026a200341c8016a41086a290300370000200341f5026a200341c8016a41106a290300370000200341fd026a200341c8016a41186a290300370000200341043a00c402200341093a00c002200320032903e8013700c50220034185036a20143a000041b0b4cc004100200341c0026a10d4010c020b2001417f6a20074f0d002003200720016b2207360290020b200341a0016a2013200710ec020240200328028c0241ffffff3f71450d00201310350b4200211a200342003703f0012003428080e983b1de163703e8012003200341a0016a3602c80120034188026a200341a0016a200341e8016a200341c8016a10f00202402003290388024201520d00200329039002211b200341f8026a20034188026a41106a290300370300200341f0026a201b370300200341c0026a41086a41003a0000200341c9026a20032903a001370000200341d1026a200341a0016a41086a290300370000200341d9026a200341a0016a41106a290300370000200341e1026a200341b8016a290300370000200341033a00c00241b0b4cc004100200341c0026a10d4010b200042003703080c040b4200211a200042003703080c030b410321060c010b0b0240200441ffffff3f71450d00200510350b20004200370308200041206a20023602002000411c6a2001360200200041186a20074180801c7120067241801a723602004201211a0b2000201a370300200341e0036a24000bbb0201097f230041106b22012400024002402000280208220241ffffff3f712002470d0020024105742203417f4c0d00200028020021040240024020030d00410121050c010b200310332205450d020b41002100200141003602082001200536020020012003410576360204200141002002108a01200128020821060240024020020d00200128020021070c010b200241057421082001280200220720064105746a21090340200920006a2203200420006a2205290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a2900003700002008200041206a2200470d000b200241057441606a41057620066a41016a21060b200641057441057521000240200128020441ffffff3f71450d00200710350b200141106a240020000f0b1044000b1045000be30204027f017e037f037e230041106b220124000240024020002802082202ad42307e2203422088a70d002003a72204417f4c0d00200028020021000240024020040d00410821050c010b200410332205450d020b20014100360208200120053602002001200441306e3602042001410020021088012001280208210502400240200241306c22020d00200128020021060c010b20012802002206200541306c6a21040340200041086a2903002103200041106a2903002107200041186a290300210820002903002109200441286a200041286a290300370300200441206a200041206a290300370300200441186a2008370300200441106a2007370300200441086a200337030020042009370300200441306a2104200541016a2105200041306a2100200241506a22020d000b0b200541306c41306d2100024020012802042204450d00200441306c450d00200610350b200141106a240020000f0b1044000b1045000be61107067f027e027f0a7e037f017e047f230041d0036b22032400200228020821042002280204210520022802002106200341206a2001108e02200341a0016a2003280220220720032802282208108f0220032903a00121094200210a200342003703a001200341e8016a280200210b20032d00ec01210c02400240200942015122020d00200341306a41306a4200370300200341306a41286a4200370300200341306a41206a4200370300200341306a41186a4200370300200341c0006a4200370300200341386a4200370300200342003703304200210d4200210e4200210f420021100c010b200341d8016a2903002111200341a0016a41306a2903002112200341a0016a41206a290300210f200341a0016a41186a290300210e200341e0016a290300211020032903b001210d20032903a801210a200341306a41206a200341a0016a41286a290300370300200341306a41286a2012370300200341306a41306a2011370300200341c0006a200e3703002003200f3703482003200a3703302003200d3703380b0240024002400240200a200629030022127d2213200a56200d200641086a29030022147d200a201254ad7d2211200d562011200d511b450d0041838c0c2108419089c20021024280808080b00221120c010b200320133703302003201137033802400240200e20127c2215200e542206200f20147c2006ad7c2216200f542016200f511b450d0041838c08210841a7d6ca0021024280808080800121120c010b200341306a41186a2016370300200320153703402012201484500d02200341e8006a2005280200108e02200341a0026a200328026822052003280270108f02200341d0026a290300420020032903a00242015122061b2112200341c8026a290300420020061b21140240200328026c450d00200510350b2014201358201220115820122011511b0d0241838c04210841a389c20021024280808080d00221120b2013210a2011210d0b2002ad221142088842ff0183210f20122011428080fcff0f8384210e410121060c010b20042802002104200341e8006a41186a200341c0006a220641086a2903002212370300200341e8006a41206a2205200641106a29030037030020034190016a2217200641186a29030037030020034198016a2218200641206a2903003703002003200629030022143703782003201337036820032011370370427f200a200e7c220e200e200a542206200d200f7c2006ad7c220a200d54200a200d511b22061b427f200a20061b8450211902400240427f201320147c220a200a2013542206201120127c2006ad7c220a201154200a2011511b22061b220d428080e983b1de16544100427f200a20061b220a501b0d00200341e8006a41106a290300210a2018290300210d2017290300210f2005290300210e200329037021142003290368211642012115200329038001211a0c010b02400240200d200a8450450d00420021150c010b42002115200341a0026a41186a221b4200370300200341a0026a41106a22174200370300200341a0026a41086a22054200370300200342003703a00241b6fdc600ad4280808080800184220f100122182900002112200341c0036a41086a2206201841086a290000370300200320123703c0032018103520052006290300370300200320032903c0033703a00241e489c200ad4280808080d00184221210012218290000210e2006201841086a2900003703002003200e3703c00320181035201720032903c003220e370300200341a0036a41086a221c2005290300370300200341a0036a41106a221d200e370300200341a0036a41186a221e2006290300370300200320032903a0023703a003200341086a200341a0036a412010d701200341086a41106a290300210e2003290310211420032802082118201b42003703002017420037030020054200370300200342003703a002200f1001221b290000210f2006201b41086a2900003703002003200f3703c003201b103520052006290300370300200320032903c0033703a00220121001221b290000210f2006201b41086a2900003703002003200f3703c003201b1035201720032903c003220f370300201c2005290300370300201d200f370300201e2006290300370300200320032903a0023703a00320034200200e420020181b220f200a7d2014420020181b2212200d54ad7d220e2012200d7d2214201256200e200f56200e200f511b22061b3703a80220034200201420061b3703a002200341a0036aad4280808080800484200341a0026aad42808080808002841002200341d8026a200a370300200341d0026a200d370300200541013a0000200341a9026a2004290000370000200341b1026a200441086a290000370000200341b9026a200441106a290000370000200341c1026a200441186a290000370000200341033a00a00241b0b4cc004100200341a0026a10d4010b0b2019ad2112200341c8016a200e370300200341d0016a200f370300200341b0016a2014370300200341d8016a200d370300200341b8016a200a3703002003201a3703c001200320103703e001200320163703a8014201210f410021062003200c4100200942015122041b3a00ec012003200b410020041b3602e801200320154201512204ad3703a001024020040d002008ad4220862007ad8410074200210f2013210a2011210d4200210e0c010b200320083602a402200320073602a002200341a8016a200341a0026a10e7024200210e2013210a2011210d0b02402003280224450d00200710350b024002402006450d0020002008360204200041086a200f4208862002ad42ff018384200e84370200410121020c010b024002400240200241ff017122020d00200f4200510d0041032106200341a0026a21020c010b2002450d01200f4200520d0141042106200341a0016a21020b200241086a20063a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b200041186a200d370300200041106a200a370300200041086a2012370300410021020b20002002360200200341d0036a24000bc90301077f230041106b220224000240200041186a28020022034105744114722204417f4c0d000240200410332205450d00200520002903003700002005200041086a290300370008200241103602082002200436020420022005360200200028021021062003200210770240024020030d002002280208210320022802042104200228020021070c010b20034105742108200228020021072002280204210420022802082103034020062100024002402004200322056b4120490d00200541206a21030c010b024002400240200541206a22032005490d00200441017422062003200620034b1b22064100480d000240024020040d00024020060d00410121070c020b2006103321070c040b20042006470d020b200621040c030b103e000b200720042006103721070b2006210420070d00103c000b200041206a2106200720056a22052000290000370000200541186a200041186a290000370000200541106a200041106a290000370000200541086a200041086a290000370000200841606a22080d000b2002200436020420022003360208200220073602000b20012902002003ad4220862007ad84100202402004450d00200710350b200241106a24000f0b1045000b1044000bea1508047f017e077f027e037f017e017f037e230041d0016b22022400200241b0016a41186a4200370300200241b0016a41106a22034200370300200241b0016a41086a22044200370300200242003703b00141a0e4cb00ad42808080808002841001220529000021062004200541086a290000370300200220063703b001200510354189eaca00ad4280808080f00084100122052900002106200241f0006a41086a2207200541086a290000370300200220063703702005103520032002290370220637030020024190016a41086a200429030037030020024190016a41106a200637030020024190016a41186a2007290300370300200220022903b00137039001200241d0006a20024190016a10a202024002400240200228025022080d00410021092002410036020820024208370300410821080c010b200220022902542206370204200220083602002006a7210941002104024002402006422088a7220a41014b0d00200a0e020201020b200a210503402005410176220720046a220b20042008200b41306c6a2001412010a0084101481b2104200520076b220541014b0d000b0b2008200441306c6a2001412010a0080d0002400240024002402004200a4f0d002008200441306c6a2205200541306a200a2004417f736a41306c109e081a2002200a417f6a220c360208200241b0016a41186a220b4200370300200241b0016a41106a220d4200370300200241b0016a41086a22044200370300200242003703b00141a0e4cb00ad4280808080800284220e1001220529000021062004200541086a290000370300200220063703b0012005103541c699c200ad4280808080900184220f100122072900002106200241f0006a41086a2205200741086a290000370300200220063703702007103520032002290370370000200341086a200529030037000020024190016a41086a2203200429030037030020024190016a41106a2210200d29030037030020024190016a41186a2211200b290300370300200220022903b00137039001200241b0016a20024190016a10a20220022802b0012207410820071b21120240024020022902b401420020071b2206422088a722070d00420021130c010b200b20122007417f6a221441306c6a220741186a290300370300200d200741106a2903003703002004200741086a290300370300200220072903003703b0012014ad422086200642ffffffff0f83842106200741286a290300211520072903202116420121130b2011200b2903003703002010200d29030037030020032004290300370300200220022903b00137039001200241f0006a41186a4200370300200241f0006a41106a220342003703002005420037030020024200370370200e10012207290000210e2004200741086a2900003703002002200e3703b0012007103520052004290300370300200220022903b001370370200f10012207290000210e2004200741086a2900003703002002200e3703b00120071035200320022903b001220e370300200241d0006a41086a2005290300370300200241d0006a41106a200e370300200241d0006a41186a2004290300370300200220022903703703500240024020120d00200241d0006aad428080808080048410070c010b200241203602b4012002200241d0006a3602b00120122006422088a7200241b0016a10a9022006a72204450d00200441306c450d00201210350b200241106a41186a20024190016a41186a22042903002206370300200241106a41106a20024190016a41106a2205290300220e370300200241106a41086a20024190016a41086a2207290300220f37030020022002290390012217370310200241306a41186a220b2006370300200241306a41106a220d200e370300200241306a41086a2212200f370300200220173703300240201350450d00200c210a4100210d0c040b2004200b2903003703002005200d29030037030020072012290300370300200220022903303703900141002104024002400240200a417f6a220541014b0d0020050e020201020b200c210503402005410176220720046a220b20042008200b41306c6a20024190016a412010a0084101481b2104200520076b220541014b0d000b0b2008200441306c6a20024190016a412010a0082205450d022005411f7620046a21040b200241d0006a41186a20024190016a41186a2903002206370300200241d0006a41106a20024190016a41106a290300220e370300200241d0006a41086a20024190016a41086a290300220f37030020022002290390012213370350200241f0006a41186a2006370300200241f0006a41106a200e370300200241f0006a41086a200f37030020022013370370200241b0016a41186a2006370300200241b0016a41106a200e370300200241b0016a41086a200f370300200220133703b001200c2004490d020240200c2009470d0020022009410110880120022802042109200228020021080b2008200441306c6a220541306a2005200c20046b41306c109e081a200541286a201537030020052016370320200541186a200241b0016a41186a290300370300200541106a200241b0016a41106a290300370300200541086a200241b0016a41086a290300370300200520022903b0013703002002200a3602084101210d0c030b2004200a104e000b200241d0006a41186a20024190016a41186a290300370300200241d0006a41106a20024190016a41106a290300370300200241d0006a41086a20024190016a41086a29030037030020022002290390013703504100210d200c210a0c010b2004200c104d000b200241f0006a41186a220b4200370300200241f0006a41106a22124200370300200241f0006a41086a220542003703002002420037037041a0e4cb00ad4280808080800284100122072900002106200241b0016a41086a2204200741086a290000370300200220063703b0012007103520052004290300370300200220022903b0013703704189eaca00ad4280808080f000841001220729000021062004200741086a290000370300200220063703b00120071035200320022903b001370000200341086a2004290300370000200241d0006a41086a2005290300370300200241d0006a41106a2012290300370300200241d0006a41186a200b29030037030020022002290370370350200241203602b4012002200241d0006a3602b0012008200a200241b0016a10a902200241003602b801200242013703b001200241b0016a4100200a41306c220b41306d108a0120022802b80121070240200a450d0020022802b00120074105746a2104200821050340200541086a2900002106200541106a290000210e2005290000210f200441186a200541186a290000370000200441106a200e370000200441086a20063700002004200f370000200741016a2107200441206a2104200541306a2105200b41506a220b0d000b0b200220073602b80102402009450d00200941306c450d00200810350b20022802b401210520022802b0012104200241b0016a41186a200141186a290000370300200241b0016a41106a200141106a290000370300200241b0016a41086a200141086a290000370300200220012900003703b001200241b0016a41012004200710a7022000200d3a0001200041003a0000200041026a200229019001370100200041086a20024196016a290100370100200541ffffff3f71450d01200410350c010b200041013a00002000410c6a4109360200200041086a41f2dfca00360200200041066a410d3a0000200041046a41831a3b01002009450d00200941306c450d00200810350b200241d0016a24000bd30403067f017e037f230041306b220124000240024020002802202202450d000240034020002002417f6a36022020002802042202450d0120002802082103200028020021040240200028020c220520022f0106490d00034002400240200228020022060d002003ad2107410021060c010b200441016a210420023301044220862003ad8421070b200210352007a72103200621022007422088a7220520062f01064f0d000b200621020b200541016a21082002200541e0006c6a220541a0036a28020021092005419c036a280200210620054198036a280200210a200541e8026a290300210702402004450d00200220084102746a41880b6a2802002102410021082004417f6a2204450d00034020022802880b21022004417f6a22040d000b0b2000200836020c20002003360208200020023602042000410036020020074202510d0302400240200a0d00410021092001410036021c2001410036020c0c010b0240024020060d00200a21020c010b20062102200a2103034020032802ec0321032002417f6a22020d000b200a21020340200220022f01064102746a41ec036a28020021022006417f6a22060d000b2003210a0b2001410036022020014100360218200142003703102001200a36020c200141003602082001200236021c200120022f01063602240b20012009360228200141086a108103200028022022020d000c020b0b41958dcc00412b41c08dcc00103f000b200028020421020b02402002450d0020022802002106200210352006450d00034020062802002102200610352002210620020d000b0b200141306a24000b13002000410e360204200041cce9c2003602000bb30201027f230041206b220724002004a7210802400240024002402001a70d0020080d01427f200320067c200220057c22052002542208ad7c22022008200220035420022003511b22081b2103427f200520081b21020c020b024020084101460d00200741086a200420052006200120022003109103200741186a290300210320072903102102200729030821050c030b427f200320067c200220057c22052002542208ad7c22022008200220035420022003511b22081b2103427f200520081b2102420121050c020b02402002200556200320065620032006511b0d00200620037d2005200254ad7d2103200520027d2102420121050c020b200320067d2002200554ad7d2103200220057d21020b420021050b2000200237030820002005370300200041106a2003370300200741206a24000b130020004105360204200041b8fdc2003602000b3400200041a8fdc60036020420004100360200200041146a4101360200200041106a41a8a8c300360200200041086a42073702000bb10201057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b2003410036020820032005360200200320043602042001200310770240024020032802042206200328020822056b2001490d0020032802002104200621070c010b200520016a22042005490d03200641017422072004200720044b1b22074100480d030240024020060d00024020070d00410121040c020b2007103322040d010c060b2003280200210420062007460d0020042006200710372204450d050b20032007360204200320043602000b200420056a20002001109d081a2002290200200520016aad4220862004ad84100202402007450d00200410350b200341106a24000f0b1044000b1045000b103e000b103c000bb60201057f230041106b2203240002400240024002402001410274220441046a2205417f4c0d000240024020050d0041012106410021050c010b200510332206450d020b2003410036020820032006360200200320053602042001200310770240024020032802042207200328020822016b2004490d0020032802002105200721060c010b200120046a22052001490d03200741017422062005200620054b1b22064100480d030240024020070d00024020060d00410121050c020b2006103322050d010c060b2003280200210520072006460d0020052007200610372205450d050b20032006360204200320053602000b200520016a20002004109d081a2002290200200120046aad4220862005ad84100202402006450d00200510350b200341106a24000f0b1044000b1045000b103e000b103c000ba00402067f027e230041106b220324000240024002400240200141186c4104722204417f4c0d00200410332205450d0120034100360208200320043602042003200536020020012003107702400240200141186c22010d002003280208210120032802042104200328020021060c010b200020016a2107200328020421042003280208210103402000280200210802400240200420016b4104490d0020032802002106200421050c010b200141046a22052001490d05200441017422062005200620054b1b22054100480d050240024020040d00024020050d00410121060c020b2005103322060d010c080b2003280200210620042005460d0020062004200510372206450d070b20032005360204200320063602000b200620016a20083600002003200141046a2208360208200041106a2903002109200041086a290300210a02400240200520086b4110490d00200141146a2101200521040c010b200841106a22012008490d05200541017422042001200420014b1b22044100480d050240024020050d00024020040d00410121060c020b200410332206450d080c010b20052004460d0020062005200410372206450d070b20032004360204200320063602000b200620086a220520093700082005200a37000020032001360208200041186a22002007470d000b0b20022902002001ad4220862006ad84100202402004450d00200610350b200341106a24000f0b1044000b1045000b103e000b103c000bdf0301057f230041106b220324000240024002400240200141046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b2003410036020820032005360200200320043602042001200310770240024020032802042204200328020822066b2001490d0020032802002105200421070c010b200620016a22052006490d03200441017422072005200720054b1b22074100480d030240024020040d00024020070d00410121050c020b2007103322050d010c060b2003280200210520042007460d0020052004200710372205450d050b20032007360204200320053602000b200520066a20002001109d081a02400240200241046a2802002200200241086a28020022046b200620016a2201490d00200228020021060c010b200420016a22062004490d03200041017422042006200420064b1b22044100480d030240024020000d00024020040d00410121060c020b200410332206450d060c010b2002280200210620002004460d0020062000200410372206450d050b20022006360200200241046a2004360200200241086a28020021040b200620046a20052001109d081a200241086a200420016a36020002402007450d00200510350b200341106a24000f0b1044000b1045000b103e000b103c000bf00201057f230041206b220324000240024002400240200241046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b2003410036021820032005360210200320043602142002200341106a10770240024020032802142206200328021822056b2002490d0020032802102104200621070c010b200520026a22042005490d03200641017422072004200720044b1b22074100480d030240024020060d00024020070d00410121040c020b2007103322040d010c060b2003280210210420062007460d0020042006200710372204450d050b20032007360214200320043602100b200420056a20012002109d081a2003200520026a2202ad4220862004ad8410032205290000370308200510352003411c6a200420026a360200200320043602182003200341106a3602142003200341086a3602102000200341106a107b02402007450d00200410350b200341206a24000f0b1044000b1045000b103e000b103c000b960503037f027e057f230041106b220224002002410036020820024201370300200028021021030240410410332204450d0020024104360204200220043602002004200336000020024104360208200041146a280200210320044104410810372204450d0020024108360204200420033600042002200436020020024108360208200041086a29030021052000290300210620044108411810372204450d0020042006370008200441106a200537000020022004360200200242988080808003370204024041000d0020044118413810372204450d010b20042000290024370018200441206a2000412c6a290000370000200441286a200041346a290000370000200441306a2000413c6a29000037000020024138360204200220043602002002413836020820002802182104200041206a28020022002002107702400240024020000d002002280208210020022802042107200228020021080c010b200041057421094100200228020822006b210a2002280204210b034002400240200b200a6a4120490d0020022802002108200b21070c010b200041206a22032000490d03200b41017422082003200820034b1b22074100480d0302400240200b0d00024020070d00410121080c020b2007103322080d010c060b20022802002108200b2007460d002008200b200710372208450d050b20022007360204200220083602002007210b0b200820006a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200041206a2200360208200a41606a210a200441206a2104200941606a22090d000b0b20012902002000ad4220862008ad84100202402007450d00200810350b200241106a24000f0b103e000b103c000be20c03037f017e077f230041c0026b22022400024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41cfa2cc00412841c086cc00103f000b2001410c6a2802002204ad42b0027e2205422088a70d052005a72206417f4c0d05200141046a28020021030240024020060d00410821070c010b200610332207450d070b20024100360208200220073602002002200641b0026e3602042002410020041092012002280208210102402004450d00200441b0026c21062002280200200141b0026c6a2107200441047441706a41047621040340200241106a2003109b032007200241106a41b002109d0841b0026a2107200341b0026a2103200641d07d6a22060d000b200120046a41016a21010b200241186a20013602002002200229030022053703102000410c6a2001360200200041046a2005370200200041013a00000c040b200141026a2f0100210641b00210332203450d062003200141046a280200109c03200041046a2003360200200041026a20063b0100200041023a00000c030b2001410c6a280200220841ffffff3f712008470d0320084105742206417f4c0d03200141026a2f01002109200141046a28020021040240024020060d00410121070c010b200610332207450d050b41002103200241003602182002200736021020022006410576360214200241106a41002008108a012002280218210a02402008450d002008410574210b2002280210200a4105746a210c0340200c20036a2206200420036a2207290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200b200341206a2203470d000b200841057441606a410576200a6a41016a210a0b200241086a2206200a36020020022002290310370300200141186a2802002107200141146a28020021042001280210210b41b00210332203450d0520032001411c6a280200109c03200041026a20093b01002000411c6a2003360200200041186a2007360200200041146a2004360200200041106a200b360200200041033a0000200041046a20022903003702002000410c6a20062802003602000c020b2001412c6a280200220841ffffff3f712008470d0220084105742206417f4c0d02200141226a2f01002109200141246a28020021040240024020060d00410121070c010b200610332207450d040b41002103200241003602182002200736021020022006410576360214200241106a41002008108a012002280218210a02402008450d002008410574210b2002280210200a4105746a210c0340200c20036a2206200420036a2207290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200b200341206a2203470d000b200841057441606a410576200a6a41016a210a0b200241086a200a360200200220022903102205370300200041226a20093b0100200041246a20053702002000412c6a200a360200200041043a0000200041386a200141386a280200360200200041306a200129023037020020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c010b2001412c6a280200220841ffffff3f712008470d0120084105742206417f4c0d01200141226a2f01002109200141246a28020021040240024020060d00410121070c010b200610332207450d030b41002103200241003602182002200736021020022006410576360214200241106a41002008108a012002280218210a02402008450d002008410574210b2002280210200a4105746a210c0340200c20036a2206200420036a2207290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200b200341206a2203470d000b200841057441606a410576200a6a41016a210a0b200241086a200a360200200220022903102205370300200041226a20093b0100200041246a20053702002000412c6a200a360200200041053a0000200041306a20012902303702002000200141016a290000370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000b200241c0026a24000f0b1044000b1045000b103c000b881c04057f017e017f037e230041b0036b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c00011302030405060708090a0b0c0d0e0f1011121313131415161713000b20024180016a200141086a109d0320004100360200200041106a20024180016a41086a290300370300200041086a2002290380013703000c170b20024180016a200141046a109a03200041013602002000413c6a200241b8016a280200360200200041346a200241b0016a2903003702002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c160b20004103360200200041086a200141086a2903003703000c150b20024180016a200141046a109e03200041043602002000410c6a20024188016a28020036020020002002290380013702040c140b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b41cfa2cc00412841c086cc00103f000b200141086a2802002103410121050c030b41022105200241026a200441036a2d00003a000020024180016a41086a200141146a29020037030020024190016a2001411c6a29020037030020024198016a200141246a2d00003a0000200220042f00013b010020022001410c6a29020037038001200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b200241026a200441036a2d00003a000020024180016a41086a200141146a29020037030020024190016a2001411c6a29020037030020024198016a200141246a2d00003a0000200220042f00013b010020022001410c6a29020037038001200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01003b000520004105360200200041086a20033602002000410c6a200229038001370200200041286a2001360200200041076a200241026a2d00003a0000200041146a20024180016a41086a2903003702002000411c6a20024190016a290300370200200041246a20024198016a2802003602000c130b20024180016a200141086a108503200041086a20024180016a41e000109d081a200041063602000c120b20024180016a200141086a108702200041086a20024180016a418802109d081a200041073602000c110b02400240200128020422060d00410021030c010b20024180016a41186a200141286a29000037030020024180016a41106a200141206a29000037030020024188016a200141186a29000037030020024180016a41286a200141386a29000037030020024180016a41306a200141c0006a29000037030020024180016a41386a200141c8006a29000037030020024180016a41c8006a200141d8006a29000037030020024180016a41d0006a200141e0006a29000037030020024180016a41d8006a200141e8006a2900003703002002200141106a290000370380012002200141306a2900003703a0012002200141d0006a2900003703c00120024180016a41f8006a20014188016a29000037030020024180016a41f0006a20014180016a29000037030020024180016a41e8006a200141f8006a2900003703002002200141f0006a2900003703e0012001410c6a2802002201417f4c0d120240024020010d0041002105410121030c010b200110332203450d14200121050b0240024020052001490d00200521040c010b200541017422042001200420014b1b22044100480d15024020050d002004103322030d010c170b20052004460d0020032005200410372203450d160b200320062001109d081a200220024180016a418001109d081a2001ad4220862004ad8421070b20002003360204200041086a2007370200200041106a2002418001109d081a200041083602000c100b20024180016a200141086a10a00320004109360200200041386a20024180016a41306a290300370300200041306a20024180016a41286a290300370300200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c0f0b20024180016a200141046a10a1032000410a3602002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c0e0b20024180016a200141046a10a1032000410b3602002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c0d0b20024180016a200141086a1086032000410c360200200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c0c0b20024180016a200141046a10a203200041046a20024180016a41c400109d081a2000410d3602000c0b0b2000410e360200200020012802043602040c0a0b2001410c6a2802002203417f4c0d0a200128020421060240024020030d0041002101410121040c010b200310332204450d0c200321010b0240024020012003490d00200121050c010b200141017422052003200520034b1b22054100480d0d024020010d00200510332204450d0f0c010b20012005460d0020042001200510372204450d0e0b200420062003109d0821012000410c6a2003360200200041086a2005360200200020013602042000410f3602000c090b20024180016a200141086a10a30320004110360200200041c0006a20024180016a41386a290300370300200041386a20024180016a41306a290300370300200041306a20024180016a41286a290300370300200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c080b20024180016a200141086a10a403200041086a20024180016a419801109d081a200041113602000c070b20024180016a200141046a10a503200041123602002000412c6a200241a8016a280200360200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c060b20024180016a200141046a10de04200041046a20024180016a41e800109d081a200041133602000c050b10a703000b20024180016a200141086a10a803200041086a20024180016a41a802109d081a200041173602000c030b20024180016a200141086a10a903200041086a20024180016a41c800109d081a200041183602000c020b20024180016a200141046a10aa03200041046a20024180016a41c400109d081a200041193602000c010b0240024002400240200141086a280200417f6a220841024b0d004101210520080e03030102030b41cfa2cc00412841c086cc00103f000b41012103024002402001410c6a22052d00004101470d00200141106a28020021060c010b200241ae036a200541036a2d00003a000020024188016a2001411c6a29020037030020024180016a41106a200141246a29020037030020024198016a2001412c6a2d00003a0000200220052f00013b01ac032002200141146a29020037038001200141106a2802002106410021030b41022105200241a8036a41026a200241ac036a41026a2d00003a0000200241086a20024180016a41086a290300370300200241106a20024180016a41106a290300370300200241186a20024180016a41186a280200360200200220022f01ac033b01a80320022002290380013703000c010b41012103024002402001410c6a22052d00004101470d00200141106a28020021060c010b200241ae036a200541036a2d00003a000020024188016a2001411c6a29020037030020024180016a41106a200141246a29020037030020024198016a2001412c6a2d00003a0000200220052f00013b01ac032002200141146a29020037038001200141106a2802002106410021030b200241a8036a41026a200241ac036a41026a2d00003a0000200241086a20024180016a41086a290300370300200241106a20024180016a41106a290300370300200241186a20024180016a41186a280200360200200220022f01ac033b01a8032002200229038001370300200141c8006a2903002109200141c0006a2903002107200141386a290300210a200141d0006a28020021042001290330210b410321050b200020022f01a8033b000d200041c8006a2009370300200041c0006a2007370300200041386a200a370300200041306a200b3703002000410c6a20033a0000200041086a2005360200200041106a2006360200200041146a2002290300370200200041d0006a20043602002000410f6a200241aa036a2d00003a00002000411c6a200241086a290300370200200041246a200241106a2903003702002000412c6a200241186a2802003602002000411a3602000b200241b0036a24000f0b1044000b1045000b103e000b103c000ba91a03047f047e027f230041c0036b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c00011302030405060708090a0b0c0d0e0f1011121313131415161713000b2002200141086a109d0320004100360200200041106a200241086a290300370300200041086a20022903003703000c170b2002200141046a109a03200041013602002000413c6a200241386a280200360200200041346a200241306a2903003702002000412c6a200241286a290300370200200041246a200241206a2903003702002000411c6a200241186a290300370200200041146a200241106a2903003702002000410c6a200241086a290300370200200020022903003702040c160b20004103360200200041086a200141086a2903003703000c150b2002200141046a109e03200041043602002000410c6a200241086a280200360200200020022903003702040c140b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b41cfa2cc00412841c086cc00103f000b200141086a2802002103410121050c030b41022105200241b0026a41026a200441036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220042f00013b01b00220022001410c6a290200370300200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b200241b2026a200441036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220042f00013b01b00220022001410c6a290200370300200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01b0023b000520004105360200200041086a20033602002000410c6a2002290300370200200041286a2001360200200041076a200241b2026a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c130b2002200141086a108503200041086a200241e000109d081a200041063602000c120b2002200141086a108702200041086a2002418802109d081a200041073602000c110b024002402001280204450d00200241b0026a41186a200141286a290000370300200241b0026a41106a200141206a290000370300200241b8026a200141186a290000370300200241b0026a41286a200141386a290000370300200241b0026a41306a200141c0006a290000370300200241b0026a41386a200141c8006a290000370300200241b0026a41c8006a200141d8006a290000370300200241b0026a41d0006a200141e0006a290000370300200241b0026a41d8006a200141e8006a2900003703002002200141106a2900003703b0022002200141306a2900003703d0022002200141d0006a2900003703f002200241b0026a41f8006a20014188016a290000370300200241b0026a41f0006a20014180016a290000370300200241b0026a41e8006a200141f8006a2900003703002002200141f0006a290000370390032002200141046a109f032002410c6a200241b0026a418001109d081a0c010b200241003602000b200041046a2002418c01109d081a200041083602000c100b2002200141086a10a00320004109360200200041386a200241306a290300370300200041306a200241286a290300370300200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a290300370300200041086a20022903003703000c0f0b2002200141046a10a1032000410a3602002000412c6a200241286a290300370200200041246a200241206a2903003702002000411c6a200241186a290300370200200041146a200241106a2903003702002000410c6a200241086a290300370200200020022903003702040c0e0b2002200141046a10a1032000410b3602002000412c6a200241286a290300370200200041246a200241206a2903003702002000411c6a200241186a290300370200200041146a200241106a2903003702002000410c6a200241086a290300370200200020022903003702040c0d0b2002200141086a1086032000410c360200200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a290300370300200041086a20022903003703000c0c0b2002200141046a10a203200041046a200241c400109d081a2000410d3602000c0b0b2000410e360200200020012802043602040c0a0b2002200141046a109f032000410f3602002000410c6a200241086a280200360200200020022903003702040c090b2002200141086a10a30320004110360200200041c0006a200241386a290300370300200041386a200241306a290300370300200041306a200241286a290300370300200041286a200241206a290300370300200041206a200241186a290300370300200041186a200241106a290300370300200041106a200241086a290300370300200041086a20022903003703000c080b2002200141086a10a403200041086a2002419801109d081a200041113602000c070b2002200141046a10a503200041123602002000412c6a200241286a280200360200200041246a200241206a2903003702002000411c6a200241186a290300370200200041146a200241106a2903003702002000410c6a200241086a290300370200200020022903003702040c060b200128020421032002200141086a109f03200241b0036a200141146a10a603200241146a200241b0036a41086a280200360200200220022903b00337020c200241b0026a41106a200241106a2903002206370300200241b0026a41086a200241086a29030022073703002002200229030022083703b002200141206a2902002109200141286a280200210520002003360204200041086a2008370200200041106a2007370200200041186a2006370200200041286a2005360200200041206a20093702002000412c6a2001412c6a290200370200200041346a200141346a2902003702002000413c6a2001413c6a290200370200200041c4006a200141c4006a290200370200200041cc006a200141cc006a290200370200200041d4006a200141d4006a290200370200200041dc006a200141dc006a290200370200200041e4006a200141e4006a290200370200200041133602000c050b10a703000b2002200141086a10a803200041086a200241a802109d081a200041173602000c030b2002200141086a10a903200041086a200241c800109d081a200041183602000c020b2002200141046a10aa03200041046a200241c400109d081a200041193602000c010b0240024002400240200141086a280200417f6a220a41024b0d0041012105200a0e03030102030b41cfa2cc00412841c086cc00103f000b41012103024002402001410c6a22052d00004101470d00200141106a280200210b0c010b200241b2036a200541036a2d00003a0000200241086a2001411c6a290200370300200241106a200141246a290200370300200241186a2001412c6a2d00003a0000200220052f00013b01b0032002200141146a290200370300200141106a280200210b410021030b41022105200241ac026a41026a200241b0036a41026a2d00003a0000200241b0026a41086a200241086a290300370300200241b0026a41106a200241106a290300370300200241b0026a41186a200241186a280200360200200220022f01b0033b01ac02200220022903003703b0020c010b41012103024002402001410c6a22052d00004101470d00200141106a280200210b0c010b200241b2036a200541036a2d00003a0000200241086a2001411c6a290200370300200241106a200141246a290200370300200241186a2001412c6a2d00003a0000200220052f00013b01b0032002200141146a290200370300200141106a280200210b410021030b200241ac026a41026a200241b0036a41026a2d00003a0000200241b0026a41086a200241086a290300370300200241b0026a41106a200241106a290300370300200241b0026a41186a200241186a280200360200200220022f01b0033b01ac02200220022903003703b002200141c8006a2903002107200141c0006a2903002106200141386a2903002109200141d0006a280200210420012903302108410321050b200020022f01ac023b000d200041c8006a2007370300200041c0006a2006370300200041386a2009370300200041306a20083703002000410c6a20033a0000200041086a2005360200200041106a200b360200200041146a20022903b002370200200041d0006a20043602002000410f6a200241ae026a2d00003a00002000411c6a200241b0026a41086a290300370200200041246a200241b0026a41106a2903003702002000412c6a200241c8026a2802003602002000411a3602000b200241c0036a24000bf20b03057f017e017f230041306b2202240002400240024002400240024002400240024002400240024002400240024002402001280200417f6a220341094b0d0020030e0a0102030405060708090a010b41cfa2cc00412841c086cc00103f000b20004101360200200020012802043602040c090b2001410c6a2802002203417f4c0d09200128020421040240024020030d0041002101410121050c010b200310332205450d0b200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d0c024020010d002006103322050d010c0e0b20012006460d0020052001200610372205450d0d0b200520042003109d0821012000410c6a2003360200200041086a200636020020002001360204200041023602000c080b20004103360200200041086a200141086a2903003703000c070b2001410c6a2802002203417f4c0d07200128020421040240024020030d0041002101410121050c010b200310332205450d09200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d0a024020010d00200610332205450d0c0c010b20012006460d0020052001200610372205450d0b0b200520042003109d0821012000410c6a2003360200200041086a200636020020002001360204200041043602000c060b2001410c6a2802002203417f4c0d06200128020421040240024020030d0041002101410121050c010b200310332205450d08200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d09024020010d00200610332205450d0b0c010b20012006460d0020052001200610372205450d0a0b200520042003109d0821012000410c6a2003360200200041086a200636020020002001360204200041053602000c050b20004106360200200020012902043702042000410c6a2001410c6a2802003602000c040b2001410c6a2802002205ad42187e2207422088a70d042007a72206417f4c0d04200128020421030240024020060d00410421010c010b200610332201450d060b20024100360228200220013602202002200641186e360224200241206a410020051097012002280228210402402005450d002003200541186c6a21062002280220200441186c6a2101200541037441786a4103762108200241086a410c6a21050340200241086a2003109f0320052003410c6a109f03200141106a200241086a41106a290300370200200141086a200241086a41086a29030037020020012002290308370200200141186a2101200341186a22032006470d000b200420086a41016a21040b200241106a20043602002002200229032022073703082000410c6a200436020020002007370204200041073602000c030b2001410c6a2802002204ad420c7e2207422088a70d032007a72206417f4c0d03200128020421030240024020060d00410421010c010b200610332201450d050b200241003602282002200136022020022006410c6e360224200241206a410020041087012002280228210502402004450d002004410c6c210620022802202005410c6c6a21012004410274417c6a41027621040340200241086a2003109f03200141086a200241086a41086a280200360200200120022903083702002001410c6a21012003410c6a2103200641746a22060d000b200520046a41016a21050b200241086a41086a20053602002002200229032022073703082000410c6a200536020020002007370204200041083602000c020b2001410c6a2802002203417f4c0d02200128020421040240024020030d0041002101410121050c010b200310332205450d04200321010b0240024020012003490d00200121060c010b200141017422062003200620034b1b22064100480d05024020010d00200610332205450d070c010b20012006460d0020052001200610372205450d060b200520042003109d0821012000410c6a2003360200200041086a200636020020002001360204200041093602000c010b2000410a3602000b200241306a24000f0b1044000b1045000b103e000b103c000ba10e03027f017e177f230041a0016b22022400024002400240024020012802082203ad42f0007e2204422088a70d002004a72205417f4c0d00200128020021060240024020050d00410421010c010b200510332201450d020b20024100360208200220013602002002200541f0006e3602042002410020031093012002280208210502402003450d002006200341f0006c6a21072002280200200541f0006c6a21082005200341047441706a4104766a21090340200241d0006a41086a220a200641186a290000370300200241d0006a41106a220b200641206a290000370300200241d0006a41186a220c200641286a290000370300200241306a41086a220d200641386a29000037030020062900102104200241306a41106a220e200641c0006a290000370300200241306a41186a220f200641c8006a290000370300200241106a41186a2210200641e8006a290000370300200241106a41106a2211200641e0006a290000370300200241106a41086a2212200641d8006a290000370300200220043703502002200629003037033020022006290050370310200628020c2205ad42247e2204422088a70d022004a72203417f4c0d0220062802002113200628020421140240024020030d00410421010c010b200310332201450d040b20024100360278200220013602702002200341246e360274200241f0006a41002005108d012002280278211502402005450d00200541246c21162002280270201541246c6a211741002101034002400240024002400240024002400240201420016a22032d00000e06010203040500010b2003410c6a2802002218417f4c0d0b200341046a28020021190240024020180d0041002103410121050c010b201810332205450d0d201821030b0240024020032018490d002003211a0c010b2003410174221a2018201a20184b1b221a4100480d0e024020030d00201a103322050d010c100b2003201a460d0020052003201a10372205450d0f0b2002200520192018109d0836009301410521190c050b2002200341046a28000036009b012002200341016a280000360298012002200341146a290000370380012002200341196a290000370085012002200228029801360290012002200228009b0136009301200341086a280000211a2003410c6a2800002118200341106a2800002105410021190c050b200341106a2802002205417f4c0d09200341086a2802002119200341016a280000211b0240024020050d00410021034101211a0c010b20051033221a450d0b200521030b0240024020032005490d00200321180c010b200341017422182005201820054b1b22184100480d0c024020030d0020181033221a450d0e0c010b20032018460d00201a200320181037221a450d0d0b201a20192005109d081a2002201b36029001410121190c040b200341106a2802002205417f4c0d08200341086a2802002119200341016a280000211b0240024020050d00410021034101211a0c010b20051033221a450d0a200521030b0240024020032005490d00200321180c010b200341017422182005201820054b1b22184100480d0b024020030d0020181033221a450d0d0c010b20032018460d00201a200320181037221a450d0c0b201a20192005109d081a2002201b36029001410221190c030b200341106a2802002205417f4c0d07200341086a2802002119200341016a280000211b0240024020050d00410021034101211a0c010b20051033221a450d09200521030b0240024020032005490d00200321180c010b200341017422182005201820054b1b22184100480d0a024020030d0020181033221a450d0c0c010b20032018460d00201a200320181037221a450d0b0b201a20192005109d081a2002201b36029001410321190c020b410421192002200341046a280200360093012003410c6a2802002118200341086a280200211a0b0b201720016a220320193a0000200341016a200228029001360000200341046a200228009301360000200341106a20053602002003410c6a2018360200200341086a201a360200200341146a2002290380013702002003411c6a20024180016a41086a290300370200201541016a21152016200141246a2201470d000b0b20024180016a41086a2015360200200220022903702204370380012008410c6a20153602002008200437020420082002290350370210200841186a200a29030037020020082013360200200841206a200b290300370200200841286a200c29030037020020082002290330370230200841386a200d290300370200200841c0006a200e290300370200200841c8006a200f290300370200200841e8006a2010290300370200200841e0006a2011290300370200200841d8006a201229030037020020082002290310370250200841f0006a2108200641f0006a22062007470d000b200941016a21050b20002002290300370200200041086a2005360200200241a0016a24000f0b1044000b1045000b103e000b103c000bc80101047f02400240024020012802082202417f4c0d00200128020021030240024020020d0041002101410121040c010b200210332204450d02200221010b0240024020012002490d00200121050c010b02400240200141017422052002200520024b1b22054100480d00024020010d002005103322040d030c060b20012005470d01200121050c020b103e000b20042001200510372204450d030b200420032002109d0821012000200236020820002005360204200020013602000f0b1044000b1045000b103c000bc01203037f027e027f230041106b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203411c4b0d0020030e1d0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d010b41cfa2cc00412841c086cc00103f000b200041013a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c1c0b200041023a0000200041046a200141046a2802003602000c1b0b200141046a28020021044101210302400240200141086a2d00004101470d00200141286a2903002105200141206a29030021060c010b200141096a2d000041017121072001410a6a2d00002108410021030b200041033a0000200041286a2005370300200041206a2006370300200041106a20012903103703002000410a6a20083a0000200041096a20073a0000200041086a20033a0000200041046a20043602002000410b6a2002280006360000200041186a200141186a2903003703002000410f6a200241066a41046a2d00003a00000c1a0b200141046a28020021044101210302400240200141086a2d00004101470d00200141286a2903002105200141206a29030021060c010b200141096a2d000041017121072001410a6a2d00002108410021030b200041043a0000200041286a2005370300200041206a2006370300200041106a20012903103703002000410a6a20083a0000200041096a20073a0000200041086a20033a0000200041046a20043602002000410b6a200228000b360000200041186a200141186a2903003703002000410f6a2002410b6a41046a2d00003a00000c190b200041053a0000200041046a200141046a2802003602000c180b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c170b200041073a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c160b200041083a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c150b200041093a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2902003702000c140b2000410a3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c130b2000410b3a0000200041046a200141046a2802003602000c120b2000410c3a0000200041046a200141046a2802003602000c110b2000410d3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c100b2000410e3a00000c0f0b2000410f3a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0e0b200041103a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c0d0b200041113a00000c0c0b200041123a00000c0b0b2001410c6a2802002203417f4c0d0b200141046a28020021070240024020030d0041002101410121080c010b200310332208450d0d200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d0e024020010d002004103322080d010c100b20012004460d0020082001200410372208450d0f0b200820072003109d0821012000410c6a2003360200200041086a2004360200200041046a2001360200200041133a00000c0a0b2001410c6a2802002203417f4c0d0a200141046a28020021070240024020030d0041002101410121080c010b200310332208450d0c200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d0d024020010d00200410332208450d0f0c010b20012004460d0020082001200410372208450d0e0b200820072003109d0821012000410c6a2003360200200041086a2004360200200041046a2001360200200041143a00000c090b200041153a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c080b200041163a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c070b200041173a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c060b200041183a0000200041046a200141046a2802003602000c050b200041193a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000c040b2000411a3a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c030b2000411b3a00000c020b2000411c3a0000200041046a200141046a2802003602000c010b2000411d3a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000b200241106a24000f0b1044000b1045000b103e000b103c000bcd0601097f230041306b22022400024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41cfa2cc00412841c086cc00103f000b2001412c6a280200220441ffffff3f712004470d0520044105742205417f4c0d05200141246a28020021060240024020050d00410121070c010b200510332207450d070b41002103200241003602182002200736021020022005410576360214200241106a41002004108a012002280218210802402004450d0020044105742109200228021020084105746a210a0340200a20036a2205200620036a2207290000370000200541186a200741186a290000370000200541106a200741106a290000370000200541086a200741086a2900003700002009200341206a2203470d000b200441057441606a41057620086a41016a21080b200241086a220520083602002002200229031037030041002103024020012d00014101470d00200241286a2001411a6a290000370300200241206a200141126a290000370300200241106a41086a2001410a6a2900003703002002200141026a290000370310410121030b200020033a0001200041013a0000200041246a2002290300370200200041026a20022903103700002000412c6a20052802003602002000410a6a200241106a41086a290300370000200041126a200241206a2903003700002000411a6a200241286a2903003700000c040b41b00210332203450d062003200141046a280200109b03200041023a0000200041046a20033602000c030b200141046a280200210541b00210332203450d052003200141086a280200109b03200041086a2003360200200041046a2005360200200041033a00000c020b200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a280200360200200041216a200141216a2d00004100473a00000c010b200041053a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041246a200141246a2802003602000b200241306a24000f0b1044000b1045000b103c000ba60602087f017e230041206b220224000240024002400240024002400240024002400240024020012d0000417f6a220341064b0d0020030e0701020304050607010b41cfa2cc00412841c086cc00103f000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c060b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c050b200041033a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c040b2001410c6a280200220441ffffff3f712004470d0420044105742203417f4c0d04200141046a28020021050240024020030d00410121060c010b200310332206450d060b41002101200241003602182002200636021020022003410576360214200241106a41002004108a012002280218210702402004450d0020044105742108200228021020074105746a21090340200920016a2203200520016a2206290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a2900003700002008200141206a2201470d000b200441057441606a41057620076a41016a21070b200241086a200736020020022002290310220a3703002000410c6a2007360200200041046a200a370200200041043a00000c030b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c020b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c010b200041073a00000b200241206a24000f0b1044000b1045000bc30903027f027e047f230041206b220224000240024002400240024002400240024002400240024002400240024020012d0000417f6a220341074b0d0020030e080102030405060708010b41cfa2cc00412841c086cc00103f000b200141306a2903002104200141286a29030021054101210302400240200141046a2d00004101470d00200141086a28020021010c010b2002411e6a200141076a2d00003a0000200241086a200141146a290000370300200241106a2001411c6a290000370300200241186a200141246a2d00003a00002002200141056a2f00003b011c20022001410c6a290000370300200141086a2800002101410021030b200041013a0000200041306a2004370300200041286a2005370300200041046a20033a0000200041056a20022f011c3b0000200041086a20013602002000410c6a2002290300370200200041076a2002411e6a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c070b200041023a0000200041046a200141046a2802003602000c060b200041033a0000200041046a200141046a2802003602000c050b2001412c6a2802002203417f4c0d05200141246a28020021060240024020030d0041002107410121080c010b200310332208450d07200321070b0240024020072003490d00200721090c010b200741017422092003200920034b1b22094100480d08024020070d002009103322080d010c0a0b20072009460d0020082007200910372208450d090b200820062003109d0821072000412c6a2003360200200041286a2009360200200041246a2007360200200041043a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c040b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c030b2001412c6a2802002203417f4c0d03200141246a28020021060240024020030d0041002107410121080c010b200310332208450d05200321070b0240024020072003490d00200721090c010b200741017422092003200920034b1b22094100480d06024020070d00200910332208450d080c010b20072009460d0020082007200910372208450d070b200820062003109d0821072000412c6a2003360200200041286a2009360200200041246a2007360200200041063a0000200041386a200141386a290300370300200041306a200129033037030020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c020b200041073a000020002001290001370001200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c010b200041083a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000b200241206a24000f0b1044000b1045000b103e000b103c000bd20e03027f107e057f230041c0006b220224000240024002400240024002400240024002400240024020012d0000417f6a220341044b0d0020030e050102030405010b41cfa2cc00412841c086cc00103f000b20014190016a2d00002103200141086a2903002104200141106a2903002105200141186a2903002106200141206a2903002107200141286a2903002108200141306a2903002109200141386a290300210a200141c0006a290300210b200141c8006a290300210c200141d0006a290300210d200141d8006a290300210e200141e0006a290300210f200141e8006a2903002110200141f0006a2903002111200141f8006a290300211220014180016a290300211320004188016a20014188016a29030037030020004180016a2013370300200041f8006a2012370300200041f0006a2011370300200041e8006a2010370300200041e0006a200f370300200041d8006a200e370300200041d0006a200d370300200041c8006a200c370300200041c0006a200b370300200041386a200a370300200041306a2009370300200041286a2008370300200041206a2007370300200041186a2006370300200041106a2005370300200041086a200437030020004190016a20034100473a0000200041013a000020004194016a200241236a28000036000020004191016a20022800203600000c040b2001410c6a2802002203417f4c0d04200141046a28020021140240024020030d0041002101410121150c010b200310332215450d06200321010b0240024020012003490d00200121160c010b200141017422162003201620034b1b22164100480d07024020010d002016103322150d010c090b20012016460d0020152001201610372215450d080b201520142003109d0821012000410c6a2003360200200041086a2016360200200041046a2001360200200041023a00000c030b4101211502400240200141046a2d00004101470d00200141086a28020021170c010b200241026a200141076a2d00003a0000200241206a41086a200141146a290000370300200241306a2001411c6a290000370300200241386a200141246a2d00003a00002002200141056a2f00003b010020022001410c6a290000370320200141086a2800002117410021150b200141306a2802002203417f4c0d03200141c0006a29030021042001290338210520012802282118200129034821060240024020030d0041002101410121140c010b200310332214450d05200321010b0240024020012003490d00200121160c010b200141017422162003201620034b1b22164100480d06024020010d00201610332214450d080c010b20012016460d0020142001201610372214450d070b201420182003109d082101200041c0006a2004370300200041386a2005370300200041046a20153a0000200041086a2017360200200041c8006a2006370300200041306a20033602002000412c6a2016360200200041286a2001360200200041056a20022f01003b0000200041076a200241026a2d00003a00002000410c6a2002290320370200200041146a200241206a41086a2903003702002000411c6a200241306a290300370200200041246a200241386a280200360200200041033a00000c020b200141386a2903002104200141306a2903002105200141c0006a2903002106200241386a200141196a290000370300200241306a200141116a290000370300200241286a200141096a290000370300200220012900013703202001412c6a2802002203417f4c0d02200141246a28020021140240024020030d0041002101410121150c010b200310332215450d04200321010b0240024020012003490d00200121160c010b200141017422162003201620034b1b22164100480d05024020010d00201610332215450d070c010b20012016460d0020152001201610372215450d060b201520142003109d082101200041386a2004370300200041306a2005370300200041c0006a20063703002000412c6a2003360200200041286a2016360200200041246a2001360200200041043a000020002002290320370001200041096a200241286a290300370000200041116a200241306a290300370000200041196a200241386a2903003700000c010b200241186a2216200141196a290000370300200241106a2215200141116a290000370300200241086a2214200141096a29000037030020022001290001370300410021030240200141216a2d00004101470d00200241206a41186a2001413a6a290000370300200241206a41106a200141326a290000370300200241206a41086a2001412a6a2900003703002002200141226a290000370320410121030b20002002290300370001200041216a20033a0000200041226a2002290320370000200041196a2016290300370000200041116a2015290300370000200041096a20142903003700002000412a6a200241206a41086a290300370000200041326a200241206a41106a2903003700002000413a6a200241206a41186a290300370000200041053a00000b200241c0006a24000f0b1044000b1045000b103e000b103c000b890501047f230041206b220224000240024002400240024002402001280200417f6a220341024b0d0020030e03010203010b41cfa2cc00412841c086cc00103f000b41b00210332203450d032003200128020410d10620004101360200200020033602040c020b410121030240024020012d00044101470d00200141086a28020021010c010b2002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002101410021030b200020033a0004200020022f011c3b000520004102360200200041086a20013602002000410c6a2002290300370200200041076a2002411c6a41026a2d00003a0000200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000c010b410121040240024020012d00044101470d00200141086a28020021050c010b2002411e6a200141046a220341036a2d00003a0000200241086a200141146a290200370300200241106a2001411c6a290200370300200241186a200141246a2d00003a0000200220032f00013b011c20022001410c6a290200370300200141086a2802002105410021040b41b00210332203450d012003200128022810d106200020043a0004200041086a2005360200200041286a200336020020004103360200200020022f011c3b0005200041076a2002411e6a2d00003a00002000410c6a2002290300370200200041146a200241086a2903003702002000411c6a200241106a290300370200200041246a200241186a2802003602000b200241206a24000f0b103c000b920203027f017e037f230041206b220224000240024020012802082203ad420c7e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410421060c010b200510332206450d020b200241003602082002200636020020022005410c6e3602042002410020031087012002280208210702402003450d002003410c6c210620022802002007410c6c6a21052003410274417c6a41027621030340200241106a2001109f03200541086a200241106a41086a280200360200200520022903103702002005410c6a21052001410c6a2101200641746a22060d000b200720036a41016a21070b20002002290300370200200041086a2007360200200241206a24000f0b1044000b1045000b110041cfa2cc00412841c086cc00103f000bc95704027f017e3a7f017e230041e0036b220224000240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410a4b0d0020030e0b0102030405060708090a0b010b41cfa2cc00412841c086cc00103f000b200041013a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c0a0b2001410c6a2802002203ad42c8007e2204422088a70d0a2004a72205417f4c0d0a200141046a28020021060240024020050d00410421070c010b200510332207450d0c0b200241003602d003200220073602c8032002200541c8006e3602cc03200241c8036a4100200310a80120022802d003210802402003450d002006200341c8006c6a210920022802c803200841c8006c6a210a4100210703404100210b4100210c024002400240024002400240200620076a22052d00000e06050102030400050b20024188026a41086a200541186a29000037030020024188026a41106a200541206a2d00003a00002002200541036a2d00003a009a032002200541016a2f00003b0198032002200541106a290000370388022005410c6a280000210d200541086a280000210e200541046a280000210f4105210c0c040b2005410c6a280200220d417f4c0d10200541046a280200210c02400240200d0d00410021034101210f0c010b200d1033220f450d12200d21030b024002402003200d490d002003210e0c010b2003410174220e200d200e200d4b1b220e4100480d13024020030d00200e1033220f0d010c150b2003200e460d00200f2003200e1037220f450d140b200f200c200d109d081a4101210c0c030b20024188026a41086a200541186a29000037030020024188026a41106a200541206a2d00003a00002002200541036a2d00003a009a032002200541016a2f00003b0198032002200541106a290000370388022005410c6a280000210d200541086a280000210e200541046a280000210f4102210c0c020b20024188026a41086a200541186a29000037030020024188026a41106a200541206a2d00003a00004103210c2002200541036a2d00003a009a032002200541016a2f00003b0198032002200541106a290000370388022005410c6a280000210d200541086a280000210e200541046a280000210f0c010b20024188026a41086a200541186a29000037030020024188026a41106a200541206a2d00003a00002002200541036a2d00003a009a032002200541016a2f00003b0198032002200541106a290000370388022005410c6a280000210d200541086a280000210e4104210c200541046a280000210f0b024002400240024002400240200541246a2d00000e06050102030400050b200241e8026a41026a200541276a2d00003a0000200241086a41086a2005413c6a290000370300200241086a41106a200541c4006a2d00003a00002002200541256a2f00003b01e8022002200541346a290000370308200541306a28000021102005412c6a2800002111200541286a28000021124105210b0c040b200541306a2802002210417f4c0d10200541286a280200210b0240024020100d0041002103410121120c010b201010332212450d12201021030b0240024020032010490d00200321110c010b200341017422112010201120104b1b22114100480d13024020030d00201110332212450d150c010b20032011460d0020122003201110372212450d140b2012200b2010109d081a4101210b0c030b4102210b200241e8026a41026a200541276a2d00003a0000200241086a41086a2005413c6a290000370300200241086a41106a200541c4006a2d00003a00002002200541256a2f00003b01e8022002200541346a290000370308200541306a28000021102005412c6a2800002111200541286a28000021120c020b200241e8026a41026a200541276a2d00003a0000200241086a41086a2005413c6a290000370300200241086a41106a200541c4006a2d00003a00002002200541256a2f00003b01e8022002200541346a290000370308200541306a28000021102005412c6a2800002111200541286a28000021124103210b0c010b200241e8026a41026a200541276a2d00003a0000200241086a41086a2005413c6a290000370300200241086a41106a200541c4006a2d00003a00002002200541256a2f00003b01e8022002200541346a290000370308200541306a28000021102005412c6a2800002111200541286a28000021124104210b0b200a20076a2203200c3a0000200341016a20022f0198033b0000200341036a20022d009a033a00002003410c6a200d360000200341086a200e360000200341046a200f360000200341106a200229038802370000200341216a20022f0080033b0000200341186a20024188026a41086a290300370000200341206a20024188026a41106a2d00003a0000200341236a20024180036a41026a2d00003a0000200341246a200b3a0000200341286a20123600002003412c6a2011360000200341306a2010360000200341256a20022f01e8023b0000200341276a200241e8026a41026a2d00003a0000200341346a20022903083700002003413c6a200241086a41086a290300370000200341c4006a200241086a41106a2d00003a0000200341c5006a20022f00b0033b0000200341c7006a200241b0036a41026a2d00003a0000200741c8006a2107200841016a2108200541c8006a2009470d000b0b200241a8026a41086a2008360200200220022903c8033703a8024100211341002114024002400240024002400240200141106a2d00000e06050102030400050b200241cc026a200141136a2d00003a0000200241b8026a41086a200141286a290000370300200241b8026a41106a200141306a2d00003a00002002200141116a2f00003b01ca022002200141206a2900003703b8022001411c6a2800002103200141186a280000210a200141146a2800002108410521140c040b2001411c6a2802002203417f4c0d0e200141146a28020021070240024020030d0041002105410121080c010b200310332208450d10200321050b0240024020052003490d002005210a0c010b2005410174220b2003200b20034b1b220a4100480d11024020050d00200a10332208450d130c010b2005200a460d0020082005200a10372208450d120b200820072003109d081a410121140c030b41022114200241ca026a41026a200141136a2d00003a0000200241b8026a41086a200141286a290000370300200241b8026a41106a200141306a2d00003a00002002200141116a2f00003b01ca022002200141206a2900003703b8022001411c6a2800002103200141186a280000210a200141146a28000021080c020b200241cc026a200141136a2d00003a0000200241b8026a41086a200141286a290000370300200241b8026a41106a200141306a2d00003a00002002200141116a2f00003b01ca022002200141206a2900003703b8022001411c6a2800002103200141186a280000210a200141146a2800002108410321140c010b200241cc026a200141136a2d00003a0000200241b8026a41086a200141286a290000370300200241b8026a41106a200141306a2d00003a00002002200141116a2f00003b01ca022002200141206a2900003703b8022001411c6a2800002103200141186a280000210a200141146a2800002108410421140b024002400240024002400240200141346a2d00000e06050102030400050b200241e4026a200141376a2d00003a0000200241d8026a200141cc006a290000370300200241e0026a200141d4006a2d00003a00002002200141356a2f00003b01e2022002200141c4006a2900003703d002200141c0006a28000021052001413c6a2800002115200141386a280000210f410521130c040b200141c0006a2802002205417f4c0d0e200141386a280200210b0240024020050d00410021074101210f0c010b20051033220f450d10200521070b0240024020072005490d00200721150c010b2007410174220c2005200c20054b1b22154100480d11024020070d0020151033220f450d130c010b20072015460d00200f200720151037220f450d120b200f200b2005109d081a410121130c030b41022113200241e2026a41026a200141376a2d00003a0000200241d8026a200141cc006a290000370300200241e0026a200141d4006a2d00003a00002002200141356a2f00003b01e2022002200141c4006a2900003703d002200141c0006a28000021052001413c6a2800002115200141386a280000210f0c020b200241e4026a200141376a2d00003a0000200241d8026a200141cc006a290000370300200241e0026a200141d4006a2d00003a00002002200141356a2f00003b01e2022002200141c4006a2900003703d002200141c0006a28000021052001413c6a2800002115200141386a280000210f410321130c010b200241e4026a200141376a2d00003a0000200241d8026a200141cc006a290000370300200241e0026a200141d4006a2d00003a00002002200141356a2f00003b01e2022002200141c4006a2900003703d002200141c0006a28000021052001413c6a2800002115200141386a280000210f410421130b4100211641002117024002400240024002400240200141d8006a2d00000e06050102030400050b200241fc026a200141db006a2d00003a0000200241f0026a200141f0006a290000370300200241f8026a200141f8006a2d00003a00002002200141d9006a2f00003b01fa022002200141e8006a2900003703e802200141e4006a2800002107200141e0006a2800002118200141dc006a2800002112410521170c040b200141e4006a2802002207417f4c0d0e200141dc006a280200210c0240024020070d004100210b410121120c010b200710332212450d102007210b0b02400240200b2007490d00200b21180c010b200b410174220d2007200d20074b1b22184100480d110240200b0d00201810332212450d130c010b200b2018460d002012200b201810372212450d120b2012200c2007109d081a410121170c030b41022117200241fa026a41026a200141db006a2d00003a0000200241f0026a200141f0006a290000370300200241f8026a200141f8006a2d00003a00002002200141d9006a2f00003b01fa022002200141e8006a2900003703e802200141e4006a2800002107200141e0006a2800002118200141dc006a28000021120c020b200241fc026a200141db006a2d00003a0000200241f0026a200141f0006a290000370300200241f8026a200141f8006a2d00003a00002002200141d9006a2f00003b01fa022002200141e8006a2900003703e802200141e4006a2800002107200141e0006a2800002118200141dc006a2800002112410321170c010b200241fc026a200141db006a2d00003a0000200241f0026a200141f0006a290000370300200241f8026a200141f8006a2d00003a00002002200141d9006a2f00003b01fa022002200141e8006a2900003703e802200141e4006a2800002107200141e0006a2800002118200141dc006a2800002112410421170b024002400240024002400240200141fc006a2d00000e06050102030400050b20024194036a200141ff006a2d00003a000020024188036a20014194016a29000037030020024190036a2001419c016a2d00003a00002002200141fd006a2f00003b01920320022001418c016a2900003703800320014188016a280000210b20014184016a280000211920014180016a280000210e410521160c040b20014188016a280200220b417f4c0d0e20014180016a280200210d02400240200b0d004100210c4101210e0c010b200b1033220e450d10200b210c0b02400240200c200b490d00200c21190c010b200c4101742210200b2010200b4b1b22194100480d110240200c0d0020191033220e450d130c010b200c2019460d00200e200c20191037220e450d120b200e200d200b109d081a410121160c030b4102211620024192036a41026a200141ff006a2d00003a000020024188036a20014194016a29000037030020024190036a2001419c016a2d00003a00002002200141fd006a2f00003b01920320022001418c016a2900003703800320014188016a280000210b20014184016a280000211920014180016a280000210e0c020b20024194036a200141ff006a2d00003a000020024188036a20014194016a29000037030020024190036a2001419c016a2d00003a00002002200141fd006a2f00003b01920320022001418c016a2900003703800320014188016a280000210b20014184016a280000211920014180016a280000210e410321160c010b20024194036a200141ff006a2d00003a000020024188036a20014194016a29000037030020024190036a2001419c016a2d00003a00002002200141fd006a2f00003b01920320022001418c016a2900003703800320014188016a280000210b20014184016a280000211920014180016a280000210e410421160b4100211a4100211b024002400240024002400240200141a0016a2d00000e06050102030400050b200241ac036a200141a3016a2d00003a0000200241a0036a200141b8016a290000370300200241a8036a200141c0016a2d00003a00002002200141a1016a2f00003b01aa032002200141b0016a29000037039803200141ac016a280000210c200141a8016a280000211c200141a4016a28000021114105211b0c040b200141ac016a280200220c417f4c0d0e200141a4016a280200211002400240200c0d004100210d410121110c010b200c10332211450d10200c210d0b02400240200d200c490d00200d211c0c010b200d4101742206200c2006200c4b1b221c4100480d110240200d0d00201c10332211450d130c010b200d201c460d002011200d201c10372211450d120b20112010200c109d081a4101211b0c030b4102211b200241aa036a41026a200141a3016a2d00003a0000200241a0036a200141b8016a290000370300200241a8036a200141c0016a2d00003a00002002200141a1016a2f00003b01aa032002200141b0016a29000037039803200141ac016a280000210c200141a8016a280000211c200141a4016a28000021110c020b200241ac036a200141a3016a2d00003a0000200241a0036a200141b8016a290000370300200241a8036a200141c0016a2d00003a00002002200141a1016a2f00003b01aa032002200141b0016a29000037039803200141ac016a280000210c200141a8016a280000211c200141a4016a28000021114103211b0c010b200241ac036a200141a3016a2d00003a0000200241a0036a200141b8016a290000370300200241a8036a200141c0016a2d00003a00002002200141a1016a2f00003b01aa032002200141b0016a29000037039803200141ac016a280000210c200141a8016a280000211c200141a4016a28000021114104211b0b02402001418c026a2d00004101470d0020024198026a2001419d026a28000036020020024190026a20014195026a29000037030020022001418d026a290000370388024101211a0b4100211d4100211e024002400240024002400240200141c4016a2d00000e06050102030400050b200241c4036a200141c7016a2d00003a0000200241b8036a200141dc016a290000370300200241c0036a200141e4016a2d00003a00002002200141c5016a2f00003b01c2032002200141d4016a2900003703b003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021064105211e0c040b200141d0016a280200220d417f4c0d0e200141c8016a280200210902400240200d0d0041002110410121060c010b200d10332206450d10200d21100b024002402010200d490d002010211f0c010b2010410174221f200d201f200d4b1b221f4100480d11024020100d00201f10332206450d130c010b2010201f460d0020062010201f10372206450d120b20062009200d109d081a4101211e0c030b4102211e200241c2036a41026a200141c7016a2d00003a0000200241b8036a200141dc016a290000370300200241c0036a200141e4016a2d00003a00002002200141c5016a2f00003b01c2032002200141d4016a2900003703b003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021060c020b200241c4036a200141c7016a2d00003a0000200241b8036a200141dc016a290000370300200241c0036a200141e4016a2d00003a00002002200141c5016a2f00003b01c2032002200141d4016a2900003703b003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021064103211e0c010b200241c4036a200141c7016a2d00003a0000200241b8036a200141dc016a290000370300200241c0036a200141e4016a2d00003a00002002200141c5016a2f00003b01c2032002200141d4016a2900003703b003200141d0016a280000210d200141cc016a280000211f200141c8016a28000021064104211e0b024002400240024002400240200141e8016a2d00000e06050102030400050b200241de036a200141eb016a2d00003a0000200241d0036a20014180026a290000370300200241d8036a20014188026a2d00003a00002002200141e9016a2f00003b01dc032002200141f8016a2900003703c803200141f4016a2800002110200141f0016a2800002120200141ec016a28000021094105211d0c040b200141f4016a2802002210417f4c0d0e200141ec016a280200211d0240024020100d0041002101410121090c010b201010332209450d10201021010b0240024020012010490d00200121200c010b200141017422202010202020104b1b22204100480d11024020010d00202010332209450d130c010b20012020460d0020092001202010372209450d120b2009201d2010109d081a4101211d0c030b4102211d200241dc036a41026a200141eb016a2d00003a0000200241d0036a20014180026a290000370300200241d8036a20014188026a2d00003a00002002200141e9016a2f00003b01dc032002200141f8016a2900003703c803200141f4016a2800002110200141f0016a2800002120200141ec016a28000021090c020b200241de036a200141eb016a2d00003a0000200241d0036a20014180026a290000370300200241d8036a20014188026a2d00003a00002002200141e9016a2f00003b01dc032002200141f8016a2900003703c803200141f4016a2800002110200141f0016a2800002120200141ec016a28000021094103211d0c010b200241de036a200141eb016a2d00003a0000200241d0036a20014180026a290000370300200241d8036a20014188026a2d00003a00002002200141e9016a2f00003b01dc032002200141f8016a2900003703c803200141f4016a2800002110200141f0016a2800002120200141ec016a28000021094104211d0b200241f8016a41086a2201200241a8026a41086a280200360200200241f4016a41026a2221200241ca026a41026a2d00003a0000200241e0016a41086a2222200241b8026a41086a290300370300200241e0016a41106a2223200241b8026a41106a2d00003a0000200241dc016a41026a2224200241b5026a41026a2d00003a0000200220022903a8023703f801200220022f01ca023b01f401200220022903b8023703e001200220022f00b5023b01dc01200241d8016a41026a2225200241e2026a41026a2d00003a0000200241c0016a41086a2226200241d0026a41086a290300370300200241c0016a41106a2227200241d0026a41106a2d00003a0000200241bc016a41026a2228200241cd026a41026a2d00003a0000200241b8016a41026a2229200241fa026a41026a2d00003a0000200220022f01e2023b01d801200220022903d0023703c001200220022f00cd023b01bc01200220022f01fa023b01b801200241a0016a41106a222a200241e8026a41106a2d00003a0000200241a0016a41086a222b200241e8026a41086a2903003703002002419c016a41026a222c200241e5026a41026a2d00003a000020024198016a41026a222d20024192036a41026a2d00003a000020024180016a41106a222e20024180036a41106a2d00003a000020024180016a41086a222f20024180036a41086a290300370300200220022903e8023703a001200220022f00e5023b019c01200220022f0192033b019801200220022903800337038001200241fc006a41026a2230200241fd026a41026a2d00003a0000200220022f00fd023b017c200241f8006a41026a2231200241aa036a41026a2d00003a0000200220022f01aa033b0178200241e0006a41106a223220024198036a41106a2d00003a0000200241e0006a41086a223320024198036a41086a2903003703002002200229039803370360200241dc006a41026a223420024195036a41026a2d00003a0000200220022f0095033b015c200241086a41106a223520024188026a41106a280200360200200241086a41086a223620024188026a41086a2903003703002002200229038802370308200241d8006a41026a2237200241c2036a41026a2d00003a0000200220022f01c2033b0158200241c0006a41106a2238200241b0036a41106a2d00003a0000200241c0006a41086a2239200241b0036a41086a290300370300200220022903b0033703402002413c6a41026a223a200241ad036a41026a2d00003a0000200220022f00ad033b013c200241386a41026a223b200241dc036a41026a2d00003a0000200220022f01dc033b0138200241206a41106a223c200241c8036a41106a2d00003a0000200241206a41086a223d200241c8036a41086a290300370300200220022903c8033703202002411c6a41026a223e200241c5036a41026a2d00003a0000200220022f00c5033b011c200041106a20143a00002000410c6a2001280200360200200041046a20022903f8013702002000411c6a2003360000200041186a200a360000200041146a2008360000200041116a20022f01f4013b0000200041136a20212d00003a0000200041206a20022903e001370000200041286a2022290300370000200041306a20232d00003a0000200041336a20242d00003a0000200041316a20022f01dc013b0000200041346a20133a0000200041376a20252d00003a0000200041356a20022f01d8013b0000200041c0006a20053600002000413c6a2015360000200041386a200f360000200041d4006a20272d00003a0000200041cc006a2026290300370000200041c4006a20022903c001370000200041d7006a20282d00003a0000200041d5006a20022f01bc013b0000200041d8006a20173a0000200041db006a20292d00003a0000200041d9006a20022f01b8013b0000200041e4006a2007360000200041e0006a2018360000200041dc006a2012360000200041f8006a202a2d00003a0000200041f0006a202b290300370000200041e8006a20022903a001370000200041fb006a202c2d00003a0000200041f9006a20022f019c013b0000200041fc006a20163a0000200041ff006a202d2d00003a0000200041fd006a20022f0198013b000020004188016a200b36000020004184016a201936000020004180016a200e3600002000419c016a202e2d00003a000020004194016a202f2903003700002000418c016a2002290380013700002000419f016a20302d00003a00002000419d016a20022f017c3b0000200041a0016a201b3a0000200041a3016a20312d00003a0000200041a1016a20022f01783b0000200041ac016a200c360000200041a8016a201c360000200041a4016a2011360000200041c0016a20322d00003a0000200041b8016a2033290300370000200041b0016a2002290360370000200041c3016a20342d00003a0000200041c1016a20022f015c3b0000200041c4016a201e3a0000200041c7016a20372d00003a0000200041c5016a20022f01583b0000200041d0016a200d360000200041cc016a201f360000200041c8016a2006360000200041e4016a20382d00003a0000200041dc016a2039290300370000200041d4016a2002290340370000200041e7016a203a2d00003a0000200041e5016a20022f013c3b0000200041e8016a201d3a0000200041eb016a203b2d00003a0000200041e9016a20022f01383b0000200041f4016a2010360000200041f0016a2020360000200041ec016a200936000020004188026a203c2d00003a000020004180026a203d290300370000200041f8016a20022903203700002000418b026a203e2d00003a000020004189026a20022f011c3b00002000418c026a201a3a00002000419d026a203528020036000020004195026a20362903003700002000418d026a2002290308370000200041a3026a20024188026a41026a2d00003a0000200041a1026a20022f0088023b0000200041023a00000c090b2001410c6a2802002203ad42c4007e2204422088a70d092004a72205417f4c0d09200141046a28020021060240024020050d00410421070c010b200510332207450d0b0b41002101200241003602b803200220073602b0032002200541c4006e3602b403200241b0036a41002003109f0120022802b803210b02402003450d002006200341c4006c6a210920022802b003200b41c4006c6a210a20024188026a41086a210c20024188026a41106a210d0340200c200620016a220541176a290000370300200d2005411f6a2d00003a0000200220052f01003b0198032002200541026a2d00003a009a0320022005410f6a290000370388022005410b6a2800002110200541076a2800002108200541036a280000210f41002107024002400240024002400240200541206a2d00000e06050102030400050b200241e8026a41026a200541236a2d00003a0000200241086a41086a200541386a290000370300200241086a41106a200541c0006a2d00003a00002002200541216a2f00003b01e8022002200541306a2900003703082005412c6a2800002111200541286a280000210e200541246a2800002112410521070c040b200241c8036a200541246a109f0320022802d003211120022802cc03210e20022802c8032112410121070c030b41022107200241e8026a41026a200541236a2d00003a0000200241086a41086a200541386a290000370300200241086a41106a200541c0006a2d00003a00002002200541216a2f00003b01e8022002200541306a2900003703082005412c6a2800002111200541286a280000210e200541246a28000021120c020b200241e8026a41026a200541236a2d00003a0000200241086a41086a200541386a290000370300200241086a41106a200541c0006a2d00003a00002002200541216a2f00003b01e8022002200541306a2900003703082005412c6a2800002111200541286a280000210e200541246a2800002112410321070c010b200241e8026a41026a200541236a2d00003a0000200241086a41086a200541386a290000370300200241086a41106a200541c0006a2d00003a00002002200541216a2f00003b01e8022002200541306a2900003703082005412c6a2800002111200541286a280000210e200541246a2800002112410421070b200a20016a220320022f0198033b0100200341026a20022d009a033a00002003410b6a2010360000200341076a2008360000200341036a200f3600002003410f6a200229038802370000200341176a200c2903003700002003411f6a200d2d00003a0000200341206a20073a0000200341216a20022f01e8023b0000200341236a200241e8026a41026a2d00003a00002003412c6a2011360000200341286a200e360000200341246a2012360000200341306a2002290308370000200341386a200241086a41086a290300370000200341c0006a200241086a41106a2d00003a0000200341c1006a20022f0080033b0000200341c3006a20024180036a41026a2d00003a0000200141c4006a2101200b41016a210b200541c4006a2009470d000b0b20024190026a200b360200200220022903b0032204370388022000410c6a200b360200200041046a2004370200200041033a00000c080b200041043a00000c070b200041053a0000200041106a200141106a290300370300200041086a200141086a290300370300200041046a200141046a2802003602000c060b200041063a0000200041046a200141046a2802003602000c050b200041073a0000200041106a200141106a290300370300200041086a200141086a290300370300200041046a200141046a2802003602000c040b200041083a000020002001290001370001200041246a200141246a280200360200200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c030b200041093a0000200041086a200141086a290300370300200041046a200141046a2802003602000c020b200141046a28020021054101210302400240200141086a2d00004101470d002001410c6a28020021070c010b2002410a6a2001410b6a2d00003a000020024188026a41086a200141186a29000037030020024188026a41106a200141206a29000037030020024188026a41186a200141286a2d00003a00002002200141096a2f00003b01082002200141106a290000370388022001410c6a2800002107410021030b200041086a20033a0000200041046a2005360200200041096a20022f01083b00002000410c6a2007360200200041106a2002290388023702002000410b6a2002410a6a2d00003a0000200041186a20024188026a41086a290300370200200041206a20024188026a41106a290300370200200041286a20024188026a41186a280200360200200141386a29030021042001350230213f200041c0006a200141c0006a290300370300200041386a2004370300200041306a203f3703002000410a3a00000c010b4101210302400240200141046a2d00004101470d00200141086a28020021050c010b2002410a6a200141076a2d00003a000020024188026a41086a200141146a29000037030020024198026a2001411c6a290000370300200241a0026a200141246a2d00003a00002002200141056a2f00003b010820022001410c6a29000037038802200141086a2800002105410021030b2000410b3a0000200041046a20033a0000200041056a20022f01083b0000200041086a20053602002000410c6a200229038802370200200041076a2002410a6a2d00003a0000200041146a20024188026a41086a2903003702002000411c6a20024198026a290300370200200041246a200241a0026a2802003602000b200241e0036a24000f0b1044000b1045000b103e000b103c000ba80901067f230041306b2202240002400240024002400240024002400240024002400240024002400240024002400240024020012d0000417f6a2203410b4b0d0020030e0c0102030405060708090a0b0c010b41cfa2cc00412841c086cc00103f000b200041013a0000200041106a200141106a290300370300200041086a200141086a2903003703000c0b0b200041023a0000200041046a200141046a2802003602000c0a0b200041033a000020002001290001370001200041c0006a200141c0006a290300370300200041386a200141386a290300370300200041306a200141306a290300370300200041286a200141286a290300370300200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a2900003700000c090b200041043a0000200041046a200141046a2802003602000c080b4101210302400240200141046a2d00004101470d00200141086a28020021040c010b2002410e6a200141076a2d00003a0000200241106a41086a200141146a290000370300200241206a2001411c6a290000370300200241286a200141246a2d00003a00002002200141056a2f00003b010c20022001410c6a290000370310200141086a2800002104410021030b200041053a0000200041046a20033a0000200041056a20022f010c3b0000200041086a20043602002000410c6a2002290310370200200041076a2002410e6a2d00003a0000200041146a200241106a41086a2903003702002000411c6a200241206a290300370200200041246a200241286a280200360200200020012d00014100473a00010c070b200041063a0000200020012d00014100473a00010c060b200041073a00000c050b200241286a200141196a290000370300200241206a200141116a290000370300200241186a200141096a29000037030020022001290001370310200141306a2802002203417f4c0d05200141286a2802002105200141246a28020021060240024020030d0041002101410121070c010b200310332207450d07200321010b0240024020012003490d00200121040c010b200141017422042003200420034b1b22044100480d08024020010d002004103322070d010c0a0b20012004460d0020072001200410372207450d090b200720052003109d082101200041306a20033602002000412c6a2004360200200041286a2001360200200041246a2006360200200041083a0000200041196a200241286a290300370000200041116a200241206a290300370000200041096a200241106a41086a290300370000200020022903103700010c040b200041093a00000c030b2000410a3a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00004100473a00000c020b2000410b3a000020002001290001370001200041096a200141096a290000370000200041116a200141116a290000370000200041196a200141196a290000370000200041216a200141216a2d00003a00000c010b2000410c3a0000200041046a200141046a2802003602000b200241306a24000f0b1044000b1045000b103e000b103c000be90802097f017e230041306b220224000240024002400240024002400240024002400240024002400240024020012d0000417f6a220341084b0d0020030e09010203040506070809010b41cfa2cc00412841c086cc00103f000b200241186a2204200141196a290000370300200241106a2205200141116a290000370300200241086a2206200141096a2900003703002002200129000137030041b00210332203450d092003200141246a280200109b03200041246a2003360200200041013a0000200041196a2004290300370000200041116a2005290300370000200041096a2006290300370000200020022903003700010c080b200041023a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c070b2001410c6a280200220741ffffff3f712007470d0820074105742204417f4c0d08200141046a28020021060240024020040d00410121050c010b200410332205450d0a0b41002103200241003602082002200536020020022004410576360204200241002007108a012002280208210802402007450d0020074105742109200228020020084105746a210a0340200a20036a2204200620036a2205290000370000200441186a200541186a290000370000200441106a200541106a290000370000200441086a200541086a2900003700002009200341206a2203470d000b200741057441606a41057620086a41016a21080b200241286a200836020020022002290300220b370320200041046a200b3702002000410c6a2008360200200041033a0000200041106a2001280210360200200041026a20012f01023b01000c060b200041043a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c050b200041053a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a290000370000200041216a200141216a290000370000200041296a200141296a290000370000200041316a200141316a290000370000200041396a200141396a2900003700000c040b200041063a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c030b200041073a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000c020b200041083a00000c010b200041093a000020002001290001370001200041196a200141196a290000370000200041116a200141116a290000370000200041096a200141096a2900003700000b200241306a24000f0b103c000b1044000b1045000bda9b01070b7f017e097f027e037f017e177f230041a00a6b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341f4066a4101360200200342013702e406200341e8d4ca003602e0062003410436029c032003419cd5ca0036029803200320034198036a3602f006200341e0066a41b0b4cc00104c000b200341e8056a41026a2204200241076a2d00003a00002003200241056a2f00003b01e805200141046a28020022052001410c6a280200220641b0026c22076a2108200141086a280200210920052101024002402006450d00200241046a2d0000210a200241026a2f0100210b200241086a280200210c2002410c6a280200210d200241106a290200210e200241186a280200210f200241246a2d0000211020022d0001211120022d0000211220034198036a410272211320034198036a4105722114200741d07d6a2106200341bd036a2115200341c0066a4103722116200341e0066a41047221172002411c6a29020022184220882119200341de066a211a4100211b2005210103402001280200210220034198036a200141046a220741ac02109d081a200341e0066a200741ac02109d081a02402002411b470d00200141b0026a21010c2b0b200341e8006a200341e0066a41ac02109d081a200320023602e0062017200341e8006a41ac02109d081a024002400240024020120e03000102000b4102210202400240024020110e03000102000b410021020c010b201620032f01e8053b0000200320183e01da06201a20193d0100201641026a20042d00003a00002003200a3a00c2062003200b3b01c0062003200f3601d6062003200e3701ce062003200d3601ca062003200c3601c606410121020b201320032903c006370000201341086a200341c0066a41086a290300370000201341106a200341c0066a41106a290300370000201341186a200341c0066a41186a290300370000200320023a009903200341003a0098030c020b41022102024002400240200a0e03000102000b410021020c010b20034188066a41026a20042d00003a0000200320032f01e8053b018806410121020b201420032f0188063b0000201520032f00b8093b0000201441026a20034188066a41026a2d00003a0000201541026a200341b8096a41026a2d00003a0000200320023a009c03200320103a00bc03200320183702b4032003200f3602b0032003200e3703a8032003200d3602a4032003200c3602a003200341013a0098030c010b41022102024002400240200a0e03000102000b410021020c010b200341c4056a41026a20042d00003a0000200320032f01e8053b01c405201c41807e71201072211c410121020b201420032f01c4053b0000200341023a009803201441026a200341c4056a41026a2d00003a0000200320023a009c032003201c3602bc03200320183702b4032003200f3602b0032003200e3703a8032003200d3602a4032003200c3602a0030b20034190096a200341e0066a20034198036a10ac032003290390094201510d02201b41016a211b200641d07d6a2106200141b0026a22012008470d000b200821010b200341e0066a20034198036a41ac02109d081a0c280b20034198036a41186a200341b0096a290300220e37030020034198036a41106a20034190096a41186a290300221837030020034198036a41086a20034190096a41106a290300370300200320032903980937039803200341e0066a41086a201b360200200341ec066a2018370200200341f4066a200e3e0200200341003a00e406200341013a00e00641b0b4cc004100200341e0066a10d40102402006450d00200141b0026a21010340200110bb02200141b0026a2101200641d07d6a22060d000b0b2009450d28200941b0026c450d28200510350c280b41022106200141046a280200210820022d00000d0520022d00014101470d052002411a6a290100210e200241196a2d00002106200241186a2d00002107200241166a2f0100211b200241156a2d00002113200241146a2d00002114200241126a2f01002112200241116a2d00002117200241106a2d0000210a2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210f2002410a6a2f01002115200241096a2d0000211c200241086a2d00002110200241066a2f01002104200241056a2d00002105200241046a2d00002111200241026a2f01002102200141026a2f01002109411210332201450d03200141086a4100290085aa43370000200141002900fda94337000020014112413010372201450d042001200e370028200120063a0027200120073a00262001201b3b0024200120133a0023200120143a0022200120123b0020200120173a001f2001200a3a001e2001200c3b001c2001200d3a001b2001200f3a001a200120153b00182001201c3a0017200120103a0016200120043b0014200120053a0013200120113a0012200120023b00102001413041e00010372202450d04200220093b00302002ad4280808080a0068410092201290000210e200141086a2900002118200141106a2900002119200341c0066a41186a2206200141186a290000370300200341c0066a41106a22072019370300200341c0066a41086a221b20183703002003200e3703c0062001103520021035200341093a0080072003410a3a0080072003410b3a008007200320032f01c0063b01e006200320032801c2063601e206200320032f01c6063b01e6062003201b2f01003b01e806200320032d00ca063a00ea062003410c3a008007200320032d00cb063a00eb062003410d3a008007200320032d00cc063a00ec062003410e3a008007200320032d00cd063a00ed062003410f3a008007200320032d00ce063a00ee06200341103a008007200320032d00cf063a00ef06200341113a008007200320072d00003a00f006200320032d00d1063a00f106200341123a008007200341133a008007200320032d00d2063a00f206200341143a008007200320032d00d3063a00f306200341153a008007200320032d00d4063a00f406200341163a008007200320032d00d5063a00f506200341173a008007200320032d00d6063a00f606200341183a008007200320032d00d7063a00f706200341193a008007200320062d00003a00f806200320032d00d9063a00f9062003411a3a0080072003411b3a008007200320032d00da063a00fa062003411c3a008007200320032d00db063a00fb062003411d3a008007200320032d00dc063a00fc062003411e3a008007200320032d00dd063a00fd062003411f3a008007200320032d00de063a00fe06200341203a008007200320032d00df063a00ff0620034190096a41186a220120032903f80637030020034190096a41106a220220032903f00637030020034190096a41086a220620032903e806370300200320032903e006370390092006290300210e2002290300211820012903002119200329039009211d200341e0066a200841b002109d081a20034198036a411a6a201937010020034198036a41126a201837010020034198036a410a6a200e3701002003201d37019a0320034180023b019803200341e8006a200341e0066a20034198036a10ac030240024020032903684201520d0020032903704202520d010b200810354200210e0c260b200341e8006a411c6a2902002118200341e8006a41186a2802002106200810354200210e200641ff01714104460d25200641807e7121010c240b2001411c6a280200210841022106200141086a2802002107200141046a280200211b024020022d00000d0020022d00014101470d00200141186a280200211e200141146a280200211f200141106a2802002120200141026a2f010021062001410c6a2802002101200241196a2d00002113200241186a2d00002114200241166a2f01002112200241156a2d00002117200241146a2d0000210a200241126a2f0100210c200241116a2d0000210d200241106a2d0000210f2002410e6a2f010021152002410d6a2d0000211c2002410c6a2d000021102002410a6a2f01002104200241096a2d00002105200241086a2d00002111200241066a2f01002109200241056a2d00002116200241046a2d0000210b200241026a2f0100211a20032002411a6a2901003703e005200320133a00df05200320143a00de05200320123b01dc05200320173a00db052003200a3a00da052003200c3b01d8052003200d3a00d7052003200f3a00d605200320153b01d4052003201c3a00d305200320103a00d205200320043b01d005200320053a00cf05200320113a00ce05200320093b01cc05200320163a00cb052003200b3a00ca052003201a3b01c805200641ffff0371450d062001450d07200141e4004f0d08200320013602702003200736026c2003201b360268200341e0066a41186a200341c8056a41186a290300370300200341e0066a41106a200341c8056a41106a290300370300200341e0066a41086a2202200341c8056a41086a290300370300200320032903c8053703e00620034198036a200341e8006a200341e0066a10ad032003280298034101460d0920034198036a41086a2802002121200328029c032117200220034198036a410c6a280200360200200320063b01ec06200320173602e406200341fda9c3003602e006200341c0066a200341e0066a10ae03200341083a0080072003410b3a0080072003410c3a008007200320032f01c0063b01e006200320032801c2063601e206200320032d00c6063a00e606200320032800c7063600e706200320032d00cb063a00eb062003410d3a008007200320032d00cc063a00ec062003410e3a008007200320032d00cd063a00ed062003410f3a008007200320032d00ce063a00ee06200320032d00cf063a00ef06200341103a008007200341113a008007200320032d00d0063a00f006200341123a008007200320032d00d1063a00f106200341133a008007200320032d00d2063a00f206200341143a008007200320032d00d3063a00f306200341153a008007200320032d00d4063a00f406200341163a008007200320032d00d5063a00f506200341173a008007200320032d00d6063a00f606200320032d00d7063a00f706200341183a008007200341193a008007200320032d00d8063a00f8062003411a3a008007200320032d00d9063a00f9062003411b3a008007200320032d00da063a00fa062003411c3a008007200320032d00db063a00fb062003411d3a008007200320032d00dc063a00fc062003411e3a008007200320032d00dd063a00fd062003411f3a008007200320032d00de063a00fe06200341203a008007200320032d00df063a00ff0620034190096a41186a220220032903f80637030020034190096a41106a220720032903f00637030020034190096a41086a221b20032903e806370300200320032903e00637039009200341e8056a41186a2002290300370300200341e8056a41106a2007290300370300200341e8056a41086a201b29030037030020032003290390093703e805200341003602e806200342013703e0062008200341e0066a10af0320032802e406210720033502e80642208620032802e006221bad8410092202290018210e20022d0017210a20022d0016210c20022f0014210d20022d0013210f20022d0012211520022f0010211c20022d000f211020022d000e210420022f000c210520022d000b211120022d000a210920022f0008211620022d0007210b20022d0006211a20022f0004212220022d0003212320022d0002212420022f000021252002103502402007450d00201b10350b2003200e3703d8062003200a3a00d7062003200c3a00d6062003200d3b01d4062003200f3a00d306200320153a00d2062003201c3b01d006200320103a00cf06200320043a00ce06200320053b01cc06200320113a00cb06200320093a00ca06200320163b01c8062003200b3a00c7062003201a3a00c606200320223b01c406200320233a00c306200320243a00c206200320253b01c00620034198036a200341e8056a200341c0066a10b003200341e0066a200328029803220720032802a00310d302200341c0066a41086a221b200341e0066a41086a290300370300200341c0066a41106a2213200341e0066a41106a29030037030020034190096a41086a221420034188076a29030037030020034190096a41106a222620034190076a29030037030020034190096a41186a222720034198076a29030037030020034190096a41206a200341a0076a290300370300200320032903e0063703c0062003200341e0066a41206a2903003703900920032802fc062112024020032802f8062202450d00200341d8096a41106a2013290300370300200341d8096a41086a201b29030037030020034188066a41086a201429030037030020034188066a41106a202629030037030020034188066a41186a202729030037030020034188066a41206a20034190096a41206a290300370300200320032903c0063703d8092003200329039009370388060b0240200328029c03450d00200710350b02400240024002400240024020020d004101210720204101460d01200641ffff037141014b0d02200341e0066a200841b002109d081a200341a2036a200341f0056a290300370100200341aa036a200341e8056a41106a290300370100200341b2036a200341e8056a41186a29030037010020034180023b019803200320032903e80537019a03200341e8006a200341e0066a20034198036a10ac0320032903684201520d0320032003290081013703e006200320034188016a2800003600e706200341e8006a41186a2d00002106200341e8006a41106a290300210e20032903702218a70d042003418c016a28020021010c050b200341b4036a201236020020034198036a41206a20032903880637030020034198036a41106a200341d8096a41106a29030037030020034198036a41086a200341d8096a41086a290300370300200341c0036a20034188066a41086a290300370300200341c8036a20034188066a41106a290300370300200341d0036a20034188066a41186a290300370300200341d8036a20034188066a41206a290300370300200320032903d80937039803200320023602b0034101210702400240024002400240024020204101470d0020032802a803201f470d04200341ac036a280200201e470d0420032802b803222041014b0d014100210720200e020302030b2003410b36005f200341c8f1c20036005b20034181123b00580c280b410021072020211b0340201b410176221320076a22142007200220144105746a200341c8056a412010a0084101481b2107201b20136b221b41014b0d000b0b200220074105746a200341c8056a412010a008221b450d02201b411f7620076a21070b2006417f6a41ffff0371202041ffff03714b0d240c230b2003410e36005f200341baf1c20036005b20034181143b00580c240b200641ffff0371202041ffff03714d0d212003410f36005f200341aff2c20036005b20034181023b0058410121070c230b2003411336005f200341a7f1c20036005b20034181163b01584100211b4201211942002118410321060c250b200341186a2006ad42ffff038342004280a0e5b9c2910142001084082003200329031822194280c0dfda8ee9067c22183703682003200341186a41086a2903002018201954ad7c22193703702003200341c8056a3602b8092003200341c8056a36029009200320034190096a3602e8062003200341b8096a3602e4062003200341e8006a3602e00620034198036a200341c8056a200341e0066a108c03024002402003280298034101470d00200341a4036a280200210720034198036a41086a280200211b20032d009f03211320032d009e03211420032d009d03212020032d009c0321060c010b41042106024020034198036a41086a2903004201520d0020034198036a41106a290300211d200328029009210720034198076a20034198036a41186a29030037030020034190076a201d370300200341e0066a41086a41003a0000200341e9066a2007290000370000200341f1066a200741086a290000370000200341f9066a200741106a29000037000020034181076a200741186a290000370000200341033a00e00641b0b4cc004100200341e0066a10d4010b0b0240200641ff01714104470d0020034198036a41186a420037030020034198036a41106a2213420037030020034198036a41086a22074200370300200342003703980341d1c4c700ad4280808080e000841001221b290000211d200341e0066a41086a2206201b41086a2900003703002003201d3703e006201b103520072006290300370300200320032903e0063703980341e7c4c700ad4280808080e000841001221b290000211d2006201b41086a2900003703002003201d3703e006201b1035201320032903e006221d37030020034190096a41086a200729030037030020034190096a41106a201d37030020034190096a41186a2006290300370300200320032903980337039009200341106a20034190096a412010c001200328021421072003280210211b200341086a41c4c3c700411010c001200328020c21132003280208211420032f01c805212020032d00ca05211f20032d00cb05211e20032f01cc05212620032d00ce05212720032d00cf05212820032f01d005212920032d00d205212a20032d00d305212b20032f01d405212c20032d00d605212d20032d00d705212e20032f01d805212f20032d00da05213020032d00db05213120032f01dc05213220032d00de05213320032d00df05213420032903e005211d412010332206450d08200620032903c805370000200641186a200341c8056a41186a290300370000200641106a200341c8056a41106a290300370000200641086a200341c8056a41086a290300370000200341f4066a2013410020141b3602002003419c076a201d3702002003419b076a20343a00002003419a076a20333a000020034198076a20323b010020034197076a20313a000020034196076a20303a000020034194076a202f3b010020034193076a202e3a000020034192076a202d3a000020034190076a202c3b01002003418f076a202b3a00002003418e076a202a3a00002003418c076a20293b01002003418b076a20283a00002003418a076a20273a000020034188076a20263b010020034187076a201e3a000020034186076a201f3a0000200320193703e806200320183703e006200320074100201b1b3602f006200320203b018407200341fc066a428180808010370200200320063602f8062003200e3703d8062003200a3a00d7062003200c3a00d6062003200d3b01d4062003200f3a00d306200320153a00d2062003201c3b01d006200320103a00cf06200320043a00ce06200320053b01cc06200320113a00cb06200320093a00ca06200320163b01c8062003200b3a00c7062003201a3a00c606200320223b01c406200320233a00c306200320243a00c206200320253b01c00620034198036a200341e8056a200341c0066a10b0032003280298032106200320032802a00336026c20032006360268200341e0066a200341e8006a1099030240200328029c03450d00200610350b024020032802fc0641ffffff3f71450d0020032802f80610350b20034185076a20032903e805370000200341ed066a200341c8056a41086a290300370000200341f5066a200341c8056a41106a290300370000200341fd066a200341c8056a41186a2903003700002003418d076a200341e8056a41086a29030037000020034195076a200341e8056a41106a2903003700002003419d076a200341e8056a41186a290300370000200341023a00e40641012107200341013a00e006200320032903c8053700e506200341bd076a200e370000200341bc076a200a3a0000200341bb076a200c3a0000200341b9076a200d3b0000200341b8076a200f3a0000200341b7076a20153a0000200341b5076a201c3b0000200341b4076a20103a0000200341b3076a20043a0000200341b1076a20053b0000200341b0076a20113a0000200341af076a20093a0000200341ad076a20163b0000200341ac076a200b3a0000200341ab076a201a3a0000200341a9076a20223b0000200341a8076a20233a0000200341a7076a20243a0000200341a5076a20253b00004100211b41b0b4cc004100200341e0066a10d4012001ad4290a10f7e42c0c09bd8007c210e42002119420121180c250b2003200736005f2003201b36005b200320133a005a200320143a0059200320203a00584100211b4101210742012119420021180c240b420021190240024020032903704201510d00420021180c010b427f427f427f200341f8006a290300220e42808ece1c7c22182018200e541b220e2001ad4290a10f7e7c22182018200e541b220e42c0b2cd3b7c22182018200e541b210e420121180b0c1d0b427f427f427f200e42808ece1c7c22182018200e541b220e2001ad4290a10f7e7c22182018200e541b220e42c0b2cd3b7c22182018200e541b210e420121180b200320032800e70636005f200320032903e006370358420121190c1b0b200341023a00e006200341e0066a21010c180b200141286a2802002106200141246a28020021134102210820022d00000d1320022d00014101470d13200141196a290000210e200141186a2d0000211a200141176a2d00002120200141156a2f0000211f200141146a2d0000211e200141136a2d00002122200141116a2f00002123200141106a2d000021242001410f6a2d000021252001410d6a2f000021212001410c6a2d000021262001410b6a2d00002127200141096a2f00002128200141086a2d00002129200141076a2d0000212a200141056a2f0000212b200141046a2d0000212c200141036a2d0000212d2001412c6a2802002107200141386a2802002131200141346a2802002130200141306a280200212f200141226a2f0100211420012f0001212e200241196a2d00002101200241186a2d00002108200241166a2f0100211b200241156a2d00002112200241146a2d00002117200241126a2f0100210a200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210f2002410d6a2d000021152002410c6a2d0000211c2002410a6a2f01002110200241096a2d00002104200241086a2d00002105200241066a2f01002111200241056a2d00002109200241046a2d00002116200241026a2f0100210b20032002411a6a2901003703d009200320013a00cf09200320083a00ce092003201b3b01cc09200320123a00cb09200320173a00ca092003200a3b01c8092003200c3a00c7092003200d3a00c6092003200f3b01c409200320153a00c3092003201c3a00c209200320103b01c009200320043a00bf09200320053a00be09200320113b01bc09200320093a00bb09200320163a00ba092003200b3b01b809024020140d0041c0d7ca00211b410d210741032108410021020c150b41032108024020070d00418df2c200211b41112107410321020c150b0240200741e3004d0d0041fbf1c200211b41122107410421020c150b200320073602702003200636026c20032013360268200341e0066a41186a200341b8096a41186a290300370300200341e0066a41106a2202200341b8096a41106a290300370300200341e0066a41086a2201200341b8096a41086a290300370300200320032903b8093703e00620034198036a200341e8006a200341e0066a10ad0302402003280298034101460d0020034198036a41086a2802002112200328029c032113200120034198036a410c6a280200360200200320143b01ec06200320133602e406200341fda9c3003602e006200341c0066a200341e0066a10ae03200341083a0080072003410b3a0080072003410c3a008007200320032f01c0063b01e006200320032801c2063601e206200320032d00c6063a00e606200320032800c7063600e706200320032d00cb063a00eb062003410d3a008007200320032d00cc063a00ec062003410e3a008007200320032d00cd063a00ed062003410f3a008007200320032d00ce063a00ee06200320032d00cf063a00ef06200341103a008007200341113a008007200320032d00d0063a00f006200341123a008007200320032d00d1063a00f106200341133a008007200320032d00d2063a00f206200341143a008007200320032d00d3063a00f306200341153a008007200320032d00d4063a00f406200341163a008007200320032d00d5063a00f506200341173a008007200320032d00d6063a00f606200320032d00d7063a00f706200341183a008007200341193a008007200320032d00d8063a00f8062003411a3a008007200320032d00d9063a00f9062003411b3a008007200320032d00da063a00fa062003411c3a008007200320032d00db063a00fb062003411d3a008007200320032d00dc063a00fc062003411e3a008007200320032d00dd063a00fd062003411f3a008007200320032d00de063a00fe06200320032d00df063a00ff06200341203a00800720034190096a41186a220820032903f80637030020034190096a41106a220620032903f00637030020034190096a41086a220720032903e806370300200320032903e0063703900920034188066a41186a200829030037030020034188066a41106a200629030037030020034188066a41086a20072903003703002003200329039009370388062003200e3703d8062003201a3a00d706200320203a00d6062003201f3b01d4062003201e3a00d306200320223a00d206200320233b01d006200320243a00cf06200320253a00ce06200320213b01cc06200320263a00cb06200320273a00ca06200320283b01c806200320293a00c7062003202a3a00c6062003202b3b01c4062003202c3a00c3062003202d3a00c2062003202e3b01c00620034198036a20034188066a200341c0066a10b003200341e0066a200328029803221b20032802a00310d302200341c0066a41086a2001290300370300200341c0066a41106a2002290300370300200720034188076a290300370300200620034190076a290300370300200820034198076a29030037030020034190096a41206a2202200341a0076a290300370300200320032903e0063703c0062003200341e0066a41206a2903003703900920032802fc062106024020032802f8062201450d00200341e8056a41106a200341c0066a41106a290300370300200341e8056a41086a200341c0066a41086a290300370300200341e8006a41086a20034190096a41086a290300370300200341e8006a41106a20034190096a41106a290300370300200341e8006a41186a20034190096a41186a290300370300200341e8006a41206a2002290300370300200320032903c0063703e80520032003290390093703680b0240200328029c03450d00201b10350b0240024020010d004101210141032108201441014b0d01419ef2c200211b41112107410221020c140b200341b4036a200636020020034198036a41206a200329036837030020034198036a41106a200341e8056a41106a29030037030020034198036a41086a200341e8056a41086a290300370300200341c0036a200341e8006a41086a290300370300200341c8036a200341e8006a41106a290300370300200341d0036a200341e8006a41186a290300370300200341d8036a200341e8006a41206a290300370300200320032903e80537039803200320013602b0030240202f4101460d0041c8f1c200211b410b2107410921020c130b41baf1c200211b410e2107410a210220032802a8032030470d12200341ac036a2802002031470d12024020032802b80322172014490d00419ef2c200211b41112107410221020c130b410021020240201741014b0d00024020170e020010000b200341e0066a41186a200341b8096a41186a290300370300200341e0066a41106a200341b8096a41106a290300370300200341e0066a41086a200341b8096a41086a290300370300200320032903b8093703e00641002102200341e0066a21080c100b2017210803402008410176220720026a221b20022001201b4105746a200341b8096a412010a0084101481b2102200820076b220841014b0d000c0f0b0b410121010240202f4101470d0041a7f1c200211b41132107410b21020c130b200341386a2014ad42004280a0e5b9c2910142001084082003200329033822194280c0dfda8ee9067c2218370390092003200341386a41086a2903002018201954ad7c2219370398092003200341b8096a3602c8052003200341b8096a3602c0062003200341c0066a3602e8062003200341c8056a3602e406200320034190096a3602e00620034198036a200341b8096a200341e0066a108c03024002402003280298034101470d00200341a4036a280200210720034198036a41086a280200211b20032d009f03210620032d009e03210220032d009d03210120032d009c0321080c010b41042108024020034198036a41086a2903004201520d0020034198036a41106a290300211d20032802c006210120034198076a20034198036a41186a29030037030020034190076a201d370300200341e0066a41086a41003a0000200341e9066a2001290000370000200341f1066a200141086a290000370000200341f9066a200141106a29000037000020034181076a200141186a290000370000200341033a00e00641b0b4cc004100200341e0066a10d4010b0b200841ff01714104470d1320034198036a41186a420037030020034198036a41106a2206420037030020034198036a41086a22024200370300200342003703980341d1c4c700ad4280808080e0008410012208290000211d200341e0066a41086a2201200841086a2900003703002003201d3703e0062008103520022001290300370300200320032903e0063703980341e7c4c700ad4280808080e0008410012208290000211d2001200841086a2900003703002003201d3703e00620081035200620032903e006221d37030020034190096a41086a200229030037030020034190096a41106a201d37030020034190096a41186a2001290300370300200320032903980337039009200341306a20034190096a412010c0012003280234210220032802302108200341286a41c4c3c700411010c001200328022c21062003280228210720032f01b809211b20032d00ba09211420032d00bb09211720032f01bc09210a20032d00be09210c20032d00bf09210d20032f01c009210f20032d00c209211520032d00c309211c20032f01c409211020032d00c609210420032d00c709210520032f01c809211120032d00ca09210920032d00cb09211620032f01cc09210b20032d00ce09212f20032d00cf09213020032903d009211d412010332201450d03200120032903b809370000200141186a200341b8096a41186a290300370000200141106a200341b8096a41106a290300370000200141086a200341b8096a41086a290300370000200341f4066a2006410020071b3602002003419c076a201d3702002003419b076a20303a00002003419a076a202f3a000020034198076a200b3b010020034197076a20163a000020034196076a20093a000020034194076a20113b010020034193076a20053a000020034192076a20043a000020034190076a20103b01002003418f076a201c3a00002003418e076a20153a00002003418c076a200f3b01002003418b076a200d3a00002003418a076a200c3a000020034188076a200a3b010020034187076a20173a000020034186076a20143a0000200320193703e806200320183703e00620032002410020081b3602f0062003201b3b018407200341fc066a428180808010370200200320013602f8062003200e3703d8062003201a3a00d706200320203a00d6062003201f3b01d4062003201e3a00d306200320223a00d206200320233b01d006200320243a00cf06200320253a00ce06200320213b01cc06200320263a00cb06200320273a00ca06200320283b01c806200320293a00c7062003202a3a00c6062003202b3b01c4062003202c3a00c3062003202d3a00c2062003202e3b01c00620034198036a20034188066a200341c0066a10b0032003280298032101200320032802a003360294092003200136029009200341e0066a20034190096a1099030240200328029c03450d00200110350b024020032802fc0641ffffff3f71450d0020032802f80610350b20034185076a200329038806370000200341ed066a200341b8096a41086a290300370000200341f5066a200341b8096a41106a290300370000200341fd066a200341b8096a41186a2903003700002003418d076a20034188066a41086a29030037000020034195076a20034188066a41106a2903003700002003419d076a20034188066a41186a290300370000200341023a00e406200341013a00e006200320032903b8093700e506200341bd076a200e370000200341bc076a201a3a0000200341bb076a20203a0000200341b9076a201f3b0000200341b8076a201e3a0000200341b7076a20223a0000200341b5076a20233b0000200341b4076a20243a0000200341b3076a20253a0000200341b1076a20213b0000200341b0076a20263a0000200341af076a20273a0000200341ad076a20283b0000200341ac076a20293a0000200341ab076a202a3a0000200341a9076a202b3b0000200341a8076a202c3a0000200341a7076a202d3a0000200341a5076a202e3b000041b0b4cc004100200341e0066a10d4010c0f0b4200210e200328029c03220841ff01714104460d16200841187621062008411076210220084108762101200341a4036a280200210720034198036a41086a280200211b0c150b2001412c6a2802002106200141286a2802002108200141246a280200211b200141346a2802002114200141306a2802002113200141226a2f01002107200341e8056a41186a200141196a290000370300200341e8056a41106a200141116a290000370300200341e8056a41086a200141096a290000370300200320012900013703e8054102210120022d00000d0720022d00014101470d07200241196a2d00002101200241186a2d00002112200241166a2f01002117200241156a2d0000210a200241146a2d0000210c200241126a2f0100210d200241116a2d0000210f200241106a2d000021152002410e6a2f0100211c2002410d6a2d000021102002410c6a2d000021042002410a6a2f01002105200241096a2d00002111200241086a2d00002109200241066a2f01002116200241056a2d0000210b200241046a2d0000211a200241026a2f0100212020032002411a6a2901003703d009200320013a00cf09200320123a00ce09200320173b01cc092003200a3a00cb092003200c3a00ca092003200d3b01c8092003200f3a00c709200320153a00c6092003201c3b01c409200320103a00c309200320043a00c209200320053b01c009200320113a00bf09200320093a00be09200320163b01bc092003200b3a00bb092003201a3a00ba09200320203b01b8090240200741ffff03710d0041c0d7ca002107410d210641032101410021020c090b41032101024020060d00418df2c200210741112106410321020c090b0240200641e3004d0d0041fbf1c200210741122106410421020c090b200320063602702003200836026c2003201b360268200341e0066a41186a200341b8096a41186a290300370300200341e0066a41106a2202200341b8096a41106a290300370300200341e0066a41086a2201200341b8096a41086a290300370300200320032903b8093703e00620034198036a200341e8006a200341e0066a10ad0302402003280298034101460d0020034198036a41086a2802002112200328029c03211b200120034198036a410c6a280200360200200320073b01ec062003201b3602e406200341fda9c3003602e006200341c0066a200341e0066a10ae03200341083a0080072003410b3a0080072003410c3a008007200320032f01c0063b01e006200320032801c2063601e206200320032d00c6063a00e606200320032800c7063600e706200320032d00cb063a00eb062003410d3a008007200320032d00cc063a00ec062003410e3a008007200320032d00cd063a00ed062003410f3a008007200320032d00ce063a00ee06200320032d00cf063a00ef06200341103a008007200341113a008007200320032d00d0063a00f006200341123a008007200320032d00d1063a00f106200341133a008007200320032d00d2063a00f206200341143a008007200320032d00d3063a00f306200341153a008007200320032d00d4063a00f406200341163a008007200320032d00d5063a00f506200341173a008007200320032d00d6063a00f606200320032d00d7063a00f706200341183a008007200341193a008007200320032d00d8063a00f8062003411a3a008007200320032d00d9063a00f9062003411b3a008007200320032d00da063a00fa062003411c3a008007200320032d00db063a00fb062003411d3a008007200320032d00dc063a00fc062003411e3a008007200320032d00dd063a00fd062003411f3a008007200320032d00de063a00fe06200320032d00df063a00ff06200341203a00800720034190096a41186a220820032903f80637030020034190096a41106a220620032903f00637030020034190096a41086a220720032903e806370300200320032903e0063703900920034188066a41186a200829030037030020034188066a41106a200629030037030020034188066a41086a20072903003703002003200329039009370388062003200341e8056a41186a2903003703d8062003200341e8056a41106a2903003703d0062003200341e8056a41086a2903003703c806200320032903e8053703c006200341900a6a20034188066a200341c0066a10b003200341e0066a20032802900a221720032802980a10d302200341c0066a41086a2001290300370300200341c0066a41106a2002290300370300200720034188076a290300370300200620034190076a290300370300200820034198076a29030037030020034190096a41206a2202200341a0076a290300370300200320032903e0063703c0062003200341e0066a41206a2903003703900902400240024020032802f8062201450d0020032802fc062108200341f8096a41106a2206200341c0066a41106a290300370300200341f8096a41086a2207200341c0066a41086a290300370300200341e8006a41086a220a20034190096a41086a290300370300200341e8006a41106a220c20034190096a41106a290300370300200341e8006a41186a220d20034190096a41186a290300370300200341e8006a41206a2002290300370300200320032903c0063703f8092003200329039009370368024020032802940a450d00201710350b200341c8056a41166a2006290300220e370100410e2106200341c8056a410e6a2007290300370100200341d8096a41166a2202200e370100200341d8096a41106a200341c8056a41106a290100370300200320032903f8093701ce05200341d8096a41086a200341c8056a41086a290100370300200320032901c8053703d80920034198036a41106a2217200229010037030020034198036a41086a200341d8096a410e6a290100370300200320032901de0937039803200341b4036a2008360200200320013602b003200341d8036a200341e8006a41206a290300370300200341d0036a200d290300370300200341c8036a200c290300370300200341c0036a200a29030037030020034198036a41206a200329036837030041baf1c2002107410a2102024020172802002013470d00200341ac036a2802002014470d00200341bc036a2202200341b8096a412010a008450d0341fbb5c300210741082102410821060b200841ffffff3f71450d01200110350c010b024020032802940a450d00201710350b41d0b9c300210741082106410721020b0240201241ffffff3f71450d00201b10350b41002108418002211b410321010c0b0b200329039803210e200320034198036a41086a2903002218370398092003200e370390090240200e201884500d00200320023602c006200341e8006a200220034190096a200341c0066a10f00220032903684201520d002003290370210e20034198076a200341e8006a41106a29030037030020034190076a200e370300200341e0066a41086a41003a0000200341e9066a2002290000370000200341f1066a200241086a290000370000200341f9066a200241106a29000037000020034181076a200241186a290000370000200341033a00e00641b0b4cc004100200341e0066a10d4010b200341c0066a41186a200341e8056a41186a2201290300370300200341c0066a41106a200341e8056a41106a2202290300370300200341c0066a41086a200341e8056a41086a290300370300200320032903e8053703c006200341e0066a20034188066a200341c0066a10b00320033502e80642208620032802e0062208ad841007024020032802e406450d00200810350b20034185076a200329038806370000200341ed066a200341b8096a41086a290300370000200341f5066a200341b8096a41106a290300370000200341fd066a200341b8096a41186a2903003700002003418d076a20034188066a41086a29030037000020034195076a20034188066a41106a2903003700002003419d076a20034188066a41186a290300370000200341053a00e406200341013a00e006200320032903b8093700e506200341c8076a2013360200200341cc076a2014360200200341bd076a2001290300370000200341b5076a2002290300370000200341ad076a200341e8056a41086a290300370000200341a5076a20032903e80537000041b0b4cc004100200341e0066a10d401024020032802b40341ffffff3f71450d0020032802b00310350b0240201241ffffff3f71450d00201b10350b4200210e0c0b0b4200210e200328029c03220141ff01714104460d0a2001418080807871210820014110762102200141807e71211b200341a4036a280200210620034198036a41086a28020021070c090b1045000b103c000b200810ba0220081035410021010c1e0b200341e8066a410d360200200341c0d7ca003602e406200341003a00e20620034183023b01e006200341e0066a2101410321060c120b200341e8066a41113602002003418df2c2003602e40641032106200341033a00e20620034183023b01e006200341e0066a21010c110b200341e8066a4112360200200341fbf1c2003602e406200341043a00e20620034183023b01e006200341e0066a2101410321060c100b2003200329009d033703582003200341a4036a28000036005f20032d009c032106200810ba0220081035420021180c100b0b0240200841ffffff3f71450d00201b10350b41002108418002211b0b200041206a20063602002000411c6a2007360200200041186a2008200241ff017141107472201b4180fe037172200141ff0171723602004201210e0b2000200e370300200042003703080c1a0b0240200120024105746a200341b8096a412010a00822070d0041aff2c200211b410f2107410121020c040b200341e0066a41186a200341b8096a41186a290300370300200341e0066a41106a200341b8096a41106a290300370300200341e0066a41086a200341b8096a41086a290300370300200320032903b8093703e006200341e0066a210820172007411f7620026a2202490d020b024020172006470d0020034198036a41186a20064101108a0120032802b00321010b200120024105746a220141206a2001201720026b410574109e081a200141186a200841186a290000370000200141106a200841106a290000370000200141086a200841086a290000370000200120082900003700002003201741016a3602b803200341e0066a20034198036a41c800109d081a2003200e3703d8062003201a3a00d706200320203a00d6062003201f3b01d4062003201e3a00d306200320223a00d206200320233b01d006200320243a00cf06200320253a00ce06200320213b01cc06200320263a00cb06200320273a00ca06200320283b01c806200320293a00c7062003202a3a00c6062003202b3b01c4062003202c3a00c3062003202d3a00c2062003202e3b01c00620034190096a20034188066a200341c0066a10b003200328029009210120032003280298093602c406200320013602c006200341e0066a200341c0066a1099030240200328029409450d00200110350b0240200341fc066a28020041ffffff3f71450d0020032802f80610350b20034185076a200329038806370000200341ed066a200341b8096a41086a290300370000200341f5066a200341b8096a41106a290300370000200341fd066a200341b8096a41186a2903003700002003418d076a20034188066a41086a29030037000020034195076a20034188066a41106a2903003700002003419d076a20034188066a41186a290300370000200341033a00e406200341013a00e006200320032903b8093700e506200341cc076a2031360200200341c8076a2030360200200341bd076a200e370000200341bc076a201a3a0000200341bb076a20203a0000200341b9076a201f3b0000200341b8076a201e3a0000200341b7076a20223a0000200341b5076a20233b0000200341b4076a20243a0000200341b3076a20253a0000200341b1076a20213b0000200341b0076a20263a0000200341af076a20273a0000200341ad076a20283b0000200341ac076a20293a0000200341ab076a202a3a0000200341a9076a202b3b0000200341a8076a202c3a0000200341a7076a202d3a0000200341a5076a202e3b000041b0b4cc004100200341e0066a10d4010b0240201241ffffff3f71450d00201310350b4200210e0c070b20022017104d000b0240200641ffffff3f71450d00200110350b41032108410121010b0b201241ffffff3f71450d02201310350c020b0b410121010240200641ffffff3f710d000c010b201310350b200041206a20073602002000411c6a201b360200200041186a2006411874200241ff017141107472200141ff017141087472200841ff0171723602004201210e0b2000200e370300200042003703080c0f0b200320012900013703582003200141086a28000036005f200810ba022008103542002118200741ffffff3f71450d00201b10350b0c080b410021074100211b0c060b200341e0066a200841b002109d081a200341f2006a200341e8056a41086a290300370100200341fa006a200341f8056a29030037010020034182016a20034180066a29030037010020034180023b0168200320032903e80537016a20034190096a200341e0066a200341e8006a10ac032003290398032118200320034198036a41086a29030022193703c009200320183703b80902402018201984500d002003200341bc036a22013602c006200341e8006a2001200341b8096a200341c0066a10f00220032903684201520d002003290370211820034198076a200341e8006a41106a29030037030020034190076a2018370300200341e0066a41086a41003a0000200341e9066a2001290000370000200341f1066a200141086a290000370000200341f9066a200141106a29000037000020034181076a200141186a290000370000200341033a00e00641b0b4cc004100200341e0066a10d4010b2003200e3703d8062003200a3a00d7062003200c3a00d6062003200d3b01d4062003200f3a00d306200320153a00d2062003201c3b01d006200320103a00cf06200320043a00ce06200320053b01cc06200320113a00cb06200320093a00ca06200320163b01c8062003200b3a00c7062003201a3a00c606200320223b01c406200320233a00c306200320243a00c206200320253b01c006200341e0066a200341e8056a200341c0066a10b00320033502e80642208620032802e0062201ad841007024020032802e406450d00200110350b200341e8006a41186a200341c8056a41186a290300370300200341e8006a41106a200341c8056a41106a290300370300200341e8006a41086a200341c8056a41086a290300370300200320032903c805370368200341e0066a41186a200341e8056a41186a290300370300200341e0066a41106a200341e8056a41106a290300370300200341e0066a41086a200341e8056a41086a290300370300200320032903e8053703e00620034190096a41186a2d0000210620032903980921192003290390092118200320032900a9093703b8092003200341b0096a2800003600bf090240024020184201510d00410421010c010b200320032800bf093600ff09200320032903b8093703f8094104210120194202510d00200320032800ff093600970a200320032903f8093703900a200621010b200341b8096a41086a2206200341e8006a41086a290300370300200341b8096a41106a2207200341e8006a41106a290300370300200341b8096a41186a221b200341e8006a41186a290300370300200341c0066a41086a2213200341e0066a41086a290300370300200341c0066a41106a2214200341e0066a41106a290300370300200341c0066a41186a2220200341e0066a41186a290300370300200320032903683703b809200320032903e0063703c006200320032800970a3600b706200320032903900a3703b006200341ed066a2006290300370000200341f5066a2007290300370000200341fd066a201b29030037000020034185076a20032903c0063700002003418d076a201329030037000020034195076a20142903003700002003419d076a2020290300370000200341043a00e406200341013a00e006200320032903b8093700e506200341bd076a200e370000200341bc076a200a3a0000200341bb076a200c3a0000200341b9076a200d3b0000200341b8076a200f3a0000200341b7076a20153a0000200341b5076a201c3b0000200341b4076a20103a0000200341b3076a20043a0000200341b1076a20053b0000200341b0076a20113a0000200341af076a20093a0000200341ad076a20163b0000200341ac076a200b3a0000200341ab076a201a3a0000200341a9076a20223b0000200341a8076a20233a0000200341a7076a20243a0000200341a5076a20253b0000200341d0076a20013a0000200341cc076a201e360200200341c8076a201f360200200341c7076a200341c6056a2d00003a0000200341c5076a20032f00c4053b0000200341d8076a20032800b706360000200341d1076a20032903b0063700004100210741b0b4cc004100200341e0066a10d4014200211920032802b40321010c020b200341e0066a41186a200341c8056a41186a290300370300200341e0066a41106a200341c8056a41106a290300370300200341e0066a41086a200341c8056a41086a290300370300200320032903c8053703e006024020202007490d0020022106024020202012470d0020034198036a41186a20124101108a0120032802b00321060b200620074105746a220641206a2006202020076b410574109e081a200641186a200341e0066a41186a290300370000200641106a200341e0066a41106a290300370000200641086a200341e0066a41086a290300370000200620032903e0063700002003202041016a3602b803200341e0066a20034198036a41c800109d081a2003200e3703d8062003200a3a00d7062003200c3a00d6062003200d3b01d4062003200f3a00d306200320153a00d2062003201c3b01d006200320103a00cf06200320043a00ce06200320053b01cc06200320113a00cb06200320093a00ca06200320163b01c8062003200b3a00c7062003201a3a00c606200320223b01c406200320233a00c306200320243a00c206200320253b01c006200341e8006a200341e8056a200341c0066a10b0032003280268210620032003280270360294092003200636029009200341e0066a20034190096a1099030240200328026c450d00200610350b0240200341fc066a28020041ffffff3f71450d0020032802f80610350b20034185076a20032903e805370000200341ed066a200341c8056a41086a290300370000200341f5066a200341c8056a41106a290300370000200341fd066a200341c8056a41186a2903003700002003418d076a200341e8056a41086a29030037000020034195076a200341e8056a41106a2903003700002003419d076a200341e8056a41186a290300370000200341033a00e40641012107200341013a00e006200320032903c8053700e506200341cc076a201e360200200341c8076a201f360200200341bd076a200e370000200341bc076a200a3a0000200341bb076a200c3a0000200341b9076a200d3b0000200341b8076a200f3a0000200341b7076a20153a0000200341b5076a201c3b0000200341b4076a20103a0000200341b3076a20043a0000200341b1076a20053b0000200341b0076a20113a0000200341af076a20093a0000200341ad076a20163b0000200341ac076a200b3a0000200341ab076a201a3a0000200341a9076a20223b0000200341a8076a20233a0000200341a7076a20243a0000200341a5076a20253b000041b0b4cc004100200341e0066a10d4012001ad4290a10f7e42c0c09bd8007c210e42002119420121180c030b20072020104d000b42012119201221010b420021180240200141ffffff3f710d000c010b20032802b00310350b4101211b410321060b0b0240202141ffffff3f71450d00201710350b0240201241ffffff3f71450d00200245201b720d00200210350b02402007450d00200810ba020b20081035201950450d0020002018370308200041106a200e370300200042003703000c050b2003200328005f36004f20032003290358370348200041186a20063a0000200041106a200e3703002000201837030820002003290348370019200041206a200328004f360000200041246a2001360200200042013703000c040b2000411c6a2018370200200041186a2001200641ff0171723602004201210e0b2000200e370300200042003703080c020b024020082001460d000340200110bb022008200141b0026a2201470d000b0b02402009450d00200941b0026c450d00200510350b200341013a00e406200341013a00e00641b0b4cc004100200341e0066a10d4010b20004200370300200041086a42003703000b200341a00a6a24000bebca010a017f017e017f017e017f017e057f017e287f0c7e230041f0116b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1b010200030405060708090a0b0c0d0e0f1011121300000014151617010b000b20034198066a41086a200141106a2903003703002003200141086a29030037039806200341a80b6a41206a200241206a290200370300200341a80b6a41186a200241186a290200370300200341a80b6a41106a200241106a290200370300200341a80b6a41086a200241086a290200370300200320022902003703a80b200020034198066a200341a80b6a1085060c280b200341e00b6a2001413c6a280200360200200341d80b6a200141346a290200370300200341d00b6a2001412c6a290200370300200341a80b6a41206a200141246a290200370300200341a80b6a41186a2001411c6a290200370300200341a80b6a41106a200141146a290200370300200341a80b6a41086a2001410c6a290200370300200320012902043703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a10ab030c270b0240024020022d00000d0020022d000141ff01714102470d00200141086a2903002104200341a80b6a41186a22054200370300200341a80b6a41106a22014200370300200341a80b6a41086a22024200370300200342003703a80b41d1efcb00ad42808080809001842206100122072900002108200341a0116a41086a2209200741086a290000370300200320083703a0112007103520022009290300370300200320032903a0113703a80b41daefcb00ad42808080809001841001220a2900002108200341f8106a41086a2207200a41086a290000370300200320083703f810200a1035200120032903f810220837030020034198066a41086a220b200229030037030020034198066a41106a220c200837030020034198066a41186a220d2007290300370300200320032903a80b37039806200341186a20034198066a412041b0b4cc0041004100108a0220032802184101460d16200542003703002001420037030020024200370300200342003703a80b20061001220a29000021062009200a41086a290000370300200320063703a011200a103520022009290300370300200320032903a0113703a80b41ebc3c400ad4280808080308422061001220929000021082007200941086a290000370300200320083703f81020091035200120032903f810370000200141086a2007290300370000200b2002290300370300200c2001290300370300200d2005290300370300200320032903a80b37039806200341086a20034198066a10e1022003290310220842dc0b7c2004580d012008500d012003280208450d0141beebc40041ce0041c086cc00103f000b20004200370308200041186a4102360200200042013703000c270b200341a80b6a41186a22094200370300200341a80b6a41106a22074200370300200341a80b6a41086a22024200370300200342003703a80b41d1efcb00ad428080808090018422081001220a290000210e200341a0116a41086a2205200a41086a2900003703002003200e3703a011200a103520022005290300370300200320032903a0113703a80b20061001220b2900002106200341f8106a41086a220a200b41086a290000370300200320063703f810200b1035200120032903f810370000200141086a220c200a29030037000020034198066a41086a220d200229030037030020034198066a41106a220f200729030037030020034198066a41186a22102009290300370300200320032903a80b37039806200320043703a80b20034198066aad42808080808004842204200341a80b6aad42808080808001841002200942003703002007420037030020024200370300200342003703a80b20081001220b29000021062005200b41086a290000370300200320063703a011200b103520022005290300370300200320032903a0113703a80b41daefcb00ad4280808080900184100122052900002106200a200541086a290000370300200320063703f81020051035200120032903f810370000200c200a290300370000200d2002290300370300200f200729030037030020102009290300370300200320032903a80b37039806200341013a00d00f2004200341d00f6aad42808080801084100220004200370308200042003703000c260b200341b00b6a2001410c6a280200360200200320012902043703a80b2000200341a80b6a20022d000020022d00011086060c250b20034198066a41206a200141246a29020037030020034198066a41186a2001411c6a29020037030020034198066a41106a200141146a29020037030020034198066a41086a2001410c6a2902003703002003200129020437039806200341a80b6a41206a200241206a290200370300200341a80b6a41186a200241186a290200370300200341a80b6a41106a200241106a290200370300200341a80b6a41086a200241086a290200370300200320022902003703a80b200020034198066a200341a80b6a10b1040c240b200341a80b6a200141086a41e000109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1087030c230b200341a80b6a200141086a418802109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1089020c220b200341a80b6a200141046a418c01109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1087060c210b200341a80b6a41306a200141386a290300370300200341a80b6a41286a200141306a290300370300200341a80b6a41206a200141286a290300370300200341a80b6a41186a200141206a290300370300200341a80b6a41106a200141186a290300370300200341a80b6a41086a200141106a2903003703002003200141086a2903003703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a108b050c200b200341d00b6a2001412c6a290200370300200341a80b6a41206a200141246a290200370300200341a80b6a41186a2001411c6a290200370300200341a80b6a41106a200141146a290200370300200341a80b6a41086a2001410c6a290200370300200320012902043703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1088060c1f0b200341d00b6a2001412c6a290200370300200341a80b6a41206a200141246a290200370300200341a80b6a41186a2001411c6a290200370300200341a80b6a41106a200141146a290200370300200341a80b6a41086a2001410c6a290200370300200320012902043703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1089060c1e0b20034198066a41206a200141286a29030037030020034198066a41186a200141206a29030037030020034198066a41106a200141186a29030037030020034198066a41086a200141106a2903003703002003200141086a29030037039806200341a80b6a41206a200241206a290200370300200341a80b6a41186a200241186a290200370300200341a80b6a41106a200241106a290200370300200341a80b6a41086a200241086a290200370300200320022902003703a80b200020034198066a200341a80b6a1089030c1d0b200341a80b6a200141046a41c400109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a108a060c1c0b4102210741002109024002400240024020022d0000450d000c010b20022d000141ff01714102470d0020012802042105200341a80b6a41186a4200370300200341a80b6a41106a22074200370300200341a80b6a41086a22014200370300200342003703a80b41bee4cb00ad4280808080f00184100122092900002104200341c00a6a41086a2202200941086a290000370300200320043703c00a2009103520012002290300370300200320032903c00a3703a80b418cc0c700ad4280808080e000841001220929000021042002200941086a290000370300200320043703c00a20091035200720032903c00a2204370300200341d00f6a41086a2001290300370300200341d00f6a41106a2004370300200341d00f6a41186a2002290300370300200320032903a80b3703d00f41002109200341286a200341d00f6a412041b0b4cc0041004100108a020240024020032802284101470d00410e210541d0b8c700210a0c010b200341d8106a41186a4200370300200341d8106a41106a220a4200370300200341d8106a41086a22024200370300200342003703d81041d1c4c700ad4280808080e000841001220929000021042002200941086a290000370300200320043703d8102009103541e7c4c700ad4280808080e000841001220929000021042001200941086a290000370300200320043703a80b20091035200a20032903a80b2204370300200341b8106a41086a2002290300370300200341b8106a41106a2004370300200341b8106a41186a2001290300370300200320032903d8103703b810200341206a200341b8106a412010c0012003280224410020032802201b20054f0d024107210541e8b8c700210a4180800421090b410321070b200041206a20053602002000411c6a200a360200200041186a2009418080047120077241801e72360200420121040c010b42002104200341a80b6a41186a220a4200370300200341a80b6a41106a220b4200370300200341a80b6a41086a22024200370300200342003703a80b41bee4cb00ad4280808080f00184100122092900002106200341c00a6a41086a2201200941086a290000370300200320063703c00a2009103520022001290300370300200320032903c00a3703a80b418cc0c700ad4280808080e000841001220929000021062001200941086a290000370300200320063703c00a20091035200720032903c00a370000200741086a2001290300370000200341d00f6a41086a2002290300370300200341d00f6a41106a200b290300370300200341d00f6a41186a200a290300370300200320032903a80b3703d00f200320053602a80b200341d00f6aad4280808080800484200341a80b6aad4280808080c0008410020b20002004370300200042003703080c1b0b200141086a280200210920012802042101024020022d00000d0020022d000141ff01714101470d0002402009450d00200110350b20004200370308200042003703000c1b0b02402009450d00200110350b20004200370308200041186a4102360200200042013703000c1a0b200341a80b6a41386a200141c0006a290300370300200341a80b6a41306a200141386a290300370300200341a80b6a41286a200141306a290300370300200341a80b6a41206a200141286a290300370300200341a80b6a41186a200141206a290300370300200341a80b6a41106a200141186a290300370300200341a80b6a41086a200141106a2903003703002003200141086a2903003703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a108b060c190b20014180016a2802002111200141d0006a2903002106200141346a2d00002112200141306a2d0000210f2001412c6a2d00002113200141086a2d0000210920012f0036211420012d0035211520012f0032211020012d0031211620012f002e211720012d002d211820012f002a211920012d0029211a20034194026a41026a221b2001410b6a2d00003a000020034180026a41086a2205200141206a29000037030020034180026a41106a220a200141286a2d00003a0000200341e8016a41086a221c200141c0006a290300370300200341e8016a41106a221d200141c8006a290300370300200320012f00093b0194022003200141186a290000370380022003200141386a2903003703e8012001410c6a2800002107200141106a280000210b200141146a280000210c200341c0016a41206a221e200141f8006a290300370300200341c0016a41186a221f200141f0006a290300370300200341c0016a41106a2220200141e8006a290300370300200341c0016a41086a2221200141e0006a290300370300200341a0016a41186a22222001419c016a280200360200200341a0016a41106a222320014194016a290200370300200341a0016a41086a22242001418c016a2902003703002003200141d8006a2903003703c001200320014184016a2902003703a0012002411a6a2901002104200241196a2d00002125200241186a2d00002126200241166a2f01002127200241156a2d00002128200241146a2d00002129200241126a2f0100212a200241116a2d0000212b200241106a2d0000212c2002410e6a2f0100212d2002410d6a2d0000212e2002410c6a2d0000212f2002410a6a2f01002130200241096a2d00002131200241086a2d00002132200241066a2f01002133200241056a2d00002134200241046a2d00002135200241026a2f0100213620022d0001210d20022d0000210102400240024002400240024020090e06000102030405000b200341a80b6a41146a4101360200200342013702ac0b200341e8d4ca003602a80b2003410436029c062003419cd5ca0036029806200320034198066a3602b80b200341a80b6a41b0b4cc00104c000b200341c8046a41086a2005290300370300200341c8046a41106a200a2d00003a000020034188036a41086a201c29030037030020034188036a41106a201d29030037030020034198066a41086a202129030037030020034198066a41106a202029030037030020034198066a41186a201f29030037030020034198066a41206a201e29030037030020032003290380023703c804200320032903e80137038803200320032903c00137039806200341800e6a41186a2022280200360200200341800e6a41106a2023290300370300200341800e6a41086a2024290300370300200320032903a0013703800e024002400240200d200141ff01714100477241ff01710d00200341f0086a41186a22054200370300200341f0086a41106a22094200370300200341f0086a41086a22024200370300200342003703f00841f1d8cb00ad42808080809001842208100122072900002104200341c00a6a41086a2201200741086a290000370300200320043703c00a2007103520022001290300370300200320032903c00a3703f00841e2d8cb00ad4280808080f00184220e1001220729000021042001200741086a290000370300200320043703c00a20071035200920032903c00a2204370300200341b8026a41086a22072002290300370300200341b8026a41106a220a2004370300200341b8026a41186a220d2001290300370300200320032903f0083703b802200341a80b6a200341b8026a10da020240410020032802980c20032d00b00c4102461b2011490d0041832421010c020b200341b40b6a2011360200200341a80b6a41086a41053a00002003410d3a00a80b41b0b4cc004100200341a80b6a10d401200341a80b6a41106a200341c8046a41086a290300370300200341a80b6a41186a200341c8046a41106a2d00003a00002003200c3602ac0b2003200b3602a80b200320032903c8043703b00b200320143b01ce0b200320153a00cd0b200320123a00cc0b200320103b01ca0b200320163a00c90b2003200f3a00c80b200320173b01c60b200320183a00c50b200320133a00c40b200320193b01c20b2003201a3a00c10b200341e00b6a20034188036a41106a290300370300200341d80b6a20034188036a41086a290300370300200341f80b6a20034198066a41086a290300370300200341800c6a20034198066a41106a290300370300200341880c6a20034198066a41186a290300370300200341900c6a200341b8066a290300370300200320063703e80b200320113602980c20032003290388033703d00b20032003290398063703f00b200341b40c6a200341800e6a41186a280200360200200341ac0c6a200341800e6a41106a290300370200200341a40c6a200341800e6a41086a290300370200200320032903800e37029c0c200542003703002009420037030020024200370300200342003703f00820081001220b29000021042001200b41086a290000370300200320043703c00a200b103520022001290300370300200320032903c00a3703f008200e1001220b29000021042001200b41086a290000370300200320043703c00a200b1035200920032903c00a370000200941086a200129030037000020072002290300370300200a2009290300370300200d2005290300370300200320032903f0083703b802200341003602f808200342013703f008200341a80b6a200341f0086a10f30520032802f4082101200341b8026aad428080808080048420033502f80842208620032802f0082202ad84100202402001450d00200210350b420021040c020b41822421010b200041206a41163602002000411c6a41bcffc600360200200041186a2001360200420121040b20004200370308200020043703000c1c0b024002400240200141ff01710d00200d41ff01714101470d00200341f0086a41186a420037030041102105200341f0086a41106a220a4200370300200341f0086a41086a22024200370300200342003703f00841f1d8cb00ad4280808080900184100122092900002104200341c00a6a41086a2201200941086a290000370300200320043703c00a2009103520022001290300370300200320032903c00a3703f00841e2d8cb00ad4280808080f001841001220929000021042001200941086a290000370300200320043703c00a20091035200a20032903c00a2204370300200341b8026a41086a2002290300370300200341b8026a41106a2004370300200341b8026a41186a2001290300370300200320032903f0083703b802200341a80b6a200341b8026a10da0220032903a80b210420032903b00b210620032903b80b210820032903c00b210e20032903c80b213720032903d00b213820032903d80b213920032903e00b213a20032903e80b213b20032903f00b213c20032903f80b213d20032903800c213e20032903880c213f20032903900c214020032802980c210f200328029c0c210220032802a00c210920032802a40c211020032802a80c210a20032802ac0c210d20032d00b00c21012003200341a80b6a418c016a2800003600f308200320032800b10c3602f0080240024020014102470d0020034280c2d72f3703800720034280e1eb173703f806200342a0c21e3703f006200342a0c21e3703e806200342e0ef97203703e006200342e0c9dc293703d806200342e0ef97203703d006200342a0c21e3703c806200342a0c21e3703c006200342a0c21e3703b806200342a0c21e3703b006200342a0c21e3703a806200342a0c21e3703a006200342a0c21e370398064100210120034100360288074120210d41808001210a418080042109410421020c010b20034198066a418c016a20032800f3083600002003200f3602880720032040370380072003203f3703f8062003203e3703f0062003203d3703e8062003203c3703e0062003203b3703d8062003203a3703d006200320393703c806200320383703c006200320373703b8062003200e3703b006200320083703a806200320063703a0062003200437039806200320032802f0083600a107201021050b200320013a00a0072003200d36029c072003200a36029807200320053602940720032009360290072003200236028c07200341a80b6a2007200c20034198066a108c06024020032802a80b4101460d00200341800e6a41186a2202200341a80b6a410472220141186a280200360200200341800e6a41106a2209200141106a290200370300200341800e6a41086a220d200141086a290200370300200320012902003703800e200341c00a6a41026a220f200cad4220862007ad841009220141026a2d00003a0000200128000321052001280007210a20012f00002110200341c8046a410d6a2216200141186a290000370000200341c8046a41086a221b200141136a290000370300200320103b01c00a2003200129000b3703c80420011035200341a80b6a41186a2002280200360200200341a80b6a41106a2009290300370300200341a80b6a41086a200d290300370300200320032903800e3703a80b200341d00f6a41026a2202200f2d00003a000020034188036a41086a2209201b29030037030020034188036a410d6a220d2016290000370000200320032f01c00a3b01d00f200320032903c8043703880341f1d8cb00ad4280808080900184100122012900002104200341a0116a41086a200141086a290000370300200320043703a0112001103541a0e0c600ad4280808080b00184100122012900002104200341f8106a41086a200141086a290000370300200320043703f81020011035412010332201450d0e200120032f01d00f3b00002001200a36000720012005360003200120032903880337000b200141026a20022d00003a0000200141136a2009290300370000200141186a200d290000370000412010332202450d0e20022001290000370000200241186a2209200141186a290000370000200241106a220d200141106a290000370000200241086a220f200141086a2900003700002001103541c00010332201450d0e200120032903f810370010200120032903a011370000200141086a200341a0116a41086a290300370000200141186a200341f8106a41086a29030037000020012002290000370020200141286a200f290000370000200141306a200d290000370000200141386a20092900003700002002103520034100360290032003420137038803200341a80b6a20034188036a10e201200341a80b6a41047220034188036a10e201200341a80b6a41086a20034188036a10e201200320032d00c00b220d3a00d00f02400240200328028c032003280290032202460d0020032802880321090c010b200241016a22092002490d112002410174220d2009200d20094b1b220d4100480d110240024020020d00410021020240200d0d00410121090c020b200d103322090d010c230b20032802880321092002200d460d0020092002200d10372209450d220b2003200d36028c03200320093602880320032d00d00f210d0b200920026a200d3a00002003200241016a3602900320032802b40b2116200341bc0b6a280200220220034188036a107702400240200328028c032210200328029003220d6b2002490d0020032802880321092010210f0c010b200d20026a2209200d490d112010410174220f2009200f20094b1b220f4100480d110240024020100d000240200f0d00410121090c020b200f10332209450d230c010b20032802880321092010200f460d0020092010200f10372209450d220b2003200f36028c0320032009360288030b2009200d6a20162002109d081a2001ad4280808080800884200d20026aad4220862009ad8410020240200f450d00200910350b200110350240200341b80b6a280200450d00201610350b20034188036a41026a2202200341c00a6a41026a2d00003a0000200341a80b6a41086a2209200341c8046a41086a290300370300200341a80b6a410d6a220d200341c8046a410d6a290000370000200320032f01c00a3b018803200320032903c8043703a80b41f1d8cb00ad4280808080900184100122012900002104200341a0116a41086a200141086a290000370300200320043703a011200110354194e0c600ad4280808080c00184100122012900002104200341f8106a41086a200141086a290000370300200320043703f81020011035412010332201450d0e200120032f0188033b00002001200a36000720012005360003200120032903a80b37000b200141026a20022d00003a0000200141136a2009290300370000200141186a2209200d290000370000412010332202450d0e20022001290000370000200241186a2009290000370000200241106a2209200141106a290000370000200241086a220d200141086a2900003700002001103541c00010332201450d0e200120032903f810370010200120032903a011370000200141086a200341a0116a41086a290300370000200141186a200341f8106a41086a29030037000020012002290000370020200141286a200d290000370000200141306a2009290000370000200141386a200241186a29000037000020021035200341c0003602ac0b200320013602a80b2007200c200341a80b6a109403200110350240200b450d00200710350b200341d8106a41026a200341c00a6a41026a2d000022013a0000200341f0086a41086a2202200341c8046a41086a290300370300200341f0086a410d6a2209200341c8046a410d6a290000370000200320032f01c00a22073b01d810200320032903c8043703f008200341a80b6a41086a41043a0000200341b10b6a20073b0000200341b30b6a20013a0000200341b80b6a200a360200200341b40b6a20053602002003410d3a00a80b200341bc0b6a20032903f008370200200341c40b6a2002290300370200200341c90b6a200929000037000041b0b4cc004100200341a80b6a10d401420021040c030b200341b00b6a350200210420033502ac0b21060240200b450d00200710350b20044220862006842104410021010c010b410221010240200b450d00200710350b0b2000411c6a2004370200200041186a2001360200420121040b20004200370308200020043703000c1b0b201d290300210820032903f001210e20032802e8012109200341a0116a41106a200a2d00003a0000200341a0116a41086a200529030037030020032003290380023703a0112016410874200f72201041107472210202400240200141ff01710d00200d41ff01714101470d00200320043701e80f200320253a00e70f200320263a00e60f200320273b01e40f200320283a00e30f200320293a00e20f2003202a3b01e00f2003202b3a00df0f2003202c3a00de0f2003202d3b01dc0f2003202e3a00db0f2003202f3a00da0f200320303b01d80f200320313a00d70f200320323a00d60f200320333b01d40f200320343a00d30f200320353a00d20f200320363b01d00f200341a80b6a41086a2201200c360200200341b40b6a20032903a011370200200341bc0b6a200341a0116a41086a290300370200200341c40b6a200341a0116a41106a2d00003a0000200341ca0b6a20173b0100200341c90b6a20183a0000200341c80b6a20133a0000200341c60b6a20193b0100200341c50b6a201a3a00002003200b3602ac0b200320073602a80b20034198066a200341a80b6a108b02200341800e6a41086a2207200341a1066a290000370300200341800e6a41106a2205200341a9066a290000370300200341800e6a41186a220a200341b1066a29000037030020032003290099063703800e20032d0098064101470d01410121072015410874201272201441107472450d190c180b4102210720154108742012722014411074720d170c180b200341b8026a41086a220b2007290300370300200341b8026a41106a22072005290300370300200341b8026a41186a2205200a290300370300200320032903800e3703b8022003200637038011200320063703f810200341c8046a41186a200341d00f6a41186a290100370300200341c8046a41106a200341d00f6a41106a290100370300200341c8046a41086a200341d00f6a41086a290100370300200320032901d00f3703c80420034188036a41186a200529030037030020034188036a41106a200729030037030020034188036a41086a200b290300370300200320032903b802370388032003200341f8106a3602b805200341d8106a41186a4200370300200341d8106a41106a22074200370300200341d8106a41086a22054200370300200342003703d81041f1d8cb00ad42808080809001841001220a29000021042005200a41086a290000370300200320043703d810200a103541e2d8cb00ad4280808080f001841001220a29000021042001200a41086a290000370300200320043703a80b200a1035200720032903a80b2204370300200341b8106a41086a2005290300370300200341b8106a41106a2004370300200341b8106a41186a2001290300370300200320032903d8103703b810200341a80b6a200341b8106a10da0220032903a80b210420032903b00b210620032903b80b213720032903c00b213820032903c80b213920032903d00b213a20032903d80b213b20032903e00b213c20032903e80b213d20032903f00b213e20032903f80b213f20032903800c214020032903880c214120032903900c214220032802980c2110200328029c0c210520032802a00c210a20032802a40c210b20032802a80c210c20032802ac0c210d20032d00b00c21012003200341a80b6a418c016a2800003600f308200320032800b10c3602f0082015410874201272201441107472210f0240024020014102470d0020034280c2d72f3703e80e20034280e1eb173703e00e200342a0c21e3703d80e200342a0c21e3703d00e200342e0ef97203703c80e200342e0c9dc293703c00e200342e0ef97203703b80e200342a0c21e3703b00e200342a0c21e3703a80e200342a0c21e3703a00e200342a0c21e3703980e200342a0c21e3703900e200342a0c21e3703880e200342a0c21e3703800e41002101200341003602f00e4120210d41808001210c4110210b41808004210a410421050c010b200341800e6a418c016a20032800f308360000200320103602f00e200320423703e80e200320413703e00e200320403703d80e2003203f3703d00e2003203e3703c80e2003203d3703c00e2003203c3703b80e2003203b3703b00e2003203a3703a80e200320393703a00e200320383703980e200320373703900e200320063703880e200320043703800e200320032802f0083600890f0b200341a80f6a4200370300200341980f6a4200370300200320013a00880f2003200d3602840f2003200c3602800f2003200b3602fc0e2003200a3602f80e200320053602f40e2003428080e983b1de163703a00f2003428080e983b1de163703900f200342a08080808080103703b00f2003200341800e6a360298022003200341800e6a3602e802200341d8106a41186a220a4200370300200341d8106a41106a220b4200370300200341d8106a41086a22014200370300200342003703d81041d1efcb00ad42808080809001841001220529000021042001200541086a290000370300200320043703d8102005103541ebc3c400ad428080808030841001220c2900002104200341a80b6a41086a2205200c41086a290000370300200320043703a80b200c1035200720032903a80b370000200741086a220d2005290300370000200341b8106a41086a22102001290300370300200341b8106a41106a2216200b290300370300200341b8106a41186a221b200a290300370300200320032903d8103703b810200341386a200341b8106a10e102200329034021042003280238211c200a4200370300200b420037030020014200370300200342003703d81041d1c4c700ad4280808080e000841001220c29000021062001200c41086a290000370300200320063703d810200c103541e7c4c700ad4280808080e000841001220c29000021062005200c41086a290000370300200320063703a80b200c1035200720032903a80b370000200d2005290300370000201020012903003703002016200b290300370300201b200a290300370300200320032903d8103703b810200341306a200341b8106a412010c001200341a8096a42003703002003419c096a419494ca0036020020034198096a41b0b4cc0036020020034194096a4100360200200341c8096a200341c8046a41086a290300370300200341d0096a200341c8046a41106a290300370300200341d8096a200341c8046a41186a2903003703002003428080808080013703a0092003420037038809200342003703f808200320032903c8043703c00920032802302101200328023421072003200341e8026a3602b809200320034198026a3602b4092003200341800e6a3602b00920032007410020011b3602bc09200320044200201c1b3703f008200341a80b6a41186a20034188036a41186a290300370300200341a80b6a41106a20034188036a41106a290300370300200520034188036a41086a29030037030020032003290388033703a80b200320093602a0062003200f36029c062003200236029806200341c00a6a200341f0086a200341a80b6a200e2008200341f8106a20034198066a10ef034101210b024020032802c00a220c0d00200341c00a6a41106a2d00000d00200341a80b6a41086a20034190096a29030037030020034198066a41086a200341b40b6a28020036020020032003290388093703a80b200320032902ac0b37039806200341e8116a20034198066a10f0034100210b0b20032802a409220520032802ac09220141d8026c6a210920032802a809210a2003200341b8056a3602d81020052102024002402001450d00200341a80b6a4101722107200521010240034020012d0000210220034198066a200141016a41d702109d081a20024103460d01200320023a00a80b200720034198066a41d702109d081a200341d8106a200341a80b6a108d06200141d8026a22012009470d000c030b0b200141d8026a21020b20092002460d0003402002220141d8026a21020240024020012d0000220741014b0d000240024020070e020001000b0240200141086a28020041ffffff3f71450d00200141046a28020010350b200141106a2d00004107470d02200141386a280200450d02200141346a28020010350c020b200141286a10bb020c010b200141e8006a28020041ffffff3f71450d00200141e4006a28020010350b20092002470d000b0b0240200a450d00200a41d8026c450d00200510350b200341d40a6a290200210e200341c00a6a41106a280200210a200341c80a6a290300210820032802c40a2107024020032802fc082201450d00200341f0086a41106a280200450d00200110350b0240200b450d0002400240200328028c0922050d004100210b200341bc0b6a4100360200200341003602ac0b0c010b200328029409210b0240024020034190096a28020022020d00200521010c010b2002210120052109034020092802880b21092001417f6a22010d000b200521010340200120012f01064102746a41880b6a28020021012002417f6a22020d000b200921050b200341c40b6a20012f0106360200200341c00b6a4100360200200341bc0b6a2001360200200341003602b80b200342003703b00b200320053602ac0b200341003602a80b0b2003200b3602c80b200341a80b6a108f030b200329038011210420032903f810210602400240200c450d000240200ea7450d00200a10350b200620047d210e410121010c010b200620047d210e410021012008a7450d00200710350b42002104420121062001450d190c180b201c290300210820032903e801210e20032903f8012106200341af026a2005290300370000200341b7026a200a2d00003a00002003201b2d00003a009a02200320032f0194023b0198022003200c3600a3022003200b36009f022003200736009b0220032003290380023700a7022018410874201372201741107472210a02400240200141ff01710d00200d41ff01714101470d00200320313a00bf02200320323a00be02200320333b01bc02200320343a00bb02200320353a00ba02200320363b01b8022003202b3a00c7022003202c3a00c6022003202d3b01c4022003202e3a00c3022003202f3a00c202200320303b01c002200320253a00cf02200320263a00ce02200320273b01cc02200320283a00cb02200320293a00ca022003202a3b01c802200320043701d002200320063703e002200320063703d802200341e8026a41186a200437030041102107200341e8026a41106a20032901c802370300200341e8026a41086a20032901c002370300200320032901b8023703e802200341d8106a41186a4200370300200341d8106a41106a22024200370300200341d8106a41086a22014200370300200342003703d81041f1d8cb00ad42808080809001841001220929000021042001200941086a290000370300200320043703d8102009103541e2d8cb00ad4280808080f00184100122092900002104200341a80b6a41086a2205200941086a290000370300200320043703a80b20091035200220032903a80b2204370300200341b8106a41086a2001290300370300200341b8106a41106a2004370300200341b8106a41186a2005290300370300200320032903d8103703b810200341a80b6a200341b8106a10da0220032903a80b210420032903b00b210620032903b80b213720032903c00b213820032903c80b213920032903d00b213a20032903d80b213b20032903e00b213c20032903e80b213d20032903f00b213e20032903f80b213f20032903800c214020032903880c214120032903900c214220032802980c211b200328029c0c210920032802a00c210520032802a40c211c20032802a80c210b20032802ac0c210c20032d00b00c21012003200341a80b6a418c016a2800003600f308200320032800b10c3602f0082016410874200f72201041107472210d0240024020014102470d0020034280c2d72f3703f00320034280e1eb173703e803200342a0c21e3703e003200342a0c21e3703d803200342e0ef97203703d003200342e0c9dc293703c803200342e0ef97203703c003200342a0c21e3703b803200342a0c21e3703b003200342a0c21e3703a803200342a0c21e3703a003200342a0c21e37039803200342a0c21e37039003200342a0c21e3703880341002101200341003602f8034120210c41808001210b418080042105410421090c010b20034188036a418c016a20032800f3083600002003201b3602f803200320423703f003200320413703e803200320403703e0032003203f3703d8032003203e3703d0032003203d3703c8032003203c3703c0032003203b3703b8032003203a3703b003200320393703a803200320383703a003200320373703980320032006370390032003200437038803200320032802f00836009104201c21070b200341b0046a4200370300200341a0046a4200370300200320013a0090042003200c36028c042003200b3602880420032007360284042003200536028004200320093602fc032003428080e983b1de163703a8042003428080e983b1de1637039804200342a08080808080103703b804200320034188036a3602c004200320034188036a3602c404200341d8106a41186a22094200370300200341d8106a41106a22074200370300200341d8106a41086a22014200370300200342003703d81041d1efcb00ad42808080809001841001220529000021042001200541086a290000370300200320043703d8102005103541ebc3c400ad428080808030841001220b2900002104200341a80b6a41086a2205200b41086a290000370300200320043703a80b200b1035200220032903a80b370000200241086a220c2005290300370000200341b8106a41086a220f2001290300370300200341b8106a41106a22102007290300370300200341b8106a41186a22162009290300370300200320032903d8103703b810200341d0006a200341b8106a10e102200329035821042003280250211b200942003703002007420037030020014200370300200342003703d81041d1c4c700ad4280808080e000841001220b29000021062001200b41086a290000370300200320063703d810200b103541e7c4c700ad4280808080e000841001220b29000021062005200b41086a290000370300200320063703a80b200b1035200220032903a80b370000200c2005290300370000200f20012903003703002010200729030037030020162009290300370300200320032903d8103703b810200341c8006a200341b8106a412010c00120034180056a4200370300200341f4046a419494ca00360200200341c8046a41286a41b0b4cc00360200200341ec046a4100360200200341a0056a200341e8026a41086a290300370300200341a8056a200341e8026a41106a290300370300200341b0056a200341e8026a41186a2903003703002003428080808080013703f804200342003703e004200342003703d004200320032903e8023703980520032802482101200328024c21022003200341c4046a360290052003200341c0046a36028c05200320034188036a3602880520032002410020011b36029405200320044200201b1b3703c804200320143b01a206200320153a00a106200320123a00a0062003200d36029c062003200a36029806200341a80b6a200341c8046a200e2008200341d8026a20034198026a20034198066a10c0054101211a200341a80b6a41047221010240024020032802a80b4101470d00200341cc056a200141106a290200370200200341c4056a200141086a2902003702004101211a200341013602b805200320012902003702bc05200341b8056a410472212f0c010b200341b8056a410c6a200141286a2902003702002003200141206a2902003702bc05200341003602b805200341b8056a410472212f200341b8056a41106a2d00000d00200341a80b6a41086a200341e8046a29030037030020034198066a41086a200341a80b6a410c6a280200360200200320032903e0043703a80b200320032902ac0b37039806200341e8116a20034198066a10f0034100211a0b20032802fc042235200328028405220141d8026c6a210720032802800521362035210202402001450d00200341f10b6a211620034181106a210f200341a80b6a41017221302003419f066a2131200341a80b6a41186a211b200341b10b6a210c200341a0116a41116a211d200341a0116a410272211420034198066a41e0006a2132200341d00f6a41186a2133200341d10b6a211c200341a4106a2115200341a0116a410f6a2112200341d00f6a41116a2110200341b8106a410f6a2113200341e8066a2134203521010240034020012d00002102200341a40b6a41026a220d200141036a2d00003a00002003200141016a2f00003b01a40b200141046a2802002109200141086a28020021052001410c6a280200210a200341c00a6a200141106a41e000109d081a200141f8006a2903002104200141f0006a290300210620014180016a2903002108200341f0086a20014188016a41d001109d081a20024103460d01200341b4106a41026a220b200d2d00003a0000200320032f01a40b3b01b410200341d00f6a200341c00a6a41e000109d081a200341800e6a200341f0086a41d001109d081a024002400240024020020e03010200010b201320032900d00f370000201341086a200341d00f6a41086a2202290000370000201341106a200341d00f6a41106a220d2d00003a0000200320032f01b4103b01b8102003200a3600c310200320053600bf10200320093600bb102003200b2d00003a00ba10200341d8106a41186a2217201041186a2218290000370300200341d8106a41106a2225201041106a2226290000370300200341d8106a41086a2227201041086a2228290000370300200320102900003703d810200341f8106a41186a2229200f41186a222a290000370300200341f8106a41106a222b200f41106a222c290000370300200341f8106a41086a222d200f41086a222e2900003703002003200f2900003703f8102003200a3600ab11200320053600a711200320093600a3112003200b2d00003a00a211200320032f01b4103b01a011201220032900d00f370000201241086a2002290000370000201241106a200d2d00003a000020034198066a41186a201829000037030020034198066a41106a202629000037030020034198066a41086a20282900003703002003201029000037039806201b202a290000370300200341a80b6a41106a202c290000370300200341a80b6a41086a202e2900003703002003200f2900003703a80b200341d8116a41086a201541086a280000360200200320152900003703d811200341c8116a200341a0116a20034198066a200341a80b6a20062004200341d8116a10f10320032d00c8112102200c20032903b810370000200c41086a200341b8106a41086a290300370000200c41106a200341b8106a41106a290300370000200c41186a200341b8106a41186a290300370000201c20032903d810370000201c41086a2027290300370000201c41106a2025290300370000201c41186a2017290300370000200341033a00b00b2003410d3a00a80b200341a80b6a41f8006a2004370300201641186a2029290300370000201641106a202b290300370000201641086a202d290300370000201620032903f810370000200320063703980c200320024104463a00910c41b0b4cc004100200341a80b6a10d4010c020b2031200341d00f6a41e000109d081a2003410d3a00a80b203020034198066a41e700109d081a200341a80b6a41f0006a2004370300200320063703900c200320083703a00c2009200a200341a80b6a10d401200541ffffff3f71450d01200910350c010b200341d8116a41026a2202200b2d00003a0000200341d8106a41086a220d200341d00f6a41086a2217290000370300200341d8106a41106a2218200341d00f6a41106a22252d00003a0000200320032f01b4103b01d811200320032900d00f3703d81020034198066a203341c800109d081a20342004370300200320063703e006200320083703f0062032200341800e6a41d001109d081a200341b8106a20034198066a10d803200341a80b6a20034198066a41b002109d081a201420032f01b4103b0000201441026a200b2d00003a0000201d20032900d00f370000201d41086a2017290000370000201d41106a20252d00003a000020034180023b01a0112003200a3600ad11200320053600a911200320093600a511200341f8106a200341a80b6a200341a0116a10ac034200210402402003290380114201520d00420020032903b81022042003290388117d220620062004561b21040b2003427f20032903e002220620047c220420042006541b220420032903d802220620042006561b3703e00220032903f8102104200c20032f01d8113b0000200c41026a20022d00003a0000201b20032903d810370000201b41086a200d290300370000201b41106a20182d00003a0000200341063a00b00b2003410d3a00a80b2003200a3602bc0b200320053602b80b200320093602b40b20032004503a00d10b41b0b4cc004100200341a80b6a10d4010b200141d8026a22012007470d000b200721020c010b200141d8026a21020b024020072002460d0003402002220141d8026a21020240024020012d0000220941014b0d000240024020090e020001000b0240200141086a28020041ffffff3f71450d00200141046a28020010350b200141106a2d00004107470d02200141386a280200450d02200141346a28020010350c020b200141286a10bb020c010b200141e8006a28020041ffffff3f71450d00200141e4006a28020010350b20072002470d000b0b02402036450d00203641d8026c450d00203510350b202f290210210e202f28020c210b202f2902042104202f280200210720032802b8052105024020032802d4042201450d00200341d8046a280200450d00200110350b0240201a450d000240024020032802e404220a0d004100210c200341bc0b6a4100360200200341003602ac0b0c010b20032802ec04210c02400240200341e8046a28020022020d00200a21010c010b20022101200a2109034020092802880b21092001417f6a22010d000b200a21010340200120012f01064102746a41880b6a28020021012002417f6a22020d000b2009210a0b200341c40b6a20012f0106360200200341c00b6a4100360200200341bc0b6a2001360200200341003602b80b200342003703b00b2003200a3602ac0b200341003602a80b0b2003200c3602c80b200341a80b6a108f030b20032903e002210620032903d802210820054101470d010240200ea7450d00200b10350b200820067d2108420121060c150b420021064102210702402016410874200f722010411074720d000c150b200a10350c140b02402004a7450d00200710350b200820067d210842002104420121060c140b20032901f201210620032d00f101210220032d00f001210920032f01ee01211c20032d00ed01211d20032d00ec01211e20032f01ea01211f20032d00e901212020032d00e8012121200320032f0194023b01c00a2003200c3600cb0a2003200b3600c70a200320073600c30a2003201b2d00003a00c20a200341d70a6a2005290300370000200341df0a6a200a2d00003a000020032003290380023700cf0a200141ff01710d0f02400240201a4101710d0041022107200d41ff01714101460d010c110b41002107201c2127201f212a2014212d2010213020172133201921362013213520182134200f2132201621312012212f2015212e2021212c2020212b201e2129201d2128200921262002212520062104200d41ff01714102470d100b200320043703e80f200320253a00e70f200320263a00e60f200320273b01e40f200320283a00e30f200320293a00e20f2003202a3b01e00f2003202b3a00df0f2003202c3a00de0f2003202d3b01dc0f2003202e3a00db0f2003202f3a00da0f200320303b01d80f200320313a00d70f200320323a00d60f200320333b01d40f200320343a00d30f200320353a00d20f200320363b01d00f200341f0086a200341c00a6a10f303200341a80b6a20032802f008220220032802f80810d90220032d00a80b210120034198066a200341a80b6a41017241d700109d081a024020014102460d00200341800e6a20034198066a41d700109d081a0b024020032802f408450d00200210350b024002402001417f6a41ff01714102490d00200341f0086a200341870e6a41d000109d081a200341a80b6a41186a4200370300200341a80b6a41106a22094200370300200341a80b6a41086a22014200370300200342003703a80b41d1c4c700ad4280808080e000841001220229000021042001200241086a290000370300200320043703a80b2002103541e7c4c700ad4280808080e00084100122022900002104200341f8106a41086a2205200241086a290000370300200320043703f81020021035200920032903f810220437030020034198066a41086a200129030037030020034198066a41106a200437030020034198066a41186a2005290300370300200320032903a80b37039806200341f8006a20034198066a412010c001200341c8046a200341c00a6a200328027c410020032802781b22012007200341f0086a10f603024020032802c804417f6a41014b0d0020034198066a200341f0086a41d000109d081a20034188036a41186a200341c8046a41186a29030037030020034188036a41106a200341c8046a41106a29030037030020034188036a41086a200341c8046a41086a290300370300200320032903c80437038803200341a80b6a200341c00a6a20034198066a200120034188036a10f703024020032d00a80b0d00200341c40b6a280200450d00200341c00b6a28020010350b42002104200342003703880e200342808086bdbacdd21a3703800e2003200341d00f6a3602f00820034198066a200341d00f6a200341800e6a200341f0086a109a022003280298064101460d02200341c0066a290300210820034198066a41206a290300210e024020034198066a41086a220b2903004201520d0020034198066a41106a2903002104200341e00b6a20034198066a41186a290300370300200341d80b6a2004370300200341a80b6a41086a41003a0000200341b10b6a20032903d00f370000200341b90b6a200341d00f6a41086a290300370000200341c10b6a200341d00f6a41106a290300370000200341c90b6a200341d00f6a41186a290300370000200341033a00a80b41b0b4cc004100200341a80b6a10d4010b42002104200341a80b6a41186a22024200370300200341a80b6a41106a22074200370300200341a80b6a41086a22014200370300200342003703a80b41b6fdc600ad428080808080018422061001220a2900002137200341a0116a41086a2205200a41086a290000370300200320373703a011200a103520012005290300370300200320032903a0113703a80b41e489c200ad4280808080d0018422371001220c2900002138200341f8106a41086a220a200c41086a290000370300200320383703f810200c1035200920032903f810370000200941086a220f200a290300370000200b200129030037030020034198066a41106a2210200729030037030020034198066a41186a22162002290300370300200320032903a80b37039806200341e0006a20034198066a412010d701200341e0006a41106a2903002138200329036821392003280260210c200242003703002007420037030020014200370300200342003703a80b20061001220d29000021062005200d41086a290000370300200320063703a011200d103520012005290300370300200320032903a0113703a80b2037100122052900002106200a200541086a290000370300200320063703f81020051035200920032903f810370000200f200a290300370000200b20012903003703002010200729030037030020162002290300370300200320032903a80b370398062003427f20384200200c1b220620087c20394200200c1b2208200e7c220e2008542201ad7c22082001200820065420082006511b22011b3703b00b2003427f200e20011b3703a80b20034198066aad4280808080800484200341a80b6aad428080808080028410020c140b20034184096a280200450d0020032802800910350b420021040c120b200328029c06220141ff01714104460d112001418080807871210220014180807c712109200141807e712107200341a0066a2903002204422088a721052004a7210a0c100b200341d00b6a2001412c6a280200360200200341a80b6a41206a200141246a290200370300200341a80b6a41186a2001411c6a290200370300200341a80b6a41106a200141146a290200370300200341a80b6a41086a2001410c6a290200370300200320012902043703a80b20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a108e060c170b2001411c6a280200210d200141186a280200210f200141146a28020021102001410c6a2802002116200141086a280200211c410021094102210702400240024020022d0000450d000c010b20022d000141ff01714102470d00200141246a280200211b200141106a2802002107200341a80b6a41186a22054200370300200341a80b6a41106a22014200370300200341a80b6a41086a22024200370300200342003703a80b41a3edcb00ad4280808080f000841001220929000021042002200941086a290000370300200320043703a80b2009103541a5ebcb00ad4280808080c001841001220a2900002104200341f8106a41086a2209200a41086a290000370300200320043703f810200a1035200120032903f810220437030020034198066a41086a220b200229030037030020034198066a41106a220c200437030020034198066a41186a221d2009290300370300200320032903a80b3703980620034188016a20034198066a412010c001200341a80b6a200328028c0141002003280288011b2213201b10ba0420034180016a20032802a80b220a20032802b00b41b0b4cc0041004100108a022003280280012112024020032802ac0b450d00200a10350b200542003703002001420037030020024200370300200342003703a80b4188e8cb00ad42808080808001841001220a29000021042002200a41086a290000370300200320043703a80b200a1035418fd1cb00ad4280808080c000841001220a29000021042009200a41086a290000370300200320043703f810200a1035200120032903f810370000200141086a2009290300370000200b2002290300370300200c2001290300370300201d2005290300370300200320032903a80b37039806200341a80b6a20034198066a10d80220032802a80b2201410120011b211d20032902ac0b420020011b21040240201241014622020d00201d201b4105746a4100201b2004422088a7491b22010d020b41eec3c4004181c4c40020021b21054113410a20021b210a2002411074210941032107200442ffffff3f83500d00201d10350b02402016450d00201c10350b0240200d450d00200d410c6c21022010210103400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b0240200f450d00200f410c6c450d00201010350b20004200370308200041206a200a3602002000411c6a2005360200200041186a200920077241802872360200200042013703000c170b200141086a2900002106200141106a29000021082001290000210e20034198066a41186a200141186a290000223737030020034198066a41106a200837030020034198066a41086a20063703002003200e37039806200341b50b6a2006370000200341bd0b6a2008370000200341c50b6a2037370000200341003a00ac0b2003410f3a00a80b2003200e3700ad0b41b0b4cc004100200341a80b6a10d401200341003602b00b200342013703a80b2007200341a80b6a10770240024020032802ac0b220920032802b00b22016b2007490d0020032802a80b21020c010b200120076a22022001490d08200941017422052002200520024b1b22054100480d080240024020090d00024020050d00410121020c020b200510332202450d1a0c010b20032802a80b210220092005460d0020022009200510372202450d190b200320053602ac0b200320023602a80b0b200220016a201c2007109d081a2003200120076a3602b00b200d200341a80b6a1077200d450d062010200d410c6c6a210c2010210203402002280200210b200241086a2802002201200341a80b6a10770240024020032802ac0b220720032802b00b22096b2001490d0020032802a80b21052007210a0c010b200920016a22052009490d092007410174220a2005200a20054b1b220a4100480d090240024020070d000240200a0d00410121050c020b200a10332205450d1b0c010b20032802a80b21052007200a460d0020052007200a10372205450d1a0b2003200a3602ac0b200320053602a80b0b200520096a200b2001109d081a2003200920016a22013602b00b2002410c6a2202200c470d000c0d0b0b200341a80b6a200141086a41a802109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a10b3040c150b200341a80b6a200141086a41c800109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a108f060c140b200341a80b6a200141046a41c400109d081a20034198066a41206a200241206a29020037030020034198066a41186a200241186a29020037030020034198066a41106a200241106a29020037030020034198066a41086a200241086a29020037030020032002290200370398062000200341a80b6a20034198066a1090060c130b200341800e6a41086a2207200141146a290200370300200341800e6a41106a22052001411c6a290200370300200341800e6a41186a220a200141246a290200370300200341800e6a41206a220b2001412c6a28020036020020032001410c6a2902003703800e2002411a6a2901002104200241196a2d0000210d200241186a2d0000210f200241166a2f01002110200241156a2d00002116200241146a2d0000211b200241126a2f0100211c200241116a2d0000211d200241106a2d000021122002410e6a2f010021132002410d6a2d000021142002410c6a2d000021152002410a6a2f01002117200241096a2d00002118200241086a2d00002125200241066a2f01002126200241056a2d00002127200241046a2d000021284102210c200241026a2f0100212920022d0001210920022d000021020240024002400240200141086a2802000e0400010203000b200341a80b6a41146a4101360200200342013702ac0b200341e8d4ca003602a80b2003410436029c062003419cd5ca0036029806200320034198066a3602b80b200341a80b6a41b0b4cc00104c000b02400240024002400240200241ff01710d00200941ff01714101460d010b200341023a0098060c010b200320043703c00b2003200d3a00bf0b2003200f3a00be0b200320103b01bc0b200320163a00bb0b2003201b3a00ba0b2003201c3b01b80b2003201d3a00b70b200320123a00b60b200320133b01b40b200320143a00b30b200320153a00b20b200320173b01b00b200320183a00af0b200320253a00ae0b200320263b01ac0b200320273a00ab0b200320283a00aa0b200320293b01a80b20034198066a200341a80b6a10890520032d0098064104460d010b20032802980621012000411c6a200329029c06370200200041186a2001360200420121040c010b420021040b200042003703080c090b20034198066a41206a200b28020036020020034198066a41186a200a29030037030020034198066a41106a200529030037030020034198066a41086a2007290300370300200320032903800e37039806200241ff01710d05200941ff01714101470d05200341a80b6a41206a20034198066a41206a280200360200200341a80b6a41186a20034198066a41186a290300370300200341a80b6a41106a20034198066a41106a290300370300200341a80b6a41086a20034198066a41086a29030037030020032003290398063703a80b200341f0086a200341a80b6a108b02024020032d00f0084101470d00200341013a00c8040c070b200341f0086a41086a2d00002101200341f9086a2f00002102200341fb086a2d00002109200341fc086a2d00002107200341fd086a2f00002105200341ff086a2d0000210a200341f0086a41106a2d0000210b20034181096a2f0000210c20034183096a2d0000210d20034184096a2d0000210f20034185096a2f0000211020034187096a2d00002116200341f0086a41186a2d0000211b20032f00f108211c20032d00f308211d20032d00f408211220032f00f508211320032d00f7082114200320034189096a2900003703a0032003201b3a009f03200320163a009e03200320103b019c032003200f3a009b032003200d3a009a032003200c3b0198032003200b3a0097032003200a3a009603200320053b019403200320073a009303200320093a009203200320023b019003200320013a008f03200320143a008e03200320133b018c03200320123a008b032003201d3a008a032003201c3b018803200341c8046a20034188036a10890520032d00c8044104470d06420021040c070b200141c8006a290300210e200141c0006a2903002137200141386a2903002106200141306a2903002108200141d0006a280200212a20034198066a41206a200b28020036020020034198066a41186a200a29030037030020034198066a41106a200529030037030020034198066a41086a2007290300370300200320032903800e37039806024002400240200241ff01710d00200941ff01714101470d00200320043703e0042003200d3a00df042003200f3a00de04200320103b01dc04200320163a00db042003201b3a00da042003201c3b01d8042003201d3a00d704200320123a00d604200320133b01d404200320143a00d304200320153a00d204200320173b01d004200320183a00cf04200320253a00ce04200320263b01cc04200320273a00cb04200320283a00ca04200320293b01c8044103210c200842808084fea6dee1115441002006501b0d00200341a80b6a41206a20034198066a41206a280200360200200341a80b6a41186a20034198066a41186a290300370300200341a80b6a41106a20034198066a41106a290300370300200341a80b6a41086a20034198066a41086a29030037030020032003290398063703a80b200341f0086a200341a80b6a108b024101210c024020032d00f0084101470d000c020b200341f0086a41086a2d00002101200341f9086a2f00002102200341fb086a2d00002109200341fc086a2d00002107200341fd086a2f00002105200341ff086a2d0000210a200341f0086a41106a2d0000210b20034181096a2f0000210c20034183096a2d0000210d20034184096a2d0000210f20034185096a2f0000211020034187096a2d00002116200341f0086a41186a2d0000211b20032f00f108211c20032d00f308211d20032d00f408211220032f00f508211320032d00f7082114200320034189096a2900003703a0032003201b3a009f03200320163a009e03200320103b019c032003200f3a009b032003200d3a009a032003200c3b0198032003200b3a0097032003200a3a009603200320053b019403200320073a009303200320093a009203200320023b019003200320013a008f03200320143a008e03200320133b018c03200320123a008b032003201d3a008a032003201c3b018803200341a80b6a20034188036a108a0520034198016a20032802a80b220120032802b00b41b0b4cc0041004100108a022003280298012102024020032802ac0b450d00200110350b41012101024020024101470d00411b21074103210c4117210941aaefc40021020c020b200341a80b6a200341c8046a20034188036a20082006410110e602024020032d00a80b220c4104460d00200341b00b6a280200210920032802ac0b210220032d00ab0b210520032d00aa0b210120032d00a90b21070c030b200341a80b6a20034188036a108a0520034190016a20032802a80b220220032802b00b41b0b4cc0041004100108a022003280290012101024020032802ac0b450d00200210350b024020014101460d00200341a80b6a20034188036a108a0520033502b00b210420032802a80b2102411010332201450d17200120083700002001200637000820014110412010372201450d1720012037370010200141186a200e3700002001412041c00010372201450d172001202a36002020044220862002ad842001ad4280808080c00484100220011035024020032802ac0b450d00200210350b200341a80b6a41186a20034188036a41186a290300370300200341a80b6a41106a20034188036a41106a290300370300200341a80b6a41086a20034188036a41086a29030037030020032003290388033703a80b200341f0086a200341a80b6a10890542002104200042003703080c0b0b200341b00b6a4117360200200341aaefc4003602ac0b200341013a00aa0b20034183363b01a80b4188bfc6004137200341a80b6a41c0bfc60041d0bfc6001046000b41022101411b21074109210941a1efc40021020b0b20004200370308200041206a20093602002000411c6a2002360200200041186a2005411874200141ff017141107472200741ff017141087472200c72360200420121040c070b418eebc400413041c086cc00103f000b1045000b20032802b00b210120032802ac0b210a20032802a80b21050c050b103e000b200341023a00c8040b20032802c80421012000411c6a20032902cc04370200200041186a2001360200420121040b200042003703080b200020043703000c0a0b200341a80b6a2013201b10ba0420032802a80b2102200320032802b00b36029c0620032002360298062005200120034198066a109403024020032802ac0b450d00200210350b0240200a450d00200510350b0240200442ffffff3f83500d00201d10350b02402016450d00201c10350b0240200d450d00200d410c6c21022010210103400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b0240200f450d00200f410c6c450d00201010350b20004200370308200042003703000c090b410021024180800421094180242107410321014115210541dcffc600210a0b200041206a20053602002000411c6a200a360200200041186a20074180fe0371200141ff0171722009418080fc077172200272360200420121040b20004200370308200020043703000c060b2000411c6a2004370200200041186a2007360200420121040b20002006370308200041106a2008370300200020043703000c040b200210350b420021060b2000411c6a2008370200200041186a2007360200420121040b20002006370308200041106a200e370300200020043703000b200341f0116a24000f0b103c000bbf0403027f017e047f230041306b22032400200341086a200141086a28020022043602002003200129020022053703002005a72106024002400240024020040d00410021070c010b200441057421084100210941002107200621010240034002402009450d0020092001412010a0084100480d00200341186a4115360200200341e6f1c200360214200341053a001220034183023b0110200341106a21010c020b0240024020012002412010a008220941004a0d0020022001460d012009450d01200741016a21070b20012109200141206a2101200841606a2208450d030c010b0b200341186a4113360200200341d3f1c200360214200341063a001220034183023b0110200341106a21010b20004101360200200020012902003702042000410c6a200141086a280200360200200328020441ffffff3f71450d01200610350c010b200341106a41186a200241186a290000370300200341106a41106a200241106a290000370300200341106a41086a200241086a2900003703002003200229000037031020042007490d01024020042003280204470d00200320044101108a01200328020021060b200620074105746a220141206a2001200420076b410574109e081a200141186a200341106a41186a290300370000200141106a200341106a41106a290300370000200141086a200341106a41086a290300370000200120032903103700002003200441016a22013602082000410c6a200136020020002003290300370204200041003602000b200341306a24000f0b20072004104d000bba0502087f037e230041106b2202240002400240200141086a28020022034105744116722204417f4c0d000240200410332205450d00200520012802002206290000370000200541086a200641086a290000370000200241103602082002200436020420022005360200200141046a280200210720032002107702400240024020030d0020022802042106200228020821040c010b20034105742108200228020021092002280204210620022802082104034020072105024002402006200422036b4120490d00200341206a21040c010b200341206a22042003490d03200641017422072004200720044b1b22074100480d03024002400240024020060d00024020070d00410121090c020b2007103321090c030b20062007470d010b200721060c020b200920062007103721090b200721062009450d060b200541206a2107200920036a22032005290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a290000370000200841606a22080d000b2002200636020420022004360208200220093602000b20012f010c210802400240200620046b4102490d00200441026a210520022802002103200621070c010b200441026a22052004490d01200641017422032005200320054b1b22074100480d010240024020060d00024020070d00410121030c020b200710332203450d060c010b2002280200210320062007460d0020032006200710372203450d050b20022007360204200220033602000b200320046a20083b00002005ad4220862003ad8410092205290000210a200541086a290000210b200541106a290000210c200041186a200541186a290000370000200041106a200c370000200041086a200b3700002000200a3700002005103502402007450d00200310350b200241106a24000f0b103e000b1045000b1044000b103c000b855802057f017e230041206b220224000240024020002802002203411b4b0d000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e1c000102030405060708090a0b0c0d0e0f101112131415161718191a1b000b200241003a00102001200241106a41011078200041086a280200417f6a220341094b0d1c024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a00042001200241046a4101107820022000410c6a2802003602102001200241106a410410780c250b200241013a00042001200241046a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c240b200241023a00042001200241046a410110782002200041106a2903003703102001200241106a410810780c230b200241033a00042001200241046a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c220b200241043a00042001200241046a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c210b200241053a00042001200241046a4101107802402000410c6a2802004101460d00200241003a00042001200241046a410110780c210b200241013a00042001200241046a410110782002200041106a2802003602102001200241106a410410782002200041146a2802003602102001200241106a410410780c200b200241063a00042001200241046a410110782000410c6a2802002103200041146a2802002200200110772000450d1f2003200041186c6a2104034020032802002100200341086a28020022052001107720012000200510782003410c6a2802002100200341146a2802002205200110772001200020051078200341186a22032004470d000c200b0b200241073a00042001200241046a410110782000410c6a2802002103200041146a2802002200200110772000450d1e20032000410c6c6a2104034020032802002100200341086a28020022052001107720012000200510782003410c6a22032004470d000c1f0b0b200241083a00042001200241046a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c1d0b200241093a00042001200241046a410110780c1c0b200241013a00102001200241106a4101107820002d0004417f6a220341044b0d1b200041046a21040240024002400240024020030e050001020304000b200241003a00042001200241046a41011078200041086a2802002103200041106a2802002200200110772000450d1f200041b0026c210003402003200110af03200341b0026a2103200041d07d6a22000d000c200b0b200241013a00042001200241046a41011078200220002f01063b01102001200241106a41021078200041086a280200200110af030c1e0b200241023a00042001200241046a41011078200220002f01063b01102001200241106a41021078200041086a2802002103200041106a28020022052001107702402005450d002005410574210503402001200341201078200341206a2103200541606a22050d000b0b0240024020002802144101460d00200241003a00042001200241046a410110780c010b200241013a00042001200241046a410110782002200041186a2802003602102001200241106a4104107820022000411c6a2802003602102001200241106a410410780b2000280220200110af030c1d0b200241033a00042001200241046a41011078200220002f01263b01102001200241106a41021078200041286a2802002103200041306a28020022052001107702402005450d002005410574210503402001200341201078200341206a2103200541606a22050d000b0b200441016a21030240024020002802344101460d00200241003a00042001200241046a410110780c010b200241013a00042001200241046a410110782002200041386a2802003602102001200241106a4104107820022000413c6a2802003602102001200241106a410410780b20012003412010780c1c0b200241043a00042001200241046a41011078200220002f01263b01102001200241106a41021078200041286a2802002103200041306a280200220520011077200441016a210402402005450d002005410574210503402001200341201078200341206a2103200541606a22050d000b0b200220002802343602102001200241106a410410782002200041386a2802003602102001200241106a4104107820012004412010780c1b0b200241023a00102001200241106a410110780c190b200241033a00102001200241106a41011078200241003a00102001200241106a41011078200041086a200110fb050c190b200241043a00102001200241106a41011078200241003a00102001200241106a41011078200028020421032000410c6a2802002200200110772000450d182003200041f0006c6a21060340412010332200450d1a20002003290010370000200041186a200341286a290000370000200041106a200341206a290000370000200041086a200341186a2900003700002001200041201078200010352003200110e201412010332200450d1a20002003290030370000200041186a200341c8006a290000370000200041106a200341c0006a290000370000200041086a200341386a290000370000200120004120107820001035412010332200450d1a200341f0006a210420002003290050370000200041186a200341e8006a290000370000200041106a200341e0006a290000370000200041086a200341d8006a29000037000020012000412010782000103520032802042100200328020c22032001107702402003450d00200341246c21030340200241106a200010c0032001200228021022052002280218107802402002280214450d00200510350b200041246a21002003415c6a22030d000b0b2004210320042006470d000c190b0b200241053a00102001200241106a4101107820002d0004417f6a220341034b0d17200041046a21050240024002400240024020030e0400010203000b200241003a00042001200241046a410110782002200041086a280200360210200241106a21000c030b200241013a00042001200241046a410110782001200541016a412010782002200041286a280200360210200241106a21000c020b200241023a00042001200241046a410110782002200041086a280200360210200241106a21000c010b200241033a00042001200241046a410110782001200541016a412010782002200041286a280200360210200241106a21000b20012000410410780c170b200241063a00102001200241106a41011078200041086a280200417f6a220341034b0d160240024002400240024020030e0400010203000b200241003a00042001200241046a410110782000410c6a200110fc05200041306a2103200221000c030b200241013a00042001200241046a410110782000410c6a200110fc052002200041306a360204200241046a200110cf01200041c0006a2103200241086a21000c020b200241023a00042001200241046a410110782000410c6a200110fc05200041306a200110fc05200041d8006a21032002410c6a21000c010b200241033a00042001200241046a410110782000410c6a200110fc05200041306a2103200241106a21000b200020033602002000200110cf010c160b200241073a00102001200241106a41011078200041086a22052d0000417f6a220341174b0d1502400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e18000102030405060708090a0b0c0d0e0f1011121314151617000b200241003a00102001200241106a410110782000410c6a200110fc052002200041306a360210200241106a200110cf0120002d0009220041024b0d2c02400240024020000e03000102000b200241003a00102001200241106a410110780c2e0b200241013a00102001200241106a410110780c2d0b200241023a00102001200241106a410110780c2c0b200241013a00102001200241106a410110782002200041106a360210200241106a200110cf010c2b0b200241023a00102001200241106a410110782002200041106a360210200241106a200110cf010c2a0b200241033a00102001200241106a410110780c290b200241043a00102001200241106a410110780240024002402000410c6a280200220341c000490d00200341808001490d012003418080808004490d02200241033a00042001200241046a410110782002200028020c3602102001200241106a410410780c2b0b200220034102743a00042001200241046a410110780c2a0b200220034102744101723b01102001200241106a410210780c290b200220034102744102723602102001200241106a410410780c280b200241053a00102001200241106a410110782000410c6a2802002103200041146a2802002200200110772000450d27200041246c210003402003200110fc05200341246a21032000415c6a22000d000c280b0b200241063a00102001200241106a410110780c260b200241073a00102001200241106a4101107820052d0001220041024b0d2502400240024020000e03000102000b200241003a00102001200241106a410110780c270b200241013a00102001200241106a410110780c260b200241023a00102001200241106a410110780c250b200241083a00102001200241106a410110782000410c6a200110fc050c240b200241093a00102001200241106a410110782000410c6a200110e2010c230b2002410a3a00102001200241106a410110780c220b2002410b3a00102001200241106a410110780c210b2002410c3a00102001200241106a410110782000410c6a2802002103200041146a2802002200200110772000450d202000410574210003402001200341201078200341206a2103200041606a22000d000c210b0b2002410d3a00102001200241106a410110782001200541016a412010780c1f0b2002410e3a00102001200241106a410110780c1e0b2002410f3a00102001200241106a4101107820022000410c6a2802003602102001200241106a41041078200041106a2802002103200041186a28020022002001107720012003200041027410780c1d0b200241103a00102001200241106a4101107820022000410c6a2802003602102001200241106a41041078200041106a2802002103200041186a2802002200200110772000450d1c2003200041246c6a2100034020012003412010782002200341206a2802003602102001200241106a410410782000200341246a2203470d000c1d0b0b200241113a00102001200241106a4101107820022000410c6a2802003602102001200241106a410410780c1b0b200241123a00102001200241106a410110782001200541016a4120107820022000412c6a2802003602102001200241106a410410780c1a0b200241133a00102001200241106a410110782002200041106a360210200241106a200110cf010c190b200241143a00102001200241106a410110782000410c6a200110e2010c180b200241153a00102001200241106a410110782001200541016a412010780c170b200241163a00102001200241106a410110782000410c6a2802002103200041146a2802002205200110772001200320054101741078200041186a200110f7012001200041e0016a413010782002200041d8016a2802003602102001200241106a410410780c160b200241173a00102001200241106a410110782000410c6a2802002103200041146a2802002205200110772001200320054101741078200041186a200110f7012001200041e0016a413010782002200041d8016a2802003602102001200241106a410410780c150b200241083a00102001200241106a4101107802402000280204450d00200241003a00042001200241046a410110782001200041106a412010782001200041306a412010782001200041d0006a412010782001200041f0006a41201078200028020421032000410c6a28020022002001107720012003200010780c150b200241013a00042001200241046a410110780c140b200241093a00102001200241106a41011078200041086a22032d0000417f6a2205411c4b0d130240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020050e1d000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c000b200241003a00102001200241106a41011078412010332205450d3020052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a2900003700002001200541201078200510352002200041306a360210200241106a200110cf010c2f0b200241013a00102001200241106a410110782000410c6a200110e2010c2e0b200241023a00102001200241106a410110782000410c6a200110e201200041106a200110fd050c2d0b200241033a00102001200241106a410110782000410c6a200110e201200041106a200110fd050c2c0b200241043a00102001200241106a4101107820022000410c6a2802003602102001200241106a410410780c2b0b200241053a00102001200241106a41011078412010332200450d2b20002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c2a0b200241063a00102001200241106a41011078412010332200450d2a20002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c290b200241073a00102001200241106a41011078412010332200450d2920002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c280b200241083a00102001200241106a41011078412010332205450d2820052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a29000037000020012005412010782005103520022000412c6a2802003602102001200241106a410410782002200041306a2802003602102001200241106a410410780c270b200241093a00102001200241106a41011078412010332200450d2720002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c260b2002410a3a00102001200241106a410110782000410c6a200110e2010c250b2002410b3a00102001200241106a4101107820022000410c6a2802003602102001200241106a410410780c240b2002410c3a00102001200241106a410110782001200341016a412010780c230b2002410d3a00102001200241106a410110780c220b2002410e3a00102001200241106a410110782001200341016a412010780c210b2002410f3a00102001200241106a410110782001200341016a41201078024020002d0029220341064b0d000240024002400240024002400240024020030e0700010203040506000b200241003a00040c060b200241013a00040c050b200241023a00040c040b200241033a00040c030b200241043a00040c020b200241053a00040c010b200241063a00040b2001200241046a410110780b200029033021072002200041386a290300370318200220073703102001200241106a411010780c200b200241103a00102001200241106a410110780c1f0b200241113a00102001200241106a410110780c1e0b200241123a00102001200241106a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c1d0b200241133a00102001200241106a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c1c0b200241143a00102001200241106a41011078412010332200450d1c20002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c1b0b200241153a00102001200241106a410110782001200341016a412010780c1a0b200241163a00102001200241106a410110782001200341016a412010780c190b200241173a00102001200241106a4101107820022000410c6a2802003602102001200241106a410410780c180b200241183a00102001200241106a410110782001200341016a4120107820022000412c6a2802003602102001200241106a410410780c170b200241193a00102001200241106a410110782001200341016a41201078024020002d0029220341064b0d000240024002400240024002400240024020030e0700010203040506000b200241003a00040c060b200241013a00040c050b200241023a00040c040b200241033a00040c030b200241043a00040c020b200241053a00040c010b200241063a00040b2001200241046a410110780b200029033021072002200041386a290300370318200220073703102001200241106a411010780c160b2002411a3a00102001200241106a410110780c150b2002411b3a00102001200241106a4101107820022000410c6a2802003602102001200241106a410410780c140b2002411c3a00102001200241106a41011078412010332205450d1420052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a29000037000020012005412010782005103520022000412c6a2802003602102001200241106a410410780c130b2002410a3a00102001200241106a41011078200041046a200110fe050c120b2002410b3a00102001200241106a41011078200041046a200110fe050c110b2002410c3a00102001200241106a41011078200041086a280200417f6a220341054b0d1002400240024002400240024020030e06000102030405000b200241003a00042001200241046a410110782000410c6a2802002103200041146a280200220520011077200041186a210402402005450d002005410574210003402001200341201078200341206a2103200041606a22000d000b0b20022004360210200241106a200110cf010c150b200241013a00042001200241046a410110780c140b200241023a00042001200241046a410110782000410c6a200110fc050c130b200241033a00042001200241046a410110780c120b200241043a00042001200241046a410110780c110b200241053a00042001200241046a410110782000410c6a200110fc050c100b2002410d3a00102001200241106a4101107820002d0004417f6a220341064b0d0f200041046a2105024002400240024002400240024020030e0700010203040506000b200241003a00042001200241046a410110782001200541016a412010780c150b200241013a00042001200241046a410110782001200541016a412010780c140b200241023a00042001200241046a410110782001200541016a412010782001200541216a412010780c130b200241033a00042001200241046a41011078200041086a2802002103200041106a2802002200200110772000450d122000410574210003402001200341201078200341206a2103200041606a22000d000c130b0b200241043a00042001200241046a410110782001200541016a412010780c110b200241053a00042001200241046a410110782001200541016a412010780c100b200241063a00042001200241046a410110780c0f0b2002410e3a00102001200241106a41011078200241003a00102001200241106a41011078200041046a200110e2010c0e0b2002410f3a00102001200241106a41011078200241003a00102001200241106a41011078200028020421032000410c6a28020022002001107720012003200010780c0d0b200241103a00102001200241106a41011078200041086a22032d0000417f6a220541074b0d0c0240024002400240024002400240024020050e080001020304050607000b200241003a00042001200241046a410110782002200041306a360210200241106a200110cf012000410c6a200110fc050c130b200241013a00042001200241046a410110782000410c6a200110e2010c120b200241023a00042001200241046a410110782000410c6a200110e2010c110b200241033a00042001200241046a410110782000412c6a2802002105200041346a28020022002001107720012005200010782001200341016a412010780c100b200241043a00042001200241046a41011078412010332200450d1020002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c0f0b200241053a00042001200241046a410110782000412c6a2802002105200041346a28020022042001107720012005200410782001200341016a41201078200041386a29030021072002200041c0006a290300370318200220073703102001200241106a411010780c0e0b200241063a00042001200241046a41011078412010332205450d0e20052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a290000370000200120054120107820051035200041306a29030021072002200041386a290300370318200220073703102001200241106a411010780c0d0b200241073a00042001200241046a41011078412010332200450d0d20002003290001370000200041186a200341196a290000370000200041106a200341116a290000370000200041086a200341096a2900003700002001200041201078200010350c0c0b200241113a00102001200241106a41011078200041086a22032d0000417f6a220541044b0d0b0240024002400240024020050e050001020304000b200241003a00042001200241046a41011078200041106a200110f3050c0f0b200241013a00042001200241046a410110782000410c6a2802002103200041146a28020022002001107720012003200010780c0e0b200241023a00042001200241046a410110782000410c6a200110fc052002200041c0006a360210200241106a200110cf01200041d0006a200110fb05200041306a2802002103200041386a28020022002001107720012003200010780c0d0b200241033a00042001200241046a410110782002200041386a360210200241106a200110cf01200041c8006a200110fb05412010332205450d0d20052003290001370000200541186a200341196a290000370000200541106a200341116a290000370000200541086a200341096a2900003700002001200541201078200510352000412c6a2802002103200041346a28020022002001107720012003200010780c0c0b200241043a00042001200241046a410110782001200341016a412010780240200341216a2d00004101460d00200241003a00042001200241046a410110780c0c0b200241013a00042001200241046a410110782001200341226a412010780c0b0b200241123a00102001200241106a410110782000280204417f6a220341024b0d0a02400240024020030e03000102000b200241003a00042001200241046a41011078200041086a280200200110af030c0c0b200241013a00042001200241046a41011078200041086a200110fc050c0b0b200241023a00042001200241046a41011078200041086a200110fc052000412c6a280200200110af030c0a0b200241133a00102001200241106a41011078200241003a00102001200241106a41011078200220002802043602102001200241106a41041078200041086a2802002103200041106a2802002205200110772001200320051078200041146a28020021032000411c6a28020022052001107702402005450d0020032005410c6c6a2106034020032802002105200341086a28020022042001107720012005200410782003410c6a22032006470d000b0b2002200041206a2802003602102001200241106a410410782002200041246a2802003602102001200241106a410410782002200041286a2802003602102001200241106a4104107820012000412c6a41c00010780c090b200241143a00102001200241106a410110780c070b200241153a00102001200241106a410110780c060b200241163a00102001200241106a410110780c050b200241173a00102001200241106a41011078200041086a22052d0000417f6a2203410a4b0d050240024002400240024002400240024002400240024020030e0b000102030405060708090a000b200241003a00042001200241046a410110782001200541016a412010780c0f0b200241013a00042001200241046a410110782000410c6a200110ab040c0e0b200241023a00042001200241046a410110782000410c6a2802002103200041146a2802002200200110772000450d0d2003200041c4006c6a210503402001200341201078200241106a200341206a220010ac042001200228021022032002280218107802402002280214450d00200310350b2005200041246a2203470d000c0e0b0b200241033a00042001200241046a410110780c0c0b200241043a00042001200241046a410110782000410c6a200110e2012002200041106a360210200241106a200110cf010c0b0b200241053a00042001200241046a4101107820022000410c6a2802003602102001200241106a410410780c0a0b200241063a00042001200241046a410110782000410c6a200110e2012002200041106a360210200241106a200110cf010c090b200241073a00042001200241046a410110782000412c6a200110e2012001200541016a412010780c080b200241083a00042001200241046a410110782000410c6a200110e2012002200041106a2903003703102001200241106a410810780c070b200241093a00042001200241046a410110782000410c6a200110e201200041106a200110fc05200041386a200110aa040c060b2002410a3a00042001200241046a410110782000410c6a200110fc050c050b200241183a00102001200241106a41011078200041086a22052d0000417f6a2203410b4b0d0402400240024002400240024002400240024002400240024020030e0c000102030405060708090a0b000b200241003a00042001200241046a41011078200041106a29030021072002200041186a290300370318200220073703102001200241106a411010780c0f0b200241013a00042001200241046a4101107820022000410c6a2802003602102001200241106a410410780c0e0b200241023a00042001200241046a410110782001200541016a41201078200041306a29030021072002200041386a290300370318200220073703102001200241106a41101078200041c0006a29030021072002200041c8006a290300370318200220073703102001200241106a411010780c0d0b200241033a00042001200241046a4101107820022000410c6a2802003602102001200241106a410410780c0c0b200241043a00042001200241046a410110782000410c6a200110fc05200220002d00093a00042001200241046a410110780c0b0b200241053a00042001200241046a41011078200220052d00013a00042001200241046a410110780c0a0b200241063a00042001200241046a410110780c090b200241073a00042001200241046a410110782001200541016a4120107820022000412c6a2802003602102001200241106a41041078200041306a2802002103200041386a28020022002001107720012003200010780c080b200241083a00042001200241046a410110780c070b200241093a00042001200241046a410110782001200541016a412010782002200541216a2d00003a00042001200241046a410110780c060b2002410a3a00042001200241046a410110782001200541016a41201078200541216a2d0000220041024b0d0502400240024020000e03000102000b200241003a00042001200241046a410110780c070b200241013a00042001200241046a410110780c060b200241023a00042001200241046a410110780c050b2002410b3a00042001200241046a4101107820022000410c6a2802003602102001200241106a410410780c040b200241193a00102001200241106a4101107820002d0004417f6a220341084b0d03200041046a210502400240024002400240024002400240024020030e09000102030405060708000b200241003a00042001200241046a410110782001200541016a41201078200041286a280200200110af030c0b0b200241013a00042001200241046a410110782001200541016a412010782001200541216a412010780c0a0b200241023a00042001200241046a41011078200041086a2802002103200041106a28020022052001107702402005450d002005410574210503402001200341201078200341206a2103200541606a22050d000b0b200220002f01063b01102001200241106a41021078200220002802143602102001200241106a410410780c090b200241033a00042001200241046a410110782001200541016a412010780c080b200241043a00042001200241046a410110782001200541016a412010782001200541216a412010780c070b200241053a00042001200241046a410110782001200541016a412010780c060b200241063a00042001200241046a410110782001200541016a412010780c050b200241073a00042001200241046a410110780c040b200241083a00042001200241046a410110782001200541016a412010780c030b2002411a3a00102001200241106a41011078200041086a280200417f6a220341024b0d0202400240024020030e03000102000b200241003a00042001200241046a410110780c040b200241013a00042001200241046a410110782000410c6a200110fc050c030b200241023a00042001200241046a410110782000410c6a200110fc05200041306a29030021072002200041386a290300370318200220073703102001200241106a41101078200041c0006a29030021072002200041c8006a290300370318200220073703102001200241106a411010782002200041d0006a2802003602102001200241106a410410780c020b2002411b3a00102001200241106a410110780b200110ff050b200241206a24000f0b1045000bf30703027f017e067f230041e0006b2203240041a8fdc600ad4280808080f00084100122042900002105200341086a200441086a29000037030020032005370300200410354180a9c300ad4280808080900184100122042900002105200341106a41086a200441086a29000037030020032005370310200410350240024002400240412010332204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020032004ad42808080808004841003220129000037034020011035200341dc006a2206200441206a360200200320043602582003200341c0006a41086a3602542003200341c0006a360250200341206a200341d0006a107b20041035412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a2900003700002004ad4280808080800484100422012900002105200341c0006a41086a200141086a29000037030020032005370340200110352006200441206a360200200320043602582003200341c0006a41106a3602542003200341c0006a360250200341306a200341d0006a107b200410352003280228220741206a2206200328023822086a2201417f4c0d01200328023021092003280220210a0240024020010d004100210b410121040c010b200110332204450d012001210b0b02400240200b410f4d0d00200b21020c010b200b41017422024110200241104b1b22024100480d030240200b0d002002103322040d010c050b200b2002460d002004200b200210372204450d040b20042003290300370000200441086a200341086a2903003700000240024020024170714110460d002002210b0c010b2002410174220b4120200b41204b1b220b4100480d032002200b460d0020042002200b10372204450d040b20042003290310370010200441186a200341106a41086a29030037000002400240200b41606a2007490d00200b21020c010b2007415f4b0d03200b41017422022006200220064b1b22024100480d03200b2002460d002004200b200210372204450d040b200441206a200a2007109d081a02400240200220066b2008490d002002210b0c010b20012006490d032002410174220b2001200b20014b1b220b4100480d03024020020d000240200b0d00410121040c020b200b10332204450d050c010b2002200b460d0020042002200b10372204450d040b200420066a20092008109d081a200020013602082000200b3602042000200436020002402003280234450d00200910350b02402003280224450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000bb10101027f024020002802082201450d0020002802002100200141246c210103400240024020002d0000220241044b0d0002400240024020020e050400010204040b2000410c6a280200450d03200041086a28020010350c030b2000410c6a280200450d02200041086a28020010350c020b2000410c6a280200450d01200041086a28020010350c010b200041086a280200450d00200041046a28020010350b200041246a21002001415c6a22010d000b0b0b13002000410c36020420004190aac3003602000beb0d02097f027e230041e0006b22022400200241386a4100290288e146370300200241306a4100290280e146370300200241286a41002902f8e046370300200241206a41002902f0e046370300200241186a41002902e8e046370300200241106a41002902e0e046370300200241086a41002902d8e046370300200241002902d0e0463703002002410036024820024201370340200241d0006a200210b40320022802502103024002400240024020022802442204200228024822056b20022802582206490d00200228024021070c010b200520066a22072005490d01200441017422082007200820074b1b22084100480d010240024020040d00024020080d00410121070c020b2008103322070d010c040b2002280240210720042008460d0020072004200810372207450d030b20022008360244200220073602400b200720056a20032006109d081a2002200520066a36024802402002280254450d00200310350b200241d0006a200241106a10b403200228025021080240024020022802442204200228024822056b20022802582203490d0020022802402106200421070c010b200520036a22062005490d01200441017422072006200720064b1b22074100480d010240024020040d00024020070d00410121060c020b200710332206450d040c010b2002280240210620042007460d0020062004200710372206450d030b20022007360244200220063602400b200620056a20082003109d081a2002200520036a220336024802402002280254450d00200810350b02400240200720036b4104490d00200341046a21050c010b200341046a22052003490d01200741017422042005200420054b1b22044100480d010240024020070d00024020040d00410121060c020b200410332206450d040c010b20072004460d0020062007200410372206450d030b20022004360244200220063602400b200620036a410a3600002002200536024820022802242103024002402002280244220720056b4104490d00200228024021060c010b200541046a22062005490d01200741017422042006200420064b1b22044100480d010240024020070d00024020040d00410121060c020b200410332206450d040c010b2002280240210620072004460d0020062007200410372206450d030b20022004360244200220063602400b200620056a20033600002002200541046a220636024820022802282104024002402002280244220320066b4104490d00200228024021070c010b200641046a22072006490d01200341017422082007200820074b1b22084100480d010240024020030d00024020080d00410121070c020b200810332207450d040c010b2002280240210720032008460d0020072003200810372207450d030b20022008360244200220073602400b200720066a20043600002002200541086a360248200241306a2802002108200241386a200241346a200228022c4101461b2802002205200241c0006a1077024002402005410c6c22050d00200228024821040c010b200820056a21092002280244210620022802482104034002400240200620046b4108490d00200441086a210520022802402103200621070c010b200441086a22052004490d03200641017422072005200720054b1b22074100480d030240024020060d00024020070d00410121030c020b200710332203450d060c010b2002280240210320062007460d0020032006200710372203450d050b20022007360244200220033602400b200320046a200829000037000020022005360248200841086a280200210402400240200720056b41034d0d00200721060c010b200541046a22062005490d032007410174220a2006200a20064b1b22064100480d030240024020070d00024020060d00410121030c020b200610332203450d060c010b20072006460d0020032007200610372203450d050b20022006360244200220033602400b200320056a20043600002002200541046a22043602482008410c6a22082009470d000b0b200228023c2107024002402002280244220620046b4104490d00200228024021050c010b200441046a22052004490d01200641017422032005200320054b1b22034100480d010240024020060d00024020030d00410121050c020b200310332205450d040c010b2002280240210520062003460d0020052006200310372205450d030b20022003360244200220053602400b200520046a2007360000200441046aad210b2002350240210c02402002280200450d00200241086a280200450d00200228020410350b200b422086210b02402002280210450d00200241186a280200450d00200241146a28020010350b200b200c84210b0240200228022c450d0020022802342205450d002005410c6c450d00200228023010350b200241e0006a2400200b0f0b103e000b103c000bd80401067f20012802042102024002400240024020012802004101470d002001410c6a280200220141046a2203417f4c0d0102400240024002400240024002400240024002402003450d00200310332204450d0c200141c000490d04200141808001490d052001418080808004490d0620030d010b41012103410110332204450d07200441033a0000410521050c010b200441033a000002402003417f6a41034d0d00200321050c020b200341017422064105200641054b1b22054100480d0720032005460d010b20042003200510372204450d050b20042001360001410521060c030b024020030d0041012103410110332204450d040b200420014102743a000041012106200321050c020b02400240200341014d0d00200321050c010b200341017422064102200641024b1b2105024020030d002005103322040d010c040b20032005460d0020042003200510372204450d030b41022106200420014102744101723b00000c010b02400240200341034d0d00200321050c010b200341017422064104200641044b1b22054100480d03024020030d002005103322040d010c030b20032005460d0020042003200510372204450d020b20042001410274410272360000410421060b0240200520066b2001490d00200521030c060b200620016a22032006490d01200541017422072003200720034b1b22034100480d0120052003460d05200420052003103722040d050b103c000b103e000b20002002200141086a28020010d3030f0b1044000b1045000b200420066a20022001109d081a2000200620016a36020820002003360204200020043602000b9b1a03047f017e057f230041a00e6b22022400024002402001450d00200220003602300c010b200241b0b4cc003602300b20022001360234200241c00a6a200241306a10b60302400240024020022802c40a450d00200241386a200241c00a6a41fc00109d081a200241b8016a200241386a41fc00109d081a200241b8016a10b703024020022802b8012201450d00200241b8026a2001417f6a10b803200241c00a6a20022802b802220120022802c00210d501200241e8066a41086a2200200241c90a6a290000370300200241e8066a41106a2203200241d10a6a290000370300200241e8066a41186a2204200241d90a6a290000370300200220022900c10a3703e8060240024020022d00c00a4101460d00200241a8036a41186a4200370300200241a8036a41106a4200370300200241a8036a41086a4200370300200242003703a8030c010b200241a8036a41186a2004290300370300200241a8036a41106a2003290300370300200241a8036a41086a2000290300370300200220022903e8063703a8030b024020022802bc02450d00200110350b200241a8036a200241c8016a412010a0080d00200241b0026a280200210120022802a8022100200241003602f006200242043703e806200241e8066a4100200110870120022802f006210402402001450d00200141c8036c21032001410374210520022802e8062004410c6c6a21010340200220003602a803200241c00a6a200241a8036a10b903200141086a200241c00a6a41086a280200360200200120022903c00a3702002001410c6a2101200041c8036a2100200341b87c6a22030d000b200541786a41037620046a41016a21040b200241a8036a41086a2004360200200220022903e80622063703a803200241e8066a41086a2004360200200220063703e806200241c00a6a200241e8066a10ba03024020024188026a2201200241c00a6a412010a008450d0041ec9ccc00ad4280808080e0018410062001ad4280808080800484100a200241c00a6aad4280808080800484100a0b02402001200241c00a6a412010a0080d00100b200241ac026a280200210720022802a802210520022802b0022103200241b8026a200241b8016a41f000109d081a2005200341c8036c6a210020022802b8022108200521010240024002402003450d00200241e8066a41f0006a2104200521010240034020024180066a200141e800109d081a200141e8006a2903002106200241a8036a200141f0006a41d802109d081a20064203510d01200241e8066a20024180066a41e800109d081a200220063703d0072004200241a8036a41d802109d081a2002200241e8066a3602b00a200241c00a6a200241b00a6a10b90320022802c80a2103024020022802c40a450d0020022802c00a10350b200241c00a6a200241e8066a41c803109d081a200241003602880e200241b00a6a200241c00a6a2003200241880e6a10bb0320022d00b00a4101460d04200141c8036a22012000470d000c030b0b200141c8036a21010b20002001460d00034020014198016a10bb022000200141c8036a2201470d000b0b02402007450d00200741c8036c450d00200510350b10bc03200810bd030240100c4101470d00200241c00a6a10be03200241206a200241b8026a410472220110bf032002200228022422003602980e200241186a200241c00a6a410472220310bf032002200228021c220436029c0e20002004470d06200241106a200110bf0320022802102105200241086a200310bf03200228020c220120022802142200200020014b1b2209450d05200228020821074100210341edc5ca00ad4280808080c002842106410021040340024002400240024002400240024002400240200520036a22012d00002208200720036a22002d0000470d0002400240024002400240024020080e06000102030405000b20052007460d0d200141016a200041016a412010a0080d050c060b024020052007460d00200141016a280000200041016a280000470d050b200141106a2802002208200041106a280200470d04200141086a280200220a200041086a280200220b460d0a200a200b200810a0080d040c0a0b024020052007460d00200141016a280000200041016a280000470d040b200141106a2802002208200041106a280200470d03200141086a280200220a200041086a280200220b460d08200a200b200810a0080d030c080b024020052007460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a280200220a200041086a280200220b460d06200a200b200810a0080d020c060b200141046a2802002208200041046a280200470d012008450d04200141086a280200200041086a280200470d012001410c6a2802002000410c6a280200470d010c040b2001410c6a28020022082000410c6a280200470d00200141046a280200220a200041046a280200220b460d02200a200b200810a008450d020b20061006200241e8066a200110c00320023502f00642208620022802e8062208ad84100a024020022802ec06450d00200810350b200241e8066a200010c00320023502f00642208620022802e8062208ad84100a024020022802ec06450d00200810350b20012d000020002d00002208470d06024020080e06000605040302000b20052007460d070b200141016a200041016a412010a0080d050c060b2001410c6a28020022082000410c6a280200470d04200141046a2802002201200041046a2802002200460d0520012000200810a0080d040c050b200141046a2802002208200041046a280200470d032008450d04200141086a280200200041086a280200470d032001410c6a2802002000410c6a280200460d040c030b024020052007460d00200141016a280000200041016a280000470d030b200141106a2802002208200041106a280200470d02200141086a2802002201200041086a2802002200460d0320012000200810a0080d020c030b024020052007460d00200141016a280000200041016a280000470d020b200141106a2802002208200041106a280200470d01200141086a2802002201200041086a2802002200460d0220012000200810a0080d010c020b024020052007460d00200141016a280000200041016a280000470d010b200141106a2802002208200041106a280200470d00200141086a2802002201200041086a2802002200460d0120012000200810a008450d010b4188cfc400412741c086cc00103f000b200341246a2103200441016a22042009490d000c060b0b41d7cfc400411e41c086cc00103f000b200241286a20022f00b10a20022d00b30a4110747210c1032002280228200228022c41c086cc00103f000b41dccec400412441c086cc00103f000b41c0cec400411c41c086cc00103f000b200241b4036a4104360200200241fc066a4102360200200242023702ec06200241f0b2c3003602e806200241043602ac03200241e8b2c3003602a803200241003602bc01200241b0b4cc003602b8012002200241a8036a3602f8062002200241b8016a3602b003200241e8066a4180b3c300104c000b0240200241b8026a41306a2201200241c00a6a41306a2200412010a008450d0041ec9ccc00ad4280808080e0018410062001ad4280808080800484100a2000ad4280808080800484100a0b024020012000412010a008450d0041afcfc400412841c086cc00103f000b0240200241c00a6a410c6a2802002200450d0020022802c40a2101200041246c210003400240024020012d0000220341044b0d0002400240024020030e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b0240200241c80a6a2802002201450d00200141246c450d0020022802c40a10350b0240200241b8026a410c6a2802002200450d0020022802bc022101200041246c210003400240024020012d0000220341044b0d0002400240024020030e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b0240200241c0026a2802002201450d00200141246c450d0020022802bc0210350b200241a00e6a240042010f0b200241a8036a41146a410a360200200241b4036a410c36020020024180066a41146a41033602002002200241980e6a3602880e20022002419c0e6a3602b00a200241e8066a41146a41003602002002420337028406200241a0b3cc00360280062002410c3602ac03200241b0b4cc003602f806200242013702ec0620024180cfc4003602e8062002200241a8036a360290062002200241e8066a3602b8032002200241b00a6a3602b0032002200241880e6a3602a80320024180066a41b0b4cc00104c000bc10603077f017e037f230041c00b6b22022400200241f8076a200110c4030240024020022802fc072203450d0020024184086a2802002104200228028008210520022802f8072106200241086a20024188086a41e000109d081a2002200110c40102400240024020022802000d0020022802042207200128020441c8036e2208200820074b1bad42c8037e2209422088a70d012009a7220a417f4c0d0102400240200a0d004108210b0c010b200a1033220b450d030b41002108200241003602702002200b3602682002200a41c8036e36026c024002402007450d00200241f8076a41f0006a210c0340200241f8076a200110c80320024190076a200241f8076a41e800109d081a20022903e0082109200241b8046a200c41d802109d081a20094203510d02200241d0036a20024190076a41e800109d081a200241f8006a200241b8046a41d802109d081a02402008200228026c470d00200241e8006a200810a9012002280268210b200228027021080b200b200841c8036c6a200241d0036a41e800109d08220a2009370368200a41f0006a200241f8006a41d802109d081a2002200841016a22083602702007417f6a22070d000b0b200b450d01200229026c2109200241f8076a200241086a41e000109d081a2000410c6a2004360200200020053602082000200336020420002006360200200041106a200241f8076a41e000109d081a200041f4006a2009370200200041f0006a200b3602000c050b02402008450d00200841c8036c2107200b4198016a21080340200810bb02200841c8036a2108200741b87c6a22070d000b0b200228026c2208450d00200841c8036c450d00200b10350b2000410036020402402004450d00200441246c21072003210803400240024020082d0000220141044b0d0002400240024020010e050400010204040b2008410c6a280200450d03200841086a28020010350c030b2008410c6a280200450d02200841086a28020010350c020b2008410c6a280200450d01200841086a28020010350c010b200841086a280200450d00200841046a28020010350b200841246a21082007415c6a22070d000b0b2005450d03200541246c450d03200310350c030b1044000b1045000b200041003602040b200241c00b6a24000bb83a05047f017e057f017e107f230041f01a6b22012400200141186a200010df03200141c8156a41186a4200370300200141c8156a41106a22024200370300200141c8156a41086a22034200370300200142003703c81541d1c4c700ad4280808080e000841001220429000021052003200441086a290000370300200120053703c8152004103541c8f1c700ad4280808080a00284100122042900002105200141b8106a41086a2206200441086a290000370300200120053703b81020041035200220012903b8102205370300200141a0186a41086a2003290300370300200141a0186a41106a2005370300200141a0186a41186a2006290300370300200120012903c8153703a0182001412036028c062001200141a0186a36028806200141e80d6a200141a0186aad22054280808080800484100510c20102400240024002400240024002400240024002400240024020012802e80d22040d00410221030c010b20012802ec0d21072001200141e80d6a41086a2802003602dc08200120043602d808200141106a200141d8086a10c401200128021421080240024020012802100d00200141086a200141d8086a10c40120012802080d0020012802dc082209200128020c2203490d002003417f4c0d030240024020030d0041002109410121060c010b200310392206450d09200620012802d808220a2003109d081a2001200920036b3602dc082001200a20036a3602d808200321090b2006450d002003ad4220862009ad84210b410121030c010b200141003602c010200142013703b810200141093602ac0b200120014188066a3602a80b2001200141b8106a3602b803200141dc156a4101360200200142013702cc15200141c888c2003602c8152001200141a80b6a3602d815200141b8036a41e88ac500200141c8156a10431a20013502c01042208620013502b810841006024020012802bc10450d0020012802b81010350b410221030b2007450d00200410350b02400240024002400240024020034102460d00200ba72104410121070240200841f501490d00410021080240200b422088a7200420034101461b4104470d004101210820064190e1c600460d00200628000041eede91ab064621080b200841017321070b02402004450d00200610350b2007450d010b200141c4106a41002902d8e046370200200141f5013602b810200141002902d0e0463702bc10200141c8156a41186a4200370300200141c8156a41106a22064200370300200141c8156a41086a22034200370300200142003703c81541d1c4c700ad4280808080e0008410012204290000210b2003200441086a2900003703002001200b3703c8152004103541c8f1c700ad4280808080a0028410012204290000210b200141286a41086a2208200441086a2900003703002001200b3703282004103520062001290328220b370300200141a0186a41086a2003290300370300200141a0186a41106a200b370300200141a0186a41186a2008290300370300200120012903c8153703a018200141003602f00d200142013703e80d41f501200141e80d6a1077200141c8156a200141b8106a41047210b40320012802c81521090240024020012802ec0d220720012802f00d22046b20012802d0152206490d0020012802e80d2103200721080c010b200420066a22032004490d02200741017422082003200820034b1b22084100480d020240024020070d00024020080d00410121030c020b2008103322030d010c110b20012802e80d210320072008460d0020032007200810372203450d100b200120083602ec0d200120033602e80d0b200320046a20092006109d081a2001200420066a22043602f00d024020012802cc15450d00200910350b200542808080808004842004ad4220862003ad84100202402008450d00200310350b420010c8040b2000280200200041106a200041d0006a200141186a410110e00320012000280200220c36023c2001428089fa00370340200141a0186a200c10c904200141c8156a20012802a018220020012802a818220310b8020240024020012802c815220d0d00420021054108210d0c010b2003ad4220862000ad84100720012902cc1521050b024020012802a418450d00200010350b200d2005422088a7220341d0026c22066a21042005a7210e200d21002003450d07200641b07d6a2107200141c8156a41046a210f200141a0186a41046a210a200141e80d6a41046a211041002106200141d8006a41086a2108200d210002400340200141e8006a200041bc02109d081a200041bc026a28020021032008200041c8026a2903003703002001200041c0026a290300370358024020034103470d00200041d0026a21000c0a0b2010200141e8006a41bc02109d082111200141a0186a200141e80d6a41c002109d081a20014188136a200a41bc02109d081a200141f8126a41086a22092008290300370300200120012903583703f8120240024020034102470d00410121090c010b200f20014188136a41bc02109d081a200141a80b6a200141c8156a41c002109d081a200141980b6a41086a2009290300370300200120012903f8123703980b41002109200621120b200141d8086a200141a80b6a41c002109d081a200141c8086a41086a200141980b6a41086a290300370300200120012903980b3703c8082009450d01200641016a2106200741b07d6a2107200041d0026a22002004470d000b200421000c080b200141b8036a200141d8086a41c002109d081a200141a8036a41086a2208200141c8086a41086a290300370300200120012903c8083703a803200141b8106a200141b8036a41c002109d081a200141a8106a41086a22092008290300370300200120012903a8033703a810200041d0026a210020034102460d0720014188066a200141b8106a41c002109d081a200141f8056a41086a22082009290300370300200120012903a8103703f805200141c8156a20014188066a41c002109d081a200141a0186a41086a2008290300370300200120012903f8053703a01841d80210332213450d0920132012360200201341046a200141c8156a41c002109d081a201320033602c402201320012903a0183703c802201341d0026a200141a0186a41086a290300370300200142818080801037024c20012013360248200421032007450d02200641016a2108200141b8106a41046a2109200141980b6a41086a210302400340200141b8036a200041bc02109d081a200041bc026a28020021062003200041c8026a2903003703002001200041c0026a2903003703980b024020064103470d00200041d0026a21030c050b2009200141b8036a41bc02109d081a200141a0186a200141b8106a41c002109d081a20014188136a200a41bc02109d081a200141f8126a41086a22072003290300370300200120012903980b3703f8120240024020064102470d00410121070c010b200f20014188136a41bc02109d081a200141e80d6a200141c8156a41c002109d081a200141e8006a41086a2007290300370300200120012903f81237036841002107200821100b200141a80b6a200141e80d6a41c002109d081a200141a8106a41086a200141e8006a41086a290300370300200120012903683703a8102007450d01200841016a2108200041d0026a22002004470d000b20042103410121140c040b200141d8086a200141a80b6a41c002109d081a200141c8086a41086a2209200141a8106a41086a2215290300370300200120012903a8103703c808200041d0026a21034101211420064102460d03200841016a210020014188066a200141d8086a41c002109d081a200141f8056a41086a22162009290300370300200120012903c8083703f80541012108410121140340200141c8156a20014188066a41c002109d081a200141a0186a41086a22072016290300370300200120012903f8053703a018024020142008470d00200141c8006a20084101109501200128024821130b2013201441d8026c6a22082010360200200841046a200141c8156a41c002109d081a200841c4026a2006360200200841c8026a20012903a018370300200841d0026a20072903003703002001201441016a2214360250024020032004470d00200421030c050b02400340200141e8006a200341bc02109d081a200341bc026a2802002106200141d8006a41086a2208200341c8026a2903003703002001200341c0026a290300370358024020064103470d00200341d0026a21030c070b2011200141e8006a41bc02109d081a200141a0186a200141e80d6a41c002109d081a20014188136a200a41bc02109d081a200141f8126a41086a22072008290300370300200120012903583703f8120240024020064102470d00410121080c010b200f20014188136a41bc02109d081a200141a80b6a200141c8156a41c002109d081a200141286a41086a20072903002205370300200141980b6a41086a2005370300200120012903f8122205370328200120053703980b41002108200021120b200141d8086a200141a80b6a41c002109d081a2009200141980b6a41086a290300370300200120012903980b3703c8082008450d01200041016a2100200341d0026a22032004470d000b200421030c050b200141b8036a200141d8086a41c002109d081a200141a8036a41086a22082009290300370300200120012903c8083703a803200141b8106a200141b8036a41c002109d081a20152008290300370300200120012903a8033703a81020064102460d02200341d0026a2103200041016a210020014188066a200141b8106a41c002109d081a20162015290300370300200120012903a8103703f805200128024c2108201221100c000b0b103e000b200341d0026a21030c010b410121140b024020042003460d000340200341d0026a21000240200341bc026a2802004102460d000240200341b0026a2802002206450d00200341b4026a280200450d00200610350b200310bb020b2000210320042000470d000b0b0240200e450d00200e41d0026c450d00200d10350b200128024c211720144115490d022014410176ad42d8027e2205422088a70d002005a72218417f4c0d00201810332219450d0541002100200141003602a818200142043703a018201341a87d6a211a201341c87a6a211b410421034100210f20142112034020122109410021124101210702402009417f6a220e450d000240024002400240024002402013200e41d8026c6a41d0026a2d0000200941d8026c221020136a41a07d6a2d00002206490d002009417e6a210a201b20106a2108410021124100210403400240200a2004470d00200921070c080b200441016a2104200641ff0171210720082d00002106200841a87d6a2108200720064f0d000b200441016a21072004417f7320096a21040c010b201b20106a2108200e210402400340024020044101470d00410021040c020b2004417f6a2104200641ff0171210720082d00002106200841a87d6a210820072006490d000b0b20092004490d02200920144b0d01200920046b2207410176220a450d002013200441d8026c6a2106201a20106a21080340200141c8156a200641d802109d081a2006200841d802109e0841d8026a21062008200141c8156a41d802109d0841a87d6a2108200a417f6a220a0d000b0b024020040d00200421120c050b0240200741094d0d00200421120c050b200920144b0d022013200441d8026c6a2110034020092004417f6a2212490d040240200920126b22074102490d002013200441d8026c6a220841d0026a2d00002013201241d8026c6a220641d0026a2d0000220d4f0d00200141c8156a200641d002109d081a2001200641d4026a2800003600bb102001200641d1026a2800003602b8102006200841d802109d082111024020074103490d00200e210a2010210620114180086a2d0000200d4f0d0003402006200641d8026a220841d802109d0821112004200a417f6a220a460d012008210620114180086a2d0000200d490d000b0b2008200141c8156a41d002109d08220441d0026a200d3a0000200441d1026a20012802b810360000200441d4026a20012800bb103600000b2012450d05201041a87d6a2110201221042007410a4f0d050c000b0b2009201441eccfca001058000b2004200941eccfca001059000b20092004417f6a2212490d002009201441fccfca001058000b2012200941fccfca001059000b0240200f20012802a418470d00200141a0186a200f410110900120012802a018210320012802a8182200210f0b2003200f4103746a22042007360204200420123602002001200041016a22003602a8182000210f024020004102490d000240024003400240024002400240024020032000417f6a4103746a2204280200450d00200041037420036a220741746a2802002208200428020422064b0d010b20004103490d022004280204210620032000417d6a22114103746a28020421040c010b4102210f200041024d0d0620032000417d6a22114103746a2802042204200620086a4d0d004103210f200041034d0d06200741646a280200200420086a4b0d050b20042006490d010b2000417e6a21110b02400240024002400240024002402000201141016a220d4d0d00200020114d0d0120032011410374220e6a2200280204221520002802006a22002003200d41037422166a2203280200220f490d02200020144b0d032013200f41d8026c6a220a2003280204221041d8026c22036a2106200041d8026c21072000200f6b220820106b220020104f0d0420192006200041d8026c2203109d08220820036a210420104101480d0520004101480d05201a20076a21072006210303402007200341a87d6a2206200441a87d6a2209200441786a2d0000200341786a2d00004922001b41d802109d0821072004200920001b21040240200a2006200320001b2203490d00200821000c080b200741a87d6a21072008210020082004490d000c070b0b200d2000418cd0ca001042000b20112000419cd0ca001042000b200f200041acd0ca001059000b2000201441acd0ca001058000b2019200a2003109d08220020036a2104024020104101480d00200820104c0d00201320076a210920002100200a2103034020062000200641d0026a2d0000200041d0026a2d00004922081b21072000200041d8026a20081b21002003200741d802109d0841d8026a2103200641d8026a200620081b220620094f0d03200420004b0d000c030b0b200a2103200021000c010b20062103200821000b20032000200420006b2204200441d802706b109d081a024020012802a818220020114d0d0020012802a0182203200e6a2204201520106a3602042004200f3602002000200d4d0d02200320166a2204200441086a2000200d417f736a410374109e081a20012000417f6a22003602a818200041014b0d010c030b0b2011200041bcd0ca001042000b200d2000104e000b2000210f0b2012450d020c000b0b1044000b024020012802a41841ffffffff0171450d00200310350b201841d802702100201841d802490d0220182000460d02201910350c020b20144102490d012014417f6a21032013201441d8026c6a2106410021080340024002400240201420032200417f6a2203490d00201420036b22074102490d022013200041d8026c6a220041d0026a2d00002013200341d8026c6a220441d0026a2d000022094f0d02200141c8156a200441d002109d081a2001200441d4026a2800003600bb102001200441d1026a2800003602b8102004200041d802109d08210a20074103490d012008210420062107200a4180086a2d000020094f0d0103402007220041a87d6a200041d802109d081a2004417f6a2204450d02200041d8026a2107200041a8056a2d000020094f0d020c000b0b2003201441dccfca001059000b2000200141c8156a41d002109d08220041d0026a20093a0000200041d1026a20012802b810360000200041d4026a20012800bb103600000b200841016a2108200641a87d6a210620030d000c020b0b024020042000460d000340200041d0026a21030240200041bc026a2802004102460d000240200041b0026a2802002206450d00200041b4026a280200450d00200610350b200010bb020b2003210020042003470d000b0b41002114410821130240200e450d00200e41d0026c450d00200d10350b410021170b200142003703d808200141800e6a4100360200200141fc0d6a2013201441d8026c6a360200200141f80d6a2013360200200141f40d6a2017360200200141900e6a200141d8086a3602002001418c0e6a2001413c6a360200200120133602f00d200142003703e80d2001200141c0006a3602880e200141a0186a200141e80d6a10ca04024020012802dc1a4103460d00200141c8156a200141a0186a41d002109d081a41d00210332206450d012006200141c8156a41d002109d08210020014281808080103702ac0b200120003602a80b200141b8106a41286a200141e80d6a41286a290300370300200141b8106a41206a200141e80d6a41206a290300370300200141b8106a41186a200141e80d6a41186a290300370300200141b8106a41106a2208200141e80d6a41106a290300370300200141b8106a41086a200141e80d6a41086a290300370300200120012903e80d3703b810200141a0186a200141b8106a10ca04024020012802dc1a4103470d00410121030c030b4102210341d0022100410121040340200141c8156a200141a0186a41d002109d081a02402003417f6a2004470d00200141a80b6a2004410110a70120012802a80b21060b200620006a200141c8156a41d002109d081a200120033602b00b200141a0186a200141b8106a10ca0420012802dc1a4103460d03200041d0026a2100200341016a210320012802ac0b21040c000b0b20012802fc0d20012802f80d22046b220041d8026d210302402000450d00200341d8026c2103200441bc026a2100034002402000417c6a2802002204450d002000280200450d00200410350b200041cc7d6a10bb02200041d8026a2100200341a87d6a22030d000b0b024020012802f40d2200450d00200041d8026c450d0020012802f00d10350b41082106410021080c020b1045000b200141cc106a280200200828020022086b220041d8026d210402402000450d00200441d8026c2104200841bc026a2100034002402000417c6a2802002208450d002000280200450d00200810350b200041cc7d6a10bb02200041d8026a2100200441a87d6a22040d000b0b0240200141c4106a2802002200450d00200041d8026c450d0020012802c01010350b20012802ac0b21082003450d00200128023c41016a2006200310cb04200341d0026c210320012903d80821052006210003400240200041bc026a2802004102460d000240200041b0026a2802002204450d00200041b4026a280200450d00200410350b200010bb020b200041d0026a2100200341b07d6a22030d000c020b0b20012903d80821050b02402008450d00200841d0026c450d00200610350b427f427f2005200c10cc047c220b200b2005541b22054280e497d0127c220b200b2005541b10c804200142003703e80d200141c8156a41186a22044200370300200141c8156a41106a22064200370300200141c8156a41086a22004200370300200142003703c81541d1c4c700ad4280808080e000841001220329000021052000200341086a290000370300200120053703c815200310354188f2c700ad4280808080e00184100122032900002105200141b8106a41086a2208200341086a290000370300200120053703b81020031035200220012903b810370000200241086a2008290300370000200141a0186a41086a2000290300370300200141a0186a41106a2006290300370300200141a0186a41186a2004290300370300200120012903c8153703a018200141203602cc152001200141a0186a3602c815200141e80d6a200141c8156a10cd0420012802182106024020012802202200450d00200041246c21032006210003400240024020002d0000220441044b0d0002400240024020040e050400010204040b2000410c6a280200450d03200041086a28020010350c030b2000410c6a280200450d02200041086a28020010350c020b2000410c6a280200450d01200041086a28020010350c010b200041086a280200450d00200041046a28020010350b200041246a21002003415c6a22030d000b0b0240200128021c2200450d00200041246c450d00200610350b200141f01a6a24000f0b103c000bfc0403027f017e057f230041d0006b2202240041d1c4c700ad4280808080e00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541dec4c700ad4280808080900184100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000b981103067f027e067f230041c0006b22022400024002400240024041ca0310332203450d00200241ca0336020420022003360200200341003b00002002410236020802400240200128020022032903684202520d00024020022802044102470d0020022802004102410410372201450d0620024104360204200220013602000b200228020041043a00022002200228020841016a3602080c010b024020022802044102470d0020022802004102410410372201450d0520024104360204200220013602000b20022802004184013a00022002200228020841016a3602082003200210fc05024020032d0024220141024b0d000240024002400240024020010e03000102000b410021040c020b410121040c010b41022104200241023a001041c10021050c010b200220043a001041c00021050b02400240200228020420022802082201460d00200228020021060c010b200141016a22062001490d05200141017422072006200720064b1b22074100480d050240024020010d0041002101024020070d00410121060c020b2007103322060d010c080b2002280200210620012007460d0020062001200710372206450d070b20022007360204200220063602000b200620016a20043a00002002200141016a2201360208024002402002280204220420016b2005490d00200228020021060c010b200120056a22062001490d05200441017422072006200720064b1b22074100480d050240024020040d00024020070d00410121060c020b200710332206450d080c010b2002280200210620042007460d0020062004200710372206450d070b20022007360204200220063602000b200620016a200341256a2005109d081a2002200120056a3602080b02400240200341e8006a22012903004201520d00200129031020012903082208420c882209420120094201561b8021090240024020022802042204200228020822056b4102490d00200228020021060c010b200541026a22062005490d06200441017422072006200720064b1b22074100480d060240024020040d00024020070d00410121060c020b200710332206450d090c010b2002280200210620042007460d0020062004200710372206450d080b20022007360204200220063602000b200620056a2009a741047420087aa7417f6a22064101200641014b1b2206410f2006410f491b723b0000200541026a21050c010b02400240200228020420022802082205460d00200228020021060c010b200541016a22062005490d05200541017422042006200420064b1b22044100480d050240024020050d0041002105024020040d00410121060c020b200410332206450d080c010b2002280200210620052004460d0020062005200410372206450d070b20022004360204200220063602000b200620056a41003a0000200541016a21050b20022005360208200141186a200210e2012002200141206a360210200241106a200210cf010b20034198016a200210af0320022802082103410410332201450d0020024204370214200220013602102003417e6a200241106a10772002280208220341014d0d01200228021821012002280214210a200220022802102207360224200241286a200720016a2205360200200241023602102002411c6a2002280200220641026a2204360200410021012002410036020820022003417e6a22033602142002200436021820022002360220200241246a210b0240024002402003450d0020072103034020032005460d032002200341016a360224200620016a20032d00003a00002002200228020841016a36020820014101460d02200141016a210120022802242103200228022821050c000b0b2002200b10c7050c010b024020022802282204200228022422036b2201450d00024002402002280220220641046a280200220c2002280214220d2002280210220e6a22056b2001490d00200628020021050c010b200520016a220f2005490d05200c4101742205200f2005200f4b1b220f4100480d0502400240200c0d000240200f0d00410121050c020b200f10332205450d080c010b20062802002105200c200f460d002005200c200f10372205450d070b20062005360200200641046a200f3602000b2005200e20016a22016a2005200e6a200d109e081a20022001360210200120062802082205460d00200520036a417f732004200e6a6a2101200628020020056a2105034020032004460d022002200341016a360224200520032d00003a00002006200628020841016a3602082001450d01200541016a21052001417f6a210120022802242103200228022821040c000b0b2002410036023820024201370330200241306a200b10c7052002280234210b2002280230210e024020022802382203450d00024002402002280220220641046a28020022042002280214220c200228021022056a22016b2003490d00200628020021010c010b200120036a220d2001490d0520044101742201200d2001200d4b1b220d4100480d050240024020040d000240200d0d00410121010c020b200d10332201450d080c010b200628020021012004200d460d0020012004200d10372201450d070b20062001360200200641046a200d3602000b2001200520036a22046a200120056a200c109e081a20022004360210200420062802082201460d00200120056b2104200628020020016a2101200e210503402003450d01200120052d00003a00002006200628020841016a360208200541016a2105200141016a210120042003417f6a2203470d000b0b200b450d00200e10350b02402002280218200228021c2203460d00200220033602180b024020022802142203450d000240200228021022062002280220220441086a22052802002201460d002004280200220420016a200420066a2003109e081a0b2005200320016a3602000b0240200a450d00200710350b20002002290300370200200041086a200241086a280200360200200241c0006a24000f0b1045000b41022003104f000b103e000b103c000bf104020b7f037e230041206b22022400024002400240024020012802082203410c6c41046a2204417f4c0d00200128020021050240024020040d0041012106410021040c010b200410332206450d020b2002410036020820022006360200200220043602042003200210770240024020030d002002280208210420022802042107200228020021080c010b20052003410c6c6a21092005210603402006280200210a200641086a280200220420021077024002402002280204220b2002280208220c6b2004490d0020022802002108200b21070c010b200c20046a2208200c490d05200b41017422072008200720084b1b22074100480d0502400240200b0d00024020070d00410121080c020b2007103322080d010c080b20022802002108200b2007460d002008200b200710372208450d070b20022007360204200220083602000b2008200c6a200a2004109d081a2002200c20046a22043602082006410c6a22062009470d000b0b2004ad4220862008ad8410282204290000210d200441086a290000210e200441106a290000210f200241186a2206200441186a290000370300200241106a220c200f370300200241086a220b200e3703002002200d37030020041035200041186a2006290300370000200041106a200c290300370000200041086a200b2903003700002000200229030037000002402007450d00200810350b02402003450d002003410c6c21062005210403400240200441046a280200450d00200428020010350b2004410c6a2104200641746a22060d000b0b0240200141046a2802002204450d002004410c6c450d00200510350b200241206a24000f0b1044000b1045000b103e000b103c000bdd3d04057f027e077f0b7e230041c00e6b22042400200441b8086a200141c803109d081a200441b0056a200441b8086a10d7034101210502400240024002400240024002400240024020042d00b0054101460d00200441b0026a200441b0056a41086a418003109d081a024020032802002201450d00200341086a280200210620032802042107200441a8026a41c4c3c700411010c00141002105200441b8086a20042802ac02410020042802a8021b10cb0320042802b8082108200420042802c0083602b405200420083602b00520012006200441b0056a109403024020042802bc08450d00200810350b2007450d00200110350b200441800c6a20044180036a10d803200441b8086a200441b0026a418003109d081a024002400240024020042903d80822094202520d0020042903800c220920042d00880c2206200210ce04220841ff01714102470d094200210a200441800d6a41086a22074200370300200441800d6a41106a220b4200370300200441800d6a41186a220c4200370300200442003703800d2004280288094113470d02200441b0056a2004418c096a10dd0320042d00b0054101460d01200441dc056a280200210d200441d8056a280200210e200441d4056a280200210f200441cc056a2802002110200441c8056a28020021110240200441d0056a2802002208450d002008410c6c21022011210803400240200841046a280200450d00200828020010350b2008410c6a2108200241746a22020d000b0b02402010450d002010410c6c450d00201110350b0240200d450d00200d410c6c2102200f210803400240200841046a280200450d00200828020010350b2008410c6a2108200241746a22020d000b0b200e450d02200e410c6c450d02200f10350c020b200441800d6a41186a200441b8086a41186a290300370300200441800d6a41106a200441b8086a41106a290300370300200441800d6a41086a200441b8086a41086a290300370300200420042903b8083703800d20044180096a2903002112200441f8086a290300210a200441f0086a280200210820042903e008211342002114200441900e6a41186a4200370300200441900e6a41106a220b4200370300200441900e6a41086a22064200370300200442003703900e41d1c4c700ad4280808080e000841001220729000021152006200741086a290000370300200420153703900e2007103541e7c4c700ad4280808080e00084100122072900002115200441f80d6a41086a220c200741086a290000370300200420153703f80d20071035200b20042903f80d2215370300200441b0056a41086a2006290300370300200441b0056a41106a2015370300200441b0056a41186a200c290300370300200420042903900e3703b005200441a0026a200441b0056a412010c001024020094201520d0020134200510d060b200441900e6a200441800d6a108e02200441b0056a20042802900e220720042802980e108f020240024020042903b0054201510d0041002106420021094200211542002113420021164200211742002118420021194100210b0c010b200441c0056a2903002119200441d0056a2903002117200441c8056a2903002116200441e0056a2903002113200441d8056a2903002115200441f0056a2903002109200441e8056a2903002114200441f8056a280200210620042903b805211820042802fc05210b0b024020042802940e450d00200710350b024020062008470d00200441b0056a200441800d6a108e0220043502b805211a20042802b0052107410410332206450d072006200841016a36000020064104410810372208450d072008200b3a000420084108411510372208450d07200820183700052008410d6a201937000020084115412a10372208450d07200820163700152008411d6a20173700002008412a41d40010372208450d0720082014370035200820153700252008413d6a20093700002008412d6a2013370000201a4220862007ad842008ad4280808080d00884100220081035024020042802b405450d00200710350b418012210820042d00880c22064102460d0920042903800c22092006200210ce04220841ff01714102470d0920044190026a2002200920042d00890c200a201210db0302400240200429039002221420044190026a41086a29030022158450450d00420021160c010b200441003a00a80d200420153703e80c200420143703e00c41012102200441014111200a201284501b3a008c0e2004200441800d6a3602f80d2004200441800d6a3602c00c2004200441c00c6a3602c00520042004418c0e6a3602bc052004200441f80d6a3602b8052004200441a80d6a3602b4052004200441e00c6a3602b005200441900e6a200441800d6a200441b0056a10dc030240024020042802900e4101470d004200211520042903980e21140c010b200441b80e6a2903002115200441b00e6a2903002114024020042903980e4201510d00410021020c010b200441900e6a41106a290300211320042802c00c2108200441e8056a200441900e6a41186a290300370300200441e0056a201337030041002102200441b0056a41086a41003a0000200441b9056a2008290000370000200441c1056a200841086a290000370000200441c9056a200841106a290000370000200441d1056a200841186a290000370000200441033a00b00541b0b4cc004100200441b0056a10d4010b42012116418002210820020d0a0b200441b80d6a41186a200441800d6a41186a2903002213370300200441b80d6a41106a200441800d6a41106a2903002217370300200441b80d6a41086a200441800d6a41086a2903002218370300200441d80d6a41086a2018370300200441d80d6a41106a2017370300200441d80d6a41186a2013370300200420042903800d22133703b80d200420133703d80d4101210d0c030b418006418004200620084b1b21080c080b20042d00b10522084102470d060b200441b80d6a41186a200c290300370300200441b80d6a41106a200b290300370300200441b80d6a41086a2007290300370300200420042903800d3703b80d4100210d42002112420021160b200441c00c6a41186a2210200441d80d6a41186a2208290300370300200441c00c6a41106a220f200441d80d6a41106a2202290300370300200441c00c6a41086a2211200441d80d6a41086a2207290300370300200420042903d80d3703c00c200441e00c6a41186a200441b80d6a41186a220b290300370300200441e00c6a41106a200441b80d6a41106a220c290300370300200441e00c6a41086a200441b80d6a41086a220e290300370300200420042903b80d3703e00c200441b0056a20044188096a41b002109d081a200820102903003703002002200f29030037030020072011290300370300200420042903c00c3703d80d410221100240200d450d00200b2008290300370300200c2002290300370300200e2007290300370300200420042903d80d3703b80d410121100b2004419a0e6a200e290300370100200441a20e6a200c290300370100200441aa0e6a200b290300370100200420103a00910e200420042903b80d3701920e200441003a00900e200441800d6a200441b0056a200441900e6a10ac03200441800d6a41106a290300211720042903880d2113200420042900990d3703b0052004200441a00d6a2800003600b7050240024020042903800d4201510d00410421080c010b200441800d6a41186a2d00002102200420042800b7053600970e200420042903b0053703900e4104210820134202510d00200420042800970e3600af0d200420042903900e3703a80d200221080b200441b80d6a41186a200441e00c6a41186a290300370300200441b80d6a41106a200441e00c6a41106a290300370300200441b80d6a41086a200441e00c6a41086a290300370300200420042903e00c3703b80d0240024002400240200841ff01714104460d00200641ff01714102460d010b20134201520d024200200920177d221820182009561b2219500d02200441b0056a41186a220c4200370300200441b0056a41106a22074200370300200441b0056a41086a22064200370300200442003703b00541d1c4c700ad4280808080e00084221a1001220b2900002118200441d80d6a41086a2202200b41086a290000370300200420183703d80d200b103520062002290300370300200420042903d80d3703b0054184eec700ad4280808080b00284221b1001220b29000021182002200b41086a290000370300200420183703d80d200b1035200720042903d80d2218370300200441900e6a41086a220e2006290300370300200441900e6a41106a22102018370300200441900e6a41186a220d2002290300370300200420042903b0053703900e20044180026a200441900e6a10e1022004290388022118200429038002211c200c42003703002007420037030020064200370300200442003703b005201a1001220b290000211a2002200b41086a2900003703002004201a3703d80d200b103520062002290300370300200420042903d80d3703b005201b1001220b290000211a2002200b41086a2900003703002004201a3703d80d200b1035200720042903d80d221a370300200e20062903003703002010201a370300200d2002290300370300200420042903b0053703900e201ca70d01200441900e6aad428080808080048410070c020b41801021082016500d08200441900e6a41186a220c4200370300200441900e6a41106a22074200370300200441900e6a41086a22064200370300200442003703900e41b6fdc600ad428080808080018422091001220b2900002112200441f80d6a41086a2202200b41086a290000370300200420123703f80d200b103520062002290300370300200420042903f80d3703900e41e489c200ad4280808080d0018422121001220b290000210a2002200b41086a2900003703002004200a3703f80d200b1035200720042903f80d220a370300200441b0056a41086a220e2006290300370300200441b0056a41106a2210200a370300200441b0056a41186a220d2002290300370300200420042903900e3703b005200441086a200441b0056a412010d701200441086a41106a290300210a200429031021132004280208210b200c42003703002007420037030020064200370300200442003703900e20091001220c29000021092002200c41086a290000370300200420093703f80d200c103520062002290300370300200420042903f80d3703900e20121001220c29000021092002200c41086a290000370300200420093703f80d200c1035200720042903f80d2209370300200e200629030037030020102009370300200d2002290300370300200420042903900e3703b00520044200200a4200200b1b220920157d20134200200b1b2215201454ad7d2212201520147d2214201556201220095620122009511b22021b3703980e20044200201420021b3703900e200441b0056aad4280808080800484200441900e6aad428080808080028410020c080b20044200201820197d221920192018561b3703b005200441900e6aad4280808080800484200441b0056aad428080808080018410020b200441d80d6a41186a200441b80d6a41186a290300370300200441d80d6a41106a200441b80d6a41106a290300370300200441d80d6a41086a200441b80d6a41086a290300370300200420042903b80d3703d80d02402016500d0042002116200441f0016a4200200920177d221720172009561b420020134201511b10cf0420042903f00121092004200441f0016a41086a29030022133703800e200420093703f80d02400240024002400240200920138450450d00420021090c010b2004200441d80d6a36028c0e200441900e6a200441d80d6a200441f80d6a2004418c0e6a109a0220042802900e4101460d01200441b80e6a2903002109200441b00e6a2903002116200441900e6a41086a2903004201520d00200441900e6a41106a2903002113200441e8056a200441900e6a41186a290300370300200441e0056a2013370300200441b0056a41086a41003a0000200441b9056a20042903d80d370000200441c1056a200441d80d6a41086a290300370000200441c9056a200441d80d6a41106a290300370000200441d1056a200441d80d6a41186a290300370000200441033a00b00541b0b4cc004100200441b0056a10d4010b20142016542202201520095420152009511b0d01201520097d2002ad7d2115201420167d21140b200441f0006a201220152014200a56201520125620152012511b22021b2212420042d0004200108408200441b0016a200a201420021b2209420042d000420010840820044180016a4200420020094200108408200441d0016a20042903b001200441b0016a41086a290300220a20042903702004290380017c7c221342e4004200109808200441a0016a201520127d2014200954ad7d2215420042d0004200108408200441c0016a201420097d2214420042d000420010840820044190016a4200420020144200108408200441e0016a20042903c001200441c0016a41086a290300221620042903a0012004290390017c7c221742e4004200109808427f201242dc9e8aae8f85d7c702200441d0016a41086a2903002004290378200429038801844200522013200a547222021b220a201242c2eba3e1f5d1f0fa2820042903d00120021b2213200954200a201254200a2012511b22021b22187d20092013200920021b221254ad7d220a201542dc9e8aae8f85d7c702200441e0016a41086a29030020042903a8012004290398018442005220172016547222021b2213201542c2eba3e1f5d1f0fa2820042903e00120021b2216201454201320155420132015511b22021b22137d20142016201420021b221554ad7d7c200920127d2209201420157d7c22162009542202ad7c220920022009200a542009200a511b22021b2114427f201620021b210a02400240201520127c2209201320187c2009201554ad7c2215844200520d00200441900e6a41186a220c4200370300200441900e6a41106a22074200370300200441900e6a41086a22064200370300200442003703900e41b6fdc600ad428080808080018422091001220b2900002115200441f80d6a41086a2202200b41086a290000370300200420153703f80d200b103520062002290300370300200420042903f80d3703900e41e489c200ad4280808080d0018422151001220b29000021122002200b41086a290000370300200420123703f80d200b1035200720042903f80d2212370300200441b0056a41086a220e2006290300370300200441b0056a41106a22102012370300200441b0056a41186a220d2002290300370300200420042903900e3703b005200441d8006a200441b0056a412010d701200441d8006a41106a2903002112200429036021132004280258210b200c42003703002007420037030020064200370300200442003703900e20091001220c29000021092002200c41086a290000370300200420093703f80d200c103520062002290300370300200420042903f80d3703900e20151001220c29000021092002200c41086a290000370300200420093703f80d200c1035200720042903f80d2209370300200e200629030037030020102009370300200d2002290300370300200420042903900e3703b005200420124200200b1b3703980e200420134200200b1b3703900e200441b0056aad4280808080800484200441900e6aad428080808080028410020c010b200442f0f2bda1a7ee9cb9f9003703900e200441b0056a200441900e6a10e001200441b0056a2009201510df01200441c8056a2015370300200441c0056a2009370300200441b0056a41086a41063a00002004410c3a00b00541b0b4cc004100200441b0056a10d4010b200a2014844200520d01200441900e6a41186a220c4200370300200441900e6a41106a22074200370300200441900e6a41086a22064200370300200442003703900e41b6fdc600ad428080808080018422091001220b2900002114200441f80d6a41086a2202200b41086a290000370300200420143703f80d200b103520062002290300370300200420042903f80d3703900e41e489c200ad4280808080d0018422141001220b29000021152002200b41086a290000370300200420153703f80d200b1035200720042903f80d2215370300200441b0056a41086a220e2006290300370300200441b0056a41106a22102015370300200441b0056a41186a220d2002290300370300200420042903900e3703b005200441c0006a200441b0056a412010d701200441c0006a41106a2903002115200429034821122004280240210b200c42003703002007420037030020064200370300200442003703900e20091001220c29000021092002200c41086a290000370300200420093703f80d200c103520062002290300370300200420042903f80d3703900e20141001220c29000021092002200c41086a290000370300200420093703f80d200c1035200720042903f80d2209370300200e200629030037030020102009370300200d2002290300370300200420042903900e3703b005200420154200200b1b3703980e200420124200200b1b3703900e200441b0056aad4280808080800484200441900e6aad428080808080028410020c020b200441900e6a41186a220b4200370300200441900e6a41106a22064200370300200441900e6a41086a22024200370300200442003703900e41b6fdc600ad4280808080800184221210012207290000210a200441f80d6a41086a2208200741086a2900003703002004200a3703f80d2007103520022008290300370300200420042903f80d3703900e41e489c200ad4280808080d00184220a1001220729000021132008200741086a290000370300200420133703f80d20071035200620042903f80d2213370300200441b0056a41086a220c2002290300370300200441b0056a41106a220e2013370300200441b0056a41186a22102008290300370300200420042903900e3703b005200441206a200441b0056a412010d701200441206a41106a29030021132004290328211720042802202107200b42003703002006420037030020024200370300200442003703900e20121001220b29000021122008200b41086a290000370300200420123703f80d200b103520022008290300370300200420042903f80d3703900e200a1001220b29000021122008200b41086a290000370300200420123703f80d200b1035200620042903f80d2212370300200c2002290300370300200e201237030020102008290300370300200420042903900e3703b0052004427f2013420020071b2212200920157d2016201454ad7d7c2017420020071b2209201620147d7c22142009542208ad7c22092008200920125420092012511b22081b3703980e2004427f201420081b3703900e200441b0056aad4280808080800484200441900e6aad4280808080800284100241800221080c080b200441b0056a10d004200441b0056a200a201410df010b200420042800af0d3600b70c200420042903a80d3703b00c200420042903b00c3703a00c200420042800b70c3600a70c200420083a00900c200441900c6a41086a20042800a70c360000200420042903a00c3700910c200441800d6a41086a200441800c6a41086a290300370300200420042903800c3703800d41072102410021060240200841ff01714104460d00200441900c6a10d104200441bb056a200441980c6a280200360000200420042903900c3700b30541012106410f21020b200441b0056a20026a220820042903800d370000200841086a200441800d6a41086a290300370000200441b8086a41086a20063a0000200441c1086a20042900b005370000200441c9086a200441b0056a41086a2208290000370000200441d1086a200441b0056a41106a2202290000370000200441b8086a41206a200441c7056a290000370000200441003a00b80841b0b4cc004100200441b8086a10d401200441386a41c4c3c700411010c0012004200428023c41016a410120042802381b22063602b80841c4c3c700ad4280808080800284200441b8086aad4280808080c000841002200420063602dc0d200441003602d80d200441b0056a41186a42003703002002420037030020084200370300200442003703b00541d1c4c700ad4280808080e000841001220629000021092008200641086a290000370300200420093703b005200610354188f2c700ad4280808080e00184100122062900002109200441f80d6a41086a2207200641086a290000370300200420093703f80d20061035200220042903f80d2209370300200441900e6a41086a2008290300370300200441900e6a41106a2009370300200441900e6a41186a2007290300370300200420042903b0053703900e200441203602bc082004200441900e6a3602b808200441d80d6a200441b8086a10cd042000410c6a200441900c6a41086a280200360200200041046a20042903900c370200200041003a00002001450d0820050d010c080b200020042f00b1053b0001200041013a0000200041036a20042d00b3053a000020032802002101410021000c060b200341046a280200450d06200110350c060b41809ccc004119419c9ccc00103f000b103c000b20042f01b20541087420087221080b20044188096a10ba020b200420042903b00c3703a00c200420042800b70c3600a70c200041036a20084110763a0000200020083b0001200041013a000020054521000b20000d002001450d00200341046a280200450d00200110350b200441c00e6a24000bcc0405067f017e017f017e047f230041e0006b22002400200041c4c3c700411010c001200028020421010240200028020022024101470d0041c4c3c700ad428080808080028410070b200041306a41186a22034200370300200041306a41106a22044200370300200041306a41086a220542003703002000420037033041d1c4c700ad4280808080e000842206100122072900002108200041d0006a41086a2209200741086a2900003703002000200837035020071035200520092903003703002000200029035037033041ecedc700ad4280808080e001841001220729000021082009200741086a2900003703002000200837035020071035200420002903502208370300200041106a41086a220a2005290300370300200041106a41106a220b2008370300200041106a41186a220c20092903003703002000200029033037031020002001410020021b360230200041106aad4280808080800484200041306aad4280808080c000841002200041013602082003420037030020044200370300200542003703002000420037033020061001220729000021062009200741086a290000370300200020063703502007103520052009290300370300200020002903503703304188f2c700ad4280808080e001841001220729000021062009200741086a2900003703002000200637035020071035200420002903502206370300200a2005290300370300200b2006370300200c200929030037030020002000290330370310200041203602342000200041106a360230200041086a200041306a10cd04200041e0006a24000b956808047f017e017f027e077f017e057f067e230041c0036b22012400200141a8016a41186a4200370300200141a8016a41106a22024200370300200141a8016a41086a22034200370300200142003703a80141a8e7cb00ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004103520032006290300370300200120012903c0023703a80141b697ca00ad4280808080d001841001220429000021052006200441086a290000370300200120053703c00220041035200220012903c002220537030020014190036a41086a200329030037030020014190036a41106a200537030020014190036a41186a2006290300370300200120012903a80137039003200141203602ac02200120014190036a3602a802200141c0026a20014190036aad220742808080808004842208100510c2010240024020012802c00222030d004102210620014102360284030c010b20012802c40221092001200628020022063602b402200120033602b0020240024020064104490d002001200341046a3602b00220012006417c6a22043602b40220044104490d002003280000210a2001200641786a3602b4022001200341086a3602b0022003280004210b200141a8016a200141b0026a10e80320012802a801220c450d0020012902ac012105410021060240024020012802b402220d0d000c010b2001200d417f6a220e3602b402200120012802b002220f41016a3602b0020240200f2d00004101460d000c010b200e4104490d002001200d417b6a3602b4022001200f41056a3602b002200f2800012104410121060b2001200436028803200120053702fc022001200c3602f8022001200b3602f4022001200a3602f0020c010b200141003602d802200142013703d002200141093602b4032001200141a8026a3602b0032001200141d0026a3602bc02200141bc016a4101360200200142013702ac01200141c888c2003602a8012001200141b0036a3602b801200141bc026a41e88ac500200141a8016a10431a20013502d80242208620013502d002841006024020012802d402450d0020012802d00210350b410221060b20012006360284032009450d00200310350b200141a8016a41106a2203200141f0026a41106a2209280200360200200141a8016a41086a220a200141f0026a41086a220b290300370300200120012903f0023703a8010240024002400240024002400240024020064102460d00200141d0026a41106a20032802002203360200200141d0026a41086a200a2903002210370300200120012903a80122053703d00220092003360200200b201037030020014188036a2004360200200120053703f002200120063602840302402005a722032000470d000240024020064101460d0020012802f4022106200141a8016a200141f0026a41086a10c605200141a0036a200636020020014190036a410c6a200141a8016a41086a22062802003602002001410036029003200120012903a80137029403200141a8016a20014190036a108805200141cb026a2006280200360000200120012903a8013700c302200141a8016a410c6a200141c7026a290000370000200141c6a4b9da043600a901200141023a00a801200120012900c0023700ad01200141a8016a10820420014190036a41086a2802002206450d01200641286c450d0120012802940310350c010b20012802f4022106200141a8016a200141f0026a41086a10c605200141a4036a200636020020014190036a41086a20012903a801370300200141a0036a200141a8016a41086a220628020036020020012004360294032001410136029003200141a8016a20014190036a108805200141cb026a2006280200360000200120012903a8013700c302200141a8016a410c6a200141c7026a290000370000200141c6a4b9da043600a901200141023a00a801200120012900c0023700ad01200141a8016a10820420014190036a410c6a2802002206450d00200641286c450d0020012802980310350b20012802f00221030b024020012802f40220036a2000470d002001200141f8026a220d3602ac01200141003602a80120014180036a28020041286c4105722206417f4c0d02200610332203450d03200341013a000020012006360294032001200336029003200141013602980320012802f8022106200128028003220320014190036a10770240024020030d002001280298032103200128029003210b0c010b2006200341286c6a210c20012802940321092001280298032103034002400240200920036b4120490d00200341206a2104200128029003210b2009210a0c010b200341206a22042003490d072009410174220a2004200a20044b1b220a4100480d070240024020090d000240200a0d004101210b0c020b200a1033220b0d010c0d0b200128029003210b2009200a460d00200b2009200a1037220b450d0c0b2001200a360294032001200b360290030b200b20036a22032006290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a2900003700002001200436029803200641206a290300210502400240200a20046b4108490d00200441086a2103200a21090c010b200441086a22032004490d07200a41017422092003200920034b1b22094100480d0702400240200a0d00024020090d004101210b0c020b20091033220b450d0d0c010b200a2009460d00200b200a20091037220b450d0c0b20012009360294032001200b360290030b200b20046a20053700002001200336029803200c200641286a2206470d000b0b2001280294032106419793ca00ad4280808080c002842003ad422086200bad84100202402006450d00200b10350b024020012802a801450d00200141b0016a2802002206450d00200641286c450d0020012802ac0110350b200141a8016a41086a2206200d290000370300200141a8016a41106a2204200d41086a280000360200200141003602ac012001410b3a00a80141b0b4cc004100200141a8016a10d401200141a8016a41186a220a42003703002004420037030020064200370300200142003703a80141a8e7cb00ad4280808080f00184100122092900002105200141c0026a41086a2203200941086a290000370300200120053703c0022009103520062003290300370300200120012903c0023703a80141b697ca00ad4280808080d001841001220929000021052003200941086a290000370300200120053703c00220091035200220012903c002370000200241086a200329030037000020014190036a41086a200629030037030020014190036a41106a200429030037030020014190036a41186a200a290300370300200120012903a80137039003200810070c010b200141fc026a2802002206450d00200641286c450d0020012802f80210350b200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141a8e7cb00ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004103520032006290300370300200120012903c0023703a80141c397ca00ad4280808080d000841001220429000021052006200441086a290000370300200120053703c00220041035200220012903c002370000200241086a200629030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200141203602c402200120014190036a3602c002200141d0026a2008100510c20120012802d0022206450d0520012802d4022104024002400240200141d0026a41086a2802002209450d0020062d0000220a41034b0d0041002103024002400240200a0e0405000102050b2009417f6a4108490d0220062900012105410121030c040b410221030c020b2009417f6a4108490d0020062900012105410321030c020b200141003602f802200142013703f002200141093602b4032001200141c0026a3602b0032001200141f0026a3602b002200141bc016a4101360200200142013702ac01200141c888c2003602a8012001200141b0036a3602b801200141b0026a41e88ac500200141a8016a10431a20013502f80242208620013502f002841006024020012802f402450d0020012802f00210350b410421030b0b02402004450d00200610350b2003417f6a220641024b0d0520060e03040503040b1044000b1045000b103e000b2005422088a7210602402005a722032000470d0020014104360290032001200636029403200141a8016a20014190036a108805200141cb026a200141b0016a280200360000200120012903a8013700c302200141b4016a200141c7026a290000370000200141c6a4b9da043600a901200141023a00a801200120012900c0023700ad01200141a8016a1082040b200620036a2000470d01200141003602f002200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141a8e7cb00ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004103520032006290300370300200120012903c0023703a80141c397ca00ad4280808080d000841001220429000021052006200441086a290000370300200120053703c00220041035200220012903c002370000200241086a200629030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200141a8016a200141f0026a10db06200820013502b00142208620012802a8012206ad841002024020012802ac01450d00200610350b200141023602ac012001410b3a00a80141b0b4cc004100200141a8016a10d4010c010b2005422088a7210602402005a722032000470d0020014103360290032001200636029403200141a8016a20014190036a108805200141cb026a200141b0016a280200360000200120012903a8013700c302200141b4016a200141c7026a290000370000200141c6a4b9da043600a901200141023a00a801200120012900c0023700ad01200141a8016a1082040b200620036a2000470d00200141023602f002200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141a8e7cb00ad4280808080f00184100122042900002105200141c0026a41086a2206200441086a290000370300200120053703c0022004103520032006290300370300200120012903c0023703a80141c397ca00ad4280808080d000841001220429000021052006200441086a290000370300200120053703c00220041035200220012903c002370000200241086a200629030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200141a8016a200141f0026a10db06200820013502b00142208620012802a8012206ad841002024020012802ac01450d00200610350b200141013602ac012001410b3a00a80141b0b4cc004100200141a8016a10d4010b200141a8016a41186a22044200370300200141a8016a41106a220d4200370300200141a8016a41086a22034200370300200142003703a80141bee4cb00ad4280808080f001842205100122092900002108200141f0026a41086a2206200941086a290000370300200120083703f0022009103520032006290300370300200120012903f0023703a801418cc0c700ad4280808080e000841001220929000021082006200941086a290000370300200120083703f00220091035200d20012903f002220837030020014190036a41086a220a200329030037030020014190036a41106a220b200837030020014190036a41186a220c2006290300370300200120012903a80137039003200141a0016a20014190036a412010c00120012802a401210f024020012802a00122024101470d002007428080808080048410070b20044200370300200d420037030020034200370300200142003703a80120051001220929000021052006200941086a290000370300200120053703f0022009103520032006290300370300200120012903f0023703a80141cde4cb00ad4280808080b001841001220929000021052006200941086a290000370300200120053703f00220091035200d20012903f002370000200d41086a2006290300370000200a2003290300370300200b200d290300370300200c2004290300370300200120012903a801370390030240024020014190036a10bd02220641ff01714102460d0020064101710d010b41041033220a450d01200a4100360200200141a8016a41186a22044200370300200141a8016a41106a22094200370300200141a8016a41086a22034200370300200142003703a80141bee4cb00ad4280808080f0018422051001220b2900002108200141f0026a41086a2206200b41086a290000370300200120083703f002200b103520032006290300370300200120012903f0023703a80141b9e0c600ad4280808080b001841001220b29000021082006200b41086a290000370300200120083703f002200b1035200d20012903f002370000200d41086a220b200629030037000020014190036a41086a220c200329030037030020014190036a41106a2200200929030037030020014190036a41186a220e2004290300370300200120012903a80137039003200141203602ac01200120014190036a3602a801200a4101200141a8016a109503200a103541041033220a450d01200a4100360200200442003703002009420037030020034200370300200142003703a80120051001221129000021082006201141086a290000370300200120083703f0022011103520032006290300370300200120012903f0023703a8014192c0c700ad4280808080c001841001221129000021082006201141086a290000370300200120083703f00220111035200d20012903f002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903a80137039003200141203602ac01200120014190036a3602a801200a4101200141a8016a109503200a1035200442003703002009420037030020034200370300200142003703a80120051001220a29000021082006200a41086a290000370300200120083703f002200a103520032006290300370300200120012903f0023703a801419ec0c700ad4280808080e000841001220a29000021082006200a41086a290000370300200120083703f002200a1035200d20012903f002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903a80137039003200141003602a801200742808080808004842208200141a8016aad22104280808080c000841002200442003703002009420037030020034200370300200142003703a80120051001220a29000021052006200a41086a290000370300200120053703f002200a103520032006290300370300200120012903f0023703a80141cde4cb00ad4280808080b001841001220a29000021052006200a41086a290000370300200120053703f002200a1035200d20012903f002370000200b2006290300370000200c200329030037030020002009290300370300200e2004290300370300200120012903a80137039003200141013a00a801200820104280808080108410020b200141a8016a41186a4200370300200141a8016a41106a22124200370300200141a8016a41086a22064200370300200142003703a80141bee4cb00ad4280808080f001841001220329000021052006200341086a290000370300200120053703a8012003103541b9e0c600ad4280808080b00184100122032900002105200141f0026a41086a2204200341086a290000370300200120053703f00220031035201220012903f002220537030020014190036a41086a200629030037030020014190036a41106a200537030020014190036a41186a2004290300370300200120012903a80137039003200141a8016a20014190036a10c5020240024020012802a801220e0d0041002113200141003602c802200142043703c0024104210e410021110c010b200120012902ac0122053702c4022001200e3602c0022005422088a721112005a721130b200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141bee4cb00ad4280808080f00184100122042900002105200141f0026a41086a2206200441086a290000370300200120053703f0022004103520032006290300370300200120012903f0023703a8014192c0c700ad4280808080c001841001220429000021052006200441086a290000370300200120053703f00220041035200d20012903f002370000200d41086a200629030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200141a8016a20014190036a10c5020240024020012802a801220a0d0041002114200141003602d802200142043703d0024104210a4100210c0c010b200120012902ac0122053702d4022001200a3602d0022005422088a7210c2005a721140b0240024002400240024020020d002011450d012011410274200e6a417c6a280200210f0b201141002011419c7f6a22062006201141016a4b1b2215490d01200141003602c8022015450d03200e20154102746a2100200e210203402002280200210b02400240024002400240200c41014b0d0041002106200c0e020201020b41002106200c2103034020062003410176220420066a2209200b200a20094102746a280200491b2106200320046b220341014b0d000b0b200b200a200641027422036a2802002204460d022006200b20044b6a21060c010b410021060b200120063602a80141dcc0c700412e200141a8016a418cc1c700419cc1c7001046000b200c20064d0d03200a20036a2203200341046a2006417f73200c6a410274109e081a2001200c417f6a220c3602d802200241046a22022000470d000c040b0b41a4c0c700412641ccc0c7001064000b20152011104f000b2006200c104e000b410021064100210b0240201120156b2203450d0002402015450d00200e200e20154102746a2003410274109e081a0b200120033602c8022003210b0b024002400240200c41014b0d00200c0e020201020b41002106200c2103034020062003410176220420066a2209200f200a20094102746a280200491b2106200320046b220341014b0d000b0b0240200f200a20064102746a2802002203460d002006200f20034b6a21060b200c20064f0d002006200c104d000b0240200c2014470d00200141d0026a2014410110860120012802d002210a0b200a20064102746a220341046a2003200c20066b410274109e081a2003200f3602002001200c41016a22033602d8020240200b2013470d00200141c0026a2013410110860120012802c002210e20012802c802210b0b200e200b4102746a200f3602002001200b41016a220b3602c80202400240024002400240024002402003450d00200341017621062003410171450d01200320064d0d03200a20064102746a28020021000c020b41acc1c70041c30041c086cc00103f000b200320064d0d0220032006417f6a22044d0d03200a20044102746a280200200a20064102746a2802006a41017621000b20012802c4022102200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22044200370300200142003703a80141bee4cb00ad4280808080f0018422051001220c2900002108200141f0026a41086a2206200c41086a290000370300200120083703f002200c103520042006290300370300200120012903f0023703a80141b9e0c600ad4280808080b001841001220c29000021082006200c41086a290000370300200120083703f002200c1035200d20012903f002370000200d41086a220f200629030037000020014190036a41086a2211200429030037030020014190036a41106a2215200a29030037030020014190036a41186a22132009290300370300200120012903a80137039003200141203602ac01200120014190036a3602a801200e200b200141a8016a1095030240200241ffffffff0371450d00200e10350b20012802d402210e20012802d002210220094200370300200a420037030020044200370300200142003703a80120051001220c29000021052006200c41086a290000370300200120053703f002200c103520042006290300370300200120012903f0023703a8014192c0c700ad4280808080c001841001220c29000021052006200c41086a290000370300200120053703f002200c1035200d20012903f002370000200f2006290300370000201120042903003703002015200a29030037030020132009290300370300200120012903a80137039003200141203602ac01200120014190036a3602a80120022003200141a8016a1095030240200e41ffffffff0371450d00200210350b200141a8016a41186a22094200370300200141a8016a41106a22044200370300200141a8016a41086a22034200370300200142003703a80141bee4cb00ad4280808080f001841001220a2900002105200141f0026a41086a2206200a41086a290000370300200120053703f002200a103520032006290300370300200120012903f0023703a801419ec0c700ad4280808080e000841001220a29000021052006200a41086a290000370300200120053703f002200a1035200d20012903f002370000200d41086a200629030037000020014190036a41086a220a200329030037030020014190036a41106a220c200429030037030020014190036a41186a22022009290300370300200120012903a80137039003200120003602a80120074280808080800484200141a8016aad22164280808080c0008410020240200b41e500470d00200942003703002004420037030020034200370300200142003703a80141d1c4c700ad4280808080e000841001220b29000021052003200b41086a290000370300200120053703a801200b103541e7c4c700ad4280808080e000841001220b29000021052006200b41086a290000370300200120053703f002200b1035201220012903f002370000201241086a2006290300370000200a2003290300370300200c200429030037030020022009290300370300200120012903a8013703900320014198016a20014190036a412010c0010b200942003703002004420037030020034200370300200142003703a80141f7edcb00ad4280808080f0008422081001220929000021052006200941086a290000370300200120053703f0022009103520032006290300370300200120012903f0023703a80141eeedcb00ad428080808090018422101001220929000021052006200941086a290000370300200120053703f00220091035200420012903f0022205370300200a2003290300370300200c200537030020022006290300370300200120012903a80137039003200141a8016a20014190036a10ac01024020012903a801427f7c4202540d0020042903002117200141a8016a41186a220a4200370300200141a8016a41106a22094200370300200141a8016a41086a22064200370300200142003703a80141d1efcb00ad42808080809001841001220329000021052006200341086a290000370300200120053703a8012003103541ebc3c400ad428080808030841001220b2900002105200141f0026a41086a2203200b41086a290000370300200120053703f002200b1035200920012903f002220537030020014190036a41086a220c200629030037030020014190036a41106a2202200537030020014190036a41186a22002003290300370300200120012903a8013703900320014188016a20014190036a10e102200141f8006a20012903900142002001280288011b221842e807802219420042e8074200108408200a42003703002009420037030020064200370300200142003703a80120081001220b29000021052003200b41086a290000370300200120053703f002200b103520062003290300370300200120012903f0023703a80120101001220b29000021052003200b41086a290000370300200120053703f002200b1035200420012903f002370000200441086a2003290300370000200c2006290300370300200220092903003703002000200a290300370300200120012903a8013703900320012903782105200141f8006a41086a2903002108410410332206450d05200620173e000020064104410810372206450d05200641013a000420064108411010372206450d0520062005201820194298787e7c42ff07837c2210427f20082010200554ad7c501b370005200742808080808004842006ad4280808080d001841002200610350b200141a8016a41186a220b4200370300200141a8016a41106a22094200370300200141a8016a41086a22034200370300200142003703a80141e3efcb00ad4280808080a00284100122042900002105200141f0026a41086a2206200441086a290000370300200120053703f0022004103520032006290300370300200120012903f0023703a80141f5efcb00ad42808080809002841001220429000021052006200441086a290000370300200120053703f00220041035200920012903f002220537030020014190036a41086a200329030037030020014190036a41106a200537030020014190036a41186a2006290300370300200120012903a80137039003200141e0006a20014190036a10bc02200141e0006a41106a29030021172001290368211920012802602104200141f0026a41186a4200370300200141f0026a41106a220c420037030020064200370300200142003703f00241d1c4c700ad4280808080e000841001220a29000021052006200a41086a290000370300200120053703f002200a10354184eec700ad4280808080b002841001220a2900002105200141c0026a41086a2202200a41086a290000370300200120053703c002200a1035200c20012903c00222053703002003200629030037030020092005370300200b2002290300370300200120012903f0023703a801200141d0006a200141a8016a10e102200141106a2001290358420020012802501b2205428090cad2c60e2005428090cad2c60e5622061b428090cad2c60e200520061b7d420042a0c21e4200108408200141c0006a20012903102208200141106a41086a29030022102008201010dc06200141c0006a41086a290300211a2001290340211b200141306a428080aace938c0942002008201010dc06200141306a41086a290300210820012903302118200141206a428090bcfd024200201b201a10dc062017420020041b21102019420020041b2119200141206a41086a29030021172001290320211a02400240200542ff8fcad2c60e560d0042ffffffffffffffffff00428080808080808080807f201042ffffffffffffffffff00428080808080808080807f200820177d2018201a54ad7d22054200531b200541012008427f552008501b220641012017427f552017501b47200641012005427f552005501b477122061b22087d20192005423f872018201a7d20061b221754ad7d22054200531b200541012010427f552010501b220641012008427f552008501b47200641012005427f552005501b477122061b2208427f2005423f87201920177d20061b2205428080f0c4c5a9d28f72562008427f552008427f511b22061b21082005428080f0c4c5a9d28f7220061b21050c010b42ffffffffffffffffff00428080808080808080807f201042ffffffffffffffffff00428080808080808080807f200820177c2018201a7c221a201854ad7c22054200531b200541012008427f552008501b220641012017427f552017501b46200641012005427f552005501b477122061b22087c20192005423f87201a20061b7c2217201954ad7c22054200531b200541012010427f552010501b220641012008427f552008501b46200641012005427f552005501b477122061b21082005423f87201720061b21050b200141a8016a41186a220a4200370300200141a8016a41106a22044200370300200141a8016a41086a22034200370300200142003703a80141e3efcb00ad4280808080a002841001220b2900002110200141f0026a41086a2206200b41086a290000370300200120103703f002200b103520032006290300370300200120012903f0023703a80141f5efcb00ad42808080809002841001220b29000021102006200b41086a290000370300200120103703f002200b1035200920012903f002370000200941086a200629030037000020014190036a41086a2209200329030037030020014190036a41106a220b200429030037030020014190036a41186a220c200a290300370300200120012903a80137039003200120083703b001200120053703a801200742808080808004842205201642808080808002841002200a42003703002004420037030020034200370300200142003703a8014193d1cb00ad4280808080a0018422081001220229000021102006200241086a290000370300200120103703f0022002103520032006290300370300200120012903f0023703a80141d8c7ca00ad4280808080e000841001220229000021102006200241086a290000370300200120103703f00220021035200420012903f002221037030020092003290300370300200b2010370300200c2006290300370300200120012903a8013703900320051007200a42003703002004420037030020034200370300200142003703a80120081001220229000021082006200241086a290000370300200120083703f0022002103520032006290300370300200120012903f0023703a801419dd1cb00ad4280808080c001841001220229000021082006200241086a290000370300200120083703f00220021035200420012903f002220837030020092003290300370300200b2008370300200c2006290300370300200120012903a8013703900320051007200a42003703002004420037030020034200370300200142003703a80141d1efcb00ad42808080809001841001220a29000021082003200a41086a290000370300200120083703a801200a103541daefcb00ad42808080809001841001220a29000021082006200a41086a290000370300200120083703f002200a1035200420012903f002220837030020092003290300370300200b2008370300200c2006290300370300200120012903a8013703900320014190036a10bd02220641ff01714102460d03200510072006410171450d03200141a8016a41186a4200370300200141a8016a41106a22064200370300200141a8016a41086a22034200370300200142003703a80141a9d1cb00ad4280808080c000841001220429000021052003200441086a290000370300200120053703a8012004103541cde4cb00ad4280808080b00184100122042900002105200141c0026a41086a2209200441086a290000370300200120053703c00220041035200620012903c002220537030020014190036a41086a200329030037030020014190036a41106a200537030020014190036a41186a2009290300370300200120012903a80137039003200141a8016a20014190036a10b702024020012d00a80122034102460d00200742808080808004841007200141d0026a41086a200141b1016a290000370300200141d0026a41106a200141b9016a290000370300200141d0026a41186a200141c1016a290000370300200120012900a9013703d0020240200341037122034103460d0020030e03010001010b200141f0026a41186a200141d0026a41186a290300370300200141f0026a41106a200141d0026a41106a290300370300200141f0026a41086a200141d0026a41086a290300370300200120012903d0023703f002200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141a9d1cb00ad4280808080c000841001220429000021052003200441086a290000370300200120053703a8012004103541f0d1cb00ad4280808080c00184100122042900002105200141c0026a41086a220b200441086a290000370300200120053703c00220041035200620012903c002370000200641086a200b29030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200141086a20014190036a412010c00141002109200141a8016a200128020c410020012802081b220a10fe0320014190036a20012802a801220b20012802b00110c3020240024020012802900322040d00200141003602b803200142013703b00341012104410021030c010b200120012902940322053702b403200120043602b0032005422088a721032005a721090b024020012802ac01450d00200b10350b024002402003418002490d00412010332203450d07200320012903f002370000200341186a200141f0026a41186a290300370000200341106a200141f0026a41106a290300370000200341086a200141f0026a41086a290300370000200141a8016a200a41016a220910fe0320012802a8012104200120012802b0013602940320012004360290032003410120014190036a109802024020012802ac01450d00200410350b20031035200141a8016a41186a220a4200370300200141a8016a41106a220b4200370300200141a8016a41086a22034200370300200142003703a80141a9d1cb00ad4280808080c000841001220429000021052003200441086a290000370300200120053703a8012004103541f0d1cb00ad4280808080c00184100122042900002105200141c0026a41086a220c200441086a290000370300200120053703c00220041035200620012903c002370000200641086a200c29030037000020014190036a41086a200329030037030020014190036a41106a200b29030037030020014190036a41186a200a290300370300200120012903a80137039003200120093602a8012007428080808080048420164280808080c000841002200141b0036a21030c010b200141a8016a41186a220b200141f0026a41186a290300370300200141a8016a41106a220c200141f0026a41106a290300370300200141a8016a41086a2202200141f0026a41086a290300370300200120012903f0023703a801024020032009470d00200141b0036a20094101108a0120012802b003210420012802b80321030b200420034105746a220920012903a801370000200941186a200b290300370000200941106a200c290300370000200941086a20022903003700002001200341016a22093602b803200141a8016a200a10fe0320012802a8012103200120012802b0013602940320012003360290032004200920014190036a109802024020012802ac01450d00200310350b200141b0036a21030b200341046a28020041ffffff3f71450d00200328020010350b200141a8016a41186a22094200370300200141a8016a41106a220a4200370300200141a8016a41086a22034200370300200142003703a80141a9d1cb00ad4280808080c000841001220429000021052003200441086a290000370300200120053703a801200410354199c2c300ad4280808080800184100122042900002105200141c0026a41086a220b200441086a290000370300200120053703c00220041035200620012903c002370000200641086a200b29030037000020014190036a41086a200329030037030020014190036a41106a200a29030037030020014190036a41186a2009290300370300200120012903a80137039003200742808080808004841007200141c0036a24000f0b2006200341f0c1c7001042000b200620034180c2c7001042000b200420034190c2c7001042000b41c0c3c400412b41c086cc00103f000b103c000ba41d08047f017e017f017e047f017e047f017e230041e0016b2201240020014190016a41186a2202420037030020014190016a41106a2203420037030020014190016a41086a22044200370300200142003703900141d1c4c700ad4280808080e000842205100122062900002107200141b8016a41086a2208200641086a290000370300200120073703b8012006103520042008290300370300200120012903b801370390014188f2c700ad4280808080e001841001220629000021072008200641086a290000370300200120073703b80120061035200320012903b8012207370300200141f0006a41086a22062004290300370300200141f0006a41106a22092007370300200141f0006a41186a220a20082903003703002001200129039001370370200141f0006aad428080808080048422071007200242003703002003420037030020044200370300200142003703900120051001220b290000210c2008200b41086a2900003703002001200c3703b801200b103520042008290300370300200120012903b8013703900141ecedc700ad4280808080e001841001220b290000210c2008200b41086a2900003703002001200c3703b801200b1035200320012903b801220c370300200620042903003703002009200c370300200a2008290300370300200120012903900137037020071007200242003703002003420037030020044200370300200142003703900120051001220b290000210c2008200b41086a2900003703002001200c3703b801200b103520042008290300370300200120012903b801370390014184eec700ad4280808080b002841001220b290000210c2008200b41086a2900003703002001200c3703b801200b1035200320012903b801220c370300200620042903003703002009200c370300200a2008290300370300200120012903900137037020071007200242003703002003420037030020044200370300200142003703900120051001220b290000210c2008200b41086a2900003703002001200c3703b801200b103520042008290300370300200120012903b8013703900141b8eec700ad42808080808002841001220b290000210c2008200b41086a2900003703002001200c3703b801200b1035200320012903b801220c370300200620042903003703002009200c370300200a2008290300370300200120012903900137037020071007200242003703002003420037030020044200370300200142003703900120051001220b290000210c2008200b41086a2900003703002001200c3703b801200b103520042008290300370300200120012903b8013703900141e7c4c700ad4280808080e000841001220b290000210c2008200b41086a2900003703002001200c3703b801200b1035200320012903b801220c370300200620042903003703002009200c370300200a20082903003703002001200129039001370370200141086a200141f0006a412010c001200128020c210d02402001280208220e4101470d00200710070b200242003703002003420037030020044200370300200142003703900120051001220b29000021052008200b41086a290000370300200120053703b801200b103520042008290300370300200120012903b8013703900141edc4c700ad4280808080a001841001220b29000021052008200b41086a290000370300200120053703b801200b1035200320012903b801370000200341086a20082903003700002006200429030037030020092003290300370300200a20022903003703002001200129039001370370200141b8016a200141f0006a412010d501024002400240024020012d00b80122080d00200141a8016a200141d1016a290000370300200141a0016a200141c9016a29000037030020014198016a200141c1016a290000370300200120012900b901370390010c010b2007100720014190016a41186a2204200141d1016a29000037030020014190016a41106a2202200141c9016a29000037030020014190016a41086a2206200141c1016a290000370300200120012900b9013703900120084101460d010b200141286a4200370300200141206a4200370300200141186a4200370300200142003703100c010b200141106a41186a2004290300370300200141106a41106a2002290300370300200141106a41086a200629030037030020012001290390013703100b20014190016a41186a2206420037030020014190016a41106a2209420037030020014190016a41086a22044200370300200142003703900141d1c4c700ad4280808080e00084100122022900002105200141b8016a41086a2208200241086a290000370300200120053703b8012002103520042008290300370300200120012903b801370390014185c5c700ad4280808080e000841001220229000021052008200241086a290000370300200120053703b80120021035200320012903b801370000200341086a2008290300370000200141f0006a41086a2004290300370300200141f0006a41106a2009290300370300200141f0006a41186a20062903003703002001200129039001370370200141b8016a200141f0006a10ce020240024020012802b801220f0d004100210a20014100360238200142043703304104210f410021100c010b200710072001200f360230200120012902bc0122053702342005422088a7210a2005a721100b200d4100200e1b210620014190016a41186a2202420037030020014190016a41106a2209420037030020014190016a41086a22084200370300200142003703900141d1c4c700ad4280808080e000841001220b2900002105200141b8016a41086a2204200b41086a290000370300200120053703b801200b103520082004290300370300200120012903b8013703900141f7c4c700ad4280808080e001841001220b29000021052004200b41086a290000370300200120053703b801200b1035200320012903b801370000200341086a2004290300370000200141f0006a41086a2008290300370300200141f0006a41106a2009290300370300200141f0006a41186a20022903003703002001200129039001370370200141b8016a200141f0006a412010d501024002400240024020012d00b80122030d002002200141d1016a2900003703002009200141c9016a2900003703002008200141c1016a290000370300200120012900b901370390010c010b200710072002200141d1016a2900003703002009200141c9016a2900003703002008200141c1016a290000370300200120012900b9013703900120034101460d010b200141d8006a4200370300200141d0006a4200370300200141c8006a4200370300200142003703400c010b200141c0006a41186a20014190016a41186a290300370300200141c0006a41106a20014190016a41106a290300370300200141c0006a41086a20014190016a41086a29030037030020012001290390013703400b0240200641fb01490d00200641857e6a2208450d00200141b8016a200810b80320013502c00142208620012802b8012208ad84100720012802bc01450d00200810350b41012109024010232207422088a72202450d002007a721090b41002108200141003a00d801200921030240024002400240034020022008460d01200141b8016a20086a20032d00003a00002001200841016a22043a00d801200341016a21032004210820044120470d000b200141f0006a41186a200141b8016a41186a290300370300200141f0006a41106a200141b8016a41106a290300370300200141f0006a41086a200141b8016a41086a290300370300200120012903b80137037002402002450d00200910350b412010332208450d0220082001290310370000200841186a2204200141106a41186a290300370000200841106a2202200141106a41106a290300370000200841086a2209200141106a41086a290300370000412010332203450d0320032008290000370000200341186a2004290000370000200341106a2002290000370000200341086a200929000037000020081035200141e0006a2003ad4280808080800484102410c20120031035024020012802602204450d00200141e8006a28020021022001280264210b41002108200141003a00d801034020022008460d03200141b8016a20086a200420086a2d00003a00002001200841016a22033a00d8012003210820034120470d000b20014190016a41186a200141b8016a41186a2203290300220737030020014190016a41106a200141b8016a41106a2202290300220537030020014190016a41086a200141b8016a41086a2209290300220c370300200120012903b8012211370390012009200c3703002002200537030020032007370300200141b4016a41026a220d200141ed006a41026a2d00003a0000200120113703b801200120012f006d3b01b4010240200a2010470d00200141306a20104101108d012001280230210f2001280238210a0b200f200a41246c6a220841003a0000200820012903b80137000120032903002107200229030021052009290300210c200820012f01b4013b0021200841236a200d2d00003a0000200841096a200c370000200841116a2005370000200841196a20073700002001200a41016a360238200b450d00200410350b200020012903103700102000200636020020002001290370370030200041286a200141106a41186a290300370000200041206a200141106a41106a290300370000200041186a200141106a41086a290300370000200041386a200141f0006a41086a290300370000200041c0006a200141f0006a41106a290300370000200041c8006a200141f0006a41186a290300370000200041e8006a200141c0006a41186a290300370000200041e0006a200141c0006a41106a290300370000200041d8006a200141c0006a41086a290300370000200020012903403700502000410c6a200141306a41086a28020036020020002001290330370204200141e0016a24000f0b0240200841ff0171450d00200141003a00d8010b41b983c800412c200141b8016a41bccfc70041e883c8001046000b0240200841ff0171450d00200141003a00d8010b41b983c800412c200141b8016a41bccfc70041f883c8001046000b1045000b103c000b160020002001280208360204200020012802003602000bff1001067f230041106b22022400024002400240024002400240024002400240024020012d00000e06010402030500010b2002410036020820024201370300410110332203450d082002410136020420022003360200200341003a000020024101360208200141046a28020021042001410c6a2802002201200210770240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d08200541017422072006200720064b1b22074100480d080240024020050d00024020070d00410121060c020b2007103322060d010c0b0b2002280200210620052007460d0020062005200710372206450d0a0b20022007360204200220063602000b200620036a20042001109d081a2002200320016a3602080c050b2002410036020820024201370300410110332203450d072002410136020420022003360200200341023a000020024101360208412010332203450d0520032001290001370000200341186a200141196a290000370000200341106a200141116a290000370000200341086a200141096a2900003700000240024020022802042206417f6a4120490d00200228020021010c010b200641017422014121200141214b1b22054100480d0720022802002101024020062005460d0020012006200510372201450d090b20022005360204200220013602000b20012003290000370001200141196a200341186a290000370000200141116a200341106a290000370000200141096a200341086a29000037000020024121360208200310350c040b2002410036020820024201370300410110332203450d062002410136020420022003360200200341043a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0620022802002103024020062005460d0020032006200510372203450d080b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210770240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d06200541017422072006200720064b1b22074100480d060240024020050d00024020070d00410121060c020b200710332206450d090c010b2002280200210620052007460d0020062005200710372206450d080b20022007360204200220063602000b200620036a20042001109d081a2002200320016a3602080c030b2002410036020820024201370300410110332203450d052002410136020420022003360200200341053a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0520022802002103024020062005460d0020032006200510372203450d070b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210770240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d05200541017422072006200720064b1b22074100480d050240024020050d00024020070d00410121060c020b200710332206450d080c010b2002280200210620052007460d0020062005200710372206450d070b20022007360204200220063602000b200620036a20042001109d081a2002200320016a3602080c020b2002410036020820024201370300410110332203450d042002410136020420022003360200200341063a0000200241013602080240024020022802042206417f6a4104490d00200228020021030c010b200641017422034105200341054b1b22054100480d0420022802002103024020062005460d0020032006200510372203450d060b20022005360204200220033602000b200320012800013600012002410536020820012802082104200141106a2802002201200210770240024020022802042205200228020822036b2001490d00200228020021060c010b200320016a22062003490d04200541017422072006200720064b1b22074100480d040240024020050d00024020070d00410121060c020b200710332206450d070c010b2002280200210620052007460d0020062005200710372206450d060b20022007360204200220063602000b200620036a20042001109d081a2002200320016a3602080c010b2002410036020820024201370300410110332203450d032002410136020420022003360200200341073a00002002410136020820022802002103024020022802044101470d0020034101410210372203450d0420024102360204200220033602000b200341003a0001200241023602082002280200210320022802042106024020012802044101460d00024020064102470d0020034102410410372203450d0520024104360204200220033602000b200341003a0002200241033602080c010b024020064102470d0020034102410410372203450d0420024104360204200220033602000b200341013a000220024103360208200141086a28020021050240024020022802042206417d6a4104490d00200228020021030c010b200641017422034107200341074b1b22044100480d0320022802002103024020062004460d0020032006200410372203450d050b20022004360204200220033602000b20032005360003200241073602082001410c6a2802002106024002402002280204220341796a4104490d00200228020021010c010b20034101742201410b2001410b4b1b22054100480d0320022802002101024020032005460d0020012003200510372201450d050b20022005360204200220013602000b200120063600072002410b3602080b200020022201290200370200200041086a200141086a280200360200200241106a24000f0b1045000b103e000b103c000b8f0201027f20014180feff07714108762102024002402001410171450d00411f210341b0a2cc00210102400240200241ff01710e03000103000b41c100210341efa1cc0021010c020b41c100210341aea1cc0021010c010b411f2103418fa1cc002101024002400240024002400240024002400240200241ff01710e0a00060102030405090708000b4120210341efa0cc0021010c080b41272103418fa0cc0021010c070b4117210341f89fcc0021010c060b41d99fcc0021010c050b4126210341b39fcc0021010c040b412b210341889fcc0021010c030b4139210341b6a0cc0021010c020b413b210341cd9ecc0021010c010b41d100210341fc9dcc0021010b20002003360204200020013602000bc00201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210420034120710d012004ad41012001105221000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000b20024180016a240020000f0b200441800141c88bc0001059000b200441800141c88bc0001059000bb00301027f23004180026b22022400024002402001450d00200220003602000c010b200241b0b4cc003602000b20022001360204200241f8006a200210c4030240200228027c450d00200241086a200241f8006a41f000109d081a200241086a10b7030240200241086a410c6a2802002200450d00200228020c2101200041246c210003400240024020012d0000220341044b0d0002400240024020030e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b0240200241106a2802002201450d00200141246c450d00200228020c10350b20024180026a240042010f0b200241f4016a41043602002002411c6a41023602002002420237020c200241f0b2c300360208200241043602ec01200241b8b3c3003602e801200241003602fc01200241b0b4cc003602f8012002200241e8016a3602182002200241f8016a3602f001200241086a4180b3c300104c000ba00a03077f037e057f230041d0026b2202240041002103200241003a00c8022001280204417f6a210402400240024002400240024003402004417f460d01200241a8026a20036a200128020022052d00003a0000200120043602042001200541016a3602002002200341016a22053a00c8022004417f6a21042005210320054120470d000b200241e8006a41086a200241a8026a41086a290300370300200241e8006a41106a200241a8026a41106a290300370300200241e8006a41186a200241a8026a41186a290300370300200220022903a8023703682002200110c40120022802000d022002280204210641002104200241003a00c80220012802042107417f2103034020072004460d02200241a8026a20046a200128020022082d00003a00002001200720036a3602042001200841016a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241a8016a41086a200241a8026a41086a2903002209370300200241a8016a41106a200241a8026a41106a290300220a370300200241a8016a41186a200241a8026a41186a290300220b37030020024188016a41086a200937030020024188016a41106a200a37030020024188016a41186a200b370300200220022903a80222093703a801200220093703880141002104200241003a00c802200720056b210c200720036a21030340200c2004460d04200241a8026a20046a200820046a220541016a2d00003a0000200120033602042001200541026a3602002002200441016a22053a00c8022003417f6a21032005210420054120470d000b200241e8016a41086a200241a8026a41086a2903002209370300200241e8016a41106a200241a8026a41106a290300220a370300200241e8016a41186a200241a8026a41186a290300220b370300200241c8016a41086a22042009370300200241c8016a41106a2203200a370300200241c8016a41186a2205200b370300200220022903a80222093703e801200220093703c801200241a8026a200110cf0220022802a8022201450d04200241c8006a41086a2208200241e8006a41086a290300370300200241c8006a41106a2207200241e8006a41106a290300370300200241c8006a41186a220c200241e8006a41186a290300370300200241286a41086a220d20024188016a41086a290300370300200241286a41106a220e20024188016a41106a290300370300200241286a41186a220f20024188016a41186a29030037030020022002290368370348200220022903880137032820022902ac022109200241086a41186a22102005290300370300200241086a41106a22052003290300370300200241086a41086a22032004290300370300200220022903c801370308200020093702082000200136020420002006360200200041106a2002290348370200200041186a2008290300370200200041206a2007290300370200200041286a200c290300370200200041306a2002290328370200200041386a200d290300370200200041c0006a200e290300370200200041c8006a200f290300370200200041e8006a2010290300370200200041e0006a2005290300370200200041d8006a2003290300370200200041d0006a20022903083702000c050b0240200341ff0171450d00200241003a00c8020b200041003602040c040b0240200441ff0171450d00200241003a00c8020b200041003602040c030b200041003602040c020b0240200441ff0171450d00200241003a00c8020b200041003602040c010b200041003602040b200241d0026a24000bc30202077f017e230041206b22022400200210c60302400240024002402002280208220341046a2204417f4c0d00200228020021050240024020040d0041012106410021040c010b200410332206450d020b2002410036021820022006360210200220043602142003200241106a10770240024020022802142207200228021822046b2003490d00200228021021060c010b200420036a22062004490d03200741017422082006200820064b1b22084100480d030240024020070d00024020080d00410121060c020b2008103322060d010c060b2002280210210620072008460d0020062007200810372206450d050b20022008360214200220063602100b200620046a20052003109d081a200420036aad4220862006ad84210902402002280204450d00200510350b200241206a240020090f0b1044000b1045000b103e000b103c000bbc34010f7f230041d0006b2201240020014100360238200142043703300240410810332202450d002002410c360204200241ba84c800360200200141306a41004101109001200128023020012802384103746a20022902003702002001200128023841016a36023820021035410810332202450d002002410c360204200241c684c800360200200141306a20012802384101109001200128023020012802384103746a20022902003702002001200128023841016a36023820021035410810332202450d0020024108360204200241d284c800360200200141306a20012802384101109001200128023020012802384103746a20022902003702002001200128023841016a36023820021035410810332202450d002002410a360204200241da84c800360200200141306a20012802384101109001200128023020012802384103746a20022902003702002001200128023841016a36023820021035410810332202450d002002410b360204200241e484c800360200200141306a20012802384101109001200128023020012802384103746a20022902003702002001200128023841016a36023820021035410810332202450d0020024118360204200241fcdfc600360200200141306a20012802384101109001200128023020012802384103746a200229020037020020012001280238220341016a22043602382002103520012802342105200128023021062001410036023820014204370330200141306a41002004410374220241037510870120012802382107024020042003490d00200620026a210820012802302007410c6c6a210220062104034020042802002203450d01200241086a200441046a280200360200200241046a2003360200200241003602002002410c6a2102200741016a2107200441086a22042008470d000b0b200120073602380240200541ffffffff0171450d00200610350b200128023421092001280230210a2001410036022820014201370320410410332202450d002001410436022420012002360220200241edcad18b063600002001410436022820012802202102024020012802244104470d0020024104410810372202450d0120014108360224200120023602200b2002410b3a000420014105360228411d200141206a107741ece4c600210b02400340200b2802042105200b2802082203200141206a10770240024020012802242206200128022822086b2003490d0020012802202104200621020c010b200820036a22022008490d02200641017422042002200420024b1b22024100480d020240024020060d00024020020d00410121040c020b2002103322040d010c050b2001280220210420062002460d0020042006200210372204450d040b20012002360224200120043602200b200420086a20052003109d081a2001200820036a220336022802400240200b28020c4102470d000240024020022003460d00200321020c010b200241016a22032002490d04200241017422082003200820034b1b22034100480d040240024020020d0041002102024020030d00410121040c020b200310332204450d070c010b20022003460d0020042002200310372204450d060b20012003360224200120043602200b200420026a41003a00002001200241016a22023602280c010b0240024020022003460d00200321020c010b200241016a22032002490d03200241017422082003200820034b1b22034100480d030240024020020d0041002102024020030d00410121040c020b200310332204450d060c010b20022003460d0020042002200310372204450d050b20012003360224200120043602200b200420026a41013a00002001200241016a36022802400240200b28020c4101470d00200b2802142106200b2802182202200141206a10770240024020012802242208200128022822046b2002490d00200128022021030c010b200420026a22032004490d05200841017422052003200520034b1b22054100480d050240024020080d00024020050d00410121030c020b200510332203450d080c010b2001280220210320082005460d0020032008200510372203450d070b20012005360224200120033602200b200320046a20062002109d081a2001200420026a360228200b28022021020240200b28021c4101470d002002200b280228200141206a107a0c020b2002200b41246a280200200141206a107a0c010b200141306a200b2802101103002001280234210620012802382202200141206a10770240024020012802242208200128022822046b2002490d00200128022021030c010b200420026a22032004490d04200841017422052003200520034b1b22054100480d040240024020080d00024020050d00410121030c020b200510332203450d070c010b2001280220210320082005460d0020032008200510372203450d060b20012005360224200120033602200b200320046a20062002109d081a2001200420026a360228200128024021030240200128023c4101460d0020032001280244200141206a107a0c010b200320012802482202200141206a107a02402002450d00200241d8006c21084100210403400240200320046a220241346a280200450d002002413c6a280200450d00200241386a28020010350b0240200241c4006a280200450d00200241cc006a28020041ffffffff0171450d00200241c8006a28020010350b2008200441d8006a2204470d000b0b20012802442202450d00200241d8006c450d00200310350b200128022821020b2001280224210402400240200b28022c4102470d000240024020042002460d00200128022021040c010b200241016a22042002490d04200241017422032004200320044b1b22034100480d040240024020020d0041002102024020030d00410121040c020b200310332204450d070c010b2001280220210420022003460d0020042002200310372204450d060b20012003360224200120043602200b200420026a41003a00002001200241016a22023602280c010b0240024020042002460d00200128022021040c010b200241016a22042002490d03200241017422032004200320044b1b22034100480d030240024020020d0041002102024020030d00410121040c020b200310332204450d060c010b2001280220210420022003460d0020042002200310372204450d050b20012003360224200120043602200b200420026a41013a00002001200241016a36022802400240200b28022c4101470d00200b2802302104200b2802382202200141206a10772002450d012002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d062006410174220d2008200d20084b1b220d4100480d060240024020060d000240200d0d00410121080c020b200d10332208450d090c010b200128022021082006200d460d0020082006200d10372208450d080b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a360228200241706a200141206a10792002200141206a10762002412c6a2102200541546a22050d000c020b0b200141186a200b28023011030020012802182104200128021c2202200141206a10772002450d002002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d052006410174220d2008200d20084b1b220d4100480d050240024020060d000240200d0d00410121080c020b200d10332208450d080c010b200128022021082006200d460d0020082006200d10372208450d070b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a360228200241706a200141206a10792002200141206a10762002412c6a2102200541546a22050d000b0b200128022821020b2001280224210402400240200b28023c4102470d000240024020042002460d00200128022021040c010b200241016a22042002490d04200241017422032004200320044b1b22034100480d040240024020020d0041002102024020030d00410121040c020b200310332204450d070c010b2001280220210420022003460d0020042002200310372204450d060b20012003360224200120043602200b200420026a41003a00002001200241016a3602280c010b0240024020042002460d00200128022021040c010b200241016a22042002490d03200241017422032004200320044b1b22034100480d030240024020020d0041002102024020030d00410121040c020b200310332204450d060c010b2001280220210420022003460d0020042002200310372204450d050b20012003360224200120043602200b200420026a41013a00002001200241016a3602280240200b28023c4101470d00200b2802402104200b2802482202200141206a10772002450d012002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d052006410174220d2008200d20084b1b220d4100480d050240024020060d000240200d0d00410121080c020b200d10332208450d080c010b200128022021082006200d460d0020082006200d10372208450d070b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a360228200241706a200141206a10762002200141206a10762002412c6a2102200541546a22050d000c020b0b200141106a200b2802401103002001280210210420012802142202200141206a10772002450d002002412c6c21052004411c6a21020340200241686a280200210c2002416c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d042006410174220d2008200d20084b1b220d4100480d040240024020060d000240200d0d00410121080c020b200d10332208450d070c010b200128022021082006200d460d0020082006200d10372208450d060b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a360228200241706a200141206a10762002200141206a10762002412c6a2102200541546a22050d000b0b02400240200b28024c4101470d00200b280250210e200b2802582202200141206a10772002450d01200241386c210f410021080340200e20086a220241046a280200210c200241086a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d052005410174220d2006200d20064b1b220d4100480d050240024020050d000240200d0d00410121060c020b200d10332206450d080c010b200128022021062005200d460d0020062005200d10372206450d070b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a360228200241106a280200210c200241146a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d052005410174220d2006200d20064b1b220d4100480d050240024020050d000240200d0d00410121060c020b200d10332206450d080c010b200128022021062005200d460d0020062005200d10372206450d070b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a36022802400240200241186a2802004101470d002002411c6a280200210c200241246a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d072005410174220d2006200d20064b1b220d4100480d070240024020050d000240200d0d00410121060c020b200d10332206450d0a0c010b200128022021062005200d460d0020062005200d10372206450d090b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a3602280c010b200141306a2002411c6a280200200241206a28020028020c1102002001280230210520012802382204200141206a1077024002402001280224220c200128022822036b2004490d00200128022021060c010b200320046a22062003490d06200c410174220d2006200d20064b1b220d4100480d0602400240200c0d000240200d0d00410121060c020b200d10332206450d090c010b20012802202106200c200d460d002006200c200d10372206450d080b2001200d360224200120063602200b200620036a20052004109d081a2001200320046a3602282001280234450d00200510350b200241286a200141206a1076200f200841386a2208470d000c020b0b200141086a200b2802501103002001280208210e200128020c2202200141206a10772002450d00200241386c210f410021080340200e20086a220241046a280200210c200241086a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d042005410174220d2006200d20064b1b220d4100480d040240024020050d000240200d0d00410121060c020b200d10332206450d070c010b200128022021062005200d460d0020062005200d10372206450d060b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a360228200241106a280200210c200241146a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d042005410174220d2006200d20064b1b220d4100480d040240024020050d000240200d0d00410121060c020b200d10332206450d070c010b200128022021062005200d460d0020062005200d10372206450d060b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a36022802400240200241186a2802004101470d002002411c6a280200210c200241246a2802002204200141206a10770240024020012802242205200128022822036b2004490d00200128022021060c010b200320046a22062003490d062005410174220d2006200d20064b1b220d4100480d060240024020050d000240200d0d00410121060c020b200d10332206450d090c010b200128022021062005200d460d0020062005200d10372206450d080b2001200d360224200120063602200b200620036a200c2004109d081a2001200320046a3602280c010b200141306a2002411c6a280200200241206a28020028020c1102002001280230210520012802382204200141206a1077024002402001280224220c200128022822036b2004490d00200128022021060c010b200320046a22062003490d05200c410174220d2006200d20064b1b220d4100480d0502400240200c0d000240200d0d00410121060c020b200d10332206450d080c010b20012802202106200c200d460d002006200c200d10372206450d070b2001200d360224200120063602200b200620036a20052004109d081a2001200320046a3602282001280234450d00200510350b200241286a200141206a1076200f200841386a2208470d000b0b02400240200b28025c4101470d00200b2802602104200b2802682202200141206a10772002450d012002411c6c21052004410c6a21020340200241786a280200210c2002417c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d052006410174220d2008200d20084b1b220d4100480d050240024020060d000240200d0d00410121080c020b200d10332208450d080c010b200128022021082006200d460d0020082006200d10372208450d070b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a3602282002200141206a10762002411c6a2102200541646a22050d000c020b0b2001200b2802601103002001280200210420012802042202200141206a10772002450d002002411c6c21052004410c6a21020340200241786a280200210c2002417c6a2802002204200141206a10770240024020012802242206200128022822036b2004490d00200128022021080c010b200320046a22082003490d042006410174220d2008200d20084b1b220d4100480d040240024020060d000240200d0d00410121080c020b200d10332208450d070c010b200128022021082006200d460d0020082006200d10372208450d060b2001200d360224200120083602200b200820036a200c2004109d081a2001200320046a3602282002200141206a10762002411c6a2102200541646a22050d000b0b200b41ec006a220b41a8fdc600470d000b02400240200128022420012802282202460d00200128022021040c010b200241016a22042002490d01200241017422032004200320044b1b22034100480d010240024020020d0041002102024020030d00410121040c020b200310332204450d040c010b2001280220210420022003460d0020042002200310372204450d030b20012003360224200120043602200b200420026a41043a00002001200241016a3602282007200141206a107702402007450d002007410c6c2105200a41086a210403402004417c6a280200210c20042802002202200141206a10770240024020012802242206200128022822036b2002490d00200128022021080c010b200320026a22082003490d032006410174220d2008200d20084b1b220d4100480d030240024020060d000240200d0d00410121080c020b200d10332208450d060c010b200128022021082006200d460d0020082006200d10372208450d050b2001200d360224200120083602200b200820036a200c2002109d081a2001200320026a3602282004410c6a2104200541746a22050d000b0b20002001290320370200200041086a200141206a41086a28020036020002402009450d002009410c6c450d00200a10350b200141d0006a24000f0b103e000b103c000bbc0602057f017e230041900b6b22022400024002402001450d00200220003602000c010b200241b0b4cc003602000b20022001360204200241b8076a200210c803024002400240024020022903a0084203510d00200241186a200241b8076a41c803109d081a200241e0036a200241186a41c803109d081a2002200241e0036a3602b807200241a8076a200241b8076a10b90320022802b0072101200241b8076a200241e0036a41c803109d081a200241880b6a20022802b007360200200220022903a8073703800b200241086a200241b8076a2001200241800b6a10bb034101410220022d000822034101461b220010332201450d01200241003602c007200220003602bc07200220013602b8070240024020034101470d00200141013a0000200241013602c007200241086a410172200241b8076a10c90320022802c00721010c010b200141003a0000200241013602c0070240024020022d000c22044104460d00200141013a000141022103200241023602c00702400240024002400240024020040e0400010203000b410021040c030b410121040c020b200241023a00e003410221040c020b200241033a00e0034104210020014102410410372201450d07200141033a0002200220013602b80720024284808080303702bc07200220022d000d22033a00e003024041010d004106210020014103410610372201450d08200241063602bc07200220013602b8070b200120033a000341042103200241043602c00720022d000e21040b200220043a00e0030b024020002003470d0041000d070240200020004101742205200041016a2206200520064b1b2205460d0020012000200510372201450d070b200220053602bc07200220013602b8070b200120036a20043a0000200341017221010c010b200141003a0001410221010b200220013602c0070b20023502b8072107200241900b6a240020072001ad422086840f0b200241246a4104360200200241f4036a4102360200200242023702e403200241f0b2c3003602e0032002410436021c200241d0b3c3003602182002410036020c200241b0b4cc003602082002200241186a3602f0032002200241086a360220200241e0036a4180b3c300104c000b1045000b103c000b103e000bfb1104047f017e037f047e230041c0086b22022400200241286a200110c401024002400240024002400240024020022802280d0020012802042203450d01200128020022042d0000210520012003417f6a3602042001200441016a360200200541ff00714104470d0220054118744118754100480d03420221060c040b200042033703680c050b200042033703680c040b200042033703680c030b20024198076a20011092060240024020022d0098074102460d00200241f0066a41206a20024198076a41206a280200360200200241f0066a41186a20024198076a41186a290300370300200241f0066a41106a20024198076a41106a290300370300200241f0066a41086a20024198076a41086a29030037030020022002290398073703f00620012802042205450d00200128020022042d0000210320012005417f6a3602042001200441016a360200200341024b0d00024002400240024002400240024020030e03000102000b41002103200241003a00f8042005417f6a2107417e21080240034020072003460d01200241b8046a20036a200420036a220941016a2d00003a00002001200520086a3602042001200941026a3602002002200341016a22093a00f8042008417f6a210820092103200941c000470d000b20024180086a41386a200241b8046a41386a290300220637030020024180086a41306a200241b8046a41306a290300220a37030020024180086a41286a200241b8046a41286a290300220b37030020024180086a41206a200241b8046a41206a290300220c37030020024180086a41186a200241b8046a41186a290300220d37030020024188026a41086a200241b8046a41086a29030037030020024188026a41106a200241b8046a41106a29030037030020024188026a41186a200d37030020024188026a41206a200c37030020024188026a41286a200b37030020024188026a41306a200a37030020024188026a41386a2006370300200220022903b804370388022009417f7320056a2105200420096a41016a2104410021030c030b200341ff0171450d06200241003a00f804420221060c070b41002103200241003a00f8042005417f6a2107417e21080240034020072003460d01200241b8046a20036a200420036a220941016a2d00003a00002001200520086a3602042001200941026a3602002002200341016a22093a00f8042008417f6a210820092103200941c000470d000b20024180086a41386a200241b8046a41386a290300220637030020024180086a41306a200241b8046a41306a290300220a37030020024180086a41286a200241b8046a41286a290300220b37030020024180086a41206a200241b8046a41206a290300220c37030020024180086a41186a200241b8046a41186a290300220d37030020024188026a41086a200241b8046a41086a29030037030020024188026a41106a200241b8046a41106a29030037030020024188026a41186a200d37030020024188026a41206a200c37030020024188026a41286a200b37030020024188026a41306a200a37030020024188026a41386a2006370300200220022903b804370388022009417f7320056a210541012103200420096a41016a21040c020b200341ff0171450d05200241003a00f804420221060c060b41002103200241003a00f9042005417f6a2107417e2108034020072003460d02200241b8046a20036a200420036a220941016a2d00003a00002001200520086a3602042001200941026a3602002002200341016a22093a00f9042008417f6a210820092103200941c100470d000b20024188026a200241b8046a41c100109d081a2009417f7320056a2105200420096a41016a2104410221030b200241bf076a20024188026a41c100109d081a2005450d032004310000210b20012005417f6a22083602042001200441016a360200200b50450d01420021060c020b200341ff0171450d02200241003a00f904420221060c030b2008450d012004310001210c20012005417e6a3602042001200441026a3602004202200b420f8386220a4204540d0142012106200c420886200b84420488200a420c88220b4201200b4201561b7e220b200a5a0d010b200241206a200110c40120022802200d0020022802242105200241086a200110f6012002290308a70d00200241086a41106a290300210d2002290310210c20024180086a41206a200241f0066a41206a28020036020020024180086a41186a200241f0066a41186a29030037030020024180086a41106a200241f0066a41106a29030037030020024180086a41086a200241f0066a41086a290300370300200220022903f00637038008200241b8046a200241bf076a41c100109d081a200220022f01ee063b0186020c010b420221060b200241e0016a41086a220420024180086a41086a290300370300200241e0016a41106a220820024180086a41106a290300370300200241e0016a41186a220920024180086a41186a290300370300200241e0016a41206a220720024180086a41206a28020036020020022002290380083703e0012002419f016a200241b8046a41c100109d081a200220022f0186023b019c0120064202510d01200241f8006a41206a2007280200360200200241f8006a41186a2009290300370300200241f8006a41106a2008290300370300200241f8006a41086a2004290300370300200220022903e001370378200241376a2002419f016a41c100109d081a200220022f019c013b01340b200241b8046a200110b90220022802b804210120024188026a200241b8046a41047241ac02109d081a02402001411b460d0020002002290378370300200020033a0024200041206a200241f8006a41206a280200360200200041186a200241f8006a41186a290300370300200041106a200241f8006a41106a290300370300200041086a200241f8006a41086a290300370300200041256a200241376a41c100109d081a200020022f01343b016620004190016a200d37030020004188016a200c37030020004198016a200136020020004180016a2005360200200041f8006a200b3703002000200a370370200020063703682000419c016a20024188026a41ac02109d081a0c020b200042033703680c010b200042033703680b200241c0086a24000bb30301027f230041106b220224000240024020002d00004101460d00200241003a000e20012002410e6a4101107820002d0001220341094b0d010240024002400240024002400240024002400240024020030e0a00010203040506070809000b200241003a000f2002410f6a21000c090b200241013a000f2002410f6a21000c080b200241023a000f2002410f6a21000c070b200241033a000f2002410f6a21000c060b200241043a000f2002410f6a21000c050b200241053a000f2002410f6a21000c040b200241063a000f2002410f6a21000c030b200241073a000f20012002410f6a410110782002200041026a2d00003a000f2002410f6a21000c020b200241083a000f2002410f6a21000c010b200241093a000f2002410f6a21000b20012000410110780c010b200241013a000e20012002410e6a4101107820002d0001220341024b0d0002400240024020030e03000102000b200241003a000e20012002410e6a410110780c020b200241013a000e20012002410e6a410110780c010b200241023a000e20012002410e6a410110782002200041026a2d00003a000e20012002410e6a410110780b200241106a24000be11305047f017e017f017e0b7f23004180026b2202240010bc03200241106a41186a22034200370300200241106a41106a22044200370300200241106a41086a220542003703002002420037031041d1c4c700ad4280808080e000842206100122072900002108200241d0016a41086a2209200741086a290000370300200220083703d0012007103520052009290300370300200220022903d00137031041e7c4c700ad4280808080e00084100122072900002108200241b0016a41086a220a200741086a290000370300200220083703b00120071035200420022903b001220837030020092005290300370300200241d0016a41106a220b2008370300200241d0016a41186a220c200a290300370300200220022903103703d001200241086a200241d0016a412010c00141002107200228020c410020022802081b10bd032003420037030020044200370300200542003703002002420037031020061001220d2900002108200241f0016a41086a220e200d41086a290000370300200220083703f001200d10352005200e290300370300200220022903f00137031041ecedc700ad4280808080e001841001220d2900002108200e200d41086a290000370300200220083703f001200d1035200420022903f001220837030020092005290300370300200b2008370300200c200e290300370300200220022903103703d0012002200241d0016a412010c0012002280204210d2002280200210f200241003602b801200242043703b001200241b0016a4100200d4100200f1b221010870120022802b801211102402010450d0020022802b0012011410c6c6a210d0340200241d0016a200710cb03200241106a20022802d001221220022802d801221310e00202402002280210220f450d002013ad4220862012ad8410070b200741016a210720022902144200200f1b2108200f4101200f1b210f024020022802d401450d00201210350b200d200f360200200d41046a2008370200200d410c6a210d20102007470d000b201120106a21110b20024180016a41086a2011360200200220022903b001220837038001200520113602002002200837031020024190016a200241106a10ba03200241b0016a41186a20024190016a41186a290300370300200241b0016a41106a20024190016a41106a290300370300200a20024190016a41086a29030037030020022002290390013703b001200342003703002004420037030020054200370300200242003703102006100122072900002108200e200741086a290000370300200220083703f001200710352005200e290300370300200220022903f00137031041f7c4c700ad4280808080e00184100122072900002108200e200741086a290000370300200220083703f00120071035200420022903f001370000200441086a200e29030037000020092005290300370300200b2004290300370300200c2003290300370300200220022903103703d001024002400240412010332207450d00200720022903b001370000200741186a200241b0016a41186a290300370000200741106a200241b0016a41106a290300370000200741086a200241b0016a41086a290300370000200241d0016aad42808080808004842007ad4280808080800484100220071035200241106a10be03200241003602b801200242013703b001412010332207450d0020072002290320370000200741186a200241386a290300370000200741106a200241106a41206a290300370000200741086a200241106a41186a29030037000041201033220d450d02200241203602b4012002200d3602b001200d2007290000370000200d41086a200741086a290000370000200d41106a200741106a290000370000200d41186a200741186a290000370000200241203602b80120071035200241106a200241b0016a10e201412010332207450d0020072002290340370000200741186a200241d8006a290300370000200741106a200241d0006a290300370000200741086a200241c8006a2903003700000240024020022802b401221020022802b80122136b4120490d00201341206a210d20022802b001210f201021120c010b201341206a220d2013490d022010410174220f200d200f200d4b1b22124100480d020240024020100d00024020120d004101210f0c020b20121033220f0d010c050b20022802b001210f20102012460d00200f201020121037220f450d040b200220123602b4012002200f3602b0010b200f20136a22132007290000370000201341186a200741186a290000370000201341106a200741106a290000370000201341086a200741086a2900003700002002200d3602b80120071035412010332207450d0020072002290360370000200741186a200241f8006a290300370000200741106a200241f0006a290300370000200741086a200241e8006a29030037000002402012200d6b411f4b0d00200d41206a2213200d490d02201241017422102013201020134b1b22134100480d020240024020120d00024020130d004101210f0c020b20131033220f450d050c010b20122013460d00200f201220131037220f450d040b200220133602b4012002200f3602b0010b200f200d6a220f2007290000370000200f41186a200741186a290000370000200f41106a200741106a290000370000200f41086a200741086a2900003700002002200d41206a3602b80120071035200228021421112002411c6a2802002209200241b0016a10770240024020090d0020022802b801210d20022802b00121050c010b200941246c210e20022802b401210f20022802b8012107201121130340200241d0016a201310c00320022802d001210402400240200f20076b20022802d8012210490d00200720106a210d20022802b0012105200f21120c010b200720106a220d2007490d04200f4101742212200d2012200d4b1b22124100480d0402400240200f0d00024020120d00410121050c020b201210332205450d070c010b20022802b0012105200f2012460d002005200f201210372205450d060b200220123602b401200220053602b0010b200520076a20042010109d081a2002200d3602b801024020022802d401450d00200410350b201341246a21132012210f200d2107200e415c6a220e0d000b0b200dad42208621082005ad210602402009450d00200941246c210d2011210703400240024020072d0000220f41044b0d00024002400240200f0e050400010204040b2007410c6a280200450d03200741086a28020010350c030b2007410c6a280200450d02200741086a28020010350c020b2007410c6a280200450d01200741086a28020010350c010b200741086a280200450d00200741046a28020010350b200741246a2107200d415c6a220d0d000b0b200820068421080240200241186a2802002207450d00200741246c450d00201110350b20024180026a240020080f0b1045000b103e000b103c000bfc0403027f017e057f230041d0006b2202240041d1c4c700ad4280808080e00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541e8eec700ad4280808080d00184100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000be82709017f017e017f017e017f017e0f7f017e0b7f230041b0056b22022400024002402001450d00200220003602200c010b200241b0b4cc003602200b20022001360224200241186a200241206a10c4010240024020022802180d00200228021c21012002200241206a36029005200241003a00f802200241003602a804200241003602a0042002200136025c200241003602582002200241f8026a360264200220024190056a360260200241d8006a200241a0046a10cd03200241b8036a41086a20022802a8042201360200200220022903a00422033703b80320022d00f8022100200241d8006a41086a22042001360200200220033703582000450d01200241d8006a10a0020b200241ac046a4104360200200241ec006a41023602002002420237025c200241f0b2c300360258200241043602a404200241e8b3c3003602a004200241003602bc03200241b0b4cc003602b8032002200241a0046a3602682002200241b8036a3602a804200241d8006a4180b3c300104c000b200241286a41086a20042802002201360200200220022903582203370328200241386a41086a2001360200200220033703382002410036025020024208370348200241d8006a200241386a10ce0302400240024020022802584101460d00200241d8006a41086a290300210342002105200241f8026a41186a4200370300200241f8026a41106a22064200370300200241f8026a41086a22014200370300200242003703f80241d1efcb00ad42808080809001841001220029000021072001200041086a290000370300200220073703f8022000103541ebc3c400ad4280808080308410012200290000210720024198036a41086a2204200041086a2900003703002002200737039803200010352006200229039803220737030020024190056a41086a200129030037030020024190056a41106a200737030020024190056a41186a2004290300370300200220022903f80237039005200241086a20024190056a10e1022002280208210020022903102107200241c8006a410010a901200228024822082002280250220441c8036c6a220141033602980120014202370368200141a0016a2003200742dc0b7c42dc0b20001b220720032007561b3703002002200441016a22093602504104210a02402002280238220b450d00200228023c210c200b210d0340200d41086a2100200d2f0106220e4103742101410021040240024003402001450d0141f495ca002000410810a008220f450d02200141786a2101200441016a2104200041086a2100200f417f4a0d000b2004417f6a210e0b200c450d02200c417f6a210c200d200e4102746a41e4016a280200210d0c010b0b2002200d2004410c6c6a220141e8006a2802003602a4042002200141e0006a2802003602a004200241d8006a200241a0046a10cf032002280258220a450d02200229025c21050b2005422088a7210e2005a721100c020b200241a8046a200241e4006a2902003703002002200229025c3703a0044184c8c4004128200241a0046a41ecc7c40041acc8c4001046000b4104210a4100210e410021100b200241003602b003200242043703a8030240024002400240024002400240200e450d00200241d8006a41186a220c4200370300200241d8006a41106a22114200370300200241d8006a41086a220f4200370300200242003703584193d1cb00ad4280808080a00184100122012900002103200f200141086a290000370300200220033703582001103541e0caca00ad4280808080e0008410012201290000210320024198036a41086a2200200141086a2900003703002002200337039803200110352011200229039803220337030020024190056a41086a200f29030037030020024190056a41106a200337030020024190056a41186a20002903003703002002200229035837039005200241d8006a20024190056a10b60220022802582201410420011b2112200229025c420020011b2203a721130240024002402003422088a72214450d002012201441c4006c22016a210d200141bc7f6a210420122101034020012d00002100200241d8006a200141016a41c300109d081a20004102460d01200241f8026a41186a200c290000370300200241f8026a41106a2011290000370300200241f8026a41086a200f290000370300200220022900583703f80220004101460d02200441bc7f6a2104200141c4006a2201200d470d000b0b2002410036028003200242013703f8022013450d01201341c4006c450d01201210350c010b20024190056a41086a2200200241f8026a41086a29030037030020024190056a41106a220f200241f8026a41106a29030037030020024190056a41186a220c200241f8026a41186a290300370300200220022903f80222033703b8032002200337039005412010332215450d042015200229039005370000201541186a200c290300370000201541106a200f290300370000201541086a2000290300370000200242818080801037029c03200220153602980302402004450d00200141c4006a2100201441c4006c20126a41bc7f6a211641012114034020002101034020012d00002100200241d8006a200141016a41c300109d081a20004102460d02200241f8026a41186a2204200241d8006a41186a290000370300200241f8026a41106a220f200241d8006a41106a290000370300200241f8026a41086a220c200241d8006a41086a290000370300200220022900583703f802024020004101460d00200141c4006a2201200d470d010c030b0b20024190056a41086a200c290300220337030020024190056a41106a200f290300220537030020024190056a41186a20042903002207370300200220022903f802221737039005200241b8036a41186a220f2007370300200241b8036a41106a220c2005370300200241b8036a41086a22182003370300200220173703b80302402014200228029c03470d0020024198036a20144101108a0120022802980321150b200141c4006a2100201520144105746a220420022903b803370000200441186a200f290300370000200441106a200c290300370000200441086a20182903003700002002201441016a22143602a00320162001470d000b0b02402013450d00201341c4006c450d00201210350b200241f8026a41086a20024198036a41086a28020036020020022002290398033703f8020b200a200e41f0006c6a2115200241a0046a41106a2119200241a0046a41086a211a41d1c4c700ad4280808080e0008421054104211b4104211c4104211d4100211e200a210f0340200f280204210d200f2802002104200241d8006a200f41086a41e800109d081a200f41f0006a210f200d450d02200241b8036a200241d8006a41e800109d081a2002200d3602a404200220043602a004201a200241b8036a41e800109d081a200241d8006a41186a22164200370300200241d8006a41106a22184200370300200241d8006a41086a220c4200370300200242003703582005100122012900002103200c200141086a290000370300200220033703582001103541e7c4c700ad4280808080e0008410012201290000210320024198036a41086a2200200141086a2900003703002002200337039803200110352011200229039803370000201141086a200029030037000020024190056a41086a221f200c29030037030020024190056a41106a2220201829030037030020024190056a41186a222120162903003703002002200229035837039005200220024190056a412010c001200228020021012002280204210020024190056a200241a0046a10d003024002402004417f6a220e2000410020011b22014f0d00200241d8006a200e10d103200241d8006a2019412010a0080d00200441002001417b6a2200200020014b1b490d002002280280032222410574211220024190056a20022802f802220e6b21144100210102400340024020122001470d00410021130c020b4101211320142001460d01200e20016a2100200141206a2101200020024190056a412010a0080d000b0b200241d8006a200410d103200241d8006a20024190056a412010a008210120130d002001450d0020024190056a200241a0046a10d003200241d8006a200241a0046a41f000109d081a0240201e20022802ac03470d00200241a8036a201e410110930120022802b003211e20022802a803221b211c201b211d0b201d201e41f0006c6a200241d8006a41f000109d081a2002201e41016a221e3602b0032016202129030037030020182020290300370300200c201f29030037030020022002290390053703580240202220022802fc02470d00200241f8026a20224101108a0120022802f802210e20022802800321220b200e20224105746a22012002290358370000200141186a2016290300370000200141106a2018290300370000200141086a200c2903003700002002202241016a36028003201e410a470d01410a211e0c040b024020022802ac042201450d00200141246c2100200d210103400240024020012d0000220441044b0d0002400240024020040e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b20022802a8042201450d00200141246c450d00200d10350b200f2015470d000b2015210f0c010b2010450d01201041f0006c450d01200a10350c010b02402015200f460d000340200f220141046a220010b103200141f0006a210f0240200141086a2802002201450d00200141246c450d00200028020010350b2015200f470d000b0b02402010450d00201041f0006c450d00200a10350b024020022802fc0241ffffff3f71450d0020022802f80210350b0240201e0d0020022802ac032201450d01200141f0006c450d01201b10350c010b201c450d0020022902ac03210302402009200228024c470d00200241c8006a200910a90120022802482108200228025021090b2008200941c8036c6a200241a0046a41e800109d0822014202370368200141a0016a20033703002001419c016a201c3602002001410436029801200120022903b803370370200141f8006a200241c0036a29030037030020014180016a200241c8036a29030037030020014188016a200241d0036a29030037030020014190016a200241d8036a290300370300200141a8016a200241d8006a41a002109d081a2002200941016a22093602500b0240200b450d00200228023c210d0340200b41086a2100200b2f0106220c4103742101410021040240024003402001450d0141fc95ca002000410810a008220f450d02200141786a2101200441016a2104200041086a2100200f417f4a0d000b2004417f6a210c0b200d450d02200d417f6a210d200b200c4102746a41e4016a280200210b0c010b0b200b41e0006a2004410c6c6a22012802084104490d002001280200280000210f200241f8026a41186a22044200370300200241f8026a41106a220d4200370300200241f8026a41086a22014200370300200242003703f80241bee4cb00ad4280808080f001841001220029000021032001200041086a290000370300200220033703f8022000103541b9e0c600ad4280808080b0018410012200290000210320024198036a41086a220c200041086a2900003703002002200337039803200010352006200229039803370000200641086a200c29030037000020024190056a41086a200129030037030020024190056a41106a200d29030037030020024190056a41186a2004290300370300200220022903f80237039005200241d8006a20024190056a10c50220022802582201410420011b2104410021000240200229025c420020011b2203422088a72201450d00200141027420046a417c6a2201450d002001280200200f4721000b0240200342ffffffff0383500d00200410350b2000450d0002402009200228024c470d00200241c8006a200910a90120022802482108200228025021090b2008200941c8036c6a200241a0046a41e800109d0822014202370368200120022903b803370370200141f8006a200241c0036a29030037030020014180016a200241c8036a29030037030020014188016a200241d0036a29030037030020014190016a200241d8036a2903003703002001419c016a200f3602002001410e36029801200141a8016a200241d8006a41a002109d081a2002200941016a22093602500b200228024c2114200241386a10a002200941c8036c4104722201417f4c0d01200110332200450d00200241003602a804200220013602a404200220003602a0042009200241a0046a10770240024020090d0020022802a804210020022802a004210e0c010b200941c8036c211320022802a404210420022802a80421012008210d03402002200d3602b803200241d8006a200241b8036a10b9032002280258211202400240200420016b2002280260220c490d002001200c6a210020022802a004210e2004210f0c010b2001200c6a22002001490d052004410174220f2000200f20004b1b220f4100480d050240024020040d000240200f0d004101210e0c020b200f1033220e0d010c080b20022802a004210e2004200f460d00200e2004200f1037220e450d070b2002200f3602a4042002200e3602a0040b200e20016a2012200c109d081a200220003602a8040240200228025c450d00201210350b200d41c8036a210d200f210420002101201341b87c6a22130d000b0b2000ad4220862103200ead210502402009450d00200941c8036c210020084198016a21010340200110bb02200141c8036a2101200041b87c6a22000d000b0b2003200584210302402014450d00201441c8036c450d00200810350b200241b0056a240020030f0b1045000b1044000b103e000b103c000bd40505067f017e047f017e027f23004180026b22022400024002400240024002402000280200220320002802044f0d00200028020c2104200141086a2105200241a0016a4102722106024003402000200341016a360200200241186a2000280208280200220710ee0220022d00184101460d0120022900192108200241086a200710c40120022802080d012007280204200228020c2203490d012003417f4c0d0302400240024020030d0041002107410121090c010b200310392209450d0820072802042003490d01200920072802002003109d081a2007280204220a2003490d062007200a20036b3602042007200728020020036a360200200321070b20022008370310024002402001280200220b450d002001280204210c0c010b2006410041da00109f081a200241186a4100418401109f081a41e4011033220b450d074100210c200b4100360200200b41046a200241a0016a41dc00109d081a200b41e0006a200241186a418401109d081a200141003602042001200b3602000b2003ad4220862007ad84210d024002400340200b41086a2107200b2f0106220e41037421034100210a024003402003450d01200241106a2007410810a008220f450d03200341786a2103200a41016a210a200741086a2107200f417f4a0d000b200a417f6a210e0b0240200c450d00200c417f6a210c200b200e4102746a41e4016a280200210b0c010b0b2002200837022c200220053602282002200e360224200220013602202002200b36021c200241003602182002200d3702a401200220093602a001200241186a200241a0016a1082030c010b200b200a410c6c6a220341e4006a2207280200210a2007200d370200200341e0006a22072802002103200720093602002003450d00200a450d00200310350b200028020022032000280204490d010c030b0b200910350b200441013a00000b20024180026a24000f0b1044000b2003200a41a4f0cb001059000b103c000b1045000b8c0201067f02400240024020012802002202450d00200128020421030340200241086a210420022f010622054103742101410021060240024003402001450d0141f8eecb002004410810a0082207450d02200141786a2101200641016a2106200441086a21042007417f4a0d000b2006417f6a21050b2003450d022003417f6a2103200220054102746a41e4016a28020021020c010b0b200241e0006a2006410c6c6a22012802084108490d01200041086a2001280200290000370300200041003602000f0b200041003602042000410c6a4128360200200041086a4180efcb003602000c010b200041003602042000410c6a4129360200200041086a41a8efcb003602000b200041013602000bf80303037f017e057f230041e0026b22022400200241086a200110c40102400240024002402002280208450d00200041003602000c010b200228020c2203200128020441f0006e2204200420034b1bad42f0007e2205422088a70d012005a72206417f4c0d010240024020060d00410421070c010b200610332207450d030b4100210420024100360218200220073602102002200641f0006e360214024002402003450d00200241f0016a41086a21080340200241f0016a200110c40320022802f401210620022802f001210920024188016a200841e800109d081a2006450d02200241206a20024188016a41e800109d081a024020042002280214470d00200241106a2004410110930120022802102107200228021821040b2007200441f0006c6a220a2006360204200a2009360200200a41086a200241206a41e800109d081a2002200441016a22043602182003417f6a22030d000b0b20002002290310370200200041086a200241106a41086a2802003602000c010b2000410036020002402004450d00200441f0006c2106200741046a21040340200410b1030240200441046a280200220a450d00200a41246c450d00200428020010350b200441f0006a2104200641907f6a22060d000b0b20022802142204450d00200441f0006c450d00200710350b200241e0026a24000f0b1044000b1045000b9b0902097f037e230041206b220224002002410036020820024201370300024002400240412010332203450d0020032001290010370000200341186a2204200141286a290000370000200341106a2205200141206a290000370000200341086a2206200141186a290000370000412010332207450d02200241203602042002200736020020072003290000370000200741086a2006290000370000200741106a2005290000370000200741186a200429000037000020024120360208200310352001200210e201412010332203450d0020032001290030370000200341186a200141c8006a290000370000200341106a200141c0006a290000370000200341086a200141386a2900003700000240024020022802042208200228020822066b4120490d00200641206a210720022802002104200821050c010b200641206a22072006490d02200841017422042007200420074b1b22054100480d020240024020080d00024020050d00410121040c020b2005103322040d010c050b2002280200210420082005460d0020042008200510372204450d040b20022005360204200220043602000b200420066a22062003290000370000200641186a200341186a290000370000200641106a200341106a290000370000200641086a200341086a2900003700002002200736020820031035412010332203450d0020032001290050370000200341186a200141e8006a290000370000200341106a200141e0006a290000370000200341086a200141d8006a2900003700000240200520076b411f4b0d00200741206a22062007490d02200541017422082006200820064b1b22064100480d020240024020050d00024020060d00410121040c020b200610332204450d050c010b20052006460d0020042005200610372204450d040b20022006360204200220043602000b200420076a22042003290000370000200441186a200341186a290000370000200441106a200341106a290000370000200441086a200341086a2900003700002002200741206a36020820031035200128020421052001410c6a2802002201200210770240024020010d002002280208210320022802042104200228020021080c010b200141246c210920022802042107200228020821010340200241106a200510c0032002280210210a02400240200720016b20022802182206490d00200120066a210320022802002108200721040c010b200120066a22032001490d04200741017422042003200420034b1b22044100480d040240024020070d00024020040d00410121080c020b200410332208450d070c010b2002280200210820072004460d0020082007200410372208450d060b20022004360204200220083602000b200820016a200a2006109d081a2002200336020802402002280214450d00200a10350b200541246a210520042107200321012009415c6a22090d000b0b2003ad4220862008ad8410092201290000210b200141086a290000210c200141106a290000210d200041186a200141186a290000370000200041106a200d370000200041086a200c3700002000200b3700002001103502402004450d00200810350b200241206a24000f0b1045000b103e000b103c000bb90603027f017e057f23004180016b2202240041d1c4c700ad4280808080e00084100122032900002104200241306a41086a200341086a290000370300200220043703302003103541dec4c700ad4280808080900184100122032900002104200241d0006a41086a200341086a2900003703002002200437035020031035200220013602742002200241f4006aad4280808080c000841003220329000037037820031035200241146a200241f8006a3602002002200241f8006a41086a36020c2002200241f4006a3602102002200241f8006a360208200241c0006a200241086a107b02400240024002402002280248220541206a2206417f4c0d00200228024021070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290330370000200341086a200241306a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290350370010200341186a200241d0006a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a02402002280244450d00200710350b200241086a2003200610d501200241d0006a41086a2201200241116a290000370300200241d0006a41106a2206200241196a290000370300200241d0006a41186a2205200241216a290000370300200220022900093703500240024020022d00084101460d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b20002002290350370000200041186a2005290300370000200041106a2006290300370000200041086a20012903003700000b02402008450d00200310350b20024180016a24000f0b1044000b1045000b103e000b103c000bac2508077f017e0d7f017e017f027e017f037e230041f0026b22022400024002402001450d00200220003602180c010b200241b0b4cc003602180b2002200136021c200241f8006a200241186a10b6030240024002400240024002400240200228027c2203450d00200241f0016a2802002104200241ec016a2802002105200241e8016a2802002106200241f8006a410c6a28020021072002280280012108200241106a200241186a10c4010240024020022802100d00200228021421012002200241186a360250200241003a0020200241003602980220024100360290022002200136027c200241003602782002200241206a360284012002200241d0006a36028001200241f8006a20024190026a10cd03200241e0006a41086a20022802980222013602002002200229039002220937036020022d00202100200241f8006a41086a220a2001360200200220093703782000450d01200241f8006a10a0020b20024190026a410c6a41043602002002418c016a41023602002002420237027c200241f0b2c300360278200241043602940220024184b4c3003602900220024100360264200241b0b4cc00360260200220024190026a360288012002200241e0006a36029802200241f8006a4180b3c300104c000b200241306a41086a200a2802002201360200200220022903782209370330200241c0006a41086a200136020020022009370340200241013b015c2002410036025820024100360250024002402004450d002006200441c8036c6a210b200241d0006a41086a210c200241e0006a410472210d20024190026a410272210e200241f8006a41106a210f200621100340201041e8006a2903004202520d0102400240024002400240201028029801221141034722120d00024002400240024020022802402213450d0020102903a0012109200228024421140340201341086a210020132f0106221541037421014100210a0240024003402001450d01418799cc002000410810a0082216450d02200141786a2101200a41016a210a200041086a21002016417f4a0d000b200a417f6a21150b2014450d022014417f6a2114201320154102746a41e4016a28020021130c010b0b0240201341e0006a200a410c6c6a220128020841074b0d002017428080808070834229842109418f99cc0021140c020b200942b8178020012802002900002217510d034131211841e8c1c30021140c020b201742808080807083421c84210941b899cc0021140b2009a721180b0240024020022d005d450d0041c4c6ca002101413121000c010b200241d0006a10a0022002410036025820024100360250200242e2c289abb68edbb7f40037036020024190026a410272410041da00109f081a200241f8006a4100418401109f081a41e40110332216450d1020164100360200201641046a20024190026a41dc00109d081a201641e0006a200241f8006a418401109d081a200241003602542002201636025020162f010622104103742113417f210041002101024002400340024020132001470d00201021000c020b200241e0006a201620016a41086a410810a008220a450d02200141086a2101200041016a2100200a41004e0d000b0b200242e2c289abb68edbb7f40037028c012002200c3602880120022000360284012002201636027c200241003602782002200241d0006a3602800120024190026a2014201810d303200241f8006a20024190026a10820320024180023b015c200241206a41086a200241d0006a41086a290300370300200220022903503703200c0a0b41f5c6ca002101412d21000b2002200036027c200220013602784181c6ca004122200241f8006a41a4c6ca0041b4c6ca001046000b20120d0020102903a0012109200241f8006a200241c0006a10ce03024002400240024020022802784101460d002002290380012119200241f8006a41186a220a4200370300200f4200370300200241f8006a41086a220142003703002002420037037841d1efcb00ad428080808090018410012200290000211a2001200041086a2900003703002002201a3703782000103541ebc3c400ad4280808080308410012200290000211a200241e0006a41086a2216200041086a2900003703002002201a37036020001035200f2002290360370000200f41086a201629030037000020024190026a41086a200129030037030020024190026a41106a200f29030037030020024190026a41186a200a2903003703002002200229037837039002200220024190026a10e1022009201942b0ea017c560d012009200229030842dc0b7c42dc0b20022802001b22195a0d032019422088211a420021090c020b2002290380012219422088211a200228027c221bad4220864201842109201c4280808080708320023502880184221c211d0c010b201d428080808070832018ad84211d41e9eac400ad21194225211a420121094100211b0b2002201d3703702002201a422086201942ffffffff0f8384221e3703682002201bad422086200942ffffffff0f838437036002400240024020022d005d450d0041c4c6ca002101413121000c010b0240024002402009a722154101470d00200241d0006a10a0022002410036025820024100360250200242f4d2b59bc7ae98b8303703200c010b20022802502113200242f4d2b59bc7ae98b8303703202013450d00200228025421140c010b200e410041da00109f081a200241f8006a4100418401109f081a41e40110332213450d124100211420134100360200201341046a20024190026a41dc00109d081a201341e0006a200241f8006a418401109d081a20024100360254200220133602500b2019a72112201aa7211102400340201341086a210020132f0106221841037421014100210a024003402001450d01200241206a2000410810a0082216450d03200141786a2101200a41016a210a200041086a21002016417f4a0d000b200a417f6a21180b02402014450d002014417f6a2114201320184102746a41e4016a28020021130c010b0b200242f4d2b59bc7ae98b83037028c012002200c3602880120022018360284012002201336027c200241003602782002200241d0006a360280014101103321010240201541014622160d002001450d13200141003a000020014101410910372201450d132001201e3700014109210a410921000c030b2001450d12200141013a000020024190026a200d10b40320022802900221140240024020022802980222130d004101210a201341016a21000c010b201341016a22002013490d1020004102200041024b1b220a4100480d1020014101200a10372201450d130b200141016a20142013109d081a200228029402450d02201410350c020b41f5c6ca002101412d21000b2002200036027c200220013602784181c6ca004122200241f8006a41a4c6ca0041b4c6ca001046000b20022000360298022002200a360294022002200136029002200241f8006a20024190026a108203200220093c005d200241003a005c20160d022015450d00201b450d002011450d00201210350b20102802980121110b20114104470d03201041a4016a280200410b490d032002410d36026820024192c8ca003602642002410036026020022d005d450d0141c4c6ca002101413121000c020b200241206a41086a200241d0006a41086a29030037030020022002290350370320201b450d052011450d05201210350c050b200241d0006a10a0022002410036025820024100360250200242f5dc8de3d6ec9c983037032020024190026a410272410041da00109f081a200241f8006a4100418401109f081a41e40110332216450d0b4100210120164100360200201641046a20024190026a41dc00109d081a201641e0006a200241f8006a418401109d081a200241003602542002201636025020162f010622144103742113417f2100024002400340024020132001470d00201421000c020b200241206a201620016a41086a410810a008220a450d02200141086a2101200041016a2100200a417f4a0d000b0b200242f5dc8de3d6ec9c983037028c012002200c3602880120022000360284012002201636027c200241003602782002200241d0006a36028001410110332201450d0c200141003a000020024190026a200241e0006a10b40320022802900221160240024020022802980222000d0041012113200041016a210a0c010b200041016a220a2000490d0a200a4102200a41024b1b22134100480d0a20014101201310372201450d0d0b200141016a20162000109d081a0240200228029402450d00201610350b2002200a3602880220022013360284022002200136028002200241f8006a20024180026a10820320024180023b015c200241206a41086a200241d0006a41086a290300370300200220022903503703200c050b41f5c6ca002101412d21000b2002200036027c200220013602784181c6ca004122200241f8006a41a4c6ca0041b4c6ca001046000b201041c8036a2210200b470d000b0b200241206a41086a200241d0006a41086a290300370300200220022903503703200b200241c0006a10a00202402007450d00200741246c21002003210103400240024020012d0000220a41044b0d00024002400240200a0e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b02402008450d00200841246c450d00200310350b02402004450d00200441c8036c210020064198016a21010340200110bb02200141c8036a2101200041b87c6a22000d000b0b02402005450d00200541c8036c450d00200610350b200241003602682002420137036020022d002c2100410110332201450d062002410136026420022001360260200120003a00002002410136026820022d002d210020014101410210372201450d062002410236026420022001360260200120003a00012002410236026820022802282200200241e0006a1077024020022802202201450d00024020022802242216450d002016210a20012113034020132802e4012113200a417f6a220a0d000b2001210a0340200a200a2f01064102746a41e4016a280200210a2016417f6a22160d000b200241f8006a2116201321010c030b200241f8006a21162001210a0c020b410021012002410036027c200241f8006a21160c020b200241ec006a4104360200200241a4026a41023602002002420237029402200241f0b2c300360290022002410436026420024184b4c30036026020024100360254200241b0b4cc003602502002200241e0006a3602a0022002200241d0006a36026820024190026a4180b3c300104c000b2002200a36027c20024184016a200a2f01063602002002410036028001200241003602780b20024190026a41086a201641086a29020022093703002002201629020022173703900220024190016a200937030020024200370380012002200136027c20024100360278200220173703880120022000360298012000450d01034020022000417f6a36029801200241f8006a410020011b2213280200210a20132802082114024002400240201328020c2216201328020422002f01064f0d00200021010c010b0240034020002802002201450d01200a41016a210a20002f0104211620012100201620012f0106490d020c000b0b2014ad2109410021010c010b2016ad4220862014ad8421090b2009422088a7221441016a21162009a7211802400240200a0d00200121000c010b200120164102746a41e4016a280200210041002116200a417f6a220a450d00034020002802e4012100200a417f6a220a0d000b0b2013201636020c2013201836020820132000360204201341003602000240024020022802642216200228026822006b4108490d002002280260210a0c010b200041086a220a2000490d0220164101742213200a2013200a4b1b22134100480d020240024020160d00024020130d004101210a0c020b20131033220a0d010c070b2002280260210a20162013460d00200a201620131037220a450d060b200220133602642002200a3602600b200a20006a200120144103746a41086a2900003700002002200041086a360268200141e0006a2014410c6c6a2201280200211320012802082201200241e0006a10770240024020022802642216200228026822006b2001490d002002280260210a0c010b200020016a220a2000490d0220164101742214200a2014200a4b1b22144100480d020240024020160d00024020140d004101210a0c020b20141033220a450d070c010b2002280260210a20162014460d00200a201620141037220a450d060b200220143602642002200a3602600b200a20006a20132001109d081a2002200020016a22013602682002280298012200450d03200228027c21010c000b0b103e000b200228026821012002280260210a0b200241206a10a002200241f0026a24002001ad422086200aad840f0b103c000bac0401057f024002400240200241046a2203417f4c0d0002400240024002400240024002400240024002402003450d00200310332204450d0b200241c000490d04200241808001490d052002418080808004490d0620030d010b41012103410110332204450d07200441033a0000410521050c010b200441033a000002402003417f6a41034d0d00200321050c020b200341017422064105200641054b1b22054100480d0720032005460d010b20042003200510372204450d050b20042002360001410521060c030b024020030d0041012103410110332204450d040b200420024102743a000041012106200321050c020b02400240200341014d0d00200321050c010b200341017422064102200641024b1b2105024020030d002005103322040d010c040b20032005460d0020042003200510372204450d030b41022106200420024102744101723b00000c010b02400240200341034d0d00200321050c010b200341017422064104200641044b1b22054100480d03024020030d002005103322040d010c030b20032005460d0020042003200510372204450d020b20042002410274410272360000410421060b0240200520066b2002490d00200521030c050b200620026a22032006490d01200541017422072003200720034b1b22034100480d0120052003460d04200420052003103722040d040b103c000b103e000b1044000b1045000b200420066a20012002109d081a2000200620026a36020820002003360204200020043602000bbf0101067f230041206b22022400200241b0b4cc00410010d50302400240412010332203450d0020032002290300370000200341186a2204200241186a290300370000200341106a2205200241106a290300370000200341086a2206200241086a290300370000412010332207450d0120072003290000370000200741186a2004290000370000200741106a2005290000370000200741086a200629000037000020031035200241206a24002007ad42808080808004840f0b1045000b103c000be51b06037f017e077f017e277f027e230041a00d6b220324002003200236020c20032001360208200341206a41186a22044200370300200341206a41106a22024200370300200341206a41086a220142003703002003420037032041d1c4c700ad4280808080e000841001220529000021062001200541086a290000370300200320063703202005103541e7c4c700ad4280808080e00084100122072900002106200341106a41086a2205200741086a2900003703002003200637031020071035200220032903102206370300200341800d6a41086a22082001290300370300200341800d6a41106a22092006370300200341800d6a41186a220a2005290300370300200320032903203703800d2003200341800d6a412010c0012003280204210b2003280200210c200442003703002002420037030020014200370300200342003703204182e9ca00ad42808080808003841001220729000021062001200741086a2900003703002003200637032020071035419ae9ca00ad4280808080e001841001220729000021062005200741086a29000037030020032006370310200710352002200329031022063703002008200129030037030020092006370300200a2005290300370300200320032903203703800d200341206a200341800d6a412010b50220032802202201410120011b210d0240024002402003290224420020011b220e422088a722020d0020004200370000200041186a4200370000200041106a4200370000200041086a42003700000c010b200341206a410041e00c109f081a200b417f6a41d100704130200c1b2101200d41206a210f200d20024105746a21104100211141002112410021134100211441002115410021164100211741002118410021194100211a4100211b4100211c4100211d4100211e4100211f410021204100212141002122410021234100212441002125410021264100212741002128410021294100212a4100212b4100212c4100212d4100212e4100212f4100210b200d21024100213041d1002131024003402030210720022105024002402001450d00200141016a2101200521020340024020102002470d00200d21020b2002220541206a21022001417f6a22010d000b20050d010c030b024020052010460d00200541206a21020c010b200f2102200d21050b0240024002400240200328020c220141056a2204417f4c0d00200328020821320240024020040d00410021044101210c0c010b20041033220c450d020b200341003602182003200c36021020032004360214024020040d0041011033220c450d08200341013602142003200c3602100b200c20073a0000200341013602182001200341106a10770240024020032802142233200328021822306b2001490d00200328021021042033210c0c010b203020016a22042030490d032033410174220c2004200c20044b1b220c4100480d030240024020330d000240200c0d00410121040c020b200c103322040d010c0a0b200328021021042033200c460d0020042033200c10372204450d090b2003200c360214200320043602100b200420306a20322001109d081a2003203020016a2230360218412010332201450d0120012005290000370000200141186a2232200541186a290000370000200141106a2234200541106a290000370000200141086a2235200541086a29000037000002400240200c20306b411f4d0d00200c21330c010b203041206a22052030490d03200c41017422332005203320054b1b22334100480d0302400240200c0d00024020330d00410121040c020b203310332204450d0a0c010b200c2033460d002004200c203310372204450d090b20032033360214200320043602100b200420306a22052001290000370000200541186a2032290000370000200541106a2034290000370000200541086a20352900003700002003203041206a2205360218200110352005ad4220862004ad84100922012900002106200141086a2900002136200141106a2900002137200a200141186a2900003703002009203737030020082036370300200320063703800d2001103502402033450d00200410350b2031417f6a2131200741016a2130200341206a20074103704105746a220120032903800d370000200141186a200a290300370000200141106a2009290300370000200141086a20082903003700004100210503402007200741036e2204417d6c6a4102470d04200341206a20056a220141df006a2d0000220b2001411f6a2d0000220c71200b200c722001413f6a2d000071722128200141de006a2d0000220b2001411e6a2d0000220c71200b200c722001413e6a2d000071722127200141dd006a2d0000220b2001411d6a2d0000220c71200b200c722001413d6a2d000071722126200141dc006a2d0000220b2001411c6a2d0000220c71200b200c722001413c6a2d000071722125200141db006a2d0000220b2001411b6a2d0000220c71200b200c722001413b6a2d000071722124200141da006a2d0000220b2001411a6a2d0000220c71200b200c722001413a6a2d000071722123200141d9006a2d0000220b200141196a2d0000220c71200b200c72200141396a2d000071722122200141d8006a2d0000220b200141186a2d0000220c71200b200c72200141386a2d000071722121200141d7006a2d0000220b200141176a2d0000220c71200b200c72200141376a2d000071722120200141d6006a2d0000220b200141166a2d0000220c71200b200c72200141366a2d00007172211f200141d5006a2d0000220b200141156a2d0000220c71200b200c72200141356a2d00007172211e200141d4006a2d0000220b200141146a2d0000220c71200b200c72200141346a2d00007172211d200141d3006a2d0000220b200141136a2d0000220c71200b200c72200141336a2d00007172211c200141d2006a2d0000220b200141126a2d0000220c71200b200c72200141326a2d00007172211b200141d1006a2d0000220b200141116a2d0000220c71200b200c72200141316a2d00007172211a200141d0006a2d0000220b200141106a2d0000220c71200b200c72200141306a2d000071722119200141cf006a2d0000220b2001410f6a2d0000220c71200b200c722001412f6a2d000071722118200141ce006a2d0000220b2001410e6a2d0000220c71200b200c722001412e6a2d000071722117200141cd006a2d0000220b2001410d6a2d0000220c71200b200c722001412d6a2d000071722116200141cc006a2d0000220b2001410c6a2d0000220c71200b200c722001412c6a2d000071722115200141cb006a2d0000220b2001410b6a2d0000220c71200b200c722001412b6a2d000071722114200141ca006a2d0000220b2001410a6a2d0000220c71200b200c722001412a6a2d000071722113200141c9006a2d0000220b200141096a2d0000220c71200b200c72200141296a2d000071722112200141c8006a2d0000220b200141086a2d0000220c71200b200c72200141286a2d000071722111200141c7006a2d0000220b200141076a2d0000220c71200b200c72200141276a2d000071722129200141c6006a2d0000220b200141066a2d0000220c71200b200c72200141266a2d00007172212a200141c5006a2d0000220b200141056a2d0000220c71200b200c72200141256a2d00007172212b200141c4006a2d0000220b200141046a2d0000220c71200b200c72200141246a2d00007172212c200141c3006a2d0000220b200141036a2d0000220c71200b200c72200141236a2d00007172212d200141c2006a2d0000220b200141026a2d0000220c71200b200c72200141226a2d00007172212e200141c1006a2d0000220b200141016a2d0000220c71200b200c72200141216a2d00007172212f200141c0006a2d0000220b20012d0000220c71200b200c72200141206a2d00007172210b200541800c460d04200341206a20052004410574200741096e41e0006c6b6a6a220141ff006a20283a0000200141fe006a20273a0000200141fd006a20263a0000200141fc006a20253a0000200141fb006a20243a0000200141fa006a20233a0000200141f9006a20223a0000200141f8006a20213a0000200141f7006a20203a0000200141f6006a201f3a0000200141f5006a201e3a0000200141f4006a201d3a0000200141f3006a201c3a0000200141f2006a201b3a0000200141f1006a201a3a0000200141f0006a20193a0000200141ef006a20183a0000200141ee006a20173a0000200141ed006a20163a0000200141ec006a20153a0000200141eb006a20143a0000200141ea006a20133a0000200141e9006a20123a0000200141e8006a20113a0000200141e7006a20293a0000200141e6006a202a3a0000200141e5006a202b3a0000200141e4006a202c3a0000200141e3006a202d3a0000200141e2006a202e3a0000200141e1006a202f3a0000200141e0006a200b3a000020042107200541e0006a220541e00c470d000c040b0b1044000b1045000b103e000b4100210120310d000b0b200020283a001f200020273a001e200020263a001d200020253a001c200020243a001b200020233a001a200020223a0019200020213a0018200020203a00172000201f3a00162000201e3a00152000201d3a00142000201c3a00132000201b3a00122000201a3a0011200020193a0010200020183a000f200020173a000e200020163a000d200020153a000c200020143a000b200020133a000a200020123a0009200020113a0008200020293a00072000202a3a00062000202b3a00052000202c3a00042000202d3a00032000202e3a00022000202f3a00012000200b3a00000b0240200e42ffffff3f83500d00200d10350b200341a00d6a24000f0b103c000b925303097f087e047f230041a0136b220224000240024020010d0020022001360254200241b0b4cc003602500c010b2002200136025420022001417f6a360254200220003602502002200041016a36025020002d0000220341034f0d00200241a80b6a200241d0006a10c80302400240024002400240024002400240024020022903900c4203510d0020024190016a200241a80b6a41c803109d081a200241d8046a20024190016a41c803109d081a2002200241d8046a3602a008200241a80b6a200241a0086a10b90320022802b00b2100024020022802ac0b450d0020022802a80b10350b200241a80b6a200241d8046a41c803109d081a200241a0086a200241a80b6a10d70341012101024020022d00a0084101460d00200241a80b6a200241a0086a41086a2201418003109d081a200241f00e6a200241f80b6a220410d8030240024020022903c80b4202520d00200241800f6a41206a22014200370300200241800f6a41186a22054280808080c000370300200241013a00a80f200242043703900f2002427f3703880f200242003703800f200241a0086a41206a22064200370300200241a0086a41186a22074280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a008200241e0106a200241800f6a200241a0086a10d903200241800f6a41286a2208200241e0106a41286a2903003703002001200241e0106a41206a2903003703002005200241e0106a41186a290300370300200241800f6a41106a2209200241e0106a41106a290300370300200241800f6a41086a220a200241e0106a41086a290300370300200220022903e0103703800f2006420037030020074280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a00820024190116a200241800f6a200241a0086a10d903200820024190116a41286a290300370300200120024190116a41206a290300370300200520024190116a41186a290300370300200920024190116a41106a290300370300200a20024190116a41086a29030037030020022002290390113703800f2006420037030020074280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a008200241c0116a200241800f6a200241a0086a10d9032008200241c0116a41286a2903003703002001200241c0116a41206a2903003703002005200241c0116a41186a2903003703002009200241c0116a41106a290300370300200a200241c0116a41086a290300370300200220022903c0113703800f2006420037030020074280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a008200241f0116a200241800f6a200241a0086a10d9032008200241f0116a41286a2903003703002001200241f0116a41206a2903003703002005200241f0116a41186a2903003703002009200241f0116a41106a290300370300200a200241f0116a41086a290300370300200220022903f0113703800f20022903f00e210b200241d0126a20022d00f80e2201200010da03024002400240024020022903d012220ca741ff01714101460d00200241e00f6a41186a4200370300200241e00f6a41106a22064200370300200241e00f6a41086a22004200370300200242003703e00f41d1c4c700ad4280808080e0008410012205290000210c2000200541086a2900003703002002200c3703e00f200510354184eec700ad4280808080b0028410012205290000210c20024188136a41086a2207200541086a2900003703002002200c37038813200510352006200229038813220c370300200241c00f6a41086a2000290300370300200241c00f6a41106a200c370300200241c00f6a41186a2007290300370300200220022903e00f3703c00f2002200241c00f6a10e102200228020021002002290308210d02400240200141024b0d004280b0def7d32b210c20010e03010004010b4280c0a8ca9a3a210c0b41800c2105200b42c0b2cd3b7c220e200b540d01200d420020001b220d200e7c220e200d540d01200e200c560d014200210c20024181136a21000240024020010e03000105000b200b210c0c040b427f210c0c030b200c420888a721050b20022802900f21060240200241980f6a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241940f6a2802002200450d002000410c6c450d00200610350b200228029c0f21060240200241a40f6a2802002200450d002000410c6c21012006210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241a00f6a2802002200450d002000410c6c450d00200610350b41010d030c080b4200210c20024181136a21000b200241a0086a41206a22014200370300200241a0086a41186a22054280808080c000370300200220002800003602b80f2002200041036a2800003600bb0f200241cc086a20022800bb0f360000200241013a00c808200242043703b0082002427f3703a8082002200c3703a008200220022802b80f3600c908200241a0126a200241800f6a200241a0086a10d903200241800f6a41286a200241a0126a41286a290300370300200241800f6a41206a200241a0126a41206a290300370300200241800f6a41186a200241a0126a41186a290300370300200241800f6a41106a200241a0126a41106a290300370300200241800f6a41086a200241a0126a41086a290300370300200220022903a0123703800f2001420037030020054280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a008200241d0126a200241800f6a200241a0086a10d903200241bc106a200241d0126a41086a290300370200200220022903d0123702b41041000d01200241e4126a2802002105200241d0126a41186a2802002101200241d0126a41206a2802002106200241f4126a280200210720022802e012210820022802ec12210920022903f812210b0c060b200241800f6a41206a22034200370300200241800f6a41186a22064280808080c000370300200241013a00a80f200242043703900f427f210b2002427f3703880f200242003703800f200241a0086a41206a22074200370300200241a0086a41186a22054280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a00820024180106a200241800f6a200241a0086a10d903200241800f6a41286a220820024180106a41286a290300370300200320024180106a41206a290300370300200620024180106a41186a290300370300200241800f6a41106a220920024180106a41106a290300370300200241800f6a41086a220a20024180106a41086a29030037030020022002290380103703800f2007420037030020054280808080c000370300200241013a00c808200242043703b0082002427f3703a808200242003703a008200241b0106a200241800f6a200241a0086a10d9032008200241b0106a41286a2903003703002003200241b0106a41206a2903003703002006200241b0106a41186a2903003703002009200241b0106a41106a290300370300200a200241b0106a41086a290300370300200220022903b0103703800f20054200370300200241a0086a41106a2206420037030020014200370300200242003703a00841d1c4c700ad4280808080e0008410012203290000210c2001200341086a2900003703002002200c3703a0082003103541e7c4c700ad4280808080e0008410012203290000210c200241a0126a41086a2208200341086a2900003703002002200c3703a01220031035200620022903a012220c370300200241d0126a41086a2001290300370300200241d0126a41106a2201200c370300200241d0126a41186a22032008290300370300200220022903a0083703d012200241c8006a200241d0126a412010c001200228024c410020022802481bad210c024020022903c80b4201520d0020022903d00b220b4200510d04200c200241d80b6a290300220d200d200c541b220e200b7c200e200d7d200b827d210b0b2007420037030020054280808080c000370300200241013a00c808200242043703b008200242003703a00820024200200b200c7d220c200c200b561b3703a808200241e0106a200241800f6a200241a0086a10d903200241d0126a41286a200241e0106a41286a290300370300200241d0126a41206a200241e0106a41206a2903003703002003200241e0106a41186a2903003703002001200241e0106a41106a290300370300200241d0126a41086a200241e0106a41086a290300370300200220022903e0103703d01220022903f00e210b20022802e00b2101200241a0126a200241a80b6a108e02200241a0086a20022802a012220520022802a812108f02200241e8086a280200410020022903a0084201511b2103024020022802a412450d00200510350b024002400240200320014b0d00410c10332206450d0d410410332205450d0b20054104412010372205450d0d200520022903a80b370000200541186a200241a80b6a41186a290300370000200541106a200241a80b6a41106a290300370000200541086a200241a80b6a41086a2903003700002005412041c00010372205450d0d20052001360020200642c0808080c004370204200620053602000240024020032001490d0041002101410421050c010b410c10332205450d0e410410332203450d0c20034104412010372203450d0e200320022903a80b370000200341186a200241a80b6a41186a290300370000200341106a200241a80b6a41106a290300370000200341086a200241a80b6a41086a2903003700002003412041c00010372203450d0e20032001417f6a360020200542c0808080c00437020420052003360200410121010b200241800f6a41206a2203428180808010370300200241800f6a41186a22072001360200200241940f6a2001360200200220022800f0113602e00f2002200241f0116a41036a2800003600e30f200241ac0f6a20022800e30f360000200241013a00a80f2002200636029c0f200220053602900f2002427f3703880f2002200b3703800f200220022802e00f3600a90f20024190116a200241d0126a200241800f6a10d903200241800f6a41286a20024190116a41286a290300370300200320024190116a41206a290300370300200720024190116a41186a290300370300200241800f6a41106a20024190116a41106a290300370300200241800f6a41086a20024190116a41086a29030037030020022002290390113703800f4180122101024020022d00f80e22054102460d00200241d0126a2005200010da03024020022903d012220ca741ff01714101460d00200241e00f6a41186a4200370300200241e00f6a41106a22064200370300200241e00f6a41086a22014200370300200242003703e00f41d1c4c700ad4280808080e0008410012203290000210c2001200341086a2900003703002002200c3703e00f200310354184eec700ad4280808080b0028410012203290000210c20024188136a41086a2207200341086a2900003703002002200c37038813200310352006200229038813220c370300200241c00f6a41086a2001290300370300200241c00f6a41106a200c370300200241c00f6a41186a2007290300370300200220022903e00f3703c00f200241386a200241c00f6a10e1020240200b42c0b2cd3b7c220c200b540d00200229034042002002290338a71b220d200c7c220c200d5a0d040b20022002280081133602b80f200220024184136a2800003600bb0f41800c21010c040b200c420888a721010b20022002280081133602b80f200220024181136a41036a2800003600bb0f0c020b200220022800f0113602e00f2002200241f3116a2800003600e30f200241003a005b20024180063b0059200241013a005820022802e01221050240200241e8126a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241e4126a2802002200450d002000410c6c450d00200510350b20022802ec1221050240200241f4126a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b200241f0126a2802002200450d082000410c6c450d08200510350c080b20022002280081133602b80f200220024184136a2800003600bb0f41800c2101200c4280c0a8ca9a3a4280b0def7d32b20051b580d050b200241013a0058200220013b0059200220014110763a005b20022802900f21050240200241980f6a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241940f6a2802002200450d002000410c6c450d00200510350b200228029c0f21050240200241a40f6a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b200241a00f6a2802002200450d062000410c6c450d06200510350c060b200241013a0058200220053b0059200220054110763a005b0c050b200220022d00a3083a005b200220022f00a1083b0059200241013a00580c050b2002419c016a4104360200200241ec046a4102360200200242023702dc04200241f0b2c3003602d80420024104360294012002419cb4c30036029001200241003602a408200241b0b4cc003602a008200220024190016a3602e8042002200241a0086a36029801200241d8046a4180b3c300104c000b41809ccc004119419c9ccc00103f000b200241a0086a41206a4200370300200241a0086a41186a4280808080c000370300200241a0086a412c6a20022800bb0f360000200241013a00c808200242043703b0082002427f3703a8082002427f200b20051b3703a008200220022802b80f3600c908200241c0116a200241800f6a200241a0086a10d903200241a0126a41286a200241c0116a41286a290300370300200241a0126a41206a200241c0116a41206a290300370300200241a0126a41186a200241c0116a41186a290300370300200241a0126a41106a200241c0116a41106a290300370300200241a0126a41086a200241c0116a41086a290300370300200220022903c0113703a012200241286a2000200b20022d00f90e20022903e80b220d200241f00b6a290300220e10db03024002402002290328220b200241286a41086a290300220c84500d0041002100200241003a00b80f2002200c3703e80f2002200b3703e00f200241014111200d200e84501b3a009f132002200241a80b6a360288132002200241a80b6a3602c00f2002200241c00f6a3602b00820022002419f136a3602ac08200220024188136a3602a8082002200241b80f6a3602a4082002200241e00f6a3602a008200241800f6a200241a80b6a200241a0086a10dc030240024020022802800f4101470d004200210e20022903880f210d410121000c010b200241a80f6a290300210e200241a00f6a290300210d20022903880f4201520d00200241800f6a41106a290300210f20022802c00f2101200241d8086a200241800f6a41186a290300370300200241d0086a200f37030041002100200241a0086a41086a41003a0000200241a9086a2001290000370000200241b1086a200141086a290000370000200241b9086a200141106a290000370000200241c1086a200141186a290000370000200241033a00a00841b0b4cc004100200241a0086a10d4010b20000d01200241e00f6a41186a22064200370300200241e00f6a41106a22054200370300200241e00f6a41086a22014200370300200242003703e00f41b6fdc600ad4280808080800184220f10012203290000211020024188136a41086a2200200341086a2900003703002002201037038813200310352001200029030037030020022002290388133703e00f41e489c200ad4280808080d0018422101001220329000021112000200341086a29000037030020022011370388132003103520052002290388132211370300200241c00f6a41086a22072001290300370300200241c00f6a41106a22082011370300200241c00f6a41186a22092000290300370300200220022903e00f3703c00f200241106a200241c00f6a412010d701200241106a41106a29030021112002290318211220022802102103200642003703002005420037030020014200370300200242003703e00f200f10012206290000210f2000200641086a2900003703002002200f37038813200610352001200029030037030020022002290388133703e00f201010012206290000210f2000200641086a2900003703002002200f37038813200610352005200229038813220f370300200720012903003703002008200f37030020092000290300370300200220022903e00f3703c00f200242002011420020031b220f200e7d2012420020031b220e200d54ad7d2210200e200d7d220d200e562010200f562010200f511b22001b3703a80820024200200d20001b3703a008200241c00f6aad4280808080800484200241a0086aad428080808080028410020b200241d0126a41206a4200370300200241d0126a41186a4280808080c000370300200241d0126a412c6a20024184136a280000360000200241013a00f812200242043703e01220022002280081133600f9122002427f3703d8122002200b427f200c501b3703d012200241f0116a200241a0126a200241d0126a10d903200241d8006a41086a20022903f011370300200241d8006a41106a200241f0116a41086a290300370300200241d8006a41186a200241f0116a41106a290300370300200241d8006a41206a200241f0116a41186a290300370300200241d8006a41286a200241f0116a41206a29030037030020024188016a200241f0116a41286a290300370300200241003a00580c020b200241003a005b20024180023b0059200241013a005820022802b01221050240200241b8126a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241b4126a2802002200450d002000410c6c450d00200510350b20022802bc1221050240200241c4126a2802002200450d002000410c6c21012005210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b200241c0126a2802002200450d012000410c6c450d01200510350c010b20024188106a200241b0106a410c6a290200370300200220022902b4103703801002400240024020022802f80b41796a2200410c4b0d000240024020000e0d00020202020202020202020201000b0240200241800c6a2d00004118460d0041002100200241003a00830f200241003b00810f200241013a00800f0c030b024020034102490d0041002100200241003a00830f200241003b00810f200241013a00800f0c030b200241a0086a41286a200241d80d6a220041286a290300370300200241a0086a41206a2203200041206a290300370300200241a0086a41186a220a200041186a290300370300200241a0086a41106a200041106a290300370300200241a0086a41086a200041086a290300370300200220002903003703a00841808eec00210002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200241a0086a20022802d00d10f101411f71417f6a0e1d0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c00010b200241d4086a410f36020020034200370300200a4280808080c000370300200241bdb5c0003602d008200241013a00c808200242043703b0082002427f3703a8082002427f20022903d80d427f200241e00d6a290300501b220c42ffffffffffffffffff007c220d200d200c541b3703a008411710332200450d22200242173702d412200220003602d012410f200241d0126a10770240024020022802d412221320022802d81222146b410f490d002014410f6a210020022802d01221032013210a0c010b2014410f6a22002014490d24201341017422032000200320004b1b220a4100480d240240024020130d000240200a0d00410121030c020b200a103322030d010c270b20022802d01221032013200a460d0020032013200a10372203450d260b2002200a3602d412200220033602d0120b200320146a221441002900bdb540370000201441076a41002900c4b540370000200220003602d81220022802d00d21140240200a20006b41034b0d00200041046a22132000490d24200a41017422152013201520134b1b22134100480d2402400240200a0d00024020130d00410121030c020b201310332203450d270c010b200a2013460d002003200a201310372203450d260b200220133602d412200220033602d0120b200241c9086a210a200320006a2014360000200041046a210320022802d012211420022802d4122113024020022802c408220020022802c008470d00200241bc086a2000410110870120022802c40821000b20022802bc082000410c6c6a220020033602082000201336020420002014360200200241d8126a2200200241a0086a41186a290300370300200220022802c40841016a3602c408200241d0126a41106a2203200241a0086a41206a290300370300200241800f6a41106a4232370300200220022903b0083703d0122002200a2900003703f0112002200a41076a2900003700f711200220022903a0083703880f200241800f6a41186a20022903d012370300200241800f6a41206a2000290300370300200241a80f6a2003290300370300200241b00f6a41003a0000200241b40f6a20022800f311360000200241b10f6a20022802f011360000200241003a00800f0c1f0b41800e21000c1a0b41808e0421000c190b41808e0821000c180b41808e0c21000c170b41808e1021000c160b41808e1421000c150b41808e1821000c140b41808e1c21000c130b41808e2021000c120b41808e2421000c110b41808e2821000c100b41808e2c21000c0f0b41808e3021000c0e0b41808e3421000c0d0b41808e3821000c0c0b41808e3c21000c0b0b41808ec00021000c0a0b41808ec40021000c090b41808ec80021000c080b41808ecc0021000c070b41808ed00021000c060b41808ed40021000c050b41808ed80021000c040b41808edc0021000c030b41808ee00021000c020b41808ee40021000c010b41808ee80021000b200241013a00800f200220003b00810f200220004110763a00830f0c020b200241800f6a200241fc0b6a10dd0320022d00800f4101470d0220022f00810f20022d00830f4110747221000c010b200241003a00830f418102210020024181023b00810f200241013a00800f0b200241013a0058200220003b0059200220004110763a005b02402001450d002001410c6c21012008210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b02402005450d002005410c6c450d00200810350b02402007450d002007410c6c21012009210003400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b2006450d012006410c6c450d01200910350c010b200241a0126a41286a2200200241800f6a41306a290300370300200241a0126a41206a2203200241800f6a41286a290300370300200241a0126a41186a220a200241800f6a41206a2214290300370300200241a0126a41106a2213200241800f6a41186a2215290300370300200241a0126a41086a2216200241800f6a41106a290300370300200220022903880f3703a012200241800f6a41086a20024180106a41086a290300370300200241a40f6a20073602002014200636020020152001360200200241940f6a200536020020022002290380103703800f2002200b3703a80f2002200936029c0f200220083602900f200241a0086a41286a2000290300370300200241a0086a41206a2003290300370300200241a0086a41186a200a290300370300200241a0086a41106a2013290300370300200241a0086a41086a2016290300370300200220022903a0123703a008200241d0126a200241800f6a200241a0086a10d903200241d8006a41086a20022903d012370300200241d8006a41106a200241d0126a41086a290300370300200241d8006a41186a200241d0126a41106a290300370300200241d8006a41206a200241d0126a41186a290300370300200241d8006a41286a200241d0126a41206a290300370300200241d8006a41306a200241d0126a41286a290300370300200241003a00580b200410ba0220022d005821010b410110332200450d00200242013702ac0b200220003602a80b02400240200141ff01714101470d00200041013a0000200241013602b00b200241d8006a410172200241a80b6a10c90320022802b00b21000c010b200041003a0000200241013602b00b200241e0006a290300210b024020022802ac0b2201417f6a41074b0d00200141017422054109200541094b1b22054100480d03024020012005460d0020002001200510372200450d050b200220053602ac0b200220003602a80b0b2000200b370001200241093602b00b200241f0006a2802002101200241f8006a2802002200200241a80b6a107702402000450d0020012000410c6c6a2108034020012802002106200141086a2802002200200241a80b6a10770240024020022802ac0b220420022802b00b22056b2000490d0020022802a80b21030c010b200520006a22032005490d05200441017422072003200720034b1b22074100480d050240024020040d00024020070d00410121030c020b200710332203450d080c010b20022802a80b210320042007460d0020032004200710372203450d070b200220073602ac0b200220033602a80b0b200320056a20062000109d081a2002200520006a3602b00b2001410c6a22012008470d000b0b200241fc006a280200210120024184016a2802002200200241a80b6a10770240024020000d0020022802ac0b210620022802b00b21000c010b20012000410c6c6a2108034020012802002107200141086a2802002200200241a80b6a10770240024020022802ac0b220320022802b00b22056b2000490d0020022802a80b2104200321060c010b200520006a22042005490d05200341017422062004200620044b1b22064100480d050240024020030d00024020060d00410121040c020b200610332204450d080c010b20022802a80b210420032006460d0020042003200610372204450d070b200220063602ac0b200220043602a80b0b200420056a20072000109d081a2002200520006a22003602b00b2001410c6a22012008470d000b0b200241e8006a290300210b02400240200620006b4108490d0020022802a80b2105200621010c010b200041086a22012000490d03200641017422052001200520014b1b22014100480d030240024020060d00024020010d00410121050c020b200110332205450d060c010b20022802a80b210520062001460d0020052006200110372205450d050b200220013602ac0b200220053602a80b0b200520006a200b3700002002200041086a22003602b00b20024188016a2d000021030240024020012000460d00200021010c010b200141016a22002001490d03200141017422042000200420004b1b22004100480d030240024020010d0041002101024020000d00410121050c020b200010332205450d060c010b20012000460d0020052001200010372205450d050b200220003602ac0b200220053602a80b0b200520016a20033a00002002200141016a22003602b00b0b2000ad42208620023502a80b84210b024020022d00580d000240200241f8006a2802002201450d00200241f0006a28020021002001410c6c210103400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b0240200241f4006a2802002200450d002000410c6c450d00200228027010350b024020024184016a2802002201450d00200241fc006a28020021002001410c6c210103400240200041046a280200450d00200028020010350b2000410c6a2100200141746a22010d000b0b20024180016a2802002200450d002000410c6c450d00200228027c10350b200241a0136a2400200b0f0b1045000b103e000b103c000b200241e4046a4104360200200241bc0b6a4102360200200242023702ac0b200241f0b2c3003602a80b200241043602dc042002419cb4c3003602d8042002410036029401200241b0b4cc00360290012002200241d8046a3602b80b200220024190016a3602e004200241a80b6a4180b3c300104c000be82307017f027e027f017e077f017e017f230041a0116b22022400420221030240024002400240024002400240024002400240200129036822044202520d00200241186a20014198016a41b002109d081a0c010b20024196036a200141246a41c200109d081a200241d8036a41086a220520014188016a290300370300200241d8036a41106a220620014190016a290300370300200220014180016a2903003703d803200141f8006a29030021032001290370210720024190046a41206a200141206a28020036020020024190046a41186a200141186a29020037030020024190046a41106a200141106a29020037030020024190046a41086a200141086a2902003703002002200129020037039004200241c80a6a20024190046a108b0220024190086a41086a2208200241d10a6a29000037030020024190086a41106a2209200241d90a6a29000037030020024190086a41186a220a200241c80a6a41196a290000370300200220022900c90a3703900820022d00c80a4101460d02200241f0036a41186a200a290300370300200241f0036a41106a2009290300370300200241f0036a41086a200829030037030020022002290390083703f003200241800d6a20014198016a41b002109d081a200241b00f6a41106a2006290300370300200241b00f6a41086a2005290300370300200220022903d8033703b00f4100210520024190116a410010b803200241e8106a200228029011220120022802981110d501200241c8106a41086a200241f4106a290200370300200241c8106a41106a200241fc106a290200370300200241dd106a2206200241e8106a41196a290000370000200220022902ec103703c8100240024020022d00e8104101460d00200241c0106a4200370300200241b8106a4200370300200241b0106a4200370300200242003703a8100c010b20022d00eb10210520022f00e9102108200241b3106a200241d0106a290300370000200241bb106a200241c8106a41106a290300370000200241c0106a2006290000370000200220022903c8103700ab102002200820054110747222053b01a810200220054110763a00aa100b0240200228029411450d00200110350b20024188106a41086a200241b3106a220629000037030020024188106a41106a200241bb106a220829000037030020024188106a41156a200241c0106a2209290000370000200220022900ab1037038810200241c8106a41156a220a4200370000200241c8106a41106a220b4200370300200241c8106a41086a220c4200370300200242003703c81041d1c4c700ad4280808080e00084100122012f0000210d200141026a2d0000210e2002200141086a2900003700ed10200220012900033703e81020011035200220022900ed103700cd10200220022903e8103703c81041e7c4c700ad4280808080e0008410012201290000210f200241e8106a41086a2210200141086a2900003703002002200f3703e81020011035200a2010290300220f3700002009200f370000200220022903e8103700d5102006200c2903003700002008200b2903003700002002200e3a00aa102002200d3b01a810200220022903c8103700ab10200241106a200241a8106a412010c00141002101024020044201520d0020074200510d052002280214410020022802101b2106417f21012006ad220f20032003200f541b220f200f20037d2007827d220f42ffffffff0f560d00200fa721010b200241e8106a200110b803200241086a20022802e810220620022802f01041b0b4cc0041004100108a0220022802082108024020022802ec10450d00200610350b41012106024002400240024020084101470d0020024190116a200110b803200241e8106a200228029011220620022802981110d501200241c8106a41086a2208200241f4106a290200370300200241c8106a41106a2209200241fc106a290200370300200241c8106a41156a220a20024181116a290000370000200220022902ec103703c81020022d00e8104101460d01200241a8106a41156a4200370000200241a8106a41106a4200370300200241a8106a41086a4200370300200242003703a810410021010c020b0c020b20022f00e91020022d00eb10411074722101200241a8106a41156a200a290000370000200241a8106a41106a2009290300370300200241a8106a41086a2008290300370300200220022903c8103703a8100b0240200228029411450d00200610350b200241c8106a41086a200241a8106a41086a290300370300200241c8106a41106a200241a8106a41106a290300370300200241c8106a41156a200241a8106a41156a290000370000200241e8106a41086a20024188106a41086a290300370300200241e8106a41106a20024188106a41106a290300370300200241e8106a41156a20024188106a41156a290000370000200220022903a8103703c81020022002290388103703e810410021060b200241e80f6a41156a2208200241e8106a41156a290000370000200241e80f6a41106a2209200241e8106a41106a290300370300200241e80f6a41086a220a200241e8106a41086a290300370300200241c80f6a41086a220b200241c8106a41086a290300370300200241c80f6a41106a220c200241c8106a41106a290300370300200241c80f6a41156a220d200241c8106a41156a290000370000200220022903e8103703e80f200220022903c8103703c80f20060d01200241d8076a41156a22062008290000370000200241d8076a41106a22082009290300370300200241d8076a41086a2209200a290300370300200241b8076a41086a220a200b290300370300200241b8076a41106a220b200c290300370300200241b8076a41156a220c200d290000370000200220022903e80f3703d807200220022903c80f3703b807200241f8076a41106a220d200241b00f6a41106a290300370300200241f8076a41086a220e200241b00f6a41086a290300370300200220022903b00f3703f807200241c80a6a41046a200241800d6a41b002109d081a20024190086a200241c80a6a41b402109d081a20024190046a20024190086a41046a41b002109d081a200241f6066a20054110763a0000200241f4066a20053b0100200241d0066a2003370300200241c8066a2007370300200241d8066a220520022903f807370300200241e0066a2210200e290300370300200241e8066a200d290300370300200241f7066a20022903d807370000200241ff066a200929030037000020024187076a20082903003700002002418c076a2006290000370000200220043703c006200241f5013602f00620024196076a20014110763a000020024194076a20013b010020024197076a20022903b8073700002002419f076a200a290300370000200241a7076a200b290300370000200241ac076a200c290000370000410410332201450d05200242043702cc0a200220013602c80a20024190046a200241c80a6a10af030240024020022903c0064201520d0020022903d00620022903c8062203420c882204420120044201561b8021040240024020022802cc0a220820022802d00a22016b4102490d0020022802c80a21060c010b200141026a22062001490d09200841017422092006200920064b1b22094100480d090240024020080d00024020090d00410121060c020b2009103322060d010c0d0b20022802c80a210620082009460d0020062008200910372206450d0c20022802d00a21010b200220093602cc0a200220063602c80a0b200620016a2004a741047420037aa7417f6a22064101200641014b1b2206410f2006410f491b723b0000200141026a21010c010b0240024020022802cc0a20022802d00a2201460d0020022802c80a21060c010b200141016a22062001490d08200141017422082006200820064b1b22084100480d080240024020010d0041002101024020080d00410121060c020b200810332206450d0c0c010b20022802c80a210620012008460d0020062001200810372206450d0b20022802d00a21010b200220083602cc0a200220063602c80a0b200620016a41003a0000200141016a21010b200220013602d00a2005200241c80a6a10e201200220103602900820024190086a200241c80a6a10cf0120022802f00621080240024020022802cc0a220620022802d00a22016b4104490d0020022802c80a21050c010b200141046a22052001490d07200641017422092005200920054b1b22094100480d070240024020060d00024020090d00410121050c020b200910332205450d0b0c010b20022802c80a210520062009460d0020052006200910372205450d0a20022802d00a21010b200220093602cc0a200220053602c80a0b200520016a20083600002002200141046a3602d00a412010332201450d052001200241f4066a290200370000200141186a2002418c076a290200370000200141106a20024184076a290200370000200141086a200241fc066a2902003700000240024020022802cc0a220820022802d00a22056b4120490d0020022802c80a21060c010b200541206a22062005490d07200841017422092006200920064b1b22094100480d070240024020080d00024020090d00410121060c020b200910332206450d0b0c010b20022802c80a210620082009460d0020062008200910372206450d0a20022802d00a21050b200220093602cc0a200220063602c80a0b200620056a22062001290000370000200641186a200141186a290000370000200641106a200141106a290000370000200641086a200141086a2900003700002002200541206a3602d00a20011035412010332201450d05200120024194076a290200370000200141186a200241ac076a290200370000200141106a200241a4076a290200370000200141086a2002419c076a2902003700000240024020022802cc0a220820022802d00a22056b4120490d0020022802c80a21060c010b200541206a22062005490d07200841017422092006200920064b1b22094100480d070240024020080d00024020090d00410121060c020b200910332206450d0b0c010b20022802c80a210620082009460d0020062008200910372206450d0a20022802d00a21050b200220093602cc0a200220063602c80a0b200620056a22062001290000370000200641186a200141186a290000370000200641106a200141106a290000370000200641086a200141086a2900003700002002200541206a3602d00a2001103520022802cc0a210620022802c80a21010240024020022802d00a22054180024b0d0020024196036a200241f0036a2001200510f90521050c010b2005ad4220862001ad84100922052900002103200541086a2900002104200541106a2900002107200241a8106a41186a200541186a290000370300200241a8106a41106a2007370300200241a8106a41086a2004370300200220033703a8102005103520024196036a200241f0036a200241a8106a412010f90521050b02402006450d00200110350b2005450d03200241f0026a41086a200241f0036a41086a290300370300200241f0026a41106a200241f0036a41106a290300370300200241f0026a41186a200241f0036a41186a290300370300200241c8026a41086a200241d0066a290300370300200241c8026a41106a200241d8066a290300370300200241c8026a41186a200241e0066a290300370300200241e8026a200241e8066a290300370300200220022903f0033703f0022002200241c8066a2903003703c80220022903c0062103200241186a20024190046a41b002109d081a0b200041086a20022903f002370300200041286a2003370300200041306a20022903c802370300200041206a200241f0026a41186a290300370300200041186a200241f0026a41106a290300370300200041106a200241f0026a41086a290300370300200041386a200241c8026a41086a290300370300200041c0006a200241c8026a41106a290300370300200041c8006a200241c8026a41186a290300370300200041d0006a200241c8026a41206a290300370300200041d8006a200241186a41b002109d081a200041003a00000c060b200241800d6a10ba02200041036a41003a0000200041800a3b0001200041013a00000c050b200041013b0001200041013a0000200041036a41003a000020014198016a10ba020c040b20004180083b0001200041013a0000200041036a41003a000020024190046a10ba020c030b41809ccc004119419c9ccc00103f000b1045000b103e000b200241a0116a24000f0b103c000b841f05017f017e037f027e017f230041d0016b22022400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c00011302030405060708090a0b0c0d0e0f1011121313131415161713000b420021034100210402400240024002400240024002400240200141086a2802000e0b0001070203030405050506000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b2001410c6a35020042d00f7e21030b410121040c040b41012104428084afdf0021030c030b410121044280dac40921030c020b410121040c010b4101210442c0f0f50b21030b200041003a0009200020043a0008200020033703000c170b0240024002400240024002400240024020012d00040e06000102030405000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b200141086a280200210442c0c3930721030240200141106a280200220541b0026c2206450d00200421010340200241106a200110d803427f427f200320022903107c220720072003541b220342c0843d7c220720072003541b2103200141b0026a2101200641d07d6a22060d000b0b200541b0026c21014101210603402001450d06200141d07d6a2101200241106a200410d803200441b0026a210420022d00184101460d000c050b0b200241106a200141086a280200220110d80320022903102103200241106a200110d803427f200342c08db7017c220720072003541b210320022d001821060c040b200141106a3502002107200241106a200141206a280200220110d80320022903102103200241106a200110d803427f427f427f200342808ece1c7c220820082003541b220320074290a10f7e7c220720072003541b220342c0b2cd3b7c220720072003541b210320022d001821060c030b200141306a35020042c0a9077e42c0c09bd8007c21030c010b200141306a35020042a08d067e42c093b9d3007c21030b410021060b200041003a0009200020063a0008200020033703000c160b200041023b0108200042c0cbe8cb003703000c150b200041023b0108200042003703000c140b200041003b0108200042003703000c130b42c0b2cd3b21074280e89226210302400240024002400240200141086a2802000e050004010203000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b42c09dd81021030c020b4280e59af70021070c010b42808ece1c21030b200041003b01082000200720037c3703000c120b4280cab5ee012103410021040240024002400240024002400240024002400240200141086a2d00000e1900090901010202090902030303030603040909090905060707000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b428088debe0121030c060b4280afd0e50221030c050b42c096b10221030c040b428094ebdc0321030c030b410121040c030b420021030c010b4280d0dbc3f40221030b410021040b200041003a0009200020043a0008200020033703000c110b200041003b010820004280f1a795034280c7bdbf0220012802041b3703000c100b4280e497d0122103410021040240024002400240024002400240024002400240200141086a2d00000e1e000909020201090909020203030404040505060404060604060605050607000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b410121044280cab5ee0121030c070b428084afdf0021030c050b41012104420021030c050b4280c2d72f21030c030b4280cab5ee0121030c020b420021030c010b42c099f9ebc02b21030b410021040b200041003a0009200020043a0008200020033703000c0f0b4280c2d72f2103024002400240024020012d00040e06000303010202000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b4280e497d01221030c010b428084afdf0021030b200041013b0108200020033703000c0e0b4280c2d72f2103024002400240024020012d00040e06000303010202000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b4280e497d01221030c010b428084afdf0021030b200041013b0108200020033703000c0d0b4280c2d72f210341002104024002400240024002400240200141086a2802000e0700050102030404000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b42002103410021040c030b428094ebdc032103410021040c020b4280cab5ee012103410021040c010b410121044280a8d6b90721030b200041003a0009200020043a0008200020033703000c0c0b200041003b010820004280e1eb173703000c0b0b200041023b0108200042003703000c0a0b200041003b0108200042003703000c090b42c090c1a401210341002104024002400240024002400240024002400240200141086a2d00000e09000801020308040506000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b410121044280ae99b50121030c060b410121044280bcded70021030c050b200141346a35020042a01f7e42c0cbf1c5017c21030c030b200141346a35020042a01f7e4280c2d1ae017c21030c020b4280caacf40021030c010b42a0dcc4a20221030b410021040b200041003a0009200020043a0008200020033703000c080b024002400240024002400240200141086a2d00000e06000102030405000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b200041003b0108200042003703000c0b0b200241106a41186a4200370300200241106a41106a22054200370300200241106a41086a220442003703002002420037031041f1d8cb00ad42808080809001841001220629000021032004200641086a290000370300200220033703102006103541e2d8cb00ad4280808080f00184100122062900002103200241c0016a41086a2209200641086a290000370300200220033703c00120061035200520022903c0012203370300200241a0016a41086a2004290300370300200241a0016a41106a2003370300200241a0016a41186a2009290300370300200220022903103703a001200241106a200241a0016a10da02200242a0c21e200229031020022d0098014102461b4200200141146a3502004200108408200041003b01082000427f200229030020022903084200521b3703000c0a0b200041003b01082000200141d0006a2903003703000c090b200041003b01082000200141c8006a2903003703000c080b200041003b0108200042003703000c070b42002103410021040240024002400240024020012802040e0400010402000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b200241106a200141086a280200220110d80320022903102103200241106a200110d803200241106a21010c010b200241106a2001412c6a280200220110d80320022903102103200241106a200110d803200241106a21010b20034290ce007c210320012d000821040b200041003a0009200020043a0008200020033703000c060b200041003b01082000200141286a35020042b0e32d7e2001411c6a35020042809fc9007e7c4280f797f3017c3703000c050b108406000b42c0d4e2cc002103024002400240024002400240024002400240024002400240200141086a2d00000e0c000b0102030405060708090a000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b42808c84a40121030c090b200141146a35020042a0acb9317e42c0b5b6f7267c21030c080b42808ea9da2721030c070b42c0f587ba0121030c060b42c0bda3a90121030c050b42c0ceffc30021030c040b42e0facec40021030c030b4280b4f3c30021030c020b42c0a0e2b30121030c010b42c0febdaf2821030b200041003b0108200020033703000c030b4280e1eb172103024002400240024002400240024002400240200141086a2d00000e0d00080108010203040705060807000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b4280dac40921030c060b428087a70e21030c050b4280dac40921030c040b428087a70e21030c030b4280dac40921030c020b428087a70e21030c010b420021030b200041003b0108200020033703000c020b420021034100210402400240024002400240024020012d00040e0a00010502020202030305000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b200241106a200141286a280200220110d80320022903102103200241106a200110d80320034290ce007c210320022d001821040c030b4280c2d72f21030c010b428087a70e21030b410021040b200041003a0009200020043a0008200020033703000c010b4280e59af700210342808ece1c21070240024002400240200141086a2802000e0400030102000b200241246a410136020020024201370214200241e8d4ca00360210200241043602a4012002419cd5ca003602a0012002200241a0016a360220200241106a41b0b4cc00104c000b42c097e8b20121030c010b42c097e8b201210342c085eb3621070b200041003b01082000200320077c3703000b200241d0016a24000bc10304017f027e067f017e230041206b22032400200229030021042001290300210520022802102106200141106a200141186a2207280200200241186a2208280200220910870120012802102007280200220a410c6c6a20062009410c6c109d081a200841003602002007200a20096a2209360200200341086a200936020020032001290210370300200228021c21082001411c6a200141246a2207280200200241246a220a2802002209108701200128021c2007280200220b410c6c6a20082009410c6c109d081a200a41003602002007200b20096a2209360200200341106a41086a20093602002003200129021c370310427f200520047c220420042005541b2105200229030822042001290308220c200c2004561b21040240024020012d0028450d004101210120022d00280d010b410021010b20002005370300200020032903003702102000200329031037021c200020013a002820002004370308200041186a200341086a280200360200200041246a200341106a41086a2802003602000240200241146a2802002201450d002001410c6c450d00200610350b0240200241206a2802002201450d002001410c6c450d00200810350b200341206a24000b920303047f017e017f230041e0006b22032400200341306a41186a4200370300200341306a41106a22044200370300200341306a41086a220542003703002003420037033041d1c4c700ad4280808080e000841001220629000021072005200641086a290000370300200320073703302006103541b8eec700ad4280808080800284100122062900002107200341d0006a41086a2208200641086a2900003703002003200737035020061035200420032903502207370300200341106a41086a2005290300370300200341106a41106a2007370300200341106a41186a200829030037030020032003290330370310200341086a200341106a412010c0014100210502400240417f200328020c410020032802081b220620026a220220022006491b22064280808080f28ba80942808080c0f588fe06200141ff01711b22072007428094ebdc038022074280ec94a37c7e7c4280cab5ee01562007a76a4b0d00200041046a20063602000c010b200041800c3b0001200041036a41003a0000410121050b200020053a0000200341e0006a24000b8b0a04027f017e017f087e230041b0026b220624000240200341ff01710d00200641b8016a2001ad42004280c8afa025420010840820064180026a41186a420037030020064180026a41106a2207420037030020064180026a41086a22034200370300200642003703800241e3efcb00ad4280808080a002841001220129000021082003200141086a29000037030020062008370380022001103541f5efcb00ad4280808080900284100122012900002108200641a0026a41086a2209200141086a290000370300200620083703a00220011035200720062903a0022208370300200641e0016a41086a2003290300370300200641e0016a41106a2008370300200641e0016a41186a200929030037030020062006290380023703e001200641b8016a41086a29030020062903b801220820024280c0a8ca9a3a20024280c0a8ca9a3a541b7c2202200854ad7c2108200641c8016a200641e0016a10bc020240024020062802c8010d00410021034200210a4200210b0c010b20062903d001220a4200522201200641c8016a41106a290300220b420055200b501b2103200b427f550d00428080808080808080807f4200200b2001ad7c7d200a200b428080808080808080807f85845022011b210b42004200200a7d20011b210a0b200641f8006a2002200842808090bbbad6adf00d4200109808200641a8016a200a200b42808090bbbad6adf00d4200109808200641e8006a2006290378220c200641f8006a41086a290300220d428080f0c4c5a9d28f72427f10840820064198016a20062903a801220b200641a8016a41086a290300220e428080f0c4c5a9d28f72427f108408200642808090bbbad6adf00d370388022006290368210f2006200a2006290398017c220a37038002200641c8006a2002200f7c42ffffffffffffffff0f83420020064180026a200a42808090bbbad6adf00d564103746a29030022104200108408200641386a2006290348220a200641c8006a41086a290300220f42808090bbbad6adf00d4200109808200641286a20062903382211200641386a41086a290300428080f0c4c5a9d28f72427f108408200641d8006a200c200d20104200108408200641186a20084200200b4200108408200641086a200e42002002420010840820064188016a20024200200b4200108408427f427f427f2008427f427f20064188016a41086a290300220b200629031820062903087c7c220c2008420052200e42005271200629032042005272200629031042005272200c200b547222011b220b200641d8006a41086a2903002006290358220e2011427f200f42808090bbbad6adf00d541b200a20062903287c220c428080c89d9deb96f80656200f200641286a41086a2903007c200c200a54ad7c220a420052200a501bad7c7c220a200e54ad7c7c427f20062903880120011b220e200a7c220f200e542201ad7c220a2001200a200b54200a200b511b22011b220e7c2002427f200f20011b220b7c220f2002542201ad7c220a2001200a200854200a2008511b22011b42002008200e7d2002200b54ad7d220a2002200b7d220b200256200a200856200a2008511b22071b20031b220a427f200f20011b4200200b20071b20031b220242c0b2cd3b7c22082002542203ad7c220b2003200b200a54200820025a1b22031b220220057c427f200820031b220820047c22042008542203ad7c22082003200820025420082002511b22031b2105427f200420031b21040b2000200437030020002005370308200641b0026a24000b8e1307077f027e037f0a7e017f037e047f230041d0036b2203240020022802102104200228020c2105200228020821062002280204210720022802002102200341206a2001108e02200341a0016a2003280220220820032802282209108f0220032903a001210a4200210b200342003703a001200341e8016a280200210c20032d00ec01210d02400240200a420151220e0d00200341306a41306a4200370300200341306a41286a4200370300200341306a41206a4200370300200341306a41186a4200370300200341c0006a4200370300200341386a4200370300200342003703304200210f4200211042002111420021120c010b200341d8016a2903002113200341a0016a41306a2903002114200341a0016a41206a290300210f200341a0016a41186a290300210b200341e0016a290300211220032903b001211120032903a8012110200341306a41206a200341a0016a41286a290300370300200341306a41286a2014370300200341306a41306a2013370300200341c0006a200b3703002003200f37034820032010370330200320113703380b02400240024002402010200229030022157d22142010562011200241086a29030022167d2010201554ad7d221320115620132011511b450d00419089c200ad4280808080b00284211141838c0c21040c010b02402010200b7c2217428080e983b1de165441002011200f7c22182017200b54ad7c501b0d002014200b7c220b42ffffe883b1de16562013200f7c200b201454ad7c220b420052200b501b0d0020072d00004101460d0041f588c200ad4280808080900184211141838c1421040c010b2015201684500d0120052d00002105200341e8006a2006280200108e02200341a0026a200328026822062003280270108f0220032903a0024201512107200341d0026a290300210f200341c8026a2903002116200341e0026a290300210b200341d8026a29030021150240200328026c450d00200610350b200b420020071b210b2015420020071b21150240200541ff01714101460d00200f420020071b210f2016420020071b2116024020054101710d0020162115200f210b0c010b200f200b2016201556200f200b56200f200b511b22071b210b2016201520071b21150b2015201458200b201358200b2013511b0d0141a389c200ad4280808080d00284211141838c0421040b20114280807c83210b201142088842ff018321102011a7210e410121020c010b2003201437033020032013370338200241086a290300210f2002290300211520042802002104200341e8006a41186a200341c0006a220241086a290300220b370300200341e8006a41206a2207200241106a29030037030020034190016a2206200241186a29030037030020034198016a2219200241206a2903003703002003201337037020032014370368200320022903002216370378427f20172017201054220220182002ad7c221020115420102011511b22021b427f201020021b8450210502400240427f201420167c2211201120145422022013200b7c2002ad7c221120135420112013511b22021b2210428080e983b1de16544100427f201120021b2211501b0d00200341e8006a41106a29030021102019290300210b2006290300211720072903002116200329037021182003290368211a4201211b200329038001211c0c010b02400240201020118450450d004200211b0c010b4200211b200341a0026a41186a221d4200370300200341a0026a41106a22064200370300200341a0026a41086a22074200370300200342003703a00241b6fdc600ad4280808080800184220b100122192900002117200341c0036a41086a2202201941086a290000370300200320173703c0032019103520072002290300370300200320032903c0033703a00241e489c200ad4280808080d0018422171001221929000021162002201941086a290000370300200320163703c00320191035200620032903c0032216370300200341a0036a41086a221e2007290300370300200341a0036a41106a221f2016370300200341a0036a41186a22202002290300370300200320032903a0023703a003200341086a200341a0036a412010d701200341086a41106a29030021162003290310211820032802082119201d42003703002006420037030020074200370300200342003703a002200b1001221d290000210b2002201d41086a2900003703002003200b3703c003201d103520072002290300370300200320032903c0033703a00220171001221d290000210b2002201d41086a2900003703002003200b3703c003201d1035200620032903c003220b370300201e2007290300370300201f200b37030020202002290300370300200320032903a0023703a003200342002016420020191b220b20117d2018420020191b2217201054ad7d2216201720107d22182017562016200b562016200b511b22021b3703a80220034200201820021b3703a002200341a0036aad4280808080800484200341a0026aad42808080808002841002200341d8026a2011370300200341d0026a2010370300200741013a0000200341a9026a2004290000370000200341b1026a200441086a290000370000200341b9026a200441106a290000370000200341c1026a200441186a290000370000200341033a00a00241b0b4cc004100200341a0026a10d4010b0b2005ad2111200341c8016a2016370300200341d0016a2017370300200341b0016a2018370300200341d8016a200b370300200341b8016a20103703002003201c3703c001200320123703e0012003201a3703a80142012110410021022003200d4100200a42015122041b3a00ec012003200c410020041b3602e8012003201b4201512204ad3703a001024020040d002009ad4220862008ad841007420021104200210b0c010b200320093602a402200320083602a002200341a8016a200341a0026a10e7024200210b0b02402003280224450d00200810350b024002402002450d0020002004360204200041086a2010420886200ead42ff018384200b84370200410121020c010b024002400240200e41ff017122020d0020104200510d004103210e200341a0026a21020c010b2002450d0120104200520d014104210e200341a0016a21020b200241086a200e3a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b200041286a200f370300200041206a2015370300200041186a2013370300200041106a2014370300200041086a2011370300410021020b20002002360200200341d0036a24000b8f1804057f017e077f017e230041f0006b2202240020012802202103200241086a41186a4200370300200241086a41106a22044200370300200241086a41086a220542003703002002420037030841a3edcb00ad4280808080f000841001220629000021072005200641086a290000370300200220073703082006103541f393ca00ad4280808080a00184100122062900002107200241e0006a41086a2208200641086a2900003703002002200737036020061035200420022903602207370300200241c0006a41086a2005290300370300200241c0006a41106a2007370300200241c0006a41186a200829030037030020022002290308370340200241086a200241c0006a10fe0120022802082205410120051b2106024002400240024002400240024002402003200229020c420020051b2207422088a7490d00200742ffffff3f83500d01200610350c010b2003200620034105746a10b90421030240200742ffffff3f83500d00200610350b20030d010b200241086a41186a22054200370300200241086a41106a22064200370300200241086a41086a220342003703002002420037030841a3edcb00ad4280808080f000841001220829000021072003200841086a290000370300200220073703082008103541a5ebcb00ad4280808080c00184100122082900002107200241e0006a41086a2209200841086a290000370300200220073703602008103520042002290360370000200441086a22082009290300370000200241c0006a41086a220a2003290300370300200241c0006a41106a220b2006290300370300200241c0006a41186a220c2005290300370300200220022903083703402002200241c0006a412010c001200128021c2002280204410020022802001b220d470d01200542003703002006420037030020034200370300200242003703084188e8cb00ad42808080808001841001220e29000021072003200e41086a29000037030020022007370308200e1035418fd1cb00ad4280808080c000841001220e29000021072009200e41086a29000037030020022007370360200e10352004200229036037000020082009290300370000200a2003290300370300200b2006290300370300200c200529030037030020022002290308370340200241086a200241c0006a10d80220022802082204410120041b210c2001280224200229020c420020041b2207422088a72205470d0202402001280220220620054f0d00200c20064105746a220e0d040b20004180083b0001200041013a0000200041036a41003a00000c040b20004180063b0001200041013a0000200041036a41003a00000c040b20004180063b0001200041013a0000200041036a41003a00000c030b200041800e3b0001200041013a0000200041036a410a3a00000c010b2002410036021020024201370308200128020021030240410410332204450d002002410436020c2002200436020820042003360000200241043602102001280204210a2001410c6a2802002204200241086a1077024002400240200228020c2209200228021022036b2004490d00200228020821080c010b200320046a22082003490d012009410174220b2008200b20084b1b220b4100480d010240024020090d000240200b0d00410121080c020b200b103322080d010c040b200228020821082009200b460d0020082009200b10372208450d030b2002200b36020c200220083602080b200820036a200a2004109d081a2002200320046a360210200141106a2802002103200141186a2802002204200241086a10770240024020040d00200228020c210920022802102104200d210b0c010b20032004410c6c6a210b03402003280200210a200341086a2802002204200241086a107702400240200228020c2206200228021022056b2004490d0020022802082108200621090c010b200520046a22082005490d03200641017422092008200920084b1b22094100480d030240024020060d00024020090d00410121080c020b200910332208450d060c010b2002280208210820062009460d0020082006200910372208450d050b2002200936020c200220083602080b200820056a200a2004109d081a2002200520046a22043602102003410c6a2203200b470d000b2001280224210520012802202106200128021c210b0b02400240200920046b4104490d00200441046a2103200228020821082009210a0c010b200441046a22032004490d01200941017422082003200820034b1b220a4100480d010240024020090d000240200a0d00410121080c020b200a10332208450d040c010b200228020821082009200a460d0020082009200a10372208450d030b2002200a36020c200220083602080b200820046a200b360000200220033602100240200a20036b41034b0d00200341046a22042003490d01200a41017422092004200920044b1b22044100480d0102400240200a0d00024020040d00410121080c020b200410332208450d040c010b200a2004460d002008200a200410372208450d030b2002200436020c200220083602080b200820036a20063600002002200341046a220636021002400240200228020c220920066b4104490d0020022802082104200921080c010b200641046a22042006490d01200941017422082004200820044b1b22084100480d010240024020090d00024020080d00410121040c020b200810332204450d040c010b2002280208210420092008460d0020042009200810372204450d030b2002200836020c200220043602080b200420066a2005360000200141286a200341086aad4220862004ad84200e1015210302402008450d00200410350b0240024020034101470d00200241086a41086a427f3703002002413c6a4108360200200241286a4200370300200241206a4280808080c0003703002002427f37030820024188e8cb00360238200241013a003020024204370318411010332204450d0120024210370244200220043602404108200241c0006a10770240024020022802442208200228024822066b4108490d00200641086a210420022802402103200821050c010b200641086a22042006490d03200841017422032004200320044b1b22054100480d030240024020080d00024020050d00410121030c020b200510332203450d060c010b2002280240210320082005460d0020032008200510372203450d050b20022005360244200220033602400b200320066a42c9dabdf2c6ad9ab7e500370000200220043602480240200520046b41034b0d00200441046a22062004490d03200541017422082006200820064b1b22064100480d030240024020050d00024020060d00410121030c020b200610332203450d060c010b20052006460d0020032005200610372203450d050b20022006360244200220033602400b200320046a200d3600002002200441046a2203360248024002402002280244220920036b4120490d00200441246a210820022802402105200921060c010b200341206a22082003490d03200941017422042008200420084b1b22064100480d030240024020090d00024020060d00410121050c020b200610332205450d060c010b2002280240210520092006460d0020052009200610372205450d050b20022006360244200220053602400b200241316a2109200520036a2204200e290000370000200441186a200e41186a290000370000200441106a200e41106a290000370000200441086a200e41086a2900003700000240200228022c22042002280228470d00200241246a20044101108701200228022c21040b20022802242004410c6c6a220420083602082004200636020420042005360200200241c0006a41086a2204200241086a41186a2903003703002002200228022c41016a36022c200241c0006a41106a2203200241086a41206a29030037030020022002290318370340200220092900003703602002200941076a2900003700672002290308210f200041106a42e400370300200041086a200f370300200041306a41013a0000200041186a2002290340370300200041206a2004290300370300200041286a2003290300370300200041003a0000200041316a2002280260360000200041346a2002280063360000200742ffffff3f83500d05200c10350c050b20004180083b0001200041013a0000200041036a41003a00000c030b1045000b103e000b103c000b200742ffffff3f83500d00200c10350b200241f0006a24000bcf3909057f017e057f017e047f017e037f017e0d7f230022022103200241c0046b41607122022400024002402001450d00200220003602400c010b200241b0b4cc003602400b20022001360244200241c0026a200241c0006a10c403024002400240024002400240024020022802c402450d00200241c8006a200241c0026a41f000109d081a200241b8016a200241c8006a10df032002280248200241d8006a20024198016a200241b8016a410010e00341004100280290b54c2201410120011b360290b54c0240200141014b0d000240024020010e020001000b410041fca1c000360298b54c410041b0b4cc00360294b54c41004102360290b54c0c010b03404100280290b54c4101460d000b0b2002410020022802482201417f6a2200200020014b1b22043602c401100d4101470d01200241c0026a41186a22054200370300200241c0026a41106a22004200370300200241c0026a41086a22014200370300200242003703c0024188e8cb00ad42808080808001841001220629000021072001200641086a290000370300200220073703c002200610354194c4c400ad4280808080e00184100122082900002107200241f0016a41086a2206200841086a290000370300200220073703f00120081035200020022903f0012207370300200241e0036a41086a22092001290300370300200241e0036a41106a220a2007370300200241e0036a41186a220b2006290300370300200220022903c0023703e003200241386a200241e0036a412010c001410021080240200228023c410020022802381b220c20044d0d00200241e0036a2100200241c8016a21010c060b200542003703002000420037030020014200370300200242003703c00241a3edcb00ad4280808080f00084220710012208290000210d2001200841086a2900003703002002200d3703c0022008103541a5ebcb00ad4280808080c0018410012208290000210d2006200841086a2900003703002002200d3703f00120081035200020022903f001220d37030020092001290300370300200a200d370300200b2006290300370300200220022903c0023703e003200241306a200241e0036a412010c0012002280234210e2002280230210f200542003703002000420037030020014200370300200242003703c00220071001220829000021072001200841086a290000370300200220073703c0022008103541f393ca00ad4280808080a001841001220829000021072006200841086a290000370300200220073703f00120081035200020022903f001220737030020092001290300370300200a2007370300200b2006290300370300200220022903c0023703e003200241c8016a200241e0036a10fe010240024020022802c80122010d00410021100c010b20022902cc012207422088a72110200742ffffff3f83500d00200110350b200241c0026a41186a22084200370300200241c0026a41106a22054200370300200241c0026a41086a22014200370300200242003703c0024188e8cb00ad42808080808001841001220629000021072001200641086a290000370300200220073703c00220061035418fd1cb00ad4280808080c00084100122062900002107200241f0016a41086a2209200641086a290000370300200220073703f00120061035200020022903f001370000200041086a2009290300370000200241e0036a41086a2001290300370300200241e0036a41106a2005290300370300200241e0036a41186a2008290300370300200220022903c0023703e003200241c0026a200241e0036a10d80220022802c002211120022902c4022112200241c0026a41e9dabdf30610e10320022802c002210820022802c402210902400240024020022802c80222000d004100211341012114410021150c010b02400240024020004105742201410575220641ffffff3f712006470d0020014100480d0020010d01410121140c020b103e000b200110332214450d020b200820016a210a2000410574210520014105762113410021010340200820016a22002900002107200041086a290000210d200041106a2900002116201420016a220641186a200041186a290000370000200641106a2016370000200641086a200d370000200620073700002005200141206a2201470d000b200a20086b41606a41057641016a21150b0240200941ffffff3f71450d00200810350b20154115490d0402404101450d0020154104744160712217417f4c0d000240201710332218450d00200241003602f801200242043703f001201441606a2119201441a07f6a211a41042106410021014100211b2015211c0340201c210b4100211c4101210a0240200b417f6a2205450d00024002400240024002400240201420054105746a200b410574221d20146a41406a412010a0084100480d00200b417e6a2109201a201d6a21004100211c410021080340024020092008470d00200b210a0c080b200841016a2108200041206a2000412010a0082105200041606a21002005417f4a0d000b200841016a210a2008417f73200b6a21050c010b201a201d6a210002400340024020054101470d00410021050c020b2005417f6a2105200041206a2000412010a0082108200041606a210020084100480d000b0b200b2005490d01200b20154b0d02200b20056b220a4101762209450d002019201d6a2100201420054105746a21080340200241e0036a41186a221d200841186a221e290000370300200241e0036a41106a221f200841106a2220290000370300200241e0036a41086a220c200841086a221c290000370300200220082900003703e003200041086a22212900002107200041106a2222290000210d200041186a2223290000211620082000290000370000201e20163700002020200d370000201c20073700002023201d2903003700002022201f2903003700002021200c290300370000200020022903e003370000200041606a2100200841206a21082009417f6a22090d000b0b024020050d002005211c0c050b0240200a41094d0d002005211c0c050b200b20154b0d02200b20056b2109201420054105746a211d0340200b2005417f6a221c490d040240200b201c6b220a4102490d00201420054105746a22002014201c4105746a2205412010a008417f4a0d00200241c0026a41186a220c200541186a2208290000370300200241c0026a41106a2221200541106a221e290000370300200241c0026a41086a2222200541086a221f290000370300200220052900003703c00220052000290000370000201f200041086a290000370000201e200041106a2900003700002008200041186a290000370000410121200240200a4103490d00200541c0006a200241c0026a412010a008417f4a0d0041022108201d210002400340200041186a200041386a290000370000200041106a200041306a290000370000200041086a200041286a2900003700002000200041206a221e29000037000020092008460d01200041c0006a211f20082120201e2100200841016a2108201f200241c0026a412010a008417f4a0d020c000b0b200821200b200520204105746a220020022903c002370000200041186a200c290300370000200041106a2021290300370000200041086a20222903003700000b201c450d05201d41606a211d200941016a2109201c2105200a410a4f0d050c000b0b2005200b41eccfca001059000b200b201541eccfca001058000b200b2005417f6a221c490d00200b201541fccfca001058000b201c200b41fccfca001059000b0240201b20022802f401470d00200241f0016a201b410110900120022802f001210620022802f8012201211b0b2006201b4103746a2200200a3602042000201c3602002002200141016a22013602f8012001211b024020014102490d000240024003400240024002400240024020062001417f6a4103746a2200280200450d00200141037420066a220941746a2802002205200028020422084b0d010b20014103490d022000280204210820062001417d6a221f4103746a28020421000c010b4102211b200141024d0d0620062001417d6a221f4103746a2802042200200820056a4d0d004103211b200141034d0d06200941646a280200200020056a4b0d050b20002008490d010b2001417e6a211f0b02400240024002400240024002402001201f41016a22204d0d002001201f4d0d012006201f41037422216a2201280204222220012802006a22012006202041037422236a2200280200220c490d02200120154b0d032014200c4105746a221d2000280204221e41057422006a2108200141057421062001200c6b2209201e6b2201201e4f0d042018200820014105742200109d08220b20006a2105201e4101480d0520014101480d05201920066a21062008210103402006200141606a2208200541606a220920092008412010a008410048220a1b2200290000370000200641186a200041186a290000370000200641106a200041106a290000370000200641086a200041086a29000037000020052009200a1b21050240201d20082001200a1b2201490d00200b21000c080b200641606a2106200b2100200b2005490d000c070b0b20202001418cd0ca001042000b201f2001419cd0ca001042000b200c200141acd0ca001059000b2001201541acd0ca001058000b2018201d2000109d08220b20006a21050240201e4101480d002009201e4c0d00201420066a210a200b2100201d2101034020012008200020082000412010a00841004822091b2206290000370000200141186a200641186a290000370000200141106a200641106a290000370000200141086a200641086a2900003700002000200041206a20091b2100200141206a2101200841206a200820091b2208200a4f0d03200520004b0d000c030b0b201d2101200b21000c010b20082101200b21000b20012000200520006b416071109d081a024020022802f8012201201f4d0d0020022802f001220620216a22002022201e6a3602042000200c360200200120204d0d02200620236a2200200041086a20012020417f736a410374109e081a20022001417f6a22013602f801200141014b0d010c030b0b201f200141bcd0ca001042000b20202001104e000b2001211b0b201c450d060c000b0b1045000b1044000b103c000b200241ec036a4104360200200241dc006a41023602002002420237024c200241f0b2c300360248200241043602e403200241b8b4c3003602e003200241003602f401200241b0b4cc003602f0012002200241e0036a3602582002200241f0016a3602e803200241c8006a4180b3c300104c000b410028028cb54c4105490d042002410d3602e4032002200241c4016a3602e0034100280298b54c21014100280294b54c21004100280290b54c210620024180036a418003360200200241f8026a42b580808010370300200241f4026a4184cac400360200200241ec026a4210370200200241e8026a41f4c9c400360200200241e0026a4201370300200241d0026a4202370300200241c0026a41086a4108360200200241dc026a200241e0036a360200200241dcc9c4003602cc02200241ecc9c4003602c402200241053602c002200041aca2c000200641024622061b200241c0026a200141c4a2c00020061b2802101102000c040b024020022802f40141ffffffff0171450d00200610350b2017450d01201810350c010b20154102490d0020142015417f6a22004105746a21054101210603400240024002400240201520002201417f6a2200490d00201520006b22094102490d03201420014105746a2201201420004105746a2208412010a008417f4a0d03200241c0026a41186a221e200841186a220a290000370300200241c0026a41106a221f200841106a220b290000370300200241c0026a41086a2220200841086a221d290000370300200220082900003703c00220082001290000370000201d200141086a290000370000200b200141106a290000370000200a200141186a2900003700004101210120094103490d02200841c0006a200241c0026a412010a008417f4a0d0241002109200521010340200141186a200141386a290000370000200141106a200141306a290000370000200141086a200141286a2900003700002001200141206a220b29000037000020062009220a460d02200a417f6a2109200141c0006a211d200b2101201d200241c0026a412010a008417f4a0d020c000b0b2000201541dccfca001059000b4102200a6b21010b200820014105746a220120022903c002370000200141186a201e290300370000200141106a201f290300370000200141086a20202903003700000b200541606a21052006417f6a210620000d000b0b200220103602e801200220043602e4012002200e4100200f1b22013602e001200220153602dc01200220133602d801200220143602d401200241003602d0012002201036028004200220043602fc03200220013602f803200220153602f403200220133602f003200220143602ec03200241003602e80320022011410120111b22083602e003200220083602c801200220082012420020111b2207422088a74105746a22013602e403200220013602cc012007a7210c200241e0036a2100200241c8016a21010b20024198026a41086a2206200141086a29020037030020024198026a41106a220a200141106a29020037030020024198026a41186a220b200141186a29020037030020024198026a41206a221d200141206a280200360200200241f0016a41086a221e200241c0026a41086a2205290200370300200241f0016a41106a221f200241c0026a41106a290200370300200241f0016a41186a2220200241c0026a41186a290200370300200241f0016a41206a221c200241c0026a41206a2902003703002002200129020037039802200220022902c0023703f001200241c8016a41206a2201200241e0036a41206a290200370300200241c8016a41186a2214200241e0036a41186a290200370300200241c8016a41106a2221200241e0036a41106a290200370300200241c8016a41086a2222200241e0036a41086a290200370300200220022902e0033703c8012005200c360200200220083602c402200241013602c002200241cc026a2208200229039802370200200241d4026a22052006290300370200200241dc026a2209200a290300370200200241e4026a220a200b290300370200200241ec026a201d280200360200200241003602f002200241f4026a20022903f001370200200241fc026a201e29030037020020024184036a201f2903003702002002418c036a202029030037020020024194036a201c2903003702002002410036029c03200241c0036a2001290300370300200241b8036a2014290300370300200241b0036a2021290300370300200241a8036a2022290300370300200241a0036a20022903c80137030020024190036a211d200241f8026a21012002419c036a2114200241f0026a212020024180036a211e20024188036a211f410021060340024002402006450d00200241286a202010e3030240200228022822064108460d00200228022c211c0c020b024020022802f0022206450d00024020022802f40241ffffff3f71450d00200610350b20022802880341ffffff3f71450d0020022802840310350b20012000290200370200200141086a200041086a290200370200200141106a200041106a290200370200200141186a200041186a290200370200200141206a200041206a2802003602002002200c3602f402200241003602f0020b2009290200210d200920022903f80337020020052902002116200520022903f00337020020082902002112200820022903e803370200200241d0036a41086a220b200a41086a280200360200200241003602e0032002200a2902003703d00320022902c4022107200220022903e0033702c40202402007a72206450d00201d20022903d00337020020012012370300201e2016370300201d41086a200b280200360200201f200d370300200220073703f0020c020b0240200228029c030d00410821060c010b200241206a201410e3032002280224211c200228022021060b02400240200641796a220b41014b0d000240200b0e020200020b024020022802c002450d0020022802c4022201450d00024020022802c80241ffffff3f71450d00200110350b200241dc026a28020041ffffff3f71450d00200241d8026a28020010350b024020022802f0022201450d00024020022802f40241ffffff3f71450d00200110350b20022802880341ffffff3f71450d0020022802840310350b200228029c032201450d030240200241a0036a28020041ffffff3f71450d00200110350b200241b4036a28020041ffffff3f71450d03200241b0036a28020010350c030b2002201c3602cc03200220063602c803410028028cb54c4104490d002002410e3602dc032002410d3602d4032002200241c8036a3602d8032002200241c4016a3602d0034100280298b54c21064100280294b54c210b4100280290b54c211c200241f7023602a004200242b5808080103703980420024184cac400360294042002421037028c04200241f4c9c400360288042002420237038004200242023703f003200241ccc9c4003602ec03200241083602e803200241ecc9c4003602e403200241043602e003200641c4a2c000201c410246221c1b28021021062002200241d0036a3602fc03200b41aca2c000201c1b200241e0036a20061102000b20022802f00221060c000b0b200241e0036a41186a4200370300200241e0036a41106a22064200370300200241e0036a41086a22014200370300200242003703e00341f7edcb00ad4280808080f000841001220029000021072001200041086a290000370300200220073703e0032000103541b6aac000ad4280808080900284100122002900002107200241f0016a41086a2208200041086a290000370300200220073703f00120001035200620022903f0012207370300200241c0026a41086a2001290300370300200241c0026a41106a2007370300200241c0026a41186a2008290300370300200220022903e0033703c002200241186a200241c0026a10f201024020022802184101470d00200228021c2004470d00200241f0016a410041aeb8c300ad4280808080800384100e10c20102400240024020022802f0012201450d00200241f8016a2802004104490d0041fd93ca002100200420012800002206490d01418294ca002100200641056a20044f0d010b2002200436029802200220043602c801200241e0036a41086a200241f0016a41086a280200360200200220022903f0013703e003200241c0026a200241e0036a10e50320022802c4022101410041aeb8c300ad428080808080038420023502c80242208620022802c0022206ad84200241c8016aad4280808080c00084100f210002402001450d00200610350b024020022802e0032201450d0020022802e403450d00200110350b20004101460d010c020b024020022802f401450d00200110350b20000d010b10e6030b20022802b8012108024020022802c0012201450d00200141246c21002008210103400240024020012d0000220641044b0d0002400240024020060e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b024020022802bc012201450d00200141246c450d00200810350b0240200241c8006a410c6a2802002200450d00200228024c2101200041246c210003400240024020012d0000220641044b0d0002400240024020060e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012000415c6a22000d000b0b0240200241d0006a2802002201450d00200141246c450d00200228024c10350b2003240042010b9704010d7f230041c0006b220224002002410036021820024204370310200241086a200141046a10bf0302400240024002400240200228020c41246c2203450d002002280208210141042104410021050340024020012d00004101470d00200141106a2802002206417f4c0d03200141036a2d00002107200141016a2f00002108200141086a2802002109200141046a2d0000210a0240024020060d004100210b4101210c0c010b20061033220c450d052006210b0b02400240200b2006490d00200b210d0c010b200b410174220d2006200d20064b1b220d4100480d060240200b0d00200d1033220c0d010c080b200b200d460d00200c200b200d1037220c450d070b20082007411074722107200c20092006109d08210c200241306a41086a2208200241206a41086a29020037030020022002290220370330200e41807e71200a72210e024020052002280214470d00200241106a20054101108d0120022802102104200228021821050b2004200541246c6a220b2006360210200b200d36020c200b200c360208200b200e360204200b20073b0001200b41013a0000200b41036a20074110763a0000200b2002290330370214200b411c6a20082903003702002002200541016a22053602180b200141246a21012003415c6a22030d000b0b20002002290310370200200041086a200241106a41086a280200360200200241c0006a24000f0b1044000b1045000b103e000b103c000b931107047f017e017f017e037f017e017f230041e0006b2205240020054102360208200541306a41186a22064200370300200541306a41106a22074200370300200541306a41086a220842003703002005420037033041d1c4c700ad4280808080e0008422091001220a290000210b200541d0006a41086a220c200a41086a2900003703002005200b370350200a10352008200c290300370300200520052903503703304188f2c700ad4280808080e001841001220a290000210b200c200a41086a2900003703002005200b370350200a103520072005290350220b370300200541106a41086a220a2008290300370300200541106a41106a220d200b370300200541106a41186a220e200c29030037030020052005290330370310200541203602342005200541106a360230200541086a200541306a10cd042005410036023041c4c3c700ad4280808080800284200541306aad4280808080c00084220f100220064200370300200742003703002008420037030020054200370330200910012210290000210b200c201041086a2900003703002005200b370350201010352008200c2903003703002005200529035037033041e7c4c700ad4280808080e0008410012210290000210b200c201041086a2900003703002005200b3703502010103520072005290350220b370300200a2008290300370300200d200b370300200e200c2903003703002005200529033037031020052000360230200541106aad4280808080800484220b200f100220064200370300200742003703002008420037030020054200370330200910012210290000210f200c201041086a2900003703002005200f370350201010352008200c290300370300200520052903503703304185c5c700ad4280808080e0008410012210290000210f200c201041086a2900003703002005200f3703502010103520072005290350220f370300200a2008290300370300200d200f370300200e200c29030037030020052005290330370310200541203602342005200541106a36023020032802002003280208200541306a109606200642003703002007420037030020084200370300200542003703302009100122062900002109200c200641086a29000037030020052009370350200610352008200c2903003703002005200529035037033041edc4c700ad4280808080a00184100122062900002109200c200641086a2900003703002005200937035020061035200720052903502209370300200a2008290300370300200d2009370300200e200c29030037030020052005290330370310024041201033220c450d00200c2001290000370000200c41186a200141186a290000370000200c41106a200141106a290000370000200c41086a200141086a290000370000200b200cad42808080808004841002200c1035200541306a2000417f6a10b803200535023821092005280230210841201033220c450d00200c2001290000370000200c41186a200141186a290000370000200c41106a200141106a290000370000200c41086a200141086a29000037000020094220862008ad84200cad42808080808004841002200c103502402005280234450d00200810350b200541306a41186a22064200370300200541306a41106a220a4200370300200541306a41086a220842003703002005420037033041d1c4c700ad4280808080e00084100122012900002109200541d0006a41086a220c200141086a29000037030020052009370350200110352008200c2903003703002005200529035037033041f7c4c700ad4280808080e00184100122012900002109200c200141086a290000370300200520093703502001103520072005290350370000200741086a200c290300370000200541106a41086a2008290300370300200541106a41106a200a290300370300200541106a41186a20062903003703002005200529033037031041201033220c450d00200c2002290000370000200c41186a200241186a290000370000200c41106a200241106a290000370000200c41086a200241086a290000370000200b200cad42808080808004841002200c103502402004450d00200541306a41186a22014200370300200541306a41106a22024200370300200541306a41086a220842003703002005420037033041d1c4c700ad4280808080e00084220910012206290000210f200541d0006a41086a220c200641086a2900003703002005200f370350200610352008200c2903003703002005200529035037033041cccfc700ad4280808080e0008410012206290000210f200c200641086a2900003703002005200f3703502006103520072005290350370000200741086a2206200c290300370000200541106a41086a220a2008290300370300200541106a41106a220d2002290300370300200541106a41186a220e200129030037030020052005290330370310200b100720014200370300200242003703002008420037030020054200370330200910012203290000210f200c200341086a2900003703002005200f370350200310352008200c290300370300200520052903503703304198f0c700ad4280808080a0018410012203290000210f200c200341086a2900003703002005200f37035020031035200720052903503700002006200c290300370000200a2008290300370300200d2002290300370300200e200129030037030020052005290330370310200b1007200142003703002002420037030020084200370300200542003703302009100122032900002109200c200341086a29000037030020052009370350200310352008200c2903003703002005200529035037033041d2cfc700ad4280808080b00184100122032900002109200c200341086a2900003703002005200937035020031035200720052903503700002006200c290300370000200a2008290300370300200d2002290300370300200e200129030037030020052005290330370310200b10080b200541e0006a24000f0b1045000bf30505017f017e0a7f017e027f230041e0006b220224002002200136020c0240024002402002410c6a10312203422088a722010d0020004100360208200042013702000c010b2002200136021420022003a722043602102002200241106a10c40120022802000d0102400240024020022802042205200228021422064105762201200120054b1b22014105742207417f4c0d0002400240024020010d00410121080c010b200710332208450d010b2001ad21032005450d024100210903402006210a200241003a0058200941016a2109410021010240024002400340200a2001460d01200241386a20016a200228021022072d00003a00002002200741016a3602102002200141016a22073a00582007210120074120470d000b200241186a41186a220b200241386a41186a290300370300200241186a41106a220c200241386a41106a290300370300200241186a41086a220d200241386a41086a290300370300200220022903383703182003422088220ea722012003a7460d012001210f0c020b200241003602140240200141ff0171450d00200241003a00580b200342ffffff3f83500d08200810350c080b0240024002400240200141016a22062001490d00200ea7220f4101742210200620062010491b220641ffffff3f712006470d00200641057422064100480d00024020010d0020060d02410121080c040b2006200f4105742201460d03024020010d0020060d02410121080c040b20082001200610372208450d020c030b103e000b2006103322080d010b103c000b2006410576ad21030b200a20076b21062008200f4105746a22012002290318370000200141186a200b290300370000200141106a200c290300370000200141086a200d290300370000200342ffffffff0f83200f41016aad42208684210320092005470d000b2002200a20076b3602140c030b1045000b1044000b2008450d020b2000200337020420002008360200200410350b200241e0006a24000f0b41b89acc00412e200241386a41a89acc0041d499cc001046000bb90201037f23004180016b2202240002400240024002400240200128020022034110710d002000280200210420034120710d012004ad41012001105221000c020b20002802002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a2100200441047622040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000b20024180016a240020000f0b200441800141c88bc0001059000b200441800141c88bc0001059000bc023030b7f047e0c7f230041c0066b2202240002400240024020012802082203200128020c2204460d002001200341206a220536020820012802102106200241f8026a41186a200341186a290000370300200241f8026a41106a200341106a290000370300200241f8026a41086a200341086a290000370300200220032900003703f8022001280214210702400240024002402001411c6a280200220841014b0d004100210920080e020201020b2008210a4100210903402009200a410176220b20096a220c2007200c4105746a200241f8026a412010a00841004a1b2109200a200b6b220a41014b0d000b0b200720094105746a200241f8026a412010a0080d002006210c0c010b2001200641016a220c3602104108210920052004460d020240200841014d0d0003402001200541206a2203360208200241f8026a41186a200541186a290000370300200241f8026a41106a200541106a290000370300200241f8026a41086a200541086a290000370300200220052900003703f8022008210a4100210903402009200a410176220520096a220b2007200b4105746a200241f8026a412010a00841004a1b2109200a20056b220a41014b0d000b200720094105746a200241f8026a412010a008450d022001200c41016a220c3602102003210520032004460d030c000b0b0240024020080e020100010b03402001200541206a2209360208200241f8026a41186a200541186a290000370300200241f8026a41106a200541106a290000370300200241f8026a41086a200541086a290000370300200220052900003703f80202402007200241f8026a412010a0080d00410021090c030b2001200c41016a220c3602102009210520042009460d030c000b0b2001200436020820012006200420036b41406a4105766a41026a3602100c020b024002400240024002400240024002400240200820094d0d00200241186a200720094105746a220941186a290000220d370300200241106a200941106a290000220e370300200241086a200941086a290000220f3703002002200929000022103703002001200c41016a360210200141286a2802002111200141206a2802002109200141246a280200210a200241206a41186a200d370300200241206a41106a200e370300200241206a41086a200f370300200220103703202002200a36024c200220093602482002200c360244200241f8026a41186a4200370300200241f8026a41106a22054200370300200241f8026a41086a22094200370300200242003703f80241a3edcb00ad4280808080f000841001220a290000210d2009200a41086a2900003703002002200d3703f802200a103541f393ca00ad4280808080a001841001220a290000210d200241b8026a41086a220b200a41086a2900003703002002200d3703b802200a1035200520022903b802220d370300200241d0006a41086a2009290300370300200241d0006a41106a200d370300200241d0006a41186a200b290300370300200220022903f802370350200241f8026a200241d0006a10fe0120022802f8022209410120091b210a02400240200c20022902fc02420020091b220d422088a7490d000240200d42ffffff3f83500d00200a10350b200228024421010c010b200c200a200c4105746a10b90421050240200d42ffffff3f83500d00200a10350b410221092002280244210120050d0c0b200228024c210520022802482106411b10332209450d01200941176a41002800b7cd44360000200941106a41002900b0cd44370000200941086a41002900a8cd44370000200941002900a0cd4437000041041033220a450d01200a20013600002009411b413610372208450d082008200a28000036001b200a1035200241b8026a41002008ad4280808080f00384220d100e10c2010240024002400240024020022802b8022209450d00200241c0026a280200220a4104490d00200a417c714104460d0041000d0020092800002006470d002009280004220a41036a20054b0d010b410410332209450d0c2009200636000020094104410810372209450d0c20092005360004200241d0006a41086a200241b8026a41086a280200360200200220022903b802370350200241f8026a200241d0006a10e50320022802fc02210a4100200d20023502800342208620022802f8022207ad842009ad4280808080800184100f210b0240200a450d00200710350b02402002280250220a450d002002280254450d00200a10350b2009103541042109200b4101470d01200241f8026a10bb0420022802f8022201450d072002418c036a280200211220024188036a280200211320024184036a280200211420024180036a280200211520022802fc022116200228024c211720022802482118200228024421192002410036028003200242013703f802410410332209450d0c200241043602fc02200220093602f8022009201736000020024104360280032015200241f8026a107720022802fc02220520022802800322096b2015490d0220022802f802210a0c030b024020022802bc02450d00200910350b41012109200a21050b20081035200521010c0d0b200920156a220a2009490d082005410174220b200a200b200a4b1b220b4100480d080240024020050d000240200b0d004101210a0c020b200b1033220a0d010c0b0b20022802f802210a2005200b460d00200a2005200b1037220a450d0a0b2002200b3602fc022002200a3602f8020b200a20096a20012015109d081a2002200920156a360280032012200241f8026a10772012450d0220142012410c6c6a21032014210a0340200a2802002104200a41086a2802002209200241f8026a10770240024020022802fc02220b20022802800322056b2009490d0020022802f8022107200b210c0c010b200520096a22072005490d09200b410174220c2007200c20074b1b220c4100480d0902400240200b0d000240200c0d00410121070c020b200c10332207450d0c0c010b20022802f8022107200b200c460d002007200b200c10372207450d0b0b2002200c3602fc02200220073602f8020b200720056a20042009109d081a2002200520096a220936028003200a410c6a220a2003470d000c050b0b200920084190cdc4001042000b1045000b20022802fc02210c20022802800321090c010b41012109410521170c010b02400240200c20096b4104490d0020022802f802210a200c21050c010b200941046a220a2009490d03200c4101742205200a2005200a4b1b22054100480d0302400240200c0d00024020050d004101210a0c020b20051033220a450d060c010b20022802f802210a200c2005460d00200a200c20051037220a450d050b200220053602fc022002200a3602f8020b200a20096a20183600002002200941046a220b3602800302402005200b6b41034b0d00200b41046a2207200b490d032005410174220c2007200c20074b1b22074100480d030240024020050d00024020070d004101210a0c020b20071033220a450d060c010b20052007460d00200a200520071037220a450d050b200220073602fc022002200a3602f8020b200a200b6a20193600002002200941086a2205360280030240024020022802fc02220b20056b4104490d0020022802f802210a200b21070c010b200541046a220a2005490d03200b4101742207200a2007200a4b1b22074100480d0302400240200b0d00024020070d004101210a0c020b20071033220a450d060c010b20022802f802210a200b2007460d00200a200b20071037220a450d050b200220073602fc022002200a3602f8020b200a20056a2011360000200241f8026a41e9dabdf306200241206a200a2009410c6a10bc04410121090240024020022d00f8024101460d00410321050c010b200241f6026a20022d00fb023a0000200241b8026a41086a2002418c036a290200370300200241c8026a20024194036a290200370300200241d0026a2002419c036a290200370300200241d8026a200241a4036a290200370300200241e0026a200241ac036a290200370300200241e5026a200241b1036a290000370000200220022f00f9023b01f4022002200241f8026a410c6a2902003703b802200241f8026a41086a280200210b4100210920022802fc0221050b200241b4026a41026a220c200241f4026a41026a2d00003a0000200241f8016a41086a2204200241b8026a41086a290300370300200241f8016a41106a2203200241b8026a41106a290300370300200241f8016a41186a221a200241b8026a41186a290300370300200241f8016a41206a221b200241b8026a41206a290300370300200241f8016a41286a221c200241b8026a41286a290300370300200241f8016a41306a200241b8026a41306a290300370300200220022f01f4023b01b402200220022903b8023703f801024020090d00200241f4016a41026a200c2d00003a0000200241f8026a41086a2004290300370300200241f8026a41106a2003290300370300200241f8026a41186a201a290300370300200241f8026a41206a201b290300370300200241f8026a41286a201c290300370300200241f8026a412d6a200241f8016a412d6a290000370000200220022f01b4023b01f401200220022903f8013703f80202402007450d00200a10350b200220022f01f4013b01b8022002200241f6016a2d00003a00ba02410021090c020b02402007450d00200a10350b02402016450d00200110350b02402012450d002012410c6c210a2014210903400240200941046a280200450d00200928020010350b2009410c6a2109200a41746a220a0d000b0b4101210902402013450d002013410c6c450d00201410350b20052117200b21010b0b200241b8016a41086a220a200241f8026a41086a290300370300200241b8016a41106a2207200241f8026a41106a290300370300200241b8016a41186a220c200241f8026a41186a290300370300200241b8016a41206a2204200241f8026a41206a290300370300200241b8016a41286a2203200241f8026a41286a290300370300200241b8016a412d6a221a200241f8026a412d6a290000370000200220022d00ba023a00f201200220022f01b8023b01f001200220022903f8023703b80102400240024020090d00200241d0006a41186a2012360200200241d0006a41146a2013360200200241d0006a41106a2014360200200241d0006a410c6a2015360200200241d0006a41086a2016360200200241fa006a20022d00f2013a0000200241ff006a200b360000200241fb006a200536000020024183016a20022903b8013700002002418b016a200a29030037000020024193016a20072903003700002002419b016a200c290300370000200241a3016a2004290300370000200241ab016a2003290300370000200241b0016a201a29000037000020022011360274200220193602702002201836026c2002200136025420022017360250200220022f01f0013b01780240410028028cb54c4103490d00200241b8026a411c6a410f360200200241b8026a41146a410d360200200241b8026a410c6a410d3602002002410d3602bc022002200241d0006a3602d0022002200241c8006a3602c8022002200241cc006a3602c0022002200241c4006a3602b8024100280298b54c21094100280294b54c210a4100280290b54c2105200241b8036a418104360200200241b0036a42b580808010370300200241ac036a4184cac400360200200241a4036a4210370200200241a0036a41f4c9c40036020020024198036a420437030020024188036a4204370300200241f8026a41086a4108360200200241f8026a411c6a200241b8026a360200200241bccdc40036028403200241ecc9c4003602fc02200241033602f802200a41aca2c000200541024622051b200241f8026a200941c4a2c00020051b2802101102000b2002411336029004200242023703e00320024194046a200241d0006a41e800109d081a2002200241f8026a3602f801200241b8026a200241f8016a10b90320022802b80220022802bc0220022802c00210a004210a20024190046a10ba024107210941062117200a0d010c020b4107210920174107460d010b410410332209450d022009200636000020094104410810372209450d02200941003600044100200d2009ad4280808080800184101620091035201721090b200810350c040b103e000b103c000b410821090b0b2000200136020420002009360200200241c0066a24000bef0401017f230041306b220224000240024002400240024002400240024020002802000e0701020304050600010b2001411c6a2802002100200128021821012002412c6a4100360200200241b0b4cc003602282002420137021c200241e4cac40036021820012000200241186a104321010c060b2002200041046a36020c2002410c3602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420137021c200241eccac4003602182002200241106a36022820012000200241186a104321010c050b2002200041046a36020c2002410c3602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420237021c200241f4cac4003602182002200241106a36022820012000200241186a104321010c040b2002200028020436020c200241013602142001411c6a280200210020022002410c6a360210200128021821012002412c6a41013602002002420237021c20024184cbc4003602182002200241106a36022820012000200241186a104321010c030b2001411c6a2802002100200128021821012002412c6a4100360200200241b0b4cc003602282002420137021c20024194cbc40036021820012000200241186a104321010c020b2001411c6a2802002100200128021821012002412c6a4100360200200241b0b4cc003602282002420137021c2002419ccbc40036021820012000200241186a104321010c010b2001411c6a2802002100200128021821012002412c6a4100360200200241b0b4cc003602282002420137021c200241a4cbc40036021820012000200241186a104321010b200241306a240020010ba50301067f230041106b22022400024002400240200128020022030d00410121040c010b0240200141086a28020041056a2204417f4c0d0020040d0141002104410121050c020b1044000b2004103322050d001045000b200241003602082002200536020020022004360204024002400240024020030d00024020040d00410110332205450d0420024101360204200220053602000b200541003a0000410121040c010b024020040d00410110332205450d0320024101360204200220053602000b200541013a000020024101360208200141086a2802002204200210770240024020022802042206200228020822056b2004490d00200228020021010c010b200520046a22012005490d02200641017422072001200720014b1b22074100480d020240024020060d00024020070d00410121010c020b2007103322010d010c050b2002280200210120062007460d0020012006200710372201450d040b20022007360204200220013602000b200120056a20032004109d081a200520046a21040b20002002290300370200200041086a2004360200200241106a24000f0b103e000b103c000bde940111027f017e087f017e017f027e037f017e0a7f037e087f027e017f027e037f017e187f230041c0076b22002400200041003602e805200042083703e005200041003602f805200042013703f00541f7edcb00ad4280808080f00084100122012900002102200041f0066a41086a2203200141086a290000370300200020023703f0062001103541f393ca00ad4280808080a00184100122012900002102200041a0076a41086a2204200141086a290000370300200020023703a00720011035024002400240024002400240024002400240412010332201450d00200120002903f006370000200120002903a007370010200141086a2003290300370000200141186a22052004290300370000412010332203450d0020032001290000370000200341186a2005290000370000200341106a200141106a290000370000200341086a200141086a290000370000200041b0066a41026a220420004198026a41026a2d00003a0000200020002f0098023b01b006200041d0066a41106a42a0808080800437030041002106200041003a00e806200020013602dc06200042a080808080043702d406200020033602d006200041eb066a20042d00003a0000200020002f01b0063b00e90620004198026a200041d0066a10c701024002400240024002402000280298024101470d0020004198026a410472210741012108410821094100210a034020004180066a41206a200741206a28020036020020004180066a41186a2201200741186a290200220237030020004180066a41106a2205200741106a290200220b37030020004180066a41086a220c200741086a290200220d37030020002007290200220e37038006200041f0066a41186a220f2002370300200041f0066a41106a2210200b370300200041f0066a41086a2211200d3703002000200e3703f00620004198026a41186a2203200129030037030020004198026a41106a2204200529030037030020004198026a41086a2205200c290300370300200020002903800637039802200041f0066a10c801210241201033220c450d02200c20002903f006370000200c41186a200f290300370000200c41106a2010290300370000200c41086a2011290300370000200041a0076a41086a2005290300220b370300200041a0076a41106a2004290300220d370300200041a0076a41186a2003290300220e370300200020002903980222123703a0072003200e3703002004200d3703002005200b37030020002012370398020240200a20002802e405470d00200041e0056a200a4101108b0120002802e005210920002802e805210a0b2009200a41386c6a22012002370300200529030021022004290300210b2003290300210d200029039802210e2001412c6a4281808080103702002001200c3602282001200e370308200141206a200d370300200141186a200b370300200141106a20023703002000200a41016a220a3602e8052003200f2903003703002004201029030037030020052011290300370300200020002903f006370398020240200620002802f405470d00200041f0056a20064101108a0120002802f005210820002802f80521060b200820064105746a2201200029039802370000200141186a2003290300370000200141106a2004290300370000200141086a20052903003700002000200641016a22063602f80520004198026a200041d0066a10c7012000280298024101460d000b0b024020002802d406450d0020002802d00610350b024020002802e006450d0020002802dc0610350b41f7edcb00ad4280808080f00084100122012900002102200041f0066a41086a2203200141086a290000370300200020023703f0062001103541cca9c000ad4280808080a00184100122012900002102200041a0076a41086a2204200141086a290000370300200020023703a00720011035412010332201450d04200120002903f006370000200120002903a007370010200141086a2003290300370000200141186a22052004290300370000412010332203450d0420032001290000370000200341186a2005290000370000200341106a200141106a290000370000200341086a200141086a29000037000020004188026a41026a220520004198026a41026a2d00003a0000200020002f0098023b01880220004198026a41106a220442a08080808004370300200041003a00b002200020013602a402200042a0808080800437029c022000200336029802200041b3026a20052d00003a0000200020002f0188023b00b102200041e0056a20004198026a10c90120004198026a41186a220642003703002004420037030020004198026a41086a22014200370300200042003703980241f7edcb00ad4280808080f00084220210012205290000210b200041f0066a41086a2203200541086a2900003703002000200b3703f0062005103520012003290300370300200020002903f0063703980241c1edcb00ad4280808080e001841001220c290000210b200041a0076a41086a2205200c41086a2900003703002000200b3703a007200c1035200420002903a007220b37030020004180066a41086a2207200129030037030020004180066a41106a220a200b37030020004180066a41186a220f2005290300370300200020002903980237038006200041b0016a20004180066a412010c00120002802b401211320002802b0012114200642003703002004420037030020014200370300200042003703980220021001220c29000021022003200c41086a290000370300200020023703f006200c103520012003290300370300200020002903f0063703980241cfedcb00ad4280808080d002841001220329000021022005200341086a290000370300200020023703a00720031035200420002903a007220237030020072001290300370300200a2002370300200f2005290300370300200020002903980237038006200041a8016a20004180066a412010c00120002802ac01210520002802a801210c20002802f005211520002802f405211620002802e005211720002802e405211820002802f805210120002802e8052119200041003602d801200041003602d001201920016aad42e0007e2202422088a70d052002a72203417f4c0d054108210402402003450d00200310332204450d050b20054104200c1b221a41014b211b200041003602d806200020043602d0062000200341e0006e3602d406200041003602a807200042083703a007200041a0076a410020014105742205410575109b0120002802a807210902402001450d00200541606a410576211c20002802a007200941d8006c6a210c200041c8026a2103200041c0026a210841002104201521010340200041b0066a41186a2206200141186a2207290000370300200041b0066a41106a220a200141106a220f290000370300200041b0066a41086a2210200141086a2211290000370300200020012900003703b00620004180066a41186a200729000037030020004180066a41106a200f29000037030020004180066a41086a20112900003703002000200129000037038006200041d0016a20004180066a200410840320004198026a41086a420037030020004198026a41106a420037030020004198026a41186a420037030020004198026a41206a420037030020084200370300200341186a2006290300370300200341106a200a290300370300200341086a2010290300370300200320002903b0063703002000420037039802200c20004198026a41d000109d08220c41d0006a41003a0000200c41d8006a210c200141206a2101200441016a2104200541606a22050d000b2009201c6a41016a21090b201a4101201b1b2101200020093602a8070240201641ffffff3f71450d00201510350b200041f0066a41086a200041a0076a41086a2802002203360200200020002903a0073703f0060240024020032001490d00200041d0066a20002802d806201941386c220341386d10a40120002802d006210420002802d8062101200041ac026a200041f0066a3602002000201720036a3602a402200020173602a0022000201836029c0220002017360298022000200041d0016a3602a80220004180066a41086a20013602002000200041d8066a3602840620002004200141e0006c6a3602800620004198026a20004180066a109a042013410020141b2215ad42307e2202422088a70d072002a72203417f4c0d0720002802f80621010240024020030d00410821080c010b200310332208450d070b200041003602980720002008360290072000200341306e360294072015412c6c2203417f4c0d070240024020030d00410421130c010b200310332213450d070b41002117200041003602c001200020153602bc01200020133602b801410021142001201520012015491b221c0d010c040b024020002802f4062201450d00200141d8006c450d0020002802f00610350b024020002802d8062201450d00200141e0006c210320002802d00641346a21010340024020012802002204450d00200441c8006c450d002001417c6a28020010350b200141e0006a2101200341a07f6a22030d000b0b024020002802d4062201450d00200141e0006c450d0020002802d00610350b200041d0016a10b10102402019450d00201941386c21032017412c6a210103400240200128020041ffffff3f71450d002001417c6a28020010350b200141386a2101200341486a22030d000b0b410021082018450d02201841386c450d02201710350c040b20004198026a41186a211a20004198026a41106a210920004198026a41086a211b41002116034020002802f006210402402001450d00200141d8006c21032004210103400240200141d0006a2d00000d0002400240200141206a290300220b200141286a290300220d8450450d0042002102427f210b427f210d0c010b427f210220004198016a427f427f200b200d10980820004198016a41086a290300210d200029039801210b0b2001200b3703002001200d370308200141106a2002370300200141186a20023703000b200141d8006a2101200341a87f6a22030d000b0b0240024020002802d8062201450d0020002802d0062205200141e0006c6a210a0340024020052802382201450d00200141c8006c2104200528023041206a2101034020002802f806220c200128020022034d0d04024020002802f006200341d8006c6a22032d00500d0020032903202202200341286a290300220b84500d0020004198026a2005290310200541186a2903002005290300200541086a2903002002200b109b04200320032903002202427f2002427f20002903a002200028029802410146220c1b220d7c220b200b2002542206200341086a22072903002202427f2009290300200c1b220e7c2006ad7c220b200254200b2002511b220c1b200d200e845022061b37030020072002427f200b200c1b20061b3703000b200141c8006a2101200441b87f6a22040d000b0b200541e0006a2205200a470d000b20002802f00621040b201641016a211620002802f80641d8006c2101200441a87f6a210303402001450d05200141a87f6a2101200341d8006a2103200441d0006a2105200441d8006a220c210420052d00000d000b02402001450d00200341086a2903002102200341186a290300210b200341106a290300210d2003290300210e4100210403400240200c20046a220541d0006a2d00000d00200541086a29030022122002200e2002200d200b2005290300221d2012200541106a290300221e200541186a290300221f109c0441ff017141014622061b2102201d200e20061b210e201f200b20061b210b201e200d20061b210d2005200320061b21030b2001200441d8006a2204470d000b2003450d050b200341013a0050024020002802d8062201450d0020002802d0062204200141e0006c6a21182003410c6a2110200341306a21110340200441e0006a2119024020042802382205450d0020042802302101200541c8006c210503400240024020102001460d00200141246a2011412010a0080d010b200441186a220c290300210e200341086a220629030021022004290310210d2003290300210b20032903102112200141186a200341186a2207290300370300200141106a20123703002001200242002002200e7d200b200d54ad7d2212200b200d7d221d200b56201220025620122002511b220a1b200d200e8450220f1b3703082001200b4200201d200a1b200f1b370300200629030021022007290300210b2003290300210d20042003290310370320200441286a200b3703002004200d370310200c20023703000b200141c8006a2101200541b87f6a22050d000b0b2019210420192018470d000b0b201a200341c8006a2900003703002009200341c0006a290000370300201b200341386a2900003703002000200329003037039802200341286a29030021022003290320210b02402014200028029407470d0020004190076a20144101108801200028029007210820002802980721140b2008201441306c6a2201200029039802370300201b290300210d2009290300210e201a29030021122001200b370320200141286a2002370300200141186a2012370300200141106a200e370300200141086a200d3703002000201441016a2214360298072016201c4f0d0420002802f80621010c010b0b2003200c41f4c4c8001042000b103c000b0c010b024020002802d8062201450d0020002802d0062210200141e0006c6a2115201441306c21192000418c066a221841186a2116201841106a211a201841086a211b4100211703402018201029003c3700002016201041d4006a290000370000201a201041cc006a290000370000201b201041c4006a29000037000020004100360288062000420237038006024020102802382201450d002010280230220a200141c8006c6a2111201041106a2109410021074102210f0340200a220641246a2104200641c8006a210a410021052019210320082101024003402003450d01024020042001460d0020012004412010a008210c200541016a2105200341506a2103200141306a2101200c0d010b0b41ffff032103024020092006109d040d00410021032006290310201029032085200641186a290300201041286a29030085844200520d0020004198026a42ffff0342002006290300200641086a2903002009290300200941086a290300109b04427f20002903a00220002802980241014622011b2202a7417f200242808004544100427f20004198026a41106a29030020011b501b1b21030b20004198026a41186a22042006413c6a29000037030020004198026a41106a2205200641346a29000037030020004198026a41086a220c2006412c6a290000370300200020062900243703980202402007200028028406470d0020004180066a20074101109e01200028028006210f20002802880621070b200f200741226c6a2201200029039802370100200c29030021022005290300210b2004290300210d200120033b0120200141186a200d370100200141106a200b370100200141086a20023701002000200741016a2207360288060b200a2011470d000b0240024002402007450d002007417f200741808004491b210602400240200741226c22040d00410021030c010b200f41206a2101410021030340417f2003411074220320012f01004110746a220520052003491b4110762103200141226a21012004415e6a22040d000b0b200641ffff03712201450d012003417f73220a41ffff0371220320016e210c0240200120034b0d00200f41206a210141002103034020072003460d042001417f20012f01004110742204200c4110746a220520052004491b4110763b0100200141226a21012007200341016a2203470d000b0b0240200a200c20066c6b41ffff03712205450d00410021010340200f200120077041226c6a2203417f20032f01204110742203418080046a220420042003491b4110763b0120200141016a22012005490d000b0b20004198026a41286a220320004180066a41286a28020036020020004198026a41206a220420004180066a41206a29030037030020004198026a41186a220520004180066a41186a29030037030020004198026a41106a220c20004180066a41106a29030037030020004198026a41086a220620004180066a41086a2903003703002000200029038006370398020240201720002802bc01470d00200041b8016a2017410110980120002802b801211320002802c00121170b20132017412c6c6a2201200029039802370200200141286a2003280200360200200141206a2004290300370200200141186a2005290300370200200141106a200c290300370200200141086a20062903003702002000201741016a22173602c0010c030b2000280284062201450d02200141226c450d02200f10350c020b41f0b8c80041194194c5c800103f000b200320074184c5c8001042000b201041e0006a22102015470d000b20002802bc0121150b2000280294072105024020002802f4062201450d00200141d8006c450d0020002802f00610350b024020002802d8062201450d00200141e0006c210320002802d00641346a21010340024020012802002204450d00200441c8006c450d002001417c6a28020010350b200141e0006a2101200341a07f6a22030d000b0b024020002802d4062201450d00200141e0006c450d0020002802d00610350b200041d0016a10b1010b2008450d0820004198026a41186a220c420037030020004198026a41106a2220420037030020004198026a41086a22014200370300200042003703980241f7edcb00ad4280808080f00084220b1001220329000021022001200341086a2900003703002000200237039802200310354192aac000ad4280808080a00284100122042900002102200041a0076a41086a2203200441086a290000370300200020023703a00720041035202020002903a007220237030020004180066a41086a2207200129030037030020004180066a41106a220a200237030020004180066a41186a220f2003290300370300200020002903980237038006200041f0066a20004180066a10fe0120002802f0062206450d07200020002902f406220d3702ec01200020063602e801200c420037030020204200370300200142003703002000420037039802200b1001220429000021022001200441086a29000037030020002002370398022004103541a4aac000ad4280808080a002841001220429000021022003200441086a290000370300200020023703a00720041035202020002903a007370000202041086a200329030037000020072001290300370300200a2020290300370300200f200c290300370300200020002903980237038006200041f0066a20004180066a10fe0120002802f0062201450d06200020002902f4063702fc01200020013602f801200041003602a002200042013703980220004198026a4100201441306c220441306d108a0120002802a002212102402014450d0020002802980220214105746a2101200821030340200341086a2900002102200341106a290000210b2003290000210d200141186a200341186a290000370000200141106a200b370000200141086a20023700002001200d370000202141016a2121200141206a2101200341306a2103200441506a22040d000b0b200020213602a00202402005450d00200541306c450d00200810350b200028029c0221222000280298022123200041003602a807200042043703a007200041a0076a41002017412c6c2203412c6d10980120002802a007210420002802a80721012000201320036a3602a402200020133602a0022000201536029c0220002013360298022000200041f0066a3602a80220004180066a41086a20013602002000200041a0076a41086a36028406200020042001412c6c6a3602800620004198026a20004180066a109d0220004188026a41086a220120002802a807360200200020002903a0073703880220004188026a10ab0220004198026a2023202120002802880222242001280200220110cc01200041e0056a41086a20004198026a41086a220a28020036020020002000290398023703e00510142203280000210420031035024020044106702225450d00410021260340024020010d00410021010c020b20242001412c6c6a212742002128420021290240034002400240202441086a222a28020041306c22030d004200210b420021020c010b202428020041206a21014200210b420021020340427f2002200141086a2903007c200b20012903007c220d200b542204ad7c220b2004200b200254200b2002511b22041b2102427f200d20041b210b200141306a2101200341506a22030d000b0b2000200041e0056a3602a0074200212b4200212c02400240202a28020022014102490d002024280200210802400240200141306c22050d004200210e4200210d0c010b200841206a21014200210e200521034200210d0340427f200d200141086a2903007c200e20012903007c2212200e542204ad7c220e2004200e200d54200e200d511b22041b210d427f201220041b210e200141306a2101200341506a22030d000b0b2024410c6a2106200820056a21112008210f024002400240024002400240024003400240200f220c2011470d004100212d4108212e0c020b200c41306a210f200c41206a290300200c41286a29030084500d0020002802e0052207450d0020002802e40521100340200741086a210320072f010622094105742101410021040240024003402001450d01200c2003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21090b2010450d022010417f6a2110200720094102746a41c8056a28020021070c010b0b0b200720044105746a220141f0026a2903002112200141e8026a290300211d41101033222e450d0d202e201d370300202e2012370308200042818080801037029c022000202e360298024101211902400340200f220c2011460d01200c41306a210f200c41206a290300200c41286a29030084500d0020002802a00722012802002207450d00200128020421100340200741086a210320072f010622094105742101410021040240024003402001450d01200c2003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21090b2010450d022010417f6a2110200720094102746a41c8056a28020021070c010b0b200720044105746a220141f0026a2903002112200141e8026a290300211d02402019200028029c02470d0020004198026a20194101109a01200028029802212e0b202e20194104746a220120123703082001201d3703002000201941016a22193602a0020c000b0b200028029c02212d20190d010b200b212b2002212c0c010b20194104742203450d01202e2109024020194101460d00202e41106a2101200341706a2103202e21090340200920012009290300200129030056200941086a2903002212200141086a290300221d562012201d511b1b2109200141106a2101200341706a22030d000b2009450d020b20002802a00721180240024003402008220c2011460d01200c41306a210820182802002219450d002019210720182802042217210f0340200741086a210320072f01062210410574210141002104024003402001450d01200c2003412010a0082205450d05200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d01200f417f6a210f200720104102746a41c8056a28020021070c000b0b0b41acc6c800413241e0c6c8001064000b200720044105746a220141f0026a2903002112200141e8026a290300211d024020082011460d0003402008220c41306a2108201921072017210f02400340200741086a210320072f010622104105742101410021040240024003402001450d01200c2003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d02200f417f6a210f200720104102746a41c8056a28020021070c010b0b200720044105746a220141f0026a290300221e2012201d200141e8026a290300221f562012201e562012201e511b22011b2112201f201d20011b211d0b20082011470d000b0b427f4200200941086a290300221e20127d20092903002212201d54ad7d221f2012201d7d221d201256201f201e56201f201e511b22011b221242002002200d7d200b200e54ad7d220d200b200e7d220e200b56200d200256200d2002511b22031b7c4200201d20011b220d4200200e20031b7c220e200d542201ad7c220d2001200d201254200d2012511b22011b212c427f200e20011b212b0b202428020021010240202a280200220341306c2204450d00200120046a211c03402001210c024020002802a00722012802002207450d002001280204210f0340200741086a210320072f010622104105742101410021040240024003402001450d01200c2003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d02200f417f6a210f200720104102746a41c8056a28020021070c010b0b200720044105746a220141e8026a220342002003290300220d200c29032022127d220e200e200d56200141f0026a2203290300220e200c41286a2903007d200d201254ad7d220d200e56200d200e511b22041b37030020034200200d20041b37030020014180036a222f2802002207450d00200141f8026a28020021014100210341002104034002400240024020062001460d0020012006412010a008450d0020030d01410021030c020b200341016a21030c010b200420036b220520074f0d0620004198026a41286a220f2001200341506c6a220541286a221029030037030020004198026a41206a2211200541206a220829030037030020004198026a41186a2209200541186a221929030037030020004198026a41106a2217200541106a2218290300370300200a200541086a22152903003703002000200529030037039802200141086a2216290300210d200141106a221a290300210e200141186a221b2903002112200141206a2213290300211d200141286a2214290300211e200520012903003703002010201e3703002008201d370300201920123703002018200e3703002015200d3703002014200f29030037030020132011290300370300201b2009290300370300201a20172903003703002016200a29030037030020012000290398023703000b200141306a21012007200441016a2204470d000b2003450d00202f280200200720036b2201490d00202f20013602000b200c4200370320200c41286a4200370300200c41306a2201201c470d000b202a2802002103202428020021010b2000200041a0076a36028006200020004180066a360298022001200320004198026a410041202003676b109e04202a2802002215417f6a21182024280200220c201541306c22016a2109024020010d004200210d4200210e0c040b20002802a007221728020021194200210d410021084200210e200c2107034002402019450d00201728020421102019210f0340200f41086a2103200f2f010622114105742101410021040240024003402001450d0120072003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21110b2010450d022010417f6a2110200f20114102746a41c8056a280200210f0c010b0b200041e8006a200f20044105746a220141f0026a290300223042002008ad2212420010840820004188016a200141e8026a290300221e420020124200108408200041f8006a42004200201e42001084084200427f20002903880120002903702000290380018442005220004188016a41086a2903002212200029036820002903787c7c221d2012547222011b2212200d7d221f201f201256427f201d20011b221d200e7d2012200d54ad7d2212201d562012201d511b22011b200b564200201220011b221220025620122002511b0d04427f200e20307c200d201e7c2212200d542201ad7c220d2001200d200e54200d200e511b22011b210e427f201220011b210d0b200841016a2108200741306a22072009470d000c040b0b41ecc5c8004130419cc6c8001064000b2005200741f485cc001042000b41002008417f6a2201200120084b1b21180b201520184d0d01200041386a200c201841306c6a220141286a290300221e4200201841016a2211ad22124200108408200041d8006a2001290320221d420020124200108408200041c8006a42004200201d42001084084200427f2002200e7c200b200d7c220d200b542201ad7c220b2001200b200254200b2002511b22011b2202427f200041d8006a41086a290300220b200029033820002903487c7c220e2000290340200029035084420052200e200b547222031b7d427f200d20011b220b427f200029035820031b220e54ad7d220d200b200e7d220e200b56200d200256200d2002511b22011b211f4200200e20011b2130024003402009200c460d012011417f6a2111024020002802a00722012802002207450d002001280204210f0340200741086a210320072f010622104105742101410021040240024003402001450d01200c2003412010a0082205450d02200141606a2101200441016a2104200341206a21032005417f4a0d000b2004417f6a21100b200f450d02200f417f6a210f200720104102746a41c8056a28020021070c010b0b200041286a2030201f20124200109808200c41286a220f4200427f200041286a41086a2903002202201e7c2000290328220b201d7c220d200b542201ad7c220b2001200b200254200b2002511b22051b2202200720044105746a220141f0026a22032903007d427f200d20051b220b200141e8026a2204290300220e54ad7d220d200b200e7d220e200b56200d200256200d2002511b22051b220b370300200c4200200e20051b22023703202004427f2004290300220d20027c22022002200d54220520032903002202200b7c2005ad7c220b200254200b2002511b22051b3703002003427f200b20051b370300200041b0066a41186a2207200641186a290000370300200041b0066a41106a2210200641106a290000370300200041b0066a41086a2208200641086a290000370300200020062900003703b006200141f8026a2105200f2903002102200c290320210b024020014180036a22032802002204200141fc026a280200470d00200520044101108801200328020021040b2005280200200441306c6a220120002903b0063703002001200b370320200141186a2007290300370300200141106a2010290300370300200141086a2008290300370300200141286a20023703002003200328020041016a3602000b200c41306a210c20110d000b0b202d41ffffffff0071450d00202e10350b202c2029202b202856202c202956202c2029511b22011b2129202b202820011b21282024412c6a22242027460d020c010b0b2018201541f0c6c8001042000b02400240202641016a222620254f0d0020282029844200520d010b200028029002210120002802880221240c020b200028028802212420002802900221010c000b0b200028028c02212a200041003602f805200042043703f005200041f0056a41002001412c6c2203412c6d109801202420036a211a20002802f805211502400240024020010d002024210f0c010b20002802f0052015412c6c6a2111200041d0066a41186a211b200041d0066a41106a2113200041d0066a41086a21142024210f0340200f2802082104200f2802042116200f2802002118201b200f41246a2902003703002013200f411c6a2902003703002014200f41146a2902003703002000200f29020c3703d006200f412c6a210f2018450d01200041f0066a41186a221c201b290300370300200041f0066a41106a222f2013290300370300200041f0066a41086a222e2014290300370300200020002903d0063703f0062018200441306c22036a21050240024020030d00420021024200210b0c010b201841206a2101420021024200210b0340200141086a290300200b7c2001290300220b20027c2202200b54ad7c210b200141306a2101200341506a22030d000b0b02400240024020052018460d00200441306c2103201821010340200141286a290300210d200141206a290300210e200041b0066a41186a220c200141186a290300370300200041b0066a41106a2206200141106a290300370300200041b0066a41086a2207200141086a290300370300200020012903003703b006200e200d2002200b109f04220441ffff03710d02200141306a2101200341506a22030d000b0b4200210d410021014102211002402016450d00201641306c450d00201810354200210d0b4200211d410021050c010b200041a0076a41086a22052007290300370300200041a0076a41106a220a2006290300370300200041a0076a41186a2208200c290300370300200020002903b006220d370380062000200d3703a007412210332210450d04201020002903a007370100201020043b0120201041186a2008290300370100201041106a200a290300370100201041086a200529030037010020004281808080103702940720002010360290072004ad210d0240024020034130470d00200d42ffff0383210d4200211d410121050c010b200341a07f6a2117200d42ffff0383210e4200211d41012105410021040340200120046a220341d8006a290300210d200341d0006a2903002112200c200341c8006a2903003703002006200341c0006a2903003703002007200341386a2903003703002000200341306a2903003703b006024002402012200d2002200b109f04220a41ffff03710d00200e210d20172004460d030c010b20004180066a41086a2007290300220d37030020004180066a41106a2006290300221237030020004180066a41186a200c290300221e370300200020002903b006221f3703800620004198026a41186a2208201e37030020004198026a41106a2209201237030020004198026a41086a2219200d3703002000201f37039802200e200aad42ffff03837c220d200e54ad210e02402005200028029407470d0020004190076a20054101109e0120002802900721100b201d200e7c211d2010200541226c6a22032000290398023701002019290300210e200929030021122008290300211e2003200a3b0120200341186a201e370100200341106a2012370100200341086a200e3701002000200541016a22053602980720172004460d020b200441306a2104200d210e0c000b0b02402016450d00201641306c450d00201810350b20002802940721010b0240024042ffff03200d7d220b42ffff03564200201d200d42ffff0356ad7c7d220242005220025022031b4101470d00200d4281807c7c2202200d56201d200d42ffff0354ad7d220b201d56200d42feff03561b0d012005450d01200541226c20106a417e6a2203410020032f010041107422032002a7417f200242808004544100200b501b1b4110746b2204200420034b1b4110763b01000c010b2005450d00200541226c20106a417e6a2204417f20042f01004110742204200ba7417f200b4280800454410020031b1b4110746a220320032004491b4110763b01000b20004198026a41186a2203201c29030037030020004198026a41106a2204202f29030037030020004198026a41086a220c202e290300370300200020002903f00637039802201120013602042011200536020820112010360200201120002903980237020c201141146a200c2903003702002011411c6a2004290300370200201141246a2003290300370200201541016a21152011412c6a2111200f201a470d000b200020153602f8050c010b200020153602f805200f201a460d000340200f2201412c6a210f0240200141046a2802002203450d00200341306c450d00200128020010350b201a200f470d000b0b0240202a450d00202a412c6c450d00202410350b2015ad422c7e2202422088a70d012002a72201417f4c0d0120002802f405211720002802f00521090240024020010d00410421030c010b200110332203450d010b200041003602a807200020033602a00720002001412c6e3602a407200041a0076a4100201510980120002802a80721010240024020150d0020002802a00721080c010b20092015412c6c6a211120002802a00722082001412c6c6a210620012015410274417c6a4102766a2119200041a4026a2107200041b0066a41186a210a200041b0066a41106a210f200041b0066a41086a21102009210c0340200a200c41246a290200370300200f200c411c6a2902003703002010200c41146a2902003703002000200c29020c3703b006200c2802082203ad42227e2202422088a70d032002a72204417f4c0d03200c28020021010240024020040d00410221050c010b200410332205450d030b200c412c6a210c200041003602880620002005360280062000200441226e3602840620004180066a41002003109e01200028028806210402402003450d00200341226c2105200028028006200441226c6a21030340200141086a2901002102200141106a290100210b200141186a290100210d2001290100210e200341206a200141206a2f01003b0100200341186a200d370100200341106a200b370100200341086a20023701002003200e370100200341226a2103200441016a2104200141226a21012005415e6a22050d000b0b20004198026a41086a220120043602002000200029038006220237039802200741186a200a290300370200200741106a200f290300370200200741086a2010290300370200200720002903b006370200200641286a20004198026a41286a280200360200200641206a20004198026a41206a290300370200200641186a20004198026a41186a290300370200200641106a20004198026a41106a290300370200200641086a2001290300370200200620023702002006412c6a2106200c2011470d000b201941016a21010b20002802a407210441002103200041003602a807200042043703a007200041a0076a41002001412c6c2205412c6d10980120002802a007210c20002802a80721012000200820056a3602a402200020083602a0022000200436029c0220002008360298022000200041f0066a3602a80220004180066a41086a20013602002000200041a0076a41086a360284062000200c2001412c6c6a3602800620004198026a20004180066a109d0220002802a407211120004198026a2023202120002802a007221920002802a807220810cc0120002802a0022110200028029c02210a024002400240200028029802220f450d000240200a450d00200a2101200f2103034020032802c80521032001417f6a22010d000b200f2101200a21040340200120012f01064102746a41c8056a28020021012004417f6a22040d000b20004198026a21040c020b20004198026a2104200f2103200f21010c010b2000410036029c0220004198026a21040c010b2000200136029c02200041a4026a20012f0106360200200041003602a00220004100360298020b20004180066a41086a200441086a290200220237030020002004290200220b37038006200041b0026a200237030042002112200042003703a0022000200336029c0220004100360298022000200b3703a802200020103602b8020240024020100d00427f211d4200210d4200211e4200211f427f210e0c010b20002010417f6a3602b80220004198026a410020031b220c2802002104200c28020821060240024002400240200c28020c2205200c28020422012f01064f0d00200121030c010b034020012802002203450d02200441016a210420012f0104210520032101200520032f01064f0d000b0b2005ad4220862006ad8421020c010b2006ad2102410021030b2002422088a7220641016a21052002a721070240024020040d00200321010c010b200320054102746a41c8056a2802002101410021052004417f6a2204450d00034020012802c80521012004417f6a22040d000b0b200c200536020c200c2007360208200c2001360204200c4100360200200320064105746a41e8026a2101427f211d427f210e4200211e4200211f420021124200210d0340200041086a200141086a290300220b4200200129030022024200108408200041186a2002420020024200108408427f200d427f200041186a41086a29030022302000290308222c202c7c7c222c200b2000290310222984202984420052202c2030547222011b7c2012427f200029031820011b7c22302012542201ad7c221220012012200d542012200d511b22011b210d427f203020011b2112200b200e2002201d54200b200e54200b200e511b22011b210e2002201d20011b211d200b201f7c2002201e7c221e200254ad7c211f20002802b8022201450d0120002001417f6a3602b80220004198026a4100200028029c021b220c2802002104200c2802082106024002400240200c28020c2205200c28020422012f01064f0d00200121030c010b0240034020012802002203450d01200441016a210420012f0104210520032101200520032f0106490d020c000b0b2006ad2102410021030c010b2005ad4220862006ad8421020b2002422088a7220641016a21052002a721070240024020040d00200321010c010b200320054102746a41c8056a2802002101410021052004417f6a2204450d00034020012802c80521012004417f6a22040d000b0b200c200536020c200c2007360208200c2001360204200c4100360200200320064105746a41e8026a21010c000b0b02400240200f0d0041002110200041ac026a41003602002000410036029c020c010b02400240200a0d00200f21010c010b200a2101200f2103034020032802c80521032001417f6a22010d000b200f21010340200120012f01064102746a41c8056a2802002101200a417f6a220a0d000b2003210f0b200041b4026a20012f0106360200200041b0026a4100360200200041ac026a2001360200200041003602a802200042003703a0022000200f36029c0220004100360298020b200020103602b80220004198026a109e0202402008450d002008412c6c21032019210103400240200141046a2802002204450d00200441306c450d00200128020010350b2001412c6a2101200341546a22030d000b0b02402011450d002011412c6c450d00201910350b20002015360288062000201736028406200020093602800620004198026a20004180066a200041f8016a200041e8016a10fb0120002d0098024101460d03202120216a22012021490d012001417f4c0d01200041d8036a2802002131200041d4036a2802002107200041d0036a2802002127200041cc036a2802002132200041c8036a280200211b200041c4036a280200212f200041c0036a2802002133200041bc036a280200210a200041b8036a280200212d200041b4036a2802002134200041b0036a280200210f200041ac036a2802002126200041a8036a2802002135200041a4036a2802002110200041a0036a28020021252000419c036a280200213620004198036a280200211120004194036a280200213720004190036a28020021382000418c036a280200210820004188036a280200213920004184036a280200213a20004180036a2802002109200041fc026a280200213b200041f8026a280200213c200041f4026a2802002119200041f0026a280200213d200041ec026a280200213e200041e8026a2802002113200041e4026a280200212e200041e0026a280200213f200041dc026a2802002117200041d8026a2802002140200041d4026a2802002141200041d0026a2802002118200041cc026a2802002142200041c8026a2802002143200041c4026a2802002115200041c0026a2802002144200041bc026a2802002145200041b8026a2802002114200041b4026a2802002124200041b0026a2802002146200041ac026a2802002116200041a8026a2802002147200041a4026a2802002148200041a0026a280200211c200028029c02212a0240024020010d00410221060c010b200110332206450d010b4100210c2000410036028806200020063602800620002001410176360284062021450d02202320214105746a212120002802f001221a41057441606a41057641016a2104202321050340200541086a2900002102200541106a290000210b2005290000213020004198026a41186a200541186a29000037030020004198026a41106a200b37030020004198026a41086a20023703002000203037039802201a450d05200541206a21054100210320002802e80121010240034020004198026a2001460d01200120004198026a412010a008450d01200141206a21012004200341016a2203470d000c070b0b200341ffff034b0d050240200c200028028406470d0020004180066a200c4101108e012000280280062106200028028806210c0b2006200c4101746a20033b01002000200c41016a220c3602880620052021470d000c030b0b1045000b1044000b0240202241ffffff3f71450d00202310350b200041de016a20004188066a28020036010020002000290380063701d6010240024020002802e00522050d004100210c200041ac026a41003602002000410036029c020c010b20002802e805210c0240024020002802e40522030d00200521010c010b2003210120052104034020042802c80521042001417f6a22010d000b200521010340200120012f01064102746a41c8056a28020021012003417f6a22030d000b200421050b200041b4026a20012f0106360200200041b0026a4100360200200041ac026a2001360200200041003602a802200042003703a0022000200536029c0220004100360298020b2000200c3602b80220004198026a109e02024020002802fc0141ffffff3f71450d0020002802f80110350b024020002802ec0141ffffff3f71450d0020002802e80110350b200041b8016a41106a200041d0016a41106a2f01003b0100200041b8016a41086a200041d0016a41086a290100370300200020002901d0013703b801200041f0066a41086a2204200041c6016a280100360200200020002901be013703f00620004198026a41186a2205420037030020004198026a41106a220c420037030020004198026a41086a22014200370300200042003703980241f7edcb00ad4280808080f000841001220329000021022001200341086a29000037030020002002370398022003103541e4edcb00ad4280808080a00184100122032900002102200041a0076a41086a2206200341086a290000370300200020023703a00720031035202020002903a007370000202041086a200629030037000020004180066a41086a2203200129030037030020004180066a41106a2201200c29030037030020004180066a41186a220c2005290300370300200020002903980237038006200020004180066a412010c0012000280204210520002802002106200041a3026a2004280200360000200020002903f00637009b0220002000290098023703a007200020004198026a41076a2900003700a707200041b8056a200d370300200041b0056a2012370300200041a8056a201f370300200041a0056a201e37030020004198056a200e37030020004190056a201d370300200041b8036a41183a0000200041c0036a20002900a70737000020004188056a2005410020061b36020020004184056a203136020020004180056a2007360200200041fc046a2027360200200041f8046a2032360200200041f4046a201b360200200041f0046a202f360200200041ec046a2033360200200041e8046a200a360200200041e4046a202d360200200041e0046a2034360200200041dc046a200f360200200041d8046a2026360200200041d4046a2035360200200041d0046a2010360200200041cc046a2025360200200041c8046a2036360200200041c4046a2011360200200041c0046a2037360200200041bc046a2038360200200041b8046a2008360200200041b4046a2039360200200041b0046a203a360200200041ac046a2009360200200041a8046a203b360200200041a4046a203c360200200041a0046a20193602002000419c046a203d36020020004198046a203e36020020004194046a201336020020004190046a202e3602002000418c046a203f36020020004188046a201736020020004184046a204036020020004180046a2041360200200041fc036a2018360200200041f8036a2042360200200041f4036a2043360200200041f0036a2015360200200041ec036a2044360200200041e8036a2045360200200041e4036a2014360200200041e0036a2024360200200041dc036a2046360200200041d8036a2016360200200041d4036a2047360200200041d0036a2048360200200041cc036a201c360200200041c8036a202a360200200041073602b0032000420237038003200020002903a0073700b903200041d8056a200c290300370300200041d0056a2001290300370300200041c8056a2003290300370300200041c0056a200029038006370300200020004198026a3602d00620004180066a200041d0066a10b90320002802800620002802840620002802880610a0041a200041b0036a10ba020c050b0240024020002802e00522050d004100210c200041ac026a41003602002000410036029c020c010b20002802e805210c0240024020002802e40522030d00200521010c010b2003210120052104034020042802c80521042001417f6a22010d000b200521010340200120012f01064102746a41c8056a28020021012003417f6a22030d000b200421050b200041b4026a20012f0106360200200041b0026a4100360200200041ac026a2001360200200041003602a802200042003703a0022000200536029c0220004100360298020b2000200c3602b80220004198026a109e02202241ffffff3f71450d01202310350c010b0240202241ffffff3f71450d00202310350b024020002802840641808080807872418080808078460d00200610350b0240201c41ffffffff0171450d00202a10350b02402016450d002016410c6c450d00204710350b0240201441ffffffff0071450d00202410350b02402015450d00201541146c450d00204410350b02402018450d00201841186c450d00204210350b02402017450d002017411c6c450d00204010350b0240201341ffffff3f71450d00202e10350b02402019450d00201941246c450d00203d10350b02402009450d00200941286c450d00203b10350b02402008450d002008412c6c450d00203910350b02402011450d00201141306c450d00203710350b02402010450d00201041346c450d00202510350b0240200f450d00200f41386c450d00202610350b0240200a450d00200a413c6c450d00202d10350b0240201b41ffffff1f71450d00202f10350b02402007450d00200741c4006c450d00202710350b0240024020002802e00522050d004100210c200041ac026a41003602002000410036029c020c010b20002802e805210c0240024020002802e40522030d00200521010c010b2003210120052104034020042802c80521042001417f6a22010d000b200521010340200120012f01064102746a41c8056a28020021012003417f6a22030d000b200421050b200041b4026a20012f0106360200200041b0026a4100360200200041ac026a2001360200200041003602a802200042003703a0022000200536029c0220004100360298020b2000200c3602b80220004198026a109e020b024020002802fc0141ffffff3f71450d0020002802f80110350b20002802ec0141ffffff3f71450d0220002802e80110350c020b200d42ffffff3f83500d00200610350b02402005450d00200541306c450d00200810350b02402017450d002017412c6c21032013210103400240200141046a2802002204450d00200441226c450d00200128020010350b2001412c6a2101200341546a22030d000b0b2015450d002015412c6c450d00201310350b200041c0076a24000ba50a07027f017e047f017e017f047e027f230041e0006b220224002002411436020c2002419793ca00360208200241106a419793ca00ad4280808080c00284100510c201024002400240024002400240200228021022030d0042002104410821050c010b200228021421062002200241186a2802002207360224200220033602200240024002402007450d0020022007417f6a3602242002200341016a36022020032d00002107200241c8006a200241206a10e80320022802482208450d00200229024c2109200741ff01714101460d012009a72207450d00200741286c450d00200810350b20024100360230200242013703282002410936023c2002200241086a3602382002200241286a36024441012107200241dc006a41013602002002420137024c200241c888c2003602482002200241386a360258200241c4006a41e88ac500200241c8006a10431a200235023042208620023502288410060240200228022c450d00200228022810350b4102210a0c010b4101210a410021070b02402006450d00200310350b4108200820071b21054200200920071b210420070d00200a4101460d0020052802082203ad42287e2209422088a70d012009a72207417f4c0d01200528020021060240024020070d00410821050c010b200710332205450d030b02400240024002400240200741286e220820034f0d002008410174220a2003200a20034b1bad42287e2209422088a70d082009a7220a4100480d08200741274d0d01200841286c2207200a460d022007450d0120052007200a10372205450d090c020b2008ad210b20030d02420021090c030b200a10332205450d070b200a41286ead210b0b200341286c210a42002109410021080340200620086a22032903002104200341086a290300210c200341106a290300210d200341186a290300210e200520086a220741206a200341206a290300370300200741186a200e370300200741106a200d370300200741086a200c3703002007200437030020094280808080107c2109200a200841286a2208470d000b0b200b20098421040b2004422088a7220341286c4104722207417f4c0d00200710332208450d01200241003602502002200736024c200220083602482003200241c8006a10772002280250210702402003450d002005200341286c6a210f200228024c210620052103034002400240200620076b4120490d00200741206a2108200228024821102006210a0c010b200741206a22082007490d052006410174220a2008200a20084b1b220a4100480d050240024020060d000240200a0d00410121100c020b200a10332210450d080c010b200228024821102006200a460d0020102006200a10372210450d070b2002200a36024c200220103602480b201020076a22072003290000370000200741186a200341186a290000370000200741106a200341106a290000370000200741086a200341086a29000037000020022008360250200341206a290300210902400240200a20086b4108490d00200841086a2107200a21060c010b200841086a22072008490d05200a41017422062007200620074b1b22064100480d0502400240200a0d00024020060d00410121100c020b200610332210450d080c010b200a2006460d002010200a200610372210450d070b2002200636024c200220103602480b201020086a200937000020022007360250200f200341286a2203470d000b0b2007ad422086200235024884210902402004a72203450d00200341286c450d00200510350b200241e0006a240020090f0b1044000b1045000b103e000b103c000bbb0504037f017e087f037e23004180016b220224002002200110c40102400240024002402002280200450d00200041003602000c010b20022802042203200128020441286e2204200420034b1bad42287e2205422088a70d012005a72204417f4c0d010240024020040d00410821060c010b200410332206450d030b4100210720024100360210200220063602082002200441286e36020c0240024002402003450d0041002108034041002104200241003a0078200841016a210820012802042109417f210a034020092004460d03200241d8006a20046a2001280200220b2d00003a000020012009200a6a3602042001200b41016a3602002002200441016a220c3a0078200a417f6a210a200c2104200c4120470d000b200241386a41186a2204200241d8006a41186a290300370300200241386a41106a220a200241d8006a41106a290300370300200241386a41086a220d200241d8006a41086a290300370300200220022903583703382009200c6b220c4108490d03200b29000121052001200b41096a3602002001200c41786a360204200241186a41086a220c200d290300370300200241186a41106a2209200a290300370300200241186a41186a220a20042903003703002002200229033837031802402007200228020c470d00200241086a20074101108f0120022802082106200228021021070b2006200741286c6a22042002290318370300200c290300210e2009290300210f200a290300211020042005370320200441186a2010370300200441106a200f370300200441086a200e3703002002200741016a220736021020082003470d000b0b20002002290308370200200041086a200241086a41086a2802003602000c020b200441ff0171450d00200241003a00780b20004100360200200228020c2204450d00200441286c450d00200610350b20024180016a24000f0b1044000b1045000b8c0f05047f017e017f017e077f23004190016b22022400200241c8006a41186a22034200370300200241c8006a41106a22044200370300200241c8006a41086a220542003703002002420037034841a9d1cb00ad4280808080c0008422061001220729000021082005200741086a290000370300200220083703482007103541b7d1cb00ad4280808080b00184100122092900002108200241286a41086a2207200941086a2900003703002002200837032820091035200420022903282208370300200241f0006a41086a220a2005290300370300200241f0006a41106a220b2008370300200241f0006a41186a220c200729030037030020022002290348370370200241c8006a200241f0006a10dd0220022802482109200229024c21082003420037030020044200370300200542003703002002420037034820061001220329000021062005200341086a290000370300200220063703482003103541d8d1cb00ad4280808080a001841001220329000021062007200341086a2900003703002002200637032820031035200420022903282206370300200a2005290300370300200b2006370300200c200729030037030020022002290348370370200241c8006a200241f0006a10b10220022d00482105200c200241e1006a290000370300200b200241d9006a290000370300200a200241d1006a290000370300200220022900493703700240024020054101460d00200241286a41186a4200370300200241286a41106a420037030020074200370300200242003703280c010b200241286a41186a200c290300370300200241286a41106a200b2903003703002007200a290300370300200220022903703703280b200241086a41086a200241286a41086a290300370300200241086a41106a200241286a41106a290300370300200241086a41186a200241286a41186a2903003703002002200229032837030820024100360250200242013703480240410810332205450d002002410836024c20022005360248200542b8173700002002410836025020054108411010372205450d00200542c8013700082002411036024c20022005360248200241103602500240024002404100450d00411021070c010b411041017422074118200741184b1b22074100480d010240024041100d002007103322050d010c040b41102007460d0020054110200710372205450d030b2002200736024c200220053602480b2005420137001020024118360250024020074138714118470d00200741017422044120200441204b1b22044100480d010240024020070d00200410332205450d040c010b20072004460d0020052007200410372205450d030b2002200436024c200220053602480b2009410820091b210d20054204370018200241203602502008420020091b2208422088a72205200241c8006a10772002280250210302402005450d00200d200541286c6a210e410020036b210b200228024c2104410021050340200320056a210c024002402004200b6a4120490d002002280248210a200421090c010b200c41206a2207200c490d03200441017422092007200920074b1b22094100480d030240024020040d00024020090d004101210a0c020b20091033220a450d060c010b2002280248210a20042009460d00200a200420091037220a450d050b2002200936024c2002200a3602480b200a20036a20056a2204200d20056a2207290000370000200441186a200741186a290000370000200441106a200741106a290000370000200441086a200741086a2900003700002002200c41206a2204360250200741206a2903002106024002402009200b6a41606a41074d0d00200921040c010b200441086a220f2004490d0320094101742204200f2004200f4b1b22044100480d030240024020090d00024020040d004101210a0c020b20041033220a450d060c010b20092004460d00200a200920041037220a450d050b2002200436024c2002200a3602480b200a20036a20056a41206a20063700002002200c41286a360250200b41586a210b200541286a2105200e200741286a470d000b200320056a21030b02400240200228024c220420036b4120490d0020022802482107200421050c010b200341206a22052003490d01200441017422072005200720054b1b22054100480d010240024020040d00024020050d00410121070c020b200510332207450d040c010b2002280248210720042005460d0020072004200510372207450d030b2002200536024c200220073602480b200720036a22042002290308370000200441186a200241086a41186a290300370000200441106a200241086a41106a290300370000200441086a200241086a41086a2903003700002002200341206a22043602500240024020052004460d00200421050c010b200541016a22042005490d01200541017422092004200920044b1b22044100480d010240024020050d0041002105024020040d00410121070c020b200410332207450d040c010b20052004460d0020072005200410372207450d030b2002200436024c200220073602480b200720056a41013a0000200541016aad422086200235024884210602402008a72205450d00200541286c450d00200d10350b20024190016a240020060f0b103e000b103c000b8e0406047f017e017f017e047f027e230041f0006b22022400200241c0006a41186a22034200370300200241c0006a41106a22044200370300200241c0006a41086a220542003703002002420037034041a9d1cb00ad4280808080c0008422061001220729000021082005200741086a290000370300200220083703402007103541add1cb00ad4280808080a00184100122092900002108200241e0006a41086a2207200941086a2900003703002002200837036020091035200420022903602208370300200241206a41086a220a2005290300370300200241206a41106a220b2008370300200241206a41186a220c200729030037030020022002290340370320200241106a200241206a10e102200229031821082002290310210d2003420037030020044200370300200542003703002002420037034020061001220929000021062005200941086a290000370300200220063703402009103541c2d1cb00ad4280808080b001841001220929000021062007200941086a2900003703002002200637036020091035200420022903602206370300200a2005290300370300200b2006370300200c2007290300370300200220022903403703202002200241206a10e102200229030821062002290300210e02404108103322050d001045000b200520064200200ea71b200842c8017e4200200da71b7c370000200241f0006a24002005ad42808080808001840baf0b04047f017e0a7f017e230041b0016b2202240020024188016a41186a420037030020024188016a41106a2203420037030020024188016a41086a22044200370300200242003703880141fdd0cb00ad4280808080a00284100122052900002106200241e8006a41086a2207200541086a2900003703002002200637036820051035200420072903003703002002200229036837038801418fd1cb00ad4280808080c000841001220529000021062007200541086a2900003703002002200637036820051035200320022903682206370300200241106a41086a2004290300370300200241106a41106a2006370300200241106a41186a20072903003703002002200229038801370310200241203602342002200241106a360230200241386a200241106aad4280808080800484100510c2010240024002400240200228023822080d00410021030c010b200228023c21092002200241386a41086a28020036024c20022008360248200241086a200241c8006a10c4010240024020022802080d00200228020c220a200228024c220b41057622072007200a4b1b22074105742204417f4c0d040240024020070d00410121030c010b200410332203450d040b4100210c200241003602602002200736025c2002200336025802400240200a450d004100210d0340200b210541002107200241003a00a801200d41016a210d034020052007460d0320024188016a20076a200228024822042d00003a00002002200441016a3602482002200741016a22043a00a8012004210720044120470d000b200241e8006a41186a220e20024188016a41186a290300370300200241e8006a41106a220f20024188016a41106a290300370300200241e8006a41086a221020024188016a41086a29030037030020022002290388013703680240200c200228025c470d00200241d8006a200c4101108a01200228025821032002280260210c0b200520046b210b2003200c4105746a22072002290368370000200741186a200e290300370000200741106a200f290300370000200741086a20102903003700002002200c41016a220c360260200d200a470d000b2002200520046b36024c0b200229025c21062003450d010c020b2002410036024c0240200741ff0171450d00200241003a00a8010b0240200228025c41ffffff3f71450d00200310350b0b4100210320024100360270200242013703682002410936025c2002200241306a3602582002200241e8006a3602542002419c016a41013602002002420137028c01200241c888c200360288012002200241d8006a36029801200241d4006a41e88ac50020024188016a10431a20023502704220862002350268841006200228026c450d00200228026810350b2009450d00200810350b2006420020031b2206422088a7220741057422094104722204417f4c0d01200410332205450d002003410120031b210a20024100360290012002200436028c012002200536028801200720024188016a10770240024020070d002002280290012104200228028801210d0c010b410020022802900122046b2103200228028801210d200228028c012108200a210c0340200c21070240200820036a411f4b0d00024002400240200441206a22052004490d002008410174220c2005200c20054b1b22054100480d000240024020080d00024020050d004101210d0c020b20051033210d0c040b20082005470d020b200521080c030b103e000b200d200820051037210d0b20052108200d0d00103c000b200741206a210c200d20046a22052007290000370000200541186a200741186a290000370000200541106a200741106a290000370000200541086a200741086a290000370000200341606a2103200441206a2104200941606a22090d000b2002200836028c0120022004360290012002200d360288010b2004ad422086200dad8421110240200642ffffff3f83500d00200a10350b200241b0016a240020110f0b1045000b1044000bb70302037f047e23004180016b2202240041002103200241003a0040200041b0b4cc0020011b210402400240034020012003460d01200241206a20036a200420036a2d00003a00002002200341016a22003a00402000210320004120470d000b200241186a200241206a41186a22032903002205370300200241106a200241206a41106a22002903002206370300200241086a200241206a41086a2201290300220737030020022002290320220837030020032005370300200020063703002001200737030020022008370320200241f0006a200241206a10ed03200241206a200228027022032002280278108f0220022903202105200241e8006a280200210002402002280274450d00200310350b4104103322030d011045000b0240200341ff0171450d00200241003a00400b200241346a41023602002002410c6a410436020020024202370224200241f0b2c30036022020024104360204200241d0b4c30036020020024100360274200241b0b4cc00360270200220023602302002200241f0006a360208200241206a4180b3c300104c000b20032000410020054201511b36000020024180016a24002003ad4280808080c000840bc20503027f017e047f230041d0006b2202240041d1c4c700ad4280808080e00084100122032900002104200241086a200341086a290000370300200220043703002003103541d7c4c700ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bec2d05057f047e067f017e1e7f230041900f6b22022400024020010d0041b0b4cc0021000b200220003602282002200136022c41002103200241003a00f80b2001417f6a210402400240024002400240024002400240024002400240034020012003460d01200241d80b6a20036a200020036a22052d00003a00002002200541016a3602282002200341016a22053a00f80b2002200436022c2004417f6a21042005210320054120470d000b200241306a41086a200241d80b6a41086a290300370300200241306a41106a200241d80b6a41106a290300370300200241306a41186a200241d80b6a41186a290300370300200220022903d80b37033041002103200241003a00f80b200120056b2106200020056a2100417f2101034020062003460d02200241d80b6a20036a200020036a22052d00003a00002002200420036b36022c2002200541016a3602282002200341016a22053a00f80b2001417f6a21012005210320054120470d000b200241d0006a41086a200241d80b6a41086a290300370300200241d0006a41106a200241d80b6a41106a290300370300200241d0006a41186a200241d80b6a41186a290300370300200220022903d80b370350200420056b220441016a4110490d042002200020056a220341106a3602282002200441716a220536022c20054108490d0720032900002107200341086a29000021082002200441696a36022c2002200341186a360228200341106a2900002109200241206a200241286a10c40120022802200d08200228022c220420022802242203490d082003417f4c0d0520030d0241002104410121060c030b0240200341ff0171450d00200241003a00f80b0b200241ec0b6a41023602002002418c096a4104360200200242023702dc0b200241f0b2c3003602d80b2002410436028409200241e8b4c30036028009200241003602cc06200241b0b4cc003602c806200220024180096a3602e80b2002200241c8066a36028809200241d80b6a4180b3c300104c000b0240200341ff0171450d00200241003a00f80b0b200241ec0b6a41023602002002418c096a4104360200200242023702dc0b200241f0b2c3003602d80b2002410436028409200241e8b4c30036028009200241003602cc06200241b0b4cc003602c806200220024180096a3602e80b2002200241c8066a36028809200241d80b6a4180b3c300104c000b200310392206450d032006200228022822052003109d081a2002200420036b36022c2002200520036a360228200321040b2006450d042003ad4220862004ad84210a200241f0006a41186a200241306a41186a290300370300200241f0006a41106a200241306a41106a290300370300200241f0006a41086a200241306a41086a2903003703002002200229033037037020024190016a41186a200241d0006a41186a29030037030020024190016a41106a200241d0006a41106a29030037030020024190016a41086a200241d0006a41086a2903003703002002200229035037039001200220093703b801200220093703b001200241d80b6a41186a4200370300200241d80b6a41106a22044200370300200241d80b6a41086a22034200370300200242003703d80b41f1d8cb00ad42808080809001841001220529000021092003200541086a290000370300200220093703d80b2005103541e2d8cb00ad4280808080f00184100122052900002109200241c8066a41086a2201200541086a290000370300200220093703c80620051035200420022903c806220937030020024180096a41086a200329030037030020024180096a41106a200937030020024180096a41186a2001290300370300200220022903d80b37038009200241d80b6a20024180096a10da0220022d00e00c210320024180096a200241d80b6a418801109d081a2002200241d80b6a418c016a2800003600cb06200220022800e10c3602c8060240024020034102470d002002428080818080043703c0022002428080848080023703b80220024280c2d72f3703a80220024280e1eb173703a002200242a0c21e37039802200242a0c21e37039002200242e0ef972037038802200242e0c9dc2937038002200242e0ef97203703f801200242a0c21e3703f001200242a0c21e3703e801200242a0c21e3703e001200242a0c21e3703d801200242a0c21e3703d001200242a0c21e3703c801200242a0c21e3703c00120024280808080c0003703b002410021030c010b200241c0016a20024180096a418801109d081a200241c0016a418c016a20022800cb06360000200220022802c8063600c9020b200241e8026a4200370300200241d8026a4200370300200220033a00c8022002428080e983b1de163703e0022002428080e983b1de163703d002200242a08080808080103703f0022002200241c0016a3602f8022002200241c0016a3602fc02200241d80b6a41186a22054200370300200241d80b6a41106a22014200370300200241d80b6a41086a22034200370300200242003703d80b41d1efcb00ad42808080809001841001220029000021092003200041086a290000370300200220093703d80b2000103541ebc3c400ad428080808030841001220b2900002109200241c8066a41086a2200200b41086a290000370300200220093703c806200b1035200420022903c806370000200441086a220c200029030037000020024180096a41086a220d200329030037030020024180096a41106a220e200129030037030020024180096a41186a220f2005290300370300200220022903d80b37038009200241106a20024180096a10e1022002290318210920022802102110200542003703002001420037030020034200370300200242003703d80b41d1c4c700ad4280808080e000841001220b29000021112003200b41086a290000370300200220113703d80b200b103541e7c4c700ad4280808080e000841001220b29000021112000200b41086a290000370300200220113703c806200b1035200420022903c806370000200c2000290300370000200d2003290300370300200e2001290300370300200f2005290300370300200220022903d80b37038009200241086a20024180096a412010c001200241b8036a4200370300200241ac036a419494ca00360200200241a8036a41b0b4cc00360200200241a4036a4100360200200241d8036a200241f0006a41086a290300370300200241e0036a200241f0006a41106a290300370300200241e8036a200241f0006a41186a2903003703002002428080808080013703b00320024200370398032002420037038803200220022903703703d00320022802082104200228020c21002002200241fc026a3602c8032002200241f8026a3602c4032002200241c0016a3602c00320022000410020041b3602cc0320022009420020101b37038003200520024190016a41186a290300370300200120024190016a41106a290300370300200320024190016a41086a29030037030020022002290390013703d80b2002200a370284092002200636028009200241f0036a20024180036a200241d80b6a20072008200241b0016a20024180096a10ef0341012112024020022802f00322130d00200241f0036a41106a2d00000d00200241d80b6a41086a200241a0036a29030037030020024180096a41086a200241e40b6a28020036020020022002290398033703d80b200220022902dc0b37038009200241880f6a20024180096a10f003410021120b20022802b403221420022802bc03220341d8026c6a210120022802b80321152014210402402003450d00200241a10c6a2110200241cd086a210e20024187096a2116200241d80b6a41186a210b200241e10b6a2117200241880e6a41116a2118200241880e6a41027221192002419c086a41186a211a200241810c6a211b200241f0086a211c200241970e6a211d2002419c086a41116a210f200241d80b6a410172211e20024180096a41e0006a211f200241d0096a2120201421030240034020032d00002104200241c4066a41026a220d200341036a2d00003a00002002200341016a2f00003b01c406200341046a2802002105200341086a28020021002003410c6a2802002106200241e0056a200341106a41e000109d081a200341f8006a2903002109200341f0006a290300210720034180016a290300210820024190046a20034188016a41d001109d081a20044103460d01200241fc086a41026a220c200d2d00003a0000200220022f01c4063b01fc082002419c086a200241e0056a41e000109d081a200241c8066a20024190046a41d001109d081a024002400240024020040e03010200010b200241c40e6a41026a2204200c2d00003a0000200241b00e6a41086a220d2002419c086a41086a2221290000370300200241b00e6a41106a22222002419c086a41106a22232d00003a0000200220022f01fc083b01c40e2002200229009c083703b00e200241c80e6a41186a2224200f41186a2225290000370300200241c80e6a41106a2226200f41106a2227290000370300200241c80e6a41086a2228200f41086a22292900003703002002200f2900003703c80e200241b00b6a41186a222a200e41186a222b290000370300200241b00b6a41106a222c200e41106a222d290000370300200241b00b6a41086a222e200e41086a222f2900003703002002200e2900003703b00b200220063600930e2002200036008f0e2002200536008b0e2002200c2d00003a008a0e200220022f01fc083b01880e201d200229009c08370000201d41086a2021290000370000201d41106a20232d00003a000020024180096a41186a202529000037030020024180096a41106a202729000037030020024180096a41086a20292900003703002002200f29000037038009200b202b290000370300200241d80b6a41106a202d290000370300200241d80b6a41086a202f2900003703002002200e2900003703d80b200241f80e6a41086a201c41086a2800003602002002201c2900003703f80e200241e80e6a200241880e6a20024180096a200241d80b6a20072009200241f80e6a10f10320022d00e80e210c201720022f01c40e3b0000201741026a20042d00003a0000200b20022903b00e370000200b41086a200d290300370000200b41106a20222d00003a0000200241033a00e00b2002410d3a00d80b200220063602ec0b200220003602e80b200220053602e40b201b20022903c80e370000201b41086a2028290300370000201b41106a2026290300370000201b41186a2024290300370000201041186a202a290300370000201041106a202c290300370000201041086a202e290300370000201020022903b00b370000200241d80b6a41f8006a2009370300200220073703c80c2002200c4104463a00c10c41b0b4cc004100200241d80b6a10d4010c020b20162002419c086a41e000109d081a2002410d3a00d80b201e20024180096a41e700109d081a200241d80b6a41f0006a2009370300200220073703c00c200220083703d00c20052006200241d80b6a10d401200041ffffff3f71450d01200510350c010b200241f80e6a41026a2204200c2d00003a0000200241c80e6a41086a220d2002419c086a41086a2221290000370300200241c80e6a41106a22222002419c086a41106a22232d00003a0000200220022f01fc083b01f80e2002200229009c083703c80e20024180096a201a41c800109d081a20202009370300200220073703c809200220083703d809201f200241c8066a41d001109d081a200241b00e6a20024180096a10d803200241d80b6a20024180096a41b002109d081a201920022f01fc083b0000201941026a200c2d00003a00002018200229009c08370000201841086a2021290000370000201841106a20232d00003a000020024180023b01880e200220063600950e200220003600910e2002200536008d0e200241b00b6a200241d80b6a200241880e6a10ac0342002109024020022903b80b4201520d00420020022903b00e220920022903c00b7d220720072009561b21090b2002427f20022903b801220720097c220920092007541b220920022903b001220720092007561b3703b80120022903b00b2109201720022f01f80e3b0000201741026a20042d00003a0000200b20022903c80e370000200b41086a200d290300370000200b41106a20222d00003a0000200241063a00e00b2002410d3a00d80b200220063602ec0b200220003602e80b200220053602e40b20022009503a00810c41b0b4cc004100200241d80b6a10d4010b200341d8026a22032001470d000b200121040c010b200341d8026a21040b024020012004460d0003402004220341d8026a21040240024020032d0000220541014b0d000240024020050e020001000b0240200341086a28020041ffffff3f71450d00200341046a28020010350b200341106a2d00004107470d02200341386a280200450d02200341346a28020010350c020b200341286a10bb020c010b200341e8006a28020041ffffff3f71450d00200341e4006a28020010350b20012004470d000b0b02402015450d00201541d8026c450d00201410350b20024184046a280200210d200241f0036a41106a2802002106200241fc036a2802002100200241f8036a280200210b20022802f40321010240200228028c032203450d0020024180036a41106a280200450d00200310350b02402012450d0002400240200228029c03220c0d004100210e200241ec0b6a4100360200200241003602dc0b0c010b20022802a403210e02400240200241a0036a28020022040d00200c21030c010b20042103200c2105034020052802880b21052003417f6a22030d000b200c21030340200320032f01064102746a41880b6a28020021032004417f6a22040d000b2005210c0b200241f40b6a20032f0106360200200241f00b6a4100360200200241ec0b6a2003360200200241003602e80b200242003703e00b2002200c3602dc0b200241003602d80b0b2002200e3602f80b200241d80b6a108f030b02402013450d00410021010240200d450d00200610350b0b200241003602e00b200242013703d80b410110332103024002402001450d002003450d08200341003a0000200220033602d80b20024281808080103702dc0b20034101410210372203450d08200320063a0001200220033602d80b20024282808080203702dc0b2000200241d80b6a10770240024020022802dc0b220520022802e00b22046b2000490d0020022802d80b21030c010b200420006a22032004490d08200541017422062003200620034b1b22064100480d080240024020050d00024020060d00410121030c020b2006103322030d010c0b0b20022802d80b210320052006460d0020032005200610372203450d0a0b200220063602dc0b200220033602d80b0b200320046a20012000109d081a200420006aad42208621090c010b2003450d07200341013a0000200241013602dc0b200220033602d80b42808080801021090b20092003ad84210902402001450d00200b450d00200110350b200241900f6a240020090f0b2002418c096a4104360200200241ec0b6a4102360200200242023702dc0b200241f0b2c3003602d80b2002410436028409200241e8b4c30036028009200241003602cc06200241b0b4cc003602c806200220024180096a3602e80b2002200241c8066a36028809200241d80b6a4180b3c300104c000b1044000b1045000b2002418c096a4104360200200241ec0b6a4102360200200242023702dc0b200241f0b2c3003602d80b2002410436028409200241e8b4c30036028009200241003602cc06200241b0b4cc003602c806200220024180096a3602e80b2002200241c8066a36028809200241d80b6a4180b3c300104c000b2002418c096a4104360200200241ec0b6a4102360200200242023702dc0b200241f0b2c3003602d80b2002410436028409200241e8b4c30036028009200241003602cc06200241b0b4cc003602c806200220024180096a3602e80b2002200241c8066a36028809200241d80b6a4180b3c300104c000b103e000b103c000bbf2303027f027e077f23004190056b2207240020072004370310200720033703082007200536021c02400240024002400240024002400240024002400240024002402001280230200128024022082802b001460d002005420020052903082209200841386a2903007d220a200a20095622081b37030820080d03200741f8026a200210f303200741a0016a20072802f802220820072802800310d90220072d00a0012105200741b8046a200741a0016a41017241d700109d081a024020054102460d00200741e0036a200741b8046a41d700109d081a0b024020072802fc02450d00200810350b2005417f6a41ff01714102490d01200741b8046a200741e7036a220b41d000109d081a200741a0016a41186a4200370300200741a0016a41106a220c4200370300200741a0016a41086a22054200370300200742003703a00141d1c4c700ad4280808080e000841001220829000021092005200841086a290000370300200720093703a0012008103541e7c4c700ad4280808080e00084100122082900002109200741b0026a41086a220d200841086a290000370300200720093703b00220081035200c20072903b0022209370300200741f8026a41086a22082005290300370300200741f8026a41106a22052009370300200741f8026a41186a220c200d290300370300200720072903a0013703f8022007200741f8026a412010c001200741b0026a20022007280204410020072802001b220e4100200741b8046a10f603200741a0016a200b41d000109d081a200c200741b0026a41186a2903003703002005200741b0026a41106a2903003703002008200d290300370300200720072903b0023703f802200741206a2002200741a0016a200e200741f8026a10f70320072d002021050c020b200041003a0004200041013602002000410c6a4129360200200041086a41c4baca00360200200041106a2006290200370200200041186a200641086a2802003602000c0b0b200720053a0020200741206a410172200741e0036a41d700109d081a0b200541037122084103460d0220080e03010201010b200041003a0004200041013602002000410c6a4123360200200041086a41edbaca00360200200041106a2006290200370200200041186a200641086a2802003602000c080b200741f8006a41186a200141e8006a29000037030020074188016a200141e0006a290000370300200741f8006a41086a200141d8006a2900003703002007200129005037037841002108024002400240200541ff0171220541024d0d000c010b024020050e03000102000b200741c0006a2802002205417f4c0d032007413c6a280200210e200741206a41186a280200210c0240024020050d004100210d410121080c010b200510332208450d052005210d0b02400240200d2005490d00200d210b0c010b200d410174220b2005200b20054b1b220b4100480d060240200d0d00200b103322080d010c0a0b200d200b460d002008200d200b10372208450d090b2008200c2005109d081a2005ad422086200bad842109200e450d00200c10350b200741086a41086a2903002104200729030821030b200741dc016a4100360200200741cc016a41d8b9ca00360200200741c4016a4100360200200741a0016a41106a2009370300200741f8016a200241086a29000037030020074180026a200241106a29000037030020074188026a200241186a290000370300200720013602a801200741a0016a41286a200141186a220f360200200742083702d401200742003703b801200720083602ac01200720022900003703f001200720012802483602e801200720012903403703e0012007200128023041016a3602d001200129030021092007200128024c3602ec01200720093703a00120074180046a200741f8006a41086a290300370300200741e0036a41286a200741f8006a41106a29030037030020074190046a200741f8006a41186a290300370300200741f4036a200641086a280200360200200720023602e803200720072903783703f803200720062902003702ec0320072007411c6a3602e4032007200741086a3602e003200741e0036a41186a211002400240200320048450450d00410021060c010b200741b8046a200728021c41002010200220032004200741a0016a10bf05024020072d00b8044104460d00200720072900ed033703a0022007200741f4036a2800003600a70220072d00ec03210520072902bc04210320072802b80421060c070b20072802b801210620072802e80321020b200641016a220e41004c0d042007200e3602b801024002400240200741bc016a280200220b450d00200741a0016a41206a280200210c0340200b41086a2105200b2f010622114105742106410021080240024003402006450d0120022005412010a008220d450d02200641606a2106200841016a2108200541206a2105200d417f4a0d000b2008417f6a21110b200c450d02200c417f6a210c200b20114102746a41880b6a280200210b0c010b0b200b200841e0006c6a220541e8026a210602400240200541c5036a2d00000d00200741b8046a41086a2208200641c5006a290000370300200741b8046a41106a220d200641cd006a290000370300200741b8046a41186a220b200641d5006a29000037030020072006413d6a2900003703b8044102210520062d003c4101470d01200741f8026a41186a200b290300370300200741f8026a41106a200d290300370300200741f8026a41086a2008290300370300200720072903b8043703f802410121050c010b20074180036a200641c5006a29000037030020074188036a200641cd006a29000037030020074190036a200641d5006a29000037030020072006413d6a2900003703f80220062d003c21050b200541ff01714102470d010b200741b0026a20072802c801200220072802cc0128021011040020072802b801210e20072d00b00221050c010b200741b9026a20074180036a290300370000200741c1026a20074188036a290300370000200741c9026a20074190036a290300370000200720053a00b002200720072903f8023700b1020b2007200e417f6a3602b8014101210602400240200541ff01714101470d00200741d8026a41186a200741c9026a290000370300200741d8026a41106a200741c1026a290000370300200741d8026a41086a200741b9026a290000370300200720072900b1023703d802200741b8046a200741d8026a20072802e80128020010a306024020072802b8044101470d00200720072900ed033703a0022007200741f4036a2800003600a70220072902bc04210320072d00ec032105410021060c080b200741b0036a41186a2205200741b8046a410472220641186a2802002202360200200741f8026a41106a200641086a290200370300200741f8026a41186a200641106a29020037030020074198036a2002360200200741043602fc02200741fbd5cb003602f802200720062902003703800320072802e40121062005201041186a2900002203370300200741b0036a41106a2202201041106a2900002204370300200741b0036a41086a2208201041086a2900002209370300200741e0046a2009370300200741e8046a2004370300200741f0046a20033703002007201029000022033703b003200720033703d80420072802e003220d41086a29030021032007200741a0016a3602d004200d290300210420072903a001210920072802ec01210d200720033703c004200720043703b8042007200d3602d404200720093703c804200741d0036a41086a200741ec036a220d41086a2802003602002007200d2902003703d003200741b0036a2006200741f8026a200741b8046a200741d0036a20072802e403280200109a05200720072900c1033703a003200720052800003600a7032008290300210320022d0000210520072802b4032106024020072802b0034101470d00200720072800a7033600a702200720072903a0033703a00220074190036a280200450d082007418c036a28020010350c080b200720072d00a2033a00a202200720072f01a0033b01a00220074190036a280200450d012007418c036a28020010350c010b4200210341002105200741f0036a280200450d0020072802ec0310350b200720072903a0022204370390022007419c016a41026a221120072d0092023a0000200720043d019c01200741c0016a280200210220072802dc01210d20072802d801210c20072802d401210820072802c401210e20072802bc01210b024020072802ac012210450d00200741b0016a280200450d00201010350b200741b8046a41026a20112d00003a0000200720072f019c013b01b80402400240200541ff01710d002007200e3602a801200720023602a4012007200b3602a001200f200741a0016a109504200141346a2001413c6a2205280200200d41d8026c220241d8026d220d1095012001280234200528020041d8026c6a20082002109d081a20052005280200200d6a3602000240200c450d00200c41d8026c450d00200810350b20002006360204200020072f01b8043b0011200041106a41003a0000200041086a2003370200200041136a200741ba046a2d00003a00000c010b20002006360204200020072f01b8043b0011200041106a20053a0000200041086a2003370200200041136a200741ba046a2d00003a00000240200d450d00200d41d8026c210d41002106034002400240200820066a22052d0000220141014b0d000240024020010e020001000b0240200541086a28020041ffffff3f71450d00200541046a28020010350b200541106a2d00004107470d02200541386a280200450d02200541346a28020010350c020b200541286a10bb020c010b200541e8006a28020041ffffff3f71450d00200541e4006a28020010350b200d200641d8026a2206470d000b0b0240200c450d00200c41d8026c450d00200810350b02400240200b0d004100210e200741b4016a4100360200200741003602a4010c010b0240024020020d00200b21060c010b20022106200b2105034020052802880b21052006417f6a22060d000b200b21060340200620062f01064102746a41880b6a28020021062002417f6a22020d000b2005210b0b200741bc016a20062f0106360200200741b8016a4100360200200741b4016a2006360200200741003602b001200742003703a8012007200b3602a401200741003602a0010b2007200e3602c001200741a0016a108f030b200041003602000c070b200041003a0004200041013602002000410c6a4119360200200041086a4190bbca00360200200041106a2006290200370200200041186a200641086a280200360200200541ff01710d062007413c6a280200450d06200741386a28020010350c060b1044000b1045000b103e000b41ac96cc004118200741b8046a41d8c1c30041d496cc001046000b200720072903a00237039002200720072800a70236009702200041106a20053a0000200041086a2003370200200020063602042000200729039002370011200041186a20072800970236000020004101360200024020072802ac012200450d00200741a0016a41106a280200450d00200010350b0240024020072802bc0122010d0041002102200741cc046a4100360200200741003602bc040c010b20072802c401210202400240200741c0016a28020022060d00200121000c010b2006210020012105034020052802880b21052000417f6a22000d000b200121000340200020002f01064102746a41880b6a28020021002006417f6a22060d000b200521010b200741d4046a20002f0106360200200741d0046a4100360200200741cc046a2000360200200741003602c804200742003703c004200720013602bc04200741003602b8040b200720023602d804200741b8046a108f03024020072802dc012200450d0020072802d4012101200041d8026c210241002100034002400240200120006a22062d0000220541014b0d000240024020050e020001000b0240200641086a28020041ffffff3f71450d00200641046a28020010350b200641106a2d00004107470d02200641386a280200450d02200641346a28020010350c020b200641286a10bb020c010b200641e8006a28020041ffffff3f71450d00200641e4006a28020010350b2002200041d8026a2200470d000b0b20072802d8012200450d01200041d8026c450d0120072802d40110350c010b103c000b20074190056a24000ba6480d077f017e047f067e047f047e0d7f067e107f027e057f027e0a7f230041b0056b2202240020024190016a42003703002002420037038801200242003703800102400240200128020022030d004100210141002103410021040c010b2001280208210402400240200128020422050d00200321010c010b2005210120032106034020062802880b21062001417f6a22010d000b200321010340200120012f01064102746a41880b6a28020021012005417f6a22050d000b200621030b20012f010621050b20024188016a2107200241b4016a2005360200200241b0016a4100360200200241ac016a2001360200200220043602b801200241003602a801200242003703a0012002200336029c012002410036029801024002400240024002402004450d0020022004417f6a3602b80102402003450d000240024020032f0106450d004100210841002106410021050c010b4100210641002105034002400240200328020022010d002005ad2109410021010c010b200641016a210620033301044220862005ad8421090b200310352009a72105200121032009422088a7220820012f01064f0d000b200121030b20024190056a41186a220a200320084105746a220141206a29000037030020024190056a41106a220b200141186a29000037030020024190056a41086a220c200141106a2900003703002002200141086a290000370390052003200841e0006c6a220141a4036a2d0000210d200141a0036a280200210420014198036a290300210e20014190036a290300210f20014188036a290300211020014180036a2903002111200141f8026a2903002112200141f0026a2903002113200141e8026a290300210920024180046a41186a2214200141bd036a29000037030020024180046a41106a2215200141b5036a29000037030020024180046a41086a2216200141ad036a2900003703002002200141a5036a29000037038004200841016a2108200141c5036a2d0000211702402006450d00200320084102746a41880b6a2802002103410021082006417f6a2201450d00034020032802880b21032001417f6a22010d000b0b200241e0026a41186a200a290300370300200241e0026a41106a200b290300370300200241e0026a41086a200c290300370300200241d0036a41086a2016290300370300200241d0036a41106a2015290300370300200241d0036a41186a201429030037030020022002290390053703e00220022002290380043703d003200220083602a401200220053602a0012002200336029c01200241003602980120094202510d0120024190056aad42808080808004842118200241d0036aad42808080808004842119200241e0026aad4280808080800284211a20024180046aad4280808080800484211b200241b4046a211c20024190056a41106a210820024180046a41106a211d20024189046a211e20024180046a41086a211f20024180046a412c6a2120200241e0026a412c6a2121200241e0026a41106a212220024188036a2123200241b8046a212402400340200241e0016a41186a2203200241e0026a41186a2225290300370300200241e0016a41106a22012022290300370300200241e0016a41086a2205200241e0026a41086a2226290300370300200241c0016a41086a2206200241d0036a41086a220b290300370300200241c0016a41106a220a200241d0036a41106a220c290300370300200241c0016a41186a2215200241d0036a41186a2214290300370300200220022903e0023703e001200220022903d0033703c00120024180026a41186a2216200329030037030020024180026a41106a2227200129030037030020024180026a41086a22282005290300370300200220022903e00137038002200241a0026a41186a22012015290300370300200241a0026a41106a2205200a290300370300200241a0026a41086a220a2006290300370300200220022903c0013703a00202402017ad42ff0183200920095022031b4201520d0020024200201220031b3703d80320024200201320031b3703d003200220024180026a36029005200241e0026a20024180026a200241d0036a20024190056a10880442022109024020022903e00222294202510d0020232903002113200229038003211220022903f802210920294201520d0020022903e802212920242022290300370300201e200229038002370000201e41086a2028290300370000201e41106a2027290300370000201e41186a2016290300370000200220293703b004200241003a008804200241033a00800441b0b4cc00410020024180046a10d4010b42002013200942025122031b21134200201220031b21124200200920031b2109024020030d0020024190056a41186a220642003703002008420037030020024190056a41086a22034200370300200242003703900541b6fdc600ad4280808080800184222910012215290000212a2026201541086a2900003703002002202a3703e0022015103520032026290300370300200220022903e0023703900541e489c200ad4280808080d00184222a10012215290000212b2026201541086a2900003703002002202b3703e00220151035200820022903e002370000200841086a22272026290300370000201f2003290300370300201d200829030037030020024180046a41186a22282006290300370300200220022903900537038004200241e8006a20024180046a412010d701200241e8006a41106a290300212b2002290370212c20022802682115200642003703002008420037030020034200370300200242003703900520291001221629000021292026201641086a290000370300200220293703e0022016103520032026290300370300200220022903e00237039005202a1001221629000021292026201641086a290000370300200220293703e00220161035200820022903e00237000020272026290300370000201f2003290300370300201d2008290300370300202820062903003703002002200229039005370380042002202b420020151b3703e8022002202c420020151b3703e002201b201a10020b200241d0006a20022903800120022903880120024180016a41106a22032903002009201220131091032003200241d0006a41106a290300370300200220022903583703880120022002290350370380010b200e422088210902400240024002400240024002400240024002400240024002400240200d41ff017122154101460d00201741ff01710d0020042011a772450d010b200241d0036a20024180026a10f30320024180046a20022802d003220620022802d80310d9022026201c41086a2900003703002022201c41106a2900003703002025201c41186a2900003703002002201c2900003703e002024020022d00800422034102460d00201d290300212d200229038804212e20022802b004212f20022802ac04213020022802a804213120022802a404213220022802a0042133200228029c042134200228029804213520024190056a41086a20262903003703002008202229030037030020024190056a41186a2025290300370300200220022903e0023703900520022802d40421360b024020022802d403450d00200610350b024002402003410371417f6a220641014b0d0041022137024020060e020002000b20030d0d2034450d0d203510350c0d0b200241c0026a41186a20024190056a41186a290300370300200241c0026a41106a2008290300370300200241c0026a41086a20024190056a41086a29030037030020022002290390053703c00220362138202f2139203021372031213a2032213b2033213c2034213d2035213e202e213f202d21400b4102210641022141024020374102460d00203c417f4c0d0202400240203c0d0041002103410121420c010b203c10332242450d04203c21030b024002402003203c490d00200321430c010b20034101742206203c2006203c4b1b22434100480d05024020030d002043103322420d010c070b20032043460d0020422003204310372242450d060b2042203e203c109d081a20024180046a41186a200241c0026a41186a290300370300201d200241c0026a41106a290300370300201f200241c0026a41086a290300370300200220022903c0023703800420374101462141203c214420372106203b2145203f214620402147203a2148203921490b200241b0036a41186a224a2001290300370300200241b0036a41106a224b2005290300370300200241b0036a41086a224c200a290300370300200b201f290300370300200c201d290300370300201420024180046a41186a2203290300370300200220022903a0023703b00320022002290380043703d003201741ff0171450d060c050b02400240200ea722030d0041002104200241003602940420024100360284040c010b024002402009a722050d00200321010c010b2005210620032101034020012802ec0321012006417f6a22060d000b0340200320032f01064102746a41ec036a28020021032005417f6a22050d000b0b200241003602980420024100360290042002420037038804200220013602840420024100360280042002200336029404200220032f010636029c040b200220043602a00420024180046a1081030c0b0b1044000b1045000b103e000b103c000b20414102460d010240200d4101710d0020024180046a2042204410f4032002350288044220862002280280042203ad8410110240200228028404450d00200310350b20024180046a20024180026a10f3032002350288044220862002280280042203ad8410070240200228028404450d00200310350b02402043450d00204210350b203721060c030b20024180046a2042204410f4032002350288044220862002280280042206ad8410110240200228028404450d00200610350b200241f0036a20024180026a10890420034200370300201d42003703004108211620024180046a41086a22064200370300200242003703800441d1c4c700ad4280808080e000841001221729000021122006201741086a29000037030020022012370380042017103541e7c4c700ad4280808080e0008410012217290000211220024180056a41086a220d201741086a290000370300200220123703800520171035201d200229038005370000201d41086a200d29030037000020024190056a41086a20062903003703002008201d29030037030020024190056a41186a2003290300370300200220022903800437039005200241c8006a20024190056a412010c001200228024c210620022802482117202241086a200241f0036a41086a280200360200202220022903f003370200202120022903b003370100202141086a200241b0036a41086a290300370100202141106a204b290300370100202141186a204a290300370100427f21132002427f3703e8022002427f3703e002200241083602fc0241002141200241003602840320022006410020171b224d36028003024020430d00427f21290c050b20421035427f2113427f21290c040b20414102470d020b200d410171450d00200241f0036a20024180026a10890420034200370300201d42003703004108211620024180046a41086a22064200370300200242003703800441d1c4c700ad4280808080e000841001221729000021122006201741086a29000037030020022012370380042017103541e7c4c700ad4280808080e0008410012217290000211220024180056a41086a220d201741086a290000370300200220123703800520171035201d200229038005370000201d41086a200d29030037000020024190056a41086a20062903003703002008201d29030037030020024190056a41186a2003290300370300200220022903800437039005200241c0006a20024190056a412010c0012002280244210620022802402117202241086a200241f0036a41086a280200360200202220022903f003370200202120022903b003370100202141086a200241b0036a41086a290300370100202141106a204b290300370100202141186a204a290300370100427f21132002427f3703e8022002427f3703e002200241083602fc0241002141200241003602840320022006410020171b224d36028003427f21290c020b20064102460d020240203d0d004100213d0c030b203e10350c020b202120022903d003370200202141086a200b290300370200202141106a200c290300370200202141186a2014290300370200200220463703e002200220493602880320022041360284032002204836028003200220453602fc02200220443602f802200220433602f402200220423602f002200220473703e8022048214d2046211320472129204521160b024020114201520d00200220103703e0022002200f3703e80220102113200f21290b02402015450d00202120022903a002370000202141186a2001290300370000202141106a2005290300370000202141086a200a2903003700000b200ea7210102402004450d0020034200370300201d4200370300201f4200370300200242003703800441d1c4c700ad4280808080e0008410012205290000210e201f200541086a2900003703002002200e370380042005103541e7c4c700ad4280808080e0008410012205290000210e20024180056a41086a2206200541086a2900003703002002200e3703800520051035201d200229038005370000201d41086a200629030037000020024190056a41086a201f2903003703002008201d29030037030020024190056a41186a2003290300370300200220022903800437039005200241386a20024190056a412010c0014101214120024101360284032002200228023c410020022802381b360288030b0240024020010d004100210341002101410021040c010b024002402009a722050d00200121030c010b2005210620012103034020032802ec0321032006417f6a22060d000b0340200120012f01064102746a41ec036a28020021012005417f6a22050d000b0b20012f0106214e0b200220043602a0042002204e36029c0420024100360298042002200136029404200241003602900420024200370388042002200336028404200241003602800402402004450d0020022004417f6a22153602a00402402003450d000240024020032f0106450d004100210d41002106410021050c010b4100210641002105034002400240200328020022010d002005ad2109410021010c010b200641016a210620033301044220862005ad8421090b200310352009a72105200121032009422088a7220d20012f01064f0d000b200121030b20024190056a41186a22172003200d4105746a220141206a2900003703002008200141186a29000037030020024190056a41086a220a200141106a2900003703002002200141086a29000037039005200d41016a21042003200d410c6c6a220141f0026a2802002127200141ec026a280200214f200141e8026a280200210d02402006450d00200320044102746a41ec036a2802002103410021042006417f6a2201450d00034020032802ec0321032001417f6a22010d000b0b20142017290300370300200c2008290300370300200b200a29030037030020022002290390053703d0032002200436028c0420022005360288042002200336028404200241003602800420022802f802212820022802f00221500340204a20142903002209370300204b200c290300220e370300204c200b2903002211370300200220022903d00322123703b00320142009370300200c200e370300200b2011370300200220123703d00320024180056a2050202810f40320191009220141086a2900002109200141106a290000210e200129000021112017200141186a2900003703002008200e370300200a2009370300200220113703900520011035200241f0036a2002350288054220862002280280052201ad842018101010c201024020022802f0032206450d00201620022802f8036b211620022802f403450d00200610350b0240200228028405450d00200110350b02400240200d450d0020024180056a2050202810f40320191009220141086a2900002109200141106a290000210e200129000021112017200141186a2900003703002008200e370300200a20093703002002201137039005200110352002350288054220862002280280052201ad8420182027ad422086200dad8410120240200228028405450d00200110350b201620276a2116204f450d01200d10350c010b20024180056a2050202810f40320191009220141086a2900002109200141106a290000210e200129000021112017200141186a2900003703002008200e370300200a20093703002002201137039005200110352002350288054220862002280280052201ad8420181013200228028405450d00200110350b024020150d00200220163602fc020c030b20022015417f6a22153602a00402402003450d00410021060240200420032f0106490d00034002400240200328020022010d002005ad2109410021010c010b200641016a210620033301044220862005ad8421090b200310352009a72105200121032009422088a7220420012f01064f0d000b200121030b2017200320044105746a220141206a2900003703002008200141186a290000370300200a200141106a2900003703002002200141086a29000037039005200441016a215120032004410c6c6a220141f0026a2802002127200141ec026a280200214f200141e8026a280200210d0240024020060d00205121040c010b200320514102746a41ec036a2802002103410021042006417f6a2201450d00034020032802ec0321032001417f6a22010d000b0b20142017290300370300200c2008290300370300200b200a29030037030020022002290390053703d0032002200436028c042002200536028804200220033602840420024100360280040c010b0b41958dcc00412b41c08dcc00103f000b41958dcc00412b41c08dcc00103f000b20024180046a10810320024190056a41186a2203200241c0026a41186a2903003703002008200241c0026a41106a29030037030020024190056a41086a2201200241c0026a41086a290300370300200220022903c002370390050240024020374102460d002020200229039005370200202041086a2001290300370200202041106a2008290300370200202041186a20032903003702002002203f37038004200220393602a804200220373602a4042002203a3602a0042002203b36029c042002203d360294042002203e36029004200220383602cc0420022040370388042002203c36029804410121030240203c20022802f802470d000240024020022802f0022201203e460d00203e2001203c10a0080d02203b2016470d020c010b203b2016470d010b20202021412010a0080d00203f2013852040202985844200520d00203a204d470d00024020372041470d004100210320374101470d012039200228028803460d010b410121030b0240203d450d00203e10350b20034102460d002003450d010b201f200241e0026a41d000109d081a200241003a00800420024190056a20024180026a10f303200228029005210320022002280298053602d403200220033602d00320024180046a200241d0036a108a040240200228029405450d00200310350b200228029c04450d0220022802980410350c020b20022802f402450d0120022802f00210350c010b02400240200ea722030d0041002104200241003602940420024100360284040c010b024002402009a722050d00200321010c010b2005210620032101034020012802ec0321012006417f6a22060d000b0340200320032f01064102746a41ec036a28020021032005417f6a22050d000b0b200241003602980420024100360290042002420037038804200220013602840420024100360280042002200336029404200220032f010636029c040b200220043602a00420024180046a1081030b024020022802b8012203450d0020022003417f6a3602b801200228029c012203450d0220022802a00121052002280298012106024020022802a401220420032f0106490d00034002400240200328020022010d002005ad2109410021010c010b200641016a210620033301044220862005ad8421090b200310352009a72105200121032009422088a7220420012f01064f0d000b200121030b20024190056a41186a2215200320044105746a220141206a2900003703002008200141186a29000037030020024190056a41086a2216200141106a2900003703002002200141086a29000037039005201f2003200441e0006c6a220141ad036a290000370300201d200141b5036a29000037030020024180046a41186a2227200141bd036a2900003703002002200141a5036a29000037038004200441016a210a20014190036a290300210f20014188036a2903002110200141f8026a2903002112200141f0026a2903002113200141c5036a2d00002117200141a4036a2d0000210d200141a0036a280200210420014198036a290300210e20014180036a2903002111200141e8026a290300210902402006450d002003200a4102746a41880b6a28020021034100210a2006417f6a2201450d00034020032802880b21032001417f6a22010d000b0b202520152903003703002022200829030037030020262016290300370300200b201f290300370300200c201d2903003703002014202729030037030020022002290390053703e00220022002290380043703d0032002200a3602a401200220053602a0012002200336029c01200241003602980120094202520d010b0b200229038001210920024198016a108f0320024180046a2104200950450d040c030b41958dcc00412b41c08dcc00103f000b41958dcc00412b41c08dcc00103f000b20024198016a108f030b024020022903880120024190016a29030084500d0041a1c2c300413341c086cc00103f000b200229038001500d0120024180046aad4280808080800484211b20024180046a21040b200220073602980120024190056a41186a2208420037030020024190056a41106a2205420037030020024190056a41086a22014200370300200242003703900541b6fdc600ad42808080808001842218100122062900002109200241e0026a41086a2203200641086a290000370300200220093703e0022006103520012003290300370300200220022903e0023703900541e489c200ad4280808080d0018422191001220629000021092003200641086a290000370300200220093703e00220061035200520022903e002220937030020024180046a41086a2217200129030037030020024180046a41106a220a200937030020024180046a41186a220b2003290300370300200220022903900537038004200241206a2004412010d701200241206a41106a290300210e200229032821112002280220210620024180016a41106a29030021122002290388012109200842003703002005420037030020014200370300200242003703900520181001220429000021182003200441086a290000370300200220183703e0022004103520012003290300370300200220022903e0023703900520191001220429000021182003200441086a290000370300200220183703e00220041035200520022903e002221837030020172001290300370300200a2018370300200b200329030037030020022002290390053703800420024200200e420020061b221820127d2011420020061b2219200954ad7d220e201920097d2209201956200e201856200e2018511b22031b3703e80220024200200920031b3703e002201b200241e0026aad428080808080028410020c010b200220073602980120024190056a41186a2204420037030020024190056a41106a2205420037030020024190056a41086a22014200370300200242003703900541b6fdc600ad42808080808001842209100122062900002118200241e0026a41086a2203200641086a290000370300200220183703e0022006103520012003290300370300200220022903e0023703900541e489c200ad4280808080d0018422181001220629000021192003200641086a290000370300200220193703e00220061035200520022903e002221937030020024180046a41086a2208200129030037030020024180046a41106a2217201937030020024180046a41186a220a2003290300370300200220022903900537038004200241086a20024180046a412010d701200241086a41106a29030021192002290310210e2002280208210620024180016a41106a29030021112002290388012112200442003703002005420037030020014200370300200242003703900520091001220429000021092003200441086a290000370300200220093703e0022004103520012003290300370300200220022903e0023703900520181001220429000021092003200441086a290000370300200220093703e00220041035200520022903e00222093703002008200129030037030020172009370300200a20032903003703002002200229039005370380042002427f20112019420020061b22097c2012200e420020061b22187c22192018542203ad7c22182003201820095420182009511b22031b3703e8022002427f201920031b3703e00220024180046aad4280808080800484200241e0026aad428080808080028410020b200241b0056a24000b9c3b040f7f017e017f067e230041d0046b2207240020074198026a200110f303200741d0036a200728029802220820072802a00210d902200741f8026a41086a2209200741da036a290100370300200741f8026a410e6a220a200741d0036a41106a290000370100200741a0036a41086a220b20074188046a290300370300200741a0036a41106a220c20074190046a290300370300200741a0036a41186a220d20074198046a290300370300200741a0036a41206a220e200741a0046a290300370300200720072901d2033703f8022007200741f1036a290000370390032007200741f8036a28000036009703200720074180046a2903003703a003200741d0036a41206a2d0000210f200741ec036a2802002110200741d0036a41186a28020021110240024020072d00d00322124102460d00200741fc036a2802002113200741e0026a410e6a200a290100370100200741e0026a41086a2009290300370300200741a8026a41086a200b290300370300200741a8026a41106a200c290300370300200741a8026a41186a200d290300370300200741a8026a41206a200e290300370300200720072903f8023703e00220072007290390033703d00220072007280097033600d702200720072903a0033703a8020240200728029c02450d00200810350b200741f8026a41086a200741e0026a41086a290300370300200741f8026a410e6a2209200741e0026a410e6a290100370100200741a0036a41086a220b200741a8026a41086a290300370300200741a0036a41106a220c200741a8026a41106a290300370300200741a0036a41186a220d200741a8026a41186a290300370300200741a0036a41206a220e200741a8026a41206a290300370300200720072903e0023703f802200720072903d00237039003200720072800d70236009703200720072903a8023703a003410221084102210a024020120d0020074198026a41086a2009290100370300200741d0036a41086a200b290300370300200741d0036a41106a200c290300370300200741d0036a41186a200d290300370300200741d0036a41206a200e290300370300200720072901fe0237039802200720072903900337038802200720072800970336008f02200720072903a0033703d0032013210a0b41012109200a4102460d01200741b6026a20074198026a41086a290300370100200741a0036a41086a200741d0036a41086a290300370300200741a0036a41106a200741d0036a41106a290300370300200741a0036a41186a200741d0036a41186a290300370300200741a0036a41206a200741d0036a41206a29030037030020072007290398023701ae0220072007290388023703f8022007200728008f023600ff02200720072903d0033703a00341002109200a21080c010b0240200728029c02450d00200810350b41012109410221080b200741f0016a41086a200741a8026a41086a220a290100370300200741f0016a410e6a220b200741a8026a410e6a290100370100200741b8016a41086a220c200741a0036a41086a220d290300370300200741b8016a41106a220e200741a0036a41106a2212290300370300200741b8016a41186a2213200741a0036a41186a2214290300370300200741b8016a41206a2215200741a0036a41206a290300370300200720072901a8023703f001200720072903f8023703e001200720072800ff023600e701200720072903a0033703b8010240024002400240024020090d00200741e8006a41186a200f3a0000200741fc006a2010360200200741e8006a41206a20072800e701360000200741e8006a41286a220f20072903b801370300200741e8006a41086a200b290100370300200741e8006a41306a200c290300370300200741e8006a41386a200e290300370300200741e8006a41c0006a2013290300370300200741e8006a41c8006a2015290300370300200720072901f60137036820072011360278200720072903e001370081012007200836028c01200741d0036a41186a4200370300200741d0036a41106a220c4200370300200741d0036a41086a22094200370300200742003703d00341d1c4c700ad4280808080e000841001220b29000021162009200b41086a290000370300200720163703d003200b103541e7c4c700ad4280808080e000841001220b2900002116200a200b41086a290000370300200720163703a802200b1035200c20072903a8022216370300200d2009290300370300201220163703002014200a290300370300200720072903d0033703a003200741e0006a200741a0036a412010c0012007280264410020072802601b210c20084101470d01200f280200200c470d0120004183243b0100200041086a4115360200200041046a41d880c700360200200041026a41053a00000c020b20004183243b0100200041086a4115360200200041046a41fcffc600360200200041026a41023a00000c020b200741f0016a200210f303200741d0036a20072802f001220820072802f80110d902200741f8026a41086a2209200741da036a290100370300200741f8026a410e6a220a200741d0036a41106a290000370100200741a0036a41086a200741d0036a41386a290300370300200741a0036a41106a200741d0036a41c0006a290300370300200741a0036a41186a200741d0036a41c8006a290300370300200741a0036a41206a200741a0046a290300370300200720072901d2033703f8022007200741f1036a290000370390032007200741d0036a41286a280000360097032007200741d0036a41306a2903003703a00302400240024020072d00d003220b4102460d00200741d0036a41206a2d0000210f200741ec036a280200210d200741d0036a41186a280200210e20072d00d1032110200741a8026a410e6a200a290100370100200741a8026a41086a2009290300370300200720072903f8023703a802024020072802f401450d00200810350b200741d0036a410e6a2208200741a8026a410e6a290100370100200741d0036a41086a2209200741a8026a41086a290300370300200720072903a8023703d003200b0d02200d450d01200e10350c010b20072802f401450d00200810350b20004183243b0100200041086a411a360200200041046a419c80c700360200200041026a41033a00000c010b200741e0026a410e6a220a2008290100370100200741e0026a41086a220b2009290300370300200741c1016a200b290300370000200741c7016a200a290100370000200720103a00b801200720072903d0033700b9012007200f3a00d7012007200d3600d3012007200e3600cf01200641086a2802002113200728028c01211520072802900121172007200628020022143602e00220072014201341057422096a3602e4022007200741e8006a3602e802024002400240024002400240024002402013450d002014210803402007200841206a220a3602e002200741d0036a200b200810800620072802d00322080d02200a2108200941606a22090d000b0b4104210d41002109410021110c010b200741a0036a41086a2211200741d0036a410c6a280200360200200720072902d4033703a00341101033220d450d01200d2008360200200d20072903a003370204200d410c6a201128020036020020074281808080103702fc022007200d3602f8022011200741e0026a41086a280200360200200720072903e00222163703a00302402016a7220820072802a4032209470d0041012109410121110c010b200741d0036a410472210f200941606a211241012109024003402007200841206a220a3602a003200741d0036a20112008108006024020072802d003220e0d002012200846210b200a2108200b450d010c020b200741a8026a41086a200f41086a280200220b3602002007200f29020022163703a802200741d0036a41086a2210200b360200200720163703d0030240200920072802fc02470d00200741f8026a20094101108c0120072802f802210d0b200d20094104746a220b200e360200200b20072903d003370204200b410c6a20102802003602002007200941016a2209360280032012200847210b200a2108200b0d000b0b20072802fc0221110b200741a0036a200728027820072802800110f4030240024020073502a80342208620072802a0032212ad8410212216422088a7220f0d00410121100c010b2016a721100b200741003602d803200742013703d0032010200f200741d0036a1097030240024020072802d403220b20072802d80322086b4120490d0020072802d003210a200b210e0c010b200841206a220a2008490d02200b410174220e200a200e200a4b1b220e4100480d0202400240200b0d000240200e0d004101210a0c020b200e1033220a0d010c070b20072802d003210a200b200e460d00200a200b200e1037220a450d060b2007200e3602d4032007200a3602d0030b200a20086a220b2003290000370000200b41186a200341186a290000370000200b41106a200341106a290000370000200b41086a200341086a2900003700002007200841206a22083602d8032008ad422086200aad84100922082900002116200841086a2900002118200841106a2900002119200741a8026a41186a200841186a290000370300200741a8026a41106a2019370300200741a8026a41086a2018370300200720163703a802200810350240200e450d00200a10350b0240200f450d00201010350b024020072802a403450d00201210350b0240200741a8026a200741b8016a412010a0080d000240024020090d004100210a0c010b2009410474210b200d410c6a21084100210a03402008280200200a6a210a200841106a2108200b41706a220b0d000b0b200741e8006a41106a2108200c201720131b210b4101201520131b210e2007200728028401200a6b36028401200741d0036a200110f30320073502d80342208620072802d003220aad841007024020072802d403450d00200a10350b200741d0036a41106a200537030020074180046a200b360200200741fc036a200e360200200741f8036a200c360200200741f4036a200728028401360200200741d0036a41186a2008290300370300200741f0036a200841086a28020036020020074184046a20032900003702002007418c046a200341086a29000037020020074194046a200341106a2900003702002007419c046a200341186a290000370200200720043703d803200741003a00d003200741a0036a200210f30320072802a0032108200720072802a8033602fc02200720083602f802200741d0036a200741f8026a108a04024020072802a403450d00200810350b0240200741ec036a280200450d0020072802e80310350b200741a0036a2001108e02200741d0036a20072802a003220820072802a803108f0220072903d0032105200741e0036a290300211620072903d8032118024020072802a403450d00200810350b200742003703f801200742003703f001200720013602f802200741a0036a2001200741f0016a200741f8026a1088040240024020072903a003221a4202520d00420221040c010b200741c8036a290300211b200741c0036a2903002119200741a0036a41186a2903002104201a4201520d0020072903a803211a20074188046a200741a0036a41106a29030037030020074180046a201a370300200741d0036a41086a41003a0000200741d9036a2001290000370000200741e1036a200141086a290000370000200741e9036a200141106a290000370000200741f1036a200141186a290000370000200741033a00d00341b0b4cc004100200741d0036a10d4010b200542015121014200201b200442025122081b211b4200201920081b21194200200420081b2104024020080d00200741d0036a41186a220e4200370300200741d0036a41106a220b4200370300200741d0036a41086a220a4200370300200742003703d00341b6fdc600ad428080808080018422051001220c290000211a200741e0026a41086a2208200c41086a2900003703002007201a3703e002200c1035200a2008290300370300200720072903e0023703d00341e489c200ad4280808080d00184221a1001220c290000211c2008200c41086a2900003703002007201c3703e002200c1035200b20072903e002221c370300200741a0036a41086a220f200a290300370300200741a0036a41106a2210201c370300200741a0036a41186a22122008290300370300200720072903d0033703a003200741c8006a200741a0036a412010d701200741c8006a41106a290300211c2007290350211d2007280248210c200e4200370300200b4200370300200a4200370300200742003703d00320051001220e29000021052008200e41086a290000370300200720053703e002200e1035200a2008290300370300200720072903e0023703d003201a1001220e29000021052008200e41086a290000370300200720053703e002200e1035200b20072903e0022205370300200f200a2903003703002010200537030020122008290300370300200720072903d0033703a0032007201c4200200c1b3703d8032007201d4200200c1b3703d003200741a0036aad4280808080800484200741d0036aad428080808080028410020b2016420020011b21052018420020011b2116200741f8026a41106a220b201b3703002007201937038003200720043703f802200741f8026a41086a21080240024020044200520d00200720083602f001200741d0036a41186a220e4200370300200741d0036a41106a220a4200370300200741d0036a41086a22014200370300200742003703d00341b6fdc600ad428080808080018422041001220c2900002118200741e0026a41086a2208200c41086a290000370300200720183703e002200c103520012008290300370300200720072903e0023703d00341e489c200ad4280808080d0018422181001220c29000021192008200c41086a290000370300200720193703e002200c1035200a20072903e0022219370300200741a0036a41086a220f2001290300370300200741a0036a41106a22102019370300200741a0036a41186a22122008290300370300200720072903d0033703a003200741186a200741a0036a412010d701200741186a41106a29030021192007290320211b2007280218210c200b290300211a200729038003211c200e4200370300200a420037030020014200370300200742003703d00320041001220b29000021042008200b41086a290000370300200720043703e002200b103520012008290300370300200720072903e0023703d00320181001220b29000021042008200b41086a290000370300200720043703e002200b1035200a20072903e0022204370300200f20012903003703002010200437030020122008290300370300200720072903d0033703a0032007427f201a20194200200c1b22047c201c201b4200200c1b22187c22192018542208ad7c22182008201820045420182004511b22081b3703d8032007427f201920081b3703d003200741a0036aad4280808080800484200741d0036aad428080808080028410020c010b200720083602f001200741d0036a41186a220e4200370300200741d0036a41106a220a4200370300200741d0036a41086a22014200370300200742003703d00341b6fdc600ad428080808080018422181001220c2900002104200741e0026a41086a2208200c41086a290000370300200720043703e002200c103520012008290300370300200720072903e0023703d00341e489c200ad4280808080d0018422191001220c29000021042008200c41086a290000370300200720043703e002200c1035200a20072903e0022204370300200741a0036a41086a220f2001290300370300200741a0036a41106a22102004370300200741a0036a41186a22122008290300370300200720072903d0033703a003200741306a200741a0036a412010d701200741306a41106a290300211b2007290338211a2007280230210c200b290300211c2007290380032104200e4200370300200a420037030020014200370300200742003703d00320181001220b29000021182008200b41086a290000370300200720183703e002200b103520012008290300370300200720072903e0023703d00320191001220b29000021182008200b41086a290000370300200720183703e002200b1035200a20072903e0022218370300200f20012903003703002010201837030020122008290300370300200720072903d0033703a00320074200201b4200200c1b2218201c7d201a4200200c1b2219200454ad7d221b201920047d2204201956201b201856201b2018511b22081b3703d80320074200200420081b3703d003200741a0036aad4280808080800484200741d0036aad428080808080028410020b200720163703f802200720053703800302400240201620058450450d0042002105420021160c010b200720023602e002200741a0036a2002200741f8026a200741e0026a10b002024020072903a0034201520d00200741b0036a290300211620072903a80321050c010b200741c8036a2903002116200741c0036a290300210520072903a8034201520d00200741a0036a41106a290300210420074188046a200741a0036a41186a29030037030020074180046a2004370300200741d0036a41086a41003a0000200741d9036a2002290000370000200741e1036a200241086a290000370000200741e9036a200241106a290000370000200741f1036a200241186a290000370000200741033a00d00341b0b4cc004100200741d0036a10d4010b200741d0036a41186a220c4200370300200741d0036a41106a220a4200370300200741d0036a41086a22014200370300200742003703d00341b6fdc600ad428080808080018422041001220b2900002118200741e0026a41086a2208200b41086a290000370300200720183703e002200b103520012008290300370300200720072903e0023703d00341e489c200ad4280808080d0018422181001220b29000021192008200b41086a290000370300200720193703e002200b1035200a20072903e0022219370300200741a0036a41086a220e2001290300370300200741a0036a41106a220f2019370300200741a0036a41186a22102008290300370300200720072903d0033703a0032007200741a0036a412010d701200741106a29030021192007290308211b2007280200210b200c4200370300200a420037030020014200370300200742003703d00320041001220c29000021042008200c41086a290000370300200720043703e002200c103520012008290300370300200720072903e0023703d00320181001220c29000021042008200c41086a290000370300200720043703e002200c1035200a20072903e0022204370300200e2001290300370300200f200437030020102008290300370300200720072903d0033703a0032007427f20194200200b1b220420167c201b4200200b1b221620057c22182016542208ad7c22052008200520045420052004511b22081b3703d8032007427f201820081b3703d003200741a0036aad4280808080800484200741d0036aad42808080808002841002200041043a000002402009450d0020094104742108200d41046a210003400240200041046a280200450d00200028020010350b200041106a2100200841706a22080d000b0b0240201141ffffffff0071450d00200d10350b200641046a28020041ffffff3f71450d08201410350c080b200d20094104746a210a024020090d00200d21080c030b200741d0036aad42808080808004842119200d210803400240200828020022090d00200841106a21080c040b200841086a280200210b200841046a28020021012008410c6a3502002104200741a0036a200728027820072802800110f4032009ad4280808080800484100922092900002105200941086a2900002116200941106a2900002118200741d0036a41186a200941186a290000370300200741d0036a41106a2018370300200741d0036a41086a2016370300200720053703d0032009103520073502a80342208620072802a0032209ad84201920044220862001ad841012024020072802a403450d00200910350b0240200b450d00200110350b200841106a2208200a470d000c040b0b1045000b103e000b200a2008460d000340200841106a21090240200841086a280200450d00200841046a28020010350b20092108200a2009470d000b0b0240201141ffffffff0071450d00200d10350b20004183243b0100200041086a4110360200200041046a41c080c700360200200041026a41043a00000c010b103c000b200728027c450d00200728027810350b200641046a28020041ffffff3f71450d00200628020010350b200741d0046a24000bd90e03087f037e027f23004180026b2202240041002103200241003a00b801200041b0b4cc0020011b210402400240024002400240034020012003460d0120024198016a20036a200420036a2d00003a00002002200341016a22003a00b8012000210320004120470d000b200241086a41186a20024198016a41186a290300370300200241086a41106a20024198016a41106a290300370300200241086a41086a20024198016a41086a290300370300200220022903980137030841002103200241003a00b801200420006a2104200120006b2101034020012003460d0220024198016a20036a200420036a2d00003a00002002200341016a22003a00b8012000210320004120470d000b200241286a41186a220320024198016a41186a2204290300370300200241286a41106a220020024198016a41106a290300370300200241286a41086a220120024198016a41086a2903003703002002200229039801370328200241c8006a41186a200241086a41186a290300370300200241c8006a41106a200241086a41106a290300370300200241c8006a41086a200241086a41086a29030037030020022002290308370348200241e8006a41186a2003290300370300200241e8006a41106a2000290300370300200241e8006a41086a200129030037030020022002290328370368200241f0016a200241c8006a10f30320024198016a20022802f001220020022802f80110d90220022802f401210320022d00980122014102460d02200241c4016a2802002105200241b8016a2802002106200241b4016a28020021072004280200210802402003450d00200010350b410121092001450d03410121040c040b0240200341ff0171450d00200241003a00b8010b200241ac016a4102360200200241f4006a41043602002002420237029c01200241f0b2c300360298012002410436026c200241f0b4c3003602682002410036024c200241b0b4cc003602482002200241e8006a3602a8012002200241c8006a36027020024198016a4180b3c300104c000b0240200341ff0171450d00200241003a00b8010b200241ac016a4102360200200241f4006a41043602002002420237029c01200241f0b2c300360298012002410436026c200241f0b4c3003602682002410036024c200241b0b4cc003602482002200241e8006a3602a8012002200241c8006a36027020024198016a4180b3c300104c000b02402003450d00200010350b41012104410021090c010b4101210420054102460d00200241f0016a2008200610f403200241e8006aad428080808080048410092203290000210a200341086a290000210b200341106a290000210c20024198016a41186a200341186a29000037030020024198016a41106a200c37030020024198016a41086a200b3703002002200a370398012003103520024188016a20023502f80142208620022802f0012203ad8420024198016aad4280808080800484101010c201024020022802f401450d00200310350b20024188016a41086a280200210d2002280288012101200228028c01210e4100210402402007450d00200810350b0b410121030240024002400240024002400240024020040d00200d41066a410220011b2203417f4c0d0220030d0041002103410121000c010b200310332200450d020b200241003602a00120022000360298012002200336029c0102402004450d00024020030d00410110332200450d052002410136029c0120022000360298010b200041013a0000200241013602a0012002280298012103200228029c0121000240200941ff01714101460d00024020004101470d0020034101410210372203450d062002410236029c0120022003360298010b200341003a0001200241023602a0010c060b024020004101470d0020034101410210372203450d052002410236029c0120022003360298010b200341013a0001200241023602a0010c050b024020030d00410110332200450d042002410136029c0120022000360298010b200041003a0000200241013602a0012002280298012103200228029c0121000240024020010d00024020004101470d0020034101410210372203450d062002410236029c0120022003360298010b200341003a0001200241023602a001428080808020210a0c010b024020004101470d0020034101410210372203450d052002410236029c0120022003360298010b200341013a0001200241023602a001200d20024198016a107702400240200228029c01220420022802a00122006b200d490d0020022802980121030c010b2000200d6a22032000490d04200441017422092003200920034b1b22094100480d040240024020040d00024020090d00410121030c020b2009103322030d010c070b200228029801210320042009460d0020032004200910372203450d060b2002200936029c0120022003360298010b200320006a2001200d109d081a20022000200d6a22003602a0012000ad422086210a0b200a2003ad84210a2001450d05200e450d05200110350c050b1044000b1045000b103e000b103c000b2003ad42808080802084210a0b20024180026a2400200a0bb10503027f017e047f230041d0006b2202240041f1d8cb00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541abe0c600ad4280808080e00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb30101037f02400240024002402002417f4c0d000240024020020d0041002103410121040c010b200210332204450d02200221030b0240024020032002490d00200321050c010b200341017422052002200520024b1b22054100480d03024020030d002005103322040d010c050b20032005460d0020042003200510372204450d040b200420012002109d0821032000200236020820002005360204200020033602000f0b1044000b1045000b103e000b103c000ba70c04037f047e047f037e23004190046b2202240041002103200241003a008003200041b0b4cc0020011b210402400240024002400240034020012003460d01200241e0026a20036a200420036a2d00003a00002002200341016a22003a0080032000210320004120470d000b200241386a41186a200241e0026a41186a2903002205370300200241386a41106a200241e0026a41106a2903002206370300200241386a41086a200241e0026a41086a2903002207370300200220022903e0022208370338200241d8006a41186a2005370300200241d8006a41106a2006370300200241d8006a41086a200737030020022008370358200241d0016a200241d8006a10f303200241e0026a20022802d001220020022802d80110d90220022d00e0022103200241b8036a200241e0026a41017241d700109d081a024020034102460d00200241f8006a200241b8036a41d700109d081a0b024020022802d401450d00200010350b410121002003417f6a41ff01714102490d04200241d0016a200241ff006a220941d000109d081a200241e0026a41186a220a4200370300200241e0026a41106a22044200370300200241e0026a41086a22034200370300200242003703e00241d1c4c700ad4280808080e000841001220029000021052003200041086a290000370300200220053703e0022000103541e7c4c700ad4280808080e00084100122002900002105200241c0026a41086a2201200041086a290000370300200220053703c00220001035200420022903c0022205370300200241b8036a41086a2003290300370300200241b8036a41106a220b2005370300200241b8036a41186a2001290300370300200220022903e0023703b803200241306a200241b8036a412010c001200241a0026a200241d8006a2002280234410020022802301b220c4100200241d0016a10f603200241b8036a200941d000109d081a200241c0026a41186a200241a0026a41186a290300370300200241c0026a41106a200241a0026a41106a2903003703002001200241a0026a41086a290300370300200220022903a0023703c002200241e0026a200241d8006a200241b8036a200c200241c0026a10f703410121014101210020022d00e002417f6a41ff01714102490d03200429030021082003290300210d20024184036a2802002103200241fc026a2802002104200a2802002109200241c0026a200241d8006a108e02200241b8036a20022802c002220a20022802c802108f02200b290300420020022903b80342015122001b210620022903c003420020001b2105024020022802c402450d00200a10350b200241206a20052006428080a8ec85afd1b1014200109808200241106a42002003ad22072002290320220e7d220f200f2007564200200241206a41086a2903002007200e54ad7c7d22074200522007501b22031b220e4200200720031b2207428080e983b1de164200108408200e200784500d022005428080d287e2bc2d5441002006501b0d0120022005428080aef89dc3527c2207200d200d200756200820062007200554ad7c427f7c22055620082005511b22031b2005200820031b2002290310200241106a41086a29030010980820022903002205a7417f2005428080808010544100200241086a290300501b1b210302402004450d00200910350b2003200c6a210441002101410021000c040b0240200341ff0171450d00200241003a0080030b200241f4026a4102360200200241c4036a4104360200200242023702e402200241f0b2c3003602e002200241043602bc0320024184b5c3003602b8032002410036027c200241b0b4cc003602782002200241b8036a3602f0022002200241f8006a3602c003200241e0026a4180b3c300104c000b41c780ca00419b0141e481ca001064000b410021002004450d00200910350b0b02400240410110332203450d000240024002402000450d00200341013a000020034101410210372203450d04200341013a00010c010b200341003a000020034101410210372103024020014101460d002003450d04200341003a000120034102410610372203450d04200320043600024280808080e00021050c020b2003450d03200341013a00010b42808080802021050b20024190046a240020052003ad840f0b1045000b103c000bb90504017f017e017f057e23004190016b220524000240024041004100200220036b2203200320024b1b220220042802206b2203200320024b1b22030d00420021060c010b20054180016a2001108e02200541306a2005280280012207200528028801108f0242002106200541c0006a2903004200200529033042015122021b21082005290338420020021b21090240200528028401450d00200710350b200541206a20092008428080a8ec85afd1b101420010980842002004411c6a350200220a2005290320220b7d220c200c200a564200200541286a290300200a200b54ad7c7d220a420052200a501b22021b220b4200200a20021b220a844200510d00420121062009428080d287e2bc2d5441002008501b0d00200541106a2003ad4200200b200a10840820052005290310200541106a41086a290300428080e983b1de164200108408024002402009428080aef89dc3527c22062004290300220a200a200656200441086a290300220a20082006200954ad7c427f7c220656200a2006511b22041b220b2005290300220c200b200c542006200a20041b220a200541086a290300220b54200a200b511b22041b2206200a200b20041b220a8450450d00410121020c010b42002008200a7d2009200654ad7d220b200920067d220c200956200b200856200b2008511b22021b21094200200c20021b210b20054180016a2001108e02200541306a2005280280012203200528028801108f02200541e0006a2903004200200529033042015122021b2108200541d8006a290300420020021b210c0240200528028401450d00200310350b200c200b58200820095820082009511b21020b024020040d002002450d0020002006370308200041106a200a370300420321060c010b200041186a200a370300200041106a200637030020002002ad370308420221060b2000200637030020054190016a24000bbe1d05017f037e057f037e037f230041f0026b220524000240024002400240024002400240024020042802000e0401020300010b200441106a290300210620042903082107200541e0006a2003360200200541386a41186a2002290310370300200541e4006a2002290224370200200541d8006a200241186a290300370300200541386a41346a200229022c370200200541386a413c6a200241346a290200370200200541386a41c4006a2002413c6a29020037020020054184016a200241c4006a290200370200200541386a41106a200241086a29030020067d20022903002208200754ad7d37030041002102200541003a00382005200820077d370340200541e0016a200110f30320052802e0012104200520052802e80136029c012005200436029801200541386a20054198016a10f805024020052802e401450d00200410350b200541003a00df01200541083a009701200520013602d801200520073703e002200520063703e80202400240200720068450450d0042002107420021060c010b200520013602c8012005200541c8016a3602f001200520054197016a3602ec012005200541d8016a3602e8012005200541df016a3602e4012005200541e0026a3602e00120054198016a2001200541e0016a10dc034101210202402005280298014101470d004200210620052903a00121070c010b200541c0016a2903002106200541b8016a29030021074100210220052903a0014201520d0020054198016a41106a290300210820052802c801210120054198026a20054198016a41186a29030037030020054190026a200837030041002102200541e0016a41086a41003a0000200541e9016a2001290000370000200541f1016a200141086a290000370000200541f9016a200141106a29000037000020054181026a200141186a290000370000200541033a00e00141b0b4cc004100200541e0016a10d4010b024020020d00200520073703c801200520063703d0010240024020072006844200520d002005200541c8016a3602d801200541c8016a21030c010b200520063703d001200520073703c8012005200541c8016a3602d801200541c8016a21030b200541e0016a41186a22094200370300200541e0016a41106a22044200370300200541e0016a41086a22014200370300200542003703e00141b6fdc600ad428080808080018422061001220a2900002107200541e0026a41086a2202200a41086a290000370300200520073703e002200a103520012002290300370300200520052903e0023703e00141e489c200ad4280808080d0018422081001220a29000021072002200a41086a290000370300200520073703e002200a1035200420052903e002220737030020054198016a41086a220b200129030037030020054198016a41106a220c200737030020054198016a41186a220d2002290300370300200520052903e00137039801200541206a20054198016a412010d701200541206a41106a290300210e2005290328210f2005280220210a200341086a290300211020032903002107200942003703002004420037030020014200370300200542003703e00120061001220329000021062002200341086a290000370300200520063703e0022003103520012002290300370300200520052903e0023703e00120081001220329000021062002200341086a290000370300200520063703e00220031035200420052903e0022206370300200b2001290300370300200c2006370300200d2002290300370300200520052903e0013703980120054200200e4200200a1b220620107d200f4200200a1b2208200754ad7d220e200820077d2207200856200e200656200e2006511b22021b3703e80120054200200720021b3703e00120054198016aad4280808080800484200541e0016aad428080808080028410020b2000200541386a41d800109d081a0c060b200541e7016a200241d000109d081a200041003a0000200041016a200541e0016a41d700109d081a0c050b200541e0016a200110f30320053502e80142208620052802e0012204ad841007024020052802e401450d00200410350b200541e0016a2002280210220a200241186a28020010f40320053502e80142208620052802e0012204ad841011024020052802e401450d00200410350b200541e0016a41086a41023a000020054189026a41003a0000200541e9016a2001290000370000200541f1016a200141086a290000370000200541f9016a200141106a29000037000020054181026a200141186a2900003700002005410d3a00e00141b0b4cc004100200541e0016a10d401200041023a00000c010b024020042903084201520d00200441106a2903002107200441186a290300210641002104200541003a00d801200541083a00df01200520063703a0012005200737039801200520013602c80102400240200720068450450d0042002107420021060c010b200520013602e0022005200541e0026a3602f0012005200541df016a3602ec012005200541c8016a3602e8012005200541d8016a3602e401200520054198016a3602e001200541386a2001200541e0016a10dc0341012104024020052802384101470d0042002106200529034021070c010b200541e0006a2903002106200541d8006a29030021074100210420052903404201520d00200541386a41106a290300210820052802e002210320054198026a200541386a41186a29030037030020054190026a200837030041002104200541e0016a41086a41003a0000200541e9016a2003290000370000200541f1016a200341086a290000370000200541f9016a200341106a29000037000020054181026a200341186a290000370000200541033a00e00141b0b4cc004100200541e0016a10d4010b20040d00200541e0016a41186a22094200370300200541e0016a41106a22034200370300200541e0016a41086a220a4200370300200542003703e00141b6fdc600ad4280808080800184220f1001220b2900002108200541e0026a41086a2204200b41086a290000370300200520083703e002200b1035200a2004290300370300200520052903e0023703e00141e489c200ad4280808080d0018422101001220b29000021082004200b41086a290000370300200520083703e002200b1035200320052903e002220837030020054198016a41086a220b200a29030037030020054198016a41106a220c200837030020054198016a41186a220d2004290300370300200520052903e00137039801200541086a20054198016a412010d701200541086a41106a2903004200200528020822111b21082005290310420020111b210e024020072006844200520d002009420037030020034200370300200a4200370300200542003703e001200f1001221129000021072004201141086a290000370300200520073703e00220111035200a2004290300370300200520052903e0023703e00120101001221129000021072004201141086a290000370300200520073703e00220111035200320052903e002370000200341086a2004290300370000200b200a290300370300200c2003290300370300200d2009290300370300200520052903e00137039801200520083703e8012005200e3703e00120054198016aad4280808080800484200541e0016aad428080808080028410020c010b2009420037030020034200370300200a4200370300200542003703e001200f10012211290000210f2004201141086a2900003703002005200f3703e00220111035200a2004290300370300200520052903e0023703e001201010012211290000210f2004201141086a2900003703002005200f3703e00220111035200320052903e002370000200341086a2004290300370000200b200a290300370300200c2003290300370300200d2009290300370300200520052903e0013703980120054200200820067d200e200754ad7d2206200e20077d2207200e56200620085620062008511b22041b3703e80120054200200720041b3703e00120054198016aad4280808080800484200541e0016aad428080808080028410020b200541e0016a2002280210220a200241186a280200221210f4030240024020053502e80142208620052802e0012204ad8410212207422088a7220d0d00410121110c010b2007a721110b024020052802e401450d00200410350b200541003602e801200542013703e0012011200d200541e0016a1097030240024020052802e401220b20052802e80122096b4120490d00200941206a210420052802e0012103200b210c0c010b200941206a22042009490d02200b41017422032004200320044b1b220c4100480d0202400240200b0d000240200c0d00410121030c020b200c103322030d010c050b20052802e0012103200b200c460d002003200b200c10372203450d040b2005200c3602e401200520033602e0010b200320096a22092002412c6a220b290000370000200941186a200b41186a290000370000200941106a200b41106a290000370000200941086a200b41086a290000370000200520043602e80120054198016a41186a22092004ad4220862003ad841009220441186a29000037030020054198016a41106a220b200441106a29000037030020054198016a41086a2213200441086a2900003703002005200429000037039801200410350240200c450d00200310350b200541d1006a2009290300370000200541c9006a200b290300370000200541c1006a20132903003700002005200529039801370039200541013a0038200541e0016a200110f30320052802e0012104200520052802e8013602e402200520043602e002200541386a200541e0026a10f805024020052802e401450d00200410350b200541e0016a200a201210f40320053502e80142208620052802e0012204ad841011024020052802e401450d00200410350b200541e0016a41086a41023a000020054189026a41013a0000200541e9016a2001290000370000200541f1016a200141086a290000370000200541f9016a200141106a29000037000020054181026a200141186a2900003700002005410d3a00e00141b0b4cc004100200541e0016a10d4012000200541386a41d800109d081a200d450d00201110350b200241146a280200450d02200a10350c020b103e000b103c000b200541f0026a24000ba50503027f037e027f230041c0076b22022400024002402001450d00200220003602100c010b200241b0b4cc003602100b20022001360214200241e8036a200241106a10c80302400240024020022903d0044203510d00200241186a200241e8036a41c803109d081a200228021422014104490d0120022802102200280000210320022001417c6a3602142002200041046a360210200241e8036a200241186a41c803109d081a200241b0076a20024180056a220110d8032002200320022903b007220420022d00b9074200420010db0341082100200241086a29030021052002290300210620022d00b8072103200110ba02410810332201450d022001200437000002400240200341024d0d00410821030c010b024002400240024020030e03000102000b410021030c020b410121030c010b410221030b200220033a00e8034110210020014108411010372201450d03200120033a0008410921030b200341107221070240200020036b410f4b0d002000200041017422082007200820074b1b2208460d0020012000200810372201450d030b200120036a2200200537000820002006370000200241c0076a24002007ad4220862001ad840f0b200241bc076a41043602002002412c6a41023602002002420237021c200241f0b2c300360218200241043602b4072002419cb5c3003602b007200241003602e403200241b0b4cc003602e0032002200241b0076a3602282002200241e0036a3602b807200241186a4180b3c300104c000b200241bc076a4104360200200241fc036a4102360200200242023702ec03200241f0b2c3003602e803200241043602b4072002419cb5c3003602b007200241003602e403200241b0b4cc003602e0032002200241b0076a3602f8032002200241e0036a3602b807200241e8036a4180b3c300104c000b103c000bd30f04037f017e027f017e230041a0026b220224000240024020010d002002200136020c200241b0b4cc003602080c010b20022001417f6a36020c2002200041016a36020820002d0000220041014b0d004100210102400240024002400240024020000e020100010b2002200241086a10c40120022802000d05200228020c220320022802042200490d052000417f4c0d010240024020000d0041002103410121010c010b200010392201450d032001200228020822042000109d081a2002200320006b36020c2002200420006a360208200021030b2001450d052000ad4220862003ad8421050b410021030240024020010d00410021040c010b2005422088a72200417f4c0d010240024020000d0041002106410121040c010b200010332204450d03200021060b0240024020062000490d00200621070c010b200641017422072000200720004b1b22074100480d04024020060d002007103322040d010c060b20062007460d0020042006200710372204450d050b200420012000109d081a2005428080808070832007ad8421080b200220083702142002200436021020024190016a41e7e485f306200241106a10fa030240024020010d000c010b2005422088a72200417f4c0d010240024020000d0041002104410121030c010b200010332203450d03200021040b0240024020042000490d00200421060c010b200441017422062000200620004b1b22064100480d04024020040d00200610332203450d060c010b20042006460d0020032004200610372203450d050b200320012000109d081a2005428080808070832006ad8421080b2002200837021420022003360210200241b0016a41e2c289ab06200241106a10fb03410021030240024020010d00410021040c010b2005422088a72200417f4c0d010240024020000d0041002106410121040c010b200010332204450d03200021060b0240024020062000490d00200621070c010b200641017422072000200720004b1b22074100480d04024020060d00200710332204450d060c010b20062007460d0020042006200710372204450d050b200420012000109d081a2005428080808070832007ad8421080b2002200837021420022004360210200241d0016a41e9dabdf306200241106a10fb030240024020010d000c010b2005422088a72200417f4c0d010240024020000d0041002104410121030c010b200010332203450d03200021040b0240024020042000490d00200421060c010b200441017422062000200620004b1b22064100480d04024020040d00200610332203450d060c010b20042006460d0020032004200610372203450d050b200320012000109d081a2005428080808070832006ad8421080b20022008370294022002200336029002200241f0016a41e1ea91cb0620024190026a10fb03200241106a41086a220320024190016a41086a290300370300200241106a41106a220420024190016a41106a290300370300200241106a41186a220620024190016a41186a290300370300200241386a200241b0016a41086a290300370300200241c0006a200241b0016a41106a290300370300200241c8006a200241b0016a41186a290300370300200241d8006a200241d0016a41086a290300370300200241e0006a200241d0016a41106a290300370300200241e8006a200241d0016a41186a2903003703002002200229039001370310200220022903b001370330200220022903d00137035020024188016a200241f0016a41186a29030037030020024180016a200241f0016a41106a290300370300200241f8006a200241f0016a41086a290300370300200220022903f001370370412010332200450d0320002002290310370000200041186a2006290300370000200041106a2004290300370000200041086a20032903003700002000412041c00010372200450d032000200241106a41206a2203290000370020200041386a200341186a290000370000200041306a200341106a290000370000200041286a200341086a290000370000200041c00041800110372200450d032000200241106a41c0006a22032900003700402000200241f0006a2204290000370060200041d8006a200341186a290000370000200041d0006a200341106a290000370000200041c8006a200341086a290000370000200041e8006a200441086a290000370000200041f0006a200441106a290000370000200041f8006a200441186a29000037000002402001450d002005a7450d00200110350b41840110332201450d01200242840137021420022001360210418001200241106a10770240024020022802142206200228021822036b418001490d0020034180016a2104200228021021010c010b20034180016a22042003490d03200641017422012004200120044b1b22074100480d030240024020060d00024020070d00410121010c020b200710332201450d060c010b2002280210210120062007460d0020012006200710372201450d050b20022007360214200220013602100b200120036a2000418001109d081a20001035200241a0026a24002004ad4220862001ad840f0b1044000b1045000b103e000b103c000b200241fc016a4104360200200241246a410236020020024202370214200241f0b2c300360210200241043602f401200241b0b5c3003602f001200241003602d401200241b0b4cc003602d0012002200241f0016a3602202002200241d0016a3602f801200241106a4180b3c300104c000bfa0103037f037e037f230041306b220324002003200136020c200341106a200210e503200328021421042003410c6a200335021842208620032802102205ad84102e22012900002106200141086a2900002107200141106a2900002108200341106a41186a2209200141186a290000370300200341106a41106a220a2008370300200341106a41086a220b20073703002003200637031020011035200041186a2009290300370000200041106a200a290300370000200041086a200b2903003700002000200329031037000002402004450d00200510350b024020022802002200450d00200241046a280200450d00200010350b200341306a24000bfa0103037f037e037f230041306b220324002003200136020c200341106a200210e503200328021421042003410c6a200335021842208620032802102205ad84103022012900002106200141086a2900002107200141106a2900002108200341106a41186a2209200141186a290000370300200341106a41106a220a2008370300200341106a41086a220b20073703002003200637031020011035200041186a2009290300370000200041106a200a290300370000200041086a200b2903003700002000200329031037000002402004450d00200510350b024020022802002200450d00200241046a280200450d00200010350b200341306a24000bc50c03037f017e077f230041c0026b22022400024002402001450d00200220003602080c010b200241b0b4cc003602080b2002200136020c2002200241086a10c401024002400240024020022802000d00200228020c220320022802042201490d0002402001417f4c0d000240024020010d0041002103410121000c010b200110392200450d032000200228020822042001109d081a2002200320016b36020c2002200420016a360208200121030b2000450d0120022001ad4220862003ad8422054220883e029c02200220003602980220024190016a20024198026a10c2020240024020022d0090014101470d00410021060c010b200241106a20024190016a410172418001109d081a20024190016a200241106a418001109d081a200241003602a802200242043703a002412010332201450d032001200229039001370000200141186a20024190016a41186a290300370000200141106a20024190016a41106a290300370000200141086a20024190016a41086a290300370000200241a0026a41004101108c0120022802a002220620022802a80222044104746a220341e7e485f30636020c200342a08080808004370204200320013602002002200441016a22013602a802200241b0026a20024190016a41206a10fd030240200120022802a4022207470d00200241a0026a20014101108c0120022802a402210720022802a002210620022802a80221010b200620014104746a220320022903b002370200200341e2c289ab0636020c200341086a200241b0026a41086a2802003602002002200141016a22013602a802200241b0026a200241d0016a10fd03024020012007470d00200241a0026a20074101108c0120022802a402210720022802a002210620022802a80221010b200620014104746a220320022903b002370200200241b0026a41086a22042802002108200341e9dabdf30636020c200341086a20083602002002200141016a22013602a802200241b0026a200241f0016a10fd03024020012007470d00200241a0026a20074101108c0120022802a402210720022802a002210620022802a80221010b200620014104746a220320022903b00237020020042802002104200341e1ea91cb0636020c200341086a2004360200200141016a21090b02402005a7450d00200010350b0240024020060d00410121010c010b20094104744105722201417f4c0d010b200110332200450d022002410036029801200220013602940120022000360290010240024020060d00200041003a00004101210020024101360298010c010b200041013a00002002410136029801200920024190016a1077024020090d0020022802980121000c010b200620094104746a210a2006210103402001280200210b200141086a280200220020024190016a107702400240200228029401220c20022802980122086b2000490d002002280290012103200c21040c010b200820006a22032008490d06200c41017422042003200420034b1b22044100480d0602400240200c0d00024020040d00410121030c020b2004103322030d010c090b2002280290012103200c2004460d002003200c200410372203450d080b200220043602940120022003360290010b200320086a200b2000109d081a2002200820006a2200360298010240200420006b41034b0d00200041046a22082000490d062004410174220c2008200c20084b1b22084100480d060240024020040d00024020080d00410121030c020b200810332203450d090c010b20042008460d0020032004200810372203450d080b200220083602940120022003360290010b200320006a2001410c6a2800003600002002200041046a220036029801200141106a2201200a470d000b0b2000ad42208620023502900184210502402006450d0002402009450d00200941047421002006210103400240200141046a280200450d00200128020010350b200141106a2101200041706a22000d000b0b200741ffffffff0071450d00200610350b200241c0026a240020050f0b1044000b2002411c6a4104360200200241a4016a41023602002002420237029401200241f0b2c3003602900120024104360214200241d0b5c300360210200241003602b402200241b0b4cc003602b0022002200241106a3602a0012002200241b0026a36021820024190016a4180b3c300104c000b1045000b103e000b103c000b5f01017f02404120103322020d001045000b200042a080808080043702042000200236020020022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700000bfc0403027f017e057f230041d0006b2202240041a9d1cb00ad4280808080c00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541fcd1cb00ad4280808080900284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bca1d09017f017e047f017e027f037e057f047e017f230041c0046b2200240042002101200041f8016a41186a22024200370300200041f8016a41106a22034200370300200041f8016a41086a22044200370300200042003703f80141a9d1cb00ad4280808080c000841001220529000021062004200541086a290000370300200020063703f8012005103541cde4cb00ad4280808080b00184100122052900002106200041d8036a41086a2207200541086a290000370300200020063703d80320051035200320002903d803220637030020004198046a41086a200429030037030020004198046a41106a200637030020004198046a41186a2007290300370300200020002903f80137039804200041f8016a20004198046a10b70202400240024020002d00f8014102470d00200242003703002003420037030020044200370300200042003703f80141d1c4c700ad4280808080e000841001220529000021062004200541086a290000370300200020063703f801200510354185c5c700ad4280808080e0008410012205290000210620004190016a41086a2207200541086a29000037030020002006370390012005103520032000290390012206370300200041f0026a41086a2004290300370300200041f0026a41106a2006370300200041f0026a41186a2007290300370300200020002903f8013703f002200041f8016a200041f0026a10ce020240024020002802f80122080d0041042108410021040c010b20002902fc012201422088a721040b02400240200441246c2205450d002008210402400340024020042d00004101470d00200441016a2800002107200441086a28020021022000200441106a2802003602f402200020023602f002200741c28289aa04470d00200041f8016a200041f0026a10800420002903f80122064203520d020b200441246a21042005415c6a2205450d020c000b0b2000290380022109200041286a20004188026a41e800109d081a0c010b420321060b02402001422088a72204450d00200441246c21052008210403400240024020042d0000220741044b0d0002400240024020070e050400010204040b2004410c6a280200450d03200441086a28020010350c030b2004410c6a280200450d02200441086a28020010350c020b2004410c6a280200450d01200441086a28020010350c010b200441086a280200450d00200441046a28020010350b200441246a21042005415c6a22050d000b0b02402001a72204450d00200441246c450d00200810350b20004190016a200041286a41e800109d081a0240024020064203520d004100210720004198046a21080c010b200041f0026a20004190016a41e800109d081a200041f8016a41186a22054200370300200041f8016a41106a22074200370300200041f8016a41086a22044200370300200042003703f80141a9d1cb00ad4280808080c00084220a1001220229000021012004200241086a290000370300200020013703f8012002103541c2d1cb00ad4280808080b00184220b100122082900002101200041d8036a41086a2202200841086a290000370300200020013703d80320081035200320002903d803370000200341086a220c200229030037000020004198046a41086a2208200429030037030020004198046a41106a220d200729030037030020004198046a41186a220e2005290300370300200020002903f80137039804200041186a20004198046a10e102024002402000280218450d002000290320500d0020004198046aad4280808080800484210120004198046a21080c010b200542003703002007420037030020044200370300200042003703f801200a1001220f29000021012004200f41086a290000370300200020013703f801200f1035200b1001220f29000021012002200f41086a290000370300200020013703d803200f1035200320002903d803370000200c200229030037000020082004290300370300200d2007290300370300200e2005290300370300200020002903f80137039804200020093703f80120004198046aad42808080808004842201200041f8016aad42808080808001841002200542003703002007420037030020044200370300200042003703f801200a1001220f290000210b2004200f41086a2900003703002000200b3703f801200f103541b7d1cb00ad4280808080b001841001220f290000210b2002200f41086a2900003703002000200b3703d803200f1035200320002903d803370000200c200229030037000020082004290300370300200d2007290300370300200e2005290300370300200020002903f80137039804200041f8016a20004198046a10dd0220002802f801210f20002902fc01210b200542003703002007420037030020044200370300200042003703f801200a10012210290000210a2004201041086a2900003703002000200a3703f8012010103541d8d1cb00ad4280808080a0018410012210290000210a2002201041086a2900003703002000200a3703d80320101035200320002903d803370000200c200229030037000020082004290300370300200d2007290300370300200e2005290300370300200020002903f80137039804200041f8016a20004198046a10b10220002d00f8012105200e20004191026a290000370300200d20004189026a290000370300200820004181026a290000370300200020002900f90137039804200b4200200f1b210a200b428080808070834200200f1b210b200f4108200f1b21040240024020054101460d0020004190046a420037030020004188046a420037030020004180046a4200370300200042003703f8030c010b200041f8036a41186a20004198046a41186a290300370300200041f8036a41106a20004198046a41106a290300370300200041f8036a41086a20004198046a41086a29030037030020002000290398043703f8030b200041d8036a41086a200041f8036a41086a2903002211370300200041d8036a41106a200041f8036a41106a2903002212370300200041d8036a41186a200041f8036a41186a2903002213370300200020002903f80322143703d803200041f8016a41086a200b200a42ffffffff0f8384370300200041f8016a41106a2014370300200041f8016a41186a201137030020004198026a2012370300200041f8016a41286a2013370300200020043602fc01200041003602f80120004198046a200041f8016a10810420004183046a20004198046a41086a28020036000020002000290398043700fb03200041a4046a200041ff036a290000370000200041c28289aa0436009904200041023a009804200020002900f80337009d0420004198046a1082040240200aa72205450d00200541286c450d00200410350b20004198046a21080b200041f8016a41186a22054200370300200041f8016a41106a22074200370300200041f8016a41086a22044200370300200042003703f80141a9d1cb00ad4280808080c00084220a10012202290000210b2004200241086a2900003703002000200b3703f8012002103541cdd1cb00ad4280808080b00184220b1001220d2900002111200041d8036a41086a2202200d41086a290000370300200020113703d803200d1035200320002903d803370000200341086a220d200229030037000020004198046a41086a220e200429030037030020004198046a41106a220c200729030037030020004198046a41186a220f2005290300370300200020002903f80137039804200041086a20004198046a10e1022000280208211520002903102111200542003703002007420037030020044200370300200042003703f801200a1001221029000021122004201041086a290000370300200020123703f801201010354199c2c300ad42808080808001841001221029000021122002201041086a290000370300200020123703d80320101035200320002903d803370000200d2002290300370000200e2004290300370300200c2007290300370300200f2005290300370300200020002903f80137039804200042002009201142017c420120151b7d221120112009561b3e02f8012001200041f8016aad22114280808080c000841002200542003703002007420037030020044200370300200042003703f801200a10012210290000210a2004201041086a2900003703002000200a3703f80120101035200b10012210290000210a2002201041086a2900003703002000200a3703d80320101035200320002903d803370000200d2002290300370000200e2004290300370300200c2007290300370300200f2005290300370300200020002903f80137039804200020093703f80120012011428080808080018410024100210720064200520d00200041f8016a200041f0026a41e800109d081a200041f8036a41186a20004194026a290200370300200041f8036a41106a2000418c026a290200370300200041f8036a41086a20004184026a290200370300200020002902fc013703f803410121070b200041f0026a41186a200041f8036a41186a290300370300200041f0026a41106a200041f8036a41106a290300370300200041f0026a41086a200041f8036a41086a290300370300200020002903f8033703f002200041f8016a41186a22024200370300200041f8016a41106a220d4200370300200041f8016a41086a22044200370300200042003703f80141a9d1cb00ad4280808080c000841001220529000021062004200541086a290000370300200020063703f8012005103541cde4cb00ad4280808080b00184100122052900002106200041d8036a41086a220e200541086a290000370300200020063703d80320051035200320002903d803370000200341086a200e29030037000020004198046a41086a200429030037030020004198046a41106a200d29030037030020004198046a41186a2002290300370300200020002903f80137039804410110332204450d010240024020070d00200441003a000042808080801021060c010b200441013a000020044101412110372204450d03200420002903f002370001200441196a20004188036a290300370000200441116a20004180036a290300370000200441096a200041f8026a2903003700004280808080900421060b2008ad428080808080048420062004ad841002200410350b200041c0046a24000f0b1045000b103c000ba71405067f017e027f057e047f23004190036b22022400024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002005417f6a220541024b0d0420050e03010203010b200042033703000c050b024020064104490d002004280001210720012003417b6a22053602042001200441056a36020020054108490d00200429000521082001200341736a36020420012004410d6a36020041002105200241003a0028410d20036b2109200341726a2106024002400340200920056a450d01200241086a20056a200420056a220a410d6a2d00003a0000200120063602042001200a410e6a3602002002200541016a220a3a00282006417f6a2106200a2105200a4120470d000b200241b0026a41086a200241086a41086a290300370300200241b0026a41106a200241086a41106a290300370300200241b0026a41186a200241086a41186a290300370300200220022903083703b00241002105200241003a00482004200a6a2109200a20036b410d6a21030340200320056a450d02200241086a20056a200920056a2204410d6a2d00003a00002001200636020420012004410e6a3602002002200541016a22043a00482006417f6a210620042105200441c000470d000b200241d0026a41386a200241086a41386a290300220b370300200241d0026a41306a200241086a41306a290300220c370300200241d0026a41286a200241086a41286a290300220d370300200241d0026a41206a200241086a41206a290300220e370300200241d0026a41186a200241086a41186a290300220f370300200241d0016a41086a2201200241086a41086a290300370300200241d0016a41106a2204200241086a41106a290300370300200241d0016a41186a2205200f370300200241d0016a41206a2206200e370300200241d0016a41286a2203200d370300200241d0016a41306a220a200c370300200241d0016a41386a2209200b370300200220022903083703d00120024190026a41186a2210200241b0026a41186a29030037030020024190026a41106a2211200241b0026a41106a29030037030020024190026a41086a2212200241b0026a41086a290300370300200220022903b00237039002200241b0016a41186a22132010290300370300200241b0016a41106a22102011290300370300200241b0016a41086a2211201229030037030020022002290390023703b001200241f0006a41386a22122009290300370300200241f0006a41306a2209200a290300370300200241f0006a41286a220a2003290300370300200241f0006a41206a22032006290300370300200241f0006a41186a22062005290300370300200241f0006a41106a22052004290300370300200241f0006a41086a22042001290300370300200220022903d001370370200041106a20073602002000200837030820004200370300200020022903b0013702142000411c6a2011290300370200200041246a20102903003702002000412c6a2013290300370200200020022903703702342000413c6a2004290300370200200041c4006a2005290300370200200041cc006a2006290300370200200041d4006a2003290300370200200041dc006a200a290300370200200041e4006a2009290300370200200041ec006a20122903003702000c070b200541ff0171450d01200241003a00280c010b200541ff0171450d00200241003a00480b200042033703000c040b024020064104490d002004280001210620012003417b6a22053602042001200441056a36020020054108490d0020004201370300200429000521082001200341736a36020420012004410d6a360200200041106a200636020020002008370308200041146a200241086a41e400109d081a0c040b200042033703000c030b20064104490d012004280001210720012003417b6a22053602042001200441056a36020020054108490d01200429000521082001200341736a36020420012004410d6a36020041002105200241003a0028410d20036b2109200341726a2106024002400340200920056a450d01200241086a20056a200420056a220a410d6a2d00003a0000200120063602042001200a410e6a3602002002200541016a220a3a00282006417f6a2106200a2105200a4120470d000b200241b0026a41086a200241086a41086a290300370300200241b0026a41106a200241086a41106a290300370300200241b0026a41186a200241086a41186a290300370300200220022903083703b00241002105200241003a00482004200a6a2109200a20036b410d6a21030340200320056a450d02200241086a20056a200920056a2204410d6a2d00003a00002001200636020420012004410e6a3602002002200541016a22043a00482006417f6a210620042105200441c000470d000b200241d0026a41386a200241086a41386a290300220b370300200241d0026a41306a200241086a41306a290300220c370300200241d0026a41286a200241086a41286a290300220d370300200241d0026a41206a200241086a41206a290300220e370300200241d0026a41186a200241086a41186a290300220f370300200241d0016a41086a2201200241086a41086a290300370300200241d0016a41106a2204200241086a41106a290300370300200241d0016a41186a2205200f370300200241d0016a41206a2206200e370300200241d0016a41286a2203200d370300200241d0016a41306a220a200c370300200241d0016a41386a2209200b370300200220022903083703d00120024190026a41186a2210200241b0026a41186a29030037030020024190026a41106a2211200241b0026a41106a29030037030020024190026a41086a2212200241b0026a41086a290300370300200220022903b00237039002200241b0016a41186a22132010290300370300200241b0016a41106a22102011290300370300200241b0016a41086a2211201229030037030020022002290390023703b001200241f0006a41386a22122009290300370300200241f0006a41306a2209200a290300370300200241f0006a41286a220a2003290300370300200241f0006a41206a22032006290300370300200241f0006a41186a22062005290300370300200241f0006a41106a22052004290300370300200241f0006a41086a22042001290300370300200220022903d001370370200041106a20073602002000200837030820004202370300200020022903b0013702142000411c6a2011290300370200200041246a20102903003702002000412c6a2013290300370200200020022903703702342000413c6a2004290300370200200041c4006a2005290300370200200041cc006a2006290300370200200041d4006a2003290300370200200041dc006a200a290300370200200041e4006a2009290300370200200041ec006a20122903003702000c040b200541ff0171450d02200241003a00280c020b200541ff0171450d01200241003a00480c010b200042033703000c010b200042033703000b20024190036a24000bd90a02087f017e230041106b220224002002410036020820024201370300024002402001280200220341024b0d0002400240024002400240024020030e03000102000b410110332203450d062002410136020420022003360200200341013a000020024101360208200128020421032001410c6a2802002204200210770240024020040d00200228020821050c010b2003200441286c6a2106200228020821050340024002402002280204220720056b4120490d00200541206a210420022802002108200721090c010b200541206a22042005490d05200741017422082004200820044b1b22094100480d050240024020070d00024020090d00410121080c020b2009103322080d010c0b0b2002280200210820072009460d0020082007200910372208450d0a0b20022009360204200220083602000b200820056a22052003290000370000200541186a200341186a290000370000200541106a200341106a290000370000200541086a200341086a29000037000020022004360208200341206a290300210a0240200920046b41074b0d00200441086a22052004490d05200941017422072005200720054b1b22054100480d050240024020090d00024020050d00410121080c020b200510332208450d0b0c010b20092005460d0020082009200510372208450d0a0b20022005360204200220083602000b200820046a200a3700002002200441086a22053602082006200341286a2203470d000b0b024002402002280204220420056b4120490d00200228020021030c010b200541206a22032005490d03200441017422082003200820034b1b22084100480d030240024020040d00024020080d00410121030c020b200810332203450d090c010b2002280200210320042008460d0020032004200810372203450d080b20022008360204200220033602000b200320056a2203200141106a2204290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200541206a3602080c050b410110332203450d052002410136020420022003360200200341023a000020024101360208200128020421080240024020022802042204417f6a4104490d00200228020021030c010b200441017422034105200341054b1b22054100480d0220022802002103024020042005460d0020032004200510372203450d070b20022005360204200220033602000b20032008360001200241053602080c040b410110332203450d042002410136020420022003360200200341033a00002002410136020820022802002103024020022802044101470d0020034101410210372203450d0520024102360204200220033602000b200341013a0001200241023602082001290308210a0240024020022802042204417e6a4108490d00200228020021030c010b20044101742203410a2003410a4b1b22084100480d0120022802002103024020042008460d0020032004200810372203450d060b20022008360204200220033602000b2003200a3700022002410a3602082001290310210a2002280204220441766a41074b0d01200441017422034112200341124b1b22084100480d0020022802002103024020042008460d0020032004200810372203450d050b2003200a37000a200220083602042002200336020020024112360208200141186a2d000021080c020b103e000b20022802002203200a37000a20024112360208200141186a2d0000210820044112470d0020034112412410372203450d0220024124360204200220033602000b200320083a0012200241133602080b20002002290300370200200041086a200241086a280200360200200241106a24000f0b103c000bd00703047f017e057f230041f0006b22012400200141c8006a41186a4200370300200141c8006a41106a22024200370300200141c8006a41086a220342003703002001420037034841d1c4c700ad4280808080e000841001220429000021052003200441086a29000037030020012005370348200410354185c5c700ad4280808080e00084100122042900002105200141386a41086a2206200441086a2900003703002001200537033820041035200220012903382205370300200141186a41086a2003290300370300200141186a41106a2005370300200141186a41186a200629030037030020012001290348370318200141c8006a200141186a10ce0202400240200128024822020d0041002106200141003602102001420437030841042102410021030c010b2001200129024c220537020c200120023602082005422088a721032005a721060b200141c8006a41206a2207200041206a280200360200200141c8006a41186a2208200041186a290200370300200141c8006a41106a2209200041106a290200370300200141c8006a41086a2204200041086a29020037030020012000290200370348024020032006470d00200141086a20034101108d01200128020c210620012802082102200128021021030b2002200341246c220a6a22002001290348370200200041206a2007280200360200200041186a2008290300370200200041106a2009290300370200200041086a20042903003702002001200341016a22003602102008420037030020094200370300200442003703002001420037034841d1c4c700ad4280808080e000841001220829000021052004200841086a29000037030020012005370348200810354185c5c700ad4280808080e00084100122082900002105200141386a41086a2207200841086a2900003703002001200537033820081035200920012903382205370300200141186a41086a2004290300370300200141186a41106a2005370300200141186a41186a2007290300370300200120012903483703182001412036024c2001200141186a36024820022000200141c8006a109606024020002003490d00200a41246a21032002210003400240024020002d0000220441044b0d0002400240024020040e050400010204040b2000410c6a280200450d03200041086a28020010350c030b2000410c6a280200450d02200041086a28020010350c020b2000410c6a280200450d01200041086a28020010350c010b200041086a280200450d00200041046a28020010350b200041246a21002003415c6a22030d000b0b02402006450d00200641246c450d00200210350b200141f0006a24000b7402027f027e230041e0006b22032400200341d0006a2002108e022003200328025022042003280258108f02200341106a2903004200200329030042015122021b21052003290308420020021b210602402003280254450d00200410350b2000200637030020002005370308200341e0006a24000bca0102017f037e230041306b220524000240024020030d00200041003602000c010b20052003280200200328020810f4032004ad4280808080800484100922032900002106200341086a2900002107200341106a2900002108200541106a41186a200341186a290000370300200541106a41106a2008370300200541106a41086a200737030020052006370310200310352000200535020842208620052802002203ad84200541106aad4280808080800484101010c2012005280204450d00200310350b200541306a24000b8505010a7f230041e0016b2203240020034198016a200210f303200341c0006a200328029801220420032802a00110d902200341a8016a41086a2205200341c0006a41286a290300370300200341a8016a41106a2206200341c0006a41306a290300370300200341a8016a41186a2207200341f8006a290300370300200341a8016a41206a220820034180016a290300370300200341a8016a41286a220920034188016a290300370300200341a8016a41306a220a20034190016a2802003602002003200341c0006a41206a2903003703a801200341dc006a280200210b200341c0006a41186a280200210c024020032d004022024102460d00200341086a41306a200a280200360200200341086a41286a2009290300370300200341086a41206a2008290300370300200341086a41186a2007290300370300200341086a41106a2006290300370300200341086a41086a2005290300370300200320032903a8013703080b0240200328029c01450d00200410350b0240024020024102470d00200041003a00000c010b200341c0006a41306a200341086a41306a280200360200200341c0006a41286a200341086a41286a290300370300200341c0006a41206a200341086a41206a290300370300200341c0006a41186a200341086a41186a290300370300200341c0006a41106a200341086a41106a290300370300200341c0006a41086a200341086a41086a2903003703002003200329030837034002402002450d00200041003a00000c010b20002003290254370001200041013a0000200041196a200341ec006a290200370000200041116a200341e4006a290200370000200041096a200341dc006a290200370000200b450d00200c10350b200341e0016a24000b5601027f230041206b22022400200241106a200110f303200241086a20022802102203200228021841b0b4cc0041004100108a022002280208210102402002280214450d00200310350b200241206a240020014101460bbc0104027f027e027f017e230041f0006b22032400200341e0006a200210f303200341086a20032802602204200328026810d902200341186a2903002105200341106a2903002106200341246a2802002107200341206a280200210820032d0008210202402003280264450d00200410350b420021090240200241ff017122044102460d00200445ad21092007450d00200241ff01710d00200810350b2000200637030820002009370300200041106a2005370300200341f0006a24000b971009037f027e027f077e047f057e017f067e047f230041d0036b2204240020032802002105200441206a2001108e02200441a0016a2004280220220320042802282206108f0220042903a001210742002108200442003703a001200441e8016a280200210920042d00ec01210a0240024020074201510d00200441306a41306a4200370300200441306a41286a4200370300200441306a41206a4200370300200441306a41186a4200370300200441c0006a4200370300200441386a4200370300200442003703304200210b4200210c4200210d4200210e0c010b200441d8016a290300210f200441a0016a41306a2903002110200441a0016a41206a290300210b200441a0016a41186a2903002108200441e0016a290300210e20042903b001210d20042903a801210c200441306a41206a200441a0016a41286a290300370300200441306a41286a2010370300200441306a41306a200f370300200441c0006a20083703002004200b3703482004200c3703302004200d3703380b427f200d200b7c200c20087c2211200c542212ad7c220f2012200f200d54200f200d511b22121b2110427f201120121b2111024002400240427f2002290300220f20087c22082008200f542212200241086a2903002208200b7c2012ad7c220b200854200b2008511b22021b42ffffe883b1de1656427f200b20021b220b420052200b501b0d002011201084500d010b2004200f37033020042008370338200441e8006a41186a200441306a41186a290300220b370300200441e8006a41206a2213200441306a41206a290300370300200441e8006a41286a2214200441306a41286a290300370300200441e8006a41306a2215200441306a41306a290300370300200420083703702004200f370368200420042903402216370378200c200f56200d200856200d2008511b21022008200d7d200f200c54ad7d2117200d20087d200c200f54ad7d2118200f200c7d2119200c200f7d211a201120108450211b02400240427f200f20167c220d200d200f5422122008200b7c2012ad7c220d200854200d2008511b22121b220c428080e983b1de16544100427f200d20121b220d501b0d00200441f8006a29030021162015290300211c2014290300211d2013290300211e2004290370211f200429036821204201211120042903800121210c010b02400240200c200d8450450d00420021110c010b42002111200441a0026a41186a22224200370300200441a0026a41106a22144200370300200441a0026a41086a22134200370300200442003703a00241b6fdc600ad4280808080800184220b100122152900002110200441c0036a41086a2212201541086a290000370300200420103703c0032015103520132012290300370300200420042903c0033703a00241e489c200ad4280808080d0018422101001221529000021162012201541086a290000370300200420163703c00320151035201420042903c0032216370300200441a0036a41086a22232013290300370300200441a0036a41106a22242016370300200441a0036a41186a22252012290300370300200420042903a0023703a003200441086a200441a0036a412010d701200441086a41106a29030021162004290310211c20042802082115202242003703002014420037030020134200370300200442003703a002200b10012222290000210b2012202241086a2900003703002004200b3703c0032022103520132012290300370300200420042903c0033703a002201010012222290000210b2012202241086a2900003703002004200b3703c00320221035201420042903c003220b370300202320132903003703002024200b37030020252012290300370300200420042903a0023703a003200442002016420020151b220b200d7d201c420020151b2210200c54ad7d22162010200c7d221c2010562016200b562016200b511b22121b3703a80220044200201c20121b3703a002200441a0036aad4280808080800484200441a0026aad42808080808002841002200441d8026a200d370300200441d0026a200c370300201341013a0000200441a9026a2005290000370000200441b1026a200541086a290000370000200441b9026a200541106a290000370000200441c1026a200541186a290000370000200441033a00a00241b0b4cc004100200441a0026a10d4010b0b2018201720021b210c201a201920021b210b2002ad2110201bad210d200441c8016a201e370300200441d0016a201d370300200441b0016a201f370300200441d8016a201c370300200441b8016a2016370300200420213703c0012004200e3703e001200420203703a801410021022004200a4100200742015122121b3a00ec0120042009410020121b3602e801200420114201512212ad3703a001024020120d002006ad4220862003ad8410070c020b200420063602a402200420033602a002200441a8016a200441a0026a10e702410121020c010b4202210d0b02402004280224450d00200310350b02400240200d4202520d00200042023703000c010b02400240024020074201510d00200241ff0171450d0041032103200441a0026a21020c010b20074201520d01200241ff01710d0141042103200441a0016a21020b200241086a20033a0000200241003a0000200241096a2001290000370000200241116a200141086a290000370000200241196a200141106a290000370000200241216a200141186a29000037000041b0b4cc004100200210d4010b2000200f3703082000200d370300200041286a200c370300200041206a200b370300200041106a2008370300200041186a20103703000b200441d0036a24000b9c0607047f017e017f017e017f017e047f230041e0006b22022400200241306a41186a22034200370300200241306a41106a22044200370300200241306a41086a220542003703002002420037033041f1d8cb00ad42808080809001842206100122072900002108200241d0006a41086a2209200741086a2900003703002002200837035020071035200520092903003703002002200229035037033041fad8cb00ad4280808080e00184220810012207290000210a2009200741086a2900003703002002200a3703502007103520042002290350220a370300200241106a41086a220b2005290300370300200241106a41106a220c200a370300200241106a41186a220d2009290300370300200220022903303703102002200241106a10e1022002280200210e2002290308210a2003420037030020044200370300200542003703002002420037033020061001220729000021062009200741086a2900003703002002200637035020071035200520092903003703002002200229035037033020081001220729000021062009200741086a2900003703002002200637035020071035200420022903502206370300200b2005290300370300200c2006370300200d2009290300370300200220022903303703102002200a42017c4201200e1b2206370330200241106aad4280808080800484200241306aad4280808080800184100202400240412010332209450d0020092001290000370000200941186a200141186a290000370000200941106a200141106a290000370000200941086a200141086a2900003700002009412041c00010372205450d0020052006370020200241306a41186a22012005ad42808080808005841009220941186a290000370300200241306a41106a2204200941106a290000370300200241306a41086a2207200941086a2900003703002002200929000037033020091035412010332209450d0120092002290330370000200042a0808080800437020420002009360200200941186a2001290300370000200941106a2004290300370000200941086a200729030037000020051035200241e0006a24000f0b103c000b1045000bf10203037f017e037f230041106b22022400200241003602082002420137030020002d00002103410110332104024002400240024020034101460d002004450d02200441003a0000200220043602002002428180808010370204200041086a200210f705200235020842208621052002280204452104200228020021000c010b2004450d01200441013a0000200220043602002002428180808010370204412010332203450d0220032000290001370000200341186a2206200041196a290000370000200341106a2207200041116a290000370000200341086a2208200041096a29000037000020044101412110372200450d0120002003290000370001200041096a2008290000370000200041116a2007290000370000200041196a200629000037000020022000360200200242a1808080900437020420031035410021044280808080900421050b200129020020052000ad841002024020040d00200010350b200241106a24000f0b103c000b1045000b3400200041a9d1cb0036020420004100360200200041146a410a360200200041106a41d4c2c300360200200041086a42043702000b910101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120103322060d001045000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000b130020004102360204200041c8d7c3003602000b2d01017f02404108103322020d001045000b20004288808080800137020420002002360200200242b8173700000b2d01017f02404108103322020d001045000b20004288808080800137020420002002360200200242c8013700000bee0202097f027e230041206b220324000240200128020041016a220441004c0d00200120043602000240024020012802042205450d00200141086a28020021060340200541086a210720052f0106220841057421094100210a0240024003402009450d0120022007412010a008220b450d02200941606a2109200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21080b2006450d022006417f6a2106200520084102746a41880b6a28020021050c010b0b2005200a41e0006c6a220941c5036a310000200941e8026a290300220c200c5022071ba7450d004200200941f8026a29030020071b210c4200200941f0026a29030020071b210d0c010b200341086a20012802102002200141146a28020028021c110400200341106a290300210c200128020021042003290308210d0b20012004417f6a3602002000200c3703082000200d370300200341206a24000f0b41ac96cc004118200341186a41d8c1c30041d496cc001046000ba60502097f017e230041106b220524000240024002400240024002400240024002400240200128020041016a220641004c0d002001200636020020012802042207450d07200141086a28020021080340200741086a210920072f0106220a41057421064100210b0240024003402006450d0120022009412010a008220c450d02200641606a2106200b41016a210b200941206a2109200c417f4a0d000b200b417f6a210a0b2008450d092008417f6a21082007200a4102746a41880b6a28020021070c010b0b2007200b41e0006c6a220d4198036a22062802002207450d05200628020421080340200741086a210920072f0106220a41057421064100210b0240024003402006450d0120042009412010a008220c450d02200641606a2106200b41016a210b200941206a2109200c417f4a0d000b200b417f6a210a0b2008450d072008417f6a21082007200a4102746a41ec036a28020021070c010b0b0240200741e8026a200b410c6c6a220628020022070d0041012109410021060c070b20062802082209417f4c0d010240024020090d004100210b410121060c010b200910332206450d032009210b0b02400240200b2009490d00200b210c0c010b200b410174220c2009200c20094b1b220c4100480d040240200b0d00200c103322060d010c060b200b200c460d002006200b200c10372206450d050b200620072009109d081a2009ad422086200cad84210e410121090c060b41ac96cc004118200541086a41d8c1c30041d496cc001046000b1044000b1045000b103e000b103c000b410021090b0240200d41e8026a2d005d450d002006410020091b21060c020b20090d010b20002001280210200220032004200141146a28020028020c1105000c010b2000200e370204200020063602000b20012001280200417f6a360200200541106a24000bd10401097f230041c0006b220324000240200128020041016a220441004c0d002001200436020002400240024020012802042205450d00200141086a28020021060340200541086a210720052f0106220841057421094100210a0240024003402009450d0120022007412010a008220b450d02200941606a2109200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21080b2006450d022006417f6a2106200520084102746a41880b6a28020021050c010b0b2005200a41e0006c6a220741e8026a210902400240200741c5036a2d00000d00200341206a41086a220a200941c5006a290000370300200341206a41106a220b200941cd006a290000370300200341206a41186a2205200941d5006a29000037030020032009413d6a2900003703204102210720092d003c4101470d01200341186a2005290300370300200341106a200b290300370300200341086a200a29030037030020032003290320370300410121070c010b200341086a200941c5006a290000370300200341106a200941cd006a290000370300200341186a200941d5006a29000037030020032009413d6a29000037030020092d003c21070b200741ff01714102470d010b200020012802102002200141146a280200280210110400200128020021040c010b200020073a000020002003290300370001200041096a200341086a290300370000200041116a200341106a290300370000200041196a200341186a2903003700000b20012004417f6a360200200341c0006a24000f0b41ac96cc004118200341206a41d8c1c30041d496cc001046000bbe0201097f230041106b220224000240200028020041016a220341004c0d002000200336020002400240024020002802042204450d00200041086a28020021050340200441086a210620042f010622074105742108410021090240024003402008450d0120012006412010a008220a450d02200841606a2108200941016a2109200641206a2106200a417f4a0d000b2009417f6a21070b2005450d022005417f6a2105200420074102746a41880b6a28020021040c010b0b2004200941e0006c6a220841a4036a2d000022064101410220064101461b200841c5036a2d00001b22084102470d010b20002802102001200041146a2802002802181101002108200028020021030c010b200841004721080b20002003417f6a360200200241106a240020080f0b41ac96cc004118200241086a41d8c1c30041d496cc001046000b820302097f037e230041206b220324000240200128020041016a220441004c0d00200120043602000240024020012802042205450d00200141086a28020021060340200541086a210720052f0106220841057421094100210a0240024003402009450d0120022007412010a008220b450d02200941606a2109200a41016a210a200741206a2107200b417f4a0d000b200a417f6a21080b2006450d022006417f6a2106200520084102746a41880b6a28020021050c010b0b2005200a41e0006c6a22094190036a290300210c20094188036a290300210d20094180036a290300210e0240200941c5036a2d00000d00200ea721094201210e2009450d010c020b200e4202520d010b200320012802102002200141146a280200280214110400200341106a290300210c200128020021042003290308210d2003290300210e0b20012004417f6a360200200041106a200c3703002000200d3703082000200e370300200341206a24000f0b41ac96cc004118200341186a41d8c1c30041d496cc001046000bc82107067f017e067f057e107f047e027f230041f00c6b220224000240024002400240024020002802000d002000417f36020002400240200128020022030d004100210141002103410021040c010b2001280208210402400240200128020422050d00200321010c010b2005210120032106034020062802880b21062001417f6a22010d000b200321010340200120012f01064102746a41880b6a28020021012005417f6a22050d000b200621030b20012f010621050b2002411c6a2005360200200241186a4100360200200241146a2001360200200220043602202002410036021020024200370308200220033602042002410036020002402004450d0020022004417f6a3602202003450d020240024020032f0106450d004100210741002106410021050c010b4100210641002105034002400240200328020022010d002005ad2108410021010c010b200641016a210620033301044220862005ad8421080b200310352008a72105200121032008422088a7220720012f01064f0d000b200121030b200241d00c6a41186a2209200320074105746a220141206a290000370300200241d00c6a41106a220a200141186a290000370300200241d00c6a41086a220b200141106a2900003703002002200141086a2900003703d00c2003200741e0006c6a220441a4036a2d0000210c200441a0036a280200210d2004419c036a280200210e20044198036a280200210120044190036a290300210f20044188036a290300211020044180036a2903002111200441f8026a2903002112200441f0026a2903002113200441e8026a2903002108200241d0016a41186a2214200441bd036a290000370300200241d0016a41106a2215200441b5036a290000370300200241d0016a41086a2216200441ad036a2900003703002002200441a5036a2900003703d001200741016a2107200441c6036a2f01002117200441c5036a2d0000211802402006450d00200320074102746a41880b6a2802002103410021072006417f6a2206450d00034020032802880b21032006417f6a22060d000b0b200241f0096a41186a2009290300370300200241f0096a41106a200a290300370300200241f0096a41086a200b29030037030020024188016a41086a201629030037030020024188016a41106a201529030037030020024188016a41186a2014290300370300200220022903d00c3703f009200220022903d001370388012002200736020c20022005360208200220033602042002410036020020084202510d002000410c6a2119200041046a211a200241d0016a41206a2107200241840a6a211b200241d0016a413d6a211c200241d0016a41286a211d0340200241c8006a41186a2203200241f0096a41186a2209290300370300200241c8006a41106a2205200241f0096a41106a220a290300370300200241c8006a41086a2206200241f0096a41086a220b290300370300200241286a41086a220420024188016a41086a221e290300370300200241286a41106a221420024188016a41106a221f290300370300200241286a41186a221520024188016a41186a2220290300370300200220022903f0093703482002200229038801370328200241e8006a41186a22212015290300370300200241e8006a41106a22222014290300370300200241e8006a41086a222320042903003703002002200229032837036820202003290300370300201f2005290300370300201e2006290300370300200220022903483703880102400240201a2802002214450d00200028020821150c010b200241f0096a410041e002109f081a200241d0016a410041a008109f081a41880b10332214450d0541002115201441003b010620144100360200201441086a200241f0096a41e002109d081a201441e8026a200241d0016a41a008109d081a20004100360208200020143602040b024002400340201441086a210520142f01062216410574210341002106024003402003450d0120024188016a2005412010a0082204450d03200341606a2103200641016a2106200541206a21052004417f4a0d000b2006417f6a21160b02402015450d002015417f6a2115201420164102746a41880b6a28020021140c010b0b200241d00c6a41186a20202903002224370300200241d00c6a41106a201f2903002225370300200241d00c6a41086a201e2903002226370300200220022903880122273703d00c201b2027370200201b41086a2026370200201b41106a2025370200201b41186a2024370200200220193602800a200220163602fc092002201a3602f809200220143602f409200241003602f009201d200f370300200241d0016a41106a2012370300200220103703f001200220133703d8012002200c3a008c022002200d360288022002200e360284022002200136028002200220113703e801200220083703d001201c2002290368370000201c41086a2023290300370000201c41106a2022290300370000201c41186a2021290300370000200220173b01ae02200220183a00ad02200241f0096a200241d0016a1080031a0c010b201441e8026a200641e0006c6a2105024020184101710d0020052005290300200820085022031b37030020052005290308201320031b370308200541106a22062006290300201220031b37030020092021290300370300200a2022290300370300200b2023290300370300200220022903683703f00920052d003c2106200241d0016a41186a2218200541d5006a2204290000370300200241d0016a41106a2221200541cd006a2214290000370300200241d0016a41086a2222200541c5006a221529000037030020022005413d6a22162900003703d001201e200241f0096a200241d0016a200c41ff0171410146220c1b220341086a290000370300201f200341106a2900003703002020200341186a2900003703002002200329000037038801200541012006200c1b3a003c20162002290388013700002015201e2903003700002014201f290300370000200420202903003700002005201020052903202011a722031b370320200541286a2206200f200629030020031b37030020052011200529031820031b3703180240024020010d0041002101410021034100210d0c010b02400240200e0d00200121030c010b200e210320012106034020062802ec0321062003417f6a22030d000b200121030340200320032f01064102746a41ec036a2802002103200e417f6a220e0d000b200621010b20032f010621280b2002200d3602a801200220283602a401200241003602a0012002200336029c01200241003602980120024200370390012002200136028c0120024100360288010240200d450d002002200d417f6a22163602a8012001450d08200541306a210c4100210641002105034002400240200620012f01064f0d0020012103410021040c010b41002104034002400240200128020022030d002005ad2108410021030c010b200441016a210420013301044220862005ad8421080b200110352008a72105200321012008422088a7220620032f01064f0d000b0b200241d00c6a41186a2214200320064105746a220141206a290000370300200241d00c6a41106a220e200141186a290000370300200241d00c6a41086a2215200141106a2900003703002002200141086a2900003703d00c200241b0016a41086a220d20032006410c6c6a220141f0026a2802003602002002200141e8026a2902003703b001200641016a21060240024020040d00200321010c010b200320064102746a41ec036a2802002101410021062004417f6a2203450d00034020012802ec0321012003417f6a22030d000b0b200720022903b001370200200741086a2203200d280200360200200b2015290300370300200a200e29030037030020092014290300370300200241f0096a41206a22042007290300370300200241f0096a41286a220d201d280200360200200220022903d00c3703f009200220063602940120022005360290012002200136028c012002410036028801201d200d28020036020020072004290300370300201820092903003703002021200a2903003703002022200b290300370300200220022903f0093703d00120142009290300370300200e200a2903003703002015200b290300370300200220022903f0093703d00c200241c0016a41086a2003280200360200200220072902003703c001200241b0016a200c200241d00c6a200241c0016a108303024020022802b001450d0020022802b4012203450d0020022802b801450d00200310350b2016450d0120022016417f6a22163602a80120010d000b41958dcc00412b41c08dcc00103f000b20024188016a1081030c010b200541386a2116200541306a211502400240200528023022140d0041002129200241003602e401200241003602d4010c010b2005280238212902400240200541346a28020022060d00201421030c010b2006210320142104034020042802ec0321042003417f6a22030d000b201421030340200320032f01064102746a41ec036a28020021032006417f6a22060d000b200421140b200241003602e801200241003602e001200242003703d801200220143602d401200241003602d001200220033602e401200220032f01063602ec010b200220293602f001200241d0016a108103200541286a200f37030020052010370320200541106a20123703002005201337030820052011370318200520083703002015200e360204201520013602002016200d3602002005200c3a003c2005413d6a2002290368370000200541c5006a2023290300370000200541cd006a2022290300370000200541d5006a2021290300370000200520173b015e200520183a005d0b20022802202201450d0120022001417f6a36022020022802042203450d0620022802082105200228020021060240200228020c220420032f0106490d00034002400240200328020022010d002005ad2108410021010c010b200641016a210620033301044220862005ad8421080b200310352008a72105200121032008422088a7220420012f01064f0d000b200121030b200241d00c6a41186a2215200320044105746a220141206a290000370300200241d00c6a41106a2216200141186a290000370300200241d00c6a41086a2221200141106a2900003703002002200141086a2900003703d00c200241d0016a41086a22222003200441e0006c6a221441ad036a290000370300200241d0016a41106a2223201441b5036a290000370300200241d0016a41186a2229201441bd036a2900003703002002201441a5036a2900003703d001200441016a210420144190036a290300210f20144188036a2903002110201441f8026a2903002112201441f0026a2903002113201441c6036a2f01002117201441c5036a2d00002118201441a4036a2d0000210c201441a0036a280200210d2014419c036a280200210e20144198036a280200210120144180036a2903002111201441e8026a290300210802402006450d00200320044102746a41880b6a2802002103410021042006417f6a2206450d00034020032802880b21032006417f6a22060d000b0b20092015290300370300200a2016290300370300200b2021290300370300201e2022290300370300201f202329030037030020202029290300370300200220022903d00c3703f009200220022903d001370388012002200436020c20022005360208200220033602042002410036020020084202520d000b0b2002108f032000200028020041016a360200200241f00c6a24000f0b41a797cc004110200241d0016a41c8c1c30041c897cc001046000b41958dcc00412b41c08dcc00103f000b103c000b41958dcc00412b41c08dcc00103f000b41958dcc00412b41c08dcc00103f000b8b0503027f017e057f230041d0006b2202240041affdc600ad4280808080f00084100122032900002104200241086a200341086a290000370300200220043703002003103541adb6c300ad4280808080800184100122032900002104200241106a41086a200341086a29000037030020022004370310200310352002200136022c2002412c6aad4280808080c00084100422032900002104200241306a41086a200341086a2900003703002002200437033020031035200241cc006a200241306a3602002002200241c0006a36024420022002412c6a3602482002200241306a360240200241206a200241c0006a107b02400240024002402002280228220541206a2206417f4c0d00200228022021070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a20002006360208200020083602042000200336020002402002280224450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bc20503027f017e047f230041d0006b2202240041fafdc600ad4280808080800184100122032900002104200241086a200341086a290000370300200220043703002003103541f5bac300ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b13002000410436020420004180dec3003602000b3400200041affdc60036020420004100360200200041146a4101360200200041106a4194edc300360200200041086a42073702000baa0b080e7f017e047f017e057f027e067f017e23004180016b22022400200141086a280200210320012802042104200028020421052000280200210602400240024020002802082207200028020c2208460d00200041146a28020021092001280200210a2000280210210b200241086a210c0340200c200741106a290300370300200241106a2201200741186a290300370300200241186a220d200741206a29030037030020022007290308370300200741386a210e02402007280228220f0d00200e21070c020b200741306a2802002100200729030021102007412c6a2802002111200241206a41186a2212200d290300370300200241206a41106a22132001290300370300200241206a41086a2214200c290300370300200220022903003703202000ad42c8007e2215422088a70d032015a72207417f4c0d030240024020070d00410821160c010b200710332216450d030b200741c8006e21170240024020000d00410021180c010b200f20004105746a211941002118200f211a0340201a41086a2900002115201a41106a290000211b201a290000211c200241c0006a41186a221d201a41186a290000370300200241c0006a41106a221e201b370300200241c0006a41086a221f20153703002002201c3703400240200b2802002220450d00200b28020421210340202041086a210020202f010622224105742107410021010240024003402007450d01200241c0006a2000412010a008220d450d02200741606a2107200141016a2101200041206a2100200d417f4a0d000b2001417f6a21220b2021450d022021417f6a2121202020224102746a4194036a28020021200c010b0b0240024002402009280208220d202020014102746a41e8026a220028020022074d0d002009280200200741d8006c6a2207427f2007290320221520107c221b201b2015542201200741286a2207290300221c2001ad7c2223201c54201b20155a1b22011b3703202007427f202320011b370300200241e0006a41186a2201201d290300370300200241e0006a41106a220d201e290300370300200241e0006a41086a2220201f290300370300200220022903403703602000280200210020182017470d02024002400240201841016a22072018490d00201841017422212007202120074b1bad42c8007e2215422088a70d002015a722074100480d00024020180d0020070d02410821160c050b201841c8006c22212007460d04024020210d0020070d02410821160c050b20162021200710372216450d020c040b103e000b2007103322160d020b103c000b2007200d41a4c5ca001042000b200741c8006e21170b2016201841c8006c6a2207420037030020072000360220200741186a4200370300200741106a4200370300200741086a4200370300200720022903603702242007412c6a2020290300370200200741346a200d2903003702002007413c6a2001290300370200201841016a21180b201a41206a221a2019470d000b0b0240201141ffffff3f71450d00200f10350b200241e0006a41186a22072012290300370300200241e0006a41106a22002013290300370300200241e0006a41086a2014290300221537030020022002290320221b370360200a4200370310200a41186a4200370300200a4200370308200a2010370300200a41286a4200370300200a4201370320200a2018360238200a2017360234200a2016360230200a201b37023c200a41c4006a2015370200200a41cc006a2000290300370200200a41d4006a2007290300370200200341016a2103200a41e0006a210a200e2107200e2008470d000b200821070b20042003360200200820076b220041386d210102402000450d00200141386c21002007412c6a210703400240200728020041ffffff3f71450d002007417c6a28020010350b200741386a2107200041486a22000d000b0b02402005450d00200541386c450d00200610350b20024180016a24000f0b1045000b1044000bef3007017f017e017f027e017f027e1c7f23004180036b2207240002400240024002402001200284500d002003200484500d004201210820074198016a200320012003200156200420025620042002511b22091b220a2004200220091b220b20054201200542015620064200522006501b220c1b220520064200200c1b220610980820074188016a200729039801220d20074198016a41086a290300220e200520061084082002200420091b21022001200320091b2104200a20072903880185200b20074188016a41086a290300858450450d01200d210a200e210b420021060c020b20004100360200200041106a4200370300200041086a42003703000c020b200741f8006a2004200220052006109808200741e8006a20072903782201200741f8006a41086a2903002203200520061084084200200620042007290368852002200741e8006a41086a29030085845022091b21064201200520091b21082003200220091b21022001200420091b21040b200741386a200b420020044200108408200741c8006a20024200200a4200108408200741d8006a200a4200200442001084080240024002400240024002400240024002400240024002400240024002400240200b420052200242005271200729034042005272200729035042005272200741d8006a41086a2903002201200729033820072903487c7c2203200154724101470d00411010332209450d0d2007420437029c02200720093602980220074198026a41004104108601200741f0026a41086a220920072802a002220c41046a360200200728029802200c4102746a220c200a3e020c200c200a4220883e0208200c200b3e0204200c200b4220883e020020072007290398023703f002200741f0026a10e607200741a8016a41086a2009280200360200200720072903f0023703a80141101033220c450d0d2007420437029c022007200c3602980220074198026a41004104108601200920072802a002220c41046a360200200728029802200c4102746a220c20043e020c200c20044220883e0208200c20023e0204200c20024220883e020020072007290398023703f002200741f0026a10e607200741b8016a41086a2009280200360200200720072903f0023703b801411010332209450d0d2007420437029c02200720093602980220074198026a41004104108601200741f0026a41086a220c20072802a002220941046a36020020072802980220094102746a22092008a7220f36020c200920084220883e0208200920063e0204200920064220883e020020072007290398023703f002200741f0026a10e607200c280200211020072802f402211120072802f0022112200c200741b8016a41086a280200360200200720072903b8013703f00220074198026a41086a200741a8016a41086a280200360200200720072903a80137039802200741c8016a20074198026a200741f0026a10e807024020072802f40241ffffffff0371450d0020072802f00210350b200741c8016a10e60720104101460d0120072802cc01211320072802c80121142010450d0a2012280200450d0a024020072802d0012215450d002014280200450d0b201520104d0d0b200720103602d401201520106b221641016a22174101201741014b1b221841ffffffff03712018470d0320184102742219417f4c0d0320191039221a450d0e201041ffffffff03712010470d032010410274221b417f4c0d03201b1039221c450d0e4101210f410221092012280200220c67221d211e0240200c41ffffffff034b0d0041022109201d210c4101210f034020094101200c4101711b200f6c210f200c41034b211f200920096c2109200c410176221e210c201f0d000b0b200720153602f802200720133602f402200720143602f0024104211f41041033220c450d0f200c20094101201e4101461b200f6c220f360200200742818080801037029c022007200c36029802200741d8016a200741f0026a20074198026a10e807200c10350240201b450d00201b1033221f450d0f0b200741003602a0022007201b410276222036029c022007201f3602980220074198026a4100201010860120072802980220072802a00222094102746a20122010410274109d081a200741f8026a200920106a36020020072007290398023703f002410410332209450d0f2009200f360200200742818080801037029c022007200936029802200741e8016a200741f0026a20074198026a10e80720091035024020072802d40120176a220920072802e001220c4d0d00200741003602a002200742043703980220074198026a41002009200c6b220c10860120072802a00221090240200c450d0020072802980220094102746a4100200c410274109f081a2009200c6a21090b200741f0026a41086a220c200936020020072007290398023703f00220072802d801211f200741f0026a200920072802e001220f10860120072802f002200c28020022094102746a201f200f410274109d081a200c2009200f6a220936020020074198026a41086a220c2009360200200720072903f00237039802024020072802dc0141ffffffff0371450d0020072802d80110350b200741d8016a41086a200c28020036020020072007290398023703d8010b20194102762121200741e8016a10e607024002400240024002400240024002400240024003402007201622223602f401024020072802e001220920072802d401220c20226a220f417f736a221f2009490d00201f200941ac95cc001042000b0240024002400240024002400240024002400240024002400240024020092009200f6b220f4d0d0020072802f00122092009200c6b220c4d0d0120072802e801200c4102746a35020022024200510d02202220224100476b211620072802d8012209201f4102746a35020021012009200f4102746a3502002104200741003602f80120072004200142208684200280220137038002200741003602880220072004200120027e7d42ffffffff0f83370390022007200741f4016a3602ac022007200741d8016a3602a8022007200741d4016a3602a4022007200741e8016a3602a002200720074188026a36029c022007200741f8016a3602980220074198026a10e9071a034020072802880241016a41004c0d04024020072903900242ffffffff0f560d0020074198026a10e9070d010b0b200729038002210220072802f401210920072802d401210c200741003a00f8022007200c20096a3602f402200720093602f0022007200741d8016a3602fc02200741b0026a200741f0026a10ec0720072802f001220941ffffffff03712009470d1c2009410274220c417f4c0d1c20072802e801210f02400240200c0d004104211f0c010b200c1033221f450d280b200741003602f8022007201f3602f0022007200c4102763602f402200741f0026a4100200910860120072802f00220072802f802221f4102746a200f200c109d081a200741e0026a41086a2223201f20096a360200200720072903f0023703e002410810332209450d2820092002a72224360204200920024220883e020020074282808080203702f402200720093602f002200741c0026a200741e0026a200741f0026a10e8072009103520072802b802221920072802c8022225201920254b1b22144101201441014b1b220c41ffffffff0371200c470d1c200c4102742226417f4c0d1c20072802b402212720072802b00221280240024020260d00410421290c010b202610392229450d280b2014450d062025417f6a221b20254b211520072802c002212a2019417f6a221720194b0d04200c417f6a2109202920266a417c6a211e4100210f4200210203404100211f024020192017200f6b22134d0d004100211f201320174b0d00202820134102746a280200211f0b201fad21044100211f024020150d002025201b200f6b22134d0d002013201b4b0d00202a20134102746a280200211f0b024002402004201fad22037d22012004560d00200120027d220a2001560d00200a42ffffffff0f832104420021020c010b20044280808080108420027d20037d2104420121020b200c20094d0d09201e20043e0200201e417c6a211e2009417f6a2109200f41016a220f2014490d000c060b0b200f200941ac95cc001042000b200c200941ac95cc001042000b419095cc00411941b494cc00103f000b41ac96cc004118200741f0026a41c496cc0041d496cc001046000b200c417f6a2109202920266a417c6a211f4100211e4200210203404100210f024020150d004100210f2025201b201e6b22134d0d004100210f2013201b4b0d00202a20134102746a280200210f0b024002404200200fad22017d22044200520d00200420027d22032004560d00200342ffffffff0f832104420021020c010b428080808010200220017c7d2104420121020b200c20094d0d04201f20043e0200201f417c6a211f2009417f6a2109201e41016a221e2014490d000b0b41012113200250450d010b410021130b0240202741ffffffff0371450d00202810350b20072802d401221f20072802f401220f6a2215201f490d05200f20154f0d01200f417f7321090340200c200c200f6a20096a221e4d0d03200920072802e00122146a220f20094f0d0420072802d801200f4102746a2029201e4102746a2802003602002009417f6a210920072802f401210f201f417f6a221f0d000c050b0b2009200c41bc95cc001042000b201f450d020c030b20252019202520194b1b22074101200741014b1b200f6a20096a200c41ac95cc001042000b200f201441bc95cc001042000b200c200c2015417f7322096a200f6a220f4d0d0220072802e001220c20096a2209200c4f0d0320072802d80120094102746a2029200f4102746a28020036020020072802f401210f0b2018200f417f736a220920184f0d03201a20094102746a202436020002402013450d00201820072802f401417f736a220920184f0d05201a20094102746a22092009280200417f6a36020020072802f401210920072802d401210c200741003a00f8022007200c20096a3602f402200720093602f0022007200741d8016a3602fc02200741d0026a200741f0026a10ec0720072802f001220941ffffffff03712009470d0f2009410274220c417f4c0d0f20072802e801210f02400240200c0d004104211f0c010b200c1033221f450d1b0b200741003602f8022007201f3602f0022007200c4102763602f402200741f0026a4100200910860120072802f00220072802f802221f4102746a200f200c109d081a2023201f20096a360200200720072903f0023703e002200741f0026a200741e0026a200741d0026a10e707024020072802d401220920072802f40122146a220c2009490d00024002402014200c4f0d00200c417f73210920072802f002211320072802f802210f2014211f0340200f200f201f6a20096a221f4d0d0a200920072802e00122156a221e20094f0d0b20072802d801201e4102746a2013201f4102746a280200360200200941016a210920072802f401211f2014200c417f6a220c490d000c020b0b20090d0120072802f802210f2014211f0b201f2014417f7322096a220c200f6a221f200c4f0d0920072802e001220c20096a2209200c4f0d0a20072802d80120094102746a20072802f002201f4102746a2802003602000b024020072802f40241ffffffff0371450d0020072802f00210350b20072802d40241ffffffff0371450d0020072802d00210350b02402026450d00202910350b024020072802c40241ffffffff0371450d0020072802c00210350b20220d000b0240201d0d0020072802e001211020072802dc01212020072802d801210f201c1035410021090c130b4101210920072802d401220c4101460d114100200c6b2114201d411f7121134100201d6b411f7121152010410274201c6a417c6a210c417f210903400240200920072802e001221f6a220f2009490d00200f201f41ac95cc001042000b201f200f417f6a221e4d0d09201020096a221f20104f0d0a200c20072802d801221f201e4102746a280200201574201f200f4102746a28020020137672360200200c417c6a210c20142009417f6a2209460d110c000b0b200f200c41ac95cc001042000b2009200c41bc95cc001042000b2009201841bc95cc001042000b2009201841ac95cc001042000b201f200f41ac95cc001042000b201e201541bc95cc001042000b201f200f41ac95cc001042000b2009200c41bc95cc001042000b200f417f6a201f41ac95cc001042000b201f201041bc95cc001042000b41004100419c96cc001042000b200741286a200729035820032008200610980820004100360200200041106a200741286a41086a290300370300200041086a20072903283703000c0f0b20074198026a41086a200741c8016a41086a280200221f360200200720072903c80137039802201f4101201f41014b1b221e41ffffffff0371201e470d00201e410274221b417f4c0d0002400240201b0d00410421170c010b201b10392217450d0c0b201f450d022017201e410274201f4102746b6a210c201f417f6a2114201e201f6b2113200f4101200f41014b1bad21024200210441002109200728029802210f0340201e201320096a22154d0d02200c2004422086200f35020084220420028022013e020020142009460d03200c41046a210c200f41046a210f2004200120027e7d2104201f200941016a22094b0d000b2009201f41ac95cc001042000b1044000b2015201e41bc95cc001042000b2007201e3602f8022007201b4102763602f402200720173602f002200728029c0241ffffffff0371450d0720072802980210350c070b20072802d40121090b20072802e001220c200c20096b220f4d0d012010201020096b22094d0d02201c20094102746a20072802d801200f4102746a280200201d411f717636020041012109201c210f0b024020072802ec0141ffffffff0371450d0020072802e80110350b2009450d0320072802dc0141ffffffff0371450d0320072802d80110350c030b200f200c41ac95cc001042000b2009201041bc95cc001042000b4100211a0240201341ffffffff0371450d00201410350b0b410410332209450d022009410036020041041033220c450d02200c41003602004101211e02400240201a0d002009211a4101212141012118200c210f41012120410121100c010b20091035200c10350b2007201836028002200720213602fc012007201a3602f801200720103602a0022007202036029c022007200f3602980220074198026a10e607420021020240024020072802a00222094105744180014d0d00421d21040c010b4100211e024020090d00420021040c010b200728029802220c200941027422096a417c6a220f280200211f0240200c200f470d00201fad21040c010b200c41786a210f201fad2104200741206a211f4120210c420021020340200741186a200f20096a3502004200200c41e0007110a308201f29030020027c2007290318220220047c2204200254ad7c2102200c41206a210c2009417c6a22094104470d000b0b0240200728029c0241ffffffff0371450d0020072802980210350b201e0d030240200420084201882006423f8684562002200642018822045620022004511b450d0020074188026a41086a200741f8016a41086a280200360200200720072903f80137038802411010332209450d022007420437029c02200720093602980220074198026a41004104108601200741f0026a41086a220920072802a002220c41046a360200200728029802200c4102746a220c428080808010370208200c420037020020072007290398023703f002200741f0026a10e60720074198026a41086a2009280200360200200720072903f00237039802200741f8016a20074188026a20074198026a10e707200728029c0241ffffffff0371450d0020072802980210350b200741f0026a41086a200741f8016a41086a280200360200200720072903f8013703f0020b200741f0026a10e60720074198026a41086a2209200741f0026a41086a280200360200200720072903f0023703980220074198026a10e6074200210202400240200928020022094105744180014d0d00421d21044101211e0c010b4100211e024020090d00420021040c010b200728029802220c200941027422096a417c6a220f280200211f0240200c200f470d00201fad21040c010b200c41786a210f201fad2104200741106a211f4120210c420021020340200741086a200f20096a3502004200200c41e0007110a308201f29030020027c2007290308220220047c2204200254ad7c2102200c41206a210c2009417c6a22094104470d000b0b0240200728029c0241ffffffff0371450d0020072802980210350b02400240201e450d00200041a898cc00360204200041086a4119360200410121090c010b200041106a2002370300200041086a2004370300410021090b20002009360200201141ffffffff0371450d03201210350c030b1045000b103c000b200720043e029c02200741fc95cc003602980241d897cc00412f20074198026a418898cc00419898cc001046000b20074180036a24000b870701047f230041d0006b2208240002400240024002402002200685200320078584500d00200220038450450d01410121090c020b417f20002004852001200585844200522000200454200120055420012005511b1b21090c010b0240200620078450450d0041ff0121090c010b411010332209450d012008420437024420082009360240200841c0006a41004104108601200841306a41086a22092008280248220a41046a3602002008280240200a4102746a220a20003e020c200a20004220883e0208200a20013e0204200a20014220883e020020082008290340370330200841306a10e607200841106a41086a220b20092802003602002008200829033037031041101033220a450d01200842043702442008200a360240200841c0006a4100410410860120092008280248220a41046a3602002008280240200a4102746a220a20063e020c200a20064220883e0208200a20073e0204200a20074220883e020020082008290340370330200841306a10e607200841206a41086a200928020036020020082008290330370320200841c0006a41086a200b280200360200200820082903103703402008200841c0006a200841206a10e8070240200828022441ffffffff0371450d00200828022010350b411010332209450d012008420437024420082009360240200841c0006a41004104108601200841306a41086a22092008280248220a41046a3602002008280240200a4102746a220a20043e020c200a20044220883e0208200a20053e0204200a20054220883e020020082008290340370330200841306a10e607200841106a41086a220b20092802003602002008200829033037031041101033220a450d01200842043702442008200a360240200841c0006a4100410410860120092008280248220a41046a3602002008280240200a4102746a220a20023e020c200a20024220883e0208200a20033e0204200a20034220883e020020082008290340370330200841306a10e607200841206a41086a200928020036020020082008290330370320200841c0006a41086a200b28020036020020082008290310370340200841306a200841c0006a200841206a10e8070240200828022441ffffffff0371450d00200828022010350b2008200841306a10ea0721090240200828023441ffffffff0371450d00200828023010350b200828020441ffffffff0371450d00200828020010350b200841d0006a240020090f0b1045000bbb0703017f067e017f230041d0006b22022400024002400240200029031022032001290310220485200041186a2903002205200141186a29030022068584500d00200041086a290300210720002903002108411010332200450d022002420437024420022000360240200241c0006a41004104108601200241306a41086a22092002280248220041046a360200200228024020004102746a220020083e020c200020084220883e0208200020073e0204200020074220883e020020022002290340370330200241306a10e607200241106a41086a200928020036020020022002290330370310411010332200450d022002420437024420022000360240200241c0006a41004104108601200241306a41086a22092002280248220041046a360200200228024020004102746a220020043e020c200020044220883e0208200020063e0204200020064220883e020020022002290340370330200241306a10e607200241206a41086a200928020036020020022002290330370320200241c0006a41086a200241106a41086a280200360200200220022903103703402002200241c0006a200241206a10e8070240200228022441ffffffff0371450d00200228022010350b200141086a290300210420012903002106411010332200450d022002420437024420022000360240200241c0006a41004104108601200241306a41086a22002002280248220141046a360200200228024020014102746a220120063e020c200120064220883e0208200120043e0204200120044220883e020020022002290340370330200241306a10e607200241106a41086a2209200028020036020020022002290330370310411010332201450d022002420437024420022001360240200241c0006a4100410410860120002002280248220141046a360200200228024020014102746a220120033e020c200120034220883e0208200120053e0204200120054220883e020020022002290340370330200241306a10e607200241206a41086a200028020036020020022002290330370320200241c0006a41086a200928020036020020022002290310370340200241306a200241c0006a200241206a10e8070240200228022441ffffffff0371450d00200228022010350b2002200241306a10ea0721000240200228023441ffffffff0371450d00200228023010350b200041ff017121000240200228020441ffffffff0371450d00200228020010350b20004521000c010b2000290300200129030085200041086a290300200141086a29030085845021000b200241d0006a240020000f0b1045000bae380b147f017e017f017e017f017e017f017e017f017e0e7f23004180036b220524000240024020014115490d004101210641012107024002400240034020012108200021092006200771410173210a02400240024002400240024003400240024002402004450d00024020064101710d002000200110ff062004417f6a21040b20052002360208200520003602502005200136025420052001410276220b36020c2005200b410174220c3602102005200b41036c220d360214200541003602182005200541186a3602d8012005200541d0006a3602d4012005200541086a3602d0012005200541d0016a36021c024020014132490d002005200b417f6a3602202005200b41016a3602d0022005411c6a200541206a2005410c6a200541d0026a1080072005200c417f6a3602202005200c4101723602d0022005411c6a200541206a200541106a200541d0026a1080072005200d417f6a3602202005200d41016a3602d0022005411c6a200541206a200541146a200541d0026a1080070b2005411c6a2005410c6a200541106a200541146a1080072005280218220b410b4b0d01200b45210b2005280210210e0c020b2000200120021081070c0e0b02402005280254220c410176220d450d002005280250220b200c41306c6a41506a210c0340200541d0026a41286a220f200b41286a2210290300370300200541d0026a41206a2211200b41206a2212290300370300200541d0026a41186a220e200b41186a2213290300370300200541d0026a41106a2214200b41106a2215290300370300200541d0026a41086a2216200b41086a22172903003703002005200b2903003703d002200c41086a22182903002119200c41106a221a290300211b200c41186a221c290300211d200c41206a221e290300211f200c41286a22202903002121200b200c290300370300201020213703002012201f3703002013201d3703002015201b370300201720193703002020200f290300370300201e2011290300370300201c200e290300370300201a201429030037030020182016290300370300200c20052903d002370300200c41506a210c200b41306a210b200d417f6a220d0d000b0b20012005280210417f736a210e4101210b0b0240200b45200a724101710d002000200120021082070d0d0b02402003450d00200e20014f0d030240200228020028020028020022142802002211450d00201428020421122011211002400340201041086a210c20102f01062213410574210b4100210d024002400340200b450d012003200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21130b024020120d004200211b420021190c030b2012417f6a2112201020134102746a41c8056a28020021100c010b0b2010200d4105746a220b41f0026a2903002119200b41e8026a290300211b0b2011450d002000200e41306c6a2110201428020421120340201141086a210c20112f01062213410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21130b2012450d022012417f6a2112201120134102746a41c8056a28020021110c010b0b201b2011200d4105746a220b41e8026a290300542019200b41f0026a290300221b542019201b511b450d0020002109200121080c030b200541d0026a41286a221a200041286a2222290300370300200541d0026a41206a221c200041206a2223290300370300200541d0026a41186a221e200041186a2224290300370300200541d0026a41106a2220200041106a2207290300370300200541d0026a41086a2225200041086a2226290300370300200520002903003703d0022000200e41306c6a220b41086a220c2903002119200b41106a220d290300211b200b41186a220f290300211d200b41206a2210290300211f200b41286a221129030021212000200b290300370300202220213703002023201f3703002024201d3703002007201b370300202620193703002011201a2903003703002010201c290300370300200f201e290300370300200d2020290300370300200c2025290300370300200b20052903d002370300200541d0016a41286a22272022290300370300200541d0016a41206a22282023290300370300200541d0016a41186a22292024290300370300200541d0016a41106a222a2007290300370300200541d0016a41086a222b2026290300370300200520002903003703d001200041306a21184100210e200121140340200228020021170240200e2014417f6a22154f0d00201728020028020022162802002113034002402013450d00201628020421112013211002400340201041086a210c20102f01062212410574210b4100210d024002400340200b450d01200541d0016a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21120b024020110d004200211b420021190c030b2011417f6a2111201020124102746a41c8056a28020021100c010b0b2010200d4105746a220b41f0026a2903002119200b41e8026a290300211b0b2013450d002018200e41306c6a211020162802042112201321110340201141086a210c20112f01062214410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21140b2012450d022012417f6a2112201120144102746a41c8056a28020021110c010b0b201b2011200d4105746a220b41e8026a2903005a2019200b41f0026a290300221b5a2019201b511b450d020b200e41016a220e2015470d000b2015210e0b02400340200e201522144f0d010240201728020028020022162802002211450d002014417f6a2115201628020421122011211002400340201041086a210c20102f01062213410574210b4100210d024002400340200b450d01200541d0016a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21130b024020120d004200211b420021190c030b2012417f6a2112201020134102746a41c8056a28020021100c010b0b2010200d4105746a220b41f0026a2903002119200b41e8026a290300211b0b2011450d002000201441306c6a2110201628020421120340201141086a210c20112f01062213410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21130b2012450d022012417f6a2112201120134102746a41c8056a28020021110c010b0b201b2011200d4105746a220b41e8026a290300542019200b41f0026a290300221b542019201b511b0d010b0b201a2018200e41306c6a220b41286a220d290300370300201c200b41206a220f290300370300201e200b41186a22102903003703002020200b41106a22112903003703002025200b41086a22122903003703002005200b2903003703d0022000201441306c6a220c41086a22132903002119200c41106a2215290300211b200c41186a2216290300211d200c41206a2217290300211f200c41286a222c2903002121200b200c290300370300200d2021370300200f201f3703002010201d3703002011201b37030020122019370300202c201a2903003703002017201c2903003703002016201e2903003703002015202029030037030020132025290300370300200c20052903d002370300200e41016a210e0c010b0b200020052903d0013703002022202729030037030020232028290300370300202420292903003703002007202a2903003703002026202b2903003703002001200e41016a220b490d042000200b41306c6a21002001200b6b220141154f0d010c0c0b0b2008450d030b200e20084f0d03200541d0026a41286a2220200941286a2226290300370300200541d0026a41206a2225200941206a2227290300370300200541d0026a41186a222c200941186a2228290300370300200541d0026a41106a2222200941106a2229290300370300200541d0026a41086a2223200941086a222a290300370300200520092903003703d0022009200e41306c6a220b41086a220c2903002119200b41106a220d290300211b200b41186a220f290300211d200b41206a2210290300211f200b41286a221129030021212009200b290300370300202620213703002027201f3703002028201d3703002029201b370300202a20193703002011202029030037030020102025290300370300200f202c290300370300200d2022290300370300200c2023290300370300200b20052903d002370300200541206a41286a222b2026290300370300200541206a41206a22062027290300370300200541206a41186a220a2028290300370300200541206a41106a222d2029290300370300200541206a41086a222e202a29030037030020052009290300370320200941306a21002002280200211602402008417f6a22170d00410021240c050b2016280200280200221428020021134100212403402013450d052000202441306c6a2110201428020421122013211102400340201141086a210c20112f0106220e410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a210e0b024020120d004200211b420021190c030b2012417f6a21122011200e4102746a41c8056a28020021110c010b0b2011200d4105746a220b41f0026a2903002119200b41e8026a290300211b0b2013450d0520142802042111201321100340201041086a210c20102f01062212410574210b4100210d024002400340200b450d01200541206a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21120b2011450d072011417f6a2111201020124102746a41c8056a28020021100c010b0b201b2010200d4105746a220b41e8026a290300542019200b41f0026a290300221b542019201b511b450d05202441016a22242017470d000b201721240c040b200e200141d086cc001042000b200b200141e485cc001059000b4100410041f485cc001042000b200e2008418486cc001042000b2017210b02400340200b221420244d22070d010240024002402016280200280200221528020022120d004200211f4200211b0c010b2009201441306c6a21102015280204210e2012211102400340201141086a210c20112f01062213410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21130b0240200e0d004200211f4200211b0c030b200e417f6a210e201120134102746a41c8056a28020021110c010b0b2011200d4105746a220b41f0026a290300211b200b41e8026a290300211f0b2012450d00201528020421100340201241086a210c20122f01062211410574210b4100210d024002400340200b450d01200541206a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21110b2010450d022010417f6a2110201220114102746a41c8056a28020021120c010b0b2012200d4105746a220b41f0026a2903002119200b41e8026a290300211d0c010b4200211d420021190b2014417f6a210b201f201d5a201b20195a201b2019511b0d000b0b20142024490d0320172014490d022000201441306c6a2117418001211c410021154100211a4100211441002118418001211e2000202441306c6a222f21000340201720006b220b41306e210c0240200b41afe0004b22010d00200c41807f6a200c201a2015492018201449220d72220f1b210b0240200f450d00201e200b200d1b211e200b201c200d1b211c0c010b200b200b410176221e6b211c0b024020182014470d000240201e0d00200541d0006a221421180c010b41002113200541d0006a2114200021100340201420133a0000201341016a21130240024002402002280200280200280200221828020022120d004200211d420021190c010b2018280204210e2012211102400340201141086a210c20112f01062216410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21160b0240200e0d004200211d420021190c030b200e417f6a210e201120164102746a41c8056a28020021110c010b0b2011200d4105746a220b41f0026a2903002119200b41e8026a290300211d0b2012450d00201828020421110340201241086a210c20122f0106220e410574210b4100210d024002400340200b450d01200541206a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a210e0b2011450d022011417f6a21112012200e4102746a41c8056a28020021120c010b0b2012200d4105746a220b41f0026a290300211b200b41e8026a290300211f0c010b4200211f4200211b0b2014201d201f5a2019201b5a2019201b511b6a2114201041306a21102013201e470d000b200541d0006a21180b0240201a2015470d000240201c0d00200541d0016a2215211a0c010b41002113200541d0016a2115201721100340201520133a0000201041506a2110201341016a21130240024002402002280200280200280200221a28020022120d004200211d420021190c010b201a280204210e2012211102400340201141086a210c20112f01062216410574210b4100210d024002400340200b450d012010200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a21160b0240200e0d004200211d420021190c030b200e417f6a210e201120164102746a41c8056a28020021110c010b0b2011200d4105746a220b41f0026a2903002119200b41e8026a290300211d0b2012450d00201a28020421110340201241086a210c20122f0106220e410574210b4100210d024002400340200b450d01200541206a200c412010a008220f450d02200b41606a210b200d41016a210d200c41206a210c200f417f4a0d000b200d417f6a210e0b2011450d022011417f6a21112012200e4102746a41c8056a28020021120c010b0b2012200d4105746a220b41f0026a290300211b200b41e8026a290300211f0c010b4200211f4200211b0b2015201d201f542019201b542019201b511b6a21152013201c470d000b200541d0016a211a0b02402015201a6b220b201420186b220c200c200b4b1b2211450d002020200020182d000041306c6a220b41286a2903003703002025200b41206a290300370300202c200b41186a2903003703002022200b41106a2903003703002023200b41086a2903003703002005200b2903003703d002200020182d000041306c6a220b2017201a2d0000417f7341306c6a220c290300370300200b41286a200c41286a290300370300200b41206a200c41206a290300370300200b41186a200c41186a290300370300200b41106a200c41106a290300370300200b41086a200c41086a290300370300024020114101460d004100210d03402017201a200d6a220f2d0000417f7341306c6a220b20002018200d6a41016a22102d000041306c6a220c290300370300200b41286a200c41286a290300370300200b41206a200c41206a290300370300200b41186a200c41186a290300370300200b41106a200c41106a290300370300200b41086a200c41086a290300370300200020102d000041306c6a220b2017200f41016a2d0000417f7341306c6a220c290300370300200b41286a200c41286a290300370300200b41206a200c41206a290300370300200b41186a200c41186a290300370300200b41106a200c41106a290300370300200b41086a200c41086a290300370300200d41026a210b200d41016a220c210d200b2011490d000b201a200c6a211a2018200c6a21180b2017201a2d0000417f7341306c6a220b20052903d002370300200b41286a2020290300370300200b41206a2025290300370300200b41186a202c290300370300200b41106a2022290300370300200b41086a2023290300370300201a41016a211a201841016a21180b2000201e41306c6a200020182014461b210020174100201c6b41306c6a2017201a2015461b211720010d000b02400240201820144f0d002017210b0340202020002014417f6a22142d000041306c6a220c41286a220d2903003703002025200c41206a220f290300370300202c200c41186a22102903003703002022200c41106a22112903003703002023200c41086a22122903003703002005200c2903003703d002200b41506a220b41086a220e2903002119200b41106a2213290300211b200b41186a2215290300211d200b41206a2216290300211f200b41286a22172903002121200c200b290300370300200d2021370300200f201f3703002010201d3703002011201b3703002012201937030020172020290300370300201620252903003703002015202c29030037030020132022290300370300200e2023290300370300200b20052903d00237030020182014490d000c020b0b2000210b201a20154f0d0003402015417f6a22152d0000210c2020200b41286a220d2903003703002025200b41206a220f290300370300202c200b41186a22102903003703002022200b41106a22112903003703002023200b41086a22122903003703002005200b2903003703d0022017200c417f7341306c6a220c41086a220e2903002119200c41106a2213290300211b200c41186a2214290300211d200c41206a2216290300211f200c41286a22002903002121200b200c290300370300200d2021370300200f201f3703002010201d3703002011201b3703002012201937030020002020290300370300201620252903003703002014202c29030037030020132022290300370300200e2023290300370300200c20052903d002370300200b41306a210b201a2015490d000b0b200920052903203703002026202b290300370300202720062903003703002028200a2903003703002029202d290300370300202a202e29030037030002402008200b202f6b41306e20246a22014d0d002020202629030037030020252027290300370300202c2028290300370300202220292903003703002023202a290300370300200520092903003703d0022009200141306c6a220b41086a220c2903002119200b41106a220d290300211b200b41186a220f290300211d200b41206a2210290300211f200b41286a221129030021212009200b290300370300202620213703002027201f3703002028201d3703002029201b370300202a20193703002011202029030037030020102025290300370300200f202c290300370300200d2022290300370300200c2023290300370300200b20052903d002370300200820016b220c450d02200c20012001200c4b1b210d2008410376210f200b41306a2100024002402001200c417f6a220c490d002000200c2002200b2004109e04200921000c010b20092001200220032004109e04200b2103200c21010b200d200f4f2106200141154f0d010c050b0b20012008418486cc001042000b41a486cc00411c41c086cc00103f000b20142017419486cc001058000b20242014419486cc001059000b20014102490d004101210b03402000200b41016a220b20021083072001200b470d000b0b20054180036a24000bad0302027f037e230041d0006b22042400200441386a20024201200242015620034200522003501b22051b22022003420020051b220342ffff034200109808200441286a20042903382206200441386a41086a290300220742ffff034200108408200441186a20022003200620022004290328852003200441286a41086a2903008584420052ad7c22084201200842015620072008200654ad7c22064200522006501b22051b22082006420020051b22061098080240024002402004290318220742808004544100200441186a41086a290300501b450d00200441086a200220002002200054200320015420032001511b22051b2003200120051b200820061098082004290308220342808004544100200441086a41086a290300501b450d012007a741ffff037122050d024190edc40041194180efc400103f000b2004411136024c20044190efc40036024841bcedc40041de00200441c8006a41acedc400419ceec4001046000b2004411136024c20044190efc40036024841bcedc40041de00200441c8006a41acedc40041f0eec4001046000b200441d0006a24002003a741ffff037141ffff036c20056e0b810103017f017e027f230041106b220324000240024002402002ad4220862000ad84102a2204428080808010540d00410121022004a722052d0000220641014b0d0020060e020102010b41b89acc00412e200341086a41c09bcc0041e89acc001046000b410021020b2005103502402001450d00200010350b200341106a240020020b13002000410b360204200041c4eec3003602000b3400200041fafdc60036020420004100360200200041146a4104360200200041106a41e8a9c400360200200041086a42083702000b930301027f024020002802082201450d0020002802002202200141c8006c6a21010340024020022d00004101470d00200241086a280200450d00200241046a28020010350b0240200241246a2d00004101470d002002412c6a280200450d00200241286a28020010350b200241c8006a22022001470d000b0b0240200041046a2802002202450d00200241c8006c450d00200028020010350b024020002d000c4101470d00200041146a280200450d00200041106a28020010350b024020002d00304101470d00200041386a280200450d00200041346a28020010350b024020002d00544101470d00200041dc006a280200450d00200041d8006a28020010350b024020002d00784101470d0020004180016a280200450d00200041fc006a28020010350b024020002d009c014101470d00200041a4016a280200450d00200041a0016a28020010350b024020002d00c0014101470d00200041c8016a280200450d00200041c4016a28020010350b024020002d00e4014101470d00200041ec016a280200450d00200041e8016a28020010350b0b13002000410636020420004188b3c4003602000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241143600000b2d01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241e4003600000b3901017f02404110103322020d001045000b200242003700082002428080d287e2bc2d370000200042908080808002370204200020023602000b3901017f02404110103322020d001045000b2002420037000820024280c0c6c9faeb38370000200042908080808002370204200020023602000b3a01017f02404110103322020d001045000b2002420037000820024280809aa6eaafe301370000200042908080808002370204200020023602000bde0102027f017e230041106b2202240002402000280200220341064b0d00024002400240024002400240024020030e0700010203040506000b200241003a000020012002410110780c060b200241013a00002001200241011078200029030821042002200041106a2903003703082002200437030020012002411010780c050b200241023a000020012002410110780c040b200241033a000020012002410110780c030b200241043a000020012002410110780c020b200241053a000020012002410110780c010b200241063a000020012002410110780b200241106a24000bfa0301047f230041106b2202240020002802002103200028020822042001107702402004450d002003200441c8006c6a210503402002200310ac042001200228020022042002280208107802402002280204450d00200410350b2002200341246a220310ac042001200228020022042002280208107802402002280204450d00200410350b200341246a22032005470d000b0b20022000410c6a10ac042001200228020022032002280208107802402002280204450d00200310350b2002200041306a10ac042001200228020022032002280208107802402002280204450d00200310350b2002200041d4006a10ac042001200228020022032002280208107802402002280204450d00200310350b2002200041f8006a10ac042001200228020022032002280208107802402002280204450d00200310350b20022000419c016a10ac042001200228020022032002280208107802402002280204450d00200310350b0240024020002d0088024101460d00200241003a000020012002410110780c010b200241013a00002001200241011078200120004189026a411410780b2002200041c0016a10ac042001200228020022032002280208107802402002280204450d00200310350b2002200041e4016a10ac042001200228020022032002280208107802402002280204450d00200310350b200241106a24000bd10201057f230041106b22022400024002400240024002400240024002400240024020012d00000e06010203040500010b20024181ca003b01082002200141216a3602042002200141016a3602000c050b410110392201450d062000428180808010370204200020013602000c050b2001410c6a22032802002204412020044120491b220541016a220410332206450d05200620042004109f082106200328020022032005490d06200641016a200141046a2802002005109d081a2000200436020820002004360204200020063602000c040b20024181c4003b01082002200141216a3602042002200141016a3602000c020b20024181c6003b01082002200141216a3602042002200141016a3602000c010b20024181c8003b01082002200141216a3602042002200141016a3602000b2000200210cc070b200241106a24000f0b1045000b2005200341c4e7cb001058000b8611010a7f23004180016b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a2207360200200541254b0d014100210820050e261301010101010101010101010101010101010101010101010101010101010101010102030405130b200041063a00000c130b02402005417f6a41ff01714121490d00200041063a00000c130b02402005417f6a22090d0020012006360204200120073602004101210a410021094100210b410121080c120b0240024020091039220a450d0020012802042009490d01200a20012802002009109d081a200128020422052009490d062001200520096b3602042001200128020020096a360200410121082009210b0c130b1045000b200041063a0000200a10350c120b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c100b41012101200541ff01710d040c0e0b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c0d0b41012101200541ff01710d040c0b0b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c0a0b41012101200541ff01710d040c080b41002105200241003a00782003417f6a210a2003417e6a210302400340200a2005460d01200241d8006a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00782003417f6a21032009210520094120470d000b200241d6006a20022d005a3a0000200241c8006a200241ef006a290000370300200241d0006a200241f7006a2d00003a0000200220022f01583b0154200220022900673703404100210120022800632109200228005f210b200228005b210a0c070b41012101200541ff01710d040c050b2009200541a4f0cb001059000b200241003a00780c090b200241003a00780c060b200241003a00780c030b200241003a00780b0b2002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b012420022002290328370310410521080c070b200041063a00000c070b0b2002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b012420022002290328370310410421080c050b200041063a00000c050b0b2002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b012420022002290328370310410321080c030b200041063a00000c030b0b410221082002413c6a41026a2205200241d4006a41026a2d00003a0000200241286a41086a2204200241c0006a41086a290300370300200241286a41106a2203200241c0006a41106a2d00003a0000200220022f01543b013c20022002290340370328024020010d00200241246a41026a20052d00003a0000200241106a41086a2004290300370300200241106a41106a20032d00003a0000200220022f013c3b0124200220022903283703100c010b200041063a00000c010b200020083a0000200020022f01243b00012000410c6a2009360000200041086a200b360000200041046a200a360000200041106a2002290310370000200041216a20022f000d3b0000200041036a200241246a41026a2d00003a0000200041186a200241106a41086a290300370000200041206a200241106a41106a2d00003a0000200041236a2002410d6a41026a2d00003a00000b20024180016a24000be40701087f230041d00b6b22042400024020002802000d002000417f360200200441206a41186a200141186a290000370300200441206a41106a200141106a290000370300200441206a41086a200141086a2900003703002004200129000037032002400240024020002802042205450d00200041086a28020021060c010b41002106200441f0086a410041e002109f081a200441d0006a410041a008109f081a41880b10332205450d01200541003b010620054100360200200541086a200441f0086a41e002109d081a200541e8026a200441d0006a41a008109d081a200041086a4100360200200020053602040b2004200041046a22073602f808200420053602f408200420063602f008034020052f010622084105742109410021014100210a024002400240034020092001460d010240200441206a200520016a41086a412010a008220b0d00410021012006210b0c030b200141206a2101200a41016a210a200b417f4a0d000b200a417f6a21080b20060d01410121014100210b2008210a0b200441d0006a41106a200a360200200441d0006a410c6a2007360200200441d0006a41086a2005360200200420073602f808200420053602f408200420063602f0082004200b360254200420013602504101210902402001450d00200441186a200441206a41186a290300370300200441106a200441206a41106a290300370300200441086a200441206a41086a29030037030020042004290320370300410021090b0240024020090d002004418c096a200441086a29030037020020044194096a200441106a2903003702002004419c096a200441186a29030037020020042000410c6a360280092004200a3602fc08200420073602f808200420053602f4082004200b3602f0082004200429030037028409200441f0006a2004290340370300200441f8006a200441c0006a41086a29030037030020044188016a41003602002004420037036820044200370350200441003a008c0120044100360280012004418d016a200429002037000020044195016a200441206a41086a2900003700002004419d016a200441206a41106a290000370000200441a5016a200441206a41186a290000370000200441003a00ad01200441f0086a200441d0006a10800321010c010b200441e4006a410036020020044100360270200441003602542005200a41e0006c6a41e8026a2101200441d0006a1081030b200141106a200337030020012002370308200142013703002000200028020041016a360200200441d00b6a24000f0b2006417f6a2106200520084102746a41880b6a28020021050c000b0b103c000b41a797cc004110200441d0006a41c8c1c30041c897cc001046000bef0801087f230041d00b6b22042400024020002802000d002000417f360200200441206a41186a200141186a290000370300200441206a41106a200141106a290000370300200441206a41086a200141086a2900003703002004200129000037032002400240024020002802042205450d00200041086a28020021060c010b41002106200441f0086a410041e002109f081a200441d0006a410041a008109f081a41880b10332205450d01200541003b010620054100360200200541086a200441f0086a41e002109d081a200541e8026a200441d0006a41a008109d081a200041086a4100360200200020053602040b2004200041046a22073602f808200420053602f408200420063602f008034020052f010622084105742109410021014100210a024002400240034020092001460d010240200441206a200520016a41086a412010a008220b0d00410021012006210b0c030b200141206a2101200a41016a210a200b417f4a0d000b200a417f6a21080b20060d01410121014100210b2008210a0b200441d0006a41106a200a360200200441d0006a410c6a2007360200200441d0006a41086a2005360200200420073602f808200420053602f408200420063602f0082004200b360254200420013602504101210902402001450d00200441186a200441206a41186a290300370300200441106a200441206a41106a290300370300200441086a200441206a41086a29030037030020042004290320370300410021090b0240024020090d002004418c096a200441086a29030037020020044194096a200441106a2903003702002004419c096a200441186a29030037020020042000410c6a360280092004200a3602fc08200420073602f808200420053602f4082004200b3602f0082004200429030037028409200441f0006a2004290340370300200441f8006a200441c0006a41086a29030037030020044188016a41003602002004420037036820044200370350200441003a008c0120044100360280012004418d016a200429002037000020044195016a200441206a41086a2900003700002004419d016a200441206a41106a290000370000200441a5016a200441206a41186a290000370000200441003a00ad01200441f0086a200441d0006a10800321010c010b200441e4006a410036020020044100360270200441003602542005200a41e0006c6a41e8026a2101200441d0006a1081030b200441d0006a41186a200241186a290000370300200441d0006a41106a200241106a290000370300200441d0006a41086a200241086a29000037030020042002290000370350200441206a41086a200341086a28020036020020042003290200370320200441f0086a200141306a200441d0006a200441206a108303024020042802f008450d0020042802f4082201450d00200441f8086a280200450d00200110350b2000200028020041016a360200200441d00b6a24000f0b2006417f6a2106200520084102746a41880b6a28020021050c000b0b103c000b41a797cc004110200441d0006a41c8c1c30041c897cc001046000b920402087f027e230041106b22022400200241003602082002420137030020002802102103200041186a2802002204200210770240024002402004450d00200320044105746a21050340200328020021060240024020022802042207200228020822046b4104490d00200228020021080c010b200441046a22082004490d03200741017422092008200920084b1b22094100480d030240024020070d00024020090d00410121080c020b2009103322080d010c060b2002280200210820072009460d0020082007200910372208450d050b20022009360204200220083602000b200820046a20063600002002200441046a360208200341086a200210aa042005200341206a2203470d000b0b200041086a290300210a2000290300210b0240024020022802042207200228020822036b4110490d00200341106a2104200228020021080c010b200341106a22042003490d01200741017422082004200820044b1b22064100480d010240024020070d00024020060d00410121080c020b200610332208450d040c010b2002280200210820072006460d0020082007200610372208450d030b20022006360204200220083602000b200820036a2203200a3700082003200b370000200220043602082000411c6a200210ab04200228020421032001290200200235020842208620022802002204ad84100202402003450d00200410350b200241106a24000f0b103e000b103c000bdf2204137f017e017f087e230041a0026b22032400024002400240024002400240024002400240024002400240024002400240024020012d00000e050001020304000b200341b4016a4101360200200342013702a401200341e8d4ca003602a0012003410436027c2003419cd5ca003602782003200341f8006a3602b001200341a0016a41b0b4cc00104c000b4102210402400240024020022d00000d0020022d00014101470d00200141046a2802002101200241196a2d00002104200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a290100370320200320043a001f200320053a001e200320063b011c200320073a001b200320083a001a200320093b01182003200a3a00172003200b3a00162003200c3b01142003200d3a00132003200e3a00122003200f3b0110200320103a000f200320113a000e200320123b010c200320133a000b200320143a000a200320153b0108200341286a2001109604200341a0016a200328022822052003280230220b10cb02200341f8006a41086a2202200341a0016a41106a290300370300200341f8006a41106a2204200341a0016a41186a290300370300200341f8006a41186a2206200341c0016a290300370300200320032903a8013703780240024020032903a0014201520d00200341386a41186a2006290300370300200341386a41106a2004290300370300200341386a41086a200229030037030020032003290378370338410321044100210241f6b5c300210741052106410221084105210a0c010b200341386a41086a200341086a41086a290300370300200341386a41106a200341086a41106a290300370300200341386a41186a200341086a41186a29030037030020032003290308370338200342003703682003428080e983b1de163703602003200341086a36025c2003200341086a3602742003200341f4006a3602a8012003200341dc006a3602a4012003200341e0006a3602a001200341f8006a200341086a200341a0016a108c030240024020032802784101470d0020032f007d20032d007f41107472220641107621092006410876210820034184016a280200210a200341f8006a41086a280200210720032d007c210c0c010b4104210c0240200341f8006a41086a2903004201520d00200341f8006a41106a290300211620032802742102200341d8016a200341f8006a41186a290300370300200341d0016a2016370300200341a0016a41086a41003a0000200341a9016a2002290000370000200341b1016a200241086a290000370000200341b9016a200241106a290000370000200341c1016a200241186a290000370000200341033a00a00141b0b4cc004100200341a0016a10d4010b0b41042104410021020240200c41ff01714104460d00200c21040c010b200341d0016a4200370300200341c8016a428080e983b1de16370300200341a0016a41106a200341386a41086a290300370300200341a0016a41186a200341386a41106a290300370300200341c0016a200341386a41186a290300370300200342013703a001200320032903383703a8012003200b36027c20032005360278200341a0016a41086a200341f8006a10b204410121020b0240200328022c450d00200510350b20020d02200941ff0171411074200841ff017141087472200641ff0171724108742102200aad4220862007ad8421160c010b410021020b200042003703082000411c6a2016370200200041186a2002200441ff017172360200420121160c0e0b200341c8016a2001360200200341ad016a200341106a290300370000200341b5016a200341186a290300370000200341bd016a200341206a290300370000200341003a00a401200341023a00a001200320032903083700a50141b0b4cc004100200341a0016a10d401420021160c0a0b200141246a2802002105200341386a41186a200141196a290000370300200341386a41106a200141116a290000370300200341386a41086a200141096a29000037030020032001290001370338410221014100210420022d00000d0a20022d00014101470d0a200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211720032002411a6a29010037039001200320013a008f01200320063a008e01200320073b018c01200320083a008b01200320093a008a012003200a3b0188012003200b3a0087012003200c3a0086012003200d3b0184012003200e3a0083012003200f3a008201200320103b018001200320113a007f200320123a007e200320133b017c200320143a007b200320153a007a200320173b01780240200341f8006a200341386a412010a0080d0041ebb5c3002102410b21074103210141800a21064180800c21050c0c0b200341e0006a2005109604200341a0016a200328026022042003280268220910cb02410321014105210641002107024020032903a0014201510d004183b6c3002102420b2116410021080c090b200341d0016a2903002118200341c8016a2903002119200341b0016a22022903002116200341a0016a41206a290300211a20032903a801211b2002200341b8016a2903003703002003201a3703b8012003201b3703a001200320163703a801200341a0016a200341f8006a412010a0080d02200341086a200341f8006a200341386a20192018410110ef02200341086a41086a290300211b0240024020032802084101460d004200211642002018200341086a41106a2903007d2019201b54ad7d221a2019201b7d221b201956201a201856201a2018511b22021b21184200201b20021b2119200341386a41106a290300211c2003290340211d2003290338211e2003290350211a4201211b4100210741002108410021060c010b201b4220882116200328020c220141187621072001411076210820014108762106201ba72102200141ff01714104470d094200211b0b200341d0016a2018370300200341c8016a2019370300200341c0016a201a3703002003201b3703a001200341b8016a201c3703002003201e3703a8012003201d3703b00102400240201b4201510d002009ad4220862004ad8410070c010b2003200936020c20032004360208200341a8016a200341086a10b2040b410421010c080b41022104024020022d00000d0020022d00014101470d00200141046a2802002101200241196a2d00002104200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a290100370320200320043a001f200320053a001e200320063b011c200320073a001b200320083a001a200320093b01182003200a3a00172003200b3a00162003200c3b01142003200d3a00132003200e3a00122003200f3b0110200320103a000f200320113a000e200320123b010c200320133a000b200320143a000a200320153b0108200341286a2001109604200341a0016a200328022822052003280230220610cb024103210441800a2102024020032903a0014201510d004280808080b00121164183b6c30021060c060b200341d0016a2903002119200341c8016a290300211b200341a0016a41106a2903002116200341a0016a41206a290300211a20032903a8012118200341386a41106a200341b8016a2903003703002003201a3703502003201837033820032016370340200341386a200341086a412010a0080d032003201b370360200320193703680240201b201984500d002003200341086a360274200341f8006a200341086a200341e0006a200341f4006a10f00220032903784201520d002003290380012116200341d8016a200341f8006a41106a290300370300200341d0016a2016370300200341a0016a41086a41003a0000200341a9016a2003290308370000200341b1016a200341086a41086a290300370000200341b9016a200341086a41106a290300370000200341c1016a200341206a290300370000200341033a00a00141b0b4cc004100200341a0016a10d4010b2006ad4220862005ad84100741042104420021160c050b410021020c050b20022d000120022d0000410047720d02200141116a290000211a200141096a2900002118200141196a29000021192001290001211b200341e0006a200141246a2802002207109604200341a0016a200328026022022003280268220810cb02200341d0016a2101200341c8016a2104200341b8016a2105200341c0016a2106024020032903a0014201520d00200129030021162004290300211c200341a0016a41106a290300211d2006290300211e20032903a801211f200341386a41106a20052903003703002003201e3703502003201f3703382003201d3703402003201c37030820032016370310201c201684500d002003200341386a360228200341f8006a200341386a200341086a200341286a10f00220032903784201520d002003290380012116200341d8016a200341f8006a41106a290300370300200341d0016a2016370300200341a0016a41086a41003a0000200341a9016a2003290338370000200341b1016a200341386a41086a290300370000200341b9016a200341386a41106a290300370000200341c1016a200341d0006a290300370000200341033a00a00141b0b4cc004100200341a0016a10d4010b420021162001420037030020044200370300200620193703002005201a3703002003201b3703a801200342013703a001200320183703b0012003200836027c20032002360278200341a8016a200341f8006a10b20402402003280264450d00200210350b200341ad016a2018370000200341c8016a2007360200200341bd016a2019370000200341b5016a201a3700002003201b3700a501200341003a00a401200341023a00a00141b0b4cc004100200341a0016a10d4010c070b41fbb5c300210242082116410121080c050b41808a04210242808080808001211641fbb5c30021060c010b20004200370308200041186a4102360200420121160c070b0240200328022c450d00200510350b20044104460d0120162006ad8421160b200042003703082000411c6a2016370200200041186a2002200472360200420121160c050b200341a8016a2001360200200341013a00a401200341023a00a00141b0b4cc004100200341a0016a10d401420021160c010b02402003280264450d00200410350b0240200141ff01714104460d002007411874210420064108744180fe037121062008411074418080fc077121052016a721070c030b200341c8016a2005360200200341ad016a200341c0006a290300370000200341b5016a200341c8006a290300370000200341bd016a200341d0006a290300370000200341003a00a401200341023a00a001200320032903383700a50141b0b4cc004100200341a0016a10d401420021160b200020163703080c020b41002105410021060b200041206a20073602002000411c6a200236020020004200370308200041186a2004200572200672200141ff017172360200420121160b20002016370300200341a0026a24000ba90102017f027e02400240411010332202450d0020024110412010372202450d0120022000290000370000200241186a200041186a290000370000200241106a200041106a290000370000200241086a200041086a290000370000200041286a2903002103200029032021042002412041c00010372200450d0120002004370020200041286a200337000020012902002000ad42808080808006841002200010350f0b1045000b103c000b9aa90105037f017e137f077e107f230041f0126b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0c000102030405060708090a0b000b200341c4106a4101360200200342013702b410200341e8d4ca003602b0102003410436029c0b2003419cd5ca003602980b2003200341980b6a3602c010200341b0106a41b0b4cc00104c000b200241036a2d0000210420022f00012105200141196a2900002106200141186a2d00002107200141176a2d00002108200141156a2f00002109200141146a2d0000210a200141136a2d0000210b200141116a2f0000210c200141106a2d0000210d2001410f6a2d0000210e2001410d6a2f0000210f2001410c6a2d000021102001410b6a2d00002111200141096a2f00002112200141086a2d00002113200141076a2d00002114200141056a2f00002115200141046a2d00002116200141036a2d0000211720012f000121180240024002400240024020022d00002219417f6a220141024b0d00024020010e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200520044110747220194100477241ff01710d010b41fafdc600ad428080808080018410012202290000211a2002290008211b2002103541e8adc400ad4280808080a0018410012202290000211c2002290008211d200210352003201d3703b00b2003201c3703a80b2003201b3703a00b2003201a3703980b200341b0106a200341980b6a10dc020240024020032802b01022020d0041002105200341003602a00620034208370398064101210141082102410021040c010b200320032902b410221a37029c062003200236029806201a422088a722044114492101201aa721050b200320063703e008200320073a00df08200320083a00de08200320093b01dc082003200a3a00db082003200b3a00da082003200c3b01d8082003200d3a00d7082003200e3a00d6082003200f3b01d408200320103a00d308200320113a00d208200320123b01d008200320133a00cf08200320143a00ce08200320153b01cc08200320163a00cb08200320173a00ca08200320183b01c8082001450d01200341b0106a41186a2207200341c8086a41186a290300370300200341b0106a41106a2208200341c8086a41106a290300370300200341b0106a41086a2209200341c8086a41086a290300370300200320032903c8083703b010024020042005470d0020034198066a2004109401200328029c062105200328029806210220032802a00621040b200220044106746a2201420037030820014201370300200141106a4200370300200141186a4200370300200141206a20032903b010370300200141286a2009290300370300200141306a2008290300370300200141386a20072903003703002003200441016a22073602a00641fafdc600ad42808080808001841001220129000021062001290008211a2001103541e8adc400ad4280808080a0018410012201290000211b2001290008211c200110352003201c3703b00b2003201b3703a80b2003201a3703a00b200320063703980b0240024020020d00200341980b6aad428080808080048410070c010b200341b0106a2002200710b404200341980b6aad428080808080048420033502b81042208620032802b0102201ad841002024020032802b410450d00200110350b200541ffffff1f71450d00200210350b200341bc106a2004360200200341b8106a41063a0000200341113a00b01041b0b4cc004100200341b0106a10d401200041106a2007ad42f0c8217e4280a3c3c7007c37030020004201370308200042003703000c1d0b200341023a00b01020032802b01021010c010b4183b0302101200541ffffff1f71450d00200210350b200041206a41113602002000411c6a41c6b8c300360200200041186a200136020020004200370308200042013703000c1a0b200341c8086a200141046a41a002109d081a410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a2901003703a00e200320013a009f0e200320043a009e0e200320053b019c0e200320073a009b0e200320083a009a0e200320093b01980e2003200a3a00970e2003200b3a00960e2003200c3b01940e2003200d3a00930e2003200e3a00920e2003200f3b01900e200320103a008f0e200320113a008e0e200320123b018c0e200320133a008b0e200320143a008a0e200320153b01880e4103210120032802d008220241e4004b0d0020032002ad221e42004280c0c6c9faeb38420010840820034198066a200341880e6a10b504200341b0106a200328029806220220032802a00610d402200341d0036a200341b0106a41a402109d081a200341b0036a41086a2201200341dd126a290000370300200341b0036a41106a2204200341e5126a290000370300200341b0036a41176a2205200341ec126a280000360000200320032900d5123703b003200341086a290300211f2003290300211c0240024020032d00d41222074102460d0020034188016a200341d0036a41a402109d081a200341e8006a41176a2005280000360000200341e8006a41106a2004290300370300200341e8006a41086a2001290300370300200320032903b0033703680240200328029c06450d00200210350b200341b0106a20034188016a41a402109d081a200341b0106a41a4026a20073a0000200341d5126a2003290368370000200341dd126a200341e8006a41086a290300370000200341e5126a200341e8006a41106a290300370000200341ec126a200341ff006a2800003600000240200341b0106a41186a2802002208450d0020032802c010210241002101410021040340024002400240200241086a2207280200417f6a220541054b0d00024020050e06000101010100000b20010d01410021010c020b200141016a21010c010b200420016b220520084f0d1020034198066a41186a2209200220014105746b220541186a220a29030037030020034198066a41106a220b200541106a220c29030037030020034198066a41086a220d200541086a220e290300370300200320052903003703980620072903002106200241106a220f290300211a200241186a2210290300211b20052002290300370300200a201b370300200c201a370300200e200637030020102009290300370300200f200b2903003703002007200d29030037030020022003290398063703000b200241206a21022008200441016a2204470d000b2001417f6a20084f0d002003200820016b3602c8100b200341cc106a220210a3042002200341c8086a41a002109d081a200341980b6a200341b0106a41c002109d081a200341980b6a41086a290300211b20032903980b211d0c010b0240200328029c06450d00200210350b200341b00b6a41003602004200211d200342003703a00b200342003703980b200342083703a80b200341b40b6a200341c8086a41a002109d081a4200211b0b2003201c4280809aa6eaafe3017c221a3703980b2003201f201a201c54ad7c221c3703a00b0240201a201d58201c201b58201c201b5122041b0d002003201c201b7d201a201d54ad7d22063703d8032003201a201d7d221f3703d0032003200341880e6a360240201f2006844200510d002003200341880e6a36028801200320034188016a3602b8102003200341c0006a3602b4102003200341d0036a3602b01020034198066a200341880e6a200341b0106a108c03024002402003280298064101470d0020032f009d0620032d009f06411074722102200341a0066a290300210620032d009c0621010c010b41042101024020034198066a41086a2903004201520d0020034198066a41106a29030021062003280288012102200341e8106a20034198066a41186a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a2002290000370000200341c1106a200241086a290000370000200341c9106a200241106a290000370000200341d1106a200241186a290000370000200341033a00b01041b0b4cc004100200341b0106a10d4010b0b200141ff01714104460d000240200341ac0b6a28020041ffffff3f71450d0020032802a80b10350b200341b40b6a10a3040c020b0240201d201a58201b201c5820041b0d002003201b201c7d201d201a54ad7d22063703d8032003201d201a7d221a3703d003201a200684500d002003200341880e6a3602880120034198066a200341880e6a200341d0036a20034188016a10f0022003290398064201520d0020032903a0062106200341e8106a20034198066a41106a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a20032903880e370000200341c1106a200341880e6a41086a290300370000200341c9106a200341880e6a41106a290300370000200341d1106a200341a00e6a290300370000200341033a00b01041b0b4cc004100200341b0106a10d4010b200341b00b6a3502002106200341b0106a200341980b6a41c002109d081a20034198066a200341880e6a10b5042003280298062102200320032802a0063602d403200320023602d003200341b0106a200341d0036a10b0040240200328029c06450d00200210350b0240200341c4106a28020041ffffff3f71450d0020032802c01010350b200341cc106a10a304200341b0106a41086a41003a0000200341b9106a20032903880e370000200341c9106a200341880e6a41106a290300370000200341d1106a200341a00e6a290300370000200341880e6a41086a290300211a200341113a00b010200341b0106a41116a201a37000041b0b4cc004100200341b0106a10d401200041106a201e42e0c6db007e20064280b5187e7c4280c5d8d8007c37030020004201370308200042003703000c1b0b41d7b8c300ad4280808080d001842106200341c8086a10a30441981621020b200020023b00192000200637021c200042003703082000411b6a20024110763a0000200041186a20013a0000200042013703000c190b2001410c6a2802002107200141086a2802002105200141046a28020021084102210920022d00000d1620022d00014101470d16200241196a2d00002101200241186a2d00002104200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820032002411a6a2901003703e803200320013a00e703200320043a00e603200320093b01e4032003200a3a00e3032003200b3a00e2032003200c3b01e0032003200d3a00df032003200e3a00de032003200f3b01dc03200320103a00db03200320113a00da03200320123b01d803200320133a00d703200320143a00d603200320153b01d403200320163a00d303200320173a00d203200320183b01d003200341b0106a200341d0036a10b504200341206a20032802b010220120032802b81041b0b4cc0041004100108a0220032802202102024020032802b410450d00200110350b41032109024020024101460d0041d0b9c300ad4280808080800184210641980221040c180b0240200741e4004d0d0041d8b9c300ad4280808080a002842106411821040c180b200341980b6a200341d0036a10b604200341b0106a20032802980b220120032802a00b10cc02200341b0106a41086a290300420020032802c01022021b211a20032903b010420020021b211b20032902c41021060240200328029c0b450d00200110350b2006420020021b211e2002410120021b2119200341106a2007ad4200428080d287e2bc2d42001084080240201b2003290310221f5a201a200341106a41086a290300221d5a201a201d5122021b0d002003201d201a7d201f201b54ad7d22063703d0082003201f201b7d221c3703c8082003200341d0036a3602880e201c2006844200510d002003200341d0036a36029806200320034198066a3602b8102003200341880e6a3602b4102003200341c8086a3602b010200341980b6a200341d0036a200341b0106a108c030240024020032802980b4101470d0020032f009d0b20032d009f0b411074722104200341a00b6a290300210620032d009c0b21090c010b410421090240200341980b6a41086a2903004201520d00200341980b6a41106a29030021062003280298062101200341e8106a200341980b6a41186a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a2001290000370000200341c1106a200141086a290000370000200341c9106a200141106a290000370000200341d1106a200141186a290000370000200341033a00b01041b0b4cc004100200341b0106a10d4010b0b200941ff01714104460d00201e42ffffff3f83500d18201910350c180b0240201b201f58201a201d5820021b0d002003201a201d7d201b201f54ad7d22063703d0082003201b201f7d221a3703c808201a200684500d002003200341d0036a36029806200341980b6a200341d0036a200341c8086a20034198066a10f00220032903980b4201520d0020032903a00b2106200341e8106a200341980b6a41106a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a20032903d003370000200341c1106a200341d0036a41086a290300370000200341c9106a200341d0036a41106a290300370000200341d1106a200341e8036a290300370000200341033a00b01041b0b4cc004100200341b0106a10d4010b0240201e4220882220a72202450d0020024105742101201921020340200341b0106a200210970420033502b81042208620032802b0102204ad841007024020032802b410450d00200410350b200241206a2102200141606a22010d000b0b200341003602800b200342013703f80a200341f80a6a4100200741c4006c221641c4006d108a0120032802800b210d20032802f80a21180240024002402016450d00200820166a21212018200d4105746a2101200341b0106a41206a2117200341b0106a41216a2104200341980b6a411f6a210e4100210a0340200341880e6a41186a22072008200a6a220241186a290200370300200341880e6a41106a2209200241106a290200370300200341880e6a41086a220b200241086a290200370300200320022902003703880e200341980b6a41086a220c200241296a290000370300200341980b6a41106a220f200241316a290000370300200341980b6a41186a2210200241396a290000370300200e200241c0006a2800003600002003200241216a2900003703980b200241206a2d000022114106460d02200341c8086a41186a22122007290300370300200341c8086a41106a22132009290300370300200341c8086a41086a2214200b290300370300200320032903880e3703c808200341b0106a41186a2207200341d0036a41186a290300370300200341b0106a41106a2209200341d0036a41106a290300370300200341b0106a41086a2215200341d0036a41086a290300370300200320032903d0033703b010200320113a00d010200420032903980b370000200441086a200c290300370000200441106a200f290300370000200441186a20102903003700002004411f6a200e280000360000200341c0006a200341c8086a109704200335024821062003280240210b412010332202450d0d200220032903b010370000200241186a2007290300370000200241106a2009290300370000200241086a201529030037000020034188016a201710ac04200328028801210c0240024020032802900122070d00200741206a21090c010b200741206a22092007490d0f200941c000200941c0004b1b220f4100480d0f20024120200f10372202450d0e0b200241206a200c2007109d081a0240200328028c01450d00200c10350b2006422086200bad842009ad4220862002ad8410022002103502402003280244450d00200b10350b024020032d00d0104101470d0020032802d810450d0020032802d41010350b20034198066a41086a2014290300220637030020034198066a41106a2013290300221a37030020034198066a41186a2012290300221b370300200320032903c808221c37039806200141186a201b370000200141106a201a370000200141086a20063700002001201c370000200d41016a210d200141206a21012016200a41c4006a220a470d000b0b2003200d3602800b0c010b2003200d3602800b200241c4006a2021460d00200241e4006a21022016200a6b41bc7f6a21010340024020022d00004101470d00200241086a280200450d00200241046a28020010350b200241c4006a2102200141bc7f6a22010d000b0b02402005450d00200541c4006c450d00200810350b20032802fc0a2102200dad210602400240200d450d00200341c8106a200d360200200341c4106a20023602002003201f3703b010200320183602c0102003201d3703b810200341980b6a200341d0036a10b60420032802980b2101200320032802a00b3602cc08200320013602c808200341b0106a200341c8086a108d030240200328029c0b450d00200110350b0240200241ffffff3f71450d00201810350b410121010c010b200341b0106a200341d0036a10b60420033502b81042208620032802b0102201ad841007024020032802b410450d00200110350b410021010b202042c0d89e017e200642a0eae1017e7c20204280c2d72f7e7c20064280c2d72f7e7c21060240200241ffffff3f71450d0020010d00201810350b200642c0db89db007c21060240201e42ffffff3f83500d00201910350b20004201370308200041106a2006370300200042003703000c180b41022101024020022d00000d004101210520022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a290100370358200320013a0057200320043a0056200320073b0154200320083a0053200320093a00522003200a3b01502003200b3a004f2003200c3a004e2003200d3b014c2003200e3a004b2003200f3a004a200320103b0148200320113a0047200320123a0046200320133b0144200320143a0043200320153a0042200320163b0140200341980b6a200341c0006a10b604200341b0106a20032802980b220220032802a00b220110cc020240024020032802c01022040d004200211b4200211c4200211d0c010b2001ad4220862002ad841007200341b8106a290300211d20032903b010211c20032902c410211b200421050b0240200328029c0b450d00200210350b200341e80d6a200341c0006a10b504200341b0106a20032802e80d220220032802f00d220410d402024020032d00d412220941024622010d002004ad4220862002ad8410070b200341880e6a200341b0106a41a402109d081a200341f80a6a41176a2204200341ec126a280000360000200341f80a6a41106a2207200341e5126a290000370300200341f80a6a41086a2208200341dd126a290000370300200320032900d5123703f80a200341d0036a200341880e6a41a402109d081a200341b0036a41176a220a2004280000360000200341b0036a41106a22042007290300370300200341b0036a41086a22072008290300370300200320032903f80a3703b003024020010d0020034188016a200341d0036a41a402109d081a200341e8006a41176a200a280000360000200341e8006a41106a2004290300370300200341e8006a41086a2007290300370300200320032903b003370368024020032802ec0d450d00200210350b200341c8086a41066a20034188016a41a402109d081a20034198066a200341c8086a41aa02109d081a200341f8056a41176a2202200341e8006a41176a280000360000200341f8056a41106a2201200341e8006a41106a290300370300200341f8056a41086a2204200341e8006a41086a290300370300200320032903683703f805200341980b6a20034198066a41066a41a402109d081a200341980b6a41a4026a20093a0000200341bd0d6a20032903f805370000200341c50d6a2004290300370000200341cd0d6a2001290300370000200341d40d6a2002280000360000200341980b6a41086a290300211e20032903980b211f20032802a80b210702400240200341b00b6a280200220841057422010d00420021064200211a0c010b200741106a2102420021064200211a0340200241086a2903004200200241786a29030042015122041b201a7c2002290300420020041b221a20067c2206201a54ad7c211a200241206a2102200141606a22010d000b0b201e201d7c201f201c7c221c201f54ad7c201a7c201c20067c2206201c54ad7c211a0240201b422088221ca72202450d0020024105742101200521020340200341b0106a200210970420033502b81042208620032802b0102204ad841007024020032802b410450d00200410350b200241206a2102200141606a22010d000b0b20032006370398062003201a3703a00602402006201a84500d002003200341c0006a3602880e200341c8086a200341c0006a20034198066a200341880e6a10f00220032903c8084201520d0020032903d008211d200341e8106a200341c8086a41106a290300370300200341e0106a201d370300200341b0106a41086a41003a0000200341b9106a2003290340370000200341c1106a200341c0006a41086a290300370000200341c9106a200341c0006a41106a290300370000200341d1106a200341d8006a290300370000200341033a00b01041b0b4cc004100200341b0106a10d4010b200341e8106a201a370300200341e0106a2006370300200341b0106a41086a41013a0000200341b9106a2003290340370000200341c9106a200341d0006a290300370000200341d1106a200341d8006a290300370000200341c0006a41086a2903002106200341113a00b010200341b0106a41116a200637000041b0b4cc004100200341b0106a10d401201c42c0d89e017e2008ad42a09c017e7c201c4280c2d72f7e7c200341bc0b6a35020042a0f7367e7c2106200341b40b6a21020240200341ac0b6a28020041ffffff3f71450d00200710350b20064280eaee92017c2106200210a3040240201b42ffffff3f83500d00200510350b20004201370308200041106a2006370300200042003703000c190b024020032802ec0d450d00200210350b41032101201b42ffffff3f83500d00200510350b20004198043b001920004200370308200041206a41083602002000411c6a41c8b9c300360200200041186a20013a0000200042013703000c170b200141106a290300211a200141086a290300211b200141046a28020021012002411a6a2901002106200241196a2d00002105200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211741012104024020022d00000d0020022d000141014721040b200320063703e008200320053a00df08200320073a00de08200320083b01dc08200320093a00db082003200a3a00da082003200b3b01d8082003200c3a00d7082003200d3a00d6082003200e3b01d4082003200f3a00d308200320103a00d208200320113b01d008200320123a00cf08200320133a00ce08200320143b01cc08200320153a00cb08200320163a00ca08200320173b01c808024020040d00200341880e6a41186a200341c8086a41186a290300370300200341880e6a41106a200341c8086a41106a290300370300200341880e6a41086a200341c8086a41086a290300370300200320032903c8083703880e41fafdc600ad42808080808001841001220229000021062002290008211c2002103541e8adc400ad4280808080a0018410012202290000211d2002290008211f200210352003201f3703b00b2003201d3703a80b2003201c3703a00b200320063703980b200341b0106a200341980b6a10dc0220032802b0102205410820051b210741beb9c300ad4280808080a001842106419806210241032104200120032902b410420020051b221c422088a74f0d13200720014106746a2205450d13024020052903004201510d0041beb9c300ad4280808080a0018421060c140b0240200720014106746a2202290308201b58200241106a2903002206201a582006201a511b0d0041b4b9c300ad4280808080a00184210641980821020c140b200341c0006a200341880e6a10b504200341b0106a20032802402205200328024810d402200341d0036a200341b0106a41a402109d081a200341b0036a41086a200341dd126a290000370300200341b0036a41106a200341e5126a290000370300200341b0036a41176a2208200341ec126a280000360000200320032900d5123703b00302400240024002400240024020032d00d41222094102460d00200241086a210b20034188016a200341d0036a41a402109d081a200341e8006a41176a2008280000360000200341e8006a41106a2202200341b0036a41106a290300370300200341e8006a41086a2204200341b0036a41086a290300370300200320032903b00337036802402003280244450d00200510350b200341c8086a41066a20034188016a41a402109d081a20034198066a200341c8086a41aa02109d081a200341f8056a41176a2205200341e8006a41176a280000360000200341f8056a41106a22082002290300370300200341f8056a41086a22022004290300370300200320032903683703f805200341980b6a20034198066a41066a41a402109d081a200341980b6a41a4026a20093a0000200341bd0d6a20032903f805370000200341c50d6a2002290300370000200341cd0d6a2008290300370000200341d40d6a2005280000360000200b41086a290300211a200b290300211b20032802a80b210941002102200341b00b6a280200220a41014b0d01200a0e020302030b02402003280244450d00200510350b41aab9c300ad4280808080a00184210641980a21020c180b200a2104034020022004410176220520026a2208200920084105746a28020020014b1b2102200420056b220441014b0d000b0b200920024105746a220528020022042001460d01200a200220042001496a2202490d0d0b0240200a200341ac0b6a280200470d00200341980b6a41106a200a410110a10120032802a80b21090b200920024105746a220441206a2004200a20026b410574109e081a200441186a201a370300200441106a201b37030020044201370308200420013602002003200a41016a220a3602b00b0c010b200a20024d0d0c0240200920024105746a2208280208417f6a220c41054b0d00419bb9c300ad4280808080f00184210641980c210241032104200c0e06140000000014140b200841086a420137030020052001360200200841186a201a370300200841106a201b3703000b200b29030021062003200b41086a290300221a3703a00620032006370398062003200341880e6a3602880102402006201a844200510d002003200341880e6a3602d0032003200341d0036a3602b810200320034188016a3602b410200320034198066a3602b010200341c8086a200341880e6a200341b0106a108c030240024020032802c8084101470d0020032f00cd0820032d00cf08411074722102200341d0086a290300210620032d00cc0821040c010b410421040240200341c8086a41086a2903004201520d00200341c8086a41106a290300210620032802d0032102200341e8106a200341c8086a41186a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a2002290000370000200341c1106a200241086a290000370000200341c9106a200241106a290000370000200341d1106a200241186a290000370000200341033a00b01041b0b4cc004100200341b0106a10d4010b0b200441ff01714104470d130b200341bc0b6a3502002106200341b0106a200341980b6a41c002109d081a200341c8086a200341880e6a10b50420032802c8082102200320032802d00836029c062003200236029806200341b0106a20034198066a10b004024020032802cc08450d00200210350b200aad211a0240200341c4106a28020041ffffff3f71450d0020032802c01010350b200341cc106a10a304200341b0106a41086a41033a0000200341b9106a20032903880e370000200341c9106a200341880e6a41106a290300370000200341d1106a200341a00e6a290300370000200341dc106a2001360200200341880e6a41086a290300211b200341113a00b010200341b0106a41116a201b37000041b0b4cc004100200341b0106a10d401201a42b0901f7e200642a0e1e7007e7c4280b191e4007c21060240201c42ffffff1f83500d00200710350b20004201370308200041106a2006370300200042003703000c170b410221040c130b02400240024002400240024020022d00000d0020022d00014101470d00200141046a2802002107200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703a00e200320013a009f0e200320043a009e0e200320053b019c0e200320083a009b0e200320093a009a0e2003200a3b01980e2003200b3a00970e2003200c3a00960e2003200d3b01940e2003200e3a00930e2003200f3a00920e200320103b01900e200320113a008f0e200320123a008e0e200320133b018c0e200320143a008b0e200320153a008a0e200320163b01880e200341e80d6a200341880e6a10b504200341b0106a20032802e80d220220032802f00d10d402200341d0036a200341b0106a41a402109d081a200341b0036a41086a2201200341dd126a290000370300200341b0036a41106a2204200341e5126a290000370300200341b0036a41176a2205200341ec126a280000360000200320032900d5123703b003024020032d00d41222084102460d0020034188016a200341d0036a41a402109d081a200341e8006a41176a2005280000360000200341e8006a41106a2004290300370300200341e8006a41086a2001290300370300200320032903b003370368024020032802ec0d450d00200210350b200341c8086a41066a20034188016a41a402109d081a20034198066a200341c8086a41aa02109d081a200341f8056a41176a2202200341e8006a41176a280000360000200341f8056a41106a2201200341e8006a41106a2903003703004108210a200341f8056a41086a2204200341e8006a41086a290300370300200320032903683703f805200341980b6a20034198066a41066a41a402109d081a200341980b6a41a4026a20083a0000200341bd0d6a20032903f805370000200341c50d6a2004290300370000200341cd0d6a2001290300370000200341d40d6a20022800003600004101210b41d0b9c300210c20032802a80b210841002102200341b00b6a280200220941014b0d0220090e020403040b024020032802ec0d450d00200210350b2003410a360248200341aab9c300360244200341053a004220034183303b01400c040b200341023a00400c030b20092101034020022001410176220420026a2205200820054105746a28020020074b1b2102200120046b220141014b0d000b0b200820024105746a2802002007470d00200920024d0d0d200820024105746a220141186a2903002106200141106a290300211a2001290308211b2001200141206a2002417f7320096a410574109e081a20032009417f6a22023602b00b201b4201510d02418db9c300210c410e210a4107210b0b2003200a3602482003200c3602442003200b3a004220034183303b01400240200341ac0b6a28020041ffffff3f71450d00200810350b200341b40b6a10a3040b200341f80a6a41086a200341c0006a41086a290300220637030020032003290340221a3703f80a20004200370308200041186a201a370300200041206a2006370300200042013703000c160b2003201a37039806200320063703a0060240201a200684500d002003200341880e6a3602d003200341c8086a200341880e6a20034198066a200341d0036a10f00220032903c8084201520d0020032903d0082106200341e8106a200341c8086a41106a290300370300200341e0106a2006370300200341b0106a41086a41003a0000200341b9106a20032903880e370000200341c1106a200341880e6a41086a290300370000200341c9106a200341880e6a41106a290300370000200341d1106a200341a00e6a290300370000200341033a00b01041b0b4cc004100200341b0106a10d4010b200341bc0b6a3502002106200341b0106a200341980b6a41c002109d081a200341c8086a200341880e6a10b50420032802c8082101200320032802d00836029c062003200136029806200341b0106a20034198066a10b004024020032802cc08450d00200110350b2002ad211a0240200341c4106a28020041ffffff3f71450d0020032802c01010350b200341cc106a10a304200341b0106a41086a41043a0000200341b9106a20032903880e370000200341c9106a200341880e6a41106a290300370000200341d1106a200341a00e6a290300370000200341dc106a2007360200200341880e6a41086a290300211b200341113a00b010200341b0106a41116a201b37000041b0b4cc004100200341b0106a10d401200041106a201a42b0901f7e200642a0e1e7007e7c4280b191e4007c37030020004201370308200042003703000c150b200141106a2903002106200141086a290300211a200141046a280200210420032002411a6a2901003703e008410221012003200241026a2901003703c80820032002410a6a2901003703d0082003200241126a2901003703d8080240024020022d00014101470d0020022d000041ff01710d00200341b0106a41186a200341c8086a41186a290300370300200341b0106a41106a200341c8086a41106a290300370300200341b0106a41086a200341c8086a41086a290300370300200320032903c8083703b01041fafdc600ad4280808080800184221b10012202290000211c2002290008211d2002103541e8adc400ad4280808080a00184221f10012202290000211e2002290008212020021035200320203703b00b2003201e3703a80b2003201d3703a00b2003201c3703980b200341c8086a200341980b6a10dc0220032802c8082205410820051b2102410121074183b02421010240200420032902cc08420020051b221d422088a722054f0d00200220044106746a2208450d0020082903004201520d000240200220044106746a220841206a2204200341b0106a460d002004200341b0106a412010a0080d010b200841086a2201201a3703002001200637030841002107200521010b201b1001220429000021062004290008211a20041035201f10012204290000211b2004290008211c200410352003201c3703b00b2003201b3703a80b2003201a3703a00b200320063703980b0240024020020d00200341980b6aad428080808080048410070c010b200341c8086a2002200510b404200341980b6aad428080808080048420033502d00842208620032802c8082204ad841002024020032802cc08450d00200410350b201d42ffffff1f83500d00200210350b2007450d010b20004200370308200041186a20013602002000411c6a41f1b8c300ad4280808080c00184370200200042013703000c150b20004201370308200041106a2001ad42b09f1a7e4280dbf23f7c370300200042003703000c140b410221040240024020022d00000d004101210520022d00014101470d00200141196a290000211d200141186a2d00002118200141176a2d00002119200141156a2f00002121200141146a2d00002122200141136a2d00002123200141116a2f00002124200141106a2d000021252001410f6a2d000021262001410d6a2f000021272001410c6a2d000021282001410b6a2d00002129200141096a2f0000212a200141086a2d0000212b200141076a2d0000212c200141056a2f0000212d200141046a2d0000212e200141036a2d0000212f200141246a280200210820012f00012130200241196a2d00002101200241186a2d00002104200241166a2f01002107200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720032002411a6a2901003703c810200320013a00c710200320043a00c610200320073b01c410200320093a00c3102003200a3a00c2102003200b3b01c0102003200c3a00bf102003200d3a00be102003200e3b01bc102003200f3a00bb10200320103a00ba10200320113b01b810200320123a00b710200320133a00b610200320143b01b410200320153a00b310200320163a00b210200320173b01b010200341980b6a41186a22094200370300200341980b6a41106a220a4200370300200341980b6a41086a22024200370300200342003703980b41fafdc600ad4280808080800184220610012201290000211a2002200141086a2900003703002003201a3703980b2001103541e8adc400ad4280808080a00184221a10012201290008211b2001290000211c20011035200341c8086a41106a220b201c370300200341c8086a41186a220c201b370300200341c8086a41086a220d2002290300370300200320032903980b3703c808200341980b6a200341c8086a10dc0220032802980b2207410820071b21014183b024210402402008200329029c0b420020071b221b422088a7220e4f0d00200120084106746a2207450d0020072903004201520d002003201d3703e008200320183a00df08200320193a00de08200320213b01dc08200320223a00db08200320233a00da08200320243b01d808200320253a00d708200320263a00d608200320273b01d408200320283a00d308200320293a00d2082003202a3b01d0082003202b3a00cf082003202c3a00ce082003202d3b01cc082003202e3a00cb082003202f3a00ca08200320303b01c8082003201d3703b00b200320183a00af0b200320193a00ae0b200320213b01ac0b200320223a00ab0b200320233a00aa0b200320243b01a80b200320253a00a70b200320263a00a60b200320273b01a40b200320283a00a30b200320293a00a20b2003202a3b01a00b2003202b3a009f0b2003202c3a009e0b2003202d3b019c0b2003202e3a009b0b2003202f3a009a0b200320303b01980b0240200341b0106a200120084106746a41206a2207460d002007200341b0106a412010a0080d010b200720032903980b370200200741186a200341980b6a41186a290300370200200741106a200341980b6a41106a290300370200200741086a200341980b6a41086a29030037020041002105200e21040b20094200370300200a420037030020024200370300200342003703980b20061001220729000021062002200741086a290000370300200320063703980b20071035201a1001220729000821062007290000211a20071035200b201a370300200c2006370300200d2002290300370300200320032903980b3703c8080240024020010d00200341c8086aad428080808080048410070c010b200341980b6a2001200e10b404200341c8086aad428080808080048420033502a00b42208620032802980b2202ad8410020240200328029c0b450d00200210350b201b42ffffff1f83500d00200110350b2005450d010b20004200370308200041186a20043602002000411c6a41f1b8c300ad4280808080c00184370200200042013703000c140b20004201370308200041106a2004ad42c0ed1a7e42e0ecb5c0007c370300200042003703000c130b200141086a2903002106200141046a280200210420032002411a6a2901003703e008410221012003200241026a2901003703c80820032002410a6a2901003703d0082003200241126a2901003703d8080240024020022d00014101470d0020022d000041ff01710d00200341b0106a41186a200341c8086a41186a290300370300200341b0106a41106a200341c8086a41106a290300370300200341b0106a41086a200341c8086a41086a290300370300200320032903c8083703b01041fafdc600ad4280808080800184221a10012202290000211b2002290008211c2002103541e8adc400ad4280808080a00184221d10012202290000211f2002290008211e200210352003201e3702b00b2003201f3702a80b2003201c3702a00b2003201b3702980b200341c8086a200341980b6a10dc0220032802c8082205410820051b2102410121074183b02421010240200420032902cc08420020051b221f422088a722054f0d00200220044106746a2208450d0020082903004201520d000240200220044106746a220841206a2204200341b0106a460d002004200341b0106a412010a0080d010b2008200637031841002107200521010b201a1001220429000021062004290008211a20041035201d10012204290000211b2004290008211c200410352003201c3702b00b2003201b3702a80b2003201a3702a00b200320063702980b0240024020020d00200341980b6aad428080808080048410070c010b200341c8086a2002200510b404200341980b6aad428080808080048420033502d00842208620032802c8082204ad841002024020032802cc08450d00200410350b201f42ffffff1f83500d00200210350b2007450d010b20004200370308200041186a20013602002000411c6a41f1b8c300ad4280808080c00184370200200042013703000c130b20004201370308200041106a2001ad42a0d1197e4280dbf23f7c370300200042003703000c120b200141c0006a290300211a200141386a290300211b200141306a2903002106200141046a2802002107200341880e6a41206a200141286a280200360200200341880e6a41186a200141206a290200370300200341880e6a41106a200141186a290200370300200341880e6a41086a200141106a2902003703002003200141086a2902003703880e4102210120022d00000d0a20022d00014101470d0a200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703900b200320013a008f0b200320043a008e0b200320053b018c0b200320083a008b0b200320093a008a0b2003200a3b01880b2003200b3a00870b2003200c3a00860b2003200d3b01840b2003200e3a00830b2003200f3a00820b200320103b01800b200320113a00ff0a200320123a00fe0a200320133b01fc0a200320143a00fb0a200320153a00fa0a200320163b01f80a200341b0106a41206a200341880e6a41206a280200360200200341b0106a41186a200341880e6a41186a29030037030041102102200341b0106a41106a200341880e6a41106a29030037030041082104200341b0106a41086a200341880e6a41086a290300370300200320032903880e3703b010200341980b6a200341b0106a108b02200341c8086a41086a2201200341a10b6a290000370300200341c8086a41106a2205200341a90b6a290000370300200341c8086a41186a2208200341b10b6a290000370300200320032900990b3703c80820032d00980b4101460d09200341c0006a41186a2008290300370300200341c0006a41106a2005290300370300200341c0006a41086a2001290300370300200320032903c8083703404103210141fdb8c300210520064201510d0b41fafdc600ad428080808080018410012202290000211c2002290008211d2002103541e8adc400ad4280808080a0018410012202290000211f2002290008211e200210352003201e3702b00b2003201f3702a80b2003201d3702a00b2003201c3702980b200341b0106a200341980b6a10dc0220032802b0102202410820021b2108024002400240024002400240200720032902b410420020021b221c422088a74f0d00200820074106746a2202450d0020022903004201520d000240200820074106746a41206a2202200341f80a6a460d002002200341f80a6a412010a0080d010b0240201c42ffffff1f83500d00200810350b200341e80d6a200341c0006a10b504200341b0106a20032802e80d220220032802f00d10d402200341d0036a200341b0106a41a402109d081a200341b0036a41086a2204200341dd126a290000370300200341b0036a41106a2205200341e5126a290000370300200341b0036a41176a2208200341ec126a280000360000200320032900d5123703b003024020032d00d41222094102460d0020034188016a200341d0036a41a402109d081a200341e8006a41176a2008280000360000200341e8006a41106a2005290300370300200341e8006a41086a2004290300370300200320032903b003370368024020032802ec0d450d00200210350b200341c8086a41066a20034188016a41a402109d081a20034198066a200341c8086a41aa02109d081a200341f8056a41176a2202200341e8006a41176a280000360000200341f8056a41106a2201200341e8006a41106a290300370300200341f8056a41086a2204200341e8006a41086a290300370300200320032903683703f805200341980b6a20034198066a41066a41a402109d081a200341980b6a41a4026a20093a0000200341bd0d6a20032903f805370000200341c50d6a2004290300370000200341cd0d6a2001290300370000200341d40d6a200228000036000020032802a80b210841002102200341b00b6a280200220941014b0d0220090e020403040b024020032802ec0d450d00200210350b410a210441e4b8c3002105410d21020c110b4109210441f1b8c3002105410c2102201c42ffffff1f83500d10200810350c100b20092101034020022001410176220420026a2205200820054105746a28020020074b1b2102200120046b220141014b0d000b0b200820024105746a220128020022042007460d012009200220042007496a2202490d0a0b02402009200341ac0b6a280200470d00200341980b6a41106a2009410110a10120032802a80b21080b200820024105746a220141206a2001200920026b410574109e081a200141186a201a370300200141106a201b37030020012006370308200120073602002003200941016a22093602b00b0c010b200920024d0d09200820024105746a220241086a2104024020022903084201520d00200341b0106a200341c0006a200341f80a6a200241106a290300200241186a290300410010ef020b2004200637030020012007360200200241186a201a370300200241106a201b3703000b200341bc0b6a3502002106200341b0106a200341980b6a41c002109d081a200341c8086a200341c0006a10b50420032802c8082102200320032802d00836029c062003200236029806200341b0106a20034198066a10b004024020032802cc08450d00200210350b2009ad211a0240200341c4106a28020041ffffff3f71450d0020032802c01010350b200341cc106a10a304200341b0106a41086a41053a0000200341b9106a2003290340370000200341c9106a200341c0006a41106a290300370000200341d1106a200341d8006a290300370000200341dc106a2007360200200341c0006a41086a290300211b200341113a00b010200341b0106a41116a201b37000041b0b4cc004100200341b0106a10d401200041106a201a4280b5187e200642a0e1e7007e7c42c0fff1de007c37030020004201370308200042003703000c110b200341e0006a200141246a280200360200200341d8006a2001411c6a290200370300200341c0006a41106a200141146a290200370300200341c8006a2001410c6a2902003703002003200141046a29020037034041022101200241036a2d0000210520022f000121070240024002400240024002400240024020022d00002208417f6a220441024b0d00024020040e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200720054110747220084100477241ff01710d010b200341b0106a41206a200341c0006a41206a280200360200200341b0106a41186a200341c0006a41186a290300370300200341b0106a41106a200341c0006a41106a290300370300200341b0106a41086a200341c0006a41086a290300370300200320032903403703b010200341980b6a200341b0106a108b0241012105024020032d00980b4101460d00200341980b6a41086a2d00002102200341a10b6a2f00002101200341a30b6a2d00002104200341a40b6a2d00002107200341a50b6a2f00002108200341a70b6a2d00002109200341980b6a41106a2d0000210a200341a90b6a2f0000210b200341ab0b6a2d0000210c200341ac0b6a2d0000210d200341ad0b6a2f0000210e200341af0b6a2d0000210f200341980b6a41186a2d0000211020032f00990b211120032d009b0b211220032d009c0b211320032f009d0b211420032d009f0b21152003200341b10b6a2900003703900b200320103a008f0b2003200f3a008e0b2003200e3b018c0b2003200d3a008b0b2003200c3a008a0b2003200b3b01880b2003200a3a00870b200320093a00860b200320083b01840b200320073a00830b200320043a00820b200320013b01800b200320023a00ff0a200320153a00fe0a200320143b01fc0a200320133a00fb0a200320123a00fa0a200320113b01f80a200341980b6a200341f80a6a10b604200341b0106a20032802980b220220032802a00b220110cc020240024020032802c01022040d004200211b4200211c4200211d0c010b2001ad4220862002ad841007200341b8106a290300211d20032903b010211c20032902c410211b200421050b0240200328029c0b450d00200210350b200341d80d6a200341f80a6a10b504200341b0106a20032802d80d220220032802e00d220410d402024020032d00d412220941024622010d002004ad4220862002ad8410070b200341880e6a200341b0106a41a402109d081a200341e80d6a41176a2204200341ec126a280000360000200341e80d6a41106a2207200341e5126a290000370300200341e80d6a41086a2208200341dd126a290000370300200320032900d5123703e80d200341d0036a200341880e6a41a402109d081a200341b0036a41176a220a2004280000360000200341b0036a41106a22042007290300370300200341b0036a41086a22072008290300370300200320032903e80d3703b003024020010d0020034188016a200341d0036a41a402109d081a200341e8006a41176a200a280000360000200341e8006a41106a2004290300370300200341e8006a41086a2007290300370300200320032903b003370368024020032802dc0d450d00200210350b200341c8086a41066a20034188016a41a402109d081a20034198066a200341c8086a41aa02109d081a200341f8056a41176a2202200341e8006a41176a280000360000200341f8056a41106a2201200341e8006a41106a290300370300200341f8056a41086a2204200341e8006a41086a290300370300200320032903683703f805200341980b6a20034198066a41066a41a402109d081a200341980b6a41a4026a20093a0000200341bd0d6a20032903f805370000200341c50d6a2004290300370000200341cd0d6a2001290300370000200341d40d6a2002280000360000200341980b6a41086a290300211e20032903980b211f20032802a80b210702400240200341b00b6a280200220841057422010d00420021064200211a0c010b200741106a2102420021064200211a0340200241086a2903004200200241786a29030042015122041b201a7c2002290300420020041b221a20067c2206201a54ad7c211a200241206a2102200141606a22010d000b0b201e201d7c201f201c7c221c201f54ad7c201a7c201c20067c2206201c54ad7c211a0240201b422088221ca72202450d0020024105742101200521020340200341b0106a200210970420033502b81042208620032802b0102204ad841007024020032802b410450d00200410350b200241206a2102200141606a22010d000b0b20032006370398062003201a3703a0062006201a844200520d03200342003703d008200342003703c8080c040b024020032802dc0d450d00200210350b0240201b42ffffff3f83500d00200510350b410321010c010b410121010b20004198043b001920004200370308200041206a41083602002000411c6a41c8b9c300360200200041186a20013a0000420121060c040b2003200341f80a6a3602880e200341c8086a200341f80a6a20034198066a200341880e6a10a802200341e8086a290300211d20032903e008211f024020032903c8084201520d0020032903d008211e200341e8106a200341c8086a41106a290300370300200341e0106a201e370300200341b0106a41086a41003a0000200341b9106a20032903f80a370000200341c1106a200341f80a6a41086a290300370000200341c9106a200341f80a6a41106a290300370000200341d1106a200341900b6a290300370000200341033a00b01041b0b4cc004100200341b0106a10d4010b2003201f3703c8082003201d3703d008201f201d844200520d010b20034198066a41186a220a420037030020034198066a41106a2204420037030020034198066a41086a22014200370300200342003703980641b6fdc600ad4280808080800184221d10012209290000211f200341b0106a41086a2202200941086a2900003703002003201f3703b0102009103520012002290300370300200320032903b0103703980641e489c200ad4280808080d00184221f10012209290000211e2002200941086a2900003703002003201e3703b01020091035200420032903b010221e370300200341880e6a41086a220b2001290300370300200341880e6a41106a220c201e370300200341880e6a41186a220d200229030037030020032003290398063703880e200341286a200341880e6a412010d701200341286a41106a290300211e2003290330212020032802282109200a420037030020044200370300200142003703002003420037039806201d1001220a290000211d2002200a41086a2900003703002003201d3703b010200a103520012002290300370300200320032903b01037039806201f1001220a290000211d2002200a41086a2900003703002003201d3703b010200a1035200420032903b010221d370300200b2001290300370300200c201d370300200d200229030037030020032003290398063703880e2003201e420020091b3703b81020032020420020091b3703b010200341880e6aad4280808080800484200341b0106aad428080808080028410020c010b200342f0f2bda1a7ee9cb9f9003703c808200341b0106a200341c8086a10e001200341b0106a201f201d10df01200341c8106a201d370300200341c0106a201f370300200341b8106a41063a00002003410c3a00b01041b0b4cc004100200341b0106a10d4010b200341e8106a201a370300200341e0106a2006370300200341b0106a41086a41023a0000200341b9106a20032903f80a370000200341f80a6a41086a2903002106200341113a00b010200341b0106a41116a2006370000200341c9106a200341880b6a290300370000200341d1106a200341900b6a29030037000041b0b4cc004100200341b0106a10d401201c42c0d89e017e2008ad42a08d067e7c201c4280c2d72f7e7c200341bc0b6a35020042a0f7367e7c2106200341b40b6a21020240200341ac0b6a28020041ffffff3f71450d00200710350b200642c086a2e7017c2106200210a3040240201b42ffffff3f83500d00200510350b200041106a200637030020004201370308420021060b200020063703000c100b2005200841f485cc001042000b103c000b103e000b2002200a104d000b2002200a41a0bdc4001042000b20022009104e000b20022009104d000b2002200941b0bdc4001042000b410121010b0b200041206a20023602002000411c6a2005360200200020043a001a200041183a0019200041186a20013a000020004200370308200042013703000c050b0240200341ac0b6a28020041ffffff3f71450d00200910350b200341b40b6a10a3040b201c42ffffff1f83500d00200710350b200020023b00192000200637021c200042003703082000411b6a20024110763a0000200041186a20043a0000200042013703000c020b0b02402007450d00200741c4006c2101200841286a210203400240200241786a2d00004101470d002002280200450d002002417c6a28020010350b200241c4006a2102200141bc7f6a22010d000b0b02402005450d00200541c4006c450d00200810350b200020043b00192000200637021c200042003703082000411b6a20044110763a0000200041186a20093a0000200042013703000b200341f0126a24000b950202037f017e230041206b220324000240024020024106744104722204417f4c0d00200410332205450d0120034100360208200320043602042003200536020020022003107702402002450d002002410674210203400240024020012903004201510d00200341003a00102003200341106a410110780c010b200341013a00102003200341106a410110782003200141206a41201078200141086a29030021062003200141106a290300370318200320063703102003200341106a411010782003200141186a2903003703102003200341106a410810780b200141c0006a2101200241406a22020d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1044000b1045000bb10503027f017e047f230041d0006b2202240041fafdc600ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541c8acc400ad4280808080a00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041fafdc600ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541b8adc400ad4280808080e00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b13002000410d360204200041c0bdc4003602000b1f0002402000280200450d00200041086a280200450d00200028020410350b0b8c0a03047f017e047f23004190016b22022400200241d8006a41186a4200370300200241d8006a41106a22034200370300200241d8006a41086a220442003703002002420037035841a3edcb00ad4280808080f000841001220529000021062004200541086a290000370300200220063703582005103541a5ebcb00ad4280808080c00184100122052900002106200241f8006a41086a2207200541086a2900003703002002200637037820051035200320022903782206370300200241386a41086a2004290300370300200241386a41106a2006370300200241386a41186a200729030037030020022002290358370338200241106a200241386a412010c001200241d8006a2002280214410020022802101b2203200010ba04200241086a20022802582204200228026041b0b4cc0041004100108a02200228020821050240200228025c450d00200410350b410121040240024002400240024020054101460d004188e8cb00ad4280808080800184100122042900002106200241f8006a41086a200441086a290000370300200220063703782004103541f1c8c400ad4280808080e00184100122042900002106200241386a41086a200441086a2900003703002002200637033820041035200220033602282002200241286aad4280808080c00084100322042900003703880120041035200241e4006a22052002412c6a360200200220024188016a41086a220036025c2002200241286a360260200220024188016a360258200241186a200241d8006a107b412010332204450d0120042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020022004ad42808080808004841003220129000037038801200110352005200441206a360200200220043602602002200036025c200220024188016a360258200241286a200241d8006a107b200410352002280220220741206a2200200228023022086a2201417f4c0d02200228022821092002280218210a0240024020010d0041002103410121040c010b200110332204450d02200121030b024002402003410f4d0d00200321050c010b200341017422054110200541104b1b22054100480d04024020030d002005103322040d010c060b20032005460d0020042003200510372204450d050b20042002290378370000200441086a200241f8006a41086a2903003700000240024020054170714110460d00200521030c010b200541017422034120200341204b1b22034100480d0420052003460d0020042005200310372204450d050b20042002290338370010200441186a200241386a41086a29030037000002400240200341606a2007490d00200321050c010b2007415f4b0d04200341017422052000200520004b1b22054100480d0420032005460d0020042003200510372204450d050b200441206a200a2007109d081a02400240200520006b2008490d00200521030c010b20012000490d04200541017422032001200320014b1b22034100480d04024020050d00024020030d00410121040c020b200310332204450d060c010b20052003460d0020042005200310372204450d050b200420006a20092008109d081a0240200228022c450d00200910350b0240200228021c450d00200a10350b20022004200110c001200228020421012002280200210502402003450d00200410350b200141004720054100477121040b20024190016a240020040f0b1045000b1044000b103e000b103c000bf60603027f017e077f230041e0006b220324004188e8cb00ad4280808080800184100122042900002105200341086a41086a200441086a29000037030020032005370308200410354190e8cb00ad4280808080a00284100122042900002105200341186a41086a200441086a2900003703002003200537031820041035200320013602382003200341386aad4280808080c000841003220429000037034820041035200341dc006a2204200341386a41046a3602002003200341c8006a41086a22013602542003200341386a3602582003200341c8006a360250200341286a200341d0006a107b200320023602442003200341c4006aad4280808080c0008410032202290000370348200210352004200341c4006a41046a360200200320013602542003200341c4006a3602582003200341c8006a360250200341386a200341d0006a107b02400240024002402003280230220641206a2207200328024022086a2202417f4c0d00200328023821092003280228210a0240024020020d004100210b410121040c010b200210332204450d022002210b0b02400240200b410f4d0d00200b21010c010b200b41017422014110200141104b1b22014100480d030240200b0d002001103322040d010c050b200b2001460d002004200b200110372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020014170714110460d002001210b0c010b2001410174220b4120200b41204b1b220b4100480d032001200b460d0020042001200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2006490d00200b21010c010b200641206a22012006490d03200b410174220c2001200c20014b1b22014100480d03200b2001460d002004200b200110372204450d040b200441206a200a2006109d081a02400240200120076b2008490d002001210b0c010b20022007490d032001410174220b2002200b20024b1b220b4100480d03024020010d000240200b0d00410121040c020b200b10332204450d050c010b2001200b460d0020042001200b10372204450d040b200420076a20092008109d081a200020023602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1044000b1045000b103e000b103c000bae0707017f017e067f017e047f017e027f230041306b220124000240024010292202422088a722030d00410121040c010b2002a721040b2001200336022420012004360220024002400240024002402003450d0020042d0000210520012003417f6a3602242001200441016a360220200541014b0d00024020050e020004000b200141186a200141206a10c40120012802180d0020012802242206200128021c2205490d002005417f4c0d020240024020050d0042002102410121070c010b200510392207450d022007200128022022082005109d081a2001200620056b3602242001200820056a3602202005ad21020b2007450d00200141106a200141206a10c4012005ad4220862002842209a7210a024020012802100d002001280214220b2001280224410c6e22052005200b4b1bad420c7e2202422088a70d032002a72205417f4c0d030240024020050d004104210c0c010b20051033220c450d030b2005410c6ead21020240200b450d000340200141086a200141206a10c40102400240024020012802080d0020012802242206200128020c2205490d002005417f4c0d080240024020050d004100210d410121080c010b200510392208450d0820082001280220220d2005109d081a2001200620056b3602242001200d20056a3602202005210d0b2002422088220ea722062002a7470d02024002400240200641016a220f2006490d00200ea74101742210200f200f2010491bad420c7e220e422088a70d00200ea7220f4100480d00024020060d00200f0d024104210c0c050b2006410c6c2206200f460d04024020060d00200f0d024104210c0c050b200c2006200f1037220c450d020c040b103e000b200f1033220c0d020b103c000b02402002422088a72205450d002005410c6c2106200c210503400240200541046a280200450d00200528020010350b2005410c6a2105200641746a22060d000b0b2002a72205450d042005410c6c450d04200c10350c040b2002422088220ea72106200f410c6ead21020b200c2006410c6c6a22062005ad422086200dad8437020420062008360200200e422086200242ffffffff0f83844280808080107c2102200b417f6a220b0d000b0b200c450d002007450d012009422088a721050c050b200a450d00200710350b41b89acc00412e200141286a41c09bcc0041e89acc001046000b1045000b1044000b410021070b2000200a36020420002007360200200041106a20023702002000410c6a200c360200200041086a200536020002402003450d00200410350b200141306a24000b970403017f017e017f23004190016b22052400200520013602040240200541046a20022004ad4220862003ad8410322206422088a72201450d002006a722072d0000220341014b0d004100210202400240024020030e020100010b41002102200541003a008801200741016a21042001417f6a2101034020012002460d02200541c8006a20026a200420026a2d00003a00002005200241016a22033a00880120032102200341c000470d000b200541086a41386a200541c8006a41386a290300370300200541086a41306a200541c8006a41306a290300370300200541086a41286a200541c8006a41286a290300370300200541086a41206a200541c8006a41206a290300370300200541086a41186a200541c8006a41186a290300370300200541086a41106a200541c8006a41106a290300370300200541086a41086a200541c8006a41086a29030037030020052005290348370308410121020b200020023a000020002005290308370001200041096a200541106a290300370000200041116a200541186a290300370000200041196a200541206a290300370000200041216a200541286a290300370000200041296a200541306a290300370000200041316a200541386a290300370000200041396a200541c0006a2903003700002007103520054190016a24000f0b200241ff0171450d00200541003a0088010b41b89acc00412e200541c8006a41c09bcc0041e89acc001046000bac0501077f23004190016b2202240002400240024002402000410c6a2802002203417f4c0d0020002802042104200028020021050240024020030d0041002106410121070c010b200310332207450d02200321060b0240024020062003490d00200621080c010b200641017422082003200820034b1b22084100480d03024020060d002008103322070d010c050b20062008460d0020072006200810372207450d040b200720042003109d082106200241f8006a200041106a10a603200241106a410c6a2003360200200241106a41086a22032008360200200241206a2002290378370300200241286a2208200241f8006a41086a280200360200200241106a41306a200041306a290200370300200241106a41386a200041386a290200370300200241106a41c0006a200041c0006a290200370300200241106a41c8006a200041c8006a290200370300200241106a41d0006a200041d0006a290200370300200241106a41d8006a200041d8006a290200370300200241106a41e0006a200041e0006a2902003703002002200636021420022005360210200220002802243602342002200029021c37022c200220002902283703382002410c6a4110360200200241fcc7c400360200200241043602042001411c6a28020021002002200241106a360208200128021821062002418c016a41023602002002420237027c20024190cec400360278200220023602880120062000200241f8006a1043210602402003280200450d00200228021410350b024020082802002203450d00200228022021002003410c6c210303400240200041046a280200450d00200028020010350b2000410c6a2100200341746a22030d000b0b0240200241246a2802002200450d002000410c6c450d00200228022010350b20024190016a240020060f0b1044000b1045000b103e000b103c000b980201027f230041206b220224002002200128021841b0b4cc0041002001411c6a28020028020c1100003a00102002200136020841012101200241013a00112002410036020c200220003602182002200041286a36021c200241086a200241186a41a0cec400106f2002411c6a41b0cec400106f1a20022d0010210002400240200228020c22030d00200021010c010b0240200041ff01710d00024020034101470d0020022d001141ff0171450d00200228020822002d00004104710d0041012101200028021841d6a0c00041012000411c6a28020028020c1100000d010b2002280208220128021841cca6cc0041012001411c6a28020028020c11000021010b200220013a00100b200241206a2400200141ff01714100470b1c00200128021841ed9dcc00410f2001411c6a28020028020c1100000bed93010a047f017e017f017e077f017e1f7f057e047f017e230041b0066b22002400200041a0056a41186a22014200370300200041a0056a41106a22024200370300200041a0056a41086a22034200370300200042003703a00541a3edcb00ad4280808080f0008422041001220529000021062003200541086a290000370300200020063703a0052005103541a5ebcb00ad4280808080c0018410012205290000210620004180046a41086a2207200541086a29000037030020002006370380042005103520022000290380042206370300200041d0046a41086a22082003290300370300200041d0046a41106a22092006370300200041d0046a41186a220a2007290300370300200020002903a0053703d004200041206a200041d0046a412010c0012000280224210b2000280220210c200142003703002002420037030020034200370300200042003703a0054188e8cb00ad42808080808001841001220529000021062003200541086a290000370300200020063703a00520051035418fd1cb00ad4280808080c000841001220529000021062007200541086a290000370300200020063703800420051035200220002903800422063703002008200329030037030020092006370300200a2007290300370300200020002903a0053703d004200041a0056a200041d0046a10d80220002802a005210d20002902a405210e200142003703002002420037030020034200370300200042003703a00520041001220529000021042003200541086a290000370300200020043703a0052005103541f393ca00ad4280808080a001841001220529000021042007200541086a290000370300200020043703800420051035200220002903800422043703002008200329030037030020092004370300200a2007290300370300200020002903a0053703d004200041a0056a200041d0046a10fe0120002802a0052205410120051b210f20002902a405420020051b2204a72110024002400240024002400240024002402004422088a72205450d00200f200541057422116a211220004194016a2113200041d0046a41206a211420004198036a4104722115200041e0026a41047221164102210541002117034020004180026a41186a200f20176a221841186a221929000037030020004180026a41106a201841106a221a29000037030020004180026a41086a201841086a221b290000370300200020182900003703800220162018290000370000201641086a201b290000370000201641106a201a290000370000201641186a201929000037000020002005417e6a221a3602e002410021190240201a201610b9040d0020004198036a41206a200041e0026a41206a28020036020020004198036a41186a200041e0026a41186a29030037030020004198036a41106a200041e0026a41106a29030037030020004198036a41086a200041e0026a41086a290300370300200020002903e00237039803200041a0026a41186a2219201541186a221a290000370300200041a0026a41106a221b201541106a221c290000370300200041a0026a41086a221d201541086a221e290000370300200020152900003703a002200a201a2900003703002009201c2900003703002008201e290000370300200020152900003703d004200041f0006a200041d0046a108402200041c0026a41186a221a2019290300370300200041c0026a41106a221c201b290300370300200041c0026a41086a221b201d290300370300200020002903a0023703c0022000280290012219450d0020142000290370370300201441186a200041f0006a41186a290300370300201441106a200041f0006a41106a290300370300201441086a200041f0006a41086a290300370300200a201a2903003703002009201c2903003703002008201b290300370300200041a0066a41086a221a201341086a280200360200200020002903c0023703d004200020132902003703a006200041a0056a41386a221b200041d0046a41386a290300370300200041a0056a41306a221c200041d0046a41306a290300370300200041a0056a41286a221d200041d0046a41286a290300370300200041a0056a41206a221e20142903003703002001200a2903003703002002200929030037030020032008290300370300200020002903d0043703a00520004180046a41386a201b29030037030020004180046a41306a201c29030037030020004180046a41286a201d29030037030020004180046a41206a201e29030037030020004180046a41186a200129030037030020004180046a41106a200229030037030020072003290300370300200020002903a00537038004200041386a41086a201a280200360200200020002903a0063703380b200041c0036a41086a2007290300370300200041c0036a41106a20004180046a41106a290300370300200041c0036a41186a20004180046a41186a290300370300200041c0036a41206a20004180046a41206a290300370300200041c0036a41286a20004180046a41286a290300370300200041c0036a41306a20004180046a41306a290300370300200041c0036a41386a20004180046a41386a29030037030020004188036a41086a200041386a41086a28020036020020002000290380043703c003200020002903383703880320190d02200541016a21052011201741206a2217470d000b0b2000410036023020004208370328201041ffffff3f71450d01200f10350c010b200041b0016a41386a2216200041c0036a41386a290300370300200041b0016a41306a2215200041c0036a41306a290300370300200041b0016a41286a221a200041c0036a41286a290300370300200041b0016a41206a221b200041c0036a41206a290300370300200041b0016a41186a2207200041c0036a41186a290300370300200041b0016a41106a2203200041c0036a41106a290300370300200041b0016a41086a2208200041c0036a41086a290300370300200041f0016a41086a220920004188036a41086a280200360200200020002903c0033703b00120002000290388033703f001200041e0006a41086a220a2009280200360200200020002903f001370360200041a0056a41086a22092008290300370300200041a0056a41106a22082003290300370300200041a0056a41186a22032007290300370300200041a0056a41206a221c201b290300370300200041a0056a41286a221b201a290300370300200041a0056a41306a221a2015290300370300200041a0056a41386a22152016290300370300200020002903b0013703a005200041d0046a41086a2216200a280200360200200020002903603703d00441d00010332207450d01200720002903a00537030020072019360240200720002903d004370244200741386a2015290300370300200741306a201a290300370300200741286a201b290300370300200741206a201c290300370300200741186a2003290300370300200741106a2008290300370300200741086a2009290300370300200741cc006a20162802003602002000428180808010370254200020073602500240201141606a2017460d00201841206a2116201120176b41606a211b200041d4016a211c20004198036a4104722115200041e0026a4104722118034020004180026a41186a201641186a221729000037030020004180026a41106a201641106a221929000037030020004180026a41086a201641086a221a290000370300200020162900003703800220162900002104201841186a201729000037000020182004370000201841086a201a290000370000201841106a201929000037000020002005417f6a22193602e0024100211702402019201810b9040d0020004198036a41206a200041e0026a41206a28020036020020004198036a41186a200041e0026a41186a29030037030020004198036a41106a200041e0026a41106a29030037030020004198036a41086a200041e0026a41086a290300370300200020002903e00237039803200041a0026a41186a2217201541186a221a290000370300200041a0026a41106a2208201541106a2203290000370300200041a0026a41086a2209201541086a220a290000370300200020152900003703a002200041d0046a41186a2219201a290000370300200041d0046a41106a221a2003290000370300200041d0046a41086a2203200a290000370300200020152900003703d004200041b0016a200041d0046a108402200041c0026a41186a220a2017290300370300200041c0026a41106a22112008290300370300200041c0026a41086a22082009290300370300200020002903a0023703c00220002802d0012217450d00201420002903b001370300201441186a200041b0016a41186a290300370300201441106a200041b0016a41106a290300370300201441086a200041b0016a41086a2903003703002019200a290300370300201a201129030037030020032008290300370300200041a0066a41086a2208201c41086a280200360200200020002903c0023703d0042000201c2902003703a006200041a0056a41386a2209200041d0046a41386a290300370300200041a0056a41306a220a200041d0046a41306a290300370300200041a0056a41286a2211200041d0046a41286a290300370300200041a0056a41206a221d200041d0046a41206a290300370300200041a0056a41186a221e2019290300370300200041a0056a41106a2219201a290300370300200041a0056a41086a221a2003290300370300200020002903d0043703a00520004180046a41386a200929030037030020004180046a41306a200a29030037030020004180046a41286a201129030037030020004180046a41206a201d29030037030020004180046a41186a201e29030037030020004180046a41106a201929030037030020004180046a41086a201a290300370300200020002903a00537038004200041386a41086a2008280200360200200020002903a0063703380b200041c0036a41086a20004180046a41086a290300370300200041c0036a41106a20004180046a41106a290300370300200041c0036a41186a20004180046a41186a290300370300200041c0036a41206a20004180046a41206a290300370300200041c0036a41286a20004180046a41286a290300370300200041c0036a41306a20004180046a41306a290300370300200041c0036a41386a20004180046a41386a29030037030020004188036a41086a200041386a41086a28020036020020002000290380043703c0032000200029033837038803024020170d00201641206a2116200541016a2105201b41606a221b0d010c020b0b200041f0006a41386a221f200041c0036a41386a2203290300370300200041f0006a41306a2220200041c0036a41306a2208290300370300200041f0006a41286a2221200041c0036a41286a2209290300370300200041f0006a41206a2222200041c0036a41206a220a290300370300200041f0006a41186a2223200041c0036a41186a2211290300370300200041f0006a41106a2224200041c0036a41106a221c290300370300200041f0006a41086a2225200041c0036a41086a221d290300370300200041f0016a41086a222620004188036a41086a221e280200360200200020002903c00337037020002000290388033703f001200041e0006a41086a22272026280200360200200020002903f001370360201641206a2116200041d4016a212820004198036a4104722115200041e0026a410472211841012119410121290340200041b0016a41086a222a2025290300370300200041b0016a41106a222b2024290300370300200041b0016a41186a222c2023290300370300200041b0016a41206a221a2022290300370300200041b0016a41286a221b2021290300370300200041b0016a41306a22012020290300370300200041b0016a41386a2213201f290300370300200020002903703703b001200041a0056a41086a222d2027280200360200200020002903603703a005024020292019470d00200041d0006a2019410110a301200028025021070b2007202941d0006c6a221920002903b001370300202b2903002104202c2903002106201a290300212e201b290300212f2001290300213020132903002131202a290300213220192017360240201941086a2032370300201920002903a005370244201941cc006a202d280200360200201941386a2031370300201941306a2030370300201941286a202f370300201941206a202e370300201941186a2006370300201941106a20043703002000202941016a222936025820162012460d01034020004180026a41186a201641186a221729000037030020004180026a41106a201641106a221929000037030020004180026a41086a201641086a221a2900003703002000201629000037038002200020053602e002201a2900002104201929000021062016290000212e201841186a2017290000370000201841106a2006370000201841086a20043700002018202e3700004100211702402005201810b9040d0020004198036a41206a200041e0026a41206a28020036020020004198036a41186a200041e0026a41186a29030037030020004198036a41106a200041e0026a41106a29030037030020004198036a41086a200041e0026a41086a290300370300200020002903e00237039803200041a0026a41186a2217201541186a221a290000370300200041a0026a41106a2201201541106a221b290000370300200041a0026a41086a2213201541086a2233290000370300200020152900003703a002200041d0046a41186a2219201a290000370300200041d0046a41106a221a201b290000370300200041d0046a41086a221b2033290000370300200020152900003703d004200041b0016a200041d0046a108402200041c0026a41186a22332017290300370300200041c0026a41106a22342001290300370300200041c0026a41086a22012013290300370300200020002903a0023703c00220002802d0012217450d00201420002903b001370300201441186a202c290300370300201441106a202b290300370300201441086a202a29030037030020192033290300370300201a2034290300370300201b2001290300370300200041a0066a41086a2201202841086a280200360200200020002903c0023703d004200020282902003703a006200041a0056a41386a2213200041d0046a41386a290300370300200041a0056a41306a2233200041d0046a41306a290300370300200041a0056a41286a2234200041d0046a41286a290300370300200041a0056a41206a2235200041d0046a41206a290300370300200041a0056a41186a22362019290300370300200041a0056a41106a2219201a290300370300202d201b290300370300200020002903d0043703a00520004180046a41386a201329030037030020004180046a41306a203329030037030020004180046a41286a203429030037030020004180046a41206a203529030037030020004180046a41186a203629030037030020004180046a41106a201929030037030020004180046a41086a202d290300370300200020002903a00537038004200041386a41086a2001280200360200200020002903a0063703380b201d20004180046a41086a290300370300201c20004180046a41106a290300370300201120004180046a41186a290300370300200a20004180046a41206a290300370300200920004180046a41286a290300370300200820004180046a41306a290300370300200320004180046a41386a290300370300201e200041386a41086a28020036020020002000290380043703c0032000200029033837038803024020170d00200541016a21052012201641206a2216470d010c030b0b201f200329030037030020202008290300370300202120092903003703002022200a290300370300202320112903003703002024201c2903003703002025201d2903003703002026201e280200360200200020002903c00337037020002000290388033703f00120272026280200360200200020002903f001370360201641206a2116200541016a2105200028025421190c000b0b0240201041ffffff3f71450d00200f10350b200041286a41086a200041d0006a41086a280200360200200020002903503703280b200041a0056a41186a22174200370300200041a0056a41106a22154200370300200041a0056a41086a22054200370300200042003703a00541a3edcb00ad4280808080f000841001221629000021042005201641086a290000370300200020043703a0052016103541a5ebcb00ad4280808080c0018410012216290000210420004180046a41086a2218201641086a2900003703002000200437038004201610352002200029038004370000200241086a2018290300370000200041d0046a41086a22162005290300370300200041d0046a41106a2015290300370300200041d0046a41186a2017290300370300200020002903a0053703d004200041186a200041d0046a412010c001200028021c2117200028021821154188e8cb00ad42808080808001841001220529000021042018200541086a2900003703002000200437038004200510354190e8cb00ad4280808080a002841001220529000021042016200541086a290000370300200020043703d004200510354100211820002017410020151b3602702000200041f0006aad22044280808080c00084100322052900003703b00120051035200041ac056a200041f4006a3602002000200041b0016a41086a22143602a4052000200041f0006a3602a8052000200041b0016a3602a005200041c0036a200041a0056a107b20002802c803221541206a2216417f4c0d0120002802c00321190240024020160d00410121050c010b201610332205450d01201621180b024002402018410f4d0d00201821170c010b201841017422174110201741104b1b22174100480d03024020180d002017103322050d010c060b20182017460d0020052018201710372205450d050b2005200029038004370000200541086a20004180046a41086a2903003700000240024020174170714110460d00201721180c010b201741017422184120201841204b1b22184100480d0320172018460d0020052017201810372205450d050b200520002903d004370010200541186a200041d0046a41086a29030037000002400240201841606a2015490d00201821170c010b2015415f4b0d03201841017422172016201720164b1b22174100480d0320182017460d0020052018201710372205450d050b200541206a20192015109d081a024020002802c403450d00201910350b2016ad4220862005ad84100802402017450d00200510350b200041a0056a41186a22174200370300200041a0056a41106a22154200370300200041a0056a41086a22054200370300200042003703a00541a3edcb00ad4280808080f000841001221629000021062005201641086a290000370300200020063703a0052016103541a5ebcb00ad4280808080c0018410012216290000210620004180046a41086a2218201641086a2900003703002000200637038004201610352002200029038004370000200241086a2018290300370000200041d0046a41086a22162005290300370300200041d0046a41106a2015290300370300200041d0046a41186a2017290300370300200020002903a0053703d004200041106a200041d0046a412010c00120002802142117200028021021154188e8cb00ad42808080808001841001220529000021062018200541086a29000037030020002006370380042005103541f1c8c400ad4280808080e001841001220529000021062016200541086a290000370300200020063703d004200510354100211820002017410020151b360270200020044280808080c00084100322052900003703b00120051035200041ac056a200041f4006a360200200020143602a4052000200041f0006a3602a8052000200041b0016a3602a005200041c0036a200041a0056a107b20002802c803221541206a2216417f4c0d0120002802c00321190240024020160d00410121050c010b201610332205450d01201621180b024002402018410f4d0d00201821170c010b201841017422174110201741104b1b22174100480d03024020180d00201710332205450d060c010b20182017460d0020052018201710372205450d050b2005200029038004370000200541086a20004180046a41086a2903003700000240024020174170714110460d00201721180c010b201741017422184120201841204b1b22184100480d0320172018460d0020052017201810372205450d050b200520002903d004370010200541186a200041d0046a41086a29030037000002400240201841606a2015490d00201821170c010b2015415f4b0d03201841017422172016201720164b1b22174100480d0320182017460d0020052018201710372205450d050b200541206a20192015109d081a024020002802c403450d00201910350b2016ad4220862005ad84100802402017450d00200510350b200e4200200d1b210e0240024002400240024002400240024002402000280230450d00200041a0056a200041286a10c104200041db046a200041a0056a41086a280200360000200020002903a0053700d304200041ac056a200041d7046a290000370000200041023a00a4052000410f3a00a005200020002900d0043700a50541b0b4cc004100200041a0056a10d401200041c8006a200041286a41086a2802003602002000200e422088a7223536023c2000200b4100200c1b221b3602382000200029032837034020004188036a200041386a41086a10c1042000280290032114200028028c0321102000280288032128410410332205450d092005201b36000020004284808080c000370284042000200536028004200041a0056a10c204200041d0046a20002802a005221620002802a80510e00220002902d404420020002802d00422051b21042005410120051b211a024020002802a405450d00201610350b200020044220883e02c4032000201a3602c003200041086a200041c0036a10c40141002115024020002802080d00200028020c220720002802c403221841246e2205200520074b1bad42247e2206422088a70d0b2006a72205417f4c0d0b0240024020050d00410421150c010b200510332215450d0b0b41002119200041003602d804200020153602d0042000200541246e22053602d4042007450d0041002119410021020240024002400340201822034104490d02200241016a2102200020002802c003221841046a3602c0032018280000210841002105200041003a00c0052003417c6a2117034020172005460d02200041a0056a20056a201820056a221641046a2d00003a00002000201641056a3602c0032000200541016a22163a00c0052016210520164120470d000b200041c0026a41186a2209200041a0056a41186a290300370300200041c0026a41106a220a200041a0056a41106a290300370300200041c0026a41086a220f200041a0056a41086a290300370300200020002903a0053703c0020240201920002802d404470d00200041d0046a20194101108d0120002802d004211520002802d80421190b201720166b21182015201941246c6a22052008360200200520002903c0023702042005410c6a200f290300370200200541146a200a2903003702002005411c6a20092903003702002000201941016a22193602d80420022007470d000b2000200320166b417c6a3602c40320002802d40421050c030b200041003602c403200541ff0171450d01200041003a00c0050c010b200020033602c4030b024020002802d4042205450d00200541246c450d00201510350b410021150b200041a0056a20004180046a10c304200041d0046a20002802a005220720002802a80510b5022019410020151b21162005410020151b211820002902d404420020002802d00422051b21062015410420151b21172005410120051b2105024020002802a405450d00200710350b200041b8036a2016360200200041b4036a2018360200200041a8036a200637030020004198036a41086a20004180046a41086a280200360200200020002903800437039803200020173602b003200020053602a40302402004a7450d00201a10350b2014450d01200041b0036a2134200041a4036a212d2028201441d0006c6a210f200041a0056a41d0006a2133200041a0056a41306a2109200041a0056a41206a210a20004180046a41306a211120004180046a41206a211c20004180046a41c4006a211d41002112202821070340200041a0056a41386a22162007220541386a2903003703002009200541306a290300370300200041a0056a41286a2218200541286a290300370300200a200541206a290300370300200041a0056a41186a2202200541186a290300370300200041a0056a41106a2203200541106a290300370300200041a0056a41086a2208200541086a290300370300200041a0066a41086a2217200541cc006a280200360200200020052903003703a0052000200541c4006a2902003703a006200541d0006a2107200541c0006a2802002205450d03200041c0036a41386a22152016290300370300200041c0036a41306a22162009290300370300200041c0036a41286a22192018290300370300200041c0036a41206a2218200a290300370300200041c0036a41186a22142002290300370300200041c0036a41106a221a2003290300370300200041c0036a41086a221e2008290300370300200041f0016a41086a22012017280200360200200020002903a0053703c003200020002903a0063703f00120004180046a41386a20152903003703002011201629030037030020004180046a41286a2019290300370300201c201829030037030020004180046a41186a2215201429030037030020004180046a41106a2219201a29030037030020004180046a41086a221a201e290300370300200020002903c00337038004200020053602c004201d20002903f001370200201d41086a2001280200360200410410332214450d0a2014201b360000411810332205450d0a200042183702a405200020053602a005200541002902f8be46370000200541086a4100290280bf46370000200041103602a8054104200041a0056a10770240024020002802a405221720002802a80522056b4104490d0020002802a0052116201721180c010b200541046a22162005490d0d201741017422182016201820164b1b22184100480d0d0240024020170d00024020180d00410121160c020b201810332216450d110c010b20002802a005211620172018460d0020162017201810372216450d100b200020183602a405200020163602a0050b201620056a20142800003600002000200541046a22173602a8050240201820176b411f4b0d00201741206a221e2017490d0d20184101742201201e2001201e4b1b221e4100480d0d0240024020180d000240201e0d00410121160c020b201e10332216450d110c010b2018201e460d0020162018201e10372216450d100b2000201e3602a405200020163602a0050b201620176a2216200029038004370000201641186a2015290300370000201641106a2019290300370000201641086a201a2903003700002000200541246a3602a8052000201c3602d004200041d0046a200041a0056a10cf01200020113602d004200041d0046a200041a0056a10cf0120002802c004210520002802c8042216200041a0056a107702402016450d00201641306c211503400240024020002802a405221720002802a80522186b4120490d0020002802a00521160c010b201841206a22162018490d0f201741017422192016201920164b1b22194100480d0f0240024020170d00024020190d00410121160c020b201910332216450d130c010b20002802a005211620172019460d0020162017201910372216450d120b200020193602a405200020163602a0050b201620186a2216200541106a290000370000201641186a200541286a290000370000201641106a200541206a290000370000201641086a200541186a2900003700002000201841206a3602a805200020053602d004200041d0046a200041a0056a10cf01200541306a2105201541506a22150d000b0b20002802a405211620003502a80542208620002802a0052218ad84100922052900002104200541086a2900002106200541106a290000212e200041b0016a41186a221e200541186a290000370300200041b0016a41106a2201202e370300200041b0016a41086a22132006370300200020043703b0012005103502402016450d00201810350b20141035200041a0056a200041b0016a10c404200020002802a005221620002802a80541b0b4cc0041004100108a0220002802002105024020002802a405450d00201610350b024002400240024020054101460d00200041d0046a20004180046a41d000109d081a2000410036027820004201370370200041f0006a41004100108a01200041e0026a41086a22052000280278360200200020002903703703e002200041a0056a200041d0046a41d000109d081a203341086a2005280200360200203320002903e002370200200041f0006a200041b0016a10c4042000350278210420002802702112200041003602d804200042013703d004412010332205450d12200041203602d404200020053602d004200520002903a005370000200541086a2008290300370000200541106a2003290300370000200541186a2002290300370000200041203602d8042000200a3602e002200041e0026a200041d0046a10cf01200020093602e002200041e0026a200041d0046a10cf0120002802e005210520002802e8052216200041d0046a107702402016450d00201641306c211503400240024020002802d404221720002802d80422186b4120490d0020002802d00421160c010b201841206a22162018490d13201741017422192016201920164b1b22194100480d130240024020170d00024020190d00410121160c020b201910332216450d170c010b20002802d004211620172019460d0020162017201910372216450d160b200020193602d404200020163602d0040b201620186a2216200541106a290000370000201641186a200541286a290000370000201641106a200541206a290000370000201641086a200541186a2900003700002000201841206a3602d804200020053602e002200041e0026a200041d0046a10cf01200541306a2105201541506a22150d000b0b20002802f005210520002802f8052216200041d0046a10770240024020160d0020002802d804211620002802d404211420002802d00421190c010b2016410574211a410020002802d80422166b211520002802d4042117034002400240201720156a4120490d0020002802d0042119201721140c010b201641206a22182016490d13201741017422192018201920184b1b22144100480d130240024020170d00024020140d00410121190c020b201410332219450d170c010b20002802d004211920172014460d0020192017201410372219450d160b200020143602d404200020193602d004201421170b201920166a22182005290000370000201841186a200541186a290000370000201841106a200541106a290000370000201841086a200541086a2900003700002000201641206a22163602d804201541606a2115200541206a2105201a41606a221a0d000b0b20044220862012ad842016ad4220862019ad84100202402014450d00201910350b02402000280274450d00201210350b024020002802e4052205450d00200541306c450d0020002802e00510350b024020002802f40541ffffff3f71450d0020002802f00510350b200041d0046a41186a2214201e290300370300200041d0046a41106a221a2001290300370300200041d0046a41086a221e2013290300370300200020002903b0013703d00420002802b003211541002105024020002802b803221941014b0d00024020190e020003000b200220142903003703002003201a2903003703002008201e290300370300200020002903d0043703a005410021050c030b20192116034020052016410176221820056a22172015201741246c6a280200201b4b1b2105201620186b221641014b0d000c020b0b20002802c4042205450d02200541306c450d0220002802c00410350c020b02402015200541246c6a2802002216201b460d0020052016201b496a21050b200220142903003703002003201a2903003703002008201e290300370300200020002903d0043703a005201920054f0d0020052019104d000b0240201920002802b403470d00203420194101108d0120002802b00321150b2015200541246c6a221641246a2016201920056b41246c109e081a2016201b360200201620002903a0053702042016410c6a2008290300370200201641146a20032903003702002016411c6a20022903003702002000201941016a3602b803200220142903003703002003201a2903003703002008201e290300370300200020002903d0043703a005024020002802ac03220520002802a803470d00202d20054101108a0120002802ac0321050b20002802a40320054105746a221620002903a005370000201641186a2002290300370000201641106a2003290300370000201641086a2008290300370000410121122000200541016a3602ac030b2007200f470d000b200f21070c020b200041013a00a4052000410f3a00a00541b0b4cc004100200041a0056a10d401200028022c2205450d07200541d0006c450d07200028022810350c070b2010450d01201041d0006c450d01202810350c010b0240200f2007460d0003402007220541d0006a21070240200541c4006a2802002216450d00201641306c450d00200541c0006a28020010350b200f2007470d000b0b02402010450d00201041d0006c450d00202810350b2012410171450d00024020002802ac032205450d0020002802a4032118200541057441406a2116200041e4056a2105034020004180026a201810c404200041a0056a200028028002221520002802880210d70220004180046a41086a2219200041a0056a41086a29030037030020004180046a41106a2214200041a0056a41106a29030037030020004180046a41186a221a200041a0056a41186a29030037030020004180046a41206a2207200041a0056a41206a29030037030020004180046a41286a2202200041a0056a41286a29030037030020004180046a41306a2203200041a0056a41306a29030037030020004180046a41386a2208200041a0056a41386a290300370300200041e0026a41086a2209200541086a290200370300200041e0026a41106a220a200541106a290200370300200041e0026a41186a220f200541186a280200360200200020002903a00537038004200020052902003703e002024020002802e0052217450d00200041f0006a41386a2008290300370300200041f0006a41306a2003290300370300200041f0006a41286a2002290300370300200041f0006a41206a2007290300370300200041f0006a41186a201a290300370300200041f0006a41106a2014290300370300200041f0006a41086a2019290300370300200041d0046a41086a2009290300370300200041d0046a41106a200a290300370300200041d0046a41186a200f2802003602002000200029038004370370200020002903e0023703d0040b0240200028028402450d00201510350b20170d03201841206a2118201641606a22164140470d000b0b4108210a410021084100210f0c020b0240200028029c03450d0020002802980310350b024020002802a80341ffffff3f71450d0020002802a40310350b20002802b4032205450d02200541246c450d0220002802b00310350c020b200041c0036a41386a2214200041f0006a41386a290300370300200041c0036a41306a221a200041f0006a41306a290300370300200041c0036a41286a2207200041f0006a41286a290300370300200041c0036a41206a2202200041f0006a41206a290300370300200041c0036a41186a2203200041f0006a41186a290300370300200041c0036a41106a2208200041f0006a41106a290300370300200041c0036a41086a2209200041f0006a41086a290300370300200041a0026a41086a220a200041d0046a41086a2205290300370300200041a0026a41106a220f200041d0046a41106a2215290300370300200041a0026a41186a2211200041d0046a41186a2219280200360200200020002903703703c003200020002903d0043703a002200041b0016a41086a221c2009290300370300200041b0016a41106a22092008290300370300200041b0016a41186a22082003290300370300200041b0016a41206a22032002290300370300200041b0016a41286a22022007290300370300200041b0016a41306a2207201a290300370300200041b0016a41386a221a2014290300370300200041c0026a41086a2214200a290300370300200041c0026a41106a220a200f290300370300200041c0026a41186a220f2011280200360200200020002903c0033703b001200020002903a0023703c002200041a0056a41086a2211201c290300370300200041a0056a41106a221c2009290300370300200041a0056a41186a22092008290300370300200041a0056a41206a22082003290300370300200041a0056a41286a22032002290300370300200041a0056a41306a22022007290300370300200041a0056a41386a2207201a290300370300200020002903b0013703a005200520142903003703002015200a2903003703002019200f280200360200200020002903c0023703d00441e0001033220a450d04200a20002903a005370300200a2017360240200a20002903d004370244200a41386a2007290300370300200a41306a2002290300370300200a41286a2003290300370300200a41206a2008290300370300200a41186a2009290300370300200a41106a201c290300370300200a41086a2011290300370300200a41cc006a2005290300370200200a41d4006a2015290300370200200a41dc006a201928020036020020004281808080103702a4062000200a3602a006024020164160470d00410121084101210f0c010b201841206a2117200041a0056a41c4006a211841012108034020004180026a201710c404200041a0056a200028028002220520002802880210d70220004180046a41086a220f200041a0056a41086a221929030037030020004180046a41106a2211200041a0056a41106a221429030037030020004180046a41186a221c200041a0056a41186a221a29030037030020004180046a41206a221d200041a0056a41206a220729030037030020004180046a41286a221e200041a0056a41286a220229030037030020004180046a41306a2201200041a0056a41306a220329030037030020004180046a41386a2213200041a0056a41386a2209290300370300200041e0026a41086a2212201841086a290200370300200041e0026a41106a2233201841106a290200370300200041e0026a41186a2234201841186a280200360200200020002903a00537038004200020182902003703e002024020002802e0052215450d00200041d0046a41386a2013290300370300200041d0046a41306a2001290300370300200041d0046a41286a201e290300370300200041d0046a41206a201d290300370300200041d0046a41186a201c290300370300200041d0046a41106a2011290300370300200041d0046a41086a200f290300370300200041f0006a41086a2012290300370300200041f0006a41106a2033290300370300200041f0006a41186a203428020036020020002000290380043703d004200020002903e0023703700b0240200028028402450d00200510350b02400240024020150d002016450d010c020b200041c0036a41386a2205200041d0046a41386a290300370300200041c0036a41306a221d200041d0046a41306a290300370300200041c0036a41286a221e200041d0046a41286a290300370300200041c0036a41206a2201200041d0046a41206a290300370300200041c0036a41186a2213200041d0046a41186a220f290300370300200041c0036a41106a2212200041d0046a41106a2211290300370300200041c0036a41086a2233200041d0046a41086a221c290300370300200041a0026a41086a2234200041f0006a41086a290300370300200041a0026a41106a222d200041f0006a41106a290300370300200041a0026a41186a2228200041f0006a41186a280200360200200020002903d0043703c003200020002903703703a002200041b0016a41086a22102033290300370300200041b0016a41106a22332012290300370300200041b0016a41186a22122013290300370300200041b0016a41206a22132001290300370300200041b0016a41286a2201201e290300370300200041b0016a41306a221e201d290300370300200041b0016a41386a221d2005290300370300200041c0026a41086a22052034290300370300200041c0026a41106a2234202d290300370300200041c0026a41186a222d2028280200360200200020002903c0033703b001200020002903a0023703c0022019201029030037030020142033290300370300201a201229030037030020072013290300370300200220012903003703002003201e2903003703002009201d290300370300200020002903b0013703a005201c200529030037030020112034290300370300200f202d280200360200200020002903c0023703d0040240200820002802a406470d00200041a0066a2008410110a40120002802a006210a0b200a200841e0006c6a220520002903a005370300200541106a2014290300370300200541086a201929030037030020032903002104200929030021062002290300212e2007290300212f201a2903002130200541c0006a2015360200200541186a2030370300200541206a202f370300200541286a202e370300200541c4006a20002903d004370200200541386a2006370300200541306a2004370300200541cc006a201c290300370200200541d4006a2011290300370200200541dc006a200f2802003602002000200841016a22083602a80620160d010b20002802a406210f0c020b201741206a2117201641606a21160c000b0b200041a0056a41206a20004198036a41206a2802002216360200200041a0056a41106a20004198036a41106a290300370300200041a0056a41086a20004198036a41086a290300370300200041a0056a41186a20004198036a41186a290300220437030020002000290398033703a005201641246c41046a2205417f4c0d040240024020050d0041012118410021050c010b200510332218450d040b200041003602d804200020183602d004200020053602d4042016200041d0046a10770240024020160d0020002802d804211820002802d404211720002802d00421190c010b2004a72205201641246c6a2109410020002802d80422186b211420002802d404211703402005280200211602400240201720146a4104490d0020002802d0042119201721150c010b201841046a22152018490d08201741017422192015201920154b1b22154100480d080240024020170d00024020150d00410121190c020b201510332219450d0c0c010b20002802d004211920172015460d0020192017201510372219450d0b0b200020153602d404200020193602d0040b201920186a20163600002000201841046a22173602d804412010332216450d05201641186a221a2005411c6a290000370000201641106a2207200541146a290000370000201641086a22022005410c6a2900003700002016200541046a29000037000002400240201520146a417c6a411f4d0d00201521170c010b201741206a22032017490d08201541017422172003201720034b1b22174100480d080240024020150d00024020170d00410121190c020b201710332219450d0c0c010b20152017460d0020192015201710372219450d0b0b200020173602d404200020193602d0040b201920186a221541046a20162900003700002015411c6a201a290000370000201541146a20072900003700002015410c6a20022900003700002000201841246a22183602d804201610352014415c6a2114200541246a22052009470d000b0b200041d0046a10c20420002802d0042105200020002802d8043602840420002005360280042019201820004180046a109403024020002802d404450d00200510350b02402017450d00201910350b200041d0046a200041a0056a10c30420002802d0042105200020002802d80436028404200020053602800420002802ac052216200041b4056a28020020004180046a10c504024020002802d404450d00200510350b024020002802a405450d0020002802a00510350b0240200041b0056a28020041ffffff3f71450d00201610350b0240200041bc056a2802002205450d00200541246c450d0020002802b80510350b200a0d010b200028024021170240200041c8006a2802002205450d00200541d0006c2116201741c4006a21050340024020052802002218450d00201841306c450d002005417c6a28020010350b200541d0006a2105201641b07f6a22160d000b0b0240200041c4006a2802002205450d00200541d0006c450d00201710350b41eba3cc00ad4280808080c00184100641dca3cc00ad4280808080f0018410060c010b4100211802402035410a6e417f7320086a221620084b0d0020354101203541014b1b2205418094ebdc036e221820052018418094ebdc036c476a22184101201841014b1b221820054b0d0520002005201641036c221620052016491b20186ead428094ebdc037e200520186ead8042ffffffff0f834280bbb0217e428094ebdc0380a722053602a0052000418094ebdc033602a405200041a0056a2005418094ebdc034b4102746a28020021180b200041003602a805200042043703a005200041a0056a4100200810860120002802a005210720002802a805211a02400240024020080d0020002802a405211141012116200a41002007201a201b10fd010d010c020b2007201a4102746a210520082116034020052018360200200541046a21052016417f6a22160d000b20002802a405211141012116200a20082007201a20086a221a201b10fd01450d010b200041a0026a41186a4200370300200041a0026a41106a22184200370300200041a0026a41086a22054200370300200042003703a00241a2e8cb00ad42808080808001841001221629000021042005201641086a290000370300200020043703a0022016103541e6f2c400ad4280808080800284100122162900002104200041a0056a41086a2217201641086a290000370300200020043703a00520161035201820002903a005220437030020004180026a41086a200529030037030020004180026a41106a200437030020004180026a41186a2017290300370300200020002903a00237038002200041a0056a20004180026a10c6020240024020002802a00522020d0041002109200041003602b801200042043703b00141042102410021030c010b200020002902a40522043702b401200020023602b0012004422088a721032004a721090b2008ad42e0007e2204422088a70d032004a72205417f4c0d030240024020050d00410821160c010b200510332216450d030b200041003602c803200020163602c0032000200541e0006e3602c403200041c0036a4100200810a40120002802c803211c02402008450d00200a200841e0006c6a211420002802c003201c41e0006c6a2105200841057441606a410576211d200041a4056a2118200a21160340200041c0026a41086a2217201641086a290300370300200041c0026a41106a2215201641106a290300370300200041c0026a41186a2219201641186a290300370300200020162903003703c002201641206a2903002104201641286a2903002106201641306a290300212e201641386a290300212f20004180046a201641c0006a10c604200041d0046a201641d0006a10a402201841086a200041d0046a41086a280200360200201820002903d00437020020192903002130201529030021312017290300213220002903c0022137200541386a202f370300200541306a202e370300200541286a2006370300200541206a2004370300200541086a203237030020052037370300200541106a2031370300200541c0006a200029038004370300200541c8006a20004180046a41086a280200360200200541186a2030370300200541cc006a20002902a005370200200541d4006a200041a0056a41086a290200370200200541e0006a2105201641e0006a22162014470d000b201c201d6a41016a211c0b200041a8056a201c360200200020002903c0033703a005201a41ffffffff0371201a470d03201a4102742205417f4c0d030240024020050d00410421160c010b200510332216450d030b200041003602d804200020163602d004200020054102763602d404200041d0046a4100201a10860120002802d00420002802d80422054102746a2007201a410274109d081a20004180046a41086a22182005201a6a2205360200200041b4056a2005360200200020002903d0043702ac05024020032009470d00200041b0016a2009410110f90120002802b401210920002802b001210220002802b80121030b20022003411c6c6a220520002903a005370200200041a0056a41086a22162903002104200041a0056a41106a221729030021062005201b360218200541106a2006370200200541086a20043702002000200341016a22153602b801200041a0056a41186a42003703002017420037030020164200370300200042003703a00541a2e8cb00ad42808080808001841001220529000021042016200541086a290000370300200020043703a0052005103541e6f2c400ad42808080808002841001220529000021042018200541086a29000037030020002004370380042005103520172000290380042204370300200041d0046a41086a2016290300370300200041d0046a41106a2004370300200041d0046a41186a2018290300370300200020002903a0053703d0040240024020020d00200041d0046aad428080808080048410070c010b200041a0056a2002201510c704200041d0046aad428080808080048420003502a80542208620002802a0052205ad841002024020002802a405450d00200510350b2002201510c8022009450d002009411c6c450d00200210350b410021160b410410332205450d012005201b360000200041a8056a4284808080c000370300200041b8056a4100290280bf46370300200041c0056a20163a0000200041103a00a005200041a0056a41106a41002902f8be46370300200020053602a40541b0b4cc004100200041a0056a10d4010240201141ffffffff0371450d00200710350b02402008450d00200841e0006c2116200a41d4006a210503400240200541706a2802002218450d00201841306c450d002005416c6a28020010350b0240200528020041ffffff3f71450d002005417c6a28020010350b200541e0006a2105201641a07f6a22160d000b0b0240200f450d00200f41e0006c450d00200a10350b200028024021170240200041c8006a2802002205450d00200541d0006c2116201741c4006a21050340024020052802002218450d00201841306c450d002005417c6a28020010350b200541d0006a2105201641b07f6a22160d000b0b200041c4006a2802002205450d00200541d0006c450d00201710350b0240200e42ffffff3f83500d00200d4101200d1b10350b200041b0066a24000f0b1045000b1044000b103e000b4190edc40041194180efc400103f000b103c000bfe0304027f017e067f077e230041c0006b220224000240024020012802082203ad42d0007e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510332206450d020b20024100360208200220063602002002200541d0006e36020420024100200310a3012002280208210702402003450d002001200341d0006c6a21082002280200200741d0006c6a2105200341047441706a41047621090340200241206a41086a2203200141086a290300370300200241206a41106a2206200141106a290300370300200241206a41186a220a200141186a29030037030020022001290300370320200141206a2903002104200141286a290300210b200141306a290300210c200141386a290300210d200241106a200141c0006a10c604200a290300210e2006290300210f2003290300211020022903202111200541386a200d370300200541306a200c370300200541286a200b370300200541206a2004370300200541086a201037030020052011370300200541106a200f370300200541186a200e370300200541c0006a2002290310370300200541c8006a200241106a41086a280200360200200541d0006a2105200141d0006a22012008470d000b200720096a41016a21070b20002002290300370200200041086a2007360200200241c0006a24000f0b1044000b1045000b970503027f017e067f230041d0006b2201240041a2e8cb00ad4280808080800184100122022900002103200141086a41086a200241086a290000370300200120033703082002103541aae8cb00ad4280808080a00284100122022900002103200141186a41086a200241086a29000037030020012003370318200210350240024002400240411010332202450d0041002104200241086a4100290280bf46370000200241002902f8be4637000020012002ad42808080808002841003220529000037033820051035200141cc006a200241106a360200200120023602482001200141386a41086a3602442001200141386a360240200141286a200141c0006a107b200210352001280230220641206a2207417f4c0d01200128022821080240024020070d00410121020c010b200710332202450d01200721040b024002402004410f4d0d00200421050c010b200441017422054110200541104b1b22054100480d03024020040d002005103322020d010c050b20042005460d0020022004200510372202450d040b20022001290308370000200241086a200141086a41086a2903003700000240024020054170714110460d00200521040c010b200541017422044120200441204b1b22044100480d0320052004460d0020022005200410372202450d040b20022001290318370010200241186a200141186a41086a29030037000002400240200441606a2006490d00200421050c010b200641206a22052006490d03200441017422092005200920054b1b22054100480d0320042005460d0020022004200510372202450d040b200241206a20082006109d081a2000200736020820002005360204200020023602000240200128022c450d00200810350b200141d0006a24000f0b1045000b1044000b103e000b103c000bbd0603027f017e087f230041d0006b2202240041a2e8cb00ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541b0a5c500ad4280808080e00284100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240411010332203450d0041002105200341086a4100290280bf46370000200341002902f8be4637000020022003ad42808080808002841003220629000037033820061035200241cc006a200341106a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b20031035200241c0006a200128020020012802081098032002280230220741206a2208200228024822096a2201417f4c0d012002280240210a2002280228210b0240024020010d00410121030c010b200110332203450d01200121050b024002402005410f4d0d002005210c0c010b200541017422064110200641104b1b220c4100480d03024020050d00200c103322030d010c050b2005200c460d0020032005200c10372203450d040b20032002290308370000200341086a200241086a41086a29030037000002400240200c4170714110460d00200c21060c010b200c41017422054120200541204b1b22064100480d03200c2006460d002003200c200610372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200641606a2007490d00200621050c010b200741206a22052007490d032006410174220c2005200c20054b1b22054100480d0320062005460d0020032006200510372203450d040b200341206a200b2007109d081a02400240200520086b2009490d00200521060c010b20012008490d03200541017422062001200620014b1b22064100480d03024020050d00024020060d00410121030c020b200610332203450d050c010b20052006460d0020032005200610372203450d040b200320086a200a2009109d081a20002001360208200020063602042000200336020002402002280244450d00200a10350b0240200228022c450d00200b10350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a2e8cb00ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541dff2c400ad4280808080f00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000be503010a7f230041106b22032400024020014105744104722204417f4c0d000240200410332205450d002003410036020820032004360204200320053602002001200310770240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020052104412010332201450d0220012000290000370000200141186a2209200041186a290000370000200141106a220a200041106a290000370000200141086a220b200041086a29000037000002400240200620046b4120490d00200441206a21050c010b024002400240200441206a22052004490d002006410174220c2005200c20054b1b220c4100480d000240024020060d000240200c0d00410121070c020b200c103321070c040b2006200c470d020b200c21060c030b103e000b20072006200c103721070b200c210620070d00103c000b200041206a2100200720046a22042001290000370000200441186a2009290000370000200441106a200a290000370000200441086a200b29000037000020011035200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100202402006450d00200710350b200341106a24000f0b1045000b1044000bb10203027f017e027f230041106b220224000240024020012802082203ad42307e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510332206450d020b20024100360208200220063602002002200541306e3602042002410020031088012002280208210502402003450d002001200341306c6a21062002280200200541306c6a21030340200320012903003703002003200141086a290300370308200341106a200141106a290300370300200341186a200141186a290300370300200341206a200141206a290300370300200341286a200141286a290300370300200341306a2103200541016a2105200141306a22012006470d000b0b20002002290300370200200041086a2005360200200241106a24000f0b1044000b1045000bfe0301067f230041106b22032400024002402002411c6c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b20034100360208200320053602002003200436020420022003107702402002450d0020012002411c6c6a2106034020012802002105200128020822022003107702402002450d002005200241e0006c6a2107034020032005412010782003200541206a36020c2003410c6a200310cf012003200541306a36020c2003410c6a200310cf0120052802402102200528024822042003107702402004450d00200441306c210403402003200241106a412010782003200236020c200241306a21022003410c6a200310cf01200441506a22040d000b0b200541e0006a210820052802502102200528025822042003107702402004450d002004410574210403402003200241201078200241206a2102200441606a22040d000b0b2008210520082007470d000b0b2001411c6a2105200128020c2102200128021422042003107702402004450d002004410274210403402003200228020036020c20032003410c6a41041078200241046a21022004417c6a22040d000b0b2003200128021836020c20032003410c6a410410782005210120052006470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1044000b1045000b960407047f017e017f017e017f017e047f230041e0006b22012400200141306a41186a22024200370300200141306a41106a22034200370300200141306a41086a220442003703002001420037033041d1c4c700ad4280808080e000842205100122062900002107200141d0006a41086a2208200641086a290000370300200120073703502006103520042008290300370300200120012903503703304184eec700ad4280808080b0028422071001220629000021092008200641086a2900003703002001200937035020061035200320012903502209370300200141106a41086a220a2004290300370300200141106a41106a220b2009370300200141106a41186a220c2008290300370300200120012903303703102001200141106a10e102200129030821092001280200210d2002420037030020034200370300200442003703002001420037033020051001220629000021052008200641086a2900003703002001200537035020061035200420082903003703002001200129035037033020071001220629000021052008200641086a2900003703002001200537035020061035200320012903502205370300200a2004290300370300200b2005370300200c2008290300370300200120012903303703102001427f20094200200d1b220520007c220020002005541b370330200141106aad4280808080800484200141306aad42808080808001841002200141e0006a24000bfc0403027f017e057f230041d0006b220224004189fec600ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541e28cc500ad4280808080e00084100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bea3506207f027e027f057e027f077e230041f0106b220224000240024002400240024002400240200141106a2802002203200141146a280200460d00200241f00a6a41c0026a21042002418d0b6a2105200241e10a6a2106200241a80a6a2107200241f00a6a4105722108200241f8076a4105722109200241a00f6a210a200241c00e6a41c0006a210b200241e00e6a210c200241e8086a210d200241f00a6a410472210e200241f8076a410472210f200241f00a6a41146a2110200241f00a6a41106a2111200241f00a6a410d6a2112200241f00a6a410c6a2113200241f00a6a41086a2114200241c8086a2115200241f8076a41146a2116200241f8076a41106a2117200241f8076a410d6a2118200241a8086a2119200241f8076a410c6a211a200241f8076a41086a211b200241f8076a41c0026a211c200241f8076a41046a211d03402001200341d8026a3602102003280200211e200241186a200341046a41c002109d081a200241086a41086a221f200341d0026a2903003703002002200341c8026a290300370308200341c4026a28020022034102460d0120012802182120200241f8076a200241186a41c002109d081a200241f00a6a201d41bc02109d081a20042002290308370300200441086a2221201f290300370300200220033602ac0d200241b8056a200241f00a6a10d8032001200129030020022903b8057c2222370300200241b8056a200241f00a6a41bc02109d081a200241a8056a41086a221f2021290300370300200220042903003703a8050240024020022802ac0d22034102470d00410321030c010b200241f8076a200241b8056a41bc02109d081a201c41086a2221201f290300370300201c20022903a805370300200220033602b40a0240024020022d00c00a41c000490d002020450d0020222001280220290300560d010b024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022802f8070e1c00011302030405060708090a0b0c0d0e0f1011121313131415161713000b200241c00e6a201b109d03201441086a200241c00e6a41086a290300370300201420022903c00e370300200241003602f00a0c170b200241c00e6a200f109a03200e41386a200241c00e6a41386a280200360200200e41306a200241c00e6a41306a290300370200200e41286a200241c00e6a41286a290300370200200e41206a200241c00e6a41206a290300370200200e41186a200241c00e6a41186a290300370200200e41106a200241c00e6a41106a290300370200200e41086a200241c00e6a41086a290300370200200e20022903c00e370200200241013602f00a0c160b20022002290380083703f80a200241033602f00a0c150b200241c00e6a200f109e03200e41086a200241c00e6a41086a280200360200200e20022903c00e370200200241043602f00a0c140b024002400240024002400240024020022d00fc07417f6a220341034b0d0020030e0401020304010b41cfa2cc00412841c086cc00103f000b41012103200228028008211f0c040b41022103200241c00d6a41026a200941026a2d00003a0000200241c00e6a41086a201a41086a290200370300200241c00e6a41106a201a41106a290200370300200241c00e6a41186a201a41186a2d00003a0000200220092f00003b01c00d2002201a2902003703c00e0c020b41032103200228028008211f0c020b200241c00d6a41026a200941026a2d00003a0000200241c00e6a41086a201a41086a290200370300200241c00e6a41106a201a41106a290200370300200241c00e6a41186a201a41186a2d00003a0000200220092f00003b01c00d2002201a2902003703c00e410421030b200228028008211f20022802a00821210b200820022f01c00d3b0000201320022903c00e370200200841026a200241c00d6a41026a2d00003a0000201341086a200241c00e6a41086a290300370200201341106a200241c00e6a41106a290300370200201341186a200241c00e6a41186a280200360200200220033a00f40a2002201f3602f80a200220213602980b200241053602f00a0c130b024002400240024002400240200228028008417f6a220341034b0d0020030e0401020304010b41cfa2cc00412841c086cc00103f000b41012103024020022d0084084101460d00200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e410021030b2002280288082121200241e8106a41026a200241ec106a41026a2d00003a0000200241c00d6a41086a200241c00e6a41086a290300370300200241c00d6a41106a200241c00e6a41106a290300370300200241c00d6a41186a200241c00e6a41186a280200360200200220022f01ec103b01e810200220022903c00e3703c00d20022903a8082223422088a721202023420888a721242023a7211f200241b0086a2903002123410121250c030b41012103024020022d0084084101460d00200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e410021030b200228028808212141022125200241e8106a41026a200241ec106a41026a2d00003a0000200241c00d6a41086a200241c00e6a41086a290300370300200241c00d6a41106a200241c00e6a41106a290300370300200241c00d6a41186a200241c00e6a41186a280200360200200220022f01ec103b01e810200220022903c00e3703c00d20022903a8082223422088a721202023420888a721242023a7211f200241c0086a2903002126200241b0086a290300212320022903b80821270c020b41012103024020022d0084084101460d00200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e410021030b20022802880821214101211f0240024020022d00a8084101470d0020022802ac0821202028212320292127202a2126202b21240c010b202c41807e7120022d00c80872212c4100211f20022802ac08212020022903b0082223212820022903b80822272129200241c0086a2903002226212a20022f00a908200241ab086a2d0000411074722224212b0b200241e8106a41026a200241ec106a41026a2d00003a0000200241c00d6a41086a200241c00e6a41086a290300370300200241c00d6a41106a200241c00e6a41106a290300370300200241c00d6a41186a200241c00e6a41186a280200360200200220022f01ec103b01e810200220022903c00e3703c00d202d42808080807083202cad84212d200241d8086a290300212e20022903d008212f410321250c010b41012103024020022d0084084101460d00200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e410021030b2002280288082121200241e8106a41026a200241ec106a41026a2d00003a0000200241c00d6a41086a200241c00e6a41086a290300370300200241c00d6a41106a200241c00e6a41106a290300370300200241c00d6a41186a200241c00e6a41186a280200360200200220022f01ec103b01e810200220022903c00e3703c00d20022903a8082223422088a721202023420888a721242023a7211f200241b0086a2903002123410421250b201220022f01e8103b0000201241026a200241e8106a41026a2d00003a0000201020022903c00d370200201041086a200241c00d6a41086a290300370200201041106a200241c00d6a41106a290300370200201041186a200241c00d6a41186a280200360200200220033a00fc0a200220253602f80a200220213602800b200241d00b6a202e370300200241b80b6a2026370300200241a80b6a20233703002002202f3703c80b200220273703b00b20022020ad4220862024ad42ffffff078342088684201fad42ff0183843703a00b2002202d3703c00b200241063602f00a0c120b200241c00e6a201b1087022014200241c00e6a418802109d081a200241073602f00a0c110b0240024020022802fc0722240d004100211f0c010b200c2019290000370000200b2015290000370000200241c00e6a41186a201741186a290000370300200241c00e6a41106a201741106a290000370300200241c00e6a41086a201741086a290000370300200c41086a201941086a290000370000200c41106a201941106a290000370000200c41186a201941186a290000370000200b41086a201541086a290000370000200b41106a201541106a290000370000200b41186a201541186a290000370000200220172900003703c00e200a41186a200d41186a290000370000200a41106a200d41106a290000370000200a41086a200d41086a290000370000200a200d2900003700002002280284082203417f4c0d180240024020030d00410021214101211f0c010b20031033221f450d1b200321210b0240024020212003490d00202121200c010b202141017422202003202020034b1b22204100480d1a024020210d0020201033221f0d010c1d0b20212020460d00201f202120201037221f450d1c0b201f20242003109d081a200241c00d6a200241c00e6a418001109d081a2003ad4220862020ad8421300b200220303703f80a2002201f3602f40a2011200241c00d6a418001109d081a200241083602f00a0c100b200241c00e6a201b10a003201441306a200241c00e6a41306a290300370300201441286a200241c00e6a41286a290300370300201441206a200241c00e6a41206a290300370300201441186a200241c00e6a41186a290300370300201441106a200241c00e6a41106a290300370300201441086a200241c00e6a41086a290300370300201420022903c00e370300200241093602f00a0c0f0b200241c00e6a200f10a103200e41286a200241c00e6a41286a290300370200200e41206a200241c00e6a41206a290300370200200e41186a200241c00e6a41186a290300370200200e41106a200241c00e6a41106a290300370200200e41086a200241c00e6a41086a290300370200200e20022903c00e3702002002410a3602f00a0c0e0b200241c00e6a200f10a103200e41286a200241c00e6a41286a290300370200200e41206a200241c00e6a41206a290300370200200e41186a200241c00e6a41186a290300370200200e41106a200241c00e6a41106a290300370200200e41086a200241c00e6a41086a290300370200200e20022903c00e3702002002410b3602f00a0c0d0b200241c00e6a201b108603201441206a200241c00e6a41206a290300370300201441186a200241c00e6a41186a290300370300201441106a200241c00e6a41106a290300370300201441086a200241c00e6a41086a290300370300201420022903c00e3703002002410c3602f00a0c0c0b200241c00e6a200f10a203200e200241c00e6a41c400109d081a2002410d3602f00a0c0b0b200220022802fc073602f40a2002410e3602f00a0c0a0b2002280284082203417f4c0d1020022802fc0721240240024020030d004100211f410121200c010b200310332220450d132003211f0b02400240201f2003490d00201f21210c010b201f41017422212003202120034b1b22214100480d120240201f0d00202110332220450d150c010b201f2021460d002020201f202110372220450d140b202020242003109d08211f200220033602fc0a200220213602f80a2002201f3602f40a2002410f3602f00a0c090b200241c00e6a201b10a303201441386a200241c00e6a41386a290300370300201441306a200241c00e6a41306a290300370300201441286a200241c00e6a41286a290300370300201441206a200241c00e6a41206a290300370300201441186a200241c00e6a41186a290300370300201441086a200241c00e6a41086a290300370300201420022903c00e370300200241103602f00a201441106a200241c00e6a41106a2903003703000c080b200241c00e6a201b10a4032014200241c00e6a419801109d081a200241113602f00a0c070b200241c00e6a200f10a503200e41286a200241c00e6a41286a280200360200200e41206a200241c00e6a41206a290300370200200e41186a200241c00e6a41186a290300370200200e41106a200241c00e6a41106a290300370200200e41086a200241c00e6a41086a290300370200200e20022903c00e370200200241123602f00a0c060b200241c00e6a200f10de04200e200241c00e6a41e800109d081a200241133602f00a0c050b10a703000b200241c00e6a201b10a8032014200241c00e6a41a802109d081a200241173602f00a0c030b200241c00e6a201b10a9032014200241c00e6a41c800109d081a200241183602f00a0c020b200241c00e6a200f10aa03200e200241c00e6a41c400109d081a200241193602f00a0c010b02400240024002400240200228028008417f6a220341024b0d004101212120030e03040102040b41cfa2cc00412841c086cc00103f000b4101211f024020022d0084084101470d00410221212002280288082124200241ec106a2125200241c00e6a21030c020b41022121200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e4100211f2002280288082124200241ec106a2125200241c00e6a21030c010b4101211f024020022d0084084101460d00200241ec106a41026a201841026a2d00003a0000200241c00e6a41086a201641086a290200370300200241c00e6a41106a201641106a290200370300200241c00e6a41186a201641186a2d00003a0000200220182f00003b01ec10200220162902003703c00e4100211f0b2002280288082124200241c0086a2903002131200241b0086a290300213220022903b808212320022903a80821334103212120022802c8082120200241ec106a2125200241c00e6a21030b200241e8106a41026a202541026a2d00003a0000200241c00d6a41086a200341086a290200370300200241c00d6a41106a200341106a290200370300200241c00d6a41186a200341186a280200360200200220252f00003b01e810200220032902003703c00d0b201220022f01e8103b0000201020022903c00d370200200241b80b6a2031370300200241a80b6a2032370300201241026a200241e8106a41026a2d00003a0000201041086a200241c00d6a41086a290300370200201041106a200241c00d6a41106a290300370200201041186a200241c00d6a41186a280200360200200220233703b00b200220333703a00b2002201f3a00fc0a200220213602f80a200220243602800b200220203602c00b2002411a3602f00a0b4100211f200241003b01c00e200241c80a6a200241f00a6a200241c00e6a10ac030240024020022802a80a22240d000c010b20022802b00a2203417f4c0d070240024020030d00410021214101211f0c010b20031033221f450d0a200321210b0240024020212003490d00202121200c010b202141017422202003202020034b1b22204100480d09024020210d0020201033221f450d0c0c010b20212020460d00201f202120201037221f450d0b0b201f20242003109d081a2003ad4220862020ad8421230b410121030240024020022802b40a4101460d0020022802a80a450d01200241f00a6a200710f00420023502f80a42208620022802f00a2221ad84100720022802f40a450d01202110350c010b20022802b80a21030240024020022802bc0a222141014b0d00200241003602b40a0c010b200241013602b40a20022021417f6a3602bc0a0b200128022428020020036a2103024020022802a80a450d00200241f00a6a200310f30420022802f40a212420022802f00a2125200241f00a6a200710f00420023502f80a213120022802f00a2120410810332221450d0a2021200336000020214100202420254101461b36000420314220862020ad842021ad428080808080018410022021103520022802f40a450d00202010350b200241f00a6a200241f8076a41d002109d081a2003200241f00a6a410110cb04024020022802ac0d4102460d00024020022802a00d2203450d0020022802a40d450d00200310350b200241f00a6a10ba020b410021030b20012802242802002120200220062900003703f00a2002200641076a2800003600f70a0240024020022903c80a4201510d00410421210c010b20022d00e00a212420022903d00a2131200220022800f70a3600c70e200220022903f00a3703c00e4104212120314202510d00200220022800c70e3600f70a200220022903c00e3703f00a202421210b200220022903f00a3703c00d200220022800f70a3600c70d200520022903c00d370000200541076a20022800c70d360000200220213a008c0b200220233702840b2002201f3602800b2002201e3602fc0a200220203602f80a200241013602f40a200241153a00f00a41b0b4cc004100200241f00a6a10d40120012802282022370300024020030d00410421030c020b024020022802a80a2203450d0020022802ac0a450d00200310350b200241f8076a10ba02410421030c010b200241f00a6a200241f8076a41bc02109d081a200241c00e6a41086a221f20212903003703002002201c2903003703c00e024020034103470d00410421030c010b200241f8076a200241f00a6a41bc02109d081a200241c00d6a41086a201f290300370300200220022903c00e3703c00d0b2001200128021841016a360218200241e8026a200241f8076a41bc02109d081a200241d8026a41086a200241c00d6a41086a290300370300200220022903c00d3703d802024020034104470d00200128021022032001280214470d010c020b0b200241f00a6a200241e8026a41bc02109d081a200241f8076a41086a2201200241d8026a41086a290300370300200220022903d8023703f80720034103470d010b200041033602bc020c010b2000200241f00a6a41bc02109d08220420033602bc02200420022903f8073703c002200441c8026a20012903003703000b200241f0106a24000f0b1044000b103e000b1045000b103c000bf41503027f017e087f23004190016b220324004189fec600ad4280808080900184100122042900002105200341c0006a41086a200441086a290000370300200320053703402004103541e28cc500ad4280808080e00084100122042900002105200341d8006a41086a200441086a2900003703002003200537035820041035200320003602082003200341086aad4280808080c00084100322042900003703182004103520034184016a2003410c6a3602002003200341186a41086a36027c2003200341086a360280012003200341186a360278200341286a200341f8006a107b0240024002400240024002400240024002400240024002402003280230220641206a2207417f4c0d00200328022821080240024020070d0041002104410121090c010b200710332209450d02200721040b024002402004410f4d0d002004210a0c010b2004410174220a4110200a41104b1b220a4100480d07024020040d00200a103322090d010c0d0b2004200a460d0020092004200a10372209450d0c0b20092003290340370000200941086a200341c0006a41086a29030037000002400240200a4170714110460d00200a21040c010b200a41017422044120200441204b1b22044100480d07200a2004460d002009200a200410372209450d0c0b20092003290358370010200941186a200341d8006a41086a29030037000002400240200441606a2006490d002004210b0c010b200641206a220a2006490d072004410174220b200a200b200a4b1b220b4100480d072004200b460d0020092004200b10372209450d0c0b200941206a20082006109d081a0240200328022c450d00200810350b200341d8006a2007ad4220862009ad842205100510c2010240024020032802580d00410410332204450d032003420437027c200320043602784100200341f8006a1077200341106a200328028001360200200320032903783703080c010b200341086a41086a200341d8006a41086a280200360200200320032903583703080b200341186a41086a200341086a41086a2802002204360200200320032903083703182001200241d0026c6a210a024002402004450d00200341f8006a20032802182004200210f10420032802784101470d01200328021c450d0b200328021810350c0b0b2002200341186a1077200a2001460d08200241d0026c210720012104034002400240200441bc026a2802004102470d0002400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d0b200a41017422082006200820064b1b22084100480d0b02400240200a0d004100210a024020080d00410121060c020b200810332206450d120c010b20032802182106200a2008460d002006200a200810372206450d112003280220210a0b2003200836021c200320063602180b2006200a6a41003a00002003200a41016a3602200c010b02400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d0a200a41017422082006200820064b1b22084100480d0a02400240200a0d004100210a024020080d00410121060c020b200810332206450d110c010b20032802182106200a2008460d002006200a200810372206450d102003280220210a0b2003200836021c200320063602180b2006200a6a41013a00002003200a41016a3602202004200341186a10da040b200441d0026a2104200741b07d6a22070d000c090b0b200328027c2108024020034184016a2802002204200341f8006a41086a2802002207460d002003280220200420076b6a220620024102746a220c417f4c0d0102400240200c0d004100210c4101210d0c010b200c1033220d450d030b2003200d3602282003200c36022c200320063602302003200341286a3602782008200341f8006a200410f20420062004490d03200328023022082006490d04200328022022082007490d052003280228210c2003280218210d2003200620046b22063602382003200820076b220836023c20062008470d06200c20046a200d20076a2006109d081a0240200a2001460d00200241d0026c210720012104034002400240200441bc026a2802004102470d0002400240200328022c2003280230220a460d00200328022821060c010b200a41016a2206200a490d0c200a41017422082006200820064b1b22084100480d0c02400240200a0d004100210a024020080d00410121060c020b200810332206450d130c010b20032802282106200a2008460d002006200a200810372206450d122003280230210a0b2003200836022c200320063602280b2006200a6a41003a00002003200a41016a3602300c010b02400240200328022c2003280230220a460d00200328022821060c010b200a41016a2206200a490d0b200a41017422082006200820064b1b22084100480d0b02400240200a0d004100210a024020080d00410121060c020b200810332206450d120c010b20032802282106200a2008460d002006200a200810372206450d112003280230210a0b2003200836022c200320063602280b2006200a6a41013a00002003200a41016a3602302004200341286a10da040b200441d0026a2104200741b07d6a22070d000b0b2003280230210a200328022c210720032802282104200328021c450d09200328021810350c090b2003200341186a3602782008200341f8006a200710f204200a2001460d07200241d0026c210720012104034002400240200441bc026a2802004102470d0002400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d0a200a41017422082006200820064b1b22084100480d0a02400240200a0d004100210a024020080d00410121060c020b200810332206450d110c010b20032802182106200a2008460d002006200a200810372206450d102003280220210a0b2003200836021c200320063602180b2006200a6a41003a00002003200a41016a3602200c010b02400240200328021c2003280220220a460d00200328021821060c010b200a41016a2206200a490d09200a41017422082006200820064b1b22084100480d0902400240200a0d004100210a024020080d00410121060c020b200810332206450d100c010b20032802182106200a2008460d002006200a200810372206450d0f2003280220210a0b2003200836021c200320063602180b2006200a6a41013a00002003200a41016a3602202004200341186a10da040b200441d0026a2104200741b07d6a2207450d080c000b0b1044000b1045000b2004200641e88cc5001059000b2006200841e88cc5001058000b2007200841f88cc5001059000b200341d8006a41146a410a360200200341e4006a410c360200200341c0006a41146a41033602002003200341386a36027020032003413c6a360274200341f8006a41146a410036020020034203370244200341a0b3cc003602402003410c36025c200341b0b4cc00360288012003420137027c200341f4b3cc003602782003200341d8006a3602502003200341f8006a3602682003200341f4006a3602602003200341f0006a360258200341c0006a41b0b4cc00104c000b103e000b2003280220210a200328021c2107200328021821040b2004450d002005200aad4220862004ad84100202402007450d00200410350b200b450d01200910350c010b0240200b450d00200910350b200341d8006a200010c9042003280258210420033502602105200341f8006a2001200210d90420054220862004ad842003350280014220862003280278220aad8410020240200328027c450d00200a10350b200328025c450d00200410350b20034190016a24000f0b103c000b81ad010a017f017e017f047e047f027e0b7f067e037f027e230041f00c6b22012400200141003602e003200142013703d803024002400240024020004180ee05700d0041a29bc800ad4280808080f00084220210012203290000210420032900082105200310354189eaca00ad4280808080f00084100122032900002106200329000821072003103520012007370288082001200637028008200120053702f807200120043702f007200141a00a6a200141f0076a10fe0120012902a40a420020012802a00a22031b21042003410120031b2103024020012802dc0341ffffff3f71450d0020012802d80310350b200120043702dc03200120033602d8032001200141d8036a3602e4032002100122032900002102200329000821042003103541ceb8c800ad42808080803084100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141c0036a200141f0076a412010d701200141c0036a41106a290300210220012903c803210420012802c0032103200141e8036a41d1b8c800411010d503200141003a00c00a2002420020031b21062004420020031b2107200141e8036a21084120210341002109024002400240024002400340200141003a00f007200141f0076a20082003410047220a109d081a024020030d00200141003a00f0070b2003200a490d01200141a00a6a20096a20012d00f0073a00002001200941016a220b3a00c00a2003200a6b21032008200a6a2108200b2109200b4120470d000b20012903a00a210420012903a80a210520012903b00a210c20012903b80a210d4100210e200141a00a6a4100418002109f081a42002102200141d00c6a4200370300200141c80c6a4200370300200141c00c6a200d370300200141b80c6a200c370300200141b00c6a2005370300200120043703a80c200141c0003602a00c4108210f024020012802e40341086a2802000d004100210a0c050b41a29bc800ad4280808080f00084100122032900002104200329000821052003103541e1b8c800ad4280808080a0018410012203290000210c2003290008210d200310352001200d370288082001200c37028008200120053702f807200120043702f007200141f0056a200141f0076a10be020240024020012802f005220a0d00410021030c010b200141f0076aad4280808080800484100720012902f4052202422088a72103200a210f0b20012802e403220a200a2802082003108a0141d1c4c700ad4280808080e00084100122032900002104200329000821052003103541e7c4c700ad4280808080e0008410012203290000210c2003290008210d200310352001200d370288082001200c37028008200120053702f807200120043702f007200141b8036a200141f0076a412010c00120012802e40341086a28020041f4036a2203450d0120012802bc03210a20012802b8032108200141e4003a00f107200141e40041d0860320036e22036b3a00f007410021102001200141f0076a200341ff017141e4004b6a2d00004180fe126c200a410020081b6a36028c04200141003602980420014201370390042001410036029c04200142003703a804200142003703a004200142003703b804200142003703b004200141e8046a2001418c046a360200200141e4046a200141b0046a360200200141c0046a41206a2001419c046a360200200141dc046a200141a0046a360200200141d8046a20014190046a360200200141d4046a200141a00a6a3602002001200f2002422088a7220341e8006c22086a3602cc042001200f3602c80420012002a722113602c4042001200f3602c0042001200141e4036a3602d0040240024002402003450d00200141f0076a410172210b200141d0046a2112200f210303402001200341e8006a22093602c80420032d0000210a200141f0056a200341016a41e700109d081a200a4102460d012001200a3a00f007200b200141f0056a41e700109d081a20014190076a2012200141f0076a10ae062001290390074201510d0220092103200841987f6a22080d000b0b4108210b02402011450d00201141e8006c450d00200f10350b410021110c010b200141d8066a41306a20014190076a41386a2903002202370300200141d8066a41286a20014190076a41306a2903002204370300200141d8066a41206a20014190076a41286a2903002205370300200141b8056a41086a220b20014190076a41106a290300370300200141b8056a41106a220920014190076a41186a290300370300200141b8056a41186a221220014190076a41206a290300370300200141b8056a41206a22082005370300200141b8056a41286a220a2004370300200141b8056a41306a2203200237030020012001290398073703b80520014180056a41306a220f200329030037030020014180056a41286a2203200a29030037030020014180056a41206a220a200829030037030020014180056a41186a2208201229030037030020014180056a41106a2212200929030037030020014180056a41086a2209200b290300370300200120012903b8053703800541381033220b450d07200b200129038005370300200b41306a200f290300370300200b41286a2003290300370300200b41206a200a290300370300200b41186a2008290300370300200b41106a2012290300370300200b41086a200929030037030020014281808080103702f4042001200b3602f0042009200141c0046a41086a29030022023703002003200141c0046a41286a280200360200200a200141c0046a41206a2903003703002008200141c0046a41186a2903003703002012200141c0046a41106a290300370300200120012903c00437038005024002402002a72203200128028c05220a470d00410121100c010b200a41987f6a210f20014190076a41086a210a200141f0076a41017221114101211003402001200341e8006a22093602880520032d00002108200141f0056a200341016a41e700109d081a20084102460d01200120083a00f0072011200141f0056a41e700109d081a20014190076a2012200141f0076a10ae0602402001290390074201510d00200f2003462108200921032008450d010c020b200141d8066a41306a200a41306a2903002202370300200141d8066a41286a200a41286a2903002204370300200141d8066a41206a200a41206a2903002205370300200141b8056a41086a2208200a41086a290300370300200141b8056a41106a2213200a41106a290300370300200141b8056a41186a2214200a41186a290300370300200141b8056a41206a22152005370300200141b8056a41286a22162004370300200141b8056a41306a221720023703002001200a2903003703b805200141f0076a41306a22182017290300370300200141f0076a41286a22172016290300370300200141f0076a41206a22162015290300370300200141f0076a41186a22152014290300370300200141f0076a41106a22142013290300370300200141f0076a41086a22132008290300370300200120012903b8053703f0070240201020012802f404470d00200141f0046a20104101108b0120012802f004210b0b200b201041386c6a220820012903f007370300200841306a2018290300370300200841286a2017290300370300200841206a2016290300370300200841186a2015290300370300200841106a2014290300370300200841086a20132903003703002001201041016a22103602f804200f20034721082009210320080d000b0b02402001280284052203450d00200341e8006c450d0020012802800510350b20012802f40421110b41a29bc800ad4280808080f00084100122032900002102200329000821042003103541b39bc800ad4280808080d000841001220329000021052003290008210c200310352001200c370288082001200537028008200120043702f807200120023702f007200141f0076aad4280808080800484220c1008024020012903a004200141a0046a41086a29030084500d00024002402001280298042203450d00200128029004210a200141a00a6a2003417f6a10af0622082003490d0120082003419cb9c8001042000b200142f0f2bd99f7edd8b4e5003703f007200141f0056a200141f0076a108106200142f0f2bd99f7edd8b4e50037039007200141f0076a20014190076a10e00120014190076a200141f0056a200141f0076a20012903a004200141a8046a290300410110e6020c010b200a20084105746a200128028c0420012903a004200141a8046a29030010b0060b024020012903b0042202200141b0046a41086a290300220484500d00200142f0f2bd99f7edd8b4e5003703f007200141f0056a200141f0076a10e001200142f0f2bd99f7edd8b4e50037039007200141f0076a20014190076a10810620014190076a200141f0056a200141f0076a20012903b004200141b8046a290300410110e6024200200620047d2007200254ad7d2204200720027d2202200756200420065620042006511b22031b21064200200220031b21070b0240024020100d004100210a0c010b201041386c210a200b41046a2109200141a00a6a200128029c04417f6a10af06210f200b2103034020092108200a450d0402402003290328200341306a29030084500d00200a41486a210a200841386a210920032802002112200341386a21032012200f4d0d010b0b200141f0056a41186a200841186a290000370300200141f0056a41106a200841106a290000370300200141f0056a41086a200841086a290000370300200120082900003703f00541002108200141003602f807200142013703f007200141f0076a4100201041386c221241386d108a0120012802f007220f20012802f80722094105746a21030340200b20086a220a41046a2902002102200a410c6a2902002104200a41146a2902002105200341186a200a411c6a290200370000200341106a2005370000200341086a200437000020032002370000200341206a2103200941016a21092012200841386a2208470d000b200120093602f80702402011450d00201141386c450d00200b10350b20012802f407210a20012802e4032203280200200328020810ac0620012802e403220328020821082003280200211241a29bc800ad4280808080f00084220210012203290000210420032900082105200310354189eaca00ad4280808080f0008410012203290000210d200329000821192003103520012019370288082001200d37028008200120053702f807200120043702f0072001200141f0076a3602900720014120360294072012200820014190076a10a8062002100122032900002102200329000821042003103541f69bc800ad4280808080c000841001220329000021052003290008210d200310352001200d370288082001200537028008200120043702f807200120023702f007412010332203450d07200320012903f005370000200341186a200141f0056a41186a2208290300370000200341106a200141f0056a41106a2212290300370000200341086a200141f0056a41086a2210290300370000200c2003ad4280808080800484100220031035200141f0076a41086a41063a0000200141f9076a20012903f00537000020014181086a201029030037000020014189086a201229030037000020014191086a2008290300370000200141a4086a2009360200200141a0086a200a3602002001419c086a200f360200200141123a00f00741b0b4cc004100200141f0076a10d4014101210a0b200142f0f2bd99f7edd8b4e5003703f007200141f0056a200141f0076a10e00120014190076a200141f0056a108e02200141f0076a2001280290072208200128029807108f0220014180086a290300420020012903f00742015122031b210220012903f807420020031b21040240200128029407450d00200810350b41a29bc800ad4280808080f000841001220329000021052003290008210d2003103541ceb8c800ad428080808030841001220329000021192003290008211a200310352001201a3702880820012019370280082001200d3702f807200120053702f00720014200200420077d22052005200456200220067d2004200754ad7d220420025620042002511b22031b4201884200200420031b2202423f8684220442808094f6c2d7e8d800200442808094f6c2d7e8d80054410020024201882202501b22031b220420077c22073703f00520012002420020031b20067c2007200454ad7c22063703f805200c200141f0056aad42808080808002841002200a201145720d03201141386c450d03200b10350c030b200a200341b89dcc001059000b41f0b8c8004119418cb9c800103f000b41b3b9c80041d700418cbac8001064000b024020012802940441ffffff3f71450d0020012802900410350b20012802e40341086a280200210a0b41a29bc800ad4280808080f000842219100122032900002102200329000821042003103541a99bc800ad4280808080a001841001220329000021052003290008210c200310352001200c370288082001200537028008200120043702f807200120023702f007200141b0036a200141f0076a412010c00102400240410020012802b403410020012802b0031b2203200a6b220a200a20034b1b2203410a2003410a491b22080d0041082111410021130c010b20191001220329000021022003290008210420031035419cbac800ad4280808080c000841001220329000021052003290008210c200310352001200c370288082001200537028008200120043702f807200120023702f007200141f0056a200141f0076a10be020240024020012802f00522180d00410821184200211b4100210a410021030c010b20012902f405221b422088a72103201ba7210a0b200141003602c005200142083703b80502400240024002402003450d000240201b422088a7220b0d00410821114100210e0c030b20032008200820034b1b210f201841286a21034100210e41082111410021174200210242002104410021124100210a4100210802400340024002402012200f4f0d00024002400240200341106a2903002205200341186a290300220c84500d00200220057c220d2007562004200c7c200d200254ad7c220420065620042006511b450d01200d21020c030b201741ff01710d02200141f0076a41186a2209200341386a290000370300200141f0076a41106a2210200341306a290000370300200141f0076a41086a2213200341286a2900003703002001200341206a2900003703f00702400240200341586a2d00004101470d002001200341596a221441036a28000036008305200341086a2903002105200341606a2215290000210c201541086a290000210d201428000021142003290300211a200141c0046a41086a200341706a221541086a2d00003a00002001201436028005200120152900003703c004410121140c010b200341606a2214290300210c201441086a290300210d410021140b200141f0056a41186a22152009290300370300200141f0056a41106a22162010290300370300200141f0056a41086a2210201329030037030020014190076a41086a2213200141c0046a41086a290300370300200120012903f0073703f00520012001280280053602b00420012001280083053600b304200120012903c004370390070240200e20012802bc05470d00200141b8056a200e410110960120012802b805211120012802c005210e0b2011200e41e8006c6a220920143a0000200941106a200d370300200941086a200c370300200920012802b004360001200941046a20012800b304360000200941206a2013290300370300200129039007210c200941c0006a420037030020094200370338200941306a2005370300200941286a201a370300200941186a200c370300200920012903f005370348200941d0006a2010290300370300200941d8006a2016290300370300200941e0006a2015290300370300410121172001200e41016a220e3602c0050c010b200141f0076a41186a2209200341386a290000370300200141f0076a41106a2210200341306a290000370300200141f0076a41086a2213200341286a2900003703002001200341206a2900003703f00702400240200341586a2d00004101470d002001200341596a221441036a28000036008305200341086a2903002102200341606a2215290000211a201541086a290000211c201428000021142003290300211d200141c0046a41086a200341706a221541086a2d00003a00002001201436028005200120152900003703c004410121140c010b200341606a2214290300211a201441086a290300211c410021140b200141d8066a41186a22152009290300370300200141d8066a41106a22162010290300370300200141d8066a41086a2210201329030037030020014190076a41086a2213200141c0046a41086a290300370300200120012903f0073703d80620012001280280053602b00420012001280083053600b304200120012903c004370390070240200e20012802bc05470d00200141b8056a200e410110960120012802b805211120012802c005210e0b2011200e41e8006c6a220920143a0000200941106a201c370300200941086a201a370300200920012802b004360001200941046a20012800b304360000200941206a2013290300370300200129039007211a200941c0006a200c37030020092005370338200941306a2002370300200941286a201d370300200941186a201a370300200920012903d806370348200941d0006a2010290300370300200941d8006a2016290300370300200941e0006a20152903003703002001200e41016a220e3602c005200d21020b200a41016a210a201241016a21120c010b0240200a0d004100210a0c010b2008200a6b2209200b4f0d02200141f0076a2003200a41987f6c6a41586a220941e800109d081a2009200341586a221041e800109e081a2010200141f0076a41e800109d081a0b200341e8006a2103200b200841016a2208460d030c000b0b2009200b41f485cc001042000b410821114100210e410021130c020b0240200a417f6a200b4f0d00201b42ffffffff0f83200b200a6bad42208684211b0b2012450d0041a29bc800ad4280808080f000841001220329000021022003290008210420031035419cbac800ad4280808080c00084100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141f0056a2018201b422088a710b106200141f0076aad428080808080048420013502f80542208620012802f005220aad841002201ba72103024020012802f405450d00200a10350b02402003450d00200341e8006c450d00201810350b20012802bc0521130c020b20012802bc052113201ba7210a0b200a450d00200a41e8006c450d00201810350b2019100122032900002102200329000821042003103541e1b8c800ad4280808080a00184100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141f0056a2011200e10b106200141f0076aad428080808080048420013502f80542208620012802f0052203ad841002024020012802f405450d00200310350b41002103024020012802e403220b41086a280200220a4102762208450d00410021032008200a460d00410021080340200841026a2103200a200841046a411e71762209450d01200321082009200a470d000b0b4100211203400240201241017422124101722208ad220220027e2202422088a70d00201220082002a7200a2003411f71764b1b21120b02402003450d0041002003417e6a2208200820034b1b21030c010b0b02402012450d0002400240200e450d00200e41e8006c210f201141c8006a21104100210e0c010b2012417f6a21080340200a450d05200141a00a6a200a417f6a10af062203200a4f0d062008450d022008417f6a210820012802e403280208210a0c000b0b0340200a450d04200b2802002108200141a00a6a200a417f6a10af062203200a4f0d05200e41016a210e200820034105746a210b200f21092010210a024002400340200141f0076a200a200b10b20620013502f807210220012802f0072108410110332203450d01200341003a000020024220862008ad842003ad42808080801084100220031035024020012802f407450d00200810350b200a41e8006a210a200941987f6a2209450d020c000b0b103c000b200e2012460d0120012802e403220b280208210a0c000b0b2013450d00201341e8006c450d00201110350b02400240024002400240024002400240024020004180a70c7022180d00024020012802e0030d0041a29bc800ad4280808080f0008410012203290000210220032900082104200310354189eaca00ad4280808080f00084100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141a00a6a200141f0076a10fe0120012902a40a420020012802a00a22031b21022003410120031b2103024020012802dc0341ffffff3f71450d0020012802d80310350b200120033602d803200120023702dc032002428080808010540d010b41a29bc800ad4280808080f00084100122032900002102200329000821042003103541ccbac800ad4280808080800184100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141a00a6a200141f0076a412010d501024020012d00a00a4101470d00200141a90a6a2800002103200141ad0a6a280000210a200141b10a6a2800002108200141b50a6a2800002109200141b90a6a280000210b20012800a10a211220012800a50a210e2001200141bd0a6a2800003602bc0a2001200b3602b80a200120093602b40a200120083602b00a2001200a3602ac0a200120033602a80a2001200e3602a40a200120123602a00a0240024020012802e003220a450d0020012802d8032103200a410574210a4100210b410021120340200141f0076a200310b30620012802f007220920012802f80710e40241ff01712108024020012802f407450d00200910350b0240024002402008417e6a220841014b0d0020080e020102010b200b41016a210b0c010b201241016a21120b200341206a2103200a41606a220a0d000b2012200b4a0d010b200141a00a6a10b40641a29bc800ad4280808080f0008410012203290000210220032900082104200310354189eaca00ad4280808080f00084100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141f0056a200141f0076a10fe0120012902f405420020012802f00522031b21022003410120031b2103024020012802dc0341ffffff3f71450d0020012802d80310350b200120023702dc03200120033602d8030b41a29bc800ad4280808080f00084100122032900002102200329000821042003103541d4bac800ad4280808080d00184100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141f0076aad428080808080048410080b024020012802e00341024d0d00200141f0056a41e1bac800411110d503200141003a00c00a200141f0056a210841202103410021090340200141003a00f007200141f0076a20082003410047220a109d081a024020030d00200141003a00f0070b2003200a490d03200141a00a6a20096a20012d00f0073a00002001200941016a220b3a00c00a2003200a6b21032008200a6a2108200b2109200b4120470d000b20012903a00a210220012903a80a210420012903b00a210520012903b80a2106200141a00a6a4100418002109f081a200141d00c6a4200370300200141c80c6a4200370300200141c00c6a2006370300200141b80c6a2005370300200141b00c6a2004370300200120023703a80c200141c0003602a00c20012802e0032203417f6a220a450d032003450d04024002402003417e6a220a450d0020012802d8032108200141a00a6a2003417d6a10af062209200a490d012009200a419cb9c8001042000b41a0bac800411c4184bbc8001064000b41a29bc800ad4280808080f00084100122032900002102200329000821042003103541ccbac800ad4280808080800184100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007412010332203450d0a2003200841206a20094105746a220a290000370000200341186a200a41186a2208290000370000200341106a200a41106a2209290000370000200341086a200a41086a220b290000370000200141f0076aad42808080808004842003ad4280808080800484100220031035200141f0076a41086a410a3a0000200141f9076a200a29000037000020014181086a200b29000037000020014189086a200929000037000020014191086a2008290000370000200141123a00f00741b0b4cc004100200141f0076a10d4010c010b41a29bc800ad4280808080f00084100122032900002102200329000821042003103541ccbac800ad4280808080800184100122032900002105200329000821062003103520012006370288082001200537028008200120043702f807200120023702f007200141f0076aad428080808080048410070b024020012802dc0341ffffff3f71450d0020012802d80310350b200141f0076a41186a22094200370300200141f0076a41106a22034200370300200141f0076a41086a220a4200370300200142003703f00741d1c4c700ad4280808080e00084100122082900002102200a200841086a290000370300200120023703f0072008103541edc4c700ad4280808080a00184100122082900002102200141a00a6a41086a220b200841086a290000370300200120023703a00a20081035200320012903a00a2202370300200141f0056a41086a200a290300370300200141f0056a41106a2002370300200141f0056a41186a200b290300370300200120012903f0073703f005200141a00a6a200141f0056a412010d50120012d00a00a21082009200141b90a6a2900003703002003200141b10a6a290000370300200a200141a90a6a290000370300200120012900a10a3703f0070240024020084101460d0020014190076a41186a420037030020014190076a41106a420037030020014190076a41086a420037030020014200370390070c010b20014190076a41186a200929030037030020014190076a41106a200329030037030020014190076a41086a200a290300370300200120012903f007370390070b200141f0076a41186a22094200370300200141f0076a41106a220b4200370300200141f0076a41086a22084200370300200142003703f0074182e9ca00ad42808080808003841001220a29000021022008200a41086a290000370300200120023703f007200a1035419ae9ca00ad4280808080e001841001220a2900002102200141a00a6a41086a2212200a41086a290000370300200120023703a00a200a1035200320012903a00a370000200341086a2012290300370000200141f0056a41086a2008290300370300200141f0056a41106a200b290300370300200141f0056a41186a2009290300370300200120012903f0073703f005200141d8066a200141f0056a412010b502024002400240024020012802d806220a0d0041002103200141003602c005200142013703b805200920014190076a41186a290300370300200b20014190076a41106a290300370300200820014190076a41086a29030037030020012001290390073703f007200141f0076a21080c010b200120012902dc0622023702bc052001200a3602b8052002a7210b02402002422088a7220341d100490d00200141a00a6a41186a220920014190076a41186a290300370300200141a00a6a41106a221220014190076a41106a290300370300200141a00a6a41086a220e20014190076a41086a29030037030020012001290390073703a00a2000417f6a41d10070220820034f0d07200a20084105746a220820012903a00a370000200841186a2009290300370000200841106a2012290300370000200841086a200e2903003700000c030b200141f0076a41186a20014190076a41186a290300370300200141f0076a41106a20014190076a41106a290300370300200141f0076a41086a20014190076a41086a29030037030020012001290390073703f007200141f0076a21082003200b470d010b200141b8056a20034101108a0120012802bc05210b20012802b805210a20012802c00521030b200a20034105746a22092008290000370000200941186a200841186a290000370000200941106a200841106a290000370000200941086a200841086a2900003700002001200341016a22033602c0050b200141a00a6a41186a4200370300200141a00a6a41106a22124200370300200141a00a6a41086a22084200370300200142003703a00a4182e9ca00ad42808080808003841001220929000021022008200941086a290000370300200120023703a00a20091035419ae9ca00ad4280808080e00184100122092900002102200141f0056a41086a220e200941086a290000370300200120023703f00520091035201220012903f0052202370300200141f0076a41086a2008290300370300200141f0076a41106a2002370300200141f0076a41186a200e290300370300200120012903a00a3703f00702400240200a0d00200141f0076aad428080808080048410070c010b200141203602a40a2001200141f0076a3602a00a200a2003200141a00a6a10c504200b41ffffff3f71450d00200a10350b4200211e200141a00a6a41186a220b4200370300200141a00a6a41106a220a4200370300200141a00a6a41086a22034200370300200142003703a00a41f7edcb00ad4280808080f000841001220829000021022003200841086a290000370300200120023703a00a2008103541b6aac000ad4280808080900284100122082900002102200141f0056a41086a2209200841086a290000370300200120023703f00520081035200a20012903f0052202370300200141f0076a41086a22082003290300370300200141f0076a41106a22122002370300200141f0076a41186a220e2009290300370300200120012903a00a3703f007200141a8036a200141f0076a10f20120012802a803417d710d07200b4200370300200a420037030020034200370300200142003703a00a41a2e8cb00ad428080808080018422061001220f29000021022003200f41086a290000370300200120023703a00a200f103541e6f2c400ad428080808080028422071001220f29000021022009200f41086a290000370300200120023703f005200f1035200a20012903f005370000200a41086a2009290300370000200820032903003703002012200a290300370300200e200b290300370300200120012903a00a3703f007200141a00a6a200141f0076a10c602200120012802a00a2203410420031b221f3602900720012902a40a420020031b2205422088a7220e450d064100210a201f21034100210803400240024002402003280200200341086a22092802002003410c6a280200200341146a280200200341186a220b28020010fd01450d00200a0d014100210a0c020b200a41016a210a0c010b2008200a6b2212200e4f0d06200141a00a6a41186a220f2003200a41646c6a221241186a2210280200360200200141a00a6a41106a2211201241106a2213290200370300200141a00a6a41086a2214201241086a2215290200370300200120122902003703a00a20092902002102200341106a22162902002104200b280200211720122003290200370200201020173602002013200437020020152002370200200b200f2802003602002016201129030037020020092014290300370200200320012903a00a3702000b2003411c6a2103200e200841016a2208460d060c000b0b200a200341b89dcc001059000b4101410041f4bac8001059000b200a410041f4bac8001058000b2008200341f0e9ca001042000b2012200e41f485cc001042000b200a450d00200e200a490d00201f200e200a6b220e411c6c6a200a10c802200542ffffffff0f8321050b2001280290072103200141a00a6a41186a4200370300200141a00a6a41106a22094200370300200141a00a6a41086a220a4200370300200142003703a00a2006100122082900002102200a200841086a290000370300200120023703a00a200810352007100122082900002102200141f0056a41086a220b200841086a290000370300200120023703f00520081035200920012903f0052202370300200141f0076a41086a200a290300370300200141f0076a41106a2002370300200141f0076a41186a200b290300370300200120012903a00a3703f007024020030d00200141f0076aad428080808080048410070c010b2005a7210a200141a00a6a2003200e10c704200141f0076aad428080808080048420013502a80a42208620012802a00a2208ad841002024020012802a40a450d00200810350b2003200e10c802200a450d00200a411c6c450d00200310350b024020004180e101700d00200142f0f2bda1a7ee9cb9f9003703a00a200141f0076a200141a00a6a10e001200141f0056a200141f0076a108e02200141a00a6a20012802f005220a20012802f805108f02200141a00a6a41106a2217290300420020012903a00a42015122031b210420012903a80a420020031b2102024020012802f405450d00200a10350b2001420020042002428080e983b1de1654ad7d2205200242808097fccea1697c22062002562005200456200242ffffe883b1de16561b22031b22023703880520014200200620031b220437038005200141a00a6a41186a221f200237030020172004370300200141a00a6a41086a220f41013a00002001410c3a00a00a41b0b4cc004100200141a00a6a10d401200141003a00a004200142003703c005200142003703b805201f420037030020174200370300200f4200370300200142003703a00a4186f0cb00ad4280808080800184221a100122032900002102200141f0056a41086a2214200341086a290000370300200120023703f00520031035200f2014290300370300200120012903f0053703a00a419bf0cb00ad4280808080900184221c1001220329000021022014200341086a290000370300200120023703f00520031035201720012903f0052202370300200141f0076a41086a2211200f290300370300200141f0076a41106a2002370300200141f0076a41186a22162014290300370300200120012903a00a3703f007200141a00a6a200141f0076a10c50220012802a00a2203410420031b2120024020012902a40a420020031b2219422088220da72210450d00200141a90a6a210b200141b0086a211220014190086a2113200141d80a6a2115200141b8076a2121202021034100210a410021080240034020014190076a2003280200220e10b506200141a00a6a200128029007220920012802980710df0220012903a00a2104200141f0076a200f41e000109d081a42002102024020044201520d00200141f0056a200141f0076a41e000109d081a420121020b0240200128029407450d00200910350b024002400240200250450d00200a41016a210a0c010b200141f0076a200141f0056a41e000109d081a0240200129038005220520012903f007220654220920014180056a41086a2903002202201129030022045420022004511b0d002001200520067d370380052001200220047d2009ad7d37038805200141a00a6a200e10b50620013502a80a42208620012802a00a2209ad841007024020012802a40a450d00200910350b20012903800821022001201629030022043703e006200120023703d80602402002200484500d00200120133602c00420014190076a2013200141d8066a200141c0046a10f0022001290390074201520d002001290398072102201520014190076a41106a290300370300200b2013290000370000200b41086a201341086a290000370000200b41106a201341106a290000370000200b41186a201341186a290000370000200120023703d00a200141003a00a80a200141033a00a00a41b0b4cc004100200141a00a6a10d4010b20012903f00721022001201129030022043703e006200120023703d80602400240200220048450450d00420021054200210642002104420021070c010b200120123602c00420014190076a2012200141d8066a200141c0046a10b002024002402001290390074201520d0020014190076a41106a290300210720012903980721040c010b2021290300210720012903b00721042001290398074201520d0020012903a0072102201520014190076a41186a290300370300200b2012290000370000200b41086a201241086a290000370000200b41106a201241106a290000370000200b41186a201241186a290000370000200120023703d00a200141003a00a80a200141033a00a00a41b0b4cc004100200141a00a6a10d4010b2011290300210620012903f00721050b200141b8056a41086a2209427f2009290300220220077c20012903b805220720047c220c2007542209ad7c22042009200420025420042002511b22091b3703002001427f200c20091b3703b80520152006370300200b2012290000370000200b41086a201241086a290000370000200b41106a201241106a290000370000200b41186a201241186a290000370000200120053703d00a200141023a00a80a2001410c3a00a00a2001200e3602cc0a41b0b4cc004100200141a00a6a10d401200a41016a210a0c010b200141013a00a0040240200a0d004100210a0c010b2008200a6b220920104f0d012003200a4102746b2209280200210e200920032802003602002003200e3602000b200341046a21032010200841016a2208460d020c010b0b2009201041f485cc001042000b200a417f6a20104f0d00201942ffffffff0f8321192010200a6b21100b201f4200370300200141a00a6a41106a220a4200370300200f4200370300200142003703a00a201a1001220329000021022014200341086a290000370300200120023703f00520031035200f2014290300370300200120012903f0053703a00a201c1001220329000021022014200341086a290000370300200120023703f00520031035201720012903f005370000201741086a20142903003700002011200f290300370300200141f0076a41106a200a2903003703002016201f290300370300200120012903a00a3703f007200141203602a40a2001200141f0076a3602a00a20202010200141a00a6a1095030240201942ffffffff0383500d00202010350b024020012d00a0040d004200210720014198036a200129038005220220014180056a41086a2203290300220442c0843d420010980820014188036a200129039803220520014198036a41086a290300220642c0fb42427f108408200141f8026a2005200642a0c21e4200108408200320042004200141f8026a41086a29030020012903f802220520022001290388037c2206420188220ca7417f200642a0c21e7e2206428080808080c8d007541b2006200c42c0fb427e7c42a0c21e566aad7c2206200554ad7c22052006200256200520045620052004511b220a1b22057d200220022006200a1b220454ad7d3703002001200220047d3703800502400240200420058450450d004200210c0c010b200141f0076a41186a22124200370300200141f0076a41106a220a4200370300200141f0076a41086a22034200370300200142003703f00741b6fdc600ad4280808080800184220210012209290000210620014190076a41086a2208200941086a2900003703002001200637039007200910352003200829030037030020012001290390073703f00741e489c200ad4280808080d0018422061001220b2900002107200141c0046a41086a2209200b41086a290000370300200120073703c004200b1035200a20012903c0042207370300200141d8066a41086a220e2003290300370300200141d8066a41106a220f2007370300200141d8066a41186a22102009290300370300200120012903f0073703d806200141e0026a200141d8066a412010d701200141e0026a41106a290300210720012903e802210c20012802e002210b20124200370300200a420037030020034200370300200142003703f00720021001221229000021022008201241086a2900003703002001200237039007201210352003200829030037030020012001290390073703f00720061001220829000021022009200841086a290000370300200120023703c00420081035200a20012903c0042202370300200e2003290300370300200f200237030020102009290300370300200120012903f0073703d8062001420020074200200b1b220220057d200c4200200b1b2206200454ad7d2207200620047d220c200656200720025620072002511b22031b3703a80a20014200200c20031b3703a00a200141d8066aad4280808080800484200141a00a6aad428080808080028410022002200520031b210c2006200420031b21070b200141b8056a41086a2203427f20032903002202200c7c20012903b805220620077c22072006542203ad7c22062003200620025420062002511b22031b3703002001427f200720031b3703b805200141b80a6a2005370300200141b00a6a2004370300200141a00a6a41086a41043a00002001410c3a00a00a41b0b4cc004100200141a00a6a10d4010b200142f0f2bda1a7ee9cb9f9003703a00a200141f0056a200141a00a6a10e001200141c0056a290300210420012903b805210241002103200141003a00e803200141023a00b004200120043703980720012002370390072001200141f0056a3602c00402400240200220048450450d0042002105420021060c010b2001200141f0056a3602d8062001200141d8066a3602b00a2001200141b0046a3602ac0a2001200141c0046a3602a80a2001200141e8036a3602a40a200120014190076a3602a00a200141f0076a200141f0056a200141a00a6a10dc0341012103024020012802f0074101470d004200210620012903f80721050c010b20014198086a290300210620014190086a29030021054100210320012903f8074201520d00200141f0076a41106a290300210720012802d806210a200141d80a6a200141f0076a41186a290300370300200141d00a6a200737030041002103200141a00a6a41086a41003a0000200141a90a6a200a290000370000200141b10a6a200a41086a290000370000200141b90a6a200a41106a290000370000200141c10a6a200a41186a290000370000200141033a00a00a41b0b4cc004100200141a00a6a10d4010b024002400240024020030d00200141f0076a41186a220b4200370300200141f0076a41106a22034200370300200141f0076a41086a220a4200370300200142003703f00741b6fdc600ad4280808080800184221a10012209290000210720014190076a41086a2208200941086a290000370300200120073703900720091035200a200829030037030020012001290390073703f00741e489c200ad4280808080d00184221c100122122900002107200141c0046a41086a2209201241086a290000370300200120073703c00420121035200320012903c0042207370300200141d8066a41086a2212200a290300370300200141d8066a41106a220e2007370300200141d8066a41186a220f2009290300370300200120012903f0073703d806200141b0026a200141d8066a412010d701200420067d2002200554ad7d200620047d2005200254ad7d20052002582006200458200620045122101b22111b211d200220057d200520027d20111b2119200141b0026a41106a290300420020012802b00222111b210720012903b802420020111b210c2005200256200620045620101b0d01200b420037030020034200370300200a4200370300200142003703f007201a1001221029000021022008201041086a290000370300200120023703900720101035200a200829030037030020012001290390073703f007201c1001220829000021022009200841086a290000370300200120023703c00420081035200320012903c004370000200341086a20092903003700002012200a290300370300200e2003290300370300200f200b290300370300200120012903f0073703d8062001427f2007201d7c200c20197c2204200c542203ad7c22022003200220075420022007511b22031b3703a80a2001427f200420031b3703a00a200141a00a6a21030c020b4184b8c800ad4280808080a009841006200141f0076a41186a22124200370300200141f0076a41106a220a4200370300200141f0076a41086a22034200370300200142003703f00741b6fdc600ad4280808080800184220510012209290000210620014190076a41086a2208200941086a2900003703002001200637039007200910352003200829030037030020012001290390073703f00741e489c200ad4280808080d0018422061001220b2900002107200141c0046a41086a2209200b41086a290000370300200120073703c004200b1035200a20012903c0042207370300200141d8066a41086a220e2003290300370300200141d8066a41106a220f2007370300200141d8066a41186a22102009290300370300200120012903f0073703d806200141c8026a200141d8066a412010d701200141c8026a41106a290300210720012903d002210c20012802c802210b20124200370300200a420037030020034200370300200142003703f00720051001221229000021052008201241086a2900003703002001200537039007201210352003200829030037030020012001290390073703f00720061001220829000021052009200841086a290000370300200120053703c00420081035200a20012903c0042205370300200e2003290300370300200f200537030020102009290300370300200120012903f0073703d8062001427f20074200200b1b220520047c200c4200200b1b220420027c22062004542203ad7c22022003200220055420022005511b22031b3703a80a2001427f200620031b3703a00a200141d8066aad4280808080800484200141a00a6aad428080808080028410020c020b200b420037030020034200370300200a4200370300200142003703f007201a1001221029000021022008201041086a290000370300200120023703900720101035200a200829030037030020012001290390073703f007201c1001220829000021022009200841086a290000370300200120023703c00420081035200320012903c004370000200341086a20092903003700002012200a290300370300200e2003290300370300200f200b290300370300200120012903f0073703d806200142002007201d7d200c201954ad7d2202200c20197d2204200c56200220075620022007511b22031b3703a80a20014200200420031b3703a00a200141a00a6a21030b200141d8066aad42808080808004842003ad428080808080028410020b2001290380052102200141b80a6a20014180056a41086a290300370300200141b00a6a2002370300200141a00a6a41086a41053a00002001410c3a00a00a41b0b4cc004100200141a00a6a10d401200d42c097e8b2017e200d4280bfdf80017e7c4280e59af7007c211e0b024020180d0010a1020b02400240200041809c3170450d00200141a00a6a21090c010b200141f0056a41186a4200370300200141f0056a41106a22094200370300200141f0056a41086a220a4200370300200142003703f00541d9e3cb00ad428080808090018410012208290000210220014190076a41086a2203200841086a290000370300200120023703900720081035200a200329030037030020012001290390073703f00541efe3cb00ad4280808080d002841001220829000021022003200841086a29000037030020012002370390072008103520092001290390072202370300200141a00a6a41086a200a290300370300200141a00a6a41106a2002370300200141a00a6a41186a2003290300370300200120012903f0053703a00a024002400240024002400240200141a00a6a10bd02220341ff01714102460d00200141a00a6aad4280808080800484100720034101710d010b200141a00a6a200010e70420012d00a00a4104460d02200141f0076a200010ea040c010b200141a00a6a200010ea0420012d00a00a4104460d01200141f0076a200010e7040b20012d00f0074104460d01200141a00a6a411610e8040c020b200141043a00f0070b200141043a00a00a0b200141a00a6a21090b200120003602b805200141f0056a41186a22124200370300200141f0056a41106a2208420037030041082113200141f0056a41086a220a4200370300200142003703f00541d9e3cb00ad428080808090018422021001220b290000210420014190076a41086a2203200b41086a2900003703002001200437039007200b1035200a200329030037030020012001290390073703f00541e2e3cb00ad4280808080d001841001220b29000021042003200b41086a2900003703002001200437039007200b103520082001290390072204370300200141a00a6a41086a220e200a290300370300200141a00a6a41106a220f2004370300200141a00a6a41186a22102003290300370300200120012903f0053703a00a200141a8026a2009412010c00120012802ac02211120012802a80221142012420037030020084200370300200a4200370300200142003703f00520021001220b29000021022003200b41086a2900003703002001200237039007200b1035200a200329030037030020012001290390073703f00541cae3cb00ad4280808080f001841001220b29000021022003200b41086a2900003703002001200237039007200b103520082001290390072202370300200e200a290300370300200f200237030020102003290300370300200120012903f0053703a00a200141a0026a2009412010c0014100210e200120012802a402410020012802a0021b3602dc0620012011410020141b3602d8062001200141b8056a3602e006200141a00a6a200141d8066a200141d8066a41086a10b6060240024020012d00800b220a4103460d00200141f0076a200141a00a6a41e000109d081a2001200141a00a6a41e4006a2800003600b304200120012800810b3602b00441e80010332213450d022013200141f0076a41e000109d082203200a3a0060200320012802b004360061200341e4006a20012800b3043600002001428180808010370294072001200336029007200141f0056a41086a220b200141d8066a41086a280200360200200120012903d8063703f005200141a00a6a200141f0056a200b10b606024020012d00800b22094103470d004101210a4101210e0c020b41c9012108200141810b6a221241036a210f4101210e4101210a0340200141f0076a200141a00a6a41e000109d081a2001200f2800003600b304200120122800003602b004200141a00a6a200141f0076a41e000109d081a200120012800b30436008305200120012802b004360280050240200a200e470d0020014190076a200e410110960120012802900721130b201320086a2203419f7f6a200141a00a6a41e000109d081a2003417f6a20093a00002003200128028005360000200341036a2001280083053600002001200a41016a220a36029807200141a00a6a200141f0056a200b10b606200841e8006a2108200128029407210e20012d00800b22094103470d000c020b0b4100210a0b0240200a450d002013200a41e8006c6a2115200141f0076a41096a2118200141f0076a41106a2109200141a8066a2114200141a00a6a41086a2120200141a00a6a410172211f200141c9066a210f20014190076a41046a211641b6fdc600ad4280808080800184212220014198066a21172013210803402008280200210b200141a00a6a200841046a41dc00109d081a2001200841e1006a2800003602f0072001200841e4006a2800003600f307200841e0006a2d000022124103460d0120014190076a200141a00a6a41dc00109d081a200120012800f3073600eb03200120012802f0073602e803200141f0056a201641d800109d081a200f20012802e803360000200f41036a20012800eb03360000200120123a00c806200141f0076a41186a2210420037030020094200370300200141f0076a41086a22034200370300200142003703f00720221001220a29000021022003200a41086a290000370300200120023703f007200a103541e489c200ad4280808080d001841001220a2900002102200141c0046a41086a2211200a41086a290000370300200120023703c004200a1035200920012903c004370000200941086a2011290300370000200141d8066a41086a2003290300370300200141d8066a41106a2009290300370300200141d8066a41186a2010290300370300200120012903f0073703d80620014188026a200141d8066a412010d70120014188026a41106a2903002105200128028802210a2001290390022106200141f0056a41186a2903002123200141f0056a41086a290300211b41002103200129038006211d20012903f005211c0240200129039006220d4202882017290300220c423e86842202200c420288220484500d002002200d852004200c8584500d00410021030340200141f8016a200d200c200341046a41fe007110a408200341026a210320012903f8012202200141f8016a41086a290300220484500d012002200d852004200c85844200520d000b0b200841e8006a210820054200200a1b211920064200200a1b211a42002106420021040340200141d8016a20044201862006423f8884220442002006420186220642018422024200108408200141e8016a20024200200242001084080240200420012903e001220584200584420052200141e8016a41086a290300220520012903d801220720077c7c2207200554720d0020012903e8012105200141c8016a200d200c200341ff007110a40820042004200520012903c801562007200141c8016a41086a29030022055620072005511b220a1b210420062002200a1b21060b02402003450d0041002003417e6a220a200a20034b1b21030c010b0b410021030240201a4202882019423e868422022019420288220584500d002002201a85200520198584500d00410021030340200141b8016a201a2019200341046a41fe007110a408200341026a210320012903b8012202200141b8016a41086a290300220584500d012002201a852005201985844200520d000b0b4200210542002102034020014198016a20024201862005423f8884220242002005420186220542018422074200108408200141a8016a20074200200742001084080240200220012903a001220c84200c84420052200141a8016a41086a290300220c200129039801220d200d7c7c220d200c54720d0020012903a801210c20014188016a201a2019200341ff007110a40820022002200c20012903880156200d20014188016a41086a290300220c56200d200c511b220a1b210220052007200a1b21050b02402003450d0041002003417e6a220a200a20034b1b21030c010b0b024002400240024002402006200484500d0002400240024020120e03000102000b0340200141386a201d2023200620041098082005220c2002220d844200510d04200141386a41086a290300210220012903382105200141286a201c201b200c200d109808200520012903282219542002200141286a41086a290300220754200220075122031b0d062019200554200720025420031b0d03200141186a2005200220062004108408200141086a20192007200c200d108408201c200129030822027d2207201b200141086a41086a2903007d201c200254ad7d220284500d032023200141186a41086a2903007d2119201d20012903182205542103201d20057d21052006211c2004211b2007210620022104200c211d200d2123200520192003ad7d22028450450d000c060b0b0340200421072006210c20052002844200510d04200141e8006a201c201b200c2007109808200141f8006a201d2023200520021098082001290378220d2001290368221954200141f8006a41086a2903002204200141e8006a41086a290300220654200420065122031b0d052019200d54200620045420031b0d02200141d8006a200d200420052002108408200141c8006a20192006200c2007108408201c200129034822047d220d201b200141c8006a41086a2903007d201c200454ad7d220484500d022023200141d8006a41086a2903007d2119201d20012903582206542103201d20067d21062005211c2002211b200d210520042102200c211d20072123200620192003ad7d22048450450d000c050b0b201c201d56201b202356201b2023511b0d030b2001200b3602ac0a200141053a00a80a200141063a00a00a4100210341b0b4cc004100200141a00a6a10d4010c030b41d0c7c40041194194c5c800103f000b41d0c7c40041194194c5c800103f000b2001200b3602ac0a200141043a00a80a200141063a00a00a41b0b4cc004100200141a00a6a10d401024002400240024020012802a4062203450d00200141d8066a201410ee04200141a00a6a20012802d806221220012802e006221010d202200320006a210a024020012d00a00a2203410371222141034622110d00024020030e03000100000b0240024020110d0020210e03010001010b20012802c80a450d0020012802c40a10350b201f20012f00b8053b0000201f41026a200141b8056a41026a2d00003a000041002103200141003a00a00a2001200a3602a40a2020200141f0076a41c800109d081a0c020b2001200a3602d80a200141013602d40a20034102470d012010ad4220862012ad8410070c020b200141a00a6a41186a201441186a290000370300200141a00a6a41106a201441106a2900003703002020201441086a290000370300200120142900003703a00a200141f0076a200141a00a6a200b10f4040c020b200141003602f807200142013703f007200141a00a6a200141f0076a10ef0420012802f40721112010ad4220862012ad8420013502f80742208620012802f0072210ad84100202402011450d00201010350b0240200341037122034103460d0020030e03010001010b20012802c80a450d0020012802c40a10350b024020012802dc06450d00201210350b20182014290000370000201841086a201441086a290000370000201841106a201441106a290000370000201841186a201441186a2900003700002001411d3a00f8072001200b36029c08200141093602f007410c10332203450d042003200b360008200342e4cab5fbb6ccdcb0e3003700002001428c808080c0013702dc06200120033602d806200141a00a6a200141d8066a10f004200120012802a00a221020012802a80a41b0b4cc0041004100108a0220012802002112024020012802a40a450d00201010350b024020124101460d00410c10332212450d0520122003290000370000201241086a200341086a280000360000200141a00a6a200141f0076a41b002109d081a2001413f3a00e80c200141003602dc0c2001428c808080c0013702d40c200120123602d00c200a200141a00a6a410110cb04024020012802dc0c4102460d00024020012802d00c2203450d0020012802d40c450d00200310350b200141a00a6a10ba020b200141a00a6a200a10f3042001410020012802a40a417f6a20012802a00a4101461b360284052001200a36028005200141a00a6a200141d8066a10f00420012802a00a2103200120012802a80a3602bc05200120033602b80520014180056a200141b8056a10db01024020012802a40a450d00200310350b20012802dc06450d0120012802d80610350c010b20031035200141f0076a10ba0241b08cc500ad4280808080a0068410060b410121030b200120003602a40a200120033a00a10a200141013a00a00a200141f0076a200b10f50420012802f0072103200120012802f8073602f405200120033602f005200141a00a6a200141f0056a10f604024020012802f407450d00200310350b20082015470d000b0b0240200e450d00200e41e8006c450d00201310350b200010b7062102200141f00c6a2400427f201e20027c22022002201e541b0f0b1045000b41a0bac800411c41bcbac8001064000b2003200a419cb9c8001042000bc30103017f017e027f0240024002402000280200220241024d0d004101210042002103410121020c010b024002400240024020020e03000102000b410110332204450d0441002102200441003a00002000280204210520044101410510372200450d04200020053600014280808080d00021030c030b410110332200450d03200041013a00000c010b410110332200450d02200041023a00000b4100210242808080801021030b200129020020032000ad841002024020020d00200010350b0f0b103c000bd10707017f017e027f017e017f027e037f230041e0006b22032400200341306a2001200210da03024002400240024020032903302204a7220241ff01714101460d00200341306a41186a4200370300200341306a41106a22054200370300200341306a41086a220242003703002003420037033041d1c4c700ad4280808080e000841001220629000021072002200641086a29000037030020032007370330200610354184eec700ad4280808080b00284100122062900002107200341d0006a41086a2208200641086a2900003703002003200737035020061035200520032903502207370300200341106a41086a2002290300370300200341106a41106a2007370300200341106a41186a2008290300370300200320032903303703102003200341106a10e1022003290308420020032802001b210702400240200141ff0171220141024b0d004280b0def7d32b210920010e03010003010b4280c0a8ca9a3a21090b4100210141800c2102200042c0b2cd3b7c220a2000540d032007200a7c22002007540d0320002009560d030c020b200241087641ff017121012004421088a741087421020c020b427f2007427f200042c0b2cd3b7c220920092000541b7c220020002007541b21000b200341306a41186a22084200370300200341306a41106a22064200370300200341306a41086a220242003703002003420037033041d1c4c700ad4280808080e000842207100122052900002109200341d0006a41086a2201200541086a2900003703002003200937035020051035200220012903003703002003200329035037033041b8eec700ad42808080808002841001220529000021092001200541086a2900003703002003200937035020051035200620032903502209370300200341106a41086a220b2002290300370300200341106a41106a220c2009370300200341106a41186a220d20012903003703002003200329033037031020032004422088a7360230200341106aad42808080808004842204200341306aad22094280808080c0008410022008420037030020064200370300200242003703002003420037033020071001220529000021072001200541086a290000370300200320073703502005103520022001290300370300200320032903503703304184eec700ad4280808080b002841001220529000021072001200541086a2900003703002003200737035020051035200620032903502207370300200b2002290300370300200c2007370300200d20012903003703002003200329033037031020032000370330200420094280808080800184100241022101410021020b200341e0006a240020022001720bac0604047f017e017f047e230041d0016b22022400200241a0016a41186a4200370300200241a0016a41106a22034200370300200241a0016a41086a22044200370300200242003703a00141e3efcb00ad4280808080a002841001220529000021062004200541086a290000370300200220063703a0012005103541f5efcb00ad4280808080900284100122052900002106200241c0016a41086a2207200541086a290000370300200220063703c00120051035200320022903c001220637030020024180016a41086a200429030037030020024180016a41106a200637030020024180016a41186a2007290300370300200220022903a0013703800120014280c0a8ca9a3a20014280c0a8ca9a3a541b2101200241e8006a20024180016a10bc020240024020022802680d004100210442002108420021060c010b200229037022084200522205200241e8006a41106a29030022064200552006501b21042006427f550d00428080808080808080807f420020062005ad7c7d20082006428080808080808080807f85845022051b21064200420020087d20051b21080b200241d8006a2008200642808090bbbad6adf00d4200109808200241c8006a20022903582209200241d8006a41086a290300220a428080f0c4c5a9d28f72427f108408200242808090bbbad6adf00d3703a8012002200820022903487c22063703a001200241286a200241a0016a200642808090bbbad6adf00d564103746a290300420020014200108408200241186a20022903282206200241286a41086a290300220842808090bbbad6adf00d4200109808200241086a2002290318220b200241186a41086a290300428080f0c4c5a9d28f72427f108408200241386a2009200a200142001084082000200241386a41086a29030020022903382209200b200620022903087c220a428080c89d9deb96f806562008200241086a41086a2903007c200a200654ad7c22064200522006501bad7c7c2206200954ad7c2208200620017c2209200654ad7c4200420020082001200654ad7c7d2208200120067d220620015620084200522008501b22051b20041b370308200020094200200620051b20041b370300200241d0016a24000b910f05017f017e047f017e067f230041f0016b2201240042002102200141d8006a41186a22034200370300200141d8006a41106a22044200370300200141d8006a41086a22054200370300200142003703584193d1cb00ad4280808080a00184100122062900002107200141c8006a41086a2208200641086a2900003703002001200737034820061035200520082903003703002001200129034837035841d8c7ca00ad4280808080e000841001220629000021072008200641086a2900003703002001200737034820061035200420012903482207370300200141286a41086a22062005290300370300200141286a41106a2007370300200141286a41186a200829030037030020012001290358370328200141f8006a200141286a412010d50120012d00782108200320014191016a290000370300200420014189016a290000370300200520014181016a290000370300200120012900793703580240024020084101470d0020002001290358370000200041186a2003290300370000200041106a2004290300370000200041086a20052903003700000c010b200141f8006a41186a4200370300200141f8006a41106a22094200370300200141f8006a41086a220842003703002001420037037841d1c4c700ad4280808080e000841001220a29000021072008200a41086a29000037030020012007370378200a10354185c5c700ad4280808080e000841001220a29000021072006200a41086a29000037030020012007370328200a103520092001290328220737030020052008290300370300200420073703002003200629030037030020012001290378370358200141f8006a200141d8006a10ce02024002402001280278220a0d004104210a410021050c010b200129027c2202422088a721050b02400240200541246c2205450d002005415c6a2108200a210503400240024020052d00004101460d002008450d030c010b200541016a2800002103200541086a28020021062001200541106a28020036025c200120063602580240200341c28289aa04460d0020080d010c030b200141f8006a200141d8006a10800420012903784203510d02200141f8006a41106a22052802002106200141f8006a41186a420037030020054200370300200141f8006a41086a220842003703002001420037037841a3edcb00ad4280808080f000841001220329000021072008200341086a290000370300200120073703782003103541f393ca00ad4280808080a00184100122032900002107200141286a41086a2209200341086a2900003703002001200737032820031035200520012903282207370300200141d8006a41086a2008290300370300200141d8006a41106a2007370300200141d8006a41186a200929030037030020012001290378370358200141f8006a200141d8006a10fe0120012802782205410120051b21034100210802402006200129027c420020051b2207422088a74f0d00200320064105746a2205450d00200141086a41186a200541186a290000370300200141086a41106a200541106a290000370300200141086a41086a200541086a29000037030020012005290000370308410121080b0240200742ffffff3f83500d00200310350b2008450d02200141f8006a41186a2208200141086a41186a290300370300200141f8006a41106a2203200141086a41106a290300370300200141f8006a41086a2206200141086a41086a29030037030020012001290308370378200141d8006a41186a220b4200370300200141d8006a41106a220c4200370300200141d8006a41086a22094200370300200142003703584193d1cb00ad4280808080a001841001220d2900002107200141c8006a41086a2205200d41086a29000037030020012007370348200d1035200920052903003703002001200129034837035841d8c7ca00ad4280808080e000841001220d29000021072005200d41086a29000037030020012007370348200d103520042001290348370000200441086a2005290300370000200141286a41086a2009290300370300200141286a41106a200c290300370300200141286a41186a200b290300370300200120012903583703280240412010332205450d0020052001290378370000200541186a2008290300370000200541106a2003290300370000200541086a2006290300370000200141286aad42808080808004842005ad4280808080800484100220051035200041186a2008290300370000200041106a2003290300370000200041086a2006290300370000200020012903783700000c040b1045000b200541246a21052008415c6a21080c000b0b20004200370000200041186a4200370000200041106a4200370000200041086a42003700000b02402002422088a72205450d00200541246c2108200a210503400240024020052d0000220341044b0d0002400240024020030e050400010204040b2005410c6a280200450d03200541086a28020010350c030b2005410c6a280200450d02200541086a28020010350c020b2005410c6a280200450d01200541086a28020010350c010b200541086a280200450d00200541046a28020010350b200541246a21052008415c6a22080d000b0b2002a72205450d00200541246c450d00200a10350b200141f0016a24000b8b0101017f41e09dcc00ad4280808080d001841006024002400240024020002d00000e0400010203000b200041046a29020010060f0b41d29dcc00ad4280808080e0018410060f0b41c89dcc00ad4280808080a0018410060f0b20003100011026200041026a31000010260240200041046a2802002201450d00200041086a3502004220862001ad8410060b0b130020004101360204200041a8d0c4003602000b850a03057f017e047f230041a0016b22012400200141e8006a41186a22024200370300200141e8006a41106a22034200370300200141e8006a41086a220442003703002001420037036841a3edcb00ad4280808080f000841001220529000021062004200541086a290000370300200120063703682005103541a5ebcb00ad4280808080c0018410012205290000210620014188016a41086a2207200541086a29000037030020012006370388012005103520032001290388012206370300200141c8006a41086a2004290300370300200141c8006a41106a2006370300200141c8006a41186a200729030037030020012001290368370348200141106a200141c8006a412010c00120012802142105200128021021082002200041186a2900003703002003200041106a2900003703002004200041086a290000370300200120002900003703684188e8cb00ad4280808080800184100122002900002106200141186a41086a200041086a290000370300200120063703182000103541f1c8c400ad4280808080e001841001220029000021062007200041086a29000037030020012006370388012000103520012005410020081b3602382001200141386aad4280808080c00084100322002900003703980120001035200141d4006a22052001413c6a360200200120014198016a41086a220736024c2001200141386a360250200120014198016a360248200141286a200141c8006a107b0240024002400240412010332200450d0020002001290368370000200041186a2002290300370000200041106a2003290300370000200041086a200429030037000020012000ad42808080808004841003220429000037039801200410352005200041206a360200200120003602502001200736024c200120014198016a360248200141386a200141c8006a107b200010352001280230220741206a2202200128024022086a2204417f4c0d01200128023821092001280228210a0240024020040d0041002105410121000c010b200410332200450d01200421050b024002402005410f4d0d00200521030c010b200541017422034110200341104b1b22034100480d03024020050d002003103322000d010c050b20052003460d0020002005200310372200450d040b20002001290318370000200041086a200141186a41086a2903003700000240024020034170714110460d00200321050c010b200341017422054120200541204b1b22054100480d0320032005460d0020002003200510372200450d040b2000200129038801370010200041186a20014188016a41086a29030037000002400240200541606a2007490d00200521030c010b2007415f4b0d03200541017422032002200320024b1b22034100480d0320052003460d0020002005200310372200450d040b200041206a200a2007109d081a02400240200320026b2008490d00200321050c010b20042002490d03200341017422052004200520044b1b22054100480d03024020030d00024020050d00410121000c020b200510332200450d050c010b20032005460d0020002003200510372200450d040b200020026a20092008109d081a0240200128023c450d00200910350b0240200128022c450d00200a10350b200141086a2000200410c0012001200128020c41016a410120012802081b3602682004ad4220862000ad84200141e8006aad4280808080c00084100202402005450d00200010350b200141a0016a24000f0b1045000b1044000b103e000b103c000b340020004188e8cb0036020420004100360200200041146a4104360200200041106a41f4d4c400360200200041086a42083702000b130020004101360204200041d8ddc4003602000b3400200041d1efcb0036020420004100360200200041146a4102360200200041106a4188e5c400360200200041086a42093702000b130020004101360204200041c8e7c4003602000b2d01017f02404108103322020d001045000b20004288808080800137020420002002360200200242dc0b3700000bd50101037f230041106b2203240002400240200241d0026c4104722204417f4c0d00200410332205450d0120034100360208200320043602042003200536020020022003107702402002450d00200241d0026c2102034002400240200141bc026a2802004102470d00200341003a000f20032003410f6a410110780c010b200341013a000f20032003410f6a410110782001200310da040b200141d0026a2101200241b07d6a22020d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1044000b1045000bec0101037f230041106b220224000240024020002802b00222030d00200241003a00072001200241076a41011078200241076a21030c010b200241013a00072001200241076a41011078200041b8026a2802002204200110772001200320041078200241076a21030b200220002d00c8023a000720012003410110782000200110af030240024020002802bc024101460d00200241003a000720012003410110780c010b200241013a000720012003410110782002200041c0026a2802003602082001200241086a410410782002200041c4026a28020036020c20012002410c6a410410780b200241106a24000b6401037f024041094101200128020022024101461b220310332204450d000240024020020d00200441003a0000410121010c010b200441013a000020042001290204370001410921010b2000200136020820002003360204200020043602000f0b1045000bc90202027f017e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d01200441012001105221000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000b20024180016a240020000f0b200341800141c88bc0001059000b200341800141c88bc0001059000b8b0605027f027e017f027e027f230041a0016b220224002000280200210002400240024002400240024002400240200128020022034110710d00200041086a29030021042000290300210520034120710d0220054290ce005441002004501b450d012005a72103412721000c060b200041086a2903002105200029030021044180012100024003402000450d01200241206a20006a417f6a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a210020044204882005423c8684220420054204882205844200520d000b0b20004181014f0d022001410141d88bc0004102200241206a20006a41800120006b105621000c060b41272100200241186a21060340200241106a200520044290ce0042001098082002200229031022072006290300220842f0b17f427f108408200241206a20006a2203417c6a200520022903007ca7220941ffff037141e4006e220a410174419a87c0006a2f00003b00002003417e6a200a419c7f6c20096a41ffff0371410174419a87c0006a2f00003b0000200542ffc1d72f56210320044200522109200450210a2000417c6a2100200721052008210420032009200a1b0d000c040b0b4180012100024003402000450d01200241206a20006a417f6a2005a7410f712203413072200341376a2003410a491b3a00002000417f6a210020054204882004423c8684220520044204882204844200520d000b0b20004181014f0d012001410141d88bc0004102200241206a20006a41800120006b105621000c040b200041800141c88bc0001059000b200041800141c88bc0001059000b2007a721030b02400240200341e3004a0d00200321090c010b200241206a2000417e6a22006a2003200341ffff037141e4006e2209419c7f6c6a41ffff0371410174419a87c0006a2f00003b00000b024002402009410a480d00200241206a2000417e6a22006a2009410174419a87c0006a2f00003b00000c010b200241206a2000417f6a22006a200941306a3a00000b2001410141b0b4cc004100200241206a20006a412720006b105621000b200241a0016a240020000ba50301077f230041106b2202240002400240024002402001410c6a2802002203417f4c0d0020012802042104200128020021050240024020030d0041002106410121070c010b200310332207450d02200321060b0240024020062003490d00200621080c010b200641017422082003200820034b1b22084100480d03024020060d002008103322070d010c050b20062008460d0020072006200810372207450d040b200720042003109d0821062002200141106a10a6032000410c6a2003360200200041086a20083602002000200636020420002005360200200041106a2002290300370200200041186a200241086a280200360200200020012802243602242000200129021c37021c20002001290228370228200041306a200141306a290200370200200041386a200141386a290200370200200041c0006a200141c0006a290200370200200041c8006a200141c8006a290200370200200041d0006a200141d0006a290200370200200041d8006a200141d8006a290200370200200041e0006a200141e0006a290200370200200241106a24000f0b1044000b1045000b103e000b103c000b1300200041023602042000418cecc4003602000b0f00200028020020012002107f41000bfe0101017f230041106b22022400200028020021002002410036020c02400240024002402001418001490d002001418010490d012001418080044f0d0220022001413f71418001723a000e20022001410676413f71418001723a000d20022001410c76410f7141e001723a000c410321010c030b200220013a000c410121010c020b20022001413f71418001723a000d20022001410676411f7141c001723a000c410221010c010b20022001413f71418001723a000f2002200141127641f001723a000c20022001410676413f71418001723a000e20022001410c76413f71418001723a000d410421010b20002002410c6a2001107f200241106a240041000b6301017f230041206b2202240020022000280200360204200241086a41106a200141106a290200370300200241086a41086a200141086a29020037030020022001290200370308200241046a41e88ac500200241086a10432101200241206a240020010ba50502067f017e230041d0006b220424002004200136020c2004200041b0b4cc0020011b3602082004200441086a10c40102400240024002400240024020042802000d0020042802042205200428020c4104762201200120054b1b22004104742201417f4c0d030240024020000d00410821060c010b200110332206450d050b41002101200441003602182004200036021420042006360210024002402005450d00200441306a4104722107410021010340200441306a200441086a10e404200441c0006a41086a2200200741086a28020036020020042007290200370340200428023022084104460d02200441206a41086a2209200028020036020020042004290340370320024020012004280214470d00200441106a20014101109a0120042802102106200428021821010b200620014104746a22002008360200200020042903203702042000410c6a20092802003602002004200141016a22013602182005417f6a22050d000b200428021421000b2006450d01200441306a200220062001200311060020042802302105410110332201450d054201210a200442013702442004200136024020054105470d02200141013a0000200441013602480c030b200428021441ffffffff0071450d00200610350b41b08bc50041f000200441306a41908bc50041a08cc5001046000b200141003a00002004410136024820014101410210372101024020054104470d002001450d04200141003a00012004200136024020044282808080203702444202210a0c010b2001450d03200141013a0001200420013602402004428280808020370244200441306a200441c0006a10e5042004350248210a200428024021010b2001ad422086200a84210a0240200041ffffffff0071450d00200610350b200441d0006a2400200a0f0b1044000b1045000b103c000bd90202047f017e02400240024002400240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a360200200441034b0d0520040e0401020304010b200041043602000f0b024020054104490d00200041003602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b200041043602000f0b024020054108490d0020004101360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b024020054104490d00200041023602002003280001210420012002417b6a3602042001200341056a360200200020043602040f0b200041043602000f0b024020054108490d0020004103360200200329000121062001200241776a3602042001200341096a360200200041086a20063703000f0b200041043602000f0b200041043602000bd70101017f230041106b220224000240024002400240024020002802000e0400010203000b200241003a00082001200241086a41011078200220002802043602082001200241086a410410780c030b200241013a00082001200241086a410110782002200041086a2903003703082001200241086a410810780c020b200241023a00082001200241086a41011078200220002802043602082001200241086a410410780c010b200241033a00082001200241086a410110782002200041086a2903003703082001200241086a410810780b200241106a24000bec0201047f230041306b22042400200441a58ecc00410310500240024002400240024020020d0041002105410121060c010b200210332206450d01200221050b0240024020052002490d00200521070c010b200541017422072002200720024b1b22074100480d02024020050d002007103322060d010c040b20052007460d0020062005200710372206450d030b200620012002109d082105200441146a2002360200200441106a220220073602002004200536020c200441186a41106a22052002290300370300200441186a41086a2207200441086a29030037030020042004290300370318024020002802082202200041046a280200470d00200020024101109101200028020821020b200028020020024105746a22024100360218200220042903183702002002411c6a2003360200200241106a2005290300370200200241086a20072903003702002000200028020841016a360208200441306a24000f0b1045000b103e000b103c000bdd0505047f017e017f017e0a7f230041e0016b22022400200241c0006a41186a22034200370300200241c0006a41106a22044200370300200241c0006a41086a220542003703002002420037034041d9e3cb00ad42808080809001842206100122072900002108200241e0006a41086a2209200741086a29000037030020022008370360200710352005200929030037030020022002290360370340419c8dc500ad4280808080c001841001220729000021082009200741086a2900003703002002200837036020071035200420022903602208370300200241206a41086a22072005290300370300200241206a41106a220a2008370300200241206a41186a220b200929030037030020022002290340370320200241e0006a200241206a10c0020240024020022d008001220c4103470d002000411610e8040c010b200241206aad428080808080048422081007200241086a220d2009290300370300200241106a220e200241e0006a41106a220f290300370300200241186a2210200241e0006a41186a2211290300370300200220022903603703002003420037030020044200370300200542003703002002420037034020061001221229000021062009201241086a2900003703002002200637036020121035200520092903003703002002200229036037034041efe3cb00ad4280808080d002841001221229000021062009201241086a290000370300200220063703602012103520042002290360370000200441086a200929030037000020072005290300370300200a2004290300370300200b200329030037030020022002290340370320200241013a00602008200241e0006aad428080808010841002200941023a0000200241063a006041b0b4cc004100200241e0006a10d40120112010290300370300200f200e2903003703002009200d29030037030020022002290300370360200141809c316a200241e0006a200c4180de3410e904200041043a00000b200241e0016a24000b8e0701047f230041c0006b2202240041f6f2c4002103412421044108210502400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200141ff01710e26000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425000b200241146a410136020020024201370204200241e8d4ca003602002002410436021c200241f0d5ca003602182002200241186a360210200241b0b4cc00104c000b41eaf5c400210341002104410821050c230b41d2dfca002103410f2105410121040c220b41e2f5c400210341022104410821050c210b41daf5c400210341032104410821050c200b41cbf5c4002103410f2105410421040c1f0b41e1dfca00210341112105410521040c1e0b41b8f5c400210341132105410621040c1d0b41a7f5c400210341112105410721040c1c0b419cf5c4002103410b2105410821040c1b0b4192f5c4002103410a2105410921040c1a0b4185f5c4002103410d2105410a21040c190b419bd6ca002103410c2105410b21040c180b41fbf4c4002103410a2105410c21040c170b41eff4c4002103410c2105410d21040c160b41def4c400210341112105410e21040c150b41d3f4c4002103410b2105410f21040c140b41a1dfca00210341102104410821050c130b41cbf4c400210341112104410821050c120b41bcf4c4002103410f2105411221040c110b41abf4c400210341112105411321040c100b419cf4c4002103410f2105411421040c0f0b4191f4c4002103410b2105411521040c0e0b4188f4c400210341092105411621040c0d0b41fef3c4002103410a2105411721040c0c0b41f7f3c400210341072105411821040c0b0b41eef3c400210341092105411921040c0a0b41e5f3c400210341092105411a21040c090b41ddf3c4002103411b2104410821050c080b41d1f3c4002103410c2105411c21040c070b41c0f3c400210341112105411d21040c060b41a7d6ca002103411e2104410821050c050b41b7f3c400210341092105411f21040c040b41a6f3c400210341112105412021040c030b4199f3c4002103410d2105412121040c020b418ff3c4002103410a2105412221040c010b41fef2c400210341112105412321040b20004183143b0100200041086a2005360200200041046a2003360200200041026a20043a0000200241c0006a24000b900707047f017e017f017e017f017e047f230041e0016b22042400200441d8006a41186a22054200370300200441d8006a41106a22064200370300200441d8006a41086a220742003703002004420037035841d9e3cb00ad4280808080900184220810012209290000210a200441c8006a41086a220b200941086a2900003703002004200a370348200910352007200b2903003703002004200429034837035841cae3cb00ad4280808080f00184220a10012209290000210c200b200941086a2900003703002004200c3703482009103520062004290348220c370300200441106a41086a22092007290300370300200441106a41106a220d200c370300200441106a41186a220e200b29030037030020042004290358370310200441086a200441106a412010c001200428020c210f20042802082110200542003703002006420037030020074200370300200442003703582008100122052900002108200b200541086a29000037030020042008370348200510352007200b29030037030020042004290348370358200a100122052900002108200b200541086a290000370300200420083703482005103520062004290348220837030020092007290300370300200d2008370300200e200b290300370300200420042903583703102004200f410020101b220b41016a360258200441106aad4280808080800484200441d8006aad4280808080c0008410022004413f6a4200370000200441376a42003700002004412f6a4200370000200441276a42003700002004411f6a420037000020044200370017200441e1006a22062009290000370000200441e9006a200d290000370000200441f1006a200e290000370000200441f9006a200441106a41206a29000037000020044181016a200441386a29000037000020044188016a420037000020044194016a200336020020044190016a200036020020044198016a2001290000370300200441a0016a200141086a290000370300200441a8016a200141106a290000370300200441b0016a200141186a290000370300200441003a005820042004290010370059200441b8016a20023a0000200441c8006a200b10f50420042802482101200420042802503602dc01200420013602d801200441d8006a200441d8016a10f6040240200428024c450d00200110350b200441e4006a200b360200200620023a0000200741033a0000200441063a005841b0b4cc004100200441d8006a10d401200441e0016a24000bcd1a06057f017e017f017e117f097e23002202210320024180046b4160712202240020024180016a41186a420037030020024180016a41106a2204420037030020024180016a41086a22054200370300200242003703800141d9e3cb00ad4280808080900184100122062900002107200241d8006a41086a2208200641086a290000370300200220073703582006103520052008290300370300200220022903583703800141918dc500ad4280808080b001841001220629000021072008200641086a2900003703002002200737035820061035200420022903582207370300200241386a41086a2005290300370300200241386a41106a2007370300200241386a41186a2008290300370300200220022903800137033820024120360294022002200241386a3602900220024198026a200241386aad42808080808004842209100510c20102400240024002400240200228029802220a0d004100210b0c010b200228029c02210c200220024198026a41086a2802003602ac022002200a3602a802200241306a200241a8026a10c4010240024020022802300d002002280234220d20022802ac02220e41c4006e22082008200d4b1bad42c4007e2207422088a70d042007a72208417f4c0d040240024020080d004104210b0c010b20081033220b450d040b200241003602b8022002200b3602b0022002200841c4006e3602b40202400240200d450d004100210f41002110034002400240200e4104490d00200220022802a802221141046a3602a8022011280000211241002108200241003a00a001200e417c6a21060240024002400240034020062008460d0120024180016a20086a201120086a220541046a2d00003a00002002200541056a3602a8022002200841016a22053a00a0012005210820054120470d000b200241d8006a41186a221320024180016a41186a2214290300370300200241d8006a41106a221520024180016a41106a2216290300370300200241d8006a41086a221720024180016a41086a2218290300370300200220022903800137035841002108200241003a00a001201120056a21192005200e6b41046a210e0340200e20086a450d0220024180016a20086a201920086a221141046a2d00003a00002002201141056a3602a8022002200841016a22113a00a0012006417f6a21062011210820114120470d000b200241c0036a41186a2014290300370300200241c0036a41106a2016290300370300200241c0036a41086a2018290300370300200241e0036a41086a2017290300370300200241e0036a41106a2015290300370300200241e0036a41186a201329030037030020022002290380013703c003200220022903583703e003200620056b210e410021082012211a0c050b200841ff0171450d020c010b200841ff0171450d010b200241003a00a0010b4100210e0b410121080b200241a0036a41186a2205200241e0036a41186a290300370300200241a0036a41106a2206200241e0036a41106a290300370300200241a0036a41086a2211200241e0036a41086a29030037030020024180036a41086a2219200241c0036a41086a29030037030020024180036a41106a2212200241c0036a41106a29030037030020024180036a41186a2213200241c0036a41186a290300370300200220022903e0033703a003200220022903c0033703800320080d02201041016a2110200241e0026a41186a22142005290300370300200241e0026a41106a22052006290300370300200241e0026a41086a22062011290300370300200241c0026a41086a22112019290300370300200241c0026a41106a22192012290300370300200241c0026a41186a22122013290300370300200220022903a0033703e00220022002290380033703c0020240200f20022802b402470d00200241b0026a200f4101109f0120022802b002210b20022802b802210f0b200b200f41c4006c6a2208201a360200200820022903e0023702042008410c6a2006290300370200200841146a20052903003702002008411c6a2014290300370200200820022903c0023702242008412c6a2011290300370200200841346a20192903003702002008413c6a20122903003702002002200f41016a220f3602b8022010200d470d000b2002200e3602ac020b20022902b4022107200b450d010c020b2002200e3602ac02024020022802b4022208450d00200841c4006c450d00200b10350b0b4100210b2002410036026020024201370358200241093602e403200220024190026a3602e0032002200241d8006a3602c00320024194016a41013602002002420137028401200241c888c200360280012002200241e0036a36029001200241c0036a41e88ac50020024180016a10431a20023502604220862002350258841006200228025c450d00200228025810350b200c450d00200a10350b200b4104200b1b2110024020074200200b1b221b422088a7220b450d00200241186a201028020010eb04200241186a41106a2903004200200228021822081b21072002290320420020081b211c0240200b4101470d002002201c3703800141002111200241003602900120022007370388010c040b201041c4006a2108200b41c4006c41bc7f6a210e41002111200241106a21192010210f4101210603402002200828020010eb04200720192903004200200228020022051b221d201c2002290308420020051b221e562007201d562007201d511b22051b2107201c201e20051b211c200f200820051b210f2011200620051b2111200641016a2106200841c4006a2108200e41bc7f6a220e0d000b2002201c3703800120022011360290012002200737038801200f0d030b2000411610e8040240201ba72202450d00200241c4006c450d00201010350b200324000f0b1045000b1044000b02402011200b4f0d002010201141c4006c6a220841186a2206290200211c2010200b417f6a221141c4006c6a220541c0006a280200210f200541206a290200211d200541286a290200211e200541306a290200211f200541386a29020021202005290200212120052902082107200529021021222006200541186a290200370200200829021021232008202237021020082902082122200820073702082008290200210720082021370200200841386a2020370200200841306a201f370200200841286a201e370200200841206a2205280200210b2005201d370200200841c0006a200f3602002002202337039001200220223703880120022007370380012002201c37039801200241e0036a41186a200228029c01360200200241e0036a41106a200229029401370300200241e0036a41086a200229028c0137030020022002290284013703e00320024180016a41186a220f420037030020024180016a41106a220e420037030020024180016a41086a22054200370300200242003703800141d9e3cb00ad428080808090018410012206290000211c200241d8006a41086a2208200641086a2900003703002002201c3703582006103520052008290300370300200220022903583703800141918dc500ad4280808080b0018410012206290000211c2008200641086a2900003703002002201c3703582006103520042002290358370000200441086a2008290300370000200241386a41086a2005290300370300200241386a41106a200e290300370300200241386a41186a200f290300370300200220022903800137033820024180016a2010201110ec0420092002350288014220862002280280012208ad8410020240200228028401450d00200810350b2007a7210e0240201ba72208450d00200841c4006c450d00201010350b200241d8006a200e10ed0420024180016a200228025822082002280260220510cc020240200228029001220f450d002005ad4220862008ad8410070b20024188016a290300210720024198016a2802002119200229038001211c20022802940121100240200228025c450d00200810350b0240200f450d0002402019410574450d00201c200784500d0020024189016a210520194105742106200241b8016a2111200f210803402002201c3703c003200220073703c803200220083602a003200241d8006a2008200241c0036a200241a0036a10f002024020022903584201520d002002290360211d200841186a290000211e200841106a290000211b200841086a29000021092008290000211f2011200241d8006a41106a2903003703002005201f370000200541086a2009370000200541106a201b370000200541186a201e370000200241003a008801200241033a0080012002201d3703b00141b0b4cc00410020024180016a10d4010b200841206a2108200641606a22060d000b0b200241a8016a2007370300200241a0016a201c37030020024180016a41186a2208201936020020024194016a201036020020024180016a41106a2205200f3602002002418c016a200e36020020024180016a41086a220641013a0000200241063a00800141b0b4cc00410020024180016a10d4012008200241e0036a41186a2802003602002005200241e0036a41106a2903003703002006200241e0036a41086a290300370300200220022903e003370380012002200b36029c01200141809c316a20024180016a41004180de3410e9040b200041043a0000200324000f0b2011200b104a000bcf0102037f047e230041c0006b22022400200241306a200110ed04200241106a20022802302203200228023810cc02200228023421010240024020022802202204450d00200241186a2903002105200229031021062002290224210702402001450d00200310350b20022006200520074220884200108408200241086a29030021054201210620022903002108200742ffffff3f83500d01200410350c010b02402001450d00200310350b420021060b2000200837030820002006370300200041106a2005370300200241c0006a24000bc006010a7f230041106b220324000240024002400240200241c4006c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b20034100360208200320053602002003200436020420022003107702402002450d002001200241c4006c6a2106200328020421022003280208210403402001280200210702400240200220046b4104490d0020032802002105200221080c010b200441046a22052004490d05200241017422082005200820054b1b22084100480d050240024020020d00024020080d00410121050c020b2008103322050d010c080b2003280200210520022008460d0020052002200810372205450d070b20032008360204200320053602000b200520046a20073600002003200441046a2209360208412010332202450d03200241186a220a2001411c6a290000370000200241106a220b200141146a290000370000200241086a220c2001410c6a2900003700002002200141046a29000037000002400240200820096b4120490d00200441246a2104200821070c010b200941206a22042009490d05200841017422072004200720044b1b22074100480d050240024020080d00024020070d00410121050c020b200710332205450d080c010b20082007460d0020052008200710372205450d070b20032007360204200320053602000b200520096a22082002290000370000200841186a200a290000370000200841106a200b290000370000200841086a200c290000370000200320043602082002103502400240200720046b411f4d0d00200721020c010b200441206a22022004490d05200741017422082002200820024b1b22024100480d050240024020070d00024020020d00410121050c020b200210332205450d080c010b20072002460d0020052007200210372205450d070b20032002360204200320053602000b200520046a2205200141246a290000370000200541186a2001413c6a290000370000200541106a200141346a290000370000200541086a2001412c6a2900003700002003200441206a2204360208200141c4006a22012006470d000b0b20002003290300370200200041086a200341086a280200360200200341106a24000f0b1044000b1045000b103e000b103c000bfc0403027f017e057f230041d0006b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541f2f8c400ad4280808080900184100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000b9f0303027f017e027f230041206b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003103541888dc500ad4280808080900184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b880202037f017e230041106b220224000240024020002d00004101460d00200241003a000020012002410110782002200041046a28020036020020012002410410780c010b200241013a00002001200241011078200041246a28020021032000412c6a28020022042001107720012003200410782001200041016a41201078200041c0006a29030021052002200041c8006a2903003703082002200537030020012002411010782002200041306a28020036020020012002410410780240200041346a2802004101460d00200241003a000020012002410110780c010b200241013a000020012002410110782002200041386a28020036020020012002410410780b200241106a24000ba50403027f017e057f230041306b220224004189fec600ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003103541b489c500ad4280808080e00084100122032900002104200241106a41086a200341086a2900003703002002200437031020031035200241206a2001280200200128020810980302400240024002402002280228220541206a2206417f4c0d00200228022021070240024020060d0041002103410121010c010b200610332201450d02200621030b024002402003410f4d0d00200321080c010b200341017422084110200841104b1b22084100480d03024020030d002008103322010d010c050b20032008460d0020012003200810372201450d040b20012002290300370000200141086a200241086a2903003700000240024020084170714110460d00200821030c010b200841017422034120200341204b1b22034100480d0320082003460d0020012008200310372201450d040b20012002290310370010200141186a200241106a41086a29030037000002400240200341606a2005490d00200321080c010b200541206a22082005490d03200341017422092008200920084b1b22084100480d0320032008460d0020012003200810372201450d040b200141206a20072005109d081a20002006360208200020083602042000200136020002402002280224450d00200710350b200241306a24000f0b1044000b1045000b103e000b103c000bd60201027f024002402002450d002002417f6a21040240024020012d0000220241037122054103460d0002400240024020050e03000102000b200241027621020c030b2004450d0320012d0001410874200272220241ffff0371418002490d03200241fcff037141027621020c020b20044103490d0220012f0001200141036a2d000041107472410874200272220241808004490d02200241027621020c010b200241034b0d0120044104490d0120012800012202418080808004490d010b200220036a22012002490d0141012103410121050240200241c000490d0041022105200241808001490d00410441052002418080808004491b21050b0240200141c000490d0041022103200141808001490d00410441052001418080808004491b21030b20002001360204200041003602002000410c6a2003360200200041086a20053602000f0b200041013602000f0b200041013602000ba40301027f230041e0006b22032400200341003a00050240024002400240200041c000490d00200041808001490d012000418080808004490d0241052104200341053a0005200341033a0000200320003600010c030b41012104200341013a0005200320004102743a00000c020b41022104200341023a0005200320004102744101723b01000c010b41042104200341043a0005200320004102744102723602000b024002402001280200220028020822012002490d0020002802002100200320023602082003200436020c20042002470d01200020032002109d081a200341e0006a24000f0b2002200141ccc8ca001058000b200341286a41146a410a360200200341346a410c360200200341106a41146a41033602002003200341086a36024020032003410c6a360244200341c8006a41146a410036020020034203370214200341a0b3cc003602102003410c36022c200341b0b4cc003602582003420137024c200341f4b3cc003602482003200341286a3602202003200341c8006a3602382003200341c4006a3602302003200341c0006a360228200341106a41b0b4cc00104c000bad0301087f230041c0006b22022400200241106a200110c904200241206a200235021842208620022802102203ad84100510c20102400240200228022022040d002002410036023820024208370330200241306a4100410010a701200228023841d0026c220141d0026d2105200228023421062002280230210702402001450d00200541d0026c21082007210103400240200141bc026a2802004102460d000240200141b0026a2802002209450d00200141b4026a280200450d00200910350b200110bb020b200141d0026a2101200841b07d6a22080d000b0b02402006450d00200641d0026c450d00200710350b4100210120004100360200200020053602040c010b200228022421082002200241206a41086a28020036023420022004360230200241086a200241306a10c401024002402002280208450d00200041b0b4cc00360204200041086a4100360200410121010c010b2000200228020c360204410021010b20002001360200410121012008450d00200410350b02402002280214450d00200310350b02402004410047200141017371450d002002280224450d00200410350b200241c0006a24000bd71203077f057e057f230041d0086b22032400200341e0006a200110ee04200341f0056a200328026022042003280268220510d20241022106024020032d00f005220741024622080d002005ad4220862004ad8410070b20034198036a411f6a220520034190066a28000036000020034198036a41186a220920034189066a29000037030020034198036a41106a20034181066a290000220a37030020034198036a41086a200341f9056a290000220b370300200320032900f105220c37039803200341b8066a290300210d200341b0066a290300210e20034194066a280200210f20034198066a28020021102003419c066a2802002111200341f0056a411f6a22122005280000360000200341f0056a41186a22052009290300370300200341f0056a41106a2209200a370300200341f0056a41086a2213200b3703002003200c3703f005024020080d00200341186a411f6a2012280000360000200341186a41186a2005290300370300200341186a41106a2009290300370300200341186a41086a2013290300370300200320032903f005370318200721060b02402003280264450d00200410350b0240024002400240200641037122064103460d0020060e03010001010b200341c0006a41186a200341186a41186a290300370300200341c0006a41106a200341186a41106a290300370300200341c0006a41086a200341186a41086a2903003703002003200329031837034020032011360294032003200f36029003200341e0006a20034190036a10b90202402003280260411b460d0020034198036a200341e0006a41b002109d081a2003200e3703c8052003200d3703d0050240200e200d84500d002003200341c0006a3602a408200341a8086a200341c0006a200341c8056a200341a4086a10f00220032903a8084201520d0020032903b008210a200341a8066a200341a8086a41106a290300370300200341a0066a200a370300200341f0056a41086a41003a0000200341f9056a200329034037000020034181066a200341c0006a41086a29030037000020034189066a200341c0006a41106a29030037000020034191066a200341d8006a290300370000200341033a00f00541b0b4cc004100200341f0056a10d4010b200341f0056a41086a2206410c3a000020034199066a2003290340370000200341f9056a2207200129000037000020034181066a200141086a29000037000020034189066a200141106a29000037000020034191066a200141186a290000370000200341a1066a200341c0006a41086a290300370000200341a9066a200341c0006a41106a290300370000200341b1066a200341c0006a41186a290300370000200341063a00f005200341c8066a200d370300200341c0066a200e37030041b0b4cc004100200341f0056a10d401200341f0056a20034198036a41b002109d081a200341003b01a808200341c8056a200341f0056a200341a8086a10ac0320032903c805210a200341f0056a410c6a20023602002007200a503a0000200641073a0000200341063a00f00541b0b4cc004100200341f0056a10d401200041043a000020100d020c030b2003200e3703a8082003200d3703b0080240024002400240200e200d844200520d00200342003703d005200342003703c8050c010b2003200341c0006a3602c80520034198036a200341c0006a200341a8086a200341c8056a10a802200341b8036a290300210a20032903b003210b02402003290398034201520d0020032903a003210c200341a8066a20034198036a41106a290300370300200341a0066a200c370300200341f0056a41086a41003a0000200341f9056a200329034037000020034181066a200341c0006a41086a29030037000020034189066a200341c0006a41106a29030037000020034191066a200341d8006a290300370000200341033a00f00541b0b4cc004100200341f0056a10d4010b2003200b3703c8052003200a3703d005200b200a844200520d010b200341f0056a41186a22054200370300200341f0056a41106a22044200370300200341f0056a41086a22074200370300200342003703f00541b6fdc600ad4280808080800184220a10012208290000210b200341a8086a41086a2206200841086a2900003703002003200b3703a8082008103520072006290300370300200320032903a8083703f00541e489c200ad4280808080d00184220b10012208290000210c2006200841086a2900003703002003200c3703a80820081035200420032903a808220c37030020034198036a41086a2209200729030037030020034198036a41106a2212200c37030020034198036a41186a22132006290300370300200320032903f00537039803200320034198036a412010d701200341106a290300210c2003290308210d20032802002108200542003703002004420037030020074200370300200342003703f005200a10012205290000210a2006200541086a2900003703002003200a3703a8082005103520072006290300370300200320032903a8083703f005200b10012205290000210a2006200541086a2900003703002003200a3703a80820051035200420032903a808220a370300200920072903003703002012200a37030020132006290300370300200320032903f005370398032003200c420020081b3703f8052003200d420020081b3703f00520034198036aad4280808080800484200341f0056aad428080808080028410020c010b200342f0f2bda1a7ee9cb9f90037039803200341f0056a20034198036a10e001200341f0056a200b200a10df0120034188066a200a37030020034180066a200b370300200341f8056a41063a00002003410c3a00f00541b0b4cc004100200341f0056a10d4010b200341f0056a41086a410d3a0000200341f9056a20012900003700002003419c066a200236020020034181066a200141086a29000037000020034189066a200141106a29000037000020034191066a200141186a290000370000200341063a00f00541b0b4cc004100200341f0056a10d4012000411510e80420100d010c020b200341f0056a41086a410e3a0000200341f9056a20012900003700002003419c066a200236020020034181066a200141086a29000037000020034189066a200141106a29000037000020034191066a200141186a290000370000200341063a00f00541b0b4cc004100200341f0056a10d4012000411310e8040240200741037122014103460d0020010e03020002020b2010450d010b200f10350b200341d0086a24000bfc0403027f017e057f230041d0006b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541fbf8c400ad4280808080800284100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000ba60203027f017e017f230041106b22022400200241003602082002420137030002400240024020002d00004101460d00410110332203450d02200341003a0000200220033602002002428180808010370204200041086a200210a406200235020842208621042002280204452103200228020021000c010b410110332203450d01200341013a000020022003360200200242818080801037020420002d0001210520034101410210372203450d01200320053a00012002200336020020024282808080203702042000280204210520034102410610372200450d01200020053600022002200036020020024286808080e000370204410021034280808080e00021040b200129020020042000ad841002024020030d00200010350b200241106a24000f0b103c000b130020004103360204200041a88dc5003602000b340020004182fec60036020420004100360200200041146a4101360200200041106a41849fc500360200200041086a42073702000b130020004101360204200041aca0c5003602000b3a01017f02404110103322020d001045000b20024200370008200242808084fea6dee111370000200042908080808002370204200020023602000b3400200041a2e8cb0036020420004100360200200041146a4104360200200041106a41c8a1c500360200200041086a42083702000b13002000411d360204200041d8aac5003602000b3400200041d9e3cb0036020420004100360200200041146a410e360200200041106a418c95c600360200200041086a42093702000b4d01027f230041106b220224000240410110332203450d00200341003a0000200041086a4101360200200241013602042002200336020020002002290300370200200241106a24000f0b1045000b7c01017f230041f0006b22022400200241106a4200370300200241186a4200370300200241206a4200370300200241286a4200370300200241306a4200370300200241386a4200370300200241c0006a410036020020024108360204200241086a4200370300200241003a000020002002108005200241f0006a24000b8d1802097f027e230041206b220224002002410036020820024201370300024002400240024020012d00004101460d00410110332203450d032002410136020420022003360200200341003a000020024101360208200141046a28020021042001410c6a2802002203200210770240024020030d0020022802042105200228020821060c010b2004200341306c6a2107200228020421052002280208210603402004280200210802400240200520066b4104490d00200641046a2103200228020021090c010b200641046a22032006490d05200541017422092003200920034b1b220a4100480d050240024020050d000240200a0d00410121090c020b200a103322090d010c080b200228020021092005200a460d0020092005200a10372209450d070b2002200a360204200220093602000b200920066a20083600002002200336020802400240200441086a2d00004101460d00200241003a00100240024020022802042003460d00200228020021050c010b200341016a22052003490d07200341017422062005200620054b1b22064100480d070240024020030d0041002103024020060d00410121050c020b200610332205450d0a0c010b2002280200210520032006460d0020052003200610372205450d090b20022006360204200220053602000b200520036a41003a00002002200341016a22033602082002200441096a2d00004100474107742004410a6a2d00007222063a00100240024020022802042003460d00200228020021050c010b200341016a22052003490d07200341017422092005200920054b1b22094100480d070240024020030d0041002103024020090d00410121050c020b200910332205450d0a0c010b2002280200210520032009460d0020052003200910372205450d090b20022009360204200220053602000b200520036a20063a00002002200341016a2203360208200441106a290300210b2002200441186a2903003703182002200b370310200241106a2109200228020421060c010b200241013a00100240024020022802042003460d00200228020021050c010b200341016a22052003490d06200341017422062005200620054b1b22064100480d060240024020030d0041002103024020060d00410121050c020b200610332205450d090c010b2002280200210520032006460d0020052003200610372205450d080b20022006360204200220053602000b200520036a41013a00002002200341016a2205360208200441186a290300210b200441106a290300210c024002402002280204220920056b4110490d00200341116a210320022802002108200921060c010b200541106a22032005490d06200941017422062003200620034b1b22064100480d060240024020090d00024020060d00410121080c020b200610332208450d090c010b2002280200210820092006460d0020082009200610372208450d080b20022006360204200220083602000b200820056a2205200b3700082005200c37000020022003360208200441206a290300210b2002200441286a2903003703182002200b370310200241106a21090b02400240200620036b4110490d0020022802002108200621050c010b200341106a22052003490d05200641017422082005200820054b1b22054100480d050240024020060d00024020050d00410121080c020b200510332208450d080c010b2002280200210820062005460d0020082006200510372208450d070b20022005360204200220083602000b200820036a22062009290000370000200641086a200941086a2900003700002002200341106a22063602082007200441306a2204470d000b0b200141186a290300210b2001290310210c02400240200520066b4110490d0020022802002103200521040c010b200641106a22032006490d03200541017422042003200420034b1b22044100480d030240024020050d00024020040d00410121030c020b200410332203450d060c010b2002280200210320052004460d0020032005200410372203450d050b20022004360204200220033602000b200320066a2205200b3700082005200c3700002002200641106a2209360208200141286a290300210b200141206a290300210c02400240200420096b410f4d0d00200421050c010b200941106a22052009490d03200441017422082005200820054b1b22054100480d030240024020040d00024020050d00410121030c020b200510332203450d060c010b20042005460d0020032004200510372203450d050b20022005360204200220033602000b200320096a2204200b3700082004200c3700002002200641206a2204360208200141c0006a28020021090240200520046b41034b0d00200441046a22082004490d032005410174220a2008200a20084b1b22084100480d030240024020050d00024020080d00410121030c020b200810332203450d060c010b20052008460d0020032005200810372203450d050b20022008360204200220033602000b200320046a20093600002002200641246a22033602082001290330210b2002200141386a2903003703182002200b370310200241106a21040c010b410110332203450d022002410136020420022003360200200341013a000020024101360208200141306a290300210b200141286a290300210c0240024020022802042205417f6a4110490d0020022802002103200521040c010b200541017422034111200341114b1b22044100480d0220022802002103024020052004460d0020032005200410372203450d040b20022004360204200220033602000b2003200c370001200341096a200b37000020024111360208024002402004416f6a411f4d0d00200421050c010b200441017422054131200541314b1b22054100480d02024020042005460d0020032004200510372203450d040b20022005360204200220033602000b20032001290001370011200341296a200141196a290000370000200341216a200141116a290000370000200341196a200141096a2900003700004131210420024131360208024020012d0021220641064b0d000240024002400240024002400240024020060e0700010203040506000b410021040c060b410121040c050b410221040c040b410321040c030b410421040c020b410521040c010b410621040b200220043a0010024020054131470d002003413141e20010372203450d04200241e200360204200220033602000b200320043a00314132210420024132360208200228020421050b200141c0006a290300210b2001290338210c02400240200520046b4110490d0020022802002103200521060c010b20054101742203200441106a2206200320064b1b22064100480d020240024020050d00200610332203450d050c010b2002280200210320052006460d0020032005200610372203450d040b20022006360204200220033602000b200320046a2205200b3700082005200c3700002002200441106a2209360208200141d0006a290300210b200141c8006a290300210c02400240200620096b410f4d0d00200621050c010b20064101742205200441206a2208200520084b1b22054100480d020240024020060d00200510332203450d050c010b20062005460d0020032006200510372203450d040b20022005360204200220033602000b200320096a2206200b3700082006200c3700002002200441206a2206360208200141e8006a28020021090240200520066b41034b0d0020054101742208200441246a220a2008200a4b1b22084100480d020240024020050d00200810332203450d050c010b20052008460d0020032005200810372203450d040b20022008360204200220033602000b200320066a20093600002002200441246a22033602082001290358210b2002200141e0006a2903003703182002200b370310200241106a21040b024002402002280204220620036b4110490d00200228020021050c010b200341106a22052003490d01200641017422092005200920054b1b22094100480d010240024020060d00024020090d00410121050c020b200910332205450d040c010b2002280200210520062009460d0020052006200910372205450d030b20022009360204200220053602000b200520036a22052004290000370000200541086a200441086a2900003700002002200341106a2203360208200041086a200336020020002002290300370200200241206a24000f0b103e000b103c000b4d01027f230041106b2202240002404104103322030d001045000b2002420437020420022003360200410020021077200041086a200228020836020020002002290300370200200241106a24000b130020004107360204200041ccb0c6003602000b3801017f02404110103322020d001045000b2002420037000820024280a094a58d1d370000200042908080808002370204200020023602000b2e01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241809c313600000b2e01017f02404104103322020d001045000b20004284808080c0003702042000200236020020024180a3053600000b2e01017f02404104103322020d001045000b20004284808080c0003702042000200236020020024180de343600000b340020004189fec60036020420004100360200200041146a4102360200200041106a41acbbc600360200200041086a42093702000bfc0f030b7f017e017f230041106b2202240020024100360208200242013703000240024002402001280200220341044b0d000240024002400240024020030e050001020304000b410110332203450d062002410136020420022003360200200341013a000020024101360208200128020421042001410c6a2802002203200210770240024020030d00200228020821030c010b2004200341286c6a21054100200228020822066b2107410021030340200620036a2108024002402007200228020422096a4120490d002002280200210a2009210b0c010b200841206a220a2008490d082009410174220b200a200b200a4b1b220b4100480d080240024020090d000240200b0d004101210a0c020b200b1033220a0d010c0b0b2002280200210a2009200b460d00200a2009200b1037220a450d0a0b2002200b3602042002200a3602000b200a20066a20036a220c200420036a2209290000370000200c41186a200941186a290000370000200c41106a200941106a290000370000200c41086a200941086a2900003700002002200841206a220c360208200941206a290300210d0240200b20076a41606a41074b0d00200c41086a220e200c490d08200b410174220c200e200c200e4b1b220c4100480d0802400240200b0d000240200c0d004101210a0c020b200c1033220a450d0b0c010b200b200c460d00200a200b200c1037220a450d0a0b2002200c3602042002200a3602000b200a20066a20036a41206a200d3700002002200841286a360208200741586a2107200341286a21032005200941286a470d000b200620036a21030b200141106a280200210b024002402002280204220a20036b4104490d00200228020021090c010b200341046a22092003490d06200a41017422072009200720094b1b22074100480d0602400240200a0d00024020070d00410121090c020b200710332209450d090c010b20022802002109200a2007460d002009200a200710372209450d080b20022007360204200220093602000b200920036a200b3600002002200341046a3602080c040b410110332203450d052002410136020420022003360200200341023a0000200241013602082001280204210a0240024020022802042209417f6a4104490d00200228020021030c010b200941017422034105200341054b1b220b4100480d052002280200210302402009200b460d0020032009200b10372203450d070b2002200b360204200220033602000b2003200a3600012002410536020820012802082103200141106a2802002209200210770240024020090d002002280208210b0c010b2003200941286c6a210c2002280208210b03400240024020022802042208200b6b4120490d00200b41206a21092002280200210a200821070c010b200b41206a2209200b490d072008410174220a2009200a20094b1b22074100480d070240024020080d00024020070d004101210a0c020b20071033220a450d0a0c010b2002280200210a20082007460d00200a200820071037220a450d090b200220073602042002200a3602000b200a200b6a220b2003290000370000200b41186a200341186a290000370000200b41106a200341106a290000370000200b41086a200341086a29000037000020022009360208200341206a290300210d0240200720096b41074b0d00200941086a220b2009490d0720074101742208200b2008200b4b1b220b4100480d070240024020070d000240200b0d004101210a0c020b200b1033220a450d0a0c010b2007200b460d00200a2007200b1037220a450d090b2002200b3602042002200a3602000b200a20096a200d3700002002200941086a220b360208200c200341286a2203470d000b0b200141146a280200210a0240024020022802042209200b6b4104490d00200228020021030c010b200b41046a2203200b490d05200941017422072003200720034b1b22074100480d050240024020090d00024020070d00410121030c020b200710332203450d080c010b2002280200210320092007460d0020032009200710372203450d070b20022007360204200220033602000b2003200b6a200a3600002002200b41046a3602080c030b410110332203450d042002410136020420022003360200200341033a000020024101360208200141086a290300210d0240024020022802042209417f6a4108490d00200228020021030c010b200941017422034109200341094b1b220a4100480d042002280200210302402009200a460d0020032009200a10372203450d060b2002200a360204200220033602000b2003200d370001200241093602080c020b410110332203450d032002410136020420022003360200200341043a0000200241013602082001280204210a0240024020022802042209417f6a4104490d00200228020021030c010b200941017422034105200341054b1b220b4100480d032002280200210302402009200b460d0020032009200b10372203450d050b2002200b360204200220033602000b2003200a360001200241053602080c010b410110332203450d022002410136020420022003360200200341053a0000200241013602082001280204210a0240024020022802042209417f6a4104490d00200228020021030c010b200941017422034105200341054b1b220b4100480d022002280200210302402009200b460d0020032009200b10372203450d040b2002200b360204200220033602000b2003200a360001200241053602080b20002002290300370200200041086a200241086a280200360200200241106a24000f0b103e000b103c000bb70905037f017e027f047e017f230041a0026b22022400200241c8006a2001108a052002280248210320022002280250220436028c022002200336028802200241f8006a2004ad4220862003ad84100510c20102400240200228027822040d00420021050c010b200228027c2106024002400240200241f8006a41086a28020022074110490d0020074170714110460d002007417c714120470d010b20024100360260200242013703582002410936029402200220024188026a360290022002200241d8006a36029c022002419c016a41013602002002420137028c01200241c888c20036028801200220024190026a360298012002419c026a41e88ac50020024188016a10431a200235026042208620023502588410060240200228025c450d00200228025810350b420021050c010b200441086a290000210820042900002109200441186a290000210a2004290010210b20042800202107420121050b2006450d00200410350b0240200228024c450d00200310350b02400240024002402005500d0020024188016a41186a420037030020024188016a41106a2206420037030020024188016a41086a22034200370300200242003703880141d1c4c700ad4280808080e000841001220429000021052003200441086a29000037030020022005370388012004103541e7c4c700ad4280808080e00084100122042900002105200241f8006a41086a220c200441086a2900003703002002200537037820041035200620022903782205370300200241d8006a41086a2003290300370300200241d8006a41106a2005370300200241d8006a41186a200c2903003703002002200229038801370358200241306a200241d8006a412010c001200241106a200a420041002002280234410020022802301b220320076b2204200420034b1bad22054200108408200241206a20054200200b4200108408200242004200200b42001084082002290308200229031884420052200241206a41086a2903002205200229030020022903107c7c220b200554720d0142002009200229032022057d220a200a2009562008200b7d2009200554ad7d220520085620052008511b22031b220b4200200520031b220584500d01200242f6cacda397cddbb320370340200241c0006a2001200b20054106109002200241c0016a2005370300200241b8016a200b37030020024188016a41086a41003a000020024191016a200129000037000020024199016a200141086a290000370000200241a1016a200141106a290000370000200241a9016a200141186a290000370000200241143a00880120024188016a21010c020b20004183363b0100200041086a410a360200200041046a41c1efc400360200200041026a41003a00000c020b200242f6cacda397cddbb320370338200241386a200110920220024188016a2001108a052002350290014220862002280288012203ad8410070240200228028c01450d00200310350b20024188016a41086a41013a000020024191016a200129000037000020024199016a200141086a290000370000200241a1016a200141106a290000370000200241a9016a200141186a290000370000200241143a00880120024188016a21010b41b0b4cc004100200110d401200041043a00000b200241a0026a24000bbc0505017f017e017f017e047f230041d0006b220224004182fec600ad4280808080f000842203100122042900002105200241086a200441086a29000037030020022005370300200410352003100122042900002103200241106a41086a200441086a29000037030020022003370310200410350240024002400240412010332204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a2900003700002004ad4280808080800484100422012900002103200241306a41086a200141086a2900003703002002200337033020011035200241cc006a200441206a360200200220043602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200410352002280228220641206a2201417f4c0d01200228022021070240024020010d0041002108410121040c010b200110332204450d01200121080b024002402008410f4d0d00200821090c010b200841017422094110200941104b1b22094100480d03024020080d002009103322040d010c050b20082009460d0020042008200910372204450d040b20042002290300370000200441086a200241086a2903003700000240024020094170714110460d00200921080c010b200941017422084120200841204b1b22084100480d0320092008460d0020042009200810372204450d040b20042002290310370010200441186a200241106a41086a29030037000002400240200841606a2006490d00200821090c010b2006415f4b0d03200841017422092001200920014b1b22094100480d0320082009460d0020042008200910372204450d040b200441206a20072006109d081a20002001360208200020093602042000200436020002402002280224450d00200710350b200241d0006a24000f0b1045000b1044000b103e000b103c000be9800205027f037e117f057e0c7f23002203210420034180086b4160712203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e1e000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d000b20034194036a41013602002003420137028403200341e8d4ca0036028003200341043602c4052003419cd5ca003602c0052003200341c0056a3602900320034180036a41b0b4cc00104c000b200141306a2903002105200141286a290300210620034180026a41186a200141196a29000037030020034180026a41106a200141116a29000037030020034180026a41086a200141096a29000037030020032001290001370380022002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109024020022d0000450d00200320073702e407200320013a00e307200320083a00e207200320093b01e0070c500b200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820022d00012102200320073703e007200241ff01714101470d4f200320073703e006200320013a00df06200320083a00de06200320093b01dc062003200a3a00db062003200b3a00da062003200c3b01d8062003200d3a00d7062003200e3a00d6062003200f3b01d406200320103a00d306200320113a00d206200320123b01d006200320133a00cf06200320143a00ce06200320153b01cc06200320163a00cb06200320173a00ca06200320183b01c8060240200642808084fea6dee1115441002005501b0d00200320063703c001200320053703c8012003200341c8066a3602e0072003200341c8066a36028801200320034188016a360288032003200341e0076a360284032003200341c0016a36028003200341c0056a200341c8066a20034180036a108c030240024020032802c0054101470d0020032f00c50520032d00c705411074722101200341c8056a290300210720032d00c40521020c010b410421020240200341c0056a41086a2903004201520d00200341c0056a41106a29030021072003280288012101200341b8036a200341c0056a41186a290300370300200341b0036a200737030020034180036a41086a41003a000020034189036a200129000037000020034191036a200141086a29000037000020034199036a200141106a290000370000200341a1036a200141186a290000370000200341033a00800341b0b4cc00410020034180036a10d4010b0b0240200241ff01714104470d0041d9e3cb00ad428080808090018422071001220229000021192002290008211a2002103541bbe3cb00ad4280808080f00184221b10012202290000211c2002290008211d200210352003201d3701d8012003201c3701d0012003201a3701c801200320193701c001200341106a200341c0016a412010c001200328021421012003280210210820071001220229000021072002290008211920021035201b10012202290000211a2002290008211b200210352003201b3701d8012003201a3701d001200320193701c801200320073701c00120032001410020081b220841016a36028003200341c0016aad4280808080800484220720034180036aad4280808080c0008410022003200341c8066a3602c001200341c0056a200810ed0420033502c805211920032802c005210c411810332202450d4f2002200637000020022005370008200342988080808002370284032003200236028003410120034180036a107720032802c0012102200328028003210102400240200328028403220a20032802880322096b411f4d0d00200a210b0c010b200941206a220b2009490d3f200a410174220d200b200d200b4b1b220b4100480d3f0240200a0d000240200b0d00410121010c020b200b103322010d010c520b200a200b460d002001200a200b10372201450d510b200120096a220a2002290000370000200a41186a200241186a290000370000200a41106a200241106a290000370000200a41086a200241086a2900003700002019422086200cad84200941206aad4220862001ad8410020240200b450d00200110350b024020032802c405450d00200c10350b200341cc056a20034180026a41086a290300370200200341d4056a20034180026a41106a290300370200200341dc056a20034180026a41186a290300370200200341ec056a200341c8066a41086a290300370200200341f4056a200341c8066a41106a290300370200200341fc056a200341c8066a41186a290300370200200320083602c00520032003290380023702c405200320032903c8063702e4052003200341c0056a3602ac0141d9e3cb00ad42808080809001841001220229000021192002290008211a2002103541918dc500ad4280808080b0018410012202290000211b2002290008211c200210352003201c3701d8012003201b3701d0012003201a3701c801200320193701c00120034188016a2007100510c201024002402003280288010d00410410332202450d5120034204370284032003200236028003410020034180036a1077200341b8016a20032802880336020020032003290380033703b0010c010b200341b0016a41086a20034188016a41086a28020036020020032003290388013703b0010b200341b8076a41086a200341b0016a41086a2802002202360200200320032903b0013703b807024002402002450d0020034180036a20032802b80722012002410110f1042003280280034101470d0120032802bc07450d4e200110350c4e0b4101200341b8076a107720032802ac01200341b8076a108c050c4b0b200328028403210a02402003418c036a280200220120034180036a41086a2802002209460d002002200120096b6a220241046a220b417f4c0d4002400240200b0d004100210b4101210c0c010b200b1033220c450d510b2003200c3602c8072003200b3602cc07200320023602d0072003200341c8076a36028003200a20034180036a200110f20420022001490d1f20032802d007220a2002490d2020032802c007220a2009490d2120032802c807210b20032802b807210c2003200220016b22023602d8072003200a20096b220a3602dc072002200a470d22200b20016a200c20096a2002109d081a20032802ac01200341c8076a108c0520032802d007210120032802cc07210920032802c807210220032802bc07450d4c20032802b80710350c4c0b2003200341b8076a36028003200a20034180036a200910f20420032802ac01200341b8076a108c050c4a0b2003200737027c200320023a0078200320013b0079200320014110763a007b0c510b200341f8006a410110e80420032d00784104460d4c200329027c21070c500b200141046a280200211e2002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d00200320073702e407200320013a00e307200320083a00e207200320093b01e007410121020c010b20022d00012102200320073703e007200241ff017141014721020b200320073701d801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320133a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c001024002400240024020020d0020034180026a41186a200341c0016a41186a29010037030020034180026a41106a200341c0016a41106a29010037030020034180026a41086a200341c0016a41086a290100370300200320032901c00137038002200341c0016a201e10ed0420034180036a20032802c001220120032802c80110cc02200341c0056a41086a22082003419c036a28020036020020032003290294033703c00502402003280290032202450d0020034180036a41086a2903002107200329038003210520034188016a41086a2008280200360200200320032903c00537038801024020032802c401450d00200110350b200341dc066a200329038801370200200341e4066a20034190016a280200360200200320053703c806200320023602d806200320073703d006200320073703c801200320053703c001200320034180026a3602e007024020052007844200510d00200320034180026a36028801200320034188016a360288032003200341e0076a360284032003200341c0016a36028003200341c0056a20034180026a20034180036a108c030240024020032802c0054101470d0020032f00c50520032d00c705411074722108200341c8056a290300210720032d00c40521010c010b410421010240200341c0056a41086a2903004201520d00200341c0056a41106a29030021072003280288012108200341b8036a200341c0056a41186a290300370300200341b0036a200737030020034180036a41086a41003a000020034189036a200829000037000020034191036a200841086a29000037000020034199036a200841106a290000370000200341a1036a200841186a290000370000200341033a00800341b0b4cc00410020034180036a10d4010b0b200141ff01714104470d030b200329039802210720032d009702210820032d009602210920032f019402210a20032d009302210b20032d009202210c20032f019002210d20032d008f02210e20032d008e02210f20032f018c02211020032d008b02211120032d008a02211220032f018802211320032d008702211420032d008602211520032f018402211620032d008302211720032d008202211820032f018002211f0240200341c8066a41186a280200220120032802dc06470d00200341d8066a20014101108a0120032802d806210220032802e00621010b200220014105746a22022007370018200220083a0017200220093a00162002200a3b00142002200b3a00132002200c3a00122002200d3b00102002200e3a000f2002200f3a000e200220103b000c200220113a000b200220123a000a200220133b0008200220143a0007200220153a0006200220163b0004200220173a0003200220183a00022002201f3b00002003200141016a3602e00620034180036a41186a20032903e00637030020034180036a41106a200341c8066a41106a29030037030020034180036a41086a200341c8066a41086a290300370300200320032903c80637038003200341c0056a201e10ed0420032802c0052102200320032802c8053602c401200320023602c00120034180036a200341c0016a108d03024020032802c405450d00200210350b024020034194036a28020041ffffff3f71450d0020032802900310350b200341043a00c8070c500b024020032802c401450d00200110350b200341c8076a410210e80420032d00c8074104460d4f0c020b200341023a00c8070c020b200320073702cc07200320013a00c807200320083b00c907200320084110763a00cb0720032802dc0641ffffff3f71450d00200210350b20032902cc0721070b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c500b200141046a2802002108200341c0056a41206a200141286a290300370300200341c0056a41186a200141206a290300370300200341c0056a41106a200141186a290300370300200341c0056a41086a200141106a2903003703002003200141086a2903003703c0050240024002400240024020022d00000d0020022d000141ff01714101460d010b200341023a0080020c010b200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211e20032002411a6a2901003703e006200320013a00df06200320093a00de062003200a3b01dc062003200b3a00db062003200c3a00da062003200d3b01d8062003200e3a00d7062003200f3a00d606200320103b01d406200320113a00d306200320123a00d206200320133b01d006200320143a00cf06200320153a00ce06200320163b01cc06200320173a00cb06200320183a00ca062003201e3b01c80620034180036a41206a200341c0056a41206a29030037030020034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c0053703800320034180026a200341c8066a200820034180036a108d0520032d0080024104460d0120032902840221070b20032802800221032000411c6a2007370200200041186a2003360200420121070c010b420021070b200042003703080c4f0b200141046a2802002108200341c0056a41206a200141286a290300370300200341c0056a41186a200141206a290300370300200341c0056a41106a200141186a290300370300200341c0056a41086a200141106a2903003703002003200141086a2903003703c00520022d00000d1d20022d000141ff01714101470d1d2002411a6a2901002107200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c0012003200e3a00cf012003200f3a00ce01200320103b01cc01200320113a00cb01200320123a00ca01200320133b01c801200320013a00d701200320093a00d6012003200a3b01d4012003200b3a00d3012003200c3a00d2012003200d3b01d001200320073701d801200341c8066a41186a2007370300200341c8066a41106a20032901d001370300200341c8066a41086a20032901c801370300200320032901c0013703c80620034180036a200341c8066a108e050240024020032d00800322024102460d0020024101470d0020034180036a41186a2d0000210220034197036a2d0000210120034195036a2f0000210920034194036a2d0000210a20034193036a2d0000210b20034191036a2f0000210c20034180036a41106a2d0000210d2003418f036a2d0000210e2003418d036a2f0000210f2003418c036a2d000021102003418b036a2d0000211120034189036a2f0000211220034180036a41086a2d0000211320032d008703211420032f008503211520032d008403211620032d008303211720032d008203211820032d008103211e200320034199036a29000037039802200320023a009702200320013a009602200320093b0194022003200a3a0093022003200b3a0092022003200c3b0190022003200d3a008f022003200e3a008e022003200f3b018c02200320103a008b02200320113a008a02200320123b018802200320133a008702200320143a008602200320153b018402200320163a008302200320173a008202200320183a0081022003201e3a00800220034180036a41206a200341c0056a41206a29030037030020034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c0053703800320034188016a20034180026a200820034180036a108d050c010b20034188016a410310e8040b024020032d0088014104460d00200329028c0121070c440b420021070c440b0240024020022d0000417f6a220841024b0d00200141046a2802002101024020080e03000102000b200241046a2d00000d00200241086a28020041036c2002410c6a2802004101744f0d010b200341023a00e0070c420b20034188016a200110f50420034180036a200328028801220820032802900110b30220032d0080032102200341c0056a20034180036a41017241e700109d081a0240024020024102460d00200341c8066a200341c0056a41e700109d081a0240200328028c01450d00200810350b20034180036a200341c8066a41e700109d081a2002450d0120034180026a411410e8040c410b0240200328028c01450d00200810350b20034180026a411410e8040c400b20034184026a20034187036a41e000109d081a20032f01bc02210220032d00be02210820032d00bf02210920032f01c002210a20032d00c202210b20032d00c302210c20032f01c402210d20032d00c602210e20032d00c702210f20032f01c802211020032d00ca02211120032d00cb02211220032f01cc02211320032d00ce02211420032d00cf02211520032f01d002211620032d00d202211720032d00d3022118200320032902d402220737039803200320183a009703200320173a009603200320163b019403200320153a009303200320143a009203200320133b019003200320123a008f03200320113a008e03200320103b018c032003200f3a008b032003200e3a008a032003200d3b0188032003200c3a0087032003200b3a0086032003200a3b018403200320093a008303200320083a008203200320023b018003200341c0056a20034180036a108f05200341186a20032802c005221f20032802c80541b0b4cc0041004100108a022003280218211e024020032802c405450d00201f10350b0240201e4101460d002003200737039803200320183a009703200320173a009603200320163b019403200320153a009303200320143a009203200320133b019003200320123a008f03200320113a008e03200320103b018c032003200f3a008b032003200e3a008a032003200d3b0188032003200c3a0087032003200b3a0086032003200a3b018403200320093a008303200320083a008203200320023b018003200341c0056a20034180036a108f0520032802c005210220033502c8052107200341013a00800320074220862002ad8420034180036aad428080808010841002024020032802c405450d00200210350b2003418c036a200136020020034188036a41063a0000200341063a00800341b0b4cc00410020034180036a10d40120034180036a200110f5042003350288034220862003280280032202ad8410070240200328028403450d00200210350b200341043a00e0070c490b200341e0076a410510e8040c400b200341d8056a200141196a290000370300200341d0056a200141116a290000370300200341c8056a200141096a290000370300200320012900013703c00502400240024020022d0000417f6a220141024b0d00024020010e03000102000b200241086a2802004101742002410c6a280200490d00200241046a28020041ff0171450d010b200341023a0080020c010b41d9e3cb00ad4280808080900184221a1001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341286a200341c0016a412041b0b4cc0041004100108a020240024020032802284101460d0020034180036a41186a2201200341c0056a41186a29030037030020034180036a41106a2208200341c0056a41106a29030037030020034180036a41086a2209200341c0056a41086a290300370300200320032903c00537038003201a100122022d000f210a20022d000e210b20022f000c210c20022d000b210d20022d000a210e20022f0008210f20022d0007211020022d0006211120022f0004211220022d0003211320022d0002211420022f000021152002103541b8a3c600ad428080808090018410012202290008210720022d0007211620022d0006211720022f0004211820022d0003211e20022d0002211f20022f0000212020021035412010332202450d4b2002200329038003370000200241186a2001290300370000200241106a2008290300370000200241086a2009290300370000412010332201450d4b20012002290000370000200141186a2208200241186a290000370000200141106a2209200241106a290000370000200141086a2221200241086a2900003700002002103541c00010332202450d4b20022007370018200220163a0017200220173a0016200220183b00142002201e3a00132002201f3a0012200220203b00102002200a3a000f2002200b3a000e2002200c3b000c2002200d3a000b2002200e3a000a2002200f3b0008200220103a0007200220113a0006200220123b0004200220133a0003200220143a0002200220153b0000200241386a2008290000370000200241306a2009290000370000200241286a2021290000370000200220012900003700202001103520034180036a200241c00010cd022003280280032109200329038803210720032802840321012002103502402001450d0020034180036a41186a420037030020034180036a41106a220a420037030020034180036a41086a22024200370300200342003703800341d1c4c700ad4280808080e000841001220829000021052002200841086a29000037030020032005370380032008103541e7c4c700ad4280808080e00084100122082900002105200341e0076a41086a220b200841086a290000370300200320053703e00720081035200a20032903e0072205370300200341c8066a41086a2002290300370300200341c8066a41106a2005370300200341c8066a41186a200b29030037030020032003290380033703c806200341206a200341c8066a412010c00102402003280224410020032802201b20094f0d0020034180026a410710e804200742ffffff3f83500d03200110350c030b200742ffffff3f83500d00200110350b20034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c00537038003200341003a00a00341d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341203602cc062003200341c0016a3602c80620034180036a200341c8066a109005200341043a0080020c4a0b20034180026a410610e8040b20032d0080024104460d4820032902840221070b20032802800221032000411c6a2007370200200041186a200336020020004200370308420121070c4c0b200341c0056a41186a200141196a290000370300200341d0056a200141116a290000370300200341c0056a41086a200141096a290000370300200320012900013703c0050240024020022d0000417f6a220141024b0d00024020010e03000102000b200241046a2d00000d00200241086a2802004102742002410c6a28020041036c4f0d010b20004200370308200041186a4102360200420121070c4c0b20034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c00537038003200341023a00a00341d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341203602cc062003200341c0016a3602c80620034180036a200341c8066a1090050c460b200341c0056a41186a200141196a290000370300200341d0056a200141116a290000370300200341c8056a200141096a290000370300200320012900013703c0050240024020022d0000417f6a220141024b0d00024020010e03000102000b200241086a2802002002410c6a280200490d00200241046a28020041ff0171450d010b20004200370308200041186a4102360200420121070c4b0b20034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c00537038003200341013a00a00341d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341203602cc062003200341c0016a3602c80620034180036a200341c8066a1090050c450b200141286a280200210d200141246a280200210820034188016a41086a220a2002411c6a2800003602002003200241146a290000370388012002410c6a280000210b200241086a280000210c200241046a280000210920022d0000210220034198026a200141196a29000037030020034190026a200141116a29000037030020034180026a41086a200141096a29000037030020032001290001370380020240024020084180a305490d00200341e0076a41086a200a28020036020020032003290388013703e00720024102470d01200941ff01710d3941002109200c41036c200b4101744f0d3a0c380b2002417e6a220241014b0d3820020e023739370b20024103470d370c380b20034198026a200141196a29000037030020034180026a41106a200141116a29000037030020034180026a41086a200141096a290000370300200320012900013703800220022d00004102470d18200241236a2d00002108200241216a2f000021092002411f6a2d0000210a2002411d6a2f0000210b2002410f6a2d0000210c2002410d6a2f0000210d2002410b6a2d0000210e200241096a2f0000210f200241076a2d00002110200241056a2f00002111200241246a2802002112200241206a2d00002113200241116a2900002107200241106a2d000021142002410c6a2d00002115200241086a2d00002116200241046a2d000021012003200241196a2800003602e807200320073703e00720014101470d182003200920084110747222023b01dc05200341de056a20024110763a00002003200b200a4110747222023b01d805200341da056a20024110763a00002003200d200c4110747222023b01c805200341c0056a410a6a20024110763a000020032007a722023b01cc05200341ce056a20024110763a0000200320123a00df05200320133a00db05200320032902e4073703d005200320143a00cb05200320153a00c705200320163a00c305200320074218883c00cf052003200f200e4110747222023b01c405200320024110763a00c6052003201120104110747222023b01c005200320024110763a00c20541d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c00120034180036a200341c0016a10c00202400240024020032d00a0034103460d0020032903800321072003290388032105200329039003210620032003290398033703980320032006370390032003200537038803200320073703800320034180026a20034180036a412010a008450d01200341c8076a410210e8040c020b200341c8076a410a10e8040c010b200341c8066a20034180026a10910520034180036a20032802c806220220032802d00610cd022003290388032107200328028403210e024020032802cc06450d00200210350b0240200e0d004100210f200341003602900120034201370388014101210e0c330b2003200e360288012003200737028c012007a7210f41002102024002402007422088a7220a41014b0d00200a0e023401340b200a210103402001410176220820026a22092002200e20094105746a200341c0056a412010a0084101481b2102200120086b220141014b0d000b0b0240200e20024105746a200341c0056a412010a0082201450d0020034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c005370380032001411f7620026a2208200a4b0d1b20034180036a21010c340b200341c8076a410b10e804200f41ffffff3f71450d00200e10350b20032d00c8074104460d4320032902cc0721070c300b20022d000120022d0000410047720d192003418c036a200141046a280200220236020020034188036a41063a0000200341063a00800341b0b4cc00410020034180036a10d40120034180036a200210f5042003350288034220862003280280032202ad841007200328028403450d42200210350c420b20022d000120022d0000410047720d19200141046a2802002102410c10332201450d4220012002360008200142e4cab5fbb6ccdcb0e3003700004189fec600ad4280808080900184100122022900002107200341c8066a41086a200241086a290000370300200320073703c8062002103541b489c500ad4280808080e00084100122022900002107200341c0056a41086a200241086a290000370300200320073703c00520021035411010332202450d4220034210370284032003200236028003410c20034180036a107702400240200328028403220a20032802880322086b410c490d002003280280032102200a21090c010b2008410c6a22022008490d32200a41017422092002200920024b1b22094100480d3202400240200a0d00024020090d00410121020c020b200910332202450d460c010b2003280280032102200a2009460d002002200a200910372202450d450b200320093602840320032002360280030b200220086a220a2001290000370000200a41086a200141086a28000036000020032008410c6a2208ad4220862002ad841003220a29000037038801200a103520034180036a410c6a200220086a3602002003200236028803200320034188016a41086a36028403200320034188016a3602800320034180026a20034180036a107b02402009450d00200210350b200328028802220b41206a2208417f4c0d32200328028002210c0240024020080d0041002109410121020c010b200810332202450d43200821090b024002402009410f4d0d002009210a0c010b2009410174220a4110200a41104b1b220a4100480d32024020090d00200a10332202450d450c010b2009200a460d0020022009200a10372202450d440b200220032903c806370000200241086a200341c8066a41086a29030037000002400240200a4170714110460d00200a21090c010b200a41017422094120200941204b1b22094100480d32200a2009460d002002200a200910372202450d440b200220032903c005370010200241186a200341c0056a41086a29030037000002400240200941606a200b490d002009210a0c010b200b415f4b0d322009410174220a2008200a20084b1b220a4100480d322009200a460d0020022009200a10372202450d440b200241206a200c200b109d081a0240200328028402450d00200c10350b20034180036a2002200810da0141012109024002402003280280034101460d00410021090c010b2008ad4220862002ad84100720032902840321070b0240200a450d00200210350b2001103502402009450d00200341c8066a2007a710c90420034180036a20032802c806220a20032802d006220110b8022003280280032202410820021b210902402007422088a72208200329028403420020021b2207422088a722024f0d002009200841d0026c6a220b450d002009200841d0026c6a220141bc026a210a024020012802bc024102460d00024020012802b002220c450d002009200841d0026c6a41b4026a280200450d00200c10350b200b10ba020b200b20034180036a41bc02109d081a200a4102360200200141c8026a200341c8056a290300370300200120032903c0053703c00220032802d006210120032802c806210a0b0240024020090d002001ad422086200aad8410070c010b20034180036a2009200210d9042001ad422086200aad842003350288034220862003280280032201ad8410020240200328028403450d00200110350b02402002450d00200241d0026c21012009210203400240200241bc026a2802004102460d000240200241b0026a2802002208450d00200241b4026a280200450d00200810350b200210bb020b200241d0026a2102200141b07d6a22010d000b0b2007a72202450d00200241d0026c450d00200910350b024020032802cc06450d00200a10350b200341043a00c0010c420b200341c0016a410210e80420032d00c0014104460d4120032902c40121070c2d0b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a29000037030020032001290001370388012002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d00200320073702e407200320013a00e307200320083a00e207200320093b01e007410121020c010b20022d00012102200320073703e007200241ff017141014721020b200320073701d801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320133a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c00120020d19200341c0016a20034188016a10920520034180036a20032802c001221e20032802c801222010c402200341a0036a2d000021020240024020032d008003221f4102470d00200341023a0080020c010b200320032d0083033a008302200320032f0081033b0081022003200329028403370284022003201f3a008002200320034198036a2903003703980220032003418c036a29020037028c02200320034194036a280200360294020b200320013a00df06200320083a00de06200320093b01dc062003200a3a00db062003200b3a00da062003200c3b01d8062003200d3a00d7062003200e3a00d6062003200f3b01d406200320103a00d306200320113a00d206200320123b01d006200320133a00cf06200320143a00ce06200320153b01cc06200320163a00cb06200320173a00ca06200320183b01c806200320073703e00620034198036a20032903980237030020034180036a41206a20023a0000200341023a00c0052003200329039002370390032003200329038802370388032003200329038002220537038003200320032903d80537039802200320032903d00537039002200320032903c80537038802200320032903c00537038002024002402005a7410371417f6a220141014b0d0041192102024020010e020002000b410c21020c010b411a210220034180036a410172200341c8066a412010a0080d00200320032903c80637008102200341013a0080022003200341df066a290000370098022003200341d8066a290300370091022003200341d0066a290300370089022003200329039802370398032003200329039002370390032003200329038802370388032003200329038002220537038003024002402005a7220241ff01714102470d002020ad422086201ead8410070c010b410110332201450d44200120023a000020014101412110372202450d44200220032900810337000120022007423888a73a0020200241186a200329009803370000200241116a200329009103370000200241096a2003290089033700002020ad422086201ead842002ad42808080809004841002200210350b412621020b024020032802c401450d00201e10350b024020024126470d00200341043a00c8070c410b200341c8076a200210e80420032d00c8074104460d4020032902cc0721070c2b0b20022d00000d1920022d000141ff01714101470d19200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211820032002411a6a2901003703d805200320013a00d705200320083a00d605200320093b01d4052003200a3a00d3052003200b3a00d2052003200c3b01d0052003200d3a00cf052003200e3a00ce052003200f3b01cc05200320103a00cb05200320113a00ca05200320123b01c805200320133a00c705200320143a00c605200320153b01c405200320163a00c305200320173a00c205200320183b01c005200341c8066a200341c0056a10920520034180036a20032802c806220220032802d006220110c402024020032d0080034102460d00200341c0056a1099020b2001ad4220862002ad84100720032802cc06450d3f200210350c3f0b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a29000037030020032001290001370388012002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d00200320073702e407200320013a00e307200320083a00e207200320093b01e007410121020c010b20022d00012102200320073703e007200241ff017141014721020b200320073701d801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320133a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c00120020d19200341c0016a20034188016a10920520034180036a20032802c001221e20032802c801222010c402200341a0036a2d000021020240024020032d008003221f4102470d00200341023a0080020c010b200320032d0083033a008302200320032f0081033b0081022003200329028403370284022003201f3a008002200320034198036a2903003703980220032003418c036a29020037028c02200320034194036a280200360294020b200320013a00df06200320083a00de06200320093b01dc062003200a3a00db062003200b3a00da062003200c3b01d8062003200d3a00d7062003200e3a00d6062003200f3b01d406200320103a00d306200320113a00d206200320123b01d006200320133a00cf06200320143a00ce06200320153b01cc06200320163a00cb06200320173a00ca06200320183b01c806200320073703e00620034198036a20032903980237030020034180036a41206a20023a0000200341023a00c0052003200329039002370390032003200329038802370388032003200329038002220537038003200320032903d80537039802200320032903d00537039002200320032903c80537038802200320032903c00537038002411b210202402005a741ff01714101470d00410d210220034180036a410172200341c8066a412010a0080d00200320032903c80637008102200341003a0080022003200341df066a290000370098022003200341d8066a290300370091022003200341d0066a290300370089022003200329039802370398032003200329039002370390032003200329038802370388032003200329038002220537038003024002402005a7220241ff01714102470d002020ad422086201ead8410070c010b410110332201450d42200120023a000020014101412110372202450d42200220032900810337000120022007423888a73a0020200241186a200329009803370000200241116a200329009103370000200241096a2003290089033700002020ad422086201ead842002ad42808080809004841002200210350b412621020b024020032802c401450d00201e10350b024020024126470d00200341043a00c8070c3f0b200341c8076a200210e80420032d00c8074104460d3e20032902cc0721070c280b200141306a2903002107200141286a2903002105200141216a2d00002108200341c8066a41186a200141196a290000370300200341c8066a41106a200141116a290000370300200341c8066a41086a200141096a290000370300200320012900013703c8060240024020022d00000d0020022d000141ff01714101470d002002411a6a2901002106200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c0012003200e3a00cf012003200f3a00ce01200320103b01cc01200320113a00cb01200320123a00ca01200320133b01c801200320013a00d701200320093a00d6012003200a3b01d4012003200b3a00d3012003200c3a00d2012003200d3b01d001200320063701d801200341c0056a41186a2006370300200341c0056a41106a20032901d001370300200341c0056a41086a20032901c801370300200320032901c0013703c00520034180036a41186a200341c8066a41186a29030037030020034180036a41106a200341c8066a41106a29030037030020034180036a41086a200341c8066a41086a290300370300200320032903c8063703800320034180026a200341c0056a20034180036a20082005200710930520032d00800222024104460d3f20032f00810220032d00830241107472210120032902840221070c010b410221020b200042003703082000411c6a2007370200200041186a2001410874200272360200420121070c420b0240024020022d00000d0020022d000141ff01714101470d002002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172003200241096a2d00003a00c701200320133a00c601200320143b01c401200320153a00c301200320163a00c201200320173b01c0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d001200320073701d80120034198036a200737030020034180036a41106a20032901d00137030020034188036a20032901c801370300200320032901c00137038003200341c0056a20034180036a10940520032d00c00522024104460d3e20032f00c10520032d00c30541107472210120032902c40521070c010b410221020b200042003703082000411c6a2007370200200041186a2001410874200272360200420121070c410b024020022d000120022d000041004772450d0020004200370308200041186a4102360200420121070c410b41d9e3cb00ad4280808080900184100122022900002107200229000821052002103541918dc500ad4280808080b001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341c0016aad428080808080048410070c3b0b200141086a2802002108200141046a280200210920022d00000d1620022d000141ff01714101470d162001410c6a2802002101200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211e200241046a2d0000211f200241026a2f0100212020032002411a6a2901003703d8012003200a3a00d7012003200b3a00d6012003200c3b01d4012003200d3a00d3012003200e3a00d2012003200f3b01d001200320103a00cf01200320113a00ce01200320123b01cc01200320133a00cb01200320143a00ca01200320153b01c801200320163a00c701200320173a00c601200320183b01c4012003201e3a00c3012003201f3a00c201200320203b01c0012001ad22194220862009ad84100922022900002107200241086a2900002105200241106a290000210620034180026a41186a200241186a29000037030020034180026a41106a200637030020034180026a41086a200537030020032007370380022002103520034180036a20034180026a10ee04200341d8006a200328028003220a20032802880341b0b4cc0041004100108a02200328025821020240200328028403450d00200a10350b20024101460d17200341c8006a201942004280a094a58d1d42001084082003200341d0006a29030022073703d0062003200329034822053703c8062003200341c0016a3602c807024002402001450d002003200341c0016a3602e0072003200341e0076a360288032003200341c8076a360284032003200341c8066a36028003200341c0056a200341c0016a20034180036a108c030240024020032802c0054101470d0020032f00c50520032d00c70541107472210a200341c8056a290300210620032d00c40521020c010b410421020240200341c0056a41086a2903004201520d00200341c0056a41106a290300210620032802e007210a200341b8036a200341c0056a41186a290300370300200341b0036a200637030020034180036a41086a41003a000020034189036a200a29000037000020034191036a200a41086a29000037000020034199036a200a41106a290000370000200341a1036a200a41186a290000370000200341033a00800341b0b4cc00410020034180036a10d4010b0b200241ff01714104470d010b20034180036a41186a420037030020034180036a41106a220b420037030020034180036a41086a22024200370300200342003703800341d1c4c700ad4280808080e000841001220a29000021062002200a41086a2900003703002003200637038003200a103541e7c4c700ad4280808080e000841001220a2900002106200341e0076a41086a220c200a41086a290000370300200320063703e007200a1035200b20032903e0072206370300200341c8066a41086a2002290300370300200341c8066a41106a2006370300200341c8066a41186a200c29030037030020032003290380033703c806200341c0006a200341c8066a412010c0012003280244210a2003280240210b200341c0056a41186a20034180026a41186a220c290300370300200341c0056a41106a20034180026a41106a220d290300370300200341c0056a41086a20034180026a41086a220e29030037030020032003290380023703c005200341c8036a2007370300200341c0036a200537030020034189036a220f200341c0016a41086a221029030037000020034191036a2211200341c0016a41106a221229030037000020034199036a2213200341c0016a41186a2214290300370000200341b4036a4100360200200341b0036a200a4100200b1b360200200341ac036a2001360200200341a8036a2008360200200341a4036a2009360200200341013a008003200320032903c00137008103200341c0056a20034180036a109505200341d8036a2007370300200341d0036a20053703002002410b3a0000200f2003290380023700002011200e2903003700002013200d290300370000200341a1036a200c290300370000200341a9036a20032903c001370000200341b1036a2010290300370000200341b9036a2012290300370000200341c1036a2014290300370000200341063a00800341b0b4cc00410020034180036a10d401200341043a0088010c3b0b2003200637028c01200320023a0088012003200a3b0089012003200a4110763a008b010c230b200141086a2802002108200141046a280200210902400240024020022d00000d0020022d000141ff01714101470d002001410c6a2802002101200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d0000211e200241046a2d0000211f200241026a2f0100212020032002411a6a2901003701d8012003200a3a00d7012003200b3a00d6012003200c3b01d4012003200d3a00d3012003200e3a00d2012003200f3b01d001200320103a00cf01200320113a00ce01200320123b01cc01200320133a00cb01200320143a00ca01200320153b01c801200320163a00c701200320173a00c601200320183b01c4012003201e3a00c3012003201f3a00c201200320203b01c0012001ad4220862009ad84100922022900002107200241086a2900002105200241106a290000210620034180026a41186a200241186a29000037030020034180026a41106a200637030020034180026a41086a2005370300200320073703800220021035200341c0056a20034180026a10ee0420034180036a20032802c005220a20032802c80510d20220032802c4052102024002400240024020032d008003220b4102460d00200341a8036a280200210c200341a4036a280200210d200335028403210702402002450d00200a10350b200b450d014201210542801e2107200c450d02200d10350c020b02402002450d00200a10350b411021020c020b200742208642801e842107420021050b410f21022005200784a741ff01714101470d030b20034188016a200210e8040c010b200341023a0088010b02402008450d00200910350b20032d0088014104460d3a20032802880121022000411c6a200329028c01370200200041186a200236020020004200370308420121070c3f0b20034180036a41186a420037030020034180036a41106a220b420037030020034180036a41086a22024200370300200342003703800341d1c4c700ad4280808080e000841001220a29000021052002200a41086a2900003703002003200537038003200a103541e7c4c700ad4280808080e000841001220a2900002105200341e0076a41086a220c200a41086a290000370300200320053703e007200a1035200b20032903e0072205370300200341c8066a41086a2002290300370300200341c8066a41106a2005370300200341c8066a41186a200c29030037030020032003290380033703c806200341e0006a200341c8066a412010c0012003280264210a2003280260210b200341c0056a41186a20034180026a41186a220c290300370300200341c0056a41106a20034180026a41106a220d290300370300200341c0056a41086a20034180026a41086a220e29030037030020032003290380023703c005200341c8036a4200370300200341c0036a420037030020034189036a220f200341c0016a41086a221029010037000020034191036a2211200341c0016a41106a221229010037000020034199036a2213200341c0016a41186a2214290100370000200341b8036a20074220883e0200200341b4036a4101360200200341b0036a200a4100200b1b360200200341ac036a2001360200200341a8036a2008360200200341a4036a2009360200200341013a008003200320032901c00137008103200341c0056a20034180036a109505200341d8036a4200370300200341d0036a42003703002002410b3a0000200f2003290380023700002011200e2903003700002013200d290300370000200341a1036a200c290300370000200341a9036a20032901c001370000200341b1036a2010290100370000200341b9036a2012290100370000200341c1036a2014290100370000200341063a00800341b0b4cc00410020034180036a10d401200341043a0088010c390b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a29000037030020032001290001370388012002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021180240024020022d0000450d00200320073702e407200320013a00e307200320083a00e207200320093b01e007410121020c010b20022d00012102200320073703e007200241ff017141014721020b200320073701d801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320133a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c0010240024020020d0020034180026a41186a200341c0016a41186a29010037030020034180026a41106a200341c0016a41106a29010037030020034180026a41086a200341c0016a41086a290100370300200320032901c00137038002200341c0056a20034188016a10ee0420034180036a20032802c005220120032802c80510d20220032802c40521020240024020032d00800322084102460d00200341c8036a2903002105200341c0036a2903002106200341b8036a2802002122200341b4036a2802002121200341b0036a280200210a200341a8036a280200210b200341a4036a280200212020034199036a290000210720034180036a41186a2d0000210c20034197036a2d0000210d20034195036a2f0000210e20034194036a2d0000210f20034193036a2d0000211020034191036a2f0000211120034180036a41106a2d000021122003418f036a2d000021132003418d036a2f000021142003418c036a2d000021152003418b036a2d0000211620034189036a2f0000211720034180036a41086a2d00002118200328028403210920032d008303211e20032f008103211f02402002450d00200110350b2008450d0120094118762102200941087621010240200b450d00202010350b200320073703d8052003200c3a00d7052003200d3a00d6052003200e3b01d4052003200f3a00d305200320103a00d205200320113b01d005200320123a00cf05200320133a00ce05200320143b01cc05200320153a00cb05200320163a00ca05200320173b01c805200320183a00c705200320023a00c605200320013b01c405200320093a00c3052003201e3a00c2052003201f3b01c00520034180036a41186a420037030020034180036a41106a2208420037030020034180036a41086a22024200370300200342003703800341d1c4c700ad4280808080e000841001220129000021072002200141086a29000037030020032007370380032001103541e7c4c700ad4280808080e00084100122012900002107200341e0076a41086a2209200141086a290000370300200320073703e00720011035200820032903e0072207370300200341c8066a41086a2002290300370300200341c8066a41106a2007370300200341c8066a41186a200929030037030020032003290380033703c806200341e8006a200341c8066a412010c001411121020240200328026c410020032802681b2201200a4180de34410020034180026a200341c0056a412010a0081b6a41809c316a490d002021450d0441122102200120224b0d040b200341c8076a200210e8040c230b2002450d00200110350b200341c8076a411310e8040c210b200341023a00c8070c210b20034180036a200341c0056a20034180026a20062005410010ef0220034180036a20034188016a10ee042003350288034220862003280280032202ad8410070240200328028403450d00200210350b20034180036a41086a410f3a000020034189036a200329038801370000200341a9036a20032903c00537000020034191036a20034188016a41086a29030037000020034199036a20034188016a41106a290300370000200341a1036a20034188016a41186a290300370000200341b1036a200341c0056a41086a290300370000200341b9036a200341c0056a41106a290300370000200341c1036a200341c0056a41186a290300370000200341063a008003200341f0036a2006370300200341f8036a2005370300200341e1036a20034180026a41186a290300370000200341d9036a20034180026a41106a290300370000200341d1036a20034180026a41086a290300370000200341c9036a20032903800237000041b0b4cc00410020034180036a10d401200341043a00c8070c380b20034180026a41186a200141196a29000037030020034190026a200141116a29000037030020034188026a200141096a29000037030020032001290001370380022002411a6a2901002107024020022d0000450d00200241166a2f01002101200241186a2d00002108200241196a2d00002102200320073702e407200320023a00e307200320083a00e207200320013b01e0070c1e0b20022d00012102200320073703e007200241ff01714101470d1d200341c0016a20034180026a10960520034180036a20032802c001220920032802c801220a10c90220032d0080032102200341c8066a20034180036a41017241ef00109d081a0240024020024102470d00200341d0056a4200370300200341d8056a4200370300200341e0056a4200370300200341e8056a4200370300200341f0056a4200370300200341f8056a42003703004100210220034180066a4100360200200341083602c405200341c0056a41086a4200370300200341003a00c0050c010b200320023a00c005200341c0056a410172200341c8066a41ef00109d081a200241014621020b20034180036a41186a420037030020034180036a41106a220b420037030020034180036a41086a22014200370300200342003703800341d1c4c700ad4280808080e000841001220829000021072001200841086a29000037030020032007370380032008103541e7c4c700ad4280808080e00084100122082900002107200341e0076a41086a220c200841086a290000370300200320073703e00720081035200b20032903e0072207370300200341c8066a41086a2001290300370300200341c8066a41106a2007370300200341c8066a41186a200c29030037030020032003290380033703c806200341f0006a200341c8066a412010c001024020034198066a200341f0056a20021b22012802102003280274410020032802701b4b0d0020014200370300200141106a4100360200200141086a42003703000b024002402002450d00200341f0056a2903002106200341e8056a29030021190c010b200341f8056a290300210620032903f0052119200341cc056a28020041306c2201450d0020032802c40541206a21020340200241706a22082903002105200841086a29030021070240200241686a2d00004101470d00427f2007200241086a2903007c200520022903007c221a2005542208ad7c22052008200520075420052007511b22081b2107427f201a20081b21050b200620072005201954200720065420072006511b22081b21062019200520081b2119200241306a2102200141506a22010d000b0b20034180036a200341c0056a41f000109d081a0240024020032d00800322024102470d00200aad4220862009ad8410070c010b200341c8066a20034180036a108005200aad4220862009ad8420033502d00642208620032802c8062201ad841002024020032802cc06450d00200110350b20020d0020034188036a2802002202450d00200241306c450d0020032802840310350b024020032802c401450d00200910350b02402019200684500d00200342e4cab5fbb6ccdcb0e3003703800320034180036a20034180026a2019200641021090020c380b200342e4cab5fbb6ccdcb0e3003703800320034180036a20034180026a1092020c370b20022d00000d1420022d000141ff01714101470d14200141196a2900002105200141186a2d00002109200141176a2d0000210a200141156a2f0000210b200141146a2d0000210c200141136a2d0000210d200141116a2f0000210e200141106a2d0000210f2001410f6a2d000021102001410d6a2f000021112001410c6a2d000021122001410b6a2d00002113200141096a2f00002114200141086a2d00002115200141076a2d00002116200141056a2f00002117200141046a2d00002118200141036a2d0000211e20012f00012101200241196a3100002106200241186a3100002119200241166a330100211a200241156a310000211b200241146a310000211c200241126a330100211d200241116a2d00002108200241106a2d0000211f2002410e6a2f010021202002410d6a2d000021212002410c6a2d000021222002410a6a2f01002123200241096a2d00002124200241086a2d00002125200241066a2f01002126200241056a2d00002127200241046a2d00002128200241026a2f01002129200341de056a2002411a6a29010022074230883c0000200341ce056a201f3a0000200341ca056a20223a000020032007a722023b01d805200341da056a20024110763a0000200320203b01cc05200320233b01c805200320253a00c605200320263b01c405200320283a00c205200320293b01c005200320083a00cf05200320213a00cb05200320243a00c705200320273a00c305200320074220883d01dc05200320074238883c00df05200320074218883c00db052003201d201c42108684201b42188684201a422086842019423086842006423886843703d005200341c8066a200341c0056a10920520034180036a20032802c806220820032802d006221f10c4020240024020032d0080034102460d0020032003290081033701c001200320034199036a2900003701d801200320034189036a2900003701c801200320034191036a2900003701d00120014180fe037141087621020c010b20014180fe03714108762102200341c0056a108d020b200320153a00c701200320163a00c601200320173b01c401200320183a00c3012003201e3a00c20120032002410874200141ff0171723b01c0012003200f3a00cf01200320103a00ce01200320113b01cc01200320123a00cb01200320133a00ca01200320143b01c801200320093a00d7012003200a3a00d6012003200b3b01d4012003200c3a00d3012003200d3a00d2012003200e3b01d001200320053701d80120034198036a200537030020034190036a20032901d00137030020034180036a41086a20032901c801370300200320032901c00137038003410110332202450d38200241003a000020024101412110372202450d382002200329038003370001200241196a20034198036a290300370000200241116a20034190036a290300370000200241096a20034188036a290300370000201fad4220862008ad842002ad428080808090048410022002103520032802cc06450d36200810350c360b0240024002400240024020022d00000d0020022d000141ff01714101460d010b200341023a00c0050c010b200141046a2802002101200241196a2d00002108200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211e20032002411a6a29010037039803200320083a009703200320093a0096032003200a3b0194032003200b3a0093032003200c3a0092032003200d3b0190032003200e3a008f032003200f3a008e03200320103b018c03200320113a008b03200320123a008a03200320133b018803200320143a008703200320153a008603200320163b018403200320173a008303200320183a0082032003201e3b018003200341c0056a20034180036a2001410010970520032d00c0054104460d0120032902c40521070b20032802c00521032000411c6a2007370200200041186a2003360200420121070c010b420021070b200042003703080c3a0b200141246a2802002108200341c0056a41186a200141196a290000370300200341c0056a41106a200141116a290000370300200341c0056a41086a200141096a290000370300200320012900013703c0050240024020022d00000d0020022d000141ff01714101470d00200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211e20032002411a6a29010037039803200320013a009703200320093a0096032003200a3b0194032003200b3a0093032003200c3a0092032003200d3b0190032003200e3a008f032003200f3a008e03200320103b018c03200320113a008b03200320123a008a03200320133b018803200320143a008703200320153a008603200320163b018403200320173a008303200320183a0082032003201e3b018003200341c8066a200341c0056a2008200341c0056a20034180036a412010a00841004710970520032d00c80622024104460d3620032f00c90620032d00cb0641107472210120032902cc0621070c010b410221020b200042003703082000411c6a2007370200200041186a2001410874200272360200420121070c390b200141306a2903002107200141286a2903002105200141216a2d00002108200341c8066a41186a200141196a290000370300200341c8066a41106a200141116a290000370300200341c8066a41086a200141096a290000370300200320012900013703c80620022d00000d1220022d000141ff01714101470d122002411a6a2901002106200241196a2d00002101200241186a2d00002109200241166a2f0100210a200241156a2d0000210b200241146a2d0000210c200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a00c701200320143a00c601200320153b01c401200320163a00c301200320173a00c201200320183b01c0012003200e3a00cf012003200f3a00ce01200320103b01cc01200320113a00cb01200320123a00ca01200320133b01c801200320013a00d701200320093a00d6012003200a3b01d4012003200b3a00d3012003200c3a00d2012003200d3b01d001200320063701d801200341c0056a41186a2006370300200341c0056a41106a20032901d001370300200341c0056a41086a20032901c801370300200320032901c0013703c00520034180036a200341c0056a108e05024020032d00800322024102460d0020024101470d0020034180036a41186a2d0000210220034197036a2d0000210120034195036a2f0000210920034194036a2d0000210a20034193036a2d0000210b20034191036a2f0000210c20034180036a41106a2d0000210d2003418f036a2d0000210e2003418d036a2f0000210f2003418c036a2d000021102003418b036a2d0000211120034189036a2f0000211220034180036a41086a2d0000211320032d008703211420032f008503211520032d008403211620032d008303211720032d008203211820032d008103211e200320034199036a2900003703d805200320023a00d705200320013a00d605200320093b01d4052003200a3a00d3052003200b3a00d2052003200c3b01d0052003200d3a00cf052003200e3a00ce052003200f3b01cc05200320103a00cb05200320113a00ca05200320123b01c805200320133a00c705200320143a00c605200320153b01c405200320163a00c305200320173a00c205200320183a00c1052003201e3a00c00520034180036a41186a200341c8066a41186a29030037030020034180036a41106a200341c8066a41106a29030037030020034180036a41086a200341c8066a41086a290300370300200320032903c8063703800320034180026a200341c0056a20034180036a200820052007109305024020032d00800222024104470d00200341043a0088010c350b20032d008302210120032f00810221082003200329028402220737028c01200320023a0088012003200820014110747222023b008901200320024110763a008b010c190b20034188016a410310e80420032d0088014104460d33200329028c0121070c180b20022d00000d1220022d000141ff01714101470d122002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172003200241096a2d00003a00c701200320133a00c601200320143b01c401200320153a00c301200320163a00c201200320173b01c0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d001200320073701d801200341c0056a41186a2007370300200341c0056a41106a20032901d001370300200341c0056a41086a20032901c801370300200320032901c0013703c00520034180036a200341c0056a108e05024020032d00800322024102460d0020024101470d0020034180036a41186a2d0000210220034197036a2d0000210120034195036a2f0000210820034194036a2d0000210920034193036a2d0000210a20034191036a2f0000210b20034180036a41106a2d0000210c2003418f036a2d0000210d2003418d036a2f0000210e2003418c036a2d0000210f2003418b036a2d0000211020034189036a2f0000211120034180036a41086a2d0000211220032d008703211320032f008503211420032d008403211520032d008303211620032d008203211720032d0081032118200320034199036a29000037039803200320023a009703200320013a009603200320083b019403200320093a0093032003200a3a0092032003200b3b0190032003200c3a008f032003200d3a008e032003200e3b018c032003200f3a008b03200320103a008a03200320113b018803200320123a008703200320133a008603200320143b018403200320153a008303200320163a008203200320173a008103200320183a008003200341c0056a20034180036a109405024020032d00c00522024104470d00200341043a00c8060c340b20032d00c305210120032f00c1052108200320032902c40522073702cc06200320023a00c8062003200820014110747222023b00c906200320024110763a00cb060c170b200341c8066a410310e80420032d00c8064104460d3220032902cc0621070c160b20022d00000d1220022d000141ff01714101470d12200141046a28020021182002411a6a2901002107200241196a2d00002101200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f010021172003200241096a2d00003a00c701200320133a00c601200320143b01c401200320153a00c301200320163a00c201200320173b01c0012003200d3a00cf012003200e3a00ce012003200f3b01cc01200320103a00cb01200320113a00ca01200320123b01c801200320013a00d701200320083a00d601200320093b01d4012003200a3a00d3012003200b3a00d2012003200c3b01d001200320073701d801200341c0056a41186a2007370300200341c0056a41106a20032901d001370300200341c0056a41086a20032901c801370300200320032901c0013703c00520034180036a200341c0056a108e050240024020032d00800322024102460d0020024101470d0020034180036a41186a2d0000210220034197036a2d0000210120034195036a2f0000210820034194036a2d0000210920034193036a2d0000210a20034191036a2f0000210b20034180036a41106a2d0000210c2003418f036a2d0000210d2003418d036a2f0000210e2003418c036a2d0000210f2003418b036a2d0000211020034189036a2f0000211120034180036a41086a2d0000211220032d008703211320032f008503211420032d008403211520032d008303211620032d008203211720032d008103211e200320034199036a2900003703e006200320023a00df06200320013a00de06200320083b01dc06200320093a00db062003200a3a00da062003200b3b01d8062003200c3a00d7062003200d3a00d6062003200e3b01d4062003200f3a00d306200320103a00d206200320113b01d006200320123a00cf06200320133a00ce06200320143b01cc06200320153a00cb06200320163a00ca06200320173a00c9062003201e3a00c80620034180026a200341c8066a201841001097050c010b20034180026a410310e8040b024020032d0080024104460d0020032902840221070c140b420021070c140b200141246a2802002108200341c0056a41186a2209200141196a290000370300200341c0056a41106a220a200141116a290000370300200341c0056a41086a220b200141096a290000370300200320012900013703c005024002400240024020022d000120022d000041004772450d00200341023a00c8060c010b20034180036a41186a200929030037030020034180036a41106a200a29030037030020034180036a41086a200b290300370300200320032903c00537038003200341c8066a20034180036a200810f40420032d00c8064104460d0120032902cc0621070b20032802c80621032000411c6a2007370200200041186a2003360200420121070c010b420021070b200042003703080c350b2001200241e88cc5001059000b2002200a41e88cc5001058000b2009200a41f88cc5001059000b20034188016a41146a410a36020020034194016a410c360200200341e0076a41146a41033602002003200341d8076a3602f8072003200341dc076a3602fc0720034180036a41146a4100360200200342033702e407200341a0b3cc003602e0072003410c36028c01200341b0b4cc00360290032003420137028403200341f4b3cc0036028003200320034188016a3602f007200320034180036a360298012003200341fc076a360290012003200341f8076a36028801200341e0076a41b0b4cc00104c000b200341023a0088010c250b200341023a00c8070c170b2008200a104d000b20004200370308200041186a4102360200420121070c2d0b200341023a00c0010c130b200341023a00c8070c110b20004200370308200041186a4102360200420121070c2a0b200341023a00c8070c0e0b200341023a0088010c0c0b20034188016a410f10e8040c0b0b20004200370308200041186a4102360200420121070c260b200341023a0088010c050b200341023a00c8060c030b200341023a0080020b20032802800221032000411c6a2007370200200041186a2003360200420121070b200042003703080c210b20032802c80621032000411c6a2007370200200041186a200336020020004200370308420121070c200b20032802880121032000411c6a2007370200200041186a200336020020004200370308420121070c1f0b200041186a410236020020004200370308420121070c1e0b20032d00c8074104460d1820032902cc0721070b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c1c0b02402008450d00200910350b20032d0088014104460d1620032802880121022000411c6a200329028c01370200200041186a200236020020004200370308420121070c1b0b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c1a0b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c190b20032802c00121032000411c6a2007370200200041186a200336020020004200370308420121070c180b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c170b20034180036a41186a200341c0056a41186a29030037030020034180036a41106a200341c0056a41106a29030037030020034180036a41086a200341c0056a41086a290300370300200320032903c005370380034100210a20034180036a2101410021080b0240200a200f470d0020034188016a200a4101108a01200328028c01210f200328028801210e0b200e20084105746a220241206a2002200a20086b410574109e081a20022001290000370000200241186a200141186a290000370000200241106a200141106a290000370000200241086a200141086a2900003700002003200a41016a22023602900120034180036a41186a420037030020034180036a41106a2209420037030020034180036a41086a22014200370300200342003703800341d1c4c700ad4280808080e000841001220829000021072001200841086a29000037030020032007370380032008103541e7c4c700ad4280808080e00084100122082900002107200341e0076a41086a220a200841086a290000370300200320073703e00720081035200920032903e0072207370300200341c8066a41086a2001290300370300200341c8066a41106a2007370300200341c8066a41186a200a29030037030020032003290380033703c806200341386a200341c8066a412010c001200328023c21092003280238210a200341c8066a20034180026a1091052002410574220b41047241046a2201417f4c0d0120033502d006210720032802c8062110200110332208450d112008200941809c316a41809c31200a1b2211360000200341043602880320032001360284032003200836028003200220034180036a10770240024020020d0020032802880321012003280284032109200328028003210d0c010b410020032802880322016b210a200328028003210d2003280284032109200e210c0340200c210202402009200a6a411f4b0d00200141206a22082001490d032009410174220c2008200c20084b1b22084100480d03024002400240024020090d00024020080d004101210d0c020b20081033210d0c030b20092008470d010b200821090c020b200d200920081037210d0b20082109200d450d150b200241206a210c200d20016a22082002290000370000200841186a200241186a290000370000200841106a200241106a290000370000200841086a200241086a290000370000200a41606a210a200141206a2101200b41606a220b0d000b200320093602840320032001360288032003200d360280030b20074220862010ad842001ad422086200dad84100202402009450d00200d10350b024020032802cc06450d00201010350b0240200f41ffffff3f71450d00200e10350b20034180036a41086a410a3a000020034189036a20032903c005370000200341a9036a20032903800237000020034191036a200341c0056a41086a29030037000020034199036a200341c0056a41106a290300370000200341a1036a200341c0056a41186a290300370000200341b1036a20034180026a41086a290300370000200341b9036a20034180026a41106a290300370000200341c1036a20034180026a41186a290300370000200341063a008003200341cc036a201136020041b0b4cc00410020034180036a10d40141d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c001200341c0016aad42808080808004841007200341043a00c8070c100b103e000b1044000b200941ff01710d00200c200b4f0d010b200341023a00c8070c010b41d9e3cb00ad42808080809001841001220229000021072002290008210520021035419c8dc500ad4280808080c001841001220229000021062002290008211920021035200320193701d801200320063701d001200320053701c801200320073701c00120034180036a200341c0016a10c0020240024020032d00a00322024103460d0020032f018003210120032d008203210920032d008303210a20032f018403210b20032d008603210c20032d008703210e20032f018803210f20032d008a03211020032d008b03211120032f018c03211220032d008e03211320032d008f03211420032f019003211520032d009203211620032d009303211720032f019403211820032d009603211e20032d009703211f20032003290398033703d8052003201f3a00d7052003201e3a00d605200320183b01d405200320173a00d305200320163a00d205200320153b01d005200320143a00cf05200320133a00ce05200320123b01cc05200320113a00cb05200320103a00ca052003200f3b01c8052003200e3a00c7052003200c3a00c6052003200b3b01c4052003200a3a00c305200320093a00c205200320013a00c00541082109200320014108763a00c10502402002450d004109210920034180026a200341c0056a412010a008450d040b200341c8076a200910e8040c010b200341c8076a410210e8040b20032d00c8074104460d0b20032902cc0721070b20032802c80721032000411c6a2007370200200041186a200336020020004200370308420121070c0f0b41d9e3cb00ad42808080809001841001220129000021072001290008210520011035419c8dc500ad4280808080c001841001220129000021062001290008211920011035200320193701d801200320063701d001200320053701c801200320073701c001200341c0016aad4280808080800484100720034180036a41186a220b420037030020034180036a41106a2209420037030020034180036a41086a22014200370300200342003703800341d1c4c700ad4280808080e000841001220a29000021072001200a41086a2900003703002003200737038003200a103541e7c4c700ad4280808080e000841001220a2900002107200341e0076a41086a220c200a41086a290000370300200320073703e007200a1035200920032903e0072207370300200341c8066a41086a2001290300370300200341c8066a41106a2007370300200341c8066a41186a200c29030037030020032003290380033703c806200341306a200341c8066a412010c0012003280234210a2003280230210c200b20034180026a41186a290300370300200920034180026a41106a290300370300200120034180026a41086a290300370300200320032903800237038003200a4100200c1b20086a20034180036a2002200d10e904200341043a00c8070c090b200341c0016a41086a20034180026a41086a2902002207370300200341c0016a41106a20034180026a41106a290200370300200341c0016a41186a20034180026a41186a290200370300200341c0016a41206a20034180026a41206a290200370300200341c0016a41286a20034180026a41286a290200370300200341c0016a41306a20034180026a41306a290200370300200341c0016a41386a20034180026a41386a280200360200200320032902800222053703c001200341e0076a41086a20073e0200200320053703e0070b20032d00e0074104460d0720032902e40721070b20032802e00721032000411c6a2007370200200041186a200336020020004200370308420121070c0b0b20032802880121032000411c6a2007370200200041186a2003360200420121070b200042003703080c090b20032802c007210120032802bc07210920032802b80721020b2002450d0020072001ad4220862002ad8410022009450d01200210350c010b41d9e3cb00ad42808080809001841001220229000021192002290008211a2002103541918dc500ad4280808080b0018410012202290000211b2002290008211c200210352003201c3701d8012003201b3701d0012003201a3701c801200320193701c001410810332202450d0220034208370284032003200236028003410120034180036a107720032802ac0120034180036a108c05200328028403210220072003350288034220862003280280032201ad8410022002450d00200110350b20034198036a200537030020034190036a20063703002003418c036a200836020020034188036a41003a0000200341063a00800341b0b4cc00410020034180036a10d401200341043a00780b42002107200042003703080c040b1045000b103c000b200341023a00780b200328027821032000411c6a2007370200200041186a200336020020004200370308420121070b20002007370300200424000b880101027f230041106b220224002002200028020036020c20012002410c6a4104107802404120103322030d001045000b20032000290004370000200341186a2000411c6a290000370000200341106a200041146a290000370000200341086a2000410c6a2900003700002001200341201078200310352001200041246a41201078200241106a24000bb91e06037f0d7e027f017e057f047e230041b0066b22042400200441d0036a200210f504200441d0046a20042802d003220520042802d80310b30220042d00d0042106200441e0036a200441d0046a41017241e700109d081a024002400240024020064102460d00200441c0056a200441e0036a41e700109d081a024020042802d403450d00200510350b200441e8026a200441c0056a41e700109d081a200441d0046a200441e8026a41e700109d081a2006450d01200441f8016a411410e8040c020b024020042802d403450d00200510350b200441f8016a411410e8040c010b200441fc016a200441d7046a41e000109d081a200441c8016a41206a200441cc026a2902002207370300200441c8016a41186a200441c4026a2902002208370300200441c8016a41106a200441bc026a2902002209370300200441c8016a41086a200441b4026a290200220a370300200441c8016a41286a2206200441d4026a290200370300200420042902ac02220b3703c80120044184026a290200210c20044194026a290200210d200441a4026a290200210e20042902fc01210f200429028c022110200429029c022111200441e8026a41086a200a370300200441e8026a41106a2009370300200441e8026a41186a2008370300200441e8026a41206a2007370300200441e8026a41286a20062903003703002004200b3703e802200341186a2903002112200341086a2903002108200341206a2903002113200341106a290300210720032d00002114200441e0036a2001108e02200441d0046a20042802e003221520042802e803108f02427f200720137c200820127c220a2008542206ad7c22092006200920075420092007511b22061b2007201441014622051b2109427f200a20061b200820051b210b200441d0046a41106a290300420020042903d00442015122061b210a20042903d804420020061b2116024020042802e403450d00201510350b0240024002400240024002400240024002400240200b2016562009200a562009200a511b0d00200441c8016a2001109605200441d0046a20042802c801221720042802d001221810c90220042d00d0042106200441c0056a200441d0046a41017241ef00109d081a0240024020064102470d00200441f0036a4200370300200441f8036a420037030020044180046a420037030020044188046a420037030020044190046a420037030020044198046a420037030041002106200441a0046a4100360200200441083602e403200441e0036a41086a4200370300200441003a00e0030c010b200420063a00e003200441e0036a410172200441c0056a41ef00109d081a0b411e210520060d0420042802e403211941002106024002400240024002400240200441ec036a280200221a41014b0d00201a0e020201020b201a2105034020062005410176221520066a221b2019201b41306c6a28020020024b1b2106200520156b220541014b0d000b0b2019200641306c6a28020022052002460d01200620052002496a21060b200441f4046a200341206a290200370200200441ec046a200341186a290200370200200441e4046a200341106a290200370200200441dc046a200341086a290200370200200420032902003702d404201a2006490d010240201a200441e0036a41086a280200470d00200441e0036a410472201a410110880120042802e40321190b2019200641306c6a220541306a2005201a20066b41306c109e081a20052002360200200520042902d0043702042005410c6a200441d8046a290200370200200541146a200441e0046a2902003702002005411c6a200441e8046a290200370200200541246a200441f0046a2902003702002005412c6a200441f8046a2802003602002004201a41016a3602ec030c060b201a20064d0d012019200641306c6a220641186a290300211c200641106a290300210a0240024020062d000822154101470d0041202105200441e8006a200641206a290300221d200641286a290300221e420a4200109808200441f8006a200a201c420a42001098082011200a7d221f201156200e201c7d2011200a54ad7d221c200e56201c200e511b0d08201f201d7d2216201f56201c201e7d201f201d54ad7d220a201c56200a201c511b0d08200f2004290378220e7d221f200f56200c200441f8006a41086a2903007d200f200e54ad7d221c200c56201c200c511b0d0920102004290368220e7d220f201056200d200441e8006a41086a2903007d2010200e54ad7d220c200d56200c200d511b450d010c0a0b200641096a2d0000211b024002402006410a6a2d0000220541ff0171450d00200441a8016a201c42002005ad42ff018322164200108408200441b8016a200a42002016420010840820044198016a42004200200a4200108408427f200441c0016a290300221620042903a8012004290398017c7c221f20042903b00120042903a00184420052201f2016547222051b211d427f20042903b80120051b211f0c010b20044188016a200a201c420a420010980820044190016a290300211d200429038801211f0b412021052011200a7d2216201156200e201c7d2011200a54ad7d220a200e56200a200e511b0d070240201b41ff01710d002010201f7d2211201056200d201d7d2010201f54ad7d220e200d56200e200d511b0d0920112110200e210d200f211e200c211c0c050b200f201f7d221e200f56200c201d7d200f201f54ad7d221c200c56201c200c511b450d040c080b20162111200a210e200f2110200c210d201f210f201c210c0c040b2006201a104d000b2006201a41ecc0c6001042000b2000412110e8040c0a0b0240024020150d00201b41ff01714102460d004200200a20044188046a2903007d201620044180046a290300221154ad7d220e201620117d2211201656200e200a56200e200a511b22051b210e4200201120051b2111200441f8036a290300211620042903f003210a0240201b4101710d004200200d20167d2010200a54ad7d22162010200a7d220a2010562016200d562016200d511b22051b210d4200200a20051b21100c020b4200201c20167d201e200a54ad7d2216201e200a7d220a201e562016201c562016201c511b22051b210c4200200a20051b210f0c020b20162111200a210e0b201e210f201c210c0b200641086a22062003290300370300200641206a200341206a290300370300200641186a200341186a290300370300200641106a200341106a290300370300200641086a200341086a2903003703000b0240024020144101470d00200441086a20122013420a4200109808200441186a20082007420a4200109808411f2105201120087c22082011542206200e20077c2006ad7c2207200e542007200e511b0d02200820127c22162008542206200720137c2006ad7c220a200754200a2007511b0d02200f20042903187c221f200f542206200c200441186a41086a2903007c2006ad7c221c200c54201c200c511b0d03201020042903087c22082010542206200d200441086a41086a2903007c2006ad7c2207200d542007200d511b0d040c010b20032d0001211502400240200341026a2d0000220641ff0171450d00200441c8006a200742002006ad42ff0183220a4200108408200441d8006a20084200200a4200108408200441386a4200420020084200108408427f200441e0006a290300220a200429034820042903387c7c221220042903502004290340844200522012200a547222061b2112427f200429035820061b21130c010b200441286a20082007420a4200109808200441306a2903002112200429032821130b411f2105201120087c22162011542206200e20077c2006ad7c220a200e54200a200e511b0d0102400240201541ff01710d00201020137c22082010542206200d20127c2006ad7c2207200d542007200d511b0d04200821102007210d200f211f200c211c0c010b200f20137c221f200f542206200c20127c2006ad7c221c200c54201c200c511b0d030b024020140d00201541ff01714102460d00427f200a20044188046a2903007c201620044180046a2903007c22082016542206ad7c220720062007200a542007200a511b22061b210a427f200820061b2116200441f8036a290300210720042903f0032108024020154101710d00427f200d20077c201020087c22082010542206ad7c220720062007200d542007200d511b22061b2107427f200820061b21080c020b427f201c20077c201f20087c2208201f542206ad7c220720062007201c542007201c511b22061b211c427f200820061b211f0b20102108200d21070b200441043a00f8010c040b20112116200e210a0b20102108200d2107200f211f200c211c0c010b20102108200d21070b200441f8016a200510e80420042d00f80122064104460d00200420042900f9013703c0052004200441f8016a41086a2800003600c70520042d00e0030d01200441e0036a41086a2802002203450d01200341306c450d0120042802e40310350c010b200441d0046a200441e0036a41f000109d081a0240024020042d00d00422064102470d002018ad4220862017ad8410070c010b200441c0056a200441d0046a1080052018ad4220862017ad8420043502c80542208620042802c0052203ad841002024020042802c405450d00200310350b20060d00200441d8046a2802002206450d00200641306c450d0020042802d40410350b200420042900f9013703c005200420044180026a2800003600c705410421060b024020042802cc01450d00201710350b200420042903c0053703d003200420042800c7053600d703024020064104470d00200442e4cab5fbb6ccdcb0e3003703e002200441e0026a2001200b200910ea0220044180056a200a370300200441d0046a41286a2016370300200441d0046a41206a2007370300200441d0046a41186a2008370300200441d0046a41106a201c37030020044188056a20042903e80237030020044190056a200441f0026a29030037030020044198056a200441e8026a41106a290300370300200441a0056a200441e8026a41186a290300370300200441a8056a200441e8026a41206a290300370300200441b0056a200441e8026a41286a2903003703002004201f3703d804200441003a00d004200441e0036a200210f50420042802e0032106200420042802e8033602c405200420063602c005200441d0046a200441c0056a10f604024020042802e403450d00200610350b200041043a00000c020b200020063a0000200020042903d003370001200041086a20042800d7033600000c010b20042802f8012106200041046a20042902fc01370200200020063602000b200441b0066a24000b810703047f017e027f23004180016b22022400200241186a2203200141186a290000370300200241106a2204200141106a290000370300200241086a2205200141086a2900003703002002200129000037030041d9e3cb00ad4280808080900184100122012900002106200241286a41086a200141086a290000370300200220063703282001103541e4a6cb00ad4280808080d00084100122012900002106200241386a41086a200141086a29000037030020022006370338200110350240024002400240412010332201450d0020012002290300370000200141186a2003290300370000200141106a2004290300370000200141086a200529030037000020022001ad42808080808004841003220329000037037820031035200241e4006a200141206a360200200220013602602002200241f8006a41086a36025c2002200241f8006a360258200241c8006a200241d8006a107b200110352002280250220741206a2203417f4c0d01200228024821080240024020030d0041002104410121010c010b200310332201450d01200321040b024002402004410f4d0d00200421050c010b200441017422054110200541104b1b22054100480d03024020040d002005103322010d010c050b20042005460d0020012004200510372201450d040b20012002290328370000200141086a200241286a41086a2903003700000240024020054170714110460d00200521040c010b200541017422044120200441204b1b22044100480d0320052004460d0020012005200410372201450d040b20012002290338370010200141186a200241386a41086a29030037000002400240200441606a2007490d00200421050c010b2007415f4b0d03200441017422052003200520034b1b22054100480d0320042005460d0020012004200510372201450d040b200141206a20082007109d081a0240200228024c450d00200810350b20022001200310c402200241e0006a2203200241096a290000370300200241e8006a2204200241116a290000370300200241f0006a2207200241196a290000370300200220022900013703580240024020022d000022084102470d00200041023a00000c010b200020083a000020002002290358370001200041096a2003290300370000200041116a2004290300370000200041196a20072903003700000b02402005450d00200110350b20024180016a24000f0b1045000b1044000b103e000b103c000b9f0303027f017e027f230041206b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a200341086a29000037030020022004370300200310354184a4c600ad4280808080d00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000ba10202067f017e230041106b2202240002400240412010332203450d0020032000290000370000200341186a2204200041186a290000370000200341106a2205200041106a290000370000200341086a2206200041086a290000370000412010332207450d0120072003290000370000200741186a2004290000370000200741106a2005290000370000200741086a2006290000370000200310350240024020002d0020220341024d0d004280808080800421080c010b024002400240024020030e03000102000b410021030c020b410121030c010b410221030b200220033a000f2007412041c00010372207450d02200720033a00204280808080900421080b200129020020082007ad84100220071035200241106a24000f0b1045000b103c000b9f0303027f017e027f230041206b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a200341086a290000370300200220043703002003103541b8a3c600ad4280808080900184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000bb10503027f017e047f230041d0006b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541e4a6cb00ad4280808080d00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bfe2208047f027e047f077e037f087e157f017e23002206210720064180056b416071220624000240024020012002460d0020012002412010a008450d00200641a0016a2001108e0220064180046a20062802a001220820062802a801108f0220064190046a290300420020062903800442015122091b210a200629038804420020091b210b024020062802a401450d00200810350b200b200454200a200554200a2005511b450d012000412110e804200724000f0b2000412510e804200724000f0b20064190016a200110960520064180046a200628029001220c200628029801220d10c90220064190036a41026a220920062d0083043a0000200641c8036a41086a220820064180046a41e0006a290300370300200641c8036a41106a220e20064180046a41e8006a290300370300200620062f0081043b019003200620064180046a41d8006a2903003703c8030240024020062d008004220f4102470d00200641a0016a41c0006a220941003602004200210b200641a0016a41106a4200370300200641a0016a41186a4200370300200641a0016a41206a4200370300200641a0016a41286a4200370300200641a0016a41306a4200370300200641a0016a41386a4200370300200641083602a401200641a0016a41086a4200370300200641003a00a001200641a0016a41d0006a2903002110200641a0016a41c8006a2903002111200929030021124200210a42002113420021140c010b20064180046a41d0006a290300211020064180046a41c8006a290300211120064180046a41386a290300211420064180046a41286a290300210a20064180046a41206a290300210b20064180046a41186a290300211520064180046a41106a290300211620064180046a41306a290300211320064180046a410c6a280200211720064180046a41086a28020021182006280284042119200641a0016a41c0006a20064180046a41c0006a2903002212370300200641a0016a41386a2014370300200641a0016a41286a200a370300200641a0016a41206a200b370300200641a0016a41186a2015370300200641a0016a41106a2016370300200641a0016a41d0006a2010370300200641a0016a41c8006a2011370300200641a0016a41306a2013370300200641a0016a410c6a2017360200200641a0016a41086a2018360200200641a0016a41d8006a20062903c803370300200641a0016a41e0006a2008290300370300200641a0016a41e8006a200e2903003703002006200f3a00a001200620062f0190033b00a101200620193602a401200620092d00003a00a3010b2006200241106a2900003700b1022006200241176a2900003700b8022006200241086a2900003700a902200620022900003700a10220062903b802211a2006200641b8016a2209290300221b3703b80220062903b002211c200620062903b001221d3703b00220062903a802211e200620062903a801221f3703a802200641013a00a00220062903a0022116200620062903a00122153703a002200231001f2120200641d8016a4200370300200641d0016a2005370300200641c8016a20043703002009201a370300200620202003ad222142ff0183420886843703c0012006201c3703b0012006201e3703a801200620163703a001200641f8016a2209290300211a20094200370300200641f0016a4200370300200641e8016a4200370300200642003703e00120064188026a2208280200210f20064180026a220e290300211c20084100360200200e420037030002400240024002400240024002402015a741ff01714101460d002015422088a7210f201fa72108201f422088a70d02200641d8016a200641b0016a2016a741ff017141014622171b220e201b370308200e201d370300200e200b370310200e41186a200a3703002009200641a0016a41306a20171b22092012a736021020092014370308200920133703002008450d01200841306c450d01200f10350c010b20064180046a41176a200641a0026a410172220841176a29000037000020064180046a41106a200841106a29000037030020064180046a41086a200841086a2900003703002006200b3c009f04200620082900003703800402400240200b420888200a42388684220ba741ff0171450d00200641e0006a20134200200b42ff0183220b4200108408200641f0006a200a4200200b4200108408200641d0006a42004200200a4200108408427f200641f8006a290300220b200629036020062903507c7c221520062903682006290358844200522015200b547222081b210b427f200629037020081b21150c010b200641c0006a200a2013420a4200109808200641c8006a290300210b200629034021150b20064180046a2015200b200a2013109805200641d8016a200641b0016a20062d00a001410146220e1b2208201137031020082012370308200841186a2010370300200820143703002009200641d0016a200e1b2209201a3703002009201c3703082009200f3602100b02400240200341ff0171450d00200641206a20054200202142ff0183220a4200108408200641306a20044200200a4200108408200641106a4200420020044200108408427f200641386a290300220a200629032020062903107c7c220b2006290328200629031884420052200b200a547222031b2121427f200629033020031b211b0c010b200620042005420a4200109808200641086a29030021212006290300211b0b200641d0026a200210960520064180046a20062802d002222220062802d802222310c90220064190036a41026a220320062d0083043a000041082124200641c8036a41086a200641e0046a290300370300200641c8036a41106a2209200641e8046a290300370300200620062f0081043b0190032006200641d8046a2903003703c803200641d0046a290300211a200641c8046a290300211f0240024020062d00800422254102470d004200211041002126410021274200211c420021114200211e4200211d4200211242002120410021250c010b200641c0046a2903002120200641b8046a2903002112200641a8046a290300211e200641a0046a290300211120064198046a290300211c20064180046a41106a2903002110200641b0046a290300211d2006418c046a280200212720064180046a41086a28020021262006280284042124200641fc026a41026a20032d00003a0000200641e0026a41086a200641c8036a41086a290300370300200641e0026a41106a2009290300370300200620062f0190033b01fc02200620062903c8033703e0020b20254101460d01427f201e20057c201120047c220b2011542203ad7c220a2003200a201e54200a201e511b22031b211e427f200b20031b2111427f201c20217c2010201b7c220b2010542203ad7c220a2003200a201c54200a201c511b22031b211c427f200b20031b2110202741306c2203450d02202420036a2119200641b8046a210920064180046a410172222841036a2129202421030340200341306a21080240200341086a2d00004101710d00200341096a2d0000212a20064180036a200328020010f50420064180046a2006280280032203200628028803222b10b302200641c8036a41086a222c200941086a222d290000370300200641c8036a41106a222e200941106a222f290000370300200641c8036a41186a2230200941186a2231290000370300200641c8036a41206a2232200941206a2233290000370300200641c8036a41286a2234200941286a2235290000370300200620282800003602f803200620292800003600fb03200620092900003703c80320064180046a41306a210e20064180046a41206a210f20064180046a41106a2117024020062d00800422184102472236450d00200e290300210a200f29030021152017290300211320062903a804210b2006290398042114200629038804211620064190036a41086a202c29030037030020064190036a41106a202e29030037030020064190036a41186a203029030037030020064190036a41206a203229030037030020064190036a41286a2034290300370300200620062800fb033600c303200620062802f8033602c003200620062903c8033703900320180d00427f200a20057c200b20047c2237200b54222cad7c220b202c200b200a54200b200a511b222c1b210a427f2037202c1b210b0240202a4101710d00427f201520217c2014201b7c2237201454222cad7c2214202c201420155420142015511b222c1b2115427f2037202c1b21140c010b427f201320217c2016201b7c2237201654222cad7c2216202c201620135420162013511b222c1b2113427f2037202c1b21160b202820062802c0033600002009200629039003370300200e200a370300200f201537030020172013370300202920062800c303360000202d20064190036a41086a290300370300202f20064190036a41106a290300370300203120064190036a41186a290300370300203320064190036a41206a290300370300203520064190036a41286a2903003703002006200b3703a80420062014370398042006201637038804200620183a0080040240024020360d00202bad4220862003ad8410070c010b2006202b3602cc03200620033602c80320064180046a200641c8036a1099050b200628028403450d00200310350b2008210320192008470d000c030b0b20064190026a412310e80402402008450d00200841306c450d00200f10350b20062d00900222034104460d0220062006290091023703c803200620064190026a41086a2800003600cf0320062d00a0010d03200641a0016a41086a2802002209450d03200941306c450d0320062802a40110350c030b427f201a20057c201f20047c220b201f542203ad7c220a2003200a201a54200a201a511b22031b211a427f200b20031b211f427f202020217c2012201b7c220b2012542203ad7c220a2003200a202054200a2020511b22031b2120427f200b20031b21120b200641d0046a201a370300200641c8046a201f370300200641c0046a2020370300200641b8046a2012370300200641a8046a201e370300200641a0046a201137030020064198046a201c37030020064180046a41106a2010370300200641b0046a201d3703002006418c046a202736020020064180046a41086a2026360200200641d8046a20062903e002370300200641e0046a200641e0026a41086a290300370300200641e8046a200641e0026a41106a290300370300200620062f01fc023b00810420062024360284042006200641fc026a41026a2d00003a008304200620253a0080040240024020254102470d002023ad4220862022ad8410070c010b200641c8036a20064180046a1080052023ad4220862022ad8420063502d00342208620062802c8032203ad841002024020062802cc03450d00200310350b20250d002026450d00202641306c450d00202410350b024020062802d402450d00202210350b200642e4cab5fbb6ccdcb0e3003703c802200641c8026a20012004200510ea02200641043a0090020b20064180046a200641a0016a41f000109d081a0240024020062d00800422034102470d00200dad422086200cad8410070c010b200641c8036a20064180046a108005200dad422086200cad8420063502d00342208620062802c8032209ad841002024020062802cc03450d00200910350b20030d0020064188046a2802002203450d00200341306c450d0020062802840410350b20062006290091023703c803200620064198026a2800003600cf03410421030b0240200628029401450d00200c10350b200620062903c80337038001200620062800cf0336008701024020034104470d0020064180046a41086a41083a000020064189046a200129000037000020064191046a200141086a29000037000020064199046a200141106a290000370000200641a1046a200141186a290000370000200641a9046a2002290000370000200641b1046a200241086a290000370000200641b9046a200241106a290000370000200641c1046a200241186a290000370000200641063a00800441b0b4cc00410020064180046a10d401200041043a0000200724000f0b200020033a00002000200629038001370001200041086a200628008701360000200724000bc90e0b057f017e017f057e027f057e017f027e017f037e017f230022022103200241e0046b41607122022400200241e0006a2001109605200241d0036a200228026022042002280268220510c90220022d00d0032106200241f0016a200241d0036a41017241ef00109d081a0240024020064102470d004200210720024180016a420037030020024188016a420037030020024190016a420037030020024198016a4200370300200241a0016a4200370300200241a8016a420037030041002108200241b0016a410036020020024108360274200241f0006a41086a4200370300200241003a007042002109410021064200210a4200210b4200210c0c010b200220063a0070200241f0006a410172200241f0016a41ef00109d081a20024190016a290300220d420888a72106200241d0016a2903002109200241a0016a290300210b20024198016a290300210a200241a8016a290300210c200241d8016a280200210e200da72108420021070b200241a8016a4200370300200241f0006a41306a420037030020024198016a420037030020024188016a220f290300210d200f42003703002002410836028403200241003a008003200241003602e00220022903800121102002420037038001200229037821112002420037037820024200370390012002200d370398032002201037039003200220113703880320022903f80221122002200241c8016a220f29030022133703f80220022903f00221142002200241c0016a221529030022163703f00220022903e80221172002200241b8016a221829030022193703e802200229038003210d200220022903702210370380032002200d37037020022903e002211a200220022903b001221b3703e002200f201237030020152014370300201820173703002002201a3703b001200da7210f0240024002402010a741ff017122154101460d00200241e0016a412210e804024020150d002011a72206450d00200641306c450d002010422088a710350b20022d00e00122064104460d01200220022900e1013703f0012002200241e8016a2800003600f701200f41ff01710d0241010d0241010d02200d422088a710350c020b200241c7036a200229009803370000200241c0036a200229009103370300200241b0036a41086a20022900890337030020022002290081033703b003200220083a00cf0302400240200641ff0171450d00200241306a200b42002006ad42ff0183220d4200108408200241c0006a200a4200200d4200108408200241206a42004200200a4200108408427f200241c8006a290300220d200229033020022903207c7c221120022903382002290328844200522011200d547222151b210d427f200229034020151b21110c010b200241106a200a200b420a4200109808200241186a290300210d200229031021110b200241b0036a2011200d200a200b109805200241d0036a41186a4200370300200241d0036a41106a22084200370300200241d0036a41086a22154200370300200242003703d00341d1c4c700ad4280808080e0008410012218290000210d2015201841086a2900003703002002200d3703d0032018103541e7c4c700ad4280808080e0008410012218290000210d200241d0046a41086a221c201841086a2900003703002002200d3703d00420181035200820022903d004220d370300200241f0016a41086a2015290300370300200241f0016a41106a200d370300200241f0016a41186a201c290300370300200220022903d0033703f001200241086a200241f0016a412010c001200228020c211520022802082118200241a8016a200241f0006a41106a200f41ff017141014622081b220f41186a2016370300200f2019370310200f201b370308200f200c370300200241c8016a200241a0016a20081b220f2007201384220d200a200d200a562009200b562009200b511b22081b370300200f2009200b20081b370308200f200e20064118744118754102744184e4cb006a2802004180de346c2015410020181b6a2206200e20064b1b360210200241043a00e0010b200241d0036a200241f0006a41f000109d081a0240024020022d00d00322064102470d002005ad4220862004ad8410070c010b200241f0016a200241d0036a1080052005ad4220862004ad8420023502f80142208620022802f001220fad841002024020022802f401450d00200f10350b20060d00200241d8036a2802002206450d00200641306c450d0020022802d40310350b200220022900e1013703f0012002200241e8016a2800003600f701410421060b02402002280264450d00200410350b200220022903f001370350200220022800f7013600570240024020064104470d00200241d0036a41086a41093a0000200241d0036a41096a2001290000370000200241e1036a200141086a290000370000200241e9036a200141106a290000370000200241f1036a200141186a290000370000200241063a00d00341b0b4cc004100200241d0036a10d4010c010b20002002290350370001200041086a20022800573600000b200020063a0000200324000bb50403047f017e017f230041c0006b22022400200241186a2203200041186a290000370300200241106a2204200041106a290000370300200241086a2205200041086a2900003703002002200029000037030041d9e3cb00ad4280808080900184100122002900002106200241206a41086a200041086a290000370300200220063703202000103541888dc500ad4280808080900184100122002900002106200241306a41086a200041086a29000037030020022006370330200010350240412010332200450d0020002002290300370000200041186a2003290300370000200041106a2004290300370000200041086a2005290300370000412010332203450d0020032000290000370000200341186a2204200041186a290000370000200341106a2205200041106a290000370000200341086a2207200041086a2900003700002000103541c00010332200450d002000200229033037001020002002290320370000200041086a200241206a41086a290300370000200041186a200241306a41086a29030037000020002003290000370020200041286a2007290000370000200041306a2005290000370000200041386a20042900003700002003103520024100360208200242013703002001200210ef04200228020421032000ad4280808080800884200235020842208620022802002204ad84100202402003450d00200410350b20001035024020012d0000450d00200141286a280200450d00200141246a28020010350b200241c0006a24000f0b1045000bb10503027f017e047f230041d0006b2202240041d9e3cb00ad4280808080900184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541a4a1c600ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bca1c08077f067e0a7f017e017f057e017f067e23004180046b2204240020044198026a200210f504200441c8026a200428029802220520042802a00210b302200441b8036a41086a220620044188036a290300370300200441b8036a41106a220720044190036a290300370300200441b8036a41186a220820044198036a290300370300200441b8036a41206a2209200441a0036a290300370300200441b8036a41286a220a200441a8036a290300370300200420044180036a2903003703b803200441f8026a290300210b200441c8026a41286a290300210c200441c8026a41206a290300210d200441c8026a41186a290300210e200441c8026a41106a290300210f200441c8026a41086a290300211020042802cc02211120042d00c9022112024020042d00c80222134102460d00200441e8006a41286a200a290300370300200441e8006a41206a2009290300370300200441e8006a41186a2008290300370300200441e8006a41106a2007290300370300200441e8006a41086a2006290300370300200420042903b8033703680b0240200428029c02450d00200510350b20044198016a41286a2205200441e8006a41286a29030037030020044198016a41206a2206200441e8006a41206a29030037030020044198016a41186a2207200441e8006a41186a29030037030020044198016a41106a2214200441e8006a41106a29030037030020044198016a41086a2215200441e8006a41086a2903003703002004200429036837039801200441c8016a2001109605200441c8026a20042802c801221620042802d00110c90220044198026a41026a220120042d00cb023a0000200441b8036a41086a20044194036a290200370300200441b8036a41106a22172004419c036a290200370300200441b8036a41186a2218200441a4036a290200370300200441b8036a41206a2219200441ac036a290200370300200441b8036a41286a221a200441b4036a280200360200200420042f00c9023b01980220042004418c036a2902003703b8030240024020042d00c80222094102470d004200211b4100210a4100211c4200211d4200211e4200211f42002120420021214100212241082108410021090c010b20044180036a2903002121200441f8026a2903002120200441c8026a41286a290300211f200441c8026a41206a290300211e200441c8026a41186a290300211d200441c8026a41106a290300211b20044188036a2802002122200441d4026a280200211c200441c8026a41086a280200210a20042802cc02210820044184026a41026a20012d00003a0000200441d8016a41086a200441b8036a41086a290300370300200441d8016a41106a2017290300370300200441d8016a41186a2018290300370300200441d8016a41206a2019290300370300200441d8016a41286a201a280200360200200420042f0198023b018402200420042903b8033703d8010b20044198026a41286a200529030037030020044198026a41206a200629030037030020044198026a41186a200729030037030020044198026a41106a201429030037030020044198026a41086a2015290300370300200420042903980137039802024002400240024020090d00410021010240024002400240024002400240024002400240201c41014b0d00201c0e020201020b201c2105034020012005410176220620016a22072008200741306c6a28020020024b1b2101200520066b220541014b0d000b0b2008200141306c6a2802002002470d00024002402013410371417f6a220541014b0d0020050e020109010b200441b8036a41286a20044198026a41286a290300370300200441b8036a41206a20044198026a41206a290300370300200441b8036a41186a20044198026a41186a290300370300200441b8036a41106a20044198026a41106a290300370300200441b8036a41086a20044198026a41086a29030037030020042004290398023703b803411d2106024020030d00201c20014d0d032008200141306c6a220541186a2903002123200541106a2903002124024020052d000822074101470d00412021062004200541206a2903002225200541286a2903002226420a4200109808200441106a20242023420a4200109808200c20247d2227200c56200b20237d200c202454ad7d2224200b562024200b511b0d01202720257d2228202756202420267d2027202554ad7d220c202456200c2024511b0d0120102004290310220b7d2224201056200f200441106a41086a2903007d2010200b54ad7d220b200f56200b200f511b0d01200e2004290300220f7d2210200e56200d200441086a2903007d200e200f54ad7d220f200d56200f200d511b0d010c090b200541096a2d00002114024002402005410a6a2d0000220541ff0171450d00200441c0006a202342002005ad42ff018322274200108408200441d0006a2024420020274200108408200441306a4200420020244200108408427f200441d8006a2903002227200429034020042903307c7c2228200429034820042903388442005220282027547222051b2125427f200429035020051b21270c010b200441206a20242023420a4200109808200441286a2903002125200429032021270b41202106200c20247d2228200c56200b20237d200c202454ad7d220c200b56200c200b511b0d000240201441ff01710d00200e20277d2226200e56200d20257d200e202754ad7d2223200d562023200d511b0d0120102124200f210b2026210e2023210d0c080b201020277d2224201056200f20257d2010202754ad7d220b200f56200b200f511b450d070b20044188026a200610e8040c050b201c20014d0d022008200141306c6a22052d00080d07201241ff0171410047200541096a2d00004573450d07200541186a290300210c200541106a290300210f2008200141306c6a410a6a2c00002107200441c8026a41186a4200370300200441c8026a41106a22024200370300200441c8026a41086a22054200370300200442003703c80241d1c4c700ad4280808080e0008410012206290000210b2005200641086a2900003703002004200b3703c8022006103541e7c4c700ad4280808080e0008410012206290000210b200441e8036a41086a2214200641086a2900003703002004200b3703e80320061035200220042903e803220b370300200441b8036a41086a2005290300370300200441b8036a41106a200b370300200441b8036a41186a2014290300370300200420042903c8023703b803200441e0006a200441b8036a412010c0012004280264410020042802601b20074102744184e4cb006a2802004180de346c20116a22054f0d0720030d032021200c2020200f562021200c562021200c511b22061b21212020200f20061b212020222005202220054b1b21220c070b20044188026a411c10e8040c030b2001201c4194c0c6001042000b2001201c41a4c0c6001042000b20044188026a411d10e8040b20042d00880222014104460d0420042004290089023703b803200420044190026a2800003600bf03200a450d05200a41306c450d05200810350c050b024020070d00201441ff01714102460d004200200c201f7d2028201e54ad7d220f2028201e7d2210202856200f200c56200f200c511b22051b210c4200201020051b2128024020144101710d004200200d201d7d200e201b54ad7d220f200e201b7d2210200e56200f200d56200f200d511b22051b210f4200201020051b21100c020b4200200b201d7d2024201b54ad7d220f2024201b7d2210202456200f200b56200f200b511b22051b210b4200201020051b21240b200e2110200d210f0b200441f8026a200c370300200441c8026a41286a2028370300200441c8026a41206a200f370300200441c8026a41186a2010370300200441c8026a41106a200b37030020044180036a20042903b80337030020044188036a200441c0036a29030037030020044190036a200441b8036a41106a29030037030020044198036a200441b8036a41186a290300370300200441a0036a200441b8036a41206a290300370300200441a8036a200441b8036a41286a290300370300200420243703d002200441003a00c802200441e8036a200210f50420042802e8032105200420042802f0033602fc03200420053602f803200441c8026a200441f8036a10f60420042802ec03450d00200510350b201c20014d0d032008200141306c6a2205200541306a201c2001417f736a41306c109e081a201c417f6a211c0b200441043a0088020b20044180036a2021370300200441f8026a2020370300200441c8026a41286a201f370300200441c8026a41206a201e370300200441c8026a41186a201d370300200441c8026a41106a201b37030020044188036a2022360200200441d4026a201c360200200441c8026a41086a200a3602002004418c036a20042903d80137020020044194036a200441d8016a41086a2903003702002004419c036a200441d8016a41106a290300370200200441a4036a200441d8016a41186a290300370200200441ac036a200441d8016a41206a290300370200200441b4036a200441d8016a41286a280200360200200420042f0184023b00c902200420083602cc02200420044184026a41026a2d00003a00cb02200420093a00c8020240024020094102470d0020043502d00142208620042802c8012216ad8410070c010b20043502d001212120042802c8012116200441b8036a200441c8026a10800520214220862016ad8420043502c00342208620042802b8032201ad84100220042802bc03450d00200110350b0240200a450d0020090d00200a41306c450d00200810350b20042004290089023703b803200420044190026a2800003600bf03410421010b024020042802cc01450d00201610350b200420042903b8033703c802200420042800bf033600cf02024020014104460d00200020042903c802370001200041086a20042800cf023600000b200020013a000020044180046a24000f0b2001201c104e000bdb0e08057f027e017f017e027f087e157f067e230041a0026b2205240020052000109605200541306a200528020022062005280208220710c902200541b0016a41026a220020052d00333a000041082108200541e8016a41086a20054190016a290300370300200541e8016a41106a220920054198016a290300370300200520052f00313b01b001200520054188016a2903003703e80120054180016a290300210a200541f8006a290300210b0240024020052d0030220c4102470d004200210d4100210e4100210f4200211042002111420021124200211342002114420021154100210c0c010b200541f0006a2903002115200541e8006a2903002114200541d8006a2903002112200541d0006a2903002111200541c8006a2903002110200541306a41106a290300210d200541e0006a29030021132005413c6a280200210f200541306a41086a280200210e200528023421082005412c6a41026a20002d00003a0000200541106a41086a200541e8016a41086a290300370300200541106a41106a2009290300370300200520052f01b0013b012c200520052903e8013703100b02400240200c4101460d004200201220047d2011200354ad7d2216201120037d2217201156201620125620162012511b22001b21124200201720001b21114200201020027d200d200154ad7d2216200d20017d2217200d56201620105620162010511b22001b21104200201720001b210d200f41306c2200450d01200820006a2118200541e8006a2109200541306a410172221941036a211a200821000340200041306a211b0240200041086a2d00004101710d00200041096a2d0000211c200541a0016a200028020010f504200541306a20052802a001220020052802a801221d10b302200541e8016a41086a221e200941086a221f290000370300200541e8016a41106a2220200941106a2221290000370300200541e8016a41186a2222200941186a2223290000370300200541e8016a41206a2224200941206a2225290000370300200541e8016a41286a2226200941286a222729000037030020052019280000360298022005201a28000036009b02200520092900003703e801200541306a41306a2128200541306a41206a2129200541306a41106a212a024020052d0030222b410247222c450d00202829030021172029290300212d202a290300212e200529035821162005290348212f20052903382130200541b0016a41086a201e290300370300200541b0016a41106a2020290300370300200541b0016a41186a2022290300370300200541b0016a41206a2024290300370300200541b0016a41286a20262903003703002005200528009b023600e30120052005280298023602e001200520052903e8013703b001202b0d004200201720047d2016200354ad7d2231201620037d2232201656203120175620312017511b221e1b211742002032201e1b21160240201c4101710d004200202d20027d202f200154ad7d2231202f20017d2232202f562031202d562031202d511b221e1b212d42002032201e1b212f0c010b4200202e20027d2030200154ad7d2231203020017d22322030562031202e562031202e511b221e1b212e42002032201e1b21300b201920052802e001360000200920052903b001370300202820173703002029202d370300202a202e370300201a20052800e301360000201f200541b0016a41086a2903003703002021200541b0016a41106a2903003703002023200541b0016a41186a2903003703002025200541b0016a41206a2903003703002027200541b0016a41286a290300370300200520163703582005202f370348200520303703382005202b3a003002400240202c0d00201dad4220862000ad8410070c010b2005201d3602ec01200520003602e801200541306a200541e8016a1099050b20052802a401450d00200010350b201b21002018201b470d000c020b0b4200200a20047d200b200354ad7d2216200b20037d2217200b562016200a562016200a511b22001b210a4200201720001b210b4200201520027d2014200154ad7d2216201420017d2217201456201620155620162015511b22001b21154200201720001b21140b20054180016a200a370300200541f8006a200b370300200541f0006a2015370300200541e8006a2014370300200541d8006a2012370300200541d0006a2011370300200541c8006a2010370300200541306a41106a200d370300200541e0006a20133703002005413c6a200f360200200541306a41086a200e36020020054188016a200529031037030020054190016a200541106a41086a29030037030020054198016a200541106a41106a290300370300200520052f012c3b00312005200836023420052005412c6a41026a2d00003a00332005200c3a003002400240200c4102470d002007ad4220862006ad8410070c010b200541e8016a200541306a1080052007ad4220862006ad8420053502f00142208620052802e8012200ad841002024020052802ec01450d00200010350b200c0d00200e450d00200e41306c450d00200810350b02402005280204450d00200610350b200541a0026a24000ba60203027f017e017f230041106b22022400200241003602082002420137030002400240024020002d00004101460d00410110332203450d02200341003a0000200220033602002002428180808010370204200041086a200210a406200235020842208621042002280204452103200228020021000c010b410110332203450d01200341013a000020024281808080103702042002200336020020002d0001210520034101410210372203450d01200320053a00012002428280808020370204200220033602002000280204210520034102410610372200450d01200020053600022002200036020020024286808080e000370204410021034280808080e00021040b200129020020042000ad841002024020030d00200010350b200241106a24000f0b103c000bd21f04067f027e027f017e230041f0006b220624000240024002402002410c6a280200200241106a28020010172207417f460d00410c103322080d010c020b109b05000b200820073602082008428180808010370200200641186a420037030020064280808080c000370310200642043703080240024002400240024002402008280200220741016a220941014d0d00200820093602002007417e460d002008200741026a3602000240200628021c22072006280218470d00200641146a20074101108601200628021c21070b200628021420074102746a20083602002006200628021c41016a36021c2008280208210a200641d0006a41a58ecc0041031050200641206a41a9bbca0041061050200641e4006a200641206a41086a22092802003602002006200629032037025c200641206a41106a220b200641d0006a41106a2903003703002009200641d0006a41086a29030037030020062006290350370320024020062802102207200628020c470d00200641086a20074101109101200628021021070b200628020820074105746a22074101360218200720062903203702002007411c6a200a360200200741106a200b290300370200200741086a20092903003702002006200628021041016a36021020082008280200417f6a2207360200024020070d002008280208101820082008280204417f6a220736020420070d00200810350b200641086a41a88ecc004103411110e604200641086a41c6dfcb00410f411210e604200641086a41d5dfcb004111411310e604200641086a41e6dfcb00410f411410e604200641086a41f5dfcb00410c411510e604200641086a4181e0cb004108411610e604200641086a4189e0cb00410f411710e604200641086a4198e0cb00410d411810e604200641086a41a5e0cb00410a411910e604200641086a41afe0cb00410a411a10e604200641086a41b9e0cb00410b411b10e604200641086a41c4e0cb00410d411c10e604200641086a41d1e0cb00410c411d10e604200641086a41dde0cb00410b411e10e604200641086a41e8e0cb004115411f10e604200641086a41fde0cb00410a412010e604200641086a4187e1cb004107412110e604200641086a418ee1cb004113412210e604200641086a41a1e1cb004115412310e604200641086a41b6e1cb004111412410e604200641086a41c7e1cb00410e412510e604200641086a41d5e1cb004110412610e604200641086a41e5e1cb004110412710e604200641086a41f5e1cb004111412810e604200641086a4186e2cb004111412910e604200641086a4197e2cb004116412a10e604200641086a41ade2cb004112412b10e604200641086a41bfe2cb00410b412c10e604200641086a41cae2cb004110412d10e604200641086a41dae2cb004117412e10e604200641086a41f1e2cb004111412f10e604200641086a4182e3cb004113413010e604200641086a4195e3cb004113413110e604200641086a41a8e3cb004113413210e604200641206a410c6a200441086a280200360200200620033602202006410336023c20062005360238200620083602342006200429020037022420062001280200360230200628021022084105744104722204417f4c0d01200241146a350200210c2002411c6a350200210d20062802082107200410332209450d022006410036025820062004360254200620093602502008200641d0006a10770240024020080d002006280258210820062802542103200628025021090c010b200720084105746a210a034020072802002103200741086a2802002208200641d0006a10770240024020062802542201200628025822046b2008490d00200628025021090c010b200420086a22092004490d06200141017422052009200520094b1b22054100480d060240024020010d00024020050d00410121090c020b200510332209450d0b0c010b2006280250210920012005460d0020092001200510372209450d0a0b20062005360254200620093602500b200920046a20032008109d081a2006200420086a3602582007410c6a2802002105200741146a2802002209200641d0006a10770240024020062802542203200628025822016b2009490d0020062802502104200321080c010b200120096a22082001490d06200341017422042008200420084b1b22084100480d060240024020030d00024020080d00410121040c020b200810332204450d0b0c010b2006280250210420032008460d0020042003200810372204450d0a0b20062008360254200620043602500b200420016a20052009109d081a2006200120096a220936025802400240200741186a2802004101460d000240024020082009460d00200921080c010b200841016a22092008490d08200841017422012009200120094b1b22094100480d080240024020080d0041002108024020090d00410121040c020b200910332204450d0d0c010b20082009460d0020042008200910372204450d0c0b20062009360254200620043602500b200420086a41013a00002006200841016a220836025820062007411c6a2802002201360268200641e8006a21050c010b0240024020082009460d00200921080c010b200841016a22092008490d07200841017422012009200120094b1b22094100480d070240024020080d0041002108024020090d00410121040c020b200910332204450d0c0c010b20082009460d0020042008200910372204450d0b0b20062009360254200620043602500b200420086a41023a00002006200841016a220836025820062007411c6a2802002201360268200641e8006a21050b024002402006280254220420086b4104490d0020062802502109200421030c010b200841046a22092008490d06200441017422012009200120094b1b22034100480d060240024020040d00024020030d00410121090c020b200310332209450d0b0c010b2006280250210920042003460d0020092004200310372209450d0a0b2006200336025420062009360250200528020021010b200920086a20013600002006200841046a2208360258200741206a2207200a470d000b0b02400240024002400240024002404133200d422086200c842008ad4220862009ad84200641206a1019220b41036a220841024b0d004100210120080e03010002010b200628021c220741ffffffff03712007470d0720074102742204417f4c0d07200628021421080240024020040d00410421010c010b200410332201450d090b200641003602582006200136025020062004410276360254200641d0006a410020071086012006280250210e2006280258210102402007450d0020074102742105200e20014102746a210703402008280200220428020041016a220a41014d0d08200841046a21082004200a36020020072004360200200141016a2101200741046a21072005417c6a22050d000b0b2006280254210f02402003450d00200910350b2002350204210c2002350200210d2006410036025820064208370350200641d0006a41004100109a01200628025822084104744104722207417f4c0d072006280254210920062802502104200710332203450d082006410036025820062007360254200620033602502008200641d0006a107702402008450d00200841047421072004210803402008200641d0006a10e504200841106a2108200741706a22070d000b0b2006350258211020062802542103200628025021070240200941ffffffff0071450d00200410350b410a10392208450d08200b200c422086200d8420104220862007ad842008410a200641206a101a41036a220441034b0d024101210520040e0404020203040b410221010b410121054100210a02402003450d00200910350b0c090b41cfa2cc00412841c086cc00103f000b2006410936026c410121052006200841016a36026820082d0000220441014b0d01410421090240024020040e020100010b200641d0006a200641e8006a10e404200628025022094104460d022006280254210a0b410021050b200810352003450d05200710350c050b20081035024020030d000c050b200710350c040b00000b1044000b1045000b103e000b200b101b02402001450d0020014102742107200e21080340200828020022042004280200417f6a3602000240200828020022042802000d0020042802081018200828020022042004280204417f6a360204200828020022042802040d00200410350b200841046a21082007417c6a22070d000b0b0240200f41ffffffff0371450d00200e10350b410221010b200641206a410c6a290200210c200641206a41086a280200210720062802342108200628022421040240024002400240024002400240024002400240200628023c0e0403020001030b20004101360204200041086a4200370200200041106a41003a00000c030b2005450d04200041003a0004200ca72109024020010d00200041b5c1c60036020820004101360200200041186a2009360200200041146a2007360200200041106a20043602002000410c6a41103602000c060b200041c5c1c60036020820004101360200200041186a2009360200200041146a2007360200200041106a20043602002000410c6a41213602000c050b200041003a000420004101360200200041186a200c3e0200200041146a2007360200200041106a20043602002000410c6a4128360200200041086a41fcc0c6003602000c020b200041106a41003a00002000410c6a200641c8006a2802003602002000200641c0006a2903003702040b200041003602002007450d00200410350b20082008280200417f6a220736020020070d032008280208101820082008280204417f6a220736020420070d030c020b0240200941044b0d000240024020090e050102020200010b2000200436020420004100360200200041106a41003a00002000410c6a4100360200200041086a20073602000c020b2000200436020420004100360200200041106a200a3a00002000410c6a200c3e0200200041086a20073602000c010b200041003a000420004101360200200041186a200c3e0200200041146a2007360200200041106a20043602002000410c6a4111360200200041086a41a4c1c6003602000b20082008280200417f6a220736020020070d012008280208101820082008280204417f6a220736020420070d010b200810350b024020062802102207450d00200628020821082007410574210703400240200841046a280200450d00200828020010350b0240200841106a280200450d002008410c6a28020010350b200841206a2108200741606a22070d000b0b0240200628020c41ffffff3f71450d00200628020810350b0240200628021c2207450d0020062802142108200741027421070340200828020022042004280200417f6a3602000240200828020022042802000d0020042802081018200828020022042004280204417f6a360204200828020022042802040d00200410350b200841046a21082007417c6a22070d000b0b0240200628021841ffffffff0371450d00200628021410350b200641f0006a24000f0b103c000b120041b1c6c60041fc0041c086cc00103f000b7201027f230041106b22042400024002402003450d002002280200450d010b41e6c1c60041f40341dcc5c6001064000b2001280210210320012802182105200228020421022004410036020020042002360204200041054104200520032001411c6a200410be051b360200200441106a24000bcb0501067f230041f0006b22042400024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d02410521030240200241246a280200220520012802002802182802402802b4014b0d0020022802042106200241146a2802002107200441186a4200370300200441106a4200370300200441086a420037030020044200370300200128021821022001280210210820044281808080800437034041052103200220082001411c6a2209200441c0006a10be050d00024002402001280214280208200620044120101c41026a220241024b0d0020020e03020001020b41cfa2cc00412841f8a2cc00103f000b20012802102102200128021821082004410136024020042005360244200820022009200441c0006a10be050d002005417f4c0d040240024020050d0041002108410121020c010b200510392202450d06200521080b0240024002402001280214280208200720022005101c41026a220641024b0d0020060e03010002010b41cfa2cc00412841f8a2cc00103f000b2008450d01200210350c010b20012802002101200441206a41186a2206200441186a290300370300200441206a41106a2209200441106a290300370300200441206a41086a2207200441086a290300370300200420042903003703200240200128021822012802402802b40120054f0d002008450d01200210350c010b200441c0006a41186a2006290300370300200441c0006a41106a2009290300370300200441c0006a41086a20072903003703002004200429032037034020042005ad4220862008ad8437026420042002360260200141186a200141d0006a200441c0006a200441e0006a10af04410421030b20002003360200200441f0006a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b1045000b860302037f047e230041f0006b2204240002402003450d0020022802000d0020022802042105200441186a4200370300200441106a4200370300200441086a4200370300200442003703002001280218210320012802102106200442818080808004370340410521020240200320062001411c6a200441c0006a10be050d00024002402001280214280208200520044120101c41026a220341024b0d0020030e03020001020b41cfa2cc00412841f8a2cc00103f000b20012802002101200441206a41186a200441186a2903002207370300200441206a41106a200441106a2903002208370300200441206a41086a200441086a290300220937030020042004290300220a37032020012802182101200441c0006a41186a2007370300200441c0006a41106a2008370300200441c0006a41086a20093703002004200a37034020044100360260200141186a200141d0006a200441c0006a200441e0006a10af04410421020b20002002360200200441f0006a24000f0b41e6c1c60041f40341dcc5c6001064000be60201027f230041306b2204240002402003450d0020022802000d0020022802042105200441186a4200370300200441106a4200370300200441086a420037030020044200370300200128021821022001280210210320044281808080800437032002400240200220032001411c6a200441206a10be050d00024002402001280214280208200520044120101c41026a220241024b0d0020020e03020001020b41cfa2cc00412841f8a2cc00103f000b200441206a2001280200280218220241186a200241d0006a2002410c6a4100200228020c1b2004109104024002402004280220450d00200141046a21020240200141086a280200450d00200228020010350b20022004290320370200200241086a200441206a41086a280200360200410021010c010b2001410c6a4100360200410121010b20004100360200200020013602040c010b200041053602000b200441306a24000f0b41e6c1c60041f40341dcc5c6001064000bdc0802087f027e23004190016b22042400024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320022802042105200241146a2802002106200241246a2802002107200241346a28020021082001280210210220012802182103200441013602482004200636024c02400240200320022001411c6a2209200441c8006a10be050d002006417f4c0d060240024002400240024002400240024020060d004100210a4101210b02402001280214280208200541014100101c41026a220241024b0d00200141146a210520020e03090002090b41cfa2cc00412841f8a2cc00103f000b20061039220b450d04024020012802142802082005200b2006101c41026a220241024b0d00200141146a21052006210a20020e03020001020b41cfa2cc00412841f8a2cc00103f000b41002102200441003a00680240034020062002460d01200441c8006a20026a200b20026a2d00003a00002004200241016a22033a00682003210220034120470d000b200441f0006a41186a2202200441c8006a41186a290300370300200441f0006a41106a2203200441c8006a41106a290300370300200441f0006a41086a2206200441c8006a41086a290300370300200420042903483703700240200a450d00200b10350b200441086a41086a2006290300370300200441086a41106a2003290300370300200441086a41186a2002290300370300200420042903703703082001280210210220012802182103200441013602482004200836024c200320022009200441c8006a10be050d072008417f4c0d0d20080d032005280200280208200741014100101c41026a220241024b0d0220020e03070207070b0240200241ff0171450d00200441003a00680b200a450d060b200b10350c050b41cfa2cc00412841f8a2cc00103f000b200810392202450d0002402005280200280208200720022008101c41026a220341024b0d0020030e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2008410f4d0d00200241086a290000210c2002290000210d200210352001280218210320012802002802182102200441f0006a41186a200441086a41186a290300370300200441f0006a41106a200441086a41106a290300370300200441f0006a41086a200441086a41086a29030037030020042004290308370370200441c8006a41186a200241e8006a290000370300200441c8006a41106a200241e0006a290000370300200441c8006a41086a200241d8006a29000037030020042002290050370348200441286a20034100200441c8006a200441f0006a200d200c200210bf0520042d0028210220004100360200200020024104473602040c020b200210350b200041053602000b20044190016a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000bfb0e04037f017e077f047e230041a0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042105200241146a2802002106200241286a2903002107200241346a2802002108200241c4006a2802002109200241d4006a280200210a200241e4006a280200210b2001280210210220012802182103200441013602682004200636026c02400240200320022001411c6a220c200441e8006a10be050d002006417f4c0d090240024002400240024002400240024020060d004100210d4101210e02402001280214280208200541014100101c41026a220241024b0d00200141146a210520020e03090002090b41cfa2cc00412841f8a2cc00103f000b20061039220e450d04024020012802142802082005200e2006101c41026a220241024b0d00200141146a21052006210d20020e03020001020b41cfa2cc00412841f8a2cc00103f000b41002102200441003a0088010240034020062002460d01200441e8006a20026a200e20026a2d00003a00002004200241016a22033a0088012003210220034120470d000b200441c8006a41186a2202200441e8006a41186a290300370300200441c8006a41106a2203200441e8006a41106a290300370300200441c8006a41086a2206200441e8006a41086a290300370300200420042903683703480240200d450d00200e10350b200441086a41086a2006290300370300200441086a41106a2003290300370300200441086a41186a2002290300370300200420042903483703082001280210210220012802182103200441013602682004200936026c20032002200c200441e8006a10be050d072009417f4c0d1020090d032005280200280208200841014100101c41026a220241024b0d0220020e03070207070b0240200241ff0171450d00200441003a0088010b200d450d060b200e10350c050b41cfa2cc00412841f8a2cc00103f000b200910392202450d0002402005280200280208200820022009101c41026a220341024b0d0020030e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2009410f4d0d00200241086a290000210f20022900002110200210352001280210210220012802182103200441013602682004200b36026c20032002200c200441e8006a10be050d0102400240200b2001410c6a220628020022034b0d00200b21020c010b02400240200141086a280200220220036b200b20036b2205490d002001280204210e200321020c010b200320056a220e2003490d0d20024101742209200e2009200e4b1b22094100480d0d0240024020020d00024020090d004101210e0c020b20091033220e0d010c100b2001280204210e20022009460d00200e200220091037220e450d0f0b2001200e360204200141086a20093602002001410c6a28020021020b200e20026a21090240024020054102490d0020094100200b2003417f7322036a2205109f081a200e200b20026a20036a6a2109200520026a21020c010b2005450d010b200941003a0000200241016a21020b20062002360200024002402001280214280208200a20012802042002101c41026a220241024b0d0020020e03030001030b41cfa2cc00412841f8a2cc00103f000b2001410c6a220228020021094100210520024100360200200141086a280200210220012802042103200142013702042001280218220629030822112112024002402007500d00418002210e2007211220112007540d010b2006201120127d3703082004201237033020042012370328200128020041186a280200210e200441e8006a41186a200441086a41186a290300370300200441e8006a41106a200441086a41106a290300370300200441e8006a41086a200441086a41086a29030037030020042004290308370368200420093602980120042002360294012004200336029001200441c8006a200e200441e8006a2010200f200441286a20044190016a10ef03410121090240024020042802484101470d00200441c8006a41186a280200210c200441dc006a2802002102200441c8006a41106a28020021034100210e0c010b200441c8006a41106a2d0000210e200441d4006a280200210c200441d0006a280200210241002109200428024c21030b2006200429033020062903087c370308200141086a280200210602402009450d00418002210e2006450d01200128020410350c010b02402006450d00200128020410350b200c21050b200120033602042001410c6a2005360200200141086a2002360200200041003602002000200e3602040c020b200210350b200041053602000b200441a0016a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b103e000b103c000b8a1004037f017e077f047e230041b0016b2204240002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802204101470d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620022802042105200241146a2802002106200241286a2903002107200241346a2802002108200241c4006a2802002109200241d4006a280200210a200241e4006a280200210b2001280210210220012802182103200441013602782004200636027c02400240200320022001411c6a220c200441f8006a10be050d002006417f4c0d090240024002400240024002400240024020060d004100210d4101210e02402001280214280208200541014100101c41026a220241024b0d00200141146a210520020e03090002090b41cfa2cc00412841f8a2cc00103f000b20061039220e450d04024020012802142802082005200e2006101c41026a220241024b0d00200141146a21052006210d20020e03020001020b41cfa2cc00412841f8a2cc00103f000b41002102200441003a0098010240034020062002460d01200441f8006a20026a200e20026a2d00003a00002004200241016a22033a0098012003210220034120470d000b200441c8006a41186a2202200441f8006a41186a290300370300200441c8006a41106a2203200441f8006a41106a290300370300200441c8006a41086a2206200441f8006a41086a290300370300200420042903783703480240200d450d00200e10350b200441086a41086a2006290300370300200441086a41106a2003290300370300200441086a41186a2002290300370300200420042903483703082001280210210220012802182103200441013602782004200936027c20032002200c200441f8006a10be050d072009417f4c0d1020090d032005280200280208200841014100101c41026a220241024b0d0220020e03070207070b0240200241ff0171450d00200441003a0098010b200d450d060b200e10350c050b41cfa2cc00412841f8a2cc00103f000b200910392202450d0002402005280200280208200820022009101c41026a220341024b0d0020030e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2009410f4d0d00200241086a290000210f20022900002110200210352001280210210220012802182103200441013602782004200b36027c20032002200c200441f8006a10be050d01200141046a210e02400240200b2001410c6a220628020022034b0d00200b21020c010b02400240200141086a280200220220036b200b20036b2209490d00200e2802002105200321020c010b200320096a22052003490d0d2002410174220c2005200c20054b1b220c4100480d0d0240024020020d000240200c0d00410121050c020b200c103322050d010c100b200e28020021052002200c460d0020052002200c10372205450d0f0b20012005360204200141086a200c3602002001410c6a28020021020b200520026a210c0240024020094102490d00200c4100200b2003417f7322036a2209109f081a2005200b20026a20036a6a210c200920026a21020c010b2009450d010b200c41003a0000200241016a21020b20062002360200024002402001280214280208200a20012802042002101c41026a220241024b0d0020020e03030001030b41cfa2cc00412841f8a2cc00103f000b2001410c6a2202280200210520024100360200200141086a28020021022001280204210320014201370204200128021822062903082211211202400240024002402007500d002007211220112007540d010b2006201120127d3703082004201237037020042012370368200128020041186a2802002109200420053602502004200236024c20042003360248200441f8006a20092010200f200441e8006a200441086a200441c8006a10c005410121050240024020042802784101470d00200441f8006a41186a28020021092004418c016a280200210220044188016a28020021030c010b200441c8006a41086a200441f8006a41186a290300370300200441c8006a41106a20044198016a2802003602002004200441f8006a41106a290300370348200441a8016a2d0000210c2004419c016a290200210720044184016a2802002109200441f8006a41086a280200210241002105200428027c21030b2006200429037020062903087c370308200441286a41086a2206200441c8006a41086a290300370300200441286a41106a2208200441c8006a41106a280200360200200420042903483703282005450d01200141086a280200450d00200e28020010350b200120033602042001410c6a4100360200200141086a200236020041800221020c010b2004418c016a200629030037020020044194016a200828020036020020042009360280012004200236027c2004200336027820042004290328370284010240200141086a280200450d00200e28020010350b200120073702042001410c6a4100360200200c41ff017122020d00200e200441f8006a412010780b20004100360200200020023602040c020b200210350b200041053602000b200441b0016a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b103e000b103c000bf113020b7f047e230022042105200441e00c6b41607122042400024002402003450d0020022802000d00024020034101460d0020022802100d0020022802042106200241146a28020021072001280210210220012802182103200441013602e001200420073602e401200320022001411c6a200441e0016a10be050d0202402007417f4c0d00024002400240024002400240024020070d00410021084101210902402001280214280208200641014100101c41026a220241024b0d0020020e030b00020b0b41cfa2cc00412841f8a2cc00103f000b0240200710392209450d0002402001280214280208200620092007101c41026a220241024b0d002007210820020e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b41002102200441003a0080020240034020072002460d01200441e0016a20026a200920026a2d00003a00002004200241016a22033a0080022003210220034120470d000b200441800a6a41186a2202200441e0016a41186a290300370300200441800a6a41106a2203200441e0016a41106a290300370300200441800a6a41086a2207200441e0016a41086a290300370300200420042903e0013703800a02402008450d00200910350b200441206a41086a2007290300370300200441206a41106a2003290300370300200441206a41186a2002290300370300200420042903800a3703202001280218210a200441c0006a41186a2001280200280218220641e8006a290000370300200441c0006a41106a200641e0006a290000370300200441c0006a41086a200641d8006a29000037030020042006290050370340200628021841016a220b41004c0d052006200b3602182006411c6a220c2802002208450d03200641206a280200210d0340200841086a210320082f0106220e410574210241002107024003402002450d01200441c0006a2003412010a0082209450d05200241606a2102200741016a2107200341206a21032009417f4a0d000b2007417f6a210e0b200d450d04200d417f6a210d2008200e4102746a41880b6a28020021080c000b0b0240200241ff0171450d00200441003a0080020b2008450d080b200910350c070b2008200741e0006c6a220241c5036a310000200241e8026a290300220f200f5022031ba7450d004200200241f8026a29030020031b210f4200200241f0026a29030020031b21100c010b200441106a200641286a280200200441c0006a2006412c6a28020028021c110400200441186a290300210f2006280218210b200429031021100b2006200b417f6a360218024020062802082202450d00200241d0006a2203200441c0006a460d052003200441c0006a412010a008450d05034020022802082202450d01200441c0006a200241d0006a2203460d062003200441c0006a412010a0080d000c060b0b200441e0016a200a4102200441c0006a200441206a2010200f200610bf0520042d00e0014104470d04024020062802180d002006417f360218200441003a009c0120044100360298012004410036029001200441013a007d200441c0016a41186a200441c0006a41186a290300370300200441c0016a41106a200441c0006a41106a290300370300200441c0016a41086a200441c0006a41086a290300370300200420042903403703c001024002400240200628021c2209450d00200641206a280200210d0c010b200441800a6a410041e002109f081a200441e0016a410041a008109f081a41880b10332209450d014100210d200941003b010620094100360200200941086a200441800a6a41e002109d081a200941e8026a200441e0016a41a008109d081a200641206a41003602002006200936021c0b2004200c3602880a200420093602840a2004200d3602800a034020092f0106220b41057421084100210241002103024002400240034020082002460d010240200441c0016a200920026a41086a412010a00822070d0041002102200d21070c030b200241206a2102200341016a21032007417f4a0d000b2003417f6a210b0b200d0d014101210241002107200b21030b200441e0016a41106a2003360200200441ec016a200c360200200441e0016a41086a20093602002004200c3602880a200420093602840a2004200d3602800a200420073602e401200420023602e001024002402002450d00200441a0016a41186a200441c0016a41186a290300220f370300200441a0016a41106a200441c0016a41106a2903002210370300200441a0016a41086a200441c0016a41086a2903002211370300200420042903c00122123703a0012004419c0a6a2011370200200441800a6a41246a2010370200200441ac0a6a200f3702002004200641246a3602900a2004200336028c0a2004200c3602880a200420093602840a200420073602800a200420123702940a200441e0016a41186a4200370300200442003703e00120044198026a20042903980137030020044190026a20042903900137030020044188026a20042903880137030020044180026a200429038001370300200441b8026a2004290378370300200441b0026a2004290370370300200441a8026a2004290368370300200441a0026a2004290360370300200441800a6a200441e0016a1080031a4202210f0c010b2009200341e0006c6a22024190036a20042903880137030020024188036a200429038001370300200241c0036a2004290378370000200241b8036a2004290370370000200241b0036a2004290368370000200241a8036a200429036037000020024180036a4200370300200241e8026a2203290300210f20034200370300200241a0036a22032802002108200320042903980137030020024198036a2202290300211020022004290390013703002010a721092010422088a721030b0240200f4202510d000240024020090d0041002108200441f4016a4100360200200441003602e4010c010b0240024020030d00200921020c010b2003210220092107034020072802ec0321072002417f6a22020d000b200921020340200220022f01064102746a41ec036a28020021022003417f6a22030d000b200721090b200441fc016a20022f0106360200200441f8016a4100360200200441f4016a2002360200200441003602f001200442003703e801200420093602e401200441003602e0010b2004200836028002200441e0016a1081030b2006200628021841016a3602180240200128021c0d00200141246a280200450d00200141206a28020010350b2001410236021c200141206a20042902e001370200200141286a200441e8016a2802003602000c080b200d417f6a210d2009200b4102746a41880b6a28020021090c000b0b103c000b41a797cc004110200441e0016a41c8c1c30041c897cc001046000b41ac96cc004118200441e0016a41d8c1c30041d496cc001046000b1044000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b20004105360200200524000b940501077f230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200241146a2802002102200128021021032001280218210620044103360200200420023602040240200620032001411c6a2207200410be050d0020012802102103200128021821062004410136020020042002360204200620032007200410be050d000240024020022001410c6a220728020022064b0d00200221030c010b02400240200141086a280200220320066b200220066b2208490d0020012802042109200621030c010b200620086a22092006490d052003410174220a2009200a20094b1b220a4100480d050240024020030d000240200a0d00410121090c020b200a103322090d010c080b200128020421092003200a460d0020092003200a10372209450d070b20012009360204200141086a200a3602002001410c6a28020021030b200920036a210a0240024020084102490d00200a410020022006417f7322066a2208109f081a2009200220036a20066a6a210a200820036a21030c010b2008450d010b200a41003a0000200341016a21030b20072003360200024002402001280214280208200520012802042003101c41026a220241024b0d0020020e03020001020b41cfa2cc00412841f8a2cc00103f000b2001410c6a2202280200210320024100360200200141086a280200210220012802042106200142013702040240200128021c0d00200141246a280200450d00200141206a28020010350b2001410036021c200141286a2003360200200141246a2002360200200141206a20063602000b20004105360200200441106a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b103e000b103c000b24002001410c6a4100360200200141046a200128020041206a41201078200041043602000b28002001410c6a4100360200200141046a200128020028021841d0006a41201078200041043602000b5702017f017e230041206b220424002001410c6a41003602002004420110cf04200429030021052004200441086a29030037031820042005370310200141046a200441106a4110107820004104360200200441206a24000b4001017f230041106b220424002001410c6a410036020020042001280218290308370308200141046a200441086a4108107820004104360200200441106a24000ba403020b7f027e230041206b220424002001410c6a410036020002402001280200280218220528021841016a220641004c0d00200141046a2107200541d0006a210820052006360218024002402005411c6a2802002209450d00200541206a280200210a0340200941086a210b20092f0106220c41057421014100210d0240024003402001450d012008200b412010a008220e450d02200141606a2101200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b200a450d02200a417f6a210a2009200c4102746a41880b6a28020021090c010b0b2009200d41e0006c6a220141c5036a310000200141e8026a290300220f200f50220b1ba7450d004200200141f8026a290300200b1b210f4200200141f0026a290300200b1b21100c010b2004200541286a28020020082005412c6a28020028021c110400200441086a290300210f20052802182106200429030021100b20052006417f6a3602182004200f370318200420103703102007200441106a4110107820004104360200200441206a24000f0b41ac96cc004118200441106a41d8c1c30041d496cc001046000b5202027f017e230041106b220424002001410c6a41003602002001280200220529030021062004200541086a29030037030820042006370300200141046a20044110107820004104360200200441106a24000bb60301057f230041206b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d01410521050240200241146a280200220320012802102206280284014b0d0020022802042107200128021821022004410136020020042003360204200220062001411c6a200410be050d002003417f4c0d0302400240024020030d00410021084101210602402001280214280208200741014100101c41026a220241024b0d0020020e03040002040b41cfa2cc00412841f8a2cc00103f000b200310392206450d0602402001280214280208200720062003101c41026a220241024b0d002003210820020e03020001020b41cfa2cc00412841f8a2cc00103f000b2001410c6a410036020020042006200310d503412010332202450d0520022004290300370000200241186a200441186a290300370000200241106a200441106a290300370000200241086a200441086a29030037000041042105200141046a200241201078200210352008450d010b200610350b20002005360200200441206a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b1045000b4001017f230041106b220424002001410c6a410036020020042001280200290310370308200141046a200441086a4108107820004104360200200441106a24000b5a02027f017e230041106b220424002001410c6a410036020020012802002802182802402205290390012106200420054198016a29030037030820042006370300200141046a20044110107820004104360200200441106a24000b5a02027f017e230041106b220424002001410c6a4100360200200128020028021828024022052903a00121062004200541a8016a29030037030820042006370300200141046a20044110107820004104360200200441106a24000bb00601047f230041e0096b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200241146a28020021022001280210210320012802182106200441013602a807200420023602ac07024002400240200620032001411c6a2207200441a8076a10be050d002002417f4c0d0502400240024020020d00410021064101210302402001280214280208200541014100101c41026a220541024b0d0020050e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200210392203450d0002402001280214280208200520032002101c41026a220541024b0d002002210620050e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2004200236020c20042003360208200441a8076a200441086a10b902024020042802a8072202411b460d00200441f8046a200441a8076a41047241ac02109d081a02402006450d00200310350b200441b8026a200441f8046a41ac02109d081a20042002360208200441086a410472200441b8026a41ac02109d081a200441e8046a200441086a10d8032001280210210220012802182103200420042903e8043703b007200441043602a807200320022007200441a8076a10be05450d03200441086a10ba02410521020c040b2006450d010b200310350b410521020c010b20012802002102200441f8046a200441086a41b002109d081a200441c0026a22032002280218220241d8006a290000370300200441c8026a2206200241e0006a290000370300200441d0026a2205200241e8006a290000370300200420022900503703b802200441af076a200441f8046a41b002109d081a02402002413c6a2802002201200241386a280200470d00200241346a20014101109501200228023c21010b2002280234200141d8026c6a220141013a0000200120042903b802370001200141096a2003290300370000200141116a2006290300370000200141196a2005290300370000200141216a200441a8076a41b702109d081a2002200228023c41016a36023c410421020b20002002360200200441e0096a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b9315020c7f027e230041b0036b220424000240024002400240024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d0320034104460d0420022802400d0420034105460d0520022802500d0520034106460d0620022802600d0620034107460d0720022802700d0720022802042105200241146a2802002106200241246a2802002107200241346a2802002108200241c4006a2802002109200241d4006a280200210a200241e4006a280200210b200241f4006a280200210c2001280210210220012802182103200441013602b801200420063602bc010240024002400240024002400240200320022001411c6a220d200441b8016a10be050d002006417f4c0d0f02400240024020060d004100210e4101210f02402001280214280208200541014100101c41026a220241024b0d00200141146a210520020e03040002040b41cfa2cc00412841f8a2cc00103f000b20061039220f450d06024020012802142802082005200f2006101c41026a220241024b0d00200141146a21052006210e20020e03020001020b41cfa2cc00412841f8a2cc00103f000b41002102200441003a00d8010240034020062002460d01200441b8016a20026a200f20026a2d00003a00002004200241016a22033a00d8012003210220034120470d000b20044190036a41086a2202200441b8016a41086a29030037030020044190036a41106a2203200441b8016a41106a29030037030020044190036a41186a2206200441b8016a41186a290300370300200420042903b801370390030240200e450d00200f10350b200441086a41086a2002290300370300200441086a41106a2003290300370300200441086a41186a200629030037030020042004290390033703082001280210210220012802182103200441013602b801200420083602bc0120032002200d200441b8016a10be050d132008417f4c0d1120080d044100210f410121062005280200280208200741014100101c41026a220241024b0d0320020e03130305130b0240200241ff0171450d00200441003a00d8010b200e450d010b200f10350b200441c8006a41186a20044190036a41186a290300370300200441c8006a41106a20044190036a41106a290300370300200441c8006a41086a20044190036a41086a2903003703002004200429039003370348410521020c110b41cfa2cc00412841f8a2cc00103f000b200810392206450d0102402005280200280208200720062008101c41026a220241024b0d002008210f20020e030e00010e0b41cfa2cc00412841f8a2cc00103f000b41002102200441003a00d801024002400240034020082002460d01200441b8016a20026a200620026a2d00003a00002004200241016a22033a00d8012003210220034120470d000b20044190036a41086a2202200441b8016a41086a29030037030020044190036a41106a2203200441b8016a41106a29030037030020044190036a41186a2208200441b8016a41186a290300370300200420042903b801370390030240200f450d00200610350b200441286a41086a2002290300370300200441286a41106a2003290300370300200441286a41186a200829030037030020042004290390033703282001280210210320012802182106200441013602b8012004200a3602bc014105210220062003200d200441b8016a10be050d11200a417f4c0d0e200a0d022005280200280208200941014100101c41026a220341024b0d0120030e03110111110b0240200241ff0171450d00200441003a00d8010b200f0d0e0c0f0b41cfa2cc00412841f8a2cc00103f000b200a10392203450d000240200528020028020820092003200a101c41026a220641024b0d0020060e03020003020b41cfa2cc00412841f8a2cc00103f000b1045000b200310350c0c0b0240200a410f4b0d00200310350c0c0b200341086a2900002110200329000021112003103541002102200441003602a00120044201370398010240200c450d0020044190036a41186a210320044190036a41106a210620044190036a41086a210f4101210a03402003420037030020064200370300200f4200370300200442003703900320012802182108200128021021072004428180808080043703b8010240024020082007200d200441b8016a10be050d00024002402005280200280208200b20044190036a4120101c41026a220841024b0d0020080e03020001020b41cfa2cc00412841f8a2cc00103f000b200441b8016a41186a22072003290300370300200441b8016a41106a22092006290300370300200441b8016a41086a220e200f29030037030020042004290390033703b80102402002200428029c01470d0020044198016a20024101108a01200428029801210a20042802a00121020b200a20024105746a220820042903b801370000200841186a2007290300370000200841106a2009290300370000200841086a200e2903003700002004200241016a22023602a001200b41206a2208200b4f0d010b0240200428029c0141ffffff3f71450d00200a10350b410521020c0e0b2008210b200c417f6a220c0d000b0b200441e8006a41086a220220044198016a41086a2206280200360200200420042903980137036820062001280200280218220341d8006a29000037030020044198016a41106a2206200341e0006a29000037030020044198016a41186a2201200341e8006a2900003703002004200329005037039801200441f8006a41086a200441086a41086a290300370300200441f8006a41106a220f200441086a41106a290300370300200441f8006a41186a2208200441086a41186a2903003703002004200429030837037820044190036a41186a2205200441286a41186a29030037030020044190036a41106a220d200441286a41106a29030037030020044190036a41086a200441286a41086a2903003703002004200429032837039003200441d3006a20022802003600002004200429036837004b02402003413c6a2802002202200341386a280200470d00200341346a20024101109501200328023c21020b2003280234200241d8026c6a220241023a0000200220042903980137000120022004290378370021200241096a20044198016a41086a290300370000200241116a2006290300370000200241196a2001290300370000200241296a200441f8006a41086a290300370000200241316a200f290300370000200241396a200829030037000020022011370370200241f8006a20103703002002200429039003370041200241c9006a20044190036a41086a290300370000200241d1006a200d290300370000200241d9006a200529030037000020022004290048370061200241e8006a200441cf006a29000037000020024180016a200441b8016a41d801109d081a2003200328023c41016a36023c410421020c0b0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b200610350b410521020b20002002360200200441b0036a24000b16002000410036020020002001410c6a2802003602040ba50201067f230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d024105210302402001410c6a2802002205200241146a2802002206490d00200520066b200241246a2802002205470d00200228020421072001280204210820012802182102200128021021092004410236020020042005360204200220092001411c6a200410be050d000240024020012802142802082007200820066a2005101d41026a220241024b0d0020020e03020001020b41cfa2cc00412841cca3cc00103f000b410421030b20002003360200200441106a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b820401087f230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200241146a280200210220012802102103200128021821062004410136020020042002360204410521070240200620032001411c6a200410be050d000240024020022001410c6a220828020022064b0d00200221030c010b02400240200141086a280200220320066b200220066b2209490d002001280204210a200621030c010b200620096a220a2006490d052003410174220b200a200b200a4b1b220b4100480d050240024020030d000240200b0d004101210a0c020b200b1033220a0d010c080b2001280204210a2003200b460d00200a2003200b1037220a450d070b2001200a360204200141086a200b3602002001410c6a28020021030b200a20036a210b0240024020094102490d00200b410020022006417f7322066a2209109f081a200a200220036a20066a6a210b200920036a21030c010b2009450d010b200b41003a0000200341016a21030b20082003360200024002402001280214280208200520012802042003101c41026a220141024b0d0020010e03020001020b41cfa2cc00412841f8a2cc00103f000b410421070b20002007360200200441106a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b103e000b103c000bf90803077f017e017f230041d0026b22042400024002400240024002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220034103460d0320022802300d03200241246a2802002105200241346a2802002106024002400240200241146a2802002203450d00200228020421072001280210210820012802182109200441013602082004200336020c41052102200920082001411c6a200441086a10be050d0a2003417f4c0d07200310392208450d08024002402001280214280208200720082003101c41026a220941024b0d0020090e03010003010b41cfa2cc00412841f8a2cc00103f000b200810350c0a0b41012107410021094100210a0c010b200420033602dc01200420083602d801200441086a200441d8016a10c301200441106a2802002109200429020c210b200428020c210a20042802082107200810352007450d082001280210280274200b422088a7490d070b20072009410041202009676b10c105024020094102490d00200721022009210303402002200241206a2208412010a008450d08200821022003417f6a220341024f0d000b0b2001280210210220012802182103200441013602082004200636020c200320022001411c6a2208200441086a10be050d062006417f4c0d040240024020060d0041002102410121030c010b200610392203450d06200621020b0240024002402001280214280208200520032006101c41026a220541024b0d0020050e03010002010b41cfa2cc00412841f8a2cc00103f000b2002450d07200310350c070b200128021021052001280218210c200441086a41086a20063602002004200936020c200441053602080240200c20052008200441086a10be05450d002002450d07200310350c070b2006ad4220862002ad84210b200441a8026a41086a2001280200280218220841d8006a290000370300200441b8026a2201200841e0006a290000370300200441c0026a2206200841e8006a290000370300200420082900503703a80202402008413c6a2802002202200841386a280200470d00200841346a20024101109501200828023c21020b2008280234200241d8026c6a220241003a0000200220042f00cd023b0001200241073a00102002200936000c2002200a36000820022007360004200220042903a802370011200241036a200441cd026a41026a2d00003a0000200241196a200441b0026a290300370000200241216a2001290300370000200241296a2006290300370000200220033600342002200b370038200220042f00a5023b0031200241336a200441a5026a41026a2d00003a0000200241c0006a200441d8016a41c800109d081a20024188016a200441086a41d001109d081a2008200828023c41016a36023c410421020c070b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b1045000b41052102200a41ffffff3f71450d00200710350b20002002360200200441d0026a24000bbd0a03047f027e037f230041d00b6b22042400024002402003450d0020022802000d00024020034101460d0020022802100d0020022802042105200241146a28020021022001280210210620012802182107200441013602502004200236025441052103200720062001411c6a200441d0006a10be050d0202402002417f4c0d00024020020d0002402001280214280208200541014100101c41026a220241024b0d0020020e03050005050b41cfa2cc00412841f8a2cc00103f000b024002400240200210392206450d0002402001280214280208200520062002101c41026a220741024b0d0020070e03020003020b41cfa2cc00412841f8a2cc00103f000b1045000b200610350c040b02402002410f4b0d00200610350c040b200641086a290000210820062900002109200610350240200128020028021822052802180d002005417f360218200441386a200541e8006a290000370300200441306a200541e0006a290000370300200441206a41086a200541d8006a290000370300200420052900503703200240024002402005411c6a220a2802002206450d00200541206a280200210b0c010b4100210b200441f0086a410041e002109f081a200441d0006a410041a008109f081a41880b10332206450d01200641003b010620064100360200200641086a200441f0086a41e002109d081a200641e8026a200441d0006a41a008109d081a200541206a41003602002005200636021c0b2004200a3602f808200420063602f4082004200b3602f008034020062f0106220c41057421074100210241002101024002400240034020072002460d010240200441206a200620026a41086a412010a00822030d0041002102200b21070c030b200241206a2102200141016a21012003417f4a0d000b2001417f6a210c0b200b0d014101210241002107200c21010b200441d0006a41106a2001360200200441dc006a200a360200200441d0006a41086a20063602002004200a3602f808200420063602f4082004200b3602f00820042007360254200420023602504101210302402002450d00200441186a200441206a41186a290300370300200441106a200441206a41106a290300370300200441086a200441206a41086a29030037030020042004290320370300410021030b0240024020030d002004418c096a200441086a29030037020020044194096a200441106a2903003702002004419c096a200441186a2903003702002004200541246a36028009200420013602fc082004200a3602f808200420063602f408200420073602f0082004200429030037028409200441f0006a2004290340370300200441f8006a200441c0006a41086a29030037030020044188016a41003602002004420037036820044200370350200441003a008c0120044100360280012004418d016a200429002037000020044195016a200441206a41086a2900003700002004419d016a200441206a41106a290000370000200441a5016a200441206a41186a290000370000200441003a00ad01200441f0086a200441d0006a10800321020c010b200441e4006a410036020020044100360270200441003602542006200141e0006c6a41e8026a2102200441d0006a1081030b200241286a2008370300200241206a2009370300200242013703182005200528021841016a360218410421030c070b200b417f6a210b2006200c4102746a41880b6a28020021060c000b0b103c000b41a797cc004110200441d0006a41c8c1c30041c897cc001046000b1044000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b20002003360200200441d00b6a24000b7d02027f017e230041306b220424002001410c6a4100360200200441086a2001280200280218220541186a200541d0006a109404200429031021062004200441086a41106a290300427f200428020822051b37032820042006427f20051b370320200141046a200441206a4110107820004104360200200441306a24000be30201047f230041106b220424000240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200241146a280200210220012802102106200128021821072004410136020020042002360204410521030240200720062001411c6a200410be050d002002417f4c0d0302400240024020020d00410021074101210602402001280214280208200541014100101c41026a220141024b0d0020010e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200210392206450d0002402001280214280208200520062002101c41026a220141024b0d002002210720010e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2004200620021074024020042802000d00200429020410060b410421032007450d010b200610350b20002003360200200441106a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000b4001017f230041106b220424002001410c6a41003602002004200128020028021c36020c200141046a2004410c6a4104107820004104360200200441106a24000bce0502087f017e230041106b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120022802042105200241146a28020021022001280210210320012802182106200441013602002004200236020402400240200620032001411c6a200410be050d00200141046a21070240024020022001410c6a220828020022064b0d00200221030c010b02400240200141086a280200220320066b200220066b2209490d002007280200210a200621030c010b200620096a220a2006490d062003410174220b200a200b200a4b1b220b4100480d060240024020030d000240200b0d004101210a0c020b200b1033220a0d010c090b2007280200210a2003200b460d00200a2003200b1037220a450d080b2001200a360204200141086a200b3602002001410c6a28020021030b200a20036a210b0240024020094102490d00200b410020022006417f7322066a2209109f081a200a200220036a20066a6a210b200920036a21030c010b2009450d010b200b41003a0000200341016a21030b20082003360200024002402001280214280208200520012802042003101c41026a220241024b0d0020020e03020001020b41cfa2cc00412841f8a2cc00103f000b2001410c6a2202350200210c20024100360200200141086a2203280200210620012802042102200142013702042004200c4220862002ad84100510c20120032802002103024002402004280200450d0002402003450d00200728020010350b20072004290300370200200741086a200441086a280200360200410021012006450d01200210350c010b02402003450d00200728020010350b200120023602042001410c6a4100360200200141086a2006360200410121010b20004100360200200020013602040c010b200041053602000b200441106a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b103e000b103c000bc70402077f037e230041306b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220022802042105200241146a2802002103200241246a280200210620012802102107200128021821082004410136020020042003360204410521020240200820072001411c6a2209200410be050d002003417f4c0d0402400240024020030d00410021084101210702402001280214280208200541014100101c41026a220a41024b0d00200141146a2105200a0e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200310392207450d0002402001280214280208200520072003101c41026a220a41024b0d00200141146a210520032108200a0e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2003ad4220862007ad84101e2203290000210b200341086a290000210c200341106a290000210d200441186a200341186a290000370300200441106a200d370300200441086a200c3703002004200b37030020031035200128021821032001280210210120044282808080800437032002400240200320012009200441206a10be050d0002402005280200280208200620044120101d41026a220141024b0d0020010e03010002010b41cfa2cc00412841cca3cc00103f000b20080d010c020b410421022008450d010b200710350b20002002360200200441306a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000bc70402077f037e230041306b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220022802042105200241146a2802002103200241246a280200210620012802102107200128021821082004410136020020042003360204410521020240200820072001411c6a2209200410be050d002003417f4c0d0402400240024020030d00410021084101210702402001280214280208200541014100101c41026a220a41024b0d00200141146a2105200a0e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200310392207450d0002402001280214280208200520072003101c41026a220a41024b0d00200141146a210520032108200a0e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2003ad4220862007ad84101f2203290000210b200341086a290000210c200341106a290000210d200441186a200341186a290000370300200441106a200d370300200441086a200c3703002004200b37030020031035200128021821032001280210210120044282808080800437032002400240200320012009200441206a10be050d0002402005280200280208200620044120101d41026a220141024b0d0020010e03010002010b41cfa2cc00412841cca3cc00103f000b20080d010c020b410421022008450d010b200710350b20002002360200200441306a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000bc70402077f037e230041306b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220022802042105200241146a2802002103200241246a280200210620012802102107200128021821082004410136020020042003360204410521020240200820072001411c6a2209200410be050d002003417f4c0d0402400240024020030d00410021084101210702402001280214280208200541014100101c41026a220a41024b0d00200141146a2105200a0e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200310392207450d0002402001280214280208200520072003101c41026a220a41024b0d00200141146a210520032108200a0e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2003ad4220862007ad8410092203290000210b200341086a290000210c200341106a290000210d200441186a200341186a290000370300200441106a200d370300200441086a200c3703002004200b37030020031035200128021821032001280210210120044282808080800437032002400240200320012009200441206a10be050d0002402005280200280208200620044120101d41026a220141024b0d0020010e03010002010b41cfa2cc00412841cca3cc00103f000b20080d010c020b410421022008450d010b200710350b20002002360200200441306a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000ba20402077f017e230041206b2204240002400240024002402003450d0020022802000d0020034101460d0120022802100d0120034102460d0220022802200d0220022802042105200241146a2802002103200241246a280200210620012802102107200128021821082004410136021020042003360214410521020240200820072001411c6a2209200441106a10be050d002003417f4c0d0402400240024020030d00410021084101210702402001280214280208200541014100101c41026a220a41024b0d00200141146a2105200a0e03040002040b41cfa2cc00412841f8a2cc00103f000b0240200310392207450d0002402001280214280208200520072003101c41026a220a41024b0d00200141146a210520032108200a0e03030002030b41cfa2cc00412841f8a2cc00103f000b1045000b2003ad4220862007ad8410042203290000210b200441086a200341086a2900003703002004200b37030020031035200128021821032001280210210120044282808080800237031002400240200320012009200441106a10be050d0002402005280200280208200620044110101d41026a220141024b0d0020010e03010002010b41cfa2cc00412841cca3cc00103f000b20080d010c020b410421022008450d010b200710350b20002002360200200441206a24000f0b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b41e6c1c60041f40341dcc5c6001064000b1044000bc60304017f017e017f027e230041e0006b22042400200341086a2903002105200328020421060240024002400240024002400240024020032802000e06010203040005010b427f2107200520012903487c220820055a0d050c060b2006ad21080c040b2004200129035042002006ad4200108408427f210720042903084200520d04200429030021080c030b200441106a200129035842002006ad4200108408427f210720042903184200520d03200429031021080c020b200441206a200129031842002006ad4200108408427f210720042903284200520d02200429032021080c010b200441306a200129032842002006ad4200108408200441c0006a20012903204200200542ffffffff0f834200108408427f210720042903484200520d0120042903384200520d012004290340220820042903307c22052008540d01200520012903307c22082005540d010b200821070b200042002000290308220520077d220720072005561b37030841002103024020072005580d00024020022802000d00200241086a280200450d00200228020410350b4101210320024101360200200220042902543702042002410c6a200441dc006a2802003602000b200441e0006a240020030bd30e06017f017e017f017e077f067e230041e0026b2208240020014200200129030822092007280240220a41e8006a200a41e0006a200241ff01714101461b2903007d220b200b2009561b37030802400240200b2009580d00200041003a0000200041086a4122360200200041046a418496ca003602000c010b0240024002400240200728021841016a220c41004c0d00200741186a210d2007200c360218024002402007411c6a280200220e450d00200741206a280200210f0340200e41086a210a200e2f010622104105742101410021110240024003402001450d012003200a412010a0082212450d02200141606a2101201141016a2111200a41206a210a2012417f4a0d000b2011417f6a21100b200f450d02200f417f6a210f200e20104102746a41880b6a280200210e0c010b0b200e201141e0006c6a220141c5036a310000200141e8026a2903002209200950220a1ba7450d004200200141f8026a290300200a1b21094200200141f0026a290300200a1b210b0c010b200841106a200741286a28020020032007412c6a28020028021c110400200841186a29030021092007280218210c2008290310210b0b200d200c417f6a220f3602000240200b20057d2213200b56200920067d200b200554ad7d220b200956200b2009511b4101470d00200041003a0000200041086a411d360200200041046a41a696ca003602000c050b200c41004c0d012007200c36021802400240200728021c220e450d00200741206a280200210c0340200e41086a210a200e2f010622104105742101410021110240024003402001450d012004200a412010a0082212450d02200141606a2101201141016a2111200a41206a210a2012417f4a0d000b2011417f6a21100b200c450d02200c417f6a210c200e20104102746a41880b6a280200210e0c010b0b200e201141e0006c6a220141c5036a310000200141e8026a2903002209200950220a1ba7450d004200200141f8026a290300200a1b21144200200141f0026a290300200a1b21150c010b2008200741286a28020020042007412c6a28020028021c1104002007280218417f6a210f200841086a2903002114200829030021150b200d200f36020042002109024020152014844200520d00200728024022012903900120055820014198016a290300221620065820162006511b0d00200041003a0000200041086a411f360200200041046a41c396ca003602000c050b420021160240200241ff01714102460d00200728024022014198016a290300211620012903900121090b201320097d2217201356200b20167d2013200954ad7d2209200b562009200b511b0d0202402005200684500d00200841b8026a2003108e02200841206a20082802b802220a20082802c002108f02200841d0006a2903004200200829032042015122011b2116200841c8006a290300420020011b2118024020082802bc02450d00200a10350b2018201756201620095620162009511b0d040b0240201520057c22162015542201201420067c2001ad7c220920145420092014511b450d00200041003a0000200041086a412d360200200041046a418997ca003602000c050b024020032004460d0020032004412010a008450d00200d20032013200b10ae04200d20042016200910ae04200841b8026a41086a220a200341086a290000370300200841b8026a41106a2211200341106a290000370300200841b8026a41186a2212200341186a29000037030020084198026a41086a220e200441086a29000037030020084198026a41106a220c200441106a29000037030020084198026a41186a2202200441186a290000370300200820032900003703b802200820042900003703980202402007413c6a2802002201200741386a280200470d00200741346a20014101109501200728023c21010b2007280234200141d8026c6a220141003a0000200120082f00dd023b00012001420037000820014101360004200120082903b8023700112001200829039802370031200141036a200841df026a2d00003a0000200141106a41003a0000200141196a200a290300370000200141216a2011290300370000200141296a2012290300370000200141396a200e290300370000200141c1006a200c290300370000200141c9006a200229030037000020012005370358200141e0006a2006370300200141d4006a20084191026a41036a2800003600002001200828009102360051200120082903f001370368200141f0006a200841f0016a41086a290300370300200141f8006a200841f0016a41106a29030037030020014180016a200841f0016a41186a29030037030020014188016a200841206a41d001109d081a2007200728023c41016a36023c0b200041043a00000c040b41ac96cc004118200841206a41d8c1c30041d496cc001046000b41ac96cc004118200841206a41d8c1c30041d496cc001046000b200041003a0000200041086a4127360200200041046a41e296ca003602000c010b200041830c3b0100200041086a4115360000200041046a41a389c200360000200041026a41013a00000b200841e0026a24000b812f05027f027e087f037e017f230041f00d6b22072400024002400240024002400240024002402001280230200128024022082802b001460d002004420020042903082209200841c0006a2903007d220a200a20095622081b37030820080d02200741106a41186a200141e8006a290000370300200741106a41106a200141e0006a290000370300200741106a41086a200141d8006a29000037030020072001290050370310200741900b6a41186a20063502084220862006350200841009220841186a290000370300200741900b6a41106a200841106a290000370300200741900b6a41086a200841086a290000370300200720082900003703900b200810354120103322080d010c070b200041003a0004200041013602002000410c6a4129360200200041086a41aeb9ca00360200200041106a2006290200370200200041186a200641086a2802003602000c050b20082005290000370000200841186a200541186a290000370000200841106a200541106a290000370000200841086a200541086a2900003700002008412041c00010372208450d05200820072903900b370020200841386a200741900b6a41186a290300370000200841306a200741900b6a41106a290300370000200841286a200741900b6a41086a290300370000200841c00041800110372208450d0520082007290310370040200841d8006a200741106a41186a290300370000200841d0006a200741106a41106a290300370000200841c8006a200741106a41086a290300370000200741f0026a41186a220b2008ad4280808080800c841009220c41186a290000370300200741f0026a41106a220d200c41106a290000370300200741f0026a41086a220e200c41086a2900003703002007200c2900003703f002200c1035200741306a41186a220c200b290300370300200741306a41106a220b200d290300370300200741306a41086a220d200e290300370300200720072903f00237033020081035200741f0006a41d8006a200d290300370300200741d0016a200b290300370300200741d8016a200c2903003703004100210d200741ac016a41003602002007419c016a41d8b9ca0036020020074194016a410036020020072001360278200741f0006a41286a200141186a220f360200200720072903303703c001200742083702a40120074200370388012007410036027c200720012802483602b801200720012903403703b0012007200128023041016a3602a001200129030021092007200128024c3602bc0120072009370370200741f4016a41026a2208200641036a2d00003a0000200720062f00013b01f40120062d0000211020062902042109200741a8026a41186a200541186a290000370300200741a8026a41106a200541106a290000370300200741a8026a41086a200541086a290000370300200720052900003703a8022007410136028801200f200741306a10930421062007200728028801417f6a220c3602880120060d010240200c0d002007417f36028801200741f8016a41186a200741306a41186a290300370300200741f8016a41106a200741306a41106a290300370300200741f8016a41086a200741306a41086a290300370300200720072903303703f80102400240200728028c01220d450d0020074190016a280200210e0c010b4100210e200741900b6a410041e002109f081a200741f0026a410041a008109f081a41880b1033220d450d07200d41003b0106200d4100360200200d41086a200741900b6a41e002109d081a200d41e8026a200741f0026a41a008109d081a20074190016a41003602002007200d36028c010b20072007418c016a22113602980b2007200d3602940b2007200e3602900b0340200d41086a2108200d2f0106221241057421064100210c024002400240024003402006450d010240200741f8016a2008412010a008220b0d0041002106200e21080c030b200641606a2106200c41016a210c200841206a2108200b417f4a0d000b200c417f6a21120b200e0d0141012106410021082012210c0b200741f0026a41106a200c360200200741fc026a2011360200200741f0026a41086a200d360200200720113602980b2007200d3602940b2007200e3602900b200720083602f402200720063602f002024002402006450d00200741d0026a41186a200741f8016a41186a290300220a370300200741d0026a41106a200741f8016a41106a2903002213370300200741d0026a41086a200741f8016a41086a2903002214370300200720072903f80122153703d002200741ac0b6a2014370200200741900b6a41246a2013370200200741bc0b6a200a3702002007200741f0006a41246a3602a00b2007200c36029c0b200720113602980b2007200d3602940b200720083602900b200720153702a40b200741a8036a4100360200200741003a00ac03200742003703f002200741003a00cd03200741003602a0032007420037038803200741900b6a200741f0026a10800321060c010b200d200c41e0006c6a41e8026a21060b200741c0026a290300210a20064201370318200641013a003c200641286a427f370300200641206a427f3703002006413d6a20072903a802370000200641c5006a200741a8026a41086a290300370000200641cd006a200741b8026a290300370000200641d5006a200a370000200720072802880141016a36028801200741f0026a20044101200741106a200741306a20022003200741f0006a10bf05024020072d00f002220d4104460d00200741f0016a41026a20072d00f3023a0000200741ec016a41026a200741f4016a41026a2d00003a0000200720072f00f1023b01f001200720072f01f4013b01ec012009422088a72106200741f0026a41086a280200210420072802f40221052009a721010c080b200741f0026a200520072802b80128020010a306024020072802f0024101470d00200741ec016a41026a200741f4016a41026a2d00003a0000200720072f01f4013b01ec012009422088a72106200741f8026a280200210420072802f40221052009a721014100210d0c080b200741900b6a41186a200741f0026a410472220641186a2802002208360200200741f8016a41106a200641086a290200370300200741f8016a41186a200641106a29020037030020074198026a2008360200200741063602fc01200741ffd5cb003602f801200720062902003703800220072802b40121062007200741f0006a360288032007290370210a20072802bc01210820074198036a200741106a41086a290300370300200741a0036a200741106a41106a290300370300200741a8036a200741106a41186a290300370300200720033703f802200720023703f0022007200836028c032007200a370380032007200729031037039003200720103a00d002200720093702d402200720072f01f4013b00d1022007200741f4016a41026a2d00003a00d302200741900b6a2006200741f8016a200741f0026a200741d0026a2004109a05200741a8026a41026a220620072d00970b3a0000200741cc026a41026a2208200741a30b6a2d00003a0000200720072f00950b3b01a802200720072f00a10b3b01cc02200741900b6a41086a28020021052007419c0b6a280200210e200741900b6a41106a2d0000211020072d00940b2112024002400240024020072802900b4101460d00200741a4026a41026a20062d00003a0000200741a0026a41026a20082d00003a0000200720072f01a8023b01a402200720072f01cc023b01a00220072802880141016a221141004c0d05200720113602880102400240200728028c012204450d00200741f0006a41206a280200210d0340200441086a210820042f0106221641057421064100210c0240024003402006450d01200741306a2008412010a008220b450d02200641606a2106200c41016a210c200841206a2108200b417f4a0d000b200c417f6a21160b200d450d02200d417f6a210d200420164102746a41880b6a28020021040c010b0b2004200c41e0006c6a220641c5036a310000200641e8026a290300220220025022081ba7450d004200200641f8026a29030020081b21024200200641f0026a29030020081b21030c010b2007200728029801200741306a200728029c0128021c110400200741086a29030021022007290300210320072802880121110b20072011417f6a36028801200320072802b00122062903900154200220064198016a29030022035420022003511b0d01200741d0026a41086a2208200741106a41086a290300370300200741d0026a41106a220c200741106a41106a290300370300200741d0026a41186a220b200741106a41186a290300370300200741a8026a41086a2204200741306a41086a290300370300200741a8026a41106a220d200741306a41106a290300370300200741a8026a41186a2211200741306a41186a290300370300200720072903103703d002200720072903303703a802024020072802ac01220620072802a801470d00200741a4016a2006410110950120072802ac0121060b20072802a401200641d8026c6a220641003a0000200620072f00cc023b0001200641013a00102006410036000c20064201370004200620072903d002370011200620072903a802370031200641036a200741cc026a41026a2d00003a0000200641196a2008290300370000200641216a200c290300370000200641296a200b290300370000200641396a2004290300370000200641c1006a200d290300370000200641c9006a201129030037000020064180016a200741bf0b6a290000370000200641f9006a200741b80b6a290000370000200641f1006a200741900b6a41206a290000370000200641e9006a200741900b6a41186a290000370000200641e1006a200741900b6a41106a290000370000200641d9006a200741900b6a41086a290000370000200620072900900b37005120064188016a200741f0026a41d001109d081a200741f0016a41026a2208200741a4026a41026a2d00003a0000200741ec016a41026a220c200741a0026a41026a2d00003a0000200720072802ac0141016a22063602ac01200720072f01a4023b01f001200720072f01a0023b01ec010240200741f8016a41186a280200450d002007418c026a280200103520072802ac0121060b200741ec006a41026a20082d00003a0000200741e8006a41026a200c2d00003a0000200720072f01f0013b016c200720072f01ec013b0168200741f0006a41206a280200210b20072802a801211120072802a40121042007280294012116200728028c01210d0240200728027c2208450d0020074180016a280200450d00200810350b200741900b6a41026a2208200741ec006a41026a2d00003a0000200741f0006a41026a220c200741e8006a41026a2d00003a0000200720072f016c3b01900b200720072f01683b0170201041ff01710d02200720163602f8022007200b3602f4022007200d3602f002200f200741f0026a109504200141346a2001413c6a2208280200200641d8026c220641d8026d220c1095012001280234200828020041d8026c6a20042006109d081a20082008280200200c6a36020002402011450d00201141d8026c450d00200410350b200741e4006a41026a200741900b6a41026a2d00003a0000200741e0006a41026a200741f0006a41026a2d00003a0000200720072f01900b3b0164200720072f01703b01600c030b200741a40b6a2902002102200741f0016a41026a20062d00003a0000200741ec016a41026a20082d00003a0000200720072f01a8023b01f001200720072f01cc023b01ec012002422088a721062002a72101200e21042012210d0c090b200741ec016a41026a200741a4026a41026a2d00003a0000200720072f01a4023b01ec014100210d411e21042005210141fcb9ca00210520122110200e21060c080b200741e4006a41026a20082d00003a0000200741e0006a41026a200c2d00003a0000200720072f01900b3b0164200720072f01703b016002402006450d00200641d8026c210141002106034002400240200420066a22082d0000220c41014b0d0002400240200c0e020001000b0240200841086a28020041ffffff3f71450d00200841046a28020010350b200841106a2d00004107470d02200841386a280200450d02200841346a28020010350c020b200841286a10bb020c010b200841e8006a28020041ffffff3f71450d00200841e4006a28020010350b2001200641d8026a2206470d000b0b02402011450d00201141d8026c450d00200410350b02400240200d0d004100211620074184036a4100360200200741003602f4020c010b02400240200b0d00200d21060c010b200b2106200d2108034020082802880b21082006417f6a22060d000b200d21060340200620062f01064102746a41880b6a2802002106200b417f6a220b0d000b2008210d0b2007418c036a20062f010636020020074188036a410036020020074184036a20063602002007410036028003200742003703f8022007200d3602f402200741003602f0020b2007201636029003200741f0026a108f030b200741d4006a41026a2206200741e4006a41026a2d00003a0000200741d0006a41026a2208200741e0006a41026a2d00003a0000200720072f0164220c3b015c200720072f0160220b3b01582007200c3b01542007200b3b0150200041246a20123a00002000411c6a200741c8006a290300370000200041146a200741c0006a2903003700002000410c6a200741386a29030037000020002007290330370004200041306a20103a00002000412c6a200e360200200041286a2005360200200020072f01543b0025200041276a20062d00003a0000200020072f01503b0031200041336a20082d00003a0000200041003602000c080b200e417f6a210e200d20124102746a41880b6a280200210d0c010b0b41ac96cc004118200741f0026a41d8c1c30041d496cc001046000b41a797cc004110200741f0026a41c8c1c30041c897cc001046000b200041003a0004200041013602002000410c6a412a360200200041086a419abaca00360200200041106a2006290200370200200041186a200641086a2802003602000c030b200741ec016a41026a20082d00003a0000200720072f01f4013b01ec012009422088a721062009a72101419cc1c3002105412a21040c010b20074190026a280200450d002007418c026a28020010350b200741e4006a41026a200741f0016a41026a2d00003a0000200741e0006a41026a200741ec016a41026a2d00003a0000200720072f01f0013b0164200720072f01ec013b01600240200728027c2208450d0020074180016a280200450d00200810350b2006ad210202400240200728028c01220b0d004100210e20074184036a4100360200200741003602f4020c010b200728029401210e0240024020074190016a28020022080d00200b21060c010b20082106200b210c0340200c2802880b210c2006417f6a22060d000b200b21060340200620062f01064102746a41880b6a28020021062008417f6a22080d000b200c210b0b2007418c036a20062f010636020020074188036a410036020020074184036a20063602002007410036028003200742003703f8022007200b3602f402200741003602f0020b200242208621022001ad21032007200e36029003200741f0026a108f03024020072802ac012206450d0020072802a401210b200641d8026c210141002106034002400240200b20066a22082d0000220c41014b0d0002400240200c0e020001000b0240200841086a28020041ffffff3f71450d00200841046a28020010350b200841106a2d00004107470d02200841386a280200450d02200841346a28020010350c020b200841286a10bb020c010b200841e8006a28020041ffffff3f71450d00200841e4006a28020010350b2001200641d8026a2206470d000b0b20022003842102024020072802a8012206450d00200641d8026c450d0020072802a40110350b200741dc006a41026a200741e4006a41026a2d000022063a0000200741d8006a41026a2208200741e0006a41026a2d00003a0000200720072f0164220c3b015c200720072f01603b01582000200d3a00042000200c3b0005200041076a20063a0000200041106a20103a00002000410c6a2004360200200041086a2005360200200041146a200237020020004101360200200020072f01583b0011200041136a20082d00003a00000b200741f00d6a24000f0b103c000bf42003167f037e067f230041c0026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110fc062003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200a200a417f6a220d2000200a4105746a2000200d4105746a412010a008220e410048220f1b2210200a41016a2211200d200a200f1b220a200020114105746a2000200a4105746a412010a00841004822111b220a2000200a4105746a200020104105746a412010a00822104100481b210a200c200c417f6a220d2000200c4105746a2000200d4105746a412010a008221241004822131b2214200c4101722215200d200c20131b220c200020154105746a2000200c4105746a412010a00822134100481b220c2000200c4105746a200020144105746a412010a00822144100481b210c200b200b417f6a220d2000200b4105746a2000200d4105746a412010a008221541004822161b2217200b41016a2218200d200b20161b220b200020184105746a2000200b4105746a412010a008220d4100481b220b2000200b4105746a200020174105746a412010a00822164100481b210b41024101200f1b200e411f7620111b2010411f766a2012411f766a2013411f766a2014411f766a2015411f766a200d411f766a2016411f766a210d0b2000200c4105746a2000200a4105746a412010a008220f411f76200d6a2000200b4105746a2000200a200c200f410048220f1b220e4105746a412010a0082210411f766a210d2000200b200e20104100481b220b4105746a2000200c200a200f1b22194105746a412010a008417f4c0d01200b21190c020b2000200110fd060c0f0b200d41016a220d410c490d0002402001410176220b450d00200020014105746a41606a210a2000210c0340200441206a41186a220d200c41186a220f290000370300200441206a41106a220e200c41106a2210290000370300200441206a41086a2211200c41086a22122900003703002004200c290000370320200a41086a2213290000211a200a41106a2214290000211b200a41186a2215290000211c200c200a290000370000200f201c3700002010201b3700002012201a3700002015200d2903003700002014200e29030037000020132011290300370000200a2004290320370000200a41606a210a200c41206a210c200b417f6a220b0d000b0b20012019417f736a21194101210a0c010b200d45210a0b0240200a452009724101710d002000200110fe060d0d0b2002450d02201920014f0d0102402002200020194105746a220a412010a00841004e0d0020002108200121070c040b200441206a41186a2212200041186a220e290000370300200441206a41106a2213200041106a2210290000370300200441206a41086a2214200041086a221129000037030020042000290000370320200a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2000200a290000370000200e201c3700002010201b3700002011201a370000200d2012290300370000200b2013290300370000200c2014290300370000200a2004290320370000200441c0016a41186a2217200e290000370300200441c0016a41106a22182010290000370300200441c0016a41086a22192011290000370300200420002900003703c001200041606a2115200041206a21164100210c2001210b03400240200c200b417f6a220d4f0d002016200c4105746a210a0340200441c0016a200a412010a008417f4c0d01200a41206a210a200d200c41016a220c470d000b200d210c0b2015200b4105746a210a02400340200c200b417f6a220b4f0d01200441c0016a200a412010a008210d200a41606a220f210a200d4100480d000b20122016200c4105746a220a41186a220d2900003703002013200a41106a221d2900003703002014200a41086a22062900003703002004200a290000370320200f41286a221e290000211a200f41306a221f290000211b200f41386a2220290000211c200a200f41206a220f290000370000200d201c370000201d201b3700002006201a37000020202012290300370000201f2013290300370000201e2014290300370000200f2004290320370000200c41016a210c0c010b0b200020042903c001370000200e2017290300370000201020182903003700002011201929030037000002402001200c41016a220a490d002000200a4105746a21002001200a6b220141154f0d010c0c0b0b200a200141e485cc001059000b2019200141d086cc001042000b2007450d010b201920074f0d01200441206a41186a2216200841186a221e290000370300200441206a41106a2217200841106a221f290000370300200441206a41086a2218200841086a222029000037030020042008290000370320200820194105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200441186a2205201e290000370300200441106a2209201f290000370300200441086a2221202029000037030020042008290000370300200841206a21014100211d2007417f6a220d450d022001210a0340200a2004412010a00841004e0d03200a41206a210a200d201d41016a221d470d000b200d211d0c020b4100410041f485cc001042000b20192007418486cc001042000b200820074105746a210c200d210b02400340200c2100200b220a201d4d22060d01200a417f6a210b200041606a220c2004412010a008417f4a0d000b0b0240200a201d490d00200d200a490d0241800121144100210f410021124100210d4100211141800121152001201d4105746a2222210103400240200020016b220a419fc0004b22190d00200a410576220a41807f6a200a2012200f492011200d49220c72220b1b210a0240200b450d002015200a200c1b2115200a2014200c1b21140c010b200a200a41017622156b21140b02402011200d470d00024020150d00200441c0006a220d21110c010b4100210a200441c0006a2211210d2001210c0340200d200a3a0000200d200c2004412010a008417f73411f766a210d200c41206a210c2015200a41016a220a470d000b0b02402012200f470d00024020140d00200441c0016a220f21120c010b200041606a210a4100210c200441c0016a2212210f0340200f200c3a0000200f200a2004412010a008411f766a210f200a41606a210a2014200c41016a220c470d000b0b0240200f20126b220a200d20116b220c200c200a4b1b2213450d002016200120112d00004105746a220a41186a2900003703002017200a41106a2900003703002018200a41086a2900003703002004200a290000370320200120112d00004105746a220a200020122d0000417f734105746a220c290000370000200a41186a200c41186a290000370000200a41106a200c41106a290000370000200a41086a200c41086a290000370000024020134101460d004100210a034020002012200a6a220e2d0000417f734105746a220c20012011200a6a41016a22102d00004105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200120102d00004105746a220c2000200e41016a2d0000417f734105746a220b290000370000200c41186a200b41186a290000370000200c41106a200b41106a290000370000200c41086a200b41086a290000370000200a41026a210c200a41016a220b210a200c2013490d000b2012200b6a21122011200b6a21110b200020122d0000417f734105746a220a2004290320370000200a41186a2016290300370000200a41106a2017290300370000200a41086a2018290300370000201241016a2112201141016a21110b200020144105746b20002012200f461b2100200120154105746a20012011200d461b210120190d000b024002402011200d4f0d002000210a034020162001200d417f6a220d2d00004105746a220c41186a220b2900003703002017200c41106a220f2900003703002018200c41086a22002900003703002004200c290000370320200a41606a220a41086a220e290000211a200a41106a2210290000211b200a41186a2212290000211c200c200a290000370000200b201c370000200f201b3700002000201a3700002012201629030037000020102017290300370000200e2018290300370000200a20042903203700002011200d490d000c020b0b2001210a2012200f4f0d000340200f417f6a220f2d0000210c2016200a41186a220b2900003703002017200a41106a220d2900003703002018200a41086a22012900003703002004200a2900003703202000200c417f734105746a220c41086a220e290000211a200c41106a2210290000211b200c41186a2211290000211c200a200c290000370000200b201c370000200d201b3700002001201a3700002011201629030037000020102017290300370000200e2018290300370000200c2004290320370000200a41206a210a2012200f490d000b0b20082004290300370000201e2005290300370000201f2009290300370000202020212903003700002007200a20226b410576201d6a22014d0d032016201e2900003703002017201f2900003703002018202029000037030020042008290000370320200820014105746a220a41086a220c290000211a200a41106a220b290000211b200a41186a220d290000211c2008200a290000370000201e201c370000201f201b3700002020201a370000200d2016290300370000200b2017290300370000200c2018290300370000200a2004290320370000200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41206a2100024002402001200c417f6a220c490d002000200c200a200310c105200821000c010b200820012002200310c105200a2102200c21010b200b200d4f2105200141154f0d010c050b0b201d200a419486cc001059000b200a200d419486cc001058000b20012007418486cc001042000b41a486cc00411c41c086cc00103f000b20014102490d00200041606a210f4101210b0340200b410574210a200b417f6a210c200b41016a210b02402000200a6a220a2000200c4105746a220d412010a008417f4a0d00200441c0016a41186a220e200a41186a2210290000370300200441c0016a41106a2211200a41106a2212290000370300200441c0016a41086a2213200a41086a22142900003703002004200a2900003703c001200a200d2900003700002014200d41086a2900003700002012200d41106a2900003700002010200d41186a2900003700004100210d0240200c450d00200f210a03400240200441c0016a200a412010a0084100480d00200c210d0c020b200a41206a200a290000370000200a41386a200a41186a290000370000200a41306a200a41106a290000370000200a41286a200a41086a290000370000200a41606a210a200c417f6a220c0d000b0b2000200d4105746a220a20042903c001370000200a41186a200e290300370000200a41106a2011290300370000200a41086a20132903003700000b200f41206a210f200b2001470d000b0b200441c0026a24000b130020004103360204200041b0c7c6003602000b130020004125360204200041d8c9c6003602000b9e0303077f017e017f230041106b220224000240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a22063602042001200441016a3602002006450d0020042d0001210720012003417e6a22063602042001200441026a3602002006450d0020042d0002210820012003417d6a22063602042001200441036a36020020060d010b200041003602040c010b20042d0003210620012003417c6a3602042001200441046a360200200241086a200110c401024020022802080d002001280204200228020c2204490d002004417f4c0d02024002400240024020040d0042002109410121030c010b200410392203450d0120012802042004490d02200320012802002004109d081a2001280204220a2004490d062001200a20046b3602042001200128020020046a3602002004ad21090b2003450d02200020092004ad4220868437020820002003360204200020074108742005722008411074722006411874723602000c030b1045000b200310350b200041003602040b200241106a24000f0b1044000b2004200a41a4f0cb001059000bc20101047f230041106b220224002000280200220028020821032000280200210041012104200128021841d9a0c00041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d0003402002200036020c20022002410c6a41accfc70010701a200041016a21002003417f6a22030d000b20022d000421050b0240200541ff01710d002002280200220028021841d8a0c00041012000411c6a28020028020c11000021040b200241106a240020040bb70204027f017e027f037e230041106b220224000240024020012802082203ad42287e2204422088a70d002004a72205417f4c0d00200128020021010240024020050d00410821060c010b200510332206450d020b20024100360208200220063602002002200541286e360204200241002003108f012002280208210502402003450d00200341286c21062002280200200541286c6a21030340200141086a2903002104200141106a2903002107200141186a290300210820012903002109200341206a200141206a290300370300200341186a2008370300200341106a2007370300200341086a200437030020032009370300200341286a2103200541016a2105200141286a2101200641586a22060d000b0b20002002290300370200200041086a2005360200200241106a24000f0b1044000b1045000bbc0201057f024002400240200041046a2802002202200041086a28020022036b20012802042204200128020022056b22064f0d00200320066a22052003490d01200241017422042005200420054b1b22054100480d010240024020020d00024020050d00410121040c020b2005103322040d010c040b2000280200210420022005460d0020042002200510372204450d03200041086a28020021030b20002004360200200041046a200536020020012802002105200128020421040b024020052004460d00200028020021042001200541016a360200200420036a20052d00003a0000200341016a2103200128020022052001280204460d0003402001200541016a360200200420036a20052d00003a0000200341016a2103200128020022052001280204470d000b0b200041086a20033602000f0b103e000b103c000bc60303037f017e047f230041a0076b220224002002200110c40102400240024002402002280200450d00200041003602000c010b20022802042203200128020441b0026e2204200420034b1bad42b0027e2205422088a70d012005a72206417f4c0d010240024020060d00410821070c010b200610332207450d030b4100210420024100360210200220073602082002200641b0026e36020c024002402003450d00200241f0046a41047221080340200241f0046a200110b90220022802f0042106200241c4026a200841ac02109d081a2006411b460d02200241186a200241c4026a41ac02109d081a02402004200228020c470d00200241086a2004410110920120022802082107200228021021040b2007200441b0026c6a22092006360200200941046a200241186a41ac02109d081a2002200441016a22043602102003417f6a22030d000b0b20002002290308370200200041086a200241086a41086a2802003602000c010b2000410036020002402004450d00200441b0026c2106200721040340200410bb02200441b0026a2104200641d07d6a22060d000b0b200228020c2204450d00200441b0026c450d00200710350b200241a0076a24000f0b1044000b1045000ba90603067f017e047f230041f0006b22022400200241286a200141146a350200422086200135020c84102710c2010240024020022802282203450d00200241086a2104200141106a2105034002400240200141086a22062802002207200229022c2208422088a722094b0d002001280200220a2003460d01200a2003200710a008450d010b2008a7450d02200310350c020b02402005280200450d00200128020c10350b2001200336020c20052008370200200220032009109c020240024020022d00104102460d00200241186a41086a200441086a280200360200200220042902003703182002280204210b2002280200210c024020012d0018450d002001350214422086200135020c8410070b2001280214220920062802002203490d0102400240200920036b22094108490d00200941786a2107200128020c20036a41086a210a0c010b410021070240410028028cb54c0d0041b0b4cc00210a0c010b410021074100280298b54c21034100280294b54c21094100280290b54c2106200241e500360268200242b48080801037036020024187a1c00036025c20024213370254200241f4a0c0003602502002420037034841b0b4cc00210a200241b0b4cc0036024420024201370338200241eca0c00036023420024113360230200241f4a0c00036022c20024101360228200941aca2c000200641024622061b200241286a200341c4a2c00020061b2802101102000b41002103200241003a00480240034020072003460d01200241286a20036a200a20036a2d00003a00002002200341016a22093a00482009210320094120470d000b20002002290328370000200041186a200241286a41186a290300370000200041106a200241286a41106a290300370000200041086a200241286a41086a2903003700002000200b3602242000200c36022020002002290318370228200041306a200241186a41086a2802003602000c050b0240200341ff0171450d00200241003a00480b200b41ffffff3f71450d00200c10350b200241286a2001350214422086200135020c84102710c201200228022822030d010c020b0b2003200941889aca001059000b200041023a00300b200241f0006a24000bf707040c7f017e047f037e23004190016b220224000240024002400240200141086a220328020022042001410c6a2802002205460d002001280210220628020021072006280208220841014b210903402003200441206a220a360200200241f0006a41186a200441186a290000370300200241f0006a41106a200441106a290000370300200241f0006a41086a200441086a29000037030020022004290000370370410021040240024020090d0020080e020401040b2008210b0340200b410176220c20046a220d20042007200d4105746a200241f0006a412010a0084101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241f0006a412010a0080d02200a2104200a2005470d000b0b2000410036020820004201370200200128020441ffffff3f71450d01200128020010350c010b200241d0006a41086a2204200241f0006a41086a290300370300200241d0006a41106a220b200241f0006a41106a290300370300200241d0006a41186a220c200241f0006a41186a29030037030020022002290370220e3703102002200e37035041201033220f450d01200f2002290350370000200f41186a200c290300370000200f41106a200b290300370000200f41086a200429030037000020024281808080103702042002200f36020020012802042110200128020021110240200a2005460d00410121120340200628020821032006280200210702400340200241f0006a41186a2208200a41186a290000370300200241f0006a41106a2209200a41106a290000370300200241f0006a41086a2201200a41086a2900003703002002200a290000370370200a41206a210a4100210402400240200341014b0d0020030e020301030b2003210b0340200b410176220c20046a220d20042007200d4105746a200241f0006a412010a0084101481b2104200b200c6b220b41014b0d000b0b200720044105746a200241f0006a412010a0080d01200a2005470d000c030b0b200241d0006a41086a2001290300220e370300200241d0006a41106a20092903002213370300200241d0006a41186a20082903002214370300200220022903702215370350200241106a41186a220b2014370300200241106a41106a220c2013370300200241106a41086a220d200e37030020022015370310024020122002280204470d00200220124101108a012002280200210f0b200f20124105746a22042002290310370000200441186a200b290300370000200441106a200c290300370000200441086a200d2903003700002002201241016a2212360208200a2005470d000b0b0240201041ffffff3f71450d00201110350b20002002290300370200200041086a200241086a2802003602000b20024190016a24000f0b1045000baa0704057f017e0a7f027e23004180016b22032400200341306a2001200228020c220411020002400240024002402003280230450d00200341d8006a41106a200341306a41106a290300370300200341d8006a41086a200341306a41086a290300370300200341d8006a41186a200341306a41186a290300370300200341d8006a41206a200341306a41206a280200360200200341106a41086a200341e4006a290200370300200341106a41106a200341ec006a290200370300200341106a41186a200341f4006a290200370300200320032903303703582003200329025c370310200341d8006a200120022802102205110200417f2003280258220641016a220720072006491bad42287e2208422088a70d022008a72206417f4c0d02200610332209450d032009200329031037030020094201370320200941186a200341106a41186a220a290300370300200941106a200341106a41106a220b290300370300200941086a200341106a41086a220c29030037030020034101360208200320093602002003200641286e2207360204200341306a2001200411020002402003280230450d00200341d8006a41047221064102210d41c800210e0340200341d8006a41206a200341306a41206a280200360200200341d8006a41186a220f200341306a41186a290300370300200341d8006a41106a2210200341306a41106a290300370300200341d8006a41086a2211200341306a41086a29030037030020032003290330370358200c200641086a290200370300200b200641106a290200370300200a200641186a29020037030020032006290200370310200f200a2903003703002010200b2903003703002011200c290300370300200320032903103703580240200d417f6a2007470d00200341306a2001200511020020032007417f2003280230221241016a220920092012491b108f01200328020021090b2009200e6a221241606a220720032903583703002011290300210820102903002113200f290300211420124201370300200741186a2014370300200741106a2013370300200741086a20083703002003200d360208200341306a200120041102002003280230450d01200e41286a210e200d41016a210d200328020421070c000b0b2001200228020011030002402002280204450d00200110350b20002003290300370200200041086a200341086a2802003602000c010b2000410036020820004208370200200120022802001103002002280204450d00200110350b20034180016a24000f0b1044000b1045000b1300200041053602042000418cc5c7003602000b130020004106360204200041f0f2c2003602000b130020004102360204200041b8b6c3003602000b130020004105360204200041f489c2003602000b3400200041e3efcb0036020420004100360200200041146a4101360200200041106a4198bfc700360200200041086a42123702000b130020004101360204200041f0bdc7003602000b130020004108360204200041c8aac0003602000b130020004101360204200041d0ebcb003602000b1300200041113602042000418cf9c4003602000b130020004107360204200041a0e0ca003602000b130020004105360204200041d890c2003602000b130020004106360204200041ccc9c7003602000b1300200041013602042000419cbcc7003602000b130020004102360204200041d0b9c7003602000b13002000410236020420004198b8c7003602000b130020004103360204200041d8e4cb003602000b13002000410b360204200041d4aec8003602000b3400200041f1d8cb0036020420004100360200200041146a4105360200200041106a41b8b1c700360200200041086a42093702000b130020004105360204200041a89fc7003602000b1300200041083602042000419492c7003602000b130020004108360204200041c083c7003602000b13002000410636020420004194fec6003602000b130020004103360204200041fc98c8003602000b130020004103360204200041a4c4c4003602000b130020004101360204200041bce8cb003602000b130020004107360204200041fcbac3003602000b13002000410f360204200041dc9dc8003602000b130020004106360204200041dcd8ca003602000b130020004102360204200041e8efc4003602000b130020004102360204200041bc89c5003602000b2e01017f02404104103322020d001045000b20004284808080c000370204200020023602002002418080013600000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241203600000b3a01017f02404110103322020d001045000b20024200370008200242808086bdbacdd21a370000200042908080808002370204200020023602000b3b01017f02404110103322020d001045000b200242003700082002428080a8ec85afd1b101370000200042908080808002370204200020023602000b3901017f02404110103322020d001045000b200242003700082002428080e983b1de16370000200042908080808002370204200020023602000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241083600000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241023600000b2201017f230041106b22022400200241003602002000200210e503200241106a24000bff0101017f230041a0016b22022400200241003a0088012002418080013602800120024280808480800237037820024280c2d72f37036820024280e1eb17370360200242a0c21e370358200242a0c21e370350200242e0ef9720370348200242e0c9dc29370340200242e0ef9720370338200242a0c21e370330200242a0c21e370328200242a0c21e370320200242a0c21e370318200242a0c21e370310200242a0c21e370308200242a0c21e37030020024280808080c000370370200241203602840120024100360298012002420137039001200220024190016a10f305200041086a2002280298013602002000200229039001370200200241a0016a24000bd00301017f230041106b22022400200220002802703602082001200241086a41041078200220002903003703082001200241086a41081078200220002903083703082001200241086a41081078200220002903103703082001200241086a41081078200220002903183703082001200241086a41081078200220002903203703082001200241086a41081078200220002903283703082001200241086a41081078200220002903303703082001200241086a41081078200220002903383703082001200241086a41081078200220002903403703082001200241086a41081078200220002903483703082001200241086a41081078200220002903503703082001200241086a41081078200220002903583703082001200241086a41081078200220002903603703082001200241086a41081078200220002903683703082001200241086a41081078200220002802743602082001200241086a41041078200220002802783602082001200241086a410410782002200028027c3602082001200241086a4104107820022000280280013602082001200241086a41041078200220002d0088013a00082001200241086a4101107820022000280284013602082001200241086a41041078200241106a24000b2d01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241e8073600000b2d01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241e5003600000b3701017f02404110103322020d001045000b2002420037000820024280c8afa025370000200042908080808002370204200020023602000b960202037f017e230041106b2202240020002802102103200041186a28020022042001107720012003200410782002200028021c36020020012002410410780240412010332203450d002003200029002c370000200341186a200041c4006a290000370000200341106a2000413c6a290000370000200341086a200041346a290000370000200120034120107820031035200029030021052002200041086a2903003703082002200537030020012002411010782002200028022036020020012002410410780240024020002802244101460d00200241003a000020012002410110780c010b200241013a000020012002410110782002200041286a28020036020020012002410410780b200241106a24000f0b1045000bf10203037f017e037f230041106b22022400200241003602082002420137030020002d00002103410110332104024002400240024020034101460d002004450d02200441003a0000200220043602002002428180808010370204200041086a200210f705200235020842208621052002280204452104200228020021000c010b2004450d01200441013a0000200220043602002002428180808010370204412010332203450d0220032000290001370000200341186a2206200041196a290000370000200341106a2207200041116a290000370000200341086a2208200041096a29000037000020044101412110372200450d0120002003290000370001200041096a2008290000370000200041116a2007290000370000200041196a200629000037000020022000360200200242a1808080900437020420031035410021044280808080900421050b200129020020052000ad841002024020040d00200010350b200241106a24000f0b103c000b1045000bc90402017f037e23004190016b22042400024002400240024020002d00000e03000102000b200441206a41186a200141186a290000370300200441206a41106a200141106a290000370300200441206a41086a200141086a29000037030020042001290000370320200041016a2003ad4220862002ad84200441206a102041014621000c020b200441206a41186a200141186a290000370300200441206a41106a200141106a290000370300200441206a41086a200141086a29000037030020042001290000370320200041016a2003ad4220862002ad84200441206a101541014621000c010b2003ad4220862002ad84100922022900002105200241086a2900002106200241106a2900002107200441186a200241186a290000370300200441106a2007370300200441086a2006370300200420053703002002103541012102200441206a200041016a200410fa054100210020042d00200d00200441c8006a41206a200441c1006a2d00003a0000200441c8006a41186a200441396a290000370300200441c8006a41106a200441316a290000370300200441c8006a41086a200441296a29000037030020042004290021370348200441c8006aad4280808080900484100922002900002105200041086a2900002106200041106a2900002107200441f0006a41186a200041186a290000370300200441f0006a41106a2007370300200441f0006a41086a200637030020042005370370200010350240200441f0006a2001460d00200441f0006a2001412010a0084521020b200221000b20044190016a240020000bcf0303017f017e037f230041d0006b22032400024020012002102f2204422088a72201450d002004a722052d0000220241014b0d002001417f6a210602400240024020020e020001000b41002101200341003a0049200541016a21070240034020062001460d01200341286a20016a200720016a2d00003a00002003200141016a22023a00492002210120024121470d000b200341106a200341316a290000370300200341186a200341396a290000370300200341206a200341c1006a2900003703002003200329002937030820032d0028210241002106200341086a21010c020b200141ff0171450d02200341003a00490c020b2006450d0120052d0001220241034f0d01200341086a41186a200341286a41186a290000370300200341086a41106a200341286a41106a290000370300200341086a41086a200341286a41086a2900003703002003200329002837030841012106200341086a21010b200020023a0001200020063a0000200041026a20012900003700002000410a6a200141086a290000370000200041126a200141106a2900003700002000411a6a200141186a29000037000020051035200341d0006a24000f0b41b89acc00412e200341286a41c09bcc0041e89acc001046000bd40303017f017e027f230041e0006b22022400024002402000290300220342c000540d00024002400240200342808001540d002003428080808004540d014108200379a741037622046b4104490d022002411320044102746b3a00482001200241c8006a41011078200220002903002203370308200441786a21000340200220033c00482001200241c8006a4101107820034208882103200041016a22042000492105200421002005450d000b200220033703082003500d04200241286a41146a410a360200200241346a4134360200200241106a41146a41033602002002200241086a36024020024180caca00360244200241c8006a41146a410036020020024203370214200241a0b3cc003602102002413436022c200241b0b4cc003602582002420137024c20024188caca003602482002200241286a3602202002200241c8006a3602382002200241c4006a3602302002200241c0006a360228200241106a41b0b4cc00104c000b20022003a74102744101723b01482001200241c8006a410210780c030b20022003a74102744102723602482001200241c8006a410410780c020b41c6c9ca00413641c086cc00103f000b20022003a74102743a00482001200241c8006a410110780b200241e0006a24000bc30101017f230041106b2202240002400240024020002d00004101470d00200041046a280200220041ffff034b0d010240200041ef014b0d00200220003a000b20012002410b6a410110780c030b200241fc013a000b20012002410b6a41011078200220003b01082001200241086a410210780c020b200241ff013a000b20012002410b6a410110782001200041016a412010780c010b200241fd013a000b20012002410b6a410110782002200036020c20012002410c6a410410780b200241106a24000bcb0102017f017e230041106b220224000240024020002d00004101460d00200241003a00002001200241011078200220002d0001410047410774200041026a2d0000723a00002001200241011078200029030821032002200041106a290300370308200220033703000c010b200241013a00002001200241011078200029030821032002200041106a290300370308200220033703002001200241101078200041186a29030021032002200041206a290300370308200220033703000b2001200241101078200241106a24000b960401037f230041106b220224000240024020002d0000417f6a220341044b0d000240024002400240024020030e050001020304000b200241003a000f20012002410f6a41011078200041246a28020021032000412c6a28020022042001107702402004450d002004410574210403402001200341201078200341206a2103200441606a22040d000b0b024020002d00014101460d00200241003a000f20012002410f6a410110780c050b200241013a000f20012002410f6a410110782001200041026a412010780c040b200241013a000f20012002410f6a41011078200041046a280200200110af030c030b200241023a000f20012002410f6a41011078200041046a200110e201200041086a280200200110af030c020b200241033a000f20012002410f6a41011078412010332203450d0220032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a290000370000200120034120107820031035200041246a200110e2012002200041216a2d00003a000f20012002410f6a410110780c010b200241043a000f20012002410f6a41011078412010332203450d0120032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a290000370000200120034120107820031035200041246a200110e2010b200241106a24000f0b1045000b4a01037f230041106b220124002001410036020820014201370300200110ff05200128020421022000200128020022032001280208107802402002450d00200310350b200141106a24000ba50303027f047e017f230041f0006b22032400200341106a20012802002204280210200441186a28020010f4032002ad42808080808004842205100922042900002106200441086a2900002107200441106a2900002108200341206a41186a200441186a290000370300200341206a41106a2008370300200341206a41086a200737030020032006370320200410352003200335021842208620032802102209ad84200341206aad4280808080800484101010c2010240024020032802000d00200041003602000c010b200341c0006a20012802002204280210200428021810f40320051009220441086a2900002106200441106a290000210720042900002108200341d0006a41186a200441186a290000370300200341d0006a41106a2007370300200341d0006a41086a20063703002003200837035020041035200335024842208620032802402204ad84200341d0006aad4280808080800484101302402003280244450d00200410350b20002002360200200020032903003702042000410c6a200341086a2802003602000b02402003280214450d00200910350b200341f0006a24000bf80201067f230041d0006b22022400024002400240410b10332203450d00200341edde91e3063600002003410b411610372204450d0120042001290000370004200441002800acb94836000c2004410f6a41002800afb948360000200241003a00484113210320042105410021060340200241003a0008200241086a200520034100472201109d081a024020030d00200241003a00080b20032001490d03200241286a20066a20022d00083a00002002200641016a22073a0048200320016b2103200520016a21052007210620074120470d000b200241086a41186a2203200241286a41186a290300370300200241086a41106a2201200241286a41106a290300370300200241086a41086a2205200241286a41086a2903003703002002200229032837030820041035200041186a2003290300370000200041106a2001290300370000200041086a200529030037000020002002290308370000200241d0006a24000f0b1045000b103c000b2001200341b89dcc001059000b964603027f017e027f230041106b220224000240024020002d0000220341154b0d00024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e16000102030405060708090a0b0c0d0e0f101112131415000b200241003a00002001200241011078200041086a2d0000220341044b0d150240024002400240024020030e050001020304000b200241003a000020012002410110782002200041106a29030037030020012002410810780240200041186a2d0000220341024b0d00024002400240024020030e03000102000b200241003a00000c020b200241013a00000c010b200241023a00000b20012002410110780b2002200041196a2d00003a000020012002410110780c190b200241013a00002001200241011078024002400240024002402000410c6a2d00000e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101107820022000410d6a2d00003a0000200120024101107820022000410e6a2d00003a00000b20012002410110782002200029031837030020012002410810780240200041206a2d0000220341024b0d00024002400240024020030e03000102000b200241003a00000c020b200241013a00000c010b200241023a00000b20012002410110780b2002200041216a2d00003a000020012002410110780c180b200241023a000020012002410110780c170b200241033a000020012002410110782001200041096a412010780c160b200241043a000020012002410110782001200041096a412010780c150b200241013a00002001200241011078200041046a2d0000220341054b0d1402400240024002400240024020030e06000102030405000b200241003a000020012002410110782002200041086a2802003602002001200241041078024002400240024002402000410c6a2d00000e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101107820022000410d6a2d00003a0000200120024101107820022000410e6a2d00003a00000b20012002410110780c190b200241013a000020012002410110780c180b200241023a000020012002410110782001200041056a412010782001200041256a412010782001200041c5006a412010780c170b200241033a000020012002410110782001200041056a412010782002200041e8006a28020036020020012002410410782002200041ec006a28020036020020012002410410782001200041256a412010782001200041c5006a412010780c160b200241043a000020012002410110782001200041056a412010782002200041e8006a28020036020020012002410410782002200041ec006a28020036020020012002410410782001200041256a412010782001200041c5006a412010780240200041f0006a2d00004104460d00200241013a000020012002410110780240024002400240024020002d00700e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a000020012002410110782002200041f1006a2d00003a000020012002410110782002200041f2006a2d00003a00000b20012002410110780c160b200241003a000020012002410110780c150b200241053a000020012002410110782001200041056a412010782002200041e8006a28020036020020012002410410782002200041ec006a28020036020020012002410410782001200041256a412010782001200041c5006a412010780c140b200241023a000020012002410110780240200041046a2d00004101460d00200241003a000020012002410110782001200041056a412010782002200041286a28020036020020012002410410780c140b200241013a000020012002410110782002200041086a28020036020020012002410410780c130b200241033a00002001200241011078200041086a2d0000220341044b0d1202400240024002400240024020030e050001020304000b200241003a000020012002410110782001200041096a41201078200041306a29030021042002200041386a290300370308200220043703000c040b200241013a000020012002410110782001200041096a41201078200041306a29030021042002200041386a290300370308200220043703000c030b200241023a000020012002410110782001200041096a412010782001200041296a41201078200041d0006a29030021042002200041d8006a290300370308200220043703000c020b200241033a000020012002410110782001200041096a41201078200041306a29030021042002200041386a290300370308200220043703002001200241101078200041c0006a29030021042002200041c8006a290300370308200220043703000c010b200241043a000020012002410110782001200041096a41201078200041306a29030021042002200041386a290300370308200220043703000b20012002411010780c120b200241043a0000200120024101107802400240024002400240024002400240200041086a2d00000e080001020304050607000b200241003a0000200120024101107820022000410c6a2802003602002001200241041078200041106a29030021042002200041186a290300370308200220043703002001200241101078200041206a29030021042002200041286a2903003703082002200437030020012002411010780c180b200241013a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c170b200241023a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c160b200241033a0000200120024101107820022000410c6a28020036020020012002410410780c150b200241043a00002001200241011078200041096a2d0000220041024b0d1402400240024020000e03000102000b200241003a000020012002410110780c160b200241013a000020012002410110780c150b200241023a000020012002410110780c140b200241053a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c130b200241063a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c120b200241073a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c110b200241053a00002001200241011078200241003a000020012002410110782002200041046a28020036020020012002410410780c100b200241063a00002001200241011078200041086a2d0000220341104b0d0f0240024002400240024002400240024002400240024002400240024002400240024020030e11000102030405060708090a0b0c0d0e0f10000b200241003a0000200120024101107820022000410c6a2802003602002001200241041078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c1f0b200241013a0000200120024101107820022000410c6a2802003602002001200241041078200041206a29030021042002200041286a290300370308200220043703002001200241101078200041106a2802002103200041186a2802002200200110772000450d1e2000410574210003402001200341201078200341206a2103200041606a22000d000c1f0b0b200241023a000020012002410110780c1d0b200241033a0000200120024101107820022000410c6a2802003602002001200241041078200041096a2d0000220041024b0d1c02400240024020000e03000102000b200241003a000020012002410110780c1e0b200241013a000020012002410110780c1d0b200241023a000020012002410110780c1c0b200241043a0000200120024101107820022000410c6a28020036020020012002410410780c1b0b200241053a0000200120024101107820022000410c6a28020036020020012002410410780c1a0b200241063a0000200120024101107820022000410c6a28020036020020012002410410780c190b200241073a0000200120024101107820022000410c6a28020036020020012002410410782002200041096a2d00003a000020012002410110780c180b200241083a000020012002410110782001200041096a412010782001200041296a412010780c170b200241093a000020012002410110782001200041096a412010780c160b2002410a3a000020012002410110782001200041096a41201078412010332203450d16200341186a200041c1006a290000370000200341106a200041396a290000370000200341086a200041316a2900003700002003200041296a2900003700002001200341201078200310352002200041cc006a28020036020020012002410410780c150b2002410b3a00002001200241011078412010332203450d15200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310352001200041296a41201078200041d0006a29030021042002200041d8006a2903003703082002200437030020012002411010780c140b2002410c3a00002001200241011078412010332203450d14200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310352001200041296a41201078200041d0006a29030021042002200041d8006a2903003703082002200437030020012002411010780c130b2002410d3a00002001200241011078412010332203450d13200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a29000037000020012003412010782003103520022000412c6a28020036020020012002410410780c120b2002410e3a00002001200241011078412010332203450d12200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a29000037000020012003412010782003103520022000412c6a28020036020020012002410410780c110b2002410f3a00002001200241011078412010332203450d11200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310352001200041296a41201078200041f0006a29030021042002200041f8006a2903003703082002200437030020012002411010782001200041c9006a412010780c100b200241103a000020012002410110782001200041096a412010780c0f0b200241073a00002001200241011078200041046a20011083060c0e0b200241083a00002001200241011078200041046a20011083060c0d0b200241093a00002001200241011078200041046a2d0000220341044b0d0c0240024002400240024020030e050001020304000b200241003a00002001200241011078200041086a2802002103200041106a2802002200200110772000450d102003200041306c6a210003402001200341201078200341206a29030021042002200341286a2903003703082002200437030020012002411010782000200341306a2203470d000c110b0b200241013a000020012002410110780c0f0b200241023a000020012002410110782001200041056a412010780c0e0b200241033a000020012002410110782001200041056a412010780c0d0b200241043a000020012002410110782001200041056a412010782001200041256a412010782002200041c5006a2d00003a000020012002410110780c0c0b2002410a3a0000200120024101107820002d0001220041054b0d0b024002400240024002400240024020000e06000102030405000b200241003a00000c050b200241013a00000c040b200241023a00000c030b200241033a00000c020b200241043a00000c010b200241053a00000b20012002410110780c0b0b2002410b3a00002001200241011078200041046a280200220341024b0d0a02400240024020030e03000102000b200241003a00002001200241011078200041086a2802002103200041106a2802002200200110772000450d0c2003200041286c6a2100034020012003412010782002200341206a29030037030020012002410810782000200341286a2203470d000c0d0b0b200241013a000020012002410110780c0b0b200241023a000020012002410110780c0a0b2002410c3a00002001200241011078200041086a2d00002203410a4b0d090240024002400240024002400240024002400240024020030e0b000102030405060708090a000b200241003a0000200120024101107820022000410c6a28020036020020012002410410780c130b200241013a00002001200241011078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c120b200241023a0000200120024101107820022000412c6a2802003602002001200241041078200041306a29030021042002200041386a2903003703082002200437030020012002411010782001200041096a412010780c110b200241033a0000200120024101107820022000410c6a2802003602002001200241041078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c100b200241043a00002001200241011078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c0f0b200241053a00002001200241011078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c0e0b200241063a00002001200241011078200041106a29030021042002200041186a2903003703082002200437030020012002411010780c0d0b200241073a00002001200241011078412010332203450d0d200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310350c0c0b200241083a00002001200241011078412010332203450d0c200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310350c0b0b200241093a00002001200241011078412010332203450d0b200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310352001200041296a41201078200041d0006a29030021042002200041d8006a2903003703082002200437030020012002411010780c0a0b2002410a3a00002001200241011078412010332203450d0a200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310350c090b2002410d3a0000200120024101107802400240024002400240024002400240200041086a2d00000e080001020304050607000b200241003a000020012002410110782001200041096a412010782001200041296a41201078200041d0006a29030021042002200041d8006a2903003703082002200437030020012002411010780c0f0b200241013a000020012002410110782001200041096a412010782001200041296a412010780c0e0b200241023a000020012002410110782001200041096a412010782002200041296a2d00003a000020012002410110780c0d0b200241033a000020012002410110782001200041096a412010782001200041296a41201078412010332203450d0d200341186a200041e1006a290000370000200341106a200041d9006a290000370000200341086a200041d1006a2900003700002003200041c9006a290000370000200120034120107820031035200041f0006a29030021042002200041f8006a2903003703082002200437030020012002411010782002200041e9006a2d00003a000020012002410110780c0c0b200241043a00002001200241011078412010332203450d0c200341186a200041216a290000370000200341106a200041196a290000370000200341086a200041116a2900003700002003200041096a2900003700002001200341201078200310350c0b0b200241053a0000200120024101107820022000410c6a28020036020020012002410410780c0a0b200241063a000020012002410110782001200041096a412010782002200041296a2d00003a000020012002410110780c090b200241073a000020012002410110782001200041096a412010782000412c6a2802002103200041346a28020022002001107720012003200010780c080b2002410e3a00002001200241011078200041046a2d0000220341024b0d0702400240024020030e03000102000b200241003a000020012002410110780240200041086a2d000022034104460d00200241013a000020012002410110780240024002400240024020030e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a000020012002410110782002200041096a2d00003a0000200120024101107820022000410a6a2d00003a00000b20012002410110780c0a0b200241003a000020012002410110780c090b200241013a000020012002410110782001200041056a412010780c080b200241023a000020012002410110782002200041056a2d00003a000020012002410110780c070b2002410f3a00002001200241011078200041046a2d0000220341024b0d0602400240024020030e03000102000b200241003a000020012002410110782001200041056a412010780c080b200241013a000020012002410110780c070b200241023a00002001200241011078200041086a2802002105200041106a2802002200200110772000450d062005200041d0006c6a2106034020012005412010782002200541206a3602002002200110cf012002200541306a3602002002200110cf01200528024021002005280248220320011077200541d0006a210502402003450d00200341306c210303402001200041106a41201078200220003602002002200110cf01200041306a2100200341506a22030d000b0b20062005470d000c070b0b200241103a00002001200241011078200241003a000020012002410110782001200041106a41101078200041046a28020021032000410c6a28020022052001107720012003200510782002200041206a2d00003a000020012002410110780c050b200241113a00002001200241011078200041086a2d0000220341064b0d04024002400240024002400240024020030e0700010203040506000b200241003a000020012002410110782001200041096a412010780c0a0b200241013a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c090b200241023a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c080b200241033a000020012002410110782001200041096a4120107820022000412c6a28020036020020012002410410780c070b200241043a000020012002410110782001200041096a4120107820022000412c6a28020036020020012002410410780c060b200241053a000020012002410110782001200041096a4120107820022000412c6a28020036020020012002410410780c050b200241063a0000200120024101107820022000410c6a28020036020020012002410410780c040b200241123a00002001200241011078200041086a2d00002203410e4b0d0302400240024002400240024002400240024002400240024002400240024020030e0f000102030405060708090a0b0c0d0e000b200241003a000020012002410110782001200041096a412010780c110b200241013a000020012002410110782001200041096a41201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c100b200241023a000020012002410110782001200041096a41201078200041d0006a29030021042002200041d8006a2903003703082002200437030020012002411010782001200041296a412010780c0f0b200241033a000020012002410110782001200041096a412010780c0e0b200241043a000020012002410110782001200041096a412010780c0d0b200241053a000020012002410110782001200041096a412010780c0c0b200241063a000020012002410110782001200041096a412010782000412c6a2802002103200041346a2802002200200110772000450d0b2000410574210003402001200341201078200341206a2103200041606a22000d000c0c0b0b200241073a000020012002410110782001200041096a412010782002200041296a2d00003a000020012002410110780c0a0b200241083a000020012002410110782001200041096a412010780c090b200241093a000020012002410110782001200041096a412010780c080b2002410a3a000020012002410110782001200041096a412010780c070b2002410b3a000020012002410110782001200041096a412010782001200041296a412010782002200041c9006a2d00003a000020012002410110780c060b2002410c3a000020012002410110782001200041096a412010782002200041296a2d00003a000020012002410110780c050b2002410d3a0000200120024101107820022000410c6a28020036020020012002410410780c040b2002410e3a000020012002410110782001200041096a412010780c030b200241133a0000200120024101107820002d0001220341054b0d02024002400240024002400240024020030e06000102030405000b200241003a00002001200241011078200041026a21000c050b200241013a000020012002410110782001200041026a41201078200041226a21000c040b200241023a000020012002410110782001200041026a412010782001200041226a41201078200041c2006a21000c030b200241033a000020012002410110782001200041026a41201078200041226a21000c020b200241043a000020012002410110782001200041026a41201078200041226a21000c010b200241053a00002001200241011078200041026a21000b20012000412010780c020b200241143a00002001200241011078200041096a21030240200041086a2d00004101460d00200241003a000020012002410110782001200341201078200041306a29030021042002200041386a2903003703082002200437030020012002411010780c020b200241013a0000200120024101107820012003412010780c010b200241153a000020012002410110780240200041046a2802004101460d00200241003a000020012002410110782002200041086a28020036020020012002410410780c010b200241013a000020012002410110782002200041086a280200360200200120024104107820022000410c6a280200360200200120024104107802400240200041106a28020022030d00200241003a000020012002410110780c010b200241013a00002001200241011078200041186a28020022052001107720012003200510780b024020002d001c22034104460d00200241013a000020012002410110780240024002400240024020030e0400010203000b200241003a00000c030b200241013a00000c020b200241023a00000c010b200241033a0000200120024101107820022000411d6a2d00003a0000200120024101107820022000411e6a2d00003a00000b20012002410110780c010b200241003a000020012002410110780b200241106a24000f0b1045000bf70701027f230041106b220224000240024020002d0000220341064b0d00024002400240024002400240024020030e0700010203040506000b200241003a000c20012002410c6a410110782001200041016a412010782002200041c4006a28020036020c20012002410c6a41041078412010332203450d07200341186a200041396a290000370000200341106a200041316a290000370000200341086a200041296a2900003700002003200041216a2900003700002001200341201078200310352002200041c8006a28020036020c20012002410c6a410410780c060b200241013a000c20012002410c6a410110782001200041016a41201078412010332203450d06200341186a200041396a290000370000200341106a200041316a290000370000200341086a200041296a2900003700002003200041216a2900003700002001200341201078200310352002200041c1006a2d00003a000c20012002410c6a410110782002200041c4006a28020036020c20012002410c6a410410782002200041c8006a28020036020c20012002410c6a410410780c050b200241023a000c20012002410c6a41011078412010332203450d0520032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201078200310350c040b200241033a000c20012002410c6a41011078412010332203450d0420032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201078200310350c030b200241043a000c20012002410c6a41011078412010332203450d0320032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201078200310352002200041216a2d00003a000c20012002410c6a410110780c020b200241053a000c20012002410c6a41011078412010332203450d0220032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201078200310352002200041216a2d00003a000c20012002410c6a410110780c010b200241063a000c20012002410c6a41011078412010332203450d0120032000290001370000200341186a200041196a290000370000200341106a200041116a290000370000200341086a200041096a2900003700002001200341201078200310352002200041246a28020036020c20012002410c6a410410782002200041286a28020036020c20012002410c6a410410780b200241106a24000f0b1045000b4d01017f230041206b22002400200041146a410136020020004201370204200041e8d4ca003602002000410436021c2000419cd5ca003602182000200041186a360210200041b0b4cc00104c000bec220a017f017e037f017e037f017e047f017e077f047e230041e0016b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280200417f6a0e0a00010203040506070809000b420021042000420037030820022d000120022d000041004772450d18200041186a41023602000c170b200141086a280200210520012802042101024020022d00000d0020022d000141ff01714101470d002005450d09200110350c090b02402005450d00200110350b20004200370308200041186a41023602000c160b024020022d000120022d0000410047720d00200141086a2903002104410810332201450d0b2001200437000041de92c800ad4280808080a001842001ad42808080808001841002200110350c080b20004200370308200041186a41023602000c150b200141086a280200210520012802042106024020022d000120022d000041004772450d00410221070c140b200341b0016a2001410c6a280200ad22044220862006ad220884102510c20120032802b0012201450d1220032802b40121022003200341b8016a2802003602ac01200320013602a801200341186a200341a8016a10c40120032802180d1120032802ac012209200328021c220a490d11200a417f4c0d0a02400240200a0d0041002109410121070c010b200a10392207450d0a200720032802a801220b200a109d081a20032009200a6b3602ac012003200b200a6a3602a801200a21090b2007450d11200341106a200341a8016a10c401200aad4220862009ad84220ca7210920032802100d0f20032802ac01220a2003280214220b490d0f200b417f4c0d0a02400240200b0d004100210b4101210d0c010b200b1039220d450d0a200d20032802a801220e200b109d081a2003200a200b6b220a3602ac012003200e200b6a3602a8010b200d450d0f02400240024002400240200a4104490d00200320032802a801220e41046a3602a8012003200a417c6a220f3602ac01200f4104490d012003200e41086a3602a801200e28000421102003200a41786a220f3602ac01200f4104490d032003200a41746a3602ac012003200e410c6a3602a801200341086a200341a8016a10c4012003280208450d020c130b0240200b450d00200d10350b20090d140c150b0240200b450d00200d10350b20090d130c140b200328020c220e20032802ac01410c6e220a200a200e4b1bad420c7e2211422088a70d0c2011a7220f417f4c0d0c02400240200f0d00410421120c010b200f10332212450d0c0b4100210a20034100360228200320123602202003200f410c6e36022402400240200e450d000340200341d0016a200341a8016a10ee0220032d00d0014101460d0220032802ac01220f4104490d0220032900d101211120032802a801221328000021142003200f417c6a3602ac012003201341046a3602a8010240200a2003280224470d00200341206a200a4101108701200328022021122003280228210a0b2012200a410c6c6a220f2014360208200f20113702002003200a41016a220a360228200e417f6a220e0d000b0b2012450d112003290224a7210e20032802ac0141044f0d020240200e450d00200e410c6c450d00201210350b0240200b450d00200d10350b2009450d140c130b2003280224220a450d10200a410c6c450d10201210350c100b0240200b450d00200d10350b20090d110c120b200c422088a7210f02402002450d00200110350b41b5c3c700210a410f210241002101200f4104470d0d024020074190e1c600460d00200728000041eede91ab06470d0e0b0240201041f6014f0d00419bc3c700210a411a2102410121010c0e0b02402009450d00200710350b0240200b450d00200d10350b0240200e450d00200e410c6c450d00201210350b41e892c800ad4280808080d0008420044220862008841002200341286a41023a0000200341003a002041b0b4cc004100200341206a10d4012005450d06200610350c060b200141086a280200210520012802042106024020022d000120022d0000410047720d0041e892c800ad4280808080d000842001410c6a3502004220862006ad841002200341206a41086a41023a0000200341003a002041b0b4cc004100200341206a10d4012005450d06200610350c060b02402005450d00200610350b20004200370308200041186a41023602000c130b20022d000120022d0000410047720d0a2001410c6a2802002105200141086a280200210702400240200128020422094101460d0041ed92c800ad4280808080d0018410070c010b410410332201450d0a2001200736000020014104410810372201450d0a2001200536000441ed92c800ad4280808080d001842001ad42808080808001841002200110350b200341206a41186a4200370300200341206a41106a22064200370300200341206a41086a220142003703002003420037032041d1c4c700ad4280808080e000841001220229000021042001200241086a29000037030020032004370320200210354185c5c700ad4280808080e00084100122022900002104200341d0016a41086a220a200241086a290000370300200320043703d00120021035200620032903d0012204370300200341b0016a41086a2001290300370300200341b0016a41106a2004370300200341b0016a41186a200a290300370300200320032903203703b001200341206a200341b0016a10ce0202400240200328022022060d004100210a200341003602d801200342043703d00141042106410021020c010b2003200329022422043702d401200320063602d0012004422088a721022004a7210a0b200341a8016a41026a220b200341a5016a41026a2d00003a0000200341206a41086a220d200341b0016a41086a290200370300200341206a41106a220e200341b0016a41106a280200360200200320032f00a5013b01a801200320032902b00137032002402002200a470d00200341d0016a200a4101108d0120032802d401210a20032802d001210620032802d80121020b2006200241246c220f6a220141043a00002001200536020c2001200736020820012009360204200141036a200b2d00003a0000200120032f01a8013b000120012003290320370210200141186a200d290300370200200141206a200e2802003602002003200241016a22013602d80141d1c4c700ad4280808080e0008410012205290000210420052900082108200510354185c5c700ad4280808080e0008410012205290000210c2005290008211120051035200320113701382003200c3701302003200837012820032004370120200341203602ac012003200341206a3602a80120062001200341a8016a109606024020012002490d00200f41246a21022006210103400240024020012d0000220541044b0d0002400240024020050e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012002415c6a22020d000b0b200a450d04200a41246c450d04200610350c040b2001410c6a2802002105200141086a28020021062001280204210a024020022d000120022d0000410047720d000240200541186c2201450d00200a20016a2102200a21010340200141086a350200422086200135020084200141146a3502004220862001410c6a350200841002200141186a22012002470d000b0b02402005450d00200541186c2102200a210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141186a2101200241686a22020d000b0b2006450d04200641186c450d04200a10350c040b02402005450d00200541186c2102200a210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141186a2101200241686a22020d000b0b02402006450d00200641186c450d00200a10350b20004200370308200041186a41023602000c110b2001410c6a2802002105200141086a28020021062001280204210a024020022d000120022d0000410047720d0002402005410c6c2201450d00200a20016a2102200a21010340200141086a35020042208620013502008410072001410c6a22012002470d000b0b02402005450d002005410c6c2102200a210103400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b2006450d032006410c6c450d03200a10350c030b02402005450d002005410c6c2102200a210103400240200141046a280200450d00200128020010350b2001410c6a2101200241746a22020d000b0b02402006450d002006410c6c450d00200a10350b20004200370308200041186a41023602000c100b200141086a280200210520012802042106024020022d000120022d0000410047720d002001410c6a3502004220862006ad8410082005450d02200610350c020b02402005450d00200610350b20004200370308200041186a41023602000c0f0b4102210120022d00000d014101210520022d00014101470d012002411a6a2901002104200241196a2d00002101200241186a2d00002106200241166a2f0100210a200241156a2d00002107200241146a2d00002109200241126a2f0100210b200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021132002410c6a2d000021142002410a6a2f01002112200241086a2d00002110200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a0027200320103a0026200320153b0124200320163a0023200320173a0022200320183b01202003200d3a002f2003200e3a002e2003200f3b012c200320133a002b200320143a002a200320123b0128200320013a0037200320063a00362003200a3b0134200320073a0033200320093a00322003200b3b013020032004370138200341b0016a41186a2004370300200341b0016a41106a2003290130370300200341b8016a2003290128370300200320032901203703b001200341d0016a200341b0016a108e02200341206a20032802d001220120032802d801108f0242002104420021084200210c42002111420021194200211a4200211b4200211c024020032903204201520d0020032d006c452105200341206a41106a290300211c200341c0006a2903002108200341206a41186a2903002104200341d0006a2903002111200341c8006a290300210c200341e0006a290300211a200341d8006a29030021192003290328211b0b024020032802d401450d00200110350b024020050d0041dcc2c7002102410f2105418080102106410321010c030b0240200c200484201984201b842011200884201a84201c8484500d0041ebc2c7002102411321054180800c2106410321010c030b200341206a41186a200341b0016a41186a290300370300200341206a41106a200341b0016a41106a290300370300200341206a41086a200341b0016a41086a290300370300200320032903b001370320200341d0016a200341206a10ed0320033502d80142208620032802d0012201ad84100720032802d401450d00200110350b42002104200042003703080c0e0b410021060b20004200370308200041206a20053602002000411c6a2002360200200041186a20064180801c712001723602000c0b0b1045000b1044000b103c000b20004200370308200041186a41023602000c070b02402009450d00200710350b0240200b450d00200d10350b41032107200e450d05200e410c6c450d05201210350c050b200b450d00200d10350b2009450d010b200710350b2002450d00200110350b4103210741fec2c700210a411d2102410221010b200141ff0171411074210102402005450d00200610350b20004200370308200041206a20023602002000411c6a200a360200200041186a20012007723602000b420121040b20002004370300200341e0016a24000b971f03077f037e127f230041a0036b22042400200128020821052001280204210620012802002107410221080240024002400240024002400240200241ff01710d00200341ff01714102470d002005410a4b0d0120044188016a41186a2209420037030020044188016a41106a220a420037030020044188016a41086a2202420037030020044200370388014193d1cb00ad4280808080a00184220b10012203290000210c20044180036a41086a2201200341086a2900003703002004200c370380032003103520022001290300370300200420042903800337038801419dd1cb00ad4280808080c00184220d10012203290000210c2001200341086a2900003703002004200c3703800320031035200a200429038003220c370300200441206a41086a220e2002290300370300200441206a41106a220f200c370300200441206a41186a221020012903003703002004200429038801370320200441206a10bd02220341ff01714102460d02410321082003410171450d020b419fc8ca0021114110210f410121122005450d030c020b4192c8ca002111410d210f41032108410221120c010b20094200370300200a4200370300200242003703002004420037038801200b10012203290000210c2001200341086a2900003703002004200c370380032003103520022001290300370300200420042903800337038801200d10012203290000210c2001200341086a2900003703002004200c3703800320031035200a200429038003370000200a41086a2001290300370000200e2002290300370300200f200a290300370300201020092903003703002004200429038801370320200441013a008801200441206aad4280808080800484220d20044188016aad42808080801084100220044180036a41186a2208420037030020044180036a41106a2213420037030020014200370300200442003703800341d1c4c700ad4280808080e0008410012202290000210c2001200241086a2900003703002004200c370380032002103541e7c4c700ad4280808080e0008410012203290000210c200441f0026a41086a2202200341086a2900003703002004200c3703f00220031035201320042903f002220c370300200441d0026a41086a22092001290300370300200441d0026a41106a220e200c370300200441d0026a41186a220f200229030037030020042004290380033703d002200441086a200441d0026a412010c001200428020c2110200428020821142008420037030020134200370300200142003703002004420037038003200b10012203290000210b2001200341086a2900003703002004200b370380032003103541e0caca00ad4280808080e0008410012203290000210b2002200341086a2900003703002004200b3703f00220031035201320042903f002220b37030020092001290300370300200e200b370300200f200229030037030020042004290380033703d00220044188016a200441d0026a10b6020240024020042802880122150d0020044100360218200442043703104104211541002102410021010c010b2004200429028c01220b37021420042015360210200b422088a72102200ba721010b2010410020141b2103024020022001470d00200441106a20024101109f0120042802102115200428021821020b2015200241c4006c6a220141003a000020012003360204200141036a200441206a41026a2d00003a0000200120042f00203b00012001200429028801370208200141106a20044188016a41086a2216290200370200200141186a20044188016a41106a2217290200370200200141206a20044188016a41186a290200370200200141286a20044188016a41206a290200370200200141306a20044188016a41286a290200370200200141386a20044188016a41306a290200370200200141c0006a20044188016a41386a2802003602002004200241016a22183602182007200541f0006c22016a211902400240024020050d00200721080c010b200741f4006a2109200141907f6a210e41d1c4c700ad4280808080e00084210c20072108024003402008280204211a2008280200210320044188016a200841086a41e800109d081a200841f0006a2108201a450d02200441206a20044188016a41e800109d081a2004201a36028c0120042003360288012016200441206a41e800109d081a20044180036a41186a221b420037030020044180036a41106a221c420037030020044180036a41086a221042003703002004420037038003200c10012201290000210b2010200141086a2900003703002004200b370380032001103541e7c4c700ad4280808080e0008410012201290000210b200441f0026a41086a2202200141086a2900003703002004200b3703f00220011035201320042903f002370000201341086a2002290300370000200441d0026a41086a221d2010290300370300200441d0026a41106a221e201c290300370300200441d0026a41186a221f201b29030037030020042004290380033703d0022004200441d0026a412010c0012004280200210120042802042102200441d0026a20044188016a10d003410c210f024020030d00410321124186c8ca0021110c020b024020032002410020011b22014d0d004104211241fac7ca0021110c020b20044180036a2003417f6a10d103024020044180036a2017412010a008450d004100211241afc8ca0021114112210f0c020b0240200341002001417b6a2202200220014b1b4f0d004106211241dec7ca0021114108210f0c020b0240024020152015201841c4006c22026a460d00201541016a2101034002402001417f6a2d00004101470d0041012114200441d0026a2001460d032001200441d0026a412010a008450d030b200141c4006a2101200241bc7f6a22020d000b0b410021140b20044180036a200310d10320044180036a200441d0026a412010a00821014105211241e6c7ca0021114114210f20140d012001450d01200441f8016a41086a220f200441b0026a41086a2202290200370300200441f8016a41106a2214200441b0026a41106a22032f01003b0100200420042f018e023b018c02200420042902b0023703f80120044190026a20044188016a10d003200441b0026a41186a221142003703002003420037030020024200370300200442003703b002201f4200370300201e4200370300201d4200370300200442003703d002024041c80010332201450d0020044180036a10d004200141186a201b290300370200200141106a201c290300370200200141086a201029030037020020012004290380033702002001410236022020014101360244200120042903d0023700242001412c6a201d290300370000200141346a201e2903003700002001413c6a201f290300370000200420013602f00220044282808080203702f402200441f0026a10ab01201b2011290300370300201c200329030037030020102002290300370300200420042903b0023703800320044180036a10d304201020044190026a41086a290300370300201c20044190026a41106a290300370300201b20044190026a41186a290300370300201d200f290300370300201e20142f01003b0100200420042903900237038003200420042f018c023b01b002200420042903f8013703d002024020182004280214470d00200441106a20184101109f01200428021821180b20042802102215201841c4006c6a220141013a00002001200429038003370001200141003a0021200120042f01b0023b0022200120042903d002370030200141096a2010290300370000200141116a201c290300370000200141196a201b290300370000200141386a201d290300370000200141c0006a201e2f01003b00002004201841016a221836021802402004280294012201450d00200141246c2102201a210103400240024020012d0000220341044b0d0002400240024020030e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012002415c6a22020d000b0b02402004280290012201450d00200141246c450d00201a10350b200e41907f6a210e200941f0006a210920082019470d010c040b0b103c000b02402004280294012201450d00200141246c2102201a210103400240024020012d0000220341044b0d0002400240024020030e050400010204040b2001410c6a280200450d03200141086a28020010350c030b2001410c6a280200450d02200141086a28020010350c020b2001410c6a280200450d01200141086a28020010350c010b200141086a280200450d00200141046a28020010350b200141246a21012002415c6a22020d000b0b02402004280290012201450d00200141246c450d00201a10350b024020192008460d000340200910b1030240200941046a2802002201450d00200141246c450d00200928020010350b200941f0006a2109200e41907f6a220e0d000b0b02402006450d00200641f0006c450d00200710350b024020042802142201450d00200141c4006c450d00201510350b410321080c040b20192008460d002007200541f0006c6a210303402008220141046a220210b103200141f0006a21080240200141086a2802002201450d00200141246c450d00200228020010350b20032008470d000b0b02402006450d00200641f0006c450d00200710350b20044188016a41186a2208420037030020044188016a41106a2209420037030020044188016a41086a2202420037030020044200370388014193d1cb00ad4280808080a0018410012203290000210b20044180036a41086a2201200341086a2900003703002004200b37038003200310352002200129030037030020042004290380033703880141e0caca00ad4280808080e0008410012203290000210b2001200341086a2900003703002004200b3703800320031035200a200429038003370000200a41086a2001290300370000200441206a41086a2002290300370300200441206a41106a2009290300370300200441206a41186a2008290300370300200420042903880137032020044188016a2015201810e006200d2004350290014220862004280288012201ad8410020240200428028c01450d00200110350b024020042802142201450d00200141c4006c450d00201510350b4200210b0c030b200541f0006c2102200741046a21010340200110b1030240200141046a2802002203450d00200341246c450d00200128020010350b200141f0006a2101200241907f6a22020d000b0b2006450d00200641f0006c450d00200710350b200041206a200f3602002000411c6a2011360200200041186a2012411074200872418008723602004201210b0b2000200b37030020004200370308200441a0036a24000be81c041c7f017e067f017e230041e0066b220324000240024002400240024002400240024002400240024020012802002204450d0020032001410c6a418001109d0821052001280204210602400240024020022d00000d0020022d00014101460d010b02402006450d00200410350b41022105410021020c010b200241196a2d00002101200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720052002411a6a29010037039801200520013a009701200520073a009601200520083b019401200520093a0093012005200a3a0092012005200b3b0190012005200c3a008f012005200d3a008e012005200e3b018c012005200f3a008b01200520103a008a01200520113b018801200520123a008701200520133a008601200520143b018401200520153a008301200520163a008201200520173b018001200541a0016a2005418001109d081a200541c0036a41186a200529039801370300200541c0036a41106a200529039001370300200541c8036a20052903880137030020052005290380013703c003200541d8056a200541c0036a10fc010240024020052d00d8054101470d00200541ef046a2202200541f1056a290000370000200541d8046a41106a2201200541ea056a290100370300200541a9026a200541e2056a290100370000200541b1026a2001290300370000200541a0026a41186a2002290000370000200520052d00d9053a00a002200520052901da053700a102200541c0026a200541a0016a418001109d081a200541c8046a200541a0026a10dd06200541d8056a20052802c804220120052802d00410c10220052d00d8052102200541d8046a200541d8056a410172418001109d081a0240024020024101460d00200541003a00c0030c010b200541013a00c003200541c0036a410172200541d8046a418001109d081a0b024020052802cc04450d00200110350b200541c0026a41206a211820054180036a2119200541a0036a211a200541e1036a211b20054181046a211c200541a1046a211d200541c0036a410172211e4170210803404100210141b0b4cc0021070240024002400240200841c4e2c6006a280000220241e6e485f3064a220b0d00200241e2c289ab06460d01200241e1ea91cb06470d0341202101201a21070c030b200241e9dabdf306460d01200241e7e485f306470d0241202101200541c0026a21070c020b41202101201821070c010b41202101201921070b200520013602e005200520073602dc05200520023602d805200541d8046a200541d8056a10f706200541d8056a20052802d804220a20052802e00410d50120052802dc0421090240024020052d00d8054101470d0020052900f105211f20052d00f005210c20052d00ef05210d20052f00ed05210e20052d00ec05210f20052d00eb05211020052f00e905211120052d00e805211220052d00e705211320052f00e505211420052d00e405211520052d00e305211620052f00e105211720052d00e005212020052d00df05212120052f00dd05212220052d00dc05212320052d00db05212420052f00d905212502402009450d00200a10350b2005201f3703f0052005200c3a00ef052005200d3a00ee052005200e3b01ec052005200f3a00eb05200520103a00ea05200520113b01e805200520123a00e705200520133a00e605200520143b01e405200520153a00e305200520163a00e205200520173b01e005200520203a00df05200520213a00de05200520223b01dc05200520233a00db05200520243a00da05200520253b01d805200541d8056a200541a0026a412010a008450d0141b193ca00ad211f4280808080d00121264180800821050c040b2009450d00200a10350b0240024020052d00c0034101470d004100210941b0b4cc00210a0240024002400240200b0d00200241e2c289ab06460d01200241e1ea91cb06470d0341202109201d210a0c030b200241e9dabdf306460d01200241e7e485f306470d0241202109201e210a0c020b41202109201b210a0c010b41202109201c210a0b024020012009470d002007200a460d022007200a200110a008450d020b200520093602e0052005200a3602dc05200520023602d805200541d8046a200541d8056a10f70620053502e00442208620052802d8042209ad84100720052802dc04450d00200910350b200520013602e005200520073602dc05200520023602d805200541d8046a200541d8056a10f70620052802d804210120053502e004211f412010332202450d0e200220052903a002370000200241186a200541a0026a41186a290300370000200241106a200541a0026a41106a290300370000200241086a200541a0026a41086a290300370000201f4220862001ad842002ad428080808080048410022002103520052802dc04450d00200110350b200841046a22080d000b200541d8056a200541a0026a10dd0620053502e005211f20052802d8052101412010332202450d0d200220052903c002370000200241186a200541c0026a41186a290300370000200241106a200541c0026a41106a290300370000200241086a200541c0026a41086a2903003700002002412041c00010372202450d0d200220052903e002370020200241386a200541c0026a41386a290300370000200241306a200541c0026a41306a290300370000200241286a200541c0026a41286a290300370000200241c00041800110372202450d0d2002200529038003370040200241d8006a200541c0026a41d8006a290300370000200241d0006a200541c0026a41d0006a290300370000200241c8006a200541c0026a41c8006a290300370000200220052903a003370060200241e8006a200541c0026a41e8006a290300370000200241f0006a200541c0026a41f0006a290300370000200241f8006a200541c0026a41f8006a290300370000201f4220862001ad842002ad4280808080801084100220021035024020052802dc05450d00200110350b024020052d00c0030d0020054180016a108d020b2006450d04200410350c040b41be93ca00ad211f4280808080f00221264180800421050b201f42ffffffff0f83211f20054180800c71210502402006450d00200410350b2026201f84211f2005418012722102410321050b200042003703082000411c6a201f370200200041186a20022005723602000c070b4102210520022d00000d0420022d00014101470d042002411a6a290100211f200241196a2d00002105200241186a2d00002101200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d000021042002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f010021142003200241096a2d00003a0007200320103a0006200320113b0104200320123a0003200320133a0002200320143b01002003200b3a000f200320043a000e2003200c3b010c2003200d3a000b2003200e3a000a2003200f3b0108200320053a0017200320013a0016200320073b0114200320083a0013200320093a00122003200a3b01102003201f370318200341c0036a41186a201f370300200341c0036a41106a2003290310370300200341c8036a2003290308370300200320032903003703c003200341d8056a200341c0036a10fc0120032d00d8054101470d02200341ef046a2205200341f1056a290000370000200341d8046a41106a2202200341ea056a290100370300200341a9016a200341e2056a290100370000200341b1016a2002290300370000200341a0016a41186a2005290000370000200320032d00d9053a00a001200320032901da053700a101200341a0026a200341a0016a10dd06200341d8056a20032802a002220520032802a802220110c102024020032d00d8052202450d002001ad4220862005ad8410070b20032d00d9052101200341d8046a200341d8056a41027241ff00109d081a200341d8056a200341d8046a41ff00109d081a20024101470d01200341c0026a200341d8056a41ff00109d081a024020032802a402450d00200510350b200320013a00c003200341c0036a410172200341c0026a41ff00109d081a200341e0056a4120360200200341e7e485f3063602d8052003200341c0036a3602dc05200341d8046a200341d8056a10f70620033502e00442208620032802d8042205ad841007024020032802dc04450d00200510350b200341e2c289ab063602d805200341203602e0052003200341c0036a41206a3602dc05200341d8046a200341d8056a10f70620033502e00442208620032802d8042205ad841007024020032802dc04450d00200510350b200341203602e005200320034180046a3602dc05200341e9dabdf3063602d805200341d8046a200341d8056a10f70620033502e00442208620032802d8042205ad841007024020032802dc04450d00200510350b200341203602e0052003200341a0046a3602dc05200341e1ea91cb063602d805200341d8046a200341d8056a10f70620033502e00442208620032802d8042205ad841007024020032802dc04450d00200510350b20031099020b4200211f200042003703080c060b024020032802a402450d00200510350b4180920c21024280808080e000211f41ab93ca0021050c010b4180920421024280808080f002211f41be93ca0021050b201f2005ad84211f410321050c010b410021020b200042003703082000411c6a201f370200200041186a20022005723602000b4201211f0b2000201f370300200341e0066a24000f0b1045000b103c000bf75d06067f017e027f017e0d7f047e230041a0046b2203240002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341e4016a4101360200200342013702d401200341e8d4ca003602d001200341043602ac012003419cd5ca003602a8012003200341a8016a3602e001200341d0016a41b0b4cc00104c000b2001412c6a2802002104200141286a2802002105200141246a280200210620012d00012107200341e0006a41186a2001411a6a290000370300200341e0006a41106a200141126a290000370300200341e0006a41086a2001410a6a2900003703002003200141026a290000370360024020022d000120022d0000410047720d002006200410ac06200341d0016a41186a4200370300200341d0016a41106a22024200370300200341d0016a41086a22014200370300200342003703d00141dad5ca00ad4280808080b002841001220829000021092001200841086a290000370300200320093703d001200810354189eaca00ad4280808080f00084100122082900002109200341306a41086a220a200841086a290000370300200320093703302008103520022003290330220937030020034180016a41086a200129030037030020034180016a41106a200937030020034180016a41186a200a290300370300200320032903d00137038001200341d0016a20034180016a10fe01200341d0016a2006200420032802d0012201410120011b220820032902d401420020011b2209422088a710a6022002280200210220032802d401210120032802d001210a20032802dc01220b200341e4016a2802002006200410a7020240200241ffffff3f71450d00200b10350b0240200141ffffff3f71450d00200a10350b20034180046a41186a2202200341e0006a41186a29030037030020034180046a41106a2201200341e0006a41106a29030037030020034180046a41086a2204200341e0006a41086a290300370300200320032903603703800402400240200741ff01710d0020034180016a41186a420037030020034180016a41106a2207420037030020034180016a41086a22014200370300200342003703800141dad5ca00ad4280808080b0028410012204290000210c200341d0006a41086a2202200441086a2900003703002003200c37035020041035200120022903003703002003200329035037038001419cdfca00ad4280808080d0008410012204290000210c2002200441086a2900003703002003200c3703502004103520072003290350220c370300200341a8016a41086a2001290300370300200341a8016a41106a200c370300200341a8016a41186a200229030037030020032003290380013703a801200341a8016aad428080808080048410070c010b200341a8016a41186a2002290300370300200341a8016a41106a2001290300370300200341a8016a41086a200429030037030020032003290380043703a801200341306a41186a4200370300200341306a41106a22074200370300200341306a41086a220242003703002003420037033041dad5ca00ad4280808080b0028410012201290000210c200341d0016a41086a2204200141086a2900003703002003200c3703d0012001103520022004290300370300200320032903d001370330419cdfca00ad4280808080d0008410012201290000210c20034180016a41086a220a200141086a2900003703002003200c37038001200110352007200329038001220c37030020042002290300370300200341d0016a41106a200c370300200341d0016a41186a200a290300370300200320032903303703d001412010332202450d06200220032903a801370000200241186a200341a8016a41186a290300370000200241106a200341a8016a41106a290300370000200241086a200341a8016a41086a290300370000200341d0016aad42808080808004842002ad42808080808004841002200210350b0240200942ffffff3f83500d00200810350b200541ffffff3f71450d0f200610350c0f0b0240200541ffffff3f71450d00200610350b20004200370308200041186a4102360200420121090c0f0b200141046a280200210520032002411a6a290100370398012003200241026a2901003703800120032002410a6a290100370388012003200241126a290100370390010240024020022d00014101470d0020022d000041ff01710d00200341e0006a41186a20034180016a41186a2206290300370300200341e0006a41106a20034180016a41106a2204290300370300200341e0006a41086a20034180016a41086a22072903003703002003200329038001370360200341d0016a41186a4200370300200341d0016a41106a22084200370300200341d0016a41086a22024200370300200342003703d00141dad5ca00ad4280808080b002841001220129000021092002200141086a290000370300200320093703d001200110354189eaca00ad4280808080f00084100122012900002109200341306a41086a220a200141086a290000370300200320093703302001103520082003290330220937030020072002290300370300200420093703002006200a290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b2209422088a741057421012002410120021b2207210202400340024020010d00410021040c020b41012104200341e0006a2002460d01200141606a21012002200341e0006a412010a0082106200241206a210220060d000b0b0240200942ffffff3f83500d00200710350b41831621022004450d01200341003602d801200342013703d0012005200341d0016a10af0320032802d401210120034180046a41186a220620033502d80142208620032802d0012208ad841009220241186a29000037030020034180046a41106a2204200241106a29000037030020034180046a41086a2207200241086a29000037030020032002290000370380042002103502402001450d00200810350b200341d0016a200541b002109d081a200341a8016a410d6a200341e0006a41086a290300370000200341a8016a41156a200341e0006a41106a290300370000200341a8016a411d6a200341e0006a41186a290300370000200341013a00ac01200320032903603700ad01200341013a00a80120034180016a200341d0016a200341a8016a10ac032003290380012109200341d0016a410d6a2007290300370000200341d0016a41156a2004290300370000200341d0016a411d6a2006290300370000200341f5016a2009503a0000200341053a00d401200341073a00d00120032003290380043700d50141b0b4cc004100200341d0016a10d401200510350c0f0b41821621020b200510ba0220051035200041206a41093602002000411c6a41f2dfca00360200200041186a200236020020004200370308420121090c0e0b200141086a2802002105200141046a280200210d2002411a6a2901002109200241196a2d00002106200241186a2d00002104200241166a2f01002107200241156a2d00002108200241146a2d0000210a200241126a2f0100210b200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211941012101024020022d00000d0020022d000141014721010b200320093703c001200320063a00bf01200320043a00be01200320073b01bc01200320083a00bb012003200a3a00ba012003200b3b01b8012003200e3a00b7012003200f3a00b601200320103b01b401200320113a00b301200320123a00b201200320133b01b001200320143a00af01200320153a00ae01200320163b01ac01200320173a00ab01200320183a00aa01200320193b01a801024020010d00200341e0006a41186a200341a8016a41186a290300370300200341e0006a41106a200341a8016a41106a290300370300200341e0006a41086a200341a8016a41086a290300370300200320032903a801370360200341d0016a41186a4200370300200341d0016a41106a22074200370300200341d0016a41086a22024200370300200342003703d00141dad5ca00ad4280808080b002841001220129000021092002200141086a290000370300200320093703d001200110354189eaca00ad4280808080f00084100122012900002109200341306a41086a2206200141086a290000370300200320093703302001103520072003290330220937030020034180016a41086a200229030037030020034180016a41106a200937030020034180016a41186a2006290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b2209422088a741057421012002410120021b2208210202400340024020010d00410021040c020b41012104200341e0006a2002460d01200141606a21012002200341e0006a412010a0082106200241206a210220060d000b0b0240200942ffffff3f83500d00200810350b41032102024020040d0041f2dfca0021014109210641801621040c0c0b200341003602d801200342013703d0012005200341d0016a10af0320032802d401210620034180046a41186a220420033502d80142208620032802d001220bad841009220141186a29000037030020034180046a41106a2208200141106a29000037030020034180046a41086a220a200141086a29000037030020032001290000370380042001103502402006450d00200b10350b200341d0016a41186a2004290300370300200341d0016a41106a2008290300370300200341d0016a41086a200a29030037030020032003290380043703d001200341a8016a200341d0016a109907200341206a20032802a801220620032802b00141b0b4cc0041004100108a0220032802202101024020032802ac01450d00200610350b20014101460d040240200d4102490d0020034180016a41186a2208420037030020034180016a41106a2206420037030020034180016a41086a22014200370300200342003703800141dad5ca00ad4280808080b00284220910012204290000210c200341d0006a41086a2202200441086a2900003703002003200c37035020041035200120022903003703002003200329035037038001418ef0cb00ad4280808080d00184220c10012204290000211a2002200441086a2900003703002003201a3703502004103520062003290350221a370300200341306a41086a22042001290300370300200341306a41106a220a201a370300200341306a41186a220b20022903003703002003200329038001370330200341186a200341306a412010c001200328021c210f20032802182110200842003703002006420037030020014200370300200342003703800120091001220e290000211a2002200e41086a2900003703002003201a370350200e1035200120022903003703002003200329035037038001200c1001220e290000211a2002200e41086a2900003703002003201a370350200e103520062003290350221a37030020042001290300370300200a201a370300200b20022903003703002003200329038001370330200341106a200341306a412010c0012003280210211120032802142112200842003703002006420037030020014200370300200342003703800120091001220e290000211a2002200e41086a2900003703002003201a370350200e1035200120022903003703002003200329035037038001200c1001220e290000210c2002200e41086a2900003703002003200c370350200e103520062003290350220c37030020042001290300370300200a200c370300200b20022903003703002003200329038001370330410121022003201241016a410120111b3602d001200341306aad4280808080800484200341d0016aad4280808080c000841002200341d0016a41186a220e4200370300200341d0016a41106a22114200370300200341d0016a41086a220a4200370300200342003703d00120091001220b2900002109200a200b41086a290000370300200320093703d001200b10354180eaca00ad42808080809001841001220b29000021092004200b41086a29000037030020032009370330200b103520072003290330370000200741086a20042903003700002001200a290300370300200620112903003703002008200e290300370300200320032903d00137038001200341d0016a20034180016a412010b5020240024020032802d00122010d00200341003602b001200342013703a8014100210a410021060c010b200320032902d40122093702ac01200320013602a8012009422088a721062009a7210a200121020b200341306a41186a220b20034180046a41186a290300370300200341306a41106a220420034180046a41106a290300370300200341306a41086a220120034180046a41086a290300370300200320032903800437033002402006200a470d00200341a8016a200a4101108a0120032802ac01210a20032802a801210220032802b00121060b200220064105746a22082003290330370000200841186a200b290300370000200841106a2004290300370000200841086a20012903003700002003200641016a220e3602b001200b420037030020044200370300200142003703002003420037033041dad5ca00ad4280808080b00284100122082900002109200341d0006a41086a2206200841086a290000370300200320093703502008103520012006290300370300200320032903503703304180eaca00ad42808080809001841001220829000021092006200841086a290000370300200320093703502008103520042003290350220937030020034180016a41086a200129030037030020034180016a41106a200937030020034180016a41186a200629030037030020032003290330370380010240024020020d0020034180016aad428080808080048410070c010b200341203602d401200320034180016a3602d0012002200e200341d0016a10c504200a41ffffff3f71450d00200210350b200341d0016a200541b002109d081a200341a8016a41186a20034180046a41186a290300370300200341a8016a41106a20034180046a41106a290300370300200341a8016a41086a20034180046a41086a29030037030020032003290380043703a80120034180016a200341a8016a10990720032802800121022003350288012109200341003602b001200342013703a801200341d0016a200341a8016a10af0320032802ac01210120094220862002ad8420033502b00142208620032802a8012206ad84100202402001450d00200610350b0240200328028401450d00200210350b200341d0016a10ba02200341d0016a41186a22064200370300200341d0016a41106a22044200370300200341d0016a41086a22024200370300200342003703d00141d1c4c700ad4280808080e000841001220129000021092002200141086a290000370300200320093703d0012001103541e7c4c700ad4280808080e00084100122012900002109200341306a41086a2208200141086a290000370300200320093703302001103520072003290330370000200741086a200829030037000020034180016a41086a200229030037030020034180016a41106a200429030037030020034180016a41186a2006290300370300200320032903d00137038001200341086a20034180016a412010c001200328020c210120032802082106412010332202450d0620022003290360370000200241186a200341e0006a41186a290300370000200241106a200341e0006a41106a290300370000200241086a200341e0006a41086a290300370000200341ec016a4100360200200341dc016a428180808010370200200320014180e5086a4180e50820061b3602f001200342013702e401200320023602d8012003200d3602d4012003200f410020101b22063602d001200341a8016a41186a20034180046a41186a290300370300200341a8016a41106a20034180046a41106a290300370300200341a8016a41086a20034180046a41086a29030037030020032003290380043703a80120034180016a200341a8016a108c07200328028001210120032003280288013602ac01200320013602a801200341d0016a200341a8016a1092070240200328028401450d00200110350b20021035200341dd016a200341e0006a41086a290300370000200341e5016a200341e0006a41106a290300370000200341ed016a200341e0006a41186a290300370000200341f5016a200329038004370000200341fd016a20034180046a41086a29030037000020034185026a20034180046a41106a2903003700002003418d026a20034180046a41186a2903003700002003419c026a200d36020020034198026a2006360200200341003a00d401200341073a00d001200320032903603700d501200341d0016a21020c0d0b200341d0016a41186a22064200370300200341d0016a41106a22044200370300200341d0016a41086a22024200370300200342003703d00141dad5ca00ad4280808080b002841001220129000021092002200141086a290000370300200320093703d001200110354189eaca00ad4280808080f00084100122012900002109200341306a41086a2208200141086a290000370300200320093703302001103520072003290330370000200741086a200829030037000020034180016a41086a200229030037030020034180016a41106a200429030037030020034180016a41186a2006290300370300200320032903d00137038001200341a8016a20034180016a10fe010240024020032802a80122010d00410021020c010b20032902ac012209422088a72102200942ffffff3f83500d00200110350b200341d0016a200541b002109d081a200341b4016a2002360200200341a8016a41086a4101360200200341003a00ac01200341013a00a80120034180016a200341d0016a200341a8016a10ac032003290380012109200341dd016a20034180046a41086a290300370000200341e5016a20034190046a290300370000200341ed016a20034198046a290300370000200341f5016a2009503a0000200341043a00d401200341073a00d00120032003290380043700d501200341d0016a21020c0c0b4102210241801621040c0a0b200141216a2d0000210d200141246a2802002119200341e0006a41186a200141196a290000370300200341e0006a41106a200141116a290000370300200341e0006a41086a200141096a290000370300200320012900013703602002411a6a2901002109200241196a2d00002106200241186a2d00002104200241166a2f01002105200241156a2d00002107200241146a2d00002108200241126a2f0100210a200241116a2d0000210b200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211841012101024020022d00000d0020022d000141014721010b200320093703c001200320063a00bf01200320043a00be01200320053b01bc01200320073a00bb01200320083a00ba012003200a3b01b8012003200b3a00b7012003200e3a00b6012003200f3b01b401200320103a00b301200320113a00b201200320123b01b001200320133a00af01200320143a00ae01200320153b01ac01200320163a00ab01200320173a00aa01200320183b01a801024020010d0020034180046a41186a200341a8016a41186a29030037030020034180046a41106a200341a8016a41106a29030037030020034180046a41086a200341a8016a41086a290300370300200320032903a80137038004200341d0016a41186a4200370300200341d0016a41106a22054200370300200341d0016a41086a22024200370300200342003703d00141dad5ca00ad4280808080b002841001220129000021092002200141086a290000370300200320093703d001200110354189eaca00ad4280808080f00084100122012900002109200341306a41086a2206200141086a290000370300200320093703302001103520052003290330220937030020034180016a41086a200229030037030020034180016a41106a200937030020034180016a41186a2006290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b2209422088a741057421012002410120021b2207210202400340024020010d00410021040c020b4101210420034180046a2002460d01200141606a2101200220034180046a412010a0082106200241206a210220060d000b0b0240200942ffffff3f83500d00200710350b41032102024020040d004100210141f2dfca002106410921040c0a0b20034180016a200341e0006a109a07200341d0016a200328028001220620032802880110de0220032802840121010240024020032802d8012208450d00200341f0016a2802002102200341ec016a280200210b200341e8016a2802002110200341e4016a280200210f200341e0016a280200210a20032802dc01210e20032903d001210902402001450d00200610350b200341c4016a200b360200200341c0016a2010360200200341b8016a200a360200200341b4016a200e360200200320023602c8012003200f3602bc01200320083602b001200320093703a80120192009a7460d0141c8dfca002106410a21044180800c21010c0a0b02402001450d00200610350b41808008210141d2dfca002106410f21040c0a0b4100210141002106410021110240200a450d00200a410574210441002106200821020240034020034180046a2002460d012006200220034180046a412010a00822074100476a21062007450d01200241206a2102200441606a22040d000b410021110c010b410121110b410021020240200b450d00200b410574210441002101200f21020240034020034180046a2002460d012001200220034180046a412010a00822074100476a21012007450d01200241206a2102200441606a22040d000b410021020c010b410121020b024002400240200d41ff01710d002002450d010c0a0b20110d09200341306a41186a220420034180046a41186a290300370300200341306a41106a220720034180046a41106a290300370300200341306a41086a220b20034180046a41086a29030037030020032003290380043703300240200a200e470d00200341b0016a200e4101108a0120032802b801210a20032802b00121080b2008200a4105746a22062003290330370000200641186a2004290300370000200641106a2007290300370000200641086a200b2903003700002003200a41016a22073602b80120032802c40121042002450d01200420014d0d0720032802bc0122062004417f6a22044105746a220229000021092002290008210c2002290010211a200241186a290000211b200320043602c401200620014105746a220241186a201b3700002002201a3700102002200c370008200220093700000c010b20034180016a41186a220120034180046a41186a29030037030020034180016a41106a220420034180046a41106a29030037030020034180016a41086a220720034180046a41086a2903003703002003200329038004370380010240200b2010470d00200341bc016a20104101108a0120032802c401210b20032802bc01210f0b200f200b4105746a2202200329038001370000200241186a2001290300370000200241106a2004290300370000200241086a2007290300370000200320032802c40141016a22043602c40120032802b80121072011450d00200720064d0d0720032802b00122012007417f6a22074105746a220229000021092002290008210c2002290010211a200241186a290000211b200320073602b801200120064105746a220241186a201b3700002002201a3700102002200c370008200220093700000b200341f5016a2003290360370000200341dd016a20034180046a41086a290300370000200341e5016a20034180046a41106a290300370000200341ed016a20034180046a41186a290300370000200341fd016a200341e0006a41086a29030037000020034185026a200341e0006a41106a2903003700002003418d026a200341e0006a41186a290300370000200341013a00d401200341073a00d00120032003290380043700d5012003419c026a200436020020034198026a200736020020034195026a200d3a00004100210241b0b4cc004100200341d0016a10d401200341d0016a41186a22084200370300200341d0016a41106a220a4200370300200341d0016a41086a22014200370300200342003703d00141dad5ca00ad4280808080b002841001220629000021092001200641086a290000370300200320093703d001200610354189eaca00ad4280808080f00084100122062900002109200341306a41086a220b200641086a290000370300200320093703302006103520052003290330370000200541086a200b29030037000020034180016a41086a200129030037030020034180016a41106a200a29030037030020034180016a41186a2008290300370300200320032903d00137038001200341d0006a20034180016a10fe01024020032802502201450d0020032902542209422088a72102200942ffffff3f83500d00200110350b0240200720032802ac0122014f22060d004100200220046b2204200420024b1b2001490d00200341d0016a41206a200341a8016a41206a280200360200200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d00120034180016a200341e0006a109a072003280280012102200320032802880136023420032002360230200341d0016a200341306a1092070240200328028401450d00200210350b0240200341dc016a28020041ffffff3f71450d0020032802d80110350b200341e8016a28020041ffffff3f71450d0d20032802e40110350c0d0b200341d0016a41206a200341a8016a41206a280200360200200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d00120034180016a41186a200341e0006a41186a29030037030020034180016a41106a200341e0006a41106a29030037030020034180016a41086a200341e0006a41086a290300370300200320032903603703800120062002200341d0016a20034180016a109b070c0c0b41002101410221020c080b200141246a280200210620034198046a200141196a29000037030020034190046a200141116a29000037030020034188046a200141096a2900003703002003200129000137038004410221010240024002400240024020022d00000d0020022d00014101470d00200341a8016a20034180046a109a07200341d0016a20032802a801220120032802b00110de0220032802ac012102024020032802d8012205450d00200341f0016a280200210b200341ec016a280200210e200341e8016a2802002107200341e4016a280200210f200341e0016a280200210a20032802dc01210820032903d001210902402002450d00200110350b20062009a7460d0241c8dfca002106410a21024180800c21040c030b02402002450d00200110350b410321010b418080082104410f210241d2dfca0021060c020b200341d0016a41186a4200370300200341d0016a41106a2210420037030041082102200341d0016a41086a22014200370300200342003703d00141d1c4c700ad4280808080e0008410012206290000210c2001200641086a2900003703002003200c3703d0012006103541e7c4c700ad4280808080e0008410012206290000210c200341306a41086a2204200641086a2900003703002003200c3703302006103520102003290330220c37030020034180016a41086a200129030037030020034180016a41106a2201200c37030020034180016a41186a22062004290300370300200320032903d00137038001200341286a20034180016a412010c001200328022c410020032802281b200b4f0d0241a1dfca0021064180801821040b0240200841ffffff3f71450d00200510350b0240200741ffffff3f71450d00200f10350b410321010b20004200370308200041206a20023602002000411c6a2006360200200041186a20044180801c7120017241801672360200420121090c0c0b2009422088210c200642003703002001420037030020034180016a41086a22024200370300200342003703800141dad5ca00ad4280808080b0028410012211290000211a200341d0006a41086a2204201141086a2900003703002003201a37035020111035200220042903003703002003200329035037038001419cdfca00ad4280808080d0008410012211290000211a2004201141086a2900003703002003201a3703502011103520012003290350221a370300200341306a41086a2002290300370300200341306a41106a201a370300200341306a41186a20042903003703002003200329038001370330200341d0016a200341306a412010d50120032d00d00121042006200341e9016a2900003703002001200341e1016a2900003703002002200341d9016a290000370300200320032900d101370380010240024020044101460d00410021040c010b200341a8016a41186a20034180016a41186a290300221a370300200341a8016a41106a20034180016a41106a290300221b370300200341a8016a41086a2002290300221c3703002003200329038001221d3703a801200341d0016a41186a201a370300200341d0016a41106a201b370300200341d0016a41086a201c3703002003201d3703d001200a4105742101200521020340024020010d00410021040c020b41012104200341d0016a2002460d01200141606a21012002200341d0016a412010a0082106200241206a210220060d000b0b200ca72106200341d0016a41186a22114200370300200341d0016a41106a22124200370300200341d0016a41086a22024200370300200342003703d00141dad5ca00ad4280808080b0028410012201290000210c2002200141086a2900003703002003200c3703d001200110354189eaca00ad4280808080f0008410012201290000210c200341306a41086a2213200141086a2900003703002003200c3703302001103520102003290330370000201041086a201329030037000020034180016a41086a200229030037030020034180016a41106a201229030037030020034180016a41186a2011290300370300200320032903d00137038001200341a8016a20034180016a10fe010240024020032802a80122010d00410021020c010b20032902ac01220c422088a72102200c42ffffff3f83500d00200110350b200341dd016a20034180046a41086a2201290300370000200341e5016a20034180046a41106a2210290300370000200341ed016a20034180046a41186a2211290300370000200341fc016a41002002200e200a6a6b221220041b200e6a360200200341f8016a2012410020041b200a6a2204360200200341063a00d401200341073a00d00120032003290380043700d50141b0b4cc004100200341d0016a10d401200341ec016a200e360200200341d0016a41186a2007360200200341d0016a41106a200a360200200341dc016a20083602002003200b3602f0012003200f3602e401200320053602d801200320093703d001200341a8016a41186a2011290300370300200341a8016a41106a2010290300370300200341a8016a41086a200129030037030020032003290380043703a801200420064f2002200341d0016a200341a8016a109b070c0a0b1045000b41e1dfca002101411121064180960421040c060b103c000b20012004104a000b20062007104a000b41bbdfca002106410d21044180801021010b0240200e41ffffff3f71450d00200810350b0240201041ffffff3f71450d00200f10350b410321020b20004200370308200041206a20043602002000411c6a2006360200200041186a20014180801c7120027241801672360200420121090c030b200510ba0220051035200041206a20063602002000411c6a2001360200200041186a200420027236020020004200370308420121090c020b41b0b4cc004100200210d401200510350b42002109200042003703080b20002009370300200341a0046a24000bf55c04097f027e0c7f047e230041a0046b2203240002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e06000102030405000b200341e4016a4101360200200342013702d401200341e8d4ca003602d001200341043602ac012003419cd5ca003602a8012003200341a8016a3602e001200341d0016a41b0b4cc00104c000b2001412c6a2802002104200141286a2802002105200141246a280200210620012d00012107200341e0006a41186a22082001411a6a290000370300200341e0006a41106a2209200141126a290000370300200341e0006a41086a220a2001410a6a2900003703002003200141026a290000370360024020022d000120022d0000410047720d002006200410ac06200341d0016a41186a4200370300200341d0016a41106a220b4200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b00284220c10012201290000210d2002200141086a2900003703002003200d3703d001200110354189eaca00ad4280808080f0008410012201290000210d200341306a41086a220e200141086a2900003703002003200d37033020011035200b2003290330220d37030020034180016a41086a200229030037030020034180016a41106a200d37030020034180016a41186a200e290300370300200320032903d00137038001200341d0016a20034180016a10fe012006200420032802d0012202410120021b220b20032902d401420020021b220d422088a710ad0620034180046a41186a200829030037030020034180046a41106a200929030037030020034180046a41086a200a290300370300200320032903603703800402400240200741ff01710d0020034180016a41186a420037030020034180016a41106a2207420037030020034180016a41086a220142003703002003420037038001200c10012204290000210c200341d0006a41086a2202200441086a2900003703002003200c37035020041035200120022903003703002003200329035037038001419cdfca00ad4280808080d0008410012204290000210c2002200441086a2900003703002003200c3703502004103520072003290350220c370300200341a8016a41086a2001290300370300200341a8016a41106a200c370300200341a8016a41186a200229030037030020032003290380013703a801200341a8016aad428080808080048410070c010b200341a8016a41186a220720034180046a41186a290300370300200341a8016a41106a220820034180046a41106a290300370300200341a8016a41086a220920034180046a41086a29030037030020032003290380043703a801200341306a41186a4200370300200341306a41106a220a4200370300200341306a41086a2202420037030020034200370330200c10012201290000210c200341d0016a41086a2204200141086a2900003703002003200c3703d0012001103520022004290300370300200320032903d001370330419cdfca00ad4280808080d0008410012201290000210c20034180016a41086a220e200141086a2900003703002003200c3703800120011035200a200329038001220c37030020042002290300370300200341d0016a41106a200c370300200341d0016a41186a200e290300370300200320032903303703d001412010332202450d06200220032903a801370000200241186a2007290300370000200241106a2008290300370000200241086a2009290300370000200341d0016aad42808080808004842002ad42808080808004841002200210350b0240200d42ffffff3f83500d00200b10350b200541ffffff3f71450d0f200610350c0f0b0240200541ffffff3f71450d00200610350b20004200370308200041186a41023602004201210c0c0f0b200141046a280200210420032002411a6a290100370398012003200241026a2901003703800120032002410a6a290100370388012003200241126a290100370390010240024020022d00014101470d0020022d000041ff01710d00200341e0006a41186a20034180016a41186a2206290300370300200341e0006a41106a20034180016a41106a2205290300370300200341e0006a41086a20034180016a41086a22072903003703002003200329038001370360200341d0016a41186a4200370300200341d0016a41106a22084200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b0028410012201290000210c2002200141086a2900003703002003200c3703d001200110354189eaca00ad4280808080f0008410012201290000210c200341306a41086a2209200141086a2900003703002003200c3703302001103520082003290330220c370300200720022903003703002005200c37030020062009290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b220c422088a741057421012002410120021b2207210202400340024020010d00410021050c020b41012105200341e0006a2002460d01200141606a21012002200341e0006a412010a0082106200241206a210220060d000b0b0240200c42ffffff3f83500d00200710350b41831821022005450d01200341003602d801200342013703d0012004200341d0016a10af0320032802d401210120034180046a41186a220620033502d80142208620032802d0012208ad841009220241186a29000037030020034180046a41106a2205200241106a29000037030020034180046a41086a2207200241086a29000037030020032002290000370380042002103502402001450d00200810350b200341d0016a200441b002109d081a200341a8016a410d6a200341e0006a41086a290300370000200341a8016a41156a200341e0006a41106a290300370000200341a8016a411d6a200341e0006a41186a290300370000200341013a00ac01200320032903603700ad01200341023a00a80120034180016a200341d0016a200341a8016a10ac03200329038001210c200341d0016a410d6a2007290300370000200341d0016a41156a2005290300370000200341d0016a411d6a2006290300370000200341f5016a200c503a0000200341053a00d401200341083a00d00120032003290380043700d50141b0b4cc004100200341d0016a10d401200410350c0f0b41821821020b200410ba0220041035200041206a41093602002000411c6a41f2dfca00360200200041186a2002360200200042003703084201210c0c0e0b200141086a2802002104200141046a280200210f2002411a6a290100210c200241196a2d00002106200241186a2d00002105200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210e2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002117200241046a2d00002118200241026a2f0100211941012101024020022d00000d0020022d000141014721010b2003200c3703c001200320063a00bf01200320053a00be01200320073b01bc01200320083a00bb01200320093a00ba012003200a3b01b8012003200b3a00b7012003200e3a00b601200320103b01b401200320113a00b301200320123a00b201200320133b01b001200320143a00af01200320153a00ae01200320163b01ac01200320173a00ab01200320183a00aa01200320193b01a801024020010d00200341e0006a41186a200341a8016a41186a290300370300200341e0006a41106a200341a8016a41106a290300370300200341e0006a41086a200341a8016a41086a290300370300200320032903a801370360200341d0016a41186a4200370300200341d0016a41106a22074200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b0028410012201290000210c2002200141086a2900003703002003200c3703d001200110354189eaca00ad4280808080f0008410012201290000210c200341306a41086a2206200141086a2900003703002003200c3703302001103520072003290330220c37030020034180016a41086a200229030037030020034180016a41106a200c37030020034180016a41186a2006290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b220c422088a741057421012002410120021b2208210202400340024020010d00410021050c020b41012105200341e0006a2002460d01200141606a21012002200341e0006a412010a0082106200241206a210220060d000b0b0240200c42ffffff3f83500d00200810350b41032102024020050d0041f2dfca0021014109210641801821050c0c0b200341003602d801200342013703d0012004200341d0016a10af0320032802d401210620034180046a41186a220520033502d80142208620032802d001220aad841009220141186a29000037030020034180046a41106a2208200141106a29000037030020034180046a41086a2209200141086a29000037030020032001290000370380042001103502402006450d00200a10350b200341d0016a41186a2005290300370300200341d0016a41106a2008290300370300200341d0016a41086a200929030037030020032003290380043703d001200341a8016a200341d0016a109d07200341206a20032802a801220620032802b00141b0b4cc0041004100108a0220032802202101024020032802ac01450d00200610350b20014101460d040240200f4102490d0020034180016a41186a2208420037030020034180016a41106a2206420037030020034180016a41086a22014200370300200342003703800141c7d5ca00ad4280808080b00284220c10012205290000210d200341d0006a41086a2202200541086a2900003703002003200d37035020051035200120022903003703002003200329035037038001418ef0cb00ad4280808080d00184220d10012205290000211a2002200541086a2900003703002003201a3703502005103520062003290350221a370300200341306a41086a22052001290300370300200341306a41106a2209201a370300200341306a41186a220a20022903003703002003200329038001370330200341186a200341306a412010c001200328021c210e200328021821102008420037030020064200370300200142003703002003420037038001200c1001220b290000211a2002200b41086a2900003703002003201a370350200b1035200120022903003703002003200329035037038001200d1001220b290000211a2002200b41086a2900003703002003201a370350200b103520062003290350221a370300200520012903003703002009201a370300200a20022903003703002003200329038001370330200341106a200341306a412010c00120032802102111200328021421122008420037030020064200370300200142003703002003420037038001200c1001220b290000211a2002200b41086a2900003703002003201a370350200b1035200120022903003703002003200329035037038001200d1001220b290000210d2002200b41086a2900003703002003200d370350200b103520062003290350220d370300200520012903003703002009200d370300200a20022903003703002003200329038001370330410121022003201241016a410120111b3602d001200341306aad4280808080800484200341d0016aad4280808080c000841002200341d0016a41186a220b4200370300200341d0016a41106a22114200370300200341d0016a41086a22094200370300200342003703d001200c1001220a290000210c2009200a41086a2900003703002003200c3703d001200a10354180eaca00ad42808080809001841001220a290000210c2005200a41086a2900003703002003200c370330200a103520072003290330370000200741086a200529030037000020012009290300370300200620112903003703002008200b290300370300200320032903d00137038001200341d0016a20034180016a412010b5020240024020032802d00122010d00200341003602b001200342013703a80141002109410021060c010b200320032902d401220c3702ac01200320013602a801200c422088a72106200ca72109200121020b200341306a41186a220a20034180046a41186a290300370300200341306a41106a220520034180046a41106a290300370300200341306a41086a220120034180046a41086a2903003703002003200329038004370330024020062009470d00200341a8016a20094101108a0120032802ac01210920032802a801210220032802b00121060b200220064105746a22082003290330370000200841186a200a290300370000200841106a2005290300370000200841086a20012903003700002003200641016a220b3602b001200a420037030020054200370300200142003703002003420037033041c7d5ca00ad4280808080b0028410012208290000210c200341d0006a41086a2206200841086a2900003703002003200c3703502008103520012006290300370300200320032903503703304180eaca00ad428080808090018410012208290000210c2006200841086a2900003703002003200c3703502008103520052003290350220c37030020034180016a41086a200129030037030020034180016a41106a200c37030020034180016a41186a200629030037030020032003290330370380010240024020020d0020034180016aad428080808080048410070c010b200341203602d401200320034180016a3602d0012002200b200341d0016a10c504200941ffffff3f71450d00200210350b200341d0016a200441b002109d081a200341a8016a41186a20034180046a41186a290300370300200341a8016a41106a20034180046a41106a290300370300200341a8016a41086a20034180046a41086a29030037030020032003290380043703a80120034180016a200341a8016a109d072003280280012102200335028801210c200341003602b001200342013703a801200341d0016a200341a8016a10af0320032802ac012101200c4220862002ad8420033502b00142208620032802a8012206ad84100202402001450d00200610350b0240200328028401450d00200210350b200341d0016a10ba02200341d0016a41186a22064200370300200341d0016a41106a22054200370300200341d0016a41086a22024200370300200342003703d00141d1c4c700ad4280808080e0008410012201290000210c2002200141086a2900003703002003200c3703d0012001103541e7c4c700ad4280808080e0008410012201290000210c200341306a41086a2208200141086a2900003703002003200c3703302001103520072003290330370000200741086a200829030037000020034180016a41086a200229030037030020034180016a41106a200529030037030020034180016a41186a2006290300370300200320032903d00137038001200341086a20034180016a412010c001200328020c210120032802082106412010332202450d0620022003290360370000200241186a200341e0006a41186a290300370000200241106a200341e0006a41106a290300370000200241086a200341e0006a41086a290300370000200341ec016a4100360200200341dc016a428180808010370200200320014180e5086a4180e50820061b3602f001200342013702e401200320023602d8012003200f3602d4012003200e410020101b22063602d001200341a8016a41186a20034180046a41186a290300370300200341a8016a41106a20034180046a41106a290300370300200341a8016a41086a20034180046a41086a29030037030020032003290380043703a80120034180016a200341a8016a108a07200328028001210120032003280288013602ac01200320013602a801200341d0016a200341a8016a1092070240200328028401450d00200110350b20021035200341e5016a200341e0006a41106a290300370000200341ed016a200341e0006a41186a290300370000200341f5016a20032903800437000020034185026a20034180046a41106a2903003700002003418d026a20034180046a41186a2903003700002003419c026a200f36020020034198026a2006360200200341083a00d001200341dd016a200341e0006a41086a290300370000200341fd016a20034180046a41086a290300370000200341003a00d401200320032903603700d501200341d0016a21020c0d0b200341d0016a41186a22064200370300200341d0016a41106a22054200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b0028410012201290000210c2002200141086a2900003703002003200c3703d001200110354189eaca00ad4280808080f0008410012201290000210c200341306a41086a2208200141086a2900003703002003200c3703302001103520072003290330370000200741086a200829030037000020034180016a41086a200229030037030020034180016a41106a200529030037030020034180016a41186a2006290300370300200320032903d00137038001200341a8016a20034180016a10fe010240024020032802a80122010d00410021020c010b20032902ac01220c422088a72102200c42ffffff3f83500d00200110350b200341d0016a200441b002109d081a200341b4016a2002360200200341a8016a41086a4101360200200341003a00ac01200341023a00a80120034180016a200341d0016a200341a8016a10ac03200329038001210c200341dd016a20034180046a41086a290300370000200341e5016a20034190046a290300370000200341ed016a20034198046a290300370000200341f5016a200c503a0000200341043a00d401200341083a00d00120032003290380043700d501200341d0016a21020c0c0b4102210241801821050c0a0b200141216a2d0000210f200141246a2802002119200341e0006a41186a200141196a290000370300200341e0006a41106a200141116a290000370300200341e0006a41086a200141096a290000370300200320012900013703602002411a6a290100210c200241196a2d00002106200241186a2d00002105200241166a2f01002104200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210e2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211841012101024020022d00000d0020022d000141014721010b2003200c3703c001200320063a00bf01200320053a00be01200320043b01bc01200320073a00bb01200320083a00ba01200320093b01b8012003200a3a00b7012003200b3a00b6012003200e3b01b401200320103a00b301200320113a00b201200320123b01b001200320133a00af01200320143a00ae01200320153b01ac01200320163a00ab01200320173a00aa01200320183b01a801024020010d0020034180046a41186a200341a8016a41186a29030037030020034180046a41106a200341a8016a41106a29030037030020034180046a41086a200341a8016a41086a290300370300200320032903a80137038004200341d0016a41186a4200370300200341d0016a41106a22044200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b0028410012201290000210c2002200141086a2900003703002003200c3703d001200110354189eaca00ad4280808080f0008410012201290000210c200341306a41086a2206200141086a2900003703002003200c3703302001103520042003290330220c37030020034180016a41086a200229030037030020034180016a41106a200c37030020034180016a41186a2006290300370300200320032903d00137038001200341d0016a20034180016a10fe0120032902d401420020032802d00122021b220c422088a741057421012002410120021b2207210202400340024020010d00410021050c020b4101210520034180046a2002460d01200141606a2101200220034180046a412010a0082106200241206a210220060d000b0b0240200c42ffffff3f83500d00200710350b41032102024020050d004100210141f2dfca002106410921050c0a0b20034180016a200341e0006a109e07200341d0016a200328028001220620032802880110de0220032802840121010240024020032802d8012208450d00200341f0016a2802002102200341ec016a280200210a200341e8016a2802002110200341e4016a280200210e200341e0016a280200210920032802dc01210b20032903d001210c02402001450d00200610350b200341c4016a200a360200200341c0016a2010360200200341b8016a2009360200200341b4016a200b360200200320023602c8012003200e3602bc01200320083602b0012003200c3703a8012019200ca7460d0141c8dfca002106410a21054180800c21010c0a0b02402001450d00200610350b41808008210141d2dfca002106410f21050c0a0b41002101410021064100211102402009450d002009410574210541002106200821020240034020034180046a2002460d012006200220034180046a412010a00822074100476a21062007450d01200241206a2102200541606a22050d000b410021110c010b410121110b410021020240200a450d00200a410574210541002101200e21020240034020034180046a2002460d012001200220034180046a412010a00822074100476a21012007450d01200241206a2102200541606a22050d000b410021020c010b410121020b024002400240200f41ff01710d002002450d010c0a0b20110d09200341306a41186a220520034180046a41186a290300370300200341306a41106a220720034180046a41106a290300370300200341306a41086a220a20034180046a41086a290300370300200320032903800437033002402009200b470d00200341b0016a200b4101108a0120032802b801210920032802b00121080b200820094105746a22062003290330370000200641186a2005290300370000200641106a2007290300370000200641086a200a2903003700002003200941016a22073602b80120032802c40121052002450d01200520014d0d0720032802bc0122062005417f6a22054105746a2202290000210c2002290008210d2002290010211a200241186a290000211b200320053602c401200620014105746a220241186a201b3700002002201a3700102002200d3700082002200c3700000c010b20034180016a41186a220120034180046a41186a29030037030020034180016a41106a220520034180046a41106a29030037030020034180016a41086a220720034180046a41086a2903003703002003200329038004370380010240200a2010470d00200341bc016a20104101108a0120032802c401210a20032802bc01210e0b200e200a4105746a2202200329038001370000200241186a2001290300370000200241106a2005290300370000200241086a2007290300370000200320032802c40141016a22053602c40120032802b80121072011450d00200720064d0d0720032802b00122012007417f6a22074105746a2202290000210c2002290008210d2002290010211a200241186a290000211b200320073602b801200120064105746a220241186a201b3700002002201a3700102002200d3700082002200c3700000b200341f5016a2003290360370000200341e5016a20034180046a41106a290300370000200341ed016a20034180046a41186a29030037000020034185026a200341e0006a41106a2903003700002003418d026a200341e0006a41186a290300370000200341083a00d001200341dd016a20034180046a41086a290300370000200341fd016a200341e0006a41086a290300370000200341013a00d40120032003290380043700d5012003419c026a200536020020034198026a200736020020034195026a200f3a00004100210241b0b4cc004100200341d0016a10d401200341d0016a41186a22084200370300200341d0016a41106a22094200370300200341d0016a41086a22014200370300200342003703d00141c7d5ca00ad4280808080b0028410012206290000210c2001200641086a2900003703002003200c3703d001200610354189eaca00ad4280808080f0008410012206290000210c200341306a41086a220a200641086a2900003703002003200c3703302006103520042003290330370000200441086a200a29030037000020034180016a41086a200129030037030020034180016a41106a200929030037030020034180016a41186a2008290300370300200320032903d00137038001200341d0006a20034180016a10fe01024020032802502201450d002003290254220c422088a72102200c42ffffff3f83500d00200110350b0240200720032802ac0122014f22060d004100200220056b2205200520024b1b2001490d00200341d0016a41206a200341a8016a41206a280200360200200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d00120034180016a200341e0006a109e072003280280012102200320032802880136023420032002360230200341d0016a200341306a1092070240200328028401450d00200210350b0240200341dc016a28020041ffffff3f71450d0020032802d80110350b200341e8016a28020041ffffff3f71450d0d20032802e40110350c0d0b200341d0016a41206a200341a8016a41206a280200360200200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d00120034180016a41186a200341e0006a41186a29030037030020034180016a41106a200341e0006a41106a29030037030020034180016a41086a200341e0006a41086a290300370300200320032903603703800120062002200341d0016a20034180016a109f070c0c0b41002101410221020c080b200141246a280200210620034198046a200141196a29000037030020034190046a200141116a29000037030020034188046a200141096a2900003703002003200129000137038004410221010240024002400240024020022d00000d0020022d00014101470d00200341a8016a20034180046a109e07200341d0016a20032802a801220120032802b00110de0220032802ac012102024020032802d8012204450d00200341f0016a280200210a200341ec016a280200210b200341e8016a2802002107200341e4016a280200210e200341e0016a280200210920032802dc01210820032903d001210c02402002450d00200110350b2006200ca7460d0241c8dfca002106410a21024180800c21050c030b02402002450d00200110350b410321010b418080082105410f210241d2dfca0021060c020b200341d0016a41186a4200370300200341d0016a41106a2210420037030041082102200341d0016a41086a22014200370300200342003703d00141d1c4c700ad4280808080e0008410012206290000210d2001200641086a2900003703002003200d3703d0012006103541e7c4c700ad4280808080e0008410012206290000210d200341306a41086a2205200641086a2900003703002003200d3703302006103520102003290330220d37030020034180016a41086a200129030037030020034180016a41106a2201200d37030020034180016a41186a22062005290300370300200320032903d00137038001200341286a20034180016a412010c001200328022c410020032802281b200a4f0d0241a1dfca0021064180801821050b0240200841ffffff3f71450d00200410350b0240200741ffffff3f71450d00200e10350b410321010b20004200370308200041206a20023602002000411c6a2006360200200041186a20054180801c71200172418018723602004201210c0c0c0b200c422088210d200642003703002001420037030020034180016a41086a22024200370300200342003703800141c7d5ca00ad4280808080b0028410012211290000211a200341d0006a41086a2205201141086a2900003703002003201a37035020111035200220052903003703002003200329035037038001419cdfca00ad4280808080d0008410012211290000211a2005201141086a2900003703002003201a3703502011103520012003290350221a370300200341306a41086a2002290300370300200341306a41106a201a370300200341306a41186a20052903003703002003200329038001370330200341d0016a200341306a412010d50120032d00d00121052006200341e9016a2900003703002001200341e1016a2900003703002002200341d9016a290000370300200320032900d101370380010240024020054101460d00410021050c010b200341a8016a41186a20034180016a41186a290300221a370300200341a8016a41106a20034180016a41106a290300221b370300200341a8016a41086a2002290300221c3703002003200329038001221d3703a801200341d0016a41186a201a370300200341d0016a41106a201b370300200341d0016a41086a201c3703002003201d3703d00120094105742101200421020340024020010d00410021050c020b41012105200341d0016a2002460d01200141606a21012002200341d0016a412010a0082106200241206a210220060d000b0b200da72106200341d0016a41186a22114200370300200341d0016a41106a22124200370300200341d0016a41086a22024200370300200342003703d00141c7d5ca00ad4280808080b0028410012201290000210d2002200141086a2900003703002003200d3703d001200110354189eaca00ad4280808080f0008410012201290000210d200341306a41086a2213200141086a2900003703002003200d3703302001103520102003290330370000201041086a201329030037000020034180016a41086a200229030037030020034180016a41106a201229030037030020034180016a41186a2011290300370300200320032903d00137038001200341a8016a20034180016a10fe010240024020032802a80122010d00410021020c010b20032902ac01220d422088a72102200d42ffffff3f83500d00200110350b200341e5016a20034180046a41106a2201290300370000200341ed016a20034180046a41186a2210290300370000200341083a00d001200341dd016a20034180046a41086a2211290300370000200341fc016a41002002200b20096a6b221220051b200b6a360200200341f8016a2012410020051b20096a2205360200200341063a00d40120032003290380043700d50141b0b4cc004100200341d0016a10d401200341ec016a200b360200200341d0016a41186a2007360200200341d0016a41106a2009360200200341dc016a20083602002003200a3602f0012003200e3602e401200320043602d8012003200c3703d001200341a8016a41186a2010290300370300200341a8016a41106a2001290300370300200341a8016a41086a201129030037030020032003290380043703a801200520064f2002200341d0016a200341a8016a109f070c0a0b1045000b41e1dfca002101411121064180980421050c060b103c000b20012005104a000b20062007104a000b41bbdfca002106410d21054180801021010b0240200b41ffffff3f71450d00200810350b0240201041ffffff3f71450d00200e10350b410321020b20004200370308200041206a20053602002000411c6a2006360200200041186a20014180801c71200272418018723602004201210c0c030b200410ba0220041035200041206a20063602002000411c6a2001360200200041186a2005200272360200200042003703084201210c0c020b41b0b4cc004100200210d401200410350b4200210c200042003703080b2000200c370300200341a0046a24000bb65d07047f017e037f027e017f027e097f23004180036b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e080001020304050607000b20034194026a41013602002003420137028402200341e8d4ca0036028002200341043602dc012003419cd5ca003602d8012003200341d8016a3602900220034180026a41b0b4cc00104c000b200341d0016a200141196a290000370300200341b8016a41106a200141116a290000370300200341c0016a200141096a290000370300200320012900013703b801200241036a2d0000210420022f000121050240024020022d00002206417f6a220141024b0d00024020010e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200641004720052004411074727241ff01710d070b20034180026a41186a420037030020034180026a41106a2204420037030020034180026a41086a22014200370300200342003703800241fb8fc800ad4280808080b002841001220229000021072001200241086a2900003703002003200737038002200210354189eaca00ad4280808080f0008410012202290000210720034198016a41086a2205200241086a29000037030020032007370398012002103520042003290398012207370300200341d8016a41086a2001290300370300200341d8016a41106a2007370300200341d8016a41186a200529030037030020032003290380023703d801200341f8006a200341d8016a10fe010240200328027822060d00410021082003410036023020034201370328410121060c170b2003200329027c220737022c200320063602282007a7210841002101024002402007422088a7220941014b0d0020090e021801180b2009210203402002410176220420016a22052001200620054105746a200341b8016a412010a0084101481b2101200220046b220241014b0d000b0b0240200620014105746a200341b8016a412010a0082202450d0020034180026a41186a200341b8016a41186a29030037030020034180026a41106a200341b8016a41106a29030037030020034180026a41086a200341b8016a41086a290300370300200320032903b801370380022002411f7620016a220420094b0d0820034180026a21020c180b02402008450d00200841ffffff3f71450d00200610350b41831c21010c150b200341c0006a200141196a290000370300200341286a41106a200141116a290000370300200341306a200141096a2900003703002003200129000137032841022101200241036a2d0000210520022f0001210602400240024020022d00002209417f6a220441024b0d00024020040e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200941004720062005411074727241ff01710d010b20034180026a41186a420037030020034180026a41106a2204420037030020034180026a41086a22014200370300200342003703800241fb8fc800ad4280808080b002841001220229000021072001200241086a2900003703002003200737038002200210354189eaca00ad4280808080f0008410012202290000210720034198016a41086a2205200241086a29000037030020032007370398012002103520042003290398012207370300200341d8016a41086a2001290300370300200341d8016a41106a2007370300200341d8016a41186a200529030037030020032003290380023703d80120034180026a200341d8016a10fe012003280280022202410120021b210641002101024002400240200329028402420020021b2207422088a7220941014b0d0020090e020201020b2009210203402002410176220420016a22052001200620054105746a200341286a412010a0084101481b2101200220046b220241014b0d000b0b200620014105746a200341286a412010a0080d00200120094f0d09200620014105746a2202200241206a2001417f7320096a410574109e081a20034180026a41186a220a420037030020034180026a41106a2208420037030020034180026a41086a22054200370300200342003703800241fb8fc800ad4280808080b00284220b10012201290000210c20034198016a41086a2202200141086a2900003703002003200c3703980120011035200520022903003703002003200329039801370380024189eaca00ad4280808080f0008410012201290000210c2002200141086a2900003703002003200c37039801200110352008200329039801220c370300200341b8016a41086a22042005290300370300200341b8016a41106a200c370300200341b8016a41186a200229030037030020032003290380023703b80120034120360284022003200341b8016a3602800220062009417f6a220120034180026a109802200a200341286a41186a2903003703002008200341286a41106a2903003703002005200341286a41086a290300370300200320032903283703800220034180026a41012006200110aa06200341d8016a41186a220d4200370300200341d8016a41106a22084200370300200341d8016a41086a22054200370300200342003703d801200b1001220a290000210b2004200a41086a2900003703002003200b3703b801200a103520052004290300370300200320032903b8013703d801419cdfca00ad4280808080d000841001220a290000210b2004200a41086a2900003703002003200b3703b801200a1035200820032903b801220b3703002002200529030037030020034198016a41106a200b37030020034198016a41186a2004290300370300200320032903d8013703980120034180026a20034198016a412010d50120032d0080022102200d20034199026a290000370300200820034191026a290000370300200520034189026a29000037030020032003290081023703d801024020024101470d00200341f8006a41186a200d290300220b370300200341f8006a41106a2008290300220c370300200341f8006a41086a2005290300220e370300200320032903d801220f370378200d200b3703002008200c3703002005200e3703002003200f3703d8014100210202400240024002402009417f6a220441014b0d0020040e020201020b03402001410176220420026a22052002200620054105746a200341d8016a412010a0084101481b2102200120046b220141014b0d000b0b200620024105746a200341d8016a412010a008450d010b20034198016a41186a420037030020034198016a41106a2205420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012204290000210b200341e8006a41086a2201200441086a2900003703002003200b37036820041035200220012903003703002003200329036837039801419cdfca00ad4280808080d0008410012204290000210b2001200441086a2900003703002003200b3703682004103520052003290368220b370300200341c8006a41086a2002290300370300200341c8006a41106a200b370300200341c8006a41186a20012903003703002003200329039801370348200341c8006aad428080808080048410070c010b20034199026a200341f0016a29030037000020034191026a200341e8016a29030037000020034189026a200341e0016a290300370000200320032903d80137008102200341013a00800220034180026a10ab060b2003418a023b01800241b0b4cc00410020034180026a10d401200742ffffff3f83500d15200610350c150b02402007a72201450d00200141ffffff3f71450d00200610350b410321010b20004200370308200041206a41093602002000411c6a41f2dfca00360200200041186a200141809c0472360200420121070c180b200341086a41186a200141196a290000370300200341086a41106a200141116a290000370300200341086a41086a200141096a29000037030020032001290001370308200341286a41186a200141396a290000370300200341286a41106a200141316a290000370300200341286a41086a200141296a2900003703002003200141216a29000037032841022101200241036a2d0000210520022f000121060240024020022d00002209417f6a220441024b0d00024020040e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200941004720062005411074727241ff0171450d000c110b200341086a200341286a412010a008450d1220034180026a41186a420037030020034180026a41106a2204420037030020034180026a41086a22014200370300200342003703800241fb8fc800ad4280808080b002841001220229000021072001200241086a2900003703002003200737038002200210354189eaca00ad4280808080f0008410012202290000210720034198016a41086a2205200241086a29000037030020032007370398012002103520042003290398012207370300200341d8016a41086a2001290300370300200341d8016a41106a2007370300200341d8016a41186a200529030037030020032003290380023703d80120034180026a200341d8016a10fe014101210d2003280280022202410120021b210641f2dfca0021084109210a4100210102400240200329028402420020021b2207422088a7220941014b0d0020090e021101110b2009210203402002410176220420016a22052001200620054105746a200341086a412010a0084101481b2101200220046b220241014b0d000b0b200620014105746a2210200341086a412010a0080d0f410021020240200941014b0d0020090e02120f120b2009210403402004410176220520026a22082002200620084105746a200341286a412010a0084101481b2102200420056b220441014b0d000c0f0b0b200241036a2d0000210520022f000121062001410c6a2802002109200141086a280200210d200141046a280200210402400240024020022d00002208417f6a220141024b0d00024020010e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200841004720062005411074727241ff01710d010b2004200910ac0620034180026a41186a420037030020034180026a41106a2205420037030020034180026a41086a22024200370300200342003703800241fb8fc800ad4280808080b00284220710012201290000210b2002200141086a2900003703002003200b37038002200110354189eaca00ad4280808080f0008410012201290000210b20034198016a41086a2208200141086a2900003703002003200b37039801200110352005200329039801220b370300200341d8016a41086a22012002290300370300200341d8016a41106a2202200b370300200341d8016a41186a2205200829030037030020032003290380023703d80120034180026a200341d8016a10fe01200420092003280280022206410120061b2210200329028402420020061b220b422088a710ad06200542003703002002420037030020014200370300200342003703d80120071001220a2900002107200341b8016a41086a2206200a41086a290000370300200320073703b801200a103520012006290300370300200320032903b8013703d801419cdfca00ad4280808080d000841001220a29000021072006200a41086a290000370300200320073703b801200a1035200220032903b80122073703002008200129030037030020034198016a41106a200737030020034198016a41186a2006290300370300200320032903d8013703980120034180026a20034198016a412010d50120032d0080022106200520034199026a290000370300200220034191026a290000370300200120034189026a29000037030020032003290081023703d801024020064101470d00200341f8006a41186a20052903002207370300200341f8006a41106a2002290300220c370300200341f8006a41086a2001290300220e370300200320032903d801220f370378200520073703002002200c3703002001200e3703002003200f3703d801410021010240024002400240200941014b0d0020090e020201020b2009210203402002410176220520016a22062001200420064105746a200341d8016a412010a0084101481b2101200220056b220241014b0d000b0b200420014105746a200341d8016a412010a008450d010b20034198016a41186a420037030020034198016a41106a2206420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b00284100122052900002107200341e8006a41086a2201200541086a2900003703002003200737036820051035200220012903003703002003200329036837039801419cdfca00ad4280808080d000841001220529000021072001200541086a2900003703002003200737036820051035200620032903682207370300200341c8006a41086a2002290300370300200341c8006a41106a2007370300200341c8006a41186a20012903003703002003200329039801370348200341c8006aad428080808080048410070c010b20034199026a200341f0016a29030037000020034191026a200341e8016a29030037000020034189026a200341e0016a290300370000200320032903d80137008102200341013a00800220034180026a10ab060b0240200b42ffffff3f83500d00201010350b4200210720034198016a41186a420037030020034198016a41106a2206420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012205290000210b200341e8006a41086a2201200541086a2900003703002003200b370368200510352002200129030037030020032003290368370398014189eaca00ad4280808080f0008410012205290000210b2001200541086a2900003703002003200b3703682005103520062003290368220b370300200341c8006a41086a2002290300370300200341c8006a41106a200b370300200341c8006a41186a2001290300370300200320032903980137034820034120360284022003200341c8006a360280022004200920034180026a1098020240200d41ffffff3f71450d00200410350b2003418a063b01800241b0b4cc00410020034180026a10d4010c160b0240200d41ffffff3f71450d00200410350b20004200370308200041186a4102360200420121070c160b200341286a41186a200141196a290000370300200341286a41106a200141116a290000370300200341286a41086a200141096a2900003703002003200129000137032841022101024020022d00000d0020022d00014101470d002002411a6a2901002107200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002109200241126a2f01002108200241116a2d0000210a200241106a2d0000210d2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f010021182003200241096a2d00003a009f01200320143a009e01200320153b019c01200320163a009b01200320173a009a01200320183b0198012003200a3a00a7012003200d3a00a601200320103b01a401200320113a00a301200320123a00a201200320133b01a001200320013a00af01200320043a00ae01200320053b01ac01200320063a00ab01200320093a00aa01200320083b01a801200320073701b001200341f8006a41186a22012007370300200341f8006a41106a220220032901a801370300200341f8006a41086a220420032901a0013703002003200329019801370378200341b8016a41186a2001290300370300200341b8016a41106a2002290300370300200341b8016a41086a2004290300370300200320032903783703b801200341b8016a200341286a412010a008450d0920034180026a41186a420037030020034180026a41106a2204420037030020034180026a41086a22014200370300200342003703800241fb8fc800ad4280808080b002841001220229000021072001200241086a2900003703002003200737038002200210354189eaca00ad4280808080f0008410012202290000210720034198016a41086a2205200241086a29000037030020032007370398012002103520042003290398012207370300200341d8016a41086a2001290300370300200341d8016a41106a2007370300200341d8016a41186a200529030037030020032003290380023703d80120034180026a200341d8016a10fe01410121092003280280022202410120021b210641f2dfca0021084109210a4100210102400240200329028402420020021b2207422088a7220d41014b0d00200d0e020901090b200d210203402002410176220420016a22052001200620054105746a200341b8016a412010a0084101481b2101200220046b220241014b0d000b0b200620014105746a2210200341b8016a412010a0080d07410021020240200d41014b0d00200d0e020907090b200d210403402004410176220520026a22092002200620094105746a200341286a412010a0084101481b2102200420056b220441014b0d000c070b0b0c090b200341d0016a200141196a290000370300200341b8016a41106a200141116a290000370300200341c0016a200141096a290000370300200320012900013703b80141022101200241036a2d0000210520022f0001210602400240024020022d00002209417f6a220441024b0d00024020040e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200941004720062005411074727241ff01710d010b20034180026a41186a420037030020034180026a41106a2204420037030020034180026a41086a22014200370300200342003703800241fb8fc800ad4280808080b002841001220229000021072001200241086a2900003703002003200737038002200210354189eaca00ad4280808080f0008410012202290000210720034198016a41086a2205200241086a29000037030020032007370398012002103520042003290398012207370300200341d8016a41086a2001290300370300200341d8016a41106a2007370300200341d8016a41186a200529030037030020032003290380023703d80120034180026a200341d8016a10fe012003280280022202410120021b210641002101024002400240200329028402420020021b2207422088a7220241014b0d0020020e020201020b03402002410176220420016a22052001200620054105746a200341b8016a412010a0084101481b2101200220046b220241014b0d000b0b200620014105746a200341b8016a412010a0080d000240200742ffffff3f83500d00200610350b4200210720034198016a41186a420037030020034198016a41106a2205420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012204290000210b200341e8006a41086a2201200441086a2900003703002003200b37036820041035200220012903003703002003200329036837039801419cdfca00ad4280808080d0008410012204290000210b2001200441086a2900003703002003200b3703682004103520052003290368220b370300200341c8006a41086a2002290300370300200341c8006a41106a200b370300200341c8006a41186a20012903003703002003200329039801370348412010332201450d0c200120032903b801370000200141186a200341b8016a41186a2202290300370000200141106a200341b8016a41106a2204290300370000200141086a200341b8016a41086a2205290300370000200341c8006aad42808080808004842001ad428080808080048410022001103520034199026a200229030037000020034191026a200429030037000020034189026a2005290300370000200320032903b80137008102200341013a00800220034180026a10ab060c150b02402007a72201450d00200141ffffff3f71450d00200610350b410321010b20004200370308200041206a41093602002000411c6a41f2dfca00360200200041186a200141809c0472360200420121070c140b200241036a2d0000210420022f000121050240024020022d00002206417f6a220141024b0d00024020010e03000102000b200241086a2802004101742002410c6a2802004d0d00200241046a28020041ff0171450d010b200641004720052004411074727241ff0171450d0020004200370308200041186a4102360200420121070c140b4200210720034198016a41186a420037030020034198016a41106a2205420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012204290000210b200341e8006a41086a2201200441086a2900003703002003200b37036820041035200220012903003703002003200329036837039801419cdfca00ad4280808080d0008410012204290000210b2001200441086a2900003703002003200b3703682004103520052003290368220b370300200341c8006a41086a2002290300370300200341c8006a41106a200b370300200341c8006a41186a20012903003703002003200329039801370348200341c8006aad42808080808004841007200341003a00800220034180026a10ab060c120b41821c21010c0e0b20042009104d000b20012009104e000b200620024105746a200341286a412010a0080d0141ce9cc8002108410d210a410021090b02402007a722010d00410321010c030b0240200141ffffff3f71450d00200610350b410321010c020b200341d8016a41186a2202200341286a41186a290300370300200341d8016a41106a2204200341286a41106a290300370300200341d8016a41086a2205200341286a41086a290300370300200320032903283703d8012001200d4f0d02201020032903d801370000201041186a2002290300370000201041106a2004290300370000201041086a20052903003700002006200d10ac0620034198016a41186a2205420037030020034198016a41106a2204420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b00284220b10012209290000210c200341e8006a41086a2201200941086a2900003703002003200c370368200910352002200129030037030020032003290368370398014189eaca00ad4280808080f0008410012209290000210c2001200941086a2900003703002003200c3703682009103520042003290368220c370300200341c8006a41086a220a2002290300370300200341c8006a41106a2210200c370300200341c8006a41186a22112001290300370300200320032903980137034820034120360284022003200341c8006a360280022006200d20034180026a10980220034180026a41186a200341b8016a41186a29030037030020034180026a41106a200341b8016a41106a29030037030020034180026a41086a200341b8016a41086a290300370300200320032903b801370380024101210820034180026a41012006200d10aa062005420037030020044200370300200242003703002003420037039801200b10012209290000210b2001200941086a2900003703002003200b37036820091035200220012903003703002003200329036837039801419cdfca00ad4280808080d0008410012209290000210b2001200941086a2900003703002003200b3703682009103520042003290368220b370300200a20022903003703002010200b37030020112001290300370300200320032903980137034820034180026a200341c8006a412010d50120032d0080022101200520034180026a41196a290000370300200420034180026a41116a290000370300200220034180026a41096a2900003703002003200329008102370398010240024020014101460d0041002108200341003a00d8010c010b200341d8016a41096a200341a0016a290300370000200341d8016a41116a200341a8016a290300370000200341d8016a41196a200341b0016a290300370000200341013a00d80120032003290398013700d9010b20034199026a200341d0016a29030037000020034191026a200341c8016a29030037000020034189026a200341c0016a290300370000200320032903b80137008102200341013a00800202402008450d00200341d8016a41017220034180026a410172412010a0080d0020034198016a41186a2209420037030020034198016a41106a2208420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012205290000210b200341e8006a41086a2201200541086a2900003703002003200b37036820051035200220012903003703002003200329036837039801419cdfca00ad4280808080d0008410012205290000210b2001200541086a2900003703002003200b3703682005103520042003290368370000200441086a2001290300370000200341c8006a41086a2002290300370300200341c8006a41106a2008290300370300200341c8006a41186a20092903003703002003200329039801370348412010332201450d0420012003290328370000200141186a200341286a41186a2202290300370000200141106a200341286a41106a2204290300370000200141086a200341286a41086a2205290300370000200341c8006aad42808080808004842001ad428080808080048410022001103520034199026a200229030037000020034191026a200429030037000020034189026a20052903003700002003200329032837008102200341013a00800220034180026a10ab060b200742ffffff3f83500d00200610350b2003418a083b01800241b0b4cc00410020034180026a10d401420021070c0b0b20004200370308200041206a200a3602002000411c6a2008360200200041186a200941ff017141107420017241801c72360200420121070c0b0b2001200d419898c8001042000b1045000b200620024105746a200341286a412010a0080d0241ce9cc8002108410d210a4100210d0b02402007a72201450d00200141ffffff3f71450d00200610350b410321010b20004200370308200041206a200a3602002000411c6a2008360200200041186a200d41ff017141107420017241801c72360200420121070c060b20034180026a41186a2205200341286a41186a29030037030020034180026a41106a2208200341286a41106a29030037030020034180026a41086a220a200341286a41086a29030037030020032003290328370380020240200120094f0d002010200329038002370000201041186a2005290300370000201041106a2008290300370000201041086a200a2903003700002006200910ac06200341d8016a41186a4200370300200341d8016a41106a220d4200370300200341d8016a41086a22044200370300200342003703d80141fb8fc800ad4280808080b00284220b10012201290000210c200341b8016a41086a2202200141086a2900003703002003200c3703b8012001103520042002290300370300200320032903b8013703d8014189eaca00ad4280808080f0008410012201290000210c2002200141086a2900003703002003200c3703b80120011035200d20032903b801220c37030020034198016a41086a2201200429030037030020034198016a41106a2204200c37030020034198016a41186a220d2002290300370300200320032903d801370398012003412036028402200320034198016a360280022006200920034180026a1098022005200341086a41186a2903003703002008200341086a41106a290300370300200a200341086a41086a290300370300200320032903083703800220034180026a41012006200910aa06200d420037030020044200370300200142003703002003420037039801200b10012205290000210b200341e8006a41086a2202200541086a2900003703002003200b37036820051035200120022903003703002003200329036837039801419cdfca00ad4280808080d0008410012205290000210b2002200541086a2900003703002003200b3703682005103520042003290368220b370300200341c8006a41086a2001290300370300200341c8006a41106a200b370300200341c8006a41186a2002290300370300200320032903980137034820034180026a200341c8006a412010d50120032d0080022102200d20034199026a290000370300200420034191026a290000370300200120034189026a290000370300200320032900810237039801024020024101470d00200341b8016a41186a20034198016a41186a290300220b370300200341b8016a41106a20034198016a41106a290300220c370300200341b8016a41086a20034198016a41086a290300220e3703002003200329039801220f3703b801200341d8016a41186a200b370300200341d8016a41106a200c370300200341d8016a41086a200e3703002003200f3703d80141002101024020094101460d004100210103402009410176220220016a22042001200620044105746a200341d8016a412010a0084101481b2101200920026b220941014b0d000b0b0240200620014105746a200341d8016a412010a008450d00200341f8006a41186a4200370300200341f8006a41106a22054200370300200341f8006a41086a220242003703002003420037037841fb8fc800ad4280808080b0028410012204290000210b20034198016a41086a2201200441086a2900003703002003200b3703980120041035200220012903003703002003200329039801370378419cdfca00ad4280808080d0008410012204290000210b2001200441086a2900003703002003200b37039801200410352005200329039801220b37030020034180026a41086a200229030037030020034180026a41106a200b37030020034180026a41186a2001290300370300200320032903783703800220034180026aad428080808080048410070c010b20034199026a200341f0016a29030037000020034191026a200341e8016a29030037000020034189026a200341e0016a290300370000200320032903d80137008102200341013a00800220034180026a10ab060b2003418a043b01800241b0b4cc00410020034180026a10d401200742ffffff3f83500d0120061035420021070c050b20012009418898c8001042000b420021070c030b20004200370308200041206a410d3602002000411c6a41ce9cc800360200200041186a2001360200420121070c030b20034180026a41186a200341b8016a41186a29030037030020034180026a41106a200341b8016a41106a29030037030020034180026a41086a200341b8016a41086a290300370300200320032903b801370380024100210920034180026a2102410021040b024020092008470d00200341286a20094101108a01200328022c2108200328022821060b200620044105746a220141206a2001200920046b410574109e081a20012002290000370000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a2900003700002003200941016a3602304200210720034198016a41186a420037030020034198016a41106a2205420037030020034198016a41086a22024200370300200342003703980141fb8fc800ad4280808080b0028410012204290000210b200341e8006a41086a2201200441086a2900003703002003200b370368200410352002200129030037030020032003290368370398014189eaca00ad4280808080f0008410012204290000210b2001200441086a2900003703002003200b3703682004103520052003290368220b370300200341c8006a41086a2002290300370300200341c8006a41106a200b370300200341c8006a41186a2001290300370300200320032903980137034820034120360284022003200341c8006a360280022003280228200328023020034180026a10980220034180026a41186a200341b8016a41186a29030037030020034180026a41106a200341b8016a41106a29030037030020034180026a41086a200341b8016a41086a290300370300200320032903b8013703800241b0b4cc00410020032802282201200328023010aa062003410a3b01800241b0b4cc00410020034180026a10d401200841ffffff3f71450d00200110350b200020073703080b2000200737030020034180036a24000b8b970107017f027e117f017e027f087e1d7f230041d0086b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0900010203040506070a000b200341d4076a4101360200200342013702c407200341e8d4ca003602c007200341043602b4062003419cd5ca003602b0062003200341b0066a3602d007200341c0076a41b0b4cc00104c000b200141306a2903002104200141286a2903002105200341b0066a41206a200141246a280200360200200341b0066a41186a2001411c6a290200370300200341b0066a41106a200141146a290200370300200341b0066a41086a2001410c6a2902003703002003200141046a2902003703b006418222210102400240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a29010037038804200320013a008704200320063a008604200320073b018404200320083a008304200320093a0082042003200a3b0180042003200b3a00ff032003200c3a00fe032003200d3b01fc032003200e3a00fb032003200f3a00fa03200320103b01f803200320113a00f703200320123a00f603200320133b01f403200320143a00f303200320153a00f203200320163b01f003200341c0076a41206a200341b0066a41206a280200360200200341c0076a41186a200341b0066a41186a290300370300200341c0076a41106a200341b0066a41106a290300370300200341c0076a41086a200341b0066a41086a290300370300200320032903b0063703c007200341f8046a200341c0076a108b02418122210120032d00f8044101460d00200341f8046a41086a2d0000210720034181056a2f0000210820034183056a2d0000210920034184056a2d0000210a20034185056a2f0000210b20034187056a2d0000210c200341f8046a41106a2d0000210d20034189056a2f0000210e2003418b056a2d0000210f2003418c056a2d000021102003418d056a2f000021112003418f056a2d00002112200341f8046a41186a2d0000211320034191056a290000211720032f00f904211420032d00fb04211520032d00fc04211620032f00fd04211820032d00ff042119200341286a2005200442c0843d4200109808200341186a2003290328221a200341286a41086a290300221b42c0fb42427f108408200341086a201a201b42d0860342001084082003200341086a41086a2903002003290308221b200520032903187c221a421480221ca7417f201a42d086037e221a428080808080c8d007541b201a201c42c0fb427e7c42a0c21e566aad7c221a201b54ad7c221b4200201a428080e983b1de1656201b420052201b501b22011b221b3703f0022003201a428080e983b1de1620011b221a3703e8022003200341f0036a360280062003200341f0036a3602e0012003200341e0016a3602c807200320034180066a3602c4072003200341e8026a3602c007200341f8046a200341f0036a200341c0076a108c0320032802f8044101470d01418322210120032d00fc044104460d020b200041206a411c3602002000411c6a41e3adc800360200200041186a200136020020004200370308420121050c160b200341f8046a41086a2903004201520d00200341f8046a41106a290300211c20032802e0012101200341f8076a200341f8046a41186a290300370300200341f0076a201c370300200341c0076a41086a41003a0000200341c9076a2001290000370000200341d1076a200141086a290000370000200341d9076a200141106a290000370000200341e1076a200141186a290000370000200341033a00c00741b0b4cc004100200341c0076a10d4010b4186f0cb00ad4280808080800184221c10012201290000211d2001290008211e20011035418ef0cb00ad4280808080d00184221f1001220129000021202001290008212120011035200320213703900520032020370388052003201e370380052003201d3703f8042003200341f8046a412010c0012003280204210220032802002106201c10012201290000211c2001290008211d20011035201f10012201290000211e2001290008211f200110352003201f370390052003201e370388052003201d370380052003201c3703f80420032002410020061b220241016a3602c007200341f8046aad4280808080800484200341c0076aad4280808080c000841002200341c0076a41186a2222200341f0036a41186a290300370300200341c0076a41106a2223200341f0036a41106a290300370300200341c0076a41086a2224200341f0036a41086a290300370300200320032903f0033703c007200341f8046a200210b506200335028005211c20032802f8042106412010332201450d15200120032903c007370000200141186a2022290300370000200141106a2023290300370000200141086a20242903003700002001412041c00010372201450d1520012005370020200141286a2004370000200141c00041800110372201450d152001201a37005020012017370048200120133a0047200120123a0046200120113b0044200120103a00432001200f3a00422001200e3b00402001200d3a003f2001200c3a003e2001200b3b003c2001200a3a003b200120093a003a200120083b0038200120073a0037200120193a0036200120183b0034200120163a0033200120153a0032200120143b0030200141d8006a201b370000201c4220862006ad842001ad4280808080800c84100220011035024020032802fc04450d00200610350b200341c8076a41003a00002003410c3a00c007200341c0076a410c6a200236020041b0b4cc004100200341c0076a10d4010c120b200241036a2d0000210620022f00012107200141046a28020021090240024002400240024020022d00002208417f6a220141024b0d00024020010e03000102000b200241086a2802004102490d00200241046a28020041ff0171450d010b4182a2042101200720064110747220084100477241ff01710d010b4186f0cb00ad4280808080800184100122012d000f210b20012d000e210c20012f000c210d20012d000b210e20012d000a210f20012f0008211020012d0007211120012d0006211220012f0004211320012d0003211420012d0002211520012f00002116200110354180eaca00ad428080808090018410012201290008210520012d0007211820012d0006211920012f0004212220012d0003212320012d0002212420012f0000212520011035200320093602c0012003200341c0016aad4280808080c00084100322012900003703800620011035200341cc076a200341c4016a360200200320034188066a3602c4072003200341c0016a3602c807200320034180066a3602c007200341f0036a200341c0076a107b20032802f803220841206a2202417f4c0d0c20032802f003210a0240024020020d0041002106410121010c010b200210332201450d0c200221060b024002402006410f4d0d00200621070c010b200641017422074110200741104b1b22074100480d0a024020060d002007103322010d010c190b20062007460d0020012006200710372201450d180b2001200b3a000f2001200c3a000e2001200d3b000c2001200e3a000b2001200f3a000a200120103b0008200120113a0007200120123a0006200120133b0004200120143a0003200120153a0002200120163b00000240024020074170714110460d00200721060c010b200741017422064120200641204b1b22064100480d0a20072006460d0020012007200610372201450d180b20012005370018200120183a0017200120193a0016200120223b0014200120233a0013200120243a0012200120253b001002400240200641606a2008490d00200621070c010b2008415f4b0d0a200641017422072002200720024b1b22074100480d0a20062007460d0020012006200710372201450d180b200141206a200a2008109d081a024020032802f403450d00200a10350b200341c0076a2001200210df02024020032903c00742015222060d002002ad4220862001ad8410070b200341f0036a200341c8076a41e000109d081a200341c0076a200341f0036a41e000109d081a024020060d00200341e8026a200341c0076a41e000109d081a02402007450d00200110350b200341b0066a41066a200341e8026a41e000109d081a200341f8046a200341b0066a41e600109d081a200341e0016a200341f8046a41066a41e000109d081a20032903f00121042003200341f8016a290300221a37038005200320043703f804024002402004201a844200520d00200342003703f803200342003703f0030c010b2003200341e0016a41206a22013602f003200341b0066a2001200341f8046a200341f0036a10a802200341b0066a41206a290300210520032903c806211b024020032903b0064201520d0020032903b806211c200341f8076a200341b0066a41106a290300370300200341f0076a201c370300200341c0076a41086a41003a0000200341c9076a2001290000370000200341d1076a200141086a290000370000200341d9076a200141106a290000370000200341e1076a200141186a290000370000200341033a00c00741b0b4cc004100200341c0076a10d4010b2003201b3703f003200320053703f803201b2005844200520d030b2003200341f0036a36028006200341f0036a21080c030b02402007450d00200110350b4183a20421010b20004200370308200041206a41143602002000411c6a41cfadc800360200200041186a2001360200420121050c150b200320053703f8032003201b3703f0032003200341f0036a36028006200341f0036a21080b42002105200341f8046a41186a220e4200370300200341f8046a41106a22024200370300200341f8046a41086a22014200370300200342003703f80441b6fdc600ad4280808080800184221c10012207290000211b200341b0066a41086a2206200741086a2900003703002003201b3703b0062007103520012006290300370300200320032903b0063703f80441e489c200ad4280808080d0018422171001220a290000211b200341e8026a41086a2207200a41086a2900003703002003201b3703e802200a1035200220032903e802221b370300200341c0076a41086a220a2001290300370300200341c0076a41106a220b201b370300200341c0076a41186a220c2007290300370300200320032903f8043703c007200341386a200341c0076a412010d701200341386a41106a290300211d2003290340211e2003280238210d200841086a290300211f2008290300211b200e42003703002002420037030020014200370300200342003703f804201c10012208290000211c2006200841086a2900003703002003201c3703b0062008103520012006290300370300200320032903b0063703f804201710012206290000211c2007200641086a2900003703002003201c3703e80220061035200220032903e802221c370300200a2001290300370300200b201c370300200c2007290300370300200320032903f8043703c00720034200201d4200200d1b221c201f7d201e4200200d1b2217201b54ad7d221d2017201b7d221b201756201d201c56201d201c511b22011b3703b80620034200201b20011b3703b006200341c0076aad4280808080800484200341b0066aad42808080808002841002200c201a370300200b2004370300200a41033a00002003410c3a00c007200341c0076a410c6a200936020041b0b4cc004100200341c0076a10d4010c120b200241036a2d0000210720022f00012108200141046a28020021010240024020022d00002209417f6a220641024b0d00024020060e03000102000b200241086a2802004104490d00200241046a28020041ff0171450d010b4182a2042102200820074110747220094100477241ff01710d050b200341c0076a200110b506200341d0006a20032802c007220220032802c80741b0b4cc0041004100108a0220032802502106024020032802c407450d00200210350b4183a204210220064101470d044186f0cb00ad42808080808001841001220229000021052002290008210420021035419bf0cb00ad428080808090018410012202290000211a2002290008211b200210352003201b370390052003201a370388052003200437038005200320053703f804200341c0076a200341f8046a10c50202400240024020032802c00722020d0041002107200341003602b806200342043703b0060c010b20032902c4072105200320023602b006200320053702b4062005422088a722062005a72207470d010b200341b0066a2007410110860120032802b406210720032802b006210220032802b80621060b200220064102746a20013602002003200641016a22063602b8064186f0cb00ad42808080808001841001220129000021052001290008210420011035419bf0cb00ad428080808090018410012201290000211a2001290008211b200110352003201b370390052003201a370388052003200437038005200320053703f804024020020d00200341f8046aad428080808080048410070c110b200341203602c4072003200341f8046a3602c00720022006200341c0076a109503200741ffffffff0371450d10200210350c100b2001412c6a280200210c200141286a2802002106200141246a280200210b200341e0016a41186a200141196a290000370300200341e0016a41106a200141116a290000370300200341e0016a41086a200141096a290000370300200320012900013703e0014102210120022d00000d0d20022d00014101470d0d200241196a2d00002101200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210d200241116a2d0000210e200241106a2d0000210f2002410e6a2f010021102002410d6a2d000021112002410c6a2d000021122002410a6a2f01002113200241096a2d00002114200241086a2d00002115200241066a2f01002116200241056a2d00002118200241046a2d00002119200241026a2f0100212220032002411a6a29010037038003200320013a00ff02200320073a00fe02200320083b01fc02200320093a00fb022003200a3a00fa022003200d3b01f8022003200e3a00f7022003200f3a00f602200320103b01f402200320113a00f302200320123a00f202200320133b01f002200320143a00ef02200320153a00ee02200320163b01ec02200320183a00eb02200320193a00ea02200320223b01e8020240200c41818001490d0041c3adc800210a410c21094103210141112108410221070c0f0b200cad221b422086200bad84100922012900002105200141086a2900002104200141106a290000211a200341f0036a41186a200141186a290000370300200341f0036a41106a201a370300200341f0036a41086a2004370300200320053703f00320011035200341c0076a200341f0036a10d206200341f0006a20032802c007220220032802c80741b0b4cc0041004100108a0220032802702101024020032802c407450d00200210350b20014101460d0c2003200341e0016a3602c4072003200341f0036a3602c007200341f8046a200341c0076a10a706200341c0076a200341f8046a10d306200341e8006a20032802c007220220032802c80741b0b4cc0041004100108a0220032802682101024020032802c407450d00200210350b20014101460d0c200341d8006a201b42004280a094a58d1d4200108408200320032903582204428080e983b1de167c2205370380062003200341d8006a41086a2903002005200454ad7c2204370388062003200341e8026a3602a0062003200341e8026a3602c0012003200341c0016a3602c8072003200341a0066a3602c407200320034180066a3602c007200341b0066a200341e8026a200341c0076a108c030240024020032802b0064101470d00200341bc066a2802002109200341b0066a41086a280200210a20032d00b706210220032d00b606210720032d00b506210820032d00b40621010c010b410421010240200341b0066a41086a2903004201520d00200341b0066a41106a290300211a20032802c0012102200341f8076a200341b0066a41186a290300370300200341f0076a201a370300200341c0076a41086a41003a0000200341c9076a2002290000370000200341d1076a200241086a290000370000200341d9076a200241106a290000370000200341e1076a200241186a290000370000200341033a00c00741b0b4cc004100200341c0076a10d4010b0b200141ff01714104470d0e200341c0076a200341f0036a10d20620032802c0072101200320032802c8073602b406200320013602b006200b200c200341b0066a109403024020032802c407450d00200110350b200341f0076a2004370300200341e8076a200537030020034188086a4100360200200341c0076a41106a200341e8026a41086a290300370300200341c0076a41186a200341e8026a41106a290300370300200341e0076a200341e8026a41186a29030037030020034194086a200341f0036a41086a2903003702002003419c086a200341f0036a41106a290300370200200341a4086a200341f0036a41186a290300370200200342013703c007200320032903e8023703c8072003420837038008200341003602f807200320032903f00337028c08200341c4086a200341e0016a41186a290300370200200341bc086a200341e0016a41106a290300370200200341b4086a200341e0016a41086a290300370200200320032903e0013702ac08200341b0066a200341f8046a10d30620032802b0062101200320032802b806360284062003200136028006200341c0076a20034180066a10cd06024020032802b406450d00200110350b200341c0076a41086a41073a0000200341c9076a20032903f804370000200341d1076a200341f8046a41086a290300370000200341d9076a200341f8046a41106a290300370000200341e1076a200341f8046a41186a2903003700002003410c3a00c00741b0b4cc004100200341c0076a10d4012006450d0f200b10350c0f0b200341c0016a41186a200141196a290000370300200341c0016a41106a200141116a290000370300200341c0016a41086a200141096a290000370300200320012900013703c00141022101024002400240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a29010037039806200320013a009706200320063a009606200320073b019406200320083a009306200320093a0092062003200a3b0190062003200b3a008f062003200c3a008e062003200d3b018c062003200e3a008b062003200f3a008a06200320103b018806200320113a008706200320123a008606200320133b018406200320143a008306200320153a008206200320163b018006200341a0066a200341c0016a10d306200341c0076a20032802a006220120032802a80610b20220032903c0072105200341f8046a200341c8076a418801109d081a024020054202510d00200341f0036a200341f8046a418801109d081a024020032802a406450d00200110350b200341e8026a200341f0036a418801109d081a200341e0016a200341e8026a418801109d081a200320053703b006200341b0066a41086a200341e0016a418801109d081a200341f0036a41186a2201200341b0066a41206a290300370300200341f0036a41106a2202200341b0066a41186a290300370300200341f0036a41086a2206200341b0066a41106a290300370300200320032903b8063703f00320054201520d02200341e0066a2903002104200341d8066a290300211a200341c0076a410e6a2006290300370100200341c0076a41166a2002290300370100200341c0076a411e6a20012903002205370100200341f8046a411e6a22072005370100200320032903f0033701c607200341f8046a41086a200341c0076a41086a290100370300200341f8046a41106a200341c0076a41106a290100370300200341f8046a41186a200341c0076a41186a290100370300200320032901c0073703f804200120072901003703002002200341f8046a41166a2901003703002006200341f8046a410e6a290100370300200320032901fe043703f003200341f0036a20034180066a412010a0080d02200341c0076a200341fc066a10d20620033502c80742208620032802c0072201ad841007024020032802c407450d00200110350b200341c0076a200341c0016a10d30620033502c80742208620032802c0072201ad841007024020032802c407450d00200110350b2003201a3703e802200320043703f0020240201a200484500d00200320034180066a3602e001200341f8046a20034180066a200341e8026a200341e0016a10f00220032903f8044201520d002003290380052105200341f8076a200341f8046a41106a290300370300200341f0076a2005370300200341c0076a41086a41003a0000200341c9076a200329038006370000200341d1076a20034180066a41086a290300370000200341d9076a20034180066a41106a290300370000200341e1076a20034198066a290300370000200341033a00c00741b0b4cc004100200341c0076a10d4010b200341c0076a41086a410a3a0000200341c9076a20032903c001370000200341d1076a200341c0016a41086a290300370000200341d9076a200341d0016a290300370000200341e1076a200341d8016a2903003700002003410c3a00c00741b0b4cc004100200341c0076a10d401200341f4066a2802002201450d13200141306c450d1320032802f00610350c130b024020032802a406450d00200110350b41adadc8002102410a21064180801021070c020b410021070c020b41a4adc800210241092106418080142107200341f4066a2802002201450d00200141306c450d0020032802f00610350b410321010b20004200370308200041206a20063602002000411c6a2002360200200041186a20074180801c7120017241802272360200420121050c100b200141386a2903002105200141306a29030021042001412c6a2802002108200141286a2802002106200141246a280200210720034180036a200141196a290000370300200341f8026a200141116a290000370300200341f0026a200141096a290000370300200320012900013703e80220032002411a6a290100370390052003200241026a2901003703f80420032002410a6a290100370380052003200241126a290100370388050240024020022d00014101470d0020022d000041ff01710d00200341f0036a41186a200341f8046a41186a2202290300370300200341f0036a41106a200341f8046a41106a2209290300370300200341f0036a41086a200341f8046a41086a220a290300370300200320032903f8043703f0034182a20c2101200341f0036a10e902450d0b2008ad4220862007ad8410092201290000211a200141086a290000211b200141106a290000211c2002200141186a2900003703002009201c370300200a201b3703002003201a3703f80420011035200341c0076a200341f8046a10d206200341f8006a20032802c007220220032802c80741b0b4cc0041004100108a0220032802782101024020032802c407450d00200210350b20014101460d012003200341e8026a3602c4072003200341f8046a3602c007200341b0066a200341c0076a10a706200341c0076a200341f8046a10d20620032802c0072101200320032802c8073602e401200320013602e00120072008200341e0016a109403024020032802c407450d00200110350b20032903b006211a20032903b806211b20032903c006211c200341e1076a20032903c806370000200341d9076a201c370000200341d1076a201b370000200341c9076a201a370000200341c0076a41086a41073a00002003410c3a00c00741b0b4cc004100200341c0076a10d401413010332201450d1220012004370320200120032903f003370000200141286a2005370300200141186a200341f0036a41186a290300370000200141106a200341f0036a41106a290300370000200141086a200341f0036a41086a29030037000020034184086a42818080801037020020034194086a200341f8046a41086a2903003702002003419c086a200341f8046a41106a290300370200200341a4086a200341f8046a41186a2903003702002003200136028008200341003602f807200342003703c007200320032903f80437028c08200341b4086a200341e8026a41086a290300370200200341bc086a200341e8026a41106a290300370200200341c4086a200341e8026a41186a290300370200200320032903e8023702ac08200341e0016a200341b0066a10d30620032802e0012102200320032802e801360284062003200236028006200341c0076a20034180066a10cd06024020032802e401450d00200210350b200110352006450d0f200710350c0f0b4182a20c21010c0a0b4183a20c21010c090b200141306a2903002105200141286a2903002104200341c0016a41186a200141196a290000370300200341c0016a41106a200141116a290000370300200341c0016a41086a200141096a290000370300200320012900013703c0014182a21021010240024002400240024002400240024020022d00000d0020022d00014101470d00200241196a2d00002106200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211820032002411a6a29010037039806200320063a009706200320073a009606200320083b019406200320093a0093062003200a3a0092062003200b3b0190062003200c3a008f062003200d3a008e062003200e3b018c062003200f3a008b06200320103a008a06200320113b018806200320123a008706200320133a008606200320143b018406200320153a008306200320163a008206200320183b01800620034180066a10e902450d00200341f8046a41186a200341c0016a41186a290300370300200341f8046a41106a200341c0016a41106a290300370300200341f8046a41086a200341c0016a41086a290300370300200320032903c0013703f804200341a0066a200341f8046a10d406200341c0076a20032802a006220120032802a80610b20220032903c007211a200341f8046a200341c0076a41086a418801109d081a0240201a4202510d00200341f0036a200341f8046a418801109d081a024020032802a406450d00200110350b200341e8026a200341f0036a418801109d081a200341e0016a200341e8026a418801109d081a2003201a3703b006200341b0066a41086a200341e0016a418801109d081a200341f0036a41186a20034180066a41186a290300370300200341f0036a41106a20034180066a41106a290300370300200341f0036a41086a20034180066a41086a29030037030020032003290380063703f00320032802f006210841002101200341f8066a280200220d41014b0d020240200d0e020004000b200341c0076a41186a200341f0036a41186a290300370300200341c0076a41106a200341f0036a41106a290300370300200341c0076a41086a200341f0036a41086a290300370300200320032903f0033703c00741002106200341c0076a21020c040b024020032802a406450d00200110350b4183a21021010b200041206a410a3602002000411c6a41adadc800360200200041186a200136020020004200370308420121050c150b200d210203402002410176220620016a220720012008200741306c6a200341f0036a412010a0084101481b2101200220066b220241014b0d000b0b2008200141306c6a2202200341f0036a412010a0082206450d01200341c0076a41186a200341f0036a41186a290300370300200341c0076a41106a200341f0036a41106a290300370300200341c0076a41086a200341f0036a41086a290300370300200320032903f0033703c007200341c0076a2102200d2006411f7620016a2206490d040b0240200d200341f4066a280200470d00200341f0066a200d410110880120032802f00621080b2008200641306c6a220141306a2001200d20066b41306c109e081a200141286a200537030020012004370320200141186a200241186a290300370300200141106a200241106a290300370300200141086a200241086a290300370300200120022903003703002003200d41016a220d3602f8060c010b200d20014d0d0120032901f203211a20032901fa03211b200328018204210620032f0186042107200329038804211c200220032f01f0033b01002008200141306c6a220120043703202001201c370318200120073b0116200120063601122001201b37010a2001201a370102200141286a20053703000b200341c0076a10e80220032802c00721250240200d450d00202520032802c80722014105746a210920032802f006210e2025410020011b2102202541206a202520011b21014100210c4100210a0340200a220b41016a210a200e200b41306c6a2108024002400340024020020d00410021020c020b20022008412010a008220641004a0d0141002001200120094622071b21022001200141206a20071b2207210120064100480d000b024002400240200c0d004100210c0c010b200b200c6b2201200d4f0d01200341f8046a41286a2206200e200141306c6a220141286a220b290300370300200341f8046a41206a220f200141206a2210290300370300200341f8046a41186a2211200141186a2212290300370300200341f8046a41106a2213200141106a2214290300370300200341f8046a41086a2215200141086a2216290300370300200320012903003703f804200841086a22182903002105200841106a22192903002104200841186a2222290300211a200841206a2223290300211b2008290300211c200b200841286a22242903003703002010201b3703002012201a37030020142004370300201620053703002001201c370300202420062903003703002023200f290300370300202220112903003703002019201329030037030020182015290300370300200820032903f8043703000b200721010c020b2001200d41f485cc001042000b200c41016a210c0b200a200d470d000b200c417f6a200d4f0d002003200d200c6b3602f8060b024020032802c40741ffffff3f71450d00202510350b200341f8046a41186a4200370300200341f8046a41106a22064200370300200341f8046a41086a22014200370300200342003703f80441a0e4cb00ad42808080808002841001220229000021052001200241086a290000370300200320053703f804200210354189eaca00ad4280808080f00084100122022900002105200341e8026a41086a2207200241086a290000370300200320053703e80220021035200620032903e8022205370300200341c0076a41086a2001290300370300200341c0076a41106a2005370300200341c0076a41186a2007290300370300200320032903f8043703c007200341f8046a200341c0076a10a20220032802f804210120032902fc042105200341003602c807200342013703c007200341c0076a41002005420020011b2205422088a7220241306c220741306d108a012005a721082001410820011b210920032802c807210602402002450d0020032802c00720064105746a2101200921020340200241086a2900002105200241106a29000021042002290000211a200141186a200241186a290000370000200141106a2004370000200141086a20053700002001201a370000200641016a2106200141206a2101200241306a2102200741506a22070d000b0b200320063602c80702402008450d00200841306c450d00200910350b024020032802c40741ffffff3f71450d0020032802c00710350b024020032802f806200641016a410176490d0020032802e8064101460d00200341c0076a41186a4200370300200341c0076a41106a22064200370300200341c0076a41086a22014200370300200342003703c00741d1c4c700ad4280808080e000841001220229000021052001200241086a290000370300200320053703c0072002103541e7c4c700ad4280808080e00084100122022900002105200341e8026a41086a2207200241086a290000370300200320053703e80220021035200620032903e8022205370300200341f8046a41086a22022001290300370300200341f8046a41106a22062005370300200341f8046a41186a22082007290300370300200320032903c0073703f80420034180016a200341f8046a412010c001200341ec066a2003280284014180e1016a4180e1012003280280011b360200200341013602e8062008200341c0016a41186a22072903003703002006200341c0016a41106a22082903003703002002200341c0016a41086a2206290300370300200320032903c0013703f804200141083a00002003410c3a00c007200341c9076a20032903c001370000200341d1076a2006290300370000200341d9076a2008290300370000200341e1076a200729030037000041b0b4cc004100200341c0076a10d4010b200341c0076a200341b0066a419001109d081a200341f8046a200341c0016a10d30620032802f804210120032003280280053602f403200320013602f003200341c0076a200341f0036a10cd06024020032802fc04450d00200110350b20034184086a2802002201450d0e200141306c450d0e20032802800810350c0e0b2001200d41bc82ca001042000b2006200d104d000b20004200370308200041206a41143602002000411c6a41cfadc800360200200041186a2002360200420121050c0d0b103e000b4104210741adadc8002108410a2109410221060240024020022d00000d0020022d00014101470d00200141186a2d00002126200141176a2d00002127200141156a2f00002128200141146a2d00002129200141136a2d0000212a200141116a2f0000212b200141106a2d0000212c2001410f6a2d0000212d2001410d6a2f0000212e2001410c6a2d0000212f2001410b6a2d00002130200141096a2f00002131200141086a2d00002132200141076a2d00002133200141056a2f00002134200141046a2d00002135200141036a2d0000213620012f000121372003200141196a290000221737039005200320263a008f05200320273a008e05200320283b018c05200320293a008b052003202a3a008a052003202b3b0188052003202c3a0087052003202d3a0086052003202e3b0184052003202f3a008305200320303a008205200320313b018005200320323a00ff04200320333a00fe04200320343b01fc04200320353a00fb04200320363a00fa04200320373b01f80420034180066a200341f8046a10d406200341c0076a200328028006220120032802880610b20220032903c0072105200341f8046a200341c8076a418801109d081a024002400240024020054202510d00200341f0036a200341f8046a418801109d081a0240200328028406450d00200110350b200341e8026a200341f0036a418801109d081a200341e0016a200341e8026a418801109d081a200320053703b006200341b0066a41086a200341e0016a418801109d081a20032802e8064101460d01419badc8002108410621070c020b200328028406450d02200110350c020b200341c0076a41186a4200370300200341c0076a41106a22064200370300200341c0076a41086a22014200370300200342003703c00741d1c4c700ad4280808080e000841001220229000021052001200241086a290000370300200320053703c0072002103541e7c4c700ad4280808080e00084100122022900002105200341e8026a41086a2207200241086a290000370300200320053703e80220021035200620032903e8022205370300200341f8046a41086a2001290300370300200341f8046a41106a2005370300200341f8046a41186a2007290300370300200320032903c0073703f804200341b8016a200341f8046a412010c00120032802bc01410020032802b8011b200341ec066a2802004f0d034192adc8002108410721070b0240200341f4066a2802002201450d00200141306c450d0020032802f00610350b410921090b410321060b20004200370308200041206a20093602002000411c6a2008360200200041186a200741107420067241802272360200420121050c0c0b200341c0076a200341fc066a10d20620033502c80742208620032802c0072201ad841007024020032802c407450d00200110350b200320173703d807200320263a00d707200320273a00d607200320283b01d407200320293a00d3072003202a3a00d2072003202b3b01d0072003202c3a00cf072003202d3a00ce072003202e3b01cc072003202f3a00cb07200320303a00ca07200320313b01c807200320323a00c707200320333a00c607200320343b01c407200320353a00c307200320363a00c207200320373b01c007200341f8046a200341c0076a10d40620033502800542208620032802f8042201ad841007024020032802fc04450d00200110350b200341c0076a200341b0066a419001109d081a20034188086a280200211620034184086a28020021382003280280082112200341f0036a10e80220032802f00321250240024020160d00410021160c010b202520032802f80322014105746a21092025410020011b2102202541206a202520011b21014100210c4100210a0340200a220b41016a210a2012200b41306c6a2108024002400340024020020d00410021020c020b20022008412010a008220641004a0d0141002001200120094622071b21022001200141206a20071b2207210120064100480d000b024002400240200c0d004100210c0c010b200b200c6b220120164f0d01200341f8046a41286a22062012200141306c6a220141286a220b290300370300200341f8046a41206a220d200141206a220e290300370300200341f8046a41186a220f200141186a2210290300370300200341f8046a41106a2211200141106a2213290300370300200341f8046a41086a2214200141086a2215290300370300200320012903003703f804200841086a22182903002105200841106a22192903002104200841186a2222290300211a200841206a2223290300211b2008290300211c200b200841286a2224290300370300200e201b3703002010201a37030020132004370300201520053703002001201c370300202420062903003703002023200d2903003703002022200f2903003703002019201129030037030020182014290300370300200820032903f8043703000b200721010c020b2001201641f485cc001042000b200c41016a210c0b200a2016470d000b200c450d0020162016200c6b220120162001491b21160b024020032802f40341ffffff3f71450d00202510350b20164115490d032016410176ad42307e2205422088a70d012005a72239417f4c0d0120391033223a450d0041002102200341003602f803200342043703f003201241506a213b201241907f6a213c410421064100213d20162111034020112109410021114101210a02402009417f6a223e450d000240024002400240024002402012203e41306c6a220141206a290300200941306c220820126a41406a2207290300220454200141286a290300221a200741086a290300220554201a2005511b0d002009417e6a210c203c20086a2101410021114100210703400240200c2007470d002009210a0c080b20042001290300221b5a21082005200141086a290300221a51210a2005201a5a210b200141506a2101200741016a2107201b2104201a21052008200b200a1b0d000b200741016a210a2007417f7320096a21080c010b203c200941066c410374220c6a2101203e210802400340024020084101470d00410021080c020b20042001290300221b5421072005200141086a290300221a51210a2005201a54210b200141506a21012008417f6a2108201b2104201a21052007200b200a1b0d000b0b20092008490d02200920164b0d01200920086b220a410176220b450d00203b200c6a21012012200841306c6a21070340200341f8046a41286a220c200741286a220d290300370300200341f8046a41206a220e200741206a220f290300370300200341f8046a41186a2210200741186a2211290300370300200341f8046a41106a2213200741106a2214290300370300200341f8046a41086a2215200741086a2218290300370300200320072903003703f804200141086a22192903002105200141106a22222903002104200141186a2223290300211a200141206a2224290300211b200141286a2225290300211c20072001290300370300200d201c370300200f201b3703002011201a37030020142004370300201820053703002025200c2903003703002024200e290300370300202320102903003703002022201329030037030020192015290300370300200120032903f804370300200141506a2101200741306a2107200b417f6a220b0d000b0b024020080d00200821110c050b0240200a41094d0d00200821110c050b200920164b0d022012200841306c6a210d034020092008417f6a2211490d040240200920116b220a4102490d002012200841306c6a220141206a220b2903002012201141306c6a220741206a220c290300221a5a200141286a220e2903002204200741286a220f29030022055a20042005511b0d002007290300210420072001290300370300200341f8046a41186a2210200741186a2213290300370300200341f8046a41106a2214200741106a2215290300370300200341f8046a41086a2218200741086a22192903003703002019200141086a2903003703002015200141106a2903003703002013200141186a290300370300200c200b290300370300200f200e290300370300200320043703f8040240200a4103490d00203e210b200d210c20074180016a290300201a5a20074188016a290300220420055a20042005511b0d0002400340200c220141286a200141d8006a290300370300200141206a200141d0006a290300370300200141186a200141c8006a290300370300200141106a200141c0006a290300370300200141086a200141386a2903003703002001200141306a220c2903003703002008200b417f6a220b460d0120014180016a290300201a5a20014188016a290300220420055a20042005511b450d000b0b200141306a21010b2001201a370320200120032903f804370300200141286a2005370300200141186a2010290300370300200141106a2014290300370300200141086a20182903003703000b2011450d05200d41506a210d20112108200a410a4f0d050c000b0b2009201641eccfca001058000b2008200941eccfca001059000b20092008417f6a2211490d002009201641fccfca001058000b2011200941fccfca001059000b0240203d20032802f403470d00200341f0036a203d410110900120032802f003210620032802f8032202213d0b2006203d4103746a2201200a360204200120113602002003200241016a22023602f8032002213d024020024102490d000240024003400240024002400240024020062002417f6a4103746a2201280200450d00200241037420066a220941746a2802002208200128020422074b0d010b20024103490d022001280204210720062002417d6a220e4103746a28020421010c010b4102213d200241024d0d0620062002417d6a220e4103746a2802042201200720086a4d0d004103213d200241034d0d06200941646a280200200120086a4b0d050b20012007490d010b2002417e6a210e0b02400240024002400240024002402002200e41016a220f4d0d002002200e4d0d012006200e41037422136a2201280204221420012802006a22012006200f41037422156a22022802002210490d02200120164b0d032012201041306c6a220c2002280204220d41306c22026a2107200141306c2106200120106b2209200d6b2201200d4f0d04203a2007200141306c2202109d08220920026a2108200d4101480d0520014101480d05203b20066a21062007210103402006200141506a220a200841506a220b200841706a2202290300200141706a220729030054200241086a2903002205200741086a29030022045420052004511b22071b2202290300370300200641086a200241086a290300370300200641106a200241106a290300370300200641186a200241186a290300370300200641206a200241206a290300370300200641286a200241286a2903003703002008200b20071b21080240200c200a200120071b2201490d00200921020c080b200641506a21062009210220092008490d000c070b0b200f2002418cd0ca001042000b200e2002419cd0ca001042000b2010200141acd0ca001059000b2001201641acd0ca001058000b203a200c2002109d08220b20026a21080240200d4101480d002009200d4c0d00201220066a210a200b2102200c21010340200120072002200741206a290300200241206a29030054200741286a2903002205200241286a29030022045420052004511b22091b2206290300370300200141086a200641086a290300370300200141106a200641106a290300370300200141186a200641186a290300370300200141206a200641206a290300370300200141286a200641286a2903003703002002200241306a20091b2102200141306a2101200741306a200720091b2207200a4f0d03200820024b0d000c030b0b200c2101200b21020c010b20072101200921020b20012002200820026b220620064130706b109d081a024020032802f8032201200e4d0d0020032802f003220620136a22022014200d6a360204200220103602002001200f4d0d02200620156a2202200241086a2001200f417f736a410374109e081a20032001417f6a22023602f803200241014b0d010c030b0b200e200141bcd0ca001042000b200f2001104e000b2002213d0b2011450d030c000b0b1045000b1044000b024020032802f40341ffffffff0171450d00200610350b2039413070210120394130490d0120392001460d01203a10350c010b20164102490d002016417f6a21062012201641306c6a2108410021090340024002400240201620062201417f6a2206490d00201620066b22074102490d022012200141306c6a220141206a220a2903002012200641306c6a220241206a220b290300221a5a200141286a220c2903002204200241286a220d29030022055a20042005511b0d022002290300210420022001290300370300200341f8046a41186a220e200241186a220f290300370300200341f8046a41106a2210200241106a2211290300370300200341f8046a41086a2213200241086a22142903003703002014200141086a2903003703002011200141106a290300370300200f200141186a290300370300200b200a290300370300200d200c290300370300200320043703f80420074103490d01200921072008210a20024180016a290300201a5a20024188016a290300220420055a20042005511b0d010340200a220141506a22022001290300370300200241286a200141286a290300370300200241206a200141206a290300370300200241186a200141186a290300370300200241106a200141106a290300370300200241086a200141086a2903003703002007417f6a2207450d02200141306a210a200141d0006a290300201a5a200141d8006a290300220420055a20042005511b0d020c000b0b2006201641dccfca001059000b2001201a370320200120032903f804370300200141286a2005370300200141186a200e290300370300200141106a2010290300370300200141086a20132903003703000b200941016a2109200841506a210820060d000b0b200342f0f2bda1a7ee9cb9f9003703f804200341e0016a200341f8046a10e001200342f0f2bda1a7ee9cb9f9003703f804200341f0036a200341f8046a10e001200341e8026a200341f0036a108e02200341f8046a20032802e802220120032802f002108f0220032903f804210520034188056a2903002104200329038005211a024020032802ec02450d00200110350b02402016201641017622014d0d00420020044200200542015122021b2204201a420020021b2205428080e983b1de1654ad7d221a200542808097fccea1697c221b200556201a200456200542ffffe883b1de16561b22021b22052012200141306c6a220141286a29030022042001290320221a4200201b20021b221b56200420055620042005511b22011b2104201b201a20011b2105024020032903c0074201520d00200341e8026a41186a200341c0076a41206a290300370300200341e8026a41106a200341c0076a41186a290300370300200341f0026a200341c0076a41106a290300370300200320032903c8073703e802200341c0076a41286a290300211a2003200341c0076a41306a290300221b370388062003201a370380060240201a201b84500d002003200341e8026a3602c001200341f0036a200341e8026a20034180066a200341c0016a10f00220032903f0034201520d0020032903f803211a200341b0056a200341f0036a41106a290300370300200341a8056a201a370300200341f8046a41086a41003a000020034181056a20032903e80237000020034189056a200341e8026a41086a29030037000020034191056a200341e8026a41106a29030037000020034199056a20034180036a290300370000200341033a00f80441b0b4cc004100200341f8046a10d4010b200341e8026a200341ac086a412010a008450d00200341a8016a2005200442e400420010980820034198016a20032903a801221a200341a8016a41086a290300221b429c7f427f10840820034188016a201a201b42144200108408200341f8046a200341e0016a200341e8026a200329038801221b20052003290398017ca741ff0071220141056e2202200141146c2002419c7f6c6a41fcff037141324b6aad7c221a20034188016a41086a290300201a201b54ad7c221b410010e6022004201b7d2005201a54ad7d21042005201a7d21050b200341f8046a200341e0016a200341ac086a20052004410010e60220034199056a201737000020034198056a20263a000020034197056a20273a000020034195056a20283b000020034194056a20293a000020034193056a202a3a000020034191056a202b3b000020034190056a202c3a00002003418f056a202d3a00002003418d056a202e3b00002003418c056a202f3a00002003418b056a20303a000020034189056a20313b000020034188056a20323a000020034187056a20333a000020034185056a20343b000020034183056a20363a0000200341f8046a41096a20373b000020034180056a41093a00002003410c3a00f804200341f8046a410c6a20353a0000200341c8056a2005370300200341d0056a2004370300200341b9056a200341c4086a290200370000200341b1056a200341bc086a290200370000200341a9056a200341b4086a290200370000200341a1056a20032902ac0837000041b0b4cc004100200341f8046a10d4012038450d05203841306c450d05201210350c050b2001201641cc82ca001042000b02402006450d00200710350b20004200370308200041206a410c3602002000411c6a41b7adc800360200200041186a2001360200420121050c050b41b7adc800210a410c21094111210841032107410321010c010b0b02402006450d00200b10350b20004200370308200041206a20093602002000411c6a200a360200200041186a2002411874200741ff017141107472200841ff017141087472200141ff017172360200420121050c020b420021050b200020053703080b20002005370300200341d0086a24000f0b103c000bbd930106147f027e0c7f017e027f017e230041e0046b22042400200441c0036a20012002200310ed06200441c0036a41086a280200210520042802c40321060240024002400240024020042802c0034101460d00200441d4036a280200220741306c2108200441d8036a2802002109200441d0036a280200210a200441cc036a280200210b4100210c4100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004102470d000b200441d8006a200b200d6a41546a10bf032004280258210c200428025c21010b4100210e20014100200c1b210f200741306c2108200c41b0b4cc00200c1b21104100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004108470d000b200441d0006a200b200d6a41546a10bf032004280250210e200428025421010b4100211120014100200e1b2112200741306c2108200e41b0b4cc00200e1b210c4100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004104470d000b200441c8006a200b200d6a41546a10bf0320042802482111200428024c21010b4100210e2001410020111b2113200741306c2108201141b0b4cc0020111b21114100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004103470d000b200441c0006a200b200d6a41546a10bf032004280240210e200428024421010b41002102024020014100200e1b2201450d00200141286c2108200e41b0b4cc00200e1b41186a2101410021020340200220012d0000456a2102200141286a2101200841586a22080d000b0b024020120d00411e210120004185d6cb003602040c030b200c201241146c6a211241002114410021150240034041a3d6cb00210841382101200c41086a280200417c6a220e41024b0d01200c280200210d024002400240200e0e03000401000b41012115200d41fbd5cb00460d01200d28000041e3c2b1e306460d010c030b41012114200d41ffd5cb00460d00200d41ffd5cb00410610a0080d020b0240200c410c6a280200450d0041132101200041a1d7cb003602040c050b0240200c41106a280200220120026b220d20014d0d00412a2101200041b4d7cb003602040c050b41fbd6cb002108412621012013200d4d0d012011200d4102746a220d450d0141dbd6cb00210841202101200f200d280200220d4d0d012010200d4104746a220d450d0141ded7cb002108411f2101200d2802080d01200d2d000d220d41077141044b0d010240200d0e050002020200000b200c41146a220c2012470d000b20142015714101710d02411c411e201441017122021b2101200041fdd7cb004185d6cb0020021b3602040c030b200020083602040c020b2000200636020420004101360200200041086a20053602000c030b200741306c2108410021010240024002400240034020082001460d01200b20016a2102200141306a220d210120022d00004106470d000b200441386a200b200d6a41546a10bf03200428023c0d010b200741306c2108200328028001210c410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004105470d000b200441306a200b200d6a41546a220110bf030240200428023441014d0d0041182101200041e8d3cb003602040c050b200441286a200110bf03200428022c450d0020042802282201450d002001280200200c4d0d004122210120004180d4cb003602040c040b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004107470d000b200441206a200b200d6a41546a10bf032004280220220120042802244104746a2108034020012008460d012001450d012001410c6a2102200141106a210120022d0000410271450d000b413221012000418cd5cb003602040c040b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d0000410c470d000b200b200d6a2201415c6a2802002202450d00200141546a280200220d200241186c6a210c0340200d220241186a210d2002280208410374210120022802002102024003402001450d01200141786a210120022d00042108200241086a21022008410271450d000b41312101200041dbd4cb003602040c060b200d200c470d000b0b200741306c2108410021010240034020082001460d01200b20016a2102200141306a220d210120022d00004102470d000b200441186a200b200d6a41546a10bf03200428021c2201450d002004280218220220014104746a210e03402002450d01200241106a210c200420022d000d22083a00c0032002280200220120022802086a210d4100200441c0036a20084104461b210802400340024002402001450d00200d2001460d0020012102200141016a21010c010b2008450d024100210120082102410021080b20022d0000410271450d000b41392101200041a2d4cb003602040c060b200c2102200c200e470d000b0b200741306c21084100210c4100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004102470d000b200441106a200b200d6a41546a10bf032004280210210c200428021421010b4100210e20014100200c1b2110200741306c2108200c41b0b4cc00200c1b21124100210102400340024020082001470d000c020b200b20016a2102200141306a220d210120022d00004103470d000b200441086a200b200d6a41546a10bf032004280208210e200428020c21010b200e41b0b4cc00200e1b220220014100200e1b41286c6a210d41002113034002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402002200d460d00412d210141ecbcca00210820022802084103470d0902402002280200220c41a58ecc00460d00200c41a58ecc00410310a0080d0a0b200241286a21114115210c41e5bbca00210e4114210141d8bcca0021080240024020022d00180e04010b0022010b412f21014199bdca00210820022802144106470d0a0240200228020c220c41a9bbca00460d00200c41a9bbca00410610a0080d0b0b2013450d02411f2101200041c8bdca003602040c270b4136210c41afbbca00210e2010200228021c22014d0d20201220014104746a220f450d202002280214210c200228020c2102024020092d0088010d00200c410b470d004138210141a0bcca002108200241bfe2cb00460d0a200241bfe2cb00410b10a008450d0a0c200b4126210141fabbca002108200c417d6a220c41144b0d09024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200c0e15003030301208300d46060b160118031f1430101d21000b200241a88ecc00460d2f200241a88ecc00410310a008450d2f41a88ecc002002410310a0080d2f41011033220e0d010c4d0b200241c6dfcb00460d0241c6dfcb002002410f10a008450d02200241e6dfcb00460d0541e6dfcb002002410f10a008450d05024020024189e0cb00460d004189e0cb002002410f10a0080d2f0b41071033220e450d4c200e4100360003200e41013a0002200e41003b0000200f2d000c41e000460d0a0c430b200e41003a0000200f2d000c41e000470d41200f2802084101470d410240200f2802002214200e460d0041002102034020024101460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d430c000b0b200f2d000d4104470d41200e1035201121020c460b200241d5dfcb00460d0141d5dfcb002002411110a008450d01200241b6e1cb00460d1341b6e1cb002002411110a008450d13200241f5e1cb00460d1841f5e1cb002002411110a008450d1820024186e2cb00460d1a4186e2cb002002411110a008450d1a0240200241f1e2cb00460d0041f1e2cb002002411110a0080d2d0b41031033220e450d4a200e41003a0002200e41003b0000200f2d000c41e000460d1f0c3f0b41031033220e450d49200e41003a0002200e41003b0000200f2d000c41e000470d3d200f2802084103470d3d0240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d3f0c000b0b200f2d000d4104470d3d200e1035201121020c440b41011033220e450d48200e41003a0000200f2d000c41e000470d3b200f2802084101470d3b0240200f2802002214200e460d0041002102034020024101460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d3d0c000b0b200f2d000d4104470d3b200e1035201121020c430b200241f5dfcb00460d0241f5dfcb002002410c10a008450d020240200241d1e0cb00460d0041d1e0cb002002410c10a0080d2a0b4126210c41fabbca00210e200f2d000c41e000470d40200f2802080d4020112102200f2d000d4104460d420c400b41011033220e450d46200e41003a0000200f2d000c41e000470d38200f2802084101470d38200f2802002214200e460d3741002102034020024101460d38200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d390c000b0b024020024181e0cb00460d00200229000042e5f0d1fbb5ac98b6ec00520d280b41071033220e450d45200e4100360003200e41013a0002200e41003b0000200f2d000c41e000460d010c350b41041033220e450d44200e4100360000200f2d000c41e000470d33200f2802084104470d33200f2802002214200e460d3241002102034020024104460d33200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d340c000b0b200f2802084107470d33200f2802002214200e460d3041002102034020024107460d31200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d340c000b0b20024198e0cb00460d024198e0cb002002410d10a008450d020240200241c4e0cb00460d0041c4e0cb002002410d10a0080d250b4126210c41fabbca00210e200f2d000c41e000470d3b200f2802080d3b20112102200f2d000d4104460d3d0c3b0b200f2802084107470d38200f2802002214200e460d2d41002102034020024107460d2e200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d390c000b0b200241a5e0cb00460d0141a5e0cb002002410a10a008450d010240200241afe0cb00460d0041afe0cb002002410a10a0080d040b4126210c41fabbca00210e200f2d000c41e000470d39200f2802080d3920112102200f2d000d4104460d3b0c390b41021033220e450d3f200e41003b0000200f2d000c41e000470d2a200f2802084102470d2a0240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d2c0c000b0b200f2d000d4104470d2a200e1035201121020c3a0b41021033220e450d3e200e41003b0000200f2d000c41e000470d28200f2802084102470d280240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d2a0c000b0b200f2d000d4104470d28200e1035201121020c390b0240200241e8e0cb00460d0041e8e0cb002002411510a0080d050b4126210c41fabbca00210e200f2d000c41e000470d36200f2802080d3620112102200f2d000d4104460d380c360b0240200241fde0cb00460d0041fde0cb002002410a10a0080d1f0b41021033220e450d3c200e41003b0000200f2d000c41e000460d010c250b024020024187e1cb00460d004187e1cb002002410710a0080d1e0b4126210c41fabbca00210e200f2d000c41e000470d34200f2802080d3420112102200f2d000d4104460d360c340b200f2802084102470d230240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d250c000b0b200f2d000d4104470d23200e1035201121020c350b02402002418ee1cb00460d00418ee1cb002002411310a0080d0e0b4126210c41fabbca00210e200f2d000c41e000470d32200f2802080d3220112102200f2d000d4104460d340c320b0240200241a1e1cb00460d0041a1e1cb002002411510a0080d1b0b4126210c41fabbca00210e200f2d000c41e000470d31200f2802080d3120112102200f2d000d4104460d330c310b0240200241c7e1cb00460d0041c7e1cb002002410e10a0080d1a0b41081033220e450d37200e4200370000200f2d000c41e000460d020c1f0b41021033220e450d36200e41003b0000200f2d000c41e000470d1d200f2802084102470d1d0240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1f0c000b0b200f2d000d4104470d1d200e1035201121020c310b200241d5e1cb00460d0141d5e1cb002002411010a008450d01200241e5e1cb00460d0241e5e1cb002002411010a008450d020240200241cae2cb00460d0041cae2cb002002411010a0080d180b4126210c41fabbca00210e200f2d000c41e000470d2e200f2802080d2e20112102200f2d000d4104460d300c2e0b200f2802084108470d1c0240200f2802002214200e460d0041002102034020024108460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1e0c000b0b200f2d000d4104470d1c200e1035201121020c2f0b4126210c41fabbca00210e200f2d000c41e000470d2c200f2802080d2c200f2d000d22014104460d2c20112102200141fb0171450d2e0c2c0b41031033220e450d32200e41003a0002200e41003b0000200f2d000c41e000470d18200f2802084103470d180240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d1a0c000b0b200f2d000d4104470d18200e1035201121020c2d0b41021033220e450d31200e41003b0000200f2d000c41e000470d16200f2802084102470d160240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d180c000b0b200f2d000d4104470d16200e1035201121020c2c0b024020024197e2cb00460d004197e2cb002002411610a0080d130b41021033220e450d30200e41003b0000200f2d000c41e000460d020c140b41041033220e450d2f200e4100360000200f2d000c41e000470d12200f2802084104470d120240200f2802002214200e460d0041002102034020024104460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d140c000b0b200f2d000d4104470d12200e1035201121020c2a0b0240200241ade2cb00460d0041ade2cb002002411210a0080d110b4126210c41fabbca00210e200f2d000c41e000470d27200f2802080d2720112102200f2d000d4104460d290c270b200f2802084102470d110240200f2802002214200e460d0041002102034020024102460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d130c000b0b200f2d000d4104470d11200e1035201121020c280b0240200241dae2cb00460d0041dae2cb002002411710a0080d0f0b410210332214450d2c201441003b0000200f2d000c41e000470d0d200f2802084102470d0d200f28020022152014460d0c41002102034020024102460d0d201420026a210c201520026a210e200241016a2102200e2d0000200c2d0000470d0e0c000b0b20024182e3cb00460d014182e3cb002002411310a008450d0120024195e3cb00460d024195e3cb002002411310a008450d020240200241a8e3cb00460d0041a8e3cb002002411310a0080d0e0b41031033220e450d2b200e41003a0002200e41003b0000200f2d000c41e000460d030c0a0b200f2802084103470d1f0240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d210c000b0b200f2d000d4104470d1f200e1035201121020c250b41031033220e450d29200e41003a0002200e41003b0000200f2d000c41e000470d07200f2802084103470d070240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d090c000b0b200f2d000d4104470d07200e1035201121020c240b41031033220e450d28200e41003a0002200e41003b0000200f2d000c41e000470d05200f2802084103470d050240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d070c000b0b200f2d000d4104470d05200e1035201121020c230b200f2802084103470d060240200f2802002214200e460d0041002102034020024103460d01200e20026a2108201420026a210c200241016a2102200c2d000020082d0000470d080c000b0b200f2d000d4104470d06200e1035201121020c220b410021164100211720130d010c020b2002411c6a2113201121020c200b024020132802040d00200041e7bdca00360204413221010c240b024020132802002216201341086a28020022174d0d0020004199beca0036020441c90021010c240b2017200328027c4d0d00200041e2beca0036020441c10021010c230b20092903082118200441c0036a410c6a22024100360200200441003602c4032009290310211920042018a7417f2018428080808010541b3602d00320042019a7417f2019428080808010541b3602c003200441c0036a4104722201410d10ee062001410c10ee062001410710ee062001410f10ee06200420042802c003360264200441c8036a220828020021122002280200211a20042802c403211320042802d003211b200441d0036a220d20073602002002200a3602002004200b3602c803200420053602c403200420063602c003200441e8006a200441c0036a10ef06410110332201450d23200141003a0000200420042f01c00322023b019002200d41e0083b01002008428180808010370300200420013602c403200441013602c003200420023b01d203200441e8006a200441c0036a10f006210c02400240410310332202450d00200241026a41002d00a78e4c3a0000200241002f00a58e4c3b0000410310332208450d00200841026a41002d00aa8e4c3a0000200841002f00a88e4c3b000020044190026a41026a200441c0036a41026a220b2d000022073a0000200420042f00c003220e3b019002200441fc006a280200210d200441e8006a41106a2802002101200b20073a00002004200e3b01c00302400240200d2001470d00200141016a220d2001490d012001410174220b200d200b200d4b1bad42287e2218422088a70d012018a7220d4100480d0102400240024020010d00200d0d014104210b0c020b2004280274210b200141286c2201200d460d01024020010d00200d0d014104210b0c020b200b2001200d1037220b450d290c010b200d1033220b450d280b2004200b3602742004200d41286e360278200428027c210d0b2004280274200d41286c6a220141003a00182001200836020c200142838080803037020420012002360200200141106a428380808030370200200141196a20042f01c0033b00002001411b6a200441c2036a2d00003a00002001411c6a200c3602002004200428027c41016a36027c200441c0036a200441e8006a418c01109d081a200441f8016a200441c0036a10f106200441f8016a41106a280200220e41306c2101200428028002220b41546a210202400340410021082001450d01200141506a21012002412c6a210d200241306a220c2102200d2d00004103470d000b200c41086a2802002201450d00200141286c2102200c28020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b200e41306c2101200b41546a21022008417f6a210d02400340410021082001450d01200141506a21012002412c6a210c200241306a22072102200c2d00004103470d000b200741086a2802002201450d00200141286c2102200728020041186a2101410021080340200820012d0000456a2108200141286a2101200241586a22020d000b0b200e41306c2101200b415c6a21020240034041002111024020010d00410021010c020b200141506a2101200241246a210c200241306a22072102200c2d00004104470d000b200728020021010b0240024002400240200e450d00200120086a211c200b200e41306c6a2115200441a0036a410c6a211d200441bc036a41046a211e200441a0036a41146a211f410021204100212103400240200b2d000041786a220141044b0d000240024002400240024020010e050301020500030b200b28020c2201450d04200b280204220c200141186c6a2122202021010340200121200240200c22082802144104742202450d00200828020c21010340024020012d0000410b470d00200141046a220c2802002207200d490d00200c200741016a3602000b200141106a2101200241706a22020d000b0b2008410c6a2106200442003703b00320044280808080c0003703a803200442043703a003200441a0036a41004101108c0120042802a00320042802a8034104746a22014200370200200141056a4200370000200420042802a80341016a3602a8030240024002400240024020082802142201450d002001ad21194200211803402018a721140240024002400240024002400240024020182001ad5a0d004110210202400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402006280200222320144104746a2d000022240eac010001020202020202020202020202020303030404050506060707080809090a0a0b0b0c0d0d0e0e0f0f1010111213131414151516161717181819191a1a1b1b1c1c1d1d1e1e1f1f2020212122222323242425252627272828292a2a2b2b2c2d2d2e2e2f2f303031313232333434353536363737383839393a3a3b3b3c3c3d3d3e3e3f3f40404141424243434444454546464747484a4a4a4a49494a4a4a4a4a4a4a4a4a4a4a4a4a4a4b4b4b4b000b411121020c4a0b411221020c490b410a21020c480b410821020c470b410821020c460b410421020c450b410421020c440b410421020c430b410421020c420b410421020c410b410421020c400b410421020c3f0b410521020c3e0b410521020c3d0b410521020c3c0b410521020c3b0b410521020c3a0b411321020c390b411421020c380b410621020c370b410721020c360b410b21020c350b410b21020c340b410b21020c330b410b21020c320b410b21020c310b410b21020c300b410b21020c2f0b410b21020c2e0b410b21020c2d0b410b21020c2c0b410b21020c2b0b410c21020c2a0b410c21020c290b410c21020c280b410c21020c270b410c21020c260b410c21020c250b410021020c240b410021020c230b410121020c220b410221020c210b410321020c200b410321020c1f0b410021020c1e0b410021020c1d0b410021020c1c0b410021020c1b0b410021020c1a0b410021020c190b410121020c180b410221020c170b410321020c160b410321020c150b410021020c140b410021020c130b410021020c120b410021020c110b410d21020c100b410d21020c0f0b410d21020c0e0b410d21020c0d0b410d21020c0c0b410d21020c0b0b410d21020c0a0b410d21020c090b410d21020c080b410d21020c070b410d21020c060b410d21020c050b410d21020c040b410d21020c030b410e21020c020b410e21020c010b410f21020b200441e4006a212502402013450d0020132107201221050340200741086a211020072f010621114100210c4100210102400240034020112001460d01201020016a210f200c41086a210c200141016a210102404100417f4101200f2d0000220f20024b1b200f2002461b41016a0e03000301000b0b2001417f6a21110b2005450d022005417f6a2105200720114102746a41ec006a28020021070c010b0b02402007200c6a2201410c6a2802000e0401140001010b200141106a21250b201842017c2118202528020021020240024002400240024002400240024002402024417e6a220141084b0d0020010e09010302050406060708010b20042802a8032201450d1a200141047420042802a0036a41786a220c280200220120026a22022001490d1a200c20023602000c0f0b20042802a8032201450d19200141047420042802a0036a41786a220c280200220120026a22022001490d19200c200236020020042802a8032202450d19200241047420042802a00322016a41746a28020021072002210c0240200220042802a403470d00200441a0036a20024101108c0120042802a803210c20042802a00321010b2001200c4104746a2201200e3b000d200141003a000c20012007360204200120023602002001410f6a200e4110763a0000200141086a4100360200200420042802a80341016a3602a8030c0e0b20042802a8032201450d18200141047420042802a0036a41786a220c280200220120026a22022001490d18200c200236020020042802a803220221010240200220042802a403470d00200441a0036a20024101108c0120042802a80321010b20042802a00320014104746a2201200e3b000d200141003a000c200120183e0204200120023602002001410f6a200e4110763a0000200141086a4100360200200420042802a80341016a3602a8030c0d0b20042802a8032201450d17200141047420042802a0036a41786a220c280200220120026a22022001490d17200c200236020020042802a803220221010240200220042802a403470d00200441a0036a20024101108c0120042802a80321010b20042802a00320014104746a2201200e3b000d200141013a000c200120183e0204200120023602002001410f6a200e4110763a0000200141086a4100360200200420042802a80341016a3602a8030c0c0b20042802a8032201450d16200141047420042802a0036a41746a22012902002126200120183702002026a7210c2026422088a7210202400240024020042802a80322014101460d002001450d0820042802a0032001417e6a4104746a2207280204200c470d00200741086a21010c010b2002450d01024020042802b403220120042802b003470d00201d2001410110900120042802b40321010b20042802ac0320014103746a220120023602042001200c36020041012102201f21010b2001200128020020026a36020020042802a8032201450d170b20042001417f6a22023602a80320042802a003220c20024104746a22072d000c4102460d162002450d0b2001410474200c6a41606a220c20072802002201200c280200220c200c20014b1b360200200120024f0d0b20042802a8032201450d16200141047420042802a0036a41746a22012902002126200120183702002026a7210c2026422088a72101024020042802a80322024101460d002002450d0720042802a0032002417e6a4104746a2202280204200c470d002002200228020820016a3602080c0c0b2001450d0b024020042802b403220220042802b003470d00201d2002410110900120042802b40321020b20042802ac0320024103746a220220013602042002200c360200200420042802b40341016a3602b4030c0b0b20042802a8032201450d15200141047420042802a0036a41746a22012902002126200120183702002026a7210c2026422088a72101024020042802a80322024101460d002002450d0720042802a0032002417e6a4104746a2202280204200c470d002002200228020820016a3602080c0b0b2001450d0a024020042802b403220220042802b003470d00201d2002410110900120042802b40321020b20042802ac0320024103746a220220013602042002200c360200200420042802b40341016a3602b4030c0a0b20042802a8032201450d14200141047420042802a0036a41786a220c280200220120026a22022001490d14202320144104746a41046a2802002107200c200236020020042802a8032201417f6a220c20014b0d14200c20076b2202200c4b0d14200141047420042802a0036a41746a22012902002126200120183702002026a721072026422088a7210c02400240024020042802a80322014101460d002001450d0920042802a0032001417e6a4104746a22112802042007470d00201141086a21010c010b200c450d01024020042802b403220120042802b003470d00201d2001410110900120042802b40321010b20042802ac0320014103746a2201200c360204200120073602004101210c201f21010b20012001280200200c6a36020020042802a80321010b200120024d0d1420042802a003220c20024104746a2d000c0d092001410474200c6a41706a2201200220012802002201200120024b1b3602000c090b20042802a8032201450d13200141047420042802a0036a41786a220c280200220120026a22022001490d13200c200236020020042802a8032202417f6a220120024b0d13200420013602b8032004202320144104746a41046a2202280200280208220c3602bc0320022802002207280200210220072802042107200441003a00cf042004200220074102746a36029c0220042002360298022004201e360294022004200441bc036a360290022004200441bc036a41046a360290022004200441cf046a3602a4022004200441b8036a3602a00202402001200c6b220220014d0d00200441013a00cf040c140b410410332201450d1b2001200236020020044281808080103702d404200420013602d004200441c0036a41106a20044190026a41106a290300370300200441c0036a41086a20044190026a41086a290300370300200420042903900222263703c00320042802d4032102024002402026a72201450d00024020042802c4032001460d002004200141046a3602c00320042802d003280200220720012802006b220c20074d0d02200241013a00000c0a0b200441003602c0030b20042802c8032201450d0820042802cc032001460d082004200141046a3602c80341012107024020042802d003280200221120012802006b220c20114d0d00200241013a0000410021070b2007417d71450d080b4101210220042802cc03211020042802d003211120042802c403210f20042802d4032105410121010340024020012002470d00200441d0046a200241011086010b20042802d00420014102746a200c3602002004200141016a3602d8040240024020042802c0032201450d000240200f2001460d002004200141046a3602c0032011280200220220012802006b220c20024d0d02200541013a00000c0b0b200441003602c0030b20042802c8032201450d0920102001460d092004200141046a3602c8034101210202402011280200220720012802006b220c20074d0d00200541013a0000410021020b2002417d71450d090b20042802d404210220042802d80421010c000b0b20042802a8032201450d12200141047420042802a0036a41786a220c280200220120026a22022001490d12200c200236020020042802a8032201450d12200141047420042802a0036a41746a22012902002126200120183702002026a7210c2026422088a7210102400240024020042802a80322024101460d002002450d0820042802a0032002417e6a4104746a2207280204200c470d00200741086a21020c010b2001450d01024020042802b403220220042802b003470d00201d2002410110900120042802b40321020b20042802ac0320024103746a220220013602042002200c36020041012101201f21020b2002200228020020016a36020020042802a8032202450d130b20042802a00322012d000c0d07200241047420016a41706a41003602000c070b2014200141fc8ecc001042000b41ab8ecc00413f41ec8ecc001064000b41ab8ecc00413f41ec8ecc001064000b41ab8ecc00413f41ec8ecc001064000b41ab8ecc00413f41ec8ecc001064000b41ab8ecc00413f41ec8ecc001064000b20042802d004210f20042802d4042105024020042d00cf04450d00200541ffffffff0371450d0c200f10350c0c0b200f450d0b0240024020042802a80322010d00410121100c010b20042802d8042102200141047420042802a0036a41746a22012902002126200120183702002026a721072026422088a7210102400240024020042802a803220c4101460d00200c450d0720042802a003200c417e6a4104746a220c2802042007470d00200c41086a210c0c010b2001450d01024020042802b403220c20042802b003470d00201d200c410110900120042802b403210c0b20042802ac03200c4103746a220c2001360204200c200736020041012101201f210c0b200c200c28020020016a3602000b410021102002450d002002410274210c200f21010340024020042802a8032207200128020022024b0d00410121100c020b024020042802a003221120024104746a2d000c0d00200741047420116a41706a2207200220072802002207200720024b1b3602000b200141046a2101200c417c6a220c0d000b0b0240200541ffffffff0371450d00200f10350b20100d0b0b20182019510d01200828021421010c000b0b20042802ac0320042802b4032201410041202001676b10f20620042903b003212620042802ac032124024020042802a40341ffffffff0071450d0020042802a00310350b024020240d00410121210c0a0b200828021422012026422088a7220c4101746a220241ffffffff00712002470d0120024104742202417f4c0d010240024020020d00410821070c010b200210332207450d11200828021421010b20084100360214200828020c21232008200736020c200841106a220f2802002127200f2002410476360200202320014104746a21112024200c4103746a212541022107024020010d0020242114202321010c030b41002102202421144100210c202321010340200141016a2f0000200141036a2d000041107472210e024020012d0000221041ac01470d00200141106a21010c040b200141086a2900002118200141046a28000021050240024020074102470d00024020142025470d0041002107202521140c020b20142902002219422088a721282019a7210a41012107201441086a21140b20074101470d00200c200a470d0002402002200f280200470d00200620024101109a01200828021421020b200828020c20024104746a220220042f00c0033b00012002412d3a000020022028360204200241036a200441c0036a41026a2d00003a00002008200828021441016a220236021402402002200f280200470d00200620024101109a01200828021421020b200828020c20024104746a220220042f00c0033b00012002410b3a00002002200d36020441022107200241036a200441c0036a41026a2d00003a00002008200828021441016a2202360214200c210a0b02402002200f280200470d00200620024101109a01200828021421020b200c41016a210c200828020c20024104746a22022018370308200220053602042002200e3b0001200220103a0000200241036a200e4110763a00002008200828021441016a2202360214200141106a22012011470d000c040b0b41ab8ecc00413f41ec8ecc001064000b1044000b20112001460d000340200141106a2102024020012d00004109470d000240200141046a220c280200220128020441ffffffff0371450d0020012802001035200c28020021010b200110350b2002210120112002470d000b0b0240202741ffffffff0071450d00202310350b2014202547200720074102461b21010240202642ffffffff0183500d00202410350b024020014101470d00410121210c060b200841186a210c02400240201b450d0020082802142202450d00200828020c210120024104742102410021080340024020012d0000412c470d002001410b3a0000200141046a201c360200200841016a21080b200141106a2101200241706a22020d000b4101210120080d010b202021010b200c2022470d000b200121200c040b200b2802042201200d490d03200b200141016a3602040c030b200b28020c2201450d02200b280204220c2001411c6c6a21070340200c2201411c6a210c024020012802182202450d0020012802102101200241027421020340024020012802002208200d490d002001200841016a3602000b200141046a21012002417c6a22020d000b0b200c2007460d030c000b0b200b28020c2201450d01200141146c2102200b28020441106a2101034002402001417c6a2802000d0020012802002208200d490d002001200841016a3602000b200141146a21012002416c6a22020d000c020b0b024020042802a40341ffffffff0071450d0020042802a00310350b024020042802b00341ffffffff0171450d0020042802ac0310350b410121210b200b41306a220b2015470d000b4101210f20214101710d0220204101710d012004280288022111200428028002210b0b20044184026a280200211020042802fc01210520042802f80121064100210f0c020b200441c0036a41106a200441f8016a41106a280200360200200441c0036a41086a200441f8016a41086a290300370300200420042903f8013703c00320044190026a200441c0036a10ef06411010332202450d28200241063a0000410110332201450d28200141003a000041011033220c450d28200c20012d00003a000020011035411010332208450d28200841063a000041f00010332201450d28200141063a00602001412c3b01502001200d3602442001410b3a0040200141d8003a00302001201b3602242001412d3a0020200141003602142001410f3a0010200141003602042001410f3a0000024020082d00004109470d0002402008280204220d28020441ffffffff0371450d00200d28020010352008280204210d0b200d10350b20081035024020022d00004109470d0002402002280204220828020441ffffffff0371450d0020082802001035200228020421080b200810350b20021035200441e4036a4287808080f000370200200441e0036a2001360200200441dc036a4100360200200441c0036a410c6a4281808080800c370200200441c8036a4101360200200441003602ec03200442043702d4032004200c3602c403200441013602c00320044190026a200441c0036a10f306200441c0036a20044190026a418c01109d081a200441a0036a200441c0036a10f106200441a0036a410c6a2802002110200441b0036a280200211120042802a003210620042802a403210520042802a803210b4100210f0c010b20044184026a2802002110200428028002220b200428028802221110f406411a210541bed5cb00210602402010450d00201041306c450d00200b10350b0b41002108410021014100210c02402013450d0002402012450d000340201328026c21132012417f6a22120d000b0b20132101201a210c0b024002400340200c450d012001450d024100210d02400240200820012f01064f0d00200121020c010b4100210d034002400240200128020022020d0041002108410021020c010b200d41016a210d20012f010421080b2001103520022101200820022f01064f0d000b0b200841016a2107200220084103746a41146a280200210e02400240200d0d0020022101200721080c010b200220074102746a41ec006a280200210141002108200d417f6a2202450d000340200128026c21012002417f6a22020d000b0b200c417f6a210c200e4103470d000b0b02402001450d0020012802002102200110352002450d00034020022802002101200210352001210220010d000b0b02400240200f0d0020044190026a41106a201136020020044190026a410c6a20103602002004200b3602980220042005360294022004200636029002200441c0036a20044190026a200928027810f50620042802c0034101470d010240200441c0036a41086a280200450d0020042802c40310350b200041d8d5cb0036020420004101360200200041086a41233602000c2a0b2000200636020420004101360200200041086a20053602000c290b200441d4036a2802002102200441c0036a41106a2802002110200441c0036a410c6a280200210f200441c8036a280200210c20042802c403210820032802702105200441003602a803200442013703a003410410332201450d27200441043602a403200420013602a00320012008360000200441043602a8030240024020042802a403220d417c714104460d004104210120042802a00321080c010b200d41017422014108200141084b1b220b4100480d0202400240200d0d0041042101200b10332208450d2a0c010b4104210120042802a0032108200d200b460d002008200d200b10372208450d2920042802a80321010b2004200b3602a403200420083602a0030b200820016a200c3600002004200141046a3602a803200f200241306c6a2113024020020d00200f21010c040b200441c0036a4101722102200441c0036a41276a210d200441c0036a41206a210c200441c0036a41186a210b200441c0036a41086a2107200f21010240034020012d00002108200d200141286a290000370000200c200141216a290000370300200b200141196a290000370300200441c0036a41106a220e200141116a2900003703002007200141096a2900003703002004200141016a2900003703c003024020084110470d00200141306a21010c060b20044190026a41276a2211200d29000037000020044190026a41206a2203200c29030037030020044190026a41186a200b290300221837030020044190026a41106a200e290300221937030020044190026a41086a20072903002226370300200420042903c00322293703900220022029370000200241086a2026370000200241106a2019370000200241186a2018370000200241206a2003290300370000200241276a2011290000370000200420083a00c003200441e8006a200441c0036a200441a0036a10f60620042d00682208411f470d01200141306a22012013470d000b201321010c040b200428026c210d20042802702102200141306a2201201320016b41306d10f40602402010450d00201041306c450d00200f10350b024020042802a403450d0020042802a00310350b024020084105470d002002450d00200d10350b20004199d8cb0036020420004101360200200041086a41253602000c280b41958dcc00412b41c08dcc00103f000b103e000b1045000b2001201320016b41306d10f40602402010450d00201041306c450d00200f10350b20042802a003210120042902a40321182000411c6a41003a0000200041146a2018370200200041106a20013602002000410c6a2017360200200041086a2016360200200020053602042000411d6a20042f00f8013b0000200041003602002000411f6a200441fa016a2d00003a00000c240b200e1035200041fabbca003602040c210b200e1035200041fabbca003602040c200b200e1035200041fabbca003602040c1f0b200f2d000d22024104460d00200241fb01710d0020141035201121020c1a0b201410350b200020083602040c1c0b200e1035200041fabbca003602040c1b0b200e1035200041fabbca003602040c1a0b200e1035200041fabbca003602040c190b200e1035200041fabbca003602040c180b200e1035200041fabbca003602040c170b200e1035200041fabbca003602040c160b200e1035200041fabbca003602040c150b200e1035200041fabbca003602040c140b200e1035200041fabbca003602040c130b200f2d000d22024104460d0a200241fb01710d0a200e1035201121020c0e0b200f2d000d22024104460d02200241fb01710d02200e1035201121020c0d0b200f2d000d22024104460d00200241fb01710d00200e1035201121020c0c0b200e1035200041fabbca003602040c0f0b200e1035200041fabbca003602040c0e0b200f2d000d22024104460d00200241fb01710d00200e1035201121020c090b200e1035200041fabbca003602040c0c0b200e1035200041fabbca003602040c0b0b200e1035200041fabbca003602040c0a0b200e1035200041fabbca003602040c090b200e1035200041fabbca003602040c080b200e1035200041fabbca003602040c070b02400240200241b9e0cb00460d0041b9e0cb002002410b10a0080d010b4126210c41fabbca00210e200f2d000c41e000470d01200f2802080d0120112102200f2d000d4104460d030c010b0240200241dde0cb00460d0041dde0cb002002410b10a0080d020b4126210c41fabbca00210e200f2d000c41e000470d00200f2802080d0020112102200f2d000d4104460d020b200c21012000200e3602040c050b0240200241bfe2cb00460d0041bfe2cb002002410b10a0080d040b41021033220c450d05200c41003b0000200f2d000c41e000470d02200f2802084102470d020240200f280200220e200c460d0041002101034020014102460d01200c20016a2102200e20016a2108200141016a210120082d000020022d0000470d040c000b0b200f2d000d4104470d02200c1035201121020c000b0b200041c9d3cb00360204411f21010c020b200c10350b41262101200041fabbca003602040b20004101360200200041086a200136020002402007450d00200b200741306c6a2111200b210703402007220041306a21070240024020002d00002201410e4b0d00024002400240024002400240024002400240024002400240024020010e0f0001020304050607080e090e0a0b0c000b200041086a280200450d0d200041046a28020010350c0d0b0240200041086a280200450d00200041046a28020010350b200041146a280200450d0c200041106a28020010350c0c0b02402000410c6a2802002202450d00200041046a28020021012002410474210203400240200141046a280200450d00200128020010350b200141106a2101200241706a22020d000b0b200041086a28020041ffffffff0071450d0b200028020410350c0b0b02402000410c6a2802002202450d00200041046a2802002101200241286c210203400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101200241586a22020d000b0b200041086a2802002201450d0a200141286c450d0a200028020410350c0a0b200041086a28020041ffffffff0371450d09200041046a28020010350c090b200041086a2802002201450d082001410c6c450d08200041046a28020010350c080b200041086a2802002201450d072001410c6c450d07200041046a28020010350c070b02402000410c6a2802002201450d00200041046a280200220c20014104746a210e03400240200c2802082202450d00200c2802002101200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d0020082802001035200d28020021080b200810350b200141106a2101200241706a22020d000b0b200c41106a21010240200c41046a28020041ffffffff0071450d00200c28020010350b2001210c2001200e470d000b0b200041086a28020041ffffffff0071450d06200028020410350c060b02402000410c6a2802002202450d00200041046a2802002101200241146c210203400240200141046a280200450d00200128020010350b200141146a21012002416c6a22020d000b0b200041086a2802002201450d05200141146c450d05200028020410350c050b02402000410c6a2802002201450d00200041046a280200220c2001411c6c6a210e03400240200c2802042201450d000240200c410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d0020082802001035200d28020021080b200810350b200141106a2101200241706a22020d000b0b200c41086a28020041ffffffff0071450d00200c28020410350b200c411c6a21010240200c41146a28020041ffffffff0371450d00200c28021010350b2001210c2001200e470d000b0b200041086a2802002201450d042001411c6c450d04200028020410350c040b02402000410c6a2802002201450d00200041046a280200220c200141186c6a210e03400240200c41046a28020041ffffffff0171450d00200c28020010350b0240200c41146a2802002202450d00200c28020c2101200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d0020082802001035200d28020021080b200810350b200141106a2101200241706a22020d000b0b200c41186a21010240200c41106a28020041ffffffff0071450d00200c28020c10350b2001210c2001200e470d000b0b200041086a2802002201450d03200141186c450d03200028020410350c030b02402000410c6a2802002201450d00200041046a280200220c2001411c6c6a210e03400240200c2802042201450d000240200c410c6a2802002202450d00200241047421020340024020012d00004109470d000240200141046a220d280200220828020441ffffffff0371450d0020082802001035200d28020021080b200810350b200141106a2101200241706a22020d000b0b200c41086a28020041ffffffff0071450d00200c28020410350b200c411c6a21010240200c41146a280200450d00200c28021010350b2001210c2001200e470d000b0b200041086a2802002201450d022001411c6c450d02200028020410350c020b0240200041046a2802002201450d00200041086a280200450d00200110350b0240200041146a2802002201450d0002402000411c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101200241746a22020d000b0b200041186a2802002201450d002001410c6c450d00200028021410350b200041246a280200220c450d0102402000412c6a2802002201450d00200c20014104746a210e0340200c220d41106a210c0240200d2802042201450d000240200d410c6a2802002202450d002002410c6c21020340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101200241746a22020d000b0b200d41086a2802002201450d002001410c6c450d00200d28020410350b200c200e470d000b0b200041286a28020041ffffffff0071450d01200028022410350c010b0240200041086a280200450d00200041046a28020010350b0240200041146a2802002201450d00200041186a280200450d00200110350b200041246a28020041ffffffff0071450d00200041206a28020010350b20072011470d000b0b200a450d01200a41306c450d01200b10350c010b103c000b200441e0046a24000bf70a02147f027e23004190066b22022400024002400240024020012d00000e03010200010b200241b0056a41186a2203200141196a2200290000370300200241b0056a41106a2204200141116a2205290000370300200241b0056a41086a2206200141096a2207290000370300200220012900013703b005200241d0056a41186a2208200141396a2209290000370300200241d0056a41106a220a200141316a220b290000370300200241d0056a41086a220c200141296a220d2900003703002002200141216a220e2900003703d005200241b0026a41186a220f200141d9006a2210290000370300200241b0026a41106a2211200141d1006a2212290000370300200241b0026a41086a2213200141c9006a22142900003703002002200141c1006a22152900003703b002200141f8006a2903002116200141f0006a290300211720024188056a41186a200029000037030020024188056a41106a200529000037030020024188056a41086a20072900003703002002200129000137038805200241186a2009290000370300200241106a200b290000370300200241086a200d2900003703002002200e290000370300200241d8026a41186a2010290000370300200241d8026a41106a2012290000370300200241d8026a41086a22002014290000370300200220152900003703d80220024180066a41086a200141ec006a2802003602002002200141e4006a29020037038006200241f0056a20024188056a2002200241d8026a2017201620024180066a10f10320022d00f0052101200041033a0000200241d8026a41096a20022903b005370000200241d8026a41116a2006290300370000200241d8026a41196a2004290300370000200241d8026a41216a2003290300370000200241d8026a41296a20022903d005370000200241d8026a41316a200c290300370000200241d8026a41396a200a290300370000200241d8026a41c1006a20082903003700002002410d3a00d802200241d8026a41f8006a2016370300200241d8026a41f0006a2017370300200241c1036a20014104463a0000200241b9036a200f290300370000200241d8026a41d9006a2011290300370000200241d8026a41d1006a2013290300370000200241d8026a41c9006a20022903b00237000041b0b4cc004100200241d8026a10d4010c020b200141086a28020021002001410c6a2802002104200141046a2802002103200241076a200141106a41f800109d081a2002410d3a00d802200241d8026a410172200241ff00109d081a20032004200241d8026a10d401200041ffffff3f71450d01200310350c010b200241e8056a2204200141196a2205290000370300200241d0056a41106a2206200141116a2207290000370300200241d0056a41086a2208200141096a2209290000370300200220012900013703d0052002200141286a41b002109d08220341b0056a200310d803200341d8026a200341b002109d081a20034192056a20092900003701002003419a056a2007290000370100200341a2056a200529000037010020034180023b0188052003200129000137018a05200341b0026a200341d8026a20034188056a10ac032000280200280200210142002116024020032903b8024201520d00420020032903b0052216200341b0026a41106a2903007d221720172016561b21160b2001427f2001290308221720167c221620162017541b22162001290300221720162017561b37030820032903b0022116200341d8026a41086a41063a0000200341d8026a41096a20032903d005370000200341d8026a41116a2008290300370000200341d8026a41196a2006290300370000200341f9026a200429030037000020034181036a2016503a00002003410d3a00d80241b0b4cc004100200341d8026a10d4010b20024190066a24000bb22402137f067e23004190046b22032400024002400240024002400240024002400240024002400240024020012802000e0400010203000b200341cc016a4101360200200342013702bc01200341e8d4ca003602b801200341043602ec032003419cd5ca003602e8032003200341e8036a3602c801200341b8016a41b0b4cc00104c000b20012802042101418226210420022d00000d0420022d00014101470d04200241196a2d00002104200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a290100370320200320043a001f200320053a001e200320063b011c200320073a001b200320083a001a200320093b01182003200a3a00172003200b3a00162003200c3b01142003200d3a00132003200e3a00122003200f3b0110200320103a000f200320113a000e200320123b010c200320133a000b200320143a000a200320153b010841d5c3c800ad4280808080c00084100122022900002116200229000821172002103541b4c4c800ad428080808030841001220229000021182002290008211920021035200320193701a801200320183701a00120032017370198012003201637019001200341b8016a20034190016a412010d5010240024020032d00b8014101460d0020034180046a4200370300200341f8036a4200370300200341f0036a4200370300200342003703e8030c010b200320032900b9013703e8032003200341d1016a290000370380042003200341c1016a2900003703f0032003200341c9016a2900003703f8030b4183262104200341086a200341e8036a412010a0080d04200341b8016a200141b002109d081a200341003b01e80320034190016a200341b8016a200341e8036a10ac03200320032900a9013703b801200320034190016a41206a2800003600bf01024002402003290390014201510d00410421020c010b200341a8016a2d000021042003290398012116200320032800bf013600ef03200320032903b8013703e8034104210220164202510d00200320032800ef033600bf01200320032903e8033703b801200421020b200320032903b801370370200320032800bf01360077200341b8016a41086a20023a0000200341c1016a2003290370370000200341b8016a41106a2003280077360000200341003a00bc012003410e3a00b801200320032f00503b00bd012003200341d2006a2d00003a00bf01200341cc016a20032902e803370200200341d4016a200341e8036a41086a290200370200200341dc016a200341e8036a41106a28020036020041b0b4cc004100200341b8016a10d401200110350c020b200341e8036a41206a200141246a280200360200200341e8036a41186a2001411c6a290200370300200341e8036a41106a200141146a290200370300200341e8036a41086a2001410c6a290200370300200320012902043703e8034182262101024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a290100370348200320013a0047200320043a0046200320053b0144200320063a0043200320073a0042200320083b0140200320093a003f2003200a3a003e2003200b3b013c2003200c3a003b2003200d3a003a2003200e3b01382003200f3a0037200320103a0036200320113b0134200320123a0033200320133a0032200320143b013041d5c3c800ad4280808080c00084100122012900002116200129000821172001103541b4c4c800ad428080808030841001220129000021182001290008211920011035200320193701a801200320183701a00120032017370198012003201637019001200341b8016a20034190016a412010d5010240024020032d00b8014101460d00200341a8016a4200370300200341a0016a420037030020034198016a420037030020034200370390010c010b200320032900b901370390012003200341d1016a2900003703a8012003200341c1016a290000370398012003200341c9016a2900003703a0010b4183262101200341306a20034190016a412010a0080d00200341b8016a41206a200341e8036a41206a280200360200200341b8016a41186a200341e8036a41186a290300370300200341b8016a41106a200341e8036a41106a290300370300200341b8016a41086a200341e8036a41086a290300370300200320032903e8033703b80120034190016a200341b8016a108b02200341086a41086a220120034199016a290000370300200341086a41106a2202200341a1016a290000370300200341086a41186a2204200341a9016a2900003703002003200329009101370308024020032d0090014101460d00200341f0006a41186a2004290300370300200341f0006a41106a2002290300370300200341f0006a41086a20012903003703002003200329030837037041d5c3c800ad4280808080c000842216100122012900002117200129000821182001103541b4c4c800ad42808080803084221910012201290000211a2001290008211b200110352003201b3701a8012003201a3701a00120032018370198012003201737019001200341b8016a20034190016a412010d5010240024020032d00b8014101460d004200211741002101410021024100210441002105410021064100210741002108410021094100210a4100210b4100210c4100210d4100210e4100210f410021104100211141002112410021130c010b200341c0016a2d0000210e200341c1016a2f0000210d200341c3016a2d0000210c200341c4016a2d0000210b200341c5016a2f0000210a200341c7016a2d00002109200341c8016a2d00002108200341c9016a2f00002107200341cb016a2d00002106200341cc016a2d00002105200341cd016a2f00002104200341cf016a2d00002102200341d0016a2d00002101200341d1016a290000211720032f00b901211320032d00bb01211220032d00bc01211120032f00bd01211020032d00bf01210f0b200341d5016a2017370000200341d4016a20013a0000200341d3016a20023a0000200341d1016a20043b0000200341b8016a41186a220220053a0000200341cf016a20063a0000200341cd016a20073b0000200341cc016a20083a0000200341cb016a20093a0000200341c9016a200a3b0000200341b8016a41106a2204200b3a0000200341c7016a200c3a0000200341c5016a200d3b0000200341c4016a200e3a0000200341c3016a200f3a0000200341c1016a20103b0000200341b8016a41086a220520113a0000200320123a00bf01200320133b00bd01200341013a00bc012003410e3a00b80141b0b4cc004100200341b8016a10d4012002200341f0006a41186a2903003703002004200341f0006a41106a2903003703002005200341f0006a41086a290300370300200320032903703703b801201610012201290000211620012900082117200110352019100122012900002118200129000821192001103520032019370168200320183701602003201737015820032016370150412010332201450d06200120032903b801370000200141186a2002290300370000200141106a2004290300370000200141086a2005290300370000200341d0006aad42808080808004842001ad42808080808004841002200110350c030b41812621010b200041206a410b3602002000411c6a41de98c800360200200041186a2001360200200042003703080c080b200141286a2802002104200341286a200141246a280200360200200341086a41186a2001411c6a290200370300200341086a41106a200141146a290200370300200341086a41086a2001410c6a290200370300200320012902043703084102210120022d00000d0420022d00014101470d04200241196a2d00002101200241186a2d00002105200241166a2f01002106200241156a2d00002107200241146a2d00002108200241126a2f01002109200241116a2d0000210a200241106a2d0000210b2002410e6a2f0100210c2002410d6a2d0000210d2002410c6a2d0000210e2002410a6a2f0100210f200241096a2d00002110200241086a2d00002111200241066a2f01002112200241056a2d00002113200241046a2d00002114200241026a2f0100211520032002411a6a29010037038801200320013a008701200320053a008601200320063b018401200320073a008301200320083a008201200320093b0180012003200a3a007f2003200b3a007e2003200c3b017c2003200d3a007b2003200e3a007a2003200f3b0178200320103a0077200320113a0076200320123b0174200320133a0073200320143a0072200320153b017041d5c3c800ad4280808080c00084100122012900002116200129000821172001103541b4c4c800ad428080808030841001220129000021182001290008211920011035200320193701a801200320183701a00120032017370198012003201637019001200341b8016a20034190016a412010d5010240024020032d00b8014101460d0020034180046a4200370300200341f8036a4200370300200341f0036a4200370300200342003703e8030c010b200320032900b9013703e8032003200341d1016a290000370380042003200341c1016a2900003703f0032003200341c9016a2900003703f8030b200341f0006a200341e8036a412010a0080d05200341b8016a41206a200341086a41206a280200360200200341b8016a41186a200341086a41186a290300370300200341b8016a41106a200341086a41106a290300370300200341b8016a41086a200341086a41086a290300370300200320032903083703b801200341e8036a200341b8016a108b024101210120032d00e8034101460d01200341e8036a41086a2d00002102200341f1036a2f00002105200341f3036a2d00002106200341f4036a2d00002107200341f5036a2f00002108200341f7036a2d00002109200341e8036a41106a2d0000210a200341f9036a2f0000210b200341fb036a2d0000210c200341fc036a2d0000210d200341fd036a2f0000210e200341ff036a2d0000210f200341e8036a41186a2d0000211020032f00e903211120032d00eb03211220032d00ec03211320032f00ed03211420032d00ef032115200320034181046a290000370168200320103a00672003200f3a00662003200e3b01642003200d3a00632003200c3a00622003200b3b01602003200a3a005f200320093a005e200320083b015c200320073a005b200320063a005a200320053b0158200320023a0057200320153a0056200320143b0154200320133a0053200320123a0052200320113b0150200341b8016a200441b002109d081a200341f2036a2003290158370100200341fa036a200329016037010020034182046a200329016837010020034180023b01e803200320032901503701ea0320034190016a200341b8016a200341e8036a10ac0302402003290390014201520d00200341b8016a41186a200341b0016a290300370300200341b8016a41106a220120034190016a41186a290300370300200341c0016a20034190016a41106a29030037030020032003290398013703b801200110d10441c4e0c600ad4280808080a001841006419ea2c000ad4280808080e0018410060240024020032903b8014201510d004194a2c000ad4280808080a0018410060c010b20032903c00110260b410021010b200320013a00bd01200341023a00bc012003410e3a00b80141b0b4cc004100200341b8016a10d401200410350b42002116200042003703080c070b200410ba0220041035410121010c040b200110ba0220011035200041206a410b3602002000411c6a41de98c800360200200041186a2004360200200042003703080c040b1045000b200410ba02200410350c010b200410ba0220041035410321010b20004200370308200041206a410b3602002000411c6a41de98c800360200200041186a2001418026723602000b420121160b2000201637030020034190046a24000bb8c20105017f037e127f087e087f23004180046b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0d00011a13120c0b0a0605040302000b20034184036a4101360200200342013702f402200341e8d4ca003602f002200341043602b4012003419cd5ca003602b0012003200341b0016a36028003200341f0026a41b0b4cc00104c000b200141106a2903002104200141086a29030021052002411a6a2901002106200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211841012101024020022d00000d0020022d000141014721010b2003200637038001200320073a007f200320083a007e200320093b017c2003200a3a007b2003200b3a007a2003200c3b01782003200d3a00772003200e3a00762003200f3b0174200320103a0073200320113a0072200320123b0170200320133a006f200320143a006e200320153b016c200320163a006b200320173a006a200320183b016820010d1920034188016a41186a200341e8006a41186a29030037030020034188016a41106a200341e8006a41106a29030037030020034188016a41086a200341e8006a41086a2903003703002003200329036837038801200341f0026a20034188016a10cf06200341106a20032802f002220120032802f80241b0b4cc0041004100108a0220032802102102024020032802f402450d00200110350b4103210720024101460d1a200341f0026a20034188016a10b906200341086a20032802f002220120032802f80241b0b4cc0041004100108a0220032802082102024020032802f402450d00200110350b20024101460d1a200341f0026a41186a4200370300200341f0026a41106a220e4200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f000841001220129000021062002200141086a290000370300200320063703f00220011035419cbac800ad4280808080c00084100122012900002106200341e8006a41086a2207200141086a2900003703002003200637036820011035200e20032903682206370300200341c8026a41086a2002290300370300200341c8026a41106a2006370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b220f20032902f402420020021b2206422088a741e8006c6a210d200f210202400340024002402002200d460d0041e59bc8002108410a2109410321074119210a410c210b20034188016a200241c8006a2201470d010c030b200341f0026a41186a22074200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f000841001220129000021192002200141086a290000370300200320193703f0022001103541e1b8c800ad4280808080a00184100122012900002119200341e8006a41086a2209200141086a2900003703002003201937036820011035200e2003290368370000200e41086a2009290300370000200341c8026a41086a2002290300370300200341c8026a41106a2008290300370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b221020032902f402420020021b2219422088a741e8006c6a210d20102102024002400240024002400340024002402002200d460d0041d59bc800210841102109410321074119210a410d210b20034188016a200241c8006a2201470d010c070b200341f0026a41186a22074200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008410012201290000211a2002200141086a2900003703002003201a3703f002200110354189eaca00ad4280808080f0008410012201290000211a200341e8006a41086a2209200141086a2900003703002003201a37036820011035200e2003290368370000200e41086a2009290300370000200341c8026a41086a2002290300370300200341c8026a41106a2008290300370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10fe0120032802f0022201410120011b210d41002102024020032902f402420020011b221a422088a7220141014b0d0020010e020403040b03402001410176220720026a22082002200d20084105746a20034188016a412010a0084101481b2102200120076b220141014b0d000c030b0b200141206a2102200120034188016a412010a0080d000c050b0b200d20024105746a20034188016a412010a0080d0041ce9cc8002108410d2109410321074119210a4102210b0c010b200342003703d00220034280809aa6eaafe3013703c802200320034188016a360268200320034188016a36028002200320034180026a3602f8022003200341e8006a3602f4022003200341c8026a3602f002200341b0016a20034188016a200341f0026a108c030240024020032802b0014101470d00200341bc016a2802002109200341b8016a280200210820032d00b701210c20032d00b601210b20032d00b501210a20032d00b40121070c010b410421070240200341b0016a41086a2903004201520d00200341b0016a41106a290300211b2003280280022102200341a8036a200341b0016a41186a290300370300200341a0036a201b370300200341f0026a41086a41003a0000200341f9026a200229000037000020034181036a200241086a29000037000020034189036a200241106a29000037000020034191036a200241186a290000370000200341033a00f00241b0b4cc004100200341f0026a10d4010b0b200741ff01714104460d010b201a42ffffff3f83500d01200d10350c010b200320063702b4012003200f3602b001200341f0026a41106a4200370300200341f0026a41086a22024280809aa6eaafe301370300200341003a00f002200341b0016a20034188016a20052004200341f0026a10d606200341a8036a2004370300200341a0036a2005370300200241013a0000200341f9026a20032903880137000020034181036a20034188016a41086a29030037000020034189036a20034188016a41106a29030037000020034191036a200341a0016a290300370000200341123a00f00241b0b4cc004100200341f0026a10d4010240201a42ffffff3f83500d00200d10350b02402019a72202450d00200241e8006c450d00201010350b420021060c200b2019a72202450d02200241e8006c450d02201010350c020b200141206a2102200120034188016a412010a0080d000b0b2006a72202450d1b200241e8006c450d1b200f10350c1b0b4182b23c21070240024020022d000120022d0000410047720d004183b23c2107200141046a280200220241014b0d010b20004200370308200041206a410a3602002000411c6a41a99bc800360200200041186a2007360200420121060c1d0b42002106200341e8006a41186a4200370300200341e8006a41106a22094200370300200341e8006a41086a220742003703002003420037036841a29bc800ad4280808080f0008410012208290000210420034180026a41086a2201200841086a29000037030020032004370380022008103520072001290300370300200320032903800237036841a99bc800ad4280808080a001841001220829000021042001200841086a29000037030020032004370380022008103520092003290380022204370300200341c8026a41086a2007290300370300200341c8026a41106a2004370300200341c8026a41186a2001290300370300200320032903683703c802200320023602f002200341c8026aad4280808080800484200341f0026aad4280808080c000841002200341fc026a2002360200200341f0026a41086a410d3a0000200341123a00f00241b0b4cc004100200341f0026a10d4010c0b0b200141216a2d0000210820034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a2900003703002003200129000137038801200341f0026a41206a200241206a290200370300200341f0026a41186a200241186a290200370300200341f0026a41106a200241106a290200370300200341f0026a41086a200241086a290200370300200320022902003703f002200341b0016a200341f0026a10d70602400240024020032d00b0014101460d00200341e8006a20034188016a10cf06200328026821022003200328027022013602bc02200320023602b802200341c8026a2001ad4220862002ad84100510c2010240024020032802c80222070d00410221010c010b20032802cc0221092003200341c8026a41086a280200220136028402200320073602800202400240024020014110490d002003200141706a360284022003200741106a36028002200741086a290000210620072900002104200341f0026a20034180026a10bf0220032d00f00222014102470d010b200341003602b801200342013703b001200341093602f4032003200341b8026a3602f0032003200341b0016a3602fc0320034184036a4101360200200342013702f402200341c888c2003602f0022003200341f0036a36028003200341fc036a41e88ac500200341f0026a10431a20033502b80142208620033502b001841006024020032802b401450d0020032802b00110350b410221010c010b200341b0016a41086a20034190036a290300370300200320032800f4023600f303200320032800f1023602f003200320034188036a2903003703b00120034180036a2903002119200341f0026a41086a2903002105200341a0036a290300211a20034198036a290300211b0b2009450d00200710350b20034180026a41086a2207200341b0016a41086a290300370300200320032802f0033602f002200320032800f3033600f302200320032903b00137038002024020014102460d00200341a0026a41086a2007290300370300200320032800f3023600b302200320032802f0023602b00220032003290380023703a0020b0240200328026c450d00200210350b20014102470d0141b99cc8002101410c21074103210241192108410421090c020b410221020c010b200341b8026a41086a2207200341a0026a41086a290300370300200320032802b0023602f003200320032800b3023600f303200320032903a0023703b80241032102024002400240024002400240024020084103710e03000201000b200341f0026a41186a220a4200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008410012209290000211c2002200941086a2900003703002003201c3703f00220091035419cbac800ad4280808080c0008410012209290000211c200341e8006a41086a220b200941086a2900003703002003201c3703682009103520082003290368221c370300200341c8026a41086a2002290300370300200341c8026a41106a201c370300200341c8026a41186a200b290300370300200320032903f0023703c802200341f0026a200341c8026a10be02200320032902f402420020032802f00222091b3702b40120032009410820091b3602b0012008201937030020022005370300200341a0036a201a37030020034198036a201b370300200a20032903b80237030020034190036a2007290300370300200320013a00f002200320032802f0033600f102200320032800f3033600f402200341b0016a20034188016a20042006200341f0026a10d6060c020b200341e8006a41186a4200370300200341e8006a41106a4200370300200341e8006a41086a220742003703002003420037036841a29bc800ad4280808080f0008410012208290000211c20034180026a41086a2209200841086a2900003703002003201c370380022008103520072009290300370300200320032903800237036841ceb8c800ad428080808030841001220841086a290000211c2008290000211d20081035200341c8026a41106a201d370300200341c8026a41186a201c370300200341c8026a41086a2007290300370300200320032903683703c802200341d0006a200341c8026a412010d701024020032903584200200328025022071b221d2004542208200341d0006a41106a290300420020071b221c200654201c2006511b450d0041949cc8002101410f210741192108410721090c060b200341f0026a20034188016a10d806200341f0026a41086a2107024020032d00f00222024104460d002007280200210720032802f402210120032d00f302210a20032d00f202210920032d00f10221080c060b200341e8006a41186a4200370300200341e8006a41106a4200370300200341e8006a41086a220242003703002003420037036841a29bc800ad4280808080f00084221e10012209290000211f20034180026a41086a220a200941086a2900003703002003201f37038002200910352002200a290300370300200320032903800237036841ceb8c800ad428080808030841001220941086a290000211f2009290000212020091035200341c8026a41106a22092020370300200341c8026a41186a220a201f370300200341c8026a41086a220b2002290300370300200320032903683703c8022003201c20067d2008ad7d3703f8022003201d20047d3703f002200341c8026aad4280808080800484200341f0026aad42808080808002841002200341f0026a41186a220d4200370300200341f0026a41106a2208420037030020074200370300200342003703f00241d1c4c700ad4280808080e000841001220c290000211c2007200c41086a2900003703002003201c3703f002200c103541e7c4c700ad4280808080e000841001220c290000211c2002200c41086a2900003703002003201c370368200c103520082003290368221c370300200b20072903003703002009201c370300200a2002290300370300200320032903f0023703c802200341c8006a200341c8026a412010c001200328024c210e2003280248210f200d42003703002008420037030020074200370300200342003703f002201e1001220c290000211c2007200c41086a2900003703002003201c3703f002200c10354189eaca00ad4280808080f000841001220c290000211c2002200c41086a2900003703002003201c370368200c103520082003290368221c370300200b20072903003703002009201c370300200a2002290300370300200320032903f0023703c802200341f0026a200341c8026a10fe0120032902f402420020032802f00222021b221c422088a741f4036a2207450d02200341e4003a00f102200341e40041d0860320076e22076b3a00f002200e4100200f1b2108200341f0026a200741ff017141e4004b6a2d00004180fe126c21070240201c42ffffff3f83500d002002410120021b10350b200720086a210220034180026a41086a2207200341b8026a41086a290300370300200320032802f003360268200320032800f30336006b200320032903b802370380020240024020014101470d00200341ff026a20193700002003418f036a20072d00003a0000200320053700f7022003200328006b3600f302200320032802683602f002200320032903800237008703200341b0016a200341f0026a10d006024020032802b001220120032802b801220810d10241ff017122074102460d002008ad4220862001ad8410070b024020032802b401450d00200110350b20070d01200341f0026a20022004201b2004201b5422012006201a542006201a511b22071b2006201a20071b10b00642002006201a7d2001ad7d22052004201b7d2219200456200520065620052006511b22011b21064200201920011b21040c010b200320053703c802200320193703d0022005201984500d00200320034188016a3602fc03200341b0016a20034188016a200341c8026a200341fc036a10f00220032903b0014201520d0020032903b8012105200341a8036a200341b0016a41106a290300370300200341a0036a2005370300200341f0026a41086a41003a0000200341f9026a20032903880137000020034181036a20034188016a41086a29030037000020034189036a20034188016a41106a29030037000020034191036a200341a0016a290300370000200341033a00f00241b0b4cc004100200341f0026a10d4010b20034188016a20022004200610b0060c010b02402001410171450d00200341ff026a20193700002003418f036a200341c0026a2d00003a0000200320053700f702200320032800f3033600f302200320032802f0033602f002200320032903b80237008703200341b0016a200341f0026a10d00620033502b801210620032802b0012101410110332202450d16200241013a000020064220862001ad842002ad4280808080108410022002103520032802b401450d01200110350c010b200342f0f2bd99f7edd8b4e5003703b001200341f0026a200341b0016a10e001200341b0016a20034188016a200341f0026a20052019410010ef020b200341f0026a41186a220120034188016a41186a290300370300200341f0026a41106a220720034188016a41106a290300370300200341f0026a41086a220820034188016a41086a29030037030020032003290388013703f00241a29bc800ad4280808080f0008410012202290000210620034180026a41086a200241086a29000037030020032006370380022002103541e0aec900ad4280808080b00284100122022900002106200241086a290000210420021035412010332202450d07200220032903f002370000200241186a2001290300370000200241106a2007290300370000200241086a200829030037000020032002ad42808080808004841003220129000037036820011035200341bc016a200241206a360200200320023602b8012003200341e8006a41086a3602b4012003200341e8006a3602b001200341c8026a200341b0016a107b2002103520032802d002220941206a2201417f4c0d0120032802c802210a0240024020010d0041002107410121020c010b200110332202450d08200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322020d010c160b20072008460d0020022007200810372202450d150b2002200329038002370000200241086a20034180026a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020022008200710372202450d150b20022006370010200241186a200437000002400240200741606a2009490d00200721080c010b2009415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020022007200810372202450d150b200241206a200a2009109d081a024020032802cc02450d00200a10350b2001ad4220862002ad8410072008450d0d20021035420021060c0e0b41f0b8c8004119418cb9c800103f000b1044000b103e000b20004200370308200041206a20073602002000411c6a2001360200200041186a200a411874200941ff017141107472200841ff017141087472200272360200420121060c1b0b200141216a2d0000210720034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a2900003703002003200129000137038801200341f0026a41206a200241206a290200370300200341f0026a41186a200241186a290200370300200341f0026a41106a200241106a290200370300200341f0026a41086a200241086a290200370300200320022902003703f002200341b0016a200341f0026a10d706410221020240024020032d00b0014101460d00200341f0026a20034188016a10b906200341c0006a20032802f002220220032802f80241b0b4cc0041004100108a0220032802402101024020032802f402450d00200210350b4103210220014101470d000240024002400240200741ff01710d00200341f0026a20034188016a10b80620033502f80242208620032802f0022202ad841007024020032802f402450d00200210350b200341f0026a20034188016a10ba0620033502f80242208620032802f0022202ad841007024020032802f402450d00200210350b200341f0026a20034188016a10d006024020032802f002220220032802f802220810d10241ff017122014102460d002008ad4220862002ad8410070b024020032802f402450d00200210350b20010d03200341f0026a41186a4200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008422041001220129000021062002200141086a290000370300200320063703f00220011035419cbac800ad4280808080c000842205100122012900002106200341e8006a41086a220d200141086a2900003703002003200637036820011035200820032903682206370300200341c8026a41086a220c2002290300370300200341c8026a41106a220e2006370300200341c8026a41186a220f200d290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b210920032902f402420020021b2206422088a72210450d02201041037441786a41037641016a210a2009417f7320034188016a6a210b410021024100210103400240200920026a22082d0000450d00200b2002460d03200841016a20034188016a412010a008450d030b200241e8006a2102200a200141016a2201470d000c030b0b200341f0026a20034188016a10d80620032d00f00222024104460d02200341f0026a41086a280200210120032802f402210720032d00f102410874210820032d00f202411074210920032d00f302411874210a0c040b200341f0026a200841e800109d081a2008200841e8006a201041e8006c20026b41987f6a109e081a200341e0026a200341d0036a2903002219370300200341d8026a200341c8036a290300221a370300200341c8026a41086a200341c0036a290300221b370300200320032903b803221c3703c802200341f0026a41086a41053a0000200341f9026a201c37000020034181036a201b37000020034189036a201a37000020034191036a2019370000200341123a00f00241b0b4cc004100200341f0026a10d40120064280808080707c21060b200f4200370300200e4200370300200c4200370300200342003703c802200410012201290000210420034180026a41086a2202200141086a290000370300200320043703800220011035200c200229030037030020032003290380023703c80220051001220129000021042002200141086a290000370300200320043703800220011035200e2003290380022204370300200d200c290300370300200341e8006a41106a2004370300200341e8006a41186a2002290300370300200320032903c802370368024020090d00200341e8006aad428080808080048410070c010b200341f0026a20092006422088a710b106200341e8006aad428080808080048420033502f80242208620032802f0022202ad841002024020032802f402450d00200210350b2006a72202450d00200241e8006c450d00200910350b200341f0026a20034188016a10b90620033502f80242208620032802f0022202ad841007024020032802f402450d00200210350b200341f0026a41086a41073a0000200341f9026a20032903880137000020034199036a20073a000020034181036a20034188016a41086a29030037000020034189036a20034198016a29030037000020034191036a200341a0016a290300370000200341123a00f00241b0b4cc004100200341f0026a10d401420021060c0b0b41b99cc8002107410c210141803221084180801021094100210a0b20004200370308200041206a20013602002000411c6a2007360200200041186a200a200972200872200272360200420121060c1a0b4102210141803221070240024020022d00000d0020022d00014101470d002002411a6a2901002104200241196a2d0000210a200241186a2d0000210b200241166a2f0100210c200241156a2d0000210d200241146a2d0000210e200241126a2f0100210f200241116a2d00002110200241106a2d000021112002410e6a2f010021122002410d6a2d000021132002410c6a2d000021142002410a6a2f01002115200241096a2d00002116200241086a2d00002117200241066a2f01002118200241056a2d00002121200241046a2d00002122200241026a2f01002123200341e8006a41186a22094200370300200341e8006a41106a22074200370300200341e8006a41086a220242003703002003420037036841a29bc800ad4280808080f0008410012208290000210620034180026a41086a2201200841086a29000037030020032006370380022008103520022001290300370300200320032903800237036841ef9bc800ad4280808080f000841001220829000021062001200841086a29000037030020032006370380022008103520072003290380022206370300200341c8026a41086a2002290300370300200341c8026a41106a2006370300200341c8026a41186a2001290300370300200320032903683703c802200341f0026a200341c8026a412010d50120032d00f00221012009200341f0026a41196a2900003703002007200341f0026a41116a2900003703002002200341f0026a41096a290000370300200320032900f1023703680240024020014101460d0041002102200341003a00b0010c010b200341b0016a41096a2002290300370000200341b0016a41116a2007290300370000200341b0016a41196a200929030037000041012102200341013a00b001200320032903683700b1010b20034189036a200437000020034188036a200a3a000020034187036a200b3a000020034185036a200c3b000020034184036a200d3a000020034183036a200e3a000020034181036a200f3b000020034180036a20103a0000200341ff026a20113a0000200341fd026a20123b0000200341fc026a20133a0000200341fb026a20143a0000200341f9026a20153b0000200341f8026a20163a0000200320173a00f702200320183b00f502200320213a00f402200320223a00f302200320233b00f102200341013a00f002024020020d0041bf9bc8002108410a2102410321014180b2c00021070c020b410321010240200341b0016a410172200341f0026a410172412010a008450d0041bf9bc8002108410a21024180b2c00021070c020b200341e8006a41186a22094200370300200341e8006a41106a22244200370300200341e8006a41086a220242003703002003420037036841a29bc800ad4280808080f0008410012225290000210620034180026a41086a2208202541086a29000037030020032006370380022025103520022008290300370300200320032903800237036841f69bc800ad4280808080c000841001222529000021062008202541086a2900003703002003200637038002202510352007200329038002370000200741086a2008290300370000200341c8026a41086a2002290300370300200341c8026a41106a2024290300370300200341c8026a41186a2009290300370300200320032903683703c802200341f0026a200341c8026a412010d50120032d00f00221252009200341f0026a41196a2900003703002024200341f0026a41116a2900003703002002200341f0026a41096a290000370300200320032900f102370368410121080240024020254101460d0041002108200341003a00b0010c010b200341b0016a41096a2002290300370000200341b0016a41116a2024290300370000200341b0016a41196a2009290300370000200341013a00b001200320032903683700b1010b20034189036a200437000020034188036a200a3a000020034187036a200b3a000020034185036a200c3b000020034184036a200d3a000020034183036a200e3a000020034181036a200f3b000020034180036a20103a0000200341ff026a20113a0000200341fd026a20123b0000200341fc026a20133a0000200341fb026a20143a0000200341f9026a20153b0000200341f8026a20163a0000200320173a00f702200320183b00f502200320213a00f402200320223a00f302200320233b00f102200341013a00f002024002402008450d00200341b0016a410172200341f0026a410172412010a008450d010b41b89bc8002108410721024180b2c40021070c020b42002106200341e8006a41186a22084200370300200341e8006a41106a22094200370300200341e8006a41086a220142003703002003420037036841a29bc800ad4280808080f00084220510012224290000211920034180026a41086a2202202441086a2900003703002003201937038002202410352001200229030037030020032003290380023703684189eaca00ad4280808080f000841001222429000021192002202441086a2900003703002003201937038002202410352007200329038002370000200741086a22242002290300370000200341c8026a41086a22252001290300370300200341c8026a41106a22262009290300370300200341c8026a41186a22272008290300370300200320032903683703c802200341c8026aad42808080808004842219100720084200370300200942003703002001420037030020034200370368200510012228290000211a2002202841086a2900003703002003201a370380022028103520012002290300370300200320032903800237036841f69bc800ad4280808080c0008410012228290000211a2002202841086a2900003703002003201a3703800220281035200720032903800237000020242002290300370000202520012903003703002026200929030037030020272008290300370300200320032903683703c8022019100720084200370300200942003703002001420037030020034200370368200510012228290000211a2002202841086a2900003703002003201a370380022028103520012002290300370300200320032903800237036841ef9bc800ad4280808080f0008410012228290000211a2002202841086a2900003703002003201a3703800220281035200720032903800237000020242002290300370000202520012903003703002026200929030037030020272008290300370300200320032903683703c8022019100720084200370300200942003703002001420037030020034200370368200510012228290000211a2002202841086a2900003703002003201a37038002202810352001200229030037030020032003290380023703684188aec900ad4280808080d0008410012228290000211a2002202841086a2900003703002003201a3703800220281035200720032903800237000020242002290300370000202520012903003703002026200929030037030020272008290300370300200320032903683703c8022019100720084200370300200942003703002001420037030020034200370368200510012228290000211a2002202841086a2900003703002003201a370380022028103520012002290300370300200320032903800237036841e1b8c800ad4280808080a0018410012228290000211a2002202841086a2900003703002003201a3703800220281035200720032903800237000020242002290300370000202520012903003703002026200929030037030020272008290300370300200320032903683703c802201910072008420037030020094200370300200142003703002003420037036820051001222829000021052002202841086a29000037030020032005370380022028103520012002290300370300200320032903800237036841e0aec900ad4280808080b002841001222829000021052002202841086a290000370300200320053703800220281035200720032903800237000020242002290300370000202520012903003703002026200929030037030020272008290300370300200320032903683703c8022019100820034191036a2004370000200341f0026a41206a200a3a00002003418f036a200b3a00002003418d036a200c3b00002003418c036a200d3a00002003418b036a200e3a000020034189036a200f3b0000200341f0026a41186a20103a000020034187036a20113a000020034185036a20123b000020034184036a20133a000020034183036a20143a000020034181036a20153b0000200341f0026a41106a20163a0000200341ff026a20173a0000200341fd026a20183b0000200341fc026a20213a0000200341fb026a20223a0000200341f9026a20233b0000200341f0026a41086a410e3a0000200341123a00f00241b0b4cc004100200341f0026a10d4010c0a0b0b20004200370308200041206a20023602002000411c6a2008360200200041186a2007200172360200420121060c190b200141246a280200210f200341c8016a200141196a290000370300200341c0016a200141116a290000370300200341b8016a200141096a290000370300200320012900013703b0014102210a2001412c6a280200210c200141286a280200210e4100210b20022d0000417f6a220d41024b0d01200141306a3502002104410021094100210102400240200d0e03000401000b200241086a2802004101742002410c6a2802004d0d024100210941002101200241046a28020041ff01710d030b200341e8006a41186a4200370300200341e8006a41106a22074200370300200341e8006a41086a220142003703002003420037036841a29bc800ad4280808080f0008410012208290000210620034180026a41086a2202200841086a29000037030020032006370380022008103520012002290300370300200320032903800237036841f69bc800ad4280808080c000841001220829000021062002200841086a29000037030020032006370380022008103520072003290380022206370300200341c8026a41086a2001290300370300200341c8026a41106a2006370300200341c8026a41186a2002290300370300200320032903683703c8024100210b200341386a200341c8026a412041b0b4cc0041004100108a024103210a4180322101024020032802384101470d0041a39cc8002108410e21074180801821090c030b0240200f41024f0d0041a99bc8002108410a21074180803c21090c030b200341e8006a41186a22084200370300200341e8006a41106a22094200370300200341e8006a41086a220142003703002003420037036841a29bc800ad4280808080f0008422051001220a290000210620034180026a41086a2202200a41086a2900003703002003200637038002200a103520012002290300370300200320032903800237036841a99bc800ad4280808080a001841001220a29000021062002200a41086a2900003703002003200637038002200a10352007200329038002370000200741086a220b2002290300370000200341c8026a41086a220d2001290300370300200341c8026a41106a22102009290300370300200341c8026a41186a22112008290300370300200320032903683703c8022003200f3602f002200341c8026aad42808080808004842206200341f0026aad4280808080c000841002200341f0026a200341b0016a10d806024020032d00f002220a4104470d002008420037030020094200370300200142003703002003420037036820051001220a29000021052002200a41086a2900003703002003200537038002200a103520012002290300370300200320032903800237036841f69bc800ad4280808080c000841001220a29000021052002200a41086a2900003703002003200537038002200a10352007200329038002370000200b2002290300370000200d20012903003703002010200929030037030020112008290300370300200320032903683703c802412010332202450d01200220032903b001370000200241186a200341b0016a41186a220b290300370000200241106a200341b0016a41106a220d290300370000200241086a200341b0016a41086a220f29030037000020062002ad4280808080800484100220021035200341e8006a41186a22094200370300200341e8006a41106a220a4200370300200341e8006a41086a220842003703002003420037036841a29bc800ad4280808080f00084220510012201290000211920034180026a41086a2202200141086a29000037030020032019370380022001103520082002290300370300200320032903800237036841ef9bc800ad4280808080f000841001220129000021192002200141086a2900003703002003201937038002200110352007200329038002370000200741086a22102002290300370000200341c8026a41086a22112008290300370300200341c8026a41106a2212200a290300370300200341c8026a41186a22132009290300370300200320032903683703c802412010332201450d01200120032903b001370000200141186a200b290300370000200141106a200d290300370000200141086a200f29030037000020062001ad4280808080800484100220011035200341f0026a41186a2004422086200ead841009220141186a290000370300200341f0026a41106a200141106a290000370300200341f0026a41086a200141086a290000370300200320012900003703f0022001103520094200370300200a4200370300200842003703002003420037036820051001220129000021042002200141086a2900003703002003200437038002200110352008200229030037030020032003290380023703684188aec900ad4280808080d000841001220129000021042002200141086a290000370300200320043703800220011035200720032903800237000020102002290300370000201120082903003703002012200a29030037030020132009290300370300200320032903683703c802412010332202450d01200220032903f002370000200241186a200341f0026a41186a290300370000200241106a200341f0026a41106a290300370000200241086a200341f0026a41086a220129030037000020062002ad4280808080800484100220021035200141003a0000200341f9026a20032903b00137000020034181036a200341b0016a41086a29030037000020034189036a200341b0016a41106a29030037000020034191036a200341b0016a41186a290300370000200341123a00f00241b0b4cc004100200341f0026a10d401200c450d07200e1035420021060c080b200341f0026a41086a280200210720032802f402210820032d00f102410874210120032d00f202411074210920032d00f302411874210b0c020b1045000b41002109410021010b0240200c450d00200e10350b20004200370308200041206a20073602002000411c6a2008360200200041186a200b200972200172200a72360200420121060c150b20032002411a6a290100370380014102210a2003200241026a29010037036820032002410a6a2901003703702003200241126a2901003703784101210b410021010240024002400240024020022d000041004720022d0001410147720d00200341b0016a41186a200341e8006a41186a290300370300200341b0016a41106a200341e8006a41106a290300370300200341b0016a41086a200341e8006a41086a2202290300370300200320032903683703b001200341f0026a41186a4200370300200341f0026a41106a220f4200370300200341f0026a41086a22074200370300200342003703f00241a29bc800ad4280808080f000841001220829000021062007200841086a290000370300200320063703f002200810354189eaca00ad4280808080f000841001220829000021062002200841086a2900003703002003200637036820081035200f20032903682206370300200341c8026a41086a2007290300370300200341c8026a41106a2006370300200341c8026a41186a2002290300370300200320032903f0023703c802200341f0026a200341c8026a10fe0120032802f0022202410120021b210941f2dfca00210c4109210d4103210a4119210e0240024020032902f402420020021b2206422088a7220241014b0d0020020e020401040b4100210103402002410176220720016a22082001200920084105746a200341b0016a412010a0084101481b2101200220076b220241014b0d000b0b200920014105746a200341b0016a412010a0080d02200341f0026a200341b0016a10b806200341c8026a20032802f002220720032802f80210b40220032902cc02210420032802c8022201410820011b2102024020032802f402450d00200710350b2004420020011b210402402002450d002004422088a72210450d00200341f0026a41186a22084200370300200341f0026a41106a220a4200370300200341f0026a41086a22014200370300200342003703f00241d1c4c700ad4280808080e000841001220729000021052001200741086a290000370300200320053703f0022007103541e7c4c700ad4280808080e00084100122072900002105200341e8006a41086a220b200741086a2900003703002003200537036820071035200f2003290368370000200f41086a200b290300370000200341c8026a41086a22072001290300370300200341c8026a41106a200a290300370300200341c8026a41186a2008290300370300200320032903f0023703c802200341306a200341c8026a412010c00120022802002003280234410020032802301b4b0d00200342f0f2bd99f7edd8b4e5003703c802200341f0026a200341c8026a108106200341c8026a200341f0026a200341b0016a2002290308200241106a290300410110e6022007280200210d20032802cc02210c20032d00cb02210720032d00ca02210b20032d00c902210e024020032d00c802220a4104470d002002200241186a2010417f6a220141186c109e08210802402001450d00200341f0026a200341b0016a10b80620032802f0022102200320032802f8023602cc02200320023602c80220082001200341c8026a109603024020032802f402450d00200210350b4104210a2004a72202450d04200241186c450d04200810350c040b200341f0026a200341b0016a10b80620033502f80242208620032802f0022201ad841007024020032802f402450d00200110350b200442ffffffff0f8321044104210a0b2004a72201450d03200141186c450d03200210350c030b02402004a72201450d00200141186c450d00200210350b0240200642ffffff3f83500d00200910350b41b19cc800210c4108210d4103210a4119210e4105210b0c030b0c020b0b0240200642ffffff3f83500d00200910350b42002106200a4104460d010b200041206a200d3602002000411c6a200c360200200041186a2007411874200b41ff017141107472200e41ff017141087472200a72360200420121060b200042003703080c140b20012d0001210a20032002411a6a29010037038001410221012003200241026a29010037036820032002410a6a2901003703702003200241126a29010037037802400240024020022d00014101470d0020022d000041ff01710d00200341b0016a41186a200341e8006a41186a290300370300200341b0016a41106a200341e8006a41106a290300370300200341b0016a41086a200341e8006a41086a2202290300370300200320032903683703b001200341f0026a41186a4200370300200341f0026a41106a22084200370300200341f0026a41086a22014200370300200342003703f00241a29bc800ad4280808080f000841001220729000021062001200741086a290000370300200320063703f002200710354189eaca00ad4280808080f000841001220729000021062002200741086a2900003703002003200637036820071035200820032903682206370300200341c8026a41086a2001290300370300200341c8026a41106a2006370300200341c8026a41186a2002290300370300200320032903f0023703c802200341f0026a200341c8026a10fe0120032802f0022201410120011b21094100210202400240024020032902f402420020011b2206422088a7220141014b0d0020010e020201020b03402001410176220720026a22082002200920084105746a200341b0016a412010a0084101481b2102200120076b220141014b0d000b0b200920024105746a200341b0016a412010a0080d00200a41ff01710d02200341013a00c802200341f0026a200341b0016a10b30620033502f802210420032802f0022101410110332202450d0c200241013a000020044220862001ad842002ad4280808080108410022002103520032802f402450d03200110350c030b02402006a72202450d00200241ffffff3f71450d00200910350b410321010b20004200370308200041206a41093602002000411c6a41f2dfca00360200200041186a20014180b20472360200420121060c150b200341023a00c802200341f0026a200341b0016a10b30620033502f802210420032802f0022101410110332202450d09200241023a000020044220862001ad842002ad4280808080108410022002103520032802f402450d00200110350b200341f0026a41086a410c3a0000200341f9026a20032903b00137000020034181036a200341b0016a41086a29030037000020034189036a200341c0016a29030037000020034191036a200341c8016a29030037000020034199036a200a3a0000200341123a00f00241b0b4cc004100200341f0026a10d401200642ffffff3f83500d0120091035420021060c020b20012d0001210c200341b0016a41206a2208200141246a280200360200200341b0016a41186a22092001411c6a290200370300200341b0016a41106a220a200141146a290200370300200341b0016a41086a220b2001410c6a2902003703002003200141046a2902003703b00120032002411a6a2901003703e002410221012003200241026a2901003703c80220032002410a6a2901003703d0022003200241126a2901003703d80241002107024020022d000041004720022d000141014772450d000c050b20034180026a41186a200341c8026a41186a29030037030020034180026a41106a200341c8026a41106a29030037030020034180026a41086a200341c8026a41086a290300370300200320032903c80237038002200341f0026a41206a2008280200360200200341f0026a41186a2009290300370300200341f0026a41106a200a290300370300200341f0026a41086a200b290300370300200320032903b0013703f002200341c8026a200341f0026a108b02200341e8006a41086a200341d1026a290000370300200341e8006a41106a200341d9026a290000370300200341e8006a41186a200341e1026a290000370300200320032900c90237036820032d00c8024101460d0220034188016a41186a200341e8006a41186a29030037030020034188016a41106a200341e8006a41106a29030037030020034188016a41086a200341e8006a41086a22022903003703002003200329036837038801200341f0026a41186a4200370300200341f0026a41106a22084200370300200341f0026a41086a22014200370300200342003703f00241a29bc800ad4280808080f000841001220729000021062001200741086a290000370300200320063703f0022007103541e1b8c800ad4280808080a001841001220729000021062002200741086a2900003703002003200637036820071035200820032903682206370300200341c8026a41086a2001290300370300200341c8026a41106a2006370300200341c8026a41186a2002290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b220a20032902f402420020021b2206422088a741e8006c6a2107200a21020340024020022007470d0041c99bc8002108410c21024180803821070c050b024020034188016a200241c8006a2201460d00200141206a2102200120034188016a412010a0080d010b0b200341f0026a41186a22074200370300200341f0026a41106a22094200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f000841001220129000021042002200141086a290000370300200320043703f002200110354189eaca00ad4280808080f00084100122012900002104200341e8006a41086a220b200141086a290000370300200320043703682001103520082003290368370000200841086a200b290300370000200341c8026a41086a2002290300370300200341c8026a41106a2009290300370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10fe0120032802f0022201410120011b2109410021020240024002400240024020032902f402420020011b2204422088a7220141014b0d0020010e020201020b03402001410176220720026a22082002200920084105746a20034180026a412010a0084101481b2102200120076b220141014b0d000b0b200920024105746a20034180026a412010a0080d00200c41ff01710d01200341013a00c802200341f0026a20034188016a20034180026a10b20620033502f802210520032802f0022101410110332202450d0a200241013a000020054220862001ad842002ad4280808080108410022002103520032802f402450d02200110350c020b41f2dfca00210841092102418080042107200442ffffff3f83500d05200910350c050b200341023a00c802200341f0026a20034188016a20034180026a10b20620033502f802210520032802f0022101410110332202450d08200241023a000020054220862001ad842002ad4280808080108410022002103520032802f402450d00200110350b200341f0026a41086a410b3a0000200341f9026a20032903880137000020034181036a20034188016a41086a29030037000020034189036a20034188016a41106a29030037000020034191036a20034188016a41186a29030037000020034199036a200329038002370000200341a1036a20034180026a41086a290300370000200341a9036a20034180026a41106a290300370000200341b1036a20034180026a41186a290300370000200341123a00f002200341b9036a200c3a000041b0b4cc004100200341f0026a10d4010240200442ffffff3f83500d00200910350b2006a72202450d00200241e8006c450d00200a10350b420021060b200020063703080c100b410121010c010b410321012006a72209450d00200941e8006c450d00200a10350b200041206a20023602002000411c6a2008360200200041186a20074180803c712001724180327236020020004200370308420121060c0d0b4102210702400240024020022d00000d0020022d00014101470d00200141046a2802002118200241196a2d00002101200241186a2d00002107200241166a2f01002108200241156a2d00002109200241146a2d0000210a200241126a2f0100210b200241116a2d0000210c200241106a2d0000210d2002410e6a2f0100210e2002410d6a2d0000210f2002410c6a2d000021102002410a6a2f01002111200241096a2d00002112200241086a2d00002113200241066a2f01002114200241056a2d00002115200241046a2d00002116200241026a2f0100211720032002411a6a2901003703c801200320013a00c701200320073a00c601200320083b01c401200320093a00c3012003200a3a00c2012003200b3b01c0012003200c3a00bf012003200d3a00be012003200e3b01bc012003200f3a00bb01200320103a00ba01200320113b01b801200320123a00b701200320133a00b601200320143b01b401200320153a00b301200320163a00b201200320173b01b001200341f0026a200341b0016a10d00620032802f002220120032802f80210d10241ff01712102024020032802f402450d00200110350b4103210720020d00200341f0026a41186a4200370300200341f0026a41106a22074200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008422041001220129000021062002200141086a290000370300200320063703f00220011035419cbac800ad4280808080c000842205100122012900002106200341e8006a41086a220b200141086a2900003703002003200637036820011035200720032903682206370300200341c8026a41086a22082002290300370300200341c8026a41106a220c2006370300200341c8026a41186a2209200b290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022201410820011b210a410b210202400240201820032902f402420020011b2206422088a72201490d0041db9cc800210141833221070c010b41803221070240200a201841e8006c6a220d2d00000d0041e683ca0021010c010b0240200341b0016a200d41016a2202460d002002200341b0016a412010a008450d0041d483ca002101411221020c010b200341f0026a200341b0016a10d00620033502f80242208620032802f0022202ad841007024020032802f402450d00200210350b200341f0026a200a201841e8006c6a220241e800109d081a2002200241e8006a20012018417f736a41e8006c109e081a200341e0026a200341d0036a2903002219370300200341d8026a200341c8036a290300221a370300200341c8026a41086a200341c0036a290300221b370300200320032903b803221c3703c802200341f0026a41086a41053a0000200341f9026a201c37000020034181036a201b37000020034189036a201a37000020034191036a2019370000200341123a00f00241b0b4cc004100200341f0026a10d40120064280808080707c210641843221070b20094200370300200c420037030020084200370300200342003703c80220041001220d290000210420034180026a41086a2209200d41086a2900003703002003200437038002200d10352008200929030037030020032003290380023703c80220051001220d29000021042009200d41086a2900003703002003200437038002200d1035200c2003290380022204370300200b2008290300370300200341e8006a41106a2004370300200341e8006a41186a2009290300370300200320032903c80237036802400240200a0d00200341e8006aad428080808080048410070c010b200341f0026a200a2006422088a710b106200341e8006aad428080808080048420033502f80242208620032802f0022208ad841002024020032802f402450d00200810350b2006a72208450d00200841e8006c450d00200a10350b4180322108420021062007418432460d020c010b41fa9bc8002101410b21024180b22421080b200041206a20023602002000411c6a2001360200200041186a2008200741ff017172360200420121060b200042003703080c0c0b200141c0006a2903002119200141386a290300211a200141306a2903002104200141286a290300210520034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a29000037030020032001290001370388012002411a6a2901002106200241196a2d00002107200241186a2d00002108200241166a2f01002109200241156a2d0000210a200241146a2d0000210b200241126a2f0100210c200241116a2d0000210d200241106a2d0000210e2002410e6a2f0100210f2002410d6a2d000021102002410c6a2d000021112002410a6a2f01002112200241096a2d00002113200241086a2d00002114200241066a2f01002115200241056a2d00002116200241046a2d00002117200241026a2f0100211841012101024020022d00000d0020022d000141014721010b2003200637038001200320073a007f200320083a007e200320093b017c2003200a3a007b2003200b3a007a2003200c3b01782003200d3a00772003200e3a00762003200f3b0174200320103a0073200320113a0072200320123b0170200320133a006f200320143a006e200320153b016c200320163a006b200320173a006a200320183b016802400240024020010d00200341b0016a41186a200341e8006a41186a290300370300200341b0016a41106a200341e8006a41106a290300370300200341b0016a41086a200341e8006a41086a290300370300200320032903683703b001200341f0026a20034188016a10cf06200341286a20032802f002220220032802f80241b0b4cc0041004100108a0220032802282101024020032802f402450d00200210350b4103210220014101460d01200341f0026a20034188016a10b906200341206a20032802f002220720032802f80241b0b4cc0041004100108a0220032802202101024020032802f402450d00200710350b20014101460d01200341f0026a41186a4200370300200341f0026a41106a220b4200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f000841001220129000021062002200141086a290000370300200320063703f00220011035419cbac800ad4280808080c00084100122012900002106200341e8006a41086a2207200141086a2900003703002003200637036820011035200b20032903682206370300200341c8026a41086a2002290300370300200341c8026a41106a2006370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b220c20032902f402420020021b2206422088a741e8006c6a210a200c2102024003402002200a460d0141e59bc8002108410a2109410c210720034188016a200241c8006a2201460d08200141206a2102200120034188016a412010a0080d000c080b0b200341f0026a41186a22074200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008410012201290000211b2002200141086a2900003703002003201b3703f0022001103541e1b8c800ad4280808080a0018410012201290000211b200341e8006a41086a2209200141086a2900003703002003201b37036820011035200b2003290368370000200b41086a2009290300370000200341c8026a41086a2002290300370300200341c8026a41106a2008290300370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f0022202410820021b220e20032902f402420020021b221b422088a741e8006c6a210a200e2102024003402002200a460d0141d59bc800210841102109410d210720034188016a200241c8006a2201460d07200141206a2102200120034188016a412010a0080d000c070b0b200341f0026a41186a22074200370300200341f0026a41106a22084200370300200341f0026a41086a22024200370300200342003703f00241a29bc800ad4280808080f0008410012201290000211c2002200141086a2900003703002003201c3703f002200110354189eaca00ad4280808080f0008410012201290000211c200341e8006a41086a2209200141086a2900003703002003201c37036820011035200b2003290368370000200b41086a2009290300370000200341c8026a41086a2002290300370300200341c8026a41106a2008290300370300200341c8026a41186a2007290300370300200320032903f0023703c802200341f0026a200341c8026a10fe014101210720032802f0022201410120011b210b41f2dfca0021084109210941002102024020032902f402420020011b221c422088a7220d41014b0d00200d0e020503050b200d210103402001410176220720026a220a2002200b200a4105746a20034188016a412010a0084101481b2102200120076b220141014b0d000c030b0b410221020b41c59cc800210841092109410321070c050b0240200b20024105746a20034188016a412010a0080d0041ce9cc8002108410d2109410221070c020b410121074100210202400240200d41014b0d00200d0e020301030b0340200d410176220120026a220a2002200b200a4105746a200341b0016a412010a0084101481b2102200d20016b220d41014b0d000b0b200b20024105746a200341b0016a412010a0080d01200341f0026a200341b0016a10d006200341186a20032802f002220120032802f80241b0b4cc0041004100108a0220032802182102024020032802f402450d00200110350b024020024101470d0041859cc8002108410f2109410821070c020b200341f0026a200341b0016a10d00620033502f802211d20032802f0022101410110332202450d00200241003a0000201d4220862001ad842002ad42808080801084100220021035024020032802f402450d00200110350b200320063702cc022003200c3602c802200341a0036a201937030020034189036a2202200341b0016a41186a220129030037000020034181036a2207200341b0016a41106a2208290300370000200341f9026a2209200341b0016a41086a220a2903003700002003201a37039803200320032903b0013700f102200341013a00f002200341c8026a20034188016a20052004200341f0026a10d606200341c8036a2004370300200341c0036a2005370300200341f0026a41086a41023a00002009200329038801370000200720034188016a41086a290300370000200220034188016a41106a29030037000020034191036a20034188016a41186a29030037000020034199036a20032903b001370000200341a1036a200a290300370000200341a9036a2008290300370000200341b1036a2001290300370000200341123a00f00241b0b4cc004100200341f0026a10d4010240201c42ffffff3f83500d00200b10350b0240201ba72202450d00200241e8006c450d00200e10350b420021060c050b103c000b201c42ffffff3f83500d00200b10350b201ba72202450d00200241e8006c450d00200e10350b02402006a72202450d00200241e8006c450d00200c10350b410321020b200041206a20093602002000411c6a2008360200200041186a200741107420027241803272360200420121060b200042003703080c050b410221070240024020022d00000d0020022d00014101470d002002411a6a2901002106200241196a2d00002108200241186a2d0000210a200241166a2f0100210b200241156a2d0000210c200241146a2d0000210d200241126a2f0100210e200241116a2d0000210f200241106a2d000021102002410e6a2f010021112002410d6a2d000021122002410c6a2d000021132002410a6a2f01002114200241096a2d00002115200241086a2d00002116200241066a2f01002117200241056a2d00002118200241046a2d00002121200241026a2f010021222003200141046a28020022093602a002200341f0026a41186a4200370300200341f0026a41106a22234200370300200341f0026a41086a22014200370300200342003703f00241a29bc800ad4280808080f0008422041001220229000021052001200241086a290000370300200320053703f00220021035419cbac800ad4280808080c000842205100122072900002119200341e8006a41086a2202200741086a2900003703002003201937036820071035202320032903682219370300200341c8026a41086a22232001290300370300200341c8026a41106a22242019370300200341c8026a41186a22252002290300370300200320032903f0023703c802200341f0026a200341c8026a10be0220032802f002210120032902f4022119200341a4016a2006370200200341a3016a20083a0000200341a2016a200a3a000020034188016a41186a200b3b01002003419f016a200c3a00002003419e016a200d3a00002003419c016a200e3b01002003419b016a200f3a00002003419a016a20103a000020034188016a41106a20113b010020034197016a20123a000020034196016a20133a000020034194016a20143b010020034193016a20153a000020034192016a20163a000020034188016a41086a20173b0100200320183a008f01200320213a008e01200320223b018c012001410820011b21082003200341a0026a360288014183322107024020092019420020011b2206422088a7220a4f0d0002402008200941e8006c6a220141c8006a220c20034188016a410472220b460d00200c200b412010a0080d010b20012d00002107200320012800013602682003200141046a28000036006b200141106a2903002119200141086a290300211a200341b0016a200141186a41d000109d081a2001200141e8006a2009417f73200a6a41e8006c109e081a0240024020074101470d00200341ff026a20193700002003418f036a200341b0016a41086a2d00003a00002003201a3700f7022003200328006b3600f302200320032802683602f002200320032903b00137008703200341c8026a200341f0026a10d00620033502d00242208620032802c8022201ad84100720032802cc02450d01200110350c010b2003201a370380022003201937038802201a201984500d002003200b3602b802200341c8026a200b20034180026a200341b8026a10f00220032903c8024201520d0020032903d0022119200341a8036a200341c8026a41106a290300370300200341a0036a2019370300200341f0026a41086a41003a0000200341f9026a200b29000037000020034181036a200b41086a29000037000020034189036a200b41106a29000037000020034191036a200b41186a290000370000200341033a00f00241b0b4cc004100200341f0026a10d4010b20064280808080707c2106200341f8026a41043a0000200341f9026a200329028c0137000020034181036a20034194016a29020037000020034189036a2003419c016a29020037000020034191036a200341a4016a290200370000200341123a00f00241b0b4cc004100200341f0026a10d40141843221070b200341e8006a41186a4200370300200341e8006a41106a220a42003703002002420037030020034200370368200410012209290000210420034180026a41086a2201200941086a29000037030020032004370380022009103520022001290300370300200320032903800237036820051001220929000021042001200941086a290000370300200320043703800220091035200a2003290380022204370300202320022903003703002024200437030020252001290300370300200320032903683703c8020240024020080d00200341c8026aad428080808080048410070c010b200341f0026a20082006422088a710b106200341c8026aad428080808080048420033502f80242208620032802f0022202ad841002024020032802f402450d00200210350b2006a72202450d00200241e8006c450d00200810350b420021062007418432460d010b2000411c6a41db9cc800ad4280808080b00184370200200041186a200741ff017141803272360200420121060b200042003703080c040b410221070b41c59cc8002108410921094119210a4103210b0b200041206a20093602002000411c6a2008360200200041186a200c411874200b41ff017141107472200a41ff017141087472200741ff017172360200420121060b200042003703080b2000200637030020034180046a24000bbb6504147f017e037f027e230041c0046b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e0a00010203040506070809000b200341e4016a4101360200200342013702d401200341e8d4ca003602d00120034104360284042003419cd5ca0036028004200320034180046a3602e001200341d0016a41b0b4cc00104c000b200141246a2802002104200341c8006a41186a200141196a290000370300200341c8006a41106a200141116a290000370300200341c8006a41086a200141096a29000037030020032001290001370348410a2105410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a29010037038001200320013a007f200320063a007e200320073b017c200320083a007b200320093a007a2003200a3b01782003200b3a00772003200c3a00762003200d3b01742003200e3a00732003200f3a0072200320103b0170200320113a006f200320123a006e200320133b016c200320143a006b200320153a006a200320163b0168200341a8046a200341e8006a109507200341d0016a20032802a804220120032802b00410d50120034180046a41086a2202200341da016a29010037030020034180046a41106a2206200341e2016a29010037030020034180046a41176a2207200341e9016a290000370000200320032901d201370380040240024020032d00d0014101470d0020032d00d1012108200341a8016a41176a2007290000370000200341a8016a41106a2006290300370300200341a8016a41086a200229030037030020032003290380043703a801024020032802ac04450d00200110350b20034191016a200341a8016a41086a29030037000020034199016a200341a8016a41106a29030037000020034188016a41186a200341bf016a290000370000200320083a008801200320032903a8013700890120034188016a200341c8006a412010a0080d01200341d0016a200441b002109d081a2003418a046a200341c8006a41086a29030037010020034192046a200341c8006a41106a2903003701002003419a046a200341c8006a41186a29030037010020034180023b0180042003200329034837018204200341a8016a200341d0016a20034180046a10ac0320032903a8014201510d030c250b20032802ac04450d00200110350b410321010b200410ba0241cdd7ca002108418034210741002102410021060c230b20032903b0014202510d21200341c8016a2802002105200341c4016a2802002108200341c0016a2802002201418080807871210220014180807c712106200141807e7121070c220b200341a8016a41186a200141196a290000370300200341a8016a41106a200141116a290000370300200341a8016a41086a200141096a290000370300200320012900013703a80120034180046a41186a200141396a29000037030020034180046a41106a200141316a29000037030020034180046a41086a200141296a2900003703002003200141216a2900003703800420022d000120022d0000410047720d08200341d0016a20034180046a10950720033502d801211720032802d0012102412010332201450d07200120032903a801370000200141186a200341a8016a41186a2204290300370000200141106a200341a8016a41106a2205290300370000200141086a200341a8016a41086a220629030037000020174220862002ad842001ad4280808080800484100220011035024020032802d401450d00200210350b200341f2016a200329038004370100200341da016a2006290300370100200341e2016a2005290300370100200341ea016a2004290300370100200341fa016a20034180046a41086a29030037010020034182026a20034180046a41106a2903003701002003418a026a20034180046a41186a29030037010020034193083b01d001200320032903a8013701d20141b0b4cc004100200341d0016a10d4010c150b200141086a2802002107200141046a28020021094102210520022d00000d1d20022d00014101470d1d2001410c6a2802002118200141106a2802002119200141026a2f0100211a200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002108200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703c001200320013a00bf01200320043a00be01200320053b01bc01200320063a00bb01200320083a00ba012003200a3b01b8012003200b3a00b7012003200c3a00b6012003200d3b01b4012003200e3a00b3012003200f3a00b201200320103b01b001200320113a00af01200320123a00ae01200320133b01ac01200320143a00ab01200320153a00aa01200320163b01a801200341d0016a200341a8016a109607200341186a20032802d001220120032802d80141b0b4cc0041004100108a0220032802182102024020032802d401450d00200110350b4101210141032105411a2106024020024101470d0041fdd6ca00210441122102410621010c1f0b0240201a0d0041c0d7ca002104410d21020c1f0b41b0d7ca0021044110210241022101024020180d000c1f0b02402018201a4f0d000c1f0b410321050240201841094d0d0041a6d7ca002104410a2102410321010c1f0b201841016a210a2009210802400340200a417f6a220a4102490d012008200841206a220b412010a008210c419dd7ca0021044109210241042101200b2108200c4100480d000b0c1f0b200341086a2018ad42004280c0f4c198af0b420010840820032003290308221b4280808d93f5d7f1007c2217370388012003200341086a41086a2903002017201b54ad7c221b370390012003200341a8016a3602482003200341a8016a3602682003200341e8006a3602d8012003200341c8006a3602d401200320034188016a3602d00120034180046a200341a8016a200341d0016a108c03024002402003280280044101470d002003418c046a280200210220034180046a41086a280200210420032d008704210820032d008604210120032d008504210620032d00840421050c010b41042105024020034180046a41086a2903004201520d0020034180046a41106a290300211c2003280268210120034188026a20034180046a41186a29030037030020034180026a201c370300200341d0016a41086a41003a0000200341d9016a2001290000370000200341e1016a200141086a290000370000200341e9016a200141106a290000370000200341f1016a200141186a290000370000200341033a00d00141b0b4cc004100200341d0016a10d4010b0b200541ff01714104470d1e20034180046a200341a8016a109607200335028804211c200328028004210e200341003602d801200342013703d001410410332201450d1c200341043602d401200320013602d00120012019360000200341043602d80120014104411410372201450d1c200120173700042001410c6a201b370000200320013602d00120034294808080c0023702d4012018200341d0016a10772018410574210c410020032802d801220b6b210d20032802d401210541002106410021010340200b20016a210802400240200d20056a20066a4120490d0020032802d00121022005210a0c010b200841206a22022008490d0b200541017422042002200420024b1b220a4100480d0b0240024020050d000240200a0d00410121020c020b200a103322020d010c200b20032802d00121022005200a460d0020022005200a10372202450d1f0b2003200a3602d401200320023602d001200a21050b2002200b6a20016a2202200920016a2204290000370000200241186a200441186a290000370000200241106a200441106a290000370000200241086a200441086a2900003700002003200841206a3602d801200641606a2106200c200141206a2201470d000b200b20016a210502400240200a200b6b20016b4102490d0020032802d0012102200a21040c010b200541026a22022005490d0a200a41017422042002200420024b1b22044100480d0a02400240200a0d00024020040d00410121020c020b200410332202450d1f0c010b20032802d0012102200a2004460d002002200a200410372202450d1e0b200320043602d401200320023602d0010b2002200b6a20016a201a3b0000201c422086200ead84200541026aad4220862002ad84100202402004450d00200210350b0240200328028404450d00200e10350b0240200741ffffff3f71450d00200910350b200341da016a200341b0016a290300370100200341e2016a200341b8016a290300370100200341ea016a200341c0016a290300370100200341133b01d001200320032903a8013701d20141b0b4cc004100200341d0016a10d4010c140b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a29000037030020032001290001370388014102210120022d00000d1920022d00014101470d19200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703c001200320013a00bf01200320043a00be01200320053b01bc01200320063a00bb01200320073a00ba01200320083b01b801200320093a00b7012003200a3a00b6012003200b3b01b4012003200c3a00b3012003200d3a00b2012003200e3b01b0012003200f3a00af01200320103a00ae01200320113b01ac01200320123a00ab01200320133a00aa01200320143b01a801200341d0016a20034188016a109607200341306a20032802d001220120032802d80141b0b4cc0041004100108a0220032802302105024020032802d401450d00200110350b410e210441032101411a2102024020054101460d00418fd7ca002107410521060c1b0b200341d0016a20034188016a200341a8016a109707200341286a20032802d001220620032802d80141b0b4cc0041004100108a0220032802282105024020032802d401450d00200610350b024020054101470d0041efd6ca002107410721060c1b0b2003420037037020034280808d93f5d7f1003703682003200341a8016a3602a8042003200341a8016a3602482003200341c8006a3602d8012003200341a8046a3602d4012003200341e8006a3602d00120034180046a200341a8016a200341d0016a108c03024002402003280280044101470d002003418c046a280200210420034188046a280200210720032d008704210520032d008604210620032d008504210220032d00840421010c010b41042101024020034180046a41086a2903004201520d0020034180046a41106a29030021172003280248210220034188026a20034180046a41186a29030037030020034180026a2017370300200341d0016a41086a41003a0000200341d9016a2002290000370000200341e1016a200241086a290000370000200341e9016a200241106a290000370000200341f1016a200241186a290000370000200341033a00d00141b0b4cc004100200341d0016a10d4010b0b200141ff01714104470d1a42002117200341d0016a41186a4200370300200341d0016a41106a22044200370300200341d0016a41086a22014200370300200342003703d00141d1c4c700ad4280808080e0008410012202290000211b2001200241086a2900003703002003201b3703d0012002103541e7c4c700ad4280808080e0008410012202290000211b200341e8006a41086a2205200241086a2900003703002003201b3703682002103520042003290368221b37030020034180046a41086a200129030037030020034180046a41106a201b37030020034180046a41186a2005290300370300200320032903d00137038004200341206a20034180046a412010c0012003280224210120032802202102200341ec016a4100360200200342003703d80120034280808d93f5d7f1003703d001200342013702e40120032001410020021b3602e00120034180046a20034188016a200341a8016a1097072003280280042101200320032802880436026c20032001360268200341d0016a200341e8006a1094070240200328028404450d00200110350b200341da016a20034188016a41086a290300370100200341e2016a20034188016a41106a290300370100200341ea016a20034188016a41186a290300370100200341f2016a20032903a801370100200341fa016a200341a8016a41086a29030037010020034182026a200341a8016a41106a2903003701002003418a026a200341a8016a41186a29030037010020034193023b01d00120032003290388013701d20141b0b4cc004100200341d0016a10d4010c140b200341e8006a41186a200141196a290000370300200341e8006a41106a200141116a290000370300200341e8006a41086a200141096a2900003703002003200129000137036820034188016a41186a200141396a29000037030020034188016a41106a200141316a29000037030020034188016a41086a200141296a2900003703002003200141216a290000370388014102210120022d00000d1620022d00014101470d16200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703c001200320013a00bf01200320043a00be01200320053b01bc01200320063a00bb01200320073a00ba01200320083b01b801200320093a00b7012003200a3a00b6012003200b3b01b4012003200c3a00b3012003200d3a00b2012003200e3b01b0012003200f3a00af01200320103a00ae01200320113b01ac01200320123a00ab01200320133a00aa01200320143b01a80120034180046a200341e8006a109607200341d0016a200328028004220420032802880410e20220032802840421020240024020032802e4012207450d00200341ec016a280200210120032802e801210902402002450d00200410350b200341c8006a200341e8006a20034188016a109707200341d0016a20032802482202200328025010d00241082104200341d0016a41086a290300211b20032903d001211c20032903e801211720032802e401210820032802e00121050240200328024c450d00200210350b20080d0141e5d6ca002106410a21050c170b02402002450d00200410350b418fd7ca002106410e210541032101410521040c180b20034198046a20173703002003201c37038004200320083602940420032005360290042003201b370388042017a7210a41dcd6ca0021064100210202400240200141014b0d00410921044109210520010e021101110b03402001410176220420026a22052002200720054105746a200341a8016a412010a0084101481b2102200120046b220141014b0d000b0b4109210441092105200720024105746a200341a8016a412010a0080d0f4100210102402017422088a7220641014b0d00024020060e020010000b200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d00141002104200341d0016a21020c120b2006210203402002410176220420016a22052001200820054105746a200341a8016a412010a0084101481b2101200220046b220241014b0d000c0f0b0b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a2900003703002003200129000137038801410e210441052105410221010240024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002106200241166a2f01002107200241156a2d00002108200241146a2d00002109200241126a2f0100210a200241116a2d0000210b200241106a2d0000210c2002410e6a2f0100210d2002410d6a2d0000210e2002410c6a2d0000210f2002410a6a2f01002110200241096a2d00002111200241086a2d00002112200241066a2f01002113200241056a2d00002114200241046a2d00002115200241026a2f0100211620032002411a6a2901003703c001200320013a00bf01200320063a00be01200320073b01bc01200320083a00bb01200320093a00ba012003200a3b01b8012003200b3a00b7012003200c3a00b6012003200d3b01b4012003200e3a00b3012003200f3a00b201200320103b01b001200320113a00af01200320123a00ae01200320133b01ac01200320143a00ab01200320153a00aa01200320163b01a80120034180046a20034188016a109607200341d0016a200328028004220220032802880410e2022003280284042101024020032802e4012206450d00200341f0016a2f0100210920032802e801210720032802e001210802402001450d00200210350b20034180046a20034188016a200341a8016a109707200341d0016a200328028004220220032802880410d00220032903e801211720032802e401210120032802e00121050240200328028404450d00200210350b20010d0241e5d6ca002102410a2104410821050c0e0b02402001450d00200210350b410321010b418fd7ca0021020c0d0b200341d0016a200341a8016a109507200341c0006a20032802d001220420032802d80141b0b4cc0041004100108a0220032802402102024020032802d401450d00200410350b024020024101470d00419bd6ca002102410c2104410f21050c0b0b200341d0016a41186a4200370300200341d0016a41106a220b420037030041082104200341d0016a41086a22024200370300200342003703d00141d1c4c700ad4280808080e000841001220a290000211b2002200a41086a2900003703002003201b3703d001200a103541e7c4c700ad4280808080e000841001220a290000211b200341e8006a41086a220c200a41086a2900003703002003201b370368200a1035200b2003290368221b37030020034180046a41086a200229030037030020034180046a41106a201b37030020034180046a41186a200c290300370300200320032903d00137038004200341386a20034180046a412010c0010240200520086a220220054f0d0041a7d6ca002102410e21050c0b0b02402002200328023c410020032802381b4d0d0041d1d6ca002102410b2104410a21050c0b0b02402017422088a720094f0d0041bad6ca00210241092104410c21050c0b0b200341d0016a200341a8016a10950720033502d801211b20032802d0012104412010332202450d032002200329038801370000200241186a20034188016a41186a2205290300370000200241106a20034188016a41106a2208290300370000200241086a20034188016a41086a2209290300370000201b4220862004ad842002ad4280808080800484100220021035024020032802d401450d00200410350b200341a8016a108d02200341da016a2009290300370100200341e2016a2008290300370100200341ea016a2005290300370100200341f2016a20032903a801370100200341fa016a200341a8016a41086a29030037010020034182026a200341a8016a41106a2903003701002003418a026a200341a8016a41186a29030037010020034193083b01d00120032003290388013701d20141b0b4cc004100200341d0016a10d4010240201742ffffff3f83500d00200110350b200741ffffff3f71450d11200610350c110b200341a8016a41186a200141196a290000370300200341a8016a41106a200141116a290000370300200341a8016a41086a200141096a290000370300200320012900013703a8014182b4202101024020022d00000d0020022d00014101470d00200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a29010037039804200320013a009704200320043a009604200320053b019404200320063a009304200320073a009204200320083b019004200320093a008f042003200a3a008e042003200b3b018c042003200c3a008b042003200d3a008a042003200e3b0188042003200f3a008704200320103a008604200320113b018404200320123a008304200320133a008204200320143b01800420034188016a20034180046a200341a8016a109707200341d0016a2003280288012201200328029001220210d002024020032802e4012204450d002002ad4220862001ad841007200341d0016a41086a290300211720032903d001211b20032903e801211c0240200328028c01450d00200110350b200341d0016a200341a8016a20034180046a201b2017410010ef02200341da016a20034180046a41086a290300370100200341e2016a20034180046a41106a290300370100200341ea016a20034180046a41186a290300370100200341f2016a20032903a801370100200341fa016a200341a8016a41086a29030037010020034182026a200341a8016a41106a2903003701002003418a026a200341a8016a41186a29030037010020034193063b01d00120032003290380043701d20141b0b4cc004100200341d0016a10d401201c42ffffff3f83500d12200410350c120b0240200328028c01450d00200110350b4183b42021010b200041206a410a3602002000411c6a41e5d6ca00360200200041186a200136020020004200370308420121170c1d0b4102210120022d00000d0520022d00014101470d05200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703c001200320013a00bf01200320043a00be01200320053b01bc01200320063a00bb01200320073a00ba01200320083b01b801200320093a00b7012003200a3a00b6012003200b3b01b4012003200c3a00b3012003200d3a00b2012003200e3b01b0012003200f3a00af01200320103a00ae01200320113b01ac01200320123a00ab01200320133a00aa01200320143b01a80141f8a2cb00ad428080808080018410012201290000211720034180046a41086a200141086a29000037030020032017370380042001103541e8a5cb00ad428080808080028410012201280004210820012800002109200341ac046a2001410e6a2f00003b01002003200128000a3602a80420012f0008210a20011035412010332201450d01200120032903a801370000200141186a200341a8016a41186a290300370000200141106a200341a8016a41106a290300370000200141086a200341a8016a41086a29030037000020032001ad42808080808004841003220229000037034820021035200341dc016a200141206a360200200320013602d8012003200341c8006a41086a3602d4012003200341c8006a3602d001200341e8006a200341d0016a107b200110352003280270220641206a2202417f4c0d03200328026821070240024020020d0041002104410121010c010b200210332201450d02200221040b024002402004410f4d0d00200421050c010b200441017422054110200541104b1b22054100480d05024020040d00200510332201450d190c010b20042005460d0020012004200510372201450d180b2001200329038004370000200141086a20034180046a41086a2903003700000240024020054170714110460d00200521040c010b200541017422044120200441204b1b22044100480d0520052004460d0020012005200410372201450d180b2001200a3b00182001200836001420012009360010200120032802a80436001a2001411e6a200341ac046a2f01003b000002400240200441606a2006490d00200421050c010b2006415f4b0d05200441017422052002200520024b1b22054100480d0520042005460d0020012004200510372201450d180b200141206a20072006109d081a0240200328026c450d00200710350b0240024020020d0041002104410121070c010b200210332207450d02200221040b0240024020042002490d00200421060c010b200441017422062002200620024b1b22064100480d05024020040d00200610332207450d190c010b20042006460d0020072004200610372207450d180b200720012002109d0821042003419c016a200236020020034198016a2005360200200320013602940120032002360290012003200636028c012003200436028801200341d0016a2002ad4220862001ad84102710c20102400240024020032802d0012201450d0020032802d401210202400240200341d8016a28020022042003280290012205490d0020032802880122062001460d0120062001200510a008450d010b2002450d01200110350c010b20034194016a2105200320043602b004200320023602ac04200320013602a804200341d0016a2001200410d002024020032802e40122010d002003410036025020034201370348200341f4006a4135360200200320053602b4042003413536026c2003200341b8046a3602702003200341b4046a3602682003200341a8046a3602b8042003200341c8006a3602bc0420034194046a4102360200200342023702840420034180c9c400360280042003200341e8006a36029004200341bc046a41e88ac50020034180046a10431a20033502504220862003350248841006200328024c450d00200328024810350b20034180046a41086a2202200341a8046a41086a280200360200200320032903a804370380040240200328029801450d0020032802940110350b2005200329038004370200200541086a200228020036020020010d010b20034180046a200341a8016a109607200341d0016a2003280280042202200328028804220410e202024020032802e4012201450d002004ad4220862002ad8410070b200328028404210402402001450d00200341d8016a290300211720032903d001211b20032802e801210502402004450d00200210350b2003201b370368200320173703700240201b201784500d002003200341a8016a36024820034180046a200341a8016a200341e8006a200341c8006a10f0022003290380044201520d00200329038804211720034188026a20034180046a41106a29030037030020034180026a2017370300200341d0016a41086a41003a0000200341d9016a20032903a801370000200341e1016a200341a8016a41086a290300370000200341e9016a200341a8016a41106a290300370000200341f1016a200341c0016a290300370000200341033a00d00141b0b4cc004100200341d0016a10d4010b200341da016a200341b0016a290300370100200341e2016a200341b8016a290300370100200341ea016a200341c0016a290300370100200341930a3b01d001200320032903a8013701d20141b0b4cc004100200341d0016a10d4010240200541ffffff3f71450d00200110350b0240200328028c01450d0020032802880110350b200328029801450d1220032802940110350c120b02402004450d00200210350b418fd7ca002102410e21044180801421050c010b41afd6ca002102410b210441808034210520032802e80141ffffff3f71450d00200110350b0240200328028c01450d0020032802880110350b0240200328029801450d0020032802940110350b410321010c070b20034188016a41186a200141196a29000037030020034188016a41106a200141116a29000037030020034188016a41086a200141096a2900003703002003200129000137038801418234210120022d00000d0520022d00014101470d05200241196a2d00002101200241186a2d00002104200241166a2f01002105200241156a2d00002106200241146a2d00002107200241126a2f01002108200241116a2d00002109200241106a2d0000210a2002410e6a2f0100210b2002410d6a2d0000210c2002410c6a2d0000210d2002410a6a2f0100210e200241096a2d0000210f200241086a2d00002110200241066a2f01002111200241056a2d00002112200241046a2d00002113200241026a2f0100211420032002411a6a2901003703c001200320013a00bf01200320043a00be01200320053b01bc01200320063a00bb01200320073a00ba01200320083b01b801200320093a00b7012003200a3a00b6012003200b3b01b4012003200c3a00b3012003200d3a00b2012003200e3b01b0012003200f3a00af01200320103a00ae01200320113b01ac01200320123a00ab01200320133a00aa01200320143b01a801200341e8006a200341a8016a109507200341d0016a20032802682202200328027010d5010240024020032d00d0014101460d0041002101200341003a0080040c010b20034180046a41196a200341d0016a41196a29000037000020034180046a41096a200341d0016a41096a29000037000020034180046a41116a200341d0016a41116a29000037000041012101200341013a008004200320032900d101370081040b0240200328026c450d00200210350b200341e9016a200341a0016a290300370000200341e1016a20034198016a290300370000200341d9016a20034190016a29030037000020032003290388013700d101200341013a00d001024020010d0041833421010c060b418334210120034180046a410172200341d0016a410172412010a0080d05200341d0016a200341a8016a10950720033502d80142208620032802d0012201ad841007024020032802d401450d00200110350b200341a8016a1099020c0e0b1045000b200041186a410236020020004200370308420121170c190b1044000b103e000b410021050c010b200041206a410a3602002000411c6a41cdd7ca00360200200041186a200136020020004200370308420121170c150b20004200370308200041206a20043602002000411c6a2002360200200041186a20054180803c7120017241803472360200420121170c140b201742ffffff3f83500d00200110350b0240200741ffffff3f71450d00200610350b410321010b20004200370308200041206a20043602002000411c6a2002360200200041186a200541107420017241803472360200420121170c110b200820014105746a200341a8016a412010a00822040d0141c3d6ca002106410e2105410b21040b200a41ffffff3f71450d05200810350c050b200341d0016a41186a200341a8016a41186a290300370300200341d0016a41106a200341a8016a41106a290300370300200341d0016a41086a200341a8016a41086a290300370300200320032903a8013703d001200341d0016a21022004411f7620016a220420064b0d030b02402006200a470d0020034194046a20064101108a0120032802940421080b200820044105746a220141206a2001200620046b410574109e081a200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a290000370000200120022900003700002003200641016a36029c04200341d0016a41186a220220034180046a41186a290300370300200341d0016a41106a20034180046a41106a290300370300200341d0016a41086a20034180046a41086a29030037030020032003290380043703d001200341c8006a200341e8006a20034188016a10970720032802482101200320032802503602ac04200320013602a804200341d0016a200341a8046a1094070240200328024c450d00200110350b0240200228020041ffffff3f71450d0020032802e40110350b200341f2016a200329038801370100200341da016a200341e8006a41086a290300370100200341e2016a200341e8006a41106a290300370100200341ea016a200341e8006a41186a290300370100200341fa016a20034188016a41086a29030037010020034182026a20034188016a41106a2903003701002003418a026a20034188016a41186a29030037010020034193043b01d001200320032903683701d201200341aa026a200341a8016a41186a290300370100200341a2026a200341a8016a41106a2903003701002003419a026a200341a8016a41086a29030037010020034192026a20032903a80137010041b0b4cc004100200341d0016a10d401200941ffffff3f71450d00200710350b420021170b200020173703080c0b0b20042006104d000b41032101200941ffffff3f71450d01200710350c010b0b200041206a20053602002000411c6a200636020020004200370308200041186a200441ff017141107420017241803472360200420121170c070b0b200041206a20043602002000411c6a200736020020004200370308200041186a2005411874200641ff017141107472200241ff017141087472200141ff017172360200420121170c050b103c000b0b0240200741ffffff3f71450d00200910350b20004200370308200041206a20023602002000411c6a2004360200200041186a2008411874200141ff017141107472200641ff017141087472200541ff017172360200420121170c020b410421014100210241002106410021070b20041035420021170240200141ff017122014104460d00200041206a20053602002000411c6a2008360200200041186a20022006418080fc07717220074180fe037172200172360200420121170b200042003703080b20002017370300200341c0046a24000bb50404057f017e017f017e0240024020012802042202450d00200128020022032d0000210420012002417f6a22053602042001200341016a3602000240200441037122064103460d00024002400240024020060e03000102000b2004410276ad21070c020b41012106024020050d000c050b20032d0001210520012002417e6a3602042001200341026a3602002005410874200472220141ffff0371418002490d04200141fcff0371410276ad21070c010b410121060240200541034f0d000c040b200341036a2d0000210520032f0001210820012002417c6a3602042001200341046a3602002008200541107472410874200472220141808004490d032001410276ad21070b410021060c020b02402004410276220841044b0d000240024020080e050002020201000b20054104490d022003350001210720012002417b6a3602042001200341056a36020020074280808080045421060c030b20054108490d01200329000121072001200241776a3602042001200341096a3602002007428080808080808080015421060c020b200841046a220541084b0d002002417e6a2102200341026a2103410021044200210741012106034002402002417f470d000c030b2003417f6a310000210920012002360204200120033602002002417f6a2102200341016a210320092004410374413871ad862007842107200441016a220441ff01712005490d000b2007427f412820084103746b413871ad885821060c010b410121060b2000200737030820002006ad3703000bf30601067f230041f0006b2102024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a2206360204410121072001200441016a360200200541f001490d06200541847e6a220541034b0d0120050e0402030405020b200041023a00000f0b200041023a00000f0b20064102490d0420042f0001210520012003417d6a3602042001200441036a3602000240200541ef014d0d00410121070c040b200041023a00000f0b20064104490d042004280001210520012003417b6a3602042001200441056a36020041012107200541ffff034b0d02200041023a00000f0b024020064104490d00200041023a000020012003417b6a3602042001200441056a3602000f0b200041023a00000f0b41002105200241003a00682003417f6a21062003417e6a210302400240034020062005460d01200241c8006a20056a200420056a220741016a2d00003a0000200120033602042001200741026a3602002002200541016a22073a00682003417f6a21032007210520074120470d000b200241c6006a20022d004a3a0000200241306a200241d7006a290000370300200241386a200241df006a290000370300200241c0006a200241e7006a2d00003a0000200220022f01483b01442002200229004f370328200228004b2105410021010c010b0240200541ff0171450d00200241003a00680b410121010b200241246a41026a2203200241c4006a41026a2d00003a0000200241086a41086a2207200241286a41086a290300370300200241086a41106a2204200241286a41106a290300370300200241086a41186a2206200241286a41186a2d00003a0000200220022f01443b01242002200229032837030820010d03200241286a41026a20032d00003a0000200241c8006a41086a2007290300370300200241c8006a41106a2004290300370300200241c8006a41186a20062d00003a0000200220022f01243b012820022002290308370348410021070b200020073a0000200020022f01283b0001200041046a2005360200200041086a2002290348370200200041036a2002412a6a2d00003a0000200041106a200241c8006a41086a290300370200200041186a200241c8006a41106a290300370200200041206a200241c8006a41186a2802003602000f0b200041023a00000f0b200041023a00000f0b200041023a00000b9f1002097f047e230041d0056b220224000240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541044b0d0620050e050102030405010b200041063a00000c090b200241a0036a200110c301024020022802a0032206450d0020022802a4032107024020012802042203450d00200241a8036a2802002108200128020022042d0000210520012003417f6a3602042001200441016a360200200541014b0d004100210902400240024020050e020100010b41002105200241003a00c0032003417f6a210a2003417e6a21030340200a2005460d02200241a0036a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00c0032003417f6a21032009210520094120470d000b200241f0006a41186a200241a0036a41186a290300370300200241f0006a41106a200241a0036a41106a290300370300200241f0006a41086a200241a0036a41086a290300370300200220022903a003370370410121090b200241206a41186a200241f0006a41186a290300220b370300200241206a41106a200241f0006a41106a290300220c370300200241206a41086a200241f0006a41086a290300220d37030020022002290370220e370320200020093a0001200041013a0000200041026a200e3700002000410a6a200d370000200041126a200c3700002000411a6a200b3700002000412c6a2008360100200041286a2007360100200041246a20063601000c0b0b200541ff0171450d00200241003a00c0030b200041063a0000200741ffffff3f71450d09200610350c090b200041063a00000c080b200241a0036a200110b90220022802a0032101200241f0006a200241a0036a41047241ac02109d081a024002402001411b460d00200241a0036a200241f0006a41ac02109d081a41b002103322050d010c080b200041063a00000c080b20052001360200200541046a200241a0036a41ac02109d081a200041023a0000200020022f00503b0001200041036a200241d0006a41026a2d00003a0000200041046a2005360200200041086a2002290220370200200041106a200241206a41086a290200370200200041186a200241206a41106a290200370200200041206a200241206a41186a290200370200200041286a200241206a41206a2902003702000c070b200241086a200110c401024020022802080d00200228020c2103200241a0036a200110b90220022802a0032101200241f0006a200241a0036a41047241ac02109d081a2001411b460d00200241a0036a200241f0006a41ac02109d081a41b00210332205450d0620052001360200200541046a200241a0036a41ac02109d081a200041033a0000200020022f00503b0001200041036a200241d2006a2d00003a0000200041086a2005360200200041046a20033602002000410c6a2002290220370200200041146a200241206a41086a2902003702002000411c6a200241306a290200370200200041246a200241386a2902003702002000412c6a200241c0006a2802003602000c070b200041063a00000c060b41002105200241003a00c0032003417f6a210a2003417e6a210302400240024002400340200a2005460d01200241a0036a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00c0032003417f6a21032009210520094120470d000b200241206a41086a200241a0036a41086a290300370300200241206a41106a200241a0036a41106a290300370300200241206a41186a200241a0036a41186a290300370300200220022903a003370320200241106a200110c40120022802100d0120012802042203450d0120022802142104200128020022092d0000210520012003417f6a3602042001200941016a360200200541014b0d014100210120050e020302030b200541ff0171450d00200241003a00c0030b200041063a00000c070b410121010b200241d0006a41186a200241206a41186a290300220b370300200241d0006a41106a200241206a41106a290300220c370300200241d0006a41086a200241206a41086a290300220d37030020022002290320220e370350200041043a00002000200e370001200041096a200d370000200041116a200c370000200041196a200b370000200041246a2004360200200041216a20013a00000c050b41002105200241003a00c0032003417f6a210a2003417e6a210302400340200a2005460d01200241a0036a20056a200420056a220941016a2d00003a0000200120033602042001200941026a3602002002200541016a22093a00c0032003417f6a21032009210520094120470d000b200241206a41086a2205200241a0036a41086a290300370300200241206a41106a2203200241a0036a41106a290300370300200241206a41186a2209200241a0036a41186a290300370300200220022903a003370320200241186a200110c4012002280218450d020c030b200541ff0171450d02200241003a00c0030c020b200041063a00000c030b200228021c2101200241d0006a41186a2009290300220b370300200241d0006a41106a2003290300220c370300200241d0006a41086a2005290300220d37030020022002290320220e370350200041053a00002000200e370001200041096a200d370000200041116a200c370000200041196a200b370000200041216a20022f004d3b0000200041236a200241cf006a2d00003a0000200041246a20013602000c020b200041063a00000c010b103c000b200241d0056a24000bc60702047f047e230041b0056b22022400024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541024b0d0320050e03010204010b200041043602000c050b20024180036a200110b9022002280280032101200241d0006a20024180036a41047241ac02109d081a024002402001411b460d0020024180036a200241d0006a41ac02109d081a41b002103322050d010c050b200041043602000c050b20052001360200200541046a20024180036a41ac02109d081a2000200536020420004101360200200041086a2002290228370200200041106a200241286a41086a290200370200200041186a200241286a41106a290200370200200041206a200241286a41186a290200370200200041286a200241286a41206a2802003602000c040b20024180036a2001109206024020022d0080034102460d00200241d0006a41206a20024180036a41206a2802002201360200200241d0006a41186a20024180036a41186a2903002206370300200241d0006a41106a20024180036a41106a2903002207370300200241d0006a41086a20024180036a41086a29030022083703002002200229038003220937035020004102360200200020093702042000410c6a2008370200200041146a20073702002000411c6a2006370200200041246a20013602000c040b200041043602000c030b200041043602000c020b20024180036a2001109206024020022d0080034102470d00200041043602000c020b200241286a41206a20024180036a41206a280200360200200241286a41186a20024180036a41186a290300370300200241286a41106a20024180036a41106a290300370300200241286a41086a20024180036a41086a290300370300200220022903800337032820024180036a200110b9022002280280032101200241d0006a20024180036a41047241ac02109d081a02402001411b460d0020024180036a200241d0006a41ac02109d081a41b00210332205450d0120052001360200200541046a20024180036a41ac02109d081a200241206a200241286a41206a2802002201360200200241186a200241286a41186a2903002206370300200241106a200241286a41106a2903002207370300200241086a200241286a41086a290300220837030020022002290328220937030020004103360200200020093702042000410c6a2008370200200041146a20073702002000411c6a2006370200200041246a2001360200200041286a20053602000c020b200041043602000c010b103c000b200241b0056a24000bbc1e03077f047e017f230041e0056b2202240002400240024002400240024002400240024002400240024020012802042203450d00200128020022042d0000210520012003417f6a3602042001200441016a360200200541084b0d0a20050e09010203040506070809010b2000410a3a00000c0a0b41002105200241003a00d0032003417f6a21062003417e6a2107024002400240034020062005460d01200241b0036a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00d0032007417f6a21072008210520084120470d000b200241c0006a41086a200241b0036a41086a290300370300200241c0006a41106a200241b0036a41106a290300370300200241c0006a41186a200241b0036a41186a290300370300200220022903b003370340200241b0036a200110b90220022802b003210120024180016a200241b0036a41047241ac02109d081a2001411b460d01200241b0036a20024180016a41ac02109d081a41b002103322040d02103c000b200541ff0171450d00200241003a00d0030b2000410a3a00000c0a0b20042001360200200441046a200241b0036a41ac02109d081a200241206a41186a200241c0006a41186a2903002209370300200241206a41106a200241c0006a41106a290300220a370300200241206a41086a200241c0006a41086a290300220b37030020022002290340220c370320200041013a00002000200c370001200041096a200b370000200041116a200a370000200041196a2009370000200041216a20022f001d3b0000200041236a2002411f6a2d00003a0000200041246a2004360200200041286a2002290200370200200041306a200241086a290200370200200041386a200241106a290200370200200041c0006a200241186a2802003602000c090b41002105200241003a00d003410120036b21062003417e6a21070240024002400340200620056a450d01200241b0036a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00d0032007417f6a21072008210520084120470d000b20024180016a41086a200241b0036a41086a29030037030020024180016a41106a200241b0036a41106a29030037030020024180016a41186a200241b0036a41186a290300370300200220022903b0033703800141002105200241003a00d003200420086a2106200820036b41016a21080340200820056a450d02200241b0036a20056a200620056a220441016a2d00003a0000200120073602042001200441026a3602002002200541016a22043a00d0032007417f6a21072004210520044120470d000b200241206a41086a2201200241b0036a41086a290300370300200241206a41106a2204200241b0036a41106a290300370300200241206a41186a2205200241b0036a41186a290300370300200241c0006a41086a220720024180016a41086a290300370300200241c0006a41106a220820024180016a41106a290300370300200241c0006a41186a220320024180016a41186a290300370300200220022903b0033703202002200229038001370340200041023a000020002002290340370001200041096a2007290300370000200041116a2008290300370000200041196a2003290300370000200041216a2002290320370000200041296a2001290300370000200041316a2004290300370000200041396a2005290300370000200041c1006a20022f00003b0000200041c3006a200241026a2d00003a00000c0b0b200541ff0171450d01200241003a00d0030c010b200541ff0171450d00200241003a00d0030b2000410a3a00000c080b20024180016a200110c3010240024002402002280280012204450d002002280284012105200128020422074102490d0120024188016a2802002106200128020022082f0000210d20012007417e6a22033602042001200841026a36020020034104490d022008280002210320012007417a6a3602042001200841066a360200200041106a20033602002000410c6a2006360200200041086a2005360200200041046a2004360200200041026a200d3b0100200041033a0000200041146a20022902b0033702002000411c6a200241b0036a41086a290200370200200041246a200241b0036a41106a2902003702002000412c6a200241c8036a290200370200200041346a200241d0036a2902003702002000413c6a200241d8036a2902003702000c0a0b2000410a3a00000c090b2000410a3a0000200541ffffff3f71450d08200410350c080b2000410a3a0000200541ffffff3f71450d07200410350c070b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041043a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c070b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c060b41002105200241003a00d003410120036b21062003417e6a21070240024002400340200620056a450d01200241b0036a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00d0032007417f6a21072008210520084120470d000b20024180016a41086a200241b0036a41086a29030037030020024180016a41106a200241b0036a41106a29030037030020024180016a41186a200241b0036a41186a290300370300200220022903b0033703800141002105200241003a00d003200420086a2106200820036b41016a21080340200820056a450d02200241b0036a20056a200620056a220441016a2d00003a0000200120073602042001200441026a3602002002200541016a22043a00d0032007417f6a21072004210520044120470d000b200241206a41086a2201200241b0036a41086a290300370300200241206a41106a2204200241b0036a41106a290300370300200241206a41186a2205200241b0036a41186a290300370300200241c0006a41086a220720024180016a41086a290300370300200241c0006a41106a220820024180016a41106a290300370300200241c0006a41186a220320024180016a41186a290300370300200220022903b0033703202002200229038001370340200041053a000020002002290340370001200041096a2007290300370000200041116a2008290300370000200041196a2003290300370000200041216a2002290320370000200041296a2001290300370000200041316a2004290300370000200041396a2005290300370000200041c1006a20022f00003b0000200041c3006a200241026a2d00003a00000c080b200541ff0171450d01200241003a00d0030c010b200541ff0171450d00200241003a00d0030b2000410a3a00000c050b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041063a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c050b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c040b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041073a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c040b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c030b200041083a00000c020b41002105200241003a00a0012003417f6a21062003417e6a21070240034020062005460d0120024180016a20056a200420056a220841016a2d00003a0000200120073602042001200841026a3602002002200541016a22083a00a0012007417f6a21072008210520084120470d000b200241c0006a41086a20024180016a41086a2903002209370300200241c0006a41106a20024180016a41106a290300220a370300200241c0006a41186a20024180016a41186a290300220b3703002002200229038001220c370340200041093a00002000200c370001200041096a2009370000200041116a200a370000200041196a200b370000200041216a20022900b003370000200041296a200241b0036a41086a290000370000200041316a200241b0036a41106a290000370000200041396a200241b0036a41186a290000370000200041c0006a200241cf036a2800003600000c020b0240200541ff0171450d00200241003a00a0010b2000410a3a00000c010b2000410a3a00000b200241e0056a24000bab0301087f230041206b220324000240024002400240200141246c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b2003410036020820032005360200200320043602042001200310770240024020010d002003280208210420032802042106200328020021070c010b200141246c210820032802042105200328020821010340200341106a200010c0032003280210210902400240200520016b2003280218220a490d002001200a6a210420032802002107200521060c010b2001200a6a22042001490d05200541017422062004200620044b1b22064100480d050240024020050d00024020060d00410121070c020b2006103322070d010c080b2003280200210720052006460d0020072005200610372207450d070b20032006360204200320073602000b200720016a2009200a109d081a2003200436020802402003280214450d00200910350b200041246a210020062105200421012008415c6a22080d000b0b20022902002004ad4220862007ad84100202402006450d00200710350b200341206a24000f0b1044000b1045000b103e000b103c000bd20301037f0240024020002d0000220141144b0d00024002400240024002400240024020010e15080808080808000808010802080308040508060808080b200041086a2d00004101470d07200041146a28020041ffffff3f71450d07200041106a28020010350f0b200041046a2d00000d062000410c6a2802002201450d06200141306c450d06200041086a28020010350f0b200041046a2802000d052000410c6a2802002201450d05200141286c450d05200041086a28020010350f0b200041086a2d00004107470d04200041306a280200450d042000412c6a28020010350f0b200041046a2d00004102490d030240200041106a2802002201450d00200141d0006c2102200041086a28020041c4006a21010340024020012802002203450d00200341306c450d002001417c6a28020010350b200141d0006a2101200241b07f6a22020d000b0b2000410c6a2802002201450d03200141d0006c450d03200028020810350f0b200041086a280200450d02200041046a28020010350f0b200041086a2d00004106470d01200041306a28020041ffffff3f71450d012000412c6a28020010350c010b200041046a280200450d00200041106a2802002201450d00200041146a280200450d00200110350f0b0b13002000410a360204200041e0cfc7003602000b3400200041d1c4c70036020420004100360200200041146a410f360200200041106a4184e3c700360200200041086a42063702000b2b01017f02404101103322020d001045000b200042818080801037020420002002360200200241003a00000be00101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002400240412010332206450d0020062002290300370000200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000412010332203450d0120032006290000370000200341186a200641186a290000370000200341106a200641106a290000370000200341086a200641086a29000037000020061035200042a0808080800437020420002003360200200241206a24000f0b1045000b103c000bae0101017f0240410410332202450d002002410036000020024104410810372202450d00200241003a000420024108411510372202450d00200242003700052002410d6a420037000020024115412a10372202450d00200242003700152002411d6a42003700002002412a41d40010372202450d002002420037003520024200370025200042d4808080d008370204200020023602002002413d6a42003700002002412d6a42003700000f0b103c000b13002000410536020420004184fdc7003602000b2f01017f02404104103322020d001045000b20004284808080c000370204200020023602002002418080c0023600000b2f01017f02404108103322020d001045000b20004288808080800137020420002002360200200242c0b2cd3b3700000b3001017f02404108103322020d001045000b2000428880808080013702042000200236020020024280e497d0123700000b4801017f0240410810332202450d00200242c0f0f50b37000020024108411010372202450d002000429080808080023702042000200236020020024280c2d72f3700080f0b103c000b3101017f02404108103322020d001045000b2000428880808080013702042000200236020020024280c0a8ca9a3a3700000b861603027f017e0a7f230041b0016b2203240041f1d8cb00ad4280808080900184100122042900002105200341c8006a41086a200441086a290000370300200320053703482004103541a0e0c600ad4280808080b00184100122042900002105200341e8006a41086a200441086a29000037030020032005370368200410350240024002400240024002400240412010332204450d0020042001290000370000200441186a2206200141186a290000370000200441106a2207200141106a290000370000200441086a200141086a290000370000412010332208450d0020082004290000370000200841186a2006290000370000200841106a2007290000370000200841086a2206200441086a2900003700002004103541c00010332204450d002004200329036837001020042003290348370000200441086a200341c8006a41086a290300370000200441186a200341e8006a41086a29030037000020042008290000370020200441286a2006290000370000200441306a200841106a290000370000200441386a200841186a29000037000020081035200341c000360294012003200436029001200341206a2004ad4280808080800884100510c20102400240200328022022070d00410221080c010b200328022421092003200341286a28020036029c012003200736029801200341186a20034198016a10c40102400240024020032802180d00200328021c2106200341106a20034198016a10c40120032802100d002003280214210a200341086a20034198016a10c40120032802080d00200328029c012208450d00200328020c210b20032008417f6a36029c012003200328029801220841016a3602980120082d0000220c41014b0d004100210802400240200c0e020100010b410121080b200320034198016a10c40120032802000d00200328029c01220d2003280204220e490d00200e417f4c0d0502400240200e0d004100210d4101210c0c010b200e1039220c450d05200c200328029801220f200e109d081a2003200d200e6b36029c012003200f200e6a36029801200e210d0b200c0d010b2003410036025020034201370348200341093602a401200320034190016a3602a0012003200341c8006a3602ac01200341fc006a41013602002003420137026c200341c888c2003602682003200341a0016a360278200341ac016a41e88ac500200341e8006a10431a200335025042208620033502488410060240200328024c450d00200328024810350b410221080c010b200ead422086200dad8421052003418c016a41026a200341e8006a41026a2d00003a0000200320032f00683b018c010b2009450d00200710350b200341e8006a41026a2003418c016a41026a2d00003a0000200320032f018c013b01680240024020084102460d00200341c4006a41026a2207200341e8006a41026a2d00003a0000200320032f01683b014420041035200341c0006a41026a20072d000022043a0000200341306a220920053703002003413b6a20043a0000200320032f014422043b0140200320083a00382003200c36022c2003200b3602282003200a360224200320043b003920032006360220200341206a41086a2107200228027020064b0d010c070b20041035200041086a4111360200200041ef84c800360204200041013602000c070b41f1d8cb00ad4280808080900184100122042900002105200341c8006a41086a200441086a29000037030020032005370348200410354194e0c600ad4280808080c00184100122042900002105200341e8006a41086a200441086a2900003703002003200537036820041035412010332204450d0020042001290000370000200441186a2206200141186a290000370000200441106a220a200141106a290000370000200441086a220b200141086a290000370000412010332208450d0020082004290000370000200841186a2006290000370000200841106a200a290000370000200841086a200b2900003700002004103541c00010332204450d002004200329036837001020042003290348370000200441086a200341c8006a41086a290300370000200441186a200341e8006a41086a29030037000020042008290000370020200441286a200841086a290000370000200441306a200841106a290000370000200441386a200841186a29000037000020081035200341e8006a200441c00010e002200329026c2105200328026821062004103502400240024002402006450d00200341e8006a20062005422088a72002108c062005a7210220032802684101460d03200341c8006a41186a220a200341e8006a410472220441186a280200360200200341c8006a41106a220b200441106a290200370300200341c8006a41086a2208200441086a2902003703002003200429020037034802402003280230450d00200328022c10350b200341206a41186a200a280200360200200341206a41106a200b290300370300200341206a41086a20082903003703002003200329034837032041f1d8cb00ad42808080809001841001220429000021052008200441086a290000370300200320053703482004103541a0e0c600ad4280808080b00184100122042900002105200341e8006a41086a200441086a2900003703002003200537036820041035412010332204450d0420042001290000370000200441186a220a200141186a290000370000200441106a220b200141106a290000370000200441086a220c200141086a290000370000412010332208450d0420082004290000370000200841186a200a290000370000200841106a200b290000370000200841086a200c2900003700002004103541c00010332204450d042004200329036837001020042003290348370000200441086a200341c8006a41086a290300370000200441186a200341e8006a41086a29030037000020042008290000370020200441286a200841086a290000370000200441306a200841106a290000370000200441386a200841186a290000370000200810352003410036027020034201370368200341206a200341e8006a10e201200341206a410472200341e8006a10e2012007200341e8006a10e20120032d0038210a200328026c20032802702208460d01200328026821010c020b2000418085c80036020420004101360200200041086a411a3602000c070b200841016a22012008490d042008410174220b2001200b20014b1b220b4100480d040240024020080d00410021080240200b0d00410121010c020b200b103322010d010c070b200328026821012008200b460d0020012008200b10372201450d060b2003200b36026c200320013602680b200120086a200a3a00002003200841016a360270200328022c210e200341346a2802002208200341e8006a107702400240200328026c220c2003280270220a6b2008490d0020032802682101200c210b0c010b200a20086a2201200a490d04200c410174220b2001200b20014b1b220b4100480d0402400240200c0d000240200b0d00410121010c020b200b10332201450d070c010b20032802682101200c200b460d002001200c200b10372201450d060b2003200b36026c200320013602680b2001200a6a200e2008109d081a2004ad4280808080800884200a20086aad4220862001ad8410020240200b450d00200110350b200410352002450d06200610350c060b2000200329026c370204200041013602002002450d04200610350c040b1045000b1044000b103e000b103c000b2003280230450d01200328022c10350c010b20002003290320370204200041003602002000411c6a200341386a280200360200200041146a20092903003702002000410c6a20072903003702000b200341b0016a24000bc00202027f017e230041106b220224002002200028023036020020012002410410780240412010332203450d0020032000290038370000200341186a200041d0006a290000370000200341106a200041c8006a290000370000200341086a200041c0006a290000370000200120034120107820031035024020002d0058220341024b0d00024002400240024020030e03000102000b200241003a00000c020b200241013a00000c010b200241023a00000b20012002410110780b200220002802343602002001200241041078200029030021042002200041086a290300370308200220043703002001200241101078200029031021042002200041186a290300370308200220043703002001200241101078200029032021042002200041286a290300370308200220043703002001200241101078200241106a24000f0b1045000b1300200041073602042000419c85c8003602000b3400200041fb8fc80036020420004100360200200041146a4102360200200041106a419090c800360200200041086a42133702000bcb0202057f037e2001280200210202400240412010332203450d0020032002290000370000200341186a2204200241186a290000370000200341106a2205200241106a290000370000200341086a2206200241086a290000370000412010332202450d0120022003290000370000200241186a2004290000370000200241106a2005290000370000200241086a200629000037000020031035200128020421012002412041c00010372203450d0120032001290000370020200341386a200141186a290000370000200341306a200141106a290000370000200341286a200141086a2900003700002003ad4280808080800884100922022900002107200241086a2900002108200241106a2900002109200041186a200241186a290000370000200041106a2009370000200041086a20083700002000200737000020021035200310350f0b1045000b103c000ba30301067f230041106b22032400024020014105744104722204417f4c0d000240200410332205450d002003410036020820032004360204200320053602002001200310770240024020010d002003280208210520032802042106200328020021070c010b20014105742108200328020021072003280204210620032802082105034020002101024002402006200522046b4120490d00200441206a21050c010b024002400240200441206a22052004490d00200641017422002005200020054b1b22004100480d000240024020060d00024020000d00410121070c020b2000103321070c040b20062000470d020b200021060c030b103e000b200720062000103721070b2000210620070d00103c000b200141206a2100200720046a22042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a290000370000200841606a22080d000b2003200636020420032005360208200320073602000b20022902002005ad4220862007ad84100202402006450d00200710350b200341106a24000f0b1045000b1044000b130020004105360204200041fc92c8003602000be80f06087f017e047f017e057f077e230022042105200441a0016b41607122042400024002400240200141ffffff3f712001470d0020014105742206417f4c0d000240024020060d00410121070c010b200610332207450d020b41002108200441003602282004200736022020042006410576360224200441206a41002001108a012004280228210902402001450d002001410574210a200428022020094105746a210b0340200b20086a2206200020086a2207290000370000200641186a200741186a290000370000200641106a200741106a290000370000200641086a200741086a290000370000200a200841206a2208470d000b200141057441606a41057620096a41016a21090b200441086a200936020020042004290320220c370300200ca72009410041202009676b10c105200441206a41186a22014200370300200441206a41106a220d4200370300200441206a41086a220e42003703002004420037032041c7d5ca00ad4280808080b0028410012208290000210c200e200841086a2900003703002004200c370320200810354180eaca00ad428080808090018410012208290000210c200441e8006a41086a220f200841086a2900003703002004200c37036820081035200d2004290368220c37030020044180016a41086a200e29030037030020044180016a41106a200c37030020044180016a41186a200f2903003703002004200429032037038001200441206a20044180016a412010b50220042802202208410120081b21102004290224420020081b2211422088a72208450d022008410574210920044180016a410c722112200441206a410c6a2100200441206a4114722113200441206a41087221142010210803402001200841186a290000370300200d200841106a290000370300200e200841086a29000037030020042008290000370320200441106a200441206a108a07200441206a2004280210220b2004280218221510de02200f200041086a290200370300200441e8006a41106a220a200041106a2802003602002004200029020037036820042802402106024020042802282207450d002004290320210c20122004290368370200201241086a200f290300370200201241106a200a2802003602002004200c37038001200621160b200420073602880120044100360228200429039801211720042004290338221837039801200429039001211920042004290330221a37039001200429038001211b20042004290320221c37038001200429038801210c20042004290328221d37038801201da7210702400240200ca7220a0d00201d210c201a211920182117201621060c010b2004201b3703202004200c37032820042019370330200420173703382004200a2019a74105746a3602742004200a3602702004200c422088a736026c2004200a36026820042004360278200441d8006a200441e8006a10ca05201441086a200441d8006a41086a22162802003602002014200429035837020020042019422088a7220a2017422088a74105746a3602742004200a36027020042017a736026c2004200a36026820042004360278200441d8006a200441e8006a10ca05201341086a2016280200360200201320042903583702002004290328210c2004290320211c200429033821172004290330211902402007450d002018a7210a0240201d422088a741ffffff3f71450d00200710350b200a41ffffff3f71450d00201a422088a710350b2004201c370380012004200c3703880120042019370390012004201737039801200ca721070b2004200c37032820042019370330200120173703002004201c37032020042006360240200ca7210a0240024020070d002015ad422086200bad8410070c010b2004201536026c2004200b360268200441206a200441e8006a108b070b0240200a450d002017a721070240200c422088a741ffffff3f71450d00200a10350b200741ffffff3f71450d002019422088a710350b02402004280214450d00200b10350b200841206a210820062116200941606a22090d000c030b0b1044000b1045000b0240201142ffffff3f83500d00201010350b200441206a41186a220a4200370300200441206a41106a22074200370300200441206a41086a220642003703002004420037032041c7d5ca00ad4280808080b00284220c10012200290000211c200441e8006a41086a2208200041086a2900003703002004201c3703682000103520062008290300370300200420042903683703204189eaca00ad4280808080f0008410012200290000211c2008200041086a2900003703002004201c3703682000103520072004290368221c37030020044180016a41086a220b200629030037030020044180016a41106a2201201c37030020044180016a41186a22092008290300370300200420042903203703800120044120360224200420044180016a36022020022003200441206a10a806200a4200370300200742003703002006420037030020044200370320200c10012200290000210c2008200041086a2900003703002004200c370368200010352006200829030037030020042004290368370320419cdfca00ad4280808080d0008410012200290000210c2008200041086a2900003703002004200c3703682000103520072004290368220c370300200b20062903003703002001200c37030020092008290300370300200420042903203703800120044180016aad428080808080048410070240200428020441ffffff3f71450d00200428020010350b200524000bec0502057f017e23004190016b2201240020002d00002102200141186a2203200041196a290000370300200141106a2204200041116a290000370300200141086a2205200041096a2900003703002001200029000137030002400240024020020d00200141f0006a41186a4200370300200141f0006a41106a22034200370300200141f0006a41086a220042003703002001420037037041c7d5ca00ad4280808080b002841001220229000021062000200241086a2900003703002001200637037020021035419cdfca00ad4280808080d00084100122022900002106200141206a41086a2204200241086a2900003703002001200637032020021035200320012903202206370300200141c0006a41086a2000290300370300200141c0006a41106a2006370300200141c0006a41186a200429030037030020012001290370370340200141c0006aad428080808080048410070c010b200141206a41186a2003290300370300200141206a41106a2004290300370300200141206a41086a200529030037030020012001290300370320200141f0006a41186a4200370300200141f0006a41106a22034200370300200141f0006a41086a220042003703002001420037037041c7d5ca00ad4280808080b002841001220229000021062000200241086a2900003703002001200637037020021035419cdfca00ad4280808080d00084100122022900002106200141e0006a41086a2204200241086a2900003703002001200637036020021035200320012903602206370300200141c0006a41086a2000290300370300200141c0006a41106a2006370300200141c0006a41186a200429030037030020012001290370370340412010332200450d0120002001290320370000200041186a200141206a41186a290300370000200041106a200141206a41106a290300370000200041086a200141206a41086a290300370000200141c0006aad42808080808004842000ad42808080808004841002200010350b20014190016a24000f0b1045000bf61407157f017e017f017e017f017e017f230041306b220224000240024020014115490d00024002402001410176220341ffffff3f712003470d0020034105742204417f4c0d000240200410332205450d002002410036020820024204370300200041606a2106200041a07f6a210741042108410021094100210a2001210b0340200b210c4100210b4101210d0240200c417f6a220e450d000240024002400240024002402000200e4105746a200c410574220f20006a41406a412010a0084100480d004102200c6b210e2007200f6a21034101210d03400240200e200d6a4101470d004100210b200c210d0c080b200d41016a210d200341206a2003412010a0082110200341606a21032010417f4a0d000b200c200d6b210e0c010b2007200f6a2103024003400240200e4101470d004100210e0c020b200e417f6a210e200341206a2003412010a0082110200341606a210320104100480d000b0b200c200e490d01200c20014b0d02200c200e6b220d4101762211450d002006200f6a21032000200e4105746a21100340200241106a41186a220f201041186a2212290000370300200241106a41106a2213201041106a2214290000370300200241106a41086a2215201041086a221629000037030020022010290000370310200341086a220b2900002117200341106a22182900002119200341186a221a290000211b201020032900003700002012201b3700002014201937000020162017370000201a200f29030037000020182013290300370000200b201529030037000020032002290310370000200341606a2103201041206a21102011417f6a22110d000b0b0240200e0d00200e210b0c050b0240200d41094d0d00200e210b0c050b200c20014b0d02200c200e6b21112000200e4105746a210f0340200c200e417f6a220b490d040240200c200b6b220d4102490d002000200e4105746a22032000200b4105746a220e412010a008417f4a0d00200e2900002117200e2003290000370000200241106a41186a2215200e41186a2210290000370300200241106a41106a2216200e41106a2212290000370300200241106a41086a2218200e41086a22132900003703002013200341086a2900003700002012200341106a2900003700002010200341186a29000037000020022017370310410121140240200d4103490d00200e41c0006a200241106a412010a008417f4a0d0041022110200f210302400340200341186a200341386a290000370000200341106a200341306a290000370000200341086a200341286a2900003700002003200341206a221229000037000020112010460d01200341c0006a21132010211420122103201041016a21102013200241106a412010a008417f4a0d020c000b0b201021140b200e20144105746a22032002290310370000200341186a2015290300370000200341106a2016290300370000200341086a20182903003700000b200b450d05200f41606a210f201141016a2111200b210e200d410a4f0d050c000b0b200e200c41eccfca001059000b200c200141eccfca001058000b200c200e417f6a220b490d00200c200141fccfca001058000b200b200c41fccfca001059000b0240200a2002280204470d002002200a41011090012002280200210820022802082209210a0b2008200a4103746a2203200d3602042003200b3602002002200941016a22093602082009210a024020094102490d00034002400240024002400240200820092214417f6a22094103746a2203280200450d00201441037420086a221141746a280200220d200328020422104b0d010b20144103490d022003280204211020082014417d6a22034103746a280204210e0c010b4102210a0240201441024b0d0020142109200b450d090c060b20082014417d6a22034103746a280204220e2010200d6a4d0d004103210a0240201441034b0d0020142109200b450d090c060b201141646a280200200e200d6a4d0d00201421092014210a0c040b200e2010490d010b2014417e6a21030b02400240024002400240024002402014200341016a22184d0d00201420034d0d0120082003410374221a6a2203280204220a20032802006a220320082018410374221c6a22102802002216490d02200320014b0d03200020164105746a22132010280204221541057422106a210d2003410574210e200320166b220c20156b220320154f0d042005200d20034105742210109d08221220106a211120154101480d0520034101480d052006200e6a210e200d21030340200e200341606a220d201141606a220c200c200d412010a008410048220f1b2210290000370000200e41186a201041186a290000370000200e41106a201041106a290000370000200e41086a201041086a2900003700002011200c200f1b211102402013200d2003200f1b2203490d00201221100c080b200e41606a210e2012211020122011490d000c070b0b20182014418cd0ca001042000b20032014419cd0ca001042000b2016200341acd0ca001059000b2003200141acd0ca001058000b200520132010109d08221220106a2111024020154101480d00200c20154c0d002000200e6a210f201221102013210303402003200d2010200d2010412010a008410048220c1b220e290000370000200341186a200e41186a290000370000200341106a200e41106a290000370000200341086a200e41086a2900003700002010201041206a200c1b2110200341206a2103200d41206a200d200c1b220d200f4f0d03201120104b0d000c030b0b20132103201221100c010b200d2103201221100b20032010201120106b416071109d081a2008201a6a2203200a20156a360204200320163602002008201c6a2203200341086a20142018417f736a410374109e081a20022009360208200941014b0d000b2009210a200b450d040c010b200b450d030c000b0b1045000b1044000b0240200228020441ffffffff0171450d00200810350b2004450d01200510350c010b20014102490d002001417f6a2110200141057420006a41206a210f410121110340024002400240024020102203417f6a221020014b0d00200120106b220e4102490d03200020034105746a2203200020104105746a220c412010a008417f4a0d03200c2900002117200c2003290000370000200241106a41186a2213200c41186a220d290000370300200241106a41106a2214200c41106a2212290000370300200241106a41086a2208200c41086a22152900003703002015200341086a2900003700002012200341106a290000370000200d200341186a2900003700002002201737031041012103200e4103490d02200c41c0006a200241106a412010a008417f4a0d0241002112200f21030340200341406a220e200341606a220d290000370000200e41186a200d41186a290000370000200e41106a200d41106a290000370000200e41086a200d41086a29000037000020112012220e460d02200e417f6a21122003200241106a412010a008210d200341206a2103200d417f4a0d020c000b0b2010200141dccfca001059000b4102200e6b21030b200c20034105746a22032002290310370000200341186a2013290300370000200341106a2014290300370000200341086a20082903003700000b200f41606a210f2011417f6a211120100d000b0b200241306a24000bfc0701137f230041c0006b22042400200441003602082004420137030020044100360218200442013703102002410020031b21052000410020011b2106200241206a200220031b2107200041206a200020011b2108200020014105746a2109200220034105746a210a4101210b4101210c4100210d4101210e4101210f410021100340200b2111200e2112201021132007210320052102024002400340024020020d00410021052006450d020c030b02402006450d000240024020022006460d0020022006412010a00822140d010b2003200341206a2003200a4622021b210741002008200820094622141b21064100200320021b21052011210b2012210e201321102008200841206a20141b21080c050b02402014417f4c0d00200221050c040b200441206a41186a2214200241186a290000370300200441206a41106a2215200241106a290000370300200441206a41086a2216200241086a29000037030020042002290000370320024020132004280214470d00200441106a20134101108a01200428021821132004280210221121122011210f0b200f20134105746a22022004290320370000200241186a2014290300370000200241106a2015290300370000200241086a20162903003700002004201341016a2213360218410020032003200a4622141b21022003200341206a20141b21030c010b0b200441206a41186a2203200541186a290000370300200441206a41106a2213200541106a290000370300200441206a41086a2206200541086a29000037030020042005290000370320024020102004280214470d00200441106a20104101108a01200428021821102004280210220b210e0b200e20104105746a22022004290320370000200241186a2003290300370000200241106a2013290300370000200241086a20062903003700002004201041016a221036021841002106410020072007200a4622021b2105200e210f2007200741206a20021b21070c020b2004280204210220042802142103201120132000200110aa060240200341ffffff3f71450d00201110350b0240200241ffffff3f71450d00200c10350b200441c0006a24000f0b200441206a41186a2214200641186a290000370300200441206a41106a2215200641106a290000370300200441206a41086a2216200641086a290000370300200420062900003703200240200d2004280204470d002004200d4101108a012004280200210c2004280208210d0b200c200d4105746a22022004290320370000200241186a2014290300370000200241106a2015290300370000200241086a20162903003700002004200d41016a220d36020841002008200820094622021b21062011210b2012210e201321102008200841206a20021b2108200321070c000b0bee1604017f067e0e7f027e230041d0026b22032400200241c0006a2903002104200241306a2903002105200241286a2903002106200241106a2903002107200241086a29030021082002290338210920022d0000210a200341086a41186a200241e0006a290000370300200341086a41106a200241d8006a290000370300200341086a41086a200241d0006a29000037030020032002290048370308200341286a41086a200241206a290300370300200320022800013602382003200241046a28000036003b2003200241186a29030037032820012802002802002202280208220b410574210c2002280200210d024002400240200b0d0041032102200d210e0c010b200c210f200d210202400340200341a8016a200341086a2002220b10b20620032802a801220e20032802b00110e40241ff01712102024020032802ac01450d00200e10350b024020024103470d00200b41206a2102200f41606a220f450d020c010b0b200b41206a210e0c020b200b41206a210e410321020b0b4101211002400240024002400240024002400240200241ff0171417e6a220f41014b0d000240200f0e020200020b4100210f410421114100210b410021100c020b410021100b410810332211450d03200d200c6a210c2011200b360204201120023a000020034281808080103702840120032011360280014101210b034002400240200c200e2202470d002002210e4103210f0c010b200341a8016a200341086a200210b20620032802a801220e20032802b00110e40241ff0171210f024020032802ac01450d00200e10350b200241206a210e200f4103460d010b024002400240200f41ff0171220d4102470d00201041016a21100c010b200d4103460d010b0240200b200328028401470d0020034180016a200b410110900120032802800121110b2011200b4103746a220d2002360204200d200f3a00002003200b41016a220b360288010c010b0b200328028401210f200b450d002001280204200b417f6a10af062202200b4f0d04201120024103746a2d000022024103470d010b410121024100210d0c010b410241012002410246220d1b21020b200320023a003f2001280208210e200341c0026a200128020c360200200341bc026a200341c8026a36020020032011200b4103746a22023602b402200320113602b0022003200f3602ac02200320113602a80220032003413f6a3602b8022003200341b8026a220b3602a8010240034020112002460d012003201141086a3602b0022011280200220241ff01714103460d010240200b2002201128020410ce0622020d0020032802b402210220032802b00221110c010b0b20034180016a41086a2211200241086a29000037030020034180016a41106a220c200241106a29000037030020034180016a41186a2212200241186a2900003703002003200229000037038001200e41046a21130340200341a8016a41186a22142012290300370300200341a8016a41106a2215200c290300370300200341a8016a41086a2216201129030037030020032003290380013703a8010240200e41086a2217280200220f2013280200470d00200e200f4101108a010b200e280200200f4105746a220220032903a801370000200241186a2014290300370000200241106a2015290300370000200241086a20162903003700002017200f41016a3602002003200b3602a801034020032802b002220220032802b402460d022003200241086a3602b0022002280200220f41ff01714103460d02200b200f200228020410ce062202450d000b2011200241086a290000370300200c200241106a2900003703002012200241186a29000037030020032002290000370380010c000b0b024020032802ac0241ffffffff0171450d0020032802a80210350b02400240200d0d0020034180016a41086a200341286a41086a290300370300200320032802383602402003200328003b3600432003200329032837038001200341a8026a200341086a10cf0620033502b002211820032802a8022111411010332202450d0220022009370000200220043700082002411041201037210202400240200a41ff01714101460d002002450d06200241003a0010200320073703b001200320083703a801200341a8016a210e4111210b4120210f0c010b2002450d05200241013a001041c000210f2002412041c00010372202450d0520022008370018200220032802403600112002200329038001370028200241206a2007370000200241146a2003280043360000200241306a20034188016a2d00003a0000200320053703b001200320063703a801200341a8016a210e4131210b0b0240200f200b6b410f470d00200f200f410174220d200b41106a220c200d200c4b1b220d460d002002200f200d10372202450d050b2002200b6a220f200e290000370000200f41086a200e41086a29000037000020184220862011ad84200b41106aad4220862002ad84100220021035024020032802ac02450d00201110350b200341a8016a41086a41083a0000200341b1016a2003290308370000200341b9016a200341086a41086a290300370000200341c1016a200341086a41106a290300370000200341c9016a200341206a290300370000200341123a00a80141b0b4cc004100200341a8016a10d401200042003703000c010b20012802102202200228020020106a360200200128021422022002290300221820097c2219370300200241086a2202200229030020047c2019201854ad7c37030020012802002802002102200341a8016a41186a220f200341086a41186a290300370300200341a8016a41106a220e200341086a41106a290300370300200341a8016a41086a2211200341086a41086a290300370300200320032903083703a80102402002280208220b200241046a280200470d002002200b4101108a012002280208210b0b2002280200200b4105746a220b20032903a801370000200b41186a200f290300370000200b41106a200e290300370000200b41086a20112903003700002002200228020841016a360208200320032802383602502003200328003b360053200341c0006a41086a200341286a41086a290300370300200320032903283703402001280218280200210202400240200a41ff01714101470d00200341b7016a2007370000200341c7016a200341c8006a2d00003a0000200320083700af01200320032800533600ab01200320032802503602a801200320032903403700bf0120034180016a200341a8016a10d0060240200328028001220b200328028801220e10d10241ff0171220f4102460d00200ead422086200bad8410070b0240200328028401450d00200b10350b2009210720042108200f0d01200341a8016a2002200920062009200654220b200420055420042005511b220f1b20042005200f1b10b0064200200420057d200bad7d2207200920067d2205200956200720045620072004511b220b1b210842002005200b1b21070c010b200320083703a802200320073703b00202402008200784500d002003200341086a36027c20034180016a200341086a200341a8026a200341fc006a10f0022003290380014201520d002003290388012107200341e0016a20034180016a41106a290300370300200341d8016a2007370300200341a8016a41086a41003a0000200341b1016a2003290308370000200341b9016a200341086a41086a290300370000200341c1016a200341086a41106a290300370000200341c9016a200341206a290300370000200341033a00a80141b0b4cc004100200341a8016a10d4010b20092107200421080b200341086a20022007200810b006200041386a2004370300200041306a20093703002000410c6a2003290308370200200041146a200341106a2903003702002000411c6a200341186a290300370200200041246a200341206a29030037020020004201370300200020012802102802003602080b200341d0026a24000f0b1045000b2002200b419cb9c8001042000b103c000b992209027f017e027f017e2f7f017e1e7f077e017f0240200028028002220241c000490d00200041a0026a22032903002204a7210520004198026a22062903002207a721082004422088a721092007422088a7210a41e5f0c18b06210b41eec8819903210c41b2da88cb07210d41f4ca81d906210e410a21022006280200220f21102000419c026a28020022112112200328020022132114200041a4026a28020022152116200f211720112118201321192015211a200f211b2011211c2013211d2015211e20004194026a280200221f210320004190026a280200222021062000418c026a2802002221212220002802880222232124201f2125202021262021212720232128201f21292020212a2021212b2023212c201f212d2020212e2021212f20232130200041b0026a2903002204422088a7223121322004a722332134200041ac026a2802002235ad422086200041a8026a2802002236ad84223742037c2204422088a7223821392004a7223a213b2031213c2033213d203742027c2204422088a7223e213f2004a7224021412031214220332143203742017c2204422088a7224421452004a722462147203121482033214941f4ca81d906214a41b2da88cb07214b41eec8819903214c41e5f0c18b06214d41f4ca81d906214e41b2da88cb07214f41eec8819903215041e5f0c18b06215141f4ca81d906215241e5f0c18b06215341eec8819903215441b2da88cb0721550340200c20226a220cad422086200b20246a220bad842039ad422086203bad84852204a74110772239201b6a221bad2004422088a7411077223b201c6a221cad422086842022ad4220862024ad84852204a7410c772222200b6a2224ad2004422088a7410c77220b200c6a220cad422086842039ad203bad42208684852204a7410877223b201b6a221bad2004422088a74108772239201c6a221cad422086842022ad200bad42208684852204a74107772222200d20066a220bad200e20036a220dad422086842034ad2032ad42208684852207a7411077220e201d6a221dad2007422088a74110772232201e6a221ead422086842006ad2003ad42208684852207422088a7410c772203200d6a22066a2234ad4220862007a7410c77220d200b6a220bad2006ad42208684200ead2032ad42208684852207a74108772206201d6a221dad2007422088a74108772232201e6a221ead42208684200dad2003ad42208684852207422088a74107772203200b6a220bad842039ad2006ad42208684852256a74110772206201b6a221bad2056422088a74110772239201c6a221cad422086842022ad4220862003ad84852256a7410c772203200b6a220dad2056422088a7410c77222220346a220ead422086842006ad2039ad42208684852256a74108772239201b6a221bad2056422088a74108772234201c6a221cad422086842003ad2022ad42208684852256a741077721032004422088a7410777220620246a2222ad2007a74107772224200c6a220cad42208684203bad4220862032ad84852204a74110772232201d6a221dad2004422088a7411077223b201e6a221ead422086842006ad2024ad42208684852204a7410c77220620226a220bad2004422088a7410c772222200c6a220cad422086842032ad203bad42208684852204a74108772232201d6a221dad2004422088a7410877223b201e6a221ead422086842006ad2022ad42208684852204a74107772122204c20276a2206ad422086204d20286a2224ad84203fad4220862041ad84852207a7411077223f20176a2217ad2007422088a7411077224120186a2218ad422086842027ad4220862028ad84852207a7410c77222720246a2224ad2007422088a7410c77222820066a2206ad42208684203fad2041ad42208684852207a7410877224120176a2217ad2007422088a7410877223f20186a2218ad422086842027ad2028ad42208684852207a74107772227204b20266a2228ad204a20256a224aad42208684203dad203cad42208684852257a7411077223c20196a2219ad2057422088a7411077223d201a6a221aad422086842026ad2025ad42208684852257422088a7410c772225204a6a22266a224aad4220862057a7410c77224b20286a2228ad2026ad42208684203cad203dad42208684852257a7410877222620196a2219ad2057422088a7410877223c201a6a221aad42208684204bad2025ad42208684852257422088a7410777222520286a2228ad84203fad2026ad42208684852258a7411077222620176a2217ad2058422088a7411077223d20186a2218ad422086842027ad4220862025ad84852258a7410c77222520286a224bad2058422088a7410c772227204a6a224aad422086842026ad203dad42208684852258a7410877223f20176a2217ad2058422088a7410877223d20186a2218ad422086842025ad2027ad42208684852258a741077721252007422088a7410777222620246a2224ad2057a7410777222720066a2206ad422086842041ad422086203cad84852207a7411077222820196a2219ad2007422088a7411077223c201a6a221aad422086842026ad2027ad42208684852207a7410c77222620246a224dad2007422088a7410c77222420066a224cad422086842028ad203cad42208684852207a7410877223c20196a2219ad2007422088a74108772241201a6a221aad422086842026ad2024ad42208684852207a741077721272050202b6a2206ad4220862051202c6a2224ad842045ad4220862047ad84852257a7411077222620106a2228ad2057422088a7411077221020126a2212ad42208684202bad422086202cad84852257a7410c77222b20246a2224ad2057422088a7410c77222c20066a2206ad422086842026ad2010ad42208684852257a7410877222620286a2228ad2057422088a7410877221020126a2212ad42208684202bad202cad42208684852257a7410777222b204f202a6a222cad204e20296a2245ad422086842043ad2042ad42208684852259a7411077224220146a2214ad2059422088a7411077224320166a2216ad42208684202aad2029ad42208684852259422088a7410c77222920456a222a6a2245ad4220862059a7410c772247202c6a222cad202aad422086842042ad2043ad42208684852259a7410877222a20146a2214ad2059422088a7410877224220166a2216ad422086842047ad2029ad42208684852259422088a74107772229202c6a222cad842010ad202aad4220868485225aa7411077222a20286a2228ad205a422088a7411077221020126a2212ad42208684202bad4220862029ad8485225aa7410c772229202c6a224fad205a422088a7410c77222b20456a224ead42208684202aad2010ad4220868485225aa7410877224520286a2210ad205a422088a7410877224320126a2212ad422086842029ad202bad4220868485225aa741077721292057422088a7410777222820246a2224ad2059a7410777222a20066a2206ad422086842026ad4220862042ad84852257a7411077222620146a222bad2057422088a7411077222c20166a2216ad422086842028ad202aad42208684852257a7410c77222820246a2251ad2057422088a7410c77222420066a2250ad422086842026ad202cad42208684852257a74108772242202b6a2214ad2057422088a7410877224720166a2216ad422086842028ad2024ad42208684852257a7410777212b205320306a2206ad2054202f6a2224ad422086842035ad4220862036ad84852259a7411077222620086a2228ad2059422088a7411077222a200a6a222cad42208684202fad4220862030ad84852259a7410c77222f20066a2206ad2059422088a7410c77223020246a2224ad422086842026ad202aad42208684852259a7410877222620286a2228ad2059422088a7410877222a202c6a222cad42208684202fad2030ad42208684852259a7410777222f2052202d6a2230ad4220862055202e6a2208ad842049ad2048ad4220868485225ba7411077220a20056a2205ad205b422088a7411077223520096a2209ad42208684202ead202dad4220868485225b422088a7410c77222d20306a222e6a2230ad422086205ba7410c77223620086a2208ad202ead42208684200aad2035ad4220868485225ba7410877222e20056a2205ad205b422088a7410877224820096a2209ad422086842036ad202dad4220868485225b422088a7410777222d20086a2208ad84202aad202ead4220868485225ca7411077222a20286a2228ad205c422088a7411077222e202c6a222cad42208684202fad422086202dad8485225ca7410c77222d20086a2255ad205c422088a7410c77222f20306a2252ad42208684202aad202ead4220868485225ca7410877223520286a2208ad205c422088a74108772249202c6a220aad42208684202dad202fad4220868485225ca7410777212d2059422088a7410777222820066a2206ad205ba7410777222a20246a2224ad422086842026ad4220862048ad84852259a7411077222620056a222cad2059422088a7411077222e20096a222fad422086842028ad202aad42208684852259a7410c77222820066a2253ad2059422088a7410c77220620246a2254ad422086842026ad202ead42208684852259a74108772248202c6a2205ad2059422088a74108772236202f6a2209ad422086842028ad2006ad42208684852259a7410777212f2056422088a741077721242004422088a741077721062058422088a741077721282007422088a74107772126205a422088a7410777212c2057422088a7410777212a205c422088a741077721302059422088a7410777212e2002417f6a22020d000b41002102200041003602800220002802a802215d2000203742047c22043e02a8022000203220316a3602fc012000203420336a3602f8012000203920386a3602f4012000203b203a6a3602f0012000201e20156a3602ec012000201d20136a3602e8012000201c20116a3602e4012000201b200f6a3602e00120002003201f6a3602dc012000200620206a3602d8012000202220216a3602d4012000202420236a3602d0012000200e41f4ca81d9066a3602cc012000200d41b2da88cb076a3602c8012000200c41eec88199036a3602c4012000200b41e5f0c18b066a3602c0012000203c20316a3602bc012000203d20336a3602b8012000203f203e6a3602b4012000204120406a3602b0012000201a20156a3602ac012000201920136a3602a8012000201820116a3602a40120002017200f6a3602a00120002025201f6a36029c012000202620206a360298012000202720216a360294012000202820236a360290012000204a41f4ca81d9066a36028c012000204b41b2da88cb076a360288012000204c41eec88199036a360284012000204d41e5f0c18b066a360280012000204220316a36027c2000204320336a3602782000204520446a3602742000204720466a3602702000201620156a36026c2000201420136a3602682000201220116a36026420002010200f6a36026020002029201f6a36025c2000202a20206a3602582000202b20216a3602542000202c20236a3602502000204e41f4ca81d9066a36024c2000204f41b2da88cb076a3602482000205041eec88199036a3602442000205141e5f0c18b066a3602402000200920156a36022c2000200520136a3602282000200a20116a36022420002008200f6a3602202000202d201f6a36021c2000202e20206a3602182000202f20216a3602142000203020236a3602102000205241f4ca81d9066a36020c2000205541b2da88cb076a3602082000205441eec88199036a3602042000205341e5f0c18b066a36020020002802ac022103200020044220883e02ac02200020002802b40220486a36023c200020002802b00220496a3602382000200320356a3602342000205d20366a3602300b200020024102746a28020021032000200241016a360280020240200141016a220620014f0d004180bcc800413941bcbcc800103f000b20032006700bfb0303057f017e047f230041306b220424000240024002402002200384500d002004200010b806200441206a200428020022052004280208220610b402024002400240024002400240200428022022070d00410021002004410036021820044208370310410021080c010b200420042902242209370214200420073602102009a7210a410021000240024002402009422088a7220841014b0d0020080e020201020b2008210b03402000200b410176220c20006a220d2007200d41186c6a28020020014b1b2100200b200c6b220b41014b0d000b0b2007200041186c6a280200220b2001460d032000200b2001496a220020084b0d070b2008200a470d010b200441106a20084101109c012004280214210a200428021021070b2007200041186c6a220b41186a200b200820006b41186c109e081a200b41106a2003370300200b2002370308200b20013602002004200841016a220836021820070d012006ad4220862005ad8410070c020b200020084f0d042007200041186c6a22002000290308220920027c2202370308200041106a2200200029030020037c2002200954ad7c3703000b200420063602242004200536022020072008200441206a109603200a450d00200a41186c450d00200710350b2004280204450d00200510350b200441306a24000f0b20002008104d000b2000200841e0bbc8001042000be30202047f017e230041206b2203240002400240200241e8006c4104722204417f4c0d00200410332205450d0120034100360208200320043602042003200536020020022003107702402002450d00200241e8006c21064100210403402003200120046a220241c8006a412010780240024020022d00004101460d00200341003a00102003200341106a41011078200241086a29030021072003200241106a29030037031820032007370310200341106a21050c010b200341013a00102003200341106a410110782003200241016a41201078200241286a29030021072003200241306a29030037031820032007370310200341106a21050b2003200541101078200241386a29030021072003200241c0006a290300370318200320073703102003200341106a411010782006200441e8006a2204470d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1044000b1045000bdc0703027f017e067f230041e0006b2203240041a29bc800ad4280808080f00084100122042900002105200341086a41086a200441086a290000370300200320053703082004103541b39bc800ad4280808080d00084100122042900002105200341186a41086a200441086a29000037030020032005370318200410350240024002400240412010332204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020032004ad42808080808004841003220129000037034820011035200341dc006a2201200441206a360200200320043602582003200341c8006a41086a22063602542003200341c8006a360250200341286a200341d0006a107b20041035412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2201417f4c0d01200328023821092003280228210a0240024020010d004100210b410121040c010b200110332204450d012001210b0b02400240200b410f4d0d00200b21020c010b200b41017422024110200241104b1b22024100480d030240200b0d002002103322040d010c050b200b2002460d002004200b200210372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020024170714110460d002002210b0c010b2002410174220b4120200b41204b1b220b4100480d032002200b460d0020042002200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21020c010b2007415f4b0d03200b41017422022006200220064b1b22024100480d03200b2002460d002004200b200210372204450d040b200441206a200a2007109d081a02400240200220066b2008490d002002210b0c010b20012006490d032002410174220b2001200b20014b1b220b4100480d03024020020d000240200b0d00410121040c020b200b10332204450d050c010b2002200b460d0020042002200b10372204450d040b200420066a20092008109d081a200020013602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541d4bac800ad4280808080d00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b8c1004057f017e047f017e230041f0016b22012400200141d0006a41186a22024200370300200141d0006a41106a22034200370300200141d0006a41086a220442003703002001420037035041a29bc800ad4280808080f00084100122052900002106200141f0006a41086a2207200541086a2900003703002001200637037020051035200420072903003703002001200129037037035041f69bc800ad4280808080c000841001220529000021062007200541086a2900003703002001200637037020051035200320012903702206370300200141306a41086a2004290300370300200141306a41106a2006370300200141306a41186a200729030037030020012001290350370330200141f0006a200141306a412010d50120012d007021052002200141f0006a41196a2900003703002003200141f0006a41116a2900003703002004200141f0006a41096a29000037030020012001290071370350410121070240024020054101460d0041002107200141003a00080c010b200141086a41096a2004290300370000200141086a41116a2003290300370000200141086a41196a2002290300370000200141013a0008200120012903503700090b20014189016a200041186a29000037000020014181016a200041106a290000370000200141f9006a200041086a29000037000020012000290000370071200141013a00700240024002402007450d00200141086a410172200141f0006a410172412010a008450d010b200141d0006a41186a22054200370300200141d0006a41106a22024200370300200141d0006a41086a220442003703002001420037035041a29bc800ad4280808080f00084100122082900002106200141f0006a41086a2207200841086a2900003703002001200637037020081035200420072903003703002001200129037037035041ef9bc800ad4280808080f000841001220829000021062007200841086a290000370300200120063703702008103520032001290370370000200341086a2007290300370000200141306a41086a2004290300370300200141306a41106a2002290300370300200141306a41186a200529030037030020012001290350370330200141f0006a200141306a412010d50120012d007021082005200141f0006a41196a2900003703002002200141f0006a41116a2900003703002004200141f0006a41096a29000037030020012001290071370350410121070240024020084101460d0041002107200141003a00080c010b200141086a41096a2004290300370000200141086a41116a2002290300370000200141086a41196a2005290300370000200141013a0008200120012903503700090b20014189016a200041186a29000037000020014181016a200041106a290000370000200141f9006a200041086a29000037000020012000290000370071200141013a007002402007450d00200141086a410172200141f0006a410172412010a008450d010b200141f0006a41186a4200370300200141f0006a41106a22054200370300200141f0006a41086a220442003703002001420037037041a29bc800ad4280808080f000841001220729000021062004200741086a29000037030020012006370370200710354189eaca00ad4280808080f00084100122072900002106200141d0006a41086a2202200741086a2900003703002001200637035020071035200520012903502206370300200141086a41086a2004290300370300200141086a41106a2006370300200141086a41186a200229030037030020012001290370370308200141f0006a200141086a10fe0120012802702207410120071b21084100210402400240024002402001290274420020071b2206422088a7220941014b0d0020090e020201020b2009210703402007410176220520046a22022004200820024105746a2000412010a0084101481b2104200720056b220741014b0d000b0b200820044105746a2000412010a008450d010b200642ffffff3f83500d01200810350c010b200420094f0d01200820044105746a2207200741206a2004417f7320096a410574109e081a200141d0006a41186a22024200370300200141d0006a41106a220a4200370300200141d0006a41086a220742003703002001420037035041a29bc800ad4280808080f0008410012205290000210b200141f0006a41086a2204200541086a2900003703002001200b3703702005103520072004290300370300200120012903703703504189eaca00ad4280808080f0008410012205290000210b2004200541086a2900003703002001200b3703702005103520032001290370370000200341086a2004290300370000200141306a41086a2007290300370300200141306a41106a200a290300370300200141306a41186a200229030037030020012001290350370330200141203602742001200141306a36027020082009417f6a200141f0006a1098020240200642ffffff3f83500d00200810350b200141f0006a200010b9062001280270210420013502782106200141013a000820064220862004ad84200141086aad42808080801084100202402001280274450d00200410350b200141f0006a200010ba06200135027842208620012802702204ad84100702402001280274450d00200410350b200141f0006a41086a41093a0000200141f0006a41096a200029000037000020014181016a200041086a29000037000020014189016a200041106a29000037000020014191016a200041186a290000370000200141123a007041b0b4cc004100200141f0006a10d4010b200141f0016a24000f0b20042009104e000bfc0403027f017e057f230041d0006b220224004186f0cb00ad4280808080800184100122032900002104200241086a41086a200341086a29000037030020022004370308200310354180eaca00ad4280808080900184100122032900002104200241186a41086a200341086a2900003703002002200437031820031035200220013602342002200241346aad4280808080c000841003220329000037033820031035200241cc006a200241386a3602002002200241386a41086a3602442002200241346a3602482002200241386a360240200241286a200241c0006a107b02400240024002402002280230220541206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121080c010b200141017422084110200841104b1b22084100480d03024020010d002008103322030d010c050b20012008460d0020032001200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821010c010b200841017422014120200141204b1b22014100480d0320082001460d0020032008200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2005490d00200121080c010b200541206a22082005490d03200141017422092008200920084b1b22084100480d0320012008460d0020032001200810372203450d040b200341206a20072005109d081a2000200636020820002008360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000bf21201277f230041f0046b220324000240024002402001280200220420012802044f0d00200341d7036a210520034184026a21062003418c046a2107200341d0036a4101722108200341b1046a220941036a210a03402001200441016a360200200341c0026a200410f504200341d0036a20032802c002220b20032802c80210b302200341b8046a41086a220c200841086a290000370300200341b8046a41106a220d200841106a290000370300200341b8046a41186a220e200841186a290000370300200341b8046a41206a220f200841206a290000370300200341b8046a41286a2210200841286a290000370300200341b8046a412f6a22112008412f6a290000370000200341e8026a41086a2212200741086a290000370300200341e8026a41106a2213200741106a290000370300200341e8026a41186a2214200741186a290000370300200341e8026a41206a2215200741206a280000360200200320082900003703b804200320072900003703e802200328028804211620032d00d0032117200320092800003602d8012003200a2800003600db010240201741024622180d0020032d00b004211920034180026a412f6a201129000037000020034180026a41286a201029030037030020034180026a41206a200f29030037030020034180026a41186a200e29030037030020034180026a41106a200d29030037030020034180026a41086a200c290300370300200341a8036a41086a2012290300370300200341a8036a41106a2013290300370300200341a8036a41186a2014290300370300200341a8036a41206a2015280200360200200320032903b80437038002200320032903e8023703a803200320032800db013600a303200320032802d8013602a0032016211a0b024020032802c402450d00200b10350b200c20034180026a41086a221b290300370300200d20034180026a41106a221c290300370300200e20034180026a41186a221d290300370300200f20034180026a41206a221e290300370300201020034180026a41286a221f290300370300201120034180026a412f6a290000370000200341d8016a41086a2220200341a8036a41086a220b290300370300200341d8016a41106a2221200341a8036a41106a2216290300370300200341d8016a41186a2222200341a8036a41186a2223290300370300200341d8016a41206a2224200341a8036a41206a222528020036020020032003290380023703b804200320032903a8033703d801200320032800a3033600d301200320032802a0033602d001200341d0036a41086a2226200c290300370300200341d0036a41106a2227200d290300370300200341d0036a41186a220d200e290300370300200341d0036a41206a220e200f290300370300200341d0036a41286a220f2010290300370300200341d0036a412f6a2011290000370000200320032903b8043703d003200b2020290300370300201620212903003703002023202229030037030020252024280200360200200320032903d8013703a803200320032800d3013600a303200320032802d0013602a00302400240024020180d002017410171450d010b4103210c0c010b20062005290000370000200641286a200541286a290000370000200641206a200541206a290000370000200641186a200541186a290000370000200641106a200541106a290000370000200641086a200541086a290000370000200341c0026a41086a2210200b290300370300200341c0026a41106a22112016290300370300200341c0026a41186a22172023290300370300200341c0026a41206a220b2025280200360200200320032903a8033703c0022012201b2902003703002013201c2902003703002014201d2902003703002015201e290200370300200341e8026a41286a2216201f290200370300200341e8026a41306a222320034180026a41306a280200360200200320032800a3033600bb02200320032802a0033602b80220032003290280023703e8024103210c201941ff01714103460d002026201229030037030020272013290300370300200d2014290300370300200e2015290300370300200f2016290300370300200341d0036a41306a22162023280200360200201b2010290300370300201c2011290300370300201d2017290300370300201e200b280200360200200320032903e8023703d003200320032903c00237038002200320032800bb023600ab03200320032802b8023602a8034103210c201a2002280200280200470d0020034198016a41306a201628020036020020034198016a41286a200f29030037030020034198016a41206a200e29030037030020034198016a41186a200d29030037030020034198016a41106a202729030037030020034198016a41086a2026290300370300200341f0006a41086a201b290300370300200341f0006a41106a201c290300370300200341f0006a41186a201d290300370300200341f0006a41206a201e280200360200200320032903d003370398012003200329038002370370200320032800ab0336006b200320032802a80336026820042128201a21292019210c0b200c41ff01714103470d02200128020022042001280204490d000b0b200041033a00600c010b200341306a41306a220820034198016a41306a280200360200200341306a41286a220720034198016a41286a290300370300200341306a41206a220d20034198016a41206a290300370300200341306a41186a220e20034198016a41186a290300370300200341306a41106a220f20034198016a41106a290300370300200341306a41086a221020034198016a41086a290300370300200341086a41086a2211200341f0006a41086a290300370300200341086a41106a2201200341f0006a41106a290300370300200341086a41186a2204200341f0006a41186a290300370300200341086a41206a2205200341f0006a41206a2802003602002003200329039801370330200320032903703703082003200328006b3600032003200328026836020020002028360200200020032903303702042000410c6a2010290300370200200041146a200f2903003702002000411c6a200e290300370200200041246a200d2903003702002000412c6a2007290300370200200041346a2008280200360200200020293602382000200329030837023c200041c4006a2011290300370200200041cc006a2001290300370200200041d4006a2004290300370200200041dc006a20052802003602002000200c3a0060200041e4006a2003280003360000200020032802003600610b200341f0046a24000b81fc010d017f017e037f017e017f017e027f017e057f017e067f067e0b7f230041f00b6b2201240010ff0342d0a1f10221020240024002400240024002400240024020004101460d00200141c8056a41186a22034200370300200141c8056a41106a22044200370300200141c8056a41086a22054200370300200142003703c80541a9d1cb00ad4280808080c0008422061001220729000021082005200741086a290000370300200120083703c8052007103541cdd1cb00ad4280808080b0018410012207290000210820014198076a41086a2209200741086a29000037030020012008370398072007103520042001290398072208370300200141a8056a41086a2005290300370300200141a8056a41106a2008370300200141a8056a41186a2009290300370300200120012903c8053703a80520014188056a200141a8056a10e1022001290390052108200128028805210a200342003703002004420037030020054200370300200142003703c805200610012207290000210b2005200741086a2900003703002001200b3703c8052007103541add1cb00ad4280808080a001841001220c290000210b200141e8056a41086a2207200c41086a2900003703002001200b3703e805200c1035200420012903e805220b370300200141a0096a41086a220c2005290300370300200141a0096a41106a220d200b370300200141a0096a41186a220e2007290300370300200120012903c8053703a009200141f8046a200141a0096a10e10220012802f804210f200129038005210b200342003703002004420037030020054200370300200142003703c80520061001220329000021062005200341086a290000370300200120063703c8052003103541c2d1cb00ad4280808080b001841001220329000021062007200341086a290000370300200120063703e80520031035200420012903e8052206370300200c2005290300370300200d2006370300200e2007290300370300200120012903c8053703a009200141e8046a200141a0096a10e102420020084200200a1b220620012903f004420020012802e8041b200b42c8017e4200200f1b7c7d220820082006561b42c801540d00200141a00a6a41186a220a4200370300200141a00a6a41106a22104200370300200141a00a6a41086a22074200370300200142003703a00a41a3edcb00ad4280808080f000842211100122032900002102200141f8056a41086a2205200341086a290000370300200120023703f8052003103520072005290300370300200120012903f8053703a00a41a5ebcb00ad4280808080c001841001220329000021022005200341086a290000370300200120023703f80520031035201020012903f8052202370300200c2007290300370300200d2002370300200e2005290300370300200120012903a00a3703a009200141e0046a200141a0096a412010c00120012802e404210f20012802e0042112200a42003703002010420037030020074200370300200142003703a00a20111001220329000021022005200341086a290000370300200120023703f8052003103520072005290300370300200120012903f8053703a00a41b1ebcb00ad4280808080d001841001220329000021022005200341086a290000370300200120023703f80520031035201020012903f8052202370300200c2007290300370300200d2002370300200e2005290300370300200120012903a00a3703a009200141a0096a10bd02210310c00420014198076a41186a420037030020014198076a41106a2213420037030020094200370300200142003703980741f7edcb00ad4280808080f000841001220729000021022009200741086a29000037030020012002370398072007103541eeedcb00ad4280808080900184100122072900002102200c200741086a290000370300200120023703a00920071035201320012903a009220237030020052009290300370300200141f8056a41106a2002370300200141f8056a41186a200c29030037030020012001290398073703f8054100210c200f410020121b210f200141a00a6a200141f8056a10ac01024020012903a00a22024202510d0020012903a80a2106200141a00a6a2010280200220d41016a10b801200141d8046a20012802a00a220720012802a80a10c00120012802dc04210920012802d8042105024020012802a40a450d00200710350b20054101470d002009200f41016a470d0020024201520d00200141c8056a41186a22074200370300200141c8056a41106a22094200370300200141c8056a41086a22054200370300200142003703c80541d1efcb00ad42808080809001841001220e29000021022005200e41086a290000370300200120023703c805200e103541ebc3c400ad428080808030841001220a2900002102200141f8056a41086a220e200a41086a290000370300200120023703f805200a1035200420012903f805370000200441086a2212200e290300370000200141a8056a41086a22142005290300370300200141a8056a41106a22152009290300370300200141a8056a41186a22162007290300370300200120012903c8053703a805200141c8046a200141a8056a10e102200141a0046a20012903d004420020012802c8041b220242e807802208420042e8074200108408200141a00a6a200d10bd01200141b0046a20012802a00a221720012802a80a10d70120012903a004220b200220084298787e7c42ff07837c2202427f200141a0046a41086a2903002002200b54ad7c501b20067d2118200141b0046a41106a290300420020012802b004220a1b210220012903b8044200200a1b210b024020012802a40a450d00201710350b200742003703002009420037030020054200370300200142003703c80541b6fdc600ad42808080808001841001220a29000021062005200a41086a290000370300200120063703c805200a103541e489c200ad4280808080d001841001220a2900002106200e200a41086a290000370300200120063703f805200a1035200420012903f8053700002012200e290300370000201420052903003703002015200929030037030020162007290300370300200120012903c8053703a80520014188046a200141a8056a412010d701200141f8036a200129039004420020012802880422051b220620014188046a41106a290300420020051b2208428094ebdc034200109808200141e8036a20012903f8032219200141f8036a41086a290300221a4280ec94a37c427f10840820082002200b200656200220085620022008511b22051b21022006200b20051b210b20012903e80320067c211b2018428086ebc7f5002018428086ebc7f500541b42058842ffffffff0f83428094ebdc037e4298ac9fd60380211c4100210741d87d2105024002400340200141d8036a2019201a200541ece4c6006a350200220642001084082007200b20012903d80322082006201b7e2206428094ebdc03802218a7417f2006428080808080c0b2cd3b541b200620184280ec94a37c7e7c4280cab5ee01566aad7c22065a2002200141d8036a41086a2903002006200854ad7c22085a200220085122091b6a2107200b200654200220085420091b0d01200541086a22050d000b200141c8036a2019201a42e8aafa0b4200108408200141d0036a29030020012903c8032206201b42e8aafa0b7e2202428094ebdc03802208a7417f2002428080808080c0b2cd3b541b200220084280ec94a37c7e7c4280cab5ee01566aad7c2202200654ad7c21060c010b02402007417f6a220520074d0d00200141c8026a2019201a42c0f0f50b4200108408200141d0026a29030020012903c8022206201b4228802202a7417f201b42c0f0f50b7e2208428080808080c0b2cd3b541b200820024280ec94a37c7e7c4280cab5ee01566aad7c2202200654ad7c21060c010b02400240200541244b0d00200141b8036a2019201a2005410374220941c4e2c6006a280200220ead2206420010840820014198036a200b20012903b80322082006201b7e2206428094ebdc03802218a7417f2006428080808080c0b2cd3b541b200620184280ec94a37c7e7c4280cab5ee01566aad7c2206200b2006562002200141b8036a41086a2903002006200854ad7c22085620022008511b22051b22182006200b20051b22067d220b2002200820051b2008200220051b7d2018200654ad7d41002007410374220a41c4e2c6006a2802002207200e6b220e200e20074b1b22074101200741014b1bad2202420010980820014188036a200129039803220620014198036a41086a290300221820024200108408200141a8036a2019201a200941c8e2c6006a2802002207ad221d4200108408200141d8026a20184200200a41c8e2c6006a28020022092007200920074b220e1b20072009200e1b6bad22084200108408200141f8026a2006420020084200108408200141e8026a4200420020064200108408427f427f200141f8026a41086a290300220620012903d80220012903e8027c7c221820012903e00220012903f00284420052201820065472220e1b2218427f20012903f802200e1b2206200b2001290388037d20087e2002807c2202200654220ead7c2208200e2008201854200220065a1b220e1b210b427f2002200e1b2108200141a8036a41086a29030020012903a8032218201d201b7e2202428094ebdc03802206a7417f2002428080808080c0b2cd3b541b200220064280ec94a37c7e7c4280cab5ee01566aad7c2206201854ad7c2102200920074d2005730d0142002002200b7d2006200854ad7d220b200620087d2208200656200b200256200b2002511b22051b21064200200820051b21020c020b2005412541e4b8ca001042000b427f2002200b7c200620087c22082006542205ad7c22062005200620025420062002511b22051b2106427f200820051b21020b20014188026a2019201a4280c2d72f4200108408200141b8026a20022006428094ebdc034200109808200141f8016a2001290388022208201b420a802206a7417f201b4280c2d72f7e220b428080808080c0b2cd3b541b200b20064280ec94a37c7e7c4280cab5ee01566aad7c220620014188026a41086a2903002006200854ad7c428094ebdc034200109808200141a8026a20012903b8022208200141b8026a41086a290300220b4280ec94a37c427f10840820014198026a2008200b201c4200108408200141e8016a20012903f8012208200141f8016a41086a290300220b4280ec94a37c427f108408200141d8016a2008200b201c4200108408200141ac0a6a200d360200200141a00a6a41086a41003a0000200141b00a6a2001290398022208201c200220012903a8027c7e2202428094ebdc0380220ba7417f2002428080808080c0b2cd3b541b2002200b4280ec94a37c7e7c4280cab5ee01566aad7c2202370300200141b80a6a20014198026a41086a2903002002200854ad7c220b370300200141c80a6a4200200141d8016a41086a29030020012903d8012208201c200620012903e8017c7e2206428094ebdc03802218a7417f2006428080808080c0b2cd3b541b200620184280ec94a37c7e7c4280cab5ee01566aad7c2206200854ad7c2208200b7d2006200254ad7d2218200620027d221b200656201820085620182008511b22051b2206370300200141c00a6a4200201b20051b2208370300200141043a00a00a41b0b4cc004100200141a00a6a10d401200141f8056a200d10be0120012802f805210520013502800621182001200b3703a80a200120023703a00a20184220862005ad84200141a00a6aad220b42808080808002841002024020012802fc05450d00200510350b02400240024020082006844200520d002001420037038006200142003703f805200141a0096aad428080808080048421180c010b200141c8056a41186a22074200370300200141c8056a41106a22094200370300200141c8056a41086a22054200370300200142003703c80541b6fdc600ad428080808080018422021001220e290000211820014198076a41086a220d200e41086a2900003703002001201837039807200e10352005200d29030037030020012001290398073703c80541e489c200ad4280808080d0018422181001220a290000211b200141e8056a41086a220e200a41086a2900003703002001201b3703e805200a1035200420012903e805370000200441086a2214200e290300370000200141a0096a41086a22152005290300370300200141a0096a41106a22162009290300370300200141a0096a41186a22172007290300370300200120012903c8053703a009200141c0016a200141a0096a412010d701200141c0016a41106a290300211b20012903c801211920012802c001210a200742003703002009420037030020054200370300200142003703c8052002100122122900002102200d201241086a2900003703002001200237039807201210352005200d29030037030020012001290398073703c80520181001220d2900002102200e200d41086a290000370300200120023703e805200d1035200420012903e8053700002014200e290300370000201520052903003703002016200929030037030020172007290300370300200120012903c8053703a0092001427f201b4200200a1b220220067c20194200200a1b221b20087c2219201b542205ad7c22182005201820025420182002511b22051b3703a80a2001427f201920051b3703a00a200141a0096aad42808080808004842218200b42808080808002841002024020050d00200120083703f80520012006370380060c020b2001201b427f8522083703f80520012002427f85220637038006201b200283427f520d010b200141c8056a41186a22074200370300200141c8056a41106a22094200370300200141c8056a41086a22054200370300200142003703c80541b6fdc600ad428080808080018422021001220e290000210620014198076a41086a220d200e41086a2900003703002001200637039807200e10352005200d29030037030020012001290398073703c80541e489c200ad4280808080d0018422061001220a2900002108200141e8056a41086a220e200a41086a290000370300200120083703e805200a1035200420012903e805370000200441086a2214200e290300370000200141a0096a41086a22152005290300370300200141a0096a41106a22162009290300370300200141a0096a41186a22172007290300370300200120012903c8053703a009200141a8016a200141a0096a412010d701200141a8016a41106a290300210820012903b001211b20012802a801210a200742003703002009420037030020054200370300200142003703c8052002100122122900002102200d201241086a2900003703002001200237039807201210352005200d29030037030020012001290398073703c80520061001220d2900002102200e200d41086a290000370300200120023703e805200d1035200420012903e8053700002014200e290300370000201520052903003703002016200929030037030020172007290300370300200120012903c8053703a009200120084200200a1b3703a80a2001201b4200200a1b3703a00a2018200b428080808080028410020c010b200142f0f2bda1a7ee9cb9f9003703f805200141a00a6a200141f8056a10e001200141a00a6a2008200610df01200141b80a6a2006370300200141b00a6a2008370300200141a80a6a41063a00002001410c3a00a00a41b0b4cc004100200141a00a6a10d4010b200141a00a6a41186a220d4200370300200141a00a6a41106a220e4200370300200141a00a6a41086a22074200370300200142003703a00a2011100122092900002102200141f8056a41086a2205200941086a290000370300200120023703f8052009103520072005290300370300200120012903f8053703a00a41c897ca00ad4280808080a001841001220929000021022005200941086a290000370300200120023703f80520091035201020012903f805370000201041086a2005290300370000200141a0096a41086a2007290300370300200141a0096a41106a200e290300370300200141a0096a41186a200d290300370300200120012903a00a3703a009200141203602e40b2001200141a0096a3602e00b200141a8056a200141a0096aad221b42808080808004842211100510c2010240024020012802a805220d0d000c010b20012802ac05210e2001200141a8056a41086a2802003602ec052001200d3602e805200141a0016a200141e8056a10c4010240024020012802a0010d0020012802a401220a20012802ec05220941a0016e22052005200a4b1bad42a0017e2202422088a70d072002a72205417f4c0d070240024020050d004101210c0c010b20051033220c450d090b200141003602a8082001200c3602a0082001200541a0016e3602a4080240200a450d00200141a00a6a41206a211520014198076a410172211641002114410021120240034041002105200141003a00b807201241016a211202400340200141003a00d00b20092005460d0120014198076a20056a20012802e80522072d00003a00002001200741016a3602e8052001200541016a22073a00b8072007210520074120470d000b200141c8056a41086a220520014198076a41086a290300370300200141c8056a41106a221720014198076a41106a290300370300200141c8056a41186a221e20014198076a41186a29030037030020012001290398073703c8052001200920076b3602ec0520014198076a200141e8056a10c20220012d0098074101460d02200141a00a6a41186a201e290300370300200141a00a6a41106a2017290300370300200141a00a6a41086a2005290300370300200120012903c8053703a00a20152016418001109d081a200141f8056a200141a00a6a41a001109d081a0240201420012802a408470d00200141a0086a2014410110a00120012802a008210c20012802a80821140b200c201441a0016c6a200141f8056a41a001109d081a2001201441016a22143602a8082012200a460d0320012802ec0521090c010b0b200141003602ec05200541ff0171450d00200141003a00b8070b024020012802a4082205450d00200541a0016c450d00200c10350b0c010b20012902a4082102200c0d010b4100210c2001410036028006200142013703f8052001410936029c072001200141e00b6a360298072001200141f8056a3602a008200141b40a6a4101360200200142013702a40a200141c888c2003602a00a200120014198076a3602b00a200141a0086a41e88ac500200141a00a6a10431a20013502800642208620013502f80584100620012802fc05450d0020012802f80510350b200e450d00200d10350b2003200341ff017141024771211f200141003602a80a200142013703a00a200141a00a6a410020024200200c1b2219422088a7222041a0016c221241a0016e108a01200c4101200c1b211620012802a80a210c20012802a00a212102402020450d002021200c4105746a21052012210920162107034020052007290000370000200541186a200741186a290000370000200541106a200741106a290000370000200541086a200741086a290000370000200c41016a210c200541206a2105200741a0016a2107200941e07e6a22090d000b0b20012802a40a2122200141a00a6a41186a22034200370300200141a00a6a41106a22094200370300200141a00a6a41086a22074200370300200142003703a00a41a3edcb00ad4280808080f0008422021001220d2900002106200141f8056a41086a2205200d41086a290000370300200120063703f805200d103520072005290300370300200120012903f8053703a00a41f393ca00ad4280808080a001841001220d29000021062005200d41086a290000370300200120063703f805200d1035201020012903f805370000201041086a22142005290300370000200141a0096a41086a220d2007290300370300200141a0096a41106a220e2009290300370300200141a0096a41186a220a2003290300370300200120012903a00a3703a009200141203602a40a2001200141a0096a3602a00a2021200c200141a00a6a1098020240201f450d00200342003703002009420037030020074200370300200142003703a00a20021001220c29000021062005200c41086a290000370300200120063703f805200c103520072005290300370300200120012903f8053703a00a41beebcb00ad4280808080a002841001220c29000021062005200c41086a290000370300200120063703f805200c1035201020012903f80537000020142005290300370000200d2007290300370300200e2009290300370300200a2003290300370300200120012903a00a3703a009200141a00a6a200141a0096a10c50220012802a00a220c450d002011100720012902a40a42ffffffff0383500d00200c10350b200342003703002009420037030020074200370300200142003703a00a20021001220c29000021022005200c41086a290000370300200120023703f805200c103520072005290300370300200120012903f8053703a00a41a5ebcb00ad4280808080c001841001220c29000021022005200c41086a290000370300200120023703f805200c1035201020012903f80537000020142005290300370000200d2007290300370300200e2009290300370300200a2003290300370300200120012903a00a3703a0092001200f41016a22153602a00a2011200141a00a6aad22184280808080c000841002200141c8056a41186a220c4200370300200141c8056a41106a22034200370300200141c8056a41086a22054200370300200142003703c80541f7edcb00ad4280808080f000841001220729000021022005200741086a290000370300200120023703c8052007103541eeedcb00ad4280808080900184100122072900002102200141e8056a41086a2214200741086a290000370300200120023703e80520071035200420012903e805370000200441086a2014290300370000200d2005290300370300200e2003290300370300200a200c290300370300200120012903c8053703a009200141a00a6a200141a0096a10ac01200141a00a6a4100200928020041016a20012903a00a4202511b10b80120014198016a20012802a00a220c20012802a80a10c001200128029c0121072001280298012105024020012802a40a450d00200c10350b024020054101470d00024020072015460d00200720154f0d0141c3a6c000ad428080808080068410060b201510d8010b200141c8056a41186a220c4200370300200141c8056a41106a22094200370300200141c8056a41086a22054200370300200142003703c80541f7edcb00ad4280808080f0008410012207290000210220014198076a41086a2203200741086a2900003703002001200237039807200710352005200329030037030020012001290398073703c80541e4edcb00ad4280808080a00184100122072900002102200141e8056a41086a2203200741086a290000370300200120023703e80520071035200420012903e805370000200441086a2003290300370000200141a0096a41086a2005290300370300200141a0096a41106a2009290300370300200141a0096a41186a200c290300370300200120012903c8053703a00920014190016a200141a0096a412010c001200f41026a2105024002402001280290014101460d0020014198056a200510bf010c010b200141a00a6a20012802940110b80120014188016a20012802a00a220c20012802a80a10c001200128028c0121092001280288012107024020012802a40a450d00200c10350b024020070d0041fdb5c000ad4280808080e006841006410021090b200141c8056a41186a22034200370300200141c8056a41106a220d4200370300200141c8056a41086a22074200370300200142003703c80541f7edcb00ad4280808080f000841001220c290000210220014198076a41086a220e200c41086a2900003703002001200237039807200c10352007200e29030037030020012001290398073703c8054193eecb00ad42808080808001841001220c2900002102200141e8056a41086a220e200c41086a290000370300200120023703e805200c1035200420012903e805370000200441086a200e290300370000200141a0096a41086a2007290300370300200141a0096a41106a200d290300370300200141a0096a41186a2003290300370300200120012903c8053703a0094100200520096b2207200720054b1b210c0240024002404100200141a0096a10e5012207200741ff01714104461b41ff0171220741034b0d00024020070e0400020103000b200c41064f0d020b0240200c41016a4106490d00200141c8056a41186a220c4200370300200141c8056a41106a22094200370300200141c8056a41086a22054200370300200142003703c80541f7edcb00ad4280808080f0008410012207290000210220014198076a41086a2203200741086a2900003703002001200237039807200710352005200329030037030020012001290398073703c80541d9eecb00ad4280808080d00284100122072900002102200141e8056a41086a2203200741086a290000370300200120023703e80520071035200420012903e805370000200441086a2003290300370000200141a0096a41086a2005290300370300200141a0096a41106a2009290300370300200141a0096a41186a200c290300370300200120012903c8053703a009200141013a00d00b201b4280808080800484200141d00b6aad4280808080108410020b20014100360298050c020b200141c8056a41186a22094200370300200141c8056a41106a22034200370300200141c8056a41086a22074200370300200142003703c80541f7edcb00ad4280808080f000841001220c290000210220014198076a41086a220d200c41086a2900003703002001200237039807200c10352007200d29030037030020012001290398073703c8054193eecb00ad42808080808001841001220c2900002102200141e8056a41086a220d200c41086a290000370300200120023703e805200c1035200420012903e805370000200441086a200d290300370000200141a0096a41086a2007290300370300200141a0096a41106a2003290300370300200141a0096a41186a2009290300370300200120012903c8053703a009201b428080808080048410070b200141c8056a41186a22094200370300200141c8056a41106a22034200370300200141c8056a41086a22074200370300200142003703c80541f7edcb00ad4280808080f000841001220c290000210220014198076a41086a220d200c41086a2900003703002001200237039807200c10352007200d29030037030020012001290398073703c80541d9eecb00ad4280808080d002841001220c2900002102200141e8056a41086a220d200c41086a290000370300200120023703e805200c1035200420012903e805370000200441086a200d290300370000200141a0096a41086a2007290300370300200141a0096a41106a2003290300370300200141a0096a41186a2009290300370300200120012903c8053703a009200141003a00d00b201b4280808080800484200141d00b6aad42808080801084100220014198056a200510bf010b201620126a211e0240024020012802980522230d00200141a00a6a41186a4200370300200141a00a6a41106a220c4200370300200141a00a6a41086a22054200370300200142003703a00a41a3edcb00ad4280808080f000841001220729000021022005200741086a290000370300200120023703a00a2007103541f393ca00ad4280808080a0018410012207290000210220014198076a41086a2209200741086a290000370300200120023703980720071035200c2001290398072202370300200141f8056a41086a2005290300370300200141f8056a41106a2002370300200141f8056a41186a2009290300370300200120012903a00a3703f805200141a00a6a200141f8056a10fe0120012902a40a420020012802a00a22051b21022005410120051b2124410021250c010b41012125200129029c052102202321240b200120253a00c00b2001201e3602d40b200120163602d00b2001200141d00b6a3602e40b2001200141c00b6a3602e00b200141003602f005200142013703e805200141e8056a41002002422088a72205410574220741057510a00120012802f005211420012802e805211702402005450d002017201441a0016c6a210c2014200741606a4105766a2126200141a00a6a41206a210a200141a0086a41e0006a2127200141a0086a41c0006a2114200141a0086a41206a2112200141f8056a410172210f202421050340200141c8056a41186a2209200541186a290000370300200141c8056a41106a2204200541106a290000370300200141c8056a41086a2203200541086a290000370300200120052900003703c805200141a8056a200141c8056a10dd06200141f8056a20012802a805220e20012802b00510c10220012d00f805210d20014198076a200f418001109d081a02400240200d4101470d00200141a0096a20014198076a418001109d081a024020012802ac05450d00200e10350b200141a0086a200141a0096a418001109d081a0c010b024020012802ac05450d00200e10350b200141a0086a4100418001109f081a0b024020012802e00b2d00000d0020012802e40b220e280200220d200e280204460d00200e200d41a0016a36020002400240200141a0086a200d41206a220e460d00200e200141a0086a412010a0080d010b02402012200d41c0006a220e460d00200e2012412010a0080d010b02402014200d41e0006a220e460d00200e2014412010a0080d010b2027200d4180016a220d460d01200d2027412010a008450d010b20012802e00b41013a00000b200541206a2105200141a00a6a41186a2009290300370300200141a00a6a41106a2004290300370300200141a00a6a41086a2003290300370300200120012903c8053703a00a200a200141a0086a418001109d081a200c200141a00a6a41a001109d0841a0016a210c200741606a22070d000b202641016a21140b200120143602f0050240200242ffffff3f83500d00202410350b2014ad42a0017e2202422088a70d042002a72205417f4c0d0420012802ec05212820012d00c00b21240240024020050d00410121070c010b200510332207450d060b2001410036028006200120073602f8052001200541a0016e3602fc05200141f8056a4100201410a00120012802800621030240024020140d0020012802f805210f0c010b2017201441a0016c6a210e20012802f805220f200341a0016c6a210d200141a00a6a4180016a2107200141a00a6a41e0006a210c200141a00a6a41c0006a2109200141a00a6a41206a2104201721050340200141a00a6a41186a200541186a290000370300200141a00a6a41106a200541106a290000370300200141a00a6a41086a200541086a290000370300200120052900003703a00a200441186a200541386a290000370000200441106a200541306a290000370000200441086a200541286a2900003700002004200541206a2900003700002009200541c0006a290000370000200941086a200541c8006a290000370000200941106a200541d0006a290000370000200941186a200541d8006a290000370000200c200541e0006a290000370000200c41086a200541e8006a290000370000200c41106a200541f0006a290000370000200c41186a200541f8006a290000370000200720054180016a290000370000200741086a20054188016a290000370000200741106a20054190016a290000370000200741186a20054198016a290000370000200341016a2103200d200141a00a6a41a001109d0841a0016a210d200541a0016a2205200e470d000b0b20012802fc052127200141a00a6a41186a22094200370300200141a00a6a41106a22044200370300200141a00a6a41086a22074200370300200142003703a00a41a3edcb00ad4280808080f000841001220c2900002102200141f8056a41086a2205200c41086a290000370300200120023703f805200c103520072005290300370300200120012903f8053703a00a41c897ca00ad4280808080a001841001220c29000021022005200c41086a290000370300200120023703f805200c1035201020012903f805370000201041086a2005290300370000200141a0096a41086a2007290300370300200141a0096a41106a2004290300370300200141a0096a41186a2009290300370300200120012903a00a3703a009200341a0016c4104722205417f4c0d04200510332207450d05200141003602a80a200120053602a40a200120073602a00a2003200141a00a6a10770240024020030d0020012802a80a210520012802a40a210d20012802a00a21070c010b200f200341a0016c6a2112410020012802a80a22036b210920012802a40a210d4100210c03402003200c6a210402400240200d20096a4120490d0020012802a00a2107200d210e0c010b200441206a22052004490d04200d41017422072005200720054b1b220e4100480d0402400240200d0d000240200e0d00410121070c020b200e103322070d010c0c0b20012802a00a2107200d200e460d002007200d200e10372207450d0b0b2001200e3602a40a200120073602a00a0b200720036a200c6a220d200f200c6a2205290000370000200d41186a200541186a290000370000200d41106a200541106a290000370000200d41086a200541086a2900003700002001200441206a220d3602a80a02400240200e20096a41606a411f4d0d00200e210d0c010b200d41206a220a200d490d04200e410174220d200a200d200a4b1b220d4100480d0402400240200e0d000240200d0d00410121070c020b200d10332207450d0c0c010b200e200d460d002007200e200d10372207450d0b0b2001200d3602a40a200120073602a00a0b200720036a200c6a220e41206a200541206a290000370000200e41386a200541386a290000370000200e41306a200541306a290000370000200e41286a200541286a2900003700002001200441c0006a220e3602a80a02400240200d20096a41406a411f4d0d00200d210e0c010b200e41206a220a200e490d04200d410174220e200a200e200a4b1b220e4100480d0402400240200d0d000240200e0d00410121070c020b200e10332207450d0c0c010b200d200e460d002007200d200e10372207450d0b0b2001200e3602a40a200120073602a00a0b200720036a200c6a220d41c0006a200541c0006a290000370000200d41d8006a200541d8006a290000370000200d41d0006a200541d0006a290000370000200d41c8006a200541c8006a2900003700002001200441e0006a220d3602a80a02400240200e20096a41a07f6a411f4d0d00200e210a0c010b200d41206a220a200d490d04200e410174220d200a200d200a4b1b220a4100480d0402400240200e0d000240200a0d00410121070c020b200a10332207450d0c0c010b200e200a460d002007200e200a10372207450d0b0b2001200a3602a40a200120073602a00a0b200720036a200c6a220d41e0006a200541e0006a290000370000200d41f8006a200541f8006a290000370000200d41f0006a200541f0006a290000370000200d41e8006a200541e8006a290000370000200120044180016a220d3602a80a02400240200a20096a41807f6a411f4d0d00200a210d0c010b200d41206a220e200d490d04200a410174220d200e200d200e4b1b220d4100480d0402400240200a0d000240200d0d00410121070c020b200d10332207450d0c0c010b200a200d460d002007200a200d10372207450d0b0b2001200d3602a40a200120073602a00a0b200720036a200c6a220e4180016a20054180016a290000370000200e4198016a20054198016a290000370000200e4190016a20054190016a290000370000200e4188016a20054188016a2900003700002001200441a0016a3602a80a200941e07e6a2109200c41a0016a210c200541a0016a2012470d000b2003200c6a21050b20112005ad4220862007ad8410020240200d450d00200710350b02402027450d00202741a0016c450d00200f10350b200141a00a6a41186a22094200370300200141a00a6a41106a22044200370300200141a00a6a41086a22074200370300200142003703a00a41a3edcb00ad4280808080f000841001220c2900002102200141f8056a41086a2205200c41086a290000370300200120023703f805200c103520072005290300370300200120012903f8053703a00a41b1ebcb00ad4280808080d001841001220c29000021022005200c41086a290000370300200120023703f805200c1035201020012903f805370000201041086a2005290300370000200141a0096a41086a2007290300370300200141a0096a41106a2004290300370300200141a0096a41186a2009290300370300200120012903a00a3703a009200120243a00a00a20112018428080808010841002200120153602a40a200141053a00a00a41b0b4cc004100200141a00a6a10d40141081033220c450d07200c201e360204200c201636020002400240201f0d00200141a00a6a41186a22094200370300200141a00a6a41106a22044200370300200141a00a6a41086a22074200370300200142003703a00a41a8e7cb00ad4280808080f00184100122032900002102200141f8056a41086a2205200341086a290000370300200120023703f8052003103520072005290300370300200120012903f8053703a00a419ce7cb00ad4280808080c001841001220329000021022005200341086a290000370300200120023703f80520031035201020012903f805370000201041086a220d2005290300370000200141a0096a41086a220e2007290300370300200141a0096a41106a220a2004290300370300200141a0096a41186a220f2009290300370300200120012903a00a3703a009200141f8006a200141a0096a10e102200129038001210220012802782112200942003703002004420037030020074200370300200142003703a00a41a3edcb00ad4280808080f000841001220329000021062005200341086a290000370300200120063703f8052003103520072005290300370300200120012903f8053703a00a41a5ebcb00ad4280808080c001841001220329000021062005200341086a290000370300200120063703f80520031035201020012903f805370000200d2005290300370000200e2007290300370300200a2004290300370300200f2009290300370300200120012903a00a3703a009200141f0006a200141a0096a412010c0012002420020121b2001280274410020012802701b10de06200c10350c010b0240024002402020450d00200c201641a0016a360200200141003a00c00a201641206a2107410021050340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141f8056a41086a2205200141a00a6a41086a290300370300200141f8056a41106a2207200141a00a6a41106a290300370300200141f8056a41186a2209200141a00a6a41186a290300370300200120012903a00a22023703a009200120023703f8052016450d0020014198076a41186a200929030037030020014198076a41106a200729030037030020014198076a41086a2005290300370300200120012903f80537039807200c280204200c2802006b41a0016e41286c41286a2205417f4c0d08200510332204450d09200420012903980737030020044201370320200441186a20014198076a41186a290300370300200441106a20014198076a41106a290300370300200441086a20014198076a41086a29030037030041012109200141013602a808200120043602a0082001200541286e22073602a408200c2802002205200c280204460d01200c200541a0016a360200200141003a00c00a200541206a2109410021050340200141003a00d00b200141a00a6a20056a200920056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141a0096a41086a2215200141a00a6a41086a22272903002202370300200141f8056a41186a2203200141a00a6a41186a2220290300370300200141f8056a41106a220d200141a00a6a41106a2224290300370300200141f8056a41086a220e2002370300200120012903a00a22023703a009200120023703f80541012109034020014198076a41186a2003290300220237030020014198076a41106a200d290300220637030020014198076a41086a200e2903002208370300200120012903f805220b37039807200141c8056a41186a220a2002370300200141c8056a41106a220f2006370300200141c8056a41086a221220083703002001200b3703c805024020092007470d00200141a0086a2007200c280204200c2802006b41a0016e41016a108f0120012802a00821040b2004200941286c6a220520012903c80537030020122903002102200f2903002106200a290300210820054201370320200541186a2008370300200541106a2006370300200541086a20023703002001200941016a22093602a8080240200c2802002207200c280204470d0020012802a40821070c030b200c200741a0016a36020041002105200141003a00c00a200741206a21070340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b20152027290300220237030020032020290300370300200d2024290300370300200e2002370300200120012903a00a22023703a009200120023703f80520012802a40821070c000b0b200c10354108210441002109410021070c010b200c10350b200141a00a6a41186a220d4200370300200141a00a6a41106a220e4200370300200141a00a6a41086a220c4200370300200142003703a00a41a8e7cb00ad4280808080f00184100122032900002102200141f8056a41086a2205200341086a290000370300200120023703f80520031035200c2005290300370300200120012903f8053703a00a41d297ca00ad4280808080f000841001220329000021022005200341086a290000370300200120023703f80520031035201020012903f805370000201041086a2005290300370000200141a0096a41086a200c290300370300200141a0096a41106a200e290300370300200141a0096a41186a200d290300370300200120012903a00a3703a009200141a00a6a200141a0096a412010da010240024020012802a00a4101460d00200120093602a80a200120073602a40a200120043602a00a200141f8056a200141a00a6a41004100200110df060c010b2011100720012902a40a2102200120093602a80a200120073602a40a200120043602a00a200141f8056a200141a00a6a2002a741012002422088a710df060b200141a00a6a41186a220c4200370300200141a00a6a41106a22094200370300200141a00a6a41086a22074200370300200142003703a00a41a8e7cb00ad4280808080f001842202100122042900002106200141f8056a41086a2205200441086a290000370300200120063703f8052004103520072005290300370300200120012903f8053703a00a419ce7cb00ad4280808080c0018422061001220429000021082005200441086a290000370300200120083703f80520041035201020012903f805370000201041086a22042005290300370000200141a0096a41086a22032007290300370300200141a0096a41106a220d2009290300370300200141a0096a41186a220e200c290300370300200120012903a00a3703a009200141e0006a200141a0096a10e1022001280260210f20012903682108200c42003703002009420037030020074200370300200142003703a00a20021001220a29000021022005200a41086a290000370300200120023703f805200a103520072005290300370300200120012903f8053703a00a20061001220a29000021022005200a41086a290000370300200120023703f805200a1035201020012903f8053700002004200529030037000020032007290300370300200d2009290300370300200e200c290300370300200120012903a00a3703a0092001200842017c4201200f1b22023703a00a2011201842808080808001841002200c42003703002009420037030020074200370300200142003703a00a41a3edcb00ad4280808080f000841001220a29000021062005200a41086a290000370300200120063703f805200a103520072005290300370300200120012903f8053703a00a41a5ebcb00ad4280808080c001841001220a29000021062005200a41086a290000370300200120063703f805200a1035201020012903f8053700002004200529030037000020032007290300370300200d2009290300370300200e200c290300370300200120012903a00a3703a009200141d8006a200141a0096a412010c0012002200128025c410020012802581b10de060b410810332205450d072005201e36020420052016360200410810332207450d0720072017201441a0016c6a222436020420072017360200200141c00b6a200541dc97ca0010cb05200141d00b6a200741dc97ca0010cb0520012802c80b210420012802c40b211220012802c00b2110200141e00b6a41086a200141d00b6a41086a280200360200200120012903d00b3703e00b20014198076a41186a2207420037030020014198076a41106a220c420037030020014198076a41086a22054200370300200142003703980741a9d1cb00ad4280808080c0008422021001220929000021062005200941086a29000037030020012006370398072009103541add1cb00ad4280808080a001842206100122032900002108200141e8056a41086a2209200341086a290000370300200120083703e80520031035201320012903e805370000201341086a22032009290300370000200141f8056a41086a220d2005290300370300200141f8056a41106a220e200c290300370300200141f8056a41186a220a200729030037030020012001290398073703f805200141c8006a200141f8056a10e10202400240024002402001290350420020012802481b220b42017c2208200b540d0020074200370300200c420037030020054200370300200142003703980720021001220f290000210b2005200f41086a2900003703002001200b37039807200f103520061001220f29000021062009200f41086a290000370300200120063703e805200f1035201320012903e80537000020032009290300370000200d2005290300370300200e200c290300370300200a200729030037030020012001290398073703f805200120083703a00a200141f8056aad4280808080800484220620184280808080800184100220074200370300200c420037030020054200370300200142003703980720021001220f29000021022005200f41086a2900003703002001200237039807200f103541b7d1cb00ad4280808080b001841001220f29000021022009200f41086a290000370300200120023703e805200f1035201320012903e80537000020032009290300370000200d2005290300370300200e200c290300370300200a200729030037030020012001290398073703f805200441286c4104722205417f4c0d08200510332207450d09200141003602a80a200120053602a40a200120073602a00a2004200141a00a6a10770240024020040d0020012802a80a210520012802a00a21040c010b2010200441286c6a210d20012802a40a210c20012802a80a210520102107034002400240200c20056b4120490d0020012802a00a2104200c21090c010b200541206a22092005490d08200c41017422042009200420094b1b22094100480d0802400240200c0d00024020090d00410121040c020b200910332204450d100c010b20012802a00a2104200c2009460d002004200c200910372204450d0f0b200120093602a40a200120043602a00a0b200420056a220c2007290000370000200c41186a200741186a290000370000200c41106a200741106a290000370000200c41086a200741086a2900003700002001200541206a22033602a80a200741206a290300210202400240200920036b4108490d00200541286a21052009210c0c010b200341086a22052003490d082009410174220c2005200c20054b1b220c4100480d080240024020090d000240200c0d00410121040c020b200c10332204450d100c010b2009200c460d0020042009200c10372204450d0f0b2001200c3602a40a200120043602a00a0b200420036a2002370000200120053602a80a200d200741286a2207470d000b0b20012802a40a210720062005ad4220862004ad84100202402007450d00200410350b02402012450d00201241286c450d00201010350b200842017c22022008540d0120014198076a41186a220c420037030020014198076a41106a2209420037030020014198076a41086a22054200370300200142003703980741a9d1cb00ad4280808080c000841001220729000021082005200741086a29000037030020012008370398072007103541e2d1cb00ad4280808080e00184100122072900002108200141e8056a41086a2204200741086a290000370300200120083703e80520071035201320012903e805370000201341086a2004290300370000200141f8056a41086a2005290300370300200141f8056a41106a2009290300370300200141f8056a41186a200c29030037030020012001290398073703f805200141a00a6a200141f8056a10b10220012d00a00a2105200141c8056a41186a2207200141b90a6a290000370300200141c8056a41106a220c200141b10a6a290000370300200141c8056a41086a2209200141a90a6a290000370300200120012900a10a3703c8050240024020054101460d00200141a8056a41186a4200370300200141a8056a41106a4200370300200141a8056a41086a4200370300200142003703a8050c010b200141a8056a41186a2007290300370300200141a8056a41106a200c290300370300200141a8056a41086a2009290300370300200120012903c8053703a8050b20014198076a41186a2207420037030020014198076a41106a220c420037030020014198076a41086a22054200370300200142003703980741a9d1cb00ad4280808080c00084220810012209290000210b2005200941086a2900003703002001200b370398072009103541f0d1cb00ad4280808080c00184220b100122042900002111200141e8056a41086a2209200441086a290000370300200120113703e80520041035201320012903e805370000201341086a22032009290300370000200141f8056a41086a220d2005290300370300200141f8056a41106a220e200c290300370300200141f8056a41186a220a200729030037030020012001290398073703f805200141c0006a200141f8056a412010c0012001280244210f2001280240211220074200370300200c420037030020054200370300200142003703980720081001220429000021082005200441086a290000370300200120083703980720041035200b1001220429000021082009200441086a290000370300200120083703e80520041035201320012903e80537000020032009290300370000200d2005290300370300200e200c290300370300200a200729030037030020012001290398073703f805200141003602a00a200620184280808080c000841002200141a0096a41186a200141a8056a41186a290300370300200141a0096a41106a200141a8056a41106a290300370300200141a0096a41086a200141a8056a41086a290300370300200120012903a8053703a009417f200f410020121b220341016a220520052003491b410d74412872220a417f4c0d08200a1033220d450d09200d20012903a009370000200d2002370020200d41186a200141a0096a41186a290300370000200d41106a200141a0096a41106a290300370000200d41086a200141a0096a41086a2903003700004128210e410021074100210502400340024002402005450d00200c2009470d01200441ffffff3f71450d00200510350b200720034f0d02200141e8056a200710fe03200141a00a6a20012802e805220c20012802f005220910c302024020012802a00a2205450d002009ad422086200cad8410070b20012902a40a420020051b21022005410120051b2105024020012802ec05450d00200c10350b200741016a210720052002422088a74105746a21092002a721042005210c0c010b20014198076a41186a200c41186a220f29000037030020014198076a41106a200c41106a221229000037030020014198076a41086a200c41086a22102900003703002001200c290000370398072010290000210220122900002108200c290000210b200141f8056a41186a2212200f290000370300200141f8056a41106a220f2008370300200141f8056a41086a221020023703002001200b3703f805200141a00a6a41186a22142012290300370300200141a00a6a41106a2212200f290300370300200141a00a6a41086a22152010290300370300200120012903f8053703a00a0240200a200e6b411f4b0d00200e41206a220f200e490d08200a4101742210200f2010200f4b1b220f4100480d0802400240200a0d000240200f0d004101210d0c020b200f1033220d450d100c010b200a200f460d00200d200a200f1037220d450d0f0b200f210a0b200c41206a210c200d200e6a220f20012903a00a370000200f41186a2014290300370000200f41106a2012290300370000200f41086a2015290300370000200e41206a210e0c000b0b200ead422086200dad84100922052900002102200541086a2900002108200541106a290000210b200141c8056a41186a200541186a290000370300200141c8056a41106a200b370300200141c8056a41086a2008370300200120023703c805200510350240200a450d00200d10350b20014198076a41186a220c420037030020014198076a41106a2209420037030020014198076a41086a22054200370300200142003703980741a9d1cb00ad4280808080c0008422021001220729000021082005200741086a29000037030020012008370398072007103541e2d1cb00ad4280808080e00184100122072900002108200141e8056a41086a2204200741086a290000370300200120083703e80520071035201320012903e805370000201341086a2004290300370000200141f8056a41086a2005290300370300200141f8056a41106a2009290300370300200141f8056a41186a200c29030037030020012001290398073703f805412010332205450d09200520012903c805370000200541186a200141c8056a41186a2203290300370000200541106a200141c8056a41106a220d290300370000200541086a200141c8056a41086a220e29030037000020062005ad4280808080800484100220051035200141a0086a41186a200141a8056a41186a2903002208370300200141a0086a41106a200141a8056a41106a290300220b370300200141a0086a41086a200141a8056a41086a2903002211370300200120012903a805221a3703a008200141a00a6a41186a220a2008370300200141a00a6a41106a220f200b370300200141a00a6a41086a221220113703002001201a3703a00a20014198076a41186a220c420037030020014198076a41106a2209420037030020014198076a41086a22074200370300200142003703980720021001220529000021022007200541086a29000037030020012002370398072005103541d8d1cb00ad4280808080a00184100122052900002102200141e8056a41086a2204200541086a290000370300200120023703e80520051035201320012903e805370000201341086a22102004290300370000200141f8056a41086a22142007290300370300200141f8056a41106a22152009290300370300200141f8056a41186a2227200c29030037030020012001290398073703f805412010332205450d09200520012903a00a370000200541186a200a290300370000200541106a200f290300370000200541086a201229030037000020062005ad4280808080800484100220051035200c42003703002009420037030020074200370300200142003703980741a9d1cb00ad4280808080c000841001220529000021022007200541086a29000037030020012002370398072005103541e2d1cb00ad4280808080e001841001220529000021022004200541086a290000370300200120023703e80520051035201320012903e8053700002010200429030037000020142007290300370300201520092903003703002027200c29030037030020012001290398073703f805200141a00a6a200141f8056a10b10220012d00a00a21052003200141b90a6a290000370300200d200141b10a6a290000370300200e200141a90a6a290000370300200120012900a10a3703c8050240024020054101460d00200141b8096a4200370300200141b0096a4200370300200141a8096a4200370300200142003703a0090c010b200141a0096a41186a200141c8056a41186a290300370300200141a0096a41106a200141c8056a41106a290300370300200141a0096a41086a200141c8056a41086a290300370300200120012903c8053703a0090b200141f8056a41086a2205200141e00b6a41086a280200360200200141f8056a41246a200141a0096a41186a290300370200200141f8056a411c6a200141a0096a41106a290300370200200141f8056a41146a200141a0096a41086a290300370200200120012903e00b22023703f805200120012903a00937028406200141cc0a6a200141f8056a41286a280200360200200141a00a6a41246a20014198066a290300370200200141a00a6a411c6a200141f8056a41186a290300370200200141a00a6a41146a200141f8056a41106a290300370200200141a00a6a410c6a2005290300370200200120023702a40a200141003602a00a20014198076a200141a00a6a108104200141d3056a20014198076a41086a28020036000020012001290398073700cb0520014198076a410c6a200141cf056a290000370000200141c28289aa0436009907200141023a009807200120012900c80537009d0720014198076a1082040240200141a00a6a41086a2802002205450d00200541286c450d0020012802a40a10350b41081033220c450d0b200c201e360204200c2016360200410810332227450d0b2027202436020420272017360200200141f8056a41186a4200370300200141f8056a41106a22264200370300200141f8056a41086a22054200370300200142003703f80541d1c4c700ad4280808080e000841001220729000021022005200741086a290000370300200120023703f8052007103541e7c4c700ad4280808080e00084100122072900002102200141e8056a41086a2209200741086a290000370300200120023703e80520071035202620012903e8052202370300200141a0096a41086a2005290300370300200141a0096a41106a2002370300200141a0096a41186a2009290300370300200120012903f8053703a009200141386a200141a0096a412010c00120012802382104200128023c2103200141a00a6a41186a4200370300200141a00a6a41106a22204200370300200141a00a6a41086a22074200370300200142003703a00a4188e8cb00ad42808080808001841001220929000021022005200941086a290000370300200120023703f8052009103520072005290300370300200120012903f8053703a00a4194c4c400ad4280808080e0018410012205290000210220014198076a41086a2209200541086a29000037030020012002370398072005103520202001290398072202370300200141a0086a41086a2007290300370300200141a0086a41106a2002370300200141a0086a41186a2009290300370300200120012903a00a3703a0082001200341e4006a41e40020041b3602a00a200141a0086aad4280808080800484221120184280808080c0008410020240200c2802002205200c280204460d00200c200541a0016a360200200141003a00c00a200541e0006a2107410021050340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141f8056a41086a200141a00a6a41086a290300220237030020014198076a41186a2205200141a00a6a41186a29030037030020014198076a41106a2207200141a00a6a41106a29030037030020014198076a41086a22092002370300200120012903a00a22023703f8052001200237039807200c280204200c2802006b41a0016e41057441206a220410332212450d0a2012200129039807370000201241186a2005290300370000201241106a2007290300370000201241086a200929030037000041012109200141013602a808200120123602a00820012004410576220a3602a408200c2802002205200c280204460d03200c200541a0016a360200200141003a00c00a200541e0006a2107410021050340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141a0096a41086a2210200141a00a6a41086a22132903002202370300200141f8056a41186a2204200141a00a6a41186a2214290300370300200141f8056a41106a2203200141a00a6a41106a2215290300370300200141f8056a41086a220d2002370300200120012903a00a22023703a009200120023703f805410121090340200141a8056a41186a20042903002202370300200141a8056a41106a20032903002206370300200141a8056a41086a200d2903002208370300200120012903f805220b3703a805200141c8056a41186a22072002370300200141c8056a41106a220e2006370300200141c8056a41086a220f20083703002001200b3703c80502402009200a470d00200141a0086a200a200c280204200c2802006b41a0016e41016a108a0120012802a00821120b201220094105746a220520012903c805370000200541186a2007290300370000200541106a200e290300370000200541086a200f2903003700002001200941016a22093602a8080240200c2802002207200c280204470d0020012802a408210a0c050b200c200741a0016a36020041002105200141003a00c00a200741e0006a21070340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b2010201329030022023703002004201429030037030020032015290300370300200d2002370300200120012903a00a22023703a009200120023703f80520012802a408210a0c000b0b200c10354100210a41012112410021090c030b41e6dcc30041c90041b0ddc3001064000b41e6dcc30041c90041c0ddc3001064000b200c10350b200141a00a6a41186a220c4200370300200141a00a6a41106a22044200370300200141a00a6a41086a22054200370300200142003703a00a4188e8cb00ad4280808080800184100122072900002102200141f8056a41086a2203200741086a290000370300200120023703f8052007103520052003290300370300200120012903f8053703a00a418fd1cb00ad4280808080c0008410012207290000210220014198076a41086a2203200741086a2900003703002001200237039807200710352020200129039807370000202041086a2003290300370000200141a0086a41086a2005290300370300200141a0086a41106a2004290300370300200141a0086a41186a200c290300370300200120012903a00a3703a008200941057422034104722205417f4c0d04200510332207450d05200141003602a80a200120053602a40a200120073602a00a2009200141a00a6a10770240024020090d0020012802a80a210720012802a40a210920012802a00a210e0c010b410020012802a80a22076b210420012802a00a210e20012802a40a21092012210d0340200d21050240200920046a411f4b0d00200741206a220c2007490d042009410174220d200c200d200c4b1b220c4100480d04024002400240024020090d000240200c0d004101210e0c020b200c1033210e0c030b2009200c470d010b200c21090c020b200e2009200c1037210e0b200c2109200e450d0a0b200541206a210d200e20076a220c2005290000370000200c41186a200541186a290000370000200c41106a200541106a290000370000200c41086a200541086a290000370000200441606a2104200741206a2107200341606a22030d000b200120093602a40a200120073602a80a2001200e3602a00a0b20112007ad422086200ead84100202402009450d00200e10350b0240200a41ffffff3f71450d00201210350b2027103541081033220c450d07200c201e360204200c201636020041081033221e450d07201e2024360204201e20173602000240024002400240201f450d000240200c2802002205200c280204460d00200c200541a0016a360200200141003a00c00a20054180016a2107410021050340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141f8056a41086a200141a00a6a41086a290300220237030020014198076a41186a2205200141a00a6a41186a29030037030020014198076a41106a2207200141a00a6a41106a29030037030020014198076a41086a22092002370300200120012903a00a22023703f8052001200237039807200c280204200c2802006b41a0016e41057441206a220410332212450d0a2012200129039807370000201241186a2005290300370000201241106a2007290300370000201241086a200929030037000041012109200141013602a808200120123602a00820012004410576220a3602a408200c2802002205200c280204460d02200c200541a0016a360200200141003a00c00a20054180016a2107410021050340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b200141a0096a41086a2210200141a00a6a41086a22132903002202370300200141f8056a41186a2204200141a00a6a41186a2214290300370300200141f8056a41106a2203200141a00a6a41106a2215290300370300200141f8056a41086a220d2002370300200120012903a00a22023703a009200120023703f805410121090340200141a8056a41186a20042903002202370300200141a8056a41106a20032903002206370300200141a8056a41086a200d2903002208370300200120012903f805220b3703a805200141c8056a41186a22072002370300200141c8056a41106a220e2006370300200141c8056a41086a220f20083703002001200b3703c80502402009200a470d00200141a0086a200a200c280204200c2802006b41a0016e41016a108a0120012802a00821120b201220094105746a220520012903c805370000200541186a2007290300370000200541106a200e290300370000200541086a200f2903003700002001200941016a22093602a8080240200c2802002207200c280204470d0020012802a408210a0c040b200c200741a0016a36020041002105200141003a00c00a20074180016a21070340200141003a00d00b200141a00a6a20056a200720056a2d00003a00002001200541016a22053a00c00a20054120470d000b2010201329030022023703002004201429030037030020032015290300370300200d2002370300200120012903a00a22023703a009200120023703f80520012802a408210a0c000b0b200c10354100210a41012112410021090c020b201e1035200c10350c020b200c10350b200141f8056a41186a220c4200370300200141f8056a41106a22044200370300200141f8056a41086a22054200370300200142003703f80541fdd0cb00ad4280808080a002841001220729000021022005200741086a290000370300200120023703f80520071035418fd1cb00ad4280808080c00084100122072900002102200141e8056a41086a2203200741086a290000370300200120023703e80520071035202620012903e805370000202641086a2003290300370000200141a0096a41086a2005290300370300200141a0096a41106a2004290300370300200141a0096a41186a200c290300370300200120012903f8053703a009200941057422034104722205417f4c0d05200510332207450d06200141003602a80a200120053602a40a200120073602a00a2009200141a00a6a10770240024020090d0020012802a80a210720012802a40a210920012802a00a210e0c010b410020012802a80a22076b210420012802a00a210e20012802a40a21092012210d0340200d21050240200920046a411f4b0d00200741206a220c2007490d052009410174220d200c200d200c4b1b220c4100480d05024002400240024020090d000240200c0d004101210e0c020b200c1033210e0c030b2009200c470d010b200c21090c020b200e2009200c1037210e0b200c2109200e450d0b0b200541206a210d200e20076a220c2005290000370000200c41186a200541186a290000370000200c41106a200541106a290000370000200c41086a200541086a290000370000200441606a2104200741206a2107200341606a22030d000b200120093602a40a200120073602a80a2001200e3602a00a0b201b42808080808004842007ad422086200ead84100202402009450d00200e10350b0240200a41ffffff3f71450d00201210350b201e10350b02402028450d00202841a0016c450d00201710350b02402025202345720d00200128029c0541ffffff3f71450d00202310350b0240202241ffffff3f71450d00202110350b42d0e199cd9a3a21022019a72205450d00200541a0016c450d00201610350b20014198076a41186a2203420037030020014198076a41106a2207420037030020014198076a41086a22054200370300200142003703980741f7edcb00ad4280808080f0008422081001220c2900002106200141a00a6a41086a2209200c41086a290000370300200120063703a00a200c103520052009290300370300200120012903a00a3703980741b6aac000ad42808080809002841001220c2900002106200141a0096a41086a2204200c41086a290000370300200120063703a009200c1035200720012903a0092206370300200141f8056a41086a220c2005290300370300200141f8056a41106a220d2006370300200141f8056a41186a220e200429030037030020012001290398073703f805200141306a200141f8056a10f2012001280230417d710d02200342003703002007420037030020054200370300200142003703980720081001220a29000021062009200a41086a290000370300200120063703a00a200a103520052009290300370300200120012903a00a3703980741d9eecb00ad4280808080d002841001220929000021062004200941086a290000370300200120063703a00920091035200720012903a009370000200741086a2004290300370000200c2005290300370300200d2007290300370300200e200329030037030020012001290398073703f8050240200141f8056a10bd02220541ff01714102460d0020054101710d020b20014198076a41186a2209420037030020014198076a41106a2204420037030020014198076a41086a22054200370300200142003703980741f7edcb00ad4280808080f000841001220c2900002106200141a00a6a41086a2203200c41086a290000370300200120063703a00a200c103520052003290300370300200120012903a00a370398074193eecb00ad42808080808001841001220c2900002106200141a0096a41086a2203200c41086a290000370300200120063703a009200c1035200720012903a009370000200741086a2003290300370000200141f8056a41086a2005290300370300200141f8056a41106a2004290300370300200141f8056a41186a200929030037030020012001290398073703f8054100200141f8056a10e5012205200541ff01714104461b41ff01710e0402010201020b103e000b200141c8056a41186a22044200370300200141c8056a41106a220c4200370300200141c8056a41086a22054200370300200142003703c80541a9d1cb00ad4280808080c0008422061001220929000021082005200941086a290000370300200120083703c8052009103541add1cb00ad4280808080a0018410012203290000210820014198076a41086a2209200341086a290000370300200120083703980720031035200c2001290398072208370300200141a0096a41086a220d2005290300370300200141a0096a41106a220e2008370300200141a0096a41186a220a2009290300370300200120012903c8053703a009200141206a200141a0096a10e1022001280220210f2001290328210820044200370300200c420037030020054200370300200142003703c805200610012203290000210b2005200341086a2900003703002001200b3703c8052003103541c2d1cb00ad4280808080b0018410012203290000210b2009200341086a2900003703002001200b3703980720031035200c200129039807220b370300200d2005290300370300200e200b370300200a2009290300370300200120012903c8053703a009200141106a200141a0096a10e1022001290318210b2001280210210320044200370300200c420037030020054200370300200142003703c80520061001220929000021062005200941086a290000370300200120063703c8052009103541cdd1cb00ad4280808080b00184100122092900002106200141f8056a41086a2204200941086a290000370300200120063703f80520091035200c20012903f8052206370300200141a8056a41086a2005290300370300200141a8056a41106a2006370300200141a8056a41186a2004290300370300200120012903c8053703a8052001200141a8056a10e102427f200b420020031b200842c8017e4200200f1b7c220642c8017c220820082006541b22062001290308420020012802001b7d22082006560d00417f20002008a7417f2008428080808010541b6a220520052000491b220520006b220c20054b0d00200c417f6a41314b0d0041f7edcb00ad4280808080f00084100122052900002106200141a00a6a41086a220c200541086a290000370300200120063703a00a2005103541f393ca00ad4280808080a00184100122052900002106200141a0096a41086a2209200541086a290000370300200120063703a00920051035412010332205450d02200520012903a00a370000200520012903a009370010200541086a200c290300370000200541186a2204200929030037000041201033220c450d02200c2005290000370000200c41186a2004290000370000200c41106a200541106a290000370000200c41086a200541086a290000370000200141a8056a41026a2209200141a00a6a41026a2d00003a0000200120012f00a00a3b01a80520014198076a41106a42a08080808004370300200141003a00b007200120053602a407200142a0808080800437029c072001200c36029807200141b3076a20092d00003a0000200120012f01a8053b00b107200141a00a6a20014198076a10c7010240024020012802a00a4101470d00200141c8056a41186a2205200141bc0a6a290200370300200141c8056a41106a200141b40a6a290200370300200141c8056a41086a200141ac0a6a290200370300200120012902a40a3703c805412010332203450d04200320012903c805370000200341186a2005290300370000200341106a200141c8056a41106a220d290300370000200341086a200141c8056a41086a220e29030037000020014281808080103702a408200120033602a008200141f8056a41186a20014198076a41186a280200360200200141f8056a41106a20014198076a41106a290300370300200141f8056a41086a20014198076a41086a29030037030020012001290398073703f805200141a00a6a200141f8056a10c70141012109024020012802a00a4101470d00200141a00a6a410472210541022109412021044101210c0340200141a0096a41186a200541186a2902002206370300200141a0096a41106a200541106a2902002208370300200141a0096a41086a200541086a290200220b3703002001200529020022183703a009200141c8056a41186a220a2006370300200d2008370300200e200b370300200120183703c80502402009417f6a200c470d00200141a0086a200c4101108a0120012802a00821030b200320046a220c20012903c805370000200c41186a200a290300370000200c41106a200d290300370000200c41086a200e290300370000200120093602a808200141a00a6a200141f8056a10c70120012802a00a4101470d01200441206a2104200941016a210920012802a408210c0c000b0b024020012802fc05450d0020012802f80510350b024020014188066a280200450d0020012802840610350b20012802a40841ffffff3f7121130c010b0240200128029c07450d0020012802980710350b4100211341012103024020012802a807450d0020012802a40710350b410021090b41f7edcb00ad4280808080f00084100122052900002106200141a00a6a41086a220c200541086a290000370300200120063703a00a2005103541cca9c000ad4280808080a00184100122052900002106200141a0096a41086a2204200541086a290000370300200120063703a00920051035412010332205450d02200520012903a00a370000200520012903a009370010200541086a200c290300370000200541186a220d200429030037000041201033220c450d02200c2005290000370000200c41186a200d290000370000200c41106a200541106a290000370000200c41086a200541086a290000370000200141e8056a41026a2204200141a00a6a41026a2d00003a0000200120012f00a00a3b01e80520014198076a41106a42a08080808004370300200141003a00b007200120053602a407200142a0808080800437029c072001200c36029807200141b3076a20042d00003a0000200120012f01e8053b00b107200141a00a6a20014198076a10c9050240024020012d00d00a4102460d00200141c8056a41186a200141a00a6a41186a290300370300200141c8056a41106a200141a00a6a41106a290300370300200141c8056a41086a200141a00a6a41086a290300370300200120012903a00a3703c805024020012802c40a41ffffff3f71450d0020012802c00a10350b412010332210450d04201020012903c805370000201041186a200141c8056a41186a220d290300370000201041106a200141c8056a41106a220e290300370000201041086a200141c8056a41086a220a29030037000020014281808080103702a408200120103602a008200141f8056a41186a20014198076a41186a280200360200200141f8056a41106a20014198076a41106a290300370300200141f8056a41086a20014198076a41086a29030037030020012001290398073703f805200141a00a6a200141f8056a10c905024020012d00d00a4102460d00412021044101210c0340200141a0096a41186a2205200141a00a6a41186a290300370300200141a0096a41106a220f200141a00a6a41106a290300370300200141a0096a41086a2212200141a00a6a41086a290300370300200120012903a00a3703a009024020012802c40a41ffffff3f71450d0020012802c00a10350b200d2005290300370300200e200f290300370300200a2012290300370300200120012903a0093703c8050240200c20012802a408470d00200141a0086a200c4101108a0120012802a00821100b201020046a220520012903c805370000200541186a200d290300370000200541106a200e290300370000200541086a200a2903003700002001200c41016a220c3602a808200441206a2104200141a00a6a200141f8056a10c90520012d00d00a4102470d000b0b024020012802fc05450d0020012802f80510350b024020014188066a280200450d0020012802840610350b200141a8056a41086a200141a0086a41086a280200360200200120012903a0083703a8050c010b200141003602b005200142013703a8050240200128029c07450d0020012802980710350b20012802a807450d0020012802a40710350b0240200941808004490d00024020012802ac0541ffffff3f71450d0020012802a80510350b2013450d01200310350c010b20094105742205417f4c0d010240024020090d00200141003602a80a200142013703a00a200141a00a6a41004100108a0120012802a80a210c20012802a00a210d0c010b200510332205450d03200141003602a80a200120093602a40a200120053602a00a200141a00a6a41002009108a012009410574210420012802a00a220d20012802a80a220e4105746a21052003210c03402005200c290000370000200541186a200c41186a290000370000200541106a200c41106a290000370000200541086a200c41086a290000370000200541206a2105200c41206a210c200441606a22040d000b2001200941057441606a410576200e6a41016a220c3602a80a0b20012802a40a2105200141a8056a20012802b005200c410574220c4105752204108a0120012802a805220f20012802b005220e4105746a200d200c109d081a2001200e20046a22123602b0050240200541ffffff3f71450d00200d10350b20014198076a41186a220c420037030020014198076a41106a2204420037030020014198076a41086a22054200370300200142003703980741f7edcb00ad4280808080f0008422061001220e2900002108200141a00a6a41086a220d200e41086a290000370300200120083703a00a200e10352005200d290300370300200120012903a00a370398074192aac000ad4280808080a002841001220a2900002108200141a0096a41086a220e200a41086a290000370300200120083703a009200a1035200720012903a009370000200741086a220a200e290300370000200141f8056a41086a22102005290300370300200141f8056a41106a22142004290300370300200141f8056a41186a2215200c29030037030020012001290398073703f805200141203602a40a2001200141f8056a3602a00a20032009200141a00a6a10980202402013450d00200310350b20012802ac052103200c4200370300200442003703002005420037030020014200370398072006100122092900002106200d200941086a290000370300200120063703a00a200910352005200d290300370300200120012903a00a3703980741a4aac000ad4280808080a00284100122092900002106200e200941086a290000370300200120063703a00920091035200720012903a009370000200a200e29030037000020102005290300370300201420042903003703002015200c29030037030020012001290398073703f805200141203602a40a2001200141f8056a3602a00a200f2012200141a00a6a1098020240200341ffffff3f71450d00200f10350b20014198076a41186a2209420037030020014198076a41106a2204420037030020014198076a41086a22054200370300200142003703980741f7edcb00ad4280808080f000841001220c2900002106200141a00a6a41086a2203200c41086a290000370300200120063703a00a200c103520052003290300370300200120012903a00a3703980741b6aac000ad42808080809002841001220c2900002106200141a0096a41086a2203200c41086a290000370300200120063703a009200c1035200720012903a009370000200741086a2003290300370000200141f8056a41086a2005290300370300200141f8056a41106a2004290300370300200141f8056a41186a200929030037030020012001290398073703f805410110332205450d04200541013a000020054101410510372205450d0420052000360001200141f8056aad42808080808004842005ad4280808080d000841002200510350b02400240200041044b0d00200141a8056a21030c010b200141c8056a41186a4200370300200141c8056a41106a220c4200370300200141c8056a41086a22054200370300200142003703c8054193d1cb00ad4280808080a001841001220729000021062005200741086a290000370300200120063703c8052007103541e0caca00ad4280808080e0008410012207290000210620014198076a41086a2209200741086a290000370300200120063703980720071035200c2001290398072206370300200141a0096a41086a2005290300370300200141a0096a41106a2006370300200141a0096a41186a2009290300370300200120012903c8053703a009200141a00a6a200141a0096a10b60220012802a00a2205410420051b210d0240024020012902a40a420020051b2206422088a7220941c4006c22050d00410021040c010b2000417b6a210c200d20056a210741002104200d210502400340024020052d00004101460d00200541046a280200200c4f0d020b200441016a21042007200541c4006a2205470d000b0b200420094b0d040b200920046b210e200642ffffffff0f832106200d200441c4006c22076a2103200d210c02400340024020070d00200321050c020b200741bc7f6a2107200c2d00002109200c41c4006a2205210c20094102470d000b0b0240034020032005460d0120052d00002107200541c4006a210520074102470d000b0b0240200e450d0002402004450d00200d200d200441c4006c6a200e41c4006c109e081a0b200ead42208620068421060b200141c8056a41186a4200370300200141c8056a41106a220c4200370300200141c8056a41086a22054200370300200142003703c8054193d1cb00ad4280808080a00184100122072900002108200141e8056a41086a2209200741086a290000370300200120083703e8052007103520052009290300370300200120012903e8053703c80541e0caca00ad4280808080e00084100122072900002108200141f8056a41086a2209200741086a290000370300200120083703f80520071035200c20012903f8052208370300200141a8056a41086a2005290300370300200141a8056a41106a2008370300200141a8056a41186a2009290300370300200120012903c8053703a805200141a00a6a200d2006422088a710e006200141a8056aad428080808080048420013502a80a42208620012802a00a2207ad8410022006a72105024020012802a40a450d00200710350b200141a8056a21032005450d00200541c4006c450d00200d10350b200141c8056a41186a22044200370300200141c8056a41106a220c4200370300200141c8056a41086a22074200370300200142003703c8054193d1cb00ad4280808080a00184100122052900002106200141e8056a41086a2209200541086a290000370300200120063703e8052005103520072009290300370300200120012903e8053703c805419dd1cb00ad4280808080c00184100122052900002106200141f8056a41086a2209200541086a290000370300200120063703f80520051035200c20012903f8052206370300200141a8056a41086a2007290300370300200141a8056a41106a2006370300200141a8056a41186a2009290300370300200120012903c8053703a805200141003a00d00b2003ad4280808080800484200141d00b6aad428080808010841002200141f8056a10d0042004200141f8056a41186a2203290300370300200c200141f8056a41106a220d29030037030020072009290300370300200120012903f8053703c805412410332205450d03200520012903c80537000020054114360220200541186a2004290300370000200541106a200c290300370000200541086a200729030037000020014281808080103702a40a200120053602a00a200141a00a6a10ab01200141a00a6a41186a2003290300370300200141a00a6a41106a200d290300370300200141a00a6a41086a2009290300370300200120012903f8053703a00a200141a00a6a10d30410ff03200141f00b6a240020020f0b1044000b1045000b20042009104f000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541f0bbc800ad4280808080f00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541cebbc800ad4280808080800284100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541c7bbc800ad4280808080f00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b130020004103360204200041ccbcc8003602000b3400200041d5c3c80036020420004100360200200041146a4101360200200041106a41dcc3c800360200200041086a42043702000b910101057f230041206b22022400200241186a22034200370300200241106a22044200370300200241086a220542003703002002420037030002404120103322060d001045000b20062002290300370000200042a0808080800437020420002006360200200641186a2003290300370000200641106a2004290300370000200641086a2005290300370000200241206a24000b13002000410c36020420004180c7c8003602000b3400200041a29bc80036020420004100360200200041146a4110360200200041106a4180a3c900360200200041086a42073702000b130020004107360204200041c8b8c9003602000b3501017f02404108103322020d001045000b20004288808080800137020420002002360200200242f0f2bd99f7edd8b4e5003700000b2e01017f02404104103322020d001045000b20004284808080c0003702042000200236020020024180ee053600000b3b01017f02404110103322020d001045000b20024200370008200242808094f6c2d7e8d800370000200042908080808002370204200020023602000b2c01017f02404104103322020d001045000b20004284808080c000370204200020023602002002410a3600000b13002000410836020420004188c2c9003602000b340020004186f0cb0036020420004100360200200041146a4105360200200041106a41a0ebc900360200200041086a42083702000b130020004109360204200041e0f4c9003602000b3501017f02404108103322020d001045000b20004288808080800137020420002002360200200242f0f2bda1a7ee9cb9f9003700000b2b01017f02404101103322020d001045000b200042818080801037020420002002360200200241143a00000b2e01017f02404104103322020d001045000b20004284808080c0003702042000200236020020024180e1013600000b2e01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241a0c21e3600000b2e01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241d086033600000b900a030a7f027e017f230041106b220224002002410036020820024201370300024002400240412010332203450d002003200029004c370000200341186a2204200041e4006a290000370000200341106a2205200041dc006a290000370000200341086a2206200041d4006a290000370000412010332207450d02200241203602042002200736020020072003290000370000200741086a2006290000370000200741106a2005290000370000200741186a200429000037000020024120360208200310352007412041c00010372203450d022003200029006c370020200341286a200041f4006a290000370000200341306a200041fc006a290000370000200341386a20004184016a29000037000020022003360200200242c080808080083702040240024020002903004201510d00200341c00041800110372203450d04200341003a004020024180013602042002200336020041c10021070c010b200341c00041800110372203450d03200341013a00402003200041086a2207290000370041200341e9006a200041306a2903003700002003200041286a290300370061200341c9006a200741086a290000370000200341d1006a200741106a290000370000200341d9006a200741186a2900003700002002200336020020024280818080900c37020441f10021070b200220073602080240024020002802384101460d00200320076a41003a0000200741016a21030c010b200320076a41013a00002002200741016a22033602082000413c6a2802002106024002402002280204220520036b4104490d00200228020021040c010b41000d0320054101742204200341046a2208200420084b1b22084100480d030240024020050d002008103322040d010c060b2002280200210420052008460d0020042005200810372204450d050b20022008360204200220043602000b200420036a2006360000200741056a21030b2002200336020820002802402109200041c8006a2802002200200210770240024020000d002002280208210020022802042107200228020021050c010b2009200041306c6a210a41002002280208220b6b210620022802042107410021030340200b20036a210802400240200720066a4120490d0020022802002105200721040c010b200841206a22002008490d04200741017422042000200420004b1b22044100480d040240024020070d00024020040d00410121050c020b200410332205450d070c010b2002280200210520072004460d0020052007200410372205450d060b20022004360204200220053602000b2005200b6a20036a2207200920036a2200290000370000200741186a200041186a290000370000200741106a200041106a290000370000200741086a200041086a2900003700002002200841206a2207360208200041286a290300210c200041206a290300210d02400240200420066a41606a410f4d0d00200421070c010b200741106a220e2007490d0420044101742207200e2007200e4b1b22074100480d040240024020040d00024020070d00410121050c020b200710332205450d070c010b20042007460d0020052004200710372205450d060b20022007360204200220053602000b2005200b6a20036a220441286a200c370000200441206a200d3700002002200841306a360208200641506a2106200341306a2103200a200041306a470d000b200b20036a21000b20012902002000ad4220862005ad84100202402007450d00200510350b200241106a24000f0b1045000b103e000b103c000b990907027f027e017f017e027f047e047f230041306b2203240002400240024002400240024020002802002d0000200141ff0171460d0020002802082104200341206a200210b806200341106a20032802202201200328022810b4024200210520032902144200200328021022001b210602402003280224450d00200110350b2000410820001b2107428080d287e2bc2d210802402006422088a72209450d0002400240200941186c22000d0042002105428080d287e2bc2d2108410021010c010b200720006a210a4200210b428080d287e2bc2d210c4100210120072100024003400240200c200041086a290300220d7d2208200c56200b200041106a290300220e7d200c200d54ad7d2205200b562005200b511b450d00200041086a200d200c7d370300200041106a200e200b7d200d200c54ad7d37030042002108420021050c020b200141016a21012008210c2005210b200a200041186a2200470d000b0b200120094b0d030b200341106a200210b806200920016b220a41186c4104722200417f4c0d032003350218210d2003280210210f200010332210450d04200341003602282003200036022420032010360220200a200341206a10770240024020012009470d002003280228210020032802242101200328022021090c010b2007200141186c6a21102007200941186c6a2111200328022421012003280228210003402010280200211202400240200120006b4104490d00200328022021092001210a0c010b200041046a220a2000490d0820014101742209200a2009200a4b1b220a4100480d080240024020010d000240200a0d00410121090c020b200a103322090d010c0b0b200328022021092001200a460d0020092001200a10372209450d0a0b2003200a360224200320093602200b200920006a20123600002003200041046a2212360228201041106a290300210c201041086a290300210b02400240200a20126b4110490d00200041146a2100200a21010c010b201241106a22002012490d08200a41017422012000200120004b1b22014100480d0802400240200a0d00024020010d00410121090c020b200110332209450d0b0c010b200a2001460d002009200a200110372209450d0a0b20032001360224200320093602200b200920126a220a200c370008200a200b37000020032000360228201041186a22102011470d000b0b200d422086200fad842000ad4220862009ad84100202402001450d00200910350b2003280214450d00200f10350b2008428080d287e2bc2d56ad210c02402006a72200450d00200041186c450d00200710350b2005200c7c210b200341206a200210ba06200341086a200328022022002003280228220110c0012003200328020c41016a410120032802081b220a3602102001ad4220862000ad84200341106aad4280808080c00084100202402003280224450d00200010350b428080d287e2bc2d20087d210c4200200b7d210b0240200a410a490d00200210b4060b2004200c20042903007c2205370300200441086a2200200b20002903007c2005200c54ad7c370300410021020b200341306a240020020f0b2001200941ac82ca001059000b1044000b1045000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541e0aec900ad4280808080b00284100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041a29bc800ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541acb0c900ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b802304057f017e037f037e230041c0036b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802000e1c00011302030405060708090a0b0c0d0e0f1011121313131415161713000b20024180016a200141086a109d0320004100360200200041106a20024180016a41086a290300370300200041086a2002290380013703000c170b20024180016a200141046a109a03200041013602002000413c6a200241b8016a280200360200200041346a200241b0016a2903003702002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c160b20004103360200200041086a200141086a2903003703000c150b20024180016a200141046a109e03200041043602002000410c6a20024188016a28020036020020002002290380013702040c140b02400240024002400240024020012d0004417f6a220341034b0d00200141046a210420030e0401020304010b41cfa2cc00412841c086cc00103f000b200141086a2802002103410121050c030b41022105200241026a200441036a2d00003a000020024180016a41086a200141146a29020037030020024190016a2001411c6a29020037030020024198016a200141246a2d00003a0000200220042f00013b010020022001410c6a29020037038001200141086a2802002103200141286a28020021010c020b200141086a2802002103410321050c010b200241026a200441036a2d00003a000020024180016a41086a200141146a29020037030020024190016a2001411c6a29020037030020024198016a200141246a2d00003a0000200220042f00013b010020022001410c6a29020037038001200141086a2802002103200141286a2802002101410421050b200020053a0004200020022f01003b000520004105360200200041086a20033602002000410c6a200229038001370200200041286a2001360200200041076a200241026a2d00003a0000200041146a20024180016a41086a2903003702002000411c6a20024190016a290300370200200041246a20024198016a2802003602000c130b20024180016a200141086a108503200041086a20024180016a41e000109d081a200041063602000c120b20024180016a200141086a108702200041086a20024180016a418802109d081a200041073602000c110b02400240200128020422060d00410021030c010b20024180016a41186a200141286a29000037030020024180016a41106a200141206a29000037030020024188016a200141186a29000037030020024180016a41286a200141386a29000037030020024180016a41306a200141c0006a29000037030020024180016a41386a200141c8006a29000037030020024180016a41c8006a200141d8006a29000037030020024180016a41d0006a200141e0006a29000037030020024180016a41d8006a200141e8006a2900003703002002200141106a290000370380012002200141306a2900003703a0012002200141d0006a2900003703c00120024180016a41f8006a20014188016a29000037030020024180016a41f0006a20014180016a29000037030020024180016a41e8006a200141f8006a2900003703002002200141f0006a2900003703e0012001410c6a2802002201417f4c0d120240024020010d0041002105410121030c010b200110332203450d14200121050b0240024020052001490d00200521040c010b200541017422042001200420014b1b22044100480d15024020050d002004103322030d010c170b20052004460d0020032005200410372203450d160b200320062001109d081a200220024180016a418001109d081a2001ad4220862004ad8421070b20002003360204200041086a2007370200200041106a2002418001109d081a200041083602000c100b20024180016a200141086a10a00320004109360200200041386a20024180016a41306a290300370300200041306a20024180016a41286a290300370300200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c0f0b20024180016a200141046a10a1032000410a3602002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c0e0b20024180016a200141046a10a1032000410b3602002000412c6a200241a8016a290300370200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c0d0b20024180016a200141086a1086032000410c360200200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c0c0b0240024002400240024002400240024020012d0004417f6a220441064b0d00200141046a21034107210520040e0701020304050607010b41cfa2cc00412841c086cc00103f000b20024198016a200341196a29000037030020024190016a200341116a29000037030020024188016a200341096a2900003703002002200329000137038001410121050c050b20024198016a200341196a29000037030020024190016a200341116a29000037030020024188016a200341096a2900003703002002200329000137038001410221050c040b20024180016a41186a200341196a29000037030020024180016a41106a200341116a29000037030020024180016a41086a200341096a290000370300200241086a200341296a290000370300200241106a200341316a290000370300200241186a200341396a29000037030020022003290001370380012002200341216a290000370300410321050c030b200141106a280200220841ffffff3f712008470d0f20084105742203417f4c0d0f200141086a28020021040240024020030d00410121050c010b200310332205450d110b41002101200241003602082002200536020020022003410576360204200241002008108a012002280208210902402008450d0020084105742106200228020020094105746a210a0340200a20016a2203200420016a2205290000370000200341186a200541186a290000370000200341106a200541106a290000370000200341086a200541086a2900003700002006200141206a2201470d000b200841057441606a41057620096a41016a21090b2002418b016a20093600002002200229030037008301410421050c020b20024198016a200341196a29000037030020024190016a200341116a29000037030020024188016a200341096a2900003703002002200329000137038001410521050c010b20024198016a200341196a29000037030020024190016a200341116a29000037030020024188016a200341096a2900003703002002200329000137038001410621050b200020053a0004200020022903800137000520002002290300370025200020022f00bc033b00452000410d6a20024180016a41086a290300370000200041156a20024180016a41106a2903003700002000411d6a20024180016a41186a2903003700002000412d6a200241086a290300370000200041356a200241106a2903003700002000413d6a200241186a290300370000200041c7006a200241be036a2d00003a00002000410d3602000c0b0b2000410e360200200020012802043602040c0a0b2001410c6a2802002203417f4c0d0a200128020421060240024020030d0041002101410121040c010b200310332204450d0c200321010b0240024020012003490d00200121050c010b200141017422052003200520034b1b22054100480d0d024020010d00200510332204450d0f0c010b20012005460d0020042001200510372204450d0e0b200420062003109d0821012000410c6a2003360200200041086a2005360200200020013602042000410f3602000c090b20024180016a200141086a10a30320004110360200200041c0006a20024180016a41386a290300370300200041386a20024180016a41306a290300370300200041306a20024180016a41286a290300370300200041286a20024180016a41206a290300370300200041206a20024180016a41186a290300370300200041186a20024180016a41106a290300370300200041106a20024180016a41086a290300370300200041086a2002290380013703000c080b20024180016a200141086a10a403200041086a20024180016a419801109d081a200041113602000c070b20024180016a200141046a10a503200041123602002000412c6a200241a8016a280200360200200041246a200241a0016a2903003702002000411c6a20024198016a290300370200200041146a20024190016a2903003702002000410c6a20024188016a29030037020020002002290380013702040c060b20024180016a200141046a10de04200041046a20024180016a41e800109d081a200041133602000c050b10a703000b20024180016a200141086a10a803200041086a20024180016a41a802109d081a200041173602000c030b20024180016a200141086a10a903200041086a20024180016a41c800109d081a200041183602000c020b20024180016a200141046a10aa03200041046a20024180016a41c400109d081a200041193602000c010b0240024002400240200141086a280200417f6a220a41024b0d0041012105200a0e03030102030b41cfa2cc00412841c086cc00103f000b41012103024002402001410c6a22052d00004101470d00200141106a28020021060c010b200241be036a200541036a2d00003a000020024188016a2001411c6a29020037030020024180016a41106a200141246a29020037030020024198016a2001412c6a2d00003a0000200220052f00013b01bc032002200141146a29020037038001200141106a2802002106410021030b41022105200241ac036a41026a200241bc036a41026a2d00003a0000200241086a20024180016a41086a290300370300200241106a20024180016a41106a290300370300200241186a20024180016a41186a280200360200200220022f01bc033b01ac0320022002290380013703000c010b41012103024002402001410c6a22052d00004101470d00200141106a28020021060c010b200241be036a200541036a2d00003a000020024188016a2001411c6a29020037030020024180016a41106a200141246a29020037030020024198016a2001412c6a2d00003a0000200220052f00013b01bc032002200141146a29020037038001200141106a2802002106410021030b200241ac036a41026a200241bc036a41026a2d00003a0000200241086a20024180016a41086a290300370300200241106a20024180016a41106a290300370300200241186a20024180016a41186a280200360200200220022f01bc033b01ac032002200229038001370300200141c8006a290300210b200141c0006a2903002107200141386a290300210c200141d0006a28020021042001290330210d410321050b200020022f01ac033b000d200041c8006a200b370300200041c0006a2007370300200041386a200c370300200041306a200d3703002000410c6a20033a0000200041086a2005360200200041106a2006360200200041146a2002290300370200200041d0006a20043602002000410f6a200241ae036a2d00003a00002000411c6a200241086a290300370200200041246a200241106a2903003702002000412c6a200241186a2802003602002000411a3602000b200241c0036a24000f0b1044000b1045000b103e000b103c000b9f0303027f017e027f230041206b220224004186f0cb00ad4280808080800184100122032900002104200241086a200341086a290000370300200220043703002003103541c0f0c900ad4280808080f00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000bb10503027f017e047f230041d0006b220224004186f0cb00ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541d8efc900ad4280808080c00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b220224004186f0cb00ad4280808080800184100122032900002104200241086a41086a200341086a290000370300200220043703082003103541d8efc900ad4280808080c00084100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b1300200041013602042000419083ca003602000bb31903077f027e067f230041a0026b22052400200028020021064100210702400240024002400240024002400240200041086a280200220841014b0d0020080e020201020b20082109034020072009410176220a20076a220b2006200b41e8006c6a220b41386a290300200256200b41c0006a290300220c200356200c2003511b1b21072009200a6b220941014b0d000b0b2006200741e8006c6a220941386a290300220d200285200941c0006a290300220c20038584500d012007200d200254200c200354200c2003511b6a21070b200541a0016a41086a200441086a290300370300200541a0016a41106a200441106a290300370300200541a0016a41186a200441186a290300370300200541a0016a41206a200441206a290300370300200541a0016a41286a200441286a290300370300200541a0016a41306a200441306a290300370300200541286a41086a200141086a290000370300200541286a41106a200141106a290000370300200541286a41186a200141186a290000370300200520042903003703a0012005200129000037032820082007490d0302402008200041046a280200470d00200020084101109601200028020021060b2006200741e8006c6a220941e8006a2009200820076b41e8006c109e081a200941c0006a200337030020092002370338200941306a200541a0016a41306a290300370300200941286a200541a0016a41286a290300370300200941206a200541a0016a41206a290300370300200941186a200541a0016a41186a290300370300200941106a200541a0016a41106a290300370300200941086a200541a0016a41086a290300370300200920052903a00137030020092005290328370348200941d0006a200541286a41086a290300370300200941d8006a200541286a41106a290300370300200941e0006a200541286a41186a290300370300200041086a200841016a22093602000c010b0240024002400240024020070d002006210a0c010b20082007417f6a22094d0d012006200941e8006c6a41e8006a210a0b200a2006200841e8006c6a460d00200820074d0d04200a290338200256200a41c0006a290300220c200356200c2003511b0d01200a41e8006a2109200841e8006c20066a200a6b41987f6a210a0340200a450d01200741016a21072009290338210c200941c0006a210b200a41987f6a210a200941e8006a2109200c200256200b290300220c200356200c2003511b0d020c000b0b200541286a41186a2209200141186a290000370300200541286a41106a220a200141106a290000370300200541286a41086a220b200141086a290000370300200541a0016a41086a220e200441086a290300370300200541a0016a41106a220f200441106a290300370300200541a0016a41186a2210200441186a290300370300200541a0016a41206a2211200441206a290300370300200541a0016a41286a2212200441286a290300370300200541a0016a41306a2213200441306a29030037030020052001290000370328200520042903003703a00102402008200041046a280200470d00200020084101109601200041086a2802002108200028020021060b2006200841e8006c6a22072002370338200720052903a00137030020072005290328370348200741c0006a2003370300200741306a2013290300370300200741286a2012290300370300200741206a2011290300370300200741186a2010290300370300200741106a200f290300370300200741086a200e290300370300200741d0006a200b290300370300200741d8006a200a290300370300200741e0006a20092903003703000c010b200541a0016a41086a200441086a290300370300200541a0016a41106a200441106a290300370300200541a0016a41186a200441186a290300370300200541a0016a41206a200441206a290300370300200541a0016a41286a200441286a290300370300200541a0016a41306a200441306a290300370300200541286a41086a200141086a290000370300200541286a41106a200141106a290000370300200541286a41186a200141186a290000370300200520042903003703a0012005200129000037032820082007490d0302402008200041046a280200470d00200020084101109601200028020021060b2006200741e8006c6a220941e8006a2009200820076b41e8006c109e081a200941c0006a200337030020092002370338200941306a200541a0016a41306a290300370300200941286a200541a0016a41286a290300370300200941206a200541a0016a41206a290300370300200941186a200541a0016a41186a290300370300200941106a200541a0016a41106a290300370300200941086a200541a0016a41086a290300370300200920052903a00137030020092005290328370348200941d0006a200541286a41086a290300370300200941d8006a200541286a41106a290300370300200941e0006a200541286a41186a2903003703000b200041086a200841016a22093602000b0240200941e907490d00200041086a2009417f6a22093602002006200941e8006c6a220741106a2903002103200741086a290300210c20072d0000210a20072800012101200741046a280000210e20054180016a41186a220b200741306a29030037030020054180016a41106a2204200741286a29030037030020054180016a41086a2208200741206a290300370300200741186a2903002102200541a0016a41286a220f200741e0006a290300370300200541a0016a41206a2210200741d8006a2903003703002005200237038001200541a0016a41186a2211200741d0006a290300370300200541a0016a41106a2212200741c8006a290300370300200541a0016a41086a2213200741c0006a2903003703002005200e36000320052001360200200520072903383703a001200a4102460d03200541d8006a41086a22072008290300370300200541d8006a41106a22012004290300370300200541d8006a41186a220e200b290300370300200541286a41086a2013290300370300200541286a41106a22132012290300370300200541286a41186a22122011290300370300200541286a41206a22112010290300370300200541286a41286a2210200f2903003703002005200528000336007b200520052802003602782005200529038001370358200520052903a001370328200541186a2010290300370300200541106a2011290300370300200541086a201229030037030020052013290300370300200520052802783602202005200528007b3600232008200729030037030020042001290300370300200b200e290300370300200520052903583703800102400240200a410171450d00200541af016a2003370000200541bf016a20054188016a2d00003a00002005200c3700a701200520052800233600a301200520052802203602a00120052005290380013700b701200541286a200541a0016a10d006200535023042208620052802282207ad841007200528022c450d01200710350c010b2005200c37035820052003370360200c200384500d0020052005360278200541286a2005200541d8006a200541f8006a10f00220052903284201520d0020052903302103200541d8016a200541286a41106a290300370300200541d0016a2003370300200541a0016a41086a41003a0000200541a9016a2005290300370000200541b1016a200541086a290300370000200541b9016a200541106a290300370000200541c1016a200541186a290300370000200541033a00a00141b0b4cc004100200541a0016a10d4010b200541a0016a41086a41033a0000200541a9016a2005290300370000200541b1016a200541086a290300370000200541b9016a200541106a290300370000200541c1016a200541186a290300370000200541123a00a00141b0b4cc004100200541a0016a10d4010b2000280204210b200541a0016a41186a4200370300200541a0016a41106a22044200370300200541a0016a41086a22074200370300200542003703a00141a29bc800ad4280808080f000841001220a29000021032007200a41086a290000370300200520033703a001200a1035419cbac800ad4280808080c000841001220a290000210320054180016a41086a2200200a41086a2900003703002005200337038001200a103520042005290380012203370300200541286a41086a2007290300370300200541286a41106a2003370300200541286a41186a2000290300370300200520052903a001370328200541a0016a2006200910b106200541286aad428080808080048420053502a80142208620052802a0012207ad841002024020052802a401450d00200710350b0240200b450d00200b41e8006c450d00200610350b200541a0026a24000f0b2007200841f483ca001042000b20072008104d000b418484ca004113419884ca001064000b810b031d7f017e017f230041b0016b2202240041012103024020012d00000d002001411d6a2d000021042001411c6a2d000021052001411a6a2f00002106200141196a2d00002107200141186a2d00002108200141166a2f00002109200141156a2d0000210a200141146a2d0000210b200141126a2f0000210c200141116a2d0000210d200141106a2d0000210e2001410e6a2f0000210f2001410d6a2d000021102001410c6a2d000021112001410a6a2f00002112200141096a2d00002113200141086a2d00002114200141066a2f00002115200141056a2d00002116200141046a2d00002117200141026a2f0000211820012d00012103200141206a2d00002119200141216a2d0000211a2001411e6a2f0000211b20024190016a41186a221c420037030020024190016a41106a221d420037030020024190016a41086a22014200370300200242003703900141a29bc800ad4280808080f000841001221e290000211f2001201e41086a2900003703002002201f37039001201e103541ef9bc800ad4280808080f000841001221e290000211f200241c8006a41086a2220201e41086a2900003703002002201f370348201e1035201d2002290348221f370300200241f0006a41086a2001290300370300200241f0006a41106a201f370300200241f0006a41186a20202903003703002002200229039001370370200241c8006a200241f0006a412010d50120022d0048211e201c200241c8006a41196a290000370300201d200241c8006a41116a2900003703002001200241c8006a41096a2900003703002002200229004937039001410021010240201e4101470d00200241f0006a41186a20024190016a41186a290300370300200241f0006a41106a20024190016a41106a290300370300200241f0006a41086a20024190016a41086a2903003703002002200229039001370370410121010b200241206a201a3a00002002411f6a20193a00002002411d6a201b3b00002002411c6a20043a00002002411b6a20053a0000200241196a20063b0000200241186a20073a0000200241176a20083a0000200241156a20093b0000200241146a200a3a0000200241136a200b3a0000200241116a200c3b0000200241106a200d3a00002002410f6a200e3a00002002410d6a200f3b00002002410c6a20103a00002002410b6a20113a0000200241096a20123b0000200241086a20133a0000200220013a0021200220143a0007200220153b0005200220163a0004200220173a0003200220183b0001200220033a00002002413a6a200241f0006a41186a290300370100200241326a200241f0006a41106a2903003701002002412a6a200241f0006a41086a290300370100200241226a221d20022903703701000240200341ff01714101470d002001450d0020024101722201201d412010a0080d00200241c8006a41026a200141026a2d000022033a0000200220012f000022013b01482002410a6a2f0100211d2002410e6a2f0100211e200241126a2f01002105200241166a2f010021082002411a6a2f0100210b2002411e6a2f0100210e20022f01062111200041036a20033a0000200020013b0001200041206a201a3a00002000411e6a200e3b00002000411d6a201b3a00002000411c6a20043a00002000411a6a200b3b0000200041196a20063a0000200041186a20073a0000200041166a20083b0000200041156a20093a0000200041146a200a3a0000200041126a20053b0000200041116a200c3a0000200041106a200d3a00002000410e6a201e3b00002000410d6a200f3a00002000410c6a20103a00002000410a6a201d3b0000200041096a20123a0000200041086a20133a0000200041066a20113b0000200041056a20153a0000200041046a20163a0000410021030c010b410121030b200020033a0000200241b0016a24000bba0a03047f017e057f230041f0006b22022400200241c0006a41186a4200370300200241c0006a41106a22034200370300200241c0006a41086a220442003703002002420037034041a29bc800ad4280808080f000841001220529000021062004200541086a29000037030020022006370340200510354189eaca00ad4280808080f00084100122052900002106200241e0006a41086a2207200541086a2900003703002002200637036020051035200320022903602206370300200241206a41086a2004290300370300200241206a41106a2006370300200241206a41186a200729030037030020022002290340370320200241c0006a200241206a10fe0102400240200228024022080d00410021092002410036021820024201370310410121084100210a0c010b200220022902442206370214200220083602102006422088a7210a2006a721090b200241c0006a41186a4200370300200241c0006a41106a220b4200370300200241c0006a41086a220542003703002002420037034041a29bc800ad4280808080f00084100122032900002106200241e0006a41086a2204200341086a2900003703002002200637036020031035200520042903003703002002200229036037034041a99bc800ad4280808080a001841001220329000021062004200341086a2900003703002002200637036020031035200b20022903602206370300200241206a41086a2005290300370300200241206a41106a2006370300200241206a41186a200429030037030020022002290340370320200241086a200241206a412010c00141002104024002400240024002400240200a200228020c410020022802081b4f0d00024002400240200a41014b0d00200a0e020201020b41002104200a210503402005410176220320046a22072004200820074105746a2001412010a0084101481b2104200520036b220541014b0d000b0b200820044105746a2001412010a0082205450d022005411f7620046a21040b200241c0006a41186a200141186a290000370300200241c0006a41106a200141106a290000370300200241c0006a41086a200141086a29000037030020022001290000370340200a2004490d040240200a2009470d00200241106a20094101108a0120022802142109200228021021080b200820044105746a220541206a2005200a20046b410574109e081a20052002290340370000200541186a200241c0006a41186a2203290300370000200541106a200241c0006a41106a2207290300370000200541086a200241c0006a41086a22042903003700002002200a41016a220a3602182003420037030020074200370300200442003703002002420037034041a29bc800ad4280808080f00084100122012900002106200241e0006a41086a2205200141086a290000370300200220063703602001103520042005290300370300200220022903603703404189eaca00ad4280808080f000841001220129000021062005200141086a2900003703002002200637036020011035200b2002290360370000200b41086a2005290300370000200241206a41086a2004290300370300200241206a41106a2007290300370300200241206a41186a200329030037030020022002290340370320200241203602442002200241206a3602402008200a200241c0006a109802200941ffffff3f710d020c030b20004183323b0100200041086a410a360200200041046a41a99bc800360200200041026a410f3a0000200941ffffff3f71450d04200810350c040b200941ffffff3f71450d010b200810350b200041043a00000c010b2004200a104d000b200241f0006a24000b130020004108360204200041a884ca003602000b130020004112360204200041c089ca003602000b8c0201037f024002400240024002400240024020012802000e0400010203000b41012102410110332201450d05200141003a0000410121030c040b410110332202450d04200241013a00002001280204210320024101410510372202450d042002200336000120012802082104410a210320024105410a10372201450d04200120043600050c020b41012102410110332201450d03200141023a0000410121030c020b410110332202450d02200241033a00002001280204210320024101410510372202450d022002200336000120012802082104410a210320024105410a10372201450d02200120043600050b410921020b2000200236020820002003360204200020013602000f0b103c000bf33010017f017e017f027e097f017e027f017e037f057e017f017e017f047e017f027e230041d0046b22052400200541d8016a4201427f420020032004844200521b2206200342005220044200552004501b22071b4200200620071b4201427f420020012002844200521b2206200142005220024200552002501b22071b4200200620071b108408200541d8016a41086a290300210820052903d801210902402002427f550d00200541003602d401200541c0016a20012002427f427f200541d4016a10850842ffffffffffffffffff00200541c0016a41086a29030020052802d40122071b2102427f20052903c00120071b21010b02402004427f550d00200541003602bc01200541a8016a20032004427f427f200541bc016a10850842ffffffffffffffffff00200541b0016a29030020052802bc0122071b2104427f20052903a80120071b21030b0240024002400240024002400240024002400240024002402002427f570d002004427f570d01200541f8006a2003420020014200108408200541e8006a200342002002420010840820054198016a200442002001420010840820054188016a20044200200242001084082005290388012204200529039801220220052903682203200541f8006a41086a2903007c22017c2206200254ad20054198016a41086a2903007c22022001200354ad200541e8006a41086a2903007c7c22037c2201200454ad20054188016a41086a2903007c22042003200254ad7c22022004540d0a2005290378210320054198026a4200370300200541a0026a42003703002005420037039002200542808090bbbad6adf00d37038802410021070340200741086a220a4128460d0b20054188026a20076a210b200a2107200b290300500d000b200520023703c002200520013703b802200520063703b002200520033703a802200541c8026a41186a20054188026a41186a290300370300200541c8026a41106a20054188026a41106a290300370300200541c8026a41086a20054188026a41086a29030037030020052005290388023703c802200541a8026a41186a2107200541a8026a41086a210c41c002210a024003400240200a41406a220a41c000470d002003210441c000210a0c020b20072903002104200741786a21072004500d000b0b200a200479a76b210b200541e0026a210741c002210a024002400340200a41406a220a41c000460d0120072903002104200741786a21072004500d000c020b0b41c000210a20052903c80221040b200a200479a76b2207450d02200b2007490d030240200741c100490d00200541e8026a41106a200c41106a290300370300200541e8026a41086a200c41086a2903003703002005200c2903003703e80220054180036a41186a220a200541c8026a41186a29030037030020054180036a41106a220c200541c8026a41106a29030037030020054180036a41086a220d200541c8026a41086a290300370300200520052903c802370380032007417f6a220e410676210f02400240024002400240200e41ff014b0d00200b417f6a4106762210200f6b210b200f41016a211120054180036a200f4103746a22122903002104200541a0036a41186a200a290300370300200541a0036a41106a200c290300370300200541a0036a41086a200d29030037030020052005290380033703a003200541e8036a41106a4200370300200541e8036a41186a4200370300200542003703f003200520047922133703e8032013a72114200541e8036a41086a210d4100210702400340200741086a220a4120460d01200d20076a210c200a2107200c290300500d000b418b80cc00412641dc80cc00103f000b200541a8046a4200370300200541a0046a420037030020054190046a41086a420037030020054200370390042014410676220d41037421072014413f71220cad2104200541a0036a210a034020054190046a20076a200a290300200486370300200a41086a210a200741086a22074120470d000b0240200c450d00200d4103742107420020137d423f83210420054190046a41086a210d200541a0036a210a0340200d20076a220c200c290300200a2903002004887c370300200a41086a210a200741086a22074118470d000b0b20054180036a41186a20054190046a41186a29030037030020054180036a41106a20054190046a41106a29030037030020054180036a41086a20054190046a41086a290300370300200520052903900437038003200541b0046a41106a200541e8026a41086a290300370300200541b0046a41186a200541e8026a41106a290300370300200520052903e8023703b804200520033703b004200541e8036a41106a4200370300200541e8036a41186a4200370300200542003703f003200541c00020146b2215ad22013703e80320032013423f832216862102200541e8036a41086a210d4100210702400340200741086a220a4120460d01200d20076a210c200a2107200c290300500d000b418b80cc00412641dc80cc00103f000b200541a8046a4200370300200541a0046a420037030020054190046a41086a420037030020054200370390042015413f71210c2015410676210d0240201541ff014b0d00200d4103742107200cad210420054190046a210a0340200a200541b0046a20076a290300200488370300200a41086a210a200741086a22074120470d000b0b0240200c450d00200d41016a41034b0d00200d410374210a420020017d423f832104200541b0046a41086a210c20054190046a2107034020072007290300200c200a6a2903002004867c370300200741086a2107200a41086a220a4118470d000b0b200520052903a8043703c003200520052903a0043703b80320052005290398043703b00320052005290390043703a803200520023703a003200541e0036a4200370300200541c8036a41106a4200370300200541c8036a41086a4200370300200542003703c803200f417f6a220741034b0d01200f41026a2117200541a0036a2010200f6b4103746a221841086a21192012290300221a201a792204423f83221b86221c42ffffffff0f83211d201c422088210120054180036a20074103746a290300211e41c0002004a76b221f413f71ad2120200541e8036a41106a21212005290398032122200529039003212320052903880321242005290380032125200e4180024921260340200b221520116a220741054f0d03427f21020240200541a0036a20074103746a22122903002204201a5a0d002015200f6a220a41044b0d052001500d0c200541a0036a200a4103746a2903002202201b86220342ffffffff0f8321062003422088210342002002202088201f413f4b1b2004201b868422272027200180220220017e7d2104024003400240200242ffffffff0f560d002002201d7e2004422086200384580d020b2002427f7c2102200420017c2204428080808010540d000b0b20274220862003842002201c7e7d22272027200180220320017e7d2104024003400240200342ffffffff0f560d002003201d7e2004422086200684580d020b2003427f7c2103200420017c220442ffffffff0f580d000b0b2007417e6a220741044b0d0d20274220862006842003201c7e7d201b882104200320024220867c2102200541a0036a20074103746a29030021060340200541d8006a20024200201e4200108408200620052903585a2004200541d8006a41086a29030022035a20042003511b0d012002427f7c21022004201a7c22032004542107200321042007450d000b0b200541c8006a2025420020024200108408200541386a2024420020024200108408200541286a2023420020024200108408200541186a20224200200242001084082005200529034822283703e803200520052903382203200541c8006a41086a2903007c22043703f003200520052903282206200541386a41086a2903002004200354ad7c7c22033703f803200520052903182227200541286a41086a2903002003200654ad7c7c2203370380042005200541186a41086a2903002003202754ad7c37038804201541064f0d0d2026450d0e024020174128201541037422106b410376220e200e20174b1b220d450d00200541a0036a20106a22072007290300220320287d22063703002006200356210c0240200d4101460d004102210a2021210b2019210703402007200729030022032004200cad4201837c22067d22273703002006200454202720035672210c200a200d4f0d01200a41016a210a200741086a2107200b2903002104200b41086a210b0c000b0b200c450d004100210b02402011200e200e20114b1b220d450d0020054180036a210a201821074100210c0340200720072903002204200a2903002203200bad42ff01837c22067c22273703002006200354202720045472210b200741086a2107200a41086a210a200c41016a220c200d490d000b0b2002427f7c210220122012290300200bad7c3703000b201541034b0d05201520154100476b210b200541c8036a20106a2002370300201841786a2118201941786a21192015450d0f0c000b0b200f410441dc80cc001042000b2007410441dc80cc001042000b2007410541dc80cc001042000b200a410541dc80cc001042000b2015410441dc80cc001042000b200541e8036a41186a200541a8026a41186a290300370300200541e8036a41106a200541a8026a41106a290300370300200541e8036a41086a200541a8026a41086a290300370300200520052903a8023703e80302400240024020052903c80222042004792203423f83221e86221a4220882204500d00201a42ffffffff0f832102200529038004210641c0002003a76b220741c000490d012004422086211d2006201e86220342ffffffff0f8321282003422088211b42002103420021064200212742002101024003400240200142ffffffff0f560d0020032006201b84580d020b200320027d21032006201d7c21062001427f7c2101202720047c2227428080808010540d000b0b201b2001201a7e7d22272027200480220320047e7d2106024003400240200342ffffffff0f560d00200320027e2006422086202884580d020b2003427f7c2103200620047c2206428080808010540d000b0b2005200320014220867c37038004427f201e8620274220862028842003201a7e7d83221d201d200480220320047e7d210120052903f803201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b2006201d422086842003201a7e7d221d201d200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703f803427f201e86201d4220862027842001201a7e7d83221d201d200480220320047e7d210120052903f003201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b2006201d422086842003201a7e7d221d201d200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703f003427f201e86201d4220862027842001201a7e7d83221d201d200480220320047e7d210120052903e803201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b2006201d422086842003201a7e7d22012001200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703e8030c020b41d0fecb00411941dc80cc00103f000b20062007413f71ad221d8822282028200480220320047e7d21012006201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b20284220862006842003201a7e7d22282028200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703800420052903f8032206201d88427f201e8620284220862027842001201a7e7d838422282028200480220320047e7d21012006201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b20284220862006842003201a7e7d22282028200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703f80320052903f0032206201d88427f201e8620284220862027842001201a7e7d838422282028200480220320047e7d21012006201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b20284220862006842003201a7e7d22282028200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703f00320052903e8032206201d88427f201e8620284220862027842001201a7e7d8384221d201d200480220320047e7d21012006201e86220642ffffffff0f83212720064220882106024003400240200342ffffffff0f560d00200320027e2001422086200684580d020b2003427f7c2103200120047c2201428080808010540d000b0b201d4220862006842003201a7e7d22012001200480220120047e7d2106024003400240200142ffffffff0f560d00200120027e2006422086202784580d020b2001427f7c2101200620047c2206428080808010540d000b0b2005200120034220867c3703e8030b20054190046a41186a200541e8036a41186a29030037030020054190046a41106a200541e8036a41106a29030037030020054190046a41086a200541e8036a41086a290300370300200520052903e803370390040c090b41e9fecb00413541dc80cc00103f000b41e9fecb00413541dc80cc00103f000b41fbffcb00411041dc80cc00103f000b200541a8046a4200370300200541a0046a420037030020054198046a420037030020054200370390040c050b41c080cc00411941dc80cc00103f000b2007410541dc80cc001042000b2015410541dc80cc001059000b2017410541dc80cc001058000b200541e8036a41206a200541a0036a41206a290300370300200541e8036a41186a200541a0036a41186a2903002204370300200541e8036a41106a200541a0036a41106a2903002202370300200541e8036a41086a200541a0036a41086a2903002203370300200520052903a00322013703e803200520012016883703b004200520032016883703b804200520022016883703c004200520042016883703c804024002402014450d00420020137d423f8321044101210703402007417f6a220a41034b0d02200541b0046a200a4103746a220a200a290300200541e8036a20074103746a29030020048684370300200720074104496a220a41044b0d01200741034b210b200a2107200b450d000b0b20054190046a41086a200541c8036a41086a29030037030020054190046a41106a200541c8036a41106a29030037030020054190046a41186a200541c8036a41186a290300370300200520052903c803370390040c010b200a410441dc80cc001042000b200541e8016a41086a20054190046a41086a2903002204370300200541e8016a41106a20054190046a41106a2903002202370300200541e8016a41186a20054190046a41186a2903002203370300200520052903900422013703e801200541e8036a41186a2003370300200541e8036a41106a220c2002370300200541e8036a41086a2004370300200520013703e8034100210702400340200741086a220a4118460d01200c20076a210b200a2107200b290300500d000c020b0b200541086a20092008422520052903e80320052903f003220442005322071b4200200420071b1084082004427f570d00200541106a2903002104200529030821020c010b428080808080808080807f42ffffffffffffffffff00200842005322071b21044200427f20071b21020b2000200237030020002004370308200541d0046a24000bb10503027f017e047f230041d0006b2202240041a3edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a290000370300200220043703082003103541fe99ca00ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000b920503027f017e067f230041d0006b2202240041a8e7cb00ad4280808080f00184100122032900002104200241086a200341086a290000370300200220043703002003103541b7e7cb00ad4280808080c00184100122032900002104200241106a41086a200341086a2900003703002002200437031020031035200220003703302002200241306aad42808080808001841003220329000037033820031035200241cc006a200241306a41086a3602002002200241386a41086a3602442002200241306a3602482002200241386a360240200241206a200241c0006a107b02400240024002402002280228220541206a2206417f4c0d00200228022021070240024020060d0041002108410121030c010b200610332203450d02200621080b024002402008410f4d0d00200821090c010b200841017422094110200941104b1b22094100480d03024020080d002009103322030d010c050b20082009460d0020032008200910372203450d040b20032002290300370000200341086a200241086a2903003700000240024020094170714110460d00200921080c010b200941017422084120200841204b1b22084100480d0320092008460d0020032009200810372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200841606a2005490d00200821090c010b200541206a22092005490d032008410174220a2009200a20094b1b22094100480d0320082009460d0020032008200910372203450d040b200341206a20072005109d081a02402002280224450d00200710350b200220013602402006ad4220862003ad84200241c0006aad4280808080c00084100202402009450d00200310350b200241d0006a24000f0b1044000b1045000b103e000b103c000be91305057f017e047f027e037f230041f0006b22052400200541c0006a41186a22064200370300200541c0006a41106a22074200370300200541c0006a41086a220842003703002005420037034041a8e7cb00ad4280808080f0018410012209290000210a200541e0006a41086a220b200941086a2900003703002005200a370360200910352008200b2903003703002005200529036037034041b697ca00ad4280808080d0018410012209290000210a200b200941086a2900003703002005200a3703602009103520072005290360220a370300200541206a41086a22092008290300370300200541206a41106a220c200a370300200541206a41186a220d200b29030037030020052005290340370320200541186a200541206a412041b0b4cc0041004100108a02024002400240024002400240024020052802184101470d0041e192ca00210b410d2108410221070c010b2006420037030020074200370300200842003703002005420037034041d1c4c700ad4280808080e0008410012206290000210a2008200641086a2900003703002005200a3703402006103541e7c4c700ad4280808080e0008410012206290000210a200b200641086a2900003703002005200a3703602006103520072005290360220a37030020092008290300370300200c200a370300200d200b29030037030020052005290340370320200541106a200541206a412010c0012005280214410020052802101b2109024020034101460d00200541206a210e0c030b200541c0006a41186a22064200370300200541c0006a41106a220c4200370300200541c0006a41086a220842003703002005420037034041a8e7cb00ad4280808080f00184220f1001220d290000210a200541e0006a41086a220b200d41086a2900003703002005200a370360200d10352008200b2903003703002005200529036037034041f499ca00ad4280808080a0018422101001220d290000210a200b200d41086a2900003703002005200a370360200d103520072005290360370000200741086a220d200b290300370000200541206a41086a220e2008290300370300200541206a41106a2211200c290300370300200541206a41186a2212200629030037030020052005290340370320200541086a200541206a412010c0012005280208450d01200528020c20094d0d0141da92ca00210b41072108410321070b20004183203b0100200041086a2008360200200041046a200b360200200041026a20073a0000200141046a280200220b450d02200b41286c450d02200128020010350c020b20064200370300200c42003703002008420037030020054200370340200f10012213290000210a200b201341086a2900003703002005200a370360201310352008200b29030037030020052005290360370340201010012213290000210a200b201341086a2900003703002005200a3703602013103520072005290360370000200d200b290300370000200e20082903003703002011200c29030037030020122006290300370300200520052903403703202005200920024101746a360240200541206aad4280808080800484200541c0006aad4280808080c000841002200541206a210e0b200128020821082001280204210c2001280200210d200541c0006a41186a22114200370300200541c0006a41106a22124200370300200541c0006a41086a220142003703002005420037034041a8e7cb00ad4280808080f0018410012206290000210a200541e0006a41086a220b200641086a2900003703002005200a370360200610352001200b2903003703002005200529036037034041b697ca00ad4280808080d0018410012206290000210a200b200641086a2900003703002005200a3703602006103520072005290360370000200741086a200b290300370000200541206a41086a2001290300370300200541206a41106a2012290300370300200541206a41186a201129030037030020052005290340370320200541003602482005420137034041041033220b450d02200541043602442005200b360240200b200936000020054104360248200b410441081037220b450d0220054108360244200b20023600042005200b360240200541083602482008200541c0006a10772005280248210702402008450d00200d200841286c6a2106200d210b0340024002402005280244220220076b4120490d00200741206a210820052802402101200221090c010b200741206a22082007490d04200241017422012008200120084b1b22094100480d040240024020020d00024020090d00410121010c020b2009103322010d010c070b2005280240210120022009460d0020012002200910372201450d060b20052009360244200520013602400b200120076a2207200b290000370000200741186a200b41186a290000370000200741106a200b41106a290000370000200741086a200b41086a29000037000020052008360248200b41206a290300210a0240200920086b41074b0d00200841086a22072008490d04200941017422022007200220074b1b22074100480d040240024020090d00024020070d00410121010c020b200710332201450d070c010b20092007460d0020012009200710372201450d060b20052007360244200520013602400b200120086a200a3700002005200841086a22073602482006200b41286a220b470d000b0b2005280244210b0240024020034101460d0002400240200b2007460d00200528024021080c010b200741016a220b2007490d0420074101742208200b2008200b4b1b220b4100480d040240024020070d00410021070240200b0d00410121080c020b200b10332208450d070c010b200528024021082007200b460d0020082007200b10372208450d060b2005200b360244200520083602400b200820076a41003a00002005200741016a22073602480c010b02400240200b2007460d00200528024021080c010b200741016a220b2007490d0320074101742208200b2008200b4b1b220b4100480d030240024020070d00410021070240200b0d00410121080c020b200b10332208450d060c010b200528024021082007200b460d0020082007200b10372208450d050b2005200b360244200520083602400b200820076a41013a00002005200741016a22013602480240200b20016b41034b0d00200141046a22092001490d03200b41017422022009200220094b1b22094100480d0302400240200b0d00024020090d00410121080c020b200910332208450d060c010b200b2009460d002008200b200910372208450d050b20052009360244200520083602400b200820016a20043600002005200741056a22073602482005280244210b200528024021080b200ead42808080808004842007ad4220862008ad8410020240200b450d00200810350b0240200c450d00200c41286c450d00200d10350b200041043a00000b200541f0006a24000f0b103e000b103c000bff0201037f230041206b2203240002400240200241c4006c41046a2204417f4c0d000240024020040d0041012105410021040c010b200410332205450d020b20034100360208200320053602002003200436020420022003107702402002450d00200241c4006c210203400240024020012d00004101460d00200341003a00102003200341106a410110782003200141046a2802003602102003200341106a410410780c010b200341013a00102003200341106a41011078412010332204450d042003422037021420032004360210200341106a200141016a41201078200328021421042003200328021022052003280218107802402004450d00200510350b0240200141216a2d00004101460d00200341003a00102003200341106a410110780c010b200341013a00102003200341106a410110782003200141226a412010780b200141c4006a2101200241bc7f6a22020d000b0b20002003290300370200200041086a200341086a280200360200200341206a24000f0b1044000b1045000b290020004101360204200041086a200128020420012802006b41a0016e2201360200200020013602000ba50201057f230041d0006b21020240200128020022032001280204470d00200041003602000f0b2001200341a0016a3602002002200329004237012a2002200329004a370132200241086a41086a220120022903303703002002200329005237013a200241086a41106a220420022903383703002002200328005a360142200220032f005e3b0146200241086a41186a22052002290340370300200220032f00403b012820022002290328370308200241286a41186a22062005290300370300200241286a41106a22052004290300370300200241286a41086a220420012903003703002002200229030837032820002003360200200020022903283702042000410c6a2004290300370200200041146a20052903003702002000411c6a20062903003702000bf30801087f230041f0006b2103024002402001280200220420012802042205460d00200241016a210603402001200441a0016a2202360200200341003a0068200441c0006a2d00002107200341013a0068200320073a0048200441c1006a2d00002107200341023a0068200320073a0049200441c2006a2d00002107200341033a0068200320073a004a200441c3006a2d00002107200341043a0068200320073a004b200441c4006a2d00002107200341053a0068200320073a004c200441c5006a2d00002107200341063a0068200320073a004d200441c6006a2d00002107200341073a0068200320073a004e2003200441c7006a2d00003a004f200341083a0068200441c8006a2d00002107200341093a0068200320073a0050200441c9006a2d000021072003410a3a0068200320073a0051200441ca006a2d000021072003410b3a0068200320073a0052200441cb006a2d000021072003410c3a0068200320073a0053200441cc006a2d000021072003410d3a0068200320073a0054200441cd006a2d000021072003410e3a0068200320073a0055200441ce006a2d000021072003410f3a0068200320073a00562003200441cf006a2d00003a0057200341103a0068200441d0006a2d00002107200341113a0068200320073a0058200441d1006a2d00002107200341123a0068200320073a0059200441d2006a2d00002107200341133a0068200320073a005a200441d3006a2d00002107200341143a0068200320073a005b200441d4006a2d00002107200341153a0068200320073a005c200441d5006a2d00002107200341163a0068200320073a005d200441d6006a2d00002107200341173a0068200320073a005e2003200441d7006a2d00003a005f200341183a0068200441d8006a2d00002107200341193a0068200320073a0060200441d9006a2d000021072003411a3a0068200320073a0061200441da006a2d000021072003411b3a0068200320073a0062200441db006a2d000021072003411c3a0068200320073a0063200441dc006a2d000021072003411d3a0068200320073a0064200441dd006a2d000021072003411e3a0068200320073a0065200441de006a2d000021072003411f3a0068200320073a0066200441df006a2d00002107200341203a0068200320073a0067200341286a41086a22072003290350370300200341286a41106a22082003290358370300200341286a41186a2209200329036037030020032003290348370328200341086a41086a220a2007290300370300200341086a41106a22072008290300370300200341086a41186a2208200929030037030020032003290328370308200341c8006a41186a2008290300370300200341c8006a41106a2007290300370300200341c8006a41086a200a290300370300200320032903083703482006417f6a2206450d022002210420052002470d000b0b200041003602000f0b20002004360200200020032903483702042000410c6a200341d0006a290300370200200041146a200341d8006a2903003702002000411c6a200341e0006a2903003702000b130020004101360204200041e09aca003602000b3400200041a8e7cb0036020420004100360200200041146a4106360200200041106a41d49bca00360200200041086a420f3702000b2c01017f02404108103322020d001045000b20004288808080800137020420002002360200200242003700000b2201017f230041106b22022400200241003602002000200210db04200241106a24000b2201017f230041106b22022400200241003602002000200210db06200241106a24000b130020004102360204200041eca4ca003602000b3400200041a3edcb0036020420004100360200200041146a4107360200200041106a41b8adca00360200200041086a42073702000b2c01017f02404104103322020d001045000b20004284808080c00037020420002002360200200241003600000bec0101057f230041306b2201240002400240200028020422020d00410021032001411c6a41003602002001410036020c0c010b2000410c6a280200210302400240200041086a28020022040d00200221000c010b2004210020022105034020052802880b21052000417f6a22000d000b200221000340200020002f01064102746a41880b6a28020021002004417f6a22040d000b200521020b200141246a20002f0106360200200141206a41003602002001411c6a200036020020014100360218200142003703102001200236020c200141003602080b20012003360228200141086a108f03200141306a24000bd564030d7f017e0c7f230041d0036b220424004100210520044100360280012004200236027c200420013602784104210602400240024002400240024002400240024002400240024002400240024002400240024002400240024020024104490d00200441043602800120012800004180c2cdeb06460d0141012101410021070c030b200441013a00b801200441a4036a41013602002004420137029403200441acfdcb0036029003200441363602ec022004200441e8026a3602a0032004200441b8016a3602e80220044180026a20044190036a10410c010b4104210602400240024002402002417c714104460d00200241074d0d0220044108360280010240200128000422084101460d004102210141042106410021070c060b20044190036a200441f8006a10b107410421062004280290034101470d0141002105410021070c030b200441013a00b801200441a4036a41013602002004420137029403200441acfdcb0036029003200441363602ec022004200441e8026a3602a0032004200441b8016a3602e80220044180026a20044190036a10410c030b20044190036a4104722101410021094100210a41002105410021074100210b0340200441b8016a41286a220c200141286a290200370300200441b8016a41206a220d200141206a290200370300200441b8016a41186a220e200141186a290200370300200441b8016a41106a220f200141106a290200370300200441b8016a41086a2210200141086a2902003703002004200129020022113703b80102402011a741ff01712212417e6a410c4f0d0041002108024002400240024002400240024002400240024002400240024020120e100c0c000102030405060708090a0b0c0c0c0b410121080c0b0b410221080c0a0b410321080c090b410421080c080b410521080c070b410621080c060b410721080c050b410821080c040b410921080c030b410a21080c020b410b21080c010b410c21080b024002400240200b41ff0171221320084d0d00411321010c010b41002108024002400240024002400240024002400240024002400240024020120e100c0c000102030405060708090a0b0c0c0c0b410121080c0b0b410221080c0a0b410321080c090b410421080c080b410521080c070b410621080c060b410721080c050b410821080c040b410921080c030b410a21080c020b410b21080c010b410c21080b20132008470d01411421010b024002402012410e4b0d00024002400240024002400240024002400240024002400240024020120e0f0001020304050607080e090e0a0b0c000b200441c0016a280200450d0d20042802bc0110350c140b0240200441c0016a280200450d0020042802bc0110350b200441cc016a280200450d0c200441c8016a28020010350c130b20042802bc0121090240200441c4016a2802002212450d002012410474210a2009211203400240201241046a280200450d00201228020010350b201241106a2112200a41706a220a0d000b0b200441c0016a28020041ffffffff0071450d0b200910350c120b20042802bc0121090240200441b8016a410c6a2802002212450d00201241286c210a2009211203400240201241046a280200450d00201228020010350b0240201241106a280200450d002012410c6a28020010350b201241286a2112200a41586a220a0d000b0b200441c0016a2802002212450d0a201241286c450d0a200910350c110b200441c0016a28020041ffffffff0371450d0920042802bc0110350c100b200441c0016a2802002212450d082012410c6c450d0820042802bc0110350c0f0b200441c0016a2802002212450d072012410c6c450d0720042802bc0110350c0e0b20042802bc01210f0240200441c4016a2802002212450d00200f20124104746a210e200f210d03400240200d280208220a450d00200d2802002112200a410474210a0340024020122d00004109470d000240201241046a220c280200220928020441ffffffff0371450d0020092802001035200c28020021090b200910350b201241106a2112200a41706a220a0d000b0b200d41106a21120240200d41046a28020041ffffffff0071450d00200d28020010350b2012210d2012200e470d000b0b200441c0016a28020041ffffffff0071450d06200f10350c0d0b20042802bc0121090240200441c4016a2802002212450d00201241146c210a2009211203400240201241046a280200450d00201228020010350b201241146a2112200a416c6a220a0d000b0b200441c0016a2802002212450d05201241146c450d05200910350c0c0b200441b8016a41047210b207200441c0016a2802002212450d042012411c6c450d0420042802bc0110350c0b0b200441b8016a41047210b307200441c0016a2802002212450d03201241186c450d0320042802bc0110350c0a0b200441b8016a41047210b407200441c0016a2802002212450d022012411c6c450d0220042802bc0110350c090b024020042802bc012212450d00200441c0016a280200450d00201210350b0240200441cc016a280200220c450d000240200441d4016a2802002212450d002012410c6c210a200c21120340024020122802002209450d00201241046a280200450d00200910350b2012410c6a2112200a41746a220a0d000b0b200441d0016a2802002212450d002012410c6c450d00200c10350b200441dc016a280200220f450d010240200441e4016a2802002212450d00200f20124104746a210e200f210d0340200d220c41106a210d0240200c2802042212450d000240200c410c6a280200220a450d00200a410c6c210a0340024020122802002209450d00201241046a280200450d00200910350b2012410c6a2112200a41746a220a0d000b0b200c41086a2802002212450d002012410c6c450d00200c28020410350b200d200e470d000b0b200441e0016a28020041ffffffff0071450d01200f10350c080b0240200441c0016a280200450d0020042802bc0110350b0240200441cc016a2802002212450d00200441d0016a280200450d00201210350b200441dc016a28020041ffffffff0071450d00200441d8016a28020010350b0c060b4100210b02400240024002400240024002400240024002400240024020120e100c0c000102030405060708090a0b0c0c0c0b4101210b0c0b0b4102210b0c0a0b4103210b0c090b4104210b0c080b4105210b0c070b4106210b0c060b4107210b0c050b4108210b0c040b4109210b0c030b410a210b0c020b410b210b0c010b410c210b0b20044180026a41286a2208200c29030037030020044180026a41206a220c200d29030037030020044180026a41186a220d200e29030037030020044180026a41106a220e200f29030037030020044180026a41086a220f2010290300370300200420042903b80137038002024020052007470d00200541016a22122005490d0720092012200920124b1bad42307e2211422088a70d072011a722124100480d0702400240024020050d0020120d01410421060c020b200a2012460d010240200a0d0020120d01410421060c020b2006200a201210372206450d180c010b201210332206450d170b201241306e21070b2006200a6a2212200429038002370200201241286a2008290300370200201241206a200c290300370200201241186a200d290300370200201241106a200e290300370200201241086a200f290300370200200941026a2109200a41306a210a200541016a210520044190036a200441f8006a10b1072004280290034101460d020c000b0b4108200241c0fdcb001058000b0240024020042d0094030d002006200541306c6a210b20062101024003400240200b2001470d00410021090c020b20012d00002112200141306a220a21012012410c470d000b200a415c6a28020021090b2006200541306c6a210b20062101024003400240200b2001470d00410021010c020b20012d00002112200141306a220a210120124104470d000b200441f0006a200a41546a10bf03200428027421010b024020092001470d00410021014101210841e100210b41f3da01210a410021120c050b2006200510f40641012112411a21012007450d01200741306c450d01200610350c040b2004280294032201411076210a2001410876210b20044190036a41106a28020021092004419c036a280200210c20044190036a41086a28020021080c020b0c020b2004280280022108200428028402210c20042802880221094105210141002105410021074100210a4100210b0b2006200510f4064101211202402007450d00200741306c450d00200610350b20092107200c21060b200a411074200b41ff017141087472200141ff01717221100240024002402012450d00200621020c010b2004280280012002460d01200441003a00b801200441a4036a41013602002004420137029403200441acfdcb0036029003200441363602ec022004200441e8026a3602a0032004200441b8016a3602e80220044180026a20044190036a1041200428028002210820042802840221022006200510f406410521102007450d00200741306c450d00200610350b02402002450d00201041ff01714105470d00200810350b200041a0d3cb0036020420004101360200200041086a41163602000c0f0b4100210a200441b0016a4100360200200441a0016a420037030020044198016a4280808080c00037030020044188016a4200370300200442043703a801200442013703900120044280808080c0003703800120044204370378200541306c211241002102024002400340024020122002470d00410421124100210b0c020b200620026a2101200241306a220b210220012d00004102470d000b200441e8006a2006200b6a41546a10bf032004280268210b200428026c21012004410036029803200442043703900320044190036a41002001108c012004280290032102200428029803210c02402001450d002001410474210d2002200c4104746a21020340200b221241086a2802002201417f4c0d032012410c6a2d0000210e2012280200210f0240024020010d004100210b410121090c010b200110332209450d082001210b0b02400240200b2001490d00200b210a0c010b200b410174220a2001200a20014b1b220a4100480d050240200b0d00200a10332209450d150c010b0240200b200a470d00200b210a0c010b2009200b200a10372209450d140b201241106a210b2009200f2001109d0821092002410d6a2012410d6a2d00003a00002002410c6a200e3a0000200241086a2001360200200241046a200a360200200220093602002002410e6a20042f0180023b0100200241106a2102200c41016a210c200d41706a220d0d000b20042802900321020b200428029403410020021b210b200c410020021b210a2002410420021b21120b024020042802a4012201450d00200428029c0121022001410474210103400240200241046a280200450d00200228020010350b200241106a2102200141706a22010d000b0b024020042802a00141ffffffff0071450d00200428029c0110350b2004200a3602a4012004200b3602a0012004201236029c01200541306c2112410021094100210203404101210b20122002460d03200620026a2101200241306a220a210220012d00004103470d000b200441e0006a2006200a6a41546a10bf0320042802602202450d024100210f20042802642201450d03200141286c21012002411c6a2102200441f8006a410c6a2113410021094100210f4101210b034002400240024002400240024002402002417c6a2d00000e0401020300010b200441f8006a2002417d6a22122d00002002417e6a220a2d000041017110b507200a2d0000210a20122d0000210c2009200f470d04200941016a22122009490d082009410174220d2012200d20124b1b220e200e6a2212200e490d0820124100480d080240024020090d0020120d014101210b0c050b200d2012460d040240200d0d0020120d014101210b0c050b200b200d20121037220b450d180c040b20121033220b450d170c030b200441f8006a200228020010b6070c040b20044190036a41086a220a200241086a28020036020020042002290200370390030240200428028c012212200428028801470d00201320124101108701200428028c0121120b2004280284012012410c6c6a2212200429039003370200201241086a200a2802003602002004200428028c0141016a36028c010c030b20044190036a41086a220a200241086a280200360200200420022902003703900302402004280280012212200428027c470d00200441f8006a2012410110870120042802800121120b20042802782012410c6c6a2212200429039003370200201241086a200a280200360200200420042802800141016a360280010c020b2012410176210f0b200b20094101746a2212200a4101713a00012012200c3a0000200941016a21090b200241286a2102200141586a2201450d040c000b0b1044000b103e000b4100210f0b200541306c2112410021020240034020122002460d01200620026a2101200241306a220a210220012d00004104470d000b200441d8006a2006200a6a41546a10bf03200428025c2201450d0020042802582102200141027421010340200441f8006a200228020010b607200241046a21022001417c6a22010d000b0b200541306c2112410021020240034020122002460d01200620026a2101200241306a220a210220012d00004105470d000b200441d0006a2006200a6a41546a10bf032004280254410c6c2212450d0020042802502102200441f8006a410c6a210d0340200241086a2101024002400240200241046a2802004101470d0020042001280200220a3602e8022002280200220c200a4b0d010b200441003602b8010c010b200441023602a4032004420237029403200441d0aacc00360290032004410136028c0220044101360284022004200c3602f802200420044180026a3602a0032004200441f8026a360288022004200441e8026a36028002200441b8016a20044190036a104120042802b801450d00200441b8016a21020c0b0b2002290200211120044190036a41086a220a200128020036020020042011370390030240200428028c012201200428028801470d00200d20014101108701200428028c0121010b2002410c6a21022004280284012001410c6c6a2201200429039003370200200141086a200a2802003602002004200428028c0141016a36028c01201241746a22120d000b0b200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d00004106470d000b200441c8006a200a10bf03200428024c2201450d00200428024821022001410c6c2112034020044190036a200210b7070240200428029003450d0020044190036a21020c0b0b2002290200211120044190036a41086a220a200241086a280200360200200420113703900302402004280280012201200428027c470d00200441f8006a2001410110870120042802800121010b2002410c6a210220042802782001410c6c6a2201200429039003370200200141086a200a280200360200200420042802800141016a36028001201241746a22120d000b0b200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d00004107470d000b200441c0006a200a10bf0320042802442201450d002004280240220220014104746a210a20044190036a4104722112034020044190036a2002200b200910b80702400240024020042d0090034101460d00200420042d00910322013a00e802024020012002410c6a2d0000220c470d00200441003602b8010c030b200441023602a4032004420237029403200441e4abcc00360290032004413736028c0220044137360284022004200c3a00f802200420044180026a3602a0032004200441e8026a360288022004200441f8026a36028002200441b8016a20044190036a10410c010b200441b8016a41086a201241086a280200360200200420122902003703b8010b024020042802b801450d00200441b8016a21020c0c0b2002410c6a2d000021010b200441f8006a20012002410d6a2d000041017110b507200241106a2202200a470d000b0b20044190036a41386a2202200441f8006a41386a28020036020020044190036a41306a2201200441f8006a41306a29030037030020044190036a41286a200441f8006a41286a29030037030020044190036a41206a2212200441f8006a41206a29030037030020044190036a41186a220a200441f8006a41186a29030037030020044190036a41106a200441f8006a41106a29030037030020044190036a41086a200441f8006a41086a22092903003703002004200429037837039003200441b8016a41086a2009280200360200200420042903783703b801200441b8016a41146a20044190036a41146a2802003602002004200429029c033702c401200441b8016a41206a20122802003602002004200a2903003703d001200441b8016a412c6a20044190036a412c6a280200360200200420042902b4033702dc01200441b8016a41386a2002280200360200200420012903003703e801200541306c2102200641546a210102400340024020020d00410021090c020b200241506a21022001412c6a2112200141306a220a210120122d00004104470d000b200441386a200a10bf03200428023c21090b200420093602f401200541306c21022006415c6a210102400340024020020d00410021020c020b200241506a2102200141246a2112200141306a220a210120122d0000410c470d000b200a28020021020b200420023602f80120092002470d050240024002400240024002402009450d00200541306c2102200641546a210103402002450d04200241506a21022001412c6a2112200141306a220a210120122d00004104470d000b200541306c2102200641546a210103402002450d03200241506a21022001412c6a2112200141306a220c210120122d0000410c470d000b200441306a200a10bf0320042802342202450d002004280230220e20024102746a211420044190036a41286a2115200c41086a2113200441b0026a2116200441b8026a21174100210d03402004200d3602fc0120132802002102200c2802002101200442013702940320044198dbcb0036029003200441013602fc02200441013602a4032004200441f8026a3602a0032004200441fc016a3602f80220044180026a20044190036a1041200428028002211220042902840221112002200d4d0d0e02402011a7450d00201210350b2004200e28020022023602e802024002400240024020042802e40120024d0d000240024002402001200d41186c6a22012802142218450d0020042802dc0120024104746a22122d000d21192012280200211a200128020c21022001280200211b2012280208221c210a024002402001280208221d450d00201d4103742109201c2101201b21120340200120122802006a220a2001490d02201241086a2112200a2101200941786a22090d000b0b200420193a00c803200442808080808080103703c003200442043703b803200442808080808080103703b003200442013703a8032004201a360294032004200aad422086201dad843703a0032004201bad422086201cad84370398032004200441b8016a36029003410021012015410010ba0720042802b80320042802c00322124103746a2019ad42ff018342288637020020044180026a41086a20042903980337030020044180026a41106a20042903a00337030020044180026a41186a20042903a80337030020044180026a41206a20042903b00337030020044180026a41286a20042903b8033703002004201241016a3602c003201620042903c003370300201720042802c803360200200420042903900337038002201841047421120340200420013602c002200420023602c402200441c8026a20044180026a200210bb07024020042802c802450d00200441e8026a41086a200441c8026a41086a280200360200200420042903c8023703e8022004410336028c03200442033702fc02200441c4d2cb003602f802200441383602a4032004410136029c032004413936029403200420044190036a360288032004200441e8026a3602a0032004200441c0026a360298032004200441c4026a36029003200441d8026a200441f8026a1041024020042802ec02450d0020042802e80210350b20042802d802220a0d040b200241106a2102200141016a2101201241706a22120d000b20042802b0020d030240200428029c02450d0020042802980210350b20042802ac0241ffffffff0171450d0720042802a80210350c070b41201033220a450d0e200a41186a41002900c0b24c370000200a41106a41002900b8b24c370000200a41086a41002900b0b24c370000200a41002900a8b24c37000042a0808080800421110c040b41201033220a450d0d200a41186a41002900bad24b370000200a41106a41002900b2d24b370000200a41086a41002900aad24b370000200a41002900a2d24b37000042a0808080800421110c030b20042902dc0221110240200428029c02450d0020042802980210350b20042802ac0241ffffffff0171450d0320042802a80210350c030b41dcd2cb00413041c086cc00103f000b200441013602a4032004420237029403200441f0aecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a1041200428028002210a20042902840221110b200a450d010b200420113702fc022004200a3602f8022004200441f8026a3602d802200441023602a4032004420237029403200441a0dbcb00360290032004413a36028c022004410136028402200420044180026a3602a0032004200441d8026a360288022004200441fc016a36028002200441e8026a20044190036a1041024020042802fc02450d0020042802f80210350b20042802e80222120d030b200d41016a210d200e41046a220e2014470d000b0b200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d00004109470d000b2004200a28020022023602d80202400240200441f0016a28020020024d0d00200420042802e80120024102746a28020022023602e802200441e4016a28020020024b0d01200441a4036a41013602002004420237029403200441f0aecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c090b200441a4036a41013602002004420237029403200441ccaecc0036029003200441013602fc022004200441f8026a3602a0032004200441d8026a3602f80220044180026a20044190036a10410c080b20042802dc0120024104746a220231000d4220862002350208844280808080c000510d00412d10332212450d06201241256a41002900d5db4b370000201241206a41002900d0db4b370000201241186a41002900c8db4b370000201241106a41002900c0db4b370000201241086a41002900b8db4b370000201241002900b0db4b37000042ad808080d00521110c0d0b200541306c2102200641546a210103402002450d05200241506a21022001412c6a2112200141306a220a210120122d00004108470d000b200441286a200a10bf0320042802282102200428022c21122004410036029803200442043703900320044190036a41002012109001200428029803210c200428029003210e02402012450d002002201241146c6a2109200e200c4103746a21012012410274417c6a410276210d034020022802002112200141046a200241086a28020036020020012012360200200141086a2101200241146a22022009470d000b200c200d6a41016a210c0b2004280294032113200e200c20044190036a41004120200c676b10be070240200c450d00200e200c4103746a210941012112200e2102200e21010340024002402012450d00200920026b41037620124d0d03200220124103746a21020c010b20092002460d020b200420013602e8020240200141046a2802002212200241046a280200470d002001280200220c2002280200220d460d0a200c200d201210a008450d0a0b200241086a210241002112200141086a22012009470d000b0b200441206a200a10bf0320042802242202450d03200241146c2101200428022041106a210203400240024002400240024002402002417c6a2802000e0400030201000b2004200228020022123602d802024020042802f00120124d0d00200420042802e80120124102746a28020022123602e80220042802e40120124b0d05200441013602a4032004420237029403200441f0aecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c0f0b200441a4036a41013602002004420237029403200441ccaecc0036029003200441013602fc022004200441f8026a3602a0032004200441d8026a3602f80220044180026a20044190036a10410c0e0b2004200228020022123602d80220042802d80120124d0d0220042802d00120124101746a2d0001450d03200441a4036a41013602002004420237029403200441b0afcc0036029003200441013602fc022004200441f8026a3602a0032004200441d8026a3602f80220044180026a20044190036a10410c0d0b2004200228020022123602e80220042802c00120124b0d02200441013602a4032004420237029403200441fcadcc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a104120042802800222120d0d0c020b2004200228020022123602e80220042802cc0120124b0d01200441a4036a41013602002004420237029403200441acaecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c0b0b200441a4036a4101360200200442023702940320044190afcc0036029003200441013602fc022004200441f8026a3602a0032004200441d8026a3602f80220044180026a20044190036a10410c0a0b200241146a21022001416c6a22010d000c040b0b20042902ec0221110c0b0b41c0dacb0041c8004188dbcb001064000b4190dacb00411e41b0dacb001064000b201341ffffffff0171450d00200e10350b200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d00004103470d000b200441186a200a10bf03200428021c2202450d002004280218210a200241286c210941002102034002400240024002400240200a20026a220141186a2d00000e0401000302010b200141206a2802004101470d032001411c6a28020021122004200141246a28020022013602d802201220014d0d03200441023602a4032004420237029403200441d0aacc00360290032004410136028c022004410136028402200420123602e802200420044180026a3602a0032004200441e8026a360288022004200441d8026a36028002200441f8026a20044190036a104120042802f80222120d0c0c030b20042001411c6a28020022013602e80220042802e40120014b0d02200441a4036a41013602002004420237029403200441f0aecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c060b2001411a6a2d0000450d012001410c6a2802002102200141146a280200210120044190036a41146a4101360200200420013602fc02200420023602f802200441043602ec022004420137029403200441e8dbcb00360290032004200441f8026a3602e8022004200441e8026a3602a00320044180026a20044190036a10410c050b20044190036a2001411c6a10b7072004280290032212450d0020042902940321110c0a0b2009200241286a2202470d000b0b024002400240200441b8016a41146a280200220241014b0d0020042802c001220241014b0d01200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d0000410d470d000b200441106a200a10bf03200428021022022004280214411c6c6a210a0240024003402002200a460d032004200228020022013602e802024020042802c00120014b0d00200441013602a4032004420237029403200441fcadcc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10412004280280022212450d0020042902840221110c0f0b200241046a2202280200450d0120044190036a200220042802d00120042802d80110b80720042d0090034101460d02200241186a210220042d009103450d000b412010332212450d06201241186a41002900c1dc4b370000201241106a41002900b9dc4b370000201241086a41002900b1dc4b370000201241002900a9dc4b37000042a0808080800421110c0d0b412910332212450d05201241286a41002d00a8dc4b3a0000201241206a41002900a0dc4b370000201241186a4100290098dc4b370000201241106a4100290090dc4b370000201241086a4100290088dc4b37000020124100290080dc4b37000042a9808080900521110c0c0b20044198036a290300211120042802940321120c0b0b200541306c2102200641546a2101024003402002450d01200241506a21022001412c6a2112200141306a220a210120122d0000410a470d000b200441086a200a10bf03200428020c2202450d00200428020822092002411c6c6a210c024002400240024003402009450d052004200928020022023602e80220042802cc0120024d0d082009280204450d0120044190036a200941046a20042802d00120042802d80110b80720042d0090034101460d0220042d0091030d032004200910bf070240024020042802042202450d00200428020021012002410274211220042802f001210a03402004200128020022023602d802200a20024d0d07200420042802e80120024102746a28020022023602e80220042802e40120024d0d02200141046a21012012417c6a22120d000b0b2009411c6a2209200c460d060c010b0b200441013602a4032004420237029403200441f0aecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c090b412a10332212450d07201241286a41002f00f1dc4b3b0000201241206a41002900e9dc4b370000201241186a41002900e1dc4b370000201241106a41002900d9dc4b370000201241086a41002900d1dc4b370000201241002900c9dc4b37000042aa808080a00521110c0e0b20044198036a290300211120042802940321120c0d0b412010332212450d05201241186a41002900c1dc4b370000201241106a41002900b9dc4b370000201241086a41002900b1dc4b370000201241002900a9dc4b37000042a0808080800421110c0c0b200441a4036a41013602002004420237029403200441ccaecc0036029003200441013602fc022004200441f8026a3602a0032004200441d8026a3602f80220044180026a20044190036a10410c050b024020042802bc012202450d002002410c6c450d0020042802b80110350b0240200441c8016a2802002202450d002002410c6c450d0020042802c40110350b0240200441d4016a28020041808080807872418080808078460d0020042802d00110350b0240200441e4016a2802002201450d0020042802dc0121022001410474210103400240200241046a280200450d00200228020010350b200241106a2102200141706a22010d000b0b0240200441e0016a28020041ffffffff0071450d0020042802dc0110350b0240200441ec016a28020041ffffffff0371450d0020042802e80110350b200f41808080807872418080808078460d0d200b10350c0d0b20044190036a41146a41013602002004420137029403200441f0dbcb0036029003200441013602fc02200420023602e8022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c030b200441a4036a41013602002004420137029403200441f8dbcb0036029003200441013602fc02200420023602e8022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c020b200441a4036a41013602002004420237029403200441acaecc0036029003200441013602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410c010b1045000b200428028002211220042902840221110c050b200441a4036a41013602002004420137029403200441e0dbcb00360290032004413b3602fc022004200441f8026a3602a0032004200441e8026a3602f80220044180026a20044190036a10410b20042802800221120b2004290284022111201341ffffffff0171450d02200e10350c020b200441a4036a41023602002004418c026a4101360200200442023702940320044180dacb00360290032004410136028402200420044180026a3602a0032004200441f8016a360288022004200441f4016a36028002200441f8026a20044190036a104120042802f80221120b20042902fc0221110b024020042802bc012202450d002002410c6c450d0020042802b80110350b0240200441c8016a2802002202450d002002410c6c450d0020042802c40110350b0240200441d4016a28020041808080807872418080808078460d0020042802d00110350b0240200441e4016a2802002201450d0020042802dc0121022001410474210103400240200241046a280200450d00200228020010350b200241106a2102200141706a22010d000b0b0240200441e0016a28020041ffffffff0071450d0020042802dc0110350b0240200441ec016a28020041ffffffff0371450d0020042802e80110350b200f41808080807872418080808078460d01200b10350c010b20022902042111200228020021120240200f41808080807872418080808078460d00200b10350b0240200428027c2202450d002002410c6c450d00200428027810350b02402004280288012202450d002002410c6c450d0020042802840110350b024020042802940141808080807872418080808078460d0020042802900110350b024020042802a4012201450d00200428029c0121022001410474210103400240200241046a280200450d00200228020010350b200241106a2102200141706a22010d000b0b024020042802a00141ffffffff0071450d00200428029c0110350b20042802ac0141ffffffff0371450d0020042802a80110350b2012450d0002402011a7450d00201210350b200041b6d3cb0036020420004101360200200041086a41133602002006200510f4062007450d01200741306c450d01200610350c010b2000201036020420004100360200200041186a2003360200200041146a2005360200200041106a20073602002000410c6a2006360200200041086a20083602000b200441d0036a24000f0b103c000bc31401187f23004190026b220224000240024002400240024020002802002203450d00200028020421040c010b41002104200241216a410041d800109f081a200241076a220542003700002002420037010241ec0010332203450d0120034100360200200320022902003702042003410b6a2005290000370000200341136a200241206a41d900109d081a20004100360204200020033602000b200220003602282002200336022420022004360220200141ff017121060240024002400340200341066a210720032f01062108410c2109410021050240034020082005460d01200320056a210a200941086a2109200541016a210502404100417f4101200a41086a2d0000220a20064b1b200a2006461b41016a0e03000401000b0b2005417f6a21080b02402004450d002004417f6a2104200320084102746a41ec006a28020021030c010b0b200241c0016a2008360200200241bc016a2000360200200241b0016a41086a20033602002002200036022820022003360224200241003602b4012000200028020841016a36020802400240024020032f01062205410b490d00200241206a41016a410041d800109f081a200241003a001141ec0010332206450d06200641003602002006410036000f20064200370007200620022f01103b0005200641136a200241206a41d900109d081a2003410e6a2d0000210b2003280248210c2003280244210d200641086a2003410f6a20032f010641796a2205109d082109200641146a200341cc006a2005410374109d082104200341063b0106200620053b010620084107490d0120092008417a6a220a6a2009200841796a22086a2209200541ffff037120086b109e081a200920013a00002004200a4103746a200420084103746a2205200641066a22072f010020086b410374109e081a2005410136020020072f010021050c020b200341086a2209200841016a22066a200920086a2209200520086b2200109e081a200920013a0000200341146a220920064103746a200920084103746a22092000410374109e081a200941013602002003200541016a3b01060c040b200341086a2205200841016a22096a200520086a220420072f0100220520086b220a109e081a200420013a0000200341146a220420094103746a200420084103746a2209200a410374109e081a200941013602000b2007200541016a3b01000240200328020022050d00410021010c020b200241206a41016a210e200241a8016a210f200241a0016a211020024198016a211120024190016a211220024180016a41086a211341002101034020062114200c2115200d2116200b211720032f01042104024002400240200522032f01062205410b490d00200e410041d800109f081a200241003a0011200220022f01103b0100200241b0016a200241206a41d900109d081a200f4200370300201042003703002011420037030020124200370300201342003703002002420037038001419c0110332206450d07200641003602002006410036000f20064200370007200620022f01003b0005200641136a200241b0016a41d900109d081a20064194016a200f2903003702002006418c016a201029030037020020064184016a2011290300370200200641fc006a2012290300370200200641f4006a2013290300370200200620022903800137026c2003410e6a2d0000210b2003280248210c2003280244210d200641086a2003410f6a20032f0106220941796a2205109d082118200641146a200341cc006a2005410374109d082119200641ec006a20034188016a2009417a6a220a410274109d082107200341063b0106200620053b01060240200a450d00410021052007210903402009280200220820053b010420082006360200200941046a2109200a200541016a2205470d000b0b20044107490d0120182004417a6a22096a2018200441796a22056a220820062f010620056b109e081a200820173a0000201920094103746a201920054103746a220820062f010620056b410374109e081a2008201636020020082015360204200620062f010641016a22083b01062004410274221520076a416c6a200720094102746a220a200841ffff0371220420096b410274109e081a200a201436020020042009490d02200620156a41d4006a2109034020092802002208200541016a22053b010420082006360200200941046a210920052004490d000c030b0b200341086a2206200441016a22096a200620046a2206200520046b2208109e081a200620173a0000200341146a220620094103746a200620044103746a22062008410374109e081a20062016360200200620153602042003200541016a22053b01062004410274200341ec006a22066a41086a200620094102746a2206200541ffff0371220820096b410274109e081a20062014360200200420084f0d0520032009417f6a22054102746a41f0006a2109034020092802002206200541016a22053b010420062003360200200941046a210920052008490d000c060b0b200341086a2209200441016a22056a200920046a220920032f0106220820046b220a109e081a200920173a0000200341146a220920054103746a200920044103746a2209200a410374109e081a20092016360200200920153602042003200841016a22093b010620044102742207200341ec006a22086a41086a200820054102746a220a200941ffff0371220820056b410274109e081a200a2014360200200420084f0d00200320076a41f0006a2105034020052802002209200441016a22043b010420092003360200200541046a210520082004470d000b0b200141016a210120032802002205450d020c000b0b200241c0016a2005417f6a360200200241bc016a2000360200200241b8016a20033602002002200036022820022003360224200220043602b401200320096a42013702000c010b200241206a41016a410041d800109f081a200241076a22034200370000200242003701022002200229020037031020022003290000370017200241b0016a200241206a41d900109d081a200241a8016a22054200370300200241a0016a2209420037030020024198016a2208420037030020024190016a2204420037030020024188016a220a42003703002002420037038001419c0110332203450d0120034100360200200320022903103702042003410b6a2002290017370000200341136a200241b0016a41d900109d081a20034194016a20052903003702002003418c016a200929030037020020034184016a2008290300370200200341fc006a2004290300370200200341f4006a200a290300370200200320022903800137026c20032000280200220536026c2000200336020020002000280204220941016a360204200541003b01042005200336020020092001470d0220032f01062205410a4b0d03200320054103746a220941186a200c360200200941146a200d360200200320056a41086a200b3a00002003200541016a22054102746a41ec006a2006360200200320053b0106200620053b0104200620033602000b20024190026a24000f0b103c000b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000bf42a11017f017e097f017e017f017e037f017e017f017e017f017e017f017e0c7f037e017f230041b0026b220224004200210320024184016a4200370200200241fc006a4280808080c000370200200241ec006a4200370200200241e4006a4280808080c000370200200241d0006a4200370300200241c0006a4200370300200241386a4280808080c000370300200241286a4200370300200241206a4280808080c000370300200241106a4200370300200242043702742002420437025c20024204370348200242043703302002420437031820024280808080c00037030820024204370300200141106a28020021042001410c6a280200210520012802082106410021072002410036029001200241003602a001200241003602b0010240024020040d004104210841002101410021094100210a4100210b4104210c4200210d4104210e4200210f41042110410021114100210441042112420021134104211442002115410421164200211741042118420021190c010b200241f0016a410172211a200241f0016a410472211b200241c0016a41086a2109200241c0016a41186a210a200241c0016a41206a210b200241c0016a41276a211c4100211d4100211e4100211f4100212041002121410021224100211102400340200920062004417f6a220441306c6a220141096a290000370300200241c0016a41106a2223200141116a290000370300200a200141196a290000370300200b200141216a290000370300201c200141286a290000370000200220012900013703c00120012d000022014110460d01201a20022903c001370000201a41086a2009290300370000201a41106a2023290300370000201a41186a200a290300370000201a41206a200b290300370000201a41276a201c290000370000200220013a00f001410121160240024002400240024002400240024002402001417e6a2214410b4d0d00410121120c010b410121124101210e410121104101210c410121244101210141012123410121084101212502400240024002400240024002400240024002400240024002400240024002400240024020140e0c000102030405060a07190809000b20022903f801211520022802f40121082022450d1002402026422088a72201450d00200141047421232022210103400240200141046a280200450d00200128020010350b200141106a2101202341706a22230d000b0b202642ffffffff0083500d10202210350c100b4100212520022903f801211520022802f40121082021450d0e02402027422088a72201450d00200141286c21232021210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101202341586a22230d000b0b2027a72201450d0e200141286c450d0e202110350c0e0b4100211220022903f801211520022802f40121012020450d0c200f42ffffffff0383500d0c202010350c0c0b4100210e20022903f801211520022802f4012101201f450d0a2013a72223450d0a2023410c6c450d0a201f10350c0a0b4100211020022903f801211520022802f4012101201e450d08200da72223450d082023410c6c450d08201e10350c080b4100210c20022903f801211520022802f4012110201d450d0602402028422088a72201450d00201d20014104746a210e201d21240340024020242802082223450d0020242802002101202341047421230340024020012d00004109470d000240200141046a2225280200220828020441ffffffff0371450d0020082802001035202528020021080b200810350b200141106a2101202341706a22230d000b0b202441106a21010240202441046a28020041ffffffff0071450d00202428020010350b200121242001200e470d000b0b202842ffffffff0083500d06201d10350c060b4100212420022903f801211520022802f40121082007450d0402402003422088a72201450d00200141146c21232007210103400240200141046a280200450d00200128020010350b200141146a21012023416c6a22230d000b0b2003a72201450d04200141146c450d04200710350c040b200241a0026a41086a2201201b41086a2802003602002002201b2902003703a00202402002280290012223450d0020024190016a10b2072002280294012208450d002008411c6c450d00202310350b20024190016a41086a2001280200360200200220022903a0023703900141002101410121124101210e410121104101210c410121240c0f0b200241a0026a41086a2201201b41086a2802003602002002201b2902003703a002024020022802a0012223450d00200241a0016a10b30720022802a4012208450d00200841186c450d00202310350b200241a0016a41086a2001280200360200200220022903a0023703a00141002123410121124101210e410121104101210c41012124410121010c0f0b200241a0026a41086a2201201b41086a2802003602002002201b2902003703a002024020022802b0012223450d00200241b0016a10b40720022802b4012208450d002008411c6c450d00202310350b200241b0016a41086a2001280200360200200220022903a0023703b00141002108410121124101210e410121104101210c410121244101210141012123410121250c0f0b4101211220022802f40121294101210e410121104101210c410121244101210141012123410121084101212541012116410121110c0e0b2015210320082107410121124101210e410121104101210c0c0a0b201521282010211d410121124101210e410121100c080b2015210d2001211e410121124101210e0c060b201521132001211f410121120c040b2015210f200121200c020b2015212720082121410121124101210e410121104101210c410121244101210141012123410121080c080b2015212620082122410121124101210e410121104101210c4101212441012101410121234101210841012125410021160c070b4101210e0b410121100b4101210c0b410121240b410121010b410121230b41012108410121250b02400240024002400240024002400240024002400240024020022d00f0012218417e6a2214410b4b0d0020140e0c0a09080706050400030002010a0b02402018410e4b0d00024002400240024002400240024002400240024002400240024020180e0f0001020304050607081809180a0b0c000b20022802f801450d1720022802f40110350c170b024020022802f801450d0020022802f40110350b200228028402450d1620022802800210350c160b20022802f4012108024020022802fc012201450d00200141047421232008210103400240200141046a280200450d00200128020010350b200141106a2101202341706a22230d000b0b20022802f80141ffffffff0071450d15200810350c150b20022802f4012108024020022802fc012201450d00200141286c21232008210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101202341586a22230d000b0b20022802f8012201450d14200141286c450d14200810350c140b20022802f80141ffffffff0371450d1320022802f40110350c130b20022802f8012201450d122001410c6c450d1220022802f40110350c120b20022802f8012201450d112001410c6c450d1120022802f40110350c110b20022802f401210e024020022802fc012201450d00200e20014104746a210c200e21240340024020242802082223450d0020242802002101202341047421230340024020012d00004109470d000240200141046a2225280200220828020441ffffffff0371450d0020082802001035202528020021080b200810350b200141106a2101202341706a22230d000b0b202441106a21010240202441046a28020041ffffffff0071450d00202428020010350b200121242001200c470d000b0b20022802f80141ffffffff0071450d10200e10350c100b20022802f4012108024020022802fc012201450d00200141146c21232008210103400240200141046a280200450d00200128020010350b200141146a21012023416c6a22230d000b0b20022802f8012201450d0f200141146c450d0f200810350c0f0b201b10b20720022802f8012201450d0e2001411c6c450d0e20022802f40110350c0e0b201b10b30720022802f8012201450d0d200141186c450d0d20022802f40110350c0d0b201b10b40720022802f8012201450d0c2001411c6c450d0c20022802f40110350c0c0b024020022802f4012201450d0020022802f801450d00200110350b02402002280284022225450d000240200228028c022201450d002001410c6c2123202521010340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101202341746a22230d000b0b2002280288022201450d002001410c6c450d00202510350b200228029402220e450d0b0240200228029c022201450d00200e20014104746a210c200e212403402024222541106a2124024020252802042201450d0002402025410c6a2802002223450d002023410c6c21230340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101202341746a22230d000b0b202541086a2802002201450d002001410c6c450d00202528020410350b2024200c470d000b0b20022802980241ffffffff0071450d0b200e10350c0b0b024020022802f801450d0020022802f40110350b02402002280284022201450d00200228028802450d00200110350b20022802940241ffffffff0071450d0a20022802900210350c0a0b2008450d09201b10b40720022802f8012201450d092001411c6c450d0920022802f40110350c090b2023450d08201b10b30720022802f8012201450d08200141186c450d0820022802f40110350c080b2001450d07201b10b20720022802f8012201450d072001411c6c450d0720022802f40110350c070b2024450d0620022802f4012108024020022802fc012201450d00200141146c21232008210103400240200141046a280200450d00200128020010350b200141146a21012023416c6a22230d000b0b20022802f8012201450d06200141146c450d06200810350c060b200c450d0520022802f401210e024020022802fc012201450d00200e20014104746a210c200e21240340024020242802082223450d0020242802002101202341047421230340024020012d00004109470d000240200141046a2225280200220828020441ffffffff0371450d0020082802001035202528020021080b200810350b200141106a2101202341706a22230d000b0b202441106a21010240202441046a28020041ffffffff0071450d00202428020010350b200121242001200c470d000b0b20022802f80141ffffffff0071450d05200e10350c050b2010450d0420022802f8012201450d042001410c6c450d0420022802f40110350c040b200e450d0320022802f8012201450d032001410c6c450d0320022802f40110350c030b2012450d0220022802f80141ffffffff0371450d0220022802f40110350c020b2025450d0120022802f4012108024020022802fc012201450d00200141286c21232008210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101202341586a22230d000b0b20022802f8012201450d01200141286c450d01200810350c010b2016450d0020022802f4012108024020022802fc012201450d00200141047421232008210103400240200141046a280200450d00200128020010350b200141106a2101202341706a22230d000b0b20022802f80141ffffffff0071450d00200810350b20040d000b410021040b2003420020071b211920284200201d1b2103200d4200201e1b211720134200201f1b210d200f420020201b21152027420020211b210f2026420020221b21132007410420071b2118201d4104201d1b210c201e4104201e1b2116201f4104201f1b210e2020410420201b21142021410420211b21102022410420221b2112200228020821012002280200210820022902b401212820022802b001210920022902a401212720022802a001210a2002290294012126200228029001210b0b02402001450d00200141047421232008210103400240200141046a280200450d00200128020010350b200141106a2101202341706a22230d000b0b0240200228020441ffffffff0071450d00200810350b200228020c2108024020022802142201450d00200141286c21232008210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101202341586a22230d000b0b024020022802102201450d00200141286c450d00200810350b0240200228021c41ffffffff0371450d00200228021810350b024020022802282201450d002001410c6c450d00200228022410350b024020022802342201450d002001410c6c450d00200228023010350b200228023c211c024020022802442201450d00201c20014104746a2124201c211a03400240201a2802082223450d00201a2802002101202341047421230340024020012d00004109470d000240200141046a2225280200220828020441ffffffff0371450d0020082802001035202528020021080b200810350b200141106a2101202341706a22230d000b0b201a41106a21010240201a41046a28020041ffffffff0071450d00201a28020010350b2001211a20012024470d000b0b0240200228024041ffffffff0071450d00201c10350b20022802482108024020022802502201450d00200141146c21232008210103400240200141046a280200450d00200128020010350b200141146a21012023416c6a22230d000b0b0240200228024c2201450d00200141146c450d00200810350b200241dc006a10b207024020022802602201450d002001411c6c450d00200228025c10350b200241e8006a10b3070240200228026c2201450d00200141186c450d00200228026810350b200241f4006a10b407024020022802782201450d002001411c6c450d00200228027410350b2028420020091b212820274200200a1b212720264200200b1b21262009410420091b2101200a4104200a1b2123200b4104200b1b2108200228028001221a20022802880110f40602402002280284012225450d00202541306c450d00201a10350b200241d8006a202936020020022004360288012002200536028401200220063602800120022028370378200220013602742002202737026c20022023360268200220263703602002200836025c200220113602542002201937024c20022018360248200220033703402002200c36023c20022017370234200220163602302002200d3703282002200e3602242002201537021c200220143602182002200f3703102002201036020c200220133702042002201236020020002002418c01109d081a200241b0026a24000bd60401107f230041106b220224000240024020012802004101460d00200128020421030c010b200141106a2d000021042001410c6a2802002105200141086a280200210620012f0112210720012d0011210820012802042109200241086a200010bf0302400240200228020c220a450d0020022802082101200a41047441706a410476210b0240200841ff0171220c4104460d004100210a200441ff0171210d0340200a2103024020012d000c200d470d0020012802082005470d0002402001280200220a2009460d002005210e2009210f0340200e450d01200e417f6a210e200f2d00002110200a2d00002111200f41016a210f200a41016a210a20112010460d000c020b0b20012d000d220a200c470d00200a4104470d040b200141106a2101200341016a210a2003200b470d000c020b0b4100210a200441ff0171210d0340200a2103024020012d000c200d470d0020012802082005470d0002402001280200220a2009460d002005210e2009210f0340200e450d01200e417f6a210e200f2d00002110200a2d00002111200f41016a210f200a41016a210a20112010460d000c020b0b20012d000d4104460d030b200141106a2101200341016a210a2003200b470d000b0b024020002802082201200041046a280200470d00200020014101108c01200028020821010b200028020020014104746a220120073b010e200120083a000d200120043a000c2001200536020820012006360204200120093602002000200028020841016a3602082002200010bf032002280204417f6a21030c010b2006450d00200910350b200241106a240020030b9d1901217f23004180016b2202240041002103200241003602102002420437030820012802042104200128020021054101210641012107024020012802082208450d0041002107200241086a410041011089012002280208200228021041306c6a2203200836000c2003200436000820032005360004200341023a00002002200228021041016a22033602100b200141106a2802002109200128020c210a0240200141146a280200220b450d0002402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341033a00002003200b36000c200320093600082003200a36000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241206a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a2203360210410021060b2001411c6a280200210c2001280218210d4100210e02400240200141206a280200220f0d00410021100c010b02402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341043a00002003200f36000c2003200c3600082003200d36000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241206a290200370200200341206a200241286a290200370200200341286a200241186a41186a290200370200410121102002200228021041016a22033602100b200141286a28020021112001280224211202402001412c6a280200220f450d0002402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341053a00002003200f36000c200320113600082003201236000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241206a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702004101210e2002200228021041016a22033602100b200141346a28020021132001280230211402400240200141386a280200220f0d00410021150c010b02402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341063a00002003200f36000c200320133600082003201436000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241206a290200370200200341206a200241286a290200370200200341286a200241186a41186a290200370200410121152002200228021041016a22033602100b200141c0006a2802002116200128023c21174101211802400240200141c4006a28020022190d004101211a0c010b02402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341073a00002003201936000c200320163600082003201736000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241206a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a22033602104100211a0b200141cc006a280200211b2001280248211c0240200141d0006a280200221d450d0002402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341083a00002003201d36000c2003201b3600082003201c36000420032002290218370210200341036a200241f3006a2d00003a0000200341186a200241186a41086a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a2203360210410021180b4101211e024020012802544101470d00200141d8006a280200210f02402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022f00713b0001200341093a00002003200f36020420032002290218370208200341036a200241f3006a2d00003a0000200341106a200241206a290200370200200341186a200241186a41106a290200370200200341206a200241186a41186a290200370200200341286a200241186a41206a2902003702002002200228021041016a22033602100b200241c0006a41086a221f200141e4006a280200220f3602002002200129025c3703400240200f450d00200241fc006a201f2802003600002002200229034037007402402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022900713700012003410a3a000020032002290218370210200341086a200241f8006a290000370000200341186a200241186a41086a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a22033602104100211e0b200241d0006a41086a200141f0006a280200220f3602002002200129026837035002400240200f0d00410121200c010b200241fc006a200241d0006a41086a2802003600002002200229035037007402402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022900713700012003410c3a000020032002290218370210200341086a200241f8006a290000370000200341186a200241186a41086a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a2203360210410021200b200241e8006a221f200141fc006a280200220f3602002002200129027437036002400240200f0d00410121210c010b200241fc006a201f2802003600002002200229036037007402402003200228020c470d00200241086a20034101108901200228021021030b2002280208200341306c6a220320022900713700012003410d3a000020032002290218370210200341086a200241f8006a290000370000200341186a200241186a41086a290200370200200341206a200241286a290200370200200341286a200241186a41186a2902003702002002200228021041016a2203360210410021210b20014184016a280200210f200128028001211f200241086a200320014188016a28020041306c220141306d222210890120022802082002280210220341306c6a201f2001109d081a2002200320226a3602100240200f450d00200f41306c450d00201f10350b200241186a41086a2201200241086a41086a280200360200200220022903083703180240024041800610332203450d0020004280c2cdeb1637020020002002290318370208200041106a2001280200360200200310352021450d01200241e0006a10b40720022802642201450d012001411c6c450d01200228026010350c010b1045000b02402020450d00200241d0006a10b30720022802542201450d00200141186c450d00200228025010350b0240201e450d00200241c0006a10b20720022802442201450d002001411c6c450d00200228024010350b02402018450d000240201d450d00201d41146c2103201c210103400240200141046a280200450d00200128020010350b200141146a21012003416c6a22030d000b0b201b450d00201b41146c450d00201c10350b0240201a450d0002402019450d00201720194104746a211e201721180340024020182802082203450d0020182802002101200341047421030340024020012d00004109470d000240200141046a220f280200220028020441ffffffff0371450d0020002802001035200f28020021000b200010350b200141106a2101200341706a22030d000b0b201841106a21010240201841046a28020041ffffffff0071450d00201828020010350b200121182001201e470d000b0b201641ffffffff0071450d00201710350b02402013452015720d002013410c6c450d00201410350b0240201145200e720d002011410c6c450d00201210350b0240200c41ffffffff0371410047201041017371450d00200d10350b02402006450d000240200b450d00200b41286c2103200a210103400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101200341586a22030d000b0b2009450d00200941286c450d00200a10350b02402007450d0002402008450d00200841047421032005210103400240200141046a280200450d00200128020010350b200141106a2101200341706a22030d000b0b200441ffffffff0071450d00200510350b20024180016a24000ba01302147f027e23004180026b220424000240024020014115490d0041012105410121060240024002400340200121072000210820052006714101732109024002400240024002400240034002400240024002402003450d00024020054101710d002000200110c8072003417f6a21030b2001410276220a41036c210b200a410174210c4100210d024020014132490d00200b200b417f6a220d2000200b4103746a280200220e2000200d4103746a280200220f4922101b2211200b41016a2212200d200b20101b200020124103746a280200220b200f200e20101b220d49220f1b200b200d200f1b200020114103746a2802004922131b210b200c200c417f6a220d2000200c4103746a28020022112000200d4103746a280200221249220e1b2214200c4101722206200d200c200e1b200020064103746a280200220c20122011200e1b220d4922111b200c200d20111b200020144103746a2802004922141b210c200a200a417f6a22122000200a4103746a2802002206200020124103746a280200221549220d1b2216200a41016a22172012200a200d1b200020174103746a280200220a20152006200d1b22064922121b200a200620121b200020164103746a2802004922061b210a41024101200d1b200d20121b20066a200e6a20116a20146a20106a200f6a20136a210d0b200d2000200c4103746a280200220e2000200a4103746a280200220f4922106a2000200b4103746a280200220d200f200e20101b221149220f6a210e200d2011200f1b2000200c200a20101b220d4103746a280200490d01200b200a200c20101b200f1b210d0c020b2000200110d9070c0f0b200e41016a220e410c490d0002402001410176220b450d00200020014103746a41786a210a2000210c0340200c2902002118200c200a290200370200200a2018370200200c41086a210c200a41786a210a200b417f6a220b0d000b0b2001200d417f736a210d4101210a0c010b200e45210a0b0240200a452009724101710d002000200110da070d0d0b2002450d02200d20014f0d01024020022802002000200d4103746a220a2802004f0d0020002108200121070c040b200029020021182000200a290200370200200a2018370200200041786a210f200041086a211120002902002218a721104100210c2001210b03400240200c200b417f6a220d4f0d002011200c4103746a210a0340200a28020020104b0d01200a41086a210a200d200c41016a220c470d000b200d210c0b200f200b4103746a210a02400340200c200b417f6a220b4f0d01200a280200210d200a41786a220e210a200d20104b0d000b2011200c4103746a220a2902002119200a200e41086a220d290200370200200d2019370200200c41016a210c0c010b0b2000201837020002402001200c41016a220a490d002000200a4103746a21002001200a6b220141154f0d010c0c0b0b200a200141e485cc001059000b200d200141d086cc001042000b2007450d010b200d20074f0d012008290200211820082008200d4103746a220a290200370200200a2018370200200841086a210e20082902002219a72111410021142007417f6a2210450d02200e210a0340200a28020020114f0d03200a41086a210a2010201441016a2214470d000b201021140c020b4100410041f485cc001042000b200d2007418486cc001042000b200820074103746a210c2010210b02400340200c210d200b220a20144d22060d01200a417f6a210b200d41786a220c28020020114f0d000b0b0240200a2014490d002010200a490d0241800121054100210b410021014100210c4100210f4180012109200e20144103746a2215211003400240200d20106b220a4187104b22130d00200a410376220a41807f6a200a2001200b49200f200c49220e7222001b210a02402000450d002009200a200e1b2109200a2005200e1b21050c010b200a200a41017622096b21050b0240200f200c470d00024020090d002004220c210f0c010b4100210a2004220f210c2010210e0340200c200a3a0000200c200e28020020114f6a210c200e41086a210e2009200a41016a220a470d000b0b02402001200b470d00024020050d0020044180016a220b21010c010b200d41786a210a4100210e20044180016a2201210b0340200b200e3a0000200b200a2802002011496a210b200a41786a210a2005200e41016a220e470d000b0b0240200b20016b220a200c200f6b220e200e200a4b1b2212450d002010200f2d00004103746a220a2902002118200a200d20012d0000417f734103746a290200370200024020124101460d004100210a0340200d2001200a6a220e2d0000417f734103746a2010200f200a6a41016a22002d00004103746a290200370200201020002d00004103746a200d200e41016a2d0000417f734103746a290200370200200a41026a210e200a41016a2200210a200e2012490d000b200120006a2101200f20006a210f0b200d20012d0000417f734103746a2018370200200141016a2101200f41016a210f0b200d20054103746b200d2001200b461b210d201020094103746a2010200f200c461b211020130d000b02400240200f200c4f0d00200d210a03402010200c417f6a220c2d00004103746a220b2902002118200b200a41786a220a290200370200200a2018370200200f200c490d000c020b0b2010210a2001200b4f0d000340200a2902002118200a200d200b417f6a220b2d0000417f734103746a220c290200370200200c2018370200200a41086a210a2001200b490d000b0b200820193702002007200a20156b41037620146a22014d0d032008200820014103746a220a290200370200200a2019370200200720016b220c450d04200c20012001200c4b1b210b2007410376210d200a41086a2100024002402001200c417f6a220c490d002000200c200a200310f206200821000c010b200820012002200310f206200a2102200c21010b200b200d4f2105200141154f0d010c050b0b2014200a419486cc001059000b200a2010419486cc001058000b20012007418486cc001042000b41a486cc00411c41c086cc00103f000b20014102490d00200041786a21104100210e4101210b0340200b410374210c200b417f6a210a200b41016a210b02402000200c6a220d2802002000200a4103746a220f2802004f0d00200d2902002118200d200f2902003702000240200a450d00200e210c2010210a200d41706a2802002018a7220d4d0d00024002400340200a41086a200a290200370200200c4101460d01200c417f6a210c200a41786a220a280200200d4b0d000c020b0b4100210c0b2000200c4103746a210f0b200f20183702000b200e41016a210e201041086a2110200b2001470d000b0b20044180026a24000b9c0402077f017e230041306b22022400200241106a2203200141246a290200370300200241086a22042001411c6a29020037030020022001290214370300200241186a41106a2205200141106a280200360200200241186a41086a2206200141086a290200370300200220012902003703182000200241186a10f00621070240200041206a28020022082000411c6a280200470d00200041186a20084101108601200028022021080b200028021820084102746a20073602002000200028022041016a3602202005200329030037030020062004290300370300200220022903003703180240200041f0006a22032802002208200041ec006a280200470d000240024002400240200841016a22042008490d00200841017422052004200520044b1bad42187e2209422088a70d002009a722044100480d00024020080d0020040d02410421050c040b20002802682105200841186c22082004460d03024020080d0020040d02410421050c040b20052008200410372205450d020c030b103e000b2004103322050d010b103c000b20002005360268200041ec006a200441186e360200200041f0006a28020021080b2000280268200841186c6a22082002290318370200200841106a200241186a41106a290300370200200841086a200241186a41086a29030037020020032003280200220841016a360200024020012d002c450d0020004101360254200041d8006a20083602000b200241306a24000bcf0f01077f02402001450d002000200141306c6a210203402000220341306a21000240024020032d00002201410e4b0d00024002400240024002400240024002400240024002400240024020010e0f0001020304050607080e090e0a0b0c000b200341086a280200450d0d200341046a28020010350c0d0b0240200341086a280200450d00200341046a28020010350b200341146a280200450d0c200341106a28020010350c0c0b02402003410c6a2802002204450d00200341046a28020021012004410474210403400240200141046a280200450d00200128020010350b200141106a2101200441706a22040d000b0b200341086a28020041ffffffff0071450d0b200328020410350c0b0b02402003410c6a2802002204450d00200341046a2802002101200441286c210403400240200141046a280200450d00200128020010350b0240200141106a280200450d002001410c6a28020010350b200141286a2101200441586a22040d000b0b200341086a2802002201450d0a200141286c450d0a200328020410350c0a0b200341086a28020041ffffffff0371450d09200341046a28020010350c090b200341086a2802002201450d082001410c6c450d08200341046a28020010350c080b200341086a2802002201450d072001410c6c450d07200341046a28020010350c070b02402003410c6a2802002201450d00200341046a280200220520014104746a21060340024020052802082204450d0020052802002101200441047421040340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d0020082802001035200728020021080b200810350b200141106a2101200441706a22040d000b0b200541106a21010240200541046a28020041ffffffff0071450d00200528020010350b2001210520012006470d000b0b200341086a28020041ffffffff0071450d06200328020410350c060b02402003410c6a2802002204450d00200341046a2802002101200441146c210403400240200141046a280200450d00200128020010350b200141146a21012004416c6a22040d000b0b200341086a2802002201450d05200141146c450d05200328020410350c050b02402003410c6a2802002201450d00200341046a28020022052001411c6c6a21060340024020052802042201450d0002402005410c6a2802002204450d00200441047421040340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d0020082802001035200728020021080b200810350b200141106a2101200441706a22040d000b0b200541086a28020041ffffffff0071450d00200528020410350b2005411c6a21010240200541146a28020041ffffffff0371450d00200528021010350b2001210520012006470d000b0b200341086a2802002201450d042001411c6c450d04200328020410350c040b02402003410c6a2802002201450d00200341046a2802002205200141186c6a210603400240200541046a28020041ffffffff0171450d00200528020010350b0240200541146a2802002204450d00200528020c2101200441047421040340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d0020082802001035200728020021080b200810350b200141106a2101200441706a22040d000b0b200541186a21010240200541106a28020041ffffffff0071450d00200528020c10350b2001210520012006470d000b0b200341086a2802002201450d03200141186c450d03200328020410350c030b02402003410c6a2802002201450d00200341046a28020022052001411c6c6a21060340024020052802042201450d0002402005410c6a2802002204450d00200441047421040340024020012d00004109470d000240200141046a2207280200220828020441ffffffff0371450d0020082802001035200728020021080b200810350b200141106a2101200441706a22040d000b0b200541086a28020041ffffffff0071450d00200528020410350b2005411c6a21010240200541146a280200450d00200528021010350b2001210520012006470d000b0b200341086a2802002201450d022001411c6c450d02200328020410350c020b0240200341046a2802002201450d00200341086a280200450d00200110350b0240200341146a2802002201450d0002402003411c6a2802002204450d002004410c6c21040340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101200441746a22040d000b0b200341186a2802002201450d002001410c6c450d00200328021410350b200341246a2802002205450d0102402003412c6a2802002201450d00200520014104746a210603402005220741106a2105024020072802042201450d0002402007410c6a2802002204450d002004410c6c21040340024020012802002208450d00200141046a280200450d00200810350b2001410c6a2101200441746a22040d000b0b200741086a2802002201450d002001410c6c450d00200728020410350b20052006470d000b0b200341286a28020041ffffffff0071450d01200328022410350c010b0240200341086a280200450d00200341046a28020010350b0240200341146a2802002201450d00200341186a280200450d00200110350b200341246a28020041ffffffff0071450d00200341206a28020010350b20002002470d000b0b0b8f7205077f017e277f047e077f23002203210420034180096b416071220324000240411010332205450d00200541063a0000412010332206450d00200641063a001020064100360204200620032f00e0043b00012006412d3a0000200641036a200341e2046a2d00003a0000024020052d00004109470d0002402005280204220728020441ffffffff0371450d0020072802001035200528020421070b200710350b20051035200141106a28020041306c2105200128020841546a21070240024002400240024002400240024002400340024020050d00411010332207450d0b20074180023b010c200742828080802037020420072006360200200720032f01d0033b010e200128021022052001410c6a280200470d03200541016a22082005490d05200541017422092008200920084b1bad42307e220a422088a70d05200aa722084100480d050240024020050d0020080d01410421090c040b20012802082109200541306c22052008460d03024020050d0020080d01410421090c040b20092005200810372209450d0c0c030b2008103322090d020c0b0b200541506a21052007412c6a2108200741306a2209210720082d00004107470d000b200320032f01d0033b01e0040240200941086a22072802002205200941046a280200470d00200920054101108c01200728020021050b200928020020054104746a22054180023b010c200542828080802037020420052006360200200520032f01e0043b010e2007200728020041016a360200200341306a200910bf032003280234417f6a210b2001280210210c0c020b200120093602082001410c6a200841306e360200200128021021050b2001280208200541306c6a220520032f00f0073b0001200541073a0000200542818080801037000820052007360004200520032902e004370210200541036a200341f2076a2d00003a0000200541186a200341e8046a290200370200200541206a200341f0046a290200370200200541286a200341e0046a41186a2902003702002001200128021041016a220c3602104100210b0b200c41306c21052001280208220d41546a210702400340410021082005450d01200541506a21052007412c6a2109200741306a2206210720092d00004103470d000b200641086a2802002205450d00200541286c2107200628020041186a2105410021080340200820052d0000456a2108200541286a2105200741586a22070d000b0b200c41306c2105200d41546a210702400340410021092005450d01200541506a21052007412c6a2106200741306a220e210720062d00004103470d000b200e41086a2802002205450d00200541286c2107200e28020041186a2105410021090340200920052d0000456a2109200541286a2105200741586a22070d000b0b200c41306c2105200d415c6a210702400340024020050d00410021050c020b200541506a2105200741246a2106200741306a220e210720062d00004104470d000b200e28020021050b200341003602d00302400240200520096a220d0d004104210f41002110410021110c010b0240024002402008450d00200342003703e004410021050c010b200341e0046a4100200110e40720032802e404210520032802e0044101470d00200341e8046a290300210a024020032802d0032207450d0020032802d403450d00200710350b2003200a3702d403200320053602d003410021114104210f410021100c010b41041033220c450d07200c200536020020034281808080103702f4072003200c3602f0070240200d4102490d0002400240024020084102490d00200342003703e0044100210e0c010b200341e0046a4101200110e40720032802e404210e20032802e0044101470d00200341e8046a290300210a024020032802d003450d0020032802d403450d0020032802d00310350b2003200a3702d4030c010b4104210941012106410121070340200741016a2105024020072006470d00200341f0076a2006410110860120032802f007210c0b200c20096a200e360200200320053602f8072005200d4f0d0202400240200820054d0d00200342003703e0044100210e0c010b200341e0046a2005200110e40720032802e404210e20032802e0044101470d0020032903e804210a024020032802d003450d0020032802d403450d0020032802d00310350b2003200a3702d4030c020b200941046a210920032802f4072106200521070c000b0b2003200e3602d0030b20032802d003210520032802f807211020032802f407211120032802f007210f0b2005450d0020032902d403210a0240201141ffffffff0371450d00200f10350b2000200536020420004101360200200041086a200a3702000c040b024020012802102205450d0020012802082212200541306c6a2113200341e0046a41106a2114200341d0066a210e20034184056a211520034194056a2116200341a4056a2117200341b4056a2118200341c4056a2119200341d4056a211a200341e4056a211b200341f4056a211c20034184066a211d20034194066a211e200341a4066a211f200341b4066a2120200341c4066a21210340024020122d0000410c470d00201228020c2205450d0020122802042206200541186c6a212203400240200641146a22232802002205450d002006410c6a21244100210c034002400240024002400240200c20054f0d00410121052024280200200c410474220d6a22072d0000410b470d042003200741046a22073602c0022007280200220720104f0d01200f20074102746a2802002208450d042003200b3602c406200341133a00c006200341d7003a00b006200320083602a4062003412d3a00a0062003200b36029406200341123a00900620032007360284062003410b3a008006200341063a00f005200341003a00e00520034184083b01d005200341373a00c005200320023602b4052003412d3a00b0052003200b3602a405200341123a00a0052003200b36029405200341133a009005200341d6003a008005200320083602f4042003412d3a00f0042003200b3602e404200341123a00e004200c41016a212520232802002226200c4d0d022023200c360200200628020c2205202541047422276a2108024002402005200d6a22282d0000220941ac01470d00202841106a21090c010b4100210502400340202820056a21070240200941ff01714109470d000240200741046a280200220928020441ffffffff0371450d00200928020010350b200910350b2005450d01200541106a2105200741106a2d0000220941ac01470d000b202820056a41106a21090c010b200741106a21090b202620256b212920082107024020092008460d0002400340200922052d0000220741ac01460d01024020074109470d000240200541046a280200220728020441ffffffff0371450d00200728020010350b200710350b200541106a22092008470d000b0b200541106a21070b02400240024002402029450d00200341e0046a21050240202520062802142209460d00200d200941047422056b41106a210d200628020c20056a2109200341e0046a21050340200341f0076a41002005200e200546222a1b10e30720032d00f00741ac01460d052005200541106a202a1b2105200920032903f007370300200941086a200341f0076a41086a2903003703002006200628021441016a360214200941106a2109200d41706a220d0d000b0b200e20056b220d41047621090240200d450d00202420262009109a01200628020c222a202520096a22254104746a202a20276a2029410474109e081a20252006280214222a460d00200c200d4104766a410474202a41047422096b41106a210d200628020c20096a21090340200341f0076a41002005200e200546222a1b10e30720032d00f00741ac01460d052005200541106a202a1b2105200920032903f007370300200941086a200341f0076a41086a2903003703002006200628021441016a360214200941106a2109200d41706a220d0d000b200e20056b41047621090b200341003602d803200342083703d003200341d0036a41002009109a0120032802d803210d20032802d003212b200341f0076a41002005200e20054622091b10e307024020032d00f00741ac01460d002005200541106a20091b2105202b200d4104746a21090340200920032903f007370300200941086a200341f0076a41086a290300370300200341f0076a41002005200e200546222a1b10e3072005200541106a202a1b2105200d41016a210d200941106a210920032d00f00741ac01470d000b0b202b200d41047422266a212a20032802d403212c200d0d01202b21050c020b20242023280200410f109a012023280200210d200628020c2105200341f0076a200341e0046a10e307024020032d00f00741ac01460d002005200d4104746a2109201421050340200920032903f007370300200941086a200341f0076a41086a290300370300200341f0076a41002005200e200546222a1b10e3072005200541106a202a1b2105200d41016a210d200941106a210920032d00f00741ac01470d000b0b2023200d3602000c020b2024202920256a20264104752205109a0120254104742109200628020c220d202520056a222541047422056a200d20096a2029410474109e081a0240202520062802142209470d00202b21050c010b200628020c220d20056a212d200d20094104746a210d202b21090340024020260d00202a21050c020b200341f0076a41026a2205200941036a2d00003a0000200320092f00013b01f007024020092d0000222741ac01470d00200941106a21050c020b200941046a280200212e200941086a290300210a200d20273a0000200d41086a200a370300200d41046a202e36020020032f01f0072127200d41036a20052d00003a0000200d41016a20273b00002006200628021441016a360214202641706a2126200941106a22052109200d41106a220d202d470d000b0b0240202a2005460d000340200541106a2109024020052d00004109470d000240200541046a220d280200220528020441ffffffff0371450d0020052802001035200d28020021050b200510350b20092105202a2009470d000b0b202c41ffffffff0071450d00202b10350b20072008460d0303400240024020072d000022054109460d00200541ac01470d0120282007460d06200741106a2105034020052d0000220741ac01460d07024020074109470d000240200541046a280200220728020441ffffffff0371450d00200728020010350b200710350b200541106a22052008470d000c070b0b0240200741046a280200220528020441ffffffff0371450d00200528020010350b200510350b200741106a22072008470d000c040b0b200c2005418490cc001042000b200341013602f404200342013702e4042003419490cc003602e0042003413c3602d4032003200341d0036a3602f0042003200341c0026a3602d003200341f0076a200341e0046a104120032802f0072205450d0420032902f407210a2000200536020420004101360200200041086a200a370200201141ffffffff0371450d0c200f10350c0c0b20252026104f000b02402029450d000240202520232802002205460d002024280200220720054104746a200720254104746a2029410474109e081a0b2023202920056a3602000b024020032d00e0044109470d00024020032802e404220528020441ffffffff0371450d002005280200103520032802e40421050b200510350b024020032d00f0044109470d000240200341e0046a41146a280200220528020441ffffffff0371450d002005280200103520032802f40421050b200510350b024020032d0080054109470d0002402015280200220528020441ffffffff0371450d002005280200103520032802840521050b200510350b024020032d0090054109470d0002402016280200220528020441ffffffff0371450d002005280200103520032802940521050b200510350b024020032d00a0054109470d0002402017280200220528020441ffffffff0371450d002005280200103520032802a40521050b200510350b024020032d00b0054109470d0002402018280200220528020441ffffffff0371450d002005280200103520032802b40521050b200510350b024020032d00c0054109470d0002402019280200220528020441ffffffff0371450d002005280200103520032802c40521050b200510350b024020032d00d0054109470d000240201a280200220528020441ffffffff0371450d002005280200103520032802d40521050b200510350b024020032d00e0054109470d000240201b280200220528020441ffffffff0371450d002005280200103520032802e40521050b200510350b024020032d00f0054109470d000240201c280200220528020441ffffffff0371450d002005280200103520032802f40521050b200510350b024020032d0080064109470d000240201d280200220528020441ffffffff0371450d002005280200103520032802840621050b200510350b024020032d0090064109470d000240201e280200220528020441ffffffff0371450d002005280200103520032802940621050b200510350b024020032d00a0064109470d000240201f280200220528020441ffffffff0371450d002005280200103520032802a40621050b200510350b024020032d00b0064109470d0002402020280200220528020441ffffffff0371450d002005280200103520032802b40621050b200510350b024020032d00c0064109470d0002402021280200220528020441ffffffff0371450d002005280200103520032802c40621050b200510350b410f21050b2005200c6a220c20232802002205490d000b0b200641186a22062022470d000b0b201241306a22122013470d000b0b200341386a41106a200141106a280200220c360200200341386a41086a200141086a290200220a37030020032001290200370338410021062003410036025820034204370350200c41306c2105200aa7220d41546a210702400340024020050d000c020b200541506a21052007412c6a2108200741306a2209210720082d00004108470d000b200341286a200910bf0320032802282106200328022c21050b4100210e2005410020061b212a200c41306c2105200d41546a2108200641b0b4cc0020061b210702400340024020050d000c020b200541506a21052008412c6a2109200841306a2206210820092d0000410a470d000b200341206a200610bf032003280220210e200328022421050b20054100200e1b2128200c41306c2105200d41546a2109200e41b0b4cc00200e1b210802400340024020050d004200210a0c020b200541506a21052009412c6a2106200941306a220e210920062d00004109470d000b200e28020021054201210a0b20034100360278200341003602702007202a41146c6a212520082028411c6c6a21242005ad422086200a84210a200341f0076a410272221541266a2116201541206a2117201541186a2118201541106a2119201541086a211a200341f0076a41286a211b4100212a410121260240024003400240024002400240024020264102460d000240024002402007450d0020252007460d000340200741146a21092007410c6a280200450d022009210720252009470d000b0b4100210720264101470d02202a2105034002402005450d004100212a20052028460d00200541046a212a410121264100210720050d030c040b20242008460d03200341186a200810bf072008411c6a210820032802182205450d032005200328021c4102746a21282005212a0c000b0b200741106a2105200921070b200528020021050c010b0240200aa722054102460d002005450d00200a422088a721054200210a410221260c010b200341e0006a41086a200341f0006a41086a280200360200200320032903703703602003280248220e41306c21052003280240220c41546a210702400340410021082005450d01200541506a21052007412c6a2109200741306a2206210720092d00004103470d000b200641086a2802002205450d00200541286c2107200628020041186a2105410021080340200820052d0000456a2108200541286a2105200741586a22070d000b0b200e41306c2105200c415c6a210702400340024020050d00410021050c020b200541506a2105200741246a2109200741306a2206210720092d00004104470d000b200628020021050b200341e0046a41106a2229200341386a41106a280200360200200341e0046a41086a200341386a41086a290300370300200320032903383703e004200341b0016a200341e0046a10ef062003280250212f20032802542130024020032802582207450d00202f20074102746a2124200520086a212a200341e0046a41e0016a2126200341e0046a41d0016a2127200341e0046a41c0016a212e200341e0046a41b0016a2110200341e0046a41a0016a212b200341e0046a4190016a212d200341e0046a4180016a212c200341e0046a41f0006a2115200341e0046a41e0006a2116200341e0046a41d0006a2117200341e0046a41c0006a2118200341e0046a41306a2119200341e0046a41206a211a200341f7076a211b20034194056a211c200341a4056a211d200341b4056a211e200341c4056a211f200341d4056a2120200341e4056a2121200341f4056a212220034184066a211420034194066a2112200341a4066a2101200341b4066a2113200341c4066a2131202f21050240034020032802602207450d01200541046a2123200528020021062003280264210d034020072f01062225410274210c41002109417f210841002105024003400240200c2005470d00202521080c020b200720056a210e200841016a2108200941206a2109200541046a21050240417f200e41086a280200220e200647200e20064b1b41016a0e03020001020b0b200720096a220e412c6a2802002107200e41306a28020021052003200b3602c406200341133a00c006200341d7003a00b006200320053602a4062003412d3a00a0062003200b36029406200341123a00900620032007360284062003410b3a008006200341063a00f005200341003a00e00520034184083b01d005200341373a00c005200320023602b4052003412d3a00b0052003200b3602a405200341123a00a0052003200b36029405200341133a009005200341d6003a008005200320053602f4042003412d3a00f0042003200b3602e404200341123a00e004200e411c6a220c280200220841106a220541ffffffff00712005470d0620054104742207417f4c0d060240024020070d00410821090c010b200710332209450d12200c28020021080b41002105200341003602880120032009360280012003200741047622073602840102402008450d002008417f6a210641002105410021080340024020052007470d0020034180016a20074101109a01200328028001210920032802880121050b200920054104746a2207410f3a000020072008360204200720032f01f0073b0001200741036a200341f0076a41026a2d00003a00002003200541016a22053602880120062008460d01200841016a210820032802840121070c000b0b20034180016a2005410f109a0120032802880121092003280280012108200341f0076a200341e0046a10d707200820094104746a220541086a200341f0076a41086a2207290300370300200520032903f007370300200341f0076a202910d707200541186a2007290300370300200520032903f007370310200341f0076a201a10d707200541286a2007290300370300200541206a20032903f007370300200341f0076a201910d707200541386a2007290300370300200541306a20032903f007370300200341f0076a201810d707200541c8006a2007290300370300200541c0006a20032903f007370300200341f0076a201710d707200541d8006a2007290300370300200541d0006a20032903f007370300200341f0076a201610d707200541e8006a2007290300370300200541e0006a20032903f007370300200341f0076a201510d707200541f8006a2007290300370300200541f0006a20032903f007370300200341f0076a202c10d70720054188016a200729030037030020054180016a20032903f007370300200341f0076a202d10d70720054198016a200729030037030020054190016a20032903f007370300200341f0076a202b10d707200541a8016a2007290300370300200541a0016a20032903f007370300200341f0076a201010d707200541b8016a2007290300370300200541b0016a20032903f007370300200341f0076a202e10d707200541c8016a2007290300370300200541c0016a20032903f007370300200341f0076a202710d707200541d8016a2007290300370300200541d0016a20032903f007370300200341f0076a202610d707200541e0016a20032903f007370300200541e8016a200729030037030020032009410f6a22053602880102402005200328028401470d0020034180016a20054101109a01200328028001210820032802880121050b200820054104746a220720032900f007370001200741063a0000200741086a201b2900003700002003200541016a36028801200341f0076a200341b0016a418c01109d081a411010332207450d12200741063a0000200341d0036a200341f0076a418c01109d081a200c2802002205417f4c0d06200e41146a280200210c0240024020050d0041002108410121060c010b200510332206450d12200521080b0240024020082005490d00200821090c010b200841017422092005200920054b1b22094100480d0d024020080d00200910332206450d140c010b20082009460d0020062008200910372206450d130b2006200c2005109d0821080240024020050d00410021064101210c0c010b20051033220c450d13200521060b200c20082005109d08210c02402009450d00200810350b200341c0026a200341d0036a418c01109d081a200e41216a3100002132200341f0076a200341c0026a418c01109d081a200341d0036a200341f0076a418c01109d081a411010332208450d12202841807e712128200a428080808080804083220a2005ad842032422886844280808080800c842132200841063a000020032802880121052003280284012109200328028001210d20081035200341c0026a200341d0036a418c01109d081a200341f0076a200341c0026a418c01109d081a024020072d00004109470d0002402007280204220828020441ffffffff0371450d0020082802001035200728020421080b200810350b20071035200341d0036a200341f0076a418c01109d081a200341f0076a200341d0036a418c01109d081a200320283602ec02200320053602e802200320093602e4022003200d3602e002200341003602dc02200342043702d402200320323702cc02200320063602c8022003200c3602c402200341013602c002200341f0076a200341c0026a10f306200341b0016a200341f0076a418c01109d081a200e41286a202a360200200e41246a4101360200024020032d00e0044109470d00024020032802e404220528020441ffffffff0371450d002005280200103520032802e40421050b200510350b024020032d00f0044109470d000240200341e0046a41146a280200220528020441ffffffff0371450d002005280200103520032802f40421050b200510350b024020032d0080054109470d000240200341e0046a41246a280200220528020441ffffffff0371450d002005280200103520032802840521050b200510350b024020032d0090054109470d000240201c280200220528020441ffffffff0371450d002005280200103520032802940521050b200510350b024020032d00a0054109470d000240201d280200220528020441ffffffff0371450d002005280200103520032802a40521050b200510350b024020032d00b0054109470d000240201e280200220528020441ffffffff0371450d002005280200103520032802b40521050b200510350b024020032d00c0054109470d000240201f280200220528020441ffffffff0371450d002005280200103520032802c40521050b200510350b024020032d00d0054109470d0002402020280200220528020441ffffffff0371450d002005280200103520032802d40521050b200510350b024020032d00e0054109470d0002402021280200220528020441ffffffff0371450d002005280200103520032802e40521050b200510350b024020032d00f0054109470d0002402022280200220528020441ffffffff0371450d002005280200103520032802f40521050b200510350b024020032d0080064109470d0002402014280200220528020441ffffffff0371450d002005280200103520032802840621050b200510350b024020032d0090064109470d0002402012280200220528020441ffffffff0371450d002005280200103520032802940621050b200510350b024020032d00a0064109470d0002402001280200220528020441ffffffff0371450d002005280200103520032802a40621050b200510350b024020032d00b0064109470d0002402013280200220528020441ffffffff0371450d002005280200103520032802b40621050b200510350b024020032d00c0064109470d0002402031280200220528020441ffffffff0371450d002005280200103520032802c40621050b200510350b200a4280808080808c0184210a202a41016a212a2023210520232024470d020c040b200d450d02200d417f6a210d200720084102746a4194036a28020021070c000b0b0b41a081cc0041800141a082cc001064000b0240203041ffffffff0371450d00202f10350b200341e0046a200341b0016a418c01109d081a200341f0076a200341e0046a10f106024020034180086a2802002205450d0020032802f8072226200541306c6a21272003280264210b200328026021280340024020262d000041786a220541024b0d0002400240024020050e03000102000b202628020c2207450d0220262802042205200741146c6a212a03400240200528020c0d002028450d002005280210210d20282106200b21230340200641286a2109200641086a210820062f010622254102742107417f210e02400340024020070d002025210e0c020b2008280200210c200e41016a210e200941206a21092007417c6a2107200841046a21080240417f200c200d47200c200d4b1b41016a0e03020001020b0b02402009417c6a280200450d00200520092802003602100c030b41b082cc00413541e882cc001064000b2023450d012023417f6a21232006200e4102746a4194036a28020021060c000b0b200541146a2205202a470d000c030b0b2028450d012026280204210c20282109200b210d0340200941286a2108200941086a210720092f0106222a4102742105417f210602400340024020050d00202a21060c020b2007280200210e200641016a2106200841206a21082005417c6a2105200741046a21070240417f200e200c47200e200c4b1b41016a0e03020001020b0b02402008417c6a280200450d00202620082802003602040c040b41b082cc00413541e882cc001064000b200d450d02200d417f6a210d200920064102746a4194036a28020021090c000b0b202628020c2205450d00202628020422292005411c6c6a21240340024020292802182205450d002029280210220d20054102746a2125034002402028450d00200d280200210c20282109200b212a0340200941286a2108200941086a210720092f010622234102742105417f210602400340024020050d00202321060c020b2007280200210e200641016a2106200841206a21082005417c6a2105200741046a21070240417f200e200c47200e200c4b1b41016a0e03020001020b0b02402008417c6a280200450d00200d20082802003602000c030b41b082cc00413541e882cc001064000b202a450d01202a417f6a212a200920064102746a4194036a28020021090c000b0b200d41046a220d2025470d000b0b2029411c6a22292024470d000b0b202641306a22262027470d000b0b20032902f4072232422088a72105200341fc076a290200210a20032802f0072129200341e0006a10e1072032a7212b410021070c090b2003200536027c0240024002400240200520104f0d00200f20054102746a280200220e450d070240200328025822092003280254470d00200341d0006a20094101108601200328025821090b200328025020094102746a20053602002003200941016a360258200341e0046a200328027c2223200341386a10e00720032802e804212b20032802e404212920032802e004222c4101460d0320292802082205417f4c0d042029280200210d20292d000c212720050d01410021094101210c0c020b200341013602f404200342023702e4042003419081cc003602e004200341013602d4032003200341d0036a3602f0042003200341fc006a3602d003200341f0076a200341e0046a104120032902f407220a422088a7210520032802f0072129200aa7212b0c0a0b20051033220c450d0d200521090b0240024020092005490d00200921060c010b200941017422062005200620054b1b22064100480d08024020090d0020061033220c450d0f0c010b024020092006470d00200921060c010b200c200920061037220c450d0e0b200c200d2005109d082109200320273a008c01200320053602880120032006360284012003200936028001200320292d000d3a008d012003200e36029c012003200328027c360298012003410036029001200320032f01f0073b018e010240024020032802702205450d00200328027421270c010b20164200370100201742003701002018420037010020194200370100201a420037010020154200370100200341e0046a410041e002109f081a41940310332205450d0e4100212720054100360200200520032903f0073702042005410c6a200341f0076a41086a290300370200200541146a200341f0076a41106a2903003702002005411c6a200341f0076a41186a290300370200200541246a200341f0076a41206a2903003702002005412c6a201b290300370200200541346a200341e0046a41e002109d081a20034100360274200320053602700b0340200541146a2109200541086a210e200541066a212d20052f0106222e4102742106417f210c02400340024020060d00202e210c0c020b200e280200210d200c41016a210c200941206a21092006417c6a2106200e41046a210e0240417f200d202347200d20234b1b41016a0e03020001020b0b200929020021322009200329038001370200200941186a200329039801370200200941106a220529020021332005200329039001370200200941086a200329038801370200203342ffffffff0f83420285500d05203242808080807083500d052032a710350c050b02402027450d002027417f6a21272005200c4102746a4194036a28020021050c010b0b2003200328027841016a36027820032903980121322003290390012133200329038801213420032903800121350240202d2f01002206410b490d0020164200370100201742003701002018420037010020194200370100201a420037010020154200370100200341e0046a410041e002109f081a41940310332209450d0e20094100360200200920032903f0073702042009410c6a200341f0076a41086a221e290300370200200941146a200341f0076a41106a221f2903003702002009411c6a200341f0076a41186a2220290300370200200941246a200341f0076a41206a22362903003702002009412c6a201b290300370200200941346a200341e0046a41e002109d08210e200341e0046a41086a2227200541fc016a290200370300200341e0046a41106a222e20054184026a290200370300200341e0046a41186a221c2005418c026a290200370300200320052902f4013703e00420052802202112200941086a200541246a20052f010641796a2206410274109d08210d200e20054194026a2006410574109d08210e200541063b0106200920063b01062020201c290300370300201f202e290300370300201e2027290300370300200320032903e0043703f00702400240200c4107490d00200d200c417a6a222d4102746a200d200c41796a220c4102746a220d200641ffff0371200c6b410274109e081a200d2023360200200e202d4105746a200e200c4105746a2206200941066a222d2f0100200c6b410574109e081a200641186a2032370200200620333702102006203437020820062035370200202d2f0100210e0c010b200541086a2206200c41016a220d4102746a2006200c4102746a2206202d2f0100220e200c6b221d410274109e081a20062023360200200541346a2206200d4105746a2006200c4105746a2206201d410574109e081a200641186a20323702002006203337021020062034370208200620353702000b202d200e41016a3b0100200341d0036a41186a222120202903002232370300200341d0036a41106a2222201f2903002233370300200341d0036a41086a2214201e2903002234370300200341b0016a41186a22012032370300200341b0016a41106a22132033370300200341b0016a41086a22312034370300200320032903f00722323703d003200320323703b00102402005280200220d0d004100212f200921060c040b20052f0104212d4100212f200921300340200341c0026a41186a22372001290300370300200341c0026a41106a22382013290300370300200341c0026a41086a22392031290300370300200320032903b0013703c002202d41ffff0371210c024002400240200d2f01062205410b490d0020164200370100201742003701002018420037010020194200370100201a4200370100201542003701002014201e2903003703002022201f29030037030020212020290300370300200341d0036a41206a22052036290300370300200341d0036a41286a2209201b290300370300200320032903f0073703d003200341e0046a4100419003109f081a41c40310332206450d1220064100360200200620032903d0033702042006410c6a2014290300370200200641146a20222903003702002006411c6a2021290300370200200641246a20052903003702002006412c6a2009290300370200200641346a200341e0046a419003109d082109200d280220213a201c200d418c026a290200370300202e200d4184026a2902003703002027200d41fc016a2902003703002003200d2902f4013703e004200641086a200d41246a200d2f0106220e41796a2205410274109d08213b2009200d4194026a2005410574109d08213c20064194036a200d41b0036a200e417a6a2223410274109d08211d200d41063b0106200620053b010602402023450d0041002105201d210903402009280200220e20053b0104200e2006360200200941046a21092023200541016a2205470d000b0b2020201c2903002232370300201f202e2903002233370300201e20272903002234370300200320032903e00422353703f007201c2032370300202e203337030020272034370300200320353703e004202d41ffff037122094107490d01203b200c417a6a220e41027422236a203b200c41796a22054102746a220920062f010620056b410274109e081a20092012360200203c200e4105746a203c20054105746a220920062f010620056b410574109e081a200941186a2037290300370200200941106a2038290300370200200941086a2039290300370200200920032903c002370200200620062f010641016a22093b0106200c410274222d201d6a416c6a201d20236a2223200941ffff0371220c200e6b410274109e081a20232030360200200c200e490d022006202d6a41fc026a210903402009280200220e200541016a22053b0104200e2006360200200941046a21092005200c490d000c030b0b200d41086a2209200c41016a2206410274220e6a2009200c41027422236a22092005200c6b2227410274109e081a20092012360200200d41346a220920064105746a2009200c4105746a22092027410574109e081a200941186a2037290300370200200941106a2038290300370200200941086a2039290300370200200920032903c002370200200d200541016a22053b01062023200d4194036a22096a41086a2009200e6a2209200541ffff0371220e20066b410274109e081a20092030360200200c200e4f0d07200d2006417f6a22054102746a4198036a2109034020092802002206200541016a22053b01042006200d360200200941046a21092005200e490d000c080b0b200d41086a2205200c41016a2223410274220e6a2005200c410274222d6a2205200d2f0106221d200c6b223b410274109e081a20052012360200200d41346a220520234105746a2005200c4105746a2205203b410574109e081a200541186a2037290300370200200541106a2038290300370200200541086a2039290300370200200520032903c002370200200d201d41016a22053b0106202d200d4194036a221d6a41086a201d200e6a221d200541ffff0371220e20236b410274109e081a201d20303602002009200e4f0d00200d202d6a4198036a2105034020052802002209200c41016a220c3b01042009200d360200200541046a2105200e200c470d000b0b202f41016a212f2001201c2903003703002013202e29030037030020312027290300370300200320032903e0043703b0010240200d28020022050d00203a21120c050b200d2f0104212d2005210d203a2112200621300c000b0b200541086a2209200c41016a220e4102746a2009200c4102746a22092006200c6b220d410274109e081a20092023360200200541346a2209200e4105746a2009200c4105746a2209200d410574109e081a200941186a20323702002009203337021020092034370208200920353702002005200641016a3b01060c030b20032802ec0421050c070b1044000b20164200370100201742003701002018420037010020194200370100201a4200370100201542003701002014201e2903003703002022201f29030037030020212020290300370300200341d0036a41206a22092036290300370300200341d0036a41286a220e201b290300370300200320032903f0073703d003200341e0046a4100419003109f081a41c40310332205450d0a20054100360200200520032903d0033702042005410c6a2014290300370200200541146a20222903003702002005411c6a2021290300370200200541246a20092903003702002005412c6a200e290300370200200541346a200341e0046a419003109d08210e2005200328027022093602940320032003280274220c41016a360274200941003b01042003200536027020092005360200201c2001290300370300202e201329030037030020272031290300370300200320032903b0013703e004200c202f470d0220052f01062209410a4b0d03200e20094105746a220e20032903e004370200200e41086a2027290300370200200e41106a202e290300370200200e41186a201c290300370200200520094102746a41086a20123602002005200941016a22094102746a4194036a2006360200200520093b0106200620093b0104200620053602000b202c450d00202b450d00202910350c000b0b41ff83cc00413041c086cc00103f000b41af84cc00412741c086cc00103f000b103e000b200341f0006a10e1070240200328025441ffffffff0371450d00200328025010350b20032802402208200328024810f406410121070240200341c4006a2802002203450d00200341306c450d00200810350b0b20002029360204200041086a2005ad422086202bad843702000240024020070d0020004100360200200041106a200a370200201141ffffffff03710d010c030b20004101360200201141ffffffff0371450d020b200f10350c010b2001280208200128021010f4062001410c6a2802002203450d00200341306c450d0020012802081035200424000f0b200424000f0b1045000b103c000bf6c70103017f037e1b7f230041e0006b220324000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000e10010002161514131211100e0f0d0c0403010b200141046a29020021042001410c6a2902002105200141146a2902002106200341003a00002002200341011078200341106a20063703002003200537030820032004370300200341d0006a2003200210c10720032d0050411f460d1c20002003290350370200200041086a200341d0006a41086a2903003702000c1d0b200141086a28020021072001410c6a2802002108200141046a2802002109200320012d00013a0000200220034101107820022009200810782007450d1b200910350c1b0b200141086a280200210a200141046a280200210b2001410c6a280200210c200341013a00002002200341011078200b200c4104746a210d41002107410021094101210e200c210803400240024020072009460d00200921010c010b200941016a22012009490d162009410174220f2001200f20014b1b22014100480d160240024020090d00024020010d004101210e0c020b20011033220e0d010c200b20092001460d00200e200920011037220e450d1f0b200121090b200e20076a200841807f72200841ff00712008410776220f1b3a0000200741016a2107200f2108200f0d000b0240200c0d00200b21100c190b200b21090340200941106a211020092d000d22114105460d1920092d000c2108200928020821122009280204211320092802002114024020012007470d00200741016a22012007490d16200741017422092001200920014b1b22014100480d16024020070d00024020010d004101210e0c020b20011033220e450d1f0c010b20072001460d00200e200720011037220e450d1e0b200e20076a20083a0000200741016a2109200741017441046a21152012210703402015210c0240024020092001460d002001210f0c010b200141016a22082001490d172001410174220f2008200f20084b1b220f4100480d170240024020010d000240200f0d004101210e0c020b200f1033220e450d210c010b2001200f460d00200e2001200f1037220e450d200b200f21010b200e20096a200741807f72200741ff0071200741077622081b3a0000200c41026a2115200941016a21092008210720080d000b0240024020120d00200921070c010b410021010340200920016a210741fc0021080240024002400240201420016a2d00000e050200010305020b41fe0021080c020b41fd0021080c010b41ff0021080b200320083a000002402007200f470d00200741016a220f2007490d18200c200f200c200f4b1b220f4100480d18024020070d000240200f0d004101210e0c020b200f1033220e450d210c010b2007200f460d00200e2007200f1037220e450d200b200e20096a20016a20083a0000200c41026a210c2012200141016a2201470d000b200920016a21070b02402013450d00201410350b41002109024020114104460d000240200f2007470d00200741016a22012007490d17200741017422092001200920014b1b220f4100480d17024020070d000240200f0d004101210e0c020b200f1033220e450d200c010b2007200f460d00200e2007200f1037220e450d1f0b200e20076a41013a0000200741016a2107201141077141ff007321090b02400240200f2007460d00200f21010c010b200741016a22012007490d16200741017422082001200820014b1b22014100480d16024020070d00024020010d004101210e0c020b20011033220e450d1f0c010b20072001460d00200e200720011037220e450d1e0b200e20076a20093a0000200741016a2107201021092010200d470d000c1a0b0b200141286a2802002112200141246a280200210a200141206a280200210d2001411c6a2802002114200141186a2802002113200141146a2802002110200141086a280200210b200141046a28020021112001410c6a2902002104200341003a00002002200341011078200341d0006a410c6a410036020020034201370254200320023602502004a7221541017441026a21092004422088a7210f41002107410021012015210803400240024020012007460d002003280254210c0c010b200741016a220c2007490d032007410174220e200c200e200c4b1b220e4100480d030240024020070d000240200e0d004101210c0c020b200e1033220c450d0b0c010b2003280254210c2007200e460d00200c2007200e1037220c450d0a0b2003200e3602582003200c3602540b200c20016a200841807f72200841ff00712008410776220c1b3a00002003200141016a220136025c200941026a210920032802582107200c2108200c0d000b02400240200720016b2015490d002003280254210c200721080c010b200120156a22082001490d022007410174220c2008200c20084b1b22084100480d020240024020070d00024020080d004101210c0c020b20081033220c450d0a0c010b2003280254210c20072008460d00200c200720081037220c450d090b200320083602582003200c3602540b200c20016a20112015109d081a2003201520016a36025c0240200b450d00201110350b034002400240201520016a220c2008460d00200328025421070c010b200841016a22072008490d032008410174220e2007200e20074b1b220e4100480d030240024020080d000240200e0d00410121070c020b200e10332207450d0b0c010b200328025421072008200e460d0020072008200e10372207450d0a0b2003200e360258200320073602540b200720156a20016a200f41807f72200f41ff0071200f41077622071b3a00002003200c41016a36025c02402007450d00200941026a2109200141016a2101200328025821082007210f0c010b0b0240024020100d00200c41016a2101410121020c010b2015417f732102201541016a210c20142107034002400240200c20016a22082003280258460d002003280254210f0c010b200841016a220f2008490d042009200f2009200f4b1b220e4100480d040240024020022001470d000240200e0d004101210f0c020b200e1033220f450d0c0c010b2003280254210f2008200e460d00200f2008200e1037220f450d0b0b2003200e3602582003200f3602540b200f200c6a20016a200741807f72200741ff00712007410776220f1b3a00002003200841016a36025c200941026a2109200141016a2101200f2107200f0d000b024002402001417f732003280258220720156b6a2014490d00200328025421090c010b201520016a41016a220820146a22092008490d03200741017422082009200820094b1b22084100480d030240024020070d00024020080d00410121090c020b200810332209450d0b0c010b2003280254210920072008460d0020092007200810372209450d0a0b20032008360258200320093602540b201520096a20016a41016a20102014109d081a2003201420156a20016a41016a220136025c410021022013450d00201010350b20014101742107200d20124104746a210e2012210903400240024020012003280258460d00200328025421080c010b200141016a22082001490d0320072008200720084b1b220f4100480d030240024020010d000240200f0d00410121080c020b200f10332208450d0b0c010b200328025421082001200f460d0020082001200f10372208450d0a0b2003200f360258200320083602540b200820016a200941807f72200941ff0071200941077622081b3a00002003200141016a220136025c200741026a21072008210920080d000b024002402012450d00200d210c0340200c410c6a2802002115200c41086a2802002101200c28020421090240024002400240024002400240024002400240200c2802000e0900010203040506070b000b200341003a0000024002402003280258200328025c2207460d004100210f200328025421080c010b200741016a22082007490d0e2007410174220f2008200f20084b1b220f4100480d0e0240024020070d000240200f0d00410121080c020b200f10332208450d160c010b200328025421082007200f460d0020082007200f10372208450d150b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0f2007410174220f2009200f20094b1b220f4100480d0f0240024020070d000240200f0d00410121090c020b200f10332209450d170c010b200328025421092007200f460d0020092007200f10372209450d160b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0f200741017422082001200820014b1b22084100480d0f0240024020070d00024020080d00410121010c020b200810332201450d170c010b2003280254210120072008460d0020012007200810372201450d160b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c2009210120090d000c090b0b200341013a0000024002402003280258200328025c2207460d004101210f200328025421080c010b200741016a22082007490d0d2007410174220f2008200f20084b1b220f4100480d0d0240024020070d000240200f0d00410121080c020b200f10332208450d150c010b200328025421082007200f460d0020082007200f10372208450d140b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0e2007410174220f2009200f20094b1b220f4100480d0e0240024020070d000240200f0d00410121090c020b200f10332209450d160c010b200328025421092007200f460d0020092007200f10372209450d150b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0e200741017422082001200820014b1b22084100480d0e0240024020070d00024020080d00410121010c020b200810332201450d160c010b2003280254210120072008460d0020012007200810372201450d150b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c200921012009450d080c000b0b200341023a0000024002402003280258200328025c2207460d004102210f200328025421080c010b200741016a22082007490d0c2007410174220f2008200f20084b1b220f4100480d0c0240024020070d000240200f0d00410121080c020b200f10332208450d140c010b200328025421082007200f460d0020082007200f10372208450d130b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0d2007410174220f2009200f20094b1b220f4100480d0d0240024020070d000240200f0d00410121090c020b200f10332209450d150c010b200328025421092007200f460d0020092007200f10372209450d140b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0d200741017422082001200820014b1b22084100480d0d0240024020070d00024020080d00410121010c020b200810332201450d150c010b2003280254210120072008460d0020012007200810372201450d140b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c200921012009450d070c000b0b200341033a0000024002402003280258200328025c2207460d004103210f200328025421080c010b200741016a22082007490d0b2007410174220f2008200f20084b1b220f4100480d0b0240024020070d000240200f0d00410121080c020b200f10332208450d130c010b200328025421082007200f460d0020082007200f10372208450d120b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0c2007410174220f2009200f20094b1b220f4100480d0c0240024020070d000240200f0d00410121090c020b200f10332209450d140c010b200328025421092007200f460d0020092007200f10372209450d130b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0c200741017422082001200820014b1b22084100480d0c0240024020070d00024020080d00410121010c020b200810332201450d140c010b2003280254210120072008460d0020012007200810372201450d130b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c2009210120090d000b20032015200341d0006a10a50720032d00002201411f460d0520032f000120032d00034110747221090c040b200341043a0000024002402003280258200328025c2207460d004104210f200328025421080c010b200741016a22082007490d0a2007410174220f2008200f20084b1b220f4100480d0a0240024020070d000240200f0d00410121080c020b200f10332208450d120c010b200328025421082007200f460d0020082007200f10372208450d110b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0b2007410174220f2009200f20094b1b220f4100480d0b0240024020070d000240200f0d00410121090c020b200f10332209450d130c010b200328025421092007200f460d0020092007200f10372209450d120b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0b200741017422082001200820014b1b22084100480d0b0240024020070d00024020080d00410121010c020b200810332201450d130c010b2003280254210120072008460d0020012007200810372201450d120b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c2009210120090d000b20032015200341d0006a10a50720032d00002201411f460d0420032f000120032d00034110747221090c030b200341053a0000024002402003280258200328025c2207460d004105210f200328025421080c010b200741016a22082007490d092007410174220f2008200f20084b1b220f4100480d090240024020070d000240200f0d00410121080c020b200f10332208450d110c010b200328025421082007200f460d0020082007200f10372208450d100b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d0a2007410174220f2009200f20094b1b220f4100480d0a0240024020070d000240200f0d00410121090c020b200f10332209450d120c010b200328025421092007200f460d0020092007200f10372209450d110b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d0a200741017422082001200820014b1b22084100480d0a0240024020070d00024020080d00410121010c020b200810332201450d120c010b2003280254210120072008460d0020012007200810372201450d110b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c2009210120090d000b20032015200341d0006a10a50720032d00002201411f460d0320032f000120032d00034110747221090c020b200341063a0000024002402003280258200328025c2207460d004106210f200328025421080c010b200741016a22082007490d082007410174220f2008200f20084b1b220f4100480d080240024020070d000240200f0d00410121080c020b200f10332208450d100c010b200328025421082007200f460d0020082007200f10372208450d0f0b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d092007410174220f2009200f20094b1b220f4100480d090240024020070d000240200f0d00410121090c020b200f10332209450d110c010b200328025421092007200f460d0020092007200f10372209450d100b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d09200741017422082001200820014b1b22084100480d090240024020070d00024020080d00410121010c020b200810332201450d110c010b2003280254210120072008460d0020012007200810372201450d100b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c200921012009450d030c000b0b200341073a0000024002402003280258200328025c2207460d004107210f200328025421080c010b200741016a22082007490d072007410174220f2008200f20084b1b220f4100480d070240024020070d000240200f0d00410121080c020b200f10332208450d0f0c010b200328025421082007200f460d0020082007200f10372208450d0e0b2003200f3602582003200836025420032d0000210f200328025c21070b200820076a200f3a00002003200741016a220736025c200341003a000003402003200941807f72200941ff0071200941077622081b220f3a00000240024020032802582007460d00200328025421090c010b200741016a22092007490d082007410174220f2009200f20094b1b220f4100480d080240024020070d000240200f0d00410121090c020b200f10332209450d100c010b200328025421092007200f460d0020092007200f10372209450d0f0b2003200f3602582003200936025420032d0000210f200328025c21070b200920076a200f3a00002003200741016a220736025c2008210920080d000b200341003a000003402003200141807f72200141ff0071200141077622091b22083a00000240024020032802582007460d00200328025421010c010b200741016a22012007490d08200741017422082001200820014b1b22084100480d080240024020070d00024020080d00410121010c020b200810332201450d100c010b2003280254210120072008460d0020012007200810372201450d0f0b200320083602582003200136025420032d00002108200328025c21070b200120076a20083a00002003200741016a220736025c200921012009450d020c000b0b200328020c210f20032802082108200328020421070240200a41ffffffff0071450d00200d10350b2003280258450d03200328025410350c030b200c41106a220c200e470d000b0b0240200a41ffffffff0071450d00200d10350b200328025c21082003280258210c2003280254210f20032802502107200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f200810780240200c450d00200f10350b2010450d1a2002450d1a2013450d1a201010350c1a0b02402010450d002002450d002013450d00201010350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a200f360000200041086a2008360000200041046a20073600000c1a0b2001412c6a2802002116200141286a2802002117200141246a280200210d200141206a28020021182001411c6a2802002119200141186a280200211a200141146a280200210b2001410c6a2902002104200141086a280200211b200141046a280200211341002112200341003a000041012108200220034101107802400240024041041033220a450d00200a41eec2b5ab06360000024020130d00410021114100211c0c030b200341003a00004101210c41002101410021092004a72215210703402003200741807f72200741ff0071200741077622081b22073a00000240024020012009460d002001210f0c010b200141016a22092001490d172001410174220f2009200f20094b1b220f4100480d170240024020010d00410021090240200f0d004101210c0c020b200f1033220c450d210c010b02402001200f470d00200121090c010b20012109200c2001200f1037220c450d200b200f21010b200c20096a20073a0000200941016a21092008210720080d000b02400240200f20096b2015490d00200f21100c010b200920156a22012009490d04200f41017422072001200720014b1b22104100480d040240200f0d00024020100d004101210c0c020b20101033220c450d1f0c010b200f2010460d00200c200f20101037220c450d0a0b200c20096a20132015109d081a0240201b450d00201310350b200341003a0000410110332208450d09200841003a0000200341003a0000410121014101210f200920156a220e210903402003200941807f72200941ff0071200941077622071b22093a00000240200f2001470d00200141016a220f2001490d0520014101742215200f2015200f4b1b220f4100480d05024020010d00410021010240200f0d00410121080c020b200f103322080d010c0c0b2001200f460d0020082001200f10372208450d0b0b200820016a20093a0000200141016a21012007210920070d000b0240200f20016b200e490d00200f21110c020b2001200e6a22092001490d03200f41017422072009200720094b1b22114100480d030240200f0d00024020110d00410121080c030b201110332208450d0a0c020b200f2011460d012008200f201110372208450d090c010b1045000b200820016a200c200e109d081a2001200e6a21124101211c2010450d00200c10350b02400240200b0d004101211d0c010b4100211d20034100360240200342013703382003410c6a2019360200200341086a201a3602002003200b360204200320044220883e0200200341d0006a2003200341386a10c20720032d0050411f470d04200341013a00000240024020112012460d002011210f0c010b201241016a22012012490d02201241017422092001200920014b1b220f4100480d02024020120d00410021120240200f0d00410121080c020b200f10332208450d090c010b2012200f460d0020082012200f10372208450d080b200820126a41013a000020032802402115200341003a0000201241016a21012015210903402003200941807f72200941ff0071200941077622071b22093a00000240200f2001470d00200141016a220f2001490d032001410174220c200f200c200f4b1b220f4100480d03024020010d00410021010240200f0d00410121080c020b200f10332208450d0a0c010b2001200f460d0020082001200f10372208450d090b200820016a20093a0000200141016a21012007210920070d000b2003280238210902400240200f20016b2015490d00200f21110c010b200120156a22072001490d02200f410174220c2007200c20074b1b22114100480d020240200f0d00024020110d00410121080c020b201110332208450d090c010b200f2011460d002008200f201110372208450d080b200820016a20092015109d081a0240200328023c450d00200910350b200120156a21124100211d0b0240200d0d004100210f0c030b2003410036024020034201370338200341003a00004101210c41002109410021012018210703402003200741807f72200741ff00712007410776220f1b22153a0000024020092001470d00200941016a22012009490d02200941017422072001200720014b1b22074100480d020240024020090d0041002101024020070d004101210c0c020b20071033220c450d0a0c010b024020092007470d00200921010c010b20092101200c200920071037220c450d090b2003200736023c2003200c360238200721090b200c20016a20153a00002003200141016a2201360240200f2107200f0d000b200d20164104746a211002400240024020160d00200d210c0c010b200d210c2018450d00201041706a211e41002101200d211f02400340201f210f02400340200f41046a28020022140d01200141016a21012010200f41106a220f470d000c050b0b200f41086a2902002104200f2802002120200341003a0000200f41106a211f200141016a21212018417f6a2118200328023c21072003280240210903402003200141807f72200141ff00712001410776220c1b220e3a00000240024020072009460d00200328023821010c010b200741016a22012007490d06200741017422092001200920014b1b22154100480d060240024020070d0041002109024020150d00410121010c020b201510332201450d0e0c010b20032802382101024020072015470d00200721090c010b2007210920012007201510372201450d0d0b2003201536023c20032001360238201521070b200120096a200e3a00002003200941016a2209360240200c2101200c0d000b200320043703082003201436020420032020360200200341d0006a2003200341386a10c207024020032d0050220e411f470d00201e200f460d022021210120180d010c020b0b20032d0053211520032f005121202003280254211f20032802582118200328025c21140240201041706a200f460d00200f41106a210c0340200c220f41106a210c0240200f2802042201450d000240200f410c6a2802002209450d002009410c6c21090340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b200f41086a2802002201450d002001410c6c450d00200f28020410350b200c2010470d000b0b201541107421010240201741ffffffff0071450d00200d10350b202020017221104101210f200328023c450d07200328023810350c070b200f41106a210c0b2010200c460d000340200c220f41106a210c0240200f2802042201450d000240200f410c6a2802002209450d002009410c6c21090340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b200f41086a2802002201450d002001410c6c450d00200f28020410350b200c2010470d000b0b0240201741ffffffff0071450d00200d10350b200341023a00000240024020112012460d002011210f0c010b201241016a22012012490d01201241017422092001200920014b1b220f4100480d01024020120d00410021120240200f0d00410121080c020b200f10332208450d080c010b2012200f460d0020082012200f10372208450d070b200820126a41023a000020032802402115200341003a0000201241016a21012015210903402003200941807f72200941ff0071200941077622071b22093a00000240200f2001470d00200141016a220f2001490d022001410174220c200f200c200f4b1b220f4100480d02024020010d00410021010240200f0d00410121080c020b200f10332208450d090c010b2001200f460d0020082001200f10372208450d080b200820016a20093a0000200141016a21012007210920070d000b200328023821090240200f20016b2015490d00200f21110c020b200120156a22072001490d00200f410174220c2007200c20074b1b22114100480d000240200f0d00024020110d00410121080c030b201110332208450d070c020b200f2011460d012008200f201110372208450d060c010b103e000b200820016a20092015109d081a0240200328023c450d00200910350b200120156a21124101210f0b0240201345201c720d00201b450d00201310350b0240200b450d00201d4101730d0002402019450d002019410c6c2109200b21010340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b201a450d00201a410c6c450d00200b10350b200d45200f720d0202402016450d00200d20164104746a2115200d210c0340200c220f41106a210c0240200f2802042201450d000240200f410c6a2802002209450d002009410c6c21090340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b200f41086a2802002201450d002001410c6c450d00200f28020410350b200c2015470d000b0b201741ffffffff0071450d02200d10350c020b2003280250220e4108762110200341d0006a410c6a2802002114200341d0006a41086a28020021182003280254211f0240200328023c450d00200328023810350b4100210f0b0240201c201345720d00201b450d00201310350b0240200b450d00201d4101730d0002402019450d002019410c6c2109200b21010340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b201a450d00201a410c6c450d00200b10350b0240200d45200f720d0002402016450d00200d20164104746a2115200d210c0340200c220f41106a210c0240200f2802042201450d000240200f410c6a2802002209450d002009410c6c21090340024020012802002207450d00200141046a280200450d00200710350b2001410c6a2101200941746a22090d000b0b200f41086a2802002201450d002001410c6c450d00200f28020410350b200c2015470d000b0b201741ffffffff0071450d00200d10350b200e41ff01712201411f460d002010410874200172210102402011450d00200810350b200020013602002000410c6a2014360200200041086a2018360200200041046a201f360200200a10350c140b200341146a2012360200200341106a20113602002003200836020c20034284808080c0003702042003200a360200200341d0006a2003200210c10720032d0050411f460d1220002003290350370200200041086a200341d0006a41086a2903003702000c130b103c000b200141086a280200210e200141046a28020021152001410c6a280200210c2003410b3a00002002200341011078200341386a410c6a41003602002003420137023c200320023602382015200c411c6c6a210d4100210141002109200c210703400240024020092001460d00200328023c21080c010b200141016a22082001490d0c2001410174220f2008200f20084b1b220f4100480d0c0240024020010d000240200f0d00410121080c020b200f10332208450d160c010b200328023c21082001200f460d0020082001200f10372208450d150b2003200f3602402003200836023c0b200820096a200741807f72200741ff0071200741077622071b3a00002003200941016a220936024402402007450d0020032802402101200721070c010b0b2003200d36025c200320153602582003200e360254200320153602500240200c450d000340200320152201411c6a22153602582001280210220e450d012001410c6a2802002102200141086a28020021102001280204210c200141146a290200210420012802002109200341003a00002003280244210103402003200941807f72200941ff0071200941077622071b22083a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0e200141017422082009200820094b1b22084100480d0e0240024020010d00024020080d00410121090c020b200810332209450d180c010b200328023c210920012008460d0020092001200810372209450d170b200320083602402003200936023c20032d00002108200328024421010b200920016a20083a00002003200141016a22013602442007210920070d000b024002400240200c0d00410121140c010b200320023602302003201036022c2003200c3602282003200341286a200341386a10a20720032d00002201411f470d0141002114200328024421010b200341003a00002004a721122004422088a7220f210903402003200941807f72200941ff0071200941077622071b22083a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0f200141017422082009200820094b1b22084100480d0f0240024020010d00024020080d00410121090c020b200810332209450d190c010b200328023c210920012008460d0020092001200810372209450d180b200320083602402003200936023c20032d00002108200328024421010b200920016a20083a00002003200141016a22013602442007210920070d000b024002402003280240220720016b200f490d00200328023c21090c010b2001200f6a22092001490d0e200741017422012009200120094b1b22014100480d0e0240024020070d00024020010d00410121090c020b200110332209450d180c010b200328023c210920072001460d0020092007200110372209450d170b200320013602402003200936023c200328024421010b200920016a200e200f109d081a20032001200f6a36024402402012450d00200e10350b0240200c450d002014450d0002402002450d0020024104742109200c21010340024020012d00004109470d000240200141046a2208280200220728020441ffffffff0371450d0020072802001035200828020021070b200710350b200141106a2101200941706a22090d000b0b201041ffffffff0071450d00200c10350b2015200d470d010c020b0b20032d0003411074210920032f00012107200328020c21082003280208210f2003280204210c02402004a7450d00200e10350b20072009722109200341d0006a10c30702402003280240450d00200328023c10350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a2008360000200041086a200f360000200041046a200c3600000c120b200341d0006a10c30720032802382107200328023c210f2003280240210c20032802442108200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d10200f10350c100b200141086a280200210e200141046a280200210f2001410c6a28020021152003410a3a00002002200341011078200341186a410c6a41003602002003420137021c20032002360218200f201541186c6a210b41002101410021092015210703400240024020092001460d00200328021c21080c010b200141016a22082001490d0b2001410174220c2008200c20084b1b220c4100480d0b0240024020010d000240200c0d00410121080c020b200c10332208450d150c010b200328021c21082001200c460d0020082001200c10372208450d140b2003200c3602202003200836021c0b200820096a200741807f72200741ff0071200741077622071b3a00002003200941016a220936022402402007450d0020032802202101200721070c010b0b2003200b3602342003200f3602302003200e36022c2003200f36022802402015450d0020034101722102200341026a210e03402003200f41186a2214360230200f2802002210450d01200f41146a280200210d200f41106a2802002111200f28020c2112200f2802082107200f280204211341002109200341003602442003420137023c201020074103746a21152003200341186a3602384100210103400240024020092001460d00200328023c21080c010b200941016a22012009490d0d200941017422082001200820014b1b22014100480d0d0240024020090d00024020010d00410121080c020b200110332208450d170c010b200328023c210820092001460d0020082009200110372208450d160b200320013602402003200836023c200328024421010b200820016a200741807f72200741ff0071200741077622071b3a00002003200141016a220136024402402007450d0020032802402109200721070c010b0b024020152010460d002010210f0340200f2902002204422088a7220941ff01714104460d01200f41086a210f2009411874411875210c200341003a00002004a7210903402003200941807f72200941ff0071200941077622071b22083a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0f200141017422082009200820094b1b22084100480d0f0240024020010d00024020080d00410121090c020b200810332209450d190c010b200328023c210920012008460d0020092001200810372209450d180b200320083602402003200936023c20032d00002108200328024421010b200920016a20083a00002003200141016a22013602442007210920070d000b2003200c417f732209413f7141c000722009200c417f4a1b22073a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0e200141017422072009200720094b1b22074100480d0e0240024020010d00024020070d00410121090c020b200710332209450d180c010b200328023c210920012007460d0020092001200710372209450d170b200320073602402003200936023c20032d00002107200328024421010b200920016a20073a00002003200141016a2201360244200f2015470d000b0b0240201341ffffffff0171450d00201010350b2012200d41047422016a21070240024002400240200d0d00201221010c010b200141706a210820122101034020012d00002109200e200141036a2d00003a00002003200141016a2f00003b01000240200941ac01470d00200141106a21010c020b200341cc006a41026a200e2d0000220f3a0000200320032f0100220c3b014c200141046a2802002115200141086a29030021042002200c3b0000200241026a200f3a0000200320093a00002003200437030820032015360204200341d0006a2003200341386a10ac07024020032d0050220c411f47220f0d00200841706a2108200141106a22012007470d010c030b0b20032d0053211020032f0051210d200328025421132003280258210a200328025c211602402008450d004100210903400240200120096a220741106a2d00004109470d000240200741146a2215280200220728020441ffffffff0371450d0020072802001035201528020021070b200710350b2008200941106a2209470d000b0b0240201141ffffffff0071450d00201210350b02402003280240450d00200328023c10350b200f450d02200d2010411074722101200341286a10c40702402003280220450d00200328021c10350b200020013b00012000200c3a0000200041036a20014110763a00002000410c6a2016360000200041086a200a360000200041046a20133600000c150b20072001460d000340200141106a2109024020012d00004109470d000240200141046a2208280200220128020441ffffffff0371450d0020012802001035200828020021010b200110350b2009210120072009470d000b0b0240201141ffffffff0071450d00201210350b200328024421102003280240210d200328023c21122003280238210f200341003a0000200f410c6a220c28020021012010210903402003200941807f72200941ff0071200941077622071b22083a000002400240200f41086a22152802002001460d00200f28020421090c010b200141016a22092001490d0e200141017422082009200820094b1b22084100480d0e0240024020010d00024020080d00410121090c020b200810332209450d180c010b200f280204210920012008460d0020092001200810372209450d170b200f200936020420152008360200200c280200210120032d000021080b200920016a20083a0000200c200141016a22013602002007210920070d000b024002402015280200220720016b2010490d00200f28020421090c010b200120106a22092001490d0d200741017422012009200120094b1b22014100480d0d0240024020070d00024020010d00410121090c020b200110332209450d170c010b200f280204210920072001460d0020092007200110372209450d160b200f200936020420152001360200200c28020021010b200920016a20122010109d081a200c200120106a360200200d450d00201210350b2014210f2014200b470d000b0b200341286a10c40720032802182107200328021c210f2003280220210c20032802242108200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d0f200f10350c0f0b200141086a2802002115200141046a28020021102001410c6a280200210c200341093a00002002200341011078200341386a410c6a41003602002003420137023c200320023602382010200c411c6c6a210d4100210141002109200c210703400240024020092001460d00200328023c21080c010b200141016a22082001490d0a2001410174220f2008200f20084b1b220f4100480d0a0240024020010d000240200f0d00410121080c020b200f10332208450d140c010b200328023c21082001200f460d0020082001200f10372208450d130b2003200f3602402003200836023c0b200820096a200741807f72200741ff0071200741077622071b3a00002003200941016a220936024402402007450d0020032802402101200721070c010b0b2003200d36025c2003201036025820032015360254200320103602500240200c450d000340200320102201411c6a221036025820012802102215450d012001410c6a2802002102200141086a28020021122001280204210e200141146a2902002104200128020021092003280244210103400240024020032802402001460d00200328023c21070c010b200141016a22072001490d0c200141017422082007200820074b1b22084100480d0c0240024020010d00024020080d00410121070c020b200810332207450d160c010b200328023c210720012008460d0020072001200810372207450d150b200320083602402003200736023c200328024421010b200720016a200941807f72200941ff0071200941077622071b3a00002003200141016a22013602442007210920070d000b024002400240200e0d00410121140c010b200320023602302003201236022c2003200e3602282003200341286a200341386a10a20720032d00002201411f470d0141002114200328024421010b200341003a000020152004422088a722094102746a210c03402003200941807f72200941ff0071200941077622071b22083a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0d200141017422082009200820094b1b22084100480d0d0240024020010d00024020080d00410121090c020b200810332209450d170c010b200328023c210920012008460d0020092001200810372209450d160b200320083602402003200936023c20032d00002108200328024421010b200920016a20083a00002003200141016a22013602442007210920070d000b0240200c2015460d002015210f0340200f2802002109200341003a000003402003200941807f72200941ff0071200941077622071b22083a00000240024020032802402001460d00200328023c21090c010b200141016a22092001490d0f200141017422082009200820094b1b22084100480d0f0240024020010d00024020080d00410121090c020b200810332209450d190c010b200328023c210920012008460d0020092001200810372209450d180b200320083602402003200936023c20032d00002108200328024421010b200920016a20083a00002003200141016a22013602442007210920070d000b200f41046a220f200c470d000b0b0240200442ffffffff0383500d00201510350b0240200e450d002014450d0002402002450d0020024104742109200e21010340024020012d00004109470d000240200141046a2208280200220728020441ffffffff0371450d0020072802001035200828020021070b200710350b200141106a2101200941706a22090d000b0b201241ffffffff0071450d00200e10350b2010200d470d010c020b0b20032d0003411074210920032f00012107200328020c21082003280208210f2003280204210c0240200442ffffffff0383500d00201510350b20072009722109200341d0006a10c50702402003280240450d00200328023c10350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a2008360000200041086a200f360000200041046a200c3600000c100b200341d0006a10c50720032802382107200328023c210f2003280240210c20032802442108200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d0e200f10350c0e0b200141046a28020021072003410c3a00002002200341011078200341003a000041002109410021014101210c03402003200741807f72200741ff0071200741077622081b22073a00000240024020092001460d002001210f0c010b200141016a220f2001490d0920014101742215200f2015200f4b1b220f4100480d090240024020010d000240200f0d004101210c0c020b200f1033220c450d130c010b2001200f460d00200c2001200f1037220c450d120b200f21010b200c20096a20073a0000200941016a21092008210720080d000b200341003a00002009210103402003200141800172200141ff0071200141077622071b3a000020022003410110782007210120070d000b2002200c20091078200f450d0d200c10350c0d0b200141046a2802002107200341083a00002002200341011078200341003a000041002109410021014101210c03402003200741807f72200741ff0071200741077622081b22073a00000240024020092001460d002001210f0c010b200141016a220f2001490d0820014101742215200f2015200f4b1b220f4100480d080240024020010d000240200f0d004101210c0c020b200f1033220c450d120c010b2001200f460d00200c2001200f1037220c450d110b200f21010b200c20096a20073a0000200941016a21092008210720080d000b200341003a00002009210103402003200141800172200141ff0071200141077622071b3a000020022003410110782007210120070d000b2002200c20091078200f450d0c200c10350c0c0b200141086a280200210b200141046a28020021132001410c6a280200210e200341073a00002002200341011078200341003a00002013200e41146c6a211441002101410021074101210f200e210803402003200841807f72200841ff00712008410776220c1b22083a00000240024020012007460d00200721090c010b200741016a22092007490d07200741017422152009201520094b1b22094100480d070240024020070d00024020090d004101210f0c020b20091033220f450d110c010b20072009460d00200f200720091037220f450d100b200921070b200f20016a20083a0000200141016a2101200c2108200c0d000b024002400240200e0d002013210e0c010b201321070340200741146a210e200728020c220d4104460d0120072802042111200741106a28020021082007280200211220072802082210210703400240024020012009460d00200921150c010b200941016a220c2009490d0a20094101742215200c2015200c4b1b22154100480d0a0240024020090d00024020150d004101210f0c020b20151033220f450d140c010b20092015460d00200f200920151037220f450d130b201521090b200f20016a200741807f72200741ff00712007410776220c1b3a0000200141016a2101200c2107200c0d000b02400240201520016b2010490d00201521090c010b200120106a22092001490d09201541017422072009200720094b1b22094100480d09024020150d00024020090d004101210f0c020b20091033220f450d120c010b20152009460d00200f201520091037220f450d110b200f20016a20122010109d081a201020096b20016a210702402011450d00201210350b024002402007450d00200921070c010b200941016a22072009490d092009410174220c2007200c20074b1b22074100480d09024020090d00024020070d004101210f0c020b20071033220f450d120c010b20092007460d00200f200920071037220f450d110b200f20106a20016a200d3a0000201020016a41016a210103400240024020012007460d00200721090c010b200741016a22092007490d0a2007410174220c2009200c20094b1b22094100480d0a0240024020070d00024020090d004101210f0c020b20091033220f450d140c010b20072009460d00200f200720091037220f450d130b200921070b200f20016a200841807f72200841ff00712008410776220c1b3a0000200141016a2101200c2108200c0d000b200e2107200e2014470d000c020b0b2014200e460d000340200e41146a21070240200e41046a280200450d00200e28020010350b2007210e20142007470d000b0b0240200b450d00200b41146c450d00201310350b200341003a00002001210703402003200741800172200741ff0071200741077622081b3a000020022003410110782008210720080d000b2002200f200110782009450d0b200f10350c0b0b200141086a280200210e200141046a280200210c2001410c6a2802002115200341063a00002002200341011078200341386a410c6a41003602002003420137023c20032002360238200c20154104746a210241002101410021092015210703400240024020092001460d00200328023c21080c010b200141016a22082001490d062001410174220f2008200f20084b1b220f4100480d060240024020010d000240200f0d00410121080c020b200f10332208450d100c010b200328023c21082001200f460d0020082001200f10372208450d0f0b2003200f3602402003200836023c0b200820096a200741807f72200741ff0071200741077622071b3a00002003200941016a220936024402402007450d0020032802402101200721070c010b0b2003200236025c2003200c3602582003200e3602542003200c36025002402015450d00024003400240200c410d6a2d000022094102470d00200c41106a21020c020b200c41086a280200210f200c41046a2802002115200c280200210e2003200c410c6a2d000041ff007322083a000002400240200328024020032802442201460d00200328023c21070c010b200141016a22072001490d08200141017422082007200820074b1b22084100480d080240024020010d00024020080d00410121070c020b200810332207450d120c010b200328023c210720012008460d0020072001200810372207450d110b200320083602402003200736023c20032d00002108200328024421010b200720016a20083a00002003200141016a2201360244200320093a00000240024020032802402001460d00200328023c21070c010b200141016a22092001490d08200141017422072009200720094b1b22094100480d080240024020010d00024020090d00410121070c020b200910332207450d120c010b200328023c210720012009460d0020072001200910372207450d110b200320093602402003200736023c20032d00002109200328024421010b200720016a20093a00002003200141016a3602442003200f3602302003201536022c2003200e3602282003200341286a200341386a10a207024020032d00002201411f470d00200c41106a220c2002470d010c020b0b20032f000120032d00034110747221092003280204210720032802082108200328020c210f2003200c41106a360258200341d0006a10c60702402003280240450d00200328023c10350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a200f360000200041086a2008360000200041046a20073600000c0d0b200320023602580b200341d0006a10c60720032802382107200328023c210f2003280240210c20032802442108200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d0a200f10350c0a0b2001410c6a2802002110200141086a2802002112200141046a280200210e200341053a00002002200341011078200341d0006a410c6a41003602002003420137025420032002360250200341003a0000410021014101210f4100210920102107034020032007220741807f72200741ff0071200741077622071b22083a0000024020012009470d00200941016a220c2009490d0520094101742215200c2015200c4b1b220c4100480d05024002400240024020090d000240200c0d004101210f0c020b200c1033210f0c030b2009200c470d010b200c21090c020b200f2009200c1037210f0b200c2109200f450d0d0b200f20016a20083a0000200141016a210120070d000b2003200136025c2003200f36025420032009360258024002402010450d002010410c6c2108410021010340200e20016a220941046a28020022074102460d01200320092802002007200941086a280200200341d0006a10af0720032d00002209411f470d0220082001410c6a2201470d000b0b02402012450d002012410c6c450d00200e10350b200328025c21082003280258210c2003280254210f20032802502107200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d0a200f10350c0a0b20032d0003411074210120032f00012107200328020c21082003280208210f2003280204210c02402012450d002012410c6c450d00200e10350b2007200172210102402003280258450d00200328025410350b200020013b0001200020093a0000200041036a20014110763a00002000410c6a2008360000200041086a200f360000200041046a200c3600000c0a0b2001410c6a2802002115200141086a2802002110200141046a280200210e200341043a00002002200341011078200341d0006a410c6a4100360200200342013702542003200236025041002101410121084100210920152107034020072107024020012009470d00200941016a220f2009490d042009410174220c200f200c200f4b1b220f4100480d04024002400240024020090d000240200f0d00410121080c020b200f103321080c030b2009200f470d010b200f21090c020b20082009200f103721080b200f21092008450d0c0b200820016a200741807f72200741ff0071200741077622071b3a0000200141016a210120070d000b2003200136025c2003200836025420032009360258024002402015450d002015410c6c2102410021090340200e20096a220141046a28020022084102460d012001280200210f200141086a280200210c200341f0003a0000024002402003280258200328025c2201460d0041f0002115200328025421070c010b200141016a22072001490d06200141017422152007201520074b1b22154100480d060240024020010d00024020150d00410121070c020b201510332207450d100c010b2003280254210720012015460d0020072001201510372207450d0f0b200320153602582003200736025420032d000021150b200720016a20153a00002003200141016a36025c2003200f2008200c200341d0006a10af0720032d00002201411f470d0220022009410c6a2209470d000b0b02402010450d002010410c6c450d00200e10350b200328025c21082003280258210c2003280254210f20032802502107200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d09200f10350c090b20032d0003411074210920032f00012107200328020c21082003280208210f2003280204210c02402010450d002010410c6c450d00200e10350b2007200972210902402003280258450d00200328025410350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a2008360000200041086a200f360000200041046a200c3600000c090b200141086a2802002114200141046a28020021122001410c6a280200210e200341033a00002002200341011078200341003a00002012200e4102746a211041002109410021074101210c200e210803402003200841807f72200841ff00712008410776220f1b22083a00000240024020092007460d00200721010c010b200741016a22012007490d03200741017422152001201520014b1b22014100480d030240024020070d00024020010d004101210c0c020b20011033220c450d0d0c010b20072001460d00200c200720011037220c450d0c0b200121070b200c20096a20083a0000200941016a2109200f2108200f0d000b02400240200e0d002001210f0c010b2012210e0340200e2802002107200341003a000003402003200741807f72200741ff0071200741077622081b22073a00000240024020092001460d002001210f0c010b200141016a220f2001490d0520014101742215200f2015200f4b1b220f4100480d050240024020010d000240200f0d004101210c0c020b200f1033220c450d0f0c010b2001200f460d00200c2001200f1037220c450d0e0b200f21010b200c20096a20073a0000200941016a21092008210720080d000b200f2101200e41046a220e2010470d000b0b0240201441ffffffff0371450d00201210350b200341003a00002009210103402003200141800172200141ff0071200141077622071b3a000020022003410110782007210120070d000b2002200c20091078200f450d07200c10350c070b200141086a280200211a200141046a28020021162001410c6a2802002115200341023a00002002200341011078200341d0006a410c6a410036020020034201370254200320023602502016201541286c6a210241002101410021092015210703400240024020092001460d00200328025421080c010b200141016a22082001490d022001410174220f2008200f20084b1b220f4100480d020240024020010d000240200f0d00410121080c020b200f10332208450d0c0c010b200328025421082001200f460d0020082001200f10372208450d0b0b2003200f360258200320083602540b200820096a200741807f72200741ff0071200741077622071b3a00002003200941016a220936025c02402007450d0020032802582101200721070c010b0b2016210c2015450d02201541286c41586a21102016210c0340200c220941286a210c20092d0018220d4104460d03200941206a29000021042009411c6a280000210f2009411a6a2d0000210a200941196a2c0000210b200941146a2802002115200941106a2802002111200928020c21122009280204211320092802002114200328025c21012009280208220e210903400240024020032802582001460d00200328025421070c010b200141016a22072001490d03200141017422082007200820074b1b22084100480d030240024020010d00024020080d00410121070c020b200810332207450d0d0c010b2003280254210720012008460d0020072001200810372207450d0c0b2003200836025820032007360254200328025c21010b200720016a200941807f72200941ff0071200941077622071b3a00002003200141016a220136025c2007210920070d000b024002402003280258220720016b200e490d00200328025421090c010b2001200e6a22092001490d02200741017422012009200120094b1b22014100480d020240024020070d00024020010d00410121090c020b200110332209450d0c0c010b2003280254210920072001460d0020092007200110372209450d0b0b2003200136025820032009360254200328025c21010b200920016a2014200e109d081a20032001200e6a220136025c02402013450d0020141035200328025c21010b2015210903400240024020032802582001460d00200328025421070c010b200141016a22072001490d03200141017422082007200820074b1b22084100480d030240024020010d00024020080d00410121070c020b200810332207450d0d0c010b2003280254210720012008460d0020072001200810372207450d0c0b2003200836025820032007360254200328025c21010b200720016a200941807f72200941ff0071200941077622071b3a00002003200141016a220136025c2007210920070d000b024002402003280258220720016b2015490d00200328025421090c010b200120156a22092001490d02200741017422012009200120094b1b22014100480d020240024020070d00024020010d00410121090c020b200110332209450d0c0c010b2003280254210920072001460d0020092007200110372209450d0b0b2003200136025820032009360254200328025c21010b200920016a20122015109d081a2003200120156a36025c02402011450d00201210350b02400240024002400240200d0e0400010203000b200341003a0000024002402003280258200328025c2201460d0041002107200328025421090c010b200141016a22092001490d06200141017422072009200720094b1b22074100480d060240024020010d00024020070d00410121090c020b200710332209450d100c010b2003280254210920012007460d0020092001200710372209450d0f0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a220136025c200341003a000003402003200f41807f72200f41ff0071200f41077622091b22083a00000240024020032802582001460d00200328025421070c010b200141016a22072001490d07200141017422082007200820074b1b22084100480d070240024020010d00024020080d00410121070c020b200810332207450d110c010b2003280254210720012008460d0020072001200810372207450d100b200320083602582003200736025420032d00002108200328025c21010b200720016a20083a00002003200141016a220136025c2009210f20090d000c040b0b200341013a0000024002402003280258200328025c2201460d0041012107200328025421090c010b200141016a22092001490d05200141017422072009200720094b1b22074100480d050240024020010d00024020070d00410121090c020b200710332209450d0f0c010b2003280254210920012007460d0020092001200710372209450d0e0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a220136025c200341f0003a00000240024020032802582001460d0041f0002107200328025421090c010b200141016a22092001490d05200141017422072009200720094b1b22074100480d050240024020010d00024020070d00410121090c020b200710332209450d0f0c010b2003280254210920012007460d0020092001200710372209450d0e0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a36025c2003200f2004a72004422088a7200341d0006a10af0720032d00002201411f460d0220032f000120032d00034110747221090c050b200341023a0000024002402003280258200328025c2201460d0041022107200328025421090c010b200141016a22092001490d04200141017422072009200720094b1b22074100480d040240024020010d00024020070d00410121090c020b200710332209450d0e0c010b2003280254210920012007460d0020092001200710372209450d0d0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a36025c2003200f2004a72004422088a7200341d0006a10af0720032d00002201411f460d0120032f000120032d00034110747221090c040b200341033a0000024002402003280258200328025c2201460d0041032107200328025421090c010b200141016a22092001490d03200141017422072009200720094b1b22074100480d030240024020010d00024020070d00410121090c020b200710332209450d0d0c010b2003280254210920012007460d0020092001200710372209450d0c0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a220136025c2003200b417f732209413f7141c000722009200b417f4a1b22073a00000240024020032802582001460d00200328025421090c010b200141016a22092001490d03200141017422072009200720094b1b22074100480d030240024020010d00024020070d00410121090c020b200710332209450d0d0c010b2003280254210920012007460d0020092001200710372209450d0c0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a220136025c2003200a41ff017141004722073a00000240024020032802582001460d00200328025421090c010b200141016a22092001490d03200141017422072009200720094b1b22074100480d030240024020010d00024020070d00410121090c020b200710332209450d0d0c010b2003280254210920012007460d0020092001200710372209450d0c0b200320073602582003200936025420032d00002107200328025c21010b200920016a20073a00002003200141016a36025c0b201041586a2110200c2002470d000c040b0b103e000b200328020c2107200328020821082003280204210f02402002200c460d0003400240200c41046a280200450d00200c28020010350b0240200c41106a280200450d00200c410c6a28020010350b200c41286a210c201041586a22100d000b0b0240201a450d00201a41286c450d00201610350b02402003280258450d00200328025410350b200020093b0001200020013a0000200041036a20094110763a00002000410c6a2007360000200041086a2008360000200041046a200f3600000c050b2002200c460d0003400240200c41046a280200450d00200c28020010350b200c41286a21010240200c41106a280200450d00200c410c6a28020010350b2001210c20022001470d000b0b0240201a450d00201a41286c450d00201610350b200328025c21082003280258210c2003280254210f20032802502107200341003a00002008210103402003200141800172200141ff0071200141077622091b3a000020072003410110782009210120090d000b2007200f20081078200c450d02200f10350c020b200d2010460d000340201041106a21090240201041046a280200450d00201028020010350b20092110200d2009470d000b0b0240200a41ffffffff0071450d00200b10350b200341003a00002007210903402003200941800172200941ff0071200941077622081b3a000020022003410110782008210920080d000b2002200e200710782001450d00200e10350b2000411f3a00000b200341e0006a24000f0b103c000be60703027f017e057f230041d0006b2202240041a3edcb00ad4280808080f00084100122032900002104200241086a41086a200341086a2900003703002002200437030820031035419cb4ca00ad4280808080800184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240200141086a28020041046a2203417f4c0d000240024020030d0041012105410021030c010b200310332205450d020b2002410036024820022005360240200220033602440240200341034b0d00200341017422064104200641044b1b22064100480d030240024020030d002006103322050d010c060b20032006460d0020052003200610372205450d050b20022006360244200220053602400b2005200128000036000020024104360248200141046a2802002107200141086a2802002201200241c0006a10770240024020022802442208200228024822056b2001490d0020022802402103200821060c010b200520016a22032005490d03200841017422062003200620034b1b22064100480d030240024020080d00024020060d00410121030c020b200610332203450d060c010b2002280240210320082006460d0020032008200610372203450d050b20022006360244200220033602400b200320056a20072001109d081a2002200520016a2201ad4220862003ad841003220529000037033820051035200241cc006a200320016a360200200220033602482002200241c0006a3602442002200241386a360240200241286a200241c0006a107b02402006450d00200310350b2002280230220841206a2206417f4c0d00200228022821070240024020060d0041002101410121030c010b200610332203450d02200621010b024002402001410f4d0d00200121050c010b200141017422054110200541104b1b22054100480d03024020010d00200510332203450d050c010b20012005460d0020032001200510372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020054170714110460d00200521010c010b200541017422014120200141204b1b22014100480d0320052001460d0020032005200110372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200141606a2008490d00200121050c010b200841206a22052008490d03200141017422092005200920054b1b22054100480d0320012005460d0020032001200510372203450d040b200341206a20072008109d081a2000200636020820002005360204200020033602000240200228022c450d00200710350b200241d0006a24000f0b1044000b1045000b103e000b103c000b130020004104360204200041a4bfca003602000b1300200041043602042000418cc3ca003602000b130020004101360204200041e8caca003602000b340020004193d1cb0036020420004100360200200041146a4103360200200041106a41e8cbca00360200200041086a420a3702000beb050a067f017e017f017e017f017e017f017e017f017e230041206b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200020044105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c37000020052008370000024020032001490d00200321040c030b2006410d7420067322054111762005732205410574200573220620077122054100200120052001491b6b220520014f0d01200020034105746a22042900002108200020054105746a220541086a2209290000210a200541106a220b290000210c200541186a220d290000210e20042005290000370000200441186a220f2900002110200f200e370000200441106a220f290000210e200f200c370000200441086a2204290000210c2004200a370000200d2010370000200b200e3700002009200c370000200520083700002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200020044105746a22012900002108200020054105746a220041086a2205290000210a200041106a2204290000210c200041186a2203290000210e20012000290000370000200141186a220629000021102006200e370000200141106a2206290000210e2006200c370000200141086a2201290000210c2001200a370000200320103700002004200e3700002005200c370000200020083700000b200241206a24000f0b20052001418486cc001042000b2004200141f485cc001042000be90609067f017e017f017e017f027e017f017e027f230041206b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d0220052006200020064105746a200020054105746a412010a0084100481b21060b200620014f0d03200420014f0d02200020044105746a2204200020064105746a2205412010a00841004e0d03200541086a22072900002108200541106a2209290000210a200541186a220b290000210c2004290000210d20042005290000370000200441186a220e290000210f200e200c370000200441106a220e290000210c200e200a370000200441086a2204290000210a20042008370000200b200f3700002009200c3700002007200a3700002005200d370000200621040c000b0b2006200141f487cc001042000b20042001418488cc001042000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241186a2209200041186a2204290000370300200241106a220b200041106a2205290000370300200241086a220e200041086a2203290000370300200020074105746a220641086a2900002108200641106a290000210a200641186a290000210c2000290000210d200020062900003700002004200c3700002005200a370000200320083700002002200d37030041002105024002400240034020062002290300370000200641186a2009290300370000200641106a200b290300370000200641086a200e2903003700002005410174220641017221040240200641026a220620074f0d00200420074f0d0220062004200020044105746a200020064105746a412010a0084100481b21040b200420074f0d03200520074f0d02200020054105746a2205200020044105746a2206412010a00841004e0d032009200541186a2203290000370300200b200541106a2210290000370300200e200541086a2211290000370300200641086a2900002108200641106a290000210a200641186a290000210c2005290000210d200520062900003700002003200c3700002010200a370000201120083700002002200d370300200421050c000b0b2004200741f487cc001042000b20052007418488cc001042000b200741014b0d000b0b200241206a24000f0b20072001418486cc001042000bdb08030a7f017e0a7f230041c0006b22022400200041a07f6a21032001417f6a2104200141324921054101210641002107024003400240024020062001490d00410021080c010b41012108200020064105746a2209200941606a412010a0084100480d0003404101210a20042006460d03200641016a2106200941206a220a2009412010a0082108200a21092008417f4a0d000b200620014921080b2006200146210a20050d0120062001460d0102400240024002402006417f6a220920014f0d002008450d0120002006410574220b6a220a290000210c200a200020094105746a22092900003700002009200c370000200a41086a220d290000210c200d200941086a220e290000370000200e200c370000200a41106a220f290000210c200f200941106a22102900003700002010200c370000200a41186a2211290000210c2011200941186a22122900003700002012200c37000020064102490d03200920002006417e6a22084105746a2213412010a008417f4a0d032009290000210c20092013290000370000200241206a41186a22142012290000370300200241206a41106a22152010290000370300200241206a41086a2216200e290000370300200e201341086a2900003700002010201341106a2900003700002012201341186a2900003700002002200c3703204100210e2008450d022003200b6a210903400240200241206a2009412010a0084100480d002008210e0c040b200941206a2009290000370000200941386a200941186a290000370000200941306a200941106a290000370000200941286a200941086a290000370000200941606a21092008417f6a22080d000c030b0b2009200141f485cc001042000b20062001418486cc001042000b2000200e4105746a22092002290320370000200941186a2014290300370000200941106a2015290300370000200941086a20162903003700000b200741016a21070240200120066b22104102490d00200a41206a2209200a412010a008417f4a0d00200a290000210c200a2009290000370000200241206a41186a22122011290000370300200241206a41106a2213200f290000370300200241206a41086a220b200d290000370300200d200941086a290000370000200f200941106a2900003700002011200941186a2900003700002002200c3703204101210d024020104103490d00200a41c0006a200241206a412010a008417f4a0d00410321084102210e0340200a200e4105746a220941606a220d2009290000370000200d41186a200941186a290000370000200d41106a200941106a290000370000200d41086a200941086a290000370000024020082010490d00200e210d0c020b20084105742109200e210d2008210e200841016a2108200a20096a200241206a412010a0084100480d000b0b200a200d4105746a22092002290320370000200941186a2012290300370000200941106a2013290300370000200941086a200b2903003700000b20074105470d000b4100210a0b200241c0006a2400200a0b88090b107f017e017f017e017f017e017f017e017f017e017f230041306b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200241286a22082000200441306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e2903003703002013201029030037030020052002290300370300024020032001490d00200321040c030b2006410d7420067322044111762004732204410574200473220620077122044100200120042001491b6b220520014f0d01200241286a22082000200341306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e29030037030020132010290300370300200520022903003703002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200241286a22032000200441306c6a220141286a2204290300370300200241206a2206200141206a2207290300370300200241186a2208200141186a2209290300370300200241106a220a200141106a220b290300370300200241086a220c200141086a220d290300370300200220012903003703002000200541306c6a22002903002112200041086a22052903002114200041106a220e2903002116200041186a220f2903002118200041206a2210290300211a2004200041286a22112903003703002007201a37030020092018370300200b2016370300200d2014370300200120123703002011200329030037030020102006290300370300200f2008290300370300200e200a2903003703002005200c290300370300200020022903003703000b200241306a24000f0b20052001418486cc001042000b2004200141f485cc001042000bf30a020e7f027e02402000280200220428020028020028020028020028020022052802002206450d0020012802002107200428020428020022082002280200220941306c6a210a2005280204210b2006210c02400340200c41086a210d200c2f0106220e410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210e0b0240200b0d0042002112420021130c030b200b417f6a210b200c200e4102746a41c8056a280200210c0c010b0b200c20104105746a220f41f0026a2903002113200f41e8026a29030021120b2006450d002008200741306c6a210a2005280204210b2006210c02400340200c41086a210d200c2f0106220e410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210e0b200b450d02200b417f6a210b200c200e4102746a41c8056a280200210c0c010b0b2012200c20104105746a220f41e8026a2903005a2013200f41f0026a29030022125a20132012511b0d0020012009360200200220073602002004280208220f200f28020041016a360200200228020021092000280200220428020428020021082004280200280200280200280200280200220528020021060b2006450d0020082003280200220741306c6a210a2005280204210b2006210c02400340200c41086a210d200c2f0106220e410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210e0b0240200b0d0042002112420021130c030b200b417f6a210b200c200e4102746a41c8056a280200210c0c010b0b200c20104105746a220f41f0026a2903002113200f41e8026a29030021120b2006450d002008200941306c6a210a2005280204210b2006210c02400340200c41086a210d200c2f0106220e410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210e0b200b450d02200b417f6a210b200c200e4102746a41c8056a280200210c0c010b0b2012200c20104105746a220f41e8026a2903005a2013200f41f0026a29030022125a20132012511b0d0020022007360200200320093602002004280208220f200f28020041016a360200200228020021092000280200220428020428020021082004280200280200280200280200280200220528020021060b2006450d00200128020021002008200941306c6a210a2005280204210b2006210c02400340200c41086a210d200c2f0106220e410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210e0b0240200b0d0042002112420021130c030b200b417f6a210b200c200e4102746a41c8056a280200210c0c010b0b200c20104105746a220f41f0026a2903002113200f41e8026a29030021120b2006450d002008200041306c6a210a2005280204210c0340200641086a210d20062f0106220b410574210f41002110024002400340200f450d01200a200d412010a0082211450d02200f41606a210f201041016a2110200d41206a210d2011417f4a0d000b2010417f6a210b0b200c450d02200c417f6a210c2006200b4102746a41c8056a28020021060c010b0b2012200620104105746a220f41e8026a2903005a2013200f41f0026a29030022125a20132012511b0d0020012009360200200220003602002004280208220f200f28020041016a3602000b0bfe030a0d7f017e017f017e017f017e017f017e017f017e230041c0006b22032400200320023602082003200341086a36020c024020014101762202450d002003410c6a200020012002417f6a1084072002417e6a210203402002417f460d012003410c6a2000200120021084072002417f6a21020c000b0b0240024020014102490d00200141306c20006a41506a21022001210403402004417f6a220520014f0d02200341106a41286a2204200041286a2206290300370300200341106a41206a2207200041206a2208290300370300200341106a41186a2209200041186a220a290300370300200341106a41106a220b200041106a220c290300370300200341106a41086a220d200041086a220e29030037030020032000290300370310200241086a220f2903002110200241106a22112903002112200241186a22132903002114200241206a22152903002116200241286a22172903002118200020022903003703002006201837030020082016370300200a2014370300200c2012370300200e20103703002017200429030037030020152007290300370300201320092903003703002011200b290300370300200f200d290300370300200220032903103703002003410c6a200020054100108407200241506a210220052104200541014b0d000b0b200341c0006a24000f0b2004417f6a2001418486cc001042000bf20f03107f027e0a7f230041306b22032400410021042001413249210541012106024003400240024020062001490d00410021070c010b20022802002802002802002208280200210941012107034002402009450d002006417f6a210a2000200641306c6a210b2008280204210c2009210d02400340200d41086a210e200d2f0106220f4105742110410021110240024003402010450d01200b200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a210f0b0240200c0d0042002113420021140c030b200c417f6a210c200d200f4102746a41c8056a280200210d0c010b0b200d20114105746a221041f0026a2903002114201041e8026a29030021130b2009450d002000200a41306c6a210b2008280204210c2009210d0340200d41086a210e200d2f0106220f4105742110410021110240024003402010450d01200b200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a210f0b200c450d02200c417f6a210c200d200f4102746a41c8056a280200210d0c010b0b2013200d20114105746a221041e8026a2903005a2014201041f0026a29030022135a20142013511b450d020b41012110200641016a2206200149210720062001470d000c030b0b2006200146211020050d0120062001460d0102400240024002402006417f6a221020014f0d002007410171450d01200441016a21042000201041306c6a2210290300211420102000200641306c6a220b290300370300200341286a2209201041286a220e290300370300200341206a2207201041206a2211290300370300200341186a2208201041186a2212290300370300200341106a220a201041106a220d290300370300200341086a2215201041086a22102903003703002010200b41086a2216290300370300200d200b41106a22172903003703002012200b41186a22182903003703002011200b41206a2219290300370300200e200b41286a221a29030037030020032014370300200b2003290300370300201a200929030037030020192007290300370300201820082903003703002017200a29030037030020162015290300370300200020062002108307200120066b221b4102490d032002280200280200280200221c280200220f450d03200b41306a210d201c280204211d200f210c02400340200c41086a210e200c2f0106221e4105742110410021110240024003402010450d01200d200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a211e0b0240201d0d0042002113420021140c030b201d417f6a211d200c201e4102746a41c8056a280200210c0c010b0b200c20114105746a221041f0026a2903002114201041e8026a29030021130b200f450d03201c280204210c0340200f41086a210e200f2f0106221d4105742110410021110240024003402010450d01200b200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a211d0b200c450d05200c417f6a210c200f201d4102746a41c8056a280200210f0c010b0b2013200f20114105746a221041e8026a2903005a2014201041f0026a29030022135a20142013511b0d03200b2903002114200b200d2903003703002009201a2903003703002007201929030037030020082018290300370300200a2017290300370300201520162903003703002016200d41086a2903003703002017200d41106a2903003703002018200d41186a2903003703002019200d41206a290300370300201a200d41286a290300370300200320143703004101211e201b4103490d02410321184102211a4101211e034020022802002802002802002219280200220c450d03200b201a41306c6a210d2018211d20192802042116200c210f02400340200f41086a210e200f2f010622174105742110410021110240024003402010450d01200d200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21170b024020160d0042002113420021140c030b2016417f6a2116200f20174102746a41c8056a280200210f0c010b0b200f20114105746a221041f0026a2903002114201041e8026a29030021130b200c450d032019280204210f0340200c41086a210e200c2f010622164105742110410021110240024003402010450d012003200e412010a0082212450d02201041606a2110201141016a2111200e41206a210e2012417f4a0d000b2011417f6a21160b200f450d05200f417f6a210f200c20164102746a41c8056a280200210c0c010b0b2013200c20114105746a221041e8026a290300542014201041f0026a29030022135420142013511b450d03200d41506a2210200d290300370300201041286a200d41286a290300370300201041206a200d41206a290300370300201041186a200d41186a290300370300201041106a200d41106a290300370300201041086a200d41086a29030037030002402018201b4f0d00201841016a2118201a211e201d211a0c010b0b201a211e0c020b2010200141f485cc001042000b20062001418486cc001042000b200b201e41306c6a22102003290300370300201041286a2009290300370300201041206a2007290300370300201041186a2008290300370300201041106a200a290300370300201041086a20152903003703000b20044105470d000b410021100b200341306a240020100bc709030c7f027e057f230041306b22032400024020014102490d00200228020028020028020022042802002205450d002001417e6a2106200141306c20006a220141a07f6a2107200141506a2108200428020421092005210a02400340200a41086a210b200a2f0106220c41057421014100210d0240024003402001450d012008200b412010a008220e450d02200141606a2101200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a210c0b024020090d004200210f420021100c030b2009417f6a2109200a200c4102746a41c8056a280200210a0c010b0b200a200d4105746a220141f0026a2903002110200141e8026a290300210f0b2005450d002004280204210a0340200541086a210b20052f0106220941057421014100210d0240024003402001450d012007200b412010a008220e450d02200141606a2101200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a21090b200a450d02200a417f6a210a200520094102746a41c8056a28020021050c010b0b200f2005200d4105746a220141e8026a2903005a2010200141f0026a290300220f5a2010200f511b0d002008290300211020082007290300370300200341286a2211200841286a2201290300370300200341206a2212200841206a220b290300370300200341186a2213200841186a220d290300370300200341106a2214200841106a220e290300370300200341086a2215200841086a22082903003703002008200741086a290300370300200e200741106a290300370300200d200741186a290300370300200b200741206a2903003703002001200741286a290300370300200320103703000240024020060d00410021060c010b03402002280200280200280200220c2802002207450d0120002006417f6a220441306c6a2108200c28020421052007210a02400340200a41086a210b200a2f0106220941057421014100210d0240024003402001450d012003200b412010a008220e450d02200141606a2101200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a21090b024020050d004200210f420021100c030b2005417f6a2105200a20094102746a41c8056a280200210a0c010b0b200a200d4105746a220141f0026a2903002110200141e8026a290300210f0b2007450d01200c280204210a0340200741086a210b20072f0106220541057421014100210d0240024003402001450d012008200b412010a008220e450d02200141606a2101200d41016a210d200b41206a210b200e417f4a0d000b200d417f6a21050b200a450d03200a417f6a210a200720054102746a41c8056a28020021070c010b0b200f2007200d4105746a220141e8026a290300542010200141f0026a290300220f542010200f511b450d012000200641306c6a22012008290300370300200141286a200841286a290300370300200141206a200841206a290300370300200141186a200841186a290300370300200141106a200841106a290300370300200141086a200841086a2903003703002004210620040d000b410021060b2000200641306c6a22012003290300370300200141286a2011290300370300200141206a2012290300370300200141186a2013290300370300200141106a2014290300370300200141086a20152903003703000b200341306a24000bd20907067f027e077f027e047f017e017f230041306b2204240003402003410174220541017221060240200541026a220720024f0d00024002400240200620024f0d0002402000280200280200280200280200280200220828020022090d004200210a4200210b0c020b2001200641306c6a210c2008280204210d2009210e02400340200e41086a210f200e2f010622104105742105410021110240024003402005450d01200c200f412010a0082212450d02200541606a2105201141016a2111200f41206a210f2012417f4a0d000b2011417f6a21100b0240200d0d004200210a4200210b0c030b200d417f6a210d200e20104102746a41c8056a280200210e0c010b0b200e20114105746a220541f0026a290300210b200541e8026a290300210a0b2009450d012001200741306c6a210c2008280204210e0340200941086a210f20092f0106220d4105742105410021110240024003402005450d01200c200f412010a0082212450d02200541606a2105201141016a2111200f41206a210f2012417f4a0d000b2011417f6a210d0b200e450d03200e417f6a210e2009200d4102746a41c8056a28020021090c010b0b200920114105746a220541f0026a2903002113200541e8026a29030021140c020b2006200241f487cc001042000b42002114420021130b20072006200a201454200b201354200b2013511b1b21060b024002400240200620024f0d00200320024f0d0120002802002802002802002802002802002210280200220e450d002001200341306c6a210c20102802042109200e210302400340200341086a210f20032f0106220d4105742105410021110240024003402005450d01200c200f412010a0082212450d02200541606a2105201141016a2111200f41206a210f2012417f4a0d000b2011417f6a210d0b024020090d00420021134200210b0c030b2009417f6a21092003200d4102746a41c8056a28020021030c010b0b200320114105746a220541f0026a290300210b200541e8026a29030021130b200e450d002001200641306c6a2103201028020421090340200e41086a210f200e2f0106220d4105742105410021110240024003402005450d012003200f412010a0082212450d02200541606a2105201141016a2111200f41206a210f2012417f4a0d000b2011417f6a210d0b2009450d022009417f6a2109200e200d4102746a41c8056a280200210e0c010b0b2013200e20114105746a220541e8026a29030054200b200541f0026a290300221354200b2013511b0d020b200441306a24000f0b20032002418488cc001042000b200441286a2205200c41286a220f290300370300200441206a2211200c41206a2212290300370300200441186a220e200c41186a2209290300370300200441106a220d200c41106a2210290300370300200441086a2207200c41086a22082903003703002004200c2903003703002003290300210b200341086a22152903002113200341106a2216290300210a200341186a22172903002114200341206a22182903002119200f200341286a221a29030037030020122019370300200920143703002010200a37030020082013370300200c200b370300201a2005290300370300201820112903003703002017200e2903003703002016200d2903003703002015200729030037030020032004290300370300200621030c000b0b88090b107f017e017f017e017f017e017f017e017f017e017f230041306b2202240002400240024020014108490d00200141017641feffffff07712203417f6a220420014f0d022001410d74200173220541117620057322054105742005732206417f2001417f6a677622077122054100200120052001491b6b220520014f0d01200241286a22082000200441306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e2903003703002013201029030037030020052002290300370300024020032001490d00200321040c030b2006410d7420067322044111762004732204410574200473220620077122044100200120042001491b6b220520014f0d01200241286a22082000200341306c6a220441286a2209290300370300200241206a220a200441206a220b290300370300200241186a220c200441186a220d290300370300200241106a220e200441106a220f290300370300200241086a2210200441086a2211290300370300200220042903003703002000200541306c6a22052903002112200541086a22132903002114200541106a22152903002116200541186a22172903002118200541206a2219290300211a2009200541286a221b290300370300200b201a370300200d2018370300200f20163703002011201437030020042012370300201b20082903003703002019200a2903003703002017200c2903003703002015200e29030037030020132010290300370300200520022903003703002003410172220420014f0d022006410d742006732205411176200573220541057420057320077122054100200120052001491b6b220520014f0d01200241286a22032000200441306c6a220141286a2204290300370300200241206a2206200141206a2207290300370300200241186a2208200141186a2209290300370300200241106a220a200141106a220b290300370300200241086a220c200141086a220d290300370300200220012903003703002000200541306c6a22002903002112200041086a22052903002114200041106a220e2903002116200041186a220f2903002118200041206a2210290300211a2004200041286a22112903003703002007201a37030020092018370300200b2016370300200d2014370300200120123703002011200329030037030020102006290300370300200f2008290300370300200e200a2903003703002005200c290300370300200020022903003703000b200241306a24000f0b20052001418486cc001042000b2004200141f485cc001042000bf20907077f027e0b7f017e017f027e017f230041306b22022400024020014101762203450d0003402003417f6a2203210402400240024003402004410174220541017221060240200541026a220520014f0d00200620014f0d02200520062000200641306c6a22072903002000200541306c6a220829030056200741086a2903002209200841086a290300220a562009200a511b1b21060b200620014f0d03200420014f0d022000200441306c6a22042903002000200641306c6a220529030056200441086a22072903002209200541086a2208290300220a562009200a511b450d03200241286a220b200441286a220c290300370300200241206a220d200441206a220e290300370300200241186a220f200441186a2210290300370300200241106a2211200441106a2212290300370300200241086a221320072903003703002002200429030037030020082903002109200541106a2214290300210a200541186a22152903002116200541206a2217290300211820052903002119200c200541286a221a290300370300200e2018370300201020163703002012200a3703002007200937030020042019370300201a200b2903003703002017200d2903003703002015200f290300370300201420112903003703002008201329030037030020052002290300370300200621040c000b0b2006200141f487cc001042000b20042001418488cc001042000b20030d000b0b0240024020014102490d002001210703402007417f6a220720014f0d02200241286a220b200041286a2205290300370300200241206a220c200041206a2206290300370300200241186a220d200041186a2208290300370300200241106a220e200041106a2210290300370300200241086a220f200041086a2211290300370300200220002903003703002000200741306c6a22042903002109200441086a290300210a200441106a2903002116200441186a2903002118200441206a29030021192005200441286a2903003703002006201937030020082018370300201020163703002011200a3703002000200937030041002105024002400240034020042002290300370300200441286a200b290300370300200441206a200c290300370300200441186a200d290300370300200441106a200e290300370300200441086a200f2903003703002005410174220441017221060240200441026a220420074f0d00200620074f0d02200420062000200641306c6a22082903002000200441306c6a221029030056200841086a2903002209201041086a290300220a562009200a511b1b21060b200620074f0d03200520074f0d022000200541306c6a22052903002000200641306c6a220429030056200541086a22082903002209200441086a2210290300220a562009200a511b450d03200b200541286a2211290300370300200c200541206a2212290300370300200d200541186a2213290300370300200e200541106a2214290300370300200f20082903003703002002200529030037030020102903002109200441106a290300210a200441186a2903002116200441206a2903002118200429030021192011200441286a29030037030020122018370300201320163703002014200a3703002008200937030020052019370300200621050c000b0b2006200741f487cc001042000b20052007418488cc001042000b200741014b0d000b0b200241306a24000f0b20072001418486cc001042000bb80c050a7f017e017f037e0f7f230041306b22022400200041c07e6a21032001417f6a2104200041306a2105410021062001413249210741012108024003400240024020082001490d00410021090c010b410121092000200841306c220a6a220b290300220c200b41506a220d29030056200b41086a290300220e200d41086a290300220f56200e200f511b0d002005200a6a210903404101210b20042008460d03200841016a210820092903002210200c58210b200941086a290300220f200e51210d200f200e58210a200941306a21092010210c200f210e200b200a200d1b0d000b200820014921090b2008200146210b20070d0120082001460d010240024002400240024002402008417f6a220b20014f0d002009450d012000200b41306c6a2209290300210e20092000200841306c22116a220b290300370300200241286a220a200941286a2212290300370300200241206a2213200941206a2214290300370300200241186a2215200941186a2216290300370300200241106a2217200941106a2218290300370300200241086a2219200941086a220d290300370300200d200b41086a221a2903003703002018200b41106a221b2903003703002016200b41186a221c2903003703002014200b41206a221d2903003703002012200b41286a221e2903003703002002200e370300200b2002290300370300201e200a290300370300201d2013290300370300201c2015290300370300201b2017290300370300201a201929030037030020084102490d052009290300220c20002008417e6a221341306c6a220a29030058200d290300220e200a41086a221f290300220f58200e200f511b0d052009200a290300370300200d201f2903003703002009290310210f2018200a41106a2903003703002015201229030037030020172014290300370300201920162903003703002016200a41186a2903003703002014200a41206a2903003703002012200a41286a2903003703002002200f370300024020130d00410021130c050b200c20002008417d6a220d41306c6a220929030058200e200941086a290300220f58200e200f511b0d04200320116a2109034020094188016a200941d8006a29030037030020094180016a200941d0006a290300370300200941f8006a200941c8006a290300370300200941f0006a200941c0006a290300370300200941e8006a200941386a290300370300200941e0006a200941306a290300370300200d450d032009290300210f200941086a210a200941506a2109200d417f6a210d200c200f56200e200a290300220f56200e200f511b0d000b200d41016a21130c030b200b200141f485cc001042000b20082001418486cc001042000b410021130b2000201341306c6a210a0b200a200c370300200a200e3703082000201341306c6a22092002290300370310200941286a2015290300370300200941206a2017290300370300200941186a20192903003703000b200641016a21060240200120086b22144102490d00200b290330200b290300220c58200b41386a290300220f201a290300220e58200f200e511b0d00200b200b41306a2212290300370300201a201241086a290300370300200b290310210f201b201241106a2903003703002015201e2903003703002017201d2903003703002019201c290300370300201c201241186a290300370300201d201241206a290300370300201e201241286a2903003703002002200f3703004101211a024020144103490d00200b290360200c58200b41e8006a290300220f200e58200f200e511b0d00200b41e0006a21094103210a4102210d0340200d221a41306c200b6a221241506a220d2009290300370300200d41286a200941286a290300370300200d41206a200941206a290300370300200d41186a200941186a290300370300200d41106a200941106a290300370300200d41086a200941086a290300370300200a20144f0d01200a41306c2109200a210d200a41016a210a200b20096a2209290300200c56200941086a290300220f200e56200f200e511b0d000b0b2012200c3703002012200e370308200b201a41306c6a22092002290300370310200941286a2015290300370300200941206a2017290300370300200941186a20192903003703000b20064105470d000b4100210b0b200241306a2400200b0b13002000410736020420004194d1ca003602000b130020004100360204200041b0b4cc003602000b9f0303027f017e027f230041206b2202240041c7d5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354190eaca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000ba10701087f230041106b220224002002410036020820024201370300200028020021030240410410332204450d00200241043602042002200436020020042003360000200241043602082000280204210320044104410810372204450d002002410836020420042003360004200220043602002002410836020820002802082104200041106a280200220320021077024002402003450d00200341057421052002280204210620022802082103034002400240200620036b4120490d00200341206a2107200228020021080c010b200341206a22072003490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009103322080d010c060b2002280200210820062009460d0020082006200910372208450d050b2002200936020420022008360200200921060b200820036a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200736020820072103200441206a2104200541606a22050d000b0b200028021421042000411c6a2802002203200210770240024020030d0020022802042109200228020821030c010b200341057421054100200228020822036b210820022802042106034002400240200620086a4120490d0020022802002107200621090c010b200341206a22072003490d03200641017422092007200920074b1b22094100480d030240024020060d00024020090d00410121070c020b200910332207450d060c010b2002280200210720062009460d0020072006200910372207450d050b2002200936020420022007360200200921060b200720036a22072004290000370000200741186a200441186a290000370000200741106a200441106a290000370000200741086a200441086a2900003700002002200341206a2203360208200841606a2108200441206a2104200541606a22050d000b0b2000280220210602400240200920036b4104490d0020022802002104200921070c010b200341046a22042003490d01200941017422072004200720044b1b22074100480d010240024020090d00024020070d00410121040c020b200710332204450d040c010b2002280200210420092007460d0020042009200710372204450d030b20022007360204200220043602000b200420036a20063600002001290200200341046aad4220862004ad84100202402007450d00200410350b200241106a24000f0b103e000b103c000b9f0303027f017e027f230041206b2202240041dad5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354190eaca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b130020004109360204200041a8eaca003602000b3400200041f8a2cb0036020420004100360200200041146a4103360200200041106a4180a3cb00360200200041086a42083702000b130020004105360204200041b4a9cb003602000b3400200041c7d5ca0036020420004100360200200041146a4106360200200041106a41f8bbcb00360200200041086a42133702000b3400200041dad5ca0036020420004100360200200041146a4106360200200041106a41f8bbcb00360200200041086a42133702000ba10701087f230041106b220224002002410036020820024201370300200028020021030240410410332204450d00200241043602042002200436020020042003360000200241043602082000280204210320044104410810372204450d002002410836020420042003360004200220043602002002410836020820002802082104200041106a280200220320021077024002402003450d00200341057421052002280204210620022802082103034002400240200620036b4120490d00200341206a2107200228020021080c010b200341206a22072003490d03200641017422082007200820074b1b22094100480d030240024020060d00024020090d00410121080c020b2009103322080d010c060b2002280200210820062009460d0020082006200910372208450d050b2002200936020420022008360200200921060b200820036a22032004290000370000200341186a200441186a290000370000200341106a200441106a290000370000200341086a200441086a2900003700002002200736020820072103200441206a2104200541606a22050d000b0b200028021421042000411c6a2802002203200210770240024020030d0020022802042109200228020821030c010b200341057421054100200228020822036b210820022802042106034002400240200620086a4120490d0020022802002107200621090c010b200341206a22072003490d03200641017422092007200920074b1b22094100480d030240024020060d00024020090d00410121070c020b200910332207450d060c010b2002280200210720062009460d0020072006200910372207450d050b2002200936020420022007360200200921060b200720036a22072004290000370000200741186a200441186a290000370000200741106a200441106a290000370000200741086a200441086a2900003700002002200341206a2203360208200841606a2108200441206a2104200541606a22050d000b0b2000280220210602400240200920036b4104490d0020022802002104200921070c010b200341046a22042003490d01200941017422072004200720044b1b22074100480d010240024020090d00024020070d00410121040c020b200710332204450d040c010b2002280200210420092007460d0020042009200710372204450d030b20022007360204200220043602000b200420036a20063600002001290200200341046aad4220862004ad84100202402007450d00200410350b200241106a24000f0b103e000b103c000b340020004182e9ca0036020420004100360200200041146a4101360200200041106a41b8c0cb00360200200041086a42183702000bfd0303037f027e047f230041106b220224002002410036020820024201370300200028021021030240410410332204450d0020024104360204200220043602002004200336000020024104360208200041086a29030021052000290300210620044104411410372204450d00200420063700042004410c6a200537000020024294808080c00237020420022004360200200028021421072000411c6a2802002200200210770240024020000d002002280208210320022802042108200228020021090c010b2000410574210a200228020021092002280204210820022802082103034020072100024002402008200322046b4120490d00200441206a21030c010b024002400240200441206a22032004490d00200841017422072003200720034b1b22074100480d000240024020080d00024020070d00410121090c020b2007103321090c040b20082007470d020b200721080c030b103e000b200920082007103721090b200721082009450d030b200041206a2107200920046a22042000290000370000200441186a200041186a290000370000200441106a200041106a290000370000200441086a200041086a290000370000200a41606a220a0d000b2002200836020420022003360208200220093602000b20012902002003ad4220862009ad84100202402008450d00200910350b200241106a24000f0b103c000bc20503027f017e047f230041d0006b2202240041f8a2cb00ad4280808080800184100122032900002104200241086a200341086a290000370300200220043703002003103541e4a6cb00ad4280808080d00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a2900003700002003ad4280808080800484100422012900002104200241306a41086a200141086a2900003703002002200437033020011035200241cc006a200341206a360200200220033602482002200241306a41106a3602442002200241306a360240200241206a200241c0006a107b200310352002280228220541206a2201417f4c0d01200228022021060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290300370000200341086a200241086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290310370010200341186a200241106a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a20002001360208200020083602042000200336020002402002280224450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bb10503027f017e047f230041d0006b2202240041f8a2cb00ad4280808080800184100122032900002104200241086a41086a200341086a29000037030020022004370308200310354188a5cb00ad4280808080b00184100122032900002104200241186a41086a200341086a29000037030020022004370318200310350240024002400240412010332203450d0020032001290000370000200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a29000037000020022003ad42808080808004841003220129000037033820011035200241cc006a200341206a360200200220033602482002200241386a41086a3602442002200241386a360240200241286a200241c0006a107b200310352002280230220541206a2201417f4c0d01200228022821060240024020010d0041002107410121030c010b200110332203450d01200121070b024002402007410f4d0d00200721080c010b200741017422084110200841104b1b22084100480d03024020070d002008103322030d010c050b20072008460d0020032007200810372203450d040b20032002290308370000200341086a200241086a41086a2903003700000240024020084170714110460d00200821070c010b200841017422074120200741204b1b22074100480d0320082007460d0020032008200710372203450d040b20032002290318370010200341186a200241186a41086a29030037000002400240200741606a2005490d00200721080c010b2005415f4b0d03200741017422082001200820014b1b22084100480d0320072008460d0020032007200810372203450d040b200341206a20062005109d081a2000200136020820002008360204200020033602000240200228022c450d00200610350b200241d0006a24000f0b1045000b1044000b103e000b103c000bdc0703027f017e067f230041e0006b2203240041f8a2cb00ad4280808080800184100122042900002105200341086a41086a200441086a290000370300200320053703082004103541e8a5cb00ad4280808080800284100122042900002105200341186a41086a200441086a29000037030020032005370318200410350240024002400240412010332204450d0020042001290000370000200441186a200141186a290000370000200441106a200141106a290000370000200441086a200141086a29000037000020032004ad42808080808004841003220129000037034820011035200341dc006a2201200441206a360200200320043602582003200341c8006a41086a22063602542003200341c8006a360250200341286a200341d0006a107b20041035412010332204450d0020042002290000370000200441186a200241186a290000370000200441106a200241106a290000370000200441086a200241086a29000037000020032004ad428080808080048410032202290000370348200210352001200441206a36020020032004360258200320063602542003200341c8006a360250200341386a200341d0006a107b200410352003280230220741206a2206200328024022086a2201417f4c0d01200328023821092003280228210a0240024020010d004100210b410121040c010b200110332204450d012001210b0b02400240200b410f4d0d00200b21020c010b200b41017422024110200241104b1b22024100480d030240200b0d002002103322040d010c050b200b2002460d002004200b200210372204450d040b20042003290308370000200441086a200341086a41086a2903003700000240024020024170714110460d002002210b0c010b2002410174220b4120200b41204b1b220b4100480d032002200b460d0020042002200b10372204450d040b20042003290318370010200441186a200341186a41086a29030037000002400240200b41606a2007490d00200b21020c010b2007415f4b0d03200b41017422022006200220064b1b22024100480d03200b2002460d002004200b200210372204450d040b200441206a200a2007109d081a02400240200220066b2008490d002002210b0c010b20012006490d032002410174220b2001200b20014b1b220b4100480d03024020020d000240200b0d00410121040c020b200b10332204450d050c010b2002200b460d0020042002200b10372204450d040b200420066a20092008109d081a200020013602082000200b360204200020043602000240200328023c450d00200910350b0240200328022c450d00200a10350b200341e0006a24000f0b1045000b1044000b103e000b103c000b130020004110360204200041fcc2cb003602000b9f0303027f017e027f230041206b2202240041dad5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354188b8cb00ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b9f0303027f017e027f230041206b2202240041dad5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354190eaca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b9b0c08057f037e057f017e077f017e017f017e230041c0076b220424000240024020000d00200441e0026a2003109c0720043502e80242208620042802e0022200ad841007024020042802e402450d00200010350b200441ed026a200341086a290000370000200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441033a00e402200441073a00e002200420032900003700e50241b0b4cc004100200441e0026a10d4010c010b200441ed026a200341086a290000370000200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441023a00e402200441073a00e002200420032900003700e50241b0b4cc004100200441e0026a10d401200441b8026a2003109c07200441e0026a20042802b802220520042802c00210e30220042802e002210020044190056a200441e0026a41047241ac02109d081a02402000411b470d0020042802bc02450d01200510350c010b200441086a20044190056a41ac02109d081a024020042802bc02450d00200510350b20022802042105200420003602e002200441e0026a410472200441086a41ac02109d081a2004419c056a200136020020044190056a41086a2005360200200441003a009405200441013a009005200441b8026a200441e0026a20044190056a10ac0320044185036a20042903b802503a0000200441ed026a200341086a290000370000200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441043a00e402200441073a00e002200420032900003700e50241b0b4cc004100200441e0026a10d4010b200441e0026a2003109a0720043502e80242208620042802e0022200ad841007024020042802e402450d00200010350b20044190056a41186a2206420037030020044190056a41106a2207420037030020044190056a41086a22084200370300200442003703900541dad5ca00ad4280808080b00284220910012200290000210a2008200041086a2900003703002004200a37039005200010354180eaca00ad4280808080900184220b10012200290000210a200441086a41086a220c200041086a2900003703002004200a3703082000103520072004290308220a370300200441e0026a41086a220d2008290300370300200441e0026a41106a220e200a370300200441e0026a41186a220f200c29030037030020042004290390053703e00220044190056a200441e0026a412010b5022004280290052200410120001b21100240200429029405420020001b2211422088a72212450d0041002101201021004100210502400240034002400240024020032000460d0020002003412010a008450d0020010d01410021010c020b200141016a21010c010b200520016b221320124f0d022006200020014105746b221341186a22142900003703002007201341106a22152900003703002008201341086a22162900003703002004201329000037039005200041086a2217290000210a200041106a22182900002119200041186a221a290000211b201320002900003700002014201b370000201520193700002016200a370000201a2006290300370000201820072903003700002017200829030037000020002004290390053700000b200041206a21002012200541016a2205460d020c000b0b2013201241f485cc001042000b2001417f6a20124f0d00201220016bad422086201142ffffffff0f838421110b200f4200370300200e4200370300200d4200370300200442003703e002200910012200290000210a200d200041086a2900003703002004200a3703e00220001035200b10012200290000210a200c200041086a2900003703002004200a37030820001035200e2004290308220a3703002008200d2903003703002007200a3703002006200c290300370300200420042903e002370390050240024020100d0020044190056aad428080808080048410070c010b200441203602e402200420044190056a3602e00220102011422088a7200441e0026a10c504201142ffffff3f83500d00201010350b02402002410c6a28020041ffffff3f71450d00200228020810350b0240200241186a28020041ffffff3f71450d00200228021410350b200441c0076a24000b9f0303027f017e027f230041206b2202240041dad5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354188b8cb00ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b9f0303027f017e027f230041206b2202240041c7d5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354188b8cb00ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b9f0303027f017e027f230041206b2202240041c7d5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354190eaca00ad4280808080e00084100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b9b0c08057f037e057f017e077f017e017f017e230041c0076b220424000240024020000d00200441e0026a200310a00720043502e80242208620042802e0022200ad841007024020042802e402450d00200010350b200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441083a00e002200441ed026a200341086a290000370000200441033a00e402200420032900003700e50241b0b4cc004100200441e0026a10d4010c010b200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441083a00e002200441ed026a200341086a290000370000200441023a00e402200420032900003700e50241b0b4cc004100200441e0026a10d401200441b8026a200310a007200441e0026a20042802b802220520042802c00210e30220042802e002210020044190056a200441e0026a41047241ac02109d081a02402000411b470d0020042802bc02450d01200510350c010b200441086a20044190056a41ac02109d081a024020042802bc02450d00200510350b20022802042105200420003602e002200441e0026a410472200441086a41ac02109d081a2004419c056a200136020020044190056a41086a2005360200200441003a009405200441023a009005200441b8026a200441e0026a20044190056a10ac0320044185036a20042903b802503a0000200441ed026a200341086a290000370000200441f5026a200341106a290000370000200441fd026a200341186a290000370000200441043a00e402200441083a00e002200420032900003700e50241b0b4cc004100200441e0026a10d4010b200441e0026a2003109e0720043502e80242208620042802e0022200ad841007024020042802e402450d00200010350b20044190056a41186a2206420037030020044190056a41106a2207420037030020044190056a41086a22084200370300200442003703900541c7d5ca00ad4280808080b00284220910012200290000210a2008200041086a2900003703002004200a37039005200010354180eaca00ad4280808080900184220b10012200290000210a200441086a41086a220c200041086a2900003703002004200a3703082000103520072004290308220a370300200441e0026a41086a220d2008290300370300200441e0026a41106a220e200a370300200441e0026a41186a220f200c29030037030020042004290390053703e00220044190056a200441e0026a412010b5022004280290052200410120001b21100240200429029405420020001b2211422088a72212450d0041002101201021004100210502400240034002400240024020032000460d0020002003412010a008450d0020010d01410021010c020b200141016a21010c010b200520016b221320124f0d022006200020014105746b221341186a22142900003703002007201341106a22152900003703002008201341086a22162900003703002004201329000037039005200041086a2217290000210a200041106a22182900002119200041186a221a290000211b201320002900003700002014201b370000201520193700002016200a370000201a2006290300370000201820072903003700002017200829030037000020002004290390053700000b200041206a21002012200541016a2205460d020c000b0b2013201241f485cc001042000b2001417f6a20124f0d00201220016bad422086201142ffffffff0f838421110b200f4200370300200e4200370300200d4200370300200442003703e002200910012200290000210a200d200041086a2900003703002004200a3703e00220001035200b10012200290000210a200c200041086a2900003703002004200a37030820001035200e2004290308220a3703002008200d2903003703002007200a3703002006200c290300370300200420042903e002370390050240024020100d0020044190056aad428080808080048410070c010b200441203602e402200420044190056a3602e00220102011422088a7200441e0026a10c504201142ffffff3f83500d00201010350b02402002410c6a28020041ffffff3f71450d00200228020810350b0240200241186a28020041ffffff3f71450d00200228021410350b200441c0076a24000b9f0303027f017e027f230041206b2202240041c7d5ca00ad4280808080b00284100122032900002104200241086a200341086a29000037030020022004370300200310354188b8cb00ad4280808080a00184100122032900002104200241106a41086a200341086a29000037030020022004370310200310350240412010332203450d0020032001290000370000200341186a2205200141186a290000370000200341106a2206200141106a290000370000200341086a200141086a290000370000412010332201450d0020012003290000370000200141186a2005290000370000200141106a2006290000370000200141086a2205200341086a2900003700002003103541c00010332203450d002003200229031037001020032002290300370000200341086a200241086a290300370000200341186a200241106a41086a290300370000200042c080808080083702042000200336020020032001290000370020200341286a2005290000370000200341306a200141106a290000370000200341386a200141186a29000037000020011035200241206a24000f0b1045000b130020004107360204200041accdcb003602000bcc04020d7f017e230041c0006b22032400200128020822044104742105200128020421062001280200220721010240024002402004450d00200341306a410172210841002104200341306a41026a2109200341206a410172220a41076a210b03402009200720046a220141036a2d00003a00002003200141016a2f00003b0130024020012d0000220c41ac01470d00200141106a21010c020b2003410c6a41026a20092d0000220d3a0000200320032f0130220e3b010c200141046a280200210f200141086a29030021102008200e3b0000200841026a200d3a00002003200c3a0030200320103703382003200f360234200341206a200341306a200210a3072003200a2900003703102003200b290000370017024020032d0020220c411f470d002005200441106a2204470d010c030b0b2000200c3a000020002003290310370001200041086a20032900173700000240200541706a2004460d00200141146a2101200520046b41706a2104034002402001417c6a2d00004109470d0002402001280200220928020441ffffffff0371450d0020092802001035200128020021090b200910350b200141106a2101200441706a22040d000b0b200641ffffffff0071450d02200710350c020b200720056a22092001460d000340200141106a2104024020012d00004109470d000240200141046a2208280200220128020441ffffffff0371450d0020012802001035200828020021010b200110350b2004210120092004470d000b0b0240200641ffffffff0071450d00200710350b2000411f3a00000b200341c0006a24000b9bee0202097f017e230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad01200441017422062005200620054b1b22064100480dad010240024020040d00024020060d00410121050c020b2006103322050d010cb9010b2002280204210520042006460d0020052004200610372205450db8010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41003a00002002410c6a200441016a3602000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac01200441017422062005200620054b1b22064100480dac010240024020040d00024020060d00410121050c020b200610332205450db8010c010b2002280204210520042006460d0020052004200610372205450db7010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41013a00002002410c6a200441016a3602000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490dab01200441017422082005200820054b1b22084100480dab010240024020040d00024020080d00410121050c020b200810332205450db7010c010b2006280200210520042008460d0020052004200810372205450db6010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41023a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490dab01200441017422082005200820054b1b22084100480dab010240024020040d00024020080d00410121050c020b200810332205450db7010c010b2006280200210520042008460d0020052004200810372205450db6010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490daa01200441017422082005200820054b1b22084100480daa010240024020040d00024020080d00410121050c020b200810332205450db6010c010b2006280200210520042008460d0020052004200810372205450db5010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41033a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490daa01200441017422082005200820054b1b22084100480daa010240024020040d00024020080d00410121050c020b200810332205450db6010c010b2006280200210520042008460d0020052004200810372205450db5010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490da901200441017422082005200820054b1b22084100480da9010240024020040d00024020080d00410121050c020b200810332205450db5010c010b2006280200210520042008460d0020052004200810372205450db4010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41043a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490da901200441017422082005200820054b1b22084100480da9010240024020040d00024020080d00410121050c020b200810332205450db5010c010b2006280200210520042008460d0020052004200810372205450db4010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da801200441017422062005200620054b1b22064100480da8010240024020040d00024020060d00410121050c020b200610332205450db4010c010b2002280204210520042006460d0020052004200610372205450db3010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41053a00002002410c6a200441016a3602000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da701200441017422062005200620054b1b22064100480da7010240024020040d00024020060d00410121050c020b200610332205450db3010c010b2002280204210520042006460d0020052004200610372205450db2010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410b3a00002002410c6a200441016a3602000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da601200441017422072006200720064b1b22074100480da6010240024020040d00024020070d00410121060c020b200710332206450db2010c010b2009280200210620042007460d0020062004200710372206450db1010b20022006360204200241086a20073602002002410c6a28020021040b200620046a410c3a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da701200441017422072006200720064b1b22074100480da7010240024020040d00024020070d00410121060c020b200710332206450db3010c010b2009280200210620042007460d0020062004200710372206450db2010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da501200441017422072006200720064b1b22074100480da5010240024020040d00024020070d00410121060c020b200710332206450db1010c010b2009280200210620042007460d0020062004200710372206450db0010b20022006360204200241086a20073602002002410c6a28020021040b200620046a410d3a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da601200441017422072006200720064b1b22074100480da6010240024020040d00024020070d00410121060c020b200710332206450db2010c010b2009280200210620042007460d0020062004200710372206450db1010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca4010b0b200241046a210902400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490da401200441017422062005200620054b1b22064100480da4010240024020040d00024020060d00410121050c020b200610332205450db0010c010b2009280200210520042006460d0020052004200610372205450daf010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410e3a00002002410c6a2208200441016a360200200320012802042204280204220520042802002204200420054102746a200210a4072003210420032d0000411f470dab012008280200210420012802042802082105200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da501200441017422072006200720064b1b22074100480da5010240024020040d00024020070d00410121060c020b200710332206450db1010c010b2009280200210620042007460d0020062004200710372206450db0010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca3010b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da301200441017422062005200620054b1b22064100480da3010240024020040d00024020060d00410121050c020b200610332205450daf010c010b2002280204210520042006460d0020052004200610372205450dae010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410f3a00002002410c6a200441016a3602000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da201200441017422072006200720064b1b22074100480da2010240024020040d00024020070d00410121060c020b200710332206450dae010c010b2009280200210620042007460d0020062004200710372206450dad010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41103a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da301200441017422072006200720064b1b22074100480da3010240024020040d00024020070d00410121060c020b200710332206450daf010c010b2009280200210620042007460d0020062004200710372206450dae010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da101200441017422072006200720064b1b22074100480da1010240024020040d00024020070d00410121060c020b200710332206450dad010c010b2009280200210620042007460d0020062004200710372206450dac010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41113a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da201200441017422072006200720064b1b22074100480da2010240024020040d00024020070d00410121060c020b200710332206450dae010c010b2009280200210620042007460d0020062004200710372206450dad010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000b02400240200241086a2802002004460d00200928020021050c010b200441016a22052004490da101200441017422062005200620054b1b22064100480da1010240024020040d00024020060d00410121050c020b200610332205450dad010c010b2009280200210520042006460d0020052004200610372205450dac010b20022005360204200241086a20063602002002410c6a28020021040b200520046a200b3a00002002410c6a200441016a3602000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da001200441017422062005200620054b1b22064100480da0010240024020040d00024020060d00410121050c020b200610332205450dac010c010b2002280204210520042006460d0020052004200610372205450dab010b20022005360204200241086a20063602002002410c6a28020021040b200520046a411a3a00002002410c6a200441016a3602000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f01200441017422062005200620054b1b22064100480d9f010240024020040d00024020060d00410121050c020b200610332205450dab010c010b2002280204210520042006460d0020052004200610372205450daa010b20022005360204200241086a20063602002002410c6a28020021040b200520046a411b3a00002002410c6a200441016a3602000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9e01200441017422072006200720064b1b22074100480d9e010240024020040d00024020070d00410121060c020b200710332206450daa010c010b2009280200210620042007460d0020062004200710372206450da9010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41203a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9f01200441017422072006200720064b1b22074100480d9f010240024020040d00024020070d00410121060c020b200710332206450dab010c010b2009280200210620042007460d0020062004200710372206450daa010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9d01200441017422072006200720064b1b22074100480d9d010240024020040d00024020070d00410121060c020b200710332206450da9010c010b2009280200210620042007460d0020062004200710372206450da8010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41213a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9e01200441017422072006200720064b1b22074100480d9e010240024020040d00024020070d00410121060c020b200710332206450daa010c010b2009280200210620042007460d0020062004200710372206450da9010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9c01200441017422072006200720064b1b22074100480d9c010240024020040d00024020070d00410121060c020b200710332206450da8010c010b2009280200210620042007460d0020062004200710372206450da7010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41223a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9d01200441017422072006200720064b1b22074100480d9d010240024020040d00024020070d00410121060c020b200710332206450da9010c010b2009280200210620042007460d0020062004200710372206450da8010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9b01200441017422072006200720064b1b22074100480d9b010240024020040d00024020070d00410121060c020b200710332206450da7010c010b2009280200210620042007460d0020062004200710372206450da6010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41233a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9c01200441017422072006200720064b1b22074100480d9c010240024020040d00024020070d00410121060c020b200710332206450da8010c010b2009280200210620042007460d0020062004200710372206450da7010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9a01200441017422072006200720064b1b22074100480d9a010240024020040d00024020070d00410121060c020b200710332206450da6010c010b2009280200210620042007460d0020062004200710372206450da5010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41243a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9b01200441017422072006200720064b1b22074100480d9b010240024020040d00024020070d00410121060c020b200710332206450da7010c010b2009280200210620042007460d0020062004200710372206450da6010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c99010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9901200441017422082007200820074b1b22084100480d99010240024020040d00024020080d00410121070c020b200810332207450da5010c010b200a280200210720042008460d0020072004200810372207450da4010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41283a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9a01200441017422082007200820074b1b22084100480d9a010240024020040d00024020080d00410121070c020b200810332207450da6010c010b200a280200210720042008460d0020072004200810372207450da5010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9a01200441017422072005200720054b1b22074100480d9a010240024020040d00024020070d00410121050c020b200710332205450da6010c010b200a280200210520042007460d0020052004200710372205450da5010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9801200441017422082007200820074b1b22084100480d98010240024020040d00024020080d00410121070c020b200810332207450da4010c010b200a280200210720042008460d0020072004200810372207450da3010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41293a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9901200441017422082007200820074b1b22084100480d99010240024020040d00024020080d00410121070c020b200810332207450da5010c010b200a280200210720042008460d0020072004200810372207450da4010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9901200441017422072006200720064b1b22074100480d99010240024020040d00024020070d00410121060c020b200710332206450da5010c010b200a280200210620042007460d0020062004200710372206450da4010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9701200441017422082007200820074b1b22084100480d97010240024020040d00024020080d00410121070c020b200810332207450da3010c010b200a280200210720042008460d0020072004200810372207450da2010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412a3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9801200441017422082007200820074b1b22084100480d98010240024020040d00024020080d00410121070c020b200810332207450da4010c010b200a280200210720042008460d0020072004200810372207450da3010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9801200441017422072006200720064b1b22074100480d98010240024020040d00024020070d00410121060c020b200710332206450da4010c010b200a280200210620042007460d0020062004200710372206450da3010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c96010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b200810332207450da2010c010b200a280200210720042008460d0020072004200810372207450da1010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412b3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9701200441017422082007200820074b1b22084100480d97010240024020040d00024020080d00410121070c020b200810332207450da3010c010b200a280200210720042008460d0020072004200810372207450da2010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9701200441017422072005200720054b1b22074100480d97010240024020040d00024020070d00410121050c020b200710332205450da3010c010b200a280200210520042007460d0020052004200710372205450da2010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b200810332207450da1010c010b200a280200210720042008460d0020072004200810372207450da0010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412c3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b200810332207450da2010c010b200a280200210720042008460d0020072004200810372207450da1010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9601200441017422072006200720064b1b22074100480d96010240024020040d00024020070d00410121060c020b200710332206450da2010c010b200a280200210620042007460d0020062004200710372206450da1010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b200810332207450da0010c010b200a280200210720042008460d0020072004200810372207450d9f010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412d3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b2008103322070d010c9e010b200a280200210720042008460d0020072004200810372207450d9c010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9601200441017422072006200720064b1b22074100480d96010240024020040d00024020070d00410121060c020b2007103322060d010c9e010b200a280200210620042007460d0020062004200710372206450d9c010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9401200441017422082007200820074b1b22084100480d94010240024020040d00024020080d00410121070c020b2008103322070d010c9c010b200a280200210720042008460d0020072004200810372207450d9a010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412e3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b2008103322070d010c9d010b200a280200210720042008460d0020072004200810372207450d9b010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9501200441017422072006200720064b1b22074100480d95010240024020040d00024020070d00410121060c020b2007103322060d010c9d010b200a280200210620042007460d0020062004200710372206450d9b010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9301200441017422082007200820074b1b22084100480d93010240024020040d00024020080d00410121070c020b2008103322070d010c9b010b200a280200210720042008460d0020072004200810372207450d99010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412f3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9401200441017422082007200820074b1b22084100480d94010240024020040d00024020080d00410121070c020b2008103322070d010c9c010b200a280200210720042008460d0020072004200810372207450d9a010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9401200441017422072006200720064b1b22074100480d94010240024020040d00024020070d00410121060c020b2007103322060d010c9c010b200a280200210620042007460d0020062004200710372206450d9a010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c91010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9201200441017422082007200820074b1b22084100480d92010240024020040d00024020080d00410121070c020b2008103322070d010c9a010b200a280200210720042008460d0020072004200810372207450d98010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41303a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9301200441017422082007200820074b1b22084100480d93010240024020040d00024020080d00410121070c020b2008103322070d010c9b010b200a280200210720042008460d0020072004200810372207450d99010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9301200441017422072005200720054b1b22074100480d93010240024020040d00024020070d00410121050c020b2007103322050d010c9b010b200a280200210520042007460d0020052004200710372205450d99010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9101200441017422082007200820074b1b22084100480d91010240024020040d00024020080d00410121070c020b2008103322070d010c99010b200a280200210720042008460d0020072004200810372207450d97010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41313a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9201200441017422082007200820074b1b22084100480d92010240024020040d00024020080d00410121070c020b2008103322070d010c9a010b200a280200210720042008460d0020072004200810372207450d98010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9201200441017422072006200720064b1b22074100480d92010240024020040d00024020070d00410121060c020b2007103322060d010c9a010b200a280200210620042007460d0020062004200710372206450d98010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9001200441017422082007200820074b1b22084100480d90010240024020040d00024020080d00410121070c020b2008103322070d010c98010b200a280200210720042008460d0020072004200810372207450d96010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41323a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9101200441017422082007200820074b1b22084100480d91010240024020040d00024020080d00410121070c020b2008103322070d010c99010b200a280200210720042008460d0020072004200810372207450d97010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9101200441017422072006200720064b1b22074100480d91010240024020040d00024020070d00410121060c020b2007103322060d010c99010b200a280200210620042007460d0020062004200710372206450d97010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8f01200441017422082007200820074b1b22084100480d8f010240024020040d00024020080d00410121070c020b2008103322070d010c97010b200a280200210720042008460d0020072004200810372207450d95010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41333a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9001200441017422082007200820074b1b22084100480d90010240024020040d00024020080d00410121070c020b2008103322070d010c98010b200a280200210720042008460d0020072004200810372207450d96010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9001200441017422072006200720064b1b22074100480d90010240024020040d00024020070d00410121060c020b2007103322060d010c98010b200a280200210620042007460d0020062004200710372206450d96010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8d010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8e01200441017422082007200820074b1b22084100480d8e010240024020040d00024020080d00410121070c020b2008103322070d010c96010b200a280200210720042008460d0020072004200810372207450d94010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41343a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8f01200441017422082007200820074b1b22084100480d8f010240024020040d00024020080d00410121070c020b2008103322070d010c97010b200a280200210720042008460d0020072004200810372207450d95010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8f01200441017422072005200720054b1b22074100480d8f010240024020040d00024020070d00410121050c020b2007103322050d010c97010b200a280200210520042007460d0020052004200710372205450d95010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8d01200441017422082007200820074b1b22084100480d8d010240024020040d00024020080d00410121070c020b2008103322070d010c95010b200a280200210720042008460d0020072004200810372207450d93010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41353a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8e01200441017422082007200820074b1b22084100480d8e010240024020040d00024020080d00410121070c020b2008103322070d010c96010b200a280200210720042008460d0020072004200810372207450d94010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8e01200441017422072006200720064b1b22074100480d8e010240024020040d00024020070d00410121060c020b2007103322060d010c96010b200a280200210620042007460d0020062004200710372206450d94010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8b010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8c01200441017422082007200820074b1b22084100480d8c010240024020040d00024020080d00410121070c020b2008103322070d010c94010b200a280200210720042008460d0020072004200810372207450d92010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41363a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8d01200441017422082007200820074b1b22084100480d8d010240024020040d00024020080d00410121070c020b2008103322070d010c95010b200a280200210720042008460d0020072004200810372207450d93010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8d01200441017422072005200720054b1b22074100480d8d010240024020040d00024020070d00410121050c020b2007103322050d010c95010b200a280200210520042007460d0020052004200710372205450d93010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8b01200441017422082007200820074b1b22084100480d8b010240024020040d00024020080d00410121070c020b2008103322070d010c93010b200a280200210720042008460d0020072004200810372207450d91010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41373a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8c01200441017422082007200820074b1b22084100480d8c010240024020040d00024020080d00410121070c020b2008103322070d010c94010b200a280200210720042008460d0020072004200810372207450d92010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8c01200441017422072006200720064b1b22074100480d8c010240024020040d00024020070d00410121060c020b2007103322060d010c94010b200a280200210620042007460d0020062004200710372206450d92010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c89010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8a01200441017422082007200820074b1b22084100480d8a010240024020040d00024020080d00410121070c020b2008103322070d010c92010b200a280200210720042008460d0020072004200810372207450d90010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41383a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8b01200441017422082007200820074b1b22084100480d8b010240024020040d00024020080d00410121070c020b2008103322070d010c93010b200a280200210720042008460d0020072004200810372207450d91010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8b01200441017422072005200720054b1b22074100480d8b010240024020040d00024020070d00410121050c020b2007103322050d010c93010b200a280200210520042007460d0020052004200710372205450d91010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8901200441017422082007200820074b1b22084100480d89010240024020040d00024020080d00410121070c020b2008103322070d010c91010b200a280200210720042008460d0020072004200810372207450d8f010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41393a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8a01200441017422082007200820074b1b22084100480d8a010240024020040d00024020080d00410121070c020b2008103322070d010c92010b200a280200210720042008460d0020072004200810372207450d90010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8a01200441017422072006200720064b1b22074100480d8a010240024020040d00024020070d00410121060c020b2007103322060d010c92010b200a280200210620042007460d0020062004200710372206450d90010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8801200441017422082007200820074b1b22084100480d88010240024020040d00024020080d00410121070c020b2008103322070d010c90010b200a280200210720042008460d0020072004200810372207450d8e010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413a3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8901200441017422082007200820074b1b22084100480d89010240024020040d00024020080d00410121070c020b2008103322070d010c91010b200a280200210720042008460d0020072004200810372207450d8f010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8901200441017422072006200720064b1b22074100480d89010240024020040d00024020070d00410121060c020b2007103322060d010c91010b200a280200210620042007460d0020062004200710372206450d8f010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8701200441017422082007200820074b1b22084100480d87010240024020040d00024020080d00410121070c020b2008103322070d010c8f010b200a280200210720042008460d0020072004200810372207450d8d010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413b3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8801200441017422082007200820074b1b22084100480d88010240024020040d00024020080d00410121070c020b2008103322070d010c90010b200a280200210720042008460d0020072004200810372207450d8e010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8801200441017422072006200720064b1b22074100480d88010240024020040d00024020070d00410121060c020b2007103322060d010c90010b200a280200210620042007460d0020062004200710372206450d8e010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c85010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8601200441017422082007200820074b1b22084100480d86010240024020040d00024020080d00410121070c020b2008103322070d010c8e010b200a280200210720042008460d0020072004200810372207450d8c010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413c3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8701200441017422082007200820074b1b22084100480d87010240024020040d00024020080d00410121070c020b2008103322070d010c8f010b200a280200210720042008460d0020072004200810372207450d8d010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8701200441017422072006200720064b1b22074100480d87010240024020040d00024020070d00410121060c020b2007103322060d010c8f010b200a280200210620042007460d0020062004200710372206450d8d010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c84010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8501200441017422082007200820074b1b22084100480d85010240024020040d00024020080d00410121070c020b2008103322070d010c8d010b200a280200210720042008460d0020072004200810372207450d8b010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413d3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8601200441017422082007200820074b1b22084100480d86010240024020040d00024020080d00410121070c020b2008103322070d010c8e010b200a280200210720042008460d0020072004200810372207450d8c010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8601200441017422072005200720054b1b22074100480d86010240024020040d00024020070d00410121050c020b2007103322050d010c8e010b200a280200210520042007460d0020052004200710372205450d8c010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c83010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8401200441017422082007200820074b1b22084100480d84010240024020040d00024020080d00410121070c020b2008103322070d010c8c010b200a280200210720042008460d0020072004200810372207450d8a010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413e3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8501200441017422082007200820074b1b22084100480d85010240024020040d00024020080d00410121070c020b2008103322070d010c8d010b200a280200210720042008460d0020072004200810372207450d8b010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8501200441017422072005200720054b1b22074100480d85010240024020040d00024020070d00410121050c020b2007103322050d010c8d010b200a280200210520042007460d0020052004200710372205450d8b010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8b010b2006280200210520042008460d0020052004200810372205450d89010b20022005360204200241086a20083602002002410c6a28020021040b200520046a413f3a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8b010b2006280200210520042008460d0020052004200810372205450d89010b20022005360204200241086a20083602002002410c6a28020021040b200520046a20073a00002002410c6a200441016a3602000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8201200441017422082005200820054b1b22084100480d82010240024020040d00024020080d00410121050c020b2008103322050d010c8a010b2006280200210520042008460d0020052004200810372205450d88010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41c0003a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8a010b2006280200210520042008460d0020052004200810372205450d88010b20022005360204200241086a20083602002002410c6a28020021040b200520046a20073a00002002410c6a200441016a3602000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8201200441017422072005200720054b1b22074100480d82010240024020040d00024020070d00410121050c020b2007103322050d010c89010b2002280204210520042007460d0020052004200710372205450d84010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c1003a00002002410c6a200441016a36020020032006200210a5072003210420032d0000411f470d87010c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8101200441017422062005200620054b1b22064100480d81010240024020040d00024020060d00410121050c020b2006103322050d010c88010b2002280204210520042006460d0020052004200610372205450d83010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c2003a00002002410c6a200441016a3602002003200c200210a6072003210420032d0000411f470d86010c7d0b200241046a2106200141046a280200210802400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8001200441017422072005200720054b1b22074100480d80010240024020040d00024020070d00410121050c020b2007103322050d010c87010b2006280200210520042007460d0020052004200710372205450d82010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c3003a00002002410c6a200441016a220436020002400240200241086a280200220720046b4104490d00200628020021050c010b200441046a22052004490d8001200741017422042005200420054b1b22044100480d80010240024020070d00024020040d00410121050c020b2004103322050d010c87010b2006280200210520072004460d0020052007200410372205450d82010b20022005360204200241086a20043602002002410c6a28020021040b200520046a20083600002002410c6a200441046a3602000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d7f200441017422072005200720054b1b22074100480d7f0240024020040d00024020070d00410121050c020b2007103322050d010c86010b2006280200210520042007460d0020052004200710372205450d81010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c4003a00002002410c6a200441016a220436020002400240200241086a280200220720046b4108490d00200628020021050c010b200441086a22052004490d7f200741017422042005200420054b1b22044100480d7f0240024020070d00024020040d00410121050c020b2004103322050d010c86010b2006280200210520072004460d0020052007200410372205450d81010b20022005360204200241086a20043602002002410c6a28020021040b200520046a200c3700002002410c6a200441086a3602000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7e200441017422062005200620054b1b22064100480d7e0240024020040d00024020060d00410121050c020b2006103322050d010c85010b2002280204210520042006460d0020052004200610372205450d80010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c5003a00002002410c6a200441016a3602000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7d200441017422062005200620054b1b22064100480d7d0240024020040d00024020060d00410121050c020b2006103322050d010c84010b2002280204210520042006460d0020052004200610372205450d7f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c6003a00002002410c6a200441016a3602000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7c200441017422062005200620054b1b22064100480d7c0240024020040d00024020060d00410121050c020b2006103322050d010c83010b2002280204210520042006460d0020052004200610372205450d7e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c7003a00002002410c6a200441016a3602000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7b200441017422062005200620054b1b22064100480d7b0240024020040d00024020060d00410121050c020b2006103322050d010c82010b2002280204210520042006460d0020052004200610372205450d7d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c8003a00002002410c6a200441016a3602000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7a200441017422062005200620054b1b22064100480d7a0240024020040d00024020060d00410121050c020b2006103322050d010c81010b2002280204210520042006460d0020052004200610372205450d7c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c9003a00002002410c6a200441016a3602000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d79200441017422062005200620054b1b22064100480d790240024020040d00024020060d00410121050c020b2006103322050d010c80010b2002280204210520042006460d0020052004200610372205450d7b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ca003a00002002410c6a200441016a3602000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d78200441017422062005200620054b1b22064100480d780240024020040d00024020060d00410121050c020b2006103322050d010c7f0b2002280204210520042006460d0020052004200610372205450d7a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cb003a00002002410c6a200441016a3602000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d77200441017422062005200620054b1b22064100480d770240024020040d00024020060d00410121050c020b2006103322050d010c7e0b2002280204210520042006460d0020052004200610372205450d790b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cc003a00002002410c6a200441016a3602000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d76200441017422062005200620054b1b22064100480d760240024020040d00024020060d00410121050c020b2006103322050d010c7d0b2002280204210520042006460d0020052004200610372205450d780b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cd003a00002002410c6a200441016a3602000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d75200441017422062005200620054b1b22064100480d750240024020040d00024020060d00410121050c020b2006103322050d010c7c0b2002280204210520042006460d0020052004200610372205450d770b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ce003a00002002410c6a200441016a3602000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d74200441017422062005200620054b1b22064100480d740240024020040d00024020060d00410121050c020b2006103322050d010c7b0b2002280204210520042006460d0020052004200610372205450d760b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cf003a00002002410c6a200441016a3602000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d73200441017422062005200620054b1b22064100480d730240024020040d00024020060d00410121050c020b2006103322050d010c7a0b2002280204210520042006460d0020052004200610372205450d750b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d0003a00002002410c6a200441016a3602000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d72200441017422062005200620054b1b22064100480d720240024020040d00024020060d00410121050c020b2006103322050d010c790b2002280204210520042006460d0020052004200610372205450d740b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d1003a00002002410c6a200441016a3602000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d71200441017422062005200620054b1b22064100480d710240024020040d00024020060d00410121050c020b2006103322050d010c780b2002280204210520042006460d0020052004200610372205450d730b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d2003a00002002410c6a200441016a3602000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d70200441017422062005200620054b1b22064100480d700240024020040d00024020060d00410121050c020b2006103322050d010c770b2002280204210520042006460d0020052004200610372205450d720b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d3003a00002002410c6a200441016a3602000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6f200441017422062005200620054b1b22064100480d6f0240024020040d00024020060d00410121050c020b2006103322050d010c760b2002280204210520042006460d0020052004200610372205450d710b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d4003a00002002410c6a200441016a3602000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6e200441017422062005200620054b1b22064100480d6e0240024020040d00024020060d00410121050c020b2006103322050d010c750b2002280204210520042006460d0020052004200610372205450d700b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d5003a00002002410c6a200441016a3602000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6d200441017422062005200620054b1b22064100480d6d0240024020040d00024020060d00410121050c020b2006103322050d010c740b2002280204210520042006460d0020052004200610372205450d6f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d6003a00002002410c6a200441016a3602000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6c200441017422062005200620054b1b22064100480d6c0240024020040d00024020060d00410121050c020b2006103322050d010c730b2002280204210520042006460d0020052004200610372205450d6e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d7003a00002002410c6a200441016a3602000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6b200441017422062005200620054b1b22064100480d6b0240024020040d00024020060d00410121050c020b2006103322050d010c720b2002280204210520042006460d0020052004200610372205450d6d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d8003a00002002410c6a200441016a3602000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6a200441017422062005200620054b1b22064100480d6a0240024020040d00024020060d00410121050c020b2006103322050d010c710b2002280204210520042006460d0020052004200610372205450d6c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d9003a00002002410c6a200441016a3602000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d69200441017422062005200620054b1b22064100480d690240024020040d00024020060d00410121050c020b2006103322050d010c700b2002280204210520042006460d0020052004200610372205450d6b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41da003a00002002410c6a200441016a3602000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d68200441017422062005200620054b1b22064100480d680240024020040d00024020060d00410121050c020b2006103322050d010c6f0b2002280204210520042006460d0020052004200610372205450d6a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41db003a00002002410c6a200441016a3602000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d67200441017422062005200620054b1b22064100480d670240024020040d00024020060d00410121050c020b2006103322050d010c6e0b2002280204210520042006460d0020052004200610372205450d690b20022005360204200241086a20063602002002410c6a28020021040b200520046a41dc003a00002002410c6a200441016a3602000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d66200441017422062005200620054b1b22064100480d660240024020040d00024020060d00410121050c020b2006103322050d010c6d0b2002280204210520042006460d0020052004200610372205450d680b20022005360204200241086a20063602002002410c6a28020021040b200520046a41dd003a00002002410c6a200441016a3602000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d65200441017422062005200620054b1b22064100480d650240024020040d00024020060d00410121050c020b2006103322050d010c6c0b2002280204210520042006460d0020052004200610372205450d670b20022005360204200241086a20063602002002410c6a28020021040b200520046a41de003a00002002410c6a200441016a3602000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d64200441017422062005200620054b1b22064100480d640240024020040d00024020060d00410121050c020b2006103322050d010c6b0b2002280204210520042006460d0020052004200610372205450d660b20022005360204200241086a20063602002002410c6a28020021040b200520046a41df003a00002002410c6a200441016a3602000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d63200441017422062005200620054b1b22064100480d630240024020040d00024020060d00410121050c020b2006103322050d010c6a0b2002280204210520042006460d0020052004200610372205450d650b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e0003a00002002410c6a200441016a3602000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d62200441017422062005200620054b1b22064100480d620240024020040d00024020060d00410121050c020b2006103322050d010c690b2002280204210520042006460d0020052004200610372205450d640b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e1003a00002002410c6a200441016a3602000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d61200441017422062005200620054b1b22064100480d610240024020040d00024020060d00410121050c020b2006103322050d010c680b2002280204210520042006460d0020052004200610372205450d630b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e2003a00002002410c6a200441016a3602000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d60200441017422062005200620054b1b22064100480d600240024020040d00024020060d00410121050c020b2006103322050d010c670b2002280204210520042006460d0020052004200610372205450d620b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e3003a00002002410c6a200441016a3602000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5f200441017422062005200620054b1b22064100480d5f0240024020040d00024020060d00410121050c020b2006103322050d010c660b2002280204210520042006460d0020052004200610372205450d610b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e4003a00002002410c6a200441016a3602000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5e200441017422062005200620054b1b22064100480d5e0240024020040d00024020060d00410121050c020b2006103322050d010c650b2002280204210520042006460d0020052004200610372205450d600b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e5003a00002002410c6a200441016a3602000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5d200441017422062005200620054b1b22064100480d5d0240024020040d00024020060d00410121050c020b2006103322050d010c640b2002280204210520042006460d0020052004200610372205450d5f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e6003a00002002410c6a200441016a3602000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5c200441017422062005200620054b1b22064100480d5c0240024020040d00024020060d00410121050c020b2006103322050d010c630b2002280204210520042006460d0020052004200610372205450d5e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e7003a00002002410c6a200441016a3602000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5b200441017422062005200620054b1b22064100480d5b0240024020040d00024020060d00410121050c020b2006103322050d010c620b2002280204210520042006460d0020052004200610372205450d5d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e8003a00002002410c6a200441016a3602000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5a200441017422062005200620054b1b22064100480d5a0240024020040d00024020060d00410121050c020b2006103322050d010c610b2002280204210520042006460d0020052004200610372205450d5c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e9003a00002002410c6a200441016a3602000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d59200441017422062005200620054b1b22064100480d590240024020040d00024020060d00410121050c020b2006103322050d010c600b2002280204210520042006460d0020052004200610372205450d5b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ea003a00002002410c6a200441016a3602000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d58200441017422062005200620054b1b22064100480d580240024020040d00024020060d00410121050c020b2006103322050d010c5f0b2002280204210520042006460d0020052004200610372205450d5a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41eb003a00002002410c6a200441016a3602000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d57200441017422062005200620054b1b22064100480d570240024020040d00024020060d00410121050c020b2006103322050d010c5e0b2002280204210520042006460d0020052004200610372205450d590b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ec003a00002002410c6a200441016a3602000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d56200441017422062005200620054b1b22064100480d560240024020040d00024020060d00410121050c020b2006103322050d010c5d0b2002280204210520042006460d0020052004200610372205450d580b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ed003a00002002410c6a200441016a3602000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d55200441017422062005200620054b1b22064100480d550240024020040d00024020060d00410121050c020b2006103322050d010c5c0b2002280204210520042006460d0020052004200610372205450d570b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ee003a00002002410c6a200441016a3602000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d54200441017422062005200620054b1b22064100480d540240024020040d00024020060d00410121050c020b2006103322050d010c5b0b2002280204210520042006460d0020052004200610372205450d560b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ef003a00002002410c6a200441016a3602000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d53200441017422062005200620054b1b22064100480d530240024020040d00024020060d00410121050c020b2006103322050d010c5a0b2002280204210520042006460d0020052004200610372205450d550b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f0003a00002002410c6a200441016a3602000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d52200441017422062005200620054b1b22064100480d520240024020040d00024020060d00410121050c020b2006103322050d010c590b2002280204210520042006460d0020052004200610372205450d540b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f1003a00002002410c6a200441016a3602000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d51200441017422062005200620054b1b22064100480d510240024020040d00024020060d00410121050c020b2006103322050d010c580b2002280204210520042006460d0020052004200610372205450d530b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f2003a00002002410c6a200441016a3602000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d50200441017422062005200620054b1b22064100480d500240024020040d00024020060d00410121050c020b2006103322050d010c570b2002280204210520042006460d0020052004200610372205450d520b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f3003a00002002410c6a200441016a3602000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4f200441017422062005200620054b1b22064100480d4f0240024020040d00024020060d00410121050c020b2006103322050d010c560b2002280204210520042006460d0020052004200610372205450d510b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f4003a00002002410c6a200441016a3602000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4e200441017422062005200620054b1b22064100480d4e0240024020040d00024020060d00410121050c020b2006103322050d010c550b2002280204210520042006460d0020052004200610372205450d500b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f5003a00002002410c6a200441016a3602000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4d200441017422062005200620054b1b22064100480d4d0240024020040d00024020060d00410121050c020b2006103322050d010c540b2002280204210520042006460d0020052004200610372205450d4f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f6003a00002002410c6a200441016a3602000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4c200441017422062005200620054b1b22064100480d4c0240024020040d00024020060d00410121050c020b2006103322050d010c530b2002280204210520042006460d0020052004200610372205450d4e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f7003a00002002410c6a200441016a3602000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4b200441017422062005200620054b1b22064100480d4b0240024020040d00024020060d00410121050c020b2006103322050d010c520b2002280204210520042006460d0020052004200610372205450d4d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f8003a00002002410c6a200441016a3602000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4a200441017422062005200620054b1b22064100480d4a0240024020040d00024020060d00410121050c020b2006103322050d010c510b2002280204210520042006460d0020052004200610372205450d4c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f9003a00002002410c6a200441016a3602000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d49200441017422062005200620054b1b22064100480d490240024020040d00024020060d00410121050c020b2006103322050d010c500b2002280204210520042006460d0020052004200610372205450d4b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fa003a00002002410c6a200441016a3602000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d48200441017422062005200620054b1b22064100480d480240024020040d00024020060d00410121050c020b2006103322050d010c4f0b2002280204210520042006460d0020052004200610372205450d4a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fb003a00002002410c6a200441016a3602000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d47200441017422062005200620054b1b22064100480d470240024020040d00024020060d00410121050c020b2006103322050d010c4e0b2002280204210520042006460d0020052004200610372205450d490b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fc003a00002002410c6a200441016a3602000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d46200441017422062005200620054b1b22064100480d460240024020040d00024020060d00410121050c020b2006103322050d010c4d0b2002280204210520042006460d0020052004200610372205450d480b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fd003a00002002410c6a200441016a3602000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d45200441017422062005200620054b1b22064100480d450240024020040d00024020060d00410121050c020b2006103322050d010c4c0b2002280204210520042006460d0020052004200610372205450d470b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fe003a00002002410c6a200441016a3602000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d44200441017422062005200620054b1b22064100480d440240024020040d00024020060d00410121050c020b2006103322050d010c4b0b2002280204210520042006460d0020052004200610372205450d460b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ff003a00002002410c6a200441016a3602000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d43200441017422062005200620054b1b22064100480d430240024020040d00024020060d00410121050c020b2006103322050d010c4a0b2002280204210520042006460d0020052004200610372205450d450b20022005360204200241086a20063602002002410c6a28020021040b200520046a4180013a00002002410c6a200441016a3602000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d42200441017422062005200620054b1b22064100480d420240024020040d00024020060d00410121050c020b2006103322050d010c490b2002280204210520042006460d0020052004200610372205450d440b20022005360204200241086a20063602002002410c6a28020021040b200520046a4181013a00002002410c6a200441016a3602000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d41200441017422062005200620054b1b22064100480d410240024020040d00024020060d00410121050c020b2006103322050d010c480b2002280204210520042006460d0020052004200610372205450d430b20022005360204200241086a20063602002002410c6a28020021040b200520046a4182013a00002002410c6a200441016a3602000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d40200441017422062005200620054b1b22064100480d400240024020040d00024020060d00410121050c020b2006103322050d010c470b2002280204210520042006460d0020052004200610372205450d420b20022005360204200241086a20063602002002410c6a28020021040b200520046a4183013a00002002410c6a200441016a3602000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3f200441017422062005200620054b1b22064100480d3f0240024020040d00024020060d00410121050c020b2006103322050d010c460b2002280204210520042006460d0020052004200610372205450d410b20022005360204200241086a20063602002002410c6a28020021040b200520046a4184013a00002002410c6a200441016a3602000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3e200441017422062005200620054b1b22064100480d3e0240024020040d00024020060d00410121050c020b2006103322050d010c450b2002280204210520042006460d0020052004200610372205450d400b20022005360204200241086a20063602002002410c6a28020021040b200520046a4185013a00002002410c6a200441016a3602000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3d200441017422062005200620054b1b22064100480d3d0240024020040d00024020060d00410121050c020b2006103322050d010c440b2002280204210520042006460d0020052004200610372205450d3f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4186013a00002002410c6a200441016a3602000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3c200441017422062005200620054b1b22064100480d3c0240024020040d00024020060d00410121050c020b2006103322050d010c430b2002280204210520042006460d0020052004200610372205450d3e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4187013a00002002410c6a200441016a3602000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3b200441017422062005200620054b1b22064100480d3b0240024020040d00024020060d00410121050c020b2006103322050d010c420b2002280204210520042006460d0020052004200610372205450d3d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4188013a00002002410c6a200441016a3602000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3d200441017422062005200620054b1b22064100480d3d0240024020040d00024020060d00410121050c020b2006103322050d010c410b2002280204210520042006460d0020052004200610372205450d3c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4189013a00002002410c6a200441016a3602000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3c200441017422062005200620054b1b22064100480d3c0240024020040d00024020060d00410121050c020b2006103322050d010c400b2002280204210520042006460d0020052004200610372205450d3c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418a013a00002002410c6a200441016a3602000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3b200441017422062005200620054b1b22064100480d3b0240024020040d00024020060d00410121050c020b2006103322050d010c3f0b2002280204210520042006460d0020052004200610372205450d3b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418b013a00002002410c6a200441016a3602000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3a200441017422062005200620054b1b22064100480d3a0240024020040d00024020060d00410121050c020b2006103322050d010c3e0b2002280204210520042006460d0020052004200610372205450d3a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418c013a00002002410c6a200441016a3602000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d39200441017422062005200620054b1b22064100480d390240024020040d00024020060d00410121050c020b2006103322050d010c3d0b2002280204210520042006460d0020052004200610372205450d390b20022005360204200241086a20063602002002410c6a28020021040b200520046a418d013a00002002410c6a200441016a3602000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d38200441017422062005200620054b1b22064100480d380240024020040d00024020060d00410121050c020b2006103322050d010c3c0b2002280204210520042006460d0020052004200610372205450d380b20022005360204200241086a20063602002002410c6a28020021040b200520046a418e013a00002002410c6a200441016a3602000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d37200441017422062005200620054b1b22064100480d370240024020040d00024020060d00410121050c020b2006103322050d010c3b0b2002280204210520042006460d0020052004200610372205450d370b20022005360204200241086a20063602002002410c6a28020021040b200520046a418f013a00002002410c6a200441016a3602000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d36200441017422062005200620054b1b22064100480d360240024020040d00024020060d00410121050c020b2006103322050d010c3a0b2002280204210520042006460d0020052004200610372205450d360b20022005360204200241086a20063602002002410c6a28020021040b200520046a4190013a00002002410c6a200441016a3602000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d35200441017422062005200620054b1b22064100480d350240024020040d00024020060d00410121050c020b2006103322050d010c390b2002280204210520042006460d0020052004200610372205450d350b20022005360204200241086a20063602002002410c6a28020021040b200520046a4191013a00002002410c6a200441016a3602000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d34200441017422062005200620054b1b22064100480d340240024020040d00024020060d00410121050c020b2006103322050d010c380b2002280204210520042006460d0020052004200610372205450d340b20022005360204200241086a20063602002002410c6a28020021040b200520046a4192013a00002002410c6a200441016a3602000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d33200441017422062005200620054b1b22064100480d330240024020040d00024020060d00410121050c020b2006103322050d010c370b2002280204210520042006460d0020052004200610372205450d330b20022005360204200241086a20063602002002410c6a28020021040b200520046a4193013a00002002410c6a200441016a3602000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d32200441017422062005200620054b1b22064100480d320240024020040d00024020060d00410121050c020b2006103322050d010c360b2002280204210520042006460d0020052004200610372205450d320b20022005360204200241086a20063602002002410c6a28020021040b200520046a4194013a00002002410c6a200441016a3602000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d31200441017422062005200620054b1b22064100480d310240024020040d00024020060d00410121050c020b2006103322050d010c350b2002280204210520042006460d0020052004200610372205450d310b20022005360204200241086a20063602002002410c6a28020021040b200520046a4195013a00002002410c6a200441016a3602000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d30200441017422062005200620054b1b22064100480d300240024020040d00024020060d00410121050c020b2006103322050d010c340b2002280204210520042006460d0020052004200610372205450d300b20022005360204200241086a20063602002002410c6a28020021040b200520046a4196013a00002002410c6a200441016a3602000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2f200441017422062005200620054b1b22064100480d2f0240024020040d00024020060d00410121050c020b2006103322050d010c330b2002280204210520042006460d0020052004200610372205450d2f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4197013a00002002410c6a200441016a3602000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2e200441017422062005200620054b1b22064100480d2e0240024020040d00024020060d00410121050c020b2006103322050d010c320b2002280204210520042006460d0020052004200610372205450d2e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4198013a00002002410c6a200441016a3602000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2d200441017422062005200620054b1b22064100480d2d0240024020040d00024020060d00410121050c020b2006103322050d010c310b2002280204210520042006460d0020052004200610372205450d2d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4199013a00002002410c6a200441016a3602000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2c200441017422062005200620054b1b22064100480d2c0240024020040d00024020060d00410121050c020b2006103322050d010c300b2002280204210520042006460d0020052004200610372205450d2c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419a013a00002002410c6a200441016a3602000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2b200441017422062005200620054b1b22064100480d2b0240024020040d00024020060d00410121050c020b2006103322050d010c2f0b2002280204210520042006460d0020052004200610372205450d2b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419b013a00002002410c6a200441016a3602000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2a200441017422062005200620054b1b22064100480d2a0240024020040d00024020060d00410121050c020b2006103322050d010c2d0b2002280204210520042006460d0020052004200610372205450d2a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419c013a00002002410c6a200441016a3602000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d29200441017422062005200620054b1b22064100480d290240024020040d00024020060d00410121050c020b200610332205450d2c0c010b2002280204210520042006460d0020052004200610372205450d290b20022005360204200241086a20063602002002410c6a28020021040b200520046a419d013a00002002410c6a200441016a3602000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d28200441017422062005200620054b1b22064100480d280240024020040d00024020060d00410121050c020b200610332205450d2b0c010b2002280204210520042006460d0020052004200610372205450d280b20022005360204200241086a20063602002002410c6a28020021040b200520046a419e013a00002002410c6a200441016a3602000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d27200441017422062005200620054b1b22064100480d270240024020040d00024020060d00410121050c020b200610332205450d2a0c010b2002280204210520042006460d0020052004200610372205450d270b20022005360204200241086a20063602002002410c6a28020021040b200520046a419f013a00002002410c6a200441016a3602000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d26200441017422062005200620054b1b22064100480d260240024020040d00024020060d00410121050c020b200610332205450d290c010b2002280204210520042006460d0020052004200610372205450d260b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a0013a00002002410c6a200441016a3602000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d25200441017422062005200620054b1b22064100480d250240024020040d00024020060d00410121050c020b200610332205450d280c010b2002280204210520042006460d0020052004200610372205450d250b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a1013a00002002410c6a200441016a3602000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d24200441017422062005200620054b1b22064100480d240240024020040d00024020060d00410121050c020b200610332205450d270c010b2002280204210520042006460d0020052004200610372205450d240b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a2013a00002002410c6a200441016a3602000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d23200441017422062005200620054b1b22064100480d230240024020040d00024020060d00410121050c020b200610332205450d260c010b2002280204210520042006460d0020052004200610372205450d230b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a3013a00002002410c6a200441016a3602000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d22200441017422062005200620054b1b22064100480d220240024020040d00024020060d00410121050c020b200610332205450d250c010b2002280204210520042006460d0020052004200610372205450d220b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a4013a00002002410c6a200441016a3602000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d00024020060d00410121050c020b200610332205450d240c010b2002280204210520042006460d0020052004200610372205450d210b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a5013a00002002410c6a200441016a3602000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d20200441017422062005200620054b1b22064100480d200240024020040d00024020060d00410121050c020b200610332205450d230c010b2002280204210520042006460d0020052004200610372205450d200b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a6013a00002002410c6a200441016a3602000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1f200441017422062005200620054b1b22064100480d1f0240024020040d00024020060d00410121050c020b200610332205450d220c010b2002280204210520042006460d0020052004200610372205450d1f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a7013a00002002410c6a200441016a3602000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1e200441017422062005200620054b1b22064100480d1e0240024020040d00024020060d00410121050c020b200610332205450d210c010b2002280204210520042006460d0020052004200610372205450d1e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a8013a00002002410c6a200441016a3602000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1d200441017422062005200620054b1b22064100480d1d0240024020040d00024020060d00410121050c020b200610332205450d200c010b2002280204210520042006460d0020052004200610372205450d1d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a9013a00002002410c6a200441016a3602000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1c200441017422062005200620054b1b22064100480d1c0240024020040d00024020060d00410121050c020b200610332205450d1f0c010b2002280204210520042006460d0020052004200610372205450d1c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41aa013a00002002410c6a200441016a3602000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1b200441017422062005200620054b1b22064100480d1b0240024020040d00024020060d00410121050c020b200610332205450d1e0c010b2002280204210520042006460d0020052004200610372205450d1b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ab013a00002002410c6a200441016a3602000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1a200441017422062005200620054b1b22064100480d1a0240024020040d00024020060d00410121050c020b200610332205450d1d0c010b2002280204210520042006460d0020052004200610372205450d1a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ac013a00002002410c6a200441016a3602000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d19200441017422062005200620054b1b22064100480d190240024020040d00024020060d00410121050c020b200610332205450d1c0c010b2002280204210520042006460d0020052004200610372205450d190b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ad013a00002002410c6a200441016a3602000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d18200441017422062005200620054b1b22064100480d180240024020040d00024020060d00410121050c020b200610332205450d1b0c010b2002280204210520042006460d0020052004200610372205450d180b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ae013a00002002410c6a200441016a3602000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d17200441017422062005200620054b1b22064100480d170240024020040d00024020060d00410121050c020b200610332205450d1a0c010b2002280204210520042006460d0020052004200610372205450d170b20022005360204200241086a20063602002002410c6a28020021040b200520046a41af013a00002002410c6a200441016a3602000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d16200441017422062005200620054b1b22064100480d160240024020040d00024020060d00410121050c020b200610332205450d190c010b2002280204210520042006460d0020052004200610372205450d160b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b0013a00002002410c6a200441016a3602000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d15200441017422062005200620054b1b22064100480d150240024020040d00024020060d00410121050c020b200610332205450d180c010b2002280204210520042006460d0020052004200610372205450d150b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b1013a00002002410c6a200441016a3602000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d14200441017422062005200620054b1b22064100480d140240024020040d00024020060d00410121050c020b200610332205450d170c010b2002280204210520042006460d0020052004200610372205450d140b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b2013a00002002410c6a200441016a3602000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d13200441017422062005200620054b1b22064100480d130240024020040d00024020060d00410121050c020b200610332205450d160c010b2002280204210520042006460d0020052004200610372205450d130b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b3013a00002002410c6a200441016a3602000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d12200441017422062005200620054b1b22064100480d120240024020040d00024020060d00410121050c020b200610332205450d150c010b2002280204210520042006460d0020052004200610372205450d120b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b4013a00002002410c6a200441016a3602000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d11200441017422062005200620054b1b22064100480d110240024020040d00024020060d00410121050c020b200610332205450d140c010b2002280204210520042006460d0020052004200610372205450d110b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b5013a00002002410c6a200441016a3602000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d10200441017422062005200620054b1b22064100480d100240024020040d00024020060d00410121050c020b200610332205450d130c010b2002280204210520042006460d0020052004200610372205450d100b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b6013a00002002410c6a200441016a3602000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0f200441017422062005200620054b1b22064100480d0f0240024020040d00024020060d00410121050c020b200610332205450d120c010b2002280204210520042006460d0020052004200610372205450d0f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b7013a00002002410c6a200441016a3602000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0e200441017422062005200620054b1b22064100480d0e0240024020040d00024020060d00410121050c020b200610332205450d110c010b2002280204210520042006460d0020052004200610372205450d0e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b8013a00002002410c6a200441016a3602000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0d200441017422062005200620054b1b22064100480d0d0240024020040d00024020060d00410121050c020b200610332205450d100c010b2002280204210520042006460d0020052004200610372205450d0d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b9013a00002002410c6a200441016a3602000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0c200441017422062005200620054b1b22064100480d0c0240024020040d00024020060d00410121050c020b200610332205450d0f0c010b2002280204210520042006460d0020052004200610372205450d0c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ba013a00002002410c6a200441016a3602000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0b200441017422062005200620054b1b22064100480d0b0240024020040d00024020060d00410121050c020b200610332205450d0e0c010b2002280204210520042006460d0020052004200610372205450d0b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bb013a00002002410c6a200441016a3602000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0a200441017422062005200620054b1b22064100480d0a0240024020040d00024020060d00410121050c020b200610332205450d0d0c010b2002280204210520042006460d0020052004200610372205450d0a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bc013a00002002410c6a200441016a3602000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d09200441017422062005200620054b1b22064100480d090240024020040d00024020060d00410121050c020b200610332205450d0c0c010b2002280204210520042006460d0020052004200610372205450d090b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bd013a00002002410c6a200441016a3602000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d08200441017422062005200620054b1b22064100480d080240024020040d00024020060d00410121050c020b200610332205450d0b0c010b2002280204210520042006460d0020052004200610372205450d080b20022005360204200241086a20063602002002410c6a28020021040b200520046a41be013a00002002410c6a200441016a3602000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d07200441017422062005200620054b1b22064100480d070240024020040d00024020060d00410121050c020b200610332205450d0a0c010b2002280204210520042006460d0020052004200610372205450d070b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bf013a00002002410c6a200441016a3602000b2000411f3a000020012d00004109470d090240200141046a280200220228020441ffffffff0371450d0020022802001035200128020421020b200210350c090b103e000b103e000b103e000b103c000b103c000b103e000b103c000b103c000b20002004290200370200200041086a200441086a29020037020020012d00004109470d000240200141046a280200220228020441ffffffff0371450d0020022802001035200128020421020b200210350b200341106a24000f0b103c000bd80301057f2004410c6a22052802002106200441086a21070240024003400240024020072802002006460d00200428020421080c010b200641016a22082006490d02200641017422092008200920084b1b22094100480d020240024020060d00024020090d00410121080c020b2009103322080d010c050b2004280204210820062009460d0020082006200910372208450d040b2004200836020420072009360200200528020021060b200820066a200141807f72200141ff0071200141077622081b3a00002005200641016a22063602002008210120080d000b024020022003460d00200441086a21052004410c6a210703402002280200210103400240024020052802002006460d00200428020421080c010b200641016a22082006490d04200641017422092008200920084b1b22094100480d040240024020060d00024020090d00410121080c020b200910332208450d070c010b2004280204210820062009460d0020082006200910372208450d060b2004200836020420052009360200200728020021060b200820066a200141807f72200141ff0071200141077622081b3a00002007200641016a22063602002008210120080d000b200241046a22022003470d000b0b2000411f3a00000f0b103e000b103c000bdb0301067f024002400240024020014107752203200141c00071220472452003417f4720044572470d002002410c6a28020021040c010b2002410c6a22052802002104200241086a210603400240024020062802002004460d00200228020421070c010b200441016a22072004490d03200441017422082007200820074b1b22084100480d030240024020040d00024020080d00410121070c020b2008103322070d010c060b2002280204210720042008460d0020072004200810372207450d050b2002200736020420062008360200200528020021040b200720046a200141807f723a00002005200441016a2204360200200341c000712107200321012003410775220821032008200772452008417f4720074572470d000b0b02400240200241086a2802002004460d00200228020421030c010b200441016a22032004490d01200441017422072003200720034b1b22074100480d010240024020040d00024020070d00410121030c020b200710332203450d040c010b2002280204210320042007460d0020032004200710372203450d030b20022003360204200241086a20073602002002410c6a28020021040b200320046a200141ff00713a00002000411f3a00002002410c6a200441016a3602000f0b103e000b103c000bdf0302017e067f024002400240024020014207872203502001a7220441c00071452205712003427f52200572470d002002410c6a28020021050c010b2002410c6a22062802002105200241086a210703400240024020072802002005460d00200228020421080c010b200541016a22082005490d03200541017422092008200920084b1b22094100480d030240024020050d00024020090d00410121080c020b2009103322080d010c060b2002280204210820052009460d0020082005200910372208450d050b2002200836020420072009360200200628020021050b200820056a200441807f723a00002006200541016a22053602002003a72104200342078722012103200150200441c00071452208712001427f52200872470d000b0b02400240200241086a2802002005460d00200228020421080c010b200541016a22082005490d01200541017422092008200920084b1b22094100480d010240024020050d00024020090d00410121080c020b200910332208450d040c010b2002280204210820052009460d0020082005200910372208450d030b20022008360204200241086a20093602002002410c6a28020021050b200820056a200441ff00713a00002000411f3a00002002410c6a200541016a3602000f0b103e000b103c000bc40301077f230041d0006b22022400410021032002410036021020024208370308200241c1006a220441076a210541082106024002400340200241386a200110a807200220042900003703282002200529000037002f20022d0040210720022802384101460d012002200229002f37001f200220022903283703182002200229001f37003f2002200229031837033802402003200228020c470d00200241086a200310a90720022802082106200228021021030b200620034104746a220820073a000020082002290338370001200841086a200229003f3700002002200341016a2203360210200741ff01714106470d000b20002002290308370204200041003602002000410c6a200241106a2802003602000c010b2000200228023c3602042000200229032837000920004101360200200041086a20073a0000200041106a200228002f36000002402003450d0020034104742107200621030340024020032d00004109470d000240200341046a2201280200220828020441ffffffff0371450d0020082802001035200128020021080b200810350b200341106a2103200741706a22070d000b0b200228020c41ffffffff0071450d00200610350b200241d0006a24000bc1ba0102097f017e230041f0006b2202240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490dab0120032005490dac012001280200220620046a2d000021072001410c6a22082005360200200741bf014b0d0120070ec001b402b402020304b402010101010105060708090a0b01010101010101010c0d010101010e0f101112010101131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01b4020b200241013a0048200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1041200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000cb6020b2000410b3a000420004101360200200041056a20073a00000cb5020b024002400240024002400240024020032005460d00200441026a21092005417f460db10120032009490db201200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410221070cb9020b20090e0405040306050b200241013a0047200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1041200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cb8020b4101210a410221070cb4020b4102210a410221070cb3020b4103210a0b410221070cb1020b024002400240024002400240024020032005460d00200441026a21092005417f460db20120032009490db301200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410321070cb8020b20090e0405040306050b200241013a0047200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1041200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cb7020b4101210a410321070cb3020b4102210a410321070cb2020b4103210a0b410321070cb0020b024002400240024002400240024020032005460d00200441026a21092005417f460db30120032009490db401200620056a2c00002101200820093602004100210a0240200141004e0d00411921090c020b0240200141017441807f71200172220141ff0171220541847e6a220941034d0d0041062109200541c001470d034104210a410421070cb7020b20090e0405040306050b200241013a0047200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c7006a360238200241c8006a200241d8006a1041200241326a200241d0006a2802003601002002200229034837012a2002200229012837031820022002412e6a29010037011e410521090b2002200229011e37010e200220022903183703080b200020013a0005200020093a000420002002290308370106200041013602002000410c6a200229010e3701000cb6020b4101210a410421070cb2020b4102210a410421070cb1020b4103210a0b410421070caf020b410621070cae020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460daf012003200541016a2207490df701200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b410721070caf020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000cb0020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460daf012003200541016a2207490df701200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b410821070cae020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000caf020b200241d8006a200110ab07200241d8006a410c6a2802002109200241d8006a41086a2802002107200228025c210420022802584101460daf012002410036026020024204370358200241d8006a4100200941027422034102751086012002280260210602402009450d002003417c6a410276210a200228025820064102746a210920042105034020092005280200360200200941046a2109200541046a21052003417c6a22030d000b2006200a6a41016a21060b200220063602600240200741ffffffff0371450d00200410350b2002280258210a0240200228025c22092006460d0020092006490dad012009450d002009410274220520064102742209460d00024020090d00024020050d004104210a0c020b200a10354104210a0c010b200a200520091037220a450dae010b410021094100210402400240034002402009411f4d0d00410f21010c030b20012802082207200128020c2205460d01200541016a22032005490db10120072003490df701200128020020056a2d0000210520082003360200200541ff00712009411f71742004722104200941076a21092005418001710d000b024020094120490d00410d21012005410f4b0d020b410c10332209450daf0120092004360208200920063602042009200a360200410921070cad020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a280200360200200641ffffffff0371450dae02200a10350cae020b410a21070caa020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db1012003200541016a2207490df601200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b410b21070cab020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000cac020b410021014100210902400240024002400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db4012003200541016a2204490df901200620056a2d0000210720082004360200200741ff00712001411f71742009722109200141076a2101200421052007418001710d000b024020014120490d00410d21012007410f4b0d020b20032004460d03200441016a22012004490db401200320014f0d022001200341c0fdcb001058000b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000cae020b200620046a2d000021052008200136020020050d01410c21074100210a0caa020b200241013a0048200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1041200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000cac020b200041163a000420004101360200200041056a20053a00000cab020b410d21070ca7020b410e21070ca6020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db0012003200541016a2207490df401200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b410f21070ca7020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca8020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db0012003200541016a2207490df401200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b411021070ca6020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca7020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db0012003200541016a2207490df401200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b411121070ca5020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca6020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db0012003200541016a2207490df401200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b411221070ca4020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca5020b410021014100210902400240034002402001411f4d0d00410f21010c030b20032005460d012005417f460db0012003200541016a2207490df401200620056a2d0000210420082007360200200441ff00712001411f71742009722109200141076a2101200721052004418001710d000b024020014120490d00410d21012004410f4b0d020b411321070ca3020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca4020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db20120032001490df601200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db3012003200141016a2207490df701200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411421070ca4020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca5020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca3020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db30120032001490df701200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db4012003200141016a2207490df801200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411521070ca3020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca4020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca2020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db40120032001490df801200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db5012003200141016a2207490df901200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411621070ca2020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca3020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca1020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db50120032001490df901200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db6012003200141016a2207490dfa01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411721070ca1020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca2020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000ca0020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db60120032001490dfa01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db7012003200141016a2207490dfb01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411821070ca0020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca1020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9f020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db70120032001490dfb01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db8012003200141016a2207490dfc01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411921070c9f020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000ca0020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9e020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db80120032001490dfc01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460db9012003200141016a2207490dfd01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411a21070c9e020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000c9f020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9d020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450db90120032001490dfd01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dba012003200141016a2207490dfe01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411b21070c9d020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000c9e020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9c020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dba0120032001490dfe01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dbb012003200141016a2207490dff01200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411c21070c9c020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000c9d020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9b020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dbb0120032001490dff01200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dbc012003200141016a2207490d8002200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411d21070c9b020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282103200228022c210520022802302109410521010b2000200136020420004101360200200041106a20093602002000410c6a2005360200200041086a20033602000c9c020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c9a020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dbc0120032001490d8002200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dbd012003200141016a2207490d8102200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411e21070c9a020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9b020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c99020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dbd0120032001490d8102200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dbe012003200141016a2207490d8202200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b411f21070c99020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c9a020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c98020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dbe0120032001490d8202200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dbf012003200141016a2207490d8302200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b41202107024020054120490d00410d21012004410f4b0d040b200aad210b0c98020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c99020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c97020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dbf0120032001490d8302200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc0012003200141016a2207490d8402200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412121070c97020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c98020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c96020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc00120032001490d8402200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc1012003200141016a2207490d8502200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412221070c96020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c97020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c95020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc10120032001490d8502200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc2012003200141016a2207490d8602200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412321070c95020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c96020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c94020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc20120032001490d8602200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc3012003200141016a2207490d8702200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412421070c94020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c95020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c93020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc30120032001490d8702200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc4012003200141016a2207490d8802200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412521070c93020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c94020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c92020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc40120032001490d8802200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc5012003200141016a2207490d8902200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412621070c92020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c93020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c91020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc50120032001490d8902200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc6012003200141016a2207490d8a02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412721070c91020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c92020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c90020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc60120032001490d8a02200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc7012003200141016a2207490d8b02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412821070c90020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c91020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c8f020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc70120032001490d8b02200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc8012003200141016a2207490d8c02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412921070c8f020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c90020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c8e020b410120036b2107200441026a210141002105410021090240024002400240034002402005411f4d0d00410f21010c030b200720016a4102460d012001450dc80120032001490d8c02200620016a417f6a2d0000210420082001360200200441ff00712005411f71742009722109200141016a2101200541076a21052004418001710d000b024020054120490d002004410f4d0d00410d21010c020b2001417f6a2101410021054100210a034002402005411f4d0d00410f21010c050b20032001460d032001417f460dc9012003200141016a2207490d8d02200620016a2d0000210420082007360200200441ff00712005411f7174200a72210a200541076a2105200721012004418001710d000b024020054120490d00410d21012004410f4b0d040b200aad210b412a21070c8e020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120022802282109200228022c210520022802302103410521010b2000200136020420004101360200200041106a20033602002000410c6a2005360200200041086a20093602000c8f020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a1041410521010b2000200136020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c8d020b0240024020032005460d00200441026a21012005417f460dc60120032001490dc701200620056a2d000021092008200136020020090d01412b21074100210a0c8b020b200241013a0048200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1041200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c8d020b200041153a000420004101360200200041056a20093a00000c8c020b0240024020032005460d00200441026a21012005417f460dc70120032001490dc801200620056a2d000021092008200136020020090d01412c21074100210a0c8a020b200241013a0048200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241c8006a360238200241086a200241d8006a1041200241336a200241106a2802003600002002200229030837002b2002200229002837031820022002412f6a29000037001f200041053a0004200020022903183700052000410c6a200229001f370000200041013602000c8c020b200041153a000420004101360200200041056a20093a00000c8b020b4100210141002109024002400340410d210a2001411f4b0d0220032005460d012005417f460dc9012003200541016a2207490d8902200620056a2c0000210420082007360200200441ff00712001411f71742009722109200141076a21012007210520044100480d000b200441c00071210502402001411f4b0d0020050dca010b02400240024020014120490d0020050d010b200441ff01714108490d0120014120490d0120050d010c030b20044180017241ff017141f801490d020b412d21070c89020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a10414105210a0b2000200a36020420004101360200200041086a2002290328370200200041106a200241286a41086a2802003602000c8a020b4200210b4100210102400340410e21072001413f4b0d890220032005460d012005417f460dc9012003200541016a2209490dca01200620056a2d0000210420082009360200200441ff0071220aad2001413f71ad86200b84210b200141076a21012009210520044118744118752209417f4c0d000b200941c0007121050240024002402001413f4b0d0020050d010b02400240200141c000490d0020050d010b200141c000490d022009450d020c8b020b200a41ff00470d8a020c010b200b428080808080808080807f427f2001413f712201ad862001413f461b84210b0b412e21070c87020b200241013a0008200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241086a360238200241286a200241d8006a10412002290328210b20022802302101410521070c88020b0240200320056b4104490d00200441056a21012005417b4b0dc90120032001490dca01200620056a280000210920082001360200412f21070c86020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a104120004281808080d000370300200041086a2002290328370200200041106a200241286a41086a2802003602000c88020b0240200320056b4108490d00200441096a2101200541774b0dca0120032001490dcb01200620056a290000210b20082001360200413021070c85020b200241013a0018200241ec006a41013602002002420137025c200241acfdcb003602582002413636023c2002200241386a3602682002200241186a360238200241286a200241d8006a10412002290328210b200041106a2002280230360200200041086a200b37020020004281808080d0003703000c87020b413121070c83020b413221070c82020b413321070c81020b413421070c80020b413521070cff010b413621070cfe010b413721070cfd010b413821070cfc010b413921070cfb010b413a21070cfa010b413b21070cf9010b413c21070cf8010b413d21070cf7010b413e21070cf6010b413f21070cf5010b41c00021070cf4010b41c10021070cf3010b41c20021070cf2010b41c30021070cf1010b41c40021070cf0010b41c50021070cef010b41c60021070cee010b41c70021070ced010b41c80021070cec010b41c90021070ceb010b41ca0021070cea010b41cb0021070ce9010b41cc0021070ce8010b41cd0021070ce7010b41ce0021070ce6010b41cf0021070ce5010b41d00021070ce4010b41d10021070ce3010b41d20021070ce2010b41d30021070ce1010b41d40021070ce0010b41d50021070cdf010b41d60021070cde010b41d70021070cdd010b41d80021070cdc010b41d90021070cdb010b41da0021070cda010b41db0021070cd9010b41dc0021070cd8010b41dd0021070cd7010b41de0021070cd6010b41df0021070cd5010b41e00021070cd4010b41e10021070cd3010b41e20021070cd2010b41e30021070cd1010b41e40021070cd0010b41e50021070ccf010b41e60021070cce010b41e70021070ccd010b41e80021070ccc010b41e90021070ccb010b41ea0021070cca010b41eb0021070cc9010b41ec0021070cc8010b41ed0021070cc7010b41ee0021070cc6010b41ef0021070cc5010b41f00021070cc4010b41f10021070cc3010b41f20021070cc2010b41f30021070cc1010b41f40021070cc0010b41f50021070cbf010b41f60021070cbe010b41f70021070cbd010b41f80021070cbc010b41f90021070cbb010b41fa0021070cba010b41fb0021070cb9010b41fc0021070cb8010b41fd0021070cb7010b41fe0021070cb6010b41ff0021070cb5010b41800121070cb4010b41810121070cb3010b41820121070cb2010b41830121070cb1010b41840121070cb0010b41850121070caf010b41860121070cae010b41870121070cad010b41880121070cac010b41890121070cab010b418a0121070caa010b418b0121070ca9010b418c0121070ca8010b418d0121070ca7010b418e0121070ca6010b418f0121070ca5010b41900121070ca4010b41910121070ca3010b41920121070ca2010b41930121070ca1010b41940121070ca0010b41950121070c9f010b41960121070c9e010b41970121070c9d010b41980121070c9c010b41990121070c9b010b419a0121070c9a010b419b0121070c99010b419c0121070c98010b419d0121070c97010b419e0121070c96010b419f0121070c95010b41a00121070c94010b41a10121070c93010b41a20121070c92010b41a30121070c91010b41a40121070c90010b41a50121070c8f010b41a60121070c8e010b41a70121070c8d010b41a80121070c8c010b41a90121070c8b010b41aa0121070c8a010b41ab0121070c89010b417f200541c0fdcb001059000b2005200341c0fdcb001058000b417f200941c0fdcb001059000b2009200341c0fdcb001058000b417f200941c0fdcb001059000b2009200341c0fdcb001058000b417f200941c0fdcb001059000b2009200341c0fdcb001058000b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b41ec80cc00412441c086cc00103f000b103c000b417f200341c0fdcb001059000b200241d8006a41106a28020021012000200436020420004101360200200041106a20013602002000410c6a2009360200200041086a20073602000c7e0b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200541016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b2001200341c0fdcb001058000b417f200141c0fdcb001059000b2001200341c0fdcb001058000b417f200541016a41c0fdcb001059000b2009417f2001411f7174722109412d21070c3f0b417f200541016a41c0fdcb001059000b200541016a200341c0fdcb001058000b2005200141c0fdcb001059000b2001200341c0fdcb001058000b2005200141c0fdcb001059000b2001200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b2003200741c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b200541016a200341c0fdcb001058000b20004100360200200041106a200b3703002000410c6a2009360200200041096a200a3a0000200041086a20073a00000c020b0b200020073a0004200020022f00183b000520004101360200200041106a2001360200200041086a200b370200200041076a2002411a6a2d00003a00000b200241f0006a24000bbb0101027f0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1b220241ffffffff00712002470d00200241047422024100480d00024020010d0020020d02410821030c040b20002802002103200141047422012002460d03024020010d0020020d02410821030c040b20032001200210372203450d020c030b103e000b2002103322030d010b103c000b20002003360200200041046a20024104763602000b0bd30101017f230041106b22022400024002400240024020002d00000e03010200010b2002200128021841a9fecb00410b2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c020b2002200128021841b4fecb00410c2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b2002200128021841c0fecb00410d2001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040b200241106a240020000bff06020c7f017e230041e0006b220224004100210341002104024002400240024002400240034002402003411f4d0d00410f21030c060b20012802082205200128020c2206460d04200641016a22072006490d0120052007490d03200128020020066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b024020034120490d00410d21032006410f4b0d050b410021082002410036021020024204370308024002402004450d00410421094100210a0340200a41016a210a4100210341002105024003404101210b02402003411f4d0d00410f21030c020b024002402001280208220c200128020c2206460d00200641016a22072006490d08200c20074f0d012007200c41c0fdcb001058000b4101210b200241013a00472002410136025c2002420137024c200241acfdcb003602482002413636023c2002200241386a3602582002200241c7006a360238200241286a200241c8006a10414100210d410521030c020b200128020020066a2d000021062001200736020c200641ff00712003411f71742005722105200341076a21032006418001710d000b024020034120490d00410d21032006410f4b0d010b2005410876210d4100210b200521030b200241186a41086a200241286a41086a28020036020020022002290328370318200d410874200341ff0171722103200b0d0202402008200228020c470d00200241086a2008410110860120022802082109200228021021080b200920084102746a20033602002002200841016a2208360210200a2004470d000b0b20002002290308370204200041003602002000410c6a200241106a2802003602000c060b2000200336020420004101360200200041086a2002290318370200200041106a200241186a41086a280200360200200228020c41ffffffff0371450d05200910350c050b417f200741c0fdcb001059000b417f200741c0fdcb001059000b2007200541c0fdcb001058000b200241013a0008200241dc006a41013602002002420137024c200241acfdcb003602482002413636023c2002200241386a3602582002200241086a360238200241286a200241c8006a1041410521030b200241186a41086a200241286a41086a280200220136020020022002290328220e37031820002003360204200041086a200e370200200041106a2001360200200041013602000b200241e0006a24000b9bee0202097f017e230041106b22032400024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020012d00000eac01000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab01000b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dad01200441017422062005200620054b1b22064100480dad010240024020040d00024020060d00410121050c020b2006103322050d010cb9010b2002280204210520042006460d0020052004200610372205450db8010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41003a00002002410c6a200441016a3602000cab010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490dac01200441017422062005200620054b1b22064100480dac010240024020040d00024020060d00410121050c020b200610332205450db8010c010b2002280204210520042006460d0020052004200610372205450db7010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41013a00002002410c6a200441016a3602000caa010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490dab01200441017422082005200820054b1b22084100480dab010240024020040d00024020080d00410121050c020b200810332205450db7010c010b2006280200210520042008460d0020052004200810372205450db6010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41023a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490dab01200441017422082005200820054b1b22084100480dab010240024020040d00024020080d00410121050c020b200810332205450db7010c010b2006280200210520042008460d0020052004200810372205450db6010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca9010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490daa01200441017422082005200820054b1b22084100480daa010240024020040d00024020080d00410121050c020b200810332205450db6010c010b2006280200210520042008460d0020052004200810372205450db5010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41033a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490daa01200441017422082005200820054b1b22084100480daa010240024020040d00024020080d00410121050c020b200810332205450db6010c010b2006280200210520042008460d0020052004200810372205450db5010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca8010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490da901200441017422082005200820054b1b22084100480da9010240024020040d00024020080d00410121050c020b200810332205450db5010c010b2006280200210520042008460d0020052004200810372205450db4010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41043a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490da901200441017422082005200820054b1b22084100480da9010240024020040d00024020080d00410121050c020b200810332205450db5010c010b2006280200210520042008460d0020052004200810372205450db4010b20022005360204200241086a20083602002002410c6a28020021040b200520046a42c0818386fcdffffe7c2007410473ad42078342038688a7413f7141c000723a00002002410c6a200441016a3602000ca7010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da801200441017422062005200620054b1b22064100480da8010240024020040d00024020060d00410121050c020b200610332205450db4010c010b2002280204210520042006460d0020052004200610372205450db3010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41053a00002002410c6a200441016a3602000ca6010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da701200441017422062005200620054b1b22064100480da7010240024020040d00024020060d00410121050c020b200610332205450db3010c010b2002280204210520042006460d0020052004200610372205450db2010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410b3a00002002410c6a200441016a3602000ca5010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da601200441017422072006200720064b1b22074100480da6010240024020040d00024020070d00410121060c020b200710332206450db2010c010b2009280200210620042007460d0020062004200710372206450db1010b20022006360204200241086a20073602002002410c6a28020021040b200620046a410c3a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da701200441017422072006200720064b1b22074100480da7010240024020040d00024020070d00410121060c020b200710332206450db3010c010b2009280200210620042007460d0020062004200710372206450db2010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca5010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da501200441017422072006200720064b1b22074100480da5010240024020040d00024020070d00410121060c020b200710332206450db1010c010b2009280200210620042007460d0020062004200710372206450db0010b20022006360204200241086a20073602002002410c6a28020021040b200620046a410d3a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da601200441017422072006200720064b1b22074100480da6010240024020040d00024020070d00410121060c020b200710332206450db2010c010b2009280200210620042007460d0020062004200710372206450db1010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca4010b0b200241046a210902400240200241086a2802002002410c6a2802002204460d00200928020021050c010b200441016a22052004490da401200441017422062005200620054b1b22064100480da4010240024020040d00024020060d00410121050c020b200610332205450db0010c010b2009280200210520042006460d0020052004200610372205450daf010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410e3a00002002410c6a2208200441016a360200200320012802042204280204220520042802002204200420054102746a200210a4072003210420032d0000411f470dab012008280200210420012802042802082105200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da501200441017422072006200720064b1b22074100480da5010240024020040d00024020070d00410121060c020b200710332206450db1010c010b2009280200210620042007460d0020062004200710372206450db0010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca3010b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da301200441017422062005200620054b1b22064100480da3010240024020040d00024020060d00410121050c020b200610332205450daf010c010b2002280204210520042006460d0020052004200610372205450dae010b20022005360204200241086a20063602002002410c6a28020021040b200520046a410f3a00002002410c6a200441016a3602000ca1010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da201200441017422072006200720064b1b22074100480da2010240024020040d00024020070d00410121060c020b200710332206450dae010c010b2009280200210620042007460d0020062004200710372206450dad010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41103a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da301200441017422072006200720064b1b22074100480da3010240024020040d00024020070d00410121060c020b200710332206450daf010c010b2009280200210620042007460d0020062004200710372206450dae010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000ca1010b0b200241046a2109200141046a280200210520012d0001210b02400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490da101200441017422072006200720064b1b22074100480da1010240024020040d00024020070d00410121060c020b200710332206450dad010c010b2009280200210620042007460d0020062004200710372206450dac010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41113a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490da201200441017422072006200720064b1b22074100480da2010240024020040d00024020070d00410121060c020b200710332206450dae010c010b2009280200210620042007460d0020062004200710372206450dad010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000b02400240200241086a2802002004460d00200928020021050c010b200441016a22052004490da101200441017422062005200620054b1b22064100480da1010240024020040d00024020060d00410121050c020b200610332205450dad010c010b2009280200210520042006460d0020052004200610372205450dac010b20022005360204200241086a20063602002002410c6a28020021040b200520046a200b3a00002002410c6a200441016a3602000c9f010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490da001200441017422062005200620054b1b22064100480da0010240024020040d00024020060d00410121050c020b200610332205450dac010c010b2002280204210520042006460d0020052004200610372205450dab010b20022005360204200241086a20063602002002410c6a28020021040b200520046a411a3a00002002410c6a200441016a3602000c9e010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d9f01200441017422062005200620054b1b22064100480d9f010240024020040d00024020060d00410121050c020b200610332205450dab010c010b2002280204210520042006460d0020052004200610372205450daa010b20022005360204200241086a20063602002002410c6a28020021040b200520046a411b3a00002002410c6a200441016a3602000c9d010b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9e01200441017422072006200720064b1b22074100480d9e010240024020040d00024020070d00410121060c020b200710332206450daa010c010b2009280200210620042007460d0020062004200710372206450da9010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41203a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9f01200441017422072006200720064b1b22074100480d9f010240024020040d00024020070d00410121060c020b200710332206450dab010c010b2009280200210620042007460d0020062004200710372206450daa010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9d010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9d01200441017422072006200720064b1b22074100480d9d010240024020040d00024020070d00410121060c020b200710332206450da9010c010b2009280200210620042007460d0020062004200710372206450da8010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41213a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9e01200441017422072006200720064b1b22074100480d9e010240024020040d00024020070d00410121060c020b200710332206450daa010c010b2009280200210620042007460d0020062004200710372206450da9010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9c010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9c01200441017422072006200720064b1b22074100480d9c010240024020040d00024020070d00410121060c020b200710332206450da8010c010b2009280200210620042007460d0020062004200710372206450da7010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41223a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9d01200441017422072006200720064b1b22074100480d9d010240024020040d00024020070d00410121060c020b200710332206450da9010c010b2009280200210620042007460d0020062004200710372206450da8010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9b010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9b01200441017422072006200720064b1b22074100480d9b010240024020040d00024020070d00410121060c020b200710332206450da7010c010b2009280200210620042007460d0020062004200710372206450da6010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41233a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9c01200441017422072006200720064b1b22074100480d9c010240024020040d00024020070d00410121060c020b200710332206450da8010c010b2009280200210620042007460d0020062004200710372206450da7010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c9a010b0b200241046a2109200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200928020021060c010b200441016a22062004490d9a01200441017422072006200720064b1b22074100480d9a010240024020040d00024020070d00410121060c020b200710332206450da6010c010b2009280200210620042007460d0020062004200710372206450da5010b20022006360204200241086a20073602002002410c6a28020021040b200620046a41243a00002002410c6a2208200441016a2204360200200241086a210a034002400240200a2802002004460d00200928020021060c010b200441016a22062004490d9b01200441017422072006200720064b1b22074100480d9b010240024020040d00024020070d00410121060c020b200710332206450da7010c010b2009280200210620042007460d0020062004200710372206450da6010b20022006360204200a2007360200200828020021040b200620046a200541807f72200541ff0071200541077622061b3a00002008200441016a22043602002006210520060d000c99010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9901200441017422082007200820074b1b22084100480d99010240024020040d00024020080d00410121070c020b200810332207450da5010c010b200a280200210720042008460d0020072004200810372207450da4010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41283a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9a01200441017422082007200820074b1b22084100480d9a010240024020040d00024020080d00410121070c020b200810332207450da6010c010b200a280200210720042008460d0020072004200810372207450da5010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9a01200441017422072005200720054b1b22074100480d9a010240024020040d00024020070d00410121050c020b200710332205450da6010c010b200a280200210520042007460d0020052004200710372205450da5010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c98010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9801200441017422082007200820074b1b22084100480d98010240024020040d00024020080d00410121070c020b200810332207450da4010c010b200a280200210720042008460d0020072004200810372207450da3010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41293a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9901200441017422082007200820074b1b22084100480d99010240024020040d00024020080d00410121070c020b200810332207450da5010c010b200a280200210720042008460d0020072004200810372207450da4010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9901200441017422072006200720064b1b22074100480d99010240024020040d00024020070d00410121060c020b200710332206450da5010c010b200a280200210620042007460d0020062004200710372206450da4010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c97010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9701200441017422082007200820074b1b22084100480d97010240024020040d00024020080d00410121070c020b200810332207450da3010c010b200a280200210720042008460d0020072004200810372207450da2010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412a3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9801200441017422082007200820074b1b22084100480d98010240024020040d00024020080d00410121070c020b200810332207450da4010c010b200a280200210720042008460d0020072004200810372207450da3010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9801200441017422072006200720064b1b22074100480d98010240024020040d00024020070d00410121060c020b200710332206450da4010c010b200a280200210620042007460d0020062004200710372206450da3010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c96010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b200810332207450da2010c010b200a280200210720042008460d0020072004200810372207450da1010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412b3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9701200441017422082007200820074b1b22084100480d97010240024020040d00024020080d00410121070c020b200810332207450da3010c010b200a280200210720042008460d0020072004200810372207450da2010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9701200441017422072005200720054b1b22074100480d97010240024020040d00024020070d00410121050c020b200710332205450da3010c010b200a280200210520042007460d0020052004200710372205450da2010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c95010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b200810332207450da1010c010b200a280200210720042008460d0020072004200810372207450da0010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412c3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b200810332207450da2010c010b200a280200210720042008460d0020072004200810372207450da1010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9601200441017422072006200720064b1b22074100480d96010240024020040d00024020070d00410121060c020b200710332206450da2010c010b200a280200210620042007460d0020062004200710372206450da1010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c94010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b200810332207450da0010c010b200a280200210720042008460d0020072004200810372207450d9f010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412d3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9601200441017422082007200820074b1b22084100480d96010240024020040d00024020080d00410121070c020b2008103322070d010c9e010b200a280200210720042008460d0020072004200810372207450d9c010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9601200441017422072006200720064b1b22074100480d96010240024020040d00024020070d00410121060c020b2007103322060d010c9e010b200a280200210620042007460d0020062004200710372206450d9c010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c93010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9401200441017422082007200820074b1b22084100480d94010240024020040d00024020080d00410121070c020b2008103322070d010c9c010b200a280200210720042008460d0020072004200810372207450d9a010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412e3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9501200441017422082007200820074b1b22084100480d95010240024020040d00024020080d00410121070c020b2008103322070d010c9d010b200a280200210720042008460d0020072004200810372207450d9b010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9501200441017422072006200720064b1b22074100480d95010240024020040d00024020070d00410121060c020b2007103322060d010c9d010b200a280200210620042007460d0020062004200710372206450d9b010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c92010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9301200441017422082007200820074b1b22084100480d93010240024020040d00024020080d00410121070c020b2008103322070d010c9b010b200a280200210720042008460d0020072004200810372207450d99010b20022007360204200241086a20083602002002410c6a28020021040b200720046a412f3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9401200441017422082007200820074b1b22084100480d94010240024020040d00024020080d00410121070c020b2008103322070d010c9c010b200a280200210720042008460d0020072004200810372207450d9a010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9401200441017422072006200720064b1b22074100480d94010240024020040d00024020070d00410121060c020b2007103322060d010c9c010b200a280200210620042007460d0020062004200710372206450d9a010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c91010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9201200441017422082007200820074b1b22084100480d92010240024020040d00024020080d00410121070c020b2008103322070d010c9a010b200a280200210720042008460d0020072004200810372207450d98010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41303a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9301200441017422082007200820074b1b22084100480d93010240024020040d00024020080d00410121070c020b2008103322070d010c9b010b200a280200210720042008460d0020072004200810372207450d99010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d9301200441017422072005200720054b1b22074100480d93010240024020040d00024020070d00410121050c020b2007103322050d010c9b010b200a280200210520042007460d0020052004200710372205450d99010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c90010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9101200441017422082007200820074b1b22084100480d91010240024020040d00024020080d00410121070c020b2008103322070d010c99010b200a280200210720042008460d0020072004200810372207450d97010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41313a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9201200441017422082007200820074b1b22084100480d92010240024020040d00024020080d00410121070c020b2008103322070d010c9a010b200a280200210720042008460d0020072004200810372207450d98010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9201200441017422072006200720064b1b22074100480d92010240024020040d00024020070d00410121060c020b2007103322060d010c9a010b200a280200210620042007460d0020062004200710372206450d98010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8f010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d9001200441017422082007200820074b1b22084100480d90010240024020040d00024020080d00410121070c020b2008103322070d010c98010b200a280200210720042008460d0020072004200810372207450d96010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41323a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9101200441017422082007200820074b1b22084100480d91010240024020040d00024020080d00410121070c020b2008103322070d010c99010b200a280200210720042008460d0020072004200810372207450d97010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9101200441017422072006200720064b1b22074100480d91010240024020040d00024020070d00410121060c020b2007103322060d010c99010b200a280200210620042007460d0020062004200710372206450d97010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8e010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8f01200441017422082007200820074b1b22084100480d8f010240024020040d00024020080d00410121070c020b2008103322070d010c97010b200a280200210720042008460d0020072004200810372207450d95010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41333a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d9001200441017422082007200820074b1b22084100480d90010240024020040d00024020080d00410121070c020b2008103322070d010c98010b200a280200210720042008460d0020072004200810372207450d96010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d9001200441017422072006200720064b1b22074100480d90010240024020040d00024020070d00410121060c020b2007103322060d010c98010b200a280200210620042007460d0020062004200710372206450d96010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8d010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8e01200441017422082007200820074b1b22084100480d8e010240024020040d00024020080d00410121070c020b2008103322070d010c96010b200a280200210720042008460d0020072004200810372207450d94010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41343a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8f01200441017422082007200820074b1b22084100480d8f010240024020040d00024020080d00410121070c020b2008103322070d010c97010b200a280200210720042008460d0020072004200810372207450d95010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8f01200441017422072005200720054b1b22074100480d8f010240024020040d00024020070d00410121050c020b2007103322050d010c97010b200a280200210520042007460d0020052004200710372205450d95010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c8c010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8d01200441017422082007200820074b1b22084100480d8d010240024020040d00024020080d00410121070c020b2008103322070d010c95010b200a280200210720042008460d0020072004200810372207450d93010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41353a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8e01200441017422082007200820074b1b22084100480d8e010240024020040d00024020080d00410121070c020b2008103322070d010c96010b200a280200210720042008460d0020072004200810372207450d94010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8e01200441017422072006200720064b1b22074100480d8e010240024020040d00024020070d00410121060c020b2007103322060d010c96010b200a280200210620042007460d0020062004200710372206450d94010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c8b010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8c01200441017422082007200820074b1b22084100480d8c010240024020040d00024020080d00410121070c020b2008103322070d010c94010b200a280200210720042008460d0020072004200810372207450d92010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41363a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8d01200441017422082007200820074b1b22084100480d8d010240024020040d00024020080d00410121070c020b2008103322070d010c95010b200a280200210720042008460d0020072004200810372207450d93010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8d01200441017422072005200720054b1b22074100480d8d010240024020040d00024020070d00410121050c020b2007103322050d010c95010b200a280200210520042007460d0020052004200710372205450d93010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c8a010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8b01200441017422082007200820074b1b22084100480d8b010240024020040d00024020080d00410121070c020b2008103322070d010c93010b200a280200210720042008460d0020072004200810372207450d91010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41373a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8c01200441017422082007200820074b1b22084100480d8c010240024020040d00024020080d00410121070c020b2008103322070d010c94010b200a280200210720042008460d0020072004200810372207450d92010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8c01200441017422072006200720064b1b22074100480d8c010240024020040d00024020070d00410121060c020b2007103322060d010c94010b200a280200210620042007460d0020062004200710372206450d92010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c89010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8a01200441017422082007200820074b1b22084100480d8a010240024020040d00024020080d00410121070c020b2008103322070d010c92010b200a280200210720042008460d0020072004200810372207450d90010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41383a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8b01200441017422082007200820074b1b22084100480d8b010240024020040d00024020080d00410121070c020b2008103322070d010c93010b200a280200210720042008460d0020072004200810372207450d91010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8b01200441017422072005200720054b1b22074100480d8b010240024020040d00024020070d00410121050c020b2007103322050d010c93010b200a280200210520042007460d0020052004200710372205450d91010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c88010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8901200441017422082007200820074b1b22084100480d89010240024020040d00024020080d00410121070c020b2008103322070d010c91010b200a280200210720042008460d0020072004200810372207450d8f010b20022007360204200241086a20083602002002410c6a28020021040b200720046a41393a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8a01200441017422082007200820074b1b22084100480d8a010240024020040d00024020080d00410121070c020b2008103322070d010c92010b200a280200210720042008460d0020072004200810372207450d90010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8a01200441017422072006200720064b1b22074100480d8a010240024020040d00024020070d00410121060c020b2007103322060d010c92010b200a280200210620042007460d0020062004200710372206450d90010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c87010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8801200441017422082007200820074b1b22084100480d88010240024020040d00024020080d00410121070c020b2008103322070d010c90010b200a280200210720042008460d0020072004200810372207450d8e010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413a3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8901200441017422082007200820074b1b22084100480d89010240024020040d00024020080d00410121070c020b2008103322070d010c91010b200a280200210720042008460d0020072004200810372207450d8f010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8901200441017422072006200720064b1b22074100480d89010240024020040d00024020070d00410121060c020b2007103322060d010c91010b200a280200210620042007460d0020062004200710372206450d8f010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c86010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8701200441017422082007200820074b1b22084100480d87010240024020040d00024020080d00410121070c020b2008103322070d010c8f010b200a280200210720042008460d0020072004200810372207450d8d010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413b3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8801200441017422082007200820074b1b22084100480d88010240024020040d00024020080d00410121070c020b2008103322070d010c90010b200a280200210720042008460d0020072004200810372207450d8e010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8801200441017422072006200720064b1b22074100480d88010240024020040d00024020070d00410121060c020b2007103322060d010c90010b200a280200210620042007460d0020062004200710372206450d8e010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c85010b0b200241046a210a200141086a2802002105200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8601200441017422082007200820074b1b22084100480d86010240024020040d00024020080d00410121070c020b2008103322070d010c8e010b200a280200210720042008460d0020072004200810372207450d8c010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413c3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8701200441017422082007200820074b1b22084100480d87010240024020040d00024020080d00410121070c020b2008103322070d010c8f010b200a280200210720042008460d0020072004200810372207450d8d010b20022007360204200b2008360200200928020021040b200720046a200641807f72200641ff0071200641077622071b3a00002009200441016a22043602002007210620070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021060c010b200441016a22062004490d8701200441017422072006200720064b1b22074100480d87010240024020040d00024020070d00410121060c020b2007103322060d010c8f010b200a280200210620042007460d0020062004200710372206450d8d010b2002200636020420082007360200200928020021040b200620046a200541807f72200541ff0071200541077622061b3a00002009200441016a22043602002006210520060d000c84010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8501200441017422082007200820074b1b22084100480d85010240024020040d00024020080d00410121070c020b2008103322070d010c8d010b200a280200210720042008460d0020072004200810372207450d8b010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413d3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8601200441017422082007200820074b1b22084100480d86010240024020040d00024020080d00410121070c020b2008103322070d010c8e010b200a280200210720042008460d0020072004200810372207450d8c010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8601200441017422072005200720054b1b22074100480d86010240024020040d00024020070d00410121050c020b2007103322050d010c8e010b200a280200210520042007460d0020052004200710372205450d8c010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c83010b0b200241046a210a200141086a2802002106200141046a280200210502400240200241086a2802002002410c6a2802002204460d00200a28020021070c010b200441016a22072004490d8401200441017422082007200820074b1b22084100480d84010240024020040d00024020080d00410121070c020b2008103322070d010c8c010b200a280200210720042008460d0020072004200810372207450d8a010b20022007360204200241086a20083602002002410c6a28020021040b200720046a413e3a00002002410c6a2209200441016a2204360200200241086a210b034002400240200b2802002004460d00200a28020021070c010b200441016a22072004490d8501200441017422082007200820074b1b22084100480d85010240024020040d00024020080d00410121070c020b2008103322070d010c8d010b200a280200210720042008460d0020072004200810372207450d8b010b20022007360204200b2008360200200928020021040b200720046a200541807f72200541ff0071200541077622071b3a00002009200441016a22043602002007210520070d000b200241086a21082002410c6a210903400240024020082802002004460d00200a28020021050c010b200441016a22052004490d8501200441017422072005200720054b1b22074100480d85010240024020040d00024020070d00410121050c020b2007103322050d010c8d010b200a280200210520042007460d0020052004200710372205450d8b010b2002200536020420082007360200200928020021040b200520046a200641807f72200641ff0071200641077622051b3a00002009200441016a22043602002005210620050d000c82010b0b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8b010b2006280200210520042008460d0020052004200810372205450d89010b20022005360204200241086a20083602002002410c6a28020021040b200520046a413f3a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8b010b2006280200210520042008460d0020052004200810372205450d89010b20022005360204200241086a20083602002002410c6a28020021040b200520046a20073a00002002410c6a200441016a3602000c80010b200241046a210620012d0001210702400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8201200441017422082005200820054b1b22084100480d82010240024020040d00024020080d00410121050c020b2008103322050d010c8a010b2006280200210520042008460d0020052004200810372205450d88010b20022005360204200241086a20083602002002410c6a28020021040b200520046a41c0003a00002002410c6a200441016a220436020002400240200241086a2802002004460d00200628020021050c010b200441016a22052004490d8301200441017422082005200820054b1b22084100480d83010240024020040d00024020080d00410121050c020b2008103322050d010c8a010b2006280200210520042008460d0020052004200810372205450d88010b20022005360204200241086a20083602002002410c6a28020021040b200520046a20073a00002002410c6a200441016a3602000c7f0b200141046a280200210602400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8201200441017422072005200720054b1b22074100480d82010240024020040d00024020070d00410121050c020b2007103322050d010c89010b2002280204210520042007460d0020052004200710372205450d84010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c1003a00002002410c6a200441016a36020020032006200210a5072003210420032d0000411f470d87010c7e0b200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d8101200441017422062005200620054b1b22064100480d81010240024020040d00024020060d00410121050c020b2006103322050d010c88010b2002280204210520042006460d0020052004200610372205450d83010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c2003a00002002410c6a200441016a3602002003200c200210a6072003210420032d0000411f470d86010c7d0b200241046a2106200141046a280200210802400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d8001200441017422072005200720054b1b22074100480d80010240024020040d00024020070d00410121050c020b2007103322050d010c87010b2006280200210520042007460d0020052004200710372205450d82010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c3003a00002002410c6a200441016a220436020002400240200241086a280200220720046b4104490d00200628020021050c010b200441046a22052004490d8001200741017422042005200420054b1b22044100480d80010240024020070d00024020040d00410121050c020b2004103322050d010c87010b2006280200210520072004460d0020052007200410372205450d82010b20022005360204200241086a20043602002002410c6a28020021040b200520046a20083600002002410c6a200441046a3602000c7c0b200241046a2106200141086a290300210c02400240200241086a2802002002410c6a2802002204460d00200628020021050c010b200441016a22052004490d7f200441017422072005200720054b1b22074100480d7f0240024020040d00024020070d00410121050c020b2007103322050d010c86010b2006280200210520042007460d0020052004200710372205450d81010b20022005360204200241086a20073602002002410c6a28020021040b200520046a41c4003a00002002410c6a200441016a220436020002400240200241086a280200220720046b4108490d00200628020021050c010b200441086a22052004490d7f200741017422042005200420054b1b22044100480d7f0240024020070d00024020040d00410121050c020b2004103322050d010c86010b2006280200210520072004460d0020052007200410372205450d81010b20022005360204200241086a20043602002002410c6a28020021040b200520046a200c3700002002410c6a200441086a3602000c7b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7e200441017422062005200620054b1b22064100480d7e0240024020040d00024020060d00410121050c020b2006103322050d010c85010b2002280204210520042006460d0020052004200610372205450d80010b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c5003a00002002410c6a200441016a3602000c7a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7d200441017422062005200620054b1b22064100480d7d0240024020040d00024020060d00410121050c020b2006103322050d010c84010b2002280204210520042006460d0020052004200610372205450d7f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c6003a00002002410c6a200441016a3602000c790b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7c200441017422062005200620054b1b22064100480d7c0240024020040d00024020060d00410121050c020b2006103322050d010c83010b2002280204210520042006460d0020052004200610372205450d7e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c7003a00002002410c6a200441016a3602000c780b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7b200441017422062005200620054b1b22064100480d7b0240024020040d00024020060d00410121050c020b2006103322050d010c82010b2002280204210520042006460d0020052004200610372205450d7d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c8003a00002002410c6a200441016a3602000c770b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d7a200441017422062005200620054b1b22064100480d7a0240024020040d00024020060d00410121050c020b2006103322050d010c81010b2002280204210520042006460d0020052004200610372205450d7c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41c9003a00002002410c6a200441016a3602000c760b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d79200441017422062005200620054b1b22064100480d790240024020040d00024020060d00410121050c020b2006103322050d010c80010b2002280204210520042006460d0020052004200610372205450d7b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ca003a00002002410c6a200441016a3602000c750b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d78200441017422062005200620054b1b22064100480d780240024020040d00024020060d00410121050c020b2006103322050d010c7f0b2002280204210520042006460d0020052004200610372205450d7a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cb003a00002002410c6a200441016a3602000c740b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d77200441017422062005200620054b1b22064100480d770240024020040d00024020060d00410121050c020b2006103322050d010c7e0b2002280204210520042006460d0020052004200610372205450d790b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cc003a00002002410c6a200441016a3602000c730b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d76200441017422062005200620054b1b22064100480d760240024020040d00024020060d00410121050c020b2006103322050d010c7d0b2002280204210520042006460d0020052004200610372205450d780b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cd003a00002002410c6a200441016a3602000c720b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d75200441017422062005200620054b1b22064100480d750240024020040d00024020060d00410121050c020b2006103322050d010c7c0b2002280204210520042006460d0020052004200610372205450d770b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ce003a00002002410c6a200441016a3602000c710b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d74200441017422062005200620054b1b22064100480d740240024020040d00024020060d00410121050c020b2006103322050d010c7b0b2002280204210520042006460d0020052004200610372205450d760b20022005360204200241086a20063602002002410c6a28020021040b200520046a41cf003a00002002410c6a200441016a3602000c700b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d73200441017422062005200620054b1b22064100480d730240024020040d00024020060d00410121050c020b2006103322050d010c7a0b2002280204210520042006460d0020052004200610372205450d750b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d0003a00002002410c6a200441016a3602000c6f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d72200441017422062005200620054b1b22064100480d720240024020040d00024020060d00410121050c020b2006103322050d010c790b2002280204210520042006460d0020052004200610372205450d740b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d1003a00002002410c6a200441016a3602000c6e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d71200441017422062005200620054b1b22064100480d710240024020040d00024020060d00410121050c020b2006103322050d010c780b2002280204210520042006460d0020052004200610372205450d730b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d2003a00002002410c6a200441016a3602000c6d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d70200441017422062005200620054b1b22064100480d700240024020040d00024020060d00410121050c020b2006103322050d010c770b2002280204210520042006460d0020052004200610372205450d720b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d3003a00002002410c6a200441016a3602000c6c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6f200441017422062005200620054b1b22064100480d6f0240024020040d00024020060d00410121050c020b2006103322050d010c760b2002280204210520042006460d0020052004200610372205450d710b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d4003a00002002410c6a200441016a3602000c6b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6e200441017422062005200620054b1b22064100480d6e0240024020040d00024020060d00410121050c020b2006103322050d010c750b2002280204210520042006460d0020052004200610372205450d700b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d5003a00002002410c6a200441016a3602000c6a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6d200441017422062005200620054b1b22064100480d6d0240024020040d00024020060d00410121050c020b2006103322050d010c740b2002280204210520042006460d0020052004200610372205450d6f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d6003a00002002410c6a200441016a3602000c690b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6c200441017422062005200620054b1b22064100480d6c0240024020040d00024020060d00410121050c020b2006103322050d010c730b2002280204210520042006460d0020052004200610372205450d6e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d7003a00002002410c6a200441016a3602000c680b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6b200441017422062005200620054b1b22064100480d6b0240024020040d00024020060d00410121050c020b2006103322050d010c720b2002280204210520042006460d0020052004200610372205450d6d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d8003a00002002410c6a200441016a3602000c670b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d6a200441017422062005200620054b1b22064100480d6a0240024020040d00024020060d00410121050c020b2006103322050d010c710b2002280204210520042006460d0020052004200610372205450d6c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41d9003a00002002410c6a200441016a3602000c660b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d69200441017422062005200620054b1b22064100480d690240024020040d00024020060d00410121050c020b2006103322050d010c700b2002280204210520042006460d0020052004200610372205450d6b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41da003a00002002410c6a200441016a3602000c650b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d68200441017422062005200620054b1b22064100480d680240024020040d00024020060d00410121050c020b2006103322050d010c6f0b2002280204210520042006460d0020052004200610372205450d6a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41db003a00002002410c6a200441016a3602000c640b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d67200441017422062005200620054b1b22064100480d670240024020040d00024020060d00410121050c020b2006103322050d010c6e0b2002280204210520042006460d0020052004200610372205450d690b20022005360204200241086a20063602002002410c6a28020021040b200520046a41dc003a00002002410c6a200441016a3602000c630b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d66200441017422062005200620054b1b22064100480d660240024020040d00024020060d00410121050c020b2006103322050d010c6d0b2002280204210520042006460d0020052004200610372205450d680b20022005360204200241086a20063602002002410c6a28020021040b200520046a41dd003a00002002410c6a200441016a3602000c620b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d65200441017422062005200620054b1b22064100480d650240024020040d00024020060d00410121050c020b2006103322050d010c6c0b2002280204210520042006460d0020052004200610372205450d670b20022005360204200241086a20063602002002410c6a28020021040b200520046a41de003a00002002410c6a200441016a3602000c610b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d64200441017422062005200620054b1b22064100480d640240024020040d00024020060d00410121050c020b2006103322050d010c6b0b2002280204210520042006460d0020052004200610372205450d660b20022005360204200241086a20063602002002410c6a28020021040b200520046a41df003a00002002410c6a200441016a3602000c600b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d63200441017422062005200620054b1b22064100480d630240024020040d00024020060d00410121050c020b2006103322050d010c6a0b2002280204210520042006460d0020052004200610372205450d650b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e0003a00002002410c6a200441016a3602000c5f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d62200441017422062005200620054b1b22064100480d620240024020040d00024020060d00410121050c020b2006103322050d010c690b2002280204210520042006460d0020052004200610372205450d640b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e1003a00002002410c6a200441016a3602000c5e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d61200441017422062005200620054b1b22064100480d610240024020040d00024020060d00410121050c020b2006103322050d010c680b2002280204210520042006460d0020052004200610372205450d630b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e2003a00002002410c6a200441016a3602000c5d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d60200441017422062005200620054b1b22064100480d600240024020040d00024020060d00410121050c020b2006103322050d010c670b2002280204210520042006460d0020052004200610372205450d620b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e3003a00002002410c6a200441016a3602000c5c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5f200441017422062005200620054b1b22064100480d5f0240024020040d00024020060d00410121050c020b2006103322050d010c660b2002280204210520042006460d0020052004200610372205450d610b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e4003a00002002410c6a200441016a3602000c5b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5e200441017422062005200620054b1b22064100480d5e0240024020040d00024020060d00410121050c020b2006103322050d010c650b2002280204210520042006460d0020052004200610372205450d600b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e5003a00002002410c6a200441016a3602000c5a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5d200441017422062005200620054b1b22064100480d5d0240024020040d00024020060d00410121050c020b2006103322050d010c640b2002280204210520042006460d0020052004200610372205450d5f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e6003a00002002410c6a200441016a3602000c590b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5c200441017422062005200620054b1b22064100480d5c0240024020040d00024020060d00410121050c020b2006103322050d010c630b2002280204210520042006460d0020052004200610372205450d5e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e7003a00002002410c6a200441016a3602000c580b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5b200441017422062005200620054b1b22064100480d5b0240024020040d00024020060d00410121050c020b2006103322050d010c620b2002280204210520042006460d0020052004200610372205450d5d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e8003a00002002410c6a200441016a3602000c570b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d5a200441017422062005200620054b1b22064100480d5a0240024020040d00024020060d00410121050c020b2006103322050d010c610b2002280204210520042006460d0020052004200610372205450d5c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41e9003a00002002410c6a200441016a3602000c560b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d59200441017422062005200620054b1b22064100480d590240024020040d00024020060d00410121050c020b2006103322050d010c600b2002280204210520042006460d0020052004200610372205450d5b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ea003a00002002410c6a200441016a3602000c550b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d58200441017422062005200620054b1b22064100480d580240024020040d00024020060d00410121050c020b2006103322050d010c5f0b2002280204210520042006460d0020052004200610372205450d5a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41eb003a00002002410c6a200441016a3602000c540b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d57200441017422062005200620054b1b22064100480d570240024020040d00024020060d00410121050c020b2006103322050d010c5e0b2002280204210520042006460d0020052004200610372205450d590b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ec003a00002002410c6a200441016a3602000c530b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d56200441017422062005200620054b1b22064100480d560240024020040d00024020060d00410121050c020b2006103322050d010c5d0b2002280204210520042006460d0020052004200610372205450d580b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ed003a00002002410c6a200441016a3602000c520b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d55200441017422062005200620054b1b22064100480d550240024020040d00024020060d00410121050c020b2006103322050d010c5c0b2002280204210520042006460d0020052004200610372205450d570b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ee003a00002002410c6a200441016a3602000c510b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d54200441017422062005200620054b1b22064100480d540240024020040d00024020060d00410121050c020b2006103322050d010c5b0b2002280204210520042006460d0020052004200610372205450d560b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ef003a00002002410c6a200441016a3602000c500b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d53200441017422062005200620054b1b22064100480d530240024020040d00024020060d00410121050c020b2006103322050d010c5a0b2002280204210520042006460d0020052004200610372205450d550b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f0003a00002002410c6a200441016a3602000c4f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d52200441017422062005200620054b1b22064100480d520240024020040d00024020060d00410121050c020b2006103322050d010c590b2002280204210520042006460d0020052004200610372205450d540b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f1003a00002002410c6a200441016a3602000c4e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d51200441017422062005200620054b1b22064100480d510240024020040d00024020060d00410121050c020b2006103322050d010c580b2002280204210520042006460d0020052004200610372205450d530b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f2003a00002002410c6a200441016a3602000c4d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d50200441017422062005200620054b1b22064100480d500240024020040d00024020060d00410121050c020b2006103322050d010c570b2002280204210520042006460d0020052004200610372205450d520b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f3003a00002002410c6a200441016a3602000c4c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4f200441017422062005200620054b1b22064100480d4f0240024020040d00024020060d00410121050c020b2006103322050d010c560b2002280204210520042006460d0020052004200610372205450d510b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f4003a00002002410c6a200441016a3602000c4b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4e200441017422062005200620054b1b22064100480d4e0240024020040d00024020060d00410121050c020b2006103322050d010c550b2002280204210520042006460d0020052004200610372205450d500b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f5003a00002002410c6a200441016a3602000c4a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4d200441017422062005200620054b1b22064100480d4d0240024020040d00024020060d00410121050c020b2006103322050d010c540b2002280204210520042006460d0020052004200610372205450d4f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f6003a00002002410c6a200441016a3602000c490b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4c200441017422062005200620054b1b22064100480d4c0240024020040d00024020060d00410121050c020b2006103322050d010c530b2002280204210520042006460d0020052004200610372205450d4e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f7003a00002002410c6a200441016a3602000c480b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4b200441017422062005200620054b1b22064100480d4b0240024020040d00024020060d00410121050c020b2006103322050d010c520b2002280204210520042006460d0020052004200610372205450d4d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f8003a00002002410c6a200441016a3602000c470b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d4a200441017422062005200620054b1b22064100480d4a0240024020040d00024020060d00410121050c020b2006103322050d010c510b2002280204210520042006460d0020052004200610372205450d4c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41f9003a00002002410c6a200441016a3602000c460b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d49200441017422062005200620054b1b22064100480d490240024020040d00024020060d00410121050c020b2006103322050d010c500b2002280204210520042006460d0020052004200610372205450d4b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fa003a00002002410c6a200441016a3602000c450b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d48200441017422062005200620054b1b22064100480d480240024020040d00024020060d00410121050c020b2006103322050d010c4f0b2002280204210520042006460d0020052004200610372205450d4a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fb003a00002002410c6a200441016a3602000c440b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d47200441017422062005200620054b1b22064100480d470240024020040d00024020060d00410121050c020b2006103322050d010c4e0b2002280204210520042006460d0020052004200610372205450d490b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fc003a00002002410c6a200441016a3602000c430b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d46200441017422062005200620054b1b22064100480d460240024020040d00024020060d00410121050c020b2006103322050d010c4d0b2002280204210520042006460d0020052004200610372205450d480b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fd003a00002002410c6a200441016a3602000c420b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d45200441017422062005200620054b1b22064100480d450240024020040d00024020060d00410121050c020b2006103322050d010c4c0b2002280204210520042006460d0020052004200610372205450d470b20022005360204200241086a20063602002002410c6a28020021040b200520046a41fe003a00002002410c6a200441016a3602000c410b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d44200441017422062005200620054b1b22064100480d440240024020040d00024020060d00410121050c020b2006103322050d010c4b0b2002280204210520042006460d0020052004200610372205450d460b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ff003a00002002410c6a200441016a3602000c400b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d43200441017422062005200620054b1b22064100480d430240024020040d00024020060d00410121050c020b2006103322050d010c4a0b2002280204210520042006460d0020052004200610372205450d450b20022005360204200241086a20063602002002410c6a28020021040b200520046a4180013a00002002410c6a200441016a3602000c3f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d42200441017422062005200620054b1b22064100480d420240024020040d00024020060d00410121050c020b2006103322050d010c490b2002280204210520042006460d0020052004200610372205450d440b20022005360204200241086a20063602002002410c6a28020021040b200520046a4181013a00002002410c6a200441016a3602000c3e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d41200441017422062005200620054b1b22064100480d410240024020040d00024020060d00410121050c020b2006103322050d010c480b2002280204210520042006460d0020052004200610372205450d430b20022005360204200241086a20063602002002410c6a28020021040b200520046a4182013a00002002410c6a200441016a3602000c3d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d40200441017422062005200620054b1b22064100480d400240024020040d00024020060d00410121050c020b2006103322050d010c470b2002280204210520042006460d0020052004200610372205450d420b20022005360204200241086a20063602002002410c6a28020021040b200520046a4183013a00002002410c6a200441016a3602000c3c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3f200441017422062005200620054b1b22064100480d3f0240024020040d00024020060d00410121050c020b2006103322050d010c460b2002280204210520042006460d0020052004200610372205450d410b20022005360204200241086a20063602002002410c6a28020021040b200520046a4184013a00002002410c6a200441016a3602000c3b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3e200441017422062005200620054b1b22064100480d3e0240024020040d00024020060d00410121050c020b2006103322050d010c450b2002280204210520042006460d0020052004200610372205450d400b20022005360204200241086a20063602002002410c6a28020021040b200520046a4185013a00002002410c6a200441016a3602000c3a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3d200441017422062005200620054b1b22064100480d3d0240024020040d00024020060d00410121050c020b2006103322050d010c440b2002280204210520042006460d0020052004200610372205450d3f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4186013a00002002410c6a200441016a3602000c390b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3c200441017422062005200620054b1b22064100480d3c0240024020040d00024020060d00410121050c020b2006103322050d010c430b2002280204210520042006460d0020052004200610372205450d3e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4187013a00002002410c6a200441016a3602000c380b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3b200441017422062005200620054b1b22064100480d3b0240024020040d00024020060d00410121050c020b2006103322050d010c420b2002280204210520042006460d0020052004200610372205450d3d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4188013a00002002410c6a200441016a3602000c370b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3d200441017422062005200620054b1b22064100480d3d0240024020040d00024020060d00410121050c020b2006103322050d010c410b2002280204210520042006460d0020052004200610372205450d3c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4189013a00002002410c6a200441016a3602000c360b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3c200441017422062005200620054b1b22064100480d3c0240024020040d00024020060d00410121050c020b2006103322050d010c400b2002280204210520042006460d0020052004200610372205450d3c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418a013a00002002410c6a200441016a3602000c350b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3b200441017422062005200620054b1b22064100480d3b0240024020040d00024020060d00410121050c020b2006103322050d010c3f0b2002280204210520042006460d0020052004200610372205450d3b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418b013a00002002410c6a200441016a3602000c340b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d3a200441017422062005200620054b1b22064100480d3a0240024020040d00024020060d00410121050c020b2006103322050d010c3e0b2002280204210520042006460d0020052004200610372205450d3a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a418c013a00002002410c6a200441016a3602000c330b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d39200441017422062005200620054b1b22064100480d390240024020040d00024020060d00410121050c020b2006103322050d010c3d0b2002280204210520042006460d0020052004200610372205450d390b20022005360204200241086a20063602002002410c6a28020021040b200520046a418d013a00002002410c6a200441016a3602000c320b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d38200441017422062005200620054b1b22064100480d380240024020040d00024020060d00410121050c020b2006103322050d010c3c0b2002280204210520042006460d0020052004200610372205450d380b20022005360204200241086a20063602002002410c6a28020021040b200520046a418e013a00002002410c6a200441016a3602000c310b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d37200441017422062005200620054b1b22064100480d370240024020040d00024020060d00410121050c020b2006103322050d010c3b0b2002280204210520042006460d0020052004200610372205450d370b20022005360204200241086a20063602002002410c6a28020021040b200520046a418f013a00002002410c6a200441016a3602000c300b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d36200441017422062005200620054b1b22064100480d360240024020040d00024020060d00410121050c020b2006103322050d010c3a0b2002280204210520042006460d0020052004200610372205450d360b20022005360204200241086a20063602002002410c6a28020021040b200520046a4190013a00002002410c6a200441016a3602000c2f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d35200441017422062005200620054b1b22064100480d350240024020040d00024020060d00410121050c020b2006103322050d010c390b2002280204210520042006460d0020052004200610372205450d350b20022005360204200241086a20063602002002410c6a28020021040b200520046a4191013a00002002410c6a200441016a3602000c2e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d34200441017422062005200620054b1b22064100480d340240024020040d00024020060d00410121050c020b2006103322050d010c380b2002280204210520042006460d0020052004200610372205450d340b20022005360204200241086a20063602002002410c6a28020021040b200520046a4192013a00002002410c6a200441016a3602000c2d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d33200441017422062005200620054b1b22064100480d330240024020040d00024020060d00410121050c020b2006103322050d010c370b2002280204210520042006460d0020052004200610372205450d330b20022005360204200241086a20063602002002410c6a28020021040b200520046a4193013a00002002410c6a200441016a3602000c2c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d32200441017422062005200620054b1b22064100480d320240024020040d00024020060d00410121050c020b2006103322050d010c360b2002280204210520042006460d0020052004200610372205450d320b20022005360204200241086a20063602002002410c6a28020021040b200520046a4194013a00002002410c6a200441016a3602000c2b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d31200441017422062005200620054b1b22064100480d310240024020040d00024020060d00410121050c020b2006103322050d010c350b2002280204210520042006460d0020052004200610372205450d310b20022005360204200241086a20063602002002410c6a28020021040b200520046a4195013a00002002410c6a200441016a3602000c2a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d30200441017422062005200620054b1b22064100480d300240024020040d00024020060d00410121050c020b2006103322050d010c340b2002280204210520042006460d0020052004200610372205450d300b20022005360204200241086a20063602002002410c6a28020021040b200520046a4196013a00002002410c6a200441016a3602000c290b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2f200441017422062005200620054b1b22064100480d2f0240024020040d00024020060d00410121050c020b2006103322050d010c330b2002280204210520042006460d0020052004200610372205450d2f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4197013a00002002410c6a200441016a3602000c280b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2e200441017422062005200620054b1b22064100480d2e0240024020040d00024020060d00410121050c020b2006103322050d010c320b2002280204210520042006460d0020052004200610372205450d2e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4198013a00002002410c6a200441016a3602000c270b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2d200441017422062005200620054b1b22064100480d2d0240024020040d00024020060d00410121050c020b2006103322050d010c310b2002280204210520042006460d0020052004200610372205450d2d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a4199013a00002002410c6a200441016a3602000c260b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2c200441017422062005200620054b1b22064100480d2c0240024020040d00024020060d00410121050c020b2006103322050d010c300b2002280204210520042006460d0020052004200610372205450d2c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419a013a00002002410c6a200441016a3602000c250b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2b200441017422062005200620054b1b22064100480d2b0240024020040d00024020060d00410121050c020b2006103322050d010c2f0b2002280204210520042006460d0020052004200610372205450d2b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419b013a00002002410c6a200441016a3602000c240b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d2a200441017422062005200620054b1b22064100480d2a0240024020040d00024020060d00410121050c020b2006103322050d010c2d0b2002280204210520042006460d0020052004200610372205450d2a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a419c013a00002002410c6a200441016a3602000c230b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d29200441017422062005200620054b1b22064100480d290240024020040d00024020060d00410121050c020b200610332205450d2c0c010b2002280204210520042006460d0020052004200610372205450d290b20022005360204200241086a20063602002002410c6a28020021040b200520046a419d013a00002002410c6a200441016a3602000c220b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d28200441017422062005200620054b1b22064100480d280240024020040d00024020060d00410121050c020b200610332205450d2b0c010b2002280204210520042006460d0020052004200610372205450d280b20022005360204200241086a20063602002002410c6a28020021040b200520046a419e013a00002002410c6a200441016a3602000c210b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d27200441017422062005200620054b1b22064100480d270240024020040d00024020060d00410121050c020b200610332205450d2a0c010b2002280204210520042006460d0020052004200610372205450d270b20022005360204200241086a20063602002002410c6a28020021040b200520046a419f013a00002002410c6a200441016a3602000c200b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d26200441017422062005200620054b1b22064100480d260240024020040d00024020060d00410121050c020b200610332205450d290c010b2002280204210520042006460d0020052004200610372205450d260b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a0013a00002002410c6a200441016a3602000c1f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d25200441017422062005200620054b1b22064100480d250240024020040d00024020060d00410121050c020b200610332205450d280c010b2002280204210520042006460d0020052004200610372205450d250b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a1013a00002002410c6a200441016a3602000c1e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d24200441017422062005200620054b1b22064100480d240240024020040d00024020060d00410121050c020b200610332205450d270c010b2002280204210520042006460d0020052004200610372205450d240b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a2013a00002002410c6a200441016a3602000c1d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d23200441017422062005200620054b1b22064100480d230240024020040d00024020060d00410121050c020b200610332205450d260c010b2002280204210520042006460d0020052004200610372205450d230b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a3013a00002002410c6a200441016a3602000c1c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d22200441017422062005200620054b1b22064100480d220240024020040d00024020060d00410121050c020b200610332205450d250c010b2002280204210520042006460d0020052004200610372205450d220b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a4013a00002002410c6a200441016a3602000c1b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d21200441017422062005200620054b1b22064100480d210240024020040d00024020060d00410121050c020b200610332205450d240c010b2002280204210520042006460d0020052004200610372205450d210b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a5013a00002002410c6a200441016a3602000c1a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d20200441017422062005200620054b1b22064100480d200240024020040d00024020060d00410121050c020b200610332205450d230c010b2002280204210520042006460d0020052004200610372205450d200b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a6013a00002002410c6a200441016a3602000c190b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1f200441017422062005200620054b1b22064100480d1f0240024020040d00024020060d00410121050c020b200610332205450d220c010b2002280204210520042006460d0020052004200610372205450d1f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a7013a00002002410c6a200441016a3602000c180b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1e200441017422062005200620054b1b22064100480d1e0240024020040d00024020060d00410121050c020b200610332205450d210c010b2002280204210520042006460d0020052004200610372205450d1e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a8013a00002002410c6a200441016a3602000c170b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1d200441017422062005200620054b1b22064100480d1d0240024020040d00024020060d00410121050c020b200610332205450d200c010b2002280204210520042006460d0020052004200610372205450d1d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41a9013a00002002410c6a200441016a3602000c160b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1c200441017422062005200620054b1b22064100480d1c0240024020040d00024020060d00410121050c020b200610332205450d1f0c010b2002280204210520042006460d0020052004200610372205450d1c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41aa013a00002002410c6a200441016a3602000c150b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1b200441017422062005200620054b1b22064100480d1b0240024020040d00024020060d00410121050c020b200610332205450d1e0c010b2002280204210520042006460d0020052004200610372205450d1b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ab013a00002002410c6a200441016a3602000c140b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d1a200441017422062005200620054b1b22064100480d1a0240024020040d00024020060d00410121050c020b200610332205450d1d0c010b2002280204210520042006460d0020052004200610372205450d1a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ac013a00002002410c6a200441016a3602000c130b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d19200441017422062005200620054b1b22064100480d190240024020040d00024020060d00410121050c020b200610332205450d1c0c010b2002280204210520042006460d0020052004200610372205450d190b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ad013a00002002410c6a200441016a3602000c120b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d18200441017422062005200620054b1b22064100480d180240024020040d00024020060d00410121050c020b200610332205450d1b0c010b2002280204210520042006460d0020052004200610372205450d180b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ae013a00002002410c6a200441016a3602000c110b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d17200441017422062005200620054b1b22064100480d170240024020040d00024020060d00410121050c020b200610332205450d1a0c010b2002280204210520042006460d0020052004200610372205450d170b20022005360204200241086a20063602002002410c6a28020021040b200520046a41af013a00002002410c6a200441016a3602000c100b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d16200441017422062005200620054b1b22064100480d160240024020040d00024020060d00410121050c020b200610332205450d190c010b2002280204210520042006460d0020052004200610372205450d160b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b0013a00002002410c6a200441016a3602000c0f0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d15200441017422062005200620054b1b22064100480d150240024020040d00024020060d00410121050c020b200610332205450d180c010b2002280204210520042006460d0020052004200610372205450d150b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b1013a00002002410c6a200441016a3602000c0e0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d14200441017422062005200620054b1b22064100480d140240024020040d00024020060d00410121050c020b200610332205450d170c010b2002280204210520042006460d0020052004200610372205450d140b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b2013a00002002410c6a200441016a3602000c0d0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d13200441017422062005200620054b1b22064100480d130240024020040d00024020060d00410121050c020b200610332205450d160c010b2002280204210520042006460d0020052004200610372205450d130b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b3013a00002002410c6a200441016a3602000c0c0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d12200441017422062005200620054b1b22064100480d120240024020040d00024020060d00410121050c020b200610332205450d150c010b2002280204210520042006460d0020052004200610372205450d120b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b4013a00002002410c6a200441016a3602000c0b0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d11200441017422062005200620054b1b22064100480d110240024020040d00024020060d00410121050c020b200610332205450d140c010b2002280204210520042006460d0020052004200610372205450d110b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b5013a00002002410c6a200441016a3602000c0a0b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d10200441017422062005200620054b1b22064100480d100240024020040d00024020060d00410121050c020b200610332205450d130c010b2002280204210520042006460d0020052004200610372205450d100b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b6013a00002002410c6a200441016a3602000c090b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0f200441017422062005200620054b1b22064100480d0f0240024020040d00024020060d00410121050c020b200610332205450d120c010b2002280204210520042006460d0020052004200610372205450d0f0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b7013a00002002410c6a200441016a3602000c080b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0e200441017422062005200620054b1b22064100480d0e0240024020040d00024020060d00410121050c020b200610332205450d110c010b2002280204210520042006460d0020052004200610372205450d0e0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b8013a00002002410c6a200441016a3602000c070b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0d200441017422062005200620054b1b22064100480d0d0240024020040d00024020060d00410121050c020b200610332205450d100c010b2002280204210520042006460d0020052004200610372205450d0d0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41b9013a00002002410c6a200441016a3602000c060b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0c200441017422062005200620054b1b22064100480d0c0240024020040d00024020060d00410121050c020b200610332205450d0f0c010b2002280204210520042006460d0020052004200610372205450d0c0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41ba013a00002002410c6a200441016a3602000c050b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0b200441017422062005200620054b1b22064100480d0b0240024020040d00024020060d00410121050c020b200610332205450d0e0c010b2002280204210520042006460d0020052004200610372205450d0b0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bb013a00002002410c6a200441016a3602000c040b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d0a200441017422062005200620054b1b22064100480d0a0240024020040d00024020060d00410121050c020b200610332205450d0d0c010b2002280204210520042006460d0020052004200610372205450d0a0b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bc013a00002002410c6a200441016a3602000c030b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d09200441017422062005200620054b1b22064100480d090240024020040d00024020060d00410121050c020b200610332205450d0c0c010b2002280204210520042006460d0020052004200610372205450d090b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bd013a00002002410c6a200441016a3602000c020b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d08200441017422062005200620054b1b22064100480d080240024020040d00024020060d00410121050c020b200610332205450d0b0c010b2002280204210520042006460d0020052004200610372205450d080b20022005360204200241086a20063602002002410c6a28020021040b200520046a41be013a00002002410c6a200441016a3602000c010b02400240200241086a2802002002410c6a2802002204460d00200228020421050c010b200441016a22052004490d07200441017422062005200620054b1b22064100480d070240024020040d00024020060d00410121050c020b200610332205450d0a0c010b2002280204210520042006460d0020052004200610372205450d070b20022005360204200241086a20063602002002410c6a28020021040b200520046a41bf013a00002002410c6a200441016a3602000b2000411f3a000020012d00004109470d090240200141046a280200220228020441ffffffff0371450d0020022802001035200128020421020b200210350c090b103e000b103e000b103e000b103c000b103c000b103e000b103c000b103c000b20002004290200370200200041086a200441086a29020037020020012d00004109470d000240200141046a280200220228020441ffffffff0371450d0020022802001035200128020421020b200210350b200341106a24000f0b103c000ba907010c7f230041d0086b22022400410021034100210402400240024002400240024002400240024002400240034002402003411f4d0d00410f21030c030b20012802082205200128020c2206460d01200641016a22072006490d0420052007490d082001280200220820066a2d000021062001200736020c200641ff00712003411f71742004722104200341076a21032006418001710d000b024020034120490d00410d21032006410f4b0d020b20040d022000428080808010370200200041086a42003702000c0a0b200241013a0089082002411c6a41013602002002420137020c200241acfdcb003602082002413636029c08200220024198086a360218200220024189086a36029808200241b8086a200241086a1041410521030b2000200336020420004101360200200041086a20022903b808370200200041106a200241b8086a41086a2802003602000c080b200241086a4100418008109f081a41002106410021094101210a4100210b02400340200520076b2004200b6b22034180082003418008491b2203490d01200720036a220c2007490d032005200c490d04200241086a200820076a2003109d081a2001200c36020c02400240200920066b2003490d00200620036a210c2009210d0c010b200620036a220c2006490d0620094101742207200c2007200c4b1b220d4100480d06024020090d000240200d0d004101210a0c020b200d1033220a0d010c090b2009200d460d00200a2009200d1037220a450d080b200a20066a200241086a2003109d081a20042003200b6a220b4d0d08200128020c21072001280208210520012802002108200c2106200d21090c000b0b200241013a00a708200241cc086a4101360200200242013702bc08200241acfdcb003602b8082002413636029c08200220024198086a3602c8082002200241a7086a36029808200241a8086a200241b8086a104120024194086a200241b0086a280200360000200220022903a80837008c08200041053a000420002002290089083700052000410c6a20024190086a290000370000200041013602002009450d07200a10350c070b417f200741c0fdcb001059000b2007200c41c0fdcb001059000b200c200541c0fdcb001058000b103e000b2007200541c0fdcb001058000b103c000b200241086a200a200c1074024020022802084101470d000240200d450d00200a10350b200041083a0004200041013602000c010b2000200a3602042000410c6a200c360200200041086a200d360200200041003602000b200241d0086a24000b15002001200028020022002802002000280208105a0bf90401067f200441046a21050240024002400240200441086a2802002004410c6a2802002206460d00200528020021070c010b200641016a22072006490d01200641017422082007200820074b1b22084100480d010240024020060d00024020080d00410121070c020b2008103322070d010c040b2005280200210720062008460d0020072006200810372207450d030b20042007360204200441086a20083602002004410c6a28020021060b200720066a20024101463a00002004410c6a2209200641016a2206360200200441086a210a034002400240200a2802002006460d00200528020021070c010b200641016a22072006490d02200641017422082007200820074b1b22084100480d020240024020060d00024020080d00410121070c020b200810332207450d050c010b2005280200210720062008460d0020072006200810372207450d040b20042007360204200a2008360200200928020021060b200720066a200141807f72200141ff0071200141077622071b3a00002009200641016a22063602002007210120070d000b024020024101470d00200441086a21082004410c6a210903400240024020082802002006460d00200528020021010c010b200641016a22012006490d03200641017422072001200720014b1b22074100480d030240024020060d00024020070d00410121010c020b200710332201450d060c010b2005280200210120062007460d0020012006200710372201450d050b2004200136020420082007360200200928020021060b200120066a200341807f72200341ff0071200341077622011b3a00002009200641016a22063602002001210320010d000b0b2000411f3a00000f0b103e000b103c000bc807010a7f230041d0006b220224000240024002400240024002400240024002400240024020012802082203200128020c2204460d00200441016a22052004490d0220032005490d032001280200220620046a2d000021072001200536020c20074102490d01200041173a000420004101360200200041056a20073a00000c0a0b200241013a001f200241cc006a41013602002002420137023c200241acfdcb00360238200241363602342002200241306a36024820022002411f6a360230200241206a200241386a10412002411b6a200241286a28020036000020022002290320370013200220022900103703002002200241176a290000370007200041053a0004200020022903003700052000410c6a2002290007370000200041013602000c090b410120036b2108200441026a21044100210541002109034002402005411f4d0d00410f21050c090b200820046a4102460d072004450d0320032004490d05200620046a417f6a2d0000210a2001200436020c200a41ff00712005411f71742009722109200441016a2104200541076a2105200a418001710d000b024020054120490d00410d2105200a410f4b0d080b410021050240024002402007410171450d002004417f6a2104410021054100210b034002402005411f4d0d00410f21040c040b20032004460d022004417f460d072003200441016a2208490d09200620046a2d0000210a2001200836020c200a41ff00712005411f7174200b72210b200541076a210520082104200a418001710d000b024020054120490d00410d2104200a410f4b0d030b410121050b20002009360204200041003602002000410c6a200b360200200041086a20053602000c0a0b200241013a0000200241cc006a41013602002002420137023c200241acfdcb00360238200241363602342002200241306a36024820022002360230200241106a200241386a1041410521040b2000200436020420004101360200200041086a2002290310370200200041106a200241106a41086a2802003602000c080b417f200541c0fdcb001059000b2005200341c0fdcb001058000b417f200441c0fdcb001059000b417f200441016a41c0fdcb001059000b2004200341c0fdcb001058000b200441016a200341c0fdcb001058000b200241013a0000200241cc006a41013602002002420137023c200241acfdcb00360238200241363602342002200241306a36024820022002360230200241106a200241386a1041410521050b2000200536020420004101360200200041086a2002290310370200200041106a200241106a41086a2802003602000b200241d0006a24000bc4c901040b7f027e147f017e230041e081046b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002402001280204220320012802082204460d00200441016a22052004490d0720032005490d06200128020020046a2d00002104200120053602082004410c4b0d0120040e0d02031211100f0e0d0c0b0a0908020b200241013a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022802c88104210420022802cc8104210120004101360200200041003a00042001450d1c200410350c1c0b200041123a000420004101360200200041056a20043a00000c1b0b200241b8016a200110c0074101210620022802bc012107024020022802b8014101460d0041002108200241b8016a410041808001109f081a41002103410021092007450d13410021054100210a410121064100210b024003402001280204220c200128020822036b2007200b6b220441808001200441808001491b2204490d01200320046a22092003490d05200c2009490d04200241b8016a200128020020036a2004109d081a2001200936020802400240200a20056b2004490d00200520046a2103200a21090c010b200520046a22032005490d19200a41017422092003200920034b1b22094100480d1902400240200a0d00024020090d00410121060c020b200910332206450d1f0c010b200a2009460d002006200a200910372206450d1e0b2009210a0b200620056a200241b8016a2004109d081a2003210520072004200b6a220b4b0d000c150b0b200241013a00b88104200241dc81046a4101360200200242013702cc8104200241acfdcb003602c881042002413636022c2002200241286a3602d881042002200241b881046a360228200241e0006a200241c881046a10412002290360210d2002280268210141052107200a450d15200610350c150b200241c8016a2802002101200241c0016a290300210d0c140b200241b8016a200110c707200241b8016a41086a290300220d422088210e200241c8016a280200210120022802bc01210a20022802b8014101460d0f200ea72103200241cc016a280200210f200da72110410021044100210b024002400240024002400240024002400240034002402004411f4d0d00410f21090c030b20032001460d012001417f460d09200141016a220820034b0d08200a20016a2d0000220541ff00712004411f7174200b72210b200441076a2104200821012005418001710d000b024020044120490d00410d21092005410f4b0d020b200241003602c08104200242043703b88104200b0d02410421040c030b200241013a00c88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241c881046a36022820024198016a200241b8016a1041410521090b20024188016a41086a20024198016a41086a28020022013602002002200229039801220d370388010c030b410020036b21114104210441002112410021130340024002400240024002400240024002400240024002400240024020082003460d00200841016a22052008490d01200520034b0d020240200a20086a2d0000220741e000460d004118211441002115200521080c0c0b200841036a2107410021084100210602400240024003402007210902402008411f4d0d00410f21140c030b20032005460d012005417f460d07200541016a220c20034b0d09200a20056a2d0000221641ff00712008411f71742006722106200941016a2107200841076a2108200c21052016418001710d000b024020084120490d00410d21142016410f4d0d00200c21050c020b41002117200241003602682002420137036020060d02410121144100211841002116200c21050c0c0b200241013a0060200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a1041200241306a41086a200241c881046a41086a280200360200200220022903c8810437033041052114200321050b200241c0006a41086a200241306a41086a280200221936020020022002290330220d370340200da72116410021074101211720022802442118410021150c0b0b200a200c6a211a2011200c6a211b410021164101211441002115410021180240034020162108201b201822056a450d012009450d060240200920034d0d002009200341c0fdcb001058000b0240201a20056a2c0000220741004e0d004119211c201d2116201e2118201f21190c0a0b4106211c200741c00071450d08200741807f72220741ff017141fc01490d080240024020052015460d00200821160c010b024020082015460d0020082116200821150c010b200841016a22162008490d2b200841017422182016201820164b1b22164100480d2b0240024020080d00024020160d00410121140c020b201610332214450d310c010b20082016460d0020142008201610372214450d300b2002201636026420022014360260201621150b201420056a2007417f733a00002002200541016a2218360268200941016a210920062018460d0a0c000b0b200241013a00a801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241a8016a360228200241c881046a200241b8016a10414105211c20022802c881042216211d20022802cc81042218211e20022802d081042219211f200321090c070b200241013a0060200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022802c88104211620022802cc8104211820022d00d08104210920022d00d18104210620022f01d2810421014105211441002115200321080c0a0b417f200541c0fdcb001059000b2005200341c0fdcb001058000b417f200541016a41c0fdcb001059000b417f200941c0fdcb001059000b200541016a200341c0fdcb001058000b2020211620212118202221190b410021154101211702402008450d00201410350b201c2114201621202018212120192122200921050c020b200c20186a21050b20144110762115201441087621070b0240024002400240024002400240024020170d002015411074200741ff017141087472201441ff017172211b410021174100210941002106034002402009411f4d0d00410f21140c080b0240024020032005460d002005417f460d05200541016a220820034d0d01200541016a200341c0fdcb001058000b200241013a0060200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022802c88104210720022802cc8104211820022d00d08104210920022d00d18104210620022f01d28104210141052114200321050c090b200a20056a2d0000220c41ff00712009411f71742006722106200941076a210920082105200c418001710d000b20094120490d01200c410f4d0d0120082105410d21140c060b201941107621012019410876210620052108201921090c070b024002400240200641014b0d00024020060e020002000b410421090c020b4104211441bed8cb00210741242118200821050c060b0240024020032008460d00200841016a22052008490d04200520034b0d05200a20086a2c0000221741004e0d01411921140c070b200241013a0060200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022802c88104210720022802cc8104211820022d00d08104210920022d00d18104210620022f01d28104210141052114200321050c070b201741c00071450d04201741807f72221741ff017141fc01490d042017417f732109200521080b20014180807c71200941ff01714108747241e000722101410021050c070b417f200541016a41c0fdcb001059000b417f200841016a41c0fdcb001059000b200841016a200341c0fdcb001058000b410621140b0b4100211502402016450d00201b10350b2005210820072116201721070b200641ff0171410874200941ff0171722001411074722101410121050b2015411074200741ff017141087472201441ff01717221092018ad4220862016ad84210d20050d02201341016a21130240201220022802bc8104470d00200241b881046a20124101108c0120022802b88104210420022802c0810421120b200420124104746a2205200136020c2005200d370204200520093602002002201241016a22123602c081042013200b470d000b0b2008200f46210120022902bc8104212302402010450d00200a10350b410221032001450d020c170b02402012450d00201241047421052004210303400240200341046a280200450d00200328020010350b200341106a2103200541706a22050d000b0b20022802bc810441ffffffff0071450d00200410350b200d422088210e20094108762103024020100d002009210a0c140b200a10352009210a0c130b20024103410220011b3a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022903c88104210d20022802d08104210102402023422088a72203450d00200341047421052004210303400240200341046a280200450d00200328020010350b200341106a2103200541706a22050d000b0b200d422088210e4105210a41002103202342ffffffff0083500d12200410350c120b200141016a200341c0fdcb001058000b417f200141016a41c0fdcb001059000b2009200c41c0fdcb001058000b2003200941c0fdcb001059000b2005200341c0fdcb001058000b417f200541c0fdcb001059000b200241b8016a200110c707200241b8016a41106a2802002101200241b8016a410c6a2802002105200241b8016a41086a280200210920022802bc01210b0240024020022802b8014101460d00200241cc016a280200210641002103410021040240024002400240034002402003411f4d0d00410f21010c030b20052001460d012001417f460d042005200141016a220a490d06200b20016a2d0000220841ff00712003411f71742004722104200341076a2103200a21012008418001710d000b024020034120490d00410d21012008410f4b0d020b2006200a46210102402009450d00200b10350b2001450d02410b21030c130b200241013a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a1041410521010b2000200136020420004101360200200041086a20022903c88104370200200041106a200241c881046a41086a2802003602002009450d18200b10350c180b20024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241d381046a200241e8006a280200360000200220022903603700cb8104200041053a0004200020022900c881043700052000410c6a200241cf81046a290000370000200041013602000c170b417f200141016a41c0fdcb001059000b2000200b36020420004101360200200041106a20013602002000410c6a2005360200200041086a20093602000c150b200141016a200541c0fdcb001058000b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b024002400240024020022802b8014101460d002002200241cc016a2802003602702002200136026c2002200b3602602002200d370264200d422088a72108410021044100210a02400240024002400240034002402004411f4d0d00410f210b0c030b20082001460d012001417f460d05200141016a220520084b0d04200b20016a2d000021032002200536026c200341ff00712004411f7174200a72210a200441076a2104200521012003418001710d000b024020044120490d00410d210b2003410f4b0d020b200241003602800120024204370378200a0d02410421040c070b200241013a00c88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241c881046a36022820024198016a200241b8016a10414105210b0b20024188016a41086a20024198016a41086a28020022013602002002200229039801220d370388010c040b410021070340200741016a21074100210141002105024002400240024002400240024002400240034002402001411f4d0d00410f210b0c030b20022802682208200228026c2204460d01200441016a22032004490d0520082003490d06200228026020046a2d000021042002200336026c200441ff00712001411f71742005722105200141076a21012004418001710d000b20014120490d022004410f4d0d02410d210b0c010b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a1041200241c0006a41086a200241c881046a41086a280200360200200220022903c88104220d370340200da7210a4105210b0b20022802482101200228024421090c010b200241b8016a200241e0006a10a70720022802c401211820022802c001211520022802bc01211420022802b8014101470d0320022802c80121012014210b2015210a201821090b200241d0006a41086a20024198016a41086a28020036020020022002290398013703500c030b417f200341c0fdcb001059000b2003200841c0fdcb001058000b410021044100210b02400240024002400240024002400240034002402004411f4d0d00410f210b0c030b20022802682208200228026c2203460d01200341016a22012003490d0420082001490d072002280260220920036a2d000021032002200136026c200341ff00712004411f7174200b72210b200441076a21042003418001710d000b024020044120490d002003410f4d0d00410d210b0c020b41002112200241b8016a410041808004109f081a200b0d02410121134100210c0c090b200241013a00b88104200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a1041200241306a41086a200241c881046a41086a280200360200200220022903c88104220d370330200da7210a4105210b0b20022802382101200228023421090c050b4100210641012113410021034100211602400340200820016b200b20166b220441808004200441808004491b2204490d01200120046a220c2001490d032008200c490d04200241b8016a200920016a2004109d081a2002200c36026c02400240200620036b2004490d00200320046a210c200621120c010b200320046a220c2003490d1f20064101742201200c2001200c4b1b22124100480d1f024020060d00024020120d00410121130c020b201210332213450d240c010b20062012460d0020132006201210372213450d230b201320036a200241b8016a2004109d081a200b200420166a22164d0d08200228026c2101200228026821082002280260210920122106200c21030c000b0b200241013a0040200241013602dc8104200242013702cc8104200241acfdcb003602c881042002413636022c2002200241286a3602d881042002200241c0006a360228200241b881046a200241c881046a104120022802b88104210a20022802bc8104210920022802c0810421014105210b2006450d04201310350c040b417f200141c0fdcb001059000b2001200c41c0fdcb001059000b200c200841c0fdcb001058000b2001200841c0fdcb001058000b02402018450d0020184104742103201421040340024020042d00004109470d000240200441046a2208280200220528020441ffffffff0371450d0020052802001035200828020021050b200510350b200441106a2104200341706a22030d000b0b0240201541ffffffff0071450d00201410350b200241d0006a41086a20024198016a41086a28020036020020022002290398013703500b2009ad422086200aad84210d200241f8006a10b407200228027c2204450d052004411c6c450d05200228027810350c050b200241d0006a41086a200c36020020024188016a41086a2208200c360200200220123602ac01200220133602a801200220022903a801220d3703502002200d370388012015ad4220862014ad84210d02402002280280012203200228027c470d00200241f8006a2003410110f90120022802800121030b200228027822042003411c6c6a2201200d3702042001200536020020012002290388013702102001410c6a2018360200200141186a20082802003602002002200341016a360280012007200a460d050c000b0b200141016a200841c0fdcb001058000b417f200141016a41c0fdcb001059000b200d422088210e200b41087621040c020b200d422088210e200b41087621042002280264450d01200228026010350c010b2002200229027c222337021c20022004360218200228026c200228027046210102402002280264450d00200228026010350b024020010d0020024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a104120022903c88104210d20022802d081042101200241186a10b40702402023a72203450d002003411c6c450d00200410350b200d422088210e4105210b410021040c010b410d21030c0d0b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002004410874200b41ff0171723602040c130b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b0240024002400240024002400240024002400240024002400240024020022802b8014101460d00200241cc016a2802002112200d422088a72105200da72106410021044100210802400240024002400240034002402004411f4d0d00410f21090c030b20052001460d012001417f460d05200141016a220320054b0d04200b20016a2d0000220a41ff00712004411f71742008722108200441076a210420032101200a418001710d000b024020044120490d00410d2109200a410f4b0d020b200241003602b001200242043703a80120080d02410421040c110b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a1041410521090b200241e0006a41086a200241c881046a41086a2802002201360200200220022903c88104220d3703600c0e0b410021150340201541016a2115410021014100210a024002400240024002400240024002400240024002400240024002400240034002402001411f4d0d00410f210920022802a00121010c1d0b20052003460d012003417f460d04200341016a220420054b0d0b200b20036a2d0000220941ff00712001411f7174200a72210a200141076a2101200421032009418001710d000b024020014120490d002009410f4d0d00410d210920022802a00121010c1c0b4100210c200241b8016a410041808001109f081a200a0d01410121182004210341002114410021090c020b200241013a00c88104200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241c881046a36022820024198016a200241b8016a104141052109200229039801210d20022802a00121010c1a0b410021164101211841002107410021130340200520046b200a20136b220141808001200141808001491b2201490d19200420016a22032004490d03200320054b0d04200241b8016a200b20046a2001109d081a02400240201620076b2001490d00200720016a2109201621140c010b200720016a22092007490d2d201641017422042009200420094b1b22144100480d2d0240024020160d00024020140d00410121180c020b201410332218450d330c010b20162014460d0020182016201410372218450d320b201421160b201820076a200241b8016a2001109d081a2003210420092107200a200120136a22134b0d000b0b200220093602702002410036026c2002201836026020022009ad4220862014ad84370264410021014100210702400240024002400240024002400240034002402001411f4d0d00410f21090c030b2009200c460d01200c417f460d0c200c41016a220a20094b0d112018200c6a2d000021042002200a36026c200441ff00712001411f71742007722107200141076a2101200a210c2004418001710d000b024020014120490d002004410f4d0d00410d21090c020b4100210c200241003602c08104200242043703b8810420070d024104211441002110410021180c030b200241013a00b88104200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a1041200241306a41086a200241c881046a41086a280200360200200220022903c88104370330410521090b200241c0006a41086a200241306a41086a280200220136020020022002290330220d370340200da722044108762105200228024421030c1b0b4100211041042114410021190340201941016a21194100210141002116034002402001411f4d0d00410f21090c050b20022802682213200228026c2204460d03200441016a220a2004490d0b2013200a490d102002280260221820046a2d000021092002200a36026c200941ff00712001411f71742016722116200141076a21012009418001710d000b024020014120490d002009410f4d0d00410d21090c040b2013200a460d04200441026a2101200a417f460d0b20132001490d0c2018200a6a2c0000210a2002200136026c0240200a41004e0d00411921090c1a0b41062109200a41c00071450d18200a41807f72220a41ff017141fb014d0d18200a417f7321010240201020022802bc8104470d00200241b881046a2010410110900120022802b88104211420022802c0810421100b201420104103746a220420013a0004200420163602002002201041016a22103602c0810420192007470d000b20022802bc810421180b201420104103746a210920142101034020092001460d04200c20012802006a2204200c49210a200141086a21012004210c200a450d000b200229038801220d422088a7210320024190016a2802002101200da72104411c21090c150b200241013a00c88104200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241c881046a36022820024198016a200241b8016a10414105210920022802980121040b2004410876210520022802a0012101200228029c0121034100210a0c160b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241c881046a200241b8016a104120022802c88104210420022802cc8104210320022802d081042101410521090c140b4100210a200241003602d08104200242083703c881044101210c410821130340200241b8016a200241e0006a10a80720022802c001210420022903c801210d20022802c4012116024002400240024020022802b8014101460d00200441ff017122014106460d022001417e6a41034f0d03200c41016a2201200c4f21092001210c20090d03200441ff0171210141152103418dd2cb0021044104210920014109460d010c150b20022802bc012109200da72101201621030c140b0240201628020441ffffffff0371450d00201628020010350b201610350c130b200c417f6a210c0b2004410876210702400240200a20022802cc8104460d00200a21090c010b200241c881046a200a10a90720022802c88104211320022802d0810421090b201320094104746a2201200d37030820012016360204200120073b0001200120043a0000200141036a20074110763a00002002200941016a220a3602d08104200c0d000b200228026c200228027046210120022802cc8104210702402002280264450d00200228026010350b024020010d0020024103410220011b3a00b88104200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a104120022903c88104210d20022802d0810421010240200a450d00200941047441106a2103201321040340024020042d00004109470d000240200441046a2208280200220528020441ffffffff0371450d0020052802001035200828020021050b200510350b200441106a2104200341706a22030d000b0b200d422088210e0240200741ffffffff0071450d00201310350b200ea72103200da7210441052109201841ffffffff0171450d1a201410350c1a0b20022802b001220120022802ac01470d0b200141016a22042001490d2a200141017422092004200920044b1bad42187e220d422088a70d2a200da722044100480d2a0240024020010d0020040d01410421090c0c0b20022802a8012109200141186c220c2004460d0b0240200c0d0020040d01410421090c0c0b2009200c200410372209450d2f0c0b0b200410332209450d2e0c0a0b417f200341016a41c0fdcb001059000b2004200341c0fdcb001059000b2003200541c0fdcb001058000b417f200c41016a41c0fdcb001059000b417f200a41c0fdcb001059000b417f200141c0fdcb001059000b2001201341c0fdcb001058000b200341016a200541c0fdcb001058000b200c41016a200941c0fdcb001058000b200a201341c0fdcb001058000b200220093602a8012002200441186e3602ac010b20022802a8012204200141186c6a2209201336020c20092010ad4220862018ad8437020420092014360200200941106a200aad4220862007ad843702002002200141016a3602b00120152008460d0f0c000b0b200141016a200541c0fdcb001058000b417f200141016a41c0fdcb001059000b200d422088210e200b41087621040c0c0b0240200a450d00200a4104742108201321050340024020052d00004109470d000240200541046a2207280200220a28020441ffffffff0371450d00200a28020010352007280200210a0b200a10350b200541106a2105200841706a22080d000b0b20022802cc810441ffffffff0071450d00201310350b201841ffffffff0171450d04201410350c040b0b200441087621050b200a41ff0171410874200972210920022802bc810441ffffffff0171450d00201410350b2005410874200441ff01717221040b2002280264450d02200228026010350c020b200241013a009801200241013602dc8104200242013702cc8104200241acfdcb003602c881042002413636022c2002200241286a3602d88104200220024198016a360228200241b881046a200241c881046a104120022903b88104210d20022802c081042101410521092016450d00201810350b200d422088a72103200da721040b200241a8016a10b3072003ad4220862004ad84210d20022802ac012204450d00200441186c450d0020022802a80110350b200d422088210e20094108762104024020060d002009210b0c020b200b10352009210b0c010b200220022902ac01222337027c200220043602782003201246210102402006450d00200b10350b024020010d0020024103410220011b3a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022903c88104210d20022802d081042101200241f8006a10b30702402023a72203450d00200341186c450d00200410350b200d422088210e4105210b410021040c010b410c21030c0c0b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002004410874200b41ff0171723602040c120b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b02400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d481042002200b3602c881042002200d3702cc8104200d422088a72108410021044100210a024002400240024002400240034002402004411f4d0d00410f210b0c030b20082001460d012001417f460d06200141016a220520084b0d05200b20016a2d00002103200220053602d48104200341ff00712004411f7174200a72210a200441076a2104200521012003418001710d000b024020044120490d00410d210b2003410f4b0d020b200241003602a0012002420437039801200a0d02410421040c030b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241c0006a41086a200241e0006a41086a280200360200200220022903603703404105210b0b20024198016a41086a200241c0006a41086a280200220136020020022002290340220d370398010c050b41042104410021090340200941016a21094100210141002108024002400240024002400240024002400240034002402001411f4d0d00410f210b0c030b20022802d08104220b20022802d481042203460d01200341016a22052003490d07200b2005490d0820022802c8810420036a2d00002103200220053602d48104200341ff00712001411f71742008722108200141076a21012003418001710d000b20014120490d022003410f4d0d02410d210b0c010b200241013a0078200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241f8006a360228200241e0006a200241b8016a1041200241306a41086a200241e0006a41086a28020036020020022002290360220d370330200da721064105210b0b20022802382101200228023421030c010b200241b8016a200241c881046a10a70720022802c401210c20022802c001211220022802bc01211620022802b8014101470d0120022802c80121012016210b20122106200c21030b200241d0006a41086a200241b881046a41086a280200360200200220022903b881043703500c010b200241b8016a200241c881046a10ab0720022802c401210320022802c001210620022802bc01210b20022802b8014101470d0320022802c80121010240200c450d00200c4104742108201621050340024020052d00004109470d000240200541046a2209280200220a28020441ffffffff0371450d00200a28020010352009280200210a0b200a10350b200541106a2105200841706a22080d000b0b0240201241ffffffff0071450d00201610350b200241d0006a41086a200241b881046a41086a280200360200200220022903b881043703500b2003ad4220862006ad84210d20024198016a10b207200228029c012203450d082003411c6c450d08200410350c080b417f200541c0fdcb001059000b2005200b41c0fdcb001058000b200241003602c001200242043703b801200241b8016a41002003410274220541027510860120022802c001210702402003450d002005417c6a410276211320022802b80120074102746a2101200b2103034020012003280200360200200141046a2101200341046a21032005417c6a22050d000b200720136a41016a21070b200220073602c0010240200641ffffffff0371450d00200b10350b200241d0006a41086a200241b8016a41086a2802002201360200200241a8016a41086a22052001360200200220022903b801220d3703502002200d3703a8012012ad4220862016ad84210d024020022802a0012203200228029c01470d0020024198016a2003410110f901200228029801210420022802a00121030b20042003411c6c6a2201200d370204200120083602002001410c6a200c360200200120022903a801370210200141186a20052802003602002002200341016a3602a0012009200a470d000b0b2002200229029c01222337028c01200220043602880120022802d4810420022802d88104462101024020022802cc8104450d0020022802c8810410350b024020010d0020024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360210d2002280268210120024188016a10b20702402023a72203450d002003411c6c450d00200410350b200d422088210e4105210b410021040c050b410a21030c0f0b200141016a200841c0fdcb001058000b417f200141016a41c0fdcb001059000b200d422088210e200b41087621040c010b200d422088210e200b410876210420022802cc8104450d0020022802c8810410350b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002004410874200b41ff0171723602040c110b200241b8016a200110c707200241b8016a41106a2802002101200241b8016a410c6a2802002105200241b8016a41086a280200210920022802bc01210b0240024020022802b8014101460d00200241cc016a280200210641002103410021040240024002400240034002402003411f4d0d00410f21010c030b20052001460d012001417f460d042005200141016a220a490d06200b20016a2d0000220841ff00712003411f71742004722104200341076a2103200a21012008418001710d000b024020034120490d00410d21012008410f4b0d020b2006200a46210102402009450d00200b10350b2001450d02410921030c0f0b200241013a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a1041410521010b2000200136020420004101360200200041086a20022903c88104370200200041106a200241c881046a41086a2802003602002009450d14200b10350c140b20024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241d381046a200241e8006a280200360000200220022903603700cb8104200041053a0004200020022900c881043700052000410c6a200241cf81046a290000370000200041013602000c130b417f200141016a41c0fdcb001059000b2000200b36020420004101360200200041106a20013602002000410c6a2005360200200041086a20093602000c110b200141016a200541c0fdcb001058000b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b02400240024002400240024002400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d481042002200b3602c881042002200d3702cc8104200d422088a72108410021044100210a024002400240024002400240034002402004411f4d0d00410f210b0c030b20082001460d012001417f460d06200141016a220520084b0d05200b20016a2d00002103200220053602d48104200341ff00712004411f7174200a72210a200441076a2104200521012003418001710d000b024020044120490d00410d210b2003410f4b0d020b200241003602b001200242043703a801200a0d02410421040c030b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241306a41086a200241e0006a41086a280200360200200220022903603703304105210b0b200241c0006a41086a200241306a41086a280200220136020020022002290330220d3703400c0b0b410021070340200241b8016a200241c881046a10ad0720022802c401211620022802c001210c20022802bc01210b0240024002400240024002400240024002400240024020022802b8014101460d0002400240024002400240024020022802d08104220420022802d481042203460d00200341016a22012003490d0920042001490d0a20022802c88104220520036a2d00002103200220013602d48104200341034b0d0720030e0401020304010b200220073602b001200241013a009801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c180b410021084100210303402008411f4b0d150240024020042001460d002001417f460d0c2004200141016a22064f0d01200141016a200441c0fdcb001058000b200220073602b001200241013a009801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c190b200520016a2d00002109200220063602d48104200941ff00712008411f71742003722103200841076a2108200621012009418001710d000b4100210420084120490d032009410f4d0d030c150b410021084100210303402008411f4b0d140240024020042001460d002001417f460d0c2004200141016a22064f0d01200141016a200441c0fdcb001058000b200220073602b001200241013a009801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c180b200520016a2d00002109200220063602d48104200941ff00712008411f71742003722103200841076a2108200621012009418001710d000b4101210420084120490d022009410f4b0d140c020b410021084100210303402008411f4b0d130240024020042001460d002001417f460d0c2004200141016a22064f0d01200141016a200441c0fdcb001058000b200220073602b001200241013a009801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c170b200520016a2d00002109200220063602d48104200941ff00712008411f71742003722103200841076a2108200621012009418001710d000b4102210420084120490d012009410f4b0d130c010b410021084100210303402008411f4b0d120240024020042001460d002001417f460d0c2004200141016a22064f0d01200141016a200441c0fdcb001058000b200220073602b001200241013a009801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c160b200520016a2d00002109200220063602d48104200941ff00712008411f71742003722103200841076a2108200621012009418001710d000b4103210420084120490d002009410f4b0d120b200220163602bc81042002200c3602b8810420022903b88104210d200720022802ac01470d0a20074101742201200741016a2205200120054b1bad42147e220e422088a70d22200ea7220141004e0d020c220b200220022802c80122013602c08104200220163602bc81042002200c3602b88104200220073602b0010c140b200220073602b00120034108742103410a21040c100b0240024020070d0020010d01410421050c080b20022802a8012105200741146c22082001460d07024020080d0020010d01410421050c080b20052008200110372205450d240c070b200110332205450d230c060b417f200141c0fdcb001059000b2001200441c0fdcb001058000b417f200141016a41c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141016a41c0fdcb001059000b417f200141016a41c0fdcb001059000b200220053602a8012002200141146e3602ac010b20022802a801200741146c6a2201200436020c2001200d3702042001200b360200200141106a2003360200200741016a220121072001200a470d000b200220013602b00120022802a80121040b20022802d4810420022802d8810446210120022902ac012123024020022802cc8104450d0020022802c8810410350b024020010d002023a7210820024103410220011b3a00b88104200241b8016a41146a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360210d2002280268210102402023422088a72203450d00200341146c21052004210303400240200341046a280200450d00200328020010350b200341146a21032005416c6a22050d000b0b200d422088210e4105210b410021032008450d0b200841146c450d0b200410350c0b0b410821030c130b200141016a200841c0fdcb001058000b417f200141016a41c0fdcb001059000b200d422088210e200b41087621030c070b200220073602b001410f2104410021030c010b200220073602b001410d2104410021030b0c010b200228026021012002290264210d41052104410021030b200220013602b881042002200d3702bc8104200d422088210d0240200c450d00200b10350b2004200372210b200da7210120022802b00121070b20022903b88104210d02402007450d0020022802a8012104200741146c210303400240200441046a280200450d00200428020010350b200441146a21042003416c6a22030d000b0b20022802ac012204450d00200441146c450d0020022802a80110350b200d422088210e200b410876210320022802cc8104450d0020022802c8810410350b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200b41ff0171723602040c0f0b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b0240024002400240024002400240024002400240024002400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d481042002200b3602c881042002200d3702cc8104200d422088a72108410021044100210a024002400240034002402004411f4d0d00410f21040c030b20082001460d012001417f460d05200141016a220320084b0d0a200b20016a2d00002105200220033602d48104200541ff00712004411f7174200a72210a200441076a2104200321012005418001710d000b024020044120490d00410d21042005410f4b0d020b200241003602b001200242043703a801200a0d02410421040c0f0b200241013a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a36022820024188016a200241b8016a1041410521040b200241b881046a41086a20024188016a41086a28020022013602002002200229038801220d3703b881040c0c0b200a417f6a2106200241b8016a410472210741042104410421124104210a4100210903400240024020082003460d00200341016a22052003490d0520082005490d06200b20036a2c00002101200220053602d48104200141004e0d01411921160c0a0b200241013a008801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024188016a360228200241e0006a200241b8016a10410c0a0b41062116200141c00071450d080240200141807f72220c41ff017141fc014f0d00200c21010c090b02400240024020082005460d00200341026a21032005417f460d0820082003490d09200b20056a2d00002101200220033602d481040240200141014d0d00410c21160c0c0b4100210320010e020201020b200241013a008801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024188016a360228200241e0006a200241b8016a10410c0b0b410121030b200241b8016a200241c881046a10a707200241306a41086a200741086a2802002201360200200241c0006a41086a2205200136020020022007290200370340024020022802b8014101470d0020022d00c801210420022d00c901210320022f01ca0121010c0c0b200c417f73210820024198016a41086a20052802002201360200200241b881046a41086a2205200136020020022002290340220d370398012002200d3703b881040240200920022802ac01470d00200241a8016a20094101108c0120022802b001210920022802a801220421122004210a0b2005280200210520022903b88104210d200a20094104746a220120083a000c2001200d3702002001410d6a20033a0000200141086a20053602002002200941016a22093602b0012006450d0d2006417f6a210620022802d48104210320022802d08104210820022802c88104210b0c000b0b200d422088210e200b41087621030c0c0b417f200141016a41c0fdcb001059000b417f200541c0fdcb001059000b2005200841c0fdcb001058000b417f200341c0fdcb001059000b2003200841c0fdcb001058000b200141016a200841c0fdcb001058000b0c010b200228026021032002280264210520022802682104410521160b2002200536024820022003360244200220013a0041200220163a004020044110762101200441087621030b20024198016a41086a200241c0006a41086a28020036020020022002290340220e37039801200341ff0171410874200441ff017172210b20014110742106200229029c01210d02402009450d00200a20094104746a210803400240200a2802082204450d00200a2802002101200441047421040340024020012d00004109470d000240200141046a2205280200220328020441ffffffff0371450d0020032802001035200528020021030b200310350b200141106a2101200441706a22040d000b0b200a41106a21010240200a41046a28020041ffffffff0071450d00200a28020010350b2001210a20012008470d000b0b200b2006722101200ea7210420022802ac0141ffffffff0071450d00201210350b200d422088210e20044108762103024020022802cc81040d002004210b0c020b20022802c8810410352004210b0c010b20022802d4810420022802d8810446210120022902ac012123024020022802cc8104450d0020022802c8810410350b024020010d0020024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360210d2002280268210102402023422088a72203450d00200420034104746a21092004210b03400240200b2802082205450d00200b2802002103200541047421050340024020032d00004109470d000240200341046a220a280200220828020441ffffffff0371450d0020082802001035200a28020021080b200810350b200341106a2103200541706a22050d000b0b200b41106a21030240200b41046a28020041ffffffff0071450d00200b28020010350b2003210b20032009470d000b0b200d422088210e4105210b41002103202342ffffffff0083500d01200410350c010b410721030c080b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200b41ff0171723602040c0e0b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210802400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d48104200220083602c881042002200d3702cc8104200d422088a7210541002104410021030240024002400240024003402004411f4b0d010240024020052001460d002001417f460d0a200141016a220a20054d0d01200141016a200541c0fdcb001058000b200220053602d48104200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241306a41086a200241e0006a41086a28020036020020022002290360370330410521080c030b200820016a2d0000220b41ff00712004411f71742003722103200441076a2104200a2101200b418001710d000b2002200a3602d48104024020044120490d00410d2108200b410f4b0d020b4100210120024100360268200242043703604104210402402003450d000340200241b8016a200241c881046a10b00720022903c001210d20022802bc01210820022802b8014101460d04024020012002280264470d00200241e0006a2001410110870120022802602104200228026821010b20042001410c6c6a2205200d370204200520083602002002200141016a22013602682003417f6a22030d000b0b20022802d4810420022802d8810446210120022902642123024020022802cc8104450d0020022802c8810410350b20010d0420024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360220d422088210e2002280268210141052108410021032023a72205450d062005410c6c450d06200410350c060b200220013602d48104410f21080b200241c0006a41086a200241306a41086a280200220136020020022002290330220d3703400c010b200241c8016a280200210120022802642203450d002003410c6c450d00200410350b200d422088210e2008410876210320022802cc8104450d0220022802c8810410350c020b410621030c090b200d422088210e200841087621030b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200841ff0171723602040c0e0b417f200141016a41c0fdcb001059000b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b02400240024002400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d481042002200b3602c881042002200d3702cc8104200d422088a721034100210441002108024002400240024003402004411f4b0d010240024020032001460d002001417f460d08200141016a220520034d0d01200141016a200341c0fdcb001058000b200220033602d48104200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241306a41086a200241e0006a41086a28020036020020022002290360370330410521090c030b200b20016a2d0000220a41ff00712004411f71742008722108200441076a210420052101200a418001710d000b200220053602d48104024020044120490d00410d2109200a410f4b0d020b4100210a200241003602c08104200242043703b8810420080d02410421040c080b200220013602d48104410f21090b200241c0006a41086a200241306a41086a280200220136020020022002290330220d3703400c010b2008417f6a21084104210402400240034020032005460d01200541016a22012005490d0620032001490d07200b20056a2c00002103200220013602d48104410021090240200341004e0d00411921060c030b410721060240200341c000710d000c030b200341807f7222034170470d02200241b8016a200241c881046a10b00720022802bc012101024020022802b8014101470d00200141ff0171210620014180807c7121092001410876210320022903c001220d422088a7210b200241c8016a2802002101200da721050c030b20022903c001210d0240200a20022802bc8104470d00200241b881046a200a410110870120022802b88104210420022802c08104210a0b2004200a410c6c6a2203200d370204200320013602002002200a41016a220a3602c081042008450d082008417f6a210820022802d48104210520022802d08104210320022802c88104210b0c000b0b200241013a00a801200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241a8016a360228200241e0006a200241b8016a1041200228026021052002280264210b2002280268210141002109410521060b200bad4220862005ad84210d2009200341ff017141087472200672210920022802bc81042203450d002003410c6c450d00200410350b200d422088210e20094108762103024020022802cc81040d002009210b0c060b20022802c8810410352009210b0c050b200d422088210e200b41087621030c040b417f200141016a41c0fdcb001059000b417f200141c0fdcb001059000b2001200341c0fdcb001058000b20022802d4810420022802d8810446210120022902bc81042123024020022802cc8104450d0020022802c8810410350b024020010d0020024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360220d422088210e200228026821014105210b410021032023a72205450d012005410c6c450d01200410350c010b410521030c060b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200b41ff0171723602040c0c0b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b024002400240024002400240024002400240024020022802b8014101460d00200241cc016a280200210c200d422088a72103200da721074100210441002108034002402004411f4d0d00410f21090c090b20032001460d072001417f460d03200141016a220520034b0d05200b20016a2d0000220a41ff00712004411f71742008722108200441076a210420052101200a418001710d000b024020044120490d00410d2109200a410f4b0d080b410021122002410036026820024204370360410421040240024002402008450d00410021160340201641016a21164100210a200521014100210903400240200a411f4d0d00410f21090c050b20032001460d032001417f460d08200141016a220520034b0d0a200b20016a2d0000220641ff0071200a411f71742009722109200a41076a210a200521012006418001710d000b0240200a4120490d002006410f4d0d00410d21090c040b20024198016a41086a200241c0006a41086a2802003602002002200229034037039801024020122002280264470d00200241e0006a2012410110860120022802602104200228026821120b200420124102746a20093602002002201241016a221236026820162008470d000b0b2005200c4621012002290264212302402007450d00200b10350b2001450d03410421030c100b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241c881046a200241b8016a1041200241306a41086a200241c881046a41086a280200360200200220022903c88104370330410521090b200241386a28020021012002290330210d200228026441ffffffff0371450d08200410350c080b200d422088210e200b41087621030c080b20024103410220011b3a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a104120022903c88104220d422088210e20022802d0810421014105210b41002103202342ffffffff0383500d07200410350c070b417f200141016a41c0fdcb001059000b417f200141016a41c0fdcb001059000b200141016a200341c0fdcb001058000b200141016a200341c0fdcb001058000b200241013a00c88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241c881046a36022820024188016a200241b8016a1041410521090b200241b881046a41086a20024188016a41086a28020022013602002002200229038801220d3703b881040b200d422088210e41002103024020070d002009210b0c010b200b10352009210b0b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200b41ff0171723602040c0b0b200241b8016a200110c707200241c8016a2802002101200241b8016a41086a290300210d20022802bc01210b024002400240024002400240024020022802b8014101460d002002200241cc016a2802003602d88104200220013602d481042002200b3602c881042002200d3702cc8104200d422088a7210a4100210441002108024002400240024002400240034002402004411f4d0d00410f210b0c030b200a2001460d012001417f460d06200141016a2205200a4b0d05200b20016a2d00002103200220053602d48104200341ff00712004411f71742008722108200441076a2104200521012003418001710d000b024020044120490d00410d210b2003410f4b0d020b200241003602b001200242043703a80120080d02410421040c030b200241013a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a1041200241306a41086a200241e0006a41086a280200360200200220022903603703304105210b0b200241c0006a41086a200241306a41086a280200220136020020022002290330220d3703400c090b20022802ac01210620022802b001210c410021150340200241b8016a200241c881046a10ad0720022802c401211420022802c001211320022802bc01210b024002400240024002400240024002400240024002400240024002400240024002400240024020022802b8014101460d00200241b8016a200241c881046a10ad0720022802c401211020022802c001211820022802bc012116024002400240024020022802b8014101460d000240024002400240024020022802d08104220320022802d481042205460d00200541016a22012005490d0a20032001490d0b20022802c88104220720056a2d00002104200220013602d481040240200441034d0d00410921090c230b20040e0401020304010b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c200b410021124100210441002109034002402004411f4d0d00410f2109410021040c080b20032001460d062001417f460d0b2003200141016a220a490d12200720016a2d000021052002200a3602d48104200541ff00712004411f71742009722109200441076a2104200a21012005418001710d000b4100211220044120490d172005410f4d0d17410d2109410021040c060b0240024020032001460d00200541026a21042001417f460d0c20032004490d0d200720016a2c00002101200220043602d4810402402001417f4a0d00411921030c160b200141c00071450d14200141807f7222014170470d14200241b8016a200241c881046a10b00720022903c001210d20022802bc01210920022802b8014101470d0120022802c80121040c160b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10412002290360210d20022802682104410521030c140b410121120c180b200241b8016a200241c881046a10b00720022903c001210d20022802bc012109024020022802b8014101460d00410221120c180b200220022802c8013602c0012009411876210320094110762112200941087621040c140b0240024020032001460d00200541026a210a2001417f460d0c2003200a490d0d200720016a2c000021042002200a3602d481040240200441004e0d0041192109410021030c200b200441c000710d010c110b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a1041410521092002290264210e20022802602101410021030c1e0b200441807f72220441ff017141fb014d0d0f02402003200a460d00200541036a2101200a417f460d0d20032001490d0e2007200a6a2d00002105200220013602d481040240200541014d0d00410c2109200521040c1f0b2004417f73210a410321124100210320050e021702170b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a10410c1c0b200220022802c80122013602c08104200220103602bc8104200220183602b881042016411876210320164110762112201641087621040c1d0b410121030c130b200241013a009801200241013602cc01200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c801200220024198016a360228200241e0006a200241b8016a1041200228026021012002290264210e41052109410021040b410021030c190b20022802c8012101200220143602bc8104200220133602b88104200220063602ac012002200c3602b0010c1a0b417f200141c0fdcb001059000b2001200341c0fdcb001058000b417f200141016a41c0fdcb001059000b417f200441c0fdcb001059000b2004200341c0fdcb001058000b417f200a41c0fdcb001059000b200a200341c0fdcb001058000b417f200141c0fdcb001059000b2001200341c0fdcb001058000b200141016a200341c0fdcb001058000b410621090c0d0b410721030b200141ff017141087420037221090b200220043602c0012009411876210320094110762112200941087621040b2002200d3703b80120022902bc01210e200da721010c090b0b0b200220143602bc8104200220133602b8810420022903b88104210e02400240200c2006460d0020062105200c21060c010b200641016a22012006490d11200641017422042001200420014b1bad42287e2223422088a70d112023a722014100480d1102400240024020060d0020010d01410421040c020b20022802a8012104200641286c22052001460d01024020050d0020010d01410421040c020b20042005200110372204450d170c010b200110332204450d160b200220043602a801200141286e21050b20022802a8012204200641286c6a220120123a00182001201636020c2001200e3702042001200b360200200141206a200d3702002001411c6a20093602002001411a6a20033a0000200141196a200a3a0000200141146a2010360200200141106a2018360200200641016a210c20052106201541016a22152008470d000b200220053602ac012002200c3602b0010b20022802d4810420022802d8810446210120022902ac012123024020022802cc8104450d0020022802c8810410350b024020010d002023a7210820024103410220011b3a00b88104200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241b881046a360228200241e0006a200241b8016a10412002290360210d2002280268210102402023422088a72203450d00200341286c21052004210303400240200341046a280200450d00200328020010350b0240200341106a280200450d002003410c6a28020010350b200341286a2103200541586a22050d000b0b200d422088210e4105210b410021032008450d09200841286c450d09200410350c090b410321030c0c0b200141016a200a41c0fdcb001058000b417f200141016a41c0fdcb001059000b200d422088210e200b41087621030c050b200228026021012002290264210e410521090b200220013602b881042002200e3702bc8104200e422088a72101024020180d00200921160c010b20161035200921160b02402013450d00200b10350b2002200c3602b001200220063602ac012003411874201241ff017141107472200441ff017141087472201641ff017172210b0b20022903b88104210d20022802a80121050240200c450d00200c41286c21032005210403400240200441046a280200450d00200428020010350b0240200441106a280200450d002004410c6a28020010350b200441286a2104200341586a22030d000b0b2006450d00200641286c450d00200510350b200d422088210e200b410876210320022802cc8104450d0020022802c8810410350b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200b41ff0171723602040c0a0b200a41087621030b20004101360200200041106a2001360200200041086a200e422086200d42ffffffff0f838437020020002003410874200a41ff0171723602040c080b4100210141002104024002400240024002400240024002400340024020084105470d00410f21070c030b20032008460d01200320084d0d04200620086a2d0000220541ff00712001411f71742004722104200141076a2101200841016a220a21082005418001710d000b024020014120490d002005410f4d0d00410d21070c020b20040d024101211641002107410021054100210b0c070b200241013a0060200241cc016a4101360200200242013702bc01200241acfdcb003602b8012002413636022c2002200241286a3602c8012002200241e0006a360228200241c881046a200241b8016a1041200241306a41086a200241c881046a41086a280200360200200220022903c88104220d370330410521070b200d422088a7210520022802382101200da7210b0c030b200241b8016a4100418008109f081a4100210541002108410121164100210702400240024003402003200a6b200420076b22014180082001418008491b2201490d01200a20016a220c200a490d022003200c490d03200241b8016a2006200a6a2001109d081a02400240200820056b2001490d002008210b0c010b200520016a220a2005490d0c2008410174220b200a200b200a4b1b220b4100480d0c0240024020080d000240200b0d00410121160c020b200b103322160d010c120b2008200b460d0020162008200b10372216450d110b200b21080b201620056a200241b8016a2001109d081a200520016a2105200c210a2004200120076a22074d0d050c000b0b200241013a00b88104200241dc81046a4101360200200242013702cc8104200241acfdcb003602c881042002413636022c2002200241286a3602d881042002200241b881046a360228200241e0006a200241c881046a10412002290360220d422088a7210520022802682101200da7210b410521072008450d04201610350c040b200a200c41c0fdcb001059000b200c200341c0fdcb001058000b200841016a200341c0fdcb001058000b200241b8016a20162005107420022802b8014101470d01410821070240200b450d00201610350b0b2005ad422086200bad84210d2009450d03200610350c030b201641807e712107200c210a0b2003200a490d052003200a6b2203417f4c0d030240024020030d0041002104410121010c010b200310332201450d05200321040b0240024020042003490d00200421080c010b200441017422082003200820034b1b22084100480d03024020040d00200810332201450d080c010b20042008460d0020012004200810372201450d070b2007201641ff01717221042005ad422086200bad84212320012006200a6a2003109d081a2003ad4220862008ad84210d410121032009450d00200610350b200020033a000420004100360200200041056a20022f00153b0000200041186a200d370200200041146a20013602002000410c6a2023370200200041086a2004360200200041206a2002290200370200200041076a200241176a2d00003a0000200041286a200241086a290200370200200041306a200241106a2802003602000c060b2000200736020420004101360200200041106a2001360200200041086a200d3702000c050b103e000b1044000b1045000b200a20034188d9cb001059000b103c000b200241e081046a24000bdc0101057f024020002802082201450d00200028020022022001411c6c6a21030340024020022802042200450d0002402002410c6a2802002201450d00200141047421010340024020002d00004109470d000240200041046a2204280200220528020441ffffffff0371450d0020052802001035200428020021050b200510350b200041106a2100200141706a22010d000b0b200241086a28020041ffffffff0071450d00200228020410350b2002411c6a21000240200241146a28020041ffffffff0371450d00200228021010350b2000210220002003470d000b0b0bd90101057f024020002802082201450d0020002802002202200141186c6a210303400240200241046a28020041ffffffff0171450d00200228020010350b0240200241146a2802002201450d00200228020c2100200141047421010340024020002d00004109470d000240200041046a2204280200220528020441ffffffff0371450d0020052802001035200428020021050b200510350b200041106a2100200141706a22010d000b0b200241186a21000240200241106a28020041ffffffff0071450d00200228020c10350b2000210220002003470d000b0b0bd50101057f024020002802082201450d00200028020022022001411c6c6a21030340024020022802042200450d0002402002410c6a2802002201450d00200141047421010340024020002d00004109470d000240200041046a2204280200220528020441ffffffff0371450d0020052802001035200428020021050b200510350b200041106a2100200141706a22010d000b0b200241086a28020041ffffffff0071450d00200228020410350b2002411c6a21000240200241146a280200450d00200228021010350b2000210220002003470d000b0b0be40101047f0240200041206a28020022032000411c6a280200470d000240024002400240200341016a22042003490d00200341017422052004200520044b1b220620066a22042006490d0020044100480d00024020030d0020040d02410121030c040b2000280218210320052004460d03024020050d0020040d02410121030c040b20032005200410372203450d020c030b103e000b2004103322030d010b103c000b200020033602182000411c6a2004410176360200200028022021030b200028021820034101746a220320023a0001200320013a00002000200028022041016a3602200be70101037f0240200041386a2802002202200041346a280200470d000240024002400240200241016a22032002490d00200241017422042003200420034b1b220341ffffffff03712003470d00200341027422034100480d00024020020d0020030d02410421040c040b20002802302104200241027422022003460d03024020020d0020030d02410421040c040b20042002200310372204450d020c030b103e000b2003103322040d010b103c000b20002004360230200041346a2003410276360200200028023821020b200028023020024102746a20013602002000200028023841016a3602380b8d0302037f017e230041c0006b22022400200141086a28020021032001280204210420022001280200220136020002400240024002402001418080044b0d002004450d022002200336020402400240200120034b0d002003418080044d0d042002413c6a41013602002002420237022c200241e0aacc003602282002410136020c200241bcaacc003602082002200241086a360238200241186a200241286a1041200241186a21010c010b2002413c6a4102360200200241246a41013602002002420237022c200241d0aacc003602282002410136021c2002200241186a360238200220023602202002200241046a360218200241086a200241286a1041200241086a21010b20012902042105200128020021010c010b2002413c6a41013602002002420237022c200241c0aacc003602282002410136020c200241bcaacc003602082002200241086a360238200241186a200241286a104120022802182101200229021c21050b2001450d0020002005370204200020013602000c010b200041003602000b200241c0006a24000be00501037f230041f0006b2204240002400240024020012802084102460d00412e10332201450d01200041013a0000200141266a41002900d4ac4c370000200141206a41002900ceac4c370000200141186a41002900c6ac4c370000200141106a41002900beac4c370000200141086a41002900b6ac4c370000200141002900aeac4c370000200041086a42ae808080e005370200200041046a20013602000c020b0240024002400240024002400240200128020022052d0000416e6a2201411e4b0d004100210620010e1f03000000000000000000000000000000000000000000000000000006040102030b412010332201450d06200041013a0000200141186a41002900f4ac4c370000200141106a41002900ecac4c370000200141086a41002900e4ac4c370000200141002900dcac4c370000200041086a42a08080808004370200200041046a20013602000c070b410221060c040b410321060c030b20042005280204220136020c0240024020012003490d0041fcaccc002105200441e8006a2103200441d0006a2101200441c0006a21020c010b200220014101746a22012d0001450d02418cadcc002105200441386a2103200441206a2101200441106a21020b20034101360204200141146a410136020020012003360210200142023702042001200536020020032004410c6a360200200220011041200041013a00002000410c6a200241086a280200360200200041046a20022902003702000c040b410121060c010b20012d000021060b0240200541106a2d00004106470d00200041003a0000200020063a00010c020b412910332201450d00200041013a0000200141286a41002d00c4ad4c3a0000200141206a41002900bcad4c370000200141186a41002900b4ad4c370000200141106a41002900acad4c370000200141086a41002900a4ad4c3700002001410029009cad4c370000200041086a42a98080809005370200200041046a20013602000c010b1045000b200441f0006a24000b8f0201017f230041106b220224000240024002400240024020002d00000e0401020300010b200220012802184180fdcb0041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c030b200220012802184183fdcb0041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c020b200220012802184186fdcb0041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b200220012802184189fdcb0041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040b200241106a240020000bbb0101027f0240200041046a2802002001470d000240024002400240200141016a22022001490d00200141017422032002200320024b1b220241ffffffff01712002470d00200241037422024100480d00024020010d0020020d02410421030c040b20002802002103200141037422012002460d03024020010d0020020d02410421030c040b20032001200210372203450d020c030b103e000b2002103322030d010b103c000b20002003360200200041046a20024103763602000b0bbbcb0203047f017e057f230041a0016b2203240002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020022d00000eac0101cc0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa0100010b20034188016a200141186a2204200141286a410110f207024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dcb01200241017422062005200620054b1b22054100480dcb010240024020020d002005103322040d010cd2010b2004280200210420022005460d0020042002200510372204450dd1010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000ccd010b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450dcc012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dcc010ccb010b200328028c012201450dcb0120034190016a29030021070cca010b200141306a2802002202450da90102400240200241037420012802286a41786a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220820026b200420026b2209490d002001280218210a200221010c010b200220096a220a2002490dc9012008410174220b200a200b200a4b1b220b4100480dc9010240024020080d000240200b0d004101210a0c020b200b1033220a450dd0010c010b2001280218210a2008200b460d00200a2008200b1037220a450dcf010b2001200a3602182001411c6a200b360200200141206a28020021010b200a20016a21080240024020094102490d002008410420042002417f736a2202109f081a200a200220016a22016a21080c010b2009450d010b200841043a0000200141016a21010b20062001360200200541013a00060cca010b0240200141306a2802002204200141346a22052802004f0d002002310001422886200141206a350200842107024020042001412c6a280200470d00200141286a200410ba07200141306a28020021040b200128022820044103746a2007370200200141306a2201200128020041016a3602000cca010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc9012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dc90120002007370204200020013602000cca010b0240200141306a2802002204200141346a22052802004f0d002002310001422886200141206a35020084428080808030842107024020042001412c6a280200470d00200141286a200410ba07200141306a28020021040b200128022820044103746a2007370200200141306a2201200128020041016a3602000cc9010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc8012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dc80120002007370204200020013602000cc9010b2002310001210720034188016a200141186a200141286a2204410010f20720032d0088014101460da7010240200141306a2802002202200141346a22052802004f0d002007422886200141206a35020084428080808010842107024020022001412c6a280200470d002004200210ba07200141306a28020021020b200128022820024103746a2007370200200141306a2201200128020041016a3602000cc8010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc7012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dc70120002007370204200020013602000cc8010b200141306a2802002202450da70102400240200141286a22042802002002417f6a4103746a22022d00044101470d002002310005210720034188016a200141186a200410f307200328028801450d012000200329038801370200200041086a20034188016a41086a2802003602000cc9010b411a10332201450da901200141186a41002f00b0a54c3b0000200141106a41002900a8a54c370000200141086a41002900a0a54c37000020014100290098a54c3700002000429a808080a003370204200020013602000cc8010b0240200141306a2802002202200141346a22052802004f0d002007422886200141206a35020084428080808020842107024020022001412c6a280200470d002004200210ba07200141306a28020021020b200128022820024103746a2007370200200141306a2201200128020041016a3602000cc7010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc6012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dc60120002007370204200020013602000cc7010b200141306a2802002202450da8012002410374200141286a22062802006a2204417d6a220a2d0000210502402004417c6a2d00004101470d00200541ff01714104470daa010b02400240024002400240024020024101460d0020034188016a200141186a2202200610f3072003280288010d01200541ff01714104460dcb01200141206a2802002204200141246a22062802004f0d0520042001411c6a280200470d04200441016a22062004490dc8012004410174220a2006200a20064b1b22064100480dc80120040d02200610332202450dcd010c030b024020012d003822024104460d0020034188016a200141186a2006200210f407200328028801450d002000200329038801370200200041086a20034188016a41086a2802003602000ccc010b20034188016a200141186a200610f307200328028801450dca012000200329038801370200200041086a20034188016a41086a2802003602000ccb010b2000200329038801370200200041086a20034188016a41086a2802003602000cca010b2002280200210220042006460d0020022004200610372202450dca010b200120023602182001411c6a2006360200200141206a28020021040b200128021820046a20053a0000200141206a2201200128020041016a3602000cc6010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320063602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc5012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450dc50120002007370204200020013602000cc6010b2003200241046a2802002202360278024002400240200141306a280200220420024d0d0020042002417f736a220220044f0dac01200141286a220428020020024103746a22022d00044103460d0220022d0005220241ff01714104460d0220034188016a200141186a2004200210f4072003280288012202450d02200329028c0121070c010b2003419c016a22024102360200200341cc006a41013602002003420237028c0120034198b0cc003602880120034101360244200320043602302003200341c0006a360298012003200341306a3602482003200341f8006a360240200341e8006a20034188016a1041200328026821042003200329026c37026c20032004360268200241013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402102200329024421070240200328026c450d00200328026810350b2002450d010b20002007370204200020023602000cc6010b200141306a2802002202450daa0102400240200241037420012802286a41786a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220820026b200420026b2209490d002001280218210a200221010c010b200220096a220a2002490dc3012008410174220b200a200b200a4b1b220b4100480dc3010240024020080d000240200b0d004101210a0c020b200b1033220a450dca010c010b2001280218210a2008200b460d00200a2008200b1037220a450dc9010b2001200a3602182001411c6a200b360200200141206a28020021010b200a20016a21080240024020094102490d002008410420042002417f736a2202109f081a200a200220016a22016a21080c010b2009450d010b200841043a0000200141016a21010b20062001360200200541013a00060cc4010b200241046a280200210220034188016a200141186a2205200141286a2204410010f20702400240024020032d0088014101460d00200141306a2802002101200320023602780240200120024d0d0020012002417f736a220220014f0db401200428020020024103746a22012d00044103460dc70120012d0005220141ff01714104460dc70120034188016a20052004200110f4072003280288012201450dc701200329028c0121070c030b2003419c016a22024102360200200341cc006a41013602002003420237028c0120034198b0cc003602880120034101360244200320013602302003200341c0006a360298012003200341306a3602482003200341f8006a360240200341e8006a20034188016a1041200328026821012003200329026c37026c20032001360268200241013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a10412003280240210120032902442107200328026c450d01200328026810350c010b20034190016a2903002107200328028c0121010b2001450dc4010b20002007370204200020013602000cc4010b200241046a2802002202280204210620022802002104200320022802082205360278200141306a280200220220054d0dbd0120022005417f736a220520024f0da901410421080240200141286a220c280200220a20054103746a22052d00044103460d0020052d000521080b200320083a00602006450db701200841ff0171220b4104460db601200641027421060340200320042802002205360278200220054d0db90120022005417f736a220520024f0dc101200a20054103746a22052d00044103460dba0120052d000522094104460dba01200b2009470dba01200441046a21042006417c6a22060d000cb8010b0b024020012d003822024104460d0020034188016a200141186a200141286a200210f407200328028801450d002000200329038801370200200041086a20034188016a41086a2802003602000cc3010b200141306a2802002202450da90102400240200241037420012802286a41786a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220820026b200420026b2209490d002001280218210a200221010c010b200220096a220a2002490dc0012008410174220b200a200b200a4b1b220b4100480dc0010240024020080d000240200b0d004101210a0c020b200b1033220a450dc7010c010b2001280218210a2008200b460d00200a2008200b1037220a450dc6010b2001200a3602182001411c6a200b360200200141206a28020021010b200a20016a21080240024020094102490d002008410420042002417f736a2202109f081a200a200220016a22016a21080c010b2009450d010b200841043a0000200141016a21010b20062001360200200541013a00060cc1010b200128020021042003200241046a280200220236028401024002400240024002400240024002400240200441386a28020020024d0d002003200428023020024102746a2802002202360230024002402004412c6a28020020024d0d00200341cc006a200428022420024104746a22042d000d220a3a0000200341c8006a2004280208220236020020042802002104410021050c010b410121052003419c016a41013602002003420237028c01200341f0aecc00360288012003410136027c2003200341f8006a360298012003200341306a360278200341e8006a20034188016a1041200341c8006a200329026c22073703002007422088a7210a200328026821042007a721020b200320053602402003200436024420050d0102402002450d002004417f6a2104200141286a2105200141186a2106034020034188016a20062005200420026a2d000010f20720032d0088014101460d082002417f6a22020d000b0b200a41ff01714104460dc901200141206a2802002202200141246a22042802004f0d0520022001411c6a280200470d04200241016a22042002490dc601200241017422052004200520044b1b22044100480dc60120020d02200410332205450dcb010c030b2003419c016a41013602002003420237028c01200341ccaecc0036028801200341013602642003200341e0006a36029801200320034184016a360260200341e8006a20034188016a1041200341c8006a200329026c370300200341013602402003200328026822043602440b200341c8006a21010c050b2001280218210520022004460d0020052002200410372205450dc8010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a200a3a0000200141206a2201200128020041016a3602000cc4010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450dc3012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402104200329024421070240200328026c450d00200328026810350b20040d020cc3010b20034190016a2101200328028c0121040b2004450dc101200129020021070b20002007370204200020043602000cc1010b200241046a28020021062001280200210220034100360268200241146a280200450da80120034188016a200141186a2204200141286a2205410010f20720032d0088014101460da9012001280200220a412c6a28020021022003200636026802400240024002400240200220064d0d00200a28022420064104746a22062d000d210a024020062802082202450d002006280200417f6a2106034020034188016a20042005200620026a2d000010f20720032d0088014101460db1012002417f6a22020d000b0b200a41ff01714104460dc401200141206a2802002202200141246a22052802004f0d0420022001411c6a280200470d03200241016a22052002490dc101200241017422062005200620054b1b22054100480dc10120020d01200510332204450dc6010c020b2003419c016a41013602002003420237028c01200341f0aecc0036028801200341013602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a10410cb5010b2004280200210420022005460d0020042002200510372204450dc4010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a200a3a0000200141206a2201200128020041016a3602000cc0010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dbf012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a10412003280240210120032902442107200328026c450db201200328026810350cb2010b20034188016a200141186a200141286a410410f20720032d0088014101470dbe01200328028c012201450dbe01200020034190016a290300370204200020013602000cbf010b20034188016a200141186a2204200141286a2205410010f20720034188016a21020240024020032d0088014101460d0020034188016a20042005410410f20720034188016a210220032d0088014101460d0020034188016a2004200520032d008901220610f20720034188016a210220032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490dbe012002410174220a2005200a20054b1b22054100480dbe010240024020020d00200510332204450dc5010c010b2004280200210420022005460d0020042002200510372204450dc4010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a20063a0000200141206a2201200128020041016a3602000cc0010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450dbf012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010cbf010b200241046a2802002201450dbe01200241086a29020021070b20002007370204200020013602000cbe010b20034188016a200141046a200241046a28020010f5070240024020032d0088014101460d000240200141206a2802002202200141246a22042802004f0d0020032d0089012104024020022001411c6a280200470d00200241016a22052002490dbd01200241017422062005200620054b1b22054100480dbd010240024020020d00200510332206450dc4010c010b2001280218210620022005460d0020062002200510372206450dc3010b200120063602182001411c6a2005360200200141206a28020021020b200128021820026a20043a0000200141206a2201200128020041016a3602000cbf010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450dbe012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010cbe010b200328028c012201450dbd0120034190016a29030021070b20002007370204200020013602000cbd010b2003200241046a280200220236023020034188016a200141046a200210f5070240024020032d0088014101460d00200320032d00890122023a006020034188016a200141186a200141286a410410f2070240024020032d0088014101460d00200320032d00890122013a007820014104460dbf01200241ff01712001460dbf01200341c0006a41146a413d360200200341cc006a413736020020034188016a41146a41033602002003420337028c01200341d4a5cc0036028801200341013602442003200341c0006a360298012003200341f8006a3602502003200341e0006a3602482003200341306a360240200341e8006a20034188016a10410c010b200341f0006a20034194016a2802003602002003200329028c013703680b200329026c2107200328026821010c010b2003200328028c012201360268200320034190016a290300220737026c0b2001450dbb0120002007370204200020013602000cbc010b20034188016a200141046a200241046a28020010f5070240024020032d0088014101460d0020034188016a200141186a200141286a20032d00890110f4072003280288012201450dbc01200329028c0121070c010b200328028c012201450dbb0120034190016a29030021070b20002007370204200020013602000cbb010b200128020021042003200241046a280200220236026802400240200441206a28020020024d0d000240200141206a2802002205200141246a22062802004f0d00200428021820024101746a2d00002102024020052001411c6a280200470d00200541016a22042005490dba01200541017422062004200620044b1b22044100480dba010240024020050d00200410332206450dc1010c010b2001280218210620052004460d0020062005200410372206450dc0010b200120063602182001411c6a2004360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000cbc010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320063602302003200341306a36029801200341c0006a20034188016a104120032802402202450dbb012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010cbb010b2003419c016a41013602002003420237028c0120034190afcc00360288012003410136027c2003200341f8006a360298012003200341e8006a360278200341c0006a20034188016a104120032802402201450dba01200329024421070b20002007370204200020013602000cba010b2003200241046a2802002202360258200128020021042003200236028401024002400240200441206a28020020024d0d00200428021820024101746a22022d00010d022003419c016a41013602002003420237028c01200341a0afcc0036028801200341013602342003200341306a36029801200320034184016a360230200341c0006a20034188016a10410c010b2003419c016a41013602002003420237028c0120034190afcc00360288012003410136027c2003200341f8006a36029801200320034184016a360278200341c0006a20034188016a10410b2003280240210120032003290244220737026c200320013602680caa010b200320022d000022023a005f20034188016a200141186a200141286a410410f20720032d0088014101470da701200341f0006a20034194016a2802003602002003200329028c013703680ca8010b20034188016a2001200241046a2802004104410010f707200328028801450db7012000200329038801370200200041086a20034188016a41086a2802003602000cb8010b20034188016a2001200241046a2802004108410110f707200328028801450db6012000200329038801370200200041086a20034188016a41086a2802003602000cb7010b20034188016a2001200241046a2802004104410210f707200328028801450db5012000200329038801370200200041086a20034188016a41086a2802003602000cb6010b20034188016a2001200241046a2802004108410310f707200328028801450db4012000200329038801370200200041086a20034188016a41086a2802003602000cb5010b20034188016a2001200241046a2802004101410010f707200328028801450db3012000200329038801370200200041086a20034188016a41086a2802003602000cb4010b20034188016a2001200241046a2802004101410010f707200328028801450db2012000200329038801370200200041086a20034188016a41086a2802003602000cb3010b20034188016a2001200241046a2802004102410010f707200328028801450db1012000200329038801370200200041086a20034188016a41086a2802003602000cb2010b20034188016a2001200241046a2802004102410010f707200328028801450db0012000200329038801370200200041086a20034188016a41086a2802003602000cb1010b20034188016a2001200241046a2802004101410110f707200328028801450daf012000200329038801370200200041086a20034188016a41086a2802003602000cb0010b20034188016a2001200241046a2802004101410110f707200328028801450dae012000200329038801370200200041086a20034188016a41086a2802003602000caf010b20034188016a2001200241046a2802004102410110f707200328028801450dad012000200329038801370200200041086a20034188016a41086a2802003602000cae010b20034188016a2001200241046a2802004102410110f707200328028801450dac012000200329038801370200200041086a20034188016a41086a2802003602000cad010b20034188016a2001200241046a2802004104410110f707200328028801450dab012000200329038801370200200041086a20034188016a41086a2802003602000cac010b20034188016a2001200241046a2802004104410110f707200328028801450daa012000200329038801370200200041086a20034188016a41086a2802003602000cab010b20034188016a2001200241046a2802004104410010f807200328028801450da9012000200329038801370200200041086a20034188016a41086a2802003602000caa010b20034188016a2001200241046a2802004108410110f807200328028801450da8012000200329038801370200200041086a20034188016a41086a2802003602000ca9010b20034188016a2001200241046a2802004104410210f807200328028801450da7012000200329038801370200200041086a20034188016a41086a2802003602000ca8010b20034188016a2001200241046a2802004108410310f807200328028801450da6012000200329038801370200200041086a20034188016a41086a2802003602000ca7010b20034188016a2001200241046a2802004101410010f807200328028801450da5012000200329038801370200200041086a20034188016a41086a2802003602000ca6010b20034188016a2001200241046a2802004102410010f807200328028801450da4012000200329038801370200200041086a20034188016a41086a2802003602000ca5010b20034188016a2001200241046a2802004101410110f807200328028801450da3012000200329038801370200200041086a20034188016a41086a2802003602000ca4010b20034188016a2001200241046a2802004102410110f807200328028801450da2012000200329038801370200200041086a20034188016a41086a2802003602000ca3010b20034188016a2001200241046a2802004104410110f807200328028801450da1012000200329038801370200200041086a20034188016a41086a2802003602000ca2010b20012802002102200341003602680240024020022802080d002003419c016a41013602002003420237028c01200341fcadcc0036028801200341013602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402202450d00200329024421070c010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490da001200241017422052004200520044b1b22044100480da0010240024020020d00200410332205450da7010c010b2001280218210520022004460d0020052002200410372205450da6010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000ca2010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450da1012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402102200329024421070240200328026c450d00200328026810350b2002450da1010b20002007370204200020023602000ca1010b20012802002102200341003602680240024020022802080d002003419c016a41013602002003420237028c01200341fcadcc0036028801200341013602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402202450d00200329024421070c010b20034188016a200141186a2204200141286a410010f207024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490da001200241017422062005200620054b1b22054100480da0010240024020020d00200510332204450da7010c010b2004280200210420022005460d0020042002200510372204450da6010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000ca2010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320053602302003200341306a36029801200341c0006a20034188016a104120032802402202450da1012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402102200329024421070240200328026c450d00200328026810350b20020d010ca1010b200328028c012202450da00120034190016a29030021070b20002007370204200020023602000ca0010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490d9d01200241017422052004200520044b1b22044100480d9d010240024020020d00200410332205450da4010c010b2001280218210520022004460d0020052002200410372205450da3010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c9f010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450d9e012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450d9e0120002007370204200020013602000c9f010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490d9c01200241017422052004200520044b1b22044100480d9c010240024020020d00200410332205450da3010c010b2001280218210520022004460d0020052002200410372205450da2010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c9e010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450d9d012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450d9d0120002007370204200020013602000c9e010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490d9b01200241017422052004200520044b1b22044100480d9b010240024020020d00200410332205450da2010c010b2001280218210520022004460d0020052002200410372205450da1010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c9d010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450d9c012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450d9c0120002007370204200020013602000c9d010b0240200141206a2802002202200141246a22042802004f0d00024020022001411c6a280200470d00200241016a22042002490d9a01200241017422052004200520044b1b22044100480d9a010240024020020d00200410332205450da1010c010b2001280218210520022004460d0020052002200410372205450da0010b200120053602182001411c6a2004360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c9c010b2003419c016a220141013602002003420137028c01200341e8b1cc003602880120034101360234200320043602302003200341306a36029801200341c0006a20034188016a104120032802402202450d9b012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b2001450d9b0120002007370204200020013602000c9c010b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d9b01200241017422062005200620054b1b22054100480d9b010240024020020d00200510332204450da2010c010b2004280200210420022005460d0020042002200510372204450da1010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c9d010b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d9c012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c9c010b200328028c012201450d9b0120034190016a29030021070b20002007370204200020013602000c9b010b20034188016a2001410010f907200328028801450d99012000200329038801370200200041086a20034188016a41086a2802003602000c9a010b20034188016a2001410010f907200328028801450d98012000200329038801370200200041086a20034188016a41086a2802003602000c99010b20034188016a2001410010f907200328028801450d97012000200329038801370200200041086a20034188016a41086a2802003602000c98010b20034188016a2001410010f907200328028801450d96012000200329038801370200200041086a20034188016a41086a2802003602000c97010b20034188016a2001410010f907200328028801450d95012000200329038801370200200041086a20034188016a41086a2802003602000c96010b20034188016a2001410010f907200328028801450d94012000200329038801370200200041086a20034188016a41086a2802003602000c95010b20034188016a2001410010f907200328028801450d93012000200329038801370200200041086a20034188016a41086a2802003602000c94010b20034188016a2001410010f907200328028801450d92012000200329038801370200200041086a20034188016a41086a2802003602000c93010b20034188016a2001410010f907200328028801450d91012000200329038801370200200041086a20034188016a41086a2802003602000c92010b20034188016a2001410010f907200328028801450d90012000200329038801370200200041086a20034188016a41086a2802003602000c91010b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d9001200241017422062005200620054b1b22054100480d90010240024020020d00200510332204450d97010c010b2004280200210420022005460d0020042002200510372204450d96010b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c92010b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d91012003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c91010b200328028c012201450d900120034190016a29030021070b20002007370204200020013602000c90010b20034188016a2001410110f907200328028801450d8e012000200329038801370200200041086a20034188016a41086a2802003602000c8f010b20034188016a2001410110f907200328028801450d8d012000200329038801370200200041086a20034188016a41086a2802003602000c8e010b20034188016a2001410110f907200328028801450d8c012000200329038801370200200041086a20034188016a41086a2802003602000c8d010b20034188016a2001410110f907200328028801450d8b012000200329038801370200200041086a20034188016a41086a2802003602000c8c010b20034188016a2001410110f907200328028801450d8a012000200329038801370200200041086a20034188016a41086a2802003602000c8b010b20034188016a2001410110f907200328028801450d89012000200329038801370200200041086a20034188016a41086a2802003602000c8a010b20034188016a2001410110f907200328028801450d88012000200329038801370200200041086a20034188016a41086a2802003602000c89010b20034188016a2001410110f907200328028801450d87012000200329038801370200200041086a20034188016a41086a2802003602000c88010b20034188016a2001410110f907200328028801450d86012000200329038801370200200041086a20034188016a41086a2802003602000c87010b20034188016a2001410110f907200328028801450d85012000200329038801370200200041086a20034188016a41086a2802003602000c86010b20034188016a2001410210f907200328028801450d84012000200329038801370200200041086a20034188016a41086a2802003602000c85010b20034188016a2001410210f907200328028801450d83012000200329038801370200200041086a20034188016a41086a2802003602000c84010b20034188016a2001410210f907200328028801450d82012000200329038801370200200041086a20034188016a41086a2802003602000c83010b20034188016a2001410210f907200328028801450d81012000200329038801370200200041086a20034188016a41086a2802003602000c82010b20034188016a2001410210f907200328028801450d80012000200329038801370200200041086a20034188016a41086a2802003602000c81010b20034188016a2001410210f907200328028801450d7f2000200329038801370200200041086a20034188016a41086a2802003602000c80010b20034188016a2001410310f907200328028801450d7e2000200329038801370200200041086a20034188016a41086a2802003602000c7f0b20034188016a2001410310f907200328028801450d7d2000200329038801370200200041086a20034188016a41086a2802003602000c7e0b20034188016a2001410310f907200328028801450d7c2000200329038801370200200041086a20034188016a41086a2802003602000c7d0b20034188016a2001410310f907200328028801450d7b2000200329038801370200200041086a20034188016a41086a2802003602000c7c0b20034188016a2001410310f907200328028801450d7a2000200329038801370200200041086a20034188016a41086a2802003602000c7b0b20034188016a2001410310f907200328028801450d792000200329038801370200200041086a20034188016a41086a2802003602000c7a0b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d79200241017422062005200620054b1b22054100480d790240024020020d00200510332204450d80010c010b2004280200210420022005460d0020042002200510372204450d7f0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c7b0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d7a2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c7a0b200328028c012201450d7920034190016a29030021070b20002007370204200020013602000c790b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d78200241017422062005200620054b1b22054100480d780240024020020d00200510332204450d7f0c010b2004280200210420022005460d0020042002200510372204450d7e0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c7a0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d792003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c790b200328028c012201450d7820034190016a29030021070b20002007370204200020013602000c780b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d77200241017422062005200620054b1b22054100480d770240024020020d00200510332204450d7e0c010b2004280200210420022005460d0020042002200510372204450d7d0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c790b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d782003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c780b200328028c012201450d7720034190016a29030021070b20002007370204200020013602000c770b20034188016a2001410010fa07200328028801450d752000200329038801370200200041086a20034188016a41086a2802003602000c760b20034188016a2001410010fa07200328028801450d742000200329038801370200200041086a20034188016a41086a2802003602000c750b20034188016a2001410010fa07200328028801450d732000200329038801370200200041086a20034188016a41086a2802003602000c740b20034188016a2001410010fa07200328028801450d722000200329038801370200200041086a20034188016a41086a2802003602000c730b20034188016a2001410010fa07200328028801450d712000200329038801370200200041086a20034188016a41086a2802003602000c720b20034188016a2001410010fa07200328028801450d702000200329038801370200200041086a20034188016a41086a2802003602000c710b20034188016a2001410010fa07200328028801450d6f2000200329038801370200200041086a20034188016a41086a2802003602000c700b20034188016a2001410010fa07200328028801450d6e2000200329038801370200200041086a20034188016a41086a2802003602000c6f0b20034188016a2001410010fa07200328028801450d6d2000200329038801370200200041086a20034188016a41086a2802003602000c6e0b20034188016a2001410010fa07200328028801450d6c2000200329038801370200200041086a20034188016a41086a2802003602000c6d0b20034188016a2001410010fa07200328028801450d6b2000200329038801370200200041086a20034188016a41086a2802003602000c6c0b20034188016a2001410010fa07200328028801450d6a2000200329038801370200200041086a20034188016a41086a2802003602000c6b0b20034188016a2001410010fa07200328028801450d692000200329038801370200200041086a20034188016a41086a2802003602000c6a0b20034188016a2001410010fa07200328028801450d682000200329038801370200200041086a20034188016a41086a2802003602000c690b20034188016a2001410010fa07200328028801450d672000200329038801370200200041086a20034188016a41086a2802003602000c680b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d67200241017422062005200620054b1b22054100480d670240024020020d00200510332204450d6e0c010b2004280200210420022005460d0020042002200510372204450d6d0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c690b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d682003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c680b200328028c012201450d6720034190016a29030021070b20002007370204200020013602000c670b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d66200241017422062005200620054b1b22054100480d660240024020020d00200510332204450d6d0c010b2004280200210420022005460d0020042002200510372204450d6c0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c680b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d672003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c670b200328028c012201450d6620034190016a29030021070b20002007370204200020013602000c660b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d65200241017422062005200620054b1b22054100480d650240024020020d00200510332204450d6c0c010b2004280200210420022005460d0020042002200510372204450d6b0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c670b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d662003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c660b200328028c012201450d6520034190016a29030021070b20002007370204200020013602000c650b20034188016a2001410110fa07200328028801450d632000200329038801370200200041086a20034188016a41086a2802003602000c640b20034188016a2001410110fa07200328028801450d622000200329038801370200200041086a20034188016a41086a2802003602000c630b20034188016a2001410110fa07200328028801450d612000200329038801370200200041086a20034188016a41086a2802003602000c620b20034188016a2001410110fa07200328028801450d602000200329038801370200200041086a20034188016a41086a2802003602000c610b20034188016a2001410110fa07200328028801450d5f2000200329038801370200200041086a20034188016a41086a2802003602000c600b20034188016a2001410110fa07200328028801450d5e2000200329038801370200200041086a20034188016a41086a2802003602000c5f0b20034188016a2001410110fa07200328028801450d5d2000200329038801370200200041086a20034188016a41086a2802003602000c5e0b20034188016a2001410110fa07200328028801450d5c2000200329038801370200200041086a20034188016a41086a2802003602000c5d0b20034188016a2001410110fa07200328028801450d5b2000200329038801370200200041086a20034188016a41086a2802003602000c5c0b20034188016a2001410110fa07200328028801450d5a2000200329038801370200200041086a20034188016a41086a2802003602000c5b0b20034188016a2001410110fa07200328028801450d592000200329038801370200200041086a20034188016a41086a2802003602000c5a0b20034188016a2001410110fa07200328028801450d582000200329038801370200200041086a20034188016a41086a2802003602000c590b20034188016a2001410110fa07200328028801450d572000200329038801370200200041086a20034188016a41086a2802003602000c580b20034188016a2001410110fa07200328028801450d562000200329038801370200200041086a20034188016a41086a2802003602000c570b20034188016a2001410110fa07200328028801450d552000200329038801370200200041086a20034188016a41086a2802003602000c560b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d55200241017422062005200620054b1b22054100480d550240024020020d00200510332204450d5c0c010b2004280200210420022005460d0020042002200510372204450d5b0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c570b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d562003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c560b200328028c012201450d5520034190016a29030021070b20002007370204200020013602000c550b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d54200241017422062005200620054b1b22054100480d540240024020020d00200510332204450d5b0c010b2004280200210420022005460d0020042002200510372204450d5a0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c560b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d552003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c550b200328028c012201450d5420034190016a29030021070b20002007370204200020013602000c540b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d53200241017422062005200620054b1b22054100480d530240024020020d00200510332204450d5a0c010b2004280200210420022005460d0020042002200510372204450d590b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c550b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d542003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c540b200328028c012201450d5320034190016a29030021070b20002007370204200020013602000c530b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d52200241017422062005200620054b1b22054100480d520240024020020d00200510332204450d590c010b2004280200210420022005460d0020042002200510372204450d580b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c540b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d532003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c530b200328028c012201450d5220034190016a29030021070b20002007370204200020013602000c520b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d51200241017422062005200620054b1b22054100480d510240024020020d00200510332204450d580c010b2004280200210420022005460d0020042002200510372204450d570b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c530b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d522003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c520b200328028c012201450d5120034190016a29030021070b20002007370204200020013602000c510b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d50200241017422062005200620054b1b22054100480d500240024020020d00200510332204450d570c010b2004280200210420022005460d0020042002200510372204450d560b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c520b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d512003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c510b200328028c012201450d5020034190016a29030021070b20002007370204200020013602000c500b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d4f200241017422062005200620054b1b22054100480d4f0240024020020d00200510332204450d560c010b2004280200210420022005460d0020042002200510372204450d550b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c510b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d502003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c500b200328028c012201450d4f20034190016a29030021070b20002007370204200020013602000c4f0b20034188016a2001410210fa07200328028801450d4d2000200329038801370200200041086a20034188016a41086a2802003602000c4e0b20034188016a2001410210fa07200328028801450d4c2000200329038801370200200041086a20034188016a41086a2802003602000c4d0b20034188016a2001410210fa07200328028801450d4b2000200329038801370200200041086a20034188016a41086a2802003602000c4c0b20034188016a2001410210fa07200328028801450d4a2000200329038801370200200041086a20034188016a41086a2802003602000c4b0b20034188016a2001410210fa07200328028801450d492000200329038801370200200041086a20034188016a41086a2802003602000c4a0b20034188016a2001410210fa07200328028801450d482000200329038801370200200041086a20034188016a41086a2802003602000c490b20034188016a2001410210fa07200328028801450d472000200329038801370200200041086a20034188016a41086a2802003602000c480b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d47200241017422062005200620054b1b22054100480d470240024020020d00200510332204450d4e0c010b2004280200210420022005460d0020042002200510372204450d4d0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c490b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d482003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c480b200328028c012201450d4720034190016a29030021070b20002007370204200020013602000c470b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d46200241017422062005200620054b1b22054100480d460240024020020d00200510332204450d4d0c010b2004280200210420022005460d0020042002200510372204450d4c0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c480b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d472003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c470b200328028c012201450d4620034190016a29030021070b20002007370204200020013602000c460b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d45200241017422062005200620054b1b22054100480d450240024020020d00200510332204450d4c0c010b2004280200210420022005460d0020042002200510372204450d4b0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c470b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d462003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c460b200328028c012201450d4520034190016a29030021070b20002007370204200020013602000c450b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d44200241017422062005200620054b1b22054100480d440240024020020d00200510332204450d4b0c010b2004280200210420022005460d0020042002200510372204450d4a0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c460b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d452003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c450b200328028c012201450d4420034190016a29030021070b20002007370204200020013602000c440b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d43200241017422062005200620054b1b22054100480d430240024020020d00200510332204450d4a0c010b2004280200210420022005460d0020042002200510372204450d490b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c450b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d442003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c440b200328028c012201450d4320034190016a29030021070b20002007370204200020013602000c430b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d42200241017422062005200620054b1b22054100480d420240024020020d00200510332204450d490c010b2004280200210420022005460d0020042002200510372204450d480b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c440b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d432003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c430b200328028c012201450d4220034190016a29030021070b20002007370204200020013602000c420b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d41200241017422062005200620054b1b22054100480d410240024020020d00200510332204450d480c010b2004280200210420022005460d0020042002200510372204450d470b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c430b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d422003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c420b200328028c012201450d4120034190016a29030021070b20002007370204200020013602000c410b20034188016a2001410310fa07200328028801450d3f2000200329038801370200200041086a20034188016a41086a2802003602000c400b20034188016a2001410310fa07200328028801450d3e2000200329038801370200200041086a20034188016a41086a2802003602000c3f0b20034188016a2001410310fa07200328028801450d3d2000200329038801370200200041086a20034188016a41086a2802003602000c3e0b20034188016a2001410310fa07200328028801450d3c2000200329038801370200200041086a20034188016a41086a2802003602000c3d0b20034188016a2001410310fa07200328028801450d3b2000200329038801370200200041086a20034188016a41086a2802003602000c3c0b20034188016a2001410310fa07200328028801450d3a2000200329038801370200200041086a20034188016a41086a2802003602000c3b0b20034188016a2001410310fa07200328028801450d392000200329038801370200200041086a20034188016a41086a2802003602000c3a0b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d39200241017422062005200620054b1b22054100480d390240024020020d00200510332204450d400c010b2004280200210420022005460d0020042002200510372204450d3f0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c3b0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d3a2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c3a0b200328028c012201450d3920034190016a29030021070b20002007370204200020013602000c390b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d38200241017422062005200620054b1b22054100480d380240024020020d00200510332204450d3f0c010b2004280200210420022005460d0020042002200510372204450d3e0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c3a0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d392003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c390b200328028c012201450d3820034190016a29030021070b20002007370204200020013602000c380b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d37200241017422062005200620054b1b22054100480d370240024020020d00200510332204450d3e0c010b2004280200210420022005460d0020042002200510372204450d3d0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c390b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d382003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c380b200328028c012201450d3720034190016a29030021070b20002007370204200020013602000c370b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d36200241017422062005200620054b1b22054100480d360240024020020d00200510332204450d3d0c010b2004280200210420022005460d0020042002200510372204450d3c0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c380b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d372003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c370b200328028c012201450d3620034190016a29030021070b20002007370204200020013602000c360b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d35200241017422062005200620054b1b22054100480d350240024020020d00200510332204450d3c0c010b2004280200210420022005460d0020042002200510372204450d3b0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c370b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d362003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c360b200328028c012201450d3520034190016a29030021070b20002007370204200020013602000c350b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d34200241017422062005200620054b1b22054100480d340240024020020d00200510332204450d3b0c010b2004280200210420022005460d0020042002200510372204450d3a0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c360b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d352003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c350b200328028c012201450d3420034190016a29030021070b20002007370204200020013602000c340b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d33200241017422062005200620054b1b22054100480d330240024020020d00200510332204450d3a0c010b2004280200210420022005460d0020042002200510372204450d390b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c350b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d342003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c340b200328028c012201450d3320034190016a29030021070b20002007370204200020013602000c330b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d21200241017422062005200620054b1b22054100480d210240024020020d002005103322040d010c250b2004280200210420022005460d0020042002200510372204450d240b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c340b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d332003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c330b200328028c012201450d3220034190016a29030021070b20002007370204200020013602000c320b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d20200241017422062005200620054b1b22054100480d200240024020020d00200510332204450d240c010b2004280200210420022005460d0020042002200510372204450d230b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c330b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d322003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c320b200328028c012201450d3120034190016a29030021070b20002007370204200020013602000c310b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1f200241017422062005200620054b1b22054100480d1f0240024020020d00200510332204450d230c010b2004280200210420022005460d0020042002200510372204450d220b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c320b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d312003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c310b200328028c012201450d3020034190016a29030021070b20002007370204200020013602000c300b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1e200241017422062005200620054b1b22054100480d1e0240024020020d00200510332204450d220c010b2004280200210420022005460d0020042002200510372204450d210b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c310b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d302003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c300b200328028c012201450d2f20034190016a29030021070b20002007370204200020013602000c2f0b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1d200241017422062005200620054b1b22054100480d1d0240024020020d00200510332204450d210c010b2004280200210420022005460d0020042002200510372204450d200b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c300b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2f2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2f0b200328028c012201450d2e20034190016a29030021070b20002007370204200020013602000c2e0b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1c200241017422062005200620054b1b22054100480d1c0240024020020d00200510332204450d200c010b2004280200210420022005460d0020042002200510372204450d1f0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c2f0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2e2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2e0b200328028c012201450d2d20034190016a29030021070b20002007370204200020013602000c2d0b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1b200241017422062005200620054b1b22054100480d1b0240024020020d00200510332204450d1f0c010b2004280200210420022005460d0020042002200510372204450d1e0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c2e0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2d2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2d0b200328028c012201450d2c20034190016a29030021070b20002007370204200020013602000c2c0b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d1a200241017422062005200620054b1b22054100480d1a0240024020020d00200510332204450d1e0c010b2004280200210420022005460d0020042002200510372204450d1d0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c2d0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2c2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2c0b200328028c012201450d2b20034190016a29030021070b20002007370204200020013602000c2b0b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d19200241017422062005200620054b1b22054100480d190240024020020d00200510332204450d1d0c010b2004280200210420022005460d0020042002200510372204450d1c0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c2c0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2b2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2b0b200328028c012201450d2a20034190016a29030021070b20002007370204200020013602000c2a0b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d18200241017422062005200620054b1b22054100480d180240024020020d00200510332204450d1c0c010b2004280200210420022005460d0020042002200510372204450d1b0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c2b0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d2a2003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c2a0b200328028c012201450d2920034190016a29030021070b20002007370204200020013602000c290b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d17200241017422062005200620054b1b22054100480d170240024020020d00200510332204450d1b0c010b2004280200210420022005460d0020042002200510372204450d1a0b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c2a0b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d292003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c290b200328028c012201450d2820034190016a29030021070b20002007370204200020013602000c280b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d16200241017422062005200620054b1b22054100480d160240024020020d00200510332204450d1a0c010b2004280200210420022005460d0020042002200510372204450d190b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c290b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d282003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c280b200328028c012201450d2720034190016a29030021070b20002007370204200020013602000c270b20034188016a200141186a2204200141286a410110f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d15200241017422062005200620054b1b22054100480d150240024020020d00200510332204450d190c010b2004280200210420022005460d0020042002200510372204450d180b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c280b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d272003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c270b200328028c012201450d2620034190016a29030021070b20002007370204200020013602000c260b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d14200241017422062005200620054b1b22054100480d140240024020020d00200510332204450d180c010b2004280200210420022005460d0020042002200510372204450d170b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41033a0000200141206a2201200128020041016a3602000c270b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d262003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c260b200328028c012201450d2520034190016a29030021070b20002007370204200020013602000c250b20034188016a200141186a2204200141286a410210f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d13200241017422062005200620054b1b22054100480d130240024020020d00200510332204450d170c010b2004280200210420022005460d0020042002200510372204450d160b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c260b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d252003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c250b200328028c012201450d2420034190016a29030021070b20002007370204200020013602000c240b20034188016a200141186a2204200141286a410310f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d12200241017422062005200620054b1b22054100480d120240024020020d00200510332204450d160c010b2004280200210420022005460d0020042002200510372204450d150b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41013a0000200141206a2201200128020041016a3602000c250b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d242003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c240b200328028c012201450d2320034190016a29030021070b20002007370204200020013602000c230b20034188016a200141186a2204200141286a410010f2070240024020032d0088014101460d000240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d11200241017422062005200620054b1b22054100480d110240024020020d00200510332204450d150c010b2004280200210420022005460d0020042002200510372204450d140b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41023a0000200141206a2201200128020041016a3602000c240b2003419c016a220141013602002003420137028c01200341e8b1cc00360288012003410136026c200320053602682003200341e8006a36029801200341c0006a20034188016a104120032802402202450d232003200329024437026c20032002360268200141013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402101200329024421070240200328026c450d00200328026810350b20010d010c230b200328028c012201450d2220034190016a29030021070b20002007370204200020013602000c220b2003411810fb072003410036029001200320032903003703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141f7a3cc00413b20034188016a41b4a4cc0041c4a4cc001046000b2000200329028c01370200200041086a20034194016a2802003602000c200b200341086a411810fb072003410036029001200320032903083703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141d4a4cc00413420034188016a41b4a4cc004188a5cc001046000b1045000b200341106a411810fb072003410036029001200320032903103703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141d4a4cc00413420034188016a41b4a4cc004188a5cc001046000b2003419c016a41013602002003420237028c01200341b4a5cc00360288012003413e36026c2003200a3602682003200341e8006a36029801200341c0006a20034188016a1041200041086a200341c0006a41086a280200360200200020032903403702000c1c0b41dab0cc00411d41f8b0cc001064000b200341186a411810fb072003410036029001200320032903183703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141f7a3cc00413b20034188016a41b4a4cc0041c4a4cc001046000b41dab0cc00411d41f8b0cc001064000b200341286a411810fb072003410036029001200320032903283703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141f7a3cc00413b20034188016a41b4a4cc0041c4a4cc001046000b20034188016a41146a41013602002003420237028c01200341acaecc0036028801200341013602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a10410c080b20034190016a2903002107200328028c0121010c080b20034190016a2903002107200328028c0121010c070b103e000b41dab0cc00411d41f8b0cc001064000b103c000b200320032d00890122013a00302001200241ff0171460d1020014104460d10200341c0006a41146a413d360200200341cc006a413d36020020034188016a41146a41033602002003420337028c01200341eca5cc0036028801200341013602442003200341c0006a360298012003200341306a3602502003200341df006a3602482003200341d8006a360240200341e8006a20034188016a10410b200329026c2107200328026821010b2001450d0e20002007370204200020013602000c0f0b20032802402101200329024421070b2001450d0c20002007370204200020013602000c0d0b200641027421060340200320042802002205360278200220054d0d0220022005417f736a220520024f0d0a0240200a20054103746a22052d00044103460d0020052d00054104470d040b200441046a21042006417c6a22060d000b410421080b20034188016a200141186a2202200c410010f20720032d0088014101460d02200841ff01714104470d030c040b2003419c016a22044102360200200341cc006a41013602002003420237028c0120034198b0cc003602880120034101360244200320023602302003200341c0006a360298012003200341306a3602482003200341f8006a360240200341e8006a20034188016a1041200328026821022003200329026c37026c20032002360268200441013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402102200329024421070240200328026c450d00200328026810350b20032007370234200320023602300c050b200341cc006a413e3602002003419c016a41023602002003420237028c01200341c4a5cc00360288012003200541056a3602482003413e3602442003200341c0006a360298012003200341e0006a360240200341306a20034188016a10410c040b200341386a20034194016a2802003602002003200329028c013703300c030b20034188016a2002200c200810f407200328028801450d00200341306a41086a20034188016a41086a28020036020020032003290388013703300c020b200341003602300c010b2003419c016a22044102360200200341cc006a41013602002003420237028c0120034198b0cc003602880120034101360244200320023602302003200341c0006a360298012003200341306a3602482003200341f8006a360240200341e8006a20034188016a1041200328026821022003200329026c37026c20032002360268200441013602002003420137028c01200341acaacc0036028801200341383602342003200341306a360298012003200341e8006a360230200341c0006a20034188016a104120032802402102200329024421070240200328026c450d00200328026810350b20032007370234200320023602300b02400240200328023022020d00200141306a2802002202450d0102400240200241037420012802286a41786a22052802002204200141206a220628020022024b0d00200421010c010b024002402001411c6a280200220820026b200420026b2209490d002001280218210a200221010c010b200220096a220a2002490d042008410174220b200a200b200a4b1b220b4100480d040240024020080d000240200b0d004101210a0c020b200b1033220a450d0b0c010b2001280218210a2008200b460d00200a2008200b1037220a450d0a0b2001200a3602182001411c6a200b360200200141206a28020021010b200a20016a21080240024020094102490d002008410420042002417f736a2202109f081a200a200220016a22016a21080c010b2009450d010b200841043a0000200141016a21010b20062001360200200541013a00060c050b20002003290234370204200020023602000c050b200341206a411810fb072003410036029001200320032903203703880120034188016a4100411810fc07200328028801220120032802900122006a411841feafcc00411810fd072003200041186a360290012003200329028c0137028c01200320013602880141f7a3cc00413b20034188016a41b4a4cc0041c4a4cc001046000b103e000b41dab0cc00411d41f8b0cc001064000b20002007370204200020013602000c010b200041003602000b200341a0016a24000f0b103c000b6401017f230041206b220224002002413f360204200220003602002001411c6a2802002100200128021821012002411c6a41013602002002420137020c20024188b2cc003602082002200236021820012000200241086a10432101200241206a240020010b0c002000280200200110cd070b8f1f03127f017e037f23004180026b220524000240024020014115490d00410121064101210702400240034020012108200021092006200771410173210a024002400240034002400240024002402004450d00024020064101710d002000200110c8072004417f6a21040b2001410276220741036c210b2007410174210c4100210d20014132490d03200741016a210e200020074103746a220f28020020002007417f6a220d4103746a2210280200201041046a2802002210200f41046a280200220f200f20104b1b10a0082211450d01417f410120114100481b21100c020b2000200110c9070c0b0b417f200f201047200f2010491b21100b2007200d2010417f4622101b210f024002402000200e4103746a22112802002000200d200720101b22124103746a2207280200200741046a2802002207201141046a280200220d200d20074b1b10a0082211450d00417f410120114100481b21070c010b417f200d200747200d2007491b21070b4102410120101b20102007417f4622071b210d024002402000200e201220071b22114103746a22102802002000200f4103746a2207280200200741046a2802002207201041046a2802002210201020074b1b10a008220e450d00417f4101200e4100481b21100c010b417f201020074720102007491b21100b200c4101722107200d2010417f4622126a2113024002402000200c4103746a220d2802002000200c417f6a22104103746a220e280200200e41046a280200220e200d41046a280200220d200d200e4b1b10a0082214450d00417f410120144100481b210e0c010b417f200d200e47200d200e491b210e0b200c2010200e417f46220e1b210d2013200e6a211302400240200020074103746a221428020020002010200c200e1b220e4103746a220c280200200c41046a280200220c201441046a28020022102010200c4b1b10a0082214450d00417f410120144100481b210c0c010b417f2010200c472010200c491b210c0b2013200c417f46220c6a21100240024020002007200e200c1b22134103746a220c2802002000200d4103746a2207280200200741046a2802002207200c41046a280200220c200c20074b1b10a008220e450d00417f4101200e4100481b210c0c010b417f200c200747200c2007491b210c0b200b41016a21072010200c417f4622146a2115024002402000200b4103746a220e2802002000200b417f6a220c4103746a2210280200201041046a2802002210200e41046a280200220e200e20104b1b10a0082216450d00417f410120164100481b21100c010b417f200e201047200e2010491b21100b200b200c2010417f4622101b210e201520106a211502400240200020074103746a22162802002000200c200b20101b22104103746a220c280200200c41046a280200220c201641046a280200220b200b200c4b1b10a0082216450d00417f410120164100481b210c0c010b417f200b200c47200b200c491b210c0b2015200c417f46220c6a211502400240200020072010200c1b220b4103746a220c2802002000200e4103746a2207280200200741046a2802002207200c41046a280200220c200c20074b1b10a0082210450d00417f410120104100481b21100c010b417f200c200747200c2007491b21100b200f201120121b2107200d201320141b210c200e200b2010417f4622101b210b201520106a210d0b024002402000200c4103746a220e280200200020074103746a2210280200201041046a2802002210200e41046a280200220e200e20104b1b10a008220f450d00417f4101200f4100481b21100c010b417f200e201047200e2010491b21100b200c20072010417f46220e1b2110200d200e6a210d024002402000200b4103746a220f28020020002007200c200e1b220e4103746a2207280200200741046a2802002207200f41046a280200220c200c20074b1b10a008220f450d00417f4101200f4100481b21070c010b417f200c200747200c2007491b21070b200d2007417f46220c6a2107024002400240024002402000200b200e200c1b220d4103746a220b280200200020104103746a220c280200200c41046a280200220c200b41046a280200220b200b200c4b1b10a008220e450d00200e4100480d010c020b200b200c4f0d010b200741016a2207410c490d0102402001410176220b450d00200020014103746a41786a21072000210c0340200c2902002117200c200729020037020020072017370200200c41086a210c200741786a2107200b417f6a220b0d000b0b20012010417f736a2110410121070c020b200d21100b20074521070b0240200745200a724101710d002000200110ca070d090b2003450d010240201020014f0d00024002402003280200200020104103746a2207280200200741046a280200220c200341046a280200220b200b200c4b1b10a008220e450d00200e41004e0d010c050b200b200c490d040b200029020021172000200729020037020020072017370200200041786a21122000410c6a2113200041086a2114200028020421072000280200210d4100210b2001210e0340024002400240200b200e417f6a22114f0d002013200b4103746a210c034002400240200d200c417c6a280200200c28020022102007200720104b1b10a008220f450d00200f4100480d030c010b20072010490d020b200c41086a210c2011200b41016a220b470d000c020b0b0240200b20114f0d002012200e4103746a210c2011210e034002400240200d200c280200200c41046a28020022102007200720104b1b10a008220f450d00200f4100480d010c050b200720104f0d040b200c41786a210c200b200e417f6a220e490d000b0b200b21110b200020073602042000200d36020002402001201141016a2207490d00200020074103746a2100200120076b220141154f0d040c0b0b2007200141e485cc001059000b2014200b4103746a221029020021172010200c290200370200200c2017370200200b41016a210b0c000b0b0b2010200141d086cc001042000b20080d014100410041f485cc001042000b20002109200121080b201020084f0d02200929020021172009200920104103746a2207290200370200200720173702002009280204210c200928020021124100210e410021184100211902402008417f6a2200450d002009410c6a21074100211803400240024002402007417c6a2802002012200c2007280200220b200b200c4b1b10a0082210450d00201041004e0d010c020b200b200c490d010b200021190240200020184d0d00200920084103746a41786a21072000211903400240024020072802002012200c200741046a280200220b200b200c4b1b10a0082210450d00201041004e0d010c030b200b200c490d020b200741786a21072019417f6a221920184b0d000b0b0240024020192018490d0020002019490d010c040b20182019419486cc001059000b20192000419486cc001058000b200741086a21072000201841016a2218470d000b20002118200021190b200941086a220720194103746a210041800121144100211141002110410021014180012106200720184103746a221a210d034002402000200d6b22074187104b220a0d002007410376220741807f6a20072011200e492001201049220b72220f1b21070240200f450d0020062007200b1b210620072014200b1b21140c010b2007200741017622066b21140b024020012010470d00024020060d002005221021010c010b4100210720052110200d210b0340201020073a0000200741016a210702400240200b2802002012200c200b41046a280200220f200f200c4b1b10a0082201450d00417f410120014100481b210f0c010b417f200f200c47200f200c491b210f0b200b41086a210b2010200f417f476a211020062007470d000b200521010b02402011200e470d00024020140d0020054180016a220e21110c010b200041786a21074100210b20054180016a210e0340200e200b3a0000200b41016a210b0240024020072802002012200c200741046a280200220f200f200c4b1b10a0082211450d00417f410120114100481b210f0c010b417f200f200c47200f200c491b210f0b200741786a2107200e200f417f466a210e2014200b470d000b20054180016a21110b0240200e20116b2207201020016b220b200b20074b1b2213450d00200d20012d00004103746a22072802042115200728020021162007200020112d0000417f734103746a290200370200024020134101460d004100210703402000201120076a220b2d0000417f734103746a200d200120076a41016a220f2d00004103746a290200370200200d200f2d00004103746a2000200b41016a2d0000417f734103746a290200370200200741026a210b200741016a220f2107200b2013490d000b2011200f6a21112001200f6a21010b200020112d0000417f734103746a2207201536020420072016360200201141016a2111200141016a21010b200020144103746b20002011200e461b2100200d20064103746a200d20012010461b210d200a0d000b02400240200120104f0d00200021070340200d2010417f6a22102d00004103746a220b2902002117200b200741786a22072902003702002007201737020020012010490d000c020b0b200d21072011200e4f0d0003402007290200211720072000200e417f6a220e2d0000417f734103746a220b290200370200200b2017370200200741086a21072011200e490d000b0b2009200c36020420092012360200024020082007201a6b41037620186a22014d0d00200929020021172009200920014103746a220729020037020020072017370200200820016b220c450d02200c20012001200c4b1b210b20084103762110200741086a2100024002402001200c417f6a220c490d002000200c20022007200410be07200921000c010b2009200120022003200410be0720072103200c21010b200b20104f2106201920184d2107200141154f0d010c040b0b20012008418486cc001042000b41a486cc00411c41c086cc00103f000b20102008418486cc001042000b20014102490d00200041786a2111410021124101210f0340200f4103742107200f417f6a210c200f41016a210f024002400240200020076a2210280200220d2000200c4103746a2207280200200741046a280200220e201041046a280200220b200b200e4b1b10a0082213450d0020134100480d010c020b200b200e4f0d010b201020072902003702000240200c450d002012210c201121070240034002400240200d2007280200200741046a2802002210200b200b20104b1b10a008220e450d00200e41004e0d030c010b200b20104f0d020b200741086a2007290200370200200741786a2107200c41016a2210200c49210e2010210c200e450d000b0b200741086a21070b2007200d3602002007200b3602040b2012417f6a2112201141086a2111200f2001470d000b0b20054180026a24000b19002000200141186a280200360204200020012802103602000bf80201067f230041c0006b2202240041002103410021040240024003400240024002402003411f4b0d002001280204220520012802082206460d01200641016a22072006490d04200520074f0d022007200541c0fdcb001058000b200041013602002000410f3a00040c040b200241013a000f200241346a410136020020024201370224200241acfdcb003602202002413636023c2002200241386a36023020022002410f6a360238200241106a200241206a10412002410b6a200241186a28020036000020022002290310370003200041053a0004200020022900003700052000410c6a200241076a290000370000200041013602000c030b200128020020066a2d0000210620012007360208200641ff00712003411f71742004722104200341076a21032006418001710d000b0240024020034120490d002006410f4b0d010b20004100360200200020043602040c020b200041013602002000410d3a00040c010b417f200741c0fdcb001059000b200241c0006a24000be704010a7f230041106b22032400200128020421042001280200210541002106410121074100210820012802082209210a0240024003400240024020082006460d002006210b0c010b200641016a220c2006490d022006410174220b200c200b200c4b1b220b4100480d020240024020060d000240200b0d00410121070c020b200b103322070d010c050b2006200b460d0020072006200b10372207450d040b200b21060b200720086a200a41807f72200a41ff0071200a410776220c1b3a0000200841016a2108200c210a200c0d000b02400240200b20086b2009490d00200b21060c010b200820096a22062008490d01200b410174220a2006200a20064b1b22064100480d010240200b0d00024020060d00410121070c020b200610332207450d030c010b200b2006460d002007200b200610372207450d020b200720086a20052009109d081a02402004450d00200510350b200128020c210502400240200620096b20086b200141146a280200220c490d002009200c6a20086a210a2006210b0c010b200920086a220b200c6a220a200b490d012006410174220b200a200b200a4b1b220b4100480d01024020060d000240200b0d00410121070c020b200b10332207450d030c010b2006200b460d0020072006200b10372207450d020b200720096a20086a2005200c109d081a200341003a000f200a210603402003200641800172200641ff0071200641077622081b3a000f20022003410f6a410110782008210620080d000b20022007200a10780240200b450d00200710350b2000411f3a00000240200141106a280200450d00200510350b200341106a24000f0b103e000b103c000bde03030a7f017e027f230041106b2203240020012802002104200341003a000e2004210503402003200541800172200541ff0071200541077622061b3a000e20022003410e6a410110782006210520060d000b200128020422072001410c6a2802002206410c6c6a2108200141086a280200210920072105024002402006450d00200721052004450d00200841746a210a410021052007210b0340200b2106024003402006280200220c0d01200541016a210520082006410c6a2206470d000c040b0b200641046a290200210d200341003a000e2006410c6a210b200541016a210e03402003200541800172200541ff0071200541077622011b3a000e20022003410e6a410110782001210520010d000b200341003a000f200d422088a7220f210503402003200541800172200541ff0071200541077622011b3a000f20022003410f6a410110782001210520010d000b2002200c200f10780240200da7450d00200c10350b0240200a2006460d00200e21052004417f6a22040d010b0b2006410c6a21050b20082005460d00034020052206410c6a2105024020062802002202450d00200641046a280200450d00200210350b20082005470d000b0b02402009450d002009410c6c450d00200710350b2000411f3a0000200341106a24000bfe0101067f2000410c6a280200200028020822016b2202411c6d210302402002450d0020012003411c6c6a21040340024020012802042202450d0002402001410c6a2802002203450d00200341047421030340024020022d00004109470d000240200241046a2205280200220628020441ffffffff0371450d0020062802001035200528020021060b200610350b200241106a2102200341706a22030d000b0b200141086a28020041ffffffff0071450d00200128020410350b2001411c6a21020240200141146a280200450d00200128021010350b2002210120022004470d000b0b024020002802042202450d002002411c6c450d00200028020010350b0b820201067f2000410c6a280200200028020822016b220241186d210302402002450d002001200341186c6a210403400240200141046a28020041ffffffff0171450d00200128020010350b0240200141146a2802002203450d00200128020c2102200341047421030340024020022d00004109470d000240200241046a2205280200220628020441ffffffff0371450d0020062802001035200528020021060b200610350b200241106a2102200341706a22030d000b0b200141186a21020240200141106a28020041ffffffff0071450d00200128020c10350b2002210120022004470d000b0b024020002802042202450d00200241186c450d00200028020010350b0b850201067f2000410c6a280200200028020822016b2202411c6d210302402002450d0020012003411c6c6a21040340024020012802042202450d0002402001410c6a2802002203450d00200341047421030340024020022d00004109470d000240200241046a2205280200220628020441ffffffff0371450d0020062802001035200528020021060b200610350b200241106a2102200341706a22030d000b0b200141086a28020041ffffffff0071450d00200128020410350b2001411c6a21020240200141146a28020041ffffffff0371450d00200128021010350b2002210120022004470d000b0b024020002802042202450d002002411c6c450d00200028020010350b0bcf0101067f02402000410c6a2802002201200028020822026b450d000340024020022802082203450d0020022802002104200341047421030340024020042d00004109470d000240200441046a2205280200220628020441ffffffff0371450d0020062802001035200528020021060b200610350b200441106a2104200341706a22030d000b0b200241106a21040240200241046a28020041ffffffff0071450d00200228020010350b2004210220042001470d000b0b0240200028020441ffffffff0071450d00200028020010350b0b8f05010b7f230041c080016b220224002002200110c007410121030240024020022802004101460d00200228020421042002410041808001109f08210541002106410021070240024002400240024002402004450d004100210841002109410121034100210a03402001280204220b200128020822076b2004200a6b220c41808001200c41808001491b220c490d022007200c6a22062007490d03200b2006490d042005200128020020076a200c109d08210b2001200636020802400240200920086b200c490d002008200c6a2107200921060c010b2008200c6a22072008490d06200941017422062007200620074b1b22064100480d060240024020090d00024020060d00410121030c020b2006103322030d010c090b20092006460d0020032009200610372203450d080b200621090b200320086a200b200c109d081a200721082004200c200a6a220a4b0d000b0b2000200336020420004100360200200041146a2007360200200041106a41003602002000410c6a2007360200200041086a20063602000c060b200541013a008f8001200541b480016a4101360200200542013702a48001200541acfdcb003602a08001200541363602bc80012005200541b880016a3602b0800120052005418f80016a3602b880012005419080016a200541a080016a10412005418b80016a2005419880016a2802003600002005200529039080013700838001200041053a00042000200529008080013700052000410c6a2005418780016a290000370000200041013602002009450d05200310350c050b2007200641c0fdcb001059000b2006200b41c0fdcb001058000b103e000b103c000b20002002290204370204200041013602002000410c6a2002410c6a2902003702000b200241c080016a24000bf50202057f017e02400240024020014108490d00200141017641feffffff07712202417f6a220320014f0d022001410d74200173220441117620047322044105742004732205417f2001417f6a677622067122044100200120042001491b6b220420014f0d01200020034103746a220329020021072003200020044103746a220429020037020020042007370200024020022001490d00200221030c030b2005410d7420057322044111762004732204410574200473220520067122044100200120042001491b6b220420014f0d01200020024103746a220329020021072003200020044103746a2204290200370200200420073702002002410172220320014f0d022005410d742005732204411176200473220441057420047320067122044100200120042001491b6b220420014f0d01200020034103746a220129020021072001200020044103746a2200290200370200200020073702000b0f0b20042001418486cc001042000b2003200141f485cc001042000bb20102037f017e024020014101762202450d00200020012002417f6a10cb072002417e6a210203402002417f460d0120002001200210cb072002417f6a21020c000b0b0240024020014102490d00200141037420006a41786a21022001210303402003417f6a220420014f0d0220002902002105200020022902003702002002200537020020002004410010cb07200241786a210220042103200441014b0d000b0b0f0b2003417f6a2001418486cc001042000b8f06050a7f017e017f017e037f200041686a2102200041786a210320014132492104410121054100210602400240024003400240024020052001490d00410021070c010b200320054103746a210841012107034002400240200841086a22092802002008280200200841046a280200220a2008410c6a28020022082008200a4b1b10a008220b450d00200b4100480d030c010b2008200a490d020b4101210a200541016a220520014921072009210820012005470d000c030b0b2005200146210a20040d0120052001460d012005417f6a220820014f0d032007410171450d02200020084103746a2208290200210c200820002005410374220d6a2209290200220e3702002009200c370200024020054102490d0002400240200ea7220f20002005417e6a22074103746a220b280200200b41046a2802002210200841046a280200220a200a20104b1b10a0082211450d0020114100480d010c020b200a20104f0d010b2008200b29020037020002402007450d002002200d6a21080240034002400240200f2008280200200841046a280200220b200a200a200b4b1b10a0082210450d00201041004e0d030c010b200a200b4f0d020b200841086a2008290200370200200841786a21082007417f6a22070d000b0b200841086a210b0b200b200f360200200b200a3602040b200641016a21060240200120056b220f4102490d000240024020092802082009280200220d200941046a280200220b2009410c6a28020022082008200b4b1b10a008220a450d00200a4100480d010c020b2008200b4f0d010b200941086a2111200920092902083702000240200f4103490d004103210a41022107034002400240200920074103746a2208280200200d200b200841046a28020022072007200b4b1b10a0082210450d00201041004e0d030c010b2007200b4f0d020b200841786a20082902003702000240200a200f4f0d00200a2107200a41016a210a200821110c010b0b200821110b2011200d3602002011200b3602040b20064105470d000b4100210a0b200a0f0b20052001418486cc001042000b2008200141f485cc001042000bb60202057f017e03402002410174220341017221040240024002400240200341026a220320014f0d00200420014f0d0102400240200020044103746a2205280200200020034103746a2206280200200641046a2802002206200541046a2802002205200520064b1b10a0082207450d00417f410120074100481b21060c010b417f200520064720052006491b21060b200320042006417f461b21040b0240200420014f0d00200220014f0d020240200020024103746a2202280200200020044103746a2203280200200341046a2802002206200241046a2802002205200520064b1b10a0082207450d00200741004e0d010c040b20052006490d030b0f0b2004200141f487cc001042000b20022001418488cc001042000b200229020021082002200329020037020020032008370200200421020c000b0b830401097f200141096a2d0000210220012802042103200128020021040240024002400240024002400240024020012d000822014102470d0020040d010c050b20014101462105024020040d00200521060c020b2005200320046b6a220620054f0d01410021074100210541002106410121080340024002400240200141ff01714102470d00200221090c010b410021092001410171450d00410021010c010b2004450d0820042003460d0820042d0000210241022101200441016a21040b024020052006470d002005417f200320046b410020041b220641016a220a200a2006491b6a22062005490d0420072006200720064b1b22064100480d04024020050d00024020060d00410121080c020b2006103322080d010c060b20052006460d0020082005200610372208450d050b200820056a20023a0000200741026a2107200541016a2105200921020c000b0b200320046b21060b2006450d0220064100480d00200610332208450d010c030b103e000b103c000b41012108410021060b02400240200141037122074103460d00410021052008210120070e03010001010b200820023a000041012105200841016a21010b2004450d0020032004460d00200421020340200120022d00003a0000200141016a21012003200241016a2202470d000b2003200520046b6a21050b2000200536020820002006360204200020083602000bc76501037f230041206b220224000240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020002d00000eac010102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80018101820183018401850186018701880189018a018b018c018d018e018f0190019101920193019401950196019701980199019a019b019c019d019e019f01a001a101a201a301a401a501a601a701a801a901aa01ab0100010b2002200128021841cff1cb0041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000cab010b2002200128021841e0f1cb00410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000caa010b2002200128021841ebf1cb0041032001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca9010b2002200128021841eef1cb0041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41f4f1cb00106f21000ca8010b200220012802184184f2cb0041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41f4f1cb00106f21000ca7010b200220012802184188f2cb0041022001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41f4f1cb00106f21000ca6010b20022001280218418af2cb0041042001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca5010b20022001280218418ef2cb0041032001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca4010b200220012802184191f2cb0041022001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000ca3010b200220012802184193f2cb0041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000ca2010b200220012802184197f2cb0041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41a0f2cb00106f21000ca1010b2002200128021841b0f2cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000ca0010b2002200128021841b6f2cb0041042001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c9f010b2002200128021841baf2cb00410c2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041016a36020c20012002410c6a41c8f2cb00106f21000c9e010b2002200128021841d8f2cb0041042001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c9d010b2002200128021841dcf2cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c9c010b2002200128021841e2f2cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c9b010b2002200128021841eaf2cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c9a010b2002200128021841f2f2cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c99010b2002200128021841faf2cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c98010b200220012802184183f3cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c97010b20022001280218418cf3cb0041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c96010b200220012802184193f3cb0041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c95010b20022001280218419af3cb0041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c94010b2002200128021841a1f3cb0041072001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c93010b2002200128021841a8f3cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c92010b2002200128021841b1f3cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c91010b2002200128021841baf3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c90010b2002200128021841c4f3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8f010b2002200128021841cef3cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8e010b2002200128021841d7f3cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8d010b2002200128021841e0f3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8c010b2002200128021841eaf3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8b010b2002200128021841f4f3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c8a010b2002200128021841fef3cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c89010b200220012802184188f4cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c88010b200220012802184190f4cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c87010b200220012802184198f4cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c86010b2002200128021841a0f4cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c85010b2002200128021841a8f4cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c84010b2002200128021841b1f4cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c83010b2002200128021841bbf4cb0041092001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c82010b2002200128021841c4f4cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c81010b2002200128021841cef4cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21012002200041086a36020c20012002410c6a4198f1cb00106f21000c80010b2002200128021841d8f4cb00410d2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41c8f2cb00106f21000c7f0b2002200128021841e5f4cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041016a36020c200241106a2002410c6a41c8f2cb00106f21000c7e0b2002200128021841eff4cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a41f8f4cb00106f21000c7d0b200220012802184188f5cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a4190f5cb00106f21000c7c0b2002200128021841a0f5cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041046a36020c200241106a2002410c6a4198f1cb00106f21000c7b0b2002200128021841a8f5cb0041082001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200041086a36020c200241106a2002410c6a41b0f5cb00106f21000c7a0b2002200128021841c0f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c790b2002200128021841c6f5cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c780b2002200128021841cbf5cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c770b2002200128021841d0f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c760b2002200128021841d6f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c750b2002200128021841dcf5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c740b2002200128021841e2f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c730b2002200128021841e8f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c720b2002200128021841eef5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c710b2002200128021841f4f5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c700b2002200128021841faf5cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6f0b200220012802184180f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6e0b200220012802184186f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6d0b20022001280218418bf6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6c0b200220012802184190f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6b0b200220012802184196f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c6a0b20022001280218419cf6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c690b2002200128021841a2f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c680b2002200128021841a8f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c670b2002200128021841aef6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c660b2002200128021841b4f6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c650b2002200128021841baf6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c640b2002200128021841c0f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c630b2002200128021841c5f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c620b2002200128021841caf6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c610b2002200128021841cff6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c600b2002200128021841d4f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5f0b2002200128021841d9f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5e0b2002200128021841def6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5d0b2002200128021841e3f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5c0b2002200128021841e8f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5b0b2002200128021841edf6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c5a0b2002200128021841f2f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c590b2002200128021841f7f6cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c580b2002200128021841fcf6cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c570b200220012802184182f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c560b200220012802184188f7cb0041092001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c550b200220012802184191f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c540b200220012802184197f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c530b20022001280218419df7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c520b2002200128021841a3f7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c510b2002200128021841aaf7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c500b2002200128021841b1f7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4f0b2002200128021841b8f7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4e0b2002200128021841bff7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4d0b2002200128021841c5f7cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4c0b2002200128021841caf7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4b0b2002200128021841d0f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c4a0b2002200128021841d6f7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c490b2002200128021841ddf7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c480b2002200128021841e4f7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c470b2002200128021841ebf7cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c460b2002200128021841f2f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c450b2002200128021841f8f7cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c440b2002200128021841fef7cb0041092001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c430b200220012802184187f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c420b20022001280218418df8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c410b200220012802184193f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c400b200220012802184199f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3f0b2002200128021841a0f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3e0b2002200128021841a7f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3d0b2002200128021841aef8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3c0b2002200128021841b5f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3b0b2002200128021841bbf8cb0041052001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c3a0b2002200128021841c0f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c390b2002200128021841c6f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c380b2002200128021841ccf8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c370b2002200128021841d3f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c360b2002200128021841daf8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c350b2002200128021841e1f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c340b2002200128021841e8f8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c330b2002200128021841eef8cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c320b2002200128021841f4f8cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c310b2002200128021841fbf8cb0041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c300b200220012802184183f9cb0041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2f0b20022001280218418bf9cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2e0b200220012802184195f9cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2d0b20022001280218419cf9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2c0b2002200128021841a2f9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2b0b2002200128021841a8f9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c2a0b2002200128021841aef9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c290b2002200128021841b4f9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c280b2002200128021841baf9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c270b2002200128021841c0f9cb00410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c260b2002200128021841cbf9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c250b2002200128021841d1f9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c240b2002200128021841d7f9cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c230b2002200128021841def9cb0041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c220b2002200128021841e6f9cb0041082001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c210b2002200128021841eef9cb00410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c200b2002200128021841f8f9cb0041072001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1f0b2002200128021841fff9cb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1e0b200220012802184185facb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1d0b20022001280218418bfacb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1c0b200220012802184191facb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1b0b200220012802184197facb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c1a0b20022001280218419dfacb0041062001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c190b2002200128021841a3facb00410b2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c180b2002200128021841aefacb00410a2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c170b2002200128021841b8facb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c160b2002200128021841c4facb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c150b2002200128021841d0facb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c140b2002200128021841dcfacb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c130b2002200128021841e8facb00410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c120b2002200128021841f5facb00410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c110b200220012802184182fbcb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c100b20022001280218418efbcb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0f0b20022001280218419afbcb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0e0b2002200128021841a6fbcb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0d0b2002200128021841b2fbcb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0c0b2002200128021841c0fbcb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0b0b2002200128021841cefbcb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c0a0b2002200128021841dcfbcb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c090b2002200128021841eafbcb00410c2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c080b2002200128021841f6fbcb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c070b200220012802184184fccb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c060b200220012802184192fccb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c050b2002200128021841a0fccb00410e2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c040b2002200128021841aefccb00410d2001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c030b2002200128021841bbfccb0041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c020b2002200128021841ccfccb0041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000c010b2002200128021841ddfccb0041112001411c6a28020028020c1100003a001820022001360210200241003a001920024100360214200241106a21000b20002d00082101024020002802042203450d00200141ff0171210441012101024020040d00024020034101470d0020002d0009450d00200028020022042d00004104710d0041012101200428021841d6a0c00041012004411c6a28020028020c1100000d010b2000280200220128021841cca6cc0041012001411c6a28020028020c11000021010b200020013a00080b200241206a2400200141ff01714100470bcc0101047f230041106b220224002000280200220041046a28020021032000280200210041012104200128021841d9a0c00041012001411c6a28020028020c1100002105200241003a0005200220053a00042002200136020002402003450d002003410274210103402002200036020c20022002410c6a41f0fccb0010701a200041046a21002001417c6a22010d000b20022d000421050b0240200541ff01710d002002280200220028021841d8a0c00041012000411c6a28020028020c11000021040b200241106a240020040b8a0201027f230041106b2202240020002802002802002100200128021841a8f1cb00410b2001411c6a28020028020c1100002103200241003a0005200220033a0004200220013602002002200036020c200241b3f1cb0041052002410c6a41b8f1cb00106921012002200041086a36020c200141c8f1cb0041072002410c6a4198f1cb0010691a20022d00042101024020022d0005450d00200141ff0171210041012101024020000d0020022802002201411c6a28020028020c210020012802182103024020012d00004104710d00200341d0a0c0004102200011000021010c010b200341d2a0c0004101200011000021010b200220013a00040b200241106a2400200141ff01714100470b0c002000280200200110b9070bc50201037f230041206b2202240002400240200028020022002d00004104470d0020022001280218419cfdcb0041082001411c6a28020028020c11000022003a001820022001360210200241003a0019200241003602140c010b2002200128021841a4fdcb0041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a418cfdcb00106f210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841d6a0c00041012004411c6a28020028020c1100000d010b2001280200220028021841cca6cc0041012000411c6a28020028020c11000021000b200120003a00080b200241206a2400200041ff01714100470bc00201037f230041206b220224000240024020002d00004104470d0020022001280218419cfdcb0041082001411c6a28020028020c11000022003a001820022001360210200241003a0019200241003602140c010b2002200128021841a4fdcb0041052001411c6a28020028020c1100003a001820022001360210200241003a0019200241003602142002200036020c200241106a2002410c6a418cfdcb00106f210120022d0018210020022802142203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841d6a0c00041012004411c6a28020028020c1100000d010b2001280200220028021841cca6cc0041012000411c6a28020028020c11000021000b200120003a00080b200241206a2400200041ff01714100470bd70203027f017e017f23004180016b220224002000280200210002400240024002400240200128020022034110710d002000280200210020034120710d012000ac22042004423f8722047c2004852000417f73411f762001105221000c020b20002802002103410021000340200220006a41ff006a2003410f712205413072200541d7006a2005410a491b3a00002000417f6a2100200341047622030d000b20004180016a22034181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021030340200220036a41ff006a2000410f712205413072200541376a2005410a491b3a00002003417f6a2103200041047622000d000b20034180016a22004181014f0d022001410141d88bc0004102200220036a4180016a410020036b105621000b20024180016a240020000f0b200341800141c88bc0001059000b200041800141c88bc0001059000bca0201037f23004180016b220224002000280200210002400240024002400240200128020022034110710d0020002d0000210420034120710d012004ad42ff018341012001105221000c020b20002d00002104410021000340200220006a41ff006a2004410f712203413072200341d7006a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021000340200220006a41ff006a2004410f712203413072200341376a2003410a491b3a00002000417f6a21002004410476410f7122040d000b20004180016a22044181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000b20024180016a240020000f0b200441800141c88bc0001059000b200441800141c88bc0001059000bd70202027f027e23004180016b220224002000280200210002400240024002400240200128020022034110710d002000290300210420034120710d0120042004423f8722057c2005852004427f552001105221000c020b20002903002104410021000340200220006a41ff006a2004a7410f712203413072200341d7006a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000c010b410021000340200220006a41ff006a2004a7410f712203413072200341376a2003410a491b3a00002000417f6a2100200442048822044200520d000b20004180016a22034181014f0d022001410141d88bc0004102200220006a4180016a410020006b105621000b20024180016a240020000f0b200341800141c88bc0001059000b200341800141c88bc0001059000b940201047f230041106b220324000240024002400240200241ffffffff03712002470d0020024102742204417f4c0d000240024020040d00410421050c010b200410332205450d020b20034100360208200320053602002003200441027636020420034100200210860120032802002205200328020822064102746a20012002410274109d081a024020032802042204200620026a2202460d0020042002490d032004450d002004410274220120024102742204460d00024020040d00024020010d00410421050c020b20051035410421050c010b20052001200410372205450d040b2000200236020420002005360200200341106a24000f0b1044000b1045000b41ec80cc00412441c086cc00103f000b103c000bab0902027f017e230041106b220224000240024020012d00002203414f6a41fb00490d0002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e312a2a0001022a2a0304052a06072a2a08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a0b200020012d00013a0001410221030c290b200020012d00013a0001410321030c280b200020012d00013a0001410421030c270b200041046a200141046a280200360200410721030c260b200041046a200141046a280200360200410821030c250b200141046a2802002103410c10332201450d25200241086a2003280200200341046a28020010d607200229030821042001200328020836020820012004370200200041046a2001360200410921030c240b200041046a200141046a280200360200410b21030c230b200020012d00013a0001200041046a200141046a280200360200410c21030c220b200041046a200141046a280200360200410f21030c210b200041046a200141046a280200360200411021030c200b200041046a200141046a280200360200411121030c1f0b200041046a200141046a280200360200411221030c1e0b200041046a200141046a280200360200411321030c1d0b200041046a200141046a290200370200411421030c1c0b200041046a200141046a290200370200411521030c1b0b200041046a200141046a290200370200411621030c1a0b200041046a200141046a290200370200411721030c190b200041046a200141046a290200370200411821030c180b200041046a200141046a290200370200411921030c170b200041046a200141046a290200370200411a21030c160b200041046a200141046a290200370200411b21030c150b200041046a200141046a290200370200411c21030c140b200041046a200141046a290200370200411d21030c130b200041046a200141046a290200370200411e21030c120b200041046a200141046a290200370200411f21030c110b200041046a200141046a290200370200412021030c100b200041046a200141046a290200370200412121030c0f0b200041046a200141046a290200370200412221030c0e0b200041046a200141046a290200370200412321030c0d0b200041046a200141046a290200370200412421030c0c0b200041046a200141046a290200370200412521030c0b0b200041046a200141046a290200370200412621030c0a0b200041046a200141046a290200370200412721030c090b200041046a200141046a290200370200412821030c080b200041046a200141046a290200370200412921030c070b200041046a200141046a290200370200412a21030c060b200020012d00013a0001412b21030c050b200020012d00013a0001412c21030c040b200041046a200141046a280200360200412d21030c030b200041086a200141086a290300370300412e21030c020b200041046a200141046a280200360200412f21030c010b200041086a200141086a290300370300413021030b200020033a0000200241106a24000f0b103c000bcc0201027f230041106b22022400200028020028020021002001280218418b85cc0041052001411c6a28020028020c1100002103200241003a0005200220033a00042002200136020020022000410c6a36020c2002419085cc00410e2002410c6a41a085cc00106921012002200036020c200141b085cc0041092002410c6a41bc85cc00106921012002200041046a36020c200141cc85cc00410c2002410c6a41bc85cc00106921012002200041086a36020c200141d885cc00410c2002410c6a41bc85cc0010691a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341d0a0c0004102200111000021000c010b200341d2a0c0004101200111000021000b200220003a00040b200241106a2400200041ff01714100470bd50302047f017e024020014101762202450d0003402002417f6a2202210302400240024003402003410174220441017221050240200441026a220420014f0d00200520014f0d0220042005200020054103746a280200200020044103746a280200491b21050b200520014f0d03200320014f0d02200020034103746a2203280200200020054103746a22042802004f0d03200329020021062003200429020037020020042006370200200521030c000b0b2005200141f487cc001042000b20032001418488cc001042000b20020d000b0b0240024020014102490d002001210403402004417f6a220420014f0d02200029020021062000200020044103746a2205290200370200200520063702004100210302400240024003402003410174220241017221050240200241026a220220044f0d00200520044f0d0220022005200020054103746a280200200020024103746a280200491b21050b200520044f0d03200320044f0d02200020034103746a2203280200200020054103746a22022802004f0d03200329020021062003200229020037020020022006370200200521030c000b0b2005200441f487cc001042000b20032004418488cc001042000b200441014b0d000b0b0f0b20042001418486cc001042000bea04050a7f017e017f017e027f200041686a21022001417f6a2103200041086a2104410021052001413249210641012107024003400240024020072001490d00410021080c010b410121082000200741037422096a220a280200220b200a41786a280200490d00200420096a210803404101210a20032007460d03200741016a21072008280200220a200b4f2109200841086a2108200a210b20090d000b200720014921080b2007200146210a20060d0120072001460d010240024002400240024002402007417f6a220b20014f0d002008450d012000200b4103746a220b290200210c200b20002007410374220d6a2208290200220e3702002008200c37020020074102490d0520002007417e6a220a4103746a220f280200200ea722094d0d05200b200f290200370200200a450d0420002007417d6a220a4103746a28020020094d0d042002200d6a210b0340200b41086a200b290200370200200a450d03200a417f6a210a200b41786a220b28020020094b0d000b200a41016a210b0c030b200b200141f485cc001042000b20072001418486cc001042000b4100210b0b2000200b4103746a210f0b200f200e3702000b200541016a21050240200120076b220a4102490d00200828020820082802004f0d002008290200210c20082008290208370200200841086a210f0240200a4103490d002008280210200ca722104f0d00200841106a21094103210b4102210d0340200d41037420086a220f41786a2009290200370200200b200a4f0d01200b4103742109200b210d200b41016a210b200820096a22092802002010490d000b0b200f200c3702000b20054105470d000b4100210a0b200a0bcc5e010c7f230041a0016b22032400200320013602242002280208220441546a2105200241106a280200220641306c21010240024002400240024002400240024002400240024003402001450d01200141506a21012005412c6a2107200541306a2208210520072d00004104470d000b200641306c2101200441546a210503402001450d02200141506a21012005412c6a2107200541306a2209210520072d0000410c470d000b200641306c2101200441546a210503402001450d03200141506a21012005412c6a2107200541306a2204210520072d00004102470d000b0240410028028cb54c4105490d00200341013602442003200341246a3602404100280298b54c21014100280294b54c21054100280290b54c210720034198016a41980136020020034190016a42ee808080103703002003418c016a41b88acc0036020020034184016a422537020020034180016a41ee8bcc00360200200341f8006a4201370300200341e8006a4201370300200341e0006a410a360200200341f4006a200341c0006a360200200341c888cc00360264200341e48bcc0036025c20034105360258200541aca2c000200741024622071b200341d8006a200141c4a2c00020071b2802101102000b200341186a200810bf03200328021c200328022422014d0d03200328021820014102746a2201450d03200341106a200410bf032003280214200128020022014d0d04200328021020014104746a2201450d04200941086a280200200328022422054d0d0820092802002109200341286a41086a420037030020034280808080c00037032820012d000d2101410021072003410036024820032001410447220a3602442003200a360240200341003a004c410028028cb54c41044b0d05200341d8006a41086a200341c0006a41086a29030037030020032003290340370358200341286a410472210b200341d8006a21010c060b411310332201450d082001410f6a41002800a3884c360000200141086a410029009c884c37000020014100290094884c370000200041086a4293808080b00237020020002001360204200041013602000c090b410f10332201450d07200141076a41002900ae884c370000200141002900a7884c370000200041086a428f808080f00137020020002001360204200041013602000c080b410f10332201450d06200141076a41002900bd884c370000200141002900b6884c370000200041086a428f808080f00137020020002001360204200041013602000c070b412510332201450d052001411d6a41002900ed884c370000200141186a41002900e8884c370000200141106a41002900e0884c370000200141086a41002900d8884c370000200141002900d0884c370000200041086a42a5808080d00437020020002001360204200041013602000c060b412510332201450d042001411d6a41002900ed884c370000200141186a41002900e8884c370000200141106a41002900e0884c370000200141086a41002900d8884c370000200141002900d0884c370000200041086a42a5808080d00437020020002001360204200041013602000c050b200341c0003602542003200341c0006a3602504100280298b54c21014100280294b54c21074100280290b54c210820034198016a41cb0036020020034190016a42ee808080103703002003418c016a41b88acc0036020020034184016a422537020020034180016a41ee8bcc00360200200341f8006a4201370300200341e8006a4201370300200341d8006a41086a2206410a360200200341f4006a200341d0006a360200200341f888cc00360264200341e48bcc0036025c20034105360258200741aca2c000200841024622081b200341d8006a200141c4a2c00020081b28021011020020032802342108200328023021072006200341c0006a41086a29030037030020032003290340370358200341286a410472210b200341d8006a210120082007470d010b200b20074101108c01200328023421080b200b28020020084104746a22072001290200370200200741086a200141086a2902003702002003200328023441016a3602344100210702402009200541186c6a2201280214450d002009200541186c6a410c6a2109200141146a2108200341d8006a410472210c41002107410021010240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240034002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200328022820074d0d00200341d8006a200341286a410010dd0720032802584101460d0120072003280228200328025c2d000c1b21070b2001200828020022054f0d1e2003200928020020014104746a220536023c0240410028028cb54c4105490d002003413936024420032003413c6a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341c90136029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc0036028001200342013703782003420137036820034188b2cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328023c21050b20052d000022060eac01031b0101011b020405060708090a0b0c0d0e0f10111111111111111111111111111112121212121212121213141515151516171717171717171717171617171717171717171717171717171717171717171717181818191919191919191919191919191919181818191919191919191919191919191919181818181818181919191919191918181818181818191919191919191a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a030b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c340b20052d000121052003200328022836024820032005410447220536024020032006410347200571360244200341003a004c0240410028028cb54c4105490d00200341c0003602542003200341c0006a3602504100280298b54c21054100280294b54c21064100280290b54c210d200341cb0036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341f888cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341d0006a360274200641aca2c000200d1b200341d8006a20051102000b200341d8006a41086a2206200341c0006a41086a290300370300200320032903403703580240200328023422052003280230470d00200b20054101108c01200328023421050b200b28020020054104746a22052003290358370200200541086a20062903003702002003200328023441016a3602340c190b0240410028028cb54c4105490d00200b2802002105200341c10036025420032005200328023422064104746a41706a410020061b3602402003200341c0006a3602504100280298b54c21054100280294b54c21064100280290b54c210d200341d30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341a889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341d0006a360274200641aca2c000200d1b200341d8006a20051102000b024020032802342205450d0020032005417f6a2205360234200b28020020054104746a22052d000c4102460d00200528020021062003200528020822053602400240410028028cb54c4105490d00200341013602542003200341c0006a3602504100280298b54c21054100280294b54c210d4100280290b54c210e200341db0036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b089cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200e410246220e1b28021021052003200341d0006a360274200d41aca2c000200e1b200341d8006a2005110200200328024021050b20032005360228200320063602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a200511020020032802282105200328025021060b0240200520066a22062005490d00200320063602280c1a0b410e10332201450d36200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c330b411710332201450d352001410f6a41002900dd894c370000200141086a41002900d6894c370000200141002900ce894c370000200041086a4297808080f00237020020002001360204200041013602000c320b0240410028028cb54c4105490d004100280298b54c21054100280294b54c21064100280290b54c210d200341c10036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc003602800120034200370378200341b0b4cc0036027420034201370368200341e889cc003602642003410a360260200341e48bcc0036025c20034105360258200641aca2c000200d410246220d1b200341d8006a200541c4a2c000200d1b2802101102000b024020032802342205450d002005410474200b2802006a417c6a41013a00000c180b411710332201450d342001410f6a41002900dd894c370000200141086a41002900d6894c370000200141002900ce894c370000200041086a4297808080f00237020020002001360204200041013602000c310b200341d8006a200341286a200541046a28020010dd0720032802584101460d1a200341d8006a200341286a200328025c28020410df0720032802580d1b0240410028028cb54c4105490d004100280298b54c21054100280294b54c21064100280290b54c210d200341c10036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc003602800120034200370378200341b0b4cc0036027420034201370368200341e889cc003602642003410a360260200341e48bcc0036025c20034105360258200641aca2c000200d410246220d1b200341d8006a200541c4a2c000200d1b2802101102000b024020032802342205450d002005410474200b2802006a417c6a41013a00000c170b411710332201450d332001410f6a41002900dd894c370000200141086a41002900d6894c370000200141002900ce894c370000200041086a4297808080f00237020020002001360204200041013602000c300b200341d8006a200341286a200541046a28020010dd0720032802584101460d1b200341d8006a200341286a200328025c280204220510df0720032802580d1c200341d8006a200341286a410110df0720032802580d1d200320053602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c160b410e10332201450d32200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c2f0b200341d8006a200341286a200541046a28020028020810dd0720032802584101460d1d200328025c280204210d2005280204220628020441027421052006280200210602400340024020050d00200341d8006a200341286a200d10df0720032802580d220240410028028cb54c4105490d004100280298b54c21054100280294b54c21064100280290b54c210d200341c10036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc003602800120034200370378200341b0b4cc0036027420034201370368200341e889cc003602642003410a360260200341e48bcc0036025c20034105360258200641aca2c000200d410246220d1b200341d8006a200541c4a2c000200d1b2802101102000b20032802342205450d022005410474200b2802006a417c6a41013a00000c170b200341d8006a200341286a200628020010dd0720032802584101460d202005417c6a2105200641046a2106200328025c280204200d460d000b412710332201450d322001411f6a410029008f8a4c370000200141186a41002900888a4c370000200141106a41002900808a4c370000200141086a41002900f8894c370000200141002900f0894c370000200041086a42a7808080f00437020020002001360204200041013602000c2f0b411710332201450d312001410f6a41002900dd894c370000200141086a41002900d6894c370000200141002900ce894c370000200041086a4297808080f00237020020002001360204200041013602000c2e0b200341d8006a200341286a200a10df0720032802580d1f0240410028028cb54c4105490d004100280298b54c21054100280294b54c21064100280290b54c210d200341c10036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc003602800120034200370378200341b0b4cc0036027420034201370368200341e889cc003602642003410a360260200341e48bcc0036025c20034105360258200641aca2c000200d410246220d1b200341d8006a200541c4a2c000200d1b2802101102000b024020032802342205450d002005410474200b2802006a417c6a41013a00000c140b411710332201450d302001410f6a41002900dd894c370000200141086a41002900d6894c370000200141002900ce894c370000200041086a4297808080f00237020020002001360204200041013602000c2d0b200341d8006a200541046a280200200210e00720032802584101460d1f200341d8006a200341286a200328025c220528020810df0720032802580d20200320052d000d41044722053602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c130b410e10332201450d2f200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c2c0b200341086a200410bf0302400240200328020c200541046a28020022054d0d002003280208220620054104746a220d450d00200341d8006a200341286a200620054104746a28020810df0720032802580d222003200d2d000d41044722053602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b2003280228220620056a22052006490d01200320053602280c130b410e10332201450d2f200141066a410029009d8a4c370000200141002900978a4c370000200041086a428e808080e00137020020002001360204200041013602000c2c0b410e10332201450d2e200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c2b0b200341d8006a200341286a410110df072003280258450d1020002003290358370204200041013602002000410c6a200341e0006a2802003602000c2a0b200341d8006a200341286a410210df0720032802580d1f41012105200341d8006a200341286a410110df0720032802580d20200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c100b410e10332201450d2c200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c290b41012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c0f0b410e10332201450d2b200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c280b200341d8006a200341286a410110df072003280258450d0d20002003290358370204200041013602002000410c6a200341e0006a2802003602000c270b41012105200341d8006a200341286a410110df0720032802580d1e200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c0d0b410e10332201450d29200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c260b41012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c0c0b410e10332201450d28200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c250b200341d8006a200341286a410110df072003280258450d0a20002003290358370204200041013602002000410c6a200341e0006a2802003602000c240b41012105200341d8006a200341286a410110df0720032802580d1c200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c0a0b410e10332201450d26200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c230b200341d8006a200341286a410210df072003280258450d0820002003290358370204200041013602002000410c6a200341e0006a2802003602000c220b41012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c080b410e10332201450d24200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c210b41012105200341d8006a200341286a410110df0720032802580d1a200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c070b410e10332201450d23200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c200b41012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c060b410e10332201450d22200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c1f0b41012105200341d8006a200341286a410110df0720032802580d19200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c050b410e10332201450d21200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c1e0b200341d8006a200341286a410210df0720032802580d1941012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c040b410e10332201450d20200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c1d0b41012105200341d8006a200341286a410110df0720032802580d19200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c030b410e10332201450d1f200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c1c0b200341d8006a200341286a410210df0720032802580d1941012105200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b02402003280228220620056a22052006490d00200320053602280c020b410e10332201450d1e200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c1b0b41012105200341d8006a200341286a410110df0720032802580d19200341013602500240410028028cb54c4105490d00200341013602442003200341d0006a3602404100280298b54c21054100280294b54c21064100280290b54c210d200341e30036029801200342ee8080801037039001200341b88acc0036028c012003422537028401200341ee8bcc00360280012003420137037820034201370368200341b889cc003602642003410a360260200341e48bcc0036025c20034105360258200541c4a2c000200d410246220d1b28021021052003200341c0006a360274200641aca2c000200d1b200341d8006a2005110200200328025021050b2003280228220620056a22052006490d02200320053602280b200141016a22012008280200490d000c1a0b0b410e10332201450d1a200141066a41002900c6894c370000200141002900c0894c370000200041086a428e808080e00137020020002001360204200041013602000c170b2001200541a88acc001042000b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c150b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c140b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c130b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c120b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c110b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c100b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c0f0b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c0e0b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c0d0b200041013602002000200c2902003702042000410c6a200c41086a2802003602000c0c0b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c0b0b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c0a0b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c090b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c080b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c070b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c060b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c050b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c040b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c030b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c020b20002003290358370204200041013602002000410c6a200341e0006a2802003602000c010b20002003290358370204200041013602002000410c6a200341e0006a2802003602000b200328023041ffffffff0071450d03200b28020010350c030b2000410036020020002007360204200328023041ffffffff0071450d02200b28020010350c020b412710332201450d002001411f6a410029009f894c370000200141186a4100290098894c370000200141106a4100290090894c370000200141086a4100290088894c37000020014100290080894c370000200041086a42a7808080f00437020020002001360204200041013602000c010b1045000b200341a0016a24000bc20201027f230041106b220224002001280218418b85cc0041052001411c6a28020028020c1100002103200241003a0005200220033a00042002200136020020022000410c6a36020c2002419085cc00410e2002410c6a41a085cc00106921012002200036020c200141b085cc0041092002410c6a41bc85cc00106921012002200041046a36020c200141cc85cc00410c2002410c6a41bc85cc00106921012002200041086a36020c200141d885cc00410c2002410c6a41bc85cc0010691a20022d00042100024020022d0005450d00200041ff0171210141012100024020010d0020022802002200411c6a28020028020c210120002802182103024020002d00004104710d00200341d0a0c0004102200111000021000c010b200341d2a0c0004101200111000021000b200220003a00040b200241106a2400200041ff01714100470b8d0201027f024002400240024002402001410c6a2802002203417f6a220420034b0d00200420026b220220044b0d01200320024d0d032000200128020420024104746a360204200041003602000f0b411610332201450d01200020013602042001410e6a41002900c98c4c370000200141086a41002900c38c4c370000200141002900bb8c4c370000200041086a4296808080e0023702000c030b411b10332201450d0020002001360204200141176a41002800fb8c4c360000200141106a41002900f48c4c370000200141086a41002900ec8c4c370000200141002900e48c4c370000200041086a429b808080b0033702000c020b1045000b2002200341d48ccc001042000b200041013602000bba0201037f230041106b220224000240024020002802000d002002200128021841ee8fcc0041042001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b2002200128021841ea8fcc0041042001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a41f48fcc00106f210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841d6a0c00041012004411c6a28020028020c1100000d010b2001280200220028021841cca6cc0041012000411c6a28020028020c11000021000b200120003a00080b200241106a2400200041ff01714100470bcd0401037f230041e0006b220324002003200236020c0240410028028cb54c4105490d002003410136021420032003410c6a3602104100280298b54c21024100280294b54c21044100280290b54c2105200341d8006a41ef00360200200341d0006a42ee80808010370300200341cc006a41b88acc00360200200341c4006a4225370200200341c0006a41ee8bcc00360200200341386a4201370300200341286a4201370300200341206a410a360200200341346a200341106a360200200341a88bcc00360224200341e48bcc0036021c20034105360218200441aca2c000200541024622051b200341186a200241c4a2c00020051b280210110200200328020c21020b0240024002400240024002402002450d00200341186a2001410010dd0720032802184101460d0120012802002202200328021c2204280208460d022002200328020c6b220420024b0d0320004100360200200120043602000c050b200041003602000c040b2000200341186a4104722202290200370200200041086a200241086a2802003602000c030b024020042d000c0d00412510332202450d02200042a5808080d004370204200020023602002002411d6a41002900cd8b4c370000200241186a41002900c88b4c370000200241106a41002900c08b4c370000200241086a41002900b88b4c370000200241002900b08b4c3700000c030b200041003602000c020b410f10332202450d002000428f808080f00137020420002002360200200241076a41002900dc8b4c370000200241002900d58b4c3700000c010b1045000b200341e0006a24000bb107010a7f230041e0006b22032400200320013602202002280208220441546a2105200241106a280200220641306c210202400340024020020d00410021070c020b200241506a21022005412c6a2107200541306a2208210520072d00004102470d000b200341186a200810bf0320032802182107200328021c21020b2002410020071b2109200641306c2102200441546a2105200741b0b4cc0020071b210a02400340024020020d004100210b0c020b200241506a21022005412c6a2107200541306a2208210520072d00004104470d000b200341106a200810bf032003280210210b2003280214210c0b200641306c2102200441546a210502400240024002400240024002400240024003402002450d01200241506a21022005412c6a2107200541306a2208210520072d00004103470d000b200841086a2802002202450d00200241286c2107200828020041186a2102410021050340200520022d0000456a2105200241286a2102200741586a22070d000b200520014d0d01200641306c2102200441546a210503402002450d07200241506a21022005412c6a2107200541306a2208210520072d00004103470d000b200341086a200810bf03200328020c220441286c210520032802082206210703402005450d08200541586a2105200741186a2108200741286a2202210720082d00000d000b20010d02200241586a21020c030b410021050b0240200c4100200b1b200120056b22024d0d00200b41b0b4cc00200b1b20024102746a22020d030b200341dc006a41013602002003420237024c200341d093cc003602482003410136022c2003200341286a3602582003200341206a360228200341386a200341c8006a1041200341386a21020c030b2006200441286c6a210803402001417f6a2101034020082002460d06200241186a2105200241286a2207210220052d00000d000b2007210220010d000b200741586a21020b2002411c6a21020b2003200228020022023602240240200920024d0d00200a20024104746a2202450d0020002002360204410021020c040b200341dc006a4102360200200341c4006a41013602002003420337024c200341e093cc003602482003410136023c2003200341386a3602582003200341206a3602402003200341246a360238200341286a200341c8006a1041200341286a21020b20022802002105200041086a200229020437020020002005360204410121020c020b419e92cc0041c20041e092cc001064000b41f092cc0041dd0041e092cc001064000b20002002360200200341e0006a24000bec0201087f024020002802002201450d0020002802082102024020002802042200450d00034020012802940321012000417f6a22000d000b0b02402002450d0041002103024003402001450d01410021040240200320012f0106490d00034002400240200128020022000d0041002103410021000c010b200441016a210420012f010421030b2001103520002101200320002f01064f0d000b200021010b200341016a2105200120034105746a220041c4006a2802002106200041386a2802002107200041346a28020021080240024020040d00200521030c010b200120054102746a4194036a2802002101410021032004417f6a2200450d00034020012802940321012000417f6a22000d000b0b20064102460d022002417f6a210202402007450d00200810350b20020d000c020b0b41958dcc00412b41c08dcc00103f000b2001450d0020012802002100200110352000450d00034020002802002101200010352001210020010d000b0b0b2600024020002802002d00000d002001419d9fc0004105105a0f0b200141a29fc0004104105a0b8c0902047f017e230041106b2202240002400240024020010d00200041ac013a00000c010b024002400240024020012d00002203414f6a41fb004f0d000c010b02400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020030e312c2c0001022c2c0304052c06072c2c08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292c0b20012d00012104410221030c2b0b20012d00012104410321030c2a0b20012d00012104410421030c290b200141046a2802002105410721030c270b200141046a2802002105410821030c260b200141046a2802002101410c10332205450d28200241086a2001280200200141046a28020010d607200229030821062005200128020836020820052006370200410921030c250b200141046a2802002105410b21030c240b200141046a280200210520012d00012104410c21030c240b200141046a2802002105410f21030c220b200141046a2802002105411021030c210b200141046a2802002105411121030c200b200141046a2802002105411221030c1f0b200141046a2802002105411321030c1e0b200141046a280200210520013502082106411421030c1d0b200141046a280200210520013502082106411521030c1c0b200141046a280200210520013502082106411621030c1b0b200141046a280200210520013502082106411721030c1a0b200141046a280200210520013502082106411821030c190b200141046a280200210520013502082106411921030c180b200141046a280200210520013502082106411a21030c170b200141046a280200210520013502082106411b21030c160b200141046a280200210520013502082106411c21030c150b200141046a280200210520013502082106411d21030c140b200141046a280200210520013502082106411e21030c130b200141046a280200210520013502082106411f21030c120b200141046a280200210520013502082106412021030c110b200141046a280200210520013502082106412121030c100b200141046a280200210520013502082106412221030c0f0b200141046a280200210520013502082106412321030c0e0b200141046a280200210520013502082106412421030c0d0b200141046a280200210520013502082106412521030c0c0b200141046a280200210520013502082106412621030c0b0b200141046a280200210520013502082106412721030c0a0b200141046a280200210520013502082106412821030c090b200141046a280200210520013502082106412921030c080b200141046a280200210520013502082106412a21030c070b20012d00012104412b21030c070b20012d00012104412c21030c060b200141046a2802002105412d21030c040b20012903082106412e21030c020b200141046a2802002105412f21030c020b20012903082106413021030b0b0b200020043a0001200020033a0000200041086a2006370300200041046a20053602000b200241106a24000f0b103c000bc60501087f230041106b220324002002280208220441546a2105200241106a280200220641306c210702400340410021082007450d01200741506a21072005412c6a2109200541306a220a210520092d00004103470d000b200a41086a2802002207450d00200741286c2105200a28020041186a2107410021080340200820072d0000456a2108200741286a2107200541586a22050d000b0b024002400240024002400240200120086b220a20014b0d00200641306c2107200441546a210503402007450d02200741506a21072005412c6a2108200541306a2209210520082d0000410c470d000b200941086a280200200a4b0d03411e10332207450d052000200736020420004101360200200741166a4100290096924c370000200741106a4100290090924c370000200741086a4100290088924c37000020074100290080924c370000200041086a429e808080e0033702000c040b412c103322070d010c040b412c10332207450d032000200736020420004101360200200741286a41002800fc914c360000200741206a41002900f4914c370000200741186a41002900ec914c370000200741106a41002900e4914c370000200741086a41002900dc914c370000200741002900d4914c370000200041086a42ac808080c0053702000c020b2000200736020420004101360200200741286a41002800d0914c360000200741206a41002900c8914c370000200741186a41002900c0914c370000200741106a41002900b8914c370000200741086a41002900b0914c370000200741002900a8914c370000200041086a42ac808080c0053702000c010b2009280200200a41186c6a28020821072003200a200210db07024020032802004101470d0020002003290204370204200041013602002000410c6a2003410c6a2802003602000c010b20032802042105200041003602002000200520076a3602040b200341106a24000f0b1045000b100020002802003502004101200110520b8903010a7f230041206b220124000240024002400240200041086a2802002202450d00410020024102746b2103417f210420002802002205210603402003450d01200441016a2104200341046a210320062802002107200641046a21062007450d000b4100200741004741016a41017122066b2004460d002002200620046a2208490d012002200741004741016a4101716b20046b220641ffffffff03712006470d0220064102742209417f4c0d024104210a02402009450d0020091033220a450d040b200141003602182001200a36021020012009410276360214200141106a410020061086012001280210200128021822064102746a200520084102746a4104200741004741016a410171220741027420036a6b109d081a200141086a22032002200620076b6a20046b360200200120012903103703000240200041046a28020041ffffffff0371450d00200028020010350b20002001290300370200200041086a20032802003602000b200141206a24000f0b2008200241cc95cc001059000b1044000b1045000bb90403077f017e097f02400240024002400240200141086a2802002203200241086a2802002204200320044b1b220541016a22064101200641014b1b220741ffffffff03712007470d0020074102742208417f4c0d00200810392209450d01024020050d004200210a0c040b2004417f6a220b20044b210c2002280200210d2003417f6a220e20034b0d022001280200210f2007417f6a2102200820096a417c6a2110410021064200210a03404100211102402003200e20066b22124d0d00410021112012200e4b0d00200f20124102746a28020021110b410021120240200c0d002004200b20066b22134d0d002013200b4b0d00200d20134102746a28020021120b200720024d0d052010200a2011ad7c2012ad7c220a3e02002010417c6a21102002417f6a2102200a422088210a200641016a22062005490d000c040b0b1044000b1045000b2007417f6a2102200820096a417c6a2111410021104200210a0340410021060240200c0d00410021062004200b20106b22124d0d00410021062012200b4b0d00200d20124102746a28020021060b200720024d0d022011200a2006ad7c220a3e02002011417c6a21112002417f6a2102200a422088210a201041016a22102005490d000b0b024020072005417f736a220220074f0d00200020073602082000200841027636020420002009360200200920024102746a200a3e02000240200141046a28020041ffffffff0371450d00200128020010350b0f0b2002200741bc95cc001042000b2002200741bc95cc001042000bb404030e7f017e017f02400240200241086a2802002203200141086a28020022046a22054101200541014b1b220641ffffffff03712006470d0020064102742207417f4c0d000240200710392208450d002004450d022001280200210902400240024020030d002006417f6a2105200720086a417c6a210a20092004417f6a22024102746a21030340200420024d0d0302402003280200450d00200620054d0d03200a41003602000b2003417c6a2103200a417c6a210a2005417f6a21052002417f6a2202417f470d000c060b0b200720086a417c6a210b200341027420022802006a417c6a210c4100210d2006210e03402004200d417f736a220220044f0d020240200920024102746a220f2802002210450d0042002111417f2102200b2105200c210a024003402006200e20026a22124d0d012005200a3502002010ad7e20117c20053502007c22113e0200201142208821110240200320026a0d002006200d20036a417f736a220520064f0d05200820054102746a20113e02000c030b2005417c6a2105200a417c6a210a200f280200211020032002417f6a22026a22122003490d000b2012200341ac95cc001042000b2012200641ac95cc001042000b200b417c6a210b200e417f6a210e200d41016a220d2004460d050c000b0b2005200641bc95cc001042000b2002200441ac95cc001042000b1045000b1044000b2000200636020820002007410276360204200020083602000240200141046a28020041ffffffff0371450d00200128020010350b0bca0302097f017e230041106b2201240002400240024002400240024002402000280200220228020041016a41004c0d002000280204220328020041016a41004c0d012000280208220441086a28020022054101200028020c22062802006b22076a220820054f0d02200720002802142802006b22052000280210220741086a28020022006a220920054f0d03024002402002290308220a42ffffffff0f560d0041002100200a200428020020084102746a3502007e2003290308422086200728020020094102746a35020084580d010b20022802000d052002410036020020022002290308427f7c370308200441086a2802002200200020062802006b22024d0d0620032802000d07200428020020024102746a350200210a200341003602002003200a20032903087c370308410121000b200141106a240020000f0b41ac96cc004118200141086a41c496cc0041d496cc001046000b41ac96cc004118200141086a41c496cc0041d496cc001046000b2008200541ac95cc001042000b2009200041ac95cc001042000b41a797cc004110200141086a41b897cc0041c897cc001046000b2002200041ac95cc001042000b41a797cc004110200141086a41b897cc0041c897cc001046000ba80301087f200028020822024102742103410021042000280200220521000240024003402003450d012004417f6a21042003417c6a210320002802002106200041046a21002006450d000b410121072004417f73200641004741016a4101716a21080c010b41002107410020046b21080b200128020822094102742103410021042001280200220121000240024003402003450d012004417f6a21042003417c6a210320002802002106200041046a21002006450d000b410021032004417f73200641004741016a4101716a21000c010b410020046b2100410121030b024020070d00410020034101736b0f0b4101210402400240024020030d0020022008490d0120092000490d02417f200220086b2203200920006b22064720032006491b22040d0020062003200320064b1b2107200120004102746a2103200520084102746a2100417f210103400240200141016a22012007490d0041000f0b2003280200210420002802002106200341046a2103200041046a2100417f200620044720062004491b2204450d000b0b20040f0b2008200241dc95cc001059000b2000200941ec95cc001059000b100020002802002000280204200110720bcd04010a7f230041106b220224002002410036020820024204370300200128000c2103410021040240024002400240024002400240024020012802042205200128020022064920012d00084100477222010d004100200520066b2204200420054b1b220741016a220420074f0d00200341086a21084100210441042109410021010340200828020022072005417f736a220a20074f0d02200620054f2107200520062005496b21052003280200200a4102746a280200210a024020012002280204470d0020022001417f41004100417f4100200520066b2209200920054b1b220941016a220b200b2009491b20071b20052006491b220941016a220b200b2009491b108601200228020021090b200920046a200a3602002002200141016a2201360208200441046a21042005200649200772450d000c070b0b2002410020041086012002280208210b20010d042002280200200b4102746a2104200520064d0d012005417f732101200341086a21092005210703402001200928020022086a220a20014f0d0320042003280200200a4102746a280200360200200141016a2101200441046a210420062007417f6a2207490d000b200520066b200b6a210b0c030b200a200741ac95cc001042000b20052006460d010c020b200a200841ac95cc001042000b200341086a28020022052006417f736a220620054f0d022004200328020020064102746a280200360200200b41016a210b0b2002200b3602080b20002002290300370200200041086a200241086a280200360200200241106a24000f0b2006200541ac95cc001042000b1c00200128021841ed9dcc00410f2001411c6a28020028020c1100000bb00301047f230041c0006b2202240020002802002103410121000240200128021841e29ec000410c2001411c6a28020028020c1100000d0002400240200328020822000d0020032802002200200328020428020c11070042e4aec285979ba58811520d012002200036020c2002413b36021420022002410c6a36021020012802182104200128021c2105410121002002413c6a41013602002002420237022c200241f09ec0003602282002200241106a36023820042005200241286a10430d020c010b2002200036020c2002410836021420022002410c6a36021020012802182104200128021c2105410121002002413c6a41013602002002420237022c200241f09ec0003602282002200241106a36023820042005200241286a10430d010b200328020c2100200241106a41146a4101360200200241106a410c6a410136020020022000410c6a3602202002200041086a360218200241043602142002200036021020012802182100200128021c2101200241286a41146a41033602002002420337022c200241809fc0003602282002200241106a36023820002001200241286a104321000b200241c0006a240020000b21002000417f6a41ff01712002ad4220862001ad842004ad4220862003ad8410000b1c00200128021841ed9dcc00410f2001411c6a28020028020c1100000b1c00200128021841ed9dcc00410f2001411c6a28020028020c1100000b9a0601037f230041d0006b22042400200420033a000f02400240024020022802082205450d00200141086a2802002106200541037420022802006a41786a220528020021020240024020052d0006450d0020062002460d010b024002400240200620024d0d00200141086a2006417f6a2202360200200128020020026a2d00002201417c6a220241014b0d0220020e020301030b412b10332202450d04200041013a0000200241276a41002800e5a94c360000200241206a41002900dea94c370000200241186a41002900d6a94c370000200241106a41002900cea94c370000200241086a41002900c6a94c370000200241002900bea94c370000200041086a42ab808080b005370200200041046a20023602000c050b411810332202450d03200241106a410029008eb04c370000200241086a4100290086b04c370000200241002900feaf4c37000020044298808080800337022420042002360220200441c4006a410136020020044201370234200441acaacc003602302004413836024c2004200441c8006a3602402004200441206a360248200441106a200441306a104102402004280224450d00200428022010350b200041013a0000200041046a20042903103702002000410c6a200441106a41086a2802003602000c040b02400240200341ff017122024104460d0020012002470d010b200041003a0000200020013a00010c040b200420013a0048200441c4006a4102360200200441206a410c6a413d36020020044202370234200441eca9cc003602302004413d3602242004200441206a3602402004200441c8006a36022820042004410f6a360220200441106a200441306a10412000410c6a200441186a280200360200200041046a2004290310370200200041013a00000c030b20004180083b01000c020b2004411810fb072004410036023820042004290300370330200441306a4100411810fc0720042802302202200428023822006a411841feafcc00411810fd072004200041186a360238200420042902343702342004200236023041d4a4cc004134200441306a41b4a4cc004188a5cc001046000b1045000b200441d0006a24000be40502047f017e230041d0006b220324000240024002400240024002400240200241086a2802002204450d00200228020022052004417f6a22044103746a2d000522064104460d02200341386a20012002200610f20720032d00384101470d012000200329023c370200200041086a200341c4006a2802003602000c060b411810332202450d04200241106a410029008eb04c370000200241086a4100290086b04c370000200241002900feaf4c37000020034298808080800337021420032002360210200341cc006a41013602002003420137023c200341acaacc00360238200341383602342003200341306a3602482003200341106a360230200341206a200341386a1041200041086a200341206a41086a280200360200200020032903203702002003280214450d05200328021010350c050b200241086a2802002204450d012004417f6a2104200228020021050b200241086a2004360200200520044103746a290200220742808080808080c0ff0083428080808080808001510d00200141086a28020021022003200737030820022007a7470d01200041003602000c030b411810332202450d01200241106a410029008eb04c370000200241086a4100290086b04c370000200241002900feaf4c37000020034298808080800337021420032002360210200341cc006a41013602002003420137023c200341acaacc00360238200341383602342003200341306a3602482003200341106a360230200341206a200341386a1041200041086a200341206a41086a280200360200200020032903203702002003280214450d02200328021010350c020b200341cc006a41023602002003412c6a41013602002003420237023c200341aca8cc0036023820034101360224200320023602302003200341206a3602482003200341086a3602282003200341306a360220200341106a200341386a1041200041086a200341106a41086a280200360200200020032903103702000c010b1045000b200341d0006a24000bef0302037f017e230041c0006b22042400200441286a20012002200310f2070240024002400240024020042d00284101460d0002400240200141086a2802002202200128020c4f0d0002402002200141046a280200470d00200241016a22052002490d05200241017422062005200620054b1b22054100480d050240024020020d002005103322060d010c090b2001280200210620022005460d0020062002200510372206450d080b20012006360200200141046a2005360200200141086a28020021020b200128020020026a20033a0000200141086a2201200128020041016a3602000c010b2004413c6a220341013602002004420137022c200441e8b1cc003602282004410136021420042001410c6a3602102004200441106a360238200441186a200441286a104120042802182201450d002004200429021c37020420042001360200200341013602002004420137022c200441acaacc00360228200441383602142004200441106a36023820042004360210200441186a200441286a104120042802182101200429021c210702402004280204450d00200428020010350b20010d020b200041003602000c030b2000200429022c370200200041086a200441346a2802003602000c020b20002007370204200020013602000c010b103e000b200441c0006a24000f0b103c000ba80301057f230041c0006b2203240020032002360200024002402001280204220420024b0d002001280208417c6a21052001410c6a280200410374210102400340024020010d00200320043602042003412c6a4102360200200341306a410c6a41013602002003420337021c200341c8b2cc00360218200341013602342003200341306a3602282003200341046a36023820032003360230200341086a200341186a10412000410c6a200341106a280200360200200041046a2003290308370200200041013a00000c040b2004200541046a2802006a22062004490d01200141786a2101200541086a2105200420024b21072006210420070d0020062104200620024d0d000b20052d00002104200041003a0000200020043a00010c020b0240412010332204450d00200041013a0000200441186a41002900c0b24c370000200441106a41002900b8b24c370000200441086a41002900b0b24c370000200441002900a8b24c370000200041086a42a08080808004370200200041046a20043602000c020b1045000b200041003a00002000200128020020026a2d00003a00010b200341c0006a24000bbd0201037f230041106b220224000240024020002d00004104470d002002200128021841a0a7cc0041032001411c6a28020028020c11000022003a000820022001360200200241003a0009200241003602040c010b200220012802184185a7cc0041082001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a4190a7cc00106f210120022d0008210020022802042203450d00200041ff0171210441012100024020040d00024020034101470d0020012d0009450d00200128020022042d00004104710d0041012100200428021841d6a0c00041012004411c6a28020028020c1100000d010b2001280200220028021841cca6cc0041012000411c6a28020028020c11000021000b200120003a00080b200241106a2400200041ff01714100470b930602037f017e230041d0006b22052400200520023602082005200336020c024002400240417f41012002411f71742002411f4b1b20034b0d00200541386a200141186a2203200141286a410010f20720052d00384101470d012000200529023c370200200041086a200541c4006a2802003602000c020b200541cc006a41023602002005411c6a41013602002005420337023c20054184a6cc00360238200541013602142005200541106a36024820052005410c6a3602182005200541086a360210200541206a200541386a1041200041086a200541206a41086a280200360200200020052903203702000c010b200128020021022005410036022002400240024020022802080d00200541cc006a41013602002005420237023c200541fcadcc00360238200541013602342005200541306a3602482005200541206a360230200541106a200541386a1041200528021022020d010b0240024002400240200141206a2802002202200141246a22062802004f0d00024020022001411c6a280200470d00200241016a22062002490d04200241017422072006200720064b1b22064100480d040240024020020d002006103322030d010c080b2003280200210320022006460d0020032002200610372203450d070b200120033602182001411c6a2006360200200141206a28020021020b200128021820026a20043a0000200141206a2202200228020041016a3602000c010b200541cc006a220241013602002005420137023c200541e8b1cc0036023820054101360234200520063602302005200541306a360248200541106a200541386a104120052802102201450d002005200529021437022420052001360220200241013602002005420137023c200541acaacc00360238200541383602342005200541306a3602482005200541206a360230200541106a200541386a1041200528021021022005290214210802402005280224450d00200528022010350b20020d010b200041003602000c040b20002008370204200020023602000c030b103e000b20002005290214370204200020023602000c010b103c000b200541d0006a24000bb00301017f230041d0006b22052400200520023602082005200336020c02400240024002400240417f41012002411f71742002411f4b1b20034b0d002001280200210220054100360234024020022802080d00200541cc006a41013602002005420237023c200541fcadcc00360238200541013602142005200541106a3602482005200541346a360210200541206a200541386a1041200528022022020d020b200541386a200141186a2202200141286a2203200410f20720052d00384101460d02200541386a20022003410010f20720052d00384101460d03200041003602000c040b200541cc006a41023602002005412c6a41013602002005420337023c20054184a6cc00360238200541013602242005200541206a36024820052005410c6a3602282005200541086a360220200541106a200541386a1041200041086a200541106a41086a280200360200200020052903103702000c030b20002005290224370204200020023602000c020b2000200529023c370200200041086a200541c4006a2802003602000c010b2000200529023c370200200041086a200541c4006a2802003602000b200541d0006a24000bb10402047f017e230041c0006b22032400200341286a200141186a2204200141286a2205200210f20702400240024020032d00284101460d00200341286a20042005200210f20720032d00284101470d012000200329022c370200200041086a200341346a2802003602000c020b2000200329022c370200200041086a200341346a2802003602000c010b02400240024002400240200141206a2802002202200141246a22052802004f0d00024020022001411c6a280200470d00200241016a22052002490d04200241017422062005200620054b1b22054100480d040240024020020d002005103322040d010c070b2004280200210420022005460d0020042002200510372204450d060b200120043602182001411c6a2005360200200141206a28020021020b200128021820026a41003a0000200141206a2201200128020041016a3602000c010b2003413c6a220141013602002003420137022c200341e8b1cc0036022820034101360214200320053602102003200341106a360238200341186a200341286a104120032802182202450d002003200329021c37020420032002360200200141013602002003420137022c200341acaacc00360228200341383602142003200341106a36023820032003360210200341186a200341286a104120032802182101200329021c210702402003280204450d00200328020010350b20010d010b200041003602000c030b20002007370204200020013602000c020b103e000b103c000b200341c0006a24000bb10402057f017e230041c0006b22032400200341286a200141186a2204200141286a2205200210f20702400240024020032d00284101460d00200341286a20042005200210f20720032d00284101470d012000200329022c370200200041086a200341346a2802003602000c020b2000200329022c370200200041086a200341346a2802003602000c010b02400240024002400240200141206a2802002205200141246a22062802004f0d00024020052001411c6a280200470d00200541016a22062005490d04200541017422072006200720064b1b22064100480d040240024020050d002006103322040d010c070b2004280200210420052006460d0020042005200610372204450d060b200120043602182001411c6a2006360200200141206a28020021050b200128021820056a20023a0000200141206a2201200128020041016a3602000c010b2003413c6a220141013602002003420137022c200341e8b1cc0036022820034101360214200320063602102003200341106a360238200341186a200341286a104120032802182202450d002003200329021c37020420032002360200200141013602002003420137022c200341acaacc00360228200341383602142003200341106a36023820032003360210200341186a200341286a104120032802182101200329021c210802402003280204450d00200328020010350b20010d010b200041003602000c030b20002008370204200020013602000c020b103e000b103c000b200341c0006a24000b3101017f0240024020010d0041002101410121020c010b2001103322020d001045000b20002002360200200020013602040b950101017f024002400240200041046a280200220320016b20024f0d00200120026a22022001490d01200341017422012002200120024b1b22014100480d010240024020030d00024020010d00410121020c020b2001103322020d010c040b2000280200210220032001460d0020022003200110372202450d030b20002002360200200041046a20013602000b0f0b103e000b103c000bea0101017f230041e0006b22042400200420013602082004200336020c024020012003470d00200020022001109d081a200441e0006a24000f0b200441286a41146a410a360200200441346a410c360200200441106a41146a41033602002004200441086a36024020042004410c6a360244200441c8006a41146a410036020020044203370214200441a0b3cc003602102004410c36022c200441b0b4cc003602582004420137024c200441f4b3cc003602482004200441286a3602202004200441c8006a3602382004200441c4006a3602302004200441c0006a360228200441106a41b0b4cc00104c000b17000240200041046a280200450d00200028020010350b0b1500200028020022002802002000280208200110720b1000200120002802002000280208105a0bfb0101027f230041106b22022400200220012802184190b2cc0041052001411c6a28020028020c1100003a000820022001360200200241003a0009200241003602042002200036020c20022002410c6a4198b2cc00106f1a20022d00082101024020022802042203450d00200141ff0171210041012101024020000d00024020034101470d0020022d000941ff0171450d00200228020022002d00004104710d0041012101200028021841d6a0c00041012000411c6a28020028020c1100000d010b2002280200220128021841cca6cc0041012001411c6a28020028020c11000021010b200220013a00080b200241106a2400200141ff01714100470b8a0202017f037e230041106b220524002001200210950842ffffffff0f832003200410950842ffffffff0f83108d082106200120021095084220882003200410950842ffffffff0f83108d0820064220887c220742208810890821082005200320041095084220882001200210950842ffffffff0f83108d08200742ffffffff0f837c2207422086200642ffffffff0f8384200820074220881089087c2001200210950842208820032004109508422088108d081089087c2001200210960820032004109508108908108d08108c082001200210950810890820032004109608108d08108c08109708200529030021032000200541086a29030037030820002003370300200541106a24000bdc0302017f057e230041f0006b2206240020054100360200200641e0006a2001200220032004109208200641e0006a41086a290300210720062903602108200641d0006a10910802400240024002402006290350200185200641d0006a41086a29030020028584500d00200641c0006a1091082006290340200385200641c0006a41086a29030020048584500d012002423f872209200185220120097d220a420254200920028520097d2001200954ad7d22014200532001501b0d032004423f872202200385220320027d220b420254200220048520027d2003200254ad7d22044200532004501b0d0320092002852202200284500d02200641306a109108200641206a2006290330200641306a41086a2903004200200b7d42002004200b420052ad7c7d109408200a2006290320562001200641206a41086a29030022025520012002511b450d03200541013602000c030b200342025441002004501b0d02200541013602000c020b200142025441002002501b0d01200541013602000c010b200641106a10900820062006290310200641106a41086a290300200b2004109408200a2006290300582001200641086a29030022025720012002511b0d00200541013602000b2000200837030020002007370308200641f0006a24000b3c01017f230041106b2205240020052001200220032004108208200529030021012000200541086a29030037030820002001370300200541106a24000b3e01017f230041106b22062400200620012002200320042005108308200629030021012000200641086a29030037030820002001370300200641106a24000b3c01017f230041106b2205240020052001200220032004109b08200529030021012000200541086a29030037030820002001370300200541106a24000b040000000b8c0202017f027e230041e0006b22052400200541d0006a2002423f872206200185200620028520062006109308200541d0006a41086a290300210120052903502107200541c0006a2004423f872202200385200220048520022002109308200541c0006a41086a290300210420052903402103200541306a20072001108e08200541306a41086a290300210120052903302107200541206a20032004108e08200541106a200720012005290320200541206a41086a290300108f0820052005290310200541106a41086a290300108e08200541086a2903002104200020052903002002200685220685220220067d3703002000200420068520067d2002200654ad7d370308200541e0006a24000b040020000b1500024020014200520d00108708000b20002001800b1500024020014200520d00108708000b20002001820b0700200120007c0b0700200120007e0b100020002002370308200020013703000b4901017f230041106b22052400024020032004844200520d00108708000b200520012002200320041098082000200541086a29030037030820002005290300370300200541106a24000b1900200042ffffffffffffffffff003703082000427f3703000b19002000428080808080808080807f370308200042003703000b3801017f230041106b22052400200520032004200120021084082000200541086a29030037030820002005290300370300200541106a24000b1d002000200120037d3703002000200220047d2001200354ad7d3703080b6a01017f230041106b22052400024002402003200484500d0020012002428080808080808080807f85844200520d012003200483427f520d010b108708000b20052001200220032004109c082000200541086a29030037030820002005290300370300200541106a24000b040020000b040020010b100020002002370308200020013703000b3c01017f230041106b2205240020052001200220032004109908200529030021012000200541086a29030037030820002001370300200541106a24000b3e01017f230041106b22052400200520012002200320044100109a08200529030021012000200541086a29030037030820002001370300200541106a24000bc00704017f027e027f047e230041d0006b22062400024002400240024002400240024002400240024020012002109608500d002003200410950821072003200410960821082007500d012008500d022003200410960879a72001200210960879a76b2209413f4b0d0341ff0020096b210a200941016a21090c080b024020032004109608500d0020050d040c060b02402005450d002001200210950820032004109508108b08210720054200370308200520073703000b2001200210950820032004109508108a0821010c060b2008500d0302400240024020012002109508500d00200320041096087b4201510d012003200410960879a72001200210960879a76b2209413e4b0d0241ff0020096b210a200941016a21090c090b02402005450d00200642002001200210960820032004109608108b08109708200629030021072005200641086a290300370308200520073703000b2001200210960820032004109608108a0821010c070b02402005450d00200641106a200120021095082001200210960820032004109608427f7c83109708200629031021072005200641186a290300370308200520073703000b20012002109608200320041096087a423f838821010c060b2005450d040c020b0240200320041095087b4201510d0041bf7f2003200410950879a72001200210960879a76b22096b210a200941c1006a21090c060b02402005450d0020012002109508210720032004109508210820054200370308200520072008427f7c833703000b200320041095084201510d06200641c0006a20012002200320041095087aa710a408200641c8006a2903002102200629034021010c060b2005450d020b2005200137030020052002370308420021010c020b108708000b420021010b420021020c010b200641206a20012002200a41ff007110a308200641306a20012002200941ff007110a408200641206a41086a2903002102200641306a41086a290300210b20062903202101200629033021070240024020090d00420021084200210c0c010b4200210c4200210d0340200b4201862007423f888422082008427f8520047c20074201862002423f88842207427f85220820037c200854ad7c423f8722082004837d20072008200383220e54ad7d210b2007200e7d2107420020024201862001423f8884842102200d200142018684210120084201832208210d2009417f6a22090d000b0b02402005450d00200520073703002005200b3703080b200c20024201862001423f8884842102200820014201868421010b2000200137030020002002370308200641d0006a24000b4c01017f230041206b22052400200542003703182005420037031020052001200220032004200541106a109a08200529031021012000200529031837030820002001370300200541206a24000b3c01017f230041106b2205240020052001200220032004108808200529030021012000200541086a29030037030820002001370300200541106a24000b3601017f02402002450d00200021030340200320012d00003a0000200341016a2103200141016a21012002417f6a22020d000b0b20000b7101017f0240024020012000490d002002450d01200021030340200320012d00003a0000200141016a2101200341016a21032002417f6a22020d000c020b0b2002450d002001417f6a21012000417f6a21030340200320026a200120026a2d00003a00002002417f6a22020d000b0b20000b2c01017f02402002450d00200021030340200320013a0000200341016a21032002417f6a22020d000b0b20000b4a01037f4100210302402002450d000240034020002d0000220420012d00002205470d01200041016a2100200141016a21012002417f6a2202450d020c000b0b200420056b21030b20030bac0102017f037e230041206b2204240002400240200341c000710d002003450d01200120021095082105200120021096082106200420052003413f71ad22078620012002109508410020036b413f71ad88200620078684109708200441086a2903002102200429030021010c010b200441106a4200200120021095082003413f71ad86109708200441186a2903002102200429031021010b2000200137030020002002370308200441206a24000b9e0102017f027e230041106b22042400024002400240200341c000710d002003450d02200120021096082105200120021095082003413f71ad2206882005410020036b413f71ad868421052001200210960820068821010c010b200120021096082003413f71ad882105420021010b200420052001109708200441086a2903002102200429030021010b2000200137030020002002370308200441106a24000b3a01017f230041106b22042400200420012002200310a108200429030021012000200441086a29030037030820002001370300200441106a24000b3a01017f230041106b22042400200420012002200310a208200429030021012000200441086a29030037030820002001370300200441106a24000b0bb4b50c0300418080c0000b89b50c6361706163697479206f766572666c6f7700000024001000170000006e020000050000007372632f6c6962616c6c6f632f7261775f7665632e727300cb0010004600000068010000130000004200000004000000040000004300000044000000450000006120666f726d617474696e6720747261697420696d706c656d656e746174696f6e2072657475726e656420616e206572726f720042000000000000000100000046000000b8001000130000004a020000050000007372632f6c6962616c6c6f632f666d742e72732f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f666d742f6d6f642e72730000004f0110001600000065011000160000004c131300010000003c01100013000000ca0300000d0000007372632f6c6962616c6c6f632f7665632e7273737761705f72656d6f766520696e6465782028697320292073686f756c64206265203c206c656e202869732000a401100014000000b8011000170000004c131300010000003c01100013000000f10300000d000000696e73657274696f6e20696e6465782028697320292073686f756c64206265203c3d206c656e202869732000f80110001200000065011000160000004c131300010000003c01100013000000210400000d00000072656d6f76616c20696e646578202869732000003402100014000000b8011000170000004c131300010000003c01100013000000330500000d000000656e6420647261696e20696e6465782028697320010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020202020202020202020202020202020202020202020202020202020203030303030303030303030303030303040404040400000000000000000000006803100020000000880310001200000042000000000000000100000047000000696e646578206f7574206f6620626f756e64733a20746865206c656e20697320206275742074686520696e646578206973203030303130323033303430353036303730383039313031313132313331343135313631373138313932303231323232333234323532363237323832393330333133323333333433353336333733383339343034313432343334343435343634373438343935303531353235333534353535363537353835393630363136323633363436353636363736383639373037313732373337343735373637373738373938303831383238333834383538363837383838393930393139323933393439353936393739383939000074041000060000007a04100022000000696e64657820206f7574206f662072616e676520666f7220736c696365206f66206c656e67746820ac04100016000000c20410000d000000736c69636520696e64657820737461727473206174202062757420656e64732061742000330f100016000000040800002f0000005b2e2e2e5d000000480510000b0000001d0f1000160000008705100001000000fb0e10000e000000090f1000040000000d0f1000100000008705100001000000480510000b00000053051000260000007905100008000000810510000600000087051000010000006279746520696e64657820206973206e6f742061206368617220626f756e646172793b20697420697320696e7369646520202862797465732029206f66206060c605100002000000b0051000160000005604000024000000b0051000160000004c040000110000007372632f6c6962636f72652f666d742f6d6f642e72732e2eda05100016000000540000001400000030787372632f6c6962636f72652f666d742f6e756d2e727300010305050606030706080809110a1c0b190c140d100e0d0f0410031212130916011705180219031a071c021d011f1620032b032c022d0b2e01300331023201a702a902aa04ab08fa02fb05fd04fe03ff09ad78798b8da23057588b8c901c1ddd0e0f4b4cfbfc2e2f3f5c5d5fb5e2848d8e9192a9b1babbc5c6c9cadee4e5ff00041112293134373a3b3d494a5d848e92a9b1b4babbc6cacecfe4e500040d0e11122931343a3b4546494a5e646584919b9dc9cecf0d112945495764658d91a9b4babbc5c9dfe4e5f00d11454964658084b2bcbebfd5d7f0f183858ba4a6bebfc5c7cecfdadb4898bdcdc6cecf494e4f57595e5f898e8fb1b6b7bfc1c6c7d71116175b5cf6f7feff800d6d71dedf0e0f1f6e6f1c1d5f7d7eaeafbbbcfa16171e1f46474e4f585a5c5e7e7fb5c5d4d5dcf0f1f572738f7475962f5f262e2fa7afb7bfc7cfd7df9a409798308f1fc0c1ceff4e4f5a5b07080f10272feeef6e6f373d3f42459091feff536775c8c9d0d1d8d9e7feff00205f2282df048244081b04061181ac0e80ab35280b80e003190801042f043404070301070607110a500f1207550703041c0a090308030703020303030c0405030b06010e15053a0311070605100757070207150d500443032d03010411060f0c3a041d255f206d046a2580c80582b0031a0682fd035907150b1709140c140c6a060a061a0659072b05460a2c040c040103310b2c041a060b0380ac060a06213f4c042d0374083c030f033c0738082b0582ff1118082f112d032010210f808c048297190b158894052f053b07020e180980b32d740c80d61a0c0580ff0580df0cee0d03848d033709815c1480b80880cb2a38030a06380846080c06740b1e035a0459098083181c0a16094c04808a06aba40c170431a10481da26070c050580a511816d1078282a064c04808d0480be031b030f0d0006010103010402080809020a050b020e041001110212051311140115021702190d1c051d0824016a036b02bc02d102d40cd509d602d702da01e005e102e802ee20f004f802f902fa02fb010c273b3e4e4f8f9e9e9f060709363d3e56f3d0d1041418363756577faaaeafbd35e01287898e9e040d0e11122931343a4546494a4e4f64655cb6b71b1c07080a0b141736393aa8a9d8d909379091a8070a3b3e66698f926f5feeef5a629a9b2728559da0a1a3a4a7a8adbabcc4060b0c151d3a3f4551a6a7cccda007191a22253e3fc5c604202325262833383a484a4c50535556585a5c5e606365666b73787d7f8aa4aaafb0c0d0aeaf79cc6e6f935e227b0503042d036603012f2e80821d03310f1c0424091e052b0544040e2a80aa06240424042808340b018090813709160a088098390363080930160521031b05014038044b052f040a070907402027040c0936033a051a07040c07504937330d33072e080a8126524e28082a561c1417094e041e0f430e19070a0648082709750b3f412a063b050a0651060105100305808b621e48080a80a65e22450b0a060d1339070a362c041080c03c64530c48090a46451b4808531d398107460a1d03474937030e080a0639070a81361980b7010f320d839b66750b80c48abc842f8fd18247a1b98239072a040260260a460a28051382b05b654b0439071140050b020e97f80884d62a09a2f7811f3103110408818c89046b050d03090710936080f60a73086e1746809a140c570919808781470385420f1585502b80d52d031a040281703a0501850080d7294c040a04028311444c3d80c23c06010455051b3402810e2c04640c560a80ae381d0d2c040907020e06809a83d8080d030d03740c59070c140c0438080a062808224e81540c15030305070919070709030d072980cb250a840600580b1000200000000a0000001c000000580b1000200000001a000000280000007372632f6c6962636f72652f756e69636f64652f7072696e7461626c652e72730003000083042000910560005d13a0001217a01e0c20e01eef2c202b2a30a02b6fa6602c02a8e02c1efbe02d00fea0359effe035fd016136010aa136240d6137ab0ee1382f182139301c6146f31ea14af06a614e4f6fa14e9dbc214f65d1e14f00da215000e0e15130e16153ece2a154d0e8e15420002e55f001bf55d80e100023000000520000003e00000000700007002d0101010201020101480b30151001650702060202010423011e1b5b0b3a09090118040109010301052b03770f0120370101010408040103070a021d013a0101010204080109010a021a010202390104020402020303011e0203010b0239010405010204011402160601013a0101020104080107030a021e013b0101010c0109012801030139030503010407020b021d013a01020102010301050207020b021c02390201010204080109010a021d0148010401020301010801510102070c08620102090b064a021b0101010101370e01050102050b0124090166040106010202021902040310040d01020206010f01000300031d031d021e02400201070801020b09012d03770222017603040209010603db0202013a010107010101010208060a020130113f0430070101050128090c0220040202010338010102030101033a0802029803010d0107040106010302c63a01050001c32100038d016020000669020004010a200250020001030104011902050197021a120d012608190b2e0330010204020227014306020202020c0108012f01330101030202050201012a020801ee010201040100010010101000020001e201950500030102050428030401a50200040002990bb001360f3803310402024503240501083e010c0234090a0402015f03020101020601a0010308150239020101010116010e070305c308020301011701510102060101020101020102eb010204060201021b025508020101026a0101010206010165030204010500090102f5010a0201010401900402020401200a280602040801090602032e0d010200070106010152160207010201027a060301010201070101480203010101000200053b0700013f0451010002000101030405080802071e0494030037043208010e011605010f000701110207010201050007000400076d07006080f000000000d80e1000230000004b00000028000000d80e10002300000057000000160000007372632f6c6962636f72652f756e69636f64652f756e69636f64655f646174612e7273626567696e203c3d20656e642028203c3d2029207768656e20736c6963696e672060206973206f7574206f6620626f756e6473206f6620607372632f6c6962636f72652f7374722f6d6f642e7273426f72726f774572726f72426f72726f774d75744572726f7270616e69636b6564206174200000990f1000010000009a0f100003000000301a130000000000980f100001000000980f1000010000003a27272c2066616c736574727565202020200000cc0f10001a0000008b01000026000000330f100016000000c30700002f0000007372632f6c6962636f72652f7374722f7061747465726e2e72730000f80f10001b00000052000000050000007372632f6c6962636f72652f736c6963652f6d656d6368722e7273207b202c20207b0a00420000000c0000000400000048000000490000004a0000002c0a00004200000004000000040000004b0000004c0000004d000000207d7d28280a2c0a5d5b0000330f100016000000800700002f000000bb101000260000006672616d655f737570706f72743a3a686173682f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f737570706f72742f7372632f686173682e7273496e76616c696420726576657273653a2068617368206c656e67746820746f6f2073686f72740000004200000004000000040000004e0000004f000000500000004200000000000000010000005100000052000000530000006d61782d77656967687461637475616c5f7765696768743d42000000000000000100000054000000550000005300000042000000000000000100000054000000550000005300000043616c6c4e6f74416c6c6f77656450687261676d656e426f67757353636f726550687261676d656e426f6775734564676550687261676d656e426f67757353656c66566f746550687261676d656e536c61736865644e6f6d696e6174696f6e50687261676d656e426f6775734e6f6d696e6174696f6e50687261676d656e426f6775734e6f6d696e61746f7250687261676d656e426f677573436f6d7061637450687261676d656e426f67757357696e6e657250687261676d656e426f67757357696e6e6572436f756e74536e617073686f74556e617661696c61626c6550687261676d656e5765616b5375626d697373696f6e50687261676d656e4561726c795375626d697373696f6e416c7265616479436c61696d65644e6f74536f72746564416e64556e69717565496e76616c69644e756d6265724f664e6f6d696e6174696f6e73496e76616c6964457261546f52657761726446756e6465645461726765744e6f556e6c6f636b4368756e6b4e6f4d6f72654368756e6b73496e73756666696369656e7456616c7565496e76616c6964536c617368496e6465784475706c6963617465496e646578456d70747954617267657473416c7265616479506169726564416c7265616479426f6e6465644e6f7453746173684e6f74436f6e74726f6c6c65725761726e696e673a20412073657373696f6e206170706561727320746f2068617665206265656e20736b69707065642e626f6e64626f6e645f6578747261756e626f6e6477697468647261775f756e626f6e64656476616c69646174656e6f6d696e6174656368696c6c7365745f70617965657365745f636f6e74726f6c6c65727365745f76616c696461746f725f636f756e74666f7263655f6e6f5f65726173666f7263655f6e65775f6572617365745f696e76756c6e657261626c6573666f7263655f756e7374616b65666f7263655f6e65775f6572615f616c7761797363616e63656c5f64656665727265645f736c6173687061796f75745f6e6f6d696e61746f727061796f75745f76616c696461746f727061796f75745f7374616b6572737265626f6e647365745f686973746f72795f6465707468726561705f73746173687375626d69745f656c656374696f6e5f736f6c7574696f6e7375626d69745f656c656374696f6e5f736f6c7574696f6e5f756e7369676e6564426f6e6465644c65646765724e6f6d696e61746f727356616c696461746f72536c617368496e4572614e6f6d696e61746f72536c617368496e457261536c617368696e675370616e735370616e536c617368536e617073686f7456616c696461746f7273536e617073686f744e6f6d696e61746f7273457261456c656374696f6e5374617475730000000000a81610000900000000000000b4161000030000000000000000000000cc161000020000000000000000000000dc161000060000000000000084111200020000000000000000000000e4161000010000000000000000000000ec161000050000000000000084111200020000000000000000000000f4161000010000000000000000000000fc1610001a0000000000000008f6120001000000000000000000000018171000020000000000000000000000281710000f000000000000003817100001000000000000000000000040171000010000000000000000000000c0141000060000000000000084111200020000000000000000000000481710000400000000000000000000006817100008000000000000008411120002000000000000000000000070171000010000000000000000000000781710000900000000000000841112000200000000000000000000008417100002000000000000004572615061796f7574000000b51a100008000000f615120007000000f6151200070000002e1a100056000000841a1000310000005265776172640000df1910004f000000536c61736800000096191000490000004f6c64536c617368696e675265706f727444697363617264656400003d1910004700000084191000120000005374616b696e67456c656374696f6e002e1910000f000000ea181000440000002a18100023000000301a1300000000004d18100054000000a118100049000000556e626f6e646564051810002500000057697468647261776e0000009417100057000000eb1710001a00000020416e206163636f756e74206861732063616c6c6564206077697468647261775f756e626f6e6465646020616e642072656d6f76656420756e626f6e64696e67206368756e6b7320776f727468206042616c616e6365602066726f6d2074686520756e6c6f636b696e672071756575652e20416e206163636f756e742068617320756e626f6e646564207468697320616d6f756e742e20416e206163636f756e742068617320626f6e646564207468697320616d6f756e742e204e4f54453a2054686973206576656e74206973206f6e6c7920656d6974746564207768656e2066756e64732061726520626f6e64656420766961206120646973706174636861626c652e204e6f7461626c792c2069742077696c6c206e6f7420626520656d697474656420666f72207374616b696e672072657761726473207768656e20746865792061726520616464656420746f207374616b652e2041206e657720736574206f66207374616b6572732077617320656c656374656420776974682074686520676976656e20636f6d7075746174696f6e206d6574686f642e456c656374696f6e436f6d7075746520416e206f6c6420736c617368696e67207265706f72742066726f6d2061207072696f72206572612077617320646973636172646564206265636175736520697420636f756c64206e6f742062652070726f6365737365642e204f6e652076616c696461746f722028616e6420697473206e6f6d696e61746f72732920686173206265656e20736c61736865642062792074686520676976656e20616d6f756e742e20546865207374616b657220686173206265656e207265776172646564206279207468697320616d6f756e742e20604163636f756e7449646020697320746865207374617368206163636f756e742e2054686520657261207061796f757420686173206265656e207365743b207468652066697273742062616c616e6365206973207468652076616c696461746f722d7061796f75743b20746865207365636f6e64206973207468652072656d61696e6465722066726f6d20746865206d6178696d756d20616d6f756e74206f66207265776172642e457261496e6465785374616b696e674f6666636861696e45726173526577617264506f696e74734572617356616c696461746f7252657761726445726173546f74616c5374616b654572726f723a2073746172745f73657373696f6e5f696e646578206d7573742062652073657420666f722063757272656e745f657261517565756564456c65637465644572617356616c696461746f725072656673457261735374616b657273436c6970706564457261735374616b657273556e6170706c696564536c61736865730000000000731310000400000000000000a01f1000030000000000000000000000e81f1000110000000000000000000000771310000a00000000000000702010000100000000000000000000008820100011000000000000000000000081131000060000000000000010211000010000000000000000000000282110001b0000000000000000000000871310001100000000000000301a13000000000000000000000000000022100013000000000000000000000098131000080000000000000098221000010000000000000000000000b02210000c0000000000000000000000a0131000080000000000000010231000010000000000000000000000282310000d0000000000000000000000a81310000500000000000000301a1300000000000000000000000000902310000c0000000000000000000000ad1310000900000000000000f0231000010000000000000000000000082410000b0000000000000000000000b61310000e0000000000000060241000010000000000000000000000782410000b0000000000000000000000c41310001300000000000000d0241000010000000000000000000000e8241000010000000000000000000000d71310000d00000000000000301a1300000000000000000000000000f0241000050000000000000000000000e41310000d00000000000000301a130000000000000000000000000018251000060000000000000000000000f113100011000000000000004825100001000000000000000000000060251000010000000000000000000000021410000d0000000000000068251000010000000000000000000000802510000100000000000000000000000f1410001400000000000000301a130000000000000000000000000088251000050000000000000000000000231410001500000000000000b0251000020000000000000000000000e025100007000000000000000000000038141000100000000000000018261000020000000000000000000000482610001e00000000000000000000004814100010000000000000003827100001000000000000000000000050271000130000000000000000000000581410000e00000000000000e8271000020000000000000000000000182810000f000000000000000000000066141000060000000000000010211000010000000000000000000000902810000900000000000000000000006c1410001100000000000000d8281000010000000000000000000000f02810000300000000000000000000007d1410000a00000000000000682510000100000000000000000000000829100007000000000000000000000087141000180000000000000040291000040000000000000000000000a02910004a00000000000000000000009f141000210000000000000040291000040000000000000000000000f02b1000050000000000000000000000674810000a00000000000000f32012002300000000000000aa4d12000500000000000000807512001500000000000000f44810000500000000000000f94810001100000038531000590000009153100021000000301a130000000000b25310004c000000301a130000000000fe53100049000000301a1300000000001a53100010000000301a130000000000f5bd12000b000000475410003500000085201200080000007c5410001a000000301a1300000000009654100054000000ea5410005000000044be12000c000000000000002a5310000e0000000000000080751200150000005e51100059000000b75110000d000000301a130000000000c45110005400000018521000590000007152100013000000301a1300000000008452100058000000dc5210003e000000301a1300000000001a53100010000000301a130000000000f5bd12000b000000d54710003a0000008520120008000000ee8811001000000044be12000c00000000000000aa4d1200050000000000000080751200150000006f4d100055000000c44d100040000000044e100049000000301a1300000000004d4e1000520000009f4e100030000000301a130000000000cf4e10004f0000001e4f10004f0000006d4f10003f000000301a1300000000009f481000550000003c49100043000000301a130000000000ac4f100012000000301a130000000000be4f100026000000301a130000000000f5bd12000b000000e44f1000500000000f4810002600000034501000590000008d5010005c000000e9501000540000003d51100017000000ee88110010000000545110000a000000554b10004b000000301a130000000000a04b10004d000000ed4b100013000000301a1300000000009f481000550000003c49100043000000301a130000000000004c100013000000301a130000000000134c10001b000000301a130000000000f5bd12000b0000002e4c100055000000834c100051000000d44c10003d000000114d10005e000000354810003200000044be12000c00000000000000424b10000500000000000000474b10000e000000084b10003a000000301a1300000000004947100037000000301a1300000000009f481000550000003c49100043000000301a130000000000f5bd12000b000000d54710003a0000000f48100026000000354810003200000044be12000c00000000000000d94a10000700000000000000e04a1000280000009449100044000000301a130000000000d849100054000000233b100023000000301a1300000000009f481000550000003c49100043000000301a130000000000f5bd12000b0000002c4a100049000000754a10002e000000a34a10003600000044be12000c0000000a49100032000000301a1300000000004947100037000000301a1300000000009f481000550000003c49100043000000301a130000000000f5bd12000b000000d54710003a0000007f49100015000000354810003200000044be12000c00000000000000f44810000500000000000000f948100011000000714810002e000000301a1300000000004947100037000000301a1300000000009f48100055000000301a130000000000f5bd12000b000000d54710003a0000000f48100026000000354810003200000044be12000c00000000000000674810000a00000000000000f3201200230000002547100024000000301a1300000000004947100037000000301a1300000000008047100055000000301a130000000000f5bd12000b000000d54710003a0000000f48100026000000354810003200000044be12000c00000000000000842112000300000000000000194710000c000000f946100020000000cd4610002c000000301a130000000000f5bd12000b000000bd4610001000000044be12000c00000042461000530000009546100028000000301a130000000000f5bd12000b000000bd4610001000000044be12000c00000000000000804410000a00000000000000ddce1200110000000f46100033000000000000000a46100005000000000000007ac312000c000000c7451000430000007245100041000000301a130000000000f5bd12000b000000b34510001400000044be12000c00000000000000093910000300000000000000b51a10000800000000000000654510000d00000000000000c499120008000000a244100051000000f34410001c0000000f45100041000000301a130000000000f5bd12000b000000504510001500000044be12000c00000000000000093910000300000000000000b51a10000800000000000000804410000a000000000000008a44100018000000f03d100058000000483e1000570000009f3e100031000000301a130000000000ac40100029000000301a130000000000d54010003f000000383f100059000000913f10004c00000014411000560000006a41100049000000b341100022000000d54110004200000017421000480000005f42100028000000301a130000000000dd3f100057000000344010000e000000301a1300000000004240100051000000301a130000000000f5bd12000b0000008742100057000000de42100027000000054310004e00000053431000370000008a43100050000000da431000520000002c4410005400000044be12000c00000000000000093910000300000000000000b51a100008000000f03d100058000000483e1000570000009f3e100031000000301a130000000000d03e100029000000301a130000000000f93e10003f000000383f100059000000913f10004c000000301a130000000000dd3f100057000000344010000e000000301a1300000000004240100051000000301a130000000000f5bd12000b00000093401000190000009f9510003100000044be12000c00000000000000e13d10000f000000000000007ac312000c00000000000000093910000300000000000000b51a100008000000bf3b100044000000301a130000000000033c100053000000563c10004a000000a03c10004d000000301a130000000000ed3c100056000000433d10001e000000301a130000000000613d100040000000301a130000000000f5bd12000b000000a13d1000400000009f9510003100000044be12000c000000963a100038000000301a130000000000ce3a100055000000233b100023000000301a130000000000f5bd12000b000000463b10003c000000823b10003d00000044be12000c00000000000000743a10001100000000000000853a100011000000463a100019000000301a1300000000005f3a1000150000000c3910004e0000005a39100058000000b239100030000000301a130000000000e239100024000000301a130000000000063a10004000000000000000b83810000700000000000000bf3810001300000000000000d23810001300000000000000e53810001200000000000000f73810000500000000000000fc3810000d00000000000000093910000300000000000000b51a100008000000112d100038000000301a130000000000492d10000d000000562d100045000000301a1300000000009b2d100021000000301a130000000000bc2d10002b000000301a130000000000e72d10003d000000242e100054000000782e10000c000000301a130000000000842e10004a000000301a130000000000ce2e10002a000000301a130000000000f82e100032000000301a1300000000002a2f1000530000007d2f100047000000c42f10004c00000010301000540000006430100058000000bc30100026000000301a130000000000e230100018000000301a130000000000fa30100039000000333110003e000000713110002b0000009c31100055000000f131100057000000483210001000000058321000430000009b3210001b000000301a130000000000b632100030000000301a130000000000e6321000590000003f331000590000009833100050000000e833100027000000301a130000000000f5bd12000b0000000f341000590000006834100039000000301a130000000000a134100059000000fa34100052000000301a1300000000004c35100038000000301a1300000000008435100027000000ab35100026000000d135100027000000f835100037000000301a1300000000002f36100045000000743610003f000000b336100042000000f536100045000000301a1300000000003a3710004f000000893710005a000000301a130000000000e3371000230000000638100022000000301a130000000000283810002b0000005338100027000000301a1300000000007a3810003e00000044be12000c000000182c100030000000301a130000000000482c1000570000009f2c100058000000f72c10001a00000020556e7369676e65642076657273696f6e206f6620607375626d69745f656c656374696f6e5f736f6c7574696f6e602e204e6f746520746861742074686973206d757374207061737320746865205b6056616c6964617465556e7369676e6564605d20636865636b207768696368206f6e6c7920616c6c6f7773207472616e73616374696f6e732066726f6d20746865206c6f63616c206e6f646520746f20626520696e636c756465642e20496e206f7468657220776f7264732c206f6e6c792074686520626c6f636b20617574686f722063616e20696e636c7564652061207472616e73616374696f6e20696e2074686520626c6f636b2e205375626d697420612070687261676d656e20726573756c7420746f2074686520636861696e2e2049662074686520736f6c7574696f6e3a20312e2069732076616c69642e20322e206861732061206265747465722073636f7265207468616e206120706f74656e7469616c6c79206578697374696e6720736f6c7574696f6e206f6e20636861696e2e207468656e2c2069742077696c6c206265205f7075745f206f6e20636861696e2e204120736f6c7574696f6e20636f6e7369737473206f662074776f20706965636573206f6620646174613a20312e206077696e6e657273603a206120666c617420766563746f72206f6620616c6c207468652077696e6e657273206f662074686520726f756e642e20322e206061737369676e6d656e7473603a2074686520636f6d706163742076657273696f6e206f6620616e2061737369676e6d656e7420766563746f72207468617420656e636f64657320746865206564676520202020776569676874732e20426f7468206f66207768696368206d617920626520636f6d7075746564207573696e67205b6070687261676d656e605d2c206f7220616e79206f7468657220616c676f726974686d2e204164646974696f6e616c6c792c20746865207375626d6974746572206d7573742070726f766964653a202d20546865206073636f7265602074686174207468657920636c61696d20746865697220736f6c7574696f6e206861732e20426f74682076616c696461746f727320616e64206e6f6d696e61746f72732077696c6c20626520726570726573656e74656420627920696e646963657320696e2074686520736f6c7574696f6e2e2054686520696e64696365732073686f756c6420726573706563742074686520636f72726573706f6e64696e6720747970657320285b6056616c696461746f72496e646578605d20616e64205b604e6f6d696e61746f72496e646578605d292e204d6f72656f7665722c20746865792073686f756c642062652076616c6964207768656e207573656420746f20696e64657820696e746f205b60536e617073686f7456616c696461746f7273605d20616e64205b60536e617073686f744e6f6d696e61746f7273605d2e20416e7920696e76616c696420696e6465782077696c6c2063617573652074686520736f6c7574696f6e20746f2062652072656a65637465642e2054686573652074776f2073746f72616765206974656d73206172652073657420647572696e672074686520656c656374696f6e2077696e646f7720616e64206d6179206265207573656420746f2064657465726d696e652074686520696e64696365732e204120736f6c7574696f6e2069732076616c69642069663a20302e204974206973207375626d6974746564207768656e205b60457261456c656374696f6e537461747573605d20697320604f70656e602e20312e2049747320636c61696d65642073636f726520697320657175616c20746f207468652073636f726520636f6d7075746564206f6e2d636861696e2e20322e2050726573656e74732074686520636f7272656374206e756d626572206f662077696e6e6572732e20332e20416c6c20696e6465786573206d7573742062652076616c7565206163636f7264696e6720746f2074686520736e617073686f7420766563746f72732e20416c6c20656467652076616c756573206d75737420202020616c736f20626520636f727265637420616e642073686f756c64206e6f74206f766572666c6f7720746865206772616e756c6172697479206f662074686520726174696f20747970652028692e652e20323536202020206f722062696c6c696f6e292e20342e20466f72206561636820656467652c20616c6c2074617267657473206172652061637475616c6c79206e6f6d696e617465642062792074686520766f7465722e20352e2048617320636f72726563742073656c662d766f7465732e204120736f6c7574696f6e732073636f726520697320636f6e736973746564206f66203320706172616d65746572733a20312e20606d696e207b20737570706f72742e746f74616c207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265206d6178696d697a65642e20322e206073756d207b20737570706f72742e746f74616c207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265206d696e696d697a65642e20332e206073756d207b20737570706f72742e746f74616c5e32207d6020666f72206561636820737570706f7274206f6620612077696e6e65722e20546869732076616c75652073686f756c64206265202020206d696e696d697a65642028746f20656e73757265206c6573732076617269616e63652920453a206e756d626572206f662065646765732e206d3a2073697a65206f662077696e6e657220636f6d6d69747465652e206e3a206e756d626572206f66206e6f6d696e61746f72732e20643a2065646765206465677265652028313620666f72206e6f772920763a206e756d626572206f66206f6e2d636861696e2076616c696461746f722063616e646964617465732e204e4f54453a20676976656e206120736f6c7574696f6e20776869636820697320726564756365642c2077652063616e20656e61626c652061206e657720636865636b2074686520656e7375726520607c457c203c206e202b206d602e20576520646f6e277420646f2074686973205f7965745f2c20627574206f7572206f6666636861696e20776f726b657220636f6465206578656375746573206974206e6f6e657468656c6573732e206d616a6f722073746570732028616c6c20646f6e6520696e2060636865636b5f616e645f7265706c6163655f736f6c7574696f6e60293a202d2053746f726167653a204f28312920726561642060456c656374696f6e537461747573602e202d2053746f726167653a204f2831292072656164206050687261676d656e53636f7265602e202d2053746f726167653a204f2831292072656164206056616c696461746f72436f756e74602e202d2053746f726167653a204f283129206c656e67746820726561642066726f6d2060536e617073686f7456616c696461746f7273602e202d2053746f726167653a204f287629207265616473206f6620604163636f756e7449646020746f2066657463682060736e617073686f745f76616c696461746f7273602e202d204d656d6f72793a204f286d2920697465726174696f6e7320746f206d61702077696e6e657220696e64657820746f2076616c696461746f722069642e202d2053746f726167653a204f286e2920726561647320604163636f756e7449646020746f2066657463682060736e617073686f745f6e6f6d696e61746f7273602e202d204d656d6f72793a204f286e202b206d2920726561647320746f206d617020696e64657820746f20604163636f756e7449646020666f7220756e2d636f6d706163742e202d2053746f726167653a204f286529206163636f756e7469642072656164732066726f6d20604e6f6d696e6174696f6e6020746f207265616420636f7272656374206e6f6d696e6174696f6e732e202d2053746f726167653a204f2865292063616c6c7320696e746f2060736c61736861626c655f62616c616e63655f6f665f766f74655f7765696768746020746f20636f6e7665727420726174696f20746f207374616b65642e202d204d656d6f72793a206275696c645f737570706f72745f6d61702e204f2865292e202d204d656d6f72793a206576616c756174655f737570706f72743a204f2845292e202d2053746f726167653a204f2865292077726974657320746f2060517565756564456c6563746564602e202d2053746f726167653a204f28312920777269746520746f206051756575656453636f7265602054686520776569676874206f6620746869732063616c6c20697320312f31307468206f662074686520626c6f636b7320746f74616c207765696768742e77696e6e6572735665633c56616c696461746f72496e6465783e636f6d706163745f61737369676e6d656e7473436f6d7061637441737369676e6d656e747373636f726550687261676d656e53636f72656572612052656d6f766520616c6c20646174612073747275637475726520636f6e6365726e696e672061207374616b65722f7374617368206f6e6365206974732062616c616e6365206973207a65726f2e205468697320697320657373656e7469616c6c79206571756976616c656e7420746f206077697468647261775f756e626f6e64656460206578636570742069742063616e2062652063616c6c656420627920616e796f6e6520616e6420746865207461726765742060737461736860206d7573742068617665206e6f2066756e6473206c6566742e20546869732063616e2062652063616c6c65642066726f6d20616e79206f726967696e2e202d20607374617368603a20546865207374617368206163636f756e7420746f20726561702e204974732062616c616e6365206d757374206265207a65726f2e2053657420686973746f72795f64657074682076616c75652e204f726967696e206d75737420626520726f6f742e6e65775f686973746f72795f6465707468436f6d706163743c457261496e6465783e205265626f6e64206120706f7274696f6e206f6620746865207374617368207363686564756c656420746f20626520756e6c6f636b65642e20546865206469737061746368206f726967696e206d757374206265207369676e65642062792074686520636f6e74726f6c6c65722c20616e642069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d2054696d6520636f6d706c65786974793a204f2831292e20426f756e64656420627920604d41585f554e4c4f434b494e475f4348554e4b53602e202d2053746f72616765206368616e6765733a2043616e277420696e6372656173652073746f726167652c206f6e6c792064656372656173652069742e20506179206f757420616c6c20746865207374616b65727320626568696e6420612073696e676c652076616c696461746f7220666f7220612073696e676c65206572612e202d206076616c696461746f725f73746173686020697320746865207374617368206163636f756e74206f66207468652076616c696461746f722e205468656972206e6f6d696e61746f72732c20757020746f20202060543a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602c2077696c6c20616c736f207265636569766520746865697220726577617264732e202d206065726160206d617920626520616e7920657261206265747765656e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e20546865206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e20416e79206163636f756e742063616e2063616c6c20746869732066756e6374696f6e2c206576656e206966206974206973206e6f74206f6e65206f6620746865207374616b6572732e20546869732063616e206f6e6c792062652063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d2054696d6520636f6d706c65786974793a206174206d6f7374204f284d61784e6f6d696e61746f72526577617264656450657256616c696461746f72292e76616c696461746f725f7374617368202a2a546869732065787472696e7369632077696c6c2062652072656d6f76656420616674657220604d6967726174696f6e457261202b20486973746f727944657074686020686173207061737365642c20676976696e67206f70706f7274756e69747920666f7220757365727320746f20636c61696d20616c6c2072657761726473206265666f7265206d6f76696e6720746f2053696d706c65205061796f7574732e20416674657220746869732074696d652c20796f752073686f756c642075736520607061796f75745f7374616b6572736020696e73746561642e2a2a204d616b65206f6e652076616c696461746f722773207061796f757420666f72206f6e65206572612e202d206077686f602069732074686520636f6e74726f6c6c6572206163636f756e74206f66207468652076616c696461746f7220746f20706179206f75742e202d206065726160206d6179206e6f74206265206c6f776572207468616e206f6e6520666f6c6c6f77696e6720746865206d6f737420726563656e746c792070616964206572612e204966206974206973206869676865722c2020207468656e20697420696e6469636174657320616e20696e737472756374696f6e20746f20736b697020746865207061796f7574206f6620616c6c2070726576696f757320657261732e205741524e494e473a206f6e636520616e2065726120697320706179656420666f7220612076616c696461746f7220737563682076616c696461746f722063616e277420636c61696d20746865207061796f7574206f662070726576696f7573206572612e205741524e494e473a20496e636f727265637420617267756d656e747320686572652063616e20726573756c7420696e206c6f7373206f66207061796f75742e2042652076657279206361726566756c2e202d2054696d6520636f6d706c65786974793a204f2831292e204d616b65206f6e65206e6f6d696e61746f722773207061796f757420666f72206f6e65206572612e202d206077686f602069732074686520636f6e74726f6c6c6572206163636f756e74206f6620746865206e6f6d696e61746f7220746f20706179206f75742e202d206076616c696461746f72736020697320746865206c697374206f6620616c6c2076616c696461746f72732074686174206077686f6020686164206578706f7375726520746f20647572696e672060657261602c202020616c6f6e67736964652074686520696e646578206f66206077686f6020696e2074686520636c6970706564206578706f73757265206f66207468652076616c696461746f722e202020492e652e206561636820656c656d656e742069732061207475706c65206f66202020602876616c696461746f722c20696e646578206f66206077686f6020696e20636c6970706564206578706f73757265206f662076616c696461746f7229602e202020496620697420697320696e636f6d706c6574652c207468656e206c657373207468616e207468652066756c6c207265776172642077696c6c2062652070616964206f75742e2020204974206d757374206e6f742065786365656420604d41585f4e4f4d494e4154494f4e53602e202d204e756d626572206f662073746f726167652072656164206f6620604f2876616c696461746f727329603b206076616c696461746f7273602069732074686520617267756d656e74206f66207468652063616c6c2c202020616e6420697320626f756e64656420627920604d41585f4e4f4d494e4154494f4e53602e202d20456163682073746f72616765207265616420697320604f284e29602073697a6520616e64206465636f646520636f6d706c65786974793b20604e602069732074686520206d6178696d756d2020206e6f6d696e6174696f6e7320746861742063616e20626520676976656e20746f20612073696e676c652076616c696461746f722e202d20436f6d7075746174696f6e20636f6d706c65786974793a20604f284d41585f4e4f4d494e4154494f4e53202a206c6f674e29603b20604d41585f4e4f4d494e4154494f4e5360206973207468652020206d6178696d756d206e756d626572206f662076616c696461746f72732074686174206d6179206265206e6f6d696e6174656420627920612073696e676c65206e6f6d696e61746f722c206974206973202020626f756e646564206f6e6c792065636f6e6f6d6963616c6c792028616c6c206e6f6d696e61746f72732061726520726571756972656420746f20706c6163652061206d696e696d756d207374616b65292e76616c696461746f72735665633c28543a3a4163636f756e7449642c20753332293e2043616e63656c20656e6163746d656e74206f66206120646566657272656420736c6173682e2043616e2062652063616c6c6564206279206569746865722074686520726f6f74206f726967696e206f72207468652060543a3a536c61736843616e63656c4f726967696e602e2070617373696e67207468652065726120616e6420696e6469636573206f662074686520736c617368657320666f7220746861742065726120746f206b696c6c2e202d204f6e652073746f726167652077726974652e736c6173685f696e646963657320466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f662073657373696f6e7320696e646566696e6974656c792e202d204f6e652073746f7261676520777269746520466f72636520612063757272656e74207374616b657220746f206265636f6d6520636f6d706c6574656c7920756e7374616b65642c20696d6d6564696174656c792e737461736820536574207468652076616c696461746f72732077686f2063616e6e6f7420626520736c61736865642028696620616e79292e20466f72636520746865726520746f2062652061206e6577206572612061742074686520656e64206f6620746865206e6578742073657373696f6e2e20416674657220746869732c2069742077696c6c20626520726573657420746f206e6f726d616c20286e6f6e2d666f7263656429206265686176696f75722e202d204e6f20617267756d656e74732e20466f72636520746865726520746f206265206e6f206e6577206572617320696e646566696e6974656c792e2054686520696465616c206e756d626572206f662076616c696461746f72732e436f6d706163743c7533323e202852652d297365742074686520636f6e74726f6c6c6572206f6620612073746173682e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c65722e202d20496e646570656e64656e74206f662074686520617267756d656e74732e20496e7369676e69666963616e7420636f6d706c65786974792e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732e202d2057726974657320617265206c696d6974656420746f2074686520606f726967696e60206163636f756e74206b65792e636f6e74726f6c6c6572202852652d2973657420746865207061796d656e742074617267657420666f72206120636f6e74726f6c6c65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2062792074686520636f6e74726f6c6c65722c206e6f74207468652073746173682e706179656552657761726444657374696e6174696f6e204465636c617265206e6f2064657369726520746f206569746865722076616c6964617465206f72206e6f6d696e6174652e20416e642c2069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e202d20436f6e7461696e73206f6e6520726561642e204465636c617265207468652064657369726520746f206e6f6d696e6174652060746172676574736020666f7220746865206f726967696e20636f6e74726f6c6c65722e20456666656374732077696c6c2062652066656c742061742074686520626567696e6e696e67206f6620746865206e657874206572612e20546869732063616e206f6e6c792062652063616c6c6564207768656e202d20546865207472616e73616374696f6e277320636f6d706c65786974792069732070726f706f7274696f6e616c20746f207468652073697a65206f66206074617267657473602c2077686963682069732063617070656420617420436f6d7061637441737369676e6d656e74733a3a4c494d49542e202d20426f74682074686520726561647320616e642077726974657320666f6c6c6f7720612073696d696c6172207061747465726e2e746172676574735665633c3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263653e204465636c617265207468652064657369726520746f2076616c696461746520666f7220746865206f726967696e20636f6e74726f6c6c65722e707265667356616c696461746f7250726566732052656d6f766520616e7920756e6c6f636b6564206368756e6b732066726f6d207468652060756e6c6f636b696e67602071756575652066726f6d206f7572206d616e6167656d656e742e205468697320657373656e7469616c6c7920667265657320757020746861742062616c616e636520746f206265207573656420627920746865207374617368206163636f756e7420746f20646f2077686174657665722069742077616e74732e20456d697473206057697468647261776e602e2053656520616c736f205b6043616c6c3a3a756e626f6e64605d2e202d20436f756c6420626520646570656e64656e74206f6e2074686520606f726967696e6020617267756d656e7420616e6420686f77206d7563682060756e6c6f636b696e6760206368756e6b732065786973742e2020497420696d706c6965732060636f6e736f6c69646174655f756e6c6f636b656460207768696368206c6f6f7073206f76657220604c65646765722e756e6c6f636b696e67602c2077686963682069732020696e6469726563746c7920757365722d636f6e74726f6c6c65642e20536565205b60756e626f6e64605d20666f72206d6f72652064657461696c2e202d20436f6e7461696e732061206c696d69746564206e756d626572206f662072656164732c20796574207468652073697a65206f6620776869636820636f756c64206265206c61726765206261736564206f6e20606c6564676572602e205363686564756c65206120706f7274696f6e206f662074686520737461736820746f20626520756e6c6f636b656420726561647920666f72207472616e73666572206f75742061667465722074686520626f6e6420706572696f6420656e64732e2049662074686973206c656176657320616e20616d6f756e74206163746976656c7920626f6e646564206c657373207468616e20543a3a43757272656e63793a3a6d696e696d756d5f62616c616e636528292c207468656e20697420697320696e6372656173656420746f207468652066756c6c20616d6f756e742e204f6e63652074686520756e6c6f636b20706572696f6420697320646f6e652c20796f752063616e2063616c6c206077697468647261775f756e626f6e6465646020746f2061637475616c6c79206d6f7665207468652066756e6473206f7574206f66206d616e6167656d656e7420726561647920666f72207472616e736665722e204e6f206d6f7265207468616e2061206c696d69746564206e756d626572206f6620756e6c6f636b696e67206368756e6b73202873656520604d41585f554e4c4f434b494e475f4348554e4b5360292063616e20636f2d657869737473206174207468652073616d652074696d652e20496e207468617420636173652c205b6043616c6c3a3a77697468647261775f756e626f6e646564605d206e65656420746f2062652063616c6c656420666972737420746f2072656d6f766520736f6d65206f6620746865206368756e6b732028696620706f737369626c65292e20456d6974732060556e626f6e646564602e2053656520616c736f205b6043616c6c3a3a77697468647261775f756e626f6e646564605d2e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204c696d697465642062757420706f74656e7469616c6c79206578706c6f697461626c6520636f6d706c65786974792e202d20456163682063616c6c20287265717569726573207468652072656d61696e646572206f662074686520626f6e6465642062616c616e636520746f2062652061626f766520606d696e696d756d5f62616c616e6365602920202077696c6c2063617573652061206e657720656e74727920746f20626520696e73657274656420696e746f206120766563746f722028604c65646765722e756e6c6f636b696e676029206b65707420696e2073746f726167652e202020546865206f6e6c792077617920746f20636c65616e207468652061666f72656d656e74696f6e65642073746f72616765206974656d20697320616c736f20757365722d636f6e74726f6c6c6564207669612020206077697468647261775f756e626f6e646564602e203c2f7765696768743e2041646420736f6d6520657874726120616d6f756e742074686174206861766520617070656172656420696e207468652073746173682060667265655f62616c616e63656020696e746f207468652062616c616e636520757020666f72207374616b696e672e20557365207468697320696620746865726520617265206164646974696f6e616c2066756e647320696e20796f7572207374617368206163636f756e74207468617420796f75207769736820746f20626f6e642e20556e6c696b65205b60626f6e64605d206f72205b60756e626f6e64605d20746869732066756e6374696f6e20646f6573206e6f7420696d706f736520616e79206c696d69746174696f6e206f6e2074686520616d6f756e7420746861742063616e2062652061646465642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f206279207468652073746173682c206e6f742074686520636f6e74726f6c6c657220616e642069742063616e206265206f6e6c792063616c6c6564207768656e205b60457261456c656374696f6e537461747573605d2069732060436c6f736564602e20456d6974732060426f6e646564602e6d61785f6164646974696f6e616c2054616b6520746865206f726967696e206163636f756e74206173206120737461736820616e64206c6f636b207570206076616c756560206f66206974732062616c616e63652e2060636f6e74726f6c6c6572602077696c6c20626520746865206163636f756e74207468617420636f6e74726f6c732069742e206076616c756560206d757374206265206d6f7265207468616e2074686520606d696e696d756d5f62616c616e636560207370656369666965642062792060543a3a43757272656e6379602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20627920746865207374617368206163636f756e742e202d20496e646570656e64656e74206f662074686520617267756d656e74732e204d6f64657261746520636f6d706c65786974792e202d20546872656520657874726120444220656e74726965732e204e4f54453a2054776f206f66207468652073746f726167652077726974657320286053656c663a3a626f6e646564602c206053656c663a3a7061796565602920617265205f6e657665725f20636c65616e656420756e6c6573732074686520606f726967696e602066616c6c732062656c6f77205f6578697374656e7469616c206465706f7369745f20616e6420676574732072656d6f76656420617320647573742e000000000000b5f612000c000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a13009c6110000000000000000000ac61100007000000000000000100000000000000c1f612000e000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a1300e46110000000000000000000f461100001000000000000000100000000000000cff6120015000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a1300fc61100000000000000000000c62100001000000000000000100000000000000146210000d0000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a13002462100000000000000000003462100003000000000000000100000000000000c01410000600000001050000000000007ac312000c000000000000007ac312000c00000000000000000000000000000000000000301a13002067100000000000000000004c62100001000000000000000000000000000000c61410000600000001020000000000007ac312000c00000000000000546210002900000000000000000000000000000000000000301a13002067100000000000000000008062100001000000000000000000000000000000886210000500000001050000000000007ac312000c00000000000000f94810001100000000000000000000000000000000000000301a1300906210000000000000000000a062100001000000000000000100000000000000f38912000a00000001050000000000007ac312000c00000000000000474b10000e00000000000000000000000000000000000000301a1300086410000000000000000000a862100001000000000000000100000000000000cc1410000a00000001050000000000007ac312000c00000000000000b06210001900000000000000000000000000000000000000301a1300cc6210000000000000000000dc62100001000000000000000000000000000000e4f612000a0000000000000000000000b51a10000800000000000000000000000000000000000000000000000000000000000000301a1300c86710000000000000000000e462100004000000000000000000000000000000eef61200090000000000000000000000046310000d00000000000000000000000000000000000000000000000000000000000000301a13001463100000000000000000002463100004000000000000000000000000000000fef61200150000000105000000000000b51a1000080000000000000097f612000c00000000000000000000000000000000000000301a1300c867100000000000000000004463100001000000000000000000000000000000641b10000b0000000205050000000000b51a100008000000000000007ac312000c000000000000004c6310002400000000000000301a1300a063100000000000000000007063100006000000000000000100000000000000521b1000120000000205050000000000b51a100008000000000000007ac312000c000000000000004c6310002400000000000000301a1300a06310000000000000000000b06310000b000000000000000100000000000000401b1000120000000205050000000000b51a100008000000000000007ac312000c00000000000000474b10000e00000000000000301a13000864100000000000000000001864100005000000000000000100000000000000dc1a1000130000000105000000000000b51a10000800000000000000b66c12000c00000000000000000000000000000000000000301a1300f465100000000000000000004064100003000000000000000000000000000000cc1a1000100000000105000000000000b51a10000800000000000000586410001d00000000000000000000000000000000000000301a13007864100000000000000000008864100002000000000000000100000000000000ef1a10000e0000000105000000000000b51a10000800000000000000b66c12000c00000000000000000000000000000000000000301a1300046510000000000000000000986410000200000000000000010000000000000013f71200080000000000000000000000a86410000700000000000000000000000000000000000000000000000000000000000000301a1300b06410000000000000000000c0641000010000000000000001000000000000001bf712001300000000000000000000007df111000700000000000000000000000000000000000000000000000000000000000000301a1300c86410000000000000000000d864100003000000000000000100000000000000f0641000130000000000000000000000b66c12000c00000000000000000000000000000000000000000000000000000000000000301a130004651000000000000000000014651000020000000000000001000000000000006f1b1000100000000105000000000000b51a10000800000000000000246510002f00000000000000000000000000000000000000301a130054651000000000000000000064651000010000000000000001000000000000002ef712000a00000000000000000000006c6510001d00000000000000000000000000000000000000000000000000000000000000301a13008c65100000000000000000009c65100004000000000000000100000000000000d6141000130000000205050000000000b51a100008000000000000007ac312000c00000000000000bc6510001700000000000000301a1300d46510000000000000000000e465100002000000000000000000000000000000e9141000130000000205050000000000b51a100008000000000000007ac312000c00000000000000b66c12000c00000000000000301a1300f465100000000000000000000466100001000000000000000000000000000000fc1410000d00000001050000000000007ac312000c000000000000000c6610001700000000000000000000000000000000000000301a13002466100000000000000000003466100001000000000000000000000000000000091510000900000001050000000000003c66100023000000000000005f6610002200000000000000000000000000000000000000301a1300846610000000000000000000946610000200000000000000010000000000000038f71200160000000000000000000000b51a10000800000000000000000000000000000000000000000000000000000000000000301a1300c86710000000000000000000a46610000100000000000000000000000000000012151000120000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a1300bc6610000000000000000000ac6610000200000000000000000000000000000024151000120000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a1300bc6610000000000000000000cc66100002000000000000000000000000000000331b10000d0000000000000000000000dc6610002a00000000000000000000000000000000000000000000000000000000000000301a130020671000000000000000000008671000030000000000000000000000000000004ef712000b0000000000000000000000fc3810000d00000000000000000000000000000000000000000000000000000000000000301a1300206710000000000000000000306710000100000000000000000000000000000036151000110000000000000000000000386710001e00000000000000000000000000000000000000000000000000000000000000301a1300586710000000000000000000686710000200000000000000010000000000000059f71200150000000000000000000000a1f512000400000000000000000000000000000000000000000000000000000000000000301a130078671000000000000000000088671000020000000000000001000000000000005c9d10000e00000000000000000000006a9d10000800000000000000000000000000000000000000000000000000000000000000301a1300986710000000000000000000a8671000040000000000000001000000000000006ef712000a0000000000000000000000b51a10000800000000000000000000000000000000000000000000000000000000000000301a1300c86710000000000000000000d8671000010000000000000000000000420000000000000001000000560000004b77100023000000301a1300000000006e7710004e000000301a130000000000bc77100043000000ff7710002b0000002a7810004400000042000000000000000100000057000000217710002a00000042000000000000000100000058000000d176100050000000496e76756c6e657261626c657300000042000000000000000100000059000000fd751000560000005376100053000000a67610002b000000bd751000400000005374616b696e674c65646765723c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e0000006c7510005100000050617965650000004200000000000000010000005a0000003375100039000000e2741000510000004e6f6d696e6174696f6e733c543a3a4163636f756e7449643e0000004200000000000000010000005b0000008974100059000000f973100017000000301a13000000000010741000590000006974100020000000416374697665457261496e666f0000004200000000000000010000005b0000004a73100036000000301a130000000000807310002e000000ae7310004b000000fe7210004c0000004578706f737572653c543a3a4163636f756e7449642c2042616c616e63654f663c543e3ee07210001e000000301a1300000000008070100058000000301a130000000000d87010002a00000090721000500000004200000000000000010000005c0000000271100026000000301a13000000000028711000560000007e71100037000000b571100047000000fc7110003d000000301a1300000000003972100057000000301a130000000000d87010002a00000090721000500000004200000000000000010000005d0000003c70100044000000301a1300000000008070100058000000301a130000000000d87010002a000000b26f100042000000301a130000000000f46f100048000000457261526577617264506f696e74733c543a3a4163636f756e7449643e0000004200000000000000010000005e0000003e6f10002b000000696f100049000000bc6e10003b000000f76e100047000000466f7263696e67004200000000000000010000005a000000a76e10001500000042000000000000000100000057000000306e10003e000000301a1300000000006e6e10003900000043616e63656c6564536c6173685061796f7574004200000000000000010000005f000000b06d100045000000f56d10003b0000005665633c556e6170706c696564536c6173683c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e3e00420000000000000001000000590000007f6d1000310000005665633c28457261496e6465782c2053657373696f6e496e646578293e00000042000000000000000100000059000000d56c100049000000301a1300000000001e6d100032000000506d10002f0000002850657262696c6c2c2042616c616e63654f663c543e29004200000000000000010000005b000000686c100051000000b96c10001c0000004200000000000000010000005b000000106c100058000000736c617368696e673a3a536c617368696e675370616e73004200000000000000010000005b000000ed6b10002300000028543a3a4163636f756e7449642c20736c617368696e673a3a5370616e496e64657829736c617368696e673a3a5370616e5265636f72643c42616c616e63654f663c543e3e00000042000000000000000100000060000000706b10004f000000bf6b10002e000000316b10003f000000d86a100059000000926a1000460000004200000000000000010000005b000000396a100059000000926a100046000000456c656374696f6e526573756c743c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e00007b69100059000000d4691000580000002c6a10000d0000004200000000000000010000005b0000004f6910002c000000456c656374696f6e5374617475733c543a3a426c6f636b4e756d6265723e00004200000000000000010000005a000000e268100052000000346910001b0000004200000000000000010000005b0000007968100053000000cc68100016000000420000000000000001000000610000001e681000330000009c9d10001f000000301a13000000000051681000280000004200000000000000010000005b000000e06710003e0000002054686520657261207768657265207765206d696772617465642066726f6d204c617a79205061796f75747320746f2053696d706c65205061796f7574732054727565206966206e6574776f726b20686173206265656e20757067726164656420746f20746869732076657273696f6e2e20546869732069732073657420746f2076332e302e3020666f72206e6577206e6574776f726b732e2054727565206966207468652063757272656e74202a2a706c616e6e65642a2a2073657373696f6e2069732066696e616c2e204e6f74652074686174207468697320646f6573206e6f742074616b652065726120666f7263696e6720696e746f206163636f756e742e20466c616720746f20636f6e74726f6c2074686520657865637574696f6e206f6620746865206f6666636861696e20656c656374696f6e2e205768656e20604f70656e285f29602c2077652061636365707420736f6c7574696f6e7320746f206265207375626d69747465642e205468652073636f7265206f66207468652063757272656e74205b60517565756564456c6563746564605d2e20546865206e6578742076616c696461746f72207365742e2041742074686520656e64206f6620616e206572612c206966207468697320697320617661696c61626c652028706f74656e7469616c6c792066726f6d2074686520726573756c74206f6620616e206f6666636861696e20776f726b6572292c20697420697320696d6d6564696174656c7920757365642e204f74686572776973652c20746865206f6e2d636861696e20656c656374696f6e2069732065786563757465642e20536e617073686f74206f66206e6f6d696e61746f72732061742074686520626567696e6e696e67206f66207468652063757272656e7420656c656374696f6e2077696e646f772e20546869732073686f756c64206f6e6c79206861766520612076616c7565207768656e205b60457261456c656374696f6e537461747573605d203d3d2060456c656374696f6e5374617475733a3a4f70656e285f29602e20536e617073686f74206f662076616c696461746f72732061742074686520626567696e6e696e67206f66207468652063757272656e7420656c656374696f6e2077696e646f772e20546869732073686f756c64206f6e6c7920546865206561726c696573742065726120666f72207768696368207765206861766520612070656e64696e672c20756e6170706c69656420736c6173682e205265636f72647320696e666f726d6174696f6e2061626f757420746865206d6178696d756d20736c617368206f6620612073746173682077697468696e206120736c617368696e67207370616e2c2061732077656c6c20617320686f77206d7563682072657761726420686173206265656e2070616964206f75742e20536c617368696e67207370616e7320666f72207374617368206163636f756e74732e20416c6c20736c617368696e67206576656e7473206f6e206e6f6d696e61746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682076616c7565206f6620746865206572612e20416c6c20736c617368696e67206576656e7473206f6e2076616c696461746f72732c206d61707065642062792065726120746f20746865206869676865737420736c6173682070726f706f7274696f6e20616e6420736c6173682076616c7565206f6620746865206572612e2041206d617070696e672066726f6d207374696c6c2d626f6e646564206572617320746f207468652066697273742073657373696f6e20696e646578206f662074686174206572612e204d75737420636f6e7461696e7320696e666f726d6174696f6e20666f72206572617320666f72207468652072616e67653a20605b6163746976655f657261202d20626f756e64696e675f6475726174696f6e3b206163746976655f6572615d6020416c6c20756e6170706c69656420736c61736865732074686174206172652071756575656420666f72206c617465722e2054686520616d6f756e74206f662063757272656e637920676976656e20746f207265706f7274657273206f66206120736c617368206576656e74207768696368207761732063616e63656c65642062792065787472616f7264696e6172792063697263756d7374616e6365732028652e672e20676f7665726e616e6365292e205468652070657263656e74616765206f662074686520736c617368207468617420697320646973747269627574656420746f207265706f72746572732e205468652072657374206f662074686520736c61736865642076616c75652069732068616e646c6564206279207468652060536c617368602e204d6f6465206f662065726120666f7263696e672e2054686520746f74616c20616d6f756e74207374616b656420666f7220746865206c6173742060484953544f52595f44455054486020657261732e20496620746f74616c206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207374616b652069732072657475726e65642e205265776172647320666f7220746865206c6173742060484953544f52595f44455054486020657261732e20496620726577617264206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e2030207265776172642069732072657475726e65642e2054686520746f74616c2076616c696461746f7220657261207061796f757420666f7220746865206c6173742060484953544f52595f44455054486020657261732e2045726173207468617420686176656e27742066696e697368656420796574206f7220686173206265656e2072656d6f76656420646f65736e27742068617665207265776172642e2053696d696c617220746f2060457261735374616b657273602c207468697320686f6c64732074686520707265666572656e636573206f662076616c696461746f72732e2054686973206973206b65796564206669727374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e2049732069742072656d6f7665642061667465722060484953544f52595f44455054486020657261732e20436c6970706564204578706f73757265206f662076616c696461746f72206174206572612e20546869732069732073696d696c617220746f205b60457261735374616b657273605d20627574206e756d626572206f66206e6f6d696e61746f7273206578706f736564206973207265647563656420746f207468652060543a3a4d61784e6f6d696e61746f72526577617264656450657256616c696461746f72602062696767657374207374616b6572732e20284e6f74653a20746865206669656c642060746f74616c6020616e6420606f776e60206f6620746865206578706f737572652072656d61696e7320756e6368616e676564292e2054686973206973207573656420746f206c696d69742074686520692f6f20636f737420666f7220746865206e6f6d696e61746f72207061796f75742e2054686973206973206b657965642066697374206279207468652065726120696e64657820746f20616c6c6f772062756c6b2064656c6574696f6e20616e64207468656e20746865207374617368206163636f756e742e204966207374616b657273206861736e2774206265656e20736574206f7220686173206265656e2072656d6f766564207468656e20656d707479206578706f737572652069732072657475726e65642e204578706f73757265206f662076616c696461746f72206174206572612e205468652073657373696f6e20696e646578206174207768696368207468652065726120737461727420666f7220746865206c6173742060484953544f52595f44455054486020657261732e20546865206163746976652065726120696e666f726d6174696f6e2c20697420686f6c647320696e64657820616e642073746172742e20546865206163746976652065726120697320746865206572612063757272656e746c792072657761726465642e2056616c696461746f7220736574206f66207468697320657261206d75737420626520657175616c20746f206053657373696f6e496e746572666163653a3a76616c696461746f7273602e205468652063757272656e742065726120696e6465782e205468697320697320746865206c617465737420706c616e6e6564206572612c20646570656e64696e67206f6e20686f77207468652053657373696f6e2070616c6c657420717565756573207468652076616c696461746f72207365742c206974206d6967687420626520616374697665206f72206e6f742e20546865206d61702066726f6d206e6f6d696e61746f72207374617368206b657920746f2074686520736574206f66207374617368206b657973206f6620616c6c2076616c696461746f727320746f206e6f6d696e6174652e20546865206d61702066726f6d202877616e6e616265292076616c696461746f72207374617368206b657920746f2074686520707265666572656e636573206f6620746861742076616c696461746f722e2057686572652074686520726577617264207061796d656e742073686f756c64206265206d6164652e204b657965642062792073746173682e204d61702066726f6d20616c6c2028756e6c6f636b6564292022636f6e74726f6c6c657222206163636f756e747320746f2074686520696e666f20726567617264696e6720746865207374616b696e672e204d61702066726f6d20616c6c206c6f636b65642022737461736822206163636f756e747320746f2074686520636f6e74726f6c6c6572206163636f756e742e20416e792076616c696461746f72732074686174206d6179206e6576657220626520736c6173686564206f7220666f726369626c79206b69636b65642e20497427732061205665632073696e63652074686579277265206561737920746f20696e697469616c697a6520616e642074686520706572666f726d616e636520686974206973206d696e696d616c2028776520657870656374206e6f206d6f7265207468616e20666f757220696e76756c6e657261626c65732920616e64207265737472696374656420746f20746573746e6574732e204d696e696d756d206e756d626572206f66207374616b696e67207061727469636970616e7473206265666f726520656d657267656e637920636f6e646974696f6e732061726520696d706f7365642e2054686520696465616c206e756d626572206f66207374616b696e67207061727469636970616e74732e204e756d626572206f66206572617320746f206b65657020696e20686973746f72792e20496e666f726d6174696f6e206973206b65707420666f72206572617320696e20605b63757272656e745f657261202d20686973746f72795f64657074683b2063757272656e745f6572615d602e204d757374206265206d6f7265207468616e20746865206e756d626572206f6620657261732064656c617965642062792073657373696f6e206f74686572776973652e20492e652e2061637469766520657261206d75737420616c7761797320626520696e20686973746f72792e20492e652e20606163746976655f657261203e2063757272656e745f657261202d20686973746f72795f646570746860206d7573742062652067756172616e746565642e000000000000e07810000e0000000000000097f612000c00000000000000301a1300f0781000000000000000000000791000010000000000000000000000087910000f00000000000000b51a10000800000000000000301a130018791000000000000000000028791000010000000000000053657373696f6e73506572457261000042000000000000000100000062000000697910001c000000426f6e64696e674475726174696f6e00420000000000000001000000630000003079100039000000204e756d626572206f6620657261732074686174207374616b65642066756e6473206d7573742072656d61696e20626f6e64656420666f722e204e756d626572206f662073657373696f6e7320706572206572612e65786163746c79206f6e65206f6620606d617962655f76616c696461746f726020616e6420606d617962655f6e6f6d696e6174696f6e2e69735f736f6d656020697320747275652e2069735f76616c696461746f722069732066616c73653b206d617962655f6e6f6d696e6174696f6e20697320736f6d653b207165640000147a1000330000005c090000220000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f7374616b696e672f7372632f6c69622e72730000000000361310000d00000000000000587d10000100000000000000000000002e1310000800000000000000607d1000010000000000000000000000211310000d00000000000000687d1000010000000000000000000000141310000d00000000000000707d1000010000000000000000000000081310000c00000000000000787d1000010000000000000000000000fa1210000e00000000000000807d1000010000000000000000000000e91210001100000000000000887d1000010000000000000000000000d81210001100000000000000907d1000010000000000000000000000cc1210000c00000000000000987d1000010000000000000000000000bf1210000d00000000000000a07d1000010000000000000000000000b31210000c00000000000000a87d1000010000000000000000000000a11210001200000000000000b07d1000010000000000000000000000871210001a00000000000000b87d1000010000000000000000000000751210001200000000000000c07d1000010000000000000000000000671210000e00000000000000c87d1000010000000000000000000000501210001700000000000000d07d10000100000000000000000000003a1210001600000000000000d87d1000010000000000000000000000271210001300000000000000e07d10000100000000000000000000000f1210001800000000000000e87d1000010000000000000000000000fc1110001300000000000000f07d1000020000000000000000000000e81110001400000000000000007e1000020000000000000000000000d21110001600000000000000107e1000010000000000000000000000bb1110001700000000000000187e1000010000000000000000000000a21110001900000000000000207e10000200000000000000000000008d1110001500000000000000307e10000100000000000000000000007c1110001100000000000000387e10000100000000000000000000006a1110001200000000000000407e10000100000000000000000000005c1110000e00000000000000487e100001000000000000002d8410001a0000001884100015000000ff83100019000000e18310001e000000c883100019000000b783100011000000958310002200000062831000330000003d831000250000001483100029000000e182100033000000ca82100017000000ab8210001f0000008a8210002100000047821000430000000e82100039000000ce811000400000009a811000340000006e8110002c0000000881100058000000608110000e0000008780100057000000de8010002a0000004280100045000000ef7f100053000000827f100058000000da7f100015000000397f100049000000e87e100051000000a27e100046000000507e100052000000205468652063616c6c206973206e6f7420616c6c6f7765642061742074686520676976656e2074696d652064756520746f207265737472696374696f6e73206f6620656c656374696f6e20706572696f642e2054686520636c61696d65642073636f726520646f6573206e6f74206d61746368207769746820746865206f6e6520636f6d70757465642066726f6d2074686520646174612e20546865207375626d697474656420726573756c742068617320756e6b6e6f776e206564676573207468617420617265206e6f7420616d6f6e67207468652070726573656e7465642077696e6e6572732e20412073656c6620766f7465206d757374206f6e6c79206265206f726967696e617465642066726f6d20612076616c696461746f7220746f204f4e4c59207468656d73656c7665732e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f72732068617320616e2065646765207768696368206973207375626d6974746564206265666f726520746865206c617374206e6f6e2d7a65726f20736c617368206f6620746865207461726765742e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f72732068617320616e206564676520746f20776869636820746865792068617665206e6f7420766f746564206f6e20636861696e2e204f6e65206f6620746865207375626d6974746564206e6f6d696e61746f7273206973206e6f7420616e20616374697665206e6f6d696e61746f72206f6e20636861696e2e204572726f72207768696c65206275696c64696e67207468652061737369676e6d656e7420747970652066726f6d2074686520636f6d706163742e20546869732063616e2068617070656e20696620616e20696e64657820697320696e76616c69642c206f72206966207468652077656967687473205f6f766572666c6f775f2e204f6e65206f6620746865207375626d69747465642077696e6e657273206973206e6f7420616e206163746976652063616e646964617465206f6e20636861696e2028696e646578206973206f7574206f662072616e676520696e20736e617073686f74292e20496e636f7272656374206e756d626572206f662077696e6e65727320776572652070726573656e7465642e2054686520736e617073686f742064617461206f66207468652063757272656e742077696e646f77206973206d697373696e672e20546865207375626d697474656420726573756c74206973206e6f7420617320676f6f6420617320746865206f6e652073746f726564206f6e20636861696e2e20546865207375626d697474656420726573756c74206973207265636569766564206f7574206f6620746865206f70656e2077696e646f772e205265776172647320666f72207468697320657261206861766520616c7265616479206265656e20636c61696d656420666f7220746869732076616c696461746f722e204974656d7320617265206e6f7420736f7274656420616e6420756e697175652e20496e76616c6964206e756d626572206f66206e6f6d696e6174696f6e732e20496e76616c69642065726120746f207265776172642e20417474656d7074696e6720746f2074617267657420612073746173682074686174207374696c6c206861732066756e64732e2043616e206e6f74207265626f6e6420776974686f757420756e6c6f636b696e67206368756e6b732e2043616e206e6f74207363686564756c65206d6f726520756e6c6f636b206368756e6b732e2043616e206e6f7420626f6e6420776974682076616c7565206c657373207468616e206d696e696d756d2062616c616e63652e20536c617368207265636f726420696e646578206f7574206f6620626f756e64732e204475706c696361746520696e6465782e20546172676574732063616e6e6f7420626520656d7074792e20436f6e74726f6c6c657220697320616c7265616479207061697265642e20537461736820697320616c726561647920626f6e6465642e204e6f742061207374617368206163636f756e742e204e6f74206120636f6e74726f6c6c6572206163636f756e742e00508410001a0000004552524f523a20436f7272757074656420737461746520617420446561644163636f756e744b656570416c6976654578697374656e7469616c4465706f736974496e73756666696369656e7442616c616e63654c69717569646974795265737472696374696f6e7356657374696e6742616c616e63657365745f62616c616e63657472616e736665725f6b6565705f616c697665546f74616c49737375616e636500000000000000d0851000070000000000000084111200020000000000000000000000d8851000010000000000000000000000e0851000080000000000000084111200020000000000000000000000e885100002000000000000000000000074ca110008000000000000007cca1100030000000000000000000000f8851000010000000000000000000000008610000a000000000000000c86100003000000000000000000000024861000010000000000000000000000c81912000700000000000000841112000200000000000000000000002c8610000100000000000000456e646f77656400318710002f000000447573744c6f7374c286100050000000128710001f0000009c8610002600000042616c616e6365536574000020af120009000000f615120007000000f6151200070000006b86100031000000348610003700000020536f6d6520616d6f756e7420776173206465706f73697465642028652e672e20666f72207472616e73616374696f6e2066656573292e20412062616c616e6365207761732073657420627920726f6f74202877686f2c20667265652c207265736572766564292e205472616e7366657220737563636565646564202866726f6d2c20746f2c2076616c7565292e20416e206163636f756e74207761732072656d6f7665642077686f73652062616c616e636520776173206e6f6e2d7a65726f206275742062656c6f77204578697374656e7469616c4465706f7369742c20726573756c74696e6720696e20616e206f75747269676874206c6f73732e20416e206163636f756e74207761732063726561746564207769746820736f6d6520667265652062616c616e63652e496e76616c69644f726967696e496e73756666696369656e7443616e64696461746546756e647352756e6e65725375626d69744d656d6265725375626d69744475706c69636174656443616e6469646174655265706f727453656c664d7573744265566f746572556e61626c65546f506179426f6e644c6f7742616c616e63654d6178696d756d566f7465734578636565646564546f6f4d616e79566f7465734e6f566f746573556e61626c65546f566f746572656d6f76655f766f7465727265706f72745f646566756e63745f766f7465727375626d69745f63616e64696461637972656e6f756e63655f63616e646964616379000000000000003489100007000000000000003c89100001000000000000000000000044891000040000000000000000000000648910000900000000000000301a130000000000000000000000000070891000020000000000000000000000808910000c0000000000000074ad12000100000000000000000000008c8910000200000000000000000000009c8910000f0000000000000074ad1200010000000000000000000000ac891000010000000000000000000000b48910000d00000000000000ac121200030000000000000000000000c489100002000000000000004e65775465726d00ad8c100019000000538b100056000000a98b100056000000ff8b100058000000578c100056000000456d7074795465726d000000d58a10004d000000228b1000310000004d656d6265724b69636b6564778a100051000000c88a10000d0000004d656d62657252656e6f756e636564004f8a100028000000566f7465725265706f72746564000000d4891000580000002c8a100023000000204120766f7465722028666972737420656c656d656e742920776173207265706f72746564202862797420746865207365636f6e6420656c656d656e742920776974682074686520746865207265706f7274206265696e67207375636365737366756c206f72206e6f742028746869726420656c656d656e74292e2041206d656d626572206861732072656e6f756e6365642074686569722063616e6469646163792e2041206d656d62657220686173206265656e2072656d6f7665642e20546869732073686f756c6420616c7761797320626520666f6c6c6f7765642062792065697468657220604e65775465726d60206f742060456d7074795465726d602e204e6f20286f72206e6f7420656e6f756768292063616e64696461746573206578697374656420666f72207468697320726f756e642e205468697320697320646966666572656e742066726f6d20604e65775465726d285b5d29602e2053656520746865206465736372697074696f6e206f6620604e65775465726d602e2041206e6577207465726d2077697468206e6577206d656d626572732e205468697320696e64696361746573207468617420656e6f7567682063616e64696461746573206578697374656420746f2072756e2074686520656c656374696f6e2c206e6f74207468617420656e6f756768206861766520686173206265656e20656c65637465642e2054686520696e6e65722076616c7565206d757374206265206578616d696e656420666f72207468697320707572706f73652e204120604e65775465726d285b5d296020696e64696361746573207468617420736f6d652063616e6469646174657320676f7420746865697220626f6e6420736c617368656420616e64206e6f6e65207765726520656c65637465642c207768696c73742060456d7074795465726d60206d65616e732074686174206e6f2063616e64696461746573206578697374656420746f20626567696e20776974682e5665633c284163636f756e7449642c2042616c616e6365293e52756e6e657273557000a48a12003e00000003030000190000003c8e10003c00000071000000130000003c8e10003c00000088000000180000003c8e10003c000000b4000000190000003c8e10003c000000ff000000420000003c8e10003c00000013010000420000004475706c696361746520766f74657220286f72206f7468657220636f727275707420696e707574292e0000003c8e10003c00000057010000150000003c8e10003c0000005c0100001e000000420000000000000001000000640000003c8e10003c0000005f0000001a0000003c8e10003c0000005f0000002c0000003c8e10003c000000cc010000240000003c8e10003c000000cd010000240000003c8e10003c000000f3010000240000003c8e10003c00000020020000240000003c8e10003c00000043020000350000003c8e10003c000000580200002b0000003c8e10003c00000059020000280000003c8e10003c000000630200002b0000003c8e10003c00000064020000280000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f70687261676d656e2f7372632f7265647563652e72730000000013db10000800000000000000288f1000020000000000000000000000588f10001b0000000000000000000000c68410000b0000000000000030901000030000000000000000000000789010001000000000000000000000001fdb10000e00000000000000f890100003000000000000000000000040911000060000000000000000000000d18410001300000000000000288f1000020000000000000000000000709110000b0000000000000000000000b2d311000400000000000000f32012002300000000000000aa4d120005000000000000000a941000130000003896100036000000301a1300000000006e96100042000000b096100048000000f8961000450000003d9710002d000000301a1300000000006a97100046000000301a130000000000f5bd12000b000000b09710004c000000fc971000330000002f9810005a000000301a1300000000008998100013000000301a1300000000009c98100054000000f09810004b0000003b991000350000007099100058000000c8991000520000001a9a10003e000000589a1000220000007a9a10004e000000c89a100037000000ff9a10004500000044be12000c00000000000000f02012000300000000000000f320120023000000000000002496100008000000000000000a94100013000000000000002c9610000c000000000000000a941000130000001d94100025000000301a13000000000042941000480000008a94100042000000cc941000460000001295100040000000301a130000000000529510002d000000301a130000000000f5bd12000b0000007f951000200000009f95100031000000d095100016000000e695100018000000fe9510002600000044be12000c00000000000000049410000600000000000000f32012002300000000000000b2d311000400000000000000f32012002300000000000000aa4d120005000000000000000a941000130000003193100054000000859310000b000000f5bd12000b0000009093100050000000e09310002400000044be12000c000000c8911000540000001c92100010000000301a1300000000002c9210002f000000301a1300000000005b92100031000000f5bd12000b0000008c9210003a000000c692100019000000df92100047000000269310000b0000002053616d6520617320746865205b607472616e73666572605d2063616c6c2c206275742077697468206120636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e20393925206f66207468652074696d6520796f752077616e74205b607472616e73666572605d20696e73746561642e205b607472616e73666572605d3a207374727563742e4d6f64756c652e68746d6c236d6574686f642e7472616e73666572202d2043686561706572207468616e207472616e736665722062656361757365206163636f756e742063616e6e6f74206265206b696c6c65642e202d2042617365205765696768743a2035372e333620c2b573202d204442205765696768743a2031205265616420616e64203120577269746520746f2064657374202873656e64657220697320696e206f7665726c617920616c72656164792920233c2f7765696768743e2045786163746c7920617320607472616e73666572602c2065786365707420746865206f726967696e206d75737420626520726f6f7420616e642074686520736f75726365206163636f756e74206d6179206265207370656369666965642e202d2053616d65206173207472616e736665722c20627574206164646974696f6e616c207265616420616e6420777269746520626563617573652074686520736f75726365206163636f756e742069732020206e6f7420617373756d656420746f20626520696e20746865206f7665726c61792e736f75726365436f6d706163743c543a3a42616c616e63653e20536574207468652062616c616e636573206f66206120676976656e206163636f756e742e20546869732077696c6c20616c74657220604672656542616c616e63656020616e642060526573657276656442616c616e63656020696e2073746f726167652e2069742077696c6c20616c736f2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d202860546f74616c49737375616e636560292e20496620746865206e65772066726565206f722072657365727665642062616c616e63652069732062656c6f7720746865206578697374656e7469616c206465706f7369742c2069742077696c6c20726573657420746865206163636f756e74206e6f6e63652028606672616d655f73797374656d3a3a4163636f756e744e6f6e636560292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c2069732060726f6f74602e202d20496e646570656e64656e74206f662074686520617267756d656e74732e202d20436f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e64207772697465732e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a2033322e3620c2b573202d204442205765696768743a203120526561642c203120577269746520746f206077686f606e65775f667265656e65775f7265736572766564205472616e7366657220736f6d65206c697175696420667265652062616c616e636520746f20616e6f74686572206163636f756e742e20607472616e73666572602077696c6c207365742074686520604672656542616c616e636560206f66207468652073656e64657220616e642072656365697665722e2049742077696c6c2064656372656173652074686520746f74616c2069737375616e6365206f66207468652073797374656d2062792074686520605472616e73666572466565602e204966207468652073656e6465722773206163636f756e742069732062656c6f7720746865206578697374656e7469616c206465706f736974206173206120726573756c74206f6620746865207472616e736665722c20746865206163636f756e742077696c6c206265207265617065642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605369676e65646020627920746865207472616e736163746f722e202d20446570656e64656e74206f6e20617267756d656e747320627574206e6f7420637269746963616c2c20676976656e2070726f70657220696d706c656d656e746174696f6e7320666f72202020696e70757420636f6e6669672074797065732e205365652072656c617465642066756e6374696f6e732062656c6f772e202d20497420636f6e7461696e732061206c696d69746564206e756d626572206f6620726561647320616e642077726974657320696e7465726e616c6c7920616e64206e6f20636f6d706c657820636f6d7075746174696f6e2e2052656c617465642066756e6374696f6e733a2020202d2060656e737572655f63616e5f77697468647261776020697320616c776179732063616c6c656420696e7465726e616c6c792062757420686173206120626f756e64656420636f6d706c65786974792e2020202d205472616e7366657272696e672062616c616e63657320746f206163636f756e7473207468617420646964206e6f74206578697374206265666f72652077696c6c20636175736520202020202060543a3a4f6e4e65774163636f756e743a3a6f6e5f6e65775f6163636f756e746020746f2062652063616c6c65642e2020202d2052656d6f76696e6720656e6f7567682066756e64732066726f6d20616e206163636f756e742077696c6c20747269676765722060543a3a4475737452656d6f76616c3a3a6f6e5f756e62616c616e636564602e2020202d20607472616e736665725f6b6565705f616c6976656020776f726b73207468652073616d652077617920617320607472616e73666572602c206275742068617320616e206164646974696f6e616c2020202020636865636b207468617420746865207472616e736665722077696c6c206e6f74206b696c6c20746865206f726967696e206163636f756e742e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a20383020c2b5732c20776f7273742063617365207363656e6172696f20286163636f756e7420637265617465642c206163636f756e742072656d6f76656429202d204442205765696768743a2031205265616420616e64203120577269746520746f2064657374696e6174696f6e206163636f756e74202d204f726967696e206163636f756e7420697320616c726561647920696e206d656d6f72792c20736f206e6f204442206f7065726174696f6e7320666f72207468656d2e00000000e48410000d0000000000000000000000a49c10000a00000000000000000000000000000000000000000000000000000000000000301a1300b09c10000000000000000000c09c10000100000000000000010000000000000057e211000700000001020000000000007ac312000c00000000000000c89c10001700000000000000000000000000000000000000301a1300e09c10000000000000000000f09c100006000000000000000100000000000000389111000500000001020000000000007ac312000c00000000000000209d10001c00000000000000000000000000000000000000301a13003c9d100000000000000000004c9d1000020000000000000001000000000000005c9d10000e00000000000000000000006a9d10000800000000000000000000000000000000000000000000000000000000000000301a1300749d10000000000000000000849d1000030000000000000001000000543a3a42616c616e636500004200000000000000010000005f0000004b9f1000260000004163636f756e74446174613c543a3a42616c616e63653e00420000000000000001000000650000005a9e10001b000000301a130000000000759e100056000000cb9e100030000000301a130000000000fb9e1000500000005665633c42616c616e63654c6f636b3c543a3a42616c616e63653e3e42000000000000000100000059000000e39d10002e000000119e10004900000053746f7261676556657273696f6e52656c656173657300004200000000000000010000005a0000009c9d10001f000000301a130000000000bb9d1000280000002053746f726167652076657273696f6e206f66207468652070616c6c65742e20546869732069732073657420746f2076322e302e3020666f72206e6577206e6574776f726b732e20416e79206c6971756964697479206c6f636b73206f6e20736f6d65206163636f756e742062616c616e6365732e204e4f54453a2053686f756c64206f6e6c79206265206163636573736564207768656e2073657474696e672c206368616e67696e6720616e642066726565696e672061206c6f636b2e205468652062616c616e6365206f6620616e206163636f756e742e204e4f54453a2054484953204d4159204e4556455220424520494e204558495354454e434520414e4420594554204841564520412060746f74616c28292e69735f7a65726f2829602e2049662074686520746f74616c2069732065766572207a65726f2c207468656e2074686520656e747279202a4d5553542a2062652072656d6f7665642e204e4f54453a2054686973206973206f6e6c79207573656420696e20746865206361736520746861742074686973206d6f64756c65206973207573656420746f2073746f72652062616c616e6365732e2054686520746f74616c20756e6974732069737375656420696e207468652073797374656d2e000000000000007e8410001200000000000000a49c10000a00000000000000301a1300d4b110000000000000000000ac9f10000100000000000000b49f10003500000020546865206d696e696d756d20616d6f756e7420726571756972656420746f206b65657020616e206163636f756e74206f70656e2e0000000000000014b012000400000000000000f4a0100002000000000000000000000024a110000f0000000000000000000000138810000c00000000000000301a13000000000000000000000000009ca110000700000000000000000000001f8810001400000000000000b4471100010000000000000000000000d4a110000d0000000000000000000000338810001000000000000000301a13000000000000000000000000003ca210000d0000000000000000000000438810001200000000000000301a1300000000000000000000000000a4a2100009000000000000000000000087e411000d00000000000000eca2100001000000000000000000000004a310000d000000000000000000000052ac10000500000000000000ddce12001100000000000000aa4d120005000000000000008075120015000000b8aa100041000000301a130000000000f9aa1000140000000dab1000120000001fab10002b000000301a1300000000004aab100057000000a1ab100057000000f8ab100028000000301a130000000000f5bd12000b000000c7a410000b000000acaa10000c00000020ac10003200000044be12000c00000064aa100048000000301a130000000000f5bd12000b000000c7a410000b000000acaa10000c000000aba810000d00000044be12000c000000b8a81000570000000fa910005700000066a9100017000000301a1300000000007da91000220000009fa9100053000000f2a910002d000000301a130000000000f5bd12000b000000c7a410000b0000001faa100045000000aba810000d00000044be12000c00000069a710001e000000301a13000000000087a7100019000000a0a710003b000000dba710004b00000026a81000550000007ba810000d000000301a130000000000f5bd12000b000000c7a410000b00000088a8100023000000aba810000d00000044be12000c000000ffa410005400000053a510001000000063a5100050000000b3a510003d000000f0a510005600000046a610002100000067a6100053000000baa610005600000010a710005900000000000000f02012000300000000000000f3201200230000006ca3100057000000c3a3100020000000301a130000000000e3a310005600000039a410003d000000301a13000000000076a4100051000000301a130000000000f5bd12000b000000c7a410000b000000d2a4100016000000e8a410001700000044be12000c0000002052656d6f7665206120706172746963756c6172206d656d6265722066726f6d20746865207365742e20546869732069732065666665637469766520696d6d6564696174656c7920616e642074686520626f6e64206f6620746865206f7574676f696e67206d656d62657220697320736c61736865642e20496620612072756e6e65722d757020697320617661696c61626c652c207468656e2074686520626573742072756e6e65722d75702077696c6c2062652072656d6f76656420616e64207265706c6163657320746865206f7574676f696e67206d656d6265722e204f74686572776973652c2061206e65772070687261676d656e20726f756e6420697320737461727465642e204e6f74652074686174207468697320646f6573206e6f7420616666656374207468652064657369676e6174656420626c6f636b206e756d626572206f6620746865206e65787420656c656374696f6e2e20232323232053746174652052656164733a204f28646f5f70687261676d656e29205772697465733a204f28646f5f70687261676d656e292052656e6f756e6365206f6e65277320696e74656e74696f6e20746f20626520612063616e64696461746520666f7220746865206e65787420656c656374696f6e20726f756e642e203320706f74656e7469616c206f7574636f6d65732065786973743a202d20606f726967696e6020697320612063616e64696461746520616e64206e6f7420656c656374656420696e20616e79207365742e20496e207468697320636173652c2074686520626f6e64206973202020756e72657365727665642c2072657475726e656420616e64206f726967696e2069732072656d6f76656420617320612063616e6469646174652e202d20606f726967696e6020697320612063757272656e742072756e6e65722075702e20496e207468697320636173652c2074686520626f6e6420697320756e72657365727665642c2072657475726e656420616e642020206f726967696e2069732072656d6f76656420617320612072756e6e65722e202d20606f726967696e6020697320612063757272656e74206d656d6265722e20496e207468697320636173652c2074686520626f6e6420697320756e726573657276656420616e64206f726967696e20697320202072656d6f7665642061732061206d656d6265722c20636f6e73657175656e746c79206e6f74206265696e6720612063616e64696461746520666f7220746865206e65787420726f756e6420616e796d6f72652e20202053696d696c617220746f205b6072656d6f76655f766f746572605d2c206966207265706c6163656d656e742072756e6e657273206578697374732c20746865792061726520696d6d6564696174656c7920757365642e205375626d6974206f6e6573656c6620666f722063616e6469646163792e20412063616e6469646174652077696c6c206569746865723a2020202d204c6f73652061742074686520656e64206f6620746865207465726d20616e6420666f7266656974207468656972206465706f7369742e2020202d2057696e20616e64206265636f6d652061206d656d6265722e204d656d626572732077696c6c206576656e7475616c6c7920676574207468656972207374617368206261636b2e2020202d204265636f6d6520612072756e6e65722d75702e2052756e6e6572732d75707320617265207265736572766564206d656d6265727320696e2063617365206f6e65206765747320666f72636566756c6c79202020202072656d6f7665642e2052656164733a204f284c6f674e2920476976656e204e2063616e646964617465732e205772697465733a204f283129205265706f727420607461726765746020666f72206265696e6720616e20646566756e637420766f7465722e20496e2063617365206f6620612076616c6964207265706f72742c20746865207265706f727465722069732072657761726465642062792074686520626f6e6420616d6f756e74206f662060746172676574602e204f74686572776973652c20746865207265706f7274657220697473656c662069732072656d6f76656420616e6420746865697220626f6e6420697320736c61736865642e204120646566756e637420766f74657220697320646566696e656420746f2062653a2020202d206120766f7465722077686f73652063757272656e74207375626d697474656420766f7465732061726520616c6c20696e76616c69642e20692e652e20616c6c206f66207468656d20617265206e6f20202020206c6f6e67657220612063616e646964617465206e6f7220616e20616374697665206d656d6265722e2052656164733a204f284e4c6f674d2920676976656e204d2063757272656e742063616e6469646174657320616e64204e20766f74657320666f722060746172676574602e2052656d6f766520606f726967696e60206173206120766f7465722e20546869732072656d6f76657320746865206c6f636b20616e642072657475726e732074686520626f6e642e2052656164733a204f28312920566f746520666f72206120736574206f662063616e6469646174657320666f7220746865207570636f6d696e6720726f756e64206f6620656c656374696f6e2e205468652060766f746573602073686f756c643a2020202d206e6f7420626520656d7074792e2020202d206265206c657373207468616e20746865206e756d626572206f662063616e646964617465732e2055706f6e20766f74696e672c206076616c75656020756e697473206f66206077686f6027732062616c616e6365206973206c6f636b656420616e64206120626f6e6420616d6f756e742069732072657365727665642e2049742069732074686520726573706f6e736962696c697479206f66207468652063616c6c657220746f206e6f7420706c61636520616c6c206f662074686569722062616c616e636520696e746f20746865206c6f636b20616e64206b65657020736f6d6520666f722066757274686572207472616e73616374696f6e732e205772697465733a204f28562920676976656e2060566020766f7465732e205620697320626f756e6465642062792031362e766f746573000000000009b5120007000000000000000000000010ae10002100000000000000000000000000000000000000000000000000000000000000301a13003cae1000000000000000000034ae100001000000000000000100000000000000c68c100009000000000000000000000010ae10002100000000000000000000000000000000000000000000000000000000000000301a13003cae100000000000000000004cae10000100000000000000010000000000000030f212000e000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a130054ae1000000000000000000064ae10000100000000000000010000000000000010b512000600000001050000000000007ac312000c00000000000000a48f11002100000000000000000000000000000000000000301a13006cae100000000000000000007cae100001000000000000000100000000000000611c12000a0000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a130084ae1000000000000000000094ae10000200000000000000010000005665633c28543a3a4163636f756e7449642c2042616c616e63654f663c543e293e0000001ab010003c00000042000000000000000100000059000000c8af1000520000004200000000000000010000005700000078af100050000000420000000000000001000000660000004aaf10002e00000042000000000000000100000059000000a4ae100056000000faae100050000000205468652070726573656e742063616e646964617465206c6973742e20536f72746564206261736564206f6e206163636f756e742d69642e20412063757272656e74206d656d626572206f722072756e6e65722d75702063616e206e6576657220656e746572207468697320766563746f7220616e6420697320616c7761797320696d706c696369746c7920617373756d656420746f20626520612063616e6469646174652e20566f74657320616e64206c6f636b6564207374616b65206f66206120706172746963756c617220766f7465722e2054686520746f74616c206e756d626572206f6620766f746520726f756e6473207468617420686176652068617070656e65642c206578636c7564696e6720746865207570636f6d696e67206f6e652e205468652063757272656e742072756e6e6572735f75702e20536f72746564206261736564206f6e206c6f7720746f2068696768206d657269742028776f72736520746f20626573742072756e6e6572292e205468652063757272656e7420656c6563746564206d656d626572736869702e20536f72746564206261736564206f6e206163636f756e742069642e000000000000a8b110000d00000000000000b66c12000c00000000000000301a1300b8b110000000000000000000301a1300000000000000000000000000c8b110000a00000000000000b66c12000c00000000000000301a1300d4b110000000000000000000301a1300000000000000000000000000e4b110000e0000000000000060dc12000300000000000000301a1300f4b110000000000000000000301a130000000000000000000000000004b21000100000000000000060dc12000300000000000000301a130014b210000000000000000000301a130000000000000000000000000024b210000c0000000000000006cf12000e00000000000000301a130030b210000000000000000000301a1300000000000000000000000000cc5e1200080000000000000040b210000e00000000000000301a130050b210000000000000000000301a1300000000000000000043616e646964616379426f6e6400000042000000000000000100000067000000566f74696e67426f6e64000042000000000000000100000068000000446573697265644d656d626572730000420000000000000001000000690000004465736972656452756e6e65727355704200000000000000010000006a0000005465726d4475726174696f6e4200000000000000010000006b0000004c6f636b4964656e74696669657200004200000000000000010000006c00000000000000b88410000e0000000000000040b31000010000000000000000000000a3841000150000000000000048b3100001000000000000000000000027ab1200080000000000000050b3100001000000000000000000000090841000130000000000000058b310000100000000000000000000007e841000120000000000000060b3100001000000000000000000000075841000090000000000000068b31000010000000000000000000000aa371100170000000000000070b310000100000000000000000000006a8410000b0000000000000078b310000100000000000000a2b410002700000070b410003200000053b410001d00000035b410001e000000fab310003b000000d6b3100024000000a3b310003300000080b31000230000002042656e6566696369617279206163636f756e74206d757374207072652d657869737420412076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e74205472616e736665722f7061796d656e7420776f756c64206b696c6c206163636f756e742056616c756520746f6f206c6f7720746f20637265617465206163636f756e742064756520746f206578697374656e7469616c206465706f7369742042616c616e636520746f6f206c6f7720746f2073656e642076616c756520476f7420616e206f766572666c6f7720616674657220616464696e67204163636f756e74206c6971756964697479207265737472696374696f6e732070726576656e74207769746864726177616c2056657374696e672062616c616e636520746f6f206869676820746f2073656e642076616c756500000000000000078810000c0000000000000054b610000100000000000000000000000088100007000000000000005cb61000010000000000000000000000f48710000c0000000000000064b61000010000000000000000000000e087100014000000000000006cb61000010000000000000000000000d68710000a0000000000000074b61000010000000000000000000000c78710000f000000000000007cb61000010000000000000000000000bc8710000b0000000000000084b61000010000000000000000000000b28710000a000000000000008cb610000100000000000000000000009f871000130000000000000094b61000010000000000000000000000938710000c000000000000009cb61000010000000000000000000000878710000c00000000000000a4b610000100000000000000000000006d8710001a00000000000000acb61000010000000000000000000000608710000d00000000000000b4b61000010000000000000000000000f2af12000900000000000000bcb61000010000000000000076b810003100000050b81000260000002eb810002200000007b8100027000000d5b7100032000000b6b710001f000000a5b710001100000091b710001400000070b71000210000004db71000230000002ab710002300000004b7100026000000d2b6100032000000c4b610000e000000204e6f742061206d656d6265722e204f726967696e206973206e6f7420612063616e6469646174652c206d656d626572206f7220612072756e6e65722075702e2043616e64696461746520646f6573206e6f74206861766520656e6f7567682066756e64732e2052756e6e65722063616e6e6f742072652d7375626d69742063616e6469646163792e204d656d6265722063616e6e6f742072652d7375626d69742063616e6469646163792e204475706c6963617465642063616e646964617465207375626d697373696f6e2e2043616e6e6f74207265706f72742073656c662e204d757374206265206120766f7465722e20566f7465722063616e206e6f742070617920766f74696e6720626f6e642e2043616e6e6f7420766f74652077697468207374616b65206c657373207468616e206d696e696d756d2062616c616e63652e2043616e6e6f7420766f7465206d6f7265207468616e206d6178696d756d20616c6c6f7765642e2043616e6e6f7420766f7465206d6f7265207468616e2063616e646964617465732e204d75737420766f746520666f72206174206c65617374206f6e652063616e6469646174652e2043616e6e6f7420766f7465207768656e206e6f2063616e64696461746573206f72206d656d626572732065786973742e556e657870656374656454696d65706f696e7457726f6e6754696d65706f696e744e6f54696d65706f696e7453656e646572496e5369676e61746f726965735369676e61746f726965734f75744f664f72646572546f6f4d616e795369676e61746f72696573546f6f4665775369676e61746f726965734e6f417070726f76616c734e6565646564416c7265616479417070726f766564626174636861735f73756261735f6d756c7469617070726f76655f61735f6d756c746963616e63656c5f61735f6d756c74690000000078ba1000100000000000000088ba100002000000000000000000000098ba1000020000000000000000000000a8ba10000e00000000000000301a1300000000000000000000000000b8ba1000010000000000000000000000c0ba10000b00000000000000ccba1000030000000000000000000000e4ba1000020000000000000000000000f4ba1000100000000000000004bb100004000000000000000000000024bb100002000000000000000000000034bb1000100000000000000044bb10000500000000000000000000006cbb10000200000000000000000000007cbb1000110000000000000004bb100004000000000000000000000090bb100002000000000000004261746368496e74657272757074656460dc120003000000e00e13000d0000004dbe100056000000a3be1000130000004261746368436f6d706c6574656400001abe1000330000004e65774d756c74697369670020af12000900000020af120009000000e9bc1000080000008dbd100052000000dfbd10003b0000004d756c7469736967417070726f76616c20af120009000000d3bc10001600000020af120009000000e9bc100008000000f1bc10005600000047bd1000460000004d756c7469736967457865637574656420af120009000000d3bc10001600000020af120009000000e9bc100008000000940d12000e00000033bc10004b0000007ebc1000550000004d756c746973696743616e63656c6c6564000000a0bb10004c000000ecbb1000470000002041206d756c7469736967206f7065726174696f6e20686173206265656e2063616e63656c6c65642e20466972737420706172616d20697320746865206163636f756e7420746861742069732063616e63656c6c696e672c20746869726420697320746865206d756c7469736967206163636f756e742c20666f757274682069732068617368206f66207468652063616c6c2e2041206d756c7469736967206f7065726174696f6e20686173206265656e2065786563757465642e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c20746869726420697320746865206d756c7469736967206163636f756e742c20666f757274682069732068617368206f66207468652063616c6c20746f2062652065786563757465642e54696d65706f696e743c426c6f636b4e756d6265723e43616c6c486173682041206d756c7469736967206f7065726174696f6e20686173206265656e20617070726f76656420627920736f6d656f6e652e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c20746869726420697320746865206d756c7469736967206163636f756e742c20666f757274682069732068617368206f66207468652063616c6c2e2041206e6577206d756c7469736967206f7065726174696f6e2068617320626567756e2e20466972737420706172616d20697320746865206163636f756e74207468617420697320617070726f76696e672c207365636f6e6420697320746865206d756c7469736967206163636f756e742c2074686972642069732068617368206f66207468652063616c6c2e204261746368206f66206469737061746368657320636f6d706c657465642066756c6c792077697468206e6f206572726f722e204261746368206f66206469737061746368657320646964206e6f7420636f6d706c6574652066756c6c792e20496e646578206f66206669727374206661696c696e6720646973706174636820676976656e2c2061732077656c6c20617320746865206572726f722e0000000000003eb91000050000000000000094bf1000010000000000000000000000acbf100013000000000000000000000043b91000060000000000000044c0100002000000000000000000000074c0100008000000000000000000000049b910000800000000000000b4c0100004000000000000000000000014c1100032000000000000000000000051b910001000000000000000a4c2100004000000000000000000000004c3100027000000000000000000000061b910000f000000000000003cc410000400000000000000000000009cc410001b00000000000000000000000bd41000050000000000000010d410001700000071d1100020000000301a13000000000091d110003b000000301a130000000000ccd110001f000000301a130000000000ebd110003c000000301a130000000000f5bd12000b00000027d21000240000004bd210002e00000079d210003100000044be12000c000000301a130000000000aad210005600000000d310004d0000004dd3100056000000a3d3100054000000f7d31000140000000000000098d912000500000000000000f7ce12000300000000000000fbea1200040000000000000061d112001700000000d1100038000000301a13000000000098c9120034000000301a130000000000f5bd12000b00000038d110001900000051d110002000000044be12000c00000000000000eece12000900000000000000f7ce120003000000000000005ec910001100000000000000ddce1200110000000000000092cd10000f00000000000000a1cd10002100000000000000fbea1200040000000000000061d1120017000000a2c9100056000000f8c910003f000000301a130000000000c2cd10002d000000301a13000000000037ca1000540000008bca100058000000e3ca10000e000000301a13000000000098c9120034000000301a130000000000fcc510005600000052c6100051000000a3c610001c000000f1ca10005700000048cb1000550000009dcb100036000000efcd100023000000301a13000000000012ce1000480000005ace100047000000301a130000000000a1ce100057000000f8ce1000560000004ecf100038000000301a130000000000f5bd12000b00000086cf1000150000006ac71000340000009ec7100050000000eec71000520000009bcf10004900000040c810003000000021cc10003600000057cc10003f0000002bc112000d000000e4cf10001c00000096cc10004c000000e2cc10002400000006cd10003d00000000d010002000000043cd10000f00000020d010002300000043d010002400000067d0100025000000f2c810000d0000008cd0100030000000bcd0100031000000edd010001300000044be12000c00000000000000eece12000900000000000000f7ce120003000000000000005ec910001100000000000000ddce1200110000000000000092cd10000f00000000000000a1cd1000210000000000000091c9100009000000000000009ac9100008000000a2c9100056000000f8c910003f000000301a13000000000037ca1000540000008bca100058000000e3ca10000e000000301a13000000000098c9120034000000301a130000000000fcc510005600000052c6100051000000a3c610001c000000f1ca10005700000048cb1000550000009dcb10003600000036c7100034000000301a130000000000d3cb10004e000000301a130000000000f5bd12000b000000af8811000a0000006ac71000340000009ec7100050000000eec710005200000040c810003000000021cc10003600000057cc10003f0000002bc112000d00000096cc10004c000000e2cc10002400000006cd10003d000000afc810002300000043cd10000f00000052cd10001f00000071cd100021000000f2c810000d000000ffc810002f0000002ec910003000000044be12000c00000000000000eece12000900000000000000f7ce120003000000000000005ec910001100000000000000ddce120011000000000000006fc91000090000000000000078c91000190000000000000091c9100009000000000000009ac910000800000074c5100056000000cac5100032000000301a13000000000098c9120034000000301a130000000000fcc510005600000052c6100051000000a3c610001c000000bfc610005800000017c710001f00000036c7100034000000301a130000000000f5bd12000b000000af8811000a0000006ac71000340000009ec7100050000000eec710005200000040c81000300000002bc112000d00000070c810002200000092c810001d000000afc8100023000000d2c8100020000000f2c810000d000000ffc810002f0000002ec910003000000044be12000c0000002043616e63656c2061207072652d6578697374696e672c206f6e2d676f696e67206d756c7469736967207472616e73616374696f6e2e20416e79206465706f7369742072657365727665642070726576696f75736c7920666f722074686973206f7065726174696f6e2077696c6c20626520756e7265736572766564206f6e20737563636573732e202d20607468726573686f6c64603a2054686520746f74616c206e756d626572206f6620617070726f76616c7320666f722074686973206469737061746368206265666f72652069742069732065786563757465642e202d20606f746865725f7369676e61746f72696573603a20546865206163636f756e747320286f74686572207468616e207468652073656e646572292077686f2063616e20617070726f766520746869732064697370617463682e204d6179206e6f7420626520656d7074792e202d206074696d65706f696e74603a205468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e20666f7220746869732064697370617463682e202d206063616c6c5f68617368603a205468652068617368206f66207468652063616c6c20746f2062652065786563757465642e202d20557020746f206f6e652062616c616e63652d72657365727665206f7220756e72657365727665206f7065726174696f6e2e202d204f6e6520706173737468726f756768206f7065726174696f6e2c206f6e6520696e736572742c20626f746820604f285329602077686572652060536020697320746865206e756d626572206f662020207369676e61746f726965732e206053602069732063617070656420627920604d61785369676e61746f72696573602c207769746820776569676874206265696e672070726f706f7274696f6e616c2e202d204f6e6520656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285329602e202d20492f4f3a2031207265616420604f285329602c206f6e652072656d6f76652e202d2053746f726167653a2072656d6f766573206f6e65206974656d2e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d202d2042617365205765696768743a2034362e3731202b20302e3039202a2053202d204442205765696768743a20202020202d20526561643a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d20202020202d2057726974653a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d6f746865725f7369676e61746f7269657374696d65706f696e7454696d65706f696e743c543a3a426c6f636b4e756d6265723e63616c6c5f686173685b75383b2033325d20526567697374657220617070726f76616c20666f72206120646973706174636820746f206265206d6164652066726f6d20612064657465726d696e697374696320636f6d706f73697465206163636f756e7420696620617070726f766564206279206120746f74616c206f6620607468726573686f6c64202d203160206f6620606f746865725f7369676e61746f72696573602e205061796d656e743a20604d756c74697369674465706f73697442617365602077696c6c20626520726573657276656420696620746869732069732074686520666972737420617070726f76616c2c20706c757320607468726573686f6c64602074696d657320604d756c74697369674465706f736974466163746f72602e2049742069732072657475726e6564206f6e636520746869732064697370617463682068617070656e73206f722069732063616e63656c6c65642e202d20606d617962655f74696d65706f696e74603a20496620746869732069732074686520666972737420617070726f76616c2c207468656e2074686973206d75737420626520604e6f6e65602e204966206974206973206e6f742074686520666972737420617070726f76616c2c207468656e206974206d7573742062652060536f6d65602c2077697468207468652074696d65706f696e742028626c6f636b206e756d62657220616e64207472616e73616374696f6e20696e64657829206f662074686520666972737420617070726f76616c207472616e73616374696f6e2e204e4f54453a2049662074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2077616e7420746f20757365206061735f6d756c74696020696e73746561642e202d20557020746f206f6e652062696e6172792073656172636820616e6420696e736572742028604f286c6f6753202b20532960292e202d20492f4f3a2031207265616420604f285329602c20757020746f2031206d757461746520604f285329602e20557020746f206f6e652072656d6f76652e202d2053746f726167653a20696e7365727473206f6e65206974656d2c2076616c75652073697a6520626f756e64656420627920604d61785369676e61746f72696573602c207769746820612020206465706f7369742074616b656e20666f7220697473206c69666574696d65206f66202020604d756c74697369674465706f73697442617365202b207468726573686f6c64202a204d756c74697369674465706f736974466163746f72602e202d2042617365205765696768743a20202020202d204372656174653a2035362e33202b20302e313037202a205320202020202d20417070726f76653a2033392e3235202b20302e313231202a20536d617962655f74696d65706f696e744f7074696f6e3c54696d65706f696e743c543a3a426c6f636b4e756d6265723e3e2049662074686572652061726520656e6f7567682c207468656e206469737061746368207468652063616c6c2e202d206063616c6c603a205468652063616c6c20746f2062652065786563757465642e204e4f54453a20556e6c6573732074686973206973207468652066696e616c20617070726f76616c2c20796f752077696c6c2067656e6572616c6c792077616e7420746f207573652060617070726f76655f61735f6d756c74696020696e73746561642c2073696e6365206974206f6e6c7920726571756972657320612068617368206f66207468652063616c6c2e20526573756c74206973206571756976616c656e7420746f20746865206469737061746368656420726573756c7420696620607468726573686f6c64602069732065786163746c79206031602e204f7468657277697365206f6e20737563636573732c20726573756c7420697320604f6b6020616e642074686520726573756c742066726f6d2074686520696e746572696f722063616c6c2c206966206974207761732065786563757465642c206d617920626520666f756e6420696e20746865206465706f736974656420604d756c7469736967457865637574656460206576656e742e202d20604f2853202b205a202b2043616c6c29602e202d204f6e652063616c6c20656e636f6465202620686173682c20626f7468206f6620636f6d706c657869747920604f285a296020776865726520605a602069732074782d6c656e2e202d2054686520776569676874206f6620746865206063616c6c602e202d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d20202020202d204372656174653a2035392e32202b20302e303936202a205320c2b57320202020202d20417070726f76653a2034322e3237202b202e313136202a205320c2b57320202020202d20436f6d706c6574653a2035302e3931202b202e323332202a205320c2b57320202020202d2052656164733a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d20202020202d205772697465733a204d756c74697369672053746f726167652c205b43616c6c6572204163636f756e745d202d20506c75732043616c6c205765696768742053656e6420612063616c6c207468726f75676820616e20696e64657865642070736575646f6e796d206f66207468652073656e6465722e202d2042617365207765696768743a20322e38363320c2b573202d20506c75732074686520776569676874206f6620746865206063616c6c602053656e642061206261746368206f662064697370617463682063616c6c732e20546869732077696c6c206578656375746520756e74696c20746865206669727374206f6e65206661696c7320616e64207468656e2073746f702e204d61792062652063616c6c65642066726f6d20616e79206f726967696e2e202d206063616c6c73603a205468652063616c6c7320746f20626520646973706174636865642066726f6d207468652073616d65206f726967696e2e202d2042617365207765696768743a2031352e3634202b202e393837202a206320c2b573202d20506c7573207468652073756d206f66207468652077656967687473206f6620746865206063616c6c73602e202d20506c7573206f6e65206164646974696f6e616c206576656e742e202872657065617420726561642f77726974652920546869732077696c6c2072657475726e20604f6b6020696e20616c6c2063697263756d7374616e6365732e20546f2064657465726d696e65207468652073756363657373206f66207468652062617463682c20616e206576656e74206973206465706f73697465642e20496620612063616c6c206661696c656420616e64207468652062617463682077617320696e7465727275707465642c207468656e2074686520604261746368496e74657272757074656460206576656e74206973206465706f73697465642c20616c6f6e67207769746820746865206e756d626572206f66207375636365737366756c2063616c6c73206d61646520616e6420746865206572726f72206f6620746865206661696c65642063616c6c2e20496620616c6c2077657265207375636365737366756c2c207468656e2074686520604261746368436f6d706c6574656460206576656e74206973206465706f73697465642e63616c6c735665633c3c542061732054726169743e3a3a43616c6c3e000000000080d410000900000002050200000000007ac312000c000000000000009ac91000080000000000000089d410003400000000000000301a1300c0d410000000000000000000d0d410000100000000000000000000004d756c7469736967734d756c74697369673c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e0000004200000000000000010000005b000000d8d41000250000002054686520736574206f66206f70656e206d756c7469736967206f7065726174696f6e732e6d6f646c70792f7574696c697375626100000000000000c0ab12000d0000000000000060d610000100000000000000000000002fb910000f0000000000000068d610000100000000000000000000001eb91000110000000000000070d610000100000000000000000000000db91000110000000000000078d61000010000000000000000000000fbb81000120000000000000080d61000010000000000000000000000e6b81000150000000000000088d61000010000000000000000000000d3b81000130000000000000090d61000010000000000000000000000d0dc1000080000000000000098d61000010000000000000000000000fbda10000800000000000000a0d61000010000000000000000000000c8b810000b00000000000000a8d61000010000000000000000000000bab810000e00000000000000b0d61000010000000000000000000000a7b810001300000000000000b8d61000010000000000000049d910001d0000001dd910002c000000f5d8100028000000cad810002b0000009ed810002c0000005ad810004400000016d8100044000000ded710003800000092d710004c0000004ad7100048000000fed610004c000000c0d610003e00000020412074696d65706f696e742077617320676976656e2c20796574206e6f206d756c7469736967206f7065726174696f6e20697320756e6465727761792e204120646966666572656e742074696d65706f696e742077617320676976656e20746f20746865206d756c7469736967206f7065726174696f6e207468617420697320756e6465727761792e204e6f2074696d65706f696e742077617320676976656e2c2079657420746865206d756c7469736967206f7065726174696f6e20697320616c726561647920756e6465727761792e204f6e6c7920746865206163636f756e742074686174206f726967696e616c6c79206372656174656420746865206d756c74697369672069732061626c6520746f2063616e63656c2069742e204d756c7469736967206f7065726174696f6e206e6f7420666f756e64207768656e20617474656d7074696e6720746f2063616e63656c2e205468652073656e6465722077617320636f6e7461696e656420696e20746865206f74686572207369676e61746f726965733b2069742073686f756c646e27742062652e20546865207369676e61746f7269657320776572652070726f7669646564206f7574206f66206f726465723b20746865792073686f756c64206265206f7264657265642e2054686572652061726520746f6f206d616e79207369676e61746f7269657320696e20746865206c6973742e2054686572652061726520746f6f20666577207369676e61746f7269657320696e20746865206c6973742e2043616c6c20646f65736e2774206e65656420616e7920286d6f72652920617070726f76616c732e2043616c6c20697320616c726561647920617070726f7665642062792074686973207369676e61746f72792e205468726573686f6c6420697320746f6f206c6f7720287a65726f292e0000abd910000d00000090d910001b0000005c09120002000000a2a3120036000000e20200000100000042616420696e70757420646174612070726f766964656420746f20657865637574655f626c6f636bc0d9100010000000696e697469616c697a655f626c6f636bd8d910000f0000006170706c795f65787472696e73696300f0d9100013000000696e686572656e745f65787472696e73696373000cda10000f000000636865636b5f696e686572656e74730024da10001400000076616c69646174655f7472616e73616374696f6e40da10000f0000006f6666636861696e5f776f726b65720058da10000d0000006163636f756e745f6e6f6e6365000000fbea12000400000078da10000b0000006765745f73746f72616765008cda10000f00000072656e745f70726f6a656374696f6e00a4da10000a00000071756572795f696e666f0000b8da10001500000067656e65726174655f73657373696f6e5f6b657973000000d8da1000130000006465636f64655f73657373696f6e5f6b6579734e6f745472616e73666572496e5573654e6f744f776e65724e6f7441737369676e6564636c61696d7472616e7366657266726565666f7263655f7472616e736665724163636f756e74730000000000000090db10000d00000000000000a0db1000020000000000000000000000b0db1000010000000000000000000000b8db10000a00000000000000c4db1000010000000000000000000000ccdb10000100000000000000496e64657841737369676e656400000020af12000900000004dc10000c00000010dc10001e000000496e6465784672656564000004dc10000c000000d4db1000300000002041206163636f756e7420696e64657820686173206265656e2066726565642075702028756e61737369676e6564292e4163636f756e74496e6465782041206163636f756e7420696e646578207761732061737369676e65642e7061726974792f7374616b696e672d656c656374696f6e2f546f6f4d616e7952656769737472617273546f6f4d616e794669656c6473496e76616c6964546172676574496e76616c6964496e646578496e76616c69644a756467656d656e744a756467656d656e74476976656e537469636b794a756467656d656e744e6f4964656e746974794665654368616e676564456d707479496e6465784e6f744e616d65644e6f74466f756e64546f6f4d616e795375624163636f756e74736164645f7265676973747261727365745f6964656e746974797365745f73756273636c6561725f6964656e74697479726571756573745f6a756467656d656e7463616e63656c5f726571756573747365745f6665657365745f6163636f756e745f69647365745f6669656c647370726f766964655f6a756467656d656e746b696c6c5f6964656e7469747953757065724f6600000000b0de10000b0000000000000074ad1200010000000000000000000000bcde1000010000000000000000000000c4de10000f0000000000000084111200020000000000000000000000d4de1000010000000000000000000000dcde10000e0000000000000084111200020000000000000000000000ecde1000010000000000000000000000f4de1000120000000000000008df100002000000000000000000000018df100001000000000000000000000020df1000140000000000000008df100002000000000000000000000034df10000100000000000000000000008ddc10000e0000000000000008df10000200000000000000000000003cdf100001000000000000000000000044df10000e0000000000000054df10000100000000000000000000005cdf100001000000000000004964656e746974795365740060e010003c0000004964656e74697479436c6561726564002ce01000340000004964656e746974794b696c6c65640000fadf1000320000004a756467656d656e74526571756573746564000020af1200090000007bdf10000e000000d2df1000280000004a756467656d656e74556e726571756573746564afdf10002300000089df100026000000526567697374726172416464656400007bdf10000e00000064df100017000000204120726567697374726172207761732061646465642e526567697374726172496e6465782041206a756467656d656e742077617320676976656e2062792061207265676973747261722e2041206a756467656d656e74207265717565737420776173207265747261637465642e2041206a756467656d656e74207761732061736b65642066726f6d2061207265676973747261722e2041206e616d65207761732072656d6f76656420616e642074686520676976656e2062616c616e636520736c61736865642e2041206e616d652077617320636c65617265642c20616e642074686520676976656e2062616c616e63652072657475726e65642e2041206e616d652077617320736574206f72207265736574202877686963682077696c6c2072656d6f766520616c6c206a756467656d656e7473292e416c69766520636f6e7472616374206f7220746f6d6273746f6e6520616c72656164792065786973747300004200000000000000010000006d0000004200000000000000010000006400000074696d657374616d702073657420696e20626c6f636b20646f65736e2774206d6174636820736c6f7420696e207365616c4c6174656e657373636f6e74726163742073756273797374656d20726573756c74696e6720696e20706f73697469766520696d62616c616e63652100000000ade812000a000000000000000000000010f111000300000000000000000000000000000000000000000000000000000000000000301a13001ce510000000000000000000c4e4100001000000000000000100000000000000b7e812000b0000000000000000000000cce410002700000000000000000000000000000000000000000000000000000000000000301a1300f4e41000000000000000000004e5100001000000000000000100000000000000c2e812000b000000000000000000000010f111000300000000000000000000000000000000000000000000000000000000000000301a13001ce5100000000000000000000ce5100002000000000000000100000000000000cde812000b000000000000000000000010f111000300000000000000000000000000000000000000000000000000000000000000301a13001ce5100000000000000000002ce5100001000000000000000100000000000000d8e812000a000000000000000000000034e510001600000000000000000000000000000000000000000000000000000000000000301a13009ce5100000000000000000004ce510000a000000000000000100000000000000e2e812000e000000000000000000000034e510001600000000000000000000000000000000000000000000000000000000000000301a13009ce510000000000000000000ace5100001000000000000000100000000000000f0e812000c000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a130054e610000000000000000000b4e5100009000000000000000100000000000000fce8120011000000010500000000000060dc12000300000000000000fce510001d00000000000000000000000000000000000000301a13001ce610000000000000000000301a1300000000000000000001000000000000004df212000b00000000000000000000002ce610000800000000000000000000000000000000000000000000000000000000000000301a130034e61000000000000000000044e610000200000000000000000000000000000019e1100008000000000000000000000006cf12000e00000000000000000000000000000000000000000000000000000000000000301a130054e61000000000000000000064e61000050000000000000001000000b2eb1000150000005665633c28417574686f7269747949642c2042616265417574686f72697479576569676874293e004200000000000000010000005900000097eb10001b00000035eb10003e00000073eb1000240000004200000000000000010000006e00000020eb1000150000007363686e6f72726b656c3a3a52616e646f6d6e65737300005ae910002e000000301a13000000000088e910000b000000301a13000000000093e9100041000000d4e910003e00000012ea10004500000057ea1000450000009cea100041000000ddea1000430000004200000000000000010000006f00000043e9100017000000fee710001f000000301a1300000000001de810003d0000005ae81000400000009ae8100025000000301a130000000000bfe810003b000000fae81000420000003ce91000070000005665633c7363686e6f72726b656c3a3a5261775652464f75747075743e000000420000000000000001000000590000004d617962655672664200000000000000010000005b00000077e7100040000000b7e7100047000000420000000000000001000000570000008ce6100036000000301a130000000000c2e610004500000007e71000440000004be710002c00000020486f77206c617465207468652063757272656e7420626c6f636b20697320636f6d706172656420746f2069747320706172656e742e205468697320656e74727920697320706f70756c617465642061732070617274206f6620626c6f636b20657865637574696f6e20616e6420697320636c65616e6564207570206f6e20626c6f636b2066696e616c697a6174696f6e2e205175657279696e6720746869732073746f7261676520656e747279206f757473696465206f6620626c6f636b20657865637574696f6e20636f6e746578742073686f756c6420616c77617973207969656c64207a65726f2e2054656d706f726172792076616c75652028636c656172656420617420626c6f636b2066696e616c697a6174696f6e292077686963682069732060536f6d6560206966207065722d626c6f636b20696e697469616c697a6174696f6e2068617320616c7265616479206265656e2063616c6c656420666f722063757272656e7420626c6f636b2e2052616e646f6d6e65737320756e64657220636f6e737472756374696f6e2e205765206d616b6520612074726164656f6666206265747765656e2073746f7261676520616363657373657320616e64206c697374206c656e6774682e2057652073746f72652074686520756e6465722d636f6e737472756374696f6e2072616e646f6d6e65737320696e207365676d656e7473206f6620757020746f2060554e4445525f434f4e535452554354494f4e5f5345474d454e545f4c454e475448602e204f6e63652061207365676d656e7420726561636865732074686973206c656e6774682c20776520626567696e20746865206e657874206f6e652e20576520726573657420616c6c207365676d656e747320616e642072657475726e20746f206030602061742074686520626567696e6e696e67206f662065766572792065706f63682e204e6578742065706f63682072616e646f6d6e6573732e205468652065706f63682072616e646f6d6e65737320666f7220746865202a63757272656e742a2065706f63682e20232053656375726974792054686973204d555354204e4f54206265207573656420666f722067616d626c696e672c2061732069742063616e20626520696e666c75656e6365642062792061206d616c6963696f75732076616c696461746f7220696e207468652073686f7274207465726d2e204974204d4159206265207573656420696e206d616e792063727970746f677261706869632070726f746f636f6c732c20686f77657665722c20736f206c6f6e67206173206f6e652072656d656d626572732074686174207468697320286c696b652065766572797468696e6720656c7365206f6e2d636861696e29206974206973207075626c69632e20466f72206578616d706c652c2069742063616e20626520757365642077686572652061206e756d626572206973206e656564656420746861742063616e6e6f742068617665206265656e2063686f73656e20627920616e206164766572736172792c20666f7220707572706f7365732073756368206173207075626c69632d636f696e207a65726f2d6b6e6f776c656467652070726f6f66732e2043757272656e7420736c6f74206e756d6265722e2054686520736c6f74206174207768696368207468652066697273742065706f63682061637475616c6c7920737461727465642e2054686973206973203020756e74696c2074686520666972737420626c6f636b206f662074686520636861696e2e2043757272656e742065706f636820617574686f7269746965732e2043757272656e742065706f636820696e6465782e000000000038ec10000d0000000000000010f111000300000000000000301a130048ec1000000000000000000058ec100002000000000000000000000068ec10001100000000000000383311000900000000000000301a13007cec100000000000000000008cec1000050000000000000045706f63684475726174696f6e00000042000000000000000100000070000000e4ed10004300000027ee10003f0000004578706563746564426c6f636b54696d6500000042000000000000000100000071000000b4ec100041000000f5ec10004400000039ed1000410000007aed100042000000bced10002800000020546865206578706563746564206176657261676520626c6f636b2074696d6520617420776869636820424142452073686f756c64206265206372656174696e6720626c6f636b732e2053696e636520424142452069732070726f626162696c6973746963206974206973206e6f74207472697669616c20746f20666967757265206f7574207768617420746865206578706563746564206176657261676520626c6f636b2074696d652073686f756c64206265206261736564206f6e2074686520736c6f74206475726174696f6e20616e642074686520736563757269747920706172616d657465722060636020287768657265206031202d20636020726570726573656e7473207468652070726f626162696c697479206f66206120736c6f74206265696e6720656d707479292e20546865206e756d626572206f66202a2a736c6f74732a2a207468617420616e2065706f63682074616b65732e20576520636f75706c652073657373696f6e7320746f2065706f6368732c20692e652e2077652073746172742061206e65772073657373696f6e206f6e636520746865206e65772065706f636820626567696e732e65706f636820696e64696365732077696c6c206e6576657220726561636820325e3634206265666f726520746865206465617468206f662074686520756e6976657273653b2071656400d0ee100030000000790100001b000000d0ee10003000000081010000200000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f626162652f7372632f6c69622e7273000000000edb10000500000000000000b0ef1000010000000000000000000000c8ef100010000000000000000000000013db1000080000000000000048f0100002000000000000000000000078f010001000000000000000000000001bdb10000400000000000000b0ef1000010000000000000000000000f8f010001000000000000000000000001fdb10000e0000000000000048f0100002000000000000000000000078f1100010000000000000000000000098d912000500000000000000e6f510000f000000f5f5100027000000301a1300000000001cf6100038000000301a13000000000098c9120034000000301a13000000000054f610003d000000301a1300000000003df3100025000000301a130000000000f5bd12000b000000184a11000a00000062f3100027000000e2f41000190000002bc112000d00000044be12000c000000000000008421120003000000000000007ac312000c0000000000000098d912000500000000000000e6f510000f000000fbf410005800000053f510002f000000301a13000000000098c9120034000000301a13000000000082f510004a000000e5f2100058000000301a1300000000003df3100025000000301a130000000000f5bd12000b000000184a11000a00000062f3100027000000ccf510001a0000002bc112000d00000044be12000c000000a8f3100026000000301a130000000000cef3100058000000301a13000000000026f4100056000000301a1300000000007cf4100044000000301a130000000000c0f4100022000000301a130000000000f5bd12000b000000184a11000a00000062f3100027000000e2f41000190000002bc112000d00000044be12000c000000f8f11000560000004ef210003b000000301a13000000000089f2100032000000301a130000000000bbf210002a000000e5f2100058000000301a1300000000003df3100025000000301a130000000000f5bd12000b000000184a11000a00000062f310002700000089f310001f0000002bc112000d00000044be12000c00000020466f72636520616e20696e64657820746f20616e206163636f756e742e205468697320646f65736e277420726571756972652061206465706f7369742e2049662074686520696e64657820697320616c72656164792068656c642c207468656e20616e79206465706f736974206973207265696d62757273656420746f206974732063757272656e74206f776e65722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f2e202d2060696e646578603a2074686520696e64657820746f206265202872652d2961737369676e65642e202d20606e6577603a20746865206e6577206f776e6572206f662074686520696e6465782e20546869732066756e6374696f6e2069732061206e6f2d6f7020696620697420697320657175616c20746f2073656e6465722e20456d6974732060496e64657841737369676e656460206966207375636365737366756c2e202d204f6e652073746f72616765206d75746174696f6e2028636f64656320604f28312960292e202d20557020746f206f6e652072657365727665206f7065726174696f6e2e204672656520757020616e20696e646578206f776e6564206279207468652073656e6465722e205061796d656e743a20416e792070726576696f7573206465706f73697420706c6163656420666f722074686520696e64657820697320756e726573657276656420696e207468652073656e646572206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206f776e2074686520696e6465782e202d2060696e646578603a2074686520696e64657820746f2062652066726565642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e20456d6974732060496e646578467265656460206966207375636365737366756c2e202d204f6e652072657365727665206f7065726174696f6e2e2041737369676e20616e20696e64657820616c7265616479206f776e6564206279207468652073656e64657220746f20616e6f74686572206163636f756e742e205468652062616c616e6365207265736572766174696f6e206973206566666563746976656c79207472616e7366657272656420746f20746865206e6577206163636f756e742e202d2060696e646578603a2074686520696e64657820746f2062652072652d61737369676e65642e2054686973206d757374206265206f776e6564206279207468652073656e6465722e202d204f6e65207472616e73666572206f7065726174696f6e2e543a3a4163636f756e74496e6465782041737369676e20616e2070726576696f75736c7920756e61737369676e656420696e6465782e205061796d656e743a20604465706f736974602069732072657365727665642066726f6d207468652073656e646572206163636f756e742e202d2060696e646578603a2074686520696e64657820746f20626520636c61696d65642e2054686973206d757374206e6f7420626520696e207573652e000000000000002ddb1000080000000102000000000000e6f510000f00000000000000ecf610001c00000000000000000000000000000000000000301a130008f71000000000000000000018f7100001000000000000000000000028543a3a4163636f756e7449642c2042616c616e63654f663c543e294200000000000000010000005b00000020f710002200000020546865206c6f6f6b75702066726f6d20696e64657820746f206163636f756e742e000000000000eadc10000d0000000000000004b9120001000000000000000000000028f910000e0000000000000000000000f7dc10000c0000000000000098f91000010000000000000000000000b0f9100014000000000000000000000003dd1000080000000000000050fa100001000000000000000000000068fa10001600000000000000000000000bdd10000e00000000000000301a130000000000000000000000000018fb100015000000000000000000000019dd10001100000000000000c0fb1000020000000000000000000000f0fb10001800000000000000000000002add10000e00000000000000b0fc1000010000000000000000000000c8fc100012000000000000000000000038dd1000070000000000000058fd100002000000000000000000000088fd10000d00000000000000000000003fdd10000e00000000000000f0fd100002000000000000000000000020fe10000d00000000000000000000004ddd10000a0000000000000088fe1000020000000000000000000000b8fe10000d000000000000000000000057dd1000110000000000000020ff100003000000000000000000000068ff100014000000000000000000000068dd10000d00000000000000b4471100010000000000000000000000080011001400000000000000841311001f000000301a130000000000a313110047000000301a130000000000ea1311002b000000301a1300000000001514110026000000301a130000000000f5bd12000b0000003b1411004a00000085141100270000002bc112000d000000ac1411003900000044be12000c00000000000000741311000400000000000000781311000c000000341111004b000000301a1300000000007f11110056000000d511110015000000301a13000000000098c9120034000000301a130000000000ea11110024000000301a1300000000000e12110023000000301a130000000000f5bd12000b000000311211001200000043121100480000008b12110039000000c412110021000000e5121100490000002bc112000d0000002e1311004600000044be12000c000000000000001711110004000000000000001b11110019000000a10e110024000000301a130000000000c50e1100560000001b0f11004c000000301a1300000000005b0c110059000000b40c11000a000000301a130000000000670f11002d000000301a130000000000f5bd12000b000000940f11000d000000a10f11003a0000002a0d110036000000db0f110022000000fd0f11000600000003101100380000003b101100300000006b101100310000009c10110035000000d11011004600000044be12000c000000d00b11004f000000301a1300000000001f0c11003c000000301a1300000000005b0c110059000000b40c11000a000000301a130000000000be0c110027000000301a130000000000f5bd12000b000000e50c110011000000f60c1100340000002a0d110036000000600d110049000000a90d110023000000cc0d1100330000002bc112000d000000ff0d11000e0000000d0e11004b000000580e11004900000044be12000c000000000000008c0511000900000000000000950511001700000000000000c90b110007000000000000008075120015000000cb09110026000000301a130000000000f109110056000000470a110007000000301a130000000000810811004e000000cf08110015000000301a1300000000004e0a110048000000960a110056000000301a130000000000ec0a11000d000000f90a11002f000000280b110004000000301a1300000000002c0b11002a000000301a130000000000f5bd12000b000000c10411000e000000bd02110021000000560b11002f0000002bc112000d000000850b11004400000044be12000c000000000000008c05110009000000000000007bdf10000e000000270811001b000000301a130000000000420811003f000000301a130000000000810811004e000000cf08110015000000301a130000000000e408110052000000301a130000000000360911002c000000301a130000000000f5bd12000b000000c10411000e000000bd0211002100000062091100230000002bc112000d000000850911004600000044be12000c0000000000000098d91200050000000000000095051100170000000000000024081100030000000000000080751200150000008d07110047000000301a1300000000007c03110056000000ee05110029000000301a130000000000170611003e000000d407110016000000301a130000000000f5bd12000b0000006c8711000a000000990611001f000000ea0711003a00000044be12000c0000000000000098d9120005000000000000009505110017000000000000008421120003000000000000007ac312000c0000000607110030000000301a1300000000007c03110056000000ee05110029000000301a130000000000170611003e000000360711001d000000301a130000000000f5bd12000b0000006c8711000a000000990611001f000000530711003a00000044be12000c0000000000000098d912000500000000000000950511001700000000000000f20611000600000000000000f80611000e000000c30511002b000000301a1300000000007c03110056000000ee05110029000000301a130000000000170611003e0000005506110044000000301a130000000000f5bd12000b0000006c8711000a000000990611001f000000b80611003a00000044be12000c000000000000008c0511000900000000000000950511001700000000000000834b11000600000000000000f320120023000000000000004e3712000900000000000000ac051100170000004d0311002f000000301a1300000000007c03110056000000d20311002d000000301a130000000000ff031100490000001102110056000000670211001e0000004804110053000000301a1300000000009b04110026000000301a130000000000f5bd12000b000000c10411000e000000cf04110022000000f104110026000000170511002f0000002bc112000d000000460511004600000044be12000c000000a800110051000000301a130000000000f9001100590000005201110052000000a401110021000000301a130000000000c50111004c000000301a1300000000001102110056000000670211001e000000301a1300000000008502110026000000301a130000000000f5bd12000b000000ab02110012000000bd02110021000000de0211001d0000002bc112000d000000fb0211005200000044be12000c0000002052656d6f766520616e206163636f756e742773206964656e7469747920616e64207375622d6163636f756e7420696e666f726d6174696f6e20616e6420736c61736820746865206465706f736974732e205061796d656e743a2052657365727665642062616c616e6365732066726f6d20607365745f737562736020616e6420607365745f6964656e74697479602061726520736c617368656420616e642068616e646c65642062792060536c617368602e20566572696669636174696f6e2072657175657374206465706f7369747320617265206e6f742072657475726e65643b20746865792073686f756c642062652063616e63656c6c6564206d616e75616c6c79207573696e67206063616e63656c5f72657175657374602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f526f6f745f206f72206d617463682060543a3a466f7263654f726967696e602e202d2060746172676574603a20746865206163636f756e742077686f7365206964656e7469747920746865206a756467656d656e742069732075706f6e2e2054686973206d75737420626520616e206163636f756e742020207769746820612072656769737465726564206964656e746974792e20456d69747320604964656e746974794b696c6c656460206966207375636365737366756c2e202d20604f2852202b2053202b205829602e202d204f6e652062616c616e63652d72657365727665206f7065726174696f6e2e202d206053202b2032602073746f72616765206d75746174696f6e732e202d2042656e63686d61726b3a203130312e39202b2052202a20302e303931202b2053202a20322e353839202b2058202a20302e38373120c2b57320286d696e207371756172657320616e616c79736973292050726f766964652061206a756467656d656e7420666f7220616e206163636f756e742773206964656e746974792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420626520746865206163636f756e74206f6620746865207265676973747261722077686f736520696e64657820697320607265675f696e646578602e202d20607265675f696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206265696e67206d6164652e202d20606a756467656d656e74603a20746865206a756467656d656e74206f662074686520726567697374726172206f6620696e64657820607265675f696e646578602061626f75742060746172676574602e20456d69747320604a756467656d656e74476976656e60206966207375636365737366756c2e202d20604f2852202b205829602e202d204f6e652062616c616e63652d7472616e73666572206f7065726174696f6e2e202d20557020746f206f6e65206163636f756e742d6c6f6f6b7570206f7065726174696f6e2e202d2053746f726167653a2031207265616420604f285229602c2031206d757461746520604f2852202b205829602e202d2042656e63686d61726b3a2034372e3737202b2052202a20302e333336202b2058202a20312e36363420c2b57320286d696e207371756172657320616e616c79736973297265675f696e646578436f6d706163743c526567697374726172496e6465783e4a756467656d656e743c42616c616e63654f663c543e3e2053657420746865206669656c6420696e666f726d6174696f6e20666f722061207265676973747261722e206f6620746865207265676973747261722077686f736520696e6465782069732060696e646578602e202d2060696e646578603a2074686520696e646578206f6620746865207265676973747261722077686f73652066656520697320746f206265207365742e202d20606669656c6473603a20746865206669656c64732074686174207468652072656769737472617220636f6e6365726e73207468656d73656c76657320776974682e202d204f6e652073746f72616765206d75746174696f6e20604f285229602e202d2042656e63686d61726b3a20382e393835202b2052202a20302e34313320c2b57320286d696e207371756172657320616e616c79736973296669656c64734964656e746974794669656c6473204368616e676520746865206163636f756e74206173736f63696174656420776974682061207265676973747261722e202d20606e6577603a20746865206e6577206163636f756e742049442e202d2042656e63686d61726b3a2031302e3035202b2052202a20302e34333820c2b57320286d696e207371756172657320616e616c797369732920536574207468652066656520726571756972656420666f722061206a756467656d656e7420746f206265207265717565737465642066726f6d2061207265676973747261722e202d2060666565603a20746865206e6577206665652e202d2042656e63686d61726b3a20382e383438202b2052202a20302e34323520c2b57320286d696e207371756172657320616e616c79736973296665652043616e63656c20612070726576696f757320726571756573742e205061796d656e743a20412070726576696f75736c79207265736572766564206465706f7369742069732072657475726e6564206f6e20737563636573732e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564206964656e746974792e202d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973206e6f206c6f6e676572207265717565737465642e20456d69747320604a756467656d656e74556e72657175657374656460206966207375636365737366756c2e202d204f6e652073746f72616765206d75746174696f6e20604f2852202b205829602e202d2042656e63686d61726b3a2035302e3035202b2052202a20302e333231202b2058202a20312e36383820c2b57320286d696e207371756172657320616e616c797369732920526571756573742061206a756467656d656e742066726f6d2061207265676973747261722e205061796d656e743a204174206d6f737420606d61785f666565602077696c6c20626520726573657276656420666f72207061796d656e7420746f2074686520726567697374726172206966206a756467656d656e7420676976656e2e202d20607265675f696e646578603a2054686520696e646578206f6620746865207265676973747261722077686f7365206a756467656d656e74206973207265717565737465642e202d20606d61785f666565603a20546865206d6178696d756d206665652074686174206d617920626520706169642e20546869732073686f756c64206a757374206265206175746f2d706f70756c617465642061733a206060606e6f636f6d70696c652053656c663a3a7265676973747261727328292e676574287265675f696e646578292e756e7772617028292e6665652060606020456d69747320604a756467656d656e7452657175657374656460206966207375636365737366756c2e202d2053746f726167653a2031207265616420604f285229602c2031206d757461746520604f2858202b205229602e202d2042656e63686d61726b3a2035392e3032202b2052202a20302e343838202b2058202a20312e3720c2b57320286d696e207371756172657320616e616c79736973296d61785f66656520436c65617220616e206163636f756e742773206964656e7469747920696e666f20616e6420616c6c207375622d6163636f756e747320616e642072657475726e20616c6c206465706f736974732e205061796d656e743a20416c6c2072657365727665642062616c616e636573206f6e20746865206163636f756e74206172652072657475726e65642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d757374206861766520612072656769737465726564206964656e746974792e20456d69747320604964656e74697479436c656172656460206966207375636365737366756c2e202d20604f2852202b2053202b205829602020202d20776865726520605260207265676973747261722d636f756e742028676f7665726e616e63652d626f756e646564292e2020202d2077686572652060536020737562732d636f756e742028686172642d20616e64206465706f7369742d626f756e646564292e2020202d20776865726520605860206164646974696f6e616c2d6669656c642d636f756e7420286465706f7369742d626f756e64656420616e6420636f64652d626f756e646564292e202d204f6e652062616c616e63652d756e72657365727665206f7065726174696f6e2e202d206032602073746f7261676520726561647320616e64206053202b2032602073746f726167652064656c6574696f6e732e202d2042656e63686d61726b733a2020202d2035372e3336202b2052202a20302e303139202b2053202a20322e353737202b2058202a20302e38373420c2b57320286d656469616e20736c6f70657320616e616c79736973292020202d2035372e3036202b2052202a20302e303036202b2053202a20322e353739202b2058202a20302e38373820c2b57320286d696e207371756172657320616e616c79736973292053657420746865207375622d6163636f756e7473206f66207468652073656e6465722e205061796d656e743a20416e79206167677265676174652062616c616e63652072657365727665642062792070726576696f757320607365745f73756273602063616c6c732077696c6c2062652072657475726e656420616e6420616e20616d6f756e7420605375624163636f756e744465706f736974602077696c6c20626520726573657276656420666f722065616368206974656d20696e206073756273602e202d206073756273603a20546865206964656e74697479277320286e657729207375622d6163636f756e74732e202d20604f2850202b205329602020202d20776865726520605060206f6c642d737562732d636f756e742028686172642d20616e64206465706f7369742d626f756e646564292e202d204174206d6f7374206f6e652062616c616e6365206f7065726174696f6e732e202d2044423a2020202d206050202b2053602073746f72616765206d75746174696f6e732028636f64656320636f6d706c657869747920604f28312960292020202d204f6e652073746f7261676520726561642028636f64656320636f6d706c657869747920604f28502960292e2020202d204f6e652073746f726167652077726974652028636f64656320636f6d706c657869747920604f28532960292e2020202d204f6e652073746f726167652d6578697374732028604964656e746974794f663a3a636f6e7461696e735f6b657960292e202d2042656e63686d61726b3a2033392e3433202b2050202a20322e353232202b2053202a20332e36393820c2b57320286d696e207371756172657320616e616c7973697329737562735665633c28543a3a4163636f756e7449642c2044617461293e2053657420616e206163636f756e742773206964656e7469747920696e666f726d6174696f6e20616e6420726573657276652074686520617070726f707269617465206465706f7369742e20496620746865206163636f756e7420616c726561647920686173206964656e7469747920696e666f726d6174696f6e2c20746865206465706f7369742069732074616b656e2061732070617274207061796d656e7420666f7220746865206e6577206465706f7369742e202d2060696e666f603a20546865206964656e7469747920696e666f726d6174696f6e2e20456d69747320604964656e7469747953657460206966207375636365737366756c2e202d20604f2858202b205827202b205229602020202d20776865726520605860206164646974696f6e616c2d6669656c642d636f756e7420286465706f7369742d626f756e64656420616e6420636f64652d626f756e646564292020202d20776865726520605260206a756467656d656e74732d636f756e7420287265676973747261722d636f756e742d626f756e64656429202d204f6e652062616c616e63652072657365727665206f7065726174696f6e2e202d204f6e652073746f72616765206d75746174696f6e2028636f6465632d7265616420604f285827202b205229602c20636f6465632d777269746520604f2858202b20522960292e202d2042656e63686d61726b3a2035392e3434202b2052202a20302e333839202b2058202a20312e34333420c2b57320286d696e207371756172657320616e616c7973697329696e666f4964656e74697479496e666f2041646420612072656769737472617220746f207468652073797374656d2e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d75737420626520605265676973747261724f726967696e60206f722060526f6f74602e202d20606163636f756e74603a20746865206163636f756e74206f6620746865207265676973747261722e20456d6974732060526567697374726172416464656460206966207375636365737366756c2e202d20604f2852296020776865726520605260207265676973747261722d636f756e742028676f7665726e616e63652d626f756e64656420616e6420636f64652d626f756e646564292e202d204f6e652073746f72616765206d75746174696f6e2028636f64656320604f28522960292e202d2042656e63686d61726b3a2032342e3633202b2052202a20302e353320c2b57320286d696e207371756172657320616e616c797369732900000000000000481611000a00000001050000000000007ac312000c00000000000000521611001a00000000000000000000000000000000000000301a13006c16110000000000000000007c1611000100000000000000000000000000000075dd10000700000001020000000000007ac312000c00000000000000841611001400000000000000000000000000000000000000301a1300981611000000000000000000a816110002000000000000000000000000000000b81611000600000001050000000000007ac312000c00000000000000a48f11002100000000000000000000000000000000000000301a1300c01611000000000000000000d016110003000000000000000100000000000000e81611000a0000000000000000000000f21611003600000000000000000000000000000000000000000000000000000000000000301a1300281711000000000000000000381711000400000000000000010000004964656e746974794f66526567697374726174696f6e3c42616c616e63654f663c543e3e4200000000000000010000005b000000401911004800000028543a3a4163636f756e7449642c2044617461294200000000000000010000005b0000009418110058000000ec18110054000000537562734f660000420000000000000001000000660000001f1811002e000000301a1300000000004d18110047000000526567697374726172735665633c4f7074696f6e3c526567697374726172496e666f3c42616c616e63654f663c543e2c20543a3a4163636f756e7449643e3e3e420000000000000001000000590000005817110053000000ab1711002a000000301a130000000000d51711004a0000002054686520736574206f6620726567697374726172732e204e6f7420657870656374656420746f206765742076657279206269672061732063616e206f6e6c79206265206164646564207468726f7567682061207370656369616c206f726967696e20286c696b656c79206120636f756e63696c206d6f74696f6e292e2054686520696e64657820696e746f20746869732063616e206265206361737420746f2060526567697374726172496e6465786020746f2067657420612076616c69642076616c75652e20416c7465726e6174697665202273756222206964656e746974696573206f662074686973206163636f756e742e20546865206669727374206974656d20697320746865206465706f7369742c20746865207365636f6e64206973206120766563746f72206f6620746865206163636f756e74732e205468652073757065722d6964656e74697479206f6620616e20616c7465726e6174697665202273756222206964656e7469747920746f676574686572207769746820697473206e616d652c2077697468696e207468617420636f6e746578742e20496620746865206163636f756e74206973206e6f7420736f6d65206f74686572206163636f756e742773207375622d6964656e746974792c207468656e206a75737420604e6f6e65602e20496e666f726d6174696f6e20746861742069732070657274696e656e7420746f206964656e746966792074686520656e7469747920626568696e6420616e206163636f756e742e00000000d81a11000c00000000000000b66c12000c00000000000000301a1300e41a11000000000000000000f41a1100010000000000000000000000fc1a11000c00000000000000b66c12000c00000000000000301a1300081b11000000000000000000181b1100010000000000000000000000201b11001100000000000000b66c12000c00000000000000301a1300341b11000000000000000000441b11000300000000000000000000005c1b11000e0000000000000060dc12000300000000000000301a1300881b110000000000000000006c1b1100010000000000000000000000741b1100130000000000000060dc12000300000000000000301a1300881b11000000000000000000981b1100020000000000000000000000a81b11000d0000000000000060dc12000300000000000000301a1300b81b11000000000000000000c81b1100020000000000000042617369634465706f73697442000000000000000100000067000000691e1100360000004669656c644465706f736974420000000000000001000000720000001e1e11004b0000005375624163636f756e744465706f736974000000420000000000000001000000730000001f1d110059000000781d11005c000000d41d11004a0000004d61785375624163636f756e74730000dc1c1100430000004d61784164646974696f6e616c4669656c647300420000000000000001000000740000004b1c110059000000a41c1100380000004d61785265676973747261727300000042000000000000000100000075000000d81b1100540000002c1c11001f000000204d61786d696d756d206e756d626572206f66207265676973747261727320616c6c6f77656420696e207468652073797374656d2e204e656564656420746f20626f756e642074686520636f6d706c6578697479206f662c20652e672e2c207570646174696e67206a756467656d656e74732e204d6178696d756d206e756d626572206f66206164646974696f6e616c206669656c64732074686174206d61792062652073746f72656420696e20616e2049442e204e656564656420746f20626f756e642074686520492f4f20726571756972656420746f2061636365737320616e206964656e746974792c206275742063616e2062652070726574747920686967682e20546865206d6178696d756d206e756d626572206f66207375622d6163636f756e747320616c6c6f77656420706572206964656e746966696564206163636f756e742e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564207375626163636f756e742e20546869732073686f756c64206163636f756e7420666f722074686520666163742074686174206f6e652073746f72616765206974656d27732076616c75652077696c6c20696e637265617365206279207468652073697a65206f6620616e206163636f756e742049442c20616e642074686572652077696c6c20626520616e6f746865722074726965206974656d2077686f73652076616c7565206973207468652073697a65206f6620616e206163636f756e7420494420706c75732033322062797465732e2054686520616d6f756e742068656c64206f6e206465706f73697420706572206164646974696f6e616c206669656c6420666f7220612072656769737465726564206964656e746974792e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220612072656769737465726564206964656e746974792e00d4f31200340000004a0300001d000000d4f31200340000001e0400003600000000000000d8dc100012000000000000002c201100010000000000000000000000d0dc1000080000000000000034201100010000000000000000000000c8dc100008000000000000003c201100010000000000000000000000bedc10000a0000000000000044201100010000000000000000000000b4dc10000a000000000000004c201100010000000000000000000000aadc10000a00000000000000542011000100000000000000000000009bdc10000f000000000000005c2011000100000000000000000000008ddc10000e00000000000000642011000100000000000000000000007ddc100010000000000000006c20110001000000000000000000000071dc10000c000000000000007420110001000000000000000000000064dc10000d000000000000007c20110001000000000000000000000057dc10000d000000000000008420110001000000000000000000000046dc100011000000000000008c2011000100000000000000a82111001800000093211100150000007e21110015000000712111000d00000061211100100000004e211100130000003c211100120000002b2111001100000018211100130000000221110016000000eb20110017000000cf2011001c000000942011003b000000204d6178696d756d20616d6f756e74206f66207265676973747261727320726561636865642e2043616e6e6f742061646420616e79206d6f72652e20546f6f206d616e79206164646974696f6e616c206669656c64732e205468652074617267657420697320696e76616c69642e2054686520696e64657820697320696e76616c69642e20496e76616c6964206a756467656d656e742e204a756467656d656e7420676976656e2e20537469636b79206a756467656d656e742e204e6f206964656e7469747920666f756e642e20466565206973206368616e6765642e20456d70747920696e6465782e204163636f756e742069736e2774206e616d65642e204163636f756e742069736e277420666f756e642e20546f6f206d616e7920737562732d6163636f756e74732e54696d657374616d70206d7573742062652075706461746564206f6e636520696e2074686520626c6f636b4e6f774475706c696361746564486561727462656174496e76616c69644b65796865617274626561744865617274626561744166746572000000000000a82211001100000000000000bc221100010000000000000000000000c4221100010000000000000000000000cc2211000700000000000000301a1300000000000000000000000000d4221100010000000000000000000000dc2211000b00000000000000e8221100010000000000000000000000f022110001000000000000004865617274626561745265636569766564000000c12311000b0000009123110030000000416c6c476f6f64005c23110035000000536f6d654f66666c696e65004423110018000000f82211004c0000002041742074686520656e64206f66207468652073657373696f6e2c206174206c65617374206f6e63652076616c696461746f722077617320666f756e6420746f206265206f66666c696e652e5665633c4964656e74696669636174696f6e5475706c653e2041742074686520656e64206f66207468652073657373696f6e2c206e6f206f6666656e63652077617320636f6d6d69747465642e2041206e657720686561727462656174207761732072656365697665642066726f6d2060417574686f72697479496460417574686f72697479496473657400617474656d707420746f20646976696465206279207a65726f000000760000001000000004000000770000000b221100090000004765747320616e64206465636f6465732074696d657374616d7020696e686572656e7420646174613c24110035000000e80000001f0000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f74696d657374616d702f7372632f6c69622e7273417574686f726564426c6f636b7300902411002e000000be2411000d0000004552524f523a2072657475726e6564206e6578745f6b657920686173206e6f2076616c75653a0a6b6579206973200a6e6578745f6b6579206973200039251100160000005c0912000200000039251100160000004f25110012000000696d6f6e6c696e6570616c6c65745f696d5f6f6e6c696e652f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f696d2d6f6e6c696e652f7372632f6c69622e7273536b697070696e6720686561727462656174206174202e204e6f7420612076616c696461746f722e000000732611001c000000452611002e000000132611001a0000002d26110018000000f72511000a0000000126110012000000df25110018000000c925110016000000ac2511001d0000004661696c656420746f206665746368206e6574776f726b2073746174654661696c656420746f2061637175697265206c6f636b4661696c656420746f207369676e20686561727462656174417574686f726974792020697320616c7265616479206f6e6c696e6548656172746265617420616c72656164792073656e74206174202e2057616974696e6720666f7220696e636c7573696f6e2e546f6f206561726c7920746f2073656e64206865617274626561742c206e657874206578706563746564206174204661696c656420746f207375626d6974207472616e73616374696f6e00042511003500000026020000340000007061726974792f696d2d6f6e6c696e652d6865617274626561742f00dc26110008000000e426110020000000042711000b0000009de91200030000005b696e6465783a205d205265706f7274696e6720696d2d6f6e6c696e6520617420626c6f636b3a20202873657373696f6e3a2000301a130000000000301a1300000000004200000004000000040000007800000042000000040000000400000078000000506172656e7420686173682073686f756c642062652076616c69642e5472616e73616374696f6e207472696520726f6f74206d7573742062652076616c69642ef527110032000000446967657374206974656d206d757374206d6174636820746861742063616c63756c617465642e53746f7261676520726f6f74206d757374206d6174636820746861742063616c63756c617465642e5369676e617475726520766572696669636174696f6e206661696c65642e4e756d626572206f6620646967657374206974656d73206d757374206d6174636820746861742063616c63756c617465642e00000000000b221100090000000000000054281100020000000000000000000000842811000a00000000000000000000000b22110009000000000000001f2a11001900000000000000382a11000a00000000000000422a11002f000000f5bd12000b000000d4281100480000001c2911002d000000301a13000000000049291100230000006c2911002c000000982911004f000000e729110017000000fe2911002100000044be12000c000000202d20436f6d706c65786974793a20604f284b202b20452960207768657265204b206973206c656e677468206f6620604b6579736020616e642045206973206c656e677468206f66202020604865617274626561742e6e6574776f726b5f73746174652e65787465726e616c5f61646472657373602020202d20604f284b29603a206465636f64696e67206f66206c656e67746820604b602020202d20604f284529603a206465636f64696e672f656e636f64696e67206f66206c656e67746820604560202d20446252656164733a2070616c6c65745f73657373696f6e206056616c696461746f7273602c2070616c6c65745f73657373696f6e206043757272656e74496e646578602c20604b657973602c2020206052656365697665644865617274626561747360202d2044625772697465733a2060526563656976656448656172746265617473604865617274626561743c543a3a426c6f636b4e756d6265723e5f7369676e61747572653c543a3a417574686f7269747949642061732052756e74696d654170705075626c69633e3a3a5369676e617475726500000000000000142211000e000000000000000000000006cf12000e00000000000000000000000000000000000000000000000000000000000000301a13005c2c11000000000000000000d42b1100060000000000000001000000000000008fe81200040000000000000000000000042c11001300000000000000000000000000000000000000000000000000000000000000301a1300182c11000000000000000000282c11000100000000000000010000000000000010f4120012000000020505000000000097f612000c00000000000000302c11000900000000000000cc8d12000700000000000000301a13003c2c110000000000000000004c2c110002000000000000000000000000000000712411000e000000020505000000000097f612000c00000000000000f49912000e0000000000000060dc12000300000000000000301a13005c2c110000000000000000006c2c1100020000000000000001000000832d11004c000000301a130000000000cf2d110044000000132e110034000000472e110040000000872e11004e0000005665633c543a3a417574686f7269747949643e00420000000000000001000000590000004f2d11003400000041757468496e6465780000004200000000000000010000005b000000f32c11003c0000002f2d110020000000420000000000000001000000570000007c2c110045000000c12c11003200000020466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f662060543a3a56616c696461746f7249646020746f20746865206e756d626572206f6620626c6f636b7320617574686f7265642062792074686520676976656e20617574686f726974792e20466f7220656163682073657373696f6e20696e6465782c207765206b6565702061206d617070696e67206f66206041757468496e6465786020746f20606f6666636861696e3a3a4f70617175654e6574776f726b5374617465602e205468652063757272656e7420736574206f66206b6579732074686174206d61792069737375652061206865617274626561742e2054686520626c6f636b206e756d6265722061667465722077686963682069742773206f6b20746f2073656e64206865617274626561747320696e2063757272656e742073657373696f6e2e2041742074686520626567696e6e696e67206f6620656163682073657373696f6e20776520736574207468697320746f20612076616c756520746861742073686f756c642066616c6c20726f7567686c7920696e20746865206d6964646c65206f66207468652073657373696f6e206475726174696f6e2e20546865206964656120697320746f206669727374207761697420666f72207468652076616c696461746f727320746f2070726f64756365206120626c6f636b20696e207468652063757272656e742073657373696f6e2c20736f20746861742074686520686561727462656174206c61746572206f6e2077696c6c206e6f74206265206e65636573736172792e00000000000000cc2311000300000000000000042f11000100000000000000000000001c2f11001200000000000000000000007232110003000000000000007532110012000000ac2f110016000000301a130000000000c22f1100560000001830110036000000301a1300000000004e301100510000009f30110011000000301a130000000000b030110036000000301a130000000000f5bd12000b000000e6301100340000001a31110068000000823111002d000000af3111002a000000d931110060000000393211003900000044be12000c00000020536574207468652063757272656e742074696d652e20546869732063616c6c2073686f756c6420626520696e766f6b65642065786163746c79206f6e63652070657220626c6f636b2e2049742077696c6c2070616e6963206174207468652066696e616c697a6174696f6e2070686173652c20696620746869732063616c6c206861736e2774206265656e20696e766f6b656420627920746861742074696d652e205468652074696d657374616d702073686f756c642062652067726561746572207468616e207468652070726576696f7573206f6e652062792074686520616d6f756e742073706563696669656420627920604d696e696d756d506572696f64602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652060496e686572656e74602e202d20604f285429602077686572652060546020636f6d706c6578697479206f6620606f6e5f74696d657374616d705f73657460202d20312073746f72616765207265616420616e6420312073746f72616765206d75746174696f6e2028636f64656320604f28312960292e202862656361757365206f6620604469645570646174653a3a74616b656020696e20606f6e5f66696e616c697a656029202d2031206576656e742068616e646c657220606f6e5f74696d657374616d705f7365746020604f285429602e202d2042656e63686d61726b3a20382e35323320286d696e207371756172657320616e616c79736973292020202d204e4f54453a20546869732062656e63686d61726b2077617320646f6e6520666f7220612072756e74696d65207769746820696e7369676e69666963616e7420606f6e5f74696d657374616d705f736574602068616e646c6572732e20202020204e65772062656e63686d61726b696e67206973206e6565646564207768656e20616464696e67206e65772068616e646c6572732e6e6f77436f6d706163743c543a3a4d6f6d656e743e0000000000eb211100030000000000000000000000383311000900000000000000000000000000000000000000000000000000000000000000301a13004433110000000000000000005433110001000000000000000100000000000000daf71200090000000000000000000000a1f512000400000000000000000000000000000000000000000000000000000000000000301a13005c33110000000000000000006c331100010000000000000001000000543a3a4d6f6d656e740000004200000000000000010000006e000000a1331100240000004200000000000000010000005b000000743311002d00000020446964207468652074696d657374616d7020676574207570646174656420696e207468697320626c6f636b3f2043757272656e742074696d6520666f72207468652063757272656e7420626c6f636b2e00000000000000003411000d00000000000000383311000900000000000000301a13001034110000000000000000002034110004000000000000004d696e696d756d506572696f6400000042000000000000000100000079000000403411005a0000009a3411005a000000f4341100590000004d3511001c00000020546865206d696e696d756d20706572696f64206265747765656e20626c6f636b732e204265776172652074686174207468697320697320646966666572656e7420746f20746865202a65787065637465642a20706572696f6420746861742074686520626c6f636b2070726f64756374696f6e206170706172617475732070726f76696465732e20596f75722063686f73656e20636f6e73656e7375732073797374656d2077696c6c2067656e6572616c6c7920776f726b2077697468207468697320746f2064657465726d696e6520612073656e7369626c6520626c6f636b2074696d652e20652e672e20466f7220417572612c2069742077696c6c20626520646f75626c65207468697320706572696f64206f6e2064656661756c742073657474696e67732e54696d657374616d7020746f6f2066617220696e2066757475726520746f2061636365707454696d657374616d70206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b54696d657374616d70206d75737420696e6372656d656e74206279206174206c65617374203c4d696e696d756d506572696f643e206265747765656e2073657175656e7469616c20626c6f636b7300000000012211000a0000000000000044361100010000000000000000000000ee21110013000000000000004c36110001000000000000006a361100190000005436110016000000204475706c696361746564206865617274626561742e204e6f6e206578697374656e74207075626c6963206b65792e00000000000000000000000000617474656d707420746f20646976696465206279207a65726f0000004200000008000000040000007a00000071202f206365696c28712f246d617829203c20246d61782e204d6163726f2070726576656e747320616e792074797065206265696e672063726561746564207468617420646f6573206e6f74207361746973667920746869733b2071656400002c3711004200000064010000270000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f61726974686d657469632f7372632f7065725f7468696e67732e727300002c371100420000006b010000270000002c3711004200000076010000210000004661696c656420746f20636f6e76657274416d6f756e744c6f774578697374696e6756657374696e675363686564756c654e6f7456657374696e6776657374766573745f6f746865727665737465645f7472616e7366657200000000403811000e00000000000000841112000200000000000000000000005038110002000000000000000000000060381100100000000000000074ad120001000000000000000000000070381100010000000000000056657374696e67557064617465640000c338110056000000193911004600000056657374696e67436f6d706c65746564783811004b00000020416e206163636f756e742028676976656e2920686173206265636f6d652066756c6c79207665737465642e204e6f20667572746865722076657374696e672063616e2068617070656e2e2054686520616d6f756e742076657374656420686173206265656e20757064617465642e205468697320636f756c6420696e646963617465206d6f72652066756e64732061726520617661696c61626c652e205468652062616c616e636520676976656e2069732074686520616d6f756e74207768696368206973206c65667420756e7665737465642028616e642074687573206c6f636b6564292e5265706f72747344656665727265644f6666656e6365734e6f6e73656e7365496e7374616e744e6f74416c6c6f776564566f74657345786973744e6f7444656c65676174696e67496e73756666696369656e7446756e6473556e646572666c6f77416c726561647944656c65676174696e674e6f5065726d697373696f6e4e6f74566f7465724e6f7441637469766557726f6e674f70656e4e6f744f70656e4e6f74457870697265644e6f744c6f636b65644e6f6e6557616974696e67507265696d616765496e76616c69645265666572656e64756d496e76616c6964507265696d6167654d697373696e67496d6d696e656e744e6f74496d6d696e656e744475706c6963617465507265696d6167654e6f7444656c65676174656457726f6e6750726f7879416c72656164795665746f65644e6f50726f706f73616c496e76616c6964486173684e6f7453696d706c654d616a6f7269747950726f706f73616c426c61636b6c6973746564416c726561647943616e63656c6564426164496e6465784e6f7450726f787956616c75654c6f777365636f6e6470726f78795f766f7465656d657267656e63795f63616e63656c65787465726e616c5f70726f706f736565787465726e616c5f70726f706f73655f6d616a6f7269747965787465726e616c5f70726f706f73655f64656661756c74666173745f747261636b7665746f5f65787465726e616c63616e63656c5f7265666572656e64756d63616e63656c5f71756575656461637469766174655f70726f7879636c6f73655f70726f7879646561637469766174655f70726f787964656c6567617465756e64656c6567617465636c6561725f7075626c69635f70726f706f73616c736e6f74655f707265696d6167656e6f74655f696d6d696e656e745f707265696d616765726561705f707265696d616765756e6c6f636b6f70656e5f70726f787972656d6f76655f766f746572656d6f76655f6f746865725f766f746570726f78795f64656c656761746570726f78795f756e64656c656761746570726f78795f72656d6f76655f766f7465656e6163745f70726f706f73616c4465706f7369744f665265666572656e64756d496e666f4f66000000000054b112000800000000000000783f1100020000000000000000000000883f1100010000000000000000000000903f11000600000000000000983f1100030000000000000000000000b03f1100010000000000000000000000b83f11000e00000000000000301a1300000000000000000000000000c83f1100010000000000000000000000d03f11000700000000000000d83f1100020000000000000000000000e83f1100010000000000000000000000f03f11000600000000000000f83f110001000000000000000000000000401100010000000000000000000000084011000900000000000000f83f1100010000000000000000000000144011000100000000000000000000001c4011000900000000000000f83f110001000000000000000000000028401100010000000000000000000000f8b112000800000000000000304011000200000000000000000000004040110001000000000000000000000048401100090000000000000098ad1200020000000000000000000000544011000100000000000000000000005c4011000b0000000000000074ad1200010000000000000000000000684011000100000000000000000000007040110006000000000000007840110003000000000000000000000090401100010000000000000000000000984011000d00000000000000081a1200030000000000000000000000a8401100010000000000000000000000b04011000c00000000000000081a1200030000000000000000000000bc4011000100000000000000000000001c3a11000f00000000000000c4401100020000000000000000000000d44011000100000000000000000000003c3a11000f00000000000000c4401100020000000000000000000000dc401100010000000000000000000000e44011000e00000000000000f4401100040000000000000000000000144111000100000000000000000000001c411100080000000000000074ad12000100000000000000000000002441110001000000000000007b44110009000000f61512000700000084441100300000005461626c656400007b44110009000000f615120007000000a81412000e000000444411003700000045787465726e616c5461626c656400001e441100260000005374617274656400344211000f000000114411000d000000f9431100180000005061737365640000344211000f000000cd4311002c0000004e6f74506173736564000000a14311002c00000043616e63656c6c65640000008043110021000000344211000f000000a1f5120004000000634311001d00000044656c6567617465640000002b43110038000000556e64656c65676174656400f14211003a0000005665746f6564000020af12000900000089b2120004000000e64211000b000000c042110026000000507265696d6167654e6f7465640000008842110038000000507265696d61676555736564434211004500000089b2120004000000344211000f000000f141110043000000ae41110043000000507265696d616765526561706564000089b212000400000020af120009000000f61512000700000020af1200090000005741110057000000556e6c6f636b65642c4111002b00000020416e206163636f756e7420686173206265656e20756e6c6f636b6564207375636365737366756c6c792e2041207265676973746572656420707265696d616765207761732072656d6f76656420616e6420746865206465706f73697420636f6c6c6563746564206279207468652072656170657220286c617374206974656d292e20412070726f706f73616c20636f756c64206e6f7420626520657865637574656420626563617573652069747320707265696d61676520776173206d697373696e672e20412070726f706f73616c20636f756c64206e6f7420626520657865637574656420626563617573652069747320707265696d6167652077617320696e76616c69642e5265666572656e64756d496e64657820412070726f706f73616c20707265696d616765207761732072656d6f76656420616e6420757365642028746865206465706f736974207761732072657475726e6564292e20412070726f706f73616c277320707265696d61676520776173206e6f7465642c20616e6420746865206465706f7369742074616b656e2e20416e2065787465726e616c2070726f706f73616c20686173206265656e207665746f65642e426c6f636b4e756d62657220416e206163636f756e74206861732063616e63656c6c656420612070726576696f75732064656c65676174696f6e206f7065726174696f6e2e20416e206163636f756e74206861732064656c65676174656420746865697220766f746520746f20616e6f74686572206163636f756e742e20412070726f706f73616c20686173206265656e20656e61637465642e2041207265666572656e64756d20686173206265656e2063616e63656c6c65642e20412070726f706f73616c20686173206265656e2072656a6563746564206279207265666572656e64756d2e20412070726f706f73616c20686173206265656e20617070726f766564206279207265666572656e64756d2e2041207265666572656e64756d2068617320626567756e2e566f74655468726573686f6c6420416e2065787465726e616c2070726f706f73616c20686173206265656e207461626c65642e2041207075626c69632070726f706f73616c20686173206265656e207461626c656420666f72207265666572656e64756d20766f74652e50726f70496e6465782041206d6f74696f6e20686173206265656e2070726f706f7365642062792061207075626c6963206163636f756e742e4c6f6f6b757000000000000014451100090000000000000020451100010000000000000000000000301a13000000000000000000000000008ccb11000a0000000000000028451100030000000000000000000000301a130000000000000000005363686564756c6564000000e64211000b0000004045110018000000584511000f000000940d12000e0000005461736b416464726573733c426c6f636b4e756d6265723e4f7074696f6e3c5665633c75383e3e004200000004000000040000007b0000007c0000007d00000042000000000000000100000064000000420000000000000001000000460000004200000000000000010000006d00000073657269616c697a656420617267732073686f756c642062652070726f7669646564206279207468652072756e74696d653b0a090909636f72726563746c792073657269616c697a656420646174612073686f756c6420626520646573657269616c697a61626c653b0a0909097165648811130043000000ba000000100000004c4f474943204552524f523a2062616b655f7265666572656e64756d2f7363686564756c655f6e616d6564206661696c65644167656e64615ca412006a000000a7000000090000005ca412006a000000a700000035000000507265696d616765735075626c696350726f70734e65787445787465726e616c00000000cb3711000400000000000000301a13000000000000000000000000002c471100110000000000000000000000cf3711000a00000000000000b4471100010000000000000000000000cc471100130000000000000000000000d93711000f0000000000000064481100020000000000000000000000944811001200000000000000ec4d11002f000000301a1300000000001b4e110058000000364c11001a000000301a130000000000504c110035000000301a130000000000f5bd12000b000000184a11000a000000734e11001e000000914e11003f000000d04e110040000000004d11000d000000104f11003a0000004a4f110039000000814d11006b00000044be12000c00000000000000834b11000600000000000000f320120023000000b24b11002f000000301a13000000000098c9120034000000301a130000000000e14b110055000000364c11001a000000301a130000000000504c110035000000301a130000000000f5bd12000b000000184a11000a000000224a11001e000000854c11003d000000c24c11003e000000004d11000d0000000d4d11003b000000484d110039000000814d11006b00000044be12000c00000000000000834b11000600000000000000f32012002300000000000000a8d811000800000000000000894b110029000000244911001a000000301a13000000000098c9120034000000301a1300000000003e491100450000008349110040000000c34911003d000000301a130000000000004a110018000000301a130000000000f5bd12000b000000184a11000a000000224a11001e000000404a11004f0000008f4a110050000000df4a110038000000174b11006c00000044be12000c00000020437265617465206120766573746564207472616e736665722e202d2060746172676574603a20546865206163636f756e7420746861742073686f756c64206265207472616e7366657272656420746865207665737465642066756e64732e202d2060616d6f756e74603a2054686520616d6f756e74206f662066756e647320746f207472616e7366657220616e642077696c6c206265207665737465642e202d20607363686564756c65603a205468652076657374696e67207363686564756c6520617474616368656420746f20746865207472616e736665722e20456d697473206056657374696e6743726561746564602e202d20604f283129602e202d2044625765696768743a20332052656164732c20332057726974657320202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e742c205b53656e646572204163636f756e745d20202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e742c205b53656e646572204163636f756e745d202d2042656e63686d61726b3a203131312e34202b202e333435202a206c20c2b57320286d696e2073717561726520616e616c7973697329202d205573696e672031313520c2b5732066697865642e20417373756d696e67206c657373207468616e203530206c6f636b73206f6e20616e7920757365722c20656c7365207765206d61792077616e7420666163746f7220696e206e756d626572206f66206c6f636b732e74617267657456657374696e67496e666f3c42616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265723e20556e6c6f636b20616e79207665737465642066756e6473206f662061206074617267657460206163636f756e742e202d2060746172676574603a20546865206163636f756e742077686f7365207665737465642066756e64732073686f756c6420626520756e6c6f636b65642e204d75737420686176652066756e6473207374696c6c206c6f636b656420756e6465722074686973206d6f64756c652e20456d69747320656974686572206056657374696e67436f6d706c6574656460206f72206056657374696e6755706461746564602e20202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e7420202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c20546172676574204163636f756e74202d2042656e63686d61726b3a20202020202d20556e6c6f636b65643a2035382e3039202b202e313034202a206c20c2b57320286d696e2073717561726520616e616c797369732920202020202d204c6f636b65643a2035352e3335202b202e323535202a206c20c2b57320286d696e2073717561726520616e616c7973697329202d205573696e6720363020c2b5732066697865642e20417373756d696e67206c657373207468616e203530206c6f636b73206f6e20616e7920757365722c20656c7365207765206d61792077616e7420666163746f7220696e206e756d626572206f66206c6f636b732e20556e6c6f636b20616e79207665737465642066756e6473206f66207468652073656e646572206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e6473207374696c6c202d2044625765696768743a20322052656164732c20322057726974657320202020202d2052656164733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c205b53656e646572204163636f756e745d20202020202d205772697465733a2056657374696e672053746f726167652c2042616c616e636573204c6f636b732c205b53656e646572204163636f756e745d20202020202d20556e6c6f636b65643a2035362e31202b202e303938202a206c20c2b57320286d696e2073717561726520616e616c797369732920202020202d204c6f636b65643a2035342e3337202b202e323534202a206c20c2b57320286d696e2073717561726520616e616c7973697329000000000002bf11000700000001020000000000007ac312000c00000000000000894b11002900000000000000000000000000000000000000301a1300dc4f11000000000000000000ec4f11000100000000000000000000004200000000000000010000005b000000f44f11003600000020496e666f726d6174696f6e20726567617264696e67207468652076657374696e67206f66206120676976656e206163636f756e742e000000000000645011001100000000000000b66c12000c00000000000000301a1300549a110000000000000000007850110001000000000000004d696e5665737465645472616e73666572000000805011004700000020546865206d696e696d756d20616d6f756e7420746f206265207472616e7366657272656420746f206372656174652061206e65772076657374696e67207363686564756c652e00000000005f391100070000000105000000000000285211000d00000000000000355211003400000000000000000000000000000000000000301a13008891110000000000000000006c5211000100000000000000000000000000000066391100100000000000000000000000745211001900000000000000000000000000000000000000000000000000000000000000301a1300905211000000000000000000a052110002000000000000000100000000000000b05211001600000002050500000000008ff51200040000000000000093f512000e00000000000000c65211001200000000000000301a1300d85211000000000000000000e8521100010000000000000001000000000000002af412001200000001050000000000008ff512000400000000000000cc8d12000700000000000000000000000000000000000000301a1300f05211000000000000000000005311000600000000000000010000005265706f727449644f663c543e4f6666656e636544657461696c733c543a3a4163636f756e7449642c20543a3a4964656e74696669636174696f6e5475706c653e00000003551100520000005665633c44656665727265644f6666656e63654f663c543e3e000000420000000000000001000000590000009954110059000000f254110011000000436f6e63757272656e745265706f727473496e6465785665633c5265706f727449644f663c543e3e420000000000000001000000590000004f5411004a000000420000000000000001000000590000003053110044000000301a130000000000745311002f000000301a130000000000a353110052000000f55311005a00000020456e756d65726174657320616c6c207265706f727473206f662061206b696e6420616c6f6e672077697468207468652074696d6520746865792068617070656e65642e20416c6c207265706f7274732061726520736f72746564206279207468652074696d65206f66206f6666656e63652e204e6f74652074686174207468652061637475616c2074797065206f662074686973206d617070696e6720697320605665633c75383e602c207468697320697320626563617573652076616c756573206f6620646966666572656e7420747970657320617265206e6f7420737570706f7274656420617420746865206d6f6d656e7420736f2077652061726520646f696e6720746865206d616e75616c2073657269616c697a6174696f6e2e204120766563746f72206f66207265706f727473206f66207468652073616d65206b696e6420746861742068617070656e6564206174207468652073616d652074696d6520736c6f742e204465666572726564207265706f72747320746861742068617665206265656e2072656a656374656420627920746865206f6666656e63652068616e646c657220616e64206e65656420746f206265207375626d69747465642061742061206c617465722074696d652e20546865207072696d61727920737472756374757265207468617420686f6c647320616c6c206f6666656e6365207265636f726473206b65796564206279207265706f7274206964656e746966696572732e000000000000000db012000700000000000000545a1100020000000000000000000000845a11000f0000000000000000000000f23a11000600000000000000fc5a1100010000000000000000000000145b11000c000000000000000000000014b012000400000000000000745b1100020000000000000000000000a45b11000d0000000000000000000000f83a11000a00000000000000745b11000200000000000000000000000c5c11000c0000000000000000000000023b110010000000000000006c5c1100010000000000000000000000845c11000a0000000000000000000000123b11001000000000000000d45c1100010000000000000000000000ec5c11000b0000000000000000000000223b11001900000000000000d45c1100010000000000000000000000445d11000e00000000000000000000003b3b11001800000000000000d45c1100010000000000000000000000b45d11000e0000000000000000000000533b11000a00000000000000245e11000300000000000000000000006c5e11001300000000000000000000005d3b11000d00000000000000d45c1100010000000000000000000000045f11000f00000000000000000000006a3b110011000000000000007c5f1100010000000000000000000000945f11000900000000000000000000007b3b11000d00000000000000dc5f1100010000000000000000000000f45f11000a0000000000000000000000883b11000e00000000000000446011000100000000000000000000005c6011000b0000000000000000000000963b11000b00000000000000301a1300000000000000000000000000b4601100090000000000000000000000a13b1100100000000000000044601100010000000000000000000000fc6011000d0000000000000000000000b13b1100080000000000000064611100030000000000000000000000ac611100140000000000000000000000b93b11000a00000000000000301a13000000000000000000000000004c6211000d0000000000000000000000c33b11001600000000000000301a1300000000000000000000000000b4621100080000000000000000000000d93b11000d00000000000000f46211000100000000000000000000000c6311000d0000000000000000000000e63b11001600000000000000f4621100010000000000000000000000746311000c0000000000000000000000fc3b11000d00000000000000d45c1100010000000000000000000000d46311000f0000000000000000000000093c110006000000000000004c641100010000000000000000000000646411000900000000000000000000000f3c11000a000000000000004c641100010000000000000000000000ac6411000d0000000000000000000000193c11000b00000000000000146511000100000000000000000000002c6511001c0000000000000000000000243c110011000000000000000c6611000200000000000000000000003c661100100000000000000000000000353c11000e0000000000000064611100030000000000000000000000bc661100170000000000000000000000433c11001000000000000000301a1300000000000000000000000000746711000d0000000000000000000000533c1100110000000000000014651100010000000000000000000000dc6711000d0000000000000000000000643c11000e000000000000004468110002000000000000000000000074681100010000000000000000000000d06811000d0000000000000091d912000700000000000000aa4d1200050000000000000080751200150000001089110028000000301a13000000000038891100460000007e89110021000000301a1300000000009f89110036000000d589110046000000301a1300000000001b8a110012000000301a130000000000f5bd12000b0000002d8a110009000000368a1100360000006c8a11002000000044be12000c0000000000000089d912000800000000000000fe88110012000000c88711002e000000301a130000000000f6871100410000003788110045000000301a1300000000007c88110033000000301a130000000000f5bd12000b000000af8811000a000000b988110035000000ee8811001000000044be12000c000000000000004f7e11000900000000000000587e1100180000000000000014b012000400000000000000af87110019000000b88611004d000000058711002f000000301a130000000000f370110033000000301a13000000000034871100380000007786110022000000301a130000000000f5bd12000b0000006c8711000a0000007687110039000000998611001f00000044be12000c000000a885110054000000fc8511003d000000301a130000000000f370110033000000301a130000000000398611003e0000007786110022000000301a130000000000f5bd12000b000000184a11000a000000998611001f00000044be12000c000000000000004f7e11000900000000000000344211000f000000e084110054000000998411000c000000301a130000000000348511003f000000301a1300000000007385110035000000301a130000000000f5bd12000b000000184a11000a00000044be12000c00000000000000d06811000d0000000000000091d91200070000004d8411004c000000998411000c000000301a130000000000a58411003b000000301a130000000000f382110036000000301a130000000000f5bd12000b000000184a11000a000000732112001100000044be12000c000000a383110056000000f983110018000000301a130000000000118411003c000000301a130000000000f382110036000000301a13000000000029831100530000007c83110027000000301a130000000000f5bd12000b000000184a11000a000000732112001100000044be12000c00000045821100520000009782110021000000301a130000000000b88211003b000000301a130000000000f382110036000000301a13000000000029831100530000007c83110027000000301a130000000000f5bd12000b000000184a11000a000000732112001100000044be12000c00000000000000d06811000d0000000000000091d912000700000000000000338211000d0000000000000006cf12000e0000000000000040821100050000000000000006cf12000e000000c57f1100540000001980110059000000728011003b000000301a130000000000ad80110035000000301a130000000000e28011003e000000208111005800000078811100260000009e81110055000000f38111002f000000301a1300000000002282110011000000301a130000000000f5bd12000b000000db7711001000000073211200110000000d7611001600000044be12000c000000707e11002f000000301a1300000000009f7e110037000000301a130000000000d67e11004c000000301a130000000000227f110010000000301a130000000000f5bd12000b000000327f110012000000db77110010000000447f110042000000867f110011000000977f11002e00000044be12000c000000000000004f7e11000900000000000000587e110018000000047e110015000000301a130000000000217a110031000000301a130000000000197e110036000000301a130000000000f5bd12000b000000184a11000a00000044be12000c00000000000000ff7d11000500000000000000344211000f000000727d110028000000301a130000000000217a110031000000301a1300000000009a7d110032000000301a130000000000f5bd12000b0000007321120011000000cc7d11003300000044be12000c000000000000006d7d110005000000000000007ac312000c000000cf7c110041000000301a130000000000107d110025000000301a130000000000f370110033000000301a130000000000357d110038000000301a130000000000f5bd12000b0000000d7611001600000044be12000c000000817c110026000000301a130000000000a77c110028000000301a130000000000f370110033000000301a130000000000f5bd12000b000000db7711001000000044be12000c000000b27b11004b000000301a130000000000fd7b110022000000301a1300000000001f7c110028000000301a130000000000f370110033000000301a130000000000477c11003a000000301a130000000000f5bd12000b000000db7711001000000044be12000c00000000000000957b110002000000000000007ac312000c00000000000000977b11000a00000000000000a17b11000a00000000000000ab7b11000700000000000000b66c12000c000000ee7a11004f000000301a1300000000000a6c110056000000606c110033000000301a1300000000003d7b110058000000886d11001e000000a66d110057000000fd6d110026000000301a130000000000236e110052000000756e110056000000cb6e1100510000001c6f110055000000716f110032000000301a130000000000a36f110013000000301a130000000000f5bd12000b00000044be12000c000000527a110034000000301a130000000000dc6a110058000000346b110038000000301a130000000000867a110052000000d87a110016000000301a130000000000a86b110015000000301a130000000000f5bd12000b000000852012000800000044be12000c000000047a11001d000000301a130000000000217a110031000000301a130000000000f5bd12000b000000184a11000a000000db7711001000000044be12000c00000000000000f47911001000000000000000cc8d120007000000fe781100580000005679110049000000301a130000000000f370110033000000301a1300000000006978110032000000301a1300000000009b78110017000000301a130000000000f5bd12000b0000009f79110041000000e07911001400000044be12000c000000eb771100510000003c7811002d000000301a130000000000f370110033000000301a1300000000006978110032000000301a1300000000009b78110017000000301a130000000000f5bd12000b000000b27811004c00000044be12000c0000007b7611003d000000301a130000000000f370110033000000301a130000000000b876110034000000301a130000000000ec761100540000004077110057000000977711002c000000301a130000000000c377110018000000301a130000000000f5bd12000b000000db7711001000000044be12000c00000000000000834b110006000000000000007ac312000c0000002376110029000000301a130000000000f370110033000000301a1300000000004c7611002f000000301a130000000000f5bd12000b000000184a11000a00000044be12000c0000003075110010000000301a1300000000004075110037000000301a1300000000007775110019000000301a130000000000907511003b000000301a130000000000cb75110042000000301a130000000000f5bd12000b0000000d7611001600000044be12000c0000000000000098d912000500000000000000344211000f000000b66f110020000000301a13000000000090711100040000009471110023000000b771110020000000d771110025000000fc711100400000003c7211003600000072721100220000009472110058000000ec72110017000000301a130000000000037311002b0000002e7311003c0000006a73110038000000a273110030000000d2731100570000002974110057000000807411003a000000301a130000000000ba741100530000000d75110023000000301a1300000000001c6a11003e000000301a130000000000f5bd12000b0000005a6a11005000000044be12000c00000000000000834b110006000000000000007ac312000c0000000000000098d912000500000000000000344211000f000000b66f110020000000301a130000000000d66f1100540000002a7011004c0000007670110056000000cc70110027000000301a130000000000f370110033000000301a13000000000026711100540000007a711100160000001c6a11003e000000301a130000000000f5bd12000b0000005a6a11005000000044be12000c000000bd6b11004d000000301a1300000000000a6c110056000000606c110033000000301a130000000000936c110055000000e86c11002c000000301a130000000000146d1100580000006c6d11001c000000886d11001e000000a66d110057000000fd6d110026000000236e110052000000756e110056000000cb6e1100510000001c6f110055000000716f110032000000301a130000000000a36f110013000000301a130000000000f5bd12000b00000044be12000c000000aa6a110032000000301a130000000000dc6a110058000000346b110038000000301a13000000000070691100540000006c6b11003c000000301a130000000000a86b110015000000301a130000000000f5bd12000b000000852012000800000044be12000c000000dd68110028000000301a13000000000005691100540000005969110017000000301a1300000000007069110054000000c469110058000000301a1300000000001c6a11003e000000301a130000000000f5bd12000b0000005a6a11005000000044be12000c00000000000000d06811000d0000000000000091d91200070000000000000098d912000500000000000000344211000f0000007c6811005400000020456e61637420612070726f706f73616c2066726f6d2061207265666572656e64756d2e20466f72206e6f77207765206a757374206d616b65207468652077656967687420626520746865206d6178696d756d2e70726f706f73616c5f686173682052656d6f766520612070726f7869656420766f746520666f722061207265666572656e64756d2e2045786163746c79206571756976616c656e7420746f206072656d6f76655f766f746560206578636570742074686174206974206f70657261746573206f6e20746865206163636f756e742074686174207468652073656e64657220697320612070726f787920666f722e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d75737420626520612070726f787920666f7220736f6d65206f74686572206163636f756e74207768696368206861732061207265676973746572656420766f746520666f7220746865207265666572656e64756d206f662060696e646578602e202d2060696e646578603a2054686520696e646578206f66207265666572656e64756d206f662074686520766f746520746f2062652072656d6f7665642e202d20604f2852202b206c6f6720522960207768657265205220697320746865206e756d626572206f66207265666572656e646120746861742060746172676574602068617320766f746564206f6e2e20556e64656c65676174652074686520766f74696e6720706f776572206f6620612070726f78696564206163636f756e742e20546f6b656e73206d617920626520756e6c6f636b656420666f6c6c6f77696e67206f6e636520616e20616d6f756e74206f662074696d6520636f6e73697374656e74207769746820746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e2077697468207768696368207468652064656c65676174696f6e20776173206973737565642e2070726f787920666f7220736f6d65206f74686572206163636f756e742077686963682069732063757272656e746c792064656c65676174696e672e20456d6974732060556e64656c656761746564602e2044656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f6620612070726f78696564206163636f756e742e205468652062616c616e63652064656c656761746564206973206c6f636b656420666f72206173206c6f6e6720617320697427732064656c6567617465642c20616e64207468657265616674657220666f72207468652074696d6520617070726f70726961746520666f722074686520636f6e76696374696f6e2773206c6f636b20706572696f642e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d7573742068617665206265656e20736574206173207468652070726f7879206163636f756e7420666f722060746172676574602e202d2060746172676574603a20546865206163636f756e742077686f6c6520766f74696e6720706f776572207368616c6c2062652064656c65676174656420616e642077686f73652062616c616e6365206c6f636b65642e20202054686973206163636f756e74206d757374206569746865723a2020202d2062652064656c65676174696e6720616c72656164793b206f722020202d2068617665206e6f20766f74696e67206163746976697479202869662074686572652069732c207468656e2069742077696c6c206e65656420746f2062652072656d6f7665642f636f6e736f6c69646174656420202020207468726f7567682060726561705f766f746560206f722060756e766f746560292e202d2060746f603a20546865206163636f756e742077686f736520766f74696e6720746865206074617267657460206163636f756e74277320766f74696e6720706f7765722077696c6c20666f6c6c6f772e202d2060636f6e76696374696f6e603a2054686520636f6e76696374696f6e20746861742077696c6c20626520617474616368656420746f207468652064656c65676174656420766f7465732e205768656e207468652020206163636f756e7420697320756e64656c6567617465642c207468652066756e64732077696c6c206265206c6f636b656420666f722074686520636f72726573706f6e64696e6720706572696f642e202d206062616c616e6365603a2054686520616d6f756e74206f6620746865206163636f756e7427732062616c616e636520746f206265207573656420696e2064656c65676174696e672e2054686973206d7573742020206e6f74206265206d6f7265207468616e20746865206163636f756e7427732063757272656e742062616c616e63652e20456d697473206044656c656761746564602e2052656d6f7665206120766f746520666f722061207265666572656e64756d2e2049662074686520607461726765746020697320657175616c20746f20746865207369676e65722c207468656e20746869732066756e6374696f6e2069732065786163746c79206571756976616c656e7420746f206072656d6f76655f766f7465602e204966206e6f7420657175616c20746f20746865207369676e65722c207468656e2074686520766f7465206d757374206861766520657870697265642c20656974686572206265636175736520746865207265666572656e64756d207761732063616e63656c6c65642c20626563617573652074686520766f746572206c6f737420746865207265666572656e64756d206f7220626563617573652074686520636f6e76696374696f6e20706572696f64206973206f7665722e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2e202d2060746172676574603a20546865206163636f756e74206f662074686520766f746520746f2062652072656d6f7665643b2074686973206163636f756e74206d757374206861766520766f74656420666f722020207265666572656e64756d2060696e646578602e2049663a202d20746865207265666572656e64756d207761732063616e63656c6c65642c206f72202d20746865207265666572656e64756d206973206f6e676f696e672c206f72202d20746865207265666572656e64756d2068617320656e646564207375636820746861742020202d2074686520766f7465206f6620746865206163636f756e742077617320696e206f70706f736974696f6e20746f2074686520726573756c743b206f722020202d20746865726520776173206e6f20636f6e76696374696f6e20746f20746865206163636f756e74277320766f74653b206f722020202d20746865206163636f756e74206d61646520612073706c697420766f7465202e2e2e7468656e2074686520766f74652069732072656d6f76656420636c65616e6c7920616e64206120666f6c6c6f77696e672063616c6c20746f2060756e6c6f636b60206d617920726573756c7420696e206d6f72652066756e6473206265696e6720617661696c61626c652e2049662c20686f77657665722c20746865207265666572656e64756d2068617320656e64656420616e643a202d2069742066696e697368656420636f72726573706f6e64696e6720746f2074686520766f7465206f6620746865206163636f756e742c20616e64202d20746865206163636f756e74206d6164652061207374616e6461726420766f7465207769746820636f6e76696374696f6e2c20616e64202d20746865206c6f636b20706572696f64206f662074686520636f6e76696374696f6e206973206e6f74206f766572202e2e2e7468656e20746865206c6f636b2077696c6c206265206167677265676174656420696e746f20746865206f766572616c6c206163636f756e742773206c6f636b2c207768696368206d617920696e766f6c7665202a6f7665726c6f636b696e672a20287768657265207468652074776f206c6f636b732061726520636f6d62696e656420696e746f20612073696e676c65206c6f636b207468617420697320746865206d6178696d756d206f6620626f74682074686520616d6f756e74206c6f636b656420616e64207468652074696d65206973206974206c6f636b656420666f72292e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e6572206d7573742068617665206120766f7465207265676973746572656420666f72207265666572656e64756d2060696e646578602e204265636f6d6520612070726f78792e2054686973206d7573742062652063616c6c6564207072696f7220746f2061206c61746572206061637469766174655f70726f7879602e204f726967696e206d7573742062652061205369676e65642e202d2060746172676574603a20546865206163636f756e742077686f736520766f7465732077696c6c206c617465722062652070726f786965642e2060636c6f73655f70726f787960206d7573742062652063616c6c6564206265666f726520746865206163636f756e742063616e2062652064657374726f7965642e202d204f6e6520657874726120444220656e7472792e20556e6c6f636b20746f6b656e732074686174206861766520616e2065787069726564206c6f636b2e202d2060746172676574603a20546865206163636f756e7420746f2072656d6f766520746865206c6f636b206f6e2e2052656d6f766520616e20657870697265642070726f706f73616c20707265696d61676520616e6420636f6c6c65637420746865206465706f7369742e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f6620612070726f706f73616c2e20546869732077696c6c206f6e6c7920776f726b2061667465722060566f74696e67506572696f646020626c6f636b732066726f6d207468652074696d6520746861742074686520707265696d61676520776173206e6f7465642c2069662069742773207468652073616d65206163636f756e7420646f696e672069742e2049662069742773206120646966666572656e74206163636f756e742c207468656e206974276c6c206f6e6c7920776f726b20616e206164646974696f6e616c2060456e6163746d656e74506572696f6460206c617465722e20456d6974732060507265696d616765526561706564602e202d204f6e6520444220636c6561722e2052656769737465722074686520707265696d61676520666f7220616e207570636f6d696e672070726f706f73616c2e2054686973207265717569726573207468652070726f706f73616c20746f20626520696e207468652064697370617463682071756575652e204e6f206465706f736974206973206e65656465642e202d2060656e636f6465645f70726f706f73616c603a2054686520707265696d616765206f6620612070726f706f73616c2e20456d6974732060507265696d6167654e6f746564602e202d20446570656e64656e74206f6e207468652073697a65206f662060656e636f6465645f70726f706f73616c6020616e64206c656e677468206f662064697370617463682071756575652e2052656769737465722074686520707265696d61676520666f7220616e207570636f6d696e672070726f706f73616c2e205468697320646f65736e27742072657175697265207468652070726f706f73616c20746f20626520696e207468652064697370617463682071756575652062757420646f657320726571756972652061206465706f7369742c2072657475726e6564206f6e636520656e61637465642e202d20446570656e64656e74206f6e207468652073697a65206f662060656e636f6465645f70726f706f73616c60206275742070726f74656374656420627920612020207265717569726564206465706f7369742e656e636f6465645f70726f706f73616c20436c6561727320616c6c207075626c69632070726f706f73616c732e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f526f6f745f2e20556e64656c65676174652074686520766f74696e6720706f776572206f66207468652073656e64696e67206163636f756e742e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062652063757272656e746c792064656c65676174696e672e2044656c65676174652074686520766f74696e6720706f77657220287769746820736f6d6520676976656e20636f6e76696374696f6e29206f66207468652073656e64696e67206163636f756e742e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f2c20616e6420746865207369676e696e67206163636f756e74206d757374206569746865723a746f636f6e76696374696f6e436f6e76696374696f6e62616c616e63652044656163746976617465207468652070726f78792c20627574206c65617665206f70656e20746f2074686973206163636f756e742e2043616c6c6564206279207468652073746173682e205468652070726f7879206d75737420616c7265616479206265206163746976652e204e4f54453a205573656420746f2062652063616c6c6564206072656d6f76655f70726f7879602e202d206070726f7879603a20546865206163636f756e7420746861742077696c6c2062652064656163746976617465642061732070726f78792e20436c656172207468652070726f78792e2043616c6c6564206279207468652070726f78792e204e4f54453a205573656420746f2062652063616c6c6564206072657369676e5f70726f7879602e205370656369667920612070726f7879207468617420697320616c7265616479206f70656e20746f2075732e2043616c6c6564206279207468652073746173682e204e4f54453a205573656420746f2062652063616c6c656420607365745f70726f7879602e202d206070726f7879603a20546865206163636f756e7420746861742077696c6c206265206163746976617465642061732070726f78792e70726f78792043616e63656c20612070726f706f73616c2071756575656420666f7220656e6163746d656e742e202d20607768696368603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e202d204f286429207768657265206420697320746865206974656d7320696e207468652064697370617463682071756575652e77686963682052656d6f76652061207265666572656e64756d2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e7265665f696e646578436f6d706163743c5265666572656e64756d496e6465783e205665746f20616e6420626c61636b6c697374207468652065787465726e616c2070726f706f73616c20686173682e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d75737420626520605665746f4f726967696e602e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c20746f207665746f20616e6420626c61636b6c6973742e20456d69747320605665746f6564602e202d2054776f20444220656e74726965732e202d20506572666f726d7320612062696e61727920736561726368206f6e20606578697374696e675f7665746f657273602077686963682073686f756c64206e6f7420202062652076657279206c617267652e202d204f286c6f672076292c2076206973206e756d626572206f6620606578697374696e675f7665746f65727360205363686564756c65207468652063757272656e746c792065787465726e616c6c792d70726f706f736564206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c656420696d6d6564696174656c792e204966207468657265206973206e6f2065787465726e616c6c792d70726f706f736564207265666572656e64756d2063757272656e746c792c206f72206966207468657265206973206f6e6520627574206974206973206e6f742061206d616a6f726974792d63617272696573207265666572656e64756d207468656e206974206661696c732e20546865206469737061746368206f6620746869732063616c6c206d757374206265206046617374547261636b4f726967696e602e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652063757272656e742065787465726e616c2070726f706f73616c2e202d2060766f74696e675f706572696f64603a2054686520706572696f64207468617420697320616c6c6f77656420666f7220766f74696e67206f6e20746869732070726f706f73616c2e20496e6372656173656420746f2020206046617374547261636b566f74696e67506572696f646020696620746f6f206c6f772e202d206064656c6179603a20546865206e756d626572206f6620626c6f636b20616674657220766f74696e672068617320656e64656420696e20617070726f76616c20616e6420746869732073686f756c64206265202020656e61637465642e205468697320646f65736e277420686176652061206d696e696d756d20616d6f756e742e20456d697473206053746172746564602e766f74696e675f706572696f6464656c6179205363686564756c652061206e656761746976652d7475726e6f75742d62696173207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c44656661756c744f726967696e602e202d206070726f706f73616c5f68617368603a2054686520707265696d6167652068617368206f66207468652070726f706f73616c2e20556e6c696b65206065787465726e616c5f70726f706f7365602c20626c61636b6c697374696e6720686173206e6f20656666656374206f6e207468697320616e64206974206d6179207265706c6163652061207072652d7363686564756c6564206065787465726e616c5f70726f706f7365602063616c6c2e205363686564756c652061206d616a6f726974792d63617272696573207265666572656e64756d20746f206265207461626c6564206e657874206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f6620746869732063616c6c206d757374206265206045787465726e616c4d616a6f726974794f726967696e602e205363686564756c652061207265666572656e64756d20746f206265207461626c6564206f6e6365206974206973206c6567616c20746f207363686564756c6520616e2065787465726e616c207265666572656e64756d2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206045787465726e616c4f726967696e602e205363686564756c6520616e20656d657267656e63792063616e63656c6c6174696f6e206f662061207265666572656e64756d2e2043616e6e6f742068617070656e20747769636520746f207468652073616d6520546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265206043616e63656c6c6174696f6e4f726967696e602e202d607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2063616e63656c2e20566f746520696e2061207265666572656e64756d206f6e20626568616c66206f6620612073746173682e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f2070726f787920766f746520666f722e202d2060766f7465603a2054686520766f746520636f6e66696775726174696f6e2e202d204f6e65204442206368616e67652c206f6e6520444220656e7472792e20566f746520696e2061207265666572656e64756d2e2049662060766f74652e69735f6179652829602c2074686520766f746520697320746f20656e616374207468652070726f706f73616c3b206f7468657277697365206974206973206120766f746520746f206b65657020746865207374617475732071756f2e202d20607265665f696e646578603a2054686520696e646578206f6620746865207265666572656e64756d20746f20766f746520666f722e202d20604f285229602e202d205220697320746865206e756d626572206f66207265666572656e64756d732074686520766f7465722068617320766f746564206f6e2e4163636f756e74566f74653c42616c616e63654f663c543e3e205369676e616c732061677265656d656e742077697468206120706172746963756c61722070726f706f73616c2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e647320746f20636f76657220746865206465706f7369742c20657175616c20746f20746865206f726967696e616c206465706f7369742e202d206070726f706f73616c603a2054686520696e646578206f66207468652070726f706f73616c20746f207365636f6e642e202d20604f285329602e202d205320697320746865206e756d626572206f66207365636f6e647320612070726f706f73616c20616c7265616479206861732e202d204f6e6520444220656e7472792e436f6d706163743c50726f70496e6465783e2050726f706f736520612073656e73697469766520616374696f6e20746f2062652074616b656e2e20546865206469737061746368206f726967696e206f6620746869732063616c6c206d757374206265205f5369676e65645f20616e64207468652073656e646572206d75737420686176652066756e647320746f20636f76657220746865206465706f7369742e202d206070726f706f73616c5f68617368603a205468652068617368206f66207468652070726f706f73616c20707265696d6167652e202d206076616c7565603a2054686520616d6f756e74206f66206465706f73697420286d757374206265206174206c6561737420604d696e696d756d4465706f73697460292e20456d697473206050726f706f736564602e202d20604f28502960202d205020697320746865206e756d6265722070726f706f73616c7320696e2074686520605075626c696350726f707360207665632e202d2054776f204442206368616e6765732c206f6e6520444220656e7472792e00000000bbf112000f00000000000000000000007b4411000900000000000000000000000000000000000000000000000000000000000000301a13003490110000000000000000005c8f110001000000000000000100000000000000914611000b0000000000000000000000648f11002700000000000000000000000000000000000000000000000000000000000000301a13008c8f110000000000000000009c8f110001000000000000000100000000000000723c11000900000001050000000000007b4411000900000000000000a48f11002100000000000000000000000000000000000000301a1300c88f11000000000000000000d88f1100010000000000000000000000000000008846110009000000010600000000000091d912000700000000000000e08f11003a00000000000000000000000000000000000000301a13008891110000000000000000001c90110002000000000000000000000000000000caf112000f0000000000000000000000344211000f00000000000000000000000000000000000000000000000000000000000000301a13003490110000000000000000002c90110001000000000000000100000000000000e2f112000d0000000000000000000000344211000f00000000000000000000000000000000000000000000000000000000000000301a130034901100000000000000000044901100020000000000000001000000000000007b3c1100100000000105000000000000344211000f00000000000000549011003500000000000000000000000000000000000000301a13008c90110000000000000000009c90110001000000000000000000000000000000a49011000800000001050000000000007ac312000c00000000000000ac9011003200000000000000000000000000000000000000301a1300e09011000000000000000000f09011000200000000000000010000000000000064d312000500000001050000000000007ac312000c00000000000000009111001800000000000000000000000000000000000000301a13001891110000000000000000002891110002000000000000000000000000000000389111000500000001050000000000007ac312000c0000000000000006cf12000e00000000000000000000000000000000000000301a13004091110000000000000000005091110002000000000000000000000000000000eff11200150000000000000000000000a1f512000400000000000000000000000000000000000000000000000000000000000000301a130014921100000000000000000060911100020000000000000001000000000000009c4611000c0000000000000000000000709111001800000000000000000000000000000000000000000000000000000000000000301a13008891110000000000000000009891110004000000000000000000000000000000b891110009000000010600000000000091d912000700000000000000c19111002300000000000000000000000000000000000000301a1300e49111000000000000000000f491110002000000000000000000000000000000049211000d000000010600000000000091d912000700000000000000a1f512000400000000000000000000000000000000000000301a1300149211000000000000000000249211000100000000000000010000000c9811003d0000005665633c2850726f70496e6465782c20543a3a486173682c20543a3a4163636f756e744964293e0042000000000000000100000059000000c4971100480000002842616c616e63654f663c543e2c205665633c543a3a4163636f756e7449643e290000004200000000000000010000007e000000a397110021000000507265696d6167655374617475733c543a3a4163636f756e7449642c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265723e000012971100580000006a97110039000000c69611004c0000004200000000000000010000005700000046961100490000008f961100370000005265666572656e64756d496e666f3c543a3a426c6f636b4e756d6265722c20543a3a486173682c2042616c616e63654f663c543e3e0000004200000000000000010000005b000000199611002d000000566f74696e674f66566f74696e673c42616c616e63654f663c543e2c20543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265723e00004200000000000000010000007f0000006b95110057000000c29511005700000050726f787953746174653c543a3a4163636f756e7449643e4200000000000000010000005b000000fd9411004c00000049951100220000004c6f636b730000004200000000000000010000005b0000005294110057000000a994110054000000f293110056000000489411000a00000028543a3a486173682c20566f74655468726573686f6c64294200000000000000010000005b00000004931100560000005a93110055000000af93110029000000d89311001a000000426c61636b6c69737428543a3a426c6f636b4e756d6265722c205665633c543a3a4163636f756e7449643e294200000000000000010000007e0000007692110054000000ca9211003a00000043616e63656c6c6174696f6e730000004200000000000000010000005b0000002c9211004a000000205265636f7264206f6620616c6c2070726f706f73616c7320746861742068617665206265656e207375626a65637420746f20656d657267656e63792063616e63656c6c6174696f6e2e2041207265636f7264206f662077686f207665746f656420776861742e204d6170732070726f706f73616c206861736820746f206120706f737369626c65206578697374656e7420626c6f636b206e756d6265722028756e74696c207768656e206974206d6179206e6f742062652072657375626d69747465642920616e642077686f207665746f65642069742e20546865207265666572656e64756d20746f206265207461626c6564207768656e6576657220697420776f756c642062652076616c696420746f207461626c6520616e2065787465726e616c2070726f706f73616c2e20546869732068617070656e73207768656e2061207265666572656e64756d206e6565647320746f206265207461626c656420616e64206f6e65206f662074776f20636f6e646974696f6e7320617265206d65743a202d20604c6173745461626c656457617345787465726e616c60206973206066616c7365603b206f72202d20605075626c696350726f70736020697320656d7074792e205472756520696620746865206c617374207265666572656e64756d207461626c656420776173207375626d69747465642065787465726e616c6c792e2046616c7365206966206974207761732061207075626c69632070726f706f73616c2e204163636f756e747320666f7220776869636820746865726520617265206c6f636b7320696e20616374696f6e207768696368206d61792062652072656d6f76656420617420736f6d6520706f696e7420696e20746865206675747572652e205468652076616c75652069732074686520626c6f636b206e756d62657220617420776869636820746865206c6f636b206578706972657320616e64206d61792062652072656d6f7665642e2057686f2069732061626c6520746f20766f746520666f722077686f6d2e2056616c7565206973207468652066756e642d686f6c64696e67206163636f756e742c206b65792069732074686520766f74652d7472616e73616374696f6e2d73656e64696e67206163636f756e742e20416c6c20766f74657320666f72206120706172746963756c617220766f7465722e2057652073746f7265207468652062616c616e636520666f7220746865206e756d626572206f6620766f74657320746861742077652068617665207265636f726465642e20546865207365636f6e64206974656d2069732074686520746f74616c20616d6f756e74206f662064656c65676174696f6e732c20746861742077696c6c2062652061646465642e20496e666f726d6174696f6e20636f6e6365726e696e6720616e7920676976656e207265666572656e64756d2e20546865206c6f77657374207265666572656e64756d20696e64657820726570726573656e74696e6720616e20756e62616b6564207265666572656e64756d2e20457175616c20746f20605265666572656e64756d436f756e74602069662074686572652069736e2774206120756e62616b6564207265666572656e64756d2e20546865206e6578742066726565207265666572656e64756d20696e6465782c20616b6120746865206e756d626572206f66207265666572656e6461207374617274656420736f206661722e204d6170206f662068617368657320746f207468652070726f706f73616c20707265696d6167652c20616c6f6e6720776974682077686f207265676973746572656420697420616e64207468656972206465706f7369742e2054686520626c6f636b206e756d6265722069732074686520626c6f636b20617420776869636820697420776173206465706f73697465642e2054686f73652077686f2068617665206c6f636b65642061206465706f7369742e20546865207075626c69632070726f706f73616c732e20556e736f727465642e20546865207365636f6e64206974656d206973207468652070726f706f73616c277320686173682e20546865206e756d626572206f6620287075626c6963292070726f706f73616c7320746861742068617665206265656e206d61646520736f206661722e00000000000000d49911000f0000000000000006cf12000e00000000000000301a1300e49911000000000000000000f49911000500000000000000000000001c9a11000c0000000000000006cf12000e00000000000000301a1300ac9a11000000000000000000289a1100010000000000000000000000309a11000c0000000000000006cf12000e00000000000000301a1300ac9a110000000000000000003c9a1100010000000000000000000000449a11000e00000000000000b66c12000c00000000000000301a1300549a11000000000000000000649a11000100000000000000000000006c9a1100150000000000000006cf12000e00000000000000301a1300849a11000000000000000000949a11000100000000000000000000009c9a11000d0000000000000006cf12000e00000000000000301a1300ac9a11000000000000000000bc9a1100010000000000000000000000c49a11001300000000000000b66c12000c00000000000000301a1300d89a11000000000000000000e89a11000100000000000000456e6163746d656e74506572696f640042000000000000000100000080000000819c11005c000000301a130000000000dd9c11004c000000299d11005a000000839d1100270000004c61756e6368506572696f64489c110039000000566f74696e67506572696f641a9c11002e0000004d696e696d756d4465706f736974000042000000000000000100000081000000cd9b11004d00000046617374547261636b566f74696e67506572696f6400000042000000000000000100000082000000929b11003b000000436f6f6c6f6666506572696f64000000420000000000000001000000830000003a9b110058000000507265696d616765427974654465706f7369740042000000000000000100000084000000f09a11004a0000002054686520616d6f756e74206f662062616c616e63652074686174206d757374206265206465706f7369746564207065722062797465206f6620707265696d6167652073746f7265642e20506572696f6420696e20626c6f636b7320776865726520616e2065787465726e616c2070726f706f73616c206d6179206e6f742062652072652d7375626d6974746564206166746572206265696e67207665746f65642e204d696e696d756d20766f74696e6720706572696f6420616c6c6f77656420666f7220616e20656d657267656e6379207265666572656e64756d2e20546865206d696e696d756d20616d6f756e7420746f20626520757365642061732061206465706f73697420666f722061207075626c6963207265666572656e64756d2070726f706f73616c2e20486f77206f6674656e2028696e20626c6f636b732920746f20636865636b20666f72206e657720766f7465732e20486f77206f6674656e2028696e20626c6f636b7329206e6577207075626c6963207265666572656e646120617265206c61756e636865642e20546865206d696e696d756d20706572696f64206f66206c6f636b696e6720616e642074686520706572696f64206265747765656e20612070726f706f73616c206265696e6720617070726f76656420616e6420656e61637465642e2049742073686f756c642067656e6572616c6c792062652061206c6974746c65206d6f7265207468616e2074686520756e7374616b6520706572696f6420746f20656e73757265207468617420766f74696e67207374616b657273206861766520616e206f70706f7274756e69747920746f2072656d6f7665207468656d73656c7665732066726f6d207468652073797374656d20696e207468652063617365207768657265207468657920617265206f6e20746865206c6f73696e672073696465206f66206120766f74652e0000000000006246110006000000010500000000000006cf12000e000000000000005c9e11003a00000000000000000000000000000000000000301a1300989e11000000000000000000a89e110001000000000000000100000000000000b4441100060000000105000000000000cc8d12000700000000000000b09e11001b00000000000000000000000000000000000000301a1300cc9e11000000000000000000dc9e11000100000000000000000000005665633c4f7074696f6e3c5363686564756c65643c3c542061732054726169743e3a3a43616c6c2c20543a3a426c6f636b4e756d6265723e3e3e000042000000000000000100000059000000249f1100530000005461736b416464726573733c543a3a426c6f636b4e756d6265723e0042000000000000000100000085000000e49e110040000000204c6f6f6b75702066726f6d206964656e7469747920746f2074686520626c6f636b206e756d62657220616e6420696e646578206f6620746865207461736b2e204974656d7320746f2062652065786563757465642c20696e64657865642062792074686520626c6f636b206e756d626572207468617420746865792073686f756c64206265206578656375746564206f6e2e00696d2d6f6e6c696e653a6f66666c696e7573657220646f6573206e6f74206861766520616e206578697374696e672076657374696e67207363686564756c653b20712e652e642e00420000000c0000000400000086000000e09f110033000000080100000d0000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f76657374696e672f7372632f6c69622e72730034a0110035000000730500002d00000034a01100350000007a050000400000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f64656d6f63726163792f7372632f6c69622e727300000034a0110035000000460500002d00000072616e206f7574206f662067617320647572696e6720636f6e747261637420657865637574696f6e72657475726e2074797065206572726f7276616c69646174696f6e206572726f72636f6e7472616374207472617070656420647572696e6720657865637574696f6e707265636f6e646974696f6e3a20616c6c20696d706f7274732073686f756c6420626520636865636b656420616761696e737420746865207369676e617475726573206f6620636f72726573706f6e64696e670a09090909090966756e6374696f6e7320646566696e65642062792060646566696e655f656e762160206d6163726f206279207468652075736572206f6620746865206d6163726f3b0a0909090909097369676e617475726573206f662074686573652066756e6374696f6e7320646566696e6564206279206024706172616d73603b0a09090909090963616c6c7320616c77617973206d616465207769746820617267756d656e7473207479706573206f662077686963682061726520646566696e65642062792074686520636f72726573706f6e64696e6720696d706f7274733b0a09090909090974687573207479706573206f6620617267756d656e74732073686f756c6420626520657175616c20746f2074797065206c69737420696e206024706172616d736020616e640a0909090909096c656e677468206f6620617267756d656e74206c69737420616e642024706172616d732073686f756c6420626520657175616c3b0a0909090909097468757320746869732063616e206e6576657220626520604e6f6e65603b0a0909090909097165643b0a0909090909090000eca211004500000046000000110000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f636f6e7472616374732f7372632f7761736d2f656e765f6465662f6d6163726f732e7273657865632e7072656661625f6d6f64756c652e696e697469616c2063616e27742062652067726561746572207468616e20657865632e7072656661625f6d6f64756c652e6d6178696d756d3b0a09090909090974687573204d656d6f72793a3a6e6577206d757374206e6f74206661696c3b0a09090909090971656400000000000000c13711000a0000000000000004a41100010000000000000000000000aa37110017000000000000000ca41100010000000000000000000000a1371100090000000000000014a411000100000000000000b5a41100220000005ea41100570000001ca411004200000020416d6f756e74206265696e67207472616e7366657272656420697320746f6f206c6f7720746f2063726561746520612076657374696e67207363686564756c652e20416e206578697374696e672076657374696e67207363686564756c6520616c72656164792065786973747320666f722074686973206163636f756e7420746861742063616e6e6f7420626520636c6f6262657265642e20546865206163636f756e7420676976656e206973206e6f742076657374696e672e0000000000ea3a11000800000000000000e4a81100010000000000000000000000d2af12000f00000000000000eca81100010000000000000000000000e23a11000800000000000000f4a81100010000000000000000000000da3a11000800000000000000fca81100010000000000000000000000cb3a11000f0000000000000004a91100010000000000000000000000e1af120011000000000000000ca91100010000000000000000000000b83a1100130000000000000014a91100010000000000000000000000a73a110011000000000000001ca911000100000000000000000000009c3a11000b0000000000000024a91100010000000000000000000000923a11000a000000000000002ca91100010000000000000000000000853a11000d0000000000000034a911000100000000000000000000001bab12000c000000000000003ca911000100000000000000000000007b3a11000a0000000000000044a911000100000000000000000000006f3a11000c000000000000004ca911000100000000000000000000005e3a1100110000000000000054a91100010000000000000000000000533a11000b000000000000005ca91100010000000000000000000000a1af1200080000000000000064a911000100000000000000000000004b3a110008000000000000006ca911000100000000000000000000003c3a11000f0000000000000074a911000100000000000000000000002b3a110011000000000000007ca911000100000000000000000000001c3a11000f0000000000000084a91100010000000000000000000000113a11000b000000000000008ca91100010000000000000000000000083a1100090000000000000094a91100010000000000000000000000fe3911000a000000000000009ca91100010000000000000000000000f73911000700000000000000a4a91100010000000000000000000000ee3911000900000000000000aca91100010000000000000000000000e53911000900000000000000b4a91100010000000000000000000000dd3911000800000000000000bca91100010000000000000000000000d13911000c00000000000000c4a91100010000000000000000000000c03911001100000000000000cca9110001000000000000000000000027ab12000800000000000000d4a91100010000000000000000000000b73911000900000000000000dca91100010000000000000000000000a63911001100000000000000e4a91100010000000000000000000000993911000d00000000000000eca911000100000000000000000000008f3911000a00000000000000f4a911000200000000000000000000007e391100110000000000000004aa11000100000000000000000000007639110008000000000000000caa1100010000000000000035af11000e0000001daf11001800000011af11000c00000003af11000e000000ddae110026000000c7ae110016000000acae11001b00000081ae11002b00000074ae11000d0000005fae11001500000038ae11002700000028ae1100100000001cae11000c0000000eae11000e000000f7ad110017000000eaad11000d000000e0ad11000a000000d7ad110009000000c4ad110013000000a2ad11002200000091ad1100110000007cad11001500000053ad11002900000017ad11003c000000d8ac11003f0000008aac11004e00000046ac11004400000014ac110032000000e1ab110033000000beab11002300000095ab1100290000006bab11002a0000002bab11004000000002ab11002900000071aa110056000000c7aa11003b0000003aaa11003700000014aa1100260000002044656c65676174696f6e20746f206f6e6573656c66206d616b6573206e6f2073656e73652e2054686520696e7374616e74207265666572656e64756d206f726967696e2069732063757272656e746c7920646973616c6c6f7765642e20546865206163636f756e742063757272656e746c792068617320766f74657320617474616368656420746f20697420616e6420746865206f7065726174696f6e2063616e6e6f74207375636365656420756e74696c207468657365206172652072656d6f7665642c20656974686572207468726f7567682060756e766f746560206f722060726561705f766f7465602e20546865206163636f756e74206973206e6f742063757272656e746c792064656c65676174696e672e20546f6f206869676820612062616c616e6365207761732070726f7669646564207468617420746865206163636f756e742063616e6e6f74206166666f72642e20416e20756e657870656374656420696e746567657220756e646572666c6f77206f636375727265642e20416e20756e657870656374656420696e7465676572206f766572666c6f77206f636375727265642e20546865206163636f756e7420697320616c72656164792064656c65676174696e672e20546865206163746f7220686173206e6f207065726d697373696f6e20746f20636f6e647563742074686520616374696f6e2e2054686520676976656e206163636f756e7420646964206e6f7420766f7465206f6e20746865207265666572656e64756d2e20412070726f78792d64652d70616972696e672077617320617474656d7074656420746f20616e206163636f756e74207468617420776173206e6f74206163746976652e20412070726f78792d70616972696e672077617320617474656d7074656420746f20616e206163636f756e74207468617420776173206f70656e20746f20616e6f74686572206163636f756e742e20412070726f78792d70616972696e672077617320617474656d7074656420746f20616e206163636f756e74207468617420776173206e6f74206f70656e2e20546865206c6f636b206f6e20746865206163636f756e7420746f20626520756e6c6f636b656420686173206e6f742079657420657870697265642e2054686520746172676574206163636f756e7420646f6573206e6f7420686176652061206c6f636b2e204e6f2070726f706f73616c732077616974696e6720496e76616c696420707265696d61676520566f746520676976656e20666f7220696e76616c6964207265666572656e64756d20507265696d616765206e6f7420666f756e6420496d6d696e656e7420546f6f206561726c79204e6f7420696d6d696e656e7420507265696d61676520616c7265616479206e6f746564204e6f742064656c6567617465642057726f6e672070726f787920416c726561647920612070726f7879204964656e74697479206d6179206e6f74207665746f20612070726f706f73616c207477696365204e6f2065787465726e616c2070726f706f73616c20496e76616c69642068617368204e6578742065787465726e616c2070726f706f73616c206e6f742073696d706c65206d616a6f726974792050726f706f73616c207374696c6c20626c61636b6c69737465642050726f706f73616c20616c7265616479206d6164652043616e6e6f742063616e63656c207468652073616d652070726f706f73616c20747769636520556e6b6e6f776e20696e646578204e6f7420612070726f78792050726f706f73616c20646f6573206e6f742065786973742056616c756520746f6f206c6f77617373657274696f6e206661696c65643a2073656c662e686569676874203e2030617373657274696f6e206661696c65643a2073656c662e6c656e2829203e203094af110056000000a5040000520000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962616c6c6f632f636f6c6c656374696f6e732f62747265652f6e6f64652e7273000094af110056000000b60400004c0000004368617267655472616e73616374696f6e5061796d656e745072697374696e65436f6465436f646553746f72616765436f6e7472616374496e666f4f66526563656e7448696e7473506f7374496e666f3a2000000000000090b0110004000000000000000000000094b011000e000000000000000a000000f50000000300000000000000a4b011000c00000000000000010000006e6f64657375627374726174652d6e6f64650000df6acb689907609b0300000037e397fc7c91f5e40100000040fe3ad401f8959a04000000d2bc9897eed08f1502000000f78b278be53f454c02000000ed99c5acb25eedf502000000cbca25e39f14238702000000687ad44ad37f03c201000000bc9d89904f5b923f0100000068b66ba122c93fa70100000037c8bb1350a9a2a801000000ab3c0572291feb8b010000006772616e62616265696d6f6e617564690000000040787d010065cd1d00e1f505d85aae1ec0542205b0508f1f38e4750488467020d853e903603c5121d0bf760338323222a8591903402013236039cd02480ef423a82a8f0268f8d42470955c02b8dab525c05a3302d8c4962648bd1102e0b27727a855f601e8a05828e8fedf0180773929c0cacd01586d1a2af8f1be019053fb2a50d8b201d00edc2be0fca80138edbc2c48f2a001e06d9d2d80669a01c80d7e2e500f9501c0575e2f08b6900140323f30e0278d0148202031b0418a0108a3ff3120e8870120bedf32f0fb85013856c03398698401f0fda03478218301b8d87f35d8178201d8c26036183d8101b8223e37508d800188d21c38c8fc7f0168b5f93898877f01a829d139d8297f0120d6ab3ab8db7e0168ae803b389d7e0100ca9a3b68957e010000000051e211000600000000000000870000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000890000000000000000000000000000008a0000000000000000000000000000008b000000000000000000000000000000a8be110007000000000000008c000000000000000000000000000000000000000000000000000000000000008d0000000000000000000000000000008e0000000000000000000000000000008f00000000000000000000000000000090000000000000000000000000000000a9e81200040000000000000091000000000000000000000000000000000000000000000000000000000000008f00000000000000000000000200000000000000000000000000000000000000920000000000000000000000000000008f000000000000000000000000000000d1f71200090000000000000093000000000000000000000000000000000000000000000000000000000000009400000000000000000000000200000000000000000000000000000000000000950000000000000000000000000000008f00000000000000000000000000000093e812000a00000000000000960000000000000000000000000000000000000000000000000000000000000097000000000000000000000002000000000000000000000000000000000000008f00000000000000000000000000000098000000000000000000000000000000afbe1100070000000000000099000000000000000000000000000000000000000000000000000000000000009a0000000000000000000000000000009b0000000000000000000000000000008f0000000000000000000000000000008f000000000000000000000000000000b6be110008000000000000009c000000000000000000000000000000000000000000000000000000000000009d0000000000000000000000000000009e0000000000000000000000000000009f000000000000000000000000000000a0000000000000000000000000000000e3f712001200000000000000a1000000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000000000000000000000000000000a20000000000000000000000000000008f000000000000000000000000000000f7f612000700000000000000a300000000000000000000000000000000000000000000000000000000000000a4000000000000000000000000000000a5000000000000000000000000000000a6000000000000000000000000000000a7000000000000000000000000000000a3f612000700000000000000a800000000000000000000000000000000000000000000000000000000000000a9000000000000000000000000000000aa0000000000000000000000000000008f000000000000000000000000000000ab000000000000000000000000000000d9f112000900000000000000ac00000000000000000000000000000000000000000000000000000000000000ad000000000000000000000000000000ae000000000000000000000000000000af000000000000000000000000000000b0000000000000000000000000000000bebe11000700000000000000b100000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000b30000000000000000000000000000008f000000000000000000000000000000b4000000000000000000000000000000c5be11001200000000000000b500000000000000000000000000000000000000000000000000000000000000b2000000000000000000000000000000b30000000000000000000000000000008f000000000000000000000000000000b4000000000000000000000000000000d7be11000900000000000000b600000000000000000000000000000000000000000000000000000000000000b7000000000000000000000000000000b8000000000000000000000000000000b9000000000000000000000000000000ba000000000000000000000000000000e0be11001300000000000000bb00000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000bd0000000000000000000000000000008f0000000000000000000000000000008f0000000000000000000000000000003ef212000f000000020000000000000000000000000000000000000000000000000000000000000000000000be00000000000000000000000200000000000000000000000000000000000000bf000000000000000000000000000000c0000000000000000000000000000000f3be11000700000000000000c100000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000c30000000000000000000000000000008f000000000000000000000000000000c400000000000000000000000000000006f812000800000000000000c500000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000c7000000000000000000000000000000c8000000000000000000000000000000c900000000000000000000000000000071ec12000900000000000000ca00000000000000000000000000000000000000000000000000000000000000cb000000000000000000000000000000cc000000000000000000000000000000cd000000000000000000000000000000ce000000000000000000000000000000d52112000400000000000000cf00000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000d10000000000000000000000000000008f000000000000000000000000000000d200000000000000000000000000000008f412000800000000000000d300000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000d50000000000000000000000000000008f000000000000000000000000000000d60000000000000000000000000000007de81200120000000200000000000000000000000000000000000000000000000000000000000000000000008f000000000000000000000002000000000000000000000000000000000000008f0000000000000000000000000000008f00000000000000000000000000000022f412000800000000000000d7000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000d80000000000000000000000000000008f0000000000000000000000000000008f00000000000000000000000000000082b412001800000000000000d9000000000000000000000000000000000000000000000000000000000000008f000000000000000000000002000000000000000000000000000000000000008f0000000000000000000000000000008f000000000000000000000000000000fabe11000800000000000000da00000000000000000000000000000000000000000000000000000000000000db000000000000000000000000000000dc000000000000000000000000000000dd000000000000000000000000000000de000000000000000000000000000000a20d12000700000000000000df00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000e1000000000000000000000000000000e2000000000000000000000000000000e300000000000000000000000000000078d112000800000000000000e400000000000000000000000000000000000000000000000000000000000000e5000000000000000000000000000000e60000000000000000000000000000008f000000000000000000000000000000e700000000000000000000000000000002bf11000700000000000000e800000000000000000000000000000000000000000000000000000000000000e9000000000000000000000000000000ea000000000000000000000000000000eb000000000000000000000000000000ec00000000000000000000000000000009bf11000900000000000000ed000000000000000000000000000000000000000000000000000000000000008f000000000000000000000000000000ee0000000000000000000000000000008f0000000000000000000000000000008f00000000000000000000005574696c697479496e646963657342616c616e636573436f756e63696c546563686e6963616c436f6d6d6974746565456c656374696f6e73546563686e6963616c4d656d626572736869704772616e6470614964656e7469747956657374696e675363686564756c6572000000000000bcbf11001600000000000000d4bf1100010000000000000000000000dcbf11001500000000000000f4bf1100010000000000000000000000fcbf1100150000000000000014c011000100000000000000000000001cc011001a0000000000000038c0110001000000000000000000000040c01100100000000000000050c0110001000000000000000000000058c01100150000000000000070c011000100000000000000496e76616c69645363686564756c6556657273696f6e00007cc1110041000000496e76616c6964537572636861726765436c61696d00000027c1110055000000496e76616c6964536f75726365436f6e7472616374000000f0c0110037000000496e76616c696444657374696e6174696f6e436f6e74726163740000bfc0110031000000496e76616c6964546f6d6273746f6e65a7c0110018000000496e76616c6964436f6e74726163744f726967696e00000078c011002f00000020416e206f726967696e20547269654964207772697474656e20696e207468652063757272656e7420626c6f636b2e20546f6d6273746f6e657320646f6e2774206d617463682e2043616e6e6f7420726573746f726520746f206e6f6e6578697374696e67206f7220616c69766520636f6e74726163742e2043616e6e6f7420726573746f72652066726f6d206e6f6e6578697374696e67206f7220746f6d6273746f6e6520636f6e74726163742e20416e206f726967696e206d757374206265207369676e6564206f7220696e686572656e7420616e6420617578696c696172792073656e646572206f6e6c792070726f7669646564206f6e20696e686572656e742e2041206e6577207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e207468652063757272656e74206f6e652e0000000000000080c31100130000000000000006cf12000e00000000000000301a130094c311000000000000000000a4c31100040000000000000000000000c4c311001000000000000000b66c12000c00000000000000301a13001cc411000000000000000000d4c31100010000000000000000000000dcc31100110000000000000060dc12000300000000000000301a1300f0c31100000000000000000000c4110002000000000000000000000010c411000b00000000000000b66c12000c00000000000000301a13001cc4110000000000000000002cc4110001000000000000000000000034c411001100000000000000b66c12000c00000000000000301a130048c41100000000000000000058c4110007000000000000000000000090c411000f00000000000000b66c12000c00000000000000301a1300a0c411000000000000000000b0c41100020000000000000000000000c0c41100080000000000000060dc12000300000000000000301a1300c8c411000000000000000000d8c41100020000000000000000000000e8c411000c0000000000000060dc12000300000000000000301a1300f4c41100000000000000000004c5110001000000000000005369676e6564436c61696d48616e646963617000420000000000000001000000ef0000007fc8110038000000301a130000000000b7c8110043000000fac811001a000000546f6d6273746f6e654465706f7369744ac811003500000053746f7261676553697a654f6666736574000000420000000000000001000000f0000000ccc711005500000021c811002900000052656e744279746546656500420000000000000001000000680000007fc711004d00000052656e744465706f7369744f6666736574000000420000000000000001000000f100000007c611004100000048c6110016000000301a1300000000005ec611005a000000b8c61100560000000ec711005300000061c711001e00000053757263686172676552657761726400420000000000000001000000f2000000b4c5110039000000edc511001a0000004d61784465707468420000000000000001000000f30000005ac511004c000000a6c511000e0000004d617856616c756553697a65420000000000000001000000f40000000cc511004e00000020546865206d6178696d756d2073697a65206f6620612073746f726167652076616c756520696e2062797465732e204120726561736f6e61626c652064656661756c74206973203136204b69422e20546865206d6178696d756d206e657374696e67206c6576656c206f6620612063616c6c2f696e7374616e746961746520737461636b2e204120726561736f6e61626c652064656661756c742076616c7565206973203130302e205265776172642074686174206973207265636569766564206279207468652070617274792077686f736520746f75636820686173206c656420746f2072656d6f76616c206f66206120636f6e74726163742e2054686520616d6f756e74206f662066756e6473206120636f6e74726163742073686f756c64206465706f73697420696e206f7264657220746f206f66667365742074686520636f7374206f66206f6e6520627974652e204c6574277320737570706f736520746865206465706f73697420697320312c303030204255202862616c616e636520756e697473292f6279746520616e64207468652072656e7420697320312042552f627974652f6461792c207468656e206120636f6e7472616374207769746820312c3030302c3030302042552074686174207573657320312c303030206279746573206f662073746f7261676520776f756c6420706179206e6f2072656e742e20427574206966207468652062616c616e6365207265647563656420746f203530302c30303020425520616e64207468652073746f7261676520737461796564207468652073616d6520617420312c3030302c207468656e20697420776f756c6420706179203530302042552f6461792e205072696365206f6620612062797465206f662073746f7261676520706572206f6e6520626c6f636b20696e74657276616c2e2053686f756c642062652067726561746572207468616e20302e2053697a65206f66206120636f6e7472616374206174207468652074696d65206f6620696e7374616e74696174696f6e2e205468697320697320612073696d706c652077617920746f20656e73757265207468617420656d70747920636f6e747261637473206576656e7475616c6c7920676574732064656c657465642e20546865206d696e696d756d20616d6f756e7420726571756972656420746f2067656e6572617465206120746f6d6273746f6e652e204e756d626572206f6620626c6f636b2064656c617920616e2065787472696e73696320636c61696d20737572636861726765206861732e205768656e20636c61696d207375726368617267652069732063616c6c656420627920616e2065787472696e736963207468652072656e7420697320636865636b656420666f722063757272656e745f626c6f636b202d2064656c61790000000074ca110008000000000000007cca110003000000000000000000000094ca11000100000000000000000000009cca11000c0000000000000098ad1200020000000000000000000000a8ca1100010000000000000000000000b0ca1100070000000000000048121200020000000000000000000000b8ca1100060000000000000000000000e8ca11000800000000000000f0ca110005000000000000000000000018cb110009000000000000000000000060cb11000a00000000000000d4b112000100000000000000000000006ccb110001000000000000000000000074cb11000f00000000000000f012120001000000000000000000000084cb11000100000000000000000000008ccb11000a000000000000004812120002000000000000000000000098cb1100020000000000000000000000a8cb11001100000000000000bccb1100020000000000000000000000cccb110001000000000000005472616e7366657220af12000900000020af120009000000f6151200070000004bcf11005a000000496e7374616e74696174656414cf11003700000045766963746564004bce110039000000301a1300000000000ecd110009000000301a13000000000084ce110043000000c7ce11004d000000526573746f72656420af12000900000020af12000900000089b2120004000000f615120007000000a1f5120004000000dfcc11002f000000301a1300000000000ecd110009000000301a13000000000017cd11003d00000054cd11003b0000008fcd11003a000000c9cd1100460000000fce11003c000000436f646553746f7265640000b1cc11002e0000005363686564756c65557064617465640081cc11003000000044697370617463686564000016cc11004e00000064cc11001d000000436f6e7472616374457865637574696f6e00000020af120009000000cc8d120007000000d4cb11004200000020416e206576656e74206465706f73697465642075706f6e20657865637574696f6e206f66206120636f6e74726163742066726f6d20746865206163636f756e742e20412063616c6c2077617320646973706174636865642066726f6d2074686520676976656e206163636f756e742e2054686520626f6f6c207369676e616c73207768657468657220697420776173207375636365737366756c20657865637574696f6e206f72206e6f742e20547269676765726564207768656e207468652063757272656e74207363686564756c6520697320757064617465642e20436f646520776974682074686520737065636966696564206861736820686173206265656e2073746f7265642e20526573746f726174696f6e20666f72206120636f6e747261637420686173206265656e20696e697469617465642e202320506172616d73202d2060646f6e6f72603a20604163636f756e744964603a204163636f756e74204944206f662074686520726573746f72696e6720636f6e7472616374202d206064657374603a20604163636f756e744964603a204163636f756e74204944206f662074686520726573746f72656420636f6e7472616374202d2060636f64655f68617368603a206048617368603a20436f64652068617368206f662074686520726573746f72656420636f6e7472616374202d206072656e745f616c6c6f77616e63653a206042616c616e6365603a2052656e7420616c6c6f77616e6365206f662074686520726573746f72656420636f6e7472616374202d206073756363657373603a2060626f6f6c603a20547275652069662074686520726573746f726174696f6e20776173207375636365737366756c20436f6e747261637420686173206265656e206576696374656420616e64206973206e6f7720696e20746f6d6273746f6e652073746174652e202d2060636f6e7472616374603a20604163636f756e744964603a20546865206163636f756e74204944206f6620746865206576696374656420636f6e74726163742e202d2060746f6d6273746f6e65603a2060626f6f6c603a205472756520696620746865206576696374656420636f6e7472616374206c65667420626568696e64206120746f6d6273746f6e652e20436f6e7472616374206465706c6f7965642062792061646472657373206174207468652073706563696669656420616464726573732e205472616e736665722068617070656e6564206066726f6d6020746f2060746f60207769746820676976656e206076616c7565602061732070617274206f662061206063616c6c60206f722060696e7374616e7469617465602e0000000000000084d011000f0000000000000094d01100010000000000000000000000acd01100030000000000000000000000c4d01100080000000000000040ea1100010000000000000000000000ccd01100020000000000000000000000fbea12000400000000000000dcd011000400000000000000000000003cd1110007000000000000000000000074d111000b0000000000000080d11100040000000000000000000000e0d111000a000000000000000000000030d211000f0000000000000040d2110002000000000000000000000070d2110005000000000000007570646174655f7363686564756c650000000000a8d811000800000000000000b0d811000800000038d811002d000000301a13000000000065d81100430000007075745f636f6465acd711005700000003d811003500000000000000b2d311000400000000000000f32012002300000000000000aa4d12000500000000000000807512001500000000000000ead511000900000000000000f3d511000c0000000000000013d611000400000000000000cc8d12000700000017d6110042000000301a13000000000059d611004a000000a3d611002c000000cfd611004600000015d711005200000067d7110045000000696e7374616e74696174650000000000e1d511000900000000000000807512001500000000000000ead511000900000000000000f3d511000c00000000000000ffd51100090000000000000008d611000b0000000000000013d611000400000000000000cc8d120007000000c0d311006f000000301a1300000000002fd4110026000000301a13000000000055d4110050000000a5d4110041000000e6d411005b00000041d511005700000098d511002a000000c2d511001f000000636c61696d5f7375726368617267650000000000b2d3110004000000000000007ac312000c00000000000000b6d311000a00000000000000dddb12001400000098d211005c000000f4d2110045000000301a13000000000039d311004e00000087d311002b00000020416c6c6f777320626c6f636b2070726f64756365727320746f20636c61696d206120736d616c6c2072657761726420666f72206576696374696e67206120636f6e74726163742e204966206120626c6f636b2070726f6475636572206661696c7320746f20646f20736f2c206120726567756c61722075736572732077696c6c20626520616c6c6f77656420746f20636c61696d20746865207265776172642e20496620636f6e7472616374206973206e6f742065766963746564206173206120726573756c74206f6620746869732063616c6c2c206e6f20616374696f6e73206172652074616b656e20616e64207468652073656e646572206973206e6f7420656c696769626c6520666f7220746865207265776172642e646573746175785f73656e64657220496e7374616e7469617465732061206e657720636f6e74726163742066726f6d207468652060636f646568617368602067656e65726174656420627920607075745f636f6465602c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e20496e7374616e74696174696f6e20697320657865637574656420617320666f6c6c6f77733a202d205468652064657374696e6174696f6e206164647265737320697320636f6d7075746564206261736564206f6e207468652073656e64657220616e642068617368206f662074686520636f64652e202d2054686520736d6172742d636f6e7472616374206163636f756e7420697320637265617465642061742074686520636f6d707574656420616464726573732e202d20546865206063746f725f636f64656020697320657865637574656420696e2074686520636f6e74657874206f6620746865206e65776c792d63726561746564206163636f756e742e204275666665722072657475726e656420202061667465722074686520657865637574696f6e206973207361766564206173207468652060636f646560206f6620746865206163636f756e742e205468617420636f64652077696c6c20626520696e766f6b656420202075706f6e20616e792063616c6c2072656365697665642062792074686973206163636f756e742e202d2054686520636f6e747261637420697320696e697469616c697a65642e656e646f776d656e746761735f6c696d6974436f6d706163743c4761733e636f64655f68617368436f6465486173683c543e64617461204d616b657320612063616c6c20746f20616e206163636f756e742c206f7074696f6e616c6c79207472616e7366657272696e6720736f6d652062616c616e63652e202a20496620746865206163636f756e74206973206120736d6172742d636f6e7472616374206163636f756e742c20746865206173736f63696174656420636f64652077696c6c20626520657865637574656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e202a20496620746865206163636f756e74206973206120726567756c6172206163636f756e742c20616e792076616c75652077696c6c206265207472616e736665727265642e202a204966206e6f206163636f756e742065786973747320616e64207468652063616c6c2076616c7565206973206e6f74206c657373207468616e20606578697374656e7469616c5f6465706f736974602c206120726567756c6172206163636f756e742077696c6c206265206372656174656420616e6420616e792076616c75652077696c6c206265207472616e736665727265642e2053746f7265732074686520676976656e2062696e617279205761736d20636f646520696e746f2074686520636861696e27732073746f7261676520616e642072657475726e73206974732060636f646568617368602e20596f752063616e20696e7374616e746961746520636f6e747261637473206f6e6c7920776974682073746f72656420636f64652e205570646174657320746865207363686564756c6520666f72206d65746572696e6720636f6e7472616374732e20546865207363686564756c65206d7573742068617665206120677265617465722076657273696f6e207468616e207468652073746f726564207363686564756c652e7363686564756c655363686564756c650000000062ec12000f0000000000000000000000b0d811000800000000000000000000000000000000000000000000000000000000000000301a130070da1100000000000000000080da11000100000000000000010000000000000014b011000c000000010600000000000008d611000b00000000000000cc8d12000700000000000000000000000000000000000000301a130088da1100000000000000000098da11000100000000000000000000000000000020b011000b000000010600000000000008d611000b00000000000000a0da11001600000000000000000000000000000000000000301a1300e8da11000000000000000000b8da1100010000000000000000000000000000007aec12000e000000000000000000000010f111000300000000000000000000000000000000000000000000000000000000000000301a1300c0da11000000000000000000d0da1100010000000000000001000000000000002bb011000e00000001050000000000007ac312000c00000000000000d8da11000f00000000000000000000000000000000000000301a1300e8da11000000000000000000f8da1100010000000000000000000000420000000000000001000000f5000000f1db110025000000420000000000000001000000f600000098db1100590000007761736d3a3a5072656661625761736d4d6f64756c6500003fdb1100590000004200000000000000010000006e0000002adb110015000000436f6e7472616374496e666f3c543e004200000000000000010000005b00000000db11002a0000002054686520636f6465206173736f6369617465642077697468206120676976656e206163636f756e742e20546865207375627472696520636f756e7465722e2041206d617070696e67206265747765656e20616e206f726967696e616c20636f6465206861736820616e6420696e737472756d656e746564207761736d20636f64652c20726561647920666f7220657865637574696f6e2e2041206d617070696e672066726f6d20616e206f726967696e616c20636f6465206861736820746f20746865206f726967696e616c20636f64652c20756e746f756368656420627920696e737472756d656e746174696f6e2e2043757272656e7420636f7374207363686564756c6520666f7220636f6e7472616374732e00000000000050dc11000e0000000000000060dc110001000000000000000000000068dc1100070000000000000070dc11000100000000000000416c72656164795570646174656400009cdc11003200000042616448696e740078dc1100240000002046696e616c697a6564206865696768742061626f766520626c6f636b206e756d6265722046696e616c2068696e74206d7573742062652075706461746564206f6e6c79206f6e636520696e2074686520626c6f636b00000000000040dd11000a0000000000000006cf12000e00000000000000301a13004cdd110000000000000000005cdd110001000000000000000000000064dd11000d0000000000000006cf12000e00000000000000301a130074dd1100000000000000000084dd1100010000000000000057696e646f7753697a650000420000000000000001000000f7000000d3dd1100460000005265706f72744c6174656e6379000000420000000000000001000000f80000008cdd110047000000205468652064656c617920616674657220776869636820706f696e74207468696e6773206265636f6d6520737573706963696f75732e2044656661756c7420697320313030302e20546865206e756d626572206f6620726563656e742073616d706c657320746f206b6565702066726f6d207468697320636861696e2e2044656661756c74206973203130312e0000000000000048de11000a0000000000000054de11000100000000000000000000006cde1100020000000000000066696e616c5f68696e74000000000000d4de11000400000000000000d8de1100170000007cde11003d000000b9de11001b0000002048696e7420746861742074686520617574686f72206f66207468697320626c6f636b207468696e6b732074686520626573742066696e616c697a656420626c6f636b2069732074686520676976656e206e756d6265722e68696e74436f6d706163743c543a3a426c6f636b4e756d6265723e000000000028df11001200000000000000b66c12000c00000000000000301a13003cdf110000000000000000004cdf110001000000000000005472616e73616374696f6e427974654665650000420000000000000001000000f900000054df110043000000205468652066656520746f206265207061696420666f72206d616b696e672061207472616e73616374696f6e3b20746865207065722d6279746520706f7274696f6e2e0000000000f5f71200110000000000000000000000f0df11000a00000000000000000000000000000000000000000000000000000000000000301a1300fcdf11000000000000000000301a13000000000000000000010000004d756c7469706c69657200004200000000000000010000005f0000005570646174654f72646572656448696e74734d656469616e616c77617973206174206c65617374206f6e6520726563656e742073616d706c653b20716564000020e111003c0000006f0000002b000000726563656e7420616e64206f72646572656420636f6e7461696e207468652073616d65206974656d733b2071656400004200000004000000040000000d00000020e111003c0000007a0000001b0000007072756e696e672064696374617465642062792077696e646f775f73697a6520776869636820697320616c776179732073617475726174656420617420313b207165640020e111003c000000950000001100000020e111003c0000008f0000001900000020e111003c00000090000000190000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f66696e616c6974792d747261636b65722f7372632f6c69622e72734e6f6e5a65726f526566436f756e744e6f6e44656661756c74436f6d706f736974654661696c6564546f4578747261637452756e74696d6556657273696f6e5370656356657273696f6e4e65656473546f496e637265617365496e76616c6964537065634e616d653a65787472696e7369635f696e64657866696c6c5f626c6f636b72656d61726b7365745f686561705f70616765737365745f636f64657365745f636f64655f776974686f75745f636865636b737365745f6368616e6765735f747269655f636f6e6669677365745f73746f726167656b696c6c5f73746f726167656b696c6c5f7072656669787375696369646553797374656d4163636f756e74426c6f636b486173684e756d626572506172656e744861736845787472696e73696373526f6f74446967657374000000000068e31100100000000000000078e3110001000000000000000000000080e3110001000000000000000000000088e311000f0000000000000098e31100020000000000000000000000a8e31100010000000000000000000000b0e311000b00000000000000301a1300000000000000000000000000bce31100010000000000000000000000c4e311000a0000000000000074ad1200010000000000000000000000d0e31100010000000000000000000000d8e311000d0000000000000074ad1200010000000000000000000000e8e31100010000000000000045787472696e736963537563636573734ce411000c00000058e411002500000045787472696e7369634661696c656400e00e13000d0000004ce411000c00000037e4110015000000436f6465557064617465640022e41100150000004e65774163636f756e74000007e411001b0000004b696c6c65644163636f756e74000000f0e311001700000020416e206163636f756e7420776173207265617065642e2041206e6577206163636f756e742077617320637265617465642e20603a636f6465602077617320757064617465642e20416e2065787472696e736963206661696c65642e4469737061746368496e666f20416e2065787472696e73696320636f6d706c65746564207375636365737366756c6c792e6164645f6d656d62657272656d6f76655f6d656d626572737761705f6d656d62657272657365745f6d656d626572736368616e67655f6b65797365745f7072696d65636c6561725f7072696d65000000000000d4e511000b00000000000000301a1300000000000000000000000000e0e51100010000000000000000000000e8e511000d00000000000000301a1300000000000000000000000000f8e5110001000000000000000000000000e611000e00000000000000301a130000000000000000000000000010e6110001000000000000000000000018e611000c00000000000000301a130000000000000000000000000024e61100010000000000000000000000180d12000a00000000000000301a13000000000000000000000000002ce6110001000000000000000000000034e6110005000000000000003ce6110001000000000000000000000044e6110001000000000000004d656d62657241646465640071e71100390000004d656d62657252656d6f76656400000036e711003b0000004d656d62657273537761707065640000ffe61100370000004d656d626572735265736574b9e611004600000097e611002200000044756d6d7900000068e611002f0000004ce611001c000000205068616e746f6d206d656d6265722c206e6576657220757365642e73705f7374643a3a6d61726b65723a3a5068616e746f6d446174613c284163636f756e7449642c204576656e74293e204f6e65206f6620746865206d656d6265727327206b657973206368616e6765642e20546865206d656d62657273686970207761732072657365743b2073656520746865207472616e73616374696f6e20666f722077686f20746865206e6577207365742069732e2054776f206d656d62657273207765726520737761707065643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732072656d6f7665643b2073656520746865207472616e73616374696f6e20666f722077686f2e2054686520676976656e206d656d626572207761732061646465643b2073656520746865207472616e73616374696f6e20666f722077686f2e0000420000000400000004000000fa000000420000000000000001000000460000004576656e74734576656e74546f7069637300000000000000d4e111000a0000000000000098e91100010000000000000000000000b0e91100010000000000000000000000dee111000600000000000000b8e91100010000000000000000000000d0e91100050000000000000000000000e4e111000e00000000000000f8e9110001000000000000000000000010ea1100060000000000000000000000f2e11100080000000000000040ea110001000000000000000000000058ea1100080000000000000000000000fae11100170000000000000040ea110001000000000000000000000098ea110007000000000000000000000011e211001700000000000000d0ea1100010000000000000000000000e8ea110007000000000000000000000028e211000b0000000000000020eb110001000000000000000000000038eb110006000000000000000000000033e211000c0000000000000068eb110001000000000000000000000080eb11000600000000000000000000003fe211000b00000000000000b0eb1100010000000000000000000000c8eb11000600000000000000000000004ae211000700000000000000301a1300000000000000000000000000f8eb110007000000000000000000000077f1110006000000000000007df111000700000035f1110042000000000000002ef111000700000000000000cc8d12000700000013f111001b000000301a130000000000f5bd12000b000000adec11000900000044be12000c000000000000000bf11100050000000000000010f1110003000000b9f011003f000000301a130000000000f5bd12000b000000adec110009000000f8f011001300000044be12000c00000000000000b5f011000400000000000000cc8d120007000000f0ef11001a000000301a130000000000f5bd12000b0000000af011004d000000c3ef11002200000057f011005e000000e5ef11000b00000044be12000c00000058ef110047000000301a130000000000f5bd12000b0000009fef110024000000c3ef110022000000e5ef11000b00000044be12000c0000000000000025ef1100130000000000000038ef1100200000005fee110028000000301a130000000000f5bd12000b00000087ee110026000000adee11002c000000d9ee11004c00000044be12000c000000000000004dee1100050000000000000052ee11000d000000eeed11001b000000301a130000000000f5bd12000b00000009ee1100250000002eee11001f00000044be12000c00000000000000a79612000400000000000000e6ed11000800000070ed11001e000000301a130000000000f5bd12000b0000008eed11003f000000cded11001900000044be12000c000000000000006aed110006000000000000003422120003000000d5ec110045000000301a130000000000f5bd12000b0000001aed11003700000051ed11001900000044be12000c00000030ec11005900000089ec110024000000301a130000000000f5bd12000b000000adec110009000000b6ec11001f00000044be12000c000000204b696c6c207468652073656e64696e67206163636f756e742c20617373756d696e6720746865726520617265206e6f207265666572656e636573206f75747374616e64696e6720616e642074686520636f6d706f73697465206461746120697320657175616c20746f206974732064656661756c742076616c75652e202d20604f28312960202d20312073746f72616765207265616420616e642064656c6574696f6e2e204b696c6c20616c6c2073746f72616765206974656d7320776974682061206b657920746861742073746172747320776974682074686520676976656e207072656669782e202d20604f285029602077686572652060506020616d6f756e74206f66206b657973207769746820707265666978206070726566697860202d206050602073746f726167652064656c6574696f6e732e707265666978204b696c6c20736f6d65206974656d732066726f6d2073746f726167652e202d20604f28564b296020776865726520605660206c656e677468206f6620606b6579736020616e6420604b60206c656e677468206f66206f6e65206b6579202d206056602073746f726167652064656c6574696f6e732e5665633c4b65793e2053657420736f6d65206974656d73206f662073746f726167652e202d20604f2849296020776865726520604960206c656e677468206f6620606974656d7360202d206049602073746f72616765207772697465732028604f28312960292e6974656d735665633c4b657956616c75653e2053657420746865206e6577206368616e676573207472696520636f6e66696775726174696f6e2e202d20604f2844296020776865726520604460206c656e677468206f66206044696765737460202d20312073746f72616765207772697465206f722064656c6574652028636f64656320604f28312960292e202d20312063616c6c20746f20606465706f7369745f6c6f67603a20604f284429602028776869636820646570656e6473206f6e20746865206c656e677468206f66206044696765737460296368616e6765735f747269655f636f6e6669674f7074696f6e3c4368616e67657354726965436f6e66696775726174696f6e3e2053657420746865206e65772072756e74696d6520636f646520776974686f757420646f696e6720616e7920636865636b73206f662074686520676976656e2060636f6465602e202d20604f2843296020776865726520604360206c656e677468206f662060636f646560202d20312073746f726167652077726974652028636f64656320604f28432960292e202d2031206576656e742e2053657420746865206e65772072756e74696d6520636f64652e202d20604f2843202b2053296020776865726520604360206c656e677468206f662060636f64656020616e642060536020636f6d706c6578697479206f66206063616e5f7365745f636f646560202d20312063616c6c20746f206063616e5f7365745f636f6465603a20604f28532960202863616c6c73206073705f696f3a3a6d6973633a3a72756e74696d655f76657273696f6e6020776869636820697320657870656e73697665292e636f64652053657420746865206e756d626572206f6620706167657320696e2074686520576562417373656d626c7920656e7669726f6e6d656e74277320686561702e202d20312073746f726167652077726974652e7061676573753634204d616b6520736f6d65206f6e2d636861696e2072656d61726b2e5f72656d61726b204120646973706174636820746861742077696c6c2066696c6c2074686520626c6f636b2077656967687420757020746f2074686520676976656e20726174696f2e5f726174696f50657262696c6c0000000057e211000700000001020000000000007ac312000c00000000000000acf611002500000000000000000000000000000000000000301a1300d4f611000000000000000000e4f6110001000000000000000100000000000000ecf611000e000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a130048f711000000000000000000fcf611000100000000000000000000000000000004f7110013000000000000000000000017f711000600000000000000000000000000000000000000000000000000000000000000301a130020f71100000000000000000030f711000100000000000000000000000000000038f7110010000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a130048f71100000000000000000058f71100010000000000000000000000000000005ee2110009000000010500000000000006cf12000e0000000000000091d912000700000000000000000000000000000000000000301a1300a0f71100000000000000000060f711000100000000000000010000000000000068f711000d000000010500000000000060dc12000300000000000000cc8d12000700000000000000000000000000000000000000301a130078f71100000000000000000088f711000100000000000000010000000000000067e2110006000000000000000000000006cf12000e00000000000000000000000000000000000000000000000000000000000000301a13002cf81100000000000000000090f71100010000000000000001000000000000006de211000a000000000000000000000091d912000700000000000000000000000000000000000000000000000000000000000000301a1300a0f71100000000000000000098f711000100000000000000010000000000000077e211000e000000000000000000000091d912000700000000000000000000000000000000000000000000000000000000000000301a1300a0f711000000000000000000b0f711000100000000000000010000000000000085e21100060000000000000000000000b8f711000b00000000000000000000000000000000000000000000000000000000000000301a1300c4f711000000000000000000d4f7110001000000000000000100000000000000cce71100060000000000000000000000dcf711002300000000000000000000000000000000000000000000000000000000000000301a130000f81100000000000000000010f811000100000000000000010000000000000018f811000a000000000000000000000022f811000a00000000000000000000000000000000000000000000000000000000000000301a13002cf8110000000000000000003cf8110001000000000000000100000000000000d2e711000b000000010200000000000091d91200070000000000000044f811002100000000000000000000000000000000000000301a130068f81100000000000000000078f811000a000000000000000100000000000000c8f81100120000000000000000000000daf811001600000000000000000000000000000000000000000000000000000000000000301a1300f0f81100000000000000000000f911000100000000000000000000000000000008f911000e000000000000000000000016f911000500000000000000000000000000000000000000000000000000000000000000301a13001cf9110000000000000000002cf911000100000000000000000000004163636f756e74496e666f3c543a3a496e6465782c20543a3a4163636f756e74446174613e000000420000000000000001000000fb0000004afe11003a00000045787472696e736963436f756e7400001cfe11002e000000416c6c45787472696e736963735765696768745765696768740000004200000000000000010000005b000000d7fd110045000000416c6c45787472696e736963734c656e4200000000000000010000005b00000087fd11005000000061fd11002600000045787472696e736963446174610000004200000000000000010000005900000012fd11004f000000d0fc110042000000b4fc11001c000000420000000000000001000000fc0000006ffc1100450000004469676573744f663c543e004200000000000000010000005900000033fc11003c0000005665633c4576656e745265636f72643c543a3a4576656e742c20543a3a486173683e3e00420000000000000001000000590000000bfc1100280000004576656e74436f756e744576656e74496e64657842000000000000000100000057000000ddfb11002e0000005665633c28543a3a426c6f636b4e756d6265722c204576656e74496e646578293e00000042000000000000000100000059000000abf9110049000000f4f9110025000000301a13000000000019fa1100540000006dfa110051000000befa110039000000301a130000000000f7fa1100530000004afb1100530000009dfb1100400000004c61737452756e74696d65557067726164654c61737452756e74696d6555706772616465496e666f4200000000000000010000005b00000056f9110055000000457865637574696f6e50686173655068617365004200000000000000010000005b00000034f91100220000002054686520657865637574696f6e207068617365206f662074686520626c6f636b2e2053746f726573207468652060737065635f76657273696f6e6020616e642060737065635f6e616d6560206f66207768656e20746865206c6173742072756e74696d6520757067726164652068617070656e65642e204d617070696e67206265747765656e206120746f7069632028726570726573656e74656420627920543a3a486173682920616e64206120766563746f72206f6620696e6465786573206f66206576656e747320696e2074686520603c4576656e74733c543e3e60206c6973742e20416c6c20746f70696320766563746f727320686176652064657465726d696e69737469632073746f72616765206c6f636174696f6e7320646570656e64696e67206f6e2074686520746f7069632e205468697320616c6c6f7773206c696768742d636c69656e747320746f206c6576657261676520746865206368616e67657320747269652073746f7261676520747261636b696e67206d656368616e69736d20616e6420696e2063617365206f66206368616e67657320666574636820746865206c697374206f66206576656e7473206f6620696e7465726573742e205468652076616c756520686173207468652074797065206028543a3a426c6f636b4e756d6265722c204576656e74496e646578296020626563617573652069662077652075736564206f6e6c79206a7573742074686520604576656e74496e64657860207468656e20696e20636173652069662074686520746f70696320686173207468652073616d6520636f6e74656e7473206f6e20746865206e65787420626c6f636b206e6f206e6f74696669636174696f6e2077696c6c20626520747269676765726564207468757320746865206576656e74206d69676874206265206c6f73742e20546865206e756d626572206f66206576656e747320696e2074686520604576656e74733c543e60206c6973742e204576656e7473206465706f736974656420666f72207468652063757272656e7420626c6f636b2e20446967657374206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2045787472696e7369637320726f6f74206f66207468652063757272656e7420626c6f636b2c20616c736f2070617274206f662074686520626c6f636b206865616465722e2048617368206f66207468652070726576696f757320626c6f636b2e205468652063757272656e7420626c6f636b206e756d626572206265696e672070726f6365737365642e205365742062792060657865637574655f626c6f636b602e2045787472696e73696373206461746120666f72207468652063757272656e7420626c6f636b20286d61707320616e2065787472696e736963277320696e64657820746f206974732064617461292e204d6170206f6620626c6f636b206e756d6265727320746f20626c6f636b206861736865732e20546f74616c206c656e6774682028696e2062797465732920666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2077656967687420666f7220616c6c2065787472696e736963732070757420746f6765746865722c20666f72207468652063757272656e7420626c6f636b2e20546f74616c2065787472696e7369637320636f756e7420666f72207468652063757272656e7420626c6f636b2e205468652066756c6c206163636f756e7420696e666f726d6174696f6e20666f72206120706172746963756c6172206163636f756e742049442e000000009cff1100120000000000000017f711000600000000000000301a1300b0ff11000000000000000000c0ff1100010000000000000000000000c8ff11000800000000000000d0ff11000f00000000000000301a1300e0ff11000000000000000000f0ff1100010000000000000000000000f8ff1100140000000000000017f711000600000000000000301a13000c00120000000000000000001c00120001000000000000000000000024001200130000000000000017f711000600000000000000301a13003800120000000000000000004800120001000000000000000000000050001200120000000000000060dc12000300000000000000301a13006400120000000000000000007400120001000000000000004d6178696d756d426c6f636b5765696768740000420000000000000001000000fd0000009a0112001f000000446257656967687452756e74696d65446257656967687400420000000000000001000000fe0000005801120042000000426c6f636b457865637574696f6e576569676874420000000000000001000000ff000000040112005400000045787472696e736963426173655765696768740042000000000000000100000000010000a60012005e0000004d6178696d756d426c6f636b4c656e6774680000420000000000000001000000010100007c0012002a00000020546865206d6178696d756d206c656e677468206f66206120626c6f636b2028696e206279746573292e20546865206261736520776569676874206f6620616e2045787472696e73696320696e2074686520626c6f636b2c20696e646570656e64656e74206f6620746865206f662065787472696e736963206265696e672065786563757465642e20546865206261736520776569676874206f6620657865637574696e67206120626c6f636b2c20696e646570656e64656e74206f6620746865207472616e73616374696f6e7320696e2074686520626c6f636b2e2054686520776569676874206f662072756e74696d65206461746162617365206f7065726174696f6e73207468652072756e74696d652063616e20696e766f6b652e20546865206d6178696d756d20776569676874206f66206120626c6f636b2e4e6f646520697320636f6e6669677572656420746f20757365207468652073616d6520686173683b207165640000000802120032000000ce0300001c0000000802120032000000d6030000110000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f73797374656d2f7372632f6c69622e7273436865636b56657273696f6e436865636b47656e65736973436865636b457261436865636b4e6f6e6365436865636b576569676874636f6465206973206e6f7420666f756e647072697374696e6520636f6465206973206e6f7420666f756e640000000000007de411000a00000000000000d0031200010000000000000000000000e803120003000000000000000000000087e411000d00000000000000d00312000100000000000000000000000004120003000000000000000000000094e411000b0000000000000018041200020000000000000000000000480412000500000000000000000000009fe411000d000000000000007004120001000000000000000000000088041200040000000000000000000000ace411000a00000000000000a8041200010000000000000000000000c0041200050000000000000000000000b6e411000900000000000000d0031200010000000000000000000000e8041200010000000000000000000000bfe411000b00000000000000301a1300000000000000000000000000f0041200010000000000000000000000f020120003000000000000007ac312000c000000af0712001f000000301a130000000000ce0712002d0000005b07120024000000301a1300000000007f07120030000000000000005207120006000000000000007ac312000c000000000000005807120003000000000000007ac312000c000000b006120030000000301a130000000000e00612002e000000301a1300000000000e0712004400000000000000a90612000700000000000000ddce12001100000009061200560000005f0612001b000000301a1300000000007a0612002f000000000000008421120003000000000000007ac312000c0000004e05120036000000301a130000000000840512003d000000301a130000000000c1051200480000001e05120030000000f8041200260000002052656d6f766520746865207072696d65206d656d626572206966206974206578697374732e2053657420746865207072696d65206d656d6265722e204d75737420626520612063757272656e74206d656d6265722e2053776170206f7574207468652073656e64696e67206d656d62657220666f7220736f6d65206f74686572206b657920606e6577602e204d6179206f6e6c792062652063616c6c65642066726f6d20605369676e656460206f726967696e206f6620612063757272656e74206d656d6265722e205072696d65206d656d62657273686970206973207061737365642066726f6d20746865206f726967696e206163636f756e7420746f20606e6577602c20696620657874616e742e204368616e676520746865206d656d6265727368697020746f2061206e6577207365742c20646973726567617264696e6720746865206578697374696e67206d656d626572736869702e204265206e69636520616e64207061737320606d656d6265727360207072652d736f727465642e204d6179206f6e6c792062652063616c6c65642066726f6d206052657365744f726967696e60206f7220726f6f742e6d656d626572732053776170206f7574206f6e65206d656d626572206072656d6f76656020666f7220616e6f746865722060616464602e204d6179206f6e6c792062652063616c6c65642066726f6d2060537761704f726967696e60206f7220726f6f742e205072696d65206d656d62657273686970206973202a6e6f742a207061737365642066726f6d206072656d6f76656020746f2060616464602c20696620657874616e742e72656d6f76656164642052656d6f76652061206d656d626572206077686f602066726f6d20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d206052656d6f76654f726967696e60206f7220726f6f742e204164642061206d656d626572206077686f6020746f20746865207365742e204d6179206f6e6c792062652063616c6c65642066726f6d20604164644f726967696e60206f7220726f6f742e496e7374616e6365314d656d6265727368697000000000000009b51200070000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a1300c00812000000000000000000d0081200010000000000000001000000000000009caf12000500000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a1300d80812000000000000000000e80812000100000000000000000000004200000000000000010000005900000019091200320000004200000000000000010000005b000000f008120029000000205468652063757272656e74207072696d65206d656d6265722c206966206f6e65206578697374732e205468652063757272656e74206d656d626572736869702c2073746f72656420617320616e206f726465726564205665632e00301a1300000000005c091200020000003a203a6865617070616765733a636f64653a6368616e6765735f74726965000000000000b5e111000f00000000000000080a12000200000000000000000000009be111001a00000000000000180a12000200000000000000000000007ee111001d00000000000000280a12000300000000000000000000006be111001300000000000000400a12000100000000000000000000005ce111000f00000000000000480a12000100000000000000c30b120045000000ae0b1200150000005d0b120051000000ae0b120015000000de0a12003c000000301a1300000000001a0b1200430000009e0a120040000000500a12004e0000002054686572652069732061206e6f6e2d7a65726f207265666572656e636520636f756e742070726576656e74696e6720746865206163636f756e742066726f6d206265696e67207075726765642e20537569636964652063616c6c6564207768656e20746865206163636f756e7420686173206e6f6e2d64656661756c7420636f6d706f7369746520646174612e204661696c656420746f2065787472616374207468652072756e74696d652076657273696f6e2066726f6d20746865206e65772072756e74696d652e204569746865722063616c6c696e672060436f72655f76657273696f6e60206f72206465636f64696e67206052756e74696d6556657273696f6e60206661696c65642e205468652073706563696669636174696f6e2076657273696f6e206973206e6f7420616c6c6f77656420746f206465637265617365206265747765656e207468652063757272656e742072756e74696d6520616e6420746865206e65772072756e74696d652e20546865206e616d65206f662073706563696669636174696f6e20646f6573206e6f74206d61746368206265747765656e207468652063757272656e742072756e74696d65280c120036000000ac0000000d000000280c120036000000dd000000110000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f6d656d626572736869702f7372632f6c69622e7273526571756972655375646f7375646f7365745f6b65797375646f5f61730000000000000d12000500000000000000080d1200010000000000000000000000100d1200010000000000000000000000180d12000a0000000000000074ad1200010000000000000000000000240d12000100000000000000000000002c0d12000a00000000000000380d1200010000000000000000000000100d120001000000000000005375646964000000940d12000e0000007c0d1200180000004b65794368616e6765640000400d12003c0000005375646f4173446f6e650000a1f512000400000020546865207375646f6572206a757374207377697463686564206964656e746974793b20746865206f6c64206b657920697320737570706c6965642e2041207375646f206a75737420746f6f6b20706c6163652e4469737061746368526573756c74536f63696574794d61784d656d62657273566f7465734e6f74486561644e6f74466f756e6465724e6f7443616e646964617465416c726561647943616e646964617465416c7265616479426964466f756e646572486561644e6f74566f756368696e67416c7265616479566f756368696e67496e73756666696369656e74506f74416c7265616479466f756e6465644e6f5061796f75744e6f7453757370656e64656453757370656e646564416c72656164794d656d626572426164506f736974696f6e626964756e626964766f756368746970756e766f756368646566656e6465725f766f74657061796f7574666f756e64756e666f756e646a756467655f73757370656e6465645f6d656d6265726a756467655f73757370656e6465645f63616e6469646174657365745f6d61785f6d656d6265727300000000000070111200070000000000000074ad1200010000000000000000000000781112000100000000000000000000008011120003000000000000008411120002000000000000000000000094111200020000000000000000000000a41112000500000000000000ac111200030000000000000000000000c4111200020000000000000000000000d4111200090000000000000074ad1200010000000000000000000000e0111200010000000000000000000000e8111200050000000000000074ad1200010000000000000000000000f0111200010000000000000000000000f8111200070000000000000074ad1200010000000000000000000000001212000100000000000000000000000812120008000000000000001012120002000000000000000000000020121200020000000000000000000000301212001800000000000000481212000200000000000000000000005812120001000000000000000000000060121200120000000000000074ad1200010000000000000000000000741212000100000000000000000000007c1212000f0000000000000074ad12000100000000000000000000008c121200010000000000000000000000941212000a0000000000000074ad1200010000000000000000000000a0121200010000000000000000000000a81212000400000000000000ac121200030000000000000000000000c4121200010000000000000000000000cc1212000c0000000000000048121200020000000000000000000000d8121200010000000000000000000000e01212000d00000000000000f0121200010000000000000000000000f812120001000000000000000000000000131200090000000000000074ad12000100000000000000000000000c1312000100000000000000466f756e64656400641612002e0000004269640020af120009000000f615120007000000fd15120058000000551612000f000000566f75636800000020af120009000000f61512000700000020af1200090000006215120058000000ba1512003c0000004175746f556e6269640000002015120042000000556e626964000000f41412002c000000556e766f75636800b61412003e000000496e64756374656420af120009000000a81412000e00000035141200560000008b1412001d00000053757370656e6465644d656d6265724a756467656d656e7420af120009000000a1f5120004000000121412002300000043616e64696461746553757370656e6465640000f31312001f0000004d656d62657253757370656e64656400d71312001c0000004368616c6c656e6765640000ba1312001d000000566f746520af12000900000020af120009000000a1f51200040000008a13120030000000446566656e646572566f74654e1312003c0000004e65774d61784d656d6265727300000060dc1200030000002a13120024000000556e666f756e646564000000141312001600000020536f636965747920697320756e666f756e6465642e2041206e6577206d6178206d656d62657220636f756e7420686173206265656e20736574204120766f746520686173206265656e20706c6163656420666f72206120646566656e64696e67206d656d6265722028766f7465722c20766f746529204120766f746520686173206265656e20706c61636564202863616e6469646174652c20766f7465722c20766f7465292041206d656d62657220686173206265656e206368616c6c656e6765642041206d656d62657220686173206265656e2073757370656e64656420412063616e64696461746520686173206265656e2073757370656e64656420412073757370656e646564206d656d62657220686173206265656e206a756467656420412067726f7570206f662063616e646964617465732068617665206265656e20696e6475637465642e205468652062617463682773207072696d617279206973207468652066697273742076616c75652c2074686520626174636820696e2066756c6c20697320746865207365636f6e642e5665633c4163636f756e7449643e20412063616e646964617465207761732064726f70706564202862792072657175657374206f662077686f20766f756368656420666f72207468656d292e20412063616e646964617465207761732064726f70706564202862792074686569722072657175657374292e20412063616e646964617465207761732064726f70706564202864756520746f20616e20657863657373206f66206269647320696e207468652073797374656d292e2041206d656d6265727368697020626964206a7573742068617070656e656420627920766f756368696e672e2054686520676976656e206163636f756e74206973207468652063616e646964617465277320494420616e64207468656972206f6666657220697320746865207365636f6e642e2054686520766f756368696e67207061727479206973207468652074686972642e42616c616e63652041206d656d6265727368697020626964206a7573742068617070656e65642e2054686520676976656e206163636f756e74206973207468652063616e646964617465277320494420616e64207468656972206f6666657220697320746865207365636f6e642e2054686520736f636965747920697320666f756e6465642062792074686520676976656e206964656e746974792e5072656d61747572655374696c6c4f70656e4e6f7446696e646572556e6b6e6f776e546970416c72656164794b6e6f776e526561736f6e546f6f426967496e76616c696450726f706f73616c496e646578496e73756666696369656e7450726f706f7365727342616c616e636570726f706f73655f7370656e6472656a6563745f70726f706f73616c617070726f76655f70726f706f73616c7265706f72745f617765736f6d65726574726163745f7469707469705f6e6577636c6f73655f7469700000000054b11200080000000000000038191200010000000000000000000000401912000100000000000000000000004819120008000000000000005019120001000000000000000000000058191200010000000000000000000000601912000700000000000000681912000300000000000000000000008019120001000000000000000000000088191200080000000000000090191200020000000000000000000000a0191200010000000000000000000000a8191200050000000000000050191200010000000000000000000000b0191200010000000000000000000000b8191200080000000000000050191200010000000000000000000000c0191200010000000000000000000000c8191200070000000000000050191200010000000000000000000000d0191200010000000000000000000000d81912000600000000000000d4b11200010000000000000000000000e0191200010000000000000000000000e81912000a00000000000000d4b11200010000000000000000000000f4191200010000000000000000000000fc1912000900000000000000081a1200030000000000000000000000201a1200010000000000000000000000281a12000c00000000000000d4b11200010000000000000000000000341a1200010000000000000075b412000d000000f61b12000e0000005370656e64696e67f615120007000000bc1b12003a000000417761726465640075b412000d000000f61512000700000020af1200090000009c1b12002000000052656a656374656475b412000d000000f6151200070000006f1b12002d0000004275726e740000004c1b120023000000526f6c6c6f766572001b12004c0000004465706f73697400e01a1200200000004e65775469700000ba1a120026000000546970436c6f73696e670000831a120037000000546970436c6f73656400000089b212000400000020af120009000000f615120007000000611a1200220000005469705265747261637465643c1a1200250000002041207469702073756767657374696f6e20686173206265656e207265747261637465642e2041207469702073756767657374696f6e20686173206265656e20636c6f7365642e2041207469702073756767657374696f6e206861732072656163686564207468726573686f6c6420616e6420697320636c6f73696e672e2041206e6577207469702073756767657374696f6e20686173206265656e206f70656e65642e20536f6d652066756e64732068617665206265656e206465706f73697465642e205370656e64696e67206861732066696e69736865643b20746869732069732074686520616d6f756e74207468617420726f6c6c73206f76657220756e74696c206e657874207370656e642e20536f6d65206f66206f75722066756e64732068617665206265656e206275726e742e20412070726f706f73616c207761732072656a65637465643b2066756e6473207765726520736c61736865642e20536f6d652066756e64732068617665206265656e20616c6c6f63617465642e205765206861766520656e6465642061207370656e6420706572696f6420616e642077696c6c206e6f7720616c6c6f636174652066756e64732e204e65772070726f706f73616c2e496e636f6e73697374656e74207374617465202d20636f756c646e277420736574746c6520696d62616c616e636520666f722066756e6473207370656e74206279207472656173757279506f74736f63696574795f726f746174696f6e43616e646964617465730000000000617474656d707420746f20646976696465206279207a65726f000000941d120033000000390600001d000000941d1200330000008d0400000f0000007061796f757473652e31206f662066696e616c206974656d203d3d20746f74616c5f617070726f76616c733b20776f72737420636173652066696e642077696c6c20616c776179732072657475726e2074686174206974656d3b207165640000941d120033000000840500001f00000042696473657869746564206966206d656d6265727320656d7074793b20716564941d120033000000a30500001f000000446566656e646572446566656e646572566f746573736f63696574795f6368616c6c656e67650000941d1200330000001a06000033000000941d1200330000001a0600001e0000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f736f63696574792f7372632f6c69622e7273537472696b657353757370656e6465644d656d626572730000941d120033000000c60500001e0000005061796f757473000000000000000000617474656d707420746f2063616c63756c617465207468652072656d61696e646572207769746820612064697669736f72206f66207a65726f000000941d120033000000940400000500000000000000690c12000400000000000000d01e1200010000000000000000000000e81e12000a00000000000000000000006d0c12000700000000000000381f1200010000000000000000000000501f1200090000000000000000000000740c12000700000000000000981f1200020000000000000000000000c81f12000b0000000000000000000000fbea1200040000000000000061d1120017000000872112004e000000301a13000000000098c9120034000000301a130000000000f5bd12000b00000085201200080000008d20120019000000a620120018000000be2012003200000044be12000c00000000000000842112000300000000000000f320120023000000162112005d000000301a13000000000098c9120034000000301a130000000000f5bd12000b00000085201200080000008d20120019000000732112001100000044be12000c00000000000000f02012000300000000000000f32012002300000000000000fbea1200040000000000000061d112001700000020201200540000007420120011000000301a13000000000098c9120034000000301a130000000000f5bd12000b00000085201200080000008d20120019000000a620120018000000be2012003200000044be12000c0000002041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c207769746820605369676e656460206f726967696e2066726f6d206120676976656e206163636f756e742e202d204f2831292e202d204c696d697465642073746f726167652072656164732e202d204f6e6520444220777269746520286576656e74292e202d20576569676874206f662064657269766174697665206063616c6c6020657865637574696f6e202b2031302c3030302e77686f3c543a3a4c6f6f6b7570206173205374617469634c6f6f6b75703e3a3a536f757263652041757468656e74696361746573207468652063757272656e74207375646f206b657920616e6420736574732074686520676976656e204163636f756e7449642028606e6577602920617320746865206e6577207375646f206b65792e202d204f6e65204442206368616e67652e6e65772041757468656e7469636174657320746865207375646f206b657920616e64206469737061746368657320612066756e6374696f6e2063616c6c20776974682060526f6f7460206f726967696e2e5375646f00000000000000342212000300000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a1300382212000000000000000000482212000100000000000000010000004b6579004200000000000000010000000201000050221200210000002054686520604163636f756e74496460206f6620746865207375646f206b65792e000000b4a21200390000009d0100001e000000b4a2120039000000fb01000029000000a422120048000000bb0100002d0000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f6f70732f61726974682e7273766563746f72207769746820706f736974697665206c656e6774682077696c6c20686176652061206d61783b20716564b4a2120039000000c5020000190000006974657261746f72207769746820706f736974697665206c656e6774682077696c6c20686176652061206d696e3b207165640000b4a2120039000000c902000019000000b4a2120039000000f40200001600000000000000660e1200030000000000000090251200010000000000000000000000a8251200210000000000000000000000690e12000500000000000000b0261200010000000000000000000000c82612001300000000000000000000006e0e1200050000000000000060271200030000000000000000000000a82712002c0000000000000000000000760e12000700000000000000b02612000100000000000000000000000829120011000000000000000000000014b01200040000000000000090291200020000000000000000000000c02912001300000000000000000000007d0e12000d00000000000000582a1200010000000000000000000000702a12001000000000000000000000008a0e12000600000000000000301a1300000000000000000000000000f02a1200140000000000000000000000900e12000500000000000000902b1200030000000000000000000000d82b1200130000000000000000000000950e12000700000000000000301a1300000000000000000000000000702c12000d00000000000000000000009c0e12001600000000000000d82c1200020000000000000000000000082d12001b0000000000000000000000b20e12001900000000000000e02d1200020000000000000000000000102e1200280000000000000000000000cb0e12000f00000000000000502f1200010000000000000000000000682f12000e0000000000000000000000aa4d12000500000000000000af4d12000f000000f94f120038000000301a130000000000315012004e0000007f5012003c000000301a13000000000098c9120034000000301a130000000000a3bd12000c000000bb50120056000000301a130000000000f5bd12000b00000011511200550000006749120011000000ec4912003b000000274a1200380000005f4a120037000000964a12003d0000007849120032000000d34a120012000000284b120060000000884b120040000000c84b1200170000000f4c12004b0000005a4c1200310000008b4c12001e000000a94c120027000000d04c120048000000184d12000a000000665112001a0000003a4d12003f000000301a130000000000794d12003100000044be12000c00000000000000f64f1200030000000000000060dc120003000000be4d120036000000f44d120040000000344e120021000000301a130000000000554e12003f000000301a130000000000944e120041000000301a130000000000a3bd12000c000000d54e120046000000301a130000000000f5bd12000b0000001b4f12002c000000474f1200430000008a4f1200510000002bc112000d000000301a130000000000db4f12001b00000044be12000c00000000000000f020120003000000000000007ac312000c00000000000000aa4d12000500000000000000af4d12000f00000000000000730e12000300000000000000af4d12000f000000f945120051000000301a1300000000004a461200550000009f46120057000000f646120050000000301a13000000000046471200560000009c47120054000000301a1300000000007b41120041000000301a130000000000a3bd12000c000000f047120033000000234812005400000077481200190000009048120052000000e248120045000000301a130000000000f5bd12000b000000274912004000000067491200110000007849120032000000aa49120042000000ec4912003b000000274a1200380000005f4a120037000000964a12003d000000d34a120012000000e54a120043000000284b120060000000884b120040000000c84b120017000000df4b1200300000000f4c12004b0000005a4c1200310000008b4c12001e000000a94c120027000000d04c120048000000184d12000a000000224d1200180000003a4d12003f000000301a130000000000794d12003100000044be12000c000000264412004b0000007144120025000000301a130000000000964412004a000000301a130000000000a3bd12000c000000e04412004b000000301a130000000000f5bd12000b0000002b451200150000004045120042000000824512003b000000bd451200250000002bc112000d000000301a130000000000e24512001700000044be12000c000000000000001d4412000900000000000000f320120023000000000000002bda12000700000000000000a1f5120004000000d042120022000000301a1300000000007b41120041000000301a130000000000a3bd12000c000000f242120043000000bc4112003d0000003543120036000000301a130000000000f5bd12000b0000006b4312002f0000003c421200470000009a43120016000000b04312004b000000834212002f0000002bc112000d000000301a130000000000fb4312002200000044be12000c000000000000002bda12000700000000000000a1f51200040000005841120023000000301a1300000000007b41120041000000301a130000000000a3bd12000c000000bc4112003d000000f941120029000000301a130000000000f5bd12000b000000224212001a0000003c42120047000000834212002f0000002bc112000d000000301a130000000000b24212001e00000044be12000c000000603e120051000000301a130000000000b13e12005a000000301a1300000000000b3f120048000000533f12001e000000301a130000000000713f120045000000b63f120013000000301a130000000000f5bd12000b000000c93f120047000000104012004900000059401200390000009240120039000000cb40120023000000ee40120044000000301a130000000000324112002600000044be12000c00000000000000493e120007000000000000007ac312000c00000000000000503e12000b0000000000000060dc120003000000000000005b3e12000500000000000000cc8d120007000000303c120013000000301a130000000000433c12003c0000007f3c120046000000301a130000000000c53c120047000000301a130000000000a3bd12000c0000000c3d120046000000523d120045000000973d12003d000000301a130000000000f5bd12000b000000d43d1200380000000c3e12003d0000002bc112000d000000301a130000000000e83012001700000044be12000c000000203b120023000000301a130000000000433b1200570000009a3b120056000000f03b120008000000301a130000000000f5bd12000b000000f83b12001a000000123c12001e0000002bc112000d000000301a130000000000e83012001700000044be12000c00000000000000f020120003000000000000007ac312000c00000000000000193b12000700000000000000a1f5120004000000603712004b000000301a130000000000ab371200560000000138120033000000301a13000000000034381200520000008638120040000000301a130000000000d832120050000000301a130000000000a3bd12000c000000c63812002d000000f33812004d0000004039120049000000301a130000000000f5bd12000b0000008939120029000000b23912003e000000f03912005c0000004c3a12003e0000008a3a120051000000bd36120035000000db3a12001c000000093712001f000000301a130000000000f73a12002200000044be12000c00000000000000f020120003000000000000007ac312000c000000000000004e37120009000000000000005737120009000000023112004d000000301a1300000000004f31120057000000a63112001d000000301a130000000000c3311200550000001832120044000000301a1300000000005c32120057000000b332120025000000301a130000000000d832120050000000301a130000000000a3bd12000c00000028331200300000005833120031000000301a130000000000f5bd12000b000000893312003d000000c63312003c0000000234120032000000343412001000000044341200450000008934120037000000c03412003a000000fa3412002d00000027351200280000004f3512002c0000007b35120053000000ce3512000f000000dd35120037000000143612004b0000005f3612000e0000006d36120050000000bd36120035000000f236120017000000093712001f000000301a130000000000283712002600000044be12000c00000000000000ff301200030000000000000060dc120003000000d82f1200470000001f3012002d000000301a1300000000004c30120037000000301a130000000000a3bd12000c0000008330120039000000301a130000000000f5bd12000b000000bc3012002c0000002bc112000d000000301a130000000000e83012001700000044be12000c00000020416c6c6f777320726f6f74206f726967696e20746f206368616e676520746865206d6178696d756d206e756d626572206f66206d656d6265727320696e20736f63696574792e204d6178206d656d6265727368697020636f756e74206d7573742062652067726561746572207468616e20312e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652066726f6d205f524f4f545f2e202d20606d617860202d20546865206d6178696d756d206e756d626572206f66206d656d6265727320666f722074686520736f63696574792e202d204f6e652073746f7261676520777269746520746f2075706461746520746865206d61782e204f28312920546f74616c20436f6d706c65786974793a204f2831296d617820416c6c6f772073757370656e646564206a756467656d656e74206f726967696e20746f206d616b65206a756467656d656e74206f6e20612073757370656e6465642063616e6469646174652e20496620746865206a756467656d656e742069732060417070726f7665602c20776520616464207468656d20746f20736f63696574792061732061206d656d62657220776974682074686520617070726f707269617465207061796d656e7420666f72206a6f696e696e6720736f63696574792e20496620746865206a756467656d656e74206973206052656a656374602c2077652065697468657220736c61736820746865206465706f736974206f6620746865206269642c20676976696e67206974206261636b20746f2074686520736f63696574792074726561737572792c206f722077652062616e2074686520766f75636865722066726f6d20766f756368696e6720616761696e2e20496620746865206a756467656d656e7420697320605265626964602c20776520707574207468652063616e646964617465206261636b20696e207468652062696420706f6f6c20616e64206c6574207468656d20676f207468726f7567682074686520696e64756374696f6e2070726f6365737320616761696e2e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652066726f6d20746865205f53757370656e73696f6e4a756467656d656e744f726967696e5f2e202d206077686f60202d205468652073757370656e6465642063616e64696461746520746f206265206a75646765642e202d20606a756467656d656e7460202d2060417070726f7665602c206052656a656374602c206f7220605265626964602e204b65793a204220286c656e206f662062696473292c204d20286c656e206f66206d656d62657273292c2058202862616c616e636520616374696f6e29202d204f6e652073746f72616765207265616420746f20636865636b206077686f6020697320612073757370656e6465642063616e6469646174652e202d204f6e652073746f726167652072656d6f76616c206f66207468652073757370656e6465642063616e6469646174652e202d20417070726f7665204c6f67696320092d204f6e652073746f72616765207265616420746f206765742074686520617661696c61626c6520706f7420746f2070617920757365727320776974682e204f28312920092d204f6e652073746f7261676520777269746520746f207570646174652074686520617661696c61626c6520706f742e204f28312920092d204f6e652073746f72616765207265616420746f20676574207468652063757272656e7420626c6f636b206e756d6265722e204f28312920092d204f6e652073746f72616765207265616420746f2067657420616c6c206d656d626572732e204f284d2920092d20557020746f206f6e6520756e726573657276652063757272656e637920616374696f6e2e20092d20557020746f2074776f206e65772073746f726167652077726974657320746f207061796f7574732e20092d20557020746f206f6e652073746f726167652077726974652077697468204f286c6f67204d292062696e6172792073656172636820746f206164642061206d656d62657220746f20736f63696574792e202d2052656a656374204c6f67696320092d20557020746f206f6e6520726570617472696174652072657365727665642063757272656e637920616374696f6e2e204f28582920092d20557020746f206f6e652073746f7261676520777269746520746f2062616e2074686520766f756368696e67206d656d6265722066726f6d20766f756368696e6720616761696e2e202d205265626964204c6f67696320092d2053746f72616765206d75746174652077697468204f286c6f672042292062696e6172792073656172636820746f20706c616365207468652075736572206261636b20696e746f20626964732e202d20557020746f206f6e65206164646974696f6e616c206576656e7420696620756e766f7563682074616b657320706c6163652e202d204f6e652073746f726167652072656d6f76616c2e202d204f6e65206576656e7420666f7220746865206a756467656d656e742e20546f74616c20436f6d706c65786974793a204f284d202b206c6f674d202b2042202b2058296a756467656d656e744a756467656d656e7420416c6c6f772073757370656e73696f6e206a756467656d656e74206f726967696e20746f206d616b65206a756467656d656e74206f6e20612073757370656e646564206d656d6265722e20496620612073757370656e646564206d656d62657220697320666f72676976656e2c2077652073696d706c7920616464207468656d206261636b2061732061206d656d6265722c206e6f7420616666656374696e6720616e79206f6620746865206578697374696e672073746f72616765206974656d7320666f722074686174206d656d6265722e20496620612073757370656e646564206d656d6265722069732072656a65637465642c2072656d6f766520616c6c206173736f6369617465642073746f72616765206974656d732c20696e636c7564696e67207468656972207061796f7574732c20616e642072656d6f766520616e7920766f7563686564206269647320746865792063757272656e746c7920686176652e202d206077686f60202d205468652073757370656e646564206d656d62657220746f206265206a75646765642e202d2060666f726769766560202d204120626f6f6c65616e20726570726573656e74696e672077686574686572207468652073757370656e73696f6e206a756467656d656e74206f726967696e202020202020202020202020202020666f726769766573202860747275656029206f722072656a6563747320286066616c7365602920612073757370656e646564206d656d6265722e204b65793a204220286c656e206f662062696473292c204d20286c656e206f66206d656d6265727329202d204f6e652073746f72616765207265616420746f20636865636b206077686f6020697320612073757370656e646564206d656d6265722e204f283129202d20557020746f206f6e652073746f72616765207772697465204f284d292077697468204f286c6f67204d292062696e6172792073656172636820746f206164642061206d656d626572206261636b20746f20736f63696574792e202d20557020746f20332073746f726167652072656d6f76616c73204f28312920746f20636c65616e20757020612072656d6f766564206d656d6265722e202d20557020746f206f6e652073746f72616765207772697465204f2842292077697468204f2842292073656172636820746f2072656d6f766520766f7563686564206269642066726f6d20626964732e202d204f6e652073746f726167652072656d6f76616c2e204f28312920546f74616c20436f6d706c65786974793a204f284d202b206c6f674d202b204229666f726769766520416e6e756c2074686520666f756e64696e67206f662074686520736f63696574792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205369676e65642c20616e6420746865207369676e696e67206163636f756e74206d75737420626520626f7468207468652060466f756e6465726020616e6420746865206048656164602e205468697320696d706c6965732074686174206974206d6179206f6e6c7920626520646f6e65207768656e207468657265206973206f6e65206d656d6265722e202d2054776f2073746f72616765207265616473204f2831292e202d20466f75722073746f726167652072656d6f76616c73204f2831292e20466f756e642074686520736f63696574792e205468697320697320646f6e65206173206120646973637265746520616374696f6e20696e206f7264657220746f20616c6c6f7720666f7220746865206d6f64756c6520746f20626520696e636c7564656420696e746f20612072756e6e696e6720636861696e20616e642063616e206f6e6c7920626520646f6e65206f6e63652e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d7573742062652066726f6d20746865205f466f756e6465725365744f726967696e5f2e202d2060666f756e64657260202d20546865206669727374206d656d62657220616e642068656164206f6620746865206e65776c7920666f756e64656420736f63696574792e202d20606d61785f6d656d6265727360202d2054686520696e697469616c206d6178206e756d626572206f66206d656d6265727320666f722074686520736f63696574792e202d206072756c657360202d205468652072756c6573206f66207468697320736f636965747920636f6e6365726e696e67206d656d626572736869702e202d2054776f2073746f72616765206d75746174657320746f207365742060486561646020616e642060466f756e646572602e204f283129202d204f6e652073746f7261676520777269746520746f2061646420746865206669727374206d656d62657220746f20736f63696574792e204f283129666f756e6465726d61785f6d656d6265727372756c6573205472616e7366657220746865206669727374206d617475726564207061796f757420666f72207468652073656e64657220616e642072656d6f76652069742066726f6d20746865207265636f7264732e204e4f54453a20546869732065787472696e736963206e6565647320746f2062652063616c6c6564206d756c7469706c652074696d657320746f20636c61696d206d756c7469706c65206d617475726564207061796f7574732e205061796d656e743a20546865206d656d6265722077696c6c20726563656976652061207061796d656e7420657175616c20746f207468656972206669727374206d617475726564207061796f757420746f20746865697220667265652062616c616e63652e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642061206d656d6265722077697468207061796f7574732072656d61696e696e672e204b65793a204d20286c656e206f66206d656d62657273292c205020286e756d626572206f66207061796f75747320666f72206120706172746963756c6172206d656d62657229202d204f6e652073746f726167652072656164204f284d2920616e64204f286c6f67204d292073656172636820746f20636865636b207369676e65722069732061206d656d6265722e202d204f6e652073746f726167652072656164204f28502920746f2067657420616c6c207061796f75747320666f722061206d656d6265722e202d204f6e652073746f726167652072656164204f28312920746f20676574207468652063757272656e7420626c6f636b206e756d6265722e202d204f6e652063757272656e6379207472616e736665722063616c6c2e204f285829202d204f6e652073746f72616765207772697465206f722072656d6f76616c20746f2075706461746520746865206d656d6265722773207061796f7574732e204f28502920546f74616c20436f6d706c65786974793a204f284d202b206c6f674d202b2050202b2058292041732061206d656d6265722c20766f7465206f6e2074686520646566656e6465722e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642061206d656d6265722e202d2060617070726f7665603a204120626f6f6c65616e2077686963682073617973206966207468652063616e6469646174652073686f756c6420626520617070726f766564202860747275656029206f722072656a656374656420286066616c736560292e202d204b65793a204d20286c656e206f66206d656d6265727329202d204f6e652073746f726167652072656164204f284d2920616e64204f286c6f67204d292073656172636820746f20636865636b20757365722069732061206d656d6265722e202d204f6e652073746f7261676520777269746520746f2061646420766f746520746f20766f7465732e204f28312920546f74616c20436f6d706c65786974793a204f284d202b206c6f674d292041732061206d656d6265722c20766f7465206f6e20612063616e6469646174652e202d206063616e646964617465603a205468652063616e646964617465207468617420746865206d656d62657220776f756c64206c696b6520746f20626964206f6e2e2020202020202020202020202020617070726f766564202860747275656029206f722072656a656374656420286066616c736560292e204b65793a204320286c656e206f662063616e64696461746573292c204d20286c656e206f66206d656d6265727329202d204f6e65206163636f756e74206c6f6f6b75702e202d204f6e652073746f726167652072656164204f28432920616e64204f2843292073656172636820746f20636865636b2074686174207573657220697320612063616e6469646174652e20546f74616c20436f6d706c65786974793a204f284d202b206c6f674d202b20432963616e646964617465204173206120766f756368696e67206d656d6265722c20756e766f7563682061206269642e2054686973206f6e6c7920776f726b73207768696c6520766f75636865642075736572206973206f6e6c792061206269646465722028616e64206e6f7420612063616e646964617465292e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206120766f756368696e67206d656d6265722e202d2060706f73603a20506f736974696f6e20696e207468652060426964736020766563746f72206f6620746865206269642077686f2073686f756c6420626520756e766f75636865642e204b65793a204220286c656e206f66206269647329202d204f6e652073746f726167652072656164204f28312920746f20636865636b20746865207369676e6572206973206120766f756368696e67206d656d6265722e202d204f6e652073746f72616765206d757461746520746f20726574726965766520616e64207570646174652074686520626964732e204f284229202d204f6e6520766f756368696e672073746f726167652072656d6f76616c2e204f28312920546f74616c20436f6d706c65786974793a204f2842292041732061206d656d6265722c20766f75636820666f7220736f6d656f6e6520746f206a6f696e20736f636965747920627920706c6163696e67206120626964206f6e20746865697220626568616c662e205468657265206973206e6f206465706f73697420726571756972656420746f20766f75636820666f722061206e6577206269642c206275742061206d656d6265722063616e206f6e6c7920766f75636820666f72206f6e652062696420617420612074696d652e2049662074686520626964206265636f6d657320612073757370656e6465642063616e64696461746520616e6420756c74696d6174656c792072656a6563746564206279207468652073757370656e73696f6e206a756467656d656e74206f726967696e2c20746865206d656d6265722077696c6c2062652062616e6e65642066726f6d20766f756368696e6720616761696e2e204173206120766f756368696e67206d656d6265722c20796f752063616e20636c61696d206120746970206966207468652063616e6469646174652069732061636365707465642e2054686973207469702077696c6c2062652070616964206173206120706f7274696f6e206f66207468652072657761726420746865206d656d6265722077696c6c207265636569766520666f72206a6f696e696e672074686520736f63696574792e202d206077686f603a2054686520757365722077686f20796f7520776f756c64206c696b6520746f20766f75636820666f722e202d206076616c7565603a2054686520746f74616c2072657761726420746f2062652070616964206265747765656e20796f7520616e64207468652063616e6469646174652069662074686579206265636f6d652061206d656d62657220696e2074686520736f63696574792e202d2060746970603a20596f757220637574206f662074686520746f74616c206076616c756560207061796f7574207768656e207468652063616e64696461746520697320696e64756374656420696e746f2074686520736f63696574792e2054697073206c6172676572207468616e206076616c7565602077696c6c206265207361747572617465642075706f6e207061796f75742e204b65793a204220286c656e206f662062696473292c204320286c656e206f662063616e64696461746573292c204d20286c656e206f66206d656d6265727329202d2053746f726167652052656164733a20092d204f6e652073746f72616765207265616420746f20726574726965766520616c6c206d656d626572732e204f284d2920092d204f6e652073746f72616765207265616420746f20636865636b206d656d626572206973206e6f7420616c726561647920766f756368696e672e204f28312920092d204f6e652073746f72616765207265616420746f20636865636b20666f722073757370656e6465642063616e6469646174652e204f28312920092d204f6e652073746f72616765207265616420746f20636865636b20666f722073757370656e646564206d656d6265722e204f28312920092d204f6e652073746f72616765207265616420746f20726574726965766520616c6c2063757272656e7420626964732e204f28422920092d204f6e652073746f72616765207265616420746f20726574726965766520616c6c2063757272656e742063616e646964617465732e204f284329202d2053746f72616765205772697465733a20092d204f6e652073746f7261676520777269746520746f20696e7365727420766f756368696e672073746174757320746f20746865206d656d6265722e204f28312920092d204f6e652073746f72616765206d757461746520746f206164642061206e65772062696420746f2074686520766563746f72204f2842292028544f444f3a20706f737369626c65206f7074696d697a6174696f6e20772f20726561642920092d20557020746f206f6e652073746f726167652072656d6f76616c206966206269642e6c656e2829203e204d41585f4249445f434f554e542e204f283129202d204e6f7461626c6520436f6d7075746174696f6e3a20092d204f286c6f67204d292073656172636820746f20636865636b2073656e6465722069732061206d656d6265722e20092d204f2842202b2043202b206c6f67204d292073656172636820746f20636865636b2075736572206973206e6f7420616c726561647920612070617274206f6620736f63696574792e20092d204f286c6f672042292073656172636820746f20696e7365727420746865206e65772062696420736f727465642e202d2045787465726e616c204d6f64756c65204f7065726174696f6e733a20092d204f6e652062616c616e63652072657365727665206f7065726174696f6e2e204f28582920092d20557020746f206f6e652062616c616e636520756e72657365727665206f7065726174696f6e20696620626964732e6c656e2829203e204d41585f4249445f434f554e542e202d204576656e74733a20092d204f6e65206576656e7420666f7220766f7563682e20092d20557020746f206f6e65206576656e7420666f72204175746f556e626964206966206269642e6c656e2829203e204d41585f4249445f434f554e542e20546f74616c20436f6d706c65786974793a204f284d202b2042202b2043202b206c6f674d202b206c6f6742202b20582976616c756542616c616e63654f663c542c20493e2041206269646465722063616e2072656d6f76652074686569722062696420666f7220656e74727920696e746f20736f63696574792e20427920646f696e6720736f2c20746865792077696c6c20686176652074686569722063616e646964617465206465706f7369742072657475726e6564206f7220746865792077696c6c20756e766f75636820746865697220766f75636865722e205061796d656e743a2054686520626964206465706f73697420697320756e7265736572766564206966207468652075736572206d6164652061206269642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642061206269646465722e202d2060706f73603a20506f736974696f6e20696e207468652060426964736020766563746f72206f6620746865206269642077686f2077616e747320746f20756e6269642e204b65793a204220286c656e206f662062696473292c2058202862616c616e636520756e7265736572766529202d204f6e652073746f72616765207265616420616e6420777269746520746f20726574726965766520616e64207570646174652074686520626964732e204f284229202d20456974686572206f6e6520756e726573657276652062616c616e636520616374696f6e204f285829206f72206f6e6520766f756368696e672073746f726167652072656d6f76616c2e204f28312920546f74616c20436f6d706c65786974793a204f2842202b205829706f7320412075736572206f757473696465206f662074686520736f63696574792063616e206d616b6520612062696420666f7220656e7472792e205061796d656e743a206043616e6469646174654465706f736974602077696c6c20626520726573657276656420666f72206d616b696e672061206269642e2049742069732072657475726e6564207768656e2074686520626964206265636f6d65732061206d656d6265722c206f7220696620746865206269642063616c6c732060756e626964602e202d206076616c7565603a2041206f6e652074696d65207061796d656e74207468652062696420776f756c64206c696b6520746f2072656365697665207768656e206a6f696e696e672074686520736f63696574792e204b65793a204220286c656e206f662062696473292c204320286c656e206f662063616e64696461746573292c204d20286c656e206f66206d656d62657273292c2058202862616c616e636520726573657276652920092d204f6e65206576656e7420666f72206e6577206269642e00000000ef0d12000700000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a130018781200000000000000000000571200010000000000000000000000000000000857120005000000000000000000000091d912000700000000000000000000000000000000000000000000000000000000000000301a13001057120000000000000000002057120002000000000000000000000000000000611c12000a0000000000000000000000305712002700000000000000000000000000000000000000000000000000000000000000301a13001458120000000000000000005857120001000000000000000100000000000000605712001300000001050000000000007ac312000c00000000000000735712003900000000000000000000000000000000000000301a1300ac5712000000000000000000bc571200010000000000000000000000000000004e1c1200030000000000000000000000af4d12000f00000000000000000000000000000000000000000000000000000000000000301a1300c45712000000000000000000d457120001000000000000000100000000000000f60d12000400000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a1300187812000000000000000000dc5712000100000000000000000000000000000009b51200070000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a1300e45712000000000000000000f457120001000000000000000100000000000000ce1d12001000000001050000000000007ac312000c00000000000000a1f512000400000000000000000000000000000000000000301a1300fc57120000000000000000000c581200010000000000000001000000000000001c1d1200040000000000000000000000305712002700000000000000000000000000000000000000000000000000000000000000301a130014581200000000000000000024581200010000000000000001000000000000002c5812000800000001050000000000007ac312000c00000000000000345812000e00000000000000000000000000000000000000301a13004458120000000000000000005458120001000000000000000000000000000000f01d12000700000001050000000000007ac312000c000000000000005c5812002600000000000000000000000000000000000000301a13008458120000000000000000009458120001000000000000000100000000000000c71d12000700000001050000000000007ac312000c000000000000009c5812000b00000000000000000000000000000000000000301a1300587712000000000000000000a858120001000000000000000100000000000000b30d12000500000002050500000000007ac312000c000000000000007ac312000c00000000000000a81212000400000000000000301a1300c05812000000000000000000b0581200010000000000000000000000000000004c1d12000800000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a1300187812000000000000000000b858120001000000000000000000000000000000541d12000d00000001050000000000007ac312000c00000000000000a81212000400000000000000000000000000000000000000301a1300c05812000000000000000000d058120001000000000000000000000000000000a90d12000a000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a1300587712000000000000000000d8581200010000000000000001000000365c12001200000052756c65730000004200000000000000010000005b000000cd5b120054000000215c1200150000005665633c4269643c543a3a4163636f756e7449642c2042616c616e63654f663c542c20493e3e3e007f5b12004e00000053757370656e64656443616e646964617465732842616c616e63654f663c542c20493e2c204269644b696e643c543a3a4163636f756e7449642c2042616c616e63654f663c542c20493e3e294200000000000000010000005b0000005e5b1200210000004200000000000000010000005f0000000e5b120050000000d45a12003a00000042000000000000000100000059000000af5a1200250000004200000000000000010000005b000000915a12001e00000042000000000000000100000059000000575a12003a000000566f756368696e67566f756368696e6753746174757300004200000000000000010000005b0000001e5a1200390000005665633c28543a3a426c6f636b4e756d6265722c2042616c616e63654f663c542c20493e293e000042000000000000000100000059000000cb59120053000000537472696b65436f756e7400945912003700000060591200340000002f591200310000004200000000000000010000005b0000001759120018000000e05812003700000020546865206d6178206e756d626572206f66206d656d6265727320666f722074686520736f6369657479206174206f6e652074696d652e20566f74657320666f722074686520646566656e6465722e2054686520646566656e64696e67206d656d6265722063757272656e746c79206265696e67206368616c6c656e6765642e20446f75626c65206d61702066726f6d2043616e646964617465202d3e20566f746572202d3e20284d617962652920566f74652e20546865206f6e676f696e67206e756d626572206f66206c6f73696e6720766f746573206361737420627920746865206d656d6265722e2050656e64696e67207061796f7574733b206f72646572656420627920626c6f636b206e756d6265722c20776974682074686520616d6f756e7420746861742073686f756c642062652070616964206f75742e204d656d626572732063757272656e746c7920766f756368696e67206f722062616e6e65642066726f6d20766f756368696e6720616761696e205468652063757272656e7420626964732c2073746f726564206f726465726564206279207468652076616c7565206f6620746865206269642e2054686520736574206f662073757370656e646564206d656d626572732e205468652063757272656e7420736574206f66206d656d626572732c206f7264657265642e20546865206d6f7374207072696d6172792066726f6d20746865206d6f737420726563656e746c7920617070726f766564206d656d626572732e20416d6f756e74206f66206f7572206163636f756e742062616c616e63652074686174206973207370656369666963616c6c7920666f7220746865206e65787420726f756e642773206269642873292e2054686520736574206f662073757370656e6465642063616e646964617465732e205468652063757272656e7420736574206f662063616e646964617465733b206269646465727320746861742061726520617474656d7074696e6720746f206265636f6d65206d656d626572732e20412068617368206f66207468652072756c6573206f66207468697320736f636965747920636f6e6365726e696e67206d656d626572736869702e2043616e206f6e6c7920626520736574206f6e636520616e64206f6e6c792062792074686520666f756e6465722e20546865206669727374206d656d6265722e00000000d05d12001000000000000000af4d12000f00000000000000301a1300e05d12000000000000000000f05d1200010000000000000000000000f85d12001200000000000000af4d12000f00000000000000301a13000c5e120000000000000000001c5e12000200000000000000000000002c5e12000a0000000000000060dc12000300000000000000301a1300385e12000000000000000000485e1200020000000000000000000000585e12000b00000000000000af4d12000f00000000000000301a1300645e12000000000000000000745e12000100000000000000000000007c5e12000e0000000000000006cf12000e00000000000000301a13008c5e120000000000000000009c5e1200010000000000000000000000a45e12000f0000000000000006cf12000e00000000000000301a1300b45e12000000000000000000c45e1200010000000000000000000000cc5e12000800000000000000cc5e12000800000000000000301a1300d45e12000000000000000000e45e1200010000000000000043616e6469646174654465706f73697442000000000000000100000067000000c96012003f00000057726f6e6753696465446564756374696f6e000042000000000000000100000073000000446012005500000099601200300000004d6178537472696b6573000042000000000000000100000003010000c95f12005d000000266012001e000000506572696f645370656e6400420000000000000001000000040100007e5f12004b000000526f746174696f6e506572696f640000420000000000000001000000050100003a5f1200440000004368616c6c656e6765506572696f64004200000000000000010000006b000000065f1200340000004d6f64756c65496442000000000000000100000006010000ec5e12001a0000002054686520736f636965746965732773206d6f64756c6520696420546865206e756d626572206f6620626c6f636b73206265747765656e206d656d62657273686970206368616c6c656e6765732e20546865206e756d626572206f6620626c6f636b73206265747765656e2063616e6469646174652f6d656d6265727368697020726f746174696f6e20706572696f64732e2054686520616d6f756e74206f6620696e63656e7469766520706169642077697468696e206561636820706572696f642e20446f65736e277420696e636c75646520566f7465725469702e20546865206e756d626572206f662074696d65732061206d656d626572206d617920766f7465207468652077726f6e672077617920286f72206e6f7420617420616c6c2c207768656e207468657920617265206120736b657074696329206265666f72652074686579206265636f6d652073757370656e6465642e2054686520616d6f756e74206f662074686520756e70616964207265776172642074686174206765747320646564756374656420696e207468652063617365207468617420656974686572206120736b657074696320646f65736e277420766f7465206f7220736f6d656f6e6520766f74657320696e207468652077726f6e67207761792e20546865206d696e696d756d20616d6f756e74206f662061206465706f73697420726571756972656420666f7220612062696420746f206265206d6164652e00000000ff1612000d0000000000000068621200020000000000000000000000986212000900000000000000000000000c1712000f00000000000000e0621200010000000000000000000000f86212000700000000000000000000001b1712001000000000000000e0621200010000000000000000000000306312000800000000000000000000002b1712000e0000000000000070631200020000000000000000000000a0631200130000000000000000000000391712000b000000000000003864120001000000000000000000000050641200130000000000000000000000441712000700000000000000e864120003000000000000000000000030651200160000000000000000000000730e12000300000000000000e0651200020000000000000000000000106612001900000000000000000000004b171200090000000000000038641200010000000000000000000000d8661200110000000000000000000000aa4d12000500000000000000807512001500000000000000957512000b00000000000000f3201200230000006b7412004b000000b67412004d0000000375120015000000301a130000000000f5bd12000b000000e473120013000000187512002d000000457512003b00000044be12000c00000000000000607412000b000000000000009dd9120016000000a57312003f000000301a130000000000f5bd12000b000000e473120013000000f7731200340000002b7412003500000044be12000c000000d4721200570000002b7312002b000000301a130000000000f5bd12000b00000056731200140000006a731200240000008e7312001700000044be12000c00000000000000486f12000600000000000000cc8d12000700000000000000f020120003000000000000007ac312000c0000004371120057000000301a13000000000098c9120034000000301a1300000000009a71120055000000ef71120035000000301a130000000000ff6c120058000000576d1200170000006e6d12003b000000301a130000000000a96d12001e000000301a130000000000f5bd12000b000000247212003300000057721200250000007c72120031000000ad7212002700000044be12000c00000000000000a96c1200040000000000000091d91200070000004e6f120055000000301a130000000000a36f120038000000301a130000000000db6f1200540000002f701200510000008070120014000000301a130000000000be671200590000001768120058000000301a1300000000009470120024000000301a130000000000f5bd12000b000000ea95120015000000b870120037000000ef70120024000000137112003000000044be12000c00000000000000486f12000600000000000000cc8d12000700000000000000f020120003000000000000007ac312000c00000000000000ad6c12000900000000000000b66c12000c000000c26c12003d000000301a130000000000df69120055000000346a12001d000000301a130000000000ff6c120058000000576d1200170000006e6d12003b000000b76a1200540000000b6b120036000000301a130000000000a96d12001e000000301a130000000000f5bd12000b000000c76d1200550000001c6e1200300000004c6e1200420000008e6e120043000000d16e1200390000000a6f1200200000002a6f12001e00000044be12000c00000000000000a96c1200040000000000000091d912000700000000000000ad6c12000900000000000000b66c12000c000000b26912002d000000301a130000000000df69120055000000346a12001d000000301a130000000000be67120059000000516a120058000000a96a12000e000000b76a1200540000000b6b120036000000301a130000000000416b1200590000009a6b12000d000000301a130000000000f5bd12000b0000006f68120039000000a76b120045000000cf681200400000000f69120041000000301a130000000000ec6b120058000000446c120035000000796c12001d000000966c12001300000044be12000c0000006067120018000000301a13000000000098c9120034000000301a1300000000007867120046000000301a130000000000be671200590000001768120058000000301a130000000000f5bd12000b0000006f68120039000000a868120027000000cf681200400000000f69120041000000506912002b0000007b6912003700000044be12000c00000020436c6f736520616e64207061796f75742061207469702e2054686520746970206964656e74696669656420627920606861736860206d75737420686176652066696e69736865642069747320636f756e74646f776e20706572696f642e202d206068617368603a20546865206964656e74697479206f6620746865206f70656e2074697020666f722077686963682061207469702076616c7565206973206465636c617265642e205468697320697320666f726d65642020206173207468652068617368206f6620746865207475706c65206f6620746865206f726967696e616c207469702060726561736f6e6020616e64207468652062656e6566696369617279206163636f756e742049442e202d20436f6d706c65786974793a20604f285429602077686572652060546020697320746865206e756d626572206f6620746970706572732e2020206465636f64696e6720605469707065726020766563206f66206c656e677468206054602e202020605460206973206368617267656420617320757070657220626f756e6420676976656e2062792060436f6e7461696e734c656e677468426f756e64602e2020205468652061637475616c20636f737420646570656e6473206f6e2074686520696d706c656d656e746174696f6e206f662060543a3a54697070657273602e202d20446252656164733a206054697073602c206054697070657273602c20607469702066696e64657260202d2044625772697465733a2060526561736f6e73602c206054697073602c206054697070657273602c20607469702066696e64657260204465636c6172652061207469702076616c756520666f7220616e20616c72656164792d6f70656e207469702e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e6420746865207369676e696e67206163636f756e74206d7573742062652061206d656d626572206f662074686520605469707065727360207365742e2020206173207468652068617368206f6620746865207475706c65206f66207468652068617368206f6620746865206f726967696e616c207469702060726561736f6e6020616e64207468652062656e65666963696172792020206163636f756e742049442e202d20607469705f76616c7565603a2054686520616d6f756e74206f66207469702074686174207468652073656e64657220776f756c64206c696b6520746f20676976652e20546865206d656469616e2074697020202076616c7565206f662061637469766520746970706572732077696c6c20626520676976656e20746f20746865206077686f602e20456d6974732060546970436c6f73696e676020696620746865207468726573686f6c64206f66207469707065727320686173206265656e207265616368656420616e642074686520636f756e74646f776e20706572696f642068617320737461727465642e2020206465636f64696e6720605469707065726020766563206f66206c656e677468206054602c20696e736572742074697020616e6420636865636b20636c6f73696e672c20202041637475616c6c792077656967687420636f756c64206265206c6f77657220617320697420646570656e6473206f6e20686f77206d616e7920746970732061726520696e20604f70656e5469706020627574206974202020697320776569676874656420617320696620616c6d6f73742066756c6c20692e65206f66206c656e6774682060542d31602e202d20446252656164733a206054697070657273602c20605469707360202d2044625772697465733a20605469707360686173687469705f76616c756542616c616e63654f663c543e204769766520612074697020666f7220736f6d657468696e67206e65773b206e6f2066696e6465722773206665652077696c6c2062652074616b656e2e202d2060726561736f6e603a2054686520726561736f6e20666f722c206f7220746865207468696e6720746861742064657365727665732c20746865207469703b2067656e6572616c6c7920746869732077696c6c20626520202061205554462d382d656e636f6465642055524c2e202d206077686f603a20546865206163636f756e742077686963682073686f756c6420626520637265646974656420666f7220746865207469702e20456d69747320604e657754697060206966207375636365737366756c2e202d20436f6d706c65786974793a20604f2852202b2054296020776865726520605260206c656e677468206f662060726561736f6e602c2060546020697320746865206e756d626572206f6620746970706572732e2020202d20604f285429603a206465636f64696e6720605469707065726020766563206f66206c656e677468206054602020202020605460206973206368617267656420617320757070657220626f756e6420676976656e2062792060436f6e7461696e734c656e677468426f756e64602e20202020205468652061637475616c20636f737420646570656e6473206f6e2074686520696d706c656d656e746174696f6e206f662060543a3a54697070657273602e2020202d20604f285229603a2068617368696e6720616e6420656e636f64696e67206f6620726561736f6e206f66206c656e67746820605260202d20446252656164733a206054697070657273602c2060526561736f6e7360202d2044625772697465733a2060526561736f6e73602c20605469707360726561736f6e20526574726163742061207072696f72207469702d7265706f72742066726f6d20607265706f72745f617765736f6d65602c20616e642063616e63656c207468652070726f63657373206f662074697070696e672e204966207375636365737366756c2c20746865206f726967696e616c206465706f7369742077696c6c20626520756e72657365727665642e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e642074686520746970206964656e74696669656420627920606861736860206d7573742068617665206265656e207265706f7274656420627920746865207369676e696e67206163636f756e74207468726f75676820607265706f72745f617765736f6d65602028616e64206e6f74207468726f75676820607469705f6e657760292e20456d697473206054697052657472616374656460206966207375636365737366756c2e2020202d20446570656e6473206f6e20746865206c656e677468206f662060543a3a48617368602077686963682069732066697865642e202d20446252656164733a206054697073602c20606f726967696e206163636f756e7460202d2044625772697465733a2060526561736f6e73602c206054697073602c20606f726967696e206163636f756e7460205265706f727420736f6d657468696e672060726561736f6e60207468617420646573657276657320612074697020616e6420636c61696d20616e79206576656e7475616c207468652066696e6465722773206665652e205061796d656e743a20605469705265706f72744465706f73697442617365602077696c6c2062652072657365727665642066726f6d20746865206f726967696e206163636f756e742c2061732077656c6c20617320605469705265706f72744465706f736974506572427974656020666f722065616368206279746520696e2060726561736f6e602e202d20436f6d706c65786974793a20604f2852296020776865726520605260206c656e677468206f662060726561736f6e602e2020202d20656e636f64696e6720616e642068617368696e67206f662027726561736f6e27202d20446252656164733a2060526561736f6e73602c206054697073602c206077686f206163636f756e74206461746160202d2044625772697465733a206054697073602c206077686f206163636f756e7420646174616020417070726f766520612070726f706f73616c2e2041742061206c617465722074696d652c207468652070726f706f73616c2077696c6c20626520616c6c6f636174656420746f207468652062656e656669636961727920616e6420746865206f726967696e616c206465706f7369742077696c6c2062652072657475726e65642e202d20436f6d706c65786974793a204f2831292e202d20446252656164733a206050726f706f73616c73602c2060417070726f76616c7360202d20446257726974653a2060417070726f76616c73602052656a65637420612070726f706f736564207370656e642e20546865206f726967696e616c206465706f7369742077696c6c20626520736c61736865642e202d20436f6d706c65786974793a204f283129202d20446252656164733a206050726f706f73616c73602c206072656a65637465642070726f706f736572206163636f756e7460202d2044625772697465733a206050726f706f73616c73602c206072656a65637465642070726f706f736572206163636f756e746070726f706f73616c5f69642050757420666f727761726420612073756767657374696f6e20666f72207370656e64696e672e2041206465706f7369742070726f706f7274696f6e616c20746f207468652076616c756520697320726573657276656420616e6420736c6173686564206966207468652070726f706f73616c2069732072656a65637465642e2049742069732072657475726e6564206f6e6365207468652070726f706f73616c20697320617761726465642e202d20446252656164733a206050726f706f73616c436f756e74602c20606f726967696e206163636f756e7460202d2044625772697465733a206050726f706f73616c436f756e74602c206050726f706f73616c73602c20606f726967696e206163636f756e7460436f6d706163743c42616c616e63654f663c543e3e62656e6566696369617279000000000ef812000d000000000000000000000075b412000d00000000000000000000000000000000000000000000000000000000000000301a1300587712000000000000000000687712000100000000000000010000000000000000b5120009000000010500000000000075b412000d00000000000000707712002400000000000000000000000000000000000000301a1300947712000000000000000000a4771200010000000000000000000000000000001bf81200090000000000000000000000ac7712001200000000000000000000000000000000000000000000000000000000000000301a1300c07712000000000000000000d077120001000000000000000100000000000000d877120004000000010500000000000091d912000700000000000000dc7712003c00000000000000000000000000000000000000301a130018781200000000000000000028781200030000000000000000000000000000004078120007000000010600000000000091d912000700000000000000cc8d12000700000000000000000000000000000000000000301a13004878120000000000000000005878120002000000000000000000000042000000000000000100000057000000347a12002900000050726f706f73616c3c543a3a4163636f756e7449642c2042616c616e63654f663c543e3e4200000000000000010000005b000000157a12001f0000005665633c50726f706f73616c496e6465783e000042000000000000000100000059000000d77912003e000000546970734f70656e5469703c543a3a4163636f756e7449642c2042616c616e63654f663c543e2c20543a3a426c6f636b4e756d6265722c20543a3a486173683e4200000000000000010000005b0000001279120056000000687912004f000000b779120020000000526561736f6e7300420000000000000001000000f60000006878120052000000ba781200580000002053696d706c6520707265696d616765206c6f6f6b75702066726f6d2074686520726561736f6e2773206861736820746f20746865206f726967696e616c20646174612e20416761696e2c2068617320616e20696e73656375726520656e756d657261626c6520686173682073696e636520746865206b65792069732067756172616e7465656420746f2062652074686520726573756c74206f6620612073656375726520686173682e2054697073207468617420617265206e6f742079657420636f6d706c657465642e204b65796564206279207468652068617368206f66206028726561736f6e2c2077686f29602066726f6d207468652076616c75652e2054686973206861732074686520696e73656375726520656e756d657261626c6520686173682066756e6374696f6e2073696e636520746865206b657920697473656c6620697320616c72656164792067756172616e7465656420746f20626520612073656375726520686173682e2050726f706f73616c20696e646963657320746861742068617665206265656e20617070726f76656420627574206e6f742079657420617761726465642e2050726f706f73616c7320746861742068617665206265656e206d6164652e204e756d626572206f662070726f706f73616c7320746861742068617665206265656e206d6164652e00000000000000587c12000c00000000000000647c12000700000000000000301a13006c7c120000000000000000007c7c12000200000000000000000000008c7c12001300000000000000b66c12000c00000000000000301a13003c7d12000000000000000000a07c1200010000000000000000000000a87c12000b0000000000000006cf12000e00000000000000301a1300e47c12000000000000000000b47c1200010000000000000000000000bc7c12000400000000000000647c12000700000000000000301a1300c07c12000000000000000000d07c1200010000000000000000000000d87c12000c0000000000000006cf12000e00000000000000301a1300e47c12000000000000000000f47c1200010000000000000000000000fc7c12000d00000000000000097d12000700000000000000301a1300107d12000000000000000000207d1200010000000000000000000000287d12001400000000000000b66c12000c00000000000000301a13003c7d120000000000000000004c7d1200010000000000000000000000547d12001700000000000000b66c12000c00000000000000301a13006c7d120000000000000000007c7d1200010000000000000000000000cc5e12000800000000000000cc5e12000800000000000000301a1300847d12000000000000000000947d1200010000000000000050726f706f73616c426f6e645065726d696c6c0042000000000000000100000007010000ae7f120055000000038012004400000050726f706f73616c426f6e644d696e696d756d005c7f1200520000005370656e64506572696f64003a7f1200220000004275726e42000000000000000100000008010000f67e120044000000546970436f756e74646f776e42000000000000000100000009010000a57e12005100000054697046696e6465727346656550657263656e744200000000000000010000000a010000597e12004c0000005469705265706f72744465706f7369744261736542000000000000000100000068000000247e1200350000005469705265706f72744465706f736974506572427974650042000000000000000100000084000000e27d1200420000004200000000000000010000000b0100009c7d120046000000205468652074726561737572792773206d6f64756c652069642c207573656420666f72206465726976696e672069747320736f7665726569676e206163636f756e742049442e2054686520616d6f756e742068656c64206f6e206465706f7369742070657220627974652077697468696e2074686520746970207265706f727420726561736f6e2e2054686520616d6f756e742068656c64206f6e206465706f73697420666f7220706c6163696e67206120746970207265706f72742e2054686520616d6f756e74206f66207468652066696e616c2074697020776869636820676f657320746f20746865206f726967696e616c207265706f72746572206f6620746865207469702e2054686520706572696f6420666f722077686963682061207469702072656d61696e73206f70656e20616674657220697320686173206163686965766564207468726573686f6c6420746970706572732e2050657263656e74616765206f662073706172652066756e64732028696620616e7929207468617420617265206275726e7420706572207370656e6420706572696f642e20506572696f64206265747765656e2073756363657373697665207370656e64732e204d696e696d756d20616d6f756e74206f662066756e647320746861742073686f756c6420626520706c6163656420696e2061206465706f73697420666f72206d616b696e6720612070726f706f73616c2e204672616374696f6e206f6620612070726f706f73616c27732076616c756520746861742073686f756c6420626520626f6e64656420696e206f7264657220746f20706c616365207468652070726f706f73616c2e20416e2061636365707465642070726f706f73616c2067657473207468657365206261636b2e20412072656a65637465642070726f706f73616c20646f6573206e6f742e74686520636f6e74726163742065786973747320616e6420696e2074686520616c6976652073746174653b0a090974686520757064617465642062616c616e6365206d7573742062652067726561746572207468616e2073756273697374656e6365206465706f7369743b0a0909746869732066756e6374696f6e20646f65736e27742072657475726e20604e6f6e65603b0a09097165640a09090000f48012003600000074010000170000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f636f6e7472616374732f7372632f72656e742e72730000941d120033000000bd0500002b0000005c8112003400000070020000180000005c811200340000009c0200001a0000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f74726561737572792f7372632f6c69622e7273000000005e0c12000b00000000000000ac8112000100000000000000b4811200200000002053656e646572206d75737420626520746865205375646f206163636f756e74696e636f7272656374206964656e746974796e6f7420766f7563686564000000941d120033000000ac04000035000000622e6c656e2829203e20313030303b2071656400941d120033000000c80400003100000000000000e31612001c0000000000000008831200010000000000000000000000cf161200140000000000000010831200010000000000000000000000c31612000c0000000000000018831200010000000000000000000000b71612000c0000000000000020831200010000000000000000000000ad1612000a0000000000000028831200010000000000000000000000a41612000900000000000000308312000100000000000000000000009b161200090000000000000038831200010000000000000000000000921612000900000000000000408312000100000000000000a18412001f000000868412001b000000648412002200000041841200230000002884120019000000e083120048000000958312004b000000488312004d00000020546865207469702063616e6e6f7420626520636c61696d65642f636c6f73656420626563617573652069742773207374696c6c20696e2074686520636f756e74646f776e20706572696f642e20546865207469702063616e6e6f7420626520636c61696d65642f636c6f736564206265636175736520746865726520617265206e6f7420656e6f7567682074697070657273207965742e20546865206163636f756e7420617474656d7074696e6720746f20726574726163742074686520746970206973206e6f74207468652066696e646572206f6620746865207469702e2054686520746970206861736820697320756e6b6e6f776e2e20546865207469702077617320616c726561647920666f756e642f737461727465642e2054686520726561736f6e20676976656e206973206a75737420746f6f206269672e204e6f2070726f706f73616c206174207468617420696e6465782e2050726f706f73657227732062616c616e636520697320746f6f206c6f772e000000005b0e12000b00000000000000b8861200010000000000000000000000f2af12000900000000000000c08612000100000000000000000000004e0e12000d00000000000000c8861200010000000000000000000000450e12000900000000000000d0861200010000000000000000000000390e12000c00000000000000d8861200010000000000000000000000310e12000800000000000000e0861200010000000000000000000000230e12000e00000000000000e8861200010000000000000000000000140e12000f00000000000000f0861200010000000000000000000000050e12000f00000000000000f8861200010000000000000000000000fa0d12000b0000000000000000871200010000000000000000000000f60d1200040000000000000008871200010000000000000000000000ef0d1200070000000000000010871200010000000000000000000000e50d12000a0000000000000018871200010000000000000000000000d50d1200100000000000000020871200010000000000000000000000c90d12000c0000000000000028871200010000000000000000000000a90d12000a0000000000000030871200010000000000000000000000bf0d12000a0000000000000038871200010000000000000000000000b80d1200070000000000000040871200010000000000000036891200240000002089120016000000068912001a000000f388120013000000dc88120017000000c988120013000000b08812001900000089881200270000004f8812003a00000037881200180000001288120025000000f78712001b000000da8712001d000000bd8712001d000000a4871200190000008387120021000000648712001f000000488712001c000000205468652063616c6c6572206973206e6f742074686520686561642e205468652063616c6c6572206973206e6f742074686520666f756e6465722e20546f6f206d616e79206d656d6265727320696e2074686520736f63696574792e2055736572206973206e6f7420612063616e6469646174652e205573657220697320616c726561647920612063616e6469646174652e20557365722068617320616c7265616479206d6164652061206269642e2043616e6e6f742072656d6f76652074686520666f756e6465722e2043616e6e6f742072656d6f7665207468652068656164206f662074686520636861696e2e204d656d626572206973206e6f7420766f756368696e672e204d656d62657220697320616c726561647920766f756368696e67206f722062616e6e65642066726f6d20766f756368696e6720616761696e2e204e6f7420656e6f75676820696e20706f7420746f206163636570742063616e6469646174652e20536f636965747920616c726561647920666f756e6465642e204e6f7468696e6720746f207061796f75742e2055736572206973206e6f742073757370656e6465642e20557365722069732073757370656e6465642e205573657220697320616c72656164792061206d656d6265722e2055736572206973206e6f742061206d656d6265722e20416e20696e636f727265637420706f736974696f6e207761732070726f76696465642e546f6f536f6f6e4368616e676550656e64696e67526573756d654661696c656450617573654661696c65647265706f72745f6d69736265686176696f723a6772616e6470615f617574686f7269746965734e6f4b6579734475706c6963617465644b65794e6f4173736f63696174656456616c696461746f724964496e76616c696450726f6f667365745f6b65797370757267655f6b65797356616c696461746f7273666f726b2e726563656e746c792065786563757465642e4200000000000000010000000c0100000d0100000e0100000f0100001001000011010000656e74697265206e65775f7365742077617320676976656e20746f206275696c645f737570706f72745f6d61703b20656e20656e747279206d757374206265206372656174656420666f722065616368206974656d3b207165640000a48a12003e000000eb020000230000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f656c656374696f6e732d70687261676d656e2f7372632f6c69622e7273000042000000000000000100000064000000756e636c6573303066696e616c6e756d6e6f7420656e6f7567682067617320746f20706179207472616e736665722066656562616c616e636520746f6f206c6f7720746f2073656e642076616c756576616c756520746f6f206c6f7720746f20637265617465206163636f756e746272696e67732073656e6465722062656c6f77206578697374656e7469616c206465706f73697464657374696e6174696f6e2062616c616e636520746f6f206869676820746f20726563656976652076616c756550656e64696e674368616e676553746174655175657565644b6579735374616c6c6564000000420000000800000004000000120100001301000000000000000000001401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e657874466f726365644e6578744b6579730000188d12004500000075000000450000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f737570706f72742f7372632f73746f726167652f67656e657261746f722f6d61702e7273000000000000008589120012000000000000008c8d1200010000000000000000000000a48d1200010000000000000000000000c58d12000700000000000000cc8d120007000000ac8d120019000000205265706f727420736f6d65206d69736265686176696f722e5f7265706f72745665633c75383e0000000000c38b1200050000000000000000000000e48f12001b00000000000000000000000000000000000000000000000000000000000000301a13000090120000000000000000001090120001000000000000000100000000000000b68b12000d0000000000000000000000189012002300000000000000000000000000000000000000000000000000000000000000301a1300389a120000000000000000003c90120001000000000000000000000000000000f48c12000a000000000000000000000006cf12000e00000000000000000000000000000000000000000000000000000000000000301a1300ac90120000000000000000004490120001000000000000000000000000000000d28b12000700000000000000000000004c9012002000000000000000000000000000000000000000000000000000000000000000301a13006c90120000000000000000007c901200010000000000000000000000000000009cf312000c0000000000000000000000849012000500000000000000000000000000000000000000000000000000000000000000301a13008c90120000000000000000009c90120002000000000000000100000000000000b7f312000c000000010500000000000084901200050000000000000097f612000c00000000000000000000000000000000000000301a1300ac9012000000000000000000bc90120002000000000000000000000053746f72656453746174653c543a3a426c6f636b4e756d6265723e0042000000000000000100000015010000489212002400000053746f72656450656e64696e674368616e67653c543a3a426c6f636b4e756d6265723e001792120031000000e89112002f00000028543a3a426c6f636b4e756d6265722c20543a3a426c6f636b4e756d6265722942000000000000000100000085000000c49112002400000053657449640000004200000000000000010000006e0000003c9112005700000093911200310000004200000000000000010000005b000000cc90120056000000229112001a0000002041206d617070696e672066726f6d206772616e6470612073657420494420746f2074686520696e646578206f6620746865202a6d6f737420726563656e742a2073657373696f6e20666f7220776869636820697473206d656d62657273207765726520726573706f6e7369626c652e20546865206e756d626572206f66206368616e6765732028626f746820696e207465726d73206f66206b65797320616e6420756e6465726c79696e672065636f6e6f6d696320726573706f6e736962696c69746965732920696e20746865202273657422206f66204772616e6470612076616c696461746f72732066726f6d2067656e657369732e20607472756560206966207765206172652063757272656e746c79207374616c6c65642e206e65787420626c6f636b206e756d6265722077686572652077652063616e20666f7263652061206368616e67652e2050656e64696e67206368616e67653a20287369676e616c65642061742c207363686564756c6564206368616e6765292e205374617465206f66207468652063757272656e7420617574686f72697479207365742e00000000e18912000800000000000000c4921200020000000000000000000000f49212000e0000000000000000000000e98912000a00000000000000301a1300000000000000000000000000649312000c0000000000000000000000a79612000400000000000000ab9612000700000000000000b29612000500000000000000cc8d120007000000689512003a000000a295120048000000f793120031000000301a1300000000002894120035000000301a130000000000f5bd12000b000000ea951200150000008a94120056000000ff9512003c0000003b961200290000006496120021000000859612002200000044be12000c000000c493120033000000f793120031000000301a1300000000002894120035000000301a130000000000f5bd12000b0000005d9412002d0000008a94120056000000e09412003c0000001c95120029000000459512002300000044be12000c0000002052656d6f76657320616e792073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c65722e205468697320646f65736e27742074616b652065666665637420756e74696c20746865206e6578742073657373696f6e2e20546865206469737061746368206f726967696e206f6620746869732066756e6374696f6e206d757374206265207369676e65642e202d20436f6d706c65786974793a20604f2831296020696e206e756d626572206f66206b65792074797065732e20202041637475616c20636f737420646570656e6473206f6e20746865206e756d626572206f66206c656e677468206f662060543a3a4b6579733a3a6b65795f6964732829602077686963682069732066697865642e202d20446252656164733a2060543a3a56616c696461746f7249644f66602c20604e6578744b657973602c20606f726967696e206163636f756e7460202d2044625772697465733a20604e6578744b657973602c20606f726967696e206163636f756e7460202d20446257726974657320706572206b65792069643a20604b65794f776e646572602053657473207468652073657373696f6e206b6579287329206f66207468652066756e6374696f6e2063616c6c657220746f20606b657973602e20416c6c6f777320616e206163636f756e7420746f20736574206974732073657373696f6e206b6579207072696f7220746f206265636f6d696e6720612076616c696461746f722e202d20436f6d706c65786974793a20604f28312960202d20446252656164733a20606f726967696e206163636f756e74602c2060543a3a56616c696461746f7249644f66602c20604e6578744b65797360202d2044625772697465733a20606f726967696e206163636f756e74602c20604e6578744b65797360202d204462526561647320706572206b65792069643a20604b65794f776e657260202d20446257726974657320706572206b65792069643a20604b65794f776e6572606b657973543a3a4b65797370726f6f660000000000f38912000a0000000000000000000000209912001300000000000000000000000000000000000000000000000000000000000000301a13003499120000000000000000004499120001000000000000000100000000000000a5f512000c000000000000000000000097f612000c00000000000000000000000000000000000000000000000000000000000000301a13004c99120000000000000000005c99120001000000000000000100000000000000b1f512000d0000000000000000000000a1f512000400000000000000000000000000000000000000000000000000000000000000301a13006499120000000000000000007499120002000000000000000100000000000000c88b12000a0000000000000000000000849912001e00000000000000000000000000000000000000000000000000000000000000301a1300a49912000000000000000000b499120002000000000000000100000000000000bef51200120000000000000000000000c49912000800000000000000000000000000000000000000000000000000000000000000301a1300cc9912000000000000000000dc99120003000000000000000100000000000000fe8c1200080000000105000000000000f49912000e00000000000000ab9612000700000000000000000000000000000000000000301a1300049a12000000000000000000149a1200010000000000000000000000000000001c9a1200080000000105000000000000249a12001400000000000000f49912000e00000000000000000000000000000000000000301a1300389a12000000000000000000489a12000100000000000000000000005665633c543a3a56616c696461746f7249643e0042000000000000000100000059000000429c12001f00000042000000000000000100000057000000249c12001e0000004200000000000000010000005b000000ad9b12004e000000fb9b1200290000005665633c28543a3a56616c696461746f7249642c20543a3a4b657973293e000042000000000000000100000059000000269b12004f000000759b1200380000005665633c7533323e42000000000000000100000059000000b99a120020000000301a130000000000d99a12004d000000543a3a56616c696461746f72496400004200000000000000010000005b000000929a1200270000004b65794f776e6572284b65795479706549642c205665633c75383e294200000000000000010000005b000000509a12004200000020546865206f776e6572206f662061206b65792e20546865206b65792069732074686520604b657954797065496460202b2074686520656e636f646564206b65792e20546865206e6578742073657373696f6e206b65797320666f7220612076616c696461746f722e20496e6469636573206f662064697361626c65642076616c696461746f72732e205468652073657420697320636c6561726564207768656e20606f6e5f73657373696f6e5f656e64696e67602072657475726e732061206e657720736574206f66206964656e7469746965732e2054686520717565756564206b65797320666f7220746865206e6578742073657373696f6e2e205768656e20746865206e6578742073657373696f6e20626567696e732c207468657365206b6579732077696c6c206265207573656420746f2064657465726d696e65207468652076616c696461746f7227732073657373696f6e206b6579732e20547275652069662074686520756e6465726c79696e672065636f6e6f6d6963206964656e746974696573206f7220776569676874696e6720626568696e64207468652076616c696461746f727320686173206368616e67656420696e20746865207175657565642076616c696461746f72207365742e2043757272656e7420696e646578206f66207468652073657373696f6e2e205468652063757272656e7420736574206f662076616c696461746f72732e000000749c12003a00000033000000120000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f72756e74696d652f7372632f63757276652e727372656163686564206d6178696d756d2064657074682c2063616e6e6f7420696e7374616e7469617465001601000018000000040000001701000018010000190100001a0100001b0100001c010000696e73756666696369656e742072656d61696e696e672062616c616e63656e6f7420656e6f7567682067617320746f20706179206261736520696e7374616e74696174652066656572656163686564206d6178696d756d2064657074682c2063616e6e6f74206d616b6520612063616c6c6e6f7420656e6f7567682067617320746f2070617920626173652063616c6c20666565636f6e747261637420686173206265656e20657669637465646d656d6f727976616c69646174696f6e3a20696d706f727420656e74727920706f696e747320746f2061206e6f6e2d6578697374656e74207479706543616e6e6f7420696d706f727420676c6f62616c736d6f64756c6520696d706f7274732061206e6f6e2d6578697374656e742066756e6374696f6e6d6f64756c6520696d706f72747320606578745f7072696e746c6e60206275742064656275672066656174757265732064697361626c656443616e6e6f7420696d706f7274207461626c65736d6f64756c652068617320696d706f7274732066726f6d2061206e6f6e2d27656e7627206e616d6573706163654d656d6f727920696d706f7274206d757374206861766520746865206669656c64206e616d6520276d656d6f7279274d756c7469706c65206d656d6f727920696d706f72747320646566696e65644d6178696d756d206e756d626572206f662070616765732073686f756c6420626520616c77617973206465636c617265642e52657175657374656420696e697469616c206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520726571756573746564206d6178696d756d4d6178696d756d206e756d626572206f662070616765732073686f756c64206e6f74206578636565642074686520636f6e66696775726564206d6178696d756d2e00000000007a8912000b0000000000000014a012000200000000000000000000006e8912000c0000000000000024a01200020000000000000000000000618912000d0000000000000034a012000100000000000000000000005a89120007000000000000003ca0120001000000000000001da11200420000005fa112002a000000afa0120045000000f4a012002900000074a012003b00000044a01200300000002043616e6e6f74207369676e616c20666f72636564206368616e676520736f20736f6f6e206166746572206c6173742e20417474656d707420746f207369676e616c204752414e445041206368616e67652077697468206f6e6520616c72656164792070656e64696e672e20417474656d707420746f207369676e616c204752414e44504120726573756d65207768656e2074686520617574686f72697479207365742069736e2774207061757365642028656974686572206c697665206f7220616c72656164792070656e64696e6720726573756d65292e20417474656d707420746f207369676e616c204752414e445041207061757365207768656e2074686520617574686f72697479207365742069736e2774206c697665202865697468657220706175736564206f7220616c72656164792070656e64696e67207061757365292e00000000000000d58912000c00000000000000fca11200010000000000000000000000be891200170000000000000004a21200010000000000000000000000b18912000d000000000000000ca21200010000000000000000000000ab891200060000000000000014a21200010000000000000088a212001900000060a212002800000046a212001a0000001ca212002a000000204e6f206b65797320617265206173736f63696174656420776974682074686973206163636f756e742e2052656769737465726564206475706c6963617465206b65792e204e6f206173736f6369617465642076616c696461746f7220494420666f72206163636f756e742e20496e76616c6964206f776e6572736869702070726f6f662e000000b4a212003900000077010000330000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f70687261676d656e2f7372632f6c69622e72734469676573744974656d206e6f7420657175616c5468657265206973206f6e6c79206f6e6520666174616c206572726f723b20716564004200000008000000040000001d010000a2a3120036000000a0020000010000004e6f206f74686572206572726f72732061726520616363657074656420616674657220616e2068617264206572726f7221496e686572656e7420776974682073616d65206964656e74696669657220616c726561647920657869737473212f686f6d652f6461766964642f6465762f7375627374726174652f62696e2f6e6f64652f72756e74696d652f7372632f6c69622e7273417574686f724f6c64556e636c65556e636c65416c7265616479496e636c75646564546f6f48696768556e636c6547656e65736973556e636c65546f6f4d616e79556e636c6573556e636c6573416c7265616479536574496e76616c6964556e636c65506172656e747365745f756e636c6573005ca412006a000000910000000d0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e332e302f7372632f656e636f64655f617070656e642e727350726576696f7573206d617463682061726d206d61746368657320616e7974696e67206c657373207468616e20325e33303b2071656400000000000000000000000010a512003d000000736869667465642073756666696369656e74206269747320726967687420746f206c656164206f6e6c79206c656164696e67207a65726f733b2071656400000000000000000000000000000000000000556e636c657300000000000041a412000a0000000000000094a51200010000000000000000000000aca51200010000000000000000000000cda512000a00000000000000d7a512000e000000b4a51200190000002050726f76696465206120736574206f6620756e636c65732e6e65775f756e636c65735665633c543a3a4865616465723e0000000000000060a51200060000000000000000000000f0a612003a00000000000000000000000000000000000000000000000000000000000000301a13002ca7120000000000000000003ca7120001000000000000000100000000000000d8a312000600000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a130044a71200000000000000000054a71200010000000000000000000000000000009de812000c0000000000000000000000a1f512000400000000000000000000000000000000000000000000000000000000000000301a13005ca7120000000000000000006ca712000100000000000000010000005665633c556e636c65456e7472794974656d3c543a3a426c6f636b4e756d6265722c20543a3a486173682c20543a3a4163636f756e7449643e3e000042000000000000000100000059000000bca71200070000004200000000000000010000005b000000a3a71200190000004200000000000000010000005b00000074a712002f000000205768657468657220756e636c6573207765726520616c72656164792073657420696e207468697320626c6f636b2e20417574686f72206f662063757272656e7420626c6f636b2e20556e636c6573000100000001000000000000000000000000000000010000004ca8120045000000c1030000220000004ca8120045000000dd030000150000004ca8120045000000eb0300001e0000004ca8120045000000f4030000180000004ca8120045000000f5030000190000004ca8120045000000f80300001a0000004ca8120045000000fe0300000d0000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962616c6c6f632f736c6963652e7273000000000000002fa41200120000000000000058a912000100000000000000000000001fa41200100000000000000060a9120001000000000000000000000012a412000d0000000000000068a9120001000000000000000000000006a412000c0000000000000070a91200010000000000000000000000faa312000c0000000000000078a91200010000000000000000000000e6a31200140000000000000080a91200010000000000000000000000dea31200080000000000000088a91200010000000000000045aa12002300000024aa12002100000013aa120011000000fda9120016000000dda9120020000000bea912001f00000090a912002e0000002054686520756e636c652069736e277420726563656e7420656e6f75676820746f20626520696e636c756465642e2054686520756e636c6520697320616c726561647920696e636c756465642e2054686520756e636c6520697320746f6f206869676820696e20636861696e2e2054686520756e636c652069732067656e657369732e20546f6f206d616e7920756e636c65732e20556e636c657320616c72656164792073657420696e2074686520626c6f636b2e2054686520756e636c6520706172656e74206e6f7420696e2074686520636861696e2e70aa12002a000000696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64653a200000a4aa1200230000005f5f5068616e746f6d4974656d2073686f756c64206e6576657220626520757365642e496e7374616e636532436f6c6c656374697665496e7374616e636531436f6c6c656374697665000000f8aa120023000000605f5f49676e6f7265602063616e206e6576657220626520636f6e7374727563746564416c726561647950726f78794f766572666c6f775374696c6c4163746976655468726573686f6c64416c7265616479566f756368656444656c6179506572696f644e6f74467269656e644e6f7453746172746564416c726561647953746172746564416c72656164795265636f76657261626c654e6f745265636f76657261626c654e6f74536f727465644d6178467269656e64734e6f74456e6f756768467269656e64735a65726f5468726573686f6c644e6f74416c6c6f77656461735f7265636f76657265647365745f7265636f76657265646372656174655f7265636f76657279696e6974696174655f7265636f76657279766f7563685f7265636f76657279636c61696d5f7265636f76657279636c6f73655f7265636f7665727972656d6f76655f7265636f7665727963616e63656c5f7265636f76657265640000000000000064ad12000f0000000000000074ad12000100000000000000000000007cad120001000000000000000000000084ad1200110000000000000098ad1200020000000000000000000000a8ad1200010000000000000000000000b0ad12000f00000000000000c0ad1200030000000000000000000000d8ad1200010000000000000000000000e0ad12000e0000000000000098ad1200020000000000000000000000f0ad1200010000000000000000000000f8ad1200100000000000000098ad120002000000000000000000000008ae120001000000000000000000000010ae12000f0000000000000074ad120001000000000000000000000020ae120001000000000000005265636f76657279437265617465640020af1200090000006aaf1200320000005265636f76657279496e6974696174656400000020af12000900000020af12000900000029af1200410000005265636f76657279566f75636865640020af12000900000020af12000900000020af120009000000d0ae1200500000005265636f76657279436c6f736564000092ae12003e0000004163636f756e745265636f76657265645bae1200370000005265636f7665727952656d6f7665640028ae1200330000002041207265636f766572792070726f6365737320686173206265656e2072656d6f76656420666f7220616e206163636f756e74204163636f756e745f3120686173206265656e207375636365737366756c6c79207265636f7665726564206279206163636f756e745f322041207265636f766572792070726f6365737320666f72206163636f756e745f31206279206163636f756e745f3220686173206265656e20636c6f7365642041207265636f766572792070726f6365737320666f72206163636f756e745f31206279206163636f756e745f3220686173206265656e20766f756368656420666f72206279206163636f756e745f334163636f756e7449642041207265636f766572792070726f6365737320686173206265656e20696e6974696174656420666f72206163636f756e745f31206279206163636f756e745f322041207265636f766572792070726f6365737320686173206265656e2073657420757020666f7220616e206163636f756e745072696d65546f6f4561726c79416c7265616479496e697469616c697a65644475706c6963617465566f746557726f6e67496e64657850726f706f73616c4d697373696e674475706c696361746550726f706f73616c4e6f744d656d6265727365745f6d656d626572736578656375746570726f706f7365766f7465636c6f73650000000000000054b1120008000000000000005cb112000400000000000000000000007cb112000200000000000000000000008cb11200050000000000000094b11200050000000000000000000000bcb11200020000000000000000000000ccb112000800000000000000d4b11200010000000000000000000000dcb11200010000000000000000000000e4b112000b00000000000000d4b11200010000000000000000000000f0b11200010000000000000000000000f8b11200080000000000000000b2120002000000000000000000000010b2120001000000000000000000000018b212000e0000000000000000b2120002000000000000000000000028b2120001000000000000000000000030b21200060000000000000038b2120003000000000000000000000050b21200010000000000000050726f706f73656420af12000900000075b412000d00000089b21200040000008db212000b00000012b412005300000065b4120010000000566f74656400000020af12000900000089b2120004000000a1f51200040000008db212000b0000008db212000b0000008ab3120042000000ccb3120046000000417070726f76656489b212000400000059b3120031000000446973617070726f7665640024b3120035000000457865637574656489b2120004000000a1f5120004000000e3b21200410000004d656d6265724578656375746564000098b212004b000000436c6f736564000089b21200040000008db212000b0000008db212000b00000058b212003100000020412070726f706f73616c2077617320636c6f73656420616674657220697473206475726174696f6e207761732075702e486173684d656d626572436f756e7420412073696e676c65206d656d6265722064696420736f6d6520616374696f6e3b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e207761732065786563757465643b2060626f6f6c6020697320747275652069662072657475726e656420776974686f7574206572726f722e2041206d6f74696f6e20776173206e6f7420617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2077617320617070726f76656420627920746865207265717569726564207468726573686f6c642e2041206d6f74696f6e2028676976656e20686173682920686173206265656e20766f746564206f6e20627920676976656e206163636f756e742c206c656176696e6720612074616c6c79202879657320766f74657320616e64206e6f20766f74657320676976656e20726573706563746976656c7920617320604d656d626572436f756e7460292e2041206d6f74696f6e2028676976656e20686173682920686173206265656e2070726f706f7365642028627920676976656e206163636f756e742920776974682061207468726573686f6c642028676976656e20604d656d626572436f756e7460292e50726f706f73616c496e64657852616e646f6d6e657373436f6c6c656374697665466c697052616e646f6d4d6174657269616c2f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f72616e646f6d6e6573732d636f6c6c6563746976652d666c69702f7372632f6c69622e72730000a8b4120046000000540000001100000050726f706f73616c734d656d62657273566f74696e67486973746f726963616c53657373696f6e7300000000d7ab12000c00000000000000b4b61200020000000000000000000000e4b612000d0000000000000000000000e3ab12000d000000000000004cb712000200000000000000000000007cb712000d0000000000000000000000f0ab12000f00000000000000e4b712000300000000000000000000002cb812001b0000000000000000000000ffab1200110000000000000004b912000100000000000000000000001cb9120016000000000000000000000010ac12000e000000000000004cb71200020000000000000000000000ccb912001900000000000000000000001eac12000e0000000000000004b9120001000000000000000000000094ba12001400000000000000000000002cac12000e0000000000000034bb12000100000000000000000000004cbb12001400000000000000000000003aac12000f00000000000000301a1300000000000000000000000000ecbb120015000000000000000000000049ac1200100000000000000004b9120001000000000000000000000094bc12000b000000000000000000000025cb120007000000000000007ac312000c00000000000000fbea1200040000000000000061d112001700000048d0120029000000301a13000000000024bd12004500000069bd12003a000000301a130000000000a3bd12000c00000071d0120049000000bad0120040000000301a130000000000f5bd12000b000000fad01200250000001fd112004200000044be12000c0000000000000044d0120004000000000000007ac312000c0000000000000073c3120007000000000000007ac312000c00000014cf1200470000005bcf12001d000000301a13000000000078cf120032000000301a130000000000a3bd12000c000000aacf12002e000000d8cf120047000000301a130000000000f5bd12000b0000001fd012001900000038d012000c00000044be12000c00000000000000d6ce12000700000000000000ddce12001100000000000000eece12000900000000000000f7ce12000300000000000000face12000c0000000000000006cf12000e0000002ccb120057000000301a13000000000083cb12004c000000cfcb12005200000021cc12002f000000301a13000000000098c9120034000000301a130000000000a3bd12000c00000050cc12004900000099cc120035000000cecc12004c0000001acd12004700000061cd12002500000086cd12004f000000d5cd12003a000000301a130000000000f5bd12000b0000000fce12001a00000029ce12004b00000074ce12003b000000e3ca120027000000afce1200270000002bc112000d000000301a13000000000038c112001b00000044be12000c0000000000000025cb120007000000000000007ac312000c0000009fc812003b000000301a130000000000dac812004700000021c91200490000006ac912002e000000301a13000000000098c9120034000000301a130000000000a3bd12000c000000ccc912004500000011ca120040000000301a130000000000f5bd12000b00000051ca12003e0000008fca120054000000e3ca120027000000cec51200390000000acb12001b0000002bc112000d000000301a13000000000038c112001b00000044be12000c00000049c612004a00000093c612001a000000301a130000000000adc612004a000000f7c612001d000000301a130000000000a3bd12000c00000014c712003500000049c71200440000008dc7120015000000301a130000000000a2c7120049000000ebc7120009000000301a130000000000f5bd12000b00000000c512003f0000003fc512004700000086c5120048000000f4c712003b0000002fc812004700000007c61200270000002bc112000d000000301a13000000000076c812002900000044be12000c00000086c312003d000000301a130000000000c3c312004b0000000ec412004700000055c412004c000000301a130000000000a3bd12000c000000a1c412004b000000ecc4120014000000301a130000000000f5bd12000b00000000c512003f0000003fc512004700000086c5120048000000cec512003900000007c61200270000002bc112000d000000301a1300000000002ec612001b00000044be12000c0000000000000073c3120007000000000000007ac312000c00000053c112004500000098c112001a000000301a130000000000b2c1120048000000fac112003e000000301a130000000000dabf12004100000038c212003c000000301a130000000000a3bd12000c00000074c2120044000000301a130000000000f5bd12000b000000b8c2120021000000d9c212004f00000028c31200300000002bc112000d000000301a13000000000058c312001b00000044be12000c00000050be120057000000301a130000000000a7be120045000000ecbe120042000000301a1300000000002ebf12004900000077bf1200260000009dbf12003d000000301a130000000000dabf1200410000001bc0120039000000301a130000000000f5bd12000b00000054c01200180000006cc012004a000000b6c012004e00000004c11200270000002bc112000d000000301a13000000000038c112001b00000044be12000c000000ecbc120038000000301a13000000000024bd12004500000069bd12003a000000301a130000000000a3bd12000c000000afbd120046000000301a130000000000f5bd12000b00000000be12004400000044be12000c0000002043616e63656c20746865206162696c69747920746f20757365206061735f7265636f76657265646020666f7220606163636f756e74602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64207265676973746572656420746f2062652061626c6520746f206d616b652063616c6c73206f6e20626568616c66206f6620746865207265636f7665726564206163636f756e742e20506172616d65746572733a202d20606163636f756e74603a20546865207265636f7665726564206163636f756e7420796f75206172652061626c6520746f2063616c6c206f6e2d626568616c662d6f662e2023203c7765696768743e202d204f6e652073746f72616765206d75746174696f6e20746f20636865636b206163636f756e74206973207265636f7665726564206279206077686f602e204f2831292023203c2f7765696768743e2052656d6f766520746865207265636f766572792070726f6365737320666f7220796f7572206163636f756e742e205265636f7665726564206163636f756e747320617265207374696c6c2061636365737369626c652e204e4f54453a205468652075736572206d757374206d616b65207375726520746f2063616c6c2060636c6f73655f7265636f7665727960206f6e20616c6c20616374697665207265636f7665727920617474656d707473206265666f72652063616c6c696e6720746869732066756e6374696f6e20656c73652069742077696c6c206661696c2e205061796d656e743a2042792063616c6c696e6720746869732066756e6374696f6e20746865207265636f76657261626c65206163636f756e742077696c6c20756e72657365727665207468656972207265636f7665727920636f6e66696775726174696f6e206465706f7369742e202860436f6e6669674465706f7369744261736560202b2060467269656e644465706f736974466163746f7260202a20235f6f665f667269656e64732920546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206d7573742062652061207265636f76657261626c65206163636f756e742028692e652e206861732061207265636f7665727920636f6e66696775726174696f6e292e204b65793a204620286c656e206f6620667269656e647329202d204f6e652073746f72616765207265616420746f206765742074686520707265666978206974657261746f7220666f7220616374697665207265636f7665726965732e204f283129202d204f6e652073746f7261676520726561642f72656d6f766520746f2067657420746865207265636f7665727920636f6e66696775726174696f6e2e204f2831292c20436f646563204f284629202d204f6e652062616c616e63652063616c6c20746f20756e72657365727665642e204f285829202d204f6e65206576656e742e20546f74616c20436f6d706c65786974793a204f2846202b2058292041732074686520636f6e74726f6c6c6572206f662061207265636f76657261626c65206163636f756e742c20636c6f736520616e20616374697665207265636f766572792070726f6365737320666f7220796f7572206163636f756e742e205061796d656e743a2042792063616c6c696e6720746869732066756e6374696f6e2c20746865207265636f76657261626c65206163636f756e742077696c6c207265636569766520746865207265636f76657279206465706f73697420605265636f766572794465706f7369746020706c616365642062792074686520726573637565722e207265636f76657261626c65206163636f756e74207769746820616e20616374697665207265636f766572792070726f6365737320666f722069742e202d206072657363756572603a20546865206163636f756e7420747279696e6720746f207265736375652074686973207265636f76657261626c65206163636f756e742e204b65793a205620286c656e206f6620766f756368696e6720667269656e647329202d204f6e652073746f7261676520726561642f72656d6f766520746f206765742074686520616374697665207265636f766572792070726f636573732e204f2831292c20436f646563204f285629202d204f6e652062616c616e63652063616c6c20746f20726570617472696174652072657365727665642e204f28582920546f74616c20436f6d706c65786974793a204f2856202b20582972657363756572543a3a4163636f756e74496420416c6c6f772061207375636365737366756c207265736375657220746f20636c61696d207468656972207265636f7665726564206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206d7573742062652061202272657363756572222077686f20686173207375636365737366756c6c7920636f6d706c6574656420746865206163636f756e74207265636f766572792070726f636573733a20636f6c6c656374656420607468726573686f6c6460206f72206d6f726520766f75636865732c20776169746564206064656c61795f706572696f646020626c6f636b732073696e636520696e6974696174696f6e2e202d20606163636f756e74603a20546865206c6f7374206163636f756e74207468617420796f752077616e7420746f20636c61696d20686173206265656e207375636365737366756c6c792020207265636f766572656420627920796f752e204b65793a204620286c656e206f6620667269656e647320696e20636f6e666967292c205620286c656e206f6620766f756368696e6720667269656e647329202d204f6e652073746f72616765207265616420746f2067657420746865207265636f7665727920636f6e66696775726174696f6e2e204f2831292c20436f646563204f284629202d204f6e652073746f72616765207265616420746f206765742074686520616374697665207265636f766572792070726f636573732e204f2831292c20436f646563204f285629202d204f6e652073746f72616765207265616420746f20676574207468652063757272656e7420626c6f636b206e756d6265722e204f283129202d204f6e652073746f726167652077726974652e204f2831292c20436f646563204f2856292e20546f74616c20436f6d706c65786974793a204f2846202b20562920416c6c6f7720612022667269656e6422206f662061207265636f76657261626c65206163636f756e7420746f20766f75636820666f7220616e20616374697665207265636f766572792070726f6365737320666f722074686174206163636f756e742e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f20616e64206d75737420626520612022667269656e642220666f7220746865207265636f76657261626c65206163636f756e742e202d20606c6f7374603a20546865206c6f7374206163636f756e74207468617420796f752077616e7420746f207265636f7665722e202d206072657363756572603a20546865206163636f756e7420747279696e6720746f2072657363756520746865206c6f7374206163636f756e74207468617420796f7520202077616e7420746f20766f75636820666f722e2054686520636f6d62696e6174696f6e206f662074686573652074776f20706172616d6574657273206d75737420706f696e7420746f20616e20616374697665207265636f766572792070726f636573732e202d204f6e652062696e6172792073656172636820746f20636f6e6669726d2063616c6c6572206973206120667269656e642e204f286c6f674629202d204f6e652062696e6172792073656172636820746f20636f6e6669726d2063616c6c657220686173206e6f7420616c726561647920766f75636865642e204f286c6f67562920546f74616c20436f6d706c65786974793a204f2846202b206c6f6746202b2056202b206c6f67562920496e697469617465207468652070726f6365737320666f72207265636f766572696e672061207265636f76657261626c65206163636f756e742e205061796d656e743a20605265636f766572794465706f736974602062616c616e63652077696c6c20626520726573657276656420666f7220696e6974696174696e6720746865207265636f766572792070726f636573732e2054686973206465706f7369742077696c6c20616c7761797320626520726570617472696174656420746f20746865206163636f756e7420747279696e6720746f206265207265636f76657265642e205365652060636c6f73655f7265636f76657279602e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f5369676e65645f2e202d20606163636f756e74603a20546865206c6f7374206163636f756e74207468617420796f752077616e7420746f207265636f7665722e2054686973206163636f756e742020206e6565647320746f206265207265636f76657261626c652028692e652e20686176652061207265636f7665727920636f6e66696775726174696f6e292e202d204f6e652073746f72616765207265616420746f20636865636b2074686174206163636f756e74206973207265636f76657261626c652e204f284629202d204f6e652073746f72616765207265616420746f20636865636b20746861742074686973207265636f766572792070726f63657373206861736e277420616c726561647920737461727465642e204f283129202d204f6e652063757272656e63792072657365727665206f7065726174696f6e2e204f285829202d204f6e652073746f726167652077726974652e204f2831292e6163636f756e74204372656174652061207265636f7665727920636f6e66696775726174696f6e20666f7220796f7572206163636f756e742e2054686973206d616b657320796f7572206163636f756e74207265636f76657261626c652e205061796d656e743a2060436f6e6669674465706f7369744261736560202b2060467269656e644465706f736974466163746f7260202a20235f6f665f667269656e64732062616c616e63652077696c6c20626520726573657276656420666f722073746f72696e6720746865207265636f7665727920636f6e66696775726174696f6e2e2054686973206465706f7369742069732072657475726e656420696e2066756c6c207768656e2074686520757365722063616c6c73206072656d6f76655f7265636f76657279602e202d2060667269656e6473603a2041206c697374206f6620667269656e647320796f7520747275737420746f20766f75636820666f72207265636f7665727920617474656d7074732e20202053686f756c64206265206f72646572656420616e6420636f6e7461696e206e6f206475706c69636174652076616c7565732e202d20607468726573686f6c64603a20546865206e756d626572206f6620667269656e64732074686174206d75737420766f75636820666f722061207265636f7665727920617474656d70742020206265666f726520746865206163636f756e742063616e206265207265636f76657265642e2053686f756c64206265206c657373207468616e206f7220657175616c20746f202020746865206c656e677468206f6620746865206c697374206f6620667269656e64732e202d206064656c61795f706572696f64603a20546865206e756d626572206f6620626c6f636b732061667465722061207265636f7665727920617474656d707420697320696e697469616c697a656420202074686174206e6565647320746f2070617373206265666f726520746865206163636f756e742063616e206265207265636f76657265642e202d204b65793a204620286c656e206f6620667269656e647329202d204f6e652073746f72616765207265616420746f20636865636b2074686174206163636f756e74206973206e6f7420616c7265616479207265636f76657261626c652e204f2831292e202d204120636865636b20746861742074686520667269656e6473206c69737420697320736f7274656420616e6420756e697175652e204f284629202d204f6e652073746f726167652077726974652e204f2831292e20436f646563204f2846292e667269656e64735665633c543a3a4163636f756e7449643e7468726573686f6c6475313664656c61795f706572696f64543a3a426c6f636b4e756d62657220416c6c6f7720524f4f5420746f2062797061737320746865207265636f766572792070726f6365737320616e642073657420616e20612072657363756572206163636f756e7420666f722061206c6f7374206163636f756e74206469726563746c792e20546865206469737061746368206f726967696e20666f7220746869732063616c6c206d757374206265205f524f4f545f2e202d20606c6f7374603a2054686520226c6f7374206163636f756e742220746f206265207265636f76657265642e202d206072657363756572603a20546865202272657363756572206163636f756e74222077686963682063616e2063616c6c20617320746865206c6f7374206163636f756e742e202d204f6e652073746f72616765207772697465204f283129202d204f6e65206576656e746c6f73742053656e6420612063616c6c207468726f7567682061207265636f7665726564206163636f756e742e202d20606163636f756e74603a20546865207265636f7665726564206163636f756e7420796f752077616e7420746f206d616b6520612063616c6c206f6e2d626568616c662d6f662e202d206063616c6c603a205468652063616c6c20796f752077616e7420746f206d616b65207769746820746865207265636f7665726564206163636f756e742e202d2054686520776569676874206f6620746865206063616c6c60202b2031302c3030302e202d204f6e652073746f72616765206c6f6f6b757020746f20636865636b206163636f756e74206973207265636f7665726564206279206077686f602e204f283129426f783c3c542061732054726169743e3a3a43616c6c3e5265636f766572790000000088d212000b00000001050000000000007ac312000c0000000000000093d212003a00000000000000000000000000000000000000301a1300d0d212000000000000000000e0d2120001000000000000000000000000000000e8d212001000000002050500000000007ac312000c000000000000007ac312000c00000000000000f8d212003a00000000000000301a130034d31200000000000000000044d312000400000000000000000000000000000064d312000500000001020000000000007ac312000c000000000000007ac312000c00000000000000000000000000000000000000301a130028e0120000000000000000006cd312000300000000000000000000005265636f76657261626c655265636f76657279436f6e6669673c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e0000004200000000000000010000005b00000070d41200420000004163746976655265636f7665726965734163746976655265636f766572793c543a3a426c6f636b4e756d6265722c2042616c616e63654f663c543e2c20543a3a4163636f756e7449643e00004200000000000000010000005b000000e6d312001a000000301a13000000000000d412004500000045d412002b00000050726f787900000084d3120024000000301a130000000000a8d312003e00000020546865206c697374206f6620616c6c6f7765642070726f7879206163636f756e74732e204d61702066726f6d2074686520757365722077686f2063616e2061636365737320697420746f20746865207265636f7665726564206163636f756e742e20416374697665207265636f7665727920617474656d7074732e204669727374206163636f756e7420697320746865206163636f756e7420746f206265207265636f76657265642c20616e6420746865207365636f6e64206163636f756e7420697320746865207573657220747279696e6720746f207265636f76657220746865206163636f756e742e2054686520736574206f66207265636f76657261626c65206163636f756e747320616e64207468656972207265636f7665727920636f6e66696775726174696f6e2e000000000000fbaf12000b0000000000000090d51200020000000000000000000000c0d5120006000000000000000000000006b012000700000000000000f0d5120001000000000000000000000008d612000300000000000000000000000db01200070000000000000020d6120002000000000000000000000050d6120004000000000000000000000014b01200040000000000000070d61200030000000000000000000000b8d6120004000000000000000000000018b012000500000000000000d8d6120002000000000000000000000008d712000d0000000000000000000000cddb12000b00000000000000ddce12001100000000000000d8db12000500000000000000dddb1200140000001edb120021000000301a1300000000003fdb12003f0000007edb120039000000301a130000000000b7db1200160000000000000089d91200080000000000000098da12001e000000b6da12003d000000301a130000000000f3da12002b00000000000000eece1200090000000000000084da1200140000000000000089d91200080000000000000098da12001e000000f5bd12000b00000032da12002400000056da12002e00000044be12000c0000000000000089d91200080000000000000091d91200070000000000000098d9120005000000000000009dd9120016000000000000002bda12000700000000000000a1f5120004000000f5bd12000b000000b3d9120023000000d6d912005500000044be12000c0000000000000089d91200080000000000000091d91200070000000000000098d9120005000000000000009dd912001600000070d7120054000000c4d7120026000000301a130000000000ead712005700000041d8120019000000301a1300000000005ad81200250000007fd81200200000009fd8120043000000e2d812002c0000000ed912001e0000002cd912002700000053d9120036000000204d61792062652063616c6c656420627920616e79207369676e6564206163636f756e742061667465722074686520766f74696e67206475726174696f6e2068617320656e64656420696e206f7264657220746f2066696e69736820766f74696e6720616e6420636c6f7365207468652070726f706f73616c2e2041627374656e74696f6e732061726520636f756e7465642061732072656a656374696f6e7320756e6c6573732074686572652069732061207072696d65206d656d6265722073657420616e6420746865207072696d65206d656d626572206361737420616e20617070726f76616c2e202d2074686520776569676874206f66206070726f706f73616c6020707265696d6167652e202d20757020746f207468726565206576656e7473206465706f73697465642e202d206f6e6520726561642c2074776f2072656d6f76616c732c206f6e65206d75746174696f6e2e2028706c7573207468726565207374617469632072656164732e29202d20636f6d7075746174696f6e20616e6420692f6f20604f2850202b204c202b204d29602077686572653a2020202d20604d60206973206e756d626572206f66206d656d626572732c2020202d20605060206973206e756d626572206f66206163746976652070726f706f73616c732c2020202d20604c602069732074686520656e636f646564206c656e677468206f66206070726f706f73616c6020707265696d6167652e70726f706f73616c543a3a48617368696e646578436f6d706163743c50726f706f73616c496e6465783e202d20426f756e6465642073746f72616765207265616420616e64207772697465732e202d2057696c6c20626520736c696768746c792068656176696572206966207468652070726f706f73616c20697320617070726f766564202f20646973617070726f7665642061667465722074686520766f74652e617070726f7665202d20426f756e6465642073746f7261676520726561647320616e64207772697465732e202d20417267756d656e7420607468726573686f6c6460206861732062656172696e67206f6e207765696768742e436f6d706163743c4d656d626572436f756e743e426f783c3c542061732054726169743c493e3e3a3a50726f706f73616c3e20446973706174636820612070726f706f73616c2066726f6d2061206d656d626572207573696e672074686520604d656d62657260206f726967696e2e204f726967696e206d7573742062652061206d656d626572206f662074686520636f6c6c6563746976652e205365742074686520636f6c6c6563746976652773206d656d626572736869702e202d20606e65775f6d656d62657273603a20546865206e6577206d656d626572206c6973742e204265206e69636520746f2074686520636861696e20616e64202d20607072696d65603a20546865207072696d65206d656d6265722077686f736520766f74652073657473207468652064656661756c742e20526571756972657320726f6f74206f726967696e2e6e65775f6d656d626572737072696d654f7074696f6e3c543a3a4163636f756e7449643e5665633c543a3a486173683e000000d4dd12002400000050726f706f73616c4f663c542061732054726169743c493e3e3a3a50726f706f73616c00a1dd120033000000566f7465733c543a3a4163636f756e7449642c20543a3a426c6f636b4e756d6265723e0074dd12002d0000007533320062dd12001200000014dd12004e00000084dc120057000000dbdc12003900000020546865206d656d6265722077686f2070726f7669646573207468652064656661756c7420766f746520666f7220616e79206f74686572206d656d62657273207468617420646f206e6f7420766f7465206265666f7265207468652074696d656f75742e204966204e6f6e652c207468656e206e6f206d656d6265722068617320746861742070726976696c6567652e205468652063757272656e74206d656d62657273206f662074686520636f6c6c6563746976652e20546869732069732073746f72656420736f7274656420286a7573742062792076616c7565292e2050726f706f73616c7320736f206661722e20566f746573206f6e206120676976656e2070726f706f73616c2c206966206974206973206f6e676f696e672e2041637475616c2070726f706f73616c20666f72206120676976656e20686173682c20696620697427732063757272656e742e2054686520686173686573206f6620746865206163746976652070726f706f73616c732e0000000000b51200090000000000000000000000f1db12000c00000000000000000000000000000000000000000000000000000000000000301a130090e01200000000000000000000dc12000100000000000000010000000000000008dc12000a000000010600000000000091d91200070000000000000012dc12001900000000000000000000000000000000000000301a130028e0120000000000000000002cdc12000100000000000000000000000000000010b5120006000000010600000000000091d91200070000000000000034dc12002300000000000000000000000000000000000000301a130028e01200000000000000000058dc1200010000000000000000000000000000000ef812000d000000000000000000000060dc12000300000000000000000000000000000000000000000000000000000000000000301a130008e01200000000000000000064dc12000100000000000000010000000000000009b51200070000000000000000000000ddce12001100000000000000000000000000000000000000000000000000000000000000301a130018e0120000000000000000006cdc1200010000000000000001000000000000009caf12000500000000000000000000007ac312000c00000000000000000000000000000000000000000000000000000000000000301a130028e01200000000000000000074dc120002000000000000000000000042000000000000000100000057000000420000000000000001000000590000004200000000000000010000005b000000000000009ab412000e0000000000000000000000f1db12000c00000000000000000000000000000000000000000000000000000000000000301a130090e012000000000000000000a0e0120003000000000000000100000042000000000000000100000059000000b8e012005800000010e112005800000068e112001100000020536572696573206f6620626c6f636b20686561646572732066726f6d20746865206c61737420383120626c6f636b73207468617420616374732061732072616e646f6d2073656564206d6174657269616c2e205468697320697320617272616e67656420617320612072696e672062756666657220776974682060626c6f636b5f6e756d626572202520383160206265696e672074686520696e64657820696e746f20746865206056656360206f6620746865206f6c6465737420686173682e00000000000000cdab12000a000000000000003ce31200010000000000000000000000c0ab12000d0000000000000044e31200010000000000000000000000b0ab120010000000000000004ce31200010000000000000000000000a6ab12000a0000000000000054e312000100000000000000000000009dab120009000000000000005ce312000100000000000000000000008fab12000e0000000000000064e312000100000000000000000000007dab120012000000000000006ce312000100000000000000000000006fab12000e0000000000000074e3120001000000000000000000000065ab12000a000000000000007ce312000100000000000000000000005cab1200090000000000000084e3120001000000000000000000000051ab12000b000000000000008ce3120001000000000000000000000043ab12000e0000000000000094e312000100000000000000000000003aab120009000000000000009ce312000100000000000000000000002fab12000b00000000000000a4e3120001000000000000000000000027ab12000800000000000000ace312000100000000000000000000001bab12000c000000000000006ce3120001000000000000006fe612003d0000004be612002400000016e6120035000000ebe512002b000000b8e512003300000090e512002800000064e512002c0000002ce5120038000000f8e4120034000000cde412002b00000086e412004700000056e41200300000001be412003b000000dbe3120040000000b4e31200270000002054686572652077617320616e206f766572666c6f7720696e20612063616c63756c6174696f6e20546865726520617265207374696c6c20616374697665207265636f7665727920617474656d7074732074686174206e65656420746f20626520636c6f73656420546865207468726573686f6c6420666f72207265636f766572696e672074686973206163636f756e7420686173206e6f74206265656e206d6574205468697320757365722068617320616c726561647920766f756368656420666f722074686973207265636f766572792054686520667269656e64206d757374207761697420756e74696c207468652064656c617920706572696f6420746f20766f75636820666f722074686973207265636f766572792054686973206163636f756e74206973206e6f74206120667269656e642077686f2063616e20766f7563682041207265636f766572792070726f6365737320686173206e6f74207374617274656420666f72207468697320726573637565722041207265636f766572792070726f636573732068617320616c7265616479207374617274656420666f722074686973206163636f756e742054686973206163636f756e7420697320616c72656164792073657420757020666f72207265636f766572792054686973206163636f756e74206973206e6f742073657420757020666f72207265636f7665727920467269656e6473206c697374206d75737420626520736f7274656420616e642066726565206f66206475706c69636174657320467269656e6473206c697374206d757374206265206c657373207468616e206d617820667269656e647320467269656e6473206c697374206d7573742062652067726561746572207468616e207a65726f20616e64207468726573686f6c64205468726573686f6c64206d7573742062652067726561746572207468616e207a65726f2055736572206973206e6f7420616c6c6f77656420746f206d616b6520612063616c6c206f6e20626568616c66206f662074686973206163636f756e7400000000f2af1200090000000000000070e71200010000000000000000000000e1af1200110000000000000078e71200010000000000000000000000d2af12000f0000000000000080e71200010000000000000000000000c8af12000a0000000000000088e71200010000000000000000000000bbaf12000d0000000000000090e71200010000000000000000000000a9af1200120000000000000098e71200010000000000000000000000a1af12000800000000000000a0e71200010000000000000065e812001800000045e812002000000031e812001400000020e812001100000009e8120017000000e8e7120021000000a8e71200400000002054686520636c6f73652063616c6c206973206d61646520746f6f206561726c792c206265666f72652074686520656e64206f662074686520766f74696e672e204d656d626572732061726520616c726561647920696e697469616c697a656421204475706c696361746520766f74652069676e6f726564204d69736d61746368656420696e6465782050726f706f73616c206d757374206578697374204475706c69636174652070726f706f73616c73206e6f7420616c6c6f776564204163636f756e74206973206e6f742061206d656d626572417574686f72697479446973636f766572794b657973417574686f7273686970446964536574556e636c65734261626545706f6368496e646578417574686f72697469657347656e65736973536c6f7443757272656e74536c6f7452616e646f6d6e6573734e65787452616e646f6d6e6573735365676d656e74496e646578556e646572436f6e737472756374696f6e746f6f206d616e7920696e737472756374696f6e734e6f6e2d656d7074792066756e6374696f6e20626f647920657870656374656400008ce912000f0000009be91200020000009de9120003000000617373657274696f6e206661696c65643a20636f6e746578742e6672616d655f737461636b2e69735f656d7074792829417420696e737472756374696f6e202840293a2043616e2774206465636f6465207761736d20636f64654d6f64756c65206973206e6f742076616c69646d6f64756c65206465636c6172657320696e7465726e616c206d656d6f72796d756c7469706c65207461626c6573206465636c617265647461626c652065786365656473206d6178696d756d2073697a6520616c6c6f776564757365206f6620666c6f6174696e6720706f696e74207479706520696e2066756e6374696f6e20747970657320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e206c6f63616c7320697320666f7262696464656e757365206f6620666c6f6174696e6720706f696e74207479706520696e20676c6f62616c7320697320666f7262696464656e67617320696e737472756d656e746174696f6e206661696c6564737461636b2068656967687420696e737472756d656e746174696f6e206661696c656463616c6c6465706c6f796465706c6f792066756e6374696f6e2069736e2774206578706f72746564756e6b6e6f776e206578706f72743a20657870656374696e67206f6e6c79206465706c6f7920616e642063616c6c2066756e6374696f6e7366756e6374696f6e206861732061206e6f6e2d6578697374656e7420747970656578706f72742072656665727320746f206e6f6e2d6578697374656e742066756e6374696f6e657870656374656420612066756e6374696f6e656e74727920706f696e7420706f696e747320746f20616e20696d706f727465642066756e6374696f6e656e74727920706f696e74206861732077726f6e67207369676e617475726563616c6c2066756e6374696f6e2069736e2774206578706f727465646572726f722073657269616c697a696e6720696e737472756d656e746564206d6f64756c6552657475726e207479706573206c656e6774682073686f756c642062652030206f72203143757272656e745363686564756c65436f6e7472616374734163636f756e74436f756e74657298ec12006700000051010000170000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7761736d2d302e34312e302f7372632f656c656d656e74732f73656374696f6e2e72730089ef12001e000000a7ef12001f00000066756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2071656400002bef12005e000000d10000002000000066756e6374696f6e5f73656374696f6e5f6c656e20213d20303b2066756e6374696f6e5f73656374696f6e5f6c656e203d3d20636f64655f73656374696f6e5f6c656e3b207165642bef12005e000000d40000001c00000011ef12001a000000ecee12000a000000f6ee12001b00000073746172742066756e6374696f6e20657870656374656420746f20686176652074797065205b5d202d3e205b5d000000dbee120011000000bbee1200200000009bee12002000000073ee12002800000070617373697665206d656d6f7279207365676d656e747320617265206e6f7420737570706f727465647365676d656e74206f66667365742073686f756c642072657475726e204933327061737369766520656c656d656e74207365676d656e747320617265206e6f7420737570706f72746564746f6f206d616e79206d656d6f727920726567696f6e7320696e20696e6465782073706163653a20746f6f206d616e79207461626c657320696e20696e6465782073706163653a20747279696e6720746f20696d706f7274206d757461626c6520676c6f62616c206475706c6963617465206578706f72742046756e6374696f6e20232072656164696e672f76616c69646174696f6e206572726f723a204d697373696e6720626f647920666f722066756e6374696f6e202f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e332e302f7372632f6c69622e72736c656e677468206f662066756e6374696f6e2073656374696f6e206973202c207768696c65206c656e206f6620636f64652073656374696f6e206973206578745f7365745f73746f726167656578745f636c6561725f73746f726167656578745f6765745f73746f726167656578745f7472616e736665726578745f63616c6c6578745f696e7374616e74696174656578745f7465726d696e6174656578745f72657475726e6578745f63616c6c65726578745f616464726573736578745f6761735f70726963656578745f6761735f6c6566746578745f62616c616e63656578745f76616c75655f7472616e736665727265646578745f72616e646f6d6578745f6e6f776578745f6d696e696d756d5f62616c616e63656578745f746f6d6273746f6e655f6465706f7369746578745f64697370617463685f63616c6c6578745f726573746f72655f746f6578745f736372617463685f73697a656578745f736372617463685f726561646578745f736372617463685f77726974656578745f6465706f7369745f6576656e746578745f7365745f72656e745f616c6c6f77616e63656578745f72656e745f616c6c6f77616e63656578745f7072696e746c6e6578745f626c6f636b5f6e756d6265726578745f6765745f72756e74696d655f73746f726167656578745f686173685f736861325f3235366578745f686173685f6b656363616b5f3235366578745f686173685f626c616b65325f3235366578745f686173685f626c616b65325f3132385075626c696350726f70436f756e745265666572656e64756d436f756e7444656d6f63726163794c6f77657374556e62616b65644c6173745461626c656457617345787465726e616c0000000001000000020000000400000008000000100000002000000050687261676d656e456c656374696f6e456c656374696f6e526f756e647346696e616c697479547261636b6572496e697469616c697a656400000000dcf212000e00000000000000ecf21200010000000000000000000000f4f21200010000000000000000000000fcf212000600000000000000301a130000000000000000000000000004f312000100000000000000000000000cf312000700000000000000301a130000000000000000000000000014f3120001000000000000004e6577417574686f72697469657300008ff312000d0000006bf3120024000000506175736564000044f3120027000000526573756d6564001cf31200280000002043757272656e7420617574686f726974792073657420686173206265656e20726573756d65642e2043757272656e7420617574686f726974792073657420686173206265656e207061757365642e204e657720617574686f726974792073657420686173206265656e206170706c6965642e417574686f726974794c69737443757272656e7453657449644772616e64706146696e616c697479536574496453657373696f6e00d4f3120034000000b00000002e0000002f686f6d652f6461766964642f6465762f7375627374726174652f6672616d652f6964656e746974792f7372632f6c69622e7273496d4f6e6c696e655265636569766564486561727462656174734f6666656e6365735265706f72747342794b696e64496e6465780000000068f41200070000000000000070f4120003000000000000000000000088f4120003000000000000004f6666656e6365008ff512000400000093f512000e000000a1f5120004000000a0f4120055000000f5f412005300000048f512004700000020546865726520697320616e206f6666656e6365207265706f72746564206f662074686520676976656e20606b696e64602068617070656e656420617420746865206073657373696f6e5f696e6465786020616e6420286b696e642d7370656369666963292074696d6520736c6f742e2054686973206576656e74206973206e6f74206465706f736974656420666f72206475706c696361746520736c61736865732e206c61737420656c656d656e7420696e64696361746573206f6620746865206f6666656e636520776173206170706c69656420287472756529206f7220717565756564202866616c7365292e4b696e644f706171756554696d65536c6f74626f6f6c43757272656e74496e6465785175657565644368616e67656444697361626c656456616c696461746f727300000000fcf512000a0000000000000008f6120001000000000000000000000010f6120002000000000000004e657753657373696f6e000097f612000c00000020f612005500000075f6120022000000204e65772073657373696f6e206861732068617070656e65642e204e6f746520746861742074686520617267756d656e74206973207468652073657373696f6e20696e6465782c206e6f742074686520626c6f636b206e756d626572206173207468652074797065206d6967687420737567676573742e53657373696f6e496e64657853657373696f6e53746f72656452616e6765486973746f7279446570746856616c696461746f72436f756e744d696e696d756d56616c696461746f72436f756e7443757272656e744572614163746976654572615374616b696e6745726173537461727453657373696f6e496e646578466f726365457261536c6173685265776172644672616374696f6e426f6e646564457261734561726c69657374556e6170706c696564536c61736851756575656453636f7265497343757272656e7453657373696f6e46696e616c4d69677261746545726174696d737461703054696d657374616d7020696e686572656e742064617461206973206e6f742070726f76696465642e496e76616c69642074696d657374616d7020696e686572656e74206461746120656e636f64696e672e54696d657374616d704469645570646174655472616e73616374696f6e5061796d656e744e6578744665654d756c7469706c696572547265617375727950726f706f73616c436f756e74417070726f76616c7334f812006200000088000000120000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7363616c652d636f6465632d312e332e302f7372632f636f6465632e727300004200000004000000040000000c00000042725461626c65446174617461626c654200000004000000040000001e01000064656661756c744636345265696e74657270726574493634556e726561636861626c654e6f70426c6f636b004200000004000000040000001f0100004c6f6f704966456c7365456e6442724272496642725461626c6500004200000004000000040000002001000052657475726e43616c6c43616c6c496e6469726563740000420000000400000004000000fa00000044726f7053656c6563744765744c6f63616c5365744c6f63616c5465654c6f63616c476574476c6f62616c536574476c6f62616c4933324c6f61644936344c6f61644633324c6f61644636344c6f61644933324c6f616438534933324c6f616438554933324c6f61643136534933324c6f61643136554936344c6f616438534936344c6f616438554936344c6f61643136534936344c6f61643136554936344c6f61643332534936344c6f616433325549333253746f726549363453746f726546333253746f726546363453746f726549333253746f72653849333253746f7265313649363453746f72653849363453746f7265313649363453746f7265333243757272656e744d656d6f727947726f774d656d6f7279493332436f6e73740042000000040000000400000021010000493634436f6e737442000000040000000400000022010000463332436f6e7374463634436f6e73744200000004000000040000003400000049333245717a49333245714933324e654933324c74534933324c74554933324774534933324774554933324c65534933324c655549333247655349333247655549363445717a49363445714936344e654936344c74534936344c74554936344774534936344774554936344c65534936344c655549363447655349363447655546333245714633324e654633324c7446333247744633324c65463332476546363445714636344e654636344c7446363447744636344c654636344765493332436c7a49333243747a493332506f70636e744933324164644933325375624933324d756c493332446976534933324469765549333252656d5349333252656d55493332416e644933324f72493332586f7249333253686c4933325368725349333253687255493332526f746c493332526f7472493634436c7a49363443747a493634506f70636e744936344164644936345375624936344d756c493634446976534936344469765549363452656d5349363452656d55493634416e644936344f72493634586f7249363453686c4936345368725349363453687255493634526f746c493634526f74724633324162734633324e65674633324365696c463332466c6f6f724633325472756e634633324e656172657374463332537172744633324164644633325375624633324d756c4633324469764633324d696e4633324d6178463332436f70797369676e4636344162734636344e65674636344365696c463634466c6f6f724636345472756e634636344e656172657374463634537172744636344164644636345375624636344d756c4636344469764636344d696e4636344d6178463634436f70797369676e493332577261704936344933325472756e63534633324933325472756e63554633324933325472756e63534636344933325472756e6355463634493634457874656e6453493332493634457874656e64554933324936345472756e63534633324936345472756e63554633324936345472756e63534636344936345472756e6355463634463332436f6e7665727453493332463332436f6e7665727455493332463332436f6e7665727453493634463332436f6e766572745549363446333244656d6f7465463634463634436f6e7665727453493332463634436f6e7665727455493332463634436f6e7665727453493634463634436f6e766572745549363446363450726f6d6f74654633324933325265696e746572707265744633324936345265696e746572707265744636344633325265696e7465727072657449333200004200000004000000040000000c000000463634493332493634463332420000000400000004000000230100004e6f526573756c7456616c7565000000b4fe12000b000000492f4f204572726f723a2000d0fe120059000000450000001e0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7061726974792d7761736d2d302e34312e302f7372632f696f2e7273496e76616c696444617461547261696c696e6744617461556e6578706563746564456f66000000617474656d707420746f20646976696465206279207a65726f556e7369676e656420696e74656765722063616e277420626520637265617465642066726f6d206e656761746976652076616c75652f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7072696d69746976652d74797065732d302e372e302f7372632f6c69622e72736469766973696f6e206279207a65726f496e7465676572206f766572666c6f77207768656e2063617374696e6720746f207573697a65000000000000000000000000000000617474656d707420746f20646976696465206279207a65726f0000009eff12005d0000002000000001000000547269656420746f20736872696e6b20746f2061206c6172676572206361706163697479e101130012000000f30113000c0000006066756e635f696478602073686f756c6420636f6d652066726f6d20606e6565645f7468756e6b73603b0a09090909606e6565645f7468756e6b736020697320706f70756c617465642077697468207468652073616d65206974656d73207468617420696e20607265706c6163656d656e745f6d6170603b0a09090909716564780113006900000050000000190000004174207468697320706f696e7420616e20696e646578206d7573742062652061737369676e656420746f2065616368207468756e6b0000007801130069000000890000001d0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31322e302f7372632f737461636b5f6865696768742f7468756e6b2e727366756e6374696f6e207769746820696478202069736e277420666f756e64617373657274696f6e206661696c65643a20656467652e686569676874203d3d2073656c662e686569676874202d2031617373657274696f6e206661696c65643a2073656c662e6c656e2829203c204341504143495459617373657274696f6e206661696c65643a20656467652e686569676874203d3d2073656c662e6e6f64652e686569676874202d20314672616d6569735f706f6c796d6f7270686963000042000000040000000400000024010000656e645f61726974790000004200000004000000040000000c0000006272616e63685f617269747973746172745f6865696768746003130049000000920200001a000000a9031300480000000002000023000000a90313004800000001020000230000006003130049000000a301000027000000617373657274696f6e206661696c65643a206d6964203c3d206c656e401a1300490000000a0000000900000060031300490000008e0200001d0000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f736c6963652f736f72742e72732f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f736c6963652f6d6f642e72730000006003130049000000a1000000300000006003130049000000a4000000300000004e6f2066756e6374696f6e2073656374696f6e4e6f20636f64652073656374696f6e4e6f20747970652073656374696f6e0000008b0613000a00000046756e6374696f6e206973206e6f7420666f756e6420696e2066756e632073656374696f6e0000007f0613000c00000046756e6374696f6e20626f647920666f722074686520696e6465782069736e277420666f756e6400300613000b00000029061300070000002306130006000000737461636b206f766572666c6f77737461636b206d757374206265206e6f6e2d656d707479000000180613000b0000004172697479206f6620616c6c206a756d702d74617267657473206d75737420626520657175616c54797065206e6f7420666f756e64000000380513006e000000c8000000170000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31322e302f7372632f737461636b5f6865696768742f6d61785f6865696768742e727300001306130005000000747279696e6720746f20706f70206d6f72652076616c756573207468616e20707573686564737461636b20756e646572666c6f776d61785f686569676874707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f686569676874706f703a20756e726561636861626c65707573683a207472756e633a20706f705f6672616d653a20636f6e74726f6c20737461636b20697320656d707479000000380513006e0000003a0000000d000000636f6e74726f6c20737461636b206f75742d6f662d626f756e6473707573685f6672616d653a2066756e635f6964783a2063616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565d006130055000000480600001b0000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962616c6c6f632f636f6c6c656374696f6e732f62747265652f6d61702e7273656e766761736c6173745f696e6465782069732067726561746572207468616e20303b206c6173745f696e64657820697320737461636b2073697a65202d20313b2071656400008c0713005e000000a6000000260000008c0713005e000000120100001c0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31322e302f7372632f6761732f6d6f642e7273536f6d654e6f6e65000042000000040000000400000025010000410813006700000010010000200000001c0813002500000043616c6c20746f2066756e6374696f6e2074686174206f75742d6f662d626f756e64733a202f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f707761736d2d7574696c732d302e31322e302f7372632f737461636b5f6865696768742f6d6f642e7273546869732073686f756c64206265206120696e646578206f66206120646566696e65642066756e6374696f6e44756520746f2076616c69646174696f6e20636f64652073656374696f6e2073686f756c642065786973747346756e6374696f6e20626f6479206973206f7574206f6620626f756e647366756e6374696f6e20696d706f727420636f756e74206973206e6f74207a65726f3b20696d706f72742073656374696f6e206d757374206578697374733b207165644108130067000000590100000900000066756e635f696478206973206c657373207468616e2066756e6374696f6e20696d706f72747320636f756e743b0a090909096e74682066756e6374696f6e20696d706f7274206d7573742062652060536f6d65603b0a090909097165640000005c17130012000000250a13000f000000f80913000a000000020a130014000000160a13000f0000005369676e61747572652020287370656369666965642062792066756e6320292069736e277420646566696e6564206973206e6f7420646566696e6564440a13003f000000440000000d0000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f61726974686d657469632f7372632f62696775696e742e727300000000000000000000000000617474656d707420746f20646976696465206279207a65726f000000440a13003f0000006d00000009000000440a13003f0000007e00000009000000440a13003f0000009c0000001b000000440a13003f000000d40100001c000000440a13003f000000d50100001c00000063616e6e6f74206669742061206e756d62657220696e746f2075313238000000440a13003f0000009000000009000000616c7265616479206d757461626c7920626f72726f77656442000000000000000100000064000000640b1300430000001e030000090000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f63656c6c2e7273616c726561647920626f72726f776564004200000000000000010000006d000000640b1300430000006e0300000900000072656d696e646572206f6620646976206279206320697320616c77617973206c657373207468616e20633b20716564004200000008000000040000007a000000410c130046000000680000001b000000726573756c742063616e6e6f742066697420696e20753132382f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f61726974686d657469632f7372632f68656c706572735f3132386269742e727362616265736c6f74436f756c64206e6f74206465636f64652072657175657374656420696e686572656e742074797065214241424520696e686572656e742064617461206e6f7420666f756e64e40c130044000000cd0000000d0000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f72756e74696d652d696e746572666163652f7372632f696d706c732e727342000000000000000100000046000000486f737420746f207761736d2076616c7565732061726520656e636f64656420636f72726563746c793b207165640000780d13004600000008010000090000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f72756e74696d652d696e746572666163652f7372632f706173735f62792e727300004200000000000000010000004600000072756e74696d6552756e74696d65206d656d6f7279206578686175737465642e2041626f7274696e6700000000000000617474656d707420746f20646976696465206279207a65726f0000002c0e1300400000005f0000002b0000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f72756e74696d652f7372632f67656e657269632f6572612e727348617368206e6f7420657175616c2f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f72756e74696d652f7372632f7472616974732e72730000007a0e13003b0000000504000013000000426164206f726967696e43616e206e6f74206c6f6f6b757044697370617463684572726f723c7761736d3a73747269707065643e5472616e616374696f6e206469737061746368206973206d616e6461746f72793b207472616e73616374696f6e73206d6179206e6f742068617665206d616e6461746f727920646973706174636865732e412063616c6c20776173206c6162656c6c6564206173206d616e6461746f72792c2062757420726573756c74656420696e20616e204572726f722e5472616e73616374696f6e20776f756c642065786861757374732074686520626c6f636b206c696d6974735472616e73616374696f6e2068617320616e20616e6369656e7420626972746820626c6f636b5472616e73616374696f6e20686173206120626164207369676e61747572655472616e73616374696f6e206973206f757464617465645472616e73616374696f6e2077696c6c2062652076616c696420696e2074686520667574757265496e6162696c69747920746f2070617920736f6d6520666565732028652e672e206163636f756e742062616c616e636520746f6f206c6f77295472616e73616374696f6e2063616c6c206973206e6f74206578706563746564496e76616c69645472616e73616374696f6e20637573746f6d206572726f72436f756c64206e6f742066696e6420616e20756e7369676e65642076616c696461746f7220666f722074686520756e7369676e6564207472616e73616374696f6e436f756c64206e6f74206c6f6f6b757020696e666f726d6174696f6e20726571756972656420746f2076616c696461746520746865207472616e73616374696f6e556e6b6e6f776e5472616e73616374696f6e20637573746f6d206572726f72696e7465726e616c206572726f723a20656e746572656420756e726561636861626c6520636f64650088111300430000005a000000120000002f686f6d652f6461766964642f6465762f7375627374726174652f7072696d6974697665732f73616e64626f782f7372632f2e2e2f776974686f75745f7374642e727300881113004300000068000000120000004475706c69636174655265706f72744f6666656e63654572726f726d616b655f746f705f6672616d655f706f6c796d6f72706869632069732063616c6c6564207769746820656d707479206672616d6520737461636b0000260100000c00000004000000270100005f1413005f0000004204000011000000746869732066756e6374696f6e2063616e27742062652063616c6c6564207769746820656d707479206672616d6520737461636b5f1413005f000000b2040000050000004d6973706c6163656420656c736520696e737472756374696f6e0000df131300470000002614130005000000a313130037000000da131300050000006e1313001700000065131300090000001a161300140000004d1313001800000065131300090000001a161300140000001c1313001d00000039131300130000004c13130001000000546f6f206c61726765206d656d6f727920616c69676e6d656e7420325e20286578706563746564206174206d6f73742029547279696e6720746f2075706461746520676c6f62616c20206f66207479706520547279696e6720746f20757064617465206c6f63616c20537065636966696300000042000000040000000400000023010000416e794c6162656c7320696e2062725f7461626c6520706f696e747320746f20626c6f636b206f6620646966666572656e742074797065733a2020616e6420496620626c6f636b20776974686f757420656c736520726571756972656420746f2068617665204e6f526573756c7420626c6f636b20747970652e2042757420697420686173202074797065003c14130018000000541413000b000000556e657870656374656420737461636b20686569676874202c206578706563746564202f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e332e302f7372632f66756e632e7273547279696e6720746f2061636365737320706172656e74206672616d6520737461636b2076616c7565732e000000fc14130017000000131513001600000045787065637465642076616c7565206f66207479706520206f6e20746f70206f6620737461636b2e20476f74200000003415130007000000537461636b3a200000000100be1513002400000094151300060000009a1513000e000000a815130016000000701513002400000094151300060000006d6178696d756d206d656d6f72792073697a65206d757374206265206174206d6f7374202070616765736d6178696d756d206c696d697420206973206c657373207468616e206d696e696d756d20696e697469616c206d656d6f72792073697a65206d757374206265206174206d6f7374200000f4151300260000001a16130014000000547279696e6720746f20696e697469616c697a65207661726961626c65206f6620747970652020776974682076616c7565206f66207479706520496e69742065787072657373696f6e2073686f756c6420616c776179732062652077697468206c656e67746820324e6f6e20636f6e7374616e74206f70636f646520696e20696e69742065787072c516130007000000d716130022000000c516130007000000cc1613000b00000045787072657373696f6e20646f65736e277420656e647320776974682060656e6460206f70636f6465476c6f62616c20206973206d757461626c6520646f65736e277420657869737473206f72206e6f742079657420646566696e65640000000c171300100000001c1713000f0000004d656d6f727920617420696e6465782020646f65736e277420657869737473003c1713000f0000001c1713000f0000005461626c6520617420696e64657820005c171300120000001c1713000f00000046756e6374696f6e20617420696e646578200000801713000e0000001c1713000f0000005479706520617420696e646578200000ee171300100000001c1713000f000000c017130010000000e01713000e000000c017130010000000d017130010000000457870656374656420676c6f62616c2020746f20626520696d6d757461626c6520746f206265206d757461626c65476c6f62616c20617420696e646578206e6f6e2d656d70747920737461636b206578706563746564000028181300200000004818130012000000747279696e6720746f206765742076616c756520617420706f736974696f6e20206f6e20737461636b206f662073697a6520636865636b656420636f75706c65206f66206c696e65732061626f76650088181300600000004b0000000c0000002f686f6d652f6461766964642f2e636172676f2f72656769737472792f7372632f6769746875622e636f6d2d316563633632393964623965633832332f7761736d692d76616c69646174696f6e2d302e332e302f7372632f737461636b2e7273f018130015000000657863656564656420737461636b206c696d697420000000301a1300000000004572726f72000000420000000400000004000000280100004c6f63616c732072616e6765206e6f7420696e2033322d6269742072616e6765601913002200000082191300150000009719130007000000547279696e6720746f20616363657373206c6f63616c207769746820696e64657820207768656e20746865726520617265206f6e6c7920206c6f63616c730000b81913002d000000e51913000c000000f119130003000000617373657274696f6e206661696c65643a2060286c656674203d3d20726967687429600a20206c6566743a2060602c0a2072696768743a2060603a20fc1913003400000064657374696e6174696f6e20616e6420736f7572636520736c69636573206861766520646966666572656e74206c656e67746873401a13004900000010000000090000002f72757374632f666135316638313065356239323534393034623932363630653732383062376436613436663131322f7372632f6c6962636f72652f6d6163726f732f6d6f642e727300418cb5cc000b080000000000000000004194b5cc000b082c1110002c11100000e1b605046e616d6501d8b605a50800196578745f6c6f6767696e675f6c6f675f76657273696f6e5f31011e6578745f68617368696e675f74776f785f3132385f76657273696f6e5f3102196578745f73746f726167655f7365745f76657273696f6e5f31031d6578745f68617368696e675f74776f785f36345f76657273696f6e5f3104206578745f68617368696e675f626c616b65325f3132385f76657273696f6e5f3105196578745f73746f726167655f6765745f76657273696f6e5f31061d6578745f6d6973635f7072696e745f757466385f76657273696f6e5f31071b6578745f73746f726167655f636c6561725f76657273696f6e5f3108226578745f73746f726167655f636c6561725f7072656669785f76657273696f6e5f3109206578745f68617368696e675f626c616b65325f3235365f76657273696f6e5f310a1c6578745f6d6973635f7072696e745f6865785f76657273696f6e5f310b276578745f63727970746f5f73746172745f62617463685f7665726966795f76657273696f6e5f310c286578745f63727970746f5f66696e6973685f62617463685f7665726966795f76657273696f6e5f310d236578745f6f6666636861696e5f69735f76616c696461746f725f76657273696f6e5f310e286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f6765745f76657273696f6e5f310f346578745f6f6666636861696e5f6c6f63616c5f73746f726167655f636f6d706172655f616e645f7365745f76657273696f6e5f3110276578745f64656661756c745f6368696c645f73746f726167655f6765745f76657273696f6e5f3111306578745f64656661756c745f6368696c645f73746f726167655f73746f726167655f6b696c6c5f76657273696f6e5f3112276578745f64656661756c745f6368696c645f73746f726167655f7365745f76657273696f6e5f3113296578745f64656661756c745f6368696c645f73746f726167655f636c6561725f76657273696f6e5f3114226578745f6f6666636861696e5f72616e646f6d5f736565645f76657273696f6e5f3115236578745f63727970746f5f737232353531395f7665726966795f76657273696f6e5f3216286578745f6f6666636861696e5f6c6f63616c5f73746f726167655f7365745f76657273696f6e5f3117206578745f73616e64626f785f6d656d6f72795f6e65775f76657273696f6e5f3118256578745f73616e64626f785f6d656d6f72795f74656172646f776e5f76657273696f6e5f3119216578745f73616e64626f785f696e7374616e74696174655f76657273696f6e5f311a1c6578745f73616e64626f785f696e766f6b655f76657273696f6e5f311b276578745f73616e64626f785f696e7374616e63655f74656172646f776e5f76657273696f6e5f311c206578745f73616e64626f785f6d656d6f72795f6765745f76657273696f6e5f311d206578745f73616e64626f785f6d656d6f72795f7365745f76657273696f6e5f311e1e6578745f68617368696e675f736861325f3235365f76657273696f6e5f311f206578745f68617368696e675f6b656363616b5f3235365f76657273696f6e5f3120236578745f63727970746f5f656432353531395f7665726966795f76657273696f6e5f3121286578745f64656661756c745f6368696c645f73746f726167655f726f6f745f76657273696f6e5f31221c6578745f73746f726167655f617070656e645f76657273696f6e5f31231a6578745f73746f726167655f726f6f745f76657273696f6e5f3124226578745f73746f726167655f6368616e6765735f726f6f745f76657273696f6e5f3125226578745f6d6973635f72756e74696d655f76657273696f6e5f76657273696f6e5f31261c6578745f6d6973635f7072696e745f6e756d5f76657273696f6e5f31271e6578745f73746f726167655f6e6578745f6b65795f76657273696f6e5f31282a6578745f747269655f626c616b65325f3235365f6f7264657265645f726f6f745f76657273696f6e5f3129246578745f6f6666636861696e5f6e6574776f726b5f73746174655f76657273696f6e5f312a296578745f6f6666636861696e5f7375626d69745f7472616e73616374696f6e5f76657273696f6e5f312b1a6578745f73746f726167655f726561645f76657273696f6e5f312c1e6578745f616c6c6f6361746f725f6d616c6c6f635f76657273696f6e5f312d1c6578745f616c6c6f6361746f725f667265655f76657273696f6e5f312e256578745f63727970746f5f656432353531395f67656e65726174655f76657273696f6e5f312f376578745f63727970746f5f736563703235366b315f65636473615f7265636f7665725f636f6d707265737365645f76657273696f6e5f3130256578745f63727970746f5f737232353531395f67656e65726174655f76657273696f6e5f3131286578745f63727970746f5f737232353531395f7075626c69635f6b6579735f76657273696f6e5f3132216578745f63727970746f5f737232353531395f7369676e5f76657273696f6e5f31330c5f5f727573745f616c6c6f63340a5f5f72675f616c6c6f63350e5f5f727573745f6465616c6c6f63360c5f5f72675f6465616c6c6f63370e5f5f727573745f7265616c6c6f63380c5f5f72675f7265616c6c6f6339135f5f727573745f616c6c6f635f7a65726f65643a115f5f72675f616c6c6f635f7a65726f65643b09686173685f746573743c33616c6c6f633a3a616c6c6f633a3a68616e646c655f616c6c6f635f6572726f723a3a68353163623932333763613366353463663d08727573745f6f6f6d3e34616c6c6f633a3a7261775f7665633a3a63617061636974795f6f766572666c6f773a3a68636633313064393836323166623433303f29636f72653a3a70616e69636b696e673a3a70616e69633a3a683030363437306536303862656439353040673c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c26542c636f72653a3a736c6963653a3a497465723c543e3e3e3a3a737065635f657874656e643a3a68663630333566303732643235353538394125616c6c6f633a3a666d743a3a666f726d61743a3a68353162646564663733633836333235354236636f72653a3a70616e69636b696e673a3a70616e69635f626f756e64735f636865636b3a3a68393562303464643938363539313862364323636f72653a3a666d743a3a77726974653a3a68303831356161306566383061653962354448616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303037343834663462386361636666364548616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a7b7b636c6f737572657d7d3a3a68303135633362643336363064376362304633636f72653a3a6f7074696f6e3a3a6578706563745f6e6f6e655f6661696c65643a3a6836383432633035363039613131616134473a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6862356535663530653539386135316130483b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6834383533323037383764313363643164493a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68323565373337646265363866313463314a41616c6c6f633a3a7665633a3a5665633c543e3a3a737761705f72656d6f76653a3a6173736572745f6661696c65643a3a68633031623332663963663337653963314b4e636f72653a3a666d743a3a6e756d3a3a696d703a3a3c696d706c20636f72653a3a666d743a3a446973706c617920666f72207533323e3a3a666d743a3a68663135303861353562323463646664644c2d636f72653a3a70616e69636b696e673a3a70616e69635f666d743a3a68313231656364656237656134313664664d3c616c6c6f633a3a7665633a3a5665633c543e3a3a696e736572743a3a6173736572745f6661696c65643a3a68613934373131623037663536363065634e3c616c6c6f633a3a7665633a3a5665633c543e3a3a72656d6f76653a3a6173736572745f6661696c65643a3a68303739623034626265643466336234324f3f616c6c6f633a3a7665633a3a5665633c543e3a3a647261696e3a3a656e645f6173736572745f6661696c65643a3a6835643131373130356238363638376435504b3c616c6c6f633a3a7665633a3a5665633c75383e20617320636f72653a3a636f6e766572743a3a46726f6d3c267374723e3e3a3a66726f6d3a3a68386463303336393566373236363031305139636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653a3a63616c6c5f6f6e63653a3a6862393936313139646531313231346565522f636f72653a3a666d743a3a6e756d3a3a696d703a3a666d745f7536343a3a68366533616365353734346466643033645311727573745f626567696e5f756e77696e64542b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a683031343036616161383432343565306555313c5420617320636f72653a3a616e793a3a416e793e3a3a747970655f69643a3a68303661353130333961616237383235345635636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a68653932373262646363616336306465615743636f72653a3a666d743a3a466f726d61747465723a3a7061645f696e74656772616c3a3a77726974655f7072656669783a3a68643738323237356538303230633037345834636f72653a3a736c6963653a3a736c6963655f696e6465785f6c656e5f6661696c3a3a68313938373562666436383834646638635936636f72653a3a736c6963653a3a736c6963655f696e6465785f6f726465725f6661696c3a3a68316465333637626133373764636538645a2c636f72653a3a666d743a3a466f726d61747465723a3a7061643a3a68313636656363363539373163643363635b2e636f72653a3a7374723a3a736c6963655f6572726f725f6661696c3a3a68623233363366646233303032316536665c323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68383435353735636630376666363164325d4a3c636f72653a3a6f70733a3a72616e67653a3a52616e67653c4964783e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68353536393033316138643865383531325e323c6368617220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68376161336631343238396430386261365f47636f72653a3a756e69636f64653a3a756e69636f64655f646174613a3a6772617068656d655f657874656e643a3a6c6f6f6b75703a3a68613835323132396535396333363565616032636f72653a3a756e69636f64653a3a7072696e7461626c653a3a636865636b3a3a68393165333839386434396631656236396149636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207573697a653e3a3a666d743a3a683236383537666231363037623539353362453c636f72653a3a63656c6c3a3a426f72726f774572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a683065623838643135356633303964303763483c636f72653a3a63656c6c3a3a426f72726f774d75744572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862333335646536383631323063633233642e636f72653a3a6f7074696f6e3a3a6578706563745f6661696c65643a3a683633646465376666396462376438623465303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686230333265336361626166646339613166323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683061643362663132396338323533363767533c636f72653a3a666d743a3a6275696c646572733a3a5061644164617074657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6836306236656363373161626162353536682e636f72653a3a736c6963653a3a6d656d6368723a3a6d656d6368723a3a6832336130393365346464623739333531693a636f72653a3a666d743a3a6275696c646572733a3a44656275675374727563743a3a6669656c643a3a68663330616534613631356331363839626a2f636f72653a3a666d743a3a57726974653a3a77726974655f636861723a3a68356261336366363138313565373762666b2e636f72653a3a666d743a3a57726974653a3a77726974655f666d743a3a68663435363732306637616333343265356c3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68383834636237333035363965623265616d3b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a68656433643766613065316262373331326e3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68666434323965346239656338393933366f39636f72653a3a666d743a3a6275696c646572733a3a44656275675475706c653a3a6669656c643a3a68613533333665666163353734656238627037636f72653a3a666d743a3a6275696c646572733a3a44656275675365743a3a656e7472793a3a686637353538653961373662616632373071443c636f72653a3a666d743a3a417267756d656e747320617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683362303935626162663933396632636272313c73747220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6862306565323536613538376662373638738001636f72653a3a7374723a3a7472616974733a3a3c696d706c20636f72653a3a736c6963653a3a536c696365496e6465783c7374723e20666f7220636f72653a3a6f70733a3a72616e67653a3a52616e67653c7573697a653e3e3a3a696e6465783a3a7b7b636c6f737572657d7d3a3a68376438313835366161663932613237397427636f72653a3a7374723a3a66726f6d5f757466383a3a6830613066313562666632633634383831753e3c636f72653a3a666d743a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a686130313939333562376233613364346576693c6672616d655f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6836633839313338393962326465613731776c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a683131636162386431306239626630303878493c616c6c6f633a3a7665633a3a5665633c75383e206173207061726974795f7761736d3a3a696f3a3a57726974653e3a3a77726974653a3a686538303463366336346431303063636479693c6672616d655f6d657461646174613a3a4465636f6465446966666572656e743c422c4f3e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68326335306536343564623663653564667a483c5b545d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a68633561613262653264646332633533397b513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a68366331646231303461373464363865327c3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a68336662333236333863616364353236377d3b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a68363239653634316237613866396631307e3a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a68653539373662636463313735623361617f503c6672616d655f737570706f72743a3a64656275673a3a57726974657220617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a683864616337306630633162323838346580014d3c6672616d655f737570706f72743a3a64656275673a3a52756e74696d654c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a68386236316431323364646263636566388101493c6672616d655f737570706f72743a3a64656275673a3a52756e74696d654c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a68353338633737353131616136353964338201323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a68333439613737636530353865613237308301383c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a656e61626c65643a3a68633239643832333162626531343461648401343c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a6c6f673a3a68373561656236636535666332353064388501363c6c6f673a3a4e6f704c6f67676572206173206c6f673a3a4c6f673e3a3a666c7573683a3a6832333664393961633239333539356465860137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830306233616230316365303566353762870137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830313138336261353330663735376166880137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830313539356333616532386461336132890137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68303938313666656635363836373464348a0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306130376261626533643332346335328b0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306233646536613136313166646435308c0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306265633839663034633230333335368d0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68306565346266623164666664633131398e0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68313833636462623733303532343237358f0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831633138383230343530626239653433900137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831636632633661666363653535343962910137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831643436663636626232336533383666920137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832303637333966373536346132336662930137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832346536633636363337653535393631940137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832616634616331623438646438396664950137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6832653933356538333434386234303034960137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6833383237316431623266633831663666970137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6834303333643664613139306665626463980137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6834383232383630643736613163353732990137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68346362313561313938626162373534339a0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68353937376632376461343466386164359b0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68356561396138313961356231613439619c0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68363439363836303666353664613035669d0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68373535626135646537663936313539659e0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a68383365633066633261353739653164329f0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6838363836623239313566613066333130a00137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6839353032353630636139636166623661a10137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6839383265313132666366646234303661a20137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6862363539333836366361323837653837a30137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6862383861646232303966323232656231a40137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6864616238346263393430363538613437a50137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6865623161653131333435316565643934a60137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6865663038666639336337353237303066a70137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6866303862623863643834643632396636a80137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6866306631373136336237626238303865a90137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6866363864656237353365313461663162aa0137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6866663363303663636265343764333434ab013b70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7265776172645f62795f6964733a3a6864636139643036343738323164633830ac01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834313139373062343437616531373362ad015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833333833633533663066646563643133ae01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862353832613638383661383164353732af014b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6839663061363539663838363338616262b001723c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6865323164343931373636326632646637b101613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6861356134346131616263636163636231b201706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6863663737636432363464396364633937b301706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6866346136633935396164626166363165b4015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831653164393839653161396135636530b5015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831666665373833303935306535353935b6015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832366334363936643039313539383762b7015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839396664303737346630666363383262b8015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862363264353235666237303932376562b9015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864376231326534373839353535313930ba015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864643435393335393231646238356666bb01746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a6866303330336532366636323661626533bc01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864616163323265636339303261363938bd015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831343835353666343531396234366532be015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863366366353362303065386236633237bf013570616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6e65775f6572613a3a6838363865613135646461396139356263c001386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831663165396231656266303064373036c1014370616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a636c6561725f6572615f696e666f726d6174696f6e3a3a6864633566356431343030633634663137c2017c3c73705f72756e74696d655f696e746572666163653a3a706173735f62793a3a436f6465633c543e2061732073705f72756e74696d655f696e746572666163653a3a706173735f62793a3a506173734279496d706c3c543e3e3a3a66726f6d5f6666695f76616c75653a3a6838333637393936366666373735343431c301543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6833643235366261663161383635393630c4016b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6835626539633733323632656564623437c501860170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7374616b696e673a3a4578706f737572653c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6862373263363130643764383364653562c601303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830356263646666653963363038383638c7018b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835343634353665383630663135313332c8014e70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a736c61736861626c655f62616c616e63655f6f665f766f74655f7765696768743a3a6834313166656532323136366431613466c901533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6837623066653764653564346663623934ca012573705f70687261676d656e3a3a656c6563743a3a6866333332326333306366633538383839cb014473705f70687261676d656e3a3a41737369676e6d656e743c4163636f756e7449642c543e3a3a696e746f5f7374616b65643a3a6830373431333861393335346132663361cc013173705f70687261676d656e3a3a6275696c645f737570706f72745f6d61703a3a6861333435313631653635393138303863cd01513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6839353934343839393133303633336265ce01706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6832353738303831353236383565323662cf01723c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6833386432653937633831393637393337d0012d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6865623630613835366464666230666437d101706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6834613934623137323135656561356361d201386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833386539373537643037376334383863d301706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6837316633396462396563613464666338d401416672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6576656e745f696e64657865643a3a6835346130353631613439363261623365d501386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830306464643131313032633630666435d601386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839393762383537626662636237363433d701386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862333265356161663330663030663162d8013770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746172745f6572613a3a6862363233363862303235626162646133d901386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839303237343363373866363065363637da01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862303837626538313962323139383562db014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6865363264373431313561666261666230dc015c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833316130313665656135376230336162dd01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863373031383135303633303237353534de013570616c6c65745f7374616b696e673a3a736c617368696e673a3a646f5f736c6173683a3a6839316164393039633461386266393130df01446672616d655f737570706f72743a3a7472616974733a3a43757272656e63793a3a7265736f6c76655f6372656174696e673a3a6837366665613630346362386236313466e0014873705f72756e74696d653a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3a3a696e746f5f6163636f756e743a3a6830633633383531633435626139366235e1014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6833653833343163646234376638656165e201713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6837303032646133353961356264666234e3013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6834643530636536383061383537613339e4013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a656e737572655f6e65775f6572613a3a6830393732666433646632643436643261e501386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831356536346137356531373461323034e6013e70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863363264663833376135313732656632e701723c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637453746f7261676556657273696f6e3c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833336135666263633530626133303430e801753c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374457261456c656374696f6e5374617475733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862333831326230663835386563666334e9016d3c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563745370616e536c6173683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865346430383431333761653038643161ea013c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6866383035616566303437346163313730eb01723c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637445726173546f74616c5374616b653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835326435363136643765613563383631ec01743c70616c6c65745f7374616b696e673a3a5f5f4765744279746553747275637445726173526577617264506f696e74733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836653530663432343764373132653937ed01763c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563744572617356616c696461746f7250726566733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835323234373938363964373462356662ee01763c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374457261735374616b657273436c69707065643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863303930616637366532613763363534ef01793c70616c6c65745f7374616b696e673a3a5f5f476574427974655374727563744d696e696d756d56616c696461746f72436f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862343734326261636139373865353332f001703c70616c6c65745f7374616b696e673a3a5f5f47657442797465537472756374486973746f727944657074683c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834376231663234316131333837383530f1014170616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a7072655f64697370617463685f636865636b733a3a6830376139616237313539316231303132f201386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861653030333130303931663063613330f3014770616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6866333435643531316437306262313931f4019b013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426f6e64696e674475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862333038356136333062623933653730f5019a013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53657373696f6e7350657245726144656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861303430396462303330346461356163f6016c3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c753132383e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6864363635653835623335616132663537f7018e0170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e3e3a3a656e636f64655f746f3a3a6837313136666235333362323266656661f8018b0170616c6c65745f7374616b696e673a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e3e3a3a6465636f64653a3a6863353762383663653866656635353130f90137616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6831353437633033383734353136373230fa012b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6830343835653435366166613339343432fb015b70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c41636375726163793e3a3a66726f6d5f61737369676e6d656e743a3a6838383732373863613233333934396261fc01ba013c70616c6c65745f7374616b696e673a3a53746173684f663c543e2061732073705f72756e74696d653a3a7472616974733a3a436f6e766572743c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3e3a3a636f6e766572743a3a6830616638363432323131623162326637fd01f3013c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e2061732073705f7374616b696e673a3a6f6666656e63653a3a4f6e4f6666656e636548616e646c65723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c283c542061732070616c6c65745f73657373696f6e3a3a54726169743e3a3a56616c696461746f7249642c3c542061732070616c6c65745f73657373696f6e3a3a686973746f726963616c3a3a54726169743e3a3a46756c6c4964656e74696669636174696f6e293e3e3a3a6f6e5f6f6666656e63653a3a6832656633633339663131363538393637fe01386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863346231663334366631316233376163ff014a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a683330303135333935663033353664653280024970616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a6572615f7370616e3a3a686637666534373739663439626634366481024470616c6c65745f7374616b696e673a3a736c617368696e673a3a536c617368696e675370616e733a3a656e645f7370616e3a3a686131613338303033663362343434323582023570616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a64697361626c653a3a683662663838313764666333626235666183025e70616c6c65745f7374616b696e673a3a736c617368696e673a3a496e7370656374696e675370616e733c543e3a3a636f6d706172655f616e645f7570646174655f7370616e5f736c6173683a3a68356662646462613166316638626462648402d3023c70616c6c65745f7374616b696e673a3a4578706f737572654f663c543e2061732073705f72756e74696d653a3a7472616974733a3a436f6e766572743c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c70616c6c65745f7374616b696e673a3a4578706f737572653c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c3c542061732070616c6c65745f7374616b696e673a3a54726169743e3a3a43757272656e6379206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a42616c616e63653e3e3e3e3a3a636f6e766572743a3a68366165633732636137343538356537328502386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a686561373263643463313939383833653786026a636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4f6e63653c413e20666f7220266d757420463e3a3a63616c6c5f6f6e63653a3a68646461313137386666616564376263308702493c70616c6c65745f7374616b696e673a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68643538653432356363326333303736388802623c70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c573e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686230643338376132663535346235633589025a3c70616c6c65745f7374616b696e673a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68376139646535393235356236623761378a024373705f696f3a3a73746f726167653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a726561643a3a68356631316666663034633234346237368b025a3c70616c6c65745f696e64696365733a3a4d6f64756c653c543e2061732073705f72756e74696d653a3a7472616974733a3a5374617469634c6f6f6b75703e3a3a6c6f6f6b75703a3a68363637616632356366663931613162338c025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68383836343239393966323134653135358d02336672616d655f73797374656d3a3a4d6f64756c653c543e3a3a696e635f7265663a3a68306235396665366132366334643530398e025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68643639653335623838326465313837368f02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a683133333464633934343966353631313390028d013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f6c6f636b3a3a683337623739646161613263303430633691023870616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6b696c6c5f73746173683a3a6864326365663735666432363461363533920290013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a72656d6f76655f6c6f636b3a3a683739616636313835633566656230373793024870616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a636865636b5f616e645f7265706c6163655f736f6c7574696f6e3a3a68303831346461353136633534306661369402746672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6765743a3a683132666433336539326564633833363395025273705f61726974686d657469633a3a7065725f7468696e67733a3a50657262696c6c3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a686630666536323262646132323831626696023970616c6c65745f7374616b696e673a3a4d6f64756c653c543e3a3a6d616b655f7061796f75743a3a68303632316136623964616133663734649702386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68383837653464393332303634306330329802437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68373261376638666436643338303831359902336672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465635f7265663a3a68373363386664363463323763653433389a02b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a68343864623564623262323538663163329b025b70616c6c65745f7374616b696e673a3a47656e65726963436f6d7061637441737369676e6d656e74733c562c542c41636375726163793e3a3a696e746f5f61737369676e6d656e743a3a68633432613962666466633334363131399c02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a68363663616538386266323333613932329d02633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a68663239656236333235643336633234649e02613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a68623532636466636630306166373430639f025f3c70616c6c65745f7374616b696e673a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6831316434303430363132373532383830a002613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6839396432663639626232396434363662a1024470616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a646f5f70687261676d656e3a3a6832313836663665366438613036636565a202386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6865363430383138323931386434353163a3028b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6839343366613839663730633763623066a402443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6830646335343235663931366265336535a502633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a6838363764336163343130306534396663a6024d6672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a636f6d707574655f6d656d626572735f646966663a3a6839353666666563636639663165616533a70299013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6834656335643432313562353635623333a802b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6831373338623865633332343562373765a902437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830396535326137613665323663643336aa02543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6831663262353933303961386238636532ab022e73705f70687261676d656e3a3a7265647563653a3a7265647563653a3a6866613839333933386335633064303363ac0248616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a456e7472793c4b2c563e3a3a6f725f696e736572743a3a6832363936366166363363626338383663ad023373705f70687261676d656e3a3a6e6f64653a3a4e6f64653c413e3a3a726f6f743a3a6832313162326230633165643831393031ae022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6837646430346163656532393739306635af023b73705f70687261676d656e3a3a6e6f64653a3a4e6f64653c413e3a3a69735f706172656e745f6f663a3a6838656537333833373639333435636461b002b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6866633538393636646663356335623934b102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830303663376135636264323163623164b202386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830346365656166336533313736373839b302386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6830396164366265643431623365333866b402386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831326238663365323232373534313765b502386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831353138626163323830343836383939b602386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831626530663065356638343261306131b702386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6831666234306230623362313530353464b802386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832383436613537373538383536313062b9026b6e6f64655f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a6465636f64653a3a6833303331316332393734623531313537ba022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6837626530343537633261323562366639bb022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6837626530343537633261323562366639bc02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6832653466383037646162323536646363bd02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833326362393833393534356432663763be02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833353064666630323434646466666339bf02850170616c6c65745f736f63696574793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f736f63696574793a3a4269644b696e643c4163636f756e7449642c42616c616e63653e3e3a3a6465636f64653a3a6866313235363563313165623962613634c002386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833626365633832626135653635626530c102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6833666539333037396566343139363235c202726e6f64655f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72206e6f64655f72756e74696d653a3a53657373696f6e4b6579733e3a3a6465636f64653a3a6839353939313966326534633236316632c302386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834336466636238346637343730653239c402386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6834623236373432613535373633633038c502386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835343638336563333961313639613737c602386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6835346432346363353461363437383562c702960173705f7374616b696e673a3a6f6666656e63653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f7374616b696e673a3a6f6666656e63653a3a4f6666656e636544657461696c733c5265706f727465722c4f6666656e6465723e3e3a3a6465636f64653a3a6831653765323661336635613461383461c8022b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6836646335333530646333613065383137c902386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836353263323130333635656163303636ca028f0170616c6c65745f64656d6f63726163793a3a766f74653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f64656d6f63726163793a3a766f74653a3a4163636f756e74566f74653c42616c616e63653e3e3a3a6465636f64653a3a6861633539363439666333356636393939cb02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836363464646364623162396564333038cc02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6836623833306538313430383264633566cd02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6837363362306534326565313733363539ce02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838316166653732346534303035396535cf02543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6866306166393161396338646231373539d002386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838336538616661363836613730363065d102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6838613564366633633165316665663834d202386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839313063323861313964653537386663d302386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6839396663356535633130633832633832d402386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6861393462353839616266346234666435d5026b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7533323e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6833336365616132373739326638656135d602573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861333165363237333335636235633762d702386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862373538343730653262376463373837d802386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6862373632303636666338356631393438d902386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863303639643361393036623066636437da02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863306130653734346233653862646133db027770616c6c65745f636f6e7472616374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f636f6e7472616374733a3a5363686564756c653e3a3a6465636f64653a3a6863336630356437396561363133623233dc02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863373162373832383237366363303838dd02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863376530396264636637353036363634de02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6863643332333865303439386236333131df02386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864323832313030306333376432366536e002386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864613738363534623466316330353965e102386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6864626232653333663964366537343837e202386672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a6765743a3a6866633435643532643461343937393632e302396672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6832386461633638616133626338393631e402396672616d655f737570706f72743a3a73746f726167653a3a756e6861736865643a3a74616b653a3a6835343632383862373566316635383163e5025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6839323562306339353930386331613735e60285013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a43757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7472616e736665723a3a6864343663333266353861633533633431e7024a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6835343932373162623464663939613461e80293013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a436f6e7461696e733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a736f727465645f6d656d626572733a3a6838383335633266313832663030666466e9024270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a69735f6d656d6265723a3a6838643735333232303465643539303231ea0290013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4c6f636b61626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a657874656e645f6c6f636b3a3a6834623132343665623938396134326233eb023670616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6c6f636b733a3a6862303366643032636131623430623863ec023d70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a7570646174655f6c6f636b733a3a6836613463346231616439316536393666ed025c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864303533343130383539663065303032ee02483c5b543b20385d206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6832666363313466303830323838336630ef029a013c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a52657365727661626c6543757272656e63793c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a726570617472696174655f72657365727665643a3a6863333161396136356539393537383538f002b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6862616238343766663637326630623339f1023f70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6866326461336234333831366166653936f2024170616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6837646666346166316365353262303238f3026e3c70616c6c65745f62616c616e6365733a3a5f5f476574427974655374727563744163636f756e743c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836323038326136323863393464373639f4024a70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6863343165313633613436316538663061f5024770616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835346438633035363837303735643862f6024970616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6836396330346162666638316161386364f702753c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a5f5f47657442797465537472756374566f74696e673c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865626363316535343431303637353433f8023c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6837383031373637633031366335316135f9025270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6838313061353662383030333963326362fa029f013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6f64756c65496444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865303833336237356336313633386666fb02a3013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5465726d4475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864326263376435386134663365643564fc02a7013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4465736972656452756e6e657273557044656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866343038326364626630333661633336fd02a5013c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a446573697265644d656d6265727344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830313564663038333234636630656564fe02fa01616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a48616e646c653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4e6f64655265663c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4d75742c4b2c562c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4c6561663e2c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a456467653e3a3a696e736572743a3a6862306530653564613066326339353763ff02fe01616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a48616e646c653c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a4e6f64655265663c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a4d75742c4b2c562c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a496e7465726e616c3e2c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6e6f64653a3a6d61726b65723a3a456467653e3a3a696e736572743a3a683566643663326365336639623734356380034b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a68393330616266633430343738623461348103613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a686462393761386332663332663562333282034b616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a566163616e74456e7472793c4b2c563e3a3a696e736572743a3a6837653937333561643437646535376431830348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6836643136353039383966373231353561840348616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a686632643433303933666533653030626385034c3c70616c6c65745f62616c616e6365733a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68386130383931393238383833643463618603543c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a686139666231633135666162666562653987035d3c70616c6c65745f62616c616e6365733a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68613035613537306163393530303263358803623c70616c6c65745f62616c616e6365733a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68626136396533323639643933633430328903653c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68356432326632396564343834633936378a03393c54206173206672616d655f737570706f72743a3a7472616974733a3a4c656e3e3a3a6c656e3a3a68396633306466656136386663646331328b03393c54206173206672616d655f737570706f72743a3a7472616974733a3a4c656e3e3a3a6c656e3a3a68613034306564333636643737613766338c03b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a68303235326339343361363263386331338d03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68353335303433356532306162393531398e035270616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e3a3a72656d6f76655f616e645f7265706c6163655f6d656d6265723a3a68323036303636626432356466343566348f03613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a496e746f497465723c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a683236656435323766326637666531656590036a3c70616c6c65745f656c656374696f6e735f70687261676d656e3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68343737393833333664393536623737639103456672616d655f737570706f72743a3a7472616974733a3a5369676e6564496d62616c616e63653c422c503e3a3a6d657267653a3a683565373432613166323763623765333592033c70616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683165373139393235373033613539363593033e70616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68366264613134316162616566633165619403437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68303962653065306334356236326338349503437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68313632316364613131363533373363309603437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68326333323665666639333932303766349703437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68383731393832336466356432353338329803437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a686131346166366162663430333231363999034a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68366631633135393734643031633335389a03493c70616c6c65745f7574696c6974793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663462306134316331353163626234619b03493c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68333736613635376637383866316639642e323036329c03443c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68333736613635376637383866316639649d03473c6672616d655f73797374656d3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68663532646138393065373263323462399e03443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68633634343962653363613331313336399f03443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6864323032313031353031396634303934a0034b3c70616c6c65745f64656d6f63726163793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6838666336653532613337343966636361a1034e3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6861623763636361336138303334346538a2034e3c70616c6c65745f6d656d626572736869703a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832636337346331373936626566666335a3034a3c70616c6c65745f74726561737572793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6863623639343032643235386531626236a4034b3c70616c6c65745f636f6e7472616374733a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6834346537393330616533373636613663a503463c70616c6c65745f7375646f3a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6864353065613531666464656538623564a603443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836306663313039343964343862333534a703463c70616c6c65745f626162653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836623738656336353333316431343666a8034a3c70616c6c65745f6964656e746974793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836623362396564656461313531303039a9034b3c70616c6c65745f736f63696574793a3a43616c6c3c542c493e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831633536343162356636303762326231aa034a3c70616c6c65745f7265636f766572793a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6836336537623530653866326531366634ab035a3c70616c6c65745f7574696c6974793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6832653138653265666336356565663837ac03553c6e6f64655f72756e74696d653a3a43616c6c2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6830386530613933623532393731393261ad034670616c6c65745f7574696c6974793a3a4d6f64756c653c543e3a3a656e737572655f736f727465645f616e645f696e736572743a3a6835383039313964346538363430666266ae03437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6861613162323539663533333232333564af036e6e6f64655f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a43616c6c3e3a3a656e636f64655f746f3a3a6839326661326535376432653361363236b003706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6834353039326334313066366132323361b103463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6832353936316464316532343531396566b2035f3c70616c6c65745f7574696c6974793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6863653832363264636461653031313665b3030c436f72655f76657273696f6eb4036b3c73705f72756e74696d653a3a72756e74696d655f737472696e673a3a52756e74696d65537472696e67206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6830353936316638653965663866343037b50312436f72655f657865637574655f626c6f636bb6039a0173705f72756e74696d653a3a67656e657269633a3a626c6f636b3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f72756e74696d653a3a67656e657269633a3a626c6f636b3a3a426c6f636b3c4865616465722c45787472696e7369633e3e3a3a6465636f64653a3a6836633664366533643238323565383166b70384016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65732c434f6e52756e74696d65557067726164653e3a3a696e697469616c697a655f626c6f636b3a3a6838393534336262666334333534303062b8035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838636465383435303864653034626362b9033e73705f72756e74696d653a3a67656e657269633a3a656e636f64655f776974685f7665635f7072656669783a3a6836616639306563633236343262396566ba035373705f696f3a3a747269653a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a626c616b65325f3235365f6f7264657265645f726f6f743a3a6838626166303166646138346239643638bb038c016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65732c434f6e52756e74696d65557067726164653e3a3a6170706c795f65787472696e7369635f776974685f6c656e3a3a6837626533313430336232346436353961bc03446672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6e6f74655f66696e69736865645f65787472696e736963733a3a6834663565633735623365366462643935bd03713c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e46696e616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f66696e616c697a653a3a6837356431383837323432663037626232be03346672616d655f73797374656d3a3a4d6f64756c653c543e3a3a66696e616c697a653a3a6834306363643339316338633733393866bf03467061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a436f646553656374696f6e3a3a626f646965733a3a6865666236393637346665636463336532c0036f3c73705f72756e74696d653a3a67656e657269633a3a6469676573743a3a4469676573744974656d3c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6861653631333134316431633734656430c103363c5420617320636f72653a3a636f6e766572743a3a496e746f3c553e3e3a3a696e746f3a3a6831653531663063306165653439623266c203303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832333239626366396430636261636135c30315436f72655f696e697469616c697a655f626c6f636bc403723c73705f72756e74696d653a3a67656e657269633a3a6865616465723a3a4865616465723c4e756d6265722c486173683e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6836353732656635373330626338323535c503114d657461646174615f6d65746164617461c603d9053c6e6f64655f72756e74696d653a3a52756e74696d652061732073705f6170693a3a72756e74696d655f6465636c5f666f725f4d657461646174613a3a4d657461646174613c73705f72756e74696d653a3a67656e657269633a3a626c6f636b3a3a426c6f636b3c73705f72756e74696d653a3a67656e657269633a3a6865616465723a3a4865616465723c7533322c73705f72756e74696d653a3a7472616974733a3a426c616b6554776f3235363e2c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c3c70616c6c65745f696e64696365733a3a4d6f64756c653c6e6f64655f72756e74696d653a3a52756e74696d653e2061732073705f72756e74696d653a3a7472616974733a3a5374617469634c6f6f6b75703e3a3a536f757263652c6e6f64655f72756e74696d653a3a43616c6c2c73705f72756e74696d653a3a4d756c74695369676e61747572652c286672616d655f73797374656d3a3a436865636b56657273696f6e3c6e6f64655f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b47656e657369733c6e6f64655f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b4572613c6e6f64655f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b4e6f6e63653c6e6f64655f72756e74696d653a3a52756e74696d653e2c6672616d655f73797374656d3a3a436865636b5765696768743c6e6f64655f72756e74696d653a3a52756e74696d653e2c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4368617267655472616e73616374696f6e5061796d656e743c6e6f64655f72756e74696d653a3a52756e74696d653e293e3e3e3e3a3a6d657461646174613a3a6839373832303465333938323838636637c7031c426c6f636b4275696c6465725f6170706c795f65787472696e736963c8039c013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838633366316637643336313964326631c903aa0173705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a5472616e73616374696f6e56616c69646974794572726f723e3a3a656e636f64655f746f3a3a6837616630643436316630373732653336ca031b426c6f636b4275696c6465725f66696e616c697a655f626c6f636bcb035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6864666365313231316532383232373936cc0320426c6f636b4275696c6465725f696e686572656e745f65787472696e73696373cd036f3c636f72653a3a697465723a3a61646170746572733a3a526573756c745368756e743c492c453e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a6837383030326161646637346638343330ce033a70616c6c65745f74696d657374616d703a3a657874726163745f696e686572656e745f646174613a3a6831316537336434343339363134626430cf03543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6837393561656339316661343637336666d003437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6862316366653033333662363463663133d103366672616d655f73797374656d3a3a4d6f64756c653c543e3a3a626c6f636b5f686173683a3a6834616266626433393131633436333032d2031c426c6f636b4275696c6465725f636865636b5f696e686572656e7473d303453c737472206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6866613461623063393161366331636337d40318426c6f636b4275696c6465725f72616e646f6d5f73656564d50390013c70616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a52616e646f6d6e6573733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a486173683e3e3a3a72616e646f6d3a3a6830663032613736303538393733646663d6032b5461676765645472616e73616374696f6e51756575655f76616c69646174655f7472616e73616374696f6ed7039f013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073705f72756e74696d653a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a6832323837393033373663643437333663d803653c6e6f64655f72756e74696d653a3a43616c6c206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a6834646464643866306463633231393133d9035373705f72756e74696d653a3a7472616e73616374696f6e5f76616c69646974793a3a56616c69645472616e73616374696f6e3a3a636f6d62696e655f776974683a3a6835303633363533356261326534313839da03436672616d655f73797374656d3a3a436865636b5765696768743c543e3a3a636865636b5f626c6f636b5f6c656e6774683a3a6839616436343133613033373137376362db034570616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a636f6d707574655f6665653a3a6866373362323964633264663765616638dc03b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6863313236303339373534623933336233dd036b3c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e2061732073705f72756e74696d653a3a7472616974733a3a56616c6964617465556e7369676e65643e3a3a76616c69646174655f756e7369676e65643a3a6837336534646664383430316138633162de03214f6666636861696e576f726b65724170695f6f6666636861696e5f776f726b6572df0386016672616d655f6578656375746976653a3a4578656375746976653c53797374656d2c426c6f636b2c436f6e746578742c556e7369676e656456616c696461746f722c416c6c4d6f64756c65732c434f6e52756e74696d65557067726164653e3a3a657874726163745f7072655f6469676573743a3a6833633036653934333837323364316438e003366672616d655f73797374656d3a3a4d6f64756c653c543e3a3a696e697469616c697a653a3a6862353039623233376562656265333134e1035173705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7075626c69635f6b6579733a3a6836343533373533326262646661653531e20347636f72653a3a666d743a3a6e756d3a3a3c696d706c20636f72653a3a666d743a3a446562756720666f72207533323e3a3a666d743a3a6831633835623037353066633565353230e303633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6862353438336361646236356530656662e403583c70616c6c65745f696d5f6f6e6c696e653a3a4f6666636861696e4572723c426c6f636b4e756d6265723e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863623733323834383634623336613164e5033c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6830336530383365663037633565323135e6034f70616c6c65745f7374616b696e673a3a6f6666636861696e5f656c656374696f6e3a3a636f6d707574655f6f6666636861696e5f656c656374696f6e3a3a6837366430386564363432653765616166e7031e4772616e6470614170695f6772616e6470615f617574686f726974696573e803543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6838616534643735326134636663633836e90315426162654170695f636f6e66696775726174696f6eea031b426162654170695f63757272656e745f65706f63685f7374617274eb0321417574686f72697479446973636f766572794170695f617574686f726974696573ec031d4163636f756e744e6f6e63654170695f6163636f756e745f6e6f6e6365ed035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6838333634626337663438643432626536ee0311436f6e7472616374734170695f63616c6cef034870616c6c65745f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a63616c6c3a3a6830366364393161376464663131303334f003783c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a6865373930646264376132643939306532f1033a70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a726573746f72655f746f3a3a6835323066363264363537326337656139f20318436f6e7472616374734170695f6765745f73746f72616765f3035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837346439313964636132303135343433f4033470616c6c65745f636f6e7472616374733a3a6368696c645f747269655f696e666f3a3a6832613034653636333861626539363636f5031c436f6e7472616374734170695f72656e745f70726f6a656374696f6ef6033870616c6c65745f636f6e7472616374733a3a72656e743a3a636f6e73696465725f636173653a3a6830303562333937373330646164633432f7033870616c6c65745f636f6e7472616374733a3a72656e743a3a656e6163745f766572646963743a3a6864643361303261343738326136646332f803205472616e73616374696f6e5061796d656e744170695f71756572795f696e666ff9032153657373696f6e4b6579735f67656e65726174655f73657373696f6e5f6b657973fa034e73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a656432353531395f67656e65726174653a3a6861663766653465303739306335326632fb034e73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f67656e65726174653a3a6864343036646464383438353830636663fc031f53657373696f6e4b6579735f6465636f64655f73657373696f6e5f6b657973fd038f0173705f6170706c69636174696f6e5f63727970746f3a3a737232353531393a3a3c696d706c2073705f6170706c69636174696f6e5f63727970746f3a3a7472616974733a3a52756e74696d655075626c696320666f722073705f636f72653a3a737232353531393a3a5075626c69633e3a3a746f5f7261775f7665633a3a6834313030303530383533656362626532fe035c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831393936653735363032656131383631ff033870616c6c65745f626162653a3a4d6f64756c653c543e3a3a646f5f696e697469616c697a653a3a68633338386661663832363234383361628004a30173705f636f6e73656e7375735f626162653a3a646967657374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f636f6e73656e7375735f626162653a3a646967657374733a3a5261775072654469676573743c5652464f75747075742c56524650726f6f663e3e3a3a6465636f64653a3a686130646632326430623236643163656481043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68313165336635633266343039316364398204376672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6465706f7369745f6c6f673a3a686630363362653331366338626237333883047d3c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a686564363866316535633066653734663984047d3c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a683938306661326366633937353864356285047f3c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6833613766373162343832633964306361860481013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6864313439303833363664313538303233870484013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4469726563744163636f756e7444622061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a68623766623738363236663665613963358804b2013c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f737570706f72743a3a7472616974733a3a53746f7265644d61703c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449642c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e74446174613e3e3a3a7472795f6d75746174655f6578697374733a3a6865333236306265366637666530353662890496013c70616c6c65745f636f6e7472616374733a3a54726965496446726f6d506172656e74436f756e7465723c543e2061732070616c6c65745f636f6e7472616374733a3a54726965496447656e657261746f723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a747269655f69643a3a68306430306531353533613839656338638a04437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a68663833616235613935626232353935328b043b70616c6c65745f626162653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68373736396466303265633361353862368c046b3c70616c6c65745f626162653a3a5f5f4765744279746553747275637452616e646f6d6e6573733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68643037353937653665626139643666318d044470616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68613465636330363035336538613934648e049a013c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4578706563746564426c6f636b54696d6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68663132623135316637333065646564318f0496013c70616c6c65745f626162653a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45706f63684475726174696f6e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864303939323866636538356432363165900481013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f62616c616e63653a3a6835346134663936366639613335613333910481013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f73746f726167653a3a6831333761343332373762393038393930920483013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f636f64655f686173683a3a6863363330343066363363346238383664930485013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6e74726163745f6578697374733a3a6861613235386264623031366636323334940488013c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a6765745f72656e745f616c6c6f77616e63653a3a683465633732623862343635643365356195047c3c70616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e2061732070616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4163636f756e7444623c543e3e3a3a636f6d6d69743a3a686139353036663666623136363539363896045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683232353165633664623062396134326397045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683763613265633161393362616636613198043c70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683730393262316634353134333762346199043e70616c6c65745f696e64696365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68663735376536623033353530613163659a04633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a666f6c643a3a68333033316564326565666233343036329b044673705f61726974686d657469633a3a68656c706572735f3132386269743a3a6d756c7469706c795f62795f726174696f6e616c3a3a68393031626331333565356638666566329c04533c73705f61726974686d657469633a3a726174696f6e616c3132383a3a526174696f6e616c31323820617320636f72653a3a636d703a3a4f72643e3a3a636d703a3a68616362613234623435383430376330329d04583c73705f61726974686d657469633a3a726174696f6e616c3132383a3a526174696f6e616c31323820617320636f72653a3a636d703a3a5061727469616c45713e3a3a65713a3a68343232666636626366653836633466619e042d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a68396534323465363362383761366161669f047a3c73705f61726974686d657469633a3a7065725f7468696e67733a3a5065725531362061732073705f61726974686d657469633a3a7065725f7468696e67733a3a5065725468696e673e3a3a66726f6d5f726174696f6e616c5f617070726f78696d6174696f6e3a3a6861383037316235323863656163643538a0045273705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a7375626d69745f7472616e73616374696f6e3a3a6834363464333661636234303335376461a1043d70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6861396537356666336265643832313831a2043f70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865616338323362343237373934623033a3042b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6832393232323238633938316134356636a4044870616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839326137653733326333633064323064a5049a013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d61785265676973747261727344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6861326337656361656162356462383565a6049b013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d61785375624163636f756e747344656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838666537313832346431326331663036a7049e013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5375624163636f756e744465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838633039343264643061663732613163a80499013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4669656c644465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863663461663934613235356665303065a90499013c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a42617369634465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864333333633633656637633635306135aa04820170616c6c65745f6964656e746974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f6964656e746974793a3a4a756467656d656e743c42616c616e63653e3e3a3a656e636f64655f746f3a3a6862343963306633303230306635653635ab047c70616c6c65745f6964656e746974793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f6964656e746974793a3a4964656e74697479496e666f3e3a3a656e636f64655f746f3a3a6832323837376662666234346564353236ac04573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64653a3a6837616237303239366439623865346535ad04573c70616c6c65745f6964656e746974793a3a44617461206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6836373039623532623961643239646633ae045170616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e3a3a7365745f62616c616e63653a3a6863386335363437633837386434663335af045170616c6c65745f636f6e7472616374733a3a6163636f756e745f64623a3a4f7665726c61794163636f756e7444623c543e3a3a7365745f73746f726167653a3a6834343931643963656639383037386463b004437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6839646263306437626664393831653038b1045a3c70616c6c65745f696e64696365733a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6830326163366530316334613661303063b2044a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6832326565616262356163633664323730b3045b3c70616c6c65745f6964656e746974793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a6866633337643032386261626630633739b4043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6837383037623265343638316565666461b5045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865343462623363643664396463353034b6045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6862313338636132333030313665643536b704603c70616c6c65745f6964656e746974793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6835383261646132356362633639623135b8042b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6837356239656266393732333739373237b9043d70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a69735f6f6e6c696e655f6175783a3a6833633636653065386335386366303261ba04706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6865393964373537383363333162663138bb044d73705f696f3a3a6f6666636861696e3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6e6574776f726b5f73746174653a3a6864363436393861636139303262366232bc044a73705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a737232353531395f7369676e3a3a6838643263316630613033363163383862bd04473c70616c6c65745f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839636435616364366236316564356130be04373c285431302c5431312920617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6833323134383937343237336366333637bf04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830363734343637326239636663623838c00496013c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e2061732070616c6c65745f73657373696f6e3a3a4f6e6553657373696f6e48616e646c65723c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6f6e5f6265666f72655f73657373696f6e5f656e64696e673a3a6862396661323234346664313931633363c104443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6865653039373465616162386365386134c2045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834316463613531376539363937633637c304706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6864666564653639646361353935623239c4045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833383837656164613662646236373964c504437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6865376337336564626436393965356639c604443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6835643031373934636661633266383865c7043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6833333966366463656630356665663331c8044b6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a72656769737465725f65787472615f7765696768745f756e636865636b65643a3a6830363637653030653263383333383865c9045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833303063393962386634303565353535ca04693c636f72653a3a697465723a3a61646170746572733a3a46696c7465724d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6866343130663637613761373036356665cb0481016672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a617070656e645f6f725f696e736572743a3a6831343462303635666137353430356262cc04753c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6865353261323135343036663731653664cd04437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830363561373534326135373733623533ce04406672616d655f73797374656d3a3a436865636b5765696768743c543e3a3a646f5f7072655f64697370617463683a3a6863646164363235623432616530386333cf045770616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a7765696768745f746f5f6665655f776974685f61646a7573746d656e743a3a6864313735373932323233353063623536d0043770616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a617574686f723a3a6866393463636564386561313039646364d104563c73705f72756e74696d653a3a44697370617463684572726f722061732073705f72756e74696d653a3a7472616974733a3a5072696e7461626c653e3a3a7072696e743a3a6863346566383637626639386531386236d2043e70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6837626466653761376130393937323932d3043f70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a6e6f74655f617574686f72736869703a3a6836383334633136353461333264623062d4044070616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6861653831363333396361316265383064d5043e70616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6835393730656335653436363337613935d6044070616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6865353864396564363730396166666565d7044970616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6862336631393833396163353133663035d8049b013c70616c6c65745f74696d657374616d703a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833616533613339373230373764306237d9043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6834643932316134343239626133323166da048d0170616c6c65745f7363686564756c65723a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f7363686564756c65723a3a5363686564756c65643c43616c6c2c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6863646237646465323139356636646462db043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6831306436353761386661656266653430dc04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831643133313534366161663930316465dd04303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832356635323932333764633036323530de044b3c70616c6c65745f696d5f6f6e6c696e653a3a43616c6c3c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6832303562383065666232313537653534df04613c70616c6c65745f696d5f6f6e6c696e653a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6866356637323433663232336634336536e0043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f7374723a3a6831616635653663383338626233653235e1043b3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f636861723a3a6861643534346239663235663461656264e2043a3c266d7574205720617320636f72653a3a666d743a3a57726974653e3a3a77726974655f666d743a3a6835366534336430616634633936666337e3043273705f73616e64626f783a3a696d703a3a64697370617463685f7468756e6b3a3a6866376564613431343138656534343638e4047673705f7761736d5f696e746572666163653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722073705f7761736d5f696e746572666163653a3a56616c75653e3a3a6465636f64653a3a6835393366313463636336656639626339e5047973705f7761736d5f696e746572666163653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722073705f7761736d5f696e746572666163653a3a56616c75653e3a3a656e636f64655f746f3a3a6839313534646335623637376664313034e6045273705f73616e64626f783a3a696d703a3a456e7669726f6e6d656e74446566696e6974696f6e4275696c6465723c543e3a3a6164645f686f73745f66756e633a3a6838373336363164663163303463316637e7043f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f65787465726e616c3a3a6836643536353630643663653737303936e8047f70616c6c65745f64656d6f63726163793a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c70616c6c65745f64656d6f63726163793a3a4572726f723c543e3e20666f722073705f72756e74696d653a3a44697370617463684572726f723e3a3a66726f6d3a3a6835326237626330383633613465643362e9044170616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a696e6a6563745f7265666572656e64756d3a3a6834623037666463353162383939383938ea043d70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6c61756e63685f7075626c69633a3a6833633034346631383532336235666139eb043b70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6261636b696e675f666f723a3a6864386130376463356365613739663666ec043c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6863373565363961353434643862303132ed045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6830353866623530366539396665336136ee045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6836323630376138623937616561333436ef049f0170616c6c65745f64656d6f63726163793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a507265696d6167655374617475733c4163636f756e7449642c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6833643935623264323734656539306466f0045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865353132616361303662316134313330f104497061726974795f7363616c655f636f6465633a3a656e636f64655f617070656e643a3a657874726163745f6c656e6774685f646174613a3a6831623937383962616439613065656536f204703c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6830626465626632353966633031623962f3047b6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a6465636f64655f6c656e3a3a6833336433396564623631626530643738f4044170616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a646f5f656e6163745f70726f706f73616c3a3a6864633334633535663465646232656166f5045c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837653263386666386330663931376132f604437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830313931363539336464323665303865f7043c70616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6838663561313062313565616238386461f8043e70616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6839613731373863376632353762646634f9044770616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6864363630313832323364363538663163fa049c013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d696e696d756d4465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839653936343061373563363536663035fb043f70616c6c65745f6f6666656e6365733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6833306633643931663932353732613065fc043e70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6830343063663230333563633164666362fd044070616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6831663536323832656232656537376239fe046f3c70616c6c65745f64656d6f63726163793a3a5f5f47657442797465537472756374426c61636b6c6973743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6864306132616435366164656331653433ff046e3c70616c6c65745f64656d6f63726163793a3a5f5f47657442797465537472756374566f74696e674f663c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686333323734333335646336633331373180053c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a68396131393765386363666230363339338105713c70616c6c65745f64656d6f63726163793a3a5f5f476574427974655374727563745075626c696350726f70733c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683033343339626338313964326538326282054970616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68393236393765383731653465663431618305a1013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a507265696d616765427974654465706f73697444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a686132326330646635646132663032313884059a013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4c61756e6368506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68393231633964636166666239653732398505a3013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a46617374547261636b566f74696e67506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683639393965326138316466656531623586059d013c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a456e6163746d656e74506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a683965633966363866326532613463643387054070616c6c65745f7363686564756c65723a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a683931643066343566313138646535643488053c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a683165633030613065306137323031356189053970616c6c65745f76657374696e673a3a4d6f64756c653c543e3a3a7570646174655f6c6f636b3a3a68306237323332303437353837333333328a055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68353736613565353061386434623762368b055c3c70616c6c65745f64656d6f63726163793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68303234626133366332633361613636348c0582017061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72202850302c51302c5230293e3a3a656e636f64655f746f3a3a68393135336435643966623834353661618d053870616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f766f74653a3a68313064326433636461376361613330618e053570616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a70726f78793a3a68323739353238313538613963653139648f055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68376562323737656265643432336362659005437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683433656363366261643662646365333291055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683635663434326137303864373762616592055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a686131373466313939383037313862396593053c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f64656c65676174653a3a683038363531333431346631363130326194053e70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f756e64656c65676174653a3a68306339343637393337616166396437329505776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a686335346231616266633734653139383896055c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a683638323938316364336131643631353897053f70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7472795f72656d6f76655f766f74653a3a686565663931356636626466383631656198054a70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e3a3a7265647563655f757073747265616d5f64656c65676174696f6e3a3a683064643061373065313139336239386499054a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68363162616132623433303539393361669a055d3c70616c6c65745f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732070616c6c65745f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a68376233376537336562663732363061359b056a3c70616c6c65745f636f6e7472616374733a3a7761736d3a3a5761736d566d2061732070616c6c65745f636f6e7472616374733a3a657865633a3a566d3c543e3e3a3a657865637574653a3a7b7b636c6f737572657d7d3a3a68383534646339396665386631643930339c0581013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6761733a3a68303335303838633964666332303034319d058d013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f73746f726167653a3a68656662643636666432363932376636379e058f013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f636c6561725f73746f726167653a3a68626363646632316562636235653533399f058d013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6765745f73746f726167653a3a6837356265373535653466313263373765a0058a013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7472616e736665723a3a6830643733383935356564303664316230a10586013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c3a3a6862313262663739333865353762393637a2058d013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f696e7374616e74696174653a3a6839656562636264333262376438373839a3058b013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7465726d696e6174653a3a6830373334386163386135373838386364a40588013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72657475726e3a3a6863363638623230373537623538373562a50588013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f63616c6c65723a3a6865386461323932333434376432393864a60589013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f616464726573733a3a6834373335333764656535303064663730a7058b013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f70726963653a3a6836616461373632366133643864306266a8058a013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6761735f6c6566743a3a6833666430316438366336393639306664a90589013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f62616c616e63653a3a6830336533383862613463396637636132aa0593013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f76616c75655f7472616e736665727265643a3a6834646462653665616561396438313866ab0588013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72616e646f6d3a3a6835303266313663336230376132646362ac0585013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6e6f773a3a6863353638323331646463336533373936ad0591013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6d696e696d756d5f62616c616e63653a3a6839326561396436653266353635663632ae0593013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f746f6d6273746f6e655f6465706f7369743a3a6839653962666535396261383662303930af058f013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f64697370617463685f63616c6c3a3a6863643336353634643830633133376164b0058c013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f726573746f72655f746f3a3a6838386534336132646530336464623934b1058e013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f73697a653a3a6837303139636333623961353864393633b2058e013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f726561643a3a6835343832623336393563373937303134b3058f013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f736372617463685f77726974653a3a6839633461373430343739393032623836b4058f013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6465706f7369745f6576656e743a3a6866333961343935306630386338323034b50594013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7365745f72656e745f616c6c6f77616e63653a3a6864306636613538623864636264666338b60590013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f72656e745f616c6c6f77616e63653a3a6838353134653630343839393530346161b70589013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f7072696e746c6e3a3a6862303738623262643435383035343662b8058e013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f626c6f636b5f6e756d6265723a3a6861356662313538373065386461313535b90595013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f6765745f72756e74696d655f73746f726167653a3a6830623930616465383335616464646463ba058f013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f686173685f736861325f3235363a3a6866356635646634623262393263656439bb0591013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f686173685f6b656363616b5f3235363a3a6837666539323932666233353837643334bc0591013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f686173685f626c616b65325f3235363a3a6832366432373238613734623064663831bd0591013c70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a456e762061732070616c6c65745f636f6e7472616374733a3a7761736d3a3a656e765f6465663a3a46756e6374696f6e496d706c50726f76696465723c453e3e3a3a696d706c733a3a6578745f686173685f626c616b65325f3132383a3a6836353664656638373130303166336330be053e70616c6c65745f636f6e7472616374733a3a7761736d3a3a72756e74696d653a3a6368617267655f6761733a3a6833343264326238626337633764303261bf053370616c6c65745f636f6e7472616374733a3a657865633a3a7472616e736665723a3a6839353065616664303466613631633736c0054f70616c6c65745f636f6e7472616374733a3a657865633a3a457865637574696f6e436f6e746578743c542c562c4c3e3a3a696e7374616e74696174653a3a6837326333393439373130303337383537c1052d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6833303639646365353332316537326664c2055f3c70616c6c65745f76657374696e673a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6836396637383763643730633564646231c305613c70616c6c65745f64656d6f63726163793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6863343035386338336531623237393362c4057c7061726974795f7363616c655f636f6465633a3a636f6465633a3a696e6e65725f7475706c655f696d706c3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f72202851302c5230293e3a3a6465636f64653a3a6837613662633666663530623563616432c505303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6838363134356262326635306231306634c605443c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6866643934383032333264636662306439c705533c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a737065635f657874656e643a3a6863653938353838666331663533653265c805543c616c6c6f633a3a7665633a3a5665633c543e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a6861643939656561356336613366313236c9058b013c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61704974657261746f723c4b2c562c4861736865723e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835333064343834303262373132633962ca05513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6830316233366132363737356365623639cb05513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6864316636633833373835616238313737cc05466e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f6672616d655f73797374656d3a3a6865623161613639353762323132663936cd05486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7574696c6974793a3a6863616530373132333564336166616335ce05486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f696e64696365733a3a6865323739323066323238376263366633cf05496e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f62616c616e6365733a3a6863383661383130666332396536643662d0054a70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6834666639316130643838646266343337d1055370616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6839333563346561333134323263623932d205486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7374616b696e673a3a6864316365643130336365643636363531d305486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f73657373696f6e3a3a6839333339383162343430633764326435d4054a6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f64656d6f63726163793a3a6839656639373339613833636639623831d505556e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f636f6c6c6563746976655f496e7374616e6365313a3a6833643664373237376330363634393766d605536e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f656c656374696f6e735f70687261676d656e3a3a6834336130633465666138323766343239d705556e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6d656d626572736869705f496e7374616e6365313a3a6834656264313639383432376235313532d8054570616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6866656531656332393265316135633063d9055070616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6836393634623035643963626363323166da05683c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6835323637386639303932326239343030db05486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6772616e6470613a3a6830656631386162363435316532383066dc05496e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f74726561737572793a3a6838386238326464633734636436303838dd054070616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6863363536326163326638616465363566de053e70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832646562663438626638656135663734df054a6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f636f6e7472616374733a3a6830643036326139336330303036323732e0054970616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6861376639386461353463316338356335e105613c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6832323661383965343737646336663631e205456e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7375646f3a3a6865376131336161623435313138323466e3054a6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f696d5f6f6e6c696e653a3a6864623130613939343133383966393236e405496e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6f6666656e6365733a3a6861333137626439666532363932363063e505496e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f6964656e746974793a3a6831633965636538353139383065633563e605486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f736f63696574793a3a6837366239313665353030366435376633e705496e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7265636f766572793a3a6831396435633835636466346536663032e805486e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f76657374696e673a3a6836303936386161396662336636653962e9054a6e6f64655f72756e74696d653a3a52756e74696d653a3a5f5f6d6f64756c655f6576656e74735f70616c6c65745f7363686564756c65723a3a6863346264306238656532396239353963ea059a013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d617856616c756553697a6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863393438343731653466633666303030eb0596013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178446570746844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6830333864356532323234303632323362ec059d013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53757263686172676552657761726444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836343830653436366165336364303937ed059f013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744465706f7369744f666673657444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839626530363830656562376135663336ee0599013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a52656e744279746546656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6836663961393366386466613437636564ef059f013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a53746f7261676553697a654f666673657444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838643633303139303332616634633336f005a1013c70616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5369676e6564436c61696d48616e646963617044656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863346466383466376635316164343366f105723c70616c6c65745f636f6e7472616374733a3a5f5f476574427974655374727563745072697374696e65436f64653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839393763623030653134396439313736f205753c70616c6c65745f636f6e7472616374733a3a5f5f4765744279746553747275637443757272656e745363686564756c653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866393832333137383262633461326433f3057a70616c6c65745f636f6e7472616374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6e7472616374733a3a5363686564756c653e3a3a656e636f64655f746f3a3a6832376466393964366137383130313132f405a2013c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5265706f72744c6174656e637944656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6833393932333966643833396664313862f5059f013c70616c6c65745f66696e616c6974795f747261636b65723a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a57696e646f7753697a6544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862306365323463633437653563363365f605aa013c70616c6c65745f7472616e73616374696f6e5f7061796d656e743a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5472616e73616374696f6e4279746546656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862656437356130663137626439343838f705a40170616c6c65745f636f6e7472616374733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6e7472616374733a3a526177416c697665436f6e7472616374496e666f3c436f6465486173682c42616c616e63652c426c6f636b4e756d6265723e3e3a3a656e636f64655f746f3a3a6834393036313261313163303935356662f8054a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6830343339333663613334336566363630f905ac013c73705f72756e74696d653a3a67656e657269633a3a756e636865636b65645f65787472696e7369633a3a556e636865636b656445787472696e7369633c416464726573732c43616c6c2c5369676e61747572652c45787472613e2061732073705f72756e74696d653a3a7472616974733a3a436865636b61626c653c4c6f6f6b75703e3e3a3a636865636b3a3a7b7b636c6f737572657d7d3a3a6835313732306465363738346439346362fa056073705f696f3a3a63727970746f3a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a736563703235366b315f65636473615f7265636f7665725f636f6d707265737365643a3a6830303331353463306265636239363333fb05713c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163745265663c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6834343239616463383933393563666663fc057d3c70616c6c65745f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a656e636f64655f746f3a3a6863303838393935643661633831383431fd05920170616c6c65745f64656d6f63726163793a3a766f74653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a766f74653a3a4163636f756e74566f74653c42616c616e63653e3e3a3a656e636f64655f746f3a3a6865666438373135663161313033393764fe057d70616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a656e636f64655f746f3a3a6833383035363664353437343365656365ff053f7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64655f746f3a3a6831303138393062613431346139333432800668636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a68616431343631393831616133613130348106573c49642061732073705f72756e74696d653a3a7472616974733a3a4163636f756e744964436f6e76657273696f6e3c543e3e3a3a696e746f5f7375625f6163636f756e743a3a686563316364626431313036666232653882066f6e6f64655f72756e74696d653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f72206e6f64655f72756e74696d653a3a4576656e743e3a3a656e636f64655f746f3a3a686636653666393138643662376334356183068e0170616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f636f6c6c6563746976653a3a5261774576656e743c486173682c4163636f756e7449642c493e3e3a3a656e636f64655f746f3a3a68326331303235313933333662396166628406763c70616c6c65745f617574686f726974795f646973636f766572793a3a43616c6c3c543e206173206672616d655f737570706f72743a3a776569676874733a3a4765744469737061746368496e666f3e3a3a6765745f64697370617463685f696e666f3a3a68376239316539663635616365623730398506583c6672616d655f73797374656d3a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a686631356263383935616364623033363486065d3c70616c6c65745f617574686f72736869703a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683365336433353465333864363733333187065a3c70616c6c65745f73657373696f6e3a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683361336639313562353663343735356388065f3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683131393766356464313431393763363989065f3c70616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68363561363031306463626432333664398a065f3c70616c6c65745f6d656d626572736869703a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68333831376537613764316438393663348b065b3c70616c6c65745f74726561737572793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68646136656437623533653762383937338c064470616c6c65745f636f6e7472616374733a3a7761736d3a3a707265706172653a3a707265706172655f636f6e74726163743a3a68306562636136353464356463346135368d064970616c6c65745f636f6e7472616374733a3a4d6f64756c653c543e3a3a657865637574655f7761736d3a3a7b7b636c6f737572657d7d3a3a68613037633433343761656339663165378e06573c70616c6c65745f7375646f3a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a68656235333666653835313961623535398f065c3c70616c6c65745f736f63696574793a3a43616c6c3c542c493e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683837643638326638366266643433353990065b3c70616c6c65745f7265636f766572793a3a43616c6c3c543e2061732073705f72756e74696d653a3a7472616974733a3a446973706174636861626c653e3a3a64697370617463683a3a683737626163353439376530613934346491066b3c7061726974795f7363616c655f636f6465633a3a636f6d706163743a3a436f6d706163743c7536343e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a686435323433616462323264653362616692067a3c70616c6c65745f696e64696365733a3a616464726573733a3a416464726573733c4163636f756e7449642c4163636f756e74496e6465783e206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f64653e3a3a6465636f64653a3a683334613364393661333031323938636293067a70616c6c65745f636f6c6c6563746976653a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f636f6c6c6563746976653a3a43616c6c3c542c493e3e3a3a6465636f64653a3a686464386233316238633161316437383894066c70616c6c65745f7375646f3a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7375646f3a3a43616c6c3c543e3e3a3a6465636f64653a3a686665366230643061623361653539363295067470616c6c65745f7265636f766572793a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a4465636f646520666f722070616c6c65745f7265636f766572793a3a43616c6c3c543e3e3a3a6465636f64653a3a68343130636536643031343038393037649606437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6830383438343261386137346565316564970630636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a68646563306531626466306138343965312e3130373098063a6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a683831376537383834613661633166386599063c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68336531316630613964306364333663369a06703c6672616d655f73797374656d3a3a5f5f47657442797465537472756374457865637574696f6e50686173653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68323138303262393830623333346530639b06703c6672616d655f73797374656d3a3a5f5f4765744279746553747275637445787472696e73696373526f6f743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68333131373865326139303164306635309c06693c6672616d655f73797374656d3a3a5f5f476574427974655374727563744163636f756e743c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68386561313265336264626535636137369d06456672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a68626466626630333830376631616636319e069c013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178696d756d426c6f636b4c656e67746844656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a68303265663366653630333561346535669f069d013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a45787472696e7369634261736557656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835623934353064346537323130363635a0069e013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a426c6f636b457865637574696f6e57656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839613765386561316361323764343865a10692013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a446257656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6866653034303734613637623134663162a2069c013c6672616d655f73797374656d3a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178696d756d426c6f636b57656967687444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832663333303361336535396365363436a3063b70616c6c65745f636f6e7472616374733a3a7761736d3a3a636f64655f63616368653a3a6c6f61643a3a6831393939343334323732646361353233a406aa0170616c6c65745f64656d6f63726163793a3a74797065733a3a5f3a3a3c696d706c207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f646520666f722070616c6c65745f64656d6f63726163793a3a74797065733a3a5265666572656e64756d5374617475733c426c6f636b4e756d6265722c486173682c42616c616e63653e3e3a3a656e636f64655f746f3a3a6862393137323034313462313038366635a5064170616c6c65745f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6866323964663330623038633836633037a6064370616c6c65745f6d656d626572736869703a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6835646331333063393561653063356366a706437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6836633466633039653364333864663661a8064a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a6835613261613431373162653338663437a9065d3c6672616d655f73797374656d3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6833643662316337306335303231333962aa0699013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a6368616e67655f6d656d626572735f736f727465643a3a6830353935366365616662323934356336ab068d013c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733c3c54206173206672616d655f73797374656d3a3a54726169743e3a3a4163636f756e7449643e3e3a3a7365745f7072696d653a3a6838336566366439663836303137343563ac062b616c6c6f633a3a736c6963653a3a6d657267655f736f72743a3a6833636639313337393965633965353439ad064b6672616d655f737570706f72743a3a7472616974733a3a4368616e67654d656d626572733a3a7365745f6d656d626572735f736f727465643a3a6839383135333962646438623262626161ae0668636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6862356630623138363637326365383565af062d70616c6c65745f736f63696574793a3a7069636b5f7573697a653a3a6837343739633461336232356230643737b0063b70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a62756d705f7061796f75743a3a6839386439353436356264363863616235b1063c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6866373338333839346538386334323162b206706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a6838363237653065643430373430393730b3065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863353830363663306264623464396537b4063e70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a73757370656e645f6d656d6265723a3a6866616665343765383366306564653932b5065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6831346538303361656533666439616162b606673c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a7472795f666f6c643a3a6832316461383965366161383535393933b706753c285475706c65456c656d656e74302c5475706c65456c656d656e743129206173206672616d655f737570706f72743a3a7472616974733a3a4f6e496e697469616c697a653c426c6f636b4e756d6265723e3e3a3a6f6e5f696e697469616c697a653a3a6830333761643364346366353234343365b8065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6863346639373934393861633137303563b9065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6834373166333530323666396361386231ba065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6837313634653061663836396463356234bb063970616c6c65745f7375646f3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6862643838643265303762666533626239bc063b70616c6c65745f7375646f3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6866323765373566346433356638666136bd06643c70616c6c65745f7375646f3a3a5f5f476574427974655374727563744b65793c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6835666533643339363864366535653732be063e70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a6838626439623466356662663865626466bf064070616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a6831396166623964653934306131636366c0064970616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6833323064366162653830343462633962c10698013c70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6f64756c65496444656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6834346566393263616134313163623830c2069e013c70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a526f746174696f6e506572696f6444656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837353731653665353963383161313438c3069b013c70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a506572696f645370656e6444656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839616536316237323166633131323063c4069a013c70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6178537472696b657344656661756c74427974654765747465723c542c493e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831626131666433373163303130343862c5063d70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6834316666376337643464373064633863c6063f70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6835623335363464653439663666616133c7064870616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a6831303639633234303865653738333566c80695013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4d6f64756c65496444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6839363964343463333261636534356236c9069a013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a54697046696e6465727346656544656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6863383661336631343061643137663666ca0698013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a5370656e64506572696f6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838343566613030653932383065336130cb0691013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a4275726e44656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6837313762333438363361383631316565cc0699013c70616c6c65745f74726561737572793a3a4d6f64756c653c543e3a3a6d6f64756c655f636f6e7374616e74735f6d657461646174613a3a50726f706f73616c426f6e6444656661756c74427974654765747465723c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6862373065636235383833306666313033cd06437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a6835383338386439623264613665653565ce0668636f72653a3a6f70733a3a66756e6374696f6e3a3a696d706c733a3a3c696d706c20636f72653a3a6f70733a3a66756e6374696f6e3a3a466e4d75743c413e20666f7220266d757420463e3a3a63616c6c5f6d75743a3a6837326264323932386338376534363531cf065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6833373163313531376437393539666637d0065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832323739653231343262613366333463d106493c6e6f64655f72756e74696d653a3a43616c6c20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a68333736613635376637383866316639642e31353034d2065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865653138306264333033636130313663d3065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6866616135386431363235396463666462d4065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6866306235363637663762346264343139d5065c3c70616c6c65745f7375646f3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6831376166616136333265626637393833d6063770616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a7075745f6269643a3a6831643330373763313363393765653438d706456672616d655f737570706f72743a3a7472616974733a3a456e737572654f726967696e3a3a656e737572655f6f726967696e3a3a6831663836393939653965313464616335d8063a70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e3a3a6164645f6d656d6265723a3a6861333839393863343961623430386131d906603c70616c6c65745f74726561737572793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6864336431366161363130356134326138da06613c70616c6c65745f736f63696574793a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6864363964616136336130306665386264db063c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6834653362623736613863613666363331dc066b3c73705f61726974686d657469633a3a66697865643132383a3a46697865643132382061732073705f61726974686d657469633a3a7472616974733a3a53617475726174696e673e3a3a73617475726174696e675f6d756c3a3a6831613530653032346332353132376262dd065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6832613534656366653262383037666630de06776672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a3c696d706c206672616d655f737570706f72743a3a73746f726167653a3a53746f726167654d61703c4b2c563e20666f7220473e3a3a696e736572743a3a6837346164333837356264353232303437df063d70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a7363686564756c655f6368616e67653a3a6866646636343030336636613135643862e0063c7061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a656e636f64653a3a6862616535666330343739363465313432e106683c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a73697a655f68696e743a3a6831396666356430383165346638376231e206633c636f72653a3a697465723a3a61646170746572733a3a4d61703c492c463e20617320636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723e3a3a6e6578743a3a6835383638636236336632353930666135e3063e636f72653a3a697465723a3a7472616974733a3a6974657261746f723a3a4974657261746f723a3a6e74683a3a6835326166653137346365323438663833e4063c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832306435616365333761663234623235e5063e70616c6c65745f6772616e6470613a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6832396166353464643230343034646563e606703c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637443757272656e7453657449643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6838376431323432303135393731343235e7066b3c70616c6c65745f6772616e6470613a3a5f5f476574427974655374727563745374616c6c65643c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6831376438303138616533323166373233e806693c70616c6c65745f6772616e6470613a3a5f5f4765744279746553747275637453746174653c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6832363230386139336637396338633139e9063c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6863656665363931333838306262303962ea063e70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6830373865323861366264386533333737eb06703c70616c6c65745f73657373696f6e3a3a5f5f4765744279746553747275637443757272656e74496e6465783c543e206173206672616d655f6d657461646174613a3a44656661756c74427974653e3a3a64656661756c745f627974653a3a6865336438313432316530386163313232ec062b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6839343863336665383135653764663132ed064770616c6c65745f636f6e7472616374733a3a7761736d3a3a707265706172653a3a436f6e74726163744d6f64756c653a3a6e65773a3a6861623435626538366235333337643233ee0648616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e3a3a696e736572743a3a6866623430333137376534626538373836ef063c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a66726f6d5f6d6f64756c653a3a6866333834373962663335336136613366f006537061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a7265736f6c76655f747970655f7265663a3a6834633266623438353162383736646366f106a9017061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a3c696d706c20636f72653a3a636f6e766572743a3a46726f6d3c7061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c6553636166666f6c643e20666f72207061726974795f7761736d3a3a656c656d656e74733a3a6d6f64756c653a3a4d6f64756c653e3a3a66726f6d3a3a6835306361373739666538313464623463f2062d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6834313530386166653865623432633038f306507061726974795f7761736d3a3a6275696c6465723a3a6d6f64756c653a3a4d6f64756c654275696c6465723c463e3a3a707573685f66756e6374696f6e3a3a6866363462363133383937383334613137f4062b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6833616534653964353339636535333539f5063c707761736d5f7574696c733a3a737461636b5f6865696768743a3a696e6a6563745f6c696d697465723a3a6839636130333231656531386331363338f6066b3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6862313134326534323564636135643531f7065c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6865326666353434643965303731393036f8065f3c70616c6c65745f6772616e6470613a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6837663863363935396266643331333939f9065f3c70616c6c65745f73657373696f6e3a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6835373864323439636139613137316632fa063f70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a6832363535616164383839393866646332fb064170616c6c65745f617574686f72736869703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a6862366162333363643165613139343731fc0634636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6835363762363965366331393861366138fd062e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6862383736626461613861633862333565fe063c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6832393836656661313337343830313433ff0634636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a686138323232383231313635343238376680073f636f72653a3a736c6963653a3a736f72743a3a63686f6f73655f7069766f743a3a7b7b636c6f737572657d7d3a3a683738333761396232663631653834326481072e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a686362653437326364636564643931663782073c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6831643439353266326632616633653931830730636f72653a3a736c6963653a3a736f72743a3a73686966745f7461696c3a3a686562373833323164356566366339326284073b636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a7b7b636c6f737572657d7d3a3a6839663264373835626337393261303131850734636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a683566333032363664303130323665396486072e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a683263353261363266333433633333343987073c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a68373133646261306637393639363532668807623c70616c6c65745f617574686f72736869703a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a68616432623466393161303466386438658907753c70616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a43616c6c3c543e206173206672616d655f737570706f72743a3a7472616974733a3a47657443616c6c4e616d653e3a3a6765745f63616c6c5f6e616d65733a3a68323961313231653735316234333562318a075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68643034313164373637326466303531658b074a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a68383632383539636661633837343062328c075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68613735376630303463336164346130378d073d70616c6c65745f7265636f766572793a3a4d6f64756c653c543e3a3a63616c6c5f66756e6374696f6e733a3a68623832396330383263663265353362628e073f70616c6c65745f7265636f766572793a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a68303165333565646537383863616465628f074170616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a63616c6c5f66756e6374696f6e733a3a683464613663376338666466336334666290074370616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a683033613166343366313736636537356691074370616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a73746f726167655f6d657461646174613a3a68663934633434326563663936303038619207437061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653a3a7573696e675f656e636f6465643a3a683536663833303332356336626564383693075170616c6c65745f72616e646f6d6e6573735f636f6c6c6563746976655f666c69703a3a4d6f64756c653c543e3a3a73746f726167655f6d657461646174613a3a683535303335613465326161353865656494074a3c58206173207061726974795f7363616c655f636f6465633a3a636f6465633a3a456e636f64653e3a3a7573696e675f656e636f6465643a3a683534323939643736623963323661616595075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a686263376264306561336335376635623796075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68626236373865393432336631613237339707706672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a646f75626c655f6d61703a3a53746f72616765446f75626c654d61703a3a73746f726167655f646f75626c655f6d61705f66696e616c5f6b65793a3a68613234653662393932343462623763629807603c70616c6c65745f7265636f766572793a3a4d6f64756c653c543e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a683533643035366435643235326332366399075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68623435343038346265653437316436649a075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68643535393733393936323038653838659b074470616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a66696e616c697a655f70726f706f73616c3a3a68616436343066333133306630313965359c075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68663838336661643664393038326338389d075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68356535616238393063626561343132399e075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a68626662363364353833396563376539619f074470616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e3a3a66696e616c697a655f70726f706f73616c3a3a6866643633623434313664643633303236a0075c6672616d655f737570706f72743a3a73746f726167653a3a67656e657261746f723a3a6d61703a3a53746f726167654d61703a3a73746f726167655f6d61705f66696e616c5f6b65793a3a6861663736336438386137366332316438a107643c70616c6c65745f636f6c6c6563746976653a3a4d6f64756c653c542c493e206173206672616d655f6d657461646174613a3a4d6f64756c654572726f724d657461646174613e3a3a6d657461646174613a3a6831343061333461373132356364386363a207683c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6834633439393331653735616331303138a3076b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6864356135626266333165343636323863a4077d3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973745772697465723c492c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6831666265366561303230383136373939a5076f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6862386538363632373939653530373036a6076f3c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a566172496e743634206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6831363563383135396232653962303266a7076c3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e697445787072206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6837303733363332303830643532303037a8076f3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6863656638303132636264353065663931a90737616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6865643330346464376366633233646363aa07443c7061726974795f7761736d3a3a696f3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830363338666230393435646262316335ab07793c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a436f756e7465644c6973743c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6862363633343636326632653739666337ac076b3c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6833326532316261643239303066363766ad0786017061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a3c696d706c207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a6520666f7220616c6c6f633a3a737472696e673a3a537472696e673e3a3a646573657269616c697a653a3a6863353961393931616461356430623731ae07323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6834666334636132316331623933643033af07783c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6832643663653261356166653563383933b0077c3c7061726974795f7761736d3a3a656c656d656e74733a3a696d706f72745f656e7472793a3a526573697a61626c654c696d697473206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6838626232643362346332336531633565b1076f3c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6837663765346430383832396631323139b207463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6833376132336136316462616631363131b307463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6863643738643132376462383834626331b407463c616c6c6f633a3a7665633a3a5665633c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6834663939323932346130383535613964b5074f7761736d695f76616c69646174696f6e3a3a636f6e746578743a3a4d6f64756c65436f6e746578744275696c6465723a3a707573685f676c6f62616c3a3a6862636338656463363736323264336163b607587761736d695f76616c69646174696f6e3a3a636f6e746578743a3a4d6f64756c65436f6e746578744275696c6465723a3a707573685f66756e635f747970655f696e6465783a3a6861356466303736306130303135376138b707397761736d695f76616c69646174696f6e3a3a76616c69646174655f6d656d6f72795f747970653a3a6831383633306138366563393738353763b807347761736d695f76616c69646174696f6e3a3a657870725f636f6e73745f747970653a3a6833613736663931623637613733323066b907553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861643864386337663861313638323138ba0737616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6839613162383130373666393532313831bb074a7761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a737465703a3a6837376339326138323465313365383937bc07473c7761736d695f76616c69646174696f6e3a3a4572726f7220617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6864656161653436366361623262613537bd07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830613238336532663738663661326566be072d636f72653a3a736c6963653a3a736f72743a3a726563757273653a3a6831363439613438666466323361333234bf07457061726974795f7761736d3a3a656c656d656e74733a3a7365676d656e743a3a446174615365676d656e743a3a76616c75653a3a6866626639333864636633313437393639c007743c7061726974795f7761736d3a3a656c656d656e74733a3a7072696d6974697665733a3a56617255696e743332206173207061726974795f7761736d3a3a656c656d656e74733a3a446573657269616c697a653e3a3a646573657269616c697a653a3a6833623230373765376464326631363864c107713c7061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a437573746f6d53656374696f6e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6864663763623061633039343731666132c207713c7061726974795f7761736d3a3a656c656d656e74733a3a696e6465785f6d61703a3a496e6465784d61703c543e206173207061726974795f7761736d3a3a656c656d656e74733a3a53657269616c697a653e3a3a73657269616c697a653a3a6864666232373762626563613239623830c3074b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6865633837386535616238626531386461c4074b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6865656338373534646334383636656137c5074b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6839313737336537633930356339383138c6074b3c616c6c6f633a3a7665633a3a496e746f497465723c543e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6833333565616231613531386161623564c707457061726974795f7761736d3a3a656c656d656e74733a3a73656374696f6e3a3a53656374696f6e5265616465723a3a6e65773a3a6832623264323232373937343937323061c80734636f72653a3a736c6963653a3a736f72743a3a627265616b5f7061747465726e733a3a6836343538633738383030373433303233c9072e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6831306338313934323835623434626230ca073c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6864613432613230353866666131383664cb073b636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a7b7b636c6f737572657d7d3a3a6835383437313839323762303531653533cc07513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6832663135653939656239653139333630cd07553c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6832303532316635393734663134313935ce07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863383639356162343734343836336363cf07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864613136343061353937346565313763d007303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6830353832373464653465663439383937d107303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6865396662333236613732333063383332d207553c7061726974795f7761736d3a3a656c656d656e74733a3a74797065733a3a426c6f636b5479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837323362653966316562343863383163d307303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835366339366664633833326565393861d407303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835666561393361383663313330373437d507303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6866636266616465653635666130653233d607483c616c6c6f633a3a626f7865643a3a426f783c5b545d3e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6863633537623165633463306466373734d707593c7061726974795f7761736d3a3a656c656d656e74733a3a6f70733a3a496e737472756374696f6e20617320636f72653a3a636c6f6e653a3a436c6f6e653e3a3a636c6f6e653a3a6831323935353262336336633161383561d807303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6863373464613163386662353263386639d9072e636f72653a3a736c6963653a3a736f72743a3a68656170736f72743a3a6863663136636133313038386537343636da073c636f72653a3a736c6963653a3a736f72743a3a7061727469616c5f696e73657274696f6e5f736f72743a3a6831313032373164326234386463616666db0741707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a636f6d707574653a3a6837656330646464396561363763366134dc075a3c707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a4672616d6520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6831643937376433336462393035613166dd0746707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a6672616d653a3a6831636263656662616631333631356230de07453c636f72653a3a6f7074696f6e3a3a4f7074696f6e3c543e20617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6864626634366461626130636234616438df074b707761736d5f7574696c733a3a737461636b5f6865696768743a3a6d61785f6865696768743a3a537461636b3a3a706f705f76616c7565733a3a6863356261643934666164326137633337e0073f707761736d5f7574696c733a3a737461636b5f6865696768743a3a7265736f6c76655f66756e635f747970653a3a6835623034396663666265376561646530e107613c616c6c6f633a3a636f6c6c656374696f6e733a3a62747265653a3a6d61703a3a42547265654d61703c4b2c563e20617320636f72653a3a6f70733a3a64726f703a3a44726f703e3a3a64726f703a3a6835373163636462353465633063306339e207303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6834373738326234376365343162386331e30733636f72653a3a6f7074696f6e3a3a4f7074696f6e3c26543e3a3a636c6f6e65643a3a6833623861386631386663366664343632e40740707761736d5f7574696c733a3a737461636b5f6865696768743a3a636f6d707574655f737461636b5f636f73743a3a6861323533626530386134336531623837e507323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6837613135656265343936356665396133e6073a73705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6c73747269703a3a6836646436653963623432323733363663e7073773705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6164643a3a6830316434306537663531376362383139e8073773705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6d756c3a3a6866643130333939633138306330393161e9074473705f61726974686d657469633a3a62696775696e743a3a42696755696e743a3a6469763a3a7b7b636c6f737572657d7d3a3a6866383462626664386539613033646631ea074b3c73705f61726974686d657469633a3a62696775696e743a3a42696755696e7420617320636f72653a3a636d703a3a4f72643e3a3a636d703a3a6834343461643533633863373732383630eb07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6837333938323135383866653231386330ec07513c616c6c6f633a3a7665633a3a5665633c543e20617320616c6c6f633a3a7665633a3a53706563457874656e643c542c493e3e3a3a66726f6d5f697465723a3a6861616431376235343262386136333034ed07413c73705f696e686572656e74733a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6866646363643030363831623962623332ee07323c265420617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a6834386262343837633064373131326537ef074273705f696f3a3a6c6f6767696e673a3a65787465726e5f686f73745f66756e6374696f6e5f696d706c733a3a6c6f673a3a6866343962313237633262386461396133f007573c73705f72756e74696d653a3a72756e74696d655f737472696e673a3a52756e74696d65537472696e6720617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839343732383631363335666331333066f107473c73705f72756e74696d653a3a44697370617463684572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6839393631343466363366333061303337f207347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f76616c75653a3a6838613630623536373166386263396664f307347761736d695f76616c69646174696f6e3a3a66756e633a3a706f705f6c6162656c3a3a6865333162373732616530303563363736f407347761736d695f76616c69646174696f6e3a3a66756e633a3a7465655f76616c75653a3a6837646138326332343962306562633331f507407761736d695f76616c69646174696f6e3a3a7574696c3a3a4c6f63616c733a3a747970655f6f665f6c6f63616c3a3a6838636138323766646134356339313330f607543c7761736d695f76616c69646174696f6e3a3a66756e633a3a537461636b56616c75655479706520617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6835353532326133316636303964363937f707537761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f6c6f61643a3a6830376132393432636464306365343338f807547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f73746f72653a3a6831323764353062613862376333643439f907547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f72656c6f703a3a6861343966626334643365306136373739fa07547761736d695f76616c69646174696f6e3a3a66756e633a3a46756e6374696f6e56616c69646174696f6e436f6e746578743a3a76616c69646174655f62696e6f703a3a6838656230653936636235643135343234fb073b616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a616c6c6f636174655f696e3a3a6831363031666261373561616639383461fc0737616c6c6f633a3a7261775f7665633a3a5261775665633c542c413e3a3a726573657276653a3a6830313230663136306336333962303561fd073b636f72653a3a736c6963653a3a3c696d706c205b545d3e3a3a636f70795f66726f6d5f736c6963653a3a6862656366363865633237636235336665fe072b636f72653a3a7074723a3a64726f705f696e5f706c6163653a3a6861626461346364333962343639396563ff07303c265420617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a68323235343564613034363464666239398008453c616c6c6f633a3a737472696e673a3a537472696e6720617320636f72653a3a666d743a3a446973706c61793e3a3a666d743a3a683430363536353032386339373630633381084c3c7761736d695f76616c69646174696f6e3a3a737461636b3a3a4572726f7220617320636f72653a3a666d743a3a44656275673e3a3a666d743a3a6861313263303261643833303862306162820838636f6d70696c65725f6275696c74696e733a3a696e743a3a6d756c3a3a5f5f6d756c7469333a3a6839373632626331636361303166383364830839636f6d70696c65725f6275696c74696e733a3a696e743a3a6d756c3a3a5f5f6d756c6f7469343a3a68323735656632666138626166616237318408085f5f6d756c7469338508095f5f6d756c6f7469348608095f5f756d6f6474693387082b636f6d70696c65725f6275696c74696e733a3a61626f72743a3a6837373662356362633663393964313163880839636f6d70696c65725f6275696c74696e733a3a696e743a3a736469763a3a5f5f6469767469333a3a68353431303861623133616630373236328908463c69363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a66726f6d5f756e7369676e65643a3a68623233353336366166363766393733388a08453c75363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a61626f7274696e675f6469763a3a68353339326136663336363336656339308b08453c75363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a61626f7274696e675f72656d3a3a68636165613162386434353561363334398c08453c69363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a7772617070696e675f6164643a3a68356438303838653933313037343366398d08453c69363420617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a7772617070696e675f6d756c3a3a68616366346631393365666533333565668e08473c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a66726f6d5f756e7369676e65643a3a68396361396438643435306530333130398f08463c7531323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a61626f7274696e675f6469763a3a68646461633866376335323365633534389008433c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a6d61785f76616c75653a3a68313965366462646366643839343564339108433c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a6d696e5f76616c75653a3a68396138626366656461353838656165339208463c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a7772617070696e675f6d756c3a3a68663762643232353766633537633430369308463c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a7772617070696e675f7375623a3a68323165393061666464326361353338329408463c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a496e743e3a3a61626f7274696e675f6469763a3a68313361346530633765653064303163399508423c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a4c61726765496e743e3a3a6c6f773a3a68633539396133336534633865356161339608433c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a4c61726765496e743e3a3a686967683a3a68666365633135386664353336366161629708493c6931323820617320636f6d70696c65725f6275696c74696e733a3a696e743a3a4c61726765496e743e3a3a66726f6d5f70617274733a3a68646135326234366661633734663438379808095f5f7564697674693399083a636f6d70696c65725f6275696c74696e733a3a696e743a3a756469763a3a5f5f756469767469333a3a68316538396139356663646439323031339a083d636f6d70696c65725f6275696c74696e733a3a696e743a3a756469763a3a5f5f756469766d6f647469343a3a68633262343431643430303733343161669b083a636f6d70696c65725f6275696c74696e733a3a696e743a3a756469763a3a5f5f756d6f647469333a3a68653963366462306266373836386263319c08085f5f6469767469339d08066d656d6370799e08076d656d6d6f76659f08066d656d736574a0080462636d70a1083b636f6d70696c65725f6275696c74696e733a3a696e743a3a73686966743a3a5f5f6173686c7469333a3a6838656231636163626365343565313733a2083b636f6d70696c65725f6275696c74696e733a3a696e743a3a73686966743a3a5f5f6c7368727469333a3a6861613765666137333665663233346637a308095f5f6173686c746933a408095f5f6c73687274693300550970726f64756365727302086c616e6775616765010452757374000c70726f6365737365642d62790105727573746325312e34352e302d6e696768746c79202866613531663831306520323032302d30342d323929", "0x5f3e4907f716ac89b6347d15ececedca422adb579f1dbf4f3886c5cfa3bb8cc49c1d737e05234a5ad3f96cf385e1f17b781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d120f0000c16ff286230f0000c16ff286230000", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95018afb0daf0c8654bf248b8e9f3ca3cf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x00000000030000c16ff28623000000000000000000000000000000000000000000000000000000c16ff286230000000000000000000000c16ff28623000000000000000000", - "0x5f3e4907f716ac89b6347d15ececedca3ed14b45ed20d054f05e37e2542cfe7079091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526", "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a00000000c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x0ff6ffc06ff286230ff6ffc06ff2862300", - "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e1690354352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x00", + "0xc2261276cc9d1f8598ea4b6a74b15c2f308ce9615de0775a82f8a94dc3d285a1": "0x01", + "0x4342193e496fab7ec59d615ed0dc5530d2d505c0e6f76fd7ce0796ebe187401c": "0x0000000020a107000000000020a107000000000020a107000000000020a107000000000020a107000000000020a107000000000020a1070000000000e0f7050400000000e024370500000000e0f705040000000020a107000000000020a107000000000080f0fa020000000000e1f50500000000040000000000010010000000004000000020000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00401eae822458363600000000000000", + "0x5f3e4907f716ac89b6347d15ececedcaad811cd65a470ddc5f1d628ff0550982b4def25cfda6ef3a00000000": "0x00000000", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a000000007441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a0000000079091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0x5f3e4907f716ac89b6347d15ececedcae1791577e4efcb083fdc3cb21e85b2e4": "0x00", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195050b3bd0c839f9eac6772616e807932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b2a4e124620611833d1b252494468c2a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x00000000030000c16ff28623000000000000000000000000000000000000000000000000000000c16ff286230000000000000000000000c16ff28623000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca0b6a45321efae92aea15e0740ec7afe7": "0x00000000", "0x3a65787472696e7369635f696e646578": "0x00000000", - "0x426e15054d267946093858132eb537f1a47a9ff5cd5bf4d848a80a0b1a947dc3": "0x00000000000000000000000000000000", - "0x8985776095addd4789fccbce8ca77b23ba7fb8745735dc3be2a2c61a72c39e78": "0x049ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", - "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc65018afb0daf0c8654bf248b8e9f3ca3cf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x047374616b696e67200000c16ff2862300000000000000000002", - "0x426e15054d267946093858132eb537f1ba7fb8745735dc3be2a2c61a72c39e78": "0x049ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", - "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6b2a4e124620611833d1b252494468c2a68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x047374616b696e67200000c16ff2862300000000000000000002", - "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb37441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f437800299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378", - "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6bed2903186223711a06d85784e730efd547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x047374616b696e67200000c16ff2862300000000000000000002", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950279056c0dd3fd147696d6f6e806e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0x5f3e4907f716ac89b6347d15ececedca88dcde934c658227ee1dfafcd6e16903c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x00", - "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade9879091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x00", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950a7c05e469443baab617564698000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195081918b9c078ba64f696d6f6e8000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0xcec5070d609dd3497f72bde07fc96ba088dcde934c658227ee1dfafcd6e16903": "0x109c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d6568655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195090ae3b675fd0a89f6175646980482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", + "0x5f3e4907f716ac89b6347d15ececedca5579297f4dfb9609e7e4c2ebab9ce40a": "0x109c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d1268655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", + "0xe2e62dd81c48a88f73b6f6463555fd8e71cd3068e6118bfb392b798317f63a89d28ebd9aad2de6179ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809": "0x0000c16ff28623000000000000000000049ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809", + "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a0000000079091c57296b2634547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65": "0x0ff6ffc06ff286230ff6ffc06ff2862300", "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a000000007441588f5c9a91b3f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x0ff6ffc06ff286230ff6ffc06ff2862300", - "0x426e15054d267946093858132eb537f1d0b4a3f7631f0c0e761898fe198211de": "0xe7030000", - "0x5f3e4907f716ac89b6347d15ececedca9220e172bed316605f73f1ff7b4ade98c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x00", - "0x5f3e4907f716ac89b6347d15ececedca487df464e44a534ba6b0cbb32407b587": "0x0000000000", - "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6a8d6d78917f3d243ed0a3d1dfb3878099c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x047374616b696e67200000c16ff2862300000000000000000002", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9a831cc69a96025a90c389ecb19a25ff29ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809": "0x000000000100405f2954c5c535360000000000000000c040b571e8030000000000000000000000c16ff2862300000000000000000000000000000000000000000000000000", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195018823a93d5cac7d062616265806e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195082216e38506cc6f7626162658000299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378": "0xf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663", - "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ecffd7b6c0f78751baa9d281e0bfa3a6d6f646c70792f74727372790000000000000000000000000000000000000000": "0x000000000000407a10f35a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746b4def25cfda6ef3a00000000": "0x4545454545454545454545454545454545454545454545454545454545454545", - "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a00000000c90f9b6dd26886b468655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78": "0x0ff6ffc06ff286230ff6ffc06ff2862300", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950414ee903f38cbde66772616e805633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195057479bdad16c7a386261626580482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e": "0x68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78", - "0xf2794c22e353e9a839f12faab03a911be2f6cb0456905c189bcb0458f9440f13": "0x00000000", + "0xe2e62dd81c48a88f73b6f6463555fd8eba7fb8745735dc3be2a2c61a72c39e78": "0x049ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e3180973474718090000c16ff28623000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedcaf7dad0317324aecae8744b87fc95f2f3": "0x00", + "0x5f3e4907f716ac89b6347d15ececedca8bde0a0ea8864605e3b68ed9cb2da01bb4def25cfda6ef3a0000000054352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x0ff6ffc06ff286230ff6ffc06ff2862300", + "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa195003e77b7332307fb461756469806e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106": "0x9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12", + "0x5f3e4907f716ac89b6347d15ececedcaa141c4fe67c2d11f4a10c6aca7a79a04b4def25cfda6ef3a00000000": "0xd8ff03bfc91b8e000000000000000000", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95018afb0daf0c8654bf248b8e9f3ca3cf26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663": "0x00000000030000c16ff28623000000000000000000000000000000000000000000000000000000c16ff286230000000000000000000000c16ff28623000000000000000000", + "0x5f3e4907f716ac89b6347d15ececedca42982b9d6c7acc99faa9094c912372c2b4def25cfda6ef3a0000000054352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x0ff6ffc06ff286230ff6ffc06ff2862300", "0x5f3e4907f716ac89b6347d15ececedca28dccb559b95c40168a1b2696581b5a7": "0x00000000000000000000000000000000", - "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6a831cc69a96025a90c389ecb19a25ff29ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809": "0x04706872656c6563740000c16ff2862300000000000000000001", - "0xcec5070d609dd3497f72bde07fc96ba0726380404683fc89e8233450c8aa1950dd81945454d561f36261626580482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a": "0x547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65" + "0xcec5070d609dd3497f72bde07fc96ba04c014e6bf8b8c2c011e7290b85696bb354352b71083d945a9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12": "0x9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe96993326e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f91066e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106" }, "childrenDefault": {} } } -} +} \ No newline at end of file diff --git a/bin/node/cli/src/browser.rs b/bin/node/cli/src/browser.rs index 861d37c6058e1aff0640da97a6ad2fdce622abd2..3aec486c103700f9e7fd9e9c9a8218b78cf555ab 100644 --- a/bin/node/cli/src/browser.rs +++ b/bin/node/cli/src/browser.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::chain_spec::ChainSpec; use log::info; @@ -50,8 +52,10 @@ async fn start_inner(chain_spec: Option, log_level: String) -> Result. +// along with this program. If not, see . //! Substrate chain configurations. @@ -23,7 +25,7 @@ use node_runtime::{ AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig,GrandpaConfig, ImOnlineConfig, SessionConfig, SessionKeys, StakerStatus, StakingConfig, ElectionsConfig, IndicesConfig, SocietyConfig, SudoConfig, SystemConfig, - TechnicalCommitteeConfig, WASM_BINARY, + TechnicalCommitteeConfig, wasm_binary_unwrap, }; use node_runtime::Block; use node_runtime::constants::currency::*; @@ -239,7 +241,7 @@ pub fn testnet_genesis( GenesisConfig { frame_system: Some(SystemConfig { - code: WASM_BINARY.to_vec(), + code: wasm_binary_unwrap().to_vec(), changes_trie_config: Default::default(), }), pallet_balances: Some(BalancesConfig { @@ -378,7 +380,7 @@ pub fn local_testnet_config() -> ChainSpec { #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::service::{new_full, new_light}; + use crate::service::{new_full_base, new_light_base}; use sc_service_test; use sp_runtime::BuildStorage; @@ -428,8 +430,14 @@ pub(crate) mod tests { fn test_connectivity() { sc_service_test::connectivity( integration_test_config_with_two_authorities(), - |config| new_full(config), - |config| new_light(config), + |config| { + let (keep_alive, _, client, network, transaction_pool) = new_full_base(config,|_, _| ())?; + Ok(sc_service_test::TestNetComponents::new(keep_alive, client, network, transaction_pool)) + }, + |config| { + let (keep_alive, _, client, network, transaction_pool) = new_light_base(config)?; + Ok(sc_service_test::TestNetComponents::new(keep_alive, client, network, transaction_pool)) + } ); } diff --git a/bin/node/cli/src/cli.rs b/bin/node/cli/src/cli.rs index fa9a43ee6841ca88302810ecb81b6d1bed5f77c0..42a13fcb390703e765f095a659ebbf8bc80f2d3c 100644 --- a/bin/node/cli/src/cli.rs +++ b/bin/node/cli/src/cli.rs @@ -1,24 +1,26 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . -use sc_cli::RunCmd; +use sc_cli::{RunCmd, KeySubcommand, SignCmd, VanityCmd, VerifyCmd}; use structopt::StructOpt; /// An overarching CLI command definition. -#[derive(Clone, Debug, StructOpt)] +#[derive(Debug, StructOpt)] pub struct Cli { /// Possible subcommand with parameters. #[structopt(subcommand)] @@ -29,12 +31,15 @@ pub struct Cli { } /// Possible subcommands of the main binary. -#[derive(Clone, Debug, StructOpt)] +#[derive(Debug, StructOpt)] pub enum Subcommand { /// A set of base subcommands handled by `sc_cli`. #[structopt(flatten)] Base(sc_cli::Subcommand), + /// Key management cli utilities + Key(KeySubcommand), + /// The custom inspect subcommmand for decoding blocks and extrinsics. #[structopt( name = "inspect", @@ -45,4 +50,13 @@ pub enum Subcommand { /// The custom benchmark subcommmand benchmarking runtime pallets. #[structopt(name = "benchmark", about = "Benchmark runtime pallets.")] Benchmark(frame_benchmarking_cli::BenchmarkCmd), + + /// Verify a signature for a message, provided on STDIN, with a given (public or secret) key. + Verify(VerifyCmd), + + /// Generate a seed that provides a vanity address. + Vanity(VanityCmd), + + /// Sign a message, with a given (secret) key. + Sign(SignCmd), } diff --git a/bin/node/cli/src/command.rs b/bin/node/cli/src/command.rs index 91c6298c9fd5c5751dab747d23d0d46d3e1a15d0..10e9413702b815c5127942e907f6e325ed04e6b7 100644 --- a/bin/node/cli/src/command.rs +++ b/bin/node/cli/src/command.rs @@ -1,53 +1,53 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::{chain_spec, service, Cli, Subcommand}; use node_executor::Executor; use node_runtime::{Block, RuntimeApi}; -use sc_cli::{Result, SubstrateCli}; +use sc_cli::{Result, SubstrateCli, RuntimeVersion, Role, ChainSpec}; +use sc_service::PartialComponents; +use crate::service::new_partial; impl SubstrateCli for Cli { - fn impl_name() -> &'static str { - "Substrate Node" + fn impl_name() -> String { + "Substrate Node".into() } - fn impl_version() -> &'static str { - env!("SUBSTRATE_CLI_IMPL_VERSION") + fn impl_version() -> String { + env!("SUBSTRATE_CLI_IMPL_VERSION").into() } - fn description() -> &'static str { - env!("CARGO_PKG_DESCRIPTION") + fn description() -> String { + env!("CARGO_PKG_DESCRIPTION").into() } - fn author() -> &'static str { - env!("CARGO_PKG_AUTHORS") + fn author() -> String { + env!("CARGO_PKG_AUTHORS").into() } - fn support_url() -> &'static str { - "https://github.com/paritytech/substrate/issues/new" + fn support_url() -> String { + "https://github.com/paritytech/substrate/issues/new".into() } fn copyright_start_year() -> i32 { 2017 } - fn executable_name() -> &'static str { - "substrate" - } - fn load_spec(&self, id: &str) -> std::result::Result, String> { Ok(match id { "dev" => Box::new(chain_spec::development_config()), @@ -59,22 +59,23 @@ impl SubstrateCli for Cli { )?), }) } + + fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { + &node_runtime::VERSION + } } /// Parse command line arguments into service configuration. pub fn run() -> Result<()> { - sc_cli::reset_signal_pipe_handler()?; - let cli = Cli::from_args(); match &cli.subcommand { None => { let runner = cli.create_runner(&cli.run)?; - runner.run_node( - service::new_light, - service::new_full, - node_runtime::VERSION - ) + runner.run_node_until_exit(|config| match config.role { + Role::Light => service::new_light(config), + _ => service::new_full(config), + }) } Some(Subcommand::Inspect(cmd)) => { let runner = cli.create_runner(cmd)?; @@ -92,10 +93,17 @@ pub fn run() -> Result<()> { Ok(()) } } + Some(Subcommand::Key(cmd)) => cmd.run(), + Some(Subcommand::Sign(cmd)) => cmd.run(), + Some(Subcommand::Verify(cmd)) => cmd.run(), + Some(Subcommand::Vanity(cmd)) => cmd.run(), Some(Subcommand::Base(subcommand)) => { let runner = cli.create_runner(subcommand)?; - - runner.run_subcommand(subcommand, |config| Ok(new_full_start!(config).0)) + runner.run_subcommand(subcommand, |config| { + let PartialComponents { client, backend, task_manager, import_queue, ..} + = new_partial(&config)?; + Ok((client, backend, import_queue, task_manager)) + }) } } } diff --git a/bin/node/cli/src/lib.rs b/bin/node/cli/src/lib.rs index 3c49f9176f15b96df4bd4ae87ea407b713f340e1..bd2298514a7a2f1ed57fa008615b11ac0947d20b 100644 --- a/bin/node/cli/src/lib.rs +++ b/bin/node/cli/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate CLI library. //! diff --git a/bin/node/cli/src/service.rs b/bin/node/cli/src/service.rs index 7e27d57063ecfef242c010c05b9b08ab5f2e71f1..d91696ab7d6bc77a6289c21c8ef4fe93c8517f67 100644 --- a/bin/node/cli/src/service.rs +++ b/bin/node/cli/src/service.rs @@ -1,377 +1,453 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . #![warn(unused_extern_crates)] //! Service implementation. Specialized wrapper over substrate service. use std::sync::Arc; - use sc_consensus_babe; -use grandpa::{ - self, FinalityProofProvider as GrandpaFinalityProofProvider, StorageAndProofProvider, -}; -use node_executor; +use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}; use node_primitives::Block; use node_runtime::RuntimeApi; use sc_service::{ - AbstractService, ServiceBuilder, config::Configuration, error::{Error as ServiceError}, + config::{Role, Configuration}, error::{Error as ServiceError}, + RpcHandlers, TaskManager, }; use sp_inherents::InherentDataProviders; -use sc_consensus::LongestChain; - -/// Starts a `ServiceBuilder` for a full service. -/// -/// Use this macro if you don't actually need the full service, but just the builder in order to -/// be able to perform chain operations. -macro_rules! new_full_start { - ($config:expr) => {{ - use std::sync::Arc; - - type RpcExtension = jsonrpc_core::IoHandler; - let mut import_setup = None; - let mut rpc_setup = None; - let inherent_data_providers = sp_inherents::InherentDataProviders::new(); - - let builder = sc_service::ServiceBuilder::new_full::< - node_primitives::Block, node_runtime::RuntimeApi, node_executor::Executor - >($config)? - .with_select_chain(|_config, backend| { - Ok(sc_consensus::LongestChain::new(backend.clone())) - })? - .with_transaction_pool(|config, client, _fetcher, prometheus_registry| { - let pool_api = sc_transaction_pool::FullChainApi::new(client.clone()); - Ok(sc_transaction_pool::BasicPool::new( - config, - std::sync::Arc::new(pool_api), - prometheus_registry, - )) - })? - .with_import_queue(|_config, client, mut select_chain, _transaction_pool, spawn_task_handle| { - let select_chain = select_chain.take() - .ok_or_else(|| sc_service::Error::SelectChainRequired)?; - let (grandpa_block_import, grandpa_link) = grandpa::block_import( - client.clone(), - &(client.clone() as Arc<_>), - select_chain, - )?; - let justification_import = grandpa_block_import.clone(); - - let (block_import, babe_link) = sc_consensus_babe::block_import( - sc_consensus_babe::Config::get_or_compute(&*client)?, - grandpa_block_import, - client.clone(), - )?; - - let import_queue = sc_consensus_babe::import_queue( - babe_link.clone(), - block_import.clone(), - Some(Box::new(justification_import)), - None, - client, - inherent_data_providers.clone(), - spawn_task_handle, - )?; - - import_setup = Some((block_import, grandpa_link, babe_link)); - Ok(import_queue) - })? - .with_rpc_extensions(|builder| -> std::result::Result { - let babe_link = import_setup.as_ref().map(|s| &s.2) - .expect("BabeLink is present for full services or set up failed; qed."); - let grandpa_link = import_setup.as_ref().map(|s| &s.1) - .expect("GRANDPA LinkHalf is present for full services or set up failed; qed."); - let shared_authority_set = grandpa_link.shared_authority_set(); - let shared_voter_state = grandpa::SharedVoterState::empty(); - let deps = node_rpc::FullDeps { - client: builder.client().clone(), - pool: builder.pool(), - select_chain: builder.select_chain().cloned() - .expect("SelectChain is present for full services or set up failed; qed."), - babe: node_rpc::BabeDeps { - keystore: builder.keystore(), - babe_config: sc_consensus_babe::BabeLink::config(babe_link).clone(), - shared_epoch_changes: sc_consensus_babe::BabeLink::epoch_changes(babe_link).clone() - }, - grandpa: node_rpc::GrandpaDeps { - shared_voter_state: shared_voter_state.clone(), - shared_authority_set: shared_authority_set.clone(), - }, - }; - rpc_setup = Some((shared_voter_state)); - Ok(node_rpc::create_full(deps)) - })?; +use sc_network::{Event, NetworkService}; +use sp_runtime::traits::Block as BlockT; +use futures::prelude::*; +use sc_client_api::{ExecutorProvider, RemoteBackend}; +use sp_core::traits::BareCryptoStorePtr; +use node_executor::Executor; + +type FullClient = sc_service::TFullClient; +type FullBackend = sc_service::TFullBackend; +type FullSelectChain = sc_consensus::LongestChain; +type FullGrandpaBlockImport = + grandpa::GrandpaBlockImport; +type LightClient = sc_service::TLightClient; + +pub fn new_partial(config: &Configuration) -> Result, + sc_transaction_pool::FullPool, + ( + impl Fn( + node_rpc::DenyUnsafe, + jsonrpc_pubsub::manager::SubscriptionManager + ) -> node_rpc::IoHandler, + ( + sc_consensus_babe::BabeBlockImport, + grandpa::LinkHalf, + sc_consensus_babe::BabeLink, + ), + grandpa::SharedVoterState, + ) +>, ServiceError> { + let (client, backend, keystore, task_manager) = + sc_service::new_full_parts::(&config)?; + let client = Arc::new(client); + + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + + let transaction_pool = sc_transaction_pool::BasicPool::new_full( + config.transaction_pool.clone(), + config.prometheus_registry(), + task_manager.spawn_handle(), + client.clone(), + ); + + let (grandpa_block_import, grandpa_link) = grandpa::block_import( + client.clone(), &(client.clone() as Arc<_>), select_chain.clone(), + )?; + let justification_import = grandpa_block_import.clone(); + + let (block_import, babe_link) = sc_consensus_babe::block_import( + sc_consensus_babe::Config::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + )?; + + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); + + let import_queue = sc_consensus_babe::import_queue( + babe_link.clone(), + block_import.clone(), + Some(Box::new(justification_import)), + None, + client.clone(), + select_chain.clone(), + inherent_data_providers.clone(), + &task_manager.spawn_handle(), + config.prometheus_registry(), + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()), + )?; + + let import_setup = (block_import, grandpa_link, babe_link); + + let (rpc_extensions_builder, rpc_setup) = { + let (_, grandpa_link, babe_link) = &import_setup; + + let justification_stream = grandpa_link.justification_stream(); + let shared_authority_set = grandpa_link.shared_authority_set().clone(); + let shared_voter_state = grandpa::SharedVoterState::empty(); + + let rpc_setup = shared_voter_state.clone(); + + let babe_config = babe_link.config().clone(); + let shared_epoch_changes = babe_link.epoch_changes().clone(); + + let client = client.clone(); + let pool = transaction_pool.clone(); + let select_chain = select_chain.clone(); + let keystore = keystore.clone(); + + let rpc_extensions_builder = move |deny_unsafe, subscriptions| { + let deps = node_rpc::FullDeps { + client: client.clone(), + pool: pool.clone(), + select_chain: select_chain.clone(), + deny_unsafe, + babe: node_rpc::BabeDeps { + babe_config: babe_config.clone(), + shared_epoch_changes: shared_epoch_changes.clone(), + keystore: keystore.clone(), + }, + grandpa: node_rpc::GrandpaDeps { + shared_voter_state: shared_voter_state.clone(), + shared_authority_set: shared_authority_set.clone(), + justification_stream: justification_stream.clone(), + subscriptions, + }, + }; + + node_rpc::create_full(deps) + }; - (builder, import_setup, inherent_data_providers, rpc_setup) - }} + (rpc_extensions_builder, rpc_setup) + }; + + Ok(sc_service::PartialComponents { + client, backend, task_manager, keystore, select_chain, import_queue, transaction_pool, + inherent_data_providers, + other: (rpc_extensions_builder, import_setup, rpc_setup) + }) } /// Creates a full service from the configuration. -/// -/// We need to use a macro because the test suit doesn't work with an opaque service. It expects -/// concrete types instead. -macro_rules! new_full { - ($config:expr, $with_startup_data: expr) => {{ - use futures::prelude::*; - use sc_network::Event; - use sc_client_api::ExecutorProvider; - - let ( - role, - force_authoring, - name, - disable_grandpa, - ) = ( - $config.role.clone(), - $config.force_authoring, - $config.network.node_name.clone(), - $config.disable_grandpa, +pub fn new_full_base( + config: Configuration, + with_startup_data: impl FnOnce( + &sc_consensus_babe::BabeBlockImport, + &sc_consensus_babe::BabeLink, + ) +) -> Result<( + TaskManager, InherentDataProviders, Arc, + Arc::Hash>>, + Arc>, +), ServiceError> { + let sc_service::PartialComponents { + client, backend, mut task_manager, import_queue, keystore, select_chain, transaction_pool, + inherent_data_providers, + other: (rpc_extensions_builder, import_setup, rpc_setup), + } = new_partial(&config)?; + + let finality_proof_provider = + GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone()); + + let (network, network_status_sinks, system_rpc_tx, network_starter) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + on_demand: None, + block_announce_validator_builder: None, + finality_proof_request_builder: None, + finality_proof_provider: Some(finality_proof_provider.clone()), + })?; + + if config.offchain_worker.enabled { + sc_service::build_offchain_workers( + &config, backend.clone(), task_manager.spawn_handle(), client.clone(), network.clone(), ); + } - let (builder, mut import_setup, inherent_data_providers, mut rpc_setup) = - new_full_start!($config); - - let service = builder - .with_finality_proof_provider(|client, backend| { - // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider - let provider = client as Arc>; - Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, provider)) as _) - })? - .build()?; - - let (block_import, grandpa_link, babe_link) = import_setup.take() - .expect("Link Half and Block Import are present for Full Services or setup failed before. qed"); - - let shared_voter_state = rpc_setup.take() - .expect("The SharedVoterState is present for Full Services or setup failed before. qed"); - - ($with_startup_data)(&block_import, &babe_link); - - if let sc_service::config::Role::Authority { .. } = &role { - let proposer = sc_basic_authorship::ProposerFactory::new( - service.client(), - service.transaction_pool() - ); - - let client = service.client(); - let select_chain = service.select_chain() - .ok_or(sc_service::Error::SelectChainRequired)?; - - let can_author_with = - sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); - - let babe_config = sc_consensus_babe::BabeParams { - keystore: service.keystore(), - client, - select_chain, - env: proposer, - block_import, - sync_oracle: service.network(), - inherent_data_providers: inherent_data_providers.clone(), - force_authoring, - babe_link, - can_author_with, - }; + let role = config.role.clone(); + let force_authoring = config.force_authoring; + let name = config.network.node_name.clone(); + let enable_grandpa = !config.disable_grandpa; + let prometheus_registry = config.prometheus_registry().cloned(); + let telemetry_connection_sinks = sc_service::TelemetryConnectionSinks::default(); + + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + config, + backend: backend.clone(), + client: client.clone(), + keystore: keystore.clone(), + network: network.clone(), + rpc_extensions_builder: Box::new(rpc_extensions_builder), + transaction_pool: transaction_pool.clone(), + task_manager: &mut task_manager, + on_demand: None, + remote_blockchain: None, + telemetry_connection_sinks: telemetry_connection_sinks.clone(), + network_status_sinks, + system_rpc_tx, + })?; + + let (block_import, grandpa_link, babe_link) = import_setup; + let shared_voter_state = rpc_setup; + + (with_startup_data)(&block_import, &babe_link); + + if let sc_service::config::Role::Authority { .. } = &role { + let proposer = sc_basic_authorship::ProposerFactory::new( + client.clone(), + transaction_pool.clone(), + prometheus_registry.as_ref(), + ); - let babe = sc_consensus_babe::start_babe(babe_config)?; - service.spawn_essential_task("babe-proposer", babe); - } - - // Spawn authority discovery module. - if matches!(role, sc_service::config::Role::Authority{..} | sc_service::config::Role::Sentry {..}) { - let (sentries, authority_discovery_role) = match role { - sc_service::config::Role::Authority { ref sentry_nodes } => ( - sentry_nodes.clone(), - sc_authority_discovery::Role::Authority ( - service.keystore(), - ), - ), - sc_service::config::Role::Sentry {..} => ( - vec![], - sc_authority_discovery::Role::Sentry, + let can_author_with = + sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone()); + + let babe_config = sc_consensus_babe::BabeParams { + keystore: keystore.clone(), + client: client.clone(), + select_chain, + env: proposer, + block_import, + sync_oracle: network.clone(), + inherent_data_providers: inherent_data_providers.clone(), + force_authoring, + babe_link, + can_author_with, + }; + + let babe = sc_consensus_babe::start_babe(babe_config)?; + task_manager.spawn_essential_handle().spawn_blocking("babe-proposer", babe); + } + + // Spawn authority discovery module. + if matches!(role, Role::Authority{..} | Role::Sentry {..}) { + let (sentries, authority_discovery_role) = match role { + sc_service::config::Role::Authority { ref sentry_nodes } => ( + sentry_nodes.clone(), + sc_authority_discovery::Role::Authority ( + keystore.clone(), ), - _ => unreachable!("Due to outer matches! constraint; qed.") - }; + ), + sc_service::config::Role::Sentry {..} => ( + vec![], + sc_authority_discovery::Role::Sentry, + ), + _ => unreachable!("Due to outer matches! constraint; qed.") + }; - let network = service.network(); - let dht_event_stream = network.event_stream("authority-discovery").filter_map(|e| async move { match e { + let dht_event_stream = network.event_stream("authority-discovery") + .filter_map(|e| async move { match e { Event::Dht(e) => Some(e), _ => None, }}).boxed(); - let authority_discovery = sc_authority_discovery::AuthorityDiscovery::new( - service.client(), - network, - sentries, - dht_event_stream, - authority_discovery_role, - service.prometheus_registry(), - ); - - service.spawn_task("authority-discovery", authority_discovery); - } - - // if the node isn't actively participating in consensus then it doesn't - // need a keystore, regardless of which protocol we use below. - let keystore = if role.is_authority() { - Some(service.keystore()) - } else { - None - }; + let (authority_discovery_worker, _service) = sc_authority_discovery::new_worker_and_service( + client.clone(), + network.clone(), + sentries, + dht_event_stream, + authority_discovery_role, + prometheus_registry.clone(), + ); - let config = grandpa::Config { - // FIXME #1578 make this available through chainspec - gossip_duration: std::time::Duration::from_millis(333), - justification_period: 512, - name: Some(name), - observer_enabled: false, - keystore, - is_authority: role.is_network_authority(), + task_manager.spawn_handle().spawn("authority-discovery-worker", authority_discovery_worker); + } + + // if the node isn't actively participating in consensus then it doesn't + // need a keystore, regardless of which protocol we use below. + let keystore = if role.is_authority() { + Some(keystore as BareCryptoStorePtr) + } else { + None + }; + + let config = grandpa::Config { + // FIXME #1578 make this available through chainspec + gossip_duration: std::time::Duration::from_millis(333), + justification_period: 512, + name: Some(name), + observer_enabled: false, + keystore, + is_authority: role.is_network_authority(), + }; + + if enable_grandpa { + // start the full GRANDPA voter + // NOTE: non-authorities could run the GRANDPA observer protocol, but at + // this point the full voter should provide better guarantees of block + // and vote data availability than the observer. The observer has not + // been tested extensively yet and having most nodes in a network run it + // could lead to finality stalls. + let grandpa_config = grandpa::GrandpaParams { + config, + link: grandpa_link, + network: network.clone(), + inherent_data_providers: inherent_data_providers.clone(), + telemetry_on_connect: Some(telemetry_connection_sinks.on_connect_stream()), + voting_rule: grandpa::VotingRulesBuilder::default().build(), + prometheus_registry, + shared_voter_state, }; - let enable_grandpa = !disable_grandpa; - if enable_grandpa { - // start the full GRANDPA voter - // NOTE: non-authorities could run the GRANDPA observer protocol, but at - // this point the full voter should provide better guarantees of block - // and vote data availability than the observer. The observer has not - // been tested extensively yet and having most nodes in a network run it - // could lead to finality stalls. - let grandpa_config = grandpa::GrandpaParams { - config, - link: grandpa_link, - network: service.network(), - inherent_data_providers: inherent_data_providers.clone(), - telemetry_on_connect: Some(service.telemetry_on_connect_stream()), - voting_rule: grandpa::VotingRulesBuilder::default().build(), - prometheus_registry: service.prometheus_registry(), - shared_voter_state, - }; + // the GRANDPA voter task is considered infallible, i.e. + // if it fails we take down the service with it. + task_manager.spawn_essential_handle().spawn_blocking( + "grandpa-voter", + grandpa::run_grandpa_voter(grandpa_config)? + ); + } else { + grandpa::setup_disabled_grandpa( + client.clone(), + &inherent_data_providers, + network.clone(), + )?; + } - // the GRANDPA voter task is considered infallible, i.e. - // if it fails we take down the service with it. - service.spawn_essential_task( - "grandpa-voter", - grandpa::run_grandpa_voter(grandpa_config)? - ); - } else { - grandpa::setup_disabled_grandpa( - service.client(), - &inherent_data_providers, - service.network(), - )?; - } - - Ok((service, inherent_data_providers)) - }}; - ($config:expr) => {{ - new_full!($config, |_, _| {}) - }} + network_starter.start_network(); + Ok((task_manager, inherent_data_providers, client, network, transaction_pool)) } /// Builds a new service for a full client. pub fn new_full(config: Configuration) --> Result -{ - new_full!(config).map(|(service, _)| service) +-> Result { + new_full_base(config, |_, _| ()).map(|(task_manager, _, _, _, _)| { + task_manager + }) } -/// Builds a new service for a light client. -pub fn new_light(config: Configuration) --> Result { - type RpcExtension = jsonrpc_core::IoHandler; - let inherent_data_providers = InherentDataProviders::new(); - - let service = ServiceBuilder::new_light::(config)? - .with_select_chain(|_config, backend| { - Ok(LongestChain::new(backend.clone())) - })? - .with_transaction_pool(|config, client, fetcher, prometheus_registry| { - let fetcher = fetcher - .ok_or_else(|| "Trying to start light transaction pool without active fetcher")?; - let pool_api = sc_transaction_pool::LightChainApi::new(client.clone(), fetcher.clone()); - let pool = sc_transaction_pool::BasicPool::with_revalidation_type( - config, Arc::new(pool_api), prometheus_registry, sc_transaction_pool::RevalidationType::Light, - ); - Ok(pool) - })? - .with_import_queue_and_fprb(|_config, client, backend, fetcher, _select_chain, _tx_pool, spawn_task_handle| { - let fetch_checker = fetcher - .map(|fetcher| fetcher.checker().clone()) - .ok_or_else(|| "Trying to start light import queue without active fetch checker")?; - let grandpa_block_import = grandpa::light_block_import( - client.clone(), - backend, - &(client.clone() as Arc<_>), - Arc::new(fetch_checker), - )?; - - let finality_proof_import = grandpa_block_import.clone(); - let finality_proof_request_builder = - finality_proof_import.create_finality_proof_request_builder(); - - let (babe_block_import, babe_link) = sc_consensus_babe::block_import( - sc_consensus_babe::Config::get_or_compute(&*client)?, - grandpa_block_import, - client.clone(), - )?; - - let import_queue = sc_consensus_babe::import_queue( - babe_link, - babe_block_import, - None, - Some(Box::new(finality_proof_import)), - client.clone(), - inherent_data_providers.clone(), - spawn_task_handle, - )?; - - Ok((import_queue, finality_proof_request_builder)) - })? - .with_finality_proof_provider(|client, backend| { - // GenesisAuthoritySetProvider is implemented for StorageAndProofProvider - let provider = client as Arc>; - Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _) - })? - .with_rpc_extensions(|builder,| -> - Result - { - let fetcher = builder.fetcher() - .ok_or_else(|| "Trying to start node RPC without active fetcher")?; - let remote_blockchain = builder.remote_backend() - .ok_or_else(|| "Trying to start node RPC without active remote blockchain")?; - - let light_deps = node_rpc::LightDeps { - remote_blockchain, - fetcher, - client: builder.client().clone(), - pool: builder.pool(), - }; - Ok(node_rpc::create_light(light_deps)) - })? - .build()?; +pub fn new_light_base(config: Configuration) -> Result<( + TaskManager, RpcHandlers, Arc, + Arc::Hash>>, + Arc>> +), ServiceError> { + let (client, backend, keystore, mut task_manager, on_demand) = + sc_service::new_light_parts::(&config)?; + + let select_chain = sc_consensus::LongestChain::new(backend.clone()); + + let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light( + config.transaction_pool.clone(), + config.prometheus_registry(), + task_manager.spawn_handle(), + client.clone(), + on_demand.clone(), + )); + + let grandpa_block_import = grandpa::light_block_import( + client.clone(), backend.clone(), &(client.clone() as Arc<_>), + Arc::new(on_demand.checker().clone()), + )?; + + let finality_proof_import = grandpa_block_import.clone(); + let finality_proof_request_builder = + finality_proof_import.create_finality_proof_request_builder(); + + let (babe_block_import, babe_link) = sc_consensus_babe::block_import( + sc_consensus_babe::Config::get_or_compute(&*client)?, + grandpa_block_import, + client.clone(), + )?; + + let inherent_data_providers = sp_inherents::InherentDataProviders::new(); + + let import_queue = sc_consensus_babe::import_queue( + babe_link, + babe_block_import, + None, + Some(Box::new(finality_proof_import)), + client.clone(), + select_chain.clone(), + inherent_data_providers.clone(), + &task_manager.spawn_handle(), + config.prometheus_registry(), + sp_consensus::NeverCanAuthor, + )?; + + let finality_proof_provider = + GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone()); + + let (network, network_status_sinks, system_rpc_tx, network_starter) = + sc_service::build_network(sc_service::BuildNetworkParams { + config: &config, + client: client.clone(), + transaction_pool: transaction_pool.clone(), + spawn_handle: task_manager.spawn_handle(), + import_queue, + on_demand: Some(on_demand.clone()), + block_announce_validator_builder: None, + finality_proof_request_builder: Some(finality_proof_request_builder), + finality_proof_provider: Some(finality_proof_provider), + })?; + network_starter.start_network(); + + if config.offchain_worker.enabled { + sc_service::build_offchain_workers( + &config, backend.clone(), task_manager.spawn_handle(), client.clone(), network.clone(), + ); + } + + let light_deps = node_rpc::LightDeps { + remote_blockchain: backend.remote_blockchain(), + fetcher: on_demand.clone(), + client: client.clone(), + pool: transaction_pool.clone(), + }; + + let rpc_extensions = node_rpc::create_light(light_deps); + + let rpc_handlers = + sc_service::spawn_tasks(sc_service::SpawnTasksParams { + on_demand: Some(on_demand), + remote_blockchain: Some(backend.remote_blockchain()), + rpc_extensions_builder: Box::new(sc_service::NoopRpcExtensionBuilder(rpc_extensions)), + client: client.clone(), + transaction_pool: transaction_pool.clone(), + config, keystore, backend, network_status_sinks, system_rpc_tx, + network: network.clone(), + telemetry_connection_sinks: sc_service::TelemetryConnectionSinks::default(), + task_manager: &mut task_manager, + })?; + + Ok((task_manager, rpc_handlers, client, network, transaction_pool)) +} - Ok(service) +/// Builds a new service for a light client. +pub fn new_light(config: Configuration) -> Result { + new_light_base(config).map(|(task_manager, _, _, _, _)| { + task_manager + }) } #[cfg(test)] mod tests { use std::{sync::Arc, borrow::Cow, any::Any}; - use sc_consensus_babe::{ - CompatibleDigestItem, BabeIntermediate, INTERMEDIATE_KEY - }; + use sc_consensus_babe::{CompatibleDigestItem, BabeIntermediate, INTERMEDIATE_KEY}; use sc_consensus_epochs::descendent_query; use sp_consensus::{ Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy, BlockImport, @@ -380,101 +456,24 @@ mod tests { use node_primitives::{Block, DigestItem, Signature}; use node_runtime::{BalancesCall, Call, UncheckedExtrinsic, Address}; use node_runtime::constants::{currency::CENTS, time::SLOT_DURATION}; - use codec::{Encode, Decode}; + use codec::Encode; use sp_core::{crypto::Pair as CryptoPair, H256}; use sp_runtime::{ generic::{BlockId, Era, Digest, SignedPayload}, traits::{Block as BlockT, Header as HeaderT}, traits::Verify, - OpaqueExtrinsic, }; use sp_timestamp; use sp_finality_tracker; use sp_keyring::AccountKeyring; - use sc_service::AbstractService; - use crate::service::{new_full, new_light}; + use sc_service_test::TestNetNode; + use crate::service::{new_full_base, new_light_base}; use sp_runtime::traits::IdentifyAccount; use sp_transaction_pool::{MaintainedTransactionPool, ChainEvent}; + use sc_client_api::BlockBackend; type AccountPublic = ::Signer; - #[cfg(feature = "rhd")] - fn test_sync() { - use sp_core::ed25519::Pair; - - use {service_test, Factory}; - use sp_consensus::{BlockImportParams, BlockOrigin}; - - let alice: Arc = Arc::new(Keyring::Alice.into()); - let bob: Arc = Arc::new(Keyring::Bob.into()); - let validators = vec![alice.public().0.into(), bob.public().0.into()]; - let keys: Vec<&ed25519::Pair> = vec![&*alice, &*bob]; - let dummy_runtime = ::tokio::runtime::Runtime::new().unwrap(); - let block_factory = |service: &::FullService| { - let block_id = BlockId::number(service.client().chain_info().best_number); - let parent_header = service.client().best_header(&block_id) - .expect("db error") - .expect("best block should exist"); - - futures::executor::block_on( - service.transaction_pool().maintain( - ChainEvent::NewBlock { - is_new_best: true, - id: block_id.clone(), - retracted: vec![], - header: parent_header, - }, - ) - ); - - let consensus_net = ConsensusNetwork::new(service.network(), service.client().clone()); - let proposer_factory = consensus::ProposerFactory { - client: service.client().clone(), - transaction_pool: service.transaction_pool().clone(), - network: consensus_net, - force_delay: 0, - handle: dummy_runtime.executor(), - }; - let (proposer, _, _) = proposer_factory.init(&parent_header, &validators, alice.clone()).unwrap(); - let block = proposer.propose().expect("Error making test block"); - BlockImportParams { - origin: BlockOrigin::File, - justification: Vec::new(), - internal_justification: Vec::new(), - finalized: false, - body: Some(block.extrinsics), - storage_changes: None, - header: block.header, - auxiliary: Vec::new(), - } - }; - let extrinsic_factory = - |service: &SyncService<::FullService>| - { - let payload = ( - 0, - Call::Balances(BalancesCall::transfer(RawAddress::Id(bob.public().0.into()), 69.into())), - Era::immortal(), - service.client().genesis_hash() - ); - let signature = alice.sign(&payload.encode()).into(); - let id = alice.public().0.into(); - let xt = UncheckedExtrinsic { - signature: Some((RawAddress::Id(id), signature, payload.0, Era::immortal())), - function: payload.1, - }.encode(); - let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); - OpaqueExtrinsic(v) - }; - sc_service_test::sync( - sc_chain_spec::integration_test_config(), - |config| new_full(config), - |mut config| new_light(config), - block_factory, - extrinsic_factory, - ); - } - #[test] // It is "ignored", but the node-cli ignored tests are running on the CI. // This can be run locally with `cargo test --release -p node-cli test_sync -- --ignored`. @@ -500,14 +499,25 @@ mod tests { chain_spec, |config| { let mut setup_handles = None; - new_full!(config, | - block_import: &sc_consensus_babe::BabeBlockImport, - babe_link: &sc_consensus_babe::BabeLink, - | { - setup_handles = Some((block_import.clone(), babe_link.clone())); - }).map(move |(node, x)| (node, (x, setup_handles.unwrap()))) + let (keep_alive, inherent_data_providers, client, network, transaction_pool) = + new_full_base(config, + | + block_import: &sc_consensus_babe::BabeBlockImport, + babe_link: &sc_consensus_babe::BabeLink, + | { + setup_handles = Some((block_import.clone(), babe_link.clone())); + } + )?; + + let node = sc_service_test::TestNetComponents::new( + keep_alive, client, network, transaction_pool + ); + Ok((node, (inherent_data_providers, setup_handles.unwrap()))) + }, + |config| { + let (keep_alive, _, client, network, transaction_pool) = new_light_base(config)?; + Ok(sc_service_test::TestNetComponents::new(keep_alive, client, network, transaction_pool)) }, - |config| new_light(config), |service, &mut (ref inherent_data_providers, (ref mut block_import, ref babe_link))| { let mut inherent_data = inherent_data_providers .create_inherent_data() @@ -521,18 +531,17 @@ mod tests { futures::executor::block_on( service.transaction_pool().maintain( - ChainEvent::NewBlock { - is_new_best: true, - id: parent_id.clone(), - retracted: vec![], - header: parent_header.clone(), + ChainEvent::NewBestBlock { + hash: parent_header.hash(), + tree_route: None, }, ) ); let mut proposer_factory = sc_basic_authorship::ProposerFactory::new( service.client(), - service.transaction_pool() + service.transaction_pool(), + None, ); let epoch_descriptor = babe_link.epoch_changes().lock().epoch_descriptor_for_child_of( @@ -602,46 +611,46 @@ mod tests { let from: Address = AccountPublic::from(charlie.public()).into_account().into(); let genesis_hash = service.client().block_hash(0).unwrap().unwrap(); let best_block_id = BlockId::number(service.client().chain_info().best_number); - let version = service.client().runtime_version_at(&best_block_id).unwrap().spec_version; + let (spec_version, transaction_version) = { + let version = service.client().runtime_version_at(&best_block_id).unwrap(); + (version.spec_version, version.transaction_version) + }; let signer = charlie.clone(); let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); - let check_version = frame_system::CheckVersion::new(); + let check_spec_version = frame_system::CheckSpecVersion::new(); + let check_tx_version = frame_system::CheckTxVersion::new(); let check_genesis = frame_system::CheckGenesis::new(); let check_era = frame_system::CheckEra::from(Era::Immortal); let check_nonce = frame_system::CheckNonce::from(index); let check_weight = frame_system::CheckWeight::new(); let payment = pallet_transaction_payment::ChargeTransactionPayment::from(0); - let validate_grandpa_equivocation = pallet_grandpa::ValidateEquivocationReport::new(); let extra = ( - check_version, + check_spec_version, + check_tx_version, check_genesis, check_era, check_nonce, check_weight, payment, - validate_grandpa_equivocation, ); let raw_payload = SignedPayload::from_raw( function, extra, - (version, genesis_hash, genesis_hash, (), (), (), ()) + (spec_version, transaction_version, genesis_hash, genesis_hash, (), (), ()) ); let signature = raw_payload.using_encoded(|payload| { signer.sign(payload) }); let (function, extra, _) = raw_payload.deconstruct(); - let xt = UncheckedExtrinsic::new_signed( + index += 1; + UncheckedExtrinsic::new_signed( function, from.into(), signature.into(), extra, - ).encode(); - let v: Vec = Decode::decode(&mut xt.as_slice()).unwrap(); - - index += 1; - OpaqueExtrinsic(v) + ).into() }, ); } @@ -651,8 +660,14 @@ mod tests { fn test_consensus() { sc_service_test::consensus( crate::chain_spec::tests::integration_test_config_with_two_authorities(), - |config| new_full(config), - |config| new_light(config), + |config| { + let (keep_alive, _, client, network, transaction_pool) = new_full_base(config, |_, _| ())?; + Ok(sc_service_test::TestNetComponents::new(keep_alive, client, network, transaction_pool)) + }, + |config| { + let (keep_alive, _, client, network, transaction_pool) = new_light_base(config)?; + Ok(sc_service_test::TestNetComponents::new(keep_alive, client, network, transaction_pool)) + }, vec![ "//Alice".into(), "//Bob".into(), diff --git a/bin/node/cli/tests/build_spec_works.rs b/bin/node/cli/tests/build_spec_works.rs index 2eca71a5b5978de1e1de20873b6584a7d5c703b0..800a4a8c51e6175e2eb8fbfb1e5ddf375d30c264 100644 --- a/bin/node/cli/tests/build_spec_works.rs +++ b/bin/node/cli/tests/build_spec_works.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use assert_cmd::cargo::cargo_bin; use std::process::Command; diff --git a/bin/node/cli/tests/check_block_works.rs b/bin/node/cli/tests/check_block_works.rs index 6bfb82a8bfafb84c1b041b87dc093e2481193ec5..34078b08cf074f218865df548ee20b3b94f19d74 100644 --- a/bin/node/cli/tests/check_block_works.rs +++ b/bin/node/cli/tests/check_block_works.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . #![cfg(unix)] @@ -20,7 +22,7 @@ use assert_cmd::cargo::cargo_bin; use std::process::Command; use tempfile::tempdir; -mod common; +pub mod common; #[test] fn check_block_works() { diff --git a/bin/node/cli/tests/common.rs b/bin/node/cli/tests/common.rs index 34e371195c16b20e216a9426f238ce6b78bcd257..61a07dd1ca877c8814169f2babdfccd3a506ec76 100644 --- a/bin/node/cli/tests/common.rs +++ b/bin/node/cli/tests/common.rs @@ -1,21 +1,22 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . #![cfg(unix)] -#![allow(dead_code)] use std::{process::{Child, ExitStatus}, thread, time::Duration, path::Path}; use assert_cmd::cargo::cargo_bin; diff --git a/bin/node/cli/tests/export_import_flow.rs b/bin/node/cli/tests/export_import_flow.rs new file mode 100644 index 0000000000000000000000000000000000000000..557e722ddb7b505a13fa8daa8361838dcfd93c45 --- /dev/null +++ b/bin/node/cli/tests/export_import_flow.rs @@ -0,0 +1,212 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +#![cfg(unix)] + +use assert_cmd::cargo::cargo_bin; +use std::{process::Command, fs, path::PathBuf}; +use tempfile::{tempdir, TempDir}; +use regex::Regex; + +pub mod common; + +fn contains_error(logged_output: &str) -> bool { + logged_output.contains("Error") +} + +/// Helper struct to execute the export/import/revert tests. +/// The fields are paths to a temporary directory +struct ExportImportRevertExecutor<'a> { + base_path: &'a TempDir, + exported_blocks_file: &'a PathBuf, + db_path: &'a PathBuf, + num_exported_blocks: Option, +} + +/// Format options for export / import commands. +enum FormatOpt { + Json, + Binary, +} + +/// Command corresponding to the different commands we would like to run. +enum SubCommand { + ExportBlocks, + ImportBlocks, +} + +impl ToString for SubCommand { + fn to_string(&self) -> String { + match self { + SubCommand::ExportBlocks => String::from("export-blocks"), + SubCommand::ImportBlocks => String::from("import-blocks"), + } + } +} + +impl<'a> ExportImportRevertExecutor<'a> { + fn new( + base_path: &'a TempDir, + exported_blocks_file: &'a PathBuf, + db_path: &'a PathBuf + ) -> Self { + Self { + base_path, + exported_blocks_file, + db_path, + num_exported_blocks: None, + } + } + + /// Helper method to run a command. Returns a string corresponding to what has been logged. + fn run_block_command(&self, + sub_command: SubCommand, + format_opt: FormatOpt, + expected_to_fail: bool + ) -> String { + let sub_command_str = sub_command.to_string(); + // Adding "--binary" if need be. + let arguments: Vec<&str> = match format_opt { + FormatOpt::Binary => vec![&sub_command_str, "--dev", "--pruning", "archive", "--binary", "-d"], + FormatOpt::Json => vec![&sub_command_str, "--dev", "--pruning", "archive", "-d"], + }; + + let tmp: TempDir; + // Setting base_path to be a temporary folder if we are importing blocks. + // This allows us to make sure we are importing from scratch. + let base_path = match sub_command { + SubCommand::ExportBlocks => &self.base_path.path(), + SubCommand::ImportBlocks => { + tmp = tempdir().unwrap(); + tmp.path() + } + }; + + // Running the command and capturing the output. + let output = Command::new(cargo_bin("substrate")) + .args(&arguments) + .arg(&base_path) + .arg(&self.exported_blocks_file) + .output() + .unwrap(); + + let logged_output = String::from_utf8_lossy(&output.stderr).to_string(); + + if expected_to_fail { + // Checking that we did indeed find an error. + assert!(contains_error(&logged_output), "expected to error but did not error!"); + assert!(!output.status.success()); + } else { + // Making sure no error were logged. + assert!(!contains_error(&logged_output), "expected not to error but error'd!"); + assert!(output.status.success()); + } + + logged_output + } + + /// Runs the `export-blocks` command. + fn run_export(&mut self, fmt_opt: FormatOpt) { + let log = self.run_block_command(SubCommand::ExportBlocks, fmt_opt, false); + + // Using regex to find out how many block we exported. + let re = Regex::new(r"Exporting blocks from #\d* to #(?P\d*)").unwrap(); + let caps = re.captures(&log).unwrap(); + // Saving the number of blocks we've exported for further use. + self.num_exported_blocks = Some(caps["exported_blocks"].parse::().unwrap()); + + let metadata = fs::metadata(&self.exported_blocks_file).unwrap(); + assert!(metadata.len() > 0, "file exported_blocks should not be empty"); + + let _ = fs::remove_dir_all(&self.db_path); + } + + /// Runs the `import-blocks` command, asserting that an error was found or + /// not depending on `expected_to_fail`. + fn run_import(&mut self, fmt_opt: FormatOpt, expected_to_fail: bool) { + let log = self.run_block_command(SubCommand::ImportBlocks, fmt_opt, expected_to_fail); + + if !expected_to_fail { + // Using regex to find out how much block we imported, + // and what's the best current block. + let re = Regex::new(r"Imported (?P\d*) blocks. Best: #(?P\d*)").unwrap(); + let caps = re.captures(&log).expect("capture should have succeeded"); + let imported = caps["imported"].parse::().unwrap(); + let best = caps["best"].parse::().unwrap(); + + assert_eq!( + imported, + best, + "numbers of blocks imported and best number differs" + ); + assert_eq!( + best, + self.num_exported_blocks.expect("number of exported blocks cannot be None; qed"), + "best block number and number of expected blocks should not differ" + ); + } + self.num_exported_blocks = None; + } + + /// Runs the `revert` command. + fn run_revert(&self) { + let output = Command::new(cargo_bin("substrate")) + .args(&["revert", "--dev", "--pruning", "archive", "-d"]) + .arg(&self.base_path.path()) + .output() + .unwrap(); + + let logged_output = String::from_utf8_lossy(&output.stderr).to_string(); + + // Reverting should not log any error. + assert!(!contains_error(&logged_output)); + // Command should never fail. + assert!(output.status.success()); + } + + /// Helper function that runs the whole export / import / revert flow and checks for errors. + fn run(&mut self, export_fmt: FormatOpt, import_fmt: FormatOpt, expected_to_fail: bool) { + self.run_export(export_fmt); + self.run_import(import_fmt, expected_to_fail); + self.run_revert(); + } +} + +#[test] +fn export_import_revert() { + let base_path = tempdir().expect("could not create a temp dir"); + let exported_blocks_file = base_path.path().join("exported_blocks"); + let db_path = base_path.path().join("db"); + + common::run_dev_node_for_a_while(base_path.path()); + + let mut executor = ExportImportRevertExecutor::new( + &base_path, + &exported_blocks_file, + &db_path, + ); + + // Binary and binary should work. + executor.run(FormatOpt::Binary, FormatOpt::Binary, false); + // Binary and JSON should fail. + executor.run(FormatOpt::Binary, FormatOpt::Json, true); + // JSON and JSON should work. + executor.run(FormatOpt::Json, FormatOpt::Json, false); + // JSON and binary should fail. + executor.run(FormatOpt::Json, FormatOpt::Binary, true); +} diff --git a/bin/node/cli/tests/import_export_and_revert_work.rs b/bin/node/cli/tests/import_export_and_revert_work.rs deleted file mode 100644 index 131265e3b4ab9bd868b9728bca6cda558d2982f2..0000000000000000000000000000000000000000 --- a/bin/node/cli/tests/import_export_and_revert_work.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -#![cfg(unix)] - -use assert_cmd::cargo::cargo_bin; -use std::{process::Command, fs}; -use tempfile::tempdir; - -mod common; - -#[test] -fn import_export_and_revert_work() { - let base_path = tempdir().expect("could not create a temp dir"); - let exported_blocks = base_path.path().join("exported_blocks"); - - common::run_dev_node_for_a_while(base_path.path()); - - let status = Command::new(cargo_bin("substrate")) - .args(&["export-blocks", "--dev", "--pruning", "archive", "-d"]) - .arg(base_path.path()) - .arg(&exported_blocks) - .status() - .unwrap(); - assert!(status.success()); - - let metadata = fs::metadata(&exported_blocks).unwrap(); - assert!(metadata.len() > 0, "file exported_blocks should not be empty"); - - let _ = fs::remove_dir_all(base_path.path().join("db")); - - let status = Command::new(cargo_bin("substrate")) - .args(&["import-blocks", "--dev", "--pruning", "archive", "-d"]) - .arg(base_path.path()) - .arg(&exported_blocks) - .status() - .unwrap(); - assert!(status.success()); - - let status = Command::new(cargo_bin("substrate")) - .args(&["revert", "--dev", "--pruning", "archive", "-d"]) - .arg(base_path.path()) - .status() - .unwrap(); - assert!(status.success()); -} diff --git a/bin/node/cli/tests/inspect_works.rs b/bin/node/cli/tests/inspect_works.rs index 441b08ccf46da1b1ef70ec49a7a46015d94f3c4c..aa9653acadba5a1db8ccd295da9d802967604a77 100644 --- a/bin/node/cli/tests/inspect_works.rs +++ b/bin/node/cli/tests/inspect_works.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . #![cfg(unix)] @@ -20,7 +22,7 @@ use assert_cmd::cargo::cargo_bin; use std::process::Command; use tempfile::tempdir; -mod common; +pub mod common; #[test] fn inspect_works() { diff --git a/bin/node/cli/tests/purge_chain_works.rs b/bin/node/cli/tests/purge_chain_works.rs index 020259d0c595a57a01b8a9b113522d826e1de912..001bed8b136f5d2349f83fe86c557466f0b7a7ca 100644 --- a/bin/node/cli/tests/purge_chain_works.rs +++ b/bin/node/cli/tests/purge_chain_works.rs @@ -1,24 +1,26 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use assert_cmd::cargo::cargo_bin; use std::process::Command; use tempfile::tempdir; -mod common; +pub mod common; #[test] #[cfg(unix)] diff --git a/bin/node/cli/tests/running_the_node_and_interrupt.rs b/bin/node/cli/tests/running_the_node_and_interrupt.rs index 67efedccbe771a65e892b5dbe94bac702d3c01ce..bd79dcd77a49a9e6a81b28ae360ef90b3174b565 100644 --- a/bin/node/cli/tests/running_the_node_and_interrupt.rs +++ b/bin/node/cli/tests/running_the_node_and_interrupt.rs @@ -1,24 +1,26 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use assert_cmd::cargo::cargo_bin; use std::{convert::TryInto, process::Command, thread, time::Duration}; use tempfile::tempdir; -mod common; +pub mod common; #[test] #[cfg(unix)] diff --git a/bin/node/cli/tests/temp_base_path_works.rs b/bin/node/cli/tests/temp_base_path_works.rs new file mode 100644 index 0000000000000000000000000000000000000000..9351568d87955b130bdde3d9f82f5ce977bc2b20 --- /dev/null +++ b/bin/node/cli/tests/temp_base_path_works.rs @@ -0,0 +1,72 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +#![cfg(unix)] + +use assert_cmd::cargo::cargo_bin; +use nix::sys::signal::{kill, Signal::SIGINT}; +use nix::unistd::Pid; +use regex::Regex; +use std::convert::TryInto; +use std::io::Read; +use std::path::PathBuf; +use std::process::{Command, Stdio}; +use std::thread; +use std::time::Duration; + +pub mod common; + +#[test] +fn temp_base_path_works() { + let mut cmd = Command::new(cargo_bin("substrate")); + + let mut cmd = cmd + .args(&["--dev", "--tmp"]) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap(); + + // Let it produce some blocks. + thread::sleep(Duration::from_secs(30)); + assert!( + cmd.try_wait().unwrap().is_none(), + "the process should still be running" + ); + + // Stop the process + kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap(); + assert!(common::wait_for(&mut cmd, 40) + .map(|x| x.success()) + .unwrap_or_default()); + + // Ensure the database has been deleted + let mut stderr = String::new(); + cmd.stderr.unwrap().read_to_string(&mut stderr).unwrap(); + let re = Regex::new(r"Database: .+ at (\S+)").unwrap(); + let db_path = PathBuf::from( + re.captures(stderr.as_str()) + .unwrap() + .get(1) + .unwrap() + .as_str() + .to_string(), + ); + + assert!(!db_path.exists()); +} diff --git a/bin/node/cli/tests/version.rs b/bin/node/cli/tests/version.rs index 6f99d7c24ae1434ff84e81ba84ee406ec6248ac4..bbc9139d4f0f8de78dfc5affd3557eb6f6b16a17 100644 --- a/bin/node/cli/tests/version.rs +++ b/bin/node/cli/tests/version.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use assert_cmd::cargo::cargo_bin; use platforms::*; @@ -20,7 +22,7 @@ use regex::Regex; use std::process::Command; fn expected_regex() -> Regex { - Regex::new(r"^substrate (\d+\.\d+\.\d+(?:-.+?)?)-([a-f\d]+|unknown-commit)-(.+?)-(.+?)(?:-(.+))?$").unwrap() + Regex::new(r"^substrate (\d+\.\d+\.\d+(?:-.+?)?)-([a-f\d]+|unknown)-(.+?)-(.+?)(?:-(.+))?$").unwrap() } #[test] diff --git a/bin/node/executor/Cargo.toml b/bin/node/executor/Cargo.toml index 99bd83bb4a2bf0c4e8f3181dcd739eccaa685690..d8fb2e4078bd15012f433263c13cf08d76b38287 100644 --- a/bin/node/executor/Cargo.toml +++ b/bin/node/executor/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "node-executor" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] description = "Substrate node implementation in Rust." edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,35 +12,35 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0" } -node-primitives = { version = "2.0.0-dev", path = "../primitives" } -node-runtime = { version = "2.0.0-dev", path = "../runtime" } -sc-executor = { version = "0.8.0-dev", path = "../../../client/executor" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } -sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } -sp-trie = { version = "2.0.0-dev", path = "../../../primitives/trie" } +codec = { package = "parity-scale-codec", version = "1.3.4" } +node-primitives = { version = "2.0.0-rc6", path = "../primitives" } +node-runtime = { version = "2.0.0-rc6", path = "../runtime" } +sc-executor = { version = "0.8.0-rc6", path = "../../../client/executor" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-rc6", path = "../../../primitives/io" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../../primitives/state-machine" } +sp-trie = { version = "2.0.0-rc6", path = "../../../primitives/trie" } trie-root = "0.16.0" -frame-benchmarking = { version = "2.0.0-dev", path = "../../../frame/benchmarking" } +frame-benchmarking = { version = "2.0.0-rc6", path = "../../../frame/benchmarking" } [dev-dependencies] criterion = "0.3.0" -frame-support = { version = "2.0.0-dev", path = "../../../frame/support" } -frame-system = { version = "2.0.0-dev", path = "../../../frame/system" } -node-testing = { version = "2.0.0-dev", path = "../testing" } -pallet-balances = { version = "2.0.0-dev", path = "../../../frame/balances" } -pallet-contracts = { version = "2.0.0-dev", path = "../../../frame/contracts" } -pallet-grandpa = { version = "2.0.0-dev", path = "../../../frame/grandpa" } -pallet-im-online = { version = "2.0.0-dev", path = "../../../frame/im-online" } -pallet-indices = { version = "2.0.0-dev", path = "../../../frame/indices" } -pallet-session = { version = "2.0.0-dev", path = "../../../frame/session" } -pallet-timestamp = { version = "2.0.0-dev", path = "../../../frame/timestamp" } -pallet-transaction-payment = { version = "2.0.0-dev", path = "../../../frame/transaction-payment" } -pallet-treasury = { version = "2.0.0-dev", path = "../../../frame/treasury" } -sp-application-crypto = { version = "2.0.0-dev", path = "../../../primitives/application-crypto" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-externalities = { version = "0.8.0-dev", path = "../../../primitives/externalities" } -substrate-test-client = { version = "2.0.0-dev", path = "../../../test-utils/client" } +frame-support = { version = "2.0.0-rc6", path = "../../../frame/support" } +frame-system = { version = "2.0.0-rc6", path = "../../../frame/system" } +node-testing = { version = "2.0.0-rc6", path = "../testing" } +pallet-balances = { version = "2.0.0-rc6", path = "../../../frame/balances" } +pallet-contracts = { version = "2.0.0-rc6", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0-rc6", path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0-rc6", path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0-rc6", path = "../../../frame/indices" } +pallet-session = { version = "2.0.0-rc6", path = "../../../frame/session" } +pallet-timestamp = { version = "2.0.0-rc6", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-rc6", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0-rc6", path = "../../../frame/treasury" } +sp-application-crypto = { version = "2.0.0-rc6", path = "../../../primitives/application-crypto" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-externalities = { version = "0.8.0-rc6", path = "../../../primitives/externalities" } +substrate-test-client = { version = "2.0.0-rc6", path = "../../../test-utils/client" } wabt = "0.9.2" [features] diff --git a/bin/node/executor/benches/bench.rs b/bin/node/executor/benches/bench.rs index 4f335df90d1ba3b1eba376601c899ec77b0909b6..168cff0ff456887246ef679d54b11ac15efabb83 100644 --- a/bin/node/executor/benches/bench.rs +++ b/bin/node/executor/benches/bench.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use codec::{Decode, Encode}; use criterion::{BatchSize, Criterion, criterion_group, criterion_main}; @@ -35,11 +36,16 @@ criterion_group!(benches, bench_execute_block); criterion_main!(benches); /// The wasm runtime code. -const COMPACT_CODE: &[u8] = node_runtime::WASM_BINARY; +pub fn compact_code_unwrap() -> &'static [u8] { + node_runtime::WASM_BINARY.expect("Development wasm binary is not available. \ + Testing is only supported with the flag disabled.") +} const GENESIS_HASH: [u8; 32] = [69u8; 32]; -const VERSION: u32 = node_runtime::VERSION.spec_version; +const TRANSACTION_VERSION: u32 = node_runtime::VERSION.transaction_version; + +const SPEC_VERSION: u32 = node_runtime::VERSION.spec_version; const HEAP_PAGES: u64 = 20; @@ -52,12 +58,12 @@ enum ExecutionMethod { } fn sign(xt: CheckedExtrinsic) -> UncheckedExtrinsic { - node_testing::keyring::sign(xt, VERSION, GENESIS_HASH) + node_testing::keyring::sign(xt, SPEC_VERSION, TRANSACTION_VERSION, GENESIS_HASH) } fn new_test_ext(genesis_config: &GenesisConfig) -> TestExternalities { let mut test_ext = TestExternalities::new_with_code( - COMPACT_CODE, + compact_code_unwrap(), genesis_config.build_storage().unwrap(), ); test_ext.ext().place_storage(well_known_keys::HEAP_PAGES.to_vec(), Some(HEAP_PAGES.encode())); @@ -91,7 +97,7 @@ fn construct_block( }; let runtime_code = RuntimeCode { - code_fetcher: &sp_core::traits::WrappedRuntimeCode(COMPACT_CODE.into()), + code_fetcher: &sp_core::traits::WrappedRuntimeCode(compact_code_unwrap().into()), hash: vec![1, 2, 3], heap_pages: None, }; @@ -165,7 +171,7 @@ fn bench_execute_block(c: &mut Criterion) { c.bench_function_over_inputs( "execute blocks", |b, strategy| { - let genesis_config = node_testing::genesis::config(false, Some(COMPACT_CODE)); + let genesis_config = node_testing::genesis::config(false, Some(compact_code_unwrap())); let (use_native, wasm_method) = match strategy { ExecutionMethod::Native => (true, WasmExecutionMethod::Interpreted), ExecutionMethod::Wasm(wasm_method) => (false, *wasm_method), @@ -173,7 +179,7 @@ fn bench_execute_block(c: &mut Criterion) { let executor = NativeExecutor::new(wasm_method, None, 8); let runtime_code = RuntimeCode { - code_fetcher: &sp_core::traits::WrappedRuntimeCode(COMPACT_CODE.into()), + code_fetcher: &sp_core::traits::WrappedRuntimeCode(compact_code_unwrap().into()), hash: vec![1, 2, 3], heap_pages: None, }; diff --git a/bin/node/executor/src/lib.rs b/bin/node/executor/src/lib.rs index bcc7f48507398cd0ea15319460f8d13e6058f2ec..4c3b82bc7d3b538234d470a5560ca61db28976b7 100644 --- a/bin/node/executor/src/lib.rs +++ b/bin/node/executor/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! A `CodeExecutor` specialization which uses natively compiled runtime when the wasm to be //! executed is equivalent to the natively compiled code. diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 47d5f3f3844e552dd3b2d2cf9af6370248cb2ac1..e7744200bccd64fb7bcf44d595e918a7d6c8eab8 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -1,31 +1,30 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use codec::{Encode, Decode, Joiner}; use frame_support::{ StorageValue, StorageMap, traits::Currency, - weights::{GetDispatchInfo, DispatchInfo, DispatchClass, constants::ExtrinsicBaseWeight}, -}; -use sp_core::{ - NeverNativeValue, map, traits::Externalities, storage::{well_known_keys, Storage}, + weights::{GetDispatchInfo, DispatchInfo, DispatchClass}, }; +use sp_core::{NeverNativeValue, traits::Externalities, storage::well_known_keys}; use sp_runtime::{ - ApplyExtrinsicResult, Fixed128, - traits::{Hash as HashT, Convert, BlakeTwo256}, + ApplyExtrinsicResult, + traits::Hash as HashT, transaction_validity::InvalidTransaction, }; use pallet_contracts::ContractAddressFor; @@ -33,7 +32,7 @@ use frame_system::{self, EventRecord, Phase}; use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, - System, TransactionPayment, Event, TransactionByteFee, + System, TransactionPayment, Event, constants::currency::*, }; use node_primitives::{Balance, Hash}; @@ -48,18 +47,22 @@ use self::common::{*, sign}; /// The idea here is to pass it as the current runtime code to the executor so the executor will /// have to execute provided wasm code instead of the native equivalent. This trick is used to /// test code paths that differ between native and wasm versions. -pub const BLOATY_CODE: &[u8] = node_runtime::WASM_BINARY_BLOATY; - -/// Default transfer fee -fn transfer_fee(extrinsic: &E, fee_multiplier: Fixed128) -> Balance { - let length_fee = TransactionByteFee::get() * (extrinsic.encode().len() as Balance); - - let base_weight = ExtrinsicBaseWeight::get(); - let base_fee = ::WeightToFee::convert(base_weight); - let weight = default_transfer_call().get_dispatch_info().weight; - let weight_fee = ::WeightToFee::convert(weight); +pub fn bloaty_code_unwrap() -> &'static [u8] { + node_runtime::WASM_BINARY_BLOATY.expect("Development wasm binary is not available. \ + Testing is only supported with the flag disabled.") +} - base_fee + fee_multiplier.saturated_multiply_accumulate(length_fee + weight_fee) +/// Default transfer fee. This will use the same logic that is implemented in transaction-payment module. +/// +/// Note that reads the multiplier from storage directly, hence to get the fee of `extrinsic` +/// at block `n`, it must be called prior to executing block `n` to do the calculation with the +/// correct multiplier. +fn transfer_fee(extrinsic: &E) -> Balance { + TransactionPayment::compute_fee( + extrinsic.encode().len() as u32, + &default_transfer_call().get_dispatch_info(), + 0, + ) } fn xt() -> UncheckedExtrinsic { @@ -75,7 +78,7 @@ fn set_heap_pages(ext: &mut E, heap_pages: u64) { fn changes_trie_block() -> (Vec, Hash) { construct_block( - &mut new_test_ext(COMPACT_CODE, true), + &mut new_test_ext(compact_code_unwrap(), true), 1, GENESIS_HASH.into(), vec![ @@ -95,7 +98,7 @@ fn changes_trie_block() -> (Vec, Hash) { /// are not guaranteed to be deterministic) and to ensure that the correct state is propagated /// from block1's execution to block2 to derive the correct storage_root. fn blocks() -> ((Vec, Hash), (Vec, Hash)) { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); let block1 = construct_block( &mut t, 1, @@ -140,7 +143,7 @@ fn blocks() -> ((Vec, Hash), (Vec, Hash)) { fn block_with_size(time: u64, nonce: u32, size: usize) -> (Vec, Hash) { construct_block( - &mut new_test_ext(COMPACT_CODE, false), + &mut new_test_ext(compact_code_unwrap(), false), 1, GENESIS_HASH.into(), vec![ @@ -158,20 +161,13 @@ fn block_with_size(time: u64, nonce: u32, size: usize) -> (Vec, Hash) { #[test] fn panic_execution_with_foreign_code_gives_error() { - let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { - top: map![ - >::hashed_key_for(alice()) => { - (69u128, 0u8, 0u128, 0u128, 0u128).encode() - }, - >::hashed_key().to_vec() => { - 69_u128.encode() - }, - >::hashed_key_for(0) => { - vec![0u8; 32] - } - ], - children_default: map![], - }); + let mut t = new_test_ext(bloaty_code_unwrap(), false); + t.insert( + >::hashed_key_for(alice()), + (69u128, 0u8, 0u128, 0u128, 0u128).encode() + ); + t.insert(>::hashed_key().to_vec(), 69_u128.encode()); + t.insert(>::hashed_key_for(0), vec![0u8; 32]); let r = executor_call:: _>( &mut t, @@ -194,20 +190,13 @@ fn panic_execution_with_foreign_code_gives_error() { #[test] fn bad_extrinsic_with_native_equivalent_code_gives_error() { - let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { - top: map![ - >::hashed_key_for(alice()) => { - (0u32, 0u8, 69u128, 0u128, 0u128, 0u128).encode() - }, - >::hashed_key().to_vec() => { - 69_u128.encode() - }, - >::hashed_key_for(0) => { - vec![0u8; 32] - } - ], - children_default: map![], - }); + let mut t = new_test_ext(compact_code_unwrap(), false); + t.insert( + >::hashed_key_for(alice()), + (0u32, 0u8, 69u128, 0u128, 0u128, 0u128).encode() + ); + t.insert(>::hashed_key().to_vec(), 69_u128.encode()); + t.insert(>::hashed_key_for(0), vec![0u8; 32]); let r = executor_call:: _>( &mut t, @@ -230,18 +219,20 @@ fn bad_extrinsic_with_native_equivalent_code_gives_error() { #[test] fn successful_execution_with_native_equivalent_code_gives_ok() { - let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { - top: map![ - >::hashed_key_for(alice()) => { - (0u32, 0u8, 111 * DOLLARS, 0u128, 0u128, 0u128).encode() - }, - >::hashed_key().to_vec() => { - (111 * DOLLARS).encode() - }, - >::hashed_key_for(0) => vec![0u8; 32] - ], - children_default: map![], - }); + let mut t = new_test_ext(compact_code_unwrap(), false); + t.insert( + >::hashed_key_for(alice()), + (0u32, 0u8, 111 * DOLLARS, 0u128, 0u128, 0u128).encode() + ); + t.insert( + >::hashed_key_for(bob()), + (0u32, 0u8, 0 * DOLLARS, 0u128, 0u128, 0u128).encode() + ); + t.insert( + >::hashed_key().to_vec(), + (111 * DOLLARS).encode() + ); + t.insert(>::hashed_key_for(0), vec![0u8; 32]); let r = executor_call:: _>( &mut t, @@ -252,7 +243,7 @@ fn successful_execution_with_native_equivalent_code_gives_ok() { ).0; assert!(r.is_ok()); - let fm = t.execute_with(TransactionPayment::next_fee_multiplier); + let fees = t.execute_with(|| transfer_fee(&xt())); let r = executor_call:: _>( &mut t, @@ -264,7 +255,6 @@ fn successful_execution_with_native_equivalent_code_gives_ok() { assert!(r.is_ok()); t.execute_with(|| { - let fees = transfer_fee(&xt(), fm); assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -272,18 +262,20 @@ fn successful_execution_with_native_equivalent_code_gives_ok() { #[test] fn successful_execution_with_foreign_code_gives_ok() { - let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { - top: map![ - >::hashed_key_for(alice()) => { - (0u32, 0u8, 111 * DOLLARS, 0u128, 0u128, 0u128).encode() - }, - >::hashed_key().to_vec() => { - (111 * DOLLARS).encode() - }, - >::hashed_key_for(0) => vec![0u8; 32] - ], - children_default: map![], - }); + let mut t = new_test_ext(bloaty_code_unwrap(), false); + t.insert( + >::hashed_key_for(alice()), + (0u32, 0u8, 111 * DOLLARS, 0u128, 0u128, 0u128).encode() + ); + t.insert( + >::hashed_key_for(bob()), + (0u32, 0u8, 0 * DOLLARS, 0u128, 0u128, 0u128).encode() + ); + t.insert( + >::hashed_key().to_vec(), + (111 * DOLLARS).encode() + ); + t.insert(>::hashed_key_for(0), vec![0u8; 32]); let r = executor_call:: _>( &mut t, @@ -294,7 +286,7 @@ fn successful_execution_with_foreign_code_gives_ok() { ).0; assert!(r.is_ok()); - let fm = t.execute_with(TransactionPayment::next_fee_multiplier); + let fees = t.execute_with(|| transfer_fee(&xt())); let r = executor_call:: _>( &mut t, @@ -306,7 +298,6 @@ fn successful_execution_with_foreign_code_gives_ok() { assert!(r.is_ok()); t.execute_with(|| { - let fees = transfer_fee(&xt(), fm); assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -314,12 +305,15 @@ fn successful_execution_with_foreign_code_gives_ok() { #[test] fn full_native_block_import_works() { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); let (block1, block2) = blocks(); let mut alice_last_known_balance: Balance = Default::default(); - let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier); + let mut fees = t.execute_with(|| transfer_fee(&xt())); + + let transfer_weight = default_transfer_call().get_dispatch_info().weight; + let timestamp_weight = pallet_timestamp::Call::set::(Default::default()).get_dispatch_info().weight; executor_call:: _>( &mut t, @@ -330,16 +324,14 @@ fn full_native_block_import_works() { ).0.unwrap(); t.execute_with(|| { - let fees = transfer_fee(&xt(), fm); assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); alice_last_known_balance = Balances::total_balance(&alice()); let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - // timestamp set call with weight 8_000_000 + 2 read + 1 write event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 8_000_000 + 2 * 25_000_000 + 1 * 100_000_000, class: DispatchClass::Mandatory, ..Default::default() } + DispatchInfo { weight: timestamp_weight, class: DispatchClass::Mandatory, ..Default::default() } )), topics: vec![], }, @@ -359,9 +351,8 @@ fn full_native_block_import_works() { }, EventRecord { phase: Phase::ApplyExtrinsic(1), - // Balance Transfer 70_000_000 + 1 Read + 1 Write event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 70_000_000 + 25_000_000 + 100_000_000, ..Default::default() } + DispatchInfo { weight: transfer_weight, ..Default::default() } )), topics: vec![], }, @@ -369,7 +360,7 @@ fn full_native_block_import_works() { assert_eq!(System::events(), events); }); - fm = t.execute_with(TransactionPayment::next_fee_multiplier); + fees = t.execute_with(|| transfer_fee(&xt())); executor_call:: _>( &mut t, @@ -380,7 +371,6 @@ fn full_native_block_import_works() { ).0.unwrap(); t.execute_with(|| { - let fees = transfer_fee(&xt(), fm); assert_eq!( Balances::total_balance(&alice()), alice_last_known_balance - 10 * DOLLARS - fees, @@ -392,9 +382,8 @@ fn full_native_block_import_works() { let events = vec![ EventRecord { phase: Phase::ApplyExtrinsic(0), - // timestamp set call with weight 8_000_000 + 2 read + 1 write event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 8_000_000 + 2 * 25_000_000 + 1 * 100_000_000, class: DispatchClass::Mandatory, ..Default::default() } + DispatchInfo { weight: timestamp_weight, class: DispatchClass::Mandatory, ..Default::default() } )), topics: vec![], }, @@ -416,9 +405,8 @@ fn full_native_block_import_works() { }, EventRecord { phase: Phase::ApplyExtrinsic(1), - // Balance Transfer 70_000_000 + 1 Read + 1 Write event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 70_000_000 + 25_000_000 + 100_000_000, ..Default::default() } + DispatchInfo { weight: transfer_weight, ..Default::default() } )), topics: vec![], }, @@ -440,9 +428,8 @@ fn full_native_block_import_works() { }, EventRecord { phase: Phase::ApplyExtrinsic(2), - // Balance Transfer 70_000_000 + 1 Read + 1 Write event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess( - DispatchInfo { weight: 70_000_000 + 25_000_000 + 100_000_000, ..Default::default() } + DispatchInfo { weight: transfer_weight, ..Default::default() } )), topics: vec![], }, @@ -453,12 +440,12 @@ fn full_native_block_import_works() { #[test] fn full_wasm_block_import_works() { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); let (block1, block2) = blocks(); let mut alice_last_known_balance: Balance = Default::default(); - let mut fm = t.execute_with(TransactionPayment::next_fee_multiplier); + let mut fees = t.execute_with(|| transfer_fee(&xt())); executor_call:: _>( &mut t, @@ -469,12 +456,12 @@ fn full_wasm_block_import_works() { ).0.unwrap(); t.execute_with(|| { - assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - transfer_fee(&xt(), fm)); + assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 169 * DOLLARS); alice_last_known_balance = Balances::total_balance(&alice()); }); - fm = t.execute_with(TransactionPayment::next_fee_multiplier); + fees = t.execute_with(|| transfer_fee(&xt())); executor_call:: _>( &mut t, @@ -487,50 +474,49 @@ fn full_wasm_block_import_works() { t.execute_with(|| { assert_eq!( Balances::total_balance(&alice()), - alice_last_known_balance - 10 * DOLLARS - transfer_fee(&xt(), fm), + alice_last_known_balance - 10 * DOLLARS - fees, ); assert_eq!( Balances::total_balance(&bob()), - 179 * DOLLARS - 1 * transfer_fee(&xt(), fm), + 179 * DOLLARS - 1 * fees, ); }); } const CODE_TRANSFER: &str = r#" (module -;; ext_call( +;; seal_call( ;; callee_ptr: u32, ;; callee_len: u32, ;; gas: u64, ;; value_ptr: u32, ;; value_len: u32, ;; input_data_ptr: u32, -;; input_data_len: u32 +;; input_data_len: u32, +;; output_ptr: u32, +;; output_len_ptr: u32 ;; ) -> u32 -(import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) -(import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) -(import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) +(import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) +(import "seal0" "seal_input" (func $seal_input (param i32 i32))) (import "env" "memory" (memory 1 1)) (func (export "deploy") ) (func (export "call") (block $fail - ;; load and check the input data (which is stored in the scratch buffer). + ;; Load input data to contract memory + (call $seal_input + (i32.const 0) + (i32.const 52) + ) + ;; fail if the input size is not != 4 (br_if $fail (i32.ne (i32.const 4) - (call $ext_scratch_size) + (i32.load (i32.const 52)) ) ) - (call $ext_scratch_read - (i32.const 0) - (i32.const 0) - (i32.const 4) - ) - - (br_if $fail (i32.ne (i32.load8_u (i32.const 0)) @@ -557,7 +543,7 @@ const CODE_TRANSFER: &str = r#" ) (drop - (call $ext_call + (call $seal_call (i32.const 4) ;; Pointer to "callee" address. (i32.const 32) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -565,6 +551,8 @@ const CODE_TRANSFER: &str = r#" (i32.const 16) ;; Length of the buffer with value to transfer. (i32.const 0) ;; Pointer to input data buffer address (i32.const 0) ;; Length of input data buffer + (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this case ) ) @@ -585,6 +573,8 @@ const CODE_TRANSFER: &str = r#" "\06\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00" "\00\00" ) +;; Length of the input buffer +(data (i32.const 52) "\04") ) "#; @@ -599,8 +589,10 @@ fn deploying_wasm_contract_should_work() { &charlie(), ); + let subsistence = pallet_contracts::Config::::subsistence_threshold_uncached(); + let b = construct_block( - &mut new_test_ext(COMPACT_CODE, false), + &mut new_test_ext(compact_code_unwrap(), false), 1, GENESIS_HASH.into(), vec![ @@ -618,7 +610,7 @@ fn deploying_wasm_contract_should_work() { signed: Some((charlie(), signed_extra(1, 0))), function: Call::Contracts( pallet_contracts::Call::instantiate::( - 1 * DOLLARS, + 1 * DOLLARS + subsistence, 500_000_000, transfer_ch, Vec::new() @@ -639,7 +631,7 @@ fn deploying_wasm_contract_should_work() { ] ); - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); executor_call:: _>( &mut t, @@ -663,7 +655,7 @@ fn deploying_wasm_contract_should_work() { #[test] fn wasm_big_block_import_fails() { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); set_heap_pages(&mut t.ext(), 4); @@ -679,7 +671,7 @@ fn wasm_big_block_import_fails() { #[test] fn native_big_block_import_succeeds() { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); executor_call:: _>( &mut t, @@ -692,7 +684,7 @@ fn native_big_block_import_succeeds() { #[test] fn native_big_block_import_fails_on_fallback() { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); assert!( executor_call:: _>( @@ -707,15 +699,13 @@ fn native_big_block_import_fails_on_fallback() { #[test] fn panic_execution_gives_error() { - let mut t = TestExternalities::::new_with_code(BLOATY_CODE, Storage { - top: map![ - >::hashed_key().to_vec() => { - 0_u128.encode() - }, - >::hashed_key_for(0) => vec![0u8; 32] - ], - children_default: map![], - }); + let mut t = new_test_ext(bloaty_code_unwrap(), false); + t.insert( + >::hashed_key_for(alice()), + (0u32, 0u8, 0 * DOLLARS, 0u128, 0u128, 0u128).encode() + ); + t.insert(>::hashed_key().to_vec(), 0_u128.encode()); + t.insert(>::hashed_key_for(0), vec![0u8; 32]); let r = executor_call:: _>( &mut t, @@ -738,18 +728,20 @@ fn panic_execution_gives_error() { #[test] fn successful_execution_gives_ok() { - let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { - top: map![ - >::hashed_key_for(alice()) => { - (0u32, 0u8, 111 * DOLLARS, 0u128, 0u128, 0u128).encode() - }, - >::hashed_key().to_vec() => { - (111 * DOLLARS).encode() - }, - >::hashed_key_for(0) => vec![0u8; 32] - ], - children_default: map![], - }); + let mut t = new_test_ext(compact_code_unwrap(), false); + t.insert( + >::hashed_key_for(alice()), + (0u32, 0u8, 111 * DOLLARS, 0u128, 0u128, 0u128).encode() + ); + t.insert( + >::hashed_key_for(bob()), + (0u32, 0u8, 0 * DOLLARS, 0u128, 0u128, 0u128).encode() + ); + t.insert( + >::hashed_key().to_vec(), + (111 * DOLLARS).encode() + ); + t.insert(>::hashed_key_for(0), vec![0u8; 32]); let r = executor_call:: _>( &mut t, @@ -759,7 +751,12 @@ fn successful_execution_gives_ok() { None, ).0; assert!(r.is_ok()); - let fm = t.execute_with(TransactionPayment::next_fee_multiplier); + t.execute_with(|| { + assert_eq!(Balances::total_balance(&alice()), 111 * DOLLARS); + }); + + let fees = t.execute_with(|| transfer_fee(&xt())); + let r = executor_call:: _>( &mut t, "BlockBuilder_apply_extrinsic", @@ -773,7 +770,6 @@ fn successful_execution_gives_ok() { .expect("Extrinsic failed"); t.execute_with(|| { - let fees = transfer_fee(&xt(), fm); assert_eq!(Balances::total_balance(&alice()), 42 * DOLLARS - fees); assert_eq!(Balances::total_balance(&bob()), 69 * DOLLARS); }); @@ -785,7 +781,7 @@ fn full_native_block_import_works_with_changes_trie() { let block_data = block1.0; let block = Block::decode(&mut &block_data[..]).unwrap(); - let mut t = new_test_ext(COMPACT_CODE, true); + let mut t = new_test_ext(compact_code_unwrap(), true); executor_call:: _>( &mut t, "Core_execute_block", @@ -801,7 +797,7 @@ fn full_native_block_import_works_with_changes_trie() { fn full_wasm_block_import_works_with_changes_trie() { let block1 = changes_trie_block(); - let mut t = new_test_ext(COMPACT_CODE, true); + let mut t = new_test_ext(compact_code_unwrap(), true); executor_call:: _>( &mut t, "Core_execute_block", diff --git a/bin/node/executor/tests/common.rs b/bin/node/executor/tests/common.rs index 5a51e4312c5e80315c3b05fc5a82bc72a6842fb2..efc54ebebf1990188862460b26d5d314080e2a83 100644 --- a/bin/node/executor/tests/common.rs +++ b/bin/node/executor/tests/common.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use codec::{Encode, Decode}; use frame_system::offchain::AppCrypto; @@ -67,16 +68,21 @@ impl AppCrypto for TestAuthorityId { /// making the binary slimmer. There is a convention to use compact version of the runtime /// as canonical. This is why `native_executor_instance` also uses the compact version of the /// runtime. -pub const COMPACT_CODE: &[u8] = node_runtime::WASM_BINARY; +pub fn compact_code_unwrap() -> &'static [u8] { + node_runtime::WASM_BINARY.expect("Development wasm binary is not available. \ + Testing is only supported with the flag disabled.") +} pub const GENESIS_HASH: [u8; 32] = [69u8; 32]; -pub const VERSION: u32 = node_runtime::VERSION.spec_version; +pub const SPEC_VERSION: u32 = node_runtime::VERSION.spec_version; + +pub const TRANSACTION_VERSION: u32 = node_runtime::VERSION.transaction_version; pub type TestExternalities = CoreTestExternalities; pub fn sign(xt: CheckedExtrinsic) -> UncheckedExtrinsic { - node_testing::keyring::sign(xt, VERSION, GENESIS_HASH) + node_testing::keyring::sign(xt, SPEC_VERSION, TRANSACTION_VERSION, GENESIS_HASH) } pub fn default_transfer_call() -> pallet_balances::Call { diff --git a/bin/node/executor/tests/fees.rs b/bin/node/executor/tests/fees.rs index c7d6bb34cd5d93dfea6727735879af834433ccab..b39cf344e6034af0608f848b5ae87722bee5fc28 100644 --- a/bin/node/executor/tests/fees.rs +++ b/bin/node/executor/tests/fees.rs @@ -1,33 +1,33 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use codec::{Encode, Joiner}; use frame_support::{ StorageValue, StorageMap, traits::Currency, - weights::{GetDispatchInfo, constants::ExtrinsicBaseWeight}, + weights::{GetDispatchInfo, constants::ExtrinsicBaseWeight, IdentityFee, WeightToFeePolynomial}, }; -use sp_core::{NeverNativeValue, map, storage::Storage}; -use sp_runtime::{Fixed128, Perbill, traits::{Convert, BlakeTwo256}}; +use sp_core::NeverNativeValue; +use sp_runtime::{Perbill, FixedPointNumber}; use node_runtime::{ - CheckedExtrinsic, Call, Runtime, Balances, TransactionPayment, - TransactionByteFee, WeightFeeCoefficient, + CheckedExtrinsic, Call, Runtime, Balances, TransactionPayment, Multiplier, + TransactionByteFee, constants::currency::*, }; -use node_runtime::impls::LinearWeightToFee; use node_primitives::Balance; use node_testing::keyring::*; @@ -36,16 +36,16 @@ use self::common::{*, sign}; #[test] fn fee_multiplier_increases_and_decreases_on_big_weight() { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); - // initial fee multiplier must be zero - let mut prev_multiplier = Fixed128::from_parts(0); + // initial fee multiplier must be one. + let mut prev_multiplier = Multiplier::one(); t.execute_with(|| { assert_eq!(TransactionPayment::next_fee_multiplier(), prev_multiplier); }); - let mut tt = new_test_ext(COMPACT_CODE, false); + let mut tt = new_test_ext(compact_code_unwrap(), false); // big one in terms of weight. let block1 = construct_block( @@ -59,7 +59,7 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() { }, CheckedExtrinsic { signed: Some((charlie(), signed_extra(0, 0))), - function: Call::System(frame_system::Call::fill_block(Perbill::from_percent(90))), + function: Call::System(frame_system::Call::fill_block(Perbill::from_percent(60))), } ] ); @@ -122,7 +122,7 @@ fn fee_multiplier_increases_and_decreases_on_big_weight() { } #[test] -fn transaction_fee_is_correct_ultimate() { +fn transaction_fee_is_correct() { // This uses the exact values of substrate-node. // // weight of transfer call as of now: 1_000_000 @@ -130,21 +130,20 @@ fn transaction_fee_is_correct_ultimate() { // - 1 MILLICENTS in substrate node. // - 1 milli-dot based on current polkadot runtime. // (this baed on assigning 0.1 CENT to the cheapest tx with `weight = 100`) - let mut t = TestExternalities::::new_with_code(COMPACT_CODE, Storage { - top: map![ - >::hashed_key_for(alice()) => { - (0u32, 0u8, 100 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() - }, - >::hashed_key_for(bob()) => { - (0u32, 0u8, 10 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() - }, - >::hashed_key().to_vec() => { - (110 * DOLLARS).encode() - }, - >::hashed_key_for(0) => vec![0u8; 32] - ], - children_default: map![], - }); + let mut t = new_test_ext(compact_code_unwrap(), false); + t.insert( + >::hashed_key_for(alice()), + (0u32, 0u8, 100 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() + ); + t.insert( + >::hashed_key_for(bob()), + (0u32, 0u8, 10 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS, 0 * DOLLARS).encode() + ); + t.insert( + >::hashed_key().to_vec(), + (110 * DOLLARS).encode() + ); + t.insert(>::hashed_key_for(0), vec![0u8; 32]); let tip = 1_000_000; let xt = sign(CheckedExtrinsic { @@ -181,13 +180,13 @@ fn transaction_fee_is_correct_ultimate() { let mut balance_alice = (100 - 69) * DOLLARS; let base_weight = ExtrinsicBaseWeight::get(); - let base_fee = LinearWeightToFee::::convert(base_weight); + let base_fee = IdentityFee::::calc(&base_weight); let length_fee = TransactionByteFee::get() * (xt.clone().encode().len() as Balance); balance_alice -= length_fee; let weight = default_transfer_call().get_dispatch_info().weight; - let weight_fee = LinearWeightToFee::::convert(weight); + let weight_fee = IdentityFee::::calc(&weight); // we know that weight to fee multiplier is effect-less in block 1. // current weight of transfer = 200_000_000 @@ -210,9 +209,9 @@ fn block_weight_capacity_report() { use node_primitives::Index; // execution ext. - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); // setup ext. - let mut tt = new_test_ext(COMPACT_CODE, false); + let mut tt = new_test_ext(compact_code_unwrap(), false); let factor = 50; let mut time = 10; @@ -277,9 +276,9 @@ fn block_length_capacity_report() { use node_primitives::Index; // execution ext. - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); // setup ext. - let mut tt = new_test_ext(COMPACT_CODE, false); + let mut tt = new_test_ext(compact_code_unwrap(), false); let factor = 256 * 1024; let mut time = 10; diff --git a/bin/node/executor/tests/submit_transaction.rs b/bin/node/executor/tests/submit_transaction.rs index 4c4e4b085505e02a497bbb677fe3862c8de89091..64c2deedac788ea8681ea54c93ec09125d8e1684 100644 --- a/bin/node/executor/tests/submit_transaction.rs +++ b/bin/node/executor/tests/submit_transaction.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use node_runtime::{ Executive, Indices, Runtime, UncheckedExtrinsic, @@ -40,7 +41,7 @@ use self::common::*; #[test] fn should_submit_unsigned_transaction() { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); let (pool, state) = TestTransactionPoolExt::new(); t.register_extension(TransactionPoolExt::new(pool)); @@ -66,7 +67,7 @@ const PHRASE: &str = "news slush supreme milk chapter athlete soap sausage put c #[test] fn should_submit_signed_transaction() { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); let (pool, state) = TestTransactionPoolExt::new(); t.register_extension(TransactionPoolExt::new(pool)); @@ -91,7 +92,7 @@ fn should_submit_signed_transaction() { #[test] fn should_submit_signed_twice_from_the_same_account() { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); let (pool, state) = TestTransactionPoolExt::new(); t.register_extension(TransactionPoolExt::new(pool)); @@ -122,7 +123,7 @@ fn should_submit_signed_twice_from_the_same_account() { let s = state.read(); fn nonce(tx: UncheckedExtrinsic) -> frame_system::CheckNonce { let extra = tx.signature.unwrap().2; - extra.3 + extra.4 } let nonce1 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[0]).unwrap()); let nonce2 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[1]).unwrap()); @@ -135,7 +136,7 @@ fn should_submit_signed_twice_from_the_same_account() { #[test] fn should_submit_signed_twice_from_all_accounts() { - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); let (pool, state) = TestTransactionPoolExt::new(); t.register_extension(TransactionPoolExt::new(pool)); @@ -170,7 +171,7 @@ fn should_submit_signed_twice_from_all_accounts() { let s = state.read(); fn nonce(tx: UncheckedExtrinsic) -> frame_system::CheckNonce { let extra = tx.signature.unwrap().2; - extra.3 + extra.4 } let nonce1 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[0]).unwrap()); let nonce2 = nonce(UncheckedExtrinsic::decode(&mut &*s.transactions[1]).unwrap()); @@ -191,10 +192,10 @@ fn should_submit_signed_twice_from_all_accounts() { fn submitted_transaction_should_be_valid() { use codec::Encode; use frame_support::storage::StorageMap; - use sp_runtime::transaction_validity::{ValidTransaction, TransactionSource}; + use sp_runtime::transaction_validity::{TransactionSource, TransactionTag}; use sp_runtime::traits::StaticLookup; - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); let (pool, state) = TestTransactionPoolExt::new(); t.register_extension(TransactionPoolExt::new(pool)); @@ -215,7 +216,7 @@ fn submitted_transaction_should_be_valid() { // check that transaction is valid, but reset environment storage, // since CreateTransaction increments the nonce let tx0 = state.read().transactions[0].clone(); - let mut t = new_test_ext(COMPACT_CODE, false); + let mut t = new_test_ext(compact_code_unwrap(), false); t.execute_with(|| { let source = TransactionSource::External; let extrinsic = UncheckedExtrinsic::decode(&mut &*tx0).unwrap(); @@ -227,14 +228,12 @@ fn submitted_transaction_should_be_valid() { >::insert(&address, account); // check validity - let res = Executive::validate_transaction(source, extrinsic); - - assert_eq!(res.unwrap(), ValidTransaction { - priority: 1_410_710_000_000, - requires: vec![], - provides: vec![(address, 0).encode()], - longevity: 128, - propagate: true, - }); + let res = Executive::validate_transaction(source, extrinsic).unwrap(); + + // We ignore res.priority since this number can change based on updates to weights and such. + assert_eq!(res.requires, Vec::::new()); + assert_eq!(res.provides, vec![(address, 0).encode()]); + assert_eq!(res.longevity, 2048); + assert_eq!(res.propagate, true); }); } diff --git a/bin/node/inspect/Cargo.toml b/bin/node/inspect/Cargo.toml index 03d3a94b6277822397af4945b53ed41ddd27f2ce..f8dc32f1e0587be4da1d39ae7dee8e7b9ba7f731 100644 --- a/bin/node/inspect/Cargo.toml +++ b/bin/node/inspect/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "node-inspect" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -11,13 +11,13 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0" } +codec = { package = "parity-scale-codec", version = "1.3.4" } derive_more = "0.99" log = "0.4.8" -sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } -sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } -sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sc-cli = { version = "0.8.0-rc6", path = "../../../client/cli" } +sc-client-api = { version = "2.0.0-rc6", path = "../../../client/api" } +sc-service = { version = "0.8.0-rc6", default-features = false, path = "../../../client/service" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } structopt = "0.3.8" diff --git a/bin/node/inspect/src/cli.rs b/bin/node/inspect/src/cli.rs index 5d51bd5848f17d308933fdcb69d429504fa8445e..d66644bab52fa78788098e3713ceae1576f25b6c 100644 --- a/bin/node/inspect/src/cli.rs +++ b/bin/node/inspect/src/cli.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Structs to easily compose inspect sub-command for CLI. @@ -21,7 +23,7 @@ use sc_cli::{ImportParams, SharedParams}; use structopt::StructOpt; /// The `inspect` command used to print decoded chain data. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct InspectCmd { #[allow(missing_docs)] #[structopt(flatten)] @@ -37,7 +39,7 @@ pub struct InspectCmd { } /// A possible inspect sub-commands. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub enum InspectSubCmd { /// Decode block with native version of runtime and print out the details. Block { diff --git a/bin/node/inspect/src/command.rs b/bin/node/inspect/src/command.rs index 2212907f763138feef1607b2236bdbbf7e0867a3..fae6c10c7fe7846dc63e990dcf03254655467705 100644 --- a/bin/node/inspect/src/command.rs +++ b/bin/node/inspect/src/command.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Command ran by the CLI diff --git a/bin/node/inspect/src/lib.rs b/bin/node/inspect/src/lib.rs index b8101d98a31ce717b4a57f9ee939abe2444253a9..02f5614b81a78044d1418d9d23f87322da2c298c 100644 --- a/bin/node/inspect/src/lib.rs +++ b/bin/node/inspect/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. - -// Substrate is free software: you can redistribute it and/or modify +// +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 +// +// 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. - -// Substrate is distributed in the hope that it will be useful, +// +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A CLI extension for substrate node, adding sub-command to pretty print debug info //! about blocks and extrinsics. diff --git a/bin/node/primitives/Cargo.toml b/bin/node/primitives/Cargo.toml index e69b626b5420fdccefbb7eec36014d05e6599857..15fc493289fee3303b78c70d3dd870ebebbdcf4e 100644 --- a/bin/node/primitives/Cargo.toml +++ b/bin/node/primitives/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "node-primitives" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -11,14 +11,14 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../../../frame/system" } -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/application-crypto" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/system" } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/application-crypto" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/runtime" } [dev-dependencies] -sp-serializer = { version = "2.0.0-dev", path = "../../../primitives/serializer" } +sp-serializer = { version = "2.0.0-rc6", path = "../../../primitives/serializer" } pretty_assertions = "0.6.1" [features] diff --git a/bin/node/primitives/src/lib.rs b/bin/node/primitives/src/lib.rs index 6e02e68add5578a9a4244ed1292a1f81df275709..137fb1d94c778aafa6b2f45713d4954070caa1d5 100644 --- a/bin/node/primitives/src/lib.rs +++ b/bin/node/primitives/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Low-level types used throughout the Substrate code. diff --git a/bin/node/rpc-client/Cargo.toml b/bin/node/rpc-client/Cargo.toml index 1df3590d1fe833f2e2c93c98cf4dfc2aa5501c2f..698aa8f08aea5efcaf6d53cb3a6462121f1c12c0 100644 --- a/bin/node/rpc-client/Cargo.toml +++ b/bin/node/rpc-client/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "node-rpc-client" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -14,7 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] env_logger = "0.7.0" futures = "0.1.29" hyper = "0.12.35" -jsonrpc-core-client = { version = "14.0.5", default-features = false, features = ["http"] } +jsonrpc-core-client = { version = "14.2.0", default-features = false, features = ["http"] } log = "0.4.8" -node-primitives = { version = "2.0.0-dev", path = "../primitives" } -sc-rpc = { version = "2.0.0-dev", path = "../../../client/rpc" } +node-primitives = { version = "2.0.0-rc6", path = "../primitives" } +sc-rpc = { version = "2.0.0-rc6", path = "../../../client/rpc" } diff --git a/bin/node/rpc-client/src/main.rs b/bin/node/rpc-client/src/main.rs index c547d30002d795b07ffc9468027bf1c06f17b877..eadd1c8d472476b6db57570d08a0233d36bea45d 100644 --- a/bin/node/rpc-client/src/main.rs +++ b/bin/node/rpc-client/src/main.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. #![warn(missing_docs)] diff --git a/bin/node/rpc/Cargo.toml b/bin/node/rpc/Cargo.toml index f0c5fc250b0cb9fdd539e662ed64758c037a5df4..9ed8c22fbe320b5ea8e97a2b4f7fa8287813d0f8 100644 --- a/bin/node/rpc/Cargo.toml +++ b/bin/node/rpc/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "node-rpc" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -11,22 +11,25 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } -jsonrpc-core = "14.0.3" -node-primitives = { version = "2.0.0-dev", path = "../primitives" } -node-runtime = { version = "2.0.0-dev", path = "../runtime" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -pallet-contracts-rpc = { version = "0.8.0-dev", path = "../../../frame/contracts/rpc/" } -pallet-transaction-payment-rpc = { version = "2.0.0-dev", path = "../../../frame/transaction-payment/rpc/" } -substrate-frame-rpc-system = { version = "2.0.0-dev", path = "../../../utils/frame/rpc/system" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } -sc-consensus-babe = { version = "0.8.0-dev", path = "../../../client/consensus/babe" } -sc-consensus-babe-rpc = { version = "0.8.0-dev", path = "../../../client/consensus/babe/rpc" } -sp-consensus-babe = { version = "0.8.0-dev", path = "../../../primitives/consensus/babe" } -sc-keystore = { version = "2.0.0-dev", path = "../../../client/keystore" } -sc-consensus-epochs = { version = "0.8.0-dev", path = "../../../client/consensus/epochs" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sc-finality-grandpa = { version = "0.8.0-dev", path = "../../../client/finality-grandpa" } -sc-finality-grandpa-rpc = { version = "0.8.0-dev", path = "../../../client/finality-grandpa/rpc" } +jsonrpc-core = "14.2.0" +jsonrpc-pubsub = "14.2.0" +node-primitives = { version = "2.0.0-rc6", path = "../primitives" } +node-runtime = { version = "2.0.0-rc6", path = "../runtime" } +pallet-contracts-rpc = { version = "0.8.0-rc6", path = "../../../frame/contracts/rpc/" } +pallet-transaction-payment-rpc = { version = "2.0.0-rc6", path = "../../../frame/transaction-payment/rpc/" } +sc-client-api = { version = "2.0.0-rc6", path = "../../../client/api" } +sc-consensus-babe = { version = "0.8.0-rc6", path = "../../../client/consensus/babe" } +sc-consensus-babe-rpc = { version = "0.8.0-rc6", path = "../../../client/consensus/babe/rpc" } +sc-consensus-epochs = { version = "0.8.0-rc6", path = "../../../client/consensus/epochs" } +sc-finality-grandpa = { version = "0.8.0-rc6", path = "../../../client/finality-grandpa" } +sc-finality-grandpa-rpc = { version = "0.8.0-rc6", path = "../../../client/finality-grandpa/rpc" } +sc-keystore = { version = "2.0.0-rc6", path = "../../../client/keystore" } +sc-rpc-api = { version = "0.8.0-rc6", path = "../../../client/rpc-api" } +sc-rpc = { version = "2.0.0-rc6", path = "../../../client/rpc" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +sp-block-builder = { version = "2.0.0-rc6", path = "../../../primitives/block-builder" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sp-consensus-babe = { version = "0.8.0-rc6", path = "../../../primitives/consensus/babe" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../../primitives/transaction-pool" } +substrate-frame-rpc-system = { version = "2.0.0-rc6", path = "../../../utils/frame/rpc/system" } diff --git a/bin/node/rpc/src/lib.rs b/bin/node/rpc/src/lib.rs index 114179c0047e2c580f4657cadd12e6d011a62eb0..a20fb03ebe1e6be0d6c663885971336ce6d8c0f9 100644 --- a/bin/node/rpc/src/lib.rs +++ b/bin/node/rpc/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! A collection of node-specific RPC methods. //! @@ -29,21 +30,23 @@ #![warn(missing_docs)] -use std::{sync::Arc, fmt}; +use std::sync::Arc; +use jsonrpc_pubsub::manager::SubscriptionManager; use node_primitives::{Block, BlockNumber, AccountId, Index, Balance, Hash}; -use node_runtime::UncheckedExtrinsic; +use sc_consensus_babe::{Config, Epoch}; +use sc_consensus_babe_rpc::BabeRpcHandler; +use sc_consensus_epochs::SharedEpochChanges; +use sc_finality_grandpa::{SharedVoterState, SharedAuthoritySet, GrandpaJustificationStream}; +use sc_finality_grandpa_rpc::GrandpaRpcHandler; +use sc_keystore::KeyStorePtr; +pub use sc_rpc_api::DenyUnsafe; use sp_api::ProvideRuntimeApi; -use sp_transaction_pool::TransactionPool; +use sp_block_builder::BlockBuilder; use sp_blockchain::{Error as BlockChainError, HeaderMetadata, HeaderBackend}; use sp_consensus::SelectChain; -use sc_keystore::KeyStorePtr; use sp_consensus_babe::BabeApi; -use sc_consensus_epochs::SharedEpochChanges; -use sc_consensus_babe::{Config, Epoch}; -use sc_consensus_babe_rpc::BabeRPCHandler; -use sc_finality_grandpa::{SharedVoterState, SharedAuthoritySet}; -use sc_finality_grandpa_rpc::GrandpaRpcHandler; +use sp_transaction_pool::TransactionPool; /// Light client extra dependencies. pub struct LightDeps { @@ -73,6 +76,10 @@ pub struct GrandpaDeps { pub shared_voter_state: SharedVoterState, /// Authority set info. pub shared_authority_set: SharedAuthoritySet, + /// Receives notifications about justification events from Grandpa. + pub justification_stream: GrandpaJustificationStream, + /// Subscription manager to keep track of pubsub subscribers. + pub subscriptions: SubscriptionManager, } /// Full client dependencies. @@ -83,26 +90,30 @@ pub struct FullDeps { pub pool: Arc

, /// The SelectChain Strategy pub select_chain: SC, + /// Whether to deny unsafe calls + pub deny_unsafe: DenyUnsafe, /// BABE specific dependencies. pub babe: BabeDeps, /// GRANDPA specific dependencies. pub grandpa: GrandpaDeps, } +/// A IO handler that uses all Full RPC extensions. +pub type IoHandler = jsonrpc_core::IoHandler; + /// Instantiate all Full RPC extensions. -pub fn create_full( +pub fn create_full( deps: FullDeps, -) -> jsonrpc_core::IoHandler where +) -> jsonrpc_core::IoHandler where C: ProvideRuntimeApi, C: HeaderBackend + HeaderMetadata + 'static, C: Send + Sync + 'static, C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: pallet_contracts_rpc::ContractsRuntimeApi, - C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, + C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, C::Api: BabeApi, - ::Error: fmt::Debug, + C::Api: BlockBuilder, P: TransactionPool + 'static, - M: jsonrpc_core::Metadata + Default, SC: SelectChain +'static, { use substrate_frame_rpc_system::{FullSystem, SystemApi}; @@ -114,9 +125,11 @@ pub fn create_full( client, pool, select_chain, + deny_unsafe, babe, grandpa, } = deps; + let BabeDeps { keystore, babe_config, @@ -125,10 +138,12 @@ pub fn create_full( let GrandpaDeps { shared_voter_state, shared_authority_set, + justification_stream, + subscriptions, } = grandpa; io.extend_with( - SystemApi::to_delegate(FullSystem::new(client.clone(), pool)) + SystemApi::to_delegate(FullSystem::new(client.clone(), pool, deny_unsafe)) ); // Making synchronous calls in light client freezes the browser currently, // more context: https://github.com/paritytech/substrate/pull/3480 @@ -141,12 +156,24 @@ pub fn create_full( ); io.extend_with( sc_consensus_babe_rpc::BabeApi::to_delegate( - BabeRPCHandler::new(client, shared_epoch_changes, keystore, babe_config, select_chain) + BabeRpcHandler::new( + client, + shared_epoch_changes, + keystore, + babe_config, + select_chain, + deny_unsafe, + ), ) ); io.extend_with( sc_finality_grandpa_rpc::GrandpaApi::to_delegate( - GrandpaRpcHandler::new(shared_authority_set, shared_voter_state) + GrandpaRpcHandler::new( + shared_authority_set, + shared_voter_state, + justification_stream, + subscriptions, + ) ) ); @@ -173,7 +200,7 @@ pub fn create_light( } = deps; let mut io = jsonrpc_core::IoHandler::default(); io.extend_with( - SystemApi::::to_delegate(LightSystem::new(client, remote_blockchain, fetcher, pool)) + SystemApi::::to_delegate(LightSystem::new(client, remote_blockchain, fetcher, pool)) ); io diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 00d1c6dd722b20ac012ffddd45cfc4c57cbac5c2..1195456b0fadadcec4ea4b9debb1f19529ce856e 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "node-runtime" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -14,73 +14,77 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] # third-party dependencies -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } integer-sqrt = { version = "0.1.2" } serde = { version = "1.0.102", optional = true } +static_assertions = "1.1.0" +hex-literal = { version = "0.3.1", optional = true } # primitives -sp-authority-discovery = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/authority-discovery" } -sp-consensus-babe = { version = "0.8.0-dev", default-features = false, path = "../../../primitives/consensus/babe" } -sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-dev"} -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/inherents" } -node-primitives = { version = "2.0.0-dev", default-features = false, path = "../primitives" } -sp-offchain = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/offchain" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } -sp-api = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } -sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/staking" } -sp-keyring = { version = "2.0.0-dev", optional = true, path = "../../../primitives/keyring" } -sp-session = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/session" } -sp-transaction-pool = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/transaction-pool" } -sp-version = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/version" } +sp-authority-discovery = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/authority-discovery" } +sp-consensus-babe = { version = "0.8.0-rc6", default-features = false, path = "../../../primitives/consensus/babe" } +sp-block-builder = { path = "../../../primitives/block-builder", default-features = false, version = "2.0.0-rc6"} +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/inherents" } +node-primitives = { version = "2.0.0-rc6", default-features = false, path = "../primitives" } +sp-offchain = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/offchain" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/std" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/runtime" } +sp-staking = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/staking" } +sp-keyring = { version = "2.0.0-rc6", optional = true, path = "../../../primitives/keyring" } +sp-session = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/session" } +sp-transaction-pool = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/transaction-pool" } +sp-version = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/version" } # frame dependencies -frame-executive = { version = "2.0.0-dev", default-features = false, path = "../../../frame/executive" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../../../frame/benchmarking", optional = true } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../../../frame/support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../../../frame/system" } -frame-system-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../../../frame/system/benchmarking", optional = true } -frame-system-rpc-runtime-api = { version = "2.0.0-dev", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } -pallet-authority-discovery = { version = "2.0.0-dev", default-features = false, path = "../../../frame/authority-discovery" } -pallet-authorship = { version = "2.0.0-dev", default-features = false, path = "../../../frame/authorship" } -pallet-babe = { version = "2.0.0-dev", default-features = false, path = "../../../frame/babe" } -pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../../../frame/balances" } -pallet-collective = { version = "2.0.0-dev", default-features = false, path = "../../../frame/collective" } -pallet-contracts = { version = "2.0.0-dev", default-features = false, path = "../../../frame/contracts" } -pallet-contracts-primitives = { version = "2.0.0-dev", default-features = false, path = "../../../frame/contracts/common/" } -pallet-contracts-rpc-runtime-api = { version = "0.8.0-dev", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } -pallet-democracy = { version = "2.0.0-dev", default-features = false, path = "../../../frame/democracy" } -pallet-elections-phragmen = { version = "2.0.0-dev", default-features = false, path = "../../../frame/elections-phragmen" } -pallet-finality-tracker = { version = "2.0.0-dev", default-features = false, path = "../../../frame/finality-tracker" } -pallet-grandpa = { version = "2.0.0-dev", default-features = false, path = "../../../frame/grandpa" } -pallet-im-online = { version = "2.0.0-dev", default-features = false, path = "../../../frame/im-online" } -pallet-indices = { version = "2.0.0-dev", default-features = false, path = "../../../frame/indices" } -pallet-identity = { version = "2.0.0-dev", default-features = false, path = "../../../frame/identity" } -pallet-membership = { version = "2.0.0-dev", default-features = false, path = "../../../frame/membership" } -pallet-offences = { version = "2.0.0-dev", default-features = false, path = "../../../frame/offences" } -pallet-offences-benchmarking = { version = "2.0.0-dev", path = "../../../frame/offences/benchmarking", default-features = false, optional = true } -pallet-randomness-collective-flip = { version = "2.0.0-dev", default-features = false, path = "../../../frame/randomness-collective-flip" } -pallet-recovery = { version = "2.0.0-dev", default-features = false, path = "../../../frame/recovery" } -pallet-session = { version = "2.0.0-dev", features = ["historical"], path = "../../../frame/session", default-features = false } -pallet-session-benchmarking = { version = "2.0.0-dev", path = "../../../frame/session/benchmarking", default-features = false, optional = true } -pallet-staking = { version = "2.0.0-dev", default-features = false, path = "../../../frame/staking" } -pallet-staking-reward-curve = { version = "2.0.0-dev", default-features = false, path = "../../../frame/staking/reward-curve" } -pallet-scheduler = { version = "2.0.0-dev", default-features = false, path = "../../../frame/scheduler" } -pallet-society = { version = "2.0.0-dev", default-features = false, path = "../../../frame/society" } -pallet-sudo = { version = "2.0.0-dev", default-features = false, path = "../../../frame/sudo" } -pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../../frame/timestamp" } -pallet-treasury = { version = "2.0.0-dev", default-features = false, path = "../../../frame/treasury" } -pallet-utility = { version = "2.0.0-dev", default-features = false, path = "../../../frame/utility" } -pallet-transaction-payment = { version = "2.0.0-dev", default-features = false, path = "../../../frame/transaction-payment" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-dev", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } -pallet-vesting = { version = "2.0.0-dev", default-features = false, path = "../../../frame/vesting" } +frame-executive = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/executive" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/benchmarking", optional = true } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/system" } +frame-system-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/system/benchmarking", optional = true } +frame-system-rpc-runtime-api = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/system/rpc/runtime-api/" } +pallet-authority-discovery = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/authority-discovery" } +pallet-authorship = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/authorship" } +pallet-babe = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/babe" } +pallet-balances = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/balances" } +pallet-collective = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/collective" } +pallet-contracts = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/contracts" } +pallet-contracts-primitives = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/contracts/common/" } +pallet-contracts-rpc-runtime-api = { version = "0.8.0-rc6", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" } +pallet-democracy = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/democracy" } +pallet-elections-phragmen = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/elections-phragmen" } +pallet-finality-tracker = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/finality-tracker" } +pallet-grandpa = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/grandpa" } +pallet-im-online = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/im-online" } +pallet-indices = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/indices" } +pallet-identity = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/identity" } +pallet-membership = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/membership" } +pallet-multisig = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/multisig" } +pallet-offences = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/offences" } +pallet-offences-benchmarking = { version = "2.0.0-rc6", path = "../../../frame/offences/benchmarking", default-features = false, optional = true } +pallet-proxy = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/proxy" } +pallet-randomness-collective-flip = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/randomness-collective-flip" } +pallet-recovery = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/recovery" } +pallet-session = { version = "2.0.0-rc6", features = ["historical"], path = "../../../frame/session", default-features = false } +pallet-session-benchmarking = { version = "2.0.0-rc6", path = "../../../frame/session/benchmarking", default-features = false, optional = true } +pallet-staking = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/staking" } +pallet-staking-reward-curve = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/staking/reward-curve" } +pallet-scheduler = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/scheduler" } +pallet-society = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/society" } +pallet-sudo = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/sudo" } +pallet-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/timestamp" } +pallet-treasury = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/treasury" } +pallet-utility = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/utility" } +pallet-transaction-payment = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/transaction-payment" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/transaction-payment/rpc/runtime-api/" } +pallet-vesting = { version = "2.0.0-rc6", default-features = false, path = "../../../frame/vesting" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } [dev-dependencies] -sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } +sp-io = { version = "2.0.0-rc6", path = "../../../primitives/io" } [features] default = ["std"] @@ -106,10 +110,13 @@ std = [ "pallet-indices/std", "sp-inherents/std", "pallet-membership/std", + "pallet-multisig/std", "pallet-identity/std", + "pallet-scheduler/std", "node-primitives/std", "sp-offchain/std", "pallet-offences/std", + "pallet-proxy/std", "sp-core/std", "pallet-randomness-collective-flip/std", "sp-std/std", @@ -142,12 +149,18 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "pallet-babe/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collective/runtime-benchmarks", + "pallet-contracts/runtime-benchmarks", "pallet-democracy/runtime-benchmarks", "pallet-elections-phragmen/runtime-benchmarks", + "pallet-grandpa/runtime-benchmarks", "pallet-identity/runtime-benchmarks", "pallet-im-online/runtime-benchmarks", + "pallet-indices/runtime-benchmarks", + "pallet-multisig/runtime-benchmarks", + "pallet-proxy/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-society/runtime-benchmarks", "pallet-staking/runtime-benchmarks", @@ -158,4 +171,5 @@ runtime-benchmarks = [ "pallet-offences-benchmarking", "pallet-session-benchmarking", "frame-system-benchmarking", + "hex-literal", ] diff --git a/bin/node/runtime/build.rs b/bin/node/runtime/build.rs index 647b4768141d2203155bf5325f9ff87f7d9c2446..a2f09a460e69da62a7ebf410cef5c6420cb09e3d 100644 --- a/bin/node/runtime/build.rs +++ b/bin/node/runtime/build.rs @@ -1,25 +1,26 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use wasm_builder_runner::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("1.0.9", "../../../utils/wasm-builder") + .with_wasm_builder_from_crates_or_path("2.0.0", "../../../utils/wasm-builder") .export_heap_base() .import_memory() .build() diff --git a/bin/node/runtime/src/constants.rs b/bin/node/runtime/src/constants.rs index bf12492f8db029dc22b519dd52af74adcad99a7f..8e87d61c1e6b597ccb0eb114351befe969264ddf 100644 --- a/bin/node/runtime/src/constants.rs +++ b/bin/node/runtime/src/constants.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! A set of constant values used in substrate runtime. @@ -23,6 +24,10 @@ pub mod currency { pub const MILLICENTS: Balance = 1_000_000_000; pub const CENTS: Balance = 1_000 * MILLICENTS; // assume this is worth about a cent. pub const DOLLARS: Balance = 100 * CENTS; + + pub const fn deposit(items: u32, bytes: u32) -> Balance { + items as Balance * 15 * CENTS + (bytes as Balance) * 6 * CENTS + } } /// Time. diff --git a/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index 878d4b6f0c266c8ef8eb122aabfd155e52d0b45b..039093ddee69700594b70200595a39b07f7e7fa4 100644 --- a/bin/node/runtime/src/impls.rs +++ b/bin/node/runtime/src/impls.rs @@ -1,27 +1,26 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Some configurable implementations as associated type for the substrate runtime. -use core::num::NonZeroI128; use node_primitives::Balance; -use sp_runtime::traits::{Convert, Saturating}; -use sp_runtime::{Fixed128, Perquintill}; -use frame_support::{traits::{OnUnbalanced, Currency, Get}, weights::Weight}; -use crate::{Balances, System, Authorship, MaximumBlockWeight, NegativeImbalance}; +use sp_runtime::traits::Convert; +use frame_support::traits::{OnUnbalanced, Currency}; +use crate::{Balances, Authorship, NegativeImbalance}; pub struct Author; impl OnUnbalanced for Author { @@ -46,106 +45,63 @@ impl Convert for CurrencyToVoteHandler { fn convert(x: u128) -> Balance { x * Self::factor() } } -/// Convert from weight to balance via a simple coefficient multiplication -/// The associated type C encapsulates a constant in units of balance per weight -pub struct LinearWeightToFee(sp_std::marker::PhantomData); - -impl> Convert for LinearWeightToFee { - fn convert(w: Weight) -> Balance { - // setting this to zero will disable the weight fee. - let coefficient = C::get(); - Balance::from(w).saturating_mul(coefficient) - } -} - -/// Update the given multiplier based on the following formula -/// -/// diff = (previous_block_weight - target_weight)/max_weight -/// v = 0.00004 -/// next_weight = weight * (1 + (v * diff) + (v * diff)^2 / 2) -/// -/// Where `target_weight` must be given as the `Get` implementation of the `T` generic type. -/// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees -pub struct TargetedFeeAdjustment(sp_std::marker::PhantomData); - -impl> Convert for TargetedFeeAdjustment { - fn convert(multiplier: Fixed128) -> Fixed128 { - let max_weight = MaximumBlockWeight::get(); - let block_weight = System::all_extrinsics_weight().total().min(max_weight); - let target_weight = (T::get() * max_weight) as u128; - let block_weight = block_weight as u128; - - // determines if the first_term is positive - let positive = block_weight >= target_weight; - let diff_abs = block_weight.max(target_weight) - block_weight.min(target_weight); - // safe, diff_abs cannot exceed u64 and it can always be computed safely even with the lossy - // `Fixed128::from_rational`. - let diff = Fixed128::from_rational( - diff_abs as i128, - NonZeroI128::new(max_weight.max(1) as i128).unwrap(), - ); - let diff_squared = diff.saturating_mul(diff); - - // 0.00004 = 4/100_000 = 40_000/10^9 - let v = Fixed128::from_rational(4, NonZeroI128::new(100_000).unwrap()); - // 0.00004^2 = 16/10^10 Taking the future /2 into account... 8/10^10 - let v_squared_2 = Fixed128::from_rational(8, NonZeroI128::new(10_000_000_000).unwrap()); - - let first_term = v.saturating_mul(diff); - let second_term = v_squared_2.saturating_mul(diff_squared); - - if positive { - // Note: this is merely bounded by how big the multiplier and the inner value can go, - // not by any economical reasoning. - let excess = first_term.saturating_add(second_term); - multiplier.saturating_add(excess) - } else { - // Defensive-only: first_term > second_term. Safe subtraction. - let negative = first_term.saturating_sub(second_term); - multiplier.saturating_sub(negative) - // despite the fact that apply_to saturates weight (final fee cannot go below 0) - // it is crucially important to stop here and don't further reduce the weight fee - // multiplier. While at -1, it means that the network is so un-congested that all - // transactions have no weight fee. We stop here and only increase if the network - // became more busy. - .max(Fixed128::from_natural(-1)) - } - } -} - #[cfg(test)] -mod tests { +mod multiplier_tests { use super::*; - use sp_runtime::assert_eq_error_rate; - use crate::{MaximumBlockWeight, AvailableBlockRatio, Runtime}; - use crate::{constants::currency::*, TransactionPayment, TargetBlockFullness}; - use frame_support::weights::Weight; - use core::num::NonZeroI128; + use sp_runtime::{assert_eq_error_rate, FixedPointNumber}; + use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; + + use crate::{ + constants::{currency::*, time::*}, + TransactionPayment, MaximumBlockWeight, AvailableBlockRatio, Runtime, TargetBlockFullness, + AdjustmentVariable, System, MinimumMultiplier, + }; + use frame_support::weights::{Weight, WeightToFeePolynomial}; fn max() -> Weight { - MaximumBlockWeight::get() + AvailableBlockRatio::get() * MaximumBlockWeight::get() + } + + fn min_multiplier() -> Multiplier { + MinimumMultiplier::get() } fn target() -> Weight { TargetBlockFullness::get() * max() } - // poc reference implementation. - fn fee_multiplier_update(block_weight: Weight, previous: Fixed128) -> Fixed128 { + // update based on runtime impl. + fn runtime_multiplier_update(fm: Multiplier) -> Multiplier { + TargetedFeeAdjustment::< + Runtime, + TargetBlockFullness, + AdjustmentVariable, + MinimumMultiplier, + >::convert(fm) + } + + // update based on reference impl. + fn truth_value_update(block_weight: Weight, previous: Multiplier) -> Multiplier { + let accuracy = Multiplier::accuracy() as f64; + let previous_float = previous.into_inner() as f64 / accuracy; + // bump if it is zero. + let previous_float = previous_float.max(min_multiplier().into_inner() as f64 / accuracy); + // maximum tx weight let m = max() as f64; // block weight always truncated to max weight let block_weight = (block_weight as f64).min(m); - let v: f64 = 0.00004; + let v: f64 = AdjustmentVariable::get().to_fraction(); // Ideal saturation in terms of weight let ss = target() as f64; // Current saturation in terms of weight let s = block_weight; - let fm = v * (s/m - ss/m) + v.powi(2) * (s/m - ss/m).powi(2) / 2.0; - let addition_fm = Fixed128::from_parts((fm * Fixed128::accuracy() as f64).round() as i128); - previous.saturating_add(addition_fm) + let t1 = v * (s/m - ss/m); + let t2 = v.powi(2) * (s/m - ss/m).powi(2) / 2.0; + let next_float = previous_float * (1.0 + t1 + t2); + Multiplier::from_fraction(next_float) } fn run_with_system_weight(w: Weight, assertions: F) where F: Fn() -> () { @@ -158,11 +114,12 @@ mod tests { } #[test] - fn fee_multiplier_update_poc_works() { - let fm = Fixed128::from_rational(0, NonZeroI128::new(1).unwrap()); + fn truth_value_update_poc_works() { + let fm = Multiplier::saturating_from_rational(1, 2); let test_set = vec![ (0, fm.clone()), (100, fm.clone()), + (1000, fm.clone()), (target(), fm.clone()), (max() / 2, fm.clone()), (max(), fm.clone()), @@ -170,37 +127,71 @@ mod tests { test_set.into_iter().for_each(|(w, fm)| { run_with_system_weight(w, || { assert_eq_error_rate!( - fee_multiplier_update(w, fm), - TargetedFeeAdjustment::::convert(fm), - // Error is only 1 in 10^18 - Fixed128::from_parts(1), + truth_value_update(w, fm), + runtime_multiplier_update(fm), + // Error is only 1 in 100^18 + Multiplier::from_inner(100), ); }) }) } #[test] - fn empty_chain_simulation() { - // just a few txs per_block. - let block_weight = 0; - run_with_system_weight(block_weight, || { - let mut fm = Fixed128::default(); + fn multiplier_can_grow_from_zero() { + // if the min is too small, then this will not change, and we are doomed forever. + // the weight is 1/100th bigger than target. + run_with_system_weight(target() * 101 / 100, || { + let next = runtime_multiplier_update(min_multiplier()); + assert!(next > min_multiplier(), "{:?} !>= {:?}", next, min_multiplier()); + }) + } + + #[test] + fn multiplier_cannot_go_below_limit() { + // will not go any further below even if block is empty. + run_with_system_weight(0, || { + let next = runtime_multiplier_update(min_multiplier()); + assert_eq!(next, min_multiplier()); + }) + } + + #[test] + fn time_to_reach_zero() { + // blocks per 24h in substrate-node: 28,800 (k) + // s* = 0.1875 + // The bound from the research in an empty chain is: + // v <~ (p / k(0 - s*)) + // p > v * k * -0.1875 + // to get p == -1 we'd need + // -1 > 0.00001 * k * -0.1875 + // 1 < 0.00001 * k * 0.1875 + // 10^9 / 1875 < k + // k > 533_333 ~ 18,5 days. + run_with_system_weight(0, || { + // start from 1, the default. + let mut fm = Multiplier::one(); let mut iterations: u64 = 0; loop { - let next = TargetedFeeAdjustment::::convert(fm); + let next = runtime_multiplier_update(fm); fm = next; - if fm == Fixed128::from_natural(-1) { break; } + if fm == min_multiplier() { break; } iterations += 1; } - println!("iteration {}, new fm = {:?}. Weight fee is now zero", iterations, fm); - assert!(iterations > 50_000, "This assertion is just a warning; Don't panic. \ - Current substrate/polkadot node are configured with a _slow adjusting fee_ \ - mechanism. Hence, it is really unlikely that fees collapse to zero even on an \ - empty chain in less than at least of couple of thousands of empty blocks. But this \ - simulation indicates that fees collapsed to zero after {} almost-empty blocks. \ - Check it", - iterations, - ); + assert!(iterations > 533_333); + }) + } + + #[test] + fn min_change_per_day() { + run_with_system_weight(max(), || { + let mut fm = Multiplier::one(); + // See the example in the doc of `TargetedFeeAdjustment`. are at least 0.234, hence + // `fm > 1.234`. + for _ in 0..DAYS { + let next = runtime_multiplier_update(fm); + fm = next; + } + assert!(fm > Multiplier::saturating_from_rational(1234, 1000)); }) } @@ -212,23 +203,24 @@ mod tests { // almost full. The entire quota of normal transactions is taken. let block_weight = AvailableBlockRatio::get() * max() - 100; - // Default substrate minimum. - let tx_weight = 10_000; + // Default substrate weight. + let tx_weight = frame_support::weights::constants::ExtrinsicBaseWeight::get(); run_with_system_weight(block_weight, || { // initial value configured on module - let mut fm = Fixed128::default(); + let mut fm = Multiplier::one(); assert_eq!(fm, TransactionPayment::next_fee_multiplier()); let mut iterations: u64 = 0; loop { - let next = TargetedFeeAdjustment::::convert(fm); + let next = runtime_multiplier_update(fm); // if no change, panic. This should never happen in this case. if fm == next { panic!("The fee should ever increase"); } fm = next; iterations += 1; - let fee = ::WeightToFee::convert(tx_weight); - let adjusted_fee = fm.saturated_multiply_accumulate(fee); + let fee = + ::WeightToFee::calc(&tx_weight); + let adjusted_fee = fm.saturating_mul_acc_int(fee); println!( "iteration {}, new fm = {:?}. Fee at this point is: {} units / {} millicents, \ {} cents, {} dollars", @@ -245,95 +237,86 @@ mod tests { #[test] fn stateless_weight_mul() { - // This test will show that heavy blocks have a weight multiplier greater than 0 - // and light blocks will have a weight multiplier less than 0. + let fm = Multiplier::saturating_from_rational(1, 2); run_with_system_weight(target() / 4, || { - // `fee_multiplier_update` is enough as it is the absolute truth value. - let next = TargetedFeeAdjustment::::convert(Fixed128::default()); - assert_eq!( + let next = runtime_multiplier_update(fm); + assert_eq_error_rate!( next, - fee_multiplier_update(target() / 4 ,Fixed128::default()) + truth_value_update(target() / 4 , fm), + Multiplier::from_inner(100), ); - // Light block. Fee is reduced a little. - assert!(next < Fixed128::zero()) + // Light block. Multiplier is reduced a little. + assert!(next < fm); }); + run_with_system_weight(target() / 2, || { - let next = TargetedFeeAdjustment::::convert(Fixed128::default()); - assert_eq!( + let next = runtime_multiplier_update(fm); + assert_eq_error_rate!( next, - fee_multiplier_update(target() / 2 ,Fixed128::default()) + truth_value_update(target() / 2 , fm), + Multiplier::from_inner(100), ); - - // Light block. Fee is reduced a little. - assert!(next < Fixed128::zero()) + // Light block. Multiplier is reduced a little. + assert!(next < fm); }); run_with_system_weight(target(), || { - // ideal. Original fee. No changes. - let next = TargetedFeeAdjustment::::convert(Fixed128::default()); - assert_eq!(next, Fixed128::zero()) + let next = runtime_multiplier_update(fm); + assert_eq_error_rate!( + next, + truth_value_update(target(), fm), + Multiplier::from_inner(100), + ); + // ideal. No changes. + assert_eq!(next, fm) }); run_with_system_weight(target() * 2, || { // More than ideal. Fee is increased. - let next = TargetedFeeAdjustment::::convert(Fixed128::default()); - assert_eq!( + let next = runtime_multiplier_update(fm); + assert_eq_error_rate!( next, - fee_multiplier_update(target() * 2 ,Fixed128::default()) + truth_value_update(target() * 2 , fm), + Multiplier::from_inner(100), ); // Heavy block. Fee is increased a little. - assert!(next > Fixed128::zero()) + assert!(next > fm); }); } #[test] - fn stateful_weight_mul_grow_to_infinity() { + fn weight_mul_grow_on_big_block() { run_with_system_weight(target() * 2, || { - let mut original = Fixed128::default(); - let mut next = Fixed128::default(); + let mut original = Multiplier::zero(); + let mut next = Multiplier::default(); (0..1_000).for_each(|_| { - next = TargetedFeeAdjustment::::convert(original); - assert_eq!( + next = runtime_multiplier_update(original); + assert_eq_error_rate!( next, - fee_multiplier_update(target() * 2, original), + truth_value_update(target() * 2, original), + Multiplier::from_inner(100), ); // must always increase - assert!(next > original); + assert!(next > original, "{:?} !>= {:?}", next, original); original = next; }); }); } #[test] - fn stateful_weight_mil_collapse_to_minus_one() { - run_with_system_weight(0, || { - let mut original = Fixed128::default(); // 0 + fn weight_mul_decrease_on_small_block() { + run_with_system_weight(target() / 2, || { + let mut original = Multiplier::saturating_from_rational(1, 2); let mut next; - // decreases - next = TargetedFeeAdjustment::::convert(original); - assert_eq!( - next, - fee_multiplier_update(0, original), - ); - assert!(next < original); - original = next; - - // keeps decreasing - next = TargetedFeeAdjustment::::convert(original); - assert_eq!( - next, - fee_multiplier_update(0, original), - ); - assert!(next < original); - - // ... stops going down at -1 - assert_eq!( - TargetedFeeAdjustment::::convert(Fixed128::from_natural(-1)), - Fixed128::from_natural(-1) - ); + for _ in 0..100 { + // decreases + next = runtime_multiplier_update(original); + assert!(next < original, "{:?} !<= {:?}", next, original); + original = next; + } }) } @@ -341,7 +324,7 @@ mod tests { fn weight_to_fee_should_not_overflow_on_large_weights() { let kb = 1024 as Weight; let mb = kb * kb; - let max_fm = Fixed128::from_natural(i128::max_value()); + let max_fm = Multiplier::saturating_from_integer(i128::max_value()); // check that for all values it can compute, correctly. vec![ @@ -362,9 +345,9 @@ mod tests { Weight::max_value(), ].into_iter().for_each(|i| { run_with_system_weight(i, || { - let next = TargetedFeeAdjustment::::convert(Fixed128::default()); - let truth = fee_multiplier_update(i, Fixed128::default()); - assert_eq_error_rate!(truth, next, Fixed128::from_parts(50_000_000)); + let next = runtime_multiplier_update(Multiplier::one()); + let truth = truth_value_update(i, Multiplier::one()); + assert_eq_error_rate!(truth, next, Multiplier::from_inner(50_000_000)); }); }); @@ -374,7 +357,7 @@ mod tests { .into_iter() .for_each(|i| { run_with_system_weight(i, || { - let fm = TargetedFeeAdjustment::::convert(max_fm); + let fm = runtime_multiplier_update(max_fm); // won't grow. The convert saturates everything. assert_eq!(fm, max_fm); }) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index a67f4855ac56bd971a43b236d1dd4ba659d7bf45..e7842e5c4ba3b953acf359aaf03cdbac1ea65db7 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! The Substrate runtime. This can be compiled with ``#[no_std]`, ready for Wasm. @@ -21,14 +23,18 @@ #![recursion_limit="256"] use sp_std::prelude::*; + use frame_support::{ - construct_runtime, parameter_types, debug, + construct_runtime, parameter_types, debug, RuntimeDebug, weights::{ - Weight, + Weight, IdentityFee, constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, }, traits::{Currency, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness, LockIdentifier}, }; +use frame_system::{EnsureRoot, EnsureOneOf}; +use frame_support::traits::InstanceFilter; +use codec::{Encode, Decode}; use sp_core::{ crypto::KeyTypeId, u32_trait::{_1, _2, _3, _4}, @@ -39,13 +45,13 @@ use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment}; use sp_api::impl_runtime_apis; use sp_runtime::{ Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult, - impl_opaque_keys, generic, create_runtime_str, ModuleId, + impl_opaque_keys, generic, create_runtime_str, ModuleId, FixedPointNumber, }; use sp_runtime::curve::PiecewiseLinear; use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority}; use sp_runtime::traits::{ self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, - ConvertInto, OpaqueKeys, NumberFor, + ConvertInto, OpaqueKeys, NumberFor, Saturating, }; use sp_version::RuntimeVersion; #[cfg(any(feature = "std", test))] @@ -55,32 +61,45 @@ use pallet_grandpa::fg_primitives; use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; +pub use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; use pallet_contracts_rpc_runtime_api::ContractExecResult; use pallet_session::{historical as pallet_session_historical}; use sp_inherents::{InherentData, CheckInherentsResult}; +use static_assertions::const_assert; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; -pub use pallet_timestamp::Call as TimestampCall; +#[cfg(any(feature = "std", test))] pub use pallet_balances::Call as BalancesCall; +#[cfg(any(feature = "std", test))] pub use frame_system::Call as SystemCall; -pub use pallet_contracts::Gas; -pub use frame_support::StorageValue; +#[cfg(any(feature = "std", test))] pub use pallet_staking::StakerStatus; -use codec::Encode; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; -use impls::{CurrencyToVoteHandler, Author, LinearWeightToFee, TargetedFeeAdjustment}; +use impls::{CurrencyToVoteHandler, Author}; /// Constant values used within the runtime. pub mod constants; use constants::{time::*, currency::*}; +use sp_runtime::generic::Era; + +/// Weights for pallets used in the runtime. +mod weights; // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +#[cfg(feature = "std")] +/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. +pub fn wasm_binary_unwrap() -> &'static [u8] { + WASM_BINARY.expect("Development wasm binary is not available. This means the client is \ + built with `BUILD_DUMMY_WASM_BINARY` flag and it is only usable for \ + production chains. Please rebuild with the flag disabled.") +} + /// Runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("node"), @@ -90,7 +109,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to 0. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 247, + spec_version: 258, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -123,16 +142,24 @@ impl OnUnbalanced for DealWithFees { } } +const AVERAGE_ON_INITIALIZE_WEIGHT: Perbill = Perbill::from_percent(10); parameter_types! { - pub const BlockHashCount: BlockNumber = 250; + pub const BlockHashCount: BlockNumber = 2400; /// We allow for 2 seconds of compute with a 6 second average block time. pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + /// Assume 10% of weight for average on_initialize calls. + pub MaximumExtrinsicWeight: Weight = + AvailableBlockRatio::get().saturating_sub(AVERAGE_ON_INITIALIZE_WEIGHT) + * MaximumBlockWeight::get(); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } +const_assert!(AvailableBlockRatio::get().deconstruct() >= AVERAGE_ON_INITIALIZE_WEIGHT.deconstruct()); + impl frame_system::Trait for Runtime { + type BaseCallFilter = (); type Origin = Origin; type Call = Call; type Index = Index; @@ -148,6 +175,7 @@ impl frame_system::Trait for Runtime { type DbWeight = RocksDbWeight; type BlockExecutionWeight = BlockExecutionWeight; type ExtrinsicBaseWeight = ExtrinsicBaseWeight; + type MaximumExtrinsicWeight = MaximumExtrinsicWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = Version; @@ -155,34 +183,106 @@ impl frame_system::Trait for Runtime { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = weights::frame_system::WeightInfo; +} + +impl pallet_utility::Trait for Runtime { + type Event = Event; + type Call = Call; + type WeightInfo = weights::pallet_utility::WeightInfo; } parameter_types! { - // One storage item; value is size 4+4+16+32 bytes = 56 bytes. - pub const MultisigDepositBase: Balance = 30 * CENTS; + // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. + pub const DepositBase: Balance = deposit(1, 88); // Additional storage item size of 32 bytes. - pub const MultisigDepositFactor: Balance = 5 * CENTS; + pub const DepositFactor: Balance = deposit(0, 32); pub const MaxSignatories: u16 = 100; } -impl pallet_utility::Trait for Runtime { +impl pallet_multisig::Trait for Runtime { type Event = Event; type Call = Call; type Currency = Balances; - type MultisigDepositBase = MultisigDepositBase; - type MultisigDepositFactor = MultisigDepositFactor; + type DepositBase = DepositBase; + type DepositFactor = DepositFactor; type MaxSignatories = MaxSignatories; + type WeightInfo = (); +} + +parameter_types! { + // One storage item; key size 32, value size 8; . + pub const ProxyDepositBase: Balance = deposit(1, 8); + // Additional storage item size of 33 bytes. + pub const ProxyDepositFactor: Balance = deposit(0, 33); + pub const MaxProxies: u16 = 32; + pub const AnnouncementDepositBase: Balance = deposit(1, 8); + pub const AnnouncementDepositFactor: Balance = deposit(0, 66); + pub const MaxPending: u16 = 32; +} + +/// The type used to represent the kinds of proxying allowed. +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug)] +pub enum ProxyType { + Any, + NonTransfer, + Governance, + Staking, +} +impl Default for ProxyType { fn default() -> Self { Self::Any } } +impl InstanceFilter for ProxyType { + fn filter(&self, c: &Call) -> bool { + match self { + ProxyType::Any => true, + ProxyType::NonTransfer => !matches!(c, + Call::Balances(..) | Call::Vesting(pallet_vesting::Call::vested_transfer(..)) + | Call::Indices(pallet_indices::Call::transfer(..)) + ), + ProxyType::Governance => matches!(c, + Call::Democracy(..) | Call::Council(..) | Call::Society(..) + | Call::TechnicalCommittee(..) | Call::Elections(..) | Call::Treasury(..) + ), + ProxyType::Staking => matches!(c, Call::Staking(..)), + } + } + fn is_superset(&self, o: &Self) -> bool { + match (self, o) { + (x, y) if x == y => true, + (ProxyType::Any, _) => true, + (_, ProxyType::Any) => false, + (ProxyType::NonTransfer, _) => true, + _ => false, + } + } +} + +impl pallet_proxy::Trait for Runtime { + type Event = Event; + type Call = Call; + type Currency = Balances; + type ProxyType = ProxyType; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type MaxProxies = MaxProxies; + type WeightInfo = weights::pallet_proxy::WeightInfo; + type MaxPending = MaxPending; + type CallHasher = BlakeTwo256; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; } parameter_types! { - pub const MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); } impl pallet_scheduler::Trait for Runtime { type Event = Event; type Origin = Origin; + type PalletsOrigin = OriginCaller; type Call = Call; type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type WeightInfo = (); } parameter_types! { @@ -194,6 +294,21 @@ impl pallet_babe::Trait for Runtime { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; type EpochChangeTrigger = pallet_babe::ExternalTrigger; + + type KeyOwnerProofSystem = Historical; + + type KeyOwnerProof = >::Proof; + + type KeyOwnerIdentification = >::IdentificationTuple; + + type HandleEquivocation = + pallet_babe::EquivocationHandler; } parameter_types! { @@ -202,9 +317,10 @@ parameter_types! { impl pallet_indices::Trait for Runtime { type AccountIndex = AccountIndex; - type Event = Event; type Currency = Balances; type Deposit = IndexDeposit; + type Event = Event; + type WeightInfo = (); } parameter_types! { @@ -217,23 +333,23 @@ impl pallet_balances::Trait for Runtime { type Event = Event; type ExistentialDeposit = ExistentialDeposit; type AccountStore = frame_system::Module; + type WeightInfo = weights::pallet_balances::WeightInfo; } parameter_types! { pub const TransactionByteFee: Balance = 10 * MILLICENTS; - // In the Substrate node, a weight of 10_000_000 (smallest non-zero weight) - // is mapped to 10_000_000 units of fees, hence: - pub const WeightFeeCoefficient: Balance = 1; - // for a sane configuration, this should always be less than `AvailableBlockRatio`. pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); + pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 100_000); + pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000_000u128); } impl pallet_transaction_payment::Trait for Runtime { type Currency = Balances; type OnTransactionPayment = DealWithFees; type TransactionByteFee = TransactionByteFee; - type WeightToFee = LinearWeightToFee; - type FeeMultiplierUpdate = TargetedFeeAdjustment; + type WeightToFee = IdentityFee; + type FeeMultiplierUpdate = + TargetedFeeAdjustment; } parameter_types! { @@ -244,6 +360,7 @@ impl pallet_timestamp::Trait for Runtime { type Moment = Moment; type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; + type WeightInfo = weights::pallet_timestamp::WeightInfo; } parameter_types! { @@ -275,11 +392,12 @@ impl pallet_session::Trait for Runtime { type ValidatorId = ::AccountId; type ValidatorIdOf = pallet_staking::StashOf; type ShouldEndSession = Babe; + type NextSessionRotation = Babe; type SessionManager = pallet_session::historical::NoteHistoricalRoot; type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; - type NextSessionRotation = Babe; + type WeightInfo = (); } impl pallet_session::historical::Trait for Runtime { @@ -303,9 +421,11 @@ parameter_types! { pub const BondingDuration: pallet_staking::EraIndex = 24 * 28; pub const SlashDeferDuration: pallet_staking::EraIndex = 24 * 7; // 1/4 the bonding duration. pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; - pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4; pub const MaxNominatorRewardedPerValidator: u32 = 64; - pub const MaxIterations: u32 = 5; + pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4; + pub const MaxIterations: u32 = 10; + // 0.05%. The higher the value, the more strict solution acceptance becomes. + pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000); } impl pallet_staking::Trait for Runtime { @@ -320,15 +440,21 @@ impl pallet_staking::Trait for Runtime { type BondingDuration = BondingDuration; type SlashDeferDuration = SlashDeferDuration; /// A super-majority of the council can cancel the slash. - type SlashCancelOrigin = pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>; + type SlashCancelOrigin = EnsureOneOf< + AccountId, + EnsureRoot, + pallet_collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective> + >; type SessionInterface = Self; type RewardCurve = RewardCurve; type NextNewSession = Session; type ElectionLookahead = ElectionLookahead; type Call = Call; type MaxIterations = MaxIterations; + type MinSolutionScoreBump = MinSolutionScoreBump; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type UnsignedPriority = StakingUnsignedPriority; + type WeightInfo = (); } parameter_types! { @@ -341,6 +467,7 @@ parameter_types! { pub const CooloffPeriod: BlockNumber = 28 * 24 * 60 * MINUTES; // One cent: $10,000 / MB pub const PreimageByteDeposit: Balance = 1 * CENTS; + pub const MaxVotes: u32 = 100; } impl pallet_democracy::Trait for Runtime { @@ -371,12 +498,17 @@ impl pallet_democracy::Trait for Runtime { type VetoOrigin = pallet_collective::EnsureMember; type CooloffPeriod = CooloffPeriod; type PreimageByteDeposit = PreimageByteDeposit; + type OperationalPreimageOrigin = pallet_collective::EnsureMember; type Slash = Treasury; type Scheduler = Scheduler; + type PalletsOrigin = OriginCaller; + type MaxVotes = MaxVotes; + type WeightInfo = weights::pallet_democracy::WeightInfo; } parameter_types! { pub const CouncilMotionDuration: BlockNumber = 5 * DAYS; + pub const CouncilMaxProposals: u32 = 100; } type CouncilCollective = pallet_collective::Instance1; @@ -385,6 +517,8 @@ impl pallet_collective::Trait for Runtime { type Proposal = Call; type Event = Event; type MotionDuration = CouncilMotionDuration; + type MaxProposals = CouncilMaxProposals; + type WeightInfo = (); } parameter_types! { @@ -396,9 +530,12 @@ parameter_types! { pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect"; } +// Make sure that there are no more than `MAX_MEMBERS` members elected via elections-phragmen. +const_assert!(DesiredMembers::get() <= pallet_collective::MAX_MEMBERS); + impl pallet_elections_phragmen::Trait for Runtime { - type ModuleId = ElectionsPhragmenModuleId; type Event = Event; + type ModuleId = ElectionsPhragmenModuleId; type Currency = Balances; type ChangeMembers = Council; // NOTE: this implies that council's genesis members cannot be set directly and must come from @@ -413,10 +550,12 @@ impl pallet_elections_phragmen::Trait for Runtime { type DesiredMembers = DesiredMembers; type DesiredRunnersUp = DesiredRunnersUp; type TermDuration = TermDuration; + type WeightInfo = (); } parameter_types! { pub const TechnicalMotionDuration: BlockNumber = 5 * DAYS; + pub const TechnicalMaxProposals: u32 = 100; } type TechnicalCollective = pallet_collective::Instance2; @@ -425,15 +564,22 @@ impl pallet_collective::Trait for Runtime { type Proposal = Call; type Event = Event; type MotionDuration = TechnicalMotionDuration; + type MaxProposals = TechnicalMaxProposals; + type WeightInfo = (); } +type EnsureRootOrHalfCouncil = EnsureOneOf< + AccountId, + EnsureRoot, + pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective> +>; impl pallet_membership::Trait for Runtime { type Event = Event; - type AddOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; - type RemoveOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; - type SwapOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; - type ResetOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; - type PrimeOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; + type AddOrigin = EnsureRootOrHalfCouncil; + type RemoveOrigin = EnsureRootOrHalfCouncil; + type SwapOrigin = EnsureRootOrHalfCouncil; + type ResetOrigin = EnsureRootOrHalfCouncil; + type PrimeOrigin = EnsureRootOrHalfCouncil; type MembershipInitialized = TechnicalCommittee; type MembershipChanged = TechnicalCommittee; } @@ -451,9 +597,18 @@ parameter_types! { } impl pallet_treasury::Trait for Runtime { + type ModuleId = TreasuryModuleId; type Currency = Balances; - type ApproveOrigin = pallet_collective::EnsureMembers<_4, AccountId, CouncilCollective>; - type RejectOrigin = pallet_collective::EnsureMembers<_2, AccountId, CouncilCollective>; + type ApproveOrigin = EnsureOneOf< + AccountId, + EnsureRoot, + pallet_collective::EnsureMembers<_4, AccountId, CouncilCollective> + >; + type RejectOrigin = EnsureOneOf< + AccountId, + EnsureRoot, + pallet_collective::EnsureMembers<_2, AccountId, CouncilCollective> + >; type Tippers = Elections; type TipCountdown = TipCountdown; type TipFindersFee = TipFindersFee; @@ -465,20 +620,21 @@ impl pallet_treasury::Trait for Runtime { type ProposalBondMinimum = ProposalBondMinimum; type SpendPeriod = SpendPeriod; type Burn = Burn; - type ModuleId = TreasuryModuleId; + type BurnDestination = (); + type WeightInfo = (); } parameter_types! { - pub const TombstoneDeposit: Balance = 1 * DOLLARS; - pub const RentByteFee: Balance = 1 * DOLLARS; - pub const RentDepositOffset: Balance = 1000 * DOLLARS; - pub const SurchargeReward: Balance = 150 * DOLLARS; + pub const TombstoneDeposit: Balance = 16 * MILLICENTS; + pub const RentByteFee: Balance = 4 * MILLICENTS; + pub const RentDepositOffset: Balance = 1000 * MILLICENTS; + pub const SurchargeReward: Balance = 150 * MILLICENTS; } impl pallet_contracts::Trait for Runtime { type Time = Timestamp; type Randomness = RandomnessCollectiveFlip; - type Call = Call; + type Currency = Balances; type Event = Event; type DetermineContractAddress = pallet_contracts::SimpleAddressDeterminer; type TrieIdGenerator = pallet_contracts::TrieIdFromParentCounter; @@ -491,6 +647,7 @@ impl pallet_contracts::Trait for Runtime { type SurchargeReward = SurchargeReward; type MaxDepth = pallet_contracts::DefaultMaxDepth; type MaxValueSize = pallet_contracts::DefaultMaxValueSize; + type WeightPrice = pallet_transaction_payment::Module; } impl pallet_sudo::Trait for Runtime { @@ -501,13 +658,13 @@ impl pallet_sudo::Trait for Runtime { parameter_types! { pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_SLOTS as _; pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); - /// We prioritize im-online heartbeats over phragmen solution submission. + /// We prioritize im-online heartbeats over election solution submission. pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2; } - -impl frame_system::offchain::CreateSignedTransaction for Runtime where - Call: From, +impl frame_system::offchain::CreateSignedTransaction for Runtime + where + Call: From, { fn create_transaction>( call: Call, @@ -515,6 +672,7 @@ impl frame_system::offchain::CreateSignedTransaction for R account: AccountId, nonce: Index, ) -> Option<(Call, ::SignaturePayload)> { + let tip = 0; // take the biggest period possible. let period = BlockHashCount::get() .checked_next_power_of_two() @@ -525,22 +683,25 @@ impl frame_system::offchain::CreateSignedTransaction for R // The `System::block_number` is initialized with `n+1`, // so the actual block number is `n`. .saturating_sub(1); - let tip = 0; - let extra: SignedExtra = ( - frame_system::CheckVersion::::new(), + let era = Era::mortal(period, current_block); + let extra = ( + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(generic::Era::mortal(period, current_block)), + frame_system::CheckEra::::from(era), frame_system::CheckNonce::::from(nonce), frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(tip), - pallet_grandpa::ValidateEquivocationReport::::new(), ); - let raw_payload = SignedPayload::new(call, extra).map_err(|e| { - debug::warn!("Unable to create signed payload: {:?}", e); - }).ok()?; - let signature = raw_payload.using_encoded(|payload| { - C::sign(payload, public) - })?; + let raw_payload = SignedPayload::new(call, extra) + .map_err(|e| { + debug::warn!("Unable to create signed payload: {:?}", e); + }) + .ok()?; + let signature = raw_payload + .using_encoded(|payload| { + C::sign(payload, public) + })?; let address = Indices::unlookup(account); let (call, extra, _) = raw_payload.deconstruct(); Some((call, (address, signature.into(), extra))) @@ -555,8 +716,8 @@ impl frame_system::offchain::SigningTypes for Runtime { impl frame_system::offchain::SendTransactionTypes for Runtime where Call: From, { - type OverarchingCall = Call; type Extrinsic = UncheckedExtrinsic; + type OverarchingCall = Call; } impl pallet_im_online::Trait for Runtime { @@ -565,12 +726,19 @@ impl pallet_im_online::Trait for Runtime { type SessionDuration = SessionDuration; type ReportUnresponsiveness = Offences; type UnsignedPriority = ImOnlineUnsignedPriority; + type WeightInfo = (); +} + +parameter_types! { + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } impl pallet_offences::Trait for Runtime { type Event = Event; type IdentificationTuple = pallet_session::historical::IdentificationTuple; type OnOffenceHandler = Staking; + type WeightSoftLimit = OffencesWeightSoftLimit; + type WeightInfo = (); } impl pallet_authority_discovery::Trait for Runtime {} @@ -589,12 +757,8 @@ impl pallet_grandpa::Trait for Runtime { GrandpaId, )>>::IdentificationTuple; - type HandleEquivocation = pallet_grandpa::EquivocationHandler< - Self::KeyOwnerIdentification, - node_primitives::report::ReporterAppCrypto, - Runtime, - Offences, - >; + type HandleEquivocation = + pallet_grandpa::EquivocationHandler; } parameter_types! { @@ -627,8 +791,9 @@ impl pallet_identity::Trait for Runtime { type MaxAdditionalFields = MaxAdditionalFields; type MaxRegistrars = MaxRegistrars; type Slashed = Treasury; - type ForceOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; - type RegistrarOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; + type ForceOrigin = EnsureRootOrHalfCouncil; + type RegistrarOrigin = EnsureRootOrHalfCouncil; + type WeightInfo = (); } parameter_types! { @@ -661,6 +826,7 @@ parameter_types! { impl pallet_society::Trait for Runtime { type Event = Event; + type ModuleId = SocietyModuleId; type Currency = Balances; type Randomness = RandomnessCollectiveFlip; type CandidateDeposit = CandidateDeposit; @@ -673,7 +839,6 @@ impl pallet_society::Trait for Runtime { type FounderSetOrigin = pallet_collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>; type SuspensionJudgementOrigin = pallet_society::EnsureFounder; type ChallengePeriod = ChallengePeriod; - type ModuleId = SocietyModuleId; } parameter_types! { @@ -685,6 +850,7 @@ impl pallet_vesting::Trait for Runtime { type Currency = Balances; type BlockNumberToBalance = ConvertInto; type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = (); } construct_runtime!( @@ -694,8 +860,8 @@ construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system::{Module, Call, Config, Storage, Event}, - Utility: pallet_utility::{Module, Call, Storage, Event}, - Babe: pallet_babe::{Module, Call, Storage, Config, Inherent(Timestamp)}, + Utility: pallet_utility::{Module, Call, Event}, + Babe: pallet_babe::{Module, Call, Storage, Config, Inherent, ValidateUnsigned}, Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent}, Authorship: pallet_authorship::{Module, Call, Storage, Inherent}, Indices: pallet_indices::{Module, Call, Storage, Config, Event}, @@ -709,7 +875,7 @@ construct_runtime!( Elections: pallet_elections_phragmen::{Module, Call, Storage, Event, Config}, TechnicalMembership: pallet_membership::::{Module, Call, Storage, Event, Config}, FinalityTracker: pallet_finality_tracker::{Module, Call, Inherent}, - Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event}, + Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event, ValidateUnsigned}, Treasury: pallet_treasury::{Module, Call, Storage, Config, Event}, Contracts: pallet_contracts::{Module, Call, Config, Storage, Event}, Sudo: pallet_sudo::{Module, Call, Config, Storage, Event}, @@ -723,6 +889,8 @@ construct_runtime!( Recovery: pallet_recovery::{Module, Call, Storage, Event}, Vesting: pallet_vesting::{Module, Call, Storage, Event, Config}, Scheduler: pallet_scheduler::{Module, Call, Storage, Event}, + Proxy: pallet_proxy::{Module, Call, Storage, Event}, + Multisig: pallet_multisig::{Module, Call, Storage, Event}, } ); @@ -737,14 +905,18 @@ pub type SignedBlock = generic::SignedBlock; /// BlockId type as expected by this runtime. pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. +/// +/// When you change this, you **MUST** modify [`sign`] in `bin/node/testing/src/keyring.rs`! +/// +/// [`sign`]: <../../testing/src/keyring.rs.html> pub type SignedExtra = ( - frame_system::CheckVersion, + frame_system::CheckSpecVersion, + frame_system::CheckTxVersion, frame_system::CheckGenesis, frame_system::CheckEra, frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, - pallet_grandpa::ValidateEquivocationReport, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; @@ -818,7 +990,7 @@ impl_runtime_apis! { Grandpa::grandpa_authorities() } - fn submit_report_equivocation_extrinsic( + fn submit_report_equivocation_unsigned_extrinsic( equivocation_proof: fg_primitives::EquivocationProof< ::Hash, NumberFor, @@ -827,7 +999,7 @@ impl_runtime_apis! { ) -> Option<()> { let key_owner_proof = key_owner_proof.decode()?; - Grandpa::submit_report_equivocation_extrinsic( + Grandpa::submit_unsigned_equivocation_report( equivocation_proof, key_owner_proof, ) @@ -865,6 +1037,29 @@ impl_runtime_apis! { fn current_epoch_start() -> sp_consensus_babe::SlotNumber { Babe::current_epoch_start() } + + fn generate_key_ownership_proof( + _slot_number: sp_consensus_babe::SlotNumber, + authority_id: sp_consensus_babe::AuthorityId, + ) -> Option { + use codec::Encode; + + Historical::prove((sp_consensus_babe::KEY_TYPE, authority_id)) + .map(|p| p.encode()) + .map(sp_consensus_babe::OpaqueKeyOwnershipProof::new) + } + + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: sp_consensus_babe::EquivocationProof<::Header>, + key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof, + ) -> Option<()> { + let key_owner_proof = key_owner_proof.decode()?; + + Babe::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + } } impl sp_authority_discovery::AuthorityDiscoveryApi for Runtime { @@ -889,12 +1084,13 @@ impl_runtime_apis! { gas_limit: u64, input_data: Vec, ) -> ContractExecResult { - let exec_result = + let (exec_result, gas_consumed) = Contracts::bare_call(origin, dest.into(), value, gas_limit, input_data); match exec_result { Ok(v) => ContractExecResult::Success { - status: v.status, + flags: v.flags.bits(), data: v.data, + gas_consumed: gas_consumed, }, Err(_) => ContractExecResult::Error, } @@ -917,9 +1113,8 @@ impl_runtime_apis! { impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi< Block, Balance, - UncheckedExtrinsic, > for Runtime { - fn query_info(uxt: UncheckedExtrinsic, len: u32) -> RuntimeDispatchInfo { + fn query_info(uxt: ::Extrinsic, len: u32) -> RuntimeDispatchInfo { TransactionPayment::query_info(uxt, len) } } @@ -945,8 +1140,9 @@ impl_runtime_apis! { highest_range_values: Vec, steps: Vec, repeat: u32, + extra: bool, ) -> Result, sp_runtime::RuntimeString> { - use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark}; + use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; // Trying to add benchmarks directly to the Session Pallet caused cyclic dependency issues. // To get around that, we separated the Session benchmarks into its own crate, which is why // we need these two lines below. @@ -958,23 +1154,45 @@ impl_runtime_apis! { impl pallet_offences_benchmarking::Trait for Runtime {} impl frame_system_benchmarking::Trait for Runtime {} + let whitelist: Vec = vec![ + // Block Number + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), + // Total Issuance + hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(), + // Execution Phase + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(), + // Event Count + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(), + // System Events + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(), + // Treasury Account + hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95ecffd7b6c0f78751baa9d281e0bfa3a6d6f646c70792f74727372790000000000000000000000000000000000000000").to_vec().into(), + ]; + let mut batches = Vec::::new(); - let params = (&pallet, &benchmark, &lowest_range_values, &highest_range_values, &steps, repeat); - - add_benchmark!(params, batches, b"balances", Balances); - add_benchmark!(params, batches, b"collective", Council); - add_benchmark!(params, batches, b"democracy", Democracy); - add_benchmark!(params, batches, b"identity", Identity); - add_benchmark!(params, batches, b"im-online", ImOnline); - add_benchmark!(params, batches, b"offences", OffencesBench::); - add_benchmark!(params, batches, b"scheduler", Scheduler); - add_benchmark!(params, batches, b"session", SessionBench::); - add_benchmark!(params, batches, b"staking", Staking); - add_benchmark!(params, batches, b"system", SystemBench::); - add_benchmark!(params, batches, b"timestamp", Timestamp); - add_benchmark!(params, batches, b"treasury", Treasury); - add_benchmark!(params, batches, b"utility", Utility); - add_benchmark!(params, batches, b"vesting", Vesting); + let params = (&pallet, &benchmark, &lowest_range_values, &highest_range_values, &steps, repeat, &whitelist, extra); + + add_benchmark!(params, batches, pallet_babe, Babe); + add_benchmark!(params, batches, pallet_balances, Balances); + add_benchmark!(params, batches, pallet_collective, Council); + add_benchmark!(params, batches, pallet_contracts, Contracts); + add_benchmark!(params, batches, pallet_democracy, Democracy); + add_benchmark!(params, batches, pallet_elections_phragmen, Elections); + add_benchmark!(params, batches, pallet_grandpa, Grandpa); + add_benchmark!(params, batches, pallet_identity, Identity); + add_benchmark!(params, batches, pallet_im_online, ImOnline); + add_benchmark!(params, batches, pallet_indices, Indices); + add_benchmark!(params, batches, pallet_multisig, Multisig); + add_benchmark!(params, batches, pallet_offences, OffencesBench::); + add_benchmark!(params, batches, pallet_proxy, Proxy); + add_benchmark!(params, batches, pallet_scheduler, Scheduler); + add_benchmark!(params, batches, pallet_session, SessionBench::); + add_benchmark!(params, batches, pallet_staking, Staking); + add_benchmark!(params, batches, frame_system, SystemBench::); + add_benchmark!(params, batches, pallet_timestamp, Timestamp); + add_benchmark!(params, batches, pallet_treasury, Treasury); + add_benchmark!(params, batches, pallet_utility, Utility); + add_benchmark!(params, batches, pallet_vesting, Vesting); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) diff --git a/bin/node/runtime/src/weights/frame_system.rs b/bin/node/runtime/src/weights/frame_system.rs new file mode 100644 index 0000000000000000000000000000000000000000..9522fa75203906ab3c7264154a4b33835375843c --- /dev/null +++ b/bin/node/runtime/src/weights/frame_system.rs @@ -0,0 +1,58 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +#![allow(unused_parens)] + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +pub struct WeightInfo; +impl frame_system::WeightInfo for WeightInfo { + // WARNING! Some components were not used: ["b"] + fn remark() -> Weight { + (1305000 as Weight) + } + fn set_heap_pages() -> Weight { + (2023000 as Weight) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + // WARNING! Some components were not used: ["d"] + fn set_changes_trie_config() -> Weight { + (10026000 as Weight) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn set_storage(i: u32, ) -> Weight { + (0 as Weight) + .saturating_add((656000 as Weight).saturating_mul(i as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(i as Weight))) + } + fn kill_storage(i: u32, ) -> Weight { + (4327000 as Weight) + .saturating_add((478000 as Weight).saturating_mul(i as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(i as Weight))) + } + fn kill_prefix(p: u32, ) -> Weight { + (8349000 as Weight) + .saturating_add((838000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight))) + } + fn suicide() -> Weight { + (29247000 as Weight) + } +} diff --git a/bin/node/runtime/src/weights/mod.rs b/bin/node/runtime/src/weights/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..322fb8886c0f4418e2b6dc45db54d48d78652d84 --- /dev/null +++ b/bin/node/runtime/src/weights/mod.rs @@ -0,0 +1,23 @@ +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! A list of the different weight modules for our runtime. + +pub mod frame_system; +pub mod pallet_balances; +pub mod pallet_democracy; +pub mod pallet_proxy; +pub mod pallet_timestamp; +pub mod pallet_utility; diff --git a/bin/node/runtime/src/weights/pallet_balances.rs b/bin/node/runtime/src/weights/pallet_balances.rs new file mode 100644 index 0000000000000000000000000000000000000000..bcbc4ced6ef56895d4c62a31a7b0580ad71b9ecf --- /dev/null +++ b/bin/node/runtime/src/weights/pallet_balances.rs @@ -0,0 +1,47 @@ +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +pub struct WeightInfo; +impl pallet_balances::WeightInfo for WeightInfo { + fn transfer() -> Weight { + (65949000 as Weight) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn transfer_keep_alive() -> Weight { + (46665000 as Weight) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn set_balance_creating() -> Weight { + (27086000 as Weight) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn set_balance_killing() -> Weight { + (33424000 as Weight) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn force_transfer() -> Weight { + (65343000 as Weight) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } +} diff --git a/bin/node/runtime/src/weights/pallet_democracy.rs b/bin/node/runtime/src/weights/pallet_democracy.rs new file mode 100644 index 0000000000000000000000000000000000000000..2c55a848061a393c179614688f18885fd63c2c97 --- /dev/null +++ b/bin/node/runtime/src/weights/pallet_democracy.rs @@ -0,0 +1,155 @@ +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Weights for the Democracy Pallet +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +pub struct WeightInfo; +impl pallet_democracy::WeightInfo for WeightInfo { + fn propose() -> Weight { + (49113000 as Weight) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn second(s: u32, ) -> Weight { + (42067000 as Weight) + .saturating_add((220000 as Weight).saturating_mul(s as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn vote_new(r: u32, ) -> Weight { + (54159000 as Weight) + .saturating_add((252000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn vote_existing(r: u32, ) -> Weight { + (54145000 as Weight) + .saturating_add((262000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn emergency_cancel() -> Weight { + (31071000 as Weight) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn external_propose(v: u32, ) -> Weight { + (14282000 as Weight) + .saturating_add((109000 as Weight).saturating_mul(v as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn external_propose_majority() -> Weight { + (3478000 as Weight) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn external_propose_default() -> Weight { + (3442000 as Weight) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn fast_track() -> Weight { + (30820000 as Weight) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn veto_external(v: u32, ) -> Weight { + (30971000 as Weight) + .saturating_add((184000 as Weight).saturating_mul(v as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn cancel_referendum() -> Weight { + (20431000 as Weight) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn cancel_queued(r: u32, ) -> Weight { + (42438000 as Weight) + .saturating_add((3284000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn on_initialize_base(r: u32, ) -> Weight { + (70826000 as Weight) + .saturating_add((10716000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(6 as Weight)) + .saturating_add(DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) + .saturating_add(DbWeight::get().writes(5 as Weight)) + } + fn delegate(r: u32, ) -> Weight { + (72046000 as Weight) + .saturating_add((7837000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(4 as Weight)) + .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight))) + .saturating_add(DbWeight::get().writes(4 as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(r as Weight))) + } + fn undelegate(r: u32, ) -> Weight { + (41028000 as Weight) + .saturating_add((7810000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight))) + .saturating_add(DbWeight::get().writes(2 as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(r as Weight))) + } + fn clear_public_proposals() -> Weight { + (3643000 as Weight) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn note_preimage(b: u32, ) -> Weight { + (46629000 as Weight) + .saturating_add((4000 as Weight).saturating_mul(b as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn note_imminent_preimage(b: u32, ) -> Weight { + (31147000 as Weight) + .saturating_add((3000 as Weight).saturating_mul(b as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn reap_preimage(b: u32, ) -> Weight { + (42848000 as Weight) + .saturating_add((3000 as Weight).saturating_mul(b as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn unlock_remove(r: u32, ) -> Weight { + (45333000 as Weight) + .saturating_add((171000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn unlock_set(r: u32, ) -> Weight { + (44424000 as Weight) + .saturating_add((291000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn remove_vote(r: u32, ) -> Weight { + (28250000 as Weight) + .saturating_add((283000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn remove_other_vote(r: u32, ) -> Weight { + (28250000 as Weight) + .saturating_add((283000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } +} diff --git a/bin/node/runtime/src/weights/pallet_proxy.rs b/bin/node/runtime/src/weights/pallet_proxy.rs new file mode 100644 index 0000000000000000000000000000000000000000..92c43cd4853a215edade20d9b281e20ee8559663 --- /dev/null +++ b/bin/node/runtime/src/weights/pallet_proxy.rs @@ -0,0 +1,85 @@ +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +pub struct WeightInfo; +impl pallet_proxy::WeightInfo for WeightInfo { + fn proxy(p: u32, ) -> Weight { + (26127000 as Weight) + .saturating_add((214000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + } + fn proxy_announced(a: u32, p: u32, ) -> Weight { + (55405000 as Weight) + .saturating_add((774000 as Weight).saturating_mul(a as Weight)) + .saturating_add((209000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn remove_announcement(a: u32, p: u32, ) -> Weight { + (35879000 as Weight) + .saturating_add((783000 as Weight).saturating_mul(a as Weight)) + .saturating_add((20000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn reject_announcement(a: u32, p: u32, ) -> Weight { + (36097000 as Weight) + .saturating_add((780000 as Weight).saturating_mul(a as Weight)) + .saturating_add((12000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn announce(a: u32, p: u32, ) -> Weight { + (53769000 as Weight) + .saturating_add((675000 as Weight).saturating_mul(a as Weight)) + .saturating_add((214000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn add_proxy(p: u32, ) -> Weight { + (36082000 as Weight) + .saturating_add((234000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn remove_proxy(p: u32, ) -> Weight { + (32885000 as Weight) + .saturating_add((267000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn remove_proxies(p: u32, ) -> Weight { + (31735000 as Weight) + .saturating_add((215000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn anonymous(p: u32, ) -> Weight { + (50907000 as Weight) + .saturating_add((61000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn kill_anonymous(p: u32, ) -> Weight { + (33926000 as Weight) + .saturating_add((208000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } +} diff --git a/bin/node/runtime/src/weights/pallet_timestamp.rs b/bin/node/runtime/src/weights/pallet_timestamp.rs new file mode 100644 index 0000000000000000000000000000000000000000..cfd5f192d35298b512ee75e4d26acf11355ce3ba --- /dev/null +++ b/bin/node/runtime/src/weights/pallet_timestamp.rs @@ -0,0 +1,34 @@ +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +#![allow(unused_parens)] + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +pub struct WeightInfo; +impl pallet_timestamp::WeightInfo for WeightInfo { + // WARNING! Some components were not used: ["t"] + fn set() -> Weight { + (9133000 as Weight) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + // WARNING! Some components were not used: ["t"] + fn on_finalize() -> Weight { + (5915000 as Weight) + } +} diff --git a/bin/node/runtime/src/weights/pallet_utility.rs b/bin/node/runtime/src/weights/pallet_utility.rs new file mode 100644 index 0000000000000000000000000000000000000000..c9ae0d7d2333b19bec65e4f5c1556df65b21e086 --- /dev/null +++ b/bin/node/runtime/src/weights/pallet_utility.rs @@ -0,0 +1,35 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +pub struct WeightInfo; +impl pallet_utility::WeightInfo for WeightInfo { + fn batch(c: u32, ) -> Weight { + (16461000 as Weight) + .saturating_add((1982000 as Weight).saturating_mul(c as Weight)) + } + // WARNING! Some components were not used: ["u"] + fn as_derivative() -> Weight { + (4086000 as Weight) + } +} diff --git a/bin/node/testing/Cargo.toml b/bin/node/testing/Cargo.toml index af375c774de425c3a940efd43e75ac49924a9606..23bf10336dcfee229e59e3479a573baadc442763 100644 --- a/bin/node/testing/Cargo.toml +++ b/bin/node/testing/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "node-testing" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] description = "Test utilities for Substrate node." edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = true @@ -13,40 +13,40 @@ publish = true targets = ["x86_64-unknown-linux-gnu"] [dependencies] -pallet-balances = { version = "2.0.0-dev", path = "../../../frame/balances" } -sc-service = { version = "0.8.0-dev", features = ["test-helpers", "db"], path = "../../../client/service" } -sc-client-db = { version = "0.8.0-dev", path = "../../../client/db/", features = ["kvdb-rocksdb", "parity-db"] } -sc-client-api = { version = "2.0.0-dev", path = "../../../client/api/" } -codec = { package = "parity-scale-codec", version = "1.3.0" } -pallet-contracts = { version = "2.0.0-dev", path = "../../../frame/contracts" } -pallet-grandpa = { version = "2.0.0-dev", path = "../../../frame/grandpa" } -pallet-indices = { version = "2.0.0-dev", path = "../../../frame/indices" } -sp-keyring = { version = "2.0.0-dev", path = "../../../primitives/keyring" } -node-executor = { version = "2.0.0-dev", path = "../executor" } -node-primitives = { version = "2.0.0-dev", path = "../primitives" } -node-runtime = { version = "2.0.0-dev", path = "../runtime" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } -frame-support = { version = "2.0.0-dev", path = "../../../frame/support" } -pallet-session = { version = "2.0.0-dev", path = "../../../frame/session" } -pallet-society = { version = "2.0.0-dev", path = "../../../frame/society" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -pallet-staking = { version = "2.0.0-dev", path = "../../../frame/staking" } -sc-executor = { version = "0.8.0-dev", path = "../../../client/executor", features = ["wasmtime"] } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -frame-system = { version = "2.0.0-dev", path = "../../../frame/system" } -substrate-test-client = { version = "2.0.0-dev", path = "../../../test-utils/client" } -pallet-timestamp = { version = "2.0.0-dev", path = "../../../frame/timestamp" } -pallet-transaction-payment = { version = "2.0.0-dev", path = "../../../frame/transaction-payment" } -pallet-treasury = { version = "2.0.0-dev", path = "../../../frame/treasury" } +pallet-balances = { version = "2.0.0-rc6", path = "../../../frame/balances" } +sc-service = { version = "0.8.0-rc6", features = ["test-helpers", "db"], path = "../../../client/service" } +sc-client-db = { version = "0.8.0-rc6", path = "../../../client/db/", features = ["kvdb-rocksdb", "parity-db"] } +sc-client-api = { version = "2.0.0-rc6", path = "../../../client/api/" } +codec = { package = "parity-scale-codec", version = "1.3.4" } +pallet-contracts = { version = "2.0.0-rc6", path = "../../../frame/contracts" } +pallet-grandpa = { version = "2.0.0-rc6", path = "../../../frame/grandpa" } +pallet-indices = { version = "2.0.0-rc6", path = "../../../frame/indices" } +sp-keyring = { version = "2.0.0-rc6", path = "../../../primitives/keyring" } +node-executor = { version = "2.0.0-rc6", path = "../executor" } +node-primitives = { version = "2.0.0-rc6", path = "../primitives" } +node-runtime = { version = "2.0.0-rc6", path = "../runtime" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-rc6", path = "../../../primitives/io" } +frame-support = { version = "2.0.0-rc6", path = "../../../frame/support" } +pallet-session = { version = "2.0.0-rc6", path = "../../../frame/session" } +pallet-society = { version = "2.0.0-rc6", path = "../../../frame/society" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +pallet-staking = { version = "2.0.0-rc6", path = "../../../frame/staking" } +sc-executor = { version = "0.8.0-rc6", path = "../../../client/executor", features = ["wasmtime"] } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +frame-system = { version = "2.0.0-rc6", path = "../../../frame/system" } +substrate-test-client = { version = "2.0.0-rc6", path = "../../../test-utils/client" } +pallet-timestamp = { version = "2.0.0-rc6", path = "../../../frame/timestamp" } +pallet-transaction-payment = { version = "2.0.0-rc6", path = "../../../frame/transaction-payment" } +pallet-treasury = { version = "2.0.0-rc6", path = "../../../frame/treasury" } wabt = "0.9.2" -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -sp-finality-tracker = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/finality-tracker" } -sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/timestamp" } -sp-block-builder = { version = "2.0.0-dev", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0-dev", path = "../../../client/block-builder" } -sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +sp-finality-tracker = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/finality-tracker" } +sp-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/timestamp" } +sp-block-builder = { version = "2.0.0-rc6", path = "../../../primitives/block-builder" } +sc-block-builder = { version = "0.8.0-rc6", path = "../../../client/block-builder" } +sp-inherents = { version = "2.0.0-rc6", path = "../../../primitives/inherents" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } log = "0.4.8" tempfile = "3.1.0" fs_extra = "1" @@ -54,4 +54,4 @@ futures = "0.3.1" [dev-dependencies] criterion = "0.3.0" -sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } +sc-cli = { version = "0.8.0-rc6", path = "../../../client/cli" } diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index b784d9f42b6c63f59e69cdbda6eb532ca5ad4d8e..8242886fe95ed5662bdd81f37de030cff56d5af2 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Benchmarking module. //! @@ -48,17 +50,16 @@ use node_runtime::{ AccountId, Signature, }; -use sp_core::{ExecutionContext, blake2_256, traits::CloneableSpawn}; +use sp_core::{ExecutionContext, blake2_256, traits::SpawnNamed, Pair, Public, sr25519, ed25519}; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; use sp_inherents::InherentData; use sc_client_api::{ - ExecutionStrategy, + ExecutionStrategy, BlockBackend, execution_extensions::{ExecutionExtensions, ExecutionStrategies}, }; -use sp_core::{Pair, Public, sr25519, ed25519}; use sc_block_builder::BlockBuilderProvider; -use futures::{executor, task}; +use futures::executor; /// Keyring full of accounts for benching. /// @@ -116,7 +117,6 @@ impl Clone for BenchDb { .map(|f_result| f_result.expect("failed to read file in seed db") .path() - .clone() ).collect(); fs_extra::copy_items( &seed_db_files, @@ -132,11 +132,28 @@ impl Clone for BenchDb { #[derive(Debug, PartialEq, Clone, Copy)] pub enum BlockType { /// Bunch of random transfers. - RandomTransfersKeepAlive(usize), + RandomTransfersKeepAlive, /// Bunch of random transfers that drain all of the source balance. - RandomTransfersReaping(usize), + RandomTransfersReaping, /// Bunch of "no-op" calls. - Noop(usize), + Noop, +} + +impl BlockType { + /// Create block content description with specified number of transactions. + pub fn to_content(self, size: Option) -> BlockContent { + BlockContent { + block_type: self, + size, + } + } +} + +/// Content of the generated block. +#[derive(Clone, Debug)] +pub struct BlockContent { + block_type: BlockType, + size: Option, } /// Type of backend database. @@ -162,15 +179,6 @@ impl DatabaseType { } } -impl BlockType { - /// Number of transactions for this block type. - pub fn transactions(&self) -> usize { - match self { - Self::RandomTransfersKeepAlive(v) | Self::RandomTransfersReaping(v) | Self::Noop(v) => *v, - } - } -} - /// Benchmarking task executor. /// /// Uses multiple threads as the regular executable. @@ -188,23 +196,107 @@ impl TaskExecutor { } } -impl task::Spawn for TaskExecutor { - fn spawn_obj(&self, future: task::FutureObj<'static, ()>) - -> Result<(), task::SpawnError> { - self.pool.spawn_obj(future) +impl SpawnNamed for TaskExecutor { + fn spawn(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) { + self.pool.spawn_ok(future); + } + + fn spawn_blocking(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) { + self.pool.spawn_ok(future); } } -impl CloneableSpawn for TaskExecutor { - fn clone(&self) -> Box { - Box::new(Clone::clone(self)) +/// Iterator for block content. +pub struct BlockContentIterator<'a> { + iteration: usize, + content: BlockContent, + runtime_version: sc_executor::RuntimeVersion, + genesis_hash: node_primitives::Hash, + keyring: &'a BenchKeyring, +} + +impl<'a> BlockContentIterator<'a> { + fn new(content: BlockContent, keyring: &'a BenchKeyring, client: &Client) -> Self { + let runtime_version = client.runtime_version_at(&BlockId::number(0)) + .expect("There should be runtime version at 0"); + + let genesis_hash = client.block_hash(Zero::zero()) + .expect("Database error?") + .expect("Genesis block always exists; qed") + .into(); + + BlockContentIterator { + iteration: 0, + content, + keyring, + runtime_version, + genesis_hash, + } + } +} + +impl<'a> Iterator for BlockContentIterator<'a> { + type Item = OpaqueExtrinsic; + + fn next(&mut self) -> Option { + if self.content.size.map(|size| size <= self.iteration).unwrap_or(false) { + return None; + } + + let sender = self.keyring.at(self.iteration); + let receiver = get_account_id_from_seed::( + &format!("random-user//{}", self.iteration) + ); + + let signed = self.keyring.sign( + CheckedExtrinsic { + signed: Some((sender, signed_extra(0, node_runtime::ExistentialDeposit::get() + 1))), + function: match self.content.block_type { + BlockType::RandomTransfersKeepAlive => { + Call::Balances( + BalancesCall::transfer_keep_alive( + pallet_indices::address::Address::Id(receiver), + node_runtime::ExistentialDeposit::get() + 1, + ) + ) + }, + BlockType::RandomTransfersReaping => { + Call::Balances( + BalancesCall::transfer( + pallet_indices::address::Address::Id(receiver), + // Transfer so that ending balance would be 1 less than existential deposit + // so that we kill the sender account. + 100*DOLLARS - (node_runtime::ExistentialDeposit::get() - 1), + ) + ) + }, + BlockType::Noop => { + Call::System( + SystemCall::remark(Vec::new()) + ) + }, + }, + }, + self.runtime_version.spec_version, + self.runtime_version.transaction_version, + self.genesis_hash.into(), + ); + + let encoded = Encode::encode(&signed); + + let opaque = OpaqueExtrinsic::decode(&mut &encoded[..]) + .expect("Failed to decode opaque"); + + self.iteration += 1; + + Some(opaque) } } impl BenchDb { /// New immutable benchmarking database. /// - /// See [`new`] method documentation for more information about the purpose + /// See [`BenchDb::new`] method documentation for more information about the purpose /// of this structure. pub fn with_key_types( database_type: DatabaseType, @@ -270,8 +362,33 @@ impl BenchDb { (client, backend) } - /// Generate new block using this database. - pub fn generate_block(&mut self, block_type: BlockType) -> Block { + /// Generate list of required inherents. + /// + /// Uses already instantiated Client. + pub fn generate_inherents(&mut self, client: &Client) -> Vec { + let mut inherent_data = InherentData::new(); + let timestamp = 1 * MinimumPeriod::get(); + + inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) + .expect("Put timestamp failed"); + inherent_data.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &0) + .expect("Put finality tracker failed"); + + client.runtime_api() + .inherent_extrinsics_with_context( + &BlockId::number(0), + ExecutionContext::BlockConstruction, + inherent_data, + ).expect("Get inherents failed") + } + + /// Iterate over some block content with transaction signed using this database keyring. + pub fn block_content(&self, content: BlockContent, client: &Client) -> BlockContentIterator { + BlockContentIterator::new(content, &self.keyring, client) + } + + /// Get cliet for this database operations. + pub fn client(&mut self) -> Client { let (client, _backend) = Self::bench_client( self.database_type, self.directory_guard.path(), @@ -279,84 +396,23 @@ impl BenchDb { &self.keyring, ); - let version = client.runtime_version_at(&BlockId::number(0)) - .expect("There should be runtime version at 0") - .spec_version; + client + } - let genesis_hash = client.block_hash(Zero::zero()) - .expect("Database error?") - .expect("Genesis block always exists; qed") - .into(); + /// Generate new block using this database. + pub fn generate_block(&mut self, content: BlockContent) -> Block { + let client = self.client(); let mut block = client .new_block(Default::default()) .expect("Block creation failed"); - let timestamp = 1 * MinimumPeriod::get(); - - let mut inherent_data = InherentData::new(); - inherent_data.put_data(sp_timestamp::INHERENT_IDENTIFIER, ×tamp) - .expect("Put timestamp failed"); - inherent_data.put_data(sp_finality_tracker::INHERENT_IDENTIFIER, &0) - .expect("Put finality tracker failed"); - - for extrinsic in client.runtime_api() - .inherent_extrinsics_with_context( - &BlockId::number(0), - ExecutionContext::BlockConstruction, - inherent_data, - ).expect("Get inherents failed") - { + for extrinsic in self.generate_inherents(&client) { block.push(extrinsic).expect("Push inherent failed"); } - let mut iteration = 0; let start = std::time::Instant::now(); - for _ in 0..block_type.transactions() { - - let sender = self.keyring.at(iteration); - let receiver = get_account_id_from_seed::( - &format!("random-user//{}", iteration) - ); - - let signed = self.keyring.sign( - CheckedExtrinsic { - signed: Some((sender, signed_extra(0, node_runtime::ExistentialDeposit::get() + 1))), - function: match block_type { - BlockType::RandomTransfersKeepAlive(_) => { - Call::Balances( - BalancesCall::transfer_keep_alive( - pallet_indices::address::Address::Id(receiver), - node_runtime::ExistentialDeposit::get() + 1, - ) - ) - }, - BlockType::RandomTransfersReaping(_) => { - Call::Balances( - BalancesCall::transfer( - pallet_indices::address::Address::Id(receiver), - // Transfer so that ending balance would be 1 less than existential deposit - // so that we kill the sender account. - 100*DOLLARS - (node_runtime::ExistentialDeposit::get() - 1), - ) - ) - }, - BlockType::Noop(_) => { - Call::System( - SystemCall::remark(Vec::new()) - ) - }, - }, - }, - version, - genesis_hash, - ); - - let encoded = Encode::encode(&signed); - - let opaque = OpaqueExtrinsic::decode(&mut &encoded[..]) - .expect("Failed to decode opaque"); - + for opaque in self.block_content(content, &client) { match block.push(opaque) { Err(sp_blockchain::Error::ApplyExtrinsicFailed( sp_blockchain::ApplyExtrinsicFailed::Validity(e) @@ -366,8 +422,8 @@ impl BenchDb { Err(err) => panic!("Error pushing transaction: {:?}", err), Ok(_) => {}, } - iteration += 1; - } + }; + let block = block.build().expect("Block build failed").block; log::info!( @@ -395,7 +451,9 @@ impl BenchDb { ); BenchContext { - client, backend, db_guard: directory_guard, + client: Arc::new(client), + db_guard: directory_guard, + backend, } } } @@ -446,10 +504,16 @@ impl BenchKeyring { } /// Sign transaction with keypair from this keyring. - pub fn sign(&self, xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> UncheckedExtrinsic { + pub fn sign( + &self, + xt: CheckedExtrinsic, + spec_version: u32, + tx_version: u32, + genesis_hash: [u8; 32] + ) -> UncheckedExtrinsic { match xt.signed { Some((signed, extra)) => { - let payload = (xt.function, extra.clone(), version, genesis_hash, genesis_hash); + let payload = (xt.function, extra.clone(), spec_version, tx_version, genesis_hash, genesis_hash); let key = self.accounts.get(&signed).expect("Account id not found in keyring"); let signature = payload.using_encoded(|b| { if b.len() > 256 { @@ -474,7 +538,7 @@ impl BenchKeyring { pub fn generate_genesis(&self) -> node_runtime::GenesisConfig { crate::genesis::config_endowed( false, - Some(node_runtime::WASM_BINARY), + Some(node_runtime::wasm_binary_unwrap()), self.collect_account_ids(), ) } @@ -521,7 +585,7 @@ impl Guard { /// Benchmarking/test context holding instantiated client and backend references. pub struct BenchContext { /// Node client. - pub client: Client, + pub client: Arc, /// Node backend. pub backend: Arc, diff --git a/bin/node/testing/src/client.rs b/bin/node/testing/src/client.rs index 69583e37dc90f25a73dfa0660b5d692f9520d57d..f44747b26b7a6eb6409e76063b23914f3fb43f66 100644 --- a/bin/node/testing/src/client.rs +++ b/bin/node/testing/src/client.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Utilities to build a `TestClient` for `node-runtime`. diff --git a/bin/node/testing/src/genesis.rs b/bin/node/testing/src/genesis.rs index 0f72d2c5471bd835be225a9d046d02867ca6fbc4..6fa178ba4bcddbc7cadb8e61fad4433d852ace22 100644 --- a/bin/node/testing/src/genesis.rs +++ b/bin/node/testing/src/genesis.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Genesis Configuration. @@ -20,8 +22,8 @@ use crate::keyring::*; use sp_keyring::{Ed25519Keyring, Sr25519Keyring}; use node_runtime::{ GenesisConfig, BalancesConfig, SessionConfig, StakingConfig, SystemConfig, - GrandpaConfig, IndicesConfig, ContractsConfig, SocietyConfig, WASM_BINARY, - AccountId, + GrandpaConfig, IndicesConfig, ContractsConfig, SocietyConfig, wasm_binary_unwrap, + AccountId, StakerStatus, }; use node_runtime::constants::currency::*; use sp_core::ChangesTrieConfiguration; @@ -59,7 +61,7 @@ pub fn config_endowed( digest_interval: 2, digest_levels: 2, }) } else { None }, - code: code.map(|x| x.to_vec()).unwrap_or_else(|| WASM_BINARY.to_vec()), + code: code.map(|x| x.to_vec()).unwrap_or_else(|| wasm_binary_unwrap().to_vec()), }), pallet_indices: Some(IndicesConfig { indices: vec![], @@ -85,9 +87,9 @@ pub fn config_endowed( }), pallet_staking: Some(StakingConfig { stakers: vec![ - (dave(), alice(), 111 * DOLLARS, pallet_staking::StakerStatus::Validator), - (eve(), bob(), 100 * DOLLARS, pallet_staking::StakerStatus::Validator), - (ferdie(), charlie(), 100 * DOLLARS, pallet_staking::StakerStatus::Validator) + (dave(), alice(), 111 * DOLLARS, StakerStatus::Validator), + (eve(), bob(), 100 * DOLLARS, StakerStatus::Validator), + (ferdie(), charlie(), 100 * DOLLARS, StakerStatus::Validator) ], validator_count: 3, minimum_validator_count: 0, diff --git a/bin/node/testing/src/keyring.rs b/bin/node/testing/src/keyring.rs index 7ed2b36502e8534c0d30e7714fc00e9c4071b278..3413748563633c2e24fda0e876ed3a34b3273b93 100644 --- a/bin/node/testing/src/keyring.rs +++ b/bin/node/testing/src/keyring.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Test accounts. @@ -68,21 +70,21 @@ pub fn to_session_keys( /// Returns transaction extra. pub fn signed_extra(nonce: Index, extra_fee: Balance) -> SignedExtra { ( - frame_system::CheckVersion::new(), + frame_system::CheckSpecVersion::new(), + frame_system::CheckTxVersion::new(), frame_system::CheckGenesis::new(), frame_system::CheckEra::from(Era::mortal(256, 0)), frame_system::CheckNonce::from(nonce), frame_system::CheckWeight::new(), pallet_transaction_payment::ChargeTransactionPayment::from(extra_fee), - pallet_grandpa::ValidateEquivocationReport::new(), ) } /// Sign given `CheckedExtrinsic`. -pub fn sign(xt: CheckedExtrinsic, version: u32, genesis_hash: [u8; 32]) -> UncheckedExtrinsic { +pub fn sign(xt: CheckedExtrinsic, spec_version: u32, tx_version: u32, genesis_hash: [u8; 32]) -> UncheckedExtrinsic { match xt.signed { Some((signed, extra)) => { - let payload = (xt.function, extra.clone(), version, genesis_hash, genesis_hash); + let payload = (xt.function, extra.clone(), spec_version, tx_version, genesis_hash, genesis_hash); let key = AccountKeyring::from_account_id(&signed).unwrap(); let signature = payload.using_encoded(|b| { if b.len() > 256 { diff --git a/bin/node/testing/src/lib.rs b/bin/node/testing/src/lib.rs index 6a06d318016f290fd96d6a33fbe7c2e2163ce988..d682347e40019dd4a7ff74a8716929130623f31e 100644 --- a/bin/node/testing/src/lib.rs +++ b/bin/node/testing/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A set of testing utilities for Substrate Node. diff --git a/bin/utils/chain-spec-builder/Cargo.toml b/bin/utils/chain-spec-builder/Cargo.toml index a6c2b671fe687f3d103c4673842a9b8a3a73266e..f6d03d4f3d107ce268f2d84efce197cdd1688659 100644 --- a/bin/utils/chain-spec-builder/Cargo.toml +++ b/bin/utils/chain-spec-builder/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "chain-spec-builder" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -13,9 +13,9 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] ansi_term = "0.12.1" -sc-keystore = { version = "2.0.0-dev", path = "../../../client/keystore" } -sc-chain-spec = { version = "2.0.0-dev", path = "../../../client/chain-spec" } -node-cli = { version = "2.0.0-dev", path = "../../node/cli" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sc-keystore = { version = "2.0.0-rc6", path = "../../../client/keystore" } +sc-chain-spec = { version = "2.0.0-rc6", path = "../../../client/chain-spec" } +node-cli = { version = "2.0.0-rc6", path = "../../node/cli" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } rand = "0.7.2" structopt = "0.3.8" diff --git a/bin/utils/chain-spec-builder/README.md b/bin/utils/chain-spec-builder/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3e9ac0bddbdc17539d12893553789983e38ab05f --- /dev/null +++ b/bin/utils/chain-spec-builder/README.md @@ -0,0 +1 @@ +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/bin/utils/chain-spec-builder/build.rs b/bin/utils/chain-spec-builder/build.rs index 513cc234d4363a854961db1efdea1cbc7007ce56..8d5aac1a08742486a9b0e5d55aaf7959941abd77 100644 --- a/bin/utils/chain-spec-builder/build.rs +++ b/bin/utils/chain-spec-builder/build.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::env; diff --git a/bin/utils/chain-spec-builder/src/main.rs b/bin/utils/chain-spec-builder/src/main.rs index 144018701460e79254db45b81cd1ef2431e2b866..2bfbb0952775d9b138d8014b1be342785ed892f6 100644 --- a/bin/utils/chain-spec-builder/src/main.rs +++ b/bin/utils/chain-spec-builder/src/main.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{fs, path::{Path, PathBuf}}; @@ -129,7 +131,7 @@ fn generate_chain_spec( Default::default(), ); - chain_spec.as_json(false).map_err(|err| err.to_string()) + chain_spec.as_json(false).map_err(|err| err) } fn generate_authority_keys_and_store( diff --git a/bin/utils/subkey/Cargo.toml b/bin/utils/subkey/Cargo.toml index 7f50f4546ce5a54c892f62842e6f302cb795978e..0dc1a1b5970c90a22a8a569d3a2e4b072d48ae93 100644 --- a/bin/utils/subkey/Cargo.toml +++ b/bin/utils/subkey/Cargo.toml @@ -1,40 +1,27 @@ [package] name = "subkey" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +[[bin]] +path = "src/main.rs" +name = "subkey" + [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies] -futures = "0.1.29" -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -node-runtime = { version = "2.0.0-dev", path = "../../node/runtime" } -node-primitives = { version = "2.0.0-dev", path = "../../node/primitives" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -rand = "0.7.2" -clap = "2.33.0" -tiny-bip39 = "0.7" -substrate-bip39 = "0.4.1" -hex = "0.4.0" -hex-literal = "0.2.1" -codec = { package = "parity-scale-codec", version = "1.3.0" } -frame-system = { version = "2.0.0-dev", path = "../../../frame/system" } -pallet-balances = { version = "2.0.0-dev", path = "../../../frame/balances" } -pallet-transaction-payment = { version = "2.0.0-dev", path = "../../../frame/transaction-payment" } -pallet-grandpa = { version = "2.0.0-dev", path = "../../../frame/grandpa" } -rpassword = "4.0.1" -itertools = "0.8.2" -derive_more = { version = "0.99.2" } -sc-rpc = { version = "2.0.0-dev", path = "../../../client/rpc" } -jsonrpc-core-client = { version = "14.0.3", features = ["http"] } -hyper = "0.12.35" -libp2p = "0.18.1" -serde_json = "1.0" +node-runtime = { version = "2.0.0-rc6", path = "../../node/runtime" } +node-primitives = { version = "2.0.0-rc6", path = "../../node/primitives" } +sc-cli = { version = "0.8.0-rc6", path = "../../../client/cli" } +substrate-frame-cli = { version = "2.0.0-rc6", path = "../../../utils/frame/frame-utilities-cli" } +structopt = "0.3.14" +frame-system = { version = "2.0.0-rc6", path = "../../../frame/system" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } [features] bench = [] diff --git a/bin/utils/subkey/README.adoc b/bin/utils/subkey/README.adoc index 1fa0753312f0cd6dc1f9a94c42866326bdf4f59d..5ce0d2d324470b51032f5c43c7978fb246691da1 100644 --- a/bin/utils/subkey/README.adoc +++ b/bin/utils/subkey/README.adoc @@ -31,7 +31,7 @@ OUTPUT: `subkey` expects a message to come in on STDIN, one way to sign a message would look like this: ```bash -echo -n | subkey sign +echo -n | subkey sign --suri OUTPUT: a69da4a6ccbf81dbbbfad235fa12cf8528c18012b991ae89214de8d20d29c1280576ced6eb38b7406d1b7e03231df6dd4a5257546ddad13259356e1c3adfb509 @@ -72,7 +72,7 @@ Will output a signed and encoded `UncheckedMortalCompactExtrinsic` as hex. === Inspecting a module ID ```bash -subkey --network kusama moduleid "py/trsry" +subkey module-id "py/trsry" --network kusama OUTPUT: Public Key URI `F3opxRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29` is account: diff --git a/bin/utils/subkey/README.md b/bin/utils/subkey/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3e9ac0bddbdc17539d12893553789983e38ab05f --- /dev/null +++ b/bin/utils/subkey/README.md @@ -0,0 +1 @@ +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/bin/utils/subkey/src/lib.rs b/bin/utils/subkey/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..bb89541d5b14edda65747109f1a8e153e7dfd368 --- /dev/null +++ b/bin/utils/subkey/src/lib.rs @@ -0,0 +1,81 @@ +// This file is part of Substrate. + +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use structopt::StructOpt; +use sc_cli::{ + Error, VanityCmd, SignCmd, VerifyCmd, InsertCmd, + GenerateNodeKeyCmd, GenerateCmd, InspectKeyCmd, InspectNodeKeyCmd +}; +use substrate_frame_cli::ModuleIdCmd; +use sp_core::crypto::Ss58Codec; + +#[derive(Debug, StructOpt)] +#[structopt( + name = "subkey", + author = "Parity Team ", + about = "Utility for generating and restoring with Substrate keys", +)] +pub enum Subkey { + /// Generate a random node libp2p key, save it to file and print its peer ID + GenerateNodeKey(GenerateNodeKeyCmd), + + /// Generate a random account + Generate(GenerateCmd), + + /// Gets a public key and a SS58 address from the provided Secret URI + InspectKey(InspectKeyCmd), + + /// Print the peer ID corresponding to the node key in the given file + InspectNodeKey(InspectNodeKeyCmd), + + /// Insert a key to the keystore of a node. + Insert(InsertCmd), + + /// Inspect a module ID address + ModuleId(ModuleIdCmd), + + /// Sign a message, with a given (secret) key. + Sign(SignCmd), + + /// Generate a seed that provides a vanity address. + Vanity(VanityCmd), + + /// Verify a signature for a message, provided on STDIN, with a given (public or secret) key. + Verify(VerifyCmd), +} + +/// Run the subkey command, given the apropriate runtime. +pub fn run() -> Result<(), Error> + where + R: frame_system::Trait, + R::AccountId: Ss58Codec +{ + match Subkey::from_args() { + Subkey::GenerateNodeKey(cmd) => cmd.run()?, + Subkey::Generate(cmd) => cmd.run()?, + Subkey::InspectKey(cmd) => cmd.run()?, + Subkey::InspectNodeKey(cmd) => cmd.run()?, + Subkey::Insert(cmd) => cmd.run()?, + Subkey::ModuleId(cmd) => cmd.run::()?, + Subkey::Vanity(cmd) => cmd.run()?, + Subkey::Verify(cmd) => cmd.run()?, + Subkey::Sign(cmd) => cmd.run()?, + }; + + Ok(()) +} diff --git a/bin/utils/subkey/src/main.rs b/bin/utils/subkey/src/main.rs index 754a2611bcd0f997e5f18b8b68868cb9a0c451d3..dd14425130b7d32ce9ddb7123929a74aa63da93d 100644 --- a/bin/utils/subkey/src/main.rs +++ b/bin/utils/subkey/src/main.rs @@ -1,813 +1,25 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - -#![cfg_attr(feature = "bench", feature(test))] -#[cfg(feature = "bench")] -extern crate test; - -use bip39::{Language, Mnemonic, MnemonicType}; -use clap::{App, ArgMatches, SubCommand}; -use codec::{Decode, Encode}; -use hex_literal::hex; -use itertools::Itertools; -use libp2p::identity::{ed25519 as libp2p_ed25519, PublicKey}; -use node_primitives::{Balance, Hash, Index, AccountId, Signature}; -use node_runtime::{BalancesCall, Call, Runtime, SignedPayload, UncheckedExtrinsic, VERSION}; -use serde_json::json; -use sp_core::{ - crypto::{set_default_ss58_version, Ss58AddressFormat, Ss58Codec}, - ed25519, sr25519, ecdsa, Pair, Public, H256, hexdisplay::HexDisplay, -}; -use sp_runtime::{traits::{AccountIdConversion, IdentifyAccount, Verify}, generic::Era, ModuleId}; -use std::{ - convert::{TryInto, TryFrom}, io::{stdin, Read}, str::FromStr, path::PathBuf, fs, fmt, -}; - -mod rpc; -mod vanity; - -enum OutputType { - Json, - Text, -} - -impl<'a> TryFrom<&'a str> for OutputType { - type Error = (); - - fn try_from(s: &'a str) -> Result { - match s { - "json" => Ok(OutputType::Json), - "text" => Ok(OutputType::Text), - _ => Err(()), - } - } - -} - -trait Crypto: Sized { - type Pair: Pair; - type Public: Public + Ss58Codec + AsRef<[u8]> + std::hash::Hash; - fn pair_from_suri(suri: &str, password: Option<&str>) -> Self::Pair { - Self::Pair::from_string(suri, password).expect("Invalid phrase") - } - fn ss58_from_pair(pair: &Self::Pair) -> String where - ::Public: PublicT, - { - pair.public().into_runtime().into_account().to_ss58check() - } - fn public_from_pair(pair: &Self::Pair) -> Self::Public { - pair.public() - } - fn print_from_uri( - uri: &str, - password: Option<&str>, - network_override: Option, - output: OutputType, - ) where - ::Public: PublicT, - { - let v = network_override.unwrap_or_default(); - if let Ok((pair, seed)) = Self::Pair::from_phrase(uri, password) { - let public_key = Self::public_from_pair(&pair); - - match output { - OutputType::Json => { - let json = json!({ - "secretPhrase": uri, - "networkId": String::from(v), - "secretSeed": format_seed::(seed), - "publicKey": format_public_key::(public_key.clone()), - "accountId": format_account_id::(public_key), - "ss58Address": Self::ss58_from_pair(&pair), - }); - println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); - }, - OutputType::Text => { - println!("Secret phrase `{}` is account:\n \ - Network ID/version: {}\n \ - Secret seed: {}\n \ - Public key (hex): {}\n \ - Account ID: {}\n \ - SS58 Address: {}", - uri, - String::from(v), - format_seed::(seed), - format_public_key::(public_key.clone()), - format_account_id::(public_key), - Self::ss58_from_pair(&pair), - ); - }, - } - } else if let Ok((pair, seed)) = Self::Pair::from_string_with_seed(uri, password) { - let public_key = Self::public_from_pair(&pair); - - match output { - OutputType::Json => { - let json = json!({ - "secretKeyUri": uri, - "networkId": String::from(v), - "secretSeed": if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, - "publicKey": format_public_key::(public_key.clone()), - "accountId": format_account_id::(public_key), - "ss58Address": Self::ss58_from_pair(&pair), - }); - println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); - }, - OutputType::Text => { - println!("Secret Key URI `{}` is account:\n \ - Network ID/version: {}\n \ - Secret seed: {}\n \ - Public key (hex): {}\n \ - Account ID: {}\n \ - SS58 Address: {}", - uri, - String::from(v), - if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, - format_public_key::(public_key.clone()), - format_account_id::(public_key), - Self::ss58_from_pair(&pair), - ); - }, - } - } else if let Ok((public_key, v)) = - ::Public::from_string_with_version(uri) - { - let v = network_override.unwrap_or(v); - - match output { - OutputType::Json => { - let json = json!({ - "publicKeyUri": uri, - "networkId": String::from(v), - "publicKey": format_public_key::(public_key.clone()), - "accountId": format_account_id::(public_key.clone()), - "ss58Address": public_key.to_ss58check_with_version(v), - }); - println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); - }, - OutputType::Text => { - println!("Public Key URI `{}` is account:\n \ - Network ID/version: {}\n \ - Public key (hex): {}\n \ - Account ID: {}\n \ - SS58 Address: {}", - uri, - String::from(v), - format_public_key::(public_key.clone()), - format_account_id::(public_key.clone()), - public_key.to_ss58check_with_version(v), - ); - }, - } - } else { - eprintln!("Invalid phrase/URI given"); - } - } -} - -struct Ed25519; - -impl Crypto for Ed25519 { - type Pair = ed25519::Pair; - type Public = ed25519::Public; - - fn pair_from_suri(suri: &str, password_override: Option<&str>) -> Self::Pair { - ed25519::Pair::from_legacy_string(suri, password_override) - } -} - -struct Sr25519; - -impl Crypto for Sr25519 { - type Pair = sr25519::Pair; - type Public = sr25519::Public; -} - -struct Ecdsa; - -impl Crypto for Ecdsa { - type Pair = ecdsa::Pair; - type Public = ecdsa::Public; -} - -type SignatureOf = <::Pair as Pair>::Signature; -type PublicOf = <::Pair as Pair>::Public; -type SeedOf = <::Pair as Pair>::Seed; -type AccountPublic = ::Signer; - -trait SignatureT: AsRef<[u8]> + AsMut<[u8]> + Default { - /// Converts the signature into a runtime account signature, if possible. If not possible, bombs out. - fn into_runtime(self) -> Signature { - panic!("This cryptography isn't supported for this runtime.") - } -} -trait PublicT: Sized + AsRef<[u8]> + Ss58Codec { - /// Converts the public key into a runtime account public key, if possible. If not possible, bombs out. - fn into_runtime(self) -> AccountPublic { - panic!("This cryptography isn't supported for this runtime.") - } -} - -impl SignatureT for sr25519::Signature { fn into_runtime(self) -> Signature { self.into() } } -impl SignatureT for ed25519::Signature { fn into_runtime(self) -> Signature { self.into() } } -impl SignatureT for ecdsa::Signature { fn into_runtime(self) -> Signature { self.into() } } -impl PublicT for sr25519::Public { fn into_runtime(self) -> AccountPublic { self.into() } } -impl PublicT for ed25519::Public { fn into_runtime(self) -> AccountPublic { self.into() } } -impl PublicT for ecdsa::Public { fn into_runtime(self) -> AccountPublic { self.into() } } - -fn get_usage() -> String { - let networks = Ss58AddressFormat::all().iter().cloned().map(String::from).join("/"); - let default_network = String::from(Ss58AddressFormat::default()); - format!(" - -e, --ed25519 'Use Ed25519/BIP39 cryptography' - -k, --secp256k1 'Use SECP256k1/ECDSA/BIP39 cryptography' - -s, --sr25519 'Use Schnorr/Ristretto x25519/BIP39 cryptography' - [network] -n, --network 'Specify a network. One of {}. Default is {}' - [password] -p, --password 'The password for the key' - --password-interactive 'You will be prompted for the password for the key.' - [output] -o, --output 'Specify an output format. One of text, json. Default is text.' - ", networks, default_network) -} - -fn get_app<'a, 'b>(usage: &'a str) -> App<'a, 'b> { - App::new("subkey") - .author("Parity Team ") - .about("Utility for generating and restoring with Substrate keys") - .version(env!("CARGO_PKG_VERSION")) - .args_from_usage(usage) - .subcommands(vec![ - SubCommand::with_name("generate") - .about("Generate a random account") - .args_from_usage("[words] -w, --words \ - 'The number of words in the phrase to generate. One of 12 \ - (default), 15, 18, 21 and 24.' - "), - SubCommand::with_name("generate-node-key") - .about("Generate a random node libp2p key, save it to file and print its peer ID") - .args_from_usage("[file] 'Name of file to save secret key to'"), - SubCommand::with_name("inspect") - .about("Gets a public key and a SS58 address from the provided Secret URI") - .args_from_usage("[uri] 'A Key URI to be inspected. May be a secret seed, \ - secret URI (with derivation paths and password), SS58 or public URI. \ - If the value is a file, the file content is used as URI. \ - If not given, you will be prompted for the URI.' - "), - SubCommand::with_name("sign") - .about("Sign a message, provided on STDIN, with a given (secret) key") - .args_from_usage(" - -h, --hex 'The message on STDIN is hex-encoded data' - 'The secret key URI. \ - If the value is a file, the file content is used as URI. \ - If not given, you will be prompted for the URI.' - "), - SubCommand::with_name("sign-transaction") - .about("Sign transaction from encoded Call. Returns a signed and encoded \ - UncheckedMortalCompactExtrinsic as hex.") - .args_from_usage(" - -c, --call 'The call, hex-encoded.' - -n, --nonce 'The nonce.' - -p, --password 'The password for the key.' - -h, --prior-block-hash 'The prior block hash, hex-encoded.' - -s, --suri 'The secret key URI.' - "), - SubCommand::with_name("transfer") - .about("Author and sign a Node pallet_balances::Transfer transaction with a given (secret) key") - .args_from_usage(" - -g, --genesis 'The genesis hash or a recognized \ - chain identifier (dev, elm, alex).' - 'The signing secret key URI.' - 'The destination account public key URI.' - 'The number of units to transfer.' - 'The signing account's transaction index.' - "), - SubCommand::with_name("vanity") - .about("Generate a seed that provides a vanity address") - .args_from_usage(" - -n, --number 'Number of keys to generate' - 'Desired pattern' - "), - SubCommand::with_name("verify") - .about("Verify a signature for a message, provided on STDIN, with a given \ - (public or secret) key") - .args_from_usage(" - -h, --hex 'The message on STDIN is hex-encoded data' - 'Signature, hex-encoded.' - 'The public or secret key URI. \ - If the value is a file, the file content is used as URI. \ - If not given, you will be prompted for the URI.' - "), - SubCommand::with_name("insert") - .about("Insert a key to the keystore of a node") - .args_from_usage(" - 'The secret key URI. \ - If the value is a file, the file content is used as URI. \ - If not given, you will be prompted for the URI.' - 'Key type, examples: \"gran\", or \"imon\" ' - [node-url] 'Node JSON-RPC endpoint, default \"http:://localhost:9933\"' - "), - SubCommand::with_name("moduleid") - .about("Inspect a module ID address") - .args_from_usage(" - 'The module ID used to derive the account' - ") - ]) -} - -fn main() -> Result<(), Error> { - let usage = get_usage(); - let matches = get_app(&usage).get_matches(); - - if matches.is_present("ed25519") { - return execute::(matches); - } - if matches.is_present("secp256k1") { - return execute::(matches) - } - return execute::(matches) -} - -/// Get `URI` from CLI or prompt the user. -/// -/// `URI` is extracted from `matches` by using `match_name`. -/// -/// If the `URI` given as CLI argument is a file, the file content is taken as `URI`. -/// If no `URI` is given to the CLI, the user is prompted for it. -fn get_uri(match_name: &str, matches: &ArgMatches) -> Result { - let uri = if let Some(uri) = matches.value_of(match_name) { - let file = PathBuf::from(uri); - if file.is_file() { - fs::read_to_string(uri)? - .trim_end() - .into() - } else { - uri.into() - } - } else { - rpassword::read_password_from_tty(Some("URI: "))? - }; - - Ok(uri) -} - -#[derive(derive_more::Display, derive_more::From)] -enum Error { - Static(&'static str), - Io(std::io::Error), - Formatted(String), -} - -impl fmt::Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) - } -} - -fn static_err(msg: &'static str) -> Result<(), Error> { - Err(Error::Static(msg)) -} - -fn execute(matches: ArgMatches) -> Result<(), Error> -where - SignatureOf: SignatureT, - PublicOf: PublicT, -{ - let password_interactive = matches.is_present("password-interactive"); - let password = matches.value_of("password"); - - let password = if password.is_some() && password_interactive { - return static_err("`--password` given and `--password-interactive` selected!"); - } else if password_interactive { - Some( - rpassword::read_password_from_tty(Some("Key password: "))? - ) - } else { - password.map(Into::into) - }; - let password = password.as_ref().map(String::as_str); - - let maybe_network: Option = match matches.value_of("network").map(|network| { - network - .try_into() - .map_err(|_| Error::Static("Invalid network name. See --help for available networks.")) - }) { - Some(Err(e)) => return Err(e), - Some(Ok(v)) => Some(v), - None => None, - }; - - if let Some(network) = maybe_network { - set_default_ss58_version(network); - } - - let output: OutputType = match matches.value_of("output").map(TryInto::try_into) { - Some(Err(_)) => return Err(Error::Static("Invalid output name. See --help for available outputs.")), - Some(Ok(v)) => v, - None => OutputType::Text, - }; - - match matches.subcommand() { - ("generate", Some(matches)) => { - let mnemonic = generate_mnemonic(matches)?; - C::print_from_uri(mnemonic.phrase(), password, maybe_network, output); - } - ("generate-node-key", Some(matches)) => { - let file = matches.value_of("file").ok_or(Error::Static("Output file name is required"))?; - - let keypair = libp2p_ed25519::Keypair::generate(); - let secret = keypair.secret(); - let peer_id = PublicKey::Ed25519(keypair.public()).into_peer_id(); - - fs::write(file, secret.as_ref())?; - - println!("{}", peer_id); - } - ("inspect", Some(matches)) => { - C::print_from_uri(&get_uri("uri", &matches)?, password, maybe_network, output); - } - ("sign", Some(matches)) => { - let suri = get_uri("suri", &matches)?; - let should_decode = matches.is_present("hex"); - - let message = read_message_from_stdin(should_decode)?; - let signature = do_sign::(&suri, message, password)?; - println!("{}", signature); - } - ("verify", Some(matches)) => { - let uri = get_uri("uri", &matches)?; - let should_decode = matches.is_present("hex"); - - let message = read_message_from_stdin(should_decode)?; - let is_valid_signature = do_verify::(matches, &uri, message)?; - if is_valid_signature { - println!("Signature verifies correctly."); - } else { - return static_err("Signature invalid."); - } - } - ("vanity", Some(matches)) => { - let desired: String = matches - .value_of("pattern") - .map(str::to_string) - .unwrap_or_default(); - let result = vanity::generate_key::(&desired)?; - let formated_seed = format_seed::(result.seed); - C::print_from_uri(&formated_seed, None, maybe_network, output); - } - ("transfer", Some(matches)) => { - let signer = read_pair::(matches.value_of("from"), password)?; - let index = read_required_parameter::(matches, "index")?; - let genesis_hash = read_genesis_hash(matches)?; - - let to: AccountId = read_account_id(matches.value_of("to")); - let amount = read_required_parameter::(matches, "amount")?; - let function = Call::Balances(BalancesCall::transfer(to.into(), amount)); - - let extrinsic = create_extrinsic::(function, index, signer, genesis_hash); - - print_extrinsic(extrinsic); - } - ("sign-transaction", Some(matches)) => { - let signer = read_pair::(matches.value_of("suri"), password)?; - let index = read_required_parameter::(matches, "nonce")?; - let genesis_hash = read_genesis_hash(matches)?; - - let call = matches.value_of("call").expect("call is required; qed"); - let function: Call = hex::decode(&call) - .ok() - .and_then(|x| Decode::decode(&mut &x[..]).ok()) - .unwrap(); - - let extrinsic = create_extrinsic::(function, index, signer, genesis_hash); - - print_extrinsic(extrinsic); - } - ("insert", Some(matches)) => { - let suri = get_uri("suri", &matches)?; - let pair = read_pair::(Some(&suri), password)?; - let node_url = matches.value_of("node-url").unwrap_or("http://localhost:9933"); - let key_type = matches.value_of("key-type").ok_or(Error::Static("Key type id is required"))?; - - // Just checking - let _key_type_id = sp_core::crypto::KeyTypeId::try_from(key_type) - .map_err(|_| Error::Static("Cannot convert argument to keytype: argument should be 4-character string"))?; - - let rpc = rpc::RpcClient::new(node_url.to_string()); - - rpc.insert_key( - key_type.to_string(), - suri, - sp_core::Bytes(pair.public().as_ref().to_vec()), - ); - } - ("moduleid", Some(matches)) => { - let id = get_uri("id", &matches)?; - if id.len() != 8 { - Err("a module id must be a string of 8 characters")? - } - - let id_fixed_array: [u8; 8] = id.as_bytes().try_into() - .map_err(|_| Error::Static("Cannot convert argument to moduleid: argument should be 8-character string"))?; - - let account_id: AccountId = ModuleId(id_fixed_array).into_account(); - let v = maybe_network.unwrap_or(Ss58AddressFormat::SubstrateAccount); - - C::print_from_uri(&account_id.to_ss58check_with_version(v), password, maybe_network, output); - } - _ => print_usage(&matches), - } - - Ok(()) -} - -/// Creates a new randomly generated mnemonic phrase. -fn generate_mnemonic(matches: &ArgMatches) -> Result { - let words = match matches.value_of("words") { - Some(words) => { - let num = usize::from_str(words).map_err(|_| Error::Static("Invalid number given for --words"))?; - MnemonicType::for_word_count(num) - .map_err(|_| Error::Static("Invalid number of words given for phrase: must be 12/15/18/21/24"))? - }, - None => MnemonicType::Words12, - }; - Ok(Mnemonic::new(words, Language::English)) -} - -fn do_sign(suri: &str, message: Vec, password: Option<&str>) -> Result -where - SignatureOf: SignatureT, - PublicOf: PublicT, -{ - let pair = read_pair::(Some(suri), password)?; - let signature = pair.sign(&message); - Ok(format_signature::(&signature)) -} - -fn do_verify(matches: &ArgMatches, uri: &str, message: Vec) -> Result -where - SignatureOf: SignatureT, - PublicOf: PublicT, -{ - - let signature = read_signature::(matches)?; - let pubkey = read_public_key::(Some(uri)); - Ok(<::Pair as Pair>::verify(&signature, &message, &pubkey)) -} - -fn decode_hex>(message: T) -> Result, Error> { - hex::decode(message).map_err(|e| Error::Formatted(format!("Invalid hex ({})", e))) -} - -fn read_message_from_stdin(should_decode: bool) -> Result, Error> { - let mut message = vec![]; - stdin() - .lock() - .read_to_end(&mut message)?; - if should_decode { - message = decode_hex(&message)?; - } - Ok(message) -} - -fn read_required_parameter(matches: &ArgMatches, name: &str) -> Result where - ::Err: std::fmt::Debug, -{ - let str_value = matches - .value_of(name) - .expect("parameter is required; thus it can't be None; qed"); - str::parse::(str_value).map_err(|_| - Error::Formatted(format!("Invalid `{}' parameter; expecting an integer.", name)) - ) -} - -fn read_genesis_hash(matches: &ArgMatches) -> Result { - let genesis_hash: Hash = match matches.value_of("genesis").unwrap_or("alex") { - "elm" => hex!["10c08714a10c7da78f40a60f6f732cf0dba97acfb5e2035445b032386157d5c3"].into(), - "alex" => hex!["dcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b"].into(), - h => Decode::decode(&mut &decode_hex(h)?[..]) - .expect("Invalid genesis hash or unrecognized chain identifier"), - }; - println!( - "Using a genesis hash of {}", - HexDisplay::from(&genesis_hash.as_ref()) - ); - Ok(genesis_hash) -} - -fn read_signature(matches: &ArgMatches) -> Result, Error> -where - SignatureOf: SignatureT, - PublicOf: PublicT, -{ - let sig_data = matches - .value_of("sig") - .expect("signature parameter is required; thus it can't be None; qed"); - let mut signature = <::Pair as Pair>::Signature::default(); - let sig_data = decode_hex(sig_data)?; - if sig_data.len() != signature.as_ref().len() { - return Err(Error::Formatted(format!( - "signature has an invalid length. read {} bytes, expected {} bytes", - sig_data.len(), - signature.as_ref().len(), - ))); - } - signature.as_mut().copy_from_slice(&sig_data); - Ok(signature) -} - -fn read_public_key(matched_uri: Option<&str>) -> PublicOf -where - PublicOf: PublicT, -{ - let uri = matched_uri.expect("parameter is required; thus it can't be None; qed"); - let uri = if uri.starts_with("0x") { - &uri[2..] - } else { - uri - }; - if let Ok(pubkey_vec) = hex::decode(uri) { - ::Public::from_slice(pubkey_vec.as_slice()) - } else { - ::Public::from_string(uri) - .ok() - .expect("Invalid URI; expecting either a secret URI or a public URI.") - } -} - -fn read_account_id(matched_uri: Option<&str>) -> AccountId { - let uri = matched_uri.expect("parameter is required; thus it can't be None; qed"); - let uri = if uri.starts_with("0x") { - &uri[2..] - } else { - uri - }; - if let Ok(data_vec) = hex::decode(uri) { - AccountId::try_from(data_vec.as_slice()) - .expect("Invalid hex length for account ID; should be 32 bytes") - } else { - AccountId::from_ss58check(uri).ok() - .expect("Invalid SS58-check address given for account ID.") - } -} - -fn read_pair( - matched_suri: Option<&str>, - password: Option<&str>, -) -> Result<::Pair, Error> where - SignatureOf: SignatureT, - PublicOf: PublicT, -{ - let suri = matched_suri.ok_or(Error::Static("parameter is required; thus it can't be None; qed"))?; - Ok(C::pair_from_suri(suri, password)) -} - -fn format_signature(signature: &SignatureOf) -> String { - format!("{}", HexDisplay::from(&signature.as_ref())) -} - -fn format_seed(seed: SeedOf) -> String { - format!("0x{}", HexDisplay::from(&seed.as_ref())) -} - -fn format_public_key(public_key: PublicOf) -> String { - format!("0x{}", HexDisplay::from(&public_key.as_ref())) -} - -fn format_account_id(public_key: PublicOf) -> String where - PublicOf: PublicT, -{ - format!("0x{}", HexDisplay::from(&public_key.into_runtime().into_account().as_ref())) -} - -fn create_extrinsic( - function: Call, - index: Index, - signer: C::Pair, - genesis_hash: H256, -) -> UncheckedExtrinsic where - PublicOf: PublicT, - SignatureOf: SignatureT, -{ - let extra = |i: Index, f: Balance| { - ( - frame_system::CheckVersion::::new(), - frame_system::CheckGenesis::::new(), - frame_system::CheckEra::::from(Era::Immortal), - frame_system::CheckNonce::::from(i), - frame_system::CheckWeight::::new(), - pallet_transaction_payment::ChargeTransactionPayment::::from(f), - pallet_grandpa::ValidateEquivocationReport::::new(), - ) - }; - let raw_payload = SignedPayload::from_raw( - function, - extra(index, 0), - ( - VERSION.spec_version as u32, - genesis_hash, - genesis_hash, - (), - (), - (), - (), - ), - ); - let signature = raw_payload.using_encoded(|payload| signer.sign(payload)).into_runtime(); - let signer = signer.public().into_runtime(); - let (function, extra, _) = raw_payload.deconstruct(); - - UncheckedExtrinsic::new_signed( - function, - signer.into_account().into(), - signature, - extra, - ) -} - -fn print_extrinsic(extrinsic: UncheckedExtrinsic) { - println!("0x{}", HexDisplay::from(&extrinsic.encode())); -} - -fn print_usage(matches: &ArgMatches) { - println!("{}", matches.usage()); -} - -#[cfg(test)] -mod tests { - use super::*; - - fn test_generate_sign_verify() - where - SignatureOf: SignatureT, - PublicOf: PublicT, - { - let usage = get_usage(); - let app = get_app(&usage); - let password = None; - - // Generate public key and seed. - let arg_vec = vec!["subkey", "generate"]; - - let matches = app.clone().get_matches_from(arg_vec); - let matches = matches.subcommand().1.unwrap(); - let mnemonic = generate_mnemonic(matches).expect("generate failed"); - - let (pair, seed) = - <::Pair as Pair>::from_phrase(mnemonic.phrase(), password) - .unwrap(); - let public_key = CryptoType::public_from_pair(&pair); - let public_key = format_public_key::(public_key); - let seed = format_seed::(seed); - let message = "Blah Blah\n".as_bytes().to_vec(); - - let signature = do_sign::(&seed, message.clone(), password).expect("signing failed"); - - // Verify the previous signature. - let arg_vec = vec!["subkey", "verify", &signature[..], &public_key[..]]; - - let matches = get_app(&usage).get_matches_from(arg_vec); - let matches = matches.subcommand().1.unwrap(); - - assert!(do_verify::(matches, &public_key, message).expect("verify failed")); - } - - #[test] - fn generate_sign_verify_should_work_for_ed25519() { - test_generate_sign_verify::(); - } - - #[test] - fn generate_sign_verify_should_work_for_sr25519() { - test_generate_sign_verify::(); - } - - #[test] - fn should_work() { - let s = "0123456789012345678901234567890123456789012345678901234567890123"; +// along with this program. If not, see . - let d1: Hash = hex::decode(s) - .ok() - .and_then(|x| Decode::decode(&mut &x[..]).ok()) - .unwrap(); +//! Subkey utility, based on node_runtime. - let d2: Hash = { - let mut gh: [u8; 32] = Default::default(); - gh.copy_from_slice(hex::decode(s).unwrap().as_ref()); - Hash::from(gh) - }; +use node_runtime::Runtime; - assert_eq!(d1, d2); - } +fn main() -> Result<(), sc_cli::Error> { + subkey::run::() } diff --git a/bin/utils/subkey/src/rpc.rs b/bin/utils/subkey/src/rpc.rs deleted file mode 100644 index e08ccc19a22b8de89088ffade2809f7418eb7d25..0000000000000000000000000000000000000000 --- a/bin/utils/subkey/src/rpc.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Helper to run commands against current node RPC - -use futures::Future; -use hyper::rt; -use node_primitives::Hash; -use sc_rpc::author::AuthorClient; -use jsonrpc_core_client::transports::http; -use sp_core::Bytes; - -pub struct RpcClient { url: String } - -impl RpcClient { - pub fn new(url: String) -> Self { Self { url } } - - pub fn insert_key( - &self, - key_type: String, - suri: String, - public: Bytes, - ) { - let url = self.url.clone(); - - rt::run( - http::connect(&url) - .and_then(|client: AuthorClient| { - client.insert_key(key_type, suri, public).map(|_| ()) - }) - .map_err(|e| { - eprintln!("Error inserting key: {:?}", e); - }) - ); - } -} diff --git a/bin/utils/subkey/src/vanity.rs b/bin/utils/subkey/src/vanity.rs deleted file mode 100644 index f921470946ec04732654091922711808f8aa6ad7..0000000000000000000000000000000000000000 --- a/bin/utils/subkey/src/vanity.rs +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -use super::{PublicOf, PublicT, Crypto}; -use sp_core::Pair; -use rand::{rngs::OsRng, RngCore}; - -fn good_waypoint(done: u64) -> u64 { - match done { - 0..=1_000_000 => 100_000, - 0..=10_000_000 => 1_000_000, - 0..=100_000_000 => 10_000_000, - _ => 100_000_000, - } -} - -fn next_seed(seed: &mut [u8]) { - for i in 0..seed.len() { - match seed[i] { - 255 => { - seed[i] = 0; - } - _ => { - seed[i] += 1; - break; - } - } - } -} - -/// A structure used to carry both Pair and seed. -/// This should usually NOT been used. If unsure, use Pair. -pub(super) struct KeyPair { - pub pair: C::Pair, - pub seed: ::Seed, - pub score: usize, -} - -/// Calculate the score of a key based on the desired -/// input. -fn calculate_score(_desired: &str, key: &str) -> usize { - for truncate in 0.._desired.len() { - let snip_size = _desired.len() - truncate; - let truncated = &_desired[0..snip_size]; - if let Some(pos) = key.find(truncated) { - return (47 - pos) + (snip_size * 48); - } - } - 0 -} - -/// Validate whether the char is allowed to be used in base58. -/// num 0, lower l, upper I and O are not allowed. -fn validate_base58(c :char) -> bool { - c.is_alphanumeric() && !"0lIO".contains(c) -} - -pub(super) fn generate_key(desired: &str) -> Result, &'static str> where - PublicOf: PublicT, -{ - if desired.is_empty() { - return Err("Pattern must not be empty"); - } - - if !desired.chars().all(validate_base58) { - return Err("Pattern can only contains valid characters in base58 \ - (all alphanumeric except for 0, l, I and O)"); - } - - eprintln!("Generating key containing pattern '{}'", desired); - - let top = 45 + (desired.len() * 48); - let mut best = 0; - let mut seed = ::Seed::default(); - let mut done = 0; - - loop { - if done % 100000 == 0 { - OsRng.fill_bytes(seed.as_mut()); - } else { - next_seed(seed.as_mut()); - } - - let p = C::Pair::from_seed(&seed); - let ss58 = C::ss58_from_pair(&p); - let score = calculate_score(&desired, &ss58); - if score > best || desired.len() < 2 { - best = score; - let keypair = KeyPair { - pair: p, - seed: seed.clone(), - score: score, - }; - if best >= top { - eprintln!("best: {} == top: {}", best, top); - return Ok(keypair); - } - } - done += 1; - - if done % good_waypoint(done) == 0 { - eprintln!("{} keys searched; best is {}/{} complete", done, best, top); - } - } -} - -#[cfg(test)] -mod tests { - use super::super::Ed25519; - use super::*; - use sp_core::{crypto::Ss58Codec, Pair}; - #[cfg(feature = "bench")] - use test::Bencher; - - #[test] - fn test_generation_with_single_char() { - assert!(generate_key::("j") - .unwrap() - .pair - .public() - .to_ss58check() - .contains("j")); - } - - #[test] - fn test_score_1_char_100() { - let score = calculate_score("j", "5jolkadotwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim"); - assert_eq!(score, 94); - } - - #[test] - fn test_score_100() { - let score = calculate_score( - "Polkadot", - "5PolkadotwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim", - ); - assert_eq!(score, 430); - } - - #[test] - fn test_score_50_2() { - // 50% for the position + 50% for the size - assert_eq!( - calculate_score( - "Polkadot", - "5PolkXXXXwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim" - ), - 238 - ); - } - - #[test] - fn test_score_0() { - assert_eq!( - calculate_score( - "Polkadot", - "5GUWv4bLCchGUHJrzULXnh4JgXsMpTKRnjuXTY7Qo1Kh9uYK" - ), - 0 - ); - } - - #[test] - fn test_invalid_pattern() { - assert!(generate_key::("").is_err()); - assert!(generate_key::("0").is_err()); - assert!(generate_key::("l").is_err()); - assert!(generate_key::("I").is_err()); - assert!(generate_key::("O").is_err()); - assert!(generate_key::("!").is_err()); - } - - #[test] - fn test_valid_pattern() { - assert!(generate_key::("o").is_ok()); - assert!(generate_key::("L").is_ok()); - } - - #[cfg(feature = "bench")] - #[bench] - fn bench_paranoiac(b: &mut Bencher) { - b.iter(|| generate_key("polk")); - } - - #[cfg(feature = "bench")] - #[bench] - fn bench_not_paranoiac(b: &mut Bencher) { - b.iter(|| generate_key("polk")); - } -} diff --git a/client/api/Cargo.toml b/client/api/Cargo.toml index a18068b83322f289ee26ec3a0fad7ce6717aae7b..8f31e831bebac62d72c2964ea882b95e6040a1f5 100644 --- a/client/api/Cargo.toml +++ b/client/api/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-client-api" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate client interfaces." @@ -13,37 +13,37 @@ documentation = "https://docs.rs/sc-client-api" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } -derive_more = { version = "0.99.2" } -sc-executor = { version = "0.8.0-dev", path = "../executor" } -sp-externalities = { version = "0.8.0-dev", path = "../../primitives/externalities" } -fnv = { version = "1.0.6" } -futures = { version = "0.3.1" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-consensus = { version = "0.8.0-rc6", path = "../../primitives/consensus/common" } +derive_more = "0.99.2" +sc-executor = { version = "0.8.0-rc6", path = "../executor" } +sp-externalities = { version = "0.8.0-rc6", path = "../../primitives/externalities" } +fnv = "1.0.6" +futures = "0.3.1" hash-db = { version = "0.15.2", default-features = false } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -hex-literal = { version = "0.2.1" } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } -kvdb = "0.5.0" -log = { version = "0.4.8" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +hex-literal = "0.3.1" +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0-rc6", path = "../../primitives/keyring" } +kvdb = "0.7.0" +log = "0.4.8" parking_lot = "0.10.0" lazy_static = "1.4.0" -sp-database = { version = "2.0.0-dev", path = "../../primitives/database" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-version = { version = "2.0.0-dev", default-features = false, path = "../../primitives/version" } -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } -sp-trie = { version = "2.0.0-dev", path = "../../primitives/trie" } -sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../../utils/prometheus" } +sp-database = { version = "2.0.0-rc6", path = "../../primitives/database" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-version = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/version" } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } +sp-utils = { version = "2.0.0-rc6", path = "../../primitives/utils" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-rc6", path = "../telemetry" } +sp-trie = { version = "2.0.0-rc6", path = "../../primitives/trie" } +sp-storage = { version = "2.0.0-rc6", path = "../../primitives/storage" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../primitives/transaction-pool" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-rc6", path = "../../utils/prometheus" } [dev-dependencies] -kvdb-memorydb = "0.5.0" -sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } -substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } +kvdb-memorydb = "0.7.0" +sp-test-primitives = { version = "2.0.0-rc6", path = "../../primitives/test-primitives" } +substrate-test-runtime = { version = "2.0.0-rc6", path = "../../test-utils/runtime" } diff --git a/client/api/README.md b/client/api/README.md new file mode 100644 index 0000000000000000000000000000000000000000..142f5b32dd9a8de7c083aac5260ac6677042c3ad --- /dev/null +++ b/client/api/README.md @@ -0,0 +1,3 @@ +Substrate client interfaces. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/api/src/backend.rs b/client/api/src/backend.rs index 8aaeb944833908bf26149b818fd99ded46da42e4..efc5ca4ee8ca054a9944ecac2c56a84b63f812bb 100644 --- a/client/api/src/backend.rs +++ b/client/api/src/backend.rs @@ -1,23 +1,25 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate Client data backend use std::sync::Arc; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use sp_core::ChangesTrieConfigurationRange; use sp_core::offchain::{OffchainStorage,storage::OffchainOverlayedChanges}; use sp_runtime::{generic::BlockId, Justification, Storage}; @@ -65,8 +67,10 @@ pub struct ImportSummary { pub is_new_best: bool, /// Optional storage changes. pub storage_changes: Option<(StorageCollection, ChildStorageCollection)>, - /// Blocks that got retracted because of this one got imported. - pub retracted: Vec, + /// Tree route from old best to new best. + /// + /// If `None`, there was no re-org while importing. + pub tree_route: Option>, } /// Import operation wrapper @@ -414,7 +418,10 @@ pub trait Backend: AuxStore + Send + Sync { ) -> sp_blockchain::Result<()>; /// Commit block insertion. - fn commit_operation(&self, transaction: Self::BlockImportOperation) -> sp_blockchain::Result<()>; + fn commit_operation( + &self, + transaction: Self::BlockImportOperation, + ) -> sp_blockchain::Result<()>; /// Finalize block with given Id. /// @@ -445,16 +452,17 @@ pub trait Backend: AuxStore + Send + Sync { /// Returns state backend with post-state of given block. fn state_at(&self, block: BlockId) -> sp_blockchain::Result; - /// Attempts to revert the chain by `n` blocks. If `revert_finalized` is set - /// it will attempt to revert past any finalized block, this is unsafe and - /// can potentially leave the node in an inconsistent state. + /// Attempts to revert the chain by `n` blocks. If `revert_finalized` is set it will attempt to + /// revert past any finalized block, this is unsafe and can potentially leave the node in an + /// inconsistent state. /// - /// Returns the number of blocks that were successfully reverted. + /// Returns the number of blocks that were successfully reverted and the list of finalized + /// blocks that has been reverted. fn revert( &self, n: NumberFor, revert_finalized: bool, - ) -> sp_blockchain::Result>; + ) -> sp_blockchain::Result<(NumberFor, HashSet)>; /// Insert auxiliary data into key-value store. fn insert_aux< diff --git a/client/api/src/call_executor.rs b/client/api/src/call_executor.rs index 00711e83b75ac639f08246527e0aa08d0ce210e2..d9d43900dfc94f2732db7be0051401a832bf8c5b 100644 --- a/client/api/src/call_executor.rs +++ b/client/api/src/call_executor.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A method call executor interface. diff --git a/client/api/src/cht.rs b/client/api/src/cht.rs index ecf52d0bab49bd409c6e7a60fb5b117f3d684d3a..30cfd3a1b671b8f159d40bdcb499137de8fe5a69 100644 --- a/client/api/src/cht.rs +++ b/client/api/src/cht.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Canonical hash trie definitions and helper functions. //! diff --git a/client/api/src/client.rs b/client/api/src/client.rs index c855cd3a0832883c3a66b5c986871909aece048a..f97daa487638fb58fbf4812074d04c864ef9ca2e 100644 --- a/client/api/src/client.rs +++ b/client/api/src/client.rs @@ -16,7 +16,7 @@ //! A set of APIs supported by the client along with their primitives. -use std::{fmt, collections::HashSet}; +use std::{fmt, collections::HashSet, sync::Arc, convert::TryFrom}; use sp_core::storage::StorageKey; use sp_runtime::{ traits::{Block as BlockT, NumberFor}, @@ -90,6 +90,9 @@ pub trait BlockBackend { /// Get block justification set by id. fn justification(&self, id: &BlockId) -> sp_blockchain::Result>; + + /// Get block hash by number. + fn block_hash(&self, number: NumberFor) -> sp_blockchain::Result>; } /// Provide a list of potential uncle headers for a given block. @@ -234,8 +237,10 @@ pub struct BlockImportNotification { pub header: Block::Header, /// Is this the new best block. pub is_new_best: bool, - /// List of retracted blocks ordered by block number. - pub retracted: Vec, + /// Tree route from old best to new best parent. + /// + /// If `None`, there was no re-org while importing. + pub tree_route: Option>>, } /// Summary of a finalized block. @@ -246,3 +251,26 @@ pub struct FinalityNotification { /// Imported block header. pub header: Block::Header, } + +impl TryFrom> for sp_transaction_pool::ChainEvent { + type Error = (); + + fn try_from(n: BlockImportNotification) -> Result { + if n.is_new_best { + Ok(Self::NewBestBlock { + hash: n.hash, + tree_route: n.tree_route, + }) + } else { + Err(()) + } + } +} + +impl From> for sp_transaction_pool::ChainEvent { + fn from(n: FinalityNotification) -> Self { + Self::Finalized { + hash: n.hash, + } + } +} diff --git a/client/api/src/execution_extensions.rs b/client/api/src/execution_extensions.rs index 55ffc3794c4eab029461d46102dc3526a23ad266..4f2ddb77e6653a056fcfd1647cfacdf6afbbec54 100644 --- a/client/api/src/execution_extensions.rs +++ b/client/api/src/execution_extensions.rs @@ -84,6 +84,10 @@ pub struct ExecutionExtensions { keystore: Option, // FIXME: these two are only RwLock because of https://github.com/paritytech/substrate/issues/4587 // remove when fixed. + // To break retain cycle between `Client` and `TransactionPool` we require this + // extension to be a `Weak` reference. + // That's also the reason why it's being registered lazily instead of + // during initialization. transaction_pool: RwLock>>>, extensions_factory: RwLock>, } @@ -121,13 +125,10 @@ impl ExecutionExtensions { } /// Register transaction pool extension. - /// - /// To break retain cycle between `Client` and `TransactionPool` we require this - /// extension to be a `Weak` reference. - /// That's also the reason why it's being registered lazily instead of - /// during initialization. - pub fn register_transaction_pool(&self, pool: Weak>) { - *self.transaction_pool.write() = Some(pool); + pub fn register_transaction_pool(&self, pool: &Arc) + where T: sp_transaction_pool::OffchainSubmitTransaction + 'static + { + *self.transaction_pool.write() = Some(Arc::downgrade(&pool) as _); } /// Create `ExecutionManager` and `Extensions` for given offchain call. diff --git a/client/api/src/in_mem.rs b/client/api/src/in_mem.rs index d5b4800f4e421dfdf55321059c036944ca05111d..306c3c2b2f10cc8e6d121817b153b8985953ea5b 100644 --- a/client/api/src/in_mem.rs +++ b/client/api/src/in_mem.rs @@ -1,27 +1,29 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! In memory client backend -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; +use std::ptr; use std::sync::Arc; use parking_lot::RwLock; -use sp_core::storage::well_known_keys; -use sp_core::offchain::storage::{ - InMemOffchainStorage as OffchainStorage +use sp_core::{ + storage::well_known_keys, offchain::storage::InMemOffchainStorage as OffchainStorage, }; use sp_runtime::generic::BlockId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Zero, NumberFor, HashFor}; @@ -112,11 +114,17 @@ pub struct Blockchain { storage: Arc>>, } +impl Default for Blockchain { + fn default() -> Self { + Self::new() + } +} + impl Clone for Blockchain { fn clone(&self) -> Self { let storage = Arc::new(RwLock::new(self.storage.read().clone())); Blockchain { - storage: storage.clone(), + storage, } } } @@ -147,7 +155,7 @@ impl Blockchain { aux: HashMap::new(), })); Blockchain { - storage: storage.clone(), + storage, } } @@ -190,11 +198,19 @@ impl Blockchain { /// Compare this blockchain with another in-mem blockchain pub fn equals_to(&self, other: &Self) -> bool { + // Check ptr equality first to avoid double read locks. + if ptr::eq(self, other) { + return true; + } self.canon_equals_to(other) && self.storage.read().blocks == other.storage.read().blocks } /// Compare canonical chain to other canonical chain. pub fn canon_equals_to(&self, other: &Self) -> bool { + // Check ptr equality first to avoid double read locks. + if ptr::eq(self, other) { + return true; + } let this = self.storage.read(); let other = other.storage.read(); this.hashes == other.hashes @@ -330,7 +346,7 @@ impl HeaderMetadata for Blockchain { fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error> { self.header(BlockId::hash(hash))?.map(|header| CachedHeaderMetadata::from(&header)) - .ok_or(sp_blockchain::Error::UnknownBlock(format!("header not found: {}", hash))) + .ok_or_else(|| sp_blockchain::Error::UnknownBlock(format!("header not found: {}", hash))) } fn insert_header_metadata(&self, _hash: Block::Hash, _metadata: CachedHeaderMetadata) { @@ -517,13 +533,17 @@ impl backend::BlockImportOperation for BlockImportOperatio fn reset_storage(&mut self, storage: Storage) -> sp_blockchain::Result { check_genesis_storage(&storage)?; - let child_delta = storage.children_default.into_iter() + let child_delta = storage.children_default.iter() .map(|(_storage_key, child_content)| - (child_content.child_info, child_content.data.into_iter().map(|(k, v)| (k, Some(v))))); + ( + &child_content.child_info, + child_content.data.iter().map(|(k, v)| (k.as_ref(), Some(v.as_ref()))) + ) + ); let (root, transaction) = self.old_state.full_storage_root( - storage.top.into_iter().map(|(k, v)| (k, Some(v))), - child_delta + storage.top.iter().map(|(k, v)| (k.as_ref(), Some(v.as_ref()))), + child_delta, ); self.new_state = Some(transaction); @@ -626,7 +646,10 @@ impl backend::Backend for Backend where Block::Hash Ok(()) } - fn commit_operation(&self, operation: Self::BlockImportOperation) -> sp_blockchain::Result<()> { + fn commit_operation( + &self, + operation: Self::BlockImportOperation, + ) -> sp_blockchain::Result<()> { if !operation.finalized_blocks.is_empty() { for (block, justification) in operation.finalized_blocks { self.blockchain.finalize_header(block, justification)?; @@ -702,8 +725,8 @@ impl backend::Backend for Backend where Block::Hash &self, _n: NumberFor, _revert_finalized: bool, - ) -> sp_blockchain::Result> { - Ok(Zero::zero()) + ) -> sp_blockchain::Result<(NumberFor, HashSet)> { + Ok((Zero::zero(), HashSet::new())) } fn get_import_lock(&self) -> &RwLock<()> { diff --git a/client/api/src/leaves.rs b/client/api/src/leaves.rs index a555943444ad1a120ad11c3ad40433af54560e25..d10fa7ac0e565347803999d7a63a6aa2a0536fb5 100644 --- a/client/api/src/leaves.rs +++ b/client/api/src/leaves.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Helper for managing the set of available leaves in the chain for DB implementations. @@ -312,7 +314,7 @@ mod tests { let mut tx = Transaction::new(); set.prepare_transaction(&mut tx, 0, PREFIX); - db.commit(tx); + db.commit(tx).unwrap(); let set2 = LeafSet::read_from_db(&*db, 0, PREFIX).unwrap(); assert_eq!(set, set2); @@ -346,12 +348,12 @@ mod tests { let mut tx = Transaction::new(); set.prepare_transaction(&mut tx, 0, PREFIX); - db.commit(tx); + db.commit(tx).unwrap(); let _ = set.finalize_height(11); let mut tx = Transaction::new(); set.prepare_transaction(&mut tx, 0, PREFIX); - db.commit(tx); + db.commit(tx).unwrap(); assert!(set.contains(11, 11_1)); assert!(set.contains(11, 11_2)); diff --git a/client/api/src/lib.rs b/client/api/src/lib.rs index bad61f7687a63293175da3e29a4c2b21049deff4..677066936330e07b6b7b6df010fe78e4be031b6e 100644 --- a/client/api/src/lib.rs +++ b/client/api/src/lib.rs @@ -37,7 +37,7 @@ pub use light::*; pub use notifications::*; pub use proof_provider::*; -pub use sp_state_machine::{StorageProof, ExecutionStrategy, CloneableSpawn}; +pub use sp_state_machine::{StorageProof, ExecutionStrategy}; /// Usage Information Provider interface /// diff --git a/client/api/src/notifications.rs b/client/api/src/notifications.rs index 412fe8adc1e5ba1e8bc36b6e3cb7e7da8cc04619..ec63c372c7e5969b28e5dfdbd54afae0b757b1b6 100644 --- a/client/api/src/notifications.rs +++ b/client/api/src/notifications.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Storage notifications diff --git a/client/api/src/proof_provider.rs b/client/api/src/proof_provider.rs index 93160855eaebe733a3058f7373b3e78a11f5813b..5749ae0576fc38799d8c2eeb9b2aeaccd49b2bca 100644 --- a/client/api/src/proof_provider.rs +++ b/client/api/src/proof_provider.rs @@ -1,18 +1,21 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . + //! Proof utilities use sp_runtime::{ generic::BlockId, diff --git a/client/authority-discovery/Cargo.toml b/client/authority-discovery/Cargo.toml index 1a0c3d89afce7c47078e3949bb04a30990ae7170..d154b3560576133c6ac804f6f376a24374f99582 100644 --- a/client/authority-discovery/Cargo.toml +++ b/client/authority-discovery/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-authority-discovery" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate authority discovery." @@ -17,27 +17,27 @@ prost-build = "0.6.1" [dependencies] bytes = "0.5.0" -codec = { package = "parity-scale-codec", default-features = false, version = "1.3.0" } +codec = { package = "parity-scale-codec", default-features = false, version = "1.3.4" } derive_more = "0.99.2" futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.18.1", default-features = false, features = ["secp256k1", "libp2p-websocket"] } +libp2p = { version = "0.24.0", default-features = false, features = ["kad"] } log = "0.4.8" -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-dev"} +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-rc6"} prost = "0.6.1" rand = "0.7.2" -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sc-keystore = { version = "2.0.0-dev", path = "../keystore" } -sc-network = { version = "0.8.0-dev", path = "../network" } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sc-keystore = { version = "2.0.0-rc6", path = "../keystore" } +sc-network = { version = "0.8.0-rc6", path = "../network" } serde_json = "1.0.41" -sp-authority-discovery = { version = "2.0.0-dev", path = "../../primitives/authority-discovery" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } +sp-authority-discovery = { version = "2.0.0-rc6", path = "../../primitives/authority-discovery" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } [dev-dependencies] env_logger = "0.7.0" quickcheck = "0.9.0" -sc-peerset = { version = "2.0.0-dev", path = "../peerset" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client"} +sc-peerset = { version = "2.0.0-rc6", path = "../peerset" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client"} diff --git a/client/authority-discovery/README.md b/client/authority-discovery/README.md new file mode 100644 index 0000000000000000000000000000000000000000..54c51d5ba04f4c6f8a0fa7e01f4ba094737899c6 --- /dev/null +++ b/client/authority-discovery/README.md @@ -0,0 +1,9 @@ +Substrate authority discovery. + +This crate enables Substrate authorities to discover and directly connect to +other authorities. It is split into two components the [`Worker`] and the +[`Service`]. + +See [`Worker`] and [`Service`] for more documentation. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/authority-discovery/build.rs b/client/authority-discovery/build.rs index ed632575f3ba86d0d02e1edc013d15ada1d934cc..c44fe8578ba257ed178dbd2415c6738b562965b5 100644 --- a/client/authority-discovery/build.rs +++ b/client/authority-discovery/build.rs @@ -1,3 +1,3 @@ fn main() { - prost_build::compile_protos(&["src/schema/dht.proto"], &["src/schema"]).unwrap(); + prost_build::compile_protos(&["src/worker/schema/dht.proto"], &["src/worker/schema"]).unwrap(); } diff --git a/client/authority-discovery/src/addr_cache.rs b/client/authority-discovery/src/addr_cache.rs deleted file mode 100644 index 96f589c5d3c020c1dacefdb3db74a7f01c6393f1..0000000000000000000000000000000000000000 --- a/client/authority-discovery/src/addr_cache.rs +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -use rand::{rngs::StdRng, seq::SliceRandom, Rng, SeedableRng}; -use std::{ - clone::Clone, - cmp::{Eq, Ord, PartialEq}, - collections::BTreeMap, - convert::AsRef, - hash::Hash, -}; - -/// The maximum number of authority connections initialized through the authority discovery module. -/// -/// In other words the maximum size of the `authority` peer set priority group. -const MAX_NUM_AUTHORITY_CONN: usize = 10; - -/// Cache of Multiaddresses of authority nodes or their sentry nodes. -// -// The network peerset interface for priority groups lets us only set an entire group, but we -// retrieve the addresses of other authorities one by one from the network. To use the peerset -// interface we need to cache the addresses and always overwrite the entire peerset priority -// group. To ensure this map doesn't grow indefinitely `purge_old_authorities_from_cache` -// function is called each time we add a new entry. -pub(super) struct AddrCache { - cache: BTreeMap>, - - /// Random number to seed address selection RNG. - /// - /// A node should only try to connect to a subset of all authorities. To choose this subset one - /// uses randomness. The choice should differ between nodes to prevent hot spots, but not within - /// each node between each update to prevent connection churn. Thus before each selection we - /// seed an RNG with the same seed. - rand_addr_selection_seed: u64, -} - -impl AddrCache -where - Id: Clone + Eq + Hash + Ord, - Addr: Clone + PartialEq + AsRef<[u8]>, -{ - pub fn new() -> Self { - AddrCache { - cache: BTreeMap::new(), - rand_addr_selection_seed: rand::thread_rng().gen(), - } - } - - pub fn insert(&mut self, id: Id, mut addresses: Vec) { - if addresses.is_empty() { - return; - } - - addresses.sort_unstable_by(|a, b| a.as_ref().cmp(b.as_ref())); - self.cache.insert(id, addresses); - } - - // Each node should connect to a subset of all authorities. In order to prevent hot spots, this - // selection is based on randomness. Selecting randomly each time we alter the address cache - // would result in connection churn. To reduce this churn a node generates a seed on startup and - // uses this seed for a new rng on each update. (One could as well use ones peer id as a seed. - // Given that the peer id is publicly known, it would make this process predictable by others, - // which might be used as an attack.) - pub fn get_subset(&self) -> Vec { - let mut rng = StdRng::seed_from_u64(self.rand_addr_selection_seed); - - let mut addresses = self - .cache - .iter() - .map(|(_peer_id, addresses)| { - addresses - .choose(&mut rng) - .expect("an empty address vector is never inserted into the cache") - }) - .cloned() - .collect::>(); - - addresses.dedup(); - addresses.sort_unstable_by(|a, b| a.as_ref().cmp(b.as_ref())); - - addresses - .choose_multiple(&mut rng, MAX_NUM_AUTHORITY_CONN) - .cloned() - .collect() - } - - pub fn retain_ids(&mut self, ids: &Vec) { - let to_remove = self - .cache - .iter() - .filter(|(id, _addresses)| !ids.contains(id)) - .map(|entry| entry.0) - .cloned() - .collect::>(); - - for key in to_remove { - self.cache.remove(&key); - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use quickcheck::{QuickCheck, TestResult}; - - #[test] - fn returns_addresses_of_same_authorities_on_repeated_calls() { - fn property(input: Vec<(u32, Vec)>) -> TestResult { - // Expect less than 1000 authorities. - if input.len() > 1000 { - return TestResult::discard(); - } - - // Expect less than 100 addresses per authority. - for i in &input { - if i.1.len() > 100 { - return TestResult::discard(); - } - } - - let mut c = AddrCache::new(); - - for (id, addresses) in input { - c.insert(id, addresses); - } - - let result = c.get_subset(); - assert!(result.len() <= MAX_NUM_AUTHORITY_CONN); - - for _ in 1..100 { - assert_eq!(c.get_subset(), result); - } - - TestResult::passed() - } - - QuickCheck::new() - .max_tests(10) - .quickcheck(property as fn(Vec<(u32, Vec)>) -> TestResult) - } - - #[test] - fn returns_same_addresses_of_first_authority_when_second_authority_changes() { - let mut c = AddrCache::new(); - - // Insert addresses of first authority. - let addresses = (1..100) - .map(|i| format!("{:?}", i)) - .collect::>(); - c.insert(1, addresses); - let first_subset = c.get_subset(); - assert_eq!(1, first_subset.len()); - - // Insert address of second authority. - c.insert(2, vec!["a".to_string()]); - let second_subset = c.get_subset(); - assert_eq!(2, second_subset.len()); - - // Expect same address of first authority. - assert!(second_subset.contains(&first_subset[0])); - - // Alter address of second authority. - c.insert(2, vec!["b".to_string()]); - let second_subset = c.get_subset(); - assert_eq!(2, second_subset.len()); - - // Expect same address of first authority. - assert!(second_subset.contains(&first_subset[0])); - } - - #[test] - fn retains_only_entries_of_provided_ids() { - let mut cache = AddrCache::new(); - - cache.insert(1, vec![vec![10]]); - cache.insert(2, vec![vec![20]]); - cache.insert(3, vec![vec![30]]); - - cache.retain_ids(&vec![1, 3]); - - let mut subset = cache.get_subset(); - subset.sort(); - - assert_eq!(vec![vec![10], vec![30]], subset); - } -} diff --git a/client/authority-discovery/src/lib.rs b/client/authority-discovery/src/lib.rs index bc76c1433140331b07c276fe132454b476b076d5..347deb8d9fc5d99f421d70c2d99623652ef7418a 100644 --- a/client/authority-discovery/src/lib.rs +++ b/client/authority-discovery/src/lib.rs @@ -18,649 +18,61 @@ //! Substrate authority discovery. //! -//! This crate enables Substrate authorities to directly connect to other authorities. -//! [`AuthorityDiscovery`] implements the Future trait. By polling [`AuthorityDiscovery`] an -//! authority: +//! This crate enables Substrate authorities to discover and directly connect to +//! other authorities. It is split into two components the [`Worker`] and the +//! [`Service`]. //! -//! -//! 1. **Makes itself discoverable** -//! -//! 1. Retrieves its external addresses (including peer id) or the ones of its sentry nodes. -//! -//! 2. Signs the above. -//! -//! 3. Puts the signature and the addresses on the libp2p Kademlia DHT. -//! -//! -//! 2. **Discovers other authorities** -//! -//! 1. Retrieves the current set of authorities. -//! -//! 2. Starts DHT queries for the ids of the authorities. -//! -//! 3. Validates the signatures of the retrieved key value pairs. -//! -//! 4. Adds the retrieved external addresses as priority nodes to the peerset. -//! -//! When run as a sentry node, the authority discovery module does not -//! publish any addresses to the DHT but still discovers validators and -//! sentry nodes of validators, i.e. only step 2 (Discovers other authorities) -//! is executed. +//! See [`Worker`] and [`Service`] for more documentation. + +pub use crate::{service::Service, worker::{NetworkProvider, Worker, Role}}; -use std::collections::{HashMap, HashSet}; -use std::convert::TryInto; -use std::marker::PhantomData; use std::pin::Pin; use std::sync::Arc; -use std::time::{Duration, Instant}; -use futures::task::{Context, Poll}; -use futures::{Future, FutureExt, ready, Stream, StreamExt}; -use futures_timer::Delay; +use futures::channel::{mpsc, oneshot}; +use futures::Stream; -use codec::Decode; -use error::{Error, Result}; -use log::{debug, error, log_enabled}; -use prometheus_endpoint::{Counter, CounterVec, Gauge, Opts, U64, register}; -use prost::Message; use sc_client_api::blockchain::HeaderBackend; -use sc_network::{Multiaddr, config::MultiaddrWithPeerId, DhtEvent, ExHashT, NetworkStateInfo}; -use sp_authority_discovery::{AuthorityDiscoveryApi, AuthorityId, AuthoritySignature, AuthorityPair}; -use sp_core::crypto::{key_types, Pair}; -use sp_core::traits::BareCryptoStorePtr; -use sp_runtime::{traits::Block as BlockT, generic::BlockId}; +use sc_network::{config::MultiaddrWithPeerId, DhtEvent, Multiaddr, PeerId}; +use sp_authority_discovery::{AuthorityDiscoveryApi, AuthorityId}; +use sp_runtime::traits::Block as BlockT; use sp_api::ProvideRuntimeApi; -use addr_cache::AddrCache; +mod error; +mod service; #[cfg(test)] mod tests; +mod worker; -mod error; -mod addr_cache; -/// Dht payload schemas generated from Protobuf definitions via Prost crate in build.rs. -mod schema { - include!(concat!(env!("OUT_DIR"), "/authority_discovery.rs")); -} - -type Interval = Box + Unpin + Send + Sync>; - -const LOG_TARGET: &'static str = "sub-authority-discovery"; - -/// Upper bound estimation on how long one should wait before accessing the Kademlia DHT. -const LIBP2P_KADEMLIA_BOOTSTRAP_TIME: Duration = Duration::from_secs(30); - -/// Name of the Substrate peerset priority group for authorities discovered through the authority -/// discovery module. -const AUTHORITIES_PRIORITY_GROUP_NAME: &'static str = "authorities"; - -/// Role an authority discovery module can run as. -pub enum Role { - /// Actual authority as well as a reference to its key store. - Authority(BareCryptoStorePtr), - /// Sentry node that guards an authority. - /// - /// No reference to its key store needed, as sentry nodes don't have an identity to sign - /// addresses with in the first place. - Sentry, -} - -/// An `AuthorityDiscovery` makes a given authority discoverable and discovers other authorities. -pub struct AuthorityDiscovery -where - Block: BlockT + 'static, - Network: NetworkProvider, - Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, - >::Api: AuthorityDiscoveryApi, -{ +/// Create a new authority discovery [`Worker`] and [`Service`]. +pub fn new_worker_and_service( client: Arc, - network: Arc, - /// List of sentry node public addresses. - // - // There are 3 states: - // - None: No addresses were specified. - // - Some(vec![]): Addresses were specified, but none could be parsed as proper - // Multiaddresses. - // - Some(vec![a, b, c, ...]): Valid addresses were specified. - sentry_nodes: Option>, - /// Channel we receive Dht events on. + sentry_nodes: Vec, dht_event_rx: Pin + Send>>, - - /// Interval to be proactive, publishing own addresses. - publish_interval: Interval, - /// Interval on which to query for addresses of other authorities. - query_interval: Interval, - - addr_cache: addr_cache::AddrCache, - - metrics: Option, - role: Role, - - phantom: PhantomData, -} - -impl AuthorityDiscovery -where - Block: BlockT + Unpin + 'static, - Network: NetworkProvider, - Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, - >::Api: - AuthorityDiscoveryApi, - Self: Future, -{ - /// Return a new authority discovery. - /// - /// Note: When specifying `sentry_nodes` this module will not advertise the public addresses of - /// the node itself but only the public addresses of its sentry nodes. - pub fn new( - client: Arc, - network: Arc, - sentry_nodes: Vec, - dht_event_rx: Pin + Send>>, - role: Role, - prometheus_registry: Option, - ) -> Self { - // Kademlia's default time-to-live for Dht records is 36h, republishing records every 24h. - // Given that a node could restart at any point in time, one can not depend on the - // republishing process, thus publishing own external addresses should happen on an interval - // < 36h. - let publish_interval = interval_at( - Instant::now() + LIBP2P_KADEMLIA_BOOTSTRAP_TIME, - Duration::from_secs(12 * 60 * 60), - ); - - // External addresses of other authorities can change at any given point in time. The - // interval on which to query for external addresses of other authorities is a trade off - // between efficiency and performance. - let query_interval = interval_at( - Instant::now() + LIBP2P_KADEMLIA_BOOTSTRAP_TIME, - Duration::from_secs(10 * 60), - ); - - let sentry_nodes = if !sentry_nodes.is_empty() { - Some(sentry_nodes.into_iter().map(|ma| ma.concat()).collect::>()) - } else { - None - }; - - let addr_cache = AddrCache::new(); - - let metrics = match prometheus_registry { - Some(registry) => { - match Metrics::register(®istry) { - Ok(metrics) => Some(metrics), - Err(e) => { - error!(target: LOG_TARGET, "Failed to register metrics: {:?}", e); - None - }, - } - }, - None => None, - }; - - AuthorityDiscovery { - client, - network, - sentry_nodes, - dht_event_rx, - publish_interval, - query_interval, - addr_cache, - role, - metrics, - phantom: PhantomData, - } - } - - /// Publish either our own or if specified the public addresses of our sentry nodes. - fn publish_ext_addresses(&mut self) -> Result<()> { - let key_store = match &self.role { - Role::Authority(key_store) => key_store, - // Only authority nodes can put addresses (their own or the ones of their sentry nodes) - // on the Dht. Sentry nodes don't have a known identity to authenticate such addresses, - // thus `publish_ext_addresses` becomes a no-op. - Role::Sentry => return Ok(()), - }; - - if let Some(metrics) = &self.metrics { - metrics.publish.inc() - } - - let addresses: Vec<_> = match &self.sentry_nodes { - Some(addrs) => addrs.clone().into_iter() - .map(|a| a.to_vec()) - .collect(), - None => self.network.external_addresses() - .into_iter() - .map(|a| a.with(libp2p::core::multiaddr::Protocol::P2p( - self.network.local_peer_id().into(), - ))) - .map(|a| a.to_vec()) - .collect(), - }; - - if let Some(metrics) = &self.metrics { - metrics.amount_last_published.set(addresses.len() as u64); - } - - let mut serialized_addresses = vec![]; - schema::AuthorityAddresses { addresses } - .encode(&mut serialized_addresses) - .map_err(Error::EncodingProto)?; - - let keys = AuthorityDiscovery::get_own_public_keys_within_authority_set( - &key_store, - &self.client, - )?.into_iter().map(Into::into).collect::>(); - - let signatures = key_store.read() - .sign_with_all( - key_types::AUTHORITY_DISCOVERY, - keys.clone(), - serialized_addresses.as_slice(), - ) - .map_err(|_| Error::Signing)?; - - for (sign_result, key) in signatures.into_iter().zip(keys) { - let mut signed_addresses = vec![]; - - // sign_with_all returns Result signature - // is generated for a public key that is supported. - // Verify that all signatures exist for all provided keys. - let signature = sign_result.map_err(|_| Error::MissingSignature(key.clone()))?; - schema::SignedAuthorityAddresses { - addresses: serialized_addresses.clone(), - signature, - } - .encode(&mut signed_addresses) - .map_err(Error::EncodingProto)?; - - self.network.put_value( - hash_authority_id(key.1.as_ref()), - signed_addresses, - ); - } - - Ok(()) - } - - fn request_addresses_of_others(&mut self) -> Result<()> { - let id = BlockId::hash(self.client.info().best_hash); - - let authorities = self - .client - .runtime_api() - .authorities(&id) - .map_err(Error::CallingRuntime)?; - - for authority_id in authorities.iter() { - if let Some(metrics) = &self.metrics { - metrics.request.inc(); - } - - self.network - .get_value(&hash_authority_id(authority_id.as_ref())); - } - - Ok(()) - } - - /// Handle incoming Dht events. - /// - /// Returns either: - /// - Poll::Pending when there are no more events to handle or - /// - Poll::Ready(()) when the dht event stream terminated. - fn handle_dht_events(&mut self, cx: &mut Context) -> Poll<()>{ - loop { - match ready!(self.dht_event_rx.poll_next_unpin(cx)) { - Some(DhtEvent::ValueFound(v)) => { - if let Some(metrics) = &self.metrics { - metrics.dht_event_received.with_label_values(&["value_found"]).inc(); - } - - if log_enabled!(log::Level::Debug) { - let hashes = v.iter().map(|(hash, _value)| hash.clone()); - debug!( - target: LOG_TARGET, - "Value for hash '{:?}' found on Dht.", hashes, - ); - } - - if let Err(e) = self.handle_dht_value_found_event(v) { - if let Some(metrics) = &self.metrics { - metrics.handle_value_found_event_failure.inc(); - } - - debug!( - target: LOG_TARGET, - "Failed to handle Dht value found event: {:?}", e, - ); - } - } - Some(DhtEvent::ValueNotFound(hash)) => { - if let Some(metrics) = &self.metrics { - metrics.dht_event_received.with_label_values(&["value_not_found"]).inc(); - } - - debug!( - target: LOG_TARGET, - "Value for hash '{:?}' not found on Dht.", hash - ) - }, - Some(DhtEvent::ValuePut(hash)) => { - if let Some(metrics) = &self.metrics { - metrics.dht_event_received.with_label_values(&["value_put"]).inc(); - } - - debug!( - target: LOG_TARGET, - "Successfully put hash '{:?}' on Dht.", hash, - ) - }, - Some(DhtEvent::ValuePutFailed(hash)) => { - if let Some(metrics) = &self.metrics { - metrics.dht_event_received.with_label_values(&["value_put_failed"]).inc(); - } - - debug!( - target: LOG_TARGET, - "Failed to put hash '{:?}' on Dht.", hash - ) - }, - None => { - debug!(target: LOG_TARGET, "Dht event stream terminated."); - return Poll::Ready(()); - }, - } - } - } - - fn handle_dht_value_found_event( - &mut self, - values: Vec<(libp2p::kad::record::Key, Vec)>, - ) -> Result<()> { - // Ensure `values` is not empty and all its keys equal. - let remote_key = values.iter().fold(Ok(None), |acc, (key, _)| { - match acc { - Ok(None) => Ok(Some(key.clone())), - Ok(Some(ref prev_key)) if prev_key != key => Err( - Error::ReceivingDhtValueFoundEventWithDifferentKeys - ), - x @ Ok(_) => x, - Err(e) => Err(e), - } - })?.ok_or(Error::ReceivingDhtValueFoundEventWithNoRecords)?; - - let authorities = { - let block_id = BlockId::hash(self.client.info().best_hash); - // From the Dht we only get the hashed authority id. In order to retrieve the actual - // authority id and to ensure it is actually an authority, we match the hash against the - // hash of the authority id of all other authorities. - let authorities = self.client.runtime_api().authorities(&block_id)?; - self.addr_cache.retain_ids(&authorities); - authorities - .into_iter() - .map(|id| (hash_authority_id(id.as_ref()), id)) - .collect::>() - }; - - // Check if the event origins from an authority in the current authority set. - let authority_id: &AuthorityId = authorities - .get(&remote_key) - .ok_or(Error::MatchingHashedAuthorityIdWithAuthorityId)?; - - let remote_addresses: Vec = values.into_iter() - .map(|(_k, v)| { - let schema::SignedAuthorityAddresses { signature, addresses } = - schema::SignedAuthorityAddresses::decode(v.as_slice()) - .map_err(Error::DecodingProto)?; - - let signature = AuthoritySignature::decode(&mut &signature[..]) - .map_err(Error::EncodingDecodingScale)?; - - if !AuthorityPair::verify(&signature, &addresses, authority_id) { - return Err(Error::VerifyingDhtPayload); - } - - let addresses = schema::AuthorityAddresses::decode(addresses.as_slice()) - .map(|a| a.addresses) - .map_err(Error::DecodingProto)? - .into_iter() - .map(|a| a.try_into()) - .collect::>() - .map_err(Error::ParsingMultiaddress)?; - - Ok(addresses) - }) - .collect::>>>()? - .into_iter().flatten().collect(); - - if !remote_addresses.is_empty() { - self.addr_cache.insert(authority_id.clone(), remote_addresses); - self.update_peer_set_priority_group()?; - } - - Ok(()) - } - - /// Retrieve our public keys within the current authority set. - // - // A node might have multiple authority discovery keys within its keystore, e.g. an old one and - // one for the upcoming session. In addition it could be participating in the current authority - // set with two keys. The function does not return all of the local authority discovery public - // keys, but only the ones intersecting with the current authority set. - fn get_own_public_keys_within_authority_set( - key_store: &BareCryptoStorePtr, - client: &Client, - ) -> Result> { - let local_pub_keys = key_store.read() - .sr25519_public_keys(key_types::AUTHORITY_DISCOVERY) - .into_iter() - .collect::>(); - - let id = BlockId::hash(client.info().best_hash); - let current_authorities = client.runtime_api() - .authorities(&id) - .map_err(Error::CallingRuntime)? - .into_iter() - .map(std::convert::Into::into) - .collect::>(); - - let intersection = local_pub_keys.intersection(¤t_authorities) - .cloned() - .map(std::convert::Into::into) - .collect(); - - Ok(intersection) - } - - /// Update the peer set 'authority' priority group. - fn update_peer_set_priority_group(&self) -> Result<()> { - let addresses = self.addr_cache.get_subset(); - - if let Some(metrics) = &self.metrics { - metrics.priority_group_size.set(addresses.len().try_into().unwrap_or(std::u64::MAX)); - } - - debug!( - target: LOG_TARGET, - "Applying priority group {:?} to peerset.", addresses, - ); - self.network - .set_priority_group( - AUTHORITIES_PRIORITY_GROUP_NAME.to_string(), - addresses.into_iter().collect(), - ) - .map_err(Error::SettingPeersetPriorityGroup)?; - - Ok(()) - } -} - -impl Future for AuthorityDiscovery + prometheus_registry: Option, +) -> (Worker, Service) where Block: BlockT + Unpin + 'static, Network: NetworkProvider, Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, - >::Api: - AuthorityDiscoveryApi, + >::Api: AuthorityDiscoveryApi, { - type Output = (); - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { - // Process incoming events. - if let Poll::Ready(()) = self.handle_dht_events(cx) { - // `handle_dht_events` returns `Poll::Ready(())` when the Dht event stream terminated. - // Termination of the Dht event stream implies that the underlying network terminated, - // thus authority discovery should terminate as well. - return Poll::Ready(()); - } - - - // Publish own addresses. - if let Poll::Ready(_) = self.publish_interval.poll_next_unpin(cx) { - // Register waker of underlying task for next interval. - while let Poll::Ready(_) = self.publish_interval.poll_next_unpin(cx) {} - - if let Err(e) = self.publish_ext_addresses() { - error!( - target: LOG_TARGET, - "Failed to publish external addresses: {:?}", e, - ); - } - } - - // Request addresses of authorities. - if let Poll::Ready(_) = self.query_interval.poll_next_unpin(cx) { - // Register waker of underlying task for next interval. - while let Poll::Ready(_) = self.query_interval.poll_next_unpin(cx) {} - - if let Err(e) = self.request_addresses_of_others() { - error!( - target: LOG_TARGET, - "Failed to request addresses of authorities: {:?}", e, - ); - } - } - - Poll::Pending - } -} + let (to_worker, from_service) = mpsc::channel(0); -/// NetworkProvider provides AuthorityDiscovery with all necessary hooks into the underlying -/// Substrate networking. Using this trait abstraction instead of NetworkService directly is -/// necessary to unit test AuthorityDiscovery. -pub trait NetworkProvider: NetworkStateInfo { - /// Modify a peerset priority group. - fn set_priority_group( - &self, - group_id: String, - peers: HashSet, - ) -> std::result::Result<(), String>; - - /// Start putting a value in the Dht. - fn put_value(&self, key: libp2p::kad::record::Key, value: Vec); - - /// Start getting a value from the Dht. - fn get_value(&self, key: &libp2p::kad::record::Key); -} - -impl NetworkProvider for sc_network::NetworkService -where - B: BlockT + 'static, - H: ExHashT, -{ - fn set_priority_group( - &self, - group_id: String, - peers: HashSet, - ) -> std::result::Result<(), String> { - self.set_priority_group(group_id, peers) - } - fn put_value(&self, key: libp2p::kad::record::Key, value: Vec) { - self.put_value(key, value) - } - fn get_value(&self, key: &libp2p::kad::record::Key) { - self.get_value(key) - } -} - -fn hash_authority_id(id: &[u8]) -> libp2p::kad::record::Key { - libp2p::kad::record::Key::new(&libp2p::multihash::Sha2_256::digest(id)) -} - -fn interval_at(start: Instant, duration: Duration) -> Interval { - let stream = futures::stream::unfold(start, move |next| { - let time_until_next = next.saturating_duration_since(Instant::now()); - - Delay::new(time_until_next).map(move |_| Some(((), next + duration))) - }); - - Box::new(stream) -} + let worker = Worker::new( + from_service, client, network, sentry_nodes, dht_event_rx, role, prometheus_registry, + ); + let service = Service::new(to_worker); -/// Prometheus metrics for an `AuthorityDiscovery`. -#[derive(Clone)] -pub(crate) struct Metrics { - publish: Counter, - amount_last_published: Gauge, - request: Counter, - dht_event_received: CounterVec, - handle_value_found_event_failure: Counter, - priority_group_size: Gauge, + (worker, service) } -impl Metrics { - pub(crate) fn register(registry: &prometheus_endpoint::Registry) -> Result { - Ok(Self { - publish: register( - Counter::new( - "authority_discovery_times_published_total", - "Number of times authority discovery has published external addresses." - )?, - registry, - )?, - amount_last_published: register( - Gauge::new( - "authority_discovery_amount_external_addresses_last_published", - "Number of external addresses published when authority discovery last \ - published addresses." - )?, - registry, - )?, - request: register( - Counter::new( - "authority_discovery_authority_addresses_requested_total", - "Number of times authority discovery has requested external addresses of a \ - single authority." - )?, - registry, - )?, - dht_event_received: register( - CounterVec::new( - Opts::new( - "authority_discovery_dht_event_received", - "Number of dht events received by authority discovery." - ), - &["name"], - )?, - registry, - )?, - handle_value_found_event_failure: register( - Counter::new( - "authority_discovery_handle_value_found_event_failure", - "Number of times handling a dht value found event failed." - )?, - registry, - )?, - priority_group_size: register( - Gauge::new( - "authority_discovery_priority_group_size", - "Number of addresses passed to the peer set as a priority group." - )?, - registry, - )?, - }) - } +/// Message send from the [`Service`] to the [`Worker`]. +pub(crate) enum ServicetoWorkerMsg { + /// See [`Service::get_addresses_by_authority_id`]. + GetAddressesByAuthorityId(AuthorityId, oneshot::Sender>>), + /// See [`Service::get_authority_id_by_peer_id`]. + GetAuthorityIdByPeerId(PeerId, oneshot::Sender>) } diff --git a/client/authority-discovery/src/service.rs b/client/authority-discovery/src/service.rs new file mode 100644 index 0000000000000000000000000000000000000000..01fb7134fb5d1b6958b13e464fa60e4a2b622331 --- /dev/null +++ b/client/authority-discovery/src/service.rs @@ -0,0 +1,70 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use crate::ServicetoWorkerMsg; + +use futures::channel::{mpsc, oneshot}; +use futures::SinkExt; + +use sc_network::{Multiaddr, PeerId}; +use sp_authority_discovery::AuthorityId; + +/// Service to interact with the [`Worker`]. +#[derive(Clone)] +pub struct Service { + to_worker: mpsc::Sender, +} + +/// A [`Service`] allows to interact with a [`Worker`], e.g. by querying the +/// [`Worker`]'s local address cache for a given [`AuthorityId`]. +impl Service { + pub(crate) fn new(to_worker: mpsc::Sender) -> Self { + Self { + to_worker, + } + } + + /// Get the addresses for the given [`AuthorityId`] from the local address cache. + /// + /// Returns `None` if no entry was present or connection to the [`crate::Worker`] failed. + /// + /// [`Multiaddr`]s returned always include a [`libp2p::core::multiaddr:Protocol::P2p`] + /// component. + pub async fn get_addresses_by_authority_id(&mut self, authority: AuthorityId) -> Option> { + let (tx, rx) = oneshot::channel(); + + self.to_worker + .send(ServicetoWorkerMsg::GetAddressesByAuthorityId(authority, tx)) + .await + .ok()?; + + rx.await.ok().flatten() + } + + /// Get the [`AuthorityId`] for the given [`PeerId`] from the local address cache. + /// + /// Returns `None` if no entry was present or connection to the [`crate::Worker`] failed. + pub async fn get_authority_id_by_peer_id(&mut self, peer_id: PeerId) -> Option { + let (tx, rx) = oneshot::channel(); + + self.to_worker + .send(ServicetoWorkerMsg::GetAuthorityIdByPeerId(peer_id, tx)) + .await + .ok()?; + + rx.await.ok().flatten() + } +} diff --git a/client/authority-discovery/src/tests.rs b/client/authority-discovery/src/tests.rs index c13bca894c60bfca4e67c7a97f49d056c7721e86..8e7367f2f78857089ff4b21c5bcd4f81099921f8 100644 --- a/client/authority-discovery/src/tests.rs +++ b/client/authority-discovery/src/tests.rs @@ -1,328 +1,57 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . + +use crate::{new_worker_and_service, worker::{tests::{TestApi, TestNetwork}, Role}}; -use std::{iter::FromIterator, sync::{Arc, Mutex}}; +use std::sync::Arc; +use futures::prelude::*; use futures::channel::mpsc::channel; -use futures::executor::{block_on, LocalPool}; -use futures::future::{poll_fn, FutureExt}; -use futures::sink::SinkExt; +use futures::executor::LocalPool; use futures::task::LocalSpawn; -use futures::poll; -use libp2p::{kad, PeerId}; +use libp2p::core::{multiaddr::{Multiaddr, Protocol}, PeerId}; -use sp_api::{ProvideRuntimeApi, ApiRef}; +use sp_authority_discovery::AuthorityId; +use sp_core::crypto::key_types; use sp_core::testing::KeyStore; -use sp_runtime::traits::{Zero, Block as BlockT, NumberFor}; -use substrate_test_runtime_client::runtime::Block; - -use super::*; - -#[test] -fn interval_at_with_start_now() { - let start = Instant::now(); - - let mut interval = interval_at( - std::time::Instant::now(), - std::time::Duration::from_secs(10), - ); - - futures::executor::block_on(async { - interval.next().await; - }); - - assert!( - Instant::now().saturating_duration_since(start) < Duration::from_secs(1), - "Expected low resolution instant interval to fire within less than a second.", - ); -} - -#[test] -fn interval_at_is_queuing_ticks() { - let start = Instant::now(); - - let interval = interval_at(start, std::time::Duration::from_millis(100)); - - // Let's wait for 200ms, thus 3 elements should be queued up (1st at 0ms, 2nd at 100ms, 3rd - // at 200ms). - std::thread::sleep(Duration::from_millis(200)); - - futures::executor::block_on(async { - interval.take(3).collect::>().await; - }); - - // Make sure we did not wait for more than 300 ms, which would imply that `at_interval` is - // not queuing ticks. - assert!( - Instant::now().saturating_duration_since(start) < Duration::from_millis(300), - "Expect interval to /queue/ events when not polled for a while.", - ); -} - -#[test] -fn interval_at_with_initial_delay() { - let start = Instant::now(); - - let mut interval = interval_at( - std::time::Instant::now() + Duration::from_millis(100), - std::time::Duration::from_secs(10), - ); - - futures::executor::block_on(async { - interval.next().await; - }); - - assert!( - Instant::now().saturating_duration_since(start) > Duration::from_millis(100), - "Expected interval with initial delay not to fire right away.", - ); -} - -#[derive(Clone)] -struct TestApi { - authorities: Vec, -} - -impl ProvideRuntimeApi for TestApi { - type Api = RuntimeApi; - - fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api> { - RuntimeApi { - authorities: self.authorities.clone(), - }.into() - } -} - -/// Blockchain database header backend. Does not perform any validation. -impl HeaderBackend for TestApi { - fn header( - &self, - _id: BlockId, - ) -> std::result::Result, sp_blockchain::Error> { - Ok(None) - } - - fn info(&self) -> sc_client_api::blockchain::Info { - sc_client_api::blockchain::Info { - best_hash: Default::default(), - best_number: Zero::zero(), - finalized_hash: Default::default(), - finalized_number: Zero::zero(), - genesis_hash: Default::default(), - number_leaves: Default::default(), - } - } - - fn status( - &self, - _id: BlockId, - ) -> std::result::Result { - Ok(sc_client_api::blockchain::BlockStatus::Unknown) - } - - fn number( - &self, - _hash: Block::Hash, - ) -> std::result::Result>, sp_blockchain::Error> { - Ok(None) - } - - fn hash( - &self, - _number: NumberFor, - ) -> std::result::Result, sp_blockchain::Error> { - Ok(None) - } -} - -struct RuntimeApi { - authorities: Vec, -} - -sp_api::mock_impl_runtime_apis! { - impl AuthorityDiscoveryApi for RuntimeApi { - type Error = sp_blockchain::Error; - - fn authorities(&self) -> Vec { - self.authorities.clone() - } - } -} - -struct TestNetwork { - peer_id: PeerId, - // Whenever functions on `TestNetwork` are called, the function arguments are added to the - // vectors below. - pub put_value_call: Arc)>>>, - pub get_value_call: Arc>>, - pub set_priority_group_call: Arc)>>>, -} - -impl Default for TestNetwork { - fn default() -> Self { - TestNetwork { - peer_id: PeerId::random(), - put_value_call: Default::default(), - get_value_call: Default::default(), - set_priority_group_call: Default::default(), - } - } -} - -impl NetworkProvider for TestNetwork { - fn set_priority_group( - &self, - group_id: String, - peers: HashSet, - ) -> std::result::Result<(), String> { - self.set_priority_group_call - .lock() - .unwrap() - .push((group_id, peers)); - Ok(()) - } - fn put_value(&self, key: kad::record::Key, value: Vec) { - self.put_value_call.lock().unwrap().push((key, value)); - } - fn get_value(&self, key: &kad::record::Key) { - self.get_value_call.lock().unwrap().push(key.clone()); - } -} - -impl NetworkStateInfo for TestNetwork { - fn local_peer_id(&self) -> PeerId { - self.peer_id.clone() - } - - fn external_addresses(&self) -> Vec { - vec!["/ip6/2001:db8::".parse().unwrap()] - } -} #[test] -fn new_registers_metrics() { - let (_dht_event_tx, dht_event_rx) = channel(1000); +fn get_addresses_and_authority_id() { + let (_dht_event_tx, dht_event_rx) = channel(0); let network: Arc = Arc::new(Default::default()); - let key_store = KeyStore::new(); - let test_api = Arc::new(TestApi { - authorities: vec![], - }); - - let registry = prometheus_endpoint::Registry::new(); - AuthorityDiscovery::new( - test_api, - network.clone(), - vec![], - dht_event_rx.boxed(), - Role::Authority(key_store), - Some(registry.clone()), - ); - - assert!(registry.gather().len() > 0); -} - -#[test] -fn request_addresses_of_others_triggers_dht_get_query() { - let _ = ::env_logger::try_init(); - let (_dht_event_tx, dht_event_rx) = channel(1000); - - // Generate authority keys - let authority_1_key_pair = AuthorityPair::from_seed_slice(&[1; 32]).unwrap(); - let authority_2_key_pair = AuthorityPair::from_seed_slice(&[2; 32]).unwrap(); - - let test_api = Arc::new(TestApi { - authorities: vec![authority_1_key_pair.public(), authority_2_key_pair.public()], - }); - - let network: Arc = Arc::new(Default::default()); let key_store = KeyStore::new(); - - let mut authority_discovery = AuthorityDiscovery::new( - test_api, - network.clone(), - vec![], - dht_event_rx.boxed(), - Role::Authority(key_store), - None, - ); - - authority_discovery.request_addresses_of_others().unwrap(); - - // Expect authority discovery to request new records from the dht. - assert_eq!(network.get_value_call.lock().unwrap().len(), 2); -} - -#[test] -fn publish_discover_cycle() { - let _ = ::env_logger::try_init(); - - // Node A publishing its address. - - let (_dht_event_tx, dht_event_rx) = channel(1000); - - let network: Arc = Arc::new(Default::default()); - let node_a_multiaddr = { - let peer_id = network.local_peer_id(); - let address = network.external_addresses().pop().unwrap(); - - address.with(libp2p::core::multiaddr::Protocol::P2p( - peer_id.into(), - )) - }; - - let key_store = KeyStore::new(); - let node_a_public = key_store + let remote_authority_id: AuthorityId = key_store .write() .sr25519_generate_new(key_types::AUTHORITY_DISCOVERY, None) - .unwrap(); - let test_api = Arc::new(TestApi { - authorities: vec![node_a_public.into()], - }); - - let mut authority_discovery = AuthorityDiscovery::new( - test_api, - network.clone(), - vec![], - dht_event_rx.boxed(), - Role::Authority(key_store), - None, - ); - - authority_discovery.publish_ext_addresses().unwrap(); - - // Expect authority discovery to put a new record onto the dht. - assert_eq!(network.put_value_call.lock().unwrap().len(), 1); + .unwrap() + .into(); - let dht_event = { - let (key, value) = network.put_value_call.lock().unwrap().pop().unwrap(); - sc_network::DhtEvent::ValueFound(vec![(key, value)]) - }; + let remote_peer_id = PeerId::random(); + let remote_addr = "/ip6/2001:db8:0:0:0:0:0:2/tcp/30333".parse::() + .unwrap() + .with(Protocol::P2p(remote_peer_id.clone().into())); - // Node B discovering node A's address. - - let (mut dht_event_tx, dht_event_rx) = channel(1000); let test_api = Arc::new(TestApi { - // Make sure node B identifies node A as an authority. - authorities: vec![node_a_public.into()], + authorities: vec![], }); - let network: Arc = Arc::new(Default::default()); - let key_store = KeyStore::new(); - let mut authority_discovery = AuthorityDiscovery::new( + let (mut worker, mut service) = new_worker_and_service( test_api, network.clone(), vec![], @@ -331,131 +60,19 @@ fn publish_discover_cycle() { None, ); - dht_event_tx.try_send(dht_event).unwrap(); - - let f = |cx: &mut Context<'_>| -> Poll<()> { - // Make authority discovery handle the event. - if let Poll::Ready(e) = authority_discovery.handle_dht_events(cx) { - panic!("Unexpected error: {:?}", e); - } + worker.inject_addresses(remote_authority_id.clone(), vec![remote_addr.clone()]); - // Expect authority discovery to set the priority set. - assert_eq!(network.set_priority_group_call.lock().unwrap().len(), 1); + let mut pool = LocalPool::new(); + pool.spawner().spawn_local_obj(Box::pin(worker).into()).unwrap(); + pool.run_until(async { assert_eq!( - network.set_priority_group_call.lock().unwrap()[0], - ( - "authorities".to_string(), - HashSet::from_iter(vec![node_a_multiaddr.clone()].into_iter()) - ) + Some(vec![remote_addr]), + service.get_addresses_by_authority_id(remote_authority_id.clone()).await, ); - - Poll::Ready(()) - }; - - let _ = block_on(poll_fn(f)); -} - -#[test] -fn terminate_when_event_stream_terminates() { - let (dht_event_tx, dht_event_rx) = channel(1000); - let network: Arc = Arc::new(Default::default()); - let key_store = KeyStore::new(); - let test_api = Arc::new(TestApi { - authorities: vec![], - }); - - let mut authority_discovery = AuthorityDiscovery::new( - test_api, - network.clone(), - vec![], - dht_event_rx.boxed(), - Role::Authority(key_store), - None, - ); - - block_on(async { - assert_eq!(Poll::Pending, poll!(&mut authority_discovery)); - - // Simulate termination of the network through dropping the sender side of the dht event - // channel. - drop(dht_event_tx); - assert_eq!( - Poll::Ready(()), poll!(&mut authority_discovery), - "Expect the authority discovery module to terminate once the sending side of the dht \ - event channel is terminated.", + Some(remote_authority_id), + service.get_authority_id_by_peer_id(remote_peer_id).await, ); }); } - -#[test] -fn dont_stop_polling_when_error_is_returned() { - #[derive(PartialEq, Debug)] - enum Event { - Processed, - End, - }; - - let (mut dht_event_tx, dht_event_rx) = channel(1000); - let (mut discovery_update_tx, mut discovery_update_rx) = channel(1000); - let network: Arc = Arc::new(Default::default()); - let key_store = KeyStore::new(); - let test_api = Arc::new(TestApi { - authorities: vec![], - }); - let mut pool = LocalPool::new(); - - let mut authority_discovery = AuthorityDiscovery::new( - test_api, - network.clone(), - vec![], - dht_event_rx.boxed(), - Role::Authority(key_store), - None, - ); - - // Spawn the authority discovery to make sure it is polled independently. - // - // As this is a local pool, only one future at a time will have the CPU and - // can make progress until the future returns `Pending`. - pool.spawner().spawn_local_obj( - futures::future::poll_fn(move |ctx| { - match std::pin::Pin::new(&mut authority_discovery).poll(ctx) { - Poll::Ready(()) => {}, - Poll::Pending => { - discovery_update_tx.send(Event::Processed).now_or_never(); - return Poll::Pending; - }, - } - let _ = discovery_update_tx.send(Event::End).now_or_never().unwrap(); - Poll::Ready(()) - }).boxed_local().into(), - ).expect("Spawns authority discovery"); - - pool.run_until( - // The future that drives the event stream - async { - // Send an event that should generate an error - let _ = dht_event_tx.send(DhtEvent::ValueFound(Default::default())).now_or_never(); - // Send the same event again to make sure that the event stream needs to be polled twice - // to be woken up again. - let _ = dht_event_tx.send(DhtEvent::ValueFound(Default::default())).now_or_never(); - - // Now we call `await` and give the control to the authority discovery future. - assert_eq!(Some(Event::Processed), discovery_update_rx.next().await); - - // Drop the event rx to stop the authority discovery. If it was polled correctly, it - // should end properly. - drop(dht_event_tx); - - assert!( - discovery_update_rx.collect::>() - .await - .into_iter() - .any(|evt| evt == Event::End), - "The authority discovery should have ended", - ); - } - ); -} diff --git a/client/authority-discovery/src/worker.rs b/client/authority-discovery/src/worker.rs new file mode 100644 index 0000000000000000000000000000000000000000..16f19489f94b73047920e0a5592cbe5b5afb300e --- /dev/null +++ b/client/authority-discovery/src/worker.rs @@ -0,0 +1,785 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use crate::{error::{Error, Result}, ServicetoWorkerMsg}; + +use std::collections::{HashMap, HashSet}; +use std::convert::TryInto; +use std::marker::PhantomData; +use std::pin::Pin; +use std::sync::Arc; +use std::time::{Duration, Instant}; + +use futures::channel::mpsc; +use futures::task::{Context, Poll}; +use futures::{Future, FutureExt, ready, Stream, StreamExt, stream::Fuse}; +use futures_timer::Delay; + +use addr_cache::AddrCache; +use codec::Decode; +use libp2p::core::multiaddr; +use log::{debug, error, log_enabled}; +use prometheus_endpoint::{Counter, CounterVec, Gauge, Opts, U64, register}; +use prost::Message; +use sc_client_api::blockchain::HeaderBackend; +use sc_network::{ + config::MultiaddrWithPeerId, + DhtEvent, + ExHashT, + Multiaddr, + NetworkStateInfo, + PeerId, +}; +use sp_authority_discovery::{AuthorityDiscoveryApi, AuthorityId, AuthoritySignature, AuthorityPair}; +use sp_core::crypto::{key_types, Pair}; +use sp_core::traits::BareCryptoStorePtr; +use sp_runtime::{traits::Block as BlockT, generic::BlockId}; +use sp_api::ProvideRuntimeApi; + +mod addr_cache; +/// Dht payload schemas generated from Protobuf definitions via Prost crate in build.rs. +mod schema { include!(concat!(env!("OUT_DIR"), "/authority_discovery.rs")); } +#[cfg(test)] +pub mod tests; + +type Interval = Box + Unpin + Send + Sync>; + +const LOG_TARGET: &'static str = "sub-authority-discovery"; + +/// Upper bound estimation on how long one should wait before accessing the Kademlia DHT. +const LIBP2P_KADEMLIA_BOOTSTRAP_TIME: Duration = Duration::from_secs(30); + +/// Name of the Substrate peerset priority group for authorities discovered through the authority +/// discovery module. +const AUTHORITIES_PRIORITY_GROUP_NAME: &'static str = "authorities"; + +/// Role an authority discovery module can run as. +pub enum Role { + /// Actual authority as well as a reference to its key store. + Authority(BareCryptoStorePtr), + /// Sentry node that guards an authority. + /// + /// No reference to its key store needed, as sentry nodes don't have an identity to sign + /// addresses with in the first place. + Sentry, +} + +/// A [`Worker`] makes a given authority discoverable and discovers other +/// authorities. +/// +/// The [`Worker`] implements the Future trait. By +/// polling [`Worker`] an authority: +/// +/// 1. **Makes itself discoverable** +/// +/// 1. Retrieves its external addresses (including peer id) or the ones of +/// its sentry nodes. +/// +/// 2. Signs the above. +/// +/// 3. Puts the signature and the addresses on the libp2p Kademlia DHT. +/// +/// +/// 2. **Discovers other authorities** +/// +/// 1. Retrieves the current set of authorities. +/// +/// 2. Starts DHT queries for the ids of the authorities. +/// +/// 3. Validates the signatures of the retrieved key value pairs. +/// +/// 4. Adds the retrieved external addresses as priority nodes to the +/// peerset. +/// +/// When run as a sentry node, the [`Worker`] does not publish +/// any addresses to the DHT but still discovers validators and sentry nodes of +/// validators, i.e. only step 2 (Discovers other authorities) is executed. +pub struct Worker +where + Block: BlockT + 'static, + Network: NetworkProvider, + Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, + >::Api: AuthorityDiscoveryApi, +{ + /// Channel receiver for messages send by an [`Service`]. + from_service: Fuse>, + + client: Arc, + + network: Arc, + /// List of sentry node public addresses. + // + // There are 3 states: + // - None: No addresses were specified. + // - Some(vec![]): Addresses were specified, but none could be parsed as proper + // Multiaddresses. + // - Some(vec![a, b, c, ...]): Valid addresses were specified. + sentry_nodes: Option>, + /// Channel we receive Dht events on. + dht_event_rx: Pin + Send>>, + + /// Interval to be proactive, publishing own addresses. + publish_interval: Interval, + /// Interval on which to query for addresses of other authorities. + query_interval: Interval, + /// Interval on which to set the peerset priority group to a new random + /// set of addresses. + priority_group_set_interval: Interval, + + addr_cache: addr_cache::AddrCache, + + metrics: Option, + + role: Role, + + phantom: PhantomData, +} + +impl Worker +where + Block: BlockT + Unpin + 'static, + Network: NetworkProvider, + Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, + >::Api: + AuthorityDiscoveryApi, + Self: Future, +{ + /// Return a new [`Worker`]. + /// + /// Note: When specifying `sentry_nodes` this module will not advertise the public addresses of + /// the node itself but only the public addresses of its sentry nodes. + pub(crate) fn new( + from_service: mpsc::Receiver, + client: Arc, + network: Arc, + sentry_nodes: Vec, + dht_event_rx: Pin + Send>>, + role: Role, + prometheus_registry: Option, + ) -> Self { + // Kademlia's default time-to-live for Dht records is 36h, republishing records every 24h. + // Given that a node could restart at any point in time, one can not depend on the + // republishing process, thus publishing own external addresses should happen on an interval + // < 36h. + let publish_interval = interval_at( + Instant::now() + LIBP2P_KADEMLIA_BOOTSTRAP_TIME, + Duration::from_secs(12 * 60 * 60), + ); + + // External addresses of other authorities can change at any given point in time. The + // interval on which to query for external addresses of other authorities is a trade off + // between efficiency and performance. + let query_interval_start = Instant::now() + LIBP2P_KADEMLIA_BOOTSTRAP_TIME; + let query_interval_duration = Duration::from_secs(10 * 60); + let query_interval = interval_at(query_interval_start, query_interval_duration); + + // Querying 500 [`AuthorityId`]s takes ~1m on the Kusama DHT (10th of August 2020) when + // comparing `authority_discovery_authority_addresses_requested_total` and + // `authority_discovery_dht_event_received`. With that in mind set the peerset priority + // group on the same interval as the [`query_interval`] above, just delayed by 2 minutes. + let priority_group_set_interval = interval_at( + query_interval_start + Duration::from_secs(2 * 60), + query_interval_duration, + ); + + let sentry_nodes = if !sentry_nodes.is_empty() { + Some(sentry_nodes.into_iter().map(|ma| ma.concat()).collect::>()) + } else { + None + }; + + let addr_cache = AddrCache::new(); + + let metrics = match prometheus_registry { + Some(registry) => { + match Metrics::register(®istry) { + Ok(metrics) => Some(metrics), + Err(e) => { + error!(target: LOG_TARGET, "Failed to register metrics: {:?}", e); + None + }, + } + }, + None => None, + }; + + Worker { + from_service: from_service.fuse(), + client, + network, + sentry_nodes, + dht_event_rx, + publish_interval, + query_interval, + priority_group_set_interval, + addr_cache, + role, + metrics, + phantom: PhantomData, + } + } + + /// Publish either our own or if specified the public addresses of our sentry nodes. + fn publish_ext_addresses(&mut self) -> Result<()> { + let key_store = match &self.role { + Role::Authority(key_store) => key_store, + // Only authority nodes can put addresses (their own or the ones of their sentry nodes) + // on the Dht. Sentry nodes don't have a known identity to authenticate such addresses, + // thus `publish_ext_addresses` becomes a no-op. + Role::Sentry => return Ok(()), + }; + + if let Some(metrics) = &self.metrics { + metrics.publish.inc() + } + + let addresses: Vec<_> = match &self.sentry_nodes { + Some(addrs) => addrs.clone().into_iter() + .map(|a| a.to_vec()) + .collect(), + None => self.network.external_addresses() + .into_iter() + .map(|a| a.with(multiaddr::Protocol::P2p( + self.network.local_peer_id().into(), + ))) + .map(|a| a.to_vec()) + .collect(), + }; + + if let Some(metrics) = &self.metrics { + metrics.amount_last_published.set(addresses.len() as u64); + } + + let mut serialized_addresses = vec![]; + schema::AuthorityAddresses { addresses } + .encode(&mut serialized_addresses) + .map_err(Error::EncodingProto)?; + + let keys = Worker::get_own_public_keys_within_authority_set( + &key_store, + &self.client, + )?.into_iter().map(Into::into).collect::>(); + + let signatures = key_store.read() + .sign_with_all( + key_types::AUTHORITY_DISCOVERY, + keys.clone(), + serialized_addresses.as_slice(), + ) + .map_err(|_| Error::Signing)?; + + for (sign_result, key) in signatures.into_iter().zip(keys) { + let mut signed_addresses = vec![]; + + // sign_with_all returns Result signature + // is generated for a public key that is supported. + // Verify that all signatures exist for all provided keys. + let signature = sign_result.map_err(|_| Error::MissingSignature(key.clone()))?; + schema::SignedAuthorityAddresses { + addresses: serialized_addresses.clone(), + signature, + } + .encode(&mut signed_addresses) + .map_err(Error::EncodingProto)?; + + self.network.put_value( + hash_authority_id(key.1.as_ref()), + signed_addresses, + ); + } + + Ok(()) + } + + fn request_addresses_of_others(&mut self) -> Result<()> { + let id = BlockId::hash(self.client.info().best_hash); + + let authorities = self + .client + .runtime_api() + .authorities(&id) + .map_err(Error::CallingRuntime)?; + + let local_keys = match &self.role { + Role::Authority(key_store) => { + key_store.read() + .sr25519_public_keys(key_types::AUTHORITY_DISCOVERY) + .into_iter() + .collect::>() + }, + Role::Sentry => HashSet::new(), + }; + + for authority_id in authorities.iter() { + // Make sure we don't look up our own keys. + if !local_keys.contains(authority_id.as_ref()) { + if let Some(metrics) = &self.metrics { + metrics.request.inc(); + } + + self.network + .get_value(&hash_authority_id(authority_id.as_ref())); + } + } + + Ok(()) + } + + /// Handle incoming Dht events. + /// + /// Returns either: + /// - Poll::Pending when there are no more events to handle or + /// - Poll::Ready(()) when the dht event stream terminated. + fn handle_dht_events(&mut self, cx: &mut Context) -> Poll<()>{ + loop { + match ready!(self.dht_event_rx.poll_next_unpin(cx)) { + Some(DhtEvent::ValueFound(v)) => { + if let Some(metrics) = &self.metrics { + metrics.dht_event_received.with_label_values(&["value_found"]).inc(); + } + + if log_enabled!(log::Level::Debug) { + let hashes = v.iter().map(|(hash, _value)| hash.clone()); + debug!( + target: LOG_TARGET, + "Value for hash '{:?}' found on Dht.", hashes, + ); + } + + if let Err(e) = self.handle_dht_value_found_event(v) { + if let Some(metrics) = &self.metrics { + metrics.handle_value_found_event_failure.inc(); + } + + debug!( + target: LOG_TARGET, + "Failed to handle Dht value found event: {:?}", e, + ); + } + } + Some(DhtEvent::ValueNotFound(hash)) => { + if let Some(metrics) = &self.metrics { + metrics.dht_event_received.with_label_values(&["value_not_found"]).inc(); + } + + debug!( + target: LOG_TARGET, + "Value for hash '{:?}' not found on Dht.", hash + ) + }, + Some(DhtEvent::ValuePut(hash)) => { + if let Some(metrics) = &self.metrics { + metrics.dht_event_received.with_label_values(&["value_put"]).inc(); + } + + debug!( + target: LOG_TARGET, + "Successfully put hash '{:?}' on Dht.", hash, + ) + }, + Some(DhtEvent::ValuePutFailed(hash)) => { + if let Some(metrics) = &self.metrics { + metrics.dht_event_received.with_label_values(&["value_put_failed"]).inc(); + } + + debug!( + target: LOG_TARGET, + "Failed to put hash '{:?}' on Dht.", hash + ) + }, + None => { + debug!(target: LOG_TARGET, "Dht event stream terminated."); + return Poll::Ready(()); + }, + } + } + } + + fn handle_dht_value_found_event( + &mut self, + values: Vec<(libp2p::kad::record::Key, Vec)>, + ) -> Result<()> { + // Ensure `values` is not empty and all its keys equal. + let remote_key = values.iter().fold(Ok(None), |acc, (key, _)| { + match acc { + Ok(None) => Ok(Some(key.clone())), + Ok(Some(ref prev_key)) if prev_key != key => Err( + Error::ReceivingDhtValueFoundEventWithDifferentKeys + ), + x @ Ok(_) => x, + Err(e) => Err(e), + } + })?.ok_or(Error::ReceivingDhtValueFoundEventWithNoRecords)?; + + let authorities = { + let block_id = BlockId::hash(self.client.info().best_hash); + // From the Dht we only get the hashed authority id. In order to retrieve the actual + // authority id and to ensure it is actually an authority, we match the hash against the + // hash of the authority id of all other authorities. + let authorities = self.client.runtime_api().authorities(&block_id)?; + self.addr_cache.retain_ids(&authorities); + authorities + .into_iter() + .map(|id| (hash_authority_id(id.as_ref()), id)) + .collect::>() + }; + + // Check if the event origins from an authority in the current authority set. + let authority_id: &AuthorityId = authorities + .get(&remote_key) + .ok_or(Error::MatchingHashedAuthorityIdWithAuthorityId)?; + + let local_peer_id = self.network.local_peer_id(); + + let remote_addresses: Vec = values.into_iter() + .map(|(_k, v)| { + let schema::SignedAuthorityAddresses { signature, addresses } = + schema::SignedAuthorityAddresses::decode(v.as_slice()) + .map_err(Error::DecodingProto)?; + + let signature = AuthoritySignature::decode(&mut &signature[..]) + .map_err(Error::EncodingDecodingScale)?; + + if !AuthorityPair::verify(&signature, &addresses, authority_id) { + return Err(Error::VerifyingDhtPayload); + } + + let addresses = schema::AuthorityAddresses::decode(addresses.as_slice()) + .map(|a| a.addresses) + .map_err(Error::DecodingProto)? + .into_iter() + .map(|a| a.try_into()) + .collect::>() + .map_err(Error::ParsingMultiaddress)?; + + Ok(addresses) + }) + .collect::>>>()? + .into_iter() + .flatten() + // Ignore [`Multiaddr`]s without [`PeerId`] and own addresses. + .filter(|addr| addr.iter().any(|protocol| { + // Parse to PeerId first as Multihashes of old and new PeerId + // representation don't equal. + // + // See https://github.com/libp2p/rust-libp2p/issues/555 for + // details. + if let multiaddr::Protocol::P2p(hash) = protocol { + let peer_id = match PeerId::from_multihash(hash) { + Ok(peer_id) => peer_id, + Err(_) => return false, // Discard address. + }; + + // Discard if equal to local peer id, keep if it differs. + return !(peer_id == local_peer_id); + } + + false // `protocol` is not a [`Protocol::P2p`], let's keep looking. + })) + .collect(); + + if !remote_addresses.is_empty() { + self.addr_cache.insert(authority_id.clone(), remote_addresses); + if let Some(metrics) = &self.metrics { + metrics.known_authorities_count.set( + self.addr_cache.num_ids().try_into().unwrap_or(std::u64::MAX) + ); + } + } + + Ok(()) + } + + /// Retrieve our public keys within the current authority set. + // + // A node might have multiple authority discovery keys within its keystore, e.g. an old one and + // one for the upcoming session. In addition it could be participating in the current authority + // set with two keys. The function does not return all of the local authority discovery public + // keys, but only the ones intersecting with the current authority set. + fn get_own_public_keys_within_authority_set( + key_store: &BareCryptoStorePtr, + client: &Client, + ) -> Result> { + let local_pub_keys = key_store.read() + .sr25519_public_keys(key_types::AUTHORITY_DISCOVERY) + .into_iter() + .collect::>(); + + let id = BlockId::hash(client.info().best_hash); + let current_authorities = client.runtime_api() + .authorities(&id) + .map_err(Error::CallingRuntime)? + .into_iter() + .map(std::convert::Into::into) + .collect::>(); + + let intersection = local_pub_keys.intersection(¤t_authorities) + .cloned() + .map(std::convert::Into::into) + .collect(); + + Ok(intersection) + } + + /// Set the peer set 'authority' priority group to a new random set of + /// [`Multiaddr`]s. + fn set_priority_group(&self) -> Result<()> { + let addresses = self.addr_cache.get_random_subset(); + + if addresses.is_empty() { + debug!( + target: LOG_TARGET, + "Got no addresses in cache for peerset priority group.", + ); + return Ok(()); + } + + if let Some(metrics) = &self.metrics { + metrics.priority_group_size.set(addresses.len().try_into().unwrap_or(std::u64::MAX)); + } + + debug!( + target: LOG_TARGET, + "Applying priority group {:?} to peerset.", addresses, + ); + + self.network + .set_priority_group( + AUTHORITIES_PRIORITY_GROUP_NAME.to_string(), + addresses.into_iter().collect(), + ) + .map_err(Error::SettingPeersetPriorityGroup)?; + + Ok(()) + } +} + +impl Future for Worker +where + Block: BlockT + Unpin + 'static, + Network: NetworkProvider, + Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, + >::Api: + AuthorityDiscoveryApi, +{ + type Output = (); + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { + // Process incoming events. + if let Poll::Ready(()) = self.handle_dht_events(cx) { + // `handle_dht_events` returns `Poll::Ready(())` when the Dht event stream terminated. + // Termination of the Dht event stream implies that the underlying network terminated, + // thus authority discovery should terminate as well. + return Poll::Ready(()); + } + + // Publish own addresses. + if let Poll::Ready(_) = self.publish_interval.poll_next_unpin(cx) { + // Register waker of underlying task for next interval. + while let Poll::Ready(_) = self.publish_interval.poll_next_unpin(cx) {} + + if let Err(e) = self.publish_ext_addresses() { + error!( + target: LOG_TARGET, + "Failed to publish external addresses: {:?}", e, + ); + } + } + + // Request addresses of authorities. + if let Poll::Ready(_) = self.query_interval.poll_next_unpin(cx) { + // Register waker of underlying task for next interval. + while let Poll::Ready(_) = self.query_interval.poll_next_unpin(cx) {} + + if let Err(e) = self.request_addresses_of_others() { + error!( + target: LOG_TARGET, + "Failed to request addresses of authorities: {:?}", e, + ); + } + } + + // Set peerset priority group to a new random set of addresses. + if let Poll::Ready(_) = self.priority_group_set_interval.poll_next_unpin(cx) { + // Register waker of underlying task for next interval. + while let Poll::Ready(_) = self.priority_group_set_interval.poll_next_unpin(cx) {} + + if let Err(e) = self.set_priority_group() { + error!( + target: LOG_TARGET, + "Failed to set priority group: {:?}", e, + ); + } + } + + // Handle messages from [`Service`]. + while let Poll::Ready(Some(msg)) = self.from_service.poll_next_unpin(cx) { + match msg { + ServicetoWorkerMsg::GetAddressesByAuthorityId(authority, sender) => { + let _ = sender.send( + self.addr_cache.get_addresses_by_authority_id(&authority).map(Clone::clone), + ); + } + ServicetoWorkerMsg::GetAuthorityIdByPeerId(peer_id, sender) => { + let _ = sender.send( + self.addr_cache.get_authority_id_by_peer_id(&peer_id).map(Clone::clone), + ); + } + } + } + + Poll::Pending + } +} + +/// NetworkProvider provides [`Worker`] with all necessary hooks into the +/// underlying Substrate networking. Using this trait abstraction instead of [`NetworkService`] +/// directly is necessary to unit test [`Worker`]. +pub trait NetworkProvider: NetworkStateInfo { + /// Modify a peerset priority group. + fn set_priority_group( + &self, + group_id: String, + peers: HashSet, + ) -> std::result::Result<(), String>; + + /// Start putting a value in the Dht. + fn put_value(&self, key: libp2p::kad::record::Key, value: Vec); + + /// Start getting a value from the Dht. + fn get_value(&self, key: &libp2p::kad::record::Key); +} + +impl NetworkProvider for sc_network::NetworkService +where + B: BlockT + 'static, + H: ExHashT, +{ + fn set_priority_group( + &self, + group_id: String, + peers: HashSet, + ) -> std::result::Result<(), String> { + self.set_priority_group(group_id, peers) + } + fn put_value(&self, key: libp2p::kad::record::Key, value: Vec) { + self.put_value(key, value) + } + fn get_value(&self, key: &libp2p::kad::record::Key) { + self.get_value(key) + } +} + +fn hash_authority_id(id: &[u8]) -> libp2p::kad::record::Key { + libp2p::kad::record::Key::new(&libp2p::multihash::Sha2_256::digest(id)) +} + +fn interval_at(start: Instant, duration: Duration) -> Interval { + let stream = futures::stream::unfold(start, move |next| { + let time_until_next = next.saturating_duration_since(Instant::now()); + + Delay::new(time_until_next).map(move |_| Some(((), next + duration))) + }); + + Box::new(stream) +} + +/// Prometheus metrics for a [`Worker`]. +#[derive(Clone)] +pub(crate) struct Metrics { + publish: Counter, + amount_last_published: Gauge, + request: Counter, + dht_event_received: CounterVec, + handle_value_found_event_failure: Counter, + known_authorities_count: Gauge, + priority_group_size: Gauge, +} + +impl Metrics { + pub(crate) fn register(registry: &prometheus_endpoint::Registry) -> Result { + Ok(Self { + publish: register( + Counter::new( + "authority_discovery_times_published_total", + "Number of times authority discovery has published external addresses." + )?, + registry, + )?, + amount_last_published: register( + Gauge::new( + "authority_discovery_amount_external_addresses_last_published", + "Number of external addresses published when authority discovery last \ + published addresses." + )?, + registry, + )?, + request: register( + Counter::new( + "authority_discovery_authority_addresses_requested_total", + "Number of times authority discovery has requested external addresses of a \ + single authority." + )?, + registry, + )?, + dht_event_received: register( + CounterVec::new( + Opts::new( + "authority_discovery_dht_event_received", + "Number of dht events received by authority discovery." + ), + &["name"], + )?, + registry, + )?, + handle_value_found_event_failure: register( + Counter::new( + "authority_discovery_handle_value_found_event_failure", + "Number of times handling a dht value found event failed." + )?, + registry, + )?, + known_authorities_count: register( + Gauge::new( + "authority_discovery_known_authorities_count", + "Number of authorities known by authority discovery." + )?, + registry, + )?, + priority_group_size: register( + Gauge::new( + "authority_discovery_priority_group_size", + "Number of addresses passed to the peer set as a priority group." + )?, + registry, + )?, + }) + } +} + +// Helper functions for unit testing. +#[cfg(test)] +impl Worker +where + Block: BlockT + 'static, + Network: NetworkProvider, + Client: ProvideRuntimeApi + Send + Sync + 'static + HeaderBackend, + >::Api: AuthorityDiscoveryApi, +{ + pub(crate) fn inject_addresses(&mut self, authority: AuthorityId, addresses: Vec) { + self.addr_cache.insert(authority, addresses); + } +} diff --git a/client/authority-discovery/src/worker/addr_cache.rs b/client/authority-discovery/src/worker/addr_cache.rs new file mode 100644 index 0000000000000000000000000000000000000000..a2cd3f33e92154668f1fc27dff7e13b286a74ce3 --- /dev/null +++ b/client/authority-discovery/src/worker/addr_cache.rs @@ -0,0 +1,233 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use libp2p::core::multiaddr::{Multiaddr, Protocol}; +use rand::seq::SliceRandom; +use std::collections::HashMap; + +use sp_authority_discovery::AuthorityId; +use sc_network::PeerId; + +/// The maximum number of authority connections initialized through the authority discovery module. +/// +/// In other words the maximum size of the `authority` peerset priority group. +const MAX_NUM_AUTHORITY_CONN: usize = 10; + +/// Cache for [`AuthorityId`] -> [`Vec`] and [`PeerId`] -> [`AuthorityId`] mappings. +pub(super) struct AddrCache { + authority_id_to_addresses: HashMap>, + peer_id_to_authority_id: HashMap, +} + +impl AddrCache { + pub fn new() -> Self { + AddrCache { + authority_id_to_addresses: HashMap::new(), + peer_id_to_authority_id: HashMap::new(), + } + } + + /// Inserts the given [`AuthorityId`] and [`Vec`] pair for future lookups by + /// [`AuthorityId`] or [`PeerId`]. + pub fn insert(&mut self, authority_id: AuthorityId, mut addresses: Vec) { + if addresses.is_empty() { + return; + } + + // Insert into `self.peer_id_to_authority_id`. + let peer_ids = addresses.iter() + .map(|a| peer_id_from_multiaddr(a)) + .filter_map(|peer_id| peer_id); + for peer_id in peer_ids { + self.peer_id_to_authority_id.insert(peer_id, authority_id.clone()); + } + + // Insert into `self.authority_id_to_addresses`. + addresses.sort_unstable_by(|a, b| a.as_ref().cmp(b.as_ref())); + self.authority_id_to_addresses.insert(authority_id, addresses); + } + + /// Returns the number of authority IDs in the cache. + pub fn num_ids(&self) -> usize { + self.authority_id_to_addresses.len() + } + + /// Returns the addresses for the given [`AuthorityId`]. + pub fn get_addresses_by_authority_id(&self, authority_id: &AuthorityId) -> Option<&Vec> { + self.authority_id_to_addresses.get(&authority_id) + } + + /// Returns the [`AuthorityId`] for the given [`PeerId`]. + pub fn get_authority_id_by_peer_id(&self, peer_id: &PeerId) -> Option<&AuthorityId> { + self.peer_id_to_authority_id.get(peer_id) + } + + /// Returns a single address for a random subset (maximum of [`MAX_NUM_AUTHORITY_CONN`]) of all + /// known authorities. + pub fn get_random_subset(&self) -> Vec { + let mut rng = rand::thread_rng(); + + let mut addresses = self + .authority_id_to_addresses + .iter() + .filter_map(|(_authority_id, addresses)| { + debug_assert!(!addresses.is_empty()); + addresses + .choose(&mut rng) + }) + .collect::>(); + + addresses.sort_unstable_by(|a, b| a.as_ref().cmp(b.as_ref())); + addresses.dedup(); + + addresses + .choose_multiple(&mut rng, MAX_NUM_AUTHORITY_CONN) + .map(|a| (**a).clone()) + .collect() + } + + /// Removes all [`PeerId`]s and [`Multiaddr`]s from the cache that are not related to the given + /// [`AuthorityId`]s. + pub fn retain_ids(&mut self, authority_ids: &Vec) { + // The below logic could be replaced by `BtreeMap::drain_filter` once it stabilized. + let authority_ids_to_remove = self.authority_id_to_addresses.iter() + .filter(|(id, _addresses)| !authority_ids.contains(id)) + .map(|entry| entry.0) + .cloned() + .collect::>(); + + for authority_id_to_remove in authority_ids_to_remove { + // Remove other entries from `self.authority_id_to_addresses`. + let addresses = self.authority_id_to_addresses.remove(&authority_id_to_remove); + + // Remove other entries from `self.peer_id_to_authority_id`. + let peer_ids = addresses.iter() + .flatten() + .map(|a| peer_id_from_multiaddr(a)) + .filter_map(|peer_id| peer_id); + for peer_id in peer_ids { + if let Some(id) = self.peer_id_to_authority_id.remove(&peer_id) { + debug_assert_eq!(authority_id_to_remove, id); + } + } + } + } +} + +fn peer_id_from_multiaddr(addr: &Multiaddr) -> Option { + addr.iter().last().and_then(|protocol| if let Protocol::P2p(multihash) = protocol { + PeerId::from_multihash(multihash).ok() + } else { + None + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + use libp2p::multihash; + use quickcheck::{Arbitrary, Gen, QuickCheck, TestResult}; + use rand::Rng; + + use sp_authority_discovery::{AuthorityId, AuthorityPair}; + use sp_core::crypto::Pair; + + #[derive(Clone, Debug)] + struct TestAuthorityId(AuthorityId); + + impl Arbitrary for TestAuthorityId { + fn arbitrary(g: &mut G) -> Self { + let seed: [u8; 32] = g.gen(); + TestAuthorityId(AuthorityPair::from_seed_slice(&seed).unwrap().public()) + } + } + + #[derive(Clone, Debug)] + struct TestMultiaddr(Multiaddr); + + impl Arbitrary for TestMultiaddr { + fn arbitrary(g: &mut G) -> Self { + let seed: [u8; 32] = g.gen(); + let peer_id = PeerId::from_multihash( + multihash::wrap(multihash::Code::Sha2_256, &seed) + ).unwrap(); + let multiaddr = "/ip6/2001:db8:0:0:0:0:0:2/tcp/30333".parse::() + .unwrap() + .with(Protocol::P2p(peer_id.into())); + + TestMultiaddr(multiaddr) + } + } + + #[test] + fn retains_only_entries_of_provided_authority_ids() { + fn property( + first: (TestAuthorityId, TestMultiaddr), + second: (TestAuthorityId, TestMultiaddr), + third: (TestAuthorityId, TestMultiaddr), + ) -> TestResult { + let first: (AuthorityId, Multiaddr) = ((first.0).0, (first.1).0); + let second: (AuthorityId, Multiaddr) = ((second.0).0, (second.1).0); + let third: (AuthorityId, Multiaddr) = ((third.0).0, (third.1).0); + + let mut cache = AddrCache::new(); + + cache.insert(first.0.clone(), vec![first.1.clone()]); + cache.insert(second.0.clone(), vec![second.1.clone()]); + cache.insert(third.0.clone(), vec![third.1.clone()]); + + let subset = cache.get_random_subset(); + assert!( + subset.contains(&first.1) && subset.contains(&second.1) && subset.contains(&third.1), + "Expect initial subset to contain all authorities.", + ); + assert_eq!( + Some(&vec![third.1.clone()]), + cache.get_addresses_by_authority_id(&third.0), + "Expect `get_addresses_by_authority_id` to return addresses of third authority." + ); + assert_eq!( + Some(&third.0), + cache.get_authority_id_by_peer_id(&peer_id_from_multiaddr(&third.1).unwrap()), + "Expect `get_authority_id_by_peer_id` to return `AuthorityId` of third authority." + ); + + cache.retain_ids(&vec![first.0, second.0]); + + let subset = cache.get_random_subset(); + assert!( + subset.contains(&first.1) || subset.contains(&second.1), + "Expected both first and second authority." + ); + assert!(!subset.contains(&third.1), "Did not expect address from third authority"); + assert_eq!( + None, cache.get_addresses_by_authority_id(&third.0), + "Expect `get_addresses_by_authority_id` to not return `None` for third authority." + ); + assert_eq!( + None, cache.get_authority_id_by_peer_id(&peer_id_from_multiaddr(&third.1).unwrap()), + "Expect `get_authority_id_by_peer_id` to return `None` for third authority." + ); + + TestResult::passed() + } + + QuickCheck::new() + .max_tests(10) + .quickcheck(property as fn(_, _, _) -> TestResult) + } +} diff --git a/client/authority-discovery/src/schema/dht.proto b/client/authority-discovery/src/worker/schema/dht.proto similarity index 100% rename from client/authority-discovery/src/schema/dht.proto rename to client/authority-discovery/src/worker/schema/dht.proto diff --git a/client/authority-discovery/src/worker/tests.rs b/client/authority-discovery/src/worker/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..68aadca7a7f30ebe62d71095b766d303a17566ef --- /dev/null +++ b/client/authority-discovery/src/worker/tests.rs @@ -0,0 +1,693 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use crate::worker::schema; + +use std::{iter::FromIterator, sync::{Arc, Mutex}}; + +use futures::channel::mpsc::channel; +use futures::executor::{block_on, LocalPool}; +use futures::future::{poll_fn, FutureExt}; +use futures::sink::SinkExt; +use futures::task::LocalSpawn; +use futures::poll; +use libp2p::{kad, core::multiaddr, PeerId}; + +use sp_api::{ProvideRuntimeApi, ApiRef}; +use sp_core::{crypto::Public, testing::KeyStore}; +use sp_runtime::traits::{Zero, Block as BlockT, NumberFor}; +use substrate_test_runtime_client::runtime::Block; + +use super::*; + +#[test] +fn interval_at_with_start_now() { + let start = Instant::now(); + + let mut interval = interval_at( + std::time::Instant::now(), + std::time::Duration::from_secs(10), + ); + + futures::executor::block_on(async { + interval.next().await; + }); + + assert!( + Instant::now().saturating_duration_since(start) < Duration::from_secs(1), + "Expected low resolution instant interval to fire within less than a second.", + ); +} + +#[test] +fn interval_at_is_queuing_ticks() { + let start = Instant::now(); + + let interval = interval_at(start, std::time::Duration::from_millis(100)); + + // Let's wait for 200ms, thus 3 elements should be queued up (1st at 0ms, 2nd at 100ms, 3rd + // at 200ms). + std::thread::sleep(Duration::from_millis(200)); + + futures::executor::block_on(async { + interval.take(3).collect::>().await; + }); + + // Make sure we did not wait for more than 300 ms, which would imply that `at_interval` is + // not queuing ticks. + assert!( + Instant::now().saturating_duration_since(start) < Duration::from_millis(300), + "Expect interval to /queue/ events when not polled for a while.", + ); +} + +#[test] +fn interval_at_with_initial_delay() { + let start = Instant::now(); + + let mut interval = interval_at( + std::time::Instant::now() + Duration::from_millis(100), + std::time::Duration::from_secs(10), + ); + + futures::executor::block_on(async { + interval.next().await; + }); + + assert!( + Instant::now().saturating_duration_since(start) > Duration::from_millis(100), + "Expected interval with initial delay not to fire right away.", + ); +} + +#[derive(Clone)] +pub(crate) struct TestApi { + pub(crate) authorities: Vec, +} + +impl ProvideRuntimeApi for TestApi { + type Api = RuntimeApi; + + fn runtime_api<'a>(&'a self) -> ApiRef<'a, Self::Api> { + RuntimeApi { + authorities: self.authorities.clone(), + }.into() + } +} + +/// Blockchain database header backend. Does not perform any validation. +impl HeaderBackend for TestApi { + fn header( + &self, + _id: BlockId, + ) -> std::result::Result, sp_blockchain::Error> { + Ok(None) + } + + fn info(&self) -> sc_client_api::blockchain::Info { + sc_client_api::blockchain::Info { + best_hash: Default::default(), + best_number: Zero::zero(), + finalized_hash: Default::default(), + finalized_number: Zero::zero(), + genesis_hash: Default::default(), + number_leaves: Default::default(), + } + } + + fn status( + &self, + _id: BlockId, + ) -> std::result::Result { + Ok(sc_client_api::blockchain::BlockStatus::Unknown) + } + + fn number( + &self, + _hash: Block::Hash, + ) -> std::result::Result>, sp_blockchain::Error> { + Ok(None) + } + + fn hash( + &self, + _number: NumberFor, + ) -> std::result::Result, sp_blockchain::Error> { + Ok(None) + } +} + +pub(crate) struct RuntimeApi { + authorities: Vec, +} + +sp_api::mock_impl_runtime_apis! { + impl AuthorityDiscoveryApi for RuntimeApi { + type Error = sp_blockchain::Error; + + fn authorities(&self) -> Vec { + self.authorities.clone() + } + } +} + +pub struct TestNetwork { + peer_id: PeerId, + // Whenever functions on `TestNetwork` are called, the function arguments are added to the + // vectors below. + pub put_value_call: Arc)>>>, + pub get_value_call: Arc>>, + pub set_priority_group_call: Arc)>>>, +} + +impl Default for TestNetwork { + fn default() -> Self { + TestNetwork { + peer_id: PeerId::random(), + put_value_call: Default::default(), + get_value_call: Default::default(), + set_priority_group_call: Default::default(), + } + } +} + +impl NetworkProvider for TestNetwork { + fn set_priority_group( + &self, + group_id: String, + peers: HashSet, + ) -> std::result::Result<(), String> { + self.set_priority_group_call + .lock() + .unwrap() + .push((group_id, peers)); + Ok(()) + } + fn put_value(&self, key: kad::record::Key, value: Vec) { + self.put_value_call.lock().unwrap().push((key, value)); + } + fn get_value(&self, key: &kad::record::Key) { + self.get_value_call.lock().unwrap().push(key.clone()); + } +} + +impl NetworkStateInfo for TestNetwork { + fn local_peer_id(&self) -> PeerId { + self.peer_id.clone() + } + + fn external_addresses(&self) -> Vec { + vec!["/ip6/2001:db8::/tcp/30333".parse().unwrap()] + } +} + +#[test] +fn new_registers_metrics() { + let (_dht_event_tx, dht_event_rx) = channel(1000); + let network: Arc = Arc::new(Default::default()); + let key_store = KeyStore::new(); + let test_api = Arc::new(TestApi { + authorities: vec![], + }); + + let registry = prometheus_endpoint::Registry::new(); + + let (_to_worker, from_service) = mpsc::channel(0); + Worker::new( + from_service, + test_api, + network.clone(), + vec![], + dht_event_rx.boxed(), + Role::Authority(key_store), + Some(registry.clone()), + ); + + assert!(registry.gather().len() > 0); +} + +#[test] +fn request_addresses_of_others_triggers_dht_get_query() { + let _ = ::env_logger::try_init(); + let (_dht_event_tx, dht_event_rx) = channel(1000); + + // Generate authority keys + let authority_1_key_pair = AuthorityPair::from_seed_slice(&[1; 32]).unwrap(); + let authority_2_key_pair = AuthorityPair::from_seed_slice(&[2; 32]).unwrap(); + + let test_api = Arc::new(TestApi { + authorities: vec![authority_1_key_pair.public(), authority_2_key_pair.public()], + }); + + let network: Arc = Arc::new(Default::default()); + let key_store = KeyStore::new(); + + + let (_to_worker, from_service) = mpsc::channel(0); + let mut worker = Worker::new( + from_service, + test_api, + network.clone(), + vec![], + dht_event_rx.boxed(), + Role::Authority(key_store), + None, + ); + + worker.request_addresses_of_others().unwrap(); + + // Expect authority discovery to request new records from the dht. + assert_eq!(network.get_value_call.lock().unwrap().len(), 2); +} + +#[test] +fn publish_discover_cycle() { + let _ = ::env_logger::try_init(); + + // Node A publishing its address. + + let (_dht_event_tx, dht_event_rx) = channel(1000); + + let network: Arc = Arc::new(Default::default()); + let node_a_multiaddr = { + let peer_id = network.local_peer_id(); + let address = network.external_addresses().pop().unwrap(); + + address.with(multiaddr::Protocol::P2p( + peer_id.into(), + )) + }; + + let key_store = KeyStore::new(); + let node_a_public = key_store + .write() + .sr25519_generate_new(key_types::AUTHORITY_DISCOVERY, None) + .unwrap(); + let test_api = Arc::new(TestApi { + authorities: vec![node_a_public.into()], + }); + + let (_to_worker, from_service) = mpsc::channel(0); + let mut worker = Worker::new( + from_service, + test_api, + network.clone(), + vec![], + dht_event_rx.boxed(), + Role::Authority(key_store), + None, + ); + + worker.publish_ext_addresses().unwrap(); + + // Expect authority discovery to put a new record onto the dht. + assert_eq!(network.put_value_call.lock().unwrap().len(), 1); + + let dht_event = { + let (key, value) = network.put_value_call.lock().unwrap().pop().unwrap(); + sc_network::DhtEvent::ValueFound(vec![(key, value)]) + }; + + // Node B discovering node A's address. + + let (mut dht_event_tx, dht_event_rx) = channel(1000); + let test_api = Arc::new(TestApi { + // Make sure node B identifies node A as an authority. + authorities: vec![node_a_public.into()], + }); + let network: Arc = Arc::new(Default::default()); + let key_store = KeyStore::new(); + + let (_to_worker, from_service) = mpsc::channel(0); + let mut worker = Worker::new( + from_service, + test_api, + network.clone(), + vec![], + dht_event_rx.boxed(), + Role::Authority(key_store), + None, + ); + + dht_event_tx.try_send(dht_event).unwrap(); + + let f = |cx: &mut Context<'_>| -> Poll<()> { + // Make authority discovery handle the event. + if let Poll::Ready(e) = worker.handle_dht_events(cx) { + panic!("Unexpected error: {:?}", e); + } + worker.set_priority_group().unwrap(); + + // Expect authority discovery to set the priority set. + assert_eq!(network.set_priority_group_call.lock().unwrap().len(), 1); + + assert_eq!( + network.set_priority_group_call.lock().unwrap()[0], + ( + "authorities".to_string(), + HashSet::from_iter(vec![node_a_multiaddr.clone()].into_iter()) + ) + ); + + Poll::Ready(()) + }; + + let _ = block_on(poll_fn(f)); +} + +#[test] +fn terminate_when_event_stream_terminates() { + let (dht_event_tx, dht_event_rx) = channel(1000); + let network: Arc = Arc::new(Default::default()); + let key_store = KeyStore::new(); + let test_api = Arc::new(TestApi { + authorities: vec![], + }); + + let (_to_worker, from_service) = mpsc::channel(0); + let mut worker = Worker::new( + from_service, + test_api, + network.clone(), + vec![], + dht_event_rx.boxed(), + Role::Authority(key_store), + None, + ); + + block_on(async { + assert_eq!(Poll::Pending, poll!(&mut worker)); + + // Simulate termination of the network through dropping the sender side of the dht event + // channel. + drop(dht_event_tx); + + assert_eq!( + Poll::Ready(()), poll!(&mut worker), + "Expect the authority discovery module to terminate once the sending side of the dht \ + event channel is terminated.", + ); + }); +} + +#[test] +fn continue_operating_when_service_channel_is_dropped() { + let (_dht_event_tx, dht_event_rx) = channel(0); + let network: Arc = Arc::new(Default::default()); + let key_store = KeyStore::new(); + let test_api = Arc::new(TestApi { + authorities: vec![], + }); + + let (to_worker, from_service) = mpsc::channel(0); + let mut worker = Worker::new( + from_service, + test_api, + network.clone(), + vec![], + dht_event_rx.boxed(), + Role::Authority(key_store), + None, + ); + + block_on(async { + assert_eq!(Poll::Pending, poll!(&mut worker)); + + drop(to_worker); + + for _ in 0..100 { + assert_eq!( + Poll::Pending, poll!(&mut worker), + "Expect authority discovery `Worker` not to panic when service channel is dropped.", + ); + } + }); +} + +#[test] +fn dont_stop_polling_when_error_is_returned() { + #[derive(PartialEq, Debug)] + enum Event { + Processed, + End, + }; + + let (mut dht_event_tx, dht_event_rx) = channel(1000); + let (mut discovery_update_tx, mut discovery_update_rx) = channel(1000); + let network: Arc = Arc::new(Default::default()); + let key_store = KeyStore::new(); + let test_api = Arc::new(TestApi { + authorities: vec![], + }); + let mut pool = LocalPool::new(); + + let (_to_worker, from_service) = mpsc::channel(0); + let mut worker = Worker::new( + from_service, + test_api, + network.clone(), + vec![], + dht_event_rx.boxed(), + Role::Authority(key_store), + None, + ); + + // Spawn the authority discovery to make sure it is polled independently. + // + // As this is a local pool, only one future at a time will have the CPU and + // can make progress until the future returns `Pending`. + pool.spawner().spawn_local_obj( + futures::future::poll_fn(move |ctx| { + match std::pin::Pin::new(&mut worker).poll(ctx) { + Poll::Ready(()) => {}, + Poll::Pending => { + discovery_update_tx.send(Event::Processed).now_or_never(); + return Poll::Pending; + }, + } + let _ = discovery_update_tx.send(Event::End).now_or_never().unwrap(); + Poll::Ready(()) + }).boxed_local().into(), + ).expect("Spawns authority discovery"); + + pool.run_until( + // The future that drives the event stream + async { + // Send an event that should generate an error + let _ = dht_event_tx.send(DhtEvent::ValueFound(Default::default())).now_or_never(); + // Send the same event again to make sure that the event stream needs to be polled twice + // to be woken up again. + let _ = dht_event_tx.send(DhtEvent::ValueFound(Default::default())).now_or_never(); + + // Now we call `await` and give the control to the authority discovery future. + assert_eq!(Some(Event::Processed), discovery_update_rx.next().await); + + // Drop the event rx to stop the authority discovery. If it was polled correctly, it + // should end properly. + drop(dht_event_tx); + + assert!( + discovery_update_rx.collect::>() + .await + .into_iter() + .any(|evt| evt == Event::End), + "The authority discovery should have ended", + ); + } + ); +} + +/// In the scenario of a validator publishing the address of its sentry node to +/// the DHT, said sentry node should not add its own Multiaddr to the +/// peerset "authority" priority group. +#[test] +fn never_add_own_address_to_priority_group() { + let validator_key_store = KeyStore::new(); + let validator_public = validator_key_store + .write() + .sr25519_generate_new(key_types::AUTHORITY_DISCOVERY, None) + .unwrap(); + + let sentry_network: Arc = Arc::new(Default::default()); + + let sentry_multiaddr = { + let peer_id = sentry_network.local_peer_id(); + let address: Multiaddr = "/ip6/2001:db8:0:0:0:0:0:2/tcp/30333".parse().unwrap(); + + address.with(multiaddr::Protocol::P2p(peer_id.into())) + }; + + // Address of some other sentry node of `validator`. + let random_multiaddr = { + let peer_id = PeerId::random(); + let address: Multiaddr = "/ip6/2001:db8:0:0:0:0:0:1/tcp/30333".parse().unwrap(); + + address.with(multiaddr::Protocol::P2p( + peer_id.into(), + )) + }; + + let dht_event = { + let addresses = vec![ + sentry_multiaddr.to_vec(), + random_multiaddr.to_vec(), + ]; + + let mut serialized_addresses = vec![]; + schema::AuthorityAddresses { addresses } + .encode(&mut serialized_addresses) + .map_err(Error::EncodingProto) + .unwrap(); + + let signature = validator_key_store.read() + .sign_with( + key_types::AUTHORITY_DISCOVERY, + &validator_public.clone().into(), + serialized_addresses.as_slice(), + ) + .map_err(|_| Error::Signing) + .unwrap(); + + let mut signed_addresses = vec![]; + schema::SignedAuthorityAddresses { + addresses: serialized_addresses.clone(), + signature, + } + .encode(&mut signed_addresses) + .map_err(Error::EncodingProto) + .unwrap(); + + let key = hash_authority_id(&validator_public.to_raw_vec()); + let value = signed_addresses; + (key, value) + }; + + let (_dht_event_tx, dht_event_rx) = channel(1); + let sentry_test_api = Arc::new(TestApi { + // Make sure the sentry node identifies its validator as an authority. + authorities: vec![validator_public.into()], + }); + + let (_to_worker, from_service) = mpsc::channel(0); + let mut sentry_worker = Worker::new( + from_service, + sentry_test_api, + sentry_network.clone(), + vec![], + dht_event_rx.boxed(), + Role::Sentry, + None, + ); + + sentry_worker.handle_dht_value_found_event(vec![dht_event]).unwrap(); + sentry_worker.set_priority_group().unwrap(); + + assert_eq!( + sentry_network.set_priority_group_call.lock().unwrap().len(), 1, + "Expect authority discovery to set the priority set.", + ); + + assert_eq!( + sentry_network.set_priority_group_call.lock().unwrap()[0], + ( + "authorities".to_string(), + HashSet::from_iter(vec![random_multiaddr.clone()].into_iter(),) + ), + "Expect authority discovery to only add `random_multiaddr`." + ); +} + +#[test] +fn do_not_cache_addresses_without_peer_id() { + let remote_key_store = KeyStore::new(); + let remote_public = remote_key_store + .write() + .sr25519_generate_new(key_types::AUTHORITY_DISCOVERY, None) + .unwrap(); + + let multiaddr_with_peer_id = { + let peer_id = PeerId::random(); + let address: Multiaddr = "/ip6/2001:db8:0:0:0:0:0:2/tcp/30333".parse().unwrap(); + + address.with(multiaddr::Protocol::P2p(peer_id.into())) + }; + + let multiaddr_without_peer_id: Multiaddr = "/ip6/2001:db8:0:0:0:0:0:1/tcp/30333".parse().unwrap(); + + let dht_event = { + let addresses = vec![ + multiaddr_with_peer_id.to_vec(), + multiaddr_without_peer_id.to_vec(), + ]; + + let mut serialized_addresses = vec![]; + schema::AuthorityAddresses { addresses } + .encode(&mut serialized_addresses) + .map_err(Error::EncodingProto) + .unwrap(); + + let signature = remote_key_store.read() + .sign_with( + key_types::AUTHORITY_DISCOVERY, + &remote_public.clone().into(), + serialized_addresses.as_slice(), + ) + .map_err(|_| Error::Signing) + .unwrap(); + + let mut signed_addresses = vec![]; + schema::SignedAuthorityAddresses { + addresses: serialized_addresses.clone(), + signature, + } + .encode(&mut signed_addresses) + .map_err(Error::EncodingProto) + .unwrap(); + + let key = hash_authority_id(&remote_public.to_raw_vec()); + let value = signed_addresses; + (key, value) + }; + + let (_dht_event_tx, dht_event_rx) = channel(1); + let local_test_api = Arc::new(TestApi { + // Make sure the sentry node identifies its validator as an authority. + authorities: vec![remote_public.into()], + }); + let local_network: Arc = Arc::new(Default::default()); + let local_key_store = KeyStore::new(); + + let (_to_worker, from_service) = mpsc::channel(0); + let mut local_worker = Worker::new( + from_service, + local_test_api, + local_network.clone(), + vec![], + dht_event_rx.boxed(), + Role::Authority(local_key_store), + None, + ); + + local_worker.handle_dht_value_found_event(vec![dht_event]).unwrap(); + + assert_eq!( + Some(&vec![multiaddr_with_peer_id]), + local_worker.addr_cache.get_addresses_by_authority_id(&remote_public.into()), + "Expect worker to only cache `Multiaddr`s with `PeerId`s.", + ); +} diff --git a/client/basic-authorship/Cargo.toml b/client/basic-authorship/Cargo.toml index a9ac58ef3211be3bc835bdc73754344964247934..6c9da3f3d8aa58a1bc51d7165650e2cf80e10145 100644 --- a/client/basic-authorship/Cargo.toml +++ b/client/basic-authorship/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-basic-authorship" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Basic implementation of block-authoring logic." @@ -12,23 +12,25 @@ description = "Basic implementation of block-authoring logic." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -log = "0.4.8" +codec = { package = "parity-scale-codec", version = "1.3.4" } futures = "0.3.4" -codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-dev", path = "../../primitives/inherents" } -sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } -sc-block-builder = { version = "0.8.0-dev", path = "../block-builder" } -tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } futures-timer = "3.0.1" +log = "0.4.8" +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-rc6"} +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sp-consensus = { version = "0.8.0-rc6", path = "../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-rc6", path = "../../primitives/inherents" } +sc-telemetry = { version = "2.0.0-rc6", path = "../telemetry" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../primitives/transaction-pool" } +sc-block-builder = { version = "0.8.0-rc6", path = "../block-builder" } +sc-proposer-metrics = { version = "0.8.0-rc6", path = "../proposer-metrics" } +tokio-executor = { version = "0.2.0-alpha.6", features = ["blocking"] } [dev-dependencies] -sc-transaction-pool = { version = "2.0.0-dev", path = "../../client/transaction-pool" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } +sc-transaction-pool = { version = "2.0.0-rc6", path = "../../client/transaction-pool" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client" } parking_lot = "0.10.0" diff --git a/client/basic-authorship/README.md b/client/basic-authorship/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1a20593c09eaa159a81ddd05c89abe77b7c1b57f --- /dev/null +++ b/client/basic-authorship/README.md @@ -0,0 +1,32 @@ +Basic implementation of block-authoring logic. + +# Example + +```rust +// The first step is to create a `ProposerFactory`. +let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone(), None); + +// From this factory, we create a `Proposer`. +let proposer = proposer_factory.init( + &client.header(&BlockId::number(0)).unwrap().unwrap(), +); + +// The proposer is created asynchronously. +let proposer = futures::executor::block_on(proposer).unwrap(); + +// This `Proposer` allows us to create a block proposition. +// The proposer will grab transactions from the transaction pool, and put them into the block. +let future = proposer.propose( + Default::default(), + Default::default(), + Duration::from_secs(2), + RecordProof::Yes, +); + +// We wait until the proposition is performed. +let block = futures::executor::block_on(future).unwrap(); +println!("Generated block: {:?}", block.block); +``` + + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/basic-authorship/src/basic_authorship.rs b/client/basic-authorship/src/basic_authorship.rs index e1e99938e375eb54ba16607938087626680df826..41d12970464f41c281eea6da490a0fa5aeb92008 100644 --- a/client/basic-authorship/src/basic_authorship.rs +++ b/client/basic-authorship/src/basic_authorship.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A consensus proposer for "basic" chains which use the primitive inherent-data. @@ -24,7 +26,6 @@ use codec::Decode; use sp_consensus::{evaluation, Proposal, RecordProof}; use sp_inherents::InherentData; use log::{error, info, debug, trace, warn}; -use sp_core::ExecutionContext; use sp_runtime::{ generic::BlockId, traits::{Block as BlockT, Hash as HashT, Header as HeaderT, DigestFor, BlakeTwo256}, @@ -37,21 +38,31 @@ use futures::{executor, future, future::Either}; use sp_blockchain::{HeaderBackend, ApplyExtrinsicFailed::Validity, Error::ApplyExtrinsicFailed}; use std::marker::PhantomData; +use prometheus_endpoint::Registry as PrometheusRegistry; +use sc_proposer_metrics::MetricsLink as PrometheusMetrics; + /// Proposer factory. pub struct ProposerFactory { /// The client instance. client: Arc, /// The transaction pool. transaction_pool: Arc, + /// Prometheus Link, + metrics: PrometheusMetrics, /// phantom member to pin the `Backend` type. _phantom: PhantomData, } impl ProposerFactory { - pub fn new(client: Arc, transaction_pool: Arc) -> Self { + pub fn new( + client: Arc, + transaction_pool: Arc, + prometheus: Option<&PrometheusRegistry>, + ) -> Self { ProposerFactory { client, transaction_pool, + metrics: PrometheusMetrics::new(prometheus), _phantom: PhantomData, } } @@ -79,15 +90,14 @@ impl ProposerFactory info!("🙌 Starting consensus session on top of parent {:?}", parent_hash); let proposer = Proposer { - inner: Arc::new(ProposerInner { - client: self.client.clone(), - parent_hash, - parent_id: id, - parent_number: *parent_header.number(), - transaction_pool: self.transaction_pool.clone(), - now, - _phantom: PhantomData, - }), + client: self.client.clone(), + parent_hash, + parent_id: id, + parent_number: *parent_header.number(), + transaction_pool: self.transaction_pool.clone(), + now, + metrics: self.metrics.clone(), + _phantom: PhantomData, }; proposer @@ -119,17 +129,13 @@ impl sp_consensus::Environment for /// The proposer logic. pub struct Proposer { - inner: Arc>, -} - -/// Proposer inner, to wrap parameters under Arc. -struct ProposerInner { client: Arc, parent_hash: ::Hash, parent_id: BlockId, parent_number: <::Header as HeaderT>::Number, transaction_pool: Arc, now: Box time::Instant + Send + Sync>, + metrics: PrometheusMetrics, _phantom: PhantomData, } @@ -151,22 +157,21 @@ impl sp_consensus::Proposer for type Error = sp_blockchain::Error; fn propose( - &mut self, + self, inherent_data: InherentData, inherent_digests: DigestFor, max_duration: time::Duration, record_proof: RecordProof, ) -> Self::Proposal { - let inner = self.inner.clone(); tokio_executor::blocking::run(move || { // leave some time for evaluation and block finalization (33%) - let deadline = (inner.now)() + max_duration - max_duration / 3; - inner.propose_with(inherent_data, inherent_digests, deadline, record_proof) + let deadline = (self.now)() + max_duration - max_duration / 3; + self.propose_with(inherent_data, inherent_digests, deadline, record_proof) }) } } -impl ProposerInner +impl Proposer where A: TransactionPool, B: backend::Backend + Send + Sync + 'static, @@ -177,7 +182,7 @@ impl ProposerInner + BlockBuilderApi, { fn propose_with( - &self, + self, inherent_data: InherentData, inherent_digests: DigestFor, deadline: time::Instant, @@ -194,15 +199,7 @@ impl ProposerInner record_proof, )?; - // We don't check the API versions any further here since the dispatch compatibility - // check should be enough. - for inherent in self.client.runtime_api() - .inherent_extrinsics_with_context( - &self.parent_id, - ExecutionContext::BlockConstruction, - inherent_data - )? - { + for inherent in block_builder.create_inherents(inherent_data)? { match block_builder.push(inherent) { Err(ApplyExtrinsicFailed(Validity(e))) if e.exhausted_resources() => warn!("⚠️ Dropping non-mandatory inherent from overweight block."), @@ -218,7 +215,7 @@ impl ProposerInner } // proceed with transactions - let mut is_first = true; + let block_timer = time::Instant::now(); let mut skipped = 0; let mut unqueue_invalid = Vec::new(); let pending_iterator = match executor::block_on(future::select( @@ -228,7 +225,8 @@ impl ProposerInner Either::Left((iterator, _)) => iterator, Either::Right(_) => { log::warn!( - "Timeout fired waiting for transaction pool to be ready. Proceeding to block production anyway.", + "Timeout fired waiting for transaction pool at block #{}. Proceeding with production.", + self.parent_number, ); self.transaction_pool.ready() } @@ -254,10 +252,7 @@ impl ProposerInner } Err(ApplyExtrinsicFailed(Validity(e))) if e.exhausted_resources() => { - if is_first { - debug!("[{:?}] Invalid transaction: FullBlock on empty block", pending_tx_hash); - unqueue_invalid.push(pending_tx_hash); - } else if skipped < MAX_SKIPPED_TRANSACTIONS { + if skipped < MAX_SKIPPED_TRANSACTIONS { skipped += 1; debug!( "Block seems full, but will try {} more transactions before quitting.", @@ -280,14 +275,19 @@ impl ProposerInner unqueue_invalid.push(pending_tx_hash); } } - - is_first = false; } self.transaction_pool.remove_invalid(&unqueue_invalid); let (block, storage_changes, proof) = block_builder.build()?.into_inner(); + self.metrics.report( + |metrics| { + metrics.number_of_transactions.set(block.extrinsics().len() as u64); + metrics.block_constructed.observe(block_timer.elapsed().as_secs_f64()); + } + ); + info!("🎁 Prepared block for proposing at {} [hash: {:?}; parent_hash: {}; extrinsics ({}): [{}]]", block.header().number(), ::Hash::from(block.header().hash()), @@ -323,15 +323,14 @@ mod tests { use parking_lot::Mutex; use sp_consensus::{BlockOrigin, Proposer}; use substrate_test_runtime_client::{ - prelude::*, - runtime::{Extrinsic, Transfer}, + prelude::*, TestClientBuilder, runtime::{Extrinsic, Transfer}, TestClientBuilderExt, }; use sp_transaction_pool::{ChainEvent, MaintainedTransactionPool, TransactionSource}; - use sc_transaction_pool::{BasicPool, FullChainApi}; + use sc_transaction_pool::BasicPool; use sp_api::Core; - use backend::Backend; use sp_blockchain::HeaderBackend; use sp_runtime::traits::NumberFor; + use sc_client_api::Backend; const SOURCE: TransactionSource = TransactionSource::External; @@ -344,14 +343,12 @@ mod tests { }.into_signed_tx() } - fn chain_event(block_number: u64, header: B::Header) -> ChainEvent + fn chain_event(header: B::Header) -> ChainEvent where NumberFor: From { - ChainEvent::NewBlock { - id: BlockId::Number(block_number.into()), - retracted: vec![], - is_new_best: true, - header, + ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, } } @@ -359,12 +356,12 @@ mod tests { fn should_cease_building_block_when_deadline_is_reached() { // given let client = Arc::new(substrate_test_runtime_client::new()); - let txpool = Arc::new( - BasicPool::new( - Default::default(), - Arc::new(FullChainApi::new(client.clone())), - None, - ).0 + let spawner = sp_core::testing::TaskExecutor::new(); + let txpool = BasicPool::new_full( + Default::default(), + None, + spawner, + client.clone(), ); futures::executor::block_on( @@ -373,15 +370,16 @@ mod tests { futures::executor::block_on( txpool.maintain(chain_event( - 0, - client.header(&BlockId::Number(0u64)).expect("header get error").expect("there should be header") + client.header(&BlockId::Number(0u64)) + .expect("header get error") + .expect("there should be header") )) ); - let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone()); + let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone(), None); let cell = Mutex::new((false, time::Instant::now())); - let mut proposer = proposer_factory.init_with_now( + let proposer = proposer_factory.init_with_now( &client.header(&BlockId::number(0)).unwrap().unwrap(), Box::new(move || { let mut value = cell.lock(); @@ -411,18 +409,18 @@ mod tests { #[test] fn should_not_panic_when_deadline_is_reached() { let client = Arc::new(substrate_test_runtime_client::new()); - let txpool = Arc::new( - BasicPool::new( - Default::default(), - Arc::new(FullChainApi::new(client.clone())), - None, - ).0 + let spawner = sp_core::testing::TaskExecutor::new(); + let txpool = BasicPool::new_full( + Default::default(), + None, + spawner, + client.clone(), ); - let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone()); + let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone(), None); let cell = Mutex::new((false, time::Instant::now())); - let mut proposer = proposer_factory.init_with_now( + let proposer = proposer_factory.init_with_now( &client.header(&BlockId::number(0)).unwrap().unwrap(), Box::new(move || { let mut value = cell.lock(); @@ -444,15 +442,14 @@ mod tests { #[test] fn proposed_storage_changes_should_match_execute_block_storage_changes() { - let (client, backend) = substrate_test_runtime_client::TestClientBuilder::new() - .build_with_backend(); + let (client, backend) = TestClientBuilder::new().build_with_backend(); let client = Arc::new(client); - let txpool = Arc::new( - BasicPool::new( - Default::default(), - Arc::new(FullChainApi::new(client.clone())), - None, - ).0 + let spawner = sp_core::testing::TaskExecutor::new(); + let txpool = BasicPool::new_full( + Default::default(), + None, + spawner, + client.clone(), ); let genesis_hash = client.info().best_hash; @@ -464,14 +461,15 @@ mod tests { futures::executor::block_on( txpool.maintain(chain_event( - 0, - client.header(&BlockId::Number(0u64)).expect("header get error").expect("there should be header") + client.header(&BlockId::Number(0u64)) + .expect("header get error") + .expect("there should be header"), )) ); - let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone()); + let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone(), None); - let mut proposer = proposer_factory.init_with_now( + let proposer = proposer_factory.init_with_now( &client.header(&block_id).unwrap().unwrap(), Box::new(move || time::Instant::now()), ); @@ -492,8 +490,11 @@ mod tests { backend.changes_trie_storage(), ).unwrap(); - let storage_changes = api.into_storage_changes(&state, changes_trie_state.as_ref(), genesis_hash) - .unwrap(); + let storage_changes = api.into_storage_changes( + &state, + changes_trie_state.as_ref(), + genesis_hash, + ).unwrap(); assert_eq!( proposal.storage_changes.transaction_storage_root, @@ -505,12 +506,12 @@ mod tests { fn should_not_remove_invalid_transactions_when_skipping() { // given let mut client = Arc::new(substrate_test_runtime_client::new()); - let txpool = Arc::new( - BasicPool::new( - Default::default(), - Arc::new(FullChainApi::new(client.clone())), - None, - ).0 + let spawner = sp_core::testing::TaskExecutor::new(); + let txpool = BasicPool::new_full( + Default::default(), + None, + spawner, + client.clone(), ); futures::executor::block_on( @@ -535,14 +536,14 @@ mod tests { ]) ).unwrap(); - let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone()); + let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone(), None); let mut propose_block = | client: &TestClient, number, expected_block_extrinsics, expected_pool_transactions, | { - let mut proposer = proposer_factory.init_with_now( + let proposer = proposer_factory.init_with_now( &client.header(&BlockId::number(number)).unwrap().unwrap(), Box::new(move || time::Instant::now()), ); @@ -563,8 +564,9 @@ mod tests { futures::executor::block_on( txpool.maintain(chain_event( - 0, - client.header(&BlockId::Number(0u64)).expect("header get error").expect("there should be header") + client.header(&BlockId::Number(0u64)) + .expect("header get error") + .expect("there should be header") )) ); @@ -574,8 +576,9 @@ mod tests { futures::executor::block_on( txpool.maintain(chain_event( - 1, - client.header(&BlockId::Number(1)).expect("header get error").expect("there should be header") + client.header(&BlockId::Number(1)) + .expect("header get error") + .expect("there should be header") )) ); diff --git a/client/basic-authorship/src/lib.rs b/client/basic-authorship/src/lib.rs index 5eb60f1cd586c53099b0aedb6542db2298e0dbc6..b405fc6de0f01b7e222d0d478a61d73c7a10b818 100644 --- a/client/basic-authorship/src/lib.rs +++ b/client/basic-authorship/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Basic implementation of block-authoring logic. //! @@ -23,12 +25,21 @@ //! # use sp_consensus::{Environment, Proposer, RecordProof}; //! # use sp_runtime::generic::BlockId; //! # use std::{sync::Arc, time::Duration}; -//! # use substrate_test_runtime_client::{self, runtime::{Extrinsic, Transfer}, AccountKeyring}; +//! # use substrate_test_runtime_client::{ +//! # runtime::{Extrinsic, Transfer}, AccountKeyring, +//! # DefaultTestClientBuilderExt, TestClientBuilderExt, +//! # }; //! # use sc_transaction_pool::{BasicPool, FullChainApi}; //! # let client = Arc::new(substrate_test_runtime_client::new()); -//! # let txpool = Arc::new(BasicPool::new(Default::default(), Arc::new(FullChainApi::new(client.clone())), None).0); +//! # let spawner = sp_core::testing::TaskExecutor::new(); +//! # let txpool = BasicPool::new_full( +//! # Default::default(), +//! # None, +//! # spawner, +//! # client.clone(), +//! # ); //! // The first step is to create a `ProposerFactory`. -//! let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone()); +//! let mut proposer_factory = ProposerFactory::new(client.clone(), txpool.clone(), None); //! //! // From this factory, we create a `Proposer`. //! let proposer = proposer_factory.init( @@ -36,7 +47,7 @@ //! ); //! //! // The proposer is created asynchronously. -//! let mut proposer = futures::executor::block_on(proposer).unwrap(); +//! let proposer = futures::executor::block_on(proposer).unwrap(); //! //! // This `Proposer` allows us to create a block proposition. //! // The proposer will grab transactions from the transaction pool, and put them into the block. diff --git a/client/block-builder/Cargo.toml b/client/block-builder/Cargo.toml index 15cc3c13934fa7e5fda805ce5d6fc5082aac25f4..94d6b70eeeb9dae9527087b4f0bde1fdedffca91 100644 --- a/client/block-builder/Cargo.toml +++ b/client/block-builder/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-block-builder" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate block builder" @@ -13,16 +13,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } -sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-block-builder = { version = "2.0.0-dev", path = "../../primitives/block-builder" } -sc-client-api = { version = "2.0.0-dev", path = "../api" } -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } +sp-consensus = { version = "0.8.0-rc6", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-block-builder = { version = "2.0.0-rc6", path = "../../primitives/block-builder" } +sp-inherents = { version = "2.0.0-rc6", path = "../../primitives/inherents" } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } [dev-dependencies] substrate-test-runtime-client = { path = "../../test-utils/runtime/client" } -sp-trie = { version = "2.0.0-dev", path = "../../primitives/trie" } +sp-trie = { version = "2.0.0-rc6", path = "../../primitives/trie" } diff --git a/client/block-builder/README.md b/client/block-builder/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c691f6692abff918c5dfe2f849d3263119724f54 --- /dev/null +++ b/client/block-builder/README.md @@ -0,0 +1,9 @@ +Substrate block builder + +This crate provides the [`BlockBuilder`] utility and the corresponding runtime api +[`BlockBuilder`](sp_block_builder::BlockBuilder).Error + +The block builder utility is used in the node as an abstraction over the runtime api to +initialize a block, to push extrinsics and to finalize a block. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/block-builder/src/lib.rs b/client/block-builder/src/lib.rs index 2154a1f5f26800ae26fca594b0d995bef9b1450f..904667b1afc6e99d3cf63f09d7f88890e631f041 100644 --- a/client/block-builder/src/lib.rs +++ b/client/block-builder/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate block builder //! @@ -32,7 +34,10 @@ use sp_runtime::{ }; use sp_blockchain::{ApplyExtrinsicFailed, Error}; use sp_core::ExecutionContext; -use sp_api::{Core, ApiExt, ApiErrorFor, ApiRef, ProvideRuntimeApi, StorageChanges, StorageProof}; +use sp_api::{ + Core, ApiExt, ApiErrorFor, ApiRef, ProvideRuntimeApi, StorageChanges, StorageProof, + TransactionOutcome, +}; use sp_consensus::RecordProof; pub use sp_block_builder::BlockBuilder as BlockBuilderApi; @@ -154,17 +159,22 @@ where let block_id = &self.block_id; let extrinsics = &mut self.extrinsics; - self.api.map_api_result(|api| { + self.api.execute_in_transaction(|api| { match api.apply_extrinsic_with_context( block_id, ExecutionContext::BlockConstruction, xt.clone(), - )? { - Ok(_) => { + ) { + Ok(Ok(_)) => { extrinsics.push(xt); - Ok(()) + TransactionOutcome::Commit(Ok(())) } - Err(tx_validity) => Err(ApplyExtrinsicFailed::Validity(tx_validity).into()), + Ok(Err(tx_validity)) => { + TransactionOutcome::Rollback( + Err(ApplyExtrinsicFailed::Validity(tx_validity).into()), + ) + }, + Err(e) => TransactionOutcome::Rollback(Err(e)), } }) } @@ -210,6 +220,25 @@ where proof, }) } + + /// Create the inherents for the block. + /// + /// Returns the inherents created by the runtime or an error if something failed. + pub fn create_inherents( + &mut self, + inherent_data: sp_inherents::InherentData, + ) -> Result, ApiErrorFor> { + let block_id = self.block_id; + self.api.execute_in_transaction(move |api| { + // `create_inherents` should not change any state, to ensure this we always rollback + // the transaction. + TransactionOutcome::Rollback(api.inherent_extrinsics_with_context( + &block_id, + ExecutionContext::BlockConstruction, + inherent_data + )) + }) + } } #[cfg(test)] diff --git a/client/chain-spec/Cargo.toml b/client/chain-spec/Cargo.toml index 6906b1ecdad434884437af619548e2b34daedf4c..fb0addf461abd0ebcce501b1df7e3788fcbfa65b 100644 --- a/client/chain-spec/Cargo.toml +++ b/client/chain-spec/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-chain-spec" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate chain configurations." @@ -12,12 +12,12 @@ description = "Substrate chain configurations." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-chain-spec-derive = { version = "2.0.0-dev", path = "./derive" } +sc-chain-spec-derive = { version = "2.0.0-rc6", path = "./derive" } impl-trait-for-tuples = "0.1.3" -sc-network = { version = "0.8.0-dev", path = "../network" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sc-network = { version = "0.8.0-rc6", path = "../network" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-chain-spec = { version = "2.0.0-dev", path = "../../primitives/chain-spec" } -sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-chain-spec = { version = "2.0.0-rc6", path = "../../primitives/chain-spec" } +sc-telemetry = { version = "2.0.0-rc6", path = "../telemetry" } diff --git a/client/chain-spec/README.md b/client/chain-spec/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6475c811045b1f44f57b87bce2a4ea37c1d321d0 --- /dev/null +++ b/client/chain-spec/README.md @@ -0,0 +1,92 @@ +Substrate chain configurations. + +This crate contains structs and utilities to declare +a runtime-specific configuration file (a.k.a chain spec). + +Basic chain spec type containing all required parameters is +[`ChainSpec`](./struct.ChainSpec.html). It can be extended with +additional options that contain configuration specific to your chain. +Usually the extension is going to be an amalgamate of types exposed +by Substrate core modules. To allow the core modules to retrieve +their configuration from your extension you should use `ChainSpecExtension` +macro exposed by this crate. + +```rust +use std::collections::HashMap; +use sc_chain_spec::{GenericChainSpec, ChainSpecExtension}; + +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecExtension)] +pub struct MyExtension { + pub known_blocks: HashMap, +} + +pub type MyChainSpec = GenericChainSpec; +``` + +Some parameters may require different values depending on the +current blockchain height (a.k.a. forks). You can use `ChainSpecGroup` +macro and provided [`Forks`](./struct.Forks.html) structure to put +such parameters to your chain spec. +This will allow to override a single parameter starting at specific +block number. + +```rust +use sc_chain_spec::{Forks, ChainSpecGroup, ChainSpecExtension, GenericChainSpec}; + +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecGroup)] +pub struct ClientParams { + max_block_size: usize, + max_extrinsic_size: usize, +} + +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecGroup)] +pub struct PoolParams { + max_transaction_size: usize, +} + +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecGroup, ChainSpecExtension)] +pub struct Extension { + pub client: ClientParams, + pub pool: PoolParams, +} + +pub type BlockNumber = u64; + +/// A chain spec supporting forkable `ClientParams`. +pub type MyChainSpec1 = GenericChainSpec>; + +/// A chain spec supporting forkable `Extension`. +pub type MyChainSpec2 = GenericChainSpec>; +``` + +It's also possible to have a set of parameters that is allowed to change +with block numbers (i.e. is forkable), and another set that is not subject to changes. +This is also possible by declaring an extension that contains `Forks` within it. + + +```rust +use serde::{Serialize, Deserialize}; +use sc_chain_spec::{Forks, GenericChainSpec, ChainSpecGroup, ChainSpecExtension}; + +#[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +pub struct ClientParams { + max_block_size: usize, + max_extrinsic_size: usize, +} + +#[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +pub struct PoolParams { + max_transaction_size: usize, +} + +#[derive(Clone, Debug, Serialize, Deserialize, ChainSpecExtension)] +pub struct Extension { + pub client: ClientParams, + #[forks] + pub pool: Forks, +} + +pub type MyChainSpec = GenericChainSpec; +``` + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/chain-spec/derive/Cargo.toml b/client/chain-spec/derive/Cargo.toml index 66058b3f729963d100b846527a538d5c0c8915b1..a3112e10faca9c5ec205d7344eff478f71a5a39b 100644 --- a/client/chain-spec/derive/Cargo.toml +++ b/client/chain-spec/derive/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-chain-spec-derive" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Macros to derive chain spec extension traits implementation." diff --git a/client/chain-spec/derive/src/impls.rs b/client/chain-spec/derive/src/impls.rs index 1b22f16581a79c25920cc8733469b12dd2ba7e94..ded961a6da8159d8cc5f1db8c3c7fe80dc94d77c 100644 --- a/client/chain-spec/derive/src/impls.rs +++ b/client/chain-spec/derive/src/impls.rs @@ -64,7 +64,6 @@ pub fn extension_derive(ast: &DeriveInput) -> proc_macro::TokenStream { }) } - /// Implements required traits and creates `Fork` structs for `ChainSpec` custom parameter group. pub fn group_derive(ast: &DeriveInput) -> proc_macro::TokenStream { derive(ast, |crate_name, name, generics: &syn::Generics, field_names, field_types, _fields| { @@ -75,9 +74,27 @@ pub fn group_derive(ast: &DeriveInput) -> proc_macro::TokenStream { let to_fork = generate_base_to_fork(&fork_name, &field_names); let combine_with = generate_combine_with(&field_names); let to_base = generate_fork_to_base(name, &field_names); + let serde_crate_name = match proc_macro_crate::crate_name("serde") { + Ok(name) => Ident::new(&name.replace("-", "_"), Span::call_site()), + Err(e) => { + let err = Error::new( + Span::call_site(), + &format!("Could not find `serde` crate: {}", e), + ).to_compile_error(); + + return quote!( #err ).into(); + } + }; quote! { - #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecExtension)] + #[derive( + Debug, + Clone, + PartialEq, + #serde_crate_name::Serialize, + #serde_crate_name::Deserialize, + ChainSpecExtension, + )] pub struct #fork_name #ty_generics #where_clause { #fork_fields } diff --git a/client/chain-spec/src/chain_spec.rs b/client/chain-spec/src/chain_spec.rs index 8e941161ee5a01d32c2606188846f7660e8f1da2..52414f8687c96ed97f56e84e1345d3c0f8423ecc 100644 --- a/client/chain-spec/src/chain_spec.rs +++ b/client/chain-spec/src/chain_spec.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate chain configurations. diff --git a/client/chain-spec/src/lib.rs b/client/chain-spec/src/lib.rs index 6fb26942612d3637202a0645c2dbbba32801ff7b..8901a9a682224991a3679f6e160ac0a0c36f8237 100644 --- a/client/chain-spec/src/lib.rs +++ b/client/chain-spec/src/lib.rs @@ -29,10 +29,9 @@ //! //! ```rust //! use std::collections::HashMap; -//! use serde::{Serialize, Deserialize}; //! use sc_chain_spec::{GenericChainSpec, ChainSpecExtension}; //! -//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecExtension)] +//! #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecExtension)] //! pub struct MyExtension { //! pub known_blocks: HashMap, //! } @@ -48,21 +47,20 @@ //! block number. //! //! ```rust -//! use serde::{Serialize, Deserialize}; //! use sc_chain_spec::{Forks, ChainSpecGroup, ChainSpecExtension, GenericChainSpec}; //! -//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +//! #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecGroup)] //! pub struct ClientParams { //! max_block_size: usize, //! max_extrinsic_size: usize, //! } //! -//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup)] +//! #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecGroup)] //! pub struct PoolParams { //! max_transaction_size: usize, //! } //! -//! #[derive(Clone, Debug, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)] +//! #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, ChainSpecGroup, ChainSpecExtension)] //! pub struct Extension { //! pub client: ClientParams, //! pub pool: PoolParams, @@ -158,3 +156,9 @@ pub trait ChainSpec: BuildStorage + Send { /// This will be used as storage at genesis. fn set_storage(&mut self, storage: Storage); } + +impl std::fmt::Debug for dyn ChainSpec { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "ChainSpec(name = {:?}, id = {:?})", self.name(), self.id()) + } +} diff --git a/client/cli/Cargo.toml b/client/cli/Cargo.toml index 198a9df5b53fdbef22f16d7cec3b8741153aeaaa..2643376f84131beac0efec06da20432ca916f161 100644 --- a/client/cli/Cargo.toml +++ b/client/cli/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-cli" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Substrate CLI interface." edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,39 +12,44 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -clap = "2.33.0" derive_more = "0.99.2" env_logger = "0.7.0" log = "0.4.8" atty = "0.2.13" -regex = "1.3.1" +regex = "1.3.4" time = "0.1.42" ansi_term = "0.12.1" lazy_static = "1.4.0" -app_dirs = "1.2.1" -tokio = { version = "0.2.9", features = [ "signal", "rt-core", "rt-threaded" ] } +tokio = { version = "0.2.21", features = [ "signal", "rt-core", "rt-threaded", "blocking" ] } futures = "0.3.4" fdlimit = "0.1.4" +libp2p = "0.24.0" +parity-scale-codec = "1.3.0" +hex = "0.4.2" +rand = "0.7.3" +bip39 = "0.6.0-beta.1" serde_json = "1.0.41" -sc-informant = { version = "0.8.0-dev", path = "../informant" } -sp-panic-handler = { version = "2.0.0-dev", path = "../../primitives/panic-handler" } -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sc-network = { version = "0.8.0-dev", path = "../network" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } -sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sc-service = { version = "0.8.0-dev", default-features = false, path = "../service" } -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } -sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } -substrate-prometheus-endpoint = { path = "../../utils/prometheus" , version = "0.8.0-dev"} -sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } +sc-keystore = { version = "2.0.0-rc6", path = "../keystore" } +sc-informant = { version = "0.8.0-rc6", path = "../informant" } +sp-panic-handler = { version = "2.0.0-rc6", path = "../../primitives/panic-handler" } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sc-network = { version = "0.8.0-rc6", path = "../network" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-rc6", path = "../../primitives/utils" } +sp-version = { version = "2.0.0-rc6", path = "../../primitives/version" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sc-service = { version = "0.8.0-rc6", default-features = false, path = "../service" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } +sc-telemetry = { version = "2.0.0-rc6", path = "../telemetry" } +substrate-prometheus-endpoint = { path = "../../utils/prometheus" , version = "0.8.0-rc6"} +sp-keyring = { version = "2.0.0-rc6", path = "../../primitives/keyring" } names = "0.11.0" structopt = "0.3.8" -sc-tracing = { version = "2.0.0-dev", path = "../tracing" } +sc-tracing = { version = "2.0.0-rc6", path = "../tracing" } chrono = "0.4.10" -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } +serde = "1.0.111" [target.'cfg(not(target_os = "unknown"))'.dependencies] rpassword = "4.0.1" @@ -54,6 +59,8 @@ nix = "0.17.0" [dev-dependencies] tempfile = "3.1.0" +sp-io = { version = "2.0.0-rc3", path = "../../primitives/io" } +sp-application-crypto = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/application-crypto" } [features] wasmtime = [ diff --git a/client/cli/README.md b/client/cli/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2504dbb0c03b5f9525c580622445ac431fe61d6f --- /dev/null +++ b/client/cli/README.md @@ -0,0 +1,3 @@ +Substrate CLI library. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/cli/src/arg_enums.rs b/client/cli/src/arg_enums.rs index c146a16886016e8a3ff8dc34f5f7ea63f162ebe4..4ba76d7a06377777dbaf99ca1bb14e67fdc7e549 100644 --- a/client/cli/src/arg_enums.rs +++ b/client/cli/src/arg_enums.rs @@ -1,19 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - +// along with this program. If not, see . // NOTE: we allow missing docs here because arg_enum! creates the function variants without doc #![allow(missing_docs)] @@ -84,6 +85,23 @@ arg_enum! { } } +arg_enum! { + #[derive(Debug, Copy, Clone, PartialEq, Eq)] + pub enum CryptoScheme { + Ed25519, + Sr25519, + Ecdsa, + } +} + +arg_enum! { + #[derive(Debug, Copy, Clone, PartialEq, Eq)] + pub enum OutputType { + Json, + Text, + } +} + arg_enum! { /// How to execute blocks #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -177,6 +195,8 @@ arg_enum! { pub const DEFAULT_EXECUTION_SYNCING: ExecutionStrategy = ExecutionStrategy::NativeElseWasm; /// Default value for the `--execution-import-block` parameter. pub const DEFAULT_EXECUTION_IMPORT_BLOCK: ExecutionStrategy = ExecutionStrategy::NativeElseWasm; +/// Default value for the `--execution-import-block` parameter when the node is a validator. +pub const DEFAULT_EXECUTION_IMPORT_BLOCK_VALIDATOR: ExecutionStrategy = ExecutionStrategy::Wasm; /// Default value for the `--execution-block-construction` parameter. pub const DEFAULT_EXECUTION_BLOCK_CONSTRUCTION: ExecutionStrategy = ExecutionStrategy::Wasm; /// Default value for the `--execution-offchain-worker` parameter. diff --git a/client/cli/src/commands/build_spec_cmd.rs b/client/cli/src/commands/build_spec_cmd.rs index a01101fa7965563795eb3058bf3be0f752801517..616c5139f64f0d370373bda2b221bacea8700b6c 100644 --- a/client/cli/src/commands/build_spec_cmd.rs +++ b/client/cli/src/commands/build_spec_cmd.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error; use crate::params::NodeKeyParams; @@ -20,11 +22,12 @@ use crate::params::SharedParams; use crate::CliConfiguration; use log::info; use sc_network::config::build_multiaddr; -use sc_service::{config::MultiaddrWithPeerId, Configuration}; +use sc_service::{config::{MultiaddrWithPeerId, NetworkConfiguration}, ChainSpec}; use structopt::StructOpt; +use std::io::Write; /// The `build-spec` command used to build a specification. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct BuildSpecCmd { /// Force raw genesis storage output. #[structopt(long = "raw")] @@ -48,13 +51,16 @@ pub struct BuildSpecCmd { impl BuildSpecCmd { /// Run the build-spec command - pub fn run(&self, config: Configuration) -> error::Result<()> { + pub fn run( + &self, + mut spec: Box, + network_config: NetworkConfiguration, + ) -> error::Result<()> { info!("Building chain spec"); - let mut spec = config.chain_spec; let raw_output = self.raw; if spec.boot_nodes().is_empty() && !self.disable_default_bootnode { - let keys = config.network.node_key.into_keypair()?; + let keys = network_config.node_key.into_keypair()?; let peer_id = keys.public().into_peer_id(); let addr = MultiaddrWithPeerId { multiaddr: build_multiaddr![Ip4([127, 0, 0, 1]), Tcp(30333u16)], @@ -64,9 +70,9 @@ impl BuildSpecCmd { } let json = sc_service::chain_ops::build_spec(&*spec, raw_output)?; - - print!("{}", json); - + if std::io::stdout().write_all(json.as_bytes()).is_err() { + let _ = std::io::stderr().write_all(b"Error writing to stdout\n"); + } Ok(()) } } diff --git a/client/cli/src/commands/check_block_cmd.rs b/client/cli/src/commands/check_block_cmd.rs index d5242cda8598131a25a4dccc32e8d78075a1e65a..b536d4f26bb6c875745e0ee180eca07a31158b68 100644 --- a/client/cli/src/commands/check_block_cmd.rs +++ b/client/cli/src/commands/check_block_cmd.rs @@ -1,29 +1,31 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::{ CliConfiguration, error, params::{ImportParams, SharedParams, BlockNumberOrHash}, }; -use sc_service::{Configuration, ServiceBuilderCommand}; -use sp_runtime::traits::{Block as BlockT, NumberFor}; -use std::{fmt::Debug, str::FromStr}; +use sc_client_api::{BlockBackend, UsageProvider}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; +use std::{fmt::Debug, str::FromStr, sync::Arc}; use structopt::StructOpt; /// The `check-block` command used to validate blocks. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct CheckBlockCmd { /// Block hash or number #[structopt(value_name = "HASH or NUMBER")] @@ -46,21 +48,21 @@ pub struct CheckBlockCmd { impl CheckBlockCmd { /// Run the check-block command - pub async fn run( + pub async fn run( &self, - config: Configuration, - builder: B, + client: Arc, + import_queue: IQ, ) -> error::Result<()> where - B: FnOnce(Configuration) -> Result, - BC: ServiceBuilderCommand + Unpin, - BB: BlockT + Debug, - as FromStr>::Err: std::fmt::Debug, - BB::Hash: FromStr, - ::Err: std::fmt::Debug, + B: BlockT + for<'de> serde::Deserialize<'de>, + C: BlockBackend + UsageProvider + Send + Sync + 'static, + IQ: sc_service::ImportQueue + 'static, + B::Hash: FromStr, + ::Err: Debug, + <::Number as FromStr>::Err: Debug, { let start = std::time::Instant::now(); - builder(config)?.check_block(self.input.parse()?).await?; + sc_service::chain_ops::check_block(client, import_queue, self.input.parse()?).await?; println!("Completed in {} ms.", start.elapsed().as_millis()); Ok(()) diff --git a/client/cli/src/commands/export_blocks_cmd.rs b/client/cli/src/commands/export_blocks_cmd.rs index 4f7cf0f48c05a172547e2308d4de0ef4e25ffeac..e175d498941b84f007c9f7fd461e5485a002b5f9 100644 --- a/client/cli/src/commands/export_blocks_cmd.rs +++ b/client/cli/src/commands/export_blocks_cmd.rs @@ -1,35 +1,40 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error; -use crate::params::{BlockNumber, DatabaseParams, PruningParams, SharedParams}; +use crate::params::{GenericNumber, DatabaseParams, PruningParams, SharedParams}; use crate::CliConfiguration; use log::info; use sc_service::{ - config::DatabaseConfig, Configuration, ServiceBuilderCommand, + config::DatabaseConfig, chain_ops::export_blocks, }; +use sc_client_api::{BlockBackend, UsageProvider}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use std::fmt::Debug; use std::fs; use std::io; use std::path::PathBuf; +use std::str::FromStr; +use std::sync::Arc; use structopt::StructOpt; /// The `export-blocks` command used to export blocks. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct ExportBlocksCmd { /// Output file name or stdout if unspecified. #[structopt(parse(from_os_str))] @@ -39,13 +44,13 @@ pub struct ExportBlocksCmd { /// /// Default is 1. #[structopt(long = "from", value_name = "BLOCK")] - pub from: Option, + pub from: Option, /// Specify last block number. /// /// Default is best block. #[structopt(long = "to", value_name = "BLOCK")] - pub to: Option, + pub to: Option, /// Use binary output rather than JSON. #[structopt(long)] @@ -66,19 +71,17 @@ pub struct ExportBlocksCmd { impl ExportBlocksCmd { /// Run the export-blocks command - pub async fn run( + pub async fn run( &self, - config: Configuration, - builder: B, + client: Arc, + database_config: DatabaseConfig, ) -> error::Result<()> where - B: FnOnce(Configuration) -> Result, - BC: ServiceBuilderCommand + Unpin, - BB: sp_runtime::traits::Block + Debug, - <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, - ::Hash: std::str::FromStr, + B: BlockT, + C: BlockBackend + UsageProvider + 'static, + <::Number as FromStr>::Err: Debug, { - if let DatabaseConfig::RocksDb { ref path, .. } = &config.database { + if let DatabaseConfig::RocksDb { ref path, .. } = database_config { info!("DB path: {}", path.display()); } @@ -92,8 +95,7 @@ impl ExportBlocksCmd { None => Box::new(io::stdout()), }; - builder(config)? - .export_blocks(file, from.into(), to, binary) + export_blocks(client, file, from.into(), to, binary) .await .map_err(Into::into) } diff --git a/client/cli/src/commands/export_state_cmd.rs b/client/cli/src/commands/export_state_cmd.rs index db6f81c498f28d7bf8197f61a31571da8e64a446..c078db0d8aea922e23ddfda88112e22f5979bbbe 100644 --- a/client/cli/src/commands/export_state_cmd.rs +++ b/client/cli/src/commands/export_state_cmd.rs @@ -1,31 +1,33 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::{ CliConfiguration, error, params::{PruningParams, SharedParams, BlockNumberOrHash}, }; use log::info; -use sc_service::{Configuration, ServiceBuilderCommand}; -use sp_runtime::traits::{Block as BlockT, NumberFor}; -use std::{fmt::Debug, str::FromStr}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; +use std::{fmt::Debug, str::FromStr, io::Write, sync::Arc}; use structopt::StructOpt; +use sc_client_api::{StorageProvider, UsageProvider}; /// The `export-state` command used to export the state of a given block into /// a chain spec. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct ExportStateCmd { /// Block hash or number. #[structopt(value_name = "HASH or NUMBER")] @@ -42,30 +44,29 @@ pub struct ExportStateCmd { impl ExportStateCmd { /// Run the `export-state` command - pub fn run( + pub async fn run( &self, - config: Configuration, - builder: B, + client: Arc, + mut input_spec: Box, ) -> error::Result<()> where - B: FnOnce(Configuration) -> Result, - BC: ServiceBuilderCommand + Unpin, - BB: BlockT + Debug, - as FromStr>::Err: std::fmt::Debug, - BB::Hash: FromStr, - ::Err: std::fmt::Debug, + B: BlockT, + C: UsageProvider + StorageProvider, + BA: sc_client_api::backend::Backend, + B::Hash: FromStr, + ::Err: Debug, + <::Number as FromStr>::Err: Debug, { info!("Exporting raw state..."); - let mut input_spec = config.chain_spec.cloned_box(); - let block_id = self.input.clone().map(|b| b.parse()).transpose()?; - let raw_state = builder(config)?.export_raw_state(block_id)?; + let block_id = self.input.as_ref().map(|b| b.parse()).transpose()?; + let raw_state = sc_service::chain_ops::export_raw_state(client, block_id)?; input_spec.set_storage(raw_state); info!("Generating new chain spec..."); let json = sc_service::chain_ops::build_spec(&*input_spec, true)?; - - print!("{}", json); - + if std::io::stdout().write_all(json.as_bytes()).is_err() { + let _ = std::io::stderr().write_all(b"Error writing to stdout\n"); + } Ok(()) } } diff --git a/client/cli/src/commands/generate.rs b/client/cli/src/commands/generate.rs new file mode 100644 index 0000000000000000000000000000000000000000..4664e17551c17ed48f690a08819586ef1a4a522c --- /dev/null +++ b/client/cli/src/commands/generate.rs @@ -0,0 +1,90 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Implementation of the `generate` subcommand +use bip39::{MnemonicType, Mnemonic, Language}; +use structopt::StructOpt; +use crate::{ + utils::print_from_uri, KeystoreParams, Error, + with_crypto_scheme, NetworkSchemeFlag, OutputTypeFlag, CryptoSchemeFlag, +}; + +/// The `generate` command +#[derive(Debug, StructOpt)] +#[structopt(name = "generate", about = "Generate a random account")] +pub struct GenerateCmd { + /// The number of words in the phrase to generate. One of 12 (default), 15, 18, 21 and 24. + #[structopt(long, short = "w", value_name = "WORDS")] + words: Option, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub keystore_params: KeystoreParams, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub network_scheme: NetworkSchemeFlag, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub output_scheme: OutputTypeFlag, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub crypto_scheme: CryptoSchemeFlag, +} + +impl GenerateCmd { + /// Run the command + pub fn run(&self) -> Result<(), Error> { + let words = match self.words { + Some(words) => { + MnemonicType::for_word_count(words) + .map_err(|_| { + Error::Input("Invalid number of words given for phrase: must be 12/15/18/21/24".into()) + })? + }, + None => MnemonicType::Words12, + }; + let mnemonic = Mnemonic::new(words, Language::English); + let password = self.keystore_params.read_password()?; + let output = self.output_scheme.output_type.clone(); + + with_crypto_scheme!( + self.crypto_scheme.scheme, + print_from_uri( + mnemonic.phrase(), + password, + self.network_scheme.network.clone(), + output + ) + ); + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::GenerateCmd; + use structopt::StructOpt; + + #[test] + fn generate() { + let generate = GenerateCmd::from_iter(&["generate", "--password", "12345"]); + assert!(generate.run().is_ok()) + } +} diff --git a/client/cli/src/commands/generate_node_key.rs b/client/cli/src/commands/generate_node_key.rs new file mode 100644 index 0000000000000000000000000000000000000000..197e0eb5d9034ace60080e879dad7156e89b7ca3 --- /dev/null +++ b/client/cli/src/commands/generate_node_key.rs @@ -0,0 +1,71 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Implementation of the `generate-node-key` subcommand + +use crate::Error; +use structopt::StructOpt; +use std::{path::PathBuf, fs}; +use libp2p::identity::{ed25519 as libp2p_ed25519, PublicKey}; + +/// The `generate-node-key` command +#[derive(Debug, StructOpt)] +#[structopt( + name = "generate-node-key", + about = "Generate a random node libp2p key, save it to file and print its peer ID" +)] +pub struct GenerateNodeKeyCmd { + /// Name of file to save secret key to. + #[structopt(long)] + file: PathBuf, +} + +impl GenerateNodeKeyCmd { + /// Run the command + pub fn run(&self) -> Result<(), Error> { + let file = &self.file; + + let keypair = libp2p_ed25519::Keypair::generate(); + let secret = keypair.secret(); + let peer_id = PublicKey::Ed25519(keypair.public()).into_peer_id(); + + fs::write(file, hex::encode(secret.as_ref()))?; + + println!("{}", peer_id); + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use tempfile::Builder; + use std::io::Read; + + #[test] + fn generate_node_key() { + let mut file = Builder::new().prefix("keyfile").tempfile().unwrap(); + let file_path = file.path().display().to_string(); + let generate = + GenerateNodeKeyCmd::from_iter(&["generate-node-key", "--file", &file_path]); + assert!(generate.run().is_ok()); + let mut buf = String::new(); + assert!(file.read_to_string(&mut buf).is_ok()); + assert!(hex::decode(buf).is_ok()); + } +} diff --git a/client/cli/src/commands/import_blocks_cmd.rs b/client/cli/src/commands/import_blocks_cmd.rs index ce95640f469ceb3f380f07727f4ed5bc09d431ae..00f8ec43b02fe937b26db243ab930adf793e75bc 100644 --- a/client/cli/src/commands/import_blocks_cmd.rs +++ b/client/cli/src/commands/import_blocks_cmd.rs @@ -1,33 +1,37 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error; use crate::params::ImportParams; use crate::params::SharedParams; use crate::CliConfiguration; -use sc_service::{Configuration, ServiceBuilderCommand}; -use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; +use sc_service::chain_ops::import_blocks; +use sp_runtime::traits::Block as BlockT; use std::fmt::Debug; use std::fs; use std::io::{self, Read, Seek}; use std::path::PathBuf; +use std::sync::Arc; use structopt::StructOpt; +use sc_client_api::UsageProvider; /// The `import-blocks` command used to import blocks. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct ImportBlocksCmd { /// Input file or stdin if unspecified. #[structopt(parse(from_os_str))] @@ -39,6 +43,10 @@ pub struct ImportBlocksCmd { #[structopt(long = "default-heap-pages", value_name = "COUNT")] pub default_heap_pages: Option, + /// Try importing blocks from binary format rather than JSON. + #[structopt(long)] + pub binary: bool, + #[allow(missing_docs)] #[structopt(flatten)] pub shared_params: SharedParams, @@ -55,17 +63,15 @@ impl ReadPlusSeek for T {} impl ImportBlocksCmd { /// Run the import-blocks command - pub async fn run( + pub async fn run( &self, - config: Configuration, - builder: B, + client: Arc, + import_queue: IQ, ) -> error::Result<()> where - B: FnOnce(Configuration) -> Result, - BC: ServiceBuilderCommand + Unpin, - BB: sp_runtime::traits::Block + Debug, - <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, - ::Hash: std::str::FromStr, + C: UsageProvider + Send + Sync + 'static, + B: BlockT + for<'de> serde::Deserialize<'de>, + IQ: sc_service::ImportQueue + 'static, { let file: Box = match &self.input { Some(filename) => Box::new(fs::File::open(filename)?), @@ -76,8 +82,7 @@ impl ImportBlocksCmd { } }; - builder(config)? - .import_blocks(file, false) + import_blocks(client, import_queue, file, false, self.binary) .await .map_err(Into::into) } diff --git a/client/cli/src/commands/insert.rs b/client/cli/src/commands/insert.rs new file mode 100644 index 0000000000000000000000000000000000000000..5e4a0d42ffefc13fb260c29336b716e144c2ab08 --- /dev/null +++ b/client/cli/src/commands/insert.rs @@ -0,0 +1,94 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Implementation of the `insert` subcommand + +use crate::{Error, KeystoreParams, CryptoSchemeFlag, SharedParams, utils, with_crypto_scheme}; +use structopt::StructOpt; +use sp_core::{crypto::KeyTypeId, traits::BareCryptoStore}; +use std::convert::TryFrom; +use sc_service::config::KeystoreConfig; +use sc_keystore::Store as KeyStore; +use sp_core::crypto::SecretString; + +/// The `insert` command +#[derive(Debug, StructOpt)] +#[structopt( + name = "insert", + about = "Insert a key to the keystore of a node." +)] +pub struct InsertCmd { + /// The secret key URI. + /// If the value is a file, the file content is used as URI. + /// If not given, you will be prompted for the URI. + #[structopt(long)] + suri: Option, + + /// Key type, examples: "gran", or "imon" + #[structopt(long)] + key_type: String, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub shared_params: SharedParams, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub keystore_params: KeystoreParams, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub crypto_scheme: CryptoSchemeFlag, +} + +impl InsertCmd { + /// Run the command + pub fn run(&self) -> Result<(), Error> { + let suri = utils::read_uri(self.suri.as_ref())?; + let base_path = self.shared_params.base_path.as_ref() + .ok_or_else(|| Error::Other("please supply base path".into()))?; + + let (keystore, public) = match self.keystore_params.keystore_config(base_path)? { + KeystoreConfig::Path { path, password } => { + let public = with_crypto_scheme!( + self.crypto_scheme.scheme, + to_vec(&suri, password.clone()) + )?; + let keystore = KeyStore::open(path, password) + .map_err(|e| format!("{}", e))?; + (keystore, public) + }, + _ => unreachable!("keystore_config always returns path and password; qed") + }; + + let key_type = KeyTypeId::try_from(self.key_type.as_str()) + .map_err(|_| { + Error::Other("Cannot convert argument to keytype: argument should be 4-character string".into()) + })?; + + keystore.write() + .insert_unknown(key_type, &suri, &public[..]) + .map_err(|e| Error::Other(format!("{:?}", e)))?; + + Ok(()) + } +} + +fn to_vec(uri: &str, pass: Option) -> Result, Error> { + let p = utils::pair_from_suri::

(uri, pass)?; + Ok(p.public().as_ref().to_vec()) +} diff --git a/client/cli/src/commands/inspect.rs b/client/cli/src/commands/inspect.rs new file mode 100644 index 0000000000000000000000000000000000000000..0c9e54d118533320492d0623fd0fbb5731c97c96 --- /dev/null +++ b/client/cli/src/commands/inspect.rs @@ -0,0 +1,97 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Implementation of the `inspect` subcommand + +use crate::{ + utils, KeystoreParams, with_crypto_scheme, NetworkSchemeFlag, + OutputTypeFlag, CryptoSchemeFlag, Error, +}; +use structopt::StructOpt; +/// The `inspect` command +#[derive(Debug, StructOpt)] +#[structopt( + name = "inspect-key", + about = "Gets a public key and a SS58 address from the provided Secret URI" +)] +pub struct InspectKeyCmd { + /// A Key URI to be inspected. May be a secret seed, secret URI + /// (with derivation paths and password), SS58 or public URI. + /// + /// If the given value is a file, the file content will be used + /// as URI. + /// + /// If omitted, you will be prompted for the URI. + uri: Option, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub keystore_params: KeystoreParams, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub network_scheme: NetworkSchemeFlag, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub output_scheme: OutputTypeFlag, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub crypto_scheme: CryptoSchemeFlag, +} + +impl InspectKeyCmd { + /// Run the command + pub fn run(&self) -> Result<(), Error> { + let uri = utils::read_uri(self.uri.as_ref())?; + let password = self.keystore_params.read_password()?; + + use utils::print_from_uri; + with_crypto_scheme!( + self.crypto_scheme.scheme, + print_from_uri( + &uri, + password, + self.network_scheme.network.clone(), + self.output_scheme.output_type.clone() + ) + ); + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use structopt::StructOpt; + + #[test] + fn inspect() { + let words = + "remember fiber forum demise paper uniform squirrel feel access exclude casual effort"; + let seed = "0xad1fb77243b536b90cfe5f0d351ab1b1ac40e3890b41dc64f766ee56340cfca5"; + + let inspect = + InspectKeyCmd::from_iter(&["inspect-key", words, "--password", "12345"]); + assert!(inspect.run().is_ok()); + + let inspect = InspectKeyCmd::from_iter(&["inspect-key", seed]); + assert!(inspect.run().is_ok()); + } +} diff --git a/client/cli/src/commands/inspect_node_key.rs b/client/cli/src/commands/inspect_node_key.rs new file mode 100644 index 0000000000000000000000000000000000000000..be0b88589d5e9dfd2cc84d0a543ba2ccb4cd836f --- /dev/null +++ b/client/cli/src/commands/inspect_node_key.rs @@ -0,0 +1,75 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Implementation of the `inspect-node-key` subcommand + +use crate::{Error, NetworkSchemeFlag}; +use std::fs; +use libp2p::identity::{PublicKey, ed25519}; +use std::path::PathBuf; +use structopt::StructOpt; + +/// The `inspect-node-key` command +#[derive(Debug, StructOpt)] +#[structopt( + name = "inspect-node-key", + about = "Print the peer ID corresponding to the node key in the given file." +)] +pub struct InspectNodeKeyCmd { + /// Name of file to read the secret key from. + #[structopt(long)] + file: PathBuf, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub network_scheme: NetworkSchemeFlag, +} + +impl InspectNodeKeyCmd { + /// runs the command + pub fn run(&self) -> Result<(), Error> { + let mut file_content = hex::decode(fs::read(&self.file)?) + .map_err(|_| "failed to decode secret as hex")?; + let secret = ed25519::SecretKey::from_bytes(&mut file_content) + .map_err(|_| "Bad node key file")?; + + let keypair = ed25519::Keypair::from(secret); + let peer_id = PublicKey::Ed25519(keypair.public()).into_peer_id(); + + println!("{}", peer_id); + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use super::super::GenerateNodeKeyCmd; + + #[test] + fn inspect_node_key() { + let path = tempfile::tempdir().unwrap().into_path().join("node-id").into_os_string(); + let path = path.to_str().unwrap(); + let cmd = GenerateNodeKeyCmd::from_iter(&["generate-node-key", "--file", path.clone()]); + + assert!(cmd.run().is_ok()); + + let cmd = InspectNodeKeyCmd::from_iter(&["inspect-node-key", "--file", path]); + assert!(cmd.run().is_ok()); + } +} diff --git a/client/cli/src/commands/key.rs b/client/cli/src/commands/key.rs new file mode 100644 index 0000000000000000000000000000000000000000..50142208b881d180d9c13d502e38f780c30a2fac --- /dev/null +++ b/client/cli/src/commands/key.rs @@ -0,0 +1,61 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Key related CLI utilities + +use crate::Error; +use structopt::StructOpt; + +use super::{ + insert::InsertCmd, + inspect::InspectKeyCmd, + generate::GenerateCmd, + inspect_node_key::InspectNodeKeyCmd, + generate_node_key::GenerateNodeKeyCmd, +}; + +/// key utilities for the cli. +#[derive(Debug, StructOpt)] +pub enum KeySubcommand { + /// Generate a random node libp2p key, save it to file and print its peer ID + GenerateNodeKey(GenerateNodeKeyCmd), + + /// Generate a random account + Generate(GenerateCmd), + + /// Gets a public key and a SS58 address from the provided Secret URI + InspectKey(InspectKeyCmd), + + /// Print the peer ID corresponding to the node key in the given file + InspectNodeKey(InspectNodeKeyCmd), + + /// Insert a key to the keystore of a node. + Insert(InsertCmd), +} + +impl KeySubcommand { + /// run the key subcommands + pub fn run(&self) -> Result<(), Error> { + match self { + KeySubcommand::GenerateNodeKey(cmd) => cmd.run(), + KeySubcommand::Generate(cmd) => cmd.run(), + KeySubcommand::InspectKey(cmd) => cmd.run(), + KeySubcommand::Insert(cmd) => cmd.run(), + KeySubcommand::InspectNodeKey(cmd) => cmd.run(), + } + } +} diff --git a/client/cli/src/commands/mod.rs b/client/cli/src/commands/mod.rs index 54a6f9b74322182400e2673c85cbdf1a1db782b7..108c38b19db3065662e22f3c589d0e5afabd3a2f 100644 --- a/client/cli/src/commands/mod.rs +++ b/client/cli/src/commands/mod.rs @@ -1,45 +1,68 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - +// along with this program. If not, see . mod build_spec_cmd; mod check_block_cmd; mod export_blocks_cmd; mod export_state_cmd; mod import_blocks_cmd; mod purge_chain_cmd; +mod sign; +mod verify; +mod vanity; mod revert_cmd; mod run_cmd; +mod generate_node_key; +mod generate; +mod insert; +mod inspect_node_key; +mod inspect; +mod key; +pub mod utils; -pub use self::build_spec_cmd::BuildSpecCmd; -pub use self::check_block_cmd::CheckBlockCmd; -pub use self::export_blocks_cmd::ExportBlocksCmd; -pub use self::import_blocks_cmd::ImportBlocksCmd; -pub use self::purge_chain_cmd::PurgeChainCmd; -pub use self::revert_cmd::RevertCmd; -pub use self::run_cmd::RunCmd; -pub use self::export_state_cmd::ExportStateCmd; use std::fmt::Debug; use structopt::StructOpt; +pub use self::{ + build_spec_cmd::BuildSpecCmd, + check_block_cmd::CheckBlockCmd, + export_blocks_cmd::ExportBlocksCmd, + export_state_cmd::ExportStateCmd, + import_blocks_cmd::ImportBlocksCmd, + purge_chain_cmd::PurgeChainCmd, + sign::SignCmd, + generate::GenerateCmd, + insert::InsertCmd, + inspect::InspectKeyCmd, + generate_node_key::GenerateNodeKeyCmd, + inspect_node_key::InspectNodeKeyCmd, + key::KeySubcommand, + vanity::VanityCmd, + verify::VerifyCmd, + revert_cmd::RevertCmd, + run_cmd::RunCmd, +}; + /// All core commands that are provided by default. /// /// The core commands are split into multiple subcommands and `Run` is the default subcommand. From /// the CLI user perspective, it is not visible that `Run` is a subcommand. So, all parameters of /// `Run` are exported as main executable parameters. -#[derive(Debug, Clone, StructOpt)] +#[derive(Debug, StructOpt)] pub enum Subcommand { /// Build a spec.json file, outputs to stdout. BuildSpec(BuildSpecCmd), @@ -53,17 +76,16 @@ pub enum Subcommand { /// Validate a single block. CheckBlock(CheckBlockCmd), + /// Export state as raw chain spec. + ExportState(ExportStateCmd), + /// Revert chain to the previous state. Revert(RevertCmd), /// Remove the whole chain data. PurgeChain(PurgeChainCmd), - - /// Export state as raw chain spec. - ExportState(ExportStateCmd), } -// TODO: move to config.rs? /// Macro that helps implement CliConfiguration on an enum of subcommand automatically /// /// # Example @@ -161,7 +183,7 @@ macro_rules! substrate_cli_subcommands { } } - fn base_path(&self) -> $crate::Result<::std::option::Option<::std::path::PathBuf>> { + fn base_path(&self) -> $crate::Result<::std::option::Option> { match self { $($enum::$variant(cmd) => cmd.base_path()),* } @@ -188,17 +210,24 @@ macro_rules! substrate_cli_subcommands { fn network_config( &self, - chain_spec: &::std::boxed::Box, + chain_spec: &std::boxed::Box, is_dev: bool, - net_config_dir: ::std::path::PathBuf, + net_config_dir: std::path::PathBuf, client_id: &str, node_name: &str, - node_key: ::sc_service::config::NodeKeyConfig, + node_key: sc_service::config::NodeKeyConfig, + default_listen_port: u16, ) -> $crate::Result<::sc_service::config::NetworkConfiguration> { match self { $( $enum::$variant(cmd) => cmd.network_config( - chain_spec, is_dev, net_config_dir, client_id, node_name, node_key + chain_spec, + is_dev, + net_config_dir, + client_id, + node_name, + node_key, + default_listen_port, ) ),* } @@ -277,22 +306,34 @@ macro_rules! substrate_cli_subcommands { } } - fn execution_strategies(&self, is_dev: bool) + fn execution_strategies(&self, is_dev: bool, is_validator: bool) -> $crate::Result<::sc_client_api::execution_extensions::ExecutionStrategies> { match self { - $($enum::$variant(cmd) => cmd.execution_strategies(is_dev)),* + $($enum::$variant(cmd) => cmd.execution_strategies(is_dev, is_validator)),* + } + } + + fn rpc_ipc(&self) -> $crate::Result<::std::option::Option<::std::string::String>> { + match self { + $($enum::$variant(cmd) => cmd.rpc_ipc()),* } } - fn rpc_http(&self) -> $crate::Result<::std::option::Option<::std::net::SocketAddr>> { + fn rpc_http( + &self, + default_listen_port: u16, + ) -> $crate::Result> { match self { - $($enum::$variant(cmd) => cmd.rpc_http()),* + $($enum::$variant(cmd) => cmd.rpc_http(default_listen_port)),* } } - fn rpc_ws(&self) -> $crate::Result<::std::option::Option<::std::net::SocketAddr>> { + fn rpc_ws( + &self, + default_listen_port: u16, + ) -> $crate::Result> { match self { - $($enum::$variant(cmd) => cmd.rpc_ws()),* + $($enum::$variant(cmd) => cmd.rpc_ws(default_listen_port)),* } } @@ -309,23 +350,23 @@ macro_rules! substrate_cli_subcommands { } fn rpc_cors(&self, is_dev: bool) - -> $crate::Result<::std::option::Option<::std::vec::Vec>> { + -> $crate::Result>> { match self { $($enum::$variant(cmd) => cmd.rpc_cors(is_dev)),* } } - fn prometheus_config(&self) - -> $crate::Result<::std::option::Option<::sc_service::config::PrometheusConfig>> { + fn prometheus_config(&self, default_listen_port: u16) + -> $crate::Result> { match self { - $($enum::$variant(cmd) => cmd.prometheus_config()),* + $($enum::$variant(cmd) => cmd.prometheus_config(default_listen_port)),* } } fn telemetry_endpoints( &self, - chain_spec: &Box, - ) -> $crate::Result<::std::option::Option<::sc_service::config::TelemetryEndpoints>> { + chain_spec: &Box, + ) -> $crate::Result> { match self { $($enum::$variant(cmd) => cmd.telemetry_endpoints(chain_spec)),* } @@ -406,6 +447,12 @@ macro_rules! substrate_cli_subcommands { } substrate_cli_subcommands!( - Subcommand => BuildSpec, ExportBlocks, ImportBlocks, CheckBlock, Revert, PurgeChain, ExportState + Subcommand => + BuildSpec, + ExportBlocks, + ExportState, + ImportBlocks, + CheckBlock, + Revert, + PurgeChain ); - diff --git a/client/cli/src/commands/purge_chain_cmd.rs b/client/cli/src/commands/purge_chain_cmd.rs index b3fb0de2470de36038f6c478d1145b3c9b923ade..9c9c6e91fb2416c56e8a6e9a3894a8a7aeb31c10 100644 --- a/client/cli/src/commands/purge_chain_cmd.rs +++ b/client/cli/src/commands/purge_chain_cmd.rs @@ -1,30 +1,32 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error; use crate::params::{DatabaseParams, SharedParams}; use crate::CliConfiguration; -use sc_service::Configuration; +use sc_service::DatabaseConfig; use std::fmt::Debug; use std::fs; use std::io::{self, Write}; use structopt::StructOpt; /// The `purge-chain` command used to remove the whole chain. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct PurgeChainCmd { /// Skip interactive prompt by answering yes automatically. #[structopt(short = "y")] @@ -41,8 +43,8 @@ pub struct PurgeChainCmd { impl PurgeChainCmd { /// Run the purge command - pub fn run(&self, config: Configuration) -> error::Result<()> { - let db_path = config.database.path() + pub fn run(&self, database_config: DatabaseConfig) -> error::Result<()> { + let db_path = database_config.path() .ok_or_else(|| error::Error::Input("Cannot purge custom database implementation".into()) )?; diff --git a/client/cli/src/commands/revert_cmd.rs b/client/cli/src/commands/revert_cmd.rs index f7629ff2f6357e71ed417b0bad6d6ad1fc96851b..b2e3c1bf8e2b674e4313253aa6abd2431701d587 100644 --- a/client/cli/src/commands/revert_cmd.rs +++ b/client/cli/src/commands/revert_cmd.rs @@ -1,33 +1,38 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error; -use crate::params::{BlockNumber, PruningParams, SharedParams}; +use crate::params::{GenericNumber, PruningParams, SharedParams}; use crate::CliConfiguration; -use sc_service::{Configuration, ServiceBuilderCommand}; +use sc_service::chain_ops::revert_chain; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use std::fmt::Debug; +use std::str::FromStr; +use std::sync::Arc; use structopt::StructOpt; +use sc_client_api::{Backend, UsageProvider}; /// The `revert` command used revert the chain to a previous state. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct RevertCmd { /// Number of blocks to revert. #[structopt(default_value = "256")] - pub num: BlockNumber, + pub num: GenericNumber, #[allow(missing_docs)] #[structopt(flatten)] @@ -40,16 +45,19 @@ pub struct RevertCmd { impl RevertCmd { /// Run the revert command - pub fn run(&self, config: Configuration, builder: B) -> error::Result<()> + pub async fn run( + &self, + client: Arc, + backend: Arc, + ) -> error::Result<()> where - B: FnOnce(Configuration) -> Result, - BC: ServiceBuilderCommand + Unpin, - BB: sp_runtime::traits::Block + Debug, - <<::Header as HeaderT>::Number as std::str::FromStr>::Err: std::fmt::Debug, - ::Hash: std::str::FromStr, + B: BlockT, + BA: Backend, + C: UsageProvider, + <<::Header as HeaderT>::Number as FromStr>::Err: Debug, { let blocks = self.num.parse()?; - builder(config)?.revert_chain(blocks)?; + revert_chain(client, backend, blocks)?; Ok(()) } diff --git a/client/cli/src/commands/run_cmd.rs b/client/cli/src/commands/run_cmd.rs index f7cec61df1b22b01e7efc4b901f7cf50e1ba3a6f..019b760e5b4aefc394b01fb29e29ece2ee1956e8 100644 --- a/client/cli/src/commands/run_cmd.rs +++ b/client/cli/src/commands/run_cmd.rs @@ -1,31 +1,33 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::arg_enums::RpcMethods; use crate::error::{Error, Result}; use crate::params::ImportParams; use crate::params::KeystoreParams; use crate::params::NetworkParams; +use crate::params::OffchainWorkerParams; use crate::params::SharedParams; use crate::params::TransactionPoolParams; -use crate::params::OffchainWorkerParams; use crate::CliConfiguration; use regex::Regex; use sc_service::{ - config::{MultiaddrWithPeerId, PrometheusConfig, TransactionPoolOptions}, + config::{BasePath, MultiaddrWithPeerId, PrometheusConfig, TransactionPoolOptions}, ChainSpec, Role, }; use sc_telemetry::TelemetryEndpoints; @@ -33,7 +35,7 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use structopt::StructOpt; /// The `run` command used to run a node. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct RunCmd { /// Enable validator mode. /// @@ -63,7 +65,7 @@ pub struct RunCmd { pub sentry: Vec, /// Disable GRANDPA voter when running in validator mode, otherwise disable the GRANDPA observer. - #[structopt(long = "no-grandpa")] + #[structopt(long)] pub no_grandpa: bool, /// Experimental: Run in light client mode. @@ -120,6 +122,10 @@ pub struct RunCmd { #[structopt(long = "prometheus-external")] pub prometheus_external: bool, + /// Specify IPC RPC server path + #[structopt(long = "ipc-path", value_name = "PATH")] + pub ipc_path: Option, + /// Specify HTTP RPC server TCP port. #[structopt(long = "rpc-port", value_name = "PORT")] pub rpc_port: Option, @@ -248,6 +254,16 @@ pub struct RunCmd { conflicts_with_all = &[ "sentry", "public-addr" ] )] pub sentry_nodes: Vec, + + /// Run a temporary node. + /// + /// A temporary directory will be created to store the configuration and will be deleted + /// at the end of the process. + /// + /// Note: the directory is random per process execution. This directory is used as base path + /// which includes: database, node key and keystore. + #[structopt(long, conflicts_with = "base-path")] + pub tmp: bool, } impl RunCmd { @@ -309,7 +325,7 @@ impl CliConfiguration for RunCmd { Error::Input(format!( "Invalid node name '{}'. Reason: {}. If unsure, use none.", name, msg - )); + )) })?; Ok(name) @@ -366,7 +382,7 @@ impl CliConfiguration for RunCmd { Ok(self.shared_params.dev || self.force_authoring) } - fn prometheus_config(&self) -> Result> { + fn prometheus_config(&self, default_listen_port: u16) -> Result> { Ok(if self.no_prometheus { None } else { @@ -377,7 +393,10 @@ impl CliConfiguration for RunCmd { }; Some(PrometheusConfig::new_with_default_registry( - SocketAddr::new(interface.into(), self.prometheus_port.unwrap_or(9615)) + SocketAddr::new( + interface.into(), + self.prometheus_port.unwrap_or(default_listen_port), + ) )) }) } @@ -411,7 +430,7 @@ impl CliConfiguration for RunCmd { .into()) } - fn rpc_http(&self) -> Result> { + fn rpc_http(&self, default_listen_port: u16) -> Result> { let interface = rpc_interface( self.rpc_external, self.unsafe_rpc_external, @@ -419,18 +438,22 @@ impl CliConfiguration for RunCmd { self.validator )?; - Ok(Some(SocketAddr::new(interface, self.rpc_port.unwrap_or(9933)))) + Ok(Some(SocketAddr::new(interface, self.rpc_port.unwrap_or(default_listen_port)))) } - fn rpc_ws(&self) -> Result> { + fn rpc_ipc(&self) -> Result> { + Ok(self.ipc_path.clone()) + } + + fn rpc_ws(&self, default_listen_port: u16) -> Result> { let interface = rpc_interface( self.ws_external, self.unsafe_ws_external, self.rpc_methods, - self.validator + self.validator, )?; - Ok(Some(SocketAddr::new(interface, self.ws_port.unwrap_or(9944)))) + Ok(Some(SocketAddr::new(interface, self.ws_port.unwrap_or(default_listen_port)))) } fn rpc_methods(&self) -> Result { @@ -444,6 +467,14 @@ impl CliConfiguration for RunCmd { fn max_runtime_instances(&self) -> Result> { Ok(self.max_runtime_instances.map(|x| x.min(256))) } + + fn base_path(&self) -> Result> { + Ok(if self.tmp { + Some(BasePath::new_temp_dir()?) + } else { + self.shared_params().base_path() + }) + } } /// Check whether a node name is considered as valid. @@ -582,7 +613,9 @@ mod tests { #[test] fn tests_node_name_bad() { - assert!(is_node_name_valid("long names are not very cool for the ui").is_err()); + assert!(is_node_name_valid( + "very very long names are really not very cool for the ui at all, really they're not" + ).is_err()); assert!(is_node_name_valid("Dots.not.Ok").is_err()); assert!(is_node_name_valid("http://visit.me").is_err()); assert!(is_node_name_valid("https://visit.me").is_err()); diff --git a/client/cli/src/commands/sign.rs b/client/cli/src/commands/sign.rs new file mode 100644 index 0000000000000000000000000000000000000000..605fd5b12313f0c75fee8eef4951fafe9ee9f680 --- /dev/null +++ b/client/cli/src/commands/sign.rs @@ -0,0 +1,98 @@ +// This file is part of Substrate. + +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +//! Implementation of the `sign` subcommand +use crate::{error, utils, with_crypto_scheme, CryptoSchemeFlag, KeystoreParams}; +use structopt::StructOpt; +use sp_core::crypto::SecretString; + +/// The `sign` command +#[derive(Debug, StructOpt)] +#[structopt( + name = "sign", + about = "Sign a message, with a given (secret) key" +)] +pub struct SignCmd { + /// The secret key URI. + /// If the value is a file, the file content is used as URI. + /// If not given, you will be prompted for the URI. + #[structopt(long)] + suri: Option, + + /// Message to sign, if not provided you will be prompted to + /// pass the message via STDIN + #[structopt(long)] + message: Option, + + /// The message on STDIN is hex-encoded data + #[structopt(long)] + hex: bool, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub keystore_params: KeystoreParams, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub crypto_scheme: CryptoSchemeFlag, +} + + +impl SignCmd { + /// Run the command + pub fn run(&self) -> error::Result<()> { + let message = utils::read_message(self.message.as_ref(), self.hex)?; + let suri = utils::read_uri(self.suri.as_ref())?; + let password = self.keystore_params.read_password()?; + + let signature = with_crypto_scheme!( + self.crypto_scheme.scheme, + sign(&suri, password, message) + )?; + + println!("{}", signature); + Ok(()) + } +} + +fn sign(suri: &str, password: Option, message: Vec) -> error::Result { + let pair = utils::pair_from_suri::

(suri, password)?; + Ok(format!("{}", hex::encode(pair.sign(&message)))) +} + +#[cfg(test)] +mod test { + use super::SignCmd; + use structopt::StructOpt; + + #[test] + fn sign() { + let seed = "0xad1fb77243b536b90cfe5f0d351ab1b1ac40e3890b41dc64f766ee56340cfca5"; + + let sign = SignCmd::from_iter(&[ + "sign", + "--suri", + seed, + "--message", + &seed[2..], + "--password", + "12345" + ]); + assert!(sign.run().is_ok()); + } +} diff --git a/client/cli/src/commands/utils.rs b/client/cli/src/commands/utils.rs new file mode 100644 index 0000000000000000000000000000000000000000..a3298b222ad2b9538fed3ef1959ec8f250455bce --- /dev/null +++ b/client/cli/src/commands/utils.rs @@ -0,0 +1,234 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +//! subcommand utilities +use std::{io::Read, path::PathBuf}; +use sp_core::{ + Pair, hexdisplay::HexDisplay, + crypto::{Ss58Codec, Ss58AddressFormat}, +}; +use sp_runtime::{MultiSigner, traits::IdentifyAccount}; +use crate::{OutputType, error::{self, Error}}; +use serde_json::json; +use sp_core::crypto::{SecretString, Zeroize, ExposeSecret}; + +/// Public key type for Runtime +pub type PublicFor

=

::Public; +/// Seed type for Runtime +pub type SeedFor

=

::Seed; + +/// helper method to fetch uri from `Option` either as a file or read from stdin +pub fn read_uri(uri: Option<&String>) -> error::Result { + let uri = if let Some(uri) = uri { + let file = PathBuf::from(&uri); + if file.is_file() { + std::fs::read_to_string(uri)? + .trim_end() + .to_owned() + } else { + uri.into() + } + } else { + rpassword::read_password_from_tty(Some("URI: "))? + }; + + Ok(uri) +} + +/// print formatted pair from uri +pub fn print_from_uri( + uri: &str, + password: Option, + network_override: Option, + output: OutputType, +) where Pair: sp_core::Pair, Pair::Public: Into { + let password = password.as_ref().map(|s| s.expose_secret().as_str()); + if let Ok((pair, seed)) = Pair::from_phrase(uri, password.clone()) { + let public_key = pair.public(); + let network_override = network_override.unwrap_or_default(); + + match output { + OutputType::Json => { + let json = json!({ + "secretPhrase": uri, + "secretSeed": format_seed::(seed), + "publicKey": format_public_key::(public_key.clone()), + "accountId": format_account_id::(public_key), + "ss58Address": pair.public().into().into_account().to_ss58check_with_version(network_override), + }); + println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); + }, + OutputType::Text => { + println!( + "Secret phrase `{}` is account:\n \ + Secret seed: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", + uri, + format_seed::(seed), + format_public_key::(public_key.clone()), + format_account_id::(public_key), + pair.public().into().into_account().to_ss58check_with_version(network_override), + ); + }, + } + } else if let Ok((pair, seed)) = Pair::from_string_with_seed(uri, password.clone()) { + let public_key = pair.public(); + let network_override = network_override.unwrap_or_default(); + + match output { + OutputType::Json => { + let json = json!({ + "secretKeyUri": uri, + "secretSeed": if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, + "publicKey": format_public_key::(public_key.clone()), + "accountId": format_account_id::(public_key), + "ss58Address": pair.public().into().into_account().to_ss58check_with_version(network_override), + }); + println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); + }, + OutputType::Text => { + println!( + "Secret Key URI `{}` is account:\n \ + Secret seed: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", + uri, + if let Some(seed) = seed { format_seed::(seed) } else { "n/a".into() }, + format_public_key::(public_key.clone()), + format_account_id::(public_key), + pair.public().into().into_account().to_ss58check_with_version(network_override), + ); + }, + } + } else if let Ok((public_key, network)) = Pair::Public::from_string_with_version(uri) { + let network_override = network_override.unwrap_or(network); + + match output { + OutputType::Json => { + let json = json!({ + "publicKeyUri": uri, + "networkId": String::from(network_override), + "publicKey": format_public_key::(public_key.clone()), + "accountId": format_account_id::(public_key.clone()), + "ss58Address": public_key.to_ss58check_with_version(network_override), + }); + println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed")); + }, + OutputType::Text => { + println!( + "Public Key URI `{}` is account:\n \ + Network ID/version: {}\n \ + Public key (hex): {}\n \ + Account ID: {}\n \ + SS58 Address: {}", + uri, + String::from(network_override), + format_public_key::(public_key.clone()), + format_account_id::(public_key.clone()), + public_key.to_ss58check_with_version(network_override), + ); + }, + } + } else { + println!("Invalid phrase/URI given"); + } +} + +/// generate a pair from suri +pub fn pair_from_suri(suri: &str, password: Option) -> Result { + let result = if let Some(pass) = password { + let mut pass_str = pass.expose_secret().clone(); + let pair = P::from_string(suri, Some(&pass_str)); + pass_str.zeroize(); + pair + } else { + P::from_string(suri, None) + }; + + Ok(result.map_err(|err| format!("Invalid phrase {:?}", err))?) +} + +/// formats seed as hex +pub fn format_seed(seed: SeedFor

) -> String { + format!("0x{}", HexDisplay::from(&seed.as_ref())) +} + +/// formats public key as hex +fn format_public_key(public_key: PublicFor

) -> String { + format!("0x{}", HexDisplay::from(&public_key.as_ref())) +} + +/// formats public key as accountId as hex +fn format_account_id(public_key: PublicFor

) -> String + where + PublicFor

: Into, +{ + format!("0x{}", HexDisplay::from(&public_key.into().into_account().as_ref())) +} + +/// helper method for decoding hex +pub fn decode_hex>(message: T) -> Result, Error> { + let mut message = message.as_ref(); + if message[..2] == [b'0', b'x'] { + message = &message[2..] + } + hex::decode(message) + .map_err(|e| Error::Other(format!("Invalid hex ({})", e))) +} + +/// checks if message is Some, otherwise reads message from stdin and optionally decodes hex +pub fn read_message(msg: Option<&String>, should_decode: bool) -> Result, Error> { + let mut message = vec![]; + match msg { + Some(m) => { + message = decode_hex(m)?; + }, + None => { + std::io::stdin().lock().read_to_end(&mut message)?; + if should_decode { + message = decode_hex(&message)?; + } + } + } + Ok(message) +} + + +/// Allows for calling $method with appropriate crypto impl. +#[macro_export] +macro_rules! with_crypto_scheme { + ($scheme:expr, $method:ident($($params:expr),*)) => { + with_crypto_scheme!($scheme, $method<>($($params),*)) + }; + ($scheme:expr, $method:ident<$($generics:ty),*>($($params:expr),*)) => { + match $scheme { + $crate::CryptoScheme::Ecdsa => { + $method::($($params),*) + } + $crate::CryptoScheme::Sr25519 => { + $method::($($params),*) + } + $crate::CryptoScheme::Ed25519 => { + $method::($($params),*) + } + } + }; +} diff --git a/client/cli/src/commands/vanity.rs b/client/cli/src/commands/vanity.rs new file mode 100644 index 0000000000000000000000000000000000000000..e6f923f73c45c74aa4563f64aaf10fedcf580ae5 --- /dev/null +++ b/client/cli/src/commands/vanity.rs @@ -0,0 +1,232 @@ +// This file is part of Substrate. + +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +//! implementation of the `vanity` subcommand + +use crate::{ + error, utils, with_crypto_scheme, + CryptoSchemeFlag, NetworkSchemeFlag, OutputTypeFlag, +}; +use sp_core::crypto::Ss58Codec; +use structopt::StructOpt; +use rand::{rngs::OsRng, RngCore}; +use sp_runtime::traits::IdentifyAccount; + +/// The `vanity` command +#[derive(Debug, StructOpt)] +#[structopt( + name = "vanity", + about = "Generate a seed that provides a vanity address" +)] +pub struct VanityCmd { + /// Desired pattern + #[structopt(long, parse(try_from_str = assert_non_empty_string))] + pattern: String, + + #[allow(missing_docs)] + #[structopt(flatten)] + network_scheme: NetworkSchemeFlag, + + #[allow(missing_docs)] + #[structopt(flatten)] + output_scheme: OutputTypeFlag, + + #[allow(missing_docs)] + #[structopt(flatten)] + crypto_scheme: CryptoSchemeFlag, +} + +impl VanityCmd { + /// Run the command + pub fn run(&self) -> error::Result<()> { + let formated_seed = with_crypto_scheme!(self.crypto_scheme.scheme, generate_key(&self.pattern))?; + use utils::print_from_uri; + with_crypto_scheme!( + self.crypto_scheme.scheme, + print_from_uri( + &formated_seed, + None, + self.network_scheme.network.clone(), + self.output_scheme.output_type.clone() + ) + ); + Ok(()) + } +} + +/// genertae a key based on given pattern +fn generate_key(desired: &str) -> Result + where + Pair: sp_core::Pair, + Pair::Public: IdentifyAccount, + ::AccountId: Ss58Codec, +{ + println!("Generating key containing pattern '{}'", desired); + + let top = 45 + (desired.len() * 48); + let mut best = 0; + let mut seed = Pair::Seed::default(); + let mut done = 0; + + loop { + if done % 100000 == 0 { + OsRng.fill_bytes(seed.as_mut()); + } else { + next_seed(seed.as_mut()); + } + + let p = Pair::from_seed(&seed); + let ss58 = p.public().into_account().to_ss58check(); + let score = calculate_score(&desired, &ss58); + if score > best || desired.len() < 2 { + best = score; + if best >= top { + println!("best: {} == top: {}", best, top); + return Ok(utils::format_seed::(seed.clone())); + } + } + done += 1; + + if done % good_waypoint(done) == 0 { + println!("{} keys searched; best is {}/{} complete", done, best, top); + } + } +} + +fn good_waypoint(done: u64) -> u64 { + match done { + 0..=1_000_000 => 100_000, + 0..=10_000_000 => 1_000_000, + 0..=100_000_000 => 10_000_000, + _ => 100_000_000, + } +} + +fn next_seed(seed: &mut [u8]) { + for i in 0..seed.len() { + match seed[i] { + 255 => { + seed[i] = 0; + } + _ => { + seed[i] += 1; + break; + } + } + } +} + +/// Calculate the score of a key based on the desired +/// input. +fn calculate_score(_desired: &str, key: &str) -> usize { + for truncate in 0.._desired.len() { + let snip_size = _desired.len() - truncate; + let truncated = &_desired[0..snip_size]; + if let Some(pos) = key.find(truncated) { + return (47 - pos) + (snip_size * 48); + } + } + 0 +} + +/// checks that `pattern` is non-empty +fn assert_non_empty_string(pattern: &str) -> Result { + if pattern.is_empty() { + Err("Pattern must not be empty") + } else { + Ok(pattern.to_string()) + } +} + + +#[cfg(test)] +mod tests { + use super::*; + use sp_core::{crypto::Ss58Codec, Pair}; + use sp_core::sr25519; + #[cfg(feature = "bench")] + use test::Bencher; + use structopt::StructOpt; + + #[test] + fn vanity() { + let vanity = VanityCmd::from_iter(&["vanity", "--pattern", "j"]); + assert!(vanity.run().is_ok()); + } + + #[test] + fn test_generation_with_single_char() { + let seed = generate_key::("j").unwrap(); + assert!( + sr25519::Pair::from_seed_slice(&hex::decode(&seed[2..]).unwrap()) + .unwrap() + .public() + .to_ss58check() + .contains("j")); + } + + #[test] + fn test_score_1_char_100() { + let score = calculate_score("j", "5jolkadotwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim"); + assert_eq!(score, 94); + } + + #[test] + fn test_score_100() { + let score = calculate_score( + "Polkadot", + "5PolkadotwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim", + ); + assert_eq!(score, 430); + } + + #[test] + fn test_score_50_2() { + // 50% for the position + 50% for the size + assert_eq!( + calculate_score( + "Polkadot", + "5PolkXXXXwHY5k9GpdTgpqs9xjuNvtv8EcwCFpEeyEf3KHim" + ), + 238 + ); + } + + #[test] + fn test_score_0() { + assert_eq!( + calculate_score( + "Polkadot", + "5GUWv4bLCchGUHJrzULXnh4JgXsMpTKRnjuXTY7Qo1Kh9uYK" + ), + 0 + ); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_paranoiac(b: &mut Bencher) { + b.iter(|| generate_key("polk")); + } + + #[cfg(feature = "bench")] + #[bench] + fn bench_not_paranoiac(b: &mut Bencher) { + b.iter(|| generate_key("polk")); + } +} diff --git a/client/cli/src/commands/verify.rs b/client/cli/src/commands/verify.rs new file mode 100644 index 0000000000000000000000000000000000000000..ad16c11d5e4415dce429aab64663f10e0cfb71ce --- /dev/null +++ b/client/cli/src/commands/verify.rs @@ -0,0 +1,104 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +//! implementation of the `verify` subcommand + +use crate::{error, utils, with_crypto_scheme, CryptoSchemeFlag}; +use sp_core::{Public, crypto::Ss58Codec}; +use structopt::StructOpt; + +/// The `verify` command +#[derive(Debug, StructOpt)] +#[structopt( + name = "verify", + about = "Verify a signature for a message, provided on STDIN, with a given (public or secret) key" +)] +pub struct VerifyCmd { + /// Signature, hex-encoded. + sig: String, + + /// The public or secret key URI. + /// If the value is a file, the file content is used as URI. + /// If not given, you will be prompted for the URI. + uri: Option, + + /// Message to verify, if not provided you will be prompted to + /// pass the message via STDIN + #[structopt(long)] + message: Option, + + /// The message on STDIN is hex-encoded data + #[structopt(long)] + hex: bool, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub crypto_scheme: CryptoSchemeFlag, +} + +impl VerifyCmd { + /// Run the command + pub fn run(&self) -> error::Result<()> { + let message = utils::read_message(self.message.as_ref(), self.hex)?; + let sig_data = utils::decode_hex(&self.sig)?; + let uri = utils::read_uri(self.uri.as_ref())?; + let uri = if uri.starts_with("0x") { + &uri[2..] + } else { + &uri + }; + + with_crypto_scheme!( + self.crypto_scheme.scheme, + verify(sig_data, message, uri) + ) + } +} + +fn verify(sig_data: Vec, message: Vec, uri: &str) -> error::Result<()> + where + Pair: sp_core::Pair, + Pair::Signature: Default + AsMut<[u8]>, +{ + let mut signature = Pair::Signature::default(); + if sig_data.len() != signature.as_ref().len() { + return Err(error::Error::Other(format!( + "signature has an invalid length. read {} bytes, expected {} bytes", + sig_data.len(), + signature.as_ref().len(), + ))); + } + signature.as_mut().copy_from_slice(&sig_data); + + let pubkey = if let Ok(pubkey_vec) = hex::decode(uri) { + Pair::Public::from_slice(pubkey_vec.as_slice()) + } else { + Pair::Public::from_string(uri) + .map_err(|_| { + error::Error::Other(format!("Invalid URI; expecting either a secret URI or a public URI.")) + })? + }; + + if Pair::verify(&signature, &message, &pubkey) { + println!("Signature verifies correctly."); + } else { + return Err(error::Error::Other("Signature invalid.".into())) + } + + Ok(()) +} diff --git a/client/cli/src/config.rs b/client/cli/src/config.rs index 56830f20763283fece19b1cdd7cceaf6dd543d71..ff0222216ce15f4aa30c49167592e32ed066ade2 100644 --- a/client/cli/src/config.rs +++ b/client/cli/src/config.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Configuration trait for a CLI based on substrate @@ -22,29 +24,61 @@ use crate::{ init_logger, DatabaseParams, ImportParams, KeystoreParams, NetworkParams, NodeKeyParams, OffchainWorkerParams, PruningParams, SharedParams, SubstrateCli, }; -use app_dirs::{AppDataType, AppInfo}; use names::{Generator, Name}; use sc_client_api::execution_extensions::ExecutionStrategies; use sc_service::config::{ - Configuration, DatabaseConfig, ExtTransport, KeystoreConfig, NetworkConfiguration, + BasePath, Configuration, DatabaseConfig, ExtTransport, KeystoreConfig, NetworkConfiguration, NodeKeyConfig, OffchainWorkerConfig, PrometheusConfig, PruningMode, Role, RpcMethods, - TaskType, TelemetryEndpoints, TransactionPoolOptions, WasmExecutionMethod, + TaskExecutor, TelemetryEndpoints, TransactionPoolOptions, WasmExecutionMethod, }; use sc_service::{ChainSpec, TracingReceiver}; -use std::future::Future; use std::net::SocketAddr; use std::path::PathBuf; -use std::pin::Pin; -use std::sync::Arc; /// The maximum number of characters for a node name. -pub(crate) const NODE_NAME_MAX_LENGTH: usize = 32; +pub(crate) const NODE_NAME_MAX_LENGTH: usize = 64; /// default sub directory to store network config pub(crate) const DEFAULT_NETWORK_CONFIG_PATH: &'static str = "network"; +/// Default configuration values used by Substrate +/// +/// These values will be used by [`CliConfiguritation`] to set +/// default values for e.g. the listen port or the RPC port. +pub trait DefaultConfigurationValues { + /// The port Substrate should listen on for p2p connections. + /// + /// By default this is `30333`. + fn p2p_listen_port() -> u16 { + 30333 + } + + /// The port Substrate should listen on for websocket connections. + /// + /// By default this is `9944`. + fn rpc_ws_listen_port() -> u16 { + 9944 + } + + /// The port Substrate should listen on for http connections. + /// + /// By default this is `9933`. + fn rpc_http_listen_port() -> u16 { + 9933 + } + + /// The port Substrate should listen on for prometheus connections. + /// + /// By default this is `9615`. + fn prometheus_listen_port() -> u16 { + 9615 + } +} + +impl DefaultConfigurationValues for () {} + /// A trait that allows converting an object to a Configuration -pub trait CliConfiguration: Sized { +pub trait CliConfiguration: Sized { /// Get the SharedParams for this object fn shared_params(&self) -> &SharedParams; @@ -86,7 +120,7 @@ pub trait CliConfiguration: Sized { /// Get the base path of the configuration (if any) /// /// By default this is retrieved from `SharedParams`. - fn base_path(&self) -> Result> { + fn base_path(&self) -> Result> { Ok(self.shared_params().base_path()) } @@ -124,6 +158,7 @@ pub trait CliConfiguration: Sized { client_id: &str, node_name: &str, node_key: NodeKeyConfig, + default_listen_port: u16, ) -> Result { Ok(if let Some(network_params) = self.network_params() { network_params.network_config( @@ -133,6 +168,7 @@ pub trait CliConfiguration: Sized { client_id, node_name, node_key, + default_listen_port, ) } else { NetworkConfiguration::new( @@ -160,7 +196,7 @@ pub trait CliConfiguration: Sized { fn database_cache_size(&self) -> Result> { Ok(self.database_params() .map(|x| x.database_cache_size()) - .unwrap_or(Default::default())) + .unwrap_or_default()) } /// Get the database backend variant. @@ -197,7 +233,7 @@ pub trait CliConfiguration: Sized { fn state_cache_size(&self) -> Result { Ok(self.import_params() .map(|x| x.state_cache_size()) - .unwrap_or(Default::default())) + .unwrap_or_default()) } /// Get the state cache child ratio (if any). @@ -214,7 +250,7 @@ pub trait CliConfiguration: Sized { fn pruning(&self, unsafe_pruning: bool, role: &Role) -> Result { self.pruning_params() .map(|x| x.pruning(unsafe_pruning, role)) - .unwrap_or(Ok(Default::default())) + .unwrap_or_else(|| Ok(Default::default())) } /// Get the chain ID (string). @@ -238,31 +274,43 @@ pub trait CliConfiguration: Sized { fn wasm_method(&self) -> Result { Ok(self.import_params() .map(|x| x.wasm_method()) - .unwrap_or(Default::default())) + .unwrap_or_default()) } /// Get the execution strategies. /// /// By default this is retrieved from `ImportParams` if it is available. Otherwise its /// `ExecutionStrategies::default()`. - fn execution_strategies(&self, is_dev: bool) -> Result { - Ok(self.import_params() - .map(|x| x.execution_strategies(is_dev)) - .unwrap_or(Default::default())) + fn execution_strategies( + &self, + is_dev: bool, + is_validator: bool, + ) -> Result { + Ok(self + .import_params() + .map(|x| x.execution_strategies(is_dev, is_validator)) + .unwrap_or_default()) } /// Get the RPC HTTP address (`None` if disabled). /// /// By default this is `None`. - fn rpc_http(&self) -> Result> { - Ok(Default::default()) + fn rpc_http(&self, _default_listen_port: u16) -> Result> { + Ok(None) + } + + /// Get the RPC IPC path (`None` if disabled). + /// + /// By default this is `None`. + fn rpc_ipc(&self) -> Result> { + Ok(None) } /// Get the RPC websocket address (`None` if disabled). /// /// By default this is `None`. - fn rpc_ws(&self) -> Result> { - Ok(Default::default()) + fn rpc_ws(&self, _default_listen_port: u16) -> Result> { + Ok(None) } /// Returns the RPC method set to expose. @@ -277,12 +325,12 @@ pub trait CliConfiguration: Sized { /// /// By default this is `None`. fn rpc_ws_max_connections(&self) -> Result> { - Ok(Default::default()) + Ok(None) } /// Get the RPC cors (`None` if disabled) /// - /// By default this is `None`. + /// By default this is `Some(Vec::new())`. fn rpc_cors(&self, _is_dev: bool) -> Result>> { Ok(Some(Vec::new())) } @@ -290,8 +338,8 @@ pub trait CliConfiguration: Sized { /// Get the prometheus configuration (`None` if disabled) /// /// By default this is `None`. - fn prometheus_config(&self) -> Result> { - Ok(Default::default()) + fn prometheus_config(&self, _default_listen_port: u16) -> Result> { + Ok(None) } /// Get the telemetry endpoints (if any) @@ -308,14 +356,14 @@ pub trait CliConfiguration: Sized { /// /// By default this is `None`. fn telemetry_external_transport(&self) -> Result> { - Ok(Default::default()) + Ok(None) } /// Get the default value for heap pages /// /// By default this is `None`. fn default_heap_pages(&self) -> Result> { - Ok(Default::default()) + Ok(None) } /// Returns an offchain worker config wrapped in `Ok(_)` @@ -355,7 +403,7 @@ pub trait CliConfiguration: Sized { fn tracing_targets(&self) -> Result> { Ok(self.import_params() .map(|x| x.tracing_targets()) - .unwrap_or(Default::default())) + .unwrap_or_else(|| Default::default())) } /// Get the TracingReceiver value from the current object @@ -365,7 +413,7 @@ pub trait CliConfiguration: Sized { fn tracing_receiver(&self) -> Result { Ok(self.import_params() .map(|x| x.tracing_receiver()) - .unwrap_or(Default::default())) + .unwrap_or_default()) } /// Get the node key from the current object @@ -375,7 +423,7 @@ pub trait CliConfiguration: Sized { fn node_key(&self, net_config_dir: &PathBuf) -> Result { self.node_key_params() .map(|x| x.node_key(net_config_dir)) - .unwrap_or(Ok(Default::default())) + .unwrap_or_else(|| Ok(Default::default())) } /// Get maximum runtime instances @@ -396,23 +444,17 @@ pub trait CliConfiguration: Sized { fn create_configuration( &self, cli: &C, - task_executor: Arc + Send>>, TaskType) + Send + Sync>, + task_executor: TaskExecutor, ) -> Result { let is_dev = self.is_dev()?; let chain_id = self.chain_id(is_dev)?; let chain_spec = cli.load_spec(chain_id.as_str())?; - let config_dir = self + let base_path = self .base_path()? - .unwrap_or_else(|| { - app_dirs::get_app_root( - AppDataType::UserData, - &AppInfo { - name: C::executable_name(), - author: C::author(), - }, - ) - .expect("app directories exist on all supported platforms; qed") - }) + .unwrap_or_else(|| BasePath::from_project("", "", &C::executable_name())); + let config_dir = base_path + .path() + .to_path_buf() .join("chains") .join(chain_spec.id()); let net_config_dir = config_dir.join(DEFAULT_NETWORK_CONFIG_PATH); @@ -422,6 +464,7 @@ pub trait CliConfiguration: Sized { let node_key = self.node_key(&net_config_dir)?; let role = self.role(is_dev)?; let max_runtime_instances = self.max_runtime_instances()?.unwrap_or(8); + let is_validator = role.is_network_authority(); let unsafe_pruning = self .import_params() @@ -440,6 +483,7 @@ pub trait CliConfiguration: Sized { client_id.as_str(), self.node_name()?.as_str(), node_key, + DCV::p2p_listen_port(), )?, keystore: self.keystore_config(&config_dir)?, database: self.database_config(&config_dir, database_cache_size, database)?, @@ -447,13 +491,14 @@ pub trait CliConfiguration: Sized { state_cache_child_ratio: self.state_cache_child_ratio()?, pruning: self.pruning(unsafe_pruning, &role)?, wasm_method: self.wasm_method()?, - execution_strategies: self.execution_strategies(is_dev)?, - rpc_http: self.rpc_http()?, - rpc_ws: self.rpc_ws()?, + execution_strategies: self.execution_strategies(is_dev, is_validator)?, + rpc_http: self.rpc_http(DCV::rpc_http_listen_port())?, + rpc_ws: self.rpc_ws(DCV::rpc_ws_listen_port())?, + rpc_ipc: self.rpc_ipc()?, rpc_methods: self.rpc_methods()?, rpc_ws_max_connections: self.rpc_ws_max_connections()?, rpc_cors: self.rpc_cors(is_dev)?, - prometheus_config: self.prometheus_config()?, + prometheus_config: self.prometheus_config(DCV::prometheus_listen_port())?, telemetry_endpoints: self.telemetry_endpoints(&chain_spec)?, telemetry_external_transport: self.telemetry_external_transport()?, default_heap_pages: self.default_heap_pages()?, @@ -467,6 +512,8 @@ pub trait CliConfiguration: Sized { max_runtime_instances, announce_block: self.announce_block()?, role, + base_path: Some(base_path), + informant_output_format: Default::default(), }) } @@ -490,7 +537,7 @@ pub trait CliConfiguration: Sized { fn init(&self) -> Result<()> { let logger_pattern = self.log_filters()?; - sp_panic_handler::set(C::support_url(), C::impl_version()); + sp_panic_handler::set(&C::support_url(), &C::impl_version()); fdlimit::raise_fd_limit(); init_logger(&logger_pattern); @@ -510,5 +557,5 @@ pub fn generate_node_name() -> String { if count < NODE_NAME_MAX_LENGTH { return node_name; } - }; + } } diff --git a/client/cli/src/error.rs b/client/cli/src/error.rs index edc1adecc762c5f70c11958d1b6f9b0b93863904..7404d31fcf7bbdef22098b61a8eacde696e69e15 100644 --- a/client/cli/src/error.rs +++ b/client/cli/src/error.rs @@ -1,21 +1,25 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Initialization errors. + + /// Result type alias for the CLI. pub type Result = std::result::Result; @@ -25,16 +29,19 @@ pub enum Error { /// Io error Io(std::io::Error), /// Cli error - Cli(clap::Error), + Cli(structopt::clap::Error), /// Service error Service(sc_service::Error), /// Client error Client(sp_blockchain::Error), + /// scale codec error + Codec(parity_scale_codec::Error), /// Input error #[from(ignore)] Input(String), /// Invalid listen multiaddress #[display(fmt="Invalid listen multiaddress")] + #[from(ignore)] InvalidListenMultiaddress, /// Other uncategorized error. #[from(ignore)] @@ -62,6 +69,7 @@ impl std::error::Error for Error { Error::Cli(ref err) => Some(err), Error::Service(ref err) => Some(err), Error::Client(ref err) => Some(err), + Error::Codec(ref err) => Some(err), Error::Input(_) => None, Error::InvalidListenMultiaddress => None, Error::Other(_) => None, diff --git a/client/cli/src/lib.rs b/client/cli/src/lib.rs index e723573bc2bdd43059563c809799e5bdecae7b86..1de74f087f8eecb6594663c33f00ac68f06d9186 100644 --- a/client/cli/src/lib.rs +++ b/client/cli/src/lib.rs @@ -1,25 +1,27 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate CLI library. #![warn(missing_docs)] #![warn(unused_extern_crates)] -mod arg_enums; +pub mod arg_enums; mod commands; mod config; mod error; @@ -35,11 +37,10 @@ use log::info; pub use params::*; use regex::Regex; pub use runner::*; -use sc_service::{ChainSpec, Configuration, TaskType}; -use std::future::Future; +use sc_service::{Configuration, TaskExecutor}; +pub use sc_service::{ChainSpec, Role}; +pub use sp_version::RuntimeVersion; use std::io::Write; -use std::pin::Pin; -use std::sync::Arc; pub use structopt; use structopt::{ clap::{self, AppSettings}, @@ -56,25 +57,33 @@ use structopt::{ /// its own implementation that will fill the necessary field based on the trait's functions. pub trait SubstrateCli: Sized { /// Implementation name. - fn impl_name() -> &'static str; + fn impl_name() -> String; /// Implementation version. /// /// By default this will look like this: 2.0.0-b950f731c-x86_64-linux-gnu where the hash is the /// short commit hash of the commit of in the Git repository. - fn impl_version() -> &'static str; + fn impl_version() -> String; /// Executable file name. - fn executable_name() -> &'static str; + /// + /// Extracts the file name from `std::env::current_exe()`. + /// Resorts to the env var `CARGO_PKG_NAME` in case of Error. + fn executable_name() -> String { + std::env::current_exe().ok() + .and_then(|e| e.file_name().map(|s| s.to_os_string())) + .and_then(|w| w.into_string().ok()) + .unwrap_or_else(|| env!("CARGO_PKG_NAME").into()) + } /// Executable file description. - fn description() -> &'static str; + fn description() -> String; /// Executable file author. - fn author() -> &'static str; + fn author() -> String; /// Support URL. - fn support_url() -> &'static str; + fn support_url() -> String; /// Copyright starting year (x-current year) fn copyright_start_year() -> i32; @@ -115,13 +124,16 @@ pub trait SubstrateCli: Sized { { let app = ::clap(); - let mut full_version = Self::impl_version().to_string(); + let mut full_version = Self::impl_version(); full_version.push_str("\n"); + let name = Self::executable_name(); + let author = Self::author(); + let about = Self::description(); let app = app - .name(Self::executable_name()) - .author(Self::author()) - .about(Self::description()) + .name(name) + .author(author.as_str()) + .about(about.as_str()) .version(full_version.as_str()) .settings(&[ AppSettings::GlobalVersion, @@ -129,7 +141,27 @@ pub trait SubstrateCli: Sized { AppSettings::SubcommandsNegateReqs, ]); - ::from_clap(&app.get_matches_from(iter)) + let matches = match app.get_matches_from_safe(iter) { + Ok(matches) => matches, + Err(mut e) => { + // To support pipes, we can not use `writeln!` as any error + // results in a "broken pipe" error. + // + // Instead we write directly to `stdout` and ignore any error + // as we exit afterwards anyway. + e.message.extend("\n".chars()); + + if e.use_stderr() { + let _ = std::io::stderr().write_all(e.message.as_bytes()); + std::process::exit(1); + } else { + let _ = std::io::stdout().write_all(e.message.as_bytes()); + std::process::exit(0); + } + }, + }; + + ::from_clap(&matches) } /// Helper function used to parse the command line arguments. This is the equivalent of @@ -143,9 +175,9 @@ pub trait SubstrateCli: Sized { /// Print the error message and quit the program in case of failure. /// /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are - /// used. It will return a [`clap::Error`], where the [`kind`] is a - /// [`ErrorKind::HelpDisplayed`] or [`ErrorKind::VersionDisplayed`] respectively. You must call - /// [`Error::exit`] or perform a [`std::process::exit`]. + /// used. It will return a [`clap::Error`], where the [`clap::Error::kind`] is a + /// [`clap::ErrorKind::HelpDisplayed`] or [`clap::ErrorKind::VersionDisplayed`] respectively. + /// You must call [`clap::Error::exit`] or perform a [`std::process::exit`]. fn try_from_iter(iter: I) -> clap::Result where Self: StructOpt + Sized, @@ -154,13 +186,16 @@ pub trait SubstrateCli: Sized { { let app = ::clap(); - let mut full_version = Self::impl_version().to_string(); + let mut full_version = Self::impl_version(); full_version.push_str("\n"); + let name = Self::executable_name(); + let author = Self::author(); + let about = Self::description(); let app = app - .name(Self::executable_name()) - .author(Self::author()) - .about(Self::description()) + .name(name) + .author(author.as_str()) + .about(about.as_str()) .version(full_version.as_str()); let matches = app.get_matches_from_safe(iter)?; @@ -174,10 +209,10 @@ pub trait SubstrateCli: Sized { } /// Only create a Configuration for the command provided in argument - fn create_configuration( + fn create_configuration, DVC: DefaultConfigurationValues>( &self, command: &T, - task_executor: Arc + Send>>, TaskType) + Send + Sync>, + task_executor: TaskExecutor, ) -> error::Result { command.create_configuration(self, task_executor) } @@ -188,6 +223,9 @@ pub trait SubstrateCli: Sized { command.init::()?; Runner::new(self, command) } + + /// Native runtime version. + fn native_runtime_version(chain_spec: &Box) -> &'static RuntimeVersion; } /// Initialize the logger @@ -197,10 +235,12 @@ pub fn init_logger(pattern: &str) { let mut builder = env_logger::Builder::new(); // Disable info logging by default for some modules: builder.filter(Some("ws"), log::LevelFilter::Off); + builder.filter(Some("yamux"), log::LevelFilter::Off); + builder.filter(Some("cranelift_codegen"), log::LevelFilter::Off); builder.filter(Some("hyper"), log::LevelFilter::Warn); builder.filter(Some("cranelift_wasm"), log::LevelFilter::Warn); // Always log the special target `sc_tracing`, overrides global level - builder.filter(Some("sc_tracing"), log::LevelFilter::Info); + builder.filter(Some("sc_tracing"), log::LevelFilter::Trace); // Enable info for others. builder.filter(None, log::LevelFilter::Info); @@ -230,7 +270,7 @@ pub fn init_logger(pattern: &str) { format!("{}", Colour::Blue.bold().paint(x)) }); let millis = (now.tm_nsec as f32 / 1000000.0).floor() as usize; - let timestamp = format!("{}.{}", timestamp, millis); + let timestamp = format!("{}.{:03}", timestamp, millis); format!( "{} {} {} {} {}", Colour::Black.bold().paint(timestamp), @@ -264,21 +304,3 @@ fn kill_color(s: &str) -> String { } RE.replace_all(s, "").to_string() } - -/// Reset the signal pipe (`SIGPIPE`) handler to the default one provided by the system. -/// This will end the program on `SIGPIPE` instead of panicking. -/// -/// This should be called before calling any cli method or printing any output. -pub fn reset_signal_pipe_handler() -> Result<()> { - #[cfg(target_family = "unix")] - { - use nix::sys::signal; - - unsafe { - signal::signal(signal::Signal::SIGPIPE, signal::SigHandler::SigDfl) - .map_err(|e| Error::Other(e.to_string()))?; - } - } - - Ok(()) -} diff --git a/client/cli/src/logger.rs b/client/cli/src/logger.rs new file mode 100644 index 0000000000000000000000000000000000000000..10e44098f0f16389c332d207d9f13ac0c82ba3b1 --- /dev/null +++ b/client/cli/src/logger.rs @@ -0,0 +1,272 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use ansi_term::Colour; +use flexi_logger::{ + DeferredNow, Duplicate, LogSpecBuilder, + LogSpecification, LogTarget, Logger, Criterion, Naming, Cleanup, Age, +}; +use lazy_static::lazy_static; +use regex::Regex; +use std::path::PathBuf; +use structopt::StructOpt; +use crate::error::{Error, Result}; + +type IoResult = std::result::Result<(), std::io::Error>; + +/// Default size used for rotation. Basically unlimited. +const DEFAULT_ROTATION_SIZE: u64 = u64::MAX; + +/// Options for log rotation. +#[derive(Debug, StructOpt, Default, Clone)] +pub struct LogRotationOpt { + /// Specify the path of the directory which will contain the log files. + /// Defaults to never rotating logs. + #[structopt(long, parse(from_os_str))] + log_directory: Option, + + /// Rotate the log file when the local clock has started a new day/hour/minute/second + /// since the current file has been created. + #[structopt(long, + conflicts_with("log-size"), + possible_values(&["day", "hour", "minute", "second"]), + parse(from_str = age_from_str)) + ] + log_age: Option, + + /// Rotate the log file when it exceeds this size (in bytes). + #[structopt(long, conflicts_with("log-age"))] + log_size: Option, +} + +/// Utility for parsing an Age from a &str. +fn age_from_str(s: &str) -> Age { + match s { + "day" => Age::Day, + "hour" => Age::Hour, + "minute" => Age::Minute, + "second" => Age::Second, + _ => unreachable!(), + } +} + +/// Format used when writing to a tty. Colors the output. +fn colored_fmt( + w: &mut dyn std::io::Write, + _now: &mut DeferredNow, + record: &log::Record, +) -> IoResult { + let now = time::now(); + let timestamp = + time::strftime("%Y-%m-%d %H:%M:%S", &now).expect("Error formatting log timestamp"); + + let output = if log::max_level() <= log::LevelFilter::Info { + format!( + "{} {}", + Colour::Black.bold().paint(timestamp), + record.args(), + ) + } else { + let name = ::std::thread::current() + .name() + .map_or_else(Default::default, |x| { + format!("{}", Colour::Blue.bold().paint(x)) + }); + let millis = (now.tm_nsec as f32 / 1000000.0).floor() as usize; + let timestamp = format!("{}.{:03}", timestamp, millis); + format!( + "{} {} {} {} {}", + Colour::Black.bold().paint(timestamp), + name, + record.level(), + record.target(), + record.args() + ) + }; + + write!(w, "{}", output) +} + +/// Format used when logging to files. Does not add any colors. +fn file_fmt( + w: &mut dyn std::io::Write, + _now: &mut DeferredNow, + record: &log::Record, +) -> IoResult { + let now = time::now(); + let timestamp = + time::strftime("%Y-%m-%d %H:%M:%S", &now).expect("Error formatting log timestamp"); + + let output = if log::max_level() <= log::LevelFilter::Info { + format!("{} {}", timestamp, record.args(),) + } else { + let name = std::thread::current() + .name() + .map_or_else(Default::default, |x| format!("{}", x)); + let millis = (now.tm_nsec as f32 / 1000000.0).floor() as usize; + let timestamp = format!("{}.{:03}", timestamp, millis); + format!( + "{} {} {} {} {}", + timestamp, + name, + record.level(), + record.target(), + record.args() + ) + }; + + // Required because substrate sometimes sends strings that are colored. + // Doing this ensures no colors are ever printed to files. + let output = kill_color(&output); + + write!(w, "{}", output) +} + +/// Initialize the logger +pub fn init_logger( + pattern: &str, + log_rotation_opt: Option, +) -> Result<()> { + let mut builder = LogSpecBuilder::new(); + // Disable info logging by default for some modules: + builder.module("ws", log::LevelFilter::Off); + builder.module("yamux", log::LevelFilter::Off); + builder.module("hyper", log::LevelFilter::Warn); + builder.module("cranelift_wasm", log::LevelFilter::Warn); + // Always log the special target `sc_tracing`, overrides global level + builder.module("sc_tracing", log::LevelFilter::Info); + // Enable info for others. + builder.default(log::LevelFilter::Info); + + // Add filters defined by RUST_LOG. + builder.insert_modules_from(LogSpecification::env()?); + + // Add filters passed in as argument. + builder.insert_modules_from(LogSpecification::parse(pattern)?); + + // Build the LogSpec. + let spec = builder.build(); + + // Use timestamps to differentiate logs. + let naming = Naming::Timestamps; + // Never cleanup old logs; let the end-user take care of that. + let cleanup = Cleanup::Never; + + let log_rotation_opt = log_rotation_opt.unwrap_or_default(); + let age = log_rotation_opt.log_age; + let size = log_rotation_opt.log_size; + + // Build a Criterion from the options. + let criterion = match (age, size) { + (Some(a), None) => Criterion::Age(a), + (None, Some(s)) => Criterion::Size(s), + // Default to rotating with a size of `DEFAULT_ROTATION_SIZE`. + (None, None) => Criterion::Size(DEFAULT_ROTATION_SIZE), + _ => return Err(Error::Input("Only one of Age or Size should be defined".into())) + }; + + let isatty_stderr = atty::is(atty::Stream::Stderr); + let isatty_stdout = atty::is(atty::Stream::Stdout); + let logger = Logger::with(spec) + .format(file_fmt) + .format_for_stderr(colored_fmt) + .format_for_stdout(colored_fmt) + .rotate(criterion, naming, cleanup); // Won't get used if log_directory has not been specified. + + + let logger = match (log_rotation_opt.log_directory.as_ref(), isatty_stderr) { + // Only log to stderr using colored format; nothing to file, nothing to stdout. + (None, true) => { + logger.log_target(LogTarget::StdErr) + } + // Log to stderr using file format, log to stdout using colored format. + (None, false) => { + let logger = logger + .log_target(LogTarget::DevNull) + .format_for_stderr(file_fmt) + .duplicate_to_stderr(Duplicate::All); + + // Write to stdout only if it's a tty. + if isatty_stdout { + logger.duplicate_to_stdout(Duplicate::Info) + } else { + logger + } + } + // Log to stderr with colored format, log to file with file format. Nothing to stdout. + (Some(file), true) => { + logger + .log_target(LogTarget::File) + .duplicate_to_stderr(Duplicate::All) + .directory(file) + } + // Log to stderr with file format, log to file with file format, log to stdout with colored format. + (Some(file), false) => { + let logger = logger + .log_target(LogTarget::File) + .format_for_stderr(file_fmt) + .duplicate_to_stderr(Duplicate::All) + .directory(file); + + // Write to stdout only if it's a tty. + if isatty_stdout { + logger.duplicate_to_stdout(Duplicate::Info) + } else { + logger + } + } + }; + + logger.start().map(|_| ()).map_err(|e| e.into()) +} + +fn kill_color(s: &str) -> String { + lazy_static! { + static ref RE: Regex = Regex::new("\x1b\\[[^m]+m").expect("Error initializing color regex"); + } + RE.replace_all(s, "").to_string() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn logger_default() { + let pattern = ""; + let log_rotation_opt = LogRotationOpt { + log_directory: None, + log_age: None, + log_size: None, + }; + + assert!(init_logger(pattern, Some(log_rotation_opt)).is_ok()); + } + + #[test] + fn logger_conflicting_opt() { + let pattern = ""; + let log_rotation_opt = LogRotationOpt { + log_directory: None, + log_age: Some(Age::Day), + log_size: Some(1337), + }; + + assert!(init_logger(pattern, Some(log_rotation_opt)).is_err()); + } +} diff --git a/client/cli/src/params/database_params.rs b/client/cli/src/params/database_params.rs index dd0d1686e099e8544e9bd6b9e84f259597a65a4d..24b23f6076a02302071c76a6da614c8e5c11e6a0 100644 --- a/client/cli/src/params/database_params.rs +++ b/client/cli/src/params/database_params.rs @@ -1,24 +1,26 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::arg_enums::Database; use structopt::StructOpt; /// Parameters for block import. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct DatabaseParams { /// Select database backend to use. #[structopt( diff --git a/client/cli/src/params/import_params.rs b/client/cli/src/params/import_params.rs index c5acc6bd8144013dc91d0fa9cb42b5096201e3ec..e60779429b179c3b2cc0264325df4b49aa712575 100644 --- a/client/cli/src/params/import_params.rs +++ b/client/cli/src/params/import_params.rs @@ -1,22 +1,24 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::arg_enums::{ - ExecutionStrategy, TracingReceiver, WasmExecutionMethod, - DEFAULT_EXECUTION_BLOCK_CONSTRUCTION, DEFAULT_EXECUTION_IMPORT_BLOCK, + ExecutionStrategy, TracingReceiver, WasmExecutionMethod, DEFAULT_EXECUTION_BLOCK_CONSTRUCTION, + DEFAULT_EXECUTION_IMPORT_BLOCK, DEFAULT_EXECUTION_IMPORT_BLOCK_VALIDATOR, DEFAULT_EXECUTION_OFFCHAIN_WORKER, DEFAULT_EXECUTION_OTHER, DEFAULT_EXECUTION_SYNCING, }; use crate::params::DatabaseParams; @@ -25,7 +27,7 @@ use sc_client_api::execution_extensions::ExecutionStrategies; use structopt::StructOpt; /// Parameters for block import. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct ImportParams { #[allow(missing_docs)] #[structopt(flatten)] @@ -102,22 +104,27 @@ impl ImportParams { } /// Get execution strategies for the parameters - pub fn execution_strategies( - &self, - is_dev: bool, - ) -> ExecutionStrategies { + pub fn execution_strategies(&self, is_dev: bool, is_validator: bool) -> ExecutionStrategies { let exec = &self.execution_strategies; - let exec_all_or = |strat: ExecutionStrategy, default: ExecutionStrategy| { - exec.execution.unwrap_or(if strat == default && is_dev { + let exec_all_or = |strat: Option, default: ExecutionStrategy| { + let default = if is_dev { ExecutionStrategy::Native } else { - strat - }).into() + default + }; + + exec.execution.unwrap_or_else(|| strat.unwrap_or(default)).into() + }; + + let default_execution_import_block = if is_validator { + DEFAULT_EXECUTION_IMPORT_BLOCK_VALIDATOR + } else { + DEFAULT_EXECUTION_IMPORT_BLOCK }; ExecutionStrategies { syncing: exec_all_or(exec.execution_syncing, DEFAULT_EXECUTION_SYNCING), - importing: exec_all_or(exec.execution_import_block, DEFAULT_EXECUTION_IMPORT_BLOCK), + importing: exec_all_or(exec.execution_import_block, default_execution_import_block), block_construction: exec_all_or(exec.execution_block_construction, DEFAULT_EXECUTION_BLOCK_CONSTRUCTION), offchain_worker: @@ -128,27 +135,27 @@ impl ImportParams { } /// Execution strategies parameters. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct ExecutionStrategiesParams { - /// The means of execution used when calling into the runtime while syncing blocks. + /// The means of execution used when calling into the runtime for importing blocks as + /// part of an initial sync. #[structopt( long = "execution-syncing", value_name = "STRATEGY", possible_values = &ExecutionStrategy::variants(), case_insensitive = true, - default_value = DEFAULT_EXECUTION_SYNCING.as_str(), )] - pub execution_syncing: ExecutionStrategy, + pub execution_syncing: Option, - /// The means of execution used when calling into the runtime while importing blocks. + /// The means of execution used when calling into the runtime for general block import + /// (including locally authored blocks). #[structopt( long = "execution-import-block", value_name = "STRATEGY", possible_values = &ExecutionStrategy::variants(), case_insensitive = true, - default_value = DEFAULT_EXECUTION_IMPORT_BLOCK.as_str(), )] - pub execution_import_block: ExecutionStrategy, + pub execution_import_block: Option, /// The means of execution used when calling into the runtime while constructing blocks. #[structopt( @@ -156,9 +163,8 @@ pub struct ExecutionStrategiesParams { value_name = "STRATEGY", possible_values = &ExecutionStrategy::variants(), case_insensitive = true, - default_value = DEFAULT_EXECUTION_BLOCK_CONSTRUCTION.as_str(), )] - pub execution_block_construction: ExecutionStrategy, + pub execution_block_construction: Option, /// The means of execution used when calling into the runtime while using an off-chain worker. #[structopt( @@ -166,9 +172,8 @@ pub struct ExecutionStrategiesParams { value_name = "STRATEGY", possible_values = &ExecutionStrategy::variants(), case_insensitive = true, - default_value = DEFAULT_EXECUTION_OFFCHAIN_WORKER.as_str(), )] - pub execution_offchain_worker: ExecutionStrategy, + pub execution_offchain_worker: Option, /// The means of execution used when calling into the runtime while not syncing, importing or constructing blocks. #[structopt( @@ -176,9 +181,8 @@ pub struct ExecutionStrategiesParams { value_name = "STRATEGY", possible_values = &ExecutionStrategy::variants(), case_insensitive = true, - default_value = DEFAULT_EXECUTION_OTHER.as_str(), )] - pub execution_other: ExecutionStrategy, + pub execution_other: Option, /// The execution strategy that should be used by all execution contexts. #[structopt( diff --git a/client/cli/src/params/keystore_params.rs b/client/cli/src/params/keystore_params.rs index c6131c2f64941afa507931e5e090a4389a1e61eb..3c04d63144595680394e00fecd4a699ed446a304 100644 --- a/client/cli/src/params/keystore_params.rs +++ b/client/cli/src/params/keystore_params.rs @@ -1,30 +1,35 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error::Result; use sc_service::config::KeystoreConfig; use std::fs; use std::path::PathBuf; use structopt::StructOpt; +use crate::error; +use sp_core::crypto::{SecretString, Zeroize}; +use std::str::FromStr; /// default sub directory for the key store const DEFAULT_KEYSTORE_CONFIG_PATH: &'static str = "keystore"; /// Parameters of the keystore -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct KeystoreParams { /// Specify custom keystore path. #[structopt(long = "keystore-path", value_name = "PATH", parse(from_os_str))] @@ -40,9 +45,10 @@ pub struct KeystoreParams { /// Password used by the keystore. #[structopt( long = "password", + parse(try_from_str = secret_string_from_str), conflicts_with_all = &[ "password-interactive", "password-filename" ] )] - pub password: Option, + pub password: Option, /// File that contains the password used by the keystore. #[structopt( @@ -54,35 +60,60 @@ pub struct KeystoreParams { pub password_filename: Option, } +/// Parse a sercret string, returning a displayable error. +pub fn secret_string_from_str(s: &str) -> std::result::Result { + Ok(std::str::FromStr::from_str(s) + .map_err(|_e| "Could not get SecretString".to_string())?) +} + impl KeystoreParams { /// Get the keystore configuration for the parameters pub fn keystore_config(&self, base_path: &PathBuf) -> Result { let password = if self.password_interactive { #[cfg(not(target_os = "unknown"))] { - Some(input_keystore_password()?.into()) + let mut password = input_keystore_password()?; + let secret = std::str::FromStr::from_str(password.as_str()) + .map_err(|()| "Error reading password")?; + password.zeroize(); + Some(secret) } #[cfg(target_os = "unknown")] None } else if let Some(ref file) = self.password_filename { - Some( - fs::read_to_string(file) - .map_err(|e| format!("{}", e))? - .into(), - ) - } else if let Some(ref password) = self.password { - Some(password.clone().into()) + let mut password = fs::read_to_string(file) + .map_err(|e| format!("{}", e))?; + let secret = std::str::FromStr::from_str(password.as_str()) + .map_err(|()| "Error reading password")?; + password.zeroize(); + Some(secret) } else { - None + self.password.clone() }; let path = self .keystore_path .clone() - .unwrap_or(base_path.join(DEFAULT_KEYSTORE_CONFIG_PATH)); + .unwrap_or_else(|| base_path.join(DEFAULT_KEYSTORE_CONFIG_PATH)); Ok(KeystoreConfig::Path { path, password }) } + + /// helper method to fetch password from `KeyParams` or read from stdin + pub fn read_password(&self) -> error::Result> { + let (password_interactive, password) = (self.password_interactive, self.password.clone()); + + let pass = if password_interactive { + let mut password = rpassword::read_password_from_tty(Some("Key password: "))?; + let pass = Some(FromStr::from_str(&password).map_err(|()| "Error reading password")?); + password.zeroize(); + pass + } else { + password + }; + + Ok(pass) + } } #[cfg(not(target_os = "unknown"))] diff --git a/client/cli/src/params/mod.rs b/client/cli/src/params/mod.rs index da236ee1656850d35db04b34957c3675fb384cd5..93467bc8ec63778e95d116b57cf8b6dc92c12636 100644 --- a/client/cli/src/params/mod.rs +++ b/client/cli/src/params/mod.rs @@ -1,19 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - +// along with this program. If not, see . mod database_params; mod import_params; mod keystore_params; @@ -24,8 +25,11 @@ mod pruning_params; mod shared_params; mod transaction_pool_params; -use std::{fmt::Debug, str::FromStr}; +use std::{fmt::Debug, str::FromStr, convert::TryFrom}; use sp_runtime::{generic::BlockId, traits::{Block as BlockT, NumberFor}}; +use sp_core::crypto::Ss58AddressFormat; +use crate::arg_enums::{OutputType, CryptoScheme}; +use structopt::StructOpt; pub use crate::params::database_params::*; pub use crate::params::import_params::*; @@ -39,9 +43,9 @@ pub use crate::params::transaction_pool_params::*; /// Wrapper type of `String` that holds an unsigned integer of arbitrary size, formatted as a decimal. #[derive(Debug, Clone)] -pub struct BlockNumber(String); +pub struct GenericNumber(String); -impl FromStr for BlockNumber { +impl FromStr for GenericNumber { type Err = String; fn from_str(block_number: &str) -> Result { @@ -56,22 +60,22 @@ impl FromStr for BlockNumber { } } -impl BlockNumber { +impl GenericNumber { /// Wrapper on top of `std::str::parse` but with `Error` as a `String` /// /// See `https://doc.rust-lang.org/std/primitive.str.html#method.parse` for more elaborate /// documentation. pub fn parse(&self) -> Result - where - N: FromStr, - N::Err: std::fmt::Debug, + where + N: FromStr, + N::Err: std::fmt::Debug, { FromStr::from_str(&self.0).map_err(|e| format!("Failed to parse block number: {:?}", e)) } } /// Wrapper type that is either a `Hash` or the number of a `Block`. -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct BlockNumberOrHash(String); impl FromStr for BlockNumberOrHash { @@ -88,7 +92,7 @@ impl FromStr for BlockNumberOrHash { Ok(Self(block_number.into())) } } else { - BlockNumber::from_str(block_number).map(|v| Self(v.0)) + GenericNumber::from_str(block_number).map(|v| Self(v.0)) } } } @@ -108,11 +112,55 @@ impl BlockNumberOrHash { .map_err(|e| format!("Failed to parse block hash: {:?}", e))? )) } else { - BlockNumber(self.0.clone()).parse().map(BlockId::Number) + GenericNumber(self.0.clone()).parse().map(BlockId::Number) } } } + +/// Optional flag for specifying crypto algorithm +#[derive(Debug, StructOpt)] +pub struct CryptoSchemeFlag { + /// cryptography scheme + #[structopt( + long, + value_name = "SCHEME", + possible_values = &CryptoScheme::variants(), + case_insensitive = true, + default_value = "Sr25519" + )] + pub scheme: CryptoScheme, +} + +/// Optional flag for specifying output type +#[derive(Debug, StructOpt)] +pub struct OutputTypeFlag { + /// output format + #[structopt( + long, + value_name = "FORMAT", + possible_values = &OutputType::variants(), + case_insensitive = true, + default_value = "Text" + )] + pub output_type: OutputType, +} + +/// Optional flag for specifying network scheme +#[derive(Debug, StructOpt)] +pub struct NetworkSchemeFlag { + /// network address format + #[structopt( + long, + value_name = "NETWORK", + short = "n", + possible_values = &Ss58AddressFormat::all_names()[..], + parse(try_from_str = Ss58AddressFormat::try_from), + case_insensitive = true, + )] + pub network: Option, +} + #[cfg(test)] mod tests { use super::*; diff --git a/client/cli/src/params/network_params.rs b/client/cli/src/params/network_params.rs index 79112b041cf3757c7f2aa8e863d55aef30ac9981..4a33644e8934e48033d296f2580372d55f549821 100644 --- a/client/cli/src/params/network_params.rs +++ b/client/cli/src/params/network_params.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::params::node_key_params::NodeKeyParams; use sc_network::{ @@ -24,7 +26,7 @@ use std::path::PathBuf; use structopt::StructOpt; /// Parameters used to create the network configuration. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct NetworkParams { /// Specify a list of bootnodes. #[structopt(long = "bootnodes", value_name = "ADDR")] @@ -100,11 +102,6 @@ pub struct NetworkParams { /// By default this option is true for `--dev` and false otherwise. #[structopt(long)] pub discover_local: bool, - - /// Use the legacy "pre-mainnet-launch" networking protocol. Enable if things seem broken. - /// This option will be removed in the future. - #[structopt(long)] - pub legacy_network_protocol: bool, } impl NetworkParams { @@ -117,11 +114,15 @@ impl NetworkParams { client_id: &str, node_name: &str, node_key: NodeKeyConfig, + default_listen_port: u16, ) -> NetworkConfiguration { - let port = self.port.unwrap_or(30333); + let port = self.port.unwrap_or(default_listen_port); let listen_addresses = if self.listen_addr.is_empty() { vec![ + Multiaddr::empty() + .with(Protocol::Ip6([0, 0, 0, 0, 0, 0, 0, 0].into())) + .with(Protocol::Tcp(port)), Multiaddr::empty() .with(Protocol::Ip4([0, 0, 0, 0].into())) .with(Protocol::Tcp(port)), @@ -160,7 +161,6 @@ impl NetworkParams { }, max_parallel_downloads: self.max_parallel_downloads, allow_non_globals_in_dht: self.discover_local || is_dev, - use_new_block_requests_protocol: !self.legacy_network_protocol, } } } diff --git a/client/cli/src/params/node_key_params.rs b/client/cli/src/params/node_key_params.rs index 2913ff2c1035e2f04ae30888e9f352420c40331d..689cc6c681c8339e79937e3dbb8ac9e3cfe04c6f 100644 --- a/client/cli/src/params/node_key_params.rs +++ b/client/cli/src/params/node_key_params.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use sc_network::config::NodeKeyConfig; use sp_core::H256; @@ -29,7 +31,7 @@ const NODE_KEY_ED25519_FILE: &str = "secret_ed25519"; /// Parameters used to create the `NodeKeyConfig`, which determines the keypair /// used for libp2p networking. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct NodeKeyParams { /// The secret key to use for libp2p networking. /// diff --git a/client/cli/src/params/offchain_worker_params.rs b/client/cli/src/params/offchain_worker_params.rs index eb3cc74ad900cd72db2511a305e2ebc733a1a299..f8d48edc4729d5f97e4f389fe78dd3cd794423b9 100644 --- a/client/cli/src/params/offchain_worker_params.rs +++ b/client/cli/src/params/offchain_worker_params.rs @@ -1,19 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - +// along with this program. If not, see . //! Offchain worker related configuration parameters. //! @@ -31,7 +32,7 @@ use crate::OffchainWorkerEnabled; /// Offchain worker related parameters. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct OffchainWorkerParams { /// Should execute offchain workers on every block. /// diff --git a/client/cli/src/params/pruning_params.rs b/client/cli/src/params/pruning_params.rs index ed8f7ab16858dce49f0b8a78ae2bb60141a47eac..7db808e6d8f2f8e249ff0e057a05297bfcf92a72 100644 --- a/client/cli/src/params/pruning_params.rs +++ b/client/cli/src/params/pruning_params.rs @@ -1,25 +1,27 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::error; use sc_service::{PruningMode, Role}; use structopt::StructOpt; /// Parameters to define the pruning mode -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct PruningParams { /// Specify the state pruning mode, a number of blocks to keep or 'archive'. /// diff --git a/client/cli/src/params/shared_params.rs b/client/cli/src/params/shared_params.rs index c8381cd069bb9092410071b0e634b1cf961aa2cb..ad9ab04070563ac5c7ea5939688f410a3257f232 100644 --- a/client/cli/src/params/shared_params.rs +++ b/client/cli/src/params/shared_params.rs @@ -1,54 +1,52 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . +use sc_service::config::BasePath; use std::path::PathBuf; use structopt::StructOpt; /// Shared parameters used by all `CoreParams`. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct SharedParams { /// Specify the chain specification (one of dev, local, or staging). - #[structopt(long = "chain", value_name = "CHAIN_SPEC")] + #[structopt(long, value_name = "CHAIN_SPEC")] pub chain: Option, /// Specify the development chain. - #[structopt(long = "dev")] + #[structopt(long, conflicts_with_all = &["chain"])] pub dev: bool, /// Specify custom base path. - #[structopt( - long = "base-path", - short = "d", - value_name = "PATH", - parse(from_os_str) - )] + #[structopt(long, short = "d", value_name = "PATH", parse(from_os_str))] pub base_path: Option, /// Sets a custom logging filter. Syntax is =, e.g. -lsync=debug. /// /// Log levels (least to most verbose) are error, warn, info, debug, and trace. /// By default, all targets log `info`. The global log level can be set with -l. - #[structopt(short = "l", long = "log", value_name = "LOG_PATTERN")] + #[structopt(short = "l", long, value_name = "LOG_PATTERN")] pub log: Vec, } impl SharedParams { /// Specify custom base path. - pub fn base_path(&self) -> Option { - self.base_path.clone() + pub fn base_path(&self) -> Option { + self.base_path.clone().map(Into::into) } /// Specify the development chain. diff --git a/client/cli/src/params/transaction_pool_params.rs b/client/cli/src/params/transaction_pool_params.rs index dfcdf9af70537e51586654e4cc72da4a7549f118..3ad278426922ec99ccc42e192cbda9db1d04207b 100644 --- a/client/cli/src/params/transaction_pool_params.rs +++ b/client/cli/src/params/transaction_pool_params.rs @@ -1,24 +1,26 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use sc_service::config::TransactionPoolOptions; use structopt::StructOpt; /// Parameters used to create the pool configuration. -#[derive(Debug, StructOpt, Clone)] +#[derive(Debug, StructOpt)] pub struct TransactionPoolParams { /// Maximum number of transactions in the transaction pool. #[structopt(long = "pool-limit", value_name = "COUNT", default_value = "8192")] diff --git a/client/cli/src/runner.rs b/client/cli/src/runner.rs index 277d5f97b8fa138d6a4181cef8fccb15c57290a5..f2558b1bb6070679a01bf88dc8589ea5a2033a1a 100644 --- a/client/cli/src/runner.rs +++ b/client/cli/src/runner.rs @@ -1,32 +1,35 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::CliConfiguration; use crate::Result; -use crate::SubstrateCli; use crate::Subcommand; +use crate::SubstrateCli; use chrono::prelude::*; use futures::pin_mut; use futures::select; use futures::{future, future::FutureExt, Future}; use log::info; -use sc_service::{AbstractService, Configuration, Role, ServiceBuilderCommand, TaskType}; +use sc_service::{Configuration, TaskType, TaskManager}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use sp_utils::metrics::{TOKIO_THREADS_ALIVE, TOKIO_THREADS_TOTAL}; -use std::{str::FromStr, fmt::Debug, marker::PhantomData, sync::Arc}; +use std::{fmt::Debug, marker::PhantomData, str::FromStr, sync::Arc}; +use sc_client_api::{UsageProvider, BlockBackend, StorageProvider}; #[cfg(target_family = "unix")] async fn main(func: F) -> std::result::Result<(), Box> @@ -79,18 +82,22 @@ where pub fn build_runtime() -> std::result::Result { tokio::runtime::Builder::new() .threaded_scheduler() - .on_thread_start(||{ + .on_thread_start(|| { TOKIO_THREADS_ALIVE.inc(); TOKIO_THREADS_TOTAL.inc(); }) - .on_thread_stop(||{ + .on_thread_stop(|| { TOKIO_THREADS_ALIVE.dec(); }) .enable_all() .build() } -fn run_until_exit(mut tokio_runtime: tokio::runtime::Runtime, future: FUT) -> Result<()> +fn run_until_exit( + mut tokio_runtime: tokio::runtime::Runtime, + future: FUT, + task_manager: TaskManager, +) -> Result<()> where FUT: Future> + future::Future, ERR: 'static + std::error::Error, @@ -99,6 +106,7 @@ where pin_mut!(f); tokio_runtime.block_on(main(f)).map_err(|e| e.to_string())?; + tokio_runtime.block_on(task_manager.clean_shutdown()); Ok(()) } @@ -116,41 +124,37 @@ impl Runner { let tokio_runtime = build_runtime()?; let runtime_handle = tokio_runtime.handle().clone(); - let task_executor = Arc::new( - move |fut, task_type| { - match task_type { - TaskType::Async => { runtime_handle.spawn(fut); } - TaskType::Blocking => { - runtime_handle.spawn( async move { - // `spawn_blocking` is looking for the current runtime, and as such has to be called - // from within `spawn`. - tokio::task::spawn_blocking(move || futures::executor::block_on(fut)) - }); - } - } + let task_executor = move |fut, task_type| { + match task_type { + TaskType::Async => runtime_handle.spawn(fut).map(drop), + TaskType::Blocking => + runtime_handle.spawn_blocking(move || futures::executor::block_on(fut)) + .map(drop), } - ); + }; Ok(Runner { - config: command.create_configuration(cli, task_executor)?, + config: command.create_configuration(cli, task_executor.into())?, tokio_runtime, phantom: PhantomData, }) } - /// A helper function that runs an `AbstractService` with tokio and stops if the process receives - /// the signal `SIGTERM` or `SIGINT`. - pub fn run_node( - self, - new_light: FNL, - new_full: FNF, - runtime_version: sp_version::RuntimeVersion, - ) -> Result<()> where - FNL: FnOnce(Configuration) -> sc_service::error::Result, - FNF: FnOnce(Configuration) -> sc_service::error::Result, - SL: AbstractService + Unpin, - SF: AbstractService + Unpin, - { + /// Log information about the node itself. + /// + /// # Example: + /// + /// ```text + /// 2020-06-03 16:14:21 Substrate Node + /// 2020-06-03 16:14:21 ✌️ version 2.0.0-rc3-f4940588c-x86_64-linux-gnu + /// 2020-06-03 16:14:21 ❤️ by Parity Technologies , 2017-2020 + /// 2020-06-03 16:14:21 📋 Chain specification: Flaming Fir + /// 2020-06-03 16:14:21 🏷 Node name: jolly-rod-7462 + /// 2020-06-03 16:14:21 👤 Role: FULL + /// 2020-06-03 16:14:21 💾 Database: RocksDb at /tmp/c/chains/flamingfir7/db + /// 2020-06-03 16:14:21 ⛓ Native runtime: node-251 (substrate-node-1.tx1.au10) + /// ``` + fn print_node_infos(&self) { info!("{}", C::impl_name()); info!("✌️ version {}", C::impl_version()); info!( @@ -166,70 +170,66 @@ impl Runner { self.config.database, self.config.database.path().map_or_else(|| "".to_owned(), |p| p.display().to_string()) ); - info!("⛓ Native runtime: {}", runtime_version); - - match self.config.role { - Role::Light => self.run_service_until_exit(new_light), - _ => self.run_service_until_exit(new_full), - } + info!("⛓ Native runtime: {}", C::native_runtime_version(&self.config.chain_spec)); } /// A helper function that runs a future with tokio and stops if the process receives the signal /// `SIGTERM` or `SIGINT`. - pub fn run_subcommand(self, subcommand: &Subcommand, builder: B) -> Result<()> + pub fn run_subcommand(self, subcommand: &Subcommand, builder: BU) + -> Result<()> where - B: FnOnce(Configuration) -> sc_service::error::Result, - BC: ServiceBuilderCommand + Unpin, - BB: sp_runtime::traits::Block + Debug, - <<::Header as HeaderT>::Number as FromStr>::Err: Debug, - ::Hash: FromStr, - <::Hash as FromStr>::Err: Debug, + BU: FnOnce(Configuration) + -> sc_service::error::Result<(Arc, Arc, IQ, TaskManager)>, + B: BlockT + for<'de> serde::Deserialize<'de>, + BA: sc_client_api::backend::Backend + 'static, + IQ: sc_service::ImportQueue + 'static, + ::Hash: FromStr, + <::Hash as FromStr>::Err: Debug, + <<::Header as HeaderT>::Number as FromStr>::Err: Debug, + CL: UsageProvider + BlockBackend + StorageProvider + Send + Sync + + 'static, { + let chain_spec = self.config.chain_spec.cloned_box(); + let network_config = self.config.network.clone(); + let db_config = self.config.database.clone(); + match subcommand { - Subcommand::BuildSpec(cmd) => cmd.run(self.config), + Subcommand::BuildSpec(cmd) => cmd.run(chain_spec, network_config), Subcommand::ExportBlocks(cmd) => { - run_until_exit(self.tokio_runtime, cmd.run(self.config, builder)) + let (client, _, _, task_manager) = builder(self.config)?; + run_until_exit(self.tokio_runtime, cmd.run(client, db_config), task_manager) } Subcommand::ImportBlocks(cmd) => { - run_until_exit(self.tokio_runtime, cmd.run(self.config, builder)) + let (client, _, import_queue, task_manager) = builder(self.config)?; + run_until_exit(self.tokio_runtime, cmd.run(client, import_queue), task_manager) } Subcommand::CheckBlock(cmd) => { - run_until_exit(self.tokio_runtime, cmd.run(self.config, builder)) + let (client, _, import_queue, task_manager) = builder(self.config)?; + run_until_exit(self.tokio_runtime, cmd.run(client, import_queue), task_manager) } - Subcommand::Revert(cmd) => cmd.run(self.config, builder), - Subcommand::PurgeChain(cmd) => cmd.run(self.config), - Subcommand::ExportState(cmd) => cmd.run(self.config, builder), + Subcommand::Revert(cmd) => { + let (client, backend, _, task_manager) = builder(self.config)?; + run_until_exit(self.tokio_runtime, cmd.run(client, backend), task_manager) + }, + Subcommand::PurgeChain(cmd) => cmd.run(db_config), + Subcommand::ExportState(cmd) => { + let (client, _, _, task_manager) = builder(self.config)?; + run_until_exit(self.tokio_runtime, cmd.run(client, chain_spec), task_manager) + }, } } - fn run_service_until_exit(mut self, service_builder: F) -> Result<()> - where - F: FnOnce(Configuration) -> std::result::Result, - T: AbstractService + Unpin, - { - let service = service_builder(self.config)?; - - let informant_future = sc_informant::build(&service, sc_informant::OutputFormat::Coloured); - let _informant_handle = self.tokio_runtime.spawn(informant_future); - - // we eagerly drop the service so that the internal exit future is fired, - // but we need to keep holding a reference to the global telemetry guard - // and drop the runtime first. - let _telemetry = service.telemetry(); - - { - let f = service.fuse(); - self.tokio_runtime - .block_on(main(f)) - .map_err(|e| e.to_string())?; - } - - // The `service` **must** have been destroyed here for the shutdown signal to propagate - // to all the tasks. Dropping `tokio_runtime` will block the thread until all tasks have - // shut down. - drop(self.tokio_runtime); - - Ok(()) + /// A helper function that runs a node with tokio and stops if the process receives the signal + /// `SIGTERM` or `SIGINT`. + pub fn run_node_until_exit( + mut self, + initialise: impl FnOnce(Configuration) -> sc_service::error::Result, + ) -> Result<()> { + self.print_node_infos(); + let mut task_manager = initialise(self.config)?; + let res = self.tokio_runtime.block_on(main(task_manager.future().fuse())); + self.tokio_runtime.block_on(task_manager.clean_shutdown()); + res.map_err(|e| e.to_string().into()) } /// A helper function that runs a command with the configuration of this node @@ -239,11 +239,14 @@ impl Runner { /// A helper function that runs a future with tokio and stops if the process receives /// the signal SIGTERM or SIGINT - pub fn async_run(self, runner: impl FnOnce(Configuration) -> FUT) -> Result<()> + pub fn async_run( + self, runner: impl FnOnce(Configuration) -> Result<(FUT, TaskManager)>, + ) -> Result<()> where FUT: Future>, { - run_until_exit(self.tokio_runtime, runner(self.config)) + let (future, task_manager) = runner(self.config)?; + run_until_exit(self.tokio_runtime, future, task_manager) } /// Get an immutable reference to the node Configuration diff --git a/client/consensus/aura/Cargo.toml b/client/consensus/aura/Cargo.toml index 82196feac0396ae32567bf9c2173f83d5618f2a4..b107499daf48b86056357ff807429dae8b92b647 100644 --- a/client/consensus/aura/Cargo.toml +++ b/client/consensus/aura/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-consensus-aura" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Aura consensus algorithm for substrate" edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,36 +12,37 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-dev", path = "../../../primitives/application-crypto" } -sp-consensus-aura = { version = "0.8.0-dev", path = "../../../primitives/consensus/aura" } -sp-block-builder = { version = "2.0.0-dev", path = "../../../primitives/block-builder" } -sc-block-builder = { version = "0.8.0-dev", path = "../../../client/block-builder" } -sc-client-api = { version = "2.0.0-dev", path = "../../api" } -codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sp-application-crypto = { version = "2.0.0-rc6", path = "../../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8.0-rc6", path = "../../../primitives/consensus/aura" } +sp-block-builder = { version = "2.0.0-rc6", path = "../../../primitives/block-builder" } +sc-block-builder = { version = "0.8.0-rc6", path = "../../../client/block-builder" } +sc-client-api = { version = "2.0.0-rc6", path = "../../api" } +codec = { package = "parity-scale-codec", version = "1.3.4" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } derive_more = "0.99.2" futures = "0.3.4" futures-timer = "3.0.1" -sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } -sc-keystore = { version = "2.0.0-dev", path = "../../keystore" } +sp-inherents = { version = "2.0.0-rc6", path = "../../../primitives/inherents" } +sc-keystore = { version = "2.0.0-rc6", path = "../../keystore" } log = "0.4.8" parking_lot = "0.10.0" -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } -sp-version = { version = "2.0.0-dev", path = "../../../primitives/version" } -sc-consensus-slots = { version = "0.8.0-dev", path = "../slots" } -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-timestamp = { version = "2.0.0-dev", path = "../../../primitives/timestamp" } -sc-telemetry = { version = "2.0.0-dev", path = "../../telemetry" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-io = { version = "2.0.0-rc6", path = "../../../primitives/io" } +sp-version = { version = "2.0.0-rc6", path = "../../../primitives/version" } +sc-consensus-slots = { version = "0.8.0-rc6", path = "../slots" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-timestamp = { version = "2.0.0-rc6", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0-rc6", path = "../../telemetry" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../../utils/prometheus", version = "0.8.0-rc6"} [dev-dependencies] -sp-keyring = { version = "2.0.0-dev", path = "../../../primitives/keyring" } -sc-executor = { version = "0.8.0-dev", path = "../../executor" } -sc-network = { version = "0.8.0-dev", path = "../../network" } -sc-network-test = { version = "0.8.0-dev", path = "../../network/test" } -sc-service = { version = "0.8.0-dev", default-features = false, path = "../../service" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } +sp-keyring = { version = "2.0.0-rc6", path = "../../../primitives/keyring" } +sc-executor = { version = "0.8.0-rc6", path = "../../executor" } +sc-network = { version = "0.8.0-rc6", path = "../../network" } +sc-network-test = { version = "0.8.0-rc6", path = "../../network/test" } +sc-service = { version = "0.8.0-rc6", default-features = false, path = "../../service" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../test-utils/runtime/client" } env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/aura/README.md b/client/consensus/aura/README.md new file mode 100644 index 0000000000000000000000000000000000000000..85d82cd7dfd3b4e392c8210c40a32a6e57508413 --- /dev/null +++ b/client/consensus/aura/README.md @@ -0,0 +1,15 @@ +Aura (Authority-round) consensus in substrate. + +Aura works by having a list of authorities A who are expected to roughly +agree on the current time. Time is divided up into discrete slots of t +seconds each. For each slot s, the author of that slot is A[s % |A|]. + +The author is allowed to issue one block but not more during that slot, +and it will be built upon the longest valid chain that has been seen. + +Blocks from future steps will be either deferred or rejected depending on how +far in the future they are. + +NOTE: Aura itself is designed to be generic over the crypto used. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/consensus/aura/src/digests.rs b/client/consensus/aura/src/digests.rs index 8dd42fc01def2ee6ac93c9551e68f038c658d428..3332e4c6a6dff99f2ee9ad367031fde15a33ada6 100644 --- a/client/consensus/aura/src/digests.rs +++ b/client/consensus/aura/src/digests.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Aura (Authority-Round) digests //! diff --git a/client/consensus/aura/src/lib.rs b/client/consensus/aura/src/lib.rs index f61fdf44917a20271f93fab971ceecec9e15417a..420402871132834b089e4b13dc33ee8a0862d302 100644 --- a/client/consensus/aura/src/lib.rs +++ b/client/consensus/aura/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Aura (Authority-round) consensus in substrate. //! @@ -30,12 +32,13 @@ #![forbid(missing_docs, unsafe_code)] use std::{ sync::Arc, time::Duration, thread, marker::PhantomData, hash::Hash, fmt::Debug, pin::Pin, - collections::HashMap + collections::HashMap, convert::{TryFrom, TryInto}, }; use futures::prelude::*; use parking_lot::Mutex; use log::{debug, info, trace}; +use prometheus_endpoint::Registry; use codec::{Encode, Decode, Codec}; @@ -44,7 +47,7 @@ use sp_consensus::{ BlockOrigin, Error as ConsensusError, SelectChain, SlotData, BlockCheckParams, ImportResult }; use sp_consensus::import_queue::{ - Verifier, BasicQueue, BoxJustificationImport, BoxFinalityProofImport, + Verifier, BasicQueue, DefaultImportQueue, BoxJustificationImport, BoxFinalityProofImport, }; use sc_client_api::{backend::AuxStore, BlockOf}; use sp_blockchain::{ @@ -52,11 +55,15 @@ use sp_blockchain::{ ProvideCache, HeaderBackend, }; use sp_block_builder::BlockBuilder as BlockBuilderApi; -use sp_runtime::{generic::{BlockId, OpaqueDigestItemId}, Justification}; +use sp_core::crypto::Public; +use sp_application_crypto::{AppKey, AppPublic}; +use sp_runtime::{ + generic::{BlockId, OpaqueDigestItemId}, + Justification, +}; use sp_runtime::traits::{Block as BlockT, Header, DigestItemFor, Zero, Member}; use sp_api::ProvideRuntimeApi; - -use sp_core::crypto::Pair; +use sp_core::{traits::BareCryptoStore, crypto::Pair}; use sp_inherents::{InherentDataProviders, InherentData}; use sp_timestamp::{ TimestampInherentData, InherentType as TimestampInherent, InherentError as TIError @@ -150,15 +157,15 @@ pub fn start_aura( E: Environment + Send + Sync + 'static, E::Proposer: Proposer>, P: Pair + Send + Sync, - P::Public: Hash + Member + Encode + Decode, - P::Signature: Hash + Member + Encode + Decode, + P::Public: AppPublic + Hash + Member + Encode + Decode, + P::Signature: TryFrom> + Hash + Member + Encode + Decode, I: BlockImport> + Send + Sync + 'static, Error: std::error::Error + Send + From + 'static, SO: SyncOracle + Send + Sync + Clone, CAW: CanAuthorWith + Send, { let worker = AuraWorker { - client: client.clone(), + client, block_import: Arc::new(Mutex::new(block_import)), env, keystore, @@ -199,8 +206,8 @@ impl sc_consensus_slots::SimpleSlotWorker for AuraW E::Proposer: Proposer>, I: BlockImport> + Send + Sync + 'static, P: Pair + Send + Sync, - P::Public: Member + Encode + Decode + Hash, - P::Signature: Member + Encode + Decode + Hash + Debug, + P::Public: AppPublic + Public + Member + Encode + Decode + Hash, + P::Signature: TryFrom> + Member + Encode + Decode + Hash + Debug, SO: SyncOracle + Send + Clone, Error: std::error::Error + Send + From + 'static, { @@ -210,7 +217,7 @@ impl sc_consensus_slots::SimpleSlotWorker for AuraW dyn Future> + Send + 'static >>; type Proposer = E::Proposer; - type Claim = P; + type Claim = P::Public; type EpochData = Vec>; fn logging_target(&self) -> &'static str { @@ -240,10 +247,11 @@ impl sc_consensus_slots::SimpleSlotWorker for AuraW epoch_data: &Self::EpochData, ) -> Option { let expected_author = slot_author::

(slot_number, epoch_data); - expected_author.and_then(|p| { self.keystore.read() .key_pair_by_type::

(&p, sp_application_crypto::key_types::AURA).ok() + }).and_then(|p| { + Some(p.public()) }) } @@ -264,11 +272,30 @@ impl sc_consensus_slots::SimpleSlotWorker for AuraW StorageChanges, B>, Self::Claim, Self::EpochData, - ) -> sp_consensus::BlockImportParams> + Send> { - Box::new(|header, header_hash, body, storage_changes, pair, _epoch| { + ) -> Result< + sp_consensus::BlockImportParams>, + sp_consensus::Error> + Send + 'static> + { + let keystore = self.keystore.clone(); + Box::new(move |header, header_hash, body, storage_changes, public, _epoch| { // sign the pre-sealed hash of the block and then // add it to a digest item. - let signature = pair.sign(header_hash.as_ref()); + let public_type_pair = public.to_public_crypto_pair(); + let public = public.to_raw_vec(); + let signature = keystore.read() + .sign_with( + as AppKey>::ID, + &public_type_pair, + header_hash.as_ref() + ) + .map_err(|e| sp_consensus::Error::CannotSign( + public.clone(), e.to_string(), + ))?; + let signature = signature.clone().try_into() + .map_err(|_| sp_consensus::Error::InvalidSignature( + signature, public + ))?; + let signature_digest_item = as CompatibleDigestItem

>::aura_seal(signature); let mut import_block = BlockImportParams::new(BlockOrigin::Own, header); @@ -277,7 +304,7 @@ impl sc_consensus_slots::SimpleSlotWorker for AuraW import_block.storage_changes = Some(storage_changes); import_block.fork_choice = Some(ForkChoiceStrategy::LongestChain); - import_block + Ok(import_block) }) } @@ -331,8 +358,8 @@ impl SlotWorker for AuraWorker>, I: BlockImport> + Send + Sync + 'static, P: Pair + Send + Sync, - P::Public: Member + Encode + Decode + Hash, - P::Signature: Member + Encode + Decode + Hash + Debug, + P::Public: AppPublic + Member + Encode + Decode + Hash, + P::Signature: TryFrom> + Member + Encode + Decode + Hash + Debug, SO: SyncOracle + Send + Sync + Clone, Error: std::error::Error + Send + From + 'static, { @@ -452,8 +479,8 @@ fn check_header( info!( "Slot author is equivocating at slot {} with headers {:?} and {:?}", slot_num, - equivocation_proof.fst_header().hash(), - equivocation_proof.snd_header().hash(), + equivocation_proof.first_header.hash(), + equivocation_proof.second_header.hash(), ); } @@ -465,14 +492,16 @@ fn check_header( } /// A verifier for Aura blocks. -pub struct AuraVerifier { +pub struct AuraVerifier { client: Arc, phantom: PhantomData

, inherent_data_providers: sp_inherents::InherentDataProviders, + can_author_with: CAW, } -impl AuraVerifier - where P: Send + Sync + 'static +impl AuraVerifier where + P: Send + Sync + 'static, + CAW: Send + Sync + 'static, { fn check_inherents( &self, @@ -480,11 +509,22 @@ impl AuraVerifier block_id: BlockId, inherent_data: InherentData, timestamp_now: u64, - ) -> Result<(), Error> - where C: ProvideRuntimeApi, C::Api: BlockBuilderApi + ) -> Result<(), Error> where + C: ProvideRuntimeApi, C::Api: BlockBuilderApi, + CAW: CanAuthorWith, { const MAX_TIMESTAMP_DRIFT_SECS: u64 = 60; + if let Err(e) = self.can_author_with.can_author_with(&block_id) { + debug!( + target: "aura", + "Skipping `check_inherents` as authoring version is not compatible: {}", + e, + ); + + return Ok(()) + } + let inherent_res = self.client.runtime_api().check_inherents( &block_id, block, @@ -526,7 +566,7 @@ impl AuraVerifier } #[forbid(deprecated)] -impl Verifier for AuraVerifier where +impl Verifier for AuraVerifier where C: ProvideRuntimeApi + Send + Sync + @@ -538,6 +578,7 @@ impl Verifier for AuraVerifier where P: Pair + Send + Sync + 'static, P::Public: Send + Sync + Hash + Eq + Clone + Decode + Encode + Debug + 'static, P::Signature: Encode + Decode, + CAW: CanAuthorWith + Send + Sync + 'static, { fn verify( &mut self, @@ -686,9 +727,6 @@ fn authorities(client: &C, at: &BlockId) -> Result, Consensus .ok_or_else(|| sp_consensus::Error::InvalidAuthoritiesSet.into()) } -/// The Aura import queue type. -pub type AuraImportQueue = BasicQueue; - /// Register the aura inherent data provider, if not registered already. fn register_aura_inherent_data_provider( inherent_data_providers: &InherentDataProviders, @@ -788,7 +826,7 @@ impl BlockImport for AuraBlockImport( +pub fn import_queue( slot_duration: SlotDuration, block_import: I, justification_import: Option>, @@ -796,7 +834,9 @@ pub fn import_queue( client: Arc, inherent_data_providers: InherentDataProviders, spawner: &S, -) -> Result>, sp_consensus::Error> where + registry: Option<&Registry>, + can_author_with: CAW, +) -> Result, sp_consensus::Error> where B: BlockT, C::Api: BlockBuilderApi + AuraApi> + ApiExt, C: 'static + ProvideRuntimeApi + BlockOf + ProvideCache + Send + Sync + AuxStore + HeaderBackend, @@ -805,15 +845,17 @@ pub fn import_queue( P: Pair + Send + Sync + 'static, P::Public: Clone + Eq + Send + Sync + Hash + Debug + Encode + Decode, P::Signature: Encode + Decode, - S: sp_core::traits::SpawnBlocking, + S: sp_core::traits::SpawnNamed, + CAW: CanAuthorWith + Send + Sync + 'static, { register_aura_inherent_data_provider(&inherent_data_providers, slot_duration.get())?; initialize_authorities_cache(&*client)?; let verifier = AuraVerifier { - client: client.clone(), + client, inherent_data_providers, phantom: PhantomData, + can_author_with, }; Ok(BasicQueue::new( @@ -822,13 +864,14 @@ pub fn import_queue( justification_import, finality_proof_import, spawner, + registry, )) } #[cfg(test)] mod tests { use super::*; - use sp_consensus::{NoNetwork as DummyOracle, Proposal, RecordProof}; + use sp_consensus::{NoNetwork as DummyOracle, Proposal, RecordProof, AlwaysCanAuthor}; use sc_network_test::{Block as TestBlock, *}; use sp_runtime::traits::{Block as BlockT, DigestFor}; use sc_network::config::ProtocolConfig; @@ -836,8 +879,11 @@ mod tests { use sp_keyring::sr25519::Keyring; use sc_client_api::BlockchainEvents; use sp_consensus_aura::sr25519::AuthorityPair; + use sc_consensus_slots::SimpleSlotWorker; use std::task::Poll; use sc_block_builder::BlockBuilderProvider; + use sp_runtime::traits::Header as _; + use substrate_test_runtime_client::runtime::{Header, H256}; type Error = sp_blockchain::Error; @@ -872,7 +918,7 @@ mod tests { type Proposal = future::Ready, Error>>; fn propose( - &mut self, + self, _: InherentData, digests: DigestFor, _: Duration, @@ -895,7 +941,7 @@ mod tests { } impl TestNetFactory for AuraTestNet { - type Verifier = AuraVerifier; + type Verifier = AuraVerifier; type PeerData = (); /// Create new test network with peers and given config. @@ -922,6 +968,7 @@ mod tests { client, inherent_data_providers, phantom: Default::default(), + can_author_with: AlwaysCanAuthor, } }, PeersClient::Light(_, _) => unreachable!("No (yet) tests for light client + Aura"), @@ -1021,4 +1068,55 @@ mod tests { Keyring::Charlie.public().into() ]); } + + #[test] + fn current_node_authority_should_claim_slot() { + let net = AuraTestNet::new(4); + + let mut authorities = vec![ + Keyring::Alice.public().into(), + Keyring::Bob.public().into(), + Keyring::Charlie.public().into() + ]; + + let keystore_path = tempfile::tempdir().expect("Creates keystore path"); + let keystore = sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore."); + let my_key = keystore.write() + .generate_by_type::(AuthorityPair::ID) + .expect("Key should be created"); + authorities.push(my_key.public()); + + let net = Arc::new(Mutex::new(net)); + + let mut net = net.lock(); + let peer = net.peer(3); + let client = peer.client().as_full().expect("full clients are created").clone(); + let environ = DummyFactory(client.clone()); + + let worker = AuraWorker { + client: client.clone(), + block_import: Arc::new(Mutex::new(client)), + env: environ, + keystore, + sync_oracle: DummyOracle.clone(), + force_authoring: false, + _key_type: PhantomData::, + }; + + let head = Header::new( + 1, + H256::from_low_u64_be(0), + H256::from_low_u64_be(0), + Default::default(), + Default::default() + ); + assert!(worker.claim_slot(&head, 0, &authorities).is_none()); + assert!(worker.claim_slot(&head, 1, &authorities).is_none()); + assert!(worker.claim_slot(&head, 2, &authorities).is_none()); + assert!(worker.claim_slot(&head, 3, &authorities).is_some()); + assert!(worker.claim_slot(&head, 4, &authorities).is_none()); + assert!(worker.claim_slot(&head, 5, &authorities).is_none()); + assert!(worker.claim_slot(&head, 6, &authorities).is_none()); + assert!(worker.claim_slot(&head, 7, &authorities).is_some()); + } } diff --git a/client/consensus/babe/Cargo.toml b/client/consensus/babe/Cargo.toml index ddae8f84b7e3ae9edc265df6d3b1f76bcc40e837..583856709670699671e83025862e5752b45acba3 100644 --- a/client/consensus/babe/Cargo.toml +++ b/client/consensus/babe/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-consensus-babe" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "BABE consensus algorithm for substrate" edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sc-consensus-babe" @@ -13,31 +13,33 @@ documentation = "https://docs.rs/sc-consensus-babe" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-consensus-babe = { version = "0.8.0-dev", path = "../../../primitives/consensus/babe" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-application-crypto = { version = "2.0.0-dev", path = "../../../primitives/application-crypto" } +codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } +sp-consensus-babe = { version = "0.8.0-rc6", path = "../../../primitives/consensus/babe" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-application-crypto = { version = "2.0.0-rc6", path = "../../../primitives/application-crypto" } num-bigint = "0.2.3" num-rational = "0.2.2" num-traits = "0.2.8" serde = { version = "1.0.104", features = ["derive"] } -sp-version = { version = "2.0.0-dev", path = "../../../primitives/version" } -sp-io = { version = "2.0.0-dev", path = "../../../primitives/io" } -sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } -sp-timestamp = { version = "2.0.0-dev", path = "../../../primitives/timestamp" } -sc-telemetry = { version = "2.0.0-dev", path = "../../telemetry" } -sc-keystore = { version = "2.0.0-dev", path = "../../keystore" } -sc-client-api = { version = "2.0.0-dev", path = "../../api" } -sc-consensus-epochs = { version = "0.8.0-dev", path = "../epochs" } -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -sp-block-builder = { version = "2.0.0-dev", path = "../../../primitives/block-builder" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -sp-consensus-vrf = { version = "0.8.0-dev", path = "../../../primitives/consensus/vrf" } -sc-consensus-uncles = { version = "0.8.0-dev", path = "../uncles" } -sc-consensus-slots = { version = "0.8.0-dev", path = "../slots" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -fork-tree = { version = "2.0.0-dev", path = "../../../utils/fork-tree" } +sp-version = { version = "2.0.0-rc6", path = "../../../primitives/version" } +sp-io = { version = "2.0.0-rc6", path = "../../../primitives/io" } +sp-inherents = { version = "2.0.0-rc6", path = "../../../primitives/inherents" } +sp-timestamp = { version = "2.0.0-rc6", path = "../../../primitives/timestamp" } +sc-telemetry = { version = "2.0.0-rc6", path = "../../telemetry" } +sc-keystore = { version = "2.0.0-rc6", path = "../../keystore" } +sc-client-api = { version = "2.0.0-rc6", path = "../../api" } +sc-consensus-epochs = { version = "0.8.0-rc6", path = "../epochs" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +sp-block-builder = { version = "2.0.0-rc6", path = "../../../primitives/block-builder" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sp-consensus-vrf = { version = "0.8.0-rc6", path = "../../../primitives/consensus/vrf" } +sc-consensus-uncles = { version = "0.8.0-rc6", path = "../uncles" } +sc-consensus-slots = { version = "0.8.0-rc6", path = "../slots" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-utils = { version = "2.0.0-rc6", path = "../../../primitives/utils" } +fork-tree = { version = "2.0.0-rc6", path = "../../../utils/fork-tree" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../../utils/prometheus", version = "0.8.0-rc6"} futures = "0.3.4" futures-timer = "3.0.1" parking_lot = "0.10.0" @@ -47,16 +49,18 @@ rand = "0.7.2" merlin = "2.0" pdqselect = "0.1.0" derive_more = "0.99.2" +retain_mut = "0.1.1" [dev-dependencies] -sp-keyring = { version = "2.0.0-dev", path = "../../../primitives/keyring" } -sc-executor = { version = "0.8.0-dev", path = "../../executor" } -sc-network = { version = "0.8.0-dev", path = "../../network" } -sc-network-test = { version = "0.8.0-dev", path = "../../network/test" } -sc-service = { version = "0.8.0-dev", default-features = false, path = "../../service" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sc-block-builder = { version = "0.8.0-dev", path = "../../block-builder" } +sp-keyring = { version = "2.0.0-rc6", path = "../../../primitives/keyring" } +sc-executor = { version = "0.8.0-rc6", path = "../../executor" } +sc-network = { version = "0.8.0-rc6", path = "../../network" } +sc-network-test = { version = "0.8.0-rc6", path = "../../network/test" } +sc-service = { version = "0.8.0-rc6", default-features = false, path = "../../service" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../test-utils/runtime/client" } +sc-block-builder = { version = "0.8.0-rc6", path = "../../block-builder" } env_logger = "0.7.0" +rand_chacha = "0.2.2" tempfile = "3.1.0" [features] diff --git a/client/consensus/babe/README.md b/client/consensus/babe/README.md new file mode 100644 index 0000000000000000000000000000000000000000..faba3948ed71583bb04d4f36962ec92c806c1634 --- /dev/null +++ b/client/consensus/babe/README.md @@ -0,0 +1,48 @@ +# BABE (Blind Assignment for Blockchain Extension) + +BABE is a slot-based block production mechanism which uses a VRF PRNG to +randomly perform the slot allocation. On every slot, all the authorities +generate a new random number with the VRF function and if it is lower than a +given threshold (which is proportional to their weight/stake) they have a +right to produce a block. The proof of the VRF function execution will be +used by other peer to validate the legitimacy of the slot claim. + +The engine is also responsible for collecting entropy on-chain which will be +used to seed the given VRF PRNG. An epoch is a contiguous number of slots +under which we will be using the same authority set. During an epoch all VRF +outputs produced as a result of block production will be collected on an +on-chain randomness pool. Epoch changes are announced one epoch in advance, +i.e. when ending epoch N, we announce the parameters (randomness, +authorities, etc.) for epoch N+2. + +Since the slot assignment is randomized, it is possible that a slot is +assigned to multiple validators in which case we will have a temporary fork, +or that a slot is assigned to no validator in which case no block is +produced. Which means that block times are not deterministic. + +The protocol has a parameter `c` [0, 1] for which `1 - c` is the probability +of a slot being empty. The choice of this parameter affects the security of +the protocol relating to maximum tolerable network delays. + +In addition to the VRF-based slot assignment described above, which we will +call primary slots, the engine also supports a deterministic secondary slot +assignment. Primary slots take precedence over secondary slots, when +authoring the node starts by trying to claim a primary slot and falls back +to a secondary slot claim attempt. The secondary slot assignment is done +by picking the authority at index: + +`blake2_256(epoch_randomness ++ slot_number) % authorities_len`. + +The secondary slots supports either a `SecondaryPlain` or `SecondaryVRF` +variant. Comparing with `SecondaryPlain` variant, the `SecondaryVRF` variant +generates an additional VRF output. The output is not included in beacon +randomness, but can be consumed by parachains. + +The fork choice rule is weight-based, where weight equals the number of +primary blocks in the chain. We will pick the heaviest chain (more primary +blocks) and will go with the longest one in case of a tie. + +An in-depth description and analysis of the protocol can be found here: + + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/consensus/babe/rpc/Cargo.toml b/client/consensus/babe/rpc/Cargo.toml index 1856ff8bafe63eb945a910cb4b4971ad80a827c7..4d2e89af3b0ed374e1d161f5f9efe872b70b7523 100644 --- a/client/consensus/babe/rpc/Cargo.toml +++ b/client/consensus/babe/rpc/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-consensus-babe-rpc" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "RPC extensions for the BABE consensus algorithm" edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,24 +12,27 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-consensus-babe = { version = "0.8.0-dev", path = "../" } -jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.5" -jsonrpc-derive = "14.0.3" -sp-consensus-babe = { version = "0.8.0-dev", path = "../../../../primitives/consensus/babe" } +sc-consensus-babe = { version = "0.8.0-rc6", path = "../" } +sc-rpc-api = { version = "0.8.0-rc6", path = "../../../rpc-api" } +jsonrpc-core = "14.2.0" +jsonrpc-core-client = "14.2.0" +jsonrpc-derive = "14.2.1" +sp-consensus-babe = { version = "0.8.0-rc6", path = "../../../../primitives/consensus/babe" } serde = { version = "1.0.104", features=["derive"] } -sp-blockchain = { version = "2.0.0-dev", path = "../../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-dev", path = "../../../../primitives/runtime" } -sc-consensus-epochs = { version = "0.8.0-dev", path = "../../epochs" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../../primitives/runtime" } +sc-consensus-epochs = { version = "0.8.0-rc6", path = "../../epochs" } futures = { version = "0.3.4", features = ["compat"] } derive_more = "0.99.2" -sp-api = { version = "2.0.0-dev", path = "../../../../primitives/api" } -sp-consensus = { version = "0.8.0-dev", path = "../../../../primitives/consensus/common" } -sp-core = { version = "2.0.0-dev", path = "../../../../primitives/core" } -sc-keystore = { version = "2.0.0-dev", path = "../../../keystore" } +sp-api = { version = "2.0.0-rc6", path = "../../../../primitives/api" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../../primitives/consensus/common" } +sp-core = { version = "2.0.0-rc6", path = "../../../../primitives/core" } +sp-application-crypto = { version = "2.0.0-rc6", path = "../../../../primitives/application-crypto" } +sc-keystore = { version = "2.0.0-rc6", path = "../../../keystore" } [dev-dependencies] -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } -sp-application-crypto = { version = "2.0.0-dev", path = "../../../../primitives/application-crypto" } -sp-keyring = { version = "2.0.0-dev", path = "../../../../primitives/keyring" } +sc-consensus = { version = "0.8.0-rc6", path = "../../../consensus/common" } +serde_json = "1.0.50" +sp-keyring = { version = "2.0.0-rc6", path = "../../../../primitives/keyring" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../../test-utils/runtime/client" } tempfile = "3.1.0" diff --git a/client/consensus/babe/rpc/README.md b/client/consensus/babe/rpc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e76dd3dc67f81d3b789e718acbb8cb8b0e755cec --- /dev/null +++ b/client/consensus/babe/rpc/README.md @@ -0,0 +1,3 @@ +RPC api for babe. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/consensus/babe/rpc/src/lib.rs b/client/consensus/babe/rpc/src/lib.rs index 44273a285949f4b72b84875bab043af2ab56a838..652f4f00baac2ae582415142c540b95014d26894 100644 --- a/client/consensus/babe/rpc/src/lib.rs +++ b/client/consensus/babe/rpc/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! RPC api for babe. @@ -30,13 +32,18 @@ use sp_consensus_babe::{ digests::PreDigest, }; use serde::{Deserialize, Serialize}; +use sp_core::{ + crypto::Public, + traits::BareCryptoStore, +}; +use sp_application_crypto::AppKey; use sc_keystore::KeyStorePtr; +use sc_rpc_api::DenyUnsafe; use sp_api::{ProvideRuntimeApi, BlockId}; -use sp_core::crypto::Pair; use sp_runtime::traits::{Block as BlockT, Header as _}; use sp_consensus::{SelectChain, Error as ConsensusError}; use sp_blockchain::{HeaderBackend, HeaderMetadata, Error as BlockChainError}; -use std::{collections::HashMap, fmt, sync::Arc}; +use std::{collections::HashMap, sync::Arc}; type FutureResult = Box + Send>; @@ -49,8 +56,8 @@ pub trait BabeApi { fn epoch_authorship(&self) -> FutureResult>; } -/// Implements the BabeRPC trait for interacting with Babe. -pub struct BabeRPCHandler { +/// Implements the BabeRpc trait for interacting with Babe. +pub struct BabeRpcHandler { /// shared reference to the client. client: Arc, /// shared reference to EpochChanges @@ -61,9 +68,11 @@ pub struct BabeRPCHandler { babe_config: Config, /// The SelectChain strategy select_chain: SC, + /// Whether to deny unsafe calls + deny_unsafe: DenyUnsafe, } -impl BabeRPCHandler { +impl BabeRpcHandler { /// Creates a new instance of the BabeRpc handler. pub fn new( client: Arc, @@ -71,6 +80,7 @@ impl BabeRPCHandler { keystore: KeyStorePtr, babe_config: Config, select_chain: SC, + deny_unsafe: DenyUnsafe, ) -> Self { Self { client, @@ -78,19 +88,23 @@ impl BabeRPCHandler { keystore, babe_config, select_chain, + deny_unsafe, } } } -impl BabeApi for BabeRPCHandler +impl BabeApi for BabeRpcHandler where B: BlockT, C: ProvideRuntimeApi + HeaderBackend + HeaderMetadata + 'static, C::Api: BabeRuntimeApi, - ::Error: fmt::Debug, SC: SelectChain + Clone + 'static, { fn epoch_authorship(&self) -> FutureResult> { + if let Err(err) = self.deny_unsafe.check_if_safe() { + return Box::new(rpc_future::err(err.into())); + } + let ( babe_config, keystore, @@ -116,32 +130,33 @@ impl BabeApi for BabeRPCHandler let mut claims: HashMap = HashMap::new(); - let key_pairs = { - let keystore = keystore.read(); + let keys = { + let ks = keystore.read(); epoch.authorities.iter() .enumerate() - .flat_map(|(i, a)| { - keystore - .key_pair::(&a.0) - .ok() - .map(|kp| (kp, i)) + .filter_map(|(i, a)| { + if ks.has_keys(&[(a.0.to_raw_vec(), AuthorityId::ID)]) { + Some((a.0.clone(), i)) + } else { + None + } }) .collect::>() }; for slot_number in epoch_start..epoch_end { if let Some((claim, key)) = - authorship::claim_slot_using_key_pairs(slot_number, &epoch, &key_pairs) + authorship::claim_slot_using_keys(slot_number, &epoch, &keystore, &keys) { match claim { PreDigest::Primary { .. } => { - claims.entry(key.public()).or_default().primary.push(slot_number); + claims.entry(key).or_default().primary.push(slot_number); } PreDigest::SecondaryPlain { .. } => { - claims.entry(key.public()).or_default().secondary.push(slot_number); + claims.entry(key).or_default().secondary.push(slot_number); } PreDigest::SecondaryVRF { .. } => { - claims.entry(key.public()).or_default().secondary_vrf.push(slot_number); + claims.entry(key).or_default().secondary_vrf.push(slot_number); }, }; } @@ -213,7 +228,10 @@ fn epoch_data( mod tests { use super::*; use substrate_test_runtime_client::{ + runtime::Block, + Backend, DefaultTestClientBuilderExt, + TestClient, TestClientBuilderExt, TestClientBuilder, }; @@ -235,8 +253,9 @@ mod tests { (keystore, keystore_path) } - #[test] - fn rpc() { + fn test_babe_rpc_handler( + deny_unsafe: DenyUnsafe + ) -> BabeRpcHandler> { let builder = TestClientBuilder::new(); let (client, longest_chain) = builder.build_with_longest_chain(); let client = Arc::new(client); @@ -248,9 +267,21 @@ mod tests { ).expect("can initialize block-import"); let epoch_changes = link.epoch_changes().clone(); - let select_chain = longest_chain; let keystore = create_temp_keystore::(Ed25519Keyring::Alice).0; - let handler = BabeRPCHandler::new(client.clone(), epoch_changes, keystore, config, select_chain); + + BabeRpcHandler::new( + client.clone(), + epoch_changes, + keystore, + config, + longest_chain, + deny_unsafe, + ) + } + + #[test] + fn epoch_authorship_works() { + let handler = test_babe_rpc_handler(DenyUnsafe::No); let mut io = IoHandler::new(); io.extend_with(BabeApi::to_delegate(handler)); @@ -259,4 +290,19 @@ mod tests { assert_eq!(Some(response.into()), io.handle_request_sync(request)); } + + #[test] + fn epoch_authorship_is_unsafe() { + let handler = test_babe_rpc_handler(DenyUnsafe::Yes); + let mut io = IoHandler::new(); + + io.extend_with(BabeApi::to_delegate(handler)); + let request = r#"{"jsonrpc":"2.0","method":"babe_epochAuthorship","params": [],"id":1}"#; + + let response = io.handle_request_sync(request).unwrap(); + let mut response: serde_json::Value = serde_json::from_str(&response).unwrap(); + let error: RpcError = serde_json::from_value(response["error"].take()).unwrap(); + + assert_eq!(error, RpcError::method_not_found()) + } } diff --git a/client/consensus/babe/src/authorship.rs b/client/consensus/babe/src/authorship.rs index 584501110b75ff7b2129dcde2bd9fa94be0ff729..682e04e380d7c32eeed887ee0db855b68e37039e 100644 --- a/client/consensus/babe/src/authorship.rs +++ b/client/consensus/babe/src/authorship.rs @@ -16,18 +16,24 @@ //! BABE authority selection and slot claiming. +use sp_application_crypto::AppKey; use sp_consensus_babe::{ - make_transcript, AuthorityId, BabeAuthorityWeight, BABE_VRF_PREFIX, - SlotNumber, AuthorityPair, + BABE_VRF_PREFIX, + AuthorityId, BabeAuthorityWeight, + SlotNumber, + make_transcript, + make_transcript_data, }; use sp_consensus_babe::digests::{ PreDigest, PrimaryPreDigest, SecondaryPlainPreDigest, SecondaryVRFPreDigest, }; use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof}; -use sp_core::{U256, blake2_256}; +use sp_core::{U256, blake2_256, crypto::Public, traits::BareCryptoStore}; use codec::Encode; -use schnorrkel::vrf::VRFInOut; -use sp_core::Pair; +use schnorrkel::{ + keys::PublicKey, + vrf::VRFInOut, +}; use sc_keystore::KeyStorePtr; use super::Epoch; @@ -124,9 +130,10 @@ pub(super) fn secondary_slot_author( fn claim_secondary_slot( slot_number: SlotNumber, epoch: &Epoch, - key_pairs: &[(AuthorityPair, usize)], + keys: &[(AuthorityId, usize)], + keystore: &KeyStorePtr, author_secondary_vrf: bool, -) -> Option<(PreDigest, AuthorityPair)> { +) -> Option<(PreDigest, AuthorityId)> { let Epoch { authorities, randomness, epoch_index, .. } = epoch; if authorities.is_empty() { @@ -139,31 +146,41 @@ fn claim_secondary_slot( *randomness, )?; - for (pair, authority_index) in key_pairs { - if pair.public() == *expected_author { + for (authority_id, authority_index) in keys { + if authority_id == expected_author { let pre_digest = if author_secondary_vrf { - let transcript = super::authorship::make_transcript( + let transcript_data = super::authorship::make_transcript_data( randomness, slot_number, *epoch_index, ); - - let s = get_keypair(&pair).vrf_sign(transcript); - - PreDigest::SecondaryVRF(SecondaryVRFPreDigest { + let result = keystore.read().sr25519_vrf_sign( + AuthorityId::ID, + authority_id.as_ref(), + transcript_data, + ); + if let Ok(signature) = result { + Some(PreDigest::SecondaryVRF(SecondaryVRFPreDigest { + slot_number, + vrf_output: VRFOutput(signature.output), + vrf_proof: VRFProof(signature.proof), + authority_index: *authority_index as u32, + })) + } else { + None + } + } else if keystore.read().has_keys(&[(authority_id.to_raw_vec(), AuthorityId::ID)]) { + Some(PreDigest::SecondaryPlain(SecondaryPlainPreDigest { slot_number, - vrf_output: VRFOutput(s.0.to_output()), - vrf_proof: VRFProof(s.1), authority_index: *authority_index as u32, - }) + })) } else { - PreDigest::SecondaryPlain(SecondaryPlainPreDigest { - slot_number, - authority_index: *authority_index as u32, - }) + None }; - return Some((pre_digest, pair.clone())); + if let Some(pre_digest) = pre_digest { + return Some((pre_digest, authority_id.clone())); + } } } @@ -178,27 +195,23 @@ pub fn claim_slot( slot_number: SlotNumber, epoch: &Epoch, keystore: &KeyStorePtr, -) -> Option<(PreDigest, AuthorityPair)> { - let key_pairs = { - let keystore = keystore.read(); - epoch.authorities.iter() - .enumerate() - .flat_map(|(i, a)| { - keystore.key_pair::(&a.0).ok().map(|kp| (kp, i)) - }) - .collect::>() - }; - claim_slot_using_key_pairs(slot_number, epoch, &key_pairs) +) -> Option<(PreDigest, AuthorityId)> { + let authorities = epoch.authorities.iter() + .enumerate() + .map(|(index, a)| (a.0.clone(), index)) + .collect::>(); + claim_slot_using_keys(slot_number, epoch, keystore, &authorities) } /// Like `claim_slot`, but allows passing an explicit set of key pairs. Useful if we intend /// to make repeated calls for different slots using the same key pairs. -pub fn claim_slot_using_key_pairs( +pub fn claim_slot_using_keys( slot_number: SlotNumber, epoch: &Epoch, - key_pairs: &[(AuthorityPair, usize)], -) -> Option<(PreDigest, AuthorityPair)> { - claim_primary_slot(slot_number, epoch, epoch.config.c, &key_pairs) + keystore: &KeyStorePtr, + keys: &[(AuthorityId, usize)], +) -> Option<(PreDigest, AuthorityId)> { + claim_primary_slot(slot_number, epoch, epoch.config.c, keystore, &keys) .or_else(|| { if epoch.config.allowed_slots.is_secondary_plain_slots_allowed() || epoch.config.allowed_slots.is_secondary_vrf_slots_allowed() @@ -206,7 +219,8 @@ pub fn claim_slot_using_key_pairs( claim_secondary_slot( slot_number, &epoch, - &key_pairs, + keys, + keystore, epoch.config.allowed_slots.is_secondary_vrf_slots_allowed(), ) } else { @@ -215,11 +229,6 @@ pub fn claim_slot_using_key_pairs( }) } -fn get_keypair(q: &AuthorityPair) -> &schnorrkel::Keypair { - use sp_core::crypto::IsWrappedBy; - sp_core::sr25519::Pair::from_ref(q).as_ref() -} - /// Claim a primary slot if it is our turn. Returns `None` if it is not our turn. /// This hashes the slot number, epoch, genesis hash, and chain randomness into /// the VRF. If the VRF produces a value less than `threshold`, it is our turn, @@ -228,35 +237,89 @@ fn claim_primary_slot( slot_number: SlotNumber, epoch: &Epoch, c: (u64, u64), - key_pairs: &[(AuthorityPair, usize)], -) -> Option<(PreDigest, AuthorityPair)> { + keystore: &KeyStorePtr, + keys: &[(AuthorityId, usize)], +) -> Option<(PreDigest, AuthorityId)> { let Epoch { authorities, randomness, epoch_index, .. } = epoch; - for (pair, authority_index) in key_pairs { - let transcript = super::authorship::make_transcript(randomness, slot_number, *epoch_index); - + for (authority_id, authority_index) in keys { + let transcript = super::authorship::make_transcript( + randomness, + slot_number, + *epoch_index + ); + let transcript_data = super::authorship::make_transcript_data( + randomness, + slot_number, + *epoch_index + ); // Compute the threshold we will use. // // We already checked that authorities contains `key.public()`, so it can't // be empty. Therefore, this division in `calculate_threshold` is safe. let threshold = super::authorship::calculate_primary_threshold(c, authorities, *authority_index); - let pre_digest = get_keypair(pair) - .vrf_sign_after_check(transcript, |inout| super::authorship::check_primary_threshold(inout, threshold)) - .map(|s| { - PreDigest::Primary(PrimaryPreDigest { + let result = keystore.read().sr25519_vrf_sign( + AuthorityId::ID, + authority_id.as_ref(), + transcript_data, + ); + if let Ok(signature) = result { + let public = PublicKey::from_bytes(&authority_id.to_raw_vec()).ok()?; + let inout = match signature.output.attach_input_hash(&public, transcript) { + Ok(inout) => inout, + Err(_) => continue, + }; + if super::authorship::check_primary_threshold(&inout, threshold) { + let pre_digest = PreDigest::Primary(PrimaryPreDigest { slot_number, - vrf_output: VRFOutput(s.0.to_output()), - vrf_proof: VRFProof(s.1), + vrf_output: VRFOutput(signature.output), + vrf_proof: VRFProof(signature.proof), authority_index: *authority_index as u32, - }) - }); + }); - // early exit on first successful claim - if let Some(pre_digest) = pre_digest { - return Some((pre_digest, pair.clone())); + return Some((pre_digest, authority_id.clone())); + } } } None } + +#[cfg(test)] +mod tests { + use super::*; + use sp_core::{sr25519::Pair, crypto::Pair as _}; + use sp_consensus_babe::{AuthorityId, BabeEpochConfiguration, AllowedSlots}; + + #[test] + fn claim_secondary_plain_slot_works() { + let keystore = sc_keystore::Store::new_in_memory(); + let valid_public_key = dbg!(keystore.write().sr25519_generate_new( + AuthorityId::ID, + Some(sp_core::crypto::DEV_PHRASE), + ).unwrap()); + + let authorities = vec![ + (AuthorityId::from(Pair::generate().0.public()), 5), + (AuthorityId::from(Pair::generate().0.public()), 7), + ]; + + let mut epoch = Epoch { + epoch_index: 10, + start_slot: 0, + duration: 20, + authorities: authorities.clone(), + randomness: Default::default(), + config: BabeEpochConfiguration { + c: (3, 10), + allowed_slots: AllowedSlots::PrimaryAndSecondaryPlainSlots, + }, + }; + + assert!(claim_slot(10, &epoch, &keystore).is_none()); + + epoch.authorities.push((valid_public_key.clone().into(), 10)); + assert_eq!(claim_slot(10, &epoch, &keystore).unwrap().1, valid_public_key.into()); + } +} diff --git a/client/consensus/babe/src/lib.rs b/client/consensus/babe/src/lib.rs index d6498c119b361043b575edba8c8e8bff99f8f229..67aca1dd43e7a28567d506a3d12c7b1cc5867547 100644 --- a/client/consensus/babe/src/lib.rs +++ b/client/consensus/babe/src/lib.rs @@ -76,12 +76,14 @@ pub use sp_consensus_babe::{ pub use sp_consensus::SyncOracle; use std::{ collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration}, - any::Any, borrow::Cow + any::Any, borrow::Cow, convert::TryInto, }; use sp_consensus::{ImportResult, CanAuthorWith}; use sp_consensus::import_queue::{ BoxJustificationImport, BoxFinalityProofImport, }; +use sp_core::{crypto::Public, traits::BareCryptoStore}; +use sp_application_crypto::AppKey; use sp_runtime::{ generic::{BlockId, OpaqueDigestItemId}, Justification, traits::{Block as BlockT, Header, DigestItemFor, Zero}, @@ -89,7 +91,6 @@ use sp_runtime::{ use sp_api::{ProvideRuntimeApi, NumberFor}; use sc_keystore::KeyStorePtr; use parking_lot::Mutex; -use sp_core::Pair; use sp_inherents::{InherentDataProviders, InherentData}; use sc_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG}; use sp_consensus::{ @@ -99,15 +100,18 @@ use sp_consensus::{ }; use sp_consensus_babe::inherents::BabeInherentData; use sp_timestamp::{TimestampInherentData, InherentType as TimestampInherent}; -use sp_consensus::import_queue::{Verifier, BasicQueue, CacheKeyId}; +use sp_consensus::import_queue::{Verifier, BasicQueue, DefaultImportQueue, CacheKeyId}; use sc_client_api::{ backend::AuxStore, BlockchainEvents, ProvideUncles, }; use sp_block_builder::BlockBuilder as BlockBuilderApi; +use futures::channel::mpsc::{channel, Sender, Receiver}; +use retain_mut::RetainMut; use futures::prelude::*; use log::{debug, info, log, trace, warn}; +use prometheus_endpoint::Registry; use sc_consensus_slots::{ SlotWorker, SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation, }; @@ -368,7 +372,7 @@ pub fn start_babe(BabeParams { babe_link, can_author_with, }: BabeParams) -> Result< - impl futures::Future, + BabeWorker, sp_consensus::Error, > where B: BlockT, @@ -376,16 +380,18 @@ pub fn start_babe(BabeParams { + HeaderBackend + HeaderMetadata + Send + Sync + 'static, C::Api: BabeApi, SC: SelectChain + 'static, - E: Environment + Send + Sync, + E: Environment + Send + Sync + 'static, E::Proposer: Proposer>, I: BlockImport> + Send + Sync + 'static, Error: std::error::Error + Send + From + From + 'static, - SO: SyncOracle + Send + Sync + Clone, - CAW: CanAuthorWith + Send, + SO: SyncOracle + Send + Sync + Clone + 'static, + CAW: CanAuthorWith + Send + 'static, { let config = babe_link.config; - let worker = BabeWorker { + let slot_notification_sinks = Arc::new(Mutex::new(Vec::new())); + + let worker = BabeSlotWorker { client: client.clone(), block_import: Arc::new(Mutex::new(block_import)), env, @@ -393,6 +399,7 @@ pub fn start_babe(BabeParams { force_authoring, keystore, epoch_changes: babe_link.epoch_changes.clone(), + slot_notification_sinks: slot_notification_sinks.clone(), config: config.clone(), }; @@ -404,7 +411,7 @@ pub fn start_babe(BabeParams { )?; info!(target: "babe", "👶 Starting BABE Authorship worker"); - Ok(sc_consensus_slots::start_slot_worker( + let inner = sc_consensus_slots::start_slot_worker( config.0, select_chain, worker, @@ -412,10 +419,49 @@ pub fn start_babe(BabeParams { inherent_data_providers, babe_link.time_source, can_author_with, - )) + ); + Ok(BabeWorker { + inner: Box::pin(inner), + slot_notification_sinks, + }) +} + +/// Worker for Babe which implements `Future`. This must be polled. +#[must_use] +pub struct BabeWorker { + inner: Pin + Send + 'static>>, + slot_notification_sinks: Arc, Epoch>)>>>>, +} + +impl BabeWorker { + /// Return an event stream of notifications for when new slot happens, and the corresponding + /// epoch descriptor. + pub fn slot_notification_stream( + &self + ) -> Receiver<(u64, ViableEpochDescriptor, Epoch>)> { + const CHANNEL_BUFFER_SIZE: usize = 1024; + + let (sink, stream) = channel(CHANNEL_BUFFER_SIZE); + self.slot_notification_sinks.lock().push(sink); + stream + } +} + +impl futures::Future for BabeWorker { + type Output = (); + + fn poll( + mut self: Pin<&mut Self>, + cx: &mut futures::task::Context + ) -> futures::task::Poll { + self.inner.as_mut().poll(cx) + } } -struct BabeWorker { +/// Slot notification sinks. +type SlotNotificationSinks = Arc::Hash, NumberFor, Epoch>)>>>>; + +struct BabeSlotWorker { client: Arc, block_import: Arc>, env: E, @@ -423,10 +469,11 @@ struct BabeWorker { force_authoring: bool, keystore: KeyStorePtr, epoch_changes: SharedEpochChanges, + slot_notification_sinks: SlotNotificationSinks, config: Config, } -impl sc_consensus_slots::SimpleSlotWorker for BabeWorker where +impl sc_consensus_slots::SimpleSlotWorker for BabeSlotWorker where B: BlockT, C: ProvideRuntimeApi + ProvideCache + @@ -440,7 +487,7 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork Error: std::error::Error + Send + From + From + 'static, { type EpochData = ViableEpochDescriptor, Epoch>; - type Claim = (PreDigest, AuthorityPair); + type Claim = (PreDigest, AuthorityId); type SyncOracle = SO; type CreateProposer = Pin> + Send + 'static @@ -500,6 +547,28 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork s } + fn notify_slot( + &self, + _parent_header: &B::Header, + slot_number: SlotNumber, + epoch_descriptor: &ViableEpochDescriptor, Epoch>, + ) { + self.slot_notification_sinks.lock() + .retain_mut(|sink| { + match sink.try_send((slot_number, epoch_descriptor.clone())) { + Ok(()) => true, + Err(e) => { + if e.is_full() { + warn!(target: "babe", "Trying to notify a slot but the channel is full"); + true + } else { + false + } + }, + } + }); + } + fn pre_digest_data( &self, _slot_number: u64, @@ -517,12 +586,30 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork StorageChanges, Self::Claim, Self::EpochData, - ) -> sp_consensus::BlockImportParams + Send> { - Box::new(|header, header_hash, body, storage_changes, (_, pair), epoch_descriptor| { + ) -> Result< + sp_consensus::BlockImportParams, + sp_consensus::Error> + Send + 'static> + { + let keystore = self.keystore.clone(); + Box::new(move |header, header_hash, body, storage_changes, (_, public), epoch_descriptor| { // sign the pre-sealed hash of the block and then // add it to a digest item. - let signature = pair.sign(header_hash.as_ref()); - let digest_item = as CompatibleDigestItem>::babe_seal(signature); + let public_type_pair = public.clone().into(); + let public = public.to_raw_vec(); + let signature = keystore.read() + .sign_with( + ::ID, + &public_type_pair, + header_hash.as_ref() + ) + .map_err(|e| sp_consensus::Error::CannotSign( + public.clone(), e.to_string(), + ))?; + let signature: AuthoritySignature = signature.clone().try_into() + .map_err(|_| sp_consensus::Error::InvalidSignature( + signature, public + ))?; + let digest_item = as CompatibleDigestItem>::babe_seal(signature.into()); let mut import_block = BlockImportParams::new(BlockOrigin::Own, header); import_block.post_digests.push(digest_item); @@ -533,7 +620,7 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork Box::new(BabeIntermediate:: { epoch_descriptor }) as Box, ); - import_block + Ok(import_block) }) } @@ -579,7 +666,7 @@ impl sc_consensus_slots::SimpleSlotWorker for BabeWork } } -impl SlotWorker for BabeWorker where +impl SlotWorker for BabeSlotWorker where B: BlockT, C: ProvideRuntimeApi + ProvideCache + @@ -700,27 +787,41 @@ impl BabeLink { } /// A verifier for Babe blocks. -pub struct BabeVerifier { +pub struct BabeVerifier { client: Arc, + select_chain: SelectChain, inherent_data_providers: sp_inherents::InherentDataProviders, config: Config, epoch_changes: SharedEpochChanges, time_source: TimeSource, + can_author_with: CAW, } -impl BabeVerifier - where - Block: BlockT, - Client: HeaderBackend + HeaderMetadata + ProvideRuntimeApi, - Client::Api: BlockBuilderApi, +impl BabeVerifier +where + Block: BlockT, + Client: AuxStore + HeaderBackend + HeaderMetadata + ProvideRuntimeApi, + Client::Api: BlockBuilderApi + + BabeApi, + SelectChain: sp_consensus::SelectChain, + CAW: CanAuthorWith, { fn check_inherents( &self, block: Block, block_id: BlockId, inherent_data: InherentData, - ) -> Result<(), Error> - { + ) -> Result<(), Error> { + if let Err(e) = self.can_author_with.can_author_with(&block_id) { + debug!( + target: "babe", + "Skipping `check_inherents` as authoring version is not compatible: {}", + e, + ); + + return Ok(()) + } + let inherent_res = self.client.runtime_api().check_inherents( &block_id, block, @@ -737,13 +838,97 @@ impl BabeVerifier Ok(()) } } + + fn check_and_report_equivocation( + &self, + slot_now: SlotNumber, + slot: SlotNumber, + header: &Block::Header, + author: &AuthorityId, + origin: &BlockOrigin, + ) -> Result<(), Error> { + // don't report any equivocations during initial sync + // as they are most likely stale. + if *origin == BlockOrigin::NetworkInitialSync { + return Ok(()); + } + + // check if authorship of this header is an equivocation and return a proof if so. + let equivocation_proof = + match check_equivocation(&*self.client, slot_now, slot, header, author) + .map_err(Error::Client)? + { + Some(proof) => proof, + None => return Ok(()), + }; + + info!( + "Slot author {:?} is equivocating at slot {} with headers {:?} and {:?}", + author, + slot, + equivocation_proof.first_header.hash(), + equivocation_proof.second_header.hash(), + ); + + // get the best block on which we will build and send the equivocation report. + let best_id = self + .select_chain + .best_chain() + .map(|h| BlockId::Hash(h.hash())) + .map_err(|e| Error::Client(e.into()))?; + + // generate a key ownership proof. we start by trying to generate the + // key owernship proof at the parent of the equivocating header, this + // will make sure that proof generation is successful since it happens + // during the on-going session (i.e. session keys are available in the + // state to be able to generate the proof). this might fail if the + // equivocation happens on the first block of the session, in which case + // its parent would be on the previous session. if generation on the + // parent header fails we try with best block as well. + let generate_key_owner_proof = |block_id: &BlockId| { + self.client + .runtime_api() + .generate_key_ownership_proof(block_id, slot, equivocation_proof.offender.clone()) + .map_err(Error::Client) + }; + + let parent_id = BlockId::Hash(*header.parent_hash()); + let key_owner_proof = match generate_key_owner_proof(&parent_id)? { + Some(proof) => proof, + None => match generate_key_owner_proof(&best_id)? { + Some(proof) => proof, + None => { + debug!(target: "babe", "Equivocation offender is not part of the authority set."); + return Ok(()); + } + }, + }; + + // submit equivocation report at best block. + self.client + .runtime_api() + .submit_report_equivocation_unsigned_extrinsic( + &best_id, + equivocation_proof, + key_owner_proof, + ) + .map_err(Error::Client)?; + + info!(target: "babe", "Submitted equivocation report for author {:?}", author); + + Ok(()) + } } -impl Verifier for BabeVerifier where +impl Verifier + for BabeVerifier +where Block: BlockT, Client: HeaderMetadata + HeaderBackend + ProvideRuntimeApi - + Send + Sync + AuxStore + ProvideCache, + + Send + Sync + AuxStore + ProvideCache, Client::Api: BlockBuilderApi + BabeApi, + SelectChain: sp_consensus::SelectChain, + CAW: CanAuthorWith + Send + Sync, { fn verify( &mut self, @@ -804,27 +989,19 @@ impl Verifier for BabeVerifier where CheckedHeader::Checked(pre_header, verified_info) => { let babe_pre_digest = verified_info.pre_digest.as_babe_pre_digest() .expect("check_header always returns a pre-digest digest item; qed"); - let slot_number = babe_pre_digest.slot_number(); - let author = verified_info.author; - // the header is valid but let's check if there was something else already - // proposed at the same slot by the given author - if let Some(equivocation_proof) = check_equivocation( - &*self.client, + // proposed at the same slot by the given author. if there was, we will + // report the equivocation to the runtime. + if let Err(err) = self.check_and_report_equivocation( slot_now, - babe_pre_digest.slot_number(), + slot_number, &header, - &author, - ).map_err(|e| e.to_string())? { - info!( - "Slot author {:?} is equivocating at slot {} with headers {:?} and {:?}", - author, - babe_pre_digest.slot_number(), - equivocation_proof.fst_header().hash(), - equivocation_proof.snd_header().hash(), - ); + &verified_info.author, + &origin, + ) { + warn!(target: "babe", "Error checking/reporting BABE equivocation: {:?}", err); } // if the body is passed through, we need to use the runtime @@ -873,9 +1050,6 @@ impl Verifier for BabeVerifier where } } -/// The BABE import queue type. -pub type BabeImportQueue = BasicQueue; - /// Register the babe inherent data provider, if not registered already. fn register_babe_inherent_data_provider( inherent_data_providers: &InherentDataProviders, @@ -1264,29 +1438,36 @@ pub fn block_import( /// /// The block import object provided must be the `BabeBlockImport` or a wrapper /// of it, otherwise crucial import logic will be omitted. -pub fn import_queue( +pub fn import_queue( babe_link: BabeLink, block_import: Inner, justification_import: Option>, finality_proof_import: Option>, client: Arc, + select_chain: SelectChain, inherent_data_providers: InherentDataProviders, - spawner: &impl sp_core::traits::SpawnBlocking, -) -> ClientResult>> where + spawner: &impl sp_core::traits::SpawnNamed, + registry: Option<&Registry>, + can_author_with: CAW, +) -> ClientResult> where Inner: BlockImport> + Send + Sync + 'static, Client: ProvideRuntimeApi + ProvideCache + Send + Sync + AuxStore + 'static, Client: HeaderBackend + HeaderMetadata, Client::Api: BlockBuilderApi + BabeApi + ApiExt, + SelectChain: sp_consensus::SelectChain + 'static, + CAW: CanAuthorWith + Send + Sync + 'static, { register_babe_inherent_data_provider(&inherent_data_providers, babe_link.config.slot_duration)?; let verifier = BabeVerifier { client, + select_chain, inherent_data_providers, config: babe_link.config, epoch_changes: babe_link.epoch_changes, time_source: babe_link.time_source, + can_author_with, }; Ok(BasicQueue::new( @@ -1295,6 +1476,7 @@ pub fn import_queue( justification_import, finality_proof_import, spawner, + registry, )) } diff --git a/client/consensus/babe/src/tests.rs b/client/consensus/babe/src/tests.rs index f933251d18e8fb624cc6162d6eda1fa1e56b6f35..e302a3b3d0a61d29a56681f486e92e60c2ee8db7 100644 --- a/client/consensus/babe/src/tests.rs +++ b/client/consensus/babe/src/tests.rs @@ -21,11 +21,17 @@ #![allow(deprecated)] use super::*; use authorship::claim_slot; - -use sp_consensus_babe::{AuthorityPair, SlotNumber, AllowedSlots}; +use sp_core::{crypto::Pair, vrf::make_transcript as transcript_from_data}; +use sp_consensus_babe::{ + AuthorityPair, + SlotNumber, + AllowedSlots, + make_transcript, + make_transcript_data, +}; use sc_block_builder::{BlockBuilder, BlockBuilderProvider}; use sp_consensus::{ - NoNetwork as DummyOracle, Proposal, RecordProof, + NoNetwork as DummyOracle, Proposal, RecordProof, AlwaysCanAuthor, import_queue::{BoxBlockImport, BoxJustificationImport, BoxFinalityProofImport}, }; use sc_network_test::*; @@ -35,6 +41,11 @@ use sp_runtime::{generic::DigestItem, traits::{Block as BlockT, DigestFor}}; use sc_client_api::{BlockchainEvents, backend::TransactionFor}; use log::debug; use std::{time::Duration, cell::RefCell, task::Poll}; +use rand::RngCore; +use rand_chacha::{ + rand_core::SeedableRng, + ChaChaRng, +}; type Item = DigestItem; @@ -159,7 +170,7 @@ impl Proposer for DummyProposer { type Proposal = future::Ready, Error>>; fn propose( - &mut self, + mut self, _: InherentData, pre_digests: DigestFor, _: Duration, @@ -203,8 +214,13 @@ pub struct BabeTestNet { type TestHeader = ::Header; type TestExtrinsic = ::Extrinsic; +type TestSelectChain = substrate_test_runtime_client::LongestChain< + substrate_test_runtime_client::Backend, + TestBlock, +>; + pub struct TestVerifier { - inner: BabeVerifier, + inner: BabeVerifier, mutator: Mutator, } @@ -286,19 +302,25 @@ impl TestNetFactory for BabeTestNet { ) -> Self::Verifier { + use substrate_test_runtime_client::DefaultTestClientBuilderExt; + let client = client.as_full().expect("only full clients are used in test"); trace!(target: "babe", "Creating a verifier"); // ensure block import and verifier are linked correctly. let data = maybe_link.as_ref().expect("babe link always provided to verifier instantiation"); + let (_, longest_chain) = TestClientBuilder::new().build_with_longest_chain(); + TestVerifier { inner: BabeVerifier { client: client.clone(), + select_chain: longest_chain, inherent_data_providers: data.inherent_data_providers.clone(), config: data.link.config.clone(), epoch_changes: data.link.epoch_changes.clone(), time_source: data.link.time_source.clone(), + can_author_with: AlwaysCanAuthor, }, mutator: MUTATOR.with(|m| m.borrow().clone()), } @@ -796,3 +818,36 @@ fn verify_slots_are_strictly_increasing() { &mut block_import, ); } + +#[test] +fn babe_transcript_generation_match() { + let _ = env_logger::try_init(); + let keystore_path = tempfile::tempdir().expect("Creates keystore path"); + let keystore = sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); + let pair = keystore.write().insert_ephemeral_from_seed::("//Alice") + .expect("Generates authority pair"); + + let epoch = Epoch { + start_slot: 0, + authorities: vec![(pair.public(), 1)], + randomness: [0; 32], + epoch_index: 1, + duration: 100, + config: BabeEpochConfiguration { + c: (3, 10), + allowed_slots: AllowedSlots::PrimaryAndSecondaryPlainSlots, + }, + }; + + let orig_transcript = make_transcript(&epoch.randomness.clone(), 1, epoch.epoch_index); + let new_transcript = make_transcript_data(&epoch.randomness, 1, epoch.epoch_index); + + let test = |t: merlin::Transcript| -> [u8; 16] { + let mut b = [0u8; 16]; + t.build_rng() + .finalize(&mut ChaChaRng::from_seed([0u8;32])) + .fill_bytes(&mut b); + b + }; + debug_assert!(test(orig_transcript) == test(transcript_from_data(new_transcript))); +} diff --git a/client/consensus/common/Cargo.toml b/client/consensus/common/Cargo.toml index dae6f341d134731917851b73c4eb7c9e4838bb2e..69d5eae851643ae5b09a0000911d11350b6e820a 100644 --- a/client/consensus/common/Cargo.toml +++ b/client/consensus/common/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-consensus" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Collection of common consensus specific imlementations for Substrate (client)" @@ -12,7 +12,7 @@ description = "Collection of common consensus specific imlementations for Substr targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-client-api = { version = "2.0.0-dev", path = "../../api" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +sc-client-api = { version = "2.0.0-rc6", path = "../../api" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } diff --git a/client/consensus/common/README.md b/client/consensus/common/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a6717a1d7a6df682607e9ddf3c45d7bbf6115dfc --- /dev/null +++ b/client/consensus/common/README.md @@ -0,0 +1,3 @@ +Collection of common consensus specific implementations + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/consensus/epochs/Cargo.toml b/client/consensus/epochs/Cargo.toml index de14b5c6be617ff01038abbaeb5c833aa81d05d8..7bcc30e3cff9b20caa3abd75cfd354f2b4353b21 100644 --- a/client/consensus/epochs/Cargo.toml +++ b/client/consensus/epochs/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-consensus-epochs" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Generic epochs-based utilities for consensus" edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,9 +12,9 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } parking_lot = "0.10.0" -fork-tree = { version = "2.0.0-dev", path = "../../../utils/fork-tree" } -sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-dev"} -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sc-client-api = { path = "../../api" , version = "2.0.0-dev"} +fork-tree = { version = "2.0.0-rc6", path = "../../../utils/fork-tree" } +sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-rc6"} +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sc-client-api = { path = "../../api" , version = "2.0.0-rc6"} diff --git a/client/consensus/epochs/README.md b/client/consensus/epochs/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1e74e04172c2400f41d9d3c18037132412feb299 --- /dev/null +++ b/client/consensus/epochs/README.md @@ -0,0 +1,3 @@ +Generic utilities for epoch-based consensus engines. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/consensus/manual-seal/Cargo.toml b/client/consensus/manual-seal/Cargo.toml index b0a3c2bd72b56cd087dbd879f0e58dbdab5972ad..b557f171c35db78540b45aa9d65406c474f88046 100644 --- a/client/consensus/manual-seal/Cargo.toml +++ b/client/consensus/manual-seal/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-consensus-manual-seal" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Manual sealing engine for Substrate" edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -14,27 +14,28 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] derive_more = "0.99.2" futures = "0.3.4" -jsonrpc-core = "14.0.5" -jsonrpc-core-client = "14.0.5" -jsonrpc-derive = "14.0.5" +jsonrpc-core = "14.2.0" +jsonrpc-core-client = "14.2.0" +jsonrpc-derive = "14.2.1" log = "0.4.8" parking_lot = "0.10.0" serde = { version = "1.0", features=["derive"] } assert_matches = "1.3.0" -sc-client-api = { path = "../../../client/api" , version = "2.0.0-dev"} -sc-transaction-pool = { path = "../../transaction-pool" , version = "2.0.0-dev"} -sp-blockchain = { path = "../../../primitives/blockchain" , version = "2.0.0-dev"} -sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common" , version = "0.8.0-dev"} -sp-inherents = { path = "../../../primitives/inherents" , version = "2.0.0-dev"} -sp-runtime = { path = "../../../primitives/runtime" , version = "2.0.0-dev"} -sp-core = { path = "../../../primitives/core" , version = "2.0.0-dev"} -sp-transaction-pool = { path = "../../../primitives/transaction-pool" , version = "2.0.0-dev"} +sc-client-api = { path = "../../../client/api", version = "2.0.0-rc6" } +sc-transaction-pool = { path = "../../transaction-pool", version = "2.0.0-rc6" } +sp-blockchain = { path = "../../../primitives/blockchain", version = "2.0.0-rc6" } +sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common", version = "0.8.0-rc6" } +sp-inherents = { path = "../../../primitives/inherents", version = "2.0.0-rc6" } +sp-runtime = { path = "../../../primitives/runtime", version = "2.0.0-rc6" } +sp-core = { path = "../../../primitives/core", version = "2.0.0-rc6" } +sp-transaction-pool = { path = "../../../primitives/transaction-pool", version = "2.0.0-rc6" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../../utils/prometheus", version = "0.8.0-rc6" } [dev-dependencies] -sc-basic-authorship = { path = "../../basic-authorship" , version = "0.8.0-dev"} -substrate-test-runtime-client = { path = "../../../test-utils/runtime/client" , version = "2.0.0-dev"} -substrate-test-runtime-transaction-pool = { path = "../../../test-utils/runtime/transaction-pool" , version = "2.0.0-dev"} +sc-basic-authorship = { path = "../../basic-authorship", version = "0.8.0-rc6" } +substrate-test-runtime-client = { path = "../../../test-utils/runtime/client", version = "2.0.0-rc6" } +substrate-test-runtime-transaction-pool = { path = "../../../test-utils/runtime/transaction-pool", version = "2.0.0-rc6" } tokio = { version = "0.2", features = ["rt-core", "macros"] } env_logger = "0.7.0" tempfile = "3.1.0" diff --git a/client/consensus/manual-seal/README.md b/client/consensus/manual-seal/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b355f8b73183cc9661b4c65d76a060d9f6cc8918 --- /dev/null +++ b/client/consensus/manual-seal/README.md @@ -0,0 +1,4 @@ +A manual sealing engine: the engine listens for rpc calls to seal blocks and create forks. +This is suitable for a testing environment. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/consensus/manual-seal/src/error.rs b/client/consensus/manual-seal/src/error.rs index d6ee9f176772128a8f597e91b944cbca3e978a0c..2411a839b027ceb51b6e927f5c09ad030571231a 100644 --- a/client/consensus/manual-seal/src/error.rs +++ b/client/consensus/manual-seal/src/error.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A manual sealing engine: the engine listens for rpc calls to seal blocks and create forks. //! This is suitable for a testing environment. diff --git a/client/consensus/manual-seal/src/lib.rs b/client/consensus/manual-seal/src/lib.rs index c59bd61a973cf94fff32edd2684d7d952d40b070..36aeffd9794f084c24fc2bf86892a3e00ae62cd0 100644 --- a/client/consensus/manual-seal/src/lib.rs +++ b/client/consensus/manual-seal/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A manual sealing engine: the engine listens for rpc calls to seal blocks and create forks. //! This is suitable for a testing environment. @@ -28,6 +30,7 @@ use sp_runtime::{traits::Block as BlockT, Justification}; use sc_client_api::backend::{Backend as ClientBackend, Finalizer}; use sc_transaction_pool::txpool; use std::{sync::Arc, marker::PhantomData}; +use prometheus_endpoint::Registry; mod error; mod finalize_block; @@ -67,7 +70,8 @@ impl Verifier for ManualSealVerifier { /// Instantiate the import queue for the manual seal consensus engine. pub fn import_queue( block_import: BoxBlockImport, - spawner: &impl sp_core::traits::SpawnBlocking, + spawner: &impl sp_core::traits::SpawnNamed, + registry: Option<&Registry>, ) -> BasicQueue where Block: BlockT, @@ -79,6 +83,7 @@ pub fn import_queue( None, None, spawner, + registry, ) } @@ -93,7 +98,7 @@ pub async fn run_manual_seal( inherent_data_providers: InherentDataProviders, ) where - A: txpool::ChainApi::Hash> + 'static, + A: txpool::ChainApi + 'static, B: BlockT + 'static, C: HeaderBackend + Finalizer + 'static, CB: ClientBackend + 'static, @@ -153,7 +158,7 @@ pub async fn run_instant_seal( inherent_data_providers: InherentDataProviders, ) where - A: txpool::ChainApi::Hash> + 'static, + A: txpool::ChainApi + 'static, B: BlockT + 'static, C: HeaderBackend + Finalizer + 'static, CB: ClientBackend + 'static, @@ -195,16 +200,14 @@ mod tests { AccountKeyring::*, TestClientBuilder, }; - use sc_transaction_pool::{ - BasicPool, - txpool::Options, - }; + use sc_transaction_pool::{BasicPool, RevalidationType, txpool::Options}; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; use sp_transaction_pool::{TransactionPool, MaintainedTransactionPool, TransactionSource}; use sp_runtime::generic::BlockId; use sp_consensus::ImportedAux; use sp_inherents::InherentDataProviders; use sc_basic_authorship::ProposerFactory; + use sc_client_api::BlockBackend; fn api() -> Arc { Arc::new(TestApi::empty()) @@ -218,10 +221,14 @@ mod tests { let (client, select_chain) = builder.build_with_longest_chain(); let client = Arc::new(client); let inherent_data_providers = InherentDataProviders::new(); - let pool = Arc::new(BasicPool::new(Options::default(), api(), None).0); + let spawner = sp_core::testing::TaskExecutor::new(); + let pool = Arc::new(BasicPool::with_revalidation_type( + Options::default(), api(), None, RevalidationType::Full, spawner, + )); let env = ProposerFactory::new( client.clone(), - pool.clone() + pool.clone(), + None, ); // this test checks that blocks are created as soon as transactions are imported into the pool. let (sender, receiver) = futures::channel::oneshot::channel(); @@ -282,10 +289,14 @@ mod tests { let (client, select_chain) = builder.build_with_longest_chain(); let client = Arc::new(client); let inherent_data_providers = InherentDataProviders::new(); - let pool = Arc::new(BasicPool::new(Options::default(), api(), None).0); + let spawner = sp_core::testing::TaskExecutor::new(); + let pool = Arc::new(BasicPool::with_revalidation_type( + Options::default(), api(), None, RevalidationType::Full, spawner, + )); let env = ProposerFactory::new( client.clone(), - pool.clone() + pool.clone(), + None, ); // this test checks that blocks are created as soon as an engine command is sent over the stream. let (mut sink, stream) = futures::channel::mpsc::channel(1024); @@ -350,10 +361,14 @@ mod tests { let client = Arc::new(client); let inherent_data_providers = InherentDataProviders::new(); let pool_api = api(); - let pool = Arc::new(BasicPool::new(Options::default(), pool_api.clone(), None).0); + let spawner = sp_core::testing::TaskExecutor::new(); + let pool = Arc::new(BasicPool::with_revalidation_type( + Options::default(), pool_api.clone(), None, RevalidationType::Full, spawner, + )); let env = ProposerFactory::new( client.clone(), pool.clone(), + None, ); // this test checks that blocks are created as soon as an engine command is sent over the stream. let (mut sink, stream) = futures::channel::mpsc::channel(1024); @@ -401,15 +416,14 @@ mod tests { } } ); - // assert that there's a new block in the db. - assert!(client.header(&BlockId::Number(0)).unwrap().is_some()); + let block = client.block(&BlockId::Number(1)).unwrap().unwrap().block; + pool_api.add_block(block, true); assert!(pool.submit_one(&BlockId::Number(1), SOURCE, uxt(Alice, 1)).await.is_ok()); - pool.maintain(sp_transaction_pool::ChainEvent::NewBlock { - id: BlockId::Number(1), - header: client.header(&BlockId::Number(1)).expect("db error").expect("imported above"), - is_new_best: true, - retracted: vec![], + let header = client.header(&BlockId::Number(1)).expect("db error").expect("imported above"); + pool.maintain(sp_transaction_pool::ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, }).await; let (tx1, rx1) = futures::channel::oneshot::channel(); @@ -423,10 +437,11 @@ mod tests { rx1.await.expect("should be no error receiving"), Ok(_) ); - assert!(client.header(&BlockId::Number(1)).unwrap().is_some()); + let block = client.block(&BlockId::Number(2)).unwrap().unwrap().block; + pool_api.add_block(block, true); pool_api.increment_nonce(Alice.into()); - assert!(pool.submit_one(&BlockId::Number(2), SOURCE, uxt(Alice, 2)).await.is_ok()); + assert!(pool.submit_one(&BlockId::Number(1), SOURCE, uxt(Alice, 2)).await.is_ok()); let (tx2, rx2) = futures::channel::oneshot::channel(); assert!(sink.send(EngineCommand::SealNewBlock { parent_hash: Some(created_block.hash), diff --git a/client/consensus/manual-seal/src/seal_new_block.rs b/client/consensus/manual-seal/src/seal_new_block.rs index 88b58ef4cc2b39cbbe3af1209e54408390e074ef..c5aea11ced316bba9a329ed954a01afcd49263ff 100644 --- a/client/consensus/manual-seal/src/seal_new_block.rs +++ b/client/consensus/manual-seal/src/seal_new_block.rs @@ -87,7 +87,7 @@ pub async fn seal_new_block( E: Environment, >::Error: std::fmt::Display, >::Error: std::fmt::Display, - P: txpool::ChainApi::Hash>, + P: txpool::ChainApi, SC: SelectChain, { let future = async { @@ -108,7 +108,7 @@ pub async fn seal_new_block( None => select_chain.best_chain()? }; - let mut proposer = env.init(&header) + let proposer = env.init(&header) .map_err(|err| Error::StringError(format!("{}", err))).await?; let id = inherent_data_provider.create_inherent_data()?; let inherents_len = id.len(); diff --git a/client/consensus/pow/Cargo.toml b/client/consensus/pow/Cargo.toml index 0c1cc9c12cd5f61068ed16d7e980c7f03feb1260..993502972f2d0f257cb4c520b8148c0b53bde2b0 100644 --- a/client/consensus/pow/Cargo.toml +++ b/client/consensus/pow/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-consensus-pow" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "PoW consensus algorithm for substrate" edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,17 +12,18 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -sc-client-api = { version = "2.0.0-dev", path = "../../api" } -sp-block-builder = { version = "2.0.0-dev", path = "../../../primitives/block-builder" } -sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } -sp-consensus-pow = { version = "0.8.0-dev", path = "../../../primitives/consensus/pow" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } +codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +sc-client-api = { version = "2.0.0-rc6", path = "../../api" } +sp-block-builder = { version = "2.0.0-rc6", path = "../../../primitives/block-builder" } +sp-inherents = { version = "2.0.0-rc6", path = "../../../primitives/inherents" } +sp-consensus-pow = { version = "0.8.0-rc6", path = "../../../primitives/consensus/pow" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } log = "0.4.8" futures = { version = "0.3.1", features = ["compat"] } -sp-timestamp = { version = "2.0.0-dev", path = "../../../primitives/timestamp" } +sp-timestamp = { version = "2.0.0-rc6", path = "../../../primitives/timestamp" } derive_more = "0.99.2" +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../../utils/prometheus", version = "0.8.0-rc6"} diff --git a/client/consensus/pow/README.md b/client/consensus/pow/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a335ec367047b9762cc01132da1b39e3d4d3ed0d --- /dev/null +++ b/client/consensus/pow/README.md @@ -0,0 +1,16 @@ +Proof of work consensus for Substrate. + +To use this engine, you can need to have a struct that implements +`PowAlgorithm`. After that, pass an instance of the struct, along +with other necessary client references to `import_queue` to setup +the queue. Use the `start_mine` function for basic CPU mining. + +The auxiliary storage for PoW engine only stores the total difficulty. +For other storage requirements for particular PoW algorithm (such as +the actual difficulty for each particular blocks), you can take a client +reference in your `PowAlgorithm` implementation, and use a separate prefix +for the auxiliary storage. It is also possible to just use the runtime +as the storage, but it is not recommended as it won't work well with light +clients. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/consensus/pow/src/lib.rs b/client/consensus/pow/src/lib.rs index 8d17071f4c15c3f9ec4817ec8058e666b82fe909..ca1a8584e2a0bc9a008093229afdd39278561ec3 100644 --- a/client/consensus/pow/src/lib.rs +++ b/client/consensus/pow/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Proof of work consensus for Substrate. //! @@ -53,6 +55,7 @@ use sp_consensus::import_queue::{ BoxBlockImport, BasicQueue, Verifier, BoxJustificationImport, BoxFinalityProofImport, }; use codec::{Encode, Decode}; +use prometheus_endpoint::Registry; use sc_client_api; use log::*; use sp_timestamp::{InherentError as TIError, TimestampInherentData}; @@ -85,10 +88,13 @@ pub enum Error { CreateInherents(sp_inherents::Error), #[display(fmt = "Checking inherents failed: {}", _0)] CheckInherents(String), + #[display(fmt = "Multiple pre-runtime digests")] + MultiplePreRuntimeDigests, Client(sp_blockchain::Error), Codec(codec::Error), Environment(String), - Runtime(RuntimeString) + Runtime(RuntimeString), + Other(String), } impl std::convert::From> for String { @@ -169,6 +175,7 @@ pub trait PowAlgorithm { &self, parent: &BlockId, pre_hash: &B::Hash, + pre_digest: Option<&[u8]>, seal: &Seal, difficulty: Self::Difficulty, ) -> Result>; @@ -177,22 +184,26 @@ pub trait PowAlgorithm { &self, parent: &BlockId, pre_hash: &B::Hash, + pre_digest: Option<&[u8]>, difficulty: Self::Difficulty, round: u32, ) -> Result, Error>; } /// A block importer for PoW. -pub struct PowBlockImport { +pub struct PowBlockImport { algorithm: Algorithm, inner: I, select_chain: Option, client: Arc, inherent_data_providers: sp_inherents::InherentDataProviders, check_inherents_after: <::Header as HeaderT>::Number, + can_author_with: CAW, } -impl Clone for PowBlockImport { +impl Clone + for PowBlockImport +{ fn clone(&self) -> Self { Self { algorithm: self.algorithm.clone(), @@ -201,17 +212,19 @@ impl Clone for PowBlockImpor client: self.client.clone(), inherent_data_providers: self.inherent_data_providers.clone(), check_inherents_after: self.check_inherents_after.clone(), + can_author_with: self.can_author_with.clone(), } } } -impl PowBlockImport where +impl PowBlockImport where B: BlockT, I: BlockImport> + Send + Sync, I::Error: Into, C: ProvideRuntimeApi + Send + Sync + HeaderBackend + AuxStore + ProvideCache + BlockOf, C::Api: BlockBuilderApi, Algorithm: PowAlgorithm, + CAW: CanAuthorWith, { /// Create a new block import suitable to be used in PoW pub fn new( @@ -221,9 +234,17 @@ impl PowBlockImport where check_inherents_after: <::Header as HeaderT>::Number, select_chain: Option, inherent_data_providers: sp_inherents::InherentDataProviders, + can_author_with: CAW, ) -> Self { - Self { inner, client, algorithm, check_inherents_after, - select_chain, inherent_data_providers } + Self { + inner, + client, + algorithm, + check_inherents_after, + select_chain, + inherent_data_providers, + can_author_with, + } } fn check_inherents( @@ -239,6 +260,16 @@ impl PowBlockImport where return Ok(()) } + if let Err(e) = self.can_author_with.can_author_with(&block_id) { + debug!( + target: "pow", + "Skipping `check_inherents` as authoring version is not compatible: {}", + e, + ); + + return Ok(()) + } + let inherent_res = self.client.runtime_api().check_inherents( &block_id, block, @@ -267,7 +298,7 @@ impl PowBlockImport where } } -impl BlockImport for PowBlockImport where +impl BlockImport for PowBlockImport where B: BlockT, I: BlockImport> + Send + Sync, I::Error: Into, @@ -276,6 +307,7 @@ impl BlockImport for PowBlockImport, Algorithm: PowAlgorithm, Algorithm::Difficulty: 'static, + CAW: CanAuthorWith, { type Error = ConsensusError; type Transaction = sp_api::TransactionFor; @@ -341,9 +373,11 @@ impl BlockImport for PowBlockImport(&block.header)?; if !self.algorithm.verify( &BlockId::hash(parent_hash), &pre_hash, + pre_digest.as_ref().map(|v| &v[..]), &inner_seal, difficulty, )? { @@ -463,7 +497,8 @@ pub fn import_queue( finality_proof_import: Option>, algorithm: Algorithm, inherent_data_providers: InherentDataProviders, - spawner: &impl sp_core::traits::SpawnBlocking, + spawner: &impl sp_core::traits::SpawnNamed, + registry: Option<&Registry>, ) -> Result< PowImportQueue, sp_consensus::Error @@ -482,6 +517,7 @@ pub fn import_queue( justification_import, finality_proof_import, spawner, + registry, )) } @@ -490,7 +526,7 @@ pub fn import_queue( /// However, it's not recommended to use background threads in the rest of the /// codebase. /// -/// `preruntime` is a parameter that allows a custom additional pre-runtime +/// `pre_runtime` is a parameter that allows a custom additional pre-runtime /// digest to be inserted for blocks being built. This can encode authorship /// information, or just be a graffiti. `round` is for number of rounds the /// CPU miner runs each time. This parameter should be tweaked so that each @@ -500,7 +536,7 @@ pub fn start_mine( client: Arc, algorithm: Algorithm, mut env: E, - preruntime: Option>, + pre_runtime: Option>, round: u32, mut sync_oracle: SO, build_time: std::time::Duration, @@ -528,7 +564,7 @@ pub fn start_mine( client.as_ref(), &algorithm, &mut env, - preruntime.as_ref(), + pre_runtime.as_ref(), round, &mut sync_oracle, build_time.clone(), @@ -552,7 +588,7 @@ fn mine_loop( client: &C, algorithm: &Algorithm, env: &mut E, - preruntime: Option<&Vec>, + pre_runtime: Option<&Vec>, round: u32, sync_oracle: &mut SO, build_time: std::time::Duration, @@ -605,14 +641,14 @@ fn mine_loop( continue 'outer } - let mut proposer = futures::executor::block_on(env.init(&best_header)) + let proposer = futures::executor::block_on(env.init(&best_header)) .map_err(|e| Error::Environment(format!("{:?}", e)))?; let inherent_data = inherent_data_providers .create_inherent_data().map_err(Error::CreateInherents)?; let mut inherent_digest = Digest::default(); - if let Some(preruntime) = &preruntime { - inherent_digest.push(DigestItem::PreRuntime(POW_ENGINE_ID, preruntime.to_vec())); + if let Some(pre_runtime) = &pre_runtime { + inherent_digest.push(DigestItem::PreRuntime(POW_ENGINE_ID, pre_runtime.to_vec())); } let proposal = futures::executor::block_on(proposer.propose( inherent_data, @@ -629,6 +665,7 @@ fn mine_loop( let seal = algorithm.mine( &BlockId::Hash(best_hash), &header.hash(), + pre_runtime.map(|v| &v[..]), difficulty, round, )?; @@ -643,6 +680,8 @@ fn mine_loop( } }; + log::info!("✅ Successfully mined block: {}", best_hash); + let (hash, seal) = { let seal = DigestItem::Seal(POW_ENGINE_ID, seal); let mut header = header.clone(); @@ -671,3 +710,22 @@ fn mine_loop( .map_err(|e| Error::BlockBuiltError(best_hash, e))?; } } + +/// Find PoW pre-runtime. +fn find_pre_digest(header: &B::Header) -> Result>, Error> { + let mut pre_digest: Option<_> = None; + for log in header.digest().logs() { + trace!(target: "pow", "Checking log {:?}, looking for pre runtime digest", log); + match (log, pre_digest.is_some()) { + (DigestItem::PreRuntime(POW_ENGINE_ID, _), true) => { + return Err(Error::MultiplePreRuntimeDigests) + }, + (DigestItem::PreRuntime(POW_ENGINE_ID, v), false) => { + pre_digest = Some(v.clone()); + }, + (_, _) => trace!(target: "pow", "Ignoring digest not meant for us"), + } + } + + Ok(pre_digest) +} diff --git a/client/consensus/slots/Cargo.toml b/client/consensus/slots/Cargo.toml index d39d5382557ddc84c6a3f3a1d232ea191c0d0eb8..1ba015b0801e4624e26220e1e7f1f278a8330734 100644 --- a/client/consensus/slots/Cargo.toml +++ b/client/consensus/slots/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "sc-consensus-slots" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Generic slots-based utilities for consensus" edition = "2018" build = "build.rs" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -13,20 +13,22 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-client-api = { version = "2.0.0-dev", path = "../../api" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -sc-telemetry = { version = "2.0.0-dev", path = "../../telemetry" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } +codec = { package = "parity-scale-codec", version = "1.3.4" } +sc-client-api = { version = "2.0.0-rc6", path = "../../api" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-application-crypto = { version = "2.0.0-rc6", path = "../../../primitives/application-crypto" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-consensus-slots = { version = "0.8.0-rc6", path = "../../../primitives/consensus/slots" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../../primitives/state-machine" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +sc-telemetry = { version = "2.0.0-rc6", path = "../../telemetry" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-rc6", path = "../../../primitives/inherents" } futures = "0.3.4" futures-timer = "3.0.1" parking_lot = "0.10.0" log = "0.4.8" [dev-dependencies] -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../test-utils/runtime/client" } diff --git a/client/consensus/slots/README.md b/client/consensus/slots/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9ab3c3742f33076b46be61efbf3c3e5fd824b50c --- /dev/null +++ b/client/consensus/slots/README.md @@ -0,0 +1,7 @@ +Slots functionality for Substrate. + +Some consensus algorithms have a concept of *slots*, which are intervals in +time during which certain events can and/or must occur. This crate +provides generic functionality for slots. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/consensus/slots/src/aux_schema.rs b/client/consensus/slots/src/aux_schema.rs index d54190ca0715890272ede7319cbc1cf21aacf296..1f1fe37068f82b2fef9c789bf0877068d0b1d0c3 100644 --- a/client/consensus/slots/src/aux_schema.rs +++ b/client/consensus/slots/src/aux_schema.rs @@ -19,6 +19,7 @@ use codec::{Encode, Decode}; use sc_client_api::backend::AuxStore; use sp_blockchain::{Result as ClientResult, Error as ClientError}; +use sp_consensus_slots::EquivocationProof; use sp_runtime::traits::Header; const SLOT_HEADER_MAP_KEY: &[u8] = b"slot_header_map"; @@ -44,31 +45,6 @@ fn load_decode(backend: &C, key: &[u8]) -> ClientResult> } } -/// Represents an equivocation proof. -#[derive(Debug, Clone)] -pub struct EquivocationProof { - slot: u64, - fst_header: H, - snd_header: H, -} - -impl EquivocationProof { - /// Get the slot number where the equivocation happened. - pub fn slot(&self) -> u64 { - self.slot - } - - /// Get the first header involved in the equivocation. - pub fn fst_header(&self) -> &H { - &self.fst_header - } - - /// Get the second header involved in the equivocation. - pub fn snd_header(&self) -> &H { - &self.snd_header - } -} - /// Checks if the header is an equivocation and returns the proof in that case. /// /// Note: it detects equivocations only when slot_now - slot <= MAX_SLOT_CAPACITY. @@ -78,7 +54,7 @@ pub fn check_equivocation( slot: u64, header: &H, signer: &P, -) -> ClientResult>> +) -> ClientResult>> where H: Header, C: AuxStore, @@ -114,9 +90,10 @@ pub fn check_equivocation( // 2) with different hash if header.hash() != prev_header.hash() { return Ok(Some(EquivocationProof { - slot, // 3) and mentioning the same slot. - fst_header: prev_header.clone(), - snd_header: header.clone(), + slot_number: slot, + offender: signer.clone(), + first_header: prev_header.clone(), + second_header: header.clone(), })); } else { // We don't need to continue in case of duplicated header, diff --git a/client/consensus/slots/src/lib.rs b/client/consensus/slots/src/lib.rs index 611e0fbb7b8053675c7b385fccbe03747eaa00a4..7d346ffe3954dbdd3f3d658ff21f4f7f44f45ac8 100644 --- a/client/consensus/slots/src/lib.rs +++ b/client/consensus/slots/src/lib.rs @@ -20,7 +20,6 @@ //! time during which certain events can and/or must occur. This crate //! provides generic functionality for slots. -#![deny(warnings)] #![forbid(unsafe_code, missing_docs)] mod slots; @@ -105,6 +104,15 @@ pub trait SimpleSlotWorker { epoch_data: &Self::EpochData, ) -> Option; + /// Notifies the given slot. Similar to `claim_slot`, but will be called no matter whether we + /// need to author blocks or not. + fn notify_slot( + &self, + _header: &B::Header, + _slot_number: u64, + _epoch_data: &Self::EpochData, + ) { } + /// Return the pre digest data to include in a block authored with the given claim. fn pre_digest_data( &self, @@ -121,11 +129,10 @@ pub trait SimpleSlotWorker { StorageChanges<>::Transaction, B>, Self::Claim, Self::EpochData, - ) -> sp_consensus::BlockImportParams< - B, - >::Transaction - > - + Send + ) -> Result< + sp_consensus::BlockImportParams>::Transaction>, + sp_consensus::Error + > + Send + 'static >; /// Whether to force authoring if offline. @@ -193,6 +200,8 @@ pub trait SimpleSlotWorker { } }; + self.notify_slot(&chain_head, slot_number, &epoch_data); + let authorities_len = self.authorities_len(&epoch_data); if !self.force_authoring() && @@ -240,7 +249,7 @@ pub trait SimpleSlotWorker { let logs = self.pre_digest_data(slot_number, &claim); // deadline our production to approx. the end of the slot - let proposing = awaiting_proposer.and_then(move |mut proposer| proposer.propose( + let proposing = awaiting_proposer.and_then(move |proposer| proposer.propose( slot_info.inherent_data, sp_runtime::generic::Digest { logs, @@ -273,7 +282,7 @@ pub trait SimpleSlotWorker { let block_import = self.block_import(); let logging_target = self.logging_target(); - Box::pin(proposal_work.map_ok(move |(proposal, claim)| { + Box::pin(proposal_work.and_then(move |(proposal, claim)| { let (header, body) = proposal.block.deconstruct(); let header_num = *header.number(); let header_hash = header.hash(); @@ -288,6 +297,11 @@ pub trait SimpleSlotWorker { epoch_data, ); + let block_import_params = match block_import_params { + Ok(params) => params, + Err(e) => return future::err(e), + }; + info!( "🔖 Pre-sealed block for proposal at {}. Hash now {:?}, previously {:?}.", header_num, @@ -312,6 +326,7 @@ pub trait SimpleSlotWorker { "hash" => ?parent_hash, "err" => ?err, ); } + future::ready(Ok(())) })) } } @@ -451,7 +466,7 @@ impl SlotDuration { CB: FnOnce(ApiRef, &BlockId) -> sp_blockchain::Result, T: SlotData + Encode + Decode + Debug, { - match client.get_aux(T::SLOT_KEY)? { + let slot_duration = match client.get_aux(T::SLOT_KEY)? { Some(v) => ::decode(&mut &v[..]) .map(SlotDuration) .map_err(|_| { @@ -467,7 +482,7 @@ impl SlotDuration { info!( "⏱ Loaded block-time = {:?} milliseconds from genesis on first-launch", - genesis_slot_duration + genesis_slot_duration.slot_duration() ); genesis_slot_duration @@ -475,7 +490,15 @@ impl SlotDuration { Ok(SlotDuration(genesis_slot_duration)) } + }?; + + if slot_duration.slot_duration() == 0 { + return Err(sp_blockchain::Error::Msg( + "Invalid value for slot_duration: the value must be greater than 0.".into(), + )) } + + Ok(slot_duration) } /// Returns slot data value. diff --git a/client/consensus/slots/src/slots.rs b/client/consensus/slots/src/slots.rs index 17a931b7c4154a8a03d57ea948ac20ee8c63c4bf..32316c56c9f53674fa4ac98b7ac85e45934d9f23 100644 --- a/client/consensus/slots/src/slots.rs +++ b/client/consensus/slots/src/slots.rs @@ -109,7 +109,7 @@ impl Slots { } } -impl Stream for Slots { +impl Stream for Slots { type Item = Result; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { @@ -165,3 +165,6 @@ impl Stream for Slots { } } } + +impl Unpin for Slots { +} diff --git a/client/consensus/uncles/Cargo.toml b/client/consensus/uncles/Cargo.toml index 019c933a20e0cc24ef3cbd0e284afce66dd379cc..106fb57b6e60d49cc7c56063550004f8d2394bc7 100644 --- a/client/consensus/uncles/Cargo.toml +++ b/client/consensus/uncles/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-consensus-uncles" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Generic uncle inclusion utilities for consensus" edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,10 +12,10 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-client-api = { version = "2.0.0-dev", path = "../../api" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-authorship = { version = "2.0.0-dev", path = "../../../primitives/authorship" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -sp-inherents = { version = "2.0.0-dev", path = "../../../primitives/inherents" } +sc-client-api = { version = "2.0.0-rc6", path = "../../api" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-authorship = { version = "2.0.0-rc6", path = "../../../primitives/authorship" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-rc6", path = "../../../primitives/inherents" } log = "0.4.8" diff --git a/client/consensus/uncles/README.md b/client/consensus/uncles/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1b6fed5b9772a69eef4abcd2997167e13e290a32 --- /dev/null +++ b/client/consensus/uncles/README.md @@ -0,0 +1,3 @@ +Uncles functionality for Substrate. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/db/Cargo.toml b/client/db/Cargo.toml index 2df1836850cd7957145198f55afc889ed2a3ac15..28ef90cf231e24973c079260e21472c2ad6b3ad0 100644 --- a/client/db/Cargo.toml +++ b/client/db/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-client-db" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Client backend that uses RocksDB database as storage." @@ -14,36 +14,40 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] parking_lot = "0.10.0" log = "0.4.8" -kvdb = "0.5.0" -kvdb-rocksdb = { version = "0.7", optional = true } -kvdb-memorydb = "0.5.0" +kvdb = "0.7.0" +kvdb-rocksdb = { version = "0.9", optional = true } +kvdb-memorydb = "0.7.0" linked-hash-map = "0.5.2" hash-db = "0.15.2" -parity-util-mem = { version = "0.6.1", default-features = false, features = ["std"] } -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["std"] } +codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } blake2-rfc = "0.2.18" -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } -sc-executor = { version = "0.8.0-dev", path = "../executor" } -sc-state-db = { version = "0.8.0-dev", path = "../state-db" } -sp-trie = { version = "2.0.0-dev", path = "../../primitives/trie" } -sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sp-database = { version = "2.0.0-dev", path = "../../primitives/database" } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sp-arithmetic = { version = "2.0.0-rc6", path = "../../primitives/arithmetic" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } +sc-executor = { version = "0.8.0-rc6", path = "../executor" } +sc-state-db = { version = "0.8.0-rc6", path = "../state-db" } +sp-trie = { version = "2.0.0-rc6", path = "../../primitives/trie" } +sp-consensus = { version = "0.8.0-rc6", path = "../../primitives/consensus/common" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sp-database = { version = "2.0.0-rc6", path = "../../primitives/database" } parity-db = { version = "0.1.2", optional = true } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../../utils/prometheus" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-rc6", path = "../../utils/prometheus" } [dev-dependencies] -sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } +sp-keyring = { version = "2.0.0-rc6", path = "../../primitives/keyring" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client" } env_logger = "0.7.0" quickcheck = "0.9" -kvdb-rocksdb = "0.7" +kvdb-rocksdb = "0.9" tempfile = "3" [features] default = [] test-helpers = [] +with-kvdb-rocksdb = ["kvdb-rocksdb"] +with-parity-db = ["parity-db"] +with-subdb = [] diff --git a/client/db/README.md b/client/db/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e5fb3fce1d9763d92554b3d0c6262e4e3cfccd66 --- /dev/null +++ b/client/db/README.md @@ -0,0 +1,11 @@ +Client backend that is backed by a database. + +# Canonicality vs. Finality + +Finality indicates that a block will not be reverted, according to the consensus algorithm, +while canonicality indicates that the block may be reverted, but we will be unable to do so, +having discarded heavy state that will allow a chain reorganization. + +Finality implies canonicality but not vice-versa. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/db/src/bench.rs b/client/db/src/bench.rs index 9d6f595498bd0e3f5a4f287090b25485142c0bb0..93b8048529fc4ed2109bbb70c02d25fc180ae499 100644 --- a/client/db/src/bench.rs +++ b/client/db/src/bench.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! State backend that's useful for benchmarking @@ -22,10 +24,13 @@ use std::collections::HashMap; use hash_db::{Prefix, Hasher}; use sp_trie::{MemoryDB, prefixed_key}; -use sp_core::storage::ChildInfo; +use sp_core::{ + storage::{ChildInfo, TrackedStorageKey}, + hexdisplay::HexDisplay +}; use sp_runtime::traits::{Block as BlockT, HashFor}; use sp_runtime::Storage; -use sp_state_machine::{DBValue, backend::Backend as StateBackend}; +use sp_state_machine::{DBValue, backend::Backend as StateBackend, StorageCollection}; use kvdb::{KeyValueDB, DBTransaction}; use crate::storage_cache::{CachingState, SharedCache, new_shared_cache}; @@ -48,6 +53,40 @@ impl sp_state_machine::Storage> for StorageDb { root: Cell, @@ -57,6 +96,9 @@ pub struct BenchmarkingState { genesis: HashMap, (Vec, i32)>, record: Cell>>, shared_cache: SharedCache, // shared cache is always empty + key_tracker: RefCell, KeyTracker>>, + read_write_tracker: RefCell, + whitelist: RefCell>, } impl BenchmarkingState { @@ -74,20 +116,25 @@ impl BenchmarkingState { genesis_root: Default::default(), record: Default::default(), shared_cache: new_shared_cache(0, (1, 10)), + key_tracker: Default::default(), + read_write_tracker: Default::default(), + whitelist: Default::default(), }; + state.add_whitelist_to_tracker(); + state.reopen()?; - let child_delta = genesis.children_default.into_iter().map(|(_storage_key, child_content)| ( - child_content.child_info, - child_content.data.into_iter().map(|(k, v)| (k, Some(v))), + let child_delta = genesis.children_default.iter().map(|(_storage_key, child_content)| ( + &child_content.child_info, + child_content.data.iter().map(|(k, v)| (k.as_ref(), Some(v.as_ref()))), )); let (root, transaction): (B::Hash, _) = state.state.borrow_mut().as_mut().unwrap().full_storage_root( - genesis.top.into_iter().map(|(k, v)| (k, Some(v))), + genesis.top.iter().map(|(k, v)| (k.as_ref(), Some(v.as_ref()))), child_delta, ); state.genesis = transaction.clone().drain(); state.genesis_root = root.clone(); - state.commit(root, transaction)?; + state.commit(root, transaction, Vec::new())?; state.record.take(); Ok(state) } @@ -107,6 +154,88 @@ impl BenchmarkingState { )); Ok(()) } + + fn add_whitelist_to_tracker(&self) { + let mut key_tracker = self.key_tracker.borrow_mut(); + + let whitelist = self.whitelist.borrow(); + + whitelist.iter().for_each(|key| { + let whitelisted = KeyTracker { + has_been_read: key.has_been_read, + has_been_written: key.has_been_written, + }; + key_tracker.insert(key.key.clone(), whitelisted); + }); + } + + fn wipe_tracker(&self) { + *self.key_tracker.borrow_mut() = HashMap::new(); + self.add_whitelist_to_tracker(); + *self.read_write_tracker.borrow_mut() = Default::default(); + } + + fn add_read_key(&self, key: &[u8]) { + log::trace!(target: "benchmark", "Read: {}", HexDisplay::from(&key)); + + let mut key_tracker = self.key_tracker.borrow_mut(); + let mut read_write_tracker = self.read_write_tracker.borrow_mut(); + + let maybe_tracker = key_tracker.get(key); + + match maybe_tracker { + None => { + let has_been_read = KeyTracker { + has_been_read: true, + has_been_written: false, + }; + key_tracker.insert(key.to_vec(), has_been_read); + read_write_tracker.add_read(); + }, + Some(tracker) => { + if !tracker.has_been_read { + let has_been_read = KeyTracker { + has_been_read: true, + has_been_written: tracker.has_been_written, + }; + key_tracker.insert(key.to_vec(), has_been_read); + read_write_tracker.add_read(); + } else { + read_write_tracker.add_repeat_read(); + } + } + } + } + + fn add_write_key(&self, key: &[u8]) { + log::trace!(target: "benchmark", "Write: {}", HexDisplay::from(&key)); + + let mut key_tracker = self.key_tracker.borrow_mut(); + let mut read_write_tracker = self.read_write_tracker.borrow_mut(); + + let maybe_tracker = key_tracker.get(key); + + // If we have written to the key, we also consider that we have read from it. + let has_been_written = KeyTracker { + has_been_read: true, + has_been_written: true, + }; + + match maybe_tracker { + None => { + key_tracker.insert(key.to_vec(), has_been_written); + read_write_tracker.add_write(); + }, + Some(tracker) => { + if !tracker.has_been_written { + key_tracker.insert(key.to_vec(), has_been_written); + read_write_tracker.add_write(); + } else { + read_write_tracker.add_repeat_write(); + } + } + } + } } fn state_err() -> String { @@ -119,10 +248,12 @@ impl StateBackend> for BenchmarkingState { type TrieBackendStorage = as StateBackend>>::TrieBackendStorage; fn storage(&self, key: &[u8]) -> Result>, Self::Error> { + self.add_read_key(key); self.state.borrow().as_ref().ok_or_else(state_err)?.storage(key) } fn storage_hash(&self, key: &[u8]) -> Result, Self::Error> { + self.add_read_key(key); self.state.borrow().as_ref().ok_or_else(state_err)?.storage_hash(key) } @@ -131,10 +262,12 @@ impl StateBackend> for BenchmarkingState { child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { + self.add_read_key(key); self.state.borrow().as_ref().ok_or_else(state_err)?.child_storage(child_info, key) } fn exists_storage(&self, key: &[u8]) -> Result { + self.add_read_key(key); self.state.borrow().as_ref().ok_or_else(state_err)?.exists_storage(key) } @@ -143,10 +276,12 @@ impl StateBackend> for BenchmarkingState { child_info: &ChildInfo, key: &[u8], ) -> Result { + self.add_read_key(key); self.state.borrow().as_ref().ok_or_else(state_err)?.exists_child_storage(child_info, key) } fn next_storage_key(&self, key: &[u8]) -> Result>, Self::Error> { + self.add_read_key(key); self.state.borrow().as_ref().ok_or_else(state_err)?.next_storage_key(key) } @@ -155,6 +290,7 @@ impl StateBackend> for BenchmarkingState { child_info: &ChildInfo, key: &[u8], ) -> Result>, Self::Error> { + self.add_read_key(key); self.state.borrow().as_ref().ok_or_else(state_err)?.next_child_storage_key(child_info, key) } @@ -191,19 +327,18 @@ impl StateBackend> for BenchmarkingState { } } - fn storage_root(&self, delta: I) -> (B::Hash, Self::Transaction) where - I: IntoIterator, Option>)> - { + fn storage_root<'a>( + &self, + delta: impl Iterator)>, + ) -> (B::Hash, Self::Transaction) where B::Hash: Ord { self.state.borrow().as_ref().map_or(Default::default(), |s| s.storage_root(delta)) } - fn child_storage_root( + fn child_storage_root<'a>( &self, child_info: &ChildInfo, - delta: I, - ) -> (B::Hash, bool, Self::Transaction) where - I: IntoIterator, Option>)>, - { + delta: impl Iterator)>, + ) -> (B::Hash, bool, Self::Transaction) where B::Hash: Ord { self.state.borrow().as_ref().map_or(Default::default(), |s| s.child_storage_root(child_info, delta)) } @@ -229,8 +364,11 @@ impl StateBackend> for BenchmarkingState { None } - fn commit(&self, storage_root: as Hasher>::Out, mut transaction: Self::Transaction) - -> Result<(), Self::Error> + fn commit(&self, + storage_root: as Hasher>::Out, + mut transaction: Self::Transaction, + storage_changes: StorageCollection, + ) -> Result<(), Self::Error> { if let Some(db) = self.db.take() { let mut db_transaction = DBTransaction::new(); @@ -244,10 +382,17 @@ impl StateBackend> for BenchmarkingState { } keys.push(key); } - self.record.set(keys); + let mut record = self.record.take(); + record.extend(keys); + self.record.set(record); db.write(db_transaction).map_err(|_| String::from("Error committing transaction"))?; self.root.set(storage_root); - self.db.set(Some(db)) + self.db.set(Some(db)); + + // Track DB Writes + storage_changes.iter().for_each(|(key, _)| { + self.add_write_key(key); + }); } else { return Err("Trying to commit to a closed db".into()) } @@ -271,9 +416,29 @@ impl StateBackend> for BenchmarkingState { self.root.set(self.genesis_root.clone()); self.reopen()?; + self.wipe_tracker(); Ok(()) } + /// Get the key tracking information for the state db. + fn read_write_count(&self) -> (u32, u32, u32, u32) { + let count = *self.read_write_tracker.borrow_mut(); + (count.reads, count.repeat_reads, count.writes, count.repeat_writes) + } + + /// Reset the key tracking information for the state db. + fn reset_read_write_count(&self) { + self.wipe_tracker() + } + + fn get_whitelist(&self) -> Vec { + self.whitelist.borrow().to_vec() + } + + fn set_whitelist(&self, new: Vec) { + *self.whitelist.borrow_mut() = new; + } + fn register_overlay_stats(&mut self, stats: &sp_state_machine::StateMachineStats) { self.state.borrow_mut().as_mut().map(|s| s.register_overlay_stats(stats)); } diff --git a/client/db/src/cache/list_cache.rs b/client/db/src/cache/list_cache.rs index f3a8171342c9158997cb1dd08e3d90aa03e94b8a..15ad339b1f2c1a387fd3e5dbac70eaef5df3a79b 100644 --- a/client/db/src/cache/list_cache.rs +++ b/client/db/src/cache/list_cache.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! List-based cache. //! @@ -858,16 +860,15 @@ fn read_forks>( } #[cfg(test)] -pub mod tests { +mod tests { use substrate_test_runtime_client::runtime::H256; use sp_runtime::testing::{Header, Block as RawBlock, ExtrinsicWrapper}; - use sp_runtime::traits::Header as HeaderT; use crate::cache::list_storage::tests::{DummyStorage, FaultyStorage, DummyTransaction}; use super::*; type Block = RawBlock>; - pub fn test_id(number: u64) -> ComplexBlockId { + fn test_id(number: u64) -> ComplexBlockId { ComplexBlockId::new(H256::from_low_u64_be(number), number) } @@ -1764,7 +1765,7 @@ pub mod tests { Some(Entry { valid_from: test_id(20), value: 20 }), vec![5, 6].into_iter().collect(), ))); - + assert_eq!( ops.operations, vec![CommitOperation::BlockFinalized( diff --git a/client/db/src/cache/list_entry.rs b/client/db/src/cache/list_entry.rs index e18434329079b68d1bc4a13af4a06698dd88d9d8..d14fab9274ccb830694082491b5f16bcf27ecf2b 100644 --- a/client/db/src/cache/list_entry.rs +++ b/client/db/src/cache/list_entry.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! List-cache storage entries. @@ -115,10 +117,14 @@ impl StorageEntry { #[cfg(test)] mod tests { - use crate::cache::list_cache::tests::test_id; use crate::cache::list_storage::tests::{DummyStorage, FaultyStorage}; + use substrate_test_runtime_client::runtime::{H256, Block}; use super::*; + fn test_id(number: u64) -> ComplexBlockId { + ComplexBlockId::new(H256::from_low_u64_be(number), number) + } + #[test] fn entry_try_update_works() { // when trying to update with None value diff --git a/client/db/src/cache/list_storage.rs b/client/db/src/cache/list_storage.rs index 07cd9fb866359b377ce7bc35f97efcb208c3adf5..377d744effa60faf57521d2a490852ef757ce1bf 100644 --- a/client/db/src/cache/list_storage.rs +++ b/client/db/src/cache/list_storage.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! List-cache storage definition and implementation. diff --git a/client/db/src/cache/mod.rs b/client/db/src/cache/mod.rs index f2d357ca9ece86e86a7ead75b5d2d46e8e4d5905..5501f0f1864c156745c6a3e63e4d8ced9a1cf25c 100644 --- a/client/db/src/cache/mod.rs +++ b/client/db/src/cache/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! DB-backed cache of blockchain data. @@ -340,8 +342,9 @@ impl BlockchainCache for DbCacheSync { EntryType::Genesis, )?; let tx_ops = tx.into_ops(); - db.commit(dbtx); + db.commit(dbtx)?; cache.commit(tx_ops)?; + Ok(()) } diff --git a/client/db/src/changes_tries_storage.rs b/client/db/src/changes_tries_storage.rs index 958e6e39f48c89c279cb5eab18fa55786c0f581a..a2299a82337a05f58ec7ba8dc867270813cc4444 100644 --- a/client/db/src/changes_tries_storage.rs +++ b/client/db/src/changes_tries_storage.rs @@ -719,7 +719,7 @@ mod tests { None, None, ).unwrap(); - backend.storage.db.commit(tx); + backend.storage.db.commit(tx).unwrap(); backend.changes_tries_storage.post_commit(Some(cache_ops)); }; diff --git a/client/db/src/children.rs b/client/db/src/children.rs index 3916321f17286313a5f1bfc1d0ee44a3648b03ee..bfba797cd467bdbc3f7a1db5d23b7f97511b5be5 100644 --- a/client/db/src/children.rs +++ b/client/db/src/children.rs @@ -99,7 +99,7 @@ mod tests { children2.push(1_6); write_children(&mut tx, 0, PREFIX, 1_2, children2); - db.commit(tx.clone()); + db.commit(tx.clone()).unwrap(); let r1: Vec = read_children(&*db, 0, PREFIX, 1_1).expect("(1) Getting r1 failed"); let r2: Vec = read_children(&*db, 0, PREFIX, 1_2).expect("(1) Getting r2 failed"); @@ -108,7 +108,7 @@ mod tests { assert_eq!(r2, vec![1_4, 1_6]); remove_children(&mut tx, 0, PREFIX, 1_2); - db.commit(tx); + db.commit(tx).unwrap(); let r1: Vec = read_children(&*db, 0, PREFIX, 1_1).expect("(2) Getting r1 failed"); let r2: Vec = read_children(&*db, 0, PREFIX, 1_2).expect("(2) Getting r2 failed"); diff --git a/client/db/src/lib.rs b/client/db/src/lib.rs index d1eb10ea31646e9cccf3d3c46cad6992fc7a5f3e..d854c80bf35351e6618796d7ac12ada24dddd766 100644 --- a/client/db/src/lib.rs +++ b/client/db/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Client backend that is backed by a database. //! @@ -29,27 +31,26 @@ pub mod light; pub mod offchain; -#[cfg(any(feature = "kvdb-rocksdb", test))] +#[cfg(any(feature = "with-kvdb-rocksdb", test))] pub mod bench; mod children; mod cache; mod changes_tries_storage; mod storage_cache; -#[cfg(any(feature = "kvdb-rocksdb", test))] +#[cfg(any(feature = "with-kvdb-rocksdb", test))] mod upgrade; mod utils; mod stats; -#[cfg(feature = "parity-db")] +#[cfg(feature = "with-parity-db")] mod parity_db; -#[cfg(feature = "subdb")] +#[cfg(feature = "with-subdb")] mod subdb; use std::sync::Arc; use std::path::{Path, PathBuf}; use std::io; -use std::collections::HashMap; - +use std::collections::{HashMap, HashSet}; use sc_client_api::{ UsageInfo, MemoryInfo, IoInfo, MemorySize, @@ -68,6 +69,7 @@ use parking_lot::RwLock; use sp_core::ChangesTrieConfiguration; use sp_core::offchain::storage::{OffchainOverlayedChange, OffchainOverlayedChanges}; use sp_core::storage::{well_known_keys, ChildInfo}; +use sp_arithmetic::traits::Saturating; use sp_runtime::{generic::BlockId, Justification, Storage}; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, NumberFor, Zero, One, SaturatedConversion, HashFor, @@ -89,7 +91,7 @@ use log::{trace, debug, warn}; pub use sp_database::Database; pub use sc_state_db::PruningMode; -#[cfg(any(feature = "kvdb-rocksdb", test))] +#[cfg(any(feature = "with-kvdb-rocksdb", test))] pub use bench::BenchmarkingState; const MIN_BLOCKS_TO_KEEP_CHANGES_TRIES_FOR: u32 = 32768; @@ -210,21 +212,18 @@ impl StateBackend> for RefTrackingState { self.state.for_child_keys_with_prefix(child_info, prefix, f) } - fn storage_root(&self, delta: I) -> (B::Hash, Self::Transaction) - where - I: IntoIterator, Option>)> - { + fn storage_root<'a>( + &self, + delta: impl Iterator)>, + ) -> (B::Hash, Self::Transaction) where B::Hash: Ord { self.state.storage_root(delta) } - fn child_storage_root( + fn child_storage_root<'a>( &self, child_info: &ChildInfo, - delta: I, - ) -> (B::Hash, bool, Self::Transaction) - where - I: IntoIterator, Option>)>, - { + delta: impl Iterator)>, + ) -> (B::Hash, bool, Self::Transaction) where B::Hash: Ord { self.state.child_storage_root(child_info, delta) } @@ -272,7 +271,7 @@ pub struct DatabaseSettings { } /// Where to find the database.. -#[derive(Clone)] +#[derive(Debug, Clone)] pub enum DatabaseSettingsSrc { /// Load a RocksDB database from a given path. Recommended for most uses. RocksDb { @@ -513,7 +512,7 @@ impl HeaderMetadata for BlockchainDb { header_metadata.clone(), ); header_metadata - }).ok_or(ClientError::UnknownBlock(format!("header not found in db: {}", hash))) + }).ok_or_else(|| ClientError::UnknownBlock(format!("header not found in db: {}", hash))) }, Ok) } @@ -545,7 +544,12 @@ pub struct BlockImportOperation { impl BlockImportOperation { fn apply_offchain(&mut self, transaction: &mut Transaction) { - for (key, value_operation) in self.offchain_storage_updates.drain() { + for ((prefix, key), value_operation) in self.offchain_storage_updates.drain() { + let key: Vec = prefix + .into_iter() + .chain(sp_core::sp_std::iter::once(b'/')) + .chain(key.into_iter()) + .collect(); match value_operation { OffchainOverlayedChange::SetValue(val) => transaction.set_from_vec(columns::OFFCHAIN, &key, val), OffchainOverlayedChange::Remove => transaction.remove(columns::OFFCHAIN, &key), @@ -603,26 +607,25 @@ impl sc_client_api::backend::BlockImportOperation for Bloc &mut self, storage: Storage, ) -> ClientResult { - - if storage.top.iter().any(|(k, _)| well_known_keys::is_child_storage_key(k)) { + if storage.top.keys().any(|k| well_known_keys::is_child_storage_key(&k)) { return Err(sp_blockchain::Error::GenesisInvalid.into()); } - let child_delta = storage.children_default.into_iter().map(|(_storage_key, child_content)|( - child_content.child_info, - child_content.data.into_iter().map(|(k, v)| (k, Some(v))), + let child_delta = storage.children_default.iter().map(|(_storage_key, child_content)|( + &child_content.child_info, + child_content.data.iter().map(|(k, v)| (&k[..], Some(&v[..]))), )); let mut changes_trie_config: Option = None; let (root, transaction) = self.old_state.full_storage_root( - storage.top.into_iter().map(|(k, v)| { - if k == well_known_keys::CHANGES_TRIE_CONFIG { + storage.top.iter().map(|(k, v)| { + if &k[..] == well_known_keys::CHANGES_TRIE_CONFIG { changes_trie_config = Some( Decode::decode(&mut &v[..]) .expect("changes trie configuration is encoded properly at genesis") ); } - (k, Some(v)) + (&k[..], Some(&v[..])) }), child_delta ); @@ -959,6 +962,7 @@ impl Backend { // TODO: ensure best chain contains this block. let number = *header.number(); self.ensure_sequential_finalization(header, last_finalized)?; + self.note_finalized( transaction, false, @@ -1012,9 +1016,10 @@ impl Backend { Ok(()) } - fn try_commit_operation(&self, mut operation: BlockImportOperation) - -> ClientResult<()> - { + fn try_commit_operation( + &self, + mut operation: BlockImportOperation, + ) -> ClientResult<()> { let mut transaction = Transaction::new(); let mut finalization_displaced_leaves = None; @@ -1240,7 +1245,7 @@ impl Backend { None }; - self.storage.db.commit(transaction); + self.storage.db.commit(transaction)?; if let Some(( number, @@ -1353,7 +1358,7 @@ impl sc_client_api::backend::AuxStore for Backend where Block: Blo for k in delete { transaction.remove(columns::AUX, k); } - self.storage.db.commit(transaction); + self.storage.db.commit(transaction)?; Ok(()) } @@ -1401,7 +1406,10 @@ impl sc_client_api::backend::Backend for Backend { Ok(()) } - fn commit_operation(&self, operation: Self::BlockImportOperation) -> ClientResult<()> { + fn commit_operation( + &self, + operation: Self::BlockImportOperation, + ) -> ClientResult<()> { let usage = operation.old_state.usage_info(); self.state_usage.merge_sm(usage); @@ -1417,9 +1425,11 @@ impl sc_client_api::backend::Backend for Backend { } } - fn finalize_block(&self, block: BlockId, justification: Option) - -> ClientResult<()> - { + fn finalize_block( + &self, + block: BlockId, + justification: Option, + ) -> ClientResult<()> { let mut transaction = Transaction::new(); let hash = self.blockchain.expect_block_hash_from_id(&block)?; let header = self.blockchain.expect_header(block)?; @@ -1435,7 +1445,7 @@ impl sc_client_api::backend::Backend for Backend { &mut changes_trie_cache_ops, &mut displaced, )?; - self.storage.db.commit(transaction); + self.storage.db.commit(transaction)?; self.blockchain.update_meta(hash, number, is_best, is_finalized); self.changes_tries_storage.post_commit(changes_trie_cache_ops); Ok(()) @@ -1485,7 +1495,13 @@ impl sc_client_api::backend::Backend for Backend { }) } - fn revert(&self, n: NumberFor, revert_finalized: bool) -> ClientResult> { + fn revert( + &self, + n: NumberFor, + revert_finalized: bool, + ) -> ClientResult<(NumberFor, HashSet)> { + let mut reverted_finalized = HashSet::new(); + let mut best_number = self.blockchain.info().best_number; let mut best_hash = self.blockchain.info().best_hash; @@ -1504,18 +1520,28 @@ impl sc_client_api::backend::Backend for Backend { return Ok(c.saturated_into::>()) } let mut transaction = Transaction::new(); + let removed_number = best_number; + let removed = self.blockchain.header(BlockId::Number(best_number))?.ok_or_else( + || sp_blockchain::Error::UnknownBlock( + format!("Error reverting to {}. Block hash not found.", best_number)))?; + let removed_hash = removed.hash(); + + let prev_number = best_number.saturating_sub(One::one()); + let prev_hash = self.blockchain.hash(prev_number)?.ok_or_else( + || sp_blockchain::Error::UnknownBlock( + format!("Error reverting to {}. Block hash not found.", best_number)) + )?; + + if !self.have_state_at(&prev_hash, prev_number) { + return Ok(c.saturated_into::>()) + } + match self.storage.state_db.revert_one() { Some(commit) => { apply_state_commit(&mut transaction, commit); - let removed_number = best_number; - let removed = self.blockchain.header(BlockId::Number(best_number))?.ok_or_else( - || sp_blockchain::Error::UnknownBlock( - format!("Error reverting to {}. Block hash not found.", best_number)))?; - best_number -= One::one(); // prev block - best_hash = self.blockchain.hash(best_number)?.ok_or_else( - || sp_blockchain::Error::UnknownBlock( - format!("Error reverting to {}. Block hash not found.", best_number)))?; + best_number = prev_number; + best_hash = prev_hash; let update_finalized = best_number < finalized; @@ -1528,12 +1554,17 @@ impl sc_client_api::backend::Backend for Backend { ), )?; if update_finalized { - transaction.set_from_vec(columns::META, meta_keys::FINALIZED_BLOCK, key.clone()); + transaction.set_from_vec( + columns::META, + meta_keys::FINALIZED_BLOCK, + key.clone() + ); + reverted_finalized.insert(removed_hash); } transaction.set_from_vec(columns::META, meta_keys::BEST_BLOCK, key); transaction.remove(columns::KEY_LOOKUP, removed.hash().as_ref()); children::remove_children(&mut transaction, columns::META, meta_keys::CHILDREN_PREFIX, best_hash); - self.storage.db.commit(transaction); + self.storage.db.commit(transaction)?; self.changes_tries_storage.post_commit(Some(changes_trie_cache_ops)); self.blockchain.update_meta(best_hash, best_number, true, update_finalized); } @@ -1552,14 +1583,14 @@ impl sc_client_api::backend::Backend for Backend { leaves.revert(best_hash, best_number); leaves.prepare_transaction(&mut transaction, columns::META, meta_keys::LEAF_PREFIX); - self.storage.db.commit(transaction); + self.storage.db.commit(transaction)?; Ok(()) }; revert_leaves()?; - Ok(reverted) + Ok((reverted, reverted_finalized)) } fn blockchain(&self) -> &BlockchainDb { @@ -1808,13 +1839,12 @@ pub(crate) mod tests { header.state_root = op.old_state.storage_root(storage .iter() - .cloned() - .map(|(x, y)| (x, Some(y))) + .map(|(x, y)| (&x[..], Some(&y[..]))) ).0.into(); let hash = header.hash(); op.reset_storage(Storage { - top: storage.iter().cloned().collect(), + top: storage.into_iter().collect(), children_default: Default::default(), }).unwrap(); op.set_block_data( @@ -1851,7 +1881,10 @@ pub(crate) mod tests { (vec![5, 5, 5], Some(vec![4, 5, 6])), ]; - let (root, overlay) = op.old_state.storage_root(storage.iter().cloned()); + let (root, overlay) = op.old_state.storage_root( + storage.iter() + .map(|(k, v)| (&k[..], v.as_ref().map(|v| &v[..]))) + ); op.update_db_storage(overlay).unwrap(); header.state_root = root.into(); @@ -1890,17 +1923,11 @@ pub(crate) mod tests { extrinsics_root: Default::default(), }; - let storage: Vec<(_, _)> = vec![]; - - header.state_root = op.old_state.storage_root(storage - .iter() - .cloned() - .map(|(x, y)| (x, Some(y))) - ).0.into(); + header.state_root = op.old_state.storage_root(std::iter::empty()).0.into(); let hash = header.hash(); op.reset_storage(Storage { - top: storage.iter().cloned().collect(), + top: Default::default(), children_default: Default::default(), }).unwrap(); @@ -1987,7 +2014,6 @@ pub(crate) mod tests { backend.commit_operation(op).unwrap(); - assert!(backend.storage.db.get( columns::STATE, &sp_trie::prefixed_key::(&key, EMPTY_PREFIX) diff --git a/client/db/src/light.rs b/client/db/src/light.rs index 849b439424d30d173d7d16263d4479424cb1dad9..139ecf3b22c72810888dbf7f72ffb6592eabdbfe 100644 --- a/client/db/src/light.rs +++ b/client/db/src/light.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! RocksDB-based light client blockchain storage. @@ -198,7 +200,7 @@ impl HeaderMetadata for LightStorage { header_metadata.clone(), ); header_metadata - }).ok_or(ClientError::UnknownBlock(format!("header not found in db: {}", hash))) + }).ok_or_else(|| ClientError::UnknownBlock(format!("header not found in db: {}", hash))) }, Ok) } @@ -400,7 +402,8 @@ impl AuxStore for LightStorage for k in delete { transaction.remove(columns::AUX, k); } - self.db.commit(transaction); + self.db.commit(transaction)?; + Ok(()) } @@ -493,7 +496,7 @@ impl Storage for LightStorage debug!("Light DB Commit {:?} ({})", hash, number); - self.db.commit(transaction); + self.db.commit(transaction)?; cache.commit(cache_ops) .expect("only fails if cache with given name isn't loaded yet;\ cache is already loaded because there are cache_ops; qed"); @@ -511,8 +514,9 @@ impl Storage for LightStorage let mut transaction = Transaction::new(); self.set_head_with_transaction(&mut transaction, hash.clone(), (number.clone(), hash.clone()))?; - self.db.commit(transaction); + self.db.commit(transaction)?; self.update_meta(hash, header.number().clone(), true, false); + Ok(()) } else { Err(ClientError::UnknownBlock(format!("Cannot set head {:?}", id))) @@ -550,7 +554,7 @@ impl Storage for LightStorage )? .into_ops(); - self.db.commit(transaction); + self.db.commit(transaction)?; cache.commit(cache_ops) .expect("only fails if cache with given name isn't loaded yet;\ cache is already loaded because there are cache_ops; qed"); diff --git a/client/db/src/offchain.rs b/client/db/src/offchain.rs index 8c58d5f42c391293268268eedd60859df0e54766..c4f0ce115ca54f1453e857cc34b96fd26918f8a8 100644 --- a/client/db/src/offchain.rs +++ b/client/db/src/offchain.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! RocksDB-based offchain workers local storage. @@ -23,6 +25,7 @@ use std::{ use crate::{columns, Database, DbHash, Transaction}; use parking_lot::Mutex; +use log::error; /// Offchain local storage #[derive(Clone)] @@ -62,7 +65,19 @@ impl sp_core::offchain::OffchainStorage for LocalStorage { let mut tx = Transaction::new(); tx.set(columns::OFFCHAIN, &key, value); - self.db.commit(tx); + if let Err(err) = self.db.commit(tx) { + error!("Error setting on local storage: {}", err) + } + } + + fn remove(&mut self, prefix: &[u8], key: &[u8]) { + let key: Vec = prefix.iter().chain(key).cloned().collect(); + let mut tx = Transaction::new(); + tx.remove(columns::OFFCHAIN, &key); + + if let Err(err) = self.db.commit(tx) { + error!("Error removing on local storage: {}", err) + } } fn get(&self, prefix: &[u8], key: &[u8]) -> Option> { diff --git a/client/db/src/parity_db.rs b/client/db/src/parity_db.rs index 7333f70e25f36ae0418e43d5fd4e8ebff8fff496..7085aa3bf8ccde1495627340352e24d4f9992a14 100644 --- a/client/db/src/parity_db.rs +++ b/client/db/src/parity_db.rs @@ -1,22 +1,23 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - +// along with this program. If not, see . /// A `Database` adapter for parity-db. -use sp_database::{Database, Change, Transaction, ColumnId}; +use sp_database::{Database, Change, ColumnId, Transaction, error::DatabaseError}; use crate::utils::NUM_COLUMNS; use crate::columns; @@ -26,7 +27,7 @@ fn handle_err(result: parity_db::Result) -> T { match result { Ok(r) => r, Err(e) => { - panic!("Critical database eror: {:?}", e); + panic!("Critical database error: {:?}", e); } } } @@ -43,7 +44,7 @@ pub fn open(path: &std::path::Path) -> parity_db::Result Database for DbAdapter { - fn commit(&self, transaction: Transaction) { + fn commit(&self, transaction: Transaction) -> Result<(), DatabaseError> { handle_err(self.0.commit(transaction.0.into_iter().map(|change| match change { Change::Set(col, key, value) => (col as u8, key, Some(value)), @@ -51,6 +52,8 @@ impl Database for DbAdapter { _ => unimplemented!(), })) ); + + Ok(()) } fn get(&self, col: ColumnId, key: &[u8]) -> Option> { diff --git a/client/db/src/stats.rs b/client/db/src/stats.rs index 8bc93b5b644cf985ff81fa0aaa0c0154c64eeaa0..8d208024b4bb29a1f064dfc00f3fa14b8df07f85 100644 --- a/client/db/src/stats.rs +++ b/client/db/src/stats.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Database usage statistics diff --git a/client/db/src/storage_cache.rs b/client/db/src/storage_cache.rs index 66ac74afa4f2a1d00458c58eeeda86e0b19e0f51..434b301ed6240e94539cbf5d3c06265231639039 100644 --- a/client/db/src/storage_cache.rs +++ b/client/db/src/storage_cache.rs @@ -621,21 +621,18 @@ impl>, B: BlockT> StateBackend> for Cachin self.state.for_child_keys_with_prefix(child_info, prefix, f) } - fn storage_root(&self, delta: I) -> (B::Hash, Self::Transaction) - where - I: IntoIterator, Option>)>, - { + fn storage_root<'a>( + &self, + delta: impl Iterator)>, + ) -> (B::Hash, Self::Transaction) where B::Hash: Ord { self.state.storage_root(delta) } - fn child_storage_root( + fn child_storage_root<'a>( &self, child_info: &ChildInfo, - delta: I, - ) -> (B::Hash, bool, Self::Transaction) - where - I: IntoIterator, Option>)>, - { + delta: impl Iterator)>, + ) -> (B::Hash, bool, Self::Transaction) where B::Hash: Ord { self.state.child_storage_root(child_info, delta) } @@ -806,21 +803,18 @@ impl>, B: BlockT> StateBackend> for Syncin self.caching_state().for_child_keys_with_prefix(child_info, prefix, f) } - fn storage_root(&self, delta: I) -> (B::Hash, Self::Transaction) - where - I: IntoIterator, Option>)>, - { + fn storage_root<'a>( + &self, + delta: impl Iterator)>, + ) -> (B::Hash, Self::Transaction) where B::Hash: Ord { self.caching_state().storage_root(delta) } - fn child_storage_root( + fn child_storage_root<'a>( &self, child_info: &ChildInfo, - delta: I, - ) -> (B::Hash, bool, Self::Transaction) - where - I: IntoIterator, Option>)>, - { + delta: impl Iterator)>, + ) -> (B::Hash, bool, Self::Transaction) where B::Hash: Ord { self.caching_state().child_storage_root(child_info, delta) } diff --git a/client/db/src/subdb.rs b/client/db/src/subdb.rs index 2e436aa2c92c870dfe60117ec50b61c6213094f3..2f72632b045622fcd035e50f7560c2c4b0fe753c 100644 --- a/client/db/src/subdb.rs +++ b/client/db/src/subdb.rs @@ -1,19 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - +// along with this program. If not, see . /// A `Database` adapter for subdb. use sp_database::{self, ColumnId}; diff --git a/client/db/src/utils.rs b/client/db/src/utils.rs index d40abcab6693c6b0cb8cce5820256ae95bccd4ab..168ab9bbb71f633706daee5c4e8b47f8088b1f35 100644 --- a/client/db/src/utils.rs +++ b/client/db/src/utils.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Db-based backend utility structures and functions, used by both //! full and light storages. @@ -34,7 +36,7 @@ use crate::{DatabaseSettings, DatabaseSettingsSrc, Database, DbHash}; /// Number of columns in the db. Must be the same for both full && light dbs. /// Otherwise RocksDb will fail to open database && check its type. -#[cfg(any(feature = "kvdb-rocksdb", feature = "test-helpers", test))] +#[cfg(any(feature = "with-kvdb-rocksdb", feature = "with-parity-db", feature = "test-helpers", test))] pub const NUM_COLUMNS: u32 = 11; /// Meta column. The set of keys in the column is shared by full && light storages. pub const COLUMN_META: u32 = 0; @@ -179,8 +181,8 @@ pub fn insert_hash_to_key_mapping, H: AsRef<[u8]> + Clone>( ) -> sp_blockchain::Result<()> { transaction.set_from_vec( key_lookup_col, - hash.clone().as_ref(), - number_and_hash_to_lookup_key(number, hash)?, + hash.as_ref(), + number_and_hash_to_lookup_key(number, hash.clone())?, ); Ok(()) } @@ -210,8 +212,14 @@ pub fn open_database( config: &DatabaseSettings, db_type: DatabaseType, ) -> sp_blockchain::Result>> { + let db_open_error = |feat| Err( + sp_blockchain::Error::Backend( + format!("`{}` feature not enabled, database can not be opened", feat), + ), + ); + let db: Arc> = match &config.source { - #[cfg(any(feature = "kvdb-rocksdb", test))] + #[cfg(any(feature = "with-kvdb-rocksdb", test))] DatabaseSettingsSrc::RocksDb { path, cache_size } => { // first upgrade database to required version crate::upgrade::upgrade_db::(&path, db_type)?; @@ -247,21 +255,29 @@ pub fn open_database( .map_err(|err| sp_blockchain::Error::Backend(format!("{}", err)))?; sp_database::as_database(db) }, - #[cfg(feature = "subdb")] + #[cfg(not(any(feature = "with-kvdb-rocksdb", test)))] + DatabaseSettingsSrc::RocksDb { .. } => { + return db_open_error("with-kvdb-rocksdb"); + }, + #[cfg(feature = "with-subdb")] DatabaseSettingsSrc::SubDb { path } => { crate::subdb::open(&path, NUM_COLUMNS) .map_err(|e| sp_blockchain::Error::Backend(format!("{:?}", e)))? }, - #[cfg(feature = "parity-db")] + #[cfg(not(feature = "with-subdb"))] + DatabaseSettingsSrc::SubDb { .. } => { + return db_open_error("with-subdb"); + }, + #[cfg(feature = "with-parity-db")] DatabaseSettingsSrc::ParityDb { path } => { crate::parity_db::open(&path) .map_err(|e| sp_blockchain::Error::Backend(format!("{:?}", e)))? }, - DatabaseSettingsSrc::Custom(db) => db.clone(), - _ => { - let msg = "Trying to open a unsupported database".into(); - return Err(sp_blockchain::Error::Backend(msg)); + #[cfg(not(feature = "with-parity-db"))] + DatabaseSettingsSrc::ParityDb { .. } => { + return db_open_error("with-parity-db"); }, + DatabaseSettingsSrc::Custom(db) => db.clone(), }; check_database_type(&*db, db_type)?; @@ -281,7 +297,7 @@ pub fn check_database_type(db: &dyn Database, db_type: DatabaseType) -> None => { let mut transaction = Transaction::new(); transaction.set(COLUMN_META, meta_keys::TYPE, db_type.as_str().as_bytes()); - db.commit(transaction) + db.commit(transaction)?; }, } diff --git a/client/executor/Cargo.toml b/client/executor/Cargo.toml index ef1b24ea7112615f21cc48c6569e2adc54cf8d40..f963068ea37b2f081121975da76874a9229877da 100644 --- a/client/executor/Cargo.toml +++ b/client/executor/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-executor" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "A crate that provides means of executing/dispatching calls into the runtime." @@ -14,23 +14,23 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] derive_more = "0.99.2" -codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-trie = { version = "2.0.0-dev", path = "../../primitives/trie" } -sp-serializer = { version = "2.0.0-dev", path = "../../primitives/serializer" } -sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } -sp-panic-handler = { version = "2.0.0-dev", path = "../../primitives/panic-handler" } +codec = { package = "parity-scale-codec", version = "1.3.4" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-trie = { version = "2.0.0-rc6", path = "../../primitives/trie" } +sp-serializer = { version = "2.0.0-rc6", path = "../../primitives/serializer" } +sp-version = { version = "2.0.0-rc6", path = "../../primitives/version" } +sp-panic-handler = { version = "2.0.0-rc6", path = "../../primitives/panic-handler" } wasmi = "0.6.2" parity-wasm = "0.41.0" lazy_static = "1.4.0" -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } -sp-wasm-interface = { version = "2.0.0-dev", path = "../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-dev", path = "../../primitives/runtime-interface" } -sp-externalities = { version = "0.8.0-dev", path = "../../primitives/externalities" } -sc-executor-common = { version = "0.8.0-dev", path = "common" } -sc-executor-wasmi = { version = "0.8.0-dev", path = "wasmi" } -sc-executor-wasmtime = { version = "0.8.0-dev", path = "wasmtime", optional = true } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } +sp-wasm-interface = { version = "2.0.0-rc6", path = "../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-rc6", path = "../../primitives/runtime-interface" } +sp-externalities = { version = "0.8.0-rc6", path = "../../primitives/externalities" } +sc-executor-common = { version = "0.8.0-rc6", path = "common" } +sc-executor-wasmi = { version = "0.8.0-rc6", path = "wasmi" } +sc-executor-wasmtime = { version = "0.8.0-rc6", path = "wasmtime", optional = true } parking_lot = "0.10.0" log = "0.4.8" libsecp256k1 = "0.3.4" @@ -38,12 +38,15 @@ libsecp256k1 = "0.3.4" [dev-dependencies] assert_matches = "1.3.0" wabt = "0.9.2" -hex-literal = "0.2.1" -sc-runtime-test = { version = "2.0.0-dev", path = "runtime-test" } -substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +hex-literal = "0.3.1" +sc-runtime-test = { version = "2.0.0-rc6", path = "runtime-test" } +substrate-test-runtime = { version = "2.0.0-rc6", path = "../../test-utils/runtime" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } test-case = "0.3.3" -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-tracing = { version = "2.0.0-rc6", path = "../../primitives/tracing" } +sc-tracing = { version = "2.0.0-rc6", path = "../tracing" } +tracing = "0.1.18" [features] default = [ "std" ] diff --git a/client/executor/README.md b/client/executor/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ab7b3d45206f9fc4ca4e0323dcc5b27bbf943226 --- /dev/null +++ b/client/executor/README.md @@ -0,0 +1,13 @@ +A crate that provides means of executing/dispatching calls into the runtime. + +There are a few responsibilities of this crate at the moment: + +- It provides an implementation of a common entrypoint for calling into the runtime, both +wasm and compiled. +- It defines the environment for the wasm execution, namely the host functions that are to be +provided into the wasm runtime module. +- It also provides the required infrastructure for executing the current wasm runtime (specified +by the current value of `:code` in the provided externalities), i.e. interfacing with +wasm engine used, instance cache. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/executor/common/Cargo.toml b/client/executor/common/Cargo.toml index c27ed8db0ae885bc22ef5377d975164e83bc57a9..bdbc5071323a4177c72acafdecd59939f2fc3257 100644 --- a/client/executor/common/Cargo.toml +++ b/client/executor/common/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-executor-common" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "A set of common definitions that are needed for defining execution engines." @@ -16,13 +16,13 @@ targets = ["x86_64-unknown-linux-gnu"] log = "0.4.8" derive_more = "0.99.2" parity-wasm = "0.41.0" -codec = { package = "parity-scale-codec", version = "1.3.0" } +codec = { package = "parity-scale-codec", version = "1.3.4" } wasmi = "0.6.2" -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-dev", path = "../../../primitives/allocator" } -sp-wasm-interface = { version = "2.0.0-dev", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-dev", path = "../../../primitives/runtime-interface" } -sp-serializer = { version = "2.0.0-dev", path = "../../../primitives/serializer" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-rc6", path = "../../../primitives/allocator" } +sp-wasm-interface = { version = "2.0.0-rc6", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-rc6", path = "../../../primitives/runtime-interface" } +sp-serializer = { version = "2.0.0-rc6", path = "../../../primitives/serializer" } [features] default = [] diff --git a/client/executor/common/README.md b/client/executor/common/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0c0d3bf08bcb20519013a428ee4daf9ce6c1a622 --- /dev/null +++ b/client/executor/common/README.md @@ -0,0 +1,3 @@ +A set of common definitions that are needed for defining execution engines. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/executor/common/src/error.rs b/client/executor/common/src/error.rs index 66d520e942411d01c540bd64f7bde4147be28c74..04850e6f8dd7e34b1b438ec1a4c58f6ed026eb5b 100644 --- a/client/executor/common/src/error.rs +++ b/client/executor/common/src/error.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Rust executor possible errors. diff --git a/client/executor/common/src/sandbox.rs b/client/executor/common/src/sandbox.rs index ccfdc2f3e0e28c2e8b6a1b1734ee8be450b088ff..b2c35b758271829c8771034da08aee46c52dd3db 100644 --- a/client/executor/common/src/sandbox.rs +++ b/client/executor/common/src/sandbox.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! This module implements sandboxing support in the runtime. //! @@ -236,21 +238,33 @@ impl<'a, FE: SandboxCapabilities + 'a> Externals for GuestExternals<'a, FE> { .supervisor_externals .allocate_memory(invoke_args_len) .map_err(|_| trap("Can't allocate memory in supervisor for the arguments"))?; - self + + let deallocate = |this: &mut GuestExternals, ptr, fail_msg| { + this + .supervisor_externals + .deallocate_memory(ptr) + .map_err(|_| trap(fail_msg)) + }; + + if self .supervisor_externals .write_memory(invoke_args_ptr, &invoke_args_data) - .map_err(|_| trap("Can't write invoke args into memory"))?; + .is_err() + { + deallocate(self, invoke_args_ptr, "Failed dealloction after failed write of invoke arguments")?; + return Err(trap("Can't write invoke args into memory")); + } + let result = self.supervisor_externals.invoke( &self.sandbox_instance.dispatch_thunk, invoke_args_ptr, invoke_args_len, state, func_idx, - )?; - self - .supervisor_externals - .deallocate_memory(invoke_args_ptr) - .map_err(|_| trap("Can't deallocate memory for dispatch thunk's invoke arguments"))?; + ); + + deallocate(self, invoke_args_ptr, "Can't deallocate memory for dispatch thunk's invoke arguments")?; + let result = result?; // dispatch_thunk returns pointer to serialized arguments. // Unpack pointer and len of the serialized result data. @@ -264,12 +278,11 @@ impl<'a, FE: SandboxCapabilities + 'a> Externals for GuestExternals<'a, FE> { let serialized_result_val = self.supervisor_externals .read_memory(serialized_result_val_ptr, serialized_result_val_len) - .map_err(|_| trap("Can't read the serialized result from dispatch thunk"))?; - self.supervisor_externals - .deallocate_memory(serialized_result_val_ptr) - .map_err(|_| trap("Can't deallocate memory for dispatch thunk's result"))?; + .map_err(|_| trap("Can't read the serialized result from dispatch thunk")); - deserialize_result(&serialized_result_val) + deallocate(self, serialized_result_val_ptr, "Can't deallocate memory for dispatch thunk's result") + .and_then(|_| serialized_result_val) + .and_then(|serialized_result_val| deserialize_result(&serialized_result_val)) } } diff --git a/client/executor/common/src/util.rs b/client/executor/common/src/util.rs index 149db13bc0768a92408f8b1af1a05d518a8ae97d..92a48e14018143944dae245abddb1db481ce4021 100644 --- a/client/executor/common/src/util.rs +++ b/client/executor/common/src/util.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A set of utilities for resetting a wasm instance to its initial state. diff --git a/client/executor/runtime-test/Cargo.toml b/client/executor/runtime-test/Cargo.toml index b8ae805192d9408c474febd8d6d266df2d81b7b2..037359ac9eef69835f0d1d928ef4b88e835a2845 100644 --- a/client/executor/runtime-test/Cargo.toml +++ b/client/executor/runtime-test/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-runtime-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -13,12 +13,12 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/io" } -sp-sandbox = { version = "0.8.0-dev", default-features = false, path = "../../../primitives/sandbox" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } -sp-allocator = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/allocator" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/io" } +sp-sandbox = { version = "0.8.0-rc6", default-features = false, path = "../../../primitives/sandbox" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/runtime" } +sp-allocator = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/allocator" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/client/executor/runtime-test/build.rs b/client/executor/runtime-test/build.rs index 647b4768141d2203155bf5325f9ff87f7d9c2446..1ed5aa44bc5c4673ad031190e2f36715907a4e00 100644 --- a/client/executor/runtime-test/build.rs +++ b/client/executor/runtime-test/build.rs @@ -19,7 +19,7 @@ use wasm_builder_runner::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("1.0.9", "../../../utils/wasm-builder") + .with_wasm_builder_from_crates_or_path("2.0.0", "../../../utils/wasm-builder") .export_heap_base() .import_memory() .build() diff --git a/client/executor/runtime-test/src/lib.rs b/client/executor/runtime-test/src/lib.rs index 15a4177048a408b3b7f308f9d4ea63049f1b0769..a80ee1d6ba40f7db952973da782cc5a504c3bc2f 100644 --- a/client/executor/runtime-test/src/lib.rs +++ b/client/executor/runtime-test/src/lib.rs @@ -1,17 +1,23 @@ #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "strict", deny(warnings))] // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +#[cfg(feature = "std")] +/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. +pub fn wasm_binary_unwrap() -> &'static [u8] { + WASM_BINARY.expect("Development wasm binary is not available. Testing is only \ + supported with the flag disabled.") +} + #[cfg(not(feature = "std"))] use sp_std::{vec::Vec, vec}; #[cfg(not(feature = "std"))] use sp_io::{ storage, hashing::{blake2_128, blake2_256, sha2_256, twox_128, twox_256}, - crypto::{ed25519_verify, sr25519_verify}, + crypto::{ed25519_verify, sr25519_verify}, wasm_tracing, }; #[cfg(not(feature = "std"))] use sp_runtime::{print, traits::{BlakeTwo256, Hash}}; @@ -247,6 +253,14 @@ sp_core::wasm_export_functions! { sp_allocator::FreeingBumpHeapAllocator::new(0); } + fn test_enter_span() -> u64 { + wasm_tracing::enter_span("integration_test_span_target", "integration_test_span_name") + } + + fn test_exit_span(span_id: u64) { + wasm_tracing::exit_span(span_id) + } + fn returns_mutable_static() -> u64 { unsafe { MUTABLE_STATIC += 1; @@ -346,7 +360,7 @@ fn execute_sandboxed( Memory::new() can't return a Error qed" ), }; - env_builder.add_memory("env", "memory", memory.clone()); + env_builder.add_memory("env", "memory", memory); env_builder }; diff --git a/client/executor/src/integration_tests/mod.rs b/client/executor/src/integration_tests/mod.rs index 886860d7feb6130b4430ac831fbb258daa287363..a9ac0d0f30c237510ab9b0a16595ff1399b65945 100644 --- a/client/executor/src/integration_tests/mod.rs +++ b/client/executor/src/integration_tests/mod.rs @@ -1,19 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - +// along with this program. If not, see . mod sandbox; use codec::{Encode, Decode}; @@ -23,7 +24,7 @@ use sp_core::{ offchain::{OffchainExt, testing}, traits::{Externalities, CallInWasm}, }; -use sc_runtime_test::WASM_BINARY; +use sc_runtime_test::wasm_binary_unwrap; use sp_state_machine::TestExternalities as CoreTestExternalities; use test_case::test_case; use sp_trie::{TrieConfiguration, trie_types::Layout}; @@ -48,7 +49,7 @@ fn call_in_wasm( 8, ); executor.call_in_wasm( - &WASM_BINARY[..], + &wasm_binary_unwrap()[..], None, function, call_data, @@ -496,9 +497,7 @@ fn offchain_http_should_work(wasm_method: WasmExecutionMethod) { let mut ext = TestExternalities::default(); let (offchain, state) = testing::TestOffchainExt::new(); ext.register_extension(OffchainExt::new(offchain)); - state.write().expect_request( - 0, - testing::PendingRequest { + state.write().expect_request(testing::PendingRequest { method: "POST".into(), uri: "http://localhost:12345".into(), body: vec![1, 2, 3, 4], @@ -534,7 +533,7 @@ fn should_trap_when_heap_exhausted(wasm_method: WasmExecutionMethod) { 8, ); executor.call_in_wasm( - &WASM_BINARY[..], + &wasm_binary_unwrap()[..], None, "test_exhaust_heap", &[0], @@ -549,7 +548,7 @@ fn returns_mutable_static(wasm_method: WasmExecutionMethod) { let runtime = crate::wasm_runtime::create_wasm_runtime_with_code( wasm_method, 1024, - &WASM_BINARY[..], + &wasm_binary_unwrap()[..], HostFunctions::host_functions(), true, ).expect("Creates runtime"); @@ -583,7 +582,7 @@ fn restoration_of_globals(wasm_method: WasmExecutionMethod) { let runtime = crate::wasm_runtime::create_wasm_runtime_with_code( wasm_method, REQUIRED_MEMORY_PAGES, - &WASM_BINARY[..], + &wasm_binary_unwrap()[..], HostFunctions::host_functions(), true, ).expect("Creates runtime"); @@ -603,7 +602,7 @@ fn heap_is_reset_between_calls(wasm_method: WasmExecutionMethod) { let runtime = crate::wasm_runtime::create_wasm_runtime_with_code( wasm_method, 1024, - &WASM_BINARY[..], + &wasm_binary_unwrap()[..], HostFunctions::host_functions(), true, ).expect("Creates runtime"); @@ -625,21 +624,136 @@ fn heap_is_reset_between_calls(wasm_method: WasmExecutionMethod) { #[test_case(WasmExecutionMethod::Interpreted)] #[cfg_attr(feature = "wasmtime", test_case(WasmExecutionMethod::Compiled))] fn parallel_execution(wasm_method: WasmExecutionMethod) { - let threads: Vec<_> = (0..8).map(|_| std::thread::spawn(move || { - let mut ext = TestExternalities::default(); - let mut ext = ext.ext(); - assert_eq!( - call_in_wasm( - "test_twox_128", - &[0], - wasm_method.clone(), - &mut ext, - ).unwrap(), - hex!("99e9d85137db46ef4bbea33613baafd5").to_vec().encode(), - ); - })).collect(); + let executor = std::sync::Arc::new(crate::WasmExecutor::new( + wasm_method, + Some(1024), + HostFunctions::host_functions(), + 8, + )); + let code_hash = blake2_256(wasm_binary_unwrap()).to_vec(); + let threads: Vec<_> = (0..8).map(|_| + { + let executor = executor.clone(); + let code_hash = code_hash.clone(); + std::thread::spawn(move || { + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + assert_eq!( + executor.call_in_wasm( + &wasm_binary_unwrap()[..], + Some(code_hash.clone()), + "test_twox_128", + &[0], + &mut ext, + sp_core::traits::MissingHostFunctions::Allow, + ).unwrap(), + hex!("99e9d85137db46ef4bbea33613baafd5").to_vec().encode(), + ); + }) + }).collect(); for t in threads.into_iter() { t.join().unwrap(); } } + +#[test_case(WasmExecutionMethod::Interpreted)] +fn wasm_tracing_should_work(wasm_method: WasmExecutionMethod) { + + use std::sync::{Arc, Mutex}; + + use sc_tracing::{SpanDatum, TraceEvent}; + + struct TestTraceHandler(Arc>>); + + impl sc_tracing::TraceHandler for TestTraceHandler { + fn handle_span(&self, sd: SpanDatum) { + self.0.lock().unwrap().push(sd); + } + + fn handle_event(&self, _event: TraceEvent) {} + } + + let traces = Arc::new(Mutex::new(Vec::new())); + let handler = TestTraceHandler(traces.clone()); + + // Create subscriber with wasm_tracing disabled + let test_subscriber = sc_tracing::ProfilingSubscriber::new_with_handler( + Box::new(handler), "integration_test_span_target"); + + let _guard = tracing::subscriber::set_default(test_subscriber); + + let mut ext = TestExternalities::default(); + let mut ext = ext.ext(); + + // Test tracing disabled + assert!(!sp_tracing::wasm_tracing_enabled()); + + let span_id = call_in_wasm( + "test_enter_span", + &[], + wasm_method, + &mut ext, + ).unwrap(); + + assert_eq!( + 0u64.encode(), + span_id + ); + // Repeat to check span id always 0 when deactivated + let span_id = call_in_wasm( + "test_enter_span", + &[], + wasm_method, + &mut ext, + ).unwrap(); + + assert_eq!( + 0u64.encode(), + span_id + ); + + call_in_wasm( + "test_exit_span", + &span_id.encode(), + wasm_method, + &mut ext, + ).unwrap(); + // Check span has not been recorded + let len = traces.lock().unwrap().len(); + assert_eq!(len, 0); + + // Test tracing enabled + sp_tracing::set_wasm_tracing(true); + + let span_id = call_in_wasm( + "test_enter_span", + &[], + wasm_method, + &mut ext, + ).unwrap(); + + let span_id = u64::decode(&mut &span_id[..]).unwrap(); + + assert!( + span_id > 0 + ); + + call_in_wasm( + "test_exit_span", + &span_id.encode(), + wasm_method, + &mut ext, + ).unwrap(); + + // Check there is only the single trace + let len = traces.lock().unwrap().len(); + assert_eq!(len, 1); + + let span_datum = traces.lock().unwrap().pop().unwrap(); + let values = span_datum.values; + assert_eq!(span_datum.target, "integration_test_span_target"); + assert_eq!(span_datum.name, "integration_test_span_name"); + assert_eq!(values.bool_values.get("wasm").unwrap(), &true); + assert_eq!(values.bool_values.get("is_valid_trace").unwrap(), &true); +} diff --git a/client/executor/src/integration_tests/sandbox.rs b/client/executor/src/integration_tests/sandbox.rs index 8e8b7896cf90b5630486fa780af0a3cc94d9b8dd..f84e446b416c06c2f423d71103dbc1597ec85138 100644 --- a/client/executor/src/integration_tests/sandbox.rs +++ b/client/executor/src/integration_tests/sandbox.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use super::{TestExternalities, call_in_wasm}; use crate::WasmExecutionMethod; diff --git a/client/executor/src/lib.rs b/client/executor/src/lib.rs index 3d7db630f04ac74e34538627a2a657af18fceb71..56a81b24b4076e39c1d66a7bc57058ae1dcd8e7d 100644 --- a/client/executor/src/lib.rs +++ b/client/executor/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A crate that provides means of executing/dispatching calls into the runtime. //! @@ -63,7 +65,7 @@ pub trait RuntimeInfo { #[cfg(test)] mod tests { use super::*; - use sc_runtime_test::WASM_BINARY; + use sc_runtime_test::wasm_binary_unwrap; use sp_io::TestExternalities; use sp_wasm_interface::HostFunctions; use sp_core::traits::CallInWasm; @@ -80,7 +82,7 @@ mod tests { 8, ); let res = executor.call_in_wasm( - &WASM_BINARY[..], + &wasm_binary_unwrap()[..], None, "test_empty_return", &[], diff --git a/client/executor/src/native_executor.rs b/client/executor/src/native_executor.rs index b859b544a3a9b95c44c56f0cd5920a8fd34cab14..0aeec98067f407d891f98d508f430bcfdc37a0ff 100644 --- a/client/executor/src/native_executor.rs +++ b/client/executor/src/native_executor.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::{ RuntimeInfo, error::{Error, Result}, @@ -334,7 +336,7 @@ impl CodeExecutor for NativeExecutor { let res = with_externalities_safe(&mut **ext, move || (call)()) .and_then(|r| r .map(NativeOrEncoded::Native) - .map_err(|s| Error::ApiError(s.to_string())) + .map_err(|s| Error::ApiError(s)) ); Ok(res) diff --git a/client/executor/wasmi/Cargo.toml b/client/executor/wasmi/Cargo.toml index 3180eebb4f56ce76a1601e4b734a32be4c5fae81..14468e71fd60eca15350142157d559cc2137bcfe 100644 --- a/client/executor/wasmi/Cargo.toml +++ b/client/executor/wasmi/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-executor-wasmi" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "This crate provides an implementation of `WasmRuntime` that is baked by wasmi." @@ -15,9 +15,9 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] log = "0.4.8" wasmi = "0.6.2" -codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-executor-common = { version = "0.8.0-dev", path = "../common" } -sp-wasm-interface = { version = "2.0.0-dev", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-dev", path = "../../../primitives/runtime-interface" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-dev", path = "../../../primitives/allocator" } +codec = { package = "parity-scale-codec", version = "1.3.4" } +sc-executor-common = { version = "0.8.0-rc6", path = "../common" } +sp-wasm-interface = { version = "2.0.0-rc6", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-rc6", path = "../../../primitives/runtime-interface" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-rc6", path = "../../../primitives/allocator" } diff --git a/client/executor/wasmi/README.md b/client/executor/wasmi/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ad613aa1245e3378704e04f5f6a70070b6dc9ec1 --- /dev/null +++ b/client/executor/wasmi/README.md @@ -0,0 +1,3 @@ +This crate provides an implementation of `WasmModule` that is baked by wasmi. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/executor/wasmi/src/lib.rs b/client/executor/wasmi/src/lib.rs index e4b4aca40967d982fe342985f829bf2c4c190e39..1632aa3c18ad59b5bf7517ecf1596a37e8ecc1d1 100644 --- a/client/executor/wasmi/src/lib.rs +++ b/client/executor/wasmi/src/lib.rs @@ -234,7 +234,6 @@ impl<'a> Sandbox for FunctionExecutor<'a> { table.get(dispatch_thunk_id) .map_err(|_| "dispatch_thunk_idx is out of the table bounds")? .ok_or_else(|| "dispatch_thunk_idx points on an empty table entry")? - .clone() }; let guest_env = match sandbox::GuestEnvironment::decode(&self.sandbox_store, raw_env_def) { diff --git a/client/executor/wasmtime/Cargo.toml b/client/executor/wasmtime/Cargo.toml index 0864c19bf0fe6a197603a2e0464980745c12e788..9618a659f526231341d45ed4c924fd4c9dc9d579 100644 --- a/client/executor/wasmtime/Cargo.toml +++ b/client/executor/wasmtime/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-executor-wasmtime" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Defines a `WasmRuntime` that uses the Wasmtime JIT to execute." @@ -15,17 +15,14 @@ targets = ["x86_64-unknown-linux-gnu"] log = "0.4.8" scoped-tls = "1.0" parity-wasm = "0.41.0" -codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-executor-common = { version = "0.8.0-dev", path = "../common" } -sp-wasm-interface = { version = "2.0.0-dev", path = "../../../primitives/wasm-interface" } -sp-runtime-interface = { version = "2.0.0-dev", path = "../../../primitives/runtime-interface" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-allocator = { version = "2.0.0-dev", path = "../../../primitives/allocator" } -wasmtime = { package = "substrate-wasmtime", version = "0.16.0-threadsafe.2" } -wasmtime-runtime = { package = "substrate-wasmtime-runtime", version = "0.16.0-threadsafe.2" } -wasmtime-environ = "0.16" -cranelift-wasm = "0.63" -cranelift-codegen = "0.63" +codec = { package = "parity-scale-codec", version = "1.3.4" } +sc-executor-common = { version = "0.8.0-rc6", path = "../common" } +sp-wasm-interface = { version = "2.0.0-rc6", path = "../../../primitives/wasm-interface" } +sp-runtime-interface = { version = "2.0.0-rc6", path = "../../../primitives/runtime-interface" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-allocator = { version = "2.0.0-rc6", path = "../../../primitives/allocator" } +wasmtime = "0.19" +pwasm-utils = "0.14.0" [dev-dependencies] assert_matches = "1.3.0" diff --git a/client/executor/wasmtime/README.md b/client/executor/wasmtime/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3e9ac0bddbdc17539d12893553789983e38ab05f --- /dev/null +++ b/client/executor/wasmtime/README.md @@ -0,0 +1 @@ +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/executor/wasmtime/src/host.rs b/client/executor/wasmtime/src/host.rs index 8c481e95c43714fa79f704881c07429b998466cb..eeb7cb927167f176641c9f0ec38d1cd4de1758e4 100644 --- a/client/executor/wasmtime/src/host.rs +++ b/client/executor/wasmtime/src/host.rs @@ -308,6 +308,7 @@ impl<'a> Sandbox for HostContext<'a> { .ok_or_else(|| "dispatch_thunk_id is out of bounds")? .funcref() .ok_or_else(|| "dispatch_thunk_idx should be a funcref")? + .ok_or_else(|| "dispatch_thunk_idx should point to actual func")? .clone(); SupervisorFuncRef(func_ref) }; diff --git a/client/executor/wasmtime/src/imports.rs b/client/executor/wasmtime/src/imports.rs index 2d9794b7eda12f5eccf38db25afe58998459521a..add62df5cef45851451503ce2a00b3d2e537b45f 100644 --- a/client/executor/wasmtime/src/imports.rs +++ b/client/executor/wasmtime/src/imports.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::state_holder; use sc_executor_common::error::WasmError; @@ -20,7 +22,7 @@ use sp_wasm_interface::{Function, Value, ValueType}; use std::any::Any; use wasmtime::{ Extern, ExternType, Func, FuncType, ImportType, Limits, Memory, MemoryType, Module, - Trap, Val, + Trap, Val, Store, }; pub struct Imports { @@ -33,6 +35,7 @@ pub struct Imports { /// Goes over all imports of a module and prepares a vector of `Extern`s that can be used for /// instantiation of the module. Returns an error if there are imports that cannot be satisfied. pub fn resolve_imports( + store: &Store, module: &Module, host_functions: &[&'static dyn Function], heap_pages: u32, @@ -52,10 +55,10 @@ pub fn resolve_imports( let resolved = match import_ty.name() { "memory" => { memory_import_index = Some(externs.len()); - resolve_memory_import(module, &import_ty, heap_pages)? + resolve_memory_import(store, &import_ty, heap_pages)? } _ => resolve_func_import( - module, + store, &import_ty, host_functions, allow_missing_func_imports, @@ -70,7 +73,7 @@ pub fn resolve_imports( } fn resolve_memory_import( - module: &Module, + store: &Store, import_ty: &ImportType, heap_pages: u32, ) -> Result { @@ -103,12 +106,12 @@ fn resolve_memory_import( } let memory_ty = MemoryType::new(Limits::new(initial, requested_memory_ty.limits().max())); - let memory = Memory::new(module.store(), memory_ty); + let memory = Memory::new(store, memory_ty); Ok(Extern::Memory(memory)) } fn resolve_func_import( - module: &Module, + store: &Store, import_ty: &ImportType, host_functions: &[&'static dyn Function], allow_missing_func_imports: bool, @@ -130,7 +133,7 @@ fn resolve_func_import( { Some(host_func) => host_func, None if allow_missing_func_imports => { - return Ok(MissingHostFuncHandler::new(import_ty).into_extern(module, &func_ty)); + return Ok(MissingHostFuncHandler::new(import_ty).into_extern(store, &func_ty)); } None => { return Err(WasmError::Other(format!( @@ -148,7 +151,7 @@ fn resolve_func_import( ))); } - Ok(HostFuncHandler::new(*host_func).into_extern(module)) + Ok(HostFuncHandler::new(*host_func).into_extern(store)) } /// Returns `true` if `lhs` and `rhs` represent the same signature. @@ -221,10 +224,10 @@ impl HostFuncHandler { } } - fn into_extern(self, module: &Module) -> Extern { + fn into_extern(self, store: &Store) -> Extern { let host_func = self.host_func; let func_ty = wasmtime_func_sig(self.host_func); - let func = Func::new(module.store(), func_ty, + let func = Func::new(store, func_ty, move |_, params, result| { call_static(host_func, params, result) } @@ -247,9 +250,9 @@ impl MissingHostFuncHandler { } } - fn into_extern(self, wasmtime_module: &Module, func_ty: &FuncType) -> Extern { + fn into_extern(self, store: &Store, func_ty: &FuncType) -> Extern { let Self { module, name } = self; - let func = Func::new(wasmtime_module.store(), func_ty.clone(), + let func = Func::new(store, func_ty.clone(), move |_, _, _| Err(Trap::new(format!( "call to a missing function {}:{}", module, name @@ -291,7 +294,7 @@ fn into_wasmtime_val_type(val_ty: ValueType) -> wasmtime::ValType { /// Converts a `Val` into a substrate runtime interface `Value`. /// /// Panics if the given value doesn't have a corresponding variant in `Value`. -fn into_value(val: Val) -> Value { +pub fn into_value(val: Val) -> Value { match val { Val::I32(v) => Value::I32(v), Val::I64(v) => Value::I64(v), @@ -301,7 +304,7 @@ fn into_value(val: Val) -> Value { } } -fn into_wasmtime_val(value: Value) -> wasmtime::Val { +pub fn into_wasmtime_val(value: Value) -> wasmtime::Val { match value { Value::I32(v) => Val::I32(v), Value::I64(v) => Val::I64(v), diff --git a/client/executor/wasmtime/src/instance_wrapper.rs b/client/executor/wasmtime/src/instance_wrapper.rs index bf01896809ed6104142308b4b298bac7648ab984..9a4e44d3b106c9777999b191e3ab297f1eb973f5 100644 --- a/client/executor/wasmtime/src/instance_wrapper.rs +++ b/client/executor/wasmtime/src/instance_wrapper.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Defines data and logic needed for interaction with an WebAssembly instance of a substrate //! runtime module. @@ -26,37 +28,37 @@ use sc_executor_common::{ util::{WasmModuleInfo, DataSegmentsSnapshot}, }; use sp_wasm_interface::{Pointer, WordSize, Value}; -use wasmtime::{Store, Instance, Module, Memory, Table, Val, Func, Extern, Global}; +use wasmtime::{Engine, Instance, Module, Memory, Table, Val, Func, Extern, Global, Store}; +use parity_wasm::elements; mod globals_snapshot; pub use globals_snapshot::GlobalsSnapshot; pub struct ModuleWrapper { - imported_globals_count: u32, - globals_count: u32, module: Module, data_segments_snapshot: DataSegmentsSnapshot, } impl ModuleWrapper { - pub fn new(store: &Store, code: &[u8]) -> Result { - let module = Module::new(&store, code) + pub fn new(engine: &Engine, code: &[u8]) -> Result { + let mut raw_module: elements::Module = elements::deserialize_buffer(code) + .map_err(|e| Error::from(format!("cannot decode module: {}", e)))?; + pwasm_utils::export_mutable_globals(&mut raw_module, "exported_internal_global"); + let instrumented_code = elements::serialize(raw_module) + .map_err(|e| Error::from(format!("cannot encode module: {}", e)))?; + + let module = Module::new(engine, &instrumented_code) .map_err(|e| Error::from(format!("cannot create module: {}", e)))?; let module_info = WasmModuleInfo::new(code) .ok_or_else(|| Error::from("cannot deserialize module".to_string()))?; - let declared_globals_count = module_info.declared_globals_count(); - let imported_globals_count = module_info.imported_globals_count(); - let globals_count = imported_globals_count + declared_globals_count; let data_segments_snapshot = DataSegmentsSnapshot::take(&module_info) .map_err(|e| Error::from(format!("cannot take data segments snapshot: {}", e)))?; Ok(Self { module, - imported_globals_count, - globals_count, data_segments_snapshot, }) } @@ -76,8 +78,6 @@ impl ModuleWrapper { /// routines. pub struct InstanceWrapper { instance: Instance, - globals_count: u32, - imported_globals_count: u32, // The memory instance of the `instance`. // // It is important to make sure that we don't make any copies of this to make it easier to proof @@ -119,8 +119,8 @@ fn extern_func(extern_: &Extern) -> Option<&Func> { impl InstanceWrapper { /// Create a new instance wrapper from the given wasm module. - pub fn new(module_wrapper: &ModuleWrapper, imports: &Imports, heap_pages: u32) -> Result { - let instance = Instance::new(&module_wrapper.module, &imports.externs) + pub fn new(store: &Store, module_wrapper: &ModuleWrapper, imports: &Imports, heap_pages: u32) -> Result { + let instance = Instance::new(store, &module_wrapper.module, &imports.externs) .map_err(|e| Error::from(format!("cannot instantiate: {}", e)))?; let memory = match imports.memory_import_index { @@ -141,8 +141,6 @@ impl InstanceWrapper { Ok(Self { table: get_table(&instance), instance, - globals_count: module_wrapper.globals_count, - imported_globals_count: module_wrapper.imported_globals_count, memory, _not_send_nor_sync: marker::PhantomData, }) diff --git a/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs b/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs index 602c780f720c748d5c5a1791d4d94ca1b8986079..42935d851d95c638b22d35693d7a47d5147356cc 100644 --- a/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs +++ b/client/executor/wasmtime/src/instance_wrapper/globals_snapshot.rs @@ -1,129 +1,84 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use super::InstanceWrapper; -use sc_executor_common::{ - error::{Error, Result}, -}; +use sc_executor_common::error::{Result, Error}; use sp_wasm_interface::Value; -use cranelift_codegen::ir; -use cranelift_wasm::GlobalIndex; -use wasmtime_runtime::{ExportGlobal, Export}; +use crate::imports::{into_value, into_wasmtime_val}; + +/// Saved value of particular exported global. +struct SavedValue { + /// Index of the export. + index: usize, + /// Global value. + value: Value, +} /// A snapshot of a global variables values. This snapshot can be used later for restoring the /// values to the preserved state. /// /// Technically, a snapshot stores only values of mutable global variables. This is because /// immutable global variables always have the same values. -pub struct GlobalsSnapshot { - handle: wasmtime_runtime::InstanceHandle, - preserved_mut_globals: Vec<(*mut wasmtime_runtime::VMGlobalDefinition, Value)>, -} +pub struct GlobalsSnapshot(Vec); impl GlobalsSnapshot { /// Take a snapshot of global variables for a given instance. pub fn take(instance_wrapper: &InstanceWrapper) -> Result { - // EVIL: - // Usage of an undocumented function. - let handle = unsafe { instance_wrapper.instance.handle().clone() }; - - let mut preserved_mut_globals = vec![]; - - for global_idx in instance_wrapper.imported_globals_count..instance_wrapper.globals_count { - let (def, global) = match handle.lookup_by_declaration( - &wasmtime_environ::EntityIndex::Global(GlobalIndex::from_u32(global_idx)), - ) { - Export::Global(ExportGlobal { definition, global, .. }) => (definition, global), - _ => unreachable!("only globals can be returned for a global request"), - }; - - // skip immutable globals. - if !global.mutability { - continue; - } - - let value = unsafe { - // Safety of this function solely depends on the correctness of the reference and - // the type information of the global. - read_global(def, global.ty)? - }; - preserved_mut_globals.push((def, value)); - } + let data = instance_wrapper.instance + .exports() + .enumerate() + .filter_map(|(index, export)| { + if export.name().starts_with("exported_internal_global") { + export.into_global().map( + |g| SavedValue { index, value: into_value(g.get()) } + ) + } else { None } + }) + .collect::>(); - Ok(Self { - preserved_mut_globals, - handle, - }) + Ok(Self(data)) } /// Apply the snapshot to the given instance. /// /// This instance must be the same that was used for creation of this snapshot. pub fn apply(&self, instance_wrapper: &InstanceWrapper) -> Result<()> { - if instance_wrapper.instance.handle() != &self.handle { - return Err(Error::from("unexpected instance handle".to_string())); - } - - for (def, value) in &self.preserved_mut_globals { - unsafe { - // The following writes are safe if the precondition that this is the same instance - // this snapshot was created with: - // - // 1. These pointers must be still not-NULL and allocated. - // 2. The set of global variables is fixed for the lifetime of the same instance. - // 3. We obviously assume that the wasmtime references are correct in the first place. - // 4. We write the data with the same type it was read in the first place. - write_global(*def, *value)?; + // This is a pointer over saved items, it moves forward when the loop value below takes over it's current value. + // Since both pointers (`current` and `index` below) are over ordered lists, they eventually hit all + // equal referenced values. + let mut current = 0; + for (index, export) in instance_wrapper.instance.exports().enumerate() { + if current >= self.0.len() { break; } + let current_saved = &self.0[current]; + if index < current_saved.index { continue; } + else if index > current_saved.index { current += 1; continue; } + else { + export.into_global() + .ok_or_else(|| Error::Other( + "Wrong instance in GlobalsSnapshot::apply: what should be global is not global.".to_string() + ))? + .set(into_wasmtime_val(current_saved.value)) + .map_err(|_e| Error::Other( + "Wrong instance in GlobalsSnapshot::apply: global saved type does not matched applied.".to_string() + ))?; } } - Ok(()) - } -} -unsafe fn read_global( - def: *const wasmtime_runtime::VMGlobalDefinition, - ty: ir::Type, -) -> Result { - let def = def - .as_ref() - .ok_or_else(|| Error::from("wasmtime global reference is null during read".to_string()))?; - let val = match ty { - ir::types::I32 => Value::I32(*def.as_i32()), - ir::types::I64 => Value::I64(*def.as_i64()), - ir::types::F32 => Value::F32(*def.as_u32()), - ir::types::F64 => Value::F64(*def.as_u64()), - _ => { - return Err(Error::from(format!( - "unsupported global variable type: {}", - ty - ))) - } - }; - Ok(val) -} - -unsafe fn write_global(def: *mut wasmtime_runtime::VMGlobalDefinition, value: Value) -> Result<()> { - let def = def - .as_mut() - .ok_or_else(|| Error::from("wasmtime global reference is null during write".to_string()))?; - match value { - Value::I32(v) => *def.as_i32_mut() = v, - Value::I64(v) => *def.as_i64_mut() = v, - Value::F32(v) => *def.as_u32_mut() = v, - Value::F64(v) => *def.as_u64_mut() = v, + Ok(()) } - Ok(()) } diff --git a/client/executor/wasmtime/src/runtime.rs b/client/executor/wasmtime/src/runtime.rs index a2ad3bada4ba0354849515db2f57699836604108..365770b3fa8665594c0e7bcbeef8f46cc316c242 100644 --- a/client/executor/wasmtime/src/runtime.rs +++ b/client/executor/wasmtime/src/runtime.rs @@ -39,13 +39,17 @@ pub struct WasmtimeRuntime { heap_pages: u32, allow_missing_func_imports: bool, host_functions: Vec<&'static dyn Function>, + engine: Engine, } impl WasmModule for WasmtimeRuntime { fn new_instance(&self) -> Result> { + let store = Store::new(&self.engine); + // Scan all imports, find the matching host functions, and create stubs that adapt arguments // and results. let imports = resolve_imports( + &store, self.module_wrapper.module(), &self.host_functions, self.heap_pages, @@ -53,11 +57,12 @@ impl WasmModule for WasmtimeRuntime { )?; let instance_wrapper = - InstanceWrapper::new(&self.module_wrapper, &imports, self.heap_pages)?; + InstanceWrapper::new(&store, &self.module_wrapper, &imports, self.heap_pages)?; let heap_base = instance_wrapper.extract_heap_base()?; let globals_snapshot = GlobalsSnapshot::take(&instance_wrapper)?; Ok(Box::new(WasmtimeInstance { + store, instance_wrapper: Rc::new(instance_wrapper), module_wrapper: Arc::clone(&self.module_wrapper), imports, @@ -71,6 +76,7 @@ impl WasmModule for WasmtimeRuntime { /// A `WasmInstance` implementation that reuses compiled module and spawns instances /// to execute the compiled code. pub struct WasmtimeInstance { + store: Store, module_wrapper: Arc, instance_wrapper: Rc, globals_snapshot: GlobalsSnapshot, @@ -106,7 +112,7 @@ impl WasmInstance for WasmtimeInstance { } fn get_global_const(&self, name: &str) -> Result> { - let instance = InstanceWrapper::new(&self.module_wrapper, &self.imports, self.heap_pages)?; + let instance = InstanceWrapper::new(&self.store, &self.module_wrapper, &self.imports, self.heap_pages)?; instance.get_global_val(name) } } @@ -124,9 +130,8 @@ pub fn create_runtime( config.cranelift_opt_level(wasmtime::OptLevel::SpeedAndSize); let engine = Engine::new(&config); - let store = Store::new(&engine); - let module_wrapper = ModuleWrapper::new(&store, code) + let module_wrapper = ModuleWrapper::new(&engine, code) .map_err(|e| WasmError::Other(format!("cannot create module: {}", e)))?; Ok(WasmtimeRuntime { @@ -134,6 +139,7 @@ pub fn create_runtime( heap_pages: heap_pages as u32, allow_missing_func_imports, host_functions, + engine, }) } diff --git a/client/executor/wasmtime/src/state_holder.rs b/client/executor/wasmtime/src/state_holder.rs index 42cb79e7a356807176033266dd0a4f22eacb5103..711d3bb735d7c04306525ba451f1e4be84ed9d21 100644 --- a/client/executor/wasmtime/src/state_holder.rs +++ b/client/executor/wasmtime/src/state_holder.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::host::{HostContext, HostState}; diff --git a/client/finality-grandpa/Cargo.toml b/client/finality-grandpa/Cargo.toml index 675e571c65539a23425260f54eb05fa6188d3375..b73fbbd8d1728fb672a38d03fc44a1755ae84714 100644 --- a/client/finality-grandpa/Cargo.toml +++ b/client/finality-grandpa/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-finality-grandpa" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Integration of the GRANDPA finality gadget into substrate." @@ -15,45 +15,46 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] derive_more = "0.99.2" -fork-tree = { version = "2.0.0-dev", path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0-rc6", path = "../../utils/fork-tree" } futures = "0.3.4" futures-timer = "3.0.1" log = "0.4.8" parking_lot = "0.10.0" rand = "0.7.2" -assert_matches = "1.3.0" -parity-scale-codec = { version = "1.3.0", features = ["derive"] } -sp-arithmetic = { version = "2.0.0-dev", path = "../../primitives/arithmetic" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } -sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } -sc-consensus = { version = "0.8.0-dev", path = "../../client/consensus/common" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } -sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } -sc-keystore = { version = "2.0.0-dev", path = "../keystore" } +parity-scale-codec = { version = "1.3.4", features = ["derive"] } +sp-application-crypto = { version = "2.0.0-rc6", path = "../../primitives/application-crypto" } +sp-arithmetic = { version = "2.0.0-rc6", path = "../../primitives/arithmetic" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-rc6", path = "../../primitives/utils" } +sp-consensus = { version = "0.8.0-rc6", path = "../../primitives/consensus/common" } +sc-consensus = { version = "0.8.0-rc6", path = "../../client/consensus/common" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } +sc-telemetry = { version = "2.0.0-rc6", path = "../telemetry" } +sc-keystore = { version = "2.0.0-rc6", path = "../keystore" } serde_json = "1.0.41" -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sp-inherents = { version = "2.0.0-dev", path = "../../primitives/inherents" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sc-network = { version = "0.8.0-dev", path = "../network" } -sc-network-gossip = { version = "0.8.0-dev", path = "../network-gossip" } -sp-finality-tracker = { version = "2.0.0-dev", path = "../../primitives/finality-tracker" } -sp-finality-grandpa = { version = "2.0.0-dev", path = "../../primitives/finality-grandpa" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-dev"} -sc-block-builder = { version = "0.8.0-dev", path = "../block-builder" } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sp-inherents = { version = "2.0.0-rc6", path = "../../primitives/inherents" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sc-network = { version = "0.8.0-rc6", path = "../network" } +sc-network-gossip = { version = "0.8.0-rc6", path = "../network-gossip" } +sp-finality-tracker = { version = "2.0.0-rc6", path = "../../primitives/finality-tracker" } +sp-finality-grandpa = { version = "2.0.0-rc6", path = "../../primitives/finality-grandpa" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-rc6"} +sc-block-builder = { version = "0.8.0-rc6", path = "../block-builder" } finality-grandpa = { version = "0.12.3", features = ["derive-codec"] } pin-project = "0.4.6" [dev-dependencies] +assert_matches = "1.3.0" finality-grandpa = { version = "0.12.3", features = ["derive-codec", "test-helpers"] } -sc-network = { version = "0.8.0-dev", path = "../network" } -sc-network-test = { version = "0.8.0-dev", path = "../network/test" } -sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } -sp-consensus-babe = { version = "0.8.0-dev", path = "../../primitives/consensus/babe" } -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +sc-network = { version = "0.8.0-rc6", path = "../network" } +sc-network-test = { version = "0.8.0-rc6", path = "../network/test" } +sp-keyring = { version = "2.0.0-rc6", path = "../../primitives/keyring" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client" } +sp-consensus-babe = { version = "0.8.0-rc6", path = "../../primitives/consensus/babe" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } env_logger = "0.7.0" tokio = { version = "0.2", features = ["rt-core"] } tempfile = "3.1.0" -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } diff --git a/client/finality-grandpa/README.md b/client/finality-grandpa/README.md new file mode 100644 index 0000000000000000000000000000000000000000..64a7e70bc6a52631016bba71343b38d3e0f9f005 --- /dev/null +++ b/client/finality-grandpa/README.md @@ -0,0 +1,39 @@ +Integration of the GRANDPA finality gadget into substrate. + +This crate is unstable and the API and usage may change. + +This crate provides a long-running future that produces finality notifications. + +# Usage + +First, create a block-import wrapper with the `block_import` function. The +GRANDPA worker needs to be linked together with this block import object, so +a `LinkHalf` is returned as well. All blocks imported (from network or +consensus or otherwise) must pass through this wrapper, otherwise consensus +is likely to break in unexpected ways. + +Next, use the `LinkHalf` and a local configuration to `run_grandpa_voter`. +This requires a `Network` implementation. The returned future should be +driven to completion and will finalize blocks in the background. + +# Changing authority sets + +The rough idea behind changing authority sets in GRANDPA is that at some point, +we obtain agreement for some maximum block height that the current set can +finalize, and once a block with that height is finalized the next set will +pick up finalization from there. + +Technically speaking, this would be implemented as a voting rule which says, +"if there is a signal for a change in N blocks in block B, only vote on +chains with length NUM(B) + N if they contain B". This conditional-inclusion +logic is complex to compute because it requires looking arbitrarily far +back in the chain. + +Instead, we keep track of a list of all signals we've seen so far (across +all forks), sorted ascending by the block number they would be applied at. +We never vote on chains with number higher than the earliest handoff block +number (this is num(signal) + N). When finalizing a block, we either apply +or prune any signaled changes based on whether the signaling block is +included in the newly-finalized chain. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/finality-grandpa/rpc/Cargo.toml b/client/finality-grandpa/rpc/Cargo.toml index 9435b6142b6b09728c901143602f33db04130651..28197405c8db79d6d6489c58cc1e564804d16ebe 100644 --- a/client/finality-grandpa/rpc/Cargo.toml +++ b/client/finality-grandpa/rpc/Cargo.toml @@ -1,23 +1,36 @@ [package] name = "sc-finality-grandpa-rpc" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "RPC extensions for the GRANDPA finality gadget" repository = "https://github.com/paritytech/substrate/" edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" [dependencies] -sc-finality-grandpa = { version = "0.8.0-dev", path = "../" } +sc-rpc = { version = "2.0.0-rc6", path = "../../rpc" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sc-finality-grandpa = { version = "0.8.0-rc6", path = "../" } finality-grandpa = { version = "0.12.3", features = ["derive-codec"] } -jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.3" -jsonrpc-derive = "14.0.3" +jsonrpc-core = "14.2.0" +jsonrpc-core-client = "14.2.0" +jsonrpc-derive = "14.2.1" +jsonrpc-pubsub = "14.2.0" futures = { version = "0.3.4", features = ["compat"] } serde = { version = "1.0.105", features = ["derive"] } serde_json = "1.0.50" log = "0.4.8" derive_more = "0.99.2" +parity-scale-codec = { version = "1.3.0", features = ["derive"] } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } +sc-block-builder = { version = "0.8.0-rc6", path = "../../block-builder" } +sc-network-test = { version = "0.8.0-rc6", path = "../../network/test" } +sc-rpc = { version = "2.0.0-rc6", path = "../../rpc", features = ["test-helpers"] } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-finality-grandpa = { version = "2.0.0-rc6", path = "../../../primitives/finality-grandpa" } +sp-keyring = { version = "2.0.0-rc6", path = "../../../primitives/keyring" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../test-utils/runtime/client" } +lazy_static = "1.4" diff --git a/client/finality-grandpa/rpc/README.md b/client/finality-grandpa/rpc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0007f55dbd4dbfa5fe0b10b0cb9e0714def30b1a --- /dev/null +++ b/client/finality-grandpa/rpc/README.md @@ -0,0 +1,3 @@ +RPC API for GRANDPA. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/finality-grandpa/rpc/src/error.rs b/client/finality-grandpa/rpc/src/error.rs index 2a5e6955e5e484ffd30b7d62322839324858ef21..bfd0596fdf3205d3eda8003a3a0f109b83fe836f 100644 --- a/client/finality-grandpa/rpc/src/error.rs +++ b/client/finality-grandpa/rpc/src/error.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::NOT_READY_ERROR_CODE; @@ -33,7 +35,7 @@ pub enum Error { impl From for jsonrpc_core::Error { fn from(error: Error) -> Self { jsonrpc_core::Error { - message: format!("{}", error).into(), + message: format!("{}", error), code: jsonrpc_core::ErrorCode::ServerError(NOT_READY_ERROR_CODE), data: None, } diff --git a/client/finality-grandpa/rpc/src/lib.rs b/client/finality-grandpa/rpc/src/lib.rs index e62bcf85b6818a53d2ad075fcbd8c76d499ad506..c00c95c5f776fd7c25ea66e7f1cf02002e6b1a2c 100644 --- a/client/finality-grandpa/rpc/src/lib.rs +++ b/client/finality-grandpa/rpc/src/lib.rs @@ -1,29 +1,43 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! RPC API for GRANDPA. #![warn(missing_docs)] -use futures::{FutureExt, TryFutureExt}; +use futures::{FutureExt, TryFutureExt, TryStreamExt, StreamExt}; +use log::warn; use jsonrpc_derive::rpc; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId, manager::SubscriptionManager}; +use jsonrpc_core::futures::{ + sink::Sink as Sink01, + stream::Stream as Stream01, + future::Future as Future01, +}; mod error; +mod notification; mod report; +use sc_finality_grandpa::GrandpaJustificationStream; +use sp_runtime::traits::Block as BlockT; + use report::{ReportAuthoritySet, ReportVoterState, ReportedRoundStates}; +use notification::JustificationNotification; /// Returned when Grandpa RPC endpoint is not ready. pub const NOT_READY_ERROR_CODE: i64 = 1; @@ -33,48 +47,128 @@ type FutureResult = /// Provides RPC methods for interacting with GRANDPA. #[rpc] -pub trait GrandpaApi { +pub trait GrandpaApi { + /// RPC Metadata + type Metadata; + /// Returns the state of the current best round state as well as the /// ongoing background rounds. #[rpc(name = "grandpa_roundState")] fn round_state(&self) -> FutureResult; + + /// Returns the block most recently finalized by Grandpa, alongside + /// side its justification. + #[pubsub( + subscription = "grandpa_justifications", + subscribe, + name = "grandpa_subscribeJustifications" + )] + fn subscribe_justifications( + &self, + metadata: Self::Metadata, + subscriber: Subscriber + ); + + /// Unsubscribe from receiving notifications about recently finalized blocks. + #[pubsub( + subscription = "grandpa_justifications", + unsubscribe, + name = "grandpa_unsubscribeJustifications" + )] + fn unsubscribe_justifications( + &self, + metadata: Option, + id: SubscriptionId + ) -> jsonrpc_core::Result; } /// Implements the GrandpaApi RPC trait for interacting with GRANDPA. -pub struct GrandpaRpcHandler { +pub struct GrandpaRpcHandler { authority_set: AuthoritySet, voter_state: VoterState, + justification_stream: GrandpaJustificationStream, + manager: SubscriptionManager, } -impl GrandpaRpcHandler { - /// Creates a new GrandpaRpcHander instance. - pub fn new(authority_set: AuthoritySet, voter_state: VoterState) -> Self { +impl GrandpaRpcHandler { + /// Creates a new GrandpaRpcHandler instance. + pub fn new( + authority_set: AuthoritySet, + voter_state: VoterState, + justification_stream: GrandpaJustificationStream, + manager: SubscriptionManager, + ) -> Self { Self { authority_set, voter_state, + justification_stream, + manager, } } } -impl GrandpaApi for GrandpaRpcHandler +impl GrandpaApi + for GrandpaRpcHandler where VoterState: ReportVoterState + Send + Sync + 'static, AuthoritySet: ReportAuthoritySet + Send + Sync + 'static, + Block: BlockT, { + type Metadata = sc_rpc::Metadata; + fn round_state(&self) -> FutureResult { let round_states = ReportedRoundStates::from(&self.authority_set, &self.voter_state); let future = async move { round_states }.boxed(); Box::new(future.map_err(jsonrpc_core::Error::from).compat()) } + + fn subscribe_justifications( + &self, + _metadata: Self::Metadata, + subscriber: Subscriber + ) { + let stream = self.justification_stream.subscribe() + .map(|x| Ok::<_,()>(JustificationNotification::from(x))) + .map_err(|e| warn!("Notification stream error: {:?}", e)) + .compat(); + + self.manager.add(subscriber, |sink| { + let stream = stream.map(|res| Ok(res)); + sink.sink_map_err(|e| warn!("Error sending notifications: {:?}", e)) + .send_all(stream) + .map(|_| ()) + }); + } + + fn unsubscribe_justifications( + &self, + _metadata: Option, + id: SubscriptionId + ) -> jsonrpc_core::Result { + Ok(self.manager.cancel(id)) + } } #[cfg(test)] mod tests { use super::*; - use jsonrpc_core::IoHandler; - use sc_finality_grandpa::{report, AuthorityId}; + use std::{collections::HashSet, convert::TryInto, sync::Arc}; + use jsonrpc_core::{Notification, Output, types::Params}; + + use parity_scale_codec::Decode; + use sc_block_builder::BlockBuilder; + use sc_finality_grandpa::{report, AuthorityId, GrandpaJustificationSender, GrandpaJustification}; + use sp_blockchain::HeaderBackend; + use sp_consensus::RecordProof; use sp_core::crypto::Public; - use std::{collections::HashSet, convert::TryInto}; + use sp_keyring::Ed25519Keyring; + use sp_runtime::traits::Header as HeaderT; + use substrate_test_runtime_client::{ + runtime::Block, + DefaultTestClientBuilderExt, + TestClientBuilderExt, + TestClientBuilder, + }; struct TestAuthoritySet; struct TestVoterState; @@ -104,7 +198,7 @@ mod tests { let voter_id_1 = AuthorityId::from_slice(&[1; 32]); let voters_best: HashSet<_> = vec![voter_id_1].into_iter().collect(); - let best_round_state = report::RoundState { + let best_round_state = sc_finality_grandpa::report::RoundState { total_weight: 100_u64.try_into().unwrap(), threshold_weight: 67_u64.try_into().unwrap(), prevote_current_weight: 50.into(), @@ -113,7 +207,7 @@ mod tests { precommit_ids: HashSet::new(), }; - let past_round_state = report::RoundState { + let past_round_state = sc_finality_grandpa::report::RoundState { total_weight: 100_u64.try_into().unwrap(), threshold_weight: 67_u64.try_into().unwrap(), prevote_current_weight: 100.into(), @@ -131,23 +225,42 @@ mod tests { } } + fn setup_io_handler(voter_state: VoterState) -> ( + jsonrpc_core::MetaIoHandler, + GrandpaJustificationSender, + ) where + VoterState: ReportVoterState + Send + Sync + 'static, + { + let (justification_sender, justification_stream) = GrandpaJustificationStream::channel(); + let manager = SubscriptionManager::new(Arc::new(sc_rpc::testing::TaskExecutor)); + + let handler = GrandpaRpcHandler::new( + TestAuthoritySet, + voter_state, + justification_stream, + manager, + ); + + let mut io = jsonrpc_core::MetaIoHandler::default(); + io.extend_with(GrandpaApi::to_delegate(handler)); + + (io, justification_sender) + } + #[test] fn uninitialized_rpc_handler() { - let handler = GrandpaRpcHandler::new(TestAuthoritySet, EmptyVoterState); - let mut io = IoHandler::new(); - io.extend_with(GrandpaApi::to_delegate(handler)); + let (io, _) = setup_io_handler(EmptyVoterState); let request = r#"{"jsonrpc":"2.0","method":"grandpa_roundState","params":[],"id":1}"#; let response = r#"{"jsonrpc":"2.0","error":{"code":1,"message":"GRANDPA RPC endpoint not ready"},"id":1}"#; - assert_eq!(Some(response.into()), io.handle_request_sync(request)); + let meta = sc_rpc::Metadata::default(); + assert_eq!(Some(response.into()), io.handle_request_sync(request, meta)); } #[test] fn working_rpc_handler() { - let handler = GrandpaRpcHandler::new(TestAuthoritySet, TestVoterState); - let mut io = IoHandler::new(); - io.extend_with(GrandpaApi::to_delegate(handler)); + let (io, _) = setup_io_handler(TestVoterState); let request = r#"{"jsonrpc":"2.0","method":"grandpa_roundState","params":[],"id":1}"#; let response = "{\"jsonrpc\":\"2.0\",\"result\":{\ @@ -164,6 +277,154 @@ mod tests { \"setId\":1\ },\"id\":1}"; - assert_eq!(io.handle_request_sync(request), Some(response.into())); + let meta = sc_rpc::Metadata::default(); + assert_eq!(io.handle_request_sync(request, meta), Some(response.into())); + } + + fn setup_session() -> (sc_rpc::Metadata, jsonrpc_core::futures::sync::mpsc::Receiver) { + let (tx, rx) = jsonrpc_core::futures::sync::mpsc::channel(1); + let meta = sc_rpc::Metadata::new(tx); + (meta, rx) + } + + #[test] + fn subscribe_and_unsubscribe_to_justifications() { + let (io, _) = setup_io_handler(TestVoterState); + let (meta, _) = setup_session(); + + // Subscribe + let sub_request = r#"{"jsonrpc":"2.0","method":"grandpa_subscribeJustifications","params":[],"id":1}"#; + let resp = io.handle_request_sync(sub_request, meta.clone()); + let resp: Output = serde_json::from_str(&resp.unwrap()).unwrap(); + + let sub_id = match resp { + Output::Success(success) => success.result, + _ => panic!(), + }; + + // Unsubscribe + let unsub_req = format!( + "{{\"jsonrpc\":\"2.0\",\"method\":\"grandpa_unsubscribeJustifications\",\"params\":[{}],\"id\":1}}", + sub_id + ); + assert_eq!( + io.handle_request_sync(&unsub_req, meta.clone()), + Some(r#"{"jsonrpc":"2.0","result":true,"id":1}"#.into()), + ); + + // Unsubscribe again and fail + assert_eq!( + io.handle_request_sync(&unsub_req, meta), + Some(r#"{"jsonrpc":"2.0","result":false,"id":1}"#.into()), + ); + } + + #[test] + fn subscribe_and_unsubscribe_with_wrong_id() { + let (io, _) = setup_io_handler(TestVoterState); + let (meta, _) = setup_session(); + + // Subscribe + let sub_request = r#"{"jsonrpc":"2.0","method":"grandpa_subscribeJustifications","params":[],"id":1}"#; + let resp = io.handle_request_sync(sub_request, meta.clone()); + let resp: Output = serde_json::from_str(&resp.unwrap()).unwrap(); + assert!(matches!(resp, Output::Success(_))); + + // Unsubscribe with wrong ID + assert_eq!( + io.handle_request_sync( + r#"{"jsonrpc":"2.0","method":"grandpa_unsubscribeJustifications","params":["FOO"],"id":1}"#, + meta.clone() + ), + Some(r#"{"jsonrpc":"2.0","result":false,"id":1}"#.into()) + ); + } + + fn create_justification() -> GrandpaJustification { + let peers = &[Ed25519Keyring::Alice]; + + let builder = TestClientBuilder::new(); + let backend = builder.backend(); + let client = builder.build(); + let client = Arc::new(client); + + let built_block = BlockBuilder::new( + &*client, + client.info().best_hash, + client.info().best_number, + RecordProof::Yes, + Default::default(), + &*backend, + ).unwrap().build().unwrap(); + + let block = built_block.block; + let block_hash = block.hash(); + + let justification = { + let round = 1; + let set_id = 0; + + let precommit = finality_grandpa::Precommit { + target_hash: block_hash, + target_number: *block.header.number(), + }; + + let msg = finality_grandpa::Message::Precommit(precommit.clone()); + let encoded = sp_finality_grandpa::localized_payload(round, set_id, &msg); + let signature = peers[0].sign(&encoded[..]).into(); + + let precommit = finality_grandpa::SignedPrecommit { + precommit, + signature, + id: peers[0].public().into(), + }; + + let commit = finality_grandpa::Commit { + target_hash: block_hash, + target_number: *block.header.number(), + precommits: vec![precommit], + }; + + GrandpaJustification::from_commit(&client, round, commit).unwrap() + }; + + justification + } + + #[test] + fn subscribe_and_listen_to_one_justification() { + let (io, justification_sender) = setup_io_handler(TestVoterState); + let (meta, receiver) = setup_session(); + + // Subscribe + let sub_request = + r#"{"jsonrpc":"2.0","method":"grandpa_subscribeJustifications","params":[],"id":1}"#; + + let resp = io.handle_request_sync(sub_request, meta.clone()); + let mut resp: serde_json::Value = serde_json::from_str(&resp.unwrap()).unwrap(); + let sub_id: String = serde_json::from_value(resp["result"].take()).unwrap(); + + // Notify with a header and justification + let justification = create_justification(); + let _ = justification_sender.notify(justification.clone()).unwrap(); + + // Inspect what we received + let recv = receiver.take(1).wait().flatten().collect::>(); + let recv: Notification = serde_json::from_str(&recv[0]).unwrap(); + let mut json_map = match recv.params { + Params::Map(json_map) => json_map, + _ => panic!(), + }; + + let recv_sub_id: String = + serde_json::from_value(json_map["subscription"].take()).unwrap(); + let recv_justification: Vec = + serde_json::from_value(json_map["result"].take()).unwrap(); + let recv_justification: GrandpaJustification = + Decode::decode(&mut &recv_justification[..]).unwrap(); + + assert_eq!(recv.method, "grandpa_justifications"); + assert_eq!(recv_sub_id, sub_id); + assert_eq!(recv_justification, justification); } } diff --git a/client/finality-grandpa/rpc/src/notification.rs b/client/finality-grandpa/rpc/src/notification.rs new file mode 100644 index 0000000000000000000000000000000000000000..831f4681549a7d0d6c50b52063d5d3c69bd5accc --- /dev/null +++ b/client/finality-grandpa/rpc/src/notification.rs @@ -0,0 +1,32 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use serde::{Serialize, Deserialize}; +use parity_scale_codec::Encode; +use sp_runtime::traits::Block as BlockT; +use sc_finality_grandpa::GrandpaJustification; + +/// An encoded justification proving that the given header has been finalized +#[derive(Clone, Serialize, Deserialize)] +pub struct JustificationNotification(Vec); + +impl From> for JustificationNotification { + fn from(notification: GrandpaJustification) -> Self { + JustificationNotification(notification.encode()) + } +} diff --git a/client/finality-grandpa/rpc/src/report.rs b/client/finality-grandpa/rpc/src/report.rs index 029fd4b46df14a33d152db467052ae4ae05f73d7..a635728cb938adf73d4ae94e1db1a63d5fcb9f50 100644 --- a/client/finality-grandpa/rpc/src/report.rs +++ b/client/finality-grandpa/rpc/src/report.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{ collections::{BTreeSet, HashSet}, diff --git a/client/finality-grandpa/src/authorities.rs b/client/finality-grandpa/src/authorities.rs index 80c1f4ad3fe3804225b3a7fbe1d318dd6e13ec31..7a064d7a6224bf30a28c156a1f5f405907848abf 100644 --- a/client/finality-grandpa/src/authorities.rs +++ b/client/finality-grandpa/src/authorities.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Utilities for dealing with authorities, authority sets, and handoffs. @@ -229,8 +231,8 @@ where (&number, &hash), pending.delay); self.pending_standard_changes.import( - hash.clone(), - number.clone(), + hash, + number, pending, is_descendent_of, )?; @@ -354,8 +356,9 @@ where .take_while(|c| c.effective_number() <= best_number) // to prevent iterating too far .filter(|c| c.effective_number() == best_number) { - // check if the given best block is in the same branch as the block that signaled the change. - if is_descendent_of(&change.canon_hash, &best_hash)? { + // check if the given best block is in the same branch as + // the block that signaled the change. + if change.canon_hash == best_hash || is_descendent_of(&change.canon_hash, &best_hash)? { // apply this change: make the set canonical afg_log!(initial_sync, "👴 Applying authority set change forced at block #{:?}", @@ -421,9 +424,21 @@ where fork_tree::FinalizationResult::Changed(change) => { status.changed = true; - // if we are able to finalize any standard change then we can - // discard all pending forced changes (on different forks) - self.pending_forced_changes.clear(); + let pending_forced_changes = std::mem::replace( + &mut self.pending_forced_changes, + Vec::new(), + ); + + // we will keep all forced change for any later blocks and that are a + // descendent of the finalized block (i.e. they are from this fork). + for change in pending_forced_changes { + if change.effective_number() > finalized_number && + is_descendent_of(&finalized_hash, &change.canon_hash) + .map_err(fork_tree::Error::Client)? + { + self.pending_forced_changes.push(change) + } + } if let Some(change) = change { afg_log!(initial_sync, @@ -970,6 +985,43 @@ mod tests { ); } + #[test] + fn forced_changes_with_no_delay() { + // NOTE: this is a regression test + let mut authorities = AuthoritySet { + current_authorities: Vec::new(), + set_id: 0, + pending_standard_changes: ForkTree::new(), + pending_forced_changes: Vec::new(), + }; + + let set_a = vec![(AuthorityId::from_slice(&[1; 32]), 5)]; + + // we create a forced change with no delay + let change_a = PendingChange { + next_authorities: set_a.clone(), + delay: 0, + canon_height: 5, + canon_hash: "hash_a", + delay_kind: DelayKind::Best { + median_last_finalized: 0, + }, + }; + + // and import it + authorities + .add_pending_change(change_a, &static_is_descendent_of(false)) + .unwrap(); + + // it should be enacted at the same block that signaled it + assert!( + authorities + .apply_forced_changes("hash_a", 5, &static_is_descendent_of(false), false) + .unwrap() + .is_some() + ); + } + #[test] fn next_change_works() { let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]), 1)]; @@ -1161,4 +1213,124 @@ mod tests { Err(Error::InvalidAuthoritySet) )); } + + #[test] + fn cleans_up_stale_forced_changes_when_applying_standard_change() { + let current_authorities = vec![(AuthorityId::from_slice(&[1; 32]), 1)]; + + let mut authorities = AuthoritySet { + current_authorities: current_authorities.clone(), + set_id: 0, + pending_standard_changes: ForkTree::new(), + pending_forced_changes: Vec::new(), + }; + + let new_set = current_authorities.clone(); + + // Create the following pending changes tree: + // + // [#C3] + // / + // /- (#C2) + // / + // (#A) - (#B) - [#C1] + // \ + // (#C0) - [#D] + // + // () - Standard change + // [] - Forced change + + let is_descendent_of = { + let hashes = vec!["B", "C0", "C1", "C2", "C3", "D"]; + is_descendent_of(move |base, hash| match (*base, *hash) { + ("B", "B") => false, // required to have the simpler case below + ("A", b) | ("B", b) => hashes.iter().any(|h| *h == b), + ("C0", "D") => true, + _ => false, + }) + }; + + let mut add_pending_change = |canon_height, canon_hash, forced| { + let change = PendingChange { + next_authorities: new_set.clone(), + delay: 0, + canon_height, + canon_hash, + delay_kind: if forced { + DelayKind::Best { + median_last_finalized: 0, + } + } else { + DelayKind::Finalized + }, + }; + + authorities + .add_pending_change(change, &is_descendent_of) + .unwrap(); + }; + + add_pending_change(5, "A", false); + add_pending_change(10, "B", false); + add_pending_change(15, "C0", false); + add_pending_change(15, "C1", true); + add_pending_change(15, "C2", false); + add_pending_change(15, "C3", true); + add_pending_change(20, "D", true); + + println!( + "pending_changes: {:?}", + authorities + .pending_changes() + .map(|c| c.canon_hash) + .collect::>() + ); + + // applying the standard change at A should not prune anything + // other then the change that was applied + authorities + .apply_standard_changes("A", 5, &is_descendent_of, false) + .unwrap(); + println!( + "pending_changes: {:?}", + authorities + .pending_changes() + .map(|c| c.canon_hash) + .collect::>() + ); + + assert_eq!(authorities.pending_changes().count(), 6); + + // same for B + authorities + .apply_standard_changes("B", 10, &is_descendent_of, false) + .unwrap(); + + assert_eq!(authorities.pending_changes().count(), 5); + + let authorities2 = authorities.clone(); + + // finalizing C2 should clear all forced changes + authorities + .apply_standard_changes("C2", 15, &is_descendent_of, false) + .unwrap(); + + assert_eq!(authorities.pending_forced_changes.len(), 0); + + // finalizing C0 should clear all forced changes but D + let mut authorities = authorities2; + authorities + .apply_standard_changes("C0", 15, &is_descendent_of, false) + .unwrap(); + + assert_eq!(authorities.pending_forced_changes.len(), 1); + assert_eq!( + authorities + .pending_forced_changes + .first() + .unwrap() + .canon_hash, + "D" + ); + } } diff --git a/client/finality-grandpa/src/aux_schema.rs b/client/finality-grandpa/src/aux_schema.rs index e4e8a980420d86cd39e9f07ffbd90efe07acba23..4ed96d058ac6b42941705c046984852fdea0b795 100644 --- a/client/finality-grandpa/src/aux_schema.rs +++ b/client/finality-grandpa/src/aux_schema.rs @@ -328,7 +328,7 @@ pub(crate) fn load_persistent( } Some(other) => return Err(ClientError::Backend( format!("Unsupported GRANDPA DB version: {:?}", other) - ).into()), + )), } // genesis. @@ -336,7 +336,7 @@ pub(crate) fn load_persistent( from genesis on what appears to be first startup."); let genesis_authorities = genesis_authorities()?; - let genesis_set = AuthoritySet::genesis(genesis_authorities.clone()) + let genesis_set = AuthoritySet::genesis(genesis_authorities) .expect("genesis authorities is non-empty; all weights are non-zero; qed."); let state = make_genesis_round(); let base = state.prevote_ghost diff --git a/client/finality-grandpa/src/communication/gossip.rs b/client/finality-grandpa/src/communication/gossip.rs index 183ffc65e8378b7751e66a7d7594db9c1ae1aeb6..276529d555ffe062a12e79b8544cc3265272467e 100644 --- a/client/finality-grandpa/src/communication/gossip.rs +++ b/client/finality-grandpa/src/communication/gossip.rs @@ -110,7 +110,7 @@ const CATCH_UP_THRESHOLD: u64 = 2; const PROPAGATION_ALL: u32 = 4; //in rounds; const PROPAGATION_ALL_AUTHORITIES: u32 = 2; //in rounds; const PROPAGATION_SOME_NON_AUTHORITIES: u32 = 3; //in rounds; -const ROUND_DURATION: u32 = 4; // measured in gossip durations +const ROUND_DURATION: u32 = 2; // measured in gossip durations const MIN_LUCKY: usize = 5; @@ -181,15 +181,27 @@ impl View { } } -/// A local view of protocol state. Only differs from `View` in that we also -/// track the round and set id at which the last commit was observed. +/// A local view of protocol state. Similar to `View` but we additionally track +/// the round and set id at which the last commit was observed, and the instant +/// at which the current round started. struct LocalView { round: Round, set_id: SetId, last_commit: Option<(N, Round, SetId)>, + round_start: Instant, } impl LocalView { + /// Creates a new `LocalView` at the given set id and round. + fn new(set_id: SetId, round: Round) -> LocalView { + LocalView { + set_id, + round, + last_commit: None, + round_start: Instant::now(), + } + } + /// Converts the local view to a `View` discarding round and set id /// information about the last commit. fn as_view(&self) -> View<&N> { @@ -205,9 +217,16 @@ impl LocalView { if set_id != self.set_id { self.set_id = set_id; self.round = Round(1); + self.round_start = Instant::now(); } } + /// Updates the current round. + fn update_round(&mut self, round: Round) { + self.round = round; + self.round_start = Instant::now(); + } + /// Returns the height of the block that the last observed commit finalizes. fn last_commit_height(&self) -> Option<&N> { self.last_commit.as_ref().map(|(number, _, _)| number) @@ -656,7 +675,6 @@ struct Inner { local_view: Option>>, peers: Peers>, live_topics: KeepTopics, - round_start: Instant, authorities: Vec, config: crate::Config, next_rebroadcast: Instant, @@ -689,7 +707,6 @@ impl Inner { local_view: None, peers: Peers::default(), live_topics: KeepTopics::new(), - round_start: Instant::now(), next_rebroadcast: Instant::now() + REBROADCAST_AFTER, authorities: Vec::new(), pending_catch_up: PendingCatchUp::None, @@ -715,10 +732,9 @@ impl Inner { debug!(target: "afg", "Voter {} noting beginning of round {:?} to network.", self.config.name(), (round, set_id)); - local_view.round = round; + local_view.update_round(round); self.live_topics.push(round, set_id); - self.round_start = Instant::now(); self.peers.reshuffle(); } self.multicast_neighbor_packet() @@ -729,13 +745,16 @@ impl Inner { fn note_set(&mut self, set_id: SetId, authorities: Vec) -> MaybeMessage { { let local_view = match self.local_view { - ref mut x @ None => x.get_or_insert(LocalView { - round: Round(1), + ref mut x @ None => x.get_or_insert(LocalView::new( set_id, - last_commit: None, - }), + Round(1), + )), Some(ref mut v) => if v.set_id == set_id { - if self.authorities != authorities { + let diff_authorities = + self.authorities.iter().collect::>() != + authorities.iter().collect(); + + if diff_authorities { debug!(target: "afg", "Gossip validator noted set {:?} twice with different authorities. \ Was the authority set hard forked?", @@ -814,7 +833,7 @@ impl Inner { return Action::Discard(cost::UNKNOWN_VOTER); } - if let Err(()) = sp_finality_grandpa::check_message_signature( + if !sp_finality_grandpa::check_message_signature( &full.message.message, &full.message.id, &full.message.signature, @@ -887,7 +906,7 @@ impl Inner { // any catch up requests until we import this one (either with a // success or failure). self.pending_catch_up = PendingCatchUp::Processing { - instant: instant.clone(), + instant: *instant, }; // always discard catch up messages, they're point-to-point @@ -903,7 +922,7 @@ impl Inner { PendingCatchUp::Processing { .. } => { self.pending_catch_up = PendingCatchUp::None; }, - state => trace!(target: "afg", + state => debug!(target: "afg", "Noted processed catch up message when state was: {:?}", state, ), @@ -1024,7 +1043,7 @@ impl Inner { let (catch_up_allowed, catch_up_report) = self.note_catch_up_request(who, &request); if catch_up_allowed { - trace!(target: "afg", "Sending catch-up request for round {} to {}", + debug!(target: "afg", "Sending catch-up request for round {} to {}", round, who, ); @@ -1121,8 +1140,10 @@ impl Inner { /// underlying gossip layer, which should happen every 30 seconds. fn round_message_allowed(&self, who: &PeerId, peer: &PeerInfo) -> bool { let round_duration = self.config.gossip_duration * ROUND_DURATION; - let round_elapsed = self.round_start.elapsed(); - + let round_elapsed = match self.local_view { + Some(ref local_view) => local_view.round_start.elapsed(), + None => return false, + }; if !self.config.is_authority && round_elapsed < round_duration * PROPAGATION_ALL @@ -1185,7 +1206,10 @@ impl Inner { /// underlying gossip layer, which should happen every 30 seconds. fn global_message_allowed(&self, who: &PeerId, peer: &PeerInfo) -> bool { let round_duration = self.config.gossip_duration * ROUND_DURATION; - let round_elapsed = self.round_start.elapsed(); + let round_elapsed = match self.local_view { + Some(ref local_view) => local_view.round_start.elapsed(), + None => return false, + }; match peer.roles { ObservedRole::OurSentry | ObservedRole::OurGuardedAuthority => true, @@ -1281,7 +1305,7 @@ impl GossipValidator { inner: parking_lot::RwLock::new(Inner::new(config)), set_state, report_sender: tx, - metrics: metrics, + metrics, }; (val, rx) @@ -2320,7 +2344,8 @@ mod tests { let test = |num_round, peers| { // rewind n round durations - val.inner.write().round_start = Instant::now() - round_duration * num_round; + val.inner.write().local_view.as_mut().unwrap().round_start = + Instant::now() - round_duration * num_round; let mut message_allowed = val.message_allowed(); move || { @@ -2448,7 +2473,8 @@ mod tests { } { - val.inner.write().round_start = Instant::now() - round_duration * 4; + val.inner.write().local_view.as_mut().unwrap().round_start = + Instant::now() - round_duration * 4; let mut message_allowed = val.message_allowed(); // on the fourth round duration we should allow messages to authorities // (on the second we would do `sqrt(authorities)`) @@ -2598,12 +2624,12 @@ mod tests { fn allow_noting_different_authorities_for_same_set() { let (val, _) = GossipValidator::::new(config(), voter_set_state(), None); - let a1 = vec![AuthorityId::default()]; + let a1 = vec![AuthorityId::from_slice(&[0; 32])]; val.note_set(SetId(1), a1.clone(), |_, _| {}); assert_eq!(val.inner().read().authorities, a1); - let a2 = vec![AuthorityId::default(), AuthorityId::default()]; + let a2 = vec![AuthorityId::from_slice(&[1; 32]), AuthorityId::from_slice(&[2; 32])]; val.note_set(SetId(1), a2.clone(), |_, _| {}); assert_eq!(val.inner().read().authorities, a2); diff --git a/client/finality-grandpa/src/communication/mod.rs b/client/finality-grandpa/src/communication/mod.rs index 16af54986a02a082339251b08739aca1eea8f5a7..a8bfb84416b8f453bfd19ae12fe693929bb5c71e 100644 --- a/client/finality-grandpa/src/communication/mod.rs +++ b/client/finality-grandpa/src/communication/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Communication streams for the polite-grandpa networking protocol. //! @@ -33,12 +35,12 @@ use parking_lot::Mutex; use prometheus_endpoint::Registry; use std::{pin::Pin, sync::Arc, task::{Context, Poll}}; +use sp_core::traits::BareCryptoStorePtr; use finality_grandpa::Message::{Prevote, Precommit, PrimaryPropose}; use finality_grandpa::{voter, voter_set::VoterSet}; use sc_network::{NetworkService, ReputationChange}; use sc_network_gossip::{GossipEngine, Network as GossipNetwork}; use parity_scale_codec::{Encode, Decode}; -use sp_core::Pair; use sp_runtime::traits::{Block as BlockT, Hash as HashT, Header as HeaderT, NumberFor}; use sc_telemetry::{telemetry, CONSENSUS_DEBUG, CONSENSUS_INFO}; @@ -56,7 +58,7 @@ use gossip::{ VoteMessage, }; use sp_finality_grandpa::{ - AuthorityPair, AuthorityId, AuthoritySignature, SetId as SetIdNumber, RoundNumber, + AuthorityId, AuthoritySignature, SetId as SetIdNumber, RoundNumber, }; use sp_utils::mpsc::TracingUnboundedReceiver; @@ -103,6 +105,34 @@ mod benefit { pub(super) const PER_EQUIVOCATION: i32 = 10; } +/// A type that ties together our local authority id and a keystore where it is +/// available for signing. +pub struct LocalIdKeystore((AuthorityId, BareCryptoStorePtr)); + +impl LocalIdKeystore { + /// Returns a reference to our local authority id. + fn local_id(&self) -> &AuthorityId { + &(self.0).0 + } + + /// Returns a reference to the keystore. + fn keystore(&self) -> &BareCryptoStorePtr { + &(self.0).1 + } +} + +impl AsRef for LocalIdKeystore { + fn as_ref(&self) -> &BareCryptoStorePtr { + self.keystore() + } +} + +impl From<(AuthorityId, BareCryptoStorePtr)> for LocalIdKeystore { + fn from(inner: (AuthorityId, BareCryptoStorePtr)) -> LocalIdKeystore { + LocalIdKeystore(inner) + } +} + /// If the voter set is larger than this value some telemetry events are not /// sent to avoid increasing usage resource on the node and flooding the /// telemetry server (e.g. received votes, received commits.) @@ -236,16 +266,14 @@ impl> NetworkBridge { let (neighbor_packet_worker, neighbor_packet_sender) = periodic::NeighborPacketWorker::new(); - let bridge = NetworkBridge { + NetworkBridge { service, gossip_engine, validator, neighbor_sender: neighbor_packet_sender, neighbor_packet_worker: Arc::new(Mutex::new(neighbor_packet_worker)), gossip_validator_report_stream: Arc::new(Mutex::new(report_stream)), - }; - - bridge + } } /// Note the beginning of a new round to the `GossipValidator`. @@ -272,10 +300,10 @@ impl> NetworkBridge { /// network all within the current set. pub(crate) fn round_communication( &self, + keystore: Option, round: Round, set_id: SetId, voters: Arc>, - local_key: Option, has_voted: HasVoted, ) -> ( impl Stream> + Unpin, @@ -287,10 +315,10 @@ impl> NetworkBridge { &*voters, ); - let locals = local_key.and_then(|pair| { - let id = pair.public(); - if voters.contains(&id) { - Some((pair, id)) + let keystore = keystore.and_then(|ks| { + let id = ks.local_id(); + if voters.contains(id) { + Some(ks) } else { None } @@ -304,7 +332,7 @@ impl> NetworkBridge { match decoded { Err(ref e) => { debug!(target: "afg", "Skipping malformed message {:?}: {}", notification, e); - return future::ready(None); + future::ready(None) } Ok(GossipMessage::Vote(msg)) => { // check signature. @@ -343,17 +371,17 @@ impl> NetworkBridge { } _ => { debug!(target: "afg", "Skipping unknown message type"); - return future::ready(None); + future::ready(None) } } }); let (tx, out_rx) = mpsc::channel(0); let outgoing = OutgoingMessages:: { + keystore, round: round.0, set_id: set_id.0, network: self.gossip_engine.clone(), - locals, sender: tx, has_voted, }; @@ -628,7 +656,7 @@ pub struct SetId(pub SetIdNumber); pub(crate) struct OutgoingMessages { round: RoundNumber, set_id: SetIdNumber, - locals: Option<(AuthorityPair, AuthorityId)>, + keystore: Option, sender: mpsc::Sender>, network: Arc>>, has_voted: HasVoted, @@ -665,14 +693,19 @@ impl Sink> for OutgoingMessages } // when locals exist, sign messages on import - if let Some((ref pair, _)) = self.locals { - let target_hash = msg.target().0.clone(); + if let Some(ref keystore) = self.keystore { + let target_hash = *(msg.target().0); let signed = sp_finality_grandpa::sign_message( + keystore.as_ref(), msg, - pair, + keystore.local_id().clone(), self.round, self.set_id, - ); + ).ok_or_else( + || Error::Signing(format!( + "Failed to sign GRANDPA vote for round {} targetting {:?}", self.round, target_hash + )) + )?; let message = GossipMessage::Vote(VoteMessage:: { message: signed.clone(), @@ -760,7 +793,7 @@ fn check_compact_commit( use crate::communication::gossip::Misbehavior; use finality_grandpa::Message as GrandpaMessage; - if let Err(()) = sp_finality_grandpa::check_message_signature_with_buffer( + if !sp_finality_grandpa::check_message_signature_with_buffer( &GrandpaMessage::Precommit(precommit.clone()), id, sig, @@ -848,7 +881,7 @@ fn check_catch_up( for (msg, id, sig) in messages { signatures_checked += 1; - if let Err(()) = sp_finality_grandpa::check_message_signature_with_buffer( + if !sp_finality_grandpa::check_message_signature_with_buffer( &msg, id, sig, diff --git a/client/finality-grandpa/src/communication/periodic.rs b/client/finality-grandpa/src/communication/periodic.rs index f894624bdf79e6e000f7a113c804517633301cb9..dadd7deb57fca1d34dd01baf0d434533f1a99fbe 100644 --- a/client/finality-grandpa/src/communication/periodic.rs +++ b/client/finality-grandpa/src/communication/periodic.rs @@ -86,7 +86,7 @@ impl Stream for NeighborPacketWorker { this.delay.reset(REBROADCAST_AFTER); this.last = Some((to.clone(), packet.clone())); - return Poll::Ready(Some((to, GossipMessage::::from(packet.clone())))); + return Poll::Ready(Some((to, GossipMessage::::from(packet)))); } // Don't return yet, maybe the timer fired. Poll::Pending => {}, @@ -108,6 +108,6 @@ impl Stream for NeighborPacketWorker { return Poll::Ready(Some((to.clone(), GossipMessage::::from(packet.clone())))); } - return Poll::Pending; + Poll::Pending } } diff --git a/client/finality-grandpa/src/environment.rs b/client/finality-grandpa/src/environment.rs index 1db1bcbb8d4a5826e032cfdc8a262c5dc42849be..a7a29fe0e8a65ec2f7a4014193ebb5ed0d789c64 100644 --- a/client/finality-grandpa/src/environment.rs +++ b/client/finality-grandpa/src/environment.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::collections::BTreeMap; use std::iter::FromIterator; @@ -33,7 +35,6 @@ use finality_grandpa::{ voter, voter_set::VoterSet, }; use sp_blockchain::{HeaderBackend, HeaderMetadata, Error as ClientError}; -use sp_core::Pair; use sp_runtime::generic::BlockId; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, NumberFor, One, Zero, @@ -50,6 +51,7 @@ use sp_consensus::SelectChain; use crate::authorities::{AuthoritySet, SharedAuthoritySet}; use crate::communication::Network as NetworkT; use crate::consensus_changes::SharedConsensusChanges; +use crate::notification::GrandpaJustificationSender; use crate::justification::GrandpaJustification; use crate::until_imported::UntilVoteTargetImported; use crate::voting_rule::VotingRule; @@ -108,7 +110,7 @@ impl Decode for CompletedRounds { fn decode(value: &mut I) -> Result { <(Vec>, SetId, Vec)>::decode(value) .map(|(rounds, set_id, voters)| CompletedRounds { - rounds: rounds.into(), + rounds, set_id, voters, }) @@ -248,14 +250,14 @@ impl VoterSetState { { if let VoterSetState::Live { completed_rounds, current_rounds } = self { if current_rounds.contains_key(&round) { - return Ok((completed_rounds, current_rounds)); + Ok((completed_rounds, current_rounds)) } else { let msg = "Voter acting on a live round we are not tracking."; - return Err(Error::Safety(msg.to_string())); + Err(Error::Safety(msg.to_string())) } } else { let msg = "Voter acting while in paused state."; - return Err(Error::Safety(msg.to_string())); + Err(Error::Safety(msg.to_string())) } } } @@ -389,7 +391,6 @@ impl Metrics { } } - /// The environment we run GRANDPA in. pub(crate) struct Environment, SC, VR> { pub(crate) client: Arc, @@ -403,6 +404,7 @@ pub(crate) struct Environment, SC, pub(crate) voter_set_state: SharedVoterSetState, pub(crate) voting_rule: VR, pub(crate) metrics: Option, + pub(crate) justification_sender: Option>, pub(crate) _phantom: PhantomData, } @@ -514,12 +516,14 @@ where equivocation, ); - self.client.runtime_api() - .submit_report_equivocation_extrinsic( + self.client + .runtime_api() + .submit_report_equivocation_unsigned_extrinsic( &BlockId::Hash(best_header.hash()), equivocation_proof, key_owner_proof, - ).map_err(Error::Client)?; + ) + .map_err(Error::Client)?; Ok(()) } @@ -622,7 +626,7 @@ where restricted_number >= base_header.number() && restricted_number < target_header.number() }) - .or(Some((target_header.hash(), *target_header.number()))) + .or_else(|| Some((target_header.hash(), *target_header.number()))) }, Ok(None) => { debug!(target: "afg", "Encountered error finding best chain containing {:?}: couldn't find target block", block); @@ -702,11 +706,11 @@ where let prevote_timer = Delay::new(self.config.gossip_duration * 2); let precommit_timer = Delay::new(self.config.gossip_duration * 4); - let local_key = crate::is_voter(&self.voters, &self.config.keystore); + let local_key = crate::is_voter(&self.voters, self.config.keystore.as_ref()); let has_voted = match self.voter_set_state.has_voted(round) { HasVoted::Yes(id, vote) => { - if local_key.as_ref().map(|k| k.public() == id).unwrap_or(false) { + if local_key.as_ref().map(|k| k == &id).unwrap_or(false) { HasVoted::Yes(id, vote) } else { HasVoted::No @@ -715,11 +719,18 @@ where HasVoted::No => HasVoted::No, }; + // we can only sign when we have a local key in the authority set + // and we have a reference to the keystore. + let keystore = match (local_key.as_ref(), self.config.keystore.as_ref()) { + (Some(id), Some(keystore)) => Some((id.clone(), keystore.clone()).into()), + _ => None, + }; + let (incoming, outgoing) = self.network.round_communication( + keystore, crate::communication::Round(round), crate::communication::SetId(self.set_id), self.voters.clone(), - local_key.clone(), has_voted, ); @@ -738,7 +749,7 @@ where let outgoing = Box::pin(outgoing.sink_err_into()); voter::RoundData { - voter_id: local_key.map(|pair| pair.public()), + voter_id: local_key, prevote_timer: Box::pin(prevote_timer.map(Ok)), precommit_timer: Box::pin(precommit_timer.map(Ok)), incoming, @@ -747,10 +758,10 @@ where } fn proposed(&self, round: RoundNumber, propose: PrimaryPropose) -> Result<(), Self::Error> { - let local_id = crate::is_voter(&self.voters, &self.config.keystore); + let local_id = crate::is_voter(&self.voters, self.config.keystore.as_ref()); let local_id = match local_id { - Some(id) => id.public(), + Some(id) => id, None => return Ok(()), }; @@ -786,10 +797,10 @@ where } fn prevoted(&self, round: RoundNumber, prevote: Prevote) -> Result<(), Self::Error> { - let local_id = crate::is_voter(&self.voters, &self.config.keystore); + let local_id = crate::is_voter(&self.voters, self.config.keystore.as_ref()); let local_id = match local_id { - Some(id) => id.public(), + Some(id) => id, None => return Ok(()), }; @@ -827,10 +838,10 @@ where } fn precommitted(&self, round: RoundNumber, precommit: Precommit) -> Result<(), Self::Error> { - let local_id = crate::is_voter(&self.voters, &self.config.keystore); + let local_id = crate::is_voter(&self.voters, self.config.keystore.as_ref()); let local_id = match local_id { - Some(id) => id.public(), + Some(id) => id, None => return Ok(()), }; @@ -920,7 +931,12 @@ where // remove the round from live rounds and start tracking the next round let mut current_rounds = current_rounds.clone(); current_rounds.remove(&round); - current_rounds.insert(round + 1, HasVoted::No); + + // NOTE: this condition should always hold as GRANDPA rounds are always + // started in increasing order, still it's better to play it safe. + if !current_rounds.contains_key(&(round + 1)) { + current_rounds.insert(round + 1, HasVoted::No); + } let set_state = VoterSetState::::Live { completed_rounds, @@ -1007,6 +1023,7 @@ where number, (round, commit).into(), false, + &self.justification_sender, ) } @@ -1071,6 +1088,7 @@ pub(crate) fn finalize_block( number: NumberFor, justification_or_commit: JustificationOrCommit, initial_sync: bool, + justification_sender: &Option>, ) -> Result<(), CommandOrError>> where Block: BlockT, BE: Backend, @@ -1082,6 +1100,7 @@ pub(crate) fn finalize_block( let mut authority_set = authority_set.inner().write(); let status = client.info(); + if number <= status.finalized_number && client.hash(number)? == Some(hash) { // This can happen after a forced change (triggered by the finality tracker when finality is stalled), since // the voter will be restarted at the median last finalized block, which can be lower than the local best @@ -1142,7 +1161,7 @@ pub(crate) fn finalize_block( // justifications for transition blocks which will be requested by // syncing clients. let justification = match justification_or_commit { - JustificationOrCommit::Justification(justification) => Some(justification.encode()), + JustificationOrCommit::Justification(justification) => Some(justification), JustificationOrCommit::Commit((round_number, commit)) => { let mut justification_required = // justification is always required when block that enacts new authorities @@ -1169,13 +1188,22 @@ pub(crate) fn finalize_block( commit, )?; - Some(justification.encode()) + Some(justification) } else { None } }, }; + // Notify any registered listeners in case we have a justification + if let Some(sender) = justification_sender { + if let Some(ref justification) = justification { + let _ = sender.notify(justification.clone()); + } + } + + let justification = justification.map(|j| j.encode()); + debug!(target: "afg", "Finalizing blocks up to ({:?}, {})", number, hash); // ideally some handle to a synchronization oracle would be used diff --git a/client/finality-grandpa/src/finality_proof.rs b/client/finality-grandpa/src/finality_proof.rs index bf3662aba36af2b79076ec62d4cc603a5a42d563..2ac9ec57f3df4a6d706514a18109addaabc2f9df 100644 --- a/client/finality-grandpa/src/finality_proof.rs +++ b/client/finality-grandpa/src/finality_proof.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! GRANDPA block finality proof generation and check. //! @@ -147,7 +149,7 @@ impl AuthoritySetForFinalityChecker for Arc { +pub struct FinalityProofProvider { backend: Arc, authority_provider: Arc>, } @@ -167,6 +169,18 @@ impl FinalityProofProvider { FinalityProofProvider { backend, authority_provider: Arc::new(authority_provider) } } + + /// Create new finality proof provider for the service using: + /// + /// - backend for accessing blockchain data; + /// - storage_and_proof_provider, which is generally a client. + pub fn new_for_service( + backend: Arc, + storage_and_proof_provider: Arc>, + ) -> Arc { + Arc::new(Self::new(backend, storage_and_proof_provider)) + } + } impl sc_network::config::FinalityProofProvider for FinalityProofProvider @@ -183,7 +197,7 @@ impl sc_network::config::FinalityProofProvider for FinalityProo let request: FinalityProofRequest = Decode::decode(&mut &request[..]) .map_err(|e| { warn!(target: "afg", "Unable to decode finality proof request: {}", e.what()); - ClientError::Backend(format!("Invalid finality proof request")) + ClientError::Backend("Invalid finality proof request".to_string()) })?; match request { FinalityProofRequest::Original(request) => prove_finality::<_, _, GrandpaJustification>( @@ -397,7 +411,7 @@ pub(crate) fn prove_finality, J>( } // else search for the next justification - current_number = current_number + One::one(); + current_number += One::one(); } if finality_proof.is_empty() { @@ -513,7 +527,7 @@ fn check_finality_proof_fragment( new_authorities_proof, )?; - current_set_id = current_set_id + 1; + current_set_id += 1; } Ok(AuthoritiesOrEffects::Effects(FinalityEffects { diff --git a/client/finality-grandpa/src/import.rs b/client/finality-grandpa/src/import.rs index c1e32dfa6cc9e3847c18030f6f88c666d182a611..d5b0a650096ca08ca328f9d2b42c2b2787dcffad 100644 --- a/client/finality-grandpa/src/import.rs +++ b/client/finality-grandpa/src/import.rs @@ -1,22 +1,24 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{sync::Arc, collections::HashMap}; -use log::{debug, trace}; +use log::debug; use parity_scale_codec::Encode; use parking_lot::RwLockWriteGuard; @@ -42,6 +44,7 @@ use crate::authorities::{AuthoritySet, SharedAuthoritySet, DelayKind, PendingCha use crate::consensus_changes::SharedConsensusChanges; use crate::environment::finalize_block; use crate::justification::GrandpaJustification; +use crate::notification::GrandpaJustificationSender; use std::marker::PhantomData; /// A block-import handler for GRANDPA. @@ -60,6 +63,7 @@ pub struct GrandpaBlockImport { send_voter_commands: TracingUnboundedSender>>, consensus_changes: SharedConsensusChanges>, authority_set_hard_forks: HashMap>>, + justification_sender: GrandpaJustificationSender, _phantom: PhantomData, } @@ -74,6 +78,7 @@ impl Clone for send_voter_commands: self.send_voter_commands.clone(), consensus_changes: self.consensus_changes.clone(), authority_set_hard_forks: self.authority_set_hard_forks.clone(), + justification_sender: self.justification_sender.clone(), _phantom: PhantomData, } } @@ -294,7 +299,7 @@ where } } - let number = block.header.number().clone(); + let number = *(block.header.number()); let maybe_change = self.check_new_change( &block.header, hash, @@ -326,7 +331,7 @@ where guard.as_mut().add_pending_change( change, &is_descendent_of, - ).map_err(|e| ConsensusError::from(ConsensusError::ClientImport(e.to_string())))?; + ).map_err(|e| ConsensusError::ClientImport(e.to_string()))?; } let applied_changes = { @@ -417,14 +422,14 @@ impl BlockImport new_cache: HashMap>, ) -> Result { let hash = block.post_hash(); - let number = block.header.number().clone(); + let number = *block.header.number(); // early exit if block already in chain, otherwise the check for // authority changes will error when trying to re-import a change block match self.inner.status(BlockId::Hash(hash)) { Ok(BlockStatus::InChain) => return Ok(ImportResult::AlreadyInChain), Ok(BlockStatus::Unknown) => {}, - Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), + Err(e) => return Err(ConsensusError::ClientImport(e.to_string())), } // on initial sync we will restrict logging under info to avoid spam. @@ -456,7 +461,7 @@ impl BlockImport e, ); pending_changes.revert(); - return Err(ConsensusError::ClientImport(e.to_string()).into()); + return Err(ConsensusError::ClientImport(e.to_string())); }, } }; @@ -466,7 +471,7 @@ impl BlockImport // Send the pause signal after import but BEFORE sending a `ChangeAuthorities` message. if do_pause { let _ = self.send_voter_commands.unbounded_send( - VoterCommand::Pause(format!("Forced change scheduled after inactivity")) + VoterCommand::Pause("Forced change scheduled after inactivity".to_string()) ); } @@ -522,7 +527,7 @@ impl BlockImport }, None => { if needs_justification { - trace!( + debug!( target: "afg", "Imported unjustified block #{} that enacts authority set change, waiting for finality for enactment.", number, @@ -558,6 +563,7 @@ impl GrandpaBlockImport>>, consensus_changes: SharedConsensusChanges>, authority_set_hard_forks: Vec<(SetId, PendingChange>)>, + justification_sender: GrandpaJustificationSender, ) -> GrandpaBlockImport { // check for and apply any forced authority set hard fork that applies // to the *current* authority set. @@ -601,6 +607,7 @@ impl GrandpaBlockImport return Err(ConsensusError::ClientImport(e.to_string()).into()), + Err(e) => return Err(ConsensusError::ClientImport(e.to_string())), Ok(justification) => justification, }; @@ -646,6 +653,7 @@ where number, justification.into(), initial_sync, + &Some(self.justification_sender.clone()), ); match result { @@ -667,8 +675,9 @@ where Error::Blockchain(error) => ConsensusError::ClientImport(error), Error::Client(error) => ConsensusError::ClientImport(error.to_string()), Error::Safety(error) => ConsensusError::ClientImport(error), + Error::Signing(error) => ConsensusError::ClientImport(error), Error::Timer(error) => ConsensusError::ClientImport(error.to_string()), - }.into()); + }); }, Ok(_) => { assert!(!enacts_change, "returns Ok when no authority set change should be enacted; qed;"); diff --git a/client/finality-grandpa/src/justification.rs b/client/finality-grandpa/src/justification.rs index cbaa2cb4415b87cbdeb3d7d3888cca2e011ec288..d5ca92d50e9371cf76e80945b69edc3c3f9e3c13 100644 --- a/client/finality-grandpa/src/justification.rs +++ b/client/finality-grandpa/src/justification.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::collections::{HashMap, HashSet}; use std::sync::Arc; @@ -35,7 +37,7 @@ use crate::{Commit, Error}; /// /// This is meant to be stored in the db and passed around the network to other /// nodes, and are used by syncing nodes to prove authority set handoffs. -#[derive(Encode, Decode)] +#[derive(Clone, Encode, Decode, PartialEq, Eq, Debug)] pub struct GrandpaJustification { round: u64, pub(crate) commit: Commit, @@ -45,7 +47,7 @@ pub struct GrandpaJustification { impl GrandpaJustification { /// Create a GRANDPA justification from the given commit. This method /// assumes the commit is valid and well-formed. - pub(crate) fn from_commit( + pub fn from_commit( client: &Arc, round: u64, commit: Commit, @@ -61,7 +63,7 @@ impl GrandpaJustification { }; for signed in commit.precommits.iter() { - let mut current_hash = signed.precommit.target_hash.clone(); + let mut current_hash = signed.precommit.target_hash; loop { if current_hash == commit.target_hash { break; } @@ -71,7 +73,7 @@ impl GrandpaJustification { return error(); } - let parent_hash = current_header.parent_hash().clone(); + let parent_hash = *current_header.parent_hash(); if votes_ancestries_hashes.insert(current_hash) { votes_ancestries.push(current_header); } @@ -131,7 +133,7 @@ impl GrandpaJustification { let mut buf = Vec::new(); let mut visited_hashes = HashSet::new(); for signed in self.commit.precommits.iter() { - if let Err(_) = sp_finality_grandpa::check_message_signature_with_buffer( + if !sp_finality_grandpa::check_message_signature_with_buffer( &finality_grandpa::Message::Precommit(signed.precommit.clone()), &signed.id, &signed.signature, @@ -140,7 +142,7 @@ impl GrandpaJustification { &mut buf, ) { return Err(ClientError::BadJustification( - "invalid signature for precommit in grandpa justification".to_string()).into()); + "invalid signature for precommit in grandpa justification".to_string())); } if self.commit.target_hash == signed.precommit.target_hash { @@ -157,7 +159,7 @@ impl GrandpaJustification { }, _ => { return Err(ClientError::BadJustification( - "invalid precommit ancestry proof in grandpa justification".to_string()).into()); + "invalid precommit ancestry proof in grandpa justification".to_string())); }, } } @@ -169,7 +171,7 @@ impl GrandpaJustification { if visited_hashes != ancestry_hashes { return Err(ClientError::BadJustification( - "invalid precommit ancestries in grandpa justification with unused headers".to_string()).into()); + "invalid precommit ancestries in grandpa justification with unused headers".to_string())); } Ok(()) diff --git a/client/finality-grandpa/src/lib.rs b/client/finality-grandpa/src/lib.rs index ac677bf3f32d2ca1a32c4296da1b9fe7b8b3999f..ab84591f9cdec7ffec60a62df473d9d8a8cb935f 100644 --- a/client/finality-grandpa/src/lib.rs +++ b/client/finality-grandpa/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Integration of the GRANDPA finality gadget into substrate. //! @@ -54,9 +56,11 @@ #![warn(missing_docs)] -use futures::prelude::*; -use futures::StreamExt; -use log::{debug, info}; +use futures::{ + prelude::*, + StreamExt, +}; +use log::{debug, error, info}; use sc_client_api::{ backend::{AuxStore, Backend}, LockImportRun, BlockchainEvents, CallExecutor, @@ -68,19 +72,20 @@ use sp_api::ProvideRuntimeApi; use sp_blockchain::{HeaderBackend, Error as ClientError, HeaderMetadata}; use sp_runtime::generic::BlockId; use sp_runtime::traits::{NumberFor, Block as BlockT, DigestFor, Zero}; -use sc_keystore::KeyStorePtr; use sp_inherents::InherentDataProviders; use sp_consensus::{SelectChain, BlockImport}; -use sp_core::Pair; +use sp_core::{ + crypto::Public, + traits::BareCryptoStorePtr, +}; +use sp_application_crypto::AppKey; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver}; use sc_telemetry::{telemetry, CONSENSUS_INFO, CONSENSUS_DEBUG}; -use serde_json; use parking_lot::RwLock; -use sp_finality_tracker; - use finality_grandpa::Error as GrandpaError; -use finality_grandpa::{voter, BlockNumberOps, voter_set::VoterSet}; +use finality_grandpa::{voter, voter_set::VoterSet}; +pub use finality_grandpa::BlockNumberOps; use std::{fmt, io}; use std::sync::Arc; @@ -114,14 +119,17 @@ mod finality_proof; mod import; mod justification; mod light_import; +mod notification; mod observer; mod until_imported; mod voting_rule; pub use authorities::SharedAuthoritySet; pub use finality_proof::{FinalityProofProvider, StorageAndProofProvider}; +pub use notification::{GrandpaJustificationSender, GrandpaJustificationStream}; +pub use import::GrandpaBlockImport; pub use justification::GrandpaJustification; -pub use light_import::light_block_import; +pub use light_import::{light_block_import, GrandpaLightBlockImport}; pub use voting_rule::{ BeforeBestBlockBy, ThreeQuartersOfTheUnfinalizedChain, VotingRule, VotingRulesBuilder }; @@ -129,13 +137,12 @@ pub use finality_grandpa::voter::report; use aux_schema::PersistentData; use environment::{Environment, VoterSetState}; -use import::GrandpaBlockImport; use until_imported::UntilGlobalMessageBlocksImported; use communication::{NetworkBridge, Network as NetworkT}; -use sp_finality_grandpa::{AuthorityList, AuthorityPair, AuthoritySignature, SetId}; +use sp_finality_grandpa::{AuthorityList, AuthoritySignature, SetId}; // Re-export these two because it's just so damn convenient. -pub use sp_finality_grandpa::{AuthorityId, GrandpaApi, ScheduledChange}; +pub use sp_finality_grandpa::{AuthorityId, AuthorityPair, GrandpaApi, ScheduledChange}; use std::marker::PhantomData; #[cfg(test)] @@ -265,7 +272,7 @@ pub struct Config { /// Some local identifier of the voter. pub name: Option, /// The keystore that manages the keys of this node. - pub keystore: Option, + pub keystore: Option, } impl Config { @@ -285,6 +292,8 @@ pub enum Error { Blockchain(String), /// Could not complete a round on disk. Client(ClientError), + /// Could not sign outgoing message + Signing(String), /// An invariant has been violated (e.g. not finalizing pending change blocks in-order) Safety(String), /// A timer failed to fire. @@ -441,6 +450,8 @@ pub struct LinkHalf { select_chain: SC, persistent_data: PersistentData, voter_commands_rx: TracingUnboundedReceiver>>, + justification_sender: GrandpaJustificationSender, + justification_stream: GrandpaJustificationStream, } impl LinkHalf { @@ -448,6 +459,11 @@ impl LinkHalf { pub fn shared_authority_set(&self) -> &SharedAuthoritySet> { &self.persistent_data.authority_set } + + /// Get the receiving end of justification notifications. + pub fn justification_stream(&self) -> GrandpaJustificationStream { + self.justification_stream.clone() + } } /// Provider for the Grandpa authority set configured on the genesis block. @@ -474,7 +490,7 @@ impl GenesisAuthoritySetProvider for Arc( voters: &Arc>, client: Arc, network: &NetworkBridge, - keystore: &Option, + keystore: Option<&BareCryptoStorePtr>, metrics: Option, ) -> ( impl Stream< @@ -649,7 +671,7 @@ fn register_finality_tracker_inherent_data_provider( Ok(info.finalized_number) } })) - .map_err(|err| sp_consensus::Error::InherentData(err.into())) + .map_err(|err| sp_consensus::Error::InherentData(err)) } else { Ok(()) } @@ -712,6 +734,8 @@ pub fn run_grandpa_voter( select_chain, persistent_data, voter_commands_rx, + justification_sender, + justification_stream: _, } = link; let network = NetworkBridge::new( @@ -730,8 +754,8 @@ pub fn run_grandpa_voter( .for_each(move |_| { let curr = authorities.current_authorities(); let mut auths = curr.iter().map(|(p, _)| p); - let maybe_authority_id = authority_id(&mut auths, &conf.keystore) - .unwrap_or(Default::default()); + let maybe_authority_id = authority_id(&mut auths, conf.keystore.as_ref()) + .unwrap_or_default(); telemetry!(CONSENSUS_INFO; "afg.authority_set"; "authority_id" => maybe_authority_id.to_string(), @@ -760,10 +784,15 @@ pub fn run_grandpa_voter( voter_commands_rx, prometheus_registry, shared_voter_state, + justification_sender, ); - let voter_work = voter_work - .map(|_| ()); + let voter_work = voter_work.map(|res| match res { + Ok(()) => error!(target: "afg", + "GRANDPA voter future has concluded naturally, this should be unreachable." + ), + Err(e) => error!(target: "afg", "GRANDPA voter error: {:?}", e), + }); // Make sure that `telemetry_task` doesn't accidentally finish and kill grandpa. let telemetry_task = telemetry_task @@ -820,6 +849,7 @@ where voter_commands_rx: TracingUnboundedReceiver>>, prometheus_registry: Option, shared_voter_state: SharedVoterState, + justification_sender: GrandpaJustificationSender, ) -> Self { let metrics = match prometheus_registry.as_ref().map(Metrics::register) { Some(Ok(metrics)) => Some(metrics), @@ -841,8 +871,9 @@ where set_id: persistent_data.authority_set.set_id(), authority_set: persistent_data.authority_set.clone(), consensus_changes: persistent_data.consensus_changes.clone(), - voter_set_state: persistent_data.set_state.clone(), + voter_set_state: persistent_data.set_state, metrics: metrics.as_ref().map(|m| m.environment.clone()), + justification_sender: Some(justification_sender), _phantom: PhantomData, }); @@ -866,9 +897,8 @@ where fn rebuild_voter(&mut self) { debug!(target: "afg", "{}: Starting new voter with set ID {}", self.env.config.name(), self.env.set_id); - let authority_id = is_voter(&self.env.voters, &self.env.config.keystore) - .map(|ap| ap.public()) - .unwrap_or(Default::default()); + let authority_id = is_voter(&self.env.voters, self.env.config.keystore.as_ref()) + .unwrap_or_default(); telemetry!(CONSENSUS_DEBUG; "afg.starting_new_voter"; "name" => ?self.env.config.name(), @@ -902,7 +932,7 @@ where &self.env.voters, self.env.client.clone(), &self.env.network, - &self.env.config.keystore, + self.env.config.keystore.as_ref(), self.metrics.as_ref().map(|m| m.until_imported.clone()), ); @@ -914,12 +944,12 @@ where global_comms, last_completed_round.number, last_completed_round.votes.clone(), - last_completed_round.base.clone(), + last_completed_round.base, last_finalized, ); // Repoint shared_voter_state so that the RPC endpoint can query the state - if let None = self.shared_voter_state.reset(voter.voter_state()) { + if self.shared_voter_state.reset(voter.voter_state()).is_none() { info!(target: "afg", "Timed out trying to update shared GRANDPA voter state. \ RPC endpoints may return stale data." @@ -982,6 +1012,7 @@ where network: self.env.network.clone(), voting_rule: self.env.voting_rule.clone(), metrics: self.env.metrics.clone(), + justification_sender: self.env.justification_sender.clone(), _phantom: PhantomData, }); @@ -1025,7 +1056,9 @@ where Poll::Pending => {} Poll::Ready(Ok(())) => { // voters don't conclude naturally - return Poll::Ready(Err(Error::Safety("GRANDPA voter has concluded.".into()))) + return Poll::Ready( + Err(Error::Safety("finality-grandpa inner voter has concluded.".into())) + ) } Poll::Ready(Err(CommandOrError::Error(e))) => { // return inner observer error @@ -1042,7 +1075,9 @@ where Poll::Pending => {} Poll::Ready(None) => { // the `voter_commands_rx` stream should never conclude since it's never closed. - return Poll::Ready(Ok(())) + return Poll::Ready( + Err(Error::Safety("`voter_commands_rx` was closed.".into())) + ) } Poll::Ready(Some(command)) => { // some command issued externally @@ -1090,12 +1125,16 @@ pub fn setup_disabled_grandpa( /// Returns the key pair of the node that is being used in the current voter set or `None`. fn is_voter( voters: &Arc>, - keystore: &Option, -) -> Option { + keystore: Option<&BareCryptoStorePtr>, +) -> Option { match keystore { Some(keystore) => voters .iter() - .find_map(|(p, _)| keystore.read().key_pair::(&p).ok()), + .find(|(p, _)| { + keystore.read() + .has_keys(&[(p.to_raw_vec(), AuthorityId::ID)]) + }) + .map(|(p, _)| p.clone()), None => None, } } @@ -1103,19 +1142,16 @@ fn is_voter( /// Returns the authority id of this node, if available. fn authority_id<'a, I>( authorities: &mut I, - keystore: &Option, + keystore: Option<&BareCryptoStorePtr>, ) -> Option where I: Iterator, { match keystore { Some(keystore) => { authorities - .find_map(|p| { - keystore.read().key_pair::(&p) - .ok() - .map(|ap| ap.public()) - }) - } + .find(|p| keystore.read().has_keys(&[(p.to_raw_vec(), AuthorityId::ID)])) + .cloned() + }, None => None, } } diff --git a/client/finality-grandpa/src/light_import.rs b/client/finality-grandpa/src/light_import.rs index e9ca94ce9824fd2a411185597f1af60fe0fee513..a7c9a655467c799ed500e6186fd64cc9825b1a7e 100644 --- a/client/finality-grandpa/src/light_import.rs +++ b/client/finality-grandpa/src/light_import.rs @@ -169,7 +169,7 @@ impl FinalityProofImport if *pending_number > chain_info.finalized_number && *pending_number <= chain_info.best_number { - out.push((pending_hash.clone(), *pending_number)); + out.push((*pending_hash, *pending_number)); } } @@ -253,7 +253,7 @@ fn do_import_block( J: ProvableJustification, { let hash = block.post_hash(); - let number = block.header.number().clone(); + let number = *block.header.number(); // we don't want to finalize on `inner.import_block` let justification = block.justification.take(); @@ -263,7 +263,7 @@ fn do_import_block( let mut imported_aux = match import_result { Ok(ImportResult::Imported(aux)) => aux, Ok(r) => return Ok(r), - Err(e) => return Err(ConsensusError::ClientImport(e.to_string()).into()), + Err(e) => return Err(ConsensusError::ClientImport(e.to_string())), }; match justification { @@ -435,7 +435,7 @@ fn do_import_justification( hash, ); - return Err(ConsensusError::ClientImport(e.to_string()).into()); + return Err(ConsensusError::ClientImport(e.to_string())); }, Ok(justification) => { trace!( @@ -573,7 +573,7 @@ pub mod tests { use sp_consensus::{import_queue::CacheKeyId, ForkChoiceStrategy, BlockImport}; use sp_finality_grandpa::AuthorityId; use sp_core::{H256, crypto::Public}; - use sc_client_api::{in_mem::Blockchain as InMemoryAuxStore, StorageProof}; + use sc_client_api::{in_mem::Blockchain as InMemoryAuxStore, StorageProof, BlockBackend}; use substrate_test_runtime_client::runtime::{Block, Header}; use crate::tests::TestApi; use crate::finality_proof::{ diff --git a/client/finality-grandpa/src/notification.rs b/client/finality-grandpa/src/notification.rs new file mode 100644 index 0000000000000000000000000000000000000000..16f705f0eeb1fda4f881e39d4977c04862233886 --- /dev/null +++ b/client/finality-grandpa/src/notification.rs @@ -0,0 +1,102 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use std::sync::Arc; +use parking_lot::Mutex; + +use sp_runtime::traits::Block as BlockT; +use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; + +use crate::justification::GrandpaJustification; + +// Stream of justifications returned when subscribing. +type JustificationStream = TracingUnboundedReceiver>; + +// Sending endpoint for notifying about justifications. +type JustificationSender = TracingUnboundedSender>; + +// Collection of channel sending endpoints shared with the receiver side so they can register +// themselves. +type SharedJustificationSenders = Arc>>>; + +/// The sending half of the Grandpa justification channel(s). +/// +/// Used to send notifications about justifications generated +/// at the end of a Grandpa round. +#[derive(Clone)] +pub struct GrandpaJustificationSender { + subscribers: SharedJustificationSenders +} + +impl GrandpaJustificationSender { + /// The `subscribers` should be shared with a corresponding + /// `GrandpaJustificationStream`. + fn new(subscribers: SharedJustificationSenders) -> Self { + Self { + subscribers, + } + } + + /// Send out a notification to all subscribers that a new justification + /// is available for a block. + pub fn notify(&self, notification: GrandpaJustification) -> Result<(), ()> { + self.subscribers.lock().retain(|n| { + !n.is_closed() && n.unbounded_send(notification.clone()).is_ok() + }); + Ok(()) + } +} + +/// The receiving half of the Grandpa justification channel. +/// +/// Used to receive notifications about justifications generated +/// at the end of a Grandpa round. +/// The `GrandpaJustificationStream` entity stores the `SharedJustificationSenders` +/// so it can be used to add more subscriptions. +#[derive(Clone)] +pub struct GrandpaJustificationStream { + subscribers: SharedJustificationSenders +} + +impl GrandpaJustificationStream { + /// Creates a new pair of receiver and sender of justification notifications. + pub fn channel() -> (GrandpaJustificationSender, Self) { + let subscribers = Arc::new(Mutex::new(vec![])); + let receiver = GrandpaJustificationStream::new(subscribers.clone()); + let sender = GrandpaJustificationSender::new(subscribers.clone()); + (sender, receiver) + } + + /// Create a new receiver of justification notifications. + /// + /// The `subscribers` should be shared with a corresponding + /// `GrandpaJustificationSender`. + fn new(subscribers: SharedJustificationSenders) -> Self { + Self { + subscribers, + } + } + + /// Subscribe to a channel through which justifications are sent + /// at the end of each Grandpa voting round. + pub fn subscribe(&self) -> JustificationStream { + let (sender, receiver) = tracing_unbounded("mpsc_justification_notification_stream"); + self.subscribers.lock().push(sender); + receiver + } +} diff --git a/client/finality-grandpa/src/observer.rs b/client/finality-grandpa/src/observer.rs index ab06f06280c83ba16f55a07b9f19b8f898bf3e5c..8fb536a369751b8bcbefa77ef827e76d706b33ad 100644 --- a/client/finality-grandpa/src/observer.rs +++ b/client/finality-grandpa/src/observer.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::pin::Pin; use std::sync::Arc; @@ -24,7 +26,7 @@ use finality_grandpa::{ BlockNumberOps, Error as GrandpaError, voter, voter_set::VoterSet }; use log::{debug, info, warn}; - +use sp_core::traits::BareCryptoStorePtr; use sp_consensus::SelectChain; use sc_client_api::backend::Backend; use sp_utils::mpsc::TracingUnboundedReceiver; @@ -38,6 +40,7 @@ use crate::{ use crate::authorities::SharedAuthoritySet; use crate::communication::{Network as NetworkT, NetworkBridge}; use crate::consensus_changes::SharedConsensusChanges; +use crate::notification::GrandpaJustificationSender; use sp_finality_grandpa::AuthorityId; use std::marker::{PhantomData, Unpin}; @@ -67,6 +70,7 @@ fn grandpa_observer( authority_set: &SharedAuthoritySet>, consensus_changes: &SharedConsensusChanges>, voters: &Arc>, + justification_sender: &Option>, last_finalized_number: NumberFor, commits: S, note_round: F, @@ -83,6 +87,7 @@ fn grandpa_observer( let consensus_changes = consensus_changes.clone(); let client = client.clone(); let voters = voters.clone(); + let justification_sender = justification_sender.clone(); let observer = commits.try_fold(last_finalized_number, move |last_finalized_number, global| { let (round, commit, callback) = match global { @@ -111,7 +116,7 @@ fn grandpa_observer( Err(e) => return future::err(e.into()), }; - if let Some(_) = validation_result.ghost() { + if validation_result.ghost().is_some() { let finalized_hash = commit.target_hash; let finalized_number = commit.target_number; @@ -125,6 +130,7 @@ fn grandpa_observer( finalized_number, (round, commit).into(), false, + &justification_sender, ) { Ok(_) => {}, Err(e) => return future::err(e), @@ -175,6 +181,7 @@ where select_chain: _, persistent_data, voter_commands_rx, + justification_sender, .. } = link; @@ -189,8 +196,9 @@ where client, network, persistent_data, - config.keystore.clone(), - voter_commands_rx + config.keystore, + voter_commands_rx, + Some(justification_sender), ); let observer_work = observer_work @@ -209,8 +217,9 @@ struct ObserverWork> { client: Arc, network: NetworkBridge, persistent_data: PersistentData, - keystore: Option, + keystore: Option, voter_commands_rx: TracingUnboundedReceiver>>, + justification_sender: Option>, _phantom: PhantomData, } @@ -226,8 +235,9 @@ where client: Arc, network: NetworkBridge, persistent_data: PersistentData, - keystore: Option, + keystore: Option, voter_commands_rx: TracingUnboundedReceiver>>, + justification_sender: Option>, ) -> Self { let mut work = ObserverWork { @@ -237,8 +247,9 @@ where client, network, persistent_data, - keystore, + keystore: keystore.clone(), voter_commands_rx, + justification_sender, _phantom: PhantomData, }; work.rebuild_observer(); @@ -258,7 +269,7 @@ where &voters, self.client.clone(), &self.network, - &self.keystore, + self.keystore.as_ref(), None, ); @@ -285,6 +296,7 @@ where &self.persistent_data.authority_set, &self.persistent_data.consensus_changes, &voters, + &self.justification_sender, last_finalized_number, global_in, note_round, @@ -420,12 +432,14 @@ mod tests { ).unwrap(); let (_tx, voter_command_rx) = tracing_unbounded(""); + let observer = ObserverWork::new( client, tester.net_handle.clone(), persistent_data, None, voter_command_rx, + None, ); // Trigger a reputation change through the gossip validator. diff --git a/client/finality-grandpa/src/tests.rs b/client/finality-grandpa/src/tests.rs index 64e5b0545b546a4f4b8b4a26634480428a105b10..d2905e4da44537a76ff602078c5283eff6631437 100644 --- a/client/finality-grandpa/src/tests.rs +++ b/client/finality-grandpa/src/tests.rs @@ -1,26 +1,29 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Tests and test helpers for GRANDPA. use super::*; +use assert_matches::assert_matches; use environment::HasVoted; use sc_network_test::{ - Block, Hash, TestNetFactory, BlockImportAdapter, Peer, - PeersClient, PassThroughVerifier, PeersFullClient, + Block, BlockImportAdapter, Hash, PassThroughVerifier, Peer, PeersClient, PeersFullClient, + TestClient, TestNetFactory, }; use sc_network::config::{ProtocolConfig, BoxFinalityProofRequestBuilder}; use parking_lot::Mutex; @@ -51,16 +54,9 @@ use consensus_changes::ConsensusChanges; use sc_block_builder::BlockBuilderProvider; use sc_consensus::LongestChain; -type PeerData = - Mutex< - Option< - LinkHalf< - Block, - PeersFullClient, - LongestChain - > - > - >; +type TestLinkHalf = + LinkHalf>; +type PeerData = Mutex>; type GrandpaPeer = Peer; struct GrandpaTestNet { @@ -104,7 +100,7 @@ impl TestNetFactory for GrandpaTestNet { _cfg: &ProtocolConfig, _: &PeerData, ) -> Self::Verifier { - PassThroughVerifier(false) // use non-instant finality. + PassThroughVerifier::new(false) // use non-instant finality. } fn make_block_import(&self, client: PeersClient) @@ -215,7 +211,7 @@ sp_api::mock_impl_runtime_apis! { self.inner.genesis_authorities.clone() } - fn submit_report_equivocation_extrinsic( + fn submit_report_equivocation_unsigned_extrinsic( _equivocation_proof: EquivocationProof, _key_owner_proof: OpaqueKeyOwnershipProof, ) -> Option<()> { @@ -280,7 +276,7 @@ fn make_ids(keys: &[Ed25519Keyring]) -> AuthorityList { keys.iter().map(|key| key.clone().public().into()).map(|id| (id, 1)).collect() } -fn create_keystore(authority: Ed25519Keyring) -> (KeyStorePtr, tempfile::TempDir) { +fn create_keystore(authority: Ed25519Keyring) -> (BareCryptoStorePtr, tempfile::TempDir) { let keystore_path = tempfile::tempdir().expect("Creates keystore path"); let keystore = sc_keystore::Store::open(keystore_path.path(), None).expect("Creates keystore"); keystore.write().insert_ephemeral_from_seed::(&authority.to_seed()) @@ -1048,7 +1044,7 @@ fn voter_persists_its_votes() { voter_rx: TracingUnboundedReceiver<()>, net: Arc>, client: PeersClient, - keystore: KeyStorePtr, + keystore: BareCryptoStorePtr, } impl Future for ResettableVoter { @@ -1134,7 +1130,7 @@ fn voter_persists_its_votes() { let config = Config { gossip_duration: TEST_GOSSIP_DURATION, justification_period: 32, - keystore: Some(keystore), + keystore: Some(keystore.clone()), name: Some(format!("peer#{}", 1)), is_authority: true, observer_enabled: true, @@ -1158,10 +1154,10 @@ fn voter_persists_its_votes() { ); let (round_rx, round_tx) = network.round_communication( + Some((peers[1].public().into(), keystore).into()), communication::Round(1), communication::SetId(0), Arc::new(VoterSet::new(voters).unwrap()), - Some(peers[1].pair().into()), HasVoted::No, ); @@ -1517,10 +1513,68 @@ fn voter_catches_up_to_latest_round_when_behind() { ); } +type TestEnvironment = Environment< + substrate_test_runtime_client::Backend, + Block, + TestClient, + N, + LongestChain, + VR, +>; + +fn test_environment( + link: &TestLinkHalf, + keystore: Option, + network_service: N, + voting_rule: VR, +) -> TestEnvironment +where + N: NetworkT, + VR: VotingRule, +{ + let PersistentData { + ref authority_set, + ref consensus_changes, + ref set_state, + .. + } = link.persistent_data; + + let config = Config { + gossip_duration: TEST_GOSSIP_DURATION, + justification_period: 32, + keystore, + name: None, + is_authority: true, + observer_enabled: true, + }; + + let network = NetworkBridge::new( + network_service.clone(), + config.clone(), + set_state.clone(), + None, + ); + + Environment { + authority_set: authority_set.clone(), + config: config.clone(), + consensus_changes: consensus_changes.clone(), + client: link.client.clone(), + select_chain: link.select_chain.clone(), + set_id: authority_set.set_id(), + voter_set_state: set_state.clone(), + voters: Arc::new(authority_set.current_authorities()), + network, + voting_rule, + metrics: None, + justification_sender: None, + _phantom: PhantomData, + } +} + #[test] fn grandpa_environment_respects_voting_rules() { use finality_grandpa::Chain; - use sc_network_test::TestClient; let peers = &[Ed25519Keyring::Alice]; let voters = make_ids(peers); @@ -1530,63 +1584,28 @@ fn grandpa_environment_respects_voting_rules() { let network_service = peer.network_service().clone(); let link = peer.data.lock().take().unwrap(); - // create a voter environment with a given voting rule - let environment = |voting_rule: Box>| { - let PersistentData { - ref authority_set, - ref consensus_changes, - ref set_state, - .. - } = link.persistent_data; - - let config = Config { - gossip_duration: TEST_GOSSIP_DURATION, - justification_period: 32, - keystore: None, - name: None, - is_authority: true, - observer_enabled: true, - }; - - let network = NetworkBridge::new( - network_service.clone(), - config.clone(), - set_state.clone(), - None, - ); - - Environment { - authority_set: authority_set.clone(), - config: config.clone(), - consensus_changes: consensus_changes.clone(), - client: link.client.clone(), - select_chain: link.select_chain.clone(), - set_id: authority_set.set_id(), - voter_set_state: set_state.clone(), - voters: Arc::new(authority_set.current_authorities()), - network, - voting_rule, - metrics: None, - _phantom: PhantomData, - } - }; - // add 21 blocks peer.push_blocks(21, false); // create an environment with no voting rule restrictions - let unrestricted_env = environment(Box::new(())); + let unrestricted_env = test_environment(&link, None, network_service.clone(), ()); // another with 3/4 unfinalized chain voting rule restriction - let three_quarters_env = environment(Box::new( - voting_rule::ThreeQuartersOfTheUnfinalizedChain - )); + let three_quarters_env = test_environment( + &link, + None, + network_service.clone(), + voting_rule::ThreeQuartersOfTheUnfinalizedChain, + ); // and another restricted with the default voting rules: i.e. 3/4 rule and // always below best block - let default_env = environment(Box::new( - VotingRulesBuilder::default().build() - )); + let default_env = test_environment( + &link, + None, + network_service.clone(), + VotingRulesBuilder::default().build(), + ); // the unrestricted environment should just return the best block assert_eq!( @@ -1646,6 +1665,70 @@ fn grandpa_environment_respects_voting_rules() { ); } +#[test] +fn grandpa_environment_never_overwrites_round_voter_state() { + use finality_grandpa::voter::Environment; + + let peers = &[Ed25519Keyring::Alice]; + let voters = make_ids(peers); + + let mut net = GrandpaTestNet::new(TestApi::new(voters), 1); + let peer = net.peer(0); + let network_service = peer.network_service().clone(); + let link = peer.data.lock().take().unwrap(); + + let (keystore, _keystore_path) = create_keystore(peers[0]); + let environment = test_environment(&link, Some(keystore), network_service.clone(), ()); + + let round_state = || finality_grandpa::round::State::genesis(Default::default()); + let base = || Default::default(); + let historical_votes = || finality_grandpa::HistoricalVotes::new(); + + let get_current_round = |n| { + let current_rounds = environment + .voter_set_state + .read() + .with_current_round(n) + .map(|(_, current_rounds)| current_rounds.clone()) + .ok()?; + + Some(current_rounds.get(&n).unwrap().clone()) + }; + + // round 2 should not be tracked + assert_eq!(get_current_round(2), None); + + // after completing round 1 we should start tracking round 2 + environment + .completed(1, round_state(), base(), &historical_votes()) + .unwrap(); + + assert_eq!(get_current_round(2).unwrap(), HasVoted::No); + + let info = peer.client().info(); + + let prevote = finality_grandpa::Prevote { + target_hash: info.best_hash, + target_number: info.best_number, + }; + + // we prevote for round 2 which should lead to us updating the voter state + environment.prevoted(2, prevote.clone()).unwrap(); + + let has_voted = get_current_round(2).unwrap(); + + assert_matches!(has_voted, HasVoted::Yes(_, _)); + assert_eq!(*has_voted.prevote().unwrap(), prevote); + + // if we report round 1 as completed again we should not overwrite the + // voter state for round 2 + environment + .completed(1, round_state(), base(), &historical_votes()) + .unwrap(); + + assert_matches!(get_current_round(2).unwrap(), HasVoted::Yes(_, _)); +} + #[test] fn imports_justification_for_regular_blocks_on_import() { // NOTE: this is a regression test since initially we would only import diff --git a/client/finality-grandpa/src/until_imported.rs b/client/finality-grandpa/src/until_imported.rs index 6f76ce3fa86c813dfe8cc28503733c99af388ad0..3ac94f3b062f0273f975e714c7318b9539243dae 100644 --- a/client/finality-grandpa/src/until_imported.rs +++ b/client/finality-grandpa/src/until_imported.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Helper stream for waiting until one or more blocks are imported before //! passing through inner items. This is done in a generic way to support @@ -258,7 +260,7 @@ impl Stream for UntilImported { // new block imported. queue up all messages tied to that hash. if let Some((_, _, messages)) = this.pending.remove(¬ification.hash) { - let canon_number = notification.header.number().clone(); + let canon_number = *notification.header.number(); let ready_messages = messages.into_iter() .filter_map(|m| m.wait_completed(canon_number)); @@ -359,7 +361,7 @@ impl BlockUntilImported for SignedMessage { } } - return Ok(DiscardWaitOrReady::Wait(vec![(target_hash, target_number, msg)])) + Ok(DiscardWaitOrReady::Wait(vec![(target_hash, target_number, msg)])) } fn wait_completed(self, canon_number: NumberFor) -> Option { @@ -430,7 +432,7 @@ impl BlockUntilImported for BlockGlobalMessage { let mut query_known = |target_hash, perceived_number| -> Result { // check integrity: all votes for same hash have same number. let canon_number = match checked_hashes.entry(target_hash) { - Entry::Occupied(entry) => entry.get().number().clone(), + Entry::Occupied(entry) => *entry.get().number(), Entry::Vacant(entry) => { if let Some(number) = status_check.block_number(target_hash)? { entry.insert(KnownOrUnknown::Known(number)); @@ -583,7 +585,7 @@ mod tests { origin: BlockOrigin::File, header, is_new_best: false, - retracted: vec![], + tree_route: None, }).unwrap(); } } diff --git a/client/finality-grandpa/src/voting_rule.rs b/client/finality-grandpa/src/voting_rule.rs index bcf17039a89b614980959666a4fb7f2055139bd8..60493867ce1f4c4e9c50e662857ef1ffcd842cba 100644 --- a/client/finality-grandpa/src/voting_rule.rs +++ b/client/finality-grandpa/src/voting_rule.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Handling custom voting rules for GRANDPA. //! diff --git a/client/informant/Cargo.toml b/client/informant/Cargo.toml index f8e6ca85f95b8347934df26254b9999294efe879..6e6dc01f91e531213b873c9a0785a59b36a77847 100644 --- a/client/informant/Cargo.toml +++ b/client/informant/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-informant" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Substrate informant." edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -15,10 +15,11 @@ targets = ["x86_64-unknown-linux-gnu"] ansi_term = "0.12.1" futures = "0.3.4" log = "0.4.8" -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sc-network = { version = "0.8.0-rc6", path = "../network" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-rc2", path = "../../primitives/utils" } +sp-transaction-pool = { version = "2.0.0-rc2", path = "../../primitives/transaction-pool" } wasm-timer = "0.2" -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sc-network = { version = "0.8.0-dev", path = "../network" } -sc-service = { version = "0.8.0-dev", default-features = false, path = "../service" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } diff --git a/client/informant/README.md b/client/informant/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b494042590a4218aaa9c63d5e4b3c8a09a804b5b --- /dev/null +++ b/client/informant/README.md @@ -0,0 +1,3 @@ +Console informant. Prints sync progress and block events. Runs on the calling thread. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/informant/src/display.rs b/client/informant/src/display.rs index 42f498998362e6eb1a6d02f4af1fc98ce285030f..ce7fb4fc4b12bf58e14905b1ee10c9947ec9bda4 100644 --- a/client/informant/src/display.rs +++ b/client/informant/src/display.rs @@ -14,15 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . +use crate::OutputFormat; use ansi_term::Colour; -use sc_client_api::ClientInfo; use log::info; -use sc_network::SyncState; -use sp_runtime::traits::{Block as BlockT, CheckedDiv, NumberFor, Zero, Saturating}; -use sc_service::NetworkStatus; -use std::{convert::{TryFrom, TryInto}, fmt}; +use sc_client_api::ClientInfo; +use sc_network::{NetworkStatus, SyncState}; +use sp_runtime::traits::{Block as BlockT, CheckedDiv, NumberFor, Saturating, Zero}; +use std::{ + convert::{TryFrom, TryInto}, + fmt, +}; use wasm_timer::Instant; -use crate::OutputFormat; /// State of the informant display system. /// @@ -43,6 +45,10 @@ pub struct InformantDisplay { last_number: Option>, /// The last time `display` or `new` has been called. last_update: Instant, + /// The last seen total of bytes received. + last_total_bytes_inbound: u64, + /// The last seen total of bytes sent. + last_total_bytes_outbound: u64, /// The format to print output in. format: OutputFormat, } @@ -53,6 +59,8 @@ impl InformantDisplay { InformantDisplay { last_number: None, last_update: Instant::now(), + last_total_bytes_inbound: 0, + last_total_bytes_outbound: 0, format, } } @@ -64,19 +72,41 @@ impl InformantDisplay { let finalized_number = info.chain.finalized_number; let num_connected_peers = net_status.num_connected_peers; let speed = speed::(best_number, self.last_number, self.last_update); - self.last_update = Instant::now(); + let total_bytes_inbound = net_status.total_bytes_inbound; + let total_bytes_outbound = net_status.total_bytes_outbound; + + let now = Instant::now(); + let elapsed = (now - self.last_update).as_secs(); + self.last_update = now; self.last_number = Some(best_number); - let (status, target) = match (net_status.sync_state, net_status.best_seen_block) { - (SyncState::Idle, _) => ("💤 Idle".into(), "".into()), - (SyncState::Downloading, None) => (format!("⚙️ Preparing{}", speed), "".into()), - (SyncState::Downloading, Some(n)) => (format!("⚙️ Syncing{}", speed), format!(", target=#{}", n)), + let diff_bytes_inbound = total_bytes_inbound - self.last_total_bytes_inbound; + let diff_bytes_outbound = total_bytes_outbound - self.last_total_bytes_outbound; + let (avg_bytes_per_sec_inbound, avg_bytes_per_sec_outbound) = + if elapsed > 0 { + self.last_total_bytes_inbound = total_bytes_inbound; + self.last_total_bytes_outbound = total_bytes_outbound; + (diff_bytes_inbound / elapsed, diff_bytes_outbound / elapsed) + } else { + (diff_bytes_inbound, diff_bytes_outbound) + }; + + let (level, status, target) = match (net_status.sync_state, net_status.best_seen_block) { + (SyncState::Idle, _) => ("💤", "Idle".into(), "".into()), + (SyncState::Downloading, None) => ("⚙️ ", format!("Preparing{}", speed), "".into()), + (SyncState::Downloading, Some(n)) => ( + "⚙️ ", + format!("Syncing{}", speed), + format!(", target=#{}", n), + ), }; - if self.format == OutputFormat::Coloured { + if self.format.enable_color { info!( target: "substrate", - "{}{} ({} peers), best: #{} ({}), finalized #{} ({}), {} {}", + "{} {}{}{} ({} peers), best: #{} ({}), finalized #{} ({}), {} {}", + level, + self.format.prefix, Colour::White.bold().paint(&status), target, Colour::White.bold().paint(format!("{}", num_connected_peers)), @@ -84,13 +114,15 @@ impl InformantDisplay { best_hash, Colour::White.bold().paint(format!("{}", finalized_number)), info.chain.finalized_hash, - Colour::Green.paint(format!("⬇ {}", TransferRateFormat(net_status.average_download_per_sec))), - Colour::Red.paint(format!("⬆ {}", TransferRateFormat(net_status.average_upload_per_sec))), - ); + Colour::Green.paint(format!("⬇ {}", TransferRateFormat(avg_bytes_per_sec_inbound))), + Colour::Red.paint(format!("⬆ {}", TransferRateFormat(avg_bytes_per_sec_outbound))), + ) } else { info!( target: "substrate", - "{}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}", + "{} {}{}{} ({} peers), best: #{} ({}), finalized #{} ({}), ⬇ {} ⬆ {}", + level, + self.format.prefix, status, target, num_connected_peers, @@ -98,9 +130,9 @@ impl InformantDisplay { best_hash, finalized_number, info.chain.finalized_hash, - TransferRateFormat(net_status.average_download_per_sec), - TransferRateFormat(net_status.average_upload_per_sec), - ); + TransferRateFormat(avg_bytes_per_sec_inbound), + TransferRateFormat(avg_bytes_per_sec_outbound), + ) } } } diff --git a/client/informant/src/lib.rs b/client/informant/src/lib.rs index 090282a982092db6ec98e504b546268dd272bb56..3daf29a9f78371d58ee34b996a0302a7fb9bd8a8 100644 --- a/client/informant/src/lib.rs +++ b/client/informant/src/lib.rs @@ -1,49 +1,103 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Console informant. Prints sync progress and block events. Runs on the calling thread. use ansi_term::Colour; -use sc_client_api::{BlockchainEvents, UsageProvider}; use futures::prelude::*; -use log::{info, warn, trace}; -use sp_runtime::traits::Header; -use sc_service::AbstractService; -use std::time::Duration; +use log::{info, trace, warn}; +use parity_util_mem::MallocSizeOf; +use sc_client_api::{BlockchainEvents, UsageProvider}; +use sc_network::{network_state::NetworkState, NetworkStatus}; +use sp_blockchain::HeaderMetadata; +use sp_runtime::traits::{Block as BlockT, Header}; +use sp_transaction_pool::TransactionPool; +use sp_utils::{status_sinks, mpsc::tracing_unbounded}; +use std::{fmt::Display, sync::Arc, time::Duration, collections::VecDeque}; mod display; /// The format to print telemetry output in. -#[derive(PartialEq)] -pub enum OutputFormat { - Coloured, - Plain, +#[derive(Clone, Debug)] +pub struct OutputFormat { + /// Enable color output in logs. True by default. + pub enable_color: bool, + /// Defines the informant's prefix for the logs. An empty string by default. + /// + /// By default substrate will show logs without a prefix. Example: + /// + /// ```text + /// 2020-05-28 15:11:06 ✨ Imported #2 (0xc21c…2ca8) + /// 2020-05-28 15:11:07 💤 Idle (0 peers), best: #2 (0xc21c…2ca8), finalized #0 (0x7299…e6df), ⬇ 0 ⬆ 0 + /// ``` + /// + /// But you can define a prefix by setting this string. This will output: + /// + /// ```text + /// 2020-05-28 15:11:06 ✨ [Prefix] Imported #2 (0xc21c…2ca8) + /// 2020-05-28 15:11:07 💤 [Prefix] Idle (0 peers), best: #2 (0xc21c…2ca8), finalized #0 (0x7299…e6df), ⬇ 0 ⬆ 0 + /// ``` + pub prefix: String, } -/// Creates an informant in the form of a `Future` that must be polled regularly. -pub fn build(service: &impl AbstractService, format: OutputFormat) -> impl futures::Future { - let client = service.client(); - let pool = service.transaction_pool(); - - let mut display = display::InformantDisplay::new(format); +impl Default for OutputFormat { + fn default() -> Self { + Self { + enable_color: true, + prefix: String::new(), + } + } +} - let display_notifications = service - .network_status(Duration::from_millis(5000)) +/// Marker trait for a type that implements `TransactionPool` and `MallocSizeOf` on `not(target_os = "unknown")`. +#[cfg(target_os = "unknown")] +pub trait TransactionPoolAndMaybeMallogSizeOf: TransactionPool {} + +/// Marker trait for a type that implements `TransactionPool` and `MallocSizeOf` on `not(target_os = "unknown")`. +#[cfg(not(target_os = "unknown"))] +pub trait TransactionPoolAndMaybeMallogSizeOf: TransactionPool + MallocSizeOf {} + +#[cfg(target_os = "unknown")] +impl TransactionPoolAndMaybeMallogSizeOf for T {} + +#[cfg(not(target_os = "unknown"))] +impl TransactionPoolAndMaybeMallogSizeOf for T {} + +/// Builds the informant and returns a `Future` that drives the informant. +pub fn build( + client: Arc, + network_status_sinks: Arc, NetworkState)>>, + pool: Arc, + format: OutputFormat, +) -> impl futures::Future +where + C: UsageProvider + HeaderMetadata + BlockchainEvents, + >::Error: Display, +{ + let mut display = display::InformantDisplay::new(format.clone()); + + let client_1 = client.clone(); + let (network_status_sink, network_status_stream) = tracing_unbounded("mpsc_network_status"); + network_status_sinks.push(Duration::from_millis(5000), network_status_sink); + + let display_notifications = network_status_stream .for_each(move |(net_status, _)| { - let info = client.usage_info(); + let info = client_1.usage_info(); if let Some(ref usage) = info.usage { trace!(target: "usage", "Usage statistics: {}", usage); } else { @@ -62,13 +116,30 @@ pub fn build(service: &impl AbstractService, format: OutputFormat) -> impl futur future::ready(()) }); - let client = service.client(); + future::join( + display_notifications, + display_block_import(client, format.prefix), + ).map(|_| ()) +} + +fn display_block_import( + client: Arc, + prefix: String, +) -> impl Future +where + C: UsageProvider + HeaderMetadata + BlockchainEvents, + >::Error: Display, +{ let mut last_best = { let info = client.usage_info(); Some((info.chain.best_number, info.chain.best_hash)) }; - let display_block_import = client.import_notification_stream().for_each(move |n| { + // Hashes of the last blocks we have seen at import. + let mut last_blocks = VecDeque::new(); + let max_blocks_to_track = 100; + + client.import_notification_stream().for_each(move |n| { // detect and log reorganizations. if let Some((ref last_num, ref last_hash)) = last_best { if n.header.parent_hash() != last_hash && n.is_new_best { @@ -80,7 +151,8 @@ pub fn build(service: &impl AbstractService, format: OutputFormat) -> impl futur match maybe_ancestor { Ok(ref ancestor) if ancestor.hash != *last_hash => info!( - "♻️ Reorg on #{},{} to #{},{}, common ancestor #{},{}", + "♻️ {}Reorg on #{},{} to #{},{}, common ancestor #{},{}", + prefix, Colour::Red.bold().paint(format!("{}", last_num)), last_hash, Colour::Green.bold().paint(format!("{}", n.header.number())), n.hash, Colour::White.bold().paint(format!("{}", ancestor.number)), ancestor.hash, @@ -95,12 +167,25 @@ pub fn build(service: &impl AbstractService, format: OutputFormat) -> impl futur last_best = Some((n.header.number().clone(), n.hash.clone())); } - info!(target: "substrate", "✨ Imported #{} ({})", Colour::White.bold().paint(format!("{}", n.header.number())), n.hash); - future::ready(()) - }); - future::join( - display_notifications, - display_block_import - ).map(|_| ()) + // If we already printed a message for a given block recently, + // we should not print it again. + if !last_blocks.contains(&n.hash) { + last_blocks.push_back(n.hash.clone()); + + if last_blocks.len() > max_blocks_to_track { + last_blocks.pop_front(); + } + + info!( + target: "substrate", + "✨ {}Imported #{} ({})", + prefix, + Colour::White.bold().paint(format!("{}", n.header.number())), + n.hash, + ); + } + + future::ready(()) + }) } diff --git a/client/keystore/Cargo.toml b/client/keystore/Cargo.toml index f3419f55e1dc3207db64bcee0544d65568f114e1..004d829bbfa0e76f60cf968153baf9cb169187b1 100644 --- a/client/keystore/Cargo.toml +++ b/client/keystore/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-keystore" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Keystore (and session key management) for ed25519 based chains like Polkadot." @@ -15,13 +15,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] derive_more = "0.99.2" -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-application-crypto = { version = "2.0.0-dev", path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-application-crypto = { version = "2.0.0-rc6", path = "../../primitives/application-crypto" } hex = "0.4.0" +merlin = { version = "2.0", default-features = false } +parking_lot = "0.10.0" rand = "0.7.2" serde_json = "1.0.41" subtle = "2.1.1" -parking_lot = "0.10.0" [dev-dependencies] tempfile = "3.1.0" diff --git a/client/keystore/README.md b/client/keystore/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9946a61d6fde65e8c0988d03c6d3e34b9d3d7bfb --- /dev/null +++ b/client/keystore/README.md @@ -0,0 +1,3 @@ +Keystore (and session key management) for ed25519 based chains like Polkadot. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/keystore/src/lib.rs b/client/keystore/src/lib.rs index f8bc93097113b300bc85373918021da742700221..f337f64d1c5f9d578942d09dc310d57a81b13674 100644 --- a/client/keystore/src/lib.rs +++ b/client/keystore/src/lib.rs @@ -19,11 +19,13 @@ #![warn(missing_docs)] use std::{collections::{HashMap, HashSet}, path::PathBuf, fs::{self, File}, io::{self, Write}, sync::Arc}; use sp_core::{ - crypto::{IsWrappedBy, CryptoTypePublicPair, KeyTypeId, Pair as PairT, Protected, Public}, - traits::{BareCryptoStore, BareCryptoStoreError as TraitError}, + crypto::{IsWrappedBy, CryptoTypePublicPair, KeyTypeId, Pair as PairT, ExposeSecret, SecretString, Public}, + traits::{BareCryptoStore, Error as TraitError}, + sr25519::{Public as Sr25519Public, Pair as Sr25519Pair}, + vrf::{VRFTranscriptData, VRFSignature, make_transcript}, Encode, }; -use sp_application_crypto::{AppKey, AppPublic, AppPair, ed25519, sr25519}; +use sp_application_crypto::{AppKey, AppPublic, AppPair, ed25519, sr25519, ecdsa}; use parking_lot::RwLock; /// Keystore pointer @@ -93,14 +95,14 @@ pub struct Store { path: Option, /// Map over `(KeyTypeId, Raw public key)` -> `Key phrase/seed` additional: HashMap<(KeyTypeId, Vec), String>, - password: Option>, + password: Option, } impl Store { /// Open the store at the given path. /// /// Optionally takes a password that will be used to encrypt/decrypt the keys. - pub fn open>(path: T, password: Option>) -> Result { + pub fn open>(path: T, password: Option) -> Result { let path = path.into(); fs::create_dir_all(&path)?; @@ -153,7 +155,7 @@ impl Store { pub fn insert_by_type(&self, key_type: KeyTypeId, suri: &str) -> Result { let pair = Pair::from_string( suri, - self.password.as_ref().map(|p| &***p) + self.password() ).map_err(|_| Error::InvalidSeed)?; self.insert_unknown(key_type, suri, pair.public().as_slice()) .map_err(|_| Error::Unavailable)?; @@ -171,7 +173,7 @@ impl Store { /// /// Places it into the file system store. pub fn generate_by_type(&self, key_type: KeyTypeId) -> Result { - let (pair, phrase, _) = Pair::generate_with_phrase(self.password.as_ref().map(|p| &***p)); + let (pair, phrase, _) = Pair::generate_with_phrase(self.password()); if let Some(path) = self.key_file_path(pair.public().as_slice(), key_type) { let mut file = File::create(path)?; serde_json::to_writer(&file, &phrase)?; @@ -227,7 +229,7 @@ impl Store { let phrase = self.key_phrase_by_type(public.as_slice(), key_type)?; let pair = Pair::from_string( &phrase, - self.password.as_ref().map(|p| &***p), + self.password(), ).map_err(|_| Error::InvalidPhrase)?; if &pair.public() == public { @@ -270,7 +272,7 @@ impl Store { fn raw_public_keys(&self, id: KeyTypeId) -> Result>> { let mut public_keys: Vec> = self.additional.keys() .into_iter() - .filter_map(|k| if k.0 == id { Some(k.1.clone()) } else { None }) + .filter_map(|k| if k.0 == id { Some(k.1.clone()) } else { None }) .collect(); if let Some(path) = &self.path { @@ -308,6 +310,7 @@ impl BareCryptoStore for Store { .fold(Vec::new(), |mut v, k| { v.push(CryptoTypePublicPair(sr25519::CRYPTO_ID, k.clone())); v.push(CryptoTypePublicPair(ed25519::CRYPTO_ID, k.clone())); + v.push(CryptoTypePublicPair(ecdsa::CRYPTO_ID, k)); v })) } @@ -343,6 +346,13 @@ impl BareCryptoStore for Store { .key_pair_by_type::(&pub_key, id) .map_err(|e| TraitError::from(e))?; Ok(key_pair.sign(msg).encode()) + }, + ecdsa::CRYPTO_ID => { + let pub_key = ecdsa::Public::from_slice(key.1.as_slice()); + let key_pair: ecdsa::Pair = self + .key_pair_by_type::(&pub_key, id) + .map_err(|e| TraitError::from(e))?; + Ok(key_pair.sign(msg).encode()) } _ => Err(TraitError::KeyNotSupported(id)) } @@ -355,7 +365,7 @@ impl BareCryptoStore for Store { .map(|k| sr25519::Public::from_slice(k.as_slice())) .collect() }) - .unwrap_or_default() + .unwrap_or_default() } fn sr25519_generate_new( @@ -394,6 +404,29 @@ impl BareCryptoStore for Store { Ok(pair.public()) } + fn ecdsa_public_keys(&self, key_type: KeyTypeId) -> Vec { + self.raw_public_keys(key_type) + .map(|v| { + v.into_iter() + .map(|k| ecdsa::Public::from_slice(k.as_slice())) + .collect() + }) + .unwrap_or_default() + } + + fn ecdsa_generate_new( + &mut self, + id: KeyTypeId, + seed: Option<&str>, + ) -> std::result::Result { + let pair = match seed { + Some(seed) => self.insert_ephemeral_from_seed_by_type::(seed, id), + None => self.generate_by_type::(id), + }.map_err(|e| -> TraitError { e.into() })?; + + Ok(pair.public()) + } + fn insert_unknown(&mut self, key_type: KeyTypeId, suri: &str, public: &[u8]) -> std::result::Result<(), ()> { @@ -401,12 +434,31 @@ impl BareCryptoStore for Store { } fn password(&self) -> Option<&str> { - self.password.as_ref().map(|x| x.as_str()) + self.password.as_ref() + .map(|p| p.expose_secret()) + .map(|p| p.as_str()) } fn has_keys(&self, public_keys: &[(Vec, KeyTypeId)]) -> bool { public_keys.iter().all(|(p, t)| self.key_phrase_by_type(&p, *t).is_ok()) } + + fn sr25519_vrf_sign( + &self, + key_type: KeyTypeId, + public: &Sr25519Public, + transcript_data: VRFTranscriptData, + ) -> std::result::Result { + let transcript = make_transcript(transcript_data); + let pair = self.key_pair_by_type::(public, key_type) + .map_err(|e| TraitError::PairNotFound(e.to_string()))?; + + let (inout, proof, _) = pair.as_ref().vrf_sign(transcript); + Ok(VRFSignature { + output: inout.to_output(), + proof, + }) + } } #[cfg(test)] @@ -414,6 +466,7 @@ mod tests { use super::*; use tempfile::TempDir; use sp_core::{testing::SR25519, crypto::Ss58Codec}; + use std::str::FromStr; #[test] fn basic_store() { @@ -454,7 +507,10 @@ mod tests { fn password_being_used() { let password = String::from("password"); let temp_dir = TempDir::new().unwrap(); - let store = Store::open(temp_dir.path(), Some(password.clone().into())).unwrap(); + let store = Store::open( + temp_dir.path(), + Some(FromStr::from_str(password.as_str()).unwrap()), + ).unwrap(); let pair: ed25519::AppPair = store.write().generate().unwrap(); assert_eq!( @@ -466,7 +522,10 @@ mod tests { let store = Store::open(temp_dir.path(), None).unwrap(); assert!(store.read().key_pair::(&pair.public()).is_err()); - let store = Store::open(temp_dir.path(), Some(password.into())).unwrap(); + let store = Store::open( + temp_dir.path(), + Some(FromStr::from_str(password.as_str()).unwrap()), + ).unwrap(); assert_eq!( pair.public(), store.read().key_pair::(&pair.public()).unwrap().public(), diff --git a/client/light/Cargo.toml b/client/light/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..23b306d178e3718a0218c76e50972643175ae295 --- /dev/null +++ b/client/light/Cargo.toml @@ -0,0 +1,27 @@ +[package] +description = "components for a light client" +name = "sc-light" +version = "2.0.0-rc6" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +authors = ["Parity Technologies "] +edition = "2018" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +documentation = "https://docs.rs/sc-light" + +[dependencies] +parking_lot = "0.10.0" +lazy_static = "1.4.0" +hash-db = "0.15.2" +sp-runtime = { version = "2.0.0-rc2", path = "../../primitives/runtime" } +sp-externalities = { version = "0.8.0-rc2", path = "../../primitives/externalities" } +sp-blockchain = { version = "2.0.0-rc2", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-rc2", path = "../../primitives/core" } +sp-state-machine = { version = "0.8.0-rc2", path = "../../primitives/state-machine" } +sc-client-api = { version = "2.0.0-rc2", path = "../api" } +sp-api = { version = "2.0.0-rc2", path = "../../primitives/api" } +codec = { package = "parity-scale-codec", version = "1.3.4" } +sc-executor = { version = "0.8.0-rc2", path = "../executor" } + +[features] +default = [] diff --git a/client/light/README.md b/client/light/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1ba1f155b16527ba11e3c39f12364bf530bdf480 --- /dev/null +++ b/client/light/README.md @@ -0,0 +1,3 @@ +Light client components. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/service/src/client/light/backend.rs b/client/light/src/backend.rs similarity index 91% rename from client/service/src/client/light/backend.rs rename to client/light/src/backend.rs index 78f3938aaa8285bc2dfb32829342794f133e567c..be7953e528bd828a31ffb1c40ee8388b9add7cbe 100644 --- a/client/service/src/client/light/backend.rs +++ b/client/light/src/backend.rs @@ -1,23 +1,25 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Light client backend. Only stores headers and justifications of blocks. //! Everything else is requested from full nodes on demand. -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::sync::Arc; use parking_lot::RwLock; @@ -144,7 +146,10 @@ impl ClientBackend for Backend> Ok(()) } - fn commit_operation(&self, mut operation: Self::BlockImportOperation) -> ClientResult<()> { + fn commit_operation( + &self, + mut operation: Self::BlockImportOperation, + ) -> ClientResult<()> { if !operation.finalized_blocks.is_empty() { for block in operation.finalized_blocks { self.blockchain.storage().finalize_header(block)?; @@ -229,7 +234,7 @@ impl ClientBackend for Backend> &self, _n: NumberFor, _revert_finalized: bool, - ) -> ClientResult> { + ) -> ClientResult<(NumberFor, HashSet)> { Err(ClientError::NotAvailableOnLightClient) } @@ -316,12 +321,12 @@ impl BlockImportOperation for ImportOperation storage.insert(None, input.top); // create a list of children keys to re-compute roots for - let child_delta = input.children_default.iter() - .map(|(_storage_key, storage_child)| (storage_child.child_info.clone(), None)) - .collect::>(); + let child_delta = input.children_default + .iter() + .map(|(_storage_key, storage_child)| (&storage_child.child_info, std::iter::empty())); // make sure to persist the child storage - for (_child_key, storage_child) in input.children_default { + for (_child_key, storage_child) in input.children_default.clone() { storage.insert(Some(storage_child.child_info), storage_child.data); } @@ -348,7 +353,11 @@ impl BlockImportOperation for ImportOperation Ok(()) } - fn mark_finalized(&mut self, block: BlockId, _justification: Option) -> ClientResult<()> { + fn mark_finalized( + &mut self, + block: BlockId, + _justification: Option, + ) -> ClientResult<()> { self.finalized_blocks.push(block); Ok(()) } @@ -457,10 +466,10 @@ impl StateBackend for GenesisOrUnavailableState } } - fn storage_root(&self, delta: I) -> (H::Out, Self::Transaction) - where - I: IntoIterator, Option>)> - { + fn storage_root<'a>( + &self, + delta: impl Iterator)>, + ) -> (H::Out, Self::Transaction) where H::Out: Ord { match *self { GenesisOrUnavailableState::Genesis(ref state) => state.storage_root(delta), @@ -468,14 +477,11 @@ impl StateBackend for GenesisOrUnavailableState } } - fn child_storage_root( + fn child_storage_root<'a>( &self, child_info: &ChildInfo, - delta: I, - ) -> (H::Out, bool, Self::Transaction) - where - I: IntoIterator, Option>)> - { + delta: impl Iterator)>, + ) -> (H::Out, bool, Self::Transaction) where H::Out: Ord { match *self { GenesisOrUnavailableState::Genesis(ref state) => { let (root, is_equal, _) = state.child_storage_root(child_info, delta); diff --git a/client/service/src/client/light/blockchain.rs b/client/light/src/blockchain.rs similarity index 90% rename from client/service/src/client/light/blockchain.rs rename to client/light/src/blockchain.rs index b6ccb4744b55907bff952cf6eba0753d72144394..9d557db887d2990549106b5436d0e043ca06a66b 100644 --- a/client/service/src/client/light/blockchain.rs +++ b/client/light/src/blockchain.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Light client blockchain backend. Only stores headers and justifications of recent //! blocks. CHT roots are stored for headers of ancient blocks. @@ -23,8 +25,7 @@ use sp_runtime::{Justification, generic::BlockId}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor, Zero}; use sp_blockchain::{ - HeaderMetadata, CachedHeaderMetadata, - Error as ClientError, Result as ClientResult, + HeaderMetadata, CachedHeaderMetadata, Error as ClientError, Result as ClientResult, }; pub use sc_client_api::{ backend::{ @@ -40,7 +41,7 @@ pub use sc_client_api::{ }, cht, }; -use super::fetcher::RemoteHeaderRequest; +use crate::fetcher::RemoteHeaderRequest; /// Light client blockchain. pub struct Blockchain { diff --git a/client/service/src/client/light/call_executor.rs b/client/light/src/call_executor.rs similarity index 91% rename from client/service/src/client/light/call_executor.rs rename to client/light/src/call_executor.rs index 54fcf8e8f7f4c3d6b0e33c32e03d49a5f511eb79..fa0f02cd5aed914e9b93608f73e08260339bed00 100644 --- a/client/service/src/client/light/call_executor.rs +++ b/client/light/src/call_executor.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Methods that light client could use to execute runtime calls. @@ -21,14 +23,17 @@ use std::{ }; use codec::{Encode, Decode}; -use sp_core::{convert_hash, NativeOrEncoded, traits::CodeExecutor, offchain::storage::OffchainOverlayedChanges}; +use sp_core::{ + convert_hash, NativeOrEncoded, traits::{CodeExecutor, SpawnNamed}, + offchain::storage::OffchainOverlayedChanges, +}; use sp_runtime::{ generic::BlockId, traits::{One, Block as BlockT, Header as HeaderT, HashFor}, }; use sp_externalities::Extensions; use sp_state_machine::{ self, Backend as StateBackend, OverlayedChanges, ExecutionStrategy, create_proof_check_backend, - execution_proof_check_on_trie_backend, ExecutionManager, StorageProof, CloneableSpawn, + execution_proof_check_on_trie_backend, ExecutionManager, StorageProof, }; use hash_db::Hasher; @@ -218,7 +223,7 @@ pub fn prove_execution( /// Proof should include both environment preparation proof and method execution proof. pub fn check_execution_proof( executor: &E, - spawn_handle: Box, + spawn_handle: Box, request: &RemoteCallRequest

, remote_proof: StorageProof, ) -> ClientResult> @@ -249,7 +254,7 @@ pub fn check_execution_proof( /// Proof should include both environment preparation proof and method execution proof. pub fn check_execution_proof_with_make_header( executor: &E, - spawn_handle: Box, + spawn_handle: Box, request: &RemoteCallRequest
, remote_proof: StorageProof, make_next_header: MakeNextHeader, @@ -273,7 +278,7 @@ pub fn check_execution_proof_with_make_header( let backend_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&trie_backend); let runtime_code = backend_runtime_code.runtime_code()?; - execution_proof_check_on_trie_backend::( + execution_proof_check_on_trie_backend::( &trie_backend, &mut changes, executor, @@ -284,7 +289,7 @@ pub fn check_execution_proof_with_make_header( )?; // execute method - execution_proof_check_on_trie_backend::( + execution_proof_check_on_trie_backend::( &trie_backend, &mut changes, executor, diff --git a/client/service/src/client/light/fetcher.rs b/client/light/src/fetcher.rs similarity index 93% rename from client/service/src/client/light/fetcher.rs rename to client/light/src/fetcher.rs index ae64565a504d1e3e90d2a3f4892ca69ac0b11069..33113c2fc7df0de727d8cf0db95c42a51b74af12 100644 --- a/client/service/src/client/light/fetcher.rs +++ b/client/light/src/fetcher.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Light client data fetcher. Fetches requested data from remote full nodes. @@ -22,8 +24,7 @@ use std::marker::PhantomData; use hash_db::{HashDB, Hasher, EMPTY_PREFIX}; use codec::{Decode, Encode}; -use sp_core::{convert_hash, traits::CodeExecutor}; -use sp_core::storage::{ChildInfo, ChildType}; +use sp_core::{convert_hash, traits::{CodeExecutor, SpawnNamed}, storage::{ChildInfo, ChildType}}; use sp_runtime::traits::{ Block as BlockT, Header as HeaderT, Hash, HashFor, NumberFor, AtLeast32Bit, CheckedConversion, @@ -31,7 +32,7 @@ use sp_runtime::traits::{ use sp_state_machine::{ ChangesTrieRootsStorage, ChangesTrieAnchorBlockId, ChangesTrieConfigurationRange, InMemoryChangesTrieStorage, TrieBackend, read_proof_check, key_changes_proof_check_with_db, - read_child_proof_check, CloneableSpawn, + read_child_proof_check, }; pub use sp_state_machine::StorageProof; use sp_blockchain::{Error as ClientError, Result as ClientResult}; @@ -44,20 +45,23 @@ pub use sc_client_api::{ }, cht, }; -use super::blockchain::{Blockchain}; -use super::call_executor::check_execution_proof; +use crate::{blockchain::Blockchain, call_executor::check_execution_proof}; /// Remote data checker. pub struct LightDataChecker> { blockchain: Arc>, executor: E, - spawn_handle: Box, + spawn_handle: Box, _hasher: PhantomData<(B, H)>, } impl> LightDataChecker { /// Create new light data checker. - pub fn new(blockchain: Arc>, executor: E, spawn_handle: Box) -> Self { + pub fn new( + blockchain: Arc>, + executor: E, + spawn_handle: Box, + ) -> Self { Self { blockchain, executor, spawn_handle, _hasher: PhantomData } diff --git a/client/light/src/lib.rs b/client/light/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..899d1ae31a3dd951a89090a0ed69cc6e5fb71f5f --- /dev/null +++ b/client/light/src/lib.rs @@ -0,0 +1,56 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +//! Light client components. + +use sp_runtime::traits::{Block as BlockT, HashFor}; +use std::sync::Arc; +use sp_core::traits::{CodeExecutor, SpawnNamed}; + +pub mod backend; +pub mod blockchain; +pub mod call_executor; +pub mod fetcher; + +pub use {backend::*, blockchain::*, call_executor::*, fetcher::*}; + +/// Create an instance of fetch data checker. +pub fn new_fetch_checker>( + blockchain: Arc>, + executor: E, + spawn_handle: Box, +) -> LightDataChecker, B, S> + where + E: CodeExecutor, +{ + LightDataChecker::new(blockchain, executor, spawn_handle) +} + +/// Create an instance of light client blockchain backend. +pub fn new_light_blockchain>(storage: S) -> Arc> { + Arc::new(Blockchain::new(storage)) +} + +/// Create an instance of light client backend. +pub fn new_light_backend(blockchain: Arc>) -> Arc>> + where + B: BlockT, + S: BlockchainStorage, +{ + Arc::new(Backend::new(blockchain)) +} diff --git a/client/network-gossip/Cargo.toml b/client/network-gossip/Cargo.toml index 4b02a6f70e8b56ab5b295333168e6a8872f920d9..f826bb88bade221d871e1c9a63242d189d733d77 100644 --- a/client/network-gossip/Cargo.toml +++ b/client/network-gossip/Cargo.toml @@ -1,8 +1,8 @@ [package] description = "Gossiping for the Substrate network protocol" name = "sc-network-gossip" -version = "0.8.0-dev" -license = "GPL-3.0" +version = "0.8.0-rc6" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" authors = ["Parity Technologies "] edition = "2018" homepage = "https://substrate.dev" @@ -16,15 +16,15 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" futures-timer = "3.0.1" -libp2p = { version = "0.18.1", default-features = false, features = ["websocket"] } +libp2p = { version = "0.24.0", default-features = false } log = "0.4.8" lru = "0.4.3" -sc-network = { version = "0.8.0-dev", path = "../network" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sc-network = { version = "0.8.0-rc6", path = "../network" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } wasm-timer = "0.2" [dev-dependencies] -async-std = "1.5" +async-std = "1.6.2" quickcheck = "0.9.0" rand = "0.7.2" -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client" } diff --git a/client/network-gossip/README.md b/client/network-gossip/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9030fac056407aada04522af786058f8f75d8718 --- /dev/null +++ b/client/network-gossip/README.md @@ -0,0 +1,41 @@ +Polite gossiping. + +This crate provides gossiping capabilities on top of a network. + +Gossip messages are separated by two categories: "topics" and consensus engine ID. +The consensus engine ID is sent over the wire with the message, while the topic is not, +with the expectation that the topic can be derived implicitly from the content of the +message, assuming it is valid. + +Topics are a single 32-byte tag associated with a message, used to group those messages +in an opaque way. Consensus code can invoke `broadcast_topic` to attempt to send all messages +under a single topic to all peers who don't have them yet, and `send_topic` to +send all messages under a single topic to a specific peer. + +# Usage + +- Implement the `Network` trait, representing the low-level networking primitives. It is + already implemented on `sc_network::NetworkService`. +- Implement the `Validator` trait. See the section below. +- Decide on a `ConsensusEngineId`. Each gossiping protocol should have a different one. +- Build a `GossipEngine` using these three elements. +- Use the methods of the `GossipEngine` in order to send out messages and receive incoming + messages. + +# What is a validator? + +The primary role of a `Validator` is to process incoming messages from peers, and decide +whether to discard them or process them. It also decides whether to re-broadcast the message. + +The secondary role of the `Validator` is to check if a message is allowed to be sent to a given +peer. All messages, before being sent, will be checked against this filter. +This enables the validator to use information it's aware of about connected peers to decide +whether to send messages to them at any given moment in time - In particular, to wait until +peers can accept and process the message before sending it. + +Lastly, the fact that gossip validators can decide not to rebroadcast messages +opens the door for neighbor status packets to be baked into the gossip protocol. +These status packets will typically contain light pieces of information +used to inform peers of a current view of protocol state. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/network-gossip/src/state_machine.rs b/client/network-gossip/src/state_machine.rs index 433457afe748e422c78c0a2d5bde7c2af54c173c..80a0f9e70bcbfcaee7f8bc812aa17ba2721bc45c 100644 --- a/client/network-gossip/src/state_machine.rs +++ b/client/network-gossip/src/state_machine.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::{Network, MessageIntent, Validator, ValidatorContext, ValidationResult}; @@ -178,7 +180,7 @@ impl ConsensusGossip { let validator = self.validator.clone(); let mut context = NetworkContext { gossip: self, network }; - validator.new_peer(&mut context, &who, role.clone()); + validator.new_peer(&mut context, &who, role); } fn register_message_hashed( diff --git a/client/network-gossip/src/validator.rs b/client/network-gossip/src/validator.rs index 6b330d7b618c0e702e52cc330ed2bd77b3ffdbdd..fd29aaddafe6dcd89f2e722bdcfa07854fc04225 100644 --- a/client/network-gossip/src/validator.rs +++ b/client/network-gossip/src/validator.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use sc_network::{ObservedRole, PeerId}; use sp_runtime::traits::Block as BlockT; diff --git a/client/network/Cargo.toml b/client/network/Cargo.toml index e31e0f3113236abcd58af3029a077ce763c4b033..de885bc65a45c1ca22216c87a32e23679f76dcab 100644 --- a/client/network/Cargo.toml +++ b/client/network/Cargo.toml @@ -1,34 +1,34 @@ [package] description = "Substrate network protocol" name = "sc-network" -version = "0.8.0-dev" -license = "GPL-3.0" +version = "0.8.0-rc6" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" authors = ["Parity Technologies "] edition = "2018" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sc-network" - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] - [build-dependencies] prost-build = "0.6.1" [dependencies] +async-std = { version = "1.6.2", features = ["unstable"] } bitflags = "1.2.0" +bs58 = "0.3.1" bytes = "0.5.0" -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } derive_more = "0.99.2" either = "1.5.3" erased-serde = "0.3.9" fnv = "1.0.6" -fork-tree = { version = "2.0.0-dev", path = "../../utils/fork-tree" } +fork-tree = { version = "2.0.0-rc6", path = "../../utils/fork-tree" } futures = "0.3.4" -futures-timer = "3.0.1" -futures_codec = "0.3.3" +futures-timer = "3.0.2" +futures_codec = "0.4.0" hex = "0.4.0" ip_network = "0.3.4" linked-hash-map = "0.5.2" @@ -38,45 +38,44 @@ lru = "0.4.0" nohash-hasher = "0.2.0" parking_lot = "0.10.0" pin-project = "0.4.6" -prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-dev", path = "../../utils/prometheus" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.8.0-rc6", path = "../../utils/prometheus" } prost = "0.6.1" rand = "0.7.2" -sc-block-builder = { version = "0.8.0-dev", path = "../block-builder" } -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sc-peerset = { version = "2.0.0-dev", path = "../peerset" } +sc-block-builder = { version = "0.8.0-rc6", path = "../block-builder" } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sc-peerset = { version = "2.0.0-rc6", path = "../peerset" } serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } slog_derive = "0.2.0" smallvec = "0.6.10" -sp-arithmetic = { version = "2.0.0-dev", path = "../../primitives/arithmetic" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +sp-arithmetic = { version = "2.0.0-rc6", path = "../../primitives/arithmetic" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-rc6", path = "../../primitives/consensus/common" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-rc6", path = "../../primitives/utils" } thiserror = "1" -unsigned-varint = { version = "0.3.1", features = ["futures", "futures-codec"] } +unsigned-varint = { version = "0.4.0", features = ["futures", "futures-codec"] } void = "1.0.2" wasm-timer = "0.2" zeroize = "1.0.0" [dependencies.libp2p] -version = "0.18.1" +version = "0.24.0" default-features = false -features = ["websocket", "kad", "mdns", "ping", "identify", "mplex", "yamux", "noise"] +features = ["identify", "kad", "mdns-async-std", "mplex", "noise", "ping", "tcp-async-std", "websocket", "yamux"] [dev-dependencies] -async-std = "1.5" assert_matches = "1.3" env_logger = "0.7.0" -libp2p = { version = "0.18.1", default-features = false, features = ["secio"] } +libp2p = { version = "0.24.0", default-features = false, features = ["secio"] } quickcheck = "0.9.0" rand = "0.7.2" -sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } -sp-test-primitives = { version = "2.0.0-dev", path = "../../primitives/test-primitives" } -substrate-test-runtime = { version = "2.0.0-dev", path = "../../test-utils/runtime" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } +sp-keyring = { version = "2.0.0-rc6", path = "../../primitives/keyring" } +sp-test-primitives = { version = "2.0.0-rc6", path = "../../primitives/test-primitives" } +substrate-test-runtime = { version = "2.0.0-rc6", path = "../../test-utils/runtime" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client" } tempfile = "3.1.0" [features] diff --git a/client/network/README.md b/client/network/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e0bd691043bee3184be7745144fc06665cade72d --- /dev/null +++ b/client/network/README.md @@ -0,0 +1,226 @@ +Substrate-specific P2P networking. + +**Important**: This crate is unstable and the API and usage may change. + +# Node identities and addresses + +In a decentralized network, each node possesses a network private key and a network public key. +In Substrate, the keys are based on the ed25519 curve. + +From a node's public key, we can derive its *identity*. In Substrate and libp2p, a node's +identity is represented with the [`PeerId`] struct. All network communications between nodes on +the network use encryption derived from both sides's keys, which means that **identities cannot +be faked**. + +A node's identity uniquely identifies a machine on the network. If you start two or more +clients using the same network key, large interferences will happen. + +# Substrate's network protocol + +Substrate's networking protocol is based upon libp2p. It is at the moment not possible and not +planned to permit using something else than the libp2p network stack and the rust-libp2p +library. However the libp2p framework is very flexible and the rust-libp2p library could be +extended to support a wider range of protocols than what is offered by libp2p. + +## Discovery mechanisms + +In order for our node to join a peer-to-peer network, it has to know a list of nodes that are +part of said network. This includes nodes identities and their address (how to reach them). +Building such a list is called the **discovery** mechanism. There are three mechanisms that +Substrate uses: + +- Bootstrap nodes. These are hard-coded node identities and addresses passed alongside with +the network configuration. +- mDNS. We perform a UDP broadcast on the local network. Nodes that listen may respond with +their identity. More info [here](https://github.com/libp2p/specs/blob/master/discovery/mdns.md). +mDNS can be disabled in the network configuration. +- Kademlia random walk. Once connected, we perform random Kademlia `FIND_NODE` requests on the +configured Kademlia DHTs (one per configured chain protocol) in order for nodes to propagate to +us their view of the network. More information about Kademlia can be found [on +Wikipedia](https://en.wikipedia.org/wiki/Kademlia). + +## Connection establishment + +When node Alice knows node Bob's identity and address, it can establish a connection with Bob. +All connections must always use encryption and multiplexing. While some node addresses (eg. +addresses using `/quic`) already imply which encryption and/or multiplexing to use, for others +the **multistream-select** protocol is used in order to negotiate an encryption layer and/or a +multiplexing layer. + +The connection establishment mechanism is called the **transport**. + +As of the writing of this documentation, the following base-layer protocols are supported by +Substrate: + +- TCP/IP for addresses of the form `/ip4/1.2.3.4/tcp/5`. Once the TCP connection is open, an +encryption and a multiplexing layer are negotiated on top. +- WebSockets for addresses of the form `/ip4/1.2.3.4/tcp/5/ws`. A TCP/IP connection is open and +the WebSockets protocol is negotiated on top. Communications then happen inside WebSockets data +frames. Encryption and multiplexing are additionally negotiated again inside this channel. +- DNS for addresses of the form `/dns/example.com/tcp/5` or `/dns/example.com/tcp/5/ws`. A +node's address can contain a domain name. +- (All of the above using IPv6 instead of IPv4.) + +On top of the base-layer protocol, the [Noise](https://noiseprotocol.org/) protocol is +negotiated and applied. The exact handshake protocol is experimental and is subject to change. + +The following multiplexing protocols are supported: + +- [Mplex](https://github.com/libp2p/specs/tree/master/mplex). Support for mplex will likely +be deprecated in the future. +- [Yamux](https://github.com/hashicorp/yamux/blob/master/spec.md). + +## Substreams + +Once a connection has been established and uses multiplexing, substreams can be opened. When +a substream is open, the **multistream-select** protocol is used to negotiate which protocol +to use on that given substream. + +Protocols that are specific to a certain chain have a `` in their name. This +"protocol ID" is defined in the chain specifications. For example, the protocol ID of Polkadot +is "dot". In the protocol names below, `` must be replaced with the corresponding +protocol ID. + +> **Note**: It is possible for the same connection to be used for multiple chains. For example, +> one can use both the `/dot/sync/2` and `/sub/sync/2` protocols on the same +> connection, provided that the remote supports them. + +Substrate uses the following standard libp2p protocols: + +- **`/ipfs/ping/1.0.0`**. We periodically open an ephemeral substream in order to ping the +remote and check whether the connection is still alive. Failure for the remote to reply leads +to a disconnection. +- **[`/ipfs/id/1.0.0`](https://github.com/libp2p/specs/tree/master/identify)**. We +periodically open an ephemeral substream in order to ask information from the remote. +- **[`//kad`](https://github.com/libp2p/specs/pull/108)**. We periodically open +ephemeral substreams for Kademlia random walk queries. Each Kademlia query is done in a +separate substream. + +Additionally, Substrate uses the following non-libp2p-standard protocols: + +- **`/substrate//`** (where `` must be replaced with the +protocol ID of the targeted chain, and `` is a number between 2 and 6). For each +connection we optionally keep an additional substream for all Substrate-based communications alive. +This protocol is considered legacy, and is progressively being replaced with alternatives. +This is designated as "The legacy Substrate substream" in this documentation. See below for +more details. +- **`//sync/2`** is a request-response protocol (see below) that lets one perform +requests for information about blocks. Each request is the encoding of a `BlockRequest` and +each response is the encoding of a `BlockResponse`, as defined in the `api.v1.proto` file in +this source tree. +- **`//light/2`** is a request-response protocol (see below) that lets one perform +light-client-related requests for information about the state. Each request is the encoding of +a `light::Request` and each response is the encoding of a `light::Response`, as defined in the +`light.v1.proto` file in this source tree. +- **`//transactions/1`** is a notifications protocol (see below) where +transactions are pushed to other nodes. The handshake is empty on both sides. The message +format is a SCALE-encoded list of transactions, where each transaction is an opaque list of +bytes. +- **`//block-announces/1`** is a notifications protocol (see below) where +block announces are pushed to other nodes. The handshake is empty on both sides. The message +format is a SCALE-encoded tuple containing a block header followed with an opaque list of +bytes containing some data associated with this block announcement, e.g. a candidate message. +- Notifications protocols that are registered using the `register_notifications_protocol` +method. For example: `/paritytech/grandpa/1`. See below for more information. + +## The legacy Substrate substream + +Substrate uses a component named the **peerset manager (PSM)**. Through the discovery +mechanism, the PSM is aware of the nodes that are part of the network and decides which nodes +we should perform Substrate-based communications with. For these nodes, we open a connection +if necessary and open a unique substream for Substrate-based communications. If the PSM decides +that we should disconnect a node, then that substream is closed. + +For more information about the PSM, see the *sc-peerset* crate. + +Note that at the moment there is no mechanism in place to solve the issues that arise where the +two sides of a connection open the unique substream simultaneously. In order to not run into +issues, only the dialer of a connection is allowed to open the unique substream. When the +substream is closed, the entire connection is closed as well. This is a bug that will be +resolved by deprecating the protocol entirely. + +Within the unique Substrate substream, messages encoded using +[*parity-scale-codec*](https://github.com/paritytech/parity-scale-codec) are exchanged. +The detail of theses messages is not totally in place, but they can be found in the +`message.rs` file. + +Once the substream is open, the first step is an exchange of a *status* message from both +sides, containing information such as the chain root hash, head of chain, and so on. + +Communications within this substream include: + +- Syncing. Blocks are announced and requested from other nodes. +- Light-client requests. When a light client requires information, a random node we have a +substream open with is chosen, and the information is requested from it. +- Gossiping. Used for example by grandpa. + +## Request-response protocols + +A so-called request-response protocol is defined as follow: + +- When a substream is opened, the opening side sends a message whose content is +protocol-specific. The message must be prefixed with an +[LEB128-encoded number](https://en.wikipedia.org/wiki/LEB128) indicating its length. After the +message has been sent, the writing side is closed. +- The remote sends back the response prefixed with a LEB128-encoded length, and closes its +side as well. + +Each request is performed in a new separate substream. + +## Notifications protocols + +A so-called notifications protocol is defined as follow: + +- When a substream is opened, the opening side sends a handshake message whose content is +protocol-specific. The handshake message must be prefixed with an +[LEB128-encoded number](https://en.wikipedia.org/wiki/LEB128) indicating its length. The +handshake message can be of length 0, in which case the sender has to send a single `0`. +- The receiver then either immediately closes the substream, or answers with its own +LEB128-prefixed protocol-specific handshake response. The message can be of length 0, in which +case a single `0` has to be sent back. +- Once the handshake has completed, the notifications protocol is unidirectional. Only the +node which initiated the substream can push notifications. If the remote wants to send +notifications as well, it has to open its own undirectional substream. +- Each notification must be prefixed with an LEB128-encoded length. The encoding of the +messages is specific to each protocol. +- Either party can signal that it doesn't want a notifications substream anymore by closing +its writing side. The other party should respond by closing its own writing side soon after. + +The API of `sc-network` allows one to register user-defined notification protocols. +`sc-network` automatically tries to open a substream towards each node for which the legacy +Substream substream is open. The handshake is then performed automatically. + +For example, the `sc-finality-grandpa` crate registers the `/paritytech/grandpa/1` +notifications protocol. + +At the moment, for backwards-compatibility, notification protocols are tied to the legacy +Substrate substream. Additionally, the handshake message is hardcoded to be a single 8-bits +integer representing the role of the node: + +- 1 for a full node. +- 2 for a light node. +- 4 for an authority. + +In the future, though, these restrictions will be removed. + +# Usage + +Using the `sc-network` crate is done through the [`NetworkWorker`] struct. Create this +struct by passing a [`config::Params`], then poll it as if it was a `Future`. You can extract an +`Arc` from the `NetworkWorker`, which can be shared amongst multiple places +in order to give orders to the networking. + +See the [`config`] module for more information about how to configure the networking. + +After the `NetworkWorker` has been created, the important things to do are: + +- Calling `NetworkWorker::poll` in order to advance the network. This can be done by +dispatching a background task with the [`NetworkWorker`]. +- Calling `on_block_import` whenever a block is added to the client. +- Calling `on_block_finalized` whenever a block is finalized. +- Calling `trigger_repropagate` when a transaction is added to the pool. + +More precise usage details are still being worked on and will likely change in the future. + + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/network/src/behaviour.rs b/client/network/src/behaviour.rs index 656743ef7f72d3b3ce2a018a72e9fa75dbcbc2b6..a43c61054d974b06d47d11509f3cd9a745dab5bd 100644 --- a/client/network/src/behaviour.rs +++ b/client/network/src/behaviour.rs @@ -16,20 +16,28 @@ use crate::{ config::{ProtocolId, Role}, block_requests, light_client_handler, finality_requests, - debug_info, discovery::{DiscoveryBehaviour, DiscoveryConfig, DiscoveryOut}, - protocol::{message::{self, Roles}, CustomMessageOutcome, Protocol}, - Event, ObservedRole, DhtEvent, ExHashT, + peer_info, discovery::{DiscoveryBehaviour, DiscoveryConfig, DiscoveryOut}, + protocol::{message::{self, Roles}, CustomMessageOutcome, NotificationsSink, Protocol}, + ObservedRole, DhtEvent, ExHashT, }; +use bytes::Bytes; use codec::Encode as _; use libp2p::NetworkBehaviour; use libp2p::core::{Multiaddr, PeerId, PublicKey}; +use libp2p::identify::IdentifyInfo; use libp2p::kad::record; use libp2p::swarm::{NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters}; use log::debug; use sp_consensus::{BlockOrigin, import_queue::{IncomingBlock, Origin}}; use sp_runtime::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId, Justification}; -use std::{borrow::Cow, collections::VecDeque, iter, task::{Context, Poll}, time::Duration}; +use std::{ + borrow::Cow, + collections::{HashSet, VecDeque}, + iter, + task::{Context, Poll}, + time::Duration, +}; /// General behaviour of the network. Combines all protocols together. #[derive(NetworkBehaviour)] @@ -39,7 +47,7 @@ pub struct Behaviour { substrate: Protocol, /// Periodically pings and identifies the nodes we are connected to, and store information in a /// cache. - debug_info: debug_info::DebugInfoBehaviour, + peer_info: peer_info::PeerInfoBehaviour, /// Discovers nodes of the network. discovery: DiscoveryBehaviour, /// Block request handling. @@ -92,11 +100,54 @@ pub enum BehaviourOut { request_duration: Duration, }, - /// Any event represented by the [`Event`] enum. + /// Opened a substream with the given node with the given notifications protocol. + /// + /// The protocol is always one of the notification protocols that have been registered. + NotificationStreamOpened { + /// Node we opened the substream with. + remote: PeerId, + /// The concerned protocol. Each protocol uses a different substream. + engine_id: ConsensusEngineId, + /// Object that permits sending notifications to the peer. + notifications_sink: NotificationsSink, + /// Role of the remote. + role: ObservedRole, + }, + + /// The [`NotificationsSink`] object used to send notifications with the given peer must be + /// replaced with a new one. /// - /// > **Note**: The [`Event`] enum contains the events that are available through the public - /// > API of the library. - Event(Event), + /// This event is typically emitted when a transport-level connection is closed and we fall + /// back to a secondary connection. + NotificationStreamReplaced { + /// Id of the peer we are connected to. + remote: PeerId, + /// The concerned protocol. Each protocol uses a different substream. + engine_id: ConsensusEngineId, + /// Replacement for the previous [`NotificationsSink`]. + notifications_sink: NotificationsSink, + }, + + /// Closed a substream with the given node. Always matches a corresponding previous + /// `NotificationStreamOpened` message. + NotificationStreamClosed { + /// Node we closed the substream with. + remote: PeerId, + /// The concerned protocol. Each protocol uses a different substream. + engine_id: ConsensusEngineId, + }, + + /// Received one or more messages from the given node using the given protocol. + NotificationsReceived { + /// Node we received the message from. + remote: PeerId, + /// Concerned protocol and associated message. + messages: Vec<(ConsensusEngineId, Bytes)>, + }, + + /// Events generated by a DHT as a response to get_value or put_value requests as well as the + /// request duration. + Dht(DhtEvent, Duration), } impl Behaviour { @@ -113,7 +164,7 @@ impl Behaviour { ) -> Self { Behaviour { substrate, - debug_info: debug_info::DebugInfoBehaviour::new(user_agent, local_public_key.clone()), + peer_info: peer_info::PeerInfoBehaviour::new(user_agent, local_public_key), discovery: disco_config.finish(), block_requests, finality_proof_requests, @@ -124,7 +175,7 @@ impl Behaviour { } /// Returns the list of nodes that we know exist in the network. - pub fn known_peers(&mut self) -> impl Iterator { + pub fn known_peers(&mut self) -> HashSet { self.discovery.known_peers() } @@ -153,14 +204,12 @@ impl Behaviour { /// Returns `None` if we don't know anything about this node. Always returns `Some` for nodes /// we're connected to, meaning that if `None` is returned then we're not connected to that /// node. - pub fn node(&self, peer_id: &PeerId) -> Option { - self.debug_info.node(peer_id) + pub fn node(&self, peer_id: &PeerId) -> Option { + self.peer_info.node(peer_id) } /// Registers a new notifications protocol. /// - /// After that, you can call `write_notifications`. - /// /// Please call `event_stream` before registering a protocol, otherwise you may miss events /// about the protocol that you have registered. /// @@ -176,14 +225,14 @@ impl Behaviour { let handshake_message = Roles::from(&self.role).encode(); let list = self.substrate.register_notifications_protocol(engine_id, protocol_name, handshake_message); - for (remote, roles) in list { + for (remote, roles, notifications_sink) in list { let role = reported_roles_to_observed_role(&self.role, remote, roles); - let ev = Event::NotificationStreamOpened { + self.events.push_back(BehaviourOut::NotificationStreamOpened { remote: remote.clone(), engine_id, role, - }; - self.events.push_back(BehaviourOut::Event(ev)); + notifications_sink: notifications_sink.clone(), + }); } } @@ -272,26 +321,34 @@ Behaviour { CustomMessageOutcome::FinalityProofRequest { target, block_hash, request } => { self.finality_proof_requests.send_request(&target, block_hash, request); }, - CustomMessageOutcome::NotificationStreamOpened { remote, protocols, roles } => { + CustomMessageOutcome::NotificationStreamOpened { remote, protocols, roles, notifications_sink } => { let role = reported_roles_to_observed_role(&self.role, &remote, roles); for engine_id in protocols { - self.events.push_back(BehaviourOut::Event(Event::NotificationStreamOpened { + self.events.push_back(BehaviourOut::NotificationStreamOpened { remote: remote.clone(), engine_id, role: role.clone(), - })); + notifications_sink: notifications_sink.clone(), + }); } }, + CustomMessageOutcome::NotificationStreamReplaced { remote, protocols, notifications_sink } => + for engine_id in protocols { + self.events.push_back(BehaviourOut::NotificationStreamReplaced { + remote: remote.clone(), + engine_id, + notifications_sink: notifications_sink.clone(), + }); + }, CustomMessageOutcome::NotificationStreamClosed { remote, protocols } => for engine_id in protocols { - self.events.push_back(BehaviourOut::Event(Event::NotificationStreamClosed { + self.events.push_back(BehaviourOut::NotificationStreamClosed { remote: remote.clone(), engine_id, - })); + }); }, CustomMessageOutcome::NotificationsReceived { remote, messages } => { - let ev = Event::NotificationsReceived { remote, messages }; - self.events.push_back(BehaviourOut::Event(ev)); + self.events.push_back(BehaviourOut::NotificationsReceived { remote, messages }); }, CustomMessageOutcome::PeerNewBest(peer_id, number) => { self.light_client_handler.update_best_block(&peer_id, number); @@ -311,13 +368,13 @@ impl NetworkBehaviourEventProcess { + block_requests::Event::Response { peer, original_request: _, response, request_duration } => { self.events.push_back(BehaviourOut::RequestFinished { peer: peer.clone(), protocol: self.block_requests.protocol_name().to_vec(), request_duration, }); - let ev = self.substrate.on_block_response(peer, original_request, response); + let ev = self.substrate.on_block_response(peer, response); self.inject_event(ev); } block_requests::Event::RequestCancelled { peer, request_duration, .. } | @@ -355,21 +412,33 @@ impl NetworkBehaviourEventProcess NetworkBehaviourEventProcess +impl NetworkBehaviourEventProcess for Behaviour { - fn inject_event(&mut self, event: debug_info::DebugInfoEvent) { - let debug_info::DebugInfoEvent::Identified { peer_id, mut info } = event; - if info.listen_addrs.len() > 30 { - debug!(target: "sub-libp2p", "Node {:?} has reported more than 30 addresses; \ - it is identified by {:?} and {:?}", peer_id, info.protocol_version, - info.agent_version + fn inject_event(&mut self, event: peer_info::PeerInfoEvent) { + let peer_info::PeerInfoEvent::Identified { + peer_id, + info: IdentifyInfo { + protocol_version, + agent_version, + mut listen_addrs, + protocols, + .. + }, + } = event; + + if listen_addrs.len() > 30 { + debug!( + target: "sub-libp2p", + "Node {:?} has reported more than 30 addresses; it is identified by {:?} and {:?}", + peer_id, protocol_version, agent_version ); - info.listen_addrs.truncate(30); + listen_addrs.truncate(30); } - for addr in &info.listen_addrs { - self.discovery.add_self_reported_address(&peer_id, addr.clone()); + + for addr in listen_addrs { + self.discovery.add_self_reported_address(&peer_id, protocols.iter(), addr); } - self.substrate.add_discovered_nodes(iter::once(peer_id.clone())); + self.substrate.add_discovered_nodes(iter::once(peer_id)); } } @@ -380,23 +449,23 @@ impl NetworkBehaviourEventProcess DiscoveryOut::UnroutablePeer(_peer_id) => { // Obtaining and reporting listen addresses for unroutable peers back // to Kademlia is handled by the `Identify` protocol, part of the - // `DebugInfoBehaviour`. See the `NetworkBehaviourEventProcess` - // implementation for `DebugInfoEvent`. + // `PeerInfoBehaviour`. See the `NetworkBehaviourEventProcess` + // implementation for `PeerInfoEvent`. } DiscoveryOut::Discovered(peer_id) => { self.substrate.add_discovered_nodes(iter::once(peer_id)); } - DiscoveryOut::ValueFound(results) => { - self.events.push_back(BehaviourOut::Event(Event::Dht(DhtEvent::ValueFound(results)))); + DiscoveryOut::ValueFound(results, duration) => { + self.events.push_back(BehaviourOut::Dht(DhtEvent::ValueFound(results), duration)); } - DiscoveryOut::ValueNotFound(key) => { - self.events.push_back(BehaviourOut::Event(Event::Dht(DhtEvent::ValueNotFound(key)))); + DiscoveryOut::ValueNotFound(key, duration) => { + self.events.push_back(BehaviourOut::Dht(DhtEvent::ValueNotFound(key), duration)); } - DiscoveryOut::ValuePut(key) => { - self.events.push_back(BehaviourOut::Event(Event::Dht(DhtEvent::ValuePut(key)))); + DiscoveryOut::ValuePut(key, duration) => { + self.events.push_back(BehaviourOut::Dht(DhtEvent::ValuePut(key), duration)); } - DiscoveryOut::ValuePutFailed(key) => { - self.events.push_back(BehaviourOut::Event(Event::Dht(DhtEvent::ValuePutFailed(key)))); + DiscoveryOut::ValuePutFailed(key, duration) => { + self.events.push_back(BehaviourOut::Dht(DhtEvent::ValuePutFailed(key), duration)); } DiscoveryOut::RandomKademliaStarted(protocols) => { for protocol in protocols { diff --git a/client/network/src/block_requests.rs b/client/network/src/block_requests.rs index 91e9983192758ef18e65e02a738d1c3148349516..d7a12816dd4e1a4923bb95e49d1a482fd86fb874 100644 --- a/client/network/src/block_requests.rs +++ b/client/network/src/block_requests.rs @@ -119,6 +119,7 @@ pub enum Event { #[derive(Debug, Clone)] pub struct Config { max_block_data_response: u32, + max_block_body_bytes: usize, max_request_len: usize, max_response_len: usize, inactivity_timeout: Duration, @@ -137,6 +138,7 @@ impl Config { pub fn new(id: &ProtocolId) -> Self { let mut c = Config { max_block_data_response: 128, + max_block_body_bytes: 8 * 1024 * 1024, max_request_len: 1024 * 1024, max_response_len: 16 * 1024 * 1024, inactivity_timeout: Duration::from_secs(15), @@ -171,6 +173,15 @@ impl Config { self } + /// Set the maximum total bytes of block bodies that are send in the response. + /// Note that at least one block is always sent regardless of the limit. + /// This should be lower than the value specified in `set_max_response_len` + /// accounting for headers, justifications and encoding overhead. + pub fn set_max_block_body_bytes(&mut self, v: usize) -> &mut Self { + self.max_block_body_bytes = v; + self + } + /// Set protocol to use for upgrade negotiation. pub fn set_protocol(&mut self, id: &ProtocolId) -> &mut Self { let mut v = Vec::new(); @@ -277,21 +288,13 @@ where return SendRequestOutcome::NotConnected; }; - let protobuf_rq = schema::v1::BlockRequest { - fields: u32::from_be_bytes([req.fields.bits(), 0, 0, 0]), - from_block: match req.from { - message::FromBlock::Hash(h) => - Some(schema::v1::block_request::FromBlock::Hash(h.encode())), - message::FromBlock::Number(n) => - Some(schema::v1::block_request::FromBlock::Number(n.encode())), - }, - to_block: req.to.map(|h| h.encode()).unwrap_or_default(), - direction: match req.direction { - message::Direction::Ascending => schema::v1::Direction::Ascending as i32, - message::Direction::Descending => schema::v1::Direction::Descending as i32, - }, - max_blocks: req.max.unwrap_or(0), - }; + let protobuf_rq = build_protobuf_block_request( + req.fields, + req.from.clone(), + req.to.clone(), + req.direction, + req.max, + ); let mut buf = Vec::with_capacity(protobuf_rq.encoded_len()); if let Err(err) = protobuf_rq.encode(&mut buf) { @@ -386,21 +389,24 @@ where return Err(io::Error::new(io::ErrorKind::Other, msg).into()) }; - let attributes = BlockAttributes::decode(&mut request.fields.to_be_bytes().as_ref())?; + let attributes = BlockAttributes::from_be_u32(request.fields)?; let get_header = attributes.contains(BlockAttributes::HEADER); let get_body = attributes.contains(BlockAttributes::BODY); let get_justification = attributes.contains(BlockAttributes::JUSTIFICATION); let mut blocks = Vec::new(); let mut block_id = from_block_id; + let mut total_size = 0; while let Some(header) = self.chain.header(block_id).unwrap_or(None) { - if blocks.len() >= max_blocks as usize { + if blocks.len() >= max_blocks as usize + || (blocks.len() >= 1 && total_size > self.config.max_block_body_bytes) + { break } - let number = header.number().clone(); + let number = *header.number(); let hash = header.hash(); - let parent_hash = header.parent_hash().clone(); + let parent_hash = *header.parent_hash(); let justification = if get_justification { self.chain.justification(&BlockId::Hash(hash))? } else { @@ -408,6 +414,20 @@ where }; let is_empty_justification = justification.as_ref().map(|j| j.is_empty()).unwrap_or(false); + let body = if get_body { + match self.chain.block_body(&BlockId::Hash(hash))? { + Some(mut extrinsics) => extrinsics.iter_mut() + .map(|extrinsic| extrinsic.encode()) + .collect(), + None => { + log::trace!(target: "sync", "Missing data for block request."); + break; + } + } + } else { + Vec::new() + }; + let block_data = schema::v1::BlockData { hash: hash.encode(), header: if get_header { @@ -415,21 +435,14 @@ where } else { Vec::new() }, - body: if get_body { - self.chain.block_body(&BlockId::Hash(hash))? - .unwrap_or(Vec::new()) - .iter_mut() - .map(|extrinsic| extrinsic.encode()) - .collect() - } else { - Vec::new() - }, + body, receipt: Vec::new(), message_queue: Vec::new(), - justification: justification.unwrap_or(Vec::new()), + justification: justification.unwrap_or_default(), is_empty_justification, }; + total_size += block_data.body.len(); blocks.push(block_data); match direction { @@ -463,8 +476,8 @@ where marker: PhantomData, }; let mut cfg = OneShotHandlerConfig::default(); - cfg.inactive_timeout = self.config.inactivity_timeout; - cfg.substream_timeout = self.config.request_timeout; + cfg.keep_alive_timeout = self.config.inactivity_timeout; + cfg.outbound_substream_timeout = self.config.request_timeout; OneShotHandler::new(SubstreamProtocol::new(p), cfg) } @@ -826,3 +839,28 @@ where }.boxed() } } + +/// Build protobuf block request message. +pub(crate) fn build_protobuf_block_request( + attributes: BlockAttributes, + from_block: message::FromBlock, + to_block: Option, + direction: message::Direction, + max_blocks: Option, +) -> schema::v1::BlockRequest { + schema::v1::BlockRequest { + fields: attributes.to_be_u32(), + from_block: match from_block { + message::FromBlock::Hash(h) => + Some(schema::v1::block_request::FromBlock::Hash(h.encode())), + message::FromBlock::Number(n) => + Some(schema::v1::block_request::FromBlock::Number(n.encode())), + }, + to_block: to_block.map(|h| h.encode()).unwrap_or_default(), + direction: match direction { + message::Direction::Ascending => schema::v1::Direction::Ascending as i32, + message::Direction::Descending => schema::v1::Direction::Descending as i32, + }, + max_blocks: max_blocks.unwrap_or(0), + } +} diff --git a/client/network/src/chain.rs b/client/network/src/chain.rs index 4e7e28be93ec0b744b181d42508b191aeb5b3357..20fbe0284397d513a909cbcf72733a265c060214 100644 --- a/client/network/src/chain.rs +++ b/client/network/src/chain.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Blockchain access trait diff --git a/client/network/src/config.rs b/client/network/src/config.rs index 9a979ac16d21b6fc1c8e0f3b57fdb4d6bfdefb72..94b2993b4e6bd255e332de67d0219ecf90ff8a0a 100644 --- a/client/network/src/config.rs +++ b/client/network/src/config.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Configuration of the networking layer. //! @@ -270,8 +272,21 @@ pub fn parse_str_addr(addr_str: &str) -> Result<(PeerId, Multiaddr), ParseErr> { /// Splits a Multiaddress into a Multiaddress and PeerId. pub fn parse_addr(mut addr: Multiaddr)-> Result<(PeerId, Multiaddr), ParseErr> { let who = match addr.pop() { - Some(multiaddr::Protocol::P2p(key)) => PeerId::from_multihash(key) - .map_err(|_| ParseErr::InvalidPeerId)?, + Some(multiaddr::Protocol::P2p(key)) => { + if !matches!(key.algorithm(), multiaddr::multihash::Code::Identity) { + // (note: this is the "person bowing" emoji) + log::warn!( + "🙇 You are using the peer ID {}. This peer ID uses a legacy, deprecated \ + representation that will no longer be supported in the future. \ + Please refresh it by performing a RPC query to the appropriate node, \ + by looking at its logs, or by using `subkey inspect-node-key` on its \ + private key.", + bs58::encode(key.as_bytes()).into_string() + ); + } + + PeerId::from_multihash(key).map_err(|_| ParseErr::InvalidPeerId)? + }, _ => return Err(ParseErr::PeerIdMissing), }; @@ -410,9 +425,6 @@ pub struct NetworkConfiguration { pub max_parallel_downloads: u32, /// Should we insert non-global addresses into the DHT? pub allow_non_globals_in_dht: bool, - /// If true, uses the `//block-requests/` experimental protocol rather than - /// the legacy substream. This option is meant to be hard-wired to `true` in the future. - pub use_new_block_requests_protocol: bool, } impl NetworkConfiguration { @@ -444,7 +456,6 @@ impl NetworkConfiguration { }, max_parallel_downloads: 5, allow_non_globals_in_dht: false, - use_new_block_requests_protocol: true, } } } diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index f5252e2695ae8b1490125ea50408c82d8d10cbcd..e349b08c41dc359f16e0e28503b9f069154cee74 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -46,13 +46,14 @@ //! use crate::config::ProtocolId; +use crate::utils::LruHashSet; use futures::prelude::*; use futures_timer::Delay; use ip_network::IpNetwork; use libp2p::core::{connection::{ConnectionId, ListenerId}, ConnectedPoint, Multiaddr, PeerId, PublicKey}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, ProtocolsHandler}; use libp2p::swarm::protocols_handler::multi::MultiHandler; -use libp2p::kad::{Kademlia, KademliaConfig, KademliaEvent, Quorum, Record}; +use libp2p::kad::{Kademlia, KademliaBucketInserts, KademliaConfig, KademliaEvent, QueryResult, Quorum, Record}; use libp2p::kad::GetClosestPeersError; use libp2p::kad::handler::KademliaHandler; use libp2p::kad::QueryId; @@ -62,11 +63,16 @@ use libp2p::swarm::toggle::Toggle; #[cfg(not(target_os = "unknown"))] use libp2p::mdns::{Mdns, MdnsEvent}; use libp2p::multiaddr::Protocol; -use log::{debug, info, trace, warn, error}; -use std::{cmp, collections::{HashMap, HashSet, VecDeque}, io, time::Duration}; +use log::{debug, info, trace, warn}; +use std::{cmp, collections::{HashMap, HashSet, VecDeque}, io, num::NonZeroUsize, time::Duration}; use std::task::{Context, Poll}; use sp_core::hexdisplay::HexDisplay; +/// Maximum number of known external addresses that we will cache. +/// This only affects whether we will log whenever we (re-)discover +/// a given address. +const MAX_KNOWN_EXTERNAL_ADDRESSES: usize = 32; + /// `DiscoveryBehaviour` configuration. /// /// Note: In order to discover nodes or load and store values via Kademlia one has to add at least @@ -108,7 +114,7 @@ impl DiscoveryConfig { { for (peer_id, addr) in user_defined { for kad in self.kademlias.values_mut() { - kad.add_address(&peer_id, addr.clone()) + kad.add_address(&peer_id, addr.clone()); } self.user_defined.push((peer_id, addr)) } @@ -137,17 +143,9 @@ impl DiscoveryConfig { } /// Add discovery via Kademlia for the given protocol. - pub fn add_protocol(&mut self, p: ProtocolId) -> &mut Self { - // NB: If this protocol name derivation is changed, check if - // `DiscoveryBehaviour::new_handler` is still correct. - let proto_name = { - let mut v = vec![b'/']; - v.extend_from_slice(p.as_bytes()); - v.extend_from_slice(b"/kad"); - v - }; - - self.add_kademlia(p, proto_name); + pub fn add_protocol(&mut self, id: ProtocolId) -> &mut Self { + let name = protocol_name_from_protocol_id(&id); + self.add_kademlia(id, name); self } @@ -159,6 +157,10 @@ impl DiscoveryConfig { let mut config = KademliaConfig::default(); config.set_protocol_name(proto_name); + // By default Kademlia attempts to insert all peers into its routing table once a dialing + // attempt succeeds. In order to control which peer is added, disable the auto-insertion and + // instead add peers manually. + config.set_kbucket_inserts(KademliaBucketInserts::Manual); let store = MemoryStore::new(self.local_peer_id.clone()); let mut kad = Kademlia::with_config(self.local_peer_id.clone(), store, config); @@ -177,7 +179,7 @@ impl DiscoveryConfig { kademlias: self.kademlias, next_kad_random_query: Delay::new(Duration::new(0, 0)), duration_to_next_kad: Duration::from_secs(1), - discoveries: VecDeque::new(), + pending_events: VecDeque::new(), local_peer_id: self.local_peer_id, num_connections: 0, allow_private_ipv4: self.allow_private_ipv4, @@ -194,7 +196,11 @@ impl DiscoveryConfig { } else { None.into() }, - allow_non_globals_in_dht: self.allow_non_globals_in_dht + allow_non_globals_in_dht: self.allow_non_globals_in_dht, + known_external_addresses: LruHashSet::new( + NonZeroUsize::new(MAX_KNOWN_EXTERNAL_ADDRESSES) + .expect("value is a constant; constant is non-zero; qed.") + ), } } } @@ -213,8 +219,8 @@ pub struct DiscoveryBehaviour { next_kad_random_query: Delay, /// After `next_kad_random_query` triggers, the next one triggers after this duration. duration_to_next_kad: Duration, - /// Discovered nodes to return. - discoveries: VecDeque, + /// Events to return in priority when polled. + pending_events: VecDeque, /// Identity of our local node. local_peer_id: PeerId, /// Number of nodes we're currently connected to. @@ -225,17 +231,25 @@ pub struct DiscoveryBehaviour { /// Number of active connections over which we interrupt the discovery process. discovery_only_if_under_num: u64, /// Should non-global addresses be added to the DHT? - allow_non_globals_in_dht: bool + allow_non_globals_in_dht: bool, + /// A cache of discovered external addresses. Only used for logging purposes. + known_external_addresses: LruHashSet, } impl DiscoveryBehaviour { /// Returns the list of nodes that we know exist in the network. - pub fn known_peers(&mut self) -> impl Iterator { - let mut set = HashSet::new(); - for p in self.kademlias.values_mut().map(|k| k.kbuckets_entries()).flatten() { - set.insert(p); + pub fn known_peers(&mut self) -> HashSet { + let mut peers = HashSet::new(); + for k in self.kademlias.values_mut() { + for b in k.kbuckets() { + for e in b.iter() { + if !peers.contains(e.node.key.preimage()) { + peers.insert(e.node.key.preimage().clone()); + } + } + } } - set.into_iter() + peers } /// Adds a hard-coded address for the given peer, that never expires. @@ -246,24 +260,50 @@ impl DiscoveryBehaviour { pub fn add_known_address(&mut self, peer_id: PeerId, addr: Multiaddr) { if self.user_defined.iter().all(|(p, a)| *p != peer_id && *a != addr) { for k in self.kademlias.values_mut() { - k.add_address(&peer_id, addr.clone()) + k.add_address(&peer_id, addr.clone()); } - self.discoveries.push_back(peer_id.clone()); + self.pending_events.push_back(DiscoveryOut::Discovered(peer_id.clone())); self.user_defined.push((peer_id, addr)); } } - /// Call this method when a node reports an address for itself. + /// Add a self-reported address of a remote peer to the k-buckets of the supported + /// DHTs (`supported_protocols`). /// - /// **Note**: It is important that you call this method, otherwise the discovery mechanism will - /// not properly work. - pub fn add_self_reported_address(&mut self, peer_id: &PeerId, addr: Multiaddr) { - if self.allow_non_globals_in_dht || self.can_add_to_dht(&addr) { - for k in self.kademlias.values_mut() { - k.add_address(peer_id, addr.clone()) + /// **Note**: It is important that you call this method. The discovery mechanism will not + /// automatically add connecting peers to the Kademlia k-buckets. + pub fn add_self_reported_address( + &mut self, + peer_id: &PeerId, + supported_protocols: impl Iterator>, + addr: Multiaddr + ) { + if !self.allow_non_globals_in_dht && !self.can_add_to_dht(&addr) { + log::trace!(target: "sub-libp2p", "Ignoring self-reported non-global address {} from {}.", addr, peer_id); + return + } + + let mut added = false; + for protocol in supported_protocols { + for kademlia in self.kademlias.values_mut() { + if protocol.as_ref() == kademlia.protocol_name() { + log::trace!( + target: "sub-libp2p", + "Adding self-reported address {} from {} to Kademlia DHT {}.", + addr, peer_id, String::from_utf8_lossy(kademlia.protocol_name()), + ); + kademlia.add_address(peer_id, addr.clone()); + added = true; + } } - } else { - log::trace!(target: "sub-libp2p", "Ignoring self-reported address {} from {}", addr, peer_id); + } + + if !added { + log::trace!( + target: "sub-libp2p", + "Ignoring self-reported address {} from {} as remote node is not part of any \ + Kademlia DHTs supported by the local node.", addr, peer_id, + ); } } @@ -272,7 +312,7 @@ impl DiscoveryBehaviour { /// A corresponding `ValueFound` or `ValueNotFound` event will later be generated. pub fn get_value(&mut self, key: &record::Key) { for k in self.kademlias.values_mut() { - k.get_record(key, Quorum::One) + k.get_record(key, Quorum::One); } } @@ -282,13 +322,17 @@ impl DiscoveryBehaviour { /// A corresponding `ValuePut` or `ValuePutFailed` event will later be generated. pub fn put_value(&mut self, key: record::Key, value: Vec) { for k in self.kademlias.values_mut() { - k.put_record(Record::new(key.clone(), value.clone()), Quorum::All) + if let Err(e) = k.put_record(Record::new(key.clone(), value.clone()), Quorum::All) { + warn!(target: "sub-libp2p", "Libp2p => Failed to put record: {:?}", e); + self.pending_events.push_back(DiscoveryOut::ValuePutFailed(key.clone(), Duration::from_secs(0))); + } } } /// Returns the number of nodes that are in the Kademlia k-buckets. pub fn num_kbuckets_entries(&mut self) -> impl ExactSizeIterator { - self.kademlias.iter_mut().map(|(id, kad)| (id, kad.kbuckets_entries().count())) + self.kademlias.iter_mut() + .map(|(id, kad)| (id, kad.kbuckets().map(|bucket| bucket.iter().count()).sum())) } /// Returns the number of records in the Kademlia record stores. @@ -321,7 +365,8 @@ impl DiscoveryBehaviour { let ip = match addr.iter().next() { Some(Protocol::Ip4(ip)) => IpNetwork::from(ip), Some(Protocol::Ip6(ip)) => IpNetwork::from(ip), - Some(Protocol::Dns4(_)) | Some(Protocol::Dns6(_)) => return true, + Some(Protocol::Dns(_)) | Some(Protocol::Dns4(_)) | Some(Protocol::Dns6(_)) + => return true, _ => return false }; ip.is_global() @@ -329,30 +374,42 @@ impl DiscoveryBehaviour { } /// Event generated by the `DiscoveryBehaviour`. +#[derive(Debug)] pub enum DiscoveryOut { - /// The address of a peer has been added to the Kademlia routing table. - /// - /// Can be called multiple times with the same identity. + /// A connection to a peer has been established but the peer has not been + /// added to the routing table because [`KademliaBucketInserts::Manual`] is + /// configured. If the peer is to be included in the routing table, it must + /// be explicitly added via + /// [`DiscoveryBehaviour::add_self_reported_address`]. Discovered(PeerId), /// A peer connected to this node for whom no listen address is known. /// /// In order for the peer to be added to the Kademlia routing table, a known - /// listen address must be added via [`DiscoveryBehaviour::add_self_reported_address`], - /// e.g. obtained through the `identify` protocol. + /// listen address must be added via + /// [`DiscoveryBehaviour::add_self_reported_address`], e.g. obtained through + /// the `identify` protocol. UnroutablePeer(PeerId), - /// The DHT yielded results for the record request, grouped in (key, value) pairs. - ValueFound(Vec<(record::Key, Vec)>), + /// The DHT yielded results for the record request. + /// + /// Returning the result grouped in (key, value) pairs as well as the request duration.. + ValueFound(Vec<(record::Key, Vec)>, Duration), /// The record requested was not found in the DHT. - ValueNotFound(record::Key), + /// + /// Returning the corresponding key as well as the request duration. + ValueNotFound(record::Key, Duration), /// The record with a given key was successfully inserted into the DHT. - ValuePut(record::Key), + /// + /// Returning the corresponding key as well as the request duration. + ValuePut(record::Key, Duration), /// Inserting a value into the DHT failed. - ValuePutFailed(record::Key), + /// + /// Returning the corresponding key as well as the request duration. + ValuePutFailed(record::Key, Duration), /// Started a random Kademlia query for each DHT identified by the given `ProtocolId`s. RandomKademliaStarted(Vec), @@ -403,23 +460,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { list.extend(list_to_filter); } - if !list.is_empty() { - trace!(target: "sub-libp2p", "Addresses of {:?}: {:?}", peer_id, list); - - } else { - let mut has_entry = false; - for k in self.kademlias.values_mut() { - if k.kbuckets_entries().any(|p| p == peer_id) { - has_entry = true; - break - } - } - if has_entry { - trace!(target: "sub-libp2p", "Addresses of {:?}: none (peer in k-buckets)", peer_id); - } else { - trace!(target: "sub-libp2p", "Addresses of {:?}: none (peer not in k-buckets)", peer_id); - } - } + trace!(target: "sub-libp2p", "Addresses of {:?}: {:?}", peer_id, list); list } @@ -478,14 +519,22 @@ impl NetworkBehaviour for DiscoveryBehaviour { fn inject_new_external_addr(&mut self, addr: &Multiaddr) { let new_addr = addr.clone() .with(Protocol::P2p(self.local_peer_id.clone().into())); - info!(target: "sub-libp2p", "🔍 Discovered new external address for our node: {}", new_addr); + + // NOTE: we might re-discover the same address multiple times + // in which case we just want to refrain from logging. + if self.known_external_addresses.insert(new_addr.clone()) { + info!(target: "sub-libp2p", + "🔍 Discovered new external address for our node: {}", + new_addr, + ); + } + for k in self.kademlias.values_mut() { NetworkBehaviour::inject_new_external_addr(k, addr) } } fn inject_expired_listen_addr(&mut self, addr: &Multiaddr) { - info!(target: "sub-libp2p", "No longer listening on {}", addr); for k in self.kademlias.values_mut() { NetworkBehaviour::inject_expired_listen_addr(k, addr) } @@ -504,14 +553,12 @@ impl NetworkBehaviour for DiscoveryBehaviour { } fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { - error!(target: "sub-libp2p", "Error on libp2p listener {:?}: {}", id, err); for k in self.kademlias.values_mut() { NetworkBehaviour::inject_listener_error(k, id, err) } } fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &io::Error>) { - error!(target: "sub-libp2p", "Libp2p listener {:?} closed", id); for k in self.kademlias.values_mut() { NetworkBehaviour::inject_listener_closed(k, id, reason) } @@ -528,8 +575,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { >, > { // Immediately process the content of `discovered`. - if let Some(peer_id) = self.discoveries.pop_front() { - let ev = DiscoveryOut::Discovered(peer_id); + if let Some(ev) = self.pending_events.pop_front() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); } @@ -541,7 +587,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { "Libp2p <= Starting random Kademlia request for {:?}", random_peer_id); for k in self.kademlias.values_mut() { - k.get_closest_peers(random_peer_id.clone()) + k.get_closest_peers(random_peer_id.clone()); } true } else { @@ -570,15 +616,22 @@ impl NetworkBehaviour for DiscoveryBehaviour { while let Poll::Ready(ev) = kademlia.poll(cx, params) { match ev { NetworkBehaviourAction::GenerateEvent(ev) => match ev { + KademliaEvent::RoutingUpdated { peer, .. } => { + let ev = DiscoveryOut::Discovered(peer); + return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); + } KademliaEvent::UnroutablePeer { peer, .. } => { let ev = DiscoveryOut::UnroutablePeer(peer); return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); } - KademliaEvent::RoutingUpdated { peer, .. } => { + KademliaEvent::RoutablePeer { peer, .. } => { let ev = DiscoveryOut::Discovered(peer); return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); } - KademliaEvent::GetClosestPeersResult(res) => { + KademliaEvent::PendingRoutablePeer { .. } => { + // We are not interested in this event at the moment. + } + KademliaEvent::QueryResult { result: QueryResult::GetClosestPeers(res), .. } => { match res { Err(GetClosestPeersError::Timeout { key, peers }) => { debug!(target: "sub-libp2p", @@ -596,41 +649,41 @@ impl NetworkBehaviour for DiscoveryBehaviour { } } } - KademliaEvent::GetRecordResult(res) => { + KademliaEvent::QueryResult { result: QueryResult::GetRecord(res), stats, .. } => { let ev = match res { Ok(ok) => { let results = ok.records .into_iter() - .map(|r| (r.key, r.value)) + .map(|r| (r.record.key, r.record.value)) .collect(); - DiscoveryOut::ValueFound(results) + DiscoveryOut::ValueFound(results, stats.duration().unwrap_or_else(Default::default)) } Err(e @ libp2p::kad::GetRecordError::NotFound { .. }) => { trace!(target: "sub-libp2p", "Libp2p => Failed to get record: {:?}", e); - DiscoveryOut::ValueNotFound(e.into_key()) + DiscoveryOut::ValueNotFound(e.into_key(), stats.duration().unwrap_or_else(Default::default)) } Err(e) => { warn!(target: "sub-libp2p", "Libp2p => Failed to get record: {:?}", e); - DiscoveryOut::ValueNotFound(e.into_key()) + DiscoveryOut::ValueNotFound(e.into_key(), stats.duration().unwrap_or_else(Default::default)) } }; return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); } - KademliaEvent::PutRecordResult(res) => { + KademliaEvent::QueryResult { result: QueryResult::PutRecord(res), stats, .. } => { let ev = match res { - Ok(ok) => DiscoveryOut::ValuePut(ok.key), + Ok(ok) => DiscoveryOut::ValuePut(ok.key, stats.duration().unwrap_or_else(Default::default)), Err(e) => { warn!(target: "sub-libp2p", "Libp2p => Failed to put record: {:?}", e); - DiscoveryOut::ValuePutFailed(e.into_key()) + DiscoveryOut::ValuePutFailed(e.into_key(), stats.duration().unwrap_or_else(Default::default)) } }; return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); } - KademliaEvent::RepublishRecordResult(res) => { + KademliaEvent::QueryResult { result: QueryResult::RepublishRecord(res), .. } => { match res { Ok(ok) => debug!(target: "sub-libp2p", "Libp2p => Record republished: {:?}", @@ -640,9 +693,6 @@ impl NetworkBehaviour for DiscoveryBehaviour { e.key(), e) } } - KademliaEvent::Discovered { .. } => { - // We are not interested in these events at the moment. - } // We never start any other type of query. e => { warn!(target: "sub-libp2p", "Libp2p => Unhandled Kademlia event: {:?}", e) @@ -675,9 +725,8 @@ impl NetworkBehaviour for DiscoveryBehaviour { continue; } - self.discoveries.extend(list.into_iter().map(|(peer_id, _)| peer_id)); - if let Some(peer_id) = self.discoveries.pop_front() { - let ev = DiscoveryOut::Discovered(peer_id); + self.pending_events.extend(list.map(|(peer_id, _)| DiscoveryOut::Discovered(peer_id))); + if let Some(ev) = self.pending_events.pop_front() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(ev)); } }, @@ -699,25 +748,36 @@ impl NetworkBehaviour for DiscoveryBehaviour { } } +// NB: If this protocol name derivation is changed, check if +// `DiscoveryBehaviour::new_handler` is still correct. +fn protocol_name_from_protocol_id(id: &ProtocolId) -> Vec { + let mut v = vec![b'/']; + v.extend_from_slice(id.as_bytes()); + v.extend_from_slice(b"/kad"); + v +} + #[cfg(test)] mod tests { use crate::config::ProtocolId; use futures::prelude::*; use libp2p::identity::Keypair; - use libp2p::Multiaddr; + use libp2p::{Multiaddr, PeerId}; use libp2p::core::upgrade; use libp2p::core::transport::{Transport, MemoryTransport}; use libp2p::core::upgrade::{InboundUpgradeExt, OutboundUpgradeExt}; use libp2p::swarm::Swarm; use std::{collections::HashSet, task::Poll}; - use super::{DiscoveryConfig, DiscoveryOut}; + use super::{DiscoveryConfig, DiscoveryOut, protocol_name_from_protocol_id}; #[test] fn discovery_working() { - let mut user_defined = Vec::new(); + let mut first_swarm_peer_id_and_addr = None; + let protocol_id = ProtocolId::from(b"dot".as_ref()); - // Build swarms whose behaviour is `DiscoveryBehaviour`. - let mut swarms = (0..25).map(|_| { + // Build swarms whose behaviour is `DiscoveryBehaviour`, each aware of + // the first swarm via `with_user_defined`. + let mut swarms = (0..25).map(|i| { let keypair = Keypair::generate_ed25519(); let keypair2 = keypair.clone(); @@ -740,14 +800,12 @@ mod tests { }); let behaviour = { - let protocol_id: &[u8] = b"/test/kad/1.0.0"; - let mut config = DiscoveryConfig::new(keypair.public()); - config.with_user_defined(user_defined.clone()) + config.with_user_defined(first_swarm_peer_id_and_addr.clone()) .allow_private_ipv4(true) .allow_non_globals_in_dht(true) .discovery_limit(50) - .add_protocol(ProtocolId::from(protocol_id)); + .add_protocol(protocol_id.clone()); config.finish() }; @@ -755,8 +813,8 @@ mod tests { let mut swarm = Swarm::new(transport, behaviour, keypair.public().into_peer_id()); let listen_addr: Multiaddr = format!("/memory/{}", rand::random::()).parse().unwrap(); - if user_defined.is_empty() { - user_defined.push((keypair.public().into_peer_id(), listen_addr.clone())); + if i == 0 { + first_swarm_peer_id_and_addr = Some((keypair.public().into_peer_id(), listen_addr.clone())) } Swarm::listen_on(&mut swarm, listen_addr.clone()).unwrap(); @@ -765,7 +823,10 @@ mod tests { // Build a `Vec>` with the list of nodes remaining to be discovered. let mut to_discover = (0..swarms.len()).map(|n| { - (0..swarms.len()).filter(|p| *p != n) + (0..swarms.len()) + // Skip the first swarm as all other swarms already know it. + .skip(1) + .filter(|p| *p != n) .map(|p| Swarm::local_peer_id(&swarms[p].0).clone()) .collect::>() }).collect::>(); @@ -776,7 +837,7 @@ mod tests { match swarms[swarm_n].0.poll_next_unpin(cx) { Poll::Ready(Some(e)) => { match e { - DiscoveryOut::UnroutablePeer(other) => { + DiscoveryOut::UnroutablePeer(other) | DiscoveryOut::Discovered(other) => { // Call `add_self_reported_address` to simulate identify happening. let addr = swarms.iter().find_map(|(s, a)| if s.local_peer_id == other { @@ -785,12 +846,16 @@ mod tests { None }) .unwrap(); - swarms[swarm_n].0.add_self_reported_address(&other, addr); - }, - DiscoveryOut::Discovered(other) => { + swarms[swarm_n].0.add_self_reported_address( + &other, + [protocol_name_from_protocol_id(&protocol_id)].iter(), + addr, + ); + to_discover[swarm_n].remove(&other); - } - _ => {} + }, + DiscoveryOut::RandomKademliaStarted(_) => {}, + e => {panic!("Unexpected event: {:?}", e)}, } continue 'polling } @@ -809,4 +874,103 @@ mod tests { futures::executor::block_on(fut); } + + #[test] + fn discovery_ignores_peers_with_unknown_protocols() { + let supported_protocol_id = ProtocolId::from(b"a".as_ref()); + let unsupported_protocol_id = ProtocolId::from(b"b".as_ref()); + + let mut discovery = { + let keypair = Keypair::generate_ed25519(); + let mut config = DiscoveryConfig::new(keypair.public()); + config.allow_private_ipv4(true) + .allow_non_globals_in_dht(true) + .discovery_limit(50) + .add_protocol(supported_protocol_id.clone()); + config.finish() + }; + + let remote_peer_id = PeerId::random(); + let remote_addr: Multiaddr = format!("/memory/{}", rand::random::()).parse().unwrap(); + + // Add remote peer with unsupported protocol. + discovery.add_self_reported_address( + &remote_peer_id, + [protocol_name_from_protocol_id(&unsupported_protocol_id)].iter(), + remote_addr.clone(), + ); + + for kademlia in discovery.kademlias.values_mut() { + assert!( + kademlia.kbucket(remote_peer_id.clone()) + .expect("Remote peer id not to be equal to local peer id.") + .is_empty(), + "Expect peer with unsupported protocol not to be added." + ); + } + + // Add remote peer with supported protocol. + discovery.add_self_reported_address( + &remote_peer_id, + [protocol_name_from_protocol_id(&supported_protocol_id)].iter(), + remote_addr.clone(), + ); + + for kademlia in discovery.kademlias.values_mut() { + assert_eq!( + 1, + kademlia.kbucket(remote_peer_id.clone()) + .expect("Remote peer id not to be equal to local peer id.") + .num_entries(), + "Expect peer with supported protocol to be added." + ); + } + } + + #[test] + fn discovery_adds_peer_to_kademlia_of_same_protocol_only() { + let protocol_a = ProtocolId::from(b"a".as_ref()); + let protocol_b = ProtocolId::from(b"b".as_ref()); + + let mut discovery = { + let keypair = Keypair::generate_ed25519(); + let mut config = DiscoveryConfig::new(keypair.public()); + config.allow_private_ipv4(true) + .allow_non_globals_in_dht(true) + .discovery_limit(50) + .add_protocol(protocol_a.clone()) + .add_protocol(protocol_b.clone()); + config.finish() + }; + + let remote_peer_id = PeerId::random(); + let remote_addr: Multiaddr = format!("/memory/{}", rand::random::()).parse().unwrap(); + + // Add remote peer with `protocol_a` only. + discovery.add_self_reported_address( + &remote_peer_id, + [protocol_name_from_protocol_id(&protocol_a)].iter(), + remote_addr.clone(), + ); + + assert_eq!( + 1, + discovery.kademlias.get_mut(&protocol_a) + .expect("Kademlia instance to exist.") + .kbucket(remote_peer_id.clone()) + .expect("Remote peer id not to be equal to local peer id.") + .num_entries(), + "Expected remote peer to be added to `protocol_a` Kademlia instance.", + + ); + + assert!( + discovery.kademlias.get_mut(&protocol_b) + .expect("Kademlia instance to exist.") + .kbucket(remote_peer_id.clone()) + .expect("Remote peer id not to be equal to local peer id.") + .is_empty(), + "Expected remote peer not to be added to `protocol_b` Kademlia instance.", + ); + } } diff --git a/client/network/src/error.rs b/client/network/src/error.rs index 158e75fcf1d721551a3f8cfb51f4a3d8b93b73f4..d5a4024ef53d7ff1b2617ab9fad4fa1f73cb853c 100644 --- a/client/network/src/error.rs +++ b/client/network/src/error.rs @@ -1,21 +1,24 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate network possible errors. +use crate::config::TransportConfig; use libp2p::{PeerId, Multiaddr}; use std::fmt; @@ -29,7 +32,7 @@ pub enum Error { /// Io error Io(std::io::Error), /// Client error - Client(sp_blockchain::Error), + Client(Box), /// The same bootnode (based on address) is registered with two different peer ids. #[display( fmt = "The same bootnode (`{}`) is registered with two different peer ids: `{}` and `{}`", @@ -46,7 +49,18 @@ pub enum Error { second_id: PeerId, }, /// Prometheus metrics error. - Prometheus(prometheus_endpoint::PrometheusError) + Prometheus(prometheus_endpoint::PrometheusError), + /// The network addresses are invalid because they don't match the transport. + #[display( + fmt = "The following addresses are invalid because they don't match the transport: {:?}", + addresses, + )] + AddressesForAnotherTransport { + /// Transport used. + transport: TransportConfig, + /// The invalid addresses. + addresses: Vec, + }, } // Make `Debug` use the `Display` implementation. @@ -63,6 +77,7 @@ impl std::error::Error for Error { Error::Client(ref err) => Some(err), Error::DuplicateBootnode { .. } => None, Error::Prometheus(ref err) => Some(err), + Error::AddressesForAnotherTransport { .. } => None, } } } diff --git a/client/network/src/finality_requests.rs b/client/network/src/finality_requests.rs index 457f934350629cf9b7fef027aaad6953a8fc2e9d..de737cdd20a4e8f2b4d4db17b7404a01cf2c9bd3 100644 --- a/client/network/src/finality_requests.rs +++ b/client/network/src/finality_requests.rs @@ -206,7 +206,7 @@ where let finality_proof = if let Some(provider) = &self.finality_proof_provider { provider .prove_finality(block_hash, &request.request)? - .unwrap_or(Vec::new()) + .unwrap_or_default() } else { log::error!("Answering a finality proof request while finality provider is empty"); return Err(From::from("Empty finality proof provider".to_string())) @@ -234,7 +234,7 @@ where marker: PhantomData, }; let mut cfg = OneShotHandlerConfig::default(); - cfg.inactive_timeout = self.config.inactivity_timeout; + cfg.keep_alive_timeout = self.config.inactivity_timeout; OneShotHandler::new(SubstreamProtocol::new(p), cfg) } diff --git a/client/network/src/gossip.rs b/client/network/src/gossip.rs new file mode 100644 index 0000000000000000000000000000000000000000..0650e7a2f818b75b594e81191c5a4f7732fe7988 --- /dev/null +++ b/client/network/src/gossip.rs @@ -0,0 +1,245 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +//! Helper for sending rate-limited gossip messages. +//! +//! # Context +//! +//! The [`NetworkService`] struct provides a way to send notifications to a certain peer through +//! the [`NetworkService::notification_sender`] method. This method is quite low level and isn't +//! expected to be used directly. +//! +//! The [`QueuedSender`] struct provided by this module is built on top of +//! [`NetworkService::notification_sender`] and provides a cleaner way to send notifications. +//! +//! # Behaviour +//! +//! An instance of [`QueuedSender`] is specific to a certain combination of `PeerId` and +//! protocol name. It maintains a buffer of messages waiting to be sent out. The user of this API +//! is able to manipulate that queue, adding or removing obsolete messages. +//! +//! Creating a [`QueuedSender`] also returns a opaque `Future` whose responsibility it to +//! drain that queue and actually send the messages. If the substream with the given combination +//! of peer and protocol is closed, the queue is silently discarded. It is the role of the user +//! to track which peers we are connected to. +//! +//! In normal situations, messages sent through a [`QueuedSender`] will arrive in the same +//! order as they have been sent. +//! It is possible, in the situation of disconnects and reconnects, that messages arrive in a +//! different order. See also https://github.com/paritytech/substrate/issues/6756. +//! However, if multiple instances of [`QueuedSender`] exist for the same peer and protocol, or +//! if some other code uses the [`NetworkService`] to send notifications to this combination or +//! peer and protocol, then the notifications will be interleaved in an unpredictable way. +//! + +use crate::{ExHashT, NetworkService}; + +use async_std::sync::{Condvar, Mutex, MutexGuard}; +use futures::prelude::*; +use libp2p::PeerId; +use sp_runtime::{traits::Block as BlockT, ConsensusEngineId}; +use std::{ + collections::VecDeque, + fmt, + sync::{atomic, Arc}, + time::Duration, +}; + +#[cfg(test)] +mod tests; + +/// Notifications sender for a specific combination of network service, peer, and protocol. +pub struct QueuedSender { + /// Shared between the front and the back task. + shared: Arc>, +} + +impl QueuedSender { + /// Returns a new [`QueuedSender`] containing a queue of message for this specific + /// combination of peer and protocol. + /// + /// In addition to the [`QueuedSender`], also returns a `Future` whose role is to drive + /// the messages sending forward. + pub fn new( + service: Arc>, + peer_id: PeerId, + protocol: ConsensusEngineId, + queue_size_limit: usize, + messages_encode: F + ) -> (Self, impl Future + Send + 'static) + where + M: Send + 'static, + B: BlockT + 'static, + H: ExHashT, + F: Fn(M) -> Vec + Send + 'static, + { + let shared = Arc::new(Shared { + stop_task: atomic::AtomicBool::new(false), + condvar: Condvar::new(), + queue_size_limit, + messages_queue: Mutex::new(VecDeque::with_capacity(queue_size_limit)), + }); + + let task = spawn_task( + service, + peer_id, + protocol, + shared.clone(), + messages_encode + ); + + (QueuedSender { shared }, task) + } + + /// Locks the queue of messages towards this peer. + /// + /// The returned `Future` is expected to be ready quite quickly. + pub async fn lock_queue<'a>(&'a self) -> QueueGuard<'a, M> { + QueueGuard { + messages_queue: self.shared.messages_queue.lock().await, + condvar: &self.shared.condvar, + queue_size_limit: self.shared.queue_size_limit, + } + } + + /// Pushes a message to the queue, or discards it if the queue is full. + /// + /// The returned `Future` is expected to be ready quite quickly. + pub async fn queue_or_discard(&self, message: M) + where + M: Send + 'static + { + self.lock_queue().await.push_or_discard(message); + } +} + +impl fmt::Debug for QueuedSender { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("QueuedSender").finish() + } +} + +impl Drop for QueuedSender { + fn drop(&mut self) { + // The "clean" way to notify the `Condvar` here is normally to first lock the `Mutex`, + // then notify the `Condvar` while the `Mutex` is locked. Unfortunately, the `Mutex` + // being asynchronous, it can't reasonably be locked from within a destructor. + // See also the corresponding code in the background task. + self.shared.stop_task.store(true, atomic::Ordering::Release); + self.shared.condvar.notify_all(); + } +} + +/// Locked queue of messages to the given peer. +/// +/// As long as this struct exists, the background task is asleep and the owner of the [`QueueGuard`] +/// is in total control of the buffer. Messages can only ever be sent out after the [`QueueGuard`] +/// is dropped. +#[must_use] +pub struct QueueGuard<'a, M> { + messages_queue: MutexGuard<'a, VecDeque>, + condvar: &'a Condvar, + /// Same as [`Shared::queue_size_limit`]. + queue_size_limit: usize, +} + +impl<'a, M: Send + 'static> QueueGuard<'a, M> { + /// Pushes a message to the queue, or discards it if the queue is full. + /// + /// The message will only start being sent out after the [`QueueGuard`] is dropped. + pub fn push_or_discard(&mut self, message: M) { + if self.messages_queue.len() < self.queue_size_limit { + self.messages_queue.push_back(message); + } + } + + /// Calls `filter` for each message in the queue, and removes the ones for which `false` is + /// returned. + /// + /// > **Note**: The parameter of `filter` is a `&M` and not a `&mut M` (which would be + /// > better) because the underlying implementation relies on `VecDeque::retain`. + pub fn retain(&mut self, filter: impl FnMut(&M) -> bool) { + self.messages_queue.retain(filter); + } +} + +impl<'a, M> Drop for QueueGuard<'a, M> { + fn drop(&mut self) { + // We notify the `Condvar` in the destructor in order to be able to push multiple + // messages and wake up the background task only once afterwards. + self.condvar.notify_one(); + } +} + +#[derive(Debug)] +struct Shared { + /// Read by the background task after locking `locked`. If true, the task stops. + stop_task: atomic::AtomicBool, + /// Queue of messages waiting to be sent out. + messages_queue: Mutex>, + /// Must be notified every time the content of `locked` changes. + condvar: Condvar, + /// Maximum number of elements in `messages_queue`. + queue_size_limit: usize, +} + +async fn spawn_task Vec>( + service: Arc>, + peer_id: PeerId, + protocol: ConsensusEngineId, + shared: Arc>, + messages_encode: F, +) { + loop { + let next_message = 'next_msg: loop { + let mut queue = shared.messages_queue.lock().await; + + loop { + if shared.stop_task.load(atomic::Ordering::Acquire) { + return; + } + + if let Some(msg) = queue.pop_front() { + break 'next_msg msg; + } + + // It is possible that the destructor of `QueuedSender` sets `stop_task` to + // true and notifies the `Condvar` after the background task loads `stop_task` + // and before it calls `Condvar::wait`. + // See also the corresponding comment in `QueuedSender::drop`. + // For this reason, we use `wait_timeout`. In the worst case scenario, + // `stop_task` will always be checked again after the timeout is reached. + queue = shared.condvar.wait_timeout(queue, Duration::from_secs(10)).await.0; + } + }; + + // Starting from below, we try to send the message. If an error happens when sending, + // the only sane option we have is to silently discard the message. + let sender = match service.notification_sender(peer_id.clone(), protocol) { + Ok(s) => s, + Err(_) => continue, + }; + + let ready = match sender.ready().await { + Ok(r) => r, + Err(_) => continue, + }; + + let _ = ready.send(messages_encode(next_message)); + } +} diff --git a/client/network/src/gossip/tests.rs b/client/network/src/gossip/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..9b16e057461bf313819463756bfe98e408acefae --- /dev/null +++ b/client/network/src/gossip/tests.rs @@ -0,0 +1,201 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use crate::{config, gossip::QueuedSender, Event, NetworkService, NetworkWorker}; + +use futures::prelude::*; +use sp_runtime::traits::{Block as BlockT, Header as _}; +use std::{sync::Arc, time::Duration}; +use substrate_test_runtime_client::{TestClientBuilder, TestClientBuilderExt as _}; + +type TestNetworkService = NetworkService< + substrate_test_runtime_client::runtime::Block, + substrate_test_runtime_client::runtime::Hash, +>; + +/// Builds a full node to be used for testing. Returns the node service and its associated events +/// stream. +/// +/// > **Note**: We return the events stream in order to not possibly lose events between the +/// > construction of the service and the moment the events stream is grabbed. +fn build_test_full_node(config: config::NetworkConfiguration) + -> (Arc, impl Stream) +{ + let client = Arc::new( + TestClientBuilder::with_default_backend() + .build_with_longest_chain() + .0, + ); + + #[derive(Clone)] + struct PassThroughVerifier(bool); + impl sp_consensus::import_queue::Verifier for PassThroughVerifier { + fn verify( + &mut self, + origin: sp_consensus::BlockOrigin, + header: B::Header, + justification: Option, + body: Option>, + ) -> Result< + ( + sp_consensus::BlockImportParams, + Option)>>, + ), + String, + > { + let maybe_keys = header + .digest() + .log(|l| { + l.try_as_raw(sp_runtime::generic::OpaqueDigestItemId::Consensus(b"aura")) + .or_else(|| { + l.try_as_raw(sp_runtime::generic::OpaqueDigestItemId::Consensus(b"babe")) + }) + }) + .map(|blob| { + vec![( + sp_blockchain::well_known_cache_keys::AUTHORITIES, + blob.to_vec(), + )] + }); + + let mut import = sp_consensus::BlockImportParams::new(origin, header); + import.body = body; + import.finalized = self.0; + import.justification = justification; + import.fork_choice = Some(sp_consensus::ForkChoiceStrategy::LongestChain); + Ok((import, maybe_keys)) + } + } + + let import_queue = Box::new(sp_consensus::import_queue::BasicQueue::new( + PassThroughVerifier(false), + Box::new(client.clone()), + None, + None, + &sp_core::testing::TaskExecutor::new(), + None, + )); + + let worker = NetworkWorker::new(config::Params { + role: config::Role::Full, + executor: None, + network_config: config, + chain: client.clone(), + finality_proof_provider: None, + finality_proof_request_builder: None, + on_demand: None, + transaction_pool: Arc::new(crate::config::EmptyTransactionPool), + protocol_id: config::ProtocolId::from(&b"/test-protocol-name"[..]), + import_queue, + block_announce_validator: Box::new( + sp_consensus::block_validation::DefaultBlockAnnounceValidator, + ), + metrics_registry: None, + }) + .unwrap(); + + let service = worker.service().clone(); + let event_stream = service.event_stream("test"); + + async_std::task::spawn(async move { + futures::pin_mut!(worker); + let _ = worker.await; + }); + + (service, event_stream) +} + +const ENGINE_ID: sp_runtime::ConsensusEngineId = *b"foo\0"; + +/// Builds two nodes and their associated events stream. +/// The nodes are connected together and have the `ENGINE_ID` protocol registered. +fn build_nodes_one_proto() + -> (Arc, impl Stream, Arc, impl Stream) +{ + let listen_addr = config::build_multiaddr![Memory(rand::random::())]; + + let (node1, events_stream1) = build_test_full_node(config::NetworkConfiguration { + notifications_protocols: vec![(ENGINE_ID, From::from(&b"/foo"[..]))], + listen_addresses: vec![listen_addr.clone()], + transport: config::TransportConfig::MemoryOnly, + .. config::NetworkConfiguration::new_local() + }); + + let (node2, events_stream2) = build_test_full_node(config::NetworkConfiguration { + notifications_protocols: vec![(ENGINE_ID, From::from(&b"/foo"[..]))], + listen_addresses: vec![], + reserved_nodes: vec![config::MultiaddrWithPeerId { + multiaddr: listen_addr, + peer_id: node1.local_peer_id().clone(), + }], + transport: config::TransportConfig::MemoryOnly, + .. config::NetworkConfiguration::new_local() + }); + + (node1, events_stream1, node2, events_stream2) +} + +#[test] +fn basic_works() { + const NUM_NOTIFS: usize = 256; + + let (node1, mut events_stream1, node2, mut events_stream2) = build_nodes_one_proto(); + let node2_id = node2.local_peer_id().clone(); + + let receiver = async_std::task::spawn(async move { + let mut received_notifications = 0; + + while received_notifications < NUM_NOTIFS { + match events_stream2.next().await.unwrap() { + Event::NotificationStreamClosed { .. } => panic!(), + Event::NotificationsReceived { messages, .. } => { + for message in messages { + assert_eq!(message.0, ENGINE_ID); + assert_eq!(message.1, &b"message"[..]); + received_notifications += 1; + } + } + _ => {} + }; + + if rand::random::() < 2 { + async_std::task::sleep(Duration::from_millis(rand::random::() % 750)).await; + } + } + }); + + async_std::task::block_on(async move { + let (sender, bg_future) = + QueuedSender::new(node1, node2_id, ENGINE_ID, NUM_NOTIFS, |msg| msg); + async_std::task::spawn(bg_future); + + // Wait for the `NotificationStreamOpened`. + loop { + match events_stream1.next().await.unwrap() { + Event::NotificationStreamOpened { .. } => break, + _ => {} + }; + } + + for _ in 0..NUM_NOTIFS { + sender.queue_or_discard(b"message".to_vec()).await; + } + + receiver.await; + }); +} diff --git a/client/network/src/lib.rs b/client/network/src/lib.rs index dbc54d21c4d5783c5b0c061076ecb535e21d8d08..e01b26026356635100c96413f1f4516458c9f0fe 100644 --- a/client/network/src/lib.rs +++ b/client/network/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . #![warn(unused_extern_crates)] #![warn(missing_docs)] @@ -76,7 +78,7 @@ //! - WebSockets for addresses of the form `/ip4/1.2.3.4/tcp/5/ws`. A TCP/IP connection is open and //! the WebSockets protocol is negotiated on top. Communications then happen inside WebSockets data //! frames. Encryption and multiplexing are additionally negotiated again inside this channel. -//! - DNS for addresses of the form `/dns4/example.com/tcp/5` or `/dns4/example.com/tcp/5/ws`. A +//! - DNS for addresses of the form `/dns/example.com/tcp/5` or `/dns/example.com/tcp/5/ws`. A //! node's address can contain a domain name. //! - (All of the above using IPv6 instead of IPv4.) //! @@ -196,13 +198,14 @@ //! handshake message can be of length 0, in which case the sender has to send a single `0`. //! - The receiver then either immediately closes the substream, or answers with its own //! LEB128-prefixed protocol-specific handshake response. The message can be of length 0, in which -//! case a single `0` has to be sent back. The receiver is then encouraged to close its sending -//! side. +//! case a single `0` has to be sent back. //! - Once the handshake has completed, the notifications protocol is unidirectional. Only the //! node which initiated the substream can push notifications. If the remote wants to send //! notifications as well, it has to open its own undirectional substream. //! - Each notification must be prefixed with an LEB128-encoded length. The encoding of the //! messages is specific to each protocol. +//! - Either party can signal that it doesn't want a notifications substream anymore by closing +//! its writing side. The other party should respond by closing its own writing side soon after. //! //! The API of `sc-network` allows one to register user-defined notification protocols. //! `sc-network` automatically tries to open a substream towards each node for which the legacy @@ -244,7 +247,7 @@ mod behaviour; mod block_requests; mod chain; -mod debug_info; +mod peer_info; mod discovery; mod finality_requests; mod light_client_handler; @@ -257,6 +260,7 @@ mod utils; pub mod config; pub mod error; +pub mod gossip; pub mod network_state; pub use service::{NetworkService, NetworkWorker}; @@ -268,6 +272,7 @@ pub use libp2p::{Multiaddr, PeerId}; pub use libp2p::multiaddr; pub use sc_peerset::ReputationChange; +use sp_runtime::traits::{Block as BlockT, NumberFor}; /// The maximum allowed number of established connections per peer. /// @@ -284,26 +289,6 @@ pub trait ExHashT: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync impl ExHashT for T where T: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static {} -/// A cloneable handle for reporting cost/benefits of peers. -#[derive(Clone)] -pub struct ReportHandle { - inner: sc_peerset::PeersetHandle, // wraps it so we don't have to worry about breaking API. -} - -impl From for ReportHandle { - fn from(peerset_handle: sc_peerset::PeersetHandle) -> Self { - ReportHandle { inner: peerset_handle } - } -} - -impl ReportHandle { - /// Report a given peer as either beneficial (+) or costly (-) according to the - /// given scalar. - pub fn report_peer(&self, who: PeerId, cost_benefit: ReputationChange) { - self.inner.report_peer(who, cost_benefit); - } -} - /// Trait for providing information about the local network state pub trait NetworkStateInfo { /// Returns the local external addresses. @@ -312,3 +297,22 @@ pub trait NetworkStateInfo { /// Returns the local Peer ID. fn local_peer_id(&self) -> PeerId; } + +/// Overview status of the network. +#[derive(Clone)] +pub struct NetworkStatus { + /// Current global sync state. + pub sync_state: SyncState, + /// Target sync block number. + pub best_seen_block: Option>, + /// Number of peers participating in syncing. + pub num_sync_peers: u32, + /// Total number of connected peers + pub num_connected_peers: usize, + /// Total number of active peers. + pub num_active_peers: usize, + /// The total number of bytes received. + pub total_bytes_inbound: u64, + /// The total number of bytes sent. + pub total_bytes_outbound: u64, +} diff --git a/client/network/src/light_client_handler.rs b/client/network/src/light_client_handler.rs index 5080d16ead68a80a0acde58aa43d8a618fe64a62..678a717a898ff47b45174c3807a6d7d6b12a508c 100644 --- a/client/network/src/light_client_handler.rs +++ b/client/network/src/light_client_handler.rs @@ -27,9 +27,10 @@ use bytes::Bytes; use codec::{self, Encode, Decode}; use crate::{ + block_requests::build_protobuf_block_request, chain::Client, config::ProtocolId, - protocol::message::BlockAttributes, + protocol::message::{BlockAttributes, Direction, FromBlock}, schema, }; use futures::{channel::oneshot, future::BoxFuture, prelude::*, stream::FuturesUnordered}; @@ -756,7 +757,7 @@ where protocol: self.config.light_protocol.clone(), }; let mut cfg = OneShotHandlerConfig::default(); - cfg.inactive_timeout = self.config.inactivity_timeout; + cfg.keep_alive_timeout = self.config.inactivity_timeout; OneShotHandler::new(SubstreamProtocol::new(p), cfg) } @@ -980,7 +981,9 @@ where let handler = request.connection.map_or(NotifyHandler::Any, NotifyHandler::One); let request_id = self.next_request_id(); - self.peers.get_mut(&peer).map(|p| p.status = PeerStatus::BusyWith(request_id)); + if let Some(p) = self.peers.get_mut(&peer) { + p.status = PeerStatus::BusyWith(request_id); + } self.outstanding.insert(request_id, request); let event = OutboundProtocol { @@ -1060,13 +1063,13 @@ fn retries(request: &Request) -> usize { fn serialize_request(request: &Request) -> Result, prost::EncodeError> { let request = match request { Request::Body { request, .. } => { - let rq = schema::v1::BlockRequest { - fields: u32::from(BlockAttributes::BODY.bits()), - from_block: Some(schema::v1::block_request::FromBlock::Hash(request.header.hash().encode())), - to_block: Vec::new(), - direction: schema::v1::Direction::Ascending as i32, - max_blocks: 1, - }; + let rq = build_protobuf_block_request::<_, NumberFor>( + BlockAttributes::BODY, + FromBlock::Hash(request.header.hash()), + None, + Direction::Ascending, + Some(1), + ); let mut buf = Vec::with_capacity(rq.encoded_len()); rq.encode(&mut buf)?; return Ok(buf); @@ -2034,4 +2037,22 @@ mod tests { assert_eq!(vec![(100, 2)], task::block_on(chan.1).unwrap().unwrap()); // ^--- from `DummyFetchChecker::check_changes_proof` } + + #[test] + fn body_request_fields_encoded_properly() { + let (sender, _) = oneshot::channel(); + let serialized_request = serialize_request::(&Request::Body { + request: RemoteBodyRequest { + header: dummy_header(), + retry_count: None, + }, + sender, + }).unwrap(); + let deserialized_request = schema::v1::BlockRequest::decode(&serialized_request[..]).unwrap(); + assert!( + BlockAttributes::from_be_u32(deserialized_request.fields) + .unwrap() + .contains(BlockAttributes::BODY) + ); + } } diff --git a/client/network/src/network_state.rs b/client/network/src/network_state.rs index 00d53976ae8fc8960e9045b1dbab7d1621429f26..2e24e9c5a9f58e9ff3fc9d8816f52481b7c3d30e 100644 --- a/client/network/src/network_state.rs +++ b/client/network/src/network_state.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Information about the networking, for diagnostic purposes. //! @@ -41,10 +43,10 @@ pub struct NetworkState { pub connected_peers: HashMap, /// List of node that we know of but that we're not connected to. pub not_connected_peers: HashMap, - /// Downloaded bytes per second averaged over the past few seconds. - pub average_download_per_sec: u64, - /// Uploaded bytes per second averaged over the past few seconds. - pub average_upload_per_sec: u64, + /// The total number of bytes received. + pub total_bytes_inbound: u64, + /// The total number of bytes sent. + pub total_bytes_outbound: u64, /// State of the peerset manager. pub peerset: serde_json::Value, } diff --git a/client/network/src/on_demand_layer.rs b/client/network/src/on_demand_layer.rs index c8bd7f286778d0d531fc98c13342894df6382189..084172ee57c4f002c66c27e22bbe6dfc42f750fa 100644 --- a/client/network/src/on_demand_layer.rs +++ b/client/network/src/on_demand_layer.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! On-demand requests service. @@ -219,7 +221,7 @@ impl Future for RemoteResponse { fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { match self.receiver.poll_unpin(cx) { Poll::Ready(Ok(res)) => Poll::Ready(res), - Poll::Ready(Err(_)) => Poll::Ready(Err(From::from(ClientError::RemoteFetchCancelled))), + Poll::Ready(Err(_)) => Poll::Ready(Err(ClientError::RemoteFetchCancelled)), Poll::Pending => Poll::Pending, } } diff --git a/client/network/src/debug_info.rs b/client/network/src/peer_info.rs similarity index 95% rename from client/network/src/debug_info.rs rename to client/network/src/peer_info.rs index e2803cde35a772e5e094919ef31b364af640c487..e69ad2b17e59c7f856f1e1e4b73be88572519936 100644 --- a/client/network/src/debug_info.rs +++ b/client/network/src/peer_info.rs @@ -38,9 +38,8 @@ const CACHE_EXPIRE: Duration = Duration::from_secs(10 * 60); /// Interval at which we perform garbage collection on the node info. const GARBAGE_COLLECT_INTERVAL: Duration = Duration::from_secs(2 * 60); -/// Implementation of `NetworkBehaviour` that holds information about nodes in cache for diagnostic -/// purposes. -pub struct DebugInfoBehaviour { +/// Implementation of `NetworkBehaviour` that holds information about peers in cache. +pub struct PeerInfoBehaviour { /// Periodically ping nodes, and close the connection if it's unresponsive. ping: Ping, /// Periodically identifies the remote and responds to incoming requests. @@ -78,18 +77,18 @@ impl NodeInfo { } } -impl DebugInfoBehaviour { - /// Builds a new `DebugInfoBehaviour`. +impl PeerInfoBehaviour { + /// Builds a new `PeerInfoBehaviour`. pub fn new( user_agent: String, local_public_key: PublicKey, ) -> Self { let identify = { let proto_version = "/substrate/1.0".to_string(); - Identify::new(proto_version, user_agent, local_public_key.clone()) + Identify::new(proto_version, user_agent, local_public_key) }; - DebugInfoBehaviour { + PeerInfoBehaviour { ping: Ping::new(PingConfig::new()), identify, nodes_info: FnvHashMap::default(), @@ -154,8 +153,8 @@ impl<'a> Node<'a> { /// Event that can be emitted by the behaviour. #[derive(Debug)] -pub enum DebugInfoEvent { - /// We have obtained debug information from a peer, including the addresses it is listening +pub enum PeerInfoEvent { + /// We have obtained identity information from a peer, including the addresses it is listening /// on. Identified { /// Id of the peer that has been identified. @@ -165,12 +164,12 @@ pub enum DebugInfoEvent { }, } -impl NetworkBehaviour for DebugInfoBehaviour { +impl NetworkBehaviour for PeerInfoBehaviour { type ProtocolsHandler = IntoProtocolsHandlerSelect< ::ProtocolsHandler, ::ProtocolsHandler >; - type OutEvent = DebugInfoEvent; + type OutEvent = PeerInfoEvent; fn new_handler(&mut self) -> Self::ProtocolsHandler { IntoProtocolsHandler::select(self.ping.new_handler(), self.identify.new_handler()) @@ -317,7 +316,7 @@ impl NetworkBehaviour for DebugInfoBehaviour { match event { IdentifyEvent::Received { peer_id, info, .. } => { self.handle_identify_report(&peer_id, &info); - let event = DebugInfoEvent::Identified { peer_id, info }; + let event = PeerInfoEvent::Identified { peer_id, info }; return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); } IdentifyEvent::Error { peer_id, error } => diff --git a/client/network/src/protocol.rs b/client/network/src/protocol.rs index c2f5fce8bfe8321bf6d13e6610d76b89c7165c67..ff95d8f12fc7803ecb19e02ddf6b3e5b57f49948 100644 --- a/client/network/src/protocol.rs +++ b/client/network/src/protocol.rs @@ -1,25 +1,27 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::{ ExHashT, - chain::{Client, FinalityProofProvider}, + chain::Client, config::{BoxFinalityProofRequestBuilder, ProtocolId, TransactionPool, TransactionImportFuture, TransactionImport}, error, - utils::interval + utils::{interval, LruHashSet}, }; use bytes::{Bytes, BytesMut}; @@ -29,10 +31,6 @@ use libp2p::{Multiaddr, PeerId}; use libp2p::core::{ConnectedPoint, connection::{ConnectionId, ListenerId}}; use libp2p::swarm::{ProtocolsHandler, IntoProtocolsHandler}; use libp2p::swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; -use sp_core::{ - storage::{StorageKey, PrefixedStorageKey, ChildInfo, ChildType}, - hexdisplay::HexDisplay -}; use sp_consensus::{ BlockOrigin, block_validation::BlockAnnounceValidator, @@ -45,38 +43,40 @@ use sp_runtime::traits::{ }; use sp_arithmetic::traits::SaturatedConversion; use message::{BlockAnnounce, Message}; -use message::generic::{Message as GenericMessage, ConsensusMessage, Roles}; -use prometheus_endpoint::{Registry, Gauge, GaugeVec, HistogramVec, PrometheusError, Opts, register, U64}; +use message::generic::{Message as GenericMessage, Roles}; +use prometheus_endpoint::{ + Registry, Gauge, Counter, CounterVec, GaugeVec, + PrometheusError, Opts, register, U64 +}; use sync::{ChainSync, SyncState}; use std::borrow::Cow; -use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; +use std::collections::{HashMap, HashSet, VecDeque, hash_map::Entry}; use std::sync::Arc; use std::fmt::Write; use std::{cmp, io, num::NonZeroUsize, pin::Pin, task::Poll, time}; use log::{log, Level, trace, debug, warn, error}; -use sc_client_api::{ChangesProof, StorageProof}; -use util::LruHashSet; use wasm_timer::Instant; mod generic_proto; -mod util; pub mod message; pub mod event; pub mod sync; -pub use generic_proto::LegacyConnectionKillError; +pub use generic_proto::{NotificationsSink, Ready, NotifsHandlerError, LegacyConnectionKillError}; const REQUEST_TIMEOUT_SEC: u64 = 40; /// Interval at which we perform time based maintenance const TICK_TIMEOUT: time::Duration = time::Duration::from_millis(1100); -/// Interval at which we propagate extrinsics; +/// Interval at which we propagate transactions; const PROPAGATE_TIMEOUT: time::Duration = time::Duration::from_millis(2900); /// Maximim number of known block hashes to keep for a peer. const MAX_KNOWN_BLOCKS: usize = 1024; // ~32kb per peer + LruHashSet overhead -/// Maximim number of known extrinsic hashes to keep for a peer. -const MAX_KNOWN_EXTRINSICS: usize = 4096; // ~128kb per peer + overhead +/// Maximim number of known transaction hashes to keep for a peer. +/// +/// This should be approx. 2 blocks full of transactions for the network to function properly. +const MAX_KNOWN_TRANSACTIONS: usize = 10240; // ~300kb per peer + overhead. /// Maximim number of transaction validation request we keep at any moment. const MAX_PENDING_TRANSACTIONS: usize = 8192; @@ -88,6 +88,9 @@ pub(crate) const MIN_VERSION: u32 = 3; // Maximum allowed entries in `BlockResponse` const MAX_BLOCK_DATA_RESPONSE: u32 = 128; +// Maximum total bytes allowed for block bodies in `BlockResponse` +const MAX_BODIES_BYTES: usize = 8 * 1024 * 1024; + /// When light node connects to the full node and the full node is behind light node /// for at least `LIGHT_MAXIMAL_BLOCKS_DIFFERENCE` blocks, we consider it not useful /// and disconnect to free connection slot. @@ -95,34 +98,27 @@ const LIGHT_MAXIMAL_BLOCKS_DIFFERENCE: u64 = 8192; mod rep { use sc_peerset::ReputationChange as Rep; - /// Reputation change when a peer is "clogged", meaning that it's not fast enough to process our - /// messages. - pub const CLOGGED_PEER: Rep = Rep::new(-(1 << 12), "Clogged message queue"); /// Reputation change when a peer doesn't respond in time to our messages. pub const TIMEOUT: Rep = Rep::new(-(1 << 10), "Request timeout"); - /// Reputation change when a peer sends us a status message while we already received one. - pub const UNEXPECTED_STATUS: Rep = Rep::new(-(1 << 20), "Unexpected status message"); /// Reputation change when we are a light client and a peer is behind us. pub const PEER_BEHIND_US_LIGHT: Rep = Rep::new(-(1 << 8), "Useless for a light peer"); - /// Reputation change when a peer sends us any extrinsic. + /// Reputation change when a peer sends us any transaction. /// - /// This forces node to verify it, thus the negative value here. Once extrinsic is verified, - /// reputation change should be refunded with `ANY_EXTRINSIC_REFUND` - pub const ANY_EXTRINSIC: Rep = Rep::new(-(1 << 4), "Any extrinsic"); - /// Reputation change when a peer sends us any extrinsic that is not invalid. - pub const ANY_EXTRINSIC_REFUND: Rep = Rep::new(1 << 4, "Any extrinsic (refund)"); - /// Reputation change when a peer sends us an extrinsic that we didn't know about. - pub const GOOD_EXTRINSIC: Rep = Rep::new(1 << 7, "Good extrinsic"); - /// Reputation change when a peer sends us a bad extrinsic. - pub const BAD_EXTRINSIC: Rep = Rep::new(-(1 << 12), "Bad extrinsic"); - /// We sent an RPC query to the given node, but it failed. - pub const RPC_FAILED: Rep = Rep::new(-(1 << 12), "Remote call failed"); + /// This forces node to verify it, thus the negative value here. Once transaction is verified, + /// reputation change should be refunded with `ANY_TRANSACTION_REFUND` + pub const ANY_TRANSACTION: Rep = Rep::new(-(1 << 4), "Any transaction"); + /// Reputation change when a peer sends us any transaction that is not invalid. + pub const ANY_TRANSACTION_REFUND: Rep = Rep::new(1 << 4, "Any transaction (refund)"); + /// Reputation change when a peer sends us an transaction that we didn't know about. + pub const GOOD_TRANSACTION: Rep = Rep::new(1 << 7, "Good transaction"); + /// Reputation change when a peer sends us a bad transaction. + pub const BAD_TRANSACTION: Rep = Rep::new(-(1 << 12), "Bad transaction"); /// We received a message that failed to decode. pub const BAD_MESSAGE: Rep = Rep::new(-(1 << 12), "Bad message"); /// We received an unexpected response. pub const UNEXPECTED_RESPONSE: Rep = Rep::new_fatal("Unexpected response packet"); - /// We received an unexpected extrinsic packet. - pub const UNEXPECTED_EXTRINSICS: Rep = Rep::new_fatal("Unexpected extrinsics packet"); + /// We received an unexpected transaction packet. + pub const UNEXPECTED_TRANSACTIONS: Rep = Rep::new_fatal("Unexpected transactions packet"); /// We received an unexpected light node request. pub const UNEXPECTED_REQUEST: Rep = Rep::new_fatal("Unexpected block request packet"); /// Peer has different genesis. @@ -136,22 +132,19 @@ mod rep { } struct Metrics { - handshaking_peers: Gauge, obsolete_requests: Gauge, peers: Gauge, queued_blocks: Gauge, fork_targets: Gauge, finality_proofs: GaugeVec, justifications: GaugeVec, + propagated_transactions: Counter, + legacy_requests_received: CounterVec, } impl Metrics { fn register(r: &Registry) -> Result { Ok(Metrics { - handshaking_peers: { - let g = Gauge::new("sync_handshaking_peers", "Number of newly connected peers")?; - register(g, r)? - }, obsolete_requests: { let g = Gauge::new("sync_obsolete_requests", "Number of obsolete requests")?; register(g, r)? @@ -188,22 +181,36 @@ impl Metrics { )?; register(g, r)? }, + propagated_transactions: register(Counter::new( + "sync_propagated_transactions", + "Number of transactions propagated to at least one peer", + )?, r)?, + legacy_requests_received: register(CounterVec::new( + Opts::new( + "sync_legacy_requests_received", + "Number of block/finality/light-client requests received on the legacy substream", + ), + &["kind"] + )?, r)?, }) } } -struct PendingTransaction { +#[pin_project::pin_project] +struct PendingTransaction { + #[pin] validation: TransactionImportFuture, - peer_id: PeerId, + tx_hash: H, } -impl Future for PendingTransaction { - type Output = (PeerId, TransactionImport); +impl Future for PendingTransaction { + type Output = (H, TransactionImport); fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { - let this = Pin::into_inner(self); - if let Poll::Ready(import_result) = this.validation.poll_unpin(cx) { - return Poll::Ready((this.peer_id.clone(), import_result)); + let mut this = self.project(); + + if let Poll::Ready(import_result) = Pin::new(&mut this.validation).poll_unpin(cx) { + return Poll::Ready((this.tx_hash.clone(), import_result)); } Poll::Pending @@ -214,12 +221,17 @@ impl Future for PendingTransaction { pub struct Protocol { /// Interval at which we call `tick`. tick_timeout: Pin + Send>>, - /// Interval at which we call `propagate_extrinsics`. + /// Interval at which we call `propagate_transactions`. propagate_timeout: Pin + Send>>, /// Pending list of messages to return from `poll` as a priority. pending_messages: VecDeque>, - /// Pending extrinsic verification tasks. - pending_transactions: FuturesUnordered, + /// Pending transactions verification tasks. + pending_transactions: FuturesUnordered>, + /// As multiple peers can send us the same transaction, we group + /// these peers using the transaction hash while the transaction is + /// imported. This prevents that we import the same transaction + /// multiple times concurrently. + pending_transactions_peers: HashMap>, config: ProtocolConfig, genesis_hash: B::Hash, sync: ChainSync, @@ -227,13 +239,9 @@ pub struct Protocol { /// List of nodes for which we perform additional logging because they are important for the /// user. important_peers: HashSet, - // Connected peers pending Status message. - handshaking_peers: HashMap, /// Used to report reputation changes. peerset_handle: sc_peerset::PeersetHandle, transaction_pool: Arc>, - /// When asked for a proof of finality, we use this struct to build one. - finality_proof_provider: Option>>, /// Handles opening the unique substream and sending and receiving raw messages. behaviour: GenericProto, /// For each legacy gossiping engine ID, the corresponding new protocol name. @@ -248,9 +256,6 @@ pub struct Protocol { metrics: Option, /// The `PeerId`'s of all boot nodes. boot_node_ids: Arc>, - /// If true, we send back requests as `CustomMessageOutcome` events. If false, we directly - /// dispatch requests using the legacy substream. - use_new_block_requests_protocol: bool, } #[derive(Default)] @@ -260,13 +265,6 @@ struct PacketStats { count_in: u64, count_out: u64, } - -/// A peer that we are connected to -/// and from whom we have not yet received a Status message. -struct HandshakingPeer { - timestamp: Instant, -} - /// Peer information #[derive(Debug, Clone)] struct Peer { @@ -276,7 +274,7 @@ struct Peer { /// Requests we are no longer interested in. obsolete_requests: HashMap, /// Holds a set of transactions known to this peer. - known_extrinsics: LruHashSet, + known_transactions: LruHashSet, /// Holds a set of blocks known to this peer. known_blocks: LruHashSet, /// Request counter, @@ -340,13 +338,29 @@ impl BlockAnnouncesHandshake { let info = chain.info(); BlockAnnouncesHandshake { genesis_hash: info.genesis_hash, - roles: protocol_config.roles.into(), + roles: protocol_config.roles, best_number: info.best_number, best_hash: info.best_hash, } } } +/// Builds a SCALE-encoded "Status" message to send as handshake for the legacy protocol. +fn build_status_message(protocol_config: &ProtocolConfig, chain: &Arc>) -> Vec { + let info = chain.info(); + let status = message::generic::Status { + version: CURRENT_VERSION, + min_supported_version: MIN_VERSION, + genesis_hash: info.genesis_hash, + roles: protocol_config.roles.into(), + best_number: info.best_number, + best_hash: info.best_hash, + chain_status: Vec::new(), // TODO: find a way to make this backwards-compatible + }; + + Message::::Status(status).encode() +} + /// Fallback mechanism to use to send a notification if no substream is open. #[derive(Debug, Clone, PartialEq, Eq)] enum Fallback { @@ -362,17 +376,15 @@ impl Protocol { /// Create a new instance. pub fn new( config: ProtocolConfig, + local_peer_id: PeerId, chain: Arc>, transaction_pool: Arc>, - finality_proof_provider: Option>>, finality_proof_request_builder: Option>, protocol_id: ProtocolId, peerset_config: sc_peerset::PeersetConfig, block_announce_validator: Box + Send>, metrics_registry: Option<&Registry>, boot_node_ids: Arc>, - use_new_block_requests_protocol: bool, - queue_size_report: Option, ) -> error::Result<(Protocol, sc_peerset::PeersetHandle)> { let info = chain.info(); let sync = ChainSync::new( @@ -395,7 +407,13 @@ impl Protocol { let (peerset, peerset_handle) = sc_peerset::Peerset::from_config(peerset_config); let versions = &((MIN_VERSION as u8)..=(CURRENT_VERSION as u8)).collect::>(); - let mut behaviour = GenericProto::new(protocol_id.clone(), versions, peerset, queue_size_report); + let mut behaviour = GenericProto::new( + local_peer_id, + protocol_id.clone(), + versions, + build_status_message(&config, &chain), + peerset, + ); let mut legacy_equiv_by_name = HashMap::new(); @@ -425,6 +443,7 @@ impl Protocol { propagate_timeout: Box::pin(interval(PROPAGATE_TIMEOUT)), pending_messages: VecDeque::new(), pending_transactions: FuturesUnordered::new(), + pending_transactions_peers: HashMap::new(), config, context_data: ContextData { peers: HashMap::new(), @@ -433,10 +452,8 @@ impl Protocol { }, genesis_hash: info.genesis_hash, sync, - handshaking_peers: HashMap::new(), important_peers, transaction_pool, - finality_proof_provider, peerset_handle: peerset_handle.clone(), behaviour, protocol_name_by_engine: HashMap::new(), @@ -449,7 +466,6 @@ impl Protocol { None }, boot_node_ids, - use_new_block_requests_protocol, }; Ok((protocol, peerset_handle)) @@ -524,9 +540,9 @@ impl Protocol { self.sync.status().queued_blocks } - /// Number of processed blocks. - pub fn num_processed_blocks(&self) -> usize { - self.sync.num_processed_blocks() + /// Number of downloaded blocks. + pub fn num_downloaded_blocks(&self) -> usize { + self.sync.num_downloaded_blocks() } /// Number of active sync requests. @@ -534,28 +550,20 @@ impl Protocol { self.sync.num_sync_requests() } - /// Accepts a response from the legacy substream and determines what the corresponding - /// request was. - fn handle_response( - &mut self, - who: PeerId, - response: &message::BlockResponse - ) -> Option> { - if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) { - if let Some(_) = peer.obsolete_requests.remove(&response.id) { - trace!(target: "sync", "Ignoring obsolete block response packet from {} ({})", who, response.id); - return None; - } - // Clear the request. If the response is invalid peer will be disconnected anyway. - let request = peer.block_request.take(); - if request.as_ref().map_or(false, |(_, r)| r.id == response.id) { - return request.map(|(_, r)| r) - } - trace!(target: "sync", "Unexpected response packet from {} ({})", who, response.id); - self.peerset_handle.report_peer(who.clone(), rep::UNEXPECTED_RESPONSE); - self.behaviour.disconnect_peer(&who); - } - None + /// Sync local state with the blockchain state. + pub fn update_chain(&mut self) { + let info = self.context_data.chain.info(); + self.sync.update_chain_info(&info.best_hash, info.best_number); + self.behaviour.set_legacy_handshake_message(build_status_message(&self.config, &self.context_data.chain)); + self.behaviour.set_notif_protocol_handshake( + &self.block_announces_protocol, + BlockAnnouncesHandshake::build(&self.config, &self.context_data.chain).encode() + ); + } + + /// Inform sync about an own imported block. + pub fn own_block_imported(&mut self, hash: B::Hash, number: NumberFor) { + self.sync.update_chain_info(&hash, number); } fn update_peer_info(&mut self, who: &PeerId) { @@ -582,7 +590,7 @@ impl Protocol { Ok(message) => message, Err(err) => { debug!(target: "sync", "Couldn't decode packet sent by {}: {:?}: {}", who, data, err.what()); - self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE); + self.peerset_handle.report_peer(who, rep::BAD_MESSAGE); return CustomMessageOutcome::None; } }; @@ -592,14 +600,13 @@ impl Protocol { stats.count_in += 1; match message { - GenericMessage::Status(s) => return self.on_status_message(who, s), + GenericMessage::Status(_) => + debug!(target: "sub-libp2p", "Received unexpected Status"), GenericMessage::BlockRequest(r) => self.on_block_request(who, r), GenericMessage::BlockResponse(r) => { - if let Some(request) = self.handle_response(who.clone(), &r) { - let outcome = self.on_block_response(who.clone(), request, r); - self.update_peer_info(&who); - return outcome - } + let outcome = self.on_block_response(who.clone(), r); + self.update_peer_info(&who); + return outcome }, GenericMessage::BlockAnnounce(announce) => { let outcome = self.on_block_announce(who.clone(), announce); @@ -607,32 +614,35 @@ impl Protocol { return outcome; }, GenericMessage::Transactions(m) => - self.on_extrinsics(who, m), - GenericMessage::RemoteCallRequest(request) => self.on_remote_call_request(who, request), + self.on_transactions(who, m), GenericMessage::RemoteCallResponse(_) => warn!(target: "sub-libp2p", "Received unexpected RemoteCallResponse"), - GenericMessage::RemoteReadRequest(request) => - self.on_remote_read_request(who, request), GenericMessage::RemoteReadResponse(_) => warn!(target: "sub-libp2p", "Received unexpected RemoteReadResponse"), - GenericMessage::RemoteHeaderRequest(request) => - self.on_remote_header_request(who, request), GenericMessage::RemoteHeaderResponse(_) => warn!(target: "sub-libp2p", "Received unexpected RemoteHeaderResponse"), - GenericMessage::RemoteChangesRequest(request) => - self.on_remote_changes_request(who, request), GenericMessage::RemoteChangesResponse(_) => warn!(target: "sub-libp2p", "Received unexpected RemoteChangesResponse"), - GenericMessage::FinalityProofRequest(request) => - self.on_finality_proof_request(who, request), - GenericMessage::FinalityProofResponse(response) => - return self.on_finality_proof_response(who, response), - GenericMessage::RemoteReadChildRequest(request) => - self.on_remote_read_child_request(who, request), + GenericMessage::FinalityProofResponse(_) => + warn!(target: "sub-libp2p", "Received unexpected FinalityProofResponse"), + GenericMessage::FinalityProofRequest(_) | + GenericMessage::RemoteReadChildRequest(_) | + GenericMessage::RemoteCallRequest(_) | + GenericMessage::RemoteReadRequest(_) | + GenericMessage::RemoteHeaderRequest(_) | + GenericMessage::RemoteChangesRequest(_) => { + debug!( + target: "sub-libp2p", + "Received no longer supported legacy request from {:?}", + who + ); + self.disconnect_peer(&who); + self.peerset_handle.report_peer(who, rep::BAD_PROTOCOL); + }, GenericMessage::Consensus(msg) => return if self.protocol_name_by_engine.contains_key(&msg.engine_id) { CustomMessageOutcome::NotificationsReceived { - remote: who.clone(), + remote: who, messages: vec![(msg.engine_id, From::from(msg.data))], } } else { @@ -654,7 +664,7 @@ impl Protocol { return if !messages.is_empty() { CustomMessageOutcome::NotificationsReceived { - remote: who.clone(), + remote: who, messages, } } else { @@ -666,16 +676,6 @@ impl Protocol { CustomMessageOutcome::None } - fn send_request(&mut self, who: &PeerId, message: Message) { - send_request::( - &mut self.behaviour, - &mut self.context_data.stats, - &mut self.context_data.peers, - who, - message, - ); - } - fn send_message( &mut self, who: &PeerId, @@ -691,11 +691,8 @@ impl Protocol { ); } - /// Called when a new peer is connected - pub fn on_peer_connected(&mut self, who: PeerId) { - trace!(target: "sync", "Connecting {}", who); - self.handshaking_peers.insert(who.clone(), HandshakingPeer { timestamp: Instant::now() }); - self.send_status(who); + fn update_peer_request(&mut self, who: &PeerId, request: &mut message::BlockRequest) { + update_peer_request::(&mut self.context_data.peers, who, request) } /// Called by peer when it is disconnecting @@ -706,13 +703,8 @@ impl Protocol { trace!(target: "sync", "{} disconnected", peer); } - // lock all the the peer lists so that add/remove peer events are in order - let removed = { - self.handshaking_peers.remove(&peer); - self.context_data.peers.remove(&peer) - }; - if let Some(_peer_data) = removed { - self.sync.peer_disconnected(peer.clone()); + if let Some(_peer_data) = self.context_data.peers.remove(&peer) { + self.sync.peer_disconnected(&peer); // Notify all the notification protocols as closed. CustomMessageOutcome::NotificationStreamClosed { @@ -724,23 +716,11 @@ impl Protocol { } } - /// Called as a back-pressure mechanism if the networking detects that the peer cannot process - /// our messaging rate fast enough. - pub fn on_clogged_peer(&self, who: PeerId, _msg: Option>) { - self.peerset_handle.report_peer(who.clone(), rep::CLOGGED_PEER); - - // Print some diagnostics. - if let Some(peer) = self.context_data.peers.get(&who) { - debug!(target: "sync", "Clogged peer {} (protocol_version: {:?}; roles: {:?}; \ - known_extrinsics: {:?}; known_blocks: {:?}; best_hash: {:?}; best_number: {:?})", - who, peer.info.protocol_version, peer.info.roles, peer.known_extrinsics, peer.known_blocks, - peer.info.best_hash, peer.info.best_number); - } else { - debug!(target: "sync", "Peer clogged before being properly connected"); + fn on_block_request(&mut self, peer: PeerId, request: message::BlockRequest) { + if let Some(metrics) = &self.metrics { + metrics.legacy_requests_received.with_label_values(&["block-request"]).inc(); } - } - fn on_block_request(&mut self, peer: PeerId, request: message::BlockRequest) { trace!(target: "sync", "BlockRequest {} from {}: from {:?} to {:?} max {:?} for {:?}", request.id, peer, @@ -769,13 +749,14 @@ impl Protocol { let get_justification = request .fields .contains(message::BlockAttributes::JUSTIFICATION); + let mut total_size = 0; while let Some(header) = self.context_data.chain.header(id).unwrap_or(None) { - if blocks.len() >= max { + if blocks.len() >= max || (blocks.len() >= 1 && total_size > MAX_BODIES_BYTES) { break; } - let number = header.number().clone(); + let number = *header.number(); let hash = header.hash(); - let parent_hash = header.parent_hash().clone(); + let parent_hash = *header.parent_hash(); let justification = if get_justification { self.context_data.chain.justification(&BlockId::Hash(hash)).unwrap_or(None) } else { @@ -801,6 +782,7 @@ impl Protocol { trace!(target: "sync", "Missing data for block request."); break; } + total_size += block_data.body.as_ref().map_or(0, |b| b.len()); blocks.push(block_data); match request.direction { message::Direction::Ascending => id = BlockId::Number(number + One::one()), @@ -830,9 +812,34 @@ impl Protocol { pub fn on_block_response( &mut self, peer: PeerId, - request: message::BlockRequest, response: message::BlockResponse, ) -> CustomMessageOutcome { + let request = if let Some(ref mut p) = self.context_data.peers.get_mut(&peer) { + if p.obsolete_requests.remove(&response.id).is_some() { + trace!(target: "sync", "Ignoring obsolete block response packet from {} ({})", peer, response.id); + return CustomMessageOutcome::None; + } + // Clear the request. If the response is invalid peer will be disconnected anyway. + match p.block_request.take() { + Some((_, request)) if request.id == response.id => request, + Some(_) => { + trace!(target: "sync", "Ignoring obsolete block response packet from {} ({})", peer, response.id); + return CustomMessageOutcome::None; + } + None => { + trace!(target: "sync", "Unexpected response packet from unknown peer {}", peer); + self.behaviour.disconnect_peer(&peer); + self.peerset_handle.report_peer(peer, rep::UNEXPECTED_RESPONSE); + return CustomMessageOutcome::None; + } + } + } else { + trace!(target: "sync", "Unexpected response packet from unknown peer {}", peer); + self.behaviour.disconnect_peer(&peer); + self.peerset_handle.report_peer(peer, rep::UNEXPECTED_RESPONSE); + return CustomMessageOutcome::None; + }; + let blocks_range = || match ( response.blocks.first().and_then(|b| b.header.as_ref().map(|h| h.number())), response.blocks.last().and_then(|b| b.header.as_ref().map(|h| h.number())), @@ -874,18 +881,14 @@ impl Protocol { return CustomMessageOutcome::None } - match self.sync.on_block_data(peer, Some(request), response) { + match self.sync.on_block_data(&peer, Some(request), response) { Ok(sync::OnBlockData::Import(origin, blocks)) => CustomMessageOutcome::BlockImport(origin, blocks), - Ok(sync::OnBlockData::Request(peer, req)) => { - if self.use_new_block_requests_protocol { - CustomMessageOutcome::BlockRequest { - target: peer, - request: req, - } - } else { - self.send_request(&peer, GenericMessage::BlockRequest(req)); - CustomMessageOutcome::None + Ok(sync::OnBlockData::Request(peer, mut req)) => { + self.update_peer_request(&peer, &mut req); + CustomMessageOutcome::BlockRequest { + target: peer, + request: req, } } Err(sync::BadPeer(id, repu)) => { @@ -935,16 +938,6 @@ impl Protocol { aborting.push(who.clone()); } } - for (who, _) in self.handshaking_peers.iter() - .filter(|(_, handshaking)| (tick - handshaking.timestamp).as_secs() > REQUEST_TIMEOUT_SEC) - { - log!( - target: "sync", - if self.important_peers.contains(who) { Level::Warn } else { Level::Trace }, - "Handshake timeout {}", who - ); - aborting.push(who.clone()); - } } for p in aborting { @@ -953,17 +946,17 @@ impl Protocol { } } - /// Called by peer to report status - fn on_status_message(&mut self, who: PeerId, status: message::Status) -> CustomMessageOutcome { + /// Called on receipt of a status message via the legacy protocol on the first connection between two peers. + pub fn on_peer_connected( + &mut self, + who: PeerId, + status: message::Status, + notifications_sink: NotificationsSink, + ) -> CustomMessageOutcome { trace!(target: "sync", "New peer {} {:?}", who, status); let _protocol_version = { if self.context_data.peers.contains_key(&who) { - log!( - target: "sync", - if self.important_peers.contains(&who) { Level::Warn } else { Level::Debug }, - "Unexpected status packet from {}", who - ); - self.peerset_handle.report_peer(who, rep::UNEXPECTED_STATUS); + debug!(target: "sync", "Ignoring duplicate status packet from {}", who); return CustomMessageOutcome::None; } if status.genesis_hash != self.genesis_hash { @@ -1026,25 +1019,15 @@ impl Protocol { } } - let info = match self.handshaking_peers.remove(&who) { - Some(_handshaking) => { - PeerInfo { - protocol_version: status.version, - roles: status.roles, - best_hash: status.best_hash, - best_number: status.best_number - } - }, - None => { - error!(target: "sync", "Received status from previously unconnected node {}", who); - return CustomMessageOutcome::None; - }, - }; - let peer = Peer { - info, + info: PeerInfo { + protocol_version: status.version, + roles: status.roles, + best_hash: status.best_hash, + best_number: status.best_number + }, block_request: None, - known_extrinsics: LruHashSet::new(NonZeroUsize::new(MAX_KNOWN_EXTRINSICS) + known_transactions: LruHashSet::new(NonZeroUsize::new(MAX_KNOWN_TRANSACTIONS) .expect("Constant is nonzero")), known_blocks: LruHashSet::new(NonZeroUsize::new(MAX_KNOWN_BLOCKS) .expect("Constant is nonzero")), @@ -1062,15 +1045,12 @@ impl Protocol { if info.roles.is_full() { match self.sync.new_peer(who.clone(), info.best_hash, info.best_number) { Ok(None) => (), - Ok(Some(req)) => { - if self.use_new_block_requests_protocol { - self.pending_messages.push_back(CustomMessageOutcome::BlockRequest { - target: who.clone(), - request: req, - }); - } else { - self.send_request(&who, GenericMessage::BlockRequest(req)) - } + Ok(Some(mut req)) => { + self.update_peer_request(&who, &mut req); + self.pending_messages.push_back(CustomMessageOutcome::BlockRequest { + target: who.clone(), + request: req, + }); }, Err(sync::BadPeer(id, repu)) => { self.behaviour.disconnect_peer(&id); @@ -1084,32 +1064,7 @@ impl Protocol { remote: who, protocols: self.protocol_name_by_engine.keys().cloned().collect(), roles: info.roles, - } - } - - /// Send a notification to the given peer we're connected to. - /// - /// Doesn't do anything if we don't have a notifications substream for that protocol with that - /// peer. - pub fn write_notification( - &mut self, - target: PeerId, - engine_id: ConsensusEngineId, - message: impl Into>, - ) { - if let Some(protocol_name) = self.protocol_name_by_engine.get(&engine_id) { - let message = message.into(); - let fallback = GenericMessage::<(), (), (), ()>::Consensus(ConsensusMessage { - engine_id, - data: message.clone(), - }).encode(); - self.behaviour.write_notification(&target, protocol_name.clone(), message, fallback); - } else { - error!( - target: "sub-libp2p", - "Sending a notification with a protocol that wasn't registered: {:?}", - engine_id - ); + notifications_sink, } } @@ -1123,7 +1078,7 @@ impl Protocol { engine_id: ConsensusEngineId, protocol_name: impl Into>, handshake_message: Vec, - ) -> impl ExactSizeIterator + 'a { + ) -> impl Iterator + 'a { let protocol_name = protocol_name.into(); if self.protocol_name_by_engine.insert(engine_id, protocol_name.clone()).is_some() { error!(target: "sub-libp2p", "Notifications protocol already registered: {:?}", protocol_name); @@ -1132,32 +1087,40 @@ impl Protocol { self.legacy_equiv_by_name.insert(protocol_name, Fallback::Consensus(engine_id)); } - self.context_data.peers.iter() - .map(|(peer_id, peer)| (peer_id, peer.info.roles)) + let behaviour = &self.behaviour; + self.context_data.peers.iter().filter_map(move |(peer_id, peer)| { + if let Some(notifications_sink) = behaviour.notifications_sink(peer_id) { + Some((peer_id, peer.info.roles, notifications_sink)) + } else { + log::error!("State mismatch: no notifications sink for opened peer {:?}", peer_id); + None + } + }) } - /// Called when peer sends us new extrinsics - fn on_extrinsics( + /// Called when peer sends us new transactions + fn on_transactions( &mut self, who: PeerId, - extrinsics: message::Transactions + transactions: message::Transactions, ) { - // sending extrinsic to light node is considered a bad behavior + // sending transaction to light node is considered a bad behavior if !self.config.roles.is_full() { - trace!(target: "sync", "Peer {} is trying to send extrinsic to the light node", who); + trace!(target: "sync", "Peer {} is trying to send transactions to the light node", who); self.behaviour.disconnect_peer(&who); - self.peerset_handle.report_peer(who, rep::UNEXPECTED_EXTRINSICS); + self.peerset_handle.report_peer(who, rep::UNEXPECTED_TRANSACTIONS); return; } - // Accept extrinsics only when fully synced + // Accept transactions only when fully synced if self.sync.status().state != SyncState::Idle { - trace!(target: "sync", "{} Ignoring extrinsics while syncing", who); + trace!(target: "sync", "{} Ignoring transactions while syncing", who); return; } - trace!(target: "sync", "Received {} extrinsics from {}", extrinsics.len(), who); + + trace!(target: "sync", "Received {} transactions from {}", transactions.len(), who); if let Some(ref mut peer) = self.context_data.peers.get_mut(&who) { - for t in extrinsics { + for t in transactions { if self.pending_transactions.len() > MAX_PENDING_TRANSACTIONS { debug!( target: "sync", @@ -1168,65 +1131,77 @@ impl Protocol { } let hash = self.transaction_pool.hash_of(&t); - peer.known_extrinsics.insert(hash); + peer.known_transactions.insert(hash.clone()); - self.peerset_handle.report_peer(who.clone(), rep::ANY_EXTRINSIC); + self.peerset_handle.report_peer(who.clone(), rep::ANY_TRANSACTION); - self.pending_transactions.push(PendingTransaction { - peer_id: who.clone(), - validation: self.transaction_pool.import(t), - }); + match self.pending_transactions_peers.entry(hash.clone()) { + Entry::Vacant(entry) => { + self.pending_transactions.push(PendingTransaction { + validation: self.transaction_pool.import(t), + tx_hash: hash, + }); + entry.insert(vec![who.clone()]); + }, + Entry::Occupied(mut entry) => { + entry.get_mut().push(who.clone()); + } + } } } } - fn on_handle_extrinsic_import(&mut self, who: PeerId, import: TransactionImport) { + fn on_handle_transaction_import(&mut self, who: PeerId, import: TransactionImport) { match import { - TransactionImport::KnownGood => self.peerset_handle.report_peer(who, rep::ANY_EXTRINSIC_REFUND), - TransactionImport::NewGood => self.peerset_handle.report_peer(who, rep::GOOD_EXTRINSIC), - TransactionImport::Bad => self.peerset_handle.report_peer(who, rep::BAD_EXTRINSIC), + TransactionImport::KnownGood => self.peerset_handle.report_peer(who, rep::ANY_TRANSACTION_REFUND), + TransactionImport::NewGood => self.peerset_handle.report_peer(who, rep::GOOD_TRANSACTION), + TransactionImport::Bad => self.peerset_handle.report_peer(who, rep::BAD_TRANSACTION), TransactionImport::None => {}, } } - /// Propagate one extrinsic. - pub fn propagate_extrinsic( + /// Propagate one transaction. + pub fn propagate_transaction( &mut self, hash: &H, ) { - debug!(target: "sync", "Propagating extrinsic [{:?}]", hash); + debug!(target: "sync", "Propagating transaction [{:?}]", hash); // Accept transactions only when fully synced if self.sync.status().state != SyncState::Idle { return; } - if let Some(extrinsic) = self.transaction_pool.transaction(hash) { - let propagated_to = self.do_propagate_extrinsics(&[(hash.clone(), extrinsic)]); + if let Some(transaction) = self.transaction_pool.transaction(hash) { + let propagated_to = self.do_propagate_transactions(&[(hash.clone(), transaction)]); self.transaction_pool.on_broadcasted(propagated_to); } } - fn do_propagate_extrinsics( + fn do_propagate_transactions( &mut self, - extrinsics: &[(H, B::Extrinsic)], + transactions: &[(H, B::Extrinsic)], ) -> HashMap> { - let mut propagated_to = HashMap::new(); + let mut propagated_to = HashMap::<_, Vec<_>>::new(); + let mut propagated_transactions = 0; + for (who, peer) in self.context_data.peers.iter_mut() { - // never send extrinsics to the light node + // never send transactions to the light node if !peer.info.roles.is_full() { continue; } - let (hashes, to_send): (Vec<_>, Vec<_>) = extrinsics + let (hashes, to_send): (Vec<_>, Vec<_>) = transactions .iter() - .filter(|&(ref hash, _)| peer.known_extrinsics.insert(hash.clone())) + .filter(|&(ref hash, _)| peer.known_transactions.insert(hash.clone())) .cloned() .unzip(); + propagated_transactions += hashes.len(); + if !to_send.is_empty() { for hash in hashes { propagated_to .entry(hash) - .or_insert_with(Vec::new) + .or_default() .push(who.to_base58()); } trace!(target: "sync", "Sending {} transactions to {}", to_send.len(), who); @@ -1241,18 +1216,22 @@ impl Protocol { } } + if let Some(ref metrics) = self.metrics { + metrics.propagated_transactions.inc_by(propagated_transactions as _) + } + propagated_to } - /// Call when we must propagate ready extrinsics to peers. - pub fn propagate_extrinsics(&mut self) { - debug!(target: "sync", "Propagating extrinsics"); + /// Call when we must propagate ready transactions to peers. + pub fn propagate_transactions(&mut self) { + debug!(target: "sync", "Propagating transactions"); // Accept transactions only when fully synced if self.sync.status().state != SyncState::Idle { return; } - let extrinsics = self.transaction_pool.transactions(); - let propagated_to = self.do_propagate_extrinsics(&extrinsics); + let transactions = self.transaction_pool.transactions(); + let propagated_to = self.do_propagate_transactions(&transactions); self.transaction_pool.on_broadcasted(propagated_to); } @@ -1279,7 +1258,7 @@ impl Protocol { } let is_best = self.context_data.chain.info().best_hash == hash; - debug!(target: "sync", "Reannouncing block {:?}", hash); + debug!(target: "sync", "Reannouncing block {:?} is_best: {}", hash, is_best); self.send_announcement(&header, data, is_best, true) } @@ -1321,22 +1300,6 @@ impl Protocol { } } - /// Send Status message - fn send_status(&mut self, who: PeerId) { - let info = self.context_data.chain.info(); - let status = message::generic::Status { - version: CURRENT_VERSION, - min_supported_version: MIN_VERSION, - genesis_hash: info.genesis_hash, - roles: self.config.roles.into(), - best_number: info.best_number, - best_hash: info.best_hash, - chain_status: Vec::new(), // TODO: find a way to make this backwards-compatible - }; - - self.send_message(&who, None, GenericMessage::Status(status)) - } - fn on_block_announce( &mut self, who: PeerId, @@ -1354,7 +1317,7 @@ impl Protocol { message::BlockState::Normal => false, }; - match self.sync.on_block_announce(who.clone(), hash, &announce, is_their_best) { + match self.sync.on_block_announce(&who, hash, &announce, is_their_best) { sync::OnBlockAnnounce::Nothing => { // `on_block_announce` returns `OnBlockAnnounce::ImportHeader` // when we have all data required to import the block @@ -1374,7 +1337,7 @@ impl Protocol { // to import header from announced block let's construct response to request that normally would have // been sent over network (but it is not in our case) let blocks_to_import = self.sync.on_block_data( - who.clone(), + &who, None, message::generic::BlockResponse { id: 0, @@ -1399,15 +1362,11 @@ impl Protocol { Ok(sync::OnBlockData::Import(origin, blocks)) => { CustomMessageOutcome::BlockImport(origin, blocks) }, - Ok(sync::OnBlockData::Request(peer, req)) => { - if self.use_new_block_requests_protocol { - CustomMessageOutcome::BlockRequest { - target: peer, - request: req, - } - } else { - self.send_request(&peer, GenericMessage::BlockRequest(req)); - CustomMessageOutcome::None + Ok(sync::OnBlockData::Request(peer, mut req)) => { + self.update_peer_request(&peer, &mut req); + CustomMessageOutcome::BlockRequest { + target: peer, + request: req, } } Err(sync::BadPeer(id, repu)) => { @@ -1418,63 +1377,12 @@ impl Protocol { } } - /// Call this when a block has been imported in the import queue - pub fn on_block_imported(&mut self, header: &B::Header, is_best: bool) { - if is_best { - self.sync.update_chain_info(header); - self.behaviour.set_notif_protocol_handshake( - &self.block_announces_protocol, - BlockAnnouncesHandshake::build(&self.config, &self.context_data.chain).encode() - ); - } - } - /// Call this when a block has been finalized. The sync layer may have some additional /// requesting to perform. pub fn on_block_finalized(&mut self, hash: B::Hash, header: &B::Header) { self.sync.on_block_finalized(&hash, *header.number()) } - fn on_remote_call_request( - &mut self, - who: PeerId, - request: message::RemoteCallRequest, - ) { - trace!(target: "sync", "Remote call request {} from {} ({} at {})", - request.id, - who, - request.method, - request.block - ); - let proof = match self.context_data.chain.execution_proof( - &BlockId::Hash(request.block), - &request.method, - &request.data, - ) { - Ok((_, proof)) => proof, - Err(error) => { - trace!(target: "sync", "Remote call request {} from {} ({} at {}) failed with: {}", - request.id, - who, - request.method, - request.block, - error - ); - self.peerset_handle.report_peer(who.clone(), rep::RPC_FAILED); - StorageProof::empty() - } - }; - - self.send_message( - &who, - None, - GenericMessage::RemoteCallResponse(message::RemoteCallResponse { - id: request.id, - proof, - }), - ); - } - /// Request a justification for the given block. /// /// Uses `protocol` to queue a new justification request and tries to dispatch all pending @@ -1493,12 +1401,24 @@ impl Protocol { /// A batch of blocks have been processed, with or without errors. /// Call this when a batch of blocks have been processed by the importqueue, with or without /// errors. - pub fn blocks_processed( + pub fn on_blocks_processed( &mut self, imported: usize, count: usize, results: Vec<(Result>, BlockImportError>, B::Hash)> ) { + let new_best = results.iter().rev().find_map(|r| match r { + (Ok(BlockImportResult::ImportedUnknown(n, aux, _)), hash) if aux.is_new_best => Some((*n, hash.clone())), + _ => None, + }); + if let Some((best_num, best_hash)) = new_best { + self.sync.update_chain_info(&best_hash, best_num); + self.behaviour.set_legacy_handshake_message(build_status_message(&self.config, &self.context_data.chain)); + self.behaviour.set_notif_protocol_handshake( + &self.block_announces_protocol, + BlockAnnouncesHandshake::build(&self.config, &self.context_data.chain).encode() + ); + } let results = self.sync.on_blocks_processed( imported, count, @@ -1506,22 +1426,12 @@ impl Protocol { ); for result in results { match result { - Ok((id, req)) => { - if self.use_new_block_requests_protocol { - self.pending_messages.push_back(CustomMessageOutcome::BlockRequest { - target: id, - request: req, - }); - } else { - let msg = GenericMessage::BlockRequest(req); - send_request( - &mut self.behaviour, - &mut self.context_data.stats, - &mut self.context_data.peers, - &id, - msg - ) - } + Ok((id, mut req)) => { + update_peer_request(&mut self.context_data.peers, &id, &mut req); + self.pending_messages.push_back(CustomMessageOutcome::BlockRequest { + target: id, + request: req, + }); } Err(sync::BadPeer(id, repu)) => { self.behaviour.disconnect_peer(&id); @@ -1559,237 +1469,6 @@ impl Protocol { self.sync.on_finality_proof_import(request_block, finalization_result) } - fn on_remote_read_request( - &mut self, - who: PeerId, - request: message::RemoteReadRequest, - ) { - if request.keys.is_empty() { - debug!(target: "sync", "Invalid remote read request sent by {}", who); - self.behaviour.disconnect_peer(&who); - self.peerset_handle.report_peer(who, rep::BAD_MESSAGE); - return; - } - - let keys_str = || match request.keys.len() { - 1 => HexDisplay::from(&request.keys[0]).to_string(), - _ => format!( - "{}..{}", - HexDisplay::from(&request.keys[0]), - HexDisplay::from(&request.keys[request.keys.len() - 1]), - ), - }; - - trace!(target: "sync", "Remote read request {} from {} ({} at {})", - request.id, who, keys_str(), request.block); - let proof = match self.context_data.chain.read_proof( - &BlockId::Hash(request.block), - &mut request.keys.iter().map(AsRef::as_ref) - ) { - Ok(proof) => proof, - Err(error) => { - trace!(target: "sync", "Remote read request {} from {} ({} at {}) failed with: {}", - request.id, - who, - keys_str(), - request.block, - error - ); - StorageProof::empty() - } - }; - self.send_message( - &who, - None, - GenericMessage::RemoteReadResponse(message::RemoteReadResponse { - id: request.id, - proof, - }), - ); - } - - fn on_remote_read_child_request( - &mut self, - who: PeerId, - request: message::RemoteReadChildRequest, - ) { - if request.keys.is_empty() { - debug!(target: "sync", "Invalid remote child read request sent by {}", who); - self.behaviour.disconnect_peer(&who); - self.peerset_handle.report_peer(who, rep::BAD_MESSAGE); - return; - } - - let keys_str = || match request.keys.len() { - 1 => HexDisplay::from(&request.keys[0]).to_string(), - _ => format!( - "{}..{}", - HexDisplay::from(&request.keys[0]), - HexDisplay::from(&request.keys[request.keys.len() - 1]), - ), - }; - - trace!(target: "sync", "Remote read child request {} from {} ({} {} at {})", - request.id, who, HexDisplay::from(&request.storage_key), keys_str(), request.block); - let prefixed_key = PrefixedStorageKey::new_ref(&request.storage_key); - let child_info = match ChildType::from_prefixed_key(prefixed_key) { - Some((ChildType::ParentKeyId, storage_key)) => Ok(ChildInfo::new_default(storage_key)), - None => Err("Invalid child storage key".into()), - }; - let proof = match child_info.and_then(|child_info| self.context_data.chain.read_child_proof( - &BlockId::Hash(request.block), - &child_info, - &mut request.keys.iter().map(AsRef::as_ref), - )) { - Ok(proof) => proof, - Err(error) => { - trace!(target: "sync", "Remote read child request {} from {} ({} {} at {}) failed with: {}", - request.id, - who, - HexDisplay::from(&request.storage_key), - keys_str(), - request.block, - error - ); - StorageProof::empty() - } - }; - self.send_message( - &who, - None, - GenericMessage::RemoteReadResponse(message::RemoteReadResponse { - id: request.id, - proof, - }), - ); - } - - fn on_remote_header_request( - &mut self, - who: PeerId, - request: message::RemoteHeaderRequest>, - ) { - trace!(target: "sync", "Remote header proof request {} from {} ({})", - request.id, who, request.block); - let (header, proof) = match self.context_data.chain.header_proof(&BlockId::Number(request.block)) { - Ok((header, proof)) => (Some(header), proof), - Err(error) => { - trace!(target: "sync", "Remote header proof request {} from {} ({}) failed with: {}", - request.id, - who, - request.block, - error - ); - (Default::default(), StorageProof::empty()) - } - }; - self.send_message( - &who, - None, - GenericMessage::RemoteHeaderResponse(message::RemoteHeaderResponse { - id: request.id, - header, - proof, - }), - ); - } - - fn on_remote_changes_request( - &mut self, - who: PeerId, - request: message::RemoteChangesRequest, - ) { - trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{})", - request.id, - who, - if let Some(sk) = request.storage_key.as_ref() { - format!("{} : {}", HexDisplay::from(sk), HexDisplay::from(&request.key)) - } else { - HexDisplay::from(&request.key).to_string() - }, - request.first, - request.last - ); - let key = StorageKey(request.key); - let prefixed_key = request.storage_key.as_ref() - .map(|storage_key| PrefixedStorageKey::new_ref(storage_key)); - let (first, last, min, max) = (request.first, request.last, request.min, request.max); - let proof = match self.context_data.chain.key_changes_proof( - first, - last, - min, - max, - prefixed_key, - &key, - ) { - Ok(proof) => proof, - Err(error) => { - trace!(target: "sync", "Remote changes proof request {} from {} for key {} ({}..{}) failed with: {}", - request.id, - who, - if let Some(sk) = request.storage_key.as_ref() { - format!("{} : {}", HexDisplay::from(sk), HexDisplay::from(&key.0)) - } else { - HexDisplay::from(&key.0).to_string() - }, - request.first, - request.last, - error - ); - ChangesProof:: { - max_block: Zero::zero(), - proof: vec![], - roots: BTreeMap::new(), - roots_proof: StorageProof::empty(), - } - } - }; - self.send_message( - &who, - None, - GenericMessage::RemoteChangesResponse(message::RemoteChangesResponse { - id: request.id, - max: proof.max_block, - proof: proof.proof, - roots: proof.roots.into_iter().collect(), - roots_proof: proof.roots_proof, - }), - ); - } - - fn on_finality_proof_request( - &mut self, - who: PeerId, - request: message::FinalityProofRequest, - ) { - trace!(target: "sync", "Finality proof request from {} for {}", who, request.block); - let finality_proof = self.finality_proof_provider.as_ref() - .ok_or_else(|| String::from("Finality provider is not configured")) - .and_then(|provider| - provider.prove_finality(request.block, &request.request).map_err(|e| e.to_string()) - ); - let finality_proof = match finality_proof { - Ok(finality_proof) => finality_proof, - Err(error) => { - trace!(target: "sync", "Finality proof request from {} for {} failed with: {}", - who, - request.block, - error - ); - None - }, - }; - self.send_message( - &who, - None, - GenericMessage::FinalityProofResponse(message::FinalityProofResponse { - id: 0, - block: request.block, - proof: finality_proof, - }), - ); - } - /// Must be called after a [`CustomMessageOutcome::FinalityProofRequest`] has been emitted, /// to notify of the response having arrived. pub fn on_finality_proof_response( @@ -1837,9 +1516,6 @@ impl Protocol { } metrics.obsolete_requests.set(obsolete_requests); - let n = self.handshaking_peers.len().try_into().unwrap_or(std::u64::MAX); - metrics.handshaking_peers.set(n); - let n = self.context_data.peers.len().try_into().unwrap_or(std::u64::MAX); metrics.peers.set(n); @@ -1877,7 +1553,18 @@ pub enum CustomMessageOutcome { JustificationImport(Origin, B::Hash, NumberFor, Justification), FinalityProofImport(Origin, B::Hash, NumberFor, Vec), /// Notification protocols have been opened with a remote. - NotificationStreamOpened { remote: PeerId, protocols: Vec, roles: Roles }, + NotificationStreamOpened { + remote: PeerId, + protocols: Vec, + roles: Roles, + notifications_sink: NotificationsSink + }, + /// The [`NotificationsSink`] of some notification protocols need an update. + NotificationStreamReplaced { + remote: PeerId, + protocols: Vec, + notifications_sink: NotificationsSink, + }, /// Notification protocols have been closed with a remote. NotificationStreamClosed { remote: PeerId, protocols: Vec }, /// Messages have been received on one or more notifications protocols. @@ -1900,25 +1587,20 @@ pub enum CustomMessageOutcome { None, } -fn send_request( - behaviour: &mut GenericProto, - stats: &mut HashMap<&'static str, PacketStats>, +fn update_peer_request( peers: &mut HashMap>, who: &PeerId, - mut message: Message, + request: &mut message::BlockRequest, ) { - if let GenericMessage::BlockRequest(ref mut r) = message { - if let Some(ref mut peer) = peers.get_mut(who) { - r.id = peer.next_request_id; - peer.next_request_id = peer.next_request_id + 1; - if let Some((timestamp, request)) = peer.block_request.take() { - trace!(target: "sync", "Request {} for {} is now obsolete.", request.id, who); - peer.obsolete_requests.insert(request.id, timestamp); - } - peer.block_request = Some((Instant::now(), r.clone())); + if let Some(ref mut peer) = peers.get_mut(who) { + request.id = peer.next_request_id; + peer.next_request_id += 1; + if let Some((timestamp, request)) = peer.block_request.take() { + trace!(target: "sync", "Request {} for {} is now obsolete.", request.id, who); + peer.obsolete_requests.insert(request.id, timestamp); } + peer.block_request = Some((Instant::now(), request.clone())); } - send_message::(behaviour, stats, who, None, message) } fn send_message( @@ -1995,64 +1677,40 @@ impl NetworkBehaviour for Protocol { } while let Poll::Ready(Some(())) = self.propagate_timeout.poll_next_unpin(cx) { - self.propagate_extrinsics(); + self.propagate_transactions(); } - for (id, r) in self.sync.block_requests() { - if self.use_new_block_requests_protocol { - let event = CustomMessageOutcome::BlockRequest { - target: id, - request: r, - }; - self.pending_messages.push_back(event); - } else { - send_request( - &mut self.behaviour, - &mut self.context_data.stats, - &mut self.context_data.peers, - &id, - GenericMessage::BlockRequest(r), - ) - } + for (id, mut r) in self.sync.block_requests() { + update_peer_request(&mut self.context_data.peers, &id, &mut r); + let event = CustomMessageOutcome::BlockRequest { + target: id.clone(), + request: r, + }; + self.pending_messages.push_back(event); } - for (id, r) in self.sync.justification_requests() { - if self.use_new_block_requests_protocol { - let event = CustomMessageOutcome::BlockRequest { - target: id, - request: r, - }; - self.pending_messages.push_back(event); - } else { - send_request( - &mut self.behaviour, - &mut self.context_data.stats, - &mut self.context_data.peers, - &id, - GenericMessage::BlockRequest(r), - ) - } + for (id, mut r) in self.sync.justification_requests() { + update_peer_request(&mut self.context_data.peers, &id, &mut r); + let event = CustomMessageOutcome::BlockRequest { + target: id, + request: r, + }; + self.pending_messages.push_back(event); } for (id, r) in self.sync.finality_proof_requests() { - if self.use_new_block_requests_protocol { - let event = CustomMessageOutcome::FinalityProofRequest { - target: id, - block_hash: r.block, - request: r.request, - }; - self.pending_messages.push_back(event); + let event = CustomMessageOutcome::FinalityProofRequest { + target: id, + block_hash: r.block, + request: r.request, + }; + self.pending_messages.push_back(event); + } + if let Poll::Ready(Some((tx_hash, result))) = self.pending_transactions.poll_next_unpin(cx) { + if let Some(peers) = self.pending_transactions_peers.remove(&tx_hash) { + peers.into_iter().for_each(|p| self.on_handle_transaction_import(p, result)); } else { - send_request( - &mut self.behaviour, - &mut self.context_data.stats, - &mut self.context_data.peers, - &id, - GenericMessage::FinalityProofRequest(r), - ) + warn!(target: "sub-libp2p", "Inconsistent state, no peers for pending transaction!"); } } - if let Poll::Ready(Some((peer_id, result))) = self.pending_transactions.poll_next_unpin(cx) { - self.on_handle_extrinsic_import(peer_id, result); - } if let Some(message) = self.pending_messages.pop_front() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(message)); } @@ -2071,12 +1729,42 @@ impl NetworkBehaviour for Protocol { }; let outcome = match event { - GenericProtoOut::CustomProtocolOpen { peer_id, .. } => { - self.on_peer_connected(peer_id.clone()); - CustomMessageOutcome::None + GenericProtoOut::CustomProtocolOpen { peer_id, received_handshake, notifications_sink, .. } => { + match as Decode>::decode(&mut &received_handshake[..]) { + Ok(GenericMessage::Status(handshake)) => + self.on_peer_connected(peer_id, handshake, notifications_sink), + Ok(msg) => { + debug!( + target: "sync", + "Expected Status message from {}, but got {:?}", + peer_id, + msg, + ); + self.peerset_handle.report_peer(peer_id, rep::BAD_MESSAGE); + CustomMessageOutcome::None + } + Err(err) => { + debug!( + target: "sync", + "Couldn't decode handshake sent by {}: {:?}: {}", + peer_id, + received_handshake, + err.what() + ); + self.peerset_handle.report_peer(peer_id, rep::BAD_MESSAGE); + CustomMessageOutcome::None + } + } } + GenericProtoOut::CustomProtocolReplaced { peer_id, notifications_sink, .. } => { + CustomMessageOutcome::NotificationStreamReplaced { + remote: peer_id, + protocols: self.protocol_name_by_engine.keys().cloned().collect(), + notifications_sink, + } + }, GenericProtoOut::CustomProtocolClosed { peer_id, .. } => { - self.on_peer_disconnected(peer_id.clone()) + self.on_peer_disconnected(peer_id) }, GenericProtoOut::LegacyMessage { peer_id, message } => self.on_custom_message(peer_id, message), @@ -2090,7 +1778,7 @@ impl NetworkBehaviour for Protocol { } Some(Fallback::Transactions) => { if let Ok(m) = message::Transactions::decode(&mut message.as_ref()) { - self.on_extrinsics(peer_id, m); + self.on_transactions(peer_id, m); } else { warn!(target: "sub-libp2p", "Failed to decode transactions list"); } @@ -2111,15 +1799,6 @@ impl NetworkBehaviour for Protocol { CustomMessageOutcome::None } } - GenericProtoOut::Clogged { peer_id, messages } => { - debug!(target: "sync", "{} clogging messages:", messages.len()); - for msg in messages.into_iter().take(5) { - let message: Option> = Decode::decode(&mut &msg[..]).ok(); - debug!(target: "sync", "{:?}", message); - self.on_clogged_peer(peer_id.clone(), message); - } - CustomMessageOutcome::None - } }; if let CustomMessageOutcome::None = outcome { @@ -2168,48 +1847,3 @@ impl Drop for Protocol { debug!(target: "sync", "Network stats:\n{}", self.format_stats()); } } - -#[cfg(test)] -mod tests { - use crate::PeerId; - use crate::config::EmptyTransactionPool; - use super::{CustomMessageOutcome, Protocol, ProtocolConfig}; - - use sp_consensus::block_validation::DefaultBlockAnnounceValidator; - use std::sync::Arc; - use substrate_test_runtime_client::{TestClientBuilder, TestClientBuilderExt}; - use substrate_test_runtime_client::runtime::{Block, Hash}; - - #[test] - fn no_handshake_no_notif_closed() { - let client = Arc::new(TestClientBuilder::with_default_backend().build_with_longest_chain().0); - - let (mut protocol, _) = Protocol::::new( - ProtocolConfig::default(), - client.clone(), - Arc::new(EmptyTransactionPool), - None, - None, - From::from(&b"test"[..]), - sc_peerset::PeersetConfig { - in_peers: 10, - out_peers: 10, - bootnodes: Vec::new(), - reserved_only: false, - priority_groups: Vec::new(), - }, - Box::new(DefaultBlockAnnounceValidator::new(client.clone())), - None, - Default::default(), - true, - None, - ).unwrap(); - - let dummy_peer_id = PeerId::random(); - let _ = protocol.on_peer_connected(dummy_peer_id.clone()); - match protocol.on_peer_disconnected(dummy_peer_id) { - CustomMessageOutcome::None => {}, - _ => panic!() - }; - } -} diff --git a/client/network/src/protocol/generic_proto.rs b/client/network/src/protocol/generic_proto.rs index cf8434d8bceffc5140a55d23d4aae1fc4fc4fa43..3133471b0d2493cb0e21b2f6d5d1264f23565f59 100644 --- a/client/network/src/protocol/generic_proto.rs +++ b/client/network/src/protocol/generic_proto.rs @@ -21,7 +21,7 @@ //! network, then performs the Substrate protocol handling on top. pub use self::behaviour::{GenericProto, GenericProtoOut}; -pub use self::handler::LegacyConnectionKillError; +pub use self::handler::{NotifsHandlerError, NotificationsSink, Ready, LegacyConnectionKillError}; mod behaviour; mod handler; diff --git a/client/network/src/protocol/generic_proto/behaviour.rs b/client/network/src/protocol/generic_proto/behaviour.rs index 9ec23d0547574298e0631719e1e7d06f87adebca..f965980640ad67e0c85b30ee26b502055760b3f9 100644 --- a/client/network/src/protocol/generic_proto/behaviour.rs +++ b/client/network/src/protocol/generic_proto/behaviour.rs @@ -15,8 +15,10 @@ // along with Substrate. If not, see . use crate::config::ProtocolId; -use crate::protocol::generic_proto::handler::{NotifsHandlerProto, NotifsHandlerOut, NotifsHandlerIn}; -use crate::protocol::generic_proto::upgrade::RegisteredProtocol; +use crate::protocol::generic_proto::{ + handler::{NotificationsSink, NotifsHandlerProto, NotifsHandlerOut, NotifsHandlerIn}, + upgrade::RegisteredProtocol +}; use bytes::BytesMut; use fnv::FnvHashMap; @@ -30,12 +32,12 @@ use libp2p::swarm::{ PollParameters }; use log::{debug, error, trace, warn}; -use prometheus_endpoint::HistogramVec; +use parking_lot::RwLock; use rand::distributions::{Distribution as _, Uniform}; use smallvec::SmallVec; use std::task::{Context, Poll}; -use std::{borrow::Cow, cmp, collections::hash_map::Entry}; -use std::{error, mem, pin::Pin, str, time::Duration}; +use std::{borrow::Cow, cmp, collections::{hash_map::Entry, VecDeque}}; +use std::{error, mem, pin::Pin, str, sync::Arc, time::Duration}; use wasm_timer::Instant; /// Network behaviour that handles opening substreams for custom protocols with other peers. @@ -109,13 +111,16 @@ use wasm_timer::Instant; /// tries to connect, the connection is accepted. A ban only delays dialing attempts. /// pub struct GenericProto { + /// `PeerId` of the local node. + local_peer_id: PeerId, + /// Legacy protocol to open with peers. Never modified. legacy_protocol: RegisteredProtocol, /// Notification protocols. Entries are only ever added and not removed. /// Contains, for each protocol, the protocol name and the message to send as part of the /// initial handshake. - notif_protocols: Vec<(Cow<'static, [u8]>, Vec)>, + notif_protocols: Vec<(Cow<'static, [u8]>, Arc>>)>, /// Receiver for instructions about who to connect to or disconnect from. peerset: sc_peerset::Peerset, @@ -123,6 +128,18 @@ pub struct GenericProto { /// List of peers in our state. peers: FnvHashMap, + /// The elements in `peers` occasionally contain `Delay` objects that we would normally have + /// to be polled one by one. In order to avoid doing so, as an optimization, every `Delay` is + /// instead put inside of `delays` and reference by a [`DelayId`]. This stream + /// yields `PeerId`s whose `DelayId` is potentially ready. + /// + /// By design, we never remove elements from this list. Elements are removed only when the + /// `Delay` triggers. As such, this stream may produce obsolete elements. + delays: stream::FuturesUnordered + Send>>>, + + /// [`DelayId`] to assign to the next delay. + next_delay_id: DelayId, + /// List of incoming messages we have sent to the peer set manager and that are waiting for an /// answer. incoming: SmallVec<[IncomingPeer; 6]>, @@ -132,12 +149,13 @@ pub struct GenericProto { next_incoming_index: sc_peerset::IncomingIndex, /// Events to produce from `poll()`. - events: SmallVec<[NetworkBehaviourAction; 4]>, - - /// If `Some`, report the message queue sizes on this `Histogram`. - queue_size_report: Option, + events: VecDeque>, } +/// Identifier for a delay firing. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +struct DelayId(u64); + /// State of a peer we're connected to. #[derive(Debug)] enum PeerState { @@ -155,8 +173,8 @@ enum PeerState { /// The peerset requested that we connect to this peer. We are currently not connected. PendingRequest { - /// When to actually start dialing. - timer: futures_timer::Delay, + /// When to actually start dialing. References an entry in `delays`. + timer: DelayId, /// When the `timer` will trigger. timer_deadline: Instant, }, @@ -169,7 +187,7 @@ enum PeerState { /// We may still have ongoing traffic with that peer, but it should cease shortly. Disabled { /// The connections that are currently open for custom protocol traffic. - open: SmallVec<[ConnectionId; crate::MAX_CONNECTIONS_PER_PEER]>, + open: SmallVec<[(ConnectionId, NotificationsSink); crate::MAX_CONNECTIONS_PER_PEER]>, /// If `Some`, any dial attempts to this peer are delayed until the given `Instant`. banned_until: Option, }, @@ -179,9 +197,9 @@ enum PeerState { /// but should get disconnected in a few seconds. DisabledPendingEnable { /// The connections that are currently open for custom protocol traffic. - open: SmallVec<[ConnectionId; crate::MAX_CONNECTIONS_PER_PEER]>, - /// When to enable this remote. - timer: futures_timer::Delay, + open: SmallVec<[(ConnectionId, NotificationsSink); crate::MAX_CONNECTIONS_PER_PEER]>, + /// When to enable this remote. References an entry in `delays`. + timer: DelayId, /// When the `timer` will trigger. timer_deadline: Instant, }, @@ -190,7 +208,7 @@ enum PeerState { /// enabled state. Enabled { /// The connections that are currently open for custom protocol traffic. - open: SmallVec<[ConnectionId; crate::MAX_CONNECTIONS_PER_PEER]>, + open: SmallVec<[(ConnectionId, NotificationsSink); crate::MAX_CONNECTIONS_PER_PEER]>, }, /// We received an incoming connection from this peer and forwarded that @@ -201,35 +219,21 @@ enum PeerState { } impl PeerState { - /// True if there exists any established connection to the peer. - fn is_connected(&self) -> bool { - match self { - PeerState::Disabled { .. } | - PeerState::DisabledPendingEnable { .. } | - PeerState::Enabled { .. } | - PeerState::PendingRequest { .. } | - PeerState::Requested | - PeerState::Incoming { .. } => true, - PeerState::Poisoned | - PeerState::Banned { .. } => false, - } - } - /// True if there exists an established connection to the peer /// that is open for custom protocol traffic. fn is_open(&self) -> bool { self.get_open().is_some() } - /// Returns the connection ID of the first established connection + /// Returns the [`NotificationsSink`] of the first established connection /// that is open for custom protocol traffic. - fn get_open(&self) -> Option { + fn get_open(&self) -> Option<&NotificationsSink> { match self { PeerState::Disabled { open, .. } | PeerState::DisabledPendingEnable { open, .. } | PeerState::Enabled { open, .. } => if !open.is_empty() { - Some(open[0]) + Some(&open[0].1) } else { None } @@ -275,9 +279,27 @@ pub enum GenericProtoOut { CustomProtocolOpen { /// Id of the peer we are connected to. peer_id: PeerId, + /// Handshake that was sent to us. + /// This is normally a "Status" message, but this is out of the concern of this code. + received_handshake: Vec, + /// Object that permits sending notifications to the peer. + notifications_sink: NotificationsSink, }, - /// Closed a custom protocol with the remote. + /// The [`NotificationsSink`] object used to send notifications with the given peer must be + /// replaced with a new one. + /// + /// This event is typically emitted when a transport-level connection is closed and we fall + /// back to a secondary connection. + CustomProtocolReplaced { + /// Id of the peer we are connected to. + peer_id: PeerId, + /// Replacement for the previous [`NotificationsSink`]. + notifications_sink: NotificationsSink, + }, + + /// Closed a custom protocol with the remote. The existing [`NotificationsSink`] should + /// be dropped. CustomProtocolClosed { /// Id of the peer we were connected to. peer_id: PeerId, @@ -304,39 +326,31 @@ pub enum GenericProtoOut { /// Message that has been received. message: BytesMut, }, - - /// The substream used by the protocol is pretty large. We should print avoid sending more - /// messages on it if possible. - Clogged { - /// Id of the peer which is clogged. - peer_id: PeerId, - /// Copy of the messages that are within the buffer, for further diagnostic. - messages: Vec>, - }, } impl GenericProto { /// Creates a `CustomProtos`. - /// - /// The `queue_size_report` is an optional Prometheus metric that can report the size of the - /// messages queue. If passed, it must have one label for the protocol name. pub fn new( + local_peer_id: PeerId, protocol: impl Into, versions: &[u8], + handshake_message: Vec, peerset: sc_peerset::Peerset, - queue_size_report: Option, ) -> Self { - let legacy_protocol = RegisteredProtocol::new(protocol, versions); + let legacy_handshake_message = Arc::new(RwLock::new(handshake_message)); + let legacy_protocol = RegisteredProtocol::new(protocol, versions, legacy_handshake_message); GenericProto { + local_peer_id, legacy_protocol, notif_protocols: Vec::new(), peerset, peers: FnvHashMap::default(), + delays: Default::default(), + next_delay_id: DelayId(0), incoming: SmallVec::new(), next_incoming_index: sc_peerset::IncomingIndex(0), - events: SmallVec::new(), - queue_size_report, + events: VecDeque::new(), } } @@ -349,7 +363,7 @@ impl GenericProto { protocol_name: impl Into>, handshake_msg: impl Into> ) { - self.notif_protocols.push((protocol_name.into(), handshake_msg.into())); + self.notif_protocols.push((protocol_name.into(), Arc::new(RwLock::new(handshake_msg.into())))); } /// Modifies the handshake of the given notifications protocol. @@ -360,24 +374,17 @@ impl GenericProto { protocol_name: &[u8], handshake_message: impl Into> ) { - let handshake_message = handshake_message.into(); if let Some(protocol) = self.notif_protocols.iter_mut().find(|(name, _)| name == &protocol_name) { - protocol.1 = handshake_message.clone(); - } else { - return; + *protocol.1.write() = handshake_message.into(); } + } - // Send an event to all the peers we're connected to, updating the handshake message. - for (peer_id, _) in self.peers.iter().filter(|(_, state)| state.is_connected()) { - self.events.push(NetworkBehaviourAction::NotifyHandler { - peer_id: peer_id.clone(), - handler: NotifyHandler::All, - event: NotifsHandlerIn::UpdateHandshake { - protocol_name: Cow::Owned(protocol_name.to_owned()), - handshake_message: handshake_message.clone(), - }, - }); - } + /// Modifies the handshake of the legacy protocol. + pub fn set_legacy_handshake_message( + &mut self, + handshake_message: impl Into> + ) { + *self.legacy_protocol.handshake_message().write() = handshake_message.into(); } /// Returns the number of discovered nodes that we keep in memory. @@ -395,6 +402,15 @@ impl GenericProto { self.peers.get(peer_id).map(|p| p.is_open()).unwrap_or(false) } + /// Returns the [`NotificationsSink`] that sends notifications to the given peer, or `None` + /// if the custom protocols aren't opened with this peer. + /// + /// If [`GenericProto::is_open`] returns `true` for this `PeerId`, then this method is + /// guaranteed to return `Some`. + pub fn notifications_sink(&self, peer_id: &PeerId) -> Option<&NotificationsSink> { + self.peers.get(peer_id).and_then(|p| p.get_open()) + } + /// Disconnects the given peer if we are connected to it. pub fn disconnect_peer(&mut self, peer_id: &PeerId) { debug!(target: "sub-libp2p", "External API => Disconnect {:?}", peer_id); @@ -441,7 +457,7 @@ impl GenericProto { debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", peer_id); self.peerset.dropped(peer_id.clone()); debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", peer_id); - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), handler: NotifyHandler::All, event: NotifsHandlerIn::Disable, @@ -466,7 +482,7 @@ impl GenericProto { inc.alive = false; debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", peer_id); - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), handler: NotifyHandler::All, event: NotifsHandlerIn::Disable, @@ -507,9 +523,18 @@ impl GenericProto { /// /// Can be called multiple times with the same `PeerId`s. pub fn add_discovered_nodes(&mut self, peer_ids: impl Iterator) { - self.peerset.discovered(peer_ids.into_iter().map(|peer_id| { + let local_peer_id = &self.local_peer_id; + self.peerset.discovered(peer_ids.filter_map(|peer_id| { + if peer_id == *local_peer_id { + error!( + target: "sub-libp2p", + "Discovered our own identity. This is a minor inconsequential bug." + ); + return None; + } + debug!(target: "sub-libp2p", "PSM <= Discovered({:?})", peer_id); - peer_id + Some(peer_id) })); } @@ -530,14 +555,14 @@ impl GenericProto { message: impl Into>, encoded_fallback_message: Vec, ) { - let conn = match self.peers.get(target).and_then(|p| p.get_open()) { + let notifs_sink = match self.peers.get(target).and_then(|p| p.get_open()) { None => { debug!(target: "sub-libp2p", "Tried to sent notification to {:?} without an open channel.", target); return }, - Some(conn) => conn + Some(sink) => sink }; trace!( @@ -547,16 +572,11 @@ impl GenericProto { str::from_utf8(&protocol_name) ); trace!(target: "sub-libp2p", "Handler({:?}) <= Packet", target); - - self.events.push(NetworkBehaviourAction::NotifyHandler { - peer_id: target.clone(), - handler: NotifyHandler::One(conn), - event: NotifsHandlerIn::SendNotification { - message: message.into(), - encoded_fallback_message, - protocol_name, - }, - }); + notifs_sink.send_sync_notification( + &protocol_name, + encoded_fallback_message, + message + ); } /// Sends a message to a peer. @@ -566,25 +586,19 @@ impl GenericProto { /// Also note that even we have a valid open substream, it may in fact be already closed /// without us knowing, in which case the packet will not be received. pub fn send_packet(&mut self, target: &PeerId, message: Vec) { - let conn = match self.peers.get(target).and_then(|p| p.get_open()) { + let notifs_sink = match self.peers.get(target).and_then(|p| p.get_open()) { None => { debug!(target: "sub-libp2p", "Tried to sent packet to {:?} without an open channel.", target); return } - Some(conn) => conn + Some(sink) => sink }; trace!(target: "sub-libp2p", "External API => Packet for {:?}", target); trace!(target: "sub-libp2p", "Handler({:?}) <= Packet", target); - self.events.push(NetworkBehaviourAction::NotifyHandler { - peer_id: target.clone(), - handler: NotifyHandler::One(conn), - event: NotifsHandlerIn::SendLegacy { - message, - } - }); + notifs_sink.send_legacy(message); } /// Returns the state of the peerset manager, for debugging purposes. @@ -600,7 +614,7 @@ impl GenericProto { // If there's no entry in `self.peers`, start dialing. debug!(target: "sub-libp2p", "PSM => Connect({:?}): Starting to connect", entry.key()); debug!(target: "sub-libp2p", "Libp2p <= Dial {:?}", entry.key()); - self.events.push(NetworkBehaviourAction::DialPeer { + self.events.push_back(NetworkBehaviourAction::DialPeer { peer_id: entry.key().clone(), condition: DialPeerCondition::Disconnected }); @@ -613,18 +627,28 @@ impl GenericProto { match mem::replace(occ_entry.get_mut(), PeerState::Poisoned) { PeerState::Banned { ref until } if *until > now => { + let peer_id = occ_entry.key().clone(); debug!(target: "sub-libp2p", "PSM => Connect({:?}): Will start to connect at \ - until {:?}", occ_entry.key(), until); + until {:?}", peer_id, until); + + let delay_id = self.next_delay_id; + self.next_delay_id.0 += 1; + let delay = futures_timer::Delay::new(*until - now); + self.delays.push(async move { + delay.await; + (delay_id, peer_id) + }.boxed()); + *occ_entry.into_mut() = PeerState::PendingRequest { - timer: futures_timer::Delay::new(until.clone() - now), - timer_deadline: until.clone(), + timer: delay_id, + timer_deadline: *until, }; }, PeerState::Banned { .. } => { debug!(target: "sub-libp2p", "PSM => Connect({:?}): Starting to connect", occ_entry.key()); debug!(target: "sub-libp2p", "Libp2p <= Dial {:?}", occ_entry.key()); - self.events.push(NetworkBehaviourAction::DialPeer { + self.events.push_back(NetworkBehaviourAction::DialPeer { peer_id: occ_entry.key().clone(), condition: DialPeerCondition::Disconnected }); @@ -635,12 +659,22 @@ impl GenericProto { open, banned_until: Some(ref banned) } if *banned > now => { + let peer_id = occ_entry.key().clone(); debug!(target: "sub-libp2p", "PSM => Connect({:?}): But peer is banned until {:?}", - occ_entry.key(), banned); + peer_id, banned); + + let delay_id = self.next_delay_id; + self.next_delay_id.0 += 1; + let delay = futures_timer::Delay::new(*banned - now); + self.delays.push(async move { + delay.await; + (delay_id, peer_id) + }.boxed()); + *occ_entry.into_mut() = PeerState::DisabledPendingEnable { open, - timer: futures_timer::Delay::new(banned.clone() - now), - timer_deadline: banned.clone(), + timer: delay_id, + timer_deadline: *banned, }; }, @@ -648,7 +682,7 @@ impl GenericProto { debug!(target: "sub-libp2p", "PSM => Connect({:?}): Enabling connections.", occ_entry.key()); debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", occ_entry.key()); - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: occ_entry.key().clone(), handler: NotifyHandler::All, event: NotifsHandlerIn::Enable, @@ -667,7 +701,7 @@ impl GenericProto { incoming for incoming peer") } debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", occ_entry.key()); - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: occ_entry.key().clone(), handler: NotifyHandler::All, event: NotifsHandlerIn::Enable, @@ -732,7 +766,7 @@ impl GenericProto { PeerState::Enabled { open } => { debug!(target: "sub-libp2p", "PSM => Drop({:?}): Disabling connections.", entry.key()); debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", entry.key()); - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: entry.key().clone(), handler: NotifyHandler::All, event: NotifsHandlerIn::Disable, @@ -778,7 +812,7 @@ impl GenericProto { debug!(target: "sub-libp2p", "PSM => Accept({:?}, {:?}): Obsolete incoming, sending back dropped", index, incoming.peer_id); debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", incoming.peer_id); - self.peerset.dropped(incoming.peer_id.clone()); + self.peerset.dropped(incoming.peer_id); return } @@ -787,7 +821,7 @@ impl GenericProto { debug!(target: "sub-libp2p", "PSM => Accept({:?}, {:?}): Enabling connections.", index, incoming.peer_id); debug!(target: "sub-libp2p", "Handler({:?}) <= Enable", incoming.peer_id); - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: incoming.peer_id, handler: NotifyHandler::All, event: NotifsHandlerIn::Enable, @@ -820,7 +854,7 @@ impl GenericProto { debug!(target: "sub-libp2p", "PSM => Reject({:?}, {:?}): Rejecting connections.", index, incoming.peer_id); debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", incoming.peer_id); - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: incoming.peer_id, handler: NotifyHandler::All, event: NotifsHandlerIn::Disable, @@ -845,7 +879,6 @@ impl NetworkBehaviour for GenericProto { NotifsHandlerProto::new( self.legacy_protocol.clone(), self.notif_protocols.clone(), - self.queue_size_report.clone() ) } @@ -867,7 +900,7 @@ impl NetworkBehaviour for GenericProto { peer_id, endpoint ); *st = PeerState::Enabled { open: SmallVec::new() }; - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), handler: NotifyHandler::One(*conn), event: NotifsHandlerIn::Enable @@ -879,7 +912,7 @@ impl NetworkBehaviour for GenericProto { // this peer", and not "banned" in the sense that we would refuse the peer altogether. (st @ &mut PeerState::Poisoned, endpoint @ ConnectedPoint::Listener { .. }) | (st @ &mut PeerState::Banned { .. }, endpoint @ ConnectedPoint::Listener { .. }) => { - let incoming_id = self.next_incoming_index.clone(); + let incoming_id = self.next_incoming_index; self.next_incoming_index.0 = match self.next_incoming_index.0.checked_add(1) { Some(v) => v, None => { @@ -911,7 +944,7 @@ impl NetworkBehaviour for GenericProto { "Libp2p => Connected({},{:?}): Not requested by PSM, disabling.", peer_id, endpoint); *st = PeerState::Disabled { open: SmallVec::new(), banned_until }; - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), handler: NotifyHandler::One(*conn), event: NotifsHandlerIn::Disable @@ -927,7 +960,7 @@ impl NetworkBehaviour for GenericProto { (PeerState::Enabled { .. }, _) => { debug!(target: "sub-libp2p", "Handler({},{:?}) <= Enable secondary connection", peer_id, conn); - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), handler: NotifyHandler::One(*conn), event: NotifsHandlerIn::Enable @@ -937,7 +970,7 @@ impl NetworkBehaviour for GenericProto { (PeerState::Disabled { .. }, _) | (PeerState::DisabledPendingEnable { .. }, _) => { debug!(target: "sub-libp2p", "Handler({},{:?}) <= Disable secondary connection", peer_id, conn); - self.events.push(NetworkBehaviourAction::NotifyHandler { + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: peer_id.clone(), handler: NotifyHandler::One(*conn), event: NotifsHandlerIn::Disable @@ -957,15 +990,26 @@ impl NetworkBehaviour for GenericProto { // i.e. there is no connection that is open for custom protocols, // in which case `CustomProtocolClosed` was already emitted. let closed = open.is_empty(); - open.retain(|c| c != conn); - if open.is_empty() && !closed { - debug!(target: "sub-libp2p", "External API <= Closed({})", peer_id); - let event = GenericProtoOut::CustomProtocolClosed { - peer_id: peer_id.clone(), - reason: "Disconnected by libp2p".into(), - }; + let sink_closed = open.get(0).map_or(false, |(c, _)| c == conn); + open.retain(|(c, _)| c != conn); + if !closed { + if let Some((_, sink)) = open.get(0) { + if sink_closed { + let event = GenericProtoOut::CustomProtocolReplaced { + peer_id: peer_id.clone(), + notifications_sink: sink.clone(), + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } + } else { + debug!(target: "sub-libp2p", "External API <= Closed({})", peer_id); + let event = GenericProtoOut::CustomProtocolClosed { + peer_id: peer_id.clone(), + reason: "Disconnected by libp2p".into(), + }; - self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } } } _ => {} @@ -981,14 +1025,30 @@ impl NetworkBehaviour for GenericProto { "`inject_disconnected` called for unknown peer {}", peer_id), - Some(PeerState::Disabled { banned_until, .. }) => { + Some(PeerState::Disabled { open, banned_until, .. }) => { + if !open.is_empty() { + debug_assert!(false); + error!( + target: "sub-libp2p", + "State mismatch: disconnected from {} with non-empty list of connections", + peer_id + ); + } debug!(target: "sub-libp2p", "Libp2p => Disconnected({}): Was disabled.", peer_id); if let Some(until) = banned_until { self.peers.insert(peer_id.clone(), PeerState::Banned { until }); } } - Some(PeerState::DisabledPendingEnable { timer_deadline, .. }) => { + Some(PeerState::DisabledPendingEnable { open, timer_deadline, .. }) => { + if !open.is_empty() { + debug_assert!(false); + error!( + target: "sub-libp2p", + "State mismatch: disconnected from {} with non-empty list of connections", + peer_id + ); + } debug!(target: "sub-libp2p", "Libp2p => Disconnected({}): Was disabled but pending enable.", peer_id); @@ -997,7 +1057,15 @@ impl NetworkBehaviour for GenericProto { self.peers.insert(peer_id.clone(), PeerState::Banned { until: timer_deadline }); } - Some(PeerState::Enabled { .. }) => { + Some(PeerState::Enabled { open, .. }) => { + if !open.is_empty() { + debug_assert!(false); + error!( + target: "sub-libp2p", + "State mismatch: disconnected from {} with non-empty list of connections", + peer_id + ); + } debug!(target: "sub-libp2p", "Libp2p => Disconnected({}): Was enabled.", peer_id); debug!(target: "sub-libp2p", "PSM <= Dropped({})", peer_id); self.peerset.dropped(peer_id.clone()); @@ -1010,7 +1078,9 @@ impl NetworkBehaviour for GenericProto { // In the incoming state, we don't report "Dropped". Instead we will just ignore the // corresponding Accept/Reject. Some(PeerState::Incoming { }) => { - if let Some(state) = self.incoming.iter_mut().find(|i| i.peer_id == *peer_id) { + if let Some(state) = self.incoming.iter_mut() + .find(|i| i.alive && i.peer_id == *peer_id) + { debug!(target: "sub-libp2p", "Libp2p => Disconnected({}): Was in incoming mode with id {:?}.", peer_id, state.incoming_id); @@ -1086,57 +1156,111 @@ impl NetworkBehaviour for GenericProto { return }; - let last = match mem::replace(entry.get_mut(), PeerState::Poisoned) { + let (last, new_notifications_sink) = match mem::replace(entry.get_mut(), PeerState::Poisoned) { PeerState::Enabled { mut open } => { - debug_assert!(open.iter().any(|c| c == &connection)); - open.retain(|c| c != &connection); + let pos = open.iter().position(|(c, _)| c == &connection); + let sink_closed = pos == Some(0); + if let Some(pos) = pos { + open.remove(pos); + } else { + debug_assert!(false); + error!( + target: "sub-libp2p", + "State mismatch with {}: unknown closed connection", + source + ); + } + // TODO: We switch the entire peer state to "disabled" because of possible + // race conditions involving the legacy substream. + // Once https://github.com/paritytech/substrate/issues/5670 is done, this + // should be changed to stay in the `Enabled` state. debug!(target: "sub-libp2p", "Handler({:?}) <= Disable", source); - self.events.push(NetworkBehaviourAction::NotifyHandler { + debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", source); + self.peerset.dropped(source.clone()); + self.events.push_back(NetworkBehaviourAction::NotifyHandler { peer_id: source.clone(), - handler: NotifyHandler::One(connection), + handler: NotifyHandler::All, event: NotifsHandlerIn::Disable, }); let last = open.is_empty(); + let new_notifications_sink = open.iter().next().and_then(|(_, sink)| + if sink_closed { + Some(sink.clone()) + } else { + None + }); - if last { - debug!(target: "sub-libp2p", "PSM <= Dropped({:?})", source); - self.peerset.dropped(source.clone()); - *entry.into_mut() = PeerState::Disabled { - open, - banned_until: None - }; - } else { - *entry.into_mut() = PeerState::Enabled { open }; - } + *entry.into_mut() = PeerState::Disabled { + open, + banned_until: None + }; - last + (last, new_notifications_sink) }, PeerState::Disabled { mut open, banned_until } => { - debug_assert!(open.iter().any(|c| c == &connection)); - open.retain(|c| c != &connection); + let pos = open.iter().position(|(c, _)| c == &connection); + let sink_closed = pos == Some(0); + if let Some(pos) = pos { + open.remove(pos); + } else { + debug_assert!(false); + error!( + target: "sub-libp2p", + "State mismatch with {}: unknown closed connection", + source + ); + } + let last = open.is_empty(); + let new_notifications_sink = open.iter().next().and_then(|(_, sink)| + if sink_closed { + Some(sink.clone()) + } else { + None + }); + *entry.into_mut() = PeerState::Disabled { open, banned_until }; - last + + (last, new_notifications_sink) }, PeerState::DisabledPendingEnable { mut open, timer, timer_deadline } => { - debug_assert!(open.iter().any(|c| c == &connection)); - open.retain(|c| c != &connection); + let pos = open.iter().position(|(c, _)| c == &connection); + let sink_closed = pos == Some(0); + if let Some(pos) = pos { + open.remove(pos); + } else { + debug_assert!(false); + error!( + target: "sub-libp2p", + "State mismatch with {}: unknown closed connection", + source + ); + } + let last = open.is_empty(); + let new_notifications_sink = open.iter().next().and_then(|(_, sink)| + if sink_closed { + Some(sink.clone()) + } else { + None + }); + *entry.into_mut() = PeerState::DisabledPendingEnable { open, timer, timer_deadline }; - last + + (last, new_notifications_sink) }, state => { error!(target: "sub-libp2p", @@ -1150,15 +1274,23 @@ impl NetworkBehaviour for GenericProto { debug!(target: "sub-libp2p", "External API <= Closed({:?})", source); let event = GenericProtoOut::CustomProtocolClosed { reason, - peer_id: source.clone(), + peer_id: source, }; - self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } else { + if let Some(new_notifications_sink) = new_notifications_sink { + let event = GenericProtoOut::CustomProtocolReplaced { + peer_id: source, + notifications_sink: new_notifications_sink, + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } debug!(target: "sub-libp2p", "Secondary connection closed custom protocol."); } } - NotifsHandlerOut::Open { endpoint } => { + NotifsHandlerOut::Open { endpoint, received_handshake, notifications_sink } => { debug!(target: "sub-libp2p", "Handler({:?}) => Endpoint {:?} open for custom protocols.", source, endpoint); @@ -1168,7 +1300,15 @@ impl NetworkBehaviour for GenericProto { Some(PeerState::DisabledPendingEnable { ref mut open, .. }) | Some(PeerState::Disabled { ref mut open, .. }) => { let first = open.is_empty(); - open.push(connection); + if !open.iter().any(|(c, _)| *c == connection) { + open.push((connection, notifications_sink.clone())); + } else { + error!( + target: "sub-libp2p", + "State mismatch: connection with {} opened a second time", + source + ); + } first } state => { @@ -1181,10 +1321,38 @@ impl NetworkBehaviour for GenericProto { if first { debug!(target: "sub-libp2p", "External API <= Open({:?})", source); - let event = GenericProtoOut::CustomProtocolOpen { peer_id: source }; - self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + let event = GenericProtoOut::CustomProtocolOpen { + peer_id: source, + received_handshake, + notifications_sink + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); + } else { - debug!(target: "sub-libp2p", "Secondary connection opened custom protocol."); + // In normal situations, the handshake is supposed to be a Status message, and + // we would discard Status messages received from secondary connections. + // However, in Polkadot 0.8.10 and below, nodes don't send a Status message + // when opening secondary connections and instead directly consider the + // substream as open. When connecting to such a node, the first message sent + // by the remote will always be considered by our local node as the handshake, + // even when it is a regular message. + // In order to maintain backwards compatibility, we therefore report the + // handshake as if it was a regular message, and the upper layer will ignore + // any superfluous Status message. + // The code below should be removed once Polkadot 0.8.10 and below are no + // longer widely in use, and should be replaced with simply printing a log + // entry. + debug!( + target: "sub-libp2p", + "Handler({:?}) => Secondary connection opened custom protocol", + source + ); + trace!(target: "sub-libp2p", "External API <= Message({:?})", source); + let event = GenericProtoOut::LegacyMessage { + peer_id: source, + message: From::from(&received_handshake[..]), + }; + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); } } @@ -1197,7 +1365,7 @@ impl NetworkBehaviour for GenericProto { message, }; - self.events.push(NetworkBehaviourAction::GenerateEvent(event)); + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); } NotifsHandlerOut::Notification { protocol_name, message } => { @@ -1215,19 +1383,7 @@ impl NetworkBehaviour for GenericProto { message, }; - self.events.push(NetworkBehaviourAction::GenerateEvent(event)); - } - - NotifsHandlerOut::Clogged { messages } => { - debug_assert!(self.is_open(&source)); - trace!(target: "sub-libp2p", "Handler({:?}) => Clogged", source); - trace!(target: "sub-libp2p", "External API <= Clogged({:?})", source); - warn!(target: "sub-libp2p", "Queue of packets to send to {:?} is \ - pretty large", source); - self.events.push(NetworkBehaviourAction::GenerateEvent(GenericProtoOut::Clogged { - peer_id: source, - messages, - })); + self.events.push_back(NetworkBehaviourAction::GenerateEvent(event)); } // Don't do anything for non-severe errors except report them. @@ -1263,6 +1419,10 @@ impl NetworkBehaviour for GenericProto { Self::OutEvent, >, > { + if let Some(event) = self.events.pop_front() { + return Poll::Ready(event); + } + // Poll for instructions from the peerset. // Note that the peerset is a *best effort* crate, and we have to use defensive programming. loop { @@ -1287,51 +1447,43 @@ impl NetworkBehaviour for GenericProto { } } - for (peer_id, peer_state) in self.peers.iter_mut() { - match mem::replace(peer_state, PeerState::Poisoned) { - PeerState::PendingRequest { mut timer, timer_deadline } => { - if let Poll::Pending = Pin::new(&mut timer).poll(cx) { - *peer_state = PeerState::PendingRequest { timer, timer_deadline }; - continue; - } - + while let Poll::Ready(Some((delay_id, peer_id))) = + Pin::new(&mut self.delays).poll_next(cx) { + let peer_state = match self.peers.get_mut(&peer_id) { + Some(s) => s, + // We intentionally never remove elements from `delays`, and it may + // thus contain peers which are now gone. This is a normal situation. + None => continue, + }; + + match peer_state { + PeerState::PendingRequest { timer, .. } if *timer == delay_id => { debug!(target: "sub-libp2p", "Libp2p <= Dial {:?} now that ban has expired", peer_id); - self.events.push(NetworkBehaviourAction::DialPeer { - peer_id: peer_id.clone(), + self.events.push_back(NetworkBehaviourAction::DialPeer { + peer_id, condition: DialPeerCondition::Disconnected }); *peer_state = PeerState::Requested; } - PeerState::DisabledPendingEnable { - mut timer, - open, - timer_deadline - } => { - if let Poll::Pending = Pin::new(&mut timer).poll(cx) { - *peer_state = PeerState::DisabledPendingEnable { - timer, - open, - timer_deadline - }; - continue; - } - + PeerState::DisabledPendingEnable { timer, open, .. } if *timer == delay_id => { debug!(target: "sub-libp2p", "Handler({:?}) <= Enable (ban expired)", peer_id); - self.events.push(NetworkBehaviourAction::NotifyHandler { - peer_id: peer_id.clone(), + self.events.push_back(NetworkBehaviourAction::NotifyHandler { + peer_id, handler: NotifyHandler::All, event: NotifsHandlerIn::Enable, }); - *peer_state = PeerState::Enabled { open }; + *peer_state = PeerState::Enabled { open: mem::replace(open, Default::default()) }; } - st @ _ => *peer_state = st, + // We intentionally never remove elements from `delays`, and it may + // thus contain obsolete entries. This is a normal situation. + _ => {}, } } - if !self.events.is_empty() { - return Poll::Ready(self.events.remove(0)) + if let Some(event) = self.events.pop_front() { + return Poll::Ready(event); } Poll::Pending diff --git a/client/network/src/protocol/generic_proto/handler.rs b/client/network/src/protocol/generic_proto/handler.rs index f0e2fc4bb8a8d70af5ef58298fa6d45be07228d8..5845130a7db87d36a84a42db843f25455c7c5d21 100644 --- a/client/network/src/protocol/generic_proto/handler.rs +++ b/client/network/src/protocol/generic_proto/handler.rs @@ -1,20 +1,24 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . -pub use self::group::{NotifsHandlerProto, NotifsHandler, NotifsHandlerIn, NotifsHandlerOut}; +pub use self::group::{ + NotificationsSink, NotifsHandlerError, Ready, NotifsHandlerProto, NotifsHandler, NotifsHandlerIn, NotifsHandlerOut +}; pub use self::legacy::ConnectionKillError as LegacyConnectionKillError; mod group; diff --git a/client/network/src/protocol/generic_proto/handler/group.rs b/client/network/src/protocol/generic_proto/handler/group.rs index 0e453a368c222c38795439d8510240aa3fd93268..bcdbaf848511f7a5d06733096886c78a53111e7b 100644 --- a/client/network/src/protocol/generic_proto/handler/group.rs +++ b/client/network/src/protocol/generic_proto/handler/group.rs @@ -63,9 +63,20 @@ use libp2p::swarm::{ SubstreamProtocol, NegotiatedSubstream, }; +use futures::{ + channel::mpsc, + lock::{Mutex as FuturesMutex, MutexGuard as FuturesMutexGuard}, + prelude::* +}; use log::{debug, error}; -use prometheus_endpoint::HistogramVec; -use std::{borrow::Cow, error, io, str, task::{Context, Poll}}; +use parking_lot::{Mutex, RwLock}; +use std::{borrow::Cow, error, io, str, sync::Arc, task::{Context, Poll}}; + +/// Number of pending notifications in asynchronous contexts. +/// See [`NotificationsSink::reserve_notification`] for context. +const ASYNC_NOTIFICATIONS_BUFFER_SIZE: usize = 8; +/// Number of pending notifications in synchronous contexts. +const SYNC_NOTIFICATIONS_BUFFER_SIZE: usize = 2048; /// Implements the `IntoProtocolsHandler` trait of libp2p. /// @@ -77,10 +88,10 @@ use std::{borrow::Cow, error, io, str, task::{Context, Poll}}; pub struct NotifsHandlerProto { /// Prototypes for handlers for inbound substreams, and the message we respond with in the /// handshake. - in_handlers: Vec<(NotifsInHandlerProto, Vec)>, + in_handlers: Vec<(NotifsInHandlerProto, Arc>>)>, /// Prototypes for handlers for outbound substreams, and the initial handshake message we send. - out_handlers: Vec<(NotifsOutHandlerProto, Vec)>, + out_handlers: Vec<(NotifsOutHandlerProto, Arc>>)>, /// Prototype for handler for backwards-compatibility. legacy: LegacyProtoHandlerProto, @@ -91,14 +102,22 @@ pub struct NotifsHandlerProto { /// See the documentation at the module level for more information. pub struct NotifsHandler { /// Handlers for inbound substreams, and the message we respond with in the handshake. - in_handlers: Vec<(NotifsInHandler, Vec)>, + in_handlers: Vec<(NotifsInHandler, Arc>>)>, /// Handlers for outbound substreams, and the initial handshake message we send. - out_handlers: Vec<(NotifsOutHandler, Vec)>, + out_handlers: Vec<(NotifsOutHandler, Arc>>)>, + + /// Whether we are the connection dialer or listener. + endpoint: ConnectedPoint, /// Handler for backwards-compatibility. legacy: LegacyProtoHandler, + /// In the situation where `legacy.is_open()` is true, but we haven't sent out any + /// [`NotifsHandlerOut::Open`] event yet, this contains the handshake received on the legacy + /// substream. + pending_legacy_handshake: Option>, + /// State of this handler. enabled: EnabledState, @@ -106,6 +125,21 @@ pub struct NotifsHandler { /// we push the corresponding index here and process them when the handler /// gets enabled/disabled. pending_in: Vec, + + /// If `Some`, contains the two `Receiver`s connected to the [`NotificationsSink`] that has + /// been sent out. The notifications to send out can be pulled from this receivers. + /// We use two different channels in order to have two different channel sizes, but from the + /// receiving point of view, the two channels are the same. + /// The receivers are fused in case the user drops the [`NotificationsSink`] entirely. + /// + /// Contains `Some` if and only if it has been reported to the user that the substreams are + /// open. + notifications_sink_rx: Option< + stream::Select< + stream::Fuse>, + stream::Fuse> + > + >, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -136,9 +170,12 @@ impl IntoProtocolsHandler for NotifsHandlerProto { .into_iter() .map(|(proto, msg)| (proto.into_handler(remote_peer_id, connected_point), msg)) .collect(), + endpoint: connected_point.clone(), legacy: self.legacy.into_handler(remote_peer_id, connected_point), + pending_legacy_handshake: None, enabled: EnabledState::Initial, pending_in: Vec::new(), + notifications_sink_rx: None, } } } @@ -151,44 +188,6 @@ pub enum NotifsHandlerIn { /// The node should stop using custom protocols. Disable, - - /// Sends a message through the custom protocol substream. - /// - /// > **Note**: This must **not** be a `ConsensusMessage`, `Transactions`, or - /// > `BlockAnnounce` message. - SendLegacy { - /// The message to send. - message: Vec, - }, - - /// Modifies the handshake message of a notifications protocol. - UpdateHandshake { - /// Name of the protocol for the message. - /// - /// Must match one of the registered protocols. - protocol_name: Cow<'static, [u8]>, - - /// The new handshake message to send if we open a substream or if the remote opens a - /// substream towards us. - handshake_message: Vec, - }, - - /// Sends a notifications message. - SendNotification { - /// Name of the protocol for the message. - /// - /// Must match one of the registered protocols. For backwards-compatibility reasons, if - /// the remote doesn't support this protocol, we use the legacy substream. - protocol_name: Cow<'static, [u8]>, - - /// Message to send on the legacy substream if the protocol isn't available. - /// - /// This corresponds to what you would have sent with `SendLegacy`. - encoded_fallback_message: Vec, - - /// The message to send. - message: Vec, - }, } /// Event that can be emitted by a `NotifsHandler`. @@ -198,6 +197,11 @@ pub enum NotifsHandlerOut { Open { /// The endpoint of the connection that is open for custom protocols. endpoint: ConnectedPoint, + /// Handshake that was sent to us. + /// This is normally a "Status" message, but this out of the concern of this code. + received_handshake: Vec, + /// How notifications can be sent to this node. + notifications_sink: NotificationsSink, }, /// The connection is closed for custom protocols. @@ -226,13 +230,6 @@ pub enum NotifsHandlerOut { message: BytesMut, }, - /// A substream to the remote is clogged. The send buffer is very large, and we should print - /// a diagnostic message and/or avoid sending more data. - Clogged { - /// Copy of the messages that are within the buffer, for further diagnostic. - messages: Vec>, - }, - /// An error has happened on the protocol level with this node. ProtocolError { /// If true the error is severe, such as a protocol violation. @@ -242,19 +239,160 @@ pub enum NotifsHandlerOut { }, } +/// Sink connected directly to the node background task. Allows sending notifications to the peer. +/// +/// Can be cloned in order to obtain multiple references to the same peer. +#[derive(Debug, Clone)] +pub struct NotificationsSink { + inner: Arc, +} + +#[derive(Debug)] +struct NotificationsSinkInner { + /// Sender to use in asynchronous contexts. Uses an asynchronous mutex. + async_channel: FuturesMutex>, + /// Sender to use in synchronous contexts. Uses a synchronous mutex. + /// This channel has a large capacity and is meant to be used in contexts where + /// back-pressure cannot be properly exerted. + /// It will be removed in a future version. + sync_channel: Mutex>, +} + +/// Message emitted through the [`NotificationsSink`] and processed by the background task +/// dedicated to the peer. +#[derive(Debug)] +enum NotificationsSinkMessage { + /// Message emitted by [`NotificationsSink::send_legacy`]. + Legacy { + message: Vec, + }, + + /// Message emitted by [`NotificationsSink::reserve_notification`] and + /// [`NotificationsSink::write_notification_now`]. + Notification { + protocol_name: Vec, + encoded_fallback_message: Vec, + message: Vec, + }, + + /// Must close the connection. + ForceClose, +} + +impl NotificationsSink { + /// Sends a message to the peer using the legacy substream. + /// + /// If too many messages are already buffered, the message is silently discarded and the + /// connection to the peer will be closed shortly after. + /// + /// This method will be removed in a future version. + pub fn send_legacy<'a>(&'a self, message: impl Into>) { + let mut lock = self.inner.sync_channel.lock(); + let result = lock.try_send(NotificationsSinkMessage::Legacy { + message: message.into() + }); + + if result.is_err() { + // Cloning the `mpsc::Sender` guarantees the allocation of an extra spot in the + // buffer, and therefore that `try_send` will succeed. + let _result2 = lock.clone().try_send(NotificationsSinkMessage::ForceClose); + debug_assert!(_result2.map(|()| true).unwrap_or_else(|err| err.is_disconnected())); + } + } + + /// Sends a notification to the peer. + /// + /// If too many messages are already buffered, the notification is silently discarded and the + /// connection to the peer will be closed shortly after. + /// + /// The protocol name is expected to be checked ahead of calling this method. It is a logic + /// error to send a notification using an unknown protocol. + /// + /// This method will be removed in a future version. + pub fn send_sync_notification<'a>( + &'a self, + protocol_name: &[u8], + encoded_fallback_message: impl Into>, + message: impl Into> + ) { + let mut lock = self.inner.sync_channel.lock(); + let result = lock.try_send(NotificationsSinkMessage::Notification { + protocol_name: protocol_name.to_owned(), + encoded_fallback_message: encoded_fallback_message.into(), + message: message.into() + }); + + if result.is_err() { + // Cloning the `mpsc::Sender` guarantees the allocation of an extra spot in the + // buffer, and therefore that `try_send` will succeed. + let _result2 = lock.clone().try_send(NotificationsSinkMessage::ForceClose); + debug_assert!(_result2.map(|()| true).unwrap_or_else(|err| err.is_disconnected())); + } + } + + /// Wait until the remote is ready to accept a notification. + /// + /// Returns an error in the case where the connection is closed. + /// + /// The protocol name is expected to be checked ahead of calling this method. It is a logic + /// error to send a notification using an unknown protocol. + pub async fn reserve_notification<'a>(&'a self, protocol_name: &[u8]) -> Result, ()> { + let mut lock = self.inner.async_channel.lock().await; + + let poll_ready = future::poll_fn(|cx| lock.poll_ready(cx)).await; + if poll_ready.is_ok() { + Ok(Ready { protocol_name: protocol_name.to_owned(), lock }) + } else { + Err(()) + } + } +} + +/// Notification slot is reserved and the notification can actually be sent. +#[must_use] +#[derive(Debug)] +pub struct Ready<'a> { + /// Guarded channel. The channel inside is guaranteed to not be full. + lock: FuturesMutexGuard<'a, mpsc::Sender>, + /// Name of the protocol. Should match one of the protocols passed at initialization. + protocol_name: Vec, +} + +impl<'a> Ready<'a> { + /// Consumes this slots reservation and actually queues the notification. + /// + /// Returns an error if the substream has been closed. + pub fn send( + mut self, + encoded_fallback_message: impl Into>, + notification: impl Into> + ) -> Result<(), ()> { + self.lock.start_send(NotificationsSinkMessage::Notification { + protocol_name: self.protocol_name, + encoded_fallback_message: encoded_fallback_message.into(), + message: notification.into(), + }).map_err(|_| ()) + } +} + +/// Error specific to the collection of protocols. +#[derive(Debug, derive_more::Display, derive_more::Error)] +pub enum NotifsHandlerError { + /// Channel of synchronous notifications is full. + SyncNotificationsClogged, + /// Error in legacy protocol. + Legacy(::Error), +} + impl NotifsHandlerProto { /// Builds a new handler. /// /// `list` is a list of notification protocols names, and the message to send as part of the /// handshake. At the moment, the message is always the same whether we open a substream /// ourselves or respond to handshake from the remote. - /// - /// The `queue_size_report` is an optional Prometheus metric that can report the size of the - /// messages queue. If passed, it must have one label for the protocol name. pub fn new( legacy: RegisteredProtocol, - list: impl Into, Vec)>>, - queue_size_report: Option + list: impl Into, Arc>>)>>, ) -> Self { let list = list.into(); @@ -262,16 +400,7 @@ impl NotifsHandlerProto { .clone() .into_iter() .map(|(proto_name, initial_message)| { - let queue_size_report = queue_size_report.as_ref().and_then(|qs| { - if let Ok(utf8) = str::from_utf8(&proto_name) { - Some(qs.with_label_values(&[utf8])) - } else { - log::warn!("Ignoring Prometheus metric because {:?} isn't UTF-8", proto_name); - None - } - }); - - (NotifsOutHandlerProto::new(proto_name, queue_size_report), initial_message) + (NotifsOutHandlerProto::new(proto_name), initial_message) }).collect(); let in_handlers = list.clone() @@ -290,13 +419,7 @@ impl NotifsHandlerProto { impl ProtocolsHandler for NotifsHandler { type InEvent = NotifsHandlerIn; type OutEvent = NotifsHandlerOut; - type Error = EitherError< - EitherError< - ::Error, - ::Error, - >, - ::Error, - >; + type Error = NotifsHandlerError; type InboundProtocol = SelectUpgrade, RegisteredProtocol>; type OutboundProtocol = EitherUpgrade; // Index within the `out_handlers`; None for legacy @@ -346,12 +469,17 @@ impl ProtocolsHandler for NotifsHandler { self.enabled = EnabledState::Enabled; self.legacy.inject_event(LegacyProtoHandlerIn::Enable); for (handler, initial_message) in &mut self.out_handlers { + // We create `initial_message` on a separate line to be sure that the lock + // is released as soon as possible. + let initial_message = initial_message.read().clone(); handler.inject_event(NotifsOutHandlerIn::Enable { - initial_message: initial_message.clone(), + initial_message, }); } for num in self.pending_in.drain(..) { - let handshake_message = self.in_handlers[num].1.clone(); + // We create `handshake_message` on a separate line to be sure + // that the lock is released as soon as possible. + let handshake_message = self.in_handlers[num].1.read().clone(); self.in_handlers[num].0 .inject_event(NotifsInHandlerIn::Accept(handshake_message)); } @@ -373,36 +501,6 @@ impl ProtocolsHandler for NotifsHandler { self.in_handlers[num].0.inject_event(NotifsInHandlerIn::Refuse); } }, - NotifsHandlerIn::SendLegacy { message } => - self.legacy.inject_event(LegacyProtoHandlerIn::SendCustomMessage { message }), - NotifsHandlerIn::UpdateHandshake { protocol_name, handshake_message } => { - for (handler, current_handshake) in &mut self.in_handlers { - if handler.protocol_name() == &*protocol_name { - *current_handshake = handshake_message.clone(); - } - } - for (handler, current_handshake) in &mut self.out_handlers { - if handler.protocol_name() == &*protocol_name { - *current_handshake = handshake_message.clone(); - } - } - } - NotifsHandlerIn::SendNotification { message, encoded_fallback_message, protocol_name } => { - for (handler, _) in &mut self.out_handlers { - if handler.protocol_name() != &protocol_name[..] { - continue; - } - - if handler.is_open() { - handler.inject_event(NotifsOutHandlerIn::Send(message)); - return; - } - } - - self.legacy.inject_event(LegacyProtoHandlerIn::SendCustomMessage { - message: encoded_fallback_message, - }); - }, } } @@ -483,64 +581,129 @@ impl ProtocolsHandler for NotifsHandler { ) -> Poll< ProtocolsHandlerEvent > { - while let Poll::Ready(ev) = self.legacy.poll(cx) { - match ev { - ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info: () } => - return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { - protocol: protocol.map_upgrade(EitherUpgrade::B), - info: None, - }), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolOpen { endpoint, .. }) => - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::Open { endpoint } - )), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolClosed { endpoint, reason }) => - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::Closed { endpoint, reason } - )), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomMessage { message }) => - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::CustomMessage { message } - )), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::Clogged { messages }) => - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::Clogged { messages } - )), - ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::ProtocolError { is_severe, error }) => - return Poll::Ready(ProtocolsHandlerEvent::Custom( - NotifsHandlerOut::ProtocolError { is_severe, error } - )), - ProtocolsHandlerEvent::Close(err) => - return Poll::Ready(ProtocolsHandlerEvent::Close(EitherError::B(err))), + if let Some(notifications_sink_rx) = &mut self.notifications_sink_rx { + 'poll_notifs_sink: loop { + // Before we poll the notifications sink receiver, check that all the notification + // channels are ready to send a message. + // TODO: it is planned that in the future we switch to one `NotificationsSink` per + // protocol, in which case each sink should wait only for its corresponding handler + // to be ready, and not all handlers + // see https://github.com/paritytech/substrate/issues/5670 + for (out_handler, _) in &mut self.out_handlers { + match out_handler.poll_ready(cx) { + Poll::Ready(_) => {}, + Poll::Pending => break 'poll_notifs_sink, + } + } + + let message = match notifications_sink_rx.poll_next_unpin(cx) { + Poll::Ready(Some(msg)) => msg, + Poll::Ready(None) | Poll::Pending => break, + }; + + match message { + NotificationsSinkMessage::Legacy { message } => { + self.legacy.inject_event(LegacyProtoHandlerIn::SendCustomMessage { + message + }); + } + NotificationsSinkMessage::Notification { + protocol_name, + encoded_fallback_message, + message + } => { + for (handler, _) in &mut self.out_handlers { + if handler.protocol_name() == &protocol_name[..] && handler.is_open() { + handler.send_or_discard(message); + continue 'poll_notifs_sink; + } + } + + self.legacy.inject_event(LegacyProtoHandlerIn::SendCustomMessage { + message: encoded_fallback_message, + }); + } + NotificationsSinkMessage::ForceClose => { + return Poll::Ready(ProtocolsHandlerEvent::Close(NotifsHandlerError::SyncNotificationsClogged)); + } + } } } - for (handler_num, (handler, handshake_message)) in self.in_handlers.iter_mut().enumerate() { - while let Poll::Ready(ev) = handler.poll(cx) { + // If `self.pending_legacy_handshake` is `Some`, we are in a state where the legacy + // substream is open but the user isn't aware yet of the substreams being open. + // When that is the case, neither the legacy substream nor the incoming notifications + // substreams should be polled, otherwise there is a risk of receiving messages from them. + if self.pending_legacy_handshake.is_none() { + while let Poll::Ready(ev) = self.legacy.poll(cx) { match ev { - ProtocolsHandlerEvent::OutboundSubstreamRequest { .. } => - error!("Incoming substream handler tried to open a substream"), - ProtocolsHandlerEvent::Close(err) => void::unreachable(err), - ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::OpenRequest(_)) => - match self.enabled { - EnabledState::Initial => self.pending_in.push(handler_num), - EnabledState::Enabled => - handler.inject_event(NotifsInHandlerIn::Accept(handshake_message.clone())), - EnabledState::Disabled => - handler.inject_event(NotifsInHandlerIn::Refuse), - }, - ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Closed) => {}, - ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Notif(message)) => { - // Note that right now the legacy substream has precedence over - // everything. If it is not open, then we consider that nothing is open. - if self.legacy.is_open() { - let msg = NotifsHandlerOut::Notification { - message, - protocol_name: handler.protocol_name().to_owned().into(), - }; - return Poll::Ready(ProtocolsHandlerEvent::Custom(msg)); - } + ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol, info: () } => + return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { + protocol: protocol.map_upgrade(EitherUpgrade::B), + info: None, + }), + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolOpen { + received_handshake, + .. + }) => { + self.pending_legacy_handshake = Some(received_handshake); + cx.waker().wake_by_ref(); + return Poll::Pending; }, + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomProtocolClosed { reason, .. }) => { + // We consciously drop the receivers despite notifications being potentially + // still buffered up. + debug_assert!(self.notifications_sink_rx.is_some()); + self.notifications_sink_rx = None; + + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::Closed { endpoint: self.endpoint.clone(), reason } + )) + }, + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::CustomMessage { message }) => { + debug_assert!(self.notifications_sink_rx.is_some()); + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::CustomMessage { message } + )) + }, + ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::ProtocolError { is_severe, error }) => + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::ProtocolError { is_severe, error } + )), + ProtocolsHandlerEvent::Close(err) => + return Poll::Ready(ProtocolsHandlerEvent::Close(NotifsHandlerError::Legacy(err))), + } + } + + for (handler_num, (handler, handshake_message)) in self.in_handlers.iter_mut().enumerate() { + while let Poll::Ready(ev) = handler.poll(cx) { + match ev { + ProtocolsHandlerEvent::OutboundSubstreamRequest { .. } => + error!("Incoming substream handler tried to open a substream"), + ProtocolsHandlerEvent::Close(err) => void::unreachable(err), + ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::OpenRequest(_)) => + match self.enabled { + EnabledState::Initial => self.pending_in.push(handler_num), + EnabledState::Enabled => { + // We create `handshake_message` on a separate line to be sure + // that the lock is released as soon as possible. + let handshake_message = handshake_message.read().clone(); + handler.inject_event(NotifsInHandlerIn::Accept(handshake_message)) + }, + EnabledState::Disabled => + handler.inject_event(NotifsInHandlerIn::Refuse), + }, + ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Closed) => {}, + ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Notif(message)) => { + if self.notifications_sink_rx.is_some() { + let msg = NotifsHandlerOut::Notification { + message, + protocol_name: handler.protocol_name().to_owned().into(), + }; + return Poll::Ready(ProtocolsHandlerEvent::Custom(msg)); + } + }, + } } } } @@ -568,6 +731,30 @@ impl ProtocolsHandler for NotifsHandler { } } + if self.out_handlers.iter().all(|(h, _)| h.is_open() || h.is_refused()) { + if let Some(handshake) = self.pending_legacy_handshake.take() { + let (async_tx, async_rx) = mpsc::channel(ASYNC_NOTIFICATIONS_BUFFER_SIZE); + let (sync_tx, sync_rx) = mpsc::channel(SYNC_NOTIFICATIONS_BUFFER_SIZE); + let notifications_sink = NotificationsSink { + inner: Arc::new(NotificationsSinkInner { + async_channel: FuturesMutex::new(async_tx), + sync_channel: Mutex::new(sync_tx), + }), + }; + + debug_assert!(self.notifications_sink_rx.is_none()); + self.notifications_sink_rx = Some(stream::select(async_rx.fuse(), sync_rx.fuse())); + + return Poll::Ready(ProtocolsHandlerEvent::Custom( + NotifsHandlerOut::Open { + endpoint: self.endpoint.clone(), + received_handshake: handshake, + notifications_sink + } + )) + } + } + Poll::Pending } } diff --git a/client/network/src/protocol/generic_proto/handler/legacy.rs b/client/network/src/protocol/generic_proto/handler/legacy.rs index bc84fd847c9c4ba44dbffcf5a7735c18c39f7776..7d31ed323a43bcc4b8a0c3967aef82ac05e4849b 100644 --- a/client/network/src/protocol/generic_proto/handler/legacy.rs +++ b/client/network/src/protocol/generic_proto/handler/legacy.rs @@ -30,7 +30,7 @@ use libp2p::swarm::{ }; use log::{debug, error}; use smallvec::{smallvec, SmallVec}; -use std::{borrow::Cow, error, fmt, io, mem, time::Duration}; +use std::{borrow::Cow, collections::VecDeque, error, fmt, io, mem, time::Duration}; use std::{pin::Pin, task::{Context, Poll}}; /// Implements the `IntoProtocolsHandler` trait of libp2p. @@ -115,9 +115,9 @@ impl IntoProtocolsHandler for LegacyProtoHandlerProto { remote_peer_id: remote_peer_id.clone(), state: ProtocolState::Init { substreams: SmallVec::new(), - init_deadline: Delay::new(Duration::from_secs(5)) + init_deadline: Delay::new(Duration::from_secs(20)) }, - events_queue: SmallVec::new(), + events_queue: VecDeque::new(), } } } @@ -142,7 +142,7 @@ pub struct LegacyProtoHandler { /// /// This queue must only ever be modified to insert elements at the back, or remove the first /// element. - events_queue: SmallVec<[ProtocolsHandlerEvent; 16]>, + events_queue: VecDeque>, } /// State of the handler. @@ -150,7 +150,8 @@ enum ProtocolState { /// Waiting for the behaviour to tell the handler whether it is enabled or disabled. Init { /// List of substreams opened by the remote but that haven't been processed yet. - substreams: SmallVec<[RegisteredProtocolSubstream; 6]>, + /// For each substream, also includes the handshake message that we have received. + substreams: SmallVec<[(RegisteredProtocolSubstream, Vec); 6]>, /// Deadline after which the initialization is abnormally long. init_deadline: Delay, }, @@ -218,16 +219,15 @@ pub enum LegacyProtoHandlerOut { CustomProtocolOpen { /// Version of the protocol that has been opened. version: u8, - /// The connected endpoint. - endpoint: ConnectedPoint, + /// Handshake message that has been sent to us. + /// This is normally a "Status" message, but this out of the concern of this code. + received_handshake: Vec, }, /// Closed a custom protocol with the remote. CustomProtocolClosed { /// Reason why the substream closed, for diagnostic purposes. reason: Cow<'static, str>, - /// The connected endpoint. - endpoint: ConnectedPoint, }, /// Receives a message on a custom protocol substream. @@ -236,13 +236,6 @@ pub enum LegacyProtoHandlerOut { message: BytesMut, }, - /// A substream to the remote is clogged. The send buffer is very large, and we should print - /// a diagnostic message and/or avoid sending more data. - Clogged { - /// Copy of the messages that are within the buffer, for further diagnostic. - messages: Vec>, - }, - /// An error has happened on the protocol level with this node. ProtocolError { /// If true the error is severe, such as a protocol violation. @@ -253,18 +246,6 @@ pub enum LegacyProtoHandlerOut { } impl LegacyProtoHandler { - /// Returns true if the legacy substream is currently open. - pub fn is_open(&self) -> bool { - match &self.state { - ProtocolState::Init { substreams, .. } => !substreams.is_empty(), - ProtocolState::Opening { .. } => false, - ProtocolState::Normal { substreams, .. } => !substreams.is_empty(), - ProtocolState::Disabled { .. } => false, - ProtocolState::KillAsap => false, - ProtocolState::Poisoned => false, - } - } - /// Enables the handler. fn enable(&mut self) { self.state = match mem::replace(&mut self.state, ProtocolState::Poisoned) { @@ -274,10 +255,10 @@ impl LegacyProtoHandler { ProtocolState::Poisoned } - ProtocolState::Init { substreams: incoming, .. } => { + ProtocolState::Init { substreams: mut incoming, .. } => { if incoming.is_empty() { if let ConnectedPoint::Dialer { .. } = self.endpoint { - self.events_queue.push(ProtocolsHandlerEvent::OutboundSubstreamRequest { + self.events_queue.push_back(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol: SubstreamProtocol::new(self.protocol.clone()), info: (), }); @@ -287,12 +268,12 @@ impl LegacyProtoHandler { } } else { let event = LegacyProtoHandlerOut::CustomProtocolOpen { - version: incoming[0].protocol_version(), - endpoint: self.endpoint.clone() + version: incoming[0].0.protocol_version(), + received_handshake: mem::replace(&mut incoming[0].1, Vec::new()), }; - self.events_queue.push(ProtocolsHandlerEvent::Custom(event)); + self.events_queue.push_back(ProtocolsHandlerEvent::Custom(event)); ProtocolState::Normal { - substreams: incoming.into_iter().collect(), + substreams: incoming.into_iter().map(|(s, _)| s).collect(), shutdown: SmallVec::new() } } @@ -316,7 +297,8 @@ impl LegacyProtoHandler { ProtocolState::Poisoned } - ProtocolState::Init { substreams: mut shutdown, .. } => { + ProtocolState::Init { substreams: shutdown, .. } => { + let mut shutdown = shutdown.into_iter().map(|(s, _)| s).collect::>(); for s in &mut shutdown { s.shutdown(); } @@ -353,26 +335,26 @@ impl LegacyProtoHandler { ProtocolState::Init { substreams, mut init_deadline } => { match Pin::new(&mut init_deadline).poll(cx) { Poll::Ready(()) => { - init_deadline = Delay::new(Duration::from_secs(60)); error!(target: "sub-libp2p", "Handler initialization process is too long \ - with {:?}", self.remote_peer_id) + with {:?}", self.remote_peer_id); + self.state = ProtocolState::KillAsap; }, - Poll::Pending => {} + Poll::Pending => { + self.state = ProtocolState::Init { substreams, init_deadline }; + } } - self.state = ProtocolState::Init { substreams, init_deadline }; None } ProtocolState::Opening { mut deadline } => { match Pin::new(&mut deadline).poll(cx) { Poll::Ready(()) => { - deadline = Delay::new(Duration::from_secs(60)); let event = LegacyProtoHandlerOut::ProtocolError { is_severe: true, error: "Timeout when opening protocol".to_string().into(), }; - self.state = ProtocolState::Opening { deadline }; + self.state = ProtocolState::KillAsap; Some(ProtocolsHandlerEvent::Custom(event)) }, Poll::Pending => { @@ -395,20 +377,24 @@ impl LegacyProtoHandler { self.state = ProtocolState::Normal { substreams, shutdown }; return Some(ProtocolsHandlerEvent::Custom(event)); }, - Poll::Ready(Some(Ok(RegisteredProtocolEvent::Clogged { messages }))) => { - let event = LegacyProtoHandlerOut::Clogged { - messages, - }; - substreams.push(substream); - self.state = ProtocolState::Normal { substreams, shutdown }; - return Some(ProtocolsHandlerEvent::Custom(event)); + Poll::Ready(Some(Ok(RegisteredProtocolEvent::Clogged))) => { + shutdown.push(substream); + if substreams.is_empty() { + let event = LegacyProtoHandlerOut::CustomProtocolClosed { + reason: "Legacy substream clogged".into(), + }; + self.state = ProtocolState::Disabled { + shutdown: shutdown.into_iter().collect(), + reenable: true + }; + return Some(ProtocolsHandlerEvent::Custom(event)); + } } Poll::Ready(None) => { shutdown.push(substream); if substreams.is_empty() { let event = LegacyProtoHandlerOut::CustomProtocolClosed { reason: "All substreams have been closed by the remote".into(), - endpoint: self.endpoint.clone() }; self.state = ProtocolState::Disabled { shutdown: shutdown.into_iter().collect(), @@ -421,7 +407,6 @@ impl LegacyProtoHandler { if substreams.is_empty() { let event = LegacyProtoHandlerOut::CustomProtocolClosed { reason: format!("Error on the last substream: {:?}", err).into(), - endpoint: self.endpoint.clone() }; self.state = ProtocolState::Disabled { shutdown: shutdown.into_iter().collect(), @@ -465,7 +450,8 @@ impl LegacyProtoHandler { /// Called by `inject_fully_negotiated_inbound` and `inject_fully_negotiated_outbound`. fn inject_fully_negotiated( &mut self, - mut substream: RegisteredProtocolSubstream + mut substream: RegisteredProtocolSubstream, + received_handshake: Vec, ) { self.state = match mem::replace(&mut self.state, ProtocolState::Poisoned) { ProtocolState::Poisoned => { @@ -479,16 +465,16 @@ impl LegacyProtoHandler { error!(target: "sub-libp2p", "Opened dialing substream with {:?} before \ initialization", self.remote_peer_id); } - substreams.push(substream); + substreams.push((substream, received_handshake)); ProtocolState::Init { substreams, init_deadline } } ProtocolState::Opening { .. } => { let event = LegacyProtoHandlerOut::CustomProtocolOpen { version: substream.protocol_version(), - endpoint: self.endpoint.clone() + received_handshake, }; - self.events_queue.push(ProtocolsHandlerEvent::Custom(event)); + self.events_queue.push_back(ProtocolsHandlerEvent::Custom(event)); ProtocolState::Normal { substreams: smallvec![substream], shutdown: SmallVec::new() @@ -536,17 +522,17 @@ impl ProtocolsHandler for LegacyProtoHandler { fn inject_fully_negotiated_inbound( &mut self, - proto: >::Output + (substream, handshake): >::Output ) { - self.inject_fully_negotiated(proto); + self.inject_fully_negotiated(substream, handshake); } fn inject_fully_negotiated_outbound( &mut self, - proto: >::Output, + (substream, handshake): >::Output, _: Self::OutboundOpenInfo ) { - self.inject_fully_negotiated(proto); + self.inject_fully_negotiated(substream, handshake); } fn inject_event(&mut self, message: LegacyProtoHandlerIn) { @@ -565,7 +551,7 @@ impl ProtocolsHandler for LegacyProtoHandler { _ => false, }; - self.events_queue.push(ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::ProtocolError { + self.events_queue.push_back(ProtocolsHandlerEvent::Custom(LegacyProtoHandlerOut::ProtocolError { is_severe, error: Box::new(err), })); @@ -587,8 +573,7 @@ impl ProtocolsHandler for LegacyProtoHandler { ProtocolsHandlerEvent > { // Flush the events queue if necessary. - if !self.events_queue.is_empty() { - let event = self.events_queue.remove(0); + if let Some(event) = self.events_queue.pop_front() { return Poll::Ready(event) } diff --git a/client/network/src/protocol/generic_proto/handler/notif_in.rs b/client/network/src/protocol/generic_proto/handler/notif_in.rs index 83923154bd6256de3bb4e983796807093f7019ad..ddd78566fcd2a7b773205d49f00c26e885da413d 100644 --- a/client/network/src/protocol/generic_proto/handler/notif_in.rs +++ b/client/network/src/protocol/generic_proto/handler/notif_in.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Implementations of the `IntoProtocolsHandler` and `ProtocolsHandler` traits for ingoing //! substreams for a single gossiping protocol. @@ -35,8 +37,7 @@ use libp2p::swarm::{ NegotiatedSubstream, }; use log::{error, warn}; -use smallvec::SmallVec; -use std::{borrow::Cow, fmt, pin::Pin, task::{Context, Poll}}; +use std::{borrow::Cow, collections::VecDeque, fmt, pin::Pin, task::{Context, Poll}}; /// Implements the `IntoProtocolsHandler` trait of libp2p. /// @@ -68,7 +69,7 @@ pub struct NotifsInHandler { /// /// This queue is only ever modified to insert elements at the back, or remove the first /// element. - events_queue: SmallVec<[ProtocolsHandlerEvent; 16]>, + events_queue: VecDeque>, } /// Event that can be received by a `NotifsInHandler`. @@ -128,7 +129,7 @@ impl IntoProtocolsHandler for NotifsInHandlerProto { in_protocol: self.in_protocol, substream: None, pending_accept_refuses: 0, - events_queue: SmallVec::new(), + events_queue: VecDeque::new(), } } } @@ -158,18 +159,16 @@ impl ProtocolsHandler for NotifsInHandler { ) { // If a substream already exists, we drop it and replace it with the new incoming one. if self.substream.is_some() { - self.events_queue.push(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Closed)); + self.events_queue.push_back(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::Closed)); } // Note that we drop the existing substream, which will send an equivalent to a TCP "RST" - // to the remote and force-close the substream. It might seem like an unclean way to get + // to the remote and force-close the substream. It might seem like an unclean way to get // rid of a substream. However, keep in mind that it is invalid for the remote to open - // multiple such substreams, and therefore sending a "RST" is the correct thing to do. - // Also note that we have already closed our writing side during the initial handshake, - // and we can't close "more" than that anyway. + // multiple such substreams, and therefore sending a "RST" is not an incorrect thing to do. self.substream = Some(proto); - self.events_queue.push(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::OpenRequest(msg))); + self.events_queue.push_back(ProtocolsHandlerEvent::Custom(NotifsInHandlerOut::OpenRequest(msg))); self.pending_accept_refuses = self.pending_accept_refuses .checked_add(1) .unwrap_or_else(|| { @@ -231,8 +230,7 @@ impl ProtocolsHandler for NotifsInHandler { ProtocolsHandlerEvent > { // Flush the events queue if necessary. - if !self.events_queue.is_empty() { - let event = self.events_queue.remove(0); + if let Some(event) = self.events_queue.pop_front() { return Poll::Ready(event) } diff --git a/client/network/src/protocol/generic_proto/handler/notif_out.rs b/client/network/src/protocol/generic_proto/handler/notif_out.rs index b5d6cd61ada2a9e54bfa5873e0f7992ab1dfcfcb..4ba9d9a0b74aad679578406b2d9adc7a070b4d79 100644 --- a/client/network/src/protocol/generic_proto/handler/notif_out.rs +++ b/client/network/src/protocol/generic_proto/handler/notif_out.rs @@ -34,9 +34,10 @@ use libp2p::swarm::{ NegotiatedSubstream, }; use log::{debug, warn, error}; -use prometheus_endpoint::Histogram; -use smallvec::SmallVec; -use std::{borrow::Cow, fmt, mem, pin::Pin, task::{Context, Poll}, time::Duration}; +use std::{ + borrow::Cow, collections::VecDeque, fmt, mem, pin::Pin, task::{Context, Poll, Waker}, + time::Duration +}; use wasm_timer::Instant; /// Maximum duration to open a substream and receive the handshake message. After that, we @@ -57,17 +58,14 @@ const INITIAL_KEEPALIVE_TIME: Duration = Duration::from_secs(5); pub struct NotifsOutHandlerProto { /// Name of the protocol to negotiate. protocol_name: Cow<'static, [u8]>, - /// Optional Prometheus histogram to report message queue size variations. - queue_size_report: Option, } impl NotifsOutHandlerProto { /// Builds a new [`NotifsOutHandlerProto`]. Will use the given protocol name for the /// notifications substream. - pub fn new(protocol_name: impl Into>, queue_size_report: Option) -> Self { + pub fn new(protocol_name: impl Into>) -> Self { NotifsOutHandlerProto { protocol_name: protocol_name.into(), - queue_size_report, } } } @@ -79,14 +77,12 @@ impl IntoProtocolsHandler for NotifsOutHandlerProto { DeniedUpgrade } - fn into_handler(self, peer_id: &PeerId, _: &ConnectedPoint) -> Self::Handler { + fn into_handler(self, _: &PeerId, _: &ConnectedPoint) -> Self::Handler { NotifsOutHandler { protocol_name: self.protocol_name, when_connection_open: Instant::now(), - queue_size_report: self.queue_size_report, state: State::Disabled, - events_queue: SmallVec::new(), - peer_id: peer_id.clone(), + events_queue: VecDeque::new(), } } } @@ -109,17 +105,11 @@ pub struct NotifsOutHandler { /// When the connection with the remote has been successfully established. when_connection_open: Instant, - /// Optional prometheus histogram to report message queue sizes variations. - queue_size_report: Option, - /// Queue of events to send to the outside. /// /// This queue must only ever be modified to insert elements at the back, or remove the first /// element. - events_queue: SmallVec<[ProtocolsHandlerEvent; 16]>, - - /// Who we are connected to. - peer_id: PeerId, + events_queue: VecDeque>, } /// Our relationship with the node we're connected to. @@ -154,6 +144,11 @@ enum State { Open { /// Substream that is currently open. substream: NotificationsOutSubstream, + /// Waker for the last task that got `Poll::Pending` from `poll_ready`, to notify + /// when the open substream closes due to being disabled or encountering an + /// error, i.e. to notify the task as soon as the substream becomes unavailable, + /// without waiting for an underlying I/O task wakeup. + close_waker: Option, /// The initial message that we sent. Necessary if we need to re-open a substream. initial_message: Vec, }, @@ -174,11 +169,6 @@ pub enum NotifsOutHandlerIn { /// Disables the notifications substream for this node. This is the default state. Disable, - - /// Sends a message on the notifications substream. Ignored if the substream isn't open. - /// - /// It is only valid to send this if the notifications substream has been enabled. - Send(Vec), } /// Event that can be emitted by a `NotifsOutHandler`. @@ -213,10 +203,61 @@ impl NotifsOutHandler { } } + /// Returns `true` if there has been an attempt to open the substream, but the remote refused + /// the substream. + /// + /// Always returns `false` if the handler is in a disabled state. + pub fn is_refused(&self) -> bool { + match &self.state { + State::Disabled => false, + State::DisabledOpening => false, + State::DisabledOpen(_) => false, + State::Opening { .. } => false, + State::Refused => true, + State::Open { .. } => false, + State::Poisoned => false, + } + } + /// Returns the name of the protocol that we negotiate. pub fn protocol_name(&self) -> &[u8] { &self.protocol_name } + + /// Polls whether the outbound substream is ready to send a notification. + /// + /// - Returns `Poll::Pending` if the substream is open but not ready to send a notification. + /// - Returns `Poll::Ready(true)` if the substream is ready to send a notification. + /// - Returns `Poll::Ready(false)` if the substream is closed. + /// + pub fn poll_ready(&mut self, cx: &mut Context) -> Poll { + if let State::Open { substream, close_waker, .. } = &mut self.state { + match substream.poll_ready_unpin(cx) { + Poll::Ready(Ok(())) => Poll::Ready(true), + Poll::Ready(Err(_)) => Poll::Ready(false), + Poll::Pending => { + *close_waker = Some(cx.waker().clone()); + Poll::Pending + } + } + } else { + Poll::Ready(false) + } + } + + /// Sends out a notification. + /// + /// If the substream is closed, or not ready to send out a notification yet, then the + /// notification is silently discarded. + /// + /// You are encouraged to call [`NotifsOutHandler::poll_ready`] beforehand to determine + /// whether this will succeed. If `Poll::Ready(true)` is returned, then this method will send + /// out a notification. + pub fn send_or_discard(&mut self, notification: Vec) { + if let State::Open { substream, .. } = &mut self.state { + let _ = substream.start_send_unpin(notification); + } + } } impl ProtocolsHandler for NotifsOutHandler { @@ -247,8 +288,8 @@ impl ProtocolsHandler for NotifsOutHandler { match mem::replace(&mut self.state, State::Poisoned) { State::Opening { initial_message } => { let ev = NotifsOutHandlerOut::Open { handshake: handshake_msg }; - self.events_queue.push(ProtocolsHandlerEvent::Custom(ev)); - self.state = State::Open { substream, initial_message }; + self.events_queue.push_back(ProtocolsHandlerEvent::Custom(ev)); + self.state = State::Open { substream, initial_message, close_waker: None }; }, // If the handler was disabled while we were negotiating the protocol, immediately // close it. @@ -267,7 +308,7 @@ impl ProtocolsHandler for NotifsOutHandler { match mem::replace(&mut self.state, State::Poisoned) { State::Disabled => { let proto = NotificationsOut::new(self.protocol_name.clone(), initial_message.clone()); - self.events_queue.push(ProtocolsHandlerEvent::OutboundSubstreamRequest { + self.events_queue.push_back(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol: SubstreamProtocol::new(proto).with_timeout(OPEN_TIMEOUT), info: (), }); @@ -287,7 +328,7 @@ impl ProtocolsHandler for NotifsOutHandler { } let proto = NotificationsOut::new(self.protocol_name.clone(), initial_message.clone()); - self.events_queue.push(ProtocolsHandlerEvent::OutboundSubstreamRequest { + self.events_queue.push_back(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol: SubstreamProtocol::new(proto).with_timeout(OPEN_TIMEOUT), info: (), }); @@ -311,31 +352,15 @@ impl ProtocolsHandler for NotifsOutHandler { } State::Opening { .. } => self.state = State::DisabledOpening, State::Refused => self.state = State::Disabled, - State::Open { substream, .. } => self.state = State::DisabledOpen(substream), + State::Open { substream, close_waker, .. } => { + if let Some(close_waker) = close_waker { + close_waker.wake(); + } + self.state = State::DisabledOpen(substream) + }, State::Poisoned => error!("☎️ Notifications handler in a poisoned state"), } } - - NotifsOutHandlerIn::Send(msg) => - if let State::Open { substream, .. } = &mut self.state { - if substream.push_message(msg).is_err() { - warn!( - target: "sub-libp2p", - "📞 Notifications queue with peer {} is full, dropped message (protocol: {:?})", - self.peer_id, - self.protocol_name, - ); - } - if let Some(metric) = &self.queue_size_report { - metric.observe(substream.queue_len() as f64); - } - } else { - // This is an API misuse. - warn!( - target: "sub-libp2p", - "📞 Tried to send a notification on a disabled handler" - ); - }, } } @@ -347,7 +372,7 @@ impl ProtocolsHandler for NotifsOutHandler { State::Opening { .. } => { self.state = State::Refused; let ev = NotifsOutHandlerOut::Refused; - self.events_queue.push(ProtocolsHandlerEvent::Custom(ev)); + self.events_queue.push_back(ProtocolsHandlerEvent::Custom(ev)); }, State::DisabledOpening => self.state = State::Disabled, State::Poisoned => error!("☎️ Notifications handler in a poisoned state"), @@ -371,21 +396,24 @@ impl ProtocolsHandler for NotifsOutHandler { cx: &mut Context, ) -> Poll> { // Flush the events queue if necessary. - if !self.events_queue.is_empty() { - let event = self.events_queue.remove(0); - return Poll::Ready(event); + if let Some(event) = self.events_queue.pop_front() { + return Poll::Ready(event) } match &mut self.state { - State::Open { substream, initial_message } => + State::Open { substream, initial_message, close_waker } => match Sink::poll_flush(Pin::new(substream), cx) { Poll::Pending | Poll::Ready(Ok(())) => {}, Poll::Ready(Err(_)) => { + if let Some(close_waker) = close_waker.take() { + close_waker.wake(); + } + // We try to re-open a substream. let initial_message = mem::replace(initial_message, Vec::new()); self.state = State::Opening { initial_message: initial_message.clone() }; let proto = NotificationsOut::new(self.protocol_name.clone(), initial_message); - self.events_queue.push(ProtocolsHandlerEvent::OutboundSubstreamRequest { + self.events_queue.push_back(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol: SubstreamProtocol::new(proto).with_timeout(OPEN_TIMEOUT), info: (), }); diff --git a/client/network/src/protocol/generic_proto/tests.rs b/client/network/src/protocol/generic_proto/tests.rs index 1bc6e745f887685af41a6c9cfdfc05da84af7918..cf9f72b89ba526ab5b6be974ebf7d1d383c39070 100644 --- a/client/network/src/protocol/generic_proto/tests.rs +++ b/client/network/src/protocol/generic_proto/tests.rs @@ -42,6 +42,7 @@ fn build_nodes() -> (Swarm, Swarm) { for index in 0 .. 2 { let keypair = keypairs[index].clone(); + let local_peer_id = keypair.public().into_peer_id(); let transport = libp2p::core::transport::MemoryTransport .and_then(move |out, endpoint| { let secio = libp2p::secio::SecioConfig::new(keypair); @@ -82,7 +83,7 @@ fn build_nodes() -> (Swarm, Swarm) { }); let behaviour = CustomProtoWithAddr { - inner: GenericProto::new(&b"test"[..], &[1], peerset, None), + inner: GenericProto::new(local_peer_id, &b"test"[..], &[1], vec![], peerset), addrs: addrs .iter() .enumerate() @@ -220,9 +221,10 @@ fn two_nodes_transfer_lots_of_packets() { // We spawn two nodes, then make the first one send lots of packets to the second one. The test // ends when the second one has received all of them. - // Note that if we go too high, we will reach the limit to the number of simultaneous - // substreams allowed by the multiplexer. - const NUM_PACKETS: u32 = 5000; + // This test consists in transferring this given number of packets. Considering that (by + // design) the connection gets closed if one of the remotes can't follow the pace, this number + // should not exceed the size of the buffer of pending notifications. + const NUM_PACKETS: u32 = 512; let (mut service1, mut service2) = build_nodes(); @@ -240,6 +242,8 @@ fn two_nodes_transfer_lots_of_packets() { ); } }, + // An empty handshake is being sent after opening. + Some(GenericProtoOut::LegacyMessage { message, .. }) if message.is_empty() => {}, _ => panic!(), } } @@ -250,6 +254,8 @@ fn two_nodes_transfer_lots_of_packets() { loop { match ready!(service2.poll_next_unpin(cx)) { Some(GenericProtoOut::CustomProtocolOpen { .. }) => {}, + // An empty handshake is being sent after opening. + Some(GenericProtoOut::LegacyMessage { message, .. }) if message.is_empty() => {}, Some(GenericProtoOut::LegacyMessage { message, .. }) => { match Message::::decode(&mut &message[..]).unwrap() { Message::::BlockResponse(BlockResponse { id: _, blocks }) => { @@ -311,6 +317,8 @@ fn basic_two_nodes_requests_in_parallel() { service1.send_packet(&peer_id, msg.encode()); } }, + // An empty handshake is being sent after opening. + Some(GenericProtoOut::LegacyMessage { message, .. }) if message.is_empty() => {}, _ => panic!(), } } @@ -320,6 +328,8 @@ fn basic_two_nodes_requests_in_parallel() { loop { match ready!(service2.poll_next_unpin(cx)) { Some(GenericProtoOut::CustomProtocolOpen { .. }) => {}, + // An empty handshake is being sent after opening. + Some(GenericProtoOut::LegacyMessage { message, .. }) if message.is_empty() => {}, Some(GenericProtoOut::LegacyMessage { message, .. }) => { let pos = to_receive.iter().position(|m| m.encode() == message).unwrap(); to_receive.remove(pos); diff --git a/client/network/src/protocol/generic_proto/upgrade.rs b/client/network/src/protocol/generic_proto/upgrade.rs index 36f826336532619479b94876776c65e8636f8c57..6322a10b572a9fa1e9d60566343e513fc2a6f15a 100644 --- a/client/network/src/protocol/generic_proto/upgrade.rs +++ b/client/network/src/protocol/generic_proto/upgrade.rs @@ -1,19 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - +// along with this program. If not, see . pub use self::collec::UpgradeCollec; pub use self::legacy::{ RegisteredProtocol, diff --git a/client/network/src/protocol/generic_proto/upgrade/legacy.rs b/client/network/src/protocol/generic_proto/upgrade/legacy.rs index 311e0b04f9724072535cad8dc429d2c1989c4c5d..f56ab2450d43e467845c039f55ef3a52ed5a172a 100644 --- a/client/network/src/protocol/generic_proto/upgrade/legacy.rs +++ b/client/network/src/protocol/generic_proto/upgrade/legacy.rs @@ -1,25 +1,28 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::config::ProtocolId; use bytes::BytesMut; use futures::prelude::*; use futures_codec::Framed; use libp2p::core::{Endpoint, UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade::ProtocolName}; -use std::{collections::VecDeque, io, pin::Pin, vec::IntoIter as VecIntoIter}; +use parking_lot::RwLock; +use std::{collections::VecDeque, io, pin::Pin, sync::Arc, vec::IntoIter as VecIntoIter}; use std::task::{Context, Poll}; use unsigned_varint::codec::UviBytes; @@ -36,12 +39,13 @@ pub struct RegisteredProtocol { /// List of protocol versions that we support. /// Ordered in descending order so that the best comes first. supported_versions: Vec, + /// Handshake to send after the substream is open. + handshake_message: Arc>>, } impl RegisteredProtocol { - /// Creates a new `RegisteredProtocol`. The `custom_data` parameter will be - /// passed inside the `RegisteredProtocolOutput`. - pub fn new(protocol: impl Into, versions: &[u8]) + /// Creates a new `RegisteredProtocol`. + pub fn new(protocol: impl Into, versions: &[u8], handshake_message: Arc>>) -> Self { let protocol = protocol.into(); let mut base_name = b"/substrate/".to_vec(); @@ -53,11 +57,17 @@ impl RegisteredProtocol { id: protocol, supported_versions: { let mut tmp = versions.to_vec(); - tmp.sort_unstable_by(|a, b| b.cmp(&a)); + tmp.sort_by(|a, b| b.cmp(&a)); tmp }, + handshake_message, } } + + /// Returns the `Arc` to the handshake message that was passed at initialization. + pub fn handshake_message(&self) -> &Arc>> { + &self.handshake_message + } } impl Clone for RegisteredProtocol { @@ -66,6 +76,7 @@ impl Clone for RegisteredProtocol { id: self.id.clone(), base_name: self.base_name.clone(), supported_versions: self.supported_versions.clone(), + handshake_message: self.handshake_message.clone(), } } } @@ -131,10 +142,7 @@ pub enum RegisteredProtocolEvent { /// Diagnostic event indicating that the connection is clogged and we should avoid sending too /// many messages to it. - Clogged { - /// Copy of the messages that are within the buffer, for further diagnostic. - messages: Vec>, - }, + Clogged, } impl Stream for RegisteredProtocolSubstream @@ -166,17 +174,13 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin { } // Indicating that the remote is clogged if that's the case. - if self.send_queue.len() >= 2048 { + if self.send_queue.len() >= 1536 { if !self.clogged_fuse { // Note: this fuse is important not just for preventing us from flooding the logs; // if you remove the fuse, then we will always return early from this function and // thus never read any message from the network. self.clogged_fuse = true; - return Poll::Ready(Some(Ok(RegisteredProtocolEvent::Clogged { - messages: self.send_queue.iter() - .map(|m| m.clone().to_vec()) - .collect(), - }))) + return Poll::Ready(Some(Ok(RegisteredProtocolEvent::Clogged))) } } else { self.clogged_fuse = false; @@ -242,10 +246,10 @@ impl ProtocolName for RegisteredProtocolName { } impl InboundUpgrade for RegisteredProtocol -where TSubstream: AsyncRead + AsyncWrite + Unpin, +where TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static, { - type Output = RegisteredProtocolSubstream; - type Future = future::Ready>; + type Output = (RegisteredProtocolSubstream, Vec); + type Future = Pin> + Send>>; type Error = io::Error; fn upgrade_inbound( @@ -253,26 +257,33 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin, socket: TSubstream, info: Self::Info, ) -> Self::Future { - let framed = { - let mut codec = UviBytes::default(); - codec.set_max_len(16 * 1024 * 1024); // 16 MiB hard limit for packets. - Framed::new(socket, codec) - }; - - future::ok(RegisteredProtocolSubstream { - is_closing: false, - endpoint: Endpoint::Listener, - send_queue: VecDeque::new(), - requires_poll_flush: false, - inner: framed.fuse(), - protocol_version: info.version, - clogged_fuse: false, + Box::pin(async move { + let mut framed = { + let mut codec = UviBytes::default(); + codec.set_max_len(16 * 1024 * 1024); // 16 MiB hard limit for packets. + Framed::new(socket, codec) + }; + + let handshake = BytesMut::from(&self.handshake_message.read()[..]); + framed.send(handshake).await?; + let received_handshake = framed.next().await + .ok_or_else(|| io::ErrorKind::UnexpectedEof)??; + + Ok((RegisteredProtocolSubstream { + is_closing: false, + endpoint: Endpoint::Listener, + send_queue: VecDeque::new(), + requires_poll_flush: false, + inner: framed.fuse(), + protocol_version: info.version, + clogged_fuse: false, + }, received_handshake.to_vec())) }) } } impl OutboundUpgrade for RegisteredProtocol -where TSubstream: AsyncRead + AsyncWrite + Unpin, +where TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static, { type Output = >::Output; type Future = >::Future; @@ -283,16 +294,29 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin, socket: TSubstream, info: Self::Info, ) -> Self::Future { - let framed = Framed::new(socket, UviBytes::default()); - - future::ok(RegisteredProtocolSubstream { - is_closing: false, - endpoint: Endpoint::Dialer, - send_queue: VecDeque::new(), - requires_poll_flush: false, - inner: framed.fuse(), - protocol_version: info.version, - clogged_fuse: false, + Box::pin(async move { + let mut framed = { + let mut codec = UviBytes::default(); + codec.set_max_len(16 * 1024 * 1024); // 16 MiB hard limit for packets. + Framed::new(socket, codec) + }; + + let handshake = BytesMut::from(&self.handshake_message.read()[..]); + framed.send(handshake).await?; + let received_handshake = framed.next().await + .ok_or_else(|| { + io::Error::new(io::ErrorKind::UnexpectedEof, "Failed to receive handshake") + })??; + + Ok((RegisteredProtocolSubstream { + is_closing: false, + endpoint: Endpoint::Dialer, + send_queue: VecDeque::new(), + requires_poll_flush: false, + inner: framed.fuse(), + protocol_version: info.version, + clogged_fuse: false, + }, received_handshake.to_vec())) }) } } diff --git a/client/network/src/protocol/generic_proto/upgrade/notifications.rs b/client/network/src/protocol/generic_proto/upgrade/notifications.rs index cf271016e728adec53b7e56ffc86fc71281b7f59..80fd7761f8088482f309d8ec772586287df8a35e 100644 --- a/client/network/src/protocol/generic_proto/upgrade/notifications.rs +++ b/client/network/src/protocol/generic_proto/upgrade/notifications.rs @@ -22,29 +22,28 @@ /// higher-level logic. This message is prefixed with a variable-length integer message length. /// This message can be empty, in which case `0` is sent. /// - If node B accepts the substream, it sends back a message with the same properties. -/// Afterwards, the sending side of B is closed. /// - If instead B refuses the connection (which typically happens because no empty slot is /// available), then it immediately closes the substream without sending back anything. /// - Node A can then send notifications to B, prefixed with a variable-length integer indicating /// the length of the message. -/// - Node A closes its writing side if it doesn't want the notifications substream anymore. +/// - Either node A or node B can signal that it doesn't want this notifications substream anymore +/// by closing its writing side. The other party should respond by also closing their own +/// writing side soon after. /// /// Notification substreams are unidirectional. If A opens a substream with B, then B is /// encouraged but not required to open a substream to A as well. /// use bytes::BytesMut; -use futures::{prelude::*, ready}; +use futures::prelude::*; use futures_codec::Framed; use libp2p::core::{UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade}; use log::error; -use std::{borrow::Cow, collections::VecDeque, convert::TryFrom as _, io, iter, mem, pin::Pin, task::{Context, Poll}}; +use std::{borrow::Cow, io, iter, mem, pin::Pin, task::{Context, Poll}}; use unsigned_varint::codec::UviBytes; /// Maximum allowed size of the two handshake messages, in bytes. const MAX_HANDSHAKE_SIZE: usize = 1024; -/// Maximum number of buffered messages before we refuse to accept more. -const MAX_PENDING_MESSAGES: usize = 512; /// Upgrade that accepts a substream, sends back a status message, then becomes a unidirectional /// stream of messages. @@ -82,9 +81,13 @@ enum NotificationsInSubstreamHandshake { /// User gave us the handshake message. Trying to push it in the socket. PendingSend(Vec), /// Handshake message was pushed in the socket. Still need to flush. - Close, - /// Handshake message successfully sent. + Flush, + /// Handshake message successfully sent and flushed. Sent, + /// Remote has closed their writing side. We close our own writing side in return. + ClosingInResponseToRemote, + /// Both our side and the remote have closed their writing side. + BothSidesClosed, } /// A substream for outgoing notification messages. @@ -93,10 +96,6 @@ pub struct NotificationsOutSubstream { /// Substream where to send messages. #[pin] socket: Framed>>>, - /// Queue of messages waiting to be sent. - messages_queue: VecDeque>, - /// If true, we need to flush `socket`. - need_flush: bool, } impl NotificationsIn { @@ -183,8 +182,6 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin, // This `Stream` implementation first tries to send back the handshake if necessary. loop { match mem::replace(this.handshake, NotificationsInSubstreamHandshake::Sent) { - NotificationsInSubstreamHandshake::Sent => - return Stream::poll_next(this.socket.as_mut(), cx), NotificationsInSubstreamHandshake::NotSent => { *this.handshake = NotificationsInSubstreamHandshake::NotSent; return Poll::Pending @@ -192,7 +189,7 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin, NotificationsInSubstreamHandshake::PendingSend(msg) => match Sink::poll_ready(this.socket.as_mut(), cx) { Poll::Ready(_) => { - *this.handshake = NotificationsInSubstreamHandshake::Close; + *this.handshake = NotificationsInSubstreamHandshake::Flush; match Sink::start_send(this.socket.as_mut(), io::Cursor::new(msg)) { Ok(()) => {}, Err(err) => return Poll::Ready(Some(Err(err))), @@ -203,15 +200,43 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin, return Poll::Pending } }, - NotificationsInSubstreamHandshake::Close => - match Sink::poll_close(this.socket.as_mut(), cx)? { + NotificationsInSubstreamHandshake::Flush => + match Sink::poll_flush(this.socket.as_mut(), cx)? { Poll::Ready(()) => *this.handshake = NotificationsInSubstreamHandshake::Sent, Poll::Pending => { - *this.handshake = NotificationsInSubstreamHandshake::Close; + *this.handshake = NotificationsInSubstreamHandshake::Flush; + return Poll::Pending + } + }, + + NotificationsInSubstreamHandshake::Sent => { + match Stream::poll_next(this.socket.as_mut(), cx) { + Poll::Ready(None) => *this.handshake = + NotificationsInSubstreamHandshake::ClosingInResponseToRemote, + Poll::Ready(Some(msg)) => { + *this.handshake = NotificationsInSubstreamHandshake::Sent; + return Poll::Ready(Some(msg)) + }, + Poll::Pending => { + *this.handshake = NotificationsInSubstreamHandshake::Sent; + return Poll::Pending + }, + } + }, + + NotificationsInSubstreamHandshake::ClosingInResponseToRemote => + match Sink::poll_close(this.socket.as_mut(), cx)? { + Poll::Ready(()) => + *this.handshake = NotificationsInSubstreamHandshake::BothSidesClosed, + Poll::Pending => { + *this.handshake = NotificationsInSubstreamHandshake::ClosingInResponseToRemote; return Poll::Pending } }, + + NotificationsInSubstreamHandshake::BothSidesClosed => + return Poll::Ready(None), } } } @@ -272,80 +297,38 @@ where TSubstream: AsyncRead + AsyncWrite + Unpin + Send + 'static, Ok((handshake, NotificationsOutSubstream { socket: Framed::new(socket, UviBytes::default()), - messages_queue: VecDeque::with_capacity(MAX_PENDING_MESSAGES), - need_flush: false, })) }) } } -impl NotificationsOutSubstream { - /// Returns the number of items in the queue, capped to `u32::max_value()`. - pub fn queue_len(&self) -> u32 { - u32::try_from(self.messages_queue.len()).unwrap_or(u32::max_value()) - } - - /// Push a message to the queue of messages. - /// - /// This has the same effect as the `Sink::start_send` implementation. - pub fn push_message(&mut self, item: Vec) -> Result<(), NotificationsOutError> { - if self.messages_queue.len() >= MAX_PENDING_MESSAGES { - return Err(NotificationsOutError::Clogged); - } - - self.messages_queue.push_back(item); - Ok(()) - } -} - impl Sink> for NotificationsOutSubstream where TSubstream: AsyncRead + AsyncWrite + Unpin, { type Error = NotificationsOutError; - fn poll_ready(self: Pin<&mut Self>, _: &mut Context) -> Poll> { - Poll::Ready(Ok(())) + fn poll_ready(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + let mut this = self.project(); + Sink::poll_ready(this.socket.as_mut(), cx) + .map_err(NotificationsOutError::Io) } - fn start_send(mut self: Pin<&mut Self>, item: Vec) -> Result<(), Self::Error> { - self.push_message(item) + fn start_send(self: Pin<&mut Self>, item: Vec) -> Result<(), Self::Error> { + let mut this = self.project(); + Sink::start_send(this.socket.as_mut(), io::Cursor::new(item)) + .map_err(NotificationsOutError::Io) } fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { let mut this = self.project(); - - while !this.messages_queue.is_empty() { - match Sink::poll_ready(this.socket.as_mut(), cx) { - Poll::Ready(Err(err)) => return Poll::Ready(Err(From::from(err))), - Poll::Ready(Ok(())) => { - let msg = this.messages_queue.pop_front() - .expect("checked for !is_empty above; qed"); - Sink::start_send(this.socket.as_mut(), io::Cursor::new(msg))?; - *this.need_flush = true; - }, - Poll::Pending => return Poll::Pending, - } - } - - if *this.need_flush { - match Sink::poll_flush(this.socket.as_mut(), cx) { - Poll::Ready(Err(err)) => return Poll::Ready(Err(From::from(err))), - Poll::Ready(Ok(())) => *this.need_flush = false, - Poll::Pending => return Poll::Pending, - } - } - - Poll::Ready(Ok(())) + Sink::poll_flush(this.socket.as_mut(), cx) + .map_err(NotificationsOutError::Io) } - fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { - ready!(Sink::poll_flush(self.as_mut(), cx))?; - let this = self.project(); - match Sink::poll_close(this.socket, cx) { - Poll::Ready(Ok(())) => Poll::Ready(Ok(())), - Poll::Ready(Err(err)) => Poll::Ready(Err(From::from(err))), - Poll::Pending => Poll::Pending, - } + fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { + let mut this = self.project(); + Sink::poll_close(this.socket.as_mut(), cx) + .map_err(NotificationsOutError::Io) } } @@ -386,13 +369,6 @@ impl From for NotificationsHandshakeError { pub enum NotificationsOutError { /// I/O error on the substream. Io(io::Error), - - /// Remote doesn't process our messages quickly enough. - /// - /// > **Note**: This is not necessarily the remote's fault, and could also be caused by the - /// > local node sending data too quickly. Properly doing back-pressure, however, - /// > would require a deep refactoring effort in Substrate as a whole. - Clogged, } #[cfg(test)] @@ -402,7 +378,6 @@ mod tests { use async_std::net::{TcpListener, TcpStream}; use futures::{prelude::*, channel::oneshot}; use libp2p::core::upgrade; - use std::pin::Pin; #[test] fn basic_works() { @@ -582,57 +557,4 @@ mod tests { async_std::task::block_on(client); } - - #[test] - fn buffer_is_full_closes_connection() { - const PROTO_NAME: &'static [u8] = b"/test/proto/1"; - let (listener_addr_tx, listener_addr_rx) = oneshot::channel(); - - let client = async_std::task::spawn(async move { - let socket = TcpStream::connect(listener_addr_rx.await.unwrap()).await.unwrap(); - let (handshake, mut substream) = upgrade::apply_outbound( - socket, - NotificationsOut::new(PROTO_NAME, vec![]), - upgrade::Version::V1 - ).await.unwrap(); - - assert!(handshake.is_empty()); - - // Push an item and flush so that the test works. - substream.send(b"hello world".to_vec()).await.unwrap(); - - for _ in 0..32768 { - // Push an item on the sink without flushing until an error happens because the - // buffer is full. - let message = b"hello world!".to_vec(); - if future::poll_fn(|cx| Sink::poll_ready(Pin::new(&mut substream), cx)).await.is_err() { - return Ok(()); - } - if Sink::start_send(Pin::new(&mut substream), message).is_err() { - return Ok(()); - } - } - - Err(()) - }); - - async_std::task::block_on(async move { - let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); - listener_addr_tx.send(listener.local_addr().unwrap()).unwrap(); - - let (socket, _) = listener.accept().await.unwrap(); - let (initial_message, mut substream) = upgrade::apply_inbound( - socket, - NotificationsIn::new(PROTO_NAME) - ).await.unwrap(); - - assert!(initial_message.is_empty()); - substream.send_handshake(vec![]); - - // Process one message so that the handshake and all works. - let _ = substream.next().await.unwrap().unwrap(); - - client.await.unwrap(); - }); - } } diff --git a/client/network/src/protocol/message.rs b/client/network/src/protocol/message.rs index 8638e9afc59b93fc134b53d71e01770fdecd01d3..a7fbb92387cf6022e894accbdf4855520a912f15 100644 --- a/client/network/src/protocol/message.rs +++ b/client/network/src/protocol/message.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Network packet message types. These get serialized and put into the lower level protocol payload. @@ -85,6 +87,20 @@ bitflags! { } } +impl BlockAttributes { + /// Encodes attributes as big endian u32, compatible with SCALE-encoding (i.e the + /// significant byte has zero index). + pub fn to_be_u32(&self) -> u32 { + u32::from_be_bytes([self.bits(), 0, 0, 0]) + } + + /// Decodes attributes, encoded with the `encode_to_be_u32()` call. + pub fn from_be_u32(encoded: u32) -> Result { + BlockAttributes::from_bits(encoded.to_be_bytes()[0]) + .ok_or_else(|| Error::from("Invalid BlockAttributes")) + } +} + impl Encode for BlockAttributes { fn encode_to(&self, dest: &mut T) { dest.push_byte(self.bits()) diff --git a/client/network/src/protocol/sync.rs b/client/network/src/protocol/sync.rs index b720ba0aefe4bd8d9cfb9f1dd8703200bc6ef2d6..bfd8c4fe218dec5116e1c2d9a49230af1b96fb61 100644 --- a/client/network/src/protocol/sync.rs +++ b/client/network/src/protocol/sync.rs @@ -48,6 +48,7 @@ use sp_runtime::{ generic::BlockId, traits::{Block as BlockT, Header, NumberFor, Zero, One, CheckedSub, SaturatedConversion, Hash, HashFor} }; +use sp_arithmetic::traits::Saturating; use std::{fmt, ops::Range, collections::{HashMap, HashSet, VecDeque}, sync::Arc}; mod blocks; @@ -189,8 +190,8 @@ pub struct ChainSync { block_announce_validator: Box + Send>, /// Maximum number of peers to ask the same blocks in parallel. max_parallel_downloads: u32, - /// Total number of processed blocks (imported or failed). - processed_blocks: usize, + /// Total number of downloaded blocks. + downloaded_blocks: usize, } /// All the data we have about a Peer that we are trying to sync with @@ -375,7 +376,7 @@ impl ChainSync { pending_requests: Default::default(), block_announce_validator, max_parallel_downloads, - processed_blocks: 0, + downloaded_blocks: 0, } } @@ -388,7 +389,7 @@ impl ChainSync { /// Returns the current sync status. pub fn status(&self) -> Status { - let best_seen = self.peers.values().max_by_key(|p| p.best_number).map(|p| p.best_number); + let best_seen = self.peers.values().map(|p| p.best_number).max(); let sync_state = if let Some(n) = best_seen { // A chain is classified as downloading if the provided best block is @@ -415,9 +416,9 @@ impl ChainSync { self.fork_targets.len() } - /// Number of processed blocks. - pub fn num_processed_blocks(&self) -> usize { - self.processed_blocks + /// Number of downloaded blocks. + pub fn num_downloaded_blocks(&self) -> usize { + self.downloaded_blocks } /// Handle a new connected peer. @@ -513,10 +514,10 @@ impl ChainSync { } } - /// Signal that `best_header` has been queued for import and update the + /// Signal that a new best block has been imported. /// `ChainSync` state with that information. - pub fn update_chain_info(&mut self, best_header: &B::Header) { - self.on_block_queued(&best_header.hash(), *best_header.number()) + pub fn update_chain_info(&mut self, best_hash: &B::Hash, best_number: NumberFor) { + self.on_block_queued(best_hash, best_number); } /// Schedule a justification request for the given block. @@ -574,7 +575,7 @@ impl ChainSync { if number > peer.best_number { peer.best_number = number; - peer.best_hash = hash.clone(); + peer.best_hash = *hash; } self.pending_requests.add(peer_id); } @@ -639,7 +640,7 @@ impl ChainSync { } /// Get an iterator over all block requests of all peers. - pub fn block_requests(&mut self) -> impl Iterator)> + '_ { + pub fn block_requests(&mut self) -> impl Iterator)> + '_ { if self.pending_requests.is_empty() { return Either::Left(std::iter::empty()) } @@ -651,7 +652,6 @@ impl ChainSync { let blocks = &mut self.blocks; let attrs = &self.required_block_attributes; let fork_targets = &mut self.fork_targets; - let mut have_requests = false; let last_finalized = self.client.info().finalized_number; let best_queued = self.best_queued_number; let client = &self.client; @@ -681,8 +681,7 @@ impl ChainSync { peer.common_number, req, ); - have_requests = true; - Some((id.clone(), req)) + Some((id, req)) } else if let Some((hash, req)) = fork_sync_request( id, fork_targets, @@ -697,8 +696,7 @@ impl ChainSync { ) { trace!(target: "sync", "Downloading fork {:?} from {}", hash, id); peer.state = PeerSyncState::DownloadingStale(hash); - have_requests = true; - Some((id.clone(), req)) + Some((id, req)) } else { None } @@ -713,24 +711,28 @@ impl ChainSync { /// /// If this corresponds to a valid block, this outputs the block that /// must be imported in the import queue. - pub fn on_block_data - (&mut self, who: PeerId, request: Option>, response: BlockResponse) -> Result, BadPeer> - { + pub fn on_block_data( + &mut self, + who: &PeerId, + request: Option>, + response: BlockResponse + ) -> Result, BadPeer> { + self.downloaded_blocks += response.blocks.len(); let mut new_blocks: Vec> = - if let Some(peer) = self.peers.get_mut(&who) { + if let Some(peer) = self.peers.get_mut(who) { let mut blocks = response.blocks; if request.as_ref().map_or(false, |r| r.direction == message::Direction::Descending) { trace!(target: "sync", "Reversing incoming block list"); blocks.reverse() } - self.pending_requests.add(&who); + self.pending_requests.add(who); if request.is_some() { match &mut peer.state { PeerSyncState::DownloadingNew(start_block) => { - self.blocks.clear_peer_download(&who); + self.blocks.clear_peer_download(who); let start_block = *start_block; peer.state = PeerSyncState::Available; - validate_blocks::(&blocks, &who)?; + validate_blocks::(&blocks, who)?; self.blocks.insert(start_block, blocks, who.clone()); self.blocks .drain(self.best_queued_number + One::one()) @@ -751,9 +753,9 @@ impl ChainSync { peer.state = PeerSyncState::Available; if blocks.is_empty() { debug!(target: "sync", "Empty block response from {}", who); - return Err(BadPeer(who, rep::NO_BLOCK)); + return Err(BadPeer(who.clone(), rep::NO_BLOCK)); } - validate_blocks::(&blocks, &who)?; + validate_blocks::(&blocks, who)?; blocks.into_iter().map(|b| { IncomingBlock { hash: b.hash, @@ -774,11 +776,11 @@ impl ChainSync { }, (None, _) => { debug!(target: "sync", "Invalid response when searching for ancestor from {}", who); - return Err(BadPeer(who, rep::UNKNOWN_ANCESTOR)) + return Err(BadPeer(who.clone(), rep::UNKNOWN_ANCESTOR)) }, (_, Err(e)) => { info!("❌ Error answering legitimate blockchain query: {:?}", e); - return Err(BadPeer(who, rep::BLOCKCHAIN_READ_ERROR)) + return Err(BadPeer(who.clone(), rep::BLOCKCHAIN_READ_ERROR)) } }; if matching_hash.is_some() { @@ -794,7 +796,7 @@ impl ChainSync { } if matching_hash.is_none() && current.is_zero() { trace!(target:"sync", "Ancestry search: genesis mismatch for peer {}", who); - return Err(BadPeer(who, rep::GENESIS_MISMATCH)) + return Err(BadPeer(who.clone(), rep::GENESIS_MISMATCH)) } if let Some((next_state, next_num)) = handle_ancestor_search_state(state, *current, matching_hash.is_some()) { peer.state = PeerSyncState::AncestorSearch { @@ -802,7 +804,7 @@ impl ChainSync { start: *start, state: next_state, }; - return Ok(OnBlockData::Request(who, ancestry_request::(next_num))) + return Ok(OnBlockData::Request(who.clone(), ancestry_request::(next_num))) } else { // Ancestry search is complete. Check if peer is on a stale fork unknown to us and // add it to sync targets if necessary. @@ -838,7 +840,7 @@ impl ChainSync { } } else { // When request.is_none() this is a block announcement. Just accept blocks. - validate_blocks::(&blocks, &who)?; + validate_blocks::(&blocks, who)?; blocks.into_iter().map(|b| { IncomingBlock { hash: b.hash, @@ -869,7 +871,7 @@ impl ChainSync { // So the only way this can happen is when peers lie about the // common block. debug!(target: "sync", "Ignoring known blocks from {}", who); - return Err(BadPeer(who, rep::KNOWN_BLOCK)); + return Err(BadPeer(who.clone(), rep::KNOWN_BLOCK)); } let orig_len = new_blocks.len(); new_blocks.retain(|b| !self.queue_blocks.contains(&b.hash)); @@ -1001,8 +1003,6 @@ impl ChainSync { for (_, hash) in &results { self.queue_blocks.remove(&hash); } - self.processed_blocks += results.len(); - for (result, hash) in results { if has_error { continue; @@ -1124,7 +1124,7 @@ impl ChainSync { /// Updates our internal state for best queued block and then goes /// through all peers to update our view of their state as well. fn on_block_queued(&mut self, hash: &B::Hash, number: NumberFor) { - if let Some(_) = self.fork_targets.remove(&hash) { + if self.fork_targets.remove(&hash).is_some() { trace!(target: "sync", "Completed fork sync {:?}", hash); } if number > self.best_queued_number { @@ -1162,7 +1162,7 @@ impl ChainSync { /// header (call `on_block_data`). The network request isn't sent /// in this case. Both hash and header is passed as an optimization /// to avoid rehashing the header. - pub fn on_block_announce(&mut self, who: PeerId, hash: B::Hash, announce: &BlockAnnounce, is_best: bool) + pub fn on_block_announce(&mut self, who: &PeerId, hash: B::Hash, announce: &BlockAnnounce, is_best: bool) -> OnBlockAnnounce { let header = &announce.header; @@ -1177,7 +1177,7 @@ impl ChainSync { let ancient_parent = parent_status == BlockStatus::InChainPruned; let known = self.is_known(&hash); - let peer = if let Some(peer) = self.peers.get_mut(&who) { + let peer = if let Some(peer) = self.peers.get_mut(who) { peer } else { error!(target: "sync", "💔 Called on_block_announce with a bad peer ID"); @@ -1187,6 +1187,21 @@ impl ChainSync { peer.recently_announced.pop_front(); } peer.recently_announced.push_back(hash.clone()); + + // Let external validator check the block announcement. + let assoc_data = announce.data.as_ref().map_or(&[][..], |v| v.as_slice()); + let is_best = match self.block_announce_validator.validate(&header, assoc_data) { + Ok(Validation::Success { is_new_best }) => is_new_best || is_best, + Ok(Validation::Failure) => { + debug!(target: "sync", "Block announcement validation of block {} from {} failed", hash, who); + return OnBlockAnnounce::Nothing + } + Err(e) => { + error!(target: "sync", "💔 Block announcement validation errored: {}", e); + return OnBlockAnnounce::Nothing + } + }; + if is_best { // update their best block peer.best_number = number; @@ -1206,31 +1221,17 @@ impl ChainSync { peer.common_number = number - One::one(); } } - self.pending_requests.add(&who); + self.pending_requests.add(who); // known block case if known || self.is_already_downloading(&hash) { trace!(target: "sync", "Known block announce from {}: {}", who, hash); if let Some(target) = self.fork_targets.get_mut(&hash) { - target.peers.insert(who); + target.peers.insert(who.clone()); } return OnBlockAnnounce::Nothing } - // Let external validator check the block announcement. - let assoc_data = announce.data.as_ref().map_or(&[][..], |v| v.as_slice()); - match self.block_announce_validator.validate(&header, assoc_data) { - Ok(Validation::Success) => (), - Ok(Validation::Failure) => { - debug!(target: "sync", "Block announcement validation of block {} from {} failed", hash, who); - return OnBlockAnnounce::Nothing - } - Err(e) => { - error!(target: "sync", "💔 Block announcement validation errored: {}", e); - return OnBlockAnnounce::Nothing - } - } - if ancient_parent { trace!(target: "sync", "Ignored ancient block announced from {}: {} {:?}", who, hash, header); return OnBlockAnnounce::Nothing @@ -1251,27 +1252,26 @@ impl ChainSync { .entry(hash.clone()) .or_insert_with(|| ForkTarget { number, - parent_hash: Some(header.parent_hash().clone()), + parent_hash: Some(*header.parent_hash()), peers: Default::default(), }) - .peers.insert(who); + .peers.insert(who.clone()); } OnBlockAnnounce::Nothing } /// Call when a peer has disconnected. - pub fn peer_disconnected(&mut self, who: PeerId) { - self.blocks.clear_peer_download(&who); - self.peers.remove(&who); - self.extra_justifications.peer_disconnected(&who); - self.extra_finality_proofs.peer_disconnected(&who); + pub fn peer_disconnected(&mut self, who: &PeerId) { + self.blocks.clear_peer_download(who); + self.peers.remove(who); + self.extra_justifications.peer_disconnected(who); + self.extra_finality_proofs.peer_disconnected(who); self.pending_requests.set_all(); } /// Restart the sync process. fn restart<'a>(&'a mut self) -> impl Iterator), BadPeer>> + 'a { - self.processed_blocks = 0; self.blocks.clear(); let info = self.client.info(); self.best_queued_hash = info.best_hash; @@ -1430,14 +1430,24 @@ fn peer_block_request( max_parallel_downloads, MAX_DOWNLOAD_AHEAD, ) { + // The end is not part of the range. + let last = range.end.saturating_sub(One::one()); + + let from = if peer.best_number == last { + message::FromBlock::Hash(peer.best_hash) + } else { + message::FromBlock::Number(last) + }; + let request = message::generic::BlockRequest { id: 0, fields: attrs.clone(), - from: message::FromBlock::Number(range.start), + from, to: None, - direction: message::Direction::Ascending, + direction: message::Direction::Descending, max: Some((range.end - range.start).saturated_into::()) }; + Some((range, request)) } else { None @@ -1471,11 +1481,12 @@ fn fork_sync_request( } if r.number <= best_num { let parent_status = r.parent_hash.as_ref().map_or(BlockStatus::Unknown, check_block); - let mut count = (r.number - finalized).saturated_into::(); // up to the last finalized block - if parent_status != BlockStatus::Unknown { + let count = if parent_status == BlockStatus::Unknown { + (r.number - finalized).saturated_into::() // up to the last finalized block + } else { // request only single block - count = 1; - } + 1 + }; trace!(target: "sync", "Downloading requested fork {:?} from {}, {} blocks", hash, id, count); return Some((hash.clone(), message::generic::BlockRequest { id: 0, @@ -1559,7 +1570,7 @@ mod test { let client = Arc::new(TestClientBuilder::new().build()); let info = client.info(); - let block_announce_validator = Box::new(DefaultBlockAnnounceValidator::new(client.clone())); + let block_announce_validator = Box::new(DefaultBlockAnnounceValidator); let peer_id = PeerId::random(); let mut sync = ChainSync::new( diff --git a/client/network/src/protocol/sync/blocks.rs b/client/network/src/protocol/sync/blocks.rs index 359287701e66e5b95b9561bbd5982fd50e77e08d..b64c9e053e97b3018562beca4f439d71f17c8edb 100644 --- a/client/network/src/protocol/sync/blocks.rs +++ b/client/network/src/protocol/sync/blocks.rs @@ -1,23 +1,24 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::cmp; use std::ops::Range; use std::collections::{HashMap, BTreeMap}; -use std::collections::hash_map::Entry; use log::trace; use libp2p::PeerId; use sp_runtime::traits::{Block as BlockT, NumberFor, One}; @@ -116,17 +117,17 @@ impl BlockCollection { let mut prev: Option<(&NumberFor, &BlockRangeState)> = None; loop { let next = downloading_iter.next(); - break match &(prev, next) { - &(Some((start, &BlockRangeState::Downloading { ref len, downloading })), _) + break match (prev, next) { + (Some((start, &BlockRangeState::Downloading { ref len, downloading })), _) if downloading < max_parallel => (*start .. *start + *len, downloading), - &(Some((start, r)), Some((next_start, _))) if *start + r.len() < *next_start => + (Some((start, r)), Some((next_start, _))) if *start + r.len() < *next_start => (*start + r.len() .. cmp::min(*next_start, *start + r.len() + count), 0), // gap - &(Some((start, r)), None) => + (Some((start, r)), None) => (*start + r.len() .. *start + r.len() + count, 0), // last range - &(None, None) => + (None, None) => (first_different .. first_different + count, 0), // empty - &(None, Some((start, _))) if *start > first_different => + (None, Some((start, _))) if *start > first_different => (first_different .. cmp::min(first_different + count, *start), 0), // gap at the start _ => { prev = next; @@ -167,7 +168,7 @@ impl BlockCollection { let mut prev = from; for (start, range_data) in &mut self.blocks { match range_data { - &mut BlockRangeState::Complete(ref mut blocks) if *start <= prev => { + BlockRangeState::Complete(blocks) if *start <= prev => { prev = *start + (blocks.len() as u32).into(); // Remove all elements from `blocks` and add them to `drained` drained.append(blocks); @@ -185,26 +186,22 @@ impl BlockCollection { } pub fn clear_peer_download(&mut self, who: &PeerId) { - match self.peer_requests.entry(who.clone()) { - Entry::Occupied(entry) => { - let start = entry.remove(); - let remove = match self.blocks.get_mut(&start) { - Some(&mut BlockRangeState::Downloading { ref mut downloading, .. }) if *downloading > 1 => { - *downloading = *downloading - 1; - false - }, - Some(&mut BlockRangeState::Downloading { .. }) => { - true - }, - _ => { - false - } - }; - if remove { - self.blocks.remove(&start); + if let Some(start) = self.peer_requests.remove(who) { + let remove = match self.blocks.get_mut(&start) { + Some(&mut BlockRangeState::Downloading { ref mut downloading, .. }) if *downloading > 1 => { + *downloading -= 1; + false + }, + Some(&mut BlockRangeState::Downloading { .. }) => { + true + }, + _ => { + false } - }, - _ => (), + }; + if remove { + self.blocks.remove(&start); + } } } } diff --git a/client/network/src/protocol/sync/extra_requests.rs b/client/network/src/protocol/sync/extra_requests.rs index 3d854b574b01fc26aaf6d1d39e15bed2b46551c2..d025b86b2536f5912ffa83a43dbbbfef1e56bed5 100644 --- a/client/network/src/protocol/sync/extra_requests.rs +++ b/client/network/src/protocol/sync/extra_requests.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use sp_blockchain::Error as ClientError; use crate::protocol::sync::{PeerSync, PeerSyncState}; @@ -102,11 +104,9 @@ impl ExtraRequests { // we have finalized further than the given request, presumably // by some other part of the system (not sync). we can safely // ignore the `Revert` error. - return; }, Err(err) => { debug!(target: "sync", "Failed to insert request {:?} into tree: {:?}", request, err); - return; } _ => () } @@ -141,7 +141,7 @@ impl ExtraRequests { request, ); } - self.failed_requests.entry(request).or_insert(Vec::new()).push((who, Instant::now())); + self.failed_requests.entry(request).or_default().push((who, Instant::now())); self.pending_requests.push_front(request); } else { trace!(target: "sync", "No active {} request to {:?}", diff --git a/client/network/src/protocol/util.rs b/client/network/src/protocol/util.rs deleted file mode 100644 index 9ba9bf6ae89c1aab2b4e2da9fb4dff237c8af660..0000000000000000000000000000000000000000 --- a/client/network/src/protocol/util.rs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -use linked_hash_set::LinkedHashSet; -use std::{hash::Hash, num::NonZeroUsize}; - -/// Wrapper around `LinkedHashSet` which grows bounded. -/// -/// In the limit, for each element inserted the oldest existing element will be removed. -#[derive(Debug, Clone)] -pub(crate) struct LruHashSet { - set: LinkedHashSet, - limit: NonZeroUsize -} - -impl LruHashSet { - /// Create a new `LruHashSet` with the given (exclusive) limit. - pub(crate) fn new(limit: NonZeroUsize) -> Self { - Self { set: LinkedHashSet::new(), limit } - } - - /// Insert element into the set. - /// - /// Returns `true` if this is a new element to the set, `false` otherwise. - /// Maintains the limit of the set by removing the oldest entry if necessary. - /// Inserting the same element will update its LRU position. - pub(crate) fn insert(&mut self, e: T) -> bool { - if self.set.insert(e) { - if self.set.len() == usize::from(self.limit) { - self.set.pop_front(); // remove oldest entry - } - return true - } - false - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn maintains_limit() { - let three = NonZeroUsize::new(3).unwrap(); - let mut set = LruHashSet::::new(three); - - // First element. - assert!(set.insert(1)); - assert_eq!(vec![&1], set.set.iter().collect::>()); - - // Second element. - assert!(set.insert(2)); - assert_eq!(vec![&1, &2], set.set.iter().collect::>()); - - // Inserting the same element updates its LRU position. - assert!(!set.insert(1)); - assert_eq!(vec![&2, &1], set.set.iter().collect::>()); - - // We reached the limit. The next element forces the oldest one out. - assert!(set.insert(3)); - assert_eq!(vec![&1, &3], set.set.iter().collect::>()); - } -} diff --git a/client/network/src/schema.rs b/client/network/src/schema.rs index 0c8a650e69394d0568ca322a33d4296a840b75d7..44fbbffd25406d5b985707f46f8c2e9123ca992a 100644 --- a/client/network/src/schema.rs +++ b/client/network/src/schema.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Include sources generated from protobuf definitions. diff --git a/client/network/src/service.rs b/client/network/src/service.rs index 64b3d3b5b22f4123db98d248a833bb2187e808c0..c9213d4dde286f870712f7322508a2d9a6366f4e 100644 --- a/client/network/src/service.rs +++ b/client/network/src/service.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Main entry point of the sc-network crate. //! @@ -28,7 +30,8 @@ use crate::{ ExHashT, NetworkStateInfo, behaviour::{Behaviour, BehaviourOut}, - config::{parse_addr, parse_str_addr, NonReservedPeerMode, Params, Role, TransportConfig}, + config::{parse_str_addr, NonReservedPeerMode, Params, Role, TransportConfig}, + DhtEvent, discovery::DiscoveryConfig, error::Error, network_state::{ @@ -36,11 +39,11 @@ use crate::{ }, on_demand_layer::AlwaysBadChecker, light_client_handler, block_requests, finality_requests, - protocol::{self, event::Event, LegacyConnectionKillError, sync::SyncState, PeerInfo, Protocol}, + protocol::{self, event::Event, NotifsHandlerError, LegacyConnectionKillError, NotificationsSink, Ready, sync::SyncState, PeerInfo, Protocol}, transport, ReputationChange, }; use futures::prelude::*; -use libp2p::{PeerId, Multiaddr}; +use libp2p::{PeerId, multiaddr, Multiaddr}; use libp2p::core::{ConnectedPoint, Executor, connection::{ConnectionError, PendingConnectionError}, either::EitherError}; use libp2p::kad::record; use libp2p::ping::handler::PingFailure; @@ -48,7 +51,9 @@ use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent, protocols_handle use log::{error, info, trace, warn}; use parking_lot::Mutex; use prometheus_endpoint::{ - register, Counter, CounterVec, Gauge, GaugeVec, HistogramOpts, HistogramVec, Opts, PrometheusError, Registry, U64, + register, Counter, CounterVec, Gauge, GaugeVec, Histogram, HistogramOpts, HistogramVec, Opts, + PrometheusError, Registry, U64, + SourcedCounter, MetricSource }; use sc_peerset::PeersetHandle; use sp_consensus::import_queue::{BlockImportError, BlockImportResult, ImportQueue, Link}; @@ -58,10 +63,11 @@ use sp_runtime::{ }; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; use std::{ - borrow::Cow, - collections::HashSet, - fs, io, + borrow::{Borrow, Cow}, + collections::{HashMap, HashSet}, + fs, marker::PhantomData, + num:: NonZeroUsize, pin::Pin, str, sync::{ @@ -92,6 +98,14 @@ pub struct NetworkService { peerset: PeersetHandle, /// Channel that sends messages to the actual worker. to_worker: TracingUnboundedSender>, + /// For each peer and protocol combination, an object that allows sending notifications to + /// that peer. Updated by the [`NetworkWorker`]. + peers_notifications_sinks: Arc>>, + /// For each legacy gossiping engine ID, the corresponding new protocol name. + protocol_name_by_engine: Mutex>>, + /// Field extracted from the [`Metrics`] struct and necessary to report the + /// notifications-related metrics. + notifications_sizes_metric: Option, /// Marker to pin the `H` generic. Serves no purpose except to not break backwards /// compatibility. _marker: PhantomData, @@ -104,7 +118,25 @@ impl NetworkWorker { /// for the network processing to advance. From it, you can extract a `NetworkService` using /// `worker.service()`. The `NetworkService` can be shared through the codebase. pub fn new(params: Params) -> Result, Error> { - let (to_worker, from_worker) = tracing_unbounded("mpsc_network_worker"); + // Ensure the listen addresses are consistent with the transport. + ensure_addresses_consistent_with_transport( + params.network_config.listen_addresses.iter(), + ¶ms.network_config.transport, + )?; + ensure_addresses_consistent_with_transport( + params.network_config.boot_nodes.iter().map(|x| &x.multiaddr), + ¶ms.network_config.transport, + )?; + ensure_addresses_consistent_with_transport( + params.network_config.reserved_nodes.iter().map(|x| &x.multiaddr), + ¶ms.network_config.transport, + )?; + ensure_addresses_consistent_with_transport( + params.network_config.public_addresses.iter(), + ¶ms.network_config.transport, + )?; + + let (to_worker, from_service) = tracing_unbounded("mpsc_network_worker"); if let Some(path) = params.network_config.net_config_path { fs::create_dir_all(&path)?; @@ -149,17 +181,34 @@ impl NetworkWorker { known_addresses.push((reserved.peer_id.clone(), reserved.multiaddr.clone())); } + let print_deprecated_message = match ¶ms.role { + Role::Sentry { .. } => true, + Role::Authority { sentry_nodes } if !sentry_nodes.is_empty() => true, + _ => false, + }; + if print_deprecated_message { + log::warn!( + "🙇 Sentry nodes are deprecated, and the `--sentry` and `--sentry-nodes` \ + CLI options will eventually be removed in a future version. The Substrate \ + and Polkadot networking protocol require validators to be \ + publicly-accessible. Please do not block access to your validator nodes. \ + For details, see https://github.com/paritytech/substrate/issues/6845." + ); + } + let mut sentries_and_validators = HashSet::new(); match ¶ms.role { Role::Sentry { validators } => { for validator in validators { sentries_and_validators.insert(validator.peer_id.clone()); + reserved_nodes.insert(validator.peer_id.clone()); known_addresses.push((validator.peer_id.clone(), validator.multiaddr.clone())); } } Role::Authority { sentry_nodes } => { for sentry_node in sentry_nodes { sentries_and_validators.insert(sentry_node.peer_id.clone()); + reserved_nodes.insert(sentry_node.peer_id.clone()); known_addresses.push((sentry_node.peer_id.clone(), sentry_node.multiaddr.clone())); } } @@ -184,17 +233,17 @@ impl NetworkWorker { let local_identity = params.network_config.node_key.clone().into_keypair()?; let local_public = local_identity.public(); let local_peer_id = local_public.clone().into_peer_id(); - info!(target: "sub-libp2p", "🏷 Local node identity is: {}", local_peer_id.to_base58()); - - // Initialize the metrics. - let metrics = match ¶ms.metrics_registry { - Some(registry) => Some(Metrics::register(®istry)?), - None => None - }; + let local_peer_id_legacy = bs58::encode(Borrow::<[u8]>::borrow(&local_peer_id)).into_string(); + info!( + target: "sub-libp2p", + "🏷 Local node identity is: {} (legacy representation: {})", + local_peer_id.to_base58(), + local_peer_id_legacy + ); let checker = params.on_demand.as_ref() .map(|od| od.checker().clone()) - .unwrap_or(Arc::new(AlwaysBadChecker)); + .unwrap_or_else(|| Arc::new(AlwaysBadChecker)); let num_connected = Arc::new(AtomicUsize::new(0)); let is_major_syncing = Arc::new(AtomicBool::new(false)); @@ -203,17 +252,15 @@ impl NetworkWorker { roles: From::from(¶ms.role), max_parallel_downloads: params.network_config.max_parallel_downloads, }, + local_peer_id.clone(), params.chain.clone(), params.transaction_pool, - params.finality_proof_provider.clone(), params.finality_proof_request_builder, params.protocol_id.clone(), peerset_config, params.block_announce_validator, params.metrics_registry.as_ref(), boot_node_ids.clone(), - params.network_config.use_new_block_requests_protocol, - metrics.as_ref().map(|m| m.notifications_queues_size.clone()), )?; // Build the swarm. @@ -285,7 +332,9 @@ impl NetworkWorker { transport::build_transport(local_identity, config_mem, config_wasm, flowctrl) }; let mut builder = SwarmBuilder::new(transport, behaviour, local_peer_id.clone()) - .peer_connection_limit(crate::MAX_CONNECTIONS_PER_PEER); + .peer_connection_limit(crate::MAX_CONNECTIONS_PER_PEER) + .notify_handler_buffer_size(NonZeroUsize::new(32).expect("32 != 0; qed")) + .connection_event_buffer_size(1024); if let Some(spawner) = params.executor { struct SpawnImpl(F); impl + Send>>)> Executor for SpawnImpl { @@ -298,6 +347,17 @@ impl NetworkWorker { (builder.build(), bandwidth) }; + // Initialize the metrics. + let metrics = match ¶ms.metrics_registry { + Some(registry) => { + // Sourced metrics. + BandwidthCounters::register(registry, bandwidth.clone())?; + // Other (i.e. new) metrics. + Some(Metrics::register(registry)?) + } + None => None + }; + // Listen on multiaddresses. for addr in ¶ms.network_config.listen_addresses { if let Err(err) = Swarm::::listen_on(&mut swarm, addr.clone()) { @@ -311,6 +371,10 @@ impl NetworkWorker { } let external_addresses = Arc::new(Mutex::new(Vec::new())); + let peers_notifications_sinks = Arc::new(Mutex::new(HashMap::new())); + let protocol_name_by_engine = Mutex::new({ + params.network_config.notifications_protocols.iter().cloned().collect() + }); let service = Arc::new(NetworkService { bandwidth, @@ -319,7 +383,11 @@ impl NetworkWorker { is_major_syncing: is_major_syncing.clone(), peerset: peerset_handle, local_peer_id, - to_worker: to_worker.clone(), + to_worker, + peers_notifications_sinks: peers_notifications_sinks.clone(), + protocol_name_by_engine, + notifications_sizes_metric: + metrics.as_ref().map(|metrics| metrics.notifications_sizes.clone()), _marker: PhantomData, }); @@ -330,22 +398,23 @@ impl NetworkWorker { network_service: swarm, service, import_queue: params.import_queue, - from_worker, + from_service, light_client_rqs: params.on_demand.and_then(|od| od.extract_receiver()), event_streams: out_events::OutChannels::new(params.metrics_registry.as_ref())?, + peers_notifications_sinks, metrics, boot_node_ids, }) } - /// Returns the downloaded bytes per second averaged over the past few seconds. - pub fn average_download_per_sec(&self) -> u64 { - self.service.bandwidth.average_download_per_sec() + /// Returns the total number of bytes received so far. + pub fn total_bytes_inbound(&self) -> u64 { + self.service.bandwidth.total_inbound() } - /// Returns the uploaded bytes per second averaged over the past few seconds. - pub fn average_upload_per_sec(&self) -> u64 { - self.service.bandwidth.average_upload_per_sec() + /// Returns the total number of bytes sent so far. + pub fn total_bytes_outbound(&self) -> u64 { + self.service.bandwidth.total_outbound() } /// Returns the number of peers we're connected to. @@ -378,9 +447,9 @@ impl NetworkWorker { self.network_service.user_protocol().num_queued_blocks() } - /// Returns the number of processed blocks. - pub fn num_processed_blocks(&self) -> usize { - self.network_service.user_protocol().num_processed_blocks() + /// Returns the number of downloaded blocks. + pub fn num_downloaded_blocks(&self) -> usize { + self.network_service.user_protocol().num_downloaded_blocks() } /// Number of active sync requests. @@ -399,16 +468,18 @@ impl NetworkWorker { &self.service } - /// You must call this when a new block is imported by the client. - pub fn on_block_imported(&mut self, header: B::Header, is_best: bool) { - self.network_service.user_protocol_mut().on_block_imported(&header, is_best); - } - /// You must call this when a new block is finalized by the client. pub fn on_block_finalized(&mut self, hash: B::Hash, header: B::Header) { self.network_service.user_protocol_mut().on_block_finalized(hash, &header); } + /// This should be called when blocks are added to the + /// chain by something other than the import queue. + /// Currently this is only useful for tests. + pub fn update_chain(&mut self) { + self.network_service.user_protocol_mut().update_chain(); + } + /// Returns the local `PeerId`. pub fn local_peer_id(&self) -> &PeerId { Swarm::::local_peer_id(&self.network_service) @@ -446,7 +517,7 @@ impl NetworkWorker { Some((peer_id.to_base58(), NetworkStatePeer { endpoint, version_string: swarm.node(peer_id) - .and_then(|i| i.client_version().map(|s| s.to_owned())).clone(), + .and_then(|i| i.client_version().map(|s| s.to_owned())), latest_ping_time: swarm.node(peer_id).and_then(|i| i.latest_ping()), enabled: swarm.user_protocol().is_enabled(&peer_id), open: swarm.user_protocol().is_open(&peer_id), @@ -457,25 +528,26 @@ impl NetworkWorker { let not_connected_peers = { let swarm = &mut *swarm; - let list = swarm.known_peers().filter(|p| open.iter().all(|n| n != *p)) - .cloned().collect::>(); - list.into_iter().map(move |peer_id| { - (peer_id.to_base58(), NetworkStateNotConnectedPeer { - version_string: swarm.node(&peer_id) - .and_then(|i| i.client_version().map(|s| s.to_owned())).clone(), - latest_ping_time: swarm.node(&peer_id).and_then(|i| i.latest_ping()), - known_addresses: NetworkBehaviour::addresses_of_peer(&mut **swarm, &peer_id) - .into_iter().collect(), + swarm.known_peers().into_iter() + .filter(|p| open.iter().all(|n| n != p)) + .map(move |peer_id| { + (peer_id.to_base58(), NetworkStateNotConnectedPeer { + version_string: swarm.node(&peer_id) + .and_then(|i| i.client_version().map(|s| s.to_owned())), + latest_ping_time: swarm.node(&peer_id).and_then(|i| i.latest_ping()), + known_addresses: NetworkBehaviour::addresses_of_peer(&mut **swarm, &peer_id) + .into_iter().collect(), + }) }) - }).collect() + .collect() }; NetworkState { peer_id: Swarm::::local_peer_id(&swarm).to_base58(), listened_addresses: Swarm::::listeners(&swarm).cloned().collect(), external_addresses: Swarm::::external_addresses(&swarm).cloned().collect(), - average_download_per_sec: self.service.bandwidth.average_download_per_sec(), - average_upload_per_sec: self.service.bandwidth.average_upload_per_sec(), + total_bytes_inbound: self.service.bandwidth.total_inbound(), + total_bytes_outbound: self.service.bandwidth.total_outbound(), connected_peers, not_connected_peers, peerset: swarm.user_protocol_mut().peerset_debug_info(), @@ -508,8 +580,16 @@ impl NetworkService { &self.local_peer_id } - /// Writes a message on an open notifications channel. Has no effect if the notifications - /// channel with this protocol name is closed. + /// Appends a notification to the buffer of pending outgoing notifications with the given peer. + /// Has no effect if the notifications channel with this protocol name is not open. + /// + /// If the buffer of pending outgoing notifications with that peer is full, the notification + /// is silently dropped and the connection to the remote will start being shut down. This + /// happens if you call this method at a higher rate than the rate at which the peer processes + /// these notifications, or if the available network bandwidth is too low. + /// + /// For this reason, this method is considered soft-deprecated. You are encouraged to use + /// [`NetworkService::notification_sender`] instead. /// /// > **Note**: The reason why this is a no-op in the situation where we have no channel is /// > that we don't guarantee message delivery anyway. Networking issues can cause @@ -517,14 +597,149 @@ impl NetworkService { /// > between the remote voluntarily closing a substream or a network error /// > preventing the message from being delivered. /// - /// The protocol must have been registered with `register_notifications_protocol`. + /// The protocol must have been registered with `register_notifications_protocol` or + /// `NetworkConfiguration::notifications_protocols`. /// pub fn write_notification(&self, target: PeerId, engine_id: ConsensusEngineId, message: Vec) { - let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::WriteNotification { - target, + // We clone the `NotificationsSink` in order to be able to unlock the network-wide + // `peers_notifications_sinks` mutex as soon as possible. + let sink = { + let peers_notifications_sinks = self.peers_notifications_sinks.lock(); + if let Some(sink) = peers_notifications_sinks.get(&(target, engine_id)) { + sink.clone() + } else { + // Notification silently discarded, as documented. + return; + } + }; + + // Used later for the metrics report. + let message_len = message.len(); + + // Determine the wire protocol name corresponding to this `engine_id`. + let protocol_name = self.protocol_name_by_engine.lock().get(&engine_id).cloned(); + if let Some(protocol_name) = protocol_name { + // For backwards-compatibility reason, we have to duplicate the message and pass it + // in the situation where the remote still uses the legacy substream. + let fallback = codec::Encode::encode(&{ + protocol::message::generic::Message::<(), (), (), ()>::Consensus({ + protocol::message::generic::ConsensusMessage { + engine_id, + data: message.clone(), + } + }) + }); + + sink.send_sync_notification(&protocol_name, fallback, message); + } else { + return; + } + + if let Some(notifications_sizes_metric) = self.notifications_sizes_metric.as_ref() { + notifications_sizes_metric + .with_label_values(&["out", &maybe_utf8_bytes_to_string(&engine_id)]) + .observe(message_len as f64); + } + } + + /// Obtains a [`NotificationSender`] for a connected peer, if it exists. + /// + /// A `NotificationSender` is scoped to a particular connection to the peer that holds + /// a receiver. With a `NotificationSender` at hand, sending a notification is done in two steps: + /// + /// 1. [`NotificationSender::ready`] is used to wait for the sender to become ready + /// for another notification, yielding a [`NotificationSenderReady`] token. + /// 2. [`NotificationSenderReady::send`] enqueues the notification for sending. This operation + /// can only fail if the underlying notification substream or connection has suddenly closed. + /// + /// An error is returned either by `notification_sender`, by [`NotificationSender::wait`], + /// or by [`NotificationSenderReady::send`] if there exists no open notifications substream + /// with that combination of peer and protocol, or if the remote has asked to close the + /// notifications substream. If that happens, it is guaranteed that an + /// [`Event::NotificationStreamClosed`] has been generated on the stream returned by + /// [`NetworkService::event_stream`]. + /// + /// If the remote requests to close the notifications substream, all notifications successfully + /// enqueued using [`NotificationSenderReady::send`] will finish being sent out before the + /// substream actually gets closed, but attempting to enqueue more notifications will now + /// return an error. It is however possible for the entire connection to be abruptly closed, + /// in which case enqueued notifications will be lost. + /// + /// The protocol must have been registered with `register_notifications_protocol` or + /// `NetworkConfiguration::notifications_protocols`. + /// + /// # Usage + /// + /// This method returns a struct that allows waiting until there is space available in the + /// buffer of messages towards the given peer. If the peer processes notifications at a slower + /// rate than we send them, this buffer will quickly fill up. + /// + /// As such, you should never do something like this: + /// + /// ```ignore + /// // Do NOT do this + /// for peer in peers { + /// if let Ok(n) = network.notification_sender(peer, ...) { + /// if let Ok(s) = n.ready().await { + /// let _ = s.send(...); + /// } + /// } + /// } + /// ``` + /// + /// Doing so would slow down all peers to the rate of the slowest one. A malicious or + /// malfunctioning peer could intentionally process notifications at a very slow rate. + /// + /// Instead, you are encouraged to maintain your own buffer of notifications on top of the one + /// maintained by `sc-network`, and use `notification_sender` to progressively send out + /// elements from your buffer. If this additional buffer is full (which will happen at some + /// point if the peer is too slow to process notifications), appropriate measures can be taken, + /// such as removing non-critical notifications from the buffer or disconnecting the peer + /// using [`NetworkService::disconnect_peer`]. + /// + /// + /// Notifications Per-peer buffer + /// broadcast +-------> of notifications +--> `notification_sender` +--> Internet + /// ^ (not covered by + /// | sc-network) + /// + + /// Notifications should be dropped + /// if buffer is full + /// + /// + /// See also the [`gossip`](crate::gossip) module for a higher-level way to send + /// notifications. + /// + pub fn notification_sender( + &self, + target: PeerId, + engine_id: ConsensusEngineId, + ) -> Result { + // We clone the `NotificationsSink` in order to be able to unlock the network-wide + // `peers_notifications_sinks` mutex as soon as possible. + let sink = { + let peers_notifications_sinks = self.peers_notifications_sinks.lock(); + if let Some(sink) = peers_notifications_sinks.get(&(target, engine_id)) { + sink.clone() + } else { + return Err(NotificationSenderError::Closed); + } + }; + + // Determine the wire protocol name corresponding to this `engine_id`. + let protocol_name = match self.protocol_name_by_engine.lock().get(&engine_id).cloned() { + Some(p) => p, + None => return Err(NotificationSenderError::BadProtocol), + }; + + Ok(NotificationSender { + sink, + protocol_name, engine_id, - message, - }); + notification_size_metric: self.notifications_sizes_metric.as_ref().map(|histogram| { + histogram.with_label_values(&["out", &maybe_utf8_bytes_to_string(&engine_id)]) + }), + }) } /// Returns a stream containing the events that happen on the network. @@ -545,21 +760,27 @@ impl NetworkService { /// Registers a new notifications protocol. /// - /// After that, you can call `write_notifications`. + /// After a protocol has been registered, you can call `write_notifications`. + /// + /// **Important**: This method is a work-around, and you are instead strongly encouraged to + /// pass the protocol in the `NetworkConfiguration::notifications_protocols` list instead. + /// If you have no other choice but to use this method, you are very strongly encouraged to + /// call it very early on. Any connection open will retain the protocols that were registered + /// then, and not any new one. /// /// Please call `event_stream` before registering a protocol, otherwise you may miss events /// about the protocol that you have registered. - /// - /// You are very strongly encouraged to call this method very early on. Any connection open - /// will retain the protocols that were registered then, and not any new one. + // TODO: remove this method after https://github.com/paritytech/substrate/issues/4587 pub fn register_notifications_protocol( &self, engine_id: ConsensusEngineId, protocol_name: impl Into>, ) { + let protocol_name = protocol_name.into(); + self.protocol_name_by_engine.lock().insert(engine_id, protocol_name.clone()); let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::RegisterNotifProtocol { engine_id, - protocol_name: protocol_name.into(), + protocol_name, }); } @@ -568,15 +789,15 @@ impl NetworkService { /// All transactions will be fetched from the `TransactionPool` that was passed at /// initialization as part of the configuration and propagated to peers. pub fn trigger_repropagate(&self) { - let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::PropagateExtrinsics); + let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::PropagateTransactions); } /// You must call when new transaction is imported by the transaction pool. /// /// This transaction will be fetched from the `TransactionPool` that was passed at /// initialization as part of the configuration and propagated to peers. - pub fn propagate_extrinsic(&self, hash: H) { - let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::PropagateExtrinsic(hash)); + pub fn propagate_transaction(&self, hash: H) { + let _ = self.to_worker.unbounded_send(ServiceToWorkerMsg::PropagateTransaction(hash)); } /// Make sure an important block is propagated to peers. @@ -607,7 +828,7 @@ impl NetworkService { pub fn request_justification(&self, hash: &B::Hash, number: NumberFor) { let _ = self .to_worker - .unbounded_send(ServiceToWorkerMsg::RequestJustification(hash.clone(), number)); + .unbounded_send(ServiceToWorkerMsg::RequestJustification(*hash, number)); } /// Are we in the process of downloading the chain? @@ -652,8 +873,15 @@ impl NetworkService { /// Adds a `PeerId` and its address as reserved. The string should encode the address /// and peer ID of the remote node. + /// + /// Returns an `Err` if the given string is not a valid multiaddress + /// or contains an invalid peer ID (which includes the local peer ID). pub fn add_reserved_peer(&self, peer: String) -> Result<(), String> { let (peer_id, addr) = parse_str_addr(&peer).map_err(|e| format!("{:?}", e))?; + // Make sure the local peer ID is never added to the PSM. + if peer_id == self.local_peer_id { + return Err("Local peer ID cannot be added as a reserved peer.".to_string()) + } self.peerset.add_reserved_peer(peer_id.clone()); let _ = self .to_worker @@ -674,12 +902,32 @@ impl NetworkService { } /// Modify a peerset priority group. + /// + /// Each `Multiaddr` must end with a `/p2p/` component containing the `PeerId`. + /// + /// Returns an `Err` if one of the given addresses is invalid or contains an + /// invalid peer ID (which includes the local peer ID). pub fn set_priority_group(&self, group_id: String, peers: HashSet) -> Result<(), String> { - let peers = peers.into_iter().map(|p| { - parse_addr(p).map_err(|e| format!("{:?}", e)) - }).collect::, String>>()?; + let peers = peers.into_iter() + .map(|mut addr| { + let peer = match addr.pop() { + Some(multiaddr::Protocol::P2p(key)) => PeerId::from_multihash(key) + .map_err(|_| "Invalid PeerId format".to_string())?, + _ => return Err("Missing PeerId from address".to_string()), + }; + + // Make sure the local peer ID is never added to the PSM + // or added as a "known address", even if given. + if peer == self.local_peer_id { + Err("Local peer ID in priority group.".to_string()) + } else { + Ok((peer, addr)) + } + }) + .collect::, String>>()?; let peer_ids = peers.iter().map(|(peer_id, _addr)| peer_id.clone()).collect(); + self.peerset.set_priority_group(group_id, peer_ids); for (peer_id, addr) in peers.into_iter() { @@ -695,6 +943,23 @@ impl NetworkService { pub fn num_connected(&self) -> usize { self.num_connected.load(Ordering::Relaxed) } + + /// This function should be called when blocks are added to the chain by something other + /// than the import queue. + /// + /// > **Important**: This function is a hack and can be removed at any time. Do **not** use it. + pub fn update_chain(&self) { + let _ = self + .to_worker + .unbounded_send(ServiceToWorkerMsg::UpdateChain); + } + + /// Inform the network service about an own imported block. + pub fn own_block_imported(&self, hash: B::Hash, number: NumberFor) { + let _ = self + .to_worker + .unbounded_send(ServiceToWorkerMsg::OwnBlockImported(hash, number)); + } } impl sp_consensus::SyncOracle @@ -737,12 +1002,93 @@ impl NetworkStateInfo for NetworkService } } +/// A `NotificationSender` allows for sending notifications to a peer with a chosen protocol. +#[must_use] +pub struct NotificationSender { + sink: NotificationsSink, + + /// Name of the protocol on the wire. + protocol_name: Cow<'static, [u8]>, + + /// Engine ID used for the fallback message. + engine_id: ConsensusEngineId, + + /// Field extracted from the [`Metrics`] struct and necessary to report the + /// notifications-related metrics. + notification_size_metric: Option, +} + +impl NotificationSender { + /// Returns a future that resolves when the `NotificationSender` is ready to send a notification. + pub async fn ready<'a>(&'a self) -> Result, NotificationSenderError> { + Ok(NotificationSenderReady { + ready: match self.sink.reserve_notification(&self.protocol_name).await { + Ok(r) => r, + Err(()) => return Err(NotificationSenderError::Closed), + }, + engine_id: self.engine_id, + notification_size_metric: self.notification_size_metric.clone(), + }) + } +} + +/// Reserved slot in the notifications buffer, ready to accept data. +#[must_use] +pub struct NotificationSenderReady<'a> { + ready: Ready<'a>, + + /// Engine ID used for the fallback message. + engine_id: ConsensusEngineId, + + /// Field extracted from the [`Metrics`] struct and necessary to report the + /// notifications-related metrics. + notification_size_metric: Option, +} + +impl<'a> NotificationSenderReady<'a> { + /// Consumes this slots reservation and actually queues the notification. + pub fn send(self, notification: impl Into>) -> Result<(), NotificationSenderError> { + let notification = notification.into(); + + if let Some(notification_size_metric) = &self.notification_size_metric { + notification_size_metric.observe(notification.len() as f64); + } + + // For backwards-compatibility reason, we have to duplicate the message and pass it + // in the situation where the remote still uses the legacy substream. + let fallback = codec::Encode::encode(&{ + protocol::message::generic::Message::<(), (), (), ()>::Consensus({ + protocol::message::generic::ConsensusMessage { + engine_id: self.engine_id, + data: notification.clone(), + } + }) + }); + + self.ready.send(fallback, notification) + .map_err(|()| NotificationSenderError::Closed) + } +} + +/// Error returned by [`NetworkService::send_notification`]. +#[derive(Debug, derive_more::Display, derive_more::Error)] +pub enum NotificationSenderError { + /// The notification receiver has been closed, usually because the underlying connection closed. + /// + /// Some of the notifications most recently sent may not have been received. However, + /// the peer may still be connected and a new `NotificationSender` for the same + /// protocol obtained from [`NetworkService::notification_sender`]. + Closed, + /// Protocol name hasn't been registered. + BadProtocol, +} + /// Messages sent from the `NetworkService` to the `NetworkWorker`. /// /// Each entry corresponds to a method of `NetworkService`. enum ServiceToWorkerMsg { - PropagateExtrinsic(H), - PropagateExtrinsics, + PropagateTransaction(H), + PropagateTransactions, RequestJustification(B::Hash, NumberFor), AnnounceBlock(B::Hash, Vec), GetValue(record::Key), @@ -750,22 +1096,19 @@ enum ServiceToWorkerMsg { AddKnownAddress(PeerId, Multiaddr), SyncFork(Vec, B::Hash, NumberFor), EventStream(out_events::Sender), - WriteNotification { - message: Vec, - engine_id: ConsensusEngineId, - target: PeerId, - }, RegisterNotifProtocol { engine_id: ConsensusEngineId, protocol_name: Cow<'static, [u8]>, }, DisconnectPeer(PeerId), + UpdateChain, + OwnBlockImported(B::Hash, NumberFor), } /// Main network worker. Must be polled in order for the network to advance. /// /// You are encouraged to poll this in a separate background thread or task. -#[must_use = "The NetworkWorker must be polled in order for the network to work"] +#[must_use = "The NetworkWorker must be polled in order for the network to advance"] pub struct NetworkWorker { /// Updated by the `NetworkWorker` and loaded by the `NetworkService`. external_addresses: Arc>>, @@ -777,10 +1120,10 @@ pub struct NetworkWorker { service: Arc>, /// The *actual* network. network_service: Swarm, - /// The import queue that was passed as initialization. + /// The import queue that was passed at initialization. import_queue: Box>, - /// Messages from the `NetworkService` and that must be processed. - from_worker: TracingUnboundedReceiver>, + /// Messages from the [`NetworkService`] that must be processed. + from_service: TracingUnboundedReceiver>, /// Receiver for queries from the light client that must be processed. light_client_rqs: Option>>, /// Senders for events that happen on the network. @@ -789,12 +1132,17 @@ pub struct NetworkWorker { metrics: Option, /// The `PeerId`'s of all boot nodes. boot_node_ids: Arc>, + /// For each peer and protocol combination, an object that allows sending notifications to + /// that peer. Shared with the [`NetworkService`]. + peers_notifications_sinks: Arc>>, } struct Metrics { // This list is ordered alphabetically connections_closed_total: CounterVec, connections_opened_total: CounterVec, + distinct_peers_connections_closed_total: Counter, + distinct_peers_connections_opened_total: Counter, import_queue_blocks_submitted: Counter, import_queue_finality_proofs_submitted: Counter, import_queue_justifications_submitted: Counter, @@ -802,14 +1150,13 @@ struct Metrics { incoming_connections_total: Counter, is_major_syncing: Gauge, issued_light_requests: Counter, + kademlia_query_duration: HistogramVec, kademlia_random_queries_total: CounterVec, kademlia_records_count: GaugeVec, kademlia_records_sizes_total: GaugeVec, kbuckets_num_nodes: GaugeVec, listeners_local_addresses: Gauge, listeners_errors_total: Counter, - network_per_sec_bytes: GaugeVec, - notifications_queues_size: HistogramVec, notifications_sizes: HistogramVec, notifications_streams_closed_total: CounterVec, notifications_streams_opened_total: CounterVec, @@ -823,6 +1170,35 @@ struct Metrics { requests_out_started_total: CounterVec, } +/// The source for bandwidth metrics. +#[derive(Clone)] +struct BandwidthCounters(Arc); + +impl BandwidthCounters { + fn register(registry: &Registry, sinks: Arc) + -> Result<(), PrometheusError> + { + register(SourcedCounter::new( + &Opts::new( + "sub_libp2p_network_bytes_total", + "Total bandwidth usage" + ).variable_label("direction"), + BandwidthCounters(sinks), + )?, registry)?; + + Ok(()) + } +} + +impl MetricSource for BandwidthCounters { + type N = u64; + + fn collect(&self, mut set: impl FnMut(&[&str], Self::N)) { + set(&[&"in"], self.0.total_inbound()); + set(&[&"out"], self.0.total_outbound()); + } +} + impl Metrics { fn register(registry: &Registry) -> Result { Ok(Self { @@ -830,17 +1206,25 @@ impl Metrics { connections_closed_total: register(CounterVec::new( Opts::new( "sub_libp2p_connections_closed_total", - "Total number of connections closed, by reason and direction" + "Total number of connections closed, by direction and reason" ), &["direction", "reason"] )?, registry)?, connections_opened_total: register(CounterVec::new( Opts::new( "sub_libp2p_connections_opened_total", - "Total number of connections opened" + "Total number of connections opened by direction" ), &["direction"] )?, registry)?, + distinct_peers_connections_closed_total: register(Counter::new( + "sub_libp2p_distinct_peers_connections_closed_total", + "Total number of connections closed with distinct peers" + )?, registry)?, + distinct_peers_connections_opened_total: register(Counter::new( + "sub_libp2p_distinct_peers_connections_opened_total", + "Total number of connections opened with distinct peers" + )?, registry)?, import_queue_blocks_submitted: register(Counter::new( "import_queue_blocks_submitted", "Number of blocks submitted to the import queue.", @@ -872,6 +1256,17 @@ impl Metrics { "issued_light_requests", "Number of light client requests that our node has issued.", )?, registry)?, + kademlia_query_duration: register(HistogramVec::new( + HistogramOpts { + common_opts: Opts::new( + "sub_libp2p_kademlia_query_duration", + "Duration of Kademlia queries per query type" + ), + buckets: prometheus_endpoint::exponential_buckets(0.5, 2.0, 10) + .expect("parameters are always valid values; qed"), + }, + &["type"] + )?, registry)?, kademlia_random_queries_total: register(CounterVec::new( Opts::new( "sub_libp2p_kademlia_random_queries_total", @@ -907,23 +1302,6 @@ impl Metrics { "sub_libp2p_listeners_errors_total", "Total number of non-fatal errors reported by a listener" )?, registry)?, - network_per_sec_bytes: register(GaugeVec::new( - Opts::new( - "sub_libp2p_network_per_sec_bytes", - "Average bandwidth usage per second" - ), - &["direction"] - )?, registry)?, - notifications_queues_size: register(HistogramVec::new( - HistogramOpts { - common_opts: Opts::new( - "sub_libp2p_notifications_queues_size", - "Total size of all the notification queues" - ), - buckets: vec![0.0, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 511.0, 512.0], - }, - &["protocol"] - )?, registry)?, notifications_sizes: register(HistogramVec::new( HistogramOpts { common_opts: Opts::new( @@ -1000,31 +1378,10 @@ impl Metrics { )?, registry)?, }) } - - fn update_with_network_event(&self, event: &Event) { - match event { - Event::NotificationStreamOpened { engine_id, .. } => { - self.notifications_streams_opened_total - .with_label_values(&[&maybe_utf8_bytes_to_string(engine_id)]).inc(); - }, - Event::NotificationStreamClosed { engine_id, .. } => { - self.notifications_streams_closed_total - .with_label_values(&[&maybe_utf8_bytes_to_string(engine_id)]).inc(); - }, - Event::NotificationsReceived { messages, .. } => { - for (engine_id, message) in messages { - self.notifications_sizes - .with_label_values(&["in", &maybe_utf8_bytes_to_string(engine_id)]) - .observe(message.len() as f64); - } - }, - _ => {} - } - } } impl Future for NetworkWorker { - type Output = Result<(), io::Error>; + type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context) -> Poll { let this = &mut *self; @@ -1047,11 +1404,26 @@ impl Future for NetworkWorker { } } + // At the time of writing of this comment, due to a high volume of messages, the network + // worker sometimes takes a long time to process the loop below. When that happens, the + // rest of the polling is frozen. In order to avoid negative side-effects caused by this + // freeze, a limit to the number of iterations is enforced below. If the limit is reached, + // the task is interrupted then scheduled again. + // + // This allows for a more even distribution in the time taken by each sub-part of the + // polling. + let mut num_iterations = 0; loop { + num_iterations += 1; + if num_iterations >= 100 { + cx.waker().wake_by_ref(); + break; + } + // Process the next message coming from the `NetworkService`. - let msg = match this.from_worker.poll_next_unpin(cx) { + let msg = match this.from_service.poll_next_unpin(cx) { Poll::Ready(Some(msg)) => msg, - Poll::Ready(None) => return Poll::Ready(Ok(())), + Poll::Ready(None) => return Poll::Ready(()), Poll::Pending => break, }; @@ -1060,10 +1432,10 @@ impl Future for NetworkWorker { this.network_service.user_protocol_mut().announce_block(hash, data), ServiceToWorkerMsg::RequestJustification(hash, number) => this.network_service.user_protocol_mut().request_justification(&hash, number), - ServiceToWorkerMsg::PropagateExtrinsic(hash) => - this.network_service.user_protocol_mut().propagate_extrinsic(&hash), - ServiceToWorkerMsg::PropagateExtrinsics => - this.network_service.user_protocol_mut().propagate_extrinsics(), + ServiceToWorkerMsg::PropagateTransaction(hash) => + this.network_service.user_protocol_mut().propagate_transaction(&hash), + ServiceToWorkerMsg::PropagateTransactions => + this.network_service.user_protocol_mut().propagate_transactions(), ServiceToWorkerMsg::GetValue(key) => this.network_service.get_value(&key), ServiceToWorkerMsg::PutValue(key, value) => @@ -1074,24 +1446,29 @@ impl Future for NetworkWorker { this.network_service.user_protocol_mut().set_sync_fork_request(peer_ids, &hash, number), ServiceToWorkerMsg::EventStream(sender) => this.event_streams.push(sender), - ServiceToWorkerMsg::WriteNotification { message, engine_id, target } => { - if let Some(metrics) = this.metrics.as_ref() { - metrics.notifications_sizes - .with_label_values(&["out", &maybe_utf8_bytes_to_string(&engine_id)]) - .observe(message.len() as f64); - } - this.network_service.user_protocol_mut().write_notification(target, engine_id, message) - }, ServiceToWorkerMsg::RegisterNotifProtocol { engine_id, protocol_name } => { this.network_service .register_notifications_protocol(engine_id, protocol_name); }, ServiceToWorkerMsg::DisconnectPeer(who) => this.network_service.user_protocol_mut().disconnect_peer(&who), + ServiceToWorkerMsg::UpdateChain => + this.network_service.user_protocol_mut().update_chain(), + ServiceToWorkerMsg::OwnBlockImported(hash, number) => + this.network_service.user_protocol_mut().own_block_imported(hash, number), } } + // `num_iterations` serves the same purpose as in the previous loop. + // See the previous loop for explanations. + let mut num_iterations = 0; loop { + num_iterations += 1; + if num_iterations >= 1000 { + cx.waker().wake_by_ref(); + break; + } + // Process the next action coming from the network. let next_event = this.network_service.next_event(); futures::pin_mut!(next_event); @@ -1145,46 +1522,136 @@ impl Future for NetworkWorker { .inc(); } }, - Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::Event(ev))) => { + Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationStreamOpened { remote, engine_id, notifications_sink, role })) => { + if let Some(metrics) = this.metrics.as_ref() { + metrics.notifications_streams_opened_total + .with_label_values(&[&maybe_utf8_bytes_to_string(&engine_id)]).inc(); + } + { + let mut peers_notifications_sinks = this.peers_notifications_sinks.lock(); + peers_notifications_sinks.insert((remote.clone(), engine_id), notifications_sink); + } + this.event_streams.send(Event::NotificationStreamOpened { + remote, + engine_id, + role, + }); + }, + Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationStreamReplaced { remote, engine_id, notifications_sink })) => { + let mut peers_notifications_sinks = this.peers_notifications_sinks.lock(); + if let Some(s) = peers_notifications_sinks.get_mut(&(remote, engine_id)) { + *s = notifications_sink; + } else { + log::error!( + target: "sub-libp2p", + "NotificationStreamReplaced for non-existing substream" + ); + } + + // TODO: Notifications might have been lost as a result of the previous + // connection being dropped, and as a result it would be preferable to notify + // the users of this fact by simulating the substream being closed then + // reopened. + // The code below doesn't compile because `role` is unknown. Propagating the + // handshake of the secondary connections is quite an invasive change and + // would conflict with https://github.com/paritytech/substrate/issues/6403. + // Considering that dropping notifications is generally regarded as + // acceptable, this bug is at the moment intentionally left there and is + // intended to be fixed at the same time as + // https://github.com/paritytech/substrate/issues/6403. + /*this.event_streams.send(Event::NotificationStreamClosed { + remote, + engine_id, + }); + this.event_streams.send(Event::NotificationStreamOpened { + remote, + engine_id, + role, + });*/ + }, + Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationStreamClosed { remote, engine_id })) => { if let Some(metrics) = this.metrics.as_ref() { - metrics.update_with_network_event(&ev); + metrics.notifications_streams_closed_total + .with_label_values(&[&maybe_utf8_bytes_to_string(&engine_id[..])]).inc(); + } + this.event_streams.send(Event::NotificationStreamClosed { + remote: remote.clone(), + engine_id, + }); + { + let mut peers_notifications_sinks = this.peers_notifications_sinks.lock(); + peers_notifications_sinks.remove(&(remote.clone(), engine_id)); } - this.event_streams.send(ev); }, - Poll::Ready(SwarmEvent::ConnectionEstablished { peer_id, endpoint, .. }) => { + Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::NotificationsReceived { remote, messages })) => { + if let Some(metrics) = this.metrics.as_ref() { + for (engine_id, message) in &messages { + metrics.notifications_sizes + .with_label_values(&["in", &maybe_utf8_bytes_to_string(engine_id)]) + .observe(message.len() as f64); + } + } + this.event_streams.send(Event::NotificationsReceived { + remote, + messages, + }); + }, + Poll::Ready(SwarmEvent::Behaviour(BehaviourOut::Dht(event, duration))) => { + if let Some(metrics) = this.metrics.as_ref() { + let query_type = match event { + DhtEvent::ValueFound(_) => "value-found", + DhtEvent::ValueNotFound(_) => "value-not-found", + DhtEvent::ValuePut(_) => "value-put", + DhtEvent::ValuePutFailed(_) => "value-put-failed", + }; + metrics.kademlia_query_duration.with_label_values(&[query_type]) + .observe(duration.as_secs_f64()); + } + + this.event_streams.send(Event::Dht(event)); + }, + Poll::Ready(SwarmEvent::ConnectionEstablished { peer_id, endpoint, num_established }) => { trace!(target: "sub-libp2p", "Libp2p => Connected({:?})", peer_id); + if let Some(metrics) = this.metrics.as_ref() { - match endpoint { - ConnectedPoint::Dialer { .. } => - metrics.connections_opened_total.with_label_values(&["out"]).inc(), - ConnectedPoint::Listener { .. } => - metrics.connections_opened_total.with_label_values(&["in"]).inc(), + let direction = match endpoint { + ConnectedPoint::Dialer { .. } => "out", + ConnectedPoint::Listener { .. } => "in", + }; + metrics.connections_opened_total.with_label_values(&[direction]).inc(); + + if num_established.get() == 1 { + metrics.distinct_peers_connections_opened_total.inc(); } } }, - Poll::Ready(SwarmEvent::ConnectionClosed { peer_id, cause, endpoint, .. }) => { + Poll::Ready(SwarmEvent::ConnectionClosed { peer_id, cause, endpoint, num_established }) => { trace!(target: "sub-libp2p", "Libp2p => Disconnected({:?}, {:?})", peer_id, cause); if let Some(metrics) = this.metrics.as_ref() { - let dir = match endpoint { + let direction = match endpoint { ConnectedPoint::Dialer { .. } => "out", ConnectedPoint::Listener { .. } => "in", }; - - match cause { - ConnectionError::IO(_) => - metrics.connections_closed_total.with_label_values(&[dir, "transport-error"]).inc(), - ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( + let reason = match cause { + Some(ConnectionError::IO(_)) => "transport-error", + Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( EitherError::A(EitherError::A(EitherError::B( - EitherError::A(PingFailure::Timeout)))))))) => - metrics.connections_closed_total.with_label_values(&[dir, "ping-timeout"]).inc(), - ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( + EitherError::A(PingFailure::Timeout))))))))) => "ping-timeout", + Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( EitherError::A(EitherError::A(EitherError::A( - EitherError::B(LegacyConnectionKillError)))))))) => - metrics.connections_closed_total.with_label_values(&[dir, "force-closed"]).inc(), - ConnectionError::Handler(NodeHandlerWrapperError::Handler(_)) => - metrics.connections_closed_total.with_label_values(&[dir, "protocol-error"]).inc(), - ConnectionError::Handler(NodeHandlerWrapperError::KeepAliveTimeout) => - metrics.connections_closed_total.with_label_values(&[dir, "keep-alive-timeout"]).inc(), + NotifsHandlerError::Legacy(LegacyConnectionKillError))))))))) => "force-closed", + Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(EitherError::A(EitherError::A( + EitherError::A(EitherError::A(EitherError::A( + NotifsHandlerError::SyncNotificationsClogged)))))))) => "sync-notifications-clogged", + Some(ConnectionError::Handler(NodeHandlerWrapperError::Handler(_))) => "protocol-error", + Some(ConnectionError::Handler(NodeHandlerWrapperError::KeepAliveTimeout)) => "keep-alive-timeout", + None => "actively-closed", + }; + metrics.connections_closed_total.with_label_values(&[direction, reason]).inc(); + + // `num_established` represents the number of *remaining* connections. + if num_established == 0 { + metrics.distinct_peers_connections_closed_total.inc(); } } }, @@ -1195,7 +1662,7 @@ impl Future for NetworkWorker { } }, Poll::Ready(SwarmEvent::ExpiredListenAddr(addr)) => { - trace!(target: "sub-libp2p", "Libp2p => ExpiredListenAddr({})", addr); + info!(target: "sub-libp2p", "📪 No longer listening on {}", addr); if let Some(metrics) = this.metrics.as_ref() { metrics.listeners_local_addresses.dec(); } @@ -1263,10 +1730,23 @@ impl Future for NetworkWorker { trace!(target: "sub-libp2p", "Libp2p => UnknownPeerUnreachableAddr({}): {}", address, error), Poll::Ready(SwarmEvent::ListenerClosed { reason, addresses }) => { - warn!(target: "sub-libp2p", "Libp2p => ListenerClosed: {:?}", reason); if let Some(metrics) = this.metrics.as_ref() { metrics.listeners_local_addresses.sub(addresses.len() as u64); } + let addrs = addresses.into_iter().map(|a| a.to_string()) + .collect::>().join(", "); + match reason { + Ok(()) => error!( + target: "sub-libp2p", + "📪 Libp2p listener ({}) closed gracefully", + addrs + ), + Err(e) => error!( + target: "sub-libp2p", + "📪 Libp2p listener ({}) closed: {}", + addrs, e + ), + } }, Poll::Ready(SwarmEvent::ListenerError { error }) => { trace!(target: "sub-libp2p", "Libp2p => ListenerError: {}", error); @@ -1294,8 +1774,6 @@ impl Future for NetworkWorker { this.is_major_syncing.store(is_major_syncing, Ordering::Relaxed); if let Some(metrics) = this.metrics.as_ref() { - metrics.network_per_sec_bytes.with_label_values(&["in"]).set(this.service.bandwidth.average_download_per_sec()); - metrics.network_per_sec_bytes.with_label_values(&["out"]).set(this.service.bandwidth.average_upload_per_sec()); metrics.is_major_syncing.set(is_major_syncing as u64); for (proto, num_entries) in this.network_service.num_kbuckets_entries() { let proto = maybe_utf8_bytes_to_string(proto.as_bytes()); @@ -1348,7 +1826,7 @@ impl<'a, B: BlockT, H: ExHashT> Link for NetworkLink<'a, B, H> { count: usize, results: Vec<(Result>, BlockImportError>, B::Hash)> ) { - self.protocol.user_protocol_mut().blocks_processed(imported, count, results) + self.protocol.user_protocol_mut().on_blocks_processed(imported, count, results) } fn justification_imported(&mut self, who: PeerId, hash: &B::Hash, number: NumberFor, success: bool) { self.protocol.user_protocol_mut().justification_import_result(hash.clone(), number, success); @@ -1379,3 +1857,40 @@ impl<'a, B: BlockT, H: ExHashT> Link for NetworkLink<'a, B, H> { } } } + +fn ensure_addresses_consistent_with_transport<'a>( + addresses: impl Iterator, + transport: &TransportConfig, +) -> Result<(), Error> { + if matches!(transport, TransportConfig::MemoryOnly) { + let addresses: Vec<_> = addresses + .filter(|x| x.iter() + .any(|y| !matches!(y, libp2p::core::multiaddr::Protocol::Memory(_))) + ) + .cloned() + .collect(); + + if !addresses.is_empty() { + return Err(Error::AddressesForAnotherTransport { + transport: transport.clone(), + addresses, + }); + } + } else { + let addresses: Vec<_> = addresses + .filter(|x| x.iter() + .any(|y| matches!(y, libp2p::core::multiaddr::Protocol::Memory(_))) + ) + .cloned() + .collect(); + + if !addresses.is_empty() { + return Err(Error::AddressesForAnotherTransport { + transport: transport.clone(), + addresses, + }); + } + } + + Ok(()) +} diff --git a/client/network/src/service/out_events.rs b/client/network/src/service/out_events.rs index 2d4d7ded213e57578daf2433ec48c9e009470bb5..1b86a5fa4317d633c70f3dd4d97bf8146d9c81dd 100644 --- a/client/network/src/service/out_events.rs +++ b/client/network/src/service/out_events.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Registering events streams. //! @@ -33,7 +35,7 @@ use crate::Event; use super::maybe_utf8_bytes_to_string; -use futures::{prelude::*, channel::mpsc, ready}; +use futures::{prelude::*, channel::mpsc, ready, stream::FusedStream}; use parking_lot::Mutex; use prometheus_endpoint::{register, CounterVec, GaugeVec, Opts, PrometheusError, Registry, U64}; use std::{ @@ -117,8 +119,10 @@ impl fmt::Debug for Receiver { impl Drop for Receiver { fn drop(&mut self) { - // Empty the list to properly decrease the metrics. - while let Some(Some(_)) = self.next().now_or_never() {} + if !self.inner.is_terminated() { + // Empty the list to properly decrease the metrics. + while let Some(Some(_)) = self.next().now_or_never() {} + } } } diff --git a/client/network/src/service/tests.rs b/client/network/src/service/tests.rs index 3bed660851b1a663dd7a0bf15cb68f883400fb23..797942e1c249059fab576c56a35293a8798a2c40 100644 --- a/client/network/src/service/tests.rs +++ b/client/network/src/service/tests.rs @@ -1,21 +1,24 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::{config, Event, NetworkService, NetworkWorker}; +use libp2p::PeerId; use futures::prelude::*; use sp_runtime::traits::{Block as BlockT, Header as _}; use std::{sync::Arc, time::Duration}; @@ -85,7 +88,8 @@ fn build_test_full_node(config: config::NetworkConfiguration) Box::new(client.clone()), None, None, - &sp_core::testing::SpawnBlockingExecutor::new(), + &sp_core::testing::TaskExecutor::new(), + None, )); let worker = NetworkWorker::new(config::Params { @@ -100,7 +104,7 @@ fn build_test_full_node(config: config::NetworkConfiguration) protocol_id: config::ProtocolId::from(&b"/test-protocol-name"[..]), import_queue, block_announce_validator: Box::new( - sp_consensus::block_validation::DefaultBlockAnnounceValidator::new(client.clone()), + sp_consensus::block_validation::DefaultBlockAnnounceValidator, ), metrics_registry: None, }) @@ -135,6 +139,7 @@ fn build_nodes_one_proto() let (node2, events_stream2) = build_test_full_node(config::NetworkConfiguration { notifications_protocols: vec![(ENGINE_ID, From::from(&b"/foo"[..]))], + listen_addresses: vec![], reserved_nodes: vec![config::MultiaddrWithPeerId { multiaddr: listen_addr, peer_id: node1.local_peer_id().clone(), @@ -146,6 +151,7 @@ fn build_nodes_one_proto() (node1, events_stream1, node2, events_stream2) } +#[ignore] #[test] fn notifications_state_consistent() { // Runs two nodes and ensures that events are propagated out of the API in a consistent @@ -269,3 +275,240 @@ fn notifications_state_consistent() { } }); } + +#[test] +fn lots_of_incoming_peers_works() { + let listen_addr = config::build_multiaddr![Memory(rand::random::())]; + + let (main_node, _) = build_test_full_node(config::NetworkConfiguration { + notifications_protocols: vec![(ENGINE_ID, From::from(&b"/foo"[..]))], + listen_addresses: vec![listen_addr.clone()], + in_peers: u32::max_value(), + transport: config::TransportConfig::MemoryOnly, + .. config::NetworkConfiguration::new_local() + }); + + let main_node_peer_id = main_node.local_peer_id().clone(); + + // We spawn background tasks and push them in this `Vec`. They will all be waited upon before + // this test ends. + let mut background_tasks_to_wait = Vec::new(); + + for _ in 0..32 { + let main_node_peer_id = main_node_peer_id.clone(); + + let (_dialing_node, event_stream) = build_test_full_node(config::NetworkConfiguration { + notifications_protocols: vec![(ENGINE_ID, From::from(&b"/foo"[..]))], + listen_addresses: vec![], + reserved_nodes: vec![config::MultiaddrWithPeerId { + multiaddr: listen_addr.clone(), + peer_id: main_node_peer_id.clone(), + }], + transport: config::TransportConfig::MemoryOnly, + .. config::NetworkConfiguration::new_local() + }); + + background_tasks_to_wait.push(async_std::task::spawn(async move { + // Create a dummy timer that will "never" fire, and that will be overwritten when we + // actually need the timer. Using an Option would be technically cleaner, but it would + // make the code below way more complicated. + let mut timer = futures_timer::Delay::new(Duration::from_secs(3600 * 24 * 7)).fuse(); + + let mut event_stream = event_stream.fuse(); + loop { + futures::select! { + _ = timer => { + // Test succeeds when timer fires. + return; + } + ev = event_stream.next() => { + match ev.unwrap() { + Event::NotificationStreamOpened { remote, .. } => { + assert_eq!(remote, main_node_peer_id); + // Test succeeds after 5 seconds. This timer is here in order to + // detect a potential problem after opening. + timer = futures_timer::Delay::new(Duration::from_secs(5)).fuse(); + } + Event::NotificationStreamClosed { .. } => { + // Test failed. + panic!(); + } + _ => {} + } + } + } + } + })); + } + + futures::executor::block_on(async move { + future::join_all(background_tasks_to_wait).await + }); +} + +#[test] +fn notifications_back_pressure() { + // Node 1 floods node 2 with notifications. Random sleeps are done on node 2 to simulate the + // node being busy. We make sure that all notifications are received. + + const TOTAL_NOTIFS: usize = 10_000; + + let (node1, mut events_stream1, node2, mut events_stream2) = build_nodes_one_proto(); + let node2_id = node2.local_peer_id(); + + let receiver = async_std::task::spawn(async move { + let mut received_notifications = 0; + + while received_notifications < TOTAL_NOTIFS { + match events_stream2.next().await.unwrap() { + Event::NotificationStreamClosed { .. } => panic!(), + Event::NotificationsReceived { messages, .. } => { + for message in messages { + assert_eq!(message.0, ENGINE_ID); + assert_eq!(message.1, format!("hello #{}", received_notifications)); + received_notifications += 1; + } + } + _ => {} + }; + + if rand::random::() < 2 { + async_std::task::sleep(Duration::from_millis(rand::random::() % 750)).await; + } + } + }); + + async_std::task::block_on(async move { + // Wait for the `NotificationStreamOpened`. + loop { + match events_stream1.next().await.unwrap() { + Event::NotificationStreamOpened { .. } => break, + _ => {} + }; + } + + // Sending! + for num in 0..TOTAL_NOTIFS { + let notif = node1.notification_sender(node2_id.clone(), ENGINE_ID).unwrap(); + notif.ready().await.unwrap().send(format!("hello #{}", num)).unwrap(); + } + + receiver.await; + }); +} + +#[test] +#[should_panic(expected = "don't match the transport")] +fn ensure_listen_addresses_consistent_with_transport_memory() { + let listen_addr = config::build_multiaddr![Ip4([127, 0, 0, 1]), Tcp(0_u16)]; + + let _ = build_test_full_node(config::NetworkConfiguration { + listen_addresses: vec![listen_addr.clone()], + transport: config::TransportConfig::MemoryOnly, + .. config::NetworkConfiguration::new("test-node", "test-client", Default::default(), None) + }); +} + +#[test] +#[should_panic(expected = "don't match the transport")] +fn ensure_listen_addresses_consistent_with_transport_not_memory() { + let listen_addr = config::build_multiaddr![Memory(rand::random::())]; + + let _ = build_test_full_node(config::NetworkConfiguration { + listen_addresses: vec![listen_addr.clone()], + .. config::NetworkConfiguration::new("test-node", "test-client", Default::default(), None) + }); +} + +#[test] +#[should_panic(expected = "don't match the transport")] +fn ensure_boot_node_addresses_consistent_with_transport_memory() { + let listen_addr = config::build_multiaddr![Memory(rand::random::())]; + let boot_node = config::MultiaddrWithPeerId { + multiaddr: config::build_multiaddr![Ip4([127, 0, 0, 1]), Tcp(0_u16)], + peer_id: PeerId::random(), + }; + + let _ = build_test_full_node(config::NetworkConfiguration { + listen_addresses: vec![listen_addr.clone()], + transport: config::TransportConfig::MemoryOnly, + boot_nodes: vec![boot_node], + .. config::NetworkConfiguration::new("test-node", "test-client", Default::default(), None) + }); +} + +#[test] +#[should_panic(expected = "don't match the transport")] +fn ensure_boot_node_addresses_consistent_with_transport_not_memory() { + let listen_addr = config::build_multiaddr![Ip4([127, 0, 0, 1]), Tcp(0_u16)]; + let boot_node = config::MultiaddrWithPeerId { + multiaddr: config::build_multiaddr![Memory(rand::random::())], + peer_id: PeerId::random(), + }; + + let _ = build_test_full_node(config::NetworkConfiguration { + listen_addresses: vec![listen_addr.clone()], + boot_nodes: vec![boot_node], + .. config::NetworkConfiguration::new("test-node", "test-client", Default::default(), None) + }); +} + +#[test] +#[should_panic(expected = "don't match the transport")] +fn ensure_reserved_node_addresses_consistent_with_transport_memory() { + let listen_addr = config::build_multiaddr![Memory(rand::random::())]; + let reserved_node = config::MultiaddrWithPeerId { + multiaddr: config::build_multiaddr![Ip4([127, 0, 0, 1]), Tcp(0_u16)], + peer_id: PeerId::random(), + }; + + let _ = build_test_full_node(config::NetworkConfiguration { + listen_addresses: vec![listen_addr.clone()], + transport: config::TransportConfig::MemoryOnly, + reserved_nodes: vec![reserved_node], + .. config::NetworkConfiguration::new("test-node", "test-client", Default::default(), None) + }); +} + +#[test] +#[should_panic(expected = "don't match the transport")] +fn ensure_reserved_node_addresses_consistent_with_transport_not_memory() { + let listen_addr = config::build_multiaddr![Ip4([127, 0, 0, 1]), Tcp(0_u16)]; + let reserved_node = config::MultiaddrWithPeerId { + multiaddr: config::build_multiaddr![Memory(rand::random::())], + peer_id: PeerId::random(), + }; + + let _ = build_test_full_node(config::NetworkConfiguration { + listen_addresses: vec![listen_addr.clone()], + reserved_nodes: vec![reserved_node], + .. config::NetworkConfiguration::new("test-node", "test-client", Default::default(), None) + }); +} + +#[test] +#[should_panic(expected = "don't match the transport")] +fn ensure_public_addresses_consistent_with_transport_memory() { + let listen_addr = config::build_multiaddr![Memory(rand::random::())]; + let public_address = config::build_multiaddr![Ip4([127, 0, 0, 1]), Tcp(0_u16)]; + + let _ = build_test_full_node(config::NetworkConfiguration { + listen_addresses: vec![listen_addr.clone()], + transport: config::TransportConfig::MemoryOnly, + public_addresses: vec![public_address], + .. config::NetworkConfiguration::new("test-node", "test-client", Default::default(), None) + }); +} + +#[test] +#[should_panic(expected = "don't match the transport")] +fn ensure_public_addresses_consistent_with_transport_not_memory() { + let listen_addr = config::build_multiaddr![Ip4([127, 0, 0, 1]), Tcp(0_u16)]; + let public_address = config::build_multiaddr![Memory(rand::random::())]; + + let _ = build_test_full_node(config::NetworkConfiguration { + listen_addresses: vec![listen_addr.clone()], + public_addresses: vec![public_address], + .. config::NetworkConfiguration::new("test-node", "test-client", Default::default(), None) + }); +} diff --git a/client/network/src/transport.rs b/client/network/src/transport.rs index 75ee2d5db89b9c64569c23a70c7384080819ef36..e8836c4c269a525b04ed08c78e504ec51f03cb95 100644 --- a/client/network/src/transport.rs +++ b/client/network/src/transport.rs @@ -1,28 +1,33 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use futures::prelude::*; use libp2p::{ InboundUpgradeExt, OutboundUpgradeExt, PeerId, Transport, + core::{ + self, either::{EitherError, EitherOutput}, muxing::StreamMuxerBox, + transport::{boxed::Boxed, OptionalTransport}, upgrade + }, mplex, identity, bandwidth, wasm_ext, noise }; #[cfg(not(target_os = "unknown"))] use libp2p::{tcp, dns, websocket}; -use libp2p::core::{self, upgrade, transport::boxed::Boxed, transport::OptionalTransport, muxing::StreamMuxerBox}; -use std::{io, sync::Arc, time::Duration, usize}; +use std::{io, sync::Arc, time::Duration}; pub use self::bandwidth::BandwidthSinks; @@ -38,17 +43,31 @@ pub fn build_transport( memory_only: bool, wasm_external_transport: Option, use_yamux_flow_control: bool -) -> (Boxed<(PeerId, StreamMuxerBox), io::Error>, Arc) { +) -> (Boxed<(PeerId, StreamMuxerBox), io::Error>, Arc) { + // Legacy noise configurations for backward compatibility. + let mut noise_legacy = noise::LegacyConfig::default(); + noise_legacy.send_legacy_handshake = true; + // Build configuration objects for encryption mechanisms. let noise_config = { - let noise_keypair = noise::Keypair::new().into_authentic(&keypair) - // For more information about this panic, see in "On the Importance of Checking - // Cryptographic Protocols for Faults" by Dan Boneh, Richard A. DeMillo, - // and Richard J. Lipton. + // For more information about these two panics, see in "On the Importance of + // Checking Cryptographic Protocols for Faults" by Dan Boneh, Richard A. DeMillo, + // and Richard J. Lipton. + let noise_keypair_legacy = noise::Keypair::::new().into_authentic(&keypair) + .expect("can only fail in case of a hardware bug; since this signing is performed only \ + once and at initialization, we're taking the bet that the inconvenience of a very \ + rare panic here is basically zero"); + let noise_keypair_spec = noise::Keypair::::new().into_authentic(&keypair) .expect("can only fail in case of a hardware bug; since this signing is performed only \ once and at initialization, we're taking the bet that the inconvenience of a very \ rare panic here is basically zero"); - noise::NoiseConfig::ix(noise_keypair) + + let mut xx_config = noise::NoiseConfig::xx(noise_keypair_spec); + xx_config.set_legacy_config(noise_legacy.clone()); + let mut ix_config = noise::NoiseConfig::ix(noise_keypair_legacy); + ix_config.set_legacy_config(noise_legacy); + + core::upgrade::SelectUpgrade::new(xx_config, ix_config) }; // Build configuration objects for multiplexing mechanisms. @@ -91,16 +110,27 @@ pub fn build_transport( OptionalTransport::none() }); - let (transport, sinks) = bandwidth::BandwidthLogging::new(transport, Duration::from_secs(5)); + let (transport, bandwidth) = bandwidth::BandwidthLogging::new(transport); // Encryption let transport = transport.and_then(move |stream, endpoint| { core::upgrade::apply(stream, noise_config, endpoint, upgrade::Version::V1) - .and_then(|(remote_id, out)| async move { - let remote_key = match remote_id { - noise::RemoteIdentity::IdentityKey(key) => key, + .map_err(|err| + err.map_err(|err| match err { + EitherError::A(err) => err, + EitherError::B(err) => err, + }) + ) + .and_then(|result| async move { + let remote_key = match &result { + EitherOutput::First((noise::RemoteIdentity::IdentityKey(key), _)) => key.clone(), + EitherOutput::Second((noise::RemoteIdentity::IdentityKey(key), _)) => key.clone(), _ => return Err(upgrade::UpgradeError::Apply(noise::NoiseError::InvalidKey)) }; + let out = match result { + EitherOutput::First((_, o)) => o, + EitherOutput::Second((_, o)) => o, + }; Ok((out, remote_key.into_peer_id())) }) }); @@ -121,5 +151,6 @@ pub fn build_transport( .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) .boxed(); - (transport, sinks) + (transport, bandwidth) } + diff --git a/client/network/src/utils.rs b/client/network/src/utils.rs index f13505d0124db8f08de09dd16c9499d2164c69d9..490e2ced3826676e9384e141b72a54b87f9cb2ea 100644 --- a/client/network/src/utils.rs +++ b/client/network/src/utils.rs @@ -14,12 +14,74 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use std::time::Duration; -use futures::{FutureExt, Stream, StreamExt, stream::unfold}; +use futures::{stream::unfold, FutureExt, Stream, StreamExt}; use futures_timer::Delay; +use linked_hash_set::LinkedHashSet; +use std::time::Duration; +use std::{hash::Hash, num::NonZeroUsize}; + +/// Creates a stream that returns a new value every `duration`. +pub fn interval(duration: Duration) -> impl Stream + Unpin { + unfold((), move |_| Delay::new(duration).map(|_| Some(((), ())))).map(drop) +} + +/// Wrapper around `LinkedHashSet` with bounded growth. +/// +/// In the limit, for each element inserted the oldest existing element will be removed. +#[derive(Debug, Clone)] +pub struct LruHashSet { + set: LinkedHashSet, + limit: NonZeroUsize, +} + +impl LruHashSet { + /// Create a new `LruHashSet` with the given (exclusive) limit. + pub fn new(limit: NonZeroUsize) -> Self { + Self { + set: LinkedHashSet::new(), + limit, + } + } + + /// Insert element into the set. + /// + /// Returns `true` if this is a new element to the set, `false` otherwise. + /// Maintains the limit of the set by removing the oldest entry if necessary. + /// Inserting the same element will update its LRU position. + pub fn insert(&mut self, e: T) -> bool { + if self.set.insert(e) { + if self.set.len() == usize::from(self.limit) { + self.set.pop_front(); // remove oldest entry + } + return true; + } + false + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn maintains_limit() { + let three = NonZeroUsize::new(3).unwrap(); + let mut set = LruHashSet::::new(three); + + // First element. + assert!(set.insert(1)); + assert_eq!(vec![&1], set.set.iter().collect::>()); + + // Second element. + assert!(set.insert(2)); + assert_eq!(vec![&1, &2], set.set.iter().collect::>()); + + // Inserting the same element updates its LRU position. + assert!(!set.insert(1)); + assert_eq!(vec![&2, &1], set.set.iter().collect::>()); -pub fn interval(duration: Duration) -> impl Stream + Unpin { - unfold((), move |_| { - Delay::new(duration).map(|_| Some(((), ()))) - }).map(drop) + // We reached the limit. The next element forces the oldest one out. + assert!(set.insert(3)); + assert_eq!(vec![&1, &3], set.set.iter().collect::>()); + } } diff --git a/client/network/test/Cargo.toml b/client/network/test/Cargo.toml index 154694c692adbb786c397529bf397509cee9bc08..7f3f535ebbd8a3e8e0bf840c73015299287a0137 100644 --- a/client/network/test/Cargo.toml +++ b/client/network/test/Cargo.toml @@ -1,8 +1,8 @@ [package] description = "Integration tests for Substrate network protocol" name = "sc-network-test" -version = "0.8.0-dev" -license = "GPL-3.0" +version = "0.8.0-rc6" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" authors = ["Parity Technologies "] edition = "2018" publish = false @@ -13,23 +13,23 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-network = { version = "0.8.0-dev", path = "../" } +sc-network = { version = "0.8.0-rc6", path = "../" } log = "0.4.8" parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" rand = "0.7.2" -libp2p = { version = "0.18.1", default-features = false, features = ["libp2p-websocket"] } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -sc-consensus = { version = "0.8.0-dev", path = "../../../client/consensus/common" } -sc-client-api = { version = "2.0.0-dev", path = "../../api" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sc-block-builder = { version = "0.8.0-dev", path = "../../block-builder" } -sp-consensus-babe = { version = "0.8.0-dev", path = "../../../primitives/consensus/babe" } +libp2p = { version = "0.24.0", default-features = false } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sc-consensus = { version = "0.8.0-rc6", path = "../../../client/consensus/common" } +sc-client-api = { version = "2.0.0-rc6", path = "../../api" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sc-block-builder = { version = "0.8.0-rc6", path = "../../block-builder" } +sp-consensus-babe = { version = "0.8.0-rc6", path = "../../../primitives/consensus/babe" } env_logger = "0.7.0" -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -substrate-test-runtime = { version = "2.0.0-dev", path = "../../../test-utils/runtime" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../test-utils/runtime/client" } +substrate-test-runtime = { version = "2.0.0-rc6", path = "../../../test-utils/runtime" } tempfile = "3.1.0" -sc-service = { version = "0.8.0-dev", default-features = false, features = ["test-helpers"], path = "../../service" } +sc-service = { version = "0.8.0-rc6", default-features = false, features = ["test-helpers"], path = "../../service" } diff --git a/client/network/test/src/block_import.rs b/client/network/test/src/block_import.rs index a77dec629b28256ad59f58e647cb6b122f0f7997..1d2cd3d687de92f5f90a4c8e8d729b1e9460e5b9 100644 --- a/client/network/test/src/block_import.rs +++ b/client/network/test/src/block_import.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Testing block import logic. @@ -53,7 +55,12 @@ fn import_single_good_block_works() { let mut expected_aux = ImportedAux::default(); expected_aux.is_new_best = true; - match import_single_block(&mut substrate_test_runtime_client::new(), BlockOrigin::File, block, &mut PassThroughVerifier(true)) { + match import_single_block( + &mut substrate_test_runtime_client::new(), + BlockOrigin::File, + block, + &mut PassThroughVerifier::new(true) + ) { Ok(BlockImportResult::ImportedUnknown(ref num, ref aux, ref org)) if *num == number && *aux == expected_aux && *org == Some(peer_id) => {} r @ _ => panic!("{:?}", r) @@ -63,7 +70,12 @@ fn import_single_good_block_works() { #[test] fn import_single_good_known_block_is_ignored() { let (mut client, _hash, number, _, block) = prepare_good_block(); - match import_single_block(&mut client, BlockOrigin::File, block, &mut PassThroughVerifier(true)) { + match import_single_block( + &mut client, + BlockOrigin::File, + block, + &mut PassThroughVerifier::new(true) + ) { Ok(BlockImportResult::ImportedKnown(ref n)) if *n == number => {} _ => panic!() } @@ -73,7 +85,12 @@ fn import_single_good_known_block_is_ignored() { fn import_single_good_block_without_header_fails() { let (_, _, _, peer_id, mut block) = prepare_good_block(); block.header = None; - match import_single_block(&mut substrate_test_runtime_client::new(), BlockOrigin::File, block, &mut PassThroughVerifier(true)) { + match import_single_block( + &mut substrate_test_runtime_client::new(), + BlockOrigin::File, + block, + &mut PassThroughVerifier::new(true) + ) { Err(BlockImportError::IncompleteHeader(ref org)) if *org == Some(peer_id) => {} _ => panic!() } @@ -81,10 +98,10 @@ fn import_single_good_block_without_header_fails() { #[test] fn async_import_queue_drops() { - let executor = sp_core::testing::SpawnBlockingExecutor::new(); + let executor = sp_core::testing::TaskExecutor::new(); // Perform this test multiple times since it exhibits non-deterministic behavior. for _ in 0..100 { - let verifier = PassThroughVerifier(true); + let verifier = PassThroughVerifier::new(true); let queue = BasicQueue::new( verifier, @@ -92,6 +109,7 @@ fn async_import_queue_drops() { None, None, &executor, + None, ); drop(queue); } diff --git a/client/network/test/src/lib.rs b/client/network/test/src/lib.rs index 999c99f64a1d4acf400359650542ba0ea28c8285..35587cbdc08b3d609ad63a648714d446982a34eb 100644 --- a/client/network/test/src/lib.rs +++ b/client/network/test/src/lib.rs @@ -1,19 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - +// along with this program. If not, see . #![allow(missing_docs)] #[cfg(test)] @@ -38,7 +39,7 @@ use sc_client_api::{ use sc_consensus::LongestChain; use sc_block_builder::{BlockBuilder, BlockBuilderProvider}; use sc_network::config::Role; -use sp_consensus::block_validation::DefaultBlockAnnounceValidator; +use sp_consensus::block_validation::{DefaultBlockAnnounceValidator, BlockAnnounceValidator}; use sp_consensus::import_queue::{ BasicQueue, BoxJustificationImport, Verifier, BoxFinalityProofImport, }; @@ -66,7 +67,33 @@ type AuthorityId = sp_consensus_babe::AuthorityId; /// A Verifier that accepts all blocks and passes them on with the configured /// finality to be imported. #[derive(Clone)] -pub struct PassThroughVerifier(pub bool); +pub struct PassThroughVerifier { + finalized: bool, + fork_choice: ForkChoiceStrategy, +} + +impl PassThroughVerifier { + /// Create a new instance. + /// + /// Every verified block will use `finalized` for the `BlockImportParams`. + pub fn new(finalized: bool) -> Self { + Self { + finalized, + fork_choice: ForkChoiceStrategy::LongestChain, + } + } + + /// Create a new instance. + /// + /// Every verified block will use `finalized` for the `BlockImportParams` and + /// the given [`ForkChoiceStrategy`]. + pub fn new_with_fork_choice(finalized: bool, fork_choice: ForkChoiceStrategy) -> Self { + Self { + finalized, + fork_choice, + } + } +} /// This `Verifier` accepts all data as valid. impl Verifier for PassThroughVerifier { @@ -84,9 +111,9 @@ impl Verifier for PassThroughVerifier { .map(|blob| vec![(well_known_cache_keys::AUTHORITIES, blob.to_vec())]); let mut import = BlockImportParams::new(origin, header); import.body = body; - import.finalized = self.0; + import.finalized = self.finalized; import.justification = justification; - import.fork_choice = Some(ForkChoiceStrategy::LongestChain); + import.fork_choice = Some(self.fork_choice.clone()); Ok((import, maybe_keys)) } @@ -220,9 +247,9 @@ impl Peer { self.network.num_connected_peers() } - /// Returns the number of processed blocks. - pub fn num_processed_blocks(&self) -> usize { - self.network.num_processed_blocks() + /// Returns the number of downloaded blocks. + pub fn num_downloaded_blocks(&self) -> usize { + self.network.num_downloaded_blocks() } /// Returns true if we have no peer. @@ -293,12 +320,13 @@ impl Peer { } else { Default::default() }; + self.block_import.import_block(import_block, cache).expect("block_import failed"); - self.network.on_block_imported(header, true); self.network.service().announce_block(hash, Vec::new()); at = hash; } + self.network.update_chain(); self.network.service().announce_block(at.clone(), Vec::new()); at } @@ -518,6 +546,15 @@ impl VerifierAdapter { } } +/// Configuration for a full peer. +#[derive(Default)] +pub struct FullPeerConfig { + /// Pruning window size. + pub keep_blocks: Option, + /// Block announce validator. + pub block_announce_validator: Option + Send + Sync>>, +} + pub trait TestNetFactory: Sized { type Verifier: 'static + Verifier; type PeerData: Default; @@ -578,12 +615,12 @@ pub trait TestNetFactory: Sized { } fn add_full_peer(&mut self) { - self.add_full_peer_with_states(None) + self.add_full_peer_with_config(Default::default()) } /// Add a full peer. - fn add_full_peer_with_states(&mut self, keep_blocks: Option) { - let test_client_builder = match keep_blocks { + fn add_full_peer_with_config(&mut self, config: FullPeerConfig) { + let test_client_builder = match config.keep_blocks { Some(keep_blocks) => TestClientBuilder::with_pruning_window(keep_blocks), None => TestClientBuilder::with_default_backend(), }; @@ -611,7 +648,8 @@ pub trait TestNetFactory: Sized { Box::new(block_import.clone()), justification_import, finality_proof_import, - &sp_core::testing::SpawnBlockingExecutor::new(), + &sp_core::testing::TaskExecutor::new(), + None, )); let listen_addr = build_multiaddr![Memory(rand::random::())]; @@ -639,7 +677,8 @@ pub trait TestNetFactory: Sized { transaction_pool: Arc::new(EmptyTransactionPool), protocol_id: ProtocolId::from(&b"test-protocol-name"[..]), import_queue, - block_announce_validator: Box::new(DefaultBlockAnnounceValidator::new(client.clone())), + block_announce_validator: config.block_announce_validator + .unwrap_or_else(|| Box::new(DefaultBlockAnnounceValidator)), metrics_registry: None, }).unwrap(); @@ -689,7 +728,8 @@ pub trait TestNetFactory: Sized { Box::new(block_import.clone()), justification_import, finality_proof_import, - &sp_core::testing::SpawnBlockingExecutor::new(), + &sp_core::testing::TaskExecutor::new(), + None, )); let listen_addr = build_multiaddr![Memory(rand::random::())]; @@ -717,7 +757,7 @@ pub trait TestNetFactory: Sized { transaction_pool: Arc::new(EmptyTransactionPool), protocol_id: ProtocolId::from(&b"test-protocol-name"[..]), import_queue, - block_announce_validator: Box::new(DefaultBlockAnnounceValidator::new(client.clone())), + block_announce_validator: Box::new(DefaultBlockAnnounceValidator), metrics_registry: None, }).unwrap(); @@ -784,6 +824,20 @@ pub trait TestNetFactory: Sized { Poll::Ready(()) } + /// Polls the testnet until all peers are connected to each other. + /// + /// Must be executed in a task context. + fn poll_until_connected(&mut self, cx: &mut FutureContext) -> Poll<()> { + self.poll(cx); + + let num_peers = self.peers().len(); + if self.peers().iter().all(|p| p.num_peers() == num_peers - 1) { + return Poll::Ready(()) + } + + Poll::Pending + } + /// Blocks the current thread until we are sync'ed. /// /// Calls `poll_until_sync` repeatedly. @@ -798,22 +852,27 @@ pub trait TestNetFactory: Sized { futures::executor::block_on(futures::future::poll_fn::<(), _>(|cx| self.poll_until_idle(cx))); } - /// Polls the testnet. Processes all the pending actions and returns `NotReady`. + /// Blocks the current thread until all peers are connected to each other. + /// + /// Calls `poll_until_connected` repeatedly with the runtime passed as parameter. + fn block_until_connected(&mut self) { + futures::executor::block_on( + futures::future::poll_fn::<(), _>(|cx| self.poll_until_connected(cx)), + ); + } + + /// Polls the testnet. Processes all the pending actions. fn poll(&mut self, cx: &mut FutureContext) { self.mut_peers(|peers| { for peer in peers { trace!(target: "sync", "-- Polling {}", peer.id()); - if let Poll::Ready(res) = Pin::new(&mut peer.network).poll(cx) { - res.unwrap(); + if let Poll::Ready(()) = peer.network.poll_unpin(cx) { + panic!("NetworkWorker has terminated unexpectedly.") } trace!(target: "sync", "-- Polling complete {}", peer.id()); // We poll `imported_blocks_stream`. while let Poll::Ready(Some(notification)) = peer.imported_blocks_stream.as_mut().poll_next(cx) { - peer.network.on_block_imported( - notification.header, - true, - ); peer.network.service().announce_block(notification.hash, Vec::new()); } @@ -832,6 +891,17 @@ pub trait TestNetFactory: Sized { pub struct TestNet { peers: Vec>, + fork_choice: ForkChoiceStrategy, +} + +impl TestNet { + /// Create a `TestNet` that used the given fork choice rule. + pub fn with_fork_choice(fork_choice: ForkChoiceStrategy) -> Self { + Self { + peers: Vec::new(), + fork_choice, + } + } } impl TestNetFactory for TestNet { @@ -842,13 +912,14 @@ impl TestNetFactory for TestNet { fn from_config(_config: &ProtocolConfig) -> Self { TestNet { peers: Vec::new(), + fork_choice: ForkChoiceStrategy::LongestChain, } } fn make_verifier(&self, _client: PeersClient, _config: &ProtocolConfig, _peer_data: &()) -> Self::Verifier { - PassThroughVerifier(false) + PassThroughVerifier::new_with_fork_choice(false, self.fork_choice.clone()) } fn peer(&mut self, i: usize) -> &mut Peer<()> { diff --git a/client/network/test/src/sync.rs b/client/network/test/src/sync.rs index 60e9e558c5fffafd0863ce47202b6129d8e2dd47..1cf2a8fee37982495811a2bd464bb0eb5644b728 100644 --- a/client/network/test/src/sync.rs +++ b/client/network/test/src/sync.rs @@ -1,23 +1,27 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use sp_consensus::BlockOrigin; use std::time::Duration; use futures::executor::block_on; use super::*; +use sp_consensus::block_validation::Validation; +use substrate_test_runtime::Header; fn test_ancestor_search_when_common_is(n: usize) { let _ = ::env_logger::try_init(); @@ -580,10 +584,10 @@ fn can_sync_explicit_forks() { #[test] fn syncs_header_only_forks() { - let _ = ::env_logger::try_init(); + let _ = env_logger::try_init(); let mut net = TestNet::new(0); - net.add_full_peer_with_states(None); - net.add_full_peer_with_states(Some(3)); + net.add_full_peer_with_config(Default::default()); + net.add_full_peer_with_config(FullPeerConfig { keep_blocks: Some(3), ..Default::default() }); net.peer(0).push_blocks(2, false); net.peer(1).push_blocks(2, false); @@ -671,17 +675,17 @@ fn imports_stale_once() { // check that NEW block is imported from announce message let new_hash = net.peer(0).push_blocks(1, false); import_with_announce(&mut net, new_hash); - assert_eq!(net.peer(1).num_processed_blocks(), 1); + assert_eq!(net.peer(1).num_downloaded_blocks(), 1); // check that KNOWN STALE block is imported from announce message let known_stale_hash = net.peer(0).push_blocks_at(BlockId::Number(0), 1, true); import_with_announce(&mut net, known_stale_hash); - assert_eq!(net.peer(1).num_processed_blocks(), 2); + assert_eq!(net.peer(1).num_downloaded_blocks(), 2); } #[test] fn can_sync_to_peers_with_wrong_common_block() { - let _ = ::env_logger::try_init(); + let _ = env_logger::try_init(); let mut net = TestNet::new(2); net.peer(0).push_blocks(2, true); @@ -708,3 +712,41 @@ fn can_sync_to_peers_with_wrong_common_block() { assert!(net.peer(1).client().header(&BlockId::Hash(final_hash)).unwrap().is_some()); } +/// Returns `is_new_best = true` for each validated announcement. +struct NewBestBlockAnnounceValidator; + +impl BlockAnnounceValidator for NewBestBlockAnnounceValidator { + fn validate( + &mut self, + _: &Header, + _: &[u8], + ) -> Result> { + Ok(Validation::Success { is_new_best: true }) + } +} + +#[test] +fn sync_blocks_when_block_announce_validator_says_it_is_new_best() { + let _ = env_logger::try_init(); + log::trace!(target: "sync", "Test"); + let mut net = TestNet::with_fork_choice(ForkChoiceStrategy::Custom(false)); + net.add_full_peer_with_config(Default::default()); + net.add_full_peer_with_config(Default::default()); + net.add_full_peer_with_config(FullPeerConfig { + block_announce_validator: Some(Box::new(NewBestBlockAnnounceValidator)), + ..Default::default() + }); + + net.block_until_connected(); + + let block_hash = net.peer(0).push_blocks(1, false); + + while !net.peer(2).has_block(&block_hash) { + net.block_until_idle(); + } + + // Peer1 should not have the block, because peer 0 did not reported the block + // as new best. However, peer2 has a special block announcement validator + // that flags all blocks as `is_new_best` and thus, it should have synced the blocks. + assert!(!net.peer(1).has_block(&block_hash)); +} diff --git a/client/offchain/Cargo.toml b/client/offchain/Cargo.toml index ac3a71ad0d9c8f89745817d926481b71cecba196..9f574ff9ebe46ded8789deae66269e903ad08e60 100644 --- a/client/offchain/Cargo.toml +++ b/client/offchain/Cargo.toml @@ -1,8 +1,8 @@ [package] description = "Substrate offchain workers" name = "sc-offchain" -version = "2.0.0-dev" -license = "GPL-3.0" +version = "2.0.0-rc6" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" authors = ["Parity Technologies "] edition = "2018" homepage = "https://substrate.dev" @@ -13,36 +13,36 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] bytes = "0.5" -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } fnv = "1.0.6" futures = "0.3.4" futures-timer = "3.0.1" log = "0.4.8" threadpool = "1.7" num_cpus = "1.10" -sp-offchain = { version = "2.0.0-dev", path = "../../primitives/offchain" } -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } +sp-offchain = { version = "2.0.0-rc6", path = "../../primitives/offchain" } +codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } parking_lot = "0.10.0" -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } rand = "0.7.2" -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } -sc-network = { version = "0.8.0-dev", path = "../network" } -sc-keystore = { version = "2.0.0-dev", path = "../keystore" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-rc6", path = "../../primitives/utils" } +sc-network = { version = "0.8.0-rc6", path = "../network" } +sc-keystore = { version = "2.0.0-rc6", path = "../keystore" } [target.'cfg(not(target_os = "unknown"))'.dependencies] hyper = "0.13.2" -hyper-rustls = "0.20" +hyper-rustls = "0.21.0" [dev-dependencies] env_logger = "0.7.0" -fdlimit = "0.1.4" -sc-client-db = { version = "0.8.0-dev", default-features = true, path = "../db/" } -sc-transaction-pool = { version = "2.0.0-dev", path = "../../client/transaction-pool" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } +sc-client-db = { version = "0.8.0-rc6", default-features = true, path = "../db/" } +sc-transaction-pool = { version = "2.0.0-rc6", path = "../../client/transaction-pool" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../primitives/transaction-pool" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client" } tokio = "0.2" +lazy_static = "1.4.0" [features] default = [] diff --git a/client/offchain/README.md b/client/offchain/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f7c097e8e0b2a9e3ac07bbf0a41359aadf4a758f --- /dev/null +++ b/client/offchain/README.md @@ -0,0 +1,18 @@ +Substrate offchain workers. + +The offchain workers is a special function of the runtime that +gets executed after block is imported. During execution +it's able to asynchronously submit extrinsics that will either +be propagated to other nodes or added to the next block +produced by the node as unsigned transactions. + +Offchain workers can be used for computation-heavy tasks +that are not feasible for execution during regular block processing. +It can either be tasks that no consensus is required for, +or some form of consensus over the data can be built on-chain +for instance via: +1. Challenge period for incorrect computations +2. Majority voting for results +3. etc + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/offchain/src/api.rs b/client/offchain/src/api.rs index 45a82d230c11a6dd6d6c8ce03635d1c49c6d7ce7..5287ac8251eebf056fae07672441b8420eb3955e 100644 --- a/client/offchain/src/api.rs +++ b/client/offchain/src/api.rs @@ -31,6 +31,7 @@ use sp_core::offchain::{ OpaqueNetworkState, OpaquePeerId, OpaqueMultiaddr, StorageKind, }; pub use sp_offchain::STORAGE_PREFIX; +pub use http::SharedClient; #[cfg(not(target_os = "unknown"))] mod http; @@ -100,6 +101,13 @@ impl OffchainExt for Api { } } + fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { + match kind { + StorageKind::PERSISTENT => self.db.remove(STORAGE_PREFIX, key), + StorageKind::LOCAL => unavailable_yet(LOCAL_DB), + } + } + fn local_storage_compare_and_set( &mut self, kind: StorageKind, @@ -253,8 +261,9 @@ impl AsyncApi { db: S, network_state: Arc, is_validator: bool, - ) -> (Api, AsyncApi) { - let (http_api, http_worker) = http::http(); + shared_client: SharedClient, + ) -> (Api, Self) { + let (http_api, http_worker) = http::http(shared_client); let api = Api { db, @@ -263,7 +272,7 @@ impl AsyncApi { http: http_api, }; - let async_api = AsyncApi { + let async_api = Self { http: Some(http_worker), }; @@ -301,11 +310,14 @@ mod tests { let _ = env_logger::try_init(); let db = LocalStorage::new_test(); let mock = Arc::new(MockNetworkStateInfo()); + let shared_client = SharedClient::new(); + AsyncApi::new( db, mock, false, + shared_client, ) } @@ -322,7 +334,7 @@ mod tests { // Compare. assert!(timestamp.unix_millis() > 0); - assert_eq!(timestamp.unix_millis(), d); + assert!(timestamp.unix_millis() >= d); } #[test] diff --git a/client/offchain/src/api/http.rs b/client/offchain/src/api/http.rs index a64fe0389706c1098eda9f1c2fbd2294843d7597..1f542b7c11e19b8bd76a39ec3c6555b5c716a866 100644 --- a/client/offchain/src/api/http.rs +++ b/client/offchain/src/api/http.rs @@ -31,11 +31,24 @@ use fnv::FnvHashMap; use futures::{prelude::*, future, channel::mpsc}; use log::error; use sp_core::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; -use std::{fmt, io::Read as _, mem, pin::Pin, task::Context, task::Poll}; +use std::{convert::TryFrom, fmt, io::Read as _, pin::Pin, task::{Context, Poll}}; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender, TracingUnboundedReceiver}; +use std::sync::Arc; +use hyper::{Client as HyperClient, Body, client}; +use hyper_rustls::HttpsConnector; + +/// Wrapper struct used for keeping the hyper_rustls client running. +#[derive(Clone)] +pub struct SharedClient(Arc, Body>>); + +impl SharedClient { + pub fn new() -> Self { + Self(Arc::new(HyperClient::builder().build(HttpsConnector::new()))) + } +} /// Creates a pair of [`HttpApi`] and [`HttpWorker`]. -pub fn http() -> (HttpApi, HttpWorker) { +pub fn http(shared_client: SharedClient) -> (HttpApi, HttpWorker) { let (to_worker, from_api) = tracing_unbounded("mpsc_ocw_to_worker"); let (to_api, from_worker) = tracing_unbounded("mpsc_ocw_to_api"); @@ -51,7 +64,7 @@ pub fn http() -> (HttpApi, HttpWorker) { let engine = HttpWorker { to_api, from_api, - http_client: hyper::Client::builder().build(hyper_rustls::HttpsConnector::new()), + http_client: shared_client.0, requests: Vec::new(), }; @@ -151,8 +164,8 @@ impl HttpApi { _ => return Err(()) }; - let name = hyper::header::HeaderName::from_bytes(name.as_bytes()).map_err(|_| ())?; - let value = hyper::header::HeaderValue::from_str(value).map_err(|_| ())?; + let name = hyper::header::HeaderName::try_from(name).map_err(drop)?; + let value = hyper::header::HeaderValue::try_from(value).map_err(drop)?; // Note that we're always appending headers and never replacing old values. // We assume here that the user knows what they're doing. request.headers_mut().append(name, value); @@ -185,7 +198,7 @@ impl HttpApi { future::MaybeDone::Done(Err(_)) => return Err(HttpError::IoError), future::MaybeDone::Future(_) | future::MaybeDone::Gone => { - debug_assert!(if let future::MaybeDone::Done(_) = deadline { true } else { false }); + debug_assert!(matches!(deadline, future::MaybeDone::Done(..))); return Err(HttpError::DeadlineReached) } }; @@ -347,7 +360,7 @@ impl HttpApi { if let future::MaybeDone::Done(msg) = next_msg { msg } else { - debug_assert!(if let future::MaybeDone::Done(_) = deadline { true } else { false }); + debug_assert!(matches!(deadline, future::MaybeDone::Done(..))); continue } }; @@ -551,7 +564,7 @@ pub struct HttpWorker { /// Used to receive messages from the `HttpApi`. from_api: TracingUnboundedReceiver, /// The engine that runs HTTP requests. - http_client: hyper::Client, hyper::Body>, + http_client: Arc, Body>>, /// HTTP requests that are being worked on by the engine. requests: Vec<(HttpRequestId, HttpWorkerRequest)>, } @@ -585,25 +598,21 @@ impl Future for HttpWorker { match request { HttpWorkerRequest::Dispatched(mut future) => { // Check for an HTTP response from the Internet. - let mut response = match Future::poll(Pin::new(&mut future), cx) { + let response = match Future::poll(Pin::new(&mut future), cx) { Poll::Pending => { me.requests.push((id, HttpWorkerRequest::Dispatched(future))); continue }, Poll::Ready(Ok(response)) => response, - Poll::Ready(Err(err)) => { - let _ = me.to_api.unbounded_send(WorkerToApi::Fail { - id, - error: err, - }); + Poll::Ready(Err(error)) => { + let _ = me.to_api.unbounded_send(WorkerToApi::Fail { id, error }); continue; // don't insert the request back } }; // We received a response! Decompose it into its parts. - let status_code = response.status(); - let headers = mem::replace(response.headers_mut(), hyper::HeaderMap::new()); - let body = response.into_body(); + let (head, body) = response.into_parts(); + let (status_code, headers) = (head.status, head.headers); let (body_tx, body_rx) = mpsc::channel(3); let _ = me.to_api.unbounded_send(WorkerToApi::Response { @@ -689,29 +698,29 @@ impl fmt::Debug for HttpWorkerRequest { mod tests { use core::convert::Infallible; use crate::api::timestamp; - use super::http; + use super::{http, SharedClient}; use sp_core::offchain::{HttpError, HttpRequestId, HttpRequestStatus, Duration}; + use futures::future; + use lazy_static::lazy_static; + + // Using lazy_static to avoid spawning lots of different SharedClients, + // as spawning a SharedClient is CPU-intensive and opens lots of fds. + lazy_static! { + static ref SHARED_CLIENT: SharedClient = SharedClient::new(); + } // Returns an `HttpApi` whose worker is ran in the background, and a `SocketAddr` to an HTTP // server that runs in the background as well. macro_rules! build_api_server { () => {{ - fn tokio_run(future: impl std::future::Future) { - let _ = tokio::runtime::Runtime::new().unwrap().block_on(future); - } - - // We spawn quite a bit of HTTP servers here due to how async API - // works for offchain workers, so be sure to raise the FD limit - // (particularly useful for macOS where the default soft limit may - // not be enough). - fdlimit::raise_fd_limit(); - - let (api, worker) = http(); - std::thread::spawn(move || tokio_run(worker)); + let hyper_client = SHARED_CLIENT.clone(); + let (api, worker) = http(hyper_client.clone()); let (addr_tx, addr_rx) = std::sync::mpsc::channel(); std::thread::spawn(move || { - tokio_run(async move { + let mut rt = tokio::runtime::Runtime::new().unwrap(); + let worker = rt.spawn(worker); + let server = rt.spawn(async move { let server = hyper::Server::bind(&"127.0.0.1:0".parse().unwrap()) .serve(hyper::service::make_service_fn(|_| { async move { Ok::<_, Infallible>(hyper::service::service_fn(move |_req| async move { @@ -721,8 +730,9 @@ mod tests { })) }})); let _ = addr_tx.send(server.local_addr()); - server.await + server.await.map_err(drop) }); + let _ = rt.block_on(future::join(worker, server)); }); (api, addr_rx.recv().unwrap()) }}; @@ -891,10 +901,10 @@ mod tests { #[test] fn response_headers_invalid_call() { let (mut api, addr) = build_api_server!(); - assert!(api.response_headers(HttpRequestId(0xdead)).is_empty()); + assert_eq!(api.response_headers(HttpRequestId(0xdead)), &[]); let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); - assert!(api.response_headers(id).is_empty()); + assert_eq!(api.response_headers(id), &[]); let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.request_write_body(id, &[], None).unwrap(); @@ -904,12 +914,12 @@ mod tests { let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); api.response_wait(&[id], None); - assert!(!api.response_headers(id).is_empty()); + assert_ne!(api.response_headers(id), &[]); let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); let mut buf = [0; 128]; while api.response_read_body(id, &mut buf, None).unwrap() != 0 {} - assert!(api.response_headers(id).is_empty()); + assert_eq!(api.response_headers(id), &[]); } #[test] @@ -917,11 +927,11 @@ mod tests { let (mut api, addr) = build_api_server!(); let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); - assert!(api.response_headers(id).is_empty()); + assert_eq!(api.response_headers(id), &[]); let id = api.request_start("POST", &format!("http://{}", addr)).unwrap(); api.request_add_header(id, "Foo", "Bar").unwrap(); - assert!(api.response_headers(id).is_empty()); + assert_eq!(api.response_headers(id), &[]); let id = api.request_start("GET", &format!("http://{}", addr)).unwrap(); api.request_add_header(id, "Foo", "Bar").unwrap(); @@ -930,7 +940,7 @@ mod tests { // where we haven't received any response yet. This test can theoretically fail if the // HTTP response comes back faster than the kernel schedules our thread, but that is highly // unlikely. - assert!(api.response_headers(id).is_empty()); + assert_eq!(api.response_headers(id), &[]); } #[test] diff --git a/client/offchain/src/api/http_dummy.rs b/client/offchain/src/api/http_dummy.rs index 5ff77a1068312bbc5da2f71d9c15a9dee7bd8380..1c83325c93b2095fe4bc5fca9c7dbfb4e48e3b2a 100644 --- a/client/offchain/src/api/http_dummy.rs +++ b/client/offchain/src/api/http_dummy.rs @@ -19,8 +19,18 @@ use sp_core::offchain::{HttpRequestId, Timestamp, HttpRequestStatus, HttpError}; use std::{future::Future, pin::Pin, task::Context, task::Poll}; +/// Wrapper struct (wrapping nothing in case of http_dummy) used for keeping the hyper_rustls client running. +#[derive(Clone)] +pub struct SharedClient; + +impl SharedClient { + pub fn new() -> Self { + Self + } +} + /// Creates a pair of [`HttpApi`] and [`HttpWorker`]. -pub fn http() -> (HttpApi, HttpWorker) { +pub fn http(_: SharedClient) -> (HttpApi, HttpWorker) { (HttpApi, HttpWorker) } diff --git a/client/offchain/src/api/timestamp.rs b/client/offchain/src/api/timestamp.rs index e5494fe70d784bca20917a38a530ef37c06b3393..222d3273cb355fa64ac4f52f8dcb568b69be25b8 100644 --- a/client/offchain/src/api/timestamp.rs +++ b/client/offchain/src/api/timestamp.rs @@ -51,12 +51,14 @@ pub fn timestamp_from_now(timestamp: Timestamp) -> Duration { pub fn deadline_to_future( deadline: Option, ) -> futures::future::MaybeDone { - use futures::future; + use futures::future::{self, Either}; - future::maybe_done(match deadline { - Some(deadline) => future::Either::Left( - futures_timer::Delay::new(timestamp_from_now(deadline)) - ), - None => future::Either::Right(future::pending()) + future::maybe_done(match deadline.map(timestamp_from_now) { + None => Either::Left(future::pending()), + // Only apply delay if we need to wait a non-zero duration + Some(duration) if duration <= Duration::from_secs(0) => + Either::Right(Either::Left(future::ready(()))), + Some(duration) => + Either::Right(Either::Right(futures_timer::Delay::new(duration))), }) } diff --git a/client/offchain/src/lib.rs b/client/offchain/src/lib.rs index 332e9f779a8e27f3e655238ed5a70510db21605a..3b17c14f19652198abba3267b1f7c4bc1060ba4f 100644 --- a/client/offchain/src/lib.rs +++ b/client/offchain/src/lib.rs @@ -19,7 +19,7 @@ //! The offchain workers is a special function of the runtime that //! gets executed after block is imported. During execution //! it's able to asynchronously submit extrinsics that will either -//! be propagated to other nodes added to the next block +//! be propagated to other nodes or added to the next block //! produced by the node as unsigned transactions. //! //! Offchain workers can be used for computation-heavy tasks @@ -41,10 +41,12 @@ use sp_api::{ApiExt, ProvideRuntimeApi}; use futures::future::Future; use log::{debug, warn}; use sc_network::NetworkStateInfo; -use sp_core::{offchain::{self, OffchainStorage}, ExecutionContext}; +use sp_core::{offchain::{self, OffchainStorage}, ExecutionContext, traits::SpawnNamed}; use sp_runtime::{generic::BlockId, traits::{self, Header}}; +use futures::{prelude::*, future::ready}; mod api; +use api::SharedClient; pub use sp_offchain::{OffchainWorkerApi, STORAGE_PREFIX}; @@ -54,16 +56,19 @@ pub struct OffchainWorkers { db: Storage, _block: PhantomData, thread_pool: Mutex, + shared_client: SharedClient, } impl OffchainWorkers { /// Creates new `OffchainWorkers`. pub fn new(client: Arc, db: Storage) -> Self { + let shared_client = SharedClient::new(); Self { client, db, _block: PhantomData, thread_pool: Mutex::new(ThreadPool::new(num_cpus::get())), + shared_client, } } } @@ -119,6 +124,7 @@ impl OffchainWorkers< self.db.clone(), network_state.clone(), is_validator, + self.shared_client.clone(), ); debug!("Spawning offchain workers at {:?}", at); let header = header.clone(); @@ -161,15 +167,51 @@ impl OffchainWorkers< } } +/// Inform the offchain worker about new imported blocks +pub async fn notification_future( + is_validator: bool, + client: Arc, + offchain: Arc>, + spawner: Spawner, + network_state_info: Arc, +) + where + Block: traits::Block, + Client: ProvideRuntimeApi + sc_client_api::BlockchainEvents + Send + Sync + 'static, + Client::Api: OffchainWorkerApi, + Storage: OffchainStorage + 'static, + Spawner: SpawnNamed +{ + client.import_notification_stream().for_each(move |n| { + if n.is_new_best { + spawner.spawn( + "offchain-on-block", + offchain.on_block_imported( + &n.header, + network_state_info.clone(), + is_validator, + ).boxed(), + ); + } else { + log::debug!( + target: "sc_offchain", + "Skipping offchain workers for non-canon block: {:?}", + n.header, + ) + } + + ready(()) + }).await; +} + #[cfg(test)] mod tests { use super::*; use std::sync::Arc; use sc_network::{Multiaddr, PeerId}; - use substrate_test_runtime_client::runtime::Block; + use substrate_test_runtime_client::{TestClient, runtime::Block}; use sc_transaction_pool::{BasicPool, FullChainApi}; use sp_transaction_pool::{TransactionPool, InPoolTransaction}; - use sc_client_api::ExecutorProvider; struct MockNetworkStateInfo(); @@ -183,7 +225,9 @@ mod tests { } } - struct TestPool(BasicPool, Block>); + struct TestPool( + Arc, Block>> + ); impl sp_transaction_pool::OffchainSubmitTransaction for TestPool { fn submit_at( @@ -200,16 +244,16 @@ mod tests { #[test] fn should_call_into_runtime_and_produce_extrinsic() { - // given let _ = env_logger::try_init(); + let client = Arc::new(substrate_test_runtime_client::new()); - let pool = Arc::new(TestPool(BasicPool::new( + let spawner = sp_core::testing::TaskExecutor::new(); + let pool = TestPool(BasicPool::new_full( Default::default(), - Arc::new(FullChainApi::new(client.clone())), None, - ).0)); - client.execution_extensions() - .register_transaction_pool(Arc::downgrade(&pool.clone()) as _); + spawner, + client.clone(), + )); let db = sc_client_db::offchain::LocalStorage::new_test(); let network_state = Arc::new(MockNetworkStateInfo()); let header = client.header(&BlockId::number(0)).unwrap().unwrap(); diff --git a/client/peerset/Cargo.toml b/client/peerset/Cargo.toml index d5aa08f2f4981203b4c94b8299b174c771b25459..5856abf4e7edb2239300eab0112464185291fb46 100644 --- a/client/peerset/Cargo.toml +++ b/client/peerset/Cargo.toml @@ -1,9 +1,9 @@ [package] description = "Connectivity manager based on reputation" homepage = "http://parity.io" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" name = "sc-peerset" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" repository = "https://github.com/paritytech/substrate/" @@ -15,8 +15,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = "0.3.4" -libp2p = { version = "0.18.1", default-features = false } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils"} +libp2p = { version = "0.24.0", default-features = false } +sp-utils = { version = "2.0.0-rc6", path = "../../primitives/utils"} log = "0.4.8" serde_json = "1.0.41" wasm-timer = "0.2" diff --git a/client/peerset/README.md b/client/peerset/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1b54c52001caf7b6767983445513fa3545fd26f4 --- /dev/null +++ b/client/peerset/README.md @@ -0,0 +1,4 @@ +Peer Set Manager (PSM). Contains the strategy for choosing which nodes the network should be +connected to. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/peerset/src/lib.rs b/client/peerset/src/lib.rs index 9376e9594b4b702dc3746661196065e4851c78b9..6f28dd036a3cc53408583be8cbe04e24af9a8448 100644 --- a/client/peerset/src/lib.rs +++ b/client/peerset/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Peer Set Manager (PSM). Contains the strategy for choosing which nodes the network should be //! connected to. @@ -180,9 +182,13 @@ pub struct PeersetConfig { /// errors. #[derive(Debug)] pub struct Peerset { + /// Underlying data structure for the nodes's states. data: peersstate::PeersState, /// If true, we only accept reserved nodes. reserved_only: bool, + /// Lists of nodes that don't occupy slots and that we should try to always be connected to. + /// Is kept in sync with the list of reserved nodes in [`Peerset::data`]. + priority_groups: HashMap>, /// Receiver for messages from the `PeersetHandle` and from `tx`. rx: TracingUnboundedReceiver, /// Sending side of `rx`. @@ -207,17 +213,18 @@ impl Peerset { let now = Instant::now(); let mut peerset = Peerset { - data: peersstate::PeersState::new(config.in_peers, config.out_peers, config.reserved_only), + data: peersstate::PeersState::new(config.in_peers, config.out_peers), tx, rx, reserved_only: config.reserved_only, + priority_groups: config.priority_groups.clone().into_iter().collect(), message_queue: VecDeque::new(), created: now, latest_time_update: now, }; - for (group, nodes) in config.priority_groups { - peerset.data.set_priority_group(&group, nodes); + for node in config.priority_groups.into_iter().flat_map(|(_, l)| l) { + peerset.data.add_no_slot_node(node); } for peer_id in config.bootnodes { @@ -233,61 +240,92 @@ impl Peerset { } fn on_add_reserved_peer(&mut self, peer_id: PeerId) { - let mut reserved = self.data.get_priority_group(RESERVED_NODES).unwrap_or_default(); - reserved.insert(peer_id); - self.data.set_priority_group(RESERVED_NODES, reserved); - self.alloc_slots(); + self.on_add_to_priority_group(RESERVED_NODES, peer_id); } fn on_remove_reserved_peer(&mut self, peer_id: PeerId) { - let mut reserved = self.data.get_priority_group(RESERVED_NODES).unwrap_or_default(); - reserved.remove(&peer_id); - self.data.set_priority_group(RESERVED_NODES, reserved); - match self.data.peer(&peer_id) { - peersstate::Peer::Connected(peer) => { - if self.reserved_only { - peer.disconnect(); - self.message_queue.push_back(Message::Drop(peer_id)); - } - } - peersstate::Peer::NotConnected(_) => {}, - peersstate::Peer::Unknown(_) => {}, - } + self.on_remove_from_priority_group(RESERVED_NODES, peer_id); } fn on_set_reserved_only(&mut self, reserved_only: bool) { self.reserved_only = reserved_only; - self.data.set_priority_only(reserved_only); if self.reserved_only { - // Disconnect non-reserved nodes. - let reserved = self.data.get_priority_group(RESERVED_NODES).unwrap_or_default(); + // Disconnect all the nodes that aren't reserved. for peer_id in self.data.connected_peers().cloned().collect::>().into_iter() { + if self.priority_groups.get(RESERVED_NODES).map_or(false, |g| g.contains(&peer_id)) { + continue; + } + let peer = self.data.peer(&peer_id).into_connected() .expect("We are enumerating connected peers, therefore the peer is connected; qed"); - if !reserved.contains(&peer_id) { - peer.disconnect(); - self.message_queue.push_back(Message::Drop(peer_id)); - } + peer.disconnect(); + self.message_queue.push_back(Message::Drop(peer_id)); } + } else { self.alloc_slots(); } } fn on_set_priority_group(&mut self, group_id: &str, peers: HashSet) { - self.data.set_priority_group(group_id, peers); - self.alloc_slots(); + // Determine the difference between the current group and the new list. + let (to_insert, to_remove) = { + let current_group = self.priority_groups.entry(group_id.to_owned()).or_default(); + let to_insert = peers.difference(current_group) + .cloned().collect::>(); + let to_remove = current_group.difference(&peers) + .cloned().collect::>(); + (to_insert, to_remove) + }; + + // Enumerate elements in `peers` not in `current_group`. + for peer_id in &to_insert { + // We don't call `on_add_to_priority_group` here in order to avoid calling + // `alloc_slots` all the time. + self.priority_groups.entry(group_id.to_owned()).or_default().insert(peer_id.clone()); + self.data.add_no_slot_node(peer_id.clone()); + } + + // Enumerate elements in `current_group` not in `peers`. + for peer in to_remove { + self.on_remove_from_priority_group(group_id, peer); + } + + if !to_insert.is_empty() { + self.alloc_slots(); + } } fn on_add_to_priority_group(&mut self, group_id: &str, peer_id: PeerId) { - self.data.add_to_priority_group(group_id, peer_id); + self.priority_groups.entry(group_id.to_owned()).or_default().insert(peer_id.clone()); + self.data.add_no_slot_node(peer_id); self.alloc_slots(); } fn on_remove_from_priority_group(&mut self, group_id: &str, peer_id: PeerId) { - self.data.remove_from_priority_group(group_id, &peer_id); - self.alloc_slots(); + if let Some(priority_group) = self.priority_groups.get_mut(group_id) { + if !priority_group.remove(&peer_id) { + // `PeerId` wasn't in the group in the first place. + return; + } + } else { + // Group doesn't exist, so the `PeerId` can't be in it. + return; + } + + // If that `PeerId` isn't in any other group, then it is no longer no-slot-occupying. + if !self.priority_groups.values().any(|l| l.contains(&peer_id)) { + self.data.remove_no_slot_node(&peer_id); + } + + // Disconnect the peer if necessary. + if group_id != RESERVED_NODES && self.reserved_only { + if let peersstate::Peer::Connected(peer) = self.data.peer(&peer_id) { + peer.disconnect(); + self.message_queue.push_back(Message::Drop(peer_id)); + } + } } fn on_report_peer(&mut self, peer_id: PeerId, change: ReputationChange) { @@ -374,25 +412,82 @@ impl Peerset { fn alloc_slots(&mut self) { self.update_time(); - // Try to grab the next node to attempt to connect to. - while let Some(next) = { - if self.reserved_only { - self.data.priority_not_connected_peer_from_group(RESERVED_NODES) - } else { - self.data.priority_not_connected_peer() - } - } { + // Try to connect to all the reserved nodes that we are not connected to. + loop { + let next = { + let data = &mut self.data; + self.priority_groups + .get(RESERVED_NODES) + .into_iter() + .flatten() + .filter(move |n| { + data.peer(n).into_connected().is_none() + }) + .next() + .cloned() + }; + + let next = match next { + Some(n) => n, + None => break, + }; + + let next = match self.data.peer(&next) { + peersstate::Peer::Unknown(n) => n.discover(), + peersstate::Peer::NotConnected(n) => n, + peersstate::Peer::Connected(_) => { + debug_assert!(false, "State inconsistency: not connected state"); + break; + } + }; + match next.try_outgoing() { Ok(conn) => self.message_queue.push_back(Message::Connect(conn.into_peer_id())), Err(_) => break, // No more slots available. } } + // Nothing more to do if we're in reserved mode. + if self.reserved_only { + return; + } + + // Try to connect to all the nodes in priority groups and that we are not connected to. loop { - if self.reserved_only { - break + let next = { + let data = &mut self.data; + self.priority_groups + .values() + .flatten() + .filter(move |n| { + data.peer(n).into_connected().is_none() + }) + .next() + .cloned() + }; + + let next = match next { + Some(n) => n, + None => break, + }; + + let next = match self.data.peer(&next) { + peersstate::Peer::Unknown(n) => n.discover(), + peersstate::Peer::NotConnected(n) => n, + peersstate::Peer::Connected(_) => { + debug_assert!(false, "State inconsistency: not connected state"); + break; + } + }; + + match next.try_outgoing() { + Ok(conn) => self.message_queue.push_back(Message::Connect(conn.into_peer_id())), + Err(_) => break, // No more slots available. } + } + // Now, we try to connect to non-priority nodes. + loop { // Try to grab the next node to attempt to connect to. let next = match self.data.highest_not_connected_peer() { Some(p) => p, @@ -425,6 +520,13 @@ impl Peerset { trace!(target: "peerset", "Incoming {:?}", peer_id); self.update_time(); + if self.reserved_only { + if !self.priority_groups.get(RESERVED_NODES).map_or(false, |n| n.contains(&peer_id)) { + self.message_queue.push_back(Message::Reject(index)); + return; + } + } + let not_connected = match self.data.peer(&peer_id) { // If we're already connected, don't answer, as the docs mention. peersstate::Peer::Connected(_) => return, @@ -527,9 +629,9 @@ impl Peerset { self.data.peers().len() } - /// Returns priority group by id. - pub fn get_priority_group(&self, group_id: &str) -> Option> { - self.data.get_priority_group(group_id) + /// Returns the content of a priority group. + pub fn priority_group(&self, group_id: &str) -> Option> { + self.priority_groups.get(group_id).map(|l| l.iter()) } } @@ -581,7 +683,6 @@ mod tests { assert_eq!(message, expected_message); peerset = p; } - assert!(peerset.message_queue.is_empty(), peerset.message_queue); peerset } @@ -646,6 +747,26 @@ mod tests { ]); } + #[test] + fn test_peerset_reject_incoming_in_reserved_only() { + let incoming = PeerId::random(); + let ii = IncomingIndex(1); + let config = PeersetConfig { + in_peers: 50, + out_peers: 50, + bootnodes: vec![], + reserved_only: true, + priority_groups: vec![], + }; + + let (mut peerset, _) = Peerset::from_config(config); + peerset.incoming(incoming.clone(), ii); + + assert_messages(peerset, vec![ + Message::Reject(ii), + ]); + } + #[test] fn test_peerset_discovered() { let bootnode = PeerId::random(); @@ -711,4 +832,3 @@ mod tests { futures::executor::block_on(fut); } } - diff --git a/client/peerset/src/peersstate.rs b/client/peerset/src/peersstate.rs index 843ec0a36006f436e3d9b2b9c83175ec632566e5..59879f629e31ecdbfbcb224a8a7dfb437f150746 100644 --- a/client/peerset/src/peersstate.rs +++ b/client/peerset/src/peersstate.rs @@ -14,10 +14,19 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Contains the state storage behind the peerset. +//! Reputation and slots allocation system behind the peerset. +//! +//! The [`PeersState`] state machine is responsible for managing the reputation and allocating +//! slots. It holds a list of nodes, each associated with a reputation value and whether we are +//! connected or not to this node. Thanks to this list, it knows how many slots are occupied. It +//! also holds a list of nodes which don't occupy slots. +//! +//! > Note: This module is purely dedicated to managing slots and reputations. Features such as +//! > for example connecting to some nodes in priority should be added outside of this +//! > module, rather than inside. use libp2p::PeerId; -use log::{error, warn}; +use log::error; use std::{borrow::Cow, collections::{HashSet, HashMap}}; use wasm_timer::Instant; @@ -37,23 +46,24 @@ pub struct PeersState { /// sort, to make the logic easier. nodes: HashMap, - /// Number of non-priority nodes for which the `ConnectionState` is `In`. + /// Number of slot-occupying nodes for which the `ConnectionState` is `In`. num_in: u32, - /// Number of non-priority nodes for which the `ConnectionState` is `In`. + /// Number of slot-occupying nodes for which the `ConnectionState` is `In`. num_out: u32, - /// Maximum allowed number of non-priority nodes for which the `ConnectionState` is `In`. + /// Maximum allowed number of slot-occupying nodes for which the `ConnectionState` is `In`. max_in: u32, - /// Maximum allowed number of non-priority nodes for which the `ConnectionState` is `Out`. + /// Maximum allowed number of slot-occupying nodes for which the `ConnectionState` is `Out`. max_out: u32, - /// Priority groups. Each group is identified by a string ID and contains a set of peer IDs. - priority_nodes: HashMap>, - - /// Only allow connections to/from peers in a priority group. - priority_only: bool, + /// List of node identities (discovered or not) that don't occupy slots. + /// + /// Note for future readers: this module is purely dedicated to managing slots. If you are + /// considering adding more features, please consider doing so outside of this module rather + /// than inside. + no_slot_nodes: HashSet, } /// State of a single node that we know about. @@ -106,15 +116,14 @@ impl ConnectionState { impl PeersState { /// Builds a new empty `PeersState`. - pub fn new(in_peers: u32, out_peers: u32, priority_only: bool) -> Self { + pub fn new(in_peers: u32, out_peers: u32) -> Self { PeersState { nodes: HashMap::new(), num_in: 0, num_out: 0, max_in: in_peers, max_out: out_peers, - priority_nodes: HashMap::new(), - priority_only, + no_slot_nodes: HashSet::new(), } } @@ -157,34 +166,6 @@ impl PeersState { .map(|(p, _)| p) } - /// Returns the first priority peer that we are not connected to. - /// - /// If multiple nodes are prioritized, which one is returned is unspecified. - pub fn priority_not_connected_peer(&mut self) -> Option { - let id = self.priority_nodes.values() - .flatten() - .find(|&id| self.nodes.get(id).map_or(false, |node| !node.connection_state.is_connected())) - .cloned(); - id.map(move |id| NotConnectedPeer { - state: self, - peer_id: Cow::Owned(id), - }) - } - - /// Returns the first priority peer that we are not connected to. - /// - /// If multiple nodes are prioritized, which one is returned is unspecified. - pub fn priority_not_connected_peer_from_group(&mut self, group_id: &str) -> Option { - let id = self.priority_nodes.get(group_id) - .and_then(|group| group.iter() - .find(|&id| self.nodes.get(id).map_or(false, |node| !node.connection_state.is_connected())) - .cloned()); - id.map(move |id| NotConnectedPeer { - state: self, - peer_id: Cow::Owned(id), - }) - } - /// Returns the peer with the highest reputation and that we are not connected to. /// /// If multiple nodes have the same reputation, which one is returned is unspecified. @@ -212,170 +193,40 @@ impl PeersState { } } - fn disconnect(&mut self, peer_id: &PeerId) { - let is_priority = self.is_priority(peer_id); - if let Some(mut node) = self.nodes.get_mut(peer_id) { - if !is_priority { - match node.connection_state { - ConnectionState::In => self.num_in -= 1, - ConnectionState::Out => self.num_out -= 1, - ConnectionState::NotConnected { .. } => - debug_assert!(false, "State inconsistency: disconnecting a disconnected node") - } - } - node.connection_state = ConnectionState::NotConnected { - last_connected: Instant::now(), - }; - } else { - warn!(target: "peerset", "Attempting to disconnect unknown peer {}", peer_id); - } - } - - /// Sets the peer as connected with an outgoing connection. - fn try_outgoing(&mut self, peer_id: &PeerId) -> bool { - let is_priority = self.is_priority(peer_id); - - // We are only accepting connections from priority nodes. - if !is_priority && self.priority_only { - return false; - } - - // Note that it is possible for num_out to be strictly superior to the max, in case we were - // connected to reserved node then marked them as not reserved. - if self.num_out >= self.max_out && !is_priority { - return false; + /// Add a node to the list of nodes that don't occupy slots. + /// + /// Has no effect if the peer was already in the group. + pub fn add_no_slot_node(&mut self, peer_id: PeerId) { + // Reminder: `HashSet::insert` returns false if the node was already in the set + if !self.no_slot_nodes.insert(peer_id.clone()) { + return; } - if let Some(mut peer) = self.nodes.get_mut(peer_id) { - peer.connection_state = ConnectionState::Out; - if !is_priority { - self.num_out += 1; + if let Some(peer) = self.nodes.get_mut(&peer_id) { + match peer.connection_state { + ConnectionState::In => self.num_in -= 1, + ConnectionState::Out => self.num_out -= 1, + ConnectionState::NotConnected { .. } => {}, } - return true; } - false } - /// Tries to accept the peer as an incoming connection. - /// - /// If there are enough slots available, switches the node to "connected" and returns `true`. If - /// the slots are full, the node stays "not connected" and we return `false`. + /// Removes a node from the list of nodes that don't occupy slots. /// - /// Note that reserved nodes don't count towards the number of slots. - fn try_accept_incoming(&mut self, peer_id: &PeerId) -> bool { - let is_priority = self.is_priority(peer_id); - - // We are only accepting connections from priority nodes. - if !is_priority && self.priority_only { - return false; + /// Has no effect if the peer was not in the group. + pub fn remove_no_slot_node(&mut self, peer_id: &PeerId) { + // Reminder: `HashSet::remove` returns false if the node was already not in the set + if !self.no_slot_nodes.remove(peer_id) { + return; } - // Note that it is possible for num_in to be strictly superior to the max, in case we were - // connected to reserved node then marked them as not reserved. - if self.num_in >= self.max_in && !is_priority { - return false; - } - if let Some(mut peer) = self.nodes.get_mut(peer_id) { - peer.connection_state = ConnectionState::In; - if !is_priority { - self.num_in += 1; + if let Some(peer) = self.nodes.get_mut(peer_id) { + match peer.connection_state { + ConnectionState::In => self.num_in += 1, + ConnectionState::Out => self.num_out += 1, + ConnectionState::NotConnected { .. } => {}, } - return true; } - false - } - - /// Sets priority group - pub fn set_priority_group(&mut self, group_id: &str, peers: HashSet) { - // update slot counters - let all_other_groups: HashSet<_> = self.priority_nodes - .iter() - .filter(|(g, _)| *g != group_id) - .flat_map(|(_, id)| id.clone()) - .collect(); - let existing_group = self.priority_nodes.remove(group_id).unwrap_or_default(); - for id in existing_group { - // update slots for nodes that are no longer priority - if !all_other_groups.contains(&id) { - if let Some(peer) = self.nodes.get_mut(&id) { - match peer.connection_state { - ConnectionState::In => self.num_in += 1, - ConnectionState::Out => self.num_out += 1, - ConnectionState::NotConnected { .. } => {}, - } - } - } - } - - for id in &peers { - // update slots for nodes that become priority - if !all_other_groups.contains(id) { - let peer = self.nodes.entry(id.clone()).or_default(); - match peer.connection_state { - ConnectionState::In => self.num_in -= 1, - ConnectionState::Out => self.num_out -= 1, - ConnectionState::NotConnected { .. } => {}, - } - } - } - self.priority_nodes.insert(group_id.into(), peers); - } - - /// Add a peer to a priority group. - pub fn add_to_priority_group(&mut self, group_id: &str, peer_id: PeerId) { - let mut peers = self.priority_nodes.get(group_id).cloned().unwrap_or_default(); - peers.insert(peer_id); - self.set_priority_group(group_id, peers); - } - - /// Remove a peer from a priority group. - pub fn remove_from_priority_group(&mut self, group_id: &str, peer_id: &PeerId) { - let mut peers = self.priority_nodes.get(group_id).cloned().unwrap_or_default(); - peers.remove(peer_id); - self.set_priority_group(group_id, peers); - } - - /// Get priority group content. - pub fn get_priority_group(&self, group_id: &str) -> Option> { - self.priority_nodes.get(group_id).cloned() - } - - /// Set whether to only allow connections to/from peers in a priority group. - /// Calling this method does not affect any existing connection, e.g. - /// enabling priority only will not disconnect from any non-priority peers - /// we are already connected to, only future incoming/outgoing connection - /// attempts will be affected. - pub fn set_priority_only(&mut self, priority: bool) { - self.priority_only = priority; - } - - /// Check that node is any priority group. - fn is_priority(&self, peer_id: &PeerId) -> bool { - self.priority_nodes.iter().any(|(_, group)| group.contains(peer_id)) - } - - /// Returns the reputation value of the node. - fn reputation(&self, peer_id: &PeerId) -> i32 { - self.nodes.get(peer_id).map_or(0, |p| p.reputation) - } - - /// Sets the reputation of the peer. - fn set_reputation(&mut self, peer_id: &PeerId, value: i32) { - let node = self.nodes - .entry(peer_id.clone()) - .or_default(); - node.reputation = value; - } - - /// Performs an arithmetic addition on the reputation score of that peer. - /// - /// In case of overflow, the value will be capped. - /// If the peer is unknown to us, we insert it and consider that it has a reputation of 0. - fn add_reputation(&mut self, peer_id: &PeerId, modifier: i32) { - let node = self.nodes - .entry(peer_id.clone()) - .or_default(); - node.reputation = node.reputation.saturating_add(modifier); } } @@ -437,7 +288,23 @@ impl<'a> ConnectedPeer<'a> { /// Switches the peer to "not connected". pub fn disconnect(self) -> NotConnectedPeer<'a> { - self.state.disconnect(&self.peer_id); + let is_no_slot_occupy = self.state.no_slot_nodes.contains(&*self.peer_id); + if let Some(mut node) = self.state.nodes.get_mut(&*self.peer_id) { + if !is_no_slot_occupy { + match node.connection_state { + ConnectionState::In => self.state.num_in -= 1, + ConnectionState::Out => self.state.num_out -= 1, + ConnectionState::NotConnected { .. } => + debug_assert!(false, "State inconsistency: disconnecting a disconnected node") + } + } + node.connection_state = ConnectionState::NotConnected { + last_connected: Instant::now(), + }; + } else { + debug_assert!(false, "State inconsistency: disconnecting a disconnected node"); + } + NotConnectedPeer { state: self.state, peer_id: self.peer_id, @@ -446,19 +313,27 @@ impl<'a> ConnectedPeer<'a> { /// Returns the reputation value of the node. pub fn reputation(&self) -> i32 { - self.state.reputation(&self.peer_id) + self.state.nodes.get(&*self.peer_id).map_or(0, |p| p.reputation) } /// Sets the reputation of the peer. pub fn set_reputation(&mut self, value: i32) { - self.state.set_reputation(&self.peer_id, value) + if let Some(node) = self.state.nodes.get_mut(&*self.peer_id) { + node.reputation = value; + } else { + debug_assert!(false, "State inconsistency: set_reputation on an unknown node"); + } } /// Performs an arithmetic addition on the reputation score of that peer. /// /// In case of overflow, the value will be capped. pub fn add_reputation(&mut self, modifier: i32) { - self.state.add_reputation(&self.peer_id, modifier) + if let Some(node) = self.state.nodes.get_mut(&*self.peer_id) { + node.reputation = node.reputation.saturating_add(modifier); + } else { + debug_assert!(false, "State inconsistency: add_reputation on an unknown node"); + } } } @@ -520,16 +395,29 @@ impl<'a> NotConnectedPeer<'a> { /// If there are enough slots available, switches the node to "connected" and returns `Ok`. If /// the slots are full, the node stays "not connected" and we return `Err`. /// - /// Note that priority nodes don't count towards the number of slots. + /// Non-slot-occupying nodes don't count towards the number of slots. pub fn try_outgoing(self) -> Result, NotConnectedPeer<'a>> { - if self.state.try_outgoing(&self.peer_id) { - Ok(ConnectedPeer { - state: self.state, - peer_id: self.peer_id, - }) + let is_no_slot_occupy = self.state.no_slot_nodes.contains(&*self.peer_id); + + // Note that it is possible for num_out to be strictly superior to the max, in case we were + // connected to reserved node then marked them as not reserved. + if self.state.num_out >= self.state.max_out && !is_no_slot_occupy { + return Err(self); + } + + if let Some(mut peer) = self.state.nodes.get_mut(&*self.peer_id) { + peer.connection_state = ConnectionState::Out; + if !is_no_slot_occupy { + self.state.num_out += 1; + } } else { - Err(self) + debug_assert!(false, "State inconsistency: try_outgoing on an unknown node"); } + + Ok(ConnectedPeer { + state: self.state, + peer_id: self.peer_id, + }) } /// Tries to accept the peer as an incoming connection. @@ -537,34 +425,54 @@ impl<'a> NotConnectedPeer<'a> { /// If there are enough slots available, switches the node to "connected" and returns `Ok`. If /// the slots are full, the node stays "not connected" and we return `Err`. /// - /// Note that priority nodes don't count towards the number of slots. + /// Non-slot-occupying nodes don't count towards the number of slots. pub fn try_accept_incoming(self) -> Result, NotConnectedPeer<'a>> { - if self.state.try_accept_incoming(&self.peer_id) { - Ok(ConnectedPeer { - state: self.state, - peer_id: self.peer_id, - }) + let is_no_slot_occupy = self.state.no_slot_nodes.contains(&*self.peer_id); + + // Note that it is possible for num_in to be strictly superior to the max, in case we were + // connected to reserved node then marked them as not reserved. + if self.state.num_in >= self.state.max_in && !is_no_slot_occupy { + return Err(self); + } + + if let Some(mut peer) = self.state.nodes.get_mut(&*self.peer_id) { + peer.connection_state = ConnectionState::In; + if !is_no_slot_occupy { + self.state.num_in += 1; + } } else { - Err(self) + debug_assert!(false, "State inconsistency: try_accept_incoming on an unknown node"); } + + Ok(ConnectedPeer { + state: self.state, + peer_id: self.peer_id, + }) } /// Returns the reputation value of the node. pub fn reputation(&self) -> i32 { - self.state.reputation(&self.peer_id) + self.state.nodes.get(&*self.peer_id).map_or(0, |p| p.reputation) } /// Sets the reputation of the peer. pub fn set_reputation(&mut self, value: i32) { - self.state.set_reputation(&self.peer_id, value) + if let Some(node) = self.state.nodes.get_mut(&*self.peer_id) { + node.reputation = value; + } else { + debug_assert!(false, "State inconsistency: set_reputation on an unknown node"); + } } /// Performs an arithmetic addition on the reputation score of that peer. /// /// In case of overflow, the value will be capped. - /// If the peer is unknown to us, we insert it and consider that it has a reputation of 0. pub fn add_reputation(&mut self, modifier: i32) { - self.state.add_reputation(&self.peer_id, modifier) + if let Some(node) = self.state.nodes.get_mut(&*self.peer_id) { + node.reputation = node.reputation.saturating_add(modifier); + } else { + debug_assert!(false, "State inconsistency: add_reputation on an unknown node"); + } } /// Un-discovers the peer. Removes it from the list. @@ -618,7 +526,7 @@ mod tests { #[test] fn full_slots_in() { - let mut peers_state = PeersState::new(1, 1, false); + let mut peers_state = PeersState::new(1, 1); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -632,14 +540,14 @@ mod tests { } #[test] - fn priority_node_doesnt_use_slot() { - let mut peers_state = PeersState::new(1, 1, false); + fn no_slot_node_doesnt_use_slot() { + let mut peers_state = PeersState::new(1, 1); let id1 = PeerId::random(); let id2 = PeerId::random(); - peers_state.set_priority_group("test", vec![id1.clone()].into_iter().collect()); - if let Peer::NotConnected(p) = peers_state.peer(&id1) { - assert!(p.try_accept_incoming().is_ok()); + peers_state.add_no_slot_node(id1.clone()); + if let Peer::Unknown(p) = peers_state.peer(&id1) { + assert!(p.discover().try_accept_incoming().is_ok()); } else { panic!() } if let Peer::Unknown(e) = peers_state.peer(&id2) { @@ -649,7 +557,7 @@ mod tests { #[test] fn disconnecting_frees_slot() { - let mut peers_state = PeersState::new(1, 1, false); + let mut peers_state = PeersState::new(1, 1); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -659,28 +567,9 @@ mod tests { assert!(peers_state.peer(&id2).into_not_connected().unwrap().try_accept_incoming().is_ok()); } - #[test] - fn priority_not_connected_peer() { - let mut peers_state = PeersState::new(25, 25, false); - let id1 = PeerId::random(); - let id2 = PeerId::random(); - - assert!(peers_state.priority_not_connected_peer().is_none()); - peers_state.peer(&id1).into_unknown().unwrap().discover(); - peers_state.peer(&id2).into_unknown().unwrap().discover(); - - assert!(peers_state.priority_not_connected_peer().is_none()); - peers_state.set_priority_group("test", vec![id1.clone()].into_iter().collect()); - assert!(peers_state.priority_not_connected_peer().is_some()); - peers_state.set_priority_group("test", vec![id2.clone(), id2.clone()].into_iter().collect()); - assert!(peers_state.priority_not_connected_peer().is_some()); - peers_state.set_priority_group("test", vec![].into_iter().collect()); - assert!(peers_state.priority_not_connected_peer().is_none()); - } - #[test] fn highest_not_connected_peer() { - let mut peers_state = PeersState::new(25, 25, false); + let mut peers_state = PeersState::new(25, 25); let id1 = PeerId::random(); let id2 = PeerId::random(); @@ -700,87 +589,11 @@ mod tests { } #[test] - fn disconnect_priority_doesnt_panic() { - let mut peers_state = PeersState::new(1, 1, false); + fn disconnect_no_slot_doesnt_panic() { + let mut peers_state = PeersState::new(1, 1); let id = PeerId::random(); - peers_state.set_priority_group("test", vec![id.clone()].into_iter().collect()); - let peer = peers_state.peer(&id).into_not_connected().unwrap().try_outgoing().unwrap(); + peers_state.add_no_slot_node(id.clone()); + let peer = peers_state.peer(&id).into_unknown().unwrap().discover().try_outgoing().unwrap(); peer.disconnect(); } - - #[test] - fn multiple_priority_groups_slot_count() { - let mut peers_state = PeersState::new(1, 1, false); - let id = PeerId::random(); - - if let Peer::Unknown(p) = peers_state.peer(&id) { - assert!(p.discover().try_accept_incoming().is_ok()); - } else { panic!() } - - assert_eq!(peers_state.num_in, 1); - peers_state.set_priority_group("test1", vec![id.clone()].into_iter().collect()); - assert_eq!(peers_state.num_in, 0); - peers_state.set_priority_group("test2", vec![id.clone()].into_iter().collect()); - assert_eq!(peers_state.num_in, 0); - peers_state.set_priority_group("test1", vec![].into_iter().collect()); - assert_eq!(peers_state.num_in, 0); - peers_state.set_priority_group("test2", vec![].into_iter().collect()); - assert_eq!(peers_state.num_in, 1); - } - - #[test] - fn priority_only_mode_ignores_drops_unknown_nodes() { - // test whether connection to/from given peer is allowed - let test_connection = |peers_state: &mut PeersState, id| { - if let Peer::Unknown(p) = peers_state.peer(id) { - p.discover(); - } - - let incoming = if let Peer::NotConnected(p) = peers_state.peer(id) { - p.try_accept_incoming().is_ok() - } else { - panic!() - }; - - if incoming { - peers_state.peer(id).into_connected().map(|p| p.disconnect()); - } - - let outgoing = if let Peer::NotConnected(p) = peers_state.peer(id) { - p.try_outgoing().is_ok() - } else { - panic!() - }; - - if outgoing { - peers_state.peer(id).into_connected().map(|p| p.disconnect()); - } - - incoming || outgoing - }; - - let mut peers_state = PeersState::new(1, 1, true); - let id = PeerId::random(); - - // this is an unknown peer and our peer state is set to only allow - // priority peers so any connection attempt should be denied. - assert!(!test_connection(&mut peers_state, &id)); - - // disabling priority only mode should allow the connection to go - // through. - peers_state.set_priority_only(false); - assert!(test_connection(&mut peers_state, &id)); - - // re-enabling it we should again deny connections from the peer. - peers_state.set_priority_only(true); - assert!(!test_connection(&mut peers_state, &id)); - - // but if we add the peer to a priority group it should be accepted. - peers_state.set_priority_group("TEST_GROUP", vec![id.clone()].into_iter().collect()); - assert!(test_connection(&mut peers_state, &id)); - - // and removing it will cause the connection to once again be denied. - peers_state.remove_from_priority_group("TEST_GROUP", &id); - assert!(!test_connection(&mut peers_state, &id)); - } } diff --git a/client/peerset/tests/fuzz.rs b/client/peerset/tests/fuzz.rs index 44477cec6589dbf2b6ce5922ae4ac3217fe9e973..6fa29e3d834cfcdaa0b035e03849432e20e7b3f3 100644 --- a/client/peerset/tests/fuzz.rs +++ b/client/peerset/tests/fuzz.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use futures::prelude::*; use libp2p::PeerId; @@ -44,13 +46,13 @@ fn test_once() { id }).collect(), priority_groups: { - let list = (0 .. Uniform::new_inclusive(0, 2).sample(&mut rng)).map(|_| { + let nodes = (0 .. Uniform::new_inclusive(0, 2).sample(&mut rng)).map(|_| { let id = PeerId::random(); known_nodes.insert(id.clone()); reserved_nodes.insert(id.clone()); id }).collect(); - vec![("reserved".to_owned(), list)] + vec![("foo".to_string(), nodes)] }, reserved_only: Uniform::new_inclusive(0, 10).sample(&mut rng) == 0, in_peers: Uniform::new_inclusive(0, 25).sample(&mut rng), diff --git a/client/proposer-metrics/Cargo.toml b/client/proposer-metrics/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5708a970a1b4e7401e8abf0b82bc51f36e25a5e5 --- /dev/null +++ b/client/proposer-metrics/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "sc-proposer-metrics" +version = "0.8.0-rc6" +authors = ["Parity Technologies "] +edition = "2018" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Basic metrics for block production." + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +log = "0.4.8" +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-rc6"} diff --git a/client/proposer-metrics/README.md b/client/proposer-metrics/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9669c7d35191dc6dc6d4c6df5878c6b4c9bea30d --- /dev/null +++ b/client/proposer-metrics/README.md @@ -0,0 +1,3 @@ +Prometheus basic proposer metrics. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/proposer-metrics/src/lib.rs b/client/proposer-metrics/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..50498d40b62d5e171ec2cd22232b441b9c735db9 --- /dev/null +++ b/client/proposer-metrics/src/lib.rs @@ -0,0 +1,67 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Prometheus basic proposer metrics. + +use prometheus_endpoint::{register, PrometheusError, Registry, Histogram, HistogramOpts, Gauge, U64}; + +/// Optional shareable link to basic authorship metrics. +#[derive(Clone, Default)] +pub struct MetricsLink(Option); + +impl MetricsLink { + pub fn new(registry: Option<&Registry>) -> Self { + Self( + registry.and_then(|registry| + Metrics::register(registry) + .map_err(|err| log::warn!("Failed to register proposer prometheus metrics: {}", err)) + .ok() + ) + ) + } + + pub fn report(&self, do_this: impl FnOnce(&Metrics) -> O) -> Option { + Some(do_this(self.0.as_ref()?)) + } +} + +/// Authorship metrics. +#[derive(Clone)] +pub struct Metrics { + pub block_constructed: Histogram, + pub number_of_transactions: Gauge, +} + +impl Metrics { + pub fn register(registry: &Registry) -> Result { + Ok(Self { + block_constructed: register( + Histogram::with_opts(HistogramOpts::new( + "proposer_block_constructed", + "Histogram of time taken to construct new block", + ))?, + registry, + )?, + number_of_transactions: register( + Gauge::new( + "proposer_number_of_transactions", + "Number of transactions included in block", + )?, + registry, + )?, + }) + } +} diff --git a/client/rpc-api/Cargo.toml b/client/rpc-api/Cargo.toml index e0dac773bf0991a9b685c2c2ebb9621f9319d4d6..95080911320d1645ff686f406804270e12528b57 100644 --- a/client/rpc-api/Cargo.toml +++ b/client/rpc-api/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-rpc-api" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate RPC interfaces." @@ -12,20 +12,20 @@ description = "Substrate RPC interfaces." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0" } +codec = { package = "parity-scale-codec", version = "1.3.4" } derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } -jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.5" -jsonrpc-derive = "14.0.3" -jsonrpc-pubsub = "14.0.3" +jsonrpc-core = "14.2.0" +jsonrpc-core-client = "14.2.0" +jsonrpc-derive = "14.2.1" +jsonrpc-pubsub = "14.2.0" log = "0.4.8" parking_lot = "0.10.0" -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } -sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-dev"} -sp-chain-spec = { path = "../../primitives/chain-spec" , version = "2.0.0-dev"} +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-version = { version = "2.0.0-rc6", path = "../../primitives/version" } +sp-runtime = { path = "../../primitives/runtime" , version = "2.0.0-rc6"} +sp-chain-spec = { path = "../../primitives/chain-spec" , version = "2.0.0-rc6"} serde = { version = "1.0.101", features = ["derive"] } serde_json = "1.0.41" -sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } -sp-rpc = { version = "2.0.0-dev", path = "../../primitives/rpc" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../primitives/transaction-pool" } +sp-rpc = { version = "2.0.0-rc6", path = "../../primitives/rpc" } diff --git a/client/rpc-api/README.md b/client/rpc-api/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e860e0c2334da50e57bee241b14e2807b25bc7f3 --- /dev/null +++ b/client/rpc-api/README.md @@ -0,0 +1,5 @@ +Substrate RPC interfaces. + +A collection of RPC methods and subscriptions supported by all substrate clients. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/rpc-api/src/author/error.rs b/client/rpc-api/src/author/error.rs index dfd488e5da37fd86d5a94b40fb893ee3cfcd2ac6..69c036be95fe085bcefeb1f38b8edbe594facaad 100644 --- a/client/rpc-api/src/author/error.rs +++ b/client/rpc-api/src/author/error.rs @@ -1,23 +1,26 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Authoring RPC module errors. use crate::errors; use jsonrpc_core as rpc; +use sp_runtime::transaction_validity::InvalidTransaction; /// Author RPC Result type. pub type Result = std::result::Result; @@ -112,10 +115,18 @@ impl From for rpc::Error { message: format!("Verification Error: {}", e).into(), data: Some(format!("{:?}", e).into()), }, - Error::Pool(PoolError::InvalidTransaction(e)) => rpc::Error { + Error::Pool(PoolError::InvalidTransaction(InvalidTransaction::Custom(e))) => rpc::Error { code: rpc::ErrorCode::ServerError(POOL_INVALID_TX), message: "Invalid Transaction".into(), - data: serde_json::to_value(e).ok(), + data: Some(format!("Custom error: {}", e).into()), + }, + Error::Pool(PoolError::InvalidTransaction(e)) => { + let msg: &str = e.into(); + rpc::Error { + code: rpc::ErrorCode::ServerError(POOL_INVALID_TX), + message: "Invalid Transaction".into(), + data: Some(msg.into()), + } }, Error::Pool(PoolError::UnknownTransaction(e)) => rpc::Error { code: rpc::ErrorCode::ServerError(POOL_UNKNOWN_VALIDITY), diff --git a/client/rpc-api/src/author/mod.rs b/client/rpc-api/src/author/mod.rs index 49c4c996fa9e1705fa4344bcce708ecf66d5b45d..29f5b1d26e84cb9c8644292da26c74e07dd23a39 100644 --- a/client/rpc-api/src/author/mod.rs +++ b/client/rpc-api/src/author/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate block-author/full-node API. diff --git a/client/rpc-api/src/chain/error.rs b/client/rpc-api/src/chain/error.rs index ffa4d82bdff890b923ad51b22ff46ccb5efdee58..fd7bd0a43d778bf2a03be96baa5960e15f3dbd47 100644 --- a/client/rpc-api/src/chain/error.rs +++ b/client/rpc-api/src/chain/error.rs @@ -1,19 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - +// along with this program. If not, see . //! Error helpers for Chain RPC module. diff --git a/client/rpc-api/src/chain/mod.rs b/client/rpc-api/src/chain/mod.rs index 2ab3851d37663a328e37b4f1d8998d103905d9f3..753ac5617a29d70380e3502d95a2145af8a926a9 100644 --- a/client/rpc-api/src/chain/mod.rs +++ b/client/rpc-api/src/chain/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate blockchain API. @@ -47,7 +49,7 @@ pub trait ChainApi { #[rpc(name = "chain_getBlockHash", alias("chain_getHead"))] fn block_hash( &self, - hash: Option>>, + hash: Option>, ) -> Result>>; /// Get hash of the last finalized block in the canon chain. diff --git a/client/rpc-api/src/child_state/mod.rs b/client/rpc-api/src/child_state/mod.rs index a46269cad6c0c72c7d6478632a7d9971032d5ab9..d956a7554f8ee798d2fa84c777ae33b591f257ce 100644 --- a/client/rpc-api/src/child_state/mod.rs +++ b/client/rpc-api/src/child_state/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate state API. diff --git a/client/rpc-api/src/errors.rs b/client/rpc-api/src/errors.rs index b75c34ead3806a7a0be3bb8104c4a30cd961138e..4e1a5b10fc5128fbb3e36dfb788a23c0575e965d 100644 --- a/client/rpc-api/src/errors.rs +++ b/client/rpc-api/src/errors.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use log::warn; diff --git a/client/rpc-api/src/helpers.rs b/client/rpc-api/src/helpers.rs index 912a5664b3c2fb9a1d48747fb46036ac02057b08..025fef1102c492adfb142a837d7e2f5e6a262e11 100644 --- a/client/rpc-api/src/helpers.rs +++ b/client/rpc-api/src/helpers.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use jsonrpc_core::futures::prelude::*; use futures::{channel::oneshot, compat::Compat}; diff --git a/client/rpc-api/src/lib.rs b/client/rpc-api/src/lib.rs index f742d73b692c00de347e8a8e6f7994b529889267..7bae75181056ff5d7ad7bfd39139a4252ad0769b 100644 --- a/client/rpc-api/src/lib.rs +++ b/client/rpc-api/src/lib.rs @@ -22,12 +22,12 @@ mod errors; mod helpers; +mod metadata; mod policy; -mod subscriptions; -pub use jsonrpc_core::IoHandlerExtension as RpcExtension; -pub use subscriptions::{Subscriptions, TaskExecutor}; pub use helpers::Receiver; +pub use jsonrpc_core::IoHandlerExtension as RpcExtension; +pub use metadata::Metadata; pub use policy::DenyUnsafe; pub mod author; diff --git a/client/rpc/src/metadata.rs b/client/rpc-api/src/metadata.rs similarity index 73% rename from client/rpc/src/metadata.rs rename to client/rpc-api/src/metadata.rs index d35653f8e6278b966cee9e4933577b07075ba786..cffcbf61f54401ee33d584198235c60e67d1fefa 100644 --- a/client/rpc/src/metadata.rs +++ b/client/rpc-api/src/metadata.rs @@ -1,24 +1,26 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! RPC Metadata use std::sync::Arc; +use jsonrpc_core::futures::sync::mpsc; use jsonrpc_pubsub::{Session, PubSubMetadata}; -use rpc::futures::sync::mpsc; /// RPC Metadata. /// @@ -30,7 +32,7 @@ pub struct Metadata { session: Option>, } -impl rpc::Metadata for Metadata {} +impl jsonrpc_core::Metadata for Metadata {} impl PubSubMetadata for Metadata { fn session(&self) -> Option> { self.session.clone() diff --git a/client/rpc-api/src/offchain/error.rs b/client/rpc-api/src/offchain/error.rs index 695c0cf41fd6da092c970b55a6638dee8ff4ea06..ea5223f1ce7f935aefa8b6629ee2e82eebb48c13 100644 --- a/client/rpc-api/src/offchain/error.rs +++ b/client/rpc-api/src/offchain/error.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Offchain RPC errors. diff --git a/client/rpc-api/src/offchain/mod.rs b/client/rpc-api/src/offchain/mod.rs index bbe466ff5994d450164c47e005e0266e83e52440..427b6a1cc017bfeb09e52a43e14c14fa6ddf8669 100644 --- a/client/rpc-api/src/offchain/mod.rs +++ b/client/rpc-api/src/offchain/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate offchain API. diff --git a/client/rpc-api/src/policy.rs b/client/rpc-api/src/policy.rs index c01b5232f359c2224708f86b43467b4cdf4ca8d2..141dcfbc415f8294d6f140db7ce74012afa200ac 100644 --- a/client/rpc-api/src/policy.rs +++ b/client/rpc-api/src/policy.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Policy-related types. //! @@ -24,21 +26,21 @@ use jsonrpc_core as rpc; /// Signifies whether a potentially unsafe RPC should be denied. #[derive(Clone, Copy, Debug)] pub enum DenyUnsafe { - /// Denies only potentially unsafe RPCs. - Yes, - /// Allows calling every RPCs. - No + /// Denies only potentially unsafe RPCs. + Yes, + /// Allows calling every RPCs. + No, } impl DenyUnsafe { - /// Returns `Ok(())` if the RPCs considered unsafe are safe to call, - /// otherwise returns `Err(UnsafeRpcError)`. - pub fn check_if_safe(self) -> Result<(), UnsafeRpcError> { - match self { - DenyUnsafe::Yes => Err(UnsafeRpcError), - DenyUnsafe::No => Ok(()) - } - } + /// Returns `Ok(())` if the RPCs considered unsafe are safe to call, + /// otherwise returns `Err(UnsafeRpcError)`. + pub fn check_if_safe(self) -> Result<(), UnsafeRpcError> { + match self { + DenyUnsafe::Yes => Err(UnsafeRpcError), + DenyUnsafe::No => Ok(()), + } + } } /// Signifies whether an RPC considered unsafe is denied to be called externally. @@ -46,15 +48,15 @@ impl DenyUnsafe { pub struct UnsafeRpcError; impl std::fmt::Display for UnsafeRpcError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "RPC call is unsafe to be called externally") - } + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "RPC call is unsafe to be called externally") + } } impl std::error::Error for UnsafeRpcError {} impl From for rpc::Error { - fn from(_: UnsafeRpcError) -> rpc::Error { - rpc::Error::method_not_found() - } + fn from(_: UnsafeRpcError) -> rpc::Error { + rpc::Error::method_not_found() + } } diff --git a/client/rpc-api/src/state/error.rs b/client/rpc-api/src/state/error.rs index c9c2cf4e454d403dd63baaf383d6e85467996306..2fcca3c343f09efdd2acb1ce767cb2f80a80e5bd 100644 --- a/client/rpc-api/src/state/error.rs +++ b/client/rpc-api/src/state/error.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! State RPC errors. diff --git a/client/rpc-api/src/state/helpers.rs b/client/rpc-api/src/state/helpers.rs index 516b6c80c49a7bfcb931f10bbdc771a81d685b19..0d176ea67f35be0449bf8bb63c49401260e39070 100644 --- a/client/rpc-api/src/state/helpers.rs +++ b/client/rpc-api/src/state/helpers.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate state API helpers. diff --git a/client/rpc-api/src/state/mod.rs b/client/rpc-api/src/state/mod.rs index 3d38a16eb4a988137cd79905daa24b0c98153ad1..1bfbb4786e677bb2eb89cb2b51346f9ae4d56890 100644 --- a/client/rpc-api/src/state/mod.rs +++ b/client/rpc-api/src/state/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate state API. diff --git a/client/rpc-api/src/subscriptions.rs b/client/rpc-api/src/subscriptions.rs deleted file mode 100644 index 54881bad5123bfb9c98c0b716f7b1b514bab2d40..0000000000000000000000000000000000000000 --- a/client/rpc-api/src/subscriptions.rs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -use std::collections::HashMap; -use std::sync::{Arc, atomic::{self, AtomicUsize}}; - -use log::{error, warn}; -use jsonrpc_pubsub::{SubscriptionId, typed::{Sink, Subscriber}}; -use parking_lot::Mutex; -use jsonrpc_core::futures::sync::oneshot; -use jsonrpc_core::futures::{Future, future}; - -type Id = u64; - -/// Alias for a an implementation of `futures::future::Executor`. -pub type TaskExecutor = Arc + Send>> + Send + Sync>; - -/// Generate unique ids for subscriptions. -#[derive(Clone, Debug)] -pub struct IdProvider { - next_id: Arc, -} -impl Default for IdProvider { - fn default() -> Self { - IdProvider { - next_id: Arc::new(AtomicUsize::new(1)), - } - } -} - -impl IdProvider { - /// Returns next id for the subscription. - pub fn next_id(&self) -> Id { - self.next_id.fetch_add(1, atomic::Ordering::AcqRel) as u64 - } -} - -/// Subscriptions manager. -/// -/// Takes care of assigning unique subscription ids and -/// driving the sinks into completion. -#[derive(Clone)] -pub struct Subscriptions { - next_id: IdProvider, - active_subscriptions: Arc>>>, - executor: TaskExecutor, -} - -impl Subscriptions { - /// Creates new `Subscriptions` object. - pub fn new(executor: TaskExecutor) -> Self { - Subscriptions { - next_id: Default::default(), - active_subscriptions: Default::default(), - executor, - } - } - - /// Borrows the internal task executor. - /// - /// This can be used to spawn additional tasks on the underlying event loop. - pub fn executor(&self) -> &TaskExecutor { - &self.executor - } - - /// Creates new subscription for given subscriber. - /// - /// Second parameter is a function that converts Subscriber sink into a future. - /// This future will be driven to completion by the underlying event loop - /// or will be cancelled in case #cancel is invoked. - pub fn add(&self, subscriber: Subscriber, into_future: G) -> SubscriptionId where - G: FnOnce(Sink) -> R, - R: future::IntoFuture, - F: future::Future + Send + 'static, - { - let id = self.next_id.next_id(); - let subscription_id: SubscriptionId = id.into(); - if let Ok(sink) = subscriber.assign_id(subscription_id.clone()) { - let (tx, rx) = oneshot::channel(); - let future = into_future(sink) - .into_future() - .select(rx.map_err(|e| warn!("Error timeing out: {:?}", e))) - .then(|_| Ok(())); - - self.active_subscriptions.lock().insert(id, tx); - if self.executor.execute(Box::new(future)).is_err() { - error!("Failed to spawn RPC subscription task"); - } - } - - subscription_id - } - - /// Cancel subscription. - /// - /// Returns true if subscription existed or false otherwise. - pub fn cancel(&self, id: SubscriptionId) -> bool { - if let SubscriptionId::Number(id) = id { - if let Some(tx) = self.active_subscriptions.lock().remove(&id) { - let _ = tx.send(()); - return true; - } - } - false - } -} diff --git a/client/rpc-api/src/system/error.rs b/client/rpc-api/src/system/error.rs index fbb4e44bcb635f0bdb486f0b581068e1d342c061..4897aa485cbe47591b787e771fda59543d3644c4 100644 --- a/client/rpc-api/src/system/error.rs +++ b/client/rpc-api/src/system/error.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! System RPC module errors. diff --git a/client/rpc-api/src/system/helpers.rs b/client/rpc-api/src/system/helpers.rs index 46461d69888c18b86b4de44eb9c1f4941547a103..5dbe93543d8e5313a617a91ccfd3fa919ec661ee 100644 --- a/client/rpc-api/src/system/helpers.rs +++ b/client/rpc-api/src/system/helpers.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate system API helpers. diff --git a/client/rpc-api/src/system/mod.rs b/client/rpc-api/src/system/mod.rs index 486623477ecf1fc87c950ded18052e9b0b240a56..a7b746ee1b114afa525b5c077d22bf34ec1d5f54 100644 --- a/client/rpc-api/src/system/mod.rs +++ b/client/rpc-api/src/system/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate system API. diff --git a/client/rpc-servers/Cargo.toml b/client/rpc-servers/Cargo.toml index 345aff13d8da75553bf7d80cdf5e9e214bf0bf1e..3af5cdd039d8b547d296ba0d7d8026bc9fafeb37 100644 --- a/client/rpc-servers/Cargo.toml +++ b/client/rpc-servers/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-rpc-server" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate RPC servers." @@ -12,13 +12,14 @@ description = "Substrate RPC servers." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -jsonrpc-core = "14.0.3" -pubsub = { package = "jsonrpc-pubsub", version = "14.0.3" } +jsonrpc-core = "14.2.0" +pubsub = { package = "jsonrpc-pubsub", version = "14.2.0" } log = "0.4.8" serde = "1.0.101" serde_json = "1.0.41" -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } [target.'cfg(not(target_os = "unknown"))'.dependencies] -http = { package = "jsonrpc-http-server", version = "14.0.3" } -ws = { package = "jsonrpc-ws-server", version = "14.0.3" } +http = { package = "jsonrpc-http-server", version = "14.2.0" } +ws = { package = "jsonrpc-ws-server", version = "14.2.0" } +ipc = { version = "14.2.0", package = "jsonrpc-ipc-server" } diff --git a/client/rpc-servers/README.md b/client/rpc-servers/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cf00b3169a6276b048b5a132d02df7c77e21dbf0 --- /dev/null +++ b/client/rpc-servers/README.md @@ -0,0 +1,3 @@ +Substrate RPC servers. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/rpc-servers/src/lib.rs b/client/rpc-servers/src/lib.rs index 97fb10c15e4b5593ac247beb25563d29d7627648..1e476262acea8761e8a0e266189934b02ad0f20d 100644 --- a/client/rpc-servers/src/lib.rs +++ b/client/rpc-servers/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate RPC servers. @@ -60,6 +62,8 @@ pub fn rpc_handler( mod inner { use super::*; + /// Type alias for ipc server + pub type IpcServer = ipc::Server; /// Type alias for http server pub type HttpServer = http::Server; /// Type alias for ws server @@ -87,6 +91,23 @@ mod inner { .start_http(addr) } + /// Start IPC server listening on given path. + /// + /// **Note**: Only available if `not(target_os = "unknown")`. + pub fn start_ipc( + addr: &str, + io: RpcHandler, + ) -> io::Result { + let builder = ipc::ServerBuilder::new(io); + #[cfg(target_os = "unix")] + builder.set_security_attributes({ + let security_attributes = ipc::SecurityAttributes::empty(); + security_attributes.set_mode(0o600)?; + security_attributes + }); + builder.start(addr) + } + /// Start WS server listening on given address. /// /// **Note**: Only available if `not(target_os = "unknown")`. diff --git a/client/rpc/Cargo.toml b/client/rpc/Cargo.toml index 66f7cb50e6d1272f8aecfe4975187fd16153674b..fe4a02aa83f2ca55828780052e87ea5424a8725a 100644 --- a/client/rpc/Cargo.toml +++ b/client/rpc/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-rpc" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate Client RPC" @@ -12,37 +12,41 @@ description = "Substrate Client RPC" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-rpc-api = { version = "0.8.0-dev", path = "../rpc-api" } -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } -codec = { package = "parity-scale-codec", version = "1.3.0" } +sc-rpc-api = { version = "0.8.0-rc6", path = "../rpc-api" } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } +codec = { package = "parity-scale-codec", version = "1.3.4" } futures = { version = "0.3.1", features = ["compat"] } -jsonrpc-pubsub = "14.0.3" +jsonrpc-pubsub = "14.2.0" log = "0.4.8" -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -rpc = { package = "jsonrpc-core", version = "14.0.3" } -sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +rpc = { package = "jsonrpc-core", version = "14.2.0" } +sp-version = { version = "2.0.0-rc6", path = "../../primitives/version" } serde_json = "1.0.41" -sp-session = { version = "2.0.0-dev", path = "../../primitives/session" } -sp-offchain = { version = "2.0.0-dev", path = "../../primitives/offchain" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } -sp-rpc = { version = "2.0.0-dev", path = "../../primitives/rpc" } -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } -sp-chain-spec = { version = "2.0.0-dev", path = "../../primitives/chain-spec" } -sc-executor = { version = "0.8.0-dev", path = "../executor" } -sc-block-builder = { version = "0.8.0-dev", path = "../../client/block-builder" } -sc-keystore = { version = "2.0.0-dev", path = "../keystore" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } +sp-session = { version = "2.0.0-rc6", path = "../../primitives/session" } +sp-offchain = { version = "2.0.0-rc6", path = "../../primitives/offchain" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-utils = { version = "2.0.0-rc6", path = "../../primitives/utils" } +sp-rpc = { version = "2.0.0-rc6", path = "../../primitives/rpc" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } +sp-chain-spec = { version = "2.0.0-rc6", path = "../../primitives/chain-spec" } +sc-executor = { version = "0.8.0-rc6", path = "../executor" } +sc-block-builder = { version = "0.8.0-rc6", path = "../../client/block-builder" } +sc-keystore = { version = "2.0.0-rc6", path = "../keystore" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } hash-db = { version = "0.15.2", default-features = false } parking_lot = "0.10.0" +lazy_static = { version = "1.4.0", optional = true } [dev-dependencies] assert_matches = "1.3.0" futures01 = { package = "futures", version = "0.1.29" } -sc-network = { version = "0.8.0-dev", path = "../network" } -sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } +sc-network = { version = "0.8.0-rc6", path = "../network" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client" } tokio = "0.1.22" -sc-transaction-pool = { version = "2.0.0-dev", path = "../transaction-pool" } +sc-transaction-pool = { version = "2.0.0-rc6", path = "../transaction-pool" } + +[features] +test-helpers = ["lazy_static"] diff --git a/client/rpc/README.md b/client/rpc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6066af4da71a36ed2748f1cce2c360592e2b51ab --- /dev/null +++ b/client/rpc/README.md @@ -0,0 +1,5 @@ +Substrate RPC implementation. + +A core implementation of Substrate RPC interfaces. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/rpc/src/author/mod.rs b/client/rpc/src/author/mod.rs index 23aed953d01df3151f926e55e7b310cad4accf53..e6384c995dce8d060baf7526b5be99ac4d6e4f4d 100644 --- a/client/rpc/src/author/mod.rs +++ b/client/rpc/src/author/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate block-author/full-node API. @@ -30,8 +32,8 @@ use rpc::futures::{ }; use futures::{StreamExt as _, compat::Compat}; use futures::future::{ready, FutureExt, TryFutureExt}; -use sc_rpc_api::{DenyUnsafe, Subscriptions}; -use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use sc_rpc_api::DenyUnsafe; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId, manager::SubscriptionManager}; use codec::{Encode, Decode}; use sp_core::{Bytes, traits::BareCryptoStorePtr}; use sp_api::ProvideRuntimeApi; @@ -53,7 +55,7 @@ pub struct Author { /// Transactions pool pool: Arc

, /// Subscriptions manager - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, /// The key store. keystore: BareCryptoStorePtr, /// Whether to deny unsafe calls @@ -65,7 +67,7 @@ impl Author { pub fn new( client: Arc, pool: Arc

, - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, keystore: BareCryptoStorePtr, deny_unsafe: DenyUnsafe, ) -> Self { @@ -79,7 +81,6 @@ impl Author { } } - /// Currently we treat all RPC transactions as externals. /// /// Possibly in the future we could allow opt-in for special treatment @@ -93,7 +94,7 @@ impl AuthorApi, BlockHash

= + Decode::decode(&mut &EQUIVOCATION_PROOF_BLOB[..]).unwrap(); + + let equivocation_proof2 = equivocation_proof1.clone(); + }: { + sp_consensus_babe::check_equivocation_proof::
(equivocation_proof1); + } verify { + assert!(sp_consensus_babe::check_equivocation_proof::
(equivocation_proof2)); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::*; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext(3).execute_with(|| { + assert_ok!(test_benchmark_check_equivocation_proof::()); + }) + } + + #[test] + fn test_generate_equivocation_report_blob() { + let (pairs, mut ext) = new_test_ext_with_pairs(3); + + let offending_authority_index = 0; + let offending_authority_pair = &pairs[0]; + + ext.execute_with(|| { + start_era(1); + + let equivocation_proof = generate_equivocation_proof( + offending_authority_index, + offending_authority_pair, + CurrentSlot::get() + 1, + ); + + println!("equivocation_proof: {:?}", equivocation_proof); + println!( + "equivocation_proof.encode(): {:?}", + equivocation_proof.encode() + ); + }); + } +} diff --git a/frame/babe/src/equivocation.rs b/frame/babe/src/equivocation.rs new file mode 100644 index 0000000000000000000000000000000000000000..322dff92f2398b330efff33357125da694c85451 --- /dev/null +++ b/frame/babe/src/equivocation.rs @@ -0,0 +1,271 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! +//! An opt-in utility module for reporting equivocations. +//! +//! This module defines an offence type for BABE equivocations +//! and some utility traits to wire together: +//! - a system for reporting offences; +//! - a system for submitting unsigned transactions; +//! - a way to get the current block author; +//! +//! These can be used in an offchain context in order to submit equivocation +//! reporting extrinsics (from the client that's import BABE blocks). +//! And in a runtime context, so that the BABE pallet can validate the +//! equivocation proofs in the extrinsic and report the offences. +//! +//! IMPORTANT: +//! When using this module for enabling equivocation reporting it is required +//! that the `ValidateUnsigned` for the BABE pallet is used in the runtime +//! definition. +//! + +use frame_support::{debug, traits::KeyOwnerProofSystem}; +use sp_consensus_babe::{EquivocationProof, SlotNumber}; +use sp_runtime::transaction_validity::{ + InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, + TransactionValidityError, ValidTransaction, +}; +use sp_runtime::{DispatchResult, Perbill}; +use sp_staking::{ + offence::{Kind, Offence, OffenceError, ReportOffence}, + SessionIndex, +}; +use sp_std::prelude::*; + +use crate::{Call, Module, Trait}; + +/// A trait with utility methods for handling equivocation reports in BABE. +/// The trait provides methods for reporting an offence triggered by a valid +/// equivocation report, checking the current block author (to declare as the +/// reporter), and also for creating and submitting equivocation report +/// extrinsics (useful only in offchain context). +pub trait HandleEquivocation { + /// Report an offence proved by the given reporters. + fn report_offence( + reporters: Vec, + offence: BabeEquivocationOffence, + ) -> Result<(), OffenceError>; + + /// Returns true if all of the offenders at the given time slot have already been reported. + fn is_known_offence(offenders: &[T::KeyOwnerIdentification], time_slot: &SlotNumber) -> bool; + + /// Create and dispatch an equivocation report extrinsic. + fn submit_unsigned_equivocation_report( + equivocation_proof: EquivocationProof, + key_owner_proof: T::KeyOwnerProof, + ) -> DispatchResult; + + /// Fetch the current block author id, if defined. + fn block_author() -> Option; +} + +impl HandleEquivocation for () { + fn report_offence( + _reporters: Vec, + _offence: BabeEquivocationOffence, + ) -> Result<(), OffenceError> { + Ok(()) + } + + fn is_known_offence(_offenders: &[T::KeyOwnerIdentification], _time_slot: &SlotNumber) -> bool { + true + } + + fn submit_unsigned_equivocation_report( + _equivocation_proof: EquivocationProof, + _key_owner_proof: T::KeyOwnerProof, + ) -> DispatchResult { + Ok(()) + } + + fn block_author() -> Option { + None + } +} + +/// Generic equivocation handler. This type implements `HandleEquivocation` +/// using existing subsystems that are part of frame (type bounds described +/// below) and will dispatch to them directly, it's only purpose is to wire all +/// subsystems together. +pub struct EquivocationHandler { + _phantom: sp_std::marker::PhantomData<(I, R)>, +} + +impl Default for EquivocationHandler { + fn default() -> Self { + Self { + _phantom: Default::default(), + } + } +} + +impl HandleEquivocation for EquivocationHandler +where + // We use the authorship pallet to fetch the current block author and use + // `offchain::SendTransactionTypes` for unsigned extrinsic creation and + // submission. + T: Trait + pallet_authorship::Trait + frame_system::offchain::SendTransactionTypes>, + // A system for reporting offences after valid equivocation reports are + // processed. + R: ReportOffence< + T::AccountId, + T::KeyOwnerIdentification, + BabeEquivocationOffence, + >, +{ + fn report_offence( + reporters: Vec, + offence: BabeEquivocationOffence, + ) -> Result<(), OffenceError> { + R::report_offence(reporters, offence) + } + + fn is_known_offence(offenders: &[T::KeyOwnerIdentification], time_slot: &SlotNumber) -> bool { + R::is_known_offence(offenders, time_slot) + } + + fn submit_unsigned_equivocation_report( + equivocation_proof: EquivocationProof, + key_owner_proof: T::KeyOwnerProof, + ) -> DispatchResult { + use frame_system::offchain::SubmitTransaction; + + let call = Call::report_equivocation_unsigned(equivocation_proof, key_owner_proof); + + match SubmitTransaction::>::submit_unsigned_transaction(call.into()) { + Ok(()) => debug::info!("Submitted BABE equivocation report."), + Err(e) => debug::error!("Error submitting equivocation report: {:?}", e), + } + + Ok(()) + } + + fn block_author() -> Option { + Some(>::author()) + } +} + +/// A `ValidateUnsigned` implementation that restricts calls to `report_equivocation_unsigned` +/// to local calls (i.e. extrinsics generated on this node) or that already in a block. This +/// guarantees that only block authors can include unsigned equivocation reports. +impl frame_support::unsigned::ValidateUnsigned for Module { + type Call = Call; + fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { + if let Call::report_equivocation_unsigned(equivocation_proof, _) = call { + // discard equivocation report not coming from the local node + match source { + TransactionSource::Local | TransactionSource::InBlock => { /* allowed */ } + _ => { + debug::warn!( + target: "babe", + "rejecting unsigned report equivocation transaction because it is not local/in-block." + ); + + return InvalidTransaction::Call.into(); + } + } + + ValidTransaction::with_tag_prefix("BabeEquivocation") + // We assign the maximum priority for any equivocation report. + .priority(TransactionPriority::max_value()) + // Only one equivocation report for the same offender at the same slot. + .and_provides(( + equivocation_proof.offender.clone(), + equivocation_proof.slot_number, + )) + // We don't propagate this. This can never be included on a remote node. + .propagate(false) + .build() + } else { + InvalidTransaction::Call.into() + } + } + + fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { + if let Call::report_equivocation_unsigned(equivocation_proof, key_owner_proof) = call { + // check the membership proof to extract the offender's id + let key = ( + sp_consensus_babe::KEY_TYPE, + equivocation_proof.offender.clone(), + ); + + let offender = T::KeyOwnerProofSystem::check_proof(key, key_owner_proof.clone()) + .ok_or(InvalidTransaction::BadProof)?; + + // check if the offence has already been reported, + // and if so then we can discard the report. + let is_known_offence = T::HandleEquivocation::is_known_offence( + &[offender], + &equivocation_proof.slot_number, + ); + + if is_known_offence { + Err(InvalidTransaction::Stale.into()) + } else { + Ok(()) + } + } else { + Err(InvalidTransaction::Call.into()) + } + } +} + +/// A BABE equivocation offence report. +/// +/// When a validator released two or more blocks at the same slot. +pub struct BabeEquivocationOffence { + /// A babe slot number in which this incident happened. + pub slot: SlotNumber, + /// The session index in which the incident happened. + pub session_index: SessionIndex, + /// The size of the validator set at the time of the offence. + pub validator_set_count: u32, + /// The authority that produced the equivocation. + pub offender: FullIdentification, +} + +impl Offence + for BabeEquivocationOffence +{ + const ID: Kind = *b"babe:equivocatio"; + type TimeSlot = SlotNumber; + + fn offenders(&self) -> Vec { + vec![self.offender.clone()] + } + + fn session_index(&self) -> SessionIndex { + self.session_index + } + + fn validator_set_count(&self) -> u32 { + self.validator_set_count + } + + fn time_slot(&self) -> Self::TimeSlot { + self.slot + } + + fn slash_fraction(offenders_count: u32, validator_set_count: u32) -> Perbill { + // the formula is min((3k / n)^2, 1) + let x = Perbill::from_rational_approximation(3 * offenders_count, validator_set_count); + // _ ^ 2 + x.square() + } +} diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index dc704b5bcc338e385c3913f48bca768d316bcda5..f80ac186434d0796387439899f8993eaadaa41f5 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Consensus extension module for BABE consensus. Collects on-chain randomness //! from VRF outputs and manages epoch transitions. @@ -20,37 +21,44 @@ #![cfg_attr(not(feature = "std"), no_std)] #![warn(unused_must_use, unsafe_code, unused_variables, unused_must_use)] -use pallet_timestamp; - -use sp_std::{result, prelude::*}; +use codec::{Decode, Encode}; use frame_support::{ - decl_storage, decl_module, traits::{FindAuthor, Get, Randomness as RandomnessT}, + decl_error, decl_module, decl_storage, + traits::{FindAuthor, Get, KeyOwnerProofSystem, Randomness as RandomnessT}, weights::Weight, + Parameter, }; -use sp_timestamp::OnTimestampSet; -use sp_runtime::{generic::DigestItem, ConsensusEngineId, Perbill}; -use sp_runtime::traits::{IsMember, SaturatedConversion, Saturating, Hash, One}; -use sp_staking::{ - SessionIndex, - offence::{Offence, Kind}, -}; +use frame_system::{ensure_none, ensure_signed}; use sp_application_crypto::Public; +use sp_runtime::{ + generic::DigestItem, + traits::{Hash, IsMember, One, SaturatedConversion, Saturating}, + ConsensusEngineId, KeyTypeId, +}; +use sp_session::{GetSessionNumber, GetValidatorCount}; +use sp_std::{prelude::*, result}; +use sp_timestamp::OnTimestampSet; -use codec::{Encode, Decode}; -use sp_inherents::{InherentIdentifier, InherentData, ProvideInherent, MakeFatalError}; use sp_consensus_babe::{ - BABE_ENGINE_ID, ConsensusLog, BabeAuthorityWeight, SlotNumber, - inherents::{INHERENT_IDENTIFIER, BabeInherentData}, - digests::{NextEpochDescriptor, PreDigest}, + digests::{NextConfigDescriptor, NextEpochDescriptor, PreDigest}, + inherents::{BabeInherentData, INHERENT_IDENTIFIER}, + BabeAuthorityWeight, ConsensusLog, EquivocationProof, SlotNumber, BABE_ENGINE_ID, }; use sp_consensus_vrf::schnorrkel; -pub use sp_consensus_babe::{AuthorityId, VRF_OUTPUT_LENGTH, RANDOMNESS_LENGTH, PUBLIC_KEY_LENGTH}; +use sp_inherents::{InherentData, InherentIdentifier, MakeFatalError, ProvideInherent}; -#[cfg(all(feature = "std", test))] -mod tests; +pub use sp_consensus_babe::{AuthorityId, PUBLIC_KEY_LENGTH, RANDOMNESS_LENGTH, VRF_OUTPUT_LENGTH}; +mod equivocation; + +#[cfg(any(feature = "runtime-benchmarks", test))] +mod benchmarking; #[cfg(all(feature = "std", test))] mod mock; +#[cfg(all(feature = "std", test))] +mod tests; + +pub use equivocation::{BabeEquivocationOffence, EquivocationHandler, HandleEquivocation}; pub trait Trait: pallet_timestamp::Trait { /// The amount of time, in slots, that each epoch should last. @@ -69,6 +77,30 @@ pub trait Trait: pallet_timestamp::Trait { /// Typically, the `ExternalTrigger` type should be used. An internal trigger should only be used /// when no other module is responsible for changing authority set. type EpochChangeTrigger: EpochChangeTrigger; + + /// The proof of key ownership, used for validating equivocation reports. + /// The proof must include the session index and validator count of the + /// session at which the equivocation occurred. + type KeyOwnerProof: Parameter + GetSessionNumber + GetValidatorCount; + + /// The identification of a key owner, used when reporting equivocations. + type KeyOwnerIdentification: Parameter; + + /// A system for proving ownership of keys, i.e. that a given key was part + /// of a validator set, needed for validating equivocation reports. + type KeyOwnerProofSystem: KeyOwnerProofSystem< + (KeyTypeId, AuthorityId), + Proof = Self::KeyOwnerProof, + IdentificationTuple = Self::KeyOwnerIdentification, + >; + + /// The equivocation handling subsystem, defines methods to report an + /// offence (after the equivocation has been validated) and for submitting a + /// transaction to report an equivocation (from an offchain context). + /// NOTE: when enabling equivocation handling (i.e. this type isn't set to + /// `()`) you must use this pallet's `ValidateUnsigned` in the runtime + /// definition. + type HandleEquivocation: HandleEquivocation; } /// Trigger an epoch change, if any should take place. @@ -105,6 +137,17 @@ const UNDER_CONSTRUCTION_SEGMENT_LENGTH: usize = 256; type MaybeRandomness = Option; +decl_error! { + pub enum Error for Module { + /// An equivocation proof provided as part of an equivocation report is invalid. + InvalidEquivocationProof, + /// A key ownership proof provided as part of an equivocation report is invalid. + InvalidKeyOwnershipProof, + /// A given equivocation report is valid but already previously reported. + DuplicateOffenceReport, + } +} + decl_storage! { trait Store for Module as Babe { /// Current epoch index. @@ -135,6 +178,9 @@ decl_storage! { // variable to its underlying value. pub Randomness get(fn randomness): schnorrkel::Randomness; + /// Next epoch configuration, if changed. + NextEpochConfig: Option; + /// Next epoch randomness. NextRandomness: schnorrkel::Randomness; @@ -148,6 +194,8 @@ decl_storage! { /// We reset all segments and return to `0` at the beginning of every /// epoch. SegmentIndex build(|_| 0): u32; + + /// TWOX-NOTE: `SegmentIndex` is an increasing integer, so this is okay. UnderConstruction: map hasher(twox_64_concat) u32 => Vec; /// Temporary value (cleared at block finalization) which is `Some` @@ -202,6 +250,69 @@ decl_module! { // remove temporary "environment" entry from storage Lateness::::kill(); } + + /// Report authority equivocation/misbehavior. This method will verify + /// the equivocation proof and validate the given key ownership proof + /// against the extracted offender. If both are valid, the offence will + /// be reported. + #[weight = weight::weight_for_report_equivocation::()] + fn report_equivocation( + origin, + equivocation_proof: EquivocationProof, + key_owner_proof: T::KeyOwnerProof, + ) { + let reporter = ensure_signed(origin)?; + + Self::do_report_equivocation( + Some(reporter), + equivocation_proof, + key_owner_proof, + )?; + } + + /// Report authority equivocation/misbehavior. This method will verify + /// the equivocation proof and validate the given key ownership proof + /// against the extracted offender. If both are valid, the offence will + /// be reported. + /// This extrinsic must be called unsigned and it is expected that only + /// block authors will call it (validated in `ValidateUnsigned`), as such + /// if the block author is defined it will be defined as the equivocation + /// reporter. + #[weight = weight::weight_for_report_equivocation::()] + fn report_equivocation_unsigned( + origin, + equivocation_proof: EquivocationProof, + key_owner_proof: T::KeyOwnerProof, + ) { + ensure_none(origin)?; + + Self::do_report_equivocation( + T::HandleEquivocation::block_author(), + equivocation_proof, + key_owner_proof, + )?; + } + } +} + +mod weight { + use frame_support::{ + traits::Get, + weights::{constants::WEIGHT_PER_MICROS, Weight}, + }; + + pub fn weight_for_report_equivocation() -> Weight { + // checking membership proof + (35 * WEIGHT_PER_MICROS) + .saturating_add(T::DbWeight::get().reads(5)) + // check equivocation proof + .saturating_add(110 * WEIGHT_PER_MICROS) + // report offence + .saturating_add(110 * WEIGHT_PER_MICROS) + // worst case we are considering is that the given offender + // is backed by 200 nominators + .saturating_add(T::DbWeight::get().reads(14 + 3 * 200)) + .saturating_add(T::DbWeight::get().writes(10 + 3 * 200)) } } @@ -268,51 +379,6 @@ impl pallet_session::ShouldEndSession for Module { } } -/// A BABE equivocation offence report. -/// -/// When a validator released two or more blocks at the same slot. -pub struct BabeEquivocationOffence { - /// A babe slot number in which this incident happened. - pub slot: u64, - /// The session index in which the incident happened. - pub session_index: SessionIndex, - /// The size of the validator set at the time of the offence. - pub validator_set_count: u32, - /// The authority that produced the equivocation. - pub offender: FullIdentification, -} - -impl Offence for BabeEquivocationOffence { - const ID: Kind = *b"babe:equivocatio"; - type TimeSlot = u64; - - fn offenders(&self) -> Vec { - vec![self.offender.clone()] - } - - fn session_index(&self) -> SessionIndex { - self.session_index - } - - fn validator_set_count(&self) -> u32 { - self.validator_set_count - } - - fn time_slot(&self) -> Self::TimeSlot { - self.slot - } - - fn slash_fraction( - offenders_count: u32, - validator_set_count: u32, - ) -> Perbill { - // the formula is min((3k / n)^2, 1) - let x = Perbill::from_rational_approximation(3 * offenders_count, validator_set_count); - // _ ^ 2 - x.square() - } -} - impl Module { /// Determine the BABE slot duration based on the Timestamp module configuration. pub fn slot_duration() -> T::Moment { @@ -349,6 +415,9 @@ impl Module { // -------------- IMPORTANT NOTE -------------- // This implementation is linked to how [`should_epoch_change`] is working. This might need to // be updated accordingly, if the underlying mechanics of slot and epochs change. + // + // WEIGHT NOTE: This function is tied to the weight of `EstimateNextSessionRotation`. If you update + // this function, you must also update the corresponding weight. pub fn next_expected_epoch_change(now: T::BlockNumber) -> Option { let next_slot = Self::current_epoch_start().saturating_add(T::EpochDuration::get()); next_slot @@ -360,6 +429,15 @@ impl Module { }) } + /// Plan an epoch config change. The epoch config change is recorded and will be enacted on the + /// next call to `enact_epoch_change`. The config will be activated one epoch after. Multiple calls to this + /// method will replace any existing planned config change that had not been enacted yet. + pub fn plan_config_change( + config: NextConfigDescriptor, + ) { + NextEpochConfig::put(config); + } + /// DANGEROUS: Enact an epoch change. Should be done on every block where `should_epoch_change` has returned `true`, /// and the caller is the only caller of this function. /// @@ -395,12 +473,15 @@ impl Module { // so that nodes can track changes. let next_randomness = NextRandomness::get(); - let next = NextEpochDescriptor { + let next_epoch = NextEpochDescriptor { authorities: next_authorities, randomness: next_randomness, }; + Self::deposit_consensus(ConsensusLog::NextEpochData(next_epoch)); - Self::deposit_consensus(ConsensusLog::NextEpochData(next)) + if let Some(next_config) = NextEpochConfig::take() { + Self::deposit_consensus(ConsensusLog::NextConfigData(next_config)); + } } // finds the start slot of the current epoch. only guaranteed to @@ -540,6 +621,69 @@ impl Module { Authorities::put(authorities); } } + + fn do_report_equivocation( + reporter: Option, + equivocation_proof: EquivocationProof, + key_owner_proof: T::KeyOwnerProof, + ) -> Result<(), Error> { + let offender = equivocation_proof.offender.clone(); + let slot_number = equivocation_proof.slot_number; + + // validate the equivocation proof + if !sp_consensus_babe::check_equivocation_proof(equivocation_proof) { + return Err(Error::InvalidEquivocationProof.into()); + } + + let validator_set_count = key_owner_proof.validator_count(); + let session_index = key_owner_proof.session(); + + let epoch_index = (slot_number.saturating_sub(GenesisSlot::get()) / T::EpochDuration::get()) + .saturated_into::(); + + // check that the slot number is consistent with the session index + // in the key ownership proof (i.e. slot is for that epoch) + if epoch_index != session_index { + return Err(Error::InvalidKeyOwnershipProof.into()); + } + + // check the membership proof and extract the offender's id + let key = (sp_consensus_babe::KEY_TYPE, offender); + let offender = T::KeyOwnerProofSystem::check_proof(key, key_owner_proof) + .ok_or(Error::InvalidKeyOwnershipProof)?; + + let offence = BabeEquivocationOffence { + slot: slot_number, + validator_set_count, + offender, + session_index, + }; + + let reporters = match reporter { + Some(id) => vec![id], + None => vec![], + }; + + T::HandleEquivocation::report_offence(reporters, offence) + .map_err(|_| Error::DuplicateOffenceReport)?; + + Ok(()) + } + + /// Submits an extrinsic to report an equivocation. This method will create + /// an unsigned extrinsic with a call to `report_equivocation_unsigned` and + /// will push the transaction to the pool. Only useful in an offchain + /// context. + pub fn submit_unsigned_equivocation_report( + equivocation_proof: EquivocationProof, + key_owner_proof: T::KeyOwnerProof, + ) -> Option<()> { + T::HandleEquivocation::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + .ok() + } } impl OnTimestampSet for Module { @@ -550,6 +694,12 @@ impl frame_support::traits::EstimateNextSessionRotation Option { Self::next_expected_epoch_change(now) } + + // The validity of this weight depends on the implementation of `estimate_next_session_rotation` + fn weight(_now: T::BlockNumber) -> Weight { + // Read: Current Slot, Epoch Index, Genesis Slot + T::DbWeight::get().reads(3) + } } impl frame_support::traits::Lateness for Module { diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 933c69c98ab6011cd8c0278ad253ae8e900e61e4..8a0356d8da7e8596dec5b155522fd0f7b5e78a43 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -1,43 +1,54 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Test utilities use codec::Encode; -use super::{Trait, Module, GenesisConfig, CurrentSlot}; +use super::{Trait, Module, CurrentSlot}; use sp_runtime::{ Perbill, impl_opaque_keys, - testing::{Header, UintAuthorityId, Digest, DigestItem}, - traits::IdentityLookup, + curve::PiecewiseLinear, + testing::{Digest, DigestItem, Header, TestXt,}, + traits::{Convert, Header as _, IdentityLookup, OpaqueKeys, SaturatedConversion}, }; use frame_system::InitKind; use frame_support::{ - impl_outer_origin, parameter_types, StorageValue, - traits::OnInitialize, + impl_outer_dispatch, impl_outer_origin, parameter_types, StorageValue, + traits::{KeyOwnerProofSystem, OnInitialize}, weights::Weight, }; use sp_io; -use sp_core::{H256, U256, crypto::Pair}; -use sp_consensus_babe::AuthorityPair; +use sp_core::{H256, U256, crypto::{KeyTypeId, Pair}}; +use sp_consensus_babe::{AuthorityId, AuthorityPair, SlotNumber}; use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof}; +use sp_staking::SessionIndex; +use pallet_staking::EraIndex; impl_outer_origin!{ pub enum Origin for Test where system = frame_system {} } +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + babe::Babe, + staking::Staking, + } +} + type DummyValidatorId = u64; // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. @@ -49,17 +60,17 @@ parameter_types! { pub const MaximumBlockWeight: Weight = 1024; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub const MinimumPeriod: u64 = 1; pub const EpochDuration: u64 = 3; pub const ExpectedBlockTime: u64 = 1; pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(16); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; - type Call = (); + type Call = Call; type Hash = H256; type Version = (); type Hashing = sp_runtime::traits::BlakeTwo256; @@ -72,65 +83,209 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type ModuleToIndex = (); - type AccountData = (); + type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); +} + +impl frame_system::offchain::SendTransactionTypes for Test +where + Call: From, +{ + type OverarchingCall = Call; + type Extrinsic = TestXt; } impl_opaque_keys! { pub struct MockSessionKeys { - pub dummy: UintAuthorityId, + pub babe_authority: super::Module, } } impl pallet_session::Trait for Test { type Event = (); type ValidatorId = ::AccountId; + type ValidatorIdOf = pallet_staking::StashOf; type ShouldEndSession = Babe; - type SessionHandler = (Babe,); - type SessionManager = (); - type ValidatorIdOf = (); + type NextSessionRotation = Babe; + type SessionManager = pallet_session::historical::NoteHistoricalRoot; + type SessionHandler = ::KeyTypeIdProviders; type Keys = MockSessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; - type NextSessionRotation = Babe; + type WeightInfo = (); +} + +impl pallet_session::historical::Trait for Test { + type FullIdentification = pallet_staking::Exposure; + type FullIdentificationOf = pallet_staking::ExposureOf; +} + +parameter_types! { + pub const UncleGenerations: u64 = 0; +} + +impl pallet_authorship::Trait for Test { + type FindAuthor = pallet_session::FindAccountFromAuthorIndex; + type UncleGenerations = UncleGenerations; + type FilterUncle = (); + type EventHandler = (); +} + +parameter_types! { + pub const MinimumPeriod: u64 = 1; } impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = Babe; type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +parameter_types! { + pub const ExistentialDeposit: u128 = 1; +} + +impl pallet_balances::Trait for Test { + type Balance = u128; + type DustRemoval = (); + type Event = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} + +pallet_staking_reward_curve::build! { + const REWARD_CURVE: PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000u64, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} + +parameter_types! { + pub const SessionsPerEra: SessionIndex = 3; + pub const BondingDuration: EraIndex = 3; + pub const SlashDeferDuration: EraIndex = 0; + pub const AttestationPeriod: u64 = 100; + pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE; + pub const MaxNominatorRewardedPerValidator: u32 = 64; + pub const ElectionLookahead: u64 = 0; + pub const StakingUnsignedPriority: u64 = u64::max_value() / 2; +} + +pub struct CurrencyToVoteHandler; + +impl Convert for CurrencyToVoteHandler { + fn convert(x: u128) -> u128 { + x + } +} + +impl Convert for CurrencyToVoteHandler { + fn convert(x: u128) -> u64 { + x.saturated_into() + } +} + +impl pallet_staking::Trait for Test { + type RewardRemainder = (); + type CurrencyToVote = CurrencyToVoteHandler; + type Event = (); + type Currency = Balances; + type Slash = (); + type Reward = (); + type SessionsPerEra = SessionsPerEra; + type BondingDuration = BondingDuration; + type SlashDeferDuration = SlashDeferDuration; + type SlashCancelOrigin = frame_system::EnsureRoot; + type SessionInterface = Self; + type UnixTime = pallet_timestamp::Module; + type RewardCurve = RewardCurve; + type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; + type NextNewSession = Session; + type ElectionLookahead = ElectionLookahead; + type Call = Call; + type UnsignedPriority = StakingUnsignedPriority; + type MaxIterations = (); + type MinSolutionScoreBump = (); + type WeightInfo = (); +} + +parameter_types! { + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); +} + +impl pallet_offences::Trait for Test { + type Event = (); + type IdentificationTuple = pallet_session::historical::IdentificationTuple; + type OnOffenceHandler = Staking; + type WeightSoftLimit = OffencesWeightSoftLimit; + type WeightInfo = (); } impl Trait for Test { type EpochDuration = EpochDuration; type ExpectedBlockTime = ExpectedBlockTime; type EpochChangeTrigger = crate::ExternalTrigger; -} -pub fn new_test_ext(authorities_len: usize) -> (Vec, sp_io::TestExternalities) { - let pairs = (0..authorities_len).map(|i| { - AuthorityPair::from_seed(&U256::from(i).into()) - }).collect::>(); + type KeyOwnerProofSystem = Historical; + + type KeyOwnerProof = + >::Proof; + + type KeyOwnerIdentification = >::IdentificationTuple; - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - GenesisConfig { - authorities: pairs.iter().map(|a| (a.public(), 1)).collect(), - }.assimilate_storage::(&mut t).unwrap(); - (pairs, t.into()) + type HandleEquivocation = super::EquivocationHandler; } +pub type Balances = pallet_balances::Module; +pub type Historical = pallet_session::historical::Module; +pub type Offences = pallet_offences::Module; +pub type Session = pallet_session::Module; +pub type Staking = pallet_staking::Module; +pub type System = frame_system::Module; +pub type Timestamp = pallet_timestamp::Module; +pub type Babe = Module; + pub fn go_to_block(n: u64, s: u64) { + use frame_support::traits::OnFinalize; + + System::on_finalize(System::block_number()); + Session::on_finalize(System::block_number()); + Staking::on_finalize(System::block_number()); + + let parent_hash = if System::block_number() > 1 { + let hdr = System::finalize(); + hdr.hash() + } else { + System::parent_hash() + }; + let pre_digest = make_secondary_plain_pre_digest(0, s); - System::initialize(&n, &Default::default(), &Default::default(), &pre_digest, InitKind::Full); + + System::initialize(&n, &parent_hash, &Default::default(), &pre_digest, InitKind::Full); System::set_block_number(n); + Timestamp::set_timestamp(n); + if s > 1 { CurrentSlot::put(s); } - // includes a call into `Babe::do_initialize`. + + System::on_initialize(n); Session::on_initialize(n); + Staking::on_initialize(n); } /// Slots will grow accordingly to blocks @@ -142,6 +297,19 @@ pub fn progress_to_block(n: u64) { } } +/// Progress to the first block at the given session +pub fn start_session(session_index: SessionIndex) { + let missing = (session_index - Session::current_index()) * 3; + progress_to_block(System::block_number() + missing as u64 + 1); + assert_eq!(Session::current_index(), session_index); +} + +/// Progress to the first block at the given era +pub fn start_era(era_index: EraIndex) { + start_session((era_index * 3).into()); + assert_eq!(Staking::current_era(), Some(era_index)); +} + pub fn make_pre_digest( authority_index: sp_consensus_babe::AuthorityIndex, slot_number: sp_consensus_babe::SlotNumber, @@ -174,6 +342,124 @@ pub fn make_secondary_plain_pre_digest( Digest { logs: vec![log] } } -pub type System = frame_system::Module; -pub type Babe = Module; -pub type Session = pallet_session::Module; +pub fn new_test_ext(authorities_len: usize) -> sp_io::TestExternalities { + new_test_ext_with_pairs(authorities_len).1 +} + +pub fn new_test_ext_with_pairs(authorities_len: usize) -> (Vec, sp_io::TestExternalities) { + let pairs = (0..authorities_len).map(|i| { + AuthorityPair::from_seed(&U256::from(i).into()) + }).collect::>(); + + let public = pairs.iter().map(|p| p.public()).collect(); + + (pairs, new_test_ext_raw_authorities(public)) +} + +pub fn new_test_ext_raw_authorities(authorities: Vec) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + // stashes are the index. + let session_keys: Vec<_> = authorities + .iter() + .enumerate() + .map(|(i, k)| { + ( + i as u64, + i as u64, + MockSessionKeys { + babe_authority: AuthorityId::from(k.clone()), + }, + ) + }) + .collect(); + + // controllers are the index + 1000 + let stakers: Vec<_> = (0..authorities.len()) + .map(|i| { + ( + i as u64, + i as u64 + 1000, + 10_000, + pallet_staking::StakerStatus::::Validator, + ) + }) + .collect(); + + let balances: Vec<_> = (0..authorities.len()) + .map(|i| (i as u64, 10_000_000)) + .collect(); + + // NOTE: this will initialize the babe authorities + // through OneSessionHandler::on_genesis_session + pallet_session::GenesisConfig:: { keys: session_keys } + .assimilate_storage(&mut t) + .unwrap(); + + pallet_balances::GenesisConfig:: { balances } + .assimilate_storage(&mut t) + .unwrap(); + + let staking_config = pallet_staking::GenesisConfig:: { + stakers, + validator_count: 8, + force_era: pallet_staking::Forcing::ForceNew, + minimum_validator_count: 0, + invulnerables: vec![], + ..Default::default() + }; + + staking_config.assimilate_storage(&mut t).unwrap(); + + t.into() +} + +/// Creates an equivocation at the current block, by generating two headers. +pub fn generate_equivocation_proof( + offender_authority_index: u32, + offender_authority_pair: &AuthorityPair, + slot_number: SlotNumber, +) -> sp_consensus_babe::EquivocationProof
{ + use sp_consensus_babe::digests::CompatibleDigestItem; + + let current_block = System::block_number(); + let current_slot = CurrentSlot::get(); + + let make_header = || { + let parent_hash = System::parent_hash(); + let pre_digest = make_secondary_plain_pre_digest(offender_authority_index, slot_number); + System::initialize(¤t_block, &parent_hash, &Default::default(), &pre_digest, InitKind::Full); + System::set_block_number(current_block); + Timestamp::set_timestamp(current_block); + System::finalize() + }; + + // sign the header prehash and sign it, adding it to the block as the seal + // digest item + let seal_header = |header: &mut Header| { + let prehash = header.hash(); + let seal = ::babe_seal( + offender_authority_pair.sign(prehash.as_ref()), + ); + header.digest_mut().push(seal); + }; + + // generate two headers at the current block + let mut h1 = make_header(); + let mut h2 = make_header(); + + seal_header(&mut h1); + seal_header(&mut h2); + + // restore previous runtime state + go_to_block(current_block, current_slot); + + sp_consensus_babe::EquivocationProof { + slot_number, + offender: offender_authority_pair.public(), + first_header: h1, + second_header: h2, + } +} diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index af2ecd1e1a0af2b13dc778140d3e2ec1c6b48f9a..bdd6748c3b3516c33c3b3db1420a5cda7b07f1bc 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -1,27 +1,32 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Consensus extension module tests for BABE consensus. -use super::*; +use super::{Call, *}; +use frame_support::{ + assert_err, assert_ok, + traits::{Currency, OnFinalize}, +}; use mock::*; -use frame_support::traits::OnFinalize; use pallet_session::ShouldEndSession; -use sp_core::crypto::IsWrappedBy; +use sp_consensus_babe::AllowedSlots; use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof}; +use sp_core::crypto::{IsWrappedBy, Pair}; const EMPTY_RANDOMNESS: [u8; 32] = [ 74, 25, 49, 128, 53, 97, 244, 49, @@ -38,14 +43,14 @@ fn empty_randomness_is_correct() { #[test] fn initial_values() { - new_test_ext(4).1.execute_with(|| { + new_test_ext(4).execute_with(|| { assert_eq!(Babe::authorities().len(), 4) }) } #[test] fn check_module() { - new_test_ext(4).1.execute_with(|| { + new_test_ext(4).execute_with(|| { assert!(!Babe::should_end_session(0), "Genesis does not change sessions"); assert!(!Babe::should_end_session(200000), "BABE does not include the block number in epoch calculations"); @@ -54,7 +59,7 @@ fn check_module() { #[test] fn first_block_epoch_zero_start() { - let (pairs, mut ext) = new_test_ext(4); + let (pairs, mut ext) = new_test_ext_with_pairs(4); ext.execute_with(|| { let genesis_slot = 100; @@ -122,7 +127,7 @@ fn first_block_epoch_zero_start() { #[test] fn authority_index() { - new_test_ext(4).1.execute_with(|| { + new_test_ext(4).execute_with(|| { assert_eq!( Babe::find_author((&[(BABE_ENGINE_ID, &[][..])]).into_iter().cloned()), None, "Trivially invalid authorities are ignored") @@ -131,7 +136,7 @@ fn authority_index() { #[test] fn can_predict_next_epoch_change() { - new_test_ext(0).1.execute_with(|| { + new_test_ext(1).execute_with(|| { assert_eq!(::EpochDuration::get(), 3); // this sets the genesis slot to 6; go_to_block(1, 6); @@ -149,3 +154,434 @@ fn can_predict_next_epoch_change() { assert_eq!(Babe::next_expected_epoch_change(System::block_number()), Some(5 + 2)); }) } + +#[test] +fn can_enact_next_config() { + new_test_ext(1).execute_with(|| { + assert_eq!(::EpochDuration::get(), 3); + // this sets the genesis slot to 6; + go_to_block(1, 6); + assert_eq!(Babe::genesis_slot(), 6); + assert_eq!(Babe::current_slot(), 6); + assert_eq!(Babe::epoch_index(), 0); + go_to_block(2, 7); + + Babe::plan_config_change(NextConfigDescriptor::V1 { + c: (1, 4), + allowed_slots: AllowedSlots::PrimarySlots, + }); + + progress_to_block(4); + Babe::on_finalize(9); + let header = System::finalize(); + + let consensus_log = sp_consensus_babe::ConsensusLog::NextConfigData( + sp_consensus_babe::digests::NextConfigDescriptor::V1 { + c: (1, 4), + allowed_slots: AllowedSlots::PrimarySlots, + } + ); + let consensus_digest = DigestItem::Consensus(BABE_ENGINE_ID, consensus_log.encode()); + + assert_eq!(header.digest.logs[2], consensus_digest.clone()) + }); +} + +#[test] +fn report_equivocation_current_session_works() { + let (pairs, mut ext) = new_test_ext_with_pairs(3); + + ext.execute_with(|| { + start_era(1); + + let authorities = Babe::authorities(); + let validators = Session::validators(); + + // make sure that all authorities have the same balance + for validator in &validators { + assert_eq!(Balances::total_balance(validator), 10_000_000); + assert_eq!(Staking::slashable_balance_of(validator), 10_000); + + assert_eq!( + Staking::eras_stakers(1, validator), + pallet_staking::Exposure { + total: 10_000, + own: 10_000, + others: vec![], + }, + ); + } + + // we will use the validator at index 0 as the offending authority + let offending_validator_index = 0; + let offending_validator_id = Session::validators()[offending_validator_index]; + let offending_authority_pair = pairs + .into_iter() + .find(|p| p.public() == authorities[offending_validator_index].0) + .unwrap(); + + // generate an equivocation proof. it creates two headers at the given + // slot with different block hashes and signed by the given key + let equivocation_proof = generate_equivocation_proof( + offending_validator_index as u32, + &offending_authority_pair, + CurrentSlot::get(), + ); + + // create the key ownership proof + let key = ( + sp_consensus_babe::KEY_TYPE, + &offending_authority_pair.public(), + ); + let key_owner_proof = Historical::prove(key).unwrap(); + + // report the equivocation + Babe::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof) + .unwrap(); + + // start a new era so that the results of the offence report + // are applied at era end + start_era(2); + + // check that the balance of offending validator is slashed 100%. + assert_eq!( + Balances::total_balance(&offending_validator_id), + 10_000_000 - 10_000 + ); + assert_eq!(Staking::slashable_balance_of(&offending_validator_id), 0); + assert_eq!( + Staking::eras_stakers(2, offending_validator_id), + pallet_staking::Exposure { + total: 0, + own: 0, + others: vec![], + }, + ); + + // check that the balances of all other validators are left intact. + for validator in &validators { + if *validator == offending_validator_id { + continue; + } + + assert_eq!(Balances::total_balance(validator), 10_000_000); + assert_eq!(Staking::slashable_balance_of(validator), 10_000); + assert_eq!( + Staking::eras_stakers(2, validator), + pallet_staking::Exposure { + total: 10_000, + own: 10_000, + others: vec![], + }, + ); + } + }) +} + +#[test] +fn report_equivocation_old_session_works() { + let (pairs, mut ext) = new_test_ext_with_pairs(3); + + ext.execute_with(|| { + start_era(1); + + let authorities = Babe::authorities(); + + // we will use the validator at index 0 as the offending authority + let offending_validator_index = 0; + let offending_validator_id = Session::validators()[offending_validator_index]; + let offending_authority_pair = pairs + .into_iter() + .find(|p| p.public() == authorities[offending_validator_index].0) + .unwrap(); + + // generate an equivocation proof at the current slot + let equivocation_proof = generate_equivocation_proof( + offending_validator_index as u32, + &offending_authority_pair, + CurrentSlot::get(), + ); + + // create the key ownership proof + let key = ( + sp_consensus_babe::KEY_TYPE, + &offending_authority_pair.public(), + ); + let key_owner_proof = Historical::prove(key).unwrap(); + + // start a new era and report the equivocation + // from the previous era + start_era(2); + + // check the balance of the offending validator + assert_eq!(Balances::total_balance(&offending_validator_id), 10_000_000); + assert_eq!( + Staking::slashable_balance_of(&offending_validator_id), + 10_000 + ); + + // report the equivocation + Babe::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof) + .unwrap(); + + // start a new era so that the results of the offence report + // are applied at era end + start_era(3); + + // check that the balance of offending validator is slashed 100%. + assert_eq!( + Balances::total_balance(&offending_validator_id), + 10_000_000 - 10_000 + ); + assert_eq!(Staking::slashable_balance_of(&offending_validator_id), 0); + assert_eq!( + Staking::eras_stakers(3, offending_validator_id), + pallet_staking::Exposure { + total: 0, + own: 0, + others: vec![], + }, + ); + }) +} + +#[test] +fn report_equivocation_invalid_key_owner_proof() { + let (pairs, mut ext) = new_test_ext_with_pairs(3); + + ext.execute_with(|| { + start_era(1); + + let authorities = Babe::authorities(); + + // we will use the validator at index 0 as the offending authority + let offending_validator_index = 0; + let offending_authority_pair = pairs + .into_iter() + .find(|p| p.public() == authorities[offending_validator_index].0) + .unwrap(); + + // generate an equivocation proof at the current slot + let equivocation_proof = generate_equivocation_proof( + offending_validator_index as u32, + &offending_authority_pair, + CurrentSlot::get(), + ); + + // create the key ownership proof + let key = ( + sp_consensus_babe::KEY_TYPE, + &offending_authority_pair.public(), + ); + let mut key_owner_proof = Historical::prove(key).unwrap(); + + // we change the session index in the key ownership proof + // which should make it invalid + key_owner_proof.session = 0; + assert_err!( + Babe::report_equivocation_unsigned( + Origin::none(), + equivocation_proof.clone(), + key_owner_proof + ), + Error::::InvalidKeyOwnershipProof, + ); + + // it should fail as well if we create a key owner proof + // for a different authority than the offender + let key = (sp_consensus_babe::KEY_TYPE, &authorities[1].0); + let key_owner_proof = Historical::prove(key).unwrap(); + + // we need to progress to a new era to make sure that the key + // ownership proof is properly checked, otherwise since the state + // is still available the historical module will just check + // against current session data. + start_era(2); + + assert_err!( + Babe::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof), + Error::::InvalidKeyOwnershipProof, + ); + }) +} + +#[test] +fn report_equivocation_invalid_equivocation_proof() { + use sp_runtime::traits::Header; + + let (pairs, mut ext) = new_test_ext_with_pairs(3); + + ext.execute_with(|| { + start_era(1); + + let authorities = Babe::authorities(); + + // we will use the validator at index 0 as the offending authority + let offending_validator_index = 0; + let offending_authority_pair = pairs + .into_iter() + .find(|p| p.public() == authorities[offending_validator_index].0) + .unwrap(); + + // create the key ownership proof + let key = ( + sp_consensus_babe::KEY_TYPE, + &offending_authority_pair.public(), + ); + let key_owner_proof = Historical::prove(key).unwrap(); + + let assert_invalid_equivocation = |equivocation_proof| { + assert_err!( + Babe::report_equivocation_unsigned( + Origin::none(), + equivocation_proof, + key_owner_proof.clone(), + ), + Error::::InvalidEquivocationProof, + ) + }; + + // both headers have the same hash, no equivocation. + let mut equivocation_proof = generate_equivocation_proof( + offending_validator_index as u32, + &offending_authority_pair, + CurrentSlot::get(), + ); + equivocation_proof.second_header = equivocation_proof.first_header.clone(); + assert_invalid_equivocation(equivocation_proof); + + // missing preruntime digest from one header + let mut equivocation_proof = generate_equivocation_proof( + offending_validator_index as u32, + &offending_authority_pair, + CurrentSlot::get(), + ); + equivocation_proof.first_header.digest_mut().logs.remove(0); + assert_invalid_equivocation(equivocation_proof); + + // missing seal from one header + let mut equivocation_proof = generate_equivocation_proof( + offending_validator_index as u32, + &offending_authority_pair, + CurrentSlot::get(), + ); + equivocation_proof.first_header.digest_mut().logs.remove(1); + assert_invalid_equivocation(equivocation_proof); + + // invalid slot number in proof compared to runtime digest + let mut equivocation_proof = generate_equivocation_proof( + offending_validator_index as u32, + &offending_authority_pair, + CurrentSlot::get(), + ); + equivocation_proof.slot_number = 0; + assert_invalid_equivocation(equivocation_proof.clone()); + + // different slot numbers in headers + let h1 = equivocation_proof.first_header; + let mut equivocation_proof = generate_equivocation_proof( + offending_validator_index as u32, + &offending_authority_pair, + CurrentSlot::get() + 1, + ); + + // use the header from the previous equivocation generated + // at the previous slot + equivocation_proof.first_header = h1.clone(); + + assert_invalid_equivocation(equivocation_proof.clone()); + + // invalid seal signature + let mut equivocation_proof = generate_equivocation_proof( + offending_validator_index as u32, + &offending_authority_pair, + CurrentSlot::get() + 1, + ); + + // replace the seal digest with the digest from the + // previous header at the previous slot + equivocation_proof.first_header.digest_mut().pop(); + equivocation_proof + .first_header + .digest_mut() + .push(h1.digest().logs().last().unwrap().clone()); + + assert_invalid_equivocation(equivocation_proof.clone()); + }) +} + +#[test] +fn report_equivocation_validate_unsigned_prevents_duplicates() { + use sp_runtime::transaction_validity::{ + InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource, + TransactionValidity, ValidTransaction, + }; + + let (pairs, mut ext) = new_test_ext_with_pairs(3); + + ext.execute_with(|| { + start_era(1); + + let authorities = Babe::authorities(); + + // generate and report an equivocation for the validator at index 0 + let offending_validator_index = 0; + let offending_authority_pair = pairs + .into_iter() + .find(|p| p.public() == authorities[offending_validator_index].0) + .unwrap(); + + let equivocation_proof = generate_equivocation_proof( + offending_validator_index as u32, + &offending_authority_pair, + CurrentSlot::get(), + ); + + let key = ( + sp_consensus_babe::KEY_TYPE, + &offending_authority_pair.public(), + ); + let key_owner_proof = Historical::prove(key).unwrap(); + + let inner = + Call::report_equivocation_unsigned(equivocation_proof.clone(), key_owner_proof.clone()); + + // only local/inblock reports are allowed + assert_eq!( + ::validate_unsigned( + TransactionSource::External, + &inner, + ), + InvalidTransaction::Call.into(), + ); + + // the transaction is valid when passed as local + let tx_tag = (offending_authority_pair.public(), CurrentSlot::get()); + assert_eq!( + ::validate_unsigned( + TransactionSource::Local, + &inner, + ), + TransactionValidity::Ok(ValidTransaction { + priority: TransactionPriority::max_value(), + requires: vec![], + provides: vec![("BabeEquivocation", tx_tag).encode()], + longevity: TransactionLongevity::max_value(), + propagate: false, + }) + ); + + // the pre dispatch checks should also pass + assert_ok!(::pre_dispatch(&inner)); + + // we submit the report + Babe::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof) + .unwrap(); + + // the report should now be considered stale and the transaction is invalid + assert_err!( + ::pre_dispatch(&inner), + InvalidTransaction::Stale, + ); + }); +} diff --git a/frame/balances/Cargo.toml b/frame/balances/Cargo.toml index 769e68112cedb46f89cf7e68462391ee7092378e..3f1a088f8897d993cf83704c7b2472a3022e293a 100644 --- a/frame/balances/Cargo.toml +++ b/frame/balances/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-balances" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet to manage balances" @@ -13,17 +13,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -pallet-transaction-payment = { version = "2.0.0-dev", path = "../transaction-payment" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +pallet-transaction-payment = { version = "2.0.0-rc6", path = "../transaction-payment" } [features] default = ["std"] @@ -31,7 +31,6 @@ std = [ "serde", "codec/std", "sp-std/std", - "sp-io/std", "sp-runtime/std", "frame-benchmarking/std", "frame-support/std", diff --git a/frame/balances/README.md b/frame/balances/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c5c578848faa1e99acb16d3e4d6dfe93d5843bed --- /dev/null +++ b/frame/balances/README.md @@ -0,0 +1,122 @@ +# Balances Module + +The Balances module provides functionality for handling accounts and balances. + +- [`balances::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) +- [`Module`](./struct.Module.html) + +## Overview + +The Balances module provides functions for: + +- Getting and setting free balances. +- Retrieving total, reserved and unreserved balances. +- Repatriating a reserved balance to a beneficiary account that exists. +- Transferring a balance between accounts (when not reserved). +- Slashing an account balance. +- Account creation and removal. +- Managing total issuance. +- Setting and managing locks. + +### Terminology + +- **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents +"dust accounts" from filling storage. When the free plus the reserved balance (i.e. the total balance) + fall below this, then the account is said to be dead; and it loses its functionality as well as any + prior history and all information on it is removed from the chain's state. + No account should ever have a total balance that is strictly between 0 and the existential + deposit (exclusive). If this ever happens, it indicates either a bug in this module or an + erroneous raw mutation of storage. + +- **Total Issuance:** The total number of units in existence in a system. + +- **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its +total balance has become zero (or, strictly speaking, less than the Existential Deposit). + +- **Free Balance:** The portion of a balance that is not reserved. The free balance is the only + balance that matters for most operations. + +- **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. + Reserved balance can still be slashed, but only after all the free balance has been slashed. + +- **Imbalance:** A condition when some funds were credited or debited without equal and opposite accounting +(i.e. a difference between total issuance and account balances). Functions that result in an imbalance will +return an object of the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is +simply dropped, it should automatically maintain any book-keeping such as total issuance.) + +- **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple +locks always operate over the same funds, so they "overlay" rather than "stack". + +### Implementations + +The Balances module provides implementations for the following traits. If these traits provide the functionality +that you need, then you can avoid coupling with the Balances module. + +- [`Currency`](../frame_support/traits/trait.Currency.html): Functions for dealing with a +fungible assets system. +- [`ReservableCurrency`](../frame_support/traits/trait.ReservableCurrency.html): +Functions for dealing with assets that can be reserved from an account. +- [`LockableCurrency`](../frame_support/traits/trait.LockableCurrency.html): Functions for +dealing with accounts that allow liquidity restrictions. +- [`Imbalance`](../frame_support/traits/trait.Imbalance.html): Functions for handling +imbalances between total issuance in the system and account balances. Must be used when a function +creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee). +- [`IsDeadAccount`](../frame_system/trait.IsDeadAccount.html): Determiner to say whether a +given account is unused. + +## Interface + +### Dispatchable Functions + +- `transfer` - Transfer some liquid free balance to another account. +- `set_balance` - Set the balances of a given account. The origin of this call must be root. + +## Usage + +The following examples show how to use the Balances module in your custom module. + +### Examples from the FRAME + +The Contract module uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`: + +```rust +use frame_support::traits::Currency; + +pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; + +``` + +The Staking module uses the `LockableCurrency` trait to lock a stash account's funds: + +```rust +use frame_support::traits::{WithdrawReasons, LockableCurrency}; +use sp_runtime::traits::Bounded; +pub trait Trait: frame_system::Trait { + type Currency: LockableCurrency; +} + +fn update_ledger( + controller: &T::AccountId, + ledger: &StakingLedger +) { + T::Currency::set_lock( + STAKING_ID, + &ledger.stash, + ledger.total, + WithdrawReasons::all() + ); + // >::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here. +} +``` + +## Genesis config + +The Balances module depends on the [`GenesisConfig`](./struct.GenesisConfig.html). + +## Assumptions + +* Total issued balanced of all accounts should be less than `Trait::Balance::max_value()`. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/balances/src/benchmarking.rs b/frame/balances/src/benchmarking.rs index 3c2067559fcf21dcae48356f0acf00685c7844f2..21f43c7c6364083ed7a8bc747e31e3b64d7b9dbd 100644 --- a/frame/balances/src/benchmarking.rs +++ b/frame/balances/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Balances pallet benchmarking. @@ -21,52 +22,46 @@ use super::*; use frame_system::RawOrigin; -use frame_benchmarking::{benchmarks, account}; +use frame_benchmarking::{benchmarks, account, whitelisted_caller}; use sp_runtime::traits::Bounded; use crate::Module as Balances; const SEED: u32 = 0; -const MAX_EXISTENTIAL_DEPOSIT: u32 = 1000; -const MAX_USER_INDEX: u32 = 1000; +// existential deposit multiplier +const ED_MULTIPLIER: u32 = 10; + benchmarks! { - _ { - let e in 2 .. MAX_EXISTENTIAL_DEPOSIT => (); - let u in 1 .. MAX_USER_INDEX => (); - } + _ { } // Benchmark `transfer` extrinsic with the worst possible conditions: // * Transfer will kill the sender account. // * Transfer will create the recipient account. transfer { - let u in ...; - let e in ...; - let existential_deposit = T::ExistentialDeposit::get(); - let caller = account("caller", u, SEED); + let caller = whitelisted_caller(); // Give some multiple of the existential deposit + creation fee + transfer fee - let balance = existential_deposit.saturating_mul(e.into()); + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); let _ = as Currency<_>>::make_free_balance_be(&caller, balance); // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. - let recipient: T::AccountId = account("recipient", u, SEED); + let recipient: T::AccountId = account("recipient", 0, SEED); let recipient_lookup: ::Source = T::Lookup::unlookup(recipient.clone()); - let transfer_amount = existential_deposit.saturating_mul((e - 1).into()) + 1.into(); - }: _(RawOrigin::Signed(caller), recipient_lookup, transfer_amount) + let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1.into(); + }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) verify { + assert_eq!(Balances::::free_balance(&caller), Zero::zero()); assert_eq!(Balances::::free_balance(&recipient), transfer_amount); } // Benchmark `transfer` with the best possible condition: // * Both accounts exist and will continue to exist. + #[extra] transfer_best_case { - let u in ...; - let e in ...; - - let caller = account("caller", u, SEED); - let recipient: T::AccountId = account("recipient", u, SEED); + let caller = whitelisted_caller(); + let recipient: T::AccountId = account("recipient", 0, SEED); let recipient_lookup: ::Source = T::Lookup::unlookup(recipient.clone()); // Give the sender account max funds for transfer (their account will never reasonably be killed). @@ -75,52 +70,80 @@ benchmarks! { // Give the recipient account existential deposit (thus their account already exists). let existential_deposit = T::ExistentialDeposit::get(); let _ = as Currency<_>>::make_free_balance_be(&recipient, existential_deposit); - let transfer_amount = existential_deposit.saturating_mul(e.into()); - }: transfer(RawOrigin::Signed(caller), recipient_lookup, transfer_amount) + let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + }: transfer(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) + verify { + assert!(!Balances::::free_balance(&caller).is_zero()); + assert!(!Balances::::free_balance(&recipient).is_zero()); + } // Benchmark `transfer_keep_alive` with the worst possible condition: // * The recipient account is created. transfer_keep_alive { - let u in ...; - let e in ...; - - let caller = account("caller", u, SEED); - let recipient = account("recipient", u, SEED); - let recipient_lookup: ::Source = T::Lookup::unlookup(recipient); + let caller = whitelisted_caller(); + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup: ::Source = T::Lookup::unlookup(recipient.clone()); // Give the sender account max funds, thus a transfer will not kill account. let _ = as Currency<_>>::make_free_balance_be(&caller, T::Balance::max_value()); let existential_deposit = T::ExistentialDeposit::get(); - let transfer_amount = existential_deposit.saturating_mul(e.into()); - }: _(RawOrigin::Signed(caller), recipient_lookup, transfer_amount) + let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + }: _(RawOrigin::Signed(caller.clone()), recipient_lookup, transfer_amount) + verify { + assert!(!Balances::::free_balance(&caller).is_zero()); + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } // Benchmark `set_balance` coming from ROOT account. This always creates an account. - set_balance { - let u in ...; - let e in ...; - - let user: T::AccountId = account("user", u, SEED); + set_balance_creating { + let user: T::AccountId = account("user", 0, SEED); let user_lookup: ::Source = T::Lookup::unlookup(user.clone()); // Give the user some initial balance. let existential_deposit = T::ExistentialDeposit::get(); - let balance_amount = existential_deposit.saturating_mul(e.into()); + let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); - }: _(RawOrigin::Root, user_lookup, balance_amount, balance_amount) + }: set_balance(RawOrigin::Root, user_lookup, balance_amount, balance_amount) + verify { + assert_eq!(Balances::::free_balance(&user), balance_amount); + assert_eq!(Balances::::reserved_balance(&user), balance_amount); + } // Benchmark `set_balance` coming from ROOT account. This always kills an account. set_balance_killing { - let u in ...; - let e in ...; - - let user: T::AccountId = account("user", u, SEED); + let user: T::AccountId = account("user", 0, SEED); let user_lookup: ::Source = T::Lookup::unlookup(user.clone()); // Give the user some initial balance. let existential_deposit = T::ExistentialDeposit::get(); - let balance_amount = existential_deposit.saturating_mul(e.into()); + let balance_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); let _ = as Currency<_>>::make_free_balance_be(&user, balance_amount); - }: set_balance(RawOrigin::Root, user_lookup, 0.into(), 0.into()) + }: set_balance(RawOrigin::Root, user_lookup, Zero::zero(), Zero::zero()) + verify { + assert!(Balances::::free_balance(&user).is_zero()); + } + + // Benchmark `force_transfer` extrinsic with the worst possible conditions: + // * Transfer will kill the sender account. + // * Transfer will create the recipient account. + force_transfer { + let existential_deposit = T::ExistentialDeposit::get(); + let source: T::AccountId = account("source", 0, SEED); + let source_lookup: ::Source = T::Lookup::unlookup(source.clone()); + + // Give some multiple of the existential deposit + creation fee + transfer fee + let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); + let _ = as Currency<_>>::make_free_balance_be(&source, balance); + + // Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account, and reap this user. + let recipient: T::AccountId = account("recipient", 0, SEED); + let recipient_lookup: ::Source = T::Lookup::unlookup(recipient.clone()); + let transfer_amount = existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1.into(); + }: force_transfer(RawOrigin::Root, source_lookup, recipient_lookup, transfer_amount) + verify { + assert_eq!(Balances::::free_balance(&source), Zero::zero()); + assert_eq!(Balances::::free_balance(&recipient), transfer_amount); + } } #[cfg(test)] @@ -151,9 +174,9 @@ mod tests { } #[test] - fn transfer_set_balance() { + fn transfer_set_balance_creating() { ExtBuilder::default().build().execute_with(|| { - assert_ok!(test_benchmark_set_balance::()); + assert_ok!(test_benchmark_set_balance_creating::()); }); } @@ -163,4 +186,11 @@ mod tests { assert_ok!(test_benchmark_set_balance_killing::()); }); } + + #[test] + fn force_transfer() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_force_transfer::()); + }); + } } diff --git a/frame/balances/src/default_weight.rs b/frame/balances/src/default_weight.rs new file mode 100644 index 0000000000000000000000000000000000000000..47a91996005644a856e5adc68c10c212ce8d38ea --- /dev/null +++ b/frame/balances/src/default_weight.rs @@ -0,0 +1,46 @@ +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Weights for the Balances Pallet + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +impl crate::WeightInfo for () { + fn transfer() -> Weight { + (65949000 as Weight) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn transfer_keep_alive() -> Weight { + (46665000 as Weight) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn set_balance_creating() -> Weight { + (27086000 as Weight) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn set_balance_killing() -> Weight { + (33424000 as Weight) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn force_transfer() -> Weight { + (65343000 as Weight) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } +} diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index b1d88edb0333eb5bae561365fcac0de091667b81..f65ed6b99a6d1c952d452eec5bc83202264e7ddd 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Balances Module //! @@ -153,12 +154,14 @@ mod tests; mod tests_local; mod tests_composite; mod benchmarking; +mod default_weight; use sp_std::prelude::*; use sp_std::{cmp, result, mem, fmt::Debug, ops::BitOr, convert::Infallible}; use codec::{Codec, Encode, Decode}; use frame_support::{ StorageValue, Parameter, decl_event, decl_storage, decl_module, decl_error, ensure, + weights::Weight, traits::{ Currency, OnKilledAccount, OnUnbalanced, TryDrop, StoredMap, WithdrawReason, WithdrawReasons, LockIdentifier, LockableCurrency, ExistenceRequirement, @@ -169,17 +172,24 @@ use frame_support::{ use sp_runtime::{ RuntimeDebug, DispatchResult, DispatchError, traits::{ - Zero, AtLeast32Bit, StaticLookup, Member, CheckedAdd, CheckedSub, + Zero, AtLeast32BitUnsigned, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Saturating, Bounded, }, }; use frame_system::{self as system, ensure_signed, ensure_root}; - pub use self::imbalances::{PositiveImbalance, NegativeImbalance}; +pub trait WeightInfo { + fn transfer() -> Weight; + fn transfer_keep_alive() -> Weight; + fn set_balance_creating() -> Weight; + fn set_balance_killing() -> Weight; + fn force_transfer() -> Weight; +} + pub trait Subtrait: frame_system::Trait { /// The balance of an account. - type Balance: Parameter + Member + AtLeast32Bit + Codec + Default + Copy + + type Balance: Parameter + Member + AtLeast32BitUnsigned + Codec + Default + Copy + MaybeSerializeDeserialize + Debug; /// The minimum amount required to keep an account open. @@ -187,11 +197,14 @@ pub trait Subtrait: frame_system::Trait { /// The means of storing the balances of an account. type AccountStore: StoredMap>; + + /// Weight information for the extrinsics in this pallet. + type WeightInfo: WeightInfo; } pub trait Trait: frame_system::Trait { /// The balance of an account. - type Balance: Parameter + Member + AtLeast32Bit + Codec + Default + Copy + + type Balance: Parameter + Member + AtLeast32BitUnsigned + Codec + Default + Copy + MaybeSerializeDeserialize + Debug; /// Handler for the unbalanced reduction when removing a dust account. @@ -205,12 +218,16 @@ pub trait Trait: frame_system::Trait { /// The means of storing the balances of an account. type AccountStore: StoredMap>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } impl, I: Instance> Subtrait for T { type Balance = T::Balance; type ExistentialDeposit = T::ExistentialDeposit; type AccountStore = T::AccountStore; + type WeightInfo = >::WeightInfo; } decl_event!( @@ -218,17 +235,25 @@ decl_event!( ::AccountId, >::Balance { - /// An account was created with some free balance. + /// An account was created with some free balance. [account, free_balance] Endowed(AccountId, Balance), /// An account was removed whose balance was non-zero but below ExistentialDeposit, - /// resulting in an outright loss. + /// resulting in an outright loss. [account, balance] DustLost(AccountId, Balance), - /// Transfer succeeded (from, to, value). + /// Transfer succeeded. [from, to, value] Transfer(AccountId, AccountId, Balance), - /// A balance was set by root (who, free, reserved). + /// A balance was set by root. [who, free, reserved] BalanceSet(AccountId, Balance, Balance), - /// Some amount was deposited (e.g. for transaction fees). + /// Some amount was deposited (e.g. for transaction fees). [who, deposit] Deposit(AccountId, Balance), + /// Some balance was reserved (moved from free to reserved). [who, value] + Reserved(AccountId, Balance), + /// Some balance was unreserved (moved from reserved to free). [who, value] + Unreserved(AccountId, Balance), + /// Some balance was moved from the reserve of the first account to the second account. + /// Final argument indicates the destination balance type. + /// [from, to, balance, destination_status] + ReserveRepatriated(AccountId, AccountId, Balance, Status), } ); @@ -364,9 +389,6 @@ decl_storage! { /// The balance of an account. /// - /// NOTE: THIS MAY NEVER BE IN EXISTENCE AND YET HAVE A `total().is_zero()`. If the total - /// is ever zero, then the entry *MUST* be removed. - /// /// NOTE: This is only used in the case that this module is used to store balances. pub Account: map hasher(blake2_128_concat) T::AccountId => AccountData; @@ -383,10 +405,6 @@ decl_storage! { config(balances): Vec<(T::AccountId, T::Balance)>; // ^^ begin, length, amount liquid at genesis build(|config: &GenesisConfig| { - assert!( - >::ExistentialDeposit::get() > Zero::zero(), - "The existential deposit should be greater than zero." - ); for (_, balance) in &config.balances { assert!( *balance >= >::ExistentialDeposit::get(), @@ -436,7 +454,7 @@ decl_module! { /// - DB Weight: 1 Read and 1 Write to destination account /// - Origin account is already in memory, so no DB operations for them. /// # - #[weight = T::DbWeight::get().reads_writes(1, 1) + 70_000_000] + #[weight = T::WeightInfo::transfer()] pub fn transfer( origin, dest: ::Source, @@ -465,7 +483,9 @@ decl_module! { /// - Killing: 35.11 µs /// - DB Weight: 1 Read, 1 Write to `who` /// # - #[weight = T::DbWeight::get().reads_writes(1, 1) + 35_000_000] + #[weight = T::WeightInfo::set_balance_creating() // Creates a new account. + .max(T::WeightInfo::set_balance_killing()) // Kills an existing account. + ] fn set_balance( origin, who: ::Source, @@ -507,7 +527,7 @@ decl_module! { /// - Same as transfer, but additional read and write because the source account is /// not assumed to be in the overlay. /// # - #[weight = T::DbWeight::get().reads_writes(2, 2) + 70_000_000] + #[weight = T::WeightInfo::force_transfer()] pub fn force_transfer( origin, source: ::Source, @@ -531,7 +551,7 @@ decl_module! { /// - Base Weight: 51.4 µs /// - DB Weight: 1 Read and 1 Write to dest (sender is in overlay already) /// # - #[weight = T::DbWeight::get().reads_writes(1, 1) + 50_000_000] + #[weight = T::WeightInfo::transfer_keep_alive()] pub fn transfer_keep_alive( origin, dest: ::Source, @@ -604,11 +624,11 @@ impl, I: Instance> Module { /// /// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that /// the caller will do this. - fn mutate_account( + pub fn mutate_account( who: &T::AccountId, f: impl FnOnce(&mut AccountData) -> R ) -> R { - Self::try_mutate_account(who, |a| -> Result { Ok(f(a)) }) + Self::try_mutate_account(who, |a, _| -> Result { Ok(f(a)) }) .expect("Error is infallible; qed") } @@ -623,13 +643,13 @@ impl, I: Instance> Module { /// the caller will do this. fn try_mutate_account( who: &T::AccountId, - f: impl FnOnce(&mut AccountData) -> Result + f: impl FnOnce(&mut AccountData, bool) -> Result ) -> Result { T::AccountStore::try_mutate_exists(who, |maybe_account| { + let is_new = maybe_account.is_none(); let mut account = maybe_account.take().unwrap_or_default(); - let was_zero = account.total().is_zero(); - f(&mut account).map(move |result| { - let maybe_endowed = if was_zero { Some(account.free) } else { None }; + f(&mut account, is_new).map(move |result| { + let maybe_endowed = if is_new { Some(account.free) } else { None }; *maybe_account = Self::post_mutation(who, account); (maybe_endowed, result) }) @@ -847,6 +867,7 @@ impl, I: Instance> PartialEq for ElevatedTrait { } impl, I: Instance> Eq for ElevatedTrait {} impl, I: Instance> frame_system::Trait for ElevatedTrait { + type BaseCallFilter = T::BaseCallFilter; type Origin = T::Origin; type Call = T::Call; type Index = T::Index; @@ -860,8 +881,9 @@ impl, I: Instance> frame_system::Trait for ElevatedTrait { type BlockHashCount = T::BlockHashCount; type MaximumBlockWeight = T::MaximumBlockWeight; type DbWeight = T::DbWeight; - type BlockExecutionWeight = (); - type ExtrinsicBaseWeight = (); + type BlockExecutionWeight = T::BlockExecutionWeight; + type ExtrinsicBaseWeight = T::ExtrinsicBaseWeight; + type MaximumExtrinsicWeight = T::MaximumBlockWeight; type MaximumBlockLength = T::MaximumBlockLength; type AvailableBlockRatio = T::AvailableBlockRatio; type Version = T::Version; @@ -869,6 +891,7 @@ impl, I: Instance> frame_system::Trait for ElevatedTrait { type OnNewAccount = T::OnNewAccount; type OnKilledAccount = T::OnKilledAccount; type AccountData = T::AccountData; + type SystemWeightInfo = T::SystemWeightInfo; } impl, I: Instance> Trait for ElevatedTrait { type Balance = T::Balance; @@ -876,6 +899,7 @@ impl, I: Instance> Trait for ElevatedTrait { type DustRemoval = (); type ExistentialDeposit = T::ExistentialDeposit; type AccountStore = T::AccountStore; + type WeightInfo = >::WeightInfo; } impl, I: Instance> Currency for Module where @@ -964,8 +988,8 @@ impl, I: Instance> Currency for Module where ) -> DispatchResult { if value.is_zero() || transactor == dest { return Ok(()) } - Self::try_mutate_account(dest, |to_account| -> DispatchResult { - Self::try_mutate_account(transactor, |from_account| -> DispatchResult { + Self::try_mutate_account(dest, |to_account, _| -> DispatchResult { + Self::try_mutate_account(transactor, |from_account, _| -> DispatchResult { from_account.free = from_account.free.checked_sub(&value) .ok_or(Error::::InsufficientBalance)?; @@ -1036,8 +1060,8 @@ impl, I: Instance> Currency for Module where ) -> Result { if value.is_zero() { return Ok(PositiveImbalance::zero()) } - Self::try_mutate_account(who, |account| -> Result { - ensure!(!account.total().is_zero(), Error::::DeadAccount); + Self::try_mutate_account(who, |account, is_new| -> Result { + ensure!(!is_new, Error::::DeadAccount); account.free = account.free.checked_add(&value).ok_or(Error::::Overflow)?; Ok(PositiveImbalance::new(value)) }) @@ -1055,14 +1079,14 @@ impl, I: Instance> Currency for Module where ) -> Self::PositiveImbalance { if value.is_zero() { return Self::PositiveImbalance::zero() } - Self::try_mutate_account(who, |account| -> Result { + Self::try_mutate_account(who, |account, is_new| -> Result { // bail if not yet created and this operation wouldn't be enough to create it. let ed = T::ExistentialDeposit::get(); - ensure!(value >= ed || !account.total().is_zero(), Self::PositiveImbalance::zero()); + ensure!(value >= ed || !is_new, Self::PositiveImbalance::zero()); // defensive only: overflow should never happen, however in case it does, then this // operation is a no-op. - account.free = account.free.checked_add(&value).ok_or(Self::PositiveImbalance::zero())?; + account.free = account.free.checked_add(&value).ok_or_else(|| Self::PositiveImbalance::zero())?; Ok(PositiveImbalance::new(value)) }).unwrap_or_else(|x| x) @@ -1079,7 +1103,7 @@ impl, I: Instance> Currency for Module where ) -> result::Result { if value.is_zero() { return Ok(NegativeImbalance::zero()); } - Self::try_mutate_account(who, |account| + Self::try_mutate_account(who, |account, _| -> Result { let new_free_account = account.free.checked_sub(&value) @@ -1103,7 +1127,7 @@ impl, I: Instance> Currency for Module where fn make_free_balance_be(who: &T::AccountId, value: Self::Balance) -> SignedImbalance { - Self::try_mutate_account(who, |account| + Self::try_mutate_account(who, |account, is_new| -> Result, ()> { let ed = T::ExistentialDeposit::get(); @@ -1114,7 +1138,7 @@ impl, I: Instance> Currency for Module where // equal and opposite cause (returned as an Imbalance), then in the // instance that there's no other accounts on the system at all, we might // underflow the issuance and our arithmetic will be off. - ensure!(value.saturating_add(account.reserved) >= ed || !account.total().is_zero(), ()); + ensure!(value.saturating_add(account.reserved) >= ed || !is_new, ()); let imbalance = if account.free <= value { SignedImbalance::Positive(PositiveImbalance::new(value - account.free)) @@ -1123,7 +1147,7 @@ impl, I: Instance> Currency for Module where }; account.free = value; Ok(imbalance) - }).unwrap_or(SignedImbalance::Positive(Self::PositiveImbalance::zero())) + }).unwrap_or_else(|_| SignedImbalance::Positive(Self::PositiveImbalance::zero())) } } @@ -1152,11 +1176,14 @@ impl, I: Instance> ReservableCurrency for Module fn reserve(who: &T::AccountId, value: Self::Balance) -> DispatchResult { if value.is_zero() { return Ok(()) } - Self::try_mutate_account(who, |account| -> DispatchResult { + Self::try_mutate_account(who, |account, _| -> DispatchResult { account.free = account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; account.reserved = account.reserved.checked_add(&value).ok_or(Error::::Overflow)?; - Self::ensure_can_withdraw(who, value, WithdrawReason::Reserve.into(), account.free) - }) + Self::ensure_can_withdraw(&who, value.clone(), WithdrawReason::Reserve.into(), account.free) + })?; + + Self::deposit_event(RawEvent::Reserved(who.clone(), value)); + Ok(()) } /// Unreserve some funds, returning any amount that was unable to be unreserved. @@ -1165,14 +1192,17 @@ impl, I: Instance> ReservableCurrency for Module fn unreserve(who: &T::AccountId, value: Self::Balance) -> Self::Balance { if value.is_zero() { return Zero::zero() } - Self::mutate_account(who, |account| { + let actual = Self::mutate_account(who, |account| { let actual = cmp::min(account.reserved, value); account.reserved -= actual; // defensive only: this can never fail since total issuance which is at least free+reserved // fits into the same data type. account.free = account.free.saturating_add(actual); - value - actual - }) + actual + }); + + Self::deposit_event(RawEvent::Unreserved(who.clone(), actual.clone())); + value - actual } /// Slash from reserved balance, returning the negative imbalance created, @@ -1213,18 +1243,21 @@ impl, I: Instance> ReservableCurrency for Module }; } - Self::try_mutate_account(beneficiary, |to_account| -> Result { - ensure!(!to_account.total().is_zero(), Error::::DeadAccount); - Self::try_mutate_account(slashed, |from_account| -> Result { + let actual = Self::try_mutate_account(beneficiary, |to_account, is_new|-> Result { + ensure!(!is_new, Error::::DeadAccount); + Self::try_mutate_account(slashed, |from_account, _| -> Result { let actual = cmp::min(from_account.reserved, value); match status { Status::Free => to_account.free = to_account.free.checked_add(&actual).ok_or(Error::::Overflow)?, Status::Reserved => to_account.reserved = to_account.reserved.checked_add(&actual).ok_or(Error::::Overflow)?, } from_account.reserved -= actual; - Ok(value - actual) + Ok(actual) }) - }) + })?; + + Self::deposit_event(RawEvent::ReserveRepatriated(slashed.clone(), beneficiary.clone(), actual, status)); + Ok(value - actual) } } @@ -1235,7 +1268,14 @@ impl, I: Instance> ReservableCurrency for Module /// storage (which is the default in most examples and tests) then there's no need.** impl, I: Instance> OnKilledAccount for Module { fn on_killed_account(who: &T::AccountId) { - Account::::remove(who); + Account::::mutate_exists(who, |account| { + let total = account.as_ref().map(|acc| acc.total()).unwrap_or_default(); + if !total.is_zero() { + T::DustRemoval::on_unbalanced(NegativeImbalance::new(total)); + Self::deposit_event(RawEvent::DustLost(who.clone(), total)); + } + *account = None; + }); } } @@ -1255,12 +1295,9 @@ where ) { if amount.is_zero() || reasons.is_none() { return } let mut new_lock = Some(BalanceLock { id, amount, reasons: reasons.into() }); - let mut locks = Self::locks(who).into_iter().filter_map(|l| - if l.id == id { - new_lock.take() - } else { - Some(l) - }).collect::>(); + let mut locks = Self::locks(who).into_iter() + .filter_map(|l| if l.id == id { new_lock.take() } else { Some(l) }) + .collect::>(); if let Some(lock) = new_lock { locks.push(lock) } @@ -1309,7 +1346,7 @@ impl, I: Instance> IsDeadAccount for Module wher T::Balance: MaybeSerializeDeserialize + Debug { fn is_dead_account(who: &T::AccountId) -> bool { - // this should always be exactly equivalent to `Self::account(who).total().is_zero()` + // this should always be exactly equivalent to `Self::account(who).total().is_zero()` if ExistentialDeposit > 0 !T::AccountStore::is_explicit(who) } } diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 7663b8922bc04efa32b1a6fefcc476590436c9c6..210c75631da6387b8f7386248059ff473f135d06 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Macro for creating the tests for the module. @@ -25,6 +26,7 @@ impl sp_runtime::traits::Dispatchable for CallWithDispatchInfo { type Trait = (); type Info = frame_support::weights::DispatchInfo; type PostInfo = frame_support::weights::PostDispatchInfo; + fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo { panic!("Do not use dummy implementation for dispatch."); @@ -36,7 +38,7 @@ macro_rules! decl_tests { ($test:ty, $ext_builder:ty, $existential_deposit:expr) => { use crate::*; - use sp_runtime::{Fixed128, traits::{SignedExtension, BadOrigin}}; + use sp_runtime::{FixedPointNumber, traits::{SignedExtension, BadOrigin}}; use frame_support::{ assert_noop, assert_ok, assert_err, traits::{ @@ -44,7 +46,7 @@ macro_rules! decl_tests { Currency, ReservableCurrency, ExistenceRequirement::AllowDeath, StoredMap } }; - use pallet_transaction_payment::ChargeTransactionPayment; + use pallet_transaction_payment::{ChargeTransactionPayment, Multiplier}; use frame_system::RawOrigin; const ID_1: LockIdentifier = *b"1 "; @@ -60,6 +62,18 @@ macro_rules! decl_tests { DispatchInfo { weight: w, ..Default::default() } } + fn events() -> Vec { + let evt = System::events().into_iter().map(|evt| evt.event).collect::>(); + + System::reset_events(); + + evt + } + + fn last_event() -> Event { + system::Module::::events().pop().expect("Event expected").event + } + #[test] fn basic_locking_should_work() { <$ext_builder>::default().existential_deposit(1).monied(true).build().execute_with(|| { @@ -153,7 +167,7 @@ macro_rules! decl_tests { .monied(true) .build() .execute_with(|| { - pallet_transaction_payment::NextFeeMultiplier::put(Fixed128::from_natural(1)); + pallet_transaction_payment::NextFeeMultiplier::put(Multiplier::saturating_from_integer(1)); Balances::set_lock(ID_1, &1, 10, WithdrawReason::Reserve.into()); assert_noop!( >::transfer(&1, &2, 1, AllowDeath), @@ -161,7 +175,7 @@ macro_rules! decl_tests { ); assert_noop!( >::reserve(&1, 1), - Error::<$test, _>::LiquidityRestrictions + Error::<$test, _>::LiquidityRestrictions, ); assert!( as SignedExtension>::pre_dispatch( ChargeTransactionPayment::from(1), @@ -476,6 +490,10 @@ macro_rules! decl_tests { let _ = Balances::deposit_creating(&2, 1); assert_ok!(Balances::reserve(&1, 110)); assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Free), 0); + assert_eq!( + last_event(), + Event::balances(RawEvent::ReserveRepatriated(1, 2, 41, Status::Free)), + ); assert_eq!(Balances::reserved_balance(1), 69); assert_eq!(Balances::free_balance(1), 0); assert_eq!(Balances::reserved_balance(2), 0); @@ -673,5 +691,101 @@ macro_rules! decl_tests { assert_eq!(Balances::reserved_balance(1), 0); }); } + + #[test] + fn emit_events_with_reserve_and_unreserve() { + <$ext_builder>::default() + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&1, 100); + + System::set_block_number(2); + let _ = Balances::reserve(&1, 10); + + assert_eq!( + last_event(), + Event::balances(RawEvent::Reserved(1, 10)), + ); + + System::set_block_number(3); + let _ = Balances::unreserve(&1, 5); + + assert_eq!( + last_event(), + Event::balances(RawEvent::Unreserved(1, 5)), + ); + + System::set_block_number(4); + let _ = Balances::unreserve(&1, 6); + + // should only unreserve 5 + assert_eq!( + last_event(), + Event::balances(RawEvent::Unreserved(1, 5)), + ); + }); + } + + #[test] + fn emit_events_with_existential_deposit() { + <$ext_builder>::default() + .existential_deposit(100) + .build() + .execute_with(|| { + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + + assert_eq!( + events(), + [ + Event::system(system::RawEvent::NewAccount(1)), + Event::balances(RawEvent::Endowed(1, 100)), + Event::balances(RawEvent::BalanceSet(1, 100, 0)), + ] + ); + + let _ = Balances::slash(&1, 1); + + assert_eq!( + events(), + [ + Event::balances(RawEvent::DustLost(1, 99)), + Event::system(system::RawEvent::KilledAccount(1)) + ] + ); + }); + } + + #[test] + fn emit_events_with_no_existential_deposit_suicide() { + <$ext_builder>::default() + .existential_deposit(0) + .build() + .execute_with(|| { + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + + assert_eq!( + events(), + [ + Event::system(system::RawEvent::NewAccount(1)), + Event::balances(RawEvent::Endowed(1, 100)), + Event::balances(RawEvent::BalanceSet(1, 100, 0)), + ] + ); + + let _ = Balances::slash(&1, 100); + + // no events + assert_eq!(events(), []); + + assert_ok!(System::suicide(Origin::signed(1))); + + assert_eq!( + events(), + [ + Event::system(system::RawEvent::KilledAccount(1)) + ] + ); + }); + } } } diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 5d25fdb50ceba6dd8b09e014f904a0e408eba43d..8e764112ba24ccf135148378be62f28bc8ab3428 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Test utilities @@ -20,14 +21,14 @@ use sp_runtime::{ Perbill, - traits::{ConvertInto, IdentityLookup}, + traits::IdentityLookup, testing::Header, }; use sp_core::H256; use sp_io; -use frame_support::{impl_outer_origin, parameter_types}; +use frame_support::{impl_outer_origin, impl_outer_event, parameter_types}; use frame_support::traits::Get; -use frame_support::weights::{Weight, DispatchInfo}; +use frame_support::weights::{Weight, DispatchInfo, IdentityFee}; use std::cell::RefCell; use crate::{GenesisConfig, Module, Trait, decl_tests, tests::CallWithDispatchInfo}; @@ -36,6 +37,17 @@ impl_outer_origin!{ pub enum Origin for Test {} } +mod balances { + pub use crate::Event; +} + +impl_outer_event! { + pub enum Event for Test { + system, + balances, + } +} + thread_local! { static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); } @@ -55,6 +67,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -64,12 +77,13 @@ impl frame_system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type Event = (); + type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -77,6 +91,7 @@ impl frame_system::Trait for Test { type AccountData = super::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { pub const TransactionByteFee: u64 = 1; @@ -85,15 +100,16 @@ impl pallet_transaction_payment::Trait for Test { type Currency = Module; type OnTransactionPayment = (); type TransactionByteFee = TransactionByteFee; - type WeightToFee = ConvertInto; + type WeightToFee = IdentityFee; type FeeMultiplierUpdate = (); } impl Trait for Test { type Balance = u64; type DustRemoval = (); - type Event = (); + type Event = Event; type ExistentialDeposit = ExistentialDeposit; type AccountStore = system::Module; + type WeightInfo = (); } pub struct ExtBuilder { @@ -136,7 +152,10 @@ impl ExtBuilder { vec![] }, }.assimilate_storage(&mut t).unwrap(); - t.into() + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext } } diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index afc0edbae7f161c3c0284f271b63c2f15cfdb3f2..86abc2b6044ce4f6802b794968140c25e3b72ba4 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Test utilities @@ -20,14 +21,14 @@ use sp_runtime::{ Perbill, - traits::{ConvertInto, IdentityLookup}, + traits::IdentityLookup, testing::Header, }; use sp_core::H256; use sp_io; -use frame_support::{impl_outer_origin, parameter_types}; +use frame_support::{impl_outer_origin, impl_outer_event, parameter_types}; use frame_support::traits::{Get, StorageMapShim}; -use frame_support::weights::{Weight, DispatchInfo}; +use frame_support::weights::{Weight, DispatchInfo, IdentityFee}; use std::cell::RefCell; use crate::{GenesisConfig, Module, Trait, decl_tests, tests::CallWithDispatchInfo}; @@ -36,6 +37,17 @@ impl_outer_origin!{ pub enum Origin for Test {} } +mod balances { + pub use crate::Event; +} + +impl_outer_event! { + pub enum Event for Test { + system, + balances, + } +} + thread_local! { static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); } @@ -55,6 +67,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -64,12 +77,13 @@ impl frame_system::Trait for Test { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type Event = (); + type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -77,6 +91,7 @@ impl frame_system::Trait for Test { type AccountData = super::AccountData; type OnNewAccount = (); type OnKilledAccount = Module; + type SystemWeightInfo = (); } parameter_types! { pub const TransactionByteFee: u64 = 1; @@ -85,13 +100,13 @@ impl pallet_transaction_payment::Trait for Test { type Currency = Module; type OnTransactionPayment = (); type TransactionByteFee = TransactionByteFee; - type WeightToFee = ConvertInto; + type WeightToFee = IdentityFee; type FeeMultiplierUpdate = (); } impl Trait for Test { type Balance = u64; type DustRemoval = (); - type Event = (); + type Event = Event; type ExistentialDeposit = ExistentialDeposit; type AccountStore = StorageMapShim< super::Account, @@ -99,6 +114,7 @@ impl Trait for Test { system::CallKillAccount, u64, super::AccountData >; + type WeightInfo = (); } pub struct ExtBuilder { @@ -144,8 +160,45 @@ impl ExtBuilder { vec![] }, }.assimilate_storage(&mut t).unwrap(); - t.into() + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext } } decl_tests!{ Test, ExtBuilder, EXISTENTIAL_DEPOSIT } + +#[test] +fn emit_events_with_no_existential_deposit_suicide_with_dust() { + ::default() + .existential_deposit(0) + .build() + .execute_with(|| { + assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); + + assert_eq!( + events(), + [ + Event::system(system::RawEvent::NewAccount(1)), + Event::balances(RawEvent::Endowed(1, 100)), + Event::balances(RawEvent::BalanceSet(1, 100, 0)), + ] + ); + + let _ = Balances::slash(&1, 99); + + // no events + assert_eq!(events(), []); + + assert_ok!(System::suicide(Origin::signed(1))); + + assert_eq!( + events(), + [ + Event::balances(RawEvent::DustLost(1, 1)), + Event::system(system::RawEvent::KilledAccount(1)) + ] + ); + }); +} diff --git a/frame/benchmark/Cargo.toml b/frame/benchmark/Cargo.toml index 0b506d12ec90e838438b433e74ac8e8df5a413f7..f731ebcbacf54583dcc19695243adda3c00b94c3 100644 --- a/frame/benchmark/Cargo.toml +++ b/frame/benchmark/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-benchmark" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Patterns to benchmark in a FRAME runtime." @@ -14,12 +14,12 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } [features] default = ["std"] diff --git a/frame/benchmark/README.md b/frame/benchmark/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e00e11292e1432fd26b397b5c80d9f0627e9554f --- /dev/null +++ b/frame/benchmark/README.md @@ -0,0 +1,5 @@ +A pallet that contains common runtime patterns in an isolated manner. +This pallet is **not** meant to be used in a production blockchain, just +for benchmarking and testing purposes. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/benchmark/src/benchmarking.rs b/frame/benchmark/src/benchmarking.rs index 1e4740da2c0595b45be30c4a1dc2496176f7d157..ddf3df9eaad4cb5a367724a5b2b1508359856bc4 100644 --- a/frame/benchmark/src/benchmarking.rs +++ b/frame/benchmark/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Benchmarks for common FRAME Pallet operations. diff --git a/frame/benchmark/src/lib.rs b/frame/benchmark/src/lib.rs index 037edc9d269860fcb5914221b33ca5c873950166..422272f817c7a2f75c2b991a40a01929b4dc48b2 100644 --- a/frame/benchmark/src/lib.rs +++ b/frame/benchmark/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! A pallet that contains common runtime patterns in an isolated manner. //! This pallet is **not** meant to be used in a production blockchain, just diff --git a/frame/benchmarking/Cargo.toml b/frame/benchmarking/Cargo.toml index 8089a2a3661d0ffecc7b5c6c067ce740e350a083..750123b14612f11b933d73de6854102001ae94b8 100644 --- a/frame/benchmarking/Cargo.toml +++ b/frame/benchmarking/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-benchmarking" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Macro for benchmarking a FRAME runtime." @@ -14,14 +14,18 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] linregress = "0.1" paste = "0.1" -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-api = { version = "2.0.0-dev", path = "../../primitives/api", default-features = false } -sp-runtime-interface = { version = "2.0.0-dev", path = "../../primitives/runtime-interface", default-features = false } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime", default-features = false } -sp-std = { version = "2.0.0-dev", path = "../../primitives/std", default-features = false } -sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-dev"} -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api", default-features = false } +sp-runtime-interface = { version = "2.0.0-rc6", path = "../../primitives/runtime-interface", default-features = false } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime", default-features = false } +sp-std = { version = "2.0.0-rc6", path = "../../primitives/std", default-features = false } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io", default-features = false } +sp-storage = { version = "2.0.0-rc6", path = "../../primitives/storage", default-features = false } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } + +[dev-dependencies] +hex-literal = "0.3.1" [features] default = [ "std" ] diff --git a/frame/benchmarking/README.md b/frame/benchmarking/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1e06135e345e7317585be196c13440c9a98e0cbb --- /dev/null +++ b/frame/benchmarking/README.md @@ -0,0 +1,3 @@ +Macro for benchmarking a FRAME runtime. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/benchmarking/src/analysis.rs b/frame/benchmarking/src/analysis.rs index 1d30b86fc9f41ccc9045f01e58a669ba3c524e75..6963d84ee614e20f94906099244d439092d86358 100644 --- a/frame/benchmarking/src/analysis.rs +++ b/frame/benchmarking/src/analysis.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Tools for analysing the benchmark results. @@ -21,31 +22,75 @@ use linregress::{FormulaRegressionBuilder, RegressionDataBuilder, RegressionMode use crate::BenchmarkResults; pub struct Analysis { - base: u128, - slopes: Vec, - names: Vec, - value_dists: Option, u128, u128)>>, - model: Option, + pub base: u128, + pub slopes: Vec, + pub names: Vec, + pub value_dists: Option, u128, u128)>>, + pub model: Option, +} + +pub enum BenchmarkSelector { + ExtrinsicTime, + StorageRootTime, + Reads, + Writes, } impl Analysis { - pub fn median_slopes(r: &Vec) -> Option { - let results = r[0].0.iter().enumerate().map(|(i, &(param, _))| { + // Useful for when there are no components, and we just need an median value of the benchmark results. + // Note: We choose the median value because it is more robust to outliers. + fn median_value(r: &Vec, selector: BenchmarkSelector) -> Option { + if r.is_empty() { return None } + + let mut values: Vec = r.iter().map(|result| + match selector { + BenchmarkSelector::ExtrinsicTime => result.extrinsic_time, + BenchmarkSelector::StorageRootTime => result.storage_root_time, + BenchmarkSelector::Reads => result.reads.into(), + BenchmarkSelector::Writes => result.writes.into(), + } + ).collect(); + + values.sort(); + let mid = values.len() / 2; + + Some(Self { + base: values[mid], + slopes: Vec::new(), + names: Vec::new(), + value_dists: None, + model: None, + }) + } + + pub fn median_slopes(r: &Vec, selector: BenchmarkSelector) -> Option { + if r[0].components.is_empty() { return Self::median_value(r, selector) } + + let results = r[0].components.iter().enumerate().map(|(i, &(param, _))| { let mut counted = BTreeMap::, usize>::new(); - for (params, _, _) in r.iter() { - let mut p = params.iter().map(|x| x.1).collect::>(); + for result in r.iter() { + let mut p = result.components.iter().map(|x| x.1).collect::>(); p[i] = 0; *counted.entry(p).or_default() += 1; } let others: Vec = counted.iter().max_by_key(|i| i.1).expect("r is not empty; qed").0.clone(); let values = r.iter() .filter(|v| - v.0.iter() + v.components.iter() .map(|x| x.1) .zip(others.iter()) .enumerate() .all(|(j, (v1, v2))| j == i || v1 == *v2) - ).map(|(ps, v, _)| (ps[i].1, *v)) + ).map(|result| { + // Extract the data we are interested in analyzing + let data = match selector { + BenchmarkSelector::ExtrinsicTime => result.extrinsic_time, + BenchmarkSelector::StorageRootTime => result.storage_root_time, + BenchmarkSelector::Reads => result.reads.into(), + BenchmarkSelector::Writes => result.writes.into(), + }; + (result.components[i].1, data) + }) .collect::>(); (format!("{:?}", param), i, others, values) }).collect::>(); @@ -96,12 +141,20 @@ impl Analysis { }) } - pub fn min_squares_iqr(r: &Vec) -> Option { + pub fn min_squares_iqr(r: &Vec, selector: BenchmarkSelector) -> Option { + if r[0].components.is_empty() { return Self::median_value(r, selector) } + let mut results = BTreeMap::, Vec>::new(); - for &(ref params, t, _) in r.iter() { - let p = params.iter().map(|x| x.1).collect::>(); - results.entry(p).or_default().push(t); + for result in r.iter() { + let p = result.components.iter().map(|x| x.1).collect::>(); + results.entry(p).or_default().push(match selector { + BenchmarkSelector::ExtrinsicTime => result.extrinsic_time, + BenchmarkSelector::StorageRootTime => result.storage_root_time, + BenchmarkSelector::Reads => result.reads.into(), + BenchmarkSelector::Writes => result.writes.into(), + }) } + for (_, rs) in results.iter_mut() { rs.sort(); let ql = rs.len() / 4; @@ -110,7 +163,7 @@ impl Analysis { let mut data = vec![("Y", results.iter().flat_map(|x| x.1.iter().map(|v| *v as f64)).collect())]; - let names = r[0].0.iter().map(|x| format!("{:?}", x.0)).collect::>(); + let names = r[0].components.iter().map(|x| format!("{:?}", x.0)).collect::>(); data.extend(names.iter() .enumerate() .map(|(i, p)| ( @@ -216,40 +269,88 @@ impl std::fmt::Display for Analysis { } } +impl std::fmt::Debug for Analysis { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.base)?; + for (&m, n) in self.slopes.iter().zip(self.names.iter()) { + write!(f, " + ({} * {})", m, n)?; + } + write!(f,"") + } +} + #[cfg(test)] mod tests { use super::*; use crate::BenchmarkParameter; + fn benchmark_result( + components: Vec<(BenchmarkParameter, u32)>, + extrinsic_time: u128, + storage_root_time: u128, + reads: u32, + writes: u32, + ) -> BenchmarkResults { + BenchmarkResults { + components, + extrinsic_time, + storage_root_time, + reads, + repeat_reads: 0, + writes, + repeat_writes: 0, + } + } + #[test] fn analysis_median_slopes_should_work() { - let a = Analysis::median_slopes(&vec![ - (vec![(BenchmarkParameter::n, 1), (BenchmarkParameter::m, 5)], 11_500_000, 0), - (vec![(BenchmarkParameter::n, 2), (BenchmarkParameter::m, 5)], 12_500_000, 0), - (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 5)], 13_500_000, 0), - (vec![(BenchmarkParameter::n, 4), (BenchmarkParameter::m, 5)], 14_500_000, 0), - (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 1)], 13_100_000, 0), - (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 3)], 13_300_000, 0), - (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 7)], 13_700_000, 0), - (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 10)], 14_000_000, 0), - ]).unwrap(); - assert_eq!(a.base, 10_000_000); - assert_eq!(a.slopes, vec![1_000_000, 100_000]); + let data = vec![ + benchmark_result(vec![(BenchmarkParameter::n, 1), (BenchmarkParameter::m, 5)], 11_500_000, 0, 3, 10), + benchmark_result(vec![(BenchmarkParameter::n, 2), (BenchmarkParameter::m, 5)], 12_500_000, 0, 4, 10), + benchmark_result(vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 5)], 13_500_000, 0, 5, 10), + benchmark_result(vec![(BenchmarkParameter::n, 4), (BenchmarkParameter::m, 5)], 14_500_000, 0, 6, 10), + benchmark_result(vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 1)], 13_100_000, 0, 5, 2), + benchmark_result(vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 3)], 13_300_000, 0, 5, 6), + benchmark_result(vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 7)], 13_700_000, 0, 5, 14), + benchmark_result(vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 10)], 14_000_000, 0, 5, 20), + ]; + + let extrinsic_time = Analysis::median_slopes(&data, BenchmarkSelector::ExtrinsicTime).unwrap(); + assert_eq!(extrinsic_time.base, 10_000_000); + assert_eq!(extrinsic_time.slopes, vec![1_000_000, 100_000]); + + let reads = Analysis::median_slopes(&data, BenchmarkSelector::Reads).unwrap(); + assert_eq!(reads.base, 2); + assert_eq!(reads.slopes, vec![1, 0]); + + let writes = Analysis::median_slopes(&data, BenchmarkSelector::Writes).unwrap(); + assert_eq!(writes.base, 0); + assert_eq!(writes.slopes, vec![0, 2]); } #[test] fn analysis_median_min_squares_should_work() { - let a = Analysis::min_squares_iqr(&vec![ - (vec![(BenchmarkParameter::n, 1), (BenchmarkParameter::m, 5)], 11_500_000, 0), - (vec![(BenchmarkParameter::n, 2), (BenchmarkParameter::m, 5)], 12_500_000, 0), - (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 5)], 13_500_000, 0), - (vec![(BenchmarkParameter::n, 4), (BenchmarkParameter::m, 5)], 14_500_000, 0), - (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 1)], 13_100_000, 0), - (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 3)], 13_300_000, 0), - (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 7)], 13_700_000, 0), - (vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 10)], 14_000_000, 0), - ]).unwrap(); - assert_eq!(a.base, 10_000_000); - assert_eq!(a.slopes, vec![1_000_000, 100_000]); + let data = vec![ + benchmark_result(vec![(BenchmarkParameter::n, 1), (BenchmarkParameter::m, 5)], 11_500_000, 0, 3, 10), + benchmark_result(vec![(BenchmarkParameter::n, 2), (BenchmarkParameter::m, 5)], 12_500_000, 0, 4, 10), + benchmark_result(vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 5)], 13_500_000, 0, 5, 10), + benchmark_result(vec![(BenchmarkParameter::n, 4), (BenchmarkParameter::m, 5)], 14_500_000, 0, 6, 10), + benchmark_result(vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 1)], 13_100_000, 0, 5, 2), + benchmark_result(vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 3)], 13_300_000, 0, 5, 6), + benchmark_result(vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 7)], 13_700_000, 0, 5, 14), + benchmark_result(vec![(BenchmarkParameter::n, 3), (BenchmarkParameter::m, 10)], 14_000_000, 0, 5, 20), + ]; + + let extrinsic_time = Analysis::min_squares_iqr(&data, BenchmarkSelector::ExtrinsicTime).unwrap(); + assert_eq!(extrinsic_time.base, 10_000_000); + assert_eq!(extrinsic_time.slopes, vec![1_000_000, 100_000]); + + let reads = Analysis::min_squares_iqr(&data, BenchmarkSelector::Reads).unwrap(); + assert_eq!(reads.base, 2); + assert_eq!(reads.slopes, vec![1, 0]); + + let writes = Analysis::min_squares_iqr(&data, BenchmarkSelector::Writes).unwrap(); + assert_eq!(writes.base, 0); + assert_eq!(writes.slopes, vec![0, 2]); } } diff --git a/frame/benchmarking/src/lib.rs b/frame/benchmarking/src/lib.rs index 8a9df7e4cf3419823bb696b979eda0550aec5e16..cebdcbcfecd25ddf7b9b3ce5dd82c586e5c13005 100644 --- a/frame/benchmarking/src/lib.rs +++ b/frame/benchmarking/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Macro for benchmarking a FRAME runtime. @@ -25,11 +26,13 @@ mod analysis; pub use utils::*; #[cfg(feature = "std")] -pub use analysis::Analysis; +pub use analysis::{Analysis, BenchmarkSelector}; #[doc(hidden)] pub use sp_io::storage::root as storage_root; -pub use sp_runtime::traits::{Dispatchable, Zero}; +pub use sp_runtime::traits::Zero; +pub use frame_support; pub use paste; +pub use sp_storage::TrackedStorageKey; /// Construct pallet benchmarks for weighing dispatchables. /// @@ -83,6 +86,8 @@ pub use paste; /// Example: /// ```ignore /// benchmarks! { +/// where_clause { where T::A: From } // Optional line to give additional bound on `T`. +/// /// // common parameter; just one for this example. /// // will be `1`, `MAX_LENGTH` or any value inbetween /// _ { @@ -171,6 +176,7 @@ pub use paste; #[macro_export] macro_rules! benchmarks { ( + $( where_clause { where $( $where_ty:ty: $where_bound:path ),* $(,)? } )? _ { $( let $common:ident in $common_from:tt .. $common_to:expr => $common_instancer:expr; @@ -179,17 +185,21 @@ macro_rules! benchmarks { $( $rest:tt )* ) => { $crate::benchmarks_iter!( - NO_INSTANCE + { } + { $( $( $where_ty: $where_bound ),* )? } { $( { $common , $common_from , $common_to , $common_instancer } )* } ( ) + ( ) $( $rest )* ); } } +/// Same as [`benchmarks`] but for instantiable module. #[macro_export] macro_rules! benchmarks_instance { ( + $( where_clause { where $( $where_ty:ty: $where_bound:path ),* $(,)? } )? _ { $( let $common:ident in $common_from:tt .. $common_to:expr => $common_instancer:expr; @@ -198,70 +208,85 @@ macro_rules! benchmarks_instance { $( $rest:tt )* ) => { $crate::benchmarks_iter!( - INSTANCE + { I } + { $( $( $where_ty: $where_bound ),* )? } { $( { $common , $common_from , $common_to , $common_instancer } )* } ( ) + ( ) $( $rest )* ); } } #[macro_export] -#[allow(missing_docs)] +#[doc(hidden)] macro_rules! benchmarks_iter { - // mutation arm: + // detect and extract extra tag: ( - $instance:ident + { $( $instance:ident )? } + { $( $where_clause:tt )* } { $( $common:tt )* } - ( $( $names:ident )* ) - $name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* ) - verify $postcode:block + ( $( $names:tt )* ) + ( $( $names_extra:tt )* ) + #[extra] + $name:ident $( $rest:tt )* ) => { $crate::benchmarks_iter! { - $instance + { $( $instance)? } + { $( $where_clause )* } { $( $common )* } ( $( $names )* ) - $name { $( $code )* }: $name ( $origin $( , $arg )* ) - verify $postcode + ( $( $names_extra )* $name ) + $name $( $rest )* } }; - // no instance mutation arm: + // mutation arm: ( - NO_INSTANCE + { $( $instance:ident )? } + { $( $where_clause:tt )* } { $( $common:tt )* } - ( $( $names:ident )* ) - $name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* ) + ( $( $names:tt )* ) // This contains $( $( { $instance } )? $name:ident )* + ( $( $names_extra:tt )* ) + $name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* ) verify $postcode:block $( $rest:tt )* ) => { $crate::benchmarks_iter! { - NO_INSTANCE + { $( $instance)? } + { $( $where_clause )* } { $( $common )* } ( $( $names )* ) - $name { $( $code )* }: { - as $crate::Dispatchable>::dispatch(Call::::$dispatch($($arg),*), $origin.into())?; - } + ( $( $names_extra )* ) + $name { $( $code )* }: $name ( $origin $( , $arg )* ) verify $postcode $( $rest )* } }; - // instance mutation arm: + // mutation arm: ( - INSTANCE + { $( $instance:ident )? } + { $( $where_clause:tt )* } { $( $common:tt )* } - ( $( $names:ident )* ) + ( $( $names:tt )* ) + ( $( $names_extra:tt )* ) $name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* ) verify $postcode:block $( $rest:tt )* ) => { $crate::benchmarks_iter! { - INSTANCE + { $( $instance)? } + { $( $where_clause )* } { $( $common )* } ( $( $names )* ) + ( $( $names_extra )* ) $name { $( $code )* }: { - as $crate::Dispatchable>::dispatch(Call::::$dispatch($($arg),*), $origin.into())?; + < + Call as $crate::frame_support::traits::UnfilteredDispatchable + >::dispatch_bypass_filter( + Call::::$dispatch($($arg),*), $origin.into() + )?; } verify $postcode $( $rest )* @@ -269,48 +294,78 @@ macro_rules! benchmarks_iter { }; // iteration arm: ( - $instance:ident + { $( $instance:ident )? } + { $( $where_clause:tt )* } { $( $common:tt )* } - ( $( $names:ident )* ) + ( $( $names:tt )* ) + ( $( $names_extra:tt )* ) $name:ident { $( $code:tt )* }: $eval:block verify $postcode:block $( $rest:tt )* ) => { $crate::benchmark_backend! { - $instance + { $( $instance)? } $name + { $( $where_clause )* } { $( $common )* } { } { $eval } { $( $code )* } $postcode } + + #[cfg(test)] + $crate::impl_benchmark_test!( + { $( $where_clause )* } + { $( $instance)? } + $name + ); + $crate::benchmarks_iter!( - $instance + { $( $instance)? } + { $( $where_clause )* } { $( $common )* } - ( $( $names )* $name ) + ( $( $names )* { $( $instance )? } $name ) + ( $( $names_extra )* ) $( $rest )* ); }; // iteration-exit arm - ( $instance:ident { $( $common:tt )* } ( $( $names:ident )* ) ) => { - $crate::selected_benchmark!( $instance $( $names ),* ); - $crate::impl_benchmark!( $instance $( $names ),* ); - #[cfg(test)] - $crate::impl_benchmark_tests!( $instance $( $names ),* ); + ( + { $( $instance:ident )? } + { $( $where_clause:tt )* } + { $( $common:tt )* } + ( $( $names:tt )* ) + ( $( $names_extra:tt )* ) + ) => { + $crate::selected_benchmark!( + { $( $where_clause)* } + { $( $instance)? } + $( $names )* + ); + $crate::impl_benchmark!( + { $( $where_clause )* } + { $( $instance)? } + ( $( $names )* ) + ( $( $names_extra ),* ) + ); }; // add verify block to _() format ( - $instance:ident + { $( $instance:ident )? } + { $( $where_clause:tt )* } { $( $common:tt )* } - ( $( $names:ident )* ) + ( $( $names:tt )* ) + ( $( $names_extra:tt )* ) $name:ident { $( $code:tt )* }: _ ( $origin:expr $( , $arg:expr )* ) $( $rest:tt )* ) => { $crate::benchmarks_iter! { - $instance + { $( $instance)? } + { $( $where_clause )* } { $( $common )* } ( $( $names )* ) + ( $( $names_extra )* ) $name { $( $code )* }: _ ( $origin $( , $arg )* ) verify { } $( $rest )* @@ -318,16 +373,20 @@ macro_rules! benchmarks_iter { }; // add verify block to name() format ( - $instance:ident + { $( $instance:ident )? } + { $( $where_clause:tt )* } { $( $common:tt )* } - ( $( $names:ident )* ) + ( $( $names:tt )* ) + ( $( $names_extra:tt )* ) $name:ident { $( $code:tt )* }: $dispatch:ident ( $origin:expr $( , $arg:expr )* ) $( $rest:tt )* ) => { $crate::benchmarks_iter! { - $instance + { $( $instance)? } + { $( $where_clause )* } { $( $common )* } ( $( $names )* ) + ( $( $names_extra )* ) $name { $( $code )* }: $dispatch ( $origin $( , $arg )* ) verify { } $( $rest )* @@ -335,16 +394,20 @@ macro_rules! benchmarks_iter { }; // add verify block to {} format ( - $instance:ident + { $( $instance:ident )? } + { $( $where_clause:tt )* } { $( $common:tt )* } - ( $( $names:ident )* ) + ( $( $names:tt )* ) + ( $( $names_extra:tt )* ) $name:ident { $( $code:tt )* }: $eval:block $( $rest:tt )* ) => { $crate::benchmarks_iter!( - $instance + { $( $instance)? } + { $( $where_clause )* } { $( $common )* } ( $( $names )* ) + ( $( $names_extra )* ) $name { $( $code )* }: $eval verify { } $( $rest )* @@ -353,202 +416,230 @@ macro_rules! benchmarks_iter { } #[macro_export] -#[allow(missing_docs)] +#[doc(hidden)] macro_rules! benchmark_backend { // parsing arms - ($instance:ident $name:ident { - $( $common:tt )* - } { - $( PRE { $( $pre_parsed:tt )* } )* - } { $eval:block } { + ( + { $( $instance:ident )? } + $name:ident + { $( $where_clause:tt )* } + { $( $common:tt )* } + { $( PRE { $( $pre_parsed:tt )* } )* } + { $eval:block } + { let $pre_id:tt : $pre_ty:ty = $pre_ex:expr; $( $rest:tt )* - } $postcode:block) => { + } + $postcode:block + ) => { $crate::benchmark_backend! { - $instance $name { $( $common )* } { + { $( $instance)? } + $name + { $( $where_clause )* } + { $( $common )* } + { $( PRE { $( $pre_parsed )* } )* PRE { $pre_id , $pre_ty , $pre_ex } - } { $eval } { $( $rest )* } $postcode + } + { $eval } + { $( $rest )* } + $postcode } }; - ($instance:ident $name:ident { - $( $common:tt )* - } { - $( $parsed:tt )* - } { $eval:block } { - let $param:ident in ( $param_from:expr ) .. $param_to:expr => $param_instancer:expr; - $( $rest:tt )* - } $postcode:block) => { + ( + { $( $instance:ident )? } + $name:ident + { $( $where_clause:tt )* } + { $( $common:tt )* } + { $( $parsed:tt )* } + { $eval:block } + { + let $param:ident in ( $param_from:expr ) .. $param_to:expr => $param_instancer:expr; + $( $rest:tt )* + } + $postcode:block + ) => { $crate::benchmark_backend! { - $instance $name { $( $common )* } { + { $( $instance)? } + $name + { $( $where_clause )* } + { $( $common )* } + { $( $parsed )* PARAM { $param , $param_from , $param_to , $param_instancer } - } { $eval } { $( $rest )* } $postcode + } + { $eval } + { $( $rest )* } + $postcode } }; // mutation arm to look after defaulting to a common param - ($instance:ident $name:ident { - $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* - } { - $( $parsed:tt )* - } { $eval:block } { - let $param:ident in ...; - $( $rest:tt )* - } $postcode:block) => { + ( + { $( $instance:ident )? } + $name:ident + { $( $where_clause:tt )* } + { $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* } + { $( $parsed:tt )* } + { $eval:block } + { + let $param:ident in ...; + $( $rest:tt )* + } + $postcode:block + ) => { $crate::benchmark_backend! { - $instance $name { - $( { $common , $common_from , $common_to , $common_instancer } )* - } { - $( $parsed )* - } { $eval } { + { $( $instance)? } + $name + { $( $where_clause )* } + { $( { $common , $common_from , $common_to , $common_instancer } )* } + { $( $parsed )* } + { $eval } + { let $param in ({ $( let $common = $common_from; )* $param }) .. ({ $( let $common = $common_to; )* $param }) => ({ $( let $common = || -> Result<(), &'static str> { $common_instancer ; Ok(()) }; )* $param()? }); $( $rest )* - } $postcode + } + $postcode } }; // mutation arm to look after defaulting only the range to common param - ($instance:ident $name:ident { - $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* - } { - $( $parsed:tt )* - } { $eval:block } { - let $param:ident in _ .. _ => $param_instancer:expr ; - $( $rest:tt )* - } $postcode:block) => { + ( + { $( $instance:ident )? } + $name:ident + { $( $where_clause:tt )* } + { $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* } + { $( $parsed:tt )* } + { $eval:block } + { + let $param:ident in _ .. _ => $param_instancer:expr ; + $( $rest:tt )* + } + $postcode:block + ) => { $crate::benchmark_backend! { - $instance $name { - $( { $common , $common_from , $common_to , $common_instancer } )* - } { - $( $parsed )* - } { $eval } { + { $( $instance)? } + $name + { $( $where_clause )* } + { $( { $common , $common_from , $common_to , $common_instancer } )* } + { $( $parsed )* } + { $eval } + { let $param in ({ $( let $common = $common_from; )* $param }) .. ({ $( let $common = $common_to; )* $param }) => $param_instancer ; $( $rest )* - } $postcode + } + $postcode } }; // mutation arm to look after a single tt for param_from. - ($instance:ident $name:ident { - $( $common:tt )* - } { - $( $parsed:tt )* - } { $eval:block } { - let $param:ident in $param_from:tt .. $param_to:expr => $param_instancer:expr ; - $( $rest:tt )* - } $postcode:block) => { + ( + { $( $instance:ident )? } + $name:ident + { $( $where_clause:tt )* } + { $( $common:tt )* } + { $( $parsed:tt )* } + { $eval:block } + { + let $param:ident in $param_from:tt .. $param_to:expr => $param_instancer:expr ; + $( $rest:tt )* + } + $postcode:block + ) => { $crate::benchmark_backend! { - $instance $name { $( $common )* } { $( $parsed )* } { $eval } { + { $( $instance)? } + $name + { $( $where_clause )* } + { $( $common )* } + { $( $parsed )* } + { $eval } + { let $param in ( $param_from ) .. $param_to => $param_instancer; $( $rest )* - } $postcode + } + $postcode } }; // mutation arm to look after the default tail of `=> ()` - ($instance:ident $name:ident { - $( $common:tt )* - } { - $( $parsed:tt )* - } { $eval:block } { - let $param:ident in $param_from:tt .. $param_to:expr; - $( $rest:tt )* - } $postcode:block) => { + ( + { $( $instance:ident )? } + $name:ident + { $( $where_clause:tt )* } + { $( $common:tt )* } + { $( $parsed:tt )* } + { $eval:block } + { + let $param:ident in $param_from:tt .. $param_to:expr; + $( $rest:tt )* + } + $postcode:block + ) => { $crate::benchmark_backend! { - $instance $name { $( $common )* } { $( $parsed )* } { $eval } { + { $( $instance)? } + $name + { $( $where_clause )* } + { $( $common )* } + { $( $parsed )* } + { $eval } + { let $param in $param_from .. $param_to => (); $( $rest )* - } $postcode + } + $postcode } }; // mutation arm to look after `let _ =` - ($instance:ident $name:ident { - $( $common:tt )* - } { - $( $parsed:tt )* - } { $eval:block } { - let $pre_id:tt = $pre_ex:expr; - $( $rest:tt )* - } $postcode:block) => { + ( + { $( $instance:ident )? } + $name:ident + { $( $where_clause:tt )* } + { $( $common:tt )* } + { $( $parsed:tt )* } + { $eval:block } + { + let $pre_id:tt = $pre_ex:expr; + $( $rest:tt )* + } + $postcode:block + ) => { $crate::benchmark_backend! { - $instance $name { $( $common )* } { $( $parsed )* } { $eval } { + { $( $instance)? } + $name + { $( $where_clause )* } + { $( $common )* } + { $( $parsed )* } + { $eval } + { let $pre_id : _ = $pre_ex; $( $rest )* - } $postcode - } - }; - // no instance actioning arm - (NO_INSTANCE $name:ident { - $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* - } { - $( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )* - $( PARAM { $param:ident , $param_from:expr , $param_to:expr , $param_instancer:expr } )* - } { $eval:block } { $( $post:tt )* } $postcode:block) => { - #[allow(non_camel_case_types)] - struct $name; - #[allow(unused_variables)] - impl $crate::BenchmarkingSetup for $name { - fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> { - vec! [ - $( - ($crate::BenchmarkParameter::$param, $param_from, $param_to) - ),* - ] - } - - fn instance(&self, components: &[($crate::BenchmarkParameter, u32)]) - -> Result Result<(), &'static str>>, &'static str> - { - $( - let $common = $common_from; - )* - $( - // Prepare instance - let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1; - )* - $( - let $pre_id : $pre_ty = $pre_ex; - )* - $( $param_instancer ; )* - $( $post )* - - Ok(Box::new(move || -> Result<(), &'static str> { $eval; Ok(()) })) - } - - fn verify(&self, components: &[($crate::BenchmarkParameter, u32)]) - -> Result Result<(), &'static str>>, &'static str> - { - $( - let $common = $common_from; - )* - $( - // Prepare instance - let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1; - )* - $( - let $pre_id : $pre_ty = $pre_ex; - )* - $( $param_instancer ; )* - $( $post )* - - Ok(Box::new(move || -> Result<(), &'static str> { $eval; $postcode; Ok(()) })) } + $postcode } }; - // instance actioning arm - (INSTANCE $name:ident { - $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* - } { - $( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )* - $( PARAM { $param:ident , $param_from:expr , $param_to:expr , $param_instancer:expr } )* - } { $eval:block } { $( $post:tt )* } $postcode:block) => { + // actioning arm + ( + { $( $instance:ident )? } + $name:ident + { $( $where_clause:tt )* } + { $( { $common:ident , $common_from:tt , $common_to:expr , $common_instancer:expr } )* } + { + $( PRE { $pre_id:tt , $pre_ty:ty , $pre_ex:expr } )* + $( PARAM { $param:ident , $param_from:expr , $param_to:expr , $param_instancer:expr } )* + } + { $eval:block } + { $( $post:tt )* } + $postcode:block + ) => { #[allow(non_camel_case_types)] struct $name; #[allow(unused_variables)] - impl, I: Instance> $crate::BenchmarkingSetupInstance for $name { + impl, I: Instance)? > + $crate::BenchmarkingSetup for $name + where $( $where_clause )* + { fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> { vec! [ $( @@ -565,7 +656,9 @@ macro_rules! benchmark_backend { )* $( // Prepare instance - let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1; + let $param = components.iter() + .find(|&c| c.0 == $crate::BenchmarkParameter::$param) + .unwrap().1; )* $( let $pre_id : $pre_ty = $pre_ex; @@ -584,7 +677,9 @@ macro_rules! benchmark_backend { )* $( // Prepare instance - let $param = components.iter().find(|&c| c.0 == $crate::BenchmarkParameter::$param).unwrap().1; + let $param = components.iter() + .find(|&c| c.0 == $crate::BenchmarkParameter::$param) + .unwrap().1; )* $( let $pre_id : $pre_ty = $pre_ex; @@ -595,27 +690,30 @@ macro_rules! benchmark_backend { Ok(Box::new(move || -> Result<(), &'static str> { $eval; $postcode; Ok(()) })) } } - } + }; } -/// Creates a `SelectedBenchmark` enum implementing `BenchmarkingSetup`. -/// -/// Every variant must implement [`BenchmarkingSetup`]. -/// -/// ```nocompile -/// -/// struct Transfer; -/// impl BenchmarkingSetup for Transfer { ... } -/// -/// struct SetBalance; -/// impl BenchmarkingSetup for SetBalance { ... } -/// -/// selected_benchmark!(Transfer, SetBalance); -/// ``` +// Creates a `SelectedBenchmark` enum implementing `BenchmarkingSetup`. +// +// Every variant must implement [`BenchmarkingSetup`]. +// +// ```nocompile +// +// struct Transfer; +// impl BenchmarkingSetup for Transfer { ... } +// +// struct SetBalance; +// impl BenchmarkingSetup for SetBalance { ... } +// +// selected_benchmark!({} Transfer {} SetBalance); +// ``` #[macro_export] +#[doc(hidden)] macro_rules! selected_benchmark { ( - NO_INSTANCE $( $bench:ident ),* + { $( $where_clause:tt )* } + { $( $instance:ident )? } + $( { $( $bench_inst:ident )? } $bench:ident )* ) => { // The list of available benchmarks for this pallet. #[allow(non_camel_case_types)] @@ -624,10 +722,17 @@ macro_rules! selected_benchmark { } // Allow us to select a benchmark from the list of available benchmarks. - impl $crate::BenchmarkingSetup for SelectedBenchmark { + impl, I: Instance )? > + $crate::BenchmarkingSetup for SelectedBenchmark + where $( $where_clause )* + { fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> { match self { - $( Self::$bench => <$bench as $crate::BenchmarkingSetup>::components(&$bench), )* + $( + Self::$bench => < + $bench as $crate::BenchmarkingSetup + >::components(&$bench), + )* } } @@ -635,7 +740,11 @@ macro_rules! selected_benchmark { -> Result Result<(), &'static str>>, &'static str> { match self { - $( Self::$bench => <$bench as $crate::BenchmarkingSetup>::instance(&$bench, components), )* + $( + Self::$bench => < + $bench as $crate::BenchmarkingSetup + >::instance(&$bench, components), + )* } } @@ -643,57 +752,37 @@ macro_rules! selected_benchmark { -> Result Result<(), &'static str>>, &'static str> { match self { - $( Self::$bench => <$bench as $crate::BenchmarkingSetup>::verify(&$bench, components), )* + $( + Self::$bench => < + $bench as $crate::BenchmarkingSetup + >::verify(&$bench, components), + )* } } } }; - ( - INSTANCE $( $bench:ident ),* - ) => { - // The list of available benchmarks for this pallet. - #[allow(non_camel_case_types)] - enum SelectedBenchmark { - $( $bench, )* - } - - // Allow us to select a benchmark from the list of available benchmarks. - impl, I: Instance> $crate::BenchmarkingSetupInstance for SelectedBenchmark { - fn components(&self) -> Vec<($crate::BenchmarkParameter, u32, u32)> { - match self { - $( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance>::components(&$bench), )* - } - } - - fn instance(&self, components: &[($crate::BenchmarkParameter, u32)]) - -> Result Result<(), &'static str>>, &'static str> - { - match self { - $( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance>::instance(&$bench, components), )* - } - } - - fn verify(&self, components: &[($crate::BenchmarkParameter, u32)]) - -> Result Result<(), &'static str>>, &'static str> - { - match self { - $( Self::$bench => <$bench as $crate::BenchmarkingSetupInstance>::verify(&$bench, components), )* - } - } - } - } } #[macro_export] +#[doc(hidden)] macro_rules! impl_benchmark { ( - NO_INSTANCE $( $name:ident ),* + { $( $where_clause:tt )* } + { $( $instance:ident )? } + ( $( { $( $name_inst:ident )? } $name:ident )* ) + ( $( $name_extra:ident ),* ) ) => { - impl $crate::Benchmarking<$crate::BenchmarkResults> for Module - where T: frame_system::Trait + impl, I: Instance)? > + $crate::Benchmarking<$crate::BenchmarkResults> for Module + where T: frame_system::Trait, $( $where_clause )* { - fn benchmarks() -> Vec<&'static [u8]> { - vec![ $( stringify!($name).as_ref() ),* ] + fn benchmarks(extra: bool) -> Vec<&'static [u8]> { + let mut all = vec![ $( stringify!($name).as_ref() ),* ]; + if !extra { + let extra = [ $( stringify!($name_extra).as_ref() ),* ]; + all.retain(|x| !extra.contains(x)); + } + all } fn run_benchmark( @@ -702,6 +791,7 @@ macro_rules! impl_benchmark { highest_range_values: &[u32], steps: &[u32], repeat: u32, + whitelist: &[$crate::TrackedStorageKey] ) -> Result, &'static str> { // Map the input to the selected benchmark. let extrinsic = sp_std::str::from_utf8(extrinsic) @@ -711,263 +801,189 @@ macro_rules! impl_benchmark { _ => return Err("Could not find extrinsic."), }; + // Add whitelist to DB including whitelisted caller + let mut whitelist = whitelist.to_vec(); + let whitelisted_caller_key = + as frame_support::storage::StorageMap<_,_>>::hashed_key_for( + $crate::whitelisted_caller::() + ); + whitelist.push(whitelisted_caller_key.into()); + $crate::benchmarking::set_whitelist(whitelist); + // Warm up the DB $crate::benchmarking::commit_db(); $crate::benchmarking::wipe_db(); - let components = >::components(&selected_benchmark); + let components = < + SelectedBenchmark as $crate::BenchmarkingSetup + >::components(&selected_benchmark); let mut results: Vec<$crate::BenchmarkResults> = Vec::new(); // Default number of steps for a component. let mut prev_steps = 10; - // Select the component we will be benchmarking. Each component will be benchmarked. - for (idx, (name, low, high)) in components.iter().enumerate() { - // Get the number of steps for this component. - let steps = steps.get(idx).cloned().unwrap_or(prev_steps); - prev_steps = steps; - - // Skip this loop if steps is zero - if steps == 0 { continue } - - let lowest = lowest_range_values.get(idx).cloned().unwrap_or(*low); - let highest = highest_range_values.get(idx).cloned().unwrap_or(*high); - - let diff = highest - lowest; - - // Create up to `STEPS` steps for that component between high and low. - let step_size = (diff / steps).max(1); - let num_of_steps = diff / step_size + 1; - - for s in 0..num_of_steps { - // This is the value we will be testing for component `name` - let component_value = lowest + step_size * s; - - // Select the max value for all the other components. - let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter() - .enumerate() - .map(|(idx, (n, _, h))| - if n == name { - (*n, component_value) - } else { - (*n, *highest_range_values.get(idx).unwrap_or(h)) - } - ) - .collect(); - - // Run the benchmark `repeat` times. - for _ in 0..repeat { - // Set up the externalities environment for the setup we want to benchmark. - let closure_to_benchmark = >::instance(&selected_benchmark, &c)?; - - // Set the block number to at least 1 so events are deposited. - if $crate::Zero::is_zero(&frame_system::Module::::block_number()) { - frame_system::Module::::set_block_number(1.into()); - } - - // Commit the externalities to the database, flushing the DB cache. - // This will enable worst case scenario for reading from the database. - $crate::benchmarking::commit_db(); - - // Time the extrinsic logic. - frame_support::debug::trace!(target: "benchmark", "Start Benchmark: {:?} {:?}", name, component_value); - let start_extrinsic = $crate::benchmarking::current_time(); - closure_to_benchmark()?; - let finish_extrinsic = $crate::benchmarking::current_time(); - let elapsed_extrinsic = finish_extrinsic - start_extrinsic; - frame_support::debug::trace!(target: "benchmark", "End Benchmark: {} ns", elapsed_extrinsic); - - // Time the storage root recalculation. - let start_storage_root = $crate::benchmarking::current_time(); - $crate::storage_root(); - let finish_storage_root = $crate::benchmarking::current_time(); - let elapsed_storage_root = finish_storage_root - start_storage_root; - - results.push((c.clone(), elapsed_extrinsic, elapsed_storage_root)); - - // Wipe the DB back to the genesis state. - $crate::benchmarking::wipe_db(); + let repeat_benchmark = | + repeat: u32, + c: Vec<($crate::BenchmarkParameter, u32)>, + results: &mut Vec<$crate::BenchmarkResults>, + | -> Result<(), &'static str> { + // Run the benchmark `repeat` times. + for _ in 0..repeat { + // Set up the externalities environment for the setup we want to + // benchmark. + let closure_to_benchmark = < + SelectedBenchmark as $crate::BenchmarkingSetup + >::instance(&selected_benchmark, &c)?; + + // Set the block number to at least 1 so events are deposited. + if $crate::Zero::is_zero(&frame_system::Module::::block_number()) { + frame_system::Module::::set_block_number(1.into()); } + + // Commit the externalities to the database, flushing the DB cache. + // This will enable worst case scenario for reading from the database. + $crate::benchmarking::commit_db(); + + // Reset the read/write counter so we don't count operations in the setup process. + $crate::benchmarking::reset_read_write_count(); + + // Time the extrinsic logic. + frame_support::debug::trace!( + target: "benchmark", + "Start Benchmark: {:?}", c + ); + + let start_extrinsic = $crate::benchmarking::current_time(); + closure_to_benchmark()?; + let finish_extrinsic = $crate::benchmarking::current_time(); + let elapsed_extrinsic = finish_extrinsic - start_extrinsic; + // Commit the changes to get proper write count + $crate::benchmarking::commit_db(); + frame_support::debug::trace!( + target: "benchmark", + "End Benchmark: {} ns", elapsed_extrinsic + ); + let read_write_count = $crate::benchmarking::read_write_count(); + frame_support::debug::trace!( + target: "benchmark", + "Read/Write Count {:?}", read_write_count + ); + + // Time the storage root recalculation. + let start_storage_root = $crate::benchmarking::current_time(); + $crate::storage_root(); + let finish_storage_root = $crate::benchmarking::current_time(); + let elapsed_storage_root = finish_storage_root - start_storage_root; + + results.push($crate::BenchmarkResults { + components: c.clone(), + extrinsic_time: elapsed_extrinsic, + storage_root_time: elapsed_storage_root, + reads: read_write_count.0, + repeat_reads: read_write_count.1, + writes: read_write_count.2, + repeat_writes: read_write_count.3, + }); + + // Wipe the DB back to the genesis state. + $crate::benchmarking::wipe_db(); } - } - return Ok(results); - } - } - }; - ( - INSTANCE $( $name:ident ),* - ) => { - impl, I: Instance> $crate::Benchmarking<$crate::BenchmarkResults> for Module - where T: frame_system::Trait - { - fn benchmarks() -> Vec<&'static [u8]> { - vec![ $( stringify!($name).as_ref() ),* ] - } - fn run_benchmark( - extrinsic: &[u8], - lowest_range_values: &[u32], - highest_range_values: &[u32], - steps: &[u32], - repeat: u32, - ) -> Result, &'static str> { - // Map the input to the selected benchmark. - let extrinsic = sp_std::str::from_utf8(extrinsic) - .map_err(|_| "`extrinsic` is not a valid utf8 string!")?; - let selected_benchmark = match extrinsic { - $( stringify!($name) => SelectedBenchmark::$name, )* - _ => return Err("Could not find extrinsic."), + Ok(()) }; - // Warm up the DB - $crate::benchmarking::commit_db(); - $crate::benchmarking::wipe_db(); - - let components = >::components(&selected_benchmark); - let mut results: Vec<$crate::BenchmarkResults> = Vec::new(); - - // Default number of steps for a component. - let mut prev_steps = 10; - - // Select the component we will be benchmarking. Each component will be benchmarked. - for (idx, (name, low, high)) in components.iter().enumerate() { - // Get the number of steps for this component. - let steps = steps.get(idx).cloned().unwrap_or(prev_steps); - prev_steps = steps; - - // Skip this loop if steps is zero - if steps == 0 { continue } - - let lowest = lowest_range_values.get(idx).cloned().unwrap_or(*low); - let highest = highest_range_values.get(idx).cloned().unwrap_or(*high); - - let diff = highest - lowest; - - // Create up to `STEPS` steps for that component between high and low. - let step_size = (diff / steps).max(1); - let num_of_steps = diff / step_size + 1; + if components.is_empty() { + repeat_benchmark(repeat, Default::default(), &mut results)?; + } else { + // Select the component we will be benchmarking. Each component will be benchmarked. + for (idx, (name, low, high)) in components.iter().enumerate() { + // Get the number of steps for this component. + let steps = steps.get(idx).cloned().unwrap_or(prev_steps); + prev_steps = steps; - for s in 0..num_of_steps { - // This is the value we will be testing for component `name` - let component_value = lowest + step_size * s; + // Skip this loop if steps is zero + if steps == 0 { continue } - // Select the max value for all the other components. - let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter() - .enumerate() - .map(|(idx, (n, _, h))| - if n == name { - (*n, component_value) - } else { - (*n, *highest_range_values.get(idx).unwrap_or(h)) - } - ) - .collect(); + let lowest = lowest_range_values.get(idx).cloned().unwrap_or(*low); + let highest = highest_range_values.get(idx).cloned().unwrap_or(*high); - // Run the benchmark `repeat` times. - for _ in 0..repeat { - // Set up the externalities environment for the setup we want to benchmark. - let closure_to_benchmark = >::instance(&selected_benchmark, &c)?; + let diff = highest - lowest; - // Set the block number to at least 1 so events are deposited. - if $crate::Zero::is_zero(&frame_system::Module::::block_number()) { - frame_system::Module::::set_block_number(1.into()); - } + // Create up to `STEPS` steps for that component between high and low. + let step_size = (diff / steps).max(1); + let num_of_steps = diff / step_size + 1; - // Commit the externalities to the database, flushing the DB cache. - // This will enable worst case scenario for reading from the database. - $crate::benchmarking::commit_db(); + for s in 0..num_of_steps { + // This is the value we will be testing for component `name` + let component_value = lowest + step_size * s; - // Time the extrinsic logic. - frame_support::debug::trace!(target: "benchmark", "Start Benchmark: {:?} {:?}", name, component_value); - let start_extrinsic = $crate::benchmarking::current_time(); - closure_to_benchmark()?; - let finish_extrinsic = $crate::benchmarking::current_time(); - let elapsed_extrinsic = finish_extrinsic - start_extrinsic; - frame_support::debug::trace!(target: "benchmark", "End Benchmark: {} ns", elapsed_extrinsic); - - // Time the storage root recalculation. - let start_storage_root = $crate::benchmarking::current_time(); - $crate::storage_root(); - let finish_storage_root = $crate::benchmarking::current_time(); - let elapsed_storage_root = finish_storage_root - start_storage_root; - - results.push((c.clone(), elapsed_extrinsic, elapsed_storage_root)); + // Select the max value for all the other components. + let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter() + .enumerate() + .map(|(idx, (n, _, h))| + if n == name { + (*n, component_value) + } else { + (*n, *highest_range_values.get(idx).unwrap_or(h)) + } + ) + .collect(); - // Wipe the DB back to the genesis state. - $crate::benchmarking::wipe_db(); + repeat_benchmark(repeat, c, &mut results)?; } } } return Ok(results); } } - } + }; } -// This creates unit tests from the main benchmark macro. -// They run the benchmark using the `high` and `low` value for each component +// This creates a unit test for one benchmark of the main benchmark macro. +// It runs the benchmark using the `high` and `low` value for each component // and ensure that everything completes successfully. #[macro_export] -macro_rules! impl_benchmark_tests { +#[doc(hidden)] +macro_rules! impl_benchmark_test { ( - NO_INSTANCE - $( $name:ident ),* + { $( $where_clause:tt )* } + { $( $instance:ident )? } + $name:ident ) => { - $( - $crate::paste::item! { - fn [] () -> Result<(), &'static str> - where T: frame_system::Trait - { - let selected_benchmark = SelectedBenchmark::$name; - let components = >::components(&selected_benchmark); - - for (_, (name, low, high)) in components.iter().enumerate() { - // Test only the low and high value, assuming values in the middle won't break - for component_value in vec![low, high] { - // Select the max value for all the other components. - let c: Vec<($crate::BenchmarkParameter, u32)> = components.iter() - .enumerate() - .map(|(_, (n, _, h))| - if n == name { - (*n, *component_value) - } else { - (*n, *h) - } - ) - .collect(); - - // Set up the verification state - let closure_to_verify = >::verify(&selected_benchmark, &c)?; + $crate::paste::item! { + fn [] () -> Result<(), &'static str> + where T: frame_system::Trait, $( $where_clause )* + { + let selected_benchmark = SelectedBenchmark::$name; + let components = < + SelectedBenchmark as $crate::BenchmarkingSetup + >::components(&selected_benchmark); + + let execute_benchmark = | + c: Vec<($crate::BenchmarkParameter, u32)> + | -> Result<(), &'static str> { + // Set up the verification state + let closure_to_verify = < + SelectedBenchmark as $crate::BenchmarkingSetup + >::verify(&selected_benchmark, &c)?; + + // Set the block number to at least 1 so events are deposited. + if $crate::Zero::is_zero(&frame_system::Module::::block_number()) { + frame_system::Module::::set_block_number(1.into()); + } - // Set the block number to at least 1 so events are deposited. - if $crate::Zero::is_zero(&frame_system::Module::::block_number()) { - frame_system::Module::::set_block_number(1.into()); - } + // Run verification + closure_to_verify()?; - // Run verification - closure_to_verify()?; + // Reset the state + $crate::benchmarking::wipe_db(); - // Reset the state - $crate::benchmarking::wipe_db(); - } - } Ok(()) - } - } - )* - }; - ( - INSTANCE - $( $name:ident ),* - ) => { - $( - $crate::paste::item! { - fn [] () -> Result<(), &'static str> - where T: frame_system::Trait - { - let selected_benchmark = SelectedBenchmark::$name; - let components = >::components(&selected_benchmark); + }; + if components.is_empty() { + execute_benchmark(Default::default())?; + } else { for (_, (name, low, high)) in components.iter().enumerate() { // Test only the low and high value, assuming values in the middle won't break for component_value in vec![low, high] { @@ -983,25 +999,13 @@ macro_rules! impl_benchmark_tests { ) .collect(); - // Set up the verification state - let closure_to_verify = >::verify(&selected_benchmark, &c)?; - - // Set the block number to at least 1 so events are deposited. - if $crate::Zero::is_zero(&frame_system::Module::::block_number()) { - frame_system::Module::::set_block_number(1.into()); - } - - // Run verification - closure_to_verify()?; - - // Reset the state - $crate::benchmarking::wipe_db(); + execute_benchmark(c)?; } } - Ok(()) } + Ok(()) } - )* + } }; } @@ -1011,7 +1015,27 @@ macro_rules! impl_benchmark_tests { /// First create an object that holds in the input parameters for the benchmark: /// /// ```ignore -/// let params = (&pallet, &benchmark, &lowest_range_values, &highest_range_values, &steps, repeat); +/// let params = (&pallet, &benchmark, &lowest_range_values, &highest_range_values, &steps, repeat, &whitelist); +/// ``` +/// +/// The `whitelist` is a parameter you pass to control the DB read/write tracking. +/// We use a vector of [TrackedStorageKey](./struct.TrackedStorageKey.html), which is a simple struct used to set +/// if a key has been read or written to. +/// +/// For values that should be skipped entirely, we can just pass `key.into()`. For example: +/// +/// ``` +/// use frame_benchmarking::TrackedStorageKey; +/// let whitelist: Vec = vec![ +/// // Block Number +/// hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), +/// // Total Issuance +/// hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(), +/// // Execution Phase +/// hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(), +/// // Event Count +/// hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(), +/// ]; /// ``` /// /// Then define a mutable local variable to hold your `BenchmarkBatch` object: @@ -1020,24 +1044,25 @@ macro_rules! impl_benchmark_tests { /// let mut batches = Vec::::new(); /// ```` /// -/// Then add the pallets you want to benchmark to this object, including the string -/// you want to use target a particular pallet: +/// Then add the pallets you want to benchmark to this object, using their crate name and generated +/// module struct: /// /// ```ignore -/// add_benchmark!(params, batches, b"balances", Balances); -/// add_benchmark!(params, batches, b"identity", Identity); -/// add_benchmark!(params, batches, b"session", SessionBench::); +/// add_benchmark!(params, batches, pallet_balances, Balances); +/// add_benchmark!(params, batches, pallet_session, SessionBench::); +/// add_benchmark!(params, batches, frame_system, SystemBench::); /// ... /// ``` /// /// At the end of `dispatch_benchmark`, you should return this batches object. #[macro_export] macro_rules! add_benchmark { - ( $params:ident, $batches:ident, $name:literal, $( $location:tt )* ) => ( - let (pallet, benchmark, lowest_range_values, highest_range_values, steps, repeat) = $params; - if &pallet[..] == &$name[..] || &pallet[..] == &b"*"[..] { + ( $params:ident, $batches:ident, $name:ident, $( $location:tt )* ) => ( + let name_string = stringify!($name).as_bytes(); + let (pallet, benchmark, lowest_range_values, highest_range_values, steps, repeat, whitelist, extra) = $params; + if &pallet[..] == &name_string[..] || &pallet[..] == &b"*"[..] { if &pallet[..] == &b"*"[..] || &benchmark[..] == &b"*"[..] { - for benchmark in $( $location )*::benchmarks().into_iter() { + for benchmark in $( $location )*::benchmarks(extra).into_iter() { $batches.push($crate::BenchmarkBatch { results: $( $location )*::run_benchmark( benchmark, @@ -1045,8 +1070,9 @@ macro_rules! add_benchmark { &highest_range_values[..], &steps[..], repeat, + whitelist, )?, - pallet: $name.to_vec(), + pallet: name_string.to_vec(), benchmark: benchmark.to_vec(), }); } @@ -1058,8 +1084,9 @@ macro_rules! add_benchmark { &highest_range_values[..], &steps[..], repeat, + whitelist, )?, - pallet: $name.to_vec(), + pallet: name_string.to_vec(), benchmark: benchmark.clone(), }); } diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 67ad9b4d22025dd8b4132ee1b023049132cf6da8..127645d4305643f3ecfa7c2f3c391c61daf6a400 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -1,25 +1,25 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for the module. #![cfg(test)] use super::*; -use codec::Decode; use sp_std::prelude::*; use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::{H256, Header}}; use frame_support::{ @@ -29,13 +29,17 @@ use frame_support::{ use frame_system::{RawOrigin, ensure_signed, ensure_none}; decl_storage! { - trait Store for Module as Test { + trait Store for Module as Test where + ::OtherEvent: Into<::Event> + { Value get(fn value): Option; } } decl_module! { - pub struct Module for enum Call where origin: T::Origin { + pub struct Module for enum Call where + origin: T::Origin, ::OtherEvent: Into<::Event> + { #[weight = 0] fn set_value(origin, n: u32) -> DispatchResult { let _sender = ensure_signed(origin)?; @@ -55,17 +59,21 @@ impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } -pub trait Trait { +pub trait OtherTrait { + type OtherEvent; +} + +pub trait Trait: frame_system::Trait + OtherTrait + where Self::OtherEvent: Into<::Event> +{ type Event; - type BlockNumber; - type AccountId: 'static + Default + Decode; - type Origin: From> + Into, Self::Origin>>; } #[derive(Clone, Eq, PartialEq)] pub struct Test; impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -81,6 +89,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = (); type MaximumBlockLength = (); type AvailableBlockRatio = (); type Version = (); @@ -88,22 +97,24 @@ impl frame_system::Trait for Test { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl Trait for Test { type Event = (); - type BlockNumber = u32; - type Origin = Origin; - type AccountId = u64; } -// This function basically just builds a genesis storage key/value store according to -// our desired mockup. +impl OtherTrait for Test { + type OtherEvent = (); +} + fn new_test_ext() -> sp_io::TestExternalities { frame_system::GenesisConfig::default().build_storage::().unwrap().into() } benchmarks!{ + where_clause { where ::OtherEvent: Into<::Event> } + _ { // Define a common range for `b`. let b in 1 .. 1000 => (); @@ -148,18 +159,22 @@ benchmarks!{ verify { ensure!(m[0] == 0, "You forgot to sort!") } + + no_components { + let caller = account::("caller", 0, 0); + }: set_value(RawOrigin::Signed(caller), 0) } #[test] fn benchmarks_macro_works() { // Check benchmark creation for `set_value`. - let selected_benchmark = SelectedBenchmark::set_value; + let selected = SelectedBenchmark::set_value; - let components = >::components(&selected_benchmark); + let components = >::components(&selected); assert_eq!(components, vec![(BenchmarkParameter::b, 1, 1000)]); let closure = >::instance( - &selected_benchmark, + &selected, &[(BenchmarkParameter::b, 1)], ).expect("failed to create closure"); @@ -171,12 +186,12 @@ fn benchmarks_macro_works() { #[test] fn benchmarks_macro_rename_works() { // Check benchmark creation for `other_dummy`. - let selected_benchmark = SelectedBenchmark::other_name; - let components = >::components(&selected_benchmark); + let selected = SelectedBenchmark::other_name; + let components = >::components(&selected); assert_eq!(components, vec![(BenchmarkParameter::b, 1, 1000)]); let closure = >::instance( - &selected_benchmark, + &selected, &[(BenchmarkParameter::b, 1)], ).expect("failed to create closure"); @@ -187,13 +202,13 @@ fn benchmarks_macro_rename_works() { #[test] fn benchmarks_macro_works_for_non_dispatchable() { - let selected_benchmark = SelectedBenchmark::sort_vector; + let selected = SelectedBenchmark::sort_vector; - let components = >::components(&selected_benchmark); + let components = >::components(&selected); assert_eq!(components, vec![(BenchmarkParameter::x, 1, 10000)]); let closure = >::instance( - &selected_benchmark, + &selected, &[(BenchmarkParameter::x, 1)], ).expect("failed to create closure"); @@ -203,10 +218,10 @@ fn benchmarks_macro_works_for_non_dispatchable() { #[test] fn benchmarks_macro_verify_works() { // Check postcondition for benchmark `set_value` is valid. - let selected_benchmark = SelectedBenchmark::set_value; + let selected = SelectedBenchmark::set_value; let closure = >::verify( - &selected_benchmark, + &selected, &[(BenchmarkParameter::b, 1)], ).expect("failed to create closure"); @@ -223,5 +238,6 @@ fn benchmarks_generate_unit_tests() { assert_ok!(test_benchmark_sort_vector::()); assert_err!(test_benchmark_bad_origin::(), "Bad origin"); assert_err!(test_benchmark_bad_verify::(), "You forgot to sort!"); + assert_ok!(test_benchmark_no_components::()); }); } diff --git a/frame/benchmarking/src/utils.rs b/frame/benchmarking/src/utils.rs index 41b968fbfcad6be7be50a5d737399a9fcd41d0c1..8c25f035802fc6e99805c1b192fc7ce484a9b57e 100644 --- a/frame/benchmarking/src/utils.rs +++ b/frame/benchmarking/src/utils.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Interfaces, types and utils for benchmarking a FRAME runtime. @@ -20,6 +21,7 @@ use codec::{Encode, Decode}; use sp_std::{vec::Vec, prelude::Box}; use sp_io::hashing::blake2_256; use sp_runtime::RuntimeString; +use sp_storage::TrackedStorageKey; /// An alphabet of possible parameters to use for benchmarking. #[derive(Encode, Decode, Clone, Copy, PartialEq, Debug)] @@ -29,6 +31,13 @@ pub enum BenchmarkParameter { a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, } +#[cfg(feature = "std")] +impl std::fmt::Display for BenchmarkParameter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + /// The results of a single of benchmark. #[derive(Encode, Decode, Clone, PartialEq, Debug)] pub struct BenchmarkBatch { @@ -43,7 +52,16 @@ pub struct BenchmarkBatch { /// Results from running benchmarks on a FRAME pallet. /// Contains duration of the function call in nanoseconds along with the benchmark parameters /// used for that benchmark result. -pub type BenchmarkResults = (Vec<(BenchmarkParameter, u32)>, u128, u128); +#[derive(Encode, Decode, Default, Clone, PartialEq, Debug)] +pub struct BenchmarkResults { + pub components: Vec<(BenchmarkParameter, u32)>, + pub extrinsic_time: u128, + pub storage_root_time: u128, + pub reads: u32, + pub repeat_reads: u32, + pub writes: u32, + pub repeat_writes: u32, +} sp_api::decl_runtime_apis! { /// Runtime api for benchmarking a FRAME runtime. @@ -56,6 +74,7 @@ sp_api::decl_runtime_apis! { highest_range_values: Vec, steps: Vec, repeat: u32, + extra: bool, ) -> Result, RuntimeString>; } } @@ -82,13 +101,64 @@ pub trait Benchmarking { fn commit_db(&mut self) { self.commit() } + + /// Get the read/write count. + fn read_write_count(&self) -> (u32, u32, u32, u32) { + self.read_write_count() + } + + /// Reset the read/write count. + fn reset_read_write_count(&mut self) { + self.reset_read_write_count() + } + + /// Get the DB whitelist. + fn get_whitelist(&self) -> Vec { + self.get_whitelist() + } + + /// Set the DB whitelist. + fn set_whitelist(&mut self, new: Vec) { + self.set_whitelist(new) + } + + // Add a new item to the DB whitelist. + fn add_to_whitelist(&mut self, add: TrackedStorageKey) { + let mut whitelist = self.get_whitelist(); + match whitelist.iter_mut().find(|x| x.key == add.key) { + // If we already have this key in the whitelist, update to be the most constrained value. + Some(item) => { + *item = TrackedStorageKey { + key: add.key, + has_been_read: item.has_been_read || add.has_been_read, + has_been_written: item.has_been_written || add.has_been_written, + } + }, + // If the key does not exist, add it. + None => { + whitelist.push(add); + } + } + self.set_whitelist(whitelist); + } + + // Remove an item from the DB whitelist. + fn remove_from_whitelist(&mut self, remove: Vec) { + let mut whitelist = self.get_whitelist(); + whitelist.retain(|x| x.key != remove); + self.set_whitelist(whitelist); + } } /// The pallet benchmarking trait. pub trait Benchmarking { /// Get the benchmarks available for this pallet. Generally there is one benchmark per /// extrinsic, so these are sometimes just called "extrinsics". - fn benchmarks() -> Vec<&'static [u8]>; + /// + /// Parameters + /// - `extra`: Also return benchmarks marked "extra" which would otherwise not be + /// needed for weight calculation. + fn benchmarks(extra: bool) -> Vec<&'static [u8]>; /// Run the benchmarks for this pallet. /// @@ -105,23 +175,15 @@ pub trait Benchmarking { highest_range_values: &[u32], steps: &[u32], repeat: u32, + whitelist: &[TrackedStorageKey] ) -> Result, &'static str>; } /// The required setup for creating a benchmark. -pub trait BenchmarkingSetup { - /// Return the components and their ranges which should be tested in this benchmark. - fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)>; - - /// Set up the storage, and prepare a closure to run the benchmark. - fn instance(&self, components: &[(BenchmarkParameter, u32)]) -> Result Result<(), &'static str>>, &'static str>; - - /// Set up the storage, and prepare a closure to test and verify the benchmark - fn verify(&self, components: &[(BenchmarkParameter, u32)]) -> Result Result<(), &'static str>>, &'static str>; -} - -/// The required setup for creating a benchmark. -pub trait BenchmarkingSetupInstance { +/// +/// Instance generic parameter is optional and can be used in order to capture unused generics for +/// instantiable pallets. +pub trait BenchmarkingSetup { /// Return the components and their ranges which should be tested in this benchmark. fn components(&self) -> Vec<(BenchmarkParameter, u32, u32)>; @@ -137,3 +199,8 @@ pub fn account(name: &'static str, index: u32, seed let entropy = (name, index, seed).using_encoded(blake2_256); AccountId::decode(&mut &entropy[..]).unwrap_or_default() } + +/// This caller account is automatically whitelisted for DB reads/writes by the benchmarking macro. +pub fn whitelisted_caller() -> AccountId { + account::("whitelisted_caller", 0, 0) +} diff --git a/frame/collective/Cargo.toml b/frame/collective/Cargo.toml index 2107bf0b2f5dbbd8834692890d376083b8e80fcc..42dc39b775d0242e5ed0245d0092244035c0997c 100644 --- a/frame/collective/Cargo.toml +++ b/frame/collective/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-collective" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Collective system: Members of a set of account IDs can make their collective feelings known through dispatched calls from one of two specialized origins." @@ -13,18 +13,18 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-dev", path = "../balances" } +hex-literal = "0.3.1" +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } [features] default = ["std"] diff --git a/frame/collective/README.md b/frame/collective/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e4928dbcf2d057ddd0d74062c6fb30a6e0fe118b --- /dev/null +++ b/frame/collective/README.md @@ -0,0 +1,22 @@ +Collective system: Members of a set of account IDs can make their collective feelings known +through dispatched calls from one of two specialized origins. + +The membership can be provided in one of two ways: either directly, using the Root-dispatchable +function `set_members`, or indirectly, through implementing the `ChangeMembers`. +The pallet assumes that the amount of members stays at or below `MAX_MEMBERS` for its weight +calculations, but enforces this neither in `set_members` nor in `change_members_sorted`. + +A "prime" member may be set allowing their vote to act as the default vote in case of any +abstentions after the voting period. + +Voting happens through motions comprising a proposal (i.e. a curried dispatchable) plus a +number of approvals required for it to pass and be called. Motions are open for members to +vote on for a minimum period given by `MotionDuration`. As soon as the needed number of +approvals is given, the motion is closed and executed. If the number of approvals is not reached +during the voting period, then `close` may be called by any account in order to force the end +the motion explicitly. If a prime member is defined then their vote is used in place of any +abstentions and the proposal is executed if there are enough approvals counting the new votes. + +If there are not, or if no prime is set, then the motion is dropped without being executed. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/collective/src/benchmarking.rs b/frame/collective/src/benchmarking.rs index 5c25051fd083716065cbb90a59b17041d7219724..2c777fadc4cc4f88b32e322e16d61d5e5f117a43 100644 --- a/frame/collective/src/benchmarking.rs +++ b/frame/collective/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Staking pallet benchmarking. @@ -20,16 +21,16 @@ use super::*; use frame_system::RawOrigin as SystemOrigin; use frame_system::EventRecord; -use frame_benchmarking::{benchmarks_instance, account}; +use frame_benchmarking::{benchmarks_instance, account, whitelisted_caller}; use sp_runtime::traits::Bounded; +use sp_std::mem::size_of; +use frame_system::Call as SystemCall; use frame_system::Module as System; use crate::Module as Collective; const SEED: u32 = 0; -const MAX_MEMBERS: u32 = 1000; -const MAX_PROPOSALS: u32 = 100; const MAX_BYTES: u32 = 1_024; fn assert_last_event, I: Instance>(generic_event: >::Event) { @@ -46,28 +47,64 @@ benchmarks_instance! { set_members { let m in 1 .. MAX_MEMBERS; let n in 1 .. MAX_MEMBERS; + let p in 1 .. T::MaxProposals::get(); // Set old members. // We compute the difference of old and new members, so it should influence timing. let mut old_members = vec![]; let mut last_old_member = T::AccountId::default(); - for i in 0 .. n { + for i in 0 .. m { last_old_member = account("old member", i, SEED); old_members.push(last_old_member.clone()); } + let old_members_count = old_members.len() as u32; - Collective::::set_members(SystemOrigin::Root.into(), old_members, Some(last_old_member))?; + Collective::::set_members( + SystemOrigin::Root.into(), + old_members.clone(), + Some(last_old_member.clone()), + MAX_MEMBERS, + )?; + + // Set a high threshold for proposals passing so that they stay around. + let threshold = m.max(2); + // Length of the proposals should be irrelevant to `set_members`. + let length = 100; + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; length]).into(); + Collective::::propose( + SystemOrigin::Signed(last_old_member.clone()).into(), + threshold, + Box::new(proposal.clone()), + MAX_BYTES, + )?; + let hash = T::Hashing::hash_of(&proposal); + // Vote on the proposal to increase state relevant for `set_members`. + // Not voting for `last_old_member` because they proposed and not voting for the first member + // to keep the proposal from passing. + for j in 2 .. m - 1 { + let voter = &old_members[j as usize]; + let approve = true; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + hash, + i, + approve, + )?; + } + } // Construct `new_members`. // It should influence timing since it will sort this vector. let mut new_members = vec![]; let mut last_member = T::AccountId::default(); - for i in 0 .. m { + for i in 0 .. n { last_member = account("member", i, SEED); new_members.push(last_member.clone()); } - }: _(SystemOrigin::Root, new_members.clone(), Some(last_member)) + }: _(SystemOrigin::Root, new_members.clone(), Some(last_member), MAX_MEMBERS) verify { new_members.sort(); assert_eq!(Collective::::members(), new_members); @@ -77,25 +114,29 @@ benchmarks_instance! { let m in 1 .. MAX_MEMBERS; let b in 1 .. MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; + // Construct `members`. let mut members = vec![]; - for i in 0 .. m { + for i in 0 .. m - 1 { let member = account("member", i, SEED); members.push(member); } - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members, None)?; + Collective::::set_members(SystemOrigin::Root.into(), members, None, MAX_MEMBERS)?; - let proposal: T::Proposal = frame_system::Call::::remark(vec![1; b as usize]).into(); + let proposal: T::Proposal = SystemCall::::remark(vec![1; b as usize]).into(); - }: _(SystemOrigin::Signed(caller), Box::new(proposal.clone())) + }: _(SystemOrigin::Signed(caller), Box::new(proposal.clone()), bytes_in_storage) verify { let proposal_hash = T::Hashing::hash_of(&proposal); // Note that execution fails due to mis-matched origin - assert_last_event::(RawEvent::MemberExecuted(proposal_hash, false).into()); + assert_last_event::( + RawEvent::MemberExecuted(proposal_hash, Err(DispatchError::BadOrigin)).into() + ); } // This tests when execution would happen immediately after proposal @@ -103,179 +144,242 @@ benchmarks_instance! { let m in 1 .. MAX_MEMBERS; let b in 1 .. MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; + // Construct `members`. let mut members = vec![]; - for i in 0 .. m { + for i in 0 .. m - 1 { let member = account("member", i, SEED); members.push(member); } - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members, None)?; + Collective::::set_members(SystemOrigin::Root.into(), members, None, MAX_MEMBERS)?; - let proposal: T::Proposal = frame_system::Call::::remark(vec![1; b as usize]).into(); + let proposal: T::Proposal = SystemCall::::remark(vec![1; b as usize]).into(); let threshold = 1; - }: propose(SystemOrigin::Signed(caller), threshold, Box::new(proposal.clone())) + }: propose(SystemOrigin::Signed(caller), threshold, Box::new(proposal.clone()), bytes_in_storage) verify { let proposal_hash = T::Hashing::hash_of(&proposal); // Note that execution fails due to mis-matched origin - assert_last_event::(RawEvent::Executed(proposal_hash, false).into()); + assert_last_event::( + RawEvent::Executed(proposal_hash, Err(DispatchError::BadOrigin)).into() + ); } // This tests when proposal is created and queued as "proposed" propose_proposed { - let m in 1 .. MAX_MEMBERS; - let p in 0 .. MAX_PROPOSALS; + let m in 2 .. MAX_MEMBERS; + let p in 1 .. T::MaxProposals::get(); let b in 1 .. MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; + // Construct `members`. let mut members = vec![]; - for i in 0 .. m { + for i in 0 .. m - 1 { let member = account("member", i, SEED); members.push(member); } - - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members, None)?; - - let threshold = m.max(2); + Collective::::set_members(SystemOrigin::Root.into(), members, None, MAX_MEMBERS)?; + let threshold = m; // Add previous proposals. - for i in 0 .. p { + for i in 0 .. p - 1 { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = frame_system::Call::::remark(vec![i as u8; b as usize]).into(); - Collective::::propose(SystemOrigin::Signed(caller.clone()).into(), threshold, Box::new(proposal))?; + let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; b as usize]).into(); + Collective::::propose( + SystemOrigin::Signed(caller.clone()).into(), + threshold, + Box::new(proposal), + bytes_in_storage, + )?; } - assert_eq!(Collective::::proposals().len(), p as usize); + assert_eq!(Collective::::proposals().len(), (p - 1) as usize); - let proposal: T::Proposal = frame_system::Call::::remark(vec![p as u8; b as usize]).into(); + let proposal: T::Proposal = SystemCall::::remark(vec![p as u8; b as usize]).into(); - }: propose(SystemOrigin::Signed(caller.clone()), threshold, Box::new(proposal.clone())) + }: propose(SystemOrigin::Signed(caller.clone()), threshold, Box::new(proposal.clone()), bytes_in_storage) verify { // New proposal is recorded - assert_eq!(Collective::::proposals().len(), (p + 1) as usize); + assert_eq!(Collective::::proposals().len(), p as usize); let proposal_hash = T::Hashing::hash_of(&proposal); - assert_last_event::(RawEvent::Proposed(caller, p, proposal_hash, threshold).into()); + assert_last_event::(RawEvent::Proposed(caller, p - 1, proposal_hash, threshold).into()); } - vote_insert { - let m in 2 .. MAX_MEMBERS; - let p in 1 .. MAX_PROPOSALS; - let b in 1 .. MAX_BYTES; + vote { + // We choose 5 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let m in 5 .. MAX_MEMBERS; + + let p = T::MaxProposals::get(); + let b = MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; // Construct `members`. let mut members = vec![]; - for i in 0 .. m { + let proposer: T::AccountId = account("proposer", 0, SEED); + members.push(proposer.clone()); + for i in 1 .. m - 1 { let member = account("member", i, SEED); members.push(member); } - - let caller: T::AccountId = account("caller", 0, SEED); - members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None)?; + let voter: T::AccountId = account("voter", 0, SEED); + members.push(voter.clone()); + Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, MAX_MEMBERS)?; // Threshold is 1 less than the number of members so that one person can vote nay - let threshold = m; + let threshold = m - 1; // Add previous proposals let mut last_hash = T::Hash::default(); for i in 0 .. p { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = frame_system::Call::::remark(vec![i as u8; b as usize]).into(); - Collective::::propose(SystemOrigin::Signed(caller.clone()).into(), threshold, Box::new(proposal.clone()))?; + let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; b as usize]).into(); + Collective::::propose( + SystemOrigin::Signed(proposer.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; last_hash = T::Hashing::hash_of(&proposal); } - // Have everyone vote aye on last proposal, while keeping it from passing - for j in 2 .. m { + let index = p - 1; + // Have almost everyone vote aye on last proposal, while keeping it from passing. + // Proposer already voted aye so we start at 1. + for j in 1 .. m - 3 { let voter = &members[j as usize]; let approve = true; - Collective::::vote(SystemOrigin::Signed(voter.clone()).into(), last_hash.clone(), p - 1, approve)?; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + approve, + )?; } + // Voter votes aye without resolving the vote. + let approve = true; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + approve, + )?; assert_eq!(Collective::::proposals().len(), p as usize); - // Caller switches vote to nay, but does not kill the vote, just updates + inserts - let index = p - 1; + // Voter switches vote to nay, but does not kill the vote, just updates + inserts let approve = false; - }: vote(SystemOrigin::Signed(caller), last_hash.clone(), index, approve) + }: _(SystemOrigin::Signed(voter), last_hash.clone(), index, approve) verify { // All proposals exist and the last proposal has just been updated. assert_eq!(Collective::::proposals().len(), p as usize); let voting = Collective::::voting(&last_hash).ok_or(Error::::ProposalMissing)?; - assert_eq!(voting.ayes.len(), (m - 2) as usize); + assert_eq!(voting.ayes.len(), (m - 3) as usize); assert_eq!(voting.nays.len(), 1); } - vote_disapproved { - let m in 2 .. MAX_MEMBERS; - let p in 1 .. MAX_PROPOSALS; + close_early_disapproved { + // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let m in 4 .. MAX_MEMBERS; + let p in 1 .. T::MaxProposals::get(); let b in 1 .. MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; + // Construct `members`. let mut members = vec![]; - for i in 0 .. m { + let proposer: T::AccountId = account("proposer", 0, SEED); + members.push(proposer.clone()); + for i in 1 .. m - 1 { let member = account("member", i, SEED); members.push(member); } - - let caller: T::AccountId = account("caller", 0, SEED); - members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None)?; + let voter: T::AccountId = account("voter", 0, SEED); + members.push(voter.clone()); + Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, MAX_MEMBERS)?; // Threshold is total members so that one nay will disapprove the vote - let threshold = m + 1; + let threshold = m; // Add previous proposals let mut last_hash = T::Hash::default(); for i in 0 .. p { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = frame_system::Call::::remark(vec![i as u8; b as usize]).into(); - Collective::::propose(SystemOrigin::Signed(caller.clone()).into(), threshold, Box::new(proposal.clone()))?; + let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; b as usize]).into(); + Collective::::propose( + SystemOrigin::Signed(proposer.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; last_hash = T::Hashing::hash_of(&proposal); } - // Have everyone vote aye on last proposal, while keeping it from passing - for j in 1 .. m { + let index = p - 1; + // Have most everyone vote aye on last proposal, while keeping it from passing. + // Proposer already voted aye so we start at 1. + for j in 1 .. m - 2 { let voter = &members[j as usize]; let approve = true; - Collective::::vote(SystemOrigin::Signed(voter.clone()).into(), last_hash.clone(), p - 1, approve)?; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + approve, + )?; } + // Voter votes aye without resolving the vote. + let approve = true; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + approve, + )?; assert_eq!(Collective::::proposals().len(), p as usize); - // Caller switches vote to nay, which kills the vote - let index = p - 1; + // Voter switches vote to nay, which kills the vote let approve = false; - - }: vote(SystemOrigin::Signed(caller), last_hash.clone(), index, approve) + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + approve, + )?; + + }: close(SystemOrigin::Signed(voter), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) verify { // The last proposal is removed. assert_eq!(Collective::::proposals().len(), (p - 1) as usize); assert_last_event::(RawEvent::Disapproved(last_hash).into()); } - vote_approved { - let m in 2 .. MAX_MEMBERS; - let p in 1 .. MAX_PROPOSALS; + close_early_approved { + // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let m in 4 .. MAX_MEMBERS; + let p in 1 .. T::MaxProposals::get(); let b in 1 .. MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; + // Construct `members`. let mut members = vec![]; - for i in 0 .. m { + for i in 0 .. m - 1 { let member = account("member", i, SEED); members.push(member); } - - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None)?; + Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, MAX_MEMBERS)?; // Threshold is 2 so any two ayes will approve the vote let threshold = 2; @@ -284,102 +388,156 @@ benchmarks_instance! { let mut last_hash = T::Hash::default(); for i in 0 .. p { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = frame_system::Call::::remark(vec![i as u8; b as usize]).into(); - Collective::::propose(SystemOrigin::Signed(caller.clone()).into(), threshold, Box::new(proposal.clone()))?; + let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; b as usize]).into(); + Collective::::propose( + SystemOrigin::Signed(caller.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; last_hash = T::Hashing::hash_of(&proposal); } // Caller switches vote to nay on their own proposal, allowing them to be the deciding approval vote - Collective::::vote(SystemOrigin::Signed(caller.clone()).into(), last_hash.clone(), p - 1, false)?; - - // Have everyone vote nay on last proposal, while keeping it from failing - for j in 2 .. m { + Collective::::vote( + SystemOrigin::Signed(caller.clone()).into(), + last_hash.clone(), + p - 1, + false, + )?; + + // Have almost everyone vote nay on last proposal, while keeping it from failing. + for j in 2 .. m - 1 { let voter = &members[j as usize]; let approve = false; - Collective::::vote(SystemOrigin::Signed(voter.clone()).into(), last_hash.clone(), p - 1, approve)?; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + p - 1, + approve, + )?; } // Member zero is the first aye - Collective::::vote(SystemOrigin::Signed(members[0].clone()).into(), last_hash.clone(), p - 1, true)?; + Collective::::vote( + SystemOrigin::Signed(members[0].clone()).into(), + last_hash.clone(), + p - 1, + true, + )?; assert_eq!(Collective::::proposals().len(), p as usize); // Caller switches vote to aye, which passes the vote let index = p - 1; let approve = true; + Collective::::vote( + SystemOrigin::Signed(caller.clone()).into(), + last_hash.clone(), + index, approve, + )?; - }: vote(SystemOrigin::Signed(caller), last_hash.clone(), index, approve) + }: close(SystemOrigin::Signed(caller), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) verify { // The last proposal is removed. assert_eq!(Collective::::proposals().len(), (p - 1) as usize); - assert_last_event::(RawEvent::Executed(last_hash, false).into()); + assert_last_event::(RawEvent::Executed(last_hash, Err(DispatchError::BadOrigin)).into()); } close_disapproved { - let m in 2 .. MAX_MEMBERS; - let p in 1 .. MAX_PROPOSALS; + // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let m in 4 .. MAX_MEMBERS; + let p in 1 .. T::MaxProposals::get(); let b in 1 .. MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; + // Construct `members`. let mut members = vec![]; - for i in 0 .. m { + for i in 0 .. m - 1 { let member = account("member", i, SEED); members.push(member); } - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); members.push(caller.clone()); - - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), Some(caller.clone()))?; + Collective::::set_members( + SystemOrigin::Root.into(), + members.clone(), + Some(caller.clone()), + MAX_MEMBERS, + )?; // Threshold is one less than total members so that two nays will disapprove the vote - let threshold = m; + let threshold = m - 1; // Add proposals let mut last_hash = T::Hash::default(); for i in 0 .. p { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = frame_system::Call::::remark(vec![i as u8; b as usize]).into(); - Collective::::propose(SystemOrigin::Signed(caller.clone()).into(), threshold, Box::new(proposal.clone()))?; + let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; b as usize]).into(); + Collective::::propose( + SystemOrigin::Signed(caller.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; last_hash = T::Hashing::hash_of(&proposal); } - // Have everyone vote aye on last proposal, while keeping it from passing - // A few abstainers will be the nay votes needed to fail the vote - for j in 2 .. m { + let index = p - 1; + // Have almost everyone vote aye on last proposal, while keeping it from passing. + // A few abstainers will be the nay votes needed to fail the vote. + for j in 2 .. m - 1 { let voter = &members[j as usize]; let approve = true; - Collective::::vote(SystemOrigin::Signed(voter.clone()).into(), last_hash.clone(), p - 1, approve)?; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + index, + approve, + )?; } // caller is prime, prime votes nay - Collective::::vote(SystemOrigin::Signed(caller.clone()).into(), last_hash.clone(), p - 1, false)?; + Collective::::vote( + SystemOrigin::Signed(caller.clone()).into(), + last_hash.clone(), + index, + false, + )?; System::::set_block_number(T::BlockNumber::max_value()); assert_eq!(Collective::::proposals().len(), p as usize); // Prime nay will close it as disapproved - }: close(SystemOrigin::Signed(caller), last_hash, p - 1) + }: close(SystemOrigin::Signed(caller), last_hash, index, Weight::max_value(), bytes_in_storage) verify { assert_eq!(Collective::::proposals().len(), (p - 1) as usize); assert_last_event::(RawEvent::Disapproved(last_hash).into()); } - close_approved { - let m in 2 .. MAX_MEMBERS; - let p in 1 .. MAX_PROPOSALS; + // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let m in 4 .. MAX_MEMBERS; + let p in 1 .. T::MaxProposals::get(); let b in 1 .. MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; + // Construct `members`. let mut members = vec![]; - for i in 0 .. m { + for i in 0 .. m - 1 { let member = account("member", i, SEED); members.push(member); } - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); members.push(caller.clone()); - - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), Some(caller.clone()))?; + Collective::::set_members( + SystemOrigin::Root.into(), + members.clone(), + Some(caller.clone()), + MAX_MEMBERS, + )?; // Threshold is two, so any two ayes will pass the vote let threshold = 2; @@ -388,17 +546,27 @@ benchmarks_instance! { let mut last_hash = T::Hash::default(); for i in 0 .. p { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = frame_system::Call::::remark(vec![i as u8; b as usize]).into(); - Collective::::propose(SystemOrigin::Signed(caller.clone()).into(), threshold, Box::new(proposal.clone()))?; + let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; b as usize]).into(); + Collective::::propose( + SystemOrigin::Signed(caller.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; last_hash = T::Hashing::hash_of(&proposal); } - // Have everyone vote nay on last proposal, while keeping it from failing - // A few abstainers will be the aye votes needed to pass the vote - for j in 2 .. m { + // Have almost everyone vote nay on last proposal, while keeping it from failing. + // A few abstainers will be the aye votes needed to pass the vote. + for j in 2 .. m - 1 { let voter = &members[j as usize]; let approve = false; - Collective::::vote(SystemOrigin::Signed(voter.clone()).into(), last_hash.clone(), p - 1, approve)?; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash.clone(), + p - 1, + approve + )?; } // caller is prime, prime already votes aye by creating the proposal @@ -406,10 +574,10 @@ benchmarks_instance! { assert_eq!(Collective::::proposals().len(), p as usize); // Prime aye will close it as approved - }: close(SystemOrigin::Signed(caller), last_hash, p - 1) + }: close(SystemOrigin::Signed(caller), last_hash, p - 1, Weight::max_value(), bytes_in_storage) verify { assert_eq!(Collective::::proposals().len(), (p - 1) as usize); - assert_last_event::(RawEvent::Executed(last_hash, false).into()); + assert_last_event::(RawEvent::Executed(last_hash, Err(DispatchError::BadOrigin)).into()); } } @@ -420,16 +588,64 @@ mod tests { use frame_support::assert_ok; #[test] - fn test_benchmarks() { + fn set_members() { new_test_ext().execute_with(|| { assert_ok!(test_benchmark_set_members::()); + }); + } + + #[test] + fn execute() { + new_test_ext().execute_with(|| { assert_ok!(test_benchmark_execute::()); + }); + } + + #[test] + fn propose_execute() { + new_test_ext().execute_with(|| { assert_ok!(test_benchmark_propose_execute::()); + }); + } + + #[test] + fn propose_proposed() { + new_test_ext().execute_with(|| { assert_ok!(test_benchmark_propose_proposed::()); - assert_ok!(test_benchmark_vote_insert::()); - assert_ok!(test_benchmark_vote_disapproved::()); - assert_ok!(test_benchmark_vote_approved::()); + }); + } + + #[test] + fn vote() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_vote::()); + }); + } + + #[test] + fn close_early_disapproved() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_close_early_disapproved::()); + }); + } + + #[test] + fn close_early_approved() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_close_early_approved::()); + }); + } + + #[test] + fn close_disapproved() { + new_test_ext().execute_with(|| { assert_ok!(test_benchmark_close_disapproved::()); + }); + } + + #[test] + fn close_approved() { + new_test_ext().execute_with(|| { assert_ok!(test_benchmark_close_approved::()); }); } diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 662465616ed1bec6c55ecff56e5e0a664ac519c2..1edd8c75b90b0c1023e78d187be26d00cc0302e0 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -1,24 +1,27 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Collective system: Members of a set of account IDs can make their collective feelings known //! through dispatched calls from one of two specialized origins. //! //! The membership can be provided in one of two ways: either directly, using the Root-dispatchable //! function `set_members`, or indirectly, through implementing the `ChangeMembers`. +//! The pallet assumes that the amount of members stays at or below `MAX_MEMBERS` for its weight +//! calculations, but enforces this neither in `set_members` nor in `change_members_sorted`. //! //! A "prime" member may be set allowing their vote to act as the default vote in case of any //! abstentions after the voting period. @@ -38,13 +41,19 @@ use sp_std::{prelude::*, result}; use sp_core::u32_trait::Value as U32; -use sp_runtime::RuntimeDebug; -use sp_runtime::traits::Hash; +use sp_io::storage; +use sp_runtime::{RuntimeDebug, traits::Hash}; + use frame_support::{ - dispatch::{Dispatchable, Parameter}, codec::{Encode, Decode}, - traits::{Get, ChangeMembers, InitializeMembers, EnsureOrigin}, decl_module, decl_event, - decl_storage, decl_error, ensure, - weights::DispatchClass, + codec::{Decode, Encode}, + debug, decl_error, decl_event, decl_module, decl_storage, + dispatch::{ + DispatchError, DispatchResult, DispatchResultWithPostInfo, Dispatchable, Parameter, + PostDispatchInfo, + }, + ensure, + traits::{ChangeMembers, EnsureOrigin, Get, InitializeMembers}, + weights::{DispatchClass, GetDispatchInfo, Weight}, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -60,22 +69,62 @@ pub type ProposalIndex = u32; /// vote exactly once, therefore also the number of votes for any given motion. pub type MemberCount = u32; +/// The maximum number of members supported by the pallet. Used for weight estimation. +/// +/// NOTE: +/// + Benchmarks will need to be re-run and weights adjusted if this changes. +/// + This pallet assumes that dependents keep to the limit without enforcing it. +pub const MAX_MEMBERS: MemberCount = 100; + +pub trait WeightInfo { + fn set_members(m: u32, n: u32, p: u32, ) -> Weight; + fn execute(m: u32, b: u32, ) -> Weight; + fn propose_execute(m: u32, b: u32, ) -> Weight; + fn propose_proposed(m: u32, p: u32, b: u32, ) -> Weight; + fn vote(m: u32, ) -> Weight; + fn close_early_disapproved(m: u32, p: u32, b: u32, ) -> Weight; + fn close_early_approved(m: u32, p: u32, b: u32, ) -> Weight; + fn close_disapproved(m: u32, p: u32, b: u32, ) -> Weight; + fn close_approved(m: u32, p: u32, b: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn set_members(_m: u32, _n: u32, _p: u32, ) -> Weight { 1_000_000_000 } + fn execute(_m: u32, _b: u32, ) -> Weight { 1_000_000_000 } + fn propose_execute(_m: u32, _b: u32, ) -> Weight { 1_000_000_000 } + fn propose_proposed(_m: u32, _p: u32, _b: u32, ) -> Weight { 1_000_000_000 } + fn vote(_m: u32, ) -> Weight { 1_000_000_000 } + fn close_early_disapproved(_m: u32, _p: u32, _b: u32, ) -> Weight { 1_000_000_000 } + fn close_early_approved(_m: u32, _p: u32, _b: u32, ) -> Weight { 1_000_000_000 } + fn close_disapproved(_m: u32, _p: u32, _b: u32, ) -> Weight { 1_000_000_000 } + fn close_approved(_m: u32, _p: u32, _b: u32, ) -> Weight { 1_000_000_000 } +} + pub trait Trait: frame_system::Trait { /// The outer origin type. type Origin: From>; /// The outer call dispatch type. - type Proposal: Parameter + Dispatchable>::Origin> + From>; + type Proposal: Parameter + + Dispatchable>::Origin, PostInfo=PostDispatchInfo> + + From> + + GetDispatchInfo; /// The outer event type. type Event: From> + Into<::Event>; /// The time-out for council motions. type MotionDuration: Get; + + /// Maximum number of proposals allowed to be active in parallel. + type MaxProposals: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } /// Origin for the collective module. -#[derive(PartialEq, Eq, Clone, RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode)] pub enum RawOrigin { /// It has been condoned by a given number of members of the collective from a given total. Members(MemberCount, MemberCount), @@ -135,19 +184,26 @@ decl_event! { { /// A motion (given hash) has been proposed (by given account) with a threshold (given /// `MemberCount`). + /// [account, proposal_index, proposal_hash, threshold] Proposed(AccountId, ProposalIndex, Hash, MemberCount), /// A motion (given hash) has been voted on by given account, leaving /// a tally (yes votes and no votes given respectively as `MemberCount`). + /// [account, proposal_hash, voted, yes, no] Voted(AccountId, Hash, bool, MemberCount, MemberCount), /// A motion was approved by the required threshold. + /// [proposal_hash] Approved(Hash), /// A motion was not approved by the required threshold. + /// [proposal_hash] Disapproved(Hash), - /// A motion was executed; `bool` is true if returned without error. - Executed(Hash, bool), - /// A single member did some action; `bool` is true if returned without error. - MemberExecuted(Hash, bool), - /// A proposal was closed after its duration was up. + /// A motion was executed; result will be `Ok` if it returned without error. + /// [proposal_hash, result] + Executed(Hash, DispatchResult), + /// A single member did some action; result will be `Ok` if it returned without error. + /// [proposal_hash, result] + MemberExecuted(Hash, DispatchResult), + /// A proposal was closed because its threshold was reached or after its duration was up. + /// [proposal_hash, yes, no] Closed(Hash, MemberCount, MemberCount), } } @@ -166,14 +222,154 @@ decl_error! { DuplicateVote, /// Members are already initialized! AlreadyInitialized, - /// The close call is made too early, before the end of the voting. + /// The close call was made too early, before the end of the voting. TooEarly, + /// There can only be a maximum of `MaxProposals` active proposals. + TooManyProposals, + /// The given weight bound for the proposal was too low. + WrongProposalWeight, + /// The given length bound for the proposal was too low. + WrongProposalLength, + } +} + +/// Functions for calcuating the weight of dispatchables. +mod weight_for { + use frame_support::{traits::Get, weights::Weight}; + use super::{Trait, Instance}; + + /// Calculate the weight for `set_members`. + /// + /// Based on benchmark: + /// 0 + M * 20.47 + N * 0.109 + P * 26.29 µs (min squares analysis) + /// + /// Note: The complexity of `set_members` is quadratic (`O(MP + N)`), so the linear approximation + /// of the benchmark is not always permissible. It is here, though, because the linear approximation + /// covered the range of possible values and we estimate weight via the worst case (max paramter + /// values) before execution so we can be sure that we are only overestimating. + pub(crate) fn set_members, I: Instance>( + old_count: Weight, + new_count: Weight, + proposals: Weight, + ) -> Weight { + let db = T::DbWeight::get(); + db.reads_writes(1, 1) // mutate `Members` + .saturating_add(db.writes(1)) // set `Prime` + .saturating_add(db.reads(1)) // read `Proposals` + .saturating_add(db.reads_writes(proposals, proposals)) // update votes (`Voting`) + .saturating_add(old_count.saturating_mul(21_000_000)) // M + .saturating_add(new_count.saturating_mul(110_000)) // N + .saturating_add(proposals.saturating_mul(27_000_000)) // P + } + + /// Calculate the weight for `execute`. + /// + /// Based on benchmark: + /// 22.62 + M * 0.115 + B * 0.003 µs (min squares analysis) + pub(crate) fn execute, I: Instance>( + members: Weight, + proposal: Weight, + length: Weight, + ) -> Weight { + T::DbWeight::get().reads(1) // read members for `is_member` + .saturating_add(23_000_000) // constant + .saturating_add(length.saturating_mul(4_000)) // B + .saturating_add(members.saturating_mul(120_000)) // M + .saturating_add(proposal) // P + } + + /// Calculate the weight for `propose` if the proposal is executed straight away (`threshold < 2`). + /// + /// Based on benchmark: + /// 28.12 + M * 0.218 + B * 0.003 µs (min squares analysis) + pub(crate) fn propose_execute, I: Instance>( + members: Weight, + proposal: Weight, + length: Weight, + ) -> Weight { + T::DbWeight::get().reads(2) // `is_member` + `contains_key` + .saturating_add(29_000_000) // constant + .saturating_add(length.saturating_mul(3_000)) // B + .saturating_add(members.saturating_mul(220_000)) // M + .saturating_add(proposal) // P1 + } + + /// Calculate the weight for `propose` if the proposal is put up for a vote (`threshold >= 2`). + /// + /// Based on benchmark: + /// 49.75 + M * 0.105 + P2 0.502 + B * 0.006 µs (min squares analysis) + pub(crate) fn propose_proposed, I: Instance>( + members: Weight, + proposals: Weight, + length: Weight, + ) -> Weight { + T::DbWeight::get().reads(2) // `is_member` + `contains_key` + .saturating_add(T::DbWeight::get().reads_writes(2, 4)) // `proposal` insertion + .saturating_add(50_000_000) // constant + .saturating_add(length.saturating_mul(6_000)) // B + .saturating_add(members.saturating_mul(110_000)) // M + .saturating_add(proposals.saturating_mul(510_000)) // P2 + } + + /// Calculate the weight for `vote`. + /// + /// Based on benchmark: + /// 24.03 + M * 0.349 + P * 0.119 + B * 0.003 µs (min squares analysis) + pub(crate) fn vote, I: Instance>( + members: Weight, + ) -> Weight { + T::DbWeight::get().reads(1) // read `Members` + .saturating_add(T::DbWeight::get().reads_writes(1, 1)) // mutate `Voting` + .saturating_add(30_000_000) // constant + .saturating_add(members.saturating_mul(500_000)) // M + } + + /// Calculate the weight for `close`. + /// + /// Based on benchmarks: + /// - early disapproved: 37.21 + M * 0.239 + P2 * 0.466 + B * 0.002 µs (min squares analysis) + /// - early approved: 50.82 + M * 0.211 + P2 * 0.478 + B * 0.008 µs (min squares analysis) + /// - disapproved: 51.08 + M * 0.224 + P2 * 0.475 + B * 0.003 µs (min squares analysis) + /// - approved: 65.95 + M * 0.226 + P2 * 0.487 + B * 0.005 µs (min squares analysis) + pub(crate) fn close, I: Instance>( + members: Weight, + proposal_weight: Weight, + proposals: Weight, + length: Weight, + ) -> Weight { + let db = T::DbWeight::get(); + close_without_finalize::(members, length) + .saturating_add(db.reads(1)) // `Prime` + .saturating_add(db.writes(1)) // `Proposals` + .saturating_add(db.writes(1)) // `Voting` + .saturating_add(proposal_weight) // P1 + .saturating_add(proposals.saturating_mul(490_000)) // P2 + } + + /// Calculate the weight for `close` without the call to `approve/disapprove_proposal`. + pub(crate) fn close_without_finalize, I: Instance>( + members: Weight, + length: Weight, + ) -> Weight { + T::DbWeight::get().reads(3) // `Members`, `Voting`, `ProposalOf` + .saturating_add(66_000_000) // constant + .saturating_add(length.saturating_mul(8_000)) // B + .saturating_add(members.saturating_mul(250_000)) // M } } -// Note: this module is not benchmarked. The weights are obtained based on the similarity of the -// executed logic with other democracy function. Note that councillor operations are assigned to the -// operational class. +/// Return the weight of a dispatch call result as an `Option`. +/// +/// Will return the weight regardless of what the state of the result is. +fn get_result_weight(result: DispatchResultWithPostInfo) -> Option { + match result { + Ok(post_info) => post_info.actual_weight, + Err(err) => err.post_info.actual_weight, + } +} + + +// Note that councillor operations are assigned to the operational class. decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where origin: ::Origin { type Error = Error; @@ -182,72 +378,231 @@ decl_module! { /// Set the collective's membership. /// - /// - `new_members`: The new member list. Be nice to the chain and - // provide it sorted. + /// - `new_members`: The new member list. Be nice to the chain and provide it sorted. /// - `prime`: The prime member whose vote sets the default. + /// - `old_count`: The upper bound for the previous number of members in storage. + /// Used for weight estimation. /// /// Requires root origin. - #[weight = (100_000_000, DispatchClass::Operational)] - fn set_members(origin, new_members: Vec, prime: Option) { + /// + /// NOTE: Does not enforce the expected `MAX_MEMBERS` limit on the amount of members, but + /// the weight estimations rely on it to estimate dispatchable weight. + /// + /// # + /// ## Weight + /// - `O(MP + N)` where: + /// - `M` old-members-count (code- and governance-bounded) + /// - `N` new-members-count (code- and governance-bounded) + /// - `P` proposals-count (code-bounded) + /// - DB: + /// - 1 storage mutation (codec `O(M)` read, `O(N)` write) for reading and writing the members + /// - 1 storage read (codec `O(P)`) for reading the proposals + /// - `P` storage mutations (codec `O(M)`) for updating the votes for each proposal + /// - 1 storage write (codec `O(1)`) for deleting the old `prime` and setting the new one + /// # + #[weight = ( + weight_for::set_members::( + (*old_count).into(), // M + new_members.len() as Weight, // N + T::MaxProposals::get().into(), // P + ), + DispatchClass::Operational + )] + fn set_members(origin, + new_members: Vec, + prime: Option, + old_count: MemberCount, + ) -> DispatchResultWithPostInfo { ensure_root(origin)?; + if new_members.len() > MAX_MEMBERS as usize { + debug::error!( + "New members count exceeds maximum amount of members expected. (expected: {}, actual: {})", + MAX_MEMBERS, + new_members.len() + ); + } + + let old = Members::::get(); + if old.len() > old_count as usize { + debug::warn!( + "Wrong count used to estimate set_members weight. (expected: {}, actual: {})", + old_count, + old.len() + ); + } let mut new_members = new_members; new_members.sort(); - let old = Members::::get(); - >::set_members_sorted(&new_members[..], &old); + >::set_members_sorted(&new_members, &old); Prime::::set(prime); + + Ok(Some(weight_for::set_members::( + old.len() as Weight, // M + new_members.len() as Weight, // N + T::MaxProposals::get().into(), // P + )).into()) } /// Dispatch a proposal from a member using the `Member` origin. /// /// Origin must be a member of the collective. - #[weight = (100_000_000, DispatchClass::Operational)] - fn execute(origin, proposal: Box<>::Proposal>) { + /// + /// # + /// ## Weight + /// - `O(M + P)` where `M` members-count (code-bounded) and `P` complexity of dispatching `proposal` + /// - DB: 1 read (codec `O(M)`) + DB access of `proposal` + /// - 1 event + /// # + #[weight = ( + weight_for::execute::( + MAX_MEMBERS.into(), + proposal.get_dispatch_info().weight, + *length_bound as Weight, + ), + DispatchClass::Operational + )] + fn execute(origin, + proposal: Box<>::Proposal>, + #[compact] length_bound: u32, + ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - ensure!(Self::is_member(&who), Error::::NotMember); + let members = Self::members(); + ensure!(members.contains(&who), Error::::NotMember); + let proposal_len = proposal.using_encoded(|x| x.len()); + ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); let proposal_hash = T::Hashing::hash_of(&proposal); - let ok = proposal.dispatch(RawOrigin::Member(who).into()).is_ok(); - Self::deposit_event(RawEvent::MemberExecuted(proposal_hash, ok)); + let result = proposal.dispatch(RawOrigin::Member(who).into()); + Self::deposit_event( + RawEvent::MemberExecuted(proposal_hash, result.map(|_| ()).map_err(|e| e.error)) + ); + + Ok(get_result_weight(result).map(|w| weight_for::execute::( + members.len() as Weight, + w, + proposal_len as Weight + )).into()) } + /// Add a new proposal to either be voted on or executed directly. + /// + /// Requires the sender to be member. + /// + /// `threshold` determines whether `proposal` is executed directly (`threshold < 2`) + /// or put up for voting. + /// /// # - /// - Bounded storage reads and writes. - /// - Argument `threshold` has bearing on weight. + /// ## Weight + /// - `O(B + M + P1)` or `O(B + M + P2)` where: + /// - `B` is `proposal` size in bytes (length-fee-bounded) + /// - `M` is members-count (code- and governance-bounded) + /// - branching is influenced by `threshold` where: + /// - `P1` is proposal execution complexity (`threshold < 2`) + /// - `P2` is proposals-count (code-bounded) (`threshold >= 2`) + /// - DB: + /// - 1 storage read `is_member` (codec `O(M)`) + /// - 1 storage read `ProposalOf::contains_key` (codec `O(1)`) + /// - DB accesses influenced by `threshold`: + /// - EITHER storage accesses done by `proposal` (`threshold < 2`) + /// - OR proposal insertion (`threshold <= 2`) + /// - 1 storage mutation `Proposals` (codec `O(P2)`) + /// - 1 storage mutation `ProposalCount` (codec `O(1)`) + /// - 1 storage write `ProposalOf` (codec `O(B)`) + /// - 1 storage write `Voting` (codec `O(M)`) + /// - 1 event /// # - #[weight = (5_000_000_000, DispatchClass::Operational)] - fn propose(origin, #[compact] threshold: MemberCount, proposal: Box<>::Proposal>) { + #[weight = ( + if *threshold < 2 { + weight_for::propose_execute::( + MAX_MEMBERS.into(), // M + proposal.get_dispatch_info().weight, // P1 + *length_bound as Weight, // B + ) + } else { + weight_for::propose_proposed::( + MAX_MEMBERS.into(), // M + T::MaxProposals::get().into(), // P2 + *length_bound as Weight, // B + ) + }, + DispatchClass::Operational + )] + fn propose(origin, + #[compact] threshold: MemberCount, + proposal: Box<>::Proposal>, + #[compact] length_bound: u32 + ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - ensure!(Self::is_member(&who), Error::::NotMember); + let members = Self::members(); + ensure!(members.contains(&who), Error::::NotMember); + let proposal_len = proposal.using_encoded(|x| x.len()); + ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); let proposal_hash = T::Hashing::hash_of(&proposal); - ensure!(!>::contains_key(proposal_hash), Error::::DuplicateProposal); if threshold < 2 { let seats = Self::members().len() as MemberCount; - let ok = proposal.dispatch(RawOrigin::Members(1, seats).into()).is_ok(); - Self::deposit_event(RawEvent::Executed(proposal_hash, ok)); + let result = proposal.dispatch(RawOrigin::Members(1, seats).into()); + Self::deposit_event( + RawEvent::Executed(proposal_hash, result.map(|_| ()).map_err(|e| e.error)) + ); + + Ok(get_result_weight(result).map(|w| weight_for::propose_execute::( + members.len() as Weight, // M + w, // P1 + proposal_len as Weight, // B + )).into()) } else { + let active_proposals = + >::try_mutate(|proposals| -> Result { + proposals.push(proposal_hash); + ensure!( + proposals.len() <= T::MaxProposals::get() as usize, + Error::::TooManyProposals + ); + Ok(proposals.len()) + })?; let index = Self::proposal_count(); >::mutate(|i| *i += 1); - >::mutate(|proposals| proposals.push(proposal_hash)); >::insert(proposal_hash, *proposal); let end = system::Module::::block_number() + T::MotionDuration::get(); let votes = Votes { index, threshold, ayes: vec![who.clone()], nays: vec![], end }; >::insert(proposal_hash, votes); Self::deposit_event(RawEvent::Proposed(who, index, proposal_hash, threshold)); + + Ok(Some(weight_for::propose_proposed::( + members.len() as Weight, // M + active_proposals as Weight, // P2 + proposal_len as Weight, // B + )).into()) } } + /// Add an aye or nay vote for the sender to the given proposal. + /// + /// Requires the sender to be a member. + /// /// # - /// - Bounded storage read and writes. - /// - Will be slightly heavier if the proposal is approved / disapproved after the vote. + /// ## Weight + /// - `O(M)` where `M` is members-count (code- and governance-bounded) + /// - DB: + /// - 1 storage read `Members` (codec `O(M)`) + /// - 1 storage mutation `Voting` (codec `O(M)`) + /// - 1 event /// # - #[weight = (200_000_000, DispatchClass::Operational)] - fn vote(origin, proposal: T::Hash, #[compact] index: ProposalIndex, approve: bool) { + #[weight = ( + weight_for::vote::(MAX_MEMBERS.into()), + DispatchClass::Operational + )] + fn vote(origin, + proposal: T::Hash, + #[compact] index: ProposalIndex, + approve: bool, + ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - ensure!(Self::is_member(&who), Error::::NotMember); + let members = Self::members(); + ensure!(members.contains(&who), Error::::NotMember); let mut voting = Self::voting(&proposal).ok_or(Error::::ProposalMissing)?; ensure!(voting.index == index, Error::::WrongIndex); @@ -279,64 +634,175 @@ decl_module! { let no_votes = voting.nays.len() as MemberCount; Self::deposit_event(RawEvent::Voted(who, proposal, approve, yes_votes, no_votes)); - let seats = Self::members().len() as MemberCount; + Voting::::insert(&proposal, voting); - let approved = yes_votes >= voting.threshold; - let disapproved = seats.saturating_sub(no_votes) < voting.threshold; - if approved || disapproved { - Self::finalize_proposal(approved, seats, voting, proposal); - } else { - Voting::::insert(&proposal, voting); - } + Ok(Some(weight_for::vote::(members.len() as Weight)).into()) } - /// May be called by any signed account after the voting duration has ended in order to - /// finish voting and close the proposal. + /// Close a vote that is either approved, disapproved or whose voting period has ended. + /// + /// May be called by any signed account in order to finish voting and close the proposal. + /// + /// If called before the end of the voting period it will only close the vote if it is + /// has enough votes to be approved or disapproved. + /// + /// If called after the end of the voting period abstentions are counted as rejections + /// unless there is a prime member set and the prime member cast an approval. /// - /// Abstentions are counted as rejections unless there is a prime member set and the prime - /// member cast an approval. + /// + `proposal_weight_bound`: The maximum amount of weight consumed by executing the closed proposal. + /// + `length_bound`: The upper bound for the length of the proposal in storage. Checked via + /// `storage::read` so it is `size_of::() == 4` larger than the pure length. /// - /// - the weight of `proposal` preimage. - /// - up to three events deposited. - /// - one read, two removals, one mutation. (plus three static reads.) - /// - computation and i/o `O(P + L + M)` where: - /// - `M` is number of members, - /// - `P` is number of active proposals, - /// - `L` is the encoded length of `proposal` preimage. - #[weight = (200_000_000, DispatchClass::Operational)] - fn close(origin, proposal: T::Hash, #[compact] index: ProposalIndex) { + /// # + /// ## Weight + /// - `O(B + M + P1 + P2)` where: + /// - `B` is `proposal` size in bytes (length-fee-bounded) + /// - `M` is members-count (code- and governance-bounded) + /// - `P1` is the complexity of `proposal` preimage. + /// - `P2` is proposal-count (code-bounded) + /// - DB: + /// - 2 storage reads (`Members`: codec `O(M)`, `Prime`: codec `O(1)`) + /// - 3 mutations (`Voting`: codec `O(M)`, `ProposalOf`: codec `O(B)`, `Proposals`: codec `O(P2)`) + /// - any mutations done while executing `proposal` (`P1`) + /// - up to 3 events + /// # + #[weight = ( + weight_for::close::( + MAX_MEMBERS.into(), // `M` + *proposal_weight_bound, // `P1` + T::MaxProposals::get().into(), // `P2` + *length_bound as Weight, // B + ), + DispatchClass::Operational + )] + fn close(origin, + proposal_hash: T::Hash, + #[compact] index: ProposalIndex, + #[compact] proposal_weight_bound: Weight, + #[compact] length_bound: u32 + ) -> DispatchResultWithPostInfo { let _ = ensure_signed(origin)?; - let voting = Self::voting(&proposal).ok_or(Error::::ProposalMissing)?; + let voting = Self::voting(&proposal_hash).ok_or(Error::::ProposalMissing)?; ensure!(voting.index == index, Error::::WrongIndex); - ensure!(system::Module::::block_number() >= voting.end, Error::::TooEarly); - - // default to true only if there's a prime and they voted in favour. - let default = Self::prime().map_or( - false, - |who| voting.ayes.iter().any(|a| a == &who), - ); let mut no_votes = voting.nays.len() as MemberCount; let mut yes_votes = voting.ayes.len() as MemberCount; let seats = Self::members().len() as MemberCount; + let approved = yes_votes >= voting.threshold; + let disapproved = seats.saturating_sub(no_votes) < voting.threshold; + // Allow (dis-)approving the proposal as soon as there are enough votes. + if approved { + let (proposal, len) = Self::validate_and_get_proposal( + &proposal_hash, + length_bound, + proposal_weight_bound + )?; + Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); + let approve_weight = Self::do_approve_proposal(seats, voting, proposal_hash, proposal); + return Ok(Some( + weight_for::close_without_finalize::(seats.into(), len as Weight) + .saturating_add(approve_weight) + ).into()); + } else if disapproved { + Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); + let disapprove_weight = Self::do_disapprove_proposal(proposal_hash); + return Ok(Some( + weight_for::close_without_finalize::(seats.into(), 0) + .saturating_add(disapprove_weight) + ).into()); + } + + // Only allow actual closing of the proposal after the voting period has ended. + ensure!(system::Module::::block_number() >= voting.end, Error::::TooEarly); + + // default to true only if there's a prime and they voted in favour. + let default = Self::prime().map_or(false, |who| voting.ayes.iter().any(|a| a == &who)); + let abstentions = seats - (yes_votes + no_votes); match default { true => yes_votes += abstentions, false => no_votes += abstentions, } + let approved = yes_votes >= voting.threshold; - Self::deposit_event(RawEvent::Closed(proposal, yes_votes, no_votes)); - Self::finalize_proposal(yes_votes >= voting.threshold, seats, voting, proposal); + if approved { + let (proposal, len) = Self::validate_and_get_proposal( + &proposal_hash, + length_bound, + proposal_weight_bound + )?; + Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); + let approve_weight = Self::do_approve_proposal(seats, voting, proposal_hash, proposal); + return Ok(Some( + weight_for::close_without_finalize::(seats.into(), len as Weight) + .saturating_add(T::DbWeight::get().reads(1)) // read `Prime` + .saturating_add(approve_weight) + ).into()); + } else { + Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); + let disapprove_weight = Self::do_disapprove_proposal(proposal_hash); + return Ok(Some( + weight_for::close_without_finalize::(seats.into(), 0) + .saturating_add(T::DbWeight::get().reads(1)) // read `Prime` + .saturating_add(disapprove_weight) + ).into()); + } + } + + /// Disapprove a proposal, close, and remove it from the system, regardless of its current state. + /// + /// Must be called by the Root origin. + /// + /// Parameters: + /// * `proposal_hash`: The hash of the proposal that should be disapproved. + /// + /// # + /// Complexity: O(P) where P is the number of max proposals + /// Base Weight: .49 * P + /// DB Weight: + /// * Reads: Proposals + /// * Writes: Voting, Proposals, ProposalOf + /// # + #[weight = T::DbWeight::get().reads_writes(1, 3) // `Voting`, `Proposals`, `ProposalOf` + .saturating_add(490_000 * Weight::from(T::MaxProposals::get())) // P2 + ] + fn disapprove_proposal(origin, proposal_hash: T::Hash) -> DispatchResultWithPostInfo { + ensure_root(origin)?; + let actual_weight = Self::do_disapprove_proposal(proposal_hash); + Ok(Some(actual_weight).into()) } } } impl, I: Instance> Module { + /// Check whether `who` is a member of the collective. pub fn is_member(who: &T::AccountId) -> bool { + // Note: The dispatchables *do not* use this to check membership so make sure + // to update those if this is changed. Self::members().contains(who) } + /// Ensure that the right proposal bounds were passed and get the proposal from storage. + /// + /// Checks the length in storage via `storage::read` which adds an extra `size_of::() == 4` + /// to the length. + fn validate_and_get_proposal( + hash: &T::Hash, + length_bound: u32, + weight_bound: Weight + ) -> Result<(>::Proposal, usize), DispatchError> { + let key = ProposalOf::::hashed_key_for(hash); + // read the length of the proposal storage entry directly + let proposal_len = storage::read(&key, &mut [0; 0], 0) + .ok_or(Error::::ProposalMissing)?; + ensure!(proposal_len <= length_bound, Error::::WrongProposalLength); + let proposal = ProposalOf::::get(hash).ok_or(Error::::ProposalMissing)?; + let proposal_weight = proposal.get_dispatch_info().weight; + ensure!(proposal_weight <= weight_bound, Error::::WrongProposalWeight); + Ok((proposal, proposal_len as usize)) + } + /// Weight: /// If `approved`: /// - the weight of `proposal` preimage. @@ -351,42 +817,83 @@ impl, I: Instance> Module { /// Two removals, one mutation. /// Computation and i/o `O(P)` where: /// - `P` is number of active proposals - fn finalize_proposal( - approved: bool, + fn do_approve_proposal( seats: MemberCount, voting: Votes, - proposal: T::Hash, - ) { - if approved { - Self::deposit_event(RawEvent::Approved(proposal)); - - // execute motion, assuming it exists. - if let Some(p) = ProposalOf::::take(&proposal) { - let origin = RawOrigin::Members(voting.threshold, seats).into(); - let ok = p.dispatch(origin).is_ok(); - Self::deposit_event(RawEvent::Executed(proposal, ok)); - } - } else { - // disapproved - ProposalOf::::remove(&proposal); - Self::deposit_event(RawEvent::Disapproved(proposal)); - } + proposal_hash: T::Hash, + proposal: >::Proposal, + ) -> Weight { + let mut weight: Weight = 0; + Self::deposit_event(RawEvent::Approved(proposal_hash)); + + let dispatch_weight = proposal.get_dispatch_info().weight; + let origin = RawOrigin::Members(voting.threshold, seats).into(); + let result = proposal.dispatch(origin); + Self::deposit_event( + RawEvent::Executed(proposal_hash, result.map(|_| ()).map_err(|e| e.error)) + ); + weight = weight.saturating_add( + // default to the dispatch info weight for safety + get_result_weight(result).unwrap_or(dispatch_weight) // P1 + ); + + let remove_proposal_weight = Self::remove_proposal(proposal_hash); + weight.saturating_add(remove_proposal_weight) + } - // remove vote - Voting::::remove(&proposal); - Proposals::::mutate(|proposals| proposals.retain(|h| h != &proposal)); + fn do_disapprove_proposal(proposal_hash: T::Hash) -> Weight { + // disapproved + Self::deposit_event(RawEvent::Disapproved(proposal_hash)); + Self::remove_proposal(proposal_hash) + } + + // Removes a proposal from the pallet, cleaning up votes and the vector of proposals. + fn remove_proposal(proposal_hash: T::Hash) -> Weight { + // remove proposal and vote + ProposalOf::::remove(&proposal_hash); + Voting::::remove(&proposal_hash); + let num_proposals = Proposals::::mutate(|proposals| { + proposals.retain(|h| h != &proposal_hash); + proposals.len() + 1 // calculate weight based on original length + }); + T::DbWeight::get().reads_writes(1, 3) // `Voting`, `Proposals`, `ProposalOf` + .saturating_add(490_000 * num_proposals as Weight) // P2 } } impl, I: Instance> ChangeMembers for Module { + /// Update the members of the collective. Votes are updated and the prime is reset. + /// + /// NOTE: Does not enforce the expected `MAX_MEMBERS` limit on the amount of members, but + /// the weight estimations rely on it to estimate dispatchable weight. + /// + /// # + /// ## Weight + /// - `O(MP + N)` + /// - where `M` old-members-count (governance-bounded) + /// - where `N` new-members-count (governance-bounded) + /// - where `P` proposals-count + /// - DB: + /// - 1 storage read (codec `O(P)`) for reading the proposals + /// - `P` storage mutations for updating the votes (codec `O(M)`) + /// - 1 storage write (codec `O(N)`) for storing the new members + /// - 1 storage write (codec `O(1)`) for deleting the old prime + /// # fn change_members_sorted( _incoming: &[T::AccountId], outgoing: &[T::AccountId], new: &[T::AccountId], ) { + if new.len() > MAX_MEMBERS as usize { + debug::error!( + "New members count exceeds maximum amount of members expected. (expected: {}, actual: {})", + MAX_MEMBERS, + new.len() + ); + } // remove accounts from all current voting in motions. let mut outgoing = outgoing.to_vec(); - outgoing.sort_unstable(); + outgoing.sort(); for h in Self::proposals().into_iter() { >::mutate(h, |v| if let Some(mut votes) = v.take() { @@ -539,12 +1046,14 @@ mod tests { pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const MotionDuration: u64 = 3; + pub const MaxProposals: u32 = 100; } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; - type Call = (); + type Call = Call; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; @@ -556,6 +1065,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -563,18 +1073,23 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl Trait for Test { type Origin = Origin; type Proposal = Call; type Event = Event; type MotionDuration = MotionDuration; + type MaxProposals = MaxProposals; + type WeightInfo = (); } impl Trait for Test { type Origin = Origin; type Proposal = Call; type Event = Event; type MotionDuration = MotionDuration; + type MaxProposals = MaxProposals; + type WeightInfo = (); } pub type Block = sp_runtime::generic::Block; @@ -620,19 +1135,21 @@ mod tests { fn close_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, true)); System::set_block_number(3); assert_noop!( - Collective::close(Origin::signed(4), hash.clone(), 0), + Collective::close(Origin::signed(4), hash.clone(), 0, proposal_weight, proposal_len), Error::::TooEarly ); System::set_block_number(4); - assert_ok!(Collective::close(Origin::signed(4), hash.clone(), 0)); + assert_ok!(Collective::close(Origin::signed(4), hash.clone(), 0, proposal_weight, proposal_len)); let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; assert_eq!(System::events(), vec![ @@ -644,18 +1161,57 @@ mod tests { }); } + #[test] + fn proposal_weight_limit_works_on_approve() { + new_test_ext().execute_with(|| { + let proposal = Call::Collective(crate::Call::set_members(vec![1, 2, 3], None, MAX_MEMBERS)); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let proposal_weight = proposal.get_dispatch_info().weight; + let hash = BlakeTwo256::hash_of(&proposal); + // Set 1 as prime voter + Prime::::set(Some(1)); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); + // With 1's prime vote, this should pass + System::set_block_number(4); + assert_noop!( + Collective::close(Origin::signed(4), hash.clone(), 0, proposal_weight - 100, proposal_len), + Error::::WrongProposalWeight + ); + assert_ok!(Collective::close(Origin::signed(4), hash.clone(), 0, proposal_weight, proposal_len)); + }) + } + + #[test] + fn proposal_weight_limit_ignored_on_disapprove() { + new_test_ext().execute_with(|| { + let proposal = Call::Collective(crate::Call::set_members(vec![1, 2, 3], None, MAX_MEMBERS)); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let proposal_weight = proposal.get_dispatch_info().weight; + let hash = BlakeTwo256::hash_of(&proposal); + + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); + // No votes, this proposal wont pass + System::set_block_number(4); + assert_ok!( + Collective::close(Origin::signed(4), hash.clone(), 0, proposal_weight - 100, proposal_len) + ); + }) + } + #[test] fn close_with_prime_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Collective::set_members(Origin::ROOT, vec![1, 2, 3], Some(3))); + assert_ok!(Collective::set_members(Origin::root(), vec![1, 2, 3], Some(3), MAX_MEMBERS)); - assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, true)); System::set_block_number(4); - assert_ok!(Collective::close(Origin::signed(4), hash.clone(), 0)); + assert_ok!(Collective::close(Origin::signed(4), hash.clone(), 0, proposal_weight, proposal_len)); let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; assert_eq!(System::events(), vec![ @@ -671,14 +1227,16 @@ mod tests { fn close_with_voting_prime_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Collective::set_members(Origin::ROOT, vec![1, 2, 3], Some(1))); + assert_ok!(Collective::set_members(Origin::root(), vec![1, 2, 3], Some(1), MAX_MEMBERS)); - assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, true)); System::set_block_number(4); - assert_ok!(Collective::close(Origin::signed(4), hash.clone(), 0)); + assert_ok!(Collective::close(Origin::signed(4), hash.clone(), 0, proposal_weight, proposal_len)); let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; assert_eq!(System::events(), vec![ @@ -686,7 +1244,7 @@ mod tests { record(Event::collective_Instance1(RawEvent::Voted(2, hash.clone(), true, 2, 0))), record(Event::collective_Instance1(RawEvent::Closed(hash.clone(), 3, 0))), record(Event::collective_Instance1(RawEvent::Approved(hash.clone()))), - record(Event::collective_Instance1(RawEvent::Executed(hash.clone(), false))) + record(Event::collective_Instance1(RawEvent::Executed(hash.clone(), Err(DispatchError::BadOrigin)))) ]); }); } @@ -695,9 +1253,10 @@ mod tests { fn removal_of_old_voters_votes_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash = BlakeTwo256::hash_of(&proposal); let end = 4; - assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, true)); assert_eq!( Collective::voting(&hash), @@ -710,8 +1269,9 @@ mod tests { ); let proposal = make_proposal(69); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Collective::propose(Origin::signed(2), 2, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(2), 2, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(3), hash.clone(), 1, false)); assert_eq!( Collective::voting(&hash), @@ -729,29 +1289,31 @@ mod tests { fn removal_of_old_voters_votes_works_with_set_members() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash = BlakeTwo256::hash_of(&proposal); let end = 4; - assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, true)); assert_eq!( Collective::voting(&hash), Some(Votes { index: 0, threshold: 3, ayes: vec![1, 2], nays: vec![], end }) ); - assert_ok!(Collective::set_members(Origin::ROOT, vec![2, 3, 4], None)); + assert_ok!(Collective::set_members(Origin::root(), vec![2, 3, 4], None, MAX_MEMBERS)); assert_eq!( Collective::voting(&hash), Some(Votes { index: 0, threshold: 3, ayes: vec![2], nays: vec![], end }) ); let proposal = make_proposal(69); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Collective::propose(Origin::signed(2), 2, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(2), 2, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(3), hash.clone(), 1, false)); assert_eq!( Collective::voting(&hash), Some(Votes { index: 1, threshold: 2, ayes: vec![2], nays: vec![3], end }) ); - assert_ok!(Collective::set_members(Origin::ROOT, vec![2, 4], None)); + assert_ok!(Collective::set_members(Origin::root(), vec![2, 4], None, MAX_MEMBERS)); assert_eq!( Collective::voting(&hash), Some(Votes { index: 1, threshold: 2, ayes: vec![2], nays: vec![], end }) @@ -763,9 +1325,10 @@ mod tests { fn propose_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash = proposal.blake2_256().into(); let end = 4; - assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_eq!(Collective::proposals(), vec![hash]); assert_eq!(Collective::proposal_of(&hash), Some(proposal)); assert_eq!( @@ -788,12 +1351,59 @@ mod tests { }); } + #[test] + fn limit_active_proposals() { + new_test_ext().execute_with(|| { + for i in 0..MaxProposals::get() { + let proposal = make_proposal(i as u64); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); + } + let proposal = make_proposal(MaxProposals::get() as u64 + 1); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + assert_noop!( + Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len), + Error::::TooManyProposals + ); + }) + } + + #[test] + fn correct_validate_and_get_proposal() { + new_test_ext().execute_with(|| { + let proposal = Call::Collective(crate::Call::set_members(vec![1, 2, 3], None, MAX_MEMBERS)); + let length = proposal.encode().len() as u32; + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), length)); + + let hash = BlakeTwo256::hash_of(&proposal); + let weight = proposal.get_dispatch_info().weight; + assert_noop!( + Collective::validate_and_get_proposal(&BlakeTwo256::hash_of(&vec![3; 4]), length, weight), + Error::::ProposalMissing + ); + assert_noop!( + Collective::validate_and_get_proposal(&hash, length - 2, weight), + Error::::WrongProposalLength + ); + assert_noop!( + Collective::validate_and_get_proposal(&hash, length, weight - 10), + Error::::WrongProposalWeight + ); + let res = Collective::validate_and_get_proposal(&hash, length, weight); + assert_ok!(res.clone()); + let (retrieved_proposal, len) = res.unwrap(); + assert_eq!(length as usize, len); + assert_eq!(proposal, retrieved_proposal); + }) + } + #[test] fn motions_ignoring_non_collective_proposals_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); assert_noop!( - Collective::propose(Origin::signed(42), 3, Box::new(proposal.clone())), + Collective::propose(Origin::signed(42), 3, Box::new(proposal.clone()), proposal_len), Error::::NotMember ); }); @@ -803,8 +1413,9 @@ mod tests { fn motions_ignoring_non_collective_votes_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_noop!( Collective::vote(Origin::signed(42), hash.clone(), 0, true), Error::::NotMember, @@ -817,8 +1428,9 @@ mod tests { new_test_ext().execute_with(|| { System::set_block_number(3); let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash: H256 = proposal.blake2_256().into(); - assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_noop!( Collective::vote(Origin::signed(2), hash.clone(), 1, true), Error::::WrongIndex, @@ -830,9 +1442,10 @@ mod tests { fn motions_revoting_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let hash: H256 = proposal.blake2_256().into(); let end = 4; - assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()), proposal_len)); assert_eq!( Collective::voting(&hash), Some(Votes { index: 0, threshold: 2, ayes: vec![1], nays: vec![], end }) @@ -881,11 +1494,14 @@ mod tests { fn motions_reproposing_disapproved_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let proposal_weight = proposal.get_dispatch_info().weight; let hash: H256 = proposal.blake2_256().into(); - assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, false)); + assert_ok!(Collective::close(Origin::signed(2), hash.clone(), 0, proposal_weight, proposal_len)); assert_eq!(Collective::proposals(), vec![]); - assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()), proposal_len)); assert_eq!(Collective::proposals(), vec![hash]); }); } @@ -894,9 +1510,12 @@ mod tests { fn motions_disapproval_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let proposal_weight = proposal.get_dispatch_info().weight; let hash: H256 = proposal.blake2_256().into(); - assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, false)); + assert_ok!(Collective::close(Origin::signed(2), hash.clone(), 0, proposal_weight, proposal_len)); assert_eq!(System::events(), vec![ EventRecord { @@ -921,6 +1540,13 @@ mod tests { )), topics: vec![], }, + EventRecord { + phase: Phase::Initialization, + event: Event::collective_Instance1(RawEvent::Closed( + hex!["68eea8f20b542ec656c6ac2d10435ae3bd1729efc34d1354ab85af840aad2d35"].into(), 1, 1, + )), + topics: vec![], + }, EventRecord { phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Disapproved( @@ -936,9 +1562,12 @@ mod tests { fn motions_approval_works() { new_test_ext().execute_with(|| { let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let proposal_weight = proposal.get_dispatch_info().weight; let hash: H256 = proposal.blake2_256().into(); - assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()))); + assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, true)); + assert_ok!(Collective::close(Origin::signed(2), hash.clone(), 0, proposal_weight, proposal_len)); assert_eq!(System::events(), vec![ EventRecord { @@ -962,6 +1591,13 @@ mod tests { )), topics: vec![], }, + EventRecord { + phase: Phase::Initialization, + event: Event::collective_Instance1(RawEvent::Closed( + hex!["68eea8f20b542ec656c6ac2d10435ae3bd1729efc34d1354ab85af840aad2d35"].into(), 2, 0, + )), + topics: vec![], + }, EventRecord { phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Approved( @@ -973,11 +1609,60 @@ mod tests { phase: Phase::Initialization, event: Event::collective_Instance1(RawEvent::Executed( hex!["68eea8f20b542ec656c6ac2d10435ae3bd1729efc34d1354ab85af840aad2d35"].into(), - false, + Err(DispatchError::BadOrigin), )), topics: vec![], } ]); }); } + + #[test] + fn close_disapprove_does_not_care_about_weight_or_len() { + // This test confirms that if you close a proposal that would be disapproved, + // we do not care about the proposal length or proposal weight since it will + // not be read from storage or executed. + new_test_ext().execute_with(|| { + let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let hash: H256 = proposal.blake2_256().into(); + assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()), proposal_len)); + // First we make the proposal succeed + assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, true)); + // It will not close with bad weight/len information + assert_noop!( + Collective::close(Origin::signed(2), hash.clone(), 0, 0, 0), + Error::::WrongProposalLength, + ); + assert_noop!( + Collective::close(Origin::signed(2), hash.clone(), 0, 0, proposal_len), + Error::::WrongProposalWeight, + ); + // Now we make the proposal fail + assert_ok!(Collective::vote(Origin::signed(1), hash.clone(), 0, false)); + assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, false)); + // It can close even if the weight/len information is bad + assert_ok!(Collective::close(Origin::signed(2), hash.clone(), 0, 0, 0)); + }) + } + + #[test] + fn disapprove_proposal_works() { + new_test_ext().execute_with(|| { + let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let hash: H256 = proposal.blake2_256().into(); + assert_ok!(Collective::propose(Origin::signed(1), 2, Box::new(proposal.clone()), proposal_len)); + // Proposal would normally succeed + assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, true)); + // But Root can disapprove and remove it anyway + assert_ok!(Collective::disapprove_proposal(Origin::root(), hash.clone())); + let record = |event| EventRecord { phase: Phase::Initialization, event, topics: vec![] }; + assert_eq!(System::events(), vec![ + record(Event::collective_Instance1(RawEvent::Proposed(1, 0, hash.clone(), 2))), + record(Event::collective_Instance1(RawEvent::Voted(2, hash.clone(), true, 2, 0))), + record(Event::collective_Instance1(RawEvent::Disapproved(hash.clone()))), + ]); + }) + } } diff --git a/frame/contracts/COMPLEXITY.md b/frame/contracts/COMPLEXITY.md index 7e8c2903c79b9348d2441b46e181a0c59a6562d0..32f6f84b89b6ad9be05bddc31d13997c70f2a59d 100644 --- a/frame/contracts/COMPLEXITY.md +++ b/frame/contracts/COMPLEXITY.md @@ -4,19 +4,19 @@ This analysis is on the computing and memory complexity of specific procedures. The primary goal is to come up with decent pricing for functions that can be invoked by a user (via extrinsics) or by untrusted code that prevents DoS attacks. -# Sandboxing +## Sandboxing It makes sense to describe the sandboxing module first because the smart-contract module is built upon it. -## Memory +### Memory -### set +#### set Copies data from the supervisor's memory to the guest's memory. **complexity**: It doesn't allocate, and the computational complexity is proportional to the number of bytes to copy. -### get +#### get Copies data from the guest's memory to the supervisor's memory. @@ -78,17 +78,10 @@ The size of the arguments and the return value depends on the exact function in **complexity**: Memory and computational complexity can be considered as a constant. -# `AccountDb` +## Transactional Storage -`AccountDb` is an abstraction that supports collecting changes to accounts with the ability to efficiently reverting them. Contract -execution contexts operate on the AccountDb. All changes are flushed into underlying storage only after origin transaction succeeds. - -## Relation to the underlying storage - -At present, `AccountDb` is implemented as a cascade of overlays with the direct storage at the bottom. The direct -storage `AccountDb` leverages child tries. Each overlay is represented by a `Map`. On a commit from an overlay to an -overlay, maps are merged. On commit from an overlay to the bottommost `AccountDb` all changes are flushed to the storage -and on revert, the overlay is just discarded. +The contracts module makes use of the nested storage transactions feature offered by +the underlying storage which allows efficient roll back of changes made by contracts. > ℹ️ The underlying storage has a overlay layer implemented as a `Map`. If the runtime reads a storage location and the > respective key doesn't exist in the overlay, then the underlying storage performs a DB access, but the value won't be @@ -105,23 +98,24 @@ storage access. ## get_storage, get_code_hash, get_rent_allowance, get_balance, contract_exists -These functions check the local cache for a requested value and, if it is there, the value is returned. Otherwise, these functions will ask an underlying `AccountDb` for the value. This means that the number of lookups is proportional to the depth of the overlay cascade. If the value can't be found before reaching the bottommost `AccountDb`, then a DB read will be performed (in case `get_balance` the function `free_balance` will be invoked). - -A lookup in the local cache consists of at least one `Map` lookup, for locating the specific account. For `get_storage` there is a second lookup: because account's storage is implemented as a nested map, another lookup is required for fetching a storage value by a key. +Those query the underlying storage for the requested value. If the value was modified in the +current block they are served from the cache. Otherwise a database read is performed. -These functions return an owned value as its result, so memory usage depends on the value being returned. - -**complexity**: The memory complexity is proportional to the size of the value. The computational complexity is proportional to the depth of the overlay cascade and the size of the value; the cost is dominated by the DB read though. +**complexity**: The memory complexity is proportional to the size of the value. The computational complexity is proportional the size of the value; the cost is dominated by the DB read. ## set_storage, set_balance, set_rent_allowance -These functions only modify the local `Map`. - -A lookup in the local cache consists of at least one `Map` lookup, for locating the specific account. For `get_storage` there is a second lookup: because account's storage is implemented as a nested map, another lookup is required for fetching a storage value by a key. +These function write to the underlying storage which caches those values and does not write +them to the database immediately. -While these functions only modify the local `Map`, if changes made by them are committed to the bottommost `AccountDb`, each changed entry in the `Map` will require a DB write. Moreover, if the balance of the account is changed to be below `existential_deposit` then that account along with all its storage will be removed, which requires time proportional to the number of storage entries that account has. It should be ensured that pricing accounts for these facts. +While these functions only modify the local cache, they trigger a database write later when +all changes that were not rolled back are written to storage. Moreover, if the balance of the +account is changed to be below `existential_deposit` then that account along with all its storage +will be removed, which requires time proportional to the number of storage entries that account has. +It should be ensured that pricing accounts for these facts. -**complexity**: Each lookup has a logarithmical computing time to the number of already inserted entries. No additional memory is required. +**complexity**: Each lookup has a logarithmical computing time to the number of already inserted entries. +No additional memory is required. ## instantiate_contract @@ -131,9 +125,11 @@ Calls `contract_exists` and if it doesn't exist, do not modify the local `Map` s ## commit -In this function, all cached values will be inserted into the underlying `AccountDb` or into the storage. +In this function, all values modified in the current transactions are committed to the parent +transaction. -We are doing `N` inserts into `Map` (`O(log M)` complexity) or into the storage, where `N` is the size of the committed `Map` and `M` is the size of the map of the underlying overlay. Consider adjusting the price of modifying the `AccountDb` to account for this (since pricing for the count of entries in `commit` will make the price of commit way less predictable). No additional memory is required. +This will trigger `N` inserts into parent transaction (`O(log M)` complexity) or into the storage, where `N` is the size of the current transaction and `M` is the size of the parent transaction. Consider adjusting the price of modifying the +current transaction to account for this (since pricing for the count of entries in `commit` will make the price of commit way less predictable). No additional memory is required. Note that in case of storage modification we need to construct a key in the underlying storage. In order to do that we need: @@ -143,21 +139,21 @@ Note that in case of storage modification we need to construct a key in the unde There is also a special case to think of: if the balance of some account goes below `existential_deposit`, then all storage entries of that account will be erased, which requires time proportional to the number of storage entries that account has. -**complexity**: `N` inserts into a `Map` or eventually into the storage (if committed). Every deleted account will induce removal of all its storage which is proportional to the number of storage entries that account has. +**complexity**: `N` inserts into a transaction or eventually into the storage (if committed). Every deleted account will induce removal of all its storage which is proportional to the number of storage entries that account has. ## revert -Consists of dropping (in the Rust sense) of the `AccountDb`. +Consists of dropping (in the Rust sense) of the current transaction. **complexity**: Computing complexity is proportional to a number of changed entries in a overlay. No additional memory is required. -# Executive +## Executive -## Transfer +### Transfer This function performs the following steps: -1. Querying source and destination balances from an overlay (see `get_balance`), +1. Querying source and destination balances from the current transaction (see `get_balance`), 2. Querying `existential_deposit`. 3. Executing `ensure_account_liquid` hook. 4. Updating source and destination balance in the overlay (see `set_balance`). @@ -171,9 +167,9 @@ returns with an error. Assuming marshaled size of a balance value is of the constant size we can neglect its effect on the performance. -**complexity**: up to 2 DB reads and up to 2 DB writes (if flushed to the storage) in the standard case. If removal of the source account takes place then it will additionally perform a DB write per one storage entry that the account has. For the current `AccountDb` implementation computing complexity also depends on the depth of the `AccountDb` cascade. Memorywise it can be assumed to be constant. +**complexity**: up to 2 DB reads and up to 2 DB writes (if flushed to the storage) in the standard case. If removal of the source account takes place then it will additionally perform a DB write per one storage entry that the account has. Memorywise it can be assumed to be constant. -## Initialization +### Initialization Before a call or instantiate can be performed the execution context must be initialized. @@ -188,7 +184,7 @@ implementation they just involve a DB read. For subsequent calls and instantiations during contract execution, the initialization requires no expensive operations. -## Terminate +### Terminate This function performs the following steps: @@ -204,17 +200,17 @@ the call stack is of a fixed maximum size we consider this operation as constant we are using child trie removal which is linear in the amount of stored keys. Upcoming changes will make the account removal constant time. - -## Call +### Call This function receives input data for the contract execution. The execution consists of the following steps: 1. Initialization of the execution context. 2. Checking rent payment. 3. Loading code from the DB. -4. `transfer`-ing funds between the caller and the destination account. -5. Executing the code of the destination account. -6. Committing overlayed changed to the underlying `AccountDb`. +4. Starting a new storage transaction. +5. `transfer`-ing funds between the caller and the destination account. +6. Executing the code of the destination account. +7. Committing or rolling back the storage transaction. **Note** that the complexity of executing the contract code should be considered separately. @@ -235,22 +231,24 @@ Loading code most likely will trigger a DB read, since the code is immutable and Also, `transfer` can make up to 2 DB reads and up to 2 DB writes (if flushed to the storage) in the standard case. If removal of the source account takes place then it will additionally perform a DB write per one storage entry that the account has. -Finally, all changes are `commit`-ted into the underlying overlay. The complexity of this depends on the number of changes performed by the code. Thus, the pricing of storage modification should account for that. +Finally, the current storage transaction is closed. The complexity of this depends on the number of changes performed by the code. Thus, the pricing of storage modification should account for that. **complexity**: + - Only for the first invocation of the contract: up to 5 DB reads and one DB write as well as logic executed by `ensure_can_withdraw`, `withdraw`, `make_free_balance_be`. - On top of that for every invocation: Up to 5 DB reads. DB read of the code is of dynamic size. There can also be up to 2 DB writes (if flushed to the storage). Additionally, if the source account removal takes place a DB write will be performed per one storage entry that the account has. -## Instantiate +### Instantiate This function takes the code of the constructor and input data. Instantiation of a contract consists of the following steps: 1. Initialization of the execution context. 2. Calling `DetermineContractAddress` hook to determine an address for the contract, -3. `transfer`-ing funds between self and the newly instantiated contract. -4. Executing the constructor code. This will yield the final code of the code. -5. Storing the code for the newly instantiated contract in the overlay. -6. Committing overlayed changed to the underlying `AccountDb`. +3. Starting a new storage transaction. +4. `transfer`-ing funds between self and the newly instantiated contract. +5. Executing the constructor code. This will yield the final code of the code. +6. Storing the code for the newly instantiated contract in the overlay. +7. Committing or rolling back the storage transaction. **Note** that the complexity of executing the constructor code should be considered separately. @@ -262,19 +260,43 @@ Also, `transfer` can make up to 2 DB reads and up to 2 DB writes (if flushed to Storing the code in the overlay may induce another DB write (if flushed to the storage) with the size proportional to the size of the constructor code. -Finally, all changes are `commit`-ted into the underlying overlay. The complexity of this depends on the number of changes performed by the constructor code. Thus, the pricing of storage modification should account for that. +Finally, the current storage transaction is closed.. The complexity of this depends on the number of changes performed by the constructor code. Thus, the pricing of storage modification should account for that. **complexity**: Up to 2 DB reads and induces up to 3 DB writes (if flushed to the storage), one of which is dependent on the size of the code. Additionally, if the source account removal takes place a DB write will be performed per one storage entry that the account has. -# Externalities +## Contracts API + +Each API function invoked from a contract can involve some overhead. + +## Getter functions + +Those are simple getter functions which copy a requested value to contract memory. They +all have the following two arguments: + +- `output_ptr`: Pointer into contract memory where to copy the value. +- `output_len_ptr`: Pointer into contract memory where the size of the buffer is stored. The size of the copied value is also stored there. -Each external function invoked from a contract can involve some overhead. +**complexity**: The size of the returned value is constant for a given runtime. Therefore we +consider its complexity constant even though some of them might involve at most one DB read. Some of those +functions call into other pallets of the runtime. The assumption here is that those functions are also +linear in regard to the size of the data that is returned and therefore considered constant for a +given runtime. -## ext_gas +This is the list of getters: -**complexity**: This is of constant complexity. +- seal_caller +- seal_address +- seal_weight_to_fee +- seal_gas_left +- seal_balance +- seal_value_transferred +- seal_now +- seal_minimum_balance +- seal_tombstone_deposit +- seal_rent_allowance +- seal_block_number -## ext_set_storage +### seal_set_storage This function receives a `key` and `value` as arguments. It consists of the following steps: @@ -283,7 +305,7 @@ This function receives a `key` and `value` as arguments. It consists of the foll **complexity**: Complexity is proportional to the size of the `value`. This function induces a DB write of size proportional to the `value` size (if flushed to the storage), so should be priced accordingly. -## ext_clear_storage +### seal_clear_storage This function receives a `key` as argument. It consists of the following steps: @@ -293,23 +315,22 @@ This function receives a `key` as argument. It consists of the following steps: **complexity**: Complexity is constant. This function induces a DB write to clear the storage entry (upon being flushed to the storage) and should be priced accordingly. -## ext_get_storage +### seal_get_storage This function receives a `key` as an argument. It consists of the following steps: 1. Reading the sandbox memory for `key` (see sandboxing memory get). 2. Reading the storage with the given key (see `get_storage`). It receives back the owned result buffer. -3. Replacing the scratch buffer. +3. Writing the storage value to contract memory. Key is of a constant size. Therefore, the sandbox memory load can be considered to be of constant complexity. Unless the value is cached, a DB read will be performed. The size of the value is not known until the read is performed. Moreover, the DB read has to be synchronous and no progress can be made until the value is fetched. -**complexity**: The memory and computing complexity is proportional to the size of the fetched value. This function performs a -DB read. +**complexity**: The memory and computing complexity is proportional to the size of the fetched value. This function performs a DB read. -## ext_transfer +### seal_transfer This function receives the following arguments: @@ -320,18 +341,19 @@ It consists of the following steps: 1. Loading `account` buffer from the sandbox memory (see sandboxing memory get) and then decoding it. 2. Loading `value` buffer from the sandbox memory and then decoding it. -4. Invoking the executive function `transfer`. +3. Invoking the executive function `transfer`. Loading of `account` and `value` buffers should be charged. This is because the sizes of buffers are specified by the calling code, even though marshaled representations are, essentially, of constant size. This can be fixed by assigning an upper bound for sizes of `AccountId` and `Balance`. -## ext_call +### seal_call This function receives the following arguments: - `callee` buffer of a marshaled `AccountId`, - `gas` limit which is plain u64, - `value` buffer of a marshaled `Balance`, -- `input_data`. An arbitrarily sized byte vector. +- `input_data` an arbitrarily sized byte vector. +- `output_ptr` pointer to contract memory. It consists of the following steps: @@ -339,14 +361,15 @@ It consists of the following steps: 2. Loading `value` buffer from the sandbox memory and then decoding it. 3. Loading `input_data` buffer from the sandbox memory. 4. Invoking the executive function `call`. +5. Writing output buffer to contract memory. Loading of `callee` and `value` buffers should be charged. This is because the sizes of buffers are specified by the calling code, even though marshaled representations are, essentially, of constant size. This can be fixed by assigning an upper bound for sizes of `AccountId` and `Balance`. Loading `input_data` should be charged in any case. -**complexity**: All complexity comes from loading buffers and executing `call` executive function. The former component is proportional to the sizes of `callee`, `value` and `input_data` buffers. The latter component completely depends on the complexity of `call` executive function, and also dominated by it. +**complexity**: All complexity comes from loading and writing buffers and executing `call` executive function. The former component is proportional to the sizes of `callee`, `value`, `input_data` and `output_ptr` buffers. The latter component completely depends on the complexity of `call` executive function, and also dominated by it. -## ext_instantiate +### seal_instantiate This function receives the following arguments: @@ -368,7 +391,7 @@ Loading `init_code` and `input_data` should be charged in any case. **complexity**: All complexity comes from loading buffers and executing `instantiate` executive function. The former component is proportional to the sizes of `init_code`, `value` and `input_data` buffers. The latter component completely depends on the complexity of `instantiate` executive function and also dominated by it. -## ext_terminate +### seal_terminate This function receives the following arguments: @@ -382,16 +405,23 @@ Loading of the `beneficiary` buffer should be charged. This is because the sizes **complexity**: All complexity comes from loading buffers and executing `terminate` executive function. The former component is proportional to the size of the `beneficiary` buffer. The latter component completely depends on the complexity of `terminate` executive function and also dominated by it. -## ext_return +### seal_input -This function receives a `data` buffer as an argument. Execution of the function consists of the following steps: +This function receives a pointer to contract memory. It copies the input to the contract call to this location. -1. Loading `data` buffer from the sandbox memory (see sandboxing memory get), -2. Trapping +**complexity**: The complextity is proportional to the size of the input buffer. + +### seal_return + +This function receives a `data` buffer and `flags` arguments. Execution of the function consists of the following steps: + +1. Loading `data` buffer from the sandbox memory (see sandboxing memory get). +2. Storing the `u32` flags value. +3. Trapping **complexity**: The complexity of this function is proportional to the size of the `data` buffer. -## ext_deposit_event +### seal_deposit_event This function receives a `data` buffer as an argument. Execution of the function consists of the following steps: @@ -402,49 +432,7 @@ This function receives a `data` buffer as an argument. Execution of the function **complexity**: The complexity of this function is proportional to the size of the `data` buffer. -## ext_caller - -This function serializes the address of the caller into the scratch buffer. - -**complexity**: Assuming that the address is of constant size, this function has constant complexity. - -## ext_random - -This function serializes a random number generated by the given subject into the scratch buffer. -The complexity of this function highly depends on the complexity of `System::random`. `max_subject_len` -limits the size of the subject buffer. - -**complexity**: The complexity of this function depends on the implementation of `System::random`. - -## ext_now - -This function serializes the current block's timestamp into the scratch buffer. - -**complexity**: Assuming that the timestamp is of constant size, this function has constant complexity. - -## ext_scratch_size - -This function returns the size of the scratch buffer. - -**complexity**: This function is of constant complexity. - -## ext_scratch_read - -This function copies slice of data from the scratch buffer to the sandbox memory. The calling code specifies the slice length. Execution of the function consists of the following steps: - -1. Storing a specified slice of the scratch buffer into the sandbox memory (see sandboxing memory set) - -**complexity**: The computing complexity of this function is proportional to the length of the slice. No additional memory is required. - -## ext_scratch_write - -This function copies slice of data from the sandbox memory to the scratch buffer. The calling code specifies the slice length. Execution of the function consists of the following steps: - -1. Loading a slice from the sandbox memory into the (see sandboxing memory get) - -**complexity**: Complexity is proportional to the length of the slice. - -## ext_set_rent_allowance +### seal_set_rent_allowance This function receives the following argument: @@ -457,22 +445,6 @@ It consists of the following steps: **complexity**: Complexity is proportional to the size of the `value`. This function induces a DB write of size proportional to the `value` size (if flushed to the storage), so should be priced accordingly. -## ext_rent_allowance - -It consists of the following steps: - -1. Invoking `get_rent_allowance` AccountDB function. -2. Serializing the rent allowance of the current contract into the scratch buffer. - -**complexity**: Assuming that the rent allowance is of constant size, this function has constant complexity. This -function performs a DB read. - -## ext_block_number - -This function serializes the current block's number into the scratch buffer. - -**complexity**: Assuming that the block number is of constant size, this function has constant complexity. - ## Built-in hashing functions This paragraph concerns the following supported built-in hash functions: diff --git a/frame/contracts/Cargo.toml b/frame/contracts/Cargo.toml index 4e1128000e33894f218f3f94a42442c255bcada5..05fbd85bc698af495f77f6d2bc75ba95df8dcf6b 100644 --- a/frame/contracts/Cargo.toml +++ b/frame/contracts/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-contracts" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for WASM contracts" @@ -12,28 +12,31 @@ description = "FRAME pallet for WASM contracts" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -serde = { version = "1.0.101", optional = true, features = ["derive"] } -pwasm-utils = { version = "0.12.0", default-features = false } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +bitflags = "1.0" +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +pallet-contracts-primitives = { version = "2.0.0-rc6", default-features = false, path = "common" } parity-wasm = { version = "0.41.0", default-features = false } +pwasm-utils = { version = "0.14.0", default-features = false } +serde = { version = "1.0.101", optional = true, features = ["derive"] } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-sandbox = { version = "0.8.0-rc6", default-features = false, path = "../../primitives/sandbox" } wasmi-validation = { version = "0.3.0", default-features = false } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-sandbox = { version = "0.8.0-dev", default-features = false, path = "../../primitives/sandbox" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -pallet-contracts-primitives = { version = "2.0.0-dev", default-features = false, path = "common" } -pallet-transaction-payment = { version = "2.0.0-dev", default-features = false, path = "../transaction-payment" } +wat = { version = "1.0", optional = true, default-features = false } [dev-dependencies] -wabt = "0.9.2" assert_matches = "1.3.0" -hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-dev", path = "../balances" } -pallet-timestamp = { version = "2.0.0-dev", path = "../timestamp" } -pallet-randomness-collective-flip = { version = "2.0.0-dev", path = "../randomness-collective-flip" } +hex-literal = "0.3.1" +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +pallet-timestamp = { version = "2.0.0-rc6", path = "../timestamp" } +pallet-randomness-collective-flip = { version = "2.0.0-rc6", path = "../randomness-collective-flip" } +pretty_assertions = "0.6.1" +wat = "1.0" [features] default = ["std"] @@ -51,5 +54,13 @@ std = [ "pwasm-utils/std", "wasmi-validation/std", "pallet-contracts-primitives/std", - "pallet-transaction-payment/std", +] +runtime-benchmarks = [ + "frame-benchmarking", + "wat", + # We are linking the wat crate which uses std and therefore brings with it the + # std panic handler. Therefore we need to disable out own panic handlers. Mind that + # we still override the std memory allocator. + "sp-io/disable_panic_handler", + "sp-io/disable_oom", ] diff --git a/frame/contracts/README.md b/frame/contracts/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f2d58048c34eb72c5dcb43054480b5a973bc2474 --- /dev/null +++ b/frame/contracts/README.md @@ -0,0 +1,64 @@ +# Contract Module + +The Contract module provides functionality for the runtime to deploy and execute WebAssembly smart-contracts. + +- [`contract::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +This module extends accounts based on the `Currency` trait to have smart-contract functionality. It can +be used with other modules that implement accounts based on `Currency`. These "smart-contract accounts" +have the ability to instantiate smart-contracts and make calls to other contract and non-contract accounts. + +The smart-contract code is stored once in a `code_cache`, and later retrievable via its `code_hash`. +This means that multiple smart-contracts can be instantiated from the same `code_cache`, without replicating +the code each time. + +When a smart-contract is called, its associated code is retrieved via the code hash and gets executed. +This call can alter the storage entries of the smart-contract account, instantiate new smart-contracts, +or call other smart-contracts. + +Finally, when an account is reaped, its associated code and storage of the smart-contract account +will also be deleted. + +### Gas + +Senders must specify a gas limit with every call, as all instructions invoked by the smart-contract require gas. +Unused gas is refunded after the call, regardless of the execution outcome. + +If the gas limit is reached, then all calls and state changes (including balance transfers) are only +reverted at the current call's contract level. For example, if contract A calls B and B runs out of gas mid-call, +then all of B's calls are reverted. Assuming correct error handling by contract A, A's other calls and state +changes still persist. + +### Notable Scenarios + +Contract call failures are not always cascading. When failures occur in a sub-call, they do not "bubble up", +and the call will only revert at the specific contract level. For example, if contract A calls contract B, and B +fails, A can decide how to handle that failure, either proceeding or reverting A's changes. + +## Interface + +### Dispatchable functions + +* `put_code` - Stores the given binary Wasm code into the chain's storage and returns its `code_hash`. +* `instantiate` - Deploys a new contract from the given `code_hash`, optionally transferring some balance. +This instantiates a new smart contract account and calls its contract deploy handler to +initialize the contract. +* `call` - Makes a call to an account, optionally transferring some balance. + +## Usage + +The Contract module is a work in progress. The following examples show how this Contract module +can be used to instantiate and call contracts. + +* [`ink`](https://github.com/paritytech/ink) is +an [`eDSL`](https://wiki.haskell.org/Embedded_domain_specific_language) that enables writing +WebAssembly based smart contracts in the Rust programming language. This is a work in progress. + +## Related Modules + +* [Balances](../pallet_balances/index.html) + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/contracts/common/Cargo.toml b/frame/contracts/common/Cargo.toml index edf1867be0a7109b968f2645b2b034749fe8a5a3..d397a2805918f83c46885b118f6135cc6125feb4 100644 --- a/frame/contracts/common/Cargo.toml +++ b/frame/contracts/common/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-contracts-primitives" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "A crate that hosts a common definitions that are relevant for the pallet-contracts." @@ -13,9 +13,9 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] # This crate should not rely on any of the frame primitives. -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/runtime" } [features] default = ["std"] diff --git a/frame/contracts/common/README.md b/frame/contracts/common/README.md new file mode 100644 index 0000000000000000000000000000000000000000..12718cd86425b4820dc63ce1369c7e4d93d3bc93 --- /dev/null +++ b/frame/contracts/common/README.md @@ -0,0 +1,3 @@ +A crate that hosts a common definitions that are relevant for the pallet-contracts. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/contracts/fixtures/benchmarks/dummy.wat b/frame/contracts/fixtures/benchmarks/dummy.wat new file mode 100644 index 0000000000000000000000000000000000000000..b878d26ef9185b5c8d6b663f6b456e9915b6672e --- /dev/null +++ b/frame/contracts/fixtures/benchmarks/dummy.wat @@ -0,0 +1,4 @@ +(module + (func (export "call")) + (func (export "deploy")) +) diff --git a/frame/contracts/fixtures/call_return_code.wat b/frame/contracts/fixtures/call_return_code.wat new file mode 100644 index 0000000000000000000000000000000000000000..f7a7ff20a49e396f90efb63882a468383aeab07c --- /dev/null +++ b/frame/contracts/fixtures/call_return_code.wat @@ -0,0 +1,44 @@ +;; This calls Django (4) and transfers 100 balance during this call and copies the return code +;; of this call to the output buffer. +;; It also forwards its input to the callee. +(module + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + ;; [0, 8) address of django + (data (i32.const 0) "\04\00\00\00\00\00\00\00") + + ;; [8, 16) 100 balance + (data (i32.const 8) "\64\00\00\00\00\00\00\00") + + ;; [16, 20) here we store the return code of the transfer + + ;; [20, 24) here we store the input data + + ;; [24, 28) size of the input data + (data (i32.const 24) "\04") + + (func (export "deploy")) + + (func (export "call") + (call $seal_input (i32.const 20) (i32.const 24)) + (i32.store + (i32.const 16) + (call $seal_call + (i32.const 0) ;; Pointer to "callee" address. + (i32.const 8) ;; Length of "callee" address. + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer. + (i32.const 20) ;; Pointer to input data buffer address + (i32.load (i32.const 24)) ;; Length of input data buffer + (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output + (i32.const 0) ;; Ptr to output buffer len + ) + ) + ;; exit with success and take transfer return code to the output buffer + (call $seal_return (i32.const 0) (i32.const 16) (i32.const 4)) + ) +) diff --git a/frame/contracts/tests/caller_contract.wat b/frame/contracts/fixtures/caller_contract.wat similarity index 61% rename from frame/contracts/tests/caller_contract.wat rename to frame/contracts/fixtures/caller_contract.wat index 4bc122c0b1863002ffc9cb0b4d8042231c2dd576..e8ff2e379716d9bf4fad85c9a3040fb07a032269 100644 --- a/frame/contracts/tests/caller_contract.wat +++ b/frame/contracts/fixtures/caller_contract.wat @@ -1,10 +1,9 @@ (module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_println" (func $ext_println (param i32 i32))) + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_balance" (func $seal_balance (param i32 i32))) + (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_instantiate" (func $seal_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_println" (func $seal_println (param i32 i32))) (import "env" "memory" (memory 1 1)) (func $assert (param i32) @@ -17,14 +16,16 @@ ) (func $current_balance (param $sp i32) (result i64) - (call $ext_balance) - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 8)) + (i32.store + (i32.sub (get_local $sp) (i32.const 16)) + (i32.const 8) ) - (call $ext_scratch_read + (call $seal_balance (i32.sub (get_local $sp) (i32.const 8)) - (i32.const 0) - (i32.const 8) + (i32.sub (get_local $sp) (i32.const 16)) + ) + (call $assert + (i32.eq (i32.load (i32.sub (get_local $sp) (i32.const 16))) (i32.const 8)) ) (i64.load (i32.sub (get_local $sp) (i32.const 8))) ) @@ -36,21 +37,20 @@ (local $exit_code i32) (local $balance i64) + ;; Length of the buffer + (i32.store (i32.const 20) (i32.const 32)) + + ;; Copy input to this contracts memory + (call $seal_input (i32.const 24) (i32.const 20)) + ;; Input data is the code hash of the contract to be deployed. (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 20)) (i32.const 32) ) ) - ;; Copy code hash from scratch buffer into this contract's memory. - (call $ext_scratch_read - (i32.const 24) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 32) ;; Count of bytes to copy. - ) - ;; Read current balance into local variable. (set_local $sp (i32.const 1024)) (set_local $balance @@ -59,7 +59,7 @@ ;; Fail to deploy the contract since it returns a non-zero exit status. (set_local $exit_code - (call $ext_instantiate + (call $seal_instantiate (i32.const 24) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -67,17 +67,16 @@ (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 9) ;; Pointer to input data buffer address (i32.const 7) ;; Length of input data buffer + (i32.const 4294967295) ;; u32 max sentinel value: do not copy address + (i32.const 0) ;; Length is ignored in this case + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this case ) ) ;; Check non-zero exit status. (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x11)) - ) - - ;; Check that scratch buffer is empty since contract instantiation failed. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 0)) + (i32.eq (get_local $exit_code) (i32.const 2)) ;; ReturnCode::CalleeReverted ) ;; Check that balance has not changed. @@ -87,25 +86,24 @@ ;; Fail to deploy the contract due to insufficient gas. (set_local $exit_code - (call $ext_instantiate + (call $seal_instantiate (i32.const 24) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. - (i64.const 200) ;; How much gas to devote for the execution. + (i64.const 187500000) ;; Just enough to pay for the instantiate (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 8) ;; Pointer to input data buffer address (i32.const 8) ;; Length of input data buffer + (i32.const 4294967295) ;; u32 max sentinel value: do not copy address + (i32.const 0) ;; Length is ignored in this case + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this case ) ) ;; Check for special trap exit status. (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x0100)) - ) - - ;; Check that scratch buffer is empty since contract instantiation failed. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 0)) + (i32.eq (get_local $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped ) ;; Check that balance has not changed. @@ -113,9 +111,15 @@ (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) ) + ;; Length of the output buffer + (i32.store + (i32.sub (get_local $sp) (i32.const 4)) + (i32.const 8) + ) + ;; Deploy the contract successfully. (set_local $exit_code - (call $ext_instantiate + (call $seal_instantiate (i32.const 24) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -123,24 +127,22 @@ (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 8) ;; Pointer to input data buffer address (i32.const 8) ;; Length of input data buffer + (i32.const 16) ;; Pointer to the address output buffer + (i32.sub (get_local $sp) (i32.const 4)) ;; Pointer to the address buffer length + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this case + ) ) ;; Check for success exit status. (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x00)) + (i32.eq (get_local $exit_code) (i32.const 0)) ;; ReturnCode::Success ) - ;; Check that scratch buffer contains the address of the new contract. + ;; Check that address has the expected length (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 8)) - ) - - ;; Copy contract address from scratch buffer into this contract's memory. - (call $ext_scratch_read - (i32.const 16) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. + (i32.eq (i32.load (i32.sub (get_local $sp) (i32.const 4))) (i32.const 8)) ) ;; Check that balance has been deducted. @@ -151,9 +153,21 @@ (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) ) + ;; Zero out destination buffer of output + (i32.store + (i32.sub (get_local $sp) (i32.const 4)) + (i32.const 0) + ) + + ;; Length of the output buffer + (i32.store + (i32.sub (get_local $sp) (i32.const 8)) + (i32.const 4) + ) + ;; Call the new contract and expect it to return failing exit code. (set_local $exit_code - (call $ext_call + (call $seal_call (i32.const 16) ;; Pointer to "callee" address. (i32.const 8) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -161,26 +175,19 @@ (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 9) ;; Pointer to input data buffer address (i32.const 7) ;; Length of input data buffer + (i32.sub (get_local $sp) (i32.const 4)) ;; Ptr to output buffer + (i32.sub (get_local $sp) (i32.const 8)) ;; Ptr to output buffer len ) ) ;; Check non-zero exit status. (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x11)) + (i32.eq (get_local $exit_code) (i32.const 2)) ;; ReturnCode::CalleeReverted ) - ;; Check that scratch buffer contains the expected return data. + ;; Check that output buffer contains the expected return data. (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 3)) - ) - (i32.store - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - ) - (call $ext_scratch_read - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - (i32.const 3) + (i32.eq (i32.load (i32.sub (get_local $sp) (i32.const 8))) (i32.const 3)) ) (call $assert (i32.eq @@ -196,25 +203,22 @@ ;; Fail to call the contract due to insufficient gas. (set_local $exit_code - (call $ext_call + (call $seal_call (i32.const 16) ;; Pointer to "callee" address. (i32.const 8) ;; Length of "callee" address. - (i64.const 100) ;; How much gas to devote for the execution. + (i64.const 117500000) ;; Just enough to make the call (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 8) ;; Pointer to input data buffer address (i32.const 8) ;; Length of input data buffer + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this cas ) ) ;; Check for special trap exit status. (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x0100)) - ) - - ;; Check that scratch buffer is empty since call trapped. - (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 0)) + (i32.eq (get_local $exit_code) (i32.const 1)) ;; ReturnCode::CalleeTrapped ) ;; Check that balance has not changed. @@ -222,9 +226,21 @@ (i64.eq (get_local $balance) (call $current_balance (get_local $sp))) ) + ;; Zero out destination buffer of output + (i32.store + (i32.sub (get_local $sp) (i32.const 4)) + (i32.const 0) + ) + + ;; Length of the output buffer + (i32.store + (i32.sub (get_local $sp) (i32.const 8)) + (i32.const 4) + ) + ;; Call the contract successfully. (set_local $exit_code - (call $ext_call + (call $seal_call (i32.const 16) ;; Pointer to "callee" address. (i32.const 8) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -232,26 +248,19 @@ (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 8) ;; Pointer to input data buffer address (i32.const 8) ;; Length of input data buffer + (i32.sub (get_local $sp) (i32.const 4)) ;; Ptr to output buffer + (i32.sub (get_local $sp) (i32.const 8)) ;; Ptr to output buffer len ) ) ;; Check for success exit status. (call $assert - (i32.eq (get_local $exit_code) (i32.const 0x00)) + (i32.eq (get_local $exit_code) (i32.const 0)) ;; ReturnCode::Success ) - ;; Check that scratch buffer contains the expected return data. + ;; Check that the output buffer contains the expected return data. (call $assert - (i32.eq (call $ext_scratch_size) (i32.const 4)) - ) - (i32.store - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - ) - (call $ext_scratch_read - (i32.sub (get_local $sp) (i32.const 4)) - (i32.const 0) - (i32.const 4) + (i32.eq (i32.load (i32.sub (get_local $sp) (i32.const 8))) (i32.const 4)) ) (call $assert (i32.eq @@ -271,5 +280,5 @@ (data (i32.const 0) "\00\80") ;; The value to transfer on instantiation and calls. ;; Chosen to be greater than existential deposit. - (data (i32.const 8) "\00\11\22\33\44\55\66\77") ;; The input data to instantiations and calls. + (data (i32.const 8) "\00\01\22\33\44\55\66\77") ;; The input data to instantiations and calls. ) diff --git a/frame/contracts/fixtures/check_default_rent_allowance.wat b/frame/contracts/fixtures/check_default_rent_allowance.wat new file mode 100644 index 0000000000000000000000000000000000000000..64cd67186bff2ca79bc5b806be0fbdb36e8fdc9b --- /dev/null +++ b/frame/contracts/fixtures/check_default_rent_allowance.wat @@ -0,0 +1,43 @@ +(module + (import "seal0" "seal_rent_allowance" (func $seal_rent_allowance (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + ;; [0, 8) reserved for $seal_rent_allowance output + + ;; [8, 16) length of the buffer + (data (i32.const 8) "\08") + + ;; [16, inf) zero initialized + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "call")) + + (func (export "deploy") + ;; fill the buffer with the rent allowance. + (call $seal_rent_allowance (i32.const 0) (i32.const 8)) + + ;; assert len == 8 + (call $assert + (i32.eq + (i32.load (i32.const 8)) + (i32.const 8) + ) + ) + + ;; assert that contents of the buffer is equal to >::max_value(). + (call $assert + (i64.eq + (i64.load (i32.const 0)) + (i64.const 0xFFFFFFFFFFFFFFFF) + ) + ) + ) +) diff --git a/frame/contracts/tests/crypto_hashes.wat b/frame/contracts/fixtures/crypto_hashes.wat similarity index 64% rename from frame/contracts/tests/crypto_hashes.wat rename to frame/contracts/fixtures/crypto_hashes.wat index 6dbca33928cb791bb32c2c6c857d687e74271b1e..c2b4d6b81edbf95cd6a08d1fd7a92f0f2d9173f5 100644 --- a/frame/contracts/tests/crypto_hashes.wat +++ b/frame/contracts/fixtures/crypto_hashes.wat @@ -1,22 +1,21 @@ (module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) - (import "env" "ext_hash_sha2_256" (func $ext_hash_sha2_256 (param i32 i32 i32))) - (import "env" "ext_hash_keccak_256" (func $ext_hash_keccak_256 (param i32 i32 i32))) - (import "env" "ext_hash_blake2_256" (func $ext_hash_blake2_256 (param i32 i32 i32))) - (import "env" "ext_hash_blake2_128" (func $ext_hash_blake2_128 (param i32 i32 i32))) + (import "seal0" "seal_hash_sha2_256" (func $seal_hash_sha2_256 (param i32 i32 i32))) + (import "seal0" "seal_hash_keccak_256" (func $seal_hash_keccak_256 (param i32 i32 i32))) + (import "seal0" "seal_hash_blake2_256" (func $seal_hash_blake2_256 (param i32 i32 i32))) + (import "seal0" "seal_hash_blake2_128" (func $seal_hash_blake2_128 (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) (type $hash_fn_sig (func (param i32 i32 i32))) (table 8 funcref) (elem (i32.const 1) - $ext_hash_sha2_256 - $ext_hash_keccak_256 - $ext_hash_blake2_256 - $ext_hash_blake2_128 + $seal_hash_sha2_256 + $seal_hash_keccak_256 + $seal_hash_blake2_256 + $seal_hash_blake2_128 ) (data (i32.const 1) "20202010201008") ;; Output sizes of the hashes in order in hex. @@ -25,8 +24,7 @@ ;; Called by the tests. ;; - ;; The `call` function expects data in a certain format in the scratch - ;; buffer. + ;; The `call` function expects data in a certain format in the input buffer. ;; ;; 1. The first byte encodes an identifier for the crypto hash function ;; under test. (*) @@ -34,7 +32,7 @@ ;; crypto hash function chosen in 1. ;; ;; The `deploy` function then computes the chosen crypto hash function - ;; given the input and puts the result back into the scratch buffer. + ;; given the input and puts the result into the output buffer. ;; After contract execution the test driver then asserts that the returned ;; values are equal to the expected bytes for the input and chosen hash ;; function. @@ -48,33 +46,36 @@ ;; | 2 | BLAKE2 | 256 | ;; | 3 | BLAKE2 | 128 | ;; --------------------------------- - (func (export "call") (result i32) + (func (export "call") (local $chosen_hash_fn i32) + (local $input_len_ptr i32) (local $input_ptr i32) (local $input_len i32) (local $output_ptr i32) (local $output_len i32) + (local.set $input_len_ptr (i32.const 256)) (local.set $input_ptr (i32.const 10)) - (call $ext_scratch_read (local.get $input_ptr) (i32.const 0) (call $ext_scratch_size)) + (i32.store (local.get $input_len_ptr) (i32.const 246)) + (call $seal_input (local.get $input_ptr) (local.get $input_len_ptr)) (local.set $chosen_hash_fn (i32.load8_u (local.get $input_ptr))) (if (i32.gt_u (local.get $chosen_hash_fn) (i32.const 7)) ;; We check that the chosen hash fn identifier is within bounds: [0,7] (unreachable) ) (local.set $input_ptr (i32.add (local.get $input_ptr) (i32.const 1))) - (local.set $input_len (i32.sub (call $ext_scratch_size) (i32.const 1))) - (local.set $output_ptr (i32.const 100)) + (local.set $input_len (i32.sub (i32.load (local.get $input_len_ptr)) (i32.const 1))) (local.set $output_len (i32.load8_u (local.get $chosen_hash_fn))) (call_indirect (type $hash_fn_sig) (local.get $input_ptr) (local.get $input_len) - (local.get $output_ptr) + (local.get $input_ptr) (local.get $chosen_hash_fn) ;; Which crypto hash function to execute. ) - (call $ext_scratch_write - (local.get $output_ptr) ;; Linear memory location of the output buffer. + (call $seal_return + (i32.const 0) + (local.get $input_ptr) ;; Linear memory location of the output buffer. (local.get $output_len) ;; Number of output buffer bytes. ) - (i32.const 0) + (unreachable) ) ) diff --git a/frame/contracts/tests/destroy_and_transfer.wat b/frame/contracts/fixtures/destroy_and_transfer.wat similarity index 58% rename from frame/contracts/tests/destroy_and_transfer.wat rename to frame/contracts/fixtures/destroy_and_transfer.wat index c8cf7271d74193bccf3d8720c34c12b43471bd45..3220f4e612d7de40e3ee64f6cbce09757834dbea 100644 --- a/frame/contracts/tests/destroy_and_transfer.wat +++ b/frame/contracts/fixtures/destroy_and_transfer.wat @@ -1,12 +1,29 @@ (module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32))) + (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) + (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_instantiate" (func $seal_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) + ;; [0, 8) Endowment to send when creating contract. + (data (i32.const 0) "\00\00\01") + + ;; [8, 16) Value to send when calling contract. + + ;; [16, 48) The key to store the contract address under. + + ;; [48, 80) Buffer where to store the input to the contract + + ;; [80, 88) Buffer where to store the address of the instantiated contract + + ;; [88, 96) Size of the buffer + (data (i32.const 88) "\08") + + ;; [96, 100) Size of the input buffer + (data (i32.const 96) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -17,25 +34,19 @@ ) (func (export "deploy") - ;; Input data is the code hash of the contract to be deployed. + ;; Input data is the code hash of the contract to be deployed. + (call $seal_input (i32.const 48) (i32.const 96)) (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 96)) (i32.const 32) ) ) - ;; Copy code hash from scratch buffer into this contract's memory. - (call $ext_scratch_read - (i32.const 48) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 32) ;; Count of bytes to copy. - ) - ;; Deploy the contract with the provided code hash. (call $assert (i32.eq - (call $ext_instantiate + (call $seal_instantiate (i32.const 48) ;; Pointer to the code hash. (i32.const 32) ;; Length of the code hash. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -43,26 +54,25 @@ (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 0) ;; Pointer to input data buffer address (i32.const 0) ;; Length of input data buffer + (i32.const 80) ;; Buffer where to store address of new contract + (i32.const 88) ;; Pointer to the length of the buffer + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this cas ) (i32.const 0) ) ) - ;; Read the address of the instantiated contract into memory. + ;; Check that address has expected length (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 88)) (i32.const 8) ) ) - (call $ext_scratch_read - (i32.const 80) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) ;; Store the return address. - (call $ext_set_storage + (call $seal_set_storage (i32.const 16) ;; Pointer to the key (i32.const 80) ;; Pointer to the value (i32.const 8) ;; Length of the value @@ -73,28 +83,25 @@ ;; Read address of destination contract from storage. (call $assert (i32.eq - (call $ext_get_storage + (call $seal_get_storage (i32.const 16) ;; Pointer to the key + (i32.const 80) ;; Pointer to the value + (i32.const 88) ;; Pointer to the len of the value ) (i32.const 0) ) ) (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 88)) (i32.const 8) ) ) - (call $ext_scratch_read - (i32.const 80) ;; The pointer where to store the contract address. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) ;; Calling the destination contract with non-empty input data should fail. (call $assert (i32.eq - (call $ext_call + (call $seal_call (i32.const 80) ;; Pointer to destination address (i32.const 8) ;; Length of destination address (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -102,15 +109,18 @@ (i32.const 8) ;; Length of the buffer with value to transfer (i32.const 0) ;; Pointer to input data buffer address (i32.const 1) ;; Length of input data buffer + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this case + ) - (i32.const 0x0100) + (i32.const 0x1) ) ) ;; Call the destination contract regularly, forcing it to self-destruct. (call $assert (i32.eq - (call $ext_call + (call $seal_call (i32.const 80) ;; Pointer to destination address (i32.const 8) ;; Length of destination address (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -118,6 +128,8 @@ (i32.const 8) ;; Length of the buffer with value to transfer (i32.const 0) ;; Pointer to input data buffer address (i32.const 0) ;; Length of input data buffer + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this case ) (i32.const 0) ) @@ -128,21 +140,14 @@ ;; does not keep the contract alive. (call $assert (i32.eq - (call $ext_call + (call $seal_transfer (i32.const 80) ;; Pointer to destination address (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. (i32.const 0) ;; Pointer to the buffer with value to transfer (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 1) ;; Length of input data buffer ) (i32.const 0) ) ) ) - - (data (i32.const 0) "\00\00\01") ;; Endowment to send when creating contract. - (data (i32.const 8) "") ;; Value to send when calling contract. - (data (i32.const 16) "") ;; The key to store the contract address under. ) diff --git a/frame/contracts/fixtures/drain.wat b/frame/contracts/fixtures/drain.wat new file mode 100644 index 0000000000000000000000000000000000000000..9180047f5d015b47e75678ce12885125a99bdbe0 --- /dev/null +++ b/frame/contracts/fixtures/drain.wat @@ -0,0 +1,49 @@ +(module + (import "seal0" "seal_balance" (func $seal_balance (param i32 i32))) + (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32))) + (import "env" "memory" (memory 1 1)) + + ;; [0, 8) reserved for $seal_balance output + + ;; [8, 16) length of the buffer + (data (i32.const 8) "\08") + + ;; [16, inf) zero initialized + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "deploy")) + + (func (export "call") + ;; Send entire remaining balance to the 0 address. + (call $seal_balance (i32.const 0) (i32.const 8)) + + ;; Balance should be encoded as a u64. + (call $assert + (i32.eq + (i32.load (i32.const 8)) + (i32.const 8) + ) + ) + + ;; Self-destruct by sending full balance to the 0 address. + (call $assert + (i32.eq + (call $seal_transfer + (i32.const 16) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + (i32.const 0) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + ) + (i32.const 4) ;; ReturnCode::BelowSubsistenceThreshold + ) + ) + ) +) diff --git a/frame/contracts/fixtures/instantiate_return_code.wat b/frame/contracts/fixtures/instantiate_return_code.wat new file mode 100644 index 0000000000000000000000000000000000000000..20ab96d88ad2e2c6fc66139597cb561793a89268 --- /dev/null +++ b/frame/contracts/fixtures/instantiate_return_code.wat @@ -0,0 +1,47 @@ +;; This instantiats Charlie (3) and transfers 100 balance during this call and copies the return code +;; of this call to the output buffer. +;; The first 32 byte of input is the code hash to instantiate +;; The rest of the input is forwarded to the constructor of the callee +(module + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_instantiate" (func $seal_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + ;; [0, 8) address of django + (data (i32.const 0) "\04\00\00\00\00\00\00\00") + + ;; [8, 16) 100 balance + (data (i32.const 8) "\64\00\00\00\00\00\00\00") + + ;; [16, 20) here we store the return code of the transfer + + ;; [20, 24) size of the input buffer + (data (i32.const 20) "\FF") + + ;; [24, inf) input buffer + + (func (export "deploy")) + + (func (export "call") + (call $seal_input (i32.const 24) (i32.const 20)) + (i32.store + (i32.const 16) + (call $seal_instantiate + (i32.const 24) ;; Pointer to the code hash. + (i32.const 32) ;; Length of the code hash. + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 8) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer. + (i32.const 56) ;; Pointer to input data buffer address + (i32.sub (i32.load (i32.const 20)) (i32.const 32)) ;; Length of input data buffer + (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy address + (i32.const 0) ;; Length is ignored in this case + (i32.const 0xffffffff) ;; u32 max sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this case + ) + ) + ;; exit with success and take transfer return code to the output buffer + (call $seal_return (i32.const 0) (i32.const 16) (i32.const 4)) + ) +) diff --git a/frame/contracts/fixtures/ok_trap_revert.wat b/frame/contracts/fixtures/ok_trap_revert.wat new file mode 100644 index 0000000000000000000000000000000000000000..b71a6435db9c1b0ac363d1602a49ae46b76d47a9 --- /dev/null +++ b/frame/contracts/fixtures/ok_trap_revert.wat @@ -0,0 +1,35 @@ +(module + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func (export "deploy") + (call $ok_trap_revert) + ) + + (func (export "call") + (call $ok_trap_revert) + ) + + (func $ok_trap_revert + (i32.store (i32.const 4) (i32.const 4)) + (call $seal_input (i32.const 0) (i32.const 4)) + (block $IF_2 + (block $IF_1 + (block $IF_0 + (br_table $IF_0 $IF_1 $IF_2 + (i32.load8_u (i32.const 0)) + ) + (unreachable) + ) + ;; 0 = return with success + return + ) + ;; 1 = revert + (call $seal_return (i32.const 1) (i32.const 0) (i32.const 0)) + (unreachable) + ) + ;; 2 = trap + (unreachable) + ) +) \ No newline at end of file diff --git a/frame/contracts/tests/restoration.wat b/frame/contracts/fixtures/restoration.wat similarity index 54% rename from frame/contracts/tests/restoration.wat rename to frame/contracts/fixtures/restoration.wat index 4e11f97d5a2ccd722a44211082cbd523a9bc4737..3c15f7ae0881e1e3c225872bb51c9352b3194d6d 100644 --- a/frame/contracts/tests/restoration.wat +++ b/frame/contracts/fixtures/restoration.wat @@ -1,10 +1,33 @@ (module - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_restore_to" (func $ext_restore_to (param i32 i32 i32 i32 i32 i32 i32 i32))) + (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_restore_to" + (func $seal_restore_to + (param i32 i32 i32 i32 i32 i32 i32 i32) + ) + ) (import "env" "memory" (memory 1 1)) + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + (func (export "call") - (call $ext_restore_to + ;; copy code hash to contract memory + (call $seal_input (i32.const 264) (i32.const 304)) + (call $assert + (i32.eq + (i32.load (i32.const 304)) + (i32.const 32) + ) + ) + + (call $seal_restore_to ;; Pointer and length of the encoded dest buffer. (i32.const 256) (i32.const 8) @@ -22,14 +45,14 @@ ) (func (export "deploy") ;; Data to restore - (call $ext_set_storage + (call $seal_set_storage (i32.const 0) (i32.const 0) (i32.const 4) ) ;; ACL - (call $ext_set_storage + (call $seal_set_storage (i32.const 100) (i32.const 0) (i32.const 4) @@ -45,12 +68,11 @@ ;; Address of bob (data (i32.const 256) "\02\00\00\00\00\00\00\00") - ;; Code hash of SET_RENT - (data (i32.const 264) - "\c2\1c\41\10\a5\22\d8\59\1c\4c\77\35\dd\2d\bf\a1" - "\13\0b\50\93\76\9b\92\31\97\b7\c5\74\26\aa\38\2a" - ) + ;; [264, 296) Code hash of SET_RENT (copied here by seal_input) - ;; Rent allowance + ;; [296, 304) Rent allowance (data (i32.const 296) "\32\00\00\00\00\00\00\00") + + ;; [304, 308) Size of SET_RENT buffer + (data (i32.const 304) "\20") ) diff --git a/frame/contracts/tests/return_from_start_fn.wat b/frame/contracts/fixtures/return_from_start_fn.wat similarity index 64% rename from frame/contracts/tests/return_from_start_fn.wat rename to frame/contracts/fixtures/return_from_start_fn.wat index ac898d4d944e9f3b08e9d2a079a8ecbdc9c77658..854b552a828c251edb989f349976d535a9f22d14 100644 --- a/frame/contracts/tests/return_from_start_fn.wat +++ b/frame/contracts/fixtures/return_from_start_fn.wat @@ -1,17 +1,18 @@ (module - (import "env" "ext_return" (func $ext_return (param i32 i32))) - (import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) + (import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32))) (import "env" "memory" (memory 1 1)) (start $start) (func $start - (call $ext_deposit_event + (call $seal_deposit_event (i32.const 0) ;; The topics buffer (i32.const 0) ;; The topics buffer's length (i32.const 8) ;; The data buffer (i32.const 4) ;; The data buffer's length ) - (call $ext_return + (call $seal_return + (i32.const 0) (i32.const 8) (i32.const 4) ) diff --git a/frame/contracts/fixtures/return_with_data.wat b/frame/contracts/fixtures/return_with_data.wat new file mode 100644 index 0000000000000000000000000000000000000000..93b9daa07a303f632e56c360b173969e4c1dfdca --- /dev/null +++ b/frame/contracts/fixtures/return_with_data.wat @@ -0,0 +1,33 @@ +(module + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + ;; [0, 128) buffer where input is copied + + ;; [128, 132) length of the input buffer + (data (i32.const 128) "\80") + + ;; Deploy routine is the same as call. + (func (export "deploy") + (call $call) + ) + + ;; Call reads the first 4 bytes (LE) as the exit status and returns the rest as output data. + (func $call (export "call") + ;; Copy input into this contracts memory. + (call $seal_input (i32.const 0) (i32.const 128)) + + ;; Copy all but the first 4 bytes of the input data as the output data. + ;; Use the first byte as exit status + (call $seal_return + (i32.load8_u (i32.const 0)) ;; Exit status + (i32.const 4) ;; Pointer to the data to return. + (i32.sub ;; Count of bytes to copy. + (i32.load (i32.const 128)) + (i32.const 4) + ) + ) + (unreachable) + ) +) diff --git a/frame/contracts/tests/run_out_of_gas.wat b/frame/contracts/fixtures/run_out_of_gas.wat similarity index 100% rename from frame/contracts/tests/run_out_of_gas.wat rename to frame/contracts/fixtures/run_out_of_gas.wat diff --git a/frame/contracts/fixtures/self_destruct.wat b/frame/contracts/fixtures/self_destruct.wat new file mode 100644 index 0000000000000000000000000000000000000000..6898e746b0836719bd711b0e67949ee0906702b0 --- /dev/null +++ b/frame/contracts/fixtures/self_destruct.wat @@ -0,0 +1,80 @@ +(module + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_address" (func $seal_address (param i32 i32))) + (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + ;; [0, 8) reserved for $seal_address output + + ;; [8, 16) length of the buffer + (data (i32.const 8) "\08") + + ;; [16, 24) Address of django + (data (i32.const 16) "\04\00\00\00\00\00\00\00") + + ;; [24, 32) reserved for output of $seal_input + + ;; [32, 36) length of the buffer + (data (i32.const 32) "\04") + + ;; [36, inf) zero initialized + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "deploy")) + + (func (export "call") + ;; If the input data is not empty, then recursively call self with empty input data. + ;; This should trap instead of self-destructing since a contract cannot be removed live in + ;; the execution stack cannot be removed. If the recursive call traps, then trap here as + ;; well. + (call $seal_input (i32.const 24) (i32.const 32)) + (if (i32.load (i32.const 32)) + (then + (call $seal_address (i32.const 0) (i32.const 8)) + + ;; Expect address to be 8 bytes. + (call $assert + (i32.eq + (i32.load (i32.const 8)) + (i32.const 8) + ) + ) + + ;; Recursively call self with empty input data. + (call $assert + (i32.eq + (call $seal_call + (i32.const 0) ;; Pointer to own address + (i32.const 8) ;; Length of own address + (i64.const 0) ;; How much gas to devote for the execution. 0 = all. + (i32.const 36) ;; Pointer to the buffer with value to transfer + (i32.const 8) ;; Length of the buffer with value to transfer + (i32.const 0) ;; Pointer to input data buffer address + (i32.const 0) ;; Length of input data buffer + (i32.const 4294967295) ;; u32 max sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this case + ) + (i32.const 0) + ) + ) + ) + (else + ;; Try to terminate and give balance to django. + (call $seal_terminate + (i32.const 16) ;; Pointer to beneficiary address + (i32.const 8) ;; Length of beneficiary address + ) + (unreachable) ;; seal_terminate never returns + ) + ) + ) +) diff --git a/frame/contracts/fixtures/self_destructing_constructor.wat b/frame/contracts/fixtures/self_destructing_constructor.wat new file mode 100644 index 0000000000000000000000000000000000000000..ab8c289f1b5640cf893ee79b5fa20745234fb878 --- /dev/null +++ b/frame/contracts/fixtures/self_destructing_constructor.wat @@ -0,0 +1,23 @@ +(module + (import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32))) + (import "env" "memory" (memory 1 1)) + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "deploy") + ;; Self-destruct by sending full balance to the 0 address. + (call $seal_terminate + (i32.const 0) ;; Pointer to destination address + (i32.const 8) ;; Length of destination address + ) + ) + + (func (export "call")) +) diff --git a/frame/contracts/fixtures/set_empty_storage.wat b/frame/contracts/fixtures/set_empty_storage.wat new file mode 100644 index 0000000000000000000000000000000000000000..dbcd3a1326aa27298704d738f75b8d5110357763 --- /dev/null +++ b/frame/contracts/fixtures/set_empty_storage.wat @@ -0,0 +1,15 @@ +;; This module stores a KV pair into the storage +(module + (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) + (import "env" "memory" (memory 16 16)) + + (func (export "call") + ) + (func (export "deploy") + (call $seal_set_storage + (i32.const 0) ;; Pointer to storage key + (i32.const 0) ;; Pointer to value + (i32.load (i32.const 0)) ;; Size of value + ) + ) +) diff --git a/frame/contracts/tests/set_rent.wat b/frame/contracts/fixtures/set_rent.wat similarity index 50% rename from frame/contracts/tests/set_rent.wat rename to frame/contracts/fixtures/set_rent.wat index d1affa0d7415f4257597cfac518b5cc7a72631e6..a09d3dc4bd47aef14fe61c3108adbeaeedc67ba4 100644 --- a/frame/contracts/tests/set_rent.wat +++ b/frame/contracts/fixtures/set_rent.wat @@ -1,15 +1,14 @@ (module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_clear_storage" (func $ext_clear_storage (param i32))) - (import "env" "ext_set_rent_allowance" (func $ext_set_rent_allowance (param i32 i32))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) + (import "seal0" "seal_clear_storage" (func $seal_clear_storage (param i32))) + (import "seal0" "seal_set_rent_allowance" (func $seal_set_rent_allowance (param i32 i32))) + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) (import "env" "memory" (memory 1 1)) ;; insert a value of 4 bytes into storage (func $call_0 - (call $ext_set_storage + (call $seal_set_storage (i32.const 1) (i32.const 0) (i32.const 4) @@ -18,16 +17,18 @@ ;; remove the value inserted by call_1 (func $call_1 - (call $ext_clear_storage + (call $seal_clear_storage (i32.const 1) ) ) - ;; transfer 50 to ALICE + ;; transfer 50 to CHARLIE (func $call_2 - (call $ext_dispatch_call - (i32.const 68) - (i32.const 11) + (call $assert + (i32.eq + (call $seal_transfer (i32.const 68) (i32.const 8) (i32.const 76) (i32.const 8)) + (i32.const 0) + ) ) ) @@ -46,8 +47,10 @@ ;; Dispatch the call according to input size (func (export "call") (local $input_size i32) + (i32.store (i32.const 64) (i32.const 64)) + (call $seal_input (i32.const 1024) (i32.const 64)) (set_local $input_size - (call $ext_scratch_size) + (i32.load (i32.const 64)) ) (block $IF_ELSE (block $IF_2 @@ -73,29 +76,30 @@ ;; Set into storage a 4 bytes value ;; Set call set_rent_allowance with input (func (export "deploy") - (local $input_size i32) - (set_local $input_size - (call $ext_scratch_size) - ) - (call $ext_set_storage + (call $seal_set_storage (i32.const 0) (i32.const 0) (i32.const 4) ) - (call $ext_scratch_read + (call $seal_input (i32.const 0) - (i32.const 0) - (get_local $input_size) + (i32.const 64) ) - (call $ext_set_rent_allowance + (call $seal_set_rent_allowance (i32.const 0) - (get_local $input_size) + (i32.load (i32.const 64)) ) ) ;; Encoding of 10 in balance (data (i32.const 0) "\28") - ;; Encoding of call transfer 50 to CHARLIE - (data (i32.const 68) "\00\00\03\00\00\00\00\00\00\00\C8") + ;; Size of the buffer at address 0 + (data (i32.const 64) "\40") + + ;; encoding of Charlies's account id + (data (i32.const 68) "\03") + + ;; encoding of 50 balance + (data (i32.const 76) "\32") ) diff --git a/frame/contracts/fixtures/storage_size.wat b/frame/contracts/fixtures/storage_size.wat new file mode 100644 index 0000000000000000000000000000000000000000..293a656d4f6ea4e029e7fc7cbd98241da263f220 --- /dev/null +++ b/frame/contracts/fixtures/storage_size.wat @@ -0,0 +1,68 @@ +(module + (import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32))) + (import "seal0" "seal_set_storage" (func $seal_set_storage (param i32 i32 i32))) + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "env" "memory" (memory 16 16)) + + ;; [0, 32) storage key + (data (i32.const 0) "\01") + + ;; [32, 36) buffer where input is copied (expected size of storage item) + + ;; [36, 40) size of the input buffer + (data (i32.const 36) "\04") + + ;; [40, 44) size of buffer for seal_get_storage set to max + (data (i32.const 40) "\FF\FF\FF\FF") + + ;; [44, inf) seal_get_storage buffer + + (func $assert (param i32) + (block $ok + (br_if $ok + (get_local 0) + ) + (unreachable) + ) + ) + + (func (export "call") + (call $seal_input (i32.const 32) (i32.const 36)) + + ;; assert input size == 4 + (call $assert + (i32.eq + (i32.load (i32.const 36)) + (i32.const 4) + ) + ) + + ;; place a garbage value in storage, the size of which is specified by the call input. + (call $seal_set_storage + (i32.const 0) ;; Pointer to storage key + (i32.const 0) ;; Pointer to value + (i32.load (i32.const 32)) ;; Size of value + ) + + (call $assert + (i32.eq + (call $seal_get_storage + (i32.const 0) ;; Pointer to storage key + (i32.const 44) ;; buffer where to copy result + (i32.const 40) ;; pointer to size of buffer + ) + (i32.const 0) + ) + ) + + (call $assert + (i32.eq + (i32.load (i32.const 40)) + (i32.load (i32.const 32)) + ) + ) + ) + + (func (export "deploy")) + +) diff --git a/frame/contracts/fixtures/transfer_return_code.wat b/frame/contracts/fixtures/transfer_return_code.wat new file mode 100644 index 0000000000000000000000000000000000000000..7a1bec9adf38c5e71f5ce50aa6b02bb5f329009a --- /dev/null +++ b/frame/contracts/fixtures/transfer_return_code.wat @@ -0,0 +1,31 @@ +;; This transfers 100 balance to the zero account and copies the return code +;; of this transfer to the output buffer. +(module + (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) + (import "env" "memory" (memory 1 1)) + + ;; [0, 8) zero-adress + (data (i32.const 0) "\00\00\00\00\00\00\00\00") + + ;; [8, 16) 100 balance + (data (i32.const 8) "\64\00\00\00\00\00\00\00") + + ;; [16, 20) here we store the return code of the transfer + + (func (export "deploy")) + + (func (export "call") + (i32.store + (i32.const 16) + (call $seal_transfer + (i32.const 0) ;; ptr to destination address + (i32.const 8) ;; length of destination address + (i32.const 8) ;; ptr to value to transfer + (i32.const 8) ;; length of value to transfer + ) + ) + ;; exit with success and take transfer return code to the output buffer + (call $seal_return (i32.const 0) (i32.const 16) (i32.const 4)) + ) +) diff --git a/frame/contracts/rpc/Cargo.toml b/frame/contracts/rpc/Cargo.toml index 66d75759f1a25cdb2ff9b6757f44fa6ec79919e3..0de6bc105a9b186bb218ffcaa63c28f2c5eede7a 100644 --- a/frame/contracts/rpc/Cargo.toml +++ b/frame/contracts/rpc/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-contracts-rpc" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Node-specific RPC methods for interaction with contracts." @@ -12,18 +12,18 @@ description = "Node-specific RPC methods for interaction with contracts." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0" } -jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.5" -jsonrpc-derive = "14.0.3" -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-rpc = { version = "2.0.0-dev", path = "../../../primitives/rpc" } +codec = { package = "parity-scale-codec", version = "1.3.4" } +jsonrpc-core = "14.2.0" +jsonrpc-core-client = "14.2.0" +jsonrpc-derive = "14.2.1" +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0-rc6", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -pallet-contracts-primitives = { version = "2.0.0-dev", path = "../common" } -pallet-contracts-rpc-runtime-api = { version = "0.8.0-dev", path = "./runtime-api" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +pallet-contracts-primitives = { version = "2.0.0-rc6", path = "../common" } +pallet-contracts-rpc-runtime-api = { version = "0.8.0-rc6", path = "./runtime-api" } [dev-dependencies] serde_json = "1.0.41" diff --git a/frame/contracts/rpc/README.md b/frame/contracts/rpc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..be6df237bf60d225a0b27b2f4e8d4651e6358016 --- /dev/null +++ b/frame/contracts/rpc/README.md @@ -0,0 +1,3 @@ +Node-specific RPC methods for interaction with contracts. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/contracts/rpc/runtime-api/Cargo.toml b/frame/contracts/rpc/runtime-api/Cargo.toml index 81c6ce3760129a58a753d0bd47519ff117fda388..fcb57d0a69fc153e4b10b36762a5104d3b7fe7cd 100644 --- a/frame/contracts/rpc/runtime-api/Cargo.toml +++ b/frame/contracts/rpc/runtime-api/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-contracts-rpc-runtime-api" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Runtime API definition required by Contracts RPC extensions." @@ -12,11 +12,11 @@ description = "Runtime API definition required by Contracts RPC extensions." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/api" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/runtime" } -pallet-contracts-primitives = { version = "2.0.0-dev", default-features = false, path = "../../common" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../../../../primitives/api" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../../primitives/runtime" } +pallet-contracts-primitives = { version = "2.0.0-rc6", default-features = false, path = "../../common" } [features] default = ["std"] diff --git a/frame/contracts/rpc/runtime-api/README.md b/frame/contracts/rpc/runtime-api/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d57f29a93bd1dca89ea826a535d47036cb97efd7 --- /dev/null +++ b/frame/contracts/rpc/runtime-api/README.md @@ -0,0 +1,7 @@ +Runtime API definition required by Contracts RPC extensions. + +This API should be imported and implemented by the runtime, +of a node that wants to use the custom RPC extension +adding Contracts access methods. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/contracts/rpc/runtime-api/src/lib.rs b/frame/contracts/rpc/runtime-api/src/lib.rs index 6fb629b02458129e0bc8ffe13bdf363cd45479e1..7d208cf7763e7f2458cf507285dacaaa0cd2ce3f 100644 --- a/frame/contracts/rpc/runtime-api/src/lib.rs +++ b/frame/contracts/rpc/runtime-api/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Runtime API definition required by Contracts RPC extensions. //! @@ -34,12 +35,15 @@ pub enum ContractExecResult { /// /// There is a status code and, optionally, some data returned by the contract. Success { - /// Status code returned by the contract. - status: u8, + /// Flags that the contract passed along on returning to alter its exit behaviour. + /// Described in `pallet_contracts::exec::ReturnFlags`. + flags: u32, /// Output data returned by the contract. /// /// Can be empty. data: Vec, + /// How much gas was consumed by the call. + gas_consumed: u64, }, /// The contract execution either trapped or returned an error. Error, diff --git a/frame/contracts/rpc/src/lib.rs b/frame/contracts/rpc/src/lib.rs index 53e8d938703c866de09d1234e2a34ebb51122e09..d99ed1e78a652cd90006b1dabed65be2df2827c8 100644 --- a/frame/contracts/rpc/src/lib.rs +++ b/frame/contracts/rpc/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Node-specific RPC methods for interaction with contracts. @@ -31,6 +32,7 @@ use sp_runtime::{ generic::BlockId, traits::{Block as BlockT, Header as HeaderT}, }; +use std::convert::TryInto; pub use self::gen_client::Client as ContractsClient; pub use pallet_contracts_rpc_runtime_api::{ @@ -79,7 +81,7 @@ pub struct CallRequest { origin: AccountId, dest: AccountId, value: Balance, - gas_limit: number::NumberOrHex, + gas_limit: number::NumberOrHex, input_data: Bytes, } @@ -90,10 +92,12 @@ pub struct CallRequest { pub enum RpcContractExecResult { /// Successful execution Success { - /// Status code - status: u8, + /// The return flags + flags: u32, /// Output data data: Bytes, + /// How much gas was consumed by the call. + gas_consumed: u64, }, /// Error execution Error(()), @@ -102,9 +106,14 @@ pub enum RpcContractExecResult { impl From for RpcContractExecResult { fn from(r: ContractExecResult) -> Self { match r { - ContractExecResult::Success { status, data } => RpcContractExecResult::Success { - status, + ContractExecResult::Success { + flags, + data, + gas_consumed + } => RpcContractExecResult::Success { + flags, data: data.into(), + gas_consumed, }, ContractExecResult::Error => RpcContractExecResult::Error(()), } @@ -202,9 +211,11 @@ where gas_limit, input_data, } = call_request; - let gas_limit = gas_limit.to_number().map_err(|e| Error { + + // Make sure that gas_limit fits into 64 bits. + let gas_limit: u64 = gas_limit.try_into().map_err(|_| Error { code: ErrorCode::InvalidParams, - message: e, + message: format!("{:?} doesn't fit in 64 bit unsigned value", gas_limit), data: None, })?; @@ -281,16 +292,31 @@ fn runtime_error_into_rpc_err(err: impl std::fmt::Debug) -> Error { #[cfg(test)] mod tests { use super::*; + use sp_core::U256; + + #[test] + fn call_request_should_serialize_deserialize_properly() { + type Req = CallRequest; + let req: Req = serde_json::from_str(r#" + { + "origin": "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", + "dest": "5DRakbLVnjVrW6niwLfHGW24EeCEvDAFGEXrtaYS5M4ynoom", + "value": 0, + "gasLimit": 1000000000000, + "inputData": "0x8c97db39" + } + "#).unwrap(); + assert_eq!(req.gas_limit.into_u256(), U256::from(0xe8d4a51000u64)); + } #[test] - fn should_serialize_deserialize_properly() { + fn result_should_serialize_deserialize_properly() { fn test(expected: &str) { let res: RpcContractExecResult = serde_json::from_str(expected).unwrap(); let actual = serde_json::to_string(&res).unwrap(); assert_eq!(actual, expected); } - - test(r#"{"success":{"status":5,"data":"0x1234"}}"#); + test(r#"{"success":{"flags":5,"data":"0x1234","gas_consumed":5000}}"#); test(r#"{"error":null}"#); } } diff --git a/frame/contracts/src/account_db.rs b/frame/contracts/src/account_db.rs deleted file mode 100644 index aae853d2ff9965c146eca1f816d6c59ed58c459d..0000000000000000000000000000000000000000 --- a/frame/contracts/src/account_db.rs +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Auxiliaries to help with managing partial changes to accounts state. - -use super::{ - AliveContractInfo, BalanceOf, CodeHash, ContractInfo, ContractInfoOf, Trait, TrieId, - TrieIdGenerator, -}; -use crate::exec::StorageKey; -use sp_std::cell::RefCell; -use sp_std::collections::btree_map::{BTreeMap, Entry}; -use sp_std::prelude::*; -use sp_io::hashing::blake2_256; -use sp_runtime::traits::{Bounded, Zero}; -use frame_support::traits::{Currency, Get, Imbalance, SignedImbalance}; -use frame_support::{storage::child, StorageMap}; -use frame_system; - -// Note: we don't provide Option because we can't create -// the trie_id in the overlay, thus we provide an overlay on the fields -// specifically. -pub struct ChangeEntry { - /// If Some(_), then the account balance is modified to the value. If None and `reset` is false, - /// the balance unmodified. If None and `reset` is true, the balance is reset to 0. - balance: Option>, - /// If Some(_), then a contract is instantiated with the code hash. If None and `reset` is false, - /// then the contract code is unmodified. If None and `reset` is true, the contract is deleted. - code_hash: Option>, - /// If Some(_), then the rent allowance is set to the value. If None and `reset` is false, then - /// the rent allowance is unmodified. If None and `reset` is true, the contract is deleted. - rent_allowance: Option>, - storage: BTreeMap>>, - /// If true, indicates that the existing contract and all its storage entries should be removed - /// and replaced with the fields on this change entry. Otherwise, the fields on this change - /// entry are updates merged into the existing contract info and storage. - reset: bool, -} - -impl ChangeEntry { - fn balance(&self) -> Option> { - self.balance.or_else(|| { - if self.reset { - Some(>::zero()) - } else { - None - } - }) - } - - fn code_hash(&self) -> Option>> { - if self.reset { - Some(self.code_hash) - } else { - self.code_hash.map(Some) - } - } - - fn rent_allowance(&self) -> Option>> { - if self.reset { - Some(self.rent_allowance) - } else { - self.rent_allowance.map(Some) - } - } - - fn storage(&self, location: &StorageKey) -> Option>> { - let value = self.storage.get(location).cloned(); - if self.reset { - Some(value.unwrap_or(None)) - } else { - value - } - } -} - -// Cannot derive(Default) since it erroneously bounds T by Default. -impl Default for ChangeEntry { - fn default() -> Self { - ChangeEntry { - rent_allowance: Default::default(), - balance: Default::default(), - code_hash: Default::default(), - storage: Default::default(), - reset: false, - } - } -} - -pub type ChangeSet = BTreeMap<::AccountId, ChangeEntry>; - -pub trait AccountDb { - /// Account is used when overlayed otherwise trie_id must be provided. - /// This is for performance reason. - /// - /// Trie id is None iff account doesn't have an associated trie id in >. - /// Because DirectAccountDb bypass the lookup for this association. - fn get_storage(&self, account: &T::AccountId, trie_id: Option<&TrieId>, location: &StorageKey) -> Option>; - /// If account has an alive contract then return the code hash associated. - fn get_code_hash(&self, account: &T::AccountId) -> Option>; - /// If account has an alive contract then return the rent allowance associated. - fn get_rent_allowance(&self, account: &T::AccountId) -> Option>; - /// Returns false iff account has no alive contract nor tombstone. - fn contract_exists(&self, account: &T::AccountId) -> bool; - fn get_balance(&self, account: &T::AccountId) -> BalanceOf; - - fn commit(&mut self, change_set: ChangeSet); -} - -pub struct DirectAccountDb; -impl AccountDb for DirectAccountDb { - fn get_storage( - &self, - _account: &T::AccountId, - trie_id: Option<&TrieId>, - location: &StorageKey - ) -> Option> { - trie_id.and_then(|id| child::get_raw(&crate::child_trie_info(&id[..]), &blake2_256(location))) - } - fn get_code_hash(&self, account: &T::AccountId) -> Option> { - >::get(account).and_then(|i| i.as_alive().map(|i| i.code_hash)) - } - fn get_rent_allowance(&self, account: &T::AccountId) -> Option> { - >::get(account).and_then(|i| i.as_alive().map(|i| i.rent_allowance)) - } - fn contract_exists(&self, account: &T::AccountId) -> bool { - >::contains_key(account) - } - fn get_balance(&self, account: &T::AccountId) -> BalanceOf { - T::Currency::free_balance(account) - } - fn commit(&mut self, s: ChangeSet) { - let mut total_imbalance = SignedImbalance::zero(); - for (address, changed) in s.into_iter() { - if let Some(balance) = changed.balance() { - let imbalance = T::Currency::make_free_balance_be(&address, balance); - total_imbalance = total_imbalance.merge(imbalance); - } - - if changed.code_hash().is_some() - || changed.rent_allowance().is_some() - || !changed.storage.is_empty() - || changed.reset - { - let old_info = match >::get(&address) { - Some(ContractInfo::Alive(alive)) => Some(alive), - None => None, - // Cannot commit changes to tombstone contract - Some(ContractInfo::Tombstone(_)) => continue, - }; - - let mut new_info = match (changed.reset, old_info.clone(), changed.code_hash) { - // Existing contract is being modified. - (false, Some(info), _) => info, - // Existing contract is being removed. - (true, Some(info), None) => { - child::kill_storage(&info.child_trie_info()); - >::remove(&address); - continue; - } - // Existing contract is being replaced by a new one. - (true, Some(info), Some(code_hash)) => { - child::kill_storage(&info.child_trie_info()); - AliveContractInfo:: { - code_hash, - storage_size: T::StorageSizeOffset::get(), - trie_id: ::TrieIdGenerator::trie_id(&address), - deduct_block: >::block_number(), - rent_allowance: >::max_value(), - last_write: None, - } - } - // New contract is being instantiated. - (_, None, Some(code_hash)) => { - AliveContractInfo:: { - code_hash, - storage_size: T::StorageSizeOffset::get(), - trie_id: ::TrieIdGenerator::trie_id(&address), - deduct_block: >::block_number(), - rent_allowance: >::max_value(), - last_write: None, - } - } - // There is no existing at the address nor a new one to be instantiated. - (_, None, None) => continue, - }; - - if let Some(rent_allowance) = changed.rent_allowance { - new_info.rent_allowance = rent_allowance; - } - - if let Some(code_hash) = changed.code_hash { - new_info.code_hash = code_hash; - } - - if !changed.storage.is_empty() { - new_info.last_write = Some(>::block_number()); - } - - for (k, v) in changed.storage.into_iter() { - if let Some(value) = child::get_raw( - &new_info.child_trie_info(), - &blake2_256(&k), - ) { - new_info.storage_size -= value.len() as u32; - } - if let Some(value) = v { - new_info.storage_size += value.len() as u32; - child::put_raw(&new_info.child_trie_info(), &blake2_256(&k), &value[..]); - } else { - child::kill(&new_info.child_trie_info(), &blake2_256(&k)); - } - } - - if old_info - .map(|old_info| old_info != new_info) - .unwrap_or(true) - { - >::insert(&address, ContractInfo::Alive(new_info)); - } - } - } - - match total_imbalance { - // If we've detected a positive imbalance as a result of our contract-level machinations - // then it's indicative of a buggy contracts system. - // Panicking is far from ideal as it opens up a DoS attack on block validators, however - // it's a less bad option than allowing arbitrary value to be created. - SignedImbalance::Positive(ref p) if !p.peek().is_zero() => - panic!("contract subsystem resulting in positive imbalance!"), - _ => {} - } - } -} -pub struct OverlayAccountDb<'a, T: Trait + 'a> { - local: RefCell>, - underlying: &'a dyn AccountDb, -} -impl<'a, T: Trait> OverlayAccountDb<'a, T> { - pub fn new(underlying: &'a dyn AccountDb) -> OverlayAccountDb<'a, T> { - OverlayAccountDb { - local: RefCell::new(ChangeSet::new()), - underlying, - } - } - - pub fn into_change_set(self) -> ChangeSet { - self.local.into_inner() - } - - pub fn set_storage( - &mut self, - account: &T::AccountId, - location: StorageKey, - value: Option>, - ) { - self.local.borrow_mut() - .entry(account.clone()) - .or_insert(Default::default()) - .storage - .insert(location, value); - } - - /// Return an error if contract already exists (either if it is alive or tombstone) - pub fn instantiate_contract( - &mut self, - account: &T::AccountId, - code_hash: CodeHash, - ) -> Result<(), &'static str> { - if self.contract_exists(account) { - return Err("Alive contract or tombstone already exists"); - } - - let mut local = self.local.borrow_mut(); - let contract = local.entry(account.clone()).or_insert_with(|| Default::default()); - - contract.code_hash = Some(code_hash); - contract.rent_allowance = Some(>::max_value()); - - Ok(()) - } - - /// Mark a contract as deleted. - pub fn destroy_contract(&mut self, account: &T::AccountId) { - let mut local = self.local.borrow_mut(); - local.insert( - account.clone(), - ChangeEntry { - reset: true, - ..Default::default() - } - ); - } - - /// Assume contract exists - pub fn set_rent_allowance(&mut self, account: &T::AccountId, rent_allowance: BalanceOf) { - self.local - .borrow_mut() - .entry(account.clone()) - .or_insert(Default::default()) - .rent_allowance = Some(rent_allowance); - } - pub fn set_balance(&mut self, account: &T::AccountId, balance: BalanceOf) { - self.local - .borrow_mut() - .entry(account.clone()) - .or_insert(Default::default()) - .balance = Some(balance); - } -} - -impl<'a, T: Trait> AccountDb for OverlayAccountDb<'a, T> { - fn get_storage( - &self, - account: &T::AccountId, - trie_id: Option<&TrieId>, - location: &StorageKey - ) -> Option> { - self.local - .borrow() - .get(account) - .and_then(|changes| changes.storage(location)) - .unwrap_or_else(|| self.underlying.get_storage(account, trie_id, location)) - } - fn get_code_hash(&self, account: &T::AccountId) -> Option> { - self.local - .borrow() - .get(account) - .and_then(|changes| changes.code_hash()) - .unwrap_or_else(|| self.underlying.get_code_hash(account)) - } - fn get_rent_allowance(&self, account: &T::AccountId) -> Option> { - self.local - .borrow() - .get(account) - .and_then(|changes| changes.rent_allowance()) - .unwrap_or_else(|| self.underlying.get_rent_allowance(account)) - } - fn contract_exists(&self, account: &T::AccountId) -> bool { - self.local - .borrow() - .get(account) - .and_then(|changes| changes.code_hash().map(|code_hash| code_hash.is_some())) - .unwrap_or_else(|| self.underlying.contract_exists(account)) - } - fn get_balance(&self, account: &T::AccountId) -> BalanceOf { - self.local - .borrow() - .get(account) - .and_then(|changes| changes.balance()) - .unwrap_or_else(|| self.underlying.get_balance(account)) - } - fn commit(&mut self, s: ChangeSet) { - let mut local = self.local.borrow_mut(); - - for (address, changed) in s.into_iter() { - match local.entry(address) { - Entry::Occupied(e) => { - let mut value = e.into_mut(); - if changed.reset { - *value = changed; - } else { - value.balance = changed.balance.or(value.balance); - value.code_hash = changed.code_hash.or(value.code_hash); - value.rent_allowance = changed.rent_allowance.or(value.rent_allowance); - value.storage.extend(changed.storage.into_iter()); - } - } - Entry::Vacant(e) => { - e.insert(changed); - } - } - } - } -} diff --git a/frame/contracts/src/benchmarking.rs b/frame/contracts/src/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..1a04db4defdb6dd4b6037e02d1ca0036c33fa298 --- /dev/null +++ b/frame/contracts/src/benchmarking.rs @@ -0,0 +1,271 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Benchmarks for the contracts pallet + +#![cfg(feature = "runtime-benchmarks")] + +use crate::*; +use crate::Module as Contracts; + +use frame_benchmarking::{benchmarks, account}; +use frame_system::{Module as System, RawOrigin}; +use parity_wasm::elements::FuncBody; +use sp_runtime::traits::Hash; + +macro_rules! load_module { + ($name:expr) => {{ + let code = include_bytes!(concat!("../fixtures/benchmarks/", $name, ".wat")); + compile_module::(code) + }}; +} + +fn compile_module(code: &[u8]) -> (Vec, ::Output) { + let code = sp_std::str::from_utf8(code).expect("Invalid utf8 in wat file."); + let binary = wat::parse_str(code).expect("Failed to compile wat file."); + let hash = T::Hashing::hash(&binary); + (binary, hash) +} + +fn funding() -> BalanceOf { + T::Currency::minimum_balance() * 10_000.into() +} + +fn create_funded_user(string: &'static str, n: u32) -> T::AccountId { + let user = account(string, n, 0); + T::Currency::make_free_balance_be(&user, funding::()); + user +} + +fn contract_with_call_body(body: FuncBody) -> (Vec, ::Output) { + use parity_wasm::elements::{ + Instructions, Instruction::End, + }; + let contract = parity_wasm::builder::ModuleBuilder::new() + // deploy function (idx 0) + .function() + .signature().with_params(vec![]).with_return_type(None).build() + .body().with_instructions(Instructions::new(vec![End])).build() + .build() + // call function (idx 1) + .function() + .signature().with_params(vec![]).with_return_type(None).build() + .with_body(body) + .build() + .export().field("deploy").internal().func(0).build() + .export().field("call").internal().func(1).build() + .build(); + let bytes = contract.to_bytes().unwrap(); + let hash = T::Hashing::hash(&bytes); + (bytes, hash) +} + +fn expanded_contract(target_bytes: u32) -> (Vec, ::Output) { + use parity_wasm::elements::{ + Instruction::{self, If, I32Const, Return, End}, + BlockType, Instructions, + }; + // Base size of a contract is 47 bytes and each expansion adds 6 bytes. + // We do one expansion less to account for the code section and function body + // size fields inside the binary wasm module representation which are leb128 encoded + // and therefore grow in size when the contract grows. We are not allowed to overshoot + // because of the maximum code size that is enforced by `put_code`. + let expansions = (target_bytes.saturating_sub(47) / 6).saturating_sub(1) as usize; + const EXPANSION: [Instruction; 4] = [ + I32Const(0), + If(BlockType::NoResult), + Return, + End, + ]; + let instructions = Instructions::new( + EXPANSION + .iter() + .cycle() + .take(EXPANSION.len() * expansions) + .cloned() + .chain(sp_std::iter::once(End)) + .collect() + ); + contract_with_call_body::(FuncBody::new(Vec::new(), instructions)) +} + +fn advance_block(num: ::BlockNumber) { + let now = System::::block_number(); + System::::set_block_number(now + num); +} + +benchmarks! { + _ { + } + + // This extrinsic is pretty much constant as it is only a simple setter. + update_schedule { + let schedule = Schedule { + version: 1, + .. Default::default() + }; + }: _(RawOrigin::Root, schedule) + + // This constructs a contract that is maximal expensive to instrument. + // It creates a maximum number of metering blocks per byte. + put_code { + let n in 0 .. Contracts::::current_schedule().max_code_size; + let caller = create_funded_user::("caller", 0); + let (binary, hash) = expanded_contract::(n); + }: _(RawOrigin::Signed(caller), binary) + + // Instantiate uses a dummy contract constructor to measure the overhead of the instantiate. + // The size of the data has no influence on the costs of this extrinsic as long as the contract + // won't call `seal_input` in its constructor to copy the data to contract memory. + // The dummy contract used here does not do this. The costs for the data copy is billed as + // part of `seal_input`. + instantiate { + let data = vec![0u8; 128]; + let endowment = Config::::subsistence_threshold_uncached(); + let caller = create_funded_user::("caller", 0); + let (binary, hash) = load_module!("dummy"); + Contracts::::put_code(RawOrigin::Signed(caller.clone()).into(), binary.to_vec()) + .unwrap(); + + }: _( + RawOrigin::Signed(caller.clone()), + endowment, + Weight::max_value(), + hash, + data + ) + verify { + assert_eq!( + funding::() - endowment, + T::Currency::free_balance(&caller), + ) + } + + // We just call a dummy contract to measure to overhead of the call extrinsic. + // As for instantiate the size of the data does not influence the costs. + call { + let data = vec![0u8; 128]; + let endowment = Config::::subsistence_threshold_uncached(); + let value = T::Currency::minimum_balance() * 100.into(); + let caller = create_funded_user::("caller", 0); + let (binary, hash) = load_module!("dummy"); + let addr = T::DetermineContractAddress::contract_address_for(&hash, &[], &caller); + Contracts::::put_code(RawOrigin::Signed(caller.clone()).into(), binary.to_vec()) + .unwrap(); + Contracts::::instantiate( + RawOrigin::Signed(caller.clone()).into(), + endowment, + Weight::max_value(), + hash, + vec![], + ).unwrap(); + }: _( + RawOrigin::Signed(caller.clone()), + T::Lookup::unlookup(addr), + value, + Weight::max_value(), + data + ) + verify { + assert_eq!( + funding::() - endowment - value, + T::Currency::free_balance(&caller), + ) + } + + // We benchmark the costs for sucessfully evicting an empty contract. + // The actual costs are depending on how many storage items the evicted contract + // does have. However, those costs are not to be payed by the sender but + // will be distributed over multiple blocks using a scheduler. Otherwise there is + // no incentive to remove large contracts when the removal is more expensive than + // the reward for removing them. + claim_surcharge { + let endowment = Config::::subsistence_threshold_uncached(); + let value = T::Currency::minimum_balance() * 100.into(); + let caller = create_funded_user::("caller", 0); + let (binary, hash) = load_module!("dummy"); + let addr = T::DetermineContractAddress::contract_address_for(&hash, &[], &caller); + Contracts::::put_code(RawOrigin::Signed(caller.clone()).into(), binary.to_vec()) + .unwrap(); + Contracts::::instantiate( + RawOrigin::Signed(caller.clone()).into(), + endowment, + Weight::max_value(), + hash, + vec![], + ).unwrap(); + + // instantiate should leave us with an alive contract + ContractInfoOf::::get(addr.clone()).unwrap().get_alive().unwrap(); + + // generate some rent + advance_block::(::SignedClaimHandicap::get() + 1.into()); + + }: _(RawOrigin::Signed(caller.clone()), addr.clone(), None) + verify { + // the claim surcharge should have evicted the contract + ContractInfoOf::::get(addr.clone()).unwrap().get_tombstone().unwrap(); + + // the caller should get the reward for being a good snitch + assert_eq!( + funding::() - endowment + ::SurchargeReward::get(), + T::Currency::free_balance(&caller), + ); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{ExtBuilder, Test}; + use frame_support::assert_ok; + + #[test] + fn update_schedule() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_update_schedule::()); + }); + } + + #[test] + fn put_code() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_put_code::()); + }); + } + + #[test] + fn instantiate() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_instantiate::()); + }); + } + + #[test] + fn call() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_call::()); + }); + } + + #[test] + fn claim_surcharge() { + ExtBuilder::default().build().execute_with(|| { + assert_ok!(test_benchmark_claim_surcharge::()); + }); + } +} diff --git a/frame/contracts/src/exec.rs b/frame/contracts/src/exec.rs index 9cc1c50260db9fed6581217e08107a61d4aafe6c..ce4e17cd1b9faadb97e4291f7bdb7bd475139b7d 100644 --- a/frame/contracts/src/exec.rs +++ b/frame/contracts/src/exec.rs @@ -14,21 +14,22 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use super::{CodeHash, Config, ContractAddressFor, Event, RawEvent, Trait, - TrieId, BalanceOf, ContractInfo}; -use crate::account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}; -use crate::gas::{Gas, GasMeter, Token}; -use crate::rent; - +use crate::{ + CodeHash, Config, ContractAddressFor, Event, RawEvent, Trait, + TrieId, BalanceOf, ContractInfo, TrieIdGenerator, + gas::{Gas, GasMeter, Token}, rent, storage, Error, ContractInfoOf +}; +use bitflags::bitflags; use sp_std::prelude::*; -use sp_runtime::traits::{Bounded, CheckedAdd, CheckedSub, Zero}; +use sp_runtime::traits::{Bounded, Zero, Convert, Saturating}; use frame_support::{ - storage::unhashed, dispatch::DispatchError, - traits::{WithdrawReason, Currency, Time, Randomness}, + dispatch::DispatchError, + traits::{ExistenceRequirement, Currency, Time, Randomness}, + weights::Weight, + ensure, StorageMap, }; pub type AccountIdOf = ::AccountId; -pub type CallOf = ::Call; pub type MomentOf = <::Time as Time>::Moment; pub type SeedOf = ::Hash; pub type BlockNumberOf = ::BlockNumber; @@ -37,59 +38,73 @@ pub type StorageKey = [u8; 32]; /// A type that represents a topic of an event. At the moment a hash is used. pub type TopicOf = ::Hash; -/// A status code return to the source of a contract call or instantiation indicating success or -/// failure. A code of 0 indicates success and that changes are applied. All other codes indicate -/// failure and that changes are reverted. The particular code in the case of failure is opaque and -/// may be interpreted by the calling contract. -pub type StatusCode = u8; +bitflags! { + /// Flags used by a contract to customize exit behaviour. + pub struct ReturnFlags: u32 { + /// If this bit is set all changes made by the contract exection are rolled back. + const REVERT = 0x0000_0001; + } +} -/// The status code indicating success. -pub const STATUS_SUCCESS: StatusCode = 0; +/// Describes whether we deal with a contract or a plain account. +pub enum TransactorKind { + /// Transaction was initiated from a plain account. That can be either be through a + /// signed transaction or through RPC. + PlainAccount, + /// The call was initiated by a contract account. + Contract, +} /// Output of a contract call or instantiation which ran to completion. #[cfg_attr(test, derive(PartialEq, Eq, Debug))] pub struct ExecReturnValue { - pub status: StatusCode, + /// Flags passed along by `seal_return`. Empty when `seal_return` was never called. + pub flags: ReturnFlags, + /// Buffer passed along by `seal_return`. Empty when `seal_return` was never called. pub data: Vec, } impl ExecReturnValue { - /// Returns whether the call or instantiation exited with a successful status code. + /// We understand the absense of a revert flag as success. pub fn is_success(&self) -> bool { - self.status == STATUS_SUCCESS + !self.flags.contains(ReturnFlags::REVERT) } } -/// An error indicating some failure to execute a contract call or instantiation. This can include -/// VM-specific errors during execution (eg. division by 0, OOB access, failure to satisfy some -/// precondition of a system call, etc.) or errors with the orchestration (eg. out-of-gas errors, a -/// non-existent destination contract, etc.). -#[cfg_attr(test, derive(sp_runtime::RuntimeDebug))] -pub struct ExecError { - pub reason: DispatchError, - /// This is an allocated buffer that may be reused. The buffer must be cleared explicitly - /// before reuse. - pub buffer: Vec, +/// Call or instantiate both call into other contracts and pass through errors happening +/// in those to the caller. This enum is for the caller to distinguish whether the error +/// happened during the execution of the callee or in the current execution context. +#[cfg_attr(test, derive(PartialEq, Eq, Debug))] +pub enum ErrorOrigin { + /// The error happened in the current exeuction context rather than in the one + /// of the contract that is called into. + Caller, + /// The error happened during execution of the called contract. + Callee, } -pub type ExecResult = Result; +/// Error returned by contract exection. +#[cfg_attr(test, derive(PartialEq, Eq, Debug))] +pub struct ExecError { + /// The reason why the execution failed. + pub error: DispatchError, + /// Origin of the error. + pub origin: ErrorOrigin, +} -/// Evaluate an expression of type Result<_, &'static str> and either resolve to the value if Ok or -/// wrap the error string into an ExecutionError with the provided buffer and return from the -/// enclosing function. This macro is used instead of .map_err(..)? in order to avoid taking -/// ownership of buffer unless there is an error. -#[macro_export] -macro_rules! try_or_exec_error { - ($e:expr, $buffer:expr) => { - match $e { - Ok(val) => val, - Err(reason) => return Err( - $crate::exec::ExecError { reason: reason.into(), buffer: $buffer } - ), +impl> From for ExecError { + fn from(error: T) -> Self { + Self { + error: error.into(), + origin: ErrorOrigin::Caller, } } } +/// The result that is returned from contract execution. It either contains the output +/// buffer or an error describing the reason for failure. +pub type ExecResult = Result; + /// An interface that provides access to the external environment in which the /// smart-contract is executed. /// @@ -105,8 +120,8 @@ pub trait Ext { fn get_storage(&self, key: &StorageKey) -> Option>; /// Sets the storage entry by the given key to the specified value. If `value` is `None` then - /// the storage entry is deleted. Returns an Err if the value size is too large. - fn set_storage(&mut self, key: StorageKey, value: Option>) -> Result<(), &'static str>; + /// the storage entry is deleted. + fn set_storage(&mut self, key: StorageKey, value: Option>); /// Instantiate a contract from the given code. /// @@ -129,6 +144,12 @@ pub trait Ext { ) -> Result<(), DispatchError>; /// Transfer all funds to `beneficiary` and delete the contract. + /// + /// Since this function removes the self contract eagerly, if succeeded, no further actions should + /// be performed on this `Ext` instance. + /// + /// This function will fail if the same contract is present on the contract + /// call stack. fn terminate( &mut self, beneficiary: &AccountIdOf, @@ -144,17 +165,20 @@ pub trait Ext { input_data: Vec, ) -> ExecResult; - /// Notes a call dispatch. - fn note_dispatch_call(&mut self, call: CallOf); - - /// Notes a restoration request. - fn note_restore_to( + /// Restores the given destination contract sacrificing the current one. + /// + /// Since this function removes the self contract eagerly, if succeeded, no further actions should + /// be performed on this `Ext` instance. + /// + /// This function will fail if the same contract is present + /// on the contract call stack. + fn restore_to( &mut self, dest: AccountIdOf, code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec, - ); + ) -> Result<(), &'static str>; /// Returns a reference to the account id of the caller. fn caller(&self) -> &AccountIdOf; @@ -199,13 +223,8 @@ pub trait Ext { /// Returns the maximum allowed size of a storage item. fn max_value_size(&self) -> u32; - /// Returns the value of runtime under the given key. - /// - /// Returns `None` if the value doesn't exist. - fn get_runtime_storage(&self, key: &[u8]) -> Option>; - - /// Returns the price of one weight unit. - fn get_weight_price(&self) -> BalanceOf; + /// Returns the price for the specified amount of weight. + fn get_weight_price(&self, weight: Weight) -> BalanceOf; } /// Loader is a companion of the `Vm` trait. It loads an appropriate abstract @@ -261,43 +280,11 @@ impl Token for ExecFeeToken { } } -#[cfg_attr(any(feature = "std", test), derive(PartialEq, Eq, Clone))] -#[derive(sp_runtime::RuntimeDebug)] -pub enum DeferredAction { - DepositEvent { - /// A list of topics this event will be deposited with. - topics: Vec, - /// The event to deposit. - event: Event, - }, - DispatchRuntimeCall { - /// The account id of the contract who dispatched this call. - origin: T::AccountId, - /// The call to dispatch. - call: ::Call, - }, - RestoreTo { - /// The account id of the contract which is removed during the restoration and transfers - /// its storage to the restored contract. - donor: T::AccountId, - /// The account id of the restored contract. - dest: T::AccountId, - /// The code hash of the restored contract. - code_hash: CodeHash, - /// The initial rent allowance to set. - rent_allowance: BalanceOf, - /// The keys to delete upon restoration. - delta: Vec, - }, -} - pub struct ExecutionContext<'a, T: Trait + 'a, V, L> { pub caller: Option<&'a ExecutionContext<'a, T, V, L>>, pub self_account: T::AccountId, pub self_trie_id: Option, - pub overlay: OverlayAccountDb<'a, T>, pub depth: usize, - pub deferred: Vec>, pub config: &'a Config, pub vm: &'a V, pub loader: &'a L, @@ -320,9 +307,7 @@ where caller: None, self_trie_id: None, self_account: origin, - overlay: OverlayAccountDb::::new(&DirectAccountDb), depth: 0, - deferred: Vec::new(), config: &cfg, vm: &vm, loader: &loader, @@ -331,16 +316,14 @@ where } } - fn nested<'b, 'c: 'b>(&'c self, dest: T::AccountId, trie_id: Option) + fn nested<'b, 'c: 'b>(&'c self, dest: T::AccountId, trie_id: TrieId) -> ExecutionContext<'b, T, V, L> { ExecutionContext { caller: Some(self), - self_trie_id: trie_id, + self_trie_id: Some(trie_id), self_account: dest, - overlay: OverlayAccountDb::new(&self.overlay), depth: self.depth + 1, - deferred: Vec::new(), config: self.config, vm: self.vm, loader: self.loader, @@ -349,23 +332,6 @@ where } } - /// Transfer balance to `dest` without calling any contract code. - pub fn transfer( - &mut self, - dest: T::AccountId, - value: BalanceOf, - gas_meter: &mut GasMeter - ) -> Result<(), DispatchError> { - transfer( - gas_meter, - TransferCause::Call, - &self.self_account.clone(), - &dest, - value, - self, - ) - } - /// Make a call to the specified address, optionally transferring some funds. pub fn call( &mut self, @@ -375,73 +341,52 @@ where input_data: Vec, ) -> ExecResult { if self.depth == self.config.max_depth as usize { - return Err(ExecError { - reason: "reached maximum depth, cannot make a call".into(), - buffer: input_data, - }); + Err(Error::::MaxCallDepthReached)? } if gas_meter .charge(self.config, ExecFeeToken::Call) .is_out_of_gas() { - return Err(ExecError { - reason: "not enough gas to pay base call fee".into(), - buffer: input_data, - }); + Err(Error::::OutOfGas)? } // Assumption: `collect_rent` doesn't collide with overlay because // `collect_rent` will be done on first call and destination contract and balance // cannot be changed before the first call - let contract_info = rent::collect_rent::(&dest); - - // Calls to dead contracts always fail. - if let Some(ContractInfo::Tombstone(_)) = contract_info { - return Err(ExecError { - reason: "contract has been evicted".into(), - buffer: input_data, - }); + // We do not allow 'calling' plain accounts. For transfering value + // `seal_transfer` must be used. + let contract = if let Some(ContractInfo::Alive(info)) = rent::collect_rent::(&dest) { + info + } else { + Err(Error::::NotCallable)? }; + let transactor_kind = self.transactor_kind(); let caller = self.self_account.clone(); - let dest_trie_id = contract_info.and_then(|i| i.as_alive().map(|i| i.trie_id.clone())); - self.with_nested_context(dest.clone(), dest_trie_id, |nested| { + self.with_nested_context(dest.clone(), contract.trie_id.clone(), |nested| { if value > BalanceOf::::zero() { - try_or_exec_error!( - transfer( - gas_meter, - TransferCause::Call, - &caller, - &dest, - value, - nested, - ), - input_data - ); + transfer( + gas_meter, + TransferCause::Call, + transactor_kind, + &caller, + &dest, + value, + nested, + )? } - // If code_hash is not none, then the destination account is a live contract, otherwise - // it is a regular account since tombstone accounts have already been rejected. - match nested.overlay.get_code_hash(&dest) { - Some(dest_code_hash) => { - let executable = try_or_exec_error!( - nested.loader.load_main(&dest_code_hash), - input_data - ); - let output = nested.vm - .execute( - &executable, - nested.new_call_context(caller, value), - input_data, - gas_meter, - )?; - - Ok(output) - } - None => Ok(ExecReturnValue { status: STATUS_SUCCESS, data: Vec::new() }), - } + let executable = nested.loader.load_main(&contract.code_hash) + .map_err(|_| Error::::CodeNotFound)?; + let output = nested.vm.execute( + &executable, + nested.new_call_context(caller, value), + input_data, + gas_meter, + ).map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?; + Ok(output) }) } @@ -453,22 +398,17 @@ where input_data: Vec, ) -> Result<(T::AccountId, ExecReturnValue), ExecError> { if self.depth == self.config.max_depth as usize { - return Err(ExecError { - reason: "reached maximum depth, cannot instantiate".into(), - buffer: input_data, - }); + Err(Error::::MaxCallDepthReached)? } if gas_meter .charge(self.config, ExecFeeToken::Instantiate) .is_out_of_gas() { - return Err(ExecError { - reason: "not enough gas to pay base instantiate fee".into(), - buffer: input_data, - }); + Err(Error::::OutOfGas)? } + let transactor_kind = self.transactor_kind(); let caller = self.self_account.clone(); let dest = T::DetermineContractAddress::contract_address_for( code_hash, @@ -477,53 +417,51 @@ where ); // TrieId has not been generated yet and storage is empty since contract is new. - let dest_trie_id = None; + // + // Generate it now. + let dest_trie_id = ::TrieIdGenerator::trie_id(&dest); let output = self.with_nested_context(dest.clone(), dest_trie_id, |nested| { - try_or_exec_error!( - nested.overlay.instantiate_contract(&dest, code_hash.clone()), - input_data - ); + storage::place_contract::( + &dest, + nested + .self_trie_id + .clone() + .expect("the nested context always has to have self_trie_id"), + code_hash.clone() + )?; // Send funds unconditionally here. If the `endowment` is below existential_deposit // then error will be returned here. - try_or_exec_error!( - transfer( - gas_meter, - TransferCause::Instantiate, - &caller, - &dest, - endowment, - nested, - ), - input_data - ); - - let executable = try_or_exec_error!( - nested.loader.load_init(&code_hash), - input_data - ); + transfer( + gas_meter, + TransferCause::Instantiate, + transactor_kind, + &caller, + &dest, + endowment, + nested, + )?; + + let executable = nested.loader.load_init(&code_hash) + .map_err(|_| Error::::CodeNotFound)?; let output = nested.vm .execute( &executable, nested.new_call_context(caller.clone(), endowment), input_data, gas_meter, - )?; - - // Error out if insufficient remaining balance. - if nested.overlay.get_balance(&dest) < nested.config.existential_deposit { - return Err(ExecError { - reason: "insufficient remaining balance".into(), - buffer: output.data, - }); + ).map_err(|e| ExecError { error: e.error, origin: ErrorOrigin::Callee })?; + + // We need each contract that exists to be above the subsistence threshold + // in order to keep up the guarantuee that we always leave a tombstone behind + // with the exception of a contract that called `seal_terminate`. + if T::Currency::total_balance(&dest) < nested.config.subsistence_threshold() { + Err(Error::::NewContractNotFunded)? } // Deposit an instantiation event. - nested.deferred.push(DeferredAction::DepositEvent { - event: RawEvent::Instantiated(caller.clone(), dest.clone()), - topics: Vec::new(), - }); + deposit_event::(vec![], RawEvent::Instantiated(caller.clone(), dest.clone())); Ok(output) })?; @@ -531,32 +469,6 @@ where Ok((dest, output)) } - pub fn terminate( - &mut self, - beneficiary: &T::AccountId, - gas_meter: &mut GasMeter, - ) -> Result<(), DispatchError> { - let self_id = self.self_account.clone(); - let value = self.overlay.get_balance(&self_id); - if let Some(caller) = self.caller { - if caller.is_live(&self_id) { - return Err(DispatchError::Other( - "Cannot terminate a contract that is present on the call stack", - )); - } - } - transfer( - gas_meter, - TransferCause::Terminate, - &self_id, - beneficiary, - value, - self, - )?; - self.overlay.destroy_contract(&self_id); - Ok(()) - } - fn new_call_context<'b>( &'b mut self, caller: T::AccountId, @@ -573,22 +485,20 @@ where } } - fn with_nested_context(&mut self, dest: T::AccountId, trie_id: Option, func: F) + /// Execute the given closure within a nested execution context. + fn with_nested_context(&mut self, dest: T::AccountId, trie_id: TrieId, func: F) -> ExecResult where F: FnOnce(&mut ExecutionContext) -> ExecResult { - let (output, change_set, deferred) = { - let mut nested = self.nested(dest, trie_id); - let output = func(&mut nested)?; - (output, nested.overlay.into_change_set(), nested.deferred) - }; - - if output.is_success() { - self.overlay.commit(change_set); - self.deferred.extend(deferred); - } - - Ok(output) + use frame_support::storage::TransactionOutcome::*; + let mut nested = self.nested(dest, trie_id); + frame_support::storage::with_transaction(|| { + let output = func(&mut nested); + match output { + Ok(ref rv) if !rv.flags.contains(ReturnFlags::REVERT) => Commit(output), + _ => Rollback(output), + } + }) } /// Returns whether a contract, identified by address, is currently live in the execution @@ -597,6 +507,17 @@ where &self.self_account == account || self.caller.map_or(false, |caller| caller.is_live(account)) } + + fn transactor_kind(&self) -> TransactorKind { + if self.depth == 0 { + debug_assert!(self.self_trie_id.is_none()); + debug_assert!(self.caller.is_none()); + debug_assert!(ContractInfoOf::::get(&self.self_account).is_none()); + TransactorKind::PlainAccount + } else { + TransactorKind::Contract + } + } } #[cfg_attr(test, derive(Debug, PartialEq, Eq))] @@ -650,6 +571,7 @@ enum TransferCause { fn transfer<'a, T: Trait, V: Vm, L: Loader>( gas_meter: &mut GasMeter, cause: TransferCause, + origin: TransactorKind, transactor: &T::AccountId, dest: &T::AccountId, value: BalanceOf, @@ -657,6 +579,7 @@ fn transfer<'a, T: Trait, V: Vm, L: Loader>( ) -> Result<(), DispatchError> { use self::TransferCause::*; use self::TransferFeeKind::*; + use self::TransactorKind::*; let token = { let kind: TransferFeeKind = match cause { @@ -673,51 +596,41 @@ fn transfer<'a, T: Trait, V: Vm, L: Loader>( }; if gas_meter.charge(ctx.config, token).is_out_of_gas() { - Err("not enough gas to pay transfer fee")? - } - - // We allow balance to go below the existential deposit here: - let from_balance = ctx.overlay.get_balance(transactor); - let new_from_balance = match from_balance.checked_sub(&value) { - Some(b) => b, - None => Err("balance too low to send value")?, - }; - let to_balance = ctx.overlay.get_balance(dest); - if to_balance.is_zero() && value < ctx.config.existential_deposit { - Err("value too low to create account")? - } - - // Only ext_terminate is allowed to bring the sender below the existential deposit - let required_balance = match cause { - Terminate => 0.into(), - _ => ctx.config.existential_deposit + Err(Error::::OutOfGas)? + } + + // Only seal_terminate is allowed to bring the sender below the subsistence + // threshold or even existential deposit. + let existence_requirement = match (cause, origin) { + (Terminate, _) => ExistenceRequirement::AllowDeath, + (_, Contract) => { + ensure!( + T::Currency::total_balance(transactor).saturating_sub(value) >= + ctx.config.subsistence_threshold(), + Error::::BelowSubsistenceThreshold, + ); + ExistenceRequirement::KeepAlive + }, + (_, PlainAccount) => ExistenceRequirement::KeepAlive, }; - T::Currency::ensure_can_withdraw( - transactor, - value, - WithdrawReason::Transfer.into(), - new_from_balance.checked_sub(&required_balance) - .ok_or("brings sender below existential deposit")?, - )?; - - let new_to_balance = match to_balance.checked_add(&value) { - Some(b) => b, - None => Err("destination balance too high to receive value")?, - }; - - if transactor != dest { - ctx.overlay.set_balance(transactor, new_from_balance); - ctx.overlay.set_balance(dest, new_to_balance); - ctx.deferred.push(DeferredAction::DepositEvent { - event: RawEvent::Transfer(transactor.clone(), dest.clone(), value), - topics: Vec::new(), - }); - } + T::Currency::transfer(transactor, dest, value, existence_requirement) + .map_err(|_| Error::::TransferFailed)?; Ok(()) } +/// A context that is active within a call. +/// +/// This context has some invariants that must be held at all times. Specifically: +///`ctx` always points to a context of an alive contract. That implies that it has an existent +/// `self_trie_id`. +/// +/// Be advised that there are brief time spans where these invariants could be invalidated. +/// For example, when a contract requests self-termination the contract is removed eagerly. That +/// implies that the control won't be returned to the contract anymore, but there is still some code +/// on the path of the return from that call context. Therefore, care must be taken in these +/// situations. struct CallContext<'a, 'b: 'a, T: Trait + 'b, V: Vm + 'b, L: Loader> { ctx: &'a mut ExecutionContext<'b, T, V, L>, caller: T::AccountId, @@ -735,20 +648,32 @@ where type T = T; fn get_storage(&self, key: &StorageKey) -> Option> { - self.ctx.overlay.get_storage(&self.ctx.self_account, self.ctx.self_trie_id.as_ref(), key) + let trie_id = self.ctx.self_trie_id.as_ref().expect( + "`ctx.self_trie_id` points to an alive contract within the `CallContext`;\ + it cannot be `None`;\ + expect can't fail;\ + qed", + ); + storage::read_contract_storage(trie_id, key) } - fn set_storage(&mut self, key: StorageKey, value: Option>) -> Result<(), &'static str> { - if let Some(ref value) = value { - if self.max_value_size() < value.len() as u32 { - return Err("value size exceeds maximum"); - } + fn set_storage(&mut self, key: StorageKey, value: Option>) { + let trie_id = self.ctx.self_trie_id.as_ref().expect( + "`ctx.self_trie_id` points to an alive contract within the `CallContext`;\ + it cannot be `None`;\ + expect can't fail;\ + qed", + ); + if let Err(storage::ContractAbsentError) = + storage::write_contract_storage::(&self.ctx.self_account, trie_id, &key, value) + { + panic!( + "the contract must be in the alive state within the `CallContext`;\ + the contract cannot be absent in storage; + write_contract_storage cannot return `None`; + qed" + ); } - - self.ctx - .overlay - .set_storage(&self.ctx.self_account, key, value); - Ok(()) } fn instantiate( @@ -767,7 +692,15 @@ where value: BalanceOf, gas_meter: &mut GasMeter, ) -> Result<(), DispatchError> { - self.ctx.transfer(to.clone(), value, gas_meter) + transfer( + gas_meter, + TransferCause::Call, + TransactorKind::Contract, + &self.ctx.self_account.clone(), + &to, + value, + self.ctx, + ) } fn terminate( @@ -775,7 +708,31 @@ where beneficiary: &AccountIdOf, gas_meter: &mut GasMeter, ) -> Result<(), DispatchError> { - self.ctx.terminate(beneficiary, gas_meter) + let self_id = self.ctx.self_account.clone(); + let value = T::Currency::free_balance(&self_id); + if let Some(caller_ctx) = self.ctx.caller { + if caller_ctx.is_live(&self_id) { + return Err(DispatchError::Other( + "Cannot terminate a contract that is present on the call stack", + )); + } + } + transfer( + gas_meter, + TransferCause::Terminate, + TransactorKind::Contract, + &self_id, + beneficiary, + value, + self.ctx, + )?; + let self_trie_id = self.ctx.self_trie_id.as_ref().expect( + "this function is only invoked by in the context of a contract;\ + a contract has a trie id;\ + this can't be None; qed", + ); + storage::destroy_contract::(&self_id, self_trie_id); + Ok(()) } fn call( @@ -788,27 +745,40 @@ where self.ctx.call(to.clone(), value, gas_meter, input_data) } - fn note_dispatch_call(&mut self, call: CallOf) { - self.ctx.deferred.push(DeferredAction::DispatchRuntimeCall { - origin: self.ctx.self_account.clone(), - call, - }); - } - - fn note_restore_to( + fn restore_to( &mut self, dest: AccountIdOf, code_hash: CodeHash, rent_allowance: BalanceOf, delta: Vec, - ) { - self.ctx.deferred.push(DeferredAction::RestoreTo { - donor: self.ctx.self_account.clone(), - dest, - code_hash, + ) -> Result<(), &'static str> { + if let Some(caller_ctx) = self.ctx.caller { + if caller_ctx.is_live(&self.ctx.self_account) { + return Err( + "Cannot perform restoration of a contract that is present on the call stack", + ); + } + } + + let result = crate::rent::restore_to::( + self.ctx.self_account.clone(), + dest.clone(), + code_hash.clone(), rent_allowance, delta, - }); + ); + if let Ok(_) = result { + deposit_event::( + vec![], + RawEvent::Restored( + self.ctx.self_account.clone(), + dest, + code_hash, + rent_allowance, + ), + ); + } + result } fn address(&self) -> &T::AccountId { @@ -820,7 +790,7 @@ where } fn balance(&self) -> BalanceOf { - self.ctx.overlay.get_balance(&self.ctx.self_account) + T::Currency::free_balance(&self.ctx.self_account) } fn value_transferred(&self) -> BalanceOf { @@ -844,19 +814,26 @@ where } fn deposit_event(&mut self, topics: Vec, data: Vec) { - self.ctx.deferred.push(DeferredAction::DepositEvent { + deposit_event::( topics, - event: RawEvent::ContractExecution(self.ctx.self_account.clone(), data), - }); + RawEvent::ContractExecution(self.ctx.self_account.clone(), data) + ); } fn set_rent_allowance(&mut self, rent_allowance: BalanceOf) { - self.ctx.overlay.set_rent_allowance(&self.ctx.self_account, rent_allowance) + if let Err(storage::ContractAbsentError) = + storage::set_rent_allowance::(&self.ctx.self_account, rent_allowance) + { + panic!( + "`self_account` points to an alive contract within the `CallContext`; + set_rent_allowance cannot return `Err`; qed" + ); + } } fn rent_allowance(&self) -> BalanceOf { - self.ctx.overlay.get_rent_allowance(&self.ctx.self_account) - .unwrap_or(>::max_value()) // Must never be triggered actually + storage::rent_allowance::(&self.ctx.self_account) + .unwrap_or_else(|_| >::max_value()) // Must never be triggered actually } fn block_number(&self) -> T::BlockNumber { self.block_number } @@ -865,16 +842,19 @@ where self.ctx.config.max_value_size } - fn get_runtime_storage(&self, key: &[u8]) -> Option> { - unhashed::get_raw(&key) + fn get_weight_price(&self, weight: Weight) -> BalanceOf { + T::WeightPrice::convert(weight) } +} - fn get_weight_price(&self) -> BalanceOf { - use pallet_transaction_payment::Module as Payment; - use sp_runtime::SaturatedConversion; - let price = Payment::::weight_to_fee_with_adjustment::(1); - price.saturated_into() - } +fn deposit_event( + topics: Vec, + event: Event, +) { + >::deposit_event_indexed( + &*topics, + ::Event::from(event).into(), + ) } /// These tests exercise the executive layer. @@ -882,25 +862,22 @@ where /// In these tests the VM/loader are mocked. Instead of dealing with wasm bytecode they use simple closures. /// This allows you to tackle executive logic more thoroughly without writing a /// wasm VM code. -/// -/// Because it's the executive layer: -/// -/// - no gas meter setup and teardown logic. All balances are *AFTER* gas purchase. -/// - executive layer doesn't alter any storage! #[cfg(test)] mod tests { use super::{ - BalanceOf, ExecFeeToken, ExecutionContext, Ext, Loader, TransferFeeKind, TransferFeeToken, - Vm, ExecResult, RawEvent, DeferredAction, + BalanceOf, Event, ExecFeeToken, ExecResult, ExecutionContext, Ext, Loader, + RawEvent, TransferFeeKind, TransferFeeToken, Vm, ReturnFlags, ExecError, ErrorOrigin }; use crate::{ - account_db::AccountDb, gas::GasMeter, tests::{ExtBuilder, Test}, - exec::{ExecReturnValue, ExecError, STATUS_SUCCESS}, CodeHash, Config, + gas::GasMeter, tests::{ExtBuilder, Test, MetaEvent}, + exec::ExecReturnValue, CodeHash, Config, gas::Gas, + storage, Error }; - use std::{cell::RefCell, rc::Rc, collections::HashMap, marker::PhantomData}; - use assert_matches::assert_matches; + use crate::tests::test_utils::{place_contract, set_balance, get_balance}; use sp_runtime::DispatchError; + use assert_matches::assert_matches; + use std::{cell::RefCell, collections::HashMap, marker::PhantomData, rc::Rc}; const ALICE: u64 = 1; const BOB: u64 = 2; @@ -908,19 +885,14 @@ mod tests { const GAS_LIMIT: Gas = 10_000_000_000; - impl<'a, T, V, L> ExecutionContext<'a, T, V, L> - where T: crate::Trait - { - fn events(&self) -> Vec> { - self.deferred - .iter() - .filter(|action| match *action { - DeferredAction::DepositEvent { .. } => true, - _ => false, - }) - .cloned() - .collect() - } + fn events() -> Vec> { + >::events() + .into_iter() + .filter_map(|meta| match meta.event { + MetaEvent::contracts(contract_event) => Some(contract_event), + _ => None, + }) + .collect() } struct MockCtx<'a> { @@ -1007,7 +979,7 @@ mod tests { } fn exec_success() -> ExecResult { - Ok(ExecReturnValue { status: STATUS_SUCCESS, data: Vec::new() }) + Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() }) } #[test] @@ -1029,7 +1001,7 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, exec_ch).unwrap(); + place_contract(&BOB, exec_ch); assert_matches!( ctx.call(BOB, value, &mut gas_meter, data), @@ -1051,16 +1023,24 @@ mod tests { let loader = MockLoader::empty(); let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 0); + set_balance(&origin, 100); + set_balance(&dest, 0); let mut gas_meter = GasMeter::::new(GAS_LIMIT); - let result = ctx.call(dest, 0, &mut gas_meter, vec![]); + let result = super::transfer( + &mut gas_meter, + super::TransferCause::Call, + super::TransactorKind::PlainAccount, + &origin, + &dest, + 0, + &mut ctx, + ); assert_matches!(result, Ok(_)); let mut toks = gas_meter.tokens().iter(); - match_tokens!(toks, ExecFeeToken::Call,); + match_tokens!(toks, TransferFeeToken { kind: TransferFeeKind::Transfer },); }); // This test verifies that base fee for instantiation is taken. @@ -1072,11 +1052,11 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); + set_balance(&origin, 100); let mut gas_meter = GasMeter::::new(GAS_LIMIT); - let result = ctx.instantiate(1, &mut gas_meter, &code, vec![]); + let result = ctx.instantiate(cfg.subsistence_threshold(), &mut gas_meter, &code, vec![]); assert_matches!(result, Ok(_)); let mut toks = gas_meter.tokens().iter(); @@ -1097,41 +1077,45 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 0); + set_balance(&origin, 100); + set_balance(&dest, 0); - let output = ctx.call( - dest, + let mut gas_meter = GasMeter::::new(GAS_LIMIT); + + super::transfer( + &mut gas_meter, + super::TransferCause::Call, + super::TransactorKind::PlainAccount, + &origin, + &dest, 55, - &mut GasMeter::::new(GAS_LIMIT), - vec![], + &mut ctx, ).unwrap(); - assert!(output.is_success()); - assert_eq!(ctx.overlay.get_balance(&origin), 45); - assert_eq!(ctx.overlay.get_balance(&dest), 55); + assert_eq!(get_balance(&origin), 45); + assert_eq!(get_balance(&dest), 55); }); } #[test] fn changes_are_reverted_on_failing_call() { - // This test verifies that a contract is able to transfer - // some funds to another account. + // This test verifies that changes are reverted on a call which fails (or equally, returns + // a non-zero status code). let origin = ALICE; let dest = BOB; let vm = MockVm::new(); let mut loader = MockLoader::empty(); let return_ch = loader.insert( - |_| Ok(ExecReturnValue { status: 1, data: Vec::new() }) + |_| Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: Vec::new() }) ); ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 0); + place_contract(&BOB, return_ch); + set_balance(&origin, 100); + set_balance(&dest, 0); let output = ctx.call( dest, @@ -1141,8 +1125,8 @@ mod tests { ).unwrap(); assert!(!output.is_success()); - assert_eq!(ctx.overlay.get_balance(&origin), 100); - assert_eq!(ctx.overlay.get_balance(&dest), 0); + assert_eq!(get_balance(&origin), 100); + assert_eq!(get_balance(&dest), 0); }); } @@ -1159,18 +1143,25 @@ mod tests { let loader = MockLoader::empty(); let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 0); + set_balance(&origin, 100); + set_balance(&dest, 0); let mut gas_meter = GasMeter::::new(GAS_LIMIT); - let result = ctx.call(dest, 50, &mut gas_meter, vec![]); + let result = super::transfer( + &mut gas_meter, + super::TransferCause::Call, + super::TransactorKind::PlainAccount, + &origin, + &dest, + 50, + &mut ctx, + ); assert_matches!(result, Ok(_)); let mut toks = gas_meter.tokens().iter(); match_tokens!( toks, - ExecFeeToken::Call, TransferFeeToken { kind: TransferFeeKind::Transfer, }, @@ -1184,18 +1175,25 @@ mod tests { let loader = MockLoader::empty(); let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 15); + set_balance(&origin, 100); + set_balance(&dest, 15); let mut gas_meter = GasMeter::::new(GAS_LIMIT); - let result = ctx.call(dest, 50, &mut gas_meter, vec![]); + let result = super::transfer( + &mut gas_meter, + super::TransferCause::Call, + super::TransactorKind::PlainAccount, + &origin, + &dest, + 50, + &mut ctx, + ); assert_matches!(result, Ok(_)); let mut toks = gas_meter.tokens().iter(); match_tokens!( toks, - ExecFeeToken::Call, TransferFeeToken { kind: TransferFeeKind::Transfer, }, @@ -1212,8 +1210,8 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 100); - ctx.overlay.set_balance(&dest, 15); + set_balance(&origin, 100); + set_balance(&dest, 15); let mut gas_meter = GasMeter::::new(GAS_LIMIT); @@ -1244,24 +1242,24 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.set_balance(&origin, 0); + set_balance(&origin, 0); - let result = ctx.call( - dest, - 100, + let result = super::transfer( &mut GasMeter::::new(GAS_LIMIT), - vec![], + super::TransferCause::Call, + super::TransactorKind::PlainAccount, + &origin, + &dest, + 100, + &mut ctx, ); - assert_matches!( + assert_eq!( result, - Err(ExecError { - reason: DispatchError::Other("balance too low to send value"), - buffer: _, - }) + Err(Error::::TransferFailed.into()) ); - assert_eq!(ctx.overlay.get_balance(&origin), 0); - assert_eq!(ctx.overlay.get_balance(&dest), 0); + assert_eq!(get_balance(&origin), 0); + assert_eq!(get_balance(&dest), 0); }); } @@ -1275,13 +1273,13 @@ mod tests { let vm = MockVm::new(); let mut loader = MockLoader::empty(); let return_ch = loader.insert( - |_| Ok(ExecReturnValue { status: STATUS_SUCCESS, data: vec![1, 2, 3, 4] }) + |_| Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: vec![1, 2, 3, 4] }) ); ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); + place_contract(&BOB, return_ch); let result = ctx.call( dest, @@ -1306,13 +1304,13 @@ mod tests { let vm = MockVm::new(); let mut loader = MockLoader::empty(); let return_ch = loader.insert( - |_| Ok(ExecReturnValue { status: 1, data: vec![1, 2, 3, 4] }) + |_| Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: vec![1, 2, 3, 4] }) ); ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, return_ch).unwrap(); + place_contract(&BOB, return_ch); let result = ctx.call( dest, @@ -1340,7 +1338,7 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, input_data_ch).unwrap(); + place_contract(&BOB, input_data_ch); let result = ctx.call( BOB, @@ -1366,10 +1364,10 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 100); + set_balance(&ALICE, 100); let result = ctx.instantiate( - 1, + cfg.subsistence_threshold(), &mut GasMeter::::new(GAS_LIMIT), &input_data_ch, vec![1, 2, 3, 4], @@ -1395,12 +1393,9 @@ mod tests { if !*reached_bottom { // We are first time here, it means we just reached bottom. // Verify that we've got proper error and set `reached_bottom`. - assert_matches!( + assert_eq!( r, - Err(ExecError { - reason: DispatchError::Other("reached maximum depth, cannot make a call"), - buffer: _, - }) + Err(Error::::MaxCallDepthReached.into()) ); *reached_bottom = true; } else { @@ -1414,8 +1409,8 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&BOB, 1); - ctx.overlay.instantiate_contract(&BOB, recurse_ch).unwrap(); + set_balance(&BOB, 1); + place_contract(&BOB, recurse_ch); let result = ctx.call( BOB, @@ -1460,8 +1455,8 @@ mod tests { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&dest, bob_ch).unwrap(); - ctx.overlay.instantiate_contract(&CHARLIE, charlie_ch).unwrap(); + place_contract(&dest, bob_ch); + place_contract(&CHARLIE, charlie_ch); let result = ctx.call( dest, @@ -1501,8 +1496,8 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.instantiate_contract(&BOB, bob_ch).unwrap(); - ctx.overlay.instantiate_contract(&CHARLIE, charlie_ch).unwrap(); + place_contract(&BOB, bob_ch); + place_contract(&CHARLIE, charlie_ch); let result = ctx.call( BOB, @@ -1544,13 +1539,13 @@ mod tests { let mut loader = MockLoader::empty(); let dummy_ch = loader.insert( - |_| Ok(ExecReturnValue { status: STATUS_SUCCESS, data: vec![80, 65, 83, 83] }) + |_| Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: vec![80, 65, 83, 83] }) ); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); + set_balance(&ALICE, 1000); let instantiated_contract_address = assert_matches!( ctx.instantiate( @@ -1564,16 +1559,9 @@ mod tests { // Check that the newly created account has the expected code hash and // there are instantiation event. - assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); - assert_eq!(&ctx.events(), &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, instantiated_contract_address, 100), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Instantiated(ALICE, instantiated_contract_address), - topics: Vec::new(), - } + assert_eq!(storage::code_hash::(&instantiated_contract_address).unwrap(), dummy_ch); + assert_eq!(&events(), &[ + RawEvent::Instantiated(ALICE, instantiated_contract_address) ]); }); } @@ -1584,13 +1572,13 @@ mod tests { let mut loader = MockLoader::empty(); let dummy_ch = loader.insert( - |_| Ok(ExecReturnValue { status: 1, data: vec![70, 65, 73, 76] }) + |_| Ok(ExecReturnValue { flags: ReturnFlags::REVERT, data: vec![70, 65, 73, 76] }) ); ExtBuilder::default().existential_deposit(15).build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); + set_balance(&ALICE, 1000); let instantiated_contract_address = assert_matches!( ctx.instantiate( @@ -1603,8 +1591,8 @@ mod tests { ); // Check that the account has not been created. - assert!(ctx.overlay.get_code_hash(&instantiated_contract_address).is_none()); - assert!(ctx.events().is_empty()); + assert!(storage::code_hash::(&instantiated_contract_address).is_err()); + assert!(events().is_empty()); }); } @@ -1622,7 +1610,7 @@ mod tests { // Instantiate a contract and save it's address in `instantiated_contract_address`. let (address, output) = ctx.ext.instantiate( &dummy_ch, - 15u64, + Config::::subsistence_threshold_uncached(), ctx.gas_meter, vec![] ).unwrap(); @@ -1635,9 +1623,9 @@ mod tests { ExtBuilder::default().existential_deposit(15).build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - ctx.overlay.set_balance(&BOB, 100); - ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); + set_balance(&ALICE, 1000); + set_balance(&BOB, 100); + place_contract(&BOB, instantiator_ch); assert_matches!( ctx.call(BOB, 20, &mut GasMeter::::new(GAS_LIMIT), vec![]), @@ -1648,20 +1636,9 @@ mod tests { // Check that the newly created account has the expected code hash and // there are instantiation event. - assert_eq!(ctx.overlay.get_code_hash(&instantiated_contract_address).unwrap(), dummy_ch); - assert_eq!(&ctx.events(), &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, BOB, 20), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Transfer(BOB, instantiated_contract_address, 15), - topics: Vec::new(), - }, - DeferredAction::DepositEvent { - event: RawEvent::Instantiated(BOB, instantiated_contract_address), - topics: Vec::new(), - }, + assert_eq!(storage::code_hash::(&instantiated_contract_address).unwrap(), dummy_ch); + assert_eq!(&events(), &[ + RawEvent::Instantiated(BOB, instantiated_contract_address) ]); }); } @@ -1672,7 +1649,7 @@ mod tests { let mut loader = MockLoader::empty(); let dummy_ch = loader.insert( - |_| Err(ExecError { reason: "It's a trap!".into(), buffer: Vec::new() }) + |_| Err("It's a trap!".into()) ); let instantiator_ch = loader.insert({ let dummy_ch = dummy_ch.clone(); @@ -1685,7 +1662,10 @@ mod tests { ctx.gas_meter, vec![] ), - Err(ExecError { reason: DispatchError::Other("It's a trap!"), buffer: _ }) + Err(ExecError { + error: DispatchError::Other("It's a trap!"), + origin: ErrorOrigin::Callee, + }) ); exec_success() @@ -1695,9 +1675,9 @@ mod tests { ExtBuilder::default().existential_deposit(15).build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); - ctx.overlay.set_balance(&BOB, 100); - ctx.overlay.instantiate_contract(&BOB, instantiator_ch).unwrap(); + set_balance(&ALICE, 1000); + set_balance(&BOB, 100); + place_contract(&BOB, instantiator_ch); assert_matches!( ctx.call(BOB, 20, &mut GasMeter::::new(GAS_LIMIT), vec![]), @@ -1706,12 +1686,7 @@ mod tests { // The contract wasn't instantiated so we don't expect to see an instantiation // event here. - assert_eq!(&ctx.events(), &[ - DeferredAction::DepositEvent { - event: RawEvent::Transfer(ALICE, BOB, 20), - topics: Vec::new(), - }, - ]); + assert_eq!(&events(), &[]); }); } @@ -1732,23 +1707,20 @@ mod tests { .execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - ctx.overlay.set_balance(&ALICE, 1000); + set_balance(&ALICE, 1000); - assert_matches!( + assert_eq!( ctx.instantiate( 100, &mut GasMeter::::new(GAS_LIMIT), &terminate_ch, vec![], ), - Err(ExecError { - reason: DispatchError::Other("insufficient remaining balance"), - buffer - }) if buffer == Vec::::new() + Err(Error::::NewContractNotFunded.into()) ); assert_eq!( - &ctx.events(), + &events(), &[] ); }); @@ -1768,11 +1740,10 @@ mod tests { ExtBuilder::default().build().execute_with(|| { let cfg = Config::preload(); let mut ctx = ExecutionContext::top_level(ALICE, &cfg, &vm, &loader); - - ctx.overlay.set_balance(&ALICE, 100); + set_balance(&ALICE, 100); let result = ctx.instantiate( - 1, + cfg.subsistence_threshold(), &mut GasMeter::::new(GAS_LIMIT), &rent_allowance_ch, vec![], diff --git a/frame/contracts/src/gas.rs b/frame/contracts/src/gas.rs index 38f231c008f8b635c10d67102ecd0c2bf3e703c4..decaf11b796f7d35688a820281d6f61edfe456fd 100644 --- a/frame/contracts/src/gas.rs +++ b/frame/contracts/src/gas.rs @@ -14,11 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -use crate::Trait; +use crate::{Trait, exec::ExecError}; use sp_std::marker::PhantomData; use sp_runtime::traits::Zero; use frame_support::dispatch::{ - DispatchError, DispatchResultWithPostInfo, PostDispatchInfo, DispatchErrorWithPostInfo, + DispatchResultWithPostInfo, PostDispatchInfo, DispatchErrorWithPostInfo, }; #[cfg(test)] @@ -178,8 +178,8 @@ impl GasMeter { } } - /// Returns how much gas left from the initial budget. - fn gas_spent(&self) -> Gas { + /// Returns how much gas was used. + pub fn gas_spent(&self) -> Gas { self.gas_limit - self.gas_left } @@ -189,16 +189,18 @@ impl GasMeter { } /// Turn this GasMeter into a DispatchResult that contains the actually used gas. - pub fn into_dispatch_result(self, result: Result) -> DispatchResultWithPostInfo where - E: Into, + pub fn into_dispatch_result(self, result: Result) -> DispatchResultWithPostInfo + where + E: Into, { let post_info = PostDispatchInfo { actual_weight: Some(self.gas_spent()), + pays_fee: Default::default(), }; result .map(|_| post_info) - .map_err(|e| DispatchErrorWithPostInfo { post_info, error: e.into() }) + .map_err(|e| DispatchErrorWithPostInfo { post_info, error: e.into().error }) } #[cfg(test)] diff --git a/frame/contracts/src/lib.rs b/frame/contracts/src/lib.rs index df53cf0a0eadd3f0bc9c30520a35a01591808653..138c8e995a0a24eb6b4ec8c1812ef202e18e6252 100644 --- a/frame/contracts/src/lib.rs +++ b/frame/contracts/src/lib.rs @@ -81,45 +81,42 @@ #[macro_use] mod gas; - -mod account_db; +mod storage; mod exec; mod wasm; mod rent; +mod benchmarking; #[cfg(test)] mod tests; use crate::exec::ExecutionContext; -use crate::account_db::{AccountDb, DirectAccountDb}; use crate::wasm::{WasmLoader, WasmVm}; pub use crate::gas::{Gas, GasMeter}; -pub use crate::exec::{ExecResult, ExecReturnValue, ExecError, StatusCode}; +pub use crate::exec::{ExecResult, ExecReturnValue}; +pub use crate::wasm::ReturnCode as RuntimeReturnCode; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; use sp_core::crypto::UncheckedFrom; use sp_std::{prelude::*, marker::PhantomData, fmt::Debug}; use codec::{Codec, Encode, Decode}; -use sp_io::hashing::blake2_256; use sp_runtime::{ traits::{ - Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, + Hash, StaticLookup, Zero, MaybeSerializeDeserialize, Member, Convert, Saturating, }, RuntimeDebug, }; -use frame_support::dispatch::{ - PostDispatchInfo, DispatchResult, Dispatchable, DispatchResultWithPostInfo -}; use frame_support::{ - Parameter, decl_module, decl_event, decl_storage, decl_error, - parameter_types, IsSubType, storage::child::{self, ChildInfo}, + decl_module, decl_event, decl_storage, decl_error, ensure, + parameter_types, storage::child::ChildInfo, + dispatch::{DispatchResult, DispatchResultWithPostInfo}, + traits::{OnUnbalanced, Currency, Get, Time, Randomness}, }; -use frame_support::traits::{OnUnbalanced, Currency, Get, Time, Randomness}; -use frame_support::weights::{FunctionOf, DispatchClass, Weight, GetDispatchInfo, Pays}; -use frame_system::{self as system, ensure_signed, RawOrigin, ensure_root}; +use frame_system::{ensure_signed, ensure_root}; use pallet_contracts_primitives::{RentProjection, ContractAccessError}; +use frame_support::weights::Weight; pub type CodeHash = ::Hash; pub type TrieId = Vec; @@ -129,11 +126,6 @@ pub trait ContractAddressFor { fn contract_address_for(code_hash: &CodeHash, data: &[u8], origin: &AccountId) -> AccountId; } -/// A function that returns the fee for dispatching a `Call`. -pub trait ComputeDispatchFee { - fn compute_dispatch_fee(call: &Call) -> Balance; -} - /// Information for managing an account and its sub trie abstraction. /// This is the required info to cache for an account #[derive(Encode, Decode, RuntimeDebug)] @@ -203,8 +195,15 @@ pub type AliveContractInfo = pub struct RawAliveContractInfo { /// Unique ID for the subtree encoded as a bytes vector. pub trie_id: TrieId, - /// The size of stored value in octet. + /// The total number of bytes used by this contract. + /// + /// It is a sum of each key-value pair stored by this contract. pub storage_size: u32, + /// The number of key-value pairs that have values of zero length. + /// The condition `empty_pair_count ≤ total_pair_count` always holds. + pub empty_pair_count: u32, + /// The total number of key-value pairs in storage of this contract. + pub total_pair_count: u32, /// The code associated with a given account. pub code_hash: CodeHash, /// Pay rent at most up to this value. @@ -248,6 +247,12 @@ where } } +impl From> for ContractInfo { + fn from(alive_info: AliveContractInfo) -> Self { + Self::Alive(alive_info) + } +} + /// Get a trie id (trie id must be unique and collision resistant depending upon its context). /// Note that it is different than encode because trie id should be collision resistant /// (being a proper unique identifier). @@ -284,9 +289,10 @@ where } } -pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; pub type NegativeImbalanceOf = - <::Currency as Currency<::AccountId>>::NegativeImbalance; + <::Currency as Currency<::AccountId>>::NegativeImbalance; parameter_types! { /// A reasonable default value for [`Trait::SignedClaimedHandicap`]. @@ -307,15 +313,12 @@ parameter_types! { pub const DefaultMaxValueSize: u32 = 16_384; } -pub trait Trait: frame_system::Trait + pallet_transaction_payment::Trait { +pub trait Trait: frame_system::Trait { type Time: Time; type Randomness: Randomness; - /// The outer call dispatch type. - type Call: - Parameter + - Dispatchable::Origin> + - IsSubType, Self> + GetDispatchInfo; + /// The currency in which fees are paid and contract balances are held. + type Currency: Currency; /// The overarching event type. type Event: From> + Into<::Event>; @@ -338,8 +341,11 @@ pub trait Trait: frame_system::Trait + pallet_transaction_payment::Trait { /// The minimum amount required to generate a tombstone. type TombstoneDeposit: Get>; - /// Size of a contract at the time of instantiation. This is a simple way to ensure - /// that empty contracts eventually gets deleted. + /// A size offset for an contract. A just created account with untouched storage will have that + /// much of storage from the perspective of the state rent. + /// + /// This is a simple way to ensure that contracts with empty storage eventually get deleted by + /// making them pay rent. This creates an incentive to remove them early in order to save rent. type StorageSizeOffset: Get; /// Price of a byte of storage per one block interval. Should be greater than 0. @@ -363,6 +369,10 @@ pub trait Trait: frame_system::Trait + pallet_transaction_payment::Trait { /// The maximum size of a storage value in bytes. type MaxValueSize: Get; + + /// Used to answer contracts's queries regarding the current weight price. This is **not** + /// used to calculate the actual fee and is only for informational purposes. + type WeightPrice: Convert>; } /// Simple contract address determiner. @@ -402,7 +412,39 @@ decl_error! { /// Tombstones don't match. InvalidTombstone, /// An origin TrieId written in the current block. - InvalidContractOrigin + InvalidContractOrigin, + /// The executed contract exhausted its gas limit. + OutOfGas, + /// The output buffer supplied to a contract API call was too small. + OutputBufferTooSmall, + /// Performing the requested transfer would have brought the contract below + /// the subsistence threshold. No transfer is allowed to do this in order to allow + /// for a tombstone to be created. Use `seal_terminate` to remove a contract without + /// leaving a tombstone behind. + BelowSubsistenceThreshold, + /// The newly created contract is below the subsistence threshold after executing + /// its contructor. No contracts are allowed to exist below that threshold. + NewContractNotFunded, + /// Performing the requested transfer failed for a reason originating in the + /// chosen currency implementation of the runtime. Most probably the balance is + /// too low or locks are placed on it. + TransferFailed, + /// Performing a call was denied because the calling depth reached the limit + /// of what is specified in the schedule. + MaxCallDepthReached, + /// The contract that was called is either no contract at all (a plain account) + /// or is a tombstone. + NotCallable, + /// The code supplied to `put_code` exceeds the limit specified in the current schedule. + CodeTooLarge, + /// No code could be found at the supplied code hash. + CodeNotFound, + /// A buffer outside of sandbox memory was passed to a contract API function. + OutOfBounds, + /// Input passed to a contract API function failed to decode as expected type. + DecodingFailed, + /// Contract trapped during execution. + ContractTrapped, } } @@ -420,8 +462,12 @@ decl_module! { /// The minimum amount required to generate a tombstone. const TombstoneDeposit: BalanceOf = T::TombstoneDeposit::get(); - /// Size of a contract at the time of instantiation. This is a simple way to ensure that - /// empty contracts eventually gets deleted. + /// A size offset for an contract. A just created account with untouched storage will have that + /// much of storage from the perspective of the state rent. + /// + /// This is a simple way to ensure that contracts with empty storage eventually get deleted + /// by making them pay rent. This creates an incentive to remove them early in order to save + /// rent. const StorageSizeOffset: u32 = T::StorageSizeOffset::get(); /// Price of a byte of storage per one block interval. Should be greater than 0. @@ -467,17 +513,14 @@ decl_module! { /// Stores the given binary Wasm code into the chain's storage and returns its `codehash`. /// You can instantiate contracts only with stored code. - #[weight = FunctionOf( - |args: (&Vec,)| Module::::calc_code_put_costs(args.0), - DispatchClass::Normal, - Pays::Yes - )] + #[weight = Module::::calc_code_put_costs(&code)] pub fn put_code( origin, code: Vec ) -> DispatchResult { ensure_signed(origin)?; let schedule = >::current_schedule(); + ensure!(code.len() as u32 <= schedule.max_code_size, Error::::CodeTooLarge); let result = wasm::save_code::(code, &schedule); if let Ok(code_hash) = result { Self::deposit_event(RawEvent::CodeStored(code_hash)); @@ -492,11 +535,7 @@ decl_module! { /// * If the account is a regular account, any value will be transferred. /// * If no account exists and the call value is not less than `existential_deposit`, /// a regular account will be created and any value will be transferred. - #[weight = FunctionOf( - |args: (&::Source, &BalanceOf, &Weight, &Vec)| *args.2, - DispatchClass::Normal, - Pays::Yes - )] + #[weight = *gas_limit] pub fn call( origin, dest: ::Source, @@ -511,7 +550,7 @@ decl_module! { let result = Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { ctx.call(dest, value, gas_meter, data) }); - gas_meter.into_dispatch_result(result.map_err(|e| e.reason)) + gas_meter.into_dispatch_result(result) } /// Instantiates a new contract from the `codehash` generated by `put_code`, optionally transferring some balance. @@ -524,11 +563,7 @@ decl_module! { /// after the execution is saved as the `code` of the account. That code will be invoked /// upon any call received by this account. /// - The contract is initialized. - #[weight = FunctionOf( - |args: (&BalanceOf, &Weight, &CodeHash, &Vec)| *args.1, - DispatchClass::Normal, - Pays::Yes - )] + #[weight = *gas_limit] pub fn instantiate( origin, #[compact] endowment: BalanceOf, @@ -543,7 +578,7 @@ decl_module! { ctx.instantiate(endowment, gas_meter, &code_hash, data) .map(|(_address, output)| output) }); - gas_meter.into_dispatch_result(result.map_err(|e| e.reason)) + gas_meter.into_dispatch_result(result) } /// Allows block producers to claim a small reward for evicting a contract. If a block producer @@ -587,17 +622,22 @@ impl Module { /// /// This function is similar to `Self::call`, but doesn't perform any address lookups and better /// suitable for calling directly from Rust. + /// + /// It returns the exection result and the amount of used weight. pub fn bare_call( origin: T::AccountId, dest: T::AccountId, value: BalanceOf, gas_limit: Gas, input_data: Vec, - ) -> ExecResult { + ) -> (ExecResult, Gas) { let mut gas_meter = GasMeter::new(gas_limit); - Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { - ctx.call(dest, value, gas_meter, input_data) - }) + ( + Self::execute_wasm(origin, &mut gas_meter, |ctx, gas_meter| { + ctx.call(dest, value, gas_meter, input_data) + }), + gas_meter.gas_spent(), + ) } /// Query storage of a specified contract under a specified key. @@ -605,17 +645,12 @@ impl Module { address: T::AccountId, key: [u8; 32], ) -> sp_std::result::Result>, ContractAccessError> { - let contract_info = >::get(&address) + let contract_info = ContractInfoOf::::get(&address) .ok_or(ContractAccessError::DoesntExist)? .get_alive() .ok_or(ContractAccessError::IsTombstone)?; - let maybe_value = AccountDb::::get_storage( - &DirectAccountDb, - &address, - Some(&contract_info.trie_id), - &key, - ); + let maybe_value = storage::read_contract_storage(&contract_info.trie_id, &key); Ok(maybe_value) } @@ -634,147 +669,13 @@ impl Module { fn execute_wasm( origin: T::AccountId, gas_meter: &mut GasMeter, - func: impl FnOnce(&mut ExecutionContext, &mut GasMeter) -> ExecResult + func: impl FnOnce(&mut ExecutionContext, &mut GasMeter) -> ExecResult, ) -> ExecResult { let cfg = Config::preload(); let vm = WasmVm::new(&cfg.schedule); let loader = WasmLoader::new(&cfg.schedule); - let mut ctx = ExecutionContext::top_level(origin.clone(), &cfg, &vm, &loader); - - let result = func(&mut ctx, gas_meter); - - if result.as_ref().map(|output| output.is_success()).unwrap_or(false) { - // Commit all changes that made it thus far into the persistent storage. - DirectAccountDb.commit(ctx.overlay.into_change_set()); - } - - // Execute deferred actions. - ctx.deferred.into_iter().for_each(|deferred| { - use self::exec::DeferredAction::*; - match deferred { - DepositEvent { - topics, - event, - } => >::deposit_event_indexed( - &*topics, - ::Event::from(event).into(), - ), - DispatchRuntimeCall { - origin: who, - call, - } => { - let info = call.get_dispatch_info(); - let result = call.dispatch(RawOrigin::Signed(who.clone()).into()); - let post_info = match result { - Ok(post_info) => post_info, - Err(err) => err.post_info, - }; - gas_meter.refund(post_info.calc_unspent(&info)); - Self::deposit_event(RawEvent::Dispatched(who, result.is_ok())); - } - RestoreTo { - donor, - dest, - code_hash, - rent_allowance, - delta, - } => { - let result = Self::restore_to( - donor.clone(), dest.clone(), code_hash.clone(), rent_allowance.clone(), delta - ); - Self::deposit_event( - RawEvent::Restored(donor, dest, code_hash, rent_allowance, result.is_ok()) - ); - } - } - }); - - result - } - - fn restore_to( - origin: T::AccountId, - dest: T::AccountId, - code_hash: CodeHash, - rent_allowance: BalanceOf, - delta: Vec - ) -> DispatchResult { - let mut origin_contract = >::get(&origin) - .and_then(|c| c.get_alive()) - .ok_or(Error::::InvalidSourceContract)?; - - let current_block = >::block_number(); - - if origin_contract.last_write == Some(current_block) { - Err(Error::::InvalidContractOrigin)? - } - - let dest_tombstone = >::get(&dest) - .and_then(|c| c.get_tombstone()) - .ok_or(Error::::InvalidDestinationContract)?; - - let last_write = if !delta.is_empty() { - Some(current_block) - } else { - origin_contract.last_write - }; - - let key_values_taken = delta.iter() - .filter_map(|key| { - child::get_raw( - &origin_contract.child_trie_info(), - &blake2_256(key), - ).map(|value| { - child::kill( - &origin_contract.child_trie_info(), - &blake2_256(key), - ); - - (key, value) - }) - }) - .collect::>(); - - let tombstone = >::new( - // This operation is cheap enough because last_write (delta not included) - // is not this block as it has been checked earlier. - &child::root( - &origin_contract.child_trie_info(), - )[..], - code_hash, - ); - - if tombstone != dest_tombstone { - for (key, value) in key_values_taken { - child::put_raw( - &origin_contract.child_trie_info(), - &blake2_256(key), - &value, - ); - } - - return Err(Error::::InvalidTombstone.into()); - } - - origin_contract.storage_size -= key_values_taken.iter() - .map(|(_, value)| value.len() as u32) - .sum::(); - - >::remove(&origin); - >::insert(&dest, ContractInfo::Alive(RawAliveContractInfo { - trie_id: origin_contract.trie_id, - storage_size: origin_contract.storage_size, - code_hash, - rent_allowance, - deduct_block: current_block, - last_write, - })); - - let origin_free_balance = T::Currency::free_balance(&origin); - T::Currency::make_free_balance_be(&origin, >::zero()); - T::Currency::deposit_creating(&dest, origin_free_balance); - - Ok(()) + let mut ctx = ExecutionContext::top_level(origin, &cfg, &vm, &loader); + func(&mut ctx, gas_meter) } } @@ -785,42 +686,38 @@ decl_event! { ::AccountId, ::Hash { - /// Transfer happened `from` to `to` with given `value` as part of a `call` or `instantiate`. - Transfer(AccountId, AccountId, Balance), - - /// Contract deployed by address at the specified address. + /// Contract deployed by address at the specified address. [owner, contract] Instantiated(AccountId, AccountId), /// Contract has been evicted and is now in tombstone state. - /// + /// [contract, tombstone] + /// /// # Params /// /// - `contract`: `AccountId`: The account ID of the evicted contract. /// - `tombstone`: `bool`: True if the evicted contract left behind a tombstone. Evicted(AccountId, bool), - /// Restoration for a contract has been initiated. - /// + /// Restoration for a contract has been successful. + /// [donor, dest, code_hash, rent_allowance] + /// /// # Params /// /// - `donor`: `AccountId`: Account ID of the restoring contract /// - `dest`: `AccountId`: Account ID of the restored contract /// - `code_hash`: `Hash`: Code hash of the restored contract /// - `rent_allowance: `Balance`: Rent allowance of the restored contract - /// - `success`: `bool`: True if the restoration was successful - Restored(AccountId, AccountId, Hash, Balance, bool), + Restored(AccountId, AccountId, Hash, Balance), /// Code with the specified hash has been stored. + /// [code_hash] CodeStored(Hash), - /// Triggered when the current schedule is updated. + /// Triggered when the current [schedule] is updated. ScheduleUpdated(u32), - /// A call was dispatched from the given account. The bool signals whether it was - /// successful execution or not. - Dispatched(AccountId, bool), - /// An event deposited upon execution of a contract from the account. + /// [account, data] ContractExecution(AccountId, Vec), } } @@ -836,6 +733,8 @@ decl_storage! { /// The subtrie counter. pub AccountCounter: u64 = 0; /// The code associated with a given account. + /// + /// TWOX-NOTE: SAFE since `AccountId` is a secure hash. pub ContractInfoOf: map hasher(twox_64_concat) T::AccountId => Option>; } } @@ -862,6 +761,25 @@ impl Config { max_value_size: T::MaxValueSize::get(), } } + + /// Subsistence threshold is the extension of the minimum balance (aka existential deposit) by the + /// tombstone deposit, required for leaving a tombstone. + /// + /// Rent or any contract initiated balance transfer mechanism cannot make the balance lower + /// than the subsistence threshold in order to guarantee that a tombstone is created. + /// + /// The only way to completely kill a contract without a tombstone is calling `seal_terminate`. + pub fn subsistence_threshold(&self) -> BalanceOf { + self.existential_deposit.saturating_add(self.tombstone_deposit) + } + + /// The same as `subsistence_threshold` but without the need for a preloaded instance. + /// + /// This is for cases where this value is needed in rent calculation rather than + /// during contract execution. + pub fn subsistence_threshold_uncached() -> BalanceOf { + T::Currency::minimum_balance().saturating_add(T::TombstoneDeposit::get()) + } } /// Definition of the cost schedule and other parameterizations for wasm vm. @@ -928,12 +846,16 @@ pub struct Schedule { /// Maximum allowed size of a declared table. pub max_table_size: u32, - /// Whether the `ext_println` function is allowed to be used contracts. + /// Whether the `seal_println` function is allowed to be used contracts. /// MUST only be enabled for `dev` chains, NOT for production chains pub enable_println: bool, /// The maximum length of a subject used for PRNG generation. pub max_subject_len: u32, + + /// The maximum length of a contract code in bytes. This limit applies to the uninstrumented + // and pristine form of the code as supplied to `put_code`. + pub max_code_size: u32, } // 500 (2 instructions per nano second on 2GHZ) * 1000x slowdown through wasmi @@ -965,6 +887,7 @@ impl Default for Schedule { max_table_size: 16 * 1024, enable_println: false, max_subject_len: 32, + max_code_size: 512 * 1024, } } } diff --git a/frame/contracts/src/rent.rs b/frame/contracts/src/rent.rs index 1aa52fff314356e4758947e128139e92a4961c73..908faca9a6c0c77ec4a6f5219e0153c83c4ee0f1 100644 --- a/frame/contracts/src/rent.rs +++ b/frame/contracts/src/rent.rs @@ -18,8 +18,10 @@ use crate::{ AliveContractInfo, BalanceOf, ContractInfo, ContractInfoOf, Module, RawEvent, - TombstoneContractInfo, Trait, + TombstoneContractInfo, Trait, CodeHash, Config }; +use sp_std::prelude::*; +use sp_io::hashing::blake2_256; use frame_support::storage::child; use frame_support::traits::{Currency, ExistenceRequirement, Get, OnUnbalanced, WithdrawReason}; use frame_support::StorageMap; @@ -85,27 +87,24 @@ enum Verdict { /// This function accounts for the storage rent deposit. I.e. if the contract possesses enough funds /// then the fee can drop to zero. fn compute_fee_per_block( - balance: &BalanceOf, + free_balance: &BalanceOf, contract: &AliveContractInfo, ) -> BalanceOf { - let free_storage = balance + let free_storage = free_balance .checked_div(&T::RentDepositOffset::get()) .unwrap_or_else(Zero::zero); - let effective_storage_size = - >::from(contract.storage_size).saturating_sub(free_storage); + // For now, we treat every empty KV pair as if it was one byte long. + let empty_pairs_equivalent = contract.empty_pair_count; + + let effective_storage_size = >::from( + contract.storage_size + T::StorageSizeOffset::get() + empty_pairs_equivalent, + ) + .saturating_sub(free_storage); effective_storage_size .checked_mul(&T::RentByteFee::get()) - .unwrap_or(>::max_value()) -} - -/// Subsistence threshold is the extension of the minimum balance (aka existential deposit) by the -/// tombstone deposit, required for leaving a tombstone. -/// -/// Rent mechanism cannot make the balance lower than subsistence threshold. -fn subsistence_threshold() -> BalanceOf { - T::Currency::minimum_balance() + T::TombstoneDeposit::get() + .unwrap_or_else(|| >::max_value()) } /// Returns amount of funds available to consume by rent mechanism. @@ -113,17 +112,22 @@ fn subsistence_threshold() -> BalanceOf { /// Rent mechanism cannot consume more than `rent_allowance` set by the contract and it cannot make /// the balance lower than [`subsistence_threshold`]. /// -/// In case the balance is below the subsistence threshold, this function returns `None`. +/// In case the toal_balance is below the subsistence threshold, this function returns `None`. fn rent_budget( - balance: &BalanceOf, + total_balance: &BalanceOf, + free_balance: &BalanceOf, contract: &AliveContractInfo, ) -> Option> { - let subsistence_threshold = subsistence_threshold::(); - if *balance < subsistence_threshold { + let subsistence_threshold = Config::::subsistence_threshold_uncached(); + // Reserved balance contributes towards the subsistence threshold to stay consistent + // with the existential deposit where the reserved balance is also counted. + if *total_balance < subsistence_threshold { return None; } - let rent_allowed_to_charge = *balance - subsistence_threshold; + // However, reserved balance cannot be charged so we need to use the free balance + // to calculate the actual budget (which can be 0). + let rent_allowed_to_charge = free_balance.saturating_sub(subsistence_threshold); Some(>::min( contract.rent_allowance, rent_allowed_to_charge, @@ -151,21 +155,22 @@ fn consider_case( return Verdict::Exempt; } - let balance = T::Currency::free_balance(account); + let total_balance = T::Currency::total_balance(account); + let free_balance = T::Currency::free_balance(account); // An amount of funds to charge per block for storage taken up by the contract. - let fee_per_block = compute_fee_per_block::(&balance, contract); + let fee_per_block = compute_fee_per_block::(&free_balance, contract); if fee_per_block.is_zero() { // The rent deposit offset reduced the fee to 0. This means that the contract // gets the rent for free. return Verdict::Exempt; } - let rent_budget = match rent_budget::(&balance, contract) { + let rent_budget = match rent_budget::(&total_balance, &free_balance, contract) { Some(rent_budget) => rent_budget, None => { - // The contract's balance is already below subsistence threshold. That indicates that - // the contract cannot afford to leave a tombstone. + // The contract's total balance is already below subsistence threshold. That + // indicates that the contract cannot afford to leave a tombstone. // // So cleanly wipe the contract. return Verdict::Kill; @@ -174,7 +179,7 @@ fn consider_case( let dues = fee_per_block .checked_mul(&blocks_passed.saturated_into::().into()) - .unwrap_or(>::max_value()); + .unwrap_or_else(|| >::max_value()); let insufficient_rent = rent_budget < dues; // If the rent payment cannot be withdrawn due to locks on the account balance, then evict the @@ -188,7 +193,7 @@ fn consider_case( account, dues_limited, WithdrawReason::Fee.into(), - balance.saturating_sub(dues_limited), + free_balance.saturating_sub(dues_limited), ) .is_ok(); @@ -362,14 +367,15 @@ pub fn compute_rent_projection( }; // Compute how much would the fee per block be with the *updated* balance. - let balance = T::Currency::free_balance(account); - let fee_per_block = compute_fee_per_block::(&balance, &alive_contract_info); + let total_balance = T::Currency::total_balance(account); + let free_balance = T::Currency::free_balance(account); + let fee_per_block = compute_fee_per_block::(&free_balance, &alive_contract_info); if fee_per_block.is_zero() { return Ok(RentProjection::NoEviction); } // Then compute how much the contract will sustain under these circumstances. - let rent_budget = rent_budget::(&balance, &alive_contract_info).expect( + let rent_budget = rent_budget::(&total_balance, &free_balance, &alive_contract_info).expect( "the contract exists and in the alive state; the updated balance must be greater than subsistence deposit; this function doesn't return `None`; @@ -391,3 +397,90 @@ pub fn compute_rent_projection( current_block_number + blocks_left, )) } + +/// Restores the destination account using the origin as prototype. +/// +/// The restoration will be performed iff: +/// - origin exists and is alive, +/// - the origin's storage is not written in the current block +/// - the restored account has tombstone +/// - the tombstone matches the hash of the origin storage root, and code hash. +/// +/// Upon succesful restoration, `origin` will be destroyed, all its funds are transferred to +/// the restored account. The restored account will inherit the last write block and its last +/// deduct block will be set to the current block. +pub fn restore_to( + origin: T::AccountId, + dest: T::AccountId, + code_hash: CodeHash, + rent_allowance: BalanceOf, + delta: Vec, +) -> Result<(), &'static str> { + let mut origin_contract = >::get(&origin) + .and_then(|c| c.get_alive()) + .ok_or("Cannot restore from inexisting or tombstone contract")?; + + let child_trie_info = origin_contract.child_trie_info(); + + let current_block = >::block_number(); + + if origin_contract.last_write == Some(current_block) { + return Err("Origin TrieId written in the current block"); + } + + let dest_tombstone = >::get(&dest) + .and_then(|c| c.get_tombstone()) + .ok_or("Cannot restore to inexisting or alive contract")?; + + let last_write = if !delta.is_empty() { + Some(current_block) + } else { + origin_contract.last_write + }; + + let key_values_taken = delta.iter() + .filter_map(|key| { + child::get_raw(&child_trie_info, &blake2_256(key)).map(|value| { + child::kill(&child_trie_info, &blake2_256(key)); + (key, value) + }) + }) + .collect::>(); + + let tombstone = >::new( + // This operation is cheap enough because last_write (delta not included) + // is not this block as it has been checked earlier. + &child::root(&child_trie_info)[..], + code_hash, + ); + + if tombstone != dest_tombstone { + for (key, value) in key_values_taken { + child::put_raw(&child_trie_info, &blake2_256(key), &value); + } + + return Err("Tombstones don't match"); + } + + origin_contract.storage_size -= key_values_taken.iter() + .map(|(_, value)| value.len() as u32) + .sum::(); + + >::remove(&origin); + >::insert(&dest, ContractInfo::Alive(AliveContractInfo:: { + trie_id: origin_contract.trie_id, + storage_size: origin_contract.storage_size, + empty_pair_count: origin_contract.empty_pair_count, + total_pair_count: origin_contract.total_pair_count, + code_hash, + rent_allowance, + deduct_block: current_block, + last_write, + })); + + let origin_free_balance = T::Currency::free_balance(&origin); + T::Currency::make_free_balance_be(&origin, >::zero()); + T::Currency::deposit_creating(&dest, origin_free_balance); + + Ok(()) +} diff --git a/frame/contracts/src/storage.rs b/frame/contracts/src/storage.rs new file mode 100644 index 0000000000000000000000000000000000000000..3740952778fd33d85b53f3e2bca8a6f5bef64881 --- /dev/null +++ b/frame/contracts/src/storage.rs @@ -0,0 +1,196 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! This module contains routines for accessing and altering a contract related state. + +use crate::{ + exec::{AccountIdOf, StorageKey}, + AliveContractInfo, BalanceOf, CodeHash, ContractInfo, ContractInfoOf, Trait, TrieId, +}; +use sp_std::prelude::*; +use sp_io::hashing::blake2_256; +use sp_runtime::traits::Bounded; +use frame_support::{storage::child, StorageMap}; + +/// An error that means that the account requested either doesn't exist or represents a tombstone +/// account. +#[cfg_attr(test, derive(PartialEq, Eq, Debug))] +pub struct ContractAbsentError; + +/// Reads a storage kv pair of a contract. +/// +/// The read is performed from the `trie_id` only. The `address` is not necessary. If the contract +/// doesn't store under the given `key` `None` is returned. +pub fn read_contract_storage(trie_id: &TrieId, key: &StorageKey) -> Option> { + child::get_raw(&crate::child_trie_info(&trie_id), &blake2_256(key)) +} + +/// Update a storage entry into a contract's kv storage. +/// +/// If the `opt_new_value` is `None` then the kv pair is removed. +/// +/// This function also updates the bookkeeping info such as: number of total non-empty pairs a +/// contract owns, the last block the storage was written to, etc. That's why, in contrast to +/// `read_contract_storage`, this function also requires the `account` ID. +/// +/// If the contract specified by the id `account` doesn't exist `Err` is returned.` +pub fn write_contract_storage( + account: &AccountIdOf, + trie_id: &TrieId, + key: &StorageKey, + opt_new_value: Option>, +) -> Result<(), ContractAbsentError> { + let mut new_info = match >::get(account) { + Some(ContractInfo::Alive(alive)) => alive, + None | Some(ContractInfo::Tombstone(_)) => return Err(ContractAbsentError), + }; + + let hashed_key = blake2_256(key); + let child_trie_info = &crate::child_trie_info(&trie_id); + + // In order to correctly update the book keeping we need to fetch the previous + // value of the key-value pair. + // + // It might be a bit more clean if we had an API that supported getting the size + // of the value without going through the loading of it. But at the moment of + // writing, there is no such API. + // + // That's not a show stopper in any case, since the performance cost is + // dominated by the trie traversal anyway. + let opt_prev_value = child::get_raw(&child_trie_info, &hashed_key); + + // Update the total number of KV pairs and the number of empty pairs. + match (&opt_prev_value, &opt_new_value) { + (Some(prev_value), None) => { + new_info.total_pair_count -= 1; + if prev_value.is_empty() { + new_info.empty_pair_count -= 1; + } + }, + (None, Some(new_value)) => { + new_info.total_pair_count += 1; + if new_value.is_empty() { + new_info.empty_pair_count += 1; + } + }, + (Some(prev_value), Some(new_value)) => { + if prev_value.is_empty() { + new_info.empty_pair_count -= 1; + } + if new_value.is_empty() { + new_info.empty_pair_count += 1; + } + } + (None, None) => {} + } + + // Update the total storage size. + let prev_value_len = opt_prev_value + .as_ref() + .map(|old_value| old_value.len() as u32) + .unwrap_or(0); + let new_value_len = opt_new_value + .as_ref() + .map(|new_value| new_value.len() as u32) + .unwrap_or(0); + new_info.storage_size = new_info + .storage_size + .saturating_add(new_value_len) + .saturating_sub(prev_value_len); + + new_info.last_write = Some(>::block_number()); + >::insert(&account, ContractInfo::Alive(new_info)); + + // Finally, perform the change on the storage. + match opt_new_value { + Some(new_value) => child::put_raw(&child_trie_info, &hashed_key, &new_value[..]), + None => child::kill(&child_trie_info, &hashed_key), + } + + Ok(()) +} + +/// Returns the rent allowance set for the contract give by the account id. +pub fn rent_allowance( + account: &AccountIdOf, +) -> Result, ContractAbsentError> { + >::get(account) + .and_then(|i| i.as_alive().map(|i| i.rent_allowance)) + .ok_or(ContractAbsentError) +} + +/// Set the rent allowance for the contract given by the account id. +/// +/// Returns `Err` if the contract doesn't exist or is a tombstone. +pub fn set_rent_allowance( + account: &AccountIdOf, + rent_allowance: BalanceOf, +) -> Result<(), ContractAbsentError> { + >::mutate(account, |maybe_contract_info| match maybe_contract_info { + Some(ContractInfo::Alive(ref mut alive_info)) => { + alive_info.rent_allowance = rent_allowance; + Ok(()) + } + _ => Err(ContractAbsentError), + }) +} + +/// Returns the code hash of the contract specified by `account` ID. +#[cfg(test)] +pub fn code_hash(account: &AccountIdOf) -> Result, ContractAbsentError> { + >::get(account) + .and_then(|i| i.as_alive().map(|i| i.code_hash)) + .ok_or(ContractAbsentError) +} + +/// Creates a new contract descriptor in the storage with the given code hash at the given address. +/// +/// Returns `Err` if there is already a contract (or a tombstone) exists at the given address. +pub fn place_contract( + account: &AccountIdOf, + trie_id: TrieId, + ch: CodeHash, +) -> Result<(), &'static str> { + >::mutate(account, |maybe_contract_info| { + if maybe_contract_info.is_some() { + return Err("Alive contract or tombstone already exists"); + } + + *maybe_contract_info = Some( + AliveContractInfo:: { + code_hash: ch, + storage_size: 0, + trie_id, + deduct_block: >::block_number(), + rent_allowance: >::max_value(), + empty_pair_count: 0, + total_pair_count: 0, + last_write: None, + } + .into(), + ); + + Ok(()) + }) +} + +/// Removes the contract and all the storage associated with it. +/// +/// This function doesn't affect the account. +pub fn destroy_contract(address: &AccountIdOf, trie_id: &TrieId) { + >::remove(address); + child::kill_storage(&crate::child_trie_info(&trie_id)); +} diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 218a5c99372d40d78ba6c68a099d89faf3f79200..bd1242ff6701a6ed8b9bb854756f86db36971e34 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -14,33 +14,27 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -// TODO: #1417 Add more integration tests -// also remove the #![allow(unused)] below. - -#![allow(unused)] - use crate::{ - BalanceOf, ComputeDispatchFee, ContractAddressFor, ContractInfo, ContractInfoOf, GenesisConfig, - Module, RawAliveContractInfo, RawEvent, Trait, TrieId, TrieIdFromParentCounter, Schedule, - TrieIdGenerator, account_db::{AccountDb, DirectAccountDb, OverlayAccountDb}, - gas::Gas, + BalanceOf, ContractAddressFor, ContractInfo, ContractInfoOf, GenesisConfig, Module, + RawAliveContractInfo, RawEvent, Trait, TrieId, Schedule, TrieIdGenerator, gas::Gas, + Error, Config, RuntimeReturnCode, }; use assert_matches::assert_matches; use hex_literal::*; -use codec::{Decode, Encode, KeyedVec}; +use codec::Encode; use sp_runtime::{ - Perbill, BuildStorage, transaction_validity::{InvalidTransaction, ValidTransaction}, - traits::{BlakeTwo256, Hash, IdentityLookup, SignedExtension, Convert}, - testing::{Digest, DigestItem, Header, UintAuthorityId, H256}, + Perbill, + traits::{BlakeTwo256, Hash, IdentityLookup, Convert}, + testing::{Header, H256}, }; use frame_support::{ - assert_ok, assert_err, assert_err_ignore_postinfo, impl_outer_dispatch, impl_outer_event, - impl_outer_origin, parameter_types, - storage::child, StorageMap, StorageValue, traits::{Currency, Get}, - weights::{DispatchInfo, DispatchClass, Weight, PostDispatchInfo, Pays}, + assert_ok, assert_err_ignore_postinfo, impl_outer_dispatch, impl_outer_event, + impl_outer_origin, parameter_types, StorageMap, StorageValue, + traits::{Currency, Get, ReservableCurrency}, + weights::{Weight, PostDispatchInfo}, + dispatch::DispatchErrorWithPostInfo, }; -use std::{cell::RefCell, sync::atomic::{AtomicUsize, Ordering}}; -use sp_core::storage::well_known_keys; +use std::cell::RefCell; use frame_system::{self as system, EventRecord, Phase}; mod contracts { @@ -48,7 +42,7 @@ mod contracts { // needs to give a name for the current crate. // This hack is required for `impl_outer_event!`. pub use super::super::*; - use frame_support::impl_outer_event; + pub use frame_support::impl_outer_event; } use pallet_balances as balances; @@ -61,7 +55,7 @@ impl_outer_event! { } } impl_outer_origin! { - pub enum Origin for Test where system = frame_system { } + pub enum Origin for Test where system = frame_system { } } impl_outer_dispatch! { pub enum Call for Test where origin: Origin { @@ -70,6 +64,41 @@ impl_outer_dispatch! { } } +#[macro_use] +pub mod test_utils { + use super::{Test, Balances}; + use crate::{ContractInfoOf, TrieIdGenerator, CodeHash}; + use crate::storage::{write_contract_storage, read_contract_storage}; + use crate::exec::StorageKey; + use frame_support::{StorageMap, traits::Currency}; + + pub fn set_storage(addr: &u64, key: &StorageKey, value: Option>) { + let contract_info = >::get(&addr).unwrap().get_alive().unwrap(); + write_contract_storage::(&1, &contract_info.trie_id, key, value).unwrap(); + } + pub fn get_storage(addr: &u64, key: &StorageKey) -> Option> { + let contract_info = >::get(&addr).unwrap().get_alive().unwrap(); + read_contract_storage(&contract_info.trie_id, key) + } + pub fn place_contract(address: &u64, code_hash: CodeHash) { + let trie_id = ::TrieIdGenerator::trie_id(address); + crate::storage::place_contract::(&address, trie_id, code_hash).unwrap() + } + pub fn set_balance(who: &u64, amount: u64) { + let imbalance = Balances::deposit_creating(who, amount); + drop(imbalance); + } + pub fn get_balance(who: &u64) -> u64 { + Balances::free_balance(who) + } + macro_rules! assert_return_code { + ( $x:expr , $y:expr $(,)? ) => {{ + use sp_std::convert::TryInto; + assert_eq!(u32::from_le_bytes($x.data[..].try_into().unwrap()), $y as u32); + }} + } +} + thread_local! { static EXISTENTIAL_DEPOSIT: RefCell = RefCell::new(0); } @@ -88,11 +117,12 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; type Hash = H256; - type Call = (); + type Call = Call; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; @@ -103,6 +133,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -110,6 +141,7 @@ impl frame_system::Trait for Test { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl pallet_balances::Trait for Test { type Balance = u64; @@ -117,6 +149,7 @@ impl pallet_balances::Trait for Test { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { pub const MinimumPeriod: u64 = 1; @@ -125,6 +158,7 @@ impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } parameter_types! { pub const SignedClaimHandicap: u64 = 2; @@ -147,18 +181,10 @@ impl Convert> for Test { } } -impl pallet_transaction_payment::Trait for Test { - type Currency = Balances; - type OnTransactionPayment = (); - type TransactionByteFee = TransactionByteFee; - type WeightToFee = Test; - type FeeMultiplierUpdate = (); -} - impl Trait for Test { type Time = Timestamp; type Randomness = Randomness; - type Call = Call; + type Currency = Balances; type DetermineContractAddress = DummyContractAddressFor; type Event = MetaEvent; type TrieIdGenerator = DummyTrieIdGenerator; @@ -171,6 +197,7 @@ impl Trait for Test { type SurchargeReward = SurchargeReward; type MaxDepth = MaxDepth; type MaxValueSize = MaxValueSize; + type WeightPrice = Self; } type Balances = pallet_balances::Module; @@ -189,8 +216,6 @@ impl ContractAddressFor for DummyContractAddressFor { pub struct DummyTrieIdGenerator; impl TrieIdGenerator for DummyTrieIdGenerator { fn trie_id(account_id: &u64) -> TrieId { - use sp_core::storage::well_known_keys; - let new_seed = super::AccountCounter::mutate(|v| { *v = v.wrapping_add(1); *v @@ -203,13 +228,6 @@ impl TrieIdGenerator for DummyTrieIdGenerator { } } -pub struct DummyComputeDispatchFee; -impl ComputeDispatchFee for DummyComputeDispatchFee { - fn compute_dispatch_fee(call: &Call) -> u64 { - 69 - } -} - const ALICE: u64 = 1; const BOB: u64 = 2; const CHARLIE: u64 = 3; @@ -253,28 +271,39 @@ impl ExtBuilder { } } -/// Generate Wasm binary and code hash from wabt source. -fn compile_module(wabt_module: &str) - -> Result<(Vec, ::Output), wabt::Error> - where T: frame_system::Trait +/// Load a given wasm module represented by a .wat file and returns a wasm binary contents along +/// with it's hash. +/// +/// The fixture files are located under the `fixtures/` directory. +fn compile_module( + fixture_name: &str, +) -> wat::Result<(Vec, ::Output)> +where + T: frame_system::Trait, { - let wasm = wabt::wat2wasm(wabt_module)?; - let code_hash = T::Hashing::hash(&wasm); - Ok((wasm, code_hash)) + let fixture_path = ["fixtures/", fixture_name, ".wat"].concat(); + let wasm_binary = wat::parse_file(fixture_path)?; + let code_hash = T::Hashing::hash(&wasm_binary); + Ok((wasm_binary, code_hash)) } -// Perform a simple transfer to a non-existent account. +// Perform a call to a plain account. +// The actual transfer fails because we can only call contracts. // Then we check that only the base costs are returned as actual costs. #[test] -fn returns_base_call_cost() { +fn calling_plain_account_fails() { ExtBuilder::default().build().execute_with(|| { - Balances::deposit_creating(&ALICE, 100_000_000); + let _ = Balances::deposit_creating(&ALICE, 100_000_000); assert_eq!( Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, Vec::new()), - Ok( - PostDispatchInfo { - actual_weight: Some(67500000), + Err( + DispatchErrorWithPostInfo { + error: Error::::NotCallable.into(), + post_info: PostDispatchInfo { + actual_weight: Some(67500000), + pays_fee: Default::default(), + }, } ) ); @@ -283,6 +312,8 @@ fn returns_base_call_cost() { #[test] fn account_removal_does_not_remove_storage() { + use self::test_utils::{set_storage, get_storage}; + ExtBuilder::default().existential_deposit(100).build().execute_with(|| { let trie_id1 = ::TrieIdGenerator::trie_id(&1); let trie_id2 = ::TrieIdGenerator::trie_id(&2); @@ -291,63 +322,63 @@ fn account_removal_does_not_remove_storage() { // Set up two accounts with free balance above the existential threshold. { - Balances::deposit_creating(&1, 110); - ContractInfoOf::::insert(1, &ContractInfo::Alive(RawAliveContractInfo { + let alice_contract_info = ContractInfo::Alive(RawAliveContractInfo { trie_id: trie_id1.clone(), - storage_size: ::StorageSizeOffset::get(), + storage_size: 0, + empty_pair_count: 0, + total_pair_count: 0, deduct_block: System::block_number(), code_hash: H256::repeat_byte(1), rent_allowance: 40, last_write: None, - })); - - let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); - overlay.set_storage(&1, key1.clone(), Some(b"1".to_vec())); - overlay.set_storage(&1, key2.clone(), Some(b"2".to_vec())); - DirectAccountDb.commit(overlay.into_change_set()); + }); + let _ = Balances::deposit_creating(&ALICE, 110); + ContractInfoOf::::insert(ALICE, &alice_contract_info); + set_storage(&ALICE, &key1, Some(b"1".to_vec())); + set_storage(&ALICE, &key2, Some(b"2".to_vec())); - Balances::deposit_creating(&2, 110); - ContractInfoOf::::insert(2, &ContractInfo::Alive(RawAliveContractInfo { + let bob_contract_info = ContractInfo::Alive(RawAliveContractInfo { trie_id: trie_id2.clone(), - storage_size: ::StorageSizeOffset::get(), + storage_size: 0, + empty_pair_count: 0, + total_pair_count: 0, deduct_block: System::block_number(), code_hash: H256::repeat_byte(2), rent_allowance: 40, last_write: None, - })); - - let mut overlay = OverlayAccountDb::::new(&DirectAccountDb); - overlay.set_storage(&2, key1.clone(), Some(b"3".to_vec())); - overlay.set_storage(&2, key2.clone(), Some(b"4".to_vec())); - DirectAccountDb.commit(overlay.into_change_set()); + }); + let _ = Balances::deposit_creating(&BOB, 110); + ContractInfoOf::::insert(BOB, &bob_contract_info); + set_storage(&BOB, &key1, Some(b"3".to_vec())); + set_storage(&BOB, &key2, Some(b"4".to_vec())); } - // Transfer funds from account 1 of such amount that after this transfer - // the balance of account 1 will be below the existential threshold. + // Transfer funds from ALICE account of such amount that after this transfer + // the balance of the ALICE account will be below the existential threshold. // // This does not remove the contract storage as we are not notified about a // account removal. This cannot happen in reality because a contract can only - // remove itself by `ext_terminate`. There is no external event that can remove + // remove itself by `seal_terminate`. There is no external event that can remove // the account appart from that. - assert_ok!(Balances::transfer(Origin::signed(1), 2, 20)); + assert_ok!(Balances::transfer(Origin::signed(ALICE), BOB, 20)); // Verify that no entries are removed. { assert_eq!( - >::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key1), + get_storage(&ALICE, key1), Some(b"1".to_vec()) ); assert_eq!( - >::get_storage(&DirectAccountDb, &1, Some(&trie_id1), key2), + get_storage(&ALICE, key2), Some(b"2".to_vec()) ); assert_eq!( - >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key1), + get_storage(&BOB, key1), Some(b"3".to_vec()) ); assert_eq!( - >::get_storage(&DirectAccountDb, &2, Some(&trie_id2), key2), + get_storage(&BOB, key2), Some(b"4".to_vec()) ); } @@ -356,302 +387,87 @@ fn account_removal_does_not_remove_storage() { #[test] fn instantiate_and_call_and_deposit_event() { - let (wasm, code_hash) = compile_module::(&load_wasm("return_from_start_fn.wat")) - .unwrap(); - - ExtBuilder::default().existential_deposit(100).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); - - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Check at the end to get hash on error easily - let creation = Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - vec![], - ); - - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances( - pallet_balances::RawEvent::Endowed(BOB, 100) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::ContractExecution(BOB, vec![1, 2, 3, 4])), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - } - ]); - - assert_ok!(creation); - assert!(ContractInfoOf::::contains_key(BOB)); - }); -} - -#[test] -fn dispatch_call() { - // This test can fail due to the encoding changes. In case it becomes too annoying - // let's rewrite so as we use this module controlled call or we serialize it in runtime. - let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer(CHARLIE, 50))); - assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - - let (wasm, code_hash) = compile_module::(&load_wasm("dispatch_call.wat")) - .unwrap(); - - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); - - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Let's keep this assert even though it's redundant. If you ever need to update the - // wasm source this test will fail and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ]); - - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, // newly created account - 0, - GAS_LIMIT, - vec![], - )); - - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances( - pallet_balances::RawEvent::Endowed(BOB, 100) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - }, - - // Dispatching the call. - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(CHARLIE)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances( - pallet_balances::RawEvent::Endowed(CHARLIE, 50) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances( - pallet_balances::RawEvent::Transfer(BOB, CHARLIE, 50) - ), - topics: vec![], - }, - - // Event emitted as a result of dispatch. - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Dispatched(BOB, true)), - topics: vec![], - } - ]); - }); -} - -#[test] -fn dispatch_call_not_dispatched_after_top_level_transaction_failure() { - // This test can fail due to the encoding changes. In case it becomes too annoying - // let's rewrite so as we use this module controlled call or we serialize it in runtime. - let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer(CHARLIE, 50))); - assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - - let (wasm, code_hash) = compile_module::(&load_wasm("dispatch_call_then_trap.wat")) - .unwrap(); - - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); - - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + let (wasm, code_hash) = compile_module::("return_from_start_fn").unwrap(); - // Let's keep this assert even though it's redundant. If you ever need to update the - // wasm source this test will fail and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ]); + ExtBuilder::default() + .existential_deposit(100) + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + let subsistence = super::Config::::subsistence_threshold_uncached(); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, - code_hash.into(), - vec![], - )); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - // Call the newly instantiated contract. The contract is expected to dispatch a call - // and then trap. - assert_err_ignore_postinfo!( - Contracts::call( + // Check at the end to get hash on error easily + let creation = Contracts::instantiate( Origin::signed(ALICE), - BOB, // newly created account - 0, + subsistence, GAS_LIMIT, + code_hash.into(), vec![], - ), - "contract trapped during execution" - ); - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances( - pallet_balances::RawEvent::Endowed(BOB, 100) - ), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Transfer(ALICE, BOB, 100)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), - topics: vec![], - }, - // ABSENCE of events which would be caused by dispatched Balances::transfer call - ]); - }); + ); + + pretty_assertions::assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::system(frame_system::RawEvent::NewAccount(BOB)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::balances( + pallet_balances::RawEvent::Endowed(BOB, subsistence) + ), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::balances( + pallet_balances::RawEvent::Transfer(ALICE, BOB, subsistence) + ), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::contracts(RawEvent::ContractExecution(BOB, vec![1, 2, 3, 4])), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::contracts(RawEvent::Instantiated(ALICE, BOB)), + topics: vec![], + } + ]); + + assert_ok!(creation); + assert!(ContractInfoOf::::contains_key(BOB)); + }); } #[test] fn run_out_of_gas() { - let (wasm, code_hash) = compile_module::(&load_wasm("run_out_of_gas.wat")) - .unwrap(); + let (wasm, code_hash) = compile_module::("run_out_of_gas").unwrap(); ExtBuilder::default() .existential_deposit(50) .build() .execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); + let _ = Balances::deposit_creating(&ALICE, 1_000_000); assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); @@ -673,7 +489,7 @@ fn run_out_of_gas() { 67_500_000, vec![], ), - "ran out of gas during contract execution" + Error::::OutOfGas, ); }); } @@ -695,60 +511,157 @@ fn test_set_rent_code_and_hash() { let encoded = Encode::encode(&Call::Balances(pallet_balances::Call::transfer(CHARLIE, 50))); assert_eq!(&encoded[..], &hex!("00000300000000000000C8")[..]); - let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); + let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - // If you ever need to update the wasm source this test will fail - // and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), - topics: vec![], - }, - ]); - }); + // If you ever need to update the wasm source this test will fail + // and will show you the actual hash. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::contracts(RawEvent::CodeStored(code_hash.into())), + topics: vec![], + }, + ]); + }); } #[test] fn storage_size() { - let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); + let (wasm, code_hash) = compile_module::("set_rent").unwrap(); // Storage size - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); - - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::set_storage_4_byte())); - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4 + 4); - - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::remove_storage_4_byte())); - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.storage_size, ::StorageSizeOffset::get() + 4); - }); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 30_000, + GAS_LIMIT, + code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + let bob_contract = ContractInfoOf::::get(BOB) + .unwrap() + .get_alive() + .unwrap(); + assert_eq!( + bob_contract.storage_size, + 4 + ); + assert_eq!( + bob_contract.total_pair_count, + 1, + ); + assert_eq!( + bob_contract.empty_pair_count, + 0, + ); + + assert_ok!(Contracts::call( + Origin::signed(ALICE), + BOB, + 0, + GAS_LIMIT, + call::set_storage_4_byte() + )); + let bob_contract = ContractInfoOf::::get(BOB) + .unwrap() + .get_alive() + .unwrap(); + assert_eq!( + bob_contract.storage_size, + 4 + 4 + ); + assert_eq!( + bob_contract.total_pair_count, + 2, + ); + assert_eq!( + bob_contract.empty_pair_count, + 0, + ); + + assert_ok!(Contracts::call( + Origin::signed(ALICE), + BOB, + 0, + GAS_LIMIT, + call::remove_storage_4_byte() + )); + let bob_contract = ContractInfoOf::::get(BOB) + .unwrap() + .get_alive() + .unwrap(); + assert_eq!( + bob_contract.storage_size, + 4 + ); + assert_eq!( + bob_contract.total_pair_count, + 1, + ); + assert_eq!( + bob_contract.empty_pair_count, + 0, + ); + }); +} + +#[test] +fn empty_kv_pairs() { + let (wasm, code_hash) = compile_module::("set_empty_storage").unwrap(); + + ExtBuilder::default() + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 30_000, + GAS_LIMIT, + code_hash.into(), + vec![], + )); + let bob_contract = ContractInfoOf::::get(BOB) + .unwrap() + .get_alive() + .unwrap(); + + assert_eq!( + bob_contract.storage_size, + 0, + ); + assert_eq!( + bob_contract.total_pair_count, + 1, + ); + assert_eq!( + bob_contract.empty_pair_count, + 1, + ); + }); } fn initialize_block(number: u64) { @@ -763,75 +676,78 @@ fn initialize_block(number: u64) { #[test] fn deduct_blocks() { - let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); + let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000); - - // Advance 4 blocks - initialize_block(5); - - // Trigger rent through call - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); - - // Check result - let rent = (8 + 4 - 3) // storage size = size_offset + deploy_set_storage - deposit_offset - * 4 // rent byte price - * 4; // blocks to rent - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent); - assert_eq!(bob_contract.deduct_block, 5); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent); - - // Advance 7 blocks more - initialize_block(12); - - // Trigger rent through call - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); - - // Check result - let rent_2 = (8 + 4 - 2) // storage size = size_offset + deploy_set_storage - deposit_offset - * 4 // rent byte price - * 7; // blocks to rent - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); - assert_eq!(bob_contract.deduct_block, 12); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); - - // Second call on same block should have no effect on rent - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); - - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); - assert_eq!(bob_contract.deduct_block, 12); - assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); - }); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 30_000, + GAS_LIMIT, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + // Check creation + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000); + + // Advance 4 blocks + initialize_block(5); + + // Trigger rent through call + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); + + // Check result + let rent = (8 + 4 - 3) // storage size = size_offset + deploy_set_storage - deposit_offset + * 4 // rent byte price + * 4; // blocks to rent + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent); + assert_eq!(bob_contract.deduct_block, 5); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent); + + // Advance 7 blocks more + initialize_block(12); + + // Trigger rent through call + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); + + // Check result + let rent_2 = (8 + 4 - 2) // storage size = size_offset + deploy_set_storage - deposit_offset + * 4 // rent byte price + * 7; // blocks to rent + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); + assert_eq!(bob_contract.deduct_block, 12); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); + + // Second call on same block should have no effect on rent + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); + + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); + assert_eq!(bob_contract.deduct_block, 12); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); + }); } #[test] fn call_contract_removals() { removals(|| { // Call on already-removed account might fail, and this is fine. - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()); + let _ = Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()); true }); } #[test] fn inherent_claim_surcharge_contract_removals() { - removals(|| Contracts::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok()); + removals(|| Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok()); } #[test] @@ -842,10 +758,10 @@ fn signed_claim_surcharge_contract_removals() { #[test] fn claim_surcharge_malus() { // Test surcharge malus for inherent - claim_surcharge(4, || Contracts::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), true); - claim_surcharge(3, || Contracts::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), true); - claim_surcharge(2, || Contracts::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), true); - claim_surcharge(1, || Contracts::claim_surcharge(Origin::NONE, BOB, Some(ALICE)).is_ok(), false); + claim_surcharge(4, || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), true); + claim_surcharge(3, || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), true); + claim_surcharge(2, || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), true); + claim_surcharge(1, || Contracts::claim_surcharge(Origin::none(), BOB, Some(ALICE)).is_ok(), false); // Test surcharge malus for signed claim_surcharge(4, || Contracts::claim_surcharge(Origin::signed(ALICE), BOB, None).is_ok(), true); @@ -857,226 +773,284 @@ fn claim_surcharge_malus() { /// Claim surcharge with the given trigger_call at the given blocks. /// If `removes` is true then assert that the contract is a tombstone. fn claim_surcharge(blocks: u64, trigger_call: impl Fn() -> bool, removes: bool) { - let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); + let (wasm, code_hash) = compile_module::("set_rent").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 100, + GAS_LIMIT, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); - // Advance blocks - initialize_block(blocks); + // Advance blocks + initialize_block(blocks); - // Trigger rent through call - assert!(trigger_call()); + // Trigger rent through call + assert!(trigger_call()); - if removes { - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - } else { - assert!(ContractInfoOf::::get(BOB).unwrap().get_alive().is_some()); - } - }); + if removes { + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + } else { + assert!(ContractInfoOf::::get(BOB).unwrap().get_alive().is_some()); + } + }); } /// Test for all kind of removals for the given trigger: /// * if balance is reached and balance > subsistence threshold /// * if allowance is exceeded /// * if balance is reached and balance < subsistence threshold +/// * this case cannot be triggered by a contract: we check whether a tombstone is left fn removals(trigger_call: impl Fn() -> bool) { - let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); + let (wasm, code_hash) = compile_module::("set_rent").unwrap(); // Balance reached and superior to subsistence threshold - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - let subsistence_threshold = 50 /*existential_deposit*/ + 16 /*tombstone_deposit*/; - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(BOB), 100); - - // Advance blocks - initialize_block(10); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(BOB), subsistence_threshold); - - // Advance blocks - initialize_block(20); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(BOB), subsistence_threshold); - }); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 100, + GAS_LIMIT, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + let subsistence_threshold = 50 /*existential_deposit*/ + 16 /*tombstone_deposit*/; + + // Trigger rent must have no effect + assert!(trigger_call()); + assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); + assert_eq!(Balances::free_balance(BOB), 100); + + // Advance blocks + initialize_block(10); + + // Trigger rent through call + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + assert_eq!(Balances::free_balance(BOB), subsistence_threshold); + + // Advance blocks + initialize_block(20); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + assert_eq!(Balances::free_balance(BOB), subsistence_threshold); + }); // Allowance exceeded - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 1_000, - GAS_LIMIT, code_hash.into(), - ::Balance::from(100u32).encode() // rent allowance - )); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 100); - assert_eq!(Balances::free_balance(BOB), 1_000); - - // Advance blocks - initialize_block(10); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - // Balance should be initial balance - initial rent_allowance - assert_eq!(Balances::free_balance(BOB), 900); - - // Advance blocks - initialize_block(20); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(Balances::free_balance(BOB), 900); - }); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 1_000, + GAS_LIMIT, + code_hash.into(), + ::Balance::from(100u32).encode() // rent allowance + )); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert_eq!( + ContractInfoOf::::get(BOB) + .unwrap() + .get_alive() + .unwrap() + .rent_allowance, + 100 + ); + assert_eq!(Balances::free_balance(BOB), 1_000); + + // Advance blocks + initialize_block(10); + + // Trigger rent through call + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB) + .unwrap() + .get_tombstone() + .is_some()); + // Balance should be initial balance - initial rent_allowance + assert_eq!(Balances::free_balance(BOB), 900); + + // Advance blocks + initialize_block(20); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert!(ContractInfoOf::::get(BOB) + .unwrap() + .get_tombstone() + .is_some()); + assert_eq!(Balances::free_balance(BOB), 900); + }); // Balance reached and inferior to subsistence threshold - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 50+Balances::minimum_balance(), - GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(BOB), 50 + Balances::minimum_balance()); - - // Transfer funds - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::transfer())); - assert_eq!(ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap().rent_allowance, 1_000); - assert_eq!(Balances::free_balance(BOB), Balances::minimum_balance()); - - // Advance blocks - initialize_block(10); - - // Trigger rent through call - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).is_none()); - assert_eq!(Balances::free_balance(BOB), Balances::minimum_balance()); - - // Advance blocks - initialize_block(20); - - // Trigger rent must have no effect - assert!(trigger_call()); - assert!(ContractInfoOf::::get(BOB).is_none()); - assert_eq!(Balances::free_balance(BOB), Balances::minimum_balance()); - }); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + let subsistence_threshold = + Balances::minimum_balance() + ::TombstoneDeposit::get(); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 50 + subsistence_threshold, + GAS_LIMIT, + code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert_eq!( + ContractInfoOf::::get(BOB) + .unwrap() + .get_alive() + .unwrap() + .rent_allowance, + 1_000 + ); + assert_eq!( + Balances::free_balance(BOB), + 50 + subsistence_threshold, + ); + + // Transfer funds + assert_ok!(Contracts::call( + Origin::signed(ALICE), + BOB, + 0, + GAS_LIMIT, + call::transfer() + )); + assert_eq!( + ContractInfoOf::::get(BOB) + .unwrap() + .get_alive() + .unwrap() + .rent_allowance, + 1_000 + ); + assert_eq!(Balances::free_balance(BOB), subsistence_threshold); + + // Advance blocks + initialize_block(10); + + // Trigger rent through call + assert!(trigger_call()); + assert_matches!(ContractInfoOf::::get(BOB), Some(ContractInfo::Tombstone(_))); + assert_eq!(Balances::free_balance(BOB), subsistence_threshold); + + // Advance blocks + initialize_block(20); + + // Trigger rent must have no effect + assert!(trigger_call()); + assert_matches!(ContractInfoOf::::get(BOB), Some(ContractInfo::Tombstone(_))); + assert_eq!(Balances::free_balance(BOB), subsistence_threshold); + }); } #[test] fn call_removed_contract() { - let (wasm, code_hash) = compile_module::(&load_wasm("set_rent.wat")).unwrap(); + let (wasm, code_hash) = compile_module::("set_rent").unwrap(); // Balance reached and superior to subsistence threshold - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, - GAS_LIMIT, code_hash.into(), - ::Balance::from(1_000u32).encode() // rent allowance - )); - - // Calling contract should succeed. - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); - - // Advance blocks - initialize_block(10); - - // Calling contract should remove contract and fail. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), - "contract has been evicted" - ); - // Calling a contract that is about to evict shall emit an event. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), - topics: vec![], - }, - ]); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm.clone())); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 100, + GAS_LIMIT, code_hash.into(), + ::Balance::from(1_000u32).encode() // rent allowance + )); - // Subsequent contract calls should also fail. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), - "contract has been evicted" - ); - }) + // Calling contract should succeed. + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); + + // Advance blocks + initialize_block(10); + + // Calling contract should remove contract and fail. + assert_err_ignore_postinfo!( + Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), + Error::::NotCallable + ); + // Calling a contract that is about to evict shall emit an event. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), + topics: vec![], + }, + ]); + + // Subsequent contract calls should also fail. + assert_err_ignore_postinfo!( + Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), + Error::::NotCallable + ); + }) } #[test] fn default_rent_allowance_on_instantiate() { - let (wasm, code_hash) = compile_module::( - &load_wasm("check_default_rent_allowance.wat")).unwrap(); + let (wasm, code_hash) = compile_module::("check_default_rent_allowance").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 30_000, + GAS_LIMIT, + code_hash.into(), + vec![], + )); - // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, >::max_value()); + // Check creation + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, >::max_value()); - // Advance blocks - initialize_block(5); + // Advance blocks + initialize_block(5); - // Trigger rent through call - assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); + // Trigger rent through call + assert_ok!(Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null())); - // Check contract is still alive - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive(); - assert!(bob_contract.is_some()) - }); + // Check contract is still alive + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive(); + assert!(bob_contract.is_some()) + }); } #[test] @@ -1100,571 +1074,755 @@ fn restoration_success() { } fn restoration(test_different_storage: bool, test_restore_to_with_dirty_storage: bool) { - let (set_rent_wasm, set_rent_code_hash) = - compile_module::(&load_wasm("set_rent.wat")).unwrap(); - let (restoration_wasm, restoration_code_hash) = - compile_module::(&load_wasm("restoration.wat")).unwrap(); - - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), restoration_wasm)); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), set_rent_wasm)); - - // If you ever need to update the wasm source this test will fail - // and will show you the actual hash. - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(restoration_code_hash.into())), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::CodeStored(set_rent_code_hash.into())), - topics: vec![], - }, - ]); + let (set_rent_wasm, set_rent_code_hash) = compile_module::("set_rent").unwrap(); + let (restoration_wasm, restoration_code_hash) = compile_module::("restoration").unwrap(); - // Create an account with address `BOB` with code `CODE_SET_RENT`. - // The input parameter sets the rent allowance to 0. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - set_rent_code_hash.into(), - ::Balance::from(0u32).encode() - )); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), restoration_wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), set_rent_wasm)); - // Check if `BOB` was created successfully and that the rent allowance is - // set to 0. - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 0); + // If you ever need to update the wasm source this test will fail + // and will show you the actual hash. + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::system(frame_system::RawEvent::NewAccount(1)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(1, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::contracts(RawEvent::CodeStored(restoration_code_hash.into())), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::contracts(RawEvent::CodeStored(set_rent_code_hash.into())), + topics: vec![], + }, + ]); - if test_different_storage { - assert_ok!(Contracts::call( + // Create an account with address `BOB` with code `CODE_SET_RENT`. + // The input parameter sets the rent allowance to 0. + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), - BOB, 0, GAS_LIMIT, - call::set_storage_4_byte()) - ); - } - - // Advance 4 blocks, to the 5th. - initialize_block(5); - - /// Preserve `BOB`'s code hash for later introspection. - let bob_code_hash = ContractInfoOf::::get(BOB).unwrap() - .get_alive().unwrap().code_hash; - // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0 - // we expect that it will get removed leaving tombstone. - assert_err_ignore_postinfo!( - Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), - "contract has been evicted" - ); - assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts( - RawEvent::Evicted(BOB.clone(), true) - ), - topics: vec![], - }, - ]); - - /// Create another account with the address `DJANGO` with `CODE_RESTORATION`. - /// - /// Note that we can't use `ALICE` for creating `DJANGO` so we create yet another - /// account `CHARLIE` and create `DJANGO` with it. - Balances::deposit_creating(&CHARLIE, 1_000_000); - assert_ok!(Contracts::instantiate( - Origin::signed(CHARLIE), - 30_000, - GAS_LIMIT, - restoration_code_hash.into(), - ::Balance::from(0u32).encode() - )); + 30_000, + GAS_LIMIT, + set_rent_code_hash.into(), + ::Balance::from(0u32).encode() + )); - // Before performing a call to `DJANGO` save its original trie id. - let django_trie_id = ContractInfoOf::::get(DJANGO).unwrap() - .get_alive().unwrap().trie_id; + // Check if `BOB` was created successfully and that the rent allowance is + // set to 0. + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 0); - if !test_restore_to_with_dirty_storage { - // Advance 1 block, to the 6th. - initialize_block(6); - } + if test_different_storage { + assert_ok!(Contracts::call( + Origin::signed(ALICE), + BOB, 0, GAS_LIMIT, + call::set_storage_4_byte()) + ); + } - // Perform a call to `DJANGO`. This should either perform restoration successfully or - // fail depending on the test parameters. - assert_ok!(Contracts::call( - Origin::signed(ALICE), - DJANGO, - 0, - GAS_LIMIT, - vec![], - )); + // Advance 4 blocks, to the 5th. + initialize_block(5); - if test_different_storage || test_restore_to_with_dirty_storage { - // Parametrization of the test imply restoration failure. Check that `DJANGO` aka - // restoration contract is still in place and also that `BOB` doesn't exist. + // Call `BOB`, which makes it pay rent. Since the rent allowance is set to 0 + // we expect that it will get removed leaving tombstone. + assert_err_ignore_postinfo!( + Contracts::call(Origin::signed(ALICE), BOB, 0, GAS_LIMIT, call::null()), + Error::::NotCallable + ); assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); - let django_contract = ContractInfoOf::::get(DJANGO).unwrap() - .get_alive().unwrap(); - assert_eq!(django_contract.storage_size, 16); - assert_eq!(django_contract.trie_id, django_trie_id); - assert_eq!(django_contract.deduct_block, System::block_number()); - match (test_different_storage, test_restore_to_with_dirty_storage) { - (true, false) => { - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts( - RawEvent::Restored(DJANGO, BOB, bob_code_hash, 50, false) - ), - topics: vec![], - }, - ]); - } - (_, true) => { - assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(CHARLIE)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(CHARLIE, 1_000_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(frame_system::RawEvent::NewAccount(DJANGO)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(DJANGO, 30_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Transfer(CHARLIE, DJANGO, 30_000)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Instantiated(CHARLIE, DJANGO)), - topics: vec![], - }, - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::contracts(RawEvent::Restored( - DJANGO, - BOB, - bob_code_hash, - 50, - false, - )), - topics: vec![], - }, - ]); - } - _ => unreachable!(), - } - } else { - // Here we expect that the restoration is succeeded. Check that the restoration - // contract `DJANGO` ceased to exist and that `BOB` returned back. - println!("{:?}", ContractInfoOf::::get(BOB)); - let bob_contract = ContractInfoOf::::get(BOB).unwrap() - .get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, 50); - assert_eq!(bob_contract.storage_size, 12); - assert_eq!(bob_contract.trie_id, django_trie_id); - assert_eq!(bob_contract.deduct_block, System::block_number()); - assert!(ContractInfoOf::::get(DJANGO).is_none()); assert_eq!(System::events(), vec![ - EventRecord { - phase: Phase::Initialization, - event: MetaEvent::system(system::RawEvent::KilledAccount(DJANGO)), - topics: vec![], - }, EventRecord { phase: Phase::Initialization, event: MetaEvent::contracts( - RawEvent::Restored(DJANGO, BOB, bob_contract.code_hash, 50, true) + RawEvent::Evicted(BOB.clone(), true) ), topics: vec![], }, ]); - } - }); + + // Create another account with the address `DJANGO` with `CODE_RESTORATION`. + // + // Note that we can't use `ALICE` for creating `DJANGO` so we create yet another + // account `CHARLIE` and create `DJANGO` with it. + let _ = Balances::deposit_creating(&CHARLIE, 1_000_000); + assert_ok!(Contracts::instantiate( + Origin::signed(CHARLIE), + 30_000, + GAS_LIMIT, + restoration_code_hash.into(), + ::Balance::from(0u32).encode() + )); + + // Before performing a call to `DJANGO` save its original trie id. + let django_trie_id = ContractInfoOf::::get(DJANGO).unwrap() + .get_alive().unwrap().trie_id; + + if !test_restore_to_with_dirty_storage { + // Advance 1 block, to the 6th. + initialize_block(6); + } + + // Perform a call to `DJANGO`. This should either perform restoration successfully or + // fail depending on the test parameters. + let perform_the_restoration = || { + Contracts::call( + Origin::signed(ALICE), + DJANGO, + 0, + GAS_LIMIT, + set_rent_code_hash.as_ref().to_vec(), + ) + }; + + if test_different_storage || test_restore_to_with_dirty_storage { + // Parametrization of the test imply restoration failure. Check that `DJANGO` aka + // restoration contract is still in place and also that `BOB` doesn't exist. + + assert_err_ignore_postinfo!( + perform_the_restoration(), + Error::::ContractTrapped, + ); + + assert!(ContractInfoOf::::get(BOB).unwrap().get_tombstone().is_some()); + let django_contract = ContractInfoOf::::get(DJANGO).unwrap() + .get_alive().unwrap(); + assert_eq!(django_contract.storage_size, 8); + assert_eq!(django_contract.trie_id, django_trie_id); + assert_eq!(django_contract.deduct_block, System::block_number()); + match (test_different_storage, test_restore_to_with_dirty_storage) { + (true, false) => { + assert_eq!(System::events(), vec![]); + } + (_, true) => { + pretty_assertions::assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::contracts(RawEvent::Evicted(BOB, true)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::system(frame_system::RawEvent::NewAccount(CHARLIE)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(CHARLIE, 1_000_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::system(frame_system::RawEvent::NewAccount(DJANGO)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::balances(pallet_balances::RawEvent::Endowed(DJANGO, 30_000)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::balances( + pallet_balances::RawEvent::Transfer(CHARLIE, DJANGO, 30_000) + ), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::contracts(RawEvent::Instantiated(CHARLIE, DJANGO)), + topics: vec![], + }, + ]); + } + _ => unreachable!(), + } + } else { + assert_ok!(perform_the_restoration()); + + // Here we expect that the restoration is succeeded. Check that the restoration + // contract `DJANGO` ceased to exist and that `BOB` returned back. + println!("{:?}", ContractInfoOf::::get(BOB)); + let bob_contract = ContractInfoOf::::get(BOB).unwrap() + .get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 50); + assert_eq!(bob_contract.storage_size, 4); + assert_eq!(bob_contract.trie_id, django_trie_id); + assert_eq!(bob_contract.deduct_block, System::block_number()); + assert!(ContractInfoOf::::get(DJANGO).is_none()); + assert_eq!(System::events(), vec![ + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::system(system::RawEvent::KilledAccount(DJANGO)), + topics: vec![], + }, + EventRecord { + phase: Phase::Initialization, + event: MetaEvent::contracts( + RawEvent::Restored(DJANGO, BOB, bob_contract.code_hash, 50) + ), + topics: vec![], + }, + ]); + } + }); } #[test] fn storage_max_value_limit() { - let (wasm, code_hash) = compile_module::(&load_wasm("storage_size.wat")) - .unwrap(); + let (wasm, code_hash) = compile_module::("storage_size").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 30_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Check creation - let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); - assert_eq!(bob_contract.rent_allowance, >::max_value()); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 30_000, + GAS_LIMIT, + code_hash.into(), + vec![], + )); - // Call contract with allowed storage value. - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - Encode::encode(&self::MaxValueSize::get()), - )); + // Check creation + let bob_contract = ContractInfoOf::::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, >::max_value()); - // Call contract with too large a storage value. - assert_err_ignore_postinfo!( - Contracts::call( + // Call contract with allowed storage value. + assert_ok!(Contracts::call( Origin::signed(ALICE), BOB, 0, - GAS_LIMIT, - Encode::encode(&(self::MaxValueSize::get() + 1)), - ), - "contract trapped during execution" - ); - }); + GAS_LIMIT * 2, // we are copying a huge buffer + Encode::encode(&self::MaxValueSize::get()), + )); + + // Call contract with too large a storage value. + assert_err_ignore_postinfo!( + Contracts::call( + Origin::signed(ALICE), + BOB, + 0, + GAS_LIMIT, + Encode::encode(&(self::MaxValueSize::get() + 1)), + ), + Error::::ContractTrapped, + ); + }); } #[test] fn deploy_and_call_other_contract() { - let (callee_wasm, callee_code_hash) = - compile_module::(&load_wasm("return_with_data.wat")).unwrap(); - let (caller_wasm, caller_code_hash) = - compile_module::(&load_wasm("caller_contract.wat")).unwrap(); + let (callee_wasm, callee_code_hash) = compile_module::("return_with_data").unwrap(); + let (caller_wasm, caller_code_hash) = compile_module::("caller_contract").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), callee_wasm)); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), caller_wasm)); - - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - caller_code_hash.into(), - vec![], - )); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), callee_wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), caller_wasm)); - // Call BOB contract, which attempts to instantiate and call the callee contract and - // makes various assertions on the results from those calls. - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - callee_code_hash.as_ref().to_vec(), - )); - }); + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 100_000, + GAS_LIMIT, + caller_code_hash.into(), + vec![], + )); + + // Call BOB contract, which attempts to instantiate and call the callee contract and + // makes various assertions on the results from those calls. + assert_ok!(Contracts::call( + Origin::signed(ALICE), + BOB, + 0, + GAS_LIMIT, + callee_code_hash.as_ref().to_vec(), + )); + }); } #[test] fn cannot_self_destruct_through_draning() { - let (wasm, code_hash) = compile_module::(&load_wasm("drain.wat")).unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Instantiate the BOB contract. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Check that the BOB contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); + let (wasm, code_hash) = compile_module::("drain").unwrap(); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - // Call BOB with no input data, forcing it to run until out-of-balance - // and eventually trapping because below existential deposit. - assert_err_ignore_postinfo!( - Contracts::call( + // Instantiate the BOB contract. + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), - BOB, - 0, + 100_000, GAS_LIMIT, + code_hash.into(), vec![], - ), - "contract trapped during execution" - ); - }); + )); + + // Check that the BOB contract has been instantiated. + assert_matches!( + ContractInfoOf::::get(BOB), + Some(ContractInfo::Alive(_)) + ); + + // Call BOB which makes it send all funds to the zero address + // The contract code asserts that the correct error value is returned. + assert_ok!( + Contracts::call( + Origin::signed(ALICE), + BOB, + 0, + GAS_LIMIT, + vec![], + ) + ); + }); } #[test] fn cannot_self_destruct_while_live() { - let (wasm, code_hash) = compile_module::(&load_wasm("self_destruct.wat")) - .unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Instantiate the BOB contract. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Check that the BOB contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); + let (wasm, code_hash) = compile_module::("self_destruct").unwrap(); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - // Call BOB with input data, forcing it make a recursive call to itself to - // self-destruct, resulting in a trap. - assert_err_ignore_postinfo!( - Contracts::call( + // Instantiate the BOB contract. + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), - BOB, - 0, + 100_000, GAS_LIMIT, - vec![0], - ), - "contract trapped during execution" - ); + code_hash.into(), + vec![], + )); - // Check that BOB is still alive. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); - }); + // Check that the BOB contract has been instantiated. + assert_matches!( + ContractInfoOf::::get(BOB), + Some(ContractInfo::Alive(_)) + ); + + // Call BOB with input data, forcing it make a recursive call to itself to + // self-destruct, resulting in a trap. + assert_err_ignore_postinfo!( + Contracts::call( + Origin::signed(ALICE), + BOB, + 0, + GAS_LIMIT, + vec![0], + ), + Error::::ContractTrapped, + ); + + // Check that BOB is still alive. + assert_matches!( + ContractInfoOf::::get(BOB), + Some(ContractInfo::Alive(_)) + ); + }); } #[test] fn self_destruct_works() { - let (wasm, code_hash) = compile_module::(&load_wasm("self_destruct.wat")) - .unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - - // Instantiate the BOB contract. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100_000, - GAS_LIMIT, - code_hash.into(), - vec![], - )); - - // Check that the BOB contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(BOB), - Some(ContractInfo::Alive(_)) - ); + let (wasm, code_hash) = compile_module::("self_destruct").unwrap(); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - // Call BOB without input data which triggers termination. - assert_matches!( - Contracts::call( + // Instantiate the BOB contract. + assert_ok!(Contracts::instantiate( Origin::signed(ALICE), - BOB, - 0, + 100_000, GAS_LIMIT, + code_hash.into(), vec![], - ), - Ok(_) - ); + )); - // Check that account is gone - assert!(ContractInfoOf::::get(BOB).is_none()); + // Check that the BOB contract has been instantiated. + assert_matches!( + ContractInfoOf::::get(BOB), + Some(ContractInfo::Alive(_)) + ); - // check that the beneficiary (django) got remaining balance - assert_eq!(Balances::free_balance(DJANGO), 100_000); - }); + // Call BOB without input data which triggers termination. + assert_matches!( + Contracts::call( + Origin::signed(ALICE), + BOB, + 0, + GAS_LIMIT, + vec![], + ), + Ok(_) + ); + + // Check that account is gone + assert!(ContractInfoOf::::get(BOB).is_none()); + + // check that the beneficiary (django) got remaining balance + assert_eq!(Balances::free_balance(DJANGO), 100_000); + }); } // This tests that one contract cannot prevent another from self-destructing by sending it // additional funds after it has been drained. #[test] fn destroy_contract_and_transfer_funds() { - let (callee_wasm, callee_code_hash) = - compile_module::(&load_wasm("self_destruct.wat")).unwrap(); - let (caller_wasm, caller_code_hash) = - compile_module::(&load_wasm("destroy_and_transfer.wat")).unwrap(); + let (callee_wasm, callee_code_hash) = compile_module::("self_destruct").unwrap(); + let (caller_wasm, caller_code_hash) = compile_module::("destroy_and_transfer").unwrap(); - ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - // Create - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), callee_wasm)); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), caller_wasm)); - - // This deploys the BOB contract, which in turn deploys the CHARLIE contract during - // construction. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 200_000, - GAS_LIMIT, - caller_code_hash.into(), - callee_code_hash.as_ref().to_vec(), - )); - - // Check that the CHARLIE contract has been instantiated. - assert_matches!( - ContractInfoOf::::get(CHARLIE), - Some(ContractInfo::Alive(_)) - ); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + // Create + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), callee_wasm)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), caller_wasm)); - // Call BOB, which calls CHARLIE, forcing CHARLIE to self-destruct. - assert_ok!(Contracts::call( - Origin::signed(ALICE), - BOB, - 0, - GAS_LIMIT, - CHARLIE.encode(), - )); + // This deploys the BOB contract, which in turn deploys the CHARLIE contract during + // construction. + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 200_000, + GAS_LIMIT, + caller_code_hash.into(), + callee_code_hash.as_ref().to_vec(), + )); - // Check that CHARLIE has moved on to the great beyond (ie. died). - assert!(ContractInfoOf::::get(CHARLIE).is_none()); - }); + // Check that the CHARLIE contract has been instantiated. + assert_matches!( + ContractInfoOf::::get(CHARLIE), + Some(ContractInfo::Alive(_)) + ); + + // Call BOB, which calls CHARLIE, forcing CHARLIE to self-destruct. + assert_ok!(Contracts::call( + Origin::signed(ALICE), + BOB, + 0, + GAS_LIMIT, + CHARLIE.encode(), + )); + + // Check that CHARLIE has moved on to the great beyond (ie. died). + assert!(ContractInfoOf::::get(CHARLIE).is_none()); + }); } #[test] fn cannot_self_destruct_in_constructor() { - let (wasm, code_hash) = - compile_module::(&load_wasm("self_destructing_constructor.wat")).unwrap(); + let (wasm, code_hash) = compile_module::("self_destructing_constructor").unwrap(); + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + + // Fail to instantiate the BOB because the contructor calls seal_terminate. + assert_err_ignore_postinfo!( + Contracts::instantiate( + Origin::signed(ALICE), + 100_000, + GAS_LIMIT, + code_hash.into(), + vec![], + ), + Error::::NewContractNotFunded, + ); + }); +} + +#[test] +fn crypto_hashes() { + let (wasm, code_hash) = compile_module::("crypto_hashes").unwrap(); + + ExtBuilder::default() + .existential_deposit(50) + .build() + .execute_with(|| { + let _ = Balances::deposit_creating(&ALICE, 1_000_000); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + + // Instantiate the CRYPTO_HASHES contract. + assert_ok!(Contracts::instantiate( + Origin::signed(ALICE), + 100_000, + GAS_LIMIT, + code_hash.into(), + vec![], + )); + // Perform the call. + let input = b"_DEAD_BEEF"; + use sp_io::hashing::*; + // Wraps a hash function into a more dynamic form usable for testing. + macro_rules! dyn_hash_fn { + ($name:ident) => { + Box::new(|input| $name(input).as_ref().to_vec().into_boxed_slice()) + }; + } + // All hash functions and their associated output byte lengths. + let test_cases: &[(Box Box<[u8]>>, usize)] = &[ + (dyn_hash_fn!(sha2_256), 32), + (dyn_hash_fn!(keccak_256), 32), + (dyn_hash_fn!(blake2_256), 32), + (dyn_hash_fn!(blake2_128), 16), + ]; + // Test the given hash functions for the input: "_DEAD_BEEF" + for (n, (hash_fn, expected_size)) in test_cases.iter().enumerate() { + // We offset data in the contract tables by 1. + let mut params = vec![(n + 1) as u8]; + params.extend_from_slice(input); + let result = >::bare_call( + ALICE, + BOB, + 0, + GAS_LIMIT, + params, + ).0.unwrap(); + assert!(result.is_success()); + let expected = hash_fn(input.as_ref()); + assert_eq!(&result.data[..*expected_size], &*expected); + } + }) +} + +#[test] +fn transfer_return_code() { + let (wasm, code_hash) = compile_module::("transfer_return_code").unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); + let subsistence = Config::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - // Fail to instantiate the BOB because the call that is issued in the deploy - // function exhausts all balances which puts it below the existential deposit. - assert_err_ignore_postinfo!( + assert_ok!( Contracts::instantiate( Origin::signed(ALICE), - 100_000, + subsistence, GAS_LIMIT, code_hash.into(), vec![], ), - "contract trapped during execution" ); + + // Contract has only the minimal balance so any transfer will return BelowSubsistence. + let result = Contracts::bare_call( + ALICE, + BOB, + 0, + GAS_LIMIT, + vec![], + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::BelowSubsistenceThreshold); + + // Contract has enough total balance in order to not go below the subsistence + // threshold when transfering 100 balance but this balance is reserved so + // the transfer still fails but with another return code. + Balances::make_free_balance_be(&BOB, subsistence + 100); + Balances::reserve(&BOB, subsistence + 100).unwrap(); + let result = Contracts::bare_call( + ALICE, + BOB, + 0, + GAS_LIMIT, + vec![], + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::TransferFailed); }); } -fn get_runtime_storage() { - let (wasm, code_hash) = compile_module::(&load_wasm("get_runtime_storage.wat")) - .unwrap(); +#[test] +fn call_return_code() { + let (caller_code, caller_hash) = compile_module::("call_return_code").unwrap(); + let (callee_code, callee_hash) = compile_module::("ok_trap_revert").unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); + let subsistence = Config::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); + let _ = Balances::deposit_creating(&CHARLIE, 10 * subsistence); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), caller_code)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), callee_code)); - frame_support::storage::unhashed::put_raw( - &[1, 2, 3, 4], - 0x14144020u32.to_le_bytes().to_vec().as_ref() + assert_ok!( + Contracts::instantiate( + Origin::signed(ALICE), + subsistence, + GAS_LIMIT, + caller_hash.into(), + vec![0], + ), ); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100, + // Contract calls into Django which is no valid contract + let result = Contracts::bare_call( + ALICE, + BOB, + 0, GAS_LIMIT, - code_hash.into(), - vec![], - )); - assert_ok!(Contracts::call( - Origin::signed(ALICE), + vec![0], + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::NotCallable); + + assert_ok!( + Contracts::instantiate( + Origin::signed(CHARLIE), + subsistence, + GAS_LIMIT, + callee_hash.into(), + vec![0], + ), + ); + + // Contract has only the minimal balance so any transfer will return BelowSubsistence. + let result = Contracts::bare_call( + ALICE, BOB, 0, GAS_LIMIT, - vec![], - )); + vec![0], + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::BelowSubsistenceThreshold); + + // Contract has enough total balance in order to not go below the subsistence + // threshold when transfering 100 balance but this balance is reserved so + // the transfer still fails but with another return code. + Balances::make_free_balance_be(&BOB, subsistence + 100); + Balances::reserve(&BOB, subsistence + 100).unwrap(); + let result = Contracts::bare_call( + ALICE, + BOB, + 0, + GAS_LIMIT, + vec![0], + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::TransferFailed); + + // Contract has enough balance but callee reverts because "1" is passed. + Balances::make_free_balance_be(&BOB, subsistence + 1000); + let result = Contracts::bare_call( + ALICE, + BOB, + 0, + GAS_LIMIT, + vec![1], + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::CalleeReverted); + + // Contract has enough balance but callee traps because "2" is passed. + let result = Contracts::bare_call( + ALICE, + BOB, + 0, + GAS_LIMIT, + vec![2], + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::CalleeTrapped); + }); } #[test] -fn crypto_hashes() { - let (wasm, code_hash) = compile_module::(&load_wasm("crypto_hashes.wat")).unwrap(); - +fn instantiate_return_code() { + let (caller_code, caller_hash) = compile_module::("instantiate_return_code").unwrap(); + let (callee_code, callee_hash) = compile_module::("ok_trap_revert").unwrap(); ExtBuilder::default().existential_deposit(50).build().execute_with(|| { - Balances::deposit_creating(&ALICE, 1_000_000); - assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm)); + let subsistence = Config::::subsistence_threshold_uncached(); + let _ = Balances::deposit_creating(&ALICE, 10 * subsistence); + let _ = Balances::deposit_creating(&CHARLIE, 10 * subsistence); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), caller_code)); + assert_ok!(Contracts::put_code(Origin::signed(ALICE), callee_code)); + let callee_hash = callee_hash.as_ref().to_vec(); + + assert_ok!( + Contracts::instantiate( + Origin::signed(ALICE), + subsistence, + GAS_LIMIT, + caller_hash.into(), + vec![], + ), + ); - // Instantiate the CRYPTO_HASHES contract. - assert_ok!(Contracts::instantiate( - Origin::signed(ALICE), - 100_000, + // Contract has only the minimal balance so any transfer will return BelowSubsistence. + let result = Contracts::bare_call( + ALICE, + BOB, + 0, GAS_LIMIT, - code_hash.into(), - vec![], - )); - // Perform the call. - let input = b"_DEAD_BEEF"; - use sp_io::hashing::*; - // Wraps a hash function into a more dynamic form usable for testing. - macro_rules! dyn_hash_fn { - ($name:ident) => { - Box::new(|input| $name(input).as_ref().to_vec().into_boxed_slice()) - }; - } - // All hash functions and their associated output byte lengths. - let test_cases: &[(Box Box<[u8]>>, usize)] = &[ - (dyn_hash_fn!(sha2_256), 32), - (dyn_hash_fn!(keccak_256), 32), - (dyn_hash_fn!(blake2_256), 32), - (dyn_hash_fn!(blake2_128), 16), - ]; - // Test the given hash functions for the input: "_DEAD_BEEF" - for (n, (hash_fn, expected_size)) in test_cases.iter().enumerate() { - // We offset data in the contract tables by 1. - let mut params = vec![(n + 1) as u8]; - params.extend_from_slice(input); - let result = >::bare_call( - ALICE, - BOB, - 0, - GAS_LIMIT, - params, - ).unwrap(); - assert_eq!(result.status, 0); - let expected = hash_fn(input.as_ref()); - assert_eq!(&result.data[..*expected_size], &*expected); - } - }) -} + vec![0; 33], + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::BelowSubsistenceThreshold); + + // Contract has enough total balance in order to not go below the subsistence + // threshold when transfering 100 balance but this balance is reserved so + // the transfer still fails but with another return code. + Balances::make_free_balance_be(&BOB, subsistence + 100); + Balances::reserve(&BOB, subsistence + 100).unwrap(); + let result = Contracts::bare_call( + ALICE, + BOB, + 0, + GAS_LIMIT, + vec![0; 33], + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::TransferFailed); + + // Contract has enough balance but the passed code hash is invalid + Balances::make_free_balance_be(&BOB, subsistence + 1000); + let result = Contracts::bare_call( + ALICE, + BOB, + 0, + GAS_LIMIT, + vec![0; 33], + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::CodeNotFound); -fn load_wasm(file_name: &str) -> String { - let path = ["tests/", file_name].concat(); - std::fs::read_to_string(&path).expect(&format!("Unable to read {} file", path)) + // Contract has enough balance but callee reverts because "1" is passed. + let result = Contracts::bare_call( + ALICE, + BOB, + 0, + GAS_LIMIT, + callee_hash.iter().cloned().chain(sp_std::iter::once(1)).collect(), + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::CalleeReverted); + + // Contract has enough balance but callee traps because "2" is passed. + let result = Contracts::bare_call( + ALICE, + BOB, + 0, + GAS_LIMIT, + callee_hash.iter().cloned().chain(sp_std::iter::once(2)).collect(), + ).0.unwrap(); + assert_return_code!(result, RuntimeReturnCode::CalleeTrapped); + + }); } diff --git a/frame/contracts/src/wasm/env_def/macros.rs b/frame/contracts/src/wasm/env_def/macros.rs index 335d35f1e7827271abc828727a87db5c2d6562df..2538f85fb73851beb1a07c8b2ccdda0a538439dd 100644 --- a/frame/contracts/src/wasm/env_def/macros.rs +++ b/frame/contracts/src/wasm/env_def/macros.rs @@ -123,8 +123,8 @@ macro_rules! unmarshall_then_body_then_marshall { #[macro_export] macro_rules! define_func { - ( < E: $ext_ty:tt > $name:ident ( $ctx: ident $(, $names:ident : $params:ty)*) $(-> $returns:ty)* => $body:tt ) => { - fn $name< E: $ext_ty >( + ( < E: $seal_ty:tt > $name:ident ( $ctx: ident $(, $names:ident : $params:ty)*) $(-> $returns:ty)* => $body:tt ) => { + fn $name< E: $seal_ty >( $ctx: &mut $crate::wasm::Runtime, args: &[sp_sandbox::Value], ) -> Result { @@ -142,9 +142,9 @@ macro_rules! define_func { #[macro_export] macro_rules! register_func { - ( $reg_cb:ident, < E: $ext_ty:tt > ; ) => {}; + ( $reg_cb:ident, < E: $seal_ty:tt > ; ) => {}; - ( $reg_cb:ident, < E: $ext_ty:tt > ; + ( $reg_cb:ident, < E: $seal_ty:tt > ; $name:ident ( $ctx:ident $( , $names:ident : $params:ty )* ) $( -> $returns:ty )* => $body:tt $($rest:tt)* ) => { @@ -152,12 +152,12 @@ macro_rules! register_func { stringify!($name).as_bytes(), { define_func!( - < E: $ext_ty > $name ( $ctx $(, $names : $params )* ) $( -> $returns )* => $body + < E: $seal_ty > $name ( $ctx $(, $names : $params )* ) $( -> $returns )* => $body ); $name:: } ); - register_func!( $reg_cb, < E: $ext_ty > ; $($rest)* ); + register_func!( $reg_cb, < E: $seal_ty > ; $($rest)* ); }; } @@ -169,7 +169,7 @@ macro_rules! register_func { /// It's up to the user of this macro to check signatures of wasm code to be executed /// and reject the code if any imported function has a mismatched signature. macro_rules! define_env { - ( $init_name:ident , < E: $ext_ty:tt > , + ( $init_name:ident , < E: $seal_ty:tt > , $( $name:ident ( $ctx:ident $( , $names:ident : $params:ty )* ) $( -> $returns:ty )* => $body:tt , )* ) => { @@ -185,7 +185,7 @@ macro_rules! define_env { impl $crate::wasm::env_def::FunctionImplProvider for $init_name { fn impls)>(f: &mut F) { - register_func!(f, < E: $ext_ty > ; $( $name ( $ctx $( , $names : $params )* ) $( -> $returns)* => $body )* ); + register_func!(f, < E: $seal_ty > ; $( $name ( $ctx $( , $names : $params )* ) $( -> $returns)* => $body )* ); } } }; @@ -255,7 +255,7 @@ mod tests { #[test] fn macro_define_func() { - define_func!( ext_gas (_ctx, amount: u32) => { + define_func!( seal_gas (_ctx, amount: u32) => { let amount = Gas::from(amount); if !amount.is_zero() { Ok(()) @@ -264,7 +264,7 @@ mod tests { } }); let _f: fn(&mut Runtime, &[sp_sandbox::Value]) - -> Result = ext_gas::; + -> Result = seal_gas::; } #[test] @@ -307,7 +307,7 @@ mod tests { use crate::wasm::env_def::ImportSatisfyCheck; define_env!(Env, , - ext_gas( _ctx, amount: u32 ) => { + seal_gas( _ctx, amount: u32 ) => { let amount = Gas::from(amount); if !amount.is_zero() { Ok(()) @@ -317,7 +317,7 @@ mod tests { }, ); - assert!(Env::can_satisfy(b"ext_gas", &FunctionType::new(vec![ValueType::I32], None))); + assert!(Env::can_satisfy(b"seal_gas", &FunctionType::new(vec![ValueType::I32], None))); assert!(!Env::can_satisfy(b"not_exists", &FunctionType::new(vec![], None))); } } diff --git a/frame/contracts/src/wasm/mod.rs b/frame/contracts/src/wasm/mod.rs index cb69cd689b2657fa159eec447f1ed569cfc4a434..e74adfcf3caca1c91339669c6403a35f91b8eb2e 100644 --- a/frame/contracts/src/wasm/mod.rs +++ b/frame/contracts/src/wasm/mod.rs @@ -36,6 +36,7 @@ use self::runtime::{to_execution_result, Runtime}; use self::code_cache::load as load_code; pub use self::code_cache::save as save_code; +pub use self::runtime::ReturnCode; /// A prepared wasm module ready for execution. #[derive(Clone, Encode, Decode)] @@ -126,9 +127,9 @@ impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a> { }); let mut imports = sp_sandbox::EnvironmentDefinitionBuilder::new(); - imports.add_memory("env", "memory", memory.clone()); + imports.add_memory(self::prepare::IMPORT_MODULE_MEMORY, "memory", memory.clone()); runtime::Env::impls(&mut |name, func_ptr| { - imports.add_host_func("env", name, func_ptr); + imports.add_host_func(self::prepare::IMPORT_MODULE_FN, name, func_ptr); }); let mut runtime = Runtime::new( @@ -151,17 +152,15 @@ impl<'a, T: Trait> crate::exec::Vm for WasmVm<'a> { mod tests { use super::*; use std::collections::HashMap; - use std::cell::RefCell; use sp_core::H256; - use crate::exec::{Ext, StorageKey, ExecError, ExecReturnValue, STATUS_SUCCESS}; + use crate::exec::{Ext, StorageKey, ExecReturnValue, ReturnFlags, ExecError, ErrorOrigin}; use crate::gas::{Gas, GasMeter}; use crate::tests::{Test, Call}; use crate::wasm::prepare::prepare_contract; - use crate::{CodeHash, BalanceOf}; - use wabt; + use crate::{CodeHash, BalanceOf, Error}; use hex_literal::hex; - use assert_matches::assert_matches; use sp_runtime::DispatchError; + use frame_support::weights::Weight; const GAS_LIMIT: Gas = 10_000_000_000; @@ -205,22 +204,10 @@ mod tests { instantiates: Vec, terminations: Vec, transfers: Vec, - dispatches: Vec, restores: Vec, // (topics, data) events: Vec<(Vec, Vec)>, next_account_id: u64, - - /// Runtime storage keys works the following way. - /// - /// - If the test code requests a value and it doesn't exist in this storage map then a - /// panic happens. - /// - If the value does exist it is returned and then removed from the map. So a panic - /// happens if the same value is requested for the second time. - /// - /// This behavior is used to prevent mixing up an access to unexpected location and empty - /// cell. - runtime_storage_keys: RefCell, Option>>>, } impl Ext for MockExt { @@ -229,11 +216,8 @@ mod tests { fn get_storage(&self, key: &StorageKey) -> Option> { self.storage.get(key).cloned() } - fn set_storage(&mut self, key: StorageKey, value: Option>) - -> Result<(), &'static str> - { + fn set_storage(&mut self, key: StorageKey, value: Option>) { *self.storage.entry(key).or_insert(Vec::new()) = value.unwrap_or(Vec::new()); - Ok(()) } fn instantiate( &mut self, @@ -254,7 +238,7 @@ mod tests { Ok(( address, ExecReturnValue { - status: STATUS_SUCCESS, + flags: ReturnFlags::empty(), data: Vec::new(), }, )) @@ -288,7 +272,7 @@ mod tests { }); // Assume for now that it was just a plain transfer. // TODO: Add tests for different call outcomes. - Ok(ExecReturnValue { status: STATUS_SUCCESS, data: Vec::new() }) + Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() }) } fn terminate( &mut self, @@ -301,22 +285,20 @@ mod tests { }); Ok(()) } - fn note_dispatch_call(&mut self, call: Call) { - self.dispatches.push(DispatchEntry(call)); - } - fn note_restore_to( + fn restore_to( &mut self, dest: u64, code_hash: H256, rent_allowance: u64, delta: Vec, - ) { + ) -> Result<(), &'static str> { self.restores.push(RestoreEntry { dest, code_hash, rent_allowance, delta, }); + Ok(()) } fn caller(&self) -> &u64 { &42 @@ -363,20 +345,8 @@ mod tests { fn max_value_size(&self) -> u32 { 16_384 } - fn get_runtime_storage(&self, key: &[u8]) -> Option> { - let opt_value = self.runtime_storage_keys - .borrow_mut() - .remove(key); - opt_value.unwrap_or_else(|| - panic!( - "{:?} doesn't exist. values that do exist {:?}", - key, - self.runtime_storage_keys - ) - ) - } - fn get_weight_price(&self) -> BalanceOf { - 1312_u32.into() + fn get_weight_price(&self, weight: Weight) -> BalanceOf { + BalanceOf::::from(1312_u32).saturating_mul(weight.into()) } } @@ -386,9 +356,7 @@ mod tests { fn get_storage(&self, key: &[u8; 32]) -> Option> { (**self).get_storage(key) } - fn set_storage(&mut self, key: [u8; 32], value: Option>) - -> Result<(), &'static str> - { + fn set_storage(&mut self, key: [u8; 32], value: Option>) { (**self).set_storage(key, value) } fn instantiate( @@ -424,17 +392,14 @@ mod tests { ) -> ExecResult { (**self).call(to, value, gas_meter, input_data) } - fn note_dispatch_call(&mut self, call: Call) { - (**self).note_dispatch_call(call) - } - fn note_restore_to( + fn restore_to( &mut self, dest: u64, code_hash: H256, rent_allowance: u64, delta: Vec, - ) { - (**self).note_restore_to( + ) -> Result<(), &'static str> { + (**self).restore_to( dest, code_hash, rent_allowance, @@ -480,11 +445,8 @@ mod tests { fn max_value_size(&self) -> u32 { (**self).max_value_size() } - fn get_runtime_storage(&self, key: &[u8]) -> Option> { - (**self).get_runtime_storage(key) - } - fn get_weight_price(&self) -> BalanceOf { - (**self).get_weight_price() + fn get_weight_price(&self, weight: Weight) -> BalanceOf { + (**self).get_weight_price(weight) } } @@ -496,7 +458,7 @@ mod tests { ) -> ExecResult { use crate::exec::Vm; - let wasm = wabt::wat2wasm(wat).unwrap(); + let wasm = wat::parse_str(wat).unwrap(); let schedule = crate::Schedule::default(); let prefab_module = prepare_contract::(&wasm, &schedule).unwrap(); @@ -515,17 +477,17 @@ mod tests { const CODE_TRANSFER: &str = r#" (module - ;; ext_transfer( + ;; seal_transfer( ;; account_ptr: u32, ;; account_len: u32, ;; value_ptr: u32, ;; value_len: u32, ;;) -> u32 - (import "env" "ext_transfer" (func $ext_transfer (param i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_transfer" (func $seal_transfer (param i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) (func (export "call") (drop - (call $ext_transfer + (call $seal_transfer (i32.const 4) ;; Pointer to "account" address. (i32.const 8) ;; Length of "account" address. (i32.const 12) ;; Pointer to the buffer with value to transfer @@ -568,20 +530,22 @@ mod tests { const CODE_CALL: &str = r#" (module - ;; ext_call( + ;; seal_call( ;; callee_ptr: u32, ;; callee_len: u32, ;; gas: u64, ;; value_ptr: u32, ;; value_len: u32, ;; input_data_ptr: u32, - ;; input_data_len: u32 + ;; input_data_len: u32, + ;; output_ptr: u32, + ;; output_len_ptr: u32 ;;) -> u32 - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) (func (export "call") (drop - (call $ext_call + (call $seal_call (i32.const 4) ;; Pointer to "callee" address. (i32.const 8) ;; Length of "callee" address. (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -589,6 +553,8 @@ mod tests { (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 20) ;; Pointer to input data buffer address (i32.const 4) ;; Length of input data buffer + (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this case ) ) ) @@ -621,14 +587,14 @@ mod tests { to: 9, value: 6, data: vec![1, 2, 3, 4], - gas_left: 9985500000, + gas_left: 9984500000, }] ); } const CODE_INSTANTIATE: &str = r#" (module - ;; ext_instantiate( + ;; seal_instantiate( ;; code_ptr: u32, ;; code_len: u32, ;; gas: u64, @@ -636,12 +602,17 @@ mod tests { ;; value_len: u32, ;; input_data_ptr: u32, ;; input_data_len: u32, + ;; input_data_len: u32, + ;; address_ptr: u32, + ;; address_len_ptr: u32, + ;; output_ptr: u32, + ;; output_len_ptr: u32 ;; ) -> u32 - (import "env" "ext_instantiate" (func $ext_instantiate (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_instantiate" (func $seal_instantiate (param i32 i32 i64 i32 i32 i32 i32 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) (func (export "call") (drop - (call $ext_instantiate + (call $seal_instantiate (i32.const 16) ;; Pointer to `code_hash` (i32.const 32) ;; Length of `code_hash` (i64.const 0) ;; How much gas to devote for the execution. 0 = all. @@ -649,6 +620,10 @@ mod tests { (i32.const 8) ;; Length of the buffer with value to transfer (i32.const 12) ;; Pointer to input data buffer address (i32.const 4) ;; Length of input data buffer + (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy address + (i32.const 0) ;; Length is ignored in this case + (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this case ) ) ) @@ -683,21 +658,21 @@ mod tests { code_hash: [0x11; 32].into(), endowment: 3, data: vec![1, 2, 3, 4], - gas_left: 9973500000, + gas_left: 9971500000, }] ); } const CODE_TERMINATE: &str = r#" (module - ;; ext_terminate( + ;; seal_terminate( ;; beneficiary_ptr: u32, ;; beneficiary_len: u32, ;; ) - (import "env" "ext_terminate" (func $ext_terminate (param i32 i32))) + (import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32))) (import "env" "memory" (memory 1 1)) (func (export "call") - (call $ext_terminate + (call $seal_terminate (i32.const 4) ;; Pointer to "beneficiary" address. (i32.const 8) ;; Length of "beneficiary" address. ) @@ -731,20 +706,22 @@ mod tests { const CODE_TRANSFER_LIMITED_GAS: &str = r#" (module - ;; ext_call( + ;; seal_call( ;; callee_ptr: u32, ;; callee_len: u32, ;; gas: u64, ;; value_ptr: u32, ;; value_len: u32, ;; input_data_ptr: u32, - ;; input_data_len: u32 + ;; input_data_len: u32, + ;; output_ptr: u32, + ;; output_len_ptr: u32 ;;) -> u32 - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) + (import "seal0" "seal_call" (func $seal_call (param i32 i32 i64 i32 i32 i32 i32 i32 i32) (result i32))) (import "env" "memory" (memory 1 1)) (func (export "call") (drop - (call $ext_call + (call $seal_call (i32.const 4) ;; Pointer to "callee" address. (i32.const 8) ;; Length of "callee" address. (i64.const 228) ;; How much gas to devote for the execution. @@ -752,6 +729,8 @@ mod tests { (i32.const 8) ;; Length of the buffer with value to transfer. (i32.const 20) ;; Pointer to input data buffer address (i32.const 4) ;; Length of input data buffer + (i32.const 4294967295) ;; u32 max value is the sentinel value: do not copy output + (i32.const 0) ;; Length is ignored in this cas ) ) ) @@ -791,12 +770,21 @@ mod tests { const CODE_GET_STORAGE: &str = r#" (module - (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_return" (func $ext_return (param i32 i32))) + (import "seal0" "seal_get_storage" (func $seal_get_storage (param i32 i32 i32) (result i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) + ;; [0, 32) key for get storage + (data (i32.const 0) + "\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11" + "\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11" + ) + + ;; [32, 36) buffer size = 128 bytes + (data (i32.const 32) "\80") + + ;; [36; inf) buffer where the result is copied + (func $assert (param i32) (block $ok (br_if $ok @@ -809,12 +797,13 @@ mod tests { (func (export "call") (local $buf_size i32) - - ;; Load a storage value into the scratch buf. + ;; Load a storage value into contract memory. (call $assert (i32.eq - (call $ext_get_storage - (i32.const 4) ;; The pointer to the storage key to fetch + (call $seal_get_storage + (i32.const 0) ;; The pointer to the storage key to fetch + (i32.const 36) ;; Pointer to the output buffer + (i32.const 32) ;; Pointer to the size of the buffer ) ;; Return value 0 means that the value is found and there were @@ -823,42 +812,28 @@ mod tests { ) ) - ;; Find out the size of the scratch buffer + ;; Find out the size of the buffer (set_local $buf_size - (call $ext_scratch_size) - ) - - ;; Copy scratch buffer into this contract memory. - (call $ext_scratch_read - (i32.const 36) ;; The pointer where to store the scratch buffer contents, - ;; 36 = 4 + 32 - (i32.const 0) ;; Offset from the start of the scratch buffer. - (get_local ;; Count of bytes to copy. - $buf_size - ) + (i32.load (i32.const 32)) ) ;; Return the contents of the buffer - (call $ext_return + (call $seal_return + (i32.const 0) (i32.const 36) (get_local $buf_size) ) - ;; env:ext_return doesn't return, so this is effectively unreachable. + ;; env:seal_return doesn't return, so this is effectively unreachable. (unreachable) ) (func (export "deploy")) - - (data (i32.const 4) - "\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11" - "\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11" - ) ) "#; #[test] - fn get_storage_puts_data_into_scratch_buf() { + fn get_storage_puts_data_into_buf() { let mut mock_ext = MockExt::default(); mock_ext .storage @@ -871,18 +846,18 @@ mod tests { &mut GasMeter::new(GAS_LIMIT), ).unwrap(); - assert_eq!(output, ExecReturnValue { status: STATUS_SUCCESS, data: [0x22; 32].to_vec() }); + assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: [0x22; 32].to_vec() }); } - /// calls `ext_caller`, loads the address from the scratch buffer and - /// compares it with the constant 42. + /// calls `seal_caller` and compares the result with the constant 42. const CODE_CALLER: &str = r#" (module - (import "env" "ext_caller" (func $ext_caller)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "seal0" "seal_caller" (func $seal_caller (param i32 i32))) (import "env" "memory" (memory 1 1)) + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -893,30 +868,21 @@ mod tests { ) (func (export "call") - ;; fill the scratch buffer with the caller. - (call $ext_caller) + ;; fill the buffer with the caller. + (call $seal_caller (i32.const 0) (i32.const 32)) - ;; assert $ext_scratch_size == 8 + ;; assert len == 8 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 32)) (i32.const 8) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - ;; assert that contents of the buffer is equal to the i64 value of 42. (call $assert (i64.eq - (i64.load - (i32.const 8) - ) + (i64.load (i32.const 0)) (i64.const 42) ) ) @@ -936,15 +902,15 @@ mod tests { ).unwrap(); } - /// calls `ext_address`, loads the address from the scratch buffer and - /// compares it with the constant 69. + /// calls `seal_address` and compares the result with the constant 69. const CODE_ADDRESS: &str = r#" (module - (import "env" "ext_address" (func $ext_address)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "seal0" "seal_address" (func $seal_address (param i32 i32))) (import "env" "memory" (memory 1 1)) + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -955,30 +921,21 @@ mod tests { ) (func (export "call") - ;; fill the scratch buffer with the self address. - (call $ext_address) + ;; fill the buffer with the self address. + (call $seal_address (i32.const 0) (i32.const 32)) - ;; assert $ext_scratch_size == 8 + ;; assert size == 8 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 32)) (i32.const 8) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - ;; assert that contents of the buffer is equal to the i64 value of 69. (call $assert (i64.eq - (i64.load - (i32.const 8) - ) + (i64.load (i32.const 0)) (i64.const 69) ) ) @@ -1000,11 +957,12 @@ mod tests { const CODE_BALANCE: &str = r#" (module - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "seal0" "seal_balance" (func $seal_balance (param i32 i32))) (import "env" "memory" (memory 1 1)) + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -1015,30 +973,21 @@ mod tests { ) (func (export "call") - ;; This stores the balance in the scratch buffer - (call $ext_balance) + ;; This stores the balance in the buffer + (call $seal_balance (i32.const 0) (i32.const 32)) - ;; assert $ext_scratch_size == 8 + ;; assert len == 8 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 32)) (i32.const 8) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - ;; assert that contents of the buffer is equal to the i64 value of 228. (call $assert (i64.eq - (i64.load - (i32.const 8) - ) + (i64.load (i32.const 0)) (i64.const 228) ) ) @@ -1060,11 +1009,12 @@ mod tests { const CODE_GAS_PRICE: &str = r#" (module - (import "env" "ext_gas_price" (func $ext_gas_price)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "seal0" "seal_weight_to_fee" (func $seal_weight_to_fee (param i64 i32 i32))) (import "env" "memory" (memory 1 1)) + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -1075,31 +1025,22 @@ mod tests { ) (func (export "call") - ;; This stores the gas price in the scratch buffer - (call $ext_gas_price) + ;; This stores the gas price in the buffer + (call $seal_weight_to_fee (i64.const 2) (i32.const 0) (i32.const 32)) - ;; assert $ext_scratch_size == 8 + ;; assert len == 8 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 32)) (i32.const 8) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i64 value of 1312. + ;; assert that contents of the buffer is equal to the i64 value of 2 * 1312. (call $assert (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 1312) + (i64.load (i32.const 0)) + (i64.const 2624) ) ) ) @@ -1120,12 +1061,13 @@ mod tests { const CODE_GAS_LEFT: &str = r#" (module - (import "env" "ext_gas_left" (func $ext_gas_left)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_return" (func $ext_return (param i32 i32))) + (import "seal0" "seal_gas_left" (func $seal_gas_left (param i32 i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -1136,28 +1078,19 @@ mod tests { ) (func (export "call") - ;; This stores the gas left in the scratch buffer - (call $ext_gas_left) + ;; This stores the gas left in the buffer + (call $seal_gas_left (i32.const 0) (i32.const 32)) - ;; assert $ext_scratch_size == 8 + ;; assert len == 8 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 32)) (i32.const 8) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - (call $ext_return - (i32.const 8) - (i32.const 8) - ) + ;; return gas left + (call $seal_return (i32.const 0) (i32.const 0) (i32.const 8)) (unreachable) ) @@ -1183,11 +1116,12 @@ mod tests { const CODE_VALUE_TRANSFERRED: &str = r#" (module - (import "env" "ext_value_transferred" (func $ext_value_transferred)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "seal0" "seal_value_transferred" (func $seal_value_transferred (param i32 i32))) (import "env" "memory" (memory 1 1)) + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -1198,30 +1132,21 @@ mod tests { ) (func (export "call") - ;; This stores the value transferred in the scratch buffer - (call $ext_value_transferred) + ;; This stores the value transferred in the buffer + (call $seal_value_transferred (i32.const 0) (i32.const 32)) - ;; assert $ext_scratch_size == 8 + ;; assert len == 8 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 32)) (i32.const 8) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - ;; assert that contents of the buffer is equal to the i64 value of 1337. (call $assert (i64.eq - (i64.load - (i32.const 8) - ) + (i64.load (i32.const 0)) (i64.const 1337) ) ) @@ -1241,52 +1166,15 @@ mod tests { ).unwrap(); } - const CODE_DISPATCH_CALL: &str = r#" -(module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_dispatch_call - (i32.const 8) ;; Pointer to the start of encoded call buffer - (i32.const 13) ;; Length of the buffer - ) - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\01\2A\00\00\00\00\00\00\00\E5\14\00") -) -"#; - - #[test] - fn dispatch_call() { - // This test can fail due to the encoding changes. In case it becomes too annoying - // let's rewrite so as we use this module controlled call or we serialize it in runtime. - - let mut mock_ext = MockExt::default(); - let _ = execute( - CODE_DISPATCH_CALL, - vec![], - &mut mock_ext, - &mut GasMeter::new(GAS_LIMIT), - ).unwrap(); - - assert_eq!( - &mock_ext.dispatches, - &[DispatchEntry( - Call::Balances(pallet_balances::Call::set_balance(42, 1337, 0)), - )] - ); - } - const CODE_RETURN_FROM_START_FN: &str = r#" (module - (import "env" "ext_return" (func $ext_return (param i32 i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) (start $start) (func $start - (call $ext_return + (call $seal_return + (i32.const 0) (i32.const 8) (i32.const 4) ) @@ -1311,16 +1199,17 @@ mod tests { &mut GasMeter::new(GAS_LIMIT), ).unwrap(); - assert_eq!(output, ExecReturnValue { status: STATUS_SUCCESS, data: vec![1, 2, 3, 4] }); + assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: vec![1, 2, 3, 4] }); } const CODE_TIMESTAMP_NOW: &str = r#" (module - (import "env" "ext_now" (func $ext_now)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "seal0" "seal_now" (func $seal_now (param i32 i32))) (import "env" "memory" (memory 1 1)) + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -1331,30 +1220,21 @@ mod tests { ) (func (export "call") - ;; This stores the block timestamp in the scratch buffer - (call $ext_now) + ;; This stores the block timestamp in the buffer + (call $seal_now (i32.const 0) (i32.const 32)) - ;; assert $ext_scratch_size == 8 + ;; assert len == 8 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 32)) (i32.const 8) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - ;; assert that contents of the buffer is equal to the i64 value of 1111. (call $assert (i64.eq - (i64.load - (i32.const 8) - ) + (i64.load (i32.const 0)) (i64.const 1111) ) ) @@ -1376,11 +1256,12 @@ mod tests { const CODE_MINIMUM_BALANCE: &str = r#" (module - (import "env" "ext_minimum_balance" (func $ext_minimum_balance)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "seal0" "seal_minimum_balance" (func $seal_minimum_balance (param i32 i32))) (import "env" "memory" (memory 1 1)) + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -1391,29 +1272,20 @@ mod tests { ) (func (export "call") - (call $ext_minimum_balance) + (call $seal_minimum_balance (i32.const 0) (i32.const 32)) - ;; assert $ext_scratch_size == 8 + ;; assert len == 8 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 32)) (i32.const 8) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - ;; assert that contents of the buffer is equal to the i64 value of 666. (call $assert (i64.eq - (i64.load - (i32.const 8) - ) + (i64.load (i32.const 0)) (i64.const 666) ) ) @@ -1435,11 +1307,12 @@ mod tests { const CODE_TOMBSTONE_DEPOSIT: &str = r#" (module - (import "env" "ext_tombstone_deposit" (func $ext_tombstone_deposit)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "seal0" "seal_tombstone_deposit" (func $seal_tombstone_deposit (param i32 i32))) (import "env" "memory" (memory 1 1)) + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -1450,29 +1323,20 @@ mod tests { ) (func (export "call") - (call $ext_tombstone_deposit) + (call $seal_tombstone_deposit (i32.const 0) (i32.const 32)) - ;; assert $ext_scratch_size == 8 + ;; assert len == 8 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 32)) (i32.const 8) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - ;; assert that contents of the buffer is equal to the i64 value of 16. (call $assert (i64.eq - (i64.load - (i32.const 8) - ) + (i64.load (i32.const 0)) (i64.const 16) ) ) @@ -1494,12 +1358,21 @@ mod tests { const CODE_RANDOM: &str = r#" (module - (import "env" "ext_random" (func $ext_random (param i32 i32))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_return" (func $ext_return (param i32 i32))) + (import "seal0" "seal_random" (func $seal_random (param i32 i32 i32 i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) + ;; [0,128) is reserved for the result of PRNG. + + ;; the subject used for the PRNG. [128,160) + (data (i32.const 128) + "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F" + "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F" + ) + + ;; size of our buffer is 128 bytes + (data (i32.const 160) "\80") + (func $assert (param i32) (block $ok (br_if $ok @@ -1510,42 +1383,30 @@ mod tests { ) (func (export "call") - ;; This stores the block random seed in the scratch buffer - (call $ext_random - (i32.const 40) ;; Pointer in memory to the start of the subject buffer + ;; This stores the block random seed in the buffer + (call $seal_random + (i32.const 128) ;; Pointer in memory to the start of the subject buffer (i32.const 32) ;; The subject buffer's length + (i32.const 0) ;; Pointer to the output buffer + (i32.const 160) ;; Pointer to the output buffer length ) - ;; assert $ext_scratch_size == 32 + ;; assert len == 32 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 160)) (i32.const 32) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 32) ;; Count of bytes to copy. - ) - - ;; return the data from the contract - (call $ext_return - (i32.const 8) + ;; return the random data + (call $seal_return + (i32.const 0) + (i32.const 0) (i32.const 32) ) ) (func (export "deploy")) - - ;; [8,40) is reserved for the result of PRNG. - - ;; the subject used for the PRNG. [40,72) - (data (i32.const 40) - "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F" - "\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F" - ) ) "#; @@ -1564,7 +1425,7 @@ mod tests { assert_eq!( output, ExecReturnValue { - status: STATUS_SUCCESS, + flags: ReturnFlags::empty(), data: hex!("000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F").to_vec(), }, ); @@ -1572,11 +1433,11 @@ mod tests { const CODE_DEPOSIT_EVENT: &str = r#" (module - (import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32))) + (import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32))) (import "env" "memory" (memory 1 1)) (func (export "call") - (call $ext_deposit_event + (call $seal_deposit_event (i32.const 32) ;; Pointer to the start of topics buffer (i32.const 33) ;; The length of the topics buffer. (i32.const 8) ;; Pointer to the start of the data buffer @@ -1614,11 +1475,11 @@ mod tests { const CODE_DEPOSIT_EVENT_MAX_TOPICS: &str = r#" (module - (import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32))) + (import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32))) (import "env" "memory" (memory 1 1)) (func (export "call") - (call $ext_deposit_event + (call $seal_deposit_event (i32.const 32) ;; Pointer to the start of topics buffer (i32.const 161) ;; The length of the topics buffer. (i32.const 8) ;; Pointer to the start of the data buffer @@ -1644,7 +1505,7 @@ mod tests { // Checks that the runtime traps if there are more than `max_topic_events` topics. let mut gas_meter = GasMeter::new(GAS_LIMIT); - assert_matches!( + assert_eq!( execute( CODE_DEPOSIT_EVENT_MAX_TOPICS, vec![], @@ -1652,18 +1513,19 @@ mod tests { &mut gas_meter ), Err(ExecError { - reason: DispatchError::Other("contract trapped during execution"), buffer: _ + error: Error::::ContractTrapped.into(), + origin: ErrorOrigin::Caller, }) ); } const CODE_DEPOSIT_EVENT_DUPLICATES: &str = r#" (module - (import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32))) + (import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32))) (import "env" "memory" (memory 1 1)) (func (export "call") - (call $ext_deposit_event + (call $seal_deposit_event (i32.const 32) ;; Pointer to the start of topics buffer (i32.const 129) ;; The length of the topics buffer. (i32.const 8) ;; Pointer to the start of the data buffer @@ -1688,26 +1550,29 @@ mod tests { // Checks that the runtime traps if there are duplicates. let mut gas_meter = GasMeter::new(GAS_LIMIT); - assert_matches!( + assert_eq!( execute( CODE_DEPOSIT_EVENT_DUPLICATES, vec![], MockExt::default(), &mut gas_meter ), - Err(ExecError { reason: DispatchError::Other("contract trapped during execution"), buffer: _ }) + Err(ExecError { + error: Error::::ContractTrapped.into(), + origin: ErrorOrigin::Caller, + }) ); } - /// calls `ext_block_number`, loads the current block number from the scratch buffer and - /// compares it with the constant 121. + /// calls `seal_block_number` compares the result with the constant 121. const CODE_BLOCK_NUMBER: &str = r#" (module - (import "env" "ext_block_number" (func $ext_block_number)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) + (import "seal0" "seal_block_number" (func $seal_block_number (param i32 i32))) (import "env" "memory" (memory 1 1)) + ;; size of our buffer is 32 bytes + (data (i32.const 32) "\20") + (func $assert (param i32) (block $ok (br_if $ok @@ -1718,30 +1583,21 @@ mod tests { ) (func (export "call") - ;; This stores the block height in the scratch buffer - (call $ext_block_number) + ;; This stores the block height in the buffer + (call $seal_block_number (i32.const 0) (i32.const 32)) - ;; assert $ext_scratch_size == 8 + ;; assert len == 8 (call $assert (i32.eq - (call $ext_scratch_size) + (i32.load (i32.const 32)) (i32.const 8) ) ) - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - ;; assert that contents of the buffer is equal to the i64 value of 121. (call $assert (i64.eq - (i64.load - (i32.const 8) - ) + (i64.load (i32.const 0)) (i64.const 121) ) ) @@ -1761,228 +1617,132 @@ mod tests { ).unwrap(); } - // asserts that the size of the input data is 4. - const CODE_SIMPLE_ASSERT: &str = r#" -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 4) - ) - ) - ) -) -"#; - - #[test] - fn output_buffer_capacity_preserved_on_success() { - let mut input_data = Vec::with_capacity(1_234); - input_data.extend_from_slice(&[1, 2, 3, 4][..]); - - let output = execute( - CODE_SIMPLE_ASSERT, - input_data, - MockExt::default(), - &mut GasMeter::new(GAS_LIMIT), - ).unwrap(); - - assert_eq!(output.data.len(), 0); - assert_eq!(output.data.capacity(), 1_234); - } - - #[test] - fn output_buffer_capacity_preserved_on_failure() { - let mut input_data = Vec::with_capacity(1_234); - input_data.extend_from_slice(&[1, 2, 3, 4, 5][..]); - - let error = execute( - CODE_SIMPLE_ASSERT, - input_data, - MockExt::default(), - &mut GasMeter::new(GAS_LIMIT), - ).err().unwrap(); - - assert_eq!(error.buffer.capacity(), 1_234); - } - const CODE_RETURN_WITH_DATA: &str = r#" (module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) + (import "seal0" "seal_input" (func $seal_input (param i32 i32))) + (import "seal0" "seal_return" (func $seal_return (param i32 i32 i32))) (import "env" "memory" (memory 1 1)) + (data (i32.const 32) "\20") + ;; Deploy routine is the same as call. - (func (export "deploy") (result i32) + (func (export "deploy") (call $call) ) ;; Call reads the first 4 bytes (LE) as the exit status and returns the rest as output data. - (func $call (export "call") (result i32) - (local $buf_size i32) - (local $exit_status i32) - - ;; Find out the size of the scratch buffer - (set_local $buf_size (call $ext_scratch_size)) - - ;; Copy scratch buffer into this contract memory. - (call $ext_scratch_read - (i32.const 0) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (get_local $buf_size) ;; Count of bytes to copy. + (func $call (export "call") + ;; Copy input data this contract memory. + (call $seal_input + (i32.const 0) ;; Pointer where to store input + (i32.const 32) ;; Pointer to the length of the buffer ) ;; Copy all but the first 4 bytes of the input data as the output data. - (call $ext_scratch_write - (i32.const 4) ;; Offset from the start of the scratch buffer. - (i32.sub ;; Count of bytes to copy. - (get_local $buf_size) - (i32.const 4) - ) + (call $seal_return + (i32.load (i32.const 0)) + (i32.const 4) + (i32.sub (i32.load (i32.const 32)) (i32.const 4)) ) - - ;; Return the first 4 bytes of the input data as the exit status. - (i32.load (i32.const 0)) + (unreachable) ) ) "#; #[test] - fn return_with_success_status() { + fn seal_return_with_success_status() { let output = execute( CODE_RETURN_WITH_DATA, - hex!("00112233445566778899").to_vec(), + hex!("00000000445566778899").to_vec(), MockExt::default(), &mut GasMeter::new(GAS_LIMIT), ).unwrap(); - assert_eq!(output, ExecReturnValue { status: 0, data: hex!("445566778899").to_vec() }); + assert_eq!(output, ExecReturnValue { flags: ReturnFlags::empty(), data: hex!("445566778899").to_vec() }); assert!(output.is_success()); } #[test] - fn return_with_failure_status() { + fn return_with_revert_status() { let output = execute( CODE_RETURN_WITH_DATA, - hex!("112233445566778899").to_vec(), + hex!("010000005566778899").to_vec(), MockExt::default(), &mut GasMeter::new(GAS_LIMIT), ).unwrap(); - assert_eq!(output, ExecReturnValue { status: 17, data: hex!("5566778899").to_vec() }); + assert_eq!(output, ExecReturnValue { flags: ReturnFlags::REVERT, data: hex!("5566778899").to_vec() }); assert!(!output.is_success()); } - const CODE_GET_RUNTIME_STORAGE: &str = r#" + const CODE_OUT_OF_BOUNDS_ACCESS: &str = r#" (module - (import "env" "ext_get_runtime_storage" - (func $ext_get_runtime_storage (param i32 i32) (result i32)) - ) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) + (import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32))) (import "env" "memory" (memory 1 1)) (func (export "deploy")) - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) + (func (export "call") + (call $seal_terminate + (i32.const 65536) ;; Pointer to "account" address (out of bound). + (i32.const 8) ;; Length of "account" address. ) ) +) +"#; - (func $call (export "call") - ;; Load runtime storage for the first key and assert that it exists. - (call $assert - (i32.eq - (call $ext_get_runtime_storage - (i32.const 16) - (i32.const 4) - ) - (i32.const 0) - ) - ) + #[test] + fn contract_out_of_bounds_access() { + let mut mock_ext = MockExt::default(); + let result = execute( + CODE_OUT_OF_BOUNDS_ACCESS, + vec![], + &mut mock_ext, + &mut GasMeter::new(GAS_LIMIT), + ); - ;; assert $ext_scratch_size == 4 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 4) - ) - ) + assert_eq!( + result, + Err(ExecError { + error: Error::::OutOfBounds.into(), + origin: ErrorOrigin::Caller, + }) + ); + } - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 4) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 4) ;; Count of bytes to copy. - ) + const CODE_DECODE_FAILURE: &str = r#" +(module + (import "seal0" "seal_terminate" (func $seal_terminate (param i32 i32))) + (import "env" "memory" (memory 1 1)) - ;; assert that contents of the buffer is equal to the i32 value of 0x14144020. - (call $assert - (i32.eq - (i32.load - (i32.const 4) - ) - (i32.const 0x14144020) - ) - ) + (func (export "deploy")) - ;; Load the second key and assert that it doesn't exist. - (call $assert - (i32.eq - (call $ext_get_runtime_storage - (i32.const 20) - (i32.const 4) - ) - (i32.const 1) - ) + (func (export "call") + (call $seal_terminate + (i32.const 0) ;; Pointer to "account" address. + (i32.const 4) ;; Length of "account" address (too small -> decode fail). ) ) - - ;; The first key, 4 bytes long. - (data (i32.const 16) "\01\02\03\04") - ;; The second key, 4 bytes long. - (data (i32.const 20) "\02\03\04\05") ) "#; #[test] - fn get_runtime_storage() { - let mut gas_meter = GasMeter::new(GAS_LIMIT); - let mock_ext = MockExt::default(); - - // "\01\02\03\04" - Some(0x14144020) - // "\02\03\04\05" - None - *mock_ext.runtime_storage_keys.borrow_mut() = [ - ([1, 2, 3, 4].to_vec(), Some(0x14144020u32.to_le_bytes().to_vec())), - ([2, 3, 4, 5].to_vec().to_vec(), None), - ] - .iter() - .cloned() - .collect(); - let _ = execute( - CODE_GET_RUNTIME_STORAGE, + fn contract_decode_failure() { + let mut mock_ext = MockExt::default(); + let result = execute( + CODE_DECODE_FAILURE, vec![], - mock_ext, - &mut gas_meter, - ).unwrap(); + &mut mock_ext, + &mut GasMeter::new(GAS_LIMIT), + ); + + assert_eq!( + result, + Err(ExecError { + error: Error::::DecodingFailed.into(), + origin: ErrorOrigin::Caller, + }) + ); } + } diff --git a/frame/contracts/src/wasm/prepare.rs b/frame/contracts/src/wasm/prepare.rs index ba934f353ec250340fd2bd1c14f69e6ee251379f..97cb06fa26042a13bf9b887ef816bb82a76e9324 100644 --- a/frame/contracts/src/wasm/prepare.rs +++ b/frame/contracts/src/wasm/prepare.rs @@ -28,6 +28,14 @@ use pwasm_utils::rules; use sp_std::prelude::*; use sp_runtime::traits::{SaturatedConversion}; +/// Currently, all imported functions must be located inside this module. We might support +/// additional modules for versioning later. +pub const IMPORT_MODULE_FN: &str = "seal0"; + +/// Imported memory must be located inside this module. The reason for that is that current +/// compiler toolchains might not support specifying other modules than "env" for memory imports. +pub const IMPORT_MODULE_MEMORY: &str = "env"; + struct ContractModule<'a> { /// A deserialized module. The module is valid (this is Guaranteed by `new` method). module: elements::Module, @@ -146,8 +154,11 @@ impl<'a> ContractModule<'a> { .with_grow_cost(self.schedule.grow_mem_cost.clone().saturated_into()) .with_forbidden_floats(); - let contract_module = pwasm_utils::inject_gas_counter(self.module, &gas_rules) - .map_err(|_| "gas instrumentation failed")?; + let contract_module = pwasm_utils::inject_gas_counter( + self.module, + &gas_rules, + IMPORT_MODULE_FN + ).map_err(|_| "gas instrumentation failed")?; Ok(ContractModule { module: contract_module, schedule: self.schedule, @@ -227,11 +238,7 @@ impl<'a> ContractModule<'a> { }; // Then check the signature. - // Both "call" and "deploy" has a [] -> [] or [] -> [i32] function type. - // - // The [] -> [] signature predates the [] -> [i32] signature and is supported for - // backwards compatibility. This will likely be removed once ink! is updated to - // generate modules with the new function signatures. + // Both "call" and "deploy" has a () -> () function type. let func_ty_idx = func_entries.get(fn_idx as usize) .ok_or_else(|| "export refers to non-existent function")? .type_ref(); @@ -274,17 +281,19 @@ impl<'a> ContractModule<'a> { let mut imported_mem_type = None; for import in import_entries { - if import.module() != "env" { - // This import tries to import something from non-"env" module, - // but all imports are located in "env" at the moment. - return Err("module has imports from a non-'env' namespace"); - } - let type_idx = match import.external() { &External::Table(_) => return Err("Cannot import tables"), &External::Global(_) => return Err("Cannot import globals"), - &External::Function(ref type_idx) => type_idx, + &External::Function(ref type_idx) => { + if import.module() != IMPORT_MODULE_FN { + return Err("Invalid module for imported function"); + } + type_idx + }, &External::Memory(ref memory_type) => { + if import.module() != IMPORT_MODULE_MEMORY { + return Err("Invalid module for imported memory"); + } if import.field() != "memory" { return Err("Memory import must have the field name 'memory'") } @@ -300,10 +309,10 @@ impl<'a> ContractModule<'a> { .get(*type_idx as usize) .ok_or_else(|| "validation: import entry points to a non-existent type")?; - // We disallow importing `ext_println` unless debug features are enabled, + // We disallow importing `seal_println` unless debug features are enabled, // which should only be allowed on a dev chain - if !self.schedule.enable_println && import.field().as_bytes() == b"ext_println" { - return Err("module imports `ext_println` but debug features disabled"); + if !self.schedule.enable_println && import.field().as_bytes() == b"seal_println" { + return Err("module imports `seal_println` but debug features disabled"); } // We disallow importing `gas` function here since it is treated as implementation detail. @@ -395,7 +404,6 @@ mod tests { use super::*; use crate::exec::Ext; use std::fmt; - use wabt; use assert_matches::assert_matches; impl fmt::Debug for PrefabWasmModule { @@ -414,14 +422,14 @@ mod tests { nop(_ctx, _unused: u64) => { unreachable!(); }, - ext_println(_ctx, _ptr: u32, _len: u32) => { unreachable!(); }, + seal_println(_ctx, _ptr: u32, _len: u32) => { unreachable!(); }, ); macro_rules! prepare_test { ($name:ident, $wat:expr, $($expected:tt)*) => { #[test] fn $name() { - let wasm = wabt::Wat2Wasm::new().validate(false).convert($wat).unwrap(); + let wasm = wat::parse_str($wat).unwrap(); let schedule = Schedule::default(); let r = prepare_contract::(wasm.as_ref(), &schedule); assert_matches!(r, $($expected)*); @@ -553,7 +561,7 @@ mod tests { prepare_test!(table_import, r#" (module - (import "env" "table" (table 1 anyfunc)) + (import "seal0" "table" (table 1 anyfunc)) (func (export "call")) (func (export "deploy")) @@ -565,7 +573,7 @@ mod tests { prepare_test!(global_import, r#" (module - (global $g (import "env" "global") i32) + (global $g (import "seal0" "global") i32) (func (export "call")) (func (export "deploy")) ) @@ -623,7 +631,7 @@ mod tests { prepare_test!(can_import_legit_function, r#" (module - (import "env" "nop" (func (param i64))) + (import "seal0" "nop" (func (param i64))) (func (export "call")) (func (export "deploy")) @@ -637,7 +645,7 @@ mod tests { prepare_test!(can_not_import_gas_function, r#" (module - (import "env" "gas" (func (param i32))) + (import "seal0" "gas" (func (param i32))) (func (export "call")) (func (export "deploy")) @@ -646,24 +654,63 @@ mod tests { Err("module imports a non-existent function") ); - // nothing can be imported from non-"env" module for now. - prepare_test!(non_env_import, + // memory is in "env" and not in "seal0" + prepare_test!(memory_not_in_seal0, + r#" + (module + (import "seal0" "memory" (memory 1 1)) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("Invalid module for imported memory") + ); + + // memory is in "env" and not in some arbitrary module + prepare_test!(memory_not_in_arbitrary_module, + r#" + (module + (import "any_module" "memory" (memory 1 1)) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("Invalid module for imported memory") + ); + + // functions are in "env" and not in "seal0" + prepare_test!(function_not_in_env, + r#" + (module + (import "env" "nop" (func (param i64))) + + (func (export "call")) + (func (export "deploy")) + ) + "#, + Err("Invalid module for imported function") + ); + + // functions are in "seal0" and not in in some arbitrary module + prepare_test!(function_not_arbitrary_module, r#" (module - (import "another_module" "memory" (memory 1 1)) + (import "any_module" "nop" (func (param i64))) (func (export "call")) (func (export "deploy")) ) "#, - Err("module has imports from a non-'env' namespace") + Err("Invalid module for imported function") ); // wrong signature prepare_test!(wrong_signature, r#" (module - (import "env" "gas" (func (param i64))) + (import "seal0" "gas" (func (param i64))) (func (export "call")) (func (export "deploy")) @@ -675,7 +722,7 @@ mod tests { prepare_test!(unknown_func_name, r#" (module - (import "env" "unknown_func" (func)) + (import "seal0" "unknown_func" (func)) (func (export "call")) (func (export "deploy")) @@ -684,24 +731,24 @@ mod tests { Err("module imports a non-existent function") ); - prepare_test!(ext_println_debug_disabled, + prepare_test!(seal_println_debug_disabled, r#" (module - (import "env" "ext_println" (func $ext_println (param i32 i32))) + (import "seal0" "seal_println" (func $seal_println (param i32 i32))) (func (export "call")) (func (export "deploy")) ) "#, - Err("module imports `ext_println` but debug features disabled") + Err("module imports `seal_println` but debug features disabled") ); #[test] - fn ext_println_debug_enabled() { - let wasm = wabt::Wat2Wasm::new().validate(false).convert( + fn seal_println_debug_enabled() { + let wasm = wat::parse_str( r#" (module - (import "env" "ext_println" (func $ext_println (param i32 i32))) + (import "seal0" "seal_println" (func $seal_println (param i32 i32))) (func (export "call")) (func (export "deploy")) @@ -750,7 +797,7 @@ mod tests { prepare_test!(try_sneak_export_as_entrypoint, r#" (module - (import "env" "panic" (func)) + (import "seal0" "panic" (func)) (func (export "deploy")) diff --git a/frame/contracts/src/wasm/runtime.rs b/frame/contracts/src/wasm/runtime.rs index f87f5d1ef53cc962ee88cad097b6e524259d6f54..806c956d292a038d1fe39f2d141a4ae3cbcc5cd2 100644 --- a/frame/contracts/src/wasm/runtime.rs +++ b/frame/contracts/src/wasm/runtime.rs @@ -16,14 +16,17 @@ //! Environment definition of the wasm smart-contract runtime. -use crate::{Schedule, Trait, CodeHash, BalanceOf}; +use crate::{Schedule, Trait, CodeHash, BalanceOf, Error}; use crate::exec::{ - Ext, ExecResult, ExecError, ExecReturnValue, StorageKey, TopicOf, STATUS_SUCCESS, + Ext, ExecResult, ExecReturnValue, StorageKey, TopicOf, ReturnFlags, ExecError }; use crate::gas::{Gas, GasMeter, Token, GasMeterResult}; +use crate::wasm::env_def::ConvertibleToWasm; use sp_sandbox; +use parity_wasm::elements::ValueType; use frame_system; -use sp_std::{prelude::*, mem, convert::TryInto}; +use frame_support::dispatch::DispatchError; +use sp_std::prelude::*; use codec::{Decode, Encode}; use sp_runtime::traits::{Bounded, SaturatedConversion}; use sp_io::hashing::{ @@ -32,35 +35,94 @@ use sp_io::hashing::{ blake2_128, sha2_256, }; -use frame_support::weights::GetDispatchInfo; -/// The value returned from ext_call and ext_instantiate contract external functions if the call or -/// instantiation traps. This value is chosen as if the execution does not trap, the return value -/// will always be an 8-bit integer, so 0x0100 is the smallest value that could not be returned. -const TRAP_RETURN_CODE: u32 = 0x0100; +/// Every error that can be returned to a contract when it calls any of the host functions. +#[repr(u32)] +pub enum ReturnCode { + /// API call successful. + Success = 0, + /// The called function trapped and has its state changes reverted. + /// In this case no output buffer is returned. + CalleeTrapped = 1, + /// The called function ran to completion but decided to revert its state. + /// An output buffer is returned when one was supplied. + CalleeReverted = 2, + /// The passed key does not exist in storage. + KeyNotFound = 3, + /// Transfer failed because it would have brought the sender's total balance below the + /// subsistence threshold. + BelowSubsistenceThreshold = 4, + /// Transfer failed for other reasons. Most probably reserved or locked balance of the + /// sender prevents the transfer. + TransferFailed = 5, + /// The newly created contract is below the subsistence threshold after executing + /// its constructor. + NewContractNotFunded = 6, + /// No code could be found at the supplied code hash. + CodeNotFound = 7, + /// The contract that was called is either no contract at all (a plain account) + /// or is a tombstone. + NotCallable = 8, +} -/// Enumerates all possible *special* trap conditions. +impl ConvertibleToWasm for ReturnCode { + type NativeType = Self; + const VALUE_TYPE: ValueType = ValueType::I32; + fn to_typed_value(self) -> sp_sandbox::Value { + sp_sandbox::Value::I32(self as i32) + } + fn from_typed_value(_: sp_sandbox::Value) -> Option { + debug_assert!(false, "We will never receive a ReturnCode but only send it to wasm."); + None + } +} + +impl From for ReturnCode { + fn from(from: ExecReturnValue) -> Self { + if from.flags.contains(ReturnFlags::REVERT) { + Self::CalleeReverted + } else { + Self::Success + } + } +} + +/// The data passed through when a contract uses `seal_return`. +struct ReturnData { + /// The flags as passed through by the contract. They are still unchecked and + /// will later be parsed into a `ReturnFlags` bitflags struct. + flags: u32, + /// The output buffer passed by the contract as return data. + data: Vec, +} + +/// Enumerates all possible reasons why a trap was generated. /// -/// In this runtime traps used not only for signaling about errors but also -/// to just terminate quickly in some cases. -enum SpecialTrap { - /// Signals that trap was generated in response to call `ext_return` host function. - Return(Vec), - /// Signals that trap was generated because the contract exhausted its gas limit. - OutOfGas, - /// Signals that a trap was generated in response to a succesful call to the - /// `ext_terminate` host function. +/// This is either used to supply the caller with more information about why an error +/// occurred (the SupervisorError variant). +/// The other case is where the trap does not constitute an error but rather was invoked +/// as a quick way to terminate the application (all other variants). +enum TrapReason { + /// The supervisor trapped the contract because of an error condition occurred during + /// execution in privileged code. + SupervisorError(DispatchError), + /// Signals that trap was generated in response to call `seal_return` host function. + Return(ReturnData), + /// Signals that a trap was generated in response to a successful call to the + /// `seal_terminate` host function. Termination, + /// Signals that a trap was generated because of a successful restoration. + Restoration, } /// Can only be used for one call. pub(crate) struct Runtime<'a, E: Ext + 'a> { ext: &'a mut E, - scratch_buf: Vec, + input_data: Option>, schedule: &'a Schedule, memory: sp_sandbox::Memory, gas_meter: &'a mut GasMeter, - special_trap: Option, + trap_reason: Option, } impl<'a, E: Ext + 'a> Runtime<'a, E> { pub(crate) fn new( @@ -72,61 +134,59 @@ impl<'a, E: Ext + 'a> Runtime<'a, E> { ) -> Self { Runtime { ext, - // Put the input data into the scratch buffer immediately. - scratch_buf: input_data, + input_data: Some(input_data), schedule, memory, gas_meter, - special_trap: None, + trap_reason: None, } } } +/// Converts the sandbox result and the runtime state into the execution outcome. +/// +/// It evaluates information stored in the `trap_reason` variable of the runtime and +/// bases the outcome on the value if this variable. Only if `trap_reason` is `None` +/// the result of the sandbox is evaluated. pub(crate) fn to_execution_result( runtime: Runtime, sandbox_result: Result, ) -> ExecResult { - match runtime.special_trap { - // The trap was the result of the execution `return` host function. - Some(SpecialTrap::Return(data)) => { - return Ok(ExecReturnValue { - status: STATUS_SUCCESS, - data, - }) - }, - Some(SpecialTrap::Termination) => { - return Ok(ExecReturnValue { - status: STATUS_SUCCESS, - data: Vec::new(), - }) - }, - Some(SpecialTrap::OutOfGas) => { - return Err(ExecError { - reason: "ran out of gas during contract execution".into(), - buffer: runtime.scratch_buf, - }) - }, - None => (), + // If a trap reason is set we base our decision solely on that. + if let Some(trap_reason) = runtime.trap_reason { + return match trap_reason { + // The trap was the result of the execution `return` host function. + TrapReason::Return(ReturnData{ flags, data }) => { + let flags = ReturnFlags::from_bits(flags).ok_or_else(|| + "used reserved bit in return flags" + )?; + Ok(ExecReturnValue { + flags, + data, + }) + }, + TrapReason::Termination => { + Ok(ExecReturnValue { + flags: ReturnFlags::empty(), + data: Vec::new(), + }) + }, + TrapReason::Restoration => { + Ok(ExecReturnValue { + flags: ReturnFlags::empty(), + data: Vec::new(), + }) + }, + TrapReason::SupervisorError(error) => Err(error)?, + } } // Check the exact type of the error. match sandbox_result { // No traps were generated. Proceed normally. - Ok(sp_sandbox::ReturnValue::Unit) => { - let mut buffer = runtime.scratch_buf; - buffer.clear(); - Ok(ExecReturnValue { status: STATUS_SUCCESS, data: buffer }) + Ok(_) => { + Ok(ExecReturnValue { flags: ReturnFlags::empty(), data: Vec::new() }) } - Ok(sp_sandbox::ReturnValue::Value(sp_sandbox::Value::I32(exit_code))) => { - let status = (exit_code & 0xFF).try_into() - .expect("exit_code is masked into the range of a u8; qed"); - Ok(ExecReturnValue { status, data: runtime.scratch_buf }) - } - // This should never happen as the return type of exported functions should have been - // validated by the code preparation process. However, because panics are really - // undesirable in the runtime code, we treat this as a trap for now. Eventually, we might - // want to revisit this. - Ok(_) => Err(ExecError { reason: "return type error".into(), buffer: runtime.scratch_buf }), // `Error::Module` is returned only if instantiation or linking failed (i.e. // wasm binary tried to import a function that is not provided by the host). // This shouldn't happen because validation process ought to reject such binaries. @@ -134,10 +194,10 @@ pub(crate) fn to_execution_result( // Because panics are really undesirable in the runtime code, we treat this as // a trap for now. Eventually, we might want to revisit this. Err(sp_sandbox::Error::Module) => - Err(ExecError { reason: "validation error".into(), buffer: runtime.scratch_buf }), + Err("validation error")?, // Any other kind of a trap should result in a failure. Err(sp_sandbox::Error::Execution) | Err(sp_sandbox::Error::OutOfBounds) => - Err(ExecError { reason: "contract trapped during execution".into(), buffer: runtime.scratch_buf }), + Err(Error::::ContractTrapped)? } } @@ -154,8 +214,6 @@ pub enum RuntimeToken { /// The given number of bytes is read from the sandbox memory and /// is returned as the return data buffer of the call. ReturnData(u32), - /// Dispatched a call with the given weight. - DispatchWithWeight(Gas), /// (topic_count, data_bytes): A buffer of the given size is posted as an event indexed with the /// given number of topics. DepositEvent(u32, u32), @@ -196,7 +254,6 @@ impl Token for RuntimeToken { data_and_topics_cost.checked_add(metadata.event_base_cost) ) }, - DispatchWithWeight(gas) => gas.checked_add(metadata.dispatch_base_cost), }; value.unwrap_or_else(|| Bounded::max_value()) @@ -209,13 +266,13 @@ impl Token for RuntimeToken { fn charge_gas>( gas_meter: &mut GasMeter, metadata: &Tok::Metadata, - special_trap: &mut Option, + trap_reason: &mut Option, token: Tok, ) -> Result<(), sp_sandbox::HostError> { match gas_meter.charge(metadata, token) { GasMeterResult::Proceed => Ok(()), GasMeterResult::OutOfGas => { - *special_trap = Some(SpecialTrap::OutOfGas); + *trap_reason = Some(TrapReason::SupervisorError(Error::::OutOfGas.into())); Err(sp_sandbox::HostError) }, } @@ -237,40 +294,16 @@ fn read_sandbox_memory( charge_gas( ctx.gas_meter, ctx.schedule, - &mut ctx.special_trap, + &mut ctx.trap_reason, RuntimeToken::ReadMemory(len), )?; let mut buf = vec![0u8; len as usize]; - ctx.memory.get(ptr, buf.as_mut_slice()).map_err(|_| sp_sandbox::HostError)?; + ctx.memory.get(ptr, buf.as_mut_slice()) + .map_err(|_| store_err(ctx, Error::::OutOfBounds))?; Ok(buf) } -/// Read designated chunk from the sandbox memory into the scratch buffer, consuming an -/// appropriate amount of gas. Resizes the scratch buffer to the specified length on success. -/// -/// Returns `Err` if one of the following conditions occurs: -/// -/// - calculating the gas cost resulted in overflow. -/// - out of gas -/// - requested buffer is not within the bounds of the sandbox memory. -fn read_sandbox_memory_into_scratch( - ctx: &mut Runtime, - ptr: u32, - len: u32, -) -> Result<(), sp_sandbox::HostError> { - charge_gas( - ctx.gas_meter, - ctx.schedule, - &mut ctx.special_trap, - RuntimeToken::ReadMemory(len), - )?; - - ctx.scratch_buf.resize(len as usize, 0); - ctx.memory.get(ptr, ctx.scratch_buf.as_mut_slice()).map_err(|_| sp_sandbox::HostError)?; - Ok(()) -} - /// Read designated chunk from the sandbox memory into the supplied buffer, consuming /// an appropriate amount of gas. /// @@ -287,11 +320,11 @@ fn read_sandbox_memory_into_buf( charge_gas( ctx.gas_meter, ctx.schedule, - &mut ctx.special_trap, + &mut ctx.trap_reason, RuntimeToken::ReadMemory(buf.len() as u32), )?; - ctx.memory.get(ptr, buf).map_err(Into::into) + ctx.memory.get(ptr, buf).map_err(|_| store_err(ctx, Error::::OutOfBounds)) } /// Read designated chunk from the sandbox memory, consuming an appropriate amount of @@ -309,7 +342,7 @@ fn read_sandbox_memory_as( len: u32, ) -> Result { let buf = read_sandbox_memory(ctx, ptr, len)?; - D::decode(&mut &buf[..]).map_err(|_| sp_sandbox::HostError) + D::decode(&mut &buf[..]).map_err(|_| store_err(ctx, Error::::DecodingFailed)) } /// Write the given buffer to the designated location in the sandbox memory, consuming @@ -320,32 +353,158 @@ fn read_sandbox_memory_as( /// - calculating the gas cost resulted in overflow. /// - out of gas /// - designated area is not within the bounds of the sandbox memory. -fn write_sandbox_memory( - schedule: &Schedule, - special_trap: &mut Option, - gas_meter: &mut GasMeter, - memory: &sp_sandbox::Memory, +fn write_sandbox_memory( + ctx: &mut Runtime, ptr: u32, buf: &[u8], ) -> Result<(), sp_sandbox::HostError> { charge_gas( - gas_meter, - schedule, - special_trap, + ctx.gas_meter, + ctx.schedule, + &mut ctx.trap_reason, RuntimeToken::WriteMemory(buf.len() as u32), )?; - memory.set(ptr, buf)?; + ctx.memory.set(ptr, buf) + .map_err(|_| store_err(ctx, Error::::OutOfBounds)) +} + +/// Write the given buffer and its length to the designated locations in sandbox memory. +// +/// `out_ptr` is the location in sandbox memory where `buf` should be written to. +/// `out_len_ptr` is an in-out location in sandbox memory. It is read to determine the +/// lenght of the buffer located at `out_ptr`. If that buffer is large enough the actual +/// `buf.len()` is written to this location. +/// +/// If `out_ptr` is set to the sentinel value of `u32::max_value()` and `allow_skip` is true the +/// operation is skipped and `Ok` is returned. This is supposed to help callers to make copying +/// output optional. For example to skip copying back the output buffer of an `seal_call` +/// when the caller is not interested in the result. +/// +/// In addition to the error conditions of `write_sandbox_memory` this functions returns +/// `Err` if the size of the buffer located at `out_ptr` is too small to fit `buf`. +fn write_sandbox_output( + ctx: &mut Runtime, + out_ptr: u32, + out_len_ptr: u32, + buf: &[u8], + allow_skip: bool, +) -> Result<(), sp_sandbox::HostError> { + if allow_skip && out_ptr == u32::max_value() { + return Ok(()); + } + + let buf_len = buf.len() as u32; + let len: u32 = read_sandbox_memory_as(ctx, out_len_ptr, 4)?; + + if len < buf_len { + Err(store_err(ctx, Error::::OutputBufferTooSmall))? + } + + charge_gas( + ctx.gas_meter, + ctx.schedule, + &mut ctx.trap_reason, + RuntimeToken::WriteMemory(buf_len.saturating_add(4)), + )?; + + ctx.memory.set(out_ptr, buf)?; + ctx.memory.set(out_len_ptr, &buf_len.encode())?; Ok(()) } +/// Stores a DispatchError returned from an Ext function into the trap_reason. +/// +/// This allows through supervisor generated errors to the caller. +fn store_err(ctx: &mut Runtime, err: Error) -> sp_sandbox::HostError where + E: Ext, + Error: Into, +{ + ctx.trap_reason = Some(TrapReason::SupervisorError(err.into())); + sp_sandbox::HostError +} + +/// Fallible conversion of `DispatchError` to `ReturnCode`. +fn err_into_return_code(from: DispatchError) -> Result { + use ReturnCode::*; + + let below_sub = Error::::BelowSubsistenceThreshold.into(); + let transfer_failed = Error::::TransferFailed.into(); + let not_funded = Error::::NewContractNotFunded.into(); + let no_code = Error::::CodeNotFound.into(); + let invalid_contract = Error::::NotCallable.into(); + + match from { + x if x == below_sub => Ok(BelowSubsistenceThreshold), + x if x == transfer_failed => Ok(TransferFailed), + x if x == not_funded => Ok(NewContractNotFunded), + x if x == no_code => Ok(CodeNotFound), + x if x == invalid_contract => Ok(NotCallable), + err => Err(err) + } +} + +/// Fallible conversion of a `ExecResult` to `ReturnCode`. +fn exec_into_return_code(from: ExecResult) -> Result { + use crate::exec::ErrorOrigin::Callee; + + let ExecError { error, origin } = match from { + Ok(retval) => return Ok(retval.into()), + Err(err) => err, + }; + + match (error, origin) { + (_, Callee) => Ok(ReturnCode::CalleeTrapped), + (err, _) => err_into_return_code::(err) + } +} + +/// Used by Runtime API that calls into other contracts. +/// +/// Those need to transform the the `ExecResult` returned from the execution into +/// a `ReturnCode`. If this conversion fails because the `ExecResult` constitutes a +/// a fatal error then this error is stored in the `ExecutionContext` so it can be +/// extracted for display in the UI. +fn map_exec_result(ctx: &mut Runtime, result: ExecResult) + -> Result +{ + match exec_into_return_code::(result) { + Ok(code) => Ok(code), + Err(err) => Err(store_err(ctx, err)), + } +} + +/// Try to convert an error into a `ReturnCode`. +/// +/// Used to decide between fatal and non-fatal errors. +fn map_dispatch_result(ctx: &mut Runtime, result: Result) + -> Result +{ + let err = if let Err(err) = result { + err + } else { + return Ok(ReturnCode::Success) + }; + + match err_into_return_code::(err) { + Ok(code) => Ok(code), + Err(err) => Err(store_err(ctx, err)), + } +} + // *********************************************************** // * AFTER MAKING A CHANGE MAKE SURE TO UPDATE COMPLEXITY.MD * // *********************************************************** // Define a function `fn init_env() -> HostFunctionSet` that returns // a function set which can be imported by an executed contract. +// +// # Note +// +// Any input that leads to a out of bound error (reading or writing) or failing to decode +// data passed to the supervisor will lead to a trap. This is not documented explicitly +// for every function. define_env!(Env, , // Account for used gas. Traps if gas used is greater than gas limit. @@ -358,7 +517,7 @@ define_env!(Env, , charge_gas( &mut ctx.gas_meter, ctx.schedule, - &mut ctx.special_trap, + &mut ctx.trap_reason, RuntimeToken::Explicit(amount) )?; Ok(()) @@ -375,11 +534,11 @@ define_env!(Env, , // - `value_ptr`: pointer into the linear memory where the value to set is placed. // - `value_len`: the length of the value in bytes. // - // # Errors + // # Traps // // - If value length exceeds the configured maximum value length of a storage entry. // - Upon trying to set an empty storage entry (value length is 0). - ext_set_storage(ctx, key_ptr: u32, value_ptr: u32, value_len: u32) => { + seal_set_storage(ctx, key_ptr: u32, value_ptr: u32, value_len: u32) => { if value_len > ctx.ext.max_value_size() { // Bail out if value length exceeds the set maximum value size. return Err(sp_sandbox::HostError); @@ -387,7 +546,7 @@ define_env!(Env, , let mut key: StorageKey = [0; 32]; read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?; let value = Some(read_sandbox_memory(ctx, value_ptr, value_len)?); - ctx.ext.set_storage(key, value).map_err(|_| sp_sandbox::HostError)?; + ctx.ext.set_storage(key, value); Ok(()) }, @@ -396,36 +555,39 @@ define_env!(Env, , // # Parameters // // - `key_ptr`: pointer into the linear memory where the location to clear the value is placed. - ext_clear_storage(ctx, key_ptr: u32) => { + seal_clear_storage(ctx, key_ptr: u32) => { let mut key: StorageKey = [0; 32]; read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?; - ctx.ext.set_storage(key, None).map_err(|_| sp_sandbox::HostError)?; + ctx.ext.set_storage(key, None); Ok(()) }, - // Retrieve the value under the given key from the storage and return 0. - // If there is no entry under the given key then this function will return 1 and - // clear the scratch buffer. + // Retrieve the value under the given key from storage. + // + // # Parameters + // + // - `key_ptr`: pointer into the linear memory where the key of the requested value is placed. + // - `out_ptr`: pointer to the linear memory where the value is written to. + // - `out_len_ptr`: in-out pointer into linear memory where the buffer length + // is read from and the value length is written to. // - // - key_ptr: pointer into the linear memory where the key - // of the requested value is placed. - ext_get_storage(ctx, key_ptr: u32) -> u32 => { + // # Errors + // + // `ReturnCode::KeyNotFound` + seal_get_storage(ctx, key_ptr: u32, out_ptr: u32, out_len_ptr: u32) -> ReturnCode => { let mut key: StorageKey = [0; 32]; read_sandbox_memory_into_buf(ctx, key_ptr, &mut key)?; if let Some(value) = ctx.ext.get_storage(&key) { - ctx.scratch_buf = value; - Ok(0) + write_sandbox_output(ctx, out_ptr, out_len_ptr, &value, false)?; + Ok(ReturnCode::Success) } else { - ctx.scratch_buf.clear(); - Ok(1) + Ok(ReturnCode::KeyNotFound) } }, // Transfer some value to another account. // - // If the value transfer was succesful zero is returned. Otherwise one is returned. - // The scratch buffer is not touched. The receiver can be a plain account or - // a contract. + // # Parameters // // - account_ptr: a pointer to the address of the beneficiary account // Should be decodable as an `T::AccountId`. Traps otherwise. @@ -433,38 +595,34 @@ define_env!(Env, , // - value_ptr: a pointer to the buffer with value, how much value to send. // Should be decodable as a `T::Balance`. Traps otherwise. // - value_len: length of the value buffer. - ext_transfer( + // + // # Errors + // + // `ReturnCode::BelowSubsistenceThreshold` + // `ReturnCode::TransferFailed` + seal_transfer( ctx, account_ptr: u32, account_len: u32, value_ptr: u32, value_len: u32 - ) -> u32 => { + ) -> ReturnCode => { let callee: <::T as frame_system::Trait>::AccountId = read_sandbox_memory_as(ctx, account_ptr, account_len)?; let value: BalanceOf<::T> = read_sandbox_memory_as(ctx, value_ptr, value_len)?; - match ctx.ext.transfer(&callee, value, ctx.gas_meter) { - Ok(_) => Ok(0), - Err(_) => Ok(1), - } + let result = ctx.ext.transfer(&callee, value, ctx.gas_meter); + map_dispatch_result(ctx, result) }, // Make a call to another contract. // - // If the called contract runs to completion, then this returns the status code the callee - // returns on exit in the bottom 8 bits of the return value. The top 24 bits are 0s. A status - // code of 0 indicates success, and any other code indicates a failure. On failure, any state - // changes made by the called contract are reverted. The scratch buffer is filled with the - // output data returned by the called contract, even in the case of a failure status. + // The callees output buffer is copied to `output_ptr` and its length to `output_len_ptr`. + // The copy of the output buffer can be skipped by supplying the sentinel value + // of `u32::max_value()` to `output_ptr`. // - // This call fails if it would bring the calling contract below the existential deposit. - // In order to destroy a contract `ext_terminate` must be used. - // - // If the contract traps during execution or otherwise fails to complete successfully, then - // this function clears the scratch buffer and returns 0x0100. As with a failure status, any - // state changes made by the called contract are reverted. + // # Parameters // // - callee_ptr: a pointer to the address of the callee contract. // Should be decodable as an `T::AccountId`. Traps otherwise. @@ -475,7 +633,21 @@ define_env!(Env, , // - value_len: length of the value buffer. // - input_data_ptr: a pointer to a buffer to be used as input data to the callee. // - input_data_len: length of the input data buffer. - ext_call( + // - output_ptr: a pointer where the output buffer is copied to. + // - output_len_ptr: in-out pointer to where the length of the buffer is read from + // and the actual length is written to. + // + // # Errors + // + // An error means that the call wasn't successful output buffer is returned unless + // stated otherwise. + // + // `ReturnCode::CalleeReverted`: Output buffer is returned. + // `ReturnCode::CalleeTrapped` + // `ReturnCode::BelowSubsistenceThreshold` + // `ReturnCode::TransferFailed` + // `ReturnCode::NotCallable` + seal_call( ctx, callee_ptr: u32, callee_len: u32, @@ -483,16 +655,14 @@ define_env!(Env, , value_ptr: u32, value_len: u32, input_data_ptr: u32, - input_data_len: u32 - ) -> u32 => { + input_data_len: u32, + output_ptr: u32, + output_len_ptr: u32 + ) -> ReturnCode => { let callee: <::T as frame_system::Trait>::AccountId = read_sandbox_memory_as(ctx, callee_ptr, callee_len)?; - let value: BalanceOf<::T> = - read_sandbox_memory_as(ctx, value_ptr, value_len)?; - - // Read input data into the scratch buffer, then take ownership of it. - read_sandbox_memory_into_scratch(ctx, input_data_ptr, input_data_len)?; - let input_data = mem::replace(&mut ctx.scratch_buf, Vec::new()); + let value: BalanceOf<::T> = read_sandbox_memory_as(ctx, value_ptr, value_len)?; + let input_data = read_sandbox_memory(ctx, input_data_ptr, input_data_len)?; let nested_gas_limit = if gas == 0 { ctx.gas_meter.gas_left() @@ -509,52 +679,31 @@ define_env!(Env, , nested_meter, input_data, ) - .map_err(|err| err.buffer) } // there is not enough gas to allocate for the nested call. - None => Err(input_data), + None => Err(Error::<::T>::OutOfGas.into()), } }); - match call_outcome { - Ok(output) => { - ctx.scratch_buf = output.data; - Ok(output.status.into()) - }, - Err(buffer) => { - ctx.scratch_buf = buffer; - ctx.scratch_buf.clear(); - Ok(TRAP_RETURN_CODE) - }, + if let Ok(output) = &call_outcome { + write_sandbox_output(ctx, output_ptr, output_len_ptr, &output.data, true)?; } + map_exec_result(ctx, call_outcome) }, // Instantiate a contract with the specified code hash. // // This function creates an account and executes the constructor defined in the code specified - // by the code hash. - // - // If the constructor runs to completion, then this returns the status code that the newly - // instantiated contract returns on exit in the bottom 8 bits of the return value. The top 24 - // bits are 0s. A status code of 0 indicates success, and any other code indicates a failure. - // On failure, any state changes made by the called contract are reverted and the contract is - // not instantiated. On a success status, the scratch buffer is filled with the encoded address - // of the newly instantiated contract. In the case of a failure status, the scratch buffer is - // cleared. + // by the code hash. The address of this new account is copied to `address_ptr` and its length + // to `address_len_ptr`. The constructors output buffer is copied to `output_ptr` and its + // length to `output_len_ptr`. The copy of the output buffer and address can be skipped by + // supplying the sentinel value of `u32::max_value()` to `output_ptr` or `address_ptr`. // - // This call fails if it would bring the calling contract below the existential deposit. - // In order to destroy a contract `ext_terminate` must be used. + // After running the constructor it is verfied that the contract account holds at + // least the subsistence threshold. If that is not the case the instantion fails and + // the contract is not created. // - // If the contract traps during execution or otherwise fails to complete successfully, then - // this function clears the scratch buffer and returns 0x0100. As with a failure status, any - // state changes made by the called contract are reverted. - - // This function creates an account and executes initializer code. After the execution, - // the returned buffer is saved as the code of the created account. - // - // Returns 0 on the successful contract instantiation and puts the address of the instantiated - // contract into the scratch buffer. Otherwise, returns non-zero value and clears the scratch - // buffer. + // # Parameters // // - code_hash_ptr: a pointer to the buffer that contains the initializer code. // - code_hash_len: length of the initializer code buffer. @@ -564,7 +713,28 @@ define_env!(Env, , // - value_len: length of the value buffer. // - input_data_ptr: a pointer to a buffer to be used as input data to the initializer code. // - input_data_len: length of the input data buffer. - ext_instantiate( + // - address_ptr: a pointer where the new account's address is copied to. + // - address_len_ptr: in-out pointer to where the length of the buffer is read from + // and the actual length is written to. + // - output_ptr: a pointer where the output buffer is copied to. + // - output_len_ptr: in-out pointer to where the length of the buffer is read from + // and the actual length is written to. + // + // # Errors + // + // Please consult the `ReturnCode` enum declaration for more information on those + // errors. Here we only note things specific to this function. + // + // An error means that the account wasn't created and no address or output buffer + // is returned unless stated otherwise. + // + // `ReturnCode::CalleeReverted`: Output buffer is returned. + // `ReturnCode::CalleeTrapped` + // `ReturnCode::BelowSubsistenceThreshold` + // `ReturnCode::TransferFailed` + // `ReturnCode::NewContractNotFunded` + // `ReturnCode::CodeNotFound` + seal_instantiate( ctx, code_hash_ptr: u32, code_hash_len: u32, @@ -572,16 +742,16 @@ define_env!(Env, , value_ptr: u32, value_len: u32, input_data_ptr: u32, - input_data_len: u32 - ) -> u32 => { + input_data_len: u32, + address_ptr: u32, + address_len_ptr: u32, + output_ptr: u32, + output_len_ptr: u32 + ) -> ReturnCode => { let code_hash: CodeHash<::T> = read_sandbox_memory_as(ctx, code_hash_ptr, code_hash_len)?; - let value: BalanceOf<::T> = - read_sandbox_memory_as(ctx, value_ptr, value_len)?; - - // Read input data into the scratch buffer, then take ownership of it. - read_sandbox_memory_into_scratch(ctx, input_data_ptr, input_data_len)?; - let input_data = mem::replace(&mut ctx.scratch_buf, Vec::new()); + let value: BalanceOf<::T> = read_sandbox_memory_as(ctx, value_ptr, value_len)?; + let input_data = read_sandbox_memory(ctx, input_data_ptr, input_data_len)?; let nested_gas_limit = if gas == 0 { ctx.gas_meter.gas_left() @@ -598,29 +768,20 @@ define_env!(Env, , nested_meter, input_data ) - .map_err(|err| err.buffer) } // there is not enough gas to allocate for the nested call. - None => Err(input_data), + None => Err(Error::<::T>::OutOfGas.into()), } }); - match instantiate_outcome { - Ok((address, output)) => { - let is_success = output.is_success(); - ctx.scratch_buf = output.data; - ctx.scratch_buf.clear(); - if is_success { - // Write the address to the scratch buffer. - address.encode_to(&mut ctx.scratch_buf); - } - Ok(output.status.into()) - }, - Err(buffer) => { - ctx.scratch_buf = buffer; - ctx.scratch_buf.clear(); - Ok(TRAP_RETURN_CODE) - }, + if let Ok((address, output)) = &instantiate_outcome { + if !output.flags.contains(ReturnFlags::REVERT) { + write_sandbox_output( + ctx, address_ptr, address_len_ptr, &address.encode(), true + )?; + } + write_sandbox_output(ctx, output_ptr, output_len_ptr, &output.data, true)?; } + map_exec_result(ctx, instantiate_outcome.map(|(_id, retval)| retval)) }, // Remove the calling account and transfer remaining balance. @@ -633,7 +794,11 @@ define_env!(Env, , // where all remaining funds of the caller are transfered. // Should be decodable as an `T::AccountId`. Traps otherwise. // - beneficiary_len: length of the address buffer. - ext_terminate( + // + // # Traps + // + // - The contract is live i.e is already on the call stack. + seal_terminate( ctx, beneficiary_ptr: u32, beneficiary_len: u32 @@ -642,27 +807,48 @@ define_env!(Env, , read_sandbox_memory_as(ctx, beneficiary_ptr, beneficiary_len)?; if let Ok(_) = ctx.ext.terminate(&beneficiary, ctx.gas_meter) { - ctx.special_trap = Some(SpecialTrap::Termination); + ctx.trap_reason = Some(TrapReason::Termination); } Err(sp_sandbox::HostError) }, - // Save a data buffer as a result of the execution, terminate the execution and return a - // successful result to the caller. + seal_input(ctx, buf_ptr: u32, buf_len_ptr: u32) => { + if let Some(input) = ctx.input_data.take() { + write_sandbox_output(ctx, buf_ptr, buf_len_ptr, &input, false) + } else { + Err(sp_sandbox::HostError) + } + }, + + // Cease contract execution and save a data buffer as a result of the execution. + // + // This function never retuns as it stops execution of the caller. + // This is the only way to return a data buffer to the caller. Returning from + // execution without calling this function is equivalent to calling: + // ``` + // seal_return(0, 0, 0); + // ``` + // + // The flags argument is a bitfield that can be used to signal special return + // conditions to the supervisor: + // --- lsb --- + // bit 0 : REVERT - Revert all storage changes made by the caller. + // bit [1, 31]: Reserved for future use. + // --- msb --- // - // This is the only way to return a data buffer to the caller. - ext_return(ctx, data_ptr: u32, data_len: u32) => { + // Using a reserved bit triggers a trap. + seal_return(ctx, flags: u32, data_ptr: u32, data_len: u32) => { charge_gas( ctx.gas_meter, ctx.schedule, - &mut ctx.special_trap, + &mut ctx.trap_reason, RuntimeToken::ReturnData(data_len) )?; - read_sandbox_memory_into_scratch(ctx, data_ptr, data_len)?; - let output_buf = mem::replace(&mut ctx.scratch_buf, Vec::new()); - - ctx.special_trap = Some(SpecialTrap::Return(output_buf)); + ctx.trap_reason = Some(TrapReason::Return(ReturnData { + flags, + data: read_sandbox_memory(ctx, data_ptr, data_len)?, + })); // The trap mechanism is used to immediately terminate the execution. // This trap should be handled appropriately before returning the result @@ -670,98 +856,131 @@ define_env!(Env, , Err(sp_sandbox::HostError) }, - // Stores the address of the caller into the scratch buffer. + // Stores the address of the caller into the supplied buffer. + // + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. // // If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the // extrinsic will be returned. Otherwise, if this call is initiated by another contract then the - // address of the contract will be returned. - ext_caller(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.caller().encode_to(&mut ctx.scratch_buf); - Ok(()) + // address of the contract will be returned. The value is encoded as T::AccountId. + seal_caller(ctx, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.caller().encode(), false) }, - // Stores the address of the current contract into the scratch buffer. - ext_address(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.address().encode_to(&mut ctx.scratch_buf); - Ok(()) + // Stores the address of the current contract into the supplied buffer. + // + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. + seal_address(ctx, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.address().encode(), false) }, - // Stores the gas price for the current transaction into the scratch buffer. + // Stores the price for the specified amount of gas into the supplied buffer. // - // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. - ext_gas_price(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.get_weight_price().encode_to(&mut ctx.scratch_buf); - Ok(()) + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. + // + // The data is encoded as T::Balance. + // + // # Note + // + // It is recommended to avoid specifying very small values for `gas` as the prices for a single + // gas can be smaller than one. + seal_weight_to_fee(ctx, gas: u64, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output( + ctx, out_ptr, out_len_ptr, &ctx.ext.get_weight_price(gas).encode(), false + ) }, - // Stores the amount of gas left into the scratch buffer. + // Stores the amount of gas left into the supplied buffer. // - // The data is encoded as Gas. The current contents of the scratch buffer are overwritten. - ext_gas_left(ctx) => { - ctx.scratch_buf.clear(); - ctx.gas_meter.gas_left().encode_to(&mut ctx.scratch_buf); - Ok(()) + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. + // + // The data is encoded as Gas. + seal_gas_left(ctx, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.gas_meter.gas_left().encode(), false) }, - // Stores the balance of the current account into the scratch buffer. + // Stores the balance of the current account into the supplied buffer. // - // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. - ext_balance(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.balance().encode_to(&mut ctx.scratch_buf); - Ok(()) + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. + // + // The data is encoded as T::Balance. + seal_balance(ctx, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.balance().encode(), false) }, - // Stores the value transferred along with this call or as endowment into the scratch buffer. + // Stores the value transferred along with this call or as endowment into the supplied buffer. // - // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. - ext_value_transferred(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.value_transferred().encode_to(&mut ctx.scratch_buf); - Ok(()) + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. + // + // The data is encoded as T::Balance. + seal_value_transferred(ctx, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output( + ctx, out_ptr, out_len_ptr, &ctx.ext.value_transferred().encode(), false + ) }, - // Stores the random number for the current block for the given subject into the scratch - // buffer. + // Stores a random number for the current block and the given subject into the supplied buffer. + // + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. // - // The data is encoded as T::Hash. The current contents of the scratch buffer are - // overwritten. - ext_random(ctx, subject_ptr: u32, subject_len: u32) => { + // The data is encoded as T::Hash. + seal_random(ctx, subject_ptr: u32, subject_len: u32, out_ptr: u32, out_len_ptr: u32) => { // The length of a subject can't exceed `max_subject_len`. if subject_len > ctx.schedule.max_subject_len { return Err(sp_sandbox::HostError); } - let subject_buf = read_sandbox_memory(ctx, subject_ptr, subject_len)?; - ctx.scratch_buf.clear(); - ctx.ext.random(&subject_buf).encode_to(&mut ctx.scratch_buf); - Ok(()) + write_sandbox_output( + ctx, out_ptr, out_len_ptr, &ctx.ext.random(&subject_buf).encode(), false + ) }, - // Load the latest block timestamp into the scratch buffer - ext_now(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.now().encode_to(&mut ctx.scratch_buf); - Ok(()) + // Load the latest block timestamp into the supplied buffer + // + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. + seal_now(ctx, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.now().encode(), false) }, - // Stores the minimum balance (a.k.a. existential deposit) into the scratch buffer. + // Stores the minimum balance (a.k.a. existential deposit) into the supplied buffer. // - // The data is encoded as T::Balance. The current contents of the scratch buffer are - // overwritten. - ext_minimum_balance(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.minimum_balance().encode_to(&mut ctx.scratch_buf); - Ok(()) + // The data is encoded as T::Balance. + seal_minimum_balance(ctx, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.minimum_balance().encode(), false) }, - // Stores the tombstone deposit into the scratch buffer. + // Stores the tombstone deposit into the supplied buffer. + // + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. // - // The data is encoded as T::Balance. The current contents of the scratch - // buffer are overwritten. + // The data is encoded as T::Balance. // // # Note // @@ -769,47 +988,24 @@ define_env!(Env, , // a contract to leave a tombstone the balance of the contract must not go // below the sum of existential deposit and the tombstone deposit. The sum // is commonly referred as subsistence threshold in code. - ext_tombstone_deposit(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.tombstone_deposit().encode_to(&mut ctx.scratch_buf); - Ok(()) + seal_tombstone_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output( + ctx, out_ptr, out_len_ptr, &ctx.ext.tombstone_deposit().encode(), false + ) }, - // Decodes the given buffer as a `T::Call` and adds it to the list - // of to-be-dispatched calls. + // Try to restore the given destination contract sacrificing the caller. // - // All calls made it to the top-level context will be dispatched before - // finishing the execution of the calling extrinsic. - ext_dispatch_call(ctx, call_ptr: u32, call_len: u32) => { - let call: <::T as Trait>::Call = - read_sandbox_memory_as(ctx, call_ptr, call_len)?; - - // We already deducted the len costs when reading from the sandbox. - // Bill on the actual weight of the dispatched call. - let info = call.get_dispatch_info(); - charge_gas( - &mut ctx.gas_meter, - ctx.schedule, - &mut ctx.special_trap, - RuntimeToken::DispatchWithWeight(info.weight) - )?; - - ctx.ext.note_dispatch_call(call); - - Ok(()) - }, - - // Record a request to restore the caller contract to the specified contract. + // This function will compute a tombstone hash from the caller's storage and the given code hash + // and if the hash matches the hash found in the tombstone at the specified address - kill + // the caller contract and restore the destination contract and set the specified `rent_allowance`. + // All caller's funds are transfered to the destination. // - // At the finalization stage, i.e. when all changes from the extrinsic that invoked this - // contract are committed, this function will compute a tombstone hash from the caller's - // storage and the given code hash and if the hash matches the hash found in the tombstone at - // the specified address - kill the caller contract and restore the destination contract and set - // the specified `rent_allowance`. All caller's funds are transferred to the destination. + // If there is no tombstone at the destination address, the hashes don't match or this contract + // instance is already present on the contract call stack, a trap is generated. // - // This function doesn't perform restoration right away but defers it to the end of the - // transaction. If there is no tombstone in the destination address or if the hashes don't match - // then restoration is cancelled and no changes are made. + // Otherwise, the destination contract is restored. This function is diverging and stops execution + // even on success. // // `dest_ptr`, `dest_len` - the pointer and the length of a buffer that encodes `T::AccountId` // with the address of the to be restored contract. @@ -819,7 +1015,12 @@ define_env!(Env, , // encodes the rent allowance that must be set in the case of successful restoration. // `delta_ptr` is the pointer to the start of a buffer that has `delta_count` storage keys // laid out sequentially. - ext_restore_to( + // + // # Traps + // + // - Tombstone hashes do not match + // - Calling cantract is live i.e is already on the call stack. + seal_restore_to( ctx, dest_ptr: u32, dest_len: u32, @@ -857,62 +1058,15 @@ define_env!(Env, , delta }; - ctx.ext.note_restore_to( + if let Ok(()) = ctx.ext.restore_to( dest, code_hash, rent_allowance, delta, - ); - - Ok(()) - }, - - // Returns the size of the scratch buffer. - // - // For more details on the scratch buffer see `ext_scratch_read`. - ext_scratch_size(ctx) -> u32 => { - Ok(ctx.scratch_buf.len() as u32) - }, - - // Copy data from the scratch buffer starting from `offset` with length `len` into the contract - // memory. The region at which the data should be put is specified by `dest_ptr`. - // - // In order to get size of the scratch buffer use `ext_scratch_size`. At the start of contract - // execution, the scratch buffer is filled with the input data. Whenever a contract calls - // function that uses the scratch buffer the contents of the scratch buffer are overwritten. - ext_scratch_read(ctx, dest_ptr: u32, offset: u32, len: u32) => { - let offset = offset as usize; - if offset > ctx.scratch_buf.len() { - // Offset can't be larger than scratch buffer length. - return Err(sp_sandbox::HostError); - } - - // This can't panic since `offset <= ctx.scratch_buf.len()`. - let src = &ctx.scratch_buf[offset..]; - if src.len() != len as usize { - return Err(sp_sandbox::HostError); + ) { + ctx.trap_reason = Some(TrapReason::Restoration); } - - // Finally, perform the write. - write_sandbox_memory( - ctx.schedule, - &mut ctx.special_trap, - ctx.gas_meter, - &ctx.memory, - dest_ptr, - src, - )?; - - Ok(()) - }, - - // Copy data from contract memory starting from `src_ptr` with length `len` into the scratch - // buffer. This overwrites the entire scratch buffer and resizes to `len`. Specifying a `len` - // of zero clears the scratch buffer. - // - // This should be used before exiting a call or instantiation in order to set the return data. - ext_scratch_write(ctx, src_ptr: u32, len: u32) => { - read_sandbox_memory_into_scratch(ctx, src_ptr, len) + Err(sp_sandbox::HostError) }, // Deposit a contract event with the data buffer and optional list of topics. There is a limit @@ -923,7 +1077,7 @@ define_env!(Env, , // - topics_len - the length of the topics buffer. Pass 0 if you want to pass an empty vector. // - data_ptr - a pointer to a raw data buffer which will saved along the event. // - data_len - the length of the data buffer. - ext_deposit_event(ctx, topics_ptr: u32, topics_len: u32, data_ptr: u32, data_len: u32) => { + seal_deposit_event(ctx, topics_ptr: u32, topics_len: u32, data_ptr: u32, data_len: u32) => { let mut topics: Vec::::T>> = match topics_len { 0 => Vec::new(), _ => read_sandbox_memory_as(ctx, topics_ptr, topics_len)?, @@ -944,7 +1098,7 @@ define_env!(Env, , charge_gas( ctx.gas_meter, ctx.schedule, - &mut ctx.special_trap, + &mut ctx.trap_reason, RuntimeToken::DepositEvent(topics.len() as u32, data_len) )?; ctx.ext.deposit_event(topics, event_data); @@ -957,7 +1111,7 @@ define_env!(Env, , // - value_ptr: a pointer to the buffer with value, how much to allow for rent // Should be decodable as a `T::Balance`. Traps otherwise. // - value_len: length of the value buffer. - ext_set_rent_allowance(ctx, value_ptr: u32, value_len: u32) => { + seal_set_rent_allowance(ctx, value_ptr: u32, value_len: u32) => { let value: BalanceOf<::T> = read_sandbox_memory_as(ctx, value_ptr, value_len)?; ctx.ext.set_rent_allowance(value); @@ -965,20 +1119,22 @@ define_env!(Env, , Ok(()) }, - // Stores the rent allowance into the scratch buffer. + // Stores the rent allowance into the supplied buffer. // - // The data is encoded as T::Balance. The current contents of the scratch buffer are overwritten. - ext_rent_allowance(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.rent_allowance().encode_to(&mut ctx.scratch_buf); - - Ok(()) + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. + // + // The data is encoded as T::Balance. + seal_rent_allowance(ctx, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.rent_allowance().encode(), false) }, // Prints utf8 encoded string from the data buffer. // Only available on `--dev` chains. // This function may be removed at any time, superseded by a more general contract debugging feature. - ext_println(ctx, str_ptr: u32, str_len: u32) => { + seal_println(ctx, str_ptr: u32, str_len: u32) => { let data = read_sandbox_memory(ctx, str_ptr, str_len)?; if let Ok(utf8) = core::str::from_utf8(&data) { sp_runtime::print(utf8); @@ -986,37 +1142,14 @@ define_env!(Env, , Ok(()) }, - // Stores the current block number of the current contract into the scratch buffer. - ext_block_number(ctx) => { - ctx.scratch_buf.clear(); - ctx.ext.block_number().encode_to(&mut ctx.scratch_buf); - Ok(()) - }, - - // Retrieve the value under the given key from the **runtime** storage and return 0. - // If there is no entry under the given key then this function will return 1 and - // clear the scratch buffer. - // - // - key_ptr: the pointer into the linear memory where the requested value is placed. - // - key_len: the length of the key in bytes. - ext_get_runtime_storage(ctx, key_ptr: u32, key_len: u32) -> u32 => { - // Steal the scratch buffer so that we hopefully save an allocation for the `key_buf`. - read_sandbox_memory_into_scratch(ctx, key_ptr, key_len)?; - let key_buf = mem::replace(&mut ctx.scratch_buf, Vec::new()); - - match ctx.ext.get_runtime_storage(&key_buf) { - Some(value_buf) => { - // The given value exists. - ctx.scratch_buf = value_buf; - Ok(0) - } - None => { - // Put back the `key_buf` and allow its allocation to be reused. - ctx.scratch_buf = key_buf; - ctx.scratch_buf.clear(); - Ok(1) - } - } + // Stores the current block number of the current contract into the supplied buffer. + // + // The value is stored to linear memory at the address pointed to by `out_ptr`. + // `out_len_ptr` must point to a u32 value that describes the available space at + // `out_ptr`. This call overwrites it with the size of the value. If the available + // space at `out_ptr` is less than the size of the value a trap is triggered. + seal_block_number(ctx, out_ptr: u32, out_len_ptr: u32) => { + write_sandbox_output(ctx, out_ptr, out_len_ptr, &ctx.ext.block_number().encode(), false) }, // Computes the SHA2 256-bit hash on the given input buffer. @@ -1039,7 +1172,7 @@ define_env!(Env, , // - `output_ptr`: the pointer into the linear memory where the output // data is placed. The function will write the result // directly into this buffer. - ext_hash_sha2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + seal_hash_sha2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { compute_hash_on_intermediate_buffer(ctx, sha2_256, input_ptr, input_len, output_ptr) }, @@ -1063,7 +1196,7 @@ define_env!(Env, , // - `output_ptr`: the pointer into the linear memory where the output // data is placed. The function will write the result // directly into this buffer. - ext_hash_keccak_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + seal_hash_keccak_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { compute_hash_on_intermediate_buffer(ctx, keccak_256, input_ptr, input_len, output_ptr) }, @@ -1087,7 +1220,7 @@ define_env!(Env, , // - `output_ptr`: the pointer into the linear memory where the output // data is placed. The function will write the result // directly into this buffer. - ext_hash_blake2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + seal_hash_blake2_256(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { compute_hash_on_intermediate_buffer(ctx, blake2_256, input_ptr, input_len, output_ptr) }, @@ -1111,12 +1244,12 @@ define_env!(Env, , // - `output_ptr`: the pointer into the linear memory where the output // data is placed. The function will write the result // directly into this buffer. - ext_hash_blake2_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { + seal_hash_blake2_128(ctx, input_ptr: u32, input_len: u32, output_ptr: u32) => { compute_hash_on_intermediate_buffer(ctx, blake2_128, input_ptr, input_len, output_ptr) }, ); -/// Computes the given hash function on the scratch buffer. +/// Computes the given hash function on the supplied input. /// /// Reads from the sandboxed input buffer into an intermediate buffer. /// Returns the result directly to the output buffer of the sandboxed memory. @@ -1140,17 +1273,13 @@ where F: FnOnce(&[u8]) -> R, R: AsRef<[u8]>, { - // Copy the input buffer directly into the scratch buffer to avoid - // heap allocations. + // Copy input into supervisor memory. let input = read_sandbox_memory(ctx, input_ptr, input_len)?; - // Compute the hash on the scratch buffer using the given hash function. + // Compute the hash on the input buffer using the given hash function. let hash = hash_fn(&input); // Write the resulting hash back into the sandboxed output buffer. write_sandbox_memory( - ctx.schedule, - &mut ctx.special_trap, - ctx.gas_meter, - &ctx.memory, + ctx, output_ptr, hash.as_ref(), )?; @@ -1163,7 +1292,7 @@ where /// the order of items is not preserved. fn has_duplicates>(items: &mut Vec) -> bool { // Sort the vector - items.sort_unstable_by(|a, b| { + items.sort_by(|a, b| { Ord::cmp(a.as_ref(), b.as_ref()) }); // And then find any two consecutive equal elements. diff --git a/frame/contracts/tests/check_default_rent_allowance.wat b/frame/contracts/tests/check_default_rent_allowance.wat deleted file mode 100644 index 12b3004adf7dea2c7db532372b0a7f9c867c6d3f..0000000000000000000000000000000000000000 --- a/frame/contracts/tests/check_default_rent_allowance.wat +++ /dev/null @@ -1,47 +0,0 @@ -(module - (import "env" "ext_rent_allowance" (func $ext_rent_allowance)) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call")) - - (func (export "deploy") - ;; fill the scratch buffer with the rent allowance. - (call $ext_rent_allowance) - - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 8) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to >::max_value(). - (call $assert - (i64.eq - (i64.load - (i32.const 8) - ) - (i64.const 0xFFFFFFFFFFFFFFFF) - ) - ) - ) -) diff --git a/frame/contracts/tests/dispatch_call.wat b/frame/contracts/tests/dispatch_call.wat deleted file mode 100644 index db0995bd6c79ad37a8b71b4db9d88a8682b308e8..0000000000000000000000000000000000000000 --- a/frame/contracts/tests/dispatch_call.wat +++ /dev/null @@ -1,14 +0,0 @@ -(module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_dispatch_call - (i32.const 8) ;; Pointer to the start of encoded call buffer - (i32.const 11) ;; Length of the buffer - ) - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\00\03\00\00\00\00\00\00\00\C8") -) diff --git a/frame/contracts/tests/dispatch_call_then_trap.wat b/frame/contracts/tests/dispatch_call_then_trap.wat deleted file mode 100644 index ce949d68236f39846f82434ac45c9b825cedd698..0000000000000000000000000000000000000000 --- a/frame/contracts/tests/dispatch_call_then_trap.wat +++ /dev/null @@ -1,15 +0,0 @@ -(module - (import "env" "ext_dispatch_call" (func $ext_dispatch_call (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "call") - (call $ext_dispatch_call - (i32.const 8) ;; Pointer to the start of encoded call buffer - (i32.const 11) ;; Length of the buffer - ) - (unreachable) ;; trap so that the top level transaction fails - ) - (func (export "deploy")) - - (data (i32.const 8) "\00\00\03\00\00\00\00\00\00\00\C8") -) diff --git a/frame/contracts/tests/drain.wat b/frame/contracts/tests/drain.wat deleted file mode 100644 index d08e1dd0d2981eb926478c081e8125a1ab3f6cbc..0000000000000000000000000000000000000000 --- a/frame/contracts/tests/drain.wat +++ /dev/null @@ -1,54 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - ;; Send entire remaining balance to the 0 address. - (call $ext_balance) - - ;; Balance should be encoded as a u64. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; Read balance into memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer to write balance to - (i32.const 0) ;; Offset into scratch buffer - (i32.const 8) ;; Length of encoded balance - ) - - ;; Self-destruct by sending full balance to the 0 address. - (call $assert - (i32.eq - (call $ext_call - (i32.const 0) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) -) diff --git a/frame/contracts/tests/get_runtime_storage.wat b/frame/contracts/tests/get_runtime_storage.wat deleted file mode 100644 index 6148f1c408c017c5096f055759d1ed66ba9b7104..0000000000000000000000000000000000000000 --- a/frame/contracts/tests/get_runtime_storage.wat +++ /dev/null @@ -1,74 +0,0 @@ -(module - (import "env" "ext_get_runtime_storage" - (func $ext_get_runtime_storage (param i32 i32) (result i32)) - ) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func (export "deploy")) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func $call (export "call") - ;; Load runtime storage for the first key and assert that it exists. - (call $assert - (i32.eq - (call $ext_get_runtime_storage - (i32.const 16) - (i32.const 4) - ) - (i32.const 0) - ) - ) - - ;; assert $ext_scratch_size == 4 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 4) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 4) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 4) ;; Count of bytes to copy. - ) - - ;; assert that contents of the buffer is equal to the i32 value of 0x14144020. - (call $assert - (i32.eq - (i32.load - (i32.const 4) - ) - (i32.const 0x14144020) - ) - ) - - ;; Load the second key and assert that it doesn't exist. - (call $assert - (i32.eq - (call $ext_get_runtime_storage - (i32.const 20) - (i32.const 4) - ) - (i32.const 1) - ) - ) - ) - - ;; The first key, 4 bytes long. - (data (i32.const 16) "\01\02\03\04") - ;; The second key, 4 bytes long. - (data (i32.const 20) "\02\03\04\05") -) diff --git a/frame/contracts/tests/return_with_data.wat b/frame/contracts/tests/return_with_data.wat deleted file mode 100644 index 8cc84006a0b00eff34536b5f861461cb045d570e..0000000000000000000000000000000000000000 --- a/frame/contracts/tests/return_with_data.wat +++ /dev/null @@ -1,39 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_scratch_write" (func $ext_scratch_write (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - ;; Deploy routine is the same as call. - (func (export "deploy") (result i32) - (call $call) - ) - - ;; Call reads the first 4 bytes (LE) as the exit status and returns the rest as output data. - (func $call (export "call") (result i32) - (local $buf_size i32) - (local $exit_status i32) - - ;; Find out the size of the scratch buffer - (set_local $buf_size (call $ext_scratch_size)) - - ;; Copy scratch buffer into this contract memory. - (call $ext_scratch_read - (i32.const 0) ;; The pointer where to store the scratch buffer contents, - (i32.const 0) ;; Offset from the start of the scratch buffer. - (get_local $buf_size) ;; Count of bytes to copy. - ) - - ;; Copy all but the first 4 bytes of the input data as the output data. - (call $ext_scratch_write - (i32.const 4) ;; Pointer to the data to return. - (i32.sub ;; Count of bytes to copy. - (get_local $buf_size) - (i32.const 4) - ) - ) - - ;; Return the first 4 bytes of the input data as the exit status. - (i32.load (i32.const 0)) - ) -) diff --git a/frame/contracts/tests/self_destruct.wat b/frame/contracts/tests/self_destruct.wat deleted file mode 100644 index 464b5c663ea4a96f544a8f7c6534006c474c5aa1..0000000000000000000000000000000000000000 --- a/frame/contracts/tests/self_destruct.wat +++ /dev/null @@ -1,72 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_address" (func $ext_address)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "ext_terminate" (func $ext_terminate (param i32 i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy")) - - (func (export "call") - ;; If the input data is not empty, then recursively call self with empty input data. - ;; This should trap instead of self-destructing since a contract cannot be removed live in - ;; the execution stack cannot be removed. If the recursive call traps, then trap here as - ;; well. - (if (call $ext_scratch_size) - (then - (call $ext_address) - - ;; Expect address to be 8 bytes. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; Read own address into memory. - (call $ext_scratch_read - (i32.const 16) ;; Pointer to write address to - (i32.const 0) ;; Offset into scratch buffer - (i32.const 8) ;; Length of encoded address - ) - - ;; Recursively call self with empty input data. - (call $assert - (i32.eq - (call $ext_call - (i32.const 16) ;; Pointer to own address - (i32.const 8) ;; Length of own address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) - (else - ;; Try to terminate and give balance to django. - (call $ext_terminate - (i32.const 32) ;; Pointer to beneficiary address - (i32.const 8) ;; Length of beneficiary address - ) - (unreachable) ;; ext_terminate never returns - ) - ) - ) - ;; Address of django - (data (i32.const 32) "\04\00\00\00\00\00\00\00") -) diff --git a/frame/contracts/tests/self_destructing_constructor.wat b/frame/contracts/tests/self_destructing_constructor.wat deleted file mode 100644 index b19d6e5b50daca2b37f20c7866134a02097c6285..0000000000000000000000000000000000000000 --- a/frame/contracts/tests/self_destructing_constructor.wat +++ /dev/null @@ -1,54 +0,0 @@ -(module - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "ext_balance" (func $ext_balance)) - (import "env" "ext_call" (func $ext_call (param i32 i32 i64 i32 i32 i32 i32) (result i32))) - (import "env" "memory" (memory 1 1)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "deploy") - ;; Send entire remaining balance to the 0 address. - (call $ext_balance) - - ;; Balance should be encoded as a u64. - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 8) - ) - ) - - ;; Read balance into memory. - (call $ext_scratch_read - (i32.const 8) ;; Pointer to write balance to - (i32.const 0) ;; Offset into scratch buffer - (i32.const 8) ;; Length of encoded balance - ) - - ;; Self-destruct by sending full balance to the 0 address. - (call $assert - (i32.eq - (call $ext_call - (i32.const 0) ;; Pointer to destination address - (i32.const 8) ;; Length of destination address - (i64.const 0) ;; How much gas to devote for the execution. 0 = all. - (i32.const 8) ;; Pointer to the buffer with value to transfer - (i32.const 8) ;; Length of the buffer with value to transfer - (i32.const 0) ;; Pointer to input data buffer address - (i32.const 0) ;; Length of input data buffer - ) - (i32.const 0) - ) - ) - ) - - (func (export "call")) -) diff --git a/frame/contracts/tests/storage_size.wat b/frame/contracts/tests/storage_size.wat deleted file mode 100644 index 8de9f42ee97483fed59b8d84724ef431c3777728..0000000000000000000000000000000000000000 --- a/frame/contracts/tests/storage_size.wat +++ /dev/null @@ -1,60 +0,0 @@ -(module - (import "env" "ext_get_storage" (func $ext_get_storage (param i32) (result i32))) - (import "env" "ext_set_storage" (func $ext_set_storage (param i32 i32 i32))) - (import "env" "ext_scratch_size" (func $ext_scratch_size (result i32))) - (import "env" "ext_scratch_read" (func $ext_scratch_read (param i32 i32 i32))) - (import "env" "memory" (memory 16 16)) - - (func $assert (param i32) - (block $ok - (br_if $ok - (get_local 0) - ) - (unreachable) - ) - ) - - (func (export "call") - ;; assert $ext_scratch_size == 8 - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.const 4) - ) - ) - - ;; copy contents of the scratch buffer into the contract's memory. - (call $ext_scratch_read - (i32.const 32) ;; Pointer in memory to the place where to copy. - (i32.const 0) ;; Offset from the start of the scratch buffer. - (i32.const 4) ;; Count of bytes to copy. - ) - - ;; place a garbage value in storage, the size of which is specified by the call input. - (call $ext_set_storage - (i32.const 0) ;; Pointer to storage key - (i32.const 0) ;; Pointer to value - (i32.load (i32.const 32)) ;; Size of value - ) - - (call $assert - (i32.eq - (call $ext_get_storage - (i32.const 0) ;; Pointer to storage key - ) - (i32.const 0) - ) - ) - - (call $assert - (i32.eq - (call $ext_scratch_size) - (i32.load (i32.const 32)) - ) - ) - ) - - (func (export "deploy")) - - (data (i32.const 0) "\01") ;; Storage key (32 B) -) diff --git a/frame/democracy/Cargo.toml b/frame/democracy/Cargo.toml index 83caa671cee958d28c68a06b744215b69a351def..8eb406fc5253d8cad62464f57e7c9e2055d13d44 100644 --- a/frame/democracy/Cargo.toml +++ b/frame/democracy/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-democracy" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for democracy" @@ -13,20 +13,21 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } -pallet-scheduler = { version = "2.0.0-dev", path = "../scheduler" } -sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } -hex-literal = "0.2.1" +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +pallet-scheduler = { version = "2.0.0-rc6", path = "../scheduler" } +sp-storage = { version = "2.0.0-rc6", path = "../../primitives/storage" } +substrate-test-utils = { version = "2.0.0-rc6", path = "../../test-utils" } +hex-literal = "0.3.1" [features] default = ["std"] @@ -43,5 +44,6 @@ std = [ runtime-benchmarks = [ "frame-benchmarking", "frame-system/runtime-benchmarks", + "frame-support/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] diff --git a/frame/democracy/README.md b/frame/democracy/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0f836f1158c8b1de8bbeeb143d8bcacb1b57d253 --- /dev/null +++ b/frame/democracy/README.md @@ -0,0 +1,135 @@ +# Democracy Pallet + +- [`democracy::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +The Democracy pallet handles the administration of general stakeholder voting. + +There are two different queues that a proposal can be added to before it +becomes a referendum, 1) the proposal queue consisting of all public proposals +and 2) the external queue consisting of a single proposal that originates +from one of the _external_ origins (such as a collective group). + +Every launch period - a length defined in the runtime - the Democracy pallet +launches a referendum from a proposal that it takes from either the proposal +queue or the external queue in turn. Any token holder in the system can vote +on referenda. The voting system +uses time-lock voting by allowing the token holder to set their _conviction_ +behind a vote. The conviction will dictate the length of time the tokens +will be locked, as well as the multiplier that scales the vote power. + +### Terminology + +- **Enactment Period:** The minimum period of locking and the period between a proposal being +approved and enacted. +- **Lock Period:** A period of time after proposal enactment that the tokens of _winning_ voters +will be locked. +- **Conviction:** An indication of a voter's strength of belief in their vote. An increase +of one in conviction indicates that a token holder is willing to lock their tokens for twice +as many lock periods after enactment. +- **Vote:** A value that can either be in approval ("Aye") or rejection ("Nay") + of a particular referendum. +- **Proposal:** A submission to the chain that represents an action that a proposer (either an +account or an external origin) suggests that the system adopt. +- **Referendum:** A proposal that is in the process of being voted on for + either acceptance or rejection as a change to the system. +- **Delegation:** The act of granting your voting power to the decisions of another account for + up to a certain conviction. + +### Adaptive Quorum Biasing + +A _referendum_ can be either simple majority-carries in which 50%+1 of the +votes decide the outcome or _adaptive quorum biased_. Adaptive quorum biasing +makes the threshold for passing or rejecting a referendum higher or lower +depending on how the referendum was originally proposed. There are two types of +adaptive quorum biasing: 1) _positive turnout bias_ makes a referendum +require a super-majority to pass that decreases as turnout increases and +2) _negative turnout bias_ makes a referendum require a super-majority to +reject that decreases as turnout increases. Another way to think about the +quorum biasing is that _positive bias_ referendums will be rejected by +default and _negative bias_ referendums get passed by default. + +## Interface + +### Dispatchable Functions + +#### Public + +These calls can be made from any externally held account capable of creating +a signed extrinsic. + +Basic actions: +- `propose` - Submits a sensitive action, represented as a hash. Requires a deposit. +- `second` - Signals agreement with a proposal, moves it higher on the proposal queue, and + requires a matching deposit to the original. +- `vote` - Votes in a referendum, either the vote is "Aye" to enact the proposal or "Nay" to + keep the status quo. +- `unvote` - Cancel a previous vote, this must be done by the voter before the vote ends. +- `delegate` - Delegates the voting power (tokens * conviction) to another account. +- `undelegate` - Stops the delegation of voting power to another account. + +Administration actions that can be done to any account: +- `reap_vote` - Remove some account's expired votes. +- `unlock` - Redetermine the account's balance lock, potentially making tokens available. + +Preimage actions: +- `note_preimage` - Registers the preimage for an upcoming proposal, requires + a deposit that is returned once the proposal is enacted. +- `note_preimage_operational` - same but provided by `T::OperationalPreimageOrigin`. +- `note_imminent_preimage` - Registers the preimage for an upcoming proposal. + Does not require a deposit, but the proposal must be in the dispatch queue. +- `note_imminent_preimage_operational` - same but provided by `T::OperationalPreimageOrigin`. +- `reap_preimage` - Removes the preimage for an expired proposal. Will only + work under the condition that it's the same account that noted it and + after the voting period, OR it's a different account after the enactment period. + +#### Cancellation Origin + +This call can only be made by the `CancellationOrigin`. + +- `emergency_cancel` - Schedules an emergency cancellation of a referendum. + Can only happen once to a specific referendum. + +#### ExternalOrigin + +This call can only be made by the `ExternalOrigin`. + +- `external_propose` - Schedules a proposal to become a referendum once it is is legal + for an externally proposed referendum. + +#### External Majority Origin + +This call can only be made by the `ExternalMajorityOrigin`. + +- `external_propose_majority` - Schedules a proposal to become a majority-carries + referendum once it is legal for an externally proposed referendum. + +#### External Default Origin + +This call can only be made by the `ExternalDefaultOrigin`. + +- `external_propose_default` - Schedules a proposal to become a negative-turnout-bias + referendum once it is legal for an externally proposed referendum. + +#### Fast Track Origin + +This call can only be made by the `FastTrackOrigin`. + +- `fast_track` - Schedules the current externally proposed proposal that + is "majority-carries" to become a referendum immediately. + +#### Veto Origin + +This call can only be made by the `VetoOrigin`. + +- `veto_external` - Vetoes and blacklists the external proposal hash. + +#### Root + +- `cancel_referendum` - Removes a referendum. +- `cancel_queued` - Cancels a proposal that is queued for enactment. +- `clear_public_proposal` - Removes all public proposals. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/democracy/src/benchmarking.rs b/frame/democracy/src/benchmarking.rs index d56113846545b912f7fd5821fffb75a8f706b684..1fa0988fbbd4d629f5b0df812d8365c56299e6fe 100644 --- a/frame/democracy/src/benchmarking.rs +++ b/frame/democracy/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Democracy pallet benchmarking. @@ -21,7 +22,7 @@ use super::*; use frame_benchmarking::{benchmarks, account}; use frame_support::{ IterableStorageMap, - traits::{Currency, Get, EnsureOrigin, OnInitialize}, + traits::{Currency, Get, EnsureOrigin, OnInitialize, UnfilteredDispatchable, schedule::DispatchTime}, }; use frame_system::{RawOrigin, Module as System, self, EventRecord}; use sp_runtime::traits::{Bounded, One}; @@ -29,11 +30,8 @@ use sp_runtime::traits::{Bounded, One}; use crate::Module as Democracy; const SEED: u32 = 0; -const MAX_USERS: u32 = 1000; const MAX_REFERENDUMS: u32 = 100; -const MAX_PROPOSALS: u32 = 100; const MAX_SECONDERS: u32 = 100; -const MAX_VETOERS: u32 = 100; const MAX_BYTES: u32 = 16_384; fn assert_last_event(generic_event: ::Event) { @@ -55,7 +53,11 @@ fn add_proposal(n: u32) -> Result { let value = T::MinimumDeposit::get(); let proposal_hash: T::Hash = T::Hashing::hash_of(&n); - Democracy::::propose(RawOrigin::Signed(other).into(), proposal_hash, value.into())?; + Democracy::::propose( + RawOrigin::Signed(other).into(), + proposal_hash, + value.into(), + )?; Ok(proposal_hash) } @@ -71,13 +73,14 @@ fn add_referendum(n: u32) -> Result { 0.into(), ); let referendum_index: ReferendumIndex = ReferendumCount::get() - 1; - let _ = T::Scheduler::schedule_named( + T::Scheduler::schedule_named( (DEMOCRACY_ID, referendum_index).encode(), - 0.into(), + DispatchTime::At(1.into()), None, 63, + system::RawOrigin::Root.into(), Call::enact_proposal(proposal_hash, referendum_index).into(), - ); + ).map_err(|_| "failed to schedule named")?; Ok(referendum_index) } @@ -93,35 +96,16 @@ fn account_vote(b: BalanceOf) -> AccountVote> { } } -fn open_activate_proxy(u: u32) -> Result<(T::AccountId, T::AccountId), &'static str> { - let caller = funded_account::("caller", u); - let voter = funded_account::("voter", u); - - Democracy::::open_proxy(RawOrigin::Signed(caller.clone()).into(), voter.clone())?; - Democracy::::activate_proxy(RawOrigin::Signed(voter.clone()).into(), caller.clone())?; - - Ok((caller, voter)) -} - benchmarks! { _ { } propose { - let p in 1 .. MAX_PROPOSALS; - - // Add p proposals - for i in 0 .. p { - add_proposal::(i)?; - } - - assert_eq!(Democracy::::public_props().len(), p as usize, "Proposals not created."); - let caller = funded_account::("caller", 0); - let proposal_hash: T::Hash = T::Hashing::hash_of(&p); + let proposal_hash: T::Hash = T::Hashing::hash_of(&0); let value = T::MinimumDeposit::get(); }: _(RawOrigin::Signed(caller), proposal_hash, value.into()) verify { - assert_eq!(Democracy::::public_props().len(), (p + 1) as usize, "Proposals not created."); + assert_eq!(Democracy::::public_props().len(), 1, "Proposals not created."); } second { @@ -133,15 +117,15 @@ benchmarks! { // Create s existing "seconds" for i in 0 .. s { let seconder = funded_account::("seconder", i); - Democracy::::second(RawOrigin::Signed(seconder).into(), 0)?; + Democracy::::second(RawOrigin::Signed(seconder).into(), 0, u32::max_value())?; } let deposits = Democracy::::deposit_of(0).ok_or("Proposal not created")?; - assert_eq!(deposits.1.len(), (s + 1) as usize, "Seconds not recorded"); - }: _(RawOrigin::Signed(caller), 0) + assert_eq!(deposits.0.len(), (s + 1) as usize, "Seconds not recorded"); + }: _(RawOrigin::Signed(caller), 0, u32::max_value()) verify { let deposits = Democracy::::deposit_of(0).ok_or("Proposal not created")?; - assert_eq!(deposits.1.len(), (s + 2) as usize, "`second` benchmark did not work"); + assert_eq!(deposits.0.len(), (s + 2) as usize, "`second` benchmark did not work"); } vote_new { @@ -211,86 +195,12 @@ benchmarks! { assert_eq!(tally.nays, 1000.into(), "changed vote was not recorded"); } - // Basically copy paste of `vote_new` - proxy_vote_new { - let r in 1 .. MAX_REFERENDUMS; - - let (caller, voter) = open_activate_proxy::(0)?; - let account_vote = account_vote::(100.into()); - - // Populate existing direct votes for the voter, they can vote on their own behalf - for i in 0 .. r { - let ref_idx = add_referendum::(i)?; - Democracy::::vote(RawOrigin::Signed(voter.clone()).into(), ref_idx, account_vote.clone())?; - } - - let referendum_index = add_referendum::(r)?; - - }: proxy_vote(RawOrigin::Signed(caller), referendum_index, account_vote) - verify { - let votes = match VotingOf::::get(&voter) { - Voting::Direct { votes, .. } => votes, - _ => return Err("Votes are not direct"), - }; - assert_eq!(votes.len(), (r + 1) as usize, "Vote was not recorded."); - } - - // Basically copy paste of `vote_existing` - proxy_vote_existing { - let r in 1 .. MAX_REFERENDUMS; - - let (caller, voter) = open_activate_proxy::(0)?; - let account_vote = account_vote::(100.into()); - - // We need to create existing direct votes - for i in 0 ..=r { - let ref_idx = add_referendum::(i)?; - Democracy::::vote(RawOrigin::Signed(voter.clone()).into(), ref_idx, account_vote.clone())?; - } - let votes = match VotingOf::::get(&voter) { - Voting::Direct { votes, .. } => votes, - _ => return Err("Votes are not direct"), - }; - assert_eq!(votes.len(), (r + 1) as usize, "Votes were not recorded."); - - // Change vote from aye to nay - let nay = Vote { aye: false, conviction: Conviction::Locked1x }; - let new_vote = AccountVote::Standard { vote: nay, balance: 1000.into() }; - let referendum_index = Democracy::::referendum_count() - 1; - - // This tests when a user changes a vote - }: proxy_vote(RawOrigin::Signed(caller.clone()), referendum_index, new_vote) - verify { - let votes = match VotingOf::::get(&voter) { - Voting::Direct { votes, .. } => votes, - _ => return Err("Votes are not direct"), - }; - assert_eq!(votes.len(), (r + 1) as usize, "Vote was incorrectly added"); - let referendum_info = Democracy::::referendum_info(referendum_index) - .ok_or("referendum doesn't exist")?; - let tally = match referendum_info { - ReferendumInfo::Ongoing(r) => r.tally, - _ => return Err("referendum not ongoing"), - }; - assert_eq!(tally.nays, 1000.into(), "changed vote was not recorded"); - } - emergency_cancel { - let r in 1 .. MAX_REFERENDUMS; let origin = T::CancellationOrigin::successful_origin(); - - // Create and cancel a bunch of referendums - for i in 0 .. r { - let ref_idx = add_referendum::(i)?; - let call = Call::::emergency_cancel(ref_idx); - call.dispatch(origin.clone())?; - } - - // Lets now measure one more - let referendum_index = add_referendum::(r)?; + let referendum_index = add_referendum::(0)?; let call = Call::::emergency_cancel(referendum_index); assert!(Democracy::::referendum_status(referendum_index).is_ok()); - }: { call.dispatch(origin)? } + }: { call.dispatch_bypass_filter(origin)? } verify { // Referendum has been canceled assert!(Democracy::::referendum_status(referendum_index).is_err()); @@ -298,11 +208,10 @@ benchmarks! { // Worst case scenario, we external propose a previously blacklisted proposal external_propose { - let p in 1 .. MAX_PROPOSALS; - let v in 1 .. MAX_VETOERS; + let v in 1 .. MAX_VETOERS as u32; let origin = T::ExternalOrigin::successful_origin(); - let proposal_hash = T::Hashing::hash_of(&p); + let proposal_hash = T::Hashing::hash_of(&0); // Add proposal to blacklist with block number 0 Blacklist::::insert( proposal_hash, @@ -310,41 +219,35 @@ benchmarks! { ); let call = Call::::external_propose(proposal_hash); - }: { call.dispatch(origin)? } + }: { call.dispatch_bypass_filter(origin)? } verify { // External proposal created ensure!(>::exists(), "External proposal didn't work"); } external_propose_majority { - let p in 1 .. MAX_PROPOSALS; - let origin = T::ExternalMajorityOrigin::successful_origin(); - let proposal_hash = T::Hashing::hash_of(&p); + let proposal_hash = T::Hashing::hash_of(&0); let call = Call::::external_propose_majority(proposal_hash); - }: { call.dispatch(origin)? } + }: { call.dispatch_bypass_filter(origin)? } verify { // External proposal created ensure!(>::exists(), "External proposal didn't work"); } external_propose_default { - let p in 1 .. MAX_PROPOSALS; - let origin = T::ExternalDefaultOrigin::successful_origin(); - let proposal_hash = T::Hashing::hash_of(&p); + let proposal_hash = T::Hashing::hash_of(&0); let call = Call::::external_propose_default(proposal_hash); - }: { call.dispatch(origin)? } + }: { call.dispatch_bypass_filter(origin)? } verify { // External proposal created ensure!(>::exists(), "External proposal didn't work"); } fast_track { - let p in 1 .. MAX_PROPOSALS; - let origin_propose = T::ExternalDefaultOrigin::successful_origin(); - let proposal_hash: T::Hash = T::Hashing::hash_of(&p); + let proposal_hash: T::Hash = T::Hashing::hash_of(&0); Democracy::::external_propose_default(origin_propose, proposal_hash.clone())?; // NOTE: Instant origin may invoke a little bit more logic, but may not always succeed. @@ -353,14 +256,14 @@ benchmarks! { let delay = 0; let call = Call::::fast_track(proposal_hash, voting_period.into(), delay.into()); - }: { call.dispatch(origin_fast_track)? } + }: { call.dispatch_bypass_filter(origin_fast_track)? } verify { assert_eq!(Democracy::::referendum_count(), 1, "referendum not created") } veto_external { // Existing veto-ers - let v in 0 .. MAX_VETOERS; + let v in 0 .. MAX_VETOERS as u32; let proposal_hash: T::Hash = T::Hashing::hash_of(&v); @@ -377,7 +280,7 @@ benchmarks! { let call = Call::::veto_external(proposal_hash); let origin = T::VetoOrigin::successful_origin(); ensure!(NextExternal::::get().is_some(), "no external proposal"); - }: { call.dispatch(origin)? } + }: { call.dispatch_bypass_filter(origin)? } verify { assert!(NextExternal::::get().is_none()); let (_, new_vetoers) = >::get(&proposal_hash).ok_or("no blacklist")?; @@ -385,24 +288,21 @@ benchmarks! { } cancel_referendum { - let r in 0 .. MAX_REFERENDUMS; - // Should have no effect on the execution time. - for i in 0..r { - add_referendum::(i)?; - } - let referendum_index = add_referendum::(r)?; + let referendum_index = add_referendum::(0)?; }: _(RawOrigin::Root, referendum_index) cancel_queued { let r in 1 .. MAX_REFERENDUMS; - // Should have no effect on the execution time. + for i in 0..r { - add_referendum::(i)?; + add_referendum::(i)?; // This add one element in the scheduler } + let referendum_index = add_referendum::(r)?; }: _(RawOrigin::Root, referendum_index) // Note that we have a separate benchmark for `launch_next` + #[extra] on_initialize_external { let r in 0 .. MAX_REFERENDUMS; @@ -418,7 +318,7 @@ benchmarks! { let origin = T::ExternalMajorityOrigin::successful_origin(); let proposal_hash = T::Hashing::hash_of(&r); let call = Call::::external_propose_majority(proposal_hash); - call.dispatch(origin)?; + call.dispatch_bypass_filter(origin)?; // External proposal created ensure!(>::exists(), "External proposal didn't work"); @@ -441,6 +341,7 @@ benchmarks! { } } + #[extra] on_initialize_public { let r in 1 .. MAX_REFERENDUMS; @@ -471,7 +372,8 @@ benchmarks! { } } - on_initialize_no_launch_no_maturing { + // No launch no maturing referenda. + on_initialize_base { let r in 1 .. MAX_REFERENDUMS; for i in 0..r { @@ -501,33 +403,6 @@ benchmarks! { } } - activate_proxy { - let u in 1 .. MAX_USERS; - - let caller: T::AccountId = funded_account::("caller", u); - let proxy: T::AccountId = funded_account::("proxy", u); - Democracy::::open_proxy(RawOrigin::Signed(proxy.clone()).into(), caller.clone())?; - }: _(RawOrigin::Signed(caller.clone()), proxy.clone()) - verify { - assert_eq!(Democracy::::proxy(proxy), Some(ProxyState::Active(caller))); - } - - close_proxy { - let u in 1 .. MAX_USERS; - let (caller, _) = open_activate_proxy::(u)?; - }: _(RawOrigin::Signed(caller.clone())) - verify { - assert_eq!(Democracy::::proxy(caller), None); - } - - deactivate_proxy { - let u in 1 .. MAX_USERS; - let (caller, voter) = open_activate_proxy::(u)?; - }: _(RawOrigin::Signed(voter.clone()), caller.clone()) - verify { - assert_eq!(Democracy::::proxy(caller), Some(ProxyState::Open(voter))); - } - delegate { let r in 1 .. MAX_REFERENDUMS; @@ -623,11 +498,7 @@ benchmarks! { } clear_public_proposals { - let p in 0 .. MAX_PROPOSALS; - - for i in 0 .. p { - add_proposal::(i)?; - } + add_proposal::(0)?; }: _(RawOrigin::Root) @@ -684,7 +555,7 @@ benchmarks! { assert!(Preimages::::contains_key(proposal_hash)); let caller = funded_account::("caller", 0); - }: _(RawOrigin::Signed(caller), proposal_hash.clone()) + }: _(RawOrigin::Signed(caller), proposal_hash.clone(), u32::max_value()) verify { let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); assert!(!Preimages::::contains_key(proposal_hash)); @@ -756,14 +627,6 @@ benchmarks! { assert_eq!(voting.locked_balance(), base_balance); } - open_proxy { - let u in 1 .. MAX_USERS; - - let caller: T::AccountId = funded_account::("caller", u); - let proxy: T::AccountId = funded_account::("proxy", u); - - }: _(RawOrigin::Signed(proxy), caller) - remove_vote { let r in 1 .. MAX_REFERENDUMS; @@ -792,150 +655,19 @@ benchmarks! { assert_eq!(votes.len(), (r - 1) as usize, "Vote was not removed"); } + // Worst case is when target == caller and referendum is ongoing remove_other_vote { let r in 1 .. MAX_REFERENDUMS; - let other = funded_account::("other", r); + let caller = funded_account::("caller", r); let account_vote = account_vote::(100.into()); for i in 0 .. r { let ref_idx = add_referendum::(i)?; - Democracy::::vote(RawOrigin::Signed(other.clone()).into(), ref_idx, account_vote.clone())?; - } - - let votes = match VotingOf::::get(&other) { - Voting::Direct { votes, .. } => votes, - _ => return Err("Votes are not direct"), - }; - assert_eq!(votes.len(), r as usize, "Votes not created"); - - let referendum_index = r - 1; - ReferendumInfoOf::::insert( - referendum_index, - ReferendumInfo::Finished { end: T::BlockNumber::zero(), approved: true } - ); - let caller = funded_account::("caller", 0); - - System::::set_block_number(T::EnactmentPeriod::get() * 10u32.into()); - - }: _(RawOrigin::Signed(caller), other.clone(), referendum_index) - verify { - let votes = match VotingOf::::get(&other) { - Voting::Direct { votes, .. } => votes, - _ => return Err("Votes are not direct"), - }; - assert_eq!(votes.len(), (r - 1) as usize, "Vote was not removed"); - } - - // This is a copy of delegate benchmark, but with `open_activate_proxy` - proxy_delegate { - let r in 1 .. MAX_REFERENDUMS; - - let initial_balance: BalanceOf = 100.into(); - let delegated_balance: BalanceOf = 1000.into(); - - let (caller, voter) = open_activate_proxy::(0)?; - - // Voter will initially delegate to `old_delegate` - let old_delegate: T::AccountId = funded_account::("old_delegate", r); - Democracy::::delegate( - RawOrigin::Signed(voter.clone()).into(), - old_delegate.clone(), - Conviction::Locked1x, - delegated_balance, - )?; - let (target, balance) = match VotingOf::::get(&voter) { - Voting::Delegating { target, balance, .. } => (target, balance), - _ => return Err("Votes are not direct"), - }; - assert_eq!(target, old_delegate, "delegation target didn't work"); - assert_eq!(balance, delegated_balance, "delegation balance didn't work"); - // Voter will now switch to `new_delegate` - let new_delegate: T::AccountId = funded_account::("new_delegate", r); - let account_vote = account_vote::(initial_balance); - // We need to create existing direct votes for the `new_delegate` - for i in 0..r { - let ref_idx = add_referendum::(i)?; - Democracy::::vote(RawOrigin::Signed(new_delegate.clone()).into(), ref_idx, account_vote.clone())?; - } - let votes = match VotingOf::::get(&new_delegate) { - Voting::Direct { votes, .. } => votes, - _ => return Err("Votes are not direct"), - }; - assert_eq!(votes.len(), r as usize, "Votes were not recorded."); - }: _(RawOrigin::Signed(caller.clone()), new_delegate.clone(), Conviction::Locked1x, delegated_balance) - verify { - let (target, balance) = match VotingOf::::get(&voter) { - Voting::Delegating { target, balance, .. } => (target, balance), - _ => return Err("Votes are not direct"), - }; - assert_eq!(target, new_delegate, "delegation target didn't work"); - assert_eq!(balance, delegated_balance, "delegation balance didn't work"); - let delegations = match VotingOf::::get(&new_delegate) { - Voting::Direct { delegations, .. } => delegations, - _ => return Err("Votes are not direct"), - }; - assert_eq!(delegations.capital, delegated_balance, "delegation was not recorded."); - } - - // This is a copy of undelegate benchmark, but with `open_activate_proxy` - proxy_undelegate { - let r in 1 .. MAX_REFERENDUMS; - - let initial_balance: BalanceOf = 100.into(); - let delegated_balance: BalanceOf = 1000.into(); - - let (caller, voter) = open_activate_proxy::(0)?; - // Caller will delegate - let the_delegate: T::AccountId = funded_account::("delegate", r); - Democracy::::delegate( - RawOrigin::Signed(voter.clone()).into(), - the_delegate.clone(), - Conviction::Locked1x, - delegated_balance, - )?; - let (target, balance) = match VotingOf::::get(&voter) { - Voting::Delegating { target, balance, .. } => (target, balance), - _ => return Err("Votes are not direct"), - }; - assert_eq!(target, the_delegate, "delegation target didn't work"); - assert_eq!(balance, delegated_balance, "delegation balance didn't work"); - // We need to create votes direct votes for the `delegate` - let account_vote = account_vote::(initial_balance); - for i in 0..r { - let ref_idx = add_referendum::(i)?; - Democracy::::vote( - RawOrigin::Signed(the_delegate.clone()).into(), - ref_idx, - account_vote.clone() - )?; - } - let votes = match VotingOf::::get(&the_delegate) { - Voting::Direct { votes, .. } => votes, - _ => return Err("Votes are not direct"), - }; - assert_eq!(votes.len(), r as usize, "Votes were not recorded."); - }: _(RawOrigin::Signed(caller.clone())) - verify { - // Voting should now be direct - match VotingOf::::get(&voter) { - Voting::Direct { .. } => (), - _ => return Err("undelegation failed"), - } - } - - proxy_remove_vote { - let r in 1 .. MAX_REFERENDUMS; - - let (caller, voter) = open_activate_proxy::(0)?; - let account_vote = account_vote::(100.into()); - - for i in 0 .. r { - let ref_idx = add_referendum::(i)?; - Democracy::::vote(RawOrigin::Signed(voter.clone()).into(), ref_idx, account_vote.clone())?; + Democracy::::vote(RawOrigin::Signed(caller.clone()).into(), ref_idx, account_vote.clone())?; } - let votes = match VotingOf::::get(&voter) { + let votes = match VotingOf::::get(&caller) { Voting::Direct { votes, .. } => votes, _ => return Err("Votes are not direct"), }; @@ -943,15 +675,16 @@ benchmarks! { let referendum_index = r - 1; - }: _(RawOrigin::Signed(caller.clone()), referendum_index) + }: _(RawOrigin::Signed(caller.clone()), caller.clone(), referendum_index) verify { - let votes = match VotingOf::::get(&voter) { + let votes = match VotingOf::::get(&caller) { Voting::Direct { votes, .. } => votes, _ => return Err("Votes are not direct"), }; assert_eq!(votes.len(), (r - 1) as usize, "Vote was not removed"); } + #[extra] enact_proposal_execute { // Num of bytes in encoded proposal let b in 0 .. MAX_BYTES; @@ -973,6 +706,7 @@ benchmarks! { assert_last_event::(RawEvent::Executed(0, false).into()); } + #[extra] enact_proposal_slash { // Num of bytes in encoded proposal let b in 0 .. MAX_BYTES; @@ -1008,8 +742,6 @@ mod tests { assert_ok!(test_benchmark_second::()); assert_ok!(test_benchmark_vote_new::()); assert_ok!(test_benchmark_vote_existing::()); - assert_ok!(test_benchmark_proxy_vote_new::()); - assert_ok!(test_benchmark_proxy_vote_existing::()); assert_ok!(test_benchmark_emergency_cancel::()); assert_ok!(test_benchmark_external_propose::()); assert_ok!(test_benchmark_external_propose_majority::()); @@ -1020,11 +752,7 @@ mod tests { assert_ok!(test_benchmark_cancel_queued::()); assert_ok!(test_benchmark_on_initialize_external::()); assert_ok!(test_benchmark_on_initialize_public::()); - assert_ok!(test_benchmark_on_initialize_no_launch_no_maturing::()); - assert_ok!(test_benchmark_open_proxy::()); - assert_ok!(test_benchmark_activate_proxy::()); - assert_ok!(test_benchmark_close_proxy::()); - assert_ok!(test_benchmark_deactivate_proxy::()); + assert_ok!(test_benchmark_on_initialize_base::()); assert_ok!(test_benchmark_delegate::()); assert_ok!(test_benchmark_undelegate::()); assert_ok!(test_benchmark_clear_public_proposals::()); @@ -1035,9 +763,6 @@ mod tests { assert_ok!(test_benchmark_unlock_set::()); assert_ok!(test_benchmark_remove_vote::()); assert_ok!(test_benchmark_remove_other_vote::()); - assert_ok!(test_benchmark_proxy_delegate::()); - assert_ok!(test_benchmark_proxy_undelegate::()); - assert_ok!(test_benchmark_proxy_remove_vote::()); assert_ok!(test_benchmark_enact_proposal_execute::()); assert_ok!(test_benchmark_enact_proposal_slash::()); }); diff --git a/frame/democracy/src/conviction.rs b/frame/democracy/src/conviction.rs index a057ee2a357503d0a51648874b92a9006c3d1087..bb563e4b74830b24bf789454a3fe36de3a3e0e0c 100644 --- a/frame/democracy/src/conviction.rs +++ b/frame/democracy/src/conviction.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! The conviction datatype. diff --git a/frame/democracy/src/default_weight.rs b/frame/democracy/src/default_weight.rs new file mode 100644 index 0000000000000000000000000000000000000000..2c74a4af2020f53bb87004e7b3bf81b070267d34 --- /dev/null +++ b/frame/democracy/src/default_weight.rs @@ -0,0 +1,158 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Default weights for the Democracy Pallet +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +/// Default implementation of weight, this is just from an example return, values may change +/// depending on the runtime. This is not meant to be used in production. +impl crate::WeightInfo for () { + fn propose() -> Weight { + (49113000 as Weight) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn second(s: u32, ) -> Weight { + (42067000 as Weight) + .saturating_add((220000 as Weight).saturating_mul(s as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn vote_new(r: u32, ) -> Weight { + (54159000 as Weight) + .saturating_add((252000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn vote_existing(r: u32, ) -> Weight { + (54145000 as Weight) + .saturating_add((262000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn emergency_cancel() -> Weight { + (31071000 as Weight) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn external_propose(v: u32, ) -> Weight { + (14282000 as Weight) + .saturating_add((109000 as Weight).saturating_mul(v as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn external_propose_majority() -> Weight { + (3478000 as Weight) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn external_propose_default() -> Weight { + (3442000 as Weight) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn fast_track() -> Weight { + (30820000 as Weight) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn veto_external(v: u32, ) -> Weight { + (30971000 as Weight) + .saturating_add((184000 as Weight).saturating_mul(v as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn cancel_referendum() -> Weight { + (20431000 as Weight) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn cancel_queued(r: u32, ) -> Weight { + (42438000 as Weight) + .saturating_add((3284000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn on_initialize_base(r: u32, ) -> Weight { + (70826000 as Weight) + .saturating_add((10716000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(6 as Weight)) + .saturating_add(DbWeight::get().reads((2 as Weight).saturating_mul(r as Weight))) + .saturating_add(DbWeight::get().writes(5 as Weight)) + } + fn delegate(r: u32, ) -> Weight { + (72046000 as Weight) + .saturating_add((7837000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(4 as Weight)) + .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight))) + .saturating_add(DbWeight::get().writes(4 as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(r as Weight))) + } + fn undelegate(r: u32, ) -> Weight { + (41028000 as Weight) + .saturating_add((7810000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight))) + .saturating_add(DbWeight::get().writes(2 as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(r as Weight))) + } + fn clear_public_proposals() -> Weight { + (3643000 as Weight) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn note_preimage(b: u32, ) -> Weight { + (46629000 as Weight) + .saturating_add((4000 as Weight).saturating_mul(b as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn note_imminent_preimage(b: u32, ) -> Weight { + (31147000 as Weight) + .saturating_add((3000 as Weight).saturating_mul(b as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn reap_preimage(b: u32, ) -> Weight { + (42848000 as Weight) + .saturating_add((3000 as Weight).saturating_mul(b as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn unlock_remove(r: u32, ) -> Weight { + (45333000 as Weight) + .saturating_add((171000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn unlock_set(r: u32, ) -> Weight { + (44424000 as Weight) + .saturating_add((291000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn remove_vote(r: u32, ) -> Weight { + (28250000 as Weight) + .saturating_add((283000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn remove_other_vote(r: u32, ) -> Weight { + (28250000 as Weight) + .saturating_add((283000 as Weight).saturating_mul(r as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } +} diff --git a/frame/democracy/src/lib.rs b/frame/democracy/src/lib.rs index a182907aba222856293bd681412ac9669295db89..e298b1e4508c2843de3c38009f6cfd68bb6d33c4 100644 --- a/frame/democracy/src/lib.rs +++ b/frame/democracy/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Democracy Pallet //! @@ -51,8 +52,6 @@ //! account or an external origin) suggests that the system adopt. //! - **Referendum:** A proposal that is in the process of being voted on for //! either acceptance or rejection as a change to the system. -//! - **Proxy:** An account that has full voting power on behalf of a separate "Stash" account -//! that holds the funds. //! - **Delegation:** The act of granting your voting power to the decisions of another account for //! up to a certain conviction. //! @@ -92,23 +91,13 @@ //! - `reap_vote` - Remove some account's expired votes. //! - `unlock` - Redetermine the account's balance lock, potentially making tokens available. //! -//! Proxy administration: -//! - `activate_proxy` - Activates a proxy that is already open to the sender. -//! - `close_proxy` - Clears the proxy status, called by the proxy. -//! - `deactivate_proxy` - Deactivates a proxy back to the open status, called by the stash. -//! - `open_proxy` - Opens a proxy account on behalf of the sender. -//! -//! Proxy actions: -//! - `proxy_vote` - Votes in a referendum on behalf of a stash account. -//! - `proxy_unvote` - Cancel a previous vote, done on behalf of the voter by a proxy. -//! - `proxy_delegate` - Delegate voting power, done on behalf of the voter by a proxy. -//! - `proxy_undelegate` - Stop delegating voting power, done on behalf of the voter by a proxy. -//! //! Preimage actions: //! - `note_preimage` - Registers the preimage for an upcoming proposal, requires //! a deposit that is returned once the proposal is enacted. +//! - `note_preimage_operational` - same but provided by `T::OperationalPreimageOrigin`. //! - `note_imminent_preimage` - Registers the preimage for an upcoming proposal. //! Does not require a deposit, but the proposal must be in the dispatch queue. +//! - `note_imminent_preimage_operational` - same but provided by `T::OperationalPreimageOrigin`. //! - `reap_preimage` - Removes the preimage for an expired proposal. Will only //! work under the condition that it's the same account that noted it and //! after the voting period, OR it's a different account after the enactment period. @@ -168,14 +157,15 @@ use sp_runtime::{ DispatchResult, DispatchError, RuntimeDebug, traits::{Zero, Hash, Dispatchable, Saturating}, }; -use codec::{Encode, Decode}; +use codec::{Encode, Decode, Input}; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, ensure, Parameter, - weights::{Weight, DispatchClass}, + weights::{Weight, DispatchClass, Pays}, traits::{ Currency, ReservableCurrency, LockableCurrency, WithdrawReason, LockIdentifier, Get, - OnUnbalanced, BalanceStatus, schedule::Named as ScheduleNamed, EnsureOrigin - } + OnUnbalanced, BalanceStatus, schedule::{Named as ScheduleNamed, DispatchTime}, EnsureOrigin + }, + dispatch::DispatchResultWithPostInfo, }; use frame_system::{self as system, ensure_signed, ensure_root}; @@ -183,10 +173,11 @@ mod vote_threshold; mod vote; mod conviction; mod types; +mod default_weight; pub use vote_threshold::{Approved, VoteThreshold}; pub use vote::{Vote, AccountVote, Voting}; pub use conviction::Conviction; -pub use types::{ReferendumInfo, ReferendumStatus, ProxyState, Tally, UnvoteScope, Delegations}; +pub use types::{ReferendumInfo, ReferendumStatus, Tally, UnvoteScope, Delegations}; #[cfg(test)] mod tests; @@ -196,6 +187,11 @@ pub mod benchmarking; const DEMOCRACY_ID: LockIdentifier = *b"democrac"; +/// The maximum number of vetoers on a single proposal used to compute Weight. +/// +/// NOTE: This is not enforced by any logic. +pub const MAX_VETOERS: u32 = 100; + /// A proposal index. pub type PropIndex = u32; @@ -206,6 +202,32 @@ type BalanceOf = <::Currency as Currency< = <::Currency as Currency<::AccountId>>::NegativeImbalance; +pub trait WeightInfo { + fn propose() -> Weight; + fn second(s: u32, ) -> Weight; + fn vote_new(r: u32, ) -> Weight; + fn vote_existing(r: u32, ) -> Weight; + fn emergency_cancel() -> Weight; + fn external_propose(v: u32, ) -> Weight; + fn external_propose_majority() -> Weight; + fn external_propose_default() -> Weight; + fn fast_track() -> Weight; + fn veto_external(v: u32, ) -> Weight; + fn cancel_referendum() -> Weight; + fn cancel_queued(r: u32, ) -> Weight; + fn on_initialize_base(r: u32, ) -> Weight; + fn delegate(r: u32, ) -> Weight; + fn undelegate(r: u32, ) -> Weight; + fn clear_public_proposals() -> Weight; + fn note_preimage(b: u32, ) -> Weight; + fn note_imminent_preimage(b: u32, ) -> Weight; + fn reap_preimage(b: u32, ) -> Weight; + fn unlock_remove(r: u32, ) -> Weight; + fn unlock_set(r: u32, ) -> Weight; + fn remove_vote(r: u32, ) -> Weight; + fn remove_other_vote(r: u32, ) -> Weight; +} + pub trait Trait: frame_system::Trait + Sized { type Proposal: Parameter + Dispatchable + From>; type Event: From> + Into<::Event>; @@ -264,6 +286,11 @@ pub trait Trait: frame_system::Trait + Sized { type CancellationOrigin: EnsureOrigin; /// Origin for anyone able to veto proposals. + /// + /// # Warning + /// + /// The number of Vetoers for a proposal must be small, extrinsics are weighted according to + /// [MAX_VETOERS](./const.MAX_VETOERS.html) type VetoOrigin: EnsureOrigin; /// Period in blocks where an external proposal may not be re-submitted after being vetoed. @@ -272,11 +299,26 @@ pub trait Trait: frame_system::Trait + Sized { /// The amount of balance that must be deposited per byte of preimage stored. type PreimageByteDeposit: Get>; + /// An origin that can provide a preimage using operational extrinsics. + type OperationalPreimageOrigin: EnsureOrigin; + /// Handler for the unbalanced reduction when slashing a preimage deposit. type Slash: OnUnbalanced>; /// The Scheduler. - type Scheduler: ScheduleNamed; + type Scheduler: ScheduleNamed; + + /// Overarching type of all pallets origins. + type PalletsOrigin: From>; + + /// The maximum number of votes for an account. + /// + /// Also used to compute weight, an overly big value can + /// lead to extrinsic with very big weight: see `delegate` for instance. + type MaxVotes: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } #[derive(Clone, Encode, Decode, RuntimeDebug)] @@ -303,6 +345,14 @@ impl PreimageStatus as Democracy { // TODO: Refactor public proposal queue into its own pallet. @@ -312,8 +362,10 @@ decl_storage! { /// The public proposals. Unsorted. The second item is the proposal's hash. pub PublicProps get(fn public_props): Vec<(PropIndex, T::Hash, T::AccountId)>; /// Those who have locked a deposit. + /// + /// TWOX-NOTE: Safe, as increasing integer keys are safe. pub DepositOf get(fn deposit_of): - map hasher(twox_64_concat) PropIndex => Option<(BalanceOf, Vec)>; + map hasher(twox_64_concat) PropIndex => Option<(Vec, BalanceOf)>; /// Map of hashes to the proposal preimage, along with who registered it and their deposit. /// The block number is the block at which it was deposited. @@ -330,22 +382,22 @@ decl_storage! { pub LowestUnbaked get(fn lowest_unbaked) build(|_| 0 as ReferendumIndex): ReferendumIndex; /// Information concerning any given referendum. + /// + /// TWOX-NOTE: SAFE as indexes are not under an attacker’s control. pub ReferendumInfoOf get(fn referendum_info): map hasher(twox_64_concat) ReferendumIndex => Option>>; /// All votes for a particular voter. We store the balance for the number of votes that we /// have recorded. The second item is the total amount of delegations, that will be added. + /// + /// TWOX-NOTE: SAFE as `AccountId`s are crypto hashes anyway. pub VotingOf: map hasher(twox_64_concat) T::AccountId => Voting, T::AccountId, T::BlockNumber>; - /// Who is able to vote for whom. Value is the fund-holding account, key is the - /// vote-transaction-sending account. - // TODO: Refactor proxy into its own pallet. - // https://github.com/paritytech/substrate/issues/5322 - pub Proxy get(fn proxy): map hasher(twox_64_concat) T::AccountId => Option>; - /// Accounts for which there are locks in action which may be removed at some point in the /// future. The value is the block number at which the lock expires and may be removed. + /// + /// TWOX-NOTE: OK ― `AccountId` is a secure hash. pub Locks get(fn locks): map hasher(twox_64_concat) T::AccountId => Option; /// True if the last referendum tabled was submitted externally. False if it was a public @@ -367,6 +419,11 @@ decl_storage! { /// Record of all proposals that have been subject to emergency cancellation. pub Cancellations: map hasher(identity) T::Hash => bool; + + /// Storage version of the pallet. + /// + /// New networks start with last version. + StorageVersion build(|_| Some(Releases::V1)): Option; } } @@ -377,39 +434,41 @@ decl_event! { ::Hash, ::BlockNumber, { - /// A motion has been proposed by a public account. + /// A motion has been proposed by a public account. [proposal_index, deposit] Proposed(PropIndex, Balance), - /// A public proposal has been tabled for referendum vote. + /// A public proposal has been tabled for referendum vote. [proposal_index, deposit, depositors] Tabled(PropIndex, Balance, Vec), /// An external proposal has been tabled. ExternalTabled, - /// A referendum has begun. + /// A referendum has begun. [ref_index, threshold] Started(ReferendumIndex, VoteThreshold), - /// A proposal has been approved by referendum. + /// A proposal has been approved by referendum. [ref_index] Passed(ReferendumIndex), - /// A proposal has been rejected by referendum. + /// A proposal has been rejected by referendum. [ref_index] NotPassed(ReferendumIndex), - /// A referendum has been cancelled. + /// A referendum has been cancelled. [ref_index] Cancelled(ReferendumIndex), - /// A proposal has been enacted. + /// A proposal has been enacted. [ref_index, is_ok] Executed(ReferendumIndex, bool), - /// An account has delegated their vote to another account. + /// An account has delegated their vote to another account. [who, target] Delegated(AccountId, AccountId), - /// An account has cancelled a previous delegation operation. + /// An [account] has cancelled a previous delegation operation. Undelegated(AccountId), - /// An external proposal has been vetoed. + /// An external proposal has been vetoed. [who, proposal_hash, until] Vetoed(AccountId, Hash, BlockNumber), - /// A proposal's preimage was noted, and the deposit taken. + /// A proposal's preimage was noted, and the deposit taken. [proposal_hash, who, deposit] PreimageNoted(Hash, AccountId, Balance), /// A proposal preimage was removed and used (the deposit was returned). + /// [proposal_hash, provider, deposit] PreimageUsed(Hash, AccountId, Balance), - /// A proposal could not be executed because its preimage was invalid. + /// A proposal could not be executed because its preimage was invalid. [proposal_hash, ref_index] PreimageInvalid(Hash, ReferendumIndex), - /// A proposal could not be executed because its preimage was missing. + /// A proposal could not be executed because its preimage was missing. [proposal_hash, ref_index] PreimageMissing(Hash, ReferendumIndex), - /// A registered preimage was removed and the deposit collected by the reaper (last item). + /// A registered preimage was removed and the deposit collected by the reaper. + /// [proposal_hash, provider, deposit, reaper] PreimageReaped(Hash, AccountId, Balance, AccountId), - /// An account has been unlocked successfully. + /// An [account] has been unlocked successfully. Unlocked(AccountId), } } @@ -420,8 +479,6 @@ decl_error! { ValueLow, /// Proposal does not exist ProposalMissing, - /// Not a proxy - NotProxy, /// Unknown index BadIndex, /// Cannot cancel the same proposal twice @@ -438,10 +495,6 @@ decl_error! { NoProposal, /// Identity may not veto a proposal twice AlreadyVetoed, - /// Already a proxy - AlreadyProxy, - /// Wrong proxy - WrongProxy, /// Not delegated NotDelegated, /// Preimage already noted @@ -464,12 +517,6 @@ decl_error! { NotLocked, /// The lock on the account to be unlocked has not yet expired. NotExpired, - /// A proxy-pairing was attempted to an account that was not open. - NotOpen, - /// A proxy-pairing was attempted to an account that was open to another account. - WrongOpen, - /// A proxy-de-pairing was attempted to an account that was not active. - NotActive, /// The given account did not vote on the referendum. NotVoter, /// The actor has no permission to conduct the action. @@ -491,6 +538,10 @@ decl_error! { InstantNotAllowed, /// Delegation to oneself makes no sense. Nonsense, + /// Invalid upper bound. + WrongUpperBound, + /// Maximum number of votes reached. + MaxVotesReached, } } @@ -523,6 +574,9 @@ decl_module! { /// The amount of balance that must be deposited per byte of preimage stored. const PreimageByteDeposit: BalanceOf = T::PreimageByteDeposit::get(); + /// The maximum number of votes for an account. + const MaxVotes: u32 = T::MaxVotes::get(); + fn deposit_event() = default; /// Propose a sensitive action to be taken. @@ -536,22 +590,20 @@ decl_module! { /// Emits `Proposed`. /// /// # - /// - `O(P)` - /// - P is the number proposals in the `PublicProps` vec. - /// - Two DB changes, one DB entry. + /// - Complexity: `O(1)` + /// - Db reads: `PublicPropCount`, `PublicProps` + /// - Db writes: `PublicPropCount`, `PublicProps`, `DepositOf` /// # - #[weight = 5_000_000_000] - fn propose(origin, - proposal_hash: T::Hash, - #[compact] value: BalanceOf - ) { + #[weight = T::WeightInfo::propose()] + fn propose(origin, proposal_hash: T::Hash, #[compact] value: BalanceOf) { let who = ensure_signed(origin)?; ensure!(value >= T::MinimumDeposit::get(), Error::::ValueLow); + T::Currency::reserve(&who, value)?; let index = Self::public_prop_count(); PublicPropCount::put(index + 1); - >::insert(index, (value, &[&who][..])); + >::insert(index, (&[&who][..], value)); >::append((index, proposal_hash, who)); @@ -564,19 +616,25 @@ decl_module! { /// must have funds to cover the deposit, equal to the original deposit. /// /// - `proposal`: The index of the proposal to second. + /// - `seconds_upper_bound`: an upper bound on the current number of seconds on this + /// proposal. Extrinsic is weighted according to this value with no refund. /// /// # - /// - `O(S)`. - /// - S is the number of seconds a proposal already has. - /// - One DB entry. + /// - Complexity: `O(S)` where S is the number of seconds a proposal already has. + /// - Db reads: `DepositOf` + /// - Db writes: `DepositOf` /// # - #[weight = 5_000_000_000] - fn second(origin, #[compact] proposal: PropIndex) { + #[weight = T::WeightInfo::second(*seconds_upper_bound)] + fn second(origin, #[compact] proposal: PropIndex, #[compact] seconds_upper_bound: u32) { let who = ensure_signed(origin)?; + + let seconds = Self::len_of_deposit_of(proposal) + .ok_or_else(|| Error::::ProposalMissing)?; + ensure!(seconds <= seconds_upper_bound, Error::::WrongUpperBound); let mut deposit = Self::deposit_of(proposal) .ok_or(Error::::ProposalMissing)?; - T::Currency::reserve(&who, deposit.0)?; - deposit.1.push(who); + T::Currency::reserve(&who, deposit.1)?; + deposit.0.push(who); >::insert(proposal, deposit); } @@ -589,11 +647,13 @@ decl_module! { /// - `vote`: The vote configuration. /// /// # - /// - `O(R)`. - /// - R is the number of referendums the voter has voted on. - /// - One DB change, one DB entry. + /// - Complexity: `O(R)` where R is the number of referendums the voter has voted on. + /// weight is charged as if maximum votes. + /// - Db reads: `ReferendumInfoOf`, `VotingOf`, `balances locks` + /// - Db writes: `ReferendumInfoOf`, `VotingOf`, `balances locks` /// # - #[weight = 200_000_000] + #[weight = T::WeightInfo::vote_new(T::MaxVotes::get()) + .max(T::WeightInfo::vote_existing(T::MaxVotes::get()))] fn vote(origin, #[compact] ref_index: ReferendumIndex, vote: AccountVote>, @@ -602,28 +662,6 @@ decl_module! { Self::try_vote(&who, ref_index, vote) } - /// Vote in a referendum on behalf of a stash. If `vote.is_aye()`, the vote is to enact - /// the proposal; otherwise it is a vote to keep the status quo. - /// - /// The dispatch origin of this call must be _Signed_. - /// - /// - `ref_index`: The index of the referendum to proxy vote for. - /// - `vote`: The vote configuration. - /// - /// # - /// - `O(1)`. - /// - One DB change, one DB entry. - /// # - #[weight = 200_000_000] - fn proxy_vote(origin, - #[compact] ref_index: ReferendumIndex, - vote: AccountVote>, - ) -> DispatchResult { - let who = ensure_signed(origin)?; - let voter = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; - Self::try_vote(&voter, ref_index, vote) - } - /// Schedule an emergency cancellation of a referendum. Cannot happen twice to the same /// referendum. /// @@ -632,9 +670,11 @@ decl_module! { /// -`ref_index`: The index of the referendum to cancel. /// /// # - /// - `O(1)`. + /// - Complexity: `O(1)`. + /// - Db reads: `ReferendumInfoOf`, `Cancellations` + /// - Db writes: `ReferendumInfoOf`, `Cancellations` /// # - #[weight = (500_000_000, DispatchClass::Operational)] + #[weight = (T::WeightInfo::emergency_cancel(), DispatchClass::Operational)] fn emergency_cancel(origin, ref_index: ReferendumIndex) { T::CancellationOrigin::ensure_origin(origin)?; @@ -654,10 +694,12 @@ decl_module! { /// - `proposal_hash`: The preimage hash of the proposal. /// /// # - /// - `O(1)`. - /// - One DB change. + /// - Complexity `O(V)` with V number of vetoers in the blacklist of proposal. + /// Decoding vec of length V. Charged as maximum + /// - Db reads: `NextExternal`, `Blacklist` + /// - Db writes: `NextExternal` /// # - #[weight = 5_000_000_000] + #[weight = T::WeightInfo::external_propose(MAX_VETOERS)] fn external_propose(origin, proposal_hash: T::Hash) { T::ExternalOrigin::ensure_origin(origin)?; ensure!(!>::exists(), Error::::DuplicateProposal); @@ -681,10 +723,10 @@ decl_module! { /// pre-scheduled `external_propose` call. /// /// # - /// - `O(1)`. - /// - One DB change. + /// - Complexity: `O(1)` + /// - Db write: `NextExternal` /// # - #[weight = 5_000_000_000] + #[weight = T::WeightInfo::external_propose_majority()] fn external_propose_majority(origin, proposal_hash: T::Hash) { T::ExternalMajorityOrigin::ensure_origin(origin)?; >::put((proposal_hash, VoteThreshold::SimpleMajority)); @@ -701,10 +743,10 @@ decl_module! { /// pre-scheduled `external_propose` call. /// /// # - /// - `O(1)`. - /// - One DB change. + /// - Complexity: `O(1)` + /// - Db write: `NextExternal` /// # - #[weight = 5_000_000_000] + #[weight = T::WeightInfo::external_propose_default()] fn external_propose_default(origin, proposal_hash: T::Hash) { T::ExternalDefaultOrigin::ensure_origin(origin)?; >::put((proposal_hash, VoteThreshold::SuperMajorityAgainst)); @@ -725,11 +767,12 @@ decl_module! { /// Emits `Started`. /// /// # - /// - One DB clear. - /// - One DB change. - /// - One extra DB entry. + /// - Complexity: `O(1)` + /// - Db reads: `NextExternal`, `ReferendumCount` + /// - Db writes: `NextExternal`, `ReferendumCount`, `ReferendumInfoOf` + /// - Base Weight: 30.1 µs /// # - #[weight = 200_000_000] + #[weight = T::WeightInfo::fast_track()] fn fast_track(origin, proposal_hash: T::Hash, voting_period: T::BlockNumber, @@ -774,13 +817,12 @@ decl_module! { /// Emits `Vetoed`. /// /// # - /// - Two DB entries. - /// - One DB clear. - /// - Performs a binary search on `existing_vetoers` which should not - /// be very large. - /// - O(log v), v is number of `existing_vetoers` + /// - Complexity: `O(V + log(V))` where V is number of `existing vetoers` + /// Performs a binary search on `existing_vetoers` which should not be very large. + /// - Db reads: `NextExternal`, `Blacklist` + /// - Db writes: `NextExternal`, `Blacklist` /// # - #[weight = 200_000_000] + #[weight = T::WeightInfo::veto_external(MAX_VETOERS)] fn veto_external(origin, proposal_hash: T::Hash) { let who = T::VetoOrigin::ensure_origin(origin)?; @@ -811,9 +853,10 @@ decl_module! { /// - `ref_index`: The index of the referendum to cancel. /// /// # - /// - `O(1)`. + /// - Complexity: `O(1)`. + /// - Db writes: `ReferendumInfoOf` /// # - #[weight = (0, DispatchClass::Operational)] + #[weight = T::WeightInfo::cancel_referendum()] fn cancel_referendum(origin, #[compact] ref_index: ReferendumIndex) { ensure_root(origin)?; Self::internal_cancel_referendum(ref_index); @@ -826,93 +869,23 @@ decl_module! { /// - `which`: The index of the referendum to cancel. /// /// # - /// - One DB change. - /// - O(d) where d is the items in the dispatch queue. + /// - `O(D)` where `D` is the items in the dispatch queue. Weighted as `D = 10`. + /// - Db reads: `scheduler lookup`, scheduler agenda` + /// - Db writes: `scheduler lookup`, scheduler agenda` /// # - #[weight = (0, DispatchClass::Operational)] + #[weight = (T::WeightInfo::cancel_queued(10), DispatchClass::Operational)] fn cancel_queued(origin, which: ReferendumIndex) { ensure_root(origin)?; T::Scheduler::cancel_named((DEMOCRACY_ID, which).encode()) .map_err(|_| Error::::ProposalMissing)?; } + /// Weight: see `begin_block` fn on_initialize(n: T::BlockNumber) -> Weight { - if let Err(e) = Self::begin_block(n) { + Self::begin_block(n).unwrap_or_else(|e| { sp_runtime::print(e); - } - - 0 - } - - /// Specify a proxy that is already open to us. Called by the stash. - /// - /// NOTE: Used to be called `set_proxy`. - /// - /// The dispatch origin of this call must be _Signed_. - /// - /// - `proxy`: The account that will be activated as proxy. - /// - /// # - /// - One extra DB entry. - /// # - #[weight = 100_000_000] - fn activate_proxy(origin, proxy: T::AccountId) { - let who = ensure_signed(origin)?; - Proxy::::try_mutate(&proxy, |a| match a.take() { - None => Err(Error::::NotOpen), - Some(ProxyState::Active(_)) => Err(Error::::AlreadyProxy), - Some(ProxyState::Open(x)) if &x == &who => { - *a = Some(ProxyState::Active(who)); - Ok(()) - } - Some(ProxyState::Open(_)) => Err(Error::::WrongOpen), - })?; - } - - /// Clear the proxy. Called by the proxy. - /// - /// NOTE: Used to be called `resign_proxy`. - /// - /// The dispatch origin of this call must be _Signed_. - /// - /// # - /// - One DB clear. - /// # - #[weight = 100_000_000] - fn close_proxy(origin) { - let who = ensure_signed(origin)?; - Proxy::::mutate(&who, |a| { - if a.is_some() { - system::Module::::dec_ref(&who); - } - *a = None; - }); - } - - /// Deactivate the proxy, but leave open to this account. Called by the stash. - /// - /// The proxy must already be active. - /// - /// NOTE: Used to be called `remove_proxy`. - /// - /// The dispatch origin of this call must be _Signed_. - /// - /// - `proxy`: The account that will be deactivated as proxy. - /// - /// # - /// - One DB clear. - /// # - #[weight = 100_000_000] - fn deactivate_proxy(origin, proxy: T::AccountId) { - let who = ensure_signed(origin)?; - Proxy::::try_mutate(&proxy, |a| match a.take() { - None | Some(ProxyState::Open(_)) => Err(Error::::NotActive), - Some(ProxyState::Active(x)) if &x == &who => { - *a = Some(ProxyState::Open(who)); - Ok(()) - } - Some(ProxyState::Active(_)) => Err(Error::::WrongProxy), - })?; + 0 + }) } /// Delegate the voting power (with some given conviction) of the sending account. @@ -934,11 +907,26 @@ decl_module! { /// Emits `Delegated`. /// /// # + /// - Complexity: `O(R)` where R is the number of referendums the voter delegating to has + /// voted on. Weight is charged as if maximum votes. + /// - Db reads: 3*`VotingOf`, `origin account locks` + /// - Db writes: 3*`VotingOf`, `origin account locks` + /// - Db reads per votes: `ReferendumInfoOf` + /// - Db writes per votes: `ReferendumInfoOf` + // NOTE: weight must cover an incorrect voting of origin with max votes, this is ensure + // because a valid delegation cover decoding a direct voting with max votes. /// # - #[weight = 500_000_000] - pub fn delegate(origin, to: T::AccountId, conviction: Conviction, balance: BalanceOf) { + #[weight = T::WeightInfo::delegate(T::MaxVotes::get())] + pub fn delegate( + origin, + to: T::AccountId, + conviction: Conviction, + balance: BalanceOf + ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - Self::try_delegate(who, to, conviction, balance)?; + let votes = Self::try_delegate(who, to, conviction, balance)?; + + Ok(Some(T::WeightInfo::delegate(votes)).into()) } /// Undelegate the voting power of the sending account. @@ -952,12 +940,20 @@ decl_module! { /// Emits `Undelegated`. /// /// # - /// - O(1). + /// - Complexity: `O(R)` where R is the number of referendums the voter delegating to has + /// voted on. Weight is charged as if maximum votes. + /// - Db reads: 2*`VotingOf` + /// - Db writes: 2*`VotingOf` + /// - Db reads per votes: `ReferendumInfoOf` + /// - Db writes per votes: `ReferendumInfoOf` + // NOTE: weight must cover an incorrect voting of origin with max votes, this is ensure + // because a valid delegation cover decoding a direct voting with max votes. /// # - #[weight = 500_000_000] - fn undelegate(origin) { + #[weight = T::WeightInfo::undelegate(T::MaxVotes::get().into())] + fn undelegate(origin) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - Self::try_undelegate(who)?; + let votes = Self::try_undelegate(who)?; + Ok(Some(T::WeightInfo::undelegate(votes)).into()) } /// Clears all public proposals. @@ -966,12 +962,11 @@ decl_module! { /// /// # /// - `O(1)`. - /// - One DB clear. + /// - Db writes: `PublicProps` /// # - #[weight = 0] + #[weight = T::WeightInfo::clear_public_proposals()] fn clear_public_proposals(origin) { ensure_root(origin)?; - >::kill(); } @@ -985,34 +980,29 @@ decl_module! { /// Emits `PreimageNoted`. /// /// # - /// - Dependent on the size of `encoded_proposal` but protected by a - /// required deposit. + /// - Complexity: `O(E)` with E size of `encoded_proposal` (protected by a required deposit). + /// - Db reads: `Preimages` + /// - Db writes: `Preimages` /// # - #[weight = 100_000_000] + #[weight = T::WeightInfo::note_preimage(encoded_proposal.len() as u32)] fn note_preimage(origin, encoded_proposal: Vec) { - let who = ensure_signed(origin)?; - let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); - ensure!(!>::contains_key(&proposal_hash), Error::::DuplicatePreimage); - - let deposit = >::from(encoded_proposal.len() as u32) - .saturating_mul(T::PreimageByteDeposit::get()); - T::Currency::reserve(&who, deposit)?; - - let now = >::block_number(); - let a = PreimageStatus::Available { - data: encoded_proposal, - provider: who.clone(), - deposit, - since: now, - expiry: None, - }; - >::insert(proposal_hash, a); + Self::note_preimage_inner(ensure_signed(origin)?, encoded_proposal)?; + } - Self::deposit_event(RawEvent::PreimageNoted(proposal_hash, who, deposit)); + /// Same as `note_preimage` but origin is `OperationalPreimageOrigin`. + #[weight = ( + T::WeightInfo::note_preimage(encoded_proposal.len() as u32), + DispatchClass::Operational, + )] + fn note_preimage_operational(origin, encoded_proposal: Vec) { + let who = T::OperationalPreimageOrigin::ensure_origin(origin)?; + Self::note_preimage_inner(who, encoded_proposal)?; } /// Register the preimage for an upcoming proposal. This requires the proposal to be - /// in the dispatch queue. No deposit is needed. + /// in the dispatch queue. No deposit is needed. When this call is successful, i.e. + /// the preimage has not been uploaded before and matches some imminent proposal, + /// no fee is paid. /// /// The dispatch origin of this call must be _Signed_. /// @@ -1021,27 +1011,29 @@ decl_module! { /// Emits `PreimageNoted`. /// /// # - /// - Dependent on the size of `encoded_proposal` and length of dispatch queue. + /// - Complexity: `O(E)` with E size of `encoded_proposal` (protected by a required deposit). + /// - Db reads: `Preimages` + /// - Db writes: `Preimages` /// # - #[weight = 100_000_000] - fn note_imminent_preimage(origin, encoded_proposal: Vec) { - let who = ensure_signed(origin)?; - let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); - let status = Preimages::::get(&proposal_hash).ok_or(Error::::NotImminent)?; - let expiry = status.to_missing_expiry().ok_or(Error::::DuplicatePreimage)?; - - let now = >::block_number(); - let free = >::zero(); - let a = PreimageStatus::Available { - data: encoded_proposal, - provider: who.clone(), - deposit: Zero::zero(), - since: now, - expiry: Some(expiry), - }; - >::insert(proposal_hash, a); + #[weight = T::WeightInfo::note_imminent_preimage(encoded_proposal.len() as u32)] + fn note_imminent_preimage(origin, encoded_proposal: Vec) -> DispatchResultWithPostInfo { + Self::note_imminent_preimage_inner(ensure_signed(origin)?, encoded_proposal)?; + // We check that this preimage was not uploaded before in `note_imminent_preimage_inner`, + // thus this call can only be successful once. If successful, user does not pay a fee. + Ok(Pays::No.into()) + } - Self::deposit_event(RawEvent::PreimageNoted(proposal_hash, who, free)); + /// Same as `note_imminent_preimage` but origin is `OperationalPreimageOrigin`. + #[weight = ( + T::WeightInfo::note_imminent_preimage(encoded_proposal.len() as u32), + DispatchClass::Operational, + )] + fn note_imminent_preimage_operational(origin, encoded_proposal: Vec) -> DispatchResultWithPostInfo { + let who = T::OperationalPreimageOrigin::ensure_origin(origin)?; + Self::note_imminent_preimage_inner(who, encoded_proposal)?; + // We check that this preimage was not uploaded before in `note_imminent_preimage_inner`, + // thus this call can only be successful once. If successful, user does not pay a fee. + Ok(Pays::No.into()) } /// Remove an expired proposal preimage and collect the deposit. @@ -1049,6 +1041,8 @@ decl_module! { /// The dispatch origin of this call must be _Signed_. /// /// - `proposal_hash`: The preimage hash of a proposal. + /// - `proposal_length_upper_bound`: an upper bound on length of the proposal. + /// Extrinsic is weighted according to this value with no refund. /// /// This will only work after `VotingPeriod` blocks from the time that the preimage was /// noted, if it's the same account doing it. If it's a different account, then it'll only @@ -1057,11 +1051,19 @@ decl_module! { /// Emits `PreimageReaped`. /// /// # - /// - One DB clear. + /// - Complexity: `O(D)` where D is length of proposal. + /// - Db reads: `Preimages`, provider account data + /// - Db writes: `Preimages` provider account data /// # - #[weight = 0] - fn reap_preimage(origin, proposal_hash: T::Hash) { + #[weight = T::WeightInfo::reap_preimage(*proposal_len_upper_bound)] + fn reap_preimage(origin, proposal_hash: T::Hash, #[compact] proposal_len_upper_bound: u32) { let who = ensure_signed(origin)?; + + ensure!( + Self::pre_image_data_len(proposal_hash)? <= proposal_len_upper_bound, + Error::::WrongUpperBound, + ); + let (provider, deposit, since, expiry) = >::get(&proposal_hash) .and_then(|m| match m { PreimageStatus::Available { provider, deposit, since, expiry, .. } @@ -1087,38 +1089,17 @@ decl_module! { /// - `target`: The account to remove the lock on. /// /// # - /// - `O(1)`. + /// - Complexity `O(R)` with R number of vote of target. + /// - Db reads: `VotingOf`, `balances locks`, `target account` + /// - Db writes: `VotingOf`, `balances locks`, `target account` /// # - #[weight = 0] + #[weight = T::WeightInfo::unlock_set(T::MaxVotes::get()) + .max(T::WeightInfo::unlock_remove(T::MaxVotes::get()))] fn unlock(origin, target: T::AccountId) { ensure_signed(origin)?; Self::update_lock(&target); } - /// Become a proxy. - /// - /// This must be called prior to a later `activate_proxy`. - /// - /// Origin must be a Signed. - /// - /// - `target`: The account whose votes will later be proxied. - /// - /// `close_proxy` must be called before the account can be destroyed. - /// - /// # - /// - One extra DB entry. - /// # - #[weight = 100_000_000] - fn open_proxy(origin, target: T::AccountId) { - let who = ensure_signed(origin)?; - Proxy::::mutate(&who, |a| { - if a.is_none() { - system::Module::::inc_ref(&who); - } - *a = Some(ProxyState::Open(target)); - }); - } - /// Remove a vote for a referendum. /// /// If: @@ -1146,8 +1127,11 @@ decl_module! { /// /// # /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. + /// Weight is calculated for the maximum number of vote. + /// - Db reads: `ReferendumInfoOf`, `VotingOf` + /// - Db writes: `ReferendumInfoOf`, `VotingOf` /// # - #[weight = 0] + #[weight = T::WeightInfo::remove_vote(T::MaxVotes::get())] fn remove_vote(origin, index: ReferendumIndex) -> DispatchResult { let who = ensure_signed(origin)?; Self::try_remove_vote(&who, index, UnvoteScope::Any) @@ -1168,8 +1152,11 @@ decl_module! { /// /// # /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. + /// Weight is calculated for the maximum number of vote. + /// - Db reads: `ReferendumInfoOf`, `VotingOf` + /// - Db writes: `ReferendumInfoOf`, `VotingOf` /// # - #[weight = 0] + #[weight = T::WeightInfo::remove_other_vote(T::MaxVotes::get())] fn remove_other_vote(origin, target: T::AccountId, index: ReferendumIndex) -> DispatchResult { let who = ensure_signed(origin)?; let scope = if target == who { UnvoteScope::Any } else { UnvoteScope::OnlyExpired }; @@ -1177,80 +1164,6 @@ decl_module! { Ok(()) } - /// Delegate the voting power (with some given conviction) of a proxied account. - /// - /// The balance delegated is locked for as long as it's delegated, and thereafter for the - /// time appropriate for the conviction's lock period. - /// - /// The dispatch origin of this call must be _Signed_, and the signing account must have - /// been set as the proxy account for `target`. - /// - /// - `target`: The account whole voting power shall be delegated and whose balance locked. - /// This account must either: - /// - be delegating already; or - /// - have no voting activity (if there is, then it will need to be removed/consolidated - /// through `reap_vote` or `unvote`). - /// - `to`: The account whose voting the `target` account's voting power will follow. - /// - `conviction`: The conviction that will be attached to the delegated votes. When the - /// account is undelegated, the funds will be locked for the corresponding period. - /// - `balance`: The amount of the account's balance to be used in delegating. This must - /// not be more than the account's current balance. - /// - /// Emits `Delegated`. - /// - /// # - /// # - #[weight = 500_000_000] - pub fn proxy_delegate(origin, - to: T::AccountId, - conviction: Conviction, - balance: BalanceOf, - ) { - let who = ensure_signed(origin)?; - let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; - Self::try_delegate(target, to, conviction, balance)?; - } - - /// Undelegate the voting power of a proxied account. - /// - /// Tokens may be unlocked following once an amount of time consistent with the lock period - /// of the conviction with which the delegation was issued. - /// - /// The dispatch origin of this call must be _Signed_ and the signing account must be a - /// proxy for some other account which is currently delegating. - /// - /// Emits `Undelegated`. - /// - /// # - /// - O(1). - /// # - #[weight = 500_000_000] - fn proxy_undelegate(origin) { - let who = ensure_signed(origin)?; - let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; - Self::try_undelegate(target)?; - } - - /// Remove a proxied vote for a referendum. - /// - /// Exactly equivalent to `remove_vote` except that it operates on the account that the - /// sender is a proxy for. - /// - /// The dispatch origin of this call must be _Signed_ and the signing account must be a - /// proxy for some other account which has a registered vote for the referendum of `index`. - /// - /// - `index`: The index of referendum of the vote to be removed. - /// - /// # - /// - `O(R + log R)` where R is the number of referenda that `target` has voted on. - /// # - #[weight = 0] - fn proxy_remove_vote(origin, index: ReferendumIndex) -> DispatchResult { - let who = ensure_signed(origin)?; - let target = Self::proxy(who).and_then(|a| a.as_active()).ok_or(Error::::NotProxy)?; - Self::try_remove_vote(&target, index, UnvoteScope::Any) - } - /// Enact a proposal from a referendum. For now we just make the weight be the maximum. #[weight = T::MaximumBlockWeight::get()] fn enact_proposal(origin, proposal_hash: T::Hash, index: ReferendumIndex) -> DispatchResult { @@ -1266,7 +1179,7 @@ impl Module { /// Get the amount locked in support of `proposal`; `None` if proposal isn't a valid proposal /// index. pub fn backing_for(proposal: PropIndex) -> Option> { - Self::deposit_of(proposal).map(|(d, l)| d * (l.len() as u32).into()) + Self::deposit_of(proposal).map(|(l, d)| d * (l.len() as u32).into()) } /// Get all referenda ready for tally at block `n`. @@ -1275,7 +1188,14 @@ impl Module { ) -> Vec<(ReferendumIndex, ReferendumStatus>)> { let next = Self::lowest_unbaked(); let last = Self::referendum_count(); - (next..last).into_iter() + Self::maturing_referenda_at_inner(n, next..last) + } + + fn maturing_referenda_at_inner( + n: T::BlockNumber, + range: core::ops::Range, + ) -> Vec<(ReferendumIndex, ReferendumStatus>)> { + range.into_iter() .map(|i| (i, Self::referendum_info(i))) .filter_map(|(i, maybe_info)| match maybe_info { Some(ReferendumInfo::Ongoing(status)) => Some((i, status)), @@ -1287,16 +1207,6 @@ impl Module { // Exposed mutables. - #[cfg(feature = "std")] - pub fn force_proxy(stash: T::AccountId, proxy: T::AccountId) { - Proxy::::mutate(&proxy, |o| { - if o.is_none() { - system::Module::::inc_ref(&proxy); - } - *o = Some(ProxyState::Active(stash)) - }) - } - /// Start a referendum. pub fn internal_start_referendum( proposal_hash: T::Hash, @@ -1352,7 +1262,10 @@ impl Module { } votes[i].1 = vote; } - Err(i) => votes.insert(i, (ref_index, vote)), + Err(i) => { + ensure!(votes.len() as u32 <= T::MaxVotes::get(), Error::::MaxVotesReached); + votes.insert(i, (ref_index, vote)); + } } // Shouldn't be possible to fail, but we handle it gracefully. status.tally.add(vote).ok_or(Error::::Overflow)?; @@ -1415,11 +1328,14 @@ impl Module { Ok(()) } - fn increase_upstream_delegation(who: &T::AccountId, amount: Delegations>) { + /// Return the number of votes for `who` + fn increase_upstream_delegation(who: &T::AccountId, amount: Delegations>) -> u32 { VotingOf::::mutate(who, |voting| match voting { - Voting::Delegating { delegations, .. } => + Voting::Delegating { delegations, .. } => { // We don't support second level delegating, so we don't need to do anything more. - *delegations = delegations.saturating_add(amount), + *delegations = delegations.saturating_add(amount); + 1 + }, Voting::Direct { votes, delegations, .. } => { *delegations = delegations.saturating_add(amount); for &(ref_index, account_vote) in votes.iter() { @@ -1431,15 +1347,19 @@ impl Module { ); } } + votes.len() as u32 } }) } - fn reduce_upstream_delegation(who: &T::AccountId, amount: Delegations>) { + /// Return the number of votes for `who` + fn reduce_upstream_delegation(who: &T::AccountId, amount: Delegations>) -> u32 { VotingOf::::mutate(who, |voting| match voting { - Voting::Delegating { delegations, .. } => - // We don't support second level delegating, so we don't need to do anything more. - *delegations = delegations.saturating_sub(amount), + Voting::Delegating { delegations, .. } => { + // We don't support second level delegating, so we don't need to do anything more. + *delegations = delegations.saturating_sub(amount); + 1 + } Voting::Direct { votes, delegations, .. } => { *delegations = delegations.saturating_sub(amount); for &(ref_index, account_vote) in votes.iter() { @@ -1451,20 +1371,23 @@ impl Module { ); } } + votes.len() as u32 } }) } /// Attempt to delegate `balance` times `conviction` of voting power from `who` to `target`. + /// + /// Return the upstream number of votes. fn try_delegate( who: T::AccountId, target: T::AccountId, conviction: Conviction, balance: BalanceOf, - ) -> DispatchResult { + ) -> Result { ensure!(who != target, Error::::Nonsense); ensure!(balance <= T::Currency::free_balance(&who), Error::::InsufficientFunds); - VotingOf::::try_mutate(&who, |voting| -> DispatchResult { + let votes = VotingOf::::try_mutate(&who, |voting| -> Result { let mut old = Voting::Delegating { balance, target: target.clone(), @@ -1485,7 +1408,7 @@ impl Module { voting.set_common(delegations, prior); } } - Self::increase_upstream_delegation(&target, conviction.votes(balance)); + let votes = Self::increase_upstream_delegation(&target, conviction.votes(balance)); // Extend the lock to `balance` (rather than setting it) since we don't know what other // votes are in place. T::Currency::extend_lock( @@ -1494,15 +1417,17 @@ impl Module { balance, WithdrawReason::Transfer.into() ); - Ok(()) + Ok(votes) })?; Self::deposit_event(Event::::Delegated(who, target)); - Ok(()) + Ok(votes) } /// Attempt to end the current delegation. - fn try_undelegate(who: T::AccountId) -> DispatchResult { - VotingOf::::try_mutate(&who, |voting| -> DispatchResult { + /// + /// Return the number of votes of upstream. + fn try_undelegate(who: T::AccountId) -> Result { + let votes = VotingOf::::try_mutate(&who, |voting| -> Result { let mut old = Voting::default(); sp_std::mem::swap(&mut old, voting); match old { @@ -1514,20 +1439,21 @@ impl Module { mut prior, } => { // remove any delegation votes to our current target. - Self::reduce_upstream_delegation(&target, conviction.votes(balance)); + let votes = Self::reduce_upstream_delegation(&target, conviction.votes(balance)); let now = system::Module::::block_number(); let lock_periods = conviction.lock_periods().into(); prior.accumulate(now + T::EnactmentPeriod::get() * lock_periods, balance); voting.set_common(delegations, prior); + + Ok(votes) } Voting::Direct { .. } => { - return Err(Error::::NotDelegating.into()) + Err(Error::::NotDelegating.into()) } } - Ok(()) })?; Self::deposit_event(Event::::Undelegated(who)); - Ok(()) + Ok(votes) } /// Rejig the lock on an account. It will never get more stringent (since that would indicate @@ -1597,7 +1523,7 @@ impl Module { let (prop_index, proposal, _) = public_props.swap_remove(winner_index); >::put(public_props); - if let Some((deposit, depositors)) = >::take(prop_index) { + if let Some((depositors, deposit)) = >::take(prop_index) { // refund depositors for d in &depositors { T::Currency::unreserve(d, deposit); @@ -1660,9 +1586,10 @@ impl Module { if T::Scheduler::schedule_named( (DEMOCRACY_ID, index).encode(), - when, + DispatchTime::At(when), None, 63, + system::RawOrigin::Root.into(), Call::enact_proposal(status.proposal_hash, index).into(), ).is_err() { frame_support::print("LOGIC ERROR: bake_referendum/schedule_named failed"); @@ -1676,19 +1603,178 @@ impl Module { } /// Current era is ending; we should finish up any proposals. - fn begin_block(now: T::BlockNumber) -> DispatchResult { + /// + /// + /// # + /// If a referendum is launched or maturing take full block weight. Otherwise: + /// - Complexity: `O(R)` where `R` is the number of unbaked referenda. + /// - Db reads: `LastTabledWasExternal`, `NextExternal`, `PublicProps`, `account`, + /// `ReferendumCount`, `LowestUnbaked` + /// - Db writes: `PublicProps`, `account`, `ReferendumCount`, `DepositOf`, `ReferendumInfoOf` + /// - Db reads per R: `DepositOf`, `ReferendumInfoOf` + /// # + fn begin_block(now: T::BlockNumber) -> Result { + let mut weight = 0; + // pick out another public referendum if it's time. if (now % T::LaunchPeriod::get()).is_zero() { // Errors come from the queue being empty. we don't really care about that, and even if // we did, there is nothing we can do here. let _ = Self::launch_next(now); + weight = T::MaximumBlockWeight::get(); } + let next = Self::lowest_unbaked(); + let last = Self::referendum_count(); + let r = last.saturating_sub(next); + weight = weight.saturating_add(T::WeightInfo::on_initialize_base(r)); // tally up votes for any expiring referenda. - for (index, info) in Self::maturing_referenda_at(now).into_iter() { + for (index, info) in Self::maturing_referenda_at_inner(now, next..last).into_iter() { let approved = Self::bake_referendum(now, index, info)?; ReferendumInfoOf::::insert(index, ReferendumInfo::Finished { end: now, approved }); + weight = T::MaximumBlockWeight::get(); } + + Ok(weight) + } + + /// Reads the length of account in DepositOf without getting the complete value in the runtime. + /// + /// Return 0 if no deposit for this proposal. + fn len_of_deposit_of(proposal: PropIndex) -> Option { + // DepositOf first tuple element is a vec, decoding its len is equivalent to decode a + // `Compact`. + decode_compact_u32_at(&>::hashed_key_for(proposal)) + } + + /// Check that pre image exists and its value is variant `PreimageStatus::Missing`. + /// + /// This check is done without getting the complete value in the runtime to avoid copying a big + /// value in the runtime. + fn check_pre_image_is_missing(proposal_hash: T::Hash) -> DispatchResult { + // To decode the enum variant we only need the first byte. + let mut buf = [0u8; 1]; + let key = >::hashed_key_for(proposal_hash); + let bytes = match sp_io::storage::read(&key, &mut buf, 0) { + Some(bytes) => bytes, + None => return Err(Error::::NotImminent.into()), + }; + // The value may be smaller that 1 byte. + let mut input = &buf[0..buf.len().min(bytes as usize)]; + + match input.read_byte() { + Ok(0) => Ok(()), // PreimageStatus::Missing is variant 0 + Ok(1) => Err(Error::::DuplicatePreimage.into()), + _ => { + sp_runtime::print("Failed to decode `PreimageStatus` variant"); + Err(Error::::NotImminent.into()) + } + } + } + + /// Check that pre image exists, its value is variant `PreimageStatus::Available` and decode + /// the length of `data: Vec` fields. + /// + /// This check is done without getting the complete value in the runtime to avoid copying a big + /// value in the runtime. + /// + /// If the pre image is missing variant or doesn't exist then the error `PreimageMissing` is + /// returned. + fn pre_image_data_len(proposal_hash: T::Hash) -> Result { + // To decode the `data` field of Available variant we need: + // * one byte for the variant + // * at most 5 bytes to decode a `Compact` + let mut buf = [0u8; 6]; + let key = >::hashed_key_for(proposal_hash); + let bytes = match sp_io::storage::read(&key, &mut buf, 0) { + Some(bytes) => bytes, + None => return Err(Error::::PreimageMissing.into()), + }; + // The value may be smaller that 6 bytes. + let mut input = &buf[0..buf.len().min(bytes as usize)]; + + match input.read_byte() { + Ok(1) => (), // Check that input exists and is second variant. + Ok(0) => return Err(Error::::PreimageMissing.into()), + _ => { + sp_runtime::print("Failed to decode `PreimageStatus` variant"); + return Err(Error::::PreimageMissing.into()); + } + } + + // Decode the length of the vector. + let len = codec::Compact::::decode(&mut input).map_err(|_| { + sp_runtime::print("Failed to decode `PreimageStatus` variant"); + DispatchError::from(Error::::PreimageMissing) + })?.0; + + Ok(len) + } + + // See `note_preimage` + fn note_preimage_inner(who: T::AccountId, encoded_proposal: Vec) -> DispatchResult { + let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); + ensure!(!>::contains_key(&proposal_hash), Error::::DuplicatePreimage); + + let deposit = >::from(encoded_proposal.len() as u32) + .saturating_mul(T::PreimageByteDeposit::get()); + T::Currency::reserve(&who, deposit)?; + + let now = >::block_number(); + let a = PreimageStatus::Available { + data: encoded_proposal, + provider: who.clone(), + deposit, + since: now, + expiry: None, + }; + >::insert(proposal_hash, a); + + Self::deposit_event(RawEvent::PreimageNoted(proposal_hash, who, deposit)); + Ok(()) } + + // See `note_imminent_preimage` + fn note_imminent_preimage_inner(who: T::AccountId, encoded_proposal: Vec) -> DispatchResult { + let proposal_hash = T::Hashing::hash(&encoded_proposal[..]); + Self::check_pre_image_is_missing(proposal_hash)?; + let status = Preimages::::get(&proposal_hash).ok_or(Error::::NotImminent)?; + let expiry = status.to_missing_expiry().ok_or(Error::::DuplicatePreimage)?; + + let now = >::block_number(); + let free = >::zero(); + let a = PreimageStatus::Available { + data: encoded_proposal, + provider: who.clone(), + deposit: Zero::zero(), + since: now, + expiry: Some(expiry), + }; + >::insert(proposal_hash, a); + + Self::deposit_event(RawEvent::PreimageNoted(proposal_hash, who, free)); + + Ok(()) + } +} + +/// Decode `Compact` from the trie at given key. +fn decode_compact_u32_at(key: &[u8]) -> Option { + // `Compact` takes at most 5 bytes. + let mut buf = [0u8; 5]; + let bytes = match sp_io::storage::read(&key, &mut buf, 0) { + Some(bytes) => bytes, + None => return None, + }; + // The value may be smaller than 5 bytes. + let mut input = &buf[0..buf.len().min(bytes as usize)]; + match codec::Compact::::decode(&mut input) { + Ok(c) => Some(c.0), + Err(_) => { + sp_runtime::print("Failed to decode compact u32 at:"); + sp_runtime::print(key); + None + } + } } diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index a835a0ff6ee1e63491bc4baf51a8a11b60fa6fc1..13c6a09a04bc15993b59a2056b321595e688f8fd 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! The crate's tests. @@ -21,7 +22,8 @@ use std::cell::RefCell; use codec::Encode; use frame_support::{ impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types, - impl_outer_event, ord_parameter_types, traits::{Contains, OnInitialize}, weights::Weight, + impl_outer_event, ord_parameter_types, traits::{Contains, OnInitialize, Filter}, + weights::Weight, }; use sp_core::H256; use sp_runtime::{ @@ -29,7 +31,7 @@ use sp_runtime::{ testing::Header, Perbill, }; use pallet_balances::{BalanceLock, Error as BalancesError}; -use frame_system::EnsureSignedBy; +use frame_system::{EnsureSignedBy, EnsureRoot}; mod cancellation; mod delegation; @@ -37,10 +39,10 @@ mod external_proposing; mod fast_tracking; mod lock_voting; mod preimage; -mod proxying; mod public_proposals; mod scheduling; mod voting; +mod decoders; const AYE: Vote = Vote { aye: true, conviction: Conviction::None }; const NAY: Vote = Vote { aye: false, conviction: Conviction::None }; @@ -48,7 +50,7 @@ const BIG_AYE: Vote = Vote { aye: true, conviction: Conviction::Locked1x }; const BIG_NAY: Vote = Vote { aye: false, conviction: Conviction::Locked1x }; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } impl_outer_dispatch! { @@ -72,6 +74,14 @@ impl_outer_event! { } } +// Test that a fitlered call can be dispatched. +pub struct BaseFilter; +impl Filter for BaseFilter { + fn filter(call: &Call) -> bool { + !matches!(call, &Call::Balances(pallet_balances::Call::set_balance(..))) + } +} + // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, Eq, PartialEq, Debug)] pub struct Test; @@ -82,6 +92,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = BaseFilter; type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -97,6 +108,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -104,15 +116,19 @@ impl frame_system::Trait for Test { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { - pub const MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); } impl pallet_scheduler::Trait for Test { type Event = Event; type Origin = Origin; + type PalletsOrigin = OriginCaller; type Call = Call; type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureRoot; + type WeightInfo = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; @@ -123,6 +139,7 @@ impl pallet_balances::Trait for Test { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { pub const LaunchPeriod: u64 = 2; @@ -131,6 +148,7 @@ parameter_types! { pub const MinimumDeposit: u64 = 1; pub const EnactmentPeriod: u64 = 2; pub const CooloffPeriod: u64 = 2; + pub const MaxVotes: u32 = 100; } ord_parameter_types! { pub const One: u64 = 1; @@ -181,6 +199,10 @@ impl super::Trait for Test { type InstantOrigin = EnsureSignedBy; type InstantAllowed = InstantAllowed; type Scheduler = Scheduler; + type MaxVotes = MaxVotes; + type OperationalPreimageOrigin = EnsureSignedBy; + type PalletsOrigin = OriginCaller; + type WeightInfo = (); } pub fn new_test_ext() -> sp_io::TestExternalities { @@ -194,6 +216,12 @@ pub fn new_test_ext() -> sp_io::TestExternalities { ext } +/// Execute the function two times, with `true` and with `false`. +pub fn new_test_ext_execute_with_cond(execute: impl FnOnce(bool) -> () + Clone) { + new_test_ext().execute_with(|| (execute.clone())(false)); + new_test_ext().execute_with(|| execute(true)); +} + type System = frame_system::Module; type Balances = pallet_balances::Module; type Scheduler = pallet_scheduler::Module; @@ -212,6 +240,14 @@ fn set_balance_proposal(value: u64) -> Vec { Call::Balances(pallet_balances::Call::set_balance(42, value, 0)).encode() } +#[test] +fn set_balance_proposal_is_correctly_filtered_out() { + for i in 0..10 { + let call = Call::decode(&mut &set_balance_proposal(i)[..]).unwrap(); + assert!(!::BaseCallFilter::filter(&call)); + } +} + fn set_balance_proposal_hash(value: u64) -> H256 { BlakeTwo256::hash(&set_balance_proposal(value)[..]) } @@ -231,7 +267,7 @@ fn propose_set_balance(who: u64, value: u64, delay: u64) -> DispatchResult { Democracy::propose( Origin::signed(who), set_balance_proposal_hash(value), - delay + delay, ) } @@ -239,14 +275,14 @@ fn propose_set_balance_and_note(who: u64, value: u64, delay: u64) -> DispatchRes Democracy::propose( Origin::signed(who), set_balance_proposal_hash_and_note(value), - delay + delay, ) } fn next_block() { System::set_block_number(System::block_number() + 1); Scheduler::on_initialize(System::block_number()); - assert_eq!(Democracy::begin_block(System::block_number()), Ok(())); + assert!(Democracy::begin_block(System::block_number()).is_ok()); } fn fast_forward_to(n: u64) { diff --git a/frame/democracy/src/tests/cancellation.rs b/frame/democracy/src/tests/cancellation.rs index 998b0c14d8c8074738f847b8d7b9497e3340b4b5..4221865a3e5b0cda7ced129ee0f60e31e728705e 100644 --- a/frame/democracy/src/tests/cancellation.rs +++ b/frame/democracy/src/tests/cancellation.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The tests for cancelation functionality. @@ -28,7 +29,7 @@ fn cancel_referendum_should_work() { 0 ); assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); - assert_ok!(Democracy::cancel_referendum(Origin::ROOT, r.into())); + assert_ok!(Democracy::cancel_referendum(Origin::root(), r.into())); next_block(); next_block(); @@ -52,8 +53,8 @@ fn cancel_queued_should_work() { assert!(pallet_scheduler::Agenda::::get(6)[0].is_some()); - assert_noop!(Democracy::cancel_queued(Origin::ROOT, 1), Error::::ProposalMissing); - assert_ok!(Democracy::cancel_queued(Origin::ROOT, 0)); + assert_noop!(Democracy::cancel_queued(Origin::root(), 1), Error::::ProposalMissing); + assert_ok!(Democracy::cancel_queued(Origin::root(), 0)); assert!(pallet_scheduler::Agenda::::get(6)[0].is_none()); }); } diff --git a/frame/democracy/src/tests/decoders.rs b/frame/democracy/src/tests/decoders.rs new file mode 100644 index 0000000000000000000000000000000000000000..6b8e661ca9fd9715e9dea882eb3c1e580535eb77 --- /dev/null +++ b/frame/democracy/src/tests/decoders.rs @@ -0,0 +1,81 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! The for various partial storage decoders + +use super::*; +use frame_support::storage::{migration, StorageMap, unhashed}; + +#[test] +fn test_decode_compact_u32_at() { + new_test_ext().execute_with(|| { + let v = codec::Compact(u64::max_value()); + migration::put_storage_value(b"test", b"", &[], v); + assert_eq!(decode_compact_u32_at(b"test"), None); + + for v in vec![0, 10, u32::max_value()] { + let compact_v = codec::Compact(v); + unhashed::put(b"test", &compact_v); + assert_eq!(decode_compact_u32_at(b"test"), Some(v)); + } + + unhashed::kill(b"test"); + assert_eq!(decode_compact_u32_at(b"test"), None); + }) +} + +#[test] +fn len_of_deposit_of() { + new_test_ext().execute_with(|| { + for l in vec![0, 1, 200, 1000] { + let value: (Vec, u64) = ((0..l).map(|_| Default::default()).collect(), 3u64); + DepositOf::::insert(2, value); + assert_eq!(Democracy::len_of_deposit_of(2), Some(l)); + } + + DepositOf::::remove(2); + assert_eq!(Democracy::len_of_deposit_of(2), None); + }) +} + +#[test] +fn pre_image() { + new_test_ext().execute_with(|| { + let key = Default::default(); + let missing = PreimageStatus::Missing(0); + Preimages::::insert(key, missing); + assert!(Democracy::pre_image_data_len(key).is_err()); + assert_eq!(Democracy::check_pre_image_is_missing(key), Ok(())); + + Preimages::::remove(key); + assert!(Democracy::pre_image_data_len(key).is_err()); + assert!(Democracy::check_pre_image_is_missing(key).is_err()); + + for l in vec![0, 10, 100, 1000u32] { + let available = PreimageStatus::Available{ + data: (0..l).map(|i| i as u8).collect(), + provider: 0, + deposit: 0, + since: 0, + expiry: None, + }; + + Preimages::::insert(key, available); + assert_eq!(Democracy::pre_image_data_len(key), Ok(l)); + assert!(Democracy::check_pre_image_is_missing(key).is_err()); + } + }) +} diff --git a/frame/democracy/src/tests/delegation.rs b/frame/democracy/src/tests/delegation.rs index 061a48b587798219f5562e8ca13fadd214c4cfe8..34dec6d0b49a6d6805d0e1f8bdf65b3114a90884 100644 --- a/frame/democracy/src/tests/delegation.rs +++ b/frame/democracy/src/tests/delegation.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The tests for functionality concerning delegation. diff --git a/frame/democracy/src/tests/external_proposing.rs b/frame/democracy/src/tests/external_proposing.rs index a249a806ee9edf4af87b6ecc81920783ac29c431..473eac81cdcb08c89bd3583706ccfb9bc0a145fd 100644 --- a/frame/democracy/src/tests/external_proposing.rs +++ b/frame/democracy/src/tests/external_proposing.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! The tests for functionality concerning the "external" origin. diff --git a/frame/democracy/src/tests/fast_tracking.rs b/frame/democracy/src/tests/fast_tracking.rs index 5ce9b15baf34cde31d2788679f3bdb106e1e8a84..8df34001cde043231587816bf253632a6f7123c0 100644 --- a/frame/democracy/src/tests/fast_tracking.rs +++ b/frame/democracy/src/tests/fast_tracking.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! The tests for fast-tracking functionality. diff --git a/frame/democracy/src/tests/lock_voting.rs b/frame/democracy/src/tests/lock_voting.rs index e83d974a8dc27fc990950ed1ae3895946b643e03..93867030588c31b3e146814bccbc4a428b4756eb 100644 --- a/frame/democracy/src/tests/lock_voting.rs +++ b/frame/democracy/src/tests/lock_voting.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The tests for functionality concerning locking and lock-voting. diff --git a/frame/democracy/src/tests/preimage.rs b/frame/democracy/src/tests/preimage.rs index 7d977b0ba83acd514e73fb77d18c485269451161..8a2cbaf53403280c585c944669c98ff367cf95ee 100644 --- a/frame/democracy/src/tests/preimage.rs +++ b/frame/democracy/src/tests/preimage.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The preimage tests. @@ -38,13 +39,14 @@ fn missing_preimage_should_fail() { #[test] fn preimage_deposit_should_be_required_and_returned() { - new_test_ext().execute_with(|| { + new_test_ext_execute_with_cond(|operational| { // fee of 100 is too much. PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 100); assert_noop!( - Democracy::note_preimage(Origin::signed(6), vec![0; 500]), - BalancesError::::InsufficientBalance, - ); + if operational { Democracy::note_preimage_operational(Origin::signed(6), vec![0; 500]) } + else { Democracy::note_preimage(Origin::signed(6), vec![0; 500]) }, + BalancesError::::InsufficientBalance, + ); // fee of 1 is reasonable. PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); let r = Democracy::inject_referendum( @@ -68,19 +70,22 @@ fn preimage_deposit_should_be_required_and_returned() { #[test] fn preimage_deposit_should_be_reapable_earlier_by_owner() { - new_test_ext().execute_with(|| { + new_test_ext_execute_with_cond(|operational| { PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); - assert_ok!(Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))); + assert_ok!( + if operational { Democracy::note_preimage_operational(Origin::signed(6), set_balance_proposal(2)) } + else { Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2)) } + ); assert_eq!(Balances::reserved_balance(6), 12); next_block(); assert_noop!( - Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2)), - Error::::TooEarly - ); + Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2), u32::max_value()), + Error::::TooEarly + ); next_block(); - assert_ok!(Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2))); + assert_ok!(Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2), u32::max_value())); assert_eq!(Balances::free_balance(6), 60); assert_eq!(Balances::reserved_balance(6), 0); @@ -89,26 +94,29 @@ fn preimage_deposit_should_be_reapable_earlier_by_owner() { #[test] fn preimage_deposit_should_be_reapable() { - new_test_ext().execute_with(|| { + new_test_ext_execute_with_cond(|operational| { assert_noop!( - Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2)), + Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2), u32::max_value()), Error::::PreimageMissing ); PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); - assert_ok!(Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))); + assert_ok!( + if operational { Democracy::note_preimage_operational(Origin::signed(6), set_balance_proposal(2)) } + else { Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2)) } + ); assert_eq!(Balances::reserved_balance(6), 12); next_block(); next_block(); next_block(); assert_noop!( - Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2)), + Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2), u32::max_value()), Error::::TooEarly ); next_block(); - assert_ok!(Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2))); + assert_ok!(Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2), u32::max_value())); assert_eq!(Balances::reserved_balance(6), 0); assert_eq!(Balances::free_balance(6), 48); assert_eq!(Balances::free_balance(5), 62); @@ -117,7 +125,7 @@ fn preimage_deposit_should_be_reapable() { #[test] fn noting_imminent_preimage_for_free_should_work() { - new_test_ext().execute_with(|| { + new_test_ext_execute_with_cond(|operational| { PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); let r = Democracy::inject_referendum( @@ -129,14 +137,15 @@ fn noting_imminent_preimage_for_free_should_work() { assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); assert_noop!( - Democracy::note_imminent_preimage(Origin::signed(7), set_balance_proposal(2)), - Error::::NotImminent - ); + if operational { Democracy::note_imminent_preimage_operational(Origin::signed(6), set_balance_proposal(2)) } + else { Democracy::note_imminent_preimage(Origin::signed(6), set_balance_proposal(2)) }, + Error::::NotImminent + ); next_block(); // Now we're in the dispatch queue it's all good. - assert_ok!(Democracy::note_imminent_preimage(Origin::signed(7), set_balance_proposal(2))); + assert_ok!(Democracy::note_imminent_preimage(Origin::signed(6), set_balance_proposal(2))); next_block(); @@ -152,6 +161,37 @@ fn reaping_imminent_preimage_should_fail() { assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); next_block(); next_block(); - assert_noop!(Democracy::reap_preimage(Origin::signed(6), h), Error::::Imminent); + assert_noop!(Democracy::reap_preimage(Origin::signed(6), h, u32::max_value()), Error::::Imminent); + }); +} + +#[test] +fn note_imminent_preimage_can_only_be_successful_once() { + new_test_ext().execute_with(|| { + PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1); + + let r = Democracy::inject_referendum( + 2, + set_balance_proposal_hash(2), + VoteThreshold::SuperMajorityApprove, + 1 + ); + assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1))); + next_block(); + + // First time works + assert_ok!(Democracy::note_imminent_preimage(Origin::signed(6), set_balance_proposal(2))); + + // Second time fails + assert_noop!( + Democracy::note_imminent_preimage(Origin::signed(6), set_balance_proposal(2)), + Error::::DuplicatePreimage + ); + + // Fails from any user + assert_noop!( + Democracy::note_imminent_preimage(Origin::signed(5), set_balance_proposal(2)), + Error::::DuplicatePreimage + ); }); } diff --git a/frame/democracy/src/tests/proxying.rs b/frame/democracy/src/tests/proxying.rs deleted file mode 100644 index 412adf6be03e707a22e9cd3bb03df3c8f2e6c6cd..0000000000000000000000000000000000000000 --- a/frame/democracy/src/tests/proxying.rs +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! The tests for functionality concerning proxying. - -use super::*; - -#[test] -fn proxy_should_work() { - new_test_ext().execute_with(|| { - assert_eq!(Democracy::proxy(10), None); - assert!(System::allow_death(&10)); - - assert_noop!(Democracy::activate_proxy(Origin::signed(1), 10), Error::::NotOpen); - - assert_ok!(Democracy::open_proxy(Origin::signed(10), 1)); - assert!(!System::allow_death(&10)); - assert_eq!(Democracy::proxy(10), Some(ProxyState::Open(1))); - - assert_noop!(Democracy::activate_proxy(Origin::signed(2), 10), Error::::WrongOpen); - assert_ok!(Democracy::activate_proxy(Origin::signed(1), 10)); - assert_eq!(Democracy::proxy(10), Some(ProxyState::Active(1))); - - // Can't set when already set. - assert_noop!(Democracy::activate_proxy(Origin::signed(2), 10), Error::::AlreadyProxy); - - // But this works because 11 isn't proxying. - assert_ok!(Democracy::open_proxy(Origin::signed(11), 2)); - assert_ok!(Democracy::activate_proxy(Origin::signed(2), 11)); - assert_eq!(Democracy::proxy(10), Some(ProxyState::Active(1))); - assert_eq!(Democracy::proxy(11), Some(ProxyState::Active(2))); - - // 2 cannot fire 1's proxy: - assert_noop!(Democracy::deactivate_proxy(Origin::signed(2), 10), Error::::WrongProxy); - - // 1 deactivates their proxy: - assert_ok!(Democracy::deactivate_proxy(Origin::signed(1), 10)); - assert_eq!(Democracy::proxy(10), Some(ProxyState::Open(1))); - // but the proxy account cannot be killed until the proxy is closed. - assert!(!System::allow_death(&10)); - - // and then 10 closes it completely: - assert_ok!(Democracy::close_proxy(Origin::signed(10))); - assert_eq!(Democracy::proxy(10), None); - assert!(System::allow_death(&10)); - - // 11 just closes without 2's "permission". - assert_ok!(Democracy::close_proxy(Origin::signed(11))); - assert_eq!(Democracy::proxy(11), None); - assert!(System::allow_death(&11)); - }); -} - -#[test] -fn voting_and_removing_votes_should_work_with_proxy() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_ok!(propose_set_balance_and_note(1, 2, 1)); - - fast_forward_to(2); - let r = 0; - assert_ok!(Democracy::open_proxy(Origin::signed(10), 1)); - assert_ok!(Democracy::activate_proxy(Origin::signed(1), 10)); - - assert_ok!(Democracy::proxy_vote(Origin::signed(10), r, aye(1))); - assert_eq!(tally(r), Tally { ayes: 1, nays: 0, turnout: 10 }); - - assert_ok!(Democracy::proxy_remove_vote(Origin::signed(10), r)); - assert_eq!(tally(r), Tally { ayes: 0, nays: 0, turnout: 0 }); - }); -} - -#[test] -fn delegation_and_undelegation_should_work_with_proxy() { - new_test_ext().execute_with(|| { - System::set_block_number(0); - assert_ok!(propose_set_balance_and_note(1, 2, 1)); - fast_forward_to(2); - let r = 0; - assert_ok!(Democracy::open_proxy(Origin::signed(10), 1)); - assert_ok!(Democracy::activate_proxy(Origin::signed(1), 10)); - assert_ok!(Democracy::vote(Origin::signed(2), r, aye(2))); - - assert_ok!(Democracy::proxy_delegate(Origin::signed(10), 2, Conviction::None, 10)); - assert_eq!(tally(r), Tally { ayes: 3, nays: 0, turnout: 30 }); - - assert_ok!(Democracy::proxy_undelegate(Origin::signed(10))); - assert_eq!(tally(r), Tally { ayes: 2, nays: 0, turnout: 20 }); - }); -} - diff --git a/frame/democracy/src/tests/public_proposals.rs b/frame/democracy/src/tests/public_proposals.rs index 04246e86f1da4fb530fb47a58bb9fbb07120bc43..68ec790baae8610591c8cf768e66644824f4c09a 100644 --- a/frame/democracy/src/tests/public_proposals.rs +++ b/frame/democracy/src/tests/public_proposals.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! The tests for the public proposal queue. @@ -34,10 +35,10 @@ fn backing_for_should_work() { fn deposit_for_proposals_should_be_taken() { new_test_ext().execute_with(|| { assert_ok!(propose_set_balance_and_note(1, 2, 5)); - assert_ok!(Democracy::second(Origin::signed(2), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); + assert_ok!(Democracy::second(Origin::signed(2), 0, u32::max_value())); + assert_ok!(Democracy::second(Origin::signed(5), 0, u32::max_value())); + assert_ok!(Democracy::second(Origin::signed(5), 0, u32::max_value())); + assert_ok!(Democracy::second(Origin::signed(5), 0, u32::max_value())); assert_eq!(Balances::free_balance(1), 5); assert_eq!(Balances::free_balance(2), 15); assert_eq!(Balances::free_balance(5), 35); @@ -48,10 +49,10 @@ fn deposit_for_proposals_should_be_taken() { fn deposit_for_proposals_should_be_returned() { new_test_ext().execute_with(|| { assert_ok!(propose_set_balance_and_note(1, 2, 5)); - assert_ok!(Democracy::second(Origin::signed(2), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); - assert_ok!(Democracy::second(Origin::signed(5), 0)); + assert_ok!(Democracy::second(Origin::signed(2), 0, u32::max_value())); + assert_ok!(Democracy::second(Origin::signed(5), 0, u32::max_value())); + assert_ok!(Democracy::second(Origin::signed(5), 0, u32::max_value())); + assert_ok!(Democracy::second(Origin::signed(5), 0, u32::max_value())); fast_forward_to(3); assert_eq!(Balances::free_balance(1), 10); assert_eq!(Balances::free_balance(2), 20); @@ -77,7 +78,21 @@ fn poor_proposer_should_not_work() { fn poor_seconder_should_not_work() { new_test_ext().execute_with(|| { assert_ok!(propose_set_balance_and_note(2, 2, 11)); - assert_noop!(Democracy::second(Origin::signed(1), 0), BalancesError::::InsufficientBalance); + assert_noop!( + Democracy::second(Origin::signed(1), 0, u32::max_value()), + BalancesError::::InsufficientBalance + ); + }); +} + +#[test] +fn invalid_seconds_upper_bound_should_not_work() { + new_test_ext().execute_with(|| { + assert_ok!(propose_set_balance_and_note(1, 2, 5)); + assert_noop!( + Democracy::second(Origin::signed(2), 0, 0), + Error::::WrongUpperBound + ); }); } diff --git a/frame/democracy/src/tests/scheduling.rs b/frame/democracy/src/tests/scheduling.rs index db9724deddc223d8895ce807f91ce65e9c020a8b..5bcfbae9946892596f21c9fc7b568e9db0bbb0d3 100644 --- a/frame/democracy/src/tests/scheduling.rs +++ b/frame/democracy/src/tests/scheduling.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The tests for functionality concerning normal starting, ending and enacting of referenda. diff --git a/frame/democracy/src/tests/voting.rs b/frame/democracy/src/tests/voting.rs index 43aed29a32d8bc8c0cc59ab0d84b7fcef44dd4aa..9ae57797d15dd703f545d5720e1ed78477fd8940 100644 --- a/frame/democracy/src/tests/voting.rs +++ b/frame/democracy/src/tests/voting.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The tests for normal voting functionality. diff --git a/frame/democracy/src/types.rs b/frame/democracy/src/types.rs index 3454326364de60412048467b8602df796110e3fd..8ee0838f8a36d14fb841b488f0055d452f1b6b18 100644 --- a/frame/democracy/src/types.rs +++ b/frame/democracy/src/types.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Miscellaneous additional datatypes. @@ -196,24 +197,6 @@ impl ReferendumInfo { - /// Account is open to becoming a proxy but is not yet assigned. - Open(AccountId), - /// Account is actively being a proxy. - Active(AccountId), -} - -impl ProxyState { - pub (crate) fn as_active(self) -> Option { - match self { - ProxyState::Active(a) => Some(a), - ProxyState::Open(_) => None, - } - } -} - /// Whether an `unvote` operation is able to make actions that are not strictly always in the /// interest of an account. pub enum UnvoteScope { diff --git a/frame/democracy/src/vote.rs b/frame/democracy/src/vote.rs index a41eb342aa12cb1ee862a0119a49f97620a0620d..09ff0d71e48ca9cf44142b4c8ab306aedaa4dc39 100644 --- a/frame/democracy/src/vote.rs +++ b/frame/democracy/src/vote.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The vote datatype. diff --git a/frame/democracy/src/vote_threshold.rs b/frame/democracy/src/vote_threshold.rs index fd976b44001cf189d497ec81c9fba789843e72d0..2268a55936c50aafa47fc5281e71d7dad5299607 100644 --- a/frame/democracy/src/vote_threshold.rs +++ b/frame/democracy/src/vote_threshold.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Voting thresholds. diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index f9d681b7608e66dd1b615c5524ca8ea8740e796e..cf76f085f01ce2f83b090e3a0ea5e63c9db6db7a 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -1,32 +1,32 @@ [package] name = "pallet-elections-phragmen" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -description = "FRAME election pallet for PHRAGMEN" +description = "FRAME pallet based on seq-Phragmén election method." [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-phragmen = { version = "2.0.0-dev", default-features = false, path = "../../primitives/phragmen" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-npos-elections = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/npos-elections" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } -hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-dev", path = "../balances" } -pallet-scheduler = { version = "2.0.0-dev", path = "../scheduler" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -substrate-test-utils = { version = "2.0.0-dev", path = "../../test-utils" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } +hex-literal = "0.3.1" +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +substrate-test-utils = { version = "2.0.0-rc6", path = "../../test-utils" } [features] default = ["std"] @@ -35,8 +35,12 @@ std = [ "codec/std", "frame-support/std", "sp-runtime/std", - "sp-phragmen/std", + "sp-npos-elections/std", "frame-system/std", "sp-std/std", ] -runtime-benchmarks = ["frame-support/runtime-benchmarks"] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] diff --git a/frame/elections-phragmen/README.md b/frame/elections-phragmen/README.md new file mode 100644 index 0000000000000000000000000000000000000000..651b8f6aa6941d598038929f3b9b433d7653a609 --- /dev/null +++ b/frame/elections-phragmen/README.md @@ -0,0 +1,67 @@ +# Phragmén Election Module. + +An election module based on sequential phragmen. + +### Term and Round + +The election happens in _rounds_: every `N` blocks, all previous members are retired and a new +set is elected (which may or may not have an intersection with the previous set). Each round +lasts for some number of blocks defined by `TermDuration` storage item. The words _term_ and +_round_ can be used interchangeably in this context. + +`TermDuration` might change during a round. This can shorten or extend the length of the round. +The next election round's block number is never stored but rather always checked on the fly. +Based on the current block number and `TermDuration`, the condition `BlockNumber % TermDuration +== 0` being satisfied will always trigger a new election round. + +### Voting + +Voters can vote for any set of the candidates by providing a list of account ids. Invalid votes +(voting for non-candidates) are ignored during election. Yet, a voter _might_ vote for a future +candidate. Voters reserve a bond as they vote. Each vote defines a `value`. This amount is +locked from the account of the voter and indicates the weight of the vote. Voters can update +their votes at any time by calling `vote()` again. This keeps the bond untouched but can +optionally change the locked `value`. After a round, votes are kept and might still be valid for +further rounds. A voter is responsible for calling `remove_voter` once they are done to have +their bond back and remove the lock. + +Voters also report other voters as being defunct to earn their bond. A voter is defunct once all +of the candidates that they have voted for are neither a valid candidate anymore nor a member. +Upon reporting, if the target voter is actually defunct, the reporter will be rewarded by the +voting bond of the target. The target will lose their bond and get removed. If the target is not +defunct, the reporter is slashed and removed. To prevent being reported, voters should manually +submit a `remove_voter()` as soon as they are in the defunct state. + +### Candidacy and Members + +Candidates also reserve a bond as they submit candidacy. A candidate cannot take their candidacy +back. A candidate can end up in one of the below situations: + - **Winner**: A winner is kept as a _member_. They must still have a bond in reserve and they + are automatically counted as a candidate for the next election. + - **Runner-up**: Runners-up are the best candidates immediately after the winners. The number + of runners_up to keep is configurable. Runners-up are used, in order that they are elected, + as replacements when a candidate is kicked by `[remove_member]`, or when an active member + renounces their candidacy. Runners are automatically counted as a candidate for the next + election. + - **Loser**: Any of the candidate who are not a winner are left as losers. A loser might be an + _outgoing member or runner_, meaning that they are an active member who failed to keep their + spot. An outgoing will always lose their bond. + +##### Renouncing candidacy. + +All candidates, elected or not, can renounce their candidacy. A call to [`Module::renounce_candidacy`] +will always cause the candidacy bond to be refunded. + +Note that with the members being the default candidates for the next round and votes persisting +in storage, the election system is entirely stable given no further input. This means that if +the system has a particular set of candidates `C` and voters `V` that lead to a set of members +`M` being elected, as long as `V` and `C` don't remove their candidacy and votes, `M` will keep +being re-elected at the end of each round. + +### Module Information + +- [`election_sp_phragmen::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) +- [`Module`](./struct.Module.html) + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/elections-phragmen/src/benchmarking.rs b/frame/elections-phragmen/src/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..6de9ad57e244fa080c41815436be290546885fb4 --- /dev/null +++ b/frame/elections-phragmen/src/benchmarking.rs @@ -0,0 +1,600 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Elections-Phragmen pallet benchmarking. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use frame_system::RawOrigin; +use frame_benchmarking::{benchmarks, account}; +use frame_support::traits::OnInitialize; + +use crate::Module as Elections; + +const BALANCE_FACTOR: u32 = 250; +const MAX_VOTERS: u32 = 500; +const MAX_CANDIDATES: u32 = 100; + +type Lookup = <::Lookup as StaticLookup>::Source; + +/// grab new account with infinite balance. +fn endowed_account(name: &'static str, index: u32) -> T::AccountId { + let account: T::AccountId = account(name, index, 0); + let amount = default_stake::(BALANCE_FACTOR); + let _ = T::Currency::make_free_balance_be(&account, amount); + // important to increase the total issuance since T::CurrencyToVote will need it to be sane for + // phragmen to work. + T::Currency::issue(amount); + account +} + +/// Account to lookup type of system trait. +fn as_lookup(account: T::AccountId) -> Lookup { + T::Lookup::unlookup(account) +} + +/// Get a reasonable amount of stake based on the execution trait's configuration +fn default_stake(factor: u32) -> BalanceOf { + let factor = BalanceOf::::from(factor); + T::Currency::minimum_balance() * factor +} + +/// Get the current number of candidates. +fn candidate_count() -> u32 { + >::decode_len().unwrap_or(0usize) as u32 +} + +/// Get the number of votes of a voter. +fn vote_count_of(who: &T::AccountId) -> u32 { + >::get(who).1.len() as u32 +} + +/// A `DefunctVoter` struct with correct value +fn defunct_for(who: T::AccountId) -> DefunctVoter> { + DefunctVoter { + who: as_lookup::(who.clone()), + candidate_count: candidate_count::(), + vote_count: vote_count_of::(&who), + } +} + +/// Add `c` new candidates. +fn submit_candidates(c: u32, prefix: &'static str) + -> Result, &'static str> +{ + (0..c).map(|i| { + let account = endowed_account::(prefix, i); + >::submit_candidacy( + RawOrigin::Signed(account.clone()).into(), + candidate_count::(), + ).map_err(|_| "failed to submit candidacy")?; + Ok(account) + }).collect::>() +} + +/// Add `c` new candidates with self vote. +fn submit_candidates_with_self_vote(c: u32, prefix: &'static str) + -> Result, &'static str> +{ + let candidates = submit_candidates::(c, prefix)?; + let stake = default_stake::(BALANCE_FACTOR); + let _ = candidates.iter().map(|c| + submit_voter::(c.clone(), vec![c.clone()], stake) + ).collect::>()?; + Ok(candidates) +} + + +/// Submit one voter. +fn submit_voter(caller: T::AccountId, votes: Vec, stake: BalanceOf) + -> Result<(), &'static str> +{ + >::vote(RawOrigin::Signed(caller).into(), votes, stake) + .map_err(|_| "failed to submit vote") +} + +/// create `num_voter` voters who randomly vote for at most `votes` of `all_candidates` if +/// available. +fn distribute_voters(mut all_candidates: Vec, num_voters: u32, votes: usize) + -> Result<(), &'static str> +{ + let stake = default_stake::(BALANCE_FACTOR); + for i in 0..num_voters { + // to ensure that votes are different + all_candidates.rotate_left(1); + let votes = all_candidates + .iter() + .cloned() + .take(votes) + .collect::>(); + let voter = endowed_account::("voter", i); + submit_voter::(voter, votes, stake)?; + } + Ok(()) +} + +/// Fill the seats of members and runners-up up until `m`. Note that this might include either only +/// members, or members and runners-up. +fn fill_seats_up_to(m: u32) -> Result, &'static str> { + let candidates = submit_candidates_with_self_vote::(m, "fill_seats_up_to")?; + assert_eq!(>::candidates().len() as u32, m, "wrong number of candidates."); + >::do_phragmen(); + assert_eq!(>::candidates().len(), 0, "some candidates remaining."); + assert_eq!( + >::members().len() + >::runners_up().len(), + m as usize, + "wrong number of members and runners-up", + ); + Ok(candidates) +} + +/// removes all the storage items to reverse any genesis state. +fn clean() { + >::kill(); + >::kill(); + >::kill(); + let _ = >::drain(); +} + +benchmarks! { + _ { + // User account seed + let u in 0 .. 1000 => (); + } + + // -- Signed ones + vote { + let u in ...; + // we fix the number of voted candidates to max + let v = MAXIMUM_VOTE; + clean::(); + + // create a bunch of candidates. + let all_candidates = submit_candidates::(MAXIMUM_VOTE as u32, "candidates")?; + + let caller = endowed_account::("caller", u); + let stake = default_stake::(BALANCE_FACTOR); + + // vote for all of them. + let votes = all_candidates.into_iter().take(v).collect(); + + }: _(RawOrigin::Signed(caller), votes, stake) + + vote_update { + let u in ...; + // we fix the number of voted candidates to max + let v = MAXIMUM_VOTE; + clean::(); + + // create a bunch of candidates. + let all_candidates = submit_candidates::(MAXIMUM_VOTE as u32, "candidates")?; + + let caller = endowed_account::("caller", u); + let stake = default_stake::(BALANCE_FACTOR); + + // original votes. + let mut votes = all_candidates.into_iter().take(v).collect::>(); + submit_voter::(caller.clone(), votes.clone(), stake)?; + // new votes. + votes.rotate_left(1); + }: vote(RawOrigin::Signed(caller), votes, stake) + + remove_voter { + let u in ...; + // we fix the number of voted candidates to max + let v = MAXIMUM_VOTE as u32; + clean::(); + + // create a bunch of candidates. + let all_candidates = submit_candidates::(v, "candidates")?; + + let caller = endowed_account::("caller", u); + + let stake = default_stake::(BALANCE_FACTOR); + submit_voter::(caller.clone(), all_candidates, stake)?; + + }: _(RawOrigin::Signed(caller)) + + report_defunct_voter_correct { + // number of already existing candidates that may or may not be voted by the reported + // account. + let c in 1 .. MAX_CANDIDATES; + // number of candidates that the reported voter voted for. The worse case of search here is + // basically `c * v`. + let v in 1 .. (MAXIMUM_VOTE as u32); + // we fix the number of members to when members and runners-up to the desired. We'll be in + // this state almost always. + let m = T::DesiredMembers::get() + T::DesiredRunnersUp::get(); + clean::(); + + let stake = default_stake::(BALANCE_FACTOR); + + // create m members and runners combined. + let _ = fill_seats_up_to::(m)?; + + // create a bunch of candidates as well. + let bailing_candidates = submit_candidates::(v, "bailing_candidates")?; + let all_candidates = submit_candidates::(c, "all_candidates")?; + + // account 1 is the reporter and it doesn't matter how many it votes. But it has to be a + // voter. + let account_1 = endowed_account::("caller", 0); + submit_voter::( + account_1.clone(), + all_candidates.iter().take(1).cloned().collect(), + stake, + )?; + + // account 2 votes for all of the mentioned candidates. + let account_2 = endowed_account::("caller_2", 1); + submit_voter::( + account_2.clone(), + bailing_candidates.clone(), + stake, + )?; + + // all the bailers go away. + bailing_candidates.into_iter().for_each(|b| { + let count = candidate_count::(); + assert!(>::renounce_candidacy( + RawOrigin::Signed(b).into(), + Renouncing::Candidate(count), + ).is_ok()); + }); + let defunct = defunct_for::(account_2.clone()); + }: report_defunct_voter(RawOrigin::Signed(account_1.clone()), defunct) + verify { + assert!(>::is_voter(&account_1)); + assert!(!>::is_voter(&account_2)); + #[cfg(test)] + { + // reset members in between benchmark tests. + use crate::tests::MEMBERS; + MEMBERS.with(|m| *m.borrow_mut() = vec![]); + } + } + + report_defunct_voter_incorrect { + // number of already existing candidates that may or may not be voted by the reported + // account. + let c in 1 .. MAX_CANDIDATES; + // number of candidates that the reported voter voted for. The worse case of search here is + // basically `c * v`. + let v in 1 .. (MAXIMUM_VOTE as u32); + // we fix the number of members to when members and runners-up to the desired. We'll be in + // this state almost always. + let m = T::DesiredMembers::get() + T::DesiredRunnersUp::get(); + + clean::(); + let stake = default_stake::(BALANCE_FACTOR); + + // create m members and runners combined. + let _ = fill_seats_up_to::(m)?; + + // create a bunch of candidates as well. + let all_candidates = submit_candidates::(c, "candidates")?; + + // account 1 is the reporter and it doesn't matter how many it votes. + let account_1 = endowed_account::("caller", 0); + submit_voter::( + account_1.clone(), + all_candidates.iter().take(1).cloned().collect(), + stake, + )?; + + // account 2 votes for a bunch of crap, and finally a correct candidate. + let account_2 = endowed_account::("caller_2", 1); + let mut invalid: Vec = + (0..(v-1)).map(|seed| account::("invalid", 0, seed).clone()).collect(); + invalid.push(all_candidates.last().unwrap().clone()); + submit_voter::( + account_2.clone(), + invalid, + stake, + )?; + + let defunct = defunct_for::(account_2.clone()); + // no one bails out. account_1 is slashed and removed as voter now. + }: report_defunct_voter(RawOrigin::Signed(account_1.clone()), defunct) + verify { + assert!(!>::is_voter(&account_1)); + assert!(>::is_voter(&account_2)); + #[cfg(test)] + { + // reset members in between benchmark tests. + use crate::tests::MEMBERS; + MEMBERS.with(|m| *m.borrow_mut() = vec![]); + } + } + + submit_candidacy { + // number of already existing candidates. + let c in 1 .. MAX_CANDIDATES; + // we fix the number of members to when members and runners-up to the desired. We'll be in + // this state almost always. + let m = T::DesiredMembers::get() + T::DesiredRunnersUp::get(); + + clean::(); + let stake = default_stake::(BALANCE_FACTOR); + + // create m members and runners combined. + let _ = fill_seats_up_to::(m)?; + + // create previous candidates; + let _ = submit_candidates::(c, "candidates")?; + + // we assume worse case that: extrinsic is successful and candidate is not duplicate. + let candidate_account = endowed_account::("caller", 0); + }: _(RawOrigin::Signed(candidate_account.clone()), candidate_count::()) + verify { + #[cfg(test)] + { + // reset members in between benchmark tests. + use crate::tests::MEMBERS; + MEMBERS.with(|m| *m.borrow_mut() = vec![]); + } + } + + renounce_candidacy_candidate { + // this will check members, runners-up and candidate for removal. Members and runners-up are + // limited by the runtime bound, nonetheless we fill them by `m`. + // number of already existing candidates. + let c in 1 .. MAX_CANDIDATES; + // we fix the number of members to when members and runners-up to the desired. We'll be in + // this state almost always. + let m = T::DesiredMembers::get() + T::DesiredRunnersUp::get(); + + clean::(); + + // create m members and runners combined. + let _ = fill_seats_up_to::(m)?; + let all_candidates = submit_candidates::(c, "caller")?; + + let bailing = all_candidates[0].clone(); // Should be ("caller", 0) + let count = candidate_count::(); + }: renounce_candidacy(RawOrigin::Signed(bailing), Renouncing::Candidate(count)) + verify { + #[cfg(test)] + { + // reset members in between benchmark tests. + use crate::tests::MEMBERS; + MEMBERS.with(|m| *m.borrow_mut() = vec![]); + } + } + + renounce_candidacy_member_runner_up { + // removing members and runners will be cheaper than a candidate. + // we fix the number of members to when members and runners-up to the desired. We'll be in + // this state almost always. + let u in ...; + let m = T::DesiredMembers::get() + T::DesiredRunnersUp::get(); + clean::(); + + // create m members and runners combined. + let members_and_runners_up = fill_seats_up_to::(m)?; + + let bailing = members_and_runners_up[0].clone(); + let renouncing = if >::is_member(&bailing) { + Renouncing::Member + } else if >::is_runner_up(&bailing) { + Renouncing::RunnerUp + } else { + panic!("Bailing must be a member or runner-up for this bench to be sane."); + }; + }: renounce_candidacy(RawOrigin::Signed(bailing.clone()), renouncing) + verify { + #[cfg(test)] + { + // reset members in between benchmark tests. + use crate::tests::MEMBERS; + MEMBERS.with(|m| *m.borrow_mut() = vec![]); + } + } + + // -- Root ones + remove_member_without_replacement { + // worse case is when we remove a member and we have no runner as a replacement. This + // triggers phragmen again. The only parameter is how many candidates will compete for the + // new slot. + let c in 1 .. MAX_CANDIDATES; + clean::(); + + // fill only desired members. no runners-up. + let all_members = fill_seats_up_to::(T::DesiredMembers::get())?; + assert_eq!(>::members().len() as u32, T::DesiredMembers::get()); + + // submit a new one to compensate, with self-vote. + let replacements = submit_candidates_with_self_vote::(c, "new_candidate")?; + + // create some voters for these replacements. + distribute_voters::(replacements, MAX_VOTERS, MAXIMUM_VOTE)?; + + let to_remove = as_lookup::(all_members[0].clone()); + }: remove_member(RawOrigin::Root, to_remove, false) + verify { + // must still have the desired number of members members. + assert_eq!(>::members().len() as u32, T::DesiredMembers::get()); + #[cfg(test)] + { + // reset members in between benchmark tests. + use crate::tests::MEMBERS; + MEMBERS.with(|m| *m.borrow_mut() = vec![]); + } + } + + remove_member_with_replacement { + // easy case. We have a runner up. Nothing will have that much of an impact. m will be + // number of members and runners. There is always at least one runner. + let u in ...; + let m = T::DesiredMembers::get() + T::DesiredRunnersUp::get(); + clean::(); + + let _ = fill_seats_up_to::(m)?; + let removing = as_lookup::(>::members_ids()[0].clone()); + }: remove_member(RawOrigin::Root, removing, true) + verify { + // must still have enough members. + assert_eq!(>::members().len() as u32, T::DesiredMembers::get()); + #[cfg(test)] + { + // reset members in between benchmark tests. + use crate::tests::MEMBERS; + MEMBERS.with(|m| *m.borrow_mut() = vec![]); + } + } + + remove_member_wrong_refund { + // The root call by mistake indicated that this will have no replacement, while it has! + // this has now consumed a lot of weight and need to refund. + let u in ...; + let m = T::DesiredMembers::get() + T::DesiredRunnersUp::get(); + clean::(); + + let _ = fill_seats_up_to::(m)?; + let removing = as_lookup::(>::members_ids()[0].clone()); + }: { + assert_eq!( + >::remove_member(RawOrigin::Root.into(), removing, false).unwrap_err().error, + Error::::InvalidReplacement.into(), + ); + } + verify { + // must still have enough members. + assert_eq!(>::members().len() as u32, T::DesiredMembers::get()); + #[cfg(test)] + { + // reset members in between benchmark tests. + use crate::tests::MEMBERS; + MEMBERS.with(|m| *m.borrow_mut() = vec![]); + } + } + + on_initialize { + // if n % TermDuration is zero, then we run phragmen. The weight function must and should + // check this as it is cheap to do so. TermDuration is not a storage item, it is a constant + // encoded in the runtime. + let c in 1 .. MAX_CANDIDATES; + clean::(); + + // create c candidates. + let all_candidates = submit_candidates_with_self_vote::(c, "candidates")?; + // create 500 voters, each voting the maximum 16 + distribute_voters::(all_candidates, MAX_VOTERS, MAXIMUM_VOTE)?; + }: { + // elect + >::on_initialize(T::TermDuration::get()); + } + verify { + assert_eq!(>::members().len() as u32, T::DesiredMembers::get().min(c)); + assert_eq!( + >::runners_up().len() as u32, + T::DesiredRunnersUp::get().min(c.saturating_sub(T::DesiredMembers::get())), + ); + + #[cfg(test)] + { + // reset members in between benchmark tests. + use crate::tests::MEMBERS; + MEMBERS.with(|m| *m.borrow_mut() = vec![]); + } + } + + phragmen { + // This is just to focus on phragmen in the context of this module. We always select 20 + // members, this is hard-coded in the runtime and cannot be trivially changed at this stage. + // Yet, change the number of voters, candidates and edge per voter to see the impact. Note + // that we give all candidates a self vote to make sure they are all considered. + let c in 1 .. MAX_CANDIDATES; + let v in 1 .. MAX_VOTERS; + let e in 1 .. (MAXIMUM_VOTE as u32); + clean::(); + + let all_candidates = submit_candidates_with_self_vote::(c, "candidates")?; + let _ = distribute_voters::(all_candidates, v, e as usize)?; + }: { + >::on_initialize(T::TermDuration::get()); + } + verify { + assert_eq!(>::members().len() as u32, T::DesiredMembers::get().min(c)); + assert_eq!( + >::runners_up().len() as u32, + T::DesiredRunnersUp::get().min(c.saturating_sub(T::DesiredMembers::get())), + ); + + #[cfg(test)] + { + // reset members in between benchmark tests. + use crate::tests::MEMBERS; + MEMBERS.with(|m| *m.borrow_mut() = vec![]); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{ExtBuilder, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks_elections_phragmen() { + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_vote::()); + }); + + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_remove_voter::()); + }); + + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_report_defunct_voter_correct::()); + }); + + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_report_defunct_voter_incorrect::()); + }); + + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_submit_candidacy::()); + }); + + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_renounce_candidacy_candidate::()); + }); + + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_renounce_candidacy_member_runner_up::()); + }); + + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_remove_member_without_replacement::()); + }); + + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_remove_member_with_replacement::()); + }); + + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_on_initialize::()); + }); + + ExtBuilder::default().desired_members(13).desired_runners_up(7).build_and_execute(|| { + assert_ok!(test_benchmark_phragmen::()); + }); + } +} diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 05f4d1e83de59014924354d808833aa050f28cd2..50c5de9bc0de46e4599f55eeebee846b0b970b4b 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -1,20 +1,21 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! # Phragmen Election Module. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! # Phragmén Election Module. //! //! An election module based on sequential phragmen. //! @@ -82,30 +83,92 @@ #![cfg_attr(not(feature = "std"), no_std)] +use codec::{Encode, Decode}; use sp_std::prelude::*; use sp_runtime::{ - print, DispatchResult, DispatchError, Perbill, traits::{Zero, StaticLookup, Convert}, + DispatchError, RuntimeDebug, Perbill, + traits::{Zero, StaticLookup, Convert}, }; use frame_support::{ decl_storage, decl_event, ensure, decl_module, decl_error, - weights::{Weight, DispatchClass}, + weights::{Weight, constants::{WEIGHT_PER_MICROS, WEIGHT_PER_NANOS}}, storage::{StorageMap, IterableStorageMap}, + dispatch::{DispatchResultWithPostInfo, WithPostDispatchInfo}, traits::{ Currency, Get, LockableCurrency, LockIdentifier, ReservableCurrency, WithdrawReasons, ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus, InitializeMembers, ContainsLengthBound, } }; -use sp_phragmen::{build_support_map, ExtendedBalance, VoteWeight, PhragmenResult}; -use frame_system::{self as system, ensure_signed, ensure_root}; +use sp_npos_elections::{build_support_map, ExtendedBalance, VoteWeight, ElectionResult}; +use frame_system::{ensure_signed, ensure_root}; + +mod benchmarking; /// The maximum votes allowed per voter. pub const MAXIMUM_VOTE: usize = 16; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +type BalanceOf = + <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +/// An indication that the renouncing account currently has which of the below roles. +#[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug)] +pub enum Renouncing { + /// A member is renouncing. + Member, + /// A runner-up is renouncing. + RunnerUp, + /// A candidate is renouncing, while the given total number of candidates exists. + Candidate(#[codec(compact)] u32), +} + +/// Information needed to prove the defunct-ness of a voter. +#[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug)] +pub struct DefunctVoter { + /// the voter's who's being challenged for being defunct + pub who: AccountId, + /// The number of votes that `who` has placed. + #[codec(compact)] + pub vote_count: u32, + /// The number of current active candidates. + #[codec(compact)] + pub candidate_count: u32 +} + +pub trait WeightInfo { + fn vote(u: u32, ) -> Weight; + fn vote_update(u: u32, ) -> Weight; + fn remove_voter(u: u32, ) -> Weight; + fn report_defunct_voter_correct(c: u32, v: u32, ) -> Weight; + fn report_defunct_voter_incorrect(c: u32, v: u32, ) -> Weight; + fn submit_candidacy(c: u32, ) -> Weight; + fn renounce_candidacy_candidate(c: u32, ) -> Weight; + fn renounce_candidacy_member_runner_up(u: u32, ) -> Weight; + fn remove_member_without_replacement(c: u32, ) -> Weight; + fn remove_member_with_replacement(u: u32, ) -> Weight; + fn remove_member_wrong_refund(u: u32, ) -> Weight; + fn on_initialize(c: u32, ) -> Weight; + fn phragmen(c: u32, v: u32, e: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn vote(_u: u32, ) -> Weight { 1_000_000_000 } + fn vote_update(_u: u32, ) -> Weight { 1_000_000_000 } + fn remove_voter(_u: u32, ) -> Weight { 1_000_000_000 } + fn report_defunct_voter_correct(_c: u32, _v: u32, ) -> Weight { 1_000_000_000 } + fn report_defunct_voter_incorrect(_c: u32, _v: u32, ) -> Weight { 1_000_000_000 } + fn submit_candidacy(_c: u32, ) -> Weight { 1_000_000_000 } + fn renounce_candidacy_candidate(_c: u32, ) -> Weight { 1_000_000_000 } + fn renounce_candidacy_member_runner_up(_u: u32, ) -> Weight { 1_000_000_000 } + fn remove_member_without_replacement(_c: u32, ) -> Weight { 1_000_000_000 } + fn remove_member_with_replacement(_u: u32, ) -> Weight { 1_000_000_000 } + fn remove_member_wrong_refund(_u: u32, ) -> Weight { 1_000_000_000 } + fn on_initialize(_c: u32, ) -> Weight { 1_000_000_000 } + fn phragmen(_c: u32, _v: u32, _e: u32, ) -> Weight { 1_000_000_000 } +} + pub trait Trait: frame_system::Trait { /// The overarching event type.c type Event: From> + Into<::Event>; @@ -153,6 +216,9 @@ pub trait Trait: frame_system::Trait { /// round will happen. If set to zero, no elections are ever triggered and the module will /// be in passive mode. type TermDuration: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_storage! { @@ -166,6 +232,8 @@ decl_storage! { pub ElectionRounds get(fn election_rounds): u32 = Zero::zero(); /// Votes and locked stake of a particular voter. + /// + /// TWOX-NOTE: SAFE as `AccountId` is a crypto hash pub Voting get(fn voting): map hasher(twox_64_concat) T::AccountId => (BalanceOf, Vec); /// The present candidate list. Sorted based on account-id. A current member or runner-up @@ -212,7 +280,6 @@ decl_storage! { } decl_error! { - /// Error for the elections-phragmen module. pub enum Error for Module { /// Cannot vote when no candidates or members exist. UnableToVote, @@ -238,10 +305,16 @@ decl_error! { RunnerSubmit, /// Candidate does not have enough funds. InsufficientCandidateFunds, - /// Origin is not a candidate, member or a runner up. - InvalidOrigin, /// Not a member. NotMember, + /// The provided count of number of candidates is incorrect. + InvalidCandidateCount, + /// The provided count of number of votes is incorrect. + InvalidVoteCount, + /// The renouncing origin presented a wrong `Renouncing` parameter. + InvalidRenouncing, + /// Prediction regarding replacement after member removal is wrong. + InvalidReplacement, } } @@ -258,46 +331,60 @@ decl_module! { const TermDuration: T::BlockNumber = T::TermDuration::get(); const ModuleId: LockIdentifier = T::ModuleId::get(); - /// Vote for a set of candidates for the upcoming round of election. + /// Vote for a set of candidates for the upcoming round of election. This can be called to + /// set the initial votes, or update already existing votes. + /// + /// Upon initial voting, `value` units of `who`'s balance is locked and a bond amount is + /// reserved. /// /// The `votes` should: /// - not be empty. - /// - be less than the number of candidates. + /// - be less than the number of possible candidates. Note that all current members and + /// runners-up are also automatically candidates for the next round. /// - /// Upon voting, `value` units of `who`'s balance is locked and a bond amount is reserved. /// It is the responsibility of the caller to not place all of their balance into the lock /// and keep some for further transactions. /// /// # - /// #### State - /// Reads: O(1) - /// Writes: O(V) given `V` votes. V is bounded by 16. + /// Base weight: 47.93 µs + /// State reads: + /// - Candidates.len() + Members.len() + RunnersUp.len() + /// - Voting (is_voter) + /// - [AccountBalance(who) (unreserve + total_balance)] + /// State writes: + /// - Voting + /// - Lock + /// - [AccountBalance(who) (unreserve -- only when creating a new voter)] /// # - #[weight = 100_000_000] - fn vote(origin, votes: Vec, #[compact] value: BalanceOf) { + #[weight = 50 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(4, 2)] + fn vote( + origin, + votes: Vec, + #[compact] value: BalanceOf, + ) { let who = ensure_signed(origin)?; + ensure!(votes.len() <= MAXIMUM_VOTE, Error::::MaximumVotesExceeded); + ensure!(!votes.is_empty(), Error::::NoVotes); + let candidates_count = >::decode_len().unwrap_or(0); let members_count = >::decode_len().unwrap_or(0); let runners_up_count = >::decode_len().unwrap_or(0); + // addition is valid: candidates, members and runners-up will never overlap. let allowed_votes = candidates_count + members_count + runners_up_count; ensure!(!allowed_votes.is_zero(), Error::::UnableToVote); ensure!(votes.len() <= allowed_votes, Error::::TooManyVotes); - ensure!(votes.len() <= MAXIMUM_VOTE, Error::::MaximumVotesExceeded); - ensure!(!votes.is_empty(), Error::::NoVotes); - ensure!( - value > T::Currency::minimum_balance(), - Error::::LowBalance, - ); + ensure!(value > T::Currency::minimum_balance(), Error::::LowBalance); + // first time voter. Reserve bond. if !Self::is_voter(&who) { - // first time voter. Reserve bond. T::Currency::reserve(&who, T::VotingBond::get()) .map_err(|_| Error::::UnableToPayBond)?; } + // Amount to be locked up. let locked_balance = value.min(T::Currency::total_balance(&who)); @@ -315,14 +402,19 @@ decl_module! { /// Remove `origin` as a voter. This removes the lock and returns the bond. /// /// # - /// #### State - /// Reads: O(1) - /// Writes: O(1) + /// Base weight: 36.8 µs + /// All state access is from do_remove_voter. + /// State reads: + /// - Voting + /// - [AccountData(who)] + /// State writes: + /// - Voting + /// - Locks + /// - [AccountData(who)] /// # - #[weight = 0] + #[weight = 35 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(1, 2)] fn remove_voter(origin) { let who = ensure_signed(origin)?; - ensure!(Self::is_voter(&who), Error::::MustBeVoter); Self::do_remove_voter(&who, true); @@ -334,27 +426,62 @@ decl_module! { /// /// A defunct voter is defined to be: /// - a voter whose current submitted votes are all invalid. i.e. all of them are no - /// longer a candidate nor an active member. + /// longer a candidate nor an active member or a runner-up. + /// + /// + /// The origin must provide the number of current candidates and votes of the reported target + /// for the purpose of accurate weight calculation. /// /// # - /// #### State - /// Reads: O(NLogM) given M current candidates and N votes for `target`. - /// Writes: O(1) + /// No Base weight based on min square analysis. + /// Complexity of candidate_count: 1.755 µs + /// Complexity of vote_count: 18.51 µs + /// State reads: + /// - Voting(reporter) + /// - Candidate.len() + /// - Voting(Target) + /// - Candidates, Members, RunnersUp (is_defunct_voter) + /// State writes: + /// - Lock(reporter || target) + /// - [AccountBalance(reporter)] + AccountBalance(target) + /// - Voting(reporter || target) + /// Note: the db access is worse with respect to db, which is when the report is correct. /// # - #[weight = 1_000_000_000] - fn report_defunct_voter(origin, target: ::Source) { + #[weight = + Weight::from(defunct.candidate_count).saturating_mul(2 * WEIGHT_PER_MICROS) + .saturating_add(Weight::from(defunct.vote_count).saturating_mul(19 * WEIGHT_PER_MICROS)) + .saturating_add(T::DbWeight::get().reads_writes(6, 3)) + ] + fn report_defunct_voter( + origin, + defunct: DefunctVoter<::Source>, + ) { let reporter = ensure_signed(origin)?; - let target = T::Lookup::lookup(target)?; + let target = T::Lookup::lookup(defunct.who)?; ensure!(reporter != target, Error::::ReportSelf); ensure!(Self::is_voter(&reporter), Error::::MustBeVoter); - // Checking if someone is a candidate and a member here is O(LogN), making the whole - // function O(MLonN) with N candidates in total and M of them being voted by `target`. - // We could easily add another mapping to be able to check if someone is a candidate in - // `O(1)` but that would make the process of removing candidates at the end of each - // round slightly harder. Note that for now we have a bound of number of votes (`N`). - let valid = Self::is_defunct_voter(&target); + let DefunctVoter { candidate_count, vote_count, .. } = defunct; + + ensure!( + >::decode_len().unwrap_or(0) as u32 <= candidate_count, + Error::::InvalidCandidateCount, + ); + + let (_, votes) = >::get(&target); + // indirect way to ensure target is a voter. We could call into `::contains()`, but it + // would have the same effect with one extra db access. Note that votes cannot be + // submitted with length 0. Hence, a non-zero length means that the target is a voter. + ensure!(votes.len() > 0, Error::::MustBeVoter); + + // ensure that the size of votes that need to be searched is correct. + ensure!( + votes.len() as u32 <= vote_count, + Error::::InvalidVoteCount, + ); + + let valid = Self::is_defunct_voter(&votes); if valid { // reporter will get the voting bond of the target T::Currency::repatriate_reserved(&target, &reporter, T::VotingBond::get(), BalanceStatus::Free)?; @@ -370,7 +497,6 @@ decl_module! { Self::deposit_event(RawEvent::VoterReported(target, reporter, valid)); } - /// Submit oneself for candidacy. /// /// A candidate will either: @@ -380,21 +506,40 @@ decl_module! { /// removed. /// /// # - /// #### State - /// Reads: O(LogN) Given N candidates. - /// Writes: O(1) + /// Base weight = 33.33 µs + /// Complexity of candidate_count: 0.375 µs + /// State reads: + /// - Candidates.len() + /// - Candidates + /// - Members + /// - RunnersUp + /// - [AccountBalance(who)] + /// State writes: + /// - [AccountBalance(who)] + /// - Candidates /// # - #[weight = 500_000_000] - fn submit_candidacy(origin) { + #[weight = + (35 * WEIGHT_PER_MICROS) + .saturating_add(Weight::from(*candidate_count).saturating_mul(375 * WEIGHT_PER_NANOS)) + .saturating_add(T::DbWeight::get().reads_writes(4, 1)) + ] + fn submit_candidacy(origin, #[compact] candidate_count: u32) { let who = ensure_signed(origin)?; + let actual_count = >::decode_len().unwrap_or(0); + ensure!( + actual_count as u32 <= candidate_count, + Error::::InvalidCandidateCount, + ); + let is_candidate = Self::is_candidate(&who); ensure!(is_candidate.is_err(), Error::::DuplicatedCandidate); + // assured to be an error, error always contains the index. let index = is_candidate.unwrap_err(); ensure!(!Self::is_member(&who), Error::::MemberSubmit); - ensure!(!Self::is_runner(&who), Error::::RunnerSubmit); + ensure!(!Self::is_runner_up(&who), Error::::RunnerSubmit); T::Currency::reserve(&who, T::CandidacyBond::get()) .map_err(|_| Error::::InsufficientCandidateFunds)?; @@ -406,94 +551,155 @@ decl_module! { /// outcomes exist: /// - `origin` is a candidate and not elected in any set. In this case, the bond is /// unreserved, returned and origin is removed as a candidate. - /// - `origin` is a current runner up. In this case, the bond is unreserved, returned and - /// origin is removed as a runner. + /// - `origin` is a current runner-up. In this case, the bond is unreserved, returned and + /// origin is removed as a runner-up. /// - `origin` is a current member. In this case, the bond is unreserved and origin is /// removed as a member, consequently not being a candidate for the next round anymore. /// Similar to [`remove_voter`], if replacement runners exists, they are immediately used. - #[weight = (2_000_000_000, DispatchClass::Operational)] - fn renounce_candidacy(origin) { - let who = ensure_signed(origin)?; - - // NOTE: this function attempts the 3 conditions (being a candidate, member, runner) and - // fails if none are matched. Unlike other Palette functions and modules where checks - // happen first and then execution happens, this function is written the other way - // around. The main intention is that reading all of the candidates, members and runners - // from storage is expensive. Furthermore, we know (soft proof) that they are always - // mutually exclusive. Hence, we try one, and only then decode more storage. - - if let Ok(_replacement) = Self::remove_and_replace_member(&who) { - T::Currency::unreserve(&who, T::CandidacyBond::get()); - Self::deposit_event(RawEvent::MemberRenounced(who.clone())); - - // safety guard to make sure we do only one arm. Better to read runners later. - return Ok(()); - } - - let mut runners_up_with_stake = Self::runners_up(); - if let Some(index) = runners_up_with_stake.iter() - .position(|(ref r, ref _s)| r == &who) - { - runners_up_with_stake.remove(index); - // unreserve the bond - T::Currency::unreserve(&who, T::CandidacyBond::get()); - // update storage. - >::put(runners_up_with_stake); - // safety guard to make sure we do only one arm. Better to read runners later. - return Ok(()); - } - - let mut candidates = Self::candidates(); - if let Ok(index) = candidates.binary_search(&who) { - candidates.remove(index); - // unreserve the bond - T::Currency::unreserve(&who, T::CandidacyBond::get()); - // update storage. - >::put(candidates); - // safety guard to make sure we do only one arm. Better to read runners later. - return Ok(()); + /// + /// If a candidate is renouncing: + /// Base weight: 17.28 µs + /// Complexity of candidate_count: 0.235 µs + /// State reads: + /// - Candidates + /// - [AccountBalance(who) (unreserve)] + /// State writes: + /// - Candidates + /// - [AccountBalance(who) (unreserve)] + /// If member is renouncing: + /// Base weight: 46.25 µs + /// State reads: + /// - Members, RunnersUp (remove_and_replace_member), + /// - [AccountData(who) (unreserve)] + /// State writes: + /// - Members, RunnersUp (remove_and_replace_member), + /// - [AccountData(who) (unreserve)] + /// If runner is renouncing: + /// Base weight: 46.25 µs + /// State reads: + /// - RunnersUp (remove_and_replace_member), + /// - [AccountData(who) (unreserve)] + /// State writes: + /// - RunnersUp (remove_and_replace_member), + /// - [AccountData(who) (unreserve)] + /// + /// Weight note: The call into changeMembers need to be accounted for. + /// + #[weight = match *renouncing { + Renouncing::Candidate(count) => { + (18 * WEIGHT_PER_MICROS) + .saturating_add(Weight::from(count).saturating_mul(235 * WEIGHT_PER_NANOS)) + .saturating_add(T::DbWeight::get().reads_writes(1, 1)) + }, + Renouncing::Member => { + 46 * WEIGHT_PER_MICROS + + T::DbWeight::get().reads_writes(2, 2) + }, + Renouncing::RunnerUp => { + 46 * WEIGHT_PER_MICROS + + T::DbWeight::get().reads_writes(1, 1) } - - Err(Error::::InvalidOrigin)? + }] + fn renounce_candidacy(origin, renouncing: Renouncing) { + let who = ensure_signed(origin)?; + match renouncing { + Renouncing::Member => { + // returns NoMember error in case of error. + let _ = Self::remove_and_replace_member(&who)?; + T::Currency::unreserve(&who, T::CandidacyBond::get()); + Self::deposit_event(RawEvent::MemberRenounced(who)); + }, + Renouncing::RunnerUp => { + let mut runners_up_with_stake = Self::runners_up(); + if let Some(index) = runners_up_with_stake + .iter() + .position(|(ref r, ref _s)| r == &who) + { + runners_up_with_stake.remove(index); + // unreserve the bond + T::Currency::unreserve(&who, T::CandidacyBond::get()); + // update storage. + >::put(runners_up_with_stake); + } else { + Err(Error::::InvalidRenouncing)?; + } + } + Renouncing::Candidate(count) => { + let mut candidates = Self::candidates(); + ensure!(count >= candidates.len() as u32, Error::::InvalidRenouncing); + if let Some(index) = candidates.iter().position(|x| *x == who) { + candidates.remove(index); + // unreserve the bond + T::Currency::unreserve(&who, T::CandidacyBond::get()); + // update storage. + >::put(candidates); + } else { + Err(Error::::InvalidRenouncing)?; + } + } + }; } /// Remove a particular member from the set. This is effective immediately and the bond of /// the outgoing member is slashed. /// /// If a runner-up is available, then the best runner-up will be removed and replaces the - /// outgoing member. Otherwise, a new phragmen round is started. + /// outgoing member. Otherwise, a new phragmen election is started. /// /// Note that this does not affect the designated block number of the next election. /// /// # - /// #### State - /// Reads: O(do_phragmen) - /// Writes: O(do_phragmen) + /// If we have a replacement: + /// - Base weight: 50.93 µs + /// - State reads: + /// - RunnersUp.len() + /// - Members, RunnersUp (remove_and_replace_member) + /// - State writes: + /// - Members, RunnersUp (remove_and_replace_member) + /// Else, since this is a root call and will go into phragmen, we assume full block for now. /// # - #[weight = (2_000_000_000, DispatchClass::Operational)] - fn remove_member(origin, who: ::Source) -> DispatchResult { + #[weight = if *has_replacement { + 50 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(3, 2) + } else { + T::MaximumBlockWeight::get() + }] + fn remove_member( + origin, + who: ::Source, + has_replacement: bool, + ) -> DispatchResultWithPostInfo { ensure_root(origin)?; let who = T::Lookup::lookup(who)?; + let will_have_replacement = >::decode_len().unwrap_or(0) > 0; + if will_have_replacement != has_replacement { + // In both cases, we will change more weight than neede. Refund and abort. + return Err(Error::::InvalidReplacement.with_weight( + // refund. The weight value comes from a benchmark which is special to this. + // 5.751 µs + 6 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(1, 0) + )); + } // else, prediction was correct. + Self::remove_and_replace_member(&who).map(|had_replacement| { let (imbalance, _) = T::Currency::slash_reserved(&who, T::CandidacyBond::get()); T::KickedMember::on_unbalanced(imbalance); Self::deposit_event(RawEvent::MemberKicked(who.clone())); if !had_replacement { + // if we end up here, we will charge a full block weight. Self::do_phragmen(); } - }) + + // no refund needed. + None.into() + }).map_err(|e| e.into()) } /// What to do at the end of each block. Checks if an election needs to happen or not. fn on_initialize(n: T::BlockNumber) -> Weight { - if let Err(e) = Self::end_block(n) { - print("Guru meditation"); - print(e); - } - - 0 + // returns the correct weight. + Self::end_block(n) } } } @@ -503,7 +709,7 @@ decl_event!( Balance = BalanceOf, ::AccountId, { - /// A new term with new members. This indicates that enough candidates existed to run the + /// A new term with [new_members]. This indicates that enough candidates existed to run the /// election, not that enough have has been elected. The inner value must be examined for /// this purpose. A `NewTerm([])` indicates that some candidates got their bond slashed and /// none were elected, whilst `EmptyTerm` means that no candidates existed to begin with. @@ -511,25 +717,31 @@ decl_event!( /// No (or not enough) candidates existed for this round. This is different from /// `NewTerm([])`. See the description of `NewTerm`. EmptyTerm, - /// A member has been removed. This should always be followed by either `NewTerm` ot + /// A [member] has been removed. This should always be followed by either `NewTerm` ot /// `EmptyTerm`. MemberKicked(AccountId), - /// A member has renounced their candidacy. + /// A [member] has renounced their candidacy. MemberRenounced(AccountId), - /// A voter (first element) was reported (byt the second element) with the the report being - /// successful or not (third element). + /// A voter was reported with the the report being successful or not. + /// [voter, reporter, success] VoterReported(AccountId, AccountId, bool), } ); impl Module { - /// Attempts to remove a member `who`. If a runner up exists, it is used as the replacement. + /// Attempts to remove a member `who`. If a runner-up exists, it is used as the replacement and + /// Ok(true). is returned. + /// /// Otherwise, `Ok(false)` is returned to signal the caller. /// - /// In both cases, [`Members`], [`ElectionRounds`] and [`RunnersUp`] storage are updated - /// accordingly. Furthermore, the membership change is reported. + /// If a replacement exists, `Members` and `RunnersUp` storage is updated, where the first + /// element of `RunnersUp` is used as the replacement and `Ok(true)` is returned. Else, + /// `Ok(false)` is returned with no storage updated. /// - /// O(phragmen) in the worse case. + /// Note that this function _will_ call into `T::ChangeMembers` in case any change happens + /// (`Ok(true)`). + /// + /// If replacement exists, this will read and write from/into both `Members` and `RunnersUp`. fn remove_and_replace_member(who: &T::AccountId) -> Result { let mut members_with_stake = Self::members(); if let Ok(index) = members_with_stake.binary_search_by(|(ref m, ref _s)| m.cmp(who)) { @@ -562,7 +774,7 @@ impl Module { /// Check if `who` is a candidate. It returns the insert index if the element does not exists as /// an error. /// - /// State: O(LogN) given N candidates. + /// O(LogN) given N candidates. fn is_candidate(who: &T::AccountId) -> Result<(), usize> { Self::candidates().binary_search(who).map(|_| ()) } @@ -576,15 +788,15 @@ impl Module { /// Check if `who` is currently an active member. /// - /// Limited number of members. Binary search. Constant time factor. O(1) + /// O(LogN) given N members. Since members are limited, O(1). fn is_member(who: &T::AccountId) -> bool { Self::members().binary_search_by(|(a, _b)| a.cmp(who)).is_ok() } - /// Check if `who` is currently an active runner. + /// Check if `who` is currently an active runner-up. /// - /// Limited number of runners-up. Binary search. Constant time factor. O(1) - fn is_runner(who: &T::AccountId) -> bool { + /// O(LogN) given N runners-up. Since runners-up are limited, O(1). + fn is_runner_up(who: &T::AccountId) -> bool { Self::runners_up().iter().position(|(a, _b)| a == who).is_some() } @@ -613,25 +825,24 @@ impl Module { Self::runners_up().into_iter().map(|(r, _)| r).collect::>() } - /// Check if `who` is a defunct voter. - /// - /// Note that false is returned if `who` is not a voter at all. + /// Check if `votes` will correspond to a defunct voter. As no origin is part of the inputs, + /// this function does not check the origin at all. /// /// O(NLogM) with M candidates and `who` having voted for `N` of them. - fn is_defunct_voter(who: &T::AccountId) -> bool { - if Self::is_voter(who) { - Self::votes_of(who) - .iter() - .all(|v| !Self::is_member(v) && !Self::is_runner(v) && !Self::is_candidate(v).is_ok()) - } else { - false - } + /// Reads Members, RunnersUp, Candidates and Voting(who) from database. + fn is_defunct_voter(votes: &[T::AccountId]) -> bool { + votes.iter().all(|v| + !Self::is_member(v) && !Self::is_runner_up(v) && !Self::is_candidate(v).is_ok() + ) } /// Remove a certain someone as a voter. /// /// This will clean always clean the storage associated with the voter, and remove the balance /// lock. Optionally, it would also return the reserved voting bond if indicated by `unreserve`. + /// If unreserve is true, has 3 storage reads and 1 reads. + /// + /// DB access: Voting and Lock are always written to, if unreserve, then 1 read and write added. fn do_remove_voter(who: &T::AccountId, unreserve: bool) { // remove storage and lock. Voting::::remove(who); @@ -647,33 +858,26 @@ impl Module { Voting::::get(who).0 } - /// The locked stake of a voter. - fn votes_of(who: &T::AccountId) -> Vec { - Voting::::get(who).1 - } - /// Check there's nothing to do this block. /// /// Runs phragmen election and cleans all the previous candidate state. The voter state is NOT /// cleaned and voters must themselves submit a transaction to retract. - fn end_block(block_number: T::BlockNumber) -> DispatchResult { + fn end_block(block_number: T::BlockNumber) -> Weight { if !Self::term_duration().is_zero() { if (block_number % Self::term_duration()).is_zero() { Self::do_phragmen(); + return T::MaximumBlockWeight::get() } } - Ok(()) + 0 } /// Run the phragmen election with all required side processes and state updates. /// - /// Calls the appropriate `ChangeMembers` function variant internally. + /// Calls the appropriate [`ChangeMembers`] function variant internally. /// - /// # - /// #### State /// Reads: O(C + V*E) where C = candidates, V voters and E votes per voter exits. /// Writes: O(M + R) with M desired members and R runners_up. - /// # fn do_phragmen() { let desired_seats = Self::desired_members() as usize; let desired_runners_up = Self::desired_runners_up() as usize; @@ -703,14 +907,14 @@ impl Module { let voters_and_votes = Voting::::iter() .map(|(voter, (stake, targets))| { (voter, to_votes(stake), targets) }) .collect::>(); - let maybe_phragmen_result = sp_phragmen::elect::( + let maybe_phragmen_result = sp_npos_elections::seq_phragmen::( num_to_elect, 0, candidates, voters_and_votes.clone(), ); - if let Some(PhragmenResult { winners, assignments }) = maybe_phragmen_result { + if let Some(ElectionResult { winners, assignments }) = maybe_phragmen_result { let old_members_ids = >::take().into_iter() .map(|(m, _)| m) .collect::>(); @@ -734,7 +938,7 @@ impl Module { // exposed candidates, cleaning any previous members, and so on. For now, in favour of // readability and veracity, we keep it simple. - let staked_assignments = sp_phragmen::assignment_ratio_to_staked( + let staked_assignments = sp_npos_elections::assignment_ratio_to_staked( assignments, stake_of, ); @@ -798,7 +1002,7 @@ impl Module { ); T::ChangeMembers::change_members_sorted( &incoming, - &outgoing.clone(), + &outgoing, &new_members_ids, ); T::ChangeMembers::set_prime(prime); @@ -881,15 +1085,16 @@ impl ContainsLengthBound for Module { mod tests { use super::*; use std::cell::RefCell; - use frame_support::{assert_ok, assert_noop, parameter_types, weights::Weight}; + use frame_support::{assert_ok, assert_noop, assert_err_with_weight, parameter_types, + weights::Weight, + }; use substrate_test_utils::assert_eq_uvec; use sp_core::H256; use sp_runtime::{ - Perbill, testing::Header, BuildStorage, + Perbill, testing::Header, BuildStorage, DispatchResult, traits::{BlakeTwo256, IdentityLookup, Block as BlockT}, }; use crate as elections_phragmen; - use frame_system as system; parameter_types! { pub const BlockHashCount: u64 = 250; @@ -899,10 +1104,11 @@ mod tests { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; - type Call = (); + type Call = Call; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = u64; @@ -914,6 +1120,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -921,6 +1128,7 @@ mod tests { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { @@ -933,7 +1141,8 @@ mod tests { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = frame_system::Module; -} + type WeightInfo = (); + } parameter_types! { pub const CandidacyBond: u64 = 3; @@ -1000,7 +1209,7 @@ mod tests { new_plus_outgoing.extend_from_slice(outgoing); new_plus_outgoing.sort(); - assert_eq!(old_plus_incoming, new_plus_outgoing); + assert_eq!(old_plus_incoming, new_plus_outgoing, "change members call is incorrect!"); MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); PRIME.with(|p| *p.borrow_mut() = None); @@ -1041,6 +1250,7 @@ mod tests { type LoserCandidate = (); type KickedMember = (); type BadReport = (); + type WeightInfo = (); } pub type Block = sp_runtime::generic::Block; @@ -1052,7 +1262,7 @@ mod tests { NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system::{Module, Call, Event}, + System: frame_system::{Module, Call, Event}, Balances: pallet_balances::{Module, Call, Event, Config}, Elections: elections_phragmen::{Module, Call, Event, Config}, } @@ -1064,6 +1274,7 @@ mod tests { voter_bond: u64, term_duration: u64, desired_runners_up: u32, + desired_members: u32, } impl Default for ExtBuilder { @@ -1072,8 +1283,9 @@ mod tests { genesis_members: vec![], balance_factor: 1, voter_bond: 2, - desired_runners_up: 0, term_duration: 5, + desired_runners_up: 0, + desired_members: 2, } } } @@ -1095,15 +1307,24 @@ mod tests { self.genesis_members = members; self } + #[cfg(feature = "runtime-benchmarks")] + pub fn desired_members(mut self, count: u32) -> Self { + self.desired_members = count; + self + } pub fn balance_factor(mut self, factor: u64) -> Self { self.balance_factor = factor; self } - pub fn build_and_execute(self, test: impl FnOnce() -> ()) { + fn set_constants(&self) { VOTING_BOND.with(|v| *v.borrow_mut() = self.voter_bond); TERM_DURATION.with(|v| *v.borrow_mut() = self.term_duration); DESIRED_RUNNERS_UP.with(|v| *v.borrow_mut() = self.desired_runners_up); + DESIRED_MEMBERS.with(|m| *m.borrow_mut() = self.desired_members); MEMBERS.with(|m| *m.borrow_mut() = self.genesis_members.iter().map(|(m, _)| m.clone()).collect::>()); + } + pub fn build_and_execute(self, test: impl FnOnce() -> ()) { + self.set_constants(); let mut ext: sp_io::TestExternalities = GenesisConfig { pallet_balances: Some(pallet_balances::GenesisConfig::{ balances: vec![ @@ -1185,6 +1406,30 @@ mod tests { ensure_members_has_approval_stake(); } + fn submit_candidacy(origin: Origin) -> DispatchResult { + Elections::submit_candidacy(origin, Elections::candidates().len() as u32) + } + + fn vote(origin: Origin, votes: Vec, stake: u64) -> DispatchResult { + // historical note: helper function was created in a period of time in which the API of vote + // call was changing. Currently it is a wrapper for the original call and does not do much. + // Nonetheless, totally harmless. + ensure_signed(origin.clone()).expect("vote origin must be signed"); + Elections::vote(origin, votes, stake) + } + + fn votes_of(who: &u64) -> Vec { + Voting::::get(who).1 + } + + fn defunct_for(who: u64) -> DefunctVoter { + DefunctVoter { + who, + candidate_count: Elections::candidates().len() as u32, + vote_count: votes_of(&who).len() as u32 + } + } + #[test] fn params_should_work() { ExtBuilder::default().build_and_execute(|| { @@ -1200,7 +1445,7 @@ mod tests { assert!(Elections::is_candidate(&1).is_err()); assert_eq!(all_voters(), vec![]); - assert_eq!(Elections::votes_of(&1), vec![]); + assert_eq!(votes_of(&1), vec![]); }); } @@ -1215,7 +1460,7 @@ mod tests { // they will persist since they have self vote. System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![1, 2]); }) @@ -1232,7 +1477,7 @@ mod tests { // they will persist since they have self vote. System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![1, 2]); }) @@ -1280,7 +1525,7 @@ mod tests { assert_eq!(Elections::candidates(), vec![]); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![]); assert_eq!(Elections::runners_up(), vec![]); @@ -1296,7 +1541,7 @@ mod tests { assert!(Elections::is_candidate(&2).is_err()); assert_eq!(balances(&1), (10, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_ok!(submit_candidacy(Origin::signed(1))); assert_eq!(balances(&1), (7, 3)); assert_eq!(Elections::candidates(), vec![1]); @@ -1305,7 +1550,7 @@ mod tests { assert!(Elections::is_candidate(&2).is_err()); assert_eq!(balances(&2), (20, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(2))); assert_eq!(balances(&2), (17, 3)); assert_eq!(Elections::candidates(), vec![1, 2]); @@ -1320,8 +1565,8 @@ mod tests { ExtBuilder::default().build_and_execute(|| { assert_eq!(Elections::candidates(), Vec::::new()); - assert_ok!(Elections::submit_candidacy(Origin::signed(1))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(1))); + assert_ok!(submit_candidacy(Origin::signed(2))); assert!(Elections::is_candidate(&1).is_ok()); assert!(Elections::is_candidate(&2).is_ok()); @@ -1331,7 +1576,7 @@ mod tests { assert_eq!(Elections::runners_up(), vec![]); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert!(Elections::is_candidate(&1).is_err()); assert!(Elections::is_candidate(&2).is_err()); @@ -1346,10 +1591,10 @@ mod tests { fn dupe_candidate_submission_should_not_work() { ExtBuilder::default().build_and_execute(|| { assert_eq!(Elections::candidates(), Vec::::new()); - assert_ok!(Elections::submit_candidacy(Origin::signed(1))); + assert_ok!(submit_candidacy(Origin::signed(1))); assert_eq!(Elections::candidates(), vec![1]); assert_noop!( - Elections::submit_candidacy(Origin::signed(1)), + submit_candidacy(Origin::signed(1)), Error::::DuplicatedCandidate, ); }); @@ -1359,18 +1604,18 @@ mod tests { fn member_candidacy_submission_should_not_work() { // critically important to make sure that outgoing candidates and losers are not mixed up. ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(vote(Origin::signed(2), vec![5], 20)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![5]); assert_eq!(Elections::runners_up(), vec![]); assert_eq!(Elections::candidates(), vec![]); assert_noop!( - Elections::submit_candidacy(Origin::signed(5)), + submit_candidacy(Origin::signed(5)), Error::::MemberSubmit, ); }); @@ -1379,21 +1624,21 @@ mod tests { #[test] fn runner_candidate_submission_should_not_work() { ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::vote(Origin::signed(2), vec![5, 4], 20)); - assert_ok!(Elections::vote(Origin::signed(1), vec![3], 10)); + assert_ok!(vote(Origin::signed(2), vec![5, 4], 20)); + assert_ok!(vote(Origin::signed(1), vec![3], 10)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::runners_up_ids(), vec![3]); assert_noop!( - Elections::submit_candidacy(Origin::signed(3)), + submit_candidacy(Origin::signed(3)), Error::::RunnerSubmit, ); }); @@ -1404,7 +1649,7 @@ mod tests { ExtBuilder::default().build_and_execute(|| { assert_eq!(Elections::candidates(), Vec::::new()); assert_noop!( - Elections::submit_candidacy(Origin::signed(7)), + submit_candidacy(Origin::signed(7)), Error::::InsufficientCandidateFunds, ); }); @@ -1416,8 +1661,8 @@ mod tests { assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(balances(&2), (20, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(vote(Origin::signed(2), vec![5], 20)); assert_eq!(balances(&2), (18, 2)); assert_eq!(has_lock(&2), 20); @@ -1430,8 +1675,8 @@ mod tests { assert_eq!(Elections::candidates(), Vec::::new()); assert_eq!(balances(&2), (20, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::vote(Origin::signed(2), vec![5], 12)); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(vote(Origin::signed(2), vec![5], 12)); assert_eq!(balances(&2), (18, 2)); assert_eq!(has_lock(&2), 12); @@ -1443,16 +1688,16 @@ mod tests { ExtBuilder::default().build_and_execute(|| { assert_eq!(balances(&2), (20, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(vote(Origin::signed(2), vec![5], 20)); assert_eq!(balances(&2), (18, 2)); assert_eq!(has_lock(&2), 20); assert_eq!(Elections::locked_stake_of(&2), 20); // can update; different stake; different lock and reserve. - assert_ok!(Elections::vote(Origin::signed(2), vec![5, 4], 15)); + assert_ok!(vote(Origin::signed(2), vec![5, 4], 15)); assert_eq!(balances(&2), (18, 2)); assert_eq!(has_lock(&2), 15); assert_eq!(Elections::locked_stake_of(&2), 15); @@ -1463,8 +1708,8 @@ mod tests { fn cannot_vote_for_no_candidate() { ExtBuilder::default().build_and_execute(|| { assert_noop!( - Elections::vote(Origin::signed(2), vec![], 20), - Error::::UnableToVote, + vote(Origin::signed(2), vec![], 20), + Error::::NoVotes, ); }); } @@ -1472,41 +1717,41 @@ mod tests { #[test] fn can_vote_for_old_members_even_when_no_new_candidates() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 20)); + assert_ok!(vote(Origin::signed(2), vec![4, 5], 20)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::candidates(), vec![]); - assert_ok!(Elections::vote(Origin::signed(3), vec![4, 5], 10)); + assert_ok!(vote(Origin::signed(3), vec![4, 5], 10)); }); } #[test] fn prime_works() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::vote(Origin::signed(1), vec![4, 3], 10)); - assert_ok!(Elections::vote(Origin::signed(2), vec![4], 20)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(1), vec![4, 3], 10)); + assert_ok!(vote(Origin::signed(2), vec![4], 20)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::candidates(), vec![]); - assert_ok!(Elections::vote(Origin::signed(3), vec![4, 5], 10)); + assert_ok!(vote(Origin::signed(3), vec![4, 5], 10)); assert_eq!(PRIME.with(|p| *p.borrow()), Some(4)); }); } @@ -1514,20 +1759,20 @@ mod tests { #[test] fn prime_votes_for_exiting_members_are_removed() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::vote(Origin::signed(1), vec![4, 3], 10)); - assert_ok!(Elections::vote(Origin::signed(2), vec![4], 20)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(1), vec![4, 3], 10)); + assert_ok!(vote(Origin::signed(2), vec![4], 20)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); - assert_ok!(Elections::renounce_candidacy(Origin::signed(4))); + assert_ok!(Elections::renounce_candidacy(Origin::signed(4), Renouncing::Candidate(3))); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![3, 5]); assert_eq!(Elections::candidates(), vec![]); @@ -1544,29 +1789,29 @@ mod tests { .build_and_execute( || { // when we have only candidates - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); assert_noop!( // content of the vote is irrelevant. - Elections::vote(Origin::signed(1), vec![9, 99, 999, 9999], 5), + vote(Origin::signed(1), vec![9, 99, 999, 9999], 5), Error::::TooManyVotes, ); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); // now we have 2 members, 1 runner-up, and 1 new candidate - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(1), vec![9, 99, 999, 9999], 5)); + assert_ok!(vote(Origin::signed(1), vec![9, 99, 999, 9999], 5)); assert_noop!( - Elections::vote(Origin::signed(1), vec![9, 99, 999, 9_999, 99_999], 5), + vote(Origin::signed(1), vec![9, 99, 999, 9_999, 99_999], 5), Error::::TooManyVotes, ); }); @@ -1575,11 +1820,11 @@ mod tests { #[test] fn cannot_vote_for_less_than_ed() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); assert_noop!( - Elections::vote(Origin::signed(2), vec![4], 1), + vote(Origin::signed(2), vec![4], 1), Error::::LowBalance, ); }) @@ -1588,10 +1833,10 @@ mod tests { #[test] fn can_vote_for_more_than_total_balance_but_moot() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 30)); + assert_ok!(vote(Origin::signed(2), vec![4, 5], 30)); // you can lie but won't get away with it. assert_eq!(Elections::locked_stake_of(&2), 20); assert_eq!(has_lock(&2), 20); @@ -1601,21 +1846,21 @@ mod tests { #[test] fn remove_voter_should_work() { ExtBuilder::default().voter_bond(8).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); - assert_ok!(Elections::vote(Origin::signed(3), vec![5], 30)); + assert_ok!(vote(Origin::signed(2), vec![5], 20)); + assert_ok!(vote(Origin::signed(3), vec![5], 30)); assert_eq_uvec!(all_voters(), vec![2, 3]); assert_eq!(Elections::locked_stake_of(&2), 20); assert_eq!(Elections::locked_stake_of(&3), 30); - assert_eq!(Elections::votes_of(&2), vec![5]); - assert_eq!(Elections::votes_of(&3), vec![5]); + assert_eq!(votes_of(&2), vec![5]); + assert_eq!(votes_of(&3), vec![5]); assert_ok!(Elections::remove_voter(Origin::signed(2))); assert_eq_uvec!(all_voters(), vec![3]); - assert_eq!(Elections::votes_of(&2), vec![]); + assert_eq!(votes_of(&2), vec![]); assert_eq!(Elections::locked_stake_of(&2), 0); assert_eq!(balances(&2), (20, 0)); @@ -1633,8 +1878,8 @@ mod tests { #[test] fn dupe_remove_should_fail() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(vote(Origin::signed(2), vec![5], 20)); assert_ok!(Elections::remove_voter(Origin::signed(2))); assert_eq!(all_voters(), vec![]); @@ -1646,18 +1891,18 @@ mod tests { #[test] fn removed_voter_should_not_be_counted() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); assert_ok!(Elections::remove_voter(Origin::signed(4))); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![3, 5]); }); @@ -1667,47 +1912,102 @@ mod tests { fn reporter_must_be_voter() { ExtBuilder::default().build_and_execute(|| { assert_noop!( - Elections::report_defunct_voter(Origin::signed(1), 2), + Elections::report_defunct_voter(Origin::signed(1), defunct_for(2)), Error::::MustBeVoter, ); }); } + #[test] + fn reporter_must_provide_lengths() { + ExtBuilder::default().build_and_execute(|| { + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + + // both are defunct. + assert_ok!(vote(Origin::signed(5), vec![99, 999, 9999], 50)); + assert_ok!(vote(Origin::signed(4), vec![999], 40)); + + // 3 candidates! incorrect candidate length. + assert_noop!( + Elections::report_defunct_voter(Origin::signed(4), DefunctVoter { + who: 5, + candidate_count: 2, + vote_count: 3, + }), + Error::::InvalidCandidateCount, + ); + + // 3 votes! incorrect vote length + assert_noop!( + Elections::report_defunct_voter(Origin::signed(4), DefunctVoter { + who: 5, + candidate_count: 3, + vote_count: 2, + }), + Error::::InvalidVoteCount, + ); + + // correct. + assert_ok!(Elections::report_defunct_voter(Origin::signed(4), DefunctVoter { + who: 5, + candidate_count: 3, + vote_count: 3, + })); + }); + } + + #[test] + fn reporter_can_overestimate_length() { + ExtBuilder::default().build_and_execute(|| { + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + + // both are defunct. + assert_ok!(vote(Origin::signed(5), vec![99], 50)); + assert_ok!(vote(Origin::signed(4), vec![999], 40)); + + // 2 candidates! overestimation is okay. + assert_ok!(Elections::report_defunct_voter(Origin::signed(4), defunct_for(5))); + }); + } + #[test] fn can_detect_defunct_voter() { ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(6))); - - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 20)); - assert_ok!(Elections::vote(Origin::signed(6), vec![6], 30)); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(6))); + + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(2), vec![4, 5], 20)); + assert_ok!(vote(Origin::signed(6), vec![6], 30)); // will be soon a defunct voter. - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::runners_up_ids(), vec![6]); assert_eq!(Elections::candidates(), vec![]); // all of them have a member or runner-up that they voted for. - assert_eq!(Elections::is_defunct_voter(&5), false); - assert_eq!(Elections::is_defunct_voter(&4), false); - assert_eq!(Elections::is_defunct_voter(&2), false); - assert_eq!(Elections::is_defunct_voter(&6), false); + assert_eq!(Elections::is_defunct_voter(&votes_of(&5)), false); + assert_eq!(Elections::is_defunct_voter(&votes_of(&4)), false); + assert_eq!(Elections::is_defunct_voter(&votes_of(&2)), false); + assert_eq!(Elections::is_defunct_voter(&votes_of(&6)), false); // defunct - assert_eq!(Elections::is_defunct_voter(&3), true); + assert_eq!(Elections::is_defunct_voter(&votes_of(&3)), true); - assert_ok!(Elections::submit_candidacy(Origin::signed(1))); - assert_ok!(Elections::vote(Origin::signed(1), vec![1], 10)); + assert_ok!(submit_candidacy(Origin::signed(1))); + assert_ok!(vote(Origin::signed(1), vec![1], 10)); // has a candidate voted for. - assert_eq!(Elections::is_defunct_voter(&1), false); + assert_eq!(Elections::is_defunct_voter(&votes_of(&1)), false); }); } @@ -1715,17 +2015,17 @@ mod tests { #[test] fn report_voter_should_work_and_earn_reward() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(2), vec![4, 5], 20)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(2), vec![4, 5], 20)); // will be soon a defunct voter. - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::candidates(), vec![]); @@ -1733,7 +2033,7 @@ mod tests { assert_eq!(balances(&3), (28, 2)); assert_eq!(balances(&5), (45, 5)); - assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 3)); + assert_ok!(Elections::report_defunct_voter(Origin::signed(5), defunct_for(3))); assert!(System::events().iter().any(|event| { event.event == Event::elections_phragmen(RawEvent::VoterReported(3, 5, true)) })); @@ -1746,14 +2046,14 @@ mod tests { #[test] fn report_voter_should_slash_when_bad_report() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::candidates(), vec![]); @@ -1761,7 +2061,7 @@ mod tests { assert_eq!(balances(&4), (35, 5)); assert_eq!(balances(&5), (45, 5)); - assert_ok!(Elections::report_defunct_voter(Origin::signed(5), 4)); + assert_ok!(Elections::report_defunct_voter(Origin::signed(5), defunct_for(4))); assert!(System::events().iter().any(|event| { event.event == Event::elections_phragmen(RawEvent::VoterReported(4, 5, false)) })); @@ -1774,19 +2074,19 @@ mod tests { #[test] fn simple_voting_rounds_should_work() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 15)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(2), vec![5], 20)); + assert_ok!(vote(Origin::signed(4), vec![4], 15)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); assert_eq_uvec!(all_voters(), vec![2, 3, 4]); - assert_eq!(Elections::votes_of(&2), vec![5]); - assert_eq!(Elections::votes_of(&3), vec![3]); - assert_eq!(Elections::votes_of(&4), vec![4]); + assert_eq!(votes_of(&2), vec![5]); + assert_eq!(votes_of(&3), vec![3]); + assert_eq!(votes_of(&4), vec![4]); assert_eq!(Elections::candidates(), vec![3, 4, 5]); assert_eq!(>::decode_len().unwrap(), 3); @@ -1794,7 +2094,7 @@ mod tests { assert_eq!(Elections::election_rounds(), 0); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members(), vec![(3, 30), (5, 20)]); assert_eq!(Elections::runners_up(), vec![]); @@ -1809,23 +2109,23 @@ mod tests { #[test] fn defunct_voter_will_be_counted() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(5))); // This guy's vote is pointless for this round. - assert_ok!(Elections::vote(Origin::signed(3), vec![4], 30)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(3), vec![4], 30)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members(), vec![(5, 50)]); assert_eq!(Elections::election_rounds(), 1); // but now it has a valid target. - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(4))); System::set_block_number(10); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); // candidate 4 is affected by an old vote. assert_eq!(Elections::members(), vec![(4, 30), (5, 50)]); @@ -1837,18 +2137,18 @@ mod tests { #[test] fn only_desired_seats_are_chosen() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(2), vec![2], 20)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::election_rounds(), 1); assert_eq!(Elections::members_ids(), vec![4, 5]); @@ -1858,11 +2158,11 @@ mod tests { #[test] fn phragmen_should_not_self_vote() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::candidates(), vec![]); assert_eq!(Elections::election_rounds(), 1); @@ -1878,18 +2178,18 @@ mod tests { #[test] fn runners_up_should_be_kept() { ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(2), vec![3], 20)); - assert_ok!(Elections::vote(Origin::signed(3), vec![2], 30)); - assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![4], 50)); + assert_ok!(vote(Origin::signed(2), vec![3], 20)); + assert_ok!(vote(Origin::signed(3), vec![2], 30)); + assert_ok!(vote(Origin::signed(4), vec![5], 40)); + assert_ok!(vote(Origin::signed(5), vec![4], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); // sorted based on account id. assert_eq!(Elections::members_ids(), vec![4, 5]); // sorted based on merit (least -> most) @@ -1905,25 +2205,25 @@ mod tests { #[test] fn runners_up_should_be_next_candidates() { ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(2), vec![2], 20)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members(), vec![(4, 40), (5, 50)]); assert_eq!(Elections::runners_up(), vec![(2, 20), (3, 30)]); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 15)); + assert_ok!(vote(Origin::signed(5), vec![5], 15)); System::set_block_number(10); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members(), vec![(3, 30), (4, 40)]); assert_eq!(Elections::runners_up(), vec![(5, 15), (2, 20)]); }); @@ -1932,25 +2232,25 @@ mod tests { #[test] fn runners_up_lose_bond_once_outgoing() { ExtBuilder::default().desired_runners_up(1).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(2), vec![2], 20)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::runners_up_ids(), vec![2]); assert_eq!(balances(&2), (15, 5)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); System::set_block_number(10); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::runners_up_ids(), vec![3]); assert_eq!(balances(&2), (15, 2)); @@ -1962,21 +2262,21 @@ mod tests { ExtBuilder::default().build_and_execute(|| { assert_eq!(balances(&5), (50, 0)); - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(5))); assert_eq!(balances(&5), (47, 3)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); assert_eq!(balances(&5), (45, 5)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![5]); assert_ok!(Elections::remove_voter(Origin::signed(5))); assert_eq!(balances(&5), (47, 3)); System::set_block_number(10); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![]); assert_eq!(balances(&5), (47, 0)); @@ -1986,16 +2286,16 @@ mod tests { #[test] fn losers_will_lose_the_bond() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); + assert_ok!(vote(Origin::signed(4), vec![5], 40)); assert_eq!(balances(&5), (47, 3)); assert_eq!(balances(&3), (27, 3)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![5]); @@ -2009,23 +2309,23 @@ mod tests { #[test] fn current_members_are_always_next_candidate() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::election_rounds(), 1); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(submit_candidacy(Origin::signed(2))); + assert_ok!(vote(Origin::signed(2), vec![2], 20)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); assert_ok!(Elections::remove_voter(Origin::signed(4))); @@ -2033,7 +2333,7 @@ mod tests { assert_eq!(Elections::candidates(), vec![2, 3]); System::set_block_number(10); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); // 4 removed; 5 and 3 are the new best. assert_eq!(Elections::members_ids(), vec![3, 5]); @@ -2045,19 +2345,19 @@ mod tests { // what I mean by uninterrupted: // given no input or stimulants the same members are re-elected. ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(2), vec![2], 20)); let check_at_block = |b: u32| { System::set_block_number(b.into()); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); // we keep re-electing the same folks. assert_eq!(Elections::members(), vec![(4, 40), (5, 50)]); assert_eq!(Elections::runners_up(), vec![(2, 20), (3, 30)]); @@ -2078,22 +2378,22 @@ mod tests { #[test] fn remove_members_triggers_election() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::election_rounds(), 1); // a new candidate - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::remove_member(Origin::ROOT, 4)); + assert_ok!(Elections::remove_member(Origin::root(), 4, false)); assert_eq!(balances(&4), (35, 2)); // slashed assert_eq!(Elections::election_rounds(), 2); // new election round @@ -2101,24 +2401,68 @@ mod tests { }); } + #[test] + fn remove_member_should_indicate_replacement() { + ExtBuilder::default().build_and_execute(|| { + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + Elections::end_block(System::block_number()); + assert_eq!(Elections::members_ids(), vec![4, 5]); + + // no replacement yet. + assert_err_with_weight!( + Elections::remove_member(Origin::root(), 4, true), + Error::::InvalidReplacement, + Some(6000000), + ); + }); + + ExtBuilder::default().desired_runners_up(1).build_and_execute(|| { + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + + System::set_block_number(5); + Elections::end_block(System::block_number()); + assert_eq!(Elections::members_ids(), vec![4, 5]); + assert_eq!(Elections::runners_up_ids(), vec![3]); + + // there is a replacement! and this one needs a weight refund. + assert_err_with_weight!( + Elections::remove_member(Origin::root(), 4, false), + Error::::InvalidReplacement, + Some(6000000) // only thing that matters for now is that it is NOT the full block. + ); + }); + } + #[test] fn seats_should_be_released_when_no_vote() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::vote(Origin::signed(2), vec![3], 20)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(2), vec![3], 20)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); assert_eq!(>::decode_len().unwrap(), 3); assert_eq!(Elections::election_rounds(), 0); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![3, 5]); assert_eq!(Elections::election_rounds(), 1); @@ -2129,7 +2473,7 @@ mod tests { // meanwhile, no one cares to become a candidate again. System::set_block_number(10); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![]); assert_eq!(Elections::election_rounds(), 2); }); @@ -2138,32 +2482,32 @@ mod tests { #[test] fn incoming_outgoing_are_reported() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); - assert_ok!(Elections::submit_candidacy(Origin::signed(1))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(1))); + assert_ok!(submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(3))); // 5 will change their vote and becomes an `outgoing` - assert_ok!(Elections::vote(Origin::signed(5), vec![4], 8)); + assert_ok!(vote(Origin::signed(5), vec![4], 8)); // 4 will stay in the set - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); // 3 will become a winner - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); // these two are losers. - assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); - assert_ok!(Elections::vote(Origin::signed(1), vec![1], 10)); + assert_ok!(vote(Origin::signed(2), vec![2], 20)); + assert_ok!(vote(Origin::signed(1), vec![1], 10)); System::set_block_number(10); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); // 3, 4 are new members, must still be bonded, nothing slashed. assert_eq!(Elections::members(), vec![(3, 30), (4, 48)]); @@ -2185,15 +2529,15 @@ mod tests { #[test] fn invalid_votes_are_moot() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![10], 50)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![10], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq_uvec!(Elections::members_ids(), vec![3, 4]); assert_eq!(Elections::election_rounds(), 1); @@ -2203,18 +2547,18 @@ mod tests { #[test] fn members_are_sorted_based_on_id_runners_on_merit() { ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(2), vec![3], 20)); - assert_ok!(Elections::vote(Origin::signed(3), vec![2], 30)); - assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![4], 50)); + assert_ok!(vote(Origin::signed(2), vec![3], 20)); + assert_ok!(vote(Origin::signed(3), vec![2], 30)); + assert_ok!(vote(Origin::signed(4), vec![5], 40)); + assert_ok!(vote(Origin::signed(5), vec![4], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); // id: low -> high. assert_eq!(Elections::members(), vec![(4, 50), (5, 40)]); // merit: low -> high. @@ -2225,14 +2569,14 @@ mod tests { #[test] fn candidates_are_sorted() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(3))); assert_eq!(Elections::candidates(), vec![3, 5]); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::renounce_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(Elections::renounce_candidacy(Origin::signed(3), Renouncing::Candidate(4))); assert_eq!(Elections::candidates(), vec![2, 4, 5]); }) @@ -2241,64 +2585,43 @@ mod tests { #[test] fn runner_up_replacement_maintains_members_order() { ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![2], 50)); + assert_ok!(vote(Origin::signed(2), vec![5], 20)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![2], 50)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![2, 4]); - assert_ok!(Elections::remove_member(Origin::ROOT, 2)); + assert_ok!(Elections::remove_member(Origin::root(), 2, true)); assert_eq!(Elections::members_ids(), vec![4, 5]); }); } - #[test] - fn runner_up_replacement_works_when_out_of_order() { - ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); - - assert_ok!(Elections::vote(Origin::signed(2), vec![5], 20)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(5), vec![2], 50)); - - System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); - - assert_eq!(Elections::members_ids(), vec![2, 4]); - assert_ok!(Elections::renounce_candidacy(Origin::signed(3))); - }); - } - #[test] fn can_renounce_candidacy_member_with_runners_bond_is_refunded() { ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(2), vec![2], 20)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::runners_up_ids(), vec![2, 3]); - assert_ok!(Elections::renounce_candidacy(Origin::signed(4))); + assert_ok!(Elections::renounce_candidacy(Origin::signed(4), Renouncing::Member)); assert_eq!(balances(&4), (38, 2)); // 2 is voting bond. assert_eq!(Elections::members_ids(), vec![3, 5]); @@ -2309,55 +2632,47 @@ mod tests { #[test] fn can_renounce_candidacy_member_without_runners_bond_is_refunded() { ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::vote(Origin::signed(5), vec![5], 50)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); - - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::runners_up_ids(), vec![]); - assert_eq!(Elections::candidates(), vec![2, 3]); - assert_ok!(Elections::renounce_candidacy(Origin::signed(4))); + assert_ok!(Elections::renounce_candidacy(Origin::signed(4), Renouncing::Member)); assert_eq!(balances(&4), (38, 2)); // 2 is voting bond. // no replacement assert_eq!(Elections::members_ids(), vec![5]); assert_eq!(Elections::runners_up_ids(), vec![]); - // still candidate - assert_eq!(Elections::candidates(), vec![2, 3]); }) } #[test] fn can_renounce_candidacy_runner() { ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); - assert_ok!(Elections::submit_candidacy(Origin::signed(4))); - assert_ok!(Elections::submit_candidacy(Origin::signed(3))); - assert_ok!(Elections::submit_candidacy(Origin::signed(2))); + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + assert_ok!(submit_candidacy(Origin::signed(2))); - assert_ok!(Elections::vote(Origin::signed(5), vec![4], 50)); - assert_ok!(Elections::vote(Origin::signed(4), vec![5], 40)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(vote(Origin::signed(5), vec![4], 50)); + assert_ok!(vote(Origin::signed(4), vec![5], 40)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(2), vec![2], 20)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![4, 5]); assert_eq!(Elections::runners_up_ids(), vec![2, 3]); - assert_ok!(Elections::renounce_candidacy(Origin::signed(3))); + assert_ok!(Elections::renounce_candidacy(Origin::signed(3), Renouncing::RunnerUp)); assert_eq!(balances(&3), (28, 2)); // 2 is voting bond. assert_eq!(Elections::members_ids(), vec![4, 5]); @@ -2365,14 +2680,38 @@ mod tests { }) } + // #[test] + // fn runner_up_replacement_works_when_out_of_order() { + // ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { + // assert_ok!(submit_candidacy(Origin::signed(5))); + // assert_ok!(submit_candidacy(Origin::signed(4))); + // assert_ok!(submit_candidacy(Origin::signed(3))); + // assert_ok!(submit_candidacy(Origin::signed(2))); + + // assert_ok!(vote(Origin::signed(2), vec![5], 20)); + // assert_ok!(vote(Origin::signed(3), vec![3], 30)); + // assert_ok!(vote(Origin::signed(4), vec![4], 40)); + // assert_ok!(vote(Origin::signed(5), vec![2], 50)); + + // System::set_block_number(5); + // Elections::end_block(System::block_number()); + + // assert_eq!(Elections::members_ids(), vec![2, 4]); + // assert_eq!(ELections::runners_up_ids(), vec![3, 5]); + // assert_ok!(Elections::renounce_candidacy(Origin::signed(3), Renouncing::RunnerUp)); + // assert_eq!(Elections::members_ids(), vec![2, 4]); + // assert_eq!(ELections::runners_up_ids(), vec![5]); + // }); + // } + #[test] fn can_renounce_candidacy_candidate() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(5))); assert_eq!(balances(&5), (47, 3)); assert_eq!(Elections::candidates(), vec![5]); - assert_ok!(Elections::renounce_candidacy(Origin::signed(5))); + assert_ok!(Elections::renounce_candidacy(Origin::signed(5), Renouncing::Candidate(1))); assert_eq!(balances(&5), (50, 0)); assert_eq!(Elections::candidates(), vec![]); }) @@ -2382,25 +2721,107 @@ mod tests { fn wrong_renounce_candidacy_should_fail() { ExtBuilder::default().build_and_execute(|| { assert_noop!( - Elections::renounce_candidacy(Origin::signed(5)), - Error::::InvalidOrigin, + Elections::renounce_candidacy(Origin::signed(5), Renouncing::Candidate(0)), + Error::::InvalidRenouncing, + ); + assert_noop!( + Elections::renounce_candidacy(Origin::signed(5), Renouncing::Member), + Error::::NotMember, + ); + assert_noop!( + Elections::renounce_candidacy(Origin::signed(5), Renouncing::RunnerUp), + Error::::InvalidRenouncing, ); }) } + #[test] + fn non_member_renounce_member_should_fail() { + ExtBuilder::default().desired_runners_up(1).build_and_execute(|| { + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + + System::set_block_number(5); + Elections::end_block(System::block_number()); + + assert_eq!(Elections::members_ids(), vec![4, 5]); + assert_eq!(Elections::runners_up_ids(), vec![3]); + + assert_noop!( + Elections::renounce_candidacy(Origin::signed(3), Renouncing::Member), + Error::::NotMember, + ); + }) + } + + #[test] + fn non_runner_up_renounce_runner_up_should_fail() { + ExtBuilder::default().desired_runners_up(1).build_and_execute(|| { + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + + assert_ok!(vote(Origin::signed(5), vec![5], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + + System::set_block_number(5); + Elections::end_block(System::block_number()); + + assert_eq!(Elections::members_ids(), vec![4, 5]); + assert_eq!(Elections::runners_up_ids(), vec![3]); + + assert_noop!( + Elections::renounce_candidacy(Origin::signed(4), Renouncing::RunnerUp), + Error::::InvalidRenouncing, + ); + }) + } + + #[test] + fn wrong_candidate_count_renounce_should_fail() { + ExtBuilder::default().build_and_execute(|| { + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + + assert_noop!( + Elections::renounce_candidacy(Origin::signed(4), Renouncing::Candidate(2)), + Error::::InvalidRenouncing, + ); + + assert_ok!(Elections::renounce_candidacy(Origin::signed(4), Renouncing::Candidate(3))); + }) + } + + #[test] + fn renounce_candidacy_count_can_overestimate() { + ExtBuilder::default().build_and_execute(|| { + assert_ok!(submit_candidacy(Origin::signed(5))); + assert_ok!(submit_candidacy(Origin::signed(4))); + assert_ok!(submit_candidacy(Origin::signed(3))); + // while we have only 3 candidates. + assert_ok!(Elections::renounce_candidacy(Origin::signed(4), Renouncing::Candidate(4))); + }) + } + #[test] fn behavior_with_dupe_candidate() { ExtBuilder::default().desired_runners_up(2).build_and_execute(|| { - // TODD: this is a demonstration and should be fixed with #4593 >::put(vec![1, 1, 2, 3, 4]); - assert_ok!(Elections::vote(Origin::signed(5), vec![1], 50)); - assert_ok!(Elections::vote(Origin::signed(4), vec![4], 40)); - assert_ok!(Elections::vote(Origin::signed(3), vec![3], 30)); - assert_ok!(Elections::vote(Origin::signed(2), vec![2], 20)); + assert_ok!(vote(Origin::signed(5), vec![1], 50)); + assert_ok!(vote(Origin::signed(4), vec![4], 40)); + assert_ok!(vote(Origin::signed(3), vec![3], 30)); + assert_ok!(vote(Origin::signed(2), vec![2], 20)); System::set_block_number(5); - assert_ok!(Elections::end_block(System::block_number())); + Elections::end_block(System::block_number()); assert_eq!(Elections::members_ids(), vec![1, 4]); assert_eq!(Elections::runners_up_ids(), vec![2, 3]); diff --git a/frame/elections/Cargo.toml b/frame/elections/Cargo.toml index 407b5ccfdb1769d503ad1c5270529f3c8cd75470..01619f2b05a3aeabafb6a1eef670e9babd6099f3 100644 --- a/frame/elections/Cargo.toml +++ b/frame/elections/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-elections" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for elections" @@ -13,17 +13,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -hex-literal = "0.2.1" -pallet-balances = { version = "2.0.0-dev", path = "../balances" } +hex-literal = "0.3.1" +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } [features] default = ["std"] diff --git a/frame/elections/README.md b/frame/elections/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1f6fd42331c15ef172346f733488d36fa4d0ed80 --- /dev/null +++ b/frame/elections/README.md @@ -0,0 +1,7 @@ +Election module for stake-weighted membership selection of a collective. + +The composition of a set of account IDs works according to one or more approval votes +weighted by stake. There is a partial carry-over facility to give greater weight to those +whose voting is serially unsuccessful. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/elections/src/lib.rs b/frame/elections/src/lib.rs index a684ce3144d8027154fb3d9fabca6fc607a342ac..1453e2f0fd9fcbcf3fda66af76b91905dd2446ff 100644 --- a/frame/elections/src/lib.rs +++ b/frame/elections/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Election module for stake-weighted membership selection of a collective. //! @@ -37,7 +38,7 @@ use frame_support::{ } }; use codec::{Encode, Decode}; -use frame_system::{self as system, ensure_signed, ensure_root}; +use frame_system::{ensure_signed, ensure_root}; mod mock; mod tests; @@ -236,16 +237,25 @@ decl_storage! { // bit-wise manner. In order to get a human-readable representation (`Vec`), use // [`all_approvals_of`]. Furthermore, each vector of scalars is chunked with the cap of // `APPROVAL_SET_SIZE`. + /// + /// TWOX-NOTE: SAFE as `AccountId` is a crypto hash and `SetIndex` is not + /// attacker-controlled. pub ApprovalsOf get(fn approvals_of): map hasher(twox_64_concat) (T::AccountId, SetIndex) => Vec; /// The vote index and list slot that the candidate `who` was registered or `None` if they /// are not currently registered. + /// + /// TWOX-NOTE: SAFE as `AccountId` is a crypto hash. pub RegisterInfoOf get(fn candidate_reg_info): map hasher(twox_64_concat) T::AccountId => Option<(VoteIndex, u32)>; /// Basic information about a voter. + /// + /// TWOX-NOTE: SAFE as `AccountId` is a crypto hash. pub VoterInfoOf get(fn voter_info): map hasher(twox_64_concat) T::AccountId => Option>>; /// The present voter list (chunked and capped at [`VOTER_SET_SIZE`]). + /// + /// TWOX-NOTE: OKAY ― `SetIndex` is not user-controlled data. pub Voters get(fn voters): map hasher(twox_64_concat) SetIndex => Vec>; /// the next free set to store a voter in. This will keep growing. pub NextVoterSet get(fn next_nonfull_voter_set): SetIndex = 0; @@ -264,10 +274,6 @@ decl_storage! { /// of each entry; It may be the direct summed approval stakes, or a weighted version of it. /// Sorted from low to high. pub Leaderboard get(fn leaderboard): Option, T::AccountId)> >; - - /// Who is able to vote for whom. Value is the fund-holding account, key is the - /// vote-transaction-sending account. - pub Proxy get(fn proxy): map hasher(blake2_128_concat) T::AccountId => Option; } } @@ -282,8 +288,6 @@ decl_error! { CannotReapPresenting, /// Cannot reap during grace period. ReapGrace, - /// Not a proxy. - NotProxy, /// Invalid reporter index. InvalidReporterIndex, /// Invalid target index. @@ -420,23 +424,6 @@ decl_module! { Self::do_set_approvals(who, votes, index, hint, value) } - /// Set candidate approvals from a proxy. Approval slots stay valid as long as candidates in - /// those slots are registered. - /// - /// # - /// - Same as `set_approvals` with one additional storage read. - /// # - #[weight = 2_500_000_000] - fn proxy_set_approvals(origin, - votes: Vec, - #[compact] index: VoteIndex, - hint: SetIndex, - #[compact] value: BalanceOf, - ) -> DispatchResult { - let who = Self::proxy(ensure_signed(origin)?).ok_or(Error::::NotProxy)?; - Self::do_set_approvals(who, votes, index, hint, value) - } - /// Remove a voter. For it not to be a bond-consuming no-op, all approved candidate indices /// must now be either unregistered or registered to a candidate that registered the slot /// after the voter gave their last approval set. @@ -713,13 +700,14 @@ decl_module! { decl_event!( pub enum Event where ::AccountId { - /// reaped voter, reaper + /// Reaped [voter, reaper]. VoterReaped(AccountId, AccountId), - /// slashed reaper + /// Slashed [reaper]. BadReaperSlashed(AccountId), - /// A tally (for approval votes of seat(s)) has started. + /// A tally (for approval votes of [seats]) has started. TallyStarted(u32), - /// A tally (for approval votes of seat(s)) has ended (with one or more new members). + /// A tally (for approval votes of seat(s)) has ended (with one or more new members). + /// [incoming, outgoing] TallyFinalized(Vec, Vec), } ); diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index c779f22a3203b17660ccaf572cd55e685a38855f..c9b2523c4bc8a8dbb705b541bf5bd4e37525dd39 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Mock file for election module. @@ -38,8 +39,9 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; - type Call = (); + type Call = Call; type Index = u64; type BlockNumber = u64; type Hash = H256; @@ -53,6 +55,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -60,6 +63,7 @@ impl frame_system::Trait for Test { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { @@ -71,6 +75,7 @@ impl pallet_balances::Trait for Test { type Event = Event; type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { @@ -125,7 +130,7 @@ impl ChangeMembers for TestChangeMembers { } parameter_types!{ - pub const ElectionModuleId: LockIdentifier = *b"py/elect"; + pub const ElectionModuleId: LockIdentifier = *b"py/elect"; } impl elections::Trait for Test { diff --git a/frame/elections/src/tests.rs b/frame/elections/src/tests.rs index 64b01f12e0cfe8c3b9971bee6e3772f4a2fb2adf..247b6272524b1c64073e4a6157af1b2a5e2bd3a3 100644 --- a/frame/elections/src/tests.rs +++ b/frame/elections/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for election module. @@ -670,7 +671,7 @@ fn retracting_active_voter_should_slash_reporter() { assert_ok!(Elections::end_block(System::block_number())); System::set_block_number(8); - assert_ok!(Elections::set_desired_seats(Origin::ROOT, 3)); + assert_ok!(Elections::set_desired_seats(Origin::root(), 3)); assert_ok!(Elections::end_block(System::block_number())); System::set_block_number(10); @@ -867,45 +868,6 @@ fn election_voting_should_work() { }); } -#[test] -fn election_proxy_voting_should_work() { - ExtBuilder::default().build().execute_with(|| { - assert_ok!(Elections::submit_candidacy(Origin::signed(5), 0)); - - >::insert(11, 1); - >::insert(12, 2); - >::insert(13, 3); - >::insert(14, 4); - assert_ok!( - Elections::proxy_set_approvals(Origin::signed(11), vec![true], 0, 0, 10) - ); - assert_ok!( - Elections::proxy_set_approvals(Origin::signed(14), vec![true], 0, 1, 40) - ); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(voter_ids(), vec![1, 4]); - - assert_ok!(Elections::submit_candidacy(Origin::signed(2), 1)); - assert_ok!(Elections::submit_candidacy(Origin::signed(3), 2)); - - assert_ok!( - Elections::proxy_set_approvals(Origin::signed(12), vec![false, true], 0, 2, 20) - ); - assert_ok!( - Elections::proxy_set_approvals(Origin::signed(13), vec![false, true], 0, 3, 30) - ); - - assert_eq!(Elections::all_approvals_of(&1), vec![true]); - assert_eq!(Elections::all_approvals_of(&4), vec![true]); - assert_eq!(Elections::all_approvals_of(&2), vec![false, true]); - assert_eq!(Elections::all_approvals_of(&3), vec![false, true]); - - assert_eq!(voter_ids(), vec![1, 4, 2, 3]); - }); -} - #[test] fn election_simple_tally_should_work() { ExtBuilder::default().build().execute_with(|| { @@ -1283,7 +1245,7 @@ fn election_second_tally_should_use_runners_up() { System::set_block_number(8); assert_ok!(Elections::set_approvals(Origin::signed(6), vec![false, false, true, false], 1, 0, 60)); - assert_ok!(Elections::set_desired_seats(Origin::ROOT, 3)); + assert_ok!(Elections::set_desired_seats(Origin::root(), 3)); assert_ok!(Elections::end_block(System::block_number())); System::set_block_number(10); diff --git a/frame/evm/Cargo.toml b/frame/evm/Cargo.toml index eaa5ae3e42baa6b514e4f2e8c50bb23032ebda26..0f14f3afe4862027aa16a0cf2e5bfc0f24a76184 100644 --- a/frame/evm/Cargo.toml +++ b/frame/evm/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-evm" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME EVM contracts pallet" @@ -13,19 +13,21 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../timestamp" } -pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../balances" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../timestamp" } +pallet-balances = { version = "2.0.0-rc6", default-features = false, path = "../balances" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } primitive-types = { version = "0.7.0", default-features = false, features = ["rlp"] } rlp = { version = "0.4", default-features = false } -evm = { version = "0.16", default-features = false } +evm = { version = "0.17", default-features = false } sha3 = { version = "0.8", default-features = false } +impl-trait-for-tuples = "0.1" +ripemd160 = { version = "0.9", default-features = false } [features] default = ["std"] @@ -44,4 +46,5 @@ std = [ "primitive-types/std", "evm/std", "pallet-timestamp/std", + "ripemd160/std", ] diff --git a/frame/evm/README.md b/frame/evm/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f8feadbf58eb41acd459e26e24841325f54c8783 --- /dev/null +++ b/frame/evm/README.md @@ -0,0 +1,3 @@ +EVM execution module for Substrate + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/evm/src/backend.rs b/frame/evm/src/backend.rs index c610f24bb1db2d763979e978dd183c5719a731b9..df8ef9b85c43e628f392eec6e3aff2c846dc3722 100644 --- a/frame/evm/src/backend.rs +++ b/frame/evm/src/backend.rs @@ -5,10 +5,11 @@ use serde::{Serialize, Deserialize}; use codec::{Encode, Decode}; use sp_core::{U256, H256, H160}; use sp_runtime::traits::UniqueSaturatedInto; -use frame_support::storage::{StorageMap, StorageDoubleMap}; +use frame_support::traits::Get; +use frame_support::{debug, storage::{StorageMap, StorageDoubleMap}}; use sha3::{Keccak256, Digest}; use evm::backend::{Backend as BackendT, ApplyBackend, Apply}; -use crate::{Trait, Accounts, AccountStorages, AccountCodes, Module, Event}; +use crate::{Trait, AccountStorages, AccountCodes, Module, Event}; #[derive(Clone, Eq, PartialEq, Encode, Decode, Default)] #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] @@ -91,7 +92,7 @@ impl<'vicinity, T: Trait> BackendT for Backend<'vicinity, T> { } fn chain_id(&self) -> U256 { - U256::from(sp_io::misc::chain_id()) + U256::from(T::ChainId::get()) } fn exists(&self, _address: H160) -> bool { @@ -99,7 +100,7 @@ impl<'vicinity, T: Trait> BackendT for Backend<'vicinity, T> { } fn basic(&self, address: H160) -> evm::backend::Basic { - let account = Accounts::get(&address); + let account = Module::::account_basic(&address); evm::backend::Basic { balance: account.balance, @@ -140,12 +141,18 @@ impl<'vicinity, T: Trait> ApplyBackend for Backend<'vicinity, T> { Apply::Modify { address, basic, code, storage, reset_storage, } => { - Accounts::mutate(&address, |account| { - account.balance = basic.balance; - account.nonce = basic.nonce; + Module::::mutate_account_basic(&address, Account { + nonce: basic.nonce, + balance: basic.balance, }); if let Some(code) = code { + debug::debug!( + target: "evm", + "Inserting code ({} bytes) at {:?}", + code.len(), + address + ); AccountCodes::insert(address, code); } @@ -155,8 +162,21 @@ impl<'vicinity, T: Trait> ApplyBackend for Backend<'vicinity, T> { for (index, value) in storage { if value == H256::default() { + debug::debug!( + target: "evm", + "Removing storage for {:?} [index: {:?}]", + address, + index + ); AccountStorages::remove(address, index); } else { + debug::debug!( + target: "evm", + "Updating storage for {:?} [index: {:?}, value: {:?}]", + address, + index, + value + ); AccountStorages::insert(address, index, value); } } @@ -166,12 +186,26 @@ impl<'vicinity, T: Trait> ApplyBackend for Backend<'vicinity, T> { } }, Apply::Delete { address } => { + debug::debug!( + target: "evm", + "Deleting account at {:?}", + address + ); Module::::remove_account(&address) }, } } for log in logs { + debug::trace!( + target: "evm", + "Inserting log for {:?}, topics ({}) {:?}, data ({}): {:?}]", + log.address, + log.topics.len(), + log.topics, + log.data.len(), + log.data + ); Module::::deposit_event(Event::::Log(Log { address: log.address, topics: log.topics, diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index c7aa8b8d3a443697aad238a3e5ca061615b84740..211946bed0e95f4e8e33987d456935e9b05e1fcf 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! EVM execution module for Substrate @@ -20,21 +21,27 @@ #![cfg_attr(not(feature = "std"), no_std)] mod backend; +mod tests; +pub mod precompiles; +pub use crate::precompiles::{Precompile, Precompiles}; pub use crate::backend::{Account, Log, Vicinity, Backend}; -use sp_std::{vec::Vec, marker::PhantomData}; -use frame_support::{ensure, decl_module, decl_storage, decl_event, decl_error}; -use frame_support::weights::{Weight, DispatchClass, FunctionOf, Pays}; -use frame_support::traits::{Currency, WithdrawReason, ExistenceRequirement, Get}; -use frame_system::{self as system, ensure_signed}; -use sp_runtime::ModuleId; +use sp_std::vec::Vec; +#[cfg(feature = "std")] +use codec::{Encode, Decode}; +#[cfg(feature = "std")] +use serde::{Serialize, Deserialize}; +use frame_support::{debug, ensure, decl_module, decl_storage, decl_event, decl_error}; +use frame_support::weights::{Weight, Pays}; +use frame_support::traits::{Currency, ExistenceRequirement, Get}; +use frame_support::dispatch::DispatchResultWithPostInfo; +use frame_system::RawOrigin; use sp_core::{U256, H256, H160, Hasher}; -use sp_runtime::{ - DispatchResult, traits::{UniqueSaturatedInto, AccountIdConversion, SaturatedConversion}, -}; +use sp_runtime::{AccountId32, traits::{UniqueSaturatedInto, SaturatedConversion, BadOrigin}}; use sha3::{Digest, Keccak256}; -use evm::{ExitReason, ExitSucceed, ExitError, Config}; +pub use evm::{ExitReason, ExitSucceed, ExitError, ExitRevert, ExitFatal}; +use evm::Config; use evm::executor::StackExecutor; use evm::backend::ApplyBackend; @@ -51,65 +58,130 @@ impl FeeCalculator for () { fn min_gas_price() -> U256 { U256::zero() } } -/// Trait for converting account ids of `balances` module into -/// `H160` for EVM module. -/// -/// Accounts and contracts of this module are stored in its own -/// storage, in an Ethereum-compatible format. In order to communicate -/// with the rest of Substrate module, we require an one-to-one -/// mapping of Substrate account to Ethereum address. -pub trait ConvertAccountId { - /// Given a Substrate address, return the corresponding Ethereum address. - fn convert_account_id(account_id: &A) -> H160; +pub trait EnsureAddressOrigin { + /// Success return type. + type Success; + + /// Perform the origin check. + fn ensure_address_origin( + address: &H160, + origin: OuterOrigin, + ) -> Result { + Self::try_address_origin(address, origin).map_err(|_| BadOrigin) + } + + /// Try with origin. + fn try_address_origin( + address: &H160, + origin: OuterOrigin, + ) -> Result; } -/// Hash and then truncate the account id, taking the last 160-bit as the Ethereum address. -pub struct HashTruncateConvertAccountId(PhantomData); +/// Ensure that the EVM address is the same as the Substrate address. This only works if the account +/// ID is `H160`. +pub struct EnsureAddressSame; + +impl EnsureAddressOrigin for EnsureAddressSame where + OuterOrigin: Into, OuterOrigin>> + From>, +{ + type Success = H160; + + fn try_address_origin( + address: &H160, + origin: OuterOrigin, + ) -> Result { + origin.into().and_then(|o| match o { + RawOrigin::Signed(who) if &who == address => Ok(who), + r => Err(OuterOrigin::from(r)) + }) + } +} -impl Default for HashTruncateConvertAccountId { - fn default() -> Self { - Self(PhantomData) +/// Ensure that the origin is root. +pub struct EnsureAddressRoot(sp_std::marker::PhantomData); + +impl EnsureAddressOrigin for EnsureAddressRoot where + OuterOrigin: Into, OuterOrigin>> + From>, +{ + type Success = (); + + fn try_address_origin( + _address: &H160, + origin: OuterOrigin, + ) -> Result<(), OuterOrigin> { + origin.into().and_then(|o| match o { + RawOrigin::Root => Ok(()), + r => Err(OuterOrigin::from(r)), + }) } } -impl> ConvertAccountId for HashTruncateConvertAccountId { - fn convert_account_id(account_id: &A) -> H160 { - let account_id = H::hash(account_id.as_ref()); - let account_id_len = account_id.as_ref().len(); - let mut value = [0u8; 20]; - let value_len = value.len(); - - if value_len > account_id_len { - value[(value_len - account_id_len)..].copy_from_slice(account_id.as_ref()); - } else { - value.copy_from_slice(&account_id.as_ref()[(account_id_len - value_len)..]); - } +/// Ensure that the origin never happens. +pub struct EnsureAddressNever(sp_std::marker::PhantomData); + +impl EnsureAddressOrigin for EnsureAddressNever { + type Success = AccountId; + + fn try_address_origin( + _address: &H160, + origin: OuterOrigin, + ) -> Result { + Err(origin) + } +} - H160::from(value) +/// Ensure that the address is truncated hash of the origin. Only works if the account id is +/// `AccountId32`. +pub struct EnsureAddressTruncated; + +impl EnsureAddressOrigin for EnsureAddressTruncated where + OuterOrigin: Into, OuterOrigin>> + From>, +{ + type Success = AccountId32; + + fn try_address_origin( + address: &H160, + origin: OuterOrigin, + ) -> Result { + origin.into().and_then(|o| match o { + RawOrigin::Signed(who) + if AsRef::<[u8; 32]>::as_ref(&who)[0..20] == address[0..20] => Ok(who), + r => Err(OuterOrigin::from(r)) + }) } } -/// Custom precompiles to be used by EVM engine. -pub trait Precompiles { - /// Try to execute the code address as precompile. If the code address is not - /// a precompile or the precompile is not yet available, return `None`. - /// Otherwise, calculate the amount of gas needed with given `input` and - /// `target_gas`. Return `Some(Ok(status, output, gas_used))` if the execution - /// is successful. Otherwise return `Some(Err(_))`. - fn execute( - address: H160, - input: &[u8], - target_gas: Option - ) -> Option, usize), ExitError>>; +pub trait AddressMapping { + fn into_account_id(address: H160) -> A; } -impl Precompiles for () { - fn execute( - _address: H160, - _input: &[u8], - _target_gas: Option - ) -> Option, usize), ExitError>> { - None +/// Identity address mapping. +pub struct IdentityAddressMapping; + +impl AddressMapping for IdentityAddressMapping { + fn into_account_id(address: H160) -> H160 { address } +} + +/// Hashed address mapping. +pub struct HashedAddressMapping(sp_std::marker::PhantomData); + +impl> AddressMapping for HashedAddressMapping { + fn into_account_id(address: H160) -> AccountId32 { + let mut data = [0u8; 24]; + data[0..4].copy_from_slice(b"evm:"); + data[4..24].copy_from_slice(&address[..]); + let hash = H::hash(&data); + + AccountId32::from(Into::<[u8; 32]>::into(hash)) + } +} + +/// Substrate system chain ID. +pub struct SystemChainId; + +impl Get for SystemChainId { + fn get() -> u64 { + sp_io::misc::chain_id() } } @@ -117,18 +189,25 @@ static ISTANBUL_CONFIG: Config = Config::istanbul(); /// EVM module trait pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { - /// The EVM's module id - type ModuleId: Get; /// Calculator for current gas price. type FeeCalculator: FeeCalculator; - /// Convert account ID to H160; - type ConvertAccountId: ConvertAccountId; - /// Currency type for deposit and withdraw. + + /// Allow the origin to call on behalf of given address. + type CallOrigin: EnsureAddressOrigin; + /// Allow the origin to withdraw on behalf of given address. + type WithdrawOrigin: EnsureAddressOrigin; + + /// Mapping from address to account id. + type AddressMapping: AddressMapping; + /// Currency type for withdraw and balance storage. type Currency: Currency; + /// The overarching event type. type Event: From> + Into<::Event>; /// Precompiles associated with this EVM engine. type Precompiles: Precompiles; + /// Chain ID of EVM. + type ChainId: Get; /// EVM config used in the module. fn config() -> &'static Config { @@ -136,11 +215,42 @@ pub trait Trait: frame_system::Trait + pallet_timestamp::Trait { } } +#[cfg(feature = "std")] +#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, Serialize, Deserialize)] +/// Account definition used for genesis block construction. +pub struct GenesisAccount { + /// Account nonce. + pub nonce: U256, + /// Account balance. + pub balance: U256, + /// Full account storage. + pub storage: std::collections::BTreeMap, + /// Account code. + pub code: Vec, +} + decl_storage! { trait Store for Module as EVM { - Accounts get(fn accounts) config(): map hasher(blake2_128_concat) H160 => Account; - AccountCodes: map hasher(blake2_128_concat) H160 => Vec; - AccountStorages: double_map hasher(blake2_128_concat) H160, hasher(blake2_128_concat) H256 => H256; + AccountCodes get(fn account_codes): map hasher(blake2_128_concat) H160 => Vec; + AccountStorages get(fn account_storages): + double_map hasher(blake2_128_concat) H160, hasher(blake2_128_concat) H256 => H256; + } + + add_extra_genesis { + config(accounts): std::collections::BTreeMap; + build(|config: &GenesisConfig| { + for (address, account) in &config.accounts { + Module::::mutate_account_basic(&address, Account { + balance: account.balance, + nonce: account.nonce, + }); + AccountCodes::insert(address, &account.code); + + for (index, value) in &account.storage { + AccountStorages::insert(address, index, value); + } + } + }); } } @@ -151,11 +261,17 @@ decl_event! { { /// Ethereum events from contracts. Log(Log), - /// A contract has been created at given address. + /// A contract has been created at given [address]. Created(H160), - /// A deposit has been made at a given address. + /// A [contract] was attempted to be created, but the execution failed. + CreatedFailed(H160), + /// A [contract] has been executed successfully with states applied. + Executed(H160), + /// A [contract] has been executed with errors. States are reverted with only gas fees applied. + ExecutedFailed(H160), + /// A deposit has been made at a given address. [sender, address, value] BalanceDeposit(AccountId, H160, U256), - /// A withdrawal has been made from a given address. + /// A withdrawal has been made from a given address. [sender, address, value] BalanceWithdraw(AccountId, H160, U256), } } @@ -172,12 +288,6 @@ decl_error! { WithdrawFailed, /// Gas price is too low. GasPriceTooLow, - /// Call failed - ExitReasonFailed, - /// Call reverted - ExitReasonRevert, - /// Call returned VM fatal error - ExitReasonFatal, /// Nonce is invalid InvalidNonce, } @@ -189,186 +299,156 @@ decl_module! { fn deposit_event() = default; - const ModuleId: ModuleId = T::ModuleId::get(); - - /// Deposit balance from currency/balances module into EVM. - #[weight = 0] - fn deposit_balance(origin, value: BalanceOf) { - let sender = ensure_signed(origin)?; - - let imbalance = T::Currency::withdraw( - &sender, - value, - WithdrawReason::Reserve.into(), - ExistenceRequirement::AllowDeath, - )?; - T::Currency::resolve_creating(&Self::account_id(), imbalance); - - let bvalue = U256::from(UniqueSaturatedInto::::unique_saturated_into(value)); - let address = T::ConvertAccountId::convert_account_id(&sender); - Accounts::mutate(&address, |account| { - account.balance += bvalue; - }); - Module::::deposit_event(Event::::BalanceDeposit(sender, address, bvalue)); - } - /// Withdraw balance from EVM into currency/balances module. #[weight = 0] - fn withdraw_balance(origin, value: BalanceOf) { - let sender = ensure_signed(origin)?; - let address = T::ConvertAccountId::convert_account_id(&sender); - let bvalue = U256::from(UniqueSaturatedInto::::unique_saturated_into(value)); - - let mut account = Accounts::get(&address); - account.balance = account.balance.checked_sub(bvalue) - .ok_or(Error::::BalanceLow)?; + fn withdraw(origin, address: H160, value: BalanceOf) { + let destination = T::WithdrawOrigin::ensure_address_origin(&address, origin)?; + let address_account_id = T::AddressMapping::into_account_id(address); - let imbalance = T::Currency::withdraw( - &Self::account_id(), + T::Currency::transfer( + &address_account_id, + &destination, value, - WithdrawReason::Reserve.into(), ExistenceRequirement::AllowDeath )?; - - Accounts::insert(&address, account); - - T::Currency::resolve_creating(&sender, imbalance); - Module::::deposit_event(Event::::BalanceWithdraw(sender, address, bvalue)); } /// Issue an EVM call operation. This is similar to a message call transaction in Ethereum. - #[weight = FunctionOf( - |(_, _, _, gas_limit, gas_price, _): (&H160, &Vec, &U256, &u32, &U256, &Option)| - (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), - DispatchClass::Normal, - Pays::Yes, - )] + #[weight = (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight)] fn call( origin, + source: H160, target: H160, input: Vec, value: U256, gas_limit: u32, gas_price: U256, nonce: Option, - ) -> DispatchResult { - let sender = ensure_signed(origin)?; - let source = T::ConvertAccountId::convert_account_id(&sender); + ) -> DispatchResultWithPostInfo { + T::CallOrigin::ensure_address_origin(&source, origin)?; - Self::execute_evm( + match Self::execute_call( source, + target, + input, value, gas_limit, - gas_price, + Some(gas_price), nonce, - |executor| ((), executor.transact_call( - source, - target, - value, - input, - gas_limit as usize, - )), - ).map_err(Into::into) + true, + )? { + (ExitReason::Succeed(_), _, _) => { + Module::::deposit_event(Event::::Executed(target)); + }, + (_, _, _) => { + Module::::deposit_event(Event::::ExecutedFailed(target)); + }, + } + + Ok(Pays::No.into()) } /// Issue an EVM create operation. This is similar to a contract creation transaction in /// Ethereum. - #[weight = FunctionOf( - |(_, _, gas_limit, gas_price, _): (&Vec, &U256, &u32, &U256, &Option)| - (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), - DispatchClass::Normal, - Pays::Yes, - )] + #[weight = (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight)] fn create( origin, + source: H160, init: Vec, value: U256, gas_limit: u32, gas_price: U256, nonce: Option, - ) -> DispatchResult { - let sender = ensure_signed(origin)?; - let source = T::ConvertAccountId::convert_account_id(&sender); + ) -> DispatchResultWithPostInfo { + T::CallOrigin::ensure_address_origin(&source, origin)?; - let create_address = Self::execute_evm( + match Self::execute_create( source, + init, value, gas_limit, - gas_price, + Some(gas_price), nonce, - |executor| { - (executor.create_address( - evm::CreateScheme::Legacy { caller: source }, - ), executor.transact_create( - source, - value, - init, - gas_limit as usize, - )) + true, + )? { + (ExitReason::Succeed(_), create_address, _) => { + Module::::deposit_event(Event::::Created(create_address)); }, - )?; + (_, create_address, _) => { + Module::::deposit_event(Event::::CreatedFailed(create_address)); + }, + } - Module::::deposit_event(Event::::Created(create_address)); - Ok(()) + Ok(Pays::No.into()) } /// Issue an EVM create2 operation. - #[weight = FunctionOf( - |(_, _, _, gas_limit, gas_price, _): (&Vec, &H256, &U256, &u32, &U256, &Option)| - (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight), - DispatchClass::Normal, - Pays::Yes, - )] + #[weight = (*gas_price).saturated_into::().saturating_mul(*gas_limit as Weight)] fn create2( origin, + source: H160, init: Vec, salt: H256, value: U256, gas_limit: u32, gas_price: U256, nonce: Option, - ) -> DispatchResult { - let sender = ensure_signed(origin)?; - let source = T::ConvertAccountId::convert_account_id(&sender); + ) -> DispatchResultWithPostInfo { + T::CallOrigin::ensure_address_origin(&source, origin)?; - let code_hash = H256::from_slice(Keccak256::digest(&init).as_slice()); - let create_address = Self::execute_evm( + match Self::execute_create2( source, + init, + salt, value, gas_limit, - gas_price, + Some(gas_price), nonce, - |executor| { - (executor.create_address( - evm::CreateScheme::Create2 { caller: source, code_hash, salt }, - ), executor.transact_create2( - source, - value, - init, - salt, - gas_limit as usize, - )) + true, + )? { + (ExitReason::Succeed(_), create_address, _) => { + Module::::deposit_event(Event::::Created(create_address)); }, - )?; + (_, create_address, _) => { + Module::::deposit_event(Event::::CreatedFailed(create_address)); + }, + } - Module::::deposit_event(Event::::Created(create_address)); - Ok(()) + Ok(Pays::No.into()) } } } impl Module { - /// The account ID of the EVM module. - /// - /// This actually does computation. If you need to keep using it, then make sure you cache the - /// value and only call this once. - pub fn account_id() -> T::AccountId { - T::ModuleId::get().into_account() + fn remove_account(address: &H160) { + AccountCodes::remove(address); + AccountStorages::remove_prefix(address); + } + + fn mutate_account_basic(address: &H160, new: Account) { + let account_id = T::AddressMapping::into_account_id(*address); + let current = Self::account_basic(address); + + if current.nonce < new.nonce { + // ASSUME: in one single EVM transaction, the nonce will not increase more than + // `u128::max_value()`. + for _ in 0..(new.nonce - current.nonce).low_u128() { + frame_system::Module::::inc_account_nonce(&account_id); + } + } + + if current.balance > new.balance { + let diff = current.balance - new.balance; + T::Currency::slash(&account_id, diff.low_u128().unique_saturated_into()); + } else if current.balance < new.balance { + let diff = new.balance - current.balance; + T::Currency::deposit_creating(&account_id, diff.low_u128().unique_saturated_into()); + } } /// Check whether an account is empty. pub fn is_account_empty(address: &H160) -> bool { - let account = Accounts::get(address); + let account = Self::account_basic(address); let code_len = AccountCodes::decode_len(address).unwrap_or(0); account.nonce == U256::zero() && @@ -379,15 +459,114 @@ impl Module { /// Remove an account if its empty. pub fn remove_account_if_empty(address: &H160) { if Self::is_account_empty(address) { - Self::remove_account(address) + Self::remove_account(address); } } - /// Remove an account from state. - fn remove_account(address: &H160) { - Accounts::remove(address); - AccountCodes::remove(address); - AccountStorages::remove_prefix(address); + /// Get the account basic in EVM format. + pub fn account_basic(address: &H160) -> Account { + let account_id = T::AddressMapping::into_account_id(*address); + + let nonce = frame_system::Module::::account_nonce(&account_id); + let balance = T::Currency::free_balance(&account_id); + + Account { + nonce: U256::from(UniqueSaturatedInto::::unique_saturated_into(nonce)), + balance: U256::from(UniqueSaturatedInto::::unique_saturated_into(balance)), + } + } + + /// Execute a create transaction on behalf of given sender. + pub fn execute_create( + source: H160, + init: Vec, + value: U256, + gas_limit: u32, + gas_price: Option, + nonce: Option, + apply_state: bool, + ) -> Result<(ExitReason, H160, U256), Error> { + Self::execute_evm( + source, + value, + gas_limit, + gas_price, + nonce, + apply_state, + |executor| { + let address = executor.create_address( + evm::CreateScheme::Legacy { caller: source }, + ); + (executor.transact_create( + source, + value, + init, + gas_limit as usize, + ), address) + }, + ) + } + + /// Execute a create2 transaction on behalf of a given sender. + pub fn execute_create2( + source: H160, + init: Vec, + salt: H256, + value: U256, + gas_limit: u32, + gas_price: Option, + nonce: Option, + apply_state: bool, + ) -> Result<(ExitReason, H160, U256), Error> { + let code_hash = H256::from_slice(Keccak256::digest(&init).as_slice()); + Self::execute_evm( + source, + value, + gas_limit, + gas_price, + nonce, + apply_state, + |executor| { + let address = executor.create_address( + evm::CreateScheme::Create2 { caller: source, code_hash, salt }, + ); + (executor.transact_create2( + source, + value, + init, + salt, + gas_limit as usize, + ), address) + }, + ) + } + + /// Execute a call transaction on behalf of a given sender. + pub fn execute_call( + source: H160, + target: H160, + input: Vec, + value: U256, + gas_limit: u32, + gas_price: Option, + nonce: Option, + apply_state: bool, + ) -> Result<(ExitReason, Vec, U256), Error> { + Self::execute_evm( + source, + value, + gas_limit, + gas_price, + nonce, + apply_state, + |executor| executor.transact_call( + source, + target, + value, + input, + gas_limit as usize, + ), + ) } /// Execute an EVM operation. @@ -395,13 +574,20 @@ impl Module { source: H160, value: U256, gas_limit: u32, - gas_price: U256, + gas_price: Option, nonce: Option, + apply_state: bool, f: F, - ) -> Result> where - F: FnOnce(&mut StackExecutor>) -> (R, ExitReason), + ) -> Result<(ExitReason, R, U256), Error> where + F: FnOnce(&mut StackExecutor>) -> (ExitReason, R), { - ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::::GasPriceTooLow); + let gas_price = match gas_price { + Some(gas_price) => { + ensure!(gas_price >= T::FeeCalculator::min_gas_price(), Error::::GasPriceTooLow); + gas_price + }, + None => U256::zero(), + }; let vicinity = Vicinity { gas_price, @@ -419,7 +605,7 @@ impl Module { let total_fee = gas_price.checked_mul(U256::from(gas_limit)) .ok_or(Error::::FeeOverflow)?; let total_payment = value.checked_add(total_fee).ok_or(Error::::PaymentOverflow)?; - let source_account = Accounts::get(&source); + let source_account = Self::account_basic(&source); ensure!(source_account.balance >= total_payment, Error::::BalanceLow); executor.withdraw(source, total_fee).map_err(|_| Error::::WithdrawFailed)?; @@ -429,19 +615,25 @@ impl Module { let (retv, reason) = f(&mut executor); - let ret = match reason { - ExitReason::Succeed(_) => Ok(retv), - ExitReason::Error(_) => Err(Error::::ExitReasonFailed), - ExitReason::Revert(_) => Err(Error::::ExitReasonRevert), - ExitReason::Fatal(_) => Err(Error::::ExitReasonFatal), - }; - + let used_gas = U256::from(executor.used_gas()); let actual_fee = executor.fee(gas_price); + debug::debug!( + target: "evm", + "Execution {:?} [source: {:?}, value: {}, gas_limit: {}, used_gas: {}, actual_fee: {}]", + retv, + source, + value, + gas_limit, + used_gas, + actual_fee + ); executor.deposit(source, total_fee.saturating_sub(actual_fee)); - let (values, logs) = executor.deconstruct(); - backend.apply(values, logs, true); + if apply_state { + let (values, logs) = executor.deconstruct(); + backend.apply(values, logs, true); + } - ret + Ok((retv, reason, used_gas)) } } diff --git a/frame/evm/src/precompiles.rs b/frame/evm/src/precompiles.rs new file mode 100644 index 0000000000000000000000000000000000000000..987724285d7b84511e1e05987908edc1520b370f --- /dev/null +++ b/frame/evm/src/precompiles.rs @@ -0,0 +1,166 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Builtin precompiles. + +use sp_std::{cmp::min, vec::Vec}; +use sp_core::H160; +use evm::{ExitError, ExitSucceed}; +use ripemd160::Digest; +use impl_trait_for_tuples::impl_for_tuples; + +/// Custom precompiles to be used by EVM engine. +pub trait Precompiles { + /// Try to execute the code address as precompile. If the code address is not + /// a precompile or the precompile is not yet available, return `None`. + /// Otherwise, calculate the amount of gas needed with given `input` and + /// `target_gas`. Return `Some(Ok(status, output, gas_used))` if the execution + /// is successful. Otherwise return `Some(Err(_))`. + fn execute( + address: H160, + input: &[u8], + target_gas: Option, + ) -> Option, usize), ExitError>>; +} + +/// One single precompile used by EVM engine. +pub trait Precompile { + /// Try to execute the precompile. Calculate the amount of gas needed with given `input` and + /// `target_gas`. Return `Ok(status, output, gas_used)` if the execution is + /// successful. Otherwise return `Err(_)`. + fn execute( + input: &[u8], + target_gas: Option, + ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError>; +} + +#[impl_for_tuples(16)] +#[tuple_types_no_default_trait_bound] +impl Precompiles for Tuple { + for_tuples!( where #( Tuple: Precompile )* ); + + fn execute( + address: H160, + input: &[u8], + target_gas: Option, + ) -> Option, usize), ExitError>> { + let mut index = 0; + + for_tuples!( #( + index += 1; + if address == H160::from_low_u64_be(index) { + return Some(Tuple::execute(input, target_gas)) + } + )* ); + + None + } +} + +/// Linear gas cost +fn ensure_linear_cost( + target_gas: Option, + len: usize, + base: usize, + word: usize +) -> Result { + let cost = base.checked_add( + word.checked_mul(len.saturating_add(31) / 32).ok_or(ExitError::OutOfGas)? + ).ok_or(ExitError::OutOfGas)?; + + if let Some(target_gas) = target_gas { + if cost > target_gas { + return Err(ExitError::OutOfGas) + } + } + + Ok(cost) +} + +/// The identity precompile. +pub struct Identity; + +impl Precompile for Identity { + fn execute( + input: &[u8], + target_gas: Option, + ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError> { + let cost = ensure_linear_cost(target_gas, input.len(), 15, 3)?; + + Ok((ExitSucceed::Returned, input.to_vec(), cost)) + } +} + +/// The ecrecover precompile. +pub struct ECRecover; + +impl Precompile for ECRecover { + fn execute( + i: &[u8], + target_gas: Option, + ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError> { + let cost = ensure_linear_cost(target_gas, i.len(), 3000, 0)?; + + let mut input = [0u8; 128]; + input[..min(i.len(), 128)].copy_from_slice(&i[..min(i.len(), 128)]); + + let mut msg = [0u8; 32]; + let mut sig = [0u8; 65]; + + msg[0..32].copy_from_slice(&input[0..32]); + sig[0..32].copy_from_slice(&input[64..96]); + sig[32..64].copy_from_slice(&input[96..128]); + sig[64] = input[63]; + + let pubkey = sp_io::crypto::secp256k1_ecdsa_recover(&sig, &msg) + .map_err(|_| ExitError::Other("Public key recover failed"))?; + let mut address = sp_io::hashing::keccak_256(&pubkey); + address[0..12].copy_from_slice(&[0u8; 12]); + + Ok((ExitSucceed::Returned, address.to_vec(), cost)) + } +} + +/// The ripemd precompile. +pub struct Ripemd160; + +impl Precompile for Ripemd160 { + fn execute( + input: &[u8], + target_gas: Option, + ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError> { + let cost = ensure_linear_cost(target_gas, input.len(), 600, 120)?; + + let ret = ripemd160::Ripemd160::digest(input).to_vec(); + Ok((ExitSucceed::Returned, ret, cost)) + } +} + +/// The sha256 precompile. +pub struct Sha256; + +impl Precompile for Sha256 { + fn execute( + input: &[u8], + target_gas: Option, + ) -> core::result::Result<(ExitSucceed, Vec, usize), ExitError> { + let cost = ensure_linear_cost(target_gas, input.len(), 60, 12)?; + + let ret = sp_io::hashing::sha2_256(input); + Ok((ExitSucceed::Returned, ret.to_vec(), cost)) + } +} diff --git a/frame/evm/src/tests.rs b/frame/evm/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..652d6c723b9d337ba42fbd62e3445dee64fa253f --- /dev/null +++ b/frame/evm/src/tests.rs @@ -0,0 +1,188 @@ +#![cfg(test)] + +use super::*; + +use std::{str::FromStr, collections::BTreeMap}; +use frame_support::{ + assert_ok, impl_outer_origin, parameter_types, impl_outer_dispatch, +}; +use sp_core::{Blake2Hasher, H256}; +use sp_runtime::{ + Perbill, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +impl_outer_dispatch! { + pub enum OuterCall for Test where origin: Origin { + self::EVM, + } +} + +#[derive(Clone, Eq, PartialEq)] +pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl frame_system::Trait for Test { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = OuterCall; + type Hashing = BlakeTwo256; + type AccountId = AccountId32; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Trait for Test { + type Balance = u64; + type DustRemoval = (); + type Event = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} + +parameter_types! { + pub const MinimumPeriod: u64 = 1000; +} +impl pallet_timestamp::Trait for Test { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +/// Fixed gas price of `0`. +pub struct FixedGasPrice; +impl FeeCalculator for FixedGasPrice { + fn min_gas_price() -> U256 { + // Gas price is always one token per gas. + 0.into() + } +} + +impl Trait for Test { + type FeeCalculator = FixedGasPrice; + + type CallOrigin = EnsureAddressRoot; + type WithdrawOrigin = EnsureAddressNever; + + type AddressMapping = HashedAddressMapping; + type Currency = Balances; + + type Event = Event; + type Precompiles = (); + type ChainId = SystemChainId; +} + +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type EVM = Module; + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + let mut accounts = BTreeMap::new(); + accounts.insert( + H160::from_str("1000000000000000000000000000000000000001").unwrap(), + GenesisAccount { + nonce: U256::from(1), + balance: U256::from(1000000), + storage: Default::default(), + code: vec![ + 0x00, // STOP + ], + } + ); + accounts.insert( + H160::from_str("1000000000000000000000000000000000000002").unwrap(), + GenesisAccount { + nonce: U256::from(1), + balance: U256::from(1000000), + storage: Default::default(), + code: vec![ + 0xff, // INVALID + ], + } + ); + + pallet_balances::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); + GenesisConfig { accounts }.assimilate_storage::(&mut t).unwrap(); + t.into() +} + +#[test] +fn fail_call_return_ok() { + new_test_ext().execute_with(|| { + assert_ok!(EVM::call( + Origin::root(), + H160::default(), + H160::from_str("1000000000000000000000000000000000000001").unwrap(), + Vec::new(), + U256::default(), + 1000000, + U256::default(), + None, + )); + + assert_ok!(EVM::call( + Origin::root(), + H160::default(), + H160::from_str("1000000000000000000000000000000000000002").unwrap(), + Vec::new(), + U256::default(), + 1000000, + U256::default(), + None, + )); + }); +} + +#[test] +fn mutate_account_works() { + new_test_ext().execute_with(|| { + EVM::mutate_account_basic( + &H160::from_str("1000000000000000000000000000000000000001").unwrap(), + Account { + nonce: U256::from(10), + balance: U256::from(1000), + }, + ); + + assert_eq!(EVM::account_basic( + &H160::from_str("1000000000000000000000000000000000000001").unwrap() + ), Account { + nonce: U256::from(10), + balance: U256::from(1000), + }); + }); +} diff --git a/frame/example-offchain-worker/Cargo.toml b/frame/example-offchain-worker/Cargo.toml index 30381adb49f171c538e18e9af8e9c64ccf110a2c..d8bc2a697dba36dd1b3f22e009e61db8f9a4ea6b 100644 --- a/frame/example-offchain-worker/Cargo.toml +++ b/frame/example-offchain-worker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-example-offchain-worker" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -12,14 +12,14 @@ description = "FRAME example pallet for offchain worker" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } lite-json = { version = "0.1", default-features = false } [features] diff --git a/frame/example-offchain-worker/README.md b/frame/example-offchain-worker/README.md new file mode 100644 index 0000000000000000000000000000000000000000..51ddaa3a9ec73295ea8873eb4580e8ffa96952e6 --- /dev/null +++ b/frame/example-offchain-worker/README.md @@ -0,0 +1,26 @@ +# Offchain Worker Example Module + +The Offchain Worker Example: A simple pallet demonstrating +concepts, APIs and structures common to most offchain workers. + +Run `cargo doc --package pallet-example-offchain-worker --open` to view this module's +documentation. + +- [`pallet_example_offchain_worker::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) +- [`Module`](./struct.Module.html) + + +## Overview + +In this example we are going to build a very simplistic, naive and definitely NOT +production-ready oracle for BTC/USD price. +Offchain Worker (OCW) will be triggered after every block, fetch the current price +and prepare either signed or unsigned transaction to feed the result back on chain. +The on-chain logic will simply aggregate the results and store last `64` values to compute +the average price. +Additional logic in OCW is put in place to prevent spamming the network with both signed +and unsigned transactions, and custom `UnsignedValidator` makes sure that there is only +one unsigned transaction floating in the network. + +License: Unlicense \ No newline at end of file diff --git a/frame/example-offchain-worker/src/lib.rs b/frame/example-offchain-worker/src/lib.rs index c3a269e46da300bbd44a0ee0c209543e36cad373..f6a4a68e3cb3deb0be54913f78209cb6f3f6ae55 100644 --- a/frame/example-offchain-worker/src/lib.rs +++ b/frame/example-offchain-worker/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Offchain Worker Example Module //! @@ -164,7 +165,8 @@ decl_storage! { decl_event!( /// Events generated by the module. pub enum Event where AccountId = ::AccountId { - /// Event generated when new price is accepted to contribute to the average. + /// Event generated when new price is accepted to contribute to the average. + /// [price, who] NewPrice(u32, AccountId), } ); diff --git a/frame/example-offchain-worker/src/tests.rs b/frame/example-offchain-worker/src/tests.rs index ad0ae01d10ea768bb4be9bcc5a48c6762b868110..4e7e4def2ba6852d8ec64ede669c3cfbd8b1f705 100644 --- a/frame/example-offchain-worker/src/tests.rs +++ b/frame/example-offchain-worker/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use crate::*; @@ -38,7 +39,7 @@ use sp_runtime::{ }; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } // For testing the module, we construct most of a mock runtime. This means @@ -53,6 +54,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Call = (); type Index = u64; @@ -68,6 +70,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -75,6 +78,7 @@ impl frame_system::Trait for Test { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } type Extrinsic = TestXt, ()>; @@ -151,6 +155,52 @@ fn should_make_http_call_and_parse_result() { }); } +#[test] +fn knows_how_to_mock_several_http_calls() { + let (offchain, state) = testing::TestOffchainExt::new(); + let mut t = sp_io::TestExternalities::default(); + t.register_extension(OffchainExt::new(offchain)); + + { + let mut state = state.write(); + state.expect_request(testing::PendingRequest { + method: "GET".into(), + uri: "https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD".into(), + response: Some(br#"{"USD": 1}"#.to_vec()), + sent: true, + ..Default::default() + }); + + state.expect_request(testing::PendingRequest { + method: "GET".into(), + uri: "https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD".into(), + response: Some(br#"{"USD": 2}"#.to_vec()), + sent: true, + ..Default::default() + }); + + state.expect_request(testing::PendingRequest { + method: "GET".into(), + uri: "https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD".into(), + response: Some(br#"{"USD": 3}"#.to_vec()), + sent: true, + ..Default::default() + }); + } + + + t.execute_with(|| { + let price1 = Example::fetch_price().unwrap(); + let price2 = Example::fetch_price().unwrap(); + let price3 = Example::fetch_price().unwrap(); + + assert_eq!(price1, 100); + assert_eq!(price2, 200); + assert_eq!(price3, 300); + }) + +} + #[test] fn should_submit_signed_transaction_on_chain() { const PHRASE: &str = "news slush supreme milk chapter athlete soap sausage put clutch what kitten"; @@ -316,7 +366,7 @@ fn should_submit_raw_unsigned_transaction_on_chain() { } fn price_oracle_response(state: &mut testing::OffchainState) { - state.expect_request(0, testing::PendingRequest { + state.expect_request(testing::PendingRequest { method: "GET".into(), uri: "https://min-api.cryptocompare.com/data/price?fsym=BTC&tsyms=USD".into(), response: Some(br#"{"USD": 155.23}"#.to_vec()), diff --git a/frame/example/Cargo.toml b/frame/example/Cargo.toml index d12b1e7c83f88c2437fa0287ceef9af9f32c5a62..29e1208419d2b7c898204ede44559e787eed8d1a 100644 --- a/frame/example/Cargo.toml +++ b/frame/example/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-example" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -13,18 +13,18 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../balances" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0-rc6", default-features = false, path = "../balances" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core", default-features = false } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core", default-features = false } [features] default = ["std"] diff --git a/frame/example/README.md b/frame/example/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8f4729a4ce4696846c16f39df5cae317af9fb893 --- /dev/null +++ b/frame/example/README.md @@ -0,0 +1,237 @@ +# Example Pallet + + +The Example: A simple example of a FRAME pallet demonstrating +concepts, APIs and structures common to most FRAME runtimes. + +Run `cargo doc --package pallet-example --open` to view this pallet's documentation. + +### Documentation Guidelines: + + + + + +### Documentation Template:
+ +Copy and paste this template from frame/example/src/lib.rs into file +`frame//src/lib.rs` of your own custom pallet and complete it. +

+// Add heading with custom pallet name
+
+\#  Pallet
+
+// Add simple description
+
+// Include the following links that shows what trait needs to be implemented to use the pallet
+// and the supported dispatchables that are documented in the Call enum.
+
+- \[`::Trait`](./trait.Trait.html)
+- \[`Call`](./enum.Call.html)
+- \[`Module`](./struct.Module.html)
+
+\## Overview
+
+
+// Short description of pallet's purpose.
+// Links to Traits that should be implemented.
+// What this pallet is for.
+// What functionality the pallet provides.
+// When to use the pallet (use case examples).
+// How it is used.
+// Inputs it uses and the source of each input.
+// Outputs it produces.
+
+
+
+
+\## Terminology
+
+// Add terminology used in the custom pallet. Include concepts, storage items, or actions that you think
+// deserve to be noted to give context to the rest of the documentation or pallet usage. The author needs to
+// use some judgment about what is included. We don't want a list of every storage item nor types - the user
+// can go to the code for that. For example, "transfer fee" is obvious and should not be included, but
+// "free balance" and "reserved balance" should be noted to give context to the pallet.
+// Please do not link to outside resources. The reference docs should be the ultimate source of truth.
+
+
+
+\## Goals
+
+// Add goals that the custom pallet is designed to achieve.
+
+
+
+\### Scenarios
+
+
+
+\#### 
+
+// Describe requirements prior to interacting with the custom pallet.
+// Describe the process of interacting with the custom pallet for this scenario and public API functions used.
+
+\## Interface
+
+\### Supported Origins
+
+// What origins are used and supported in this pallet (root, signed, none)
+// i.e. root when \`ensure_root\` used
+// i.e. none when \`ensure_none\` used
+// i.e. signed when \`ensure_signed\` used
+
+\`inherent\` 
+
+
+
+
+\### Types
+
+// Type aliases. Include any associated types and where the user would typically define them.
+
+\`ExampleType\` 
+
+
+
+// Reference documentation of aspects such as `storageItems` and `dispatchable` functions should only be
+// included in the https://docs.rs Rustdocs for Substrate and not repeated in the README file.
+
+\### Dispatchable Functions
+
+
+
+// A brief description of dispatchable functions and a link to the rustdoc with their actual documentation.
+
+// MUST have link to Call enum
+// MUST have origin information included in function doc
+// CAN have more info up to the user
+
+\### Public Functions
+
+
+
+// A link to the rustdoc and any notes about usage in the pallet, not for specific functions.
+// For example, in the Balances Pallet: "Note that when using the publicly exposed functions,
+// you (the runtime developer) are responsible for implementing any necessary checks
+// (e.g. that the sender is the signer) before calling a function that will affect storage."
+
+
+
+// It is up to the writer of the respective pallet (with respect to how much information to provide).
+
+\#### Public Inspection functions - Immutable (getters)
+
+// Insert a subheading for each getter function signature
+
+\##### \`example_getter_name()\`
+
+// What it returns
+// Why, when, and how often to call it
+// When it could panic or error
+// When safety issues to consider
+
+\#### Public Mutable functions (changing state)
+
+// Insert a subheading for each setter function signature
+
+\##### \`example_setter_name(origin, parameter_name: T::ExampleType)\`
+
+// What state it changes
+// Why, when, and how often to call it
+// When it could panic or error
+// When safety issues to consider
+// What parameter values are valid and why
+
+\### Storage Items
+
+// Explain any storage items included in this pallet
+
+\### Digest Items
+
+// Explain any digest items included in this pallet
+
+\### Inherent Data
+
+// Explain what inherent data (if any) is defined in the pallet and any other related types
+
+\### Events:
+
+// Insert events for this pallet if any
+
+\### Errors:
+
+// Explain what generates errors
+
+\## Usage
+
+// Insert 2-3 examples of usage and code snippets that show how to
+// use  Pallet in a custom pallet.
+
+\### Prerequisites
+
+// Show how to include necessary imports for  and derive
+// your pallet configuration trait with the `INSERT_CUSTOM_PALLET_NAME` trait.
+
+\```rust
+use ;
+
+pub trait Trait: ::Trait { }
+\```
+
+\### Simple Code Snippet
+
+// Show a simple example (e.g. how to query a public getter function of )
+
+\### Example from FRAME
+
+// Show a usage example in an actual runtime
+
+// See:
+// - Substrate TCR https://github.com/parity-samples/substrate-tcr
+// - Substrate Kitties https://shawntabrizi.github.io/substrate-collectables-workshop/#/
+
+\## Genesis Config
+
+
+
+\## Dependencies
+
+// Dependencies on other FRAME pallets and the genesis config should be mentioned,
+// but not the Rust Standard Library.
+// Genesis configuration modifications that may be made to incorporate this pallet
+// Interaction with other pallets
+
+
+
+\## Related Pallets
+
+// Interaction with other pallets in the form of a bullet point list
+
+\## References
+
+
+
+// Links to reference material, if applicable. For example, Phragmen, W3F research, etc.
+// that the implementation is based on.
+

+ +License: Unlicense \ No newline at end of file diff --git a/frame/example/src/lib.rs b/frame/example/src/lib.rs index 78ff803d37aaf5a52b21b6adc9f1a6c7aefb1dea..b41c8196c018fd5b3c7cccb8a441d3b99c0ec897 100644 --- a/frame/example/src/lib.rs +++ b/frame/example/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! # Example Pallet //! @@ -255,11 +256,11 @@ use sp_std::marker::PhantomData; use frame_support::{ - dispatch::DispatchResult, decl_module, decl_storage, decl_event, + dispatch::{DispatchResult, IsSubType}, decl_module, decl_storage, decl_event, weights::{DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, Pays}, }; use sp_std::prelude::*; -use frame_system::{self as system, ensure_signed, ensure_root}; +use frame_system::{ensure_signed, ensure_root}; use codec::{Encode, Decode}; use sp_runtime::{ traits::{ @@ -608,14 +609,13 @@ impl sp_std::fmt::Debug for WatchDummy { } } -impl SignedExtension for WatchDummy { +impl SignedExtension for WatchDummy +where + ::Call: IsSubType>, +{ const IDENTIFIER: &'static str = "WatchDummy"; type AccountId = T::AccountId; - // Note that this could also be assigned to the top-level call enum. It is passed into the - // Balances Pallet directly and since `Trait: pallet_balances::Trait`, you could also use `T::Call`. - // In that case, you would have had access to all call variants and could match on variants from - // other pallets. - type Call = Call; + type Call = ::Call; type AdditionalSigned = (); type Pre = (); @@ -634,8 +634,8 @@ impl SignedExtension for WatchDummy { } // check for `set_dummy` - match call { - Call::set_dummy(..) => { + match call.is_sub_type() { + Some(Call::set_dummy(..)) => { sp_runtime::print("set_dummy was received."); let mut valid_tx = ValidTransaction::default(); @@ -710,8 +710,8 @@ mod tests { use super::*; use frame_support::{ - assert_ok, impl_outer_origin, parameter_types, weights::{DispatchInfo, GetDispatchInfo}, - traits::{OnInitialize, OnFinalize} + assert_ok, impl_outer_origin, parameter_types, impl_outer_dispatch, + weights::{DispatchInfo, GetDispatchInfo}, traits::{OnInitialize, OnFinalize} }; use sp_core::H256; // The testing primitives are very useful for avoiding having to work with signatures @@ -723,7 +723,13 @@ mod tests { }; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} + } + + impl_outer_dispatch! { + pub enum OuterCall for Test where origin: Origin { + self::Example, + } } // For testing the pallet, we construct most of a mock runtime. This means @@ -738,11 +744,12 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; type Hash = H256; - type Call = (); + type Call = OuterCall; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; @@ -753,6 +760,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -760,6 +768,7 @@ mod tests { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; @@ -770,6 +779,7 @@ mod tests { type Event = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } impl Trait for Test { type Event = (); @@ -825,7 +835,7 @@ mod tests { #[test] fn signed_ext_watch_dummy_works() { new_test_ext().execute_with(|| { - let call = >::set_dummy(10); + let call = >::set_dummy(10).into(); let info = DispatchInfo::default(); assert_eq!( diff --git a/frame/executive/Cargo.toml b/frame/executive/Cargo.toml index 3e0e1c938a89ab01d44d6beb7e4575e450fc8b14..8114f74b8fe67bdf106184a870c02b0e26c9f409 100644 --- a/frame/executive/Cargo.toml +++ b/frame/executive/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-executive" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME executives engine" @@ -12,23 +12,23 @@ description = "FRAME executives engine" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-tracing = { version = "2.0.0-dev", default-features = false, path = "../../primitives/tracing" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-tracing = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/tracing" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } [dev-dependencies] -hex-literal = "0.2.1" -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-io ={ path = "../../primitives/io", version = "2.0.0-dev"} -pallet-indices = { version = "2.0.0-dev", path = "../indices" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } -pallet-transaction-payment = { version = "2.0.0-dev", path = "../transaction-payment" } -sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } +hex-literal = "0.3.1" +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-rc6", path = "../../primitives/io" } +pallet-indices = { version = "2.0.0-rc6", path = "../indices" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +pallet-transaction-payment = { version = "2.0.0-rc6", path = "../transaction-payment" } +sp-version = { version = "2.0.0-rc6", path = "../../primitives/version" } [features] default = ["std"] diff --git a/frame/executive/README.md b/frame/executive/README.md new file mode 100644 index 0000000000000000000000000000000000000000..017aa5d0444312db4ffe49a191f7ab53092cce0b --- /dev/null +++ b/frame/executive/README.md @@ -0,0 +1,61 @@ +# Executive Module + +The Executive module acts as the orchestration layer for the runtime. It dispatches incoming +extrinsic calls to the respective modules in the runtime. + +## Overview + +The executive module is not a typical pallet providing functionality around a specific feature. +It is a cross-cutting framework component for the FRAME. It works in conjunction with the +[FRAME System module](../frame_system/index.html) to perform these cross-cutting functions. + +The Executive module provides functions to: + +- Check transaction validity. +- Initialize a block. +- Apply extrinsics. +- Execute a block. +- Finalize a block. +- Start an off-chain worker. + +### Implementations + +The Executive module provides the following implementations: + +- `ExecuteBlock`: Trait that can be used to execute a block. +- `Executive`: Type that can be used to make the FRAME available from the runtime. + +## Usage + +The default Substrate node template declares the [`Executive`](./struct.Executive.html) type in its library. + +### Example + +`Executive` type declaration from the node template. + +```rust +# +/// Executive: handles dispatch to the various modules. +pub type Executive = executive::Executive; +``` + +### Custom `OnRuntimeUpgrade` logic + +You can add custom logic that should be called in your runtime on a runtime upgrade. This is +done by setting an optional generic parameter. The custom logic will be called before +the on runtime upgrade logic of all modules is called. + +```rust +# +struct CustomOnRuntimeUpgrade; +impl frame_support::traits::OnRuntimeUpgrade for CustomOnRuntimeUpgrade { + fn on_runtime_upgrade() -> frame_support::weights::Weight { + // Do whatever you want. + 0 + } +} + +pub type Executive = executive::Executive; +``` + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 9c46d86d744298a5d9a913cfce1dfcc01fc5951a..24dccf8b0b4a41f97e996e2e005d65051ff9a782 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Executive Module //! @@ -118,6 +119,7 @@ use sp_std::{prelude::*, marker::PhantomData}; use frame_support::{ storage::StorageValue, weights::{GetDispatchInfo, DispatchInfo, DispatchClass}, traits::{OnInitialize, OnFinalize, OnRuntimeUpgrade, OffchainWorker}, + dispatch::PostDispatchInfo, }; use sp_runtime::{ generic::Digest, ApplyExtrinsicResult, @@ -173,7 +175,7 @@ where CheckedOf: Applyable + GetDispatchInfo, - CallOf: Dispatchable, + CallOf: Dispatchable, OriginOf: From>, UnsignedValidator: ValidateUnsigned>, { @@ -199,7 +201,7 @@ where CheckedOf: Applyable + GetDispatchInfo, - CallOf: Dispatchable, + CallOf: Dispatchable, OriginOf: From>, UnsignedValidator: ValidateUnsigned>, { @@ -291,11 +293,13 @@ where // any initial checks Self::initial_checks(&block); - let batching_safeguard = sp_runtime::SignatureBatching::start(); + let signature_batching = sp_runtime::SignatureBatching::start(); + // execute extrinsics let (header, extrinsics) = block.deconstruct(); Self::execute_extrinsics_with_book_keeping(extrinsics, *header.number()); - if !sp_runtime::SignatureBatching::verify(batching_safeguard) { + + if !signature_batching.verify() { panic!("Signature verification failed."); } @@ -367,9 +371,9 @@ where let dispatch_info = xt.get_dispatch_info(); let r = Applyable::apply::(xt, &dispatch_info, encoded_len)?; - >::note_applied_extrinsic(&r, encoded_len as u32, dispatch_info); + >::note_applied_extrinsic(&r, dispatch_info); - Ok(r) + Ok(r.map(|_| ()).map_err(|e| e.error)) } fn final_checks(header: &System::Header) { @@ -452,12 +456,12 @@ mod tests { use sp_core::H256; use sp_runtime::{ generic::Era, Perbill, DispatchError, testing::{Digest, Header, Block}, - traits::{Header as HeaderT, BlakeTwo256, IdentityLookup, Convert, ConvertInto}, + traits::{Header as HeaderT, BlakeTwo256, IdentityLookup}, transaction_validity::{InvalidTransaction, UnknownTransaction, TransactionValidityError}, }; use frame_support::{ impl_outer_event, impl_outer_origin, parameter_types, impl_outer_dispatch, - weights::{Weight, RuntimeDbWeight}, + weights::{Weight, RuntimeDbWeight, IdentityFee, WeightToFeePolynomial}, traits::{Currency, LockIdentifier, LockableCurrency, WithdrawReasons, WithdrawReason}, }; use frame_system::{self as system, Call as SystemCall, ChainContext, LastRuntimeUpgradeInfo}; @@ -543,6 +547,7 @@ mod tests { }; } impl frame_system::Trait for Runtime { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type Call = Call; @@ -558,6 +563,7 @@ mod tests { type DbWeight = DbWeight; type BlockExecutionWeight = BlockExecutionWeight; type ExtrinsicBaseWeight = ExtrinsicBaseWeight; + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = RuntimeVersion; @@ -565,6 +571,7 @@ mod tests { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } type Balance = u64; @@ -577,6 +584,7 @@ mod tests { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { @@ -586,7 +594,7 @@ mod tests { type Currency = Balances; type OnTransactionPayment = (); type TransactionByteFee = TransactionByteFee; - type WeightToFee = ConvertInto; + type WeightToFee = IdentityFee; type FeeMultiplierUpdate = (); } impl custom::Trait for Runtime {} @@ -672,7 +680,8 @@ mod tests { }.assimilate_storage(&mut t).unwrap(); let xt = TestXt::new(Call::Balances(BalancesCall::transfer(2, 69)), sign_extra(1, 0, 0)); let weight = xt.get_dispatch_info().weight + ::ExtrinsicBaseWeight::get(); - let fee: Balance = ::WeightToFee::convert(weight); + let fee: Balance + = ::WeightToFee::calc(&weight); let mut t = sp_io::TestExternalities::new(t); t.execute_with(|| { Executive::initialize_block(&Header::new( @@ -704,7 +713,7 @@ mod tests { header: Header { parent_hash: [69u8; 32].into(), number: 1, - state_root: hex!("409fb5a14aeb8b8c59258b503396a56dee45a0ee28a78de3e622db957425e275").into(), + state_root: hex!("e8ff7b3dd4375f6f3a76e24a1999e2a7be2d15b353e49ac94ace1eae3e80eb87").into(), extrinsics_root: hex!("03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314").into(), digest: Digest { logs: vec![], }, }, @@ -785,7 +794,7 @@ mod tests { Digest::default(), )); // Base block execution weight + `on_initialize` weight from the custom module. - assert_eq!(>::all_extrinsics_weight().total(), base_block_weight); + assert_eq!(>::block_weight().total(), base_block_weight); for nonce in 0..=num_to_exhaust_block { let xt = TestXt::new( @@ -795,7 +804,7 @@ mod tests { if nonce != num_to_exhaust_block { assert!(res.is_ok()); assert_eq!( - >::all_extrinsics_weight().total(), + >::block_weight().total(), //--------------------- on_initialize + block_execution + extrinsic_base weight (encoded_len + 5) * (nonce + 1) + base_block_weight, ); @@ -815,7 +824,18 @@ mod tests { let len = xt.clone().encode().len() as u32; let mut t = new_test_ext(1); t.execute_with(|| { - assert_eq!(>::all_extrinsics_weight().total(), 0); + // Block execution weight + on_initialize weight from custom module + let base_block_weight = 175 + ::BlockExecutionWeight::get(); + + Executive::initialize_block(&Header::new( + 1, + H256::default(), + H256::default(), + [69u8; 32].into(), + Digest::default(), + )); + + assert_eq!(>::block_weight().total(), base_block_weight); assert_eq!(>::all_extrinsics_len(), 0); assert!(Executive::apply_extrinsic(xt.clone()).unwrap().is_ok()); @@ -823,16 +843,28 @@ mod tests { assert!(Executive::apply_extrinsic(x2.clone()).unwrap().is_ok()); // default weight for `TestXt` == encoded length. + let extrinsic_weight = len as Weight + ::ExtrinsicBaseWeight::get(); assert_eq!( - >::all_extrinsics_weight().total(), - 3 * (len as Weight + ::ExtrinsicBaseWeight::get()), + >::block_weight().total(), + base_block_weight + 3 * extrinsic_weight, ); assert_eq!(>::all_extrinsics_len(), 3 * len); let _ = >::finalize(); - - assert_eq!(>::all_extrinsics_weight().total(), 0); + // All extrinsics length cleaned on `System::finalize` assert_eq!(>::all_extrinsics_len(), 0); + + // New Block + Executive::initialize_block(&Header::new( + 2, + H256::default(), + H256::default(), + [69u8; 32].into(), + Digest::default(), + )); + + // Block weight cleaned up on `System::initialize` + assert_eq!(>::block_weight().total(), base_block_weight); }); } @@ -868,7 +900,8 @@ mod tests { ); let weight = xt.get_dispatch_info().weight + ::ExtrinsicBaseWeight::get(); - let fee: Balance = ::WeightToFee::convert(weight); + let fee: Balance = + ::WeightToFee::calc(&weight); Executive::initialize_block(&Header::new( 1, H256::default(), @@ -903,7 +936,7 @@ mod tests { // NOTE: might need updates over time if new weights are introduced. // For now it only accounts for the base block execution weight and // the `on_initialize` weight defined in the custom test module. - assert_eq!(>::all_extrinsics_weight().total(), 175 + 10); + assert_eq!(>::block_weight().total(), 175 + 10); }) } diff --git a/frame/finality-tracker/Cargo.toml b/frame/finality-tracker/Cargo.toml index 1b11fbea5ad585a1a34bfa08c22b31d9c8729869..2f3d504879eb208be1b90f7ed11c37b399651f19 100644 --- a/frame/finality-tracker/Cargo.toml +++ b/frame/finality-tracker/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-finality-tracker" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME Pallet that tracks the last finalized block, as perceived by block authors." @@ -15,18 +15,18 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-finality-tracker = { version = "2.0.0-dev", default-features = false, path = "../../primitives/finality-tracker" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-finality-tracker = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/finality-tracker" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/finality-tracker/README.md b/frame/finality-tracker/README.md new file mode 100644 index 0000000000000000000000000000000000000000..bf42605ffc6f99029e015d40b98d6bada2ab40f8 --- /dev/null +++ b/frame/finality-tracker/README.md @@ -0,0 +1,3 @@ +FRAME Pallet that tracks the last finalized block, as perceived by block authors. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/finality-tracker/src/lib.rs b/frame/finality-tracker/src/lib.rs index ac306e268998ff925248ff21bc4c72960330ba0a..58f16d72766ebbfe2faf018a7470859c4686c7d0 100644 --- a/frame/finality-tracker/src/lib.rs +++ b/frame/finality-tracker/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! FRAME Pallet that tracks the last finalized block, as perceived by block authors. @@ -208,8 +209,9 @@ mod tests { use sp_io::TestExternalities; use sp_core::H256; use sp_runtime::{ - testing::Header, Perbill, - traits::{BlakeTwo256, IdentityLookup, Header as HeaderT}, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + Perbill, }; use frame_support::{ assert_ok, impl_outer_origin, parameter_types, @@ -229,7 +231,7 @@ mod tests { pub struct Test; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } thread_local! { @@ -251,6 +253,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -266,6 +269,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -273,6 +277,7 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { pub const WindowSize: u64 = 11; @@ -335,10 +340,7 @@ mod tests { &Default::default(), Default::default(), ); - assert_ok!(FinalityTracker::dispatch( - Call::final_hint(i-1), - Origin::NONE, - )); + assert_ok!(FinalityTracker::final_hint(Origin::none(), i - 1)); FinalityTracker::on_finalize(i); let hdr = System::finalize(); parent_hash = hdr.hash(); diff --git a/frame/generic-asset/Cargo.toml b/frame/generic-asset/Cargo.toml index c19a7884b3eadb802d25f73fbb4f46ccf90e601c..9dfc76991589d2f8be3f76926752d04fa8a9489e 100644 --- a/frame/generic-asset/Cargo.toml +++ b/frame/generic-asset/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-generic-asset" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Centrality Developers "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for generic asset management" @@ -13,15 +13,15 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -sp-io ={ version = "2.0.0-dev", path = "../../primitives/io" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-rc6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/generic-asset/README.md b/frame/generic-asset/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ab82be54b208031dae0e3c78d1638cf807bf2721 --- /dev/null +++ b/frame/generic-asset/README.md @@ -0,0 +1,131 @@ +# Generic Asset Module + +The Generic Asset module provides functionality for handling accounts and asset balances. + +## Overview + +The Generic Asset module provides functions for: + +- Creating a new kind of asset. +- Setting permissions of an asset. +- Getting and setting free balances. +- Retrieving total, reserved and unreserved balances. +- Repatriating a reserved balance to a beneficiary account. +- Transferring a balance between accounts (when not reserved). +- Slashing an account balance. +- Managing total issuance. +- Setting and managing locks. + +### Terminology + +- **Staking Asset:** The asset for staking, to participate as Validators in the network. +- **Spending Asset:** The asset for payment, such as paying transfer fees, gas fees, etc. +- **Permissions:** A set of rules for a kind of asset, defining the allowed operations to the asset, and which +accounts are allowed to possess it. +- **Total Issuance:** The total number of units in existence in a system. +- **Free Balance:** The portion of a balance that is not reserved. The free balance is the only balance that matters +for most operations. When this balance falls below the existential deposit, most functionality of the account is +removed. When both it and the reserved balance are deleted, then the account is said to be dead. +- **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. Reserved balance +can still be slashed, but only after all the free balance has been slashed. If the reserved balance falls below the +existential deposit then it and any related functionality will be deleted. When both it and the free balance are +deleted, then the account is said to be dead. +- **Imbalance:** A condition when some assets were credited or debited without equal and opposite accounting +(i.e. a difference between total issuance and account balances). Functions that result in an imbalance will +return an object of the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is +simply dropped, it should automatically maintain any book-keeping such as total issuance.) +- **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple +locks always operate over the same funds, so they "overlay" rather than "stack". + +### Implementations + +The Generic Asset module provides `AssetCurrency`, which implements the following traits. If these traits provide +the functionality that you need, you can avoid coupling with the Generic Asset module. + +- `Currency`: Functions for dealing with a fungible assets system. +- `ReservableCurrency`: Functions for dealing with assets that can be reserved from an account. +- `LockableCurrency`: Functions for dealing with accounts that allow liquidity restrictions. +- `Imbalance`: Functions for handling imbalances between total issuance in the system and account balances. +Must be used when a function creates new assets (e.g. a reward) or destroys some assets (e.g. a system fee). + +The Generic Asset module provides two types of `AssetCurrency` as follows. + +- `StakingAssetCurrency`: Currency for staking. +- `SpendingAssetCurrency`: Currency for payments such as transfer fee, gas fee. + +## Interface + +### Dispatchable Functions + +- `create`: Create a new kind of asset. +- `transfer`: Transfer some liquid free balance to another account. +- `update_permission`: Updates permission for a given `asset_id` and an account. The origin of this call +must have update permissions. +- `mint`: Mint an asset, increases its total issuance. The origin of this call must have mint permissions. +- `burn`: Burn an asset, decreases its total issuance. The origin of this call must have burn permissions. +- `create_reserved`: Create a new kind of reserved asset. The origin of this call must be root. + +### Public Functions + +- `total_balance`: Get an account's total balance of an asset kind. +- `free_balance`: Get an account's free balance of an asset kind. +- `reserved_balance`: Get an account's reserved balance of an asset kind. +- `create_asset`: Creates an asset. +- `make_transfer`: Transfer some liquid free balance from one account to another. +This will not emit the `Transferred` event. +- `make_transfer_with_event`: Transfer some liquid free balance from one account to another. +This will emit the `Transferred` event. +- `reserve`: Moves an amount from free balance to reserved balance. +- `unreserve`: Move up to an amount from reserved balance to free balance. This function cannot fail. +- `mint_free`: Mint to an account's free balance. +- `burn_free`: Burn an account's free balance. +- `slash`: Deduct up to an amount from the combined balance of `who`, preferring to deduct from the + free balance. This function cannot fail. +- `slash_reserved`: Deduct up to an amount from reserved balance of an account. This function cannot fail. +- `repatriate_reserved`: Move up to an amount from reserved balance of an account to free balance of another +account. +- `check_permission`: Check permission to perform burn, mint or update. +- `ensure_can_withdraw`: Check if the account is able to make a withdrawal of the given amount + for the given reason. + +### Usage + +The following examples show how to use the Generic Asset Pallet in your custom pallet. + +### Examples from the FRAME pallet + +The Fees Pallet uses the `Currency` trait to handle fee charge/refund, and its types inherit from `Currency`: + +```rust +use frame_support::{ + dispatch, + traits::{Currency, ExistenceRequirement, WithdrawReason}, +}; +type AssetOf = <::Currency as Currency<::AccountId>>::Balance; + +fn charge_fee(transactor: &T::AccountId, amount: AssetOf) -> dispatch::DispatchResult { + // ... + T::Currency::withdraw( + transactor, + amount, + WithdrawReason::TransactionPayment.into(), + ExistenceRequirement::KeepAlive, + )?; + // ... + Ok(()) +} + +fn refund_fee(transactor: &T::AccountId, amount: AssetOf) -> dispatch::DispatchResult { + // ... + T::Currency::deposit_into_existing(transactor, amount)?; + // ... + Ok(()) +} + +``` + +## Genesis config + +The Generic Asset Pallet depends on the [`GenesisConfig`](./struct.GenesisConfig.html). + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/generic-asset/src/lib.rs b/frame/generic-asset/src/lib.rs index f2507669e537866bc58a54eb1451c4d4ddbc185c..881d89439ec7b15d84d4c91d537ca571c36ca618 100644 --- a/frame/generic-asset/src/lib.rs +++ b/frame/generic-asset/src/lib.rs @@ -157,7 +157,7 @@ use codec::{Decode, Encode, HasCompact, Input, Output, Error as CodecError}; use sp_runtime::{RuntimeDebug, DispatchResult, DispatchError}; use sp_runtime::traits::{ CheckedAdd, CheckedSub, MaybeSerializeDeserialize, Member, One, Saturating, AtLeast32Bit, - Zero, Bounded, + Zero, Bounded, AtLeast32BitUnsigned }; use sp_std::prelude::*; @@ -165,12 +165,13 @@ use sp_std::{cmp, result, fmt::Debug}; use frame_support::{ decl_event, decl_module, decl_storage, ensure, decl_error, traits::{ - Currency, ExistenceRequirement, Imbalance, LockIdentifier, LockableCurrency, ReservableCurrency, - SignedImbalance, WithdrawReason, WithdrawReasons, TryDrop, BalanceStatus, + Currency, ExistenceRequirement, Imbalance, LockIdentifier, LockableCurrency, + ReservableCurrency, SignedImbalance, WithdrawReason, WithdrawReasons, TryDrop, + BalanceStatus, }, Parameter, StorageMap, }; -use frame_system::{self as system, ensure_signed, ensure_root}; +use frame_system::{ensure_signed, ensure_root}; mod mock; mod tests; @@ -178,25 +179,15 @@ mod tests; pub use self::imbalances::{NegativeImbalance, PositiveImbalance}; pub trait Trait: frame_system::Trait { - type Balance: Parameter - + Member - + AtLeast32Bit - + Default - + Copy - + MaybeSerializeDeserialize - + Debug; + type Balance: Parameter + Member + AtLeast32BitUnsigned + Default + Copy + Debug + + MaybeSerializeDeserialize; type AssetId: Parameter + Member + AtLeast32Bit + Default + Copy; type Event: From> + Into<::Event>; } pub trait Subtrait: frame_system::Trait { - type Balance: Parameter - + Member - + AtLeast32Bit - + Default - + Copy - + MaybeSerializeDeserialize - + Debug; + type Balance: Parameter + Member + AtLeast32BitUnsigned + Default + Copy + Debug + + MaybeSerializeDeserialize; type AssetId: Parameter + Member + AtLeast32Bit + Default + Copy; } @@ -442,16 +433,22 @@ pub struct BalanceLock { decl_storage! { trait Store for Module as GenericAsset { /// Total issuance of a given asset. + /// + /// TWOX-NOTE: `AssetId` is trusted. pub TotalIssuance get(fn total_issuance) build(|config: &GenesisConfig| { let issuance = config.initial_balance * (config.endowed_accounts.len() as u32).into(); config.assets.iter().map(|id| (id.clone(), issuance)).collect::>() }): map hasher(twox_64_concat) T::AssetId => T::Balance; /// The free balance of a given asset under an account. + /// + /// TWOX-NOTE: `AssetId` is trusted. pub FreeBalance: double_map hasher(twox_64_concat) T::AssetId, hasher(blake2_128_concat) T::AccountId => T::Balance; /// The reserved balance of a given asset under an account. + /// + /// TWOX-NOTE: `AssetId` is trusted. pub ReservedBalance: double_map hasher(twox_64_concat) T::AssetId, hasher(blake2_128_concat) T::AccountId => T::Balance; @@ -459,6 +456,8 @@ decl_storage! { pub NextAssetId get(fn next_asset_id) config(): T::AssetId; /// Permission options for a given asset. + /// + /// TWOX-NOTE: `AssetId` is trusted. pub Permissions get(fn get_permission): map hasher(twox_64_concat) T::AssetId => PermissionVersions; @@ -494,15 +493,15 @@ decl_event!( ::AssetId, AssetOptions = AssetOptions<::Balance, ::AccountId> { - /// Asset created (asset_id, creator, asset_options). + /// Asset created. [asset_id, creator, asset_options] Created(AssetId, AccountId, AssetOptions), - /// Asset transfer succeeded (asset_id, from, to, amount). + /// Asset transfer succeeded. [asset_id, from, to, amount] Transferred(AssetId, AccountId, AccountId, Balance), - /// Asset permission updated (asset_id, new_permissions). + /// Asset permission updated. [asset_id, new_permissions] PermissionUpdated(AssetId, PermissionLatest), - /// New asset minted (asset_id, account, amount). + /// New asset minted. [asset_id, account, amount] Minted(AssetId, AccountId, Balance), - /// Asset burned (asset_id, account, amount). + /// Asset burned. [asset_id, account, amount] Burned(AssetId, AccountId, Balance), } ); @@ -1112,6 +1111,7 @@ impl PartialEq for ElevatedTrait { } impl Eq for ElevatedTrait {} impl frame_system::Trait for ElevatedTrait { + type BaseCallFilter = T::BaseCallFilter; type Origin = T::Origin; type Call = T::Call; type Index = T::Index; @@ -1127,6 +1127,7 @@ impl frame_system::Trait for ElevatedTrait { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = T::MaximumBlockWeight; type MaximumBlockLength = T::MaximumBlockLength; type AvailableBlockRatio = T::AvailableBlockRatio; type Version = T::Version; @@ -1134,6 +1135,7 @@ impl frame_system::Trait for ElevatedTrait { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl Trait for ElevatedTrait { type Balance = T::Balance; diff --git a/frame/generic-asset/src/mock.rs b/frame/generic-asset/src/mock.rs index 3e3bd892d56880f2a3d512e1120cf71590f513c0..8c0a06a1564df1840a7a47f8ca5d9e59d874f0a5 100644 --- a/frame/generic-asset/src/mock.rs +++ b/frame/generic-asset/src/mock.rs @@ -34,9 +34,6 @@ impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } -// For testing the pallet, we construct most of a mock runtime. This means -// first constructing a configuration type (`Test`) which `impl`s each of the -// configuration traits of pallets we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -46,6 +43,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -60,6 +58,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type BlockHashCount = BlockHashCount; @@ -68,6 +67,7 @@ impl frame_system::Trait for Test { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl Trait for Test { @@ -144,8 +144,6 @@ impl ExtBuilder { } } -// This function basically just builds a genesis storage key/value store according to -// our desired mockup. pub fn new_test_ext() -> sp_io::TestExternalities { frame_system::GenesisConfig::default() .build_storage::() diff --git a/frame/generic-asset/src/tests.rs b/frame/generic-asset/src/tests.rs index d5c0a877dfe75aba4236a2130372a80b06f74a6c..a094f69ba1fc581f0138574e06c202c404050cd6 100644 --- a/frame/generic-asset/src/tests.rs +++ b/frame/generic-asset/src/tests.rs @@ -598,7 +598,7 @@ fn create_reserved_should_create_a_default_account_with_the_balance_given() { let created_asset_id = 9; let created_account_id = 0; - assert_ok!(GenericAsset::create_reserved(Origin::ROOT, created_asset_id, options)); + assert_ok!(GenericAsset::create_reserved(Origin::root(), created_asset_id, options)); // Tests for side effects. assert_eq!(>::get(created_asset_id), expected_total_issuance); diff --git a/frame/grandpa/Cargo.toml b/frame/grandpa/Cargo.toml index 04547acaf1d6eb7dab4dd41f7d724b83d65c5164..fcfa15813dc03ad2f7041294e1a9d980efc72ac1 100644 --- a/frame/grandpa/Cargo.toml +++ b/frame/grandpa/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-grandpa" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for GRANDPA finality gadget" @@ -13,34 +13,38 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-finality-grandpa = { version = "2.0.0-dev", default-features = false, path = "../../primitives/finality-grandpa" } -sp-session = { version = "2.0.0-dev", default-features = false, path = "../../primitives/session" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -pallet-session = { version = "2.0.0-dev", default-features = false, path = "../session" } -pallet-finality-tracker = { version = "2.0.0-dev", default-features = false, path = "../finality-tracker" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/application-crypto" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-finality-grandpa = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/finality-grandpa" } +sp-session = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/session" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/staking" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +pallet-authorship = { version = "2.0.0-rc6", default-features = false, path = "../authorship" } +pallet-session = { version = "2.0.0-rc6", default-features = false, path = "../session" } +pallet-finality-tracker = { version = "2.0.0-rc6", default-features = false, path = "../finality-tracker" } [dev-dependencies] +frame-benchmarking = { version = "2.0.0-rc6", path = "../benchmarking" } grandpa = { package = "finality-grandpa", version = "0.12.3", features = ["derive-codec"] } -sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } -sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } -pallet-offences = { version = "2.0.0-dev", path = "../offences" } -pallet-staking = { version = "2.0.0-dev", path = "../staking" } -pallet-staking-reward-curve = { version = "2.0.0-dev", path = "../staking/reward-curve" } -pallet-timestamp = { version = "2.0.0-dev", path = "../timestamp" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } +sp-keyring = { version = "2.0.0-rc6", path = "../../primitives/keyring" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +pallet-offences = { version = "2.0.0-rc6", path = "../offences" } +pallet-staking = { version = "2.0.0-rc6", path = "../staking" } +pallet-staking-reward-curve = { version = "2.0.0-rc6", path = "../staking/reward-curve" } +pallet-timestamp = { version = "2.0.0-rc6", path = "../timestamp" } [features] default = ["std"] std = [ "serde", "codec/std", + "frame-benchmarking/std", "sp-application-crypto/std", "sp-core/std", "sp-finality-grandpa/std", @@ -50,6 +54,8 @@ std = [ "sp-runtime/std", "sp-staking/std", "frame-system/std", + "pallet-authorship/std", "pallet-session/std", "pallet-finality-tracker/std", ] +runtime-benchmarks = ["frame-benchmarking"] diff --git a/frame/grandpa/README.md b/frame/grandpa/README.md new file mode 100644 index 0000000000000000000000000000000000000000..84b181a8b31e1c102215f72d6a2d59724a9af596 --- /dev/null +++ b/frame/grandpa/README.md @@ -0,0 +1,12 @@ +GRANDPA Consensus module for runtime. + +This manages the GRANDPA authority set ready for the native code. +These authorities are only for GRANDPA finality, not for consensus overall. + +In the future, it will also handle misbehavior reports, and on-chain +finality notifications. + +For full integration with GRANDPA, the `GrandpaApi` should be implemented. +The necessary items are re-exported via the `fg_primitives` crate. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/grandpa/src/benchmarking.rs b/frame/grandpa/src/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..048f99fff7a9bebf2c5e2c57309e384f7669e04b --- /dev/null +++ b/frame/grandpa/src/benchmarking.rs @@ -0,0 +1,117 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Benchmarks for the GRANDPA pallet. + +#![cfg_attr(not(feature = "std"), no_std)] + +use super::{*, Module as Grandpa}; +use frame_benchmarking::benchmarks; +use frame_system::RawOrigin; +use sp_core::H256; + +benchmarks! { + _ { } + + check_equivocation_proof { + let x in 0 .. 1; + + // NOTE: generated with the test below `test_generate_equivocation_report_blob`. + // the output should be deterministic since the keys we use are static. + // with the current benchmark setup it is not possible to generate this + // programatically from the benchmark setup. + const EQUIVOCATION_PROOF_BLOB: [u8; 257] = [ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 136, 220, 52, 23, + 213, 5, 142, 196, 180, 80, 62, 12, 18, 234, 26, 10, 137, 190, 32, + 15, 233, 137, 34, 66, 61, 67, 52, 1, 79, 166, 176, 238, 207, 48, + 195, 55, 171, 225, 252, 130, 161, 56, 151, 29, 193, 32, 25, 157, + 249, 39, 80, 193, 214, 96, 167, 147, 25, 130, 45, 42, 64, 208, 182, + 164, 10, 0, 0, 0, 0, 0, 0, 0, 234, 236, 231, 45, 70, 171, 135, 246, + 136, 153, 38, 167, 91, 134, 150, 242, 215, 83, 56, 238, 16, 119, 55, + 170, 32, 69, 255, 248, 164, 20, 57, 50, 122, 115, 135, 96, 80, 203, + 131, 232, 73, 23, 149, 86, 174, 59, 193, 92, 121, 76, 154, 211, 44, + 96, 10, 84, 159, 133, 211, 56, 103, 0, 59, 2, 96, 20, 69, 2, 32, + 179, 16, 184, 108, 76, 215, 64, 195, 78, 143, 73, 177, 139, 20, 144, + 98, 231, 41, 117, 255, 220, 115, 41, 59, 27, 75, 56, 10, 0, 0, 0, 0, + 0, 0, 0, 128, 179, 250, 48, 211, 76, 10, 70, 74, 230, 219, 139, 96, + 78, 88, 112, 33, 170, 44, 184, 59, 200, 155, 143, 128, 40, 222, 179, + 210, 190, 84, 16, 182, 21, 34, 94, 28, 193, 163, 226, 51, 251, 134, + 233, 187, 121, 63, 157, 240, 165, 203, 92, 16, 146, 120, 190, 229, + 251, 129, 29, 45, 32, 29, 6 + ]; + + let equivocation_proof1: sp_finality_grandpa::EquivocationProof = + Decode::decode(&mut &EQUIVOCATION_PROOF_BLOB[..]).unwrap(); + + let equivocation_proof2 = equivocation_proof1.clone(); + }: { + sp_finality_grandpa::check_equivocation_proof(equivocation_proof1); + } verify { + assert!(sp_finality_grandpa::check_equivocation_proof(equivocation_proof2)); + } + + note_stalled { + let delay = 1000.into(); + let best_finalized_block_number = 1.into(); + + }: _(RawOrigin::Root, delay, best_finalized_block_number) + verify { + assert!(Grandpa::::stalled().is_some()); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::*; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { + assert_ok!(test_benchmark_check_equivocation_proof::()); + assert_ok!(test_benchmark_note_stalled::()); + }) + } + + #[test] + fn test_generate_equivocation_report_blob() { + let authorities = crate::tests::test_authorities(); + + let equivocation_authority_index = 0; + let equivocation_key = &authorities[equivocation_authority_index].0; + let equivocation_keyring = extract_keyring(equivocation_key); + + new_test_ext_raw_authorities(authorities).execute_with(|| { + start_era(1); + + // generate an equivocation proof, with two votes in the same round for + // different block hashes signed by the same key + let equivocation_proof = generate_equivocation_proof( + 1, + (1, H256::random(), 10, &equivocation_keyring), + (1, H256::random(), 10, &equivocation_keyring), + ); + + println!("equivocation_proof: {:?}", equivocation_proof); + println!( + "equivocation_proof.encode(): {:?}", + equivocation_proof.encode() + ); + }); + } +} diff --git a/frame/grandpa/src/equivocation.rs b/frame/grandpa/src/equivocation.rs index 2a8c3e572217f159e6350b463678161c33ba720d..e9662a726c40e308e1e9ff0e4eb14b4d43992b9f 100644 --- a/frame/grandpa/src/equivocation.rs +++ b/frame/grandpa/src/equivocation.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! //! An opt-in utility module for reporting equivocations. @@ -23,6 +24,7 @@ //! part of a session); //! - a system for reporting offences; //! - a system for signing and submitting transactions; +//! - a way to get the current block author; //! //! These can be used in an offchain context in order to submit equivocation //! reporting extrinsics (from the client that's running the GRANDPA protocol). @@ -31,21 +33,19 @@ //! //! IMPORTANT: //! When using this module for enabling equivocation reporting it is required -//! that the `ValidateEquivocationReport` signed extension is used in the runtime -//! definition. Failure to do so will allow invalid equivocation reports to be -//! accepted by the runtime. +//! that the `ValidateUnsigned` for the GRANDPA pallet is used in the runtime +//! definition. //! use sp_std::prelude::*; use codec::{self as codec, Decode, Encode}; -use frame_support::{debug, dispatch::IsSubType, traits::KeyOwnerProofSystem}; -use frame_system::offchain::{AppCrypto, CreateSignedTransaction, Signer}; +use frame_support::{debug, traits::KeyOwnerProofSystem}; use sp_finality_grandpa::{EquivocationProof, RoundNumber, SetId}; use sp_runtime::{ - traits::{DispatchInfoOf, SignedExtension}, transaction_validity::{ - InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction, + InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity, + TransactionValidityError, ValidTransaction, }, DispatchResult, Perbill, }; @@ -54,141 +54,13 @@ use sp_staking::{ SessionIndex, }; -/// Ensure that equivocation reports are only processed if valid. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct ValidateEquivocationReport(sp_std::marker::PhantomData); - -impl Default for ValidateEquivocationReport { - fn default() -> ValidateEquivocationReport { - ValidateEquivocationReport::new() - } -} - -impl ValidateEquivocationReport { - pub fn new() -> ValidateEquivocationReport { - ValidateEquivocationReport(Default::default()) - } -} - -impl sp_std::fmt::Debug for ValidateEquivocationReport { - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "ValidateEquivocationReport") - } -} - -/// Custom validity error used when validating equivocation reports. -#[derive(Debug)] -#[repr(u8)] -pub enum ReportEquivocationValidityError { - /// The proof provided in the report is not valid. - InvalidEquivocationProof = 1, - /// The proof provided in the report is not valid. - InvalidKeyOwnershipProof = 2, - /// The set id provided in the report is not valid. - InvalidSetId = 3, - /// The session index provided in the report is not valid. - InvalidSession = 4, -} - -impl From for TransactionValidityError { - fn from(e: ReportEquivocationValidityError) -> TransactionValidityError { - TransactionValidityError::from(InvalidTransaction::Custom(e as u8)) - } -} - -impl SignedExtension for ValidateEquivocationReport -where - ::Call: IsSubType, T>, -{ - const IDENTIFIER: &'static str = "ValidateEquivocationReport"; - type AccountId = T::AccountId; - type Call = ::Call; - type AdditionalSigned = (); - type Pre = (); - - fn additional_signed( - &self, - ) -> sp_std::result::Result { - Ok(()) - } - - fn validate( - &self, - _who: &Self::AccountId, - call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> TransactionValidity { - let (equivocation_proof, key_owner_proof) = match call.is_sub_type() { - Some(super::Call::report_equivocation(equivocation_proof, key_owner_proof)) => { - (equivocation_proof, key_owner_proof) - } - _ => return Ok(ValidTransaction::default()), - }; - - // validate the key ownership proof extracting the id of the offender. - if let None = T::KeyOwnerProofSystem::check_proof( - ( - sp_finality_grandpa::KEY_TYPE, - equivocation_proof.offender().clone(), - ), - key_owner_proof.clone(), - ) { - return Err(ReportEquivocationValidityError::InvalidKeyOwnershipProof.into()); - } - - // we check the equivocation within the context of its set id (and - // associated session). - let set_id = equivocation_proof.set_id(); - let session_index = key_owner_proof.session(); - - // validate equivocation proof (check votes are different and - // signatures are valid). - if let Err(_) = sp_finality_grandpa::check_equivocation_proof(equivocation_proof.clone()) { - return Err(ReportEquivocationValidityError::InvalidEquivocationProof.into()); - } - - // fetch the current and previous sets last session index. on the - // genesis set there's no previous set. - let previous_set_id_session_index = if set_id == 0 { - None - } else { - let session_index = - if let Some(session_id) = >::session_for_set(set_id - 1) { - session_id - } else { - return Err(ReportEquivocationValidityError::InvalidSetId.into()); - }; - - Some(session_index) - }; - - let set_id_session_index = - if let Some(session_id) = >::session_for_set(set_id) { - session_id - } else { - return Err(ReportEquivocationValidityError::InvalidSetId.into()); - }; - - // check that the session id for the membership proof is within the - // bounds of the set id reported in the equivocation. - if session_index > set_id_session_index || - previous_set_id_session_index - .map(|previous_index| session_index <= previous_index) - .unwrap_or(false) - { - return Err(ReportEquivocationValidityError::InvalidSession.into()); - } - - Ok(ValidTransaction::default()) - } -} +use super::{Call, Module, Trait}; /// A trait with utility methods for handling equivocation reports in GRANDPA. /// The offence type is generic, and the trait provides , reporting an offence /// triggered by a valid equivocation report, and also for creating and /// submitting equivocation report extrinsics (useful only in offchain context). -pub trait HandleEquivocation { +pub trait HandleEquivocation { /// The offence type used for reporting offences on valid equivocation reports. type Offence: GrandpaOffence; @@ -198,14 +70,23 @@ pub trait HandleEquivocation { offence: Self::Offence, ) -> Result<(), OffenceError>; + /// Returns true if all of the offenders at the given time slot have already been reported. + fn is_known_offence( + offenders: &[T::KeyOwnerIdentification], + time_slot: &>::TimeSlot, + ) -> bool; + /// Create and dispatch an equivocation report extrinsic. - fn submit_equivocation_report( + fn submit_unsigned_equivocation_report( equivocation_proof: EquivocationProof, key_owner_proof: T::KeyOwnerProof, ) -> DispatchResult; + + /// Fetch the current block author id, if defined. + fn block_author() -> Option; } -impl HandleEquivocation for () { +impl HandleEquivocation for () { type Offence = GrandpaEquivocationOffence; fn report_offence( @@ -215,23 +96,34 @@ impl HandleEquivocation for () { Ok(()) } - fn submit_equivocation_report( + fn is_known_offence( + _offenders: &[T::KeyOwnerIdentification], + _time_slot: &GrandpaTimeSlot, + ) -> bool { + true + } + + fn submit_unsigned_equivocation_report( _equivocation_proof: EquivocationProof, _key_owner_proof: T::KeyOwnerProof, ) -> DispatchResult { Ok(()) } + + fn block_author() -> Option { + None + } } /// Generic equivocation handler. This type implements `HandleEquivocation` /// using existing subsystems that are part of frame (type bounds described /// below) and will dispatch to them directly, it's only purpose is to wire all /// subsystems together. -pub struct EquivocationHandler> { - _phantom: sp_std::marker::PhantomData<(I, C, S, R, O)>, +pub struct EquivocationHandler> { + _phantom: sp_std::marker::PhantomData<(I, R, O)>, } -impl Default for EquivocationHandler { +impl Default for EquivocationHandler { fn default() -> Self { Self { _phantom: Default::default(), @@ -239,18 +131,17 @@ impl Default for EquivocationHandler { } } -impl HandleEquivocation - for EquivocationHandler +impl HandleEquivocation for EquivocationHandler where - // A signed transaction creator. Used for signing and submitting equivocation reports. - T: super::Trait + CreateSignedTransaction>, - // Application-specific crypto bindings. - C: AppCrypto, - // The offence type that should be used when reporting. - O: GrandpaOffence, + // We use the authorship pallet to fetch the current block author and use + // `offchain::SendTransactionTypes` for unsigned extrinsic creation and + // submission. + T: Trait + pallet_authorship::Trait + frame_system::offchain::SendTransactionTypes>, // A system for reporting offences after valid equivocation reports are // processed. R: ReportOffence, + // The offence type that should be used when reporting. + O: GrandpaOffence, { type Offence = O; @@ -258,36 +149,29 @@ where R::report_offence(reporters, offence) } - fn submit_equivocation_report( + fn is_known_offence(offenders: &[T::KeyOwnerIdentification], time_slot: &O::TimeSlot) -> bool { + R::is_known_offence(offenders, time_slot) + } + + fn submit_unsigned_equivocation_report( equivocation_proof: EquivocationProof, key_owner_proof: T::KeyOwnerProof, ) -> DispatchResult { - use frame_system::offchain::SendSignedTransaction; + use frame_system::offchain::SubmitTransaction; - let signer = Signer::::all_accounts(); - if !signer.can_sign() { - return Err( - "No local accounts available. Consider adding one via `author_insertKey` RPC.", - )?; - } + let call = Call::report_equivocation_unsigned(equivocation_proof, key_owner_proof); - let results = signer.send_signed_transaction(|_account| { - super::Call::report_equivocation(equivocation_proof.clone(), key_owner_proof.clone()) - }); - - for (acc, res) in &results { - match res { - Ok(()) => debug::info!("[{:?}] Submitted GRANDPA equivocation report.", acc.id), - Err(e) => debug::error!( - "[{:?}] Error submitting equivocation report: {:?}", - acc.id, - e - ), - } + match SubmitTransaction::>::submit_unsigned_transaction(call.into()) { + Ok(()) => debug::info!("Submitted GRANDPA equivocation report."), + Err(e) => debug::error!("Error submitting equivocation report: {:?}", e), } Ok(()) } + + fn block_author() -> Option { + Some(>::author()) + } } /// A round number and set id which point on the time of an offence. @@ -300,6 +184,75 @@ pub struct GrandpaTimeSlot { pub round: RoundNumber, } +/// A `ValidateUnsigned` implementation that restricts calls to `report_equivocation_unsigned` +/// to local calls (i.e. extrinsics generated on this node) or that already in a block. This +/// guarantees that only block authors can include unsigned equivocation reports. +impl frame_support::unsigned::ValidateUnsigned for Module { + type Call = Call; + fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { + if let Call::report_equivocation_unsigned(equivocation_proof, _) = call { + // discard equivocation report not coming from the local node + match source { + TransactionSource::Local | TransactionSource::InBlock => { /* allowed */ } + _ => { + debug::warn!( + target: "afg", + "rejecting unsigned report equivocation transaction because it is not local/in-block." + ); + + return InvalidTransaction::Call.into(); + } + } + + ValidTransaction::with_tag_prefix("GrandpaEquivocation") + // We assign the maximum priority for any equivocation report. + .priority(TransactionPriority::max_value()) + // Only one equivocation report for the same offender at the same slot. + .and_provides(( + equivocation_proof.offender().clone(), + equivocation_proof.set_id(), + equivocation_proof.round(), + )) + // We don't propagate this. This can never be included on a remote node. + .propagate(false) + .build() + } else { + InvalidTransaction::Call.into() + } + } + + fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { + if let Call::report_equivocation_unsigned(equivocation_proof, key_owner_proof) = call { + // check the membership proof to extract the offender's id + let key = ( + sp_finality_grandpa::KEY_TYPE, + equivocation_proof.offender().clone(), + ); + + let offender = T::KeyOwnerProofSystem::check_proof(key, key_owner_proof.clone()) + .ok_or(InvalidTransaction::BadProof)?; + + // check if the offence has already been reported, + // and if so then we can discard the report. + let time_slot = + >::Offence::new_time_slot( + equivocation_proof.set_id(), + equivocation_proof.round(), + ); + + let is_known_offence = T::HandleEquivocation::is_known_offence(&[offender], &time_slot); + + if is_known_offence { + Err(InvalidTransaction::Stale.into()) + } else { + Ok(()) + } + } else { + Err(InvalidTransaction::Call.into()) + } + } +} + /// A grandpa equivocation offence report. #[allow(dead_code)] pub struct GrandpaEquivocationOffence { @@ -325,6 +278,9 @@ pub trait GrandpaOffence: Offence { set_id: SetId, round: RoundNumber, ) -> Self; + + /// Create a new GRANDPA offence time slot. + fn new_time_slot(set_id: SetId, round: RoundNumber) -> Self::TimeSlot; } impl GrandpaOffence @@ -344,6 +300,10 @@ impl GrandpaOffence time_slot: GrandpaTimeSlot { set_id, round }, } } + + fn new_time_slot(set_id: SetId, round: RoundNumber) -> Self::TimeSlot { + GrandpaTimeSlot { set_id, round } + } } impl Offence @@ -375,38 +335,3 @@ impl Offence x.square() } } - -/// A trait to get a session number the `MembershipProof` belongs to. -pub trait GetSessionNumber { - fn session(&self) -> SessionIndex; -} - -/// A trait to get the validator count at the session the `MembershipProof` -/// belongs to. -pub trait GetValidatorCount { - fn validator_count(&self) -> sp_session::ValidatorCount; -} - -impl GetSessionNumber for frame_support::Void { - fn session(&self) -> SessionIndex { - Default::default() - } -} - -impl GetValidatorCount for frame_support::Void { - fn validator_count(&self) -> sp_session::ValidatorCount { - Default::default() - } -} - -impl GetSessionNumber for sp_session::MembershipProof { - fn session(&self) -> SessionIndex { - self.session - } -} - -impl GetValidatorCount for sp_session::MembershipProof { - fn validator_count(&self) -> sp_session::ValidatorCount { - self.validator_count - } -} diff --git a/frame/grandpa/src/lib.rs b/frame/grandpa/src/lib.rs index 055607816d3f1af58821528fd1ab7b4bc1bcdeac..961c0994607520f15201f96df6e6c504350a94f3 100644 --- a/frame/grandpa/src/lib.rs +++ b/frame/grandpa/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! GRANDPA Consensus module for runtime. //! @@ -42,21 +43,28 @@ use frame_support::{ decl_error, decl_event, decl_module, decl_storage, storage, traits::KeyOwnerProofSystem, Parameter, }; -use frame_system::{self as system, ensure_signed, DigestOf}; +use frame_system::{ensure_none, ensure_root, ensure_signed}; +use pallet_finality_tracker::OnFinalizationStalled; use sp_runtime::{ - generic::{DigestItem, OpaqueDigestItemId}, + generic::DigestItem, traits::Zero, DispatchResult, KeyTypeId, }; +use sp_session::{GetSessionNumber, GetValidatorCount}; use sp_staking::SessionIndex; mod equivocation; + +#[cfg(any(feature = "runtime-benchmarks", test))] +mod benchmarking; +#[cfg(all(feature = "std", test))] mod mock; +#[cfg(all(feature = "std", test))] mod tests; pub use equivocation::{ - EquivocationHandler, GetSessionNumber, GetValidatorCount, GrandpaEquivocationOffence, - GrandpaOffence, GrandpaTimeSlot, HandleEquivocation, ValidateEquivocationReport, + EquivocationHandler, GrandpaEquivocationOffence, GrandpaOffence, GrandpaTimeSlot, + HandleEquivocation, }; pub trait Trait: frame_system::Trait { @@ -86,9 +94,8 @@ pub trait Trait: frame_system::Trait { /// offence (after the equivocation has been validated) and for submitting a /// transaction to report an equivocation (from an offchain context). /// NOTE: when enabling equivocation handling (i.e. this type isn't set to - /// `()`) you must add the `equivocation::ValidateEquivocationReport` signed - /// extension to the runtime's `SignedExtra` definition, otherwise - /// equivocation reports won't be properly validated. + /// `()`) you must use this pallet's `ValidateUnsigned` in the runtime + /// definition. type HandleEquivocation: HandleEquivocation; } @@ -163,7 +170,7 @@ pub enum StoredState { decl_event! { pub enum Event { - /// New authority set has been applied. + /// New authority set has been applied. [authority_set] NewAuthorities(AuthorityList), /// Current authority set has been paused. Paused, @@ -186,6 +193,8 @@ decl_error! { TooSoon, /// A key ownership proof provided as part of an equivocation report is invalid. InvalidKeyOwnershipProof, + /// An equivocation proof provided as part of an equivocation report is invalid. + InvalidEquivocationProof, /// A given equivocation report is valid but already previously reported. DuplicateOffenceReport, } @@ -197,7 +206,7 @@ decl_storage! { State get(fn state): StoredState = StoredState::Live; /// Pending change: (signaled at, scheduled change). - PendingChange: Option>; + PendingChange get(fn pending_change): Option>; /// next block number where we can force a change. NextForced get(fn next_forced): Option; @@ -211,6 +220,8 @@ decl_storage! { /// A mapping from grandpa set ID to the index of the *most recent* session for which its /// members were responsible. + /// + /// TWOX-NOTE: `SetId` is not under user control. SetIdSession get(fn session_for_set): map hasher(twox_64_concat) SetId => Option; } add_extra_genesis { @@ -231,46 +242,61 @@ decl_module! { /// equivocation proof and validate the given key ownership proof /// against the extracted offender. If both are valid, the offence /// will be reported. - /// - /// Since the weight of the extrinsic is 0, in order to avoid DoS by - /// submission of invalid equivocation reports, a mandatory pre-validation of - /// the extrinsic is implemented in a `SignedExtension`. - #[weight = 0] + #[weight = weight_for::report_equivocation::(key_owner_proof.validator_count())] fn report_equivocation( origin, equivocation_proof: EquivocationProof, key_owner_proof: T::KeyOwnerProof, ) { - let reporter_id = ensure_signed(origin)?; + let reporter = ensure_signed(origin)?; - let (session_index, validator_set_count) = ( - key_owner_proof.session(), - key_owner_proof.validator_count(), - ); + Self::do_report_equivocation( + Some(reporter), + equivocation_proof, + key_owner_proof, + )?; + } - // we have already checked this proof in `SignedExtension`, we to - // check it again to get the full identification of the offender. - let offender = - T::KeyOwnerProofSystem::check_proof( - (fg_primitives::KEY_TYPE, equivocation_proof.offender().clone()), - key_owner_proof, - ).ok_or(Error::::InvalidKeyOwnershipProof)?; - - // the set id and round when the offence happened - let set_id = equivocation_proof.set_id(); - let round = equivocation_proof.round(); - - // report to the offences module rewarding the sender. - T::HandleEquivocation::report_offence( - vec![reporter_id], - >::Offence::new( - session_index, - validator_set_count, - offender, - set_id, - round, - ), - ).map_err(|_| Error::::DuplicateOffenceReport)?; + /// Report voter equivocation/misbehavior. This method will verify the + /// equivocation proof and validate the given key ownership proof + /// against the extracted offender. If both are valid, the offence + /// will be reported. + /// + /// This extrinsic must be called unsigned and it is expected that only + /// block authors will call it (validated in `ValidateUnsigned`), as such + /// if the block author is defined it will be defined as the equivocation + /// reporter. + #[weight = weight_for::report_equivocation::(key_owner_proof.validator_count())] + fn report_equivocation_unsigned( + origin, + equivocation_proof: EquivocationProof, + key_owner_proof: T::KeyOwnerProof, + ) { + ensure_none(origin)?; + + Self::do_report_equivocation( + T::HandleEquivocation::block_author(), + equivocation_proof, + key_owner_proof, + )?; + } + + /// Note that the current authority set of the GRANDPA finality gadget has + /// stalled. This will trigger a forced authority set change at the beginning + /// of the next session, to be enacted `delay` blocks after that. The delay + /// should be high enough to safely assume that the block signalling the + /// forced change will not be re-orged (e.g. 1000 blocks). The GRANDPA voters + /// will start the new authority set using the given finalized block as base. + /// Only callable by root. + #[weight = weight_for::note_stalled::()] + fn note_stalled( + origin, + delay: T::BlockNumber, + best_finalized_block_number: T::BlockNumber, + ) { + ensure_root(origin)?; + + Self::on_stalled(delay, best_finalized_block_number) } fn on_finalize(block_number: T::BlockNumber) { @@ -288,7 +314,7 @@ decl_module! { )) } else { Self::deposit_log(ConsensusLog::ScheduledChange( - ScheduledChange{ + ScheduledChange { delay: pending_change.delay, next_authorities: pending_change.next_authorities.clone(), } @@ -338,6 +364,45 @@ decl_module! { } } +mod weight_for { + use frame_support::{ + traits::Get, + weights::{ + constants::{WEIGHT_PER_MICROS, WEIGHT_PER_NANOS}, + Weight, + }, + }; + + pub fn report_equivocation(validator_count: u32) -> Weight { + // we take the validator set count from the membership proof to + // calculate the weight but we set a floor of 100 validators. + let validator_count = validator_count.min(100) as u64; + + // worst case we are considering is that the given offender + // is backed by 200 nominators + const MAX_NOMINATORS: u64 = 200; + + // checking membership proof + (35 * WEIGHT_PER_MICROS) + .saturating_add((175 * WEIGHT_PER_NANOS).saturating_mul(validator_count)) + .saturating_add(T::DbWeight::get().reads(5)) + // check equivocation proof + .saturating_add(95 * WEIGHT_PER_MICROS) + // report offence + .saturating_add(110 * WEIGHT_PER_MICROS) + .saturating_add(25 * WEIGHT_PER_MICROS * MAX_NOMINATORS) + .saturating_add(T::DbWeight::get().reads(14 + 3 * MAX_NOMINATORS)) + .saturating_add(T::DbWeight::get().writes(10 + 3 * MAX_NOMINATORS)) + // fetching set id -> session index mappings + .saturating_add(T::DbWeight::get().reads(2)) + } + + pub fn note_stalled() -> Weight { + (3 * WEIGHT_PER_MICROS) + .saturating_add(T::DbWeight::get().writes(1)) + } +} + impl Module { /// Get the current set of authorities, along with their respective weights. pub fn grandpa_authorities() -> AuthorityList { @@ -451,51 +516,91 @@ impl Module { SetIdSession::insert(0, 0); } - /// Submits an extrinsic to report an equivocation. This method will sign an - /// extrinsic with a call to `report_equivocation` with any reporting keys - /// available in the keystore and will push the transaction to the pool. - /// Only useful in an offchain context. - pub fn submit_report_equivocation_extrinsic( + fn do_report_equivocation( + reporter: Option, equivocation_proof: EquivocationProof, key_owner_proof: T::KeyOwnerProof, - ) -> Option<()> { - T::HandleEquivocation::submit_equivocation_report(equivocation_proof, key_owner_proof).ok() - } -} - -impl Module { - /// Attempt to extract a GRANDPA log from a generic digest. - pub fn grandpa_log(digest: &DigestOf) -> Option> { - let id = OpaqueDigestItemId::Consensus(&GRANDPA_ENGINE_ID); - digest.convert_first(|l| l.try_to::>(id)) - } + ) -> Result<(), Error> { + // we check the equivocation within the context of its set id (and + // associated session) and round. we also need to know the validator + // set count when the offence since it is required to calculate the + // slash amount. + let set_id = equivocation_proof.set_id(); + let round = equivocation_proof.round(); + let session_index = key_owner_proof.session(); + let validator_count = key_owner_proof.validator_count(); + + // validate the key ownership proof extracting the id of the offender. + let offender = + T::KeyOwnerProofSystem::check_proof( + (fg_primitives::KEY_TYPE, equivocation_proof.offender().clone()), + key_owner_proof, + ).ok_or(Error::::InvalidKeyOwnershipProof)?; + + // validate equivocation proof (check votes are different and + // signatures are valid). + if !sp_finality_grandpa::check_equivocation_proof(equivocation_proof) { + return Err(Error::::InvalidEquivocationProof.into()); + } - /// Attempt to extract a pending set-change signal from a digest. - pub fn pending_change(digest: &DigestOf) - -> Option> - { - Self::grandpa_log(digest).and_then(|signal| signal.try_into_change()) - } + // fetch the current and previous sets last session index. on the + // genesis set there's no previous set. + let previous_set_id_session_index = if set_id == 0 { + None + } else { + let session_index = + if let Some(session_id) = Self::session_for_set(set_id - 1) { + session_id + } else { + return Err(Error::::InvalidEquivocationProof.into()); + }; + + Some(session_index) + }; - /// Attempt to extract a forced set-change signal from a digest. - pub fn forced_change(digest: &DigestOf) - -> Option<(T::BlockNumber, ScheduledChange)> - { - Self::grandpa_log(digest).and_then(|signal| signal.try_into_forced_change()) - } + let set_id_session_index = + if let Some(session_id) = Self::session_for_set(set_id) { + session_id + } else { + return Err(Error::::InvalidEquivocationProof.into()); + }; + + // check that the session id for the membership proof is within the + // bounds of the set id reported in the equivocation. + if session_index > set_id_session_index || + previous_set_id_session_index + .map(|previous_index| session_index <= previous_index) + .unwrap_or(false) + { + return Err(Error::::InvalidEquivocationProof.into()); + } - /// Attempt to extract a pause signal from a digest. - pub fn pending_pause(digest: &DigestOf) - -> Option - { - Self::grandpa_log(digest).and_then(|signal| signal.try_into_pause()) + // report to the offences module rewarding the sender. + T::HandleEquivocation::report_offence( + reporter.into_iter().collect(), + >::Offence::new( + session_index, + validator_count, + offender, + set_id, + round, + ), + ).map_err(|_| Error::::DuplicateOffenceReport) } - /// Attempt to extract a resume signal from a digest. - pub fn pending_resume(digest: &DigestOf) - -> Option - { - Self::grandpa_log(digest).and_then(|signal| signal.try_into_resume()) + /// Submits an extrinsic to report an equivocation. This method will create + /// an unsigned extrinsic with a call to `report_equivocation_unsigned` and + /// will push the transaction to the pool. Only useful in an offchain + /// context. + pub fn submit_unsigned_equivocation_report( + equivocation_proof: EquivocationProof, + key_owner_proof: T::KeyOwnerProof, + ) -> Option<()> { + T::HandleEquivocation::submit_unsigned_equivocation_report( + equivocation_proof, + key_owner_proof, + ) + .ok() } } @@ -521,14 +626,26 @@ impl pallet_session::OneSessionHandler for Module // Always issue a change if `session` says that the validators have changed. // Even if their session keys are the same as before, the underlying economic // identities have changed. - let current_set_id = if changed { + let current_set_id = if changed || >::exists() { let next_authorities = validators.map(|(_, k)| (k, 1)).collect::>(); - if let Some((further_wait, median)) = >::take() { - let _ = Self::schedule_change(next_authorities, further_wait, Some(median)); + + let res = if let Some((further_wait, median)) = >::take() { + Self::schedule_change(next_authorities, further_wait, Some(median)) + } else { + Self::schedule_change(next_authorities, Zero::zero(), None) + }; + + if res.is_ok() { + CurrentSetId::mutate(|s| { + *s += 1; + *s + }) } else { - let _ = Self::schedule_change(next_authorities, Zero::zero(), None); + // either the session module signalled that the validators have changed + // or the set was stalled. but since we didn't successfully schedule + // an authority set change we do not increment the set id. + Self::current_set_id() } - CurrentSetId::mutate(|s| { *s += 1; *s }) } else { // nothing's changed, neither economic conditions nor session keys. update the pointer // of the current set. @@ -546,7 +663,7 @@ impl pallet_session::OneSessionHandler for Module } } -impl pallet_finality_tracker::OnFinalizationStalled for Module { +impl OnFinalizationStalled for Module { fn on_stalled(further_wait: T::BlockNumber, median: T::BlockNumber) { // when we record old authority sets, we can use `pallet_finality_tracker::median` // to figure out _who_ failed. until then, we can't meaningfully guard diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index f307f17fd4d53379cdb7d1a9e07953e2315af0a6..684712df7d078362a5aebc5524c4b4c286bb9fe5 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -1,33 +1,31 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Test utilities #![cfg(test)] -use crate::{ - equivocation::ValidateEquivocationReport, AuthorityId, AuthorityList, Call as GrandpaCall, - ConsensusLog, Module, Trait, -}; +use crate::{AuthorityId, AuthorityList, ConsensusLog, Module, Trait}; use ::grandpa as finality_grandpa; use codec::Encode; use frame_support::{ impl_outer_dispatch, impl_outer_event, impl_outer_origin, parameter_types, traits::{KeyOwnerProofSystem, OnFinalize, OnInitialize}, - weights::{DispatchInfo, Weight}, + weights::Weight, }; use pallet_staking::EraIndex; use sp_core::{crypto::KeyTypeId, H256}; @@ -38,11 +36,7 @@ use sp_runtime::{ curve::PiecewiseLinear, impl_opaque_keys, testing::{Header, TestXt, UintAuthorityId}, - traits::{ - Convert, Extrinsic as ExtrinsicT, Header as _, IdentityLookup, OpaqueKeys, - SaturatedConversion, SignedExtension, - }, - transaction_validity::TransactionValidityError, + traits::{Convert, IdentityLookup, OpaqueKeys, SaturatedConversion}, DigestItem, Perbill, }; use sp_staking::SessionIndex; @@ -93,6 +87,7 @@ parameter_types! { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -108,6 +103,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -115,6 +111,7 @@ impl frame_system::Trait for Test { type AccountData = balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl system::offchain::SendTransactionTypes for Test @@ -142,6 +139,7 @@ impl session::Trait for Test { type SessionHandler = ::KeyTypeIdProviders; type Keys = TestSessionKeys; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; + type WeightInfo = (); } impl session::historical::Trait for Test { @@ -149,6 +147,17 @@ impl session::historical::Trait for Test { type FullIdentificationOf = staking::ExposureOf; } +parameter_types! { + pub const UncleGenerations: u64 = 0; +} + +impl pallet_authorship::Trait for Test { + type FindAuthor = (); + type UncleGenerations = UncleGenerations; + type FilterUncle = (); + type EventHandler = (); +} + parameter_types! { pub const ExistentialDeposit: u128 = 1; } @@ -159,6 +168,7 @@ impl balances::Trait for Test { type Event = TestEvent; type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { @@ -169,6 +179,7 @@ impl timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } pallet_staking_reward_curve::build! { @@ -227,12 +238,20 @@ impl staking::Trait for Test { type Call = Call; type UnsignedPriority = StakingUnsignedPriority; type MaxIterations = (); + type MinSolutionScoreBump = (); + type WeightInfo = (); +} + +parameter_types! { + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } impl offences::Trait for Test { type Event = TestEvent; type IdentificationTuple = session::historical::IdentificationTuple; type OnOffenceHandler = Staking; + type WeightSoftLimit = OffencesWeightSoftLimit; + type WeightInfo = (); } impl Trait for Test { @@ -249,66 +268,7 @@ impl Trait for Test { AuthorityId, )>>::IdentificationTuple; - type HandleEquivocation = super::EquivocationHandler< - Self::KeyOwnerIdentification, - reporting_keys::ReporterAppCrypto, - Test, - Offences, - >; -} - -pub mod reporting_keys { - use sp_core::crypto::KeyTypeId; - - pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"test"); - - mod app { - use sp_application_crypto::{app_crypto, ed25519}; - app_crypto!(ed25519, super::KEY_TYPE); - - impl sp_runtime::traits::IdentifyAccount for Public { - type AccountId = u64; - fn into_account(self) -> Self::AccountId { - super::super::Grandpa::grandpa_authorities() - .iter() - .map(|(k, _)| k) - .position(|b| *b == self.0.clone().into()) - .unwrap() as u64 - } - } - } - - pub type ReporterId = app::Public; - - pub struct ReporterAppCrypto; - impl frame_system::offchain::AppCrypto - for ReporterAppCrypto - { - type RuntimeAppPublic = ReporterId; - type GenericSignature = sp_core::ed25519::Signature; - type GenericPublic = sp_core::ed25519::Public; - } -} - -type Extrinsic = TestXt; - -impl system::offchain::CreateSignedTransaction for Test -where - Call: From, -{ - fn create_transaction>( - call: Call, - _public: reporting_keys::ReporterId, - _account: ::AccountId, - nonce: ::Index, - ) -> Option<(Call, ::SignaturePayload)> { - Some((call, (nonce, ()))) - } -} - -impl frame_system::offchain::SigningTypes for Test { - type Public = reporting_keys::ReporterId; - type Signature = sp_core::ed25519::Signature; + type HandleEquivocation = super::EquivocationHandler; } mod grandpa { @@ -405,23 +365,18 @@ pub fn new_test_ext_raw_authorities(authorities: AuthorityList) -> sp_io::TestEx } pub fn start_session(session_index: SessionIndex) { - let mut parent_hash = System::parent_hash(); - for i in Session::current_index()..session_index { + System::on_finalize(System::block_number()); + Session::on_finalize(System::block_number()); Staking::on_finalize(System::block_number()); - System::set_block_number((i + 1).into()); - Timestamp::set_timestamp(System::block_number() * 6000); + Grandpa::on_finalize(System::block_number()); - // In order to be able to use `System::parent_hash()` in the tests - // we need to first get it via `System::finalize` and then set it - // the `System::initialize`. However, it is needed to be taken into - // consideration that finalizing will prune some data in `System` - // storage including old values `BlockHash` if that reaches above - // `BlockHashCount` capacity. - if System::block_number() > 1 { + let parent_hash = if System::block_number() > 1 { let hdr = System::finalize(); - parent_hash = hdr.hash(); - } + hdr.hash() + } else { + System::parent_hash() + }; System::initialize( &(i as u64 + 1), @@ -430,9 +385,13 @@ pub fn start_session(session_index: SessionIndex) { &Default::default(), Default::default(), ); + System::set_block_number((i + 1).into()); + Timestamp::set_timestamp(System::block_number() * 6000); - Session::on_initialize(System::block_number()); System::on_initialize(System::block_number()); + Session::on_initialize(System::block_number()); + Staking::on_initialize(System::block_number()); + Grandpa::on_initialize(System::block_number()); } assert_eq!(Session::current_index(), session_index); @@ -453,18 +412,6 @@ pub fn initialize_block(number: u64, parent_hash: H256) { ); } -pub fn report_equivocation( - equivocation_proof: sp_finality_grandpa::EquivocationProof, - key_owner_proof: sp_session::MembershipProof, -) -> Result, TransactionValidityError> { - let inner = GrandpaCall::report_equivocation(equivocation_proof, key_owner_proof); - let call = Call::Grandpa(inner.clone()); - - ValidateEquivocationReport::::new().validate(&0, &call, &DispatchInfo::default(), 0)?; - - Ok(inner) -} - pub fn generate_equivocation_proof( set_id: SetId, vote1: (RoundNumber, H256, u64, &Ed25519Keyring), diff --git a/frame/grandpa/src/tests.rs b/frame/grandpa/src/tests.rs index 898c67583565f14874b18574f870bef37b1f5c34..9eca2cc381371ab8fddf0bd86a5b3c5c0bdd8430 100644 --- a/frame/grandpa/src/tests.rs +++ b/frame/grandpa/src/tests.rs @@ -1,24 +1,25 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for the module. #![cfg(test)] -use super::*; +use super::{Call, *}; use crate::mock::*; use codec::{Decode, Encode}; use fg_primitives::ScheduledChange; @@ -27,9 +28,10 @@ use frame_support::{ traits::{Currency, OnFinalize}, }; use frame_system::{EventRecord, Phase}; +use pallet_session::OneSessionHandler; use sp_core::H256; use sp_keyring::Ed25519Keyring; -use sp_runtime::{testing::Digest, traits::Header}; +use sp_runtime::testing::Digest; #[test] fn authorities_change_logged() { @@ -315,7 +317,9 @@ fn time_slot_have_sane_ord() { assert!(FIXTURE.windows(2).all(|f| f[0] < f[1])); } -fn test_authorities() -> AuthorityList { +/// Returns a list with 3 authorities with known keys: +/// Alice, Bob and Charlie. +pub fn test_authorities() -> AuthorityList { let authorities = vec![ Ed25519Keyring::Alice, Ed25519Keyring::Bob, @@ -339,14 +343,15 @@ fn report_equivocation_current_set_works() { start_era(1); let authorities = Grandpa::grandpa_authorities(); + let validators = Session::validators(); - // make sure that all authorities have the same balance - for i in 0..authorities.len() { - assert_eq!(Balances::total_balance(&(i as u64)), 10_000_000); - assert_eq!(Staking::slashable_balance_of(&(i as u64)), 10_000); + // make sure that all validators have the same balance + for validator in &validators { + assert_eq!(Balances::total_balance(validator), 10_000_000); + assert_eq!(Staking::slashable_balance_of(validator), 10_000); assert_eq!( - Staking::eras_stakers(1, i as u64), + Staking::eras_stakers(1, validator), pallet_staking::Exposure { total: 10_000, own: 10_000, @@ -374,17 +379,23 @@ fn report_equivocation_current_set_works() { Historical::prove((sp_finality_grandpa::KEY_TYPE, &equivocation_key)).unwrap(); // report the equivocation and the tx should be dispatched successfully - let inner = report_equivocation(equivocation_proof, key_owner_proof).unwrap(); - assert_ok!(Grandpa::dispatch(inner, Origin::signed(1))); + assert_ok!( + Grandpa::report_equivocation_unsigned( + Origin::none(), + equivocation_proof, + key_owner_proof, + ), + ); start_era(2); // check that the balance of 0-th validator is slashed 100%. - assert_eq!(Balances::total_balance(&0), 10_000_000 - 10_000); - assert_eq!(Staking::slashable_balance_of(&0), 0); + let equivocation_validator_id = validators[equivocation_authority_index]; + assert_eq!(Balances::total_balance(&equivocation_validator_id), 10_000_000 - 10_000); + assert_eq!(Staking::slashable_balance_of(&equivocation_validator_id), 0); assert_eq!( - Staking::eras_stakers(2, 0), + Staking::eras_stakers(2, equivocation_validator_id), pallet_staking::Exposure { total: 0, own: 0, @@ -393,12 +404,16 @@ fn report_equivocation_current_set_works() { ); // check that the balances of all other validators are left intact. - for i in 1..authorities.len() { - assert_eq!(Balances::total_balance(&(i as u64)), 10_000_000); - assert_eq!(Staking::slashable_balance_of(&(i as u64)), 10_000); + for validator in &validators { + if *validator == equivocation_validator_id { + continue; + } + + assert_eq!(Balances::total_balance(validator), 10_000_000); + assert_eq!(Staking::slashable_balance_of(validator), 10_000); assert_eq!( - Staking::eras_stakers(2, i as u64), + Staking::eras_stakers(2, validator), pallet_staking::Exposure { total: 10_000, own: 10_000, @@ -417,6 +432,7 @@ fn report_equivocation_old_set_works() { start_era(1); let authorities = Grandpa::grandpa_authorities(); + let validators = Session::validators(); let equivocation_authority_index = 0; let equivocation_key = &authorities[equivocation_authority_index].0; @@ -428,12 +444,12 @@ fn report_equivocation_old_set_works() { start_era(2); // make sure that all authorities have the same balance - for i in 0..authorities.len() { - assert_eq!(Balances::total_balance(&(i as u64)), 10_000_000); - assert_eq!(Staking::slashable_balance_of(&(i as u64)), 10_000); + for validator in &validators { + assert_eq!(Balances::total_balance(validator), 10_000_000); + assert_eq!(Staking::slashable_balance_of(validator), 10_000); assert_eq!( - Staking::eras_stakers(2, i as u64), + Staking::eras_stakers(2, validator), pallet_staking::Exposure { total: 10_000, own: 10_000, @@ -455,17 +471,24 @@ fn report_equivocation_old_set_works() { // report the equivocation using the key ownership proof generated on // the old set, the tx should be dispatched successfully - let inner = report_equivocation(equivocation_proof, key_owner_proof).unwrap(); - assert_ok!(Grandpa::dispatch(inner, Origin::signed(1))); + assert_ok!( + Grandpa::report_equivocation_unsigned( + Origin::none(), + equivocation_proof, + key_owner_proof, + ), + ); start_era(3); // check that the balance of 0-th validator is slashed 100%. - assert_eq!(Balances::total_balance(&0), 10_000_000 - 10_000); - assert_eq!(Staking::slashable_balance_of(&0), 0); + let equivocation_validator_id = validators[equivocation_authority_index]; + + assert_eq!(Balances::total_balance(&equivocation_validator_id), 10_000_000 - 10_000); + assert_eq!(Staking::slashable_balance_of(&equivocation_validator_id), 0); assert_eq!( - Staking::eras_stakers(3, 0), + Staking::eras_stakers(3, equivocation_validator_id), pallet_staking::Exposure { total: 0, own: 0, @@ -474,12 +497,16 @@ fn report_equivocation_old_set_works() { ); // check that the balances of all other validators are left intact. - for i in 1..authorities.len() { - assert_eq!(Balances::total_balance(&(i as u64)), 10_000_000); - assert_eq!(Staking::slashable_balance_of(&(i as u64)), 10_000); + for validator in &validators { + if *validator == equivocation_validator_id { + continue; + } + + assert_eq!(Balances::total_balance(validator), 10_000_000); + assert_eq!(Staking::slashable_balance_of(validator), 10_000); assert_eq!( - Staking::eras_stakers(3, i as u64), + Staking::eras_stakers(3, validator), pallet_staking::Exposure { total: 10_000, own: 10_000, @@ -515,10 +542,14 @@ fn report_equivocation_invalid_set_id() { (1, H256::random(), 10, &equivocation_keyring), ); - // it should be filtered by the signed extension validation + // the call for reporting the equivocation should error assert_err!( - report_equivocation(equivocation_proof, key_owner_proof), - equivocation::ReportEquivocationValidityError::InvalidSetId, + Grandpa::report_equivocation_unsigned( + Origin::none(), + equivocation_proof, + key_owner_proof, + ), + Error::::InvalidEquivocationProof, ); }); } @@ -554,8 +585,12 @@ fn report_equivocation_invalid_session() { // report an equivocation for the current set using an key ownership // proof from the previous set, the session should be invalid. assert_err!( - report_equivocation(equivocation_proof, key_owner_proof), - equivocation::ReportEquivocationValidityError::InvalidSession, + Grandpa::report_equivocation_unsigned( + Origin::none(), + equivocation_proof, + key_owner_proof, + ), + Error::::InvalidEquivocationProof, ); }); } @@ -595,8 +630,12 @@ fn report_equivocation_invalid_key_owner_proof() { // report an equivocation for the current set using a key ownership // proof for a different key than the one in the equivocation proof. assert_err!( - report_equivocation(equivocation_proof, invalid_key_owner_proof), - equivocation::ReportEquivocationValidityError::InvalidKeyOwnershipProof, + Grandpa::report_equivocation_unsigned( + Origin::none(), + equivocation_proof, + invalid_key_owner_proof, + ), + Error::::InvalidKeyOwnershipProof, ); }); } @@ -622,8 +661,12 @@ fn report_equivocation_invalid_equivocation_proof() { let assert_invalid_equivocation_proof = |equivocation_proof| { assert_err!( - report_equivocation(equivocation_proof, key_owner_proof.clone()), - equivocation::ReportEquivocationValidityError::InvalidEquivocationProof, + Grandpa::report_equivocation_unsigned( + Origin::none(), + equivocation_proof, + key_owner_proof.clone(), + ), + Error::::InvalidEquivocationProof, ); }; @@ -659,3 +702,143 @@ fn report_equivocation_invalid_equivocation_proof() { )); }); } + +#[test] +fn report_equivocation_validate_unsigned_prevents_duplicates() { + use sp_runtime::transaction_validity::{ + InvalidTransaction, TransactionLongevity, TransactionPriority, TransactionSource, + TransactionValidity, ValidTransaction, + }; + + let authorities = test_authorities(); + + new_test_ext_raw_authorities(authorities).execute_with(|| { + start_era(1); + + let authorities = Grandpa::grandpa_authorities(); + + // generate and report an equivocation for the validator at index 0 + let equivocation_authority_index = 0; + let equivocation_key = &authorities[equivocation_authority_index].0; + let equivocation_keyring = extract_keyring(equivocation_key); + let set_id = Grandpa::current_set_id(); + + let equivocation_proof = generate_equivocation_proof( + set_id, + (1, H256::random(), 10, &equivocation_keyring), + (1, H256::random(), 10, &equivocation_keyring), + ); + + let key_owner_proof = + Historical::prove((sp_finality_grandpa::KEY_TYPE, &equivocation_key)).unwrap(); + + let call = Call::report_equivocation_unsigned( + equivocation_proof.clone(), + key_owner_proof.clone(), + ); + + // only local/inblock reports are allowed + assert_eq!( + ::validate_unsigned( + TransactionSource::External, + &call, + ), + InvalidTransaction::Call.into(), + ); + + // the transaction is valid when passed as local + let tx_tag = ( + equivocation_key, + set_id, + 1u64, + ); + + assert_eq!( + ::validate_unsigned( + TransactionSource::Local, + &call, + ), + TransactionValidity::Ok(ValidTransaction { + priority: TransactionPriority::max_value(), + requires: vec![], + provides: vec![("GrandpaEquivocation", tx_tag).encode()], + longevity: TransactionLongevity::max_value(), + propagate: false, + }) + ); + + // the pre dispatch checks should also pass + assert_ok!(::pre_dispatch(&call)); + + // we submit the report + Grandpa::report_equivocation_unsigned(Origin::none(), equivocation_proof, key_owner_proof) + .unwrap(); + + // the report should now be considered stale and the transaction is invalid + assert_err!( + ::pre_dispatch(&call), + InvalidTransaction::Stale, + ); + }); +} + +#[test] +fn on_new_session_doesnt_start_new_set_if_schedule_change_failed() { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { + assert_eq!(Grandpa::current_set_id(), 0); + + // starting a new era should lead to a change in the session + // validators and trigger a new set + start_era(1); + assert_eq!(Grandpa::current_set_id(), 1); + + // we schedule a change delayed by 2 blocks, this should make it so that + // when we try to rotate the session at the beginning of the era we will + // fail to schedule a change (there's already one pending), so we should + // not increment the set id. + Grandpa::schedule_change(to_authorities(vec![(1, 1)]), 2, None).unwrap(); + start_era(2); + assert_eq!(Grandpa::current_set_id(), 1); + + // everything should go back to normal after. + start_era(3); + assert_eq!(Grandpa::current_set_id(), 2); + + // session rotation might also fail to schedule a change if it's for a + // forced change (i.e. grandpa is stalled) and it is too soon. + >::put(1000); + >::put((30, 1)); + + // NOTE: we cannot go through normal era rotation since having `Stalled` + // defined will also trigger a new set (regardless of whether the + // session validators changed) + Grandpa::on_new_session(true, std::iter::empty(), std::iter::empty()); + assert_eq!(Grandpa::current_set_id(), 2); + }); +} + +#[test] +fn always_schedules_a_change_on_new_session_when_stalled() { + new_test_ext(vec![(1, 1), (2, 1), (3, 1)]).execute_with(|| { + start_era(1); + + assert!(Grandpa::pending_change().is_none()); + assert_eq!(Grandpa::current_set_id(), 1); + + // if the session handler reports no change then we should not schedule + // any pending change + Grandpa::on_new_session(false, std::iter::empty(), std::iter::empty()); + + assert!(Grandpa::pending_change().is_none()); + assert_eq!(Grandpa::current_set_id(), 1); + + // if grandpa is stalled then we should **always** schedule a forced + // change on a new session + >::put((10, 1)); + Grandpa::on_new_session(false, std::iter::empty(), std::iter::empty()); + + assert!(Grandpa::pending_change().is_some()); + assert!(Grandpa::pending_change().unwrap().forced.is_some()); + assert_eq!(Grandpa::current_set_id(), 2); + }); +} diff --git a/frame/identity/Cargo.toml b/frame/identity/Cargo.toml index f20a8c983df24f126bd64da20590e46dc6f56517..6e6289a9dea743052130ba6cda975201660a45ad 100644 --- a/frame/identity/Cargo.toml +++ b/frame/identity/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-identity" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME identity management pallet" @@ -13,18 +13,18 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } [features] default = ["std"] diff --git a/frame/identity/README.md b/frame/identity/README.md new file mode 100644 index 0000000000000000000000000000000000000000..de2f415cdf73ea264a5a239cd0a421012a7fa00e --- /dev/null +++ b/frame/identity/README.md @@ -0,0 +1,56 @@ +# Identity Module + +- [`identity::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +A federated naming system, allowing for multiple registrars to be added from a specified origin. +Registrars can set a fee to provide identity-verification service. Anyone can put forth a +proposed identity for a fixed deposit and ask for review by any number of registrars (paying +each of their fees). Registrar judgements are given as an `enum`, allowing for sophisticated, +multi-tier opinions. + +Some judgements are identified as *sticky*, which means they cannot be removed except by +complete removal of the identity, or by the registrar. Judgements are allowed to represent a +portion of funds that have been reserved for the registrar. + +A super-user can remove accounts and in doing so, slash the deposit. + +All accounts may also have a limited number of sub-accounts which may be specified by the owner; +by definition, these have equivalent ownership and each has an individual name. + +The number of registrars should be limited, and the deposit made sufficiently large, to ensure +no state-bloat attack is viable. + +## Interface + +### Dispatchable Functions + +#### For general users +* `set_identity` - Set the associated identity of an account; a small deposit is reserved if not + already taken. +* `clear_identity` - Remove an account's associated identity; the deposit is returned. +* `request_judgement` - Request a judgement from a registrar, paying a fee. +* `cancel_request` - Cancel the previous request for a judgement. + +#### For general users with sub-identities +* `set_subs` - Set the sub-accounts of an identity. +* `add_sub` - Add a sub-identity to an identity. +* `remove_sub` - Remove a sub-identity of an identity. +* `rename_sub` - Rename a sub-identity of an identity. +* `quit_sub` - Remove a sub-identity of an identity (called by the sub-identity). + +#### For registrars +* `set_fee` - Set the fee required to be paid for a judgement to be given by the registrar. +* `set_fields` - Set the fields that a registrar cares about in their judgements. +* `provide_judgement` - Provide a judgement to an identity. + +#### For super-users +* `add_registrar` - Add a new registrar to the system. +* `kill_identity` - Forcibly remove the associated identity; the deposit is lost. + +[`Call`]: ./enum.Call.html +[`Trait`]: ./trait.Trait.html + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/identity/src/benchmarking.rs b/frame/identity/src/benchmarking.rs index 81a9f3e1340cf82458adfd5f71562ecc76afbdef..8b0cb0c27cf0e1c98312fcbaf3ceee613ade5af7 100644 --- a/frame/identity/src/benchmarking.rs +++ b/frame/identity/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Identity pallet benchmarking. @@ -171,6 +172,48 @@ benchmarks! { }: _(RawOrigin::Signed(caller), subs) + add_sub { + let caller = account::("caller", 0); + + // Give them p many previous sub accounts. + let p in 1 .. T::MaxSubAccounts::get() - 1 => { + let _ = add_sub_accounts::(&caller, p)?; + }; + let sub = account::("new_sub", 0); + let data = Data::Raw(vec![0; 32]); + }: _(RawOrigin::Signed(caller), T::Lookup::unlookup(sub), data) + + rename_sub { + let caller = account::("caller", 0); + + let p in 1 .. T::MaxSubAccounts::get(); + + // Give them p many previous sub accounts. + let (sub, _) = add_sub_accounts::(&caller, p)?.remove(0); + let data = Data::Raw(vec![1; 32]); + + }: _(RawOrigin::Signed(caller), T::Lookup::unlookup(sub), data) + + remove_sub { + let caller = account::("caller", 0); + + // Give them p many previous sub accounts. + let p in 1 .. T::MaxSubAccounts::get(); + let (sub, _) = add_sub_accounts::(&caller, p)?.remove(0); + }: _(RawOrigin::Signed(caller), T::Lookup::unlookup(sub)) + + quit_sub { + let caller = account::("caller", 0); + let sup = account::("super", 0); + + // Give them p many previous sub accounts. + let p in 1 .. T::MaxSubAccounts::get() - 1 => { + let _ = add_sub_accounts::(&sup, p)?; + }; + let sup_origin = RawOrigin::Signed(sup).into(); + Identity::::add_sub(sup_origin, T::Lookup::unlookup(caller.clone()), Data::Raw(vec![0; 32]))?; + }: _(RawOrigin::Signed(caller)) + clear_identity { let caller = account::("caller", 0); let caller_origin = ::Origin::from(RawOrigin::Signed(caller.clone())); diff --git a/frame/identity/src/lib.rs b/frame/identity/src/lib.rs index c790203635ae63e3a67476fcd18d0dc41501e2a9..1607835f2414b0daef7029ac91d99b7e24db5b1d 100644 --- a/frame/identity/src/lib.rs +++ b/frame/identity/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Identity Module //! @@ -46,11 +47,17 @@ //! #### For general users //! * `set_identity` - Set the associated identity of an account; a small deposit is reserved if not //! already taken. -//! * `set_subs` - Set the sub-accounts of an identity. //! * `clear_identity` - Remove an account's associated identity; the deposit is returned. //! * `request_judgement` - Request a judgement from a registrar, paying a fee. //! * `cancel_request` - Cancel the previous request for a judgement. //! +//! #### For general users with sub-identities +//! * `set_subs` - Set the sub-accounts of an identity. +//! * `add_sub` - Add a sub-identity to an identity. +//! * `remove_sub` - Remove a sub-identity of an identity. +//! * `rename_sub` - Rename a sub-identity of an identity. +//! * `quit_sub` - Remove a sub-identity of an identity (called by the sub-identity). +//! //! #### For registrars //! * `set_fee` - Set the fee required to be paid for a judgement to be given by the registrar. //! * `set_fields` - Set the fields that a registrar cares about in their judgements. @@ -69,21 +76,57 @@ use sp_std::prelude::*; use sp_std::{fmt::Debug, ops::Add, iter::once}; use enumflags2::BitFlags; use codec::{Encode, Decode}; -use sp_runtime::{DispatchError, RuntimeDebug}; -use sp_runtime::traits::{StaticLookup, Zero, AppendZerosInput}; +use sp_runtime::{DispatchError, RuntimeDebug, DispatchResult}; +use sp_runtime::traits::{StaticLookup, Zero, AppendZerosInput, Saturating}; use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, dispatch::DispatchResultWithPostInfo, traits::{Currency, ReservableCurrency, OnUnbalanced, Get, BalanceStatus, EnsureOrigin}, weights::Weight, }; -use frame_system::{self as system, ensure_signed, ensure_root}; +use frame_system::ensure_signed; mod benchmarking; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +pub trait WeightInfo { + fn add_registrar(r: u32, ) -> Weight; + fn set_identity(r: u32, x: u32, ) -> Weight; + fn set_subs(p: u32, s: u32, ) -> Weight; + fn clear_identity(r: u32, s: u32, x: u32, ) -> Weight; + fn request_judgement(r: u32, x: u32, ) -> Weight; + fn cancel_request(r: u32, x: u32, ) -> Weight; + fn set_fee(r: u32, ) -> Weight; + fn set_account_id(r: u32, ) -> Weight; + fn set_fields(r: u32, ) -> Weight; + fn provide_judgement(r: u32, x: u32, ) -> Weight; + fn kill_identity(r: u32, s: u32, x: u32, ) -> Weight; + fn add_sub(p: u32, ) -> Weight; + fn rename_sub() -> Weight; + fn remove_sub(p: u32, ) -> Weight; + fn quit_sub(p: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn add_registrar(_r: u32, ) -> Weight { 1_000_000_000 } + fn set_identity(_r: u32, _x: u32, ) -> Weight { 1_000_000_000 } + fn set_subs(_p: u32, _s: u32, ) -> Weight { 1_000_000_000 } + fn clear_identity(_r: u32, _s: u32, _x: u32, ) -> Weight { 1_000_000_000 } + fn request_judgement(_r: u32, _x: u32, ) -> Weight { 1_000_000_000 } + fn cancel_request(_r: u32, _x: u32, ) -> Weight { 1_000_000_000 } + fn set_fee(_r: u32, ) -> Weight { 1_000_000_000 } + fn set_account_id(_r: u32, ) -> Weight { 1_000_000_000 } + fn set_fields(_r: u32, ) -> Weight { 1_000_000_000 } + fn provide_judgement(_r: u32, _x: u32, ) -> Weight { 1_000_000_000 } + fn kill_identity(_r: u32, _s: u32, _x: u32, ) -> Weight { 1_000_000_000 } + fn add_sub(_p: u32, ) -> Weight { 1_000_000_000 } + fn rename_sub() -> Weight { 1_000_000_000 } + fn remove_sub(_p: u32, ) -> Weight { 1_000_000_000 } + fn quit_sub(_p: u32, ) -> Weight { 1_000_000_000 } +} + pub trait Trait: frame_system::Trait { /// The overarching event type. type Event: From> + Into<::Event>; @@ -121,6 +164,9 @@ pub trait Trait: frame_system::Trait { /// The origin which may add or remove registrars. Root can always do this. type RegistrarOrigin: EnsureOrigin; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } /// Either underlying data blob if it is at most 32 bytes, or a hash of it. If the data is greater @@ -388,6 +434,8 @@ pub struct RegistrarInfo< decl_storage! { trait Store for Module as Identity { /// Information that is pertinent to identify the entity behind an account. + /// + /// TWOX-NOTE: OK ― `AccountId` is a secure hash. pub IdentityOf get(fn identity): map hasher(twox_64_concat) T::AccountId => Option>>; @@ -399,6 +447,8 @@ decl_storage! { /// Alternative "sub" identities of this account. /// /// The first item is the deposit, the second is a vector of the accounts. + /// + /// TWOX-NOTE: OK ― `AccountId` is a secure hash. pub SubsOf get(fn subs_of): map hasher(twox_64_concat) T::AccountId => (BalanceOf, Vec); @@ -412,20 +462,28 @@ decl_storage! { decl_event!( pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { - /// A name was set or reset (which will remove all judgements). + /// A name was set or reset (which will remove all judgements). [who] IdentitySet(AccountId), - /// A name was cleared, and the given balance returned. + /// A name was cleared, and the given balance returned. [who, deposit] IdentityCleared(AccountId, Balance), - /// A name was removed and the given balance slashed. + /// A name was removed and the given balance slashed. [who, deposit] IdentityKilled(AccountId, Balance), - /// A judgement was asked from a registrar. + /// A judgement was asked from a registrar. [who, registrar_index] JudgementRequested(AccountId, RegistrarIndex), - /// A judgement request was retracted. + /// A judgement request was retracted. [who, registrar_index] JudgementUnrequested(AccountId, RegistrarIndex), - /// A judgement was given by a registrar. + /// A judgement was given by a registrar. [target, registrar_index] JudgementGiven(AccountId, RegistrarIndex), - /// A registrar was added. + /// A registrar was added. [registrar_index] RegistrarAdded(RegistrarIndex), + /// A sub-identity was added to an identity and the deposit paid. [sub, main, deposit] + SubIdentityAdded(AccountId, AccountId, Balance), + /// A sub-identity was removed from an identity and the deposit freed. + /// [sub, main, deposit] + SubIdentityRemoved(AccountId, AccountId, Balance), + /// A sub-identity was cleared, and the given deposit repatriated from the + /// main identity account to the sub-identity account. [sub, main, deposit] + SubIdentityRevoked(AccountId, AccountId, Balance), } ); @@ -458,7 +516,13 @@ decl_error! { TooManyFields, /// Maximum amount of registrars reached. Cannot add any more. TooManyRegistrars, -} + /// Account ID is already named. + AlreadyClaimed, + /// Sender is not a sub-account. + NotSub, + /// Sub-account isn't owned by sender. + NotOwned + } } /// Functions for calcuating the weight of dispatchables. @@ -584,6 +648,36 @@ mod weight_for { + 2_600_000 * subs // S + 900_000 * extra_fields // X } + + /// Weight calculation for `add_sub`. + pub(crate) fn add_sub( + subs: Weight, + ) -> Weight { + let db = T::DbWeight::get(); + db.reads_writes(4, 3) + 124_000_000 + 156_000 * subs + } + + /// Weight calculation for `rename_sub`. + pub(crate) fn rename_sub() -> Weight { + let db = T::DbWeight::get(); + db.reads_writes(2, 1) + 30_000_000 + } + + /// Weight calculation for `remove_sub`. + pub(crate) fn remove_sub( + subs: Weight, + ) -> Weight { + let db = T::DbWeight::get(); + db.reads_writes(4, 3) + 86_000_000 + 50_000 * subs + } + + /// Weight calculation for `quit_sub`. + pub(crate) fn quit_sub( + subs: Weight, + ) -> Weight { + let db = T::DbWeight::get(); + db.reads_writes(3, 2) + 63_000_000 + 230_000 * subs + } } decl_module! { @@ -617,7 +711,7 @@ decl_module! { /// Add a registrar to the system. /// - /// The dispatch origin for this call must be `RegistrarOrigin` or `Root`. + /// The dispatch origin for this call must be `T::RegistrarOrigin`. /// /// - `account`: the account of the registrar. /// @@ -630,9 +724,7 @@ decl_module! { /// # #[weight = weight_for::add_registrar::(T::MaxRegistrars::get().into()) ] fn add_registrar(origin, account: T::AccountId) -> DispatchResultWithPostInfo { - T::RegistrarOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + T::RegistrarOrigin::ensure_origin(origin)?; let (i, registrar_count) = >::try_mutate( |registrars| -> Result<(RegistrarIndex, usize), DispatchError> { @@ -740,6 +832,9 @@ decl_module! { let (old_deposit, old_ids) = >::get(&sender); let new_deposit = T::SubAccountDeposit::get() * >::from(subs.len() as u32); + let not_other_sub = subs.iter().filter_map(|i| SuperOf::::get(&i.0)).all(|i| &i.0 == &sender); + ensure!(not_other_sub, Error::::AlreadyClaimed); + if old_deposit < new_deposit { T::Currency::reserve(&sender, new_deposit - old_deposit)?; } @@ -797,8 +892,7 @@ decl_module! { let (subs_deposit, sub_ids) = >::take(&sender); let id = >::take(&sender).ok_or(Error::::NotNamed)?; - let deposit = id.total_deposit() - + subs_deposit; + let deposit = id.total_deposit() + subs_deposit; for sub in sub_ids.iter() { >::remove(sub); } @@ -1084,7 +1178,7 @@ decl_module! { /// `Slash`. Verification request deposits are not returned; they should be cancelled /// manually using `cancel_request`. /// - /// The dispatch origin for this call must be _Root_ or match `T::ForceOrigin`. + /// The dispatch origin for this call must match `T::ForceOrigin`. /// /// - `target`: the account whose identity the judgement is upon. This must be an account /// with a registered identity. @@ -1103,9 +1197,7 @@ decl_module! { T::MaxAdditionalFields::get().into(), // X )] fn kill_identity(origin, target: ::Source) -> DispatchResultWithPostInfo { - T::ForceOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + T::ForceOrigin::ensure_origin(origin)?; // Figure out who we're meant to be clearing. let target = T::Lookup::lookup(target)?; @@ -1127,6 +1219,103 @@ decl_module! { id.info.additional.len() as Weight // X )).into()) } + + /// Add the given account to the sender's subs. + /// + /// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated + /// to the sender. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must have a registered + /// sub identity of `sub`. + #[weight = weight_for::add_sub::( + T::MaxSubAccounts::get().into(), // S + )] + fn add_sub(origin, sub: ::Source, data: Data) -> DispatchResult { + let sender = ensure_signed(origin)?; + let sub = T::Lookup::lookup(sub)?; + ensure!(IdentityOf::::contains_key(&sender), Error::::NoIdentity); + + // Check if it's already claimed as sub-identity. + ensure!(!SuperOf::::contains_key(&sub), Error::::AlreadyClaimed); + + SubsOf::::try_mutate(&sender, |(ref mut subs_deposit, ref mut sub_ids)| { + // Ensure there is space and that the deposit is paid. + ensure!(sub_ids.len() < T::MaxSubAccounts::get() as usize, Error::::TooManySubAccounts); + let deposit = T::SubAccountDeposit::get(); + T::Currency::reserve(&sender, deposit)?; + + SuperOf::::insert(&sub, (sender.clone(), data)); + sub_ids.push(sub.clone()); + *subs_deposit = subs_deposit.saturating_add(deposit); + + Self::deposit_event(RawEvent::SubIdentityAdded(sub, sender.clone(), deposit)); + Ok(()) + }) + } + + /// Alter the associated name of the given sub-account. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must have a registered + /// sub identity of `sub`. + #[weight = weight_for::rename_sub::()] + fn rename_sub(origin, sub: ::Source, data: Data) { + let sender = ensure_signed(origin)?; + let sub = T::Lookup::lookup(sub)?; + ensure!(IdentityOf::::contains_key(&sender), Error::::NoIdentity); + ensure!(SuperOf::::get(&sub).map_or(false, |x| x.0 == sender), Error::::NotOwned); + SuperOf::::insert(&sub, (sender, data)); + } + + /// Remove the given account from the sender's subs. + /// + /// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated + /// to the sender. + /// + /// The dispatch origin for this call must be _Signed_ and the sender must have a registered + /// sub identity of `sub`. + #[weight = weight_for::remove_sub::( + T::MaxSubAccounts::get().into(), // S + )] + fn remove_sub(origin, sub: ::Source) { + let sender = ensure_signed(origin)?; + ensure!(IdentityOf::::contains_key(&sender), Error::::NoIdentity); + let sub = T::Lookup::lookup(sub)?; + let (sup, _) = SuperOf::::get(&sub).ok_or(Error::::NotSub)?; + ensure!(sup == sender, Error::::NotOwned); + SuperOf::::remove(&sub); + SubsOf::::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| { + sub_ids.retain(|x| x != &sub); + let deposit = T::SubAccountDeposit::get().min(*subs_deposit); + *subs_deposit -= deposit; + let _ = T::Currency::unreserve(&sender, deposit); + Self::deposit_event(RawEvent::SubIdentityRemoved(sub, sender, deposit)); + }); + } + + /// Remove the sender as a sub-account. + /// + /// Payment: Balance reserved by a previous `set_subs` call for one sub will be repatriated + /// to the sender (*not* the original depositor). + /// + /// The dispatch origin for this call must be _Signed_ and the sender must have a registered + /// super-identity. + /// + /// NOTE: This should not normally be used, but is provided in the case that the non- + /// controller of an account is maliciously registered as a sub-account. + #[weight = weight_for::quit_sub::( + T::MaxSubAccounts::get().into(), // S + )] + fn quit_sub(origin) { + let sender = ensure_signed(origin)?; + let (sup, _) = SuperOf::::take(&sender).ok_or(Error::::NotSub)?; + SubsOf::::mutate(&sup, |(ref mut subs_deposit, ref mut sub_ids)| { + sub_ids.retain(|x| x != &sender); + let deposit = T::SubAccountDeposit::get().min(*subs_deposit); + *subs_deposit -= deposit; + let _ = T::Currency::repatriate_reserved(&sup, &sender, deposit, BalanceStatus::Free); + Self::deposit_event(RawEvent::SubIdentityRevoked(sender, sup.clone(), deposit)); + }); + } } } @@ -1150,20 +1339,15 @@ mod tests { ord_parameter_types, }; use sp_core::H256; - use frame_system::EnsureSignedBy; - // The testing primitives are very useful for avoiding having to work with signatures - // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. + use frame_system::{EnsureSignedBy, EnsureOneOf, EnsureRoot}; use sp_runtime::{ Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } - // For testing the pallet, we construct most of a mock runtime. This means - // first constructing a configuration type (`Test`) which `impl`s each of the - // configuration traits of pallets we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -1173,6 +1357,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -1188,6 +1373,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -1195,6 +1381,7 @@ mod tests { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; @@ -1205,6 +1392,7 @@ mod tests { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { pub const BasicDeposit: u64 = 10; @@ -1218,6 +1406,16 @@ mod tests { pub const One: u64 = 1; pub const Two: u64 = 2; } + type EnsureOneOrRoot = EnsureOneOf< + u64, + EnsureRoot, + EnsureSignedBy + >; + type EnsureTwoOrRoot = EnsureOneOf< + u64, + EnsureRoot, + EnsureSignedBy + >; impl Trait for Test { type Event = (); type Currency = Balances; @@ -1228,18 +1426,16 @@ mod tests { type MaxSubAccounts = MaxSubAccounts; type MaxAdditionalFields = MaxAdditionalFields; type MaxRegistrars = MaxRegistrars; - type RegistrarOrigin = EnsureSignedBy; - type ForceOrigin = EnsureSignedBy; + type RegistrarOrigin = EnsureOneOrRoot; + type ForceOrigin = EnsureTwoOrRoot; + type WeightInfo = (); } type System = frame_system::Module; type Balances = pallet_balances::Module; type Identity = Module; - // This function basically just builds a genesis storage key/value store according to - // our desired mockup. pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - // We use default for brevity, but you can configure as desired if needed. pallet_balances::GenesisConfig:: { balances: vec![ (1, 10), @@ -1261,6 +1457,84 @@ mod tests { } } + fn twenty() -> IdentityInfo { + IdentityInfo { + display: Data::Raw(b"twenty".to_vec()), + legal: Data::Raw(b"The Right Ordinal Twenty, Esq.".to_vec()), + .. Default::default() + } + } + + #[test] + fn editing_subaccounts_should_work() { + new_test_ext().execute_with(|| { + let data = |x| Data::Raw(vec![x; 1]); + + assert_noop!(Identity::add_sub(Origin::signed(10), 20, data(1)), Error::::NoIdentity); + + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + + // first sub account + assert_ok!(Identity::add_sub(Origin::signed(10), 1, data(1))); + assert_eq!(SuperOf::::get(1), Some((10, data(1)))); + assert_eq!(Balances::free_balance(10), 80); + + // second sub account + assert_ok!(Identity::add_sub(Origin::signed(10), 2, data(2))); + assert_eq!(SuperOf::::get(1), Some((10, data(1)))); + assert_eq!(SuperOf::::get(2), Some((10, data(2)))); + assert_eq!(Balances::free_balance(10), 70); + + // third sub account is too many + assert_noop!(Identity::add_sub(Origin::signed(10), 3, data(3)), Error::::TooManySubAccounts); + + // rename first sub account + assert_ok!(Identity::rename_sub(Origin::signed(10), 1, data(11))); + assert_eq!(SuperOf::::get(1), Some((10, data(11)))); + assert_eq!(SuperOf::::get(2), Some((10, data(2)))); + assert_eq!(Balances::free_balance(10), 70); + + // remove first sub account + assert_ok!(Identity::remove_sub(Origin::signed(10), 1)); + assert_eq!(SuperOf::::get(1), None); + assert_eq!(SuperOf::::get(2), Some((10, data(2)))); + assert_eq!(Balances::free_balance(10), 80); + + // add third sub account + assert_ok!(Identity::add_sub(Origin::signed(10), 3, data(3))); + assert_eq!(SuperOf::::get(1), None); + assert_eq!(SuperOf::::get(2), Some((10, data(2)))); + assert_eq!(SuperOf::::get(3), Some((10, data(3)))); + assert_eq!(Balances::free_balance(10), 70); + }); + } + + #[test] + fn resolving_subaccount_ownership_works() { + new_test_ext().execute_with(|| { + let data = |x| Data::Raw(vec![x; 1]); + + assert_ok!(Identity::set_identity(Origin::signed(10), ten())); + assert_ok!(Identity::set_identity(Origin::signed(20), twenty())); + + // 10 claims 1 as a subaccount + assert_ok!(Identity::add_sub(Origin::signed(10), 1, data(1))); + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(10), 80); + assert_eq!(Balances::reserved_balance(10), 20); + // 20 cannot claim 1 now + assert_noop!(Identity::add_sub(Origin::signed(20), 1, data(1)), Error::::AlreadyClaimed); + // 1 wants to be with 20 so it quits from 10 + assert_ok!(Identity::quit_sub(Origin::signed(1))); + // 1 gets the 10 that 10 paid. + assert_eq!(Balances::free_balance(1), 20); + assert_eq!(Balances::free_balance(10), 80); + assert_eq!(Balances::reserved_balance(10), 10); + // 20 can claim 1 now + assert_ok!(Identity::add_sub(Origin::signed(20), 1, data(1))); + }); + } + #[test] fn trailing_zeros_decodes_into_default_data() { let encoded = Data::Raw(b"Hello".to_vec()).encode(); @@ -1429,7 +1703,7 @@ mod tests { new_test_ext().execute_with(|| { assert_ok!(Identity::set_identity(Origin::signed(10), ten())); assert_ok!(Identity::set_subs(Origin::signed(10), vec![(20, Data::Raw(vec![40; 1]))])); - assert_ok!(Identity::kill_identity(Origin::ROOT, 10)); + assert_ok!(Identity::kill_identity(Origin::signed(2), 10)); assert_eq!(Balances::free_balance(10), 80); assert!(Identity::super_of(20).is_none()); }); diff --git a/frame/im-online/Cargo.toml b/frame/im-online/Cargo.toml index 55e5a49d586e5ff1554eec5dbacae7d6668f18f5..8541b46c9c879ad40371b378d979884027a83736 100644 --- a/frame/im-online/Cargo.toml +++ b/frame/im-online/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-im-online" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME's I'm online pallet" @@ -12,20 +12,20 @@ description = "FRAME's I'm online pallet" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } -pallet-authorship = { version = "2.0.0-dev", default-features = false, path = "../authorship" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/application-crypto" } +pallet-authorship = { version = "2.0.0-rc6", default-features = false, path = "../authorship" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -pallet-session = { version = "2.0.0-dev", default-features = false, path = "../session" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-rc6", default-features = false, path = "../session" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } [features] default = ["std", "pallet-session/historical"] diff --git a/frame/im-online/README.md b/frame/im-online/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c85705bd0ee6fbbbf5c132dec18ae0801b18ca57 --- /dev/null +++ b/frame/im-online/README.md @@ -0,0 +1,51 @@ +# I'm online Module + +If the local node is a validator (i.e. contains an authority key), this module +gossips a heartbeat transaction with each new session. The heartbeat functions +as a simple mechanism to signal that the node is online in the current era. + +Received heartbeats are tracked for one era and reset with each new era. The +module exposes two public functions to query if a heartbeat has been received +in the current era or session. + +The heartbeat is a signed transaction, which was signed using the session key +and includes the recent best block number of the local validators chain as well +as the [NetworkState](../../client/offchain/struct.NetworkState.html). +It is submitted as an Unsigned Transaction via off-chain workers. + +- [`im_online::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) +- [`Module`](./struct.Module.html) + +## Interface + +### Public Functions + +- `is_online` - True if the validator sent a heartbeat in the current session. + +## Usage + +```rust +use frame_support::{decl_module, dispatch}; +use frame_system::ensure_signed; +use pallet_im_online::{self as im_online}; + +pub trait Trait: im_online::Trait {} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + #[weight = 0] + pub fn is_online(origin, authority_index: u32) -> dispatch::DispatchResult { + let _sender = ensure_signed(origin)?; + let _is_online = >::is_online(authority_index); + Ok(()) + } + } +} +``` + +## Dependencies + +This module depends on the [Session module](../pallet_session/index.html). + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/im-online/src/benchmarking.rs b/frame/im-online/src/benchmarking.rs index dae2f719b614cc2317d65f7f231fb53c6663d170..92d9b9d5a5364524065b263af8e422628b847420 100644 --- a/frame/im-online/src/benchmarking.rs +++ b/frame/im-online/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! I'm Online pallet benchmarking. @@ -23,8 +24,9 @@ use super::*; use frame_system::RawOrigin; use frame_benchmarking::benchmarks; use sp_core::offchain::{OpaquePeerId, OpaqueMultiaddr}; -use sp_runtime::traits::{ValidateUnsigned, Zero, Dispatchable}; +use sp_runtime::traits::{ValidateUnsigned, Zero}; use sp_runtime::transaction_validity::TransactionSource; +use frame_support::traits::UnfilteredDispatchable; use crate::Module as ImOnline; @@ -84,7 +86,7 @@ benchmarks! { let call = Call::heartbeat(input_heartbeat, signature); }: { ImOnline::::validate_unsigned(TransactionSource::InBlock, &call)?; - call.dispatch(RawOrigin::None.into())?; + call.dispatch_bypass_filter(RawOrigin::None.into())?; } } diff --git a/frame/im-online/src/lib.rs b/frame/im-online/src/lib.rs index e280a890545c8d115726585abfa311608a392da0..01b7b999dd004749e6bc25e579486db1b5773205 100644 --- a/frame/im-online/src/lib.rs +++ b/frame/im-online/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # I'm online Module //! @@ -43,7 +44,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; -//! use frame_system::{self as system, ensure_signed}; +//! use frame_system::ensure_signed; //! use pallet_im_online::{self as im_online}; //! //! pub trait Trait: im_online::Trait {} @@ -81,7 +82,7 @@ use pallet_session::historical::IdentificationTuple; use sp_runtime::{ offchain::storage::StorageValueRef, RuntimeDebug, - traits::{Convert, Member, Saturating, AtLeast32Bit}, Perbill, + traits::{Convert, Member, Saturating, AtLeast32BitUnsigned}, Perbill, transaction_validity::{ TransactionValidity, ValidTransaction, InvalidTransaction, TransactionSource, TransactionPriority, @@ -96,7 +97,7 @@ use frame_support::{ traits::Get, weights::Weight, }; -use frame_system::{self as system, ensure_none}; +use frame_system::ensure_none; use frame_system::offchain::{ SendTransactionTypes, SubmitTransaction, @@ -159,7 +160,7 @@ struct HeartbeatStatus { pub sent_at: BlockNumber, } -impl HeartbeatStatus { +impl HeartbeatStatus { /// Returns true if heartbeat has been recently sent. /// /// Parameters: @@ -225,6 +226,18 @@ pub struct Heartbeat pub validators_len: u32, } +pub trait WeightInfo { + fn heartbeat(k: u32, e: u32, ) -> Weight; + fn validate_unsigned(k: u32, e: u32, ) -> Weight; + fn validate_unsigned_and_then_heartbeat(k: u32, e: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn heartbeat(_k: u32, _e: u32, ) -> Weight { 1_000_000_000 } + fn validate_unsigned(_k: u32, _e: u32, ) -> Weight { 1_000_000_000 } + fn validate_unsigned_and_then_heartbeat(_k: u32, _e: u32, ) -> Weight { 1_000_000_000 } +} + pub trait Trait: SendTransactionTypes> + pallet_session::historical::Trait { /// The identifier type for an authority. type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + Ord; @@ -253,6 +266,9 @@ pub trait Trait: SendTransactionTypes> + pallet_session::historical:: /// This is exposed so that it can be tuned for particular runtime, when /// multiple pallets send unsigned transactions. type UnsignedPriority: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_event!( @@ -260,11 +276,11 @@ decl_event!( ::AuthorityId, IdentificationTuple = IdentificationTuple, { - /// A new heartbeat was received from `AuthorityId` + /// A new heartbeat was received from `AuthorityId` [authority_id] HeartbeatReceived(AuthorityId), /// At the end of the session, no offence was committed. AllGood, - /// At the end of the session, at least once validator was found to be offline. + /// At the end of the session, at least one validator was found to be [offline]. SomeOffline(Vec), } ); diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 7ba9dd19f91d325e9f25266f703504a4d12640be..29fe6acb3337cd3aeecc503b1da2b0cfdd984e05 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Test utilities @@ -27,7 +28,7 @@ use sp_runtime::testing::{Header, UintAuthorityId, TestXt}; use sp_runtime::traits::{IdentityLookup, BlakeTwo256, ConvertInto}; use sp_core::H256; use frame_support::{impl_outer_origin, impl_outer_dispatch, parameter_types, weights::Weight}; -use frame_system as system; + impl_outer_origin!{ pub enum Origin for Runtime {} } @@ -85,10 +86,16 @@ impl ReportOffence for OffenceHandler { OFFENCES.with(|l| l.borrow_mut().push((reporters, offence))); Ok(()) } + + fn is_known_offence(_offenders: &[IdentificationTuple], _time_slot: &SessionIndex) -> bool { + false + } } pub fn new_test_ext() -> sp_io::TestExternalities { - let t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + let t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); t.into() } @@ -103,6 +110,7 @@ parameter_types! { } impl frame_system::Trait for Runtime { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -118,6 +126,7 @@ impl frame_system::Trait for Runtime { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -125,6 +134,7 @@ impl frame_system::Trait for Runtime { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { @@ -146,6 +156,7 @@ impl pallet_session::Trait for Runtime { type Event = (); type DisabledValidatorsThreshold = DisabledValidatorsThreshold; type NextSessionRotation = pallet_session::PeriodicSessions; + type WeightInfo = (); } impl pallet_session::historical::Trait for Runtime { @@ -174,6 +185,7 @@ impl Trait for Runtime { type ReportUnresponsiveness = OffenceHandler; type SessionDuration = Period; type UnsignedPriority = UnsignedPriority; + type WeightInfo = (); } impl frame_system::offchain::SendTransactionTypes for Runtime where diff --git a/frame/im-online/src/tests.rs b/frame/im-online/src/tests.rs index 2578b5114e21a866cddfa4f7eea04b29c4124602..835d8440e6d5b0e0f16caf750d841361a3012edc 100644 --- a/frame/im-online/src/tests.rs +++ b/frame/im-online/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for the im-online module. @@ -134,7 +135,7 @@ fn heartbeat( e @ _ => <&'static str>::from(e), })?; ImOnline::heartbeat( - Origin::system(frame_system::RawOrigin::None), + Origin::none(), heartbeat, signature, ) diff --git a/frame/indices/Cargo.toml b/frame/indices/Cargo.toml index 515c0b478ddb426ca754c383a686a0e9a77a715a..25d5c2527a94809e6f9b7a400670668d749f5b54 100644 --- a/frame/indices/Cargo.toml +++ b/frame/indices/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-indices" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME indices management pallet" @@ -13,17 +13,19 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-keyring = { version = "2.0.0-dev", optional = true, path = "../../primitives/keyring" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-keyring = { version = "2.0.0-rc6", optional = true, path = "../../primitives/keyring" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } + +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -pallet-balances = { version = "2.0.0-dev", path = "../balances" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } [features] default = ["std"] @@ -38,3 +40,7 @@ std = [ "sp-runtime/std", "frame-system/std", ] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", +] diff --git a/frame/indices/README.md b/frame/indices/README.md new file mode 100644 index 0000000000000000000000000000000000000000..243392780db28e9e6b941a5bb1e7d3c79d78887d --- /dev/null +++ b/frame/indices/README.md @@ -0,0 +1,4 @@ +An index is a short form of an address. This module handles allocation +of indices for a newly created accounts. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/indices/src/address.rs b/frame/indices/src/address.rs index f4487eeb693dec14bfcc3bae7229c3ce41177329..0fd89333813289d448f85e50cdf1002b8386e2db 100644 --- a/frame/indices/src/address.rs +++ b/frame/indices/src/address.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Address type that is union of index and id for an account. diff --git a/frame/indices/src/benchmarking.rs b/frame/indices/src/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..e8465c44cdc1653769e38f5c10f728dbe9248160 --- /dev/null +++ b/frame/indices/src/benchmarking.rs @@ -0,0 +1,124 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +// Benchmarks for Indices Pallet + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use frame_system::RawOrigin; +use frame_benchmarking::{benchmarks, account, whitelisted_caller}; +use sp_runtime::traits::Bounded; + +use crate::Module as Indices; + +const SEED: u32 = 0; + +benchmarks! { + _ { } + + claim { + // Index being claimed + let i in 0 .. 1000; + let account_index = T::AccountIndex::from(i); + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + }: _(RawOrigin::Signed(caller.clone()), account_index) + verify { + assert_eq!(Accounts::::get(account_index).unwrap().0, caller); + } + + transfer { + // Index being claimed + let i in 0 .. 1000; + let account_index = T::AccountIndex::from(i); + // Setup accounts + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + let recipient: T::AccountId = account("recipient", i, SEED); + T::Currency::make_free_balance_be(&recipient, BalanceOf::::max_value()); + // Claim the index + Indices::::claim(RawOrigin::Signed(caller.clone()).into(), account_index)?; + }: _(RawOrigin::Signed(caller.clone()), recipient.clone(), account_index) + verify { + assert_eq!(Accounts::::get(account_index).unwrap().0, recipient); + } + + free { + // Index being claimed + let i in 0 .. 1000; + let account_index = T::AccountIndex::from(i); + // Setup accounts + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + // Claim the index + Indices::::claim(RawOrigin::Signed(caller.clone()).into(), account_index)?; + }: _(RawOrigin::Signed(caller.clone()), account_index) + verify { + assert_eq!(Accounts::::get(account_index), None); + } + + force_transfer { + // Index being claimed + let i in 0 .. 1000; + let account_index = T::AccountIndex::from(i); + // Setup accounts + let original: T::AccountId = account("original", 0, SEED); + T::Currency::make_free_balance_be(&original, BalanceOf::::max_value()); + let recipient: T::AccountId = account("recipient", i, SEED); + T::Currency::make_free_balance_be(&recipient, BalanceOf::::max_value()); + // Claim the index + Indices::::claim(RawOrigin::Signed(original).into(), account_index)?; + }: _(RawOrigin::Root, recipient.clone(), account_index, false) + verify { + assert_eq!(Accounts::::get(account_index).unwrap().0, recipient); + } + + freeze { + // Index being claimed + let i in 0 .. 1000; + let account_index = T::AccountIndex::from(i); + // Setup accounts + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + // Claim the index + Indices::::claim(RawOrigin::Signed(caller.clone()).into(), account_index)?; + }: _(RawOrigin::Signed(caller.clone()), account_index) + verify { + assert_eq!(Accounts::::get(account_index).unwrap().2, true); + } + + // TODO in another PR: lookup and unlookup trait weights (not critical) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_claim::()); + assert_ok!(test_benchmark_transfer::()); + assert_ok!(test_benchmark_free::()); + assert_ok!(test_benchmark_force_transfer::()); + assert_ok!(test_benchmark_freeze::()); + }); + } +} diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index 8c17fed5921301c0f2ac5ad1bba6d30bde0e89fb..c99beb463bc5f5df5244c081d29d00a9687047cd 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! An index is a short form of an address. This module handles allocation //! of indices for a newly created accounts. @@ -27,16 +28,34 @@ use sp_runtime::traits::{ use frame_support::{Parameter, decl_module, decl_error, decl_event, decl_storage, ensure}; use frame_support::dispatch::DispatchResult; use frame_support::traits::{Currency, ReservableCurrency, Get, BalanceStatus::Reserved}; +use frame_support::weights::{Weight, constants::WEIGHT_PER_MICROS}; use frame_system::{ensure_signed, ensure_root}; use self::address::Address as RawAddress; mod mock; pub mod address; mod tests; +mod benchmarking; pub type Address = RawAddress<::AccountId, ::AccountIndex>; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub trait WeightInfo { + fn claim(i: u32, ) -> Weight; + fn transfer(i: u32, ) -> Weight; + fn free(i: u32, ) -> Weight; + fn force_transfer(i: u32, ) -> Weight; + fn freeze(i: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn claim(_i: u32, ) -> Weight { 1_000_000_000 } + fn transfer(_i: u32, ) -> Weight { 1_000_000_000 } + fn free(_i: u32, ) -> Weight { 1_000_000_000 } + fn force_transfer(_i: u32, ) -> Weight { 1_000_000_000 } + fn freeze(_i: u32, ) -> Weight { 1_000_000_000 } +} + /// The module's config trait. pub trait Trait: frame_system::Trait { /// Type used for storing an account's index; implies the maximum number of accounts the system @@ -51,6 +70,9 @@ pub trait Trait: frame_system::Trait { /// The overarching event type. type Event: From> + Into<::Event>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_storage! { @@ -59,9 +81,9 @@ decl_storage! { pub Accounts build(|config: &GenesisConfig| config.indices.iter() .cloned() - .map(|(a, b)| (a, (b, Zero::zero()))) + .map(|(a, b)| (a, (b, Zero::zero(), false))) .collect::>() - ): map hasher(blake2_128_concat) T::AccountIndex => Option<(T::AccountId, BalanceOf)>; + ): map hasher(blake2_128_concat) T::AccountIndex => Option<(T::AccountId, BalanceOf, bool)>; } add_extra_genesis { config(indices): Vec<(T::AccountIndex, T::AccountId)>; @@ -73,10 +95,12 @@ decl_event!( ::AccountId, ::AccountIndex { - /// A account index was assigned. + /// A account index was assigned. [who, index] IndexAssigned(AccountId, AccountIndex), - /// A account index has been freed up (unassigned). + /// A account index has been freed up (unassigned). [index] IndexFreed(AccountIndex), + /// A account index has been frozen to its current account ID. [who, index] + IndexFrozen(AccountIndex, AccountId), } ); @@ -90,6 +114,8 @@ decl_error! { InUse, /// The source and destination accounts are identical. NotTransfer, + /// The index is permanent and may not be freed/changed. + Permanent, } } @@ -112,14 +138,17 @@ decl_module! { /// - One storage mutation (codec `O(1)`). /// - One reserve operation. /// - One event. + /// ------------------- + /// - Base Weight: 28.69 µs + /// - DB Weight: 1 Read/Write (Accounts) /// # - #[weight = 0] + #[weight = T::DbWeight::get().reads_writes(1, 1) + 30 * WEIGHT_PER_MICROS] fn claim(origin, index: T::AccountIndex) { let who = ensure_signed(origin)?; Accounts::::try_mutate(index, |maybe_value| { ensure!(maybe_value.is_none(), Error::::InUse); - *maybe_value = Some((who.clone(), T::Deposit::get())); + *maybe_value = Some((who.clone(), T::Deposit::get(), false)); T::Currency::reserve(&who, T::Deposit::get()) })?; Self::deposit_event(RawEvent::IndexAssigned(who, index)); @@ -140,17 +169,23 @@ decl_module! { /// - One storage mutation (codec `O(1)`). /// - One transfer operation. /// - One event. + /// ------------------- + /// - Base Weight: 33.74 µs + /// - DB Weight: + /// - Reads: Indices Accounts, System Account (recipient) + /// - Writes: Indices Accounts, System Account (recipient) /// # - #[weight = 0] + #[weight = T::DbWeight::get().reads_writes(2, 2) + 35 * WEIGHT_PER_MICROS] fn transfer(origin, new: T::AccountId, index: T::AccountIndex) { let who = ensure_signed(origin)?; ensure!(who != new, Error::::NotTransfer); Accounts::::try_mutate(index, |maybe_value| -> DispatchResult { - let (account, amount) = maybe_value.take().ok_or(Error::::NotAssigned)?; + let (account, amount, perm) = maybe_value.take().ok_or(Error::::NotAssigned)?; + ensure!(!perm, Error::::Permanent); ensure!(&account == &who, Error::::NotOwner); let lost = T::Currency::repatriate_reserved(&who, &new, amount, Reserved)?; - *maybe_value = Some((new.clone(), amount.saturating_sub(lost))); + *maybe_value = Some((new.clone(), amount.saturating_sub(lost), false)); Ok(()) })?; Self::deposit_event(RawEvent::IndexAssigned(new, index)); @@ -171,13 +206,17 @@ decl_module! { /// - One storage mutation (codec `O(1)`). /// - One reserve operation. /// - One event. + /// ------------------- + /// - Base Weight: 25.53 µs + /// - DB Weight: 1 Read/Write (Accounts) /// # - #[weight = 0] + #[weight = T::DbWeight::get().reads_writes(1, 1) + 25 * WEIGHT_PER_MICROS] fn free(origin, index: T::AccountIndex) { let who = ensure_signed(origin)?; Accounts::::try_mutate(index, |maybe_value| -> DispatchResult { - let (account, amount) = maybe_value.take().ok_or(Error::::NotAssigned)?; + let (account, amount, perm) = maybe_value.take().ok_or(Error::::NotAssigned)?; + ensure!(!perm, Error::::Permanent); ensure!(&account == &who, Error::::NotOwner); T::Currency::unreserve(&who, amount); Ok(()) @@ -192,6 +231,7 @@ decl_module! { /// /// - `index`: the index to be (re-)assigned. /// - `new`: the new owner of the index. This function is a no-op if it is equal to sender. + /// - `freeze`: if set to `true`, will freeze the index so it cannot be transferred. /// /// Emits `IndexAssigned` if successful. /// @@ -200,19 +240,57 @@ decl_module! { /// - One storage mutation (codec `O(1)`). /// - Up to one reserve operation. /// - One event. + /// ------------------- + /// - Base Weight: 26.83 µs + /// - DB Weight: + /// - Reads: Indices Accounts, System Account (original owner) + /// - Writes: Indices Accounts, System Account (original owner) /// # - #[weight = 0] - fn force_transfer(origin, new: T::AccountId, index: T::AccountIndex) { + #[weight = T::DbWeight::get().reads_writes(2, 2) + 25 * WEIGHT_PER_MICROS] + fn force_transfer(origin, new: T::AccountId, index: T::AccountIndex, freeze: bool) { ensure_root(origin)?; Accounts::::mutate(index, |maybe_value| { - if let Some((account, amount)) = maybe_value.take() { + if let Some((account, amount, _)) = maybe_value.take() { T::Currency::unreserve(&account, amount); } - *maybe_value = Some((new.clone(), Zero::zero())); + *maybe_value = Some((new.clone(), Zero::zero(), freeze)); }); Self::deposit_event(RawEvent::IndexAssigned(new, index)); } + + /// Freeze an index so it will always point to the sender account. This consumes the deposit. + /// + /// The dispatch origin for this call must be _Signed_ and the signing account must have a + /// non-frozen account `index`. + /// + /// - `index`: the index to be frozen in place. + /// + /// Emits `IndexFrozen` if successful. + /// + /// # + /// - `O(1)`. + /// - One storage mutation (codec `O(1)`). + /// - Up to one slash operation. + /// - One event. + /// ------------------- + /// - Base Weight: 30.86 µs + /// - DB Weight: 1 Read/Write (Accounts) + /// # + #[weight = T::DbWeight::get().reads_writes(1, 1) + 30 * WEIGHT_PER_MICROS] + fn freeze(origin, index: T::AccountIndex) { + let who = ensure_signed(origin)?; + + Accounts::::try_mutate(index, |maybe_value| -> DispatchResult { + let (account, amount, perm) = maybe_value.take().ok_or(Error::::NotAssigned)?; + ensure!(!perm, Error::::Permanent); + ensure!(&account == &who, Error::::NotOwner); + T::Currency::slash_reserved(&who, amount); + *maybe_value = Some((account, Zero::zero(), true)); + Ok(()) + })?; + Self::deposit_event(RawEvent::IndexFrozen(index, who)); + } } } diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index aa7057e61a1dce71904cc89c46410a7069059574..97e7a954f8f58876497edf1a2cc431ac56a6ec5a 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Test utilities @@ -49,6 +50,7 @@ parameter_types! { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Call = (); type Index = u64; @@ -64,6 +66,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -71,6 +74,7 @@ impl frame_system::Trait for Test { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { @@ -83,6 +87,7 @@ impl pallet_balances::Trait for Test { type Event = MetaEvent; type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { @@ -94,6 +99,7 @@ impl Trait for Test { type Currency = Balances; type Deposit = Deposit; type Event = MetaEvent; + type WeightInfo = (); } pub fn new_test_ext() -> sp_io::TestExternalities { diff --git a/frame/indices/src/tests.rs b/frame/indices/src/tests.rs index 9e434cfbe2a1c299ff2f16988c3b350af494d2fc..e288871d5530739f07aa0212d9721f681d1c1912 100644 --- a/frame/indices/src/tests.rs +++ b/frame/indices/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Tests for the module. @@ -47,6 +48,20 @@ fn freeing_should_work() { }); } +#[test] +fn freezing_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Indices::claim(Some(1).into(), 0)); + assert_noop!(Indices::freeze(Some(1).into(), 1), Error::::NotAssigned); + assert_noop!(Indices::freeze(Some(2).into(), 0), Error::::NotOwner); + assert_ok!(Indices::freeze(Some(1).into(), 0)); + assert_noop!(Indices::freeze(Some(1).into(), 0), Error::::Permanent); + + assert_noop!(Indices::free(Some(1).into(), 0), Error::::Permanent); + assert_noop!(Indices::transfer(Some(1).into(), 2, 0), Error::::Permanent); + }); +} + #[test] fn indexing_lookup_should_work() { new_test_ext().execute_with(|| { @@ -86,7 +101,7 @@ fn transfer_index_on_accounts_should_work() { fn force_transfer_index_on_preowned_should_work() { new_test_ext().execute_with(|| { assert_ok!(Indices::claim(Some(1).into(), 0)); - assert_ok!(Indices::force_transfer(Origin::ROOT, 3, 0)); + assert_ok!(Indices::force_transfer(Origin::root(), 3, 0, false)); assert_eq!(Balances::reserved_balance(1), 0); assert_eq!(Balances::reserved_balance(3), 0); assert_eq!(Indices::lookup_index(0), Some(3)); @@ -96,7 +111,7 @@ fn force_transfer_index_on_preowned_should_work() { #[test] fn force_transfer_index_on_free_should_work() { new_test_ext().execute_with(|| { - assert_ok!(Indices::force_transfer(Origin::ROOT, 3, 0)); + assert_ok!(Indices::force_transfer(Origin::root(), 3, 0, false)); assert_eq!(Balances::reserved_balance(3), 0); assert_eq!(Indices::lookup_index(0), Some(3)); }); diff --git a/frame/membership/Cargo.toml b/frame/membership/Cargo.toml index 742cc124a295a9cb2a8d664aa88eb3883f5834f6..8ebcce3de784c11f7aa5dd6eea6d6aed4a7dfce5 100644 --- a/frame/membership/Cargo.toml +++ b/frame/membership/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-membership" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME membership management pallet" @@ -13,15 +13,15 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/membership/README.md b/frame/membership/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a769be497050e1c2f0fc6e2be2d218f6239fff02 --- /dev/null +++ b/frame/membership/README.md @@ -0,0 +1,6 @@ +# Membership Module + +Allows control of membership of a set of `AccountId`s, useful for managing membership of of a +collective. A prime member may be set. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index faf2be8e11e5eb77f77bd2406f4cc6aec7379407..2bc4a440b8d475b9b4aa6c34db37922fcb72fffa 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Membership Module //! @@ -25,9 +26,9 @@ use sp_std::prelude::*; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, - traits::{ChangeMembers, InitializeMembers, EnsureOrigin}, + traits::{ChangeMembers, InitializeMembers, EnsureOrigin, Contains}, }; -use frame_system::{self as system, ensure_root, ensure_signed}; +use frame_system::ensure_signed; pub trait Trait: frame_system::Trait { /// The overarching event type. @@ -116,12 +117,10 @@ decl_module! { /// Add a member `who` to the set. /// - /// May only be called from `AddOrigin` or root. + /// May only be called from `T::AddOrigin`. #[weight = 50_000_000] - fn add_member(origin, who: T::AccountId) { - T::AddOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + pub fn add_member(origin, who: T::AccountId) { + T::AddOrigin::ensure_origin(origin)?; let mut members = >::get(); let location = members.binary_search(&who).err().ok_or(Error::::AlreadyMember)?; @@ -135,12 +134,10 @@ decl_module! { /// Remove a member `who` from the set. /// - /// May only be called from `RemoveOrigin` or root. + /// May only be called from `T::RemoveOrigin`. #[weight = 50_000_000] - fn remove_member(origin, who: T::AccountId) { - T::RemoveOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + pub fn remove_member(origin, who: T::AccountId) { + T::RemoveOrigin::ensure_origin(origin)?; let mut members = >::get(); let location = members.binary_search(&who).ok().ok_or(Error::::NotMember)?; @@ -155,14 +152,12 @@ decl_module! { /// Swap out one member `remove` for another `add`. /// - /// May only be called from `SwapOrigin` or root. + /// May only be called from `T::SwapOrigin`. /// /// Prime membership is *not* passed from `remove` to `add`, if extant. #[weight = 50_000_000] - fn swap_member(origin, remove: T::AccountId, add: T::AccountId) { - T::SwapOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + pub fn swap_member(origin, remove: T::AccountId, add: T::AccountId) { + T::SwapOrigin::ensure_origin(origin)?; if remove == add { return Ok(()) } @@ -186,12 +181,10 @@ decl_module! { /// Change the membership to a new set, disregarding the existing membership. Be nice and /// pass `members` pre-sorted. /// - /// May only be called from `ResetOrigin` or root. + /// May only be called from `T::ResetOrigin`. #[weight = 50_000_000] - fn reset_members(origin, members: Vec) { - T::ResetOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + pub fn reset_members(origin, members: Vec) { + T::ResetOrigin::ensure_origin(origin)?; let mut members = members; members.sort(); @@ -211,7 +204,7 @@ decl_module! { /// /// Prime membership is passed from the origin account to `new`, if extant. #[weight = 50_000_000] - fn change_key(origin, new: T::AccountId) { + pub fn change_key(origin, new: T::AccountId) { let remove = ensure_signed(origin)?; if remove != new { @@ -238,22 +231,22 @@ decl_module! { } /// Set the prime member. Must be a current member. + /// + /// May only be called from `T::PrimeOrigin`. #[weight = 50_000_000] - fn set_prime(origin, who: T::AccountId) { - T::PrimeOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + pub fn set_prime(origin, who: T::AccountId) { + T::PrimeOrigin::ensure_origin(origin)?; Self::members().binary_search(&who).ok().ok_or(Error::::NotMember)?; Prime::::put(&who); T::MembershipChanged::set_prime(Some(who)); } /// Remove the prime member if it exists. + /// + /// May only be called from `T::PrimeOrigin`. #[weight = 50_000_000] - fn clear_prime(origin) { - T::PrimeOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + pub fn clear_prime(origin) { + T::PrimeOrigin::ensure_origin(origin)?; Prime::::kill(); T::MembershipChanged::set_prime(None); } @@ -271,6 +264,16 @@ impl, I: Instance> Module { } } +impl, I: Instance> Contains for Module { + fn sorted_members() -> Vec { + Self::members() + } + + fn count() -> usize { + Members::::decode_len().unwrap_or(0) + } +} + #[cfg(test)] mod tests { use super::*; @@ -281,18 +284,13 @@ mod tests { ord_parameter_types }; use sp_core::H256; - // The testing primitives are very useful for avoiding having to work with signatures - // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, testing::Header}; use frame_system::EnsureSignedBy; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } - // For testing the pallet, we construct most of a mock runtime. This means - // first constructing a configuration type (`Test`) which `impl`s each of the - // configuration traits of pallets we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -302,6 +300,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -317,6 +316,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -324,6 +324,7 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } ord_parameter_types! { pub const One: u64 = 1; @@ -375,8 +376,6 @@ mod tests { type Membership = Module; - // This function basically just builds a genesis storage key/value store according to - // our desired mockup. fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. diff --git a/frame/metadata/Cargo.toml b/frame/metadata/Cargo.toml index 73418be9b2b69295cd8cfd088be1161b0cf8e6b8..7e2cb28f5e43dafaf1cbf2255b8317012f451187 100644 --- a/frame/metadata/Cargo.toml +++ b/frame/metadata/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-metadata" -version = "11.0.0-dev" +version = "11.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Decodable variant of the RuntimeMetadata." @@ -12,10 +12,10 @@ description = "Decodable variant of the RuntimeMetadata." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/metadata/README.md b/frame/metadata/README.md new file mode 100644 index 0000000000000000000000000000000000000000..423af8602e3f013fa4632e62da9399bd1901806e --- /dev/null +++ b/frame/metadata/README.md @@ -0,0 +1,7 @@ +Decodable variant of the RuntimeMetadata. + +This really doesn't belong here, but is necessary for the moment. In the future +it should be removed entirely to an external module for shimming on to the +codec-encoded metadata. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/metadata/src/lib.rs b/frame/metadata/src/lib.rs index bec69999b2187338ea48c5f57941105c70fbc691..c0eeb76b6f97625179caa47bb08b7232ea1835ca 100644 --- a/frame/metadata/src/lib.rs +++ b/frame/metadata/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Decodable variant of the RuntimeMetadata. //! diff --git a/frame/multisig/Cargo.toml b/frame/multisig/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..98db6477e3efb3959b7de18bff92ba4b702265a0 --- /dev/null +++ b/frame/multisig/Cargo.toml @@ -0,0 +1,44 @@ +[package] +name = "pallet-multisig" +version = "2.0.0-rc6" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME multi-signature dispatch pallet" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +serde = { version = "1.0.101", optional = true } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } + +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } + +[dev-dependencies] +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "sp-io/std", + "sp-std/std" +] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", +] diff --git a/frame/multisig/README.md b/frame/multisig/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c7694d8cb596914d37beb802544a972cdb8c427a --- /dev/null +++ b/frame/multisig/README.md @@ -0,0 +1,29 @@ +# Multisig Module +A module for doing multisig dispatch. + +- [`multisig::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +This module contains functionality for multi-signature dispatch, a (potentially) stateful +operation, allowing multiple signed +origins (accounts) to coordinate and dispatch a call from a well-known origin, derivable +deterministically from the set of account IDs and the threshold number of accounts from the +set that must approve it. In the case that the threshold is just one then this is a stateless +operation. This is useful for multisig wallets where cryptographic threshold signatures are +not available or desired. + +## Interface + +### Dispatchable Functions + +* `as_multi` - Approve and if possible dispatch a call from a composite origin formed from a + number of signed origins. +* `approve_as_multi` - Approve a call from a composite origin. +* `cancel_as_multi` - Cancel a call from a composite origin. + +[`Call`]: ./enum.Call.html +[`Trait`]: ./trait.Trait.html + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/multisig/src/benchmarking.rs b/frame/multisig/src/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..8113d179cd1576c43dfb0418dbcf94327f63b44b --- /dev/null +++ b/frame/multisig/src/benchmarking.rs @@ -0,0 +1,289 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +// Benchmarks for Multisig Pallet + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use frame_system::RawOrigin; +use frame_benchmarking::{benchmarks, account}; +use sp_runtime::traits::Bounded; +use core::convert::TryInto; + +use crate::Module as Multisig; + +const SEED: u32 = 0; + +fn setup_multi(s: u32, z: u32) + -> Result<(Vec, Vec), &'static str> +{ + let mut signatories: Vec = Vec::new(); + for i in 0 .. s { + let signatory = account("signatory", i, SEED); + // Give them some balance for a possible deposit + let balance = BalanceOf::::max_value(); + T::Currency::make_free_balance_be(&signatory, balance); + signatories.push(signatory); + } + signatories.sort(); + // Must first convert to outer call type. + let call: ::Call = frame_system::Call::::remark(vec![0; z as usize]).into(); + let call_data = call.encode(); + return Ok((signatories, call_data)) +} + +benchmarks! { + _ { } + + as_multi_threshold_1 { + // Transaction Length + let z in 0 .. 10_000; + let max_signatories = T::MaxSignatories::get().into(); + let (mut signatories, _) = setup_multi::(max_signatories, z)?; + let call: ::Call = frame_system::Call::::remark(vec![0; z as usize]).into(); + let call_hash = call.using_encoded(blake2_256); + let multi_account_id = Multisig::::multi_account_id(&signatories, 1); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + }: _(RawOrigin::Signed(caller.clone()), signatories, Box::new(call)) + verify { + // If the benchmark resolves, then the call was dispatched successfully. + } + + as_multi_create { + // Signatories, need at least 2 total people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let call_hash = blake2_256(&call); + let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + }: as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call, false, 0) + verify { + assert!(Multisigs::::contains_key(multi_account_id, call_hash)); + } + + as_multi_create_store { + // Signatories, need at least 2 total people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let call_hash = blake2_256(&call); + let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + }: as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call, true, 0) + verify { + assert!(Multisigs::::contains_key(multi_account_id, call_hash)); + assert!(Calls::::contains_key(call_hash)); + } + + as_multi_approve { + // Signatories, need at least 3 people (so we don't complete the multisig) + let s in 3 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let call_hash = blake2_256(&call); + let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); + let mut signatories2 = signatories.clone(); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + // before the call, get the timepoint + let timepoint = Multisig::::timepoint(); + // Create the multi, storing for worst case + Multisig::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone(), true, 0)?; + let caller2 = signatories2.remove(0); + }: as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call, false, 0) + verify { + let multisig = Multisigs::::get(multi_account_id, call_hash).ok_or("multisig not created")?; + assert_eq!(multisig.approvals.len(), 2); + } + + as_multi_complete { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let call_hash = blake2_256(&call); + let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); + let mut signatories2 = signatories.clone(); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + // before the call, get the timepoint + let timepoint = Multisig::::timepoint(); + // Create the multi, storing it for worst case + Multisig::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone(), true, 0)?; + // Everyone except the first person approves + for i in 1 .. s - 1 { + let mut signatories_loop = signatories2.clone(); + let caller_loop = signatories_loop.remove(i as usize); + let o = RawOrigin::Signed(caller_loop).into(); + Multisig::::as_multi(o, s as u16, signatories_loop, Some(timepoint), call.clone(), false, 0)?; + } + let caller2 = signatories2.remove(0); + assert!(Multisigs::::contains_key(&multi_account_id, call_hash)); + }: as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call, false, Weight::max_value()) + verify { + assert!(!Multisigs::::contains_key(&multi_account_id, call_hash)); + } + + approve_as_multi_create { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + let call_hash = blake2_256(&call); + // Create the multi + }: approve_as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call_hash, 0) + verify { + assert!(Multisigs::::contains_key(multi_account_id, call_hash)); + } + + approve_as_multi_approve { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let mut signatories2 = signatories.clone(); + let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + let call_hash = blake2_256(&call); + // before the call, get the timepoint + let timepoint = Multisig::::timepoint(); + // Create the multi + Multisig::::as_multi( + RawOrigin::Signed(caller.clone()).into(), + s as u16, + signatories, + None, + call.clone(), + false, + 0 + )?; + let caller2 = signatories2.remove(0); + }: approve_as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call_hash, 0) + verify { + let multisig = Multisigs::::get(multi_account_id, call_hash).ok_or("multisig not created")?; + assert_eq!(multisig.approvals.len(), 2); + } + + approve_as_multi_complete { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); + let mut signatories2 = signatories.clone(); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + let call_hash = blake2_256(&call); + // before the call, get the timepoint + let timepoint = Multisig::::timepoint(); + // Create the multi + Multisig::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone(), true, 0)?; + // Everyone except the first person approves + for i in 1 .. s - 1 { + let mut signatories_loop = signatories2.clone(); + let caller_loop = signatories_loop.remove(i as usize); + let o = RawOrigin::Signed(caller_loop).into(); + Multisig::::as_multi(o, s as u16, signatories_loop, Some(timepoint), call.clone(), false, 0)?; + } + let caller2 = signatories2.remove(0); + assert!(Multisigs::::contains_key(&multi_account_id, call_hash)); + }: approve_as_multi( + RawOrigin::Signed(caller2), + s as u16, + signatories2, + Some(timepoint), + call_hash, + Weight::max_value() + ) + verify { + assert!(!Multisigs::::contains_key(multi_account_id, call_hash)); + } + + cancel_as_multi { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + let call_hash = blake2_256(&call); + let timepoint = Multisig::::timepoint(); + // Create the multi + let o = RawOrigin::Signed(caller.clone()).into(); + Multisig::::as_multi(o, s as u16, signatories.clone(), None, call.clone(), true, 0)?; + assert!(Multisigs::::contains_key(&multi_account_id, call_hash)); + }: _(RawOrigin::Signed(caller), s as u16, signatories, timepoint, call_hash) + verify { + assert!(!Multisigs::::contains_key(multi_account_id, call_hash)); + } + + cancel_as_multi_store { + // Signatories, need at least 2 people + let s in 2 .. T::MaxSignatories::get() as u32; + // Transaction Length + let z in 0 .. 10_000; + let (mut signatories, call) = setup_multi::(s, z)?; + let multi_account_id = Multisig::::multi_account_id(&signatories, s.try_into().unwrap()); + let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + let call_hash = blake2_256(&call); + let timepoint = Multisig::::timepoint(); + // Create the multi + let o = RawOrigin::Signed(caller.clone()).into(); + Multisig::::as_multi(o, s as u16, signatories.clone(), None, call.clone(), true, 0)?; + assert!(Multisigs::::contains_key(&multi_account_id, call_hash)); + assert!(Calls::::contains_key(call_hash)); + }: cancel_as_multi(RawOrigin::Signed(caller), s as u16, signatories, timepoint, call_hash) + verify { + assert!(!Multisigs::::contains_key(&multi_account_id, call_hash)); + assert!(!Calls::::contains_key(call_hash)); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_as_multi_threshold_1::()); + assert_ok!(test_benchmark_as_multi_create::()); + assert_ok!(test_benchmark_as_multi_create_store::()); + assert_ok!(test_benchmark_as_multi_approve::()); + assert_ok!(test_benchmark_as_multi_complete::()); + assert_ok!(test_benchmark_approve_as_multi_create::()); + assert_ok!(test_benchmark_approve_as_multi_approve::()); + assert_ok!(test_benchmark_approve_as_multi_complete::()); + assert_ok!(test_benchmark_cancel_as_multi::()); + assert_ok!(test_benchmark_cancel_as_multi_store::()); + }); + } +} diff --git a/frame/multisig/src/lib.rs b/frame/multisig/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..f8f6e8ed63bc98a49464e01a4263abeb775f007c --- /dev/null +++ b/frame/multisig/src/lib.rs @@ -0,0 +1,730 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! # Multisig Module +//! A module for doing multisig dispatch. +//! +//! - [`multisig::Trait`](./trait.Trait.html) +//! - [`Call`](./enum.Call.html) +//! +//! ## Overview +//! +//! This module contains functionality for multi-signature dispatch, a (potentially) stateful +//! operation, allowing multiple signed +//! origins (accounts) to coordinate and dispatch a call from a well-known origin, derivable +//! deterministically from the set of account IDs and the threshold number of accounts from the +//! set that must approve it. In the case that the threshold is just one then this is a stateless +//! operation. This is useful for multisig wallets where cryptographic threshold signatures are +//! not available or desired. +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! * `as_multi` - Approve and if possible dispatch a call from a composite origin formed from a +//! number of signed origins. +//! * `approve_as_multi` - Approve a call from a composite origin. +//! * `cancel_as_multi` - Cancel a call from a composite origin. +//! +//! [`Call`]: ./enum.Call.html +//! [`Trait`]: ./trait.Trait.html + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +use sp_std::prelude::*; +use codec::{Encode, Decode}; +use sp_io::hashing::blake2_256; +use frame_support::{decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug}; +use frame_support::{traits::{Get, ReservableCurrency, Currency}, + weights::{Weight, GetDispatchInfo, constants::{WEIGHT_PER_NANOS, WEIGHT_PER_MICROS}}, + dispatch::{DispatchResultWithPostInfo, DispatchErrorWithPostInfo, PostDispatchInfo}, +}; +use frame_system::{self as system, ensure_signed, RawOrigin}; +use sp_runtime::{DispatchError, DispatchResult, traits::{Dispatchable, Zero}}; + +mod tests; +mod benchmarking; + +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +/// Just a bunch of bytes, but they should decode to a valid `Call`. +pub type OpaqueCall = Vec; + +pub trait WeightInfo { + fn as_multi_threshold_1(z: u32, ) -> Weight; + fn as_multi_create(s: u32, z: u32, ) -> Weight; + fn as_multi_create_store(s: u32, z: u32, ) -> Weight; + fn as_multi_approve(s: u32, z: u32, ) -> Weight; + fn as_multi_complete(s: u32, z: u32, ) -> Weight; + fn approve_as_multi_create(s: u32, z: u32, ) -> Weight; + fn approve_as_multi_approve(s: u32, z: u32, ) -> Weight; + fn approve_as_multi_complete(s: u32, z: u32, ) -> Weight; + fn cancel_as_multi(s: u32, z: u32, ) -> Weight; + fn cancel_as_multi_store(s: u32, z: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn as_multi_threshold_1(_z: u32, ) -> Weight { 1_000_000_000 } + fn as_multi_create(_s: u32, _z: u32, ) -> Weight { 1_000_000_000 } + fn as_multi_create_store(_s: u32, _z: u32, ) -> Weight { 1_000_000_000 } + fn as_multi_approve(_s: u32, _z: u32, ) -> Weight { 1_000_000_000 } + fn as_multi_complete(_s: u32, _z: u32, ) -> Weight { 1_000_000_000 } + fn approve_as_multi_create(_s: u32, _z: u32, ) -> Weight { 1_000_000_000 } + fn approve_as_multi_approve(_s: u32, _z: u32, ) -> Weight { 1_000_000_000 } + fn approve_as_multi_complete(_s: u32, _z: u32, ) -> Weight { 1_000_000_000 } + fn cancel_as_multi(_s: u32, _z: u32, ) -> Weight { 1_000_000_000 } + fn cancel_as_multi_store(_s: u32, _z: u32, ) -> Weight { 1_000_000_000 } +} + +/// Configuration trait. +pub trait Trait: frame_system::Trait { + /// The overarching event type. + type Event: From> + Into<::Event>; + + /// The overarching call type. + type Call: Parameter + Dispatchable + + GetDispatchInfo + From>; + + /// The currency mechanism. + type Currency: ReservableCurrency; + + /// The base amount of currency needed to reserve for creating a multisig execution or to store + /// a dispatch call for later. + /// + /// This is held for an additional storage item whose value size is + /// `4 + sizeof((BlockNumber, Balance, AccountId))` bytes and whose key size is + /// `32 + sizeof(AccountId)` bytes. + type DepositBase: Get>; + + /// The amount of currency needed per unit threshold when creating a multisig execution. + /// + /// This is held for adding 32 bytes more into a pre-existing storage value. + type DepositFactor: Get>; + + /// The maximum amount of signatories allowed in the multisig. + type MaxSignatories: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; +} + +/// A global extrinsic index, formed as the extrinsic index within a block, together with that +/// block's height. This allows a transaction in which a multisig operation of a particular +/// composite was created to be uniquely identified. +#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug)] +pub struct Timepoint { + /// The height of the chain at the point in time. + height: BlockNumber, + /// The index of the extrinsic at the point in time. + index: u32, +} + +/// An open multisig operation. +#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug)] +pub struct Multisig { + /// The extrinsic when the multisig operation was opened. + when: Timepoint, + /// The amount held in reserve of the `depositor`, to be returned once the operation ends. + deposit: Balance, + /// The account who opened it (i.e. the first to approve it). + depositor: AccountId, + /// The approvals achieved so far, including the depositor. Always sorted. + approvals: Vec, +} + +decl_storage! { + trait Store for Module as Multisig { + /// The set of open multisig operations. + pub Multisigs: double_map + hasher(twox_64_concat) T::AccountId, hasher(blake2_128_concat) [u8; 32] + => Option, T::AccountId>>; + + pub Calls: map hasher(identity) [u8; 32] => Option<(OpaqueCall, T::AccountId, BalanceOf)>; + } +} + +decl_error! { + pub enum Error for Module { + /// Threshold must be 2 or greater. + MinimumThreshold, + /// Call is already approved by this signatory. + AlreadyApproved, + /// Call doesn't need any (more) approvals. + NoApprovalsNeeded, + /// There are too few signatories in the list. + TooFewSignatories, + /// There are too many signatories in the list. + TooManySignatories, + /// The signatories were provided out of order; they should be ordered. + SignatoriesOutOfOrder, + /// The sender was contained in the other signatories; it shouldn't be. + SenderInSignatories, + /// Multisig operation not found when attempting to cancel. + NotFound, + /// Only the account that originally created the multisig is able to cancel it. + NotOwner, + /// No timepoint was given, yet the multisig operation is already underway. + NoTimepoint, + /// A different timepoint was given to the multisig operation that is underway. + WrongTimepoint, + /// A timepoint was given, yet no multisig operation is underway. + UnexpectedTimepoint, + /// The maximum weight information provided was too low. + WeightTooLow, + /// The data to be stored is already stored. + AlreadyStored, + } +} + +decl_event! { + /// Events type. + pub enum Event where + AccountId = ::AccountId, + BlockNumber = ::BlockNumber, + CallHash = [u8; 32] + { + /// A new multisig operation has begun. [approving, multisig, call_hash] + NewMultisig(AccountId, AccountId, CallHash), + /// A multisig operation has been approved by someone. [approving, timepoint, multisig, call_hash] + MultisigApproval(AccountId, Timepoint, AccountId, CallHash), + /// A multisig operation has been executed. [approving, timepoint, multisig, call_hash] + MultisigExecuted(AccountId, Timepoint, AccountId, CallHash, DispatchResult), + /// A multisig operation has been cancelled. [cancelling, timepoint, multisig, call_hash] + MultisigCancelled(AccountId, Timepoint, AccountId, CallHash), + } +} + +mod weight_of { + use super::*; + + /// - Base Weight: 33.72 + 0.002 * Z µs + /// - DB Weight: None + /// - Plus Call Weight + pub fn as_multi_threshold_1( + call_len: usize, + call_weight: Weight, + ) -> Weight { + (34 * WEIGHT_PER_MICROS) + .saturating_add((2 * WEIGHT_PER_NANOS).saturating_mul(call_len as Weight)) + .saturating_add(call_weight) + } + + /// - Base Weight: + /// - Create: 38.82 + 0.121 * S + .001 * Z µs + /// - Create w/ Store: 54.22 + 0.120 * S + .003 * Z µs + /// - Approve: 29.86 + 0.143 * S + .001 * Z µs + /// - Complete: 39.55 + 0.267 * S + .002 * Z µs + /// - DB Weight: + /// - Reads: Multisig Storage, [Caller Account], Calls, Depositor Account + /// - Writes: Multisig Storage, [Caller Account], Calls, Depositor Account + /// - Plus Call Weight + pub fn as_multi( + sig_len: usize, + call_len: usize, + call_weight: Weight, + calls_write: bool, + refunded: bool, + ) -> Weight { + call_weight + .saturating_add(55 * WEIGHT_PER_MICROS) + .saturating_add((250 * WEIGHT_PER_NANOS).saturating_mul(sig_len as Weight)) + .saturating_add((3 * WEIGHT_PER_NANOS).saturating_mul(call_len as Weight)) + .saturating_add(T::DbWeight::get().reads_writes(1, 1)) // Multisig read/write + .saturating_add(T::DbWeight::get().reads(1)) // Calls read + .saturating_add(T::DbWeight::get().writes(calls_write.into())) // Calls write + .saturating_add(T::DbWeight::get().reads_writes(refunded.into(), refunded.into())) // Deposit refunded + } +} + +enum CallOrHash { + Call(OpaqueCall, bool), + Hash([u8; 32]), +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + + /// Deposit one of this module's events by using the default implementation. + fn deposit_event() = default; + + /// Immediately dispatch a multi-signature call using a single approval from the caller. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `other_signatories`: The accounts (other than the sender) who are part of the + /// multi-signature, but do not participate in the approval process. + /// - `call`: The call to be executed. + /// + /// Result is equivalent to the dispatched result. + /// + /// # + /// O(Z + C) where Z is the length of the call and C its execution weight. + /// ------------------------------- + /// - Base Weight: 33.72 + 0.002 * Z µs + /// - DB Weight: None + /// - Plus Call Weight + /// # + #[weight = ( + weight_of::as_multi_threshold_1::( + call.using_encoded(|c| c.len()), + call.get_dispatch_info().weight + ), + call.get_dispatch_info().class, + )] + fn as_multi_threshold_1(origin, + other_signatories: Vec, + call: Box<::Call>, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let max_sigs = T::MaxSignatories::get() as usize; + ensure!(!other_signatories.is_empty(), Error::::TooFewSignatories); + let other_signatories_len = other_signatories.len(); + ensure!(other_signatories_len < max_sigs, Error::::TooManySignatories); + let signatories = Self::ensure_sorted_and_insert(other_signatories, who)?; + + let id = Self::multi_account_id(&signatories, 1); + + let call_len = call.using_encoded(|c| c.len()); + let result = call.dispatch(RawOrigin::Signed(id).into()); + + result.map(|post_dispatch_info| post_dispatch_info.actual_weight + .map(|actual_weight| weight_of::as_multi_threshold_1::( + call_len, + actual_weight, + )) + .into() + ).map_err(|err| match err.post_info.actual_weight { + Some(actual_weight) => { + let weight_used = weight_of::as_multi_threshold_1::( + call_len, + actual_weight, + ); + let post_info = Some(weight_used).into(); + let error = err.error.into(); + DispatchErrorWithPostInfo { post_info, error } + }, + None => err, + }) + } + + /// Register approval for a dispatch to be made from a deterministic composite account if + /// approved by a total of `threshold - 1` of `other_signatories`. + /// + /// If there are enough, then dispatch the call. + /// + /// Payment: `DepositBase` will be reserved if this is the first approval, plus + /// `threshold` times `DepositFactor`. It is returned once this dispatch happens or + /// is cancelled. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `threshold`: The total number of approvals for this dispatch before it is executed. + /// - `other_signatories`: The accounts (other than the sender) who can approve this + /// dispatch. May not be empty. + /// - `maybe_timepoint`: If this is the first approval, then this must be `None`. If it is + /// not the first approval, then it must be `Some`, with the timepoint (block number and + /// transaction index) of the first approval transaction. + /// - `call`: The call to be executed. + /// + /// NOTE: Unless this is the final approval, you will generally want to use + /// `approve_as_multi` instead, since it only requires a hash of the call. + /// + /// Result is equivalent to the dispatched result if `threshold` is exactly `1`. Otherwise + /// on success, result is `Ok` and the result from the interior call, if it was executed, + /// may be found in the deposited `MultisigExecuted` event. + /// + /// # + /// - `O(S + Z + Call)`. + /// - Up to one balance-reserve or unreserve operation. + /// - One passthrough operation, one insert, both `O(S)` where `S` is the number of + /// signatories. `S` is capped by `MaxSignatories`, with weight being proportional. + /// - One call encode & hash, both of complexity `O(Z)` where `Z` is tx-len. + /// - One encode & hash, both of complexity `O(S)`. + /// - Up to one binary search and insert (`O(logS + S)`). + /// - I/O: 1 read `O(S)`, up to 1 mutate `O(S)`. Up to one remove. + /// - One event. + /// - The weight of the `call`. + /// - Storage: inserts one item, value size bounded by `MaxSignatories`, with a + /// deposit taken for its lifetime of + /// `DepositBase + threshold * DepositFactor`. + /// ------------------------------- + /// - Base Weight: + /// - Create: 41.89 + 0.118 * S + .002 * Z µs + /// - Create w/ Store: 53.57 + 0.119 * S + .003 * Z µs + /// - Approve: 31.39 + 0.136 * S + .002 * Z µs + /// - Complete: 39.94 + 0.26 * S + .002 * Z µs + /// - DB Weight: + /// - Reads: Multisig Storage, [Caller Account], Calls (if `store_call`) + /// - Writes: Multisig Storage, [Caller Account], Calls (if `store_call`) + /// - Plus Call Weight + /// # + #[weight = weight_of::as_multi::( + other_signatories.len(), + call.len(), + *max_weight, + true, // assume worst case: calls write + true, // assume worst case: refunded + )] + fn as_multi(origin, + threshold: u16, + other_signatories: Vec, + maybe_timepoint: Option>, + call: OpaqueCall, + store_call: bool, + max_weight: Weight, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + Self::operate(who, threshold, other_signatories, maybe_timepoint, CallOrHash::Call(call, store_call), max_weight) + } + + /// Register approval for a dispatch to be made from a deterministic composite account if + /// approved by a total of `threshold - 1` of `other_signatories`. + /// + /// Payment: `DepositBase` will be reserved if this is the first approval, plus + /// `threshold` times `DepositFactor`. It is returned once this dispatch happens or + /// is cancelled. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `threshold`: The total number of approvals for this dispatch before it is executed. + /// - `other_signatories`: The accounts (other than the sender) who can approve this + /// dispatch. May not be empty. + /// - `maybe_timepoint`: If this is the first approval, then this must be `None`. If it is + /// not the first approval, then it must be `Some`, with the timepoint (block number and + /// transaction index) of the first approval transaction. + /// - `call_hash`: The hash of the call to be executed. + /// + /// NOTE: If this is the final approval, you will want to use `as_multi` instead. + /// + /// # + /// - `O(S)`. + /// - Up to one balance-reserve or unreserve operation. + /// - One passthrough operation, one insert, both `O(S)` where `S` is the number of + /// signatories. `S` is capped by `MaxSignatories`, with weight being proportional. + /// - One encode & hash, both of complexity `O(S)`. + /// - Up to one binary search and insert (`O(logS + S)`). + /// - I/O: 1 read `O(S)`, up to 1 mutate `O(S)`. Up to one remove. + /// - One event. + /// - Storage: inserts one item, value size bounded by `MaxSignatories`, with a + /// deposit taken for its lifetime of + /// `DepositBase + threshold * DepositFactor`. + /// ---------------------------------- + /// - Base Weight: + /// - Create: 44.71 + 0.088 * S + /// - Approve: 31.48 + 0.116 * S + /// - DB Weight: + /// - Read: Multisig Storage, [Caller Account] + /// - Write: Multisig Storage, [Caller Account] + /// # + #[weight = weight_of::as_multi::( + other_signatories.len(), + 0, // call_len is zero in this case + *max_weight, + true, // assume worst case: calls write + true, // assume worst case: refunded + )] + fn approve_as_multi(origin, + threshold: u16, + other_signatories: Vec, + maybe_timepoint: Option>, + call_hash: [u8; 32], + max_weight: Weight, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + Self::operate(who, threshold, other_signatories, maybe_timepoint, CallOrHash::Hash(call_hash), max_weight) + } + + /// Cancel a pre-existing, on-going multisig transaction. Any deposit reserved previously + /// for this operation will be unreserved on success. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `threshold`: The total number of approvals for this dispatch before it is executed. + /// - `other_signatories`: The accounts (other than the sender) who can approve this + /// dispatch. May not be empty. + /// - `timepoint`: The timepoint (block number and transaction index) of the first approval + /// transaction for this dispatch. + /// - `call_hash`: The hash of the call to be executed. + /// + /// # + /// - `O(S)`. + /// - Up to one balance-reserve or unreserve operation. + /// - One passthrough operation, one insert, both `O(S)` where `S` is the number of + /// signatories. `S` is capped by `MaxSignatories`, with weight being proportional. + /// - One encode & hash, both of complexity `O(S)`. + /// - One event. + /// - I/O: 1 read `O(S)`, one remove. + /// - Storage: removes one item. + /// ---------------------------------- + /// - Base Weight: 36.07 + 0.124 * S + /// - DB Weight: + /// - Read: Multisig Storage, [Caller Account], Refund Account, Calls + /// - Write: Multisig Storage, [Caller Account], Refund Account, Calls + /// # + #[weight = T::DbWeight::get().reads_writes(3, 3) + .saturating_add(36 * WEIGHT_PER_MICROS) + .saturating_add((other_signatories.len() as Weight).saturating_mul(100 * WEIGHT_PER_NANOS)) + ] + fn cancel_as_multi(origin, + threshold: u16, + other_signatories: Vec, + timepoint: Timepoint, + call_hash: [u8; 32], + ) -> DispatchResult { + let who = ensure_signed(origin)?; + ensure!(threshold >= 2, Error::::MinimumThreshold); + let max_sigs = T::MaxSignatories::get() as usize; + ensure!(!other_signatories.is_empty(), Error::::TooFewSignatories); + ensure!(other_signatories.len() < max_sigs, Error::::TooManySignatories); + let signatories = Self::ensure_sorted_and_insert(other_signatories, who.clone())?; + + let id = Self::multi_account_id(&signatories, threshold); + + let m = >::get(&id, call_hash) + .ok_or(Error::::NotFound)?; + ensure!(m.when == timepoint, Error::::WrongTimepoint); + ensure!(m.depositor == who, Error::::NotOwner); + + let _ = T::Currency::unreserve(&m.depositor, m.deposit); + >::remove(&id, &call_hash); + Self::clear_call(&call_hash); + + Self::deposit_event(RawEvent::MultisigCancelled(who, timepoint, id, call_hash)); + Ok(()) + } + } +} + +impl Module { + /// Derive a multi-account ID from the sorted list of accounts and the threshold that are + /// required. + /// + /// NOTE: `who` must be sorted. If it is not, then you'll get the wrong answer. + pub fn multi_account_id(who: &[T::AccountId], threshold: u16) -> T::AccountId { + let entropy = (b"modlpy/utilisuba", who, threshold).using_encoded(blake2_256); + T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() + } + + fn operate( + who: T::AccountId, + threshold: u16, + other_signatories: Vec, + maybe_timepoint: Option>, + call_or_hash: CallOrHash, + max_weight: Weight, + ) -> DispatchResultWithPostInfo { + ensure!(threshold >= 2, Error::::MinimumThreshold); + let max_sigs = T::MaxSignatories::get() as usize; + ensure!(!other_signatories.is_empty(), Error::::TooFewSignatories); + let other_signatories_len = other_signatories.len(); + ensure!(other_signatories_len < max_sigs, Error::::TooManySignatories); + let signatories = Self::ensure_sorted_and_insert(other_signatories, who.clone())?; + + let id = Self::multi_account_id(&signatories, threshold); + + // Threshold > 1; this means it's a multi-step operation. We extract the `call_hash`. + let (call_hash, call_len, maybe_call, store) = match call_or_hash { + CallOrHash::Call(call, should_store) => { + let call_hash = blake2_256(&call); + let call_len = call.len(); + (call_hash, call_len, Some(call), should_store) + } + CallOrHash::Hash(h) => (h, 0, None, false), + }; + + // Branch on whether the operation has already started or not. + if let Some(mut m) = >::get(&id, call_hash) { + // Yes; ensure that the timepoint exists and agrees. + let timepoint = maybe_timepoint.ok_or(Error::::NoTimepoint)?; + ensure!(m.when == timepoint, Error::::WrongTimepoint); + + // Ensure that either we have not yet signed or that it is at threshold. + let mut approvals = m.approvals.len() as u16; + // We only bother with the approval if we're below threshold. + let maybe_pos = m.approvals.binary_search(&who).err().filter(|_| approvals < threshold); + // Bump approvals if not yet voted and the vote is needed. + if maybe_pos.is_some() { approvals += 1; } + + // We only bother fetching/decoding call if we know that we're ready to execute. + let maybe_approved_call = if approvals >= threshold { + Self::get_call(&call_hash, maybe_call.as_ref().map(|c| c.as_ref())) + } else { None }; + + if let Some(call) = maybe_approved_call { + // verify weight + ensure!(call.get_dispatch_info().weight <= max_weight, Error::::WeightTooLow); + + // Clean up storage before executing call to avoid an possibility of reentrancy + // attack. + >::remove(&id, call_hash); + Self::clear_call(&call_hash); + T::Currency::unreserve(&m.depositor, m.deposit); + + let result = call.dispatch(RawOrigin::Signed(id.clone()).into()); + Self::deposit_event(RawEvent::MultisigExecuted( + who, timepoint, id, call_hash, result.map(|_| ()).map_err(|e| e.error) + )); + Ok(get_result_weight(result).map(|actual_weight| weight_of::as_multi::( + other_signatories_len, + call_len, + actual_weight, + true, // Call is removed + true, // User is refunded + )).into()) + } else { + // We cannot dispatch the call now; either it isn't available, or it is, but we + // don't have threshold approvals even with our signature. + + // Store the call if desired. + let stored = if let Some(data) = maybe_call.filter(|_| store) { + Self::store_call_and_reserve(who.clone(), &call_hash, data, BalanceOf::::zero())?; + true + } else { + false + }; + + if let Some(pos) = maybe_pos { + // Record approval. + m.approvals.insert(pos, who.clone()); + >::insert(&id, call_hash, m); + Self::deposit_event(RawEvent::MultisigApproval(who, timepoint, id, call_hash)); + } else { + // If we already approved and didn't store the Call, then this was useless and + // we report an error. + ensure!(stored, Error::::AlreadyApproved); + } + + // Call is not made, so the actual weight does not include call + Ok(Some(weight_of::as_multi::( + other_signatories_len, + call_len, + 0, + stored, // Call stored? + false, // No refund + )).into()) + } + } else { + // Not yet started; there should be no timepoint given. + ensure!(maybe_timepoint.is_none(), Error::::UnexpectedTimepoint); + + // Just start the operation by recording it in storage. + let deposit = T::DepositBase::get() + T::DepositFactor::get() * threshold.into(); + + // Store the call if desired. + let stored = if let Some(data) = maybe_call.filter(|_| store) { + Self::store_call_and_reserve(who.clone(), &call_hash, data, deposit)?; + true + } else { + T::Currency::reserve(&who, deposit)?; + false + }; + + >::insert(&id, call_hash, Multisig { + when: Self::timepoint(), + deposit, + depositor: who.clone(), + approvals: vec![who.clone()], + }); + Self::deposit_event(RawEvent::NewMultisig(who, id, call_hash)); + // Call is not made, so we can return that weight + return Ok(Some(weight_of::as_multi::( + other_signatories_len, + call_len, + 0, + stored, // Call stored? + false, // No refund + )).into()) + } + } + + /// Place a call's encoded data in storage, reserving funds as appropriate. + /// + /// We store `data` here because storing `call` would result in needing another `.encode`. + /// + /// Returns a `bool` indicating whether the data did end up being stored. + fn store_call_and_reserve( + who: T::AccountId, + hash: &[u8; 32], + data: OpaqueCall, + other_deposit: BalanceOf, + ) -> DispatchResult { + ensure!(!Calls::::contains_key(hash), Error::::AlreadyStored); + let deposit = other_deposit + T::DepositBase::get() + + T::DepositFactor::get() * BalanceOf::::from(((data.len() + 31) / 32) as u32); + T::Currency::reserve(&who, deposit)?; + Calls::::insert(&hash, (data, who, deposit)); + Ok(()) + } + + /// Attempt to decode and return the call, provided by the user or from storage. + fn get_call(hash: &[u8; 32], maybe_known: Option<&[u8]>) -> Option<::Call> { + maybe_known.map_or_else(|| { + Calls::::get(hash).and_then(|(data, ..)| { + Decode::decode(&mut &data[..]).ok() + }) + }, |data| { + Decode::decode(&mut &data[..]).ok() + }) + } + + /// Attempt to remove a call from storage, returning any deposit on it to the owner. + fn clear_call(hash: &[u8; 32]) { + if let Some((_, who, deposit)) = Calls::::take(hash) { + T::Currency::unreserve(&who, deposit); + } + } + + /// The current `Timepoint`. + pub fn timepoint() -> Timepoint { + Timepoint { + height: >::block_number(), + index: >::extrinsic_index().unwrap_or_default(), + } + } + + /// Check that signatories is sorted and doesn't contain sender, then insert sender. + fn ensure_sorted_and_insert(other_signatories: Vec, who: T::AccountId) + -> Result, DispatchError> + { + let mut signatories = other_signatories; + let mut maybe_last = None; + let mut index = 0; + for item in signatories.iter() { + if let Some(last) = maybe_last { + ensure!(last < item, Error::::SignatoriesOutOfOrder); + } + if item <= &who { + ensure!(item != &who, Error::::SenderInSignatories); + index += 1; + } + maybe_last = Some(item); + } + signatories.insert(index, who); + Ok(signatories) + } +} + +/// Return the weight of a dispatch call result as an `Option`. +/// +/// Will return the weight regardless of what the state of the result is. +fn get_result_weight(result: DispatchResultWithPostInfo) -> Option { + match result { + Ok(post_info) => post_info.actual_weight, + Err(err) => err.post_info.actual_weight, + } +} diff --git a/frame/multisig/src/tests.rs b/frame/multisig/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..888dcecb3a8fd9cd1a8e8f60ede7f644828d0093 --- /dev/null +++ b/frame/multisig/src/tests.rs @@ -0,0 +1,577 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +// Tests for Multisig Pallet + +#![cfg(test)] + +use super::*; + +use frame_support::{ + assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch, + weights::Weight, impl_outer_event, traits::Filter, +}; +use sp_core::H256; +use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; +use crate as multisig; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +impl_outer_event! { + pub enum TestEvent for Test { + system, + pallet_balances, + multisig, + } +} +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + frame_system::System, + pallet_balances::Balances, + multisig::Multisig, + } +} + +// For testing the pallet, we construct most of a mock runtime. This means +// first constructing a configuration type (`Test`) which `impl`s each of the +// configuration traits of pallets we want to use. +#[derive(Clone, Eq, PartialEq)] +pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl frame_system::Trait for Test { + type BaseCallFilter = TestBaseCallFilter; + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = Call; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = TestEvent; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Trait for Test { + type Balance = u64; + type Event = TestEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} +parameter_types! { + pub const DepositBase: u64 = 1; + pub const DepositFactor: u64 = 1; + pub const MaxSignatories: u16 = 3; +} +pub struct TestBaseCallFilter; +impl Filter for TestBaseCallFilter { + fn filter(c: &Call) -> bool { + match *c { + Call::Balances(_) => true, + // Needed for benchmarking + Call::System(frame_system::Call::remark(_)) => true, + _ => false, + } + } +} +impl Trait for Test { + type Event = TestEvent; + type Call = Call; + type Currency = Balances; + type DepositBase = DepositBase; + type DepositFactor = DepositFactor; + type MaxSignatories = MaxSignatories; + type WeightInfo = (); +} +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type Multisig = Module; + +use pallet_balances::Call as BalancesCall; +use pallet_balances::Error as BalancesError; + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 2)], + }.assimilate_storage(&mut t).unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn last_event() -> TestEvent { + system::Module::::events().pop().map(|e| e.event).expect("Event expected") +} + +fn expect_event>(e: E) { + assert_eq!(last_event(), e.into()); +} + +fn now() -> Timepoint { + Multisig::timepoint() +} + +#[test] +fn multisig_deposit_is_taken_and_returned() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)); + let call_weight = call.get_dispatch_info().weight; + let data = call.encode(); + assert_ok!(Multisig::as_multi(Origin::signed(1), 2, vec![2, 3], None, data.clone(), false, 0)); + assert_eq!(Balances::free_balance(1), 2); + assert_eq!(Balances::reserved_balance(1), 3); + + assert_ok!(Multisig::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), data, false, call_weight)); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::reserved_balance(1), 0); + }); +} + +#[test] +fn multisig_deposit_is_taken_and_returned_with_call_storage() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)); + let call_weight = call.get_dispatch_info().weight; + let data = call.encode(); + let hash = blake2_256(&data); + assert_ok!(Multisig::as_multi(Origin::signed(1), 2, vec![2, 3], None, data, true, 0)); + assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 5); + + assert_ok!(Multisig::approve_as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), hash, call_weight)); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::reserved_balance(1), 0); + }); +} + +#[test] +fn multisig_deposit_is_taken_and_returned_with_alt_call_storage() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 3); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)); + let call_weight = call.get_dispatch_info().weight; + let data = call.encode(); + let hash = blake2_256(&data); + + assert_ok!(Multisig::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone(), 0)); + assert_eq!(Balances::free_balance(1), 1); + assert_eq!(Balances::reserved_balance(1), 4); + + assert_ok!(Multisig::as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), data, true, 0)); + assert_eq!(Balances::free_balance(2), 3); + assert_eq!(Balances::reserved_balance(2), 2); + assert_eq!(Balances::free_balance(1), 1); + assert_eq!(Balances::reserved_balance(1), 4); + + assert_ok!(Multisig::approve_as_multi(Origin::signed(3), 3, vec![1, 2], Some(now()), hash, call_weight)); + assert_eq!(Balances::free_balance(1), 5); + assert_eq!(Balances::reserved_balance(1), 0); + assert_eq!(Balances::free_balance(2), 5); + assert_eq!(Balances::reserved_balance(2), 0); + }); +} + +#[test] +fn cancel_multisig_returns_deposit() { + new_test_ext().execute_with(|| { + let call = Call::Balances(BalancesCall::transfer(6, 15)).encode(); + let hash = blake2_256(&call); + assert_ok!(Multisig::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone(), 0)); + assert_ok!(Multisig::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone(), 0)); + assert_eq!(Balances::free_balance(1), 6); + assert_eq!(Balances::reserved_balance(1), 4); + assert_ok!( + Multisig::cancel_as_multi(Origin::signed(1), 3, vec![2, 3], now(), hash.clone()), + ); + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::reserved_balance(1), 0); + }); +} + +#[test] +fn timepoint_checking_works() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)).encode(); + let hash = blake2_256(&call); + + assert_noop!( + Multisig::approve_as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), hash.clone(), 0), + Error::::UnexpectedTimepoint, + ); + + assert_ok!(Multisig::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash, 0)); + + assert_noop!( + Multisig::as_multi(Origin::signed(2), 2, vec![1, 3], None, call.clone(), false, 0), + Error::::NoTimepoint, + ); + let later = Timepoint { index: 1, .. now() }; + assert_noop!( + Multisig::as_multi(Origin::signed(2), 2, vec![1, 3], Some(later), call.clone(), false, 0), + Error::::WrongTimepoint, + ); + }); +} + +#[test] +fn multisig_2_of_3_works_with_call_storing() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)); + let call_weight = call.get_dispatch_info().weight; + let data = call.encode(); + let hash = blake2_256(&data); + assert_ok!(Multisig::as_multi(Origin::signed(1), 2, vec![2, 3], None, data, true, 0)); + assert_eq!(Balances::free_balance(6), 0); + + assert_ok!(Multisig::approve_as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), hash, call_weight)); + assert_eq!(Balances::free_balance(6), 15); + }); +} + +#[test] +fn multisig_2_of_3_works() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)); + let call_weight = call.get_dispatch_info().weight; + let data = call.encode(); + let hash = blake2_256(&data); + assert_ok!(Multisig::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash, 0)); + assert_eq!(Balances::free_balance(6), 0); + + assert_ok!(Multisig::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), data, false, call_weight)); + assert_eq!(Balances::free_balance(6), 15); + }); +} + +#[test] +fn multisig_3_of_3_works() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 3); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)); + let call_weight = call.get_dispatch_info().weight; + let data = call.encode(); + let hash = blake2_256(&data); + assert_ok!(Multisig::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone(), 0)); + assert_ok!(Multisig::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone(), 0)); + assert_eq!(Balances::free_balance(6), 0); + + assert_ok!(Multisig::as_multi(Origin::signed(3), 3, vec![1, 2], Some(now()), data, false, call_weight)); + assert_eq!(Balances::free_balance(6), 15); + }); +} + +#[test] +fn cancel_multisig_works() { + new_test_ext().execute_with(|| { + let call = Call::Balances(BalancesCall::transfer(6, 15)).encode(); + let hash = blake2_256(&call); + assert_ok!(Multisig::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone(), 0)); + assert_ok!(Multisig::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone(), 0)); + assert_noop!( + Multisig::cancel_as_multi(Origin::signed(2), 3, vec![1, 3], now(), hash.clone()), + Error::::NotOwner, + ); + assert_ok!( + Multisig::cancel_as_multi(Origin::signed(1), 3, vec![2, 3], now(), hash.clone()), + ); + }); +} + +#[test] +fn cancel_multisig_with_call_storage_works() { + new_test_ext().execute_with(|| { + let call = Call::Balances(BalancesCall::transfer(6, 15)).encode(); + let hash = blake2_256(&call); + assert_ok!(Multisig::as_multi(Origin::signed(1), 3, vec![2, 3], None, call, true, 0)); + assert_eq!(Balances::free_balance(1), 4); + assert_ok!(Multisig::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone(), 0)); + assert_noop!( + Multisig::cancel_as_multi(Origin::signed(2), 3, vec![1, 3], now(), hash.clone()), + Error::::NotOwner, + ); + assert_ok!( + Multisig::cancel_as_multi(Origin::signed(1), 3, vec![2, 3], now(), hash.clone()), + ); + assert_eq!(Balances::free_balance(1), 10); + }); +} + +#[test] +fn cancel_multisig_with_alt_call_storage_works() { + new_test_ext().execute_with(|| { + let call = Call::Balances(BalancesCall::transfer(6, 15)).encode(); + let hash = blake2_256(&call); + assert_ok!(Multisig::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone(), 0)); + assert_eq!(Balances::free_balance(1), 6); + assert_ok!(Multisig::as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), call, true, 0)); + assert_eq!(Balances::free_balance(2), 8); + assert_ok!(Multisig::cancel_as_multi(Origin::signed(1), 3, vec![2, 3], now(), hash)); + assert_eq!(Balances::free_balance(1), 10); + assert_eq!(Balances::free_balance(2), 10); + }); +} + +#[test] +fn multisig_2_of_3_as_multi_works() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)); + let call_weight = call.get_dispatch_info().weight; + let data = call.encode(); + assert_ok!(Multisig::as_multi(Origin::signed(1), 2, vec![2, 3], None, data.clone(), false, 0)); + assert_eq!(Balances::free_balance(6), 0); + + assert_ok!(Multisig::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), data, false, call_weight)); + assert_eq!(Balances::free_balance(6), 15); + }); +} + +#[test] +fn multisig_2_of_3_as_multi_with_many_calls_works() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call1 = Call::Balances(BalancesCall::transfer(6, 10)); + let call1_weight = call1.get_dispatch_info().weight; + let data1 = call1.encode(); + let call2 = Call::Balances(BalancesCall::transfer(7, 5)); + let call2_weight = call2.get_dispatch_info().weight; + let data2 = call2.encode(); + + assert_ok!(Multisig::as_multi(Origin::signed(1), 2, vec![2, 3], None, data1.clone(), false, 0)); + assert_ok!(Multisig::as_multi(Origin::signed(2), 2, vec![1, 3], None, data2.clone(), false, 0)); + assert_ok!(Multisig::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), data1, false, call1_weight)); + assert_ok!(Multisig::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), data2, false, call2_weight)); + + assert_eq!(Balances::free_balance(6), 10); + assert_eq!(Balances::free_balance(7), 5); + }); +} + +#[test] +fn multisig_2_of_3_cannot_reissue_same_call() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 10)); + let call_weight = call.get_dispatch_info().weight; + let data = call.encode(); + let hash = blake2_256(&data); + assert_ok!(Multisig::as_multi(Origin::signed(1), 2, vec![2, 3], None, data.clone(), false, 0)); + assert_ok!(Multisig::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), data.clone(), false, call_weight)); + assert_eq!(Balances::free_balance(multi), 5); + + assert_ok!(Multisig::as_multi(Origin::signed(1), 2, vec![2, 3], None, data.clone(), false, 0)); + assert_ok!(Multisig::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), data.clone(), false, call_weight)); + + let err = DispatchError::from(BalancesError::::InsufficientBalance).stripped(); + expect_event(RawEvent::MultisigExecuted(3, now(), multi, hash, Err(err))); + }); +} + +#[test] +fn minimum_threshold_check_works() { + new_test_ext().execute_with(|| { + let call = Call::Balances(BalancesCall::transfer(6, 15)).encode(); + assert_noop!( + Multisig::as_multi(Origin::signed(1), 0, vec![2], None, call.clone(), false, 0), + Error::::MinimumThreshold, + ); + assert_noop!( + Multisig::as_multi(Origin::signed(1), 1, vec![2], None, call.clone(), false, 0), + Error::::MinimumThreshold, + ); + }); +} + +#[test] +fn too_many_signatories_fails() { + new_test_ext().execute_with(|| { + let call = Call::Balances(BalancesCall::transfer(6, 15)).encode(); + assert_noop!( + Multisig::as_multi(Origin::signed(1), 2, vec![2, 3, 4], None, call.clone(), false, 0), + Error::::TooManySignatories, + ); + }); +} + +#[test] +fn duplicate_approvals_are_ignored() { + new_test_ext().execute_with(|| { + let call = Call::Balances(BalancesCall::transfer(6, 15)).encode(); + let hash = blake2_256(&call); + assert_ok!(Multisig::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash.clone(), 0)); + assert_noop!( + Multisig::approve_as_multi(Origin::signed(1), 2, vec![2, 3], Some(now()), hash.clone(), 0), + Error::::AlreadyApproved, + ); + assert_ok!(Multisig::approve_as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), hash.clone(), 0)); + assert_noop!( + Multisig::approve_as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), hash.clone(), 0), + Error::::AlreadyApproved, + ); + }); +} + +#[test] +fn multisig_1_of_3_works() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 1); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)).encode(); + let hash = blake2_256(&call); + assert_noop!( + Multisig::approve_as_multi(Origin::signed(1), 1, vec![2, 3], None, hash.clone(), 0), + Error::::MinimumThreshold, + ); + assert_noop!( + Multisig::as_multi(Origin::signed(1), 1, vec![2, 3], None, call.clone(), false, 0), + Error::::MinimumThreshold, + ); + let boxed_call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); + assert_ok!(Multisig::as_multi_threshold_1(Origin::signed(1), vec![2, 3], boxed_call)); + + assert_eq!(Balances::free_balance(6), 15); + }); +} + +#[test] +fn multisig_filters() { + new_test_ext().execute_with(|| { + let call = Box::new(Call::System(frame_system::Call::set_code(vec![]))); + assert_noop!( + Multisig::as_multi_threshold_1(Origin::signed(1), vec![2], call.clone()), + DispatchError::BadOrigin, + ); + }); +} + +#[test] +fn weight_check_works() { + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 2); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)); + let data = call.encode(); + assert_ok!(Multisig::as_multi(Origin::signed(1), 2, vec![2, 3], None, data.clone(), false, 0)); + assert_eq!(Balances::free_balance(6), 0); + + assert_noop!( + Multisig::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), data, false, 0), + Error::::WeightTooLow, + ); + }); +} + +#[test] +fn multisig_handles_no_preimage_after_all_approve() { + // This test checks the situation where everyone approves a multi-sig, but no-one provides the call data. + // In the end, any of the multisig callers can approve again with the call data and the call will go through. + new_test_ext().execute_with(|| { + let multi = Multisig::multi_account_id(&[1, 2, 3][..], 3); + assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); + assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); + + let call = Call::Balances(BalancesCall::transfer(6, 15)); + let call_weight = call.get_dispatch_info().weight; + let data = call.encode(); + let hash = blake2_256(&data); + assert_ok!(Multisig::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone(), 0)); + assert_ok!(Multisig::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone(), 0)); + assert_ok!(Multisig::approve_as_multi(Origin::signed(3), 3, vec![1, 2], Some(now()), hash.clone(), 0)); + assert_eq!(Balances::free_balance(6), 0); + + assert_ok!(Multisig::as_multi(Origin::signed(3), 3, vec![1, 2], Some(now()), data, false, call_weight)); + assert_eq!(Balances::free_balance(6), 15); + }); +} diff --git a/frame/nicks/Cargo.toml b/frame/nicks/Cargo.toml index fcb64731051e0e8d85894571232942e5f6c5f08c..084469864994e63d7957968c9c1a75b6dee48ba4 100644 --- a/frame/nicks/Cargo.toml +++ b/frame/nicks/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-nicks" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for nick management" @@ -13,16 +13,16 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } [features] default = ["std"] diff --git a/frame/nicks/README.md b/frame/nicks/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b021357bd778438bb928d678b0de1ba6da8ca897 --- /dev/null +++ b/frame/nicks/README.md @@ -0,0 +1,23 @@ +# Nicks Module + +- [`nicks::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +Nicks is a trivial module for keeping track of account names on-chain. It makes no effort to +create a name hierarchy, be a DNS replacement or provide reverse lookups. + +## Interface + +### Dispatchable Functions + +* `set_name` - Set the associated name of an account; a small deposit is reserved if not already + taken. +* `clear_name` - Remove an account's associated name; the deposit is returned. +* `kill_name` - Forcibly remove the associated name; the deposit is lost. + +[`Call`]: ./enum.Call.html +[`Trait`]: ./trait.Trait.html + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 3088e7b68da4d37d63378c637eed08e15cccf8a0..56262819c9654cb471af72bb22b4641c257bd03b 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Nicks Module //! @@ -46,7 +47,7 @@ use frame_support::{ decl_module, decl_event, decl_storage, ensure, decl_error, traits::{Currency, EnsureOrigin, ReservableCurrency, OnUnbalanced, Get}, }; -use frame_system::{self as system, ensure_signed, ensure_root}; +use frame_system::ensure_signed; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; @@ -83,15 +84,15 @@ decl_storage! { decl_event!( pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { - /// A name was set. + /// A name was set. [who] NameSet(AccountId), - /// A name was forcibly set. + /// A name was forcibly set. [target] NameForced(AccountId), - /// A name was changed. + /// A name was changed. [who] NameChanged(AccountId), - /// A name was cleared, and the given balance returned. + /// A name was cleared, and the given balance returned. [who, deposit] NameCleared(AccountId, Balance), - /// A name was removed and the given balance slashed. + /// A name was removed and the given balance slashed. [target, deposit] NameKilled(AccountId, Balance), } ); @@ -186,7 +187,7 @@ decl_module! { /// Fails if `who` has not been named. The deposit is dealt with through `T::Slashed` /// imbalance handler. /// - /// The dispatch origin for this call must be _Root_ or match `T::ForceOrigin`. + /// The dispatch origin for this call must match `T::ForceOrigin`. /// /// # /// - O(1). @@ -196,9 +197,7 @@ decl_module! { /// # #[weight = 70_000_000] fn kill_name(origin, target: ::Source) { - T::ForceOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + T::ForceOrigin::ensure_origin(origin)?; // Figure out who we're meant to be clearing. let target = T::Lookup::lookup(target)?; @@ -214,7 +213,7 @@ decl_module! { /// /// No length checking is done on the name. /// - /// The dispatch origin for this call must be _Root_ or match `T::ForceOrigin`. + /// The dispatch origin for this call must match `T::ForceOrigin`. /// /// # /// - O(1). @@ -224,9 +223,7 @@ decl_module! { /// # #[weight = 70_000_000] fn force_name(origin, target: ::Source, name: Vec) { - T::ForceOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + T::ForceOrigin::ensure_origin(origin)?; let target = T::Lookup::lookup(target)?; let deposit = >::get(&target).map(|x| x.1).unwrap_or_else(Zero::zero); @@ -247,19 +244,14 @@ mod tests { }; use sp_core::H256; use frame_system::EnsureSignedBy; - // The testing primitives are very useful for avoiding having to work with signatures - // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, }; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } - // For testing the pallet, we construct most of a mock runtime. This means - // first constructing a configuration type (`Test`) which `impl`s each of the - // configuration traits of pallets we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -269,6 +261,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -284,6 +277,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -291,6 +285,7 @@ mod tests { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; @@ -301,6 +296,7 @@ mod tests { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { pub const ReservationFee: u64 = 2; @@ -323,11 +319,8 @@ mod tests { type Balances = pallet_balances::Module; type Nicks = Module; - // This function basically just builds a genesis storage key/value store according to - // our desired mockup. fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - // We use default for brevity, but you can configure as desired if needed. pallet_balances::GenesisConfig:: { balances: vec![ (1, 10), diff --git a/frame/offences/Cargo.toml b/frame/offences/Cargo.toml index e0759325feba7db1591f38e34823248dc6990e98..1585732a9f5efca1f0d6ecc187ad4bfb17854462 100644 --- a/frame/offences/Cargo.toml +++ b/frame/offences/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-offences" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME offences pallet" @@ -12,18 +12,18 @@ description = "FRAME offences pallet" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../balances" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +pallet-balances = { version = "2.0.0-rc6", default-features = false, path = "../balances" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/offences/README.md b/frame/offences/README.md new file mode 100644 index 0000000000000000000000000000000000000000..454c7effaf36cc599516feb5d047606415ee68d5 --- /dev/null +++ b/frame/offences/README.md @@ -0,0 +1,5 @@ +# Offences Module + +Tracks reported offences + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/offences/benchmarking/Cargo.toml b/frame/offences/benchmarking/Cargo.toml index 7b998176eb0de810841b5b242e430d9c7686801b..d5bfe302cb5ea95d5d2327e55a29e9f230a85049 100644 --- a/frame/offences/benchmarking/Cargo.toml +++ b/frame/offences/benchmarking/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-offences-benchmarking" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME offences pallet benchmarking" @@ -12,29 +12,27 @@ description = "FRAME offences pallet benchmarking" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../../benchmarking" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../../system" } -pallet-babe = { version = "2.0.0-dev", default-features = false, path = "../../babe" } -pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../../balances" } -pallet-grandpa = { version = "2.0.0-dev", default-features = false, path = "../../grandpa" } -pallet-im-online = { version = "2.0.0-dev", default-features = false, path = "../../im-online" } -pallet-offences = { version = "2.0.0-dev", default-features = false, features = ["runtime-benchmarks"], path = "../../offences" } -pallet-session = { version = "2.0.0-dev", default-features = false, path = "../../session" } -pallet-staking = { version = "2.0.0-dev", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } -sp-io = { path = "../../../primitives/io", default-features = false, version = "2.0.0-dev"} -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } -sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/staking" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../../benchmarking" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../../system" } +pallet-babe = { version = "2.0.0-rc6", default-features = false, path = "../../babe" } +pallet-balances = { version = "2.0.0-rc6", default-features = false, path = "../../balances" } +pallet-grandpa = { version = "2.0.0-rc6", default-features = false, path = "../../grandpa" } +pallet-im-online = { version = "2.0.0-rc6", default-features = false, path = "../../im-online" } +pallet-offences = { version = "2.0.0-rc6", default-features = false, features = ["runtime-benchmarks"], path = "../../offences" } +pallet-session = { version = "2.0.0-rc6", default-features = false, path = "../../session" } +pallet-staking = { version = "2.0.0-rc6", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/runtime" } +sp-staking = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/staking" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/std" } [dev-dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -pallet-staking-reward-curve = { version = "2.0.0-dev", path = "../../staking/reward-curve" } -pallet-timestamp = { version = "2.0.0-dev", path = "../../timestamp" } +pallet-staking-reward-curve = { version = "2.0.0-rc6", path = "../../staking/reward-curve" } +pallet-timestamp = { version = "2.0.0-rc6", path = "../../timestamp" } serde = { version = "1.0.101" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-io ={ path = "../../../primitives/io", version = "2.0.0-dev"} +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-io = { version = "2.0.0-rc6", path = "../../../primitives/io" } [features] default = ["std"] @@ -52,5 +50,5 @@ std = [ "sp-runtime/std", "sp-staking/std", "sp-std/std", - "sp-io/std", + "codec/std", ] diff --git a/frame/offences/benchmarking/README.md b/frame/offences/benchmarking/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cbfe91d73a6a7cc5118f4e56a806f4c766c426d1 --- /dev/null +++ b/frame/offences/benchmarking/README.md @@ -0,0 +1,3 @@ +Offences pallet benchmarking. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/offences/benchmarking/src/lib.rs b/frame/offences/benchmarking/src/lib.rs index a0e05a74d58db8dee8fc34c1688d0fce5635d9de..1aa9fed85b1270e8a6adac8d235adfaec8fa2121 100644 --- a/frame/offences/benchmarking/src/lib.rs +++ b/frame/offences/benchmarking/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Offences pallet benchmarking. @@ -256,7 +257,7 @@ benchmarks! { .flat_map(|reporter| vec![ frame_system::Event::::NewAccount(reporter.clone()).into(), ::Event::from( - pallet_balances::Event::::Endowed(reporter.clone(), (reward_amount / r).into()) + pallet_balances::Event::::Endowed(reporter, (reward_amount / r).into()) ).into() ]); @@ -281,21 +282,16 @@ benchmarks! { } report_offence_grandpa { - let r in 1 .. MAX_REPORTERS; let n in 0 .. MAX_NOMINATORS.min(MAX_NOMINATIONS as u32); - let o = 1; - // Make r reporters - let mut reporters = vec![]; - for i in 0 .. r { - let reporter = account("reporter", i, SEED); - reporters.push(reporter); - } + // for grandpa equivocation reports the number of reporters + // and offenders is always 1 + let reporters = vec![account("reporter", 1, SEED)]; // make sure reporters actually get rewarded Staking::::set_slash_reward_fraction(Perbill::one()); - let (mut offenders, raw_offenders) = make_offenders::(o, n)?; + let (mut offenders, raw_offenders) = make_offenders::(1, n)?; let keys = ImOnline::::keys(); let offence = GrandpaEquivocationOffence { @@ -315,28 +311,23 @@ benchmarks! { assert_eq!( System::::event_count(), 0 + 1 // offence - + 2 * r // reporter (reward + endowment) - + o // offenders slashed - + o * n // nominators slashed + + 2 // reporter (reward + endowment) + + 1 // offenders slashed + + n // nominators slashed ); } report_offence_babe { - let r in 1 .. MAX_REPORTERS; let n in 0 .. MAX_NOMINATORS.min(MAX_NOMINATIONS as u32); - let o = 1; - // Make r reporters - let mut reporters = vec![]; - for i in 0 .. r { - let reporter = account("reporter", i, SEED); - reporters.push(reporter); - } + // for babe equivocation reports the number of reporters + // and offenders is always 1 + let reporters = vec![account("reporter", 1, SEED)]; // make sure reporters actually get rewarded Staking::::set_slash_reward_fraction(Perbill::one()); - let (mut offenders, raw_offenders) = make_offenders::(o, n)?; + let (mut offenders, raw_offenders) = make_offenders::(1, n)?; let keys = ImOnline::::keys(); let offence = BabeEquivocationOffence { @@ -356,9 +347,9 @@ benchmarks! { assert_eq!( System::::event_count(), 0 + 1 // offence - + 2 * r // reporter (reward + endowment) - + o // offenders slashed - + o * n // nominators slashed + + 2 // reporter (reward + endowment) + + 1 // offenders slashed + + n // nominators slashed ); } diff --git a/frame/offences/benchmarking/src/mock.rs b/frame/offences/benchmarking/src/mock.rs index 20cf337d442b935682471f8fdaf7667ca4b49816..ad6e8a14d5622f0fe1922fc31e5801262ab10323 100644 --- a/frame/offences/benchmarking/src/mock.rs +++ b/frame/offences/benchmarking/src/mock.rs @@ -1,25 +1,29 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Mock file for offences benchmarking. #![cfg(test)] use super::*; -use frame_support::parameter_types; +use frame_support::{ + parameter_types, + weights::{Weight, constants::WEIGHT_PER_SECOND}, +}; use frame_system as system; use sp_runtime::{ SaturatedConversion, @@ -33,7 +37,12 @@ type AccountIndex = u32; type BlockNumber = u64; type Balance = u64; +parameter_types! { + pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; +} + impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; type BlockNumber = BlockNumber; @@ -45,7 +54,7 @@ impl frame_system::Trait for Test { type Header = sp_runtime::testing::Header; type Event = Event; type BlockHashCount = (); - type MaximumBlockWeight = (); + type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); type AvailableBlockRatio = (); type MaximumBlockLength = (); @@ -56,6 +65,8 @@ impl frame_system::Trait for Test { type OnKilledAccount = (Balances,); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = (); + type SystemWeightInfo = (); } parameter_types! { pub const ExistentialDeposit: Balance = 10; @@ -66,6 +77,7 @@ impl pallet_balances::Trait for Test { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { @@ -75,6 +87,7 @@ impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } impl pallet_session::historical::Trait for Test { type FullIdentification = pallet_staking::Exposure; @@ -117,6 +130,7 @@ impl pallet_session::Trait for Test { type ValidatorId = AccountId; type ValidatorIdOf = pallet_staking::StashOf; type DisabledValidatorsThreshold = (); + type WeightInfo = (); } pallet_staking_reward_curve::build! { const I_NPOS: sp_runtime::curve::PiecewiseLinear<'static> = curve!( @@ -167,6 +181,8 @@ impl pallet_staking::Trait for Test { type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type UnsignedPriority = (); type MaxIterations = (); + type MinSolutionScoreBump = (); + type WeightInfo = (); } impl pallet_im_online::Trait for Test { @@ -175,12 +191,19 @@ impl pallet_im_online::Trait for Test { type SessionDuration = Period; type ReportUnresponsiveness = Offences; type UnsignedPriority = (); + type WeightInfo = (); +} + +parameter_types! { + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } impl pallet_offences::Trait for Test { type Event = Event; type IdentificationTuple = pallet_session::historical::IdentificationTuple; type OnOffenceHandler = Staking; + type WeightSoftLimit = OffencesWeightSoftLimit; + type WeightInfo = (); } impl frame_system::offchain::SendTransactionTypes for Test where Call: From { diff --git a/frame/offences/src/lib.rs b/frame/offences/src/lib.rs index b877d1e2b20dd1972c2dd6db776e984b76c9de56..9a067d903fe2dba46cd51d54e6ad98adfab9afb1 100644 --- a/frame/offences/src/lib.rs +++ b/frame/offences/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Offences Module //! @@ -27,15 +28,15 @@ mod tests; use sp_std::vec::Vec; use frame_support::{ decl_module, decl_event, decl_storage, Parameter, debug, + traits::Get, weights::Weight, }; -use sp_runtime::{traits::Hash, Perbill}; +use sp_runtime::{traits::{Hash, Zero}, Perbill}; use sp_staking::{ SessionIndex, offence::{Offence, ReportOffence, Kind, OnOffenceHandler, OffenceDetails, OffenceError}, }; use codec::{Encode, Decode}; -use frame_system as system; /// A binary blob which represents a SCALE codec-encoded `O::TimeSlot`. type OpaqueTimeSlot = Vec; @@ -50,6 +51,20 @@ pub type DeferredOffenceOf = ( SessionIndex, ); +pub trait WeightInfo { + fn report_offence_im_online(r: u32, o: u32, n: u32, ) -> Weight; + fn report_offence_grandpa(r: u32, n: u32, ) -> Weight; + fn report_offence_babe(r: u32, n: u32, ) -> Weight; + fn on_initialize(d: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn report_offence_im_online(_r: u32, _o: u32, _n: u32, ) -> Weight { 1_000_000_000 } + fn report_offence_grandpa(_r: u32, _n: u32, ) -> Weight { 1_000_000_000 } + fn report_offence_babe(_r: u32, _n: u32, ) -> Weight { 1_000_000_000 } + fn on_initialize(_d: u32, ) -> Weight { 1_000_000_000 } +} + /// Offences trait pub trait Trait: frame_system::Trait { /// The overarching event type. @@ -57,7 +72,13 @@ pub trait Trait: frame_system::Trait { /// Full identification of the validator. type IdentificationTuple: Parameter + Ord; /// A handler called for every offence report. - type OnOffenceHandler: OnOffenceHandler; + type OnOffenceHandler: OnOffenceHandler; + /// The a soft limit on maximum weight that may be consumed while dispatching deferred offences in + /// `on_initialize`. + /// Note it's going to be exceeded before we stop adding to it, so it has to be set conservatively. + type WeightSoftLimit: Get; + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_storage! { @@ -90,7 +111,8 @@ decl_event!( pub enum Event { /// There is an offence reported of the given `kind` happened at the `session_index` and /// (kind-specific) time slot. This event is not deposited for duplicate slashes. last - /// element indicates of the offence was applied (true) or queued (false). + /// element indicates of the offence was applied (true) or queued (false) + /// [kind, timeslot, applied]. Offence(Kind, OpaqueTimeSlot, bool), } ); @@ -101,23 +123,39 @@ decl_module! { fn on_initialize(now: T::BlockNumber) -> Weight { // only decode storage if we can actually submit anything again. - if T::OnOffenceHandler::can_report() { - >::mutate(|deferred| { - // keep those that fail to be reported again. An error log is emitted here; this - // should not happen if staking's `can_report` is implemented properly. - deferred.retain(|(o, p, s)| { - T::OnOffenceHandler::on_offence(&o, &p, *s).map_err(|_| { - debug::native::error!( - target: "pallet-offences", - "re-submitting a deferred slash returned Err at {}. This should not happen with pallet-staking", - now, - ); - }).is_err() - }) - }) + if !T::OnOffenceHandler::can_report() { + return 0; } - 0 + let limit = T::WeightSoftLimit::get(); + let mut consumed = Weight::zero(); + + >::mutate(|deferred| { + deferred.retain(|(offences, perbill, session)| { + if consumed >= limit { + true + } else { + // keep those that fail to be reported again. An error log is emitted here; this + // should not happen if staking's `can_report` is implemented properly. + match T::OnOffenceHandler::on_offence(&offences, &perbill, *session) { + Ok(weight) => { + consumed += weight; + false + }, + Err(_) => { + debug::native::error!( + target: "pallet-offences", + "re-submitting a deferred slash returned Err at {}. This should not happen with pallet-staking", + now, + ); + true + }, + } + } + }) + }); + + consumed } } } @@ -163,6 +201,15 @@ where Ok(()) } + + fn is_known_offence(offenders: &[T::IdentificationTuple], time_slot: &O::TimeSlot) -> bool { + let any_unknown = offenders.iter().any(|offender| { + let report_id = Self::report_id::(time_slot, offender); + !>::contains_key(&report_id) + }); + + !any_unknown + } } impl Module { diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index 595d091ea445556261e320803e06ad2d4e792938..f981e70835c0e14acf0a7b03ac4bd1dcd9b30c77 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Test utilities @@ -31,7 +32,7 @@ use sp_runtime::traits::{IdentityLookup, BlakeTwo256}; use sp_core::H256; use frame_support::{ impl_outer_origin, impl_outer_event, parameter_types, StorageMap, StorageDoubleMap, - weights::Weight, + weights::{Weight, constants::{WEIGHT_PER_SECOND, RocksDbWeight}}, }; use frame_system as system; @@ -44,20 +45,23 @@ pub struct OnOffenceHandler; thread_local! { pub static ON_OFFENCE_PERBILL: RefCell> = RefCell::new(Default::default()); pub static CAN_REPORT: RefCell = RefCell::new(true); + pub static OFFENCE_WEIGHT: RefCell = RefCell::new(Default::default()); } -impl offence::OnOffenceHandler for OnOffenceHandler { +impl + offence::OnOffenceHandler for OnOffenceHandler +{ fn on_offence( _offenders: &[OffenceDetails], slash_fraction: &[Perbill], _offence_session: SessionIndex, - ) -> Result<(), ()> { - if >::can_report() { + ) -> Result { + if >::can_report() { ON_OFFENCE_PERBILL.with(|f| { *f.borrow_mut() = slash_fraction.to_vec(); }); - Ok(()) + Ok(OFFENCE_WEIGHT.with(|w| *w.borrow())) } else { Err(()) } @@ -78,16 +82,21 @@ pub fn with_on_offence_fractions) -> R>(f: F) -> }) } +pub fn set_offence_weight(new: Weight) { + OFFENCE_WEIGHT.with(|w| *w.borrow_mut() = new); +} + // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Runtime; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND; pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Runtime { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -100,9 +109,10 @@ impl frame_system::Trait for Runtime { type Event = TestEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); + type DbWeight = RocksDbWeight; type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -110,12 +120,19 @@ impl frame_system::Trait for Runtime { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); +} + +parameter_types! { + pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get(); } impl Trait for Runtime { type Event = TestEvent; type IdentificationTuple = u64; type OnOffenceHandler = OnOffenceHandler; + type WeightSoftLimit = OffencesWeightSoftLimit; + type WeightInfo = (); } mod offences { diff --git a/frame/offences/src/tests.rs b/frame/offences/src/tests.rs index 3179a0752318f1340ae924599734423b793fb012..ca9f46a198820ba93a2618803fab956f610636f2 100644 --- a/frame/offences/src/tests.rs +++ b/frame/offences/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for the offences module. @@ -21,7 +22,7 @@ use super::*; use crate::mock::{ Offences, System, Offence, TestEvent, KIND, new_test_ext, with_on_offence_fractions, - offence_reports, set_can_report, + offence_reports, set_can_report, set_offence_weight, }; use sp_runtime::Perbill; use frame_support::traits::OnInitialize; @@ -173,6 +174,77 @@ fn doesnt_deposit_event_for_dups() { }); } +#[test] +fn reports_if_an_offence_is_dup() { + type TestOffence = Offence; + + new_test_ext().execute_with(|| { + let time_slot = 42; + assert_eq!(offence_reports(KIND, time_slot), vec![]); + + let offence = |time_slot, offenders| TestOffence { + validator_set_count: 5, + time_slot, + offenders, + }; + + let mut test_offence = offence(time_slot, vec![0]); + + // the report for authority 0 at time slot 42 should not be a known + // offence + assert!( + !>::is_known_offence( + &test_offence.offenders, + &test_offence.time_slot + ) + ); + + // we report an offence for authority 0 at time slot 42 + Offences::report_offence(vec![], test_offence.clone()).unwrap(); + + // the same report should be a known offence now + assert!( + >::is_known_offence( + &test_offence.offenders, + &test_offence.time_slot + ) + ); + + // and reporting it again should yield a duplicate report error + assert_eq!( + Offences::report_offence(vec![], test_offence.clone()), + Err(OffenceError::DuplicateReport) + ); + + // after adding a new offender to the offence report + test_offence.offenders.push(1); + + // it should not be a known offence anymore + assert!( + !>::is_known_offence( + &test_offence.offenders, + &test_offence.time_slot + ) + ); + + // and reporting it again should work without any error + assert_eq!( + Offences::report_offence(vec![], test_offence.clone()), + Ok(()) + ); + + // creating a new offence for the same authorities on the next slot + // should be considered a new offence and thefore not known + let test_offence_next_slot = offence(time_slot + 1, vec![0, 1]); + assert!( + !>::is_known_offence( + &test_offence_next_slot.offenders, + &test_offence_next_slot.time_slot + ) + ); + }); +} + #[test] fn should_properly_count_offences() { // We report two different authorities for the same issue. Ultimately, the 1st authority @@ -264,3 +336,48 @@ fn should_queue_and_resubmit_rejected_offence() { assert_eq!(Offences::deferred_offences().len(), 0); }) } + +#[test] +fn weight_soft_limit_is_used() { + new_test_ext().execute_with(|| { + set_can_report(false); + // Only 2 can fit in one block + set_offence_weight(::WeightSoftLimit::get() / 2); + + // Queue 3 offences + // #1 + let offence = Offence { + validator_set_count: 5, + time_slot: 42, + offenders: vec![5], + }; + Offences::report_offence(vec![], offence).unwrap(); + // #2 + let offence = Offence { + validator_set_count: 5, + time_slot: 62, + offenders: vec![5], + }; + Offences::report_offence(vec![], offence).unwrap(); + // #3 + let offence = Offence { + validator_set_count: 5, + time_slot: 72, + offenders: vec![5], + }; + Offences::report_offence(vec![], offence).unwrap(); + // 3 are queued + assert_eq!(Offences::deferred_offences().len(), 3); + + // Allow reporting + set_can_report(true); + + Offences::on_initialize(3); + // Two are completed, one is left in the queue + assert_eq!(Offences::deferred_offences().len(), 1); + + Offences::on_initialize(4); + // All are done now + assert_eq!(Offences::deferred_offences().len(), 0); + }) +} diff --git a/frame/proxy/Cargo.toml b/frame/proxy/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..77c9ae8bba6e1a6134713fd790e69e4af2349219 --- /dev/null +++ b/frame/proxy/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "pallet-proxy" +version = "2.0.0-rc6" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME proxying pallet" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +serde = { version = "1.0.101", optional = true } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } + +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } + +[dev-dependencies] +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +pallet-utility = { version = "2.0.0-rc6", path = "../utility" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "sp-runtime/std", + "frame-support/std", + "frame-system/std", + "sp-std/std", + "sp-io/std" +] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", +] diff --git a/frame/proxy/README.md b/frame/proxy/README.md new file mode 100644 index 0000000000000000000000000000000000000000..105cf5561aee8f7d602faa764ee1fed75af944bf --- /dev/null +++ b/frame/proxy/README.md @@ -0,0 +1,17 @@ +# Proxy Module +A module allowing accounts to give permission to other accounts to dispatch types of calls from +their signed origin. + +- [`proxy::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +## Interface + +### Dispatchable Functions + +[`Call`]: ./enum.Call.html +[`Trait`]: ./trait.Trait.html + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/proxy/src/benchmarking.rs b/frame/proxy/src/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..5f1d79741dd8e02cec922401b2be94c128a3eb61 --- /dev/null +++ b/frame/proxy/src/benchmarking.rs @@ -0,0 +1,279 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +// Benchmarks for Proxy Pallet + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use frame_system::{RawOrigin, EventRecord}; +use frame_benchmarking::{benchmarks, account, whitelisted_caller}; +use sp_runtime::traits::Bounded; +use crate::Module as Proxy; + +const SEED: u32 = 0; + +fn assert_last_event(generic_event: ::Event) { + let events = frame_system::Module::::events(); + let system_event: ::Event = generic_event.into(); + // compare to the last event record + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} + +fn add_proxies(n: u32, maybe_who: Option) -> Result<(), &'static str> { + let caller = maybe_who.unwrap_or_else(|| whitelisted_caller()); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + for i in 0..n { + Proxy::::add_proxy( + RawOrigin::Signed(caller.clone()).into(), + account("target", i, SEED), + T::ProxyType::default(), + T::BlockNumber::zero(), + )?; + } + Ok(()) +} + +fn add_announcements( + n: u32, + maybe_who: Option, + maybe_real: Option +) -> Result<(), &'static str> { + let caller = maybe_who.unwrap_or_else(|| account("caller", 0, SEED)); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + let real = if let Some(real) = maybe_real { + real + } else { + let real = account("real", 0, SEED); + T::Currency::make_free_balance_be(&real, BalanceOf::::max_value()); + Proxy::::add_proxy( + RawOrigin::Signed(real.clone()).into(), + caller.clone(), + T::ProxyType::default(), + T::BlockNumber::zero(), + )?; + real + }; + for _ in 0..n { + Proxy::::announce( + RawOrigin::Signed(caller.clone()).into(), + real.clone(), + T::CallHasher::hash_of(&("add_announcement", n)), + )?; + } + Ok(()) +} + +benchmarks! { + _ { + let p in 1 .. (T::MaxProxies::get() - 1).into() => add_proxies::(p, None)?; + } + + proxy { + let p in ...; + // In this case the caller is the "target" proxy + let caller: T::AccountId = account("target", p - 1, SEED); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + // ... and "real" is the traditional caller. This is not a typo. + let real: T::AccountId = whitelisted_caller(); + let call: ::Call = frame_system::Call::::remark(vec![]).into(); + }: _(RawOrigin::Signed(caller), real, Some(T::ProxyType::default()), Box::new(call)) + verify { + assert_last_event::(RawEvent::ProxyExecuted(Ok(())).into()) + } + + proxy_announced { + let a in 0 .. T::MaxPending::get() - 1; + let p in ...; + // In this case the caller is the "target" proxy + let caller: T::AccountId = account("anonymous", 0, SEED); + let delegate: T::AccountId = account("target", p - 1, SEED); + T::Currency::make_free_balance_be(&delegate, BalanceOf::::max_value()); + // ... and "real" is the traditional caller. This is not a typo. + let real: T::AccountId = whitelisted_caller(); + let call: ::Call = frame_system::Call::::remark(vec![]).into(); + Proxy::::announce( + RawOrigin::Signed(delegate.clone()).into(), + real.clone(), + T::CallHasher::hash_of(&call), + )?; + add_announcements::(a, Some(delegate.clone()), None)?; + }: _(RawOrigin::Signed(caller), delegate, real, Some(T::ProxyType::default()), Box::new(call)) + verify { + assert_last_event::(RawEvent::ProxyExecuted(Ok(())).into()) + } + + remove_announcement { + let a in 0 .. T::MaxPending::get() - 1; + let p in ...; + // In this case the caller is the "target" proxy + let caller: T::AccountId = account("target", p - 1, SEED); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + // ... and "real" is the traditional caller. This is not a typo. + let real: T::AccountId = whitelisted_caller(); + let call: ::Call = frame_system::Call::::remark(vec![]).into(); + Proxy::::announce( + RawOrigin::Signed(caller.clone()).into(), + real.clone(), + T::CallHasher::hash_of(&call), + )?; + add_announcements::(a, Some(caller.clone()), None)?; + }: _(RawOrigin::Signed(caller.clone()), real, T::CallHasher::hash_of(&call)) + verify { + let (announcements, _) = Announcements::::get(&caller); + assert_eq!(announcements.len() as u32, a); + } + + reject_announcement { + let a in 0 .. T::MaxPending::get() - 1; + let p in ...; + // In this case the caller is the "target" proxy + let caller: T::AccountId = account("target", p - 1, SEED); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + // ... and "real" is the traditional caller. This is not a typo. + let real: T::AccountId = whitelisted_caller(); + let call: ::Call = frame_system::Call::::remark(vec![]).into(); + Proxy::::announce( + RawOrigin::Signed(caller.clone()).into(), + real.clone(), + T::CallHasher::hash_of(&call), + )?; + add_announcements::(a, Some(caller.clone()), None)?; + }: _(RawOrigin::Signed(real), caller.clone(), T::CallHasher::hash_of(&call)) + verify { + let (announcements, _) = Announcements::::get(&caller); + assert_eq!(announcements.len() as u32, a); + } + + announce { + let a in 0 .. T::MaxPending::get() - 1; + let p in ...; + // In this case the caller is the "target" proxy + let caller: T::AccountId = account("target", p - 1, SEED); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + // ... and "real" is the traditional caller. This is not a typo. + let real: T::AccountId = whitelisted_caller(); + add_announcements::(a, Some(caller.clone()), None)?; + let call: ::Call = frame_system::Call::::remark(vec![]).into(); + let call_hash = T::CallHasher::hash_of(&call); + }: _(RawOrigin::Signed(caller.clone()), real.clone(), call_hash) + verify { + assert_last_event::(RawEvent::Announced(real, caller, call_hash).into()); + } + + add_proxy { + let p in ...; + let caller: T::AccountId = whitelisted_caller(); + }: _( + RawOrigin::Signed(caller.clone()), + account("target", T::MaxProxies::get().into(), SEED), + T::ProxyType::default(), + T::BlockNumber::zero() + ) + verify { + let (proxies, _) = Proxies::::get(caller); + assert_eq!(proxies.len() as u32, p + 1); + } + + remove_proxy { + let p in ...; + let caller: T::AccountId = whitelisted_caller(); + }: _( + RawOrigin::Signed(caller.clone()), + account("target", 0, SEED), + T::ProxyType::default(), + T::BlockNumber::zero() + ) + verify { + let (proxies, _) = Proxies::::get(caller); + assert_eq!(proxies.len() as u32, p - 1); + } + + remove_proxies { + let p in ...; + let caller: T::AccountId = whitelisted_caller(); + }: _(RawOrigin::Signed(caller.clone())) + verify { + let (proxies, _) = Proxies::::get(caller); + assert_eq!(proxies.len() as u32, 0); + } + + anonymous { + let p in ...; + let caller: T::AccountId = whitelisted_caller(); + }: _( + RawOrigin::Signed(caller.clone()), + T::ProxyType::default(), + T::BlockNumber::zero(), + 0 + ) + verify { + let anon_account = Module::::anonymous_account(&caller, &T::ProxyType::default(), 0, None); + assert_last_event::(RawEvent::AnonymousCreated( + anon_account, + caller, + T::ProxyType::default(), + 0, + ).into()); + } + + kill_anonymous { + let p in 0 .. (T::MaxProxies::get() - 2).into(); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + Module::::anonymous( + RawOrigin::Signed(whitelisted_caller()).into(), + T::ProxyType::default(), + T::BlockNumber::zero(), + 0 + )?; + let height = system::Module::::block_number(); + let ext_index = system::Module::::extrinsic_index().unwrap_or(0); + let anon = Module::::anonymous_account(&caller, &T::ProxyType::default(), 0, None); + + add_proxies::(p, Some(anon.clone()))?; + ensure!(Proxies::::contains_key(&anon), "anon proxy not created"); + }: _(RawOrigin::Signed(anon.clone()), caller.clone(), T::ProxyType::default(), 0, height, ext_index) + verify { + assert!(!Proxies::::contains_key(&anon)); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::tests::{new_test_ext, Test}; + use frame_support::assert_ok; + + #[test] + fn test_benchmarks() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_proxy::()); + assert_ok!(test_benchmark_proxy_announced::()); + assert_ok!(test_benchmark_remove_announcement::()); + assert_ok!(test_benchmark_reject_announcement::()); + assert_ok!(test_benchmark_announce::()); + assert_ok!(test_benchmark_add_proxy::()); + assert_ok!(test_benchmark_remove_proxy::()); + assert_ok!(test_benchmark_remove_proxies::()); + assert_ok!(test_benchmark_anonymous::()); + assert_ok!(test_benchmark_kill_anonymous::()); + }); + } +} diff --git a/frame/proxy/src/default_weight.rs b/frame/proxy/src/default_weight.rs new file mode 100644 index 0000000000000000000000000000000000000000..183c0b81c8a07e570edf914ba65b2456dba43e78 --- /dev/null +++ b/frame/proxy/src/default_weight.rs @@ -0,0 +1,84 @@ +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +impl crate::WeightInfo for () { + fn proxy(p: u32, ) -> Weight { + (26127000 as Weight) + .saturating_add((214000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + } + fn proxy_announced(a: u32, p: u32, ) -> Weight { + (55405000 as Weight) + .saturating_add((774000 as Weight).saturating_mul(a as Weight)) + .saturating_add((209000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn remove_announcement(a: u32, p: u32, ) -> Weight { + (35879000 as Weight) + .saturating_add((783000 as Weight).saturating_mul(a as Weight)) + .saturating_add((20000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn reject_announcement(a: u32, p: u32, ) -> Weight { + (36097000 as Weight) + .saturating_add((780000 as Weight).saturating_mul(a as Weight)) + .saturating_add((12000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn announce(a: u32, p: u32, ) -> Weight { + (53769000 as Weight) + .saturating_add((675000 as Weight).saturating_mul(a as Weight)) + .saturating_add((214000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn add_proxy(p: u32, ) -> Weight { + (36082000 as Weight) + .saturating_add((234000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn remove_proxy(p: u32, ) -> Weight { + (32885000 as Weight) + .saturating_add((267000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn remove_proxies(p: u32, ) -> Weight { + (31735000 as Weight) + .saturating_add((215000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn anonymous(p: u32, ) -> Weight { + (50907000 as Weight) + .saturating_add((61000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn kill_anonymous(p: u32, ) -> Weight { + (33926000 as Weight) + .saturating_add((208000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } +} diff --git a/frame/proxy/src/lib.rs b/frame/proxy/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..5a852ea9f5314a7ca865e7e7fb12961443457ef3 --- /dev/null +++ b/frame/proxy/src/lib.rs @@ -0,0 +1,677 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! # Proxy Module +//! A module allowing accounts to give permission to other accounts to dispatch types of calls from +//! their signed origin. +//! +//! The accounts to which permission is delegated may be requied to announce the action that they +//! wish to execute some duration prior to execution happens. In this case, the target account may +//! reject the announcement and in doing so, veto the execution. +//! +//! - [`proxy::Trait`](./trait.Trait.html) +//! - [`Call`](./enum.Call.html) +//! +//! ## Overview +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! [`Call`]: ./enum.Call.html +//! [`Trait`]: ./trait.Trait.html + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +use sp_std::prelude::*; +use codec::{Encode, Decode}; +use sp_io::hashing::blake2_256; +use sp_runtime::{DispatchResult, traits::{Dispatchable, Zero, Hash, Member, Saturating}}; +use frame_support::{ + decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug, traits::{ + Get, ReservableCurrency, Currency, InstanceFilter, OriginTrait, IsType, + }, weights::{Weight, GetDispatchInfo}, + dispatch::{PostDispatchInfo, IsSubType}, storage::IterableStorageMap, +}; +use frame_system::{self as system, ensure_signed}; +use frame_support::dispatch::DispatchError; + +mod tests; +mod benchmarking; +mod default_weight; + +type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; + +pub trait WeightInfo { + fn proxy_announced(a: u32, p: u32, ) -> Weight; + fn remove_announcement(a: u32, p: u32, ) -> Weight; + fn reject_announcement(a: u32, p: u32, ) -> Weight; + fn announce(a: u32, p: u32, ) -> Weight; + fn proxy(p: u32, ) -> Weight; + fn add_proxy(p: u32, ) -> Weight; + fn remove_proxy(p: u32, ) -> Weight; + fn remove_proxies(p: u32, ) -> Weight; + fn anonymous(p: u32, ) -> Weight; + fn kill_anonymous(p: u32, ) -> Weight; +} + +/// Configuration trait. +pub trait Trait: frame_system::Trait { + /// The overarching event type. + type Event: From> + Into<::Event>; + + /// The overarching call type. + type Call: Parameter + Dispatchable + + GetDispatchInfo + From> + IsSubType> + + IsType<::Call>; + + /// The currency mechanism. + type Currency: ReservableCurrency; + + /// A kind of proxy; specified with the proxy and passed in to the `IsProxyable` fitler. + /// The instance filter determines whether a given call may be proxied under this type. + /// + /// IMPORTANT: `Default` must be provided and MUST BE the the *most permissive* value. + type ProxyType: Parameter + Member + Ord + PartialOrd + InstanceFilter<::Call> + + Default; + + /// The base amount of currency needed to reserve for creating a proxy. + /// + /// This is held for an additional storage item whose value size is + /// `sizeof(Balance)` bytes and whose key size is `sizeof(AccountId)` bytes. + type ProxyDepositBase: Get>; + + /// The amount of currency needed per proxy added. + /// + /// This is held for adding 32 bytes plus an instance of `ProxyType` more into a pre-existing + /// storage value. + type ProxyDepositFactor: Get>; + + /// The maximum amount of proxies allowed for a single account. + type MaxProxies: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + + /// The maximum amount of time-delayed announcements that are allowed to be pending. + type MaxPending: Get; + + /// The type of hash used for hashing the call. + type CallHasher: Hash; + + /// The base amount of currency needed to reserve for creating an announcement. + /// + /// This is held when a new storage item holding a `Balance` is created (typically 16 bytes). + type AnnouncementDepositBase: Get>; + + /// The amount of currency needed per announcement made. + /// + /// This is held for adding an `AccountId`, `Hash` and `BlockNumber` (typically 68 bytes) + /// into a pre-existing storage value. + type AnnouncementDepositFactor: Get>; +} + +/// The parameters under which a particular account has a proxy relationship with some other +/// account. +#[derive(Encode, Decode, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)] +pub struct ProxyDefinition { + /// The account which may act on behalf of another. + delegate: AccountId, + /// A value defining the subset of calls that it is allowed to make. + proxy_type: ProxyType, + /// The number of blocks that an announcement must be in place for before the corresponding call + /// may be dispatched. If zero, then no announcement is needed. + delay: BlockNumber, +} + +/// Details surrounding a specific instance of an announcement to make a call. +#[derive(Encode, Decode, Clone, Copy, Eq, PartialEq, RuntimeDebug)] +pub struct Announcement { + /// The account which made the announcement. + real: AccountId, + /// The hash of the call to be made. + call_hash: Hash, + /// The height at which the announcement was made. + height: BlockNumber, +} + +type CallHashOf = <::CallHasher as Hash>::Output; + +decl_storage! { + trait Store for Module as Proxy { + /// The set of account proxies. Maps the account which has delegated to the accounts + /// which are being delegated to, together with the amount held on deposit. + pub Proxies: map hasher(twox_64_concat) T::AccountId + => (Vec>, BalanceOf); + + /// The announcements made by the proxy (key). + pub Announcements: map hasher(twox_64_concat) T::AccountId + => (Vec, T::BlockNumber>>, BalanceOf); + } +} + +decl_error! { + pub enum Error for Module { + /// There are too many proxies registered or too many announcements pending. + TooMany, + /// Proxy registration not found. + NotFound, + /// Sender is not a proxy of the account to be proxied. + NotProxy, + /// A call which is incompatible with the proxy type's filter was attempted. + Unproxyable, + /// Account is already a proxy. + Duplicate, + /// Call may not be made by proxy because it may escalate its privileges. + NoPermission, + /// Announcement, if made at all, was made too recently. + Unannounced, + } +} + +decl_event! { + /// Events type. + pub enum Event where + AccountId = ::AccountId, + ProxyType = ::ProxyType, + Hash = CallHashOf, + { + /// A proxy was executed correctly, with the given [result]. + ProxyExecuted(DispatchResult), + /// Anonymous account has been created by new proxy with given + /// disambiguation index and proxy type. [anonymous, who, proxy_type, disambiguation_index] + AnonymousCreated(AccountId, AccountId, ProxyType, u16), + /// An announcement was placed to make a call in the future. [real, proxy, call_hash] + Announced(AccountId, AccountId, Hash), + } +} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + + /// Deposit one of this module's events by using the default implementation. + fn deposit_event() = default; + + /// The base amount of currency needed to reserve for creating a proxy. + const ProxyDepositBase: BalanceOf = T::ProxyDepositBase::get(); + + /// The amount of currency needed per proxy added. + const ProxyDepositFactor: BalanceOf = T::ProxyDepositFactor::get(); + + /// The maximum amount of proxies allowed for a single account. + const MaxProxies: u16 = T::MaxProxies::get(); + + /// `MaxPending` metadata shadow. + const MaxPending: u32 = T::MaxPending::get(); + + /// `AnnouncementDepositBase` metadata shadow. + const AnnouncementDepositBase: BalanceOf = T::AnnouncementDepositBase::get(); + + /// `AnnouncementDepositFactor` metadata shadow. + const AnnouncementDepositFactor: BalanceOf = T::AnnouncementDepositFactor::get(); + + fn on_runtime_upgrade() -> Weight { + Proxies::::translate::<(Vec<(T::AccountId, T::ProxyType)>, BalanceOf), _>( + |_, (targets, deposit)| Some(( + targets.into_iter() + .map(|(a, t)| ProxyDefinition { + delegate: a, + proxy_type: t, + delay: Zero::zero(), + }) + .collect::>(), + deposit, + )) + ); + T::MaximumBlockWeight::get() + } + + /// Dispatch the given `call` from an account that the sender is authorised for through + /// `add_proxy`. + /// + /// Removes any corresponding announcement(s). + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// Parameters: + /// - `real`: The account that the proxy will make a call on behalf of. + /// - `force_proxy_type`: Specify the exact proxy type to be used and checked for this call. + /// - `call`: The call to be made by the `real` account. + /// + /// # + /// Weight is a function of the number of proxies the user has (P). + /// # + #[weight = { + let di = call.get_dispatch_info(); + (T::WeightInfo::proxy(T::MaxProxies::get().into()) + .saturating_add(di.weight), + di.class) + }] + fn proxy(origin, + real: T::AccountId, + force_proxy_type: Option, + call: Box<::Call>, + ) { + let who = ensure_signed(origin)?; + let def = Self::find_proxy(&real, &who, force_proxy_type)?; + ensure!(def.delay.is_zero(), Error::::Unannounced); + + Self::do_proxy(def, real, *call); + } + + /// Register a proxy account for the sender that is able to make calls on its behalf. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// Parameters: + /// - `proxy`: The account that the `caller` would like to make a proxy. + /// - `proxy_type`: The permissions allowed for this proxy account. + /// + /// # + /// Weight is a function of the number of proxies the user has (P). + /// # + #[weight = T::WeightInfo::add_proxy(T::MaxProxies::get().into())] + fn add_proxy(origin, + delegate: T::AccountId, + proxy_type: T::ProxyType, + delay: T::BlockNumber, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Proxies::::try_mutate(&who, |(ref mut proxies, ref mut deposit)| { + ensure!(proxies.len() < T::MaxProxies::get() as usize, Error::::TooMany); + let proxy_def = ProxyDefinition { delegate, proxy_type, delay }; + let i = proxies.binary_search(&proxy_def).err().ok_or(Error::::Duplicate)?; + proxies.insert(i, proxy_def); + let new_deposit = T::ProxyDepositBase::get() + + T::ProxyDepositFactor::get() * (proxies.len() as u32).into(); + if new_deposit > *deposit { + T::Currency::reserve(&who, new_deposit - *deposit)?; + } else if new_deposit < *deposit { + T::Currency::unreserve(&who, *deposit - new_deposit); + } + *deposit = new_deposit; + Ok(()) + }) + } + + /// Unregister a proxy account for the sender. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// Parameters: + /// - `proxy`: The account that the `caller` would like to remove as a proxy. + /// - `proxy_type`: The permissions currently enabled for the removed proxy account. + /// + /// # + /// Weight is a function of the number of proxies the user has (P). + /// # + #[weight = T::WeightInfo::remove_proxy(T::MaxProxies::get().into())] + fn remove_proxy(origin, + delegate: T::AccountId, + proxy_type: T::ProxyType, + delay: T::BlockNumber, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Proxies::::try_mutate_exists(&who, |x| { + let (mut proxies, old_deposit) = x.take().ok_or(Error::::NotFound)?; + let proxy_def = ProxyDefinition { delegate, proxy_type, delay }; + let i = proxies.binary_search(&proxy_def).ok().ok_or(Error::::NotFound)?; + proxies.remove(i); + let new_deposit = if proxies.is_empty() { + BalanceOf::::zero() + } else { + T::ProxyDepositBase::get() + T::ProxyDepositFactor::get() * (proxies.len() as u32).into() + }; + if new_deposit > old_deposit { + T::Currency::reserve(&who, new_deposit - old_deposit)?; + } else if new_deposit < old_deposit { + T::Currency::unreserve(&who, old_deposit - new_deposit); + } + if !proxies.is_empty() { + *x = Some((proxies, new_deposit)) + } + Ok(()) + }) + } + + /// Unregister all proxy accounts for the sender. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// WARNING: This may be called on accounts created by `anonymous`, however if done, then + /// the unreserved fees will be inaccessible. **All access to this account will be lost.** + /// + /// # + /// Weight is a function of the number of proxies the user has (P). + /// # + #[weight = T::WeightInfo::remove_proxies(T::MaxProxies::get().into())] + fn remove_proxies(origin) { + let who = ensure_signed(origin)?; + let (_, old_deposit) = Proxies::::take(&who); + T::Currency::unreserve(&who, old_deposit); + } + + /// Spawn a fresh new account that is guaranteed to be otherwise inaccessible, and + /// initialize it with a proxy of `proxy_type` for `origin` sender. + /// + /// Requires a `Signed` origin. + /// + /// - `proxy_type`: The type of the proxy that the sender will be registered as over the + /// new account. This will almost always be the most permissive `ProxyType` possible to + /// allow for maximum flexibility. + /// - `index`: A disambiguation index, in case this is called multiple times in the same + /// transaction (e.g. with `utility::batch`). Unless you're using `batch` you probably just + /// want to use `0`. + /// - `delay`: The announcement period required of the initial proxy. Will generally be + /// zero. + /// + /// Fails with `Duplicate` if this has already been called in this transaction, from the + /// same sender, with the same parameters. + /// + /// Fails if there are insufficient funds to pay for deposit. + /// + /// # + /// Weight is a function of the number of proxies the user has (P). + /// # + /// TODO: Might be over counting 1 read + #[weight = T::WeightInfo::anonymous(T::MaxProxies::get().into())] + fn anonymous(origin, proxy_type: T::ProxyType, delay: T::BlockNumber, index: u16) { + let who = ensure_signed(origin)?; + + let anonymous = Self::anonymous_account(&who, &proxy_type, index, None); + ensure!(!Proxies::::contains_key(&anonymous), Error::::Duplicate); + let deposit = T::ProxyDepositBase::get() + T::ProxyDepositFactor::get(); + T::Currency::reserve(&who, deposit)?; + let proxy_def = ProxyDefinition { + delegate: who.clone(), + proxy_type: proxy_type.clone(), + delay, + }; + Proxies::::insert(&anonymous, (vec![proxy_def], deposit)); + Self::deposit_event(RawEvent::AnonymousCreated(anonymous, who, proxy_type, index)); + } + + /// Removes a previously spawned anonymous proxy. + /// + /// WARNING: **All access to this account will be lost.** Any funds held in it will be + /// inaccessible. + /// + /// Requires a `Signed` origin, and the sender account must have been created by a call to + /// `anonymous` with corresponding parameters. + /// + /// - `spawner`: The account that originally called `anonymous` to create this account. + /// - `index`: The disambiguation index originally passed to `anonymous`. Probably `0`. + /// - `proxy_type`: The proxy type originally passed to `anonymous`. + /// - `height`: The height of the chain when the call to `anonymous` was processed. + /// - `ext_index`: The extrinsic index in which the call to `anonymous` was processed. + /// + /// Fails with `NoPermission` in case the caller is not a previously created anonymous + /// account whose `anonymous` call has corresponding parameters. + /// + /// # + /// Weight is a function of the number of proxies the user has (P). + /// # + #[weight = T::WeightInfo::kill_anonymous(T::MaxProxies::get().into())] + fn kill_anonymous(origin, + spawner: T::AccountId, + proxy_type: T::ProxyType, + index: u16, + #[compact] height: T::BlockNumber, + #[compact] ext_index: u32, + ) { + let who = ensure_signed(origin)?; + + let when = (height, ext_index); + let proxy = Self::anonymous_account(&spawner, &proxy_type, index, Some(when)); + ensure!(proxy == who, Error::::NoPermission); + + let (_, deposit) = Proxies::::take(&who); + T::Currency::unreserve(&spawner, deposit); + } + + /// Publish the hash of a proxy-call that will be made in the future. + /// + /// This must be called some number of blocks before the corresponding `proxy` is attempted + /// if the delay associated with the proxy relationship is greater than zero. + /// + /// No more than `MaxPending` announcements may be made at any one time. + /// + /// This will take a deposit of `AnnouncementDepositFactor` as well as + /// `AnnouncementDepositBase` if there are no other pending announcements. + /// + /// The dispatch origin for this call must be _Signed_ and a proxy of `real`. + /// + /// Parameters: + /// - `real`: The account that the proxy will make a call on behalf of. + /// - `call_hash`: The hash of the call to be made by the `real` account. + /// + /// # + /// Weight is a function of: + /// - A: the number of announcements made. + /// - P: the number of proxies the user has. + /// # + #[weight = T::WeightInfo::announce(T::MaxPending::get(), T::MaxProxies::get().into())] + fn announce(origin, real: T::AccountId, call_hash: CallHashOf) { + let who = ensure_signed(origin)?; + Proxies::::get(&real).0.into_iter() + .find(|x| &x.delegate == &who) + .ok_or(Error::::NotProxy)?; + + let announcement = Announcement { + real: real.clone(), + call_hash: call_hash.clone(), + height: system::Module::::block_number(), + }; + + Announcements::::try_mutate(&who, |(ref mut pending, ref mut deposit)| { + ensure!(pending.len() < T::MaxPending::get() as usize, Error::::TooMany); + pending.push(announcement); + Self::rejig_deposit( + &who, + *deposit, + T::AnnouncementDepositBase::get(), + T::AnnouncementDepositFactor::get(), + pending.len(), + ).map(|d| d.expect("Just pushed; pending.len() > 0; rejig_deposit returns Some; qed")) + .map(|d| *deposit = d) + })?; + Self::deposit_event(RawEvent::Announced(real, who, call_hash)); + } + + /// Remove a given announcement. + /// + /// May be called by a proxy account to remove a call they previously announced and return + /// the deposit. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// Parameters: + /// - `real`: The account that the proxy will make a call on behalf of. + /// - `call_hash`: The hash of the call to be made by the `real` account. + /// + /// # + /// Weight is a function of: + /// - A: the number of announcements made. + /// - P: the number of proxies the user has. + /// # + #[weight = T::WeightInfo::remove_announcement(T::MaxPending::get(), T::MaxProxies::get().into())] + fn remove_announcement(origin, real: T::AccountId, call_hash: CallHashOf) { + let who = ensure_signed(origin)?; + Self::edit_announcements(&who, |ann| ann.real != real || ann.call_hash != call_hash)?; + } + + /// Remove the given announcement of a delegate. + /// + /// May be called by a target (proxied) account to remove a call that one of their delegates + /// (`delegate`) has announced they want to execute. The deposit is returned. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// Parameters: + /// - `delegate`: The account that previously announced the call. + /// - `call_hash`: The hash of the call to be made. + /// + /// # + /// Weight is a function of: + /// - A: the number of announcements made. + /// - P: the number of proxies the user has. + /// # + #[weight = T::WeightInfo::reject_announcement(T::MaxPending::get(), T::MaxProxies::get().into())] + fn reject_announcement(origin, delegate: T::AccountId, call_hash: CallHashOf) { + let who = ensure_signed(origin)?; + Self::edit_announcements(&delegate, |ann| ann.real != who || ann.call_hash != call_hash)?; + } + + /// Dispatch the given `call` from an account that the sender is authorised for through + /// `add_proxy`. + /// + /// Removes any corresponding announcement(s). + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// Parameters: + /// - `real`: The account that the proxy will make a call on behalf of. + /// - `force_proxy_type`: Specify the exact proxy type to be used and checked for this call. + /// - `call`: The call to be made by the `real` account. + /// + /// # + /// Weight is a function of: + /// - A: the number of announcements made. + /// - P: the number of proxies the user has. + /// # + #[weight = { + let di = call.get_dispatch_info(); + (T::WeightInfo::proxy_announced(T::MaxPending::get(), T::MaxProxies::get().into()) + .saturating_add(di.weight), + di.class) + }] + fn proxy_announced(origin, + delegate: T::AccountId, + real: T::AccountId, + force_proxy_type: Option, + call: Box<::Call>, + ) { + ensure_signed(origin)?; + let def = Self::find_proxy(&real, &delegate, force_proxy_type)?; + + let call_hash = T::CallHasher::hash_of(&call); + let now = system::Module::::block_number(); + Self::edit_announcements(&delegate, |ann| + ann.real != real || ann.call_hash != call_hash || now.saturating_sub(ann.height) < def.delay + ).map_err(|_| Error::::Unannounced)?; + + Self::do_proxy(def, real, *call); + } + } +} + +impl Module { + pub fn anonymous_account( + who: &T::AccountId, + proxy_type: &T::ProxyType, + index: u16, + maybe_when: Option<(T::BlockNumber, u32)>, + ) -> T::AccountId { + let (height, ext_index) = maybe_when.unwrap_or_else(|| ( + system::Module::::block_number(), + system::Module::::extrinsic_index().unwrap_or_default() + )); + let entropy = (b"modlpy/proxy____", who, height, ext_index, proxy_type, index) + .using_encoded(blake2_256); + T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() + } + + fn rejig_deposit( + who: &T::AccountId, + old_deposit: BalanceOf, + base: BalanceOf, + factor: BalanceOf, + len: usize, + ) -> Result>, DispatchError> { + let new_deposit = if len == 0 { + BalanceOf::::zero() + } else { + base + factor * (len as u32).into() + }; + if new_deposit > old_deposit { + T::Currency::reserve(&who, new_deposit - old_deposit)?; + } else if new_deposit < old_deposit { + T::Currency::unreserve(&who, old_deposit - new_deposit); + } + Ok(if len == 0 { + None + } else { + Some(new_deposit) + }) + } + + fn edit_announcements< + F: FnMut(&Announcement, T::BlockNumber>) -> bool + >(delegate: &T::AccountId, f: F) -> DispatchResult { + Announcements::::try_mutate_exists(delegate, |x| { + let (mut pending, old_deposit) = x.take().ok_or(Error::::NotFound)?; + let orig_pending_len = pending.len(); + pending.retain(f); + ensure!(orig_pending_len > pending.len(), Error::::NotFound); + *x = Self::rejig_deposit( + delegate, + old_deposit, + T::AnnouncementDepositBase::get(), + T::AnnouncementDepositFactor::get(), + pending.len(), + )?.map(|deposit| (pending, deposit)); + Ok(()) + }) + } + + fn find_proxy( + real: &T::AccountId, + delegate: &T::AccountId, + force_proxy_type: Option, + ) -> Result, DispatchError> { + let f = |x: &ProxyDefinition| -> bool { + &x.delegate == delegate && force_proxy_type.as_ref().map_or(true, |y| &x.proxy_type == y) + }; + Ok(Proxies::::get(real).0.into_iter().find(f).ok_or(Error::::NotProxy)?) + } + + fn do_proxy( + def: ProxyDefinition, + real: T::AccountId, + call: ::Call, + ) { + // This is a freshly authenticated new account, the origin restrictions doesn't apply. + let mut origin: T::Origin = frame_system::RawOrigin::Signed(real).into(); + origin.add_filter(move |c: &::Call| { + let c = ::Call::from_ref(c); + // We make sure the proxy call does access this pallet to change modify proxies. + match c.is_sub_type() { + // Proxy call cannot add or remove a proxy with more permissions than it already has. + Some(Call::add_proxy(_, ref pt, _)) | Some(Call::remove_proxy(_, ref pt, _)) + if !def.proxy_type.is_superset(&pt) => false, + // Proxy call cannot remove all proxies or kill anonymous proxies unless it has full permissions. + Some(Call::remove_proxies(..)) | Some(Call::kill_anonymous(..)) + if def.proxy_type != T::ProxyType::default() => false, + _ => def.proxy_type.filter(c) + } + }); + let e = call.dispatch(origin); + Self::deposit_event(RawEvent::ProxyExecuted(e.map(|_| ()).map_err(|e| e.error))); + } +} diff --git a/frame/proxy/src/tests.rs b/frame/proxy/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..00d84e65ad1d69c6a92aca6390f52026be8ef8c1 --- /dev/null +++ b/frame/proxy/src/tests.rs @@ -0,0 +1,485 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +// Tests for Proxy Pallet + +#![cfg(test)] + +use super::*; + +use frame_support::{ + assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch, + weights::Weight, impl_outer_event, RuntimeDebug, dispatch::DispatchError, traits::Filter, +}; +use codec::{Encode, Decode}; +use sp_core::H256; +use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; +use crate as proxy; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} +impl_outer_event! { + pub enum TestEvent for Test { + system, + pallet_balances, + proxy, + pallet_utility, + } +} +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + frame_system::System, + pallet_balances::Balances, + proxy::Proxy, + pallet_utility::Utility, + } +} + +// For testing the pallet, we construct most of a mock runtime. This means +// first constructing a configuration type (`Test`) which `impl`s each of the +// configuration traits of pallets we want to use. +#[derive(Clone, Eq, PartialEq)] +pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl frame_system::Trait for Test { + type BaseCallFilter = BaseFilter; + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = Call; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = TestEvent; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Trait for Test { + type Balance = u64; + type Event = TestEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} +impl pallet_utility::Trait for Test { + type Event = TestEvent; + type Call = Call; + type WeightInfo = (); +} +parameter_types! { + pub const ProxyDepositBase: u64 = 1; + pub const ProxyDepositFactor: u64 = 1; + pub const MaxProxies: u16 = 4; + pub const MaxPending: u32 = 2; + pub const AnnouncementDepositBase: u64 = 1; + pub const AnnouncementDepositFactor: u64 = 1; +} +#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug)] +pub enum ProxyType { + Any, + JustTransfer, + JustUtility, +} +impl Default for ProxyType { fn default() -> Self { Self::Any } } +impl InstanceFilter for ProxyType { + fn filter(&self, c: &Call) -> bool { + match self { + ProxyType::Any => true, + ProxyType::JustTransfer => matches!(c, Call::Balances(pallet_balances::Call::transfer(..))), + ProxyType::JustUtility => matches!(c, Call::Utility(..)), + } + } + fn is_superset(&self, o: &Self) -> bool { + self == &ProxyType::Any || self == o + } +} +pub struct BaseFilter; +impl Filter for BaseFilter { + fn filter(c: &Call) -> bool { + match *c { + // Remark is used as a no-op call in the benchmarking + Call::System(SystemCall::remark(_)) => true, + Call::System(_) => false, + _ => true, + } + } +} +impl Trait for Test { + type Event = TestEvent; + type Call = Call; + type Currency = Balances; + type ProxyType = ProxyType; + type ProxyDepositBase = ProxyDepositBase; + type ProxyDepositFactor = ProxyDepositFactor; + type MaxProxies = MaxProxies; + type WeightInfo = (); + type CallHasher = BlakeTwo256; + type MaxPending = MaxPending; + type AnnouncementDepositBase = AnnouncementDepositBase; + type AnnouncementDepositFactor = AnnouncementDepositFactor; +} + +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type Utility = pallet_utility::Module; +type Proxy = Module; + +use frame_system::Call as SystemCall; +use pallet_balances::Call as BalancesCall; +use pallet_balances::Error as BalancesError; +use pallet_balances::Event as BalancesEvent; +use pallet_utility::Call as UtilityCall; +use pallet_utility::Event as UtilityEvent; +use super::Call as ProxyCall; + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 2)], + }.assimilate_storage(&mut t).unwrap(); + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn last_event() -> TestEvent { + system::Module::::events().pop().expect("Event expected").event +} + +fn expect_event>(e: E) { + assert_eq!(last_event(), e.into()); +} + +fn last_events(n: usize) -> Vec { + system::Module::::events().into_iter().rev().take(n).rev().map(|e| e.event).collect() +} + +fn expect_events(e: Vec) { + assert_eq!(last_events(e.len()), e); +} + +#[test] +fn announcement_works() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy(Origin::signed(1), 3, ProxyType::Any, 1)); + assert_ok!(Proxy::add_proxy(Origin::signed(2), 3, ProxyType::Any, 1)); + assert_eq!(Balances::reserved_balance(3), 0); + + assert_ok!(Proxy::announce(Origin::signed(3), 1, [1; 32].into())); + assert_eq!(Announcements::::get(3), (vec![Announcement { + real: 1, + call_hash: [1; 32].into(), + height: 1, + }], 2)); + assert_eq!(Balances::reserved_balance(3), 2); + + assert_ok!(Proxy::announce(Origin::signed(3), 2, [2; 32].into())); + assert_eq!(Announcements::::get(3), (vec![ + Announcement { + real: 1, + call_hash: [1; 32].into(), + height: 1, + }, + Announcement { + real: 2, + call_hash: [2; 32].into(), + height: 1, + }, + ], 3)); + assert_eq!(Balances::reserved_balance(3), 3); + + assert_noop!(Proxy::announce(Origin::signed(3), 2, [3; 32].into()), Error::::TooMany); + }); +} + +#[test] +fn remove_announcement_works() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy(Origin::signed(1), 3, ProxyType::Any, 1)); + assert_ok!(Proxy::add_proxy(Origin::signed(2), 3, ProxyType::Any, 1)); + assert_ok!(Proxy::announce(Origin::signed(3), 1, [1; 32].into())); + assert_ok!(Proxy::announce(Origin::signed(3), 2, [2; 32].into())); + let e = Error::::NotFound; + assert_noop!(Proxy::remove_announcement(Origin::signed(3), 1, [0; 32].into()), e); + assert_ok!(Proxy::remove_announcement(Origin::signed(3), 1, [1; 32].into())); + assert_eq!(Announcements::::get(3), (vec![Announcement { + real: 2, + call_hash: [2; 32].into(), + height: 1, + }], 2)); + assert_eq!(Balances::reserved_balance(3), 2); + }); +} + +#[test] +fn reject_announcement_works() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy(Origin::signed(1), 3, ProxyType::Any, 1)); + assert_ok!(Proxy::add_proxy(Origin::signed(2), 3, ProxyType::Any, 1)); + assert_ok!(Proxy::announce(Origin::signed(3), 1, [1; 32].into())); + assert_ok!(Proxy::announce(Origin::signed(3), 2, [2; 32].into())); + let e = Error::::NotFound; + assert_noop!(Proxy::reject_announcement(Origin::signed(1), 3, [0; 32].into()), e); + let e = Error::::NotFound; + assert_noop!(Proxy::reject_announcement(Origin::signed(4), 3, [1; 32].into()), e); + assert_ok!(Proxy::reject_announcement(Origin::signed(1), 3, [1; 32].into())); + assert_eq!(Announcements::::get(3), (vec![Announcement { + real: 2, + call_hash: [2; 32].into(), + height: 1, + }], 2)); + assert_eq!(Balances::reserved_balance(3), 2); + }); +} + +#[test] +fn announcer_must_be_proxy() { + new_test_ext().execute_with(|| { + assert_noop!(Proxy::announce(Origin::signed(2), 1, H256::zero()), Error::::NotProxy); + }); +} + +#[test] +fn delayed_requires_pre_announcement() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy(Origin::signed(1), 2, ProxyType::Any, 1)); + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 1))); + let e = Error::::Unannounced; + assert_noop!(Proxy::proxy(Origin::signed(2), 1, None, call.clone()), e); + let e = Error::::Unannounced; + assert_noop!(Proxy::proxy_announced(Origin::signed(0), 2, 1, None, call.clone()), e); + let call_hash = BlakeTwo256::hash_of(&call); + assert_ok!(Proxy::announce(Origin::signed(2), 1, call_hash)); + system::Module::::set_block_number(2); + assert_ok!(Proxy::proxy_announced(Origin::signed(0), 2, 1, None, call.clone())); + }); +} + +#[test] +fn proxy_announced_removes_announcement_and_returns_deposit() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy(Origin::signed(1), 3, ProxyType::Any, 1)); + assert_ok!(Proxy::add_proxy(Origin::signed(2), 3, ProxyType::Any, 1)); + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 1))); + let call_hash = BlakeTwo256::hash_of(&call); + assert_ok!(Proxy::announce(Origin::signed(3), 1, call_hash)); + assert_ok!(Proxy::announce(Origin::signed(3), 2, call_hash)); + // Too early to execute announced call + let e = Error::::Unannounced; + assert_noop!(Proxy::proxy_announced(Origin::signed(0), 3, 1, None, call.clone()), e); + + system::Module::::set_block_number(2); + assert_ok!(Proxy::proxy_announced(Origin::signed(0), 3, 1, None, call.clone())); + assert_eq!(Announcements::::get(3), (vec![Announcement { + real: 2, + call_hash, + height: 1, + }], 2)); + assert_eq!(Balances::reserved_balance(3), 2); + }); +} + +#[test] +fn filtering_works() { + new_test_ext().execute_with(|| { + Balances::mutate_account(&1, |a| a.free = 1000); + assert_ok!(Proxy::add_proxy(Origin::signed(1), 2, ProxyType::Any, 0)); + assert_ok!(Proxy::add_proxy(Origin::signed(1), 3, ProxyType::JustTransfer, 0)); + assert_ok!(Proxy::add_proxy(Origin::signed(1), 4, ProxyType::JustUtility, 0)); + + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 1))); + assert_ok!(Proxy::proxy(Origin::signed(2), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Ok(()))); + assert_ok!(Proxy::proxy(Origin::signed(3), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Ok(()))); + assert_ok!(Proxy::proxy(Origin::signed(4), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); + + let derivative_id = Utility::derivative_account_id(1, 0); + Balances::mutate_account(&derivative_id, |a| a.free = 1000); + let inner = Box::new(Call::Balances(BalancesCall::transfer(6, 1))); + + let call = Box::new(Call::Utility(UtilityCall::as_derivative(0, inner.clone()))); + assert_ok!(Proxy::proxy(Origin::signed(2), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Ok(()))); + assert_ok!(Proxy::proxy(Origin::signed(3), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); + assert_ok!(Proxy::proxy(Origin::signed(4), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); + + let call = Box::new(Call::Utility(UtilityCall::batch(vec![*inner]))); + assert_ok!(Proxy::proxy(Origin::signed(2), 1, None, call.clone())); + expect_events(vec![UtilityEvent::BatchCompleted.into(), RawEvent::ProxyExecuted(Ok(())).into()]); + assert_ok!(Proxy::proxy(Origin::signed(3), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); + assert_ok!(Proxy::proxy(Origin::signed(4), 1, None, call.clone())); + expect_events(vec![ + UtilityEvent::BatchInterrupted(0, DispatchError::BadOrigin).into(), + RawEvent::ProxyExecuted(Ok(())).into(), + ]); + + let inner = Box::new(Call::Proxy(ProxyCall::add_proxy(5, ProxyType::Any, 0))); + let call = Box::new(Call::Utility(UtilityCall::batch(vec![*inner]))); + assert_ok!(Proxy::proxy(Origin::signed(2), 1, None, call.clone())); + expect_events(vec![UtilityEvent::BatchCompleted.into(), RawEvent::ProxyExecuted(Ok(())).into()]); + assert_ok!(Proxy::proxy(Origin::signed(3), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); + assert_ok!(Proxy::proxy(Origin::signed(4), 1, None, call.clone())); + expect_events(vec![ + UtilityEvent::BatchInterrupted(0, DispatchError::BadOrigin).into(), + RawEvent::ProxyExecuted(Ok(())).into(), + ]); + + let call = Box::new(Call::Proxy(ProxyCall::remove_proxies())); + assert_ok!(Proxy::proxy(Origin::signed(3), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); + assert_ok!(Proxy::proxy(Origin::signed(4), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); + assert_ok!(Proxy::proxy(Origin::signed(2), 1, None, call.clone())); + expect_events(vec![BalancesEvent::::Unreserved(1, 5).into(), RawEvent::ProxyExecuted(Ok(())).into()]); + }); +} + +#[test] +fn add_remove_proxies_works() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy(Origin::signed(1), 2, ProxyType::Any, 0)); + assert_noop!(Proxy::add_proxy(Origin::signed(1), 2, ProxyType::Any, 0), Error::::Duplicate); + assert_eq!(Balances::reserved_balance(1), 2); + assert_ok!(Proxy::add_proxy(Origin::signed(1), 2, ProxyType::JustTransfer, 0)); + assert_eq!(Balances::reserved_balance(1), 3); + assert_ok!(Proxy::add_proxy(Origin::signed(1), 3, ProxyType::Any, 0)); + assert_eq!(Balances::reserved_balance(1), 4); + assert_ok!(Proxy::add_proxy(Origin::signed(1), 4, ProxyType::JustUtility, 0)); + assert_eq!(Balances::reserved_balance(1), 5); + assert_noop!(Proxy::add_proxy(Origin::signed(1), 4, ProxyType::Any, 0), Error::::TooMany); + assert_noop!(Proxy::remove_proxy(Origin::signed(1), 3, ProxyType::JustTransfer, 0), Error::::NotFound); + assert_ok!(Proxy::remove_proxy(Origin::signed(1), 4, ProxyType::JustUtility, 0)); + assert_eq!(Balances::reserved_balance(1), 4); + assert_ok!(Proxy::remove_proxy(Origin::signed(1), 3, ProxyType::Any, 0)); + assert_eq!(Balances::reserved_balance(1), 3); + assert_ok!(Proxy::remove_proxy(Origin::signed(1), 2, ProxyType::Any, 0)); + assert_eq!(Balances::reserved_balance(1), 2); + assert_ok!(Proxy::remove_proxy(Origin::signed(1), 2, ProxyType::JustTransfer, 0)); + assert_eq!(Balances::reserved_balance(1), 0); + }); +} + +#[test] +fn cannot_add_proxy_without_balance() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy(Origin::signed(5), 3, ProxyType::Any, 0)); + assert_eq!(Balances::reserved_balance(5), 2); + assert_noop!( + Proxy::add_proxy(Origin::signed(5), 4, ProxyType::Any, 0), + BalancesError::::InsufficientBalance + ); + }); +} + +#[test] +fn proxying_works() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy(Origin::signed(1), 2, ProxyType::JustTransfer, 0)); + assert_ok!(Proxy::add_proxy(Origin::signed(1), 3, ProxyType::Any, 0)); + + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 1))); + assert_noop!(Proxy::proxy(Origin::signed(4), 1, None, call.clone()), Error::::NotProxy); + assert_noop!( + Proxy::proxy(Origin::signed(2), 1, Some(ProxyType::Any), call.clone()), + Error::::NotProxy + ); + assert_ok!(Proxy::proxy(Origin::signed(2), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Ok(()))); + assert_eq!(Balances::free_balance(6), 1); + + let call = Box::new(Call::System(SystemCall::set_code(vec![]))); + assert_ok!(Proxy::proxy(Origin::signed(3), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); + + let call = Box::new(Call::Balances(BalancesCall::transfer_keep_alive(6, 1))); + assert_ok!(Call::Proxy(super::Call::proxy(1, None, call.clone())).dispatch(Origin::signed(2))); + expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); + assert_ok!(Proxy::proxy(Origin::signed(3), 1, None, call.clone())); + expect_event(RawEvent::ProxyExecuted(Ok(()))); + assert_eq!(Balances::free_balance(6), 2); + }); +} + +#[test] +fn anonymous_works() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::anonymous(Origin::signed(1), ProxyType::Any, 0, 0)); + let anon = Proxy::anonymous_account(&1, &ProxyType::Any, 0, None); + expect_event(RawEvent::AnonymousCreated(anon.clone(), 1, ProxyType::Any, 0)); + + // other calls to anonymous allowed as long as they're not exactly the same. + assert_ok!(Proxy::anonymous(Origin::signed(1), ProxyType::JustTransfer, 0, 0)); + assert_ok!(Proxy::anonymous(Origin::signed(1), ProxyType::Any, 0, 1)); + let anon2 = Proxy::anonymous_account(&2, &ProxyType::Any, 0, None); + assert_ok!(Proxy::anonymous(Origin::signed(2), ProxyType::Any, 0, 0)); + assert_noop!(Proxy::anonymous(Origin::signed(1), ProxyType::Any, 0, 0), Error::::Duplicate); + System::set_extrinsic_index(1); + assert_ok!(Proxy::anonymous(Origin::signed(1), ProxyType::Any, 0, 0)); + System::set_extrinsic_index(0); + System::set_block_number(2); + assert_ok!(Proxy::anonymous(Origin::signed(1), ProxyType::Any, 0, 0)); + + let call = Box::new(Call::Balances(BalancesCall::transfer(6, 1))); + assert_ok!(Balances::transfer(Origin::signed(3), anon, 5)); + assert_ok!(Proxy::proxy(Origin::signed(1), anon, None, call)); + expect_event(RawEvent::ProxyExecuted(Ok(()))); + assert_eq!(Balances::free_balance(6), 1); + + let call = Box::new(Call::Proxy(ProxyCall::kill_anonymous(1, ProxyType::Any, 0, 1, 0))); + assert_ok!(Proxy::proxy(Origin::signed(2), anon2, None, call.clone())); + let de = DispatchError::from(Error::::NoPermission).stripped(); + expect_event(RawEvent::ProxyExecuted(Err(de))); + assert_noop!( + Proxy::kill_anonymous(Origin::signed(1), 1, ProxyType::Any, 0, 1, 0), + Error::::NoPermission + ); + assert_eq!(Balances::free_balance(1), 0); + assert_ok!(Proxy::proxy(Origin::signed(1), anon, None, call.clone())); + assert_eq!(Balances::free_balance(1), 2); + assert_noop!(Proxy::proxy(Origin::signed(1), anon, None, call.clone()), Error::::NotProxy); + }); +} diff --git a/frame/randomness-collective-flip/Cargo.toml b/frame/randomness-collective-flip/Cargo.toml index 08d715899fb89189f83e3806ade882e0a01fb482..0d0c5db0f49a56b44ad4f73ce42e8c3a0dedcbc8 100644 --- a/frame/randomness-collective-flip/Cargo.toml +++ b/frame/randomness-collective-flip/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-randomness-collective-flip" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME randomness collective flip pallet" @@ -13,15 +13,15 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] safe-mix = { version = "1.0", default-features = false } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/randomness-collective-flip/README.md b/frame/randomness-collective-flip/README.md new file mode 100644 index 0000000000000000000000000000000000000000..318f9d0f88b1e42315adf29aadf226110a87f8ca --- /dev/null +++ b/frame/randomness-collective-flip/README.md @@ -0,0 +1,38 @@ +# Randomness Module + +The Randomness Collective Flip module provides a [`random`](./struct.Module.html#method.random) +function that generates low-influence random values based on the block hashes from the previous +`81` blocks. Low-influence randomness can be useful when defending against relatively weak +adversaries. Using this pallet as a randomness source is advisable primarily in low-security +situations like testing. + +## Public Functions + +See the [`Module`](./struct.Module.html) struct for details of publicly available functions. + +## Usage + +### Prerequisites + +Import the Randomness Collective Flip module and derive your module's configuration trait from +the system trait. + +### Example - Get random seed for the current block + +```rust +use frame_support::{decl_module, dispatch, traits::Randomness}; + +pub trait Trait: frame_system::Trait {} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + #[weight = 0] + pub fn random_module_example(origin) -> dispatch::DispatchResult { + let _random_value = >::random(&b"my context"[..]); + Ok(()) + } + } +} +``` + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 29068ea91ff81e17de7df6ea7dbea793772feabd..74a08c0150935003c5e0b49d1e7cccbda089a339 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Randomness Module //! @@ -146,7 +147,7 @@ mod tests { pub struct Test; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } parameter_types! { @@ -157,6 +158,7 @@ mod tests { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -172,6 +174,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -179,6 +182,7 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } type System = frame_system::Module; diff --git a/frame/recovery/Cargo.toml b/frame/recovery/Cargo.toml index de422678c370d5e84b0525de89b83c8bc0fcc283..dfacac42fb44f6e7635f5a174c453114a6b7db26 100644 --- a/frame/recovery/Cargo.toml +++ b/frame/recovery/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-recovery" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME account recovery pallet" @@ -13,17 +13,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } [features] default = ["std"] diff --git a/frame/recovery/README.md b/frame/recovery/README.md new file mode 100644 index 0000000000000000000000000000000000000000..30631da1d9a447d76211402a41ff3506fcbfe316 --- /dev/null +++ b/frame/recovery/README.md @@ -0,0 +1,134 @@ +# Recovery Pallet + +- [`recovery::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +The Recovery pallet is an M-of-N social recovery tool for users to gain +access to their accounts if the private key or other authentication mechanism +is lost. Through this pallet, a user is able to make calls on-behalf-of another +account which they have recovered. The recovery process is protected by trusted +"friends" whom the original account owner chooses. A threshold (M) out of N +friends are needed to give another account access to the recoverable account. + +### Recovery Configuration + +The recovery process for each recoverable account can be configured by the account owner. +They are able to choose: +* `friends` - The list of friends that the account owner trusts to protect the + recovery process for their account. +* `threshold` - The number of friends that need to approve a recovery process for + the account to be successfully recovered. +* `delay_period` - The minimum number of blocks after the beginning of the recovery + process that need to pass before the account can be successfully recovered. + +There is a configurable deposit that all users need to pay to create a recovery +configuration. This deposit is composed of a base deposit plus a multiplier for +the number of friends chosen. This deposit is returned in full when the account +owner removes their recovery configuration. + +### Recovery Life Cycle + +The intended life cycle of a successful recovery takes the following steps: +1. The account owner calls `create_recovery` to set up a recovery configuration + for their account. +2. At some later time, the account owner loses access to their account and wants + to recover it. Likely, they will need to create a new account and fund it with + enough balance to support the transaction fees and the deposit for the + recovery process. +3. Using this new account, they call `initiate_recovery`. +4. Then the account owner would contact their configured friends to vouch for + the recovery attempt. The account owner would provide their old account id + and the new account id, and friends would call `vouch_recovery` with those + parameters. +5. Once a threshold number of friends have vouched for the recovery attempt, + the account owner needs to wait until the delay period has passed, starting + when they initiated the recovery process. +6. Now the account owner is able to call `claim_recovery`, which subsequently + allows them to call `as_recovered` and directly make calls on-behalf-of the lost + account. +7. Using the now recovered account, the account owner can call `close_recovery` + on the recovery process they opened, reclaiming the recovery deposit they + placed. +8. Then the account owner should then call `remove_recovery` to remove the recovery + configuration on the recovered account and reclaim the recovery configuration + deposit they placed. +9. Using `as_recovered`, the account owner is able to call any other pallets + to clean up their state and reclaim any reserved or locked funds. They + can then transfer all funds from the recovered account to the new account. +10. When the recovered account becomes reaped (i.e. its free and reserved + balance drops to zero), the final recovery link is removed. + +### Malicious Recovery Attempts + +Initializing a the recovery process for a recoverable account is open and +permissionless. However, the recovery deposit is an economic deterrent that +should disincentivize would-be attackers from trying to maliciously recover +accounts. + +The recovery deposit can always be claimed by the account which is trying to +to be recovered. In the case of a malicious recovery attempt, the account +owner who still has access to their account can claim the deposit and +essentially punish the malicious user. + +Furthermore, the malicious recovery attempt can only be successful if the +attacker is also able to get enough friends to vouch for the recovery attempt. +In the case where the account owner prevents a malicious recovery process, +this pallet makes it near-zero cost to re-configure the recovery settings and +remove/replace friends who are acting inappropriately. + +### Safety Considerations + +It is important to note that this is a powerful pallet that can compromise the +security of an account if used incorrectly. Some recommended practices for users +of this pallet are: + +* Configure a significant `delay_period` for your recovery process: As long as you + have access to your recoverable account, you need only check the blockchain once + every `delay_period` blocks to ensure that no recovery attempt is successful + against your account. Using off-chain notification systems can help with this, + but ultimately, setting a large `delay_period` means that even the most skilled + attacker will need to wait this long before they can access your account. +* Use a high threshold of approvals: Setting a value of 1 for the threshold means + that any of your friends would be able to recover your account. They would + simply need to start a recovery process and approve their own process. Similarly, + a threshold of 2 would mean that any 2 friends could work together to gain + access to your account. The only way to prevent against these kinds of attacks + is to choose a high threshold of approvals and select from a diverse friend + group that would not be able to reasonably coordinate with one another. +* Reset your configuration over time: Since the entire deposit of creating a + recovery configuration is returned to the user, the only cost of updating + your recovery configuration is the transaction fees for the calls. Thus, + it is strongly encouraged to regularly update your recovery configuration + as your life changes and your relationship with new and existing friends + change as well. + +## Interface + +### Dispatchable Functions + +#### For General Users + +* `create_recovery` - Create a recovery configuration for your account and make it recoverable. +* `initiate_recovery` - Start the recovery process for a recoverable account. + +#### For Friends of a Recoverable Account +* `vouch_recovery` - As a `friend` of a recoverable account, vouch for a recovery attempt on the account. + +#### For a User Who Successfully Recovered an Account + +* `claim_recovery` - Claim access to the account that you have successfully completed the recovery process for. +* `as_recovered` - Send a transaction as an account that you have recovered. See other functions below. + +#### For the Recoverable Account + +* `close_recovery` - Close an active recovery process for your account and reclaim the recovery deposit. +* `remove_recovery` - Remove the recovery configuration from the account, making it un-recoverable. + +#### For Super Users + +* `set_recovered` - The ROOT origin is able to skip the recovery process and directly allow + one account to access another. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/recovery/src/lib.rs b/frame/recovery/src/lib.rs index 008461e50392b6ed144c6137fe0d37c5ed75f8fb..1c0dd5041380f750eb1054eef8c9ef6206cd10fc 100644 --- a/frame/recovery/src/lib.rs +++ b/frame/recovery/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Recovery Pallet //! @@ -159,7 +160,7 @@ use codec::{Encode, Decode}; use frame_support::{ decl_module, decl_event, decl_storage, decl_error, ensure, - Parameter, RuntimeDebug, weights::{GetDispatchInfo, FunctionOf, Pays}, + Parameter, RuntimeDebug, weights::GetDispatchInfo, traits::{Currency, ReservableCurrency, Get, BalanceStatus}, dispatch::PostDispatchInfo, }; @@ -263,17 +264,21 @@ decl_event! { pub enum Event where AccountId = ::AccountId, { - /// A recovery process has been set up for an account + /// A recovery process has been set up for an [account]. RecoveryCreated(AccountId), - /// A recovery process has been initiated for account_1 by account_2 + /// A recovery process has been initiated for lost account by rescuer account. + /// [lost, rescuer] RecoveryInitiated(AccountId, AccountId), - /// A recovery process for account_1 by account_2 has been vouched for by account_3 + /// A recovery process for lost account by rescuer account has been vouched for by sender. + /// [lost, rescuer, sender] RecoveryVouched(AccountId, AccountId, AccountId), - /// A recovery process for account_1 by account_2 has been closed + /// A recovery process for lost account by rescuer account has been closed. + /// [lost, rescuer] RecoveryClosed(AccountId, AccountId), - /// Account_1 has been successfully recovered by account_2 + /// Lost account has been successfully recovered by rescuer account. + /// [lost, rescuer] AccountRecovered(AccountId, AccountId), - /// A recovery process has been removed for an account + /// A recovery process has been removed for an [account]. RecoveryRemoved(AccountId), } } @@ -319,6 +324,18 @@ decl_module! { pub struct Module for enum Call where origin: T::Origin { type Error = Error; + /// The base amount of currency needed to reserve for creating a recovery configuration. + const ConfigDepositBase: BalanceOf = T::ConfigDepositBase::get(); + + /// The amount of currency needed per additional user when creating a recovery configuration. + const FriendDepositFactor: BalanceOf = T::FriendDepositFactor::get(); + + /// The maximum amount of friends allowed in a recovery configuration. + const MaxFriends: u16 = T::MaxFriends::get(); + + /// The base amount of currency needed to reserve for starting a recovery. + const RecoveryDeposit: BalanceOf = T::RecoveryDeposit::get(); + /// Deposit one of this module's events by using the default implementation. fn deposit_event() = default; @@ -335,11 +352,7 @@ decl_module! { /// - The weight of the `call` + 10,000. /// - One storage lookup to check account is recovered by `who`. O(1) /// # - #[weight = FunctionOf( - |args: (&T::AccountId, &Box<::Call>)| args.1.get_dispatch_info().weight + 10_000, - |args: (&T::AccountId, &Box<::Call>)| args.1.get_dispatch_info().class, - Pays::Yes, - )] + #[weight = (call.get_dispatch_info().weight + 10_000, call.get_dispatch_info().class)] fn as_recovered(origin, account: T::AccountId, call: Box<::Call> diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index 648321a0ae77b541ec64643da6a5d38b83ce8892..6b8ef169c0076ee441e19d6d849063b1b09e7b5b 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Test utilities @@ -24,8 +25,6 @@ use frame_support::{ traits::{OnInitialize, OnFinalize}, }; use sp_core::H256; -// The testing primitives are very useful for avoiding having to work with signatures -// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, }; @@ -49,9 +48,6 @@ impl_outer_dispatch! { } } -// For testing the pallet, we construct most of a mock runtime. This means -// first constructing a configuration type (`Test`) which `impl`s each of the -// configuration traits of pallets we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; @@ -63,6 +59,7 @@ parameter_types! { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Call = Call; type Index = u64; @@ -78,6 +75,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -85,6 +83,7 @@ impl frame_system::Trait for Test { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { @@ -97,6 +96,7 @@ impl pallet_balances::Trait for Test { type Event = TestEvent; type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { diff --git a/frame/recovery/src/tests.rs b/frame/recovery/src/tests.rs index fb993043a5b005f4e94976f99a9701af6ab83b79..8e9484f0fb089588cfe1ef9c347fcbe6d517ae8d 100644 --- a/frame/recovery/src/tests.rs +++ b/frame/recovery/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Tests for the module. @@ -45,7 +46,7 @@ fn set_recovered_works() { // Not accessible by a normal user assert_noop!(Recovery::set_recovered(Origin::signed(1), 5, 1), BadOrigin); // Root can set a recovered account though - assert_ok!(Recovery::set_recovered(Origin::ROOT, 5, 1)); + assert_ok!(Recovery::set_recovered(Origin::root(), 5, 1)); // Account 1 should now be able to make a call through account 5 let call = Box::new(Call::Balances(BalancesCall::transfer(1, 100))); assert_ok!(Recovery::as_recovered(Origin::signed(1), 5, call)); diff --git a/frame/scheduler/Cargo.toml b/frame/scheduler/Cargo.toml index 6cc9161eea455212517aa3affa7d13027a1f54af..ea759b15f9e5ff22ccf7eb3bba640e9df8240095 100644 --- a/frame/scheduler/Cargo.toml +++ b/frame/scheduler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-scheduler" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" license = "Unlicense" @@ -11,16 +11,17 @@ description = "FRAME example pallet" [dependencies] serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.2.0", default-features = false } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core", default-features = false } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core", default-features = false } +substrate-test-utils = { version = "2.0.0-rc6", path = "../../test-utils" } [features] default = ["std"] @@ -34,4 +35,8 @@ std = [ "sp-io/std", "sp-std/std" ] -runtime-benchmarks = ["frame-benchmarking"] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] diff --git a/frame/scheduler/README.md b/frame/scheduler/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f51d02a1d7bef97e3ce4b50d1c488afeee74c447 --- /dev/null +++ b/frame/scheduler/README.md @@ -0,0 +1,34 @@ +# Scheduler +A module for scheduling dispatches. + +- [`scheduler::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) +- [`Module`](./struct.Module.html) + +## Overview + +This module exposes capabilities for scheduling dispatches to occur at a +specified block number or at a specified period. These scheduled dispatches +may be named or anonymous and may be canceled. + +**NOTE:** The scheduled calls will be dispatched with the default filter +for the origin: namely `frame_system::Trait::BaseCallFilter` for all origin +except root which will get no filter. And not the filter contained in origin +use to call `fn schedule`. + +If a call is scheduled using proxy or whatever mecanism which adds filter, +then those filter will not be used when dispatching the schedule call. + +## Interface + +### Dispatchable Functions + +* `schedule` - schedule a dispatch, which may be periodic, to occur at a + specified block and with a specified priority. +* `cancel` - cancel a scheduled dispatch, specified by block number and + index. +* `schedule_named` - augments the `schedule` interface with an additional + `Vec` parameter that can be used for identification. +* `cancel_named` - the named complement to the cancel function. + +License: Unlicense \ No newline at end of file diff --git a/frame/scheduler/src/benchmarking.rs b/frame/scheduler/src/benchmarking.rs index ac9c19f7c3dc05b59f1480f80b74b85b2138c087..847460fe85a502b0f1a3dea0f46e6b42fdd21604 100644 --- a/frame/scheduler/src/benchmarking.rs +++ b/frame/scheduler/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Scheduler pallet benchmarking. @@ -28,6 +29,7 @@ use crate::Module as Scheduler; use frame_system::Module as System; const MAX_SCHEDULED: u32 = 50; +const BLOCK_NUMBER: u32 = 2; // Add `n` named items to the schedule fn fill_schedule (when: T::BlockNumber, n: u32) -> Result<(), &'static str> { @@ -37,11 +39,12 @@ fn fill_schedule (when: T::BlockNumber, n: u32) -> Result<(), &'static // Named schedule is strictly heavier than anonymous Scheduler::::do_schedule_named( i.encode(), - when, + DispatchTime::At(when), // Add periodicity Some((T::BlockNumber::one(), 100)), // HARD_DEADLINE priority means it gets executed no matter what 0, + frame_system::RawOrigin::Root.into(), call.clone().into(), )?; } @@ -54,7 +57,7 @@ benchmarks! { schedule { let s in 0 .. MAX_SCHEDULED; - let when = T::BlockNumber::one(); + let when = BLOCK_NUMBER.into(); let periodic = Some((T::BlockNumber::one(), 100)); let priority = 0; // Essentially a no-op call. @@ -71,7 +74,7 @@ benchmarks! { cancel { let s in 1 .. MAX_SCHEDULED; - let when: T::BlockNumber = 2.into(); + let when = BLOCK_NUMBER.into(); fill_schedule::(when, s)?; assert_eq!(Agenda::::get(when).len(), s as usize); @@ -91,7 +94,7 @@ benchmarks! { schedule_named { let s in 0 .. MAX_SCHEDULED; let id = s.encode(); - let when = T::BlockNumber::one(); + let when = BLOCK_NUMBER.into(); let periodic = Some((T::BlockNumber::one(), 100)); let priority = 0; // Essentially a no-op call. @@ -108,7 +111,7 @@ benchmarks! { cancel_named { let s in 1 .. MAX_SCHEDULED; - let when = T::BlockNumber::one(); + let when = BLOCK_NUMBER.into(); fill_schedule::(when, s)?; }: _(RawOrigin::Root, 0.encode()) @@ -126,9 +129,9 @@ benchmarks! { on_initialize { let s in 0 .. MAX_SCHEDULED; - let when = T::BlockNumber::one(); + let when = BLOCK_NUMBER.into(); fill_schedule::(when, s)?; - }: { Scheduler::::on_initialize(T::BlockNumber::one()); } + }: { Scheduler::::on_initialize(BLOCK_NUMBER.into()); } verify { assert_eq!(System::::event_count(), s); // Next block should have all the schedules again diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index 029e1fd138db0d7cbad8f96934ff5b4991d7a31e..831ed64d438d7e99d8ccf17910670f399c0e6595 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -1,61 +1,84 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Scheduler +//! A module for scheduling dispatches. //! -//! \# Scheduler +//! - [`scheduler::Trait`](./trait.Trait.html) +//! - [`Call`](./enum.Call.html) +//! - [`Module`](./struct.Module.html) //! -//! - \[`scheduler::Trait`](./trait.Trait.html) -//! - \[`Call`](./enum.Call.html) -//! - \[`Module`](./struct.Module.html) +//! ## Overview //! -//! \## Overview +//! This module exposes capabilities for scheduling dispatches to occur at a +//! specified block number or at a specified period. These scheduled dispatches +//! may be named or anonymous and may be canceled. //! -//! // Short description of pallet's purpose. -//! // Links to Traits that should be implemented. -//! // What this pallet is for. -//! // What functionality the pallet provides. -//! // When to use the pallet (use case examples). -//! // How it is used. -//! // Inputs it uses and the source of each input. -//! // Outputs it produces. +//! **NOTE:** The scheduled calls will be dispatched with the default filter +//! for the origin: namely `frame_system::Trait::BaseCallFilter` for all origin +//! except root which will get no filter. And not the filter contained in origin +//! use to call `fn schedule`. //! -//! \## Terminology +//! If a call is scheduled using proxy or whatever mecanism which adds filter, +//! then those filter will not be used when dispatching the schedule call. //! -//! \## Goals +//! ## Interface //! -//! \## Interface +//! ### Dispatchable Functions //! -//! \### Dispatchable Functions +//! * `schedule` - schedule a dispatch, which may be periodic, to occur at a +//! specified block and with a specified priority. +//! * `cancel` - cancel a scheduled dispatch, specified by block number and +//! index. +//! * `schedule_named` - augments the `schedule` interface with an additional +//! `Vec` parameter that can be used for identification. +//! * `cancel_named` - the named complement to the cancel function. // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] mod benchmarking; -use sp_std::prelude::*; -use codec::{Encode, Decode}; -use sp_runtime::{RuntimeDebug, traits::{Zero, One}}; +use sp_std::{prelude::*, marker::PhantomData, borrow::Borrow}; +use codec::{Encode, Decode, Codec}; +use sp_runtime::{RuntimeDebug, traits::{Zero, One, BadOrigin, Saturating}}; use frame_support::{ - decl_module, decl_storage, decl_event, decl_error, + decl_module, decl_storage, decl_event, decl_error, IterableStorageMap, dispatch::{Dispatchable, DispatchError, DispatchResult, Parameter}, - traits::{Get, schedule}, + traits::{Get, schedule::{self, DispatchTime}, OriginTrait, EnsureOrigin, IsType}, weights::{GetDispatchInfo, Weight}, }; -use frame_system::{self as system, ensure_root}; +use frame_system::{self as system}; + +pub trait WeightInfo { + fn schedule(s: u32, ) -> Weight; + fn cancel(s: u32, ) -> Weight; + fn schedule_named(s: u32, ) -> Weight; + fn cancel_named(s: u32, ) -> Weight; + fn on_initialize(s: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn schedule(_s: u32, ) -> Weight { 1_000_000_000 } + fn cancel(_s: u32, ) -> Weight { 1_000_000_000 } + fn schedule_named(_s: u32, ) -> Weight { 1_000_000_000 } + fn cancel_named(_s: u32, ) -> Weight { 1_000_000_000 } + fn on_initialize(_s: u32, ) -> Weight { 1_000_000_000 } +} /// Our pallet's configuration trait. All our types and constants go in here. If the /// pallet is dependent on specific other pallets, then their configuration traits @@ -67,7 +90,11 @@ pub trait Trait: system::Trait { type Event: From> + Into<::Event>; /// The aggregated origin which the dispatch will take. - type Origin: From>; + type Origin: OriginTrait + From + IsType<::Origin>; + + /// The caller origin, overarching type of all pallets origins. + type PalletsOrigin: From> + Codec + Clone + Eq; /// The aggregated call type. type Call: Parameter + Dispatchable::Origin> + GetDispatchInfo + From>; @@ -75,6 +102,12 @@ pub trait Trait: system::Trait { /// The maximum weight that may be scheduled per block for any dispatchables of less priority /// than `schedule::HARD_DEADLINE`. type MaximumWeight: Get; + + /// Required origin to schedule or cancel calls. + type ScheduleOrigin: EnsureOrigin<::Origin>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } /// Just a simple index for naming period tasks. @@ -82,9 +115,19 @@ pub type PeriodicIndex = u32; /// The location of a scheduled task that can be used to remove it. pub type TaskAddress = (BlockNumber, u32); +#[cfg_attr(any(feature = "std", test), derive(PartialEq, Eq))] +#[derive(Clone, RuntimeDebug, Encode, Decode)] +struct ScheduledV1 { + maybe_id: Option>, + priority: schedule::Priority, + call: Call, + maybe_periodic: Option>, +} + /// Information regarding an item to be executed in the future. +#[cfg_attr(any(feature = "std", test), derive(PartialEq, Eq))] #[derive(Clone, RuntimeDebug, Encode, Decode)] -pub struct Scheduled { +pub struct ScheduledV2 { /// The unique identity for this task, if there is one. maybe_id: Option>, /// This task's priority. @@ -93,23 +136,52 @@ pub struct Scheduled { call: Call, /// If the call is periodic, then this points to the information concerning that. maybe_periodic: Option>, + /// The origin to dispatch the call. + origin: PalletsOrigin, + _phantom: PhantomData, +} + +/// The current version of Scheduled struct. +pub type Scheduled = ScheduledV2; + +// A value placed in storage that represents the current version of the Scheduler storage. +// This value is used by the `on_runtime_upgrade` logic to determine whether we run +// storage migration logic. +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug)] +enum Releases { + V1, + V2, +} + +impl Default for Releases { + fn default() -> Self { + Releases::V1 + } } decl_storage! { trait Store for Module as Scheduler { /// Items to be executed, indexed by the block number that they should be executed on. pub Agenda: map hasher(twox_64_concat) T::BlockNumber - => Vec::Call, T::BlockNumber>>>; + => Vec::Call, T::BlockNumber, T::PalletsOrigin, T::AccountId>>>; /// Lookup from identity to the block number and index of the task. Lookup: map hasher(twox_64_concat) Vec => Option>; + + /// Storage version of the pallet. + /// + /// New networks start with last version. + StorageVersion build(|_| Releases::V2): Releases; } } decl_event!( pub enum Event where ::BlockNumber { + /// Scheduled some task. [when, index] Scheduled(BlockNumber, u32), + /// Canceled some task. [when, index] Canceled(BlockNumber, u32), + /// Dispatched some task. [task, id, result] Dispatched(TaskAddress, Option>, DispatchResult), } ); @@ -120,12 +192,15 @@ decl_error! { FailedToSchedule, /// Failed to cancel a scheduled call FailedToCancel, + /// Given target block number is in the past. + TargetBlockNumberInPast, } } decl_module! { /// Scheduler module declaration. pub struct Module for enum Call where origin: ::Origin { + type Error = Error; fn deposit_event() = default; /// Anonymously schedule a task. @@ -145,8 +220,9 @@ decl_module! { priority: schedule::Priority, call: Box<::Call>, ) { - ensure_root(origin)?; - let _ = Self::do_schedule(when, maybe_periodic, priority, *call); + T::ScheduleOrigin::ensure_origin(origin.clone())?; + let origin = ::Origin::from(origin); + Self::do_schedule(DispatchTime::At(when), maybe_periodic, priority, origin.caller().clone(), *call)?; } /// Cancel an anonymously scheduled task. @@ -161,8 +237,9 @@ decl_module! { /// # #[weight = 100_000_000 + T::DbWeight::get().reads_writes(1, 2)] fn cancel(origin, when: T::BlockNumber, index: u32) { - ensure_root(origin)?; - Self::do_cancel((when, index))?; + T::ScheduleOrigin::ensure_origin(origin.clone())?; + let origin = ::Origin::from(origin); + Self::do_cancel(Some(origin.caller().clone()), (when, index))?; } /// Schedule a named task. @@ -183,8 +260,11 @@ decl_module! { priority: schedule::Priority, call: Box<::Call>, ) { - ensure_root(origin)?; - Self::do_schedule_named(id, when, maybe_periodic, priority, *call)?; + T::ScheduleOrigin::ensure_origin(origin.clone())?; + let origin = ::Origin::from(origin); + Self::do_schedule_named( + id, DispatchTime::At(when), maybe_periodic, priority, origin.caller().clone(), *call + )?; } /// Cancel a named scheduled task. @@ -199,8 +279,48 @@ decl_module! { /// # #[weight = 100_000_000 + T::DbWeight::get().reads_writes(2, 2)] fn cancel_named(origin, id: Vec) { - ensure_root(origin)?; - Self::do_cancel_named(id)?; + T::ScheduleOrigin::ensure_origin(origin.clone())?; + let origin = ::Origin::from(origin); + Self::do_cancel_named(Some(origin.caller().clone()), id)?; + } + + /// Anonymously schedule a task after a delay. + /// + /// # + /// Same as [`schedule`]. + /// # + #[weight = 25_000_000 + T::DbWeight::get().reads_writes(1, 1)] + fn schedule_after(origin, + after: T::BlockNumber, + maybe_periodic: Option>, + priority: schedule::Priority, + call: Box<::Call>, + ) { + T::ScheduleOrigin::ensure_origin(origin.clone())?; + let origin = ::Origin::from(origin); + Self::do_schedule( + DispatchTime::After(after), maybe_periodic, priority, origin.caller().clone(), *call + )?; + } + + /// Schedule a named task after a delay. + /// + /// # + /// Same as [`schedule_named`]. + /// # + #[weight = 35_000_000 + T::DbWeight::get().reads_writes(2, 2)] + fn schedule_named_after(origin, + id: Vec, + after: T::BlockNumber, + maybe_periodic: Option>, + priority: schedule::Priority, + call: Box<::Call>, + ) { + T::ScheduleOrigin::ensure_origin(origin.clone())?; + let origin = ::Origin::from(origin); + Self::do_schedule_named( + id, DispatchTime::After(after), maybe_periodic, priority, origin.caller().clone(), *call + )?; } /// Execute the scheduled calls @@ -248,7 +368,7 @@ decl_module! { // - It does not push the weight past the limit. // - It is the first item in the schedule if s.priority <= schedule::HARD_DEADLINE || cumulative_weight <= limit || order == 0 { - let r = s.call.clone().dispatch(system::RawOrigin::Root.into()); + let r = s.call.clone().dispatch(s.origin.clone().into()); let maybe_id = s.maybe_id.clone(); if let &Some((period, count)) = &s.maybe_periodic { if count > 1 { @@ -290,26 +410,86 @@ decl_module! { } impl Module { + /// Migrate storage format from V1 to V2. + /// Return true if migration is performed. + pub fn migrate_v1_to_t2() -> bool { + if StorageVersion::get() == Releases::V1 { + StorageVersion::put(Releases::V2); + + Agenda::::translate::< + Vec::Call, T::BlockNumber>>>, _ + >(|_, agenda| Some( + agenda + .into_iter() + .map(|schedule| schedule.map(|schedule| ScheduledV2 { + maybe_id: schedule.maybe_id, + priority: schedule.priority, + call: schedule.call, + maybe_periodic: schedule.maybe_periodic, + origin: system::RawOrigin::Root.into(), + _phantom: Default::default(), + })) + .collect::>() + )); + + true + } else { + false + } + } + fn do_schedule( - when: T::BlockNumber, + when: DispatchTime, maybe_periodic: Option>, priority: schedule::Priority, + origin: T::PalletsOrigin, call: ::Call - ) -> TaskAddress { + ) -> Result, DispatchError> { + let now = frame_system::Module::::block_number(); + + let when = match when { + DispatchTime::At(x) => x, + DispatchTime::After(x) => now.saturating_add(x) + }; + + if when <= now { + return Err(Error::::TargetBlockNumberInPast.into()) + } + // sanitize maybe_periodic let maybe_periodic = maybe_periodic .filter(|p| p.1 > 1 && !p.0.is_zero()) // Remove one from the number of repetitions since we will schedule one now. .map(|(p, c)| (p, c - 1)); - let s = Some(Scheduled { maybe_id: None, priority, call, maybe_periodic }); + let s = Some(Scheduled { + maybe_id: None, priority, call, maybe_periodic, origin, _phantom: PhantomData::::default(), + }); Agenda::::append(when, s); let index = Agenda::::decode_len(when).unwrap_or(1) as u32 - 1; Self::deposit_event(RawEvent::Scheduled(when, index)); - (when, index) + + Ok((when, index)) } - fn do_cancel((when, index): TaskAddress) -> Result<(), DispatchError> { - if let Some(s) = Agenda::::mutate(when, |agenda| agenda.get_mut(index as usize).and_then(Option::take)) { + fn do_cancel( + origin: Option, + (when, index): TaskAddress + ) -> Result<(), DispatchError> { + let scheduled = Agenda::::try_mutate( + when, + |agenda| { + agenda.get_mut(index as usize) + .map_or(Ok(None), |s| -> Result>, DispatchError> { + if let (Some(ref o), Some(ref s)) = (origin, s.borrow()) { + if *o != s.origin { + return Err(BadOrigin.into()); + } + }; + Ok(s.take()) + }) + }, + )?; + if let Some(s) = scheduled { if let Some(id) = s.maybe_id { Lookup::::remove(id); } @@ -322,9 +502,10 @@ impl Module { fn do_schedule_named( id: Vec, - when: T::BlockNumber, + when: DispatchTime, maybe_periodic: Option>, priority: schedule::Priority, + origin: T::PalletsOrigin, call: ::Call, ) -> Result, DispatchError> { // ensure id it is unique @@ -332,65 +513,93 @@ impl Module { return Err(Error::::FailedToSchedule)? } + let now = frame_system::Module::::block_number(); + + let when = match when { + DispatchTime::At(x) => x, + DispatchTime::After(x) => now.saturating_add(x) + }; + + if when <= now { + return Err(Error::::TargetBlockNumberInPast.into()) + } + // sanitize maybe_periodic let maybe_periodic = maybe_periodic .filter(|p| p.1 > 1 && !p.0.is_zero()) // Remove one from the number of repetitions since we will schedule one now. .map(|(p, c)| (p, c - 1)); - let s = Scheduled { maybe_id: Some(id.clone()), priority, call, maybe_periodic }; + let s = Scheduled { + maybe_id: Some(id.clone()), priority, call, maybe_periodic, origin, _phantom: Default::default() + }; Agenda::::append(when, Some(s)); let index = Agenda::::decode_len(when).unwrap_or(1) as u32 - 1; let address = (when, index); Lookup::::insert(&id, &address); Self::deposit_event(RawEvent::Scheduled(when, index)); + Ok(address) } - fn do_cancel_named(id: Vec) -> Result<(), DispatchError> { - if let Some((when, index)) = Lookup::::take(id) { - let i = index as usize; - Agenda::::mutate(when, |agenda| if let Some(s) = agenda.get_mut(i) { *s = None }); - Self::deposit_event(RawEvent::Canceled(when, index)); - Ok(()) - } else { - Err(Error::::FailedToCancel)? - } + fn do_cancel_named(origin: Option, id: Vec) -> DispatchResult { + Lookup::::try_mutate_exists(id, |lookup| -> DispatchResult { + if let Some((when, index)) = lookup.take() { + let i = index as usize; + Agenda::::try_mutate(when, |agenda| -> DispatchResult { + if let Some(s) = agenda.get_mut(i) { + if let (Some(ref o), Some(ref s)) = (origin, s.borrow()) { + if *o != s.origin { + return Err(BadOrigin.into()); + } + } + *s = None; + } + Ok(()) + })?; + Self::deposit_event(RawEvent::Canceled(when, index)); + Ok(()) + } else { + Err(Error::::FailedToCancel)? + } + }) } } -impl schedule::Anon::Call> for Module { +impl schedule::Anon::Call, T::PalletsOrigin> for Module { type Address = TaskAddress; fn schedule( - when: T::BlockNumber, + when: DispatchTime, maybe_periodic: Option>, priority: schedule::Priority, + origin: T::PalletsOrigin, call: ::Call - ) -> Self::Address { - Self::do_schedule(when, maybe_periodic, priority, call) + ) -> Result { + Self::do_schedule(when, maybe_periodic, priority, origin, call) } fn cancel((when, index): Self::Address) -> Result<(), ()> { - Self::do_cancel((when, index)).map_err(|_| ()) + Self::do_cancel(None, (when, index)).map_err(|_| ()) } } -impl schedule::Named::Call> for Module { +impl schedule::Named::Call, T::PalletsOrigin> for Module { type Address = TaskAddress; fn schedule_named( id: Vec, - when: T::BlockNumber, + when: DispatchTime, maybe_periodic: Option>, priority: schedule::Priority, + origin: T::PalletsOrigin, call: ::Call, ) -> Result { - Self::do_schedule_named(id, when, maybe_periodic, priority, call).map_err(|_| ()) + Self::do_schedule_named(id, when, maybe_periodic, priority, origin, call).map_err(|_| ()) } fn cancel_named(id: Vec) -> Result<(), ()> { - Self::do_cancel_named(id).map_err(|_| ()) + Self::do_cancel_named(None, id).map_err(|_| ()) } } @@ -399,57 +608,59 @@ mod tests { use super::*; use frame_support::{ - impl_outer_event, impl_outer_origin, impl_outer_dispatch, parameter_types, assert_ok, - traits::{OnInitialize, OnFinalize}, - weights::{DispatchClass, FunctionOf, Pays, constants::RocksDbWeight}, + impl_outer_event, impl_outer_origin, impl_outer_dispatch, parameter_types, assert_ok, ord_parameter_types, + assert_noop, assert_err, Hashable, + traits::{OnInitialize, OnFinalize, Filter}, + weights::constants::RocksDbWeight, }; use sp_core::H256; - // The testing primitives are very useful for avoiding having to work with signatures - // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ Perbill, testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; + use frame_system::{EnsureOneOf, EnsureRoot, EnsureSignedBy}; use crate as scheduler; mod logger { use super::*; use std::cell::RefCell; - use frame_system::ensure_root; thread_local! { - static LOG: RefCell> = RefCell::new(Vec::new()); + static LOG: RefCell> = RefCell::new(Vec::new()); } - pub fn log() -> Vec { + pub fn log() -> Vec<(OriginCaller, u32)> { LOG.with(|log| log.borrow().clone()) } pub trait Trait: system::Trait { type Event: From + Into<::Event>; } - decl_storage! { - trait Store for Module as Logger { - } - } decl_event! { pub enum Event { Logged(u32, Weight), } } decl_module! { - pub struct Module for enum Call where origin: ::Origin { + pub struct Module for enum Call + where + origin: ::Origin, + ::Origin: OriginTrait + { fn deposit_event() = default; - #[weight = FunctionOf( - |args: (&u32, &Weight)| *args.1, - |_: (&u32, &Weight)| DispatchClass::Normal, - Pays::Yes, - )] + #[weight = *weight] fn log(origin, i: u32, weight: Weight) { - ensure_root(origin)?; Self::deposit_event(Event::Logged(i, weight)); LOG.with(|log| { - log.borrow_mut().push(i); + log.borrow_mut().push((origin.caller().clone(), i)); + }) + } + + #[weight = *weight] + fn log_without_filter(origin, i: u32, weight: Weight) { + Self::deposit_event(Event::Logged(i, weight)); + LOG.with(|log| { + log.borrow_mut().push((origin.caller().clone(), i)); }) } } @@ -474,9 +685,15 @@ mod tests { scheduler, } } - // For testing the pallet, we construct most of a mock runtime. This means - // first constructing a configuration type (`Test`) which `impl`s each of the - // configuration traits of pallets we want to use. + + // Scheduler must dispatch with root and no filter, this tests base filter is indeed not used. + pub struct BaseFilter; + impl Filter for BaseFilter { + fn filter(call: &Call) -> bool { + !matches!(call, Call::Logger(logger::Call::log(_, _))) + } + } + #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -486,8 +703,9 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl system::Trait for Test { + type BaseCallFilter = BaseFilter; type Origin = Origin; - type Call = (); + type Call = Call; type Index = u64; type BlockNumber = u64; type Hash = H256; @@ -501,6 +719,7 @@ mod tests { type DbWeight = RocksDbWeight; type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -508,25 +727,31 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl logger::Trait for Test { type Event = (); } parameter_types! { - pub const MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get(); + } + ord_parameter_types! { + pub const One: u64 = 1; } + impl Trait for Test { type Event = (); type Origin = Origin; + type PalletsOrigin = OriginCaller; type Call = Call; type MaximumWeight = MaximumSchedulerWeight; + type ScheduleOrigin = EnsureOneOf, EnsureSignedBy>; + type WeightInfo = (); } type System = system::Module; type Logger = logger::Module; type Scheduler = Module; - // This function basically just builds a genesis storage key/value store according to - // our desired mockup. pub fn new_test_ext() -> sp_io::TestExternalities { let t = system::GenesisConfig::default().build_storage::().unwrap(); t.into() @@ -540,16 +765,38 @@ mod tests { } } + fn root() -> OriginCaller { + system::RawOrigin::Root.into() + } + #[test] fn basic_scheduling_works() { new_test_ext().execute_with(|| { - Scheduler::do_schedule(4, None, 127, Call::Logger(logger::Call::log(42, 1000))); + let call = Call::Logger(logger::Call::log(42, 1000)); + assert!(!::BaseCallFilter::filter(&call)); + let _ = Scheduler::do_schedule(DispatchTime::At(4), None, 127, root(), call); run_to_block(3); assert!(logger::log().is_empty()); run_to_block(4); - assert_eq!(logger::log(), vec![42u32]); + assert_eq!(logger::log(), vec![(root(), 42u32)]); run_to_block(100); - assert_eq!(logger::log(), vec![42u32]); + assert_eq!(logger::log(), vec![(root(), 42u32)]); + }); + } + + #[test] + fn schedule_after_works() { + new_test_ext().execute_with(|| { + run_to_block(2); + let call = Call::Logger(logger::Call::log(42, 1000)); + assert!(!::BaseCallFilter::filter(&call)); + let _ = Scheduler::do_schedule(DispatchTime::After(3), None, 127, root(), call); + run_to_block(4); + assert!(logger::log().is_empty()); + run_to_block(5); + assert_eq!(logger::log(), vec![(root(), 42u32)]); + run_to_block(100); + assert_eq!(logger::log(), vec![(root(), 42u32)]); }); } @@ -557,21 +804,23 @@ mod tests { fn periodic_scheduling_works() { new_test_ext().execute_with(|| { // at #4, every 3 blocks, 3 times. - Scheduler::do_schedule(4, Some((3, 3)), 127, Call::Logger(logger::Call::log(42, 1000))); + let _ = Scheduler::do_schedule( + DispatchTime::At(4), Some((3, 3)), 127, root(), Call::Logger(logger::Call::log(42, 1000)) + ); run_to_block(3); assert!(logger::log().is_empty()); run_to_block(4); - assert_eq!(logger::log(), vec![42u32]); + assert_eq!(logger::log(), vec![(root(), 42u32)]); run_to_block(6); - assert_eq!(logger::log(), vec![42u32]); + assert_eq!(logger::log(), vec![(root(), 42u32)]); run_to_block(7); - assert_eq!(logger::log(), vec![42u32, 42u32]); + assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); run_to_block(9); - assert_eq!(logger::log(), vec![42u32, 42u32]); + assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); run_to_block(10); - assert_eq!(logger::log(), vec![42u32, 42u32, 42u32]); + assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); run_to_block(100); - assert_eq!(logger::log(), vec![42u32, 42u32, 42u32]); + assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); }); } @@ -579,12 +828,16 @@ mod tests { fn cancel_named_scheduling_works_with_normal_cancel() { new_test_ext().execute_with(|| { // at #4. - Scheduler::do_schedule_named(1u32.encode(), 4, None, 127, Call::Logger(logger::Call::log(69, 1000))).unwrap(); - let i = Scheduler::do_schedule(4, None, 127, Call::Logger(logger::Call::log(42, 1000))); + Scheduler::do_schedule_named( + 1u32.encode(), DispatchTime::At(4), None, 127, root(), Call::Logger(logger::Call::log(69, 1000)) + ).unwrap(); + let i = Scheduler::do_schedule( + DispatchTime::At(4), None, 127, root(), Call::Logger(logger::Call::log(42, 1000)) + ).unwrap(); run_to_block(3); assert!(logger::log().is_empty()); - assert_ok!(Scheduler::do_cancel_named(1u32.encode())); - assert_ok!(Scheduler::do_cancel(i)); + assert_ok!(Scheduler::do_cancel_named(None, 1u32.encode())); + assert_ok!(Scheduler::do_cancel(None, i)); run_to_block(100); assert!(logger::log().is_empty()); }); @@ -594,69 +847,135 @@ mod tests { fn cancel_named_periodic_scheduling_works() { new_test_ext().execute_with(|| { // at #4, every 3 blocks, 3 times. - Scheduler::do_schedule_named(1u32.encode(), 4, Some((3, 3)), 127, Call::Logger(logger::Call::log(42, 1000))).unwrap(); + Scheduler::do_schedule_named( + 1u32.encode(), + DispatchTime::At(4), + Some((3, 3)), + 127, + root(), + Call::Logger(logger::Call::log(42, 1000)) + ).unwrap(); // same id results in error. - assert!(Scheduler::do_schedule_named(1u32.encode(), 4, None, 127, Call::Logger(logger::Call::log(69, 1000))).is_err()); + assert!(Scheduler::do_schedule_named( + 1u32.encode(), + DispatchTime::At(4), + None, + 127, + root(), + Call::Logger(logger::Call::log(69, 1000)) + ).is_err()); // different id is ok. - Scheduler::do_schedule_named(2u32.encode(), 8, None, 127, Call::Logger(logger::Call::log(69, 1000))).unwrap(); + Scheduler::do_schedule_named( + 2u32.encode(), DispatchTime::At(8), None, 127, root(), Call::Logger(logger::Call::log(69, 1000)) + ).unwrap(); run_to_block(3); assert!(logger::log().is_empty()); run_to_block(4); - assert_eq!(logger::log(), vec![42u32]); + assert_eq!(logger::log(), vec![(root(), 42u32)]); run_to_block(6); - assert_ok!(Scheduler::do_cancel_named(1u32.encode())); + assert_ok!(Scheduler::do_cancel_named(None, 1u32.encode())); run_to_block(100); - assert_eq!(logger::log(), vec![42u32, 69u32]); + assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 69u32)]); }); } #[test] fn scheduler_respects_weight_limits() { new_test_ext().execute_with(|| { - Scheduler::do_schedule(4, None, 127, Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2))); - Scheduler::do_schedule(4, None, 127, Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2))); + let _ = Scheduler::do_schedule( + DispatchTime::At(4), + None, + 127, + root(), + Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2)) + ); + let _ = Scheduler::do_schedule( + DispatchTime::At(4), + None, + 127, + root(), Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2)) + ); // 69 and 42 do not fit together run_to_block(4); - assert_eq!(logger::log(), vec![42u32]); + assert_eq!(logger::log(), vec![(root(), 42u32)]); run_to_block(5); - assert_eq!(logger::log(), vec![42u32, 69u32]); + assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 69u32)]); }); } #[test] fn scheduler_respects_hard_deadlines_more() { new_test_ext().execute_with(|| { - Scheduler::do_schedule(4, None, 0, Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2))); - Scheduler::do_schedule(4, None, 0, Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2))); + let _ = Scheduler::do_schedule( + DispatchTime::At(4), + None, + 0, + root(), + Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2)) + ); + let _ = Scheduler::do_schedule( + DispatchTime::At(4), + None, + 0, + root(), + Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2)) + ); // With base weights, 69 and 42 should not fit together, but do because of hard deadlines run_to_block(4); - assert_eq!(logger::log(), vec![42u32, 69u32]); + assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 69u32)]); }); } #[test] fn scheduler_respects_priority_ordering() { new_test_ext().execute_with(|| { - Scheduler::do_schedule(4, None, 1, Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2))); - Scheduler::do_schedule(4, None, 0, Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2))); + let _ = Scheduler::do_schedule( + DispatchTime::At(4), + None, + 1, + root(), + Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 2)) + ); + let _ = Scheduler::do_schedule( + DispatchTime::At(4), + None, + 0, + root(), + Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2)) + ); run_to_block(4); - assert_eq!(logger::log(), vec![69u32, 42u32]); + assert_eq!(logger::log(), vec![(root(), 69u32), (root(), 42u32)]); }); } #[test] fn scheduler_respects_priority_ordering_with_soft_deadlines() { new_test_ext().execute_with(|| { - Scheduler::do_schedule(4, None, 255, Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 3))); - Scheduler::do_schedule(4, None, 127, Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2))); - Scheduler::do_schedule(4, None, 126, Call::Logger(logger::Call::log(2600, MaximumSchedulerWeight::get() / 2))); + let _ = Scheduler::do_schedule( + DispatchTime::At(4), + None, + 255, + root(), Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 3)) + ); + let _ = Scheduler::do_schedule( + DispatchTime::At(4), + None, + 127, + root(), Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2)) + ); + let _ = Scheduler::do_schedule( + DispatchTime::At(4), + None, + 126, + root(), Call::Logger(logger::Call::log(2600, MaximumSchedulerWeight::get() / 2)) + ); // 2600 does not fit with 69 or 42, but has higher priority, so will go through run_to_block(4); - assert_eq!(logger::log(), vec![2600u32]); + assert_eq!(logger::log(), vec![(root(), 2600u32)]); // 69 and 42 fit together run_to_block(5); - assert_eq!(logger::log(), vec![2600u32, 69u32, 42u32]); + assert_eq!(logger::log(), vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32)]); }); } @@ -669,31 +988,53 @@ mod tests { let periodic_multiplier = ::DbWeight::get().reads_writes(1, 1); // Named - assert_ok!(Scheduler::do_schedule_named(1u32.encode(), 1, None, 255, Call::Logger(logger::Call::log(3, MaximumSchedulerWeight::get() / 3)))); + assert_ok!( + Scheduler::do_schedule_named( + 1u32.encode(), DispatchTime::At(1), None, 255, root(), + Call::Logger(logger::Call::log(3, MaximumSchedulerWeight::get() / 3)) + ) + ); // Anon Periodic - Scheduler::do_schedule(1, Some((1000, 3)), 128, Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 3))); + let _ = Scheduler::do_schedule( + DispatchTime::At(1), + Some((1000, 3)), + 128, + root(), + Call::Logger(logger::Call::log(42, MaximumSchedulerWeight::get() / 3)) + ); // Anon - Scheduler::do_schedule(1, None, 127, Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2))); + let _ = Scheduler::do_schedule( + DispatchTime::At(1), + None, + 127, + root(), + Call::Logger(logger::Call::log(69, MaximumSchedulerWeight::get() / 2)) + ); // Named Periodic - assert_ok!(Scheduler::do_schedule_named(2u32.encode(), 1, Some((1000, 3)), 126, Call::Logger(logger::Call::log(2600, MaximumSchedulerWeight::get() / 2)))); + assert_ok!(Scheduler::do_schedule_named( + 2u32.encode(), DispatchTime::At(1), Some((1000, 3)), 126, root(), + Call::Logger(logger::Call::log(2600, MaximumSchedulerWeight::get() / 2))) + ); // Will include the named periodic only let actual_weight = Scheduler::on_initialize(1); let call_weight = MaximumSchedulerWeight::get() / 2; - assert_eq!(actual_weight, call_weight + base_weight + base_multiplier + named_multiplier + periodic_multiplier); - assert_eq!(logger::log(), vec![2600u32]); + assert_eq!( + actual_weight, call_weight + base_weight + base_multiplier + named_multiplier + periodic_multiplier + ); + assert_eq!(logger::log(), vec![(root(), 2600u32)]); // Will include anon and anon periodic let actual_weight = Scheduler::on_initialize(2); let call_weight = MaximumSchedulerWeight::get() / 2 + MaximumSchedulerWeight::get() / 3; assert_eq!(actual_weight, call_weight + base_weight + base_multiplier * 2 + periodic_multiplier); - assert_eq!(logger::log(), vec![2600u32, 69u32, 42u32]); + assert_eq!(logger::log(), vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32)]); // Will include named only let actual_weight = Scheduler::on_initialize(3); let call_weight = MaximumSchedulerWeight::get() / 3; assert_eq!(actual_weight, call_weight + base_weight + base_multiplier + named_multiplier); - assert_eq!(logger::log(), vec![2600u32, 69u32, 42u32, 3u32]); + assert_eq!(logger::log(), vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32), (root(), 3u32)]); // Will contain none let actual_weight = Scheduler::on_initialize(4); @@ -706,17 +1047,207 @@ mod tests { new_test_ext().execute_with(|| { let call = Box::new(Call::Logger(logger::Call::log(69, 1000))); let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000))); - assert_ok!(Scheduler::schedule_named(Origin::ROOT, 1u32.encode(), 4, None, 127, call)); - assert_ok!(Scheduler::schedule(Origin::ROOT, 4, None, 127, call2)); + assert_ok!(Scheduler::schedule_named(Origin::root(), 1u32.encode(), 4, None, 127, call)); + assert_ok!(Scheduler::schedule(Origin::root(), 4, None, 127, call2)); run_to_block(3); // Scheduled calls are in the agenda. assert_eq!(Agenda::::get(4).len(), 2); assert!(logger::log().is_empty()); - assert_ok!(Scheduler::cancel_named(Origin::ROOT, 1u32.encode())); - assert_ok!(Scheduler::cancel(Origin::ROOT, 4, 1)); + assert_ok!(Scheduler::cancel_named(Origin::root(), 1u32.encode())); + assert_ok!(Scheduler::cancel(Origin::root(), 4, 1)); // Scheduled calls are made NONE, so should not effect state run_to_block(100); assert!(logger::log().is_empty()); }); } + + #[test] + fn fails_to_schedule_task_in_the_past() { + new_test_ext().execute_with(|| { + run_to_block(3); + + let call = Box::new(Call::Logger(logger::Call::log(69, 1000))); + let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000))); + + assert_err!( + Scheduler::schedule_named(Origin::root(), 1u32.encode(), 2, None, 127, call), + Error::::TargetBlockNumberInPast, + ); + + assert_err!( + Scheduler::schedule(Origin::root(), 2, None, 127, call2.clone()), + Error::::TargetBlockNumberInPast, + ); + + assert_err!( + Scheduler::schedule(Origin::root(), 3, None, 127, call2), + Error::::TargetBlockNumberInPast, + ); + }); + } + + #[test] + fn should_use_orign() { + new_test_ext().execute_with(|| { + let call = Box::new(Call::Logger(logger::Call::log(69, 1000))); + let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000))); + assert_ok!( + Scheduler::schedule_named(system::RawOrigin::Signed(1).into(), 1u32.encode(), 4, None, 127, call) + ); + assert_ok!(Scheduler::schedule(system::RawOrigin::Signed(1).into(), 4, None, 127, call2)); + run_to_block(3); + // Scheduled calls are in the agenda. + assert_eq!(Agenda::::get(4).len(), 2); + assert!(logger::log().is_empty()); + assert_ok!(Scheduler::cancel_named(system::RawOrigin::Signed(1).into(), 1u32.encode())); + assert_ok!(Scheduler::cancel(system::RawOrigin::Signed(1).into(), 4, 1)); + // Scheduled calls are made NONE, so should not effect state + run_to_block(100); + assert!(logger::log().is_empty()); + }); + } + + #[test] + fn should_check_orign() { + new_test_ext().execute_with(|| { + let call = Box::new(Call::Logger(logger::Call::log(69, 1000))); + let call2 = Box::new(Call::Logger(logger::Call::log(42, 1000))); + assert_noop!( + Scheduler::schedule_named(system::RawOrigin::Signed(2).into(), 1u32.encode(), 4, None, 127, call), + BadOrigin + ); + assert_noop!(Scheduler::schedule(system::RawOrigin::Signed(2).into(), 4, None, 127, call2), BadOrigin); + }); + } + + #[test] + fn should_check_orign_for_cancel() { + new_test_ext().execute_with(|| { + let call = Box::new(Call::Logger(logger::Call::log_without_filter(69, 1000))); + let call2 = Box::new(Call::Logger(logger::Call::log_without_filter(42, 1000))); + assert_ok!( + Scheduler::schedule_named(system::RawOrigin::Signed(1).into(), 1u32.encode(), 4, None, 127, call) + ); + assert_ok!(Scheduler::schedule(system::RawOrigin::Signed(1).into(), 4, None, 127, call2)); + run_to_block(3); + // Scheduled calls are in the agenda. + assert_eq!(Agenda::::get(4).len(), 2); + assert!(logger::log().is_empty()); + assert_noop!(Scheduler::cancel_named(system::RawOrigin::Signed(2).into(), 1u32.encode()), BadOrigin); + assert_noop!(Scheduler::cancel(system::RawOrigin::Signed(2).into(), 4, 1), BadOrigin); + assert_noop!(Scheduler::cancel_named(system::RawOrigin::Root.into(), 1u32.encode()), BadOrigin); + assert_noop!(Scheduler::cancel(system::RawOrigin::Root.into(), 4, 1), BadOrigin); + run_to_block(5); + assert_eq!( + logger::log(), + vec![(system::RawOrigin::Signed(1).into(), 69u32), (system::RawOrigin::Signed(1).into(), 42u32)] + ); + }); + } + + #[test] + fn migration_to_v2_works() { + use substrate_test_utils::assert_eq_uvec; + + new_test_ext().execute_with(|| { + for i in 0..3u64 { + let k = i.twox_64_concat(); + let old = vec![ + Some(ScheduledV1 { + maybe_id: None, + priority: i as u8 + 10, + call: Call::Logger(logger::Call::log(96, 100)), + maybe_periodic: None, + }), + None, + Some(ScheduledV1 { + maybe_id: Some(b"test".to_vec()), + priority: 123, + call: Call::Logger(logger::Call::log(69, 1000)), + maybe_periodic: Some((456u64, 10)), + }), + ]; + frame_support::migration::put_storage_value( + b"Scheduler", + b"Agenda", + &k, + old, + ); + } + + assert_eq!(StorageVersion::get(), Releases::V1); + + assert!(Scheduler::migrate_v1_to_t2()); + + assert_eq_uvec!(Agenda::::iter().collect::>(), vec![ + ( + 0, + vec![ + Some(ScheduledV2 { + maybe_id: None, + priority: 10, + call: Call::Logger(logger::Call::log(96, 100)), + maybe_periodic: None, + origin: root(), + _phantom: PhantomData::::default(), + }), + None, + Some(ScheduledV2 { + maybe_id: Some(b"test".to_vec()), + priority: 123, + call: Call::Logger(logger::Call::log(69, 1000)), + maybe_periodic: Some((456u64, 10)), + origin: root(), + _phantom: PhantomData::::default(), + }), + ]), + ( + 1, + vec![ + Some(ScheduledV2 { + maybe_id: None, + priority: 11, + call: Call::Logger(logger::Call::log(96, 100)), + maybe_periodic: None, + origin: root(), + _phantom: PhantomData::::default(), + }), + None, + Some(ScheduledV2 { + maybe_id: Some(b"test".to_vec()), + priority: 123, + call: Call::Logger(logger::Call::log(69, 1000)), + maybe_periodic: Some((456u64, 10)), + origin: root(), + _phantom: PhantomData::::default(), + }), + ] + ), + ( + 2, + vec![ + Some(ScheduledV2 { + maybe_id: None, + priority: 12, + call: Call::Logger(logger::Call::log(96, 100)), + maybe_periodic: None, + origin: root(), + _phantom: PhantomData::::default(), + }), + None, + Some(ScheduledV2 { + maybe_id: Some(b"test".to_vec()), + priority: 123, + call: Call::Logger(logger::Call::log(69, 1000)), + maybe_periodic: Some((456u64, 10)), + origin: root(), + _phantom: PhantomData::::default(), + }), + ] + ) + ]); + + assert_eq!(StorageVersion::get(), Releases::V2); + }); + } } diff --git a/frame/scored-pool/Cargo.toml b/frame/scored-pool/Cargo.toml index ae8def3dd391b0e43ac4cd156eb70d6241cce4c0..cffb408422d1f05bbab7322c8e235da2547cb819 100644 --- a/frame/scored-pool/Cargo.toml +++ b/frame/scored-pool/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-scored-pool" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for scored pools" @@ -12,17 +12,17 @@ description = "FRAME pallet for scored pools" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -pallet-balances = { version = "2.0.0-dev", path = "../balances" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/scored-pool/README.md b/frame/scored-pool/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1cdbff72ef2663687ad276f69168f3f55fca6295 --- /dev/null +++ b/frame/scored-pool/README.md @@ -0,0 +1,66 @@ +# Scored Pool Module + +The module maintains a scored membership pool. Each entity in the +pool can be attributed a `Score`. From this pool a set `Members` +is constructed. This set contains the `MemberCount` highest +scoring entities. Unscored entities are never part of `Members`. + +If an entity wants to be part of the pool a deposit is required. +The deposit is returned when the entity withdraws or when it +is removed by an entity with the appropriate authority. + +Every `Period` blocks the set of `Members` is refreshed from the +highest scoring members in the pool and, no matter if changes +occurred, `T::MembershipChanged::set_members_sorted` is invoked. +On first load `T::MembershipInitialized::initialize_members` is +invoked with the initial `Members` set. + +It is possible to withdraw candidacy/resign your membership at any +time. If an entity is currently a member, this results in removal +from the `Pool` and `Members`; the entity is immediately replaced +by the next highest scoring candidate in the pool, if available. + +- [`scored_pool::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) +- [`Module`](./struct.Module.html) + +## Interface + +### Public Functions + +- `submit_candidacy` - Submit candidacy to become a member. Requires a deposit. +- `withdraw_candidacy` - Withdraw candidacy. Deposit is returned. +- `score` - Attribute a quantitative score to an entity. +- `kick` - Remove an entity from the pool and members. Deposit is returned. +- `change_member_count` - Changes the amount of candidates taken into `Members`. + +## Usage + +```rust +use frame_support::{decl_module, dispatch}; +use frame_system::ensure_signed; +use pallet_scored_pool::{self as scored_pool}; + +pub trait Trait: scored_pool::Trait {} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + #[weight = 0] + pub fn candidate(origin) -> dispatch::DispatchResult { + let who = ensure_signed(origin)?; + + let _ = >::submit_candidacy( + T::Origin::from(Some(who.clone()).into()) + ); + Ok(()) + } + } +} + +``` + +## Dependencies + +This module depends on the [System module](../frame_system/index.html). + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/scored-pool/src/lib.rs b/frame/scored-pool/src/lib.rs index 1ba999cc7c8380bd8a68eb9627e5853f0255304f..90d4aca4e42a42e8030a468fb741ae69fd846be4 100644 --- a/frame/scored-pool/src/lib.rs +++ b/frame/scored-pool/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Scored Pool Module //! @@ -54,7 +55,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; -//! use frame_system::{self as system, ensure_signed}; +//! use frame_system::ensure_signed; //! use pallet_scored_pool::{self as scored_pool}; //! //! pub trait Trait: scored_pool::Trait {} @@ -99,7 +100,7 @@ use frame_support::{ traits::{EnsureOrigin, ChangeMembers, InitializeMembers, Currency, Get, ReservableCurrency}, weights::Weight, }; -use frame_system::{self as system, ensure_root, ensure_signed}; +use frame_system::{ensure_root, ensure_signed}; use sp_runtime::traits::{AtLeast32Bit, MaybeSerializeDeserialize, Zero, StaticLookup}; type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; @@ -307,7 +308,7 @@ decl_module! { /// Kick a member `who` from the set. /// - /// May only be called from `KickOrigin` or root. + /// May only be called from `T::KickOrigin`. /// /// The `index` parameter of this function must be set to /// the index of `dest` in the `Pool`. @@ -317,9 +318,7 @@ decl_module! { dest: ::Source, index: u32 ) { - T::KickOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + T::KickOrigin::ensure_origin(origin)?; let who = T::Lookup::lookup(dest)?; @@ -332,7 +331,7 @@ decl_module! { /// Score a member `who` with `score`. /// - /// May only be called from `ScoreOrigin` or root. + /// May only be called from `T::ScoreOrigin`. /// /// The `index` parameter of this function must be set to /// the index of the `dest` in the `Pool`. @@ -343,9 +342,7 @@ decl_module! { index: u32, score: T::Score ) { - T::ScoreOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + T::ScoreOrigin::ensure_origin(origin)?; let who = T::Lookup::lookup(dest)?; @@ -358,7 +355,7 @@ decl_module! { // if there is already an element with `score`, we insert // right before that. if not, the search returns a location // where we can insert while maintaining order. - let item = (who.clone(), Some(score.clone())); + let item = (who, Some(score.clone())); let location = pool .binary_search_by_key( &Reverse(score), diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index 6d914c60aae2c90cccada321d783d379ee590866..4581f49bbbcb69986abcd3399e2f6ea171758536 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Test utilities @@ -21,20 +22,15 @@ use super::*; use std::cell::RefCell; use frame_support::{impl_outer_origin, parameter_types, weights::Weight, ord_parameter_types}; use sp_core::H256; -// The testing primitives are very useful for avoiding having to work with signatures -// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header, }; use frame_system::EnsureSignedBy; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } -// For testing the pallet, we construct most of a mock runtime. This means -// first constructing a configuration type (`Test`) which `impl`s each of the -// configuration traits of pallets we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -54,6 +50,7 @@ ord_parameter_types! { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -69,6 +66,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -76,6 +74,7 @@ impl frame_system::Trait for Test { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl pallet_balances::Trait for Test { @@ -84,6 +83,7 @@ impl pallet_balances::Trait for Test { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } thread_local! { @@ -128,11 +128,8 @@ impl Trait for Test { type System = frame_system::Module; type Balances = pallet_balances::Module; -// This function basically just builds a genesis storage key/value store according to -// our desired mockup. pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - // We use default for brevity, but you can configure as desired if needed. pallet_balances::GenesisConfig:: { balances: vec![ (5, 500_000), diff --git a/frame/scored-pool/src/tests.rs b/frame/scored-pool/src/tests.rs index 8d87a20f757b223443b2b134fb1d66f0ab793b53..9c0074ff6e6899f6efe7967c1ddeb28661a3b5fd 100644 --- a/frame/scored-pool/src/tests.rs +++ b/frame/scored-pool/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for the module. diff --git a/frame/session/Cargo.toml b/frame/session/Cargo.toml index 9237f0a16f64a435f9758971ea64dc248ab4ff7d..81e2fc191f53580c133c7aa617864460afcee67f 100644 --- a/frame/session/Cargo.toml +++ b/frame/session/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-session" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME sessions pallet" @@ -13,21 +13,21 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-session = { version = "2.0.0-dev", default-features = false, path = "../../primitives/session" } -sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../timestamp" } -sp-trie = { optional = true, path = "../../primitives/trie", default-features = false, version = "2.0.0-dev"} -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-session = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/session" } +sp-staking = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +pallet-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../timestamp" } +sp-trie = { version = "2.0.0-rc6", optional = true, default-features = false, path = "../../primitives/trie" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-application-crypto = { version = "2.0.0-dev", path = "../../primitives/application-crypto" } +sp-application-crypto = { version = "2.0.0-rc6", path = "../../primitives/application-crypto" } lazy_static = "1.4.0" [features] @@ -37,11 +37,12 @@ std = [ "serde", "codec/std", "sp-std/std", + "sp-io/std", "frame-support/std", + "sp-core/std", "sp-runtime/std", "sp-session/std", "sp-staking/std", "pallet-timestamp/std", "sp-trie/std", - "sp-io/std", ] diff --git a/frame/session/README.md b/frame/session/README.md new file mode 100644 index 0000000000000000000000000000000000000000..387f44798261a2dd4ab8ac06fb9f15c9676216b0 --- /dev/null +++ b/frame/session/README.md @@ -0,0 +1,83 @@ +# Session Module + +The Session module allows validators to manage their session keys, provides a function for changing +the session length, and handles session rotation. + +- [`session::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) +- [`Module`](./struct.Module.html) + +## Overview + +### Terminology + + +- **Session:** A session is a period of time that has a constant set of validators. Validators can only join +or exit the validator set at a session change. It is measured in block numbers. The block where a session is +ended is determined by the `ShouldEndSession` trait. When the session is ending, a new validator set +can be chosen by `OnSessionEnding` implementations. +- **Session key:** A session key is actually several keys kept together that provide the various signing +functions required by network authorities/validators in pursuit of their duties. +- **Validator ID:** Every account has an associated validator ID. For some simple staking systems, this +may just be the same as the account ID. For staking systems using a stash/controller model, +the validator ID would be the stash account ID of the controller. +- **Session key configuration process:** Session keys are set using `set_keys` for use not in +the next session, but the session after next. They are stored in `NextKeys`, a mapping between +the caller's `ValidatorId` and the session keys provided. `set_keys` allows users to set their +session key prior to being selected as validator. +It is a public call since it uses `ensure_signed`, which checks that the origin is a signed account. +As such, the account ID of the origin stored in `NextKeys` may not necessarily be associated with +a block author or a validator. The session keys of accounts are removed once their account balance is zero. +- **Session length:** This pallet does not assume anything about the length of each session. +Rather, it relies on an implementation of `ShouldEndSession` to dictate a new session's start. +This pallet provides the `PeriodicSessions` struct for simple periodic sessions. +- **Session rotation configuration:** Configure as either a 'normal' (rewardable session where rewards are +applied) or 'exceptional' (slashable) session rotation. +- **Session rotation process:** At the beginning of each block, the `on_initialize` function +queries the provided implementation of `ShouldEndSession`. If the session is to end the newly +activated validator IDs and session keys are taken from storage and passed to the +`SessionHandler`. The validator set supplied by `SessionManager::new_session` and the corresponding session +keys, which may have been registered via `set_keys` during the previous session, are written +to storage where they will wait one session before being passed to the `SessionHandler` +themselves. + +### Goals + +The Session pallet is designed to make the following possible: + +- Set session keys of the validator set for upcoming sessions. +- Control the length of sessions. +- Configure and switch between either normal or exceptional session rotations. + +## Interface + +### Dispatchable Functions + +- `set_keys` - Set a validator's session keys for upcoming sessions. + +### Public Functions + +- `rotate_session` - Change to the next session. Register the new authority set. Queue changes +for next session rotation. +- `disable_index` - Disable a validator by index. +- `disable` - Disable a validator by Validator ID + +## Usage + +### Example from the FRAME + +The [Staking pallet](../pallet_staking/index.html) uses the Session pallet to get the validator set. + +```rust +use pallet_session as session; + +fn validators() -> Vec<::ValidatorId> { + >::validators() +} +``` + +## Related Modules + +- [Staking](../pallet_staking/index.html) + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/session/benchmarking/Cargo.toml b/frame/session/benchmarking/Cargo.toml index a3994ab3790aeea6a621382850991ed00228d171..c5e94aa61f0c3af93ce785b128a0ffb8e69223a9 100644 --- a/frame/session/benchmarking/Cargo.toml +++ b/frame/session/benchmarking/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-session-benchmarking" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME sessions pallet benchmarking" @@ -12,27 +12,30 @@ description = "FRAME sessions pallet benchmarking" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../../system" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../../benchmarking" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../../support" } -pallet-staking = { version = "2.0.0-dev", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } -pallet-session = { version = "2.0.0-dev", default-features = false, path = "../../session" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/std" } +sp-session = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/session" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/runtime" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../../system" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../../benchmarking" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../../support" } +pallet-staking = { version = "2.0.0-rc6", default-features = false, features = ["runtime-benchmarks"], path = "../../staking" } +pallet-session = { version = "2.0.0-rc6", default-features = false, path = "../../session" } +rand = { version = "0.7.2", default-features = false } [dev-dependencies] serde = { version = "1.0.101" } -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -pallet-staking-reward-curve = { version = "2.0.0-dev", path = "../../staking/reward-curve" } -sp-io ={ path = "../../../primitives/io", version = "2.0.0-dev"} -pallet-timestamp = { version = "2.0.0-dev", path = "../../timestamp" } -pallet-balances = { version = "2.0.0-dev", path = "../../balances" } +codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +pallet-staking-reward-curve = { version = "2.0.0-rc6", path = "../../staking/reward-curve" } +sp-io ={ version = "2.0.0-rc6", path = "../../../primitives/io" } +pallet-timestamp = { version = "2.0.0-rc6", path = "../../timestamp" } +pallet-balances = { version = "2.0.0-rc6", path = "../../balances" } [features] default = ["std"] std = [ "sp-std/std", + "sp-session/std", "sp-runtime/std", "frame-system/std", "frame-benchmarking/std", diff --git a/frame/session/benchmarking/README.md b/frame/session/benchmarking/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d034a9ec73284fee91c5a2a8c397f5d4bc551a0e --- /dev/null +++ b/frame/session/benchmarking/README.md @@ -0,0 +1,3 @@ +Benchmarks for the Session Pallet. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/session/benchmarking/src/lib.rs b/frame/session/benchmarking/src/lib.rs index 3b91c2fdc5194f56086b139eb33a71efc468e050..cc471893356d54eee36ec998e0bf8b6c5ff2c57f 100644 --- a/frame/session/benchmarking/src/lib.rs +++ b/frame/session/benchmarking/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Benchmarks for the Session Pallet. // This is separated into its own crate due to cyclic dependency issues. @@ -24,27 +25,37 @@ mod mock; use sp_std::prelude::*; use sp_std::vec; -use frame_system::RawOrigin; use frame_benchmarking::benchmarks; - -use pallet_session::*; -use pallet_session::Module as Session; - +use frame_support::{ + codec::Decode, + storage::StorageValue, + traits::{KeyOwnerProofSystem, OnInitialize}, +}; +use frame_system::RawOrigin; +use pallet_session::{historical::Module as Historical, Module as Session, *}; use pallet_staking::{ + benchmarking::create_validator_with_nominators, testing_utils::create_validators, MAX_NOMINATIONS, - benchmarking::create_validator_with_nominators, }; +use sp_runtime::traits::{One, StaticLookup}; + +const MAX_VALIDATORS: u32 = 1000; pub struct Module(pallet_session::Module); +pub trait Trait: pallet_session::Trait + pallet_session::historical::Trait + pallet_staking::Trait {} -pub trait Trait: pallet_session::Trait + pallet_staking::Trait {} +impl OnInitialize for Module { + fn on_initialize(n: T::BlockNumber) -> frame_support::weights::Weight { + pallet_session::Module::::on_initialize(n) + } +} benchmarks! { _ { } set_keys { let n in 1 .. MAX_NOMINATIONS as u32; - let v_stash = create_validator_with_nominators::(n, MAX_NOMINATIONS as u32)?; + let v_stash = create_validator_with_nominators::(n, MAX_NOMINATIONS as u32, false)?; let v_controller = pallet_staking::Module::::bonded(&v_stash).ok_or("not stash")?; let keys = T::Keys::default(); let proof: Vec = vec![0,1,2,3]; @@ -52,12 +63,94 @@ benchmarks! { purge_keys { let n in 1 .. MAX_NOMINATIONS as u32; - let v_stash = create_validator_with_nominators::(n, MAX_NOMINATIONS as u32)?; + let v_stash = create_validator_with_nominators::(n, MAX_NOMINATIONS as u32, false)?; let v_controller = pallet_staking::Module::::bonded(&v_stash).ok_or("not stash")?; let keys = T::Keys::default(); let proof: Vec = vec![0,1,2,3]; Session::::set_keys(RawOrigin::Signed(v_controller.clone()).into(), keys, proof)?; }: _(RawOrigin::Signed(v_controller)) + + check_membership_proof_current_session { + let n in 2 .. MAX_VALIDATORS as u32; + + let (key, key_owner_proof1) = check_membership_proof_setup::(n); + let key_owner_proof2 = key_owner_proof1.clone(); + }: { + Historical::::check_proof(key, key_owner_proof1); + } + verify { + assert!(Historical::::check_proof(key, key_owner_proof2).is_some()); + } + + check_membership_proof_historical_session { + let n in 2 .. MAX_VALIDATORS as u32; + + let (key, key_owner_proof1) = check_membership_proof_setup::(n); + + // skip to the next session so that the session is historical + // and the membership merkle proof must be checked. + Session::::rotate_session(); + + let key_owner_proof2 = key_owner_proof1.clone(); + }: { + Historical::::check_proof(key, key_owner_proof1); + } + verify { + assert!(Historical::::check_proof(key, key_owner_proof2).is_some()); + } +} + +/// Sets up the benchmark for checking a membership proof. It creates the given +/// number of validators, sets random session keys and then creates a membership +/// proof for the first authority and returns its key and the proof. +fn check_membership_proof_setup( + n: u32, +) -> ( + (sp_runtime::KeyTypeId, &'static [u8; 32]), + sp_session::MembershipProof, +) { + pallet_staking::ValidatorCount::put(n); + + // create validators and set random session keys + for (n, who) in create_validators::(n, 1000) + .unwrap() + .into_iter() + .enumerate() + { + use rand::RngCore; + use rand::SeedableRng; + + let validator = T::Lookup::lookup(who).unwrap(); + let controller = pallet_staking::Module::::bonded(validator).unwrap(); + + let keys = { + let mut keys = [0u8; 128]; + + // we keep the keys for the first validator as 0x00000... + if n > 0 { + let mut rng = rand::rngs::StdRng::seed_from_u64(n as u64); + rng.fill_bytes(&mut keys); + } + + keys + }; + + let keys: T::Keys = Decode::decode(&mut &keys[..]).unwrap(); + let proof: Vec = vec![]; + + Session::::set_keys(RawOrigin::Signed(controller).into(), keys, proof).unwrap(); + } + + Module::::on_initialize(T::BlockNumber::one()); + + // skip sessions until the new validator set is enacted + while Session::::validators().len() < n as usize { + Session::::rotate_session(); + } + + let key = (sp_runtime::KeyTypeId(*b"babe"), &[0u8; 32]); + + (key, Historical::::prove(key).unwrap()) } #[cfg(test)] diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index 5a7082dabbad65fcc48d179476421e50e63a17ea..d4eac4247734f420655d724cd267c7603d3c297d 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Mock file for session benchmarking. @@ -32,7 +33,7 @@ type Staking = pallet_staking::Module; type Session = pallet_session::Module; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } impl_outer_dispatch! { @@ -57,6 +58,7 @@ impl Convert for CurrencyToVoteHandler { pub struct Test; impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; type BlockNumber = BlockNumber; @@ -72,13 +74,15 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = (); type AvailableBlockRatio = (); type MaximumBlockLength = (); type Version = (); type ModuleToIndex = (); type AccountData = pallet_balances::AccountData; type OnNewAccount = (); - type OnKilledAccount = (Balances,); + type OnKilledAccount = Balances; + type SystemWeightInfo = (); } parameter_types! { pub const ExistentialDeposit: Balance = 10; @@ -89,6 +93,7 @@ impl pallet_balances::Trait for Test { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { @@ -98,6 +103,7 @@ impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } impl pallet_session::historical::Trait for Test { type FullIdentification = pallet_staking::Exposure; @@ -135,6 +141,7 @@ impl pallet_session::Trait for Test { type ValidatorId = AccountId; type ValidatorIdOf = pallet_staking::StashOf; type DisabledValidatorsThreshold = (); + type WeightInfo = (); } pallet_staking_reward_curve::build! { const I_NPOS: sp_runtime::curve::PiecewiseLinear<'static> = curve!( @@ -181,6 +188,8 @@ impl pallet_staking::Trait for Test { type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type UnsignedPriority = UnsignedPriority; type MaxIterations = (); + type MinSolutionScoreBump = (); + type WeightInfo = (); } impl crate::Trait for Test {} diff --git a/frame/session/src/historical.rs b/frame/session/src/historical/mod.rs similarity index 92% rename from frame/session/src/historical.rs rename to frame/session/src/historical/mod.rs index d9711ecf9d3bd0242555749889604ea75810b1d5..20c3d57464c89c9a3f6b4877e64210e489a79513 100644 --- a/frame/session/src/historical.rs +++ b/frame/session/src/historical/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! An opt-in utility for tracking historical sessions in FRAME-session. //! @@ -36,6 +37,10 @@ use sp_trie::{MemoryDB, Trie, TrieMut, Recorder, EMPTY_PREFIX}; use sp_trie::trie_types::{TrieDBMut, TrieDB}; use super::{SessionIndex, Module as SessionModule}; +mod shared; +pub mod offchain; +pub mod onchain; + /// Trait necessary for the historical module. pub trait Trait: super::Trait { /// Full identification of the validator. @@ -115,6 +120,7 @@ impl crate::SessionManager for NoteHistoricalRoot { fn new_session(new_index: SessionIndex) -> Option> { + StoredRange::mutate(|range| { range.get_or_insert_with(|| (new_index, new_index)).1 = new_index + 1; }); @@ -142,10 +148,13 @@ impl crate::SessionManager for NoteHistoricalRoot>::start_session(start_index) } + fn end_session(end_index: SessionIndex) { + onchain::store_session_validator_set_to_offchain::(end_index); >::end_session(end_index) } } @@ -153,7 +162,7 @@ impl crate::SessionManager for NoteHistoricalRoot = (::ValidatorId, ::FullIdentification); -/// a trie instance for checking and generating proofs. +/// A trie instance for checking and generating proofs. pub struct ProvingTrie { db: MemoryDB, root: T::Hash, @@ -249,7 +258,6 @@ impl ProvingTrie { .ok()? .and_then(|raw| >::decode(&mut &*raw).ok()) } - } impl> frame_support::traits::KeyOwnerProofSystem<(KeyTypeId, D)> @@ -310,9 +318,9 @@ impl> frame_support::traits::KeyOwnerProofSystem<(KeyTy } #[cfg(test)] -mod tests { +pub(crate) mod tests { use super::*; - use sp_core::crypto::key_types::DUMMY; + use sp_runtime::key_types::DUMMY; use sp_runtime::testing::UintAuthorityId; use crate::mock::{ NEXT_VALIDATORS, force_new_session, @@ -322,7 +330,7 @@ mod tests { type Historical = Module; - fn new_test_ext() -> sp_io::TestExternalities { + pub(crate) fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); crate::GenesisConfig:: { keys: NEXT_VALIDATORS.with(|l| diff --git a/frame/session/src/historical/offchain.rs b/frame/session/src/historical/offchain.rs new file mode 100644 index 0000000000000000000000000000000000000000..97655d1a18b3280b85e7d2074e8071152611dfea --- /dev/null +++ b/frame/session/src/historical/offchain.rs @@ -0,0 +1,263 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Off-chain logic for creating a proof based data provided by on-chain logic. +//! +//! Validator-set extracting an iterator from an off-chain worker stored list containing +//! historical validator-sets. +//! Based on the logic of historical slashing, but the validation is done off-chain. +//! Use [`fn store_current_session_validator_set_to_offchain()`](super::onchain) to store the +//! required data to the offchain validator set. +//! This is used in conjunction with [`ProvingTrie`](super::ProvingTrie) and +//! the off-chain indexing API. + +use sp_runtime::{offchain::storage::StorageValueRef, KeyTypeId}; +use sp_session::MembershipProof; + +use super::super::{Module as SessionModule, SessionIndex}; +use super::{IdentificationTuple, ProvingTrie, Trait}; + +use super::shared; +use sp_std::prelude::*; + + +/// A set of validators, which was used for a fixed session index. +struct ValidatorSet { + validator_set: Vec>, +} + +impl ValidatorSet { + /// Load the set of validators for a particular session index from the off-chain storage. + /// + /// If none is found or decodable given `prefix` and `session`, it will return `None`. + /// Empty validator sets should only ever exist for genesis blocks. + pub fn load_from_offchain_db(session_index: SessionIndex) -> Option { + let derived_key = shared::derive_key(shared::PREFIX, session_index); + StorageValueRef::persistent(derived_key.as_ref()) + .get::>() + .flatten() + .map(|validator_set| Self { validator_set }) + } + + #[inline] + fn len(&self) -> usize { + self.validator_set.len() + } +} + +/// Implement conversion into iterator for usage +/// with [ProvingTrie](super::ProvingTrie::generate_for). +impl sp_std::iter::IntoIterator for ValidatorSet { + type Item = (T::ValidatorId, T::FullIdentification); + type IntoIter = sp_std::vec::IntoIter; + fn into_iter(self) -> Self::IntoIter { + self.validator_set.into_iter() + } +} + +/// Create a proof based on the data available in the off-chain database. +/// +/// Based on the yielded `MembershipProof` the implementer may decide what +/// to do, i.e. in case of a failed proof, enqueue a transaction back on +/// chain reflecting that, with all its consequences such as i.e. slashing. +pub fn prove_session_membership>( + session_index: SessionIndex, + session_key: (KeyTypeId, D), +) -> Option { + let validators = ValidatorSet::::load_from_offchain_db(session_index)?; + let count = validators.len() as u32; + let trie = ProvingTrie::::generate_for(validators.into_iter()).ok()?; + + let (id, data) = session_key; + trie.prove(id, data.as_ref()) + .map(|trie_nodes| MembershipProof { + session: session_index, + trie_nodes, + validator_count: count, + }) +} + + +/// Attempt to prune anything that is older than `first_to_keep` session index. +/// +/// Due to re-organisation it could be that the `first_to_keep` might be less +/// than the stored one, in which case the conservative choice is made to keep records +/// up to the one that is the lesser. +pub fn prune_older_than(first_to_keep: SessionIndex) { + let derived_key = shared::LAST_PRUNE.to_vec(); + let entry = StorageValueRef::persistent(derived_key.as_ref()); + match entry.mutate(|current: Option>| -> Result<_, ()> { + match current { + Some(Some(current)) if current < first_to_keep => Ok(first_to_keep), + // do not move the cursor, if the new one would be behind ours + Some(Some(current)) => Ok(current), + None => Ok(first_to_keep), + // if the storage contains undecodable data, overwrite with current anyways + // which might leak some entries being never purged, but that is acceptable + // in this context + Some(None) => Ok(first_to_keep), + } + }) { + Ok(Ok(new_value)) => { + // on a re-org this is not necessarily true, with the above they might be equal + if new_value < first_to_keep { + for session_index in new_value..first_to_keep { + let derived_key = shared::derive_key(shared::PREFIX, session_index); + let _ = StorageValueRef::persistent(derived_key.as_ref()).clear(); + } + } + } + Ok(Err(_)) => {} // failed to store the value calculated with the given closure + Err(_) => {} // failed to calculate the value to store with the given closure + } +} + +/// Keep the newest `n` items, and prune all items older than that. +pub fn keep_newest(n_to_keep: usize) { + let session_index = >::current_index(); + let n_to_keep = n_to_keep as SessionIndex; + if n_to_keep < session_index { + prune_older_than::(session_index - n_to_keep) + } +} + +#[cfg(test)] +mod tests { + use super::super::{onchain, Module}; + use super::*; + use crate::mock::{ + force_new_session, set_next_validators, Session, System, Test, NEXT_VALIDATORS, + }; + use codec::Encode; + use frame_support::traits::{KeyOwnerProofSystem, OnInitialize}; + use sp_core::crypto::key_types::DUMMY; + use sp_core::offchain::{ + testing::TestOffchainExt, + OffchainExt, + StorageKind, + }; + + use sp_runtime::testing::UintAuthorityId; + + type Historical = Module; + + pub fn new_test_ext() -> sp_io::TestExternalities { + let mut ext = frame_system::GenesisConfig::default() + .build_storage::() + .expect("Failed to create test externalities."); + + crate::GenesisConfig:: { + keys: NEXT_VALIDATORS.with(|l| { + l.borrow() + .iter() + .cloned() + .map(|i| (i, i, UintAuthorityId(i).into())) + .collect() + }), + } + .assimilate_storage(&mut ext) + .unwrap(); + + + let mut ext = sp_io::TestExternalities::new(ext); + + let (offchain, offchain_state) = TestOffchainExt::with_offchain_db(ext.offchain_db()); + + const ITERATIONS: u32 = 5u32; + let mut seed = [0u8; 32]; + seed[0..4].copy_from_slice(&ITERATIONS.to_le_bytes()); + offchain_state.write().seed = seed; + + ext.register_extension(OffchainExt::new(offchain)); + ext + } + + #[test] + fn encode_decode_roundtrip() { + use codec::{Decode, Encode}; + use super::super::super::Trait as SessionTrait; + use super::super::Trait as HistoricalTrait; + + let sample = ( + 22u32 as ::ValidatorId, + 7_777_777 as ::FullIdentification); + + let encoded = sample.encode(); + let decoded = Decode::decode(&mut encoded.as_slice()).expect("Must decode"); + assert_eq!(sample, decoded); + } + + #[test] + fn onchain_to_offchain() { + let mut ext = new_test_ext(); + + const DATA: &[u8] = &[7,8,9,10,11]; + ext.execute_with(|| { + b"alphaomega"[..].using_encoded(|key| sp_io::offchain_index::set(key, DATA)); + }); + + ext.persist_offchain_overlay(); + + ext.execute_with(|| { + let data = + b"alphaomega"[..].using_encoded(|key| { + sp_io::offchain::local_storage_get(StorageKind::PERSISTENT, key) + }); + assert_eq!(data, Some(DATA.to_vec())); + }); + } + + + #[test] + fn historical_proof_offchain() { + let mut ext = new_test_ext(); + let encoded_key_1 = UintAuthorityId(1).encode(); + + ext.execute_with(|| { + set_next_validators(vec![1, 2]); + force_new_session(); + + System::set_block_number(1); + Session::on_initialize(1); + + // "on-chain" + onchain::store_current_session_validator_set_to_offchain::(); + assert_eq!(>::current_index(), 1); + + set_next_validators(vec![7, 8]); + + force_new_session(); + }); + + ext.persist_offchain_overlay(); + + ext.execute_with(|| { + + + System::set_block_number(2); + Session::on_initialize(2); + assert_eq!(>::current_index(), 2); + + // "off-chain" + let proof = prove_session_membership::(1, (DUMMY, &encoded_key_1)); + assert!(proof.is_some()); + let proof = proof.expect("Must be Some(Proof)"); + + assert!(Historical::check_proof((DUMMY, &encoded_key_1[..]), proof.clone()).is_some()); + }); + } +} diff --git a/frame/session/src/historical/onchain.rs b/frame/session/src/historical/onchain.rs new file mode 100644 index 0000000000000000000000000000000000000000..745603a49829be556cddd7f1fbfe244a1ea0a93d --- /dev/null +++ b/frame/session/src/historical/onchain.rs @@ -0,0 +1,62 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! On-chain logic to store a validator-set for deferred validation using an off-chain worker. + +use codec::Encode; +use sp_runtime::traits::Convert; + +use super::super::Trait as SessionTrait; +use super::super::{Module as SessionModule, SessionIndex}; +use super::Trait as HistoricalTrait; + +use super::shared; +use sp_std::prelude::*; + +/// Store the validator-set associated to the `session_index` to the off-chain database. +/// +/// Further processing is then done [`off-chain side`](super::offchain). +/// +/// **Must** be called from on-chain, i.e. a call that originates from +/// `on_initialize(..)` or `on_finalization(..)`. +/// **Must** be called during the session, which validator-set is to be stored for further +/// off-chain processing. Otherwise the `FullIdentification` might not be available. +pub fn store_session_validator_set_to_offchain( + session_index: SessionIndex, +) { + let encoded_validator_list = >::validators() + .into_iter() + .filter_map(|validator_id: ::ValidatorId| { + let full_identification = + <::FullIdentificationOf>::convert(validator_id.clone()); + full_identification.map(|full_identification| (validator_id, full_identification)) + }) + .collect::>(); + + encoded_validator_list.using_encoded(|encoded_validator_list| { + let derived_key = shared::derive_key(shared::PREFIX, session_index); + sp_io::offchain_index::set(derived_key.as_slice(), encoded_validator_list); + }); +} + +/// Store the validator set associated to the _current_ session index to the off-chain database. +/// +/// See [`fn store_session_validator_set_...(..)`](Self::store_session_validator_set_to_offchain) +/// for further information and restrictions. +pub fn store_current_session_validator_set_to_offchain() { + store_session_validator_set_to_offchain::(>::current_index()); +} diff --git a/frame/session/src/historical/shared.rs b/frame/session/src/historical/shared.rs new file mode 100644 index 0000000000000000000000000000000000000000..fda0361b05959ab388a34d31d7fce5e1efc8ea4b --- /dev/null +++ b/frame/session/src/historical/shared.rs @@ -0,0 +1,39 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Shared logic between on-chain and off-chain components used for slashing using an off-chain +//! worker. + + +use super::SessionIndex; +use sp_std::prelude::*; +use codec::Encode; + +pub(super) const PREFIX: &[u8] = b"session_historical"; +pub(super) const LAST_PRUNE: &[u8] = b"session_historical_last_prune"; + +/// Derive the key used to store the list of validators +pub(super) fn derive_key>(prefix: P, session_index: SessionIndex) -> Vec { + let prefix: &[u8] = prefix.as_ref(); + session_index.using_encoded(|encoded_session_index| { + prefix.into_iter() + .chain(b"/".into_iter()) + .chain(encoded_session_index.into_iter()) + .copied() + .collect::>() + }) +} \ No newline at end of file diff --git a/frame/session/src/lib.rs b/frame/session/src/lib.rs index 8e252211319fbf8652148399ea75eea0a450eae1..2c1cba7137dccc63d44f33af1cd3e4ca314d3194 100644 --- a/frame/session/src/lib.rs +++ b/frame/session/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Session Module //! @@ -112,7 +113,7 @@ use frame_support::{ dispatch::{self, DispatchResult, DispatchError}, weights::Weight, }; -use frame_system::{self as system, ensure_signed}; +use frame_system::ensure_signed; #[cfg(test)] mod mock; @@ -170,6 +171,14 @@ impl< offset }) } + + fn weight(_now: BlockNumber) -> Weight { + // Weight note: `estimate_next_session_rotation` has no storage reads and trivial computational overhead. + // There should be no risk to the chain having this weight value be zero for now. + // However, this value of zero was not properly calculated, and so it would be reasonable + // to come back here and properly calculate the weight of this function. + 0 + } } /// A trait for managing creation of new validator set. @@ -210,7 +219,7 @@ pub trait SessionHandler { /// All the key type ids this session handler can process. /// /// The order must be the same as it expects them in - /// [`on_new_session`](Self::on_new_session) and [`on_genesis_session`](Self::on_genesis_session). + /// [`on_new_session`](Self::on_new_session) and [`on_genesis_session`](Self::on_genesis_session). const KEY_TYPE_IDS: &'static [KeyTypeId]; /// The given validator set will be used for the genesis session. @@ -342,6 +351,16 @@ impl ValidatorRegistration for Module { } } +pub trait WeightInfo { + fn set_keys(n: u32, ) -> Weight; + fn purge_keys(n: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn set_keys(_n: u32, ) -> Weight { 1_000_000_000 } + fn purge_keys(_n: u32, ) -> Weight { 1_000_000_000 } +} + pub trait Trait: frame_system::Trait { /// The overarching event type. type Event: From + Into<::Event>; @@ -376,6 +395,9 @@ pub trait Trait: frame_system::Trait { /// After the threshold is reached `disabled` method starts to return true, /// which in combination with `pallet_staking` forces a new era. type DisabledValidatorsThreshold: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_storage! { @@ -425,7 +447,7 @@ decl_storage! { for (account, val, keys) in config.keys.iter().cloned() { >::inner_set_keys(&val, keys) .expect("genesis config must not contain duplicates; qed"); - system::Module::::inc_ref(&account); + frame_system::Module::::inc_ref(&account); } let initial_validators_0 = T::SessionManager::new_session(0) @@ -462,7 +484,7 @@ decl_storage! { decl_event!( pub enum Event { - /// New session has happened. Note that the argument is the session index, not the block + /// New session has happened. Note that the argument is the [session_index], not the block /// number as the type might suggest. NewSession(SessionIndex), } @@ -683,7 +705,7 @@ impl Module { let old_keys = Self::inner_set_keys(&who, keys)?; if old_keys.is_none() { - system::Module::::inc_ref(&account); + frame_system::Module::::inc_ref(&account); } Ok(()) @@ -731,7 +753,7 @@ impl Module { let key_data = old_keys.get_raw(*id); Self::clear_key_owner(*id, key_data); } - system::Module::::dec_ref(&account); + frame_system::Module::::dec_ref(&account); Ok(()) } @@ -785,4 +807,8 @@ impl EstimateNextNewSession for Module { fn estimate_next_new_session(now: T::BlockNumber) -> Option { T::NextSessionRotation::estimate_next_session_rotation(now) } + + fn weight(now: T::BlockNumber) -> Weight { + T::NextSessionRotation::weight(now) + } } diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index 9e9b8776589d29b88fc58738bfe77b45f997ec2e..bd94264b155602e697f664ddf58a1d7ae1768299 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Mock helpers for Session. @@ -40,7 +41,7 @@ impl From for MockSessionKeys { } impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } thread_local! { @@ -172,6 +173,7 @@ parameter_types! { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -187,6 +189,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -194,12 +197,14 @@ impl frame_system::Trait for Test { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } parameter_types! { @@ -219,6 +224,7 @@ impl Trait for Test { type Event = (); type DisabledValidatorsThreshold = DisabledValidatorsThreshold; type NextSessionRotation = (); + type WeightInfo = (); } #[cfg(feature = "historical")] diff --git a/frame/session/src/tests.rs b/frame/session/src/tests.rs index abfd9f738b614e2d9078ddfe02c07a1f3d862a32..75def78046bebf97111feca0320a256d17bb3207 100644 --- a/frame/session/src/tests.rs +++ b/frame/session/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // Tests for the Session Pallet diff --git a/frame/society/Cargo.toml b/frame/society/Cargo.toml index d79eb78b7d664dbd88da1c931730678aab6d7c4f..2fd44446cc84dbdc2c2186bee499b678c015369e 100644 --- a/frame/society/Cargo.toml +++ b/frame/society/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-society" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME society pallet" @@ -13,24 +13,23 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } rand_chacha = { version = "0.2", default-features = false } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-rc6", path = "../../primitives/io" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } [features] default = ["std"] std = [ "codec/std", "serde", - "sp-io/std", "sp-runtime/std", "rand_chacha/std", "sp-std/std", diff --git a/frame/society/README.md b/frame/society/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d73397cc99cbb24d5f091122f672ad9f6d88af63 --- /dev/null +++ b/frame/society/README.md @@ -0,0 +1,228 @@ +# Society Module + +- [`society::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +The Society module is an economic game which incentivizes users to participate +and maintain a membership society. + +### User Types + +At any point, a user in the society can be one of a: +* Bidder - A user who has submitted intention of joining the society. +* Candidate - A user who will be voted on to join the society. +* Suspended Candidate - A user who failed to win a vote. +* Member - A user who is a member of the society. +* Suspended Member - A member of the society who has accumulated too many strikes +or failed their membership challenge. + +Of the non-suspended members, there is always a: +* Head - A member who is exempt from suspension. +* Defender - A member whose membership is under question and voted on again. + +Of the non-suspended members of the society, a random set of them are chosen as +"skeptics". The mechanics of skeptics is explained in the +[member phase](#member-phase) below. + +### Mechanics + +#### Rewards + +Members are incentivized to participate in the society through rewards paid +by the Society treasury. These payments have a maturity period that the user +must wait before they are able to access the funds. + +#### Punishments + +Members can be punished by slashing the reward payouts that have not been +collected. Additionally, members can accumulate "strikes", and when they +reach a max strike limit, they become suspended. + +#### Skeptics + +During the voting period, a random set of members are selected as "skeptics". +These skeptics are expected to vote on the current candidates. If they do not vote, +their skeptic status is treated as a rejection vote, the member is deemed +"lazy", and are given a strike per missing vote. + +#### Membership Challenges + +Every challenge rotation period, an existing member will be randomly selected +to defend their membership into society. Then, other members can vote whether +this defender should stay in society. A simple majority wins vote will determine +the outcome of the user. Ties are treated as a failure of the challenge, but +assuming no one else votes, the defender always get a free vote on their +own challenge keeping them in the society. The Head member is exempt from the +negative outcome of a membership challenge. + +#### Society Treasury + +The membership society is independently funded by a treasury managed by this +module. Some subset of this treasury is placed in a Society Pot, which is used +to determine the number of accepted bids. + +#### Rate of Growth + +The membership society can grow at a rate of 10 accepted candidates per rotation period up +to the max membership threshold. Once this threshold is met, candidate selections +are stalled until there is space for new members to join. This can be resolved by +voting out existing members through the random challenges or by using governance +to increase the maximum membership count. + +### User Life Cycle + +A user can go through the following phases: + +```rust + +-------> User <----------+ + | + | + | | | ++----------------------------------------------+ +| | | | | +| | v | | +| | Bidder <-----------+ | +| | + | | +| | | + | +| | v Suspended | +| | Candidate +----> Candidate | +| | + + | +| | | | | +| + | | | +| Suspended +------>| | | +| Member | | | +| ^ | | | +| | v | | +| +-------+ Member <----------+ | +| | +| | ++------------------Society---------------------+ +``` + +#### Initialization + +The society is initialized with a single member who is automatically chosen as the Head. + +#### Bid Phase + +New users must have a bid to join the society. + +A user can make a bid by reserving a deposit. Alternatively, an already existing member +can create a bid on a user's behalf by "vouching" for them. + +A bid includes reward information that the user would like to receive for joining +the society. A vouching bid can additionally request some portion of that reward as a tip +to the voucher for vouching for the prospective candidate. + +Every rotation period, Bids are ordered by reward amount, and the module +selects as many bids the Society Pot can support for that period. + +These selected bids become candidates and move on to the Candidate phase. +Bids that were not selected stay in the bidder pool until they are selected or +a user chooses to "unbid". + +#### Candidate Phase + +Once a bidder becomes a candidate, members vote whether to approve or reject +that candidate into society. This voting process also happens during a rotation period. + +The approval and rejection criteria for candidates are not set on chain, +and may change for different societies. + +At the end of the rotation period, we collect the votes for a candidate +and randomly select a vote as the final outcome. + +```rust + [ a-accept, r-reject, s-skeptic ] ++----------------------------------+ +| | +| Member |0|1|2|3|4|5|6|7|8|9| | +| ----------------------------- | +| Vote |a|a|a|r|s|r|a|a|s|a| | +| ----------------------------- | +| Selected | | | |x| | | | | | | | +| | ++----------------------------------+ + +Result: Rejected +``` + +Each member that voted opposite to this randomly selected vote is punished by +slashing their unclaimed payouts and increasing the number of strikes they have. + +These slashed funds are given to a random user who voted the same as the +selected vote as a reward for participating in the vote. + +If the candidate wins the vote, they receive their bid reward as a future payout. +If the bid was placed by a voucher, they will receive their portion of the reward, +before the rest is paid to the winning candidate. + +One winning candidate is selected as the Head of the members. This is randomly +chosen, weighted by the number of approvals the winning candidates accumulated. + +If the candidate loses the vote, they are suspended and it is up to the Suspension +Judgement origin to determine if the candidate should go through the bidding process +again, should be accepted into the membership society, or rejected and their deposit +slashed. + +#### Member Phase + +Once a candidate becomes a member, their role is to participate in society. + +Regular participation involves voting on candidates who want to join the membership +society, and by voting in the right way, a member will accumulate future payouts. +When a payout matures, members are able to claim those payouts. + +Members can also vouch for users to join the society, and request a "tip" from +the fees the new member would collect by joining the society. This vouching +process is useful in situations where a user may not have enough balance to +satisfy the bid deposit. A member can only vouch one user at a time. + +During rotation periods, a random group of members are selected as "skeptics". +These skeptics are expected to vote on the current candidates. If they do not vote, +their skeptic status is treated as a rejection vote, the member is deemed +"lazy", and are given a strike per missing vote. + +There is a challenge period in parallel to the rotation period. During a challenge period, +a random member is selected to defend their membership to the society. Other members +make a traditional majority-wins vote to determine if the member should stay in the society. +Ties are treated as a failure of the challenge. + +If a member accumulates too many strikes or fails their membership challenge, +they will become suspended. While a member is suspended, they are unable to +claim matured payouts. It is up to the Suspension Judgement origin to determine +if the member should re-enter society or be removed from society with all their +future payouts slashed. + +## Interface + +### Dispatchable Functions + +#### For General Users + +* `bid` - A user can make a bid to join the membership society by reserving a deposit. +* `unbid` - A user can withdraw their bid for entry, the deposit is returned. + +#### For Members + +* `vouch` - A member can place a bid on behalf of a user to join the membership society. +* `unvouch` - A member can revoke their vouch for a user. +* `vote` - A member can vote to approve or reject a candidate's request to join the society. +* `defender_vote` - A member can vote to approve or reject a defender's continued membership +to the society. +* `payout` - A member can claim their first matured payment. +* `unfound` - Allow the founder to unfound the society when they are the only member. + +#### For Super Users + +* `found` - The founder origin can initiate this society. Useful for bootstrapping the Society +pallet on an already running chain. +* `judge_suspended_member` - The suspension judgement origin is able to make +judgement on a suspended member. +* `judge_suspended_candidate` - The suspension judgement origin is able to +make judgement on a suspended candidate. +* `set_max_membership` - The ROOT origin can update the maximum member count for the society. +The max membership count must be greater than 1. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/society/src/lib.rs b/frame/society/src/lib.rs index fcc0c66ebdbb463db4b320c388cc9eb32e1165d5..69ba46c83295563ca71b4301090ba2226dd8ecc7 100644 --- a/frame/society/src/lib.rs +++ b/frame/society/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Society Module //! @@ -263,11 +264,12 @@ use frame_support::{decl_error, decl_module, decl_storage, decl_event, ensure, d use frame_support::weights::Weight; use frame_support::traits::{ Currency, ReservableCurrency, Randomness, Get, ChangeMembers, BalanceStatus, - ExistenceRequirement::AllowDeath, EnsureOrigin + ExistenceRequirement::AllowDeath, EnsureOrigin, OnUnbalanced, Imbalance }; use frame_system::{self as system, ensure_signed, ensure_root}; type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; +type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; /// The module's configuration trait. pub trait Trait: system::Trait { @@ -531,7 +533,7 @@ decl_module! { /// /// Total Complexity: O(M + B + C + logM + logB + X) /// # - #[weight = 50_000_000] + #[weight = T::MaximumBlockWeight::get() / 10] pub fn bid(origin, value: BalanceOf) -> DispatchResult { let who = ensure_signed(origin)?; ensure!(!>::contains_key(&who), Error::::Suspended); @@ -570,7 +572,7 @@ decl_module! { /// /// Total Complexity: O(B + X) /// # - #[weight = 20_000_000] + #[weight = T::MaximumBlockWeight::get() / 10] pub fn unbid(origin, pos: u32) -> DispatchResult { let who = ensure_signed(origin)?; @@ -640,7 +642,7 @@ decl_module! { /// /// Total Complexity: O(M + B + C + logM + logB + X) /// # - #[weight = 50_000_000] + #[weight = T::MaximumBlockWeight::get() / 10] pub fn vouch(origin, who: T::AccountId, value: BalanceOf, tip: BalanceOf) -> DispatchResult { let voucher = ensure_signed(origin)?; // Check user is not suspended. @@ -681,7 +683,7 @@ decl_module! { /// /// Total Complexity: O(B) /// # - #[weight = 20_000_000] + #[weight = T::MaximumBlockWeight::get() / 10] pub fn unvouch(origin, pos: u32) -> DispatchResult { let voucher = ensure_signed(origin)?; ensure!(Self::vouching(&voucher) == Some(VouchingStatus::Vouching), Error::::NotVouching); @@ -719,7 +721,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + C) /// # - #[weight = 30_000_000] + #[weight = T::MaximumBlockWeight::get() / 10] pub fn vote(origin, candidate: ::Source, approve: bool) { let voter = ensure_signed(origin)?; let candidate = T::Lookup::lookup(candidate)?; @@ -750,7 +752,7 @@ decl_module! { /// /// Total Complexity: O(M + logM) /// # - #[weight = 20_000_000] + #[weight = T::MaximumBlockWeight::get() / 10] pub fn defender_vote(origin, approve: bool) { let voter = ensure_signed(origin)?; let members = >::get(); @@ -782,7 +784,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + P + X) /// # - #[weight = 30_000_000] + #[weight = T::MaximumBlockWeight::get() / 10] pub fn payout(origin) { let who = ensure_signed(origin)?; @@ -824,7 +826,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = 0] + #[weight = T::MaximumBlockWeight::get() / 10] fn found(origin, founder: T::AccountId, max_members: u32, rules: Vec) { T::FounderSetOrigin::ensure_origin(origin)?; ensure!(!>::exists(), Error::::AlreadyFounded); @@ -851,7 +853,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = 20_000_000] + #[weight = T::MaximumBlockWeight::get() / 10] fn unfound(origin) { let founder = ensure_signed(origin)?; ensure!(Founder::::get() == Some(founder.clone()), Error::::NotFounder); @@ -893,7 +895,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + B) /// # - #[weight = 30_000_000] + #[weight = T::MaximumBlockWeight::get() / 10] fn judge_suspended_member(origin, who: T::AccountId, forgive: bool) { T::SuspensionJudgementOrigin::ensure_origin(origin)?; ensure!(>::contains_key(&who), Error::::NotSuspended); @@ -964,7 +966,7 @@ decl_module! { /// /// Total Complexity: O(M + logM + B + X) /// # - #[weight = 50_000_000] + #[weight = T::MaximumBlockWeight::get() / 10] fn judge_suspended_candidate(origin, who: T::AccountId, judgement: Judgement) { T::SuspensionJudgementOrigin::ensure_origin(origin)?; if let Some((value, kind)) = >::get(&who) { @@ -1024,7 +1026,7 @@ decl_module! { /// /// Total Complexity: O(1) /// # - #[weight = 0] + #[weight = T::MaximumBlockWeight::get() / 10] fn set_max_members(origin, max: u32) { ensure_root(origin)?; ensure!(max > 1, Error::::MaxMembers); @@ -1035,10 +1037,14 @@ decl_module! { fn on_initialize(n: T::BlockNumber) -> Weight { let mut members = vec![]; + let mut weight = 0; + // Run a candidate/membership rotation if (n % T::RotationPeriod::get()).is_zero() { members = >::get(); Self::rotate_period(&mut members); + + weight += T::MaximumBlockWeight::get() / 20; } // Run a challenge rotation @@ -1048,9 +1054,11 @@ decl_module! { members = >::get(); } Self::rotate_challenge(&mut members); + + weight += T::MaximumBlockWeight::get() / 20; } - 0 + weight } } } @@ -1103,39 +1111,41 @@ decl_event! { AccountId = ::AccountId, Balance = BalanceOf { - /// The society is founded by the given identity. + /// The society is founded by the given identity. [founder] Founded(AccountId), /// A membership bid just happened. The given account is the candidate's ID and their offer - /// is the second. + /// is the second. [candidate_id, offer] Bid(AccountId, Balance), /// A membership bid just happened by vouching. The given account is the candidate's ID and - /// their offer is the second. The vouching party is the third. + /// their offer is the second. The vouching party is the third. [candidate_id, offer, vouching] Vouch(AccountId, Balance, AccountId), - /// A candidate was dropped (due to an excess of bids in the system). + /// A [candidate] was dropped (due to an excess of bids in the system). AutoUnbid(AccountId), - /// A candidate was dropped (by their request). + /// A [candidate] was dropped (by their request). Unbid(AccountId), - /// A candidate was dropped (by request of who vouched for them). + /// A [candidate] was dropped (by request of who vouched for them). Unvouch(AccountId), /// A group of candidates have been inducted. The batch's primary is the first value, the - /// batch in full is the second. + /// batch in full is the second. [primary, candidates] Inducted(AccountId, Vec), - /// A suspended member has been judged + /// A suspended member has been judged. [who, judged] SuspendedMemberJudgement(AccountId, bool), - /// A candidate has been suspended + /// A [candidate] has been suspended CandidateSuspended(AccountId), - /// A member has been suspended + /// A [member] has been suspended MemberSuspended(AccountId), - /// A member has been challenged + /// A [member] has been challenged Challenged(AccountId), - /// A vote has been placed (candidate, voter, vote) + /// A vote has been placed [candidate, voter, vote] Vote(AccountId, AccountId, bool), - /// A vote has been placed for a defending member (voter, vote) + /// A vote has been placed for a defending member [voter, vote] DefenderVote(AccountId, bool), - /// A new max member count has been set + /// A new [max] member count has been set NewMaxMembers(u32), - /// Society is unfounded. + /// Society is unfounded. [founder] Unfounded(AccountId), + /// Some funds were deposited into the society account. [value] + Deposit(Balance), } } @@ -1658,3 +1668,14 @@ impl, I: Instance> Module { } } } + +impl OnUnbalanced> for Module { + fn on_nonzero_unbalanced(amount: NegativeImbalanceOf) { + let numeric_amount = amount.peek(); + + // Must resolve into existing but better to be safe. + let _ = T::Currency::resolve_creating(&Self::account_id(), amount); + + Self::deposit_event(RawEvent::Deposit(numeric_amount)); + } +} diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index 121ec59555f0e73497600ef5ff653db443163202..f29dbc8cb17ad5aee8821f8888d89f85c2eee910 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Test utilities @@ -22,8 +23,6 @@ use frame_support::{ impl_outer_origin, parameter_types, ord_parameter_types, traits::{OnInitialize, OnFinalize} }; use sp_core::H256; -// The testing primitives are very useful for avoiding having to work with signatures -// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ Perbill, testing::Header, @@ -35,9 +34,6 @@ impl_outer_origin! { pub enum Origin for Test {} } -// For testing the pallet, we construct most of a mock runtime. This means -// first constructing a configuration type (`Test`) which `impl`s each of the -// configuration traits of pallets we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -64,6 +60,7 @@ ord_parameter_types! { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -79,6 +76,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -86,6 +84,7 @@ impl frame_system::Trait for Test { type OnNewAccount = (); type OnKilledAccount = (); type AccountData = pallet_balances::AccountData; + type SystemWeightInfo = (); } impl pallet_balances::Trait for Test { @@ -94,6 +93,7 @@ impl pallet_balances::Trait for Test { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } impl Trait for Test { diff --git a/frame/society/src/tests.rs b/frame/society/src/tests.rs index 8b10dc32e7ba0de12199d35ce580e77319090d26..0374c7bcd7a6079d1b7960a5f87fef0e89d17547 100644 --- a/frame/society/src/tests.rs +++ b/frame/society/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for the module. @@ -812,7 +813,7 @@ fn max_limits_work() { // No candidates because full assert_eq!(Society::candidates().len(), 0); // Increase member limit - assert_ok!(Society::set_max_members(Origin::ROOT, 200)); + assert_ok!(Society::set_max_members(Origin::root(), 200)); // Rotate period run_to_block(16); // Candidates are back! diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 3ee07b5dec80d7b271e87aadbf933bd6f8d6bc5f..2d1487afb03dfd8d6ebc07bb56b26a929c5a4d8e 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-staking" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet staking" @@ -12,55 +12,44 @@ description = "FRAME pallet staking" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-phragmen = { version = "2.0.0-dev", default-features = false, path = "../../primitives/phragmen" } -sp-io ={ version = "2.0.0-dev", path = "../../primitives/io", default-features = false } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -pallet-session = { version = "2.0.0-dev", features = ["historical"], path = "../session", default-features = false } -pallet-authorship = { version = "2.0.0-dev", default-features = false, path = "../authorship" } -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } static_assertions = "1.1.0" - -# Optional imports for tesing-utils feature -pallet-indices = { version = "2.0.0-dev", optional = true, path = "../indices", default-features = false } -sp-core = { version = "2.0.0-dev", optional = true, path = "../../primitives/core", default-features = false } -rand = { version = "0.7.3", optional = true, default-features = false } +serde = { version = "1.0.101", optional = true } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-npos-elections = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/npos-elections" } +sp-io ={ version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-staking = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/staking" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-rc6", default-features = false, features = ["historical"], path = "../session" } +pallet-authorship = { version = "2.0.0-rc6", default-features = false, path = "../authorship" } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/application-crypto" } # Optional imports for benchmarking -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } rand_chacha = { version = "0.2", default-features = false, optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } -pallet-timestamp = { version = "2.0.0-dev", path = "../timestamp" } -pallet-staking-reward-curve = { version = "2.0.0-dev", path = "../staking/reward-curve" } -substrate-test-utils = { version = "2.0.0-dev", path = "../../test-utils" } -frame-benchmarking = { version = "2.0.0-dev", path = "../benchmarking" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-storage = { version = "2.0.0-rc6", path = "../../primitives/storage" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +pallet-timestamp = { version = "2.0.0-rc6", path = "../timestamp" } +pallet-staking-reward-curve = { version = "2.0.0-rc6", path = "../staking/reward-curve" } +substrate-test-utils = { version = "2.0.0-rc6", path = "../../test-utils" } +frame-benchmarking = { version = "2.0.0-rc6", path = "../benchmarking" } rand_chacha = { version = "0.2" } parking_lot = "0.10.2" env_logger = "0.7.1" hex = "0.4" [features] -testing-utils = [ - "std", - "pallet-indices/std", - "sp-core/std", - "rand/std", -] default = ["std"] std = [ "serde", "codec/std", "sp-std/std", - "sp-phragmen/std", + "sp-npos-elections/std", "sp-io/std", "frame-support/std", "sp-runtime/std", @@ -69,9 +58,8 @@ std = [ "frame-system/std", "pallet-authorship/std", "sp-application-crypto/std", - "sp-core/std", ] runtime-benchmarks = [ - "rand_chacha", "frame-benchmarking", + "rand_chacha", ] diff --git a/frame/staking/README.md b/frame/staking/README.md new file mode 100644 index 0000000000000000000000000000000000000000..02db98ab7f0c2d4d3a8591cb98ca7d334e66f0f5 --- /dev/null +++ b/frame/staking/README.md @@ -0,0 +1,249 @@ +# Staking Module + +The Staking module is used to manage funds at stake by network maintainers. + +- [`staking::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) +- [`Module`](./struct.Module.html) + +## Overview + +The Staking module is the means by which a set of network maintainers (known as _authorities_ in +some contexts and _validators_ in others) are chosen based upon those who voluntarily place +funds under deposit. Under deposit, those funds are rewarded under normal operation but are held +at pain of _slash_ (expropriation) should the staked maintainer be found not to be discharging +its duties properly. + +### Terminology + + +- Staking: The process of locking up funds for some time, placing them at risk of slashing + (loss) in order to become a rewarded maintainer of the network. +- Validating: The process of running a node to actively maintain the network, either by + producing blocks or guaranteeing finality of the chain. +- Nominating: The process of placing staked funds behind one or more validators in order to + share in any reward, and punishment, they take. +- Stash account: The account holding an owner's funds used for staking. +- Controller account: The account that controls an owner's funds for staking. +- Era: A (whole) number of sessions, which is the period that the validator set (and each + validator's active nominator set) is recalculated and where rewards are paid out. +- Slash: The punishment of a staker by reducing its funds. + +### Goals + + +The staking system in Substrate NPoS is designed to make the following possible: + +- Stake funds that are controlled by a cold wallet. +- Withdraw some, or deposit more, funds without interrupting the role of an entity. +- Switch between roles (nominator, validator, idle) with minimal overhead. + +### Scenarios + +#### Staking + +Almost any interaction with the Staking module requires a process of _**bonding**_ (also known +as being a _staker_). To become *bonded*, a fund-holding account known as the _stash account_, +which holds some or all of the funds that become frozen in place as part of the staking process, +is paired with an active **controller** account, which issues instructions on how they shall be +used. + +An account pair can become bonded using the [`bond`](./enum.Call.html#variant.bond) call. + +Stash accounts can change their associated controller using the +[`set_controller`](./enum.Call.html#variant.set_controller) call. + +There are three possible roles that any staked account pair can be in: `Validator`, `Nominator` +and `Idle` (defined in [`StakerStatus`](./enum.StakerStatus.html)). There are three +corresponding instructions to change between roles, namely: +[`validate`](./enum.Call.html#variant.validate), +[`nominate`](./enum.Call.html#variant.nominate), and [`chill`](./enum.Call.html#variant.chill). + +#### Validating + +A **validator** takes the role of either validating blocks or ensuring their finality, +maintaining the veracity of the network. A validator should avoid both any sort of malicious +misbehavior and going offline. Bonded accounts that state interest in being a validator do NOT +get immediately chosen as a validator. Instead, they are declared as a _candidate_ and they +_might_ get elected at the _next era_ as a validator. The result of the election is determined +by nominators and their votes. + +An account can become a validator candidate via the +[`validate`](./enum.Call.html#variant.validate) call. + +#### Nomination + +A **nominator** does not take any _direct_ role in maintaining the network, instead, it votes on +a set of validators to be elected. Once interest in nomination is stated by an account, it +takes effect at the next election round. The funds in the nominator's stash account indicate the +_weight_ of its vote. Both the rewards and any punishment that a validator earns are shared +between the validator and its nominators. This rule incentivizes the nominators to NOT vote for +the misbehaving/offline validators as much as possible, simply because the nominators will also +lose funds if they vote poorly. + +An account can become a nominator via the [`nominate`](enum.Call.html#variant.nominate) call. + +#### Rewards and Slash + +The **reward and slashing** procedure is the core of the Staking module, attempting to _embrace +valid behavior_ while _punishing any misbehavior or lack of availability_. + +Rewards must be claimed for each era before it gets too old by `$HISTORY_DEPTH` using the +`payout_stakers` call. Any account can call `payout_stakers`, which pays the reward to the +validator as well as its nominators. Only the [`Trait::MaxNominatorRewardedPerValidator`] +biggest stakers can claim their reward. This is to limit the i/o cost to mutate storage for each +nominator's account. + +Slashing can occur at any point in time, once misbehavior is reported. Once slashing is +determined, a value is deducted from the balance of the validator and all the nominators who +voted for this validator (values are deducted from the _stash_ account of the slashed entity). + +Slashing logic is further described in the documentation of the `slashing` module. + +Similar to slashing, rewards are also shared among a validator and its associated nominators. +Yet, the reward funds are not always transferred to the stash account and can be configured. See +[Reward Calculation](#reward-calculation) for more details. + +#### Chilling + +Finally, any of the roles above can choose to step back temporarily and just chill for a while. +This means that if they are a nominator, they will not be considered as voters anymore and if +they are validators, they will no longer be a candidate for the next election. + +An account can step back via the [`chill`](enum.Call.html#variant.chill) call. + +### Session managing + +The module implement the trait `SessionManager`. Which is the only API to query new validator +set and allowing these validator set to be rewarded once their era is ended. + +## Interface + +### Dispatchable Functions + +The dispatchable functions of the Staking module enable the steps needed for entities to accept +and change their role, alongside some helper functions to get/set the metadata of the module. + +### Public Functions + +The Staking module contains many public storage items and (im)mutable functions. + +## Usage + +### Example: Rewarding a validator by id. + +```rust +use frame_support::{decl_module, dispatch}; +use frame_system::ensure_signed; +use pallet_staking::{self as staking}; + +pub trait Trait: staking::Trait {} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + /// Reward a validator. + #[weight = 0] + pub fn reward_myself(origin) -> dispatch::DispatchResult { + let reported = ensure_signed(origin)?; + >::reward_by_ids(vec![(reported, 10)]); + Ok(()) + } + } +} +``` + +## Implementation Details + +### Era payout + +The era payout is computed using yearly inflation curve defined at +[`T::RewardCurve`](./trait.Trait.html#associatedtype.RewardCurve) as such: + +```nocompile +staker_payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokens / era_per_year +``` +This payout is used to reward stakers as defined in next section + +```nocompile +remaining_payout = max_yearly_inflation * total_tokens / era_per_year - staker_payout +``` +The remaining reward is send to the configurable end-point +[`T::RewardRemainder`](./trait.Trait.html#associatedtype.RewardRemainder). + +### Reward Calculation + +Validators and nominators are rewarded at the end of each era. The total reward of an era is +calculated using the era duration and the staking rate (the total amount of tokens staked by +nominators and validators, divided by the total token supply). It aims to incentivize toward a +defined staking rate. The full specification can be found +[here](https://research.web3.foundation/en/latest/polkadot/Token%20Economics.html#inflation-model). + +Total reward is split among validators and their nominators depending on the number of points +they received during the era. Points are added to a validator using +[`reward_by_ids`](./enum.Call.html#variant.reward_by_ids) or +[`reward_by_indices`](./enum.Call.html#variant.reward_by_indices). + +[`Module`](./struct.Module.html) implements +[`pallet_authorship::EventHandler`](../pallet_authorship/trait.EventHandler.html) to add reward +points to block producer and block producer of referenced uncles. + +The validator and its nominator split their reward as following: + +The validator can declare an amount, named +[`commission`](./struct.ValidatorPrefs.html#structfield.commission), that does not get shared +with the nominators at each reward payout through its +[`ValidatorPrefs`](./struct.ValidatorPrefs.html). This value gets deducted from the total reward +that is paid to the validator and its nominators. The remaining portion is split among the +validator and all of the nominators that nominated the validator, proportional to the value +staked behind this validator (_i.e._ dividing the +[`own`](./struct.Exposure.html#structfield.own) or +[`others`](./struct.Exposure.html#structfield.others) by +[`total`](./struct.Exposure.html#structfield.total) in [`Exposure`](./struct.Exposure.html)). + +All entities who receive a reward have the option to choose their reward destination through the +[`Payee`](./struct.Payee.html) storage item (see +[`set_payee`](enum.Call.html#variant.set_payee)), to be one of the following: + +- Controller account, (obviously) not increasing the staked value. +- Stash account, not increasing the staked value. +- Stash account, also increasing the staked value. + +### Additional Fund Management Operations + +Any funds already placed into stash can be the target of the following operations: + +The controller account can free a portion (or all) of the funds using the +[`unbond`](enum.Call.html#variant.unbond) call. Note that the funds are not immediately +accessible. Instead, a duration denoted by [`BondingDuration`](./struct.BondingDuration.html) +(in number of eras) must pass until the funds can actually be removed. Once the +`BondingDuration` is over, the [`withdraw_unbonded`](./enum.Call.html#variant.withdraw_unbonded) +call can be used to actually withdraw the funds. + +Note that there is a limitation to the number of fund-chunks that can be scheduled to be +unlocked in the future via [`unbond`](enum.Call.html#variant.unbond). In case this maximum +(`MAX_UNLOCKING_CHUNKS`) is reached, the bonded account _must_ first wait until a successful +call to `withdraw_unbonded` to remove some of the chunks. + +### Election Algorithm + +The current election algorithm is implemented based on Phragmén. The reference implementation +can be found [here](https://github.com/w3f/consensus/tree/master/NPoS). + +The election algorithm, aside from electing the validators with the most stake value and votes, +tries to divide the nominator votes among candidates in an equal manner. To further assure this, +an optional post-processing can be applied that iteratively normalizes the nominator staked +values until the total difference among votes of a particular nominator are less than a +threshold. + +## GenesisConfig + +The Staking module depends on the [`GenesisConfig`](./struct.GenesisConfig.html). The +`GenesisConfig` is optional and allow to set some initial stakers. + +## Related Modules + +- [Balances](../pallet_balances/index.html): Used to manage values at stake. +- [Session](../pallet_session/index.html): Used to manage sessions. Also, a list of new + validators is stored in the Session module's `Validators` at the end of each era. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/staking/fuzzer/Cargo.lock b/frame/staking/fuzzer/Cargo.lock index a45f33fdce2492109446030c1a082e7cc32f2f19..e451e12d101310d0ec36d08f0105b8fbd496cc64 100644 --- a/frame/staking/fuzzer/Cargo.lock +++ b/frame/staking/fuzzer/Cargo.lock @@ -1003,7 +1003,7 @@ dependencies = [ "sp-application-crypto", "sp-core", "sp-io", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-staking", "sp-std", @@ -1027,7 +1027,7 @@ dependencies = [ "rand 0.7.3", "sp-core", "sp-io", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-std", ] @@ -1751,19 +1751,19 @@ dependencies = [ ] [[package]] -name = "sp-phragmen" +name = "sp-npos-elections" version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "serde", - "sp-phragmen-compact", + "sp-npos-elections-compact", "sp-runtime", "sp-std", ] [[package]] -name = "sp-phragmen-compact" -version = "2.0.0-dev" +name = "sp-npos-elections-compact" +version = "2.0.0-rc3" dependencies = [ "proc-macro-crate", "proc-macro2", diff --git a/frame/staking/fuzzer/Cargo.toml b/frame/staking/fuzzer/Cargo.toml index 812e5b2fc1de9ac82f9e71448fe0d2b09f41b8a8..ee3e8928676918ee94db7a9b0faea14f8bd98410 100644 --- a/frame/staking/fuzzer/Cargo.toml +++ b/frame/staking/fuzzer/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.0" authors = ["Automatically generated"] publish = false edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet staking fuzzing" @@ -14,20 +14,20 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] honggfuzz = "0.5" -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -pallet-staking = { version = "2.0.0-dev", path = "..", features = ["testing-utils"] } -pallet-staking-reward-curve = { version = "2.0.0-dev", path = "../reward-curve" } -pallet-session = { version = "2.0.0-dev", path = "../../session" } -pallet-indices = { version = "2.0.0-dev", path = "../../indices" } -pallet-balances = { version = "2.0.0-dev", path = "../../balances" } -pallet-timestamp = { version = "2.0.0-dev", path = "../../timestamp" } -frame-system = { version = "2.0.0-dev", path = "../../system" } -frame-support = { version = "2.0.0-dev", path = "../../support" } -sp-std = { version = "2.0.0-dev", path = "../../../primitives/std" } -sp-io ={ version = "2.0.0-dev", path = "../../../primitives/io" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-phragmen = { version = "2.0.0-dev", path = "../../../primitives/phragmen" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +pallet-staking = { version = "2.0.0-rc6", path = "..", features = ["runtime-benchmarks"] } +pallet-staking-reward-curve = { version = "2.0.0-rc6", path = "../reward-curve" } +pallet-session = { version = "2.0.0-rc6", path = "../../session" } +pallet-indices = { version = "2.0.0-rc6", path = "../../indices" } +pallet-balances = { version = "2.0.0-rc6", path = "../../balances" } +pallet-timestamp = { version = "2.0.0-rc6", path = "../../timestamp" } +frame-system = { version = "2.0.0-rc6", path = "../../system" } +frame-support = { version = "2.0.0-rc6", path = "../../support" } +sp-std = { version = "2.0.0-rc6", path = "../../../primitives/std" } +sp-io ={ version = "2.0.0-rc6", path = "../../../primitives/io" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-npos-elections = { version = "2.0.0-rc6", path = "../../../primitives/npos-elections" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } [[bin]] name = "submit_solution" diff --git a/frame/staking/fuzzer/src/mock.rs b/frame/staking/fuzzer/src/mock.rs index 1819970e6061e62ef54537887bcbc50efca1d260..1f5b29b56b6b60d58e4b9b0703011472b22cf666 100644 --- a/frame/staking/fuzzer/src/mock.rs +++ b/frame/staking/fuzzer/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Mock file for staking fuzzing. @@ -31,7 +32,7 @@ pub type Indices = pallet_indices::Module; pub type Session = pallet_session::Module; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } impl_outer_dispatch! { @@ -56,10 +57,12 @@ impl Convert for CurrencyToVoteHandler { pub struct Test; impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = (); type Index = AccountIndex; type BlockNumber = BlockNumber; type Call = Call; @@ -78,6 +81,7 @@ impl frame_system::Trait for Test { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (Balances,); + type SystemWeightInfo = (); } parameter_types! { pub const ExistentialDeposit: Balance = 10; @@ -88,12 +92,14 @@ impl pallet_balances::Trait for Test { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } impl pallet_indices::Trait for Test { type AccountIndex = AccountIndex; type Event = (); type Currency = Balances; type Deposit = (); + type WeightInfo = (); } parameter_types! { pub const MinimumPeriod: u64 = 5; @@ -102,6 +108,7 @@ impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } impl pallet_session::historical::Trait for Test { type FullIdentification = pallet_staking::Exposure; @@ -139,6 +146,7 @@ impl pallet_session::Trait for Test { type ValidatorId = AccountId; type ValidatorIdOf = pallet_staking::StashOf; type DisabledValidatorsThreshold = (); + type WeightInfo = (); } pallet_staking_reward_curve::build! { const I_NPOS: sp_runtime::curve::PiecewiseLinear<'static> = curve!( @@ -183,6 +191,8 @@ impl pallet_staking::Trait for Test { type ElectionLookahead = (); type Call = Call; type MaxIterations = MaxIterations; + type MinSolutionScoreBump = (); type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type UnsignedPriority = (); + type WeightInfo = (); } diff --git a/frame/staking/fuzzer/src/submit_solution.rs b/frame/staking/fuzzer/src/submit_solution.rs index cc897abac2d78edfa3cac8f354ddc2775daf6c1c..6812a739c4929158d3b1d9986e5fbbe786b9c3f6 100644 --- a/frame/staking/fuzzer/src/submit_solution.rs +++ b/frame/staking/fuzzer/src/submit_solution.rs @@ -1,31 +1,33 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Fuzzing for staking pallet. +//! +//! HFUZZ_RUN_ARGS="-n 8" cargo hfuzz run submit_solution use honggfuzz::fuzz; use mock::Test; -use pallet_staking::testing_utils::{ - USER, get_seq_phragmen_solution, get_weak_solution, setup_chain_stakers, - set_validator_count, signed_account, -}; -use frame_support::{assert_ok, storage::StorageValue}; -use sp_runtime::{traits::Dispatchable, DispatchError}; +use pallet_staking::testing_utils::*; +use frame_support::{assert_ok, storage::StorageValue, traits::UnfilteredDispatchable}; +use frame_system::RawOrigin; +use sp_runtime::DispatchError; use sp_core::offchain::{testing::TestOffchainExt, OffchainExt}; +use pallet_staking::{EraElectionStatus, ElectionStatus, Module as Staking, Call as StakingCall}; mod mock; @@ -42,7 +44,9 @@ enum Mode { } pub fn new_test_ext(iterations: u32) -> sp_io::TestExternalities { - let mut ext: sp_io::TestExternalities = frame_system::GenesisConfig::default().build_storage::().map(Into::into) + let mut ext: sp_io::TestExternalities = frame_system::GenesisConfig::default() + .build_storage::() + .map(Into::into) .expect("Failed to create test externalities."); let (offchain, offchain_state) = TestOffchainExt::new(); @@ -68,96 +72,109 @@ fn main() { loop { fuzz!(|data: (u32, u32, u32, u32, u32)| { let (mut num_validators, mut num_nominators, mut edge_per_voter, mut to_elect, mode_u32) = data; + // always run with 5 iterations. let mut ext = new_test_ext(5); let mode: Mode = unsafe { std::mem::transmute(mode_u32) }; num_validators = to_range(num_validators, 50, 1000); num_nominators = to_range(num_nominators, 50, 2000); edge_per_voter = to_range(edge_per_voter, 1, 16); to_elect = to_range(to_elect, 20, num_validators); + let do_reduce = true; - println!("+++ instance with params {} / {} / {} / {:?}({}) / {}", + println!("+++ instance with params {} / {} / {} / {} / {:?}({})", num_nominators, num_validators, edge_per_voter, + to_elect, mode, mode_u32, - to_elect, ); ext.execute_with(|| { // initial setup - set_validator_count::(to_elect); - pallet_staking::testing_utils::init_active_era(); - setup_chain_stakers::( + init_active_era(); + + assert_ok!(create_validators_with_nominators_for_era::( num_validators, num_nominators, - edge_per_voter, - ); - >::put(pallet_staking::ElectionStatus::Open(1)); + edge_per_voter as usize, + true, + None, + )); + + >::put(ElectionStatus::Open(1)); + assert!(>::create_stakers_snapshot().0); - println!("++ Chain setup done."); + let origin = RawOrigin::Signed(create_funded_user::("fuzzer", 0, 100)); // stuff to submit - let (winners, compact, score) = match mode { + let (winners, compact, score, size) = match mode { Mode::InitialSubmission => { /* No need to setup anything */ get_seq_phragmen_solution::(do_reduce) }, Mode::StrongerSubmission => { - let (winners, compact, score) = get_weak_solution::(false); + let (winners, compact, score, size) = get_weak_solution::(false); println!("Weak on chain score = {:?}", score); assert_ok!( - >::submit_election_solution( - signed_account::(USER), + >::submit_election_solution( + origin.clone().into(), winners, compact, score, - pallet_staking::testing_utils::active_era::(), + current_era::(), + size, ) ); get_seq_phragmen_solution::(do_reduce) }, Mode::WeakerSubmission => { - let (winners, compact, score) = get_seq_phragmen_solution::(do_reduce); + let (winners, compact, score, size) = get_seq_phragmen_solution::(do_reduce); println!("Strong on chain score = {:?}", score); assert_ok!( - >::submit_election_solution( - signed_account::(USER), + >::submit_election_solution( + origin.clone().into(), winners, compact, score, - pallet_staking::testing_utils::active_era::(), + current_era::(), + size, ) ); get_weak_solution::(false) } }; - println!("++ Submission ready. Score = {:?}", score); - // must have chosen correct number of winners. - assert_eq!(winners.len() as u32, >::validator_count()); + assert_eq!(winners.len() as u32, >::validator_count()); // final call and origin - let call = pallet_staking::Call::::submit_election_solution( + let call = StakingCall::::submit_election_solution( winners, compact, score, - pallet_staking::testing_utils::active_era::(), + current_era::(), + size, ); - let caller = signed_account::(USER); // actually submit match mode { Mode::WeakerSubmission => { assert_eq!( - call.dispatch(caller.into()).unwrap_err().error, - DispatchError::Module { index: 0, error: 16, message: Some("PhragmenWeakSubmission") }, + call.dispatch_bypass_filter(origin.into()).unwrap_err().error, + DispatchError::Module { + index: 0, + error: 16, + message: Some("PhragmenWeakSubmission"), + }, ); }, - // NOTE: so exhaustive pattern doesn't work here.. maybe some rust issue? or due to `#[repr(u32)]`? - Mode::InitialSubmission | Mode::StrongerSubmission => assert!(call.dispatch(caller.into()).is_ok()), + // NOTE: so exhaustive pattern doesn't work here.. maybe some rust issue? + // or due to `#[repr(u32)]`? + Mode::InitialSubmission | Mode::StrongerSubmission => { + assert_ok!(call.dispatch_bypass_filter(origin.into())); + } }; }) }); diff --git a/frame/staking/reward-curve/Cargo.toml b/frame/staking/reward-curve/Cargo.toml index b11d1cc0493389473a78e527b14d14ec68a1d765..a3ef91d3bc63d057b503ba7e4ef1f4e42a7da677 100644 --- a/frame/staking/reward-curve/Cargo.toml +++ b/frame/staking/reward-curve/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-staking-reward-curve" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Reward Curve for FRAME staking pallet" @@ -21,4 +21,4 @@ proc-macro2 = "1.0.6" proc-macro-crate = "0.1.4" [dev-dependencies] -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } diff --git a/frame/staking/reward-curve/src/lib.rs b/frame/staking/reward-curve/src/lib.rs index 5a3d88bb537a876e3d89dbad715ba11523c5b983..275669fe26b3b4f1ddcf839d4906aa07dfad66f3 100644 --- a/frame/staking/reward-curve/src/lib.rs +++ b/frame/staking/reward-curve/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Proc macro to generate the reward curve functions and tests. @@ -28,7 +29,7 @@ use syn::parse::{Parse, ParseStream}; /// Accepts a number of expressions to create a instance of PiecewiseLinear which represents the /// NPoS curve (as detailed -/// [here](http://research.web3.foundation/en/latest/polkadot/Token%20Economics/#inflation-model)) +/// [here](https://research.web3.foundation/en/latest/polkadot/Token%20Economics.html#inflation-model)) /// for those parameters. Parameters are: /// - `min_inflation`: the minimal amount to be rewarded between validators, expressed as a fraction /// of total issuance. Known as `I_0` in the literature. diff --git a/frame/staking/reward-curve/tests/test.rs b/frame/staking/reward-curve/tests/test.rs index 89f8653fe18d937881a2b6f916c2bca26918716c..45ad59e00ad279f9c4db932370183fdeb336ef1c 100644 --- a/frame/staking/reward-curve/tests/test.rs +++ b/frame/staking/reward-curve/tests/test.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Test crate for pallet-staking-reward-curve. Allows to test for procedural macro. //! See tests directory. diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 2686623aa1eae85655beaf9a917679d1e483319f..77eecb2ef04d5b9ee44d4c0a20009bee4f4f0f64 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -1,116 +1,65 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Staking pallet benchmarking. use super::*; - -use rand_chacha::{rand_core::{RngCore, SeedableRng}, ChaChaRng}; - -use sp_runtime::traits::{Dispatchable, One}; -use sp_io::hashing::blake2_256; - -use frame_system::RawOrigin; -use frame_benchmarking::{benchmarks, account}; - use crate::Module as Staking; -use frame_system::Module as System; +use testing_utils::*; +use sp_runtime::traits::One; +use frame_system::RawOrigin; +pub use frame_benchmarking::{benchmarks, account, whitelisted_caller}; const SEED: u32 = 0; - -fn create_funded_user(string: &'static str, n: u32) -> T::AccountId { - let user = account(string, n, SEED); - let balance = T::Currency::minimum_balance() * 100.into(); - T::Currency::make_free_balance_be(&user, balance); - user -} - -pub fn create_stash_controller(n: u32) -> Result<(T::AccountId, T::AccountId), &'static str> { - let stash = create_funded_user::("stash", n); - let controller = create_funded_user::("controller", n); - let controller_lookup: ::Source = T::Lookup::unlookup(controller.clone()); - let reward_destination = RewardDestination::Staked; - let amount = T::Currency::minimum_balance() * 10.into(); - Staking::::bond(RawOrigin::Signed(stash.clone()).into(), controller_lookup, amount, reward_destination)?; - return Ok((stash, controller)) -} - -fn create_validators(max: u32) -> Result::Source>, &'static str> { - let mut validators: Vec<::Source> = Vec::with_capacity(max as usize); - for i in 0 .. max { - let (stash, controller) = create_stash_controller::(i)?; - let validator_prefs = ValidatorPrefs { - commission: Perbill::from_percent(50), - }; - Staking::::validate(RawOrigin::Signed(controller).into(), validator_prefs)?; - let stash_lookup: ::Source = T::Lookup::unlookup(stash); - validators.push(stash_lookup); +const MAX_SPANS: u32 = 100; +const MAX_VALIDATORS: u32 = 1000; +const MAX_SLASHES: u32 = 1000; + +// Add slashing spans to a user account. Not relevant for actual use, only to benchmark +// read and write operations. +fn add_slashing_spans(who: &T::AccountId, spans: u32) { + if spans == 0 { return } + + // For the first slashing span, we initialize + let mut slashing_spans = crate::slashing::SlashingSpans::new(0); + SpanSlash::::insert((who, 0), crate::slashing::SpanRecord::default()); + + for i in 1 .. spans { + assert!(slashing_spans.end_span(i)); + SpanSlash::::insert((who, i), crate::slashing::SpanRecord::default()); } - Ok(validators) + SlashingSpans::::insert(who, slashing_spans); } -// This function generates v validators and n nominators who are randomly nominating up to MAX_NOMINATIONS. -pub fn create_validators_with_nominators_for_era(v: u32, n: u32) -> Result<(), &'static str> { - let mut validators: Vec<::Source> = Vec::with_capacity(v as usize); - let mut rng = ChaChaRng::from_seed(SEED.using_encoded(blake2_256)); - - // Create v validators - for i in 0 .. v { - let (v_stash, v_controller) = create_stash_controller::(i)?; - let validator_prefs = ValidatorPrefs { - commission: Perbill::from_percent(50), - }; - Staking::::validate(RawOrigin::Signed(v_controller.clone()).into(), validator_prefs)?; - let stash_lookup: ::Source = T::Lookup::unlookup(v_stash.clone()); - validators.push(stash_lookup.clone()); - } - - // Create n nominators - for j in 0 .. n { - let (_n_stash, n_controller) = create_stash_controller::(u32::max_value() - j)?; - - // Have them randomly validate - let mut available_validators = validators.clone(); - let mut selected_validators: Vec<::Source> = Vec::with_capacity(MAX_NOMINATIONS); - for _ in 0 .. v.min(MAX_NOMINATIONS as u32) { - let selected = rng.next_u32() as usize % available_validators.len(); - let validator = available_validators.remove(selected); - selected_validators.push(validator); - } - Staking::::nominate(RawOrigin::Signed(n_controller.clone()).into(), selected_validators)?; - } - - ValidatorCount::put(v); - - Ok(()) -} - -// This function generates one validator being nominated by n nominators, and returns -//the validator stash account. It also starts an era and creates pending payouts. -pub fn create_validator_with_nominators(n: u32, upper_bound: u32) -> Result { +// This function generates one validator being nominated by n nominators, and returns the validator +// stash account. It also starts an era and creates pending payouts. +pub fn create_validator_with_nominators( + n: u32, + upper_bound: u32, + dead: bool, +) -> Result { let mut points_total = 0; let mut points_individual = Vec::new(); - MinimumValidatorCount::put(0); - - let (v_stash, v_controller) = create_stash_controller::(0)?; + let (v_stash, v_controller) = create_stash_controller::(0, 100)?; let validator_prefs = ValidatorPrefs { commission: Perbill::from_percent(50), }; - Staking::::validate(RawOrigin::Signed(v_controller.clone()).into(), validator_prefs)?; + Staking::::validate(RawOrigin::Signed(v_controller).into(), validator_prefs)?; let stash_lookup: ::Source = T::Lookup::unlookup(v_stash.clone()); points_total += 10; @@ -118,7 +67,11 @@ pub fn create_validator_with_nominators(n: u32, upper_bound: u32) -> R // Give the validator n nominators, but keep total users in the system the same. for i in 0 .. upper_bound { - let (_n_stash, n_controller) = create_stash_controller::(u32::max_value() - i)?; + let (_n_stash, n_controller) = if !dead { + create_stash_controller::(u32::max_value() - i, 100)? + } else { + create_stash_and_dead_controller::(u32::max_value() - i, 100)? + }; if i < n { Staking::::nominate(RawOrigin::Signed(n_controller.clone()).into(), vec![stash_lookup.clone()])?; } @@ -155,112 +108,204 @@ benchmarks! { bond { let u in ...; - let stash = create_funded_user::("stash",u); - let controller = create_funded_user::("controller", u); - let controller_lookup: ::Source = T::Lookup::unlookup(controller); + let stash = create_funded_user::("stash", u, 100); + let controller = create_funded_user::("controller", u, 100); + let controller_lookup: ::Source = T::Lookup::unlookup(controller.clone()); let reward_destination = RewardDestination::Staked; let amount = T::Currency::minimum_balance() * 10.into(); - }: _(RawOrigin::Signed(stash), controller_lookup, amount, reward_destination) + }: _(RawOrigin::Signed(stash.clone()), controller_lookup, amount, reward_destination) + verify { + assert!(Bonded::::contains_key(stash)); + assert!(Ledger::::contains_key(controller)); + } bond_extra { let u in ...; - let (stash, _) = create_stash_controller::(u)?; + let (stash, controller) = create_stash_controller::(u, 100)?; let max_additional = T::Currency::minimum_balance() * 10.into(); + let ledger = Ledger::::get(&controller).ok_or("ledger not created before")?; + let original_bonded: BalanceOf = ledger.active; }: _(RawOrigin::Signed(stash), max_additional) + verify { + let ledger = Ledger::::get(&controller).ok_or("ledger not created after")?; + let new_bonded: BalanceOf = ledger.active; + assert!(original_bonded < new_bonded); + } unbond { let u in ...; - let (_, controller) = create_stash_controller::(u)?; + let (_, controller) = create_stash_controller::(u, 100)?; let amount = T::Currency::minimum_balance() * 10.into(); - }: _(RawOrigin::Signed(controller), amount) + let ledger = Ledger::::get(&controller).ok_or("ledger not created before")?; + let original_bonded: BalanceOf = ledger.active; + }: _(RawOrigin::Signed(controller.clone()), amount) + verify { + let ledger = Ledger::::get(&controller).ok_or("ledger not created after")?; + let new_bonded: BalanceOf = ledger.active; + assert!(original_bonded > new_bonded); + } + + // Withdraw only updates the ledger + withdraw_unbonded_update { + // Slashing Spans + let s in 0 .. MAX_SPANS; + let (stash, controller) = create_stash_controller::(0, 100)?; + add_slashing_spans::(&stash, s); + let amount = T::Currency::minimum_balance() * 5.into(); // Half of total + Staking::::unbond(RawOrigin::Signed(controller.clone()).into(), amount)?; + CurrentEra::put(EraIndex::max_value()); + let ledger = Ledger::::get(&controller).ok_or("ledger not created before")?; + let original_total: BalanceOf = ledger.total; + }: withdraw_unbonded(RawOrigin::Signed(controller.clone()), s) + verify { + let ledger = Ledger::::get(&controller).ok_or("ledger not created after")?; + let new_total: BalanceOf = ledger.total; + assert!(original_total > new_total); + } // Worst case scenario, everything is removed after the bonding duration - withdraw_unbonded { - let u in ...; - let (stash, controller) = create_stash_controller::(u)?; + withdraw_unbonded_kill { + // Slashing Spans + let s in 0 .. MAX_SPANS; + let (stash, controller) = create_stash_controller::(0, 100)?; + add_slashing_spans::(&stash, s); let amount = T::Currency::minimum_balance() * 10.into(); Staking::::unbond(RawOrigin::Signed(controller.clone()).into(), amount)?; - let current_block = System::::block_number(); - // let unbond_block = current_block + T::BondingDuration::get().into() + 10.into(); - // System::::set_block_number(unbond_block); - }: _(RawOrigin::Signed(controller)) + CurrentEra::put(EraIndex::max_value()); + let ledger = Ledger::::get(&controller).ok_or("ledger not created before")?; + let original_total: BalanceOf = ledger.total; + }: withdraw_unbonded(RawOrigin::Signed(controller.clone()), s) + verify { + assert!(!Ledger::::contains_key(controller)); + } validate { let u in ...; - let (_, controller) = create_stash_controller::(u)?; + let (stash, controller) = create_stash_controller::(u, 100)?; let prefs = ValidatorPrefs::default(); }: _(RawOrigin::Signed(controller), prefs) + verify { + assert!(Validators::::contains_key(stash)); + } // Worst case scenario, MAX_NOMINATIONS nominate { let n in 1 .. MAX_NOMINATIONS as u32; - let (_, controller) = create_stash_controller::(n + 1)?; - let validators = create_validators::(n)?; + let (stash, controller) = create_stash_controller::(n + 1, 100)?; + let validators = create_validators::(n, 100)?; }: _(RawOrigin::Signed(controller), validators) + verify { + assert!(Nominators::::contains_key(stash)); + } chill { let u in ...; - let (_, controller) = create_stash_controller::(u)?; + let (_, controller) = create_stash_controller::(u, 100)?; }: _(RawOrigin::Signed(controller)) set_payee { let u in ...; - let (_, controller) = create_stash_controller::(u)?; + let (stash, controller) = create_stash_controller::(u, 100)?; + assert_eq!(Payee::::get(&stash), RewardDestination::Staked); }: _(RawOrigin::Signed(controller), RewardDestination::Controller) + verify { + assert_eq!(Payee::::get(&stash), RewardDestination::Controller); + } set_controller { let u in ...; - let (stash, _) = create_stash_controller::(u)?; - let new_controller = create_funded_user::("new_controller", u); - let new_controller_lookup = T::Lookup::unlookup(new_controller); + let (stash, _) = create_stash_controller::(u, 100)?; + let new_controller = create_funded_user::("new_controller", u, 100); + let new_controller_lookup = T::Lookup::unlookup(new_controller.clone()); }: _(RawOrigin::Signed(stash), new_controller_lookup) + verify { + assert!(Ledger::::contains_key(&new_controller)); + } set_validator_count { - let c in 0 .. 1000; + let c in 0 .. MAX_VALIDATORS; }: _(RawOrigin::Root, c) + verify { + assert_eq!(ValidatorCount::get(), c); + } force_no_eras { let i in 0 .. 1; }: _(RawOrigin::Root) + verify { assert_eq!(ForceEra::get(), Forcing::ForceNone); } force_new_era {let i in 0 .. 1; }: _(RawOrigin::Root) + verify { assert_eq!(ForceEra::get(), Forcing::ForceNew); } force_new_era_always { let i in 0 .. 1; }: _(RawOrigin::Root) + verify { assert_eq!(ForceEra::get(), Forcing::ForceAlways); } // Worst case scenario, the list of invulnerables is very long. set_invulnerables { - let v in 0 .. 1000; + let v in 0 .. MAX_VALIDATORS; let mut invulnerables = Vec::new(); for i in 0 .. v { invulnerables.push(account("invulnerable", i, SEED)); } }: _(RawOrigin::Root, invulnerables) + verify { + assert_eq!(Invulnerables::::get().len(), v as usize); + } force_unstake { - let u in ...; - let (stash, _) = create_stash_controller::(u)?; - }: _(RawOrigin::Root, stash) + // Slashing Spans + let s in 0 .. MAX_SPANS; + let (stash, controller) = create_stash_controller::(0, 100)?; + add_slashing_spans::(&stash, s); + }: _(RawOrigin::Root, stash, s) + verify { + assert!(!Ledger::::contains_key(&controller)); + } cancel_deferred_slash { - let s in 1 .. 1000; + let s in 1 .. MAX_SLASHES; let mut unapplied_slashes = Vec::new(); let era = EraIndex::one(); - for _ in 0 .. 1000 { + for _ in 0 .. MAX_SLASHES { unapplied_slashes.push(UnappliedSlash::>::default()); } UnappliedSlashes::::insert(era, &unapplied_slashes); let slash_indices: Vec = (0 .. s).collect(); }: _(RawOrigin::Root, era, slash_indices) + verify { + assert_eq!(UnappliedSlashes::::get(&era).len(), (MAX_SLASHES - s) as usize); + } payout_stakers { - let n in 1 .. MAX_NOMINATIONS as u32; - let validator = create_validator_with_nominators::(n, MAX_NOMINATIONS as u32)?; + let n in 1 .. T::MaxNominatorRewardedPerValidator::get() as u32; + let validator = create_validator_with_nominators::(n, T::MaxNominatorRewardedPerValidator::get() as u32, true)?; + let current_era = CurrentEra::get().unwrap(); - let caller = account("caller", n, SEED); - }: _(RawOrigin::Signed(caller), validator, current_era) + let caller = whitelisted_caller(); + let balance_before = T::Currency::free_balance(&validator); + }: _(RawOrigin::Signed(caller), validator.clone(), current_era) + verify { + // Validator has been paid! + let balance_after = T::Currency::free_balance(&validator); + assert!(balance_before < balance_after); + } + + payout_stakers_alive_controller { + let n in 1 .. T::MaxNominatorRewardedPerValidator::get() as u32; + let validator = create_validator_with_nominators::(n, T::MaxNominatorRewardedPerValidator::get() as u32, false)?; + + let current_era = CurrentEra::get().unwrap(); + let caller = whitelisted_caller(); + let balance_before = T::Currency::free_balance(&validator); + }: payout_stakers(RawOrigin::Signed(caller), validator.clone(), current_era) + verify { + // Validator has been paid! + let balance_after = T::Currency::free_balance(&validator); + assert!(balance_before < balance_after); + } rebond { - let l in 1 .. 1000; - let (_, controller) = create_stash_controller::(u)?; + let l in 1 .. MAX_UNLOCKING_CHUNKS as u32; + let (_, controller) = create_stash_controller::(u, 100)?; let mut staking_ledger = Ledger::::get(controller.clone()).unwrap(); let unlock_chunk = UnlockChunk::> { value: 1.into(), @@ -269,8 +314,14 @@ benchmarks! { for _ in 0 .. l { staking_ledger.unlocking.push(unlock_chunk.clone()) } - Ledger::::insert(controller.clone(), staking_ledger); - }: _(RawOrigin::Signed(controller), (l + 100).into()) + Ledger::::insert(controller.clone(), staking_ledger.clone()); + let original_bonded: BalanceOf = staking_ledger.active; + }: _(RawOrigin::Signed(controller.clone()), (l + 100).into()) + verify { + let ledger = Ledger::::get(&controller).ok_or("ledger not created after")?; + let new_bonded: BalanceOf = ledger.active; + assert!(original_bonded < new_bonded); + } set_history_depth { let e in 1 .. 100; @@ -285,19 +336,26 @@ benchmarks! { >::insert(i, BalanceOf::::one()); ErasStartSessionIndex::insert(i, i); } - }: _(RawOrigin::Root, EraIndex::zero()) + }: _(RawOrigin::Root, EraIndex::zero(), u32::max_value()) + verify { + assert_eq!(HistoryDepth::get(), 0); + } reap_stash { - let u in 1 .. 1000; - let (stash, controller) = create_stash_controller::(u)?; + let s in 1 .. MAX_SPANS; + let (stash, controller) = create_stash_controller::(0, 100)?; + add_slashing_spans::(&stash, s); T::Currency::make_free_balance_be(&stash, 0.into()); - }: _(RawOrigin::Signed(controller), stash) + }: _(RawOrigin::Signed(controller), stash.clone(), s) + verify { + assert!(!Bonded::::contains_key(&stash)); + } new_era { let v in 1 .. 10; let n in 1 .. 100; - MinimumValidatorCount::put(0); - create_validators_with_nominators_for_era::(v, n)?; + + create_validators_with_nominators_for_era::(v, n, MAX_NOMINATIONS, false, None)?; let session_index = SessionIndex::one(); }: { let validators = Staking::::new_era(session_index).ok_or("`new_era` failed")?; @@ -305,8 +363,8 @@ benchmarks! { } do_slash { - let l in 1 .. 1000; - let (stash, controller) = create_stash_controller::(0)?; + let l in 1 .. MAX_UNLOCKING_CHUNKS as u32; + let (stash, controller) = create_stash_controller::(0, 100)?; let mut staking_ledger = Ledger::::get(controller.clone()).unwrap(); let unlock_chunk = UnlockChunk::> { value: 1.into(), @@ -315,8 +373,9 @@ benchmarks! { for _ in 0 .. l { staking_ledger.unlocking.push(unlock_chunk.clone()) } - Ledger::::insert(controller.clone(), staking_ledger.clone()); + Ledger::::insert(controller, staking_ledger); let slash_amount = T::Currency::minimum_balance() * 10.into(); + let balance_before = T::Currency::free_balance(&stash); }: { crate::slashing::do_slash::( &stash, @@ -324,13 +383,15 @@ benchmarks! { &mut BalanceOf::::zero(), &mut NegativeImbalanceOf::::zero() ); + } verify { + let balance_after = T::Currency::free_balance(&stash); + assert!(balance_before > balance_after); } payout_all { let v in 1 .. 10; let n in 1 .. 100; - MinimumValidatorCount::put(0); - create_validators_with_nominators_for_era::(v, n)?; + create_validators_with_nominators_for_era::(v, n, MAX_NOMINATIONS, false, None)?; // Start a new Era let new_validators = Staking::::new_era(SessionIndex::one()).unwrap(); assert!(new_validators.len() == v as usize); @@ -338,12 +399,12 @@ benchmarks! { let current_era = CurrentEra::get().unwrap(); let mut points_total = 0; let mut points_individual = Vec::new(); - let mut payout_calls = Vec::new(); + let mut payout_calls_arg = Vec::new(); for validator in new_validators.iter() { points_total += 10; points_individual.push((validator.clone(), 10)); - payout_calls.push(Call::::payout_stakers(validator.clone(), current_era)) + payout_calls_arg.push((validator.clone(), current_era)); } // Give Era Points @@ -358,11 +419,214 @@ benchmarks! { let total_payout = T::Currency::minimum_balance() * 1000.into(); >::insert(current_era, total_payout); - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); + }: { + for arg in payout_calls_arg { + >::payout_stakers(RawOrigin::Signed(caller.clone()).into(), arg.0, arg.1)?; + } + } + + // This benchmark create `v` validators intent, `n` nominators intent, each nominator nominate + // MAX_NOMINATIONS in the set of the first `w` validators. + // It builds a solution with `w` winners composed of nominated validators randomly nominated, + // `a` assignment with MAX_NOMINATIONS. + submit_solution_initial { + // number of validator intent + let v in 1000 .. 2000; + // number of nominator intent + let n in 1000 .. 2000; + // number of assignments. Basically, number of active nominators. + let a in 200 .. 500; + // number of winners, also ValidatorCount + let w in 16 .. 100; + + ensure!(w as usize >= MAX_NOMINATIONS, "doesn't support lower value"); + + let winners = create_validators_with_nominators_for_era::( + v, + n, + MAX_NOMINATIONS, + false, + Some(w), + )?; + + // needed for the solution to be generates. + assert!(>::create_stakers_snapshot().0); + + // set number of winners + ValidatorCount::put(w); + + // create a assignments in total for the w winners. + let (winners, assignments) = create_assignments_for_offchain::(a, winners)?; + + let ( + winners, + compact, + score, + size + ) = offchain_election::prepare_submission::(assignments, winners, false).unwrap(); + + // needed for the solution to be accepted + >::put(ElectionStatus::Open(T::BlockNumber::from(1u32))); + + let era = >::current_era().unwrap_or(0); + let caller: T::AccountId = account("caller", n, SEED); + + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); }: { - for call in payout_calls { - call.dispatch(RawOrigin::Signed(caller.clone()).into())?; + let result = >::submit_election_solution( + RawOrigin::Signed(caller.clone()).into(), + winners, + compact, + score.clone(), + era, + size, + ); + assert!(result.is_ok()); + } + verify { + // new solution has been accepted. + assert_eq!(>::queued_score().unwrap(), score); + } + + // same as submit_solution_initial but we place a very weak solution on chian first. + submit_solution_better { + // number of validator intent + let v in 1000 .. 2000; + // number of nominator intent + let n in 1000 .. 2000; + // number of assignments. Basically, number of active nominators. + let a in 200 .. 500; + // number of winners, also ValidatorCount + let w in 16 .. 100; + + ensure!(w as usize >= MAX_NOMINATIONS, "doesn't support lower value"); + + let winners = create_validators_with_nominators_for_era::( + v, + n, + MAX_NOMINATIONS, + false, + Some(w), + )?; + + // needed for the solution to be generates. + assert!(>::create_stakers_snapshot().0); + + // set number of winners + ValidatorCount::put(w); + + // create a assignments in total for the w winners. + let (winners, assignments) = create_assignments_for_offchain::(a, winners)?; + + let single_winner = winners[0].0.clone(); + + let ( + winners, + compact, + score, + size + ) = offchain_election::prepare_submission::(assignments, winners, false).unwrap(); + + // needed for the solution to be accepted + >::put(ElectionStatus::Open(T::BlockNumber::from(1u32))); + + let era = >::current_era().unwrap_or(0); + let caller: T::AccountId = account("caller", n, SEED); + + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); + + // submit a very bad solution on-chain + { + // this is needed to fool the chain to accept this solution. + ValidatorCount::put(1); + let (winners, compact, score, size) = get_single_winner_solution::(single_winner)?; + assert!( + >::submit_election_solution( + RawOrigin::Signed(caller.clone()).into(), + winners, + compact, + score.clone(), + era, + size, + ).is_ok()); + + // new solution has been accepted. + assert_eq!(>::queued_score().unwrap(), score); + ValidatorCount::put(w); + } + }: { + let result = >::submit_election_solution( + RawOrigin::Signed(caller.clone()).into(), + winners, + compact, + score.clone(), + era, + size, + ); + assert!(result.is_ok()); + } + verify { + // new solution has been accepted. + assert_eq!(>::queued_score().unwrap(), score); + } + + // This will be early rejected based on the score. + submit_solution_weaker { + // number of validator intent + let v in 1000 .. 2000; + // number of nominator intent + let n in 1000 .. 2000; + + create_validators_with_nominators_for_era::(v, n, MAX_NOMINATIONS, false, None)?; + + // needed for the solution to be generates. + assert!(>::create_stakers_snapshot().0); + + // needed for the solution to be accepted + >::put(ElectionStatus::Open(T::BlockNumber::from(1u32))); + let caller: T::AccountId = account("caller", n, SEED); + let era = >::current_era().unwrap_or(0); + + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); + + // submit a seq-phragmen with all the good stuff on chain. + { + let (winners, compact, score, size) = get_seq_phragmen_solution::(true); + assert!( + >::submit_election_solution( + RawOrigin::Signed(caller.clone()).into(), + winners, + compact, + score.clone(), + era, + size, + ).is_ok() + ); + + // new solution has been accepted. + assert_eq!(>::queued_score().unwrap(), score); } + + // prepare a bad solution. This will be very early rejected. + let (winners, compact, score, size) = get_weak_solution::(true); + }: { + assert!( + >::submit_election_solution( + RawOrigin::Signed(caller.clone()).into(), + winners, + compact, + score.clone(), + era, + size, + ).is_err() + ); } } @@ -378,7 +642,8 @@ mod tests { let v = 10; let n = 100; - create_validators_with_nominators_for_era::(v,n).unwrap(); + create_validators_with_nominators_for_era::(v, n, MAX_NOMINATIONS, false, None) + .unwrap(); let count_validators = Validators::::iter().count(); let count_nominators = Nominators::::iter().count(); @@ -395,7 +660,8 @@ mod tests { let validator_stash = create_validator_with_nominators::( n, - MAX_NOMINATIONS as u32, + ::MaxNominatorRewardedPerValidator::get() as u32, + false, ).unwrap(); let current_era = CurrentEra::get().unwrap(); @@ -408,6 +674,36 @@ mod tests { }); } + #[test] + fn add_slashing_spans_works() { + ExtBuilder::default().has_stakers(false).build().execute_with(|| { + let n = 10; + + let validator_stash = create_validator_with_nominators::( + n, + ::MaxNominatorRewardedPerValidator::get() as u32, + false, + ).unwrap(); + + // Add 20 slashing spans + let num_of_slashing_spans = 20; + add_slashing_spans::(&validator_stash, num_of_slashing_spans); + + let slashing_spans = SlashingSpans::::get(&validator_stash).unwrap(); + assert_eq!(slashing_spans.iter().count(), num_of_slashing_spans as usize); + for i in 0 .. num_of_slashing_spans { + assert!(SpanSlash::::contains_key((&validator_stash, i))); + } + + // Test everything is cleaned up + assert_ok!(Staking::kill_stash(&validator_stash, num_of_slashing_spans)); + assert!(SlashingSpans::::get(&validator_stash).is_none()); + for i in 0 .. num_of_slashing_spans { + assert!(!SpanSlash::::contains_key((&validator_stash, i))); + } + }); + } + #[test] fn test_payout_all() { ExtBuilder::default().has_stakers(false).build().execute_with(|| { @@ -432,7 +728,8 @@ mod tests { assert_ok!(test_benchmark_bond::()); assert_ok!(test_benchmark_bond_extra::()); assert_ok!(test_benchmark_unbond::()); - assert_ok!(test_benchmark_withdraw_unbonded::()); + assert_ok!(test_benchmark_withdraw_unbonded_update::()); + assert_ok!(test_benchmark_withdraw_unbonded_kill::()); assert_ok!(test_benchmark_validate::()); assert_ok!(test_benchmark_nominate::()); assert_ok!(test_benchmark_chill::()); @@ -446,12 +743,25 @@ mod tests { assert_ok!(test_benchmark_force_unstake::()); assert_ok!(test_benchmark_cancel_deferred_slash::()); assert_ok!(test_benchmark_payout_stakers::()); + assert_ok!(test_benchmark_payout_stakers_alive_controller::()); assert_ok!(test_benchmark_rebond::()); assert_ok!(test_benchmark_set_history_depth::()); assert_ok!(test_benchmark_reap_stash::()); assert_ok!(test_benchmark_new_era::()); assert_ok!(test_benchmark_do_slash::()); assert_ok!(test_benchmark_payout_all::()); + // only run one of them to same time on the CI. ignore the other two. + assert_ok!(test_benchmark_submit_solution_initial::()); }); } + + #[test] + #[ignore] + fn test_benchmarks_offchain() { + ExtBuilder::default().has_stakers(false).build().execute_with(|| { + assert_ok!(test_benchmark_submit_solution_better::()); + assert_ok!(test_benchmark_submit_solution_weaker::()); + }); + } + } diff --git a/frame/staking/src/inflation.rs b/frame/staking/src/inflation.rs index 63d008a197c6465b3e937dccf36319842be375d6..2161fe20af8299a5d163f7b17f5ae1a0e7e059d1 100644 --- a/frame/staking/src/inflation.rs +++ b/frame/staking/src/inflation.rs @@ -1,25 +1,26 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! This module expose one function `P_NPoS` (Payout NPoS) or `compute_total_payout` which returns //! the total payout for the era given the era duration and the staking rate in NPoS. //! The staking rate in NPoS is the total amount of tokens staked by nominators and validators, //! divided by the total token supply. -use sp_runtime::{Perbill, traits::AtLeast32Bit, curve::PiecewiseLinear}; +use sp_runtime::{Perbill, traits::AtLeast32BitUnsigned, curve::PiecewiseLinear}; /// The total payout to all validators (and their nominators) per era and maximum payout. /// @@ -33,7 +34,7 @@ pub fn compute_total_payout( npos_token_staked: N, total_tokens: N, era_duration: u64 -) -> (N, N) where N: AtLeast32Bit + Clone { +) -> (N, N) where N: AtLeast32BitUnsigned + Clone { // Milliseconds per year for the Julian year (365.25 days). const MILLISECONDS_PER_YEAR: u64 = 1000 * 3600 * 24 * 36525 / 100; diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 71042d69b3a4d373c03c12cb97dfdcb20d7560b2..8f5b8561eb420b1a0e0877b526a5a4bf4a8ae485 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Staking Module //! @@ -24,25 +25,25 @@ //! //! ## Overview //! -//! The Staking module is the means by which a set of network maintainers (known as _authorities_ -//! in some contexts and _validators_ in others) are chosen based upon those who voluntarily place -//! funds under deposit. Under deposit, those funds are rewarded under normal operation but are -//! held at pain of _slash_ (expropriation) should the staked maintainer be found not to be -//! discharging its duties properly. +//! The Staking module is the means by which a set of network maintainers (known as _authorities_ in +//! some contexts and _validators_ in others) are chosen based upon those who voluntarily place +//! funds under deposit. Under deposit, those funds are rewarded under normal operation but are held +//! at pain of _slash_ (expropriation) should the staked maintainer be found not to be discharging +//! its duties properly. //! //! ### Terminology //! //! //! - Staking: The process of locking up funds for some time, placing them at risk of slashing -//! (loss) in order to become a rewarded maintainer of the network. +//! (loss) in order to become a rewarded maintainer of the network. //! - Validating: The process of running a node to actively maintain the network, either by -//! producing blocks or guaranteeing finality of the chain. +//! producing blocks or guaranteeing finality of the chain. //! - Nominating: The process of placing staked funds behind one or more validators in order to -//! share in any reward, and punishment, they take. +//! share in any reward, and punishment, they take. //! - Stash account: The account holding an owner's funds used for staking. //! - Controller account: The account that controls an owner's funds for staking. //! - Era: A (whole) number of sessions, which is the period that the validator set (and each -//! validator's active nominator set) is recalculated and where rewards are paid out. +//! validator's active nominator set) is recalculated and where rewards are paid out. //! - Slash: The punishment of a staker by reducing its funds. //! //! ### Goals @@ -105,10 +106,10 @@ //! valid behavior_ while _punishing any misbehavior or lack of availability_. //! //! Rewards must be claimed for each era before it gets too old by `$HISTORY_DEPTH` using the -//! `payout_stakers` call. Any account can call `payout_stakers`, which pays the reward to -//! the validator as well as its nominators. -//! Only the [`T::MaxNominatorRewardedPerValidator`] biggest stakers can claim their reward. This -//! is to limit the i/o cost to mutate storage for each nominator's account. +//! `payout_stakers` call. Any account can call `payout_stakers`, which pays the reward to the +//! validator as well as its nominators. Only the [`Trait::MaxNominatorRewardedPerValidator`] +//! biggest stakers can claim their reward. This is to limit the i/o cost to mutate storage for each +//! nominator's account. //! //! Slashing can occur at any point in time, once misbehavior is reported. Once slashing is //! determined, a value is deducted from the balance of the validator and all the nominators who @@ -117,8 +118,8 @@ //! Slashing logic is further described in the documentation of the `slashing` module. //! //! Similar to slashing, rewards are also shared among a validator and its associated nominators. -//! Yet, the reward funds are not always transferred to the stash account and can be configured. -//! See [Reward Calculation](#reward-calculation) for more details. +//! Yet, the reward funds are not always transferred to the stash account and can be configured. See +//! [Reward Calculation](#reward-calculation) for more details. //! //! #### Chilling //! @@ -150,21 +151,21 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; -//! use frame_system::{self as system, ensure_signed}; +//! use frame_system::ensure_signed; //! use pallet_staking::{self as staking}; //! //! pub trait Trait: staking::Trait {} //! //! decl_module! { -//! pub struct Module for enum Call where origin: T::Origin { -//! /// Reward a validator. -//! #[weight = 0] -//! pub fn reward_myself(origin) -> dispatch::DispatchResult { -//! let reported = ensure_signed(origin)?; -//! >::reward_by_ids(vec![(reported, 10)]); -//! Ok(()) -//! } -//! } +//! pub struct Module for enum Call where origin: T::Origin { +//! /// Reward a validator. +//! #[weight = 0] +//! pub fn reward_myself(origin) -> dispatch::DispatchResult { +//! let reported = ensure_signed(origin)?; +//! >::reward_by_ids(vec![(reported, 10)]); +//! Ok(()) +//! } +//! } //! } //! # fn main() { } //! ``` @@ -207,8 +208,8 @@ //! The validator and its nominator split their reward as following: //! //! The validator can declare an amount, named -//! [`commission`](./struct.ValidatorPrefs.html#structfield.commission), that does not -//! get shared with the nominators at each reward payout through its +//! [`commission`](./struct.ValidatorPrefs.html#structfield.commission), that does not get shared +//! with the nominators at each reward payout through its //! [`ValidatorPrefs`](./struct.ValidatorPrefs.html). This value gets deducted from the total reward //! that is paid to the validator and its nominators. The remaining portion is split among the //! validator and all of the nominators that nominated the validator, proportional to the value @@ -217,8 +218,8 @@ //! [`others`](./struct.Exposure.html#structfield.others) by //! [`total`](./struct.Exposure.html#structfield.total) in [`Exposure`](./struct.Exposure.html)). //! -//! All entities who receive a reward have the option to choose their reward destination -//! through the [`Payee`](./struct.Payee.html) storage item (see +//! All entities who receive a reward have the option to choose their reward destination through the +//! [`Payee`](./struct.Payee.html) storage item (see //! [`set_payee`](enum.Call.html#variant.set_payee)), to be one of the following: //! //! - Controller account, (obviously) not increasing the staked value. @@ -243,9 +244,8 @@ //! //! ### Election Algorithm //! -//! The current election algorithm is implemented based on Phragmén. -//! The reference implementation can be found -//! [here](https://github.com/w3f/consensus/tree/master/NPoS). +//! The current election algorithm is implemented based on Phragmén. The reference implementation +//! can be found [here](https://github.com/w3f/consensus/tree/master/NPoS). //! //! The election algorithm, aside from electing the validators with the most stake value and votes, //! tries to divide the nominator votes among candidates in an equal manner. To further assure this, @@ -255,8 +255,8 @@ //! //! ## GenesisConfig //! -//! The Staking module depends on the [`GenesisConfig`](./struct.GenesisConfig.html). -//! The `GenesisConfig` is optional and allow to set some initial stakers. +//! The Staking module depends on the [`GenesisConfig`](./struct.GenesisConfig.html). The +//! `GenesisConfig` is optional and allow to set some initial stakers. //! //! ## Related Modules //! @@ -271,7 +271,7 @@ mod mock; #[cfg(test)] mod tests; -#[cfg(feature = "testing-utils")] +#[cfg(any(feature = "runtime-benchmarks", test))] pub mod testing_utils; #[cfg(any(feature = "runtime-benchmarks", test))] pub mod benchmarking; @@ -289,10 +289,13 @@ use sp_std::{ }; use codec::{HasCompact, Encode, Decode}; use frame_support::{ - decl_module, decl_event, decl_storage, ensure, decl_error, debug, - weights::{Weight, DispatchClass}, + decl_module, decl_event, decl_storage, ensure, decl_error, + weights::{Weight, constants::{WEIGHT_PER_MICROS, WEIGHT_PER_NANOS}}, storage::IterableStorageMap, - dispatch::{IsSubType, DispatchResult}, + dispatch::{ + IsSubType, DispatchResult, DispatchResultWithPostInfo, DispatchErrorWithPostInfo, + WithPostDispatchInfo, + }, traits::{ Currency, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get, UnixTime, EstimateNextNewSession, EnsureOrigin, @@ -300,11 +303,11 @@ use frame_support::{ }; use pallet_session::historical; use sp_runtime::{ - Perbill, PerU16, PerThing, RuntimeDebug, + Percent, Perbill, PerU16, PerThing, RuntimeDebug, DispatchError, curve::PiecewiseLinear, traits::{ - Convert, Zero, StaticLookup, CheckedSub, Saturating, SaturatedConversion, AtLeast32Bit, - Dispatchable, + Convert, Zero, StaticLookup, CheckedSub, Saturating, SaturatedConversion, + AtLeast32BitUnsigned, Dispatchable, }, transaction_validity::{ TransactionValidityError, TransactionValidity, ValidTransaction, InvalidTransaction, @@ -321,23 +324,24 @@ use frame_system::{ self as system, ensure_signed, ensure_root, ensure_none, offchain::SendTransactionTypes, }; -use sp_phragmen::{ - ExtendedBalance, Assignment, PhragmenScore, PhragmenResult, build_support_map, evaluate_support, - elect, generate_compact_solution_type, is_score_better, VotingLimit, SupportMap, VoteWeight, +use sp_npos_elections::{ + ExtendedBalance, Assignment, ElectionScore, ElectionResult as PrimitiveElectionResult, + build_support_map, evaluate_support, seq_phragmen, generate_solution_type, + is_score_better, VotingLimit, SupportMap, VoteWeight, }; -const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4; const STAKING_ID: LockIdentifier = *b"staking "; pub const MAX_UNLOCKING_CHUNKS: usize = 32; pub const MAX_NOMINATIONS: usize = ::LIMIT; -// syntactic sugar for logging -#[cfg(feature = "std")] -const LOG_TARGET: &'static str = "staking"; +pub(crate) const LOG_TARGET: &'static str = "staking"; + +// syntactic sugar for logging. +#[macro_export] macro_rules! log { ($level:tt, $patter:expr $(, $values:expr)* $(,)?) => { - debug::native::$level!( - target: LOG_TARGET, + frame_support::debug::$level!( + target: crate::LOG_TARGET, $patter $(, $values)* ) }; @@ -364,39 +368,38 @@ pub type EraIndex = u32; pub type RewardPoint = u32; // Note: Maximum nomination limit is set here -- 16. -generate_compact_solution_type!(pub GenericCompactAssignments, 16); - -/// Information regarding the active era (era in used in session). -#[derive(Encode, Decode, RuntimeDebug)] -pub struct ActiveEraInfo { - /// Index of era. - pub index: EraIndex, - /// Moment of start expresed as millisecond from `$UNIX_EPOCH`. - /// - /// Start can be none if start hasn't been set for the era yet, - /// Start is set on the first on_finalize of the era to guarantee usage of `Time`. - start: Option, -} +generate_solution_type!( + #[compact] + pub struct CompactAssignments::(16) +); -/// Accuracy used for on-chain phragmen. +/// Accuracy used for on-chain election. pub type ChainAccuracy = Perbill; -/// Accuracy used for off-chain phragmen. This better be small. +/// Accuracy used for off-chain election. This better be small. pub type OffchainAccuracy = PerU16; /// The balance type of this module. pub type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -/// The compact type for election solutions. -pub type CompactAssignments = - GenericCompactAssignments; - type PositiveImbalanceOf = <::Currency as Currency<::AccountId>>::PositiveImbalance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +/// Information regarding the active era (era in used in session). +#[derive(Encode, Decode, RuntimeDebug)] +pub struct ActiveEraInfo { + /// Index of era. + pub index: EraIndex, + /// Moment of start expressed as millisecond from `$UNIX_EPOCH`. + /// + /// Start can be none if start hasn't been set for the era yet, + /// Start is set on the first on_finalize of the era to guarantee usage of `Time`. + start: Option, +} + /// Reward points of an era. Used to split era total payout between validators. /// /// This points will be used to reward validators and their respective nominators. @@ -488,7 +491,7 @@ pub struct StakingLedger { impl< AccountId, - Balance: HasCompact + Copy + Saturating + AtLeast32Bit, + Balance: HasCompact + Copy + Saturating + AtLeast32BitUnsigned, > StakingLedger { /// Remove entries from `unlocking` that are sufficiently old and reduce the /// total by the sum of their balances. @@ -539,7 +542,7 @@ impl< } impl StakingLedger where - Balance: AtLeast32Bit + Saturating + Copy, + Balance: AtLeast32BitUnsigned + Saturating + Copy, { /// Slash the validator for a given amount of balance. This can grow the value /// of the slash in the case that the validator has less than `minimum_balance` @@ -603,7 +606,10 @@ pub struct Nominations { /// /// Except for initial nominations which are considered submitted at era 0. pub submitted_in: EraIndex, - /// Whether the nominations have been suppressed. + /// Whether the nominations have been suppressed. This can happen due to slashing of the + /// validators, or other events that might invalidate the nomination. + /// + /// NOTE: this for future proofing and is thus far not used. pub suppressed: bool, } @@ -679,6 +685,22 @@ pub enum ElectionStatus { Open(BlockNumber), } +/// Some indications about the size of the election. This must be submitted with the solution. +/// +/// Note that these values must reflect the __total__ number, not only those that are present in the +/// solution. In short, these should be the same size as the size of the values dumped in +/// `SnapshotValidators` and `SnapshotNominators`. +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, Default)] +pub struct ElectionSize { + /// Number of validators in the snapshot of the current election round. + #[codec(compact)] + pub validators: ValidatorIndex, + /// Number of nominators in the snapshot of the current election round. + #[codec(compact)] + pub nominators: NominatorIndex, +} + + impl ElectionStatus { fn is_open_at(&self, n: BlockNumber) -> bool { *self == Self::Open(n) @@ -742,6 +764,134 @@ impl SessionInterface<::AccountId> for T whe } } +pub mod weight { + use super::*; + + /// All weight notes are pertaining to the case of a better solution, in which we execute + /// the longest code path. + /// Weight: 0 + (0.63 μs * v) + (0.36 μs * n) + (96.53 μs * a ) + (8 μs * w ) with: + /// * v validators in snapshot validators, + /// * n nominators in snapshot nominators, + /// * a assignment in the submitted solution + /// * w winners in the submitted solution + /// + /// State reads: + /// - Initial checks: + /// - ElectionState, CurrentEra, QueuedScore + /// - SnapshotValidators.len() + SnapShotNominators.len() + /// - ValidatorCount + /// - SnapshotValidators + /// - SnapshotNominators + /// - Iterate over nominators: + /// - compact.len() * Nominators(who) + /// - (non_self_vote_edges) * SlashingSpans + /// - For `assignment_ratio_to_staked`: Basically read the staked value of each stash. + /// - (winners.len() + compact.len()) * (Ledger + Bonded) + /// - TotalIssuance (read a gzillion times potentially, but well it is cached.) + /// - State writes: + /// - QueuedElected, QueuedScore + pub fn weight_for_submit_solution( + winners: &Vec, + compact: &CompactAssignments, + size: &ElectionSize, + ) -> Weight { + (630 * WEIGHT_PER_NANOS).saturating_mul(size.validators as Weight) + .saturating_add((360 * WEIGHT_PER_NANOS).saturating_mul(size.nominators as Weight)) + .saturating_add((96 * WEIGHT_PER_MICROS).saturating_mul(compact.len() as Weight)) + .saturating_add((8 * WEIGHT_PER_MICROS).saturating_mul(winners.len() as Weight)) + // Initial checks + .saturating_add(T::DbWeight::get().reads(8)) + // Nominators + .saturating_add(T::DbWeight::get().reads(compact.len() as Weight)) + // SlashingSpans (upper bound for invalid solution) + .saturating_add(T::DbWeight::get().reads(compact.edge_count() as Weight)) + // `assignment_ratio_to_staked` + .saturating_add(T::DbWeight::get().reads(2 * ((winners.len() + compact.len()) as Weight))) + .saturating_add(T::DbWeight::get().reads(1)) + // write queued score and elected + .saturating_add(T::DbWeight::get().writes(2)) + } + + /// Weight of `submit_solution` in case of a correct submission. + /// + /// refund: we charged compact.len() * read(1) for SlashingSpans. A valid solution only reads + /// winners.len(). + pub fn weight_for_correct_submit_solution( + winners: &Vec, + compact: &CompactAssignments, + size: &ElectionSize, + ) -> Weight { + // NOTE: for consistency, we re-compute the original weight to maintain their relation and + // prevent any foot-guns. + let original_weight = weight_for_submit_solution::(winners, compact, size); + original_weight + .saturating_sub(T::DbWeight::get().reads(compact.edge_count() as Weight)) + .saturating_add(T::DbWeight::get().reads(winners.len() as Weight)) + } +} + +pub trait WeightInfo { + fn bond(u: u32, ) -> Weight; + fn bond_extra(u: u32, ) -> Weight; + fn unbond(u: u32, ) -> Weight; + fn withdraw_unbonded_update(s: u32, ) -> Weight; + fn withdraw_unbonded_kill(s: u32, ) -> Weight; + fn validate(u: u32, ) -> Weight; + fn nominate(n: u32, ) -> Weight; + fn chill(u: u32, ) -> Weight; + fn set_payee(u: u32, ) -> Weight; + fn set_controller(u: u32, ) -> Weight; + fn set_validator_count(c: u32, ) -> Weight; + fn force_no_eras(i: u32, ) -> Weight; + fn force_new_era(i: u32, ) -> Weight; + fn force_new_era_always(i: u32, ) -> Weight; + fn set_invulnerables(v: u32, ) -> Weight; + fn force_unstake(s: u32, ) -> Weight; + fn cancel_deferred_slash(s: u32, ) -> Weight; + fn payout_stakers(n: u32, ) -> Weight; + fn payout_stakers_alive_controller(n: u32, ) -> Weight; + fn rebond(l: u32, ) -> Weight; + fn set_history_depth(e: u32, ) -> Weight; + fn reap_stash(s: u32, ) -> Weight; + fn new_era(v: u32, n: u32, ) -> Weight; + fn do_slash(l: u32, ) -> Weight; + fn payout_all(v: u32, n: u32, ) -> Weight; + fn submit_solution_initial(v: u32, n: u32, a: u32, w: u32, ) -> Weight; + fn submit_solution_better(v: u32, n: u32, a: u32, w: u32, ) -> Weight; + fn submit_solution_weaker(v: u32, n: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn bond(_u: u32, ) -> Weight { 1_000_000_000 } + fn bond_extra(_u: u32, ) -> Weight { 1_000_000_000 } + fn unbond(_u: u32, ) -> Weight { 1_000_000_000 } + fn withdraw_unbonded_update(_s: u32, ) -> Weight { 1_000_000_000 } + fn withdraw_unbonded_kill(_s: u32, ) -> Weight { 1_000_000_000 } + fn validate(_u: u32, ) -> Weight { 1_000_000_000 } + fn nominate(_n: u32, ) -> Weight { 1_000_000_000 } + fn chill(_u: u32, ) -> Weight { 1_000_000_000 } + fn set_payee(_u: u32, ) -> Weight { 1_000_000_000 } + fn set_controller(_u: u32, ) -> Weight { 1_000_000_000 } + fn set_validator_count(_c: u32, ) -> Weight { 1_000_000_000 } + fn force_no_eras(_i: u32, ) -> Weight { 1_000_000_000 } + fn force_new_era(_i: u32, ) -> Weight { 1_000_000_000 } + fn force_new_era_always(_i: u32, ) -> Weight { 1_000_000_000 } + fn set_invulnerables(_v: u32, ) -> Weight { 1_000_000_000 } + fn force_unstake(_s: u32, ) -> Weight { 1_000_000_000 } + fn cancel_deferred_slash(_s: u32, ) -> Weight { 1_000_000_000 } + fn payout_stakers(_n: u32, ) -> Weight { 1_000_000_000 } + fn payout_stakers_alive_controller(_n: u32, ) -> Weight { 1_000_000_000 } + fn rebond(_l: u32, ) -> Weight { 1_000_000_000 } + fn set_history_depth(_e: u32, ) -> Weight { 1_000_000_000 } + fn reap_stash(_s: u32, ) -> Weight { 1_000_000_000 } + fn new_era(_v: u32, _n: u32, ) -> Weight { 1_000_000_000 } + fn do_slash(_l: u32, ) -> Weight { 1_000_000_000 } + fn payout_all(_v: u32, _n: u32, ) -> Weight { 1_000_000_000 } + fn submit_solution_initial(_v: u32, _n: u32, _a: u32, _w: u32, ) -> Weight { 1_000_000_000 } + fn submit_solution_better(_v: u32, _n: u32, _a: u32, _w: u32, ) -> Weight { 1_000_000_000 } + fn submit_solution_weaker(_v: u32, _n: u32, ) -> Weight { 1_000_000_000 } +} + pub trait Trait: frame_system::Trait + SendTransactionTypes> { /// The staking balance. type Currency: LockableCurrency; @@ -754,8 +904,9 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes> { /// Convert a balance into a number used for election calculation. This must fit into a `u64` /// but is allowed to be sensibly lossy. The `u64` is used to communicate with the - /// [`sp_phragmen`] crate which accepts u64 numbers and does operations in 128. Consequently, - /// the backward convert is used convert the u128s from phragmen back to a [`BalanceOf`]. + /// [`sp_npos_elections`] crate which accepts u64 numbers and does operations in 128. + /// Consequently, the backward convert is used convert the u128s from sp-elections back to a + /// [`BalanceOf`]. type CurrencyToVote: Convert, VoteWeight> + Convert>; /// Tokens have been minted and are unused for validator-reward. @@ -777,9 +928,10 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes> { /// Number of eras that staked funds must remain bonded for. type BondingDuration: Get; - /// Number of eras that slashes are deferred by, after computation. This - /// should be less than the bonding duration. Set to 0 if slashes should be - /// applied immediately, without opportunity for intervention. + /// Number of eras that slashes are deferred by, after computation. + /// + /// This should be less than the bonding duration. Set to 0 if slashes + /// should be applied immediately, without opportunity for intervention. type SlashDeferDuration: Get; /// The origin which can cancel a deferred slash. Root can always do this. @@ -795,19 +947,27 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes> { /// Something that can estimate the next session change, accurately or as a best effort guess. type NextNewSession: EstimateNextNewSession; - /// How many blocks ahead of the era, within the last do we try to run the phragmen offchain? + /// The number of blocks before the end of the era from which election submissions are allowed. + /// /// Setting this to zero will disable the offchain compute and only on-chain seq-phragmen will /// be used. + /// + /// This is bounded by being within the last session. Hence, setting it to a value more than the + /// length of a session will be pointless. type ElectionLookahead: Get; /// The overarching call type. - type Call: Dispatchable + From> + IsSubType, Self> + Clone; + type Call: Dispatchable + From> + IsSubType> + Clone; - /// Maximum number of equalise iterations to run in the offchain submission. If set to 0, - /// equalize will not be executed at all. + /// Maximum number of balancing iterations to run in the offchain submission. + /// + /// If set to 0, balance_solution will not be executed at all. type MaxIterations: Get; - /// The maximum number of nominator rewarded for each validator. + /// The threshold of improvement that should be provided for a new solution to be accepted. + type MinSolutionScoreBump: Get; + + /// The maximum number of nominators rewarded for each validator. /// /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim /// their reward. This used to limit the i/o cost for the nominator payout. @@ -818,6 +978,9 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes> { /// This is exposed so that it can be tuned for particular runtime, when /// multiple pallets send unsigned transactions. type UnsignedPriority: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } /// Mode of era-forcing. @@ -838,19 +1001,20 @@ impl Default for Forcing { fn default() -> Self { Forcing::NotForcing } } -// A value placed in storage that represents the current version of the Staking storage. -// This value is used by the `on_runtime_upgrade` logic to determine whether we run -// storage migration logic. This should match directly with the semantic versions of the Rust crate. +// A value placed in storage that represents the current version of the Staking storage. This value +// is used by the `on_runtime_upgrade` logic to determine whether we run storage migration logic. +// This should match directly with the semantic versions of the Rust crate. #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug)] enum Releases { V1_0_0Ancient, V2_0_0, V3_0_0, + V4_0_0, } impl Default for Releases { fn default() -> Self { - Releases::V3_0_0 + Releases::V4_0_0 } } @@ -860,17 +1024,16 @@ decl_storage! { /// /// Information is kept for eras in `[current_era - history_depth; current_era]`. /// - /// Must be more than the number of eras delayed by session otherwise. - /// I.e. active era must always be in history. - /// I.e. `active_era > current_era - history_depth` must be guaranteed. + /// Must be more than the number of eras delayed by session otherwise. I.e. active era must + /// always be in history. I.e. `active_era > current_era - history_depth` must be + /// guaranteed. HistoryDepth get(fn history_depth) config(): u32 = 84; /// The ideal number of staking participants. pub ValidatorCount get(fn validator_count) config(): u32; /// Minimum number of staking participants before emergency conditions are imposed. - pub MinimumValidatorCount get(fn minimum_validator_count) config(): - u32 = DEFAULT_MINIMUM_VALIDATOR_COUNT; + pub MinimumValidatorCount get(fn minimum_validator_count) config(): u32; /// Any validators that may never be slashed or forcibly kicked. It's a Vec since they're /// easy to initialize and the performance hit is minimal (we expect no more than four @@ -1022,7 +1185,7 @@ decl_storage! { pub QueuedElected get(fn queued_elected): Option>>; /// The score of the current [`QueuedElected`]. - pub QueuedScore get(fn queued_score): Option; + pub QueuedScore get(fn queued_score): Option; /// Flag to control the execution of the offchain election. When `Open(_)`, we accept /// solutions to be submitted. @@ -1036,10 +1199,7 @@ decl_storage! { /// Storage version of the pallet. /// /// This is set to v3.0.0 for new networks. - StorageVersion build(|_: &GenesisConfig| Releases::V3_0_0): Releases; - - /// The era where we migrated from Lazy Payouts to Simple Payouts - MigrateEra: Option; + StorageVersion build(|_: &GenesisConfig| Releases::V4_0_0): Releases; } add_extra_genesis { config(stakers): @@ -1079,25 +1239,29 @@ decl_event!( pub enum Event where Balance = BalanceOf, ::AccountId { /// The era payout has been set; the first balance is the validator-payout; the second is /// the remainder from the maximum amount of reward. + /// [era_index, validator_payout, remainder] EraPayout(EraIndex, Balance, Balance), - /// The staker has been rewarded by this amount. `AccountId` is the stash account. + /// The staker has been rewarded by this amount. [stash, amount] Reward(AccountId, Balance), /// One validator (and its nominators) has been slashed by the given amount. + /// [validator, amount] Slash(AccountId, Balance), /// An old slashing report from a prior era was discarded because it could - /// not be processed. + /// not be processed. [session_index] OldSlashingReportDiscarded(SessionIndex), - /// A new set of stakers was elected with the given computation method. + /// A new set of stakers was elected with the given [compute]. StakingElection(ElectionCompute), - /// An account has bonded this amount. + /// A new solution for the upcoming election has been stored. [compute] + SolutionStored(ElectionCompute), + /// An account has bonded this amount. [stash, amount] /// /// NOTE: This event is only emitted when funds are bonded via a dispatchable. Notably, /// it will not be emitted for staking rewards when they are added to stake. Bonded(AccountId, Balance), - /// An account has unbonded this amount. + /// An account has unbonded this amount. [stash, amount] Unbonded(AccountId, Balance), /// An account has called `withdraw_unbonded` and removed unbonding chunks worth `Balance` - /// from the unlocking queue. + /// from the unlocking queue. [stash, amount] Withdrawn(AccountId, Balance), } ); @@ -1136,34 +1300,40 @@ decl_error! { /// Rewards for this era have already been claimed for this validator. AlreadyClaimed, /// The submitted result is received out of the open window. - PhragmenEarlySubmission, + OffchainElectionEarlySubmission, /// The submitted result is not as good as the one stored on chain. - PhragmenWeakSubmission, + OffchainElectionWeakSubmission, /// The snapshot data of the current window is missing. SnapshotUnavailable, /// Incorrect number of winners were presented. - PhragmenBogusWinnerCount, + OffchainElectionBogusWinnerCount, /// One of the submitted winners is not an active candidate on chain (index is out of range /// in snapshot). - PhragmenBogusWinner, + OffchainElectionBogusWinner, /// Error while building the assignment type from the compact. This can happen if an index /// is invalid, or if the weights _overflow_. - PhragmenBogusCompact, + OffchainElectionBogusCompact, /// One of the submitted nominators is not an active nominator on chain. - PhragmenBogusNominator, + OffchainElectionBogusNominator, /// One of the submitted nominators has an edge to which they have not voted on chain. - PhragmenBogusNomination, + OffchainElectionBogusNomination, /// One of the submitted nominators has an edge which is submitted before the last non-zero /// slash of the target. - PhragmenSlashedNomination, + OffchainElectionSlashedNomination, /// A self vote must only be originated from a validator to ONLY themselves. - PhragmenBogusSelfVote, + OffchainElectionBogusSelfVote, /// The submitted result has unknown edges that are not among the presented winners. - PhragmenBogusEdge, + OffchainElectionBogusEdge, /// The claimed score does not match with the one computed from the data. - PhragmenBogusScore, + OffchainElectionBogusScore, + /// The election size is invalid. + OffchainElectionBogusElectionSize, /// The call is not allowed at the given time due to restrictions of election period. CallNotAllowed, + /// Incorrect previous history depth input provided. + IncorrectHistoryDepth, + /// Incorrect number of slashing spans provided. + IncorrectSlashingSpans, } } @@ -1175,6 +1345,36 @@ decl_module! { /// Number of eras that staked funds must remain bonded for. const BondingDuration: EraIndex = T::BondingDuration::get(); + /// Number of eras that slashes are deferred by, after computation. + /// + /// This should be less than the bonding duration. + /// Set to 0 if slashes should be applied immediately, without opportunity for + /// intervention. + const SlashDeferDuration: EraIndex = T::SlashDeferDuration::get(); + + /// The number of blocks before the end of the era from which election submissions are allowed. + /// + /// Setting this to zero will disable the offchain compute and only on-chain seq-phragmen will + /// be used. + /// + /// This is bounded by being within the last session. Hence, setting it to a value more than the + /// length of a session will be pointless. + const ElectionLookahead: T::BlockNumber = T::ElectionLookahead::get(); + + /// Maximum number of balancing iterations to run in the offchain submission. + /// + /// If set to 0, balance_solution will not be executed at all. + const MaxIterations: u32 = T::MaxIterations::get(); + + /// The threshold of improvement that should be provided for a new solution to be accepted. + const MinSolutionScoreBump: Perbill = T::MinSolutionScoreBump::get(); + + /// The maximum number of nominators rewarded for each validator. + /// + /// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim + /// their reward. This used to limit the i/o cost for the nominator payout. + const MaxNominatorRewardedPerValidator: u32 = T::MaxNominatorRewardedPerValidator::get(); + type Error = Error; fn deposit_event() = default; @@ -1185,22 +1385,30 @@ decl_module! { /// worker, if applicable, will execute at the end of the current block, and solutions may /// be submitted. fn on_initialize(now: T::BlockNumber) -> Weight { + let mut consumed_weight = 0; + let mut add_weight = |reads, writes, weight| { + consumed_weight += T::DbWeight::get().reads_writes(reads, writes); + consumed_weight += weight; + }; if // if we don't have any ongoing offchain compute. Self::era_election_status().is_closed() && // either current session final based on the plan, or we're forcing. (Self::is_current_session_final() || Self::will_era_be_forced()) { - if let Some(next_session_change) = T::NextNewSession::estimate_next_new_session(now){ + if let Some(next_session_change) = T::NextNewSession::estimate_next_new_session(now) { if let Some(remaining) = next_session_change.checked_sub(&now) { if remaining <= T::ElectionLookahead::get() && !remaining.is_zero() { // create snapshot. - if Self::create_stakers_snapshot() { + let (did_snapshot, snapshot_weight) = Self::create_stakers_snapshot(); + add_weight(0, 0, snapshot_weight); + if did_snapshot { // Set the flag to make sure we don't waste any compute here in the same era // after we have triggered the offline compute. >::put( ElectionStatus::::Open(now) ); + add_weight(0, 1, 0); log!(info, "💸 Election window is Open({:?}). Snapshot created", now); } else { log!(warn, "💸 Failed to create snapshot at {:?}.", now); @@ -1210,10 +1418,13 @@ decl_module! { } else { log!(warn, "💸 Estimating next session change failed."); } + add_weight(0, 0, T::NextNewSession::weight(now)) } - - // weight - 50_000 + // For `era_election_status`, `is_current_session_final`, `will_era_be_forced` + add_weight(3, 0, 0); + // Additional read from `on_finalize` + add_weight(1, 0, 0); + consumed_weight } /// Check if the current block number is the one at which the election window has been set @@ -1227,7 +1438,7 @@ decl_module! { log!(debug, "skipping offchain worker in open election window due to [{}]", why); } else { if let Err(e) = compute_offchain_election::() { - log!(warn, "💸 Error in phragmen offchain worker: {:?}", e); + log!(error, "💸 Error in election offchain worker: {:?}", e); } else { log!(debug, "Executed offchain worker thread without errors."); } @@ -1241,9 +1452,22 @@ decl_module! { if active_era.start.is_none() { let now_as_millis_u64 = T::UnixTime::now().as_millis().saturated_into::(); active_era.start = Some(now_as_millis_u64); + // This write only ever happens once, we don't include it in the weight in general ActiveEra::put(active_era); } } + // `on_finalize` weight is tracked in `on_initialize` + } + + fn integrity_test() { + sp_io::TestExternalities::new_empty().execute_with(|| + assert!( + T::SlashDeferDuration::get() < T::BondingDuration::get() || T::BondingDuration::get() == 0, + "As per documentation, slash defer duration ({}) should be less than bonding duration ({}).", + T::SlashDeferDuration::get(), + T::BondingDuration::get(), + ) + ); } /// Take the origin account as a stash and lock up `value` of its balance. `controller` will @@ -1262,8 +1486,13 @@ decl_module! { /// /// NOTE: Two of the storage writes (`Self::bonded`, `Self::payee`) are _never_ cleaned /// unless the `origin` falls below _existential deposit_ and gets removed as dust. + /// ------------------ + /// Base Weight: 67.87 µs + /// DB Weight: + /// - Read: Bonded, Ledger, [Origin Account], Current Era, History Depth, Locks + /// - Write: Bonded, Payee, [Origin Account], Locks, Ledger /// # - #[weight = 500_000_000] + #[weight = 67 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(5, 4)] pub fn bond(origin, controller: ::Source, #[compact] value: BalanceOf, @@ -1326,8 +1555,13 @@ decl_module! { /// - Independent of the arguments. Insignificant complexity. /// - O(1). /// - One DB entry. + /// ------------ + /// Base Weight: 54.88 µs + /// DB Weight: + /// - Read: Era Election Status, Bonded, Ledger, [Origin Account], Locks + /// - Write: [Origin Account], Locks, Ledger /// # - #[weight = 500_000_000] + #[weight = 55 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(4, 2)] fn bond_extra(origin, #[compact] max_additional: BalanceOf) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let stash = ensure_signed(origin)?; @@ -1372,8 +1606,13 @@ decl_module! { /// The only way to clean the aforementioned storage item is also user-controlled via /// `withdraw_unbonded`. /// - One DB entry. + /// ---------- + /// Base Weight: 50.34 µs + /// DB Weight: + /// - Read: Era Election Status, Ledger, Current Era, Locks, [Origin Account] + /// - Write: [Origin Account], Locks, Ledger /// - #[weight = 400_000_000] + #[weight = 50 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(4, 2)] fn unbond(origin, #[compact] value: BalanceOf) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1398,7 +1637,7 @@ decl_module! { let era = Self::current_era().unwrap_or(0) + T::BondingDuration::get(); ledger.unlocking.push(UnlockChunk { value, era }); Self::update_ledger(&controller, &ledger); - Self::deposit_event(RawEvent::Unbonded(ledger.stash.clone(), value)); + Self::deposit_event(RawEvent::Unbonded(ledger.stash, value)); } } @@ -1420,9 +1659,28 @@ decl_module! { /// indirectly user-controlled. See [`unbond`] for more detail. /// - Contains a limited number of reads, yet the size of which could be large based on `ledger`. /// - Writes are limited to the `origin` account key. + /// --------------- + /// Complexity O(S) where S is the number of slashing spans to remove + /// Base Weight: + /// Update: 50.52 + .028 * S µs + /// - Reads: EraElectionStatus, Ledger, Current Era, Locks, [Origin Account] + /// - Writes: [Origin Account], Locks, Ledger + /// Kill: 79.41 + 2.366 * S µs + /// - Reads: EraElectionStatus, Ledger, Current Era, Bonded, Slashing Spans, [Origin Account], Locks + /// - Writes: Bonded, Slashing Spans (if S > 0), Ledger, Payee, Validators, Nominators, [Origin Account], Locks + /// - Writes Each: SpanSlash * S + /// NOTE: Weight annotation is the kill scenario, we refund otherwise. /// # - #[weight = 400_000_000] - fn withdraw_unbonded(origin) { + #[weight = T::DbWeight::get().reads_writes(6, 6) + .saturating_add(80 * WEIGHT_PER_MICROS) + .saturating_add( + (2 * WEIGHT_PER_MICROS).saturating_mul(Weight::from(*num_slashing_spans)) + ) + .saturating_add(T::DbWeight::get().writes(Weight::from(*num_slashing_spans))) + // if slashing spans is non-zero, add 1 more write + .saturating_add(T::DbWeight::get().writes(Weight::from(*num_slashing_spans).min(1))) + ] + fn withdraw_unbonded(origin, num_slashing_spans: u32) -> DispatchResultWithPostInfo { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; let mut ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; @@ -1431,17 +1689,21 @@ decl_module! { ledger = ledger.consolidate_unlocked(current_era) } - if ledger.unlocking.is_empty() && ledger.active.is_zero() { + let post_info_weight = if ledger.unlocking.is_empty() && ledger.active.is_zero() { // This account must have called `unbond()` with some value that caused the active // portion to fall below existential deposit + will have no more unlocking chunks // left. We can now safely remove all staking-related information. - Self::kill_stash(&stash)?; + Self::kill_stash(&stash, num_slashing_spans)?; // remove the lock. T::Currency::remove_lock(STAKING_ID, &stash); + // This is worst case scenario, so we use the full weight and return None + None } else { // This was the consequence of a partial unbond. just update the ledger and move on. Self::update_ledger(&controller, &ledger); - } + // This is only an update, so we use less overall weight + Some(50 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(4, 2)) + }; // `old_total` should never be less than the new total because // `consolidate_unlocked` strictly subtracts balance. @@ -1450,6 +1712,8 @@ decl_module! { let value = old_total - ledger.total; Self::deposit_event(RawEvent::Withdrawn(stash, value)); } + + Ok(post_info_weight.into()) } /// Declare the desire to validate for the origin controller. @@ -1463,8 +1727,13 @@ decl_module! { /// - Independent of the arguments. Insignificant complexity. /// - Contains a limited number of reads. /// - Writes are limited to the `origin` account key. + /// ----------- + /// Base Weight: 17.13 µs + /// DB Weight: + /// - Read: Era Election Status, Ledger + /// - Write: Nominators, Validators /// # - #[weight = 750_000_000] + #[weight = 17 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(2, 2)] pub fn validate(origin, prefs: ValidatorPrefs) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1483,11 +1752,20 @@ decl_module! { /// And, it can be only called when [`EraElectionStatus`] is `Closed`. /// /// # - /// - The transaction's complexity is proportional to the size of `targets`, - /// which is capped at CompactAssignments::LIMIT. + /// - The transaction's complexity is proportional to the size of `targets` (N) + /// which is capped at CompactAssignments::LIMIT (MAX_NOMINATIONS). /// - Both the reads and writes follow a similar pattern. + /// --------- + /// Base Weight: 22.34 + .36 * N µs + /// where N is the number of targets + /// DB Weight: + /// - Reads: Era Election Status, Ledger, Current Era + /// - Writes: Validators, Nominators /// # - #[weight = 750_000_000] + #[weight = T::DbWeight::get().reads_writes(3, 2) + .saturating_add(22 * WEIGHT_PER_MICROS) + .saturating_add((360 * WEIGHT_PER_NANOS).saturating_mul(targets.len() as Weight)) + ] pub fn nominate(origin, targets: Vec<::Source>) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1495,7 +1773,7 @@ decl_module! { let stash = &ledger.stash; ensure!(!targets.is_empty(), Error::::EmptyTargets); let targets = targets.into_iter() - .take(::LIMIT) + .take(MAX_NOMINATIONS) .map(|t| T::Lookup::lookup(t)) .collect::, _>>()?; @@ -1521,8 +1799,13 @@ decl_module! { /// - Independent of the arguments. Insignificant complexity. /// - Contains one read. /// - Writes are limited to the `origin` account key. + /// -------- + /// Base Weight: 16.53 µs + /// DB Weight: + /// - Read: EraElectionStatus, Ledger + /// - Write: Validators, Nominators /// # - #[weight = 500_000_000] + #[weight = 16 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(2, 2)] fn chill(origin) { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; @@ -1540,8 +1823,13 @@ decl_module! { /// - Independent of the arguments. Insignificant complexity. /// - Contains a limited number of reads. /// - Writes are limited to the `origin` account key. + /// --------- + /// - Base Weight: 11.33 µs + /// - DB Weight: + /// - Read: Ledger + /// - Write: Payee /// # - #[weight = 500_000_000] + #[weight = 11 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(1, 1)] fn set_payee(origin, payee: RewardDestination) { let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; @@ -1559,8 +1847,13 @@ decl_module! { /// - Independent of the arguments. Insignificant complexity. /// - Contains a limited number of reads. /// - Writes are limited to the `origin` account key. + /// ---------- + /// Base Weight: 25.22 µs + /// DB Weight: + /// - Read: Bonded, Ledger New Controller, Ledger Old Controller + /// - Write: Bonded, Ledger New Controller, Ledger Old Controller /// # - #[weight = 750_000_000] + #[weight = 25 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(3, 3)] fn set_controller(origin, controller: ::Source) { let stash = ensure_signed(origin)?; let old_controller = Self::bonded(&stash).ok_or(Error::::NotStash)?; @@ -1576,19 +1869,58 @@ decl_module! { } } - /// The ideal number of validators. - #[weight = 5_000_000] + /// Sets the ideal number of validators. + /// + /// The dispatch origin must be Root. + /// + /// # + /// Base Weight: 1.717 µs + /// Write: Validator Count + /// # + #[weight = 2 * WEIGHT_PER_MICROS + T::DbWeight::get().writes(1)] fn set_validator_count(origin, #[compact] new: u32) { ensure_root(origin)?; ValidatorCount::put(new); } + /// Increments the ideal number of validators. + /// + /// The dispatch origin must be Root. + /// + /// # + /// Base Weight: 1.717 µs + /// Read/Write: Validator Count + /// # + #[weight = 2 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(1, 1)] + fn increase_validator_count(origin, #[compact] additional: u32) { + ensure_root(origin)?; + ValidatorCount::mutate(|n| *n += additional); + } + + /// Scale up the ideal number of validators by a factor. + /// + /// The dispatch origin must be Root. + /// + /// # + /// Base Weight: 1.717 µs + /// Read/Write: Validator Count + /// # + #[weight = 2 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(1, 1)] + fn scale_validator_count(origin, factor: Percent) { + ensure_root(origin)?; + ValidatorCount::mutate(|n| *n += factor * *n); + } + /// Force there to be no new eras indefinitely. /// + /// The dispatch origin must be Root. + /// /// # /// - No arguments. + /// - Base Weight: 1.857 µs + /// - Write: ForceEra /// # - #[weight = 5_000_000] + #[weight = 2 * WEIGHT_PER_MICROS + T::DbWeight::get().writes(1)] fn force_no_eras(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceNone); @@ -1597,29 +1929,62 @@ decl_module! { /// Force there to be a new era at the end of the next session. After this, it will be /// reset to normal (non-forced) behaviour. /// + /// The dispatch origin must be Root. + /// /// # /// - No arguments. + /// - Base Weight: 1.959 µs + /// - Write ForceEra /// # - #[weight = 5_000_000] + #[weight = 2 * WEIGHT_PER_MICROS + T::DbWeight::get().writes(1)] fn force_new_era(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceNew); } /// Set the validators who cannot be slashed (if any). - #[weight = 5_000_000] + /// + /// The dispatch origin must be Root. + /// + /// # + /// - O(V) + /// - Base Weight: 2.208 + .006 * V µs + /// - Write: Invulnerables + /// # + #[weight = T::DbWeight::get().writes(1) + .saturating_add(2 * WEIGHT_PER_MICROS) + .saturating_add((6 * WEIGHT_PER_NANOS).saturating_mul(validators.len() as Weight)) + ] fn set_invulnerables(origin, validators: Vec) { ensure_root(origin)?; >::put(validators); } /// Force a current staker to become completely unstaked, immediately. - #[weight = 0] - fn force_unstake(origin, stash: T::AccountId) { + /// + /// The dispatch origin must be Root. + /// + /// # + /// O(S) where S is the number of slashing spans to be removed + /// Base Weight: 53.07 + 2.365 * S µs + /// Reads: Bonded, Slashing Spans, Account, Locks + /// Writes: Bonded, Slashing Spans (if S > 0), Ledger, Payee, Validators, Nominators, Account, Locks + /// Writes Each: SpanSlash * S + /// # + #[weight = T::DbWeight::get().reads_writes(4, 7) + .saturating_add(53 * WEIGHT_PER_MICROS) + .saturating_add( + WEIGHT_PER_MICROS.saturating_mul(2).saturating_mul(Weight::from(*num_slashing_spans)) + ) + .saturating_add(T::DbWeight::get().writes(Weight::from(*num_slashing_spans))) + // if slashing spans is non-zero, add 1 more write + .saturating_add(T::DbWeight::get().writes(Weight::from(*num_slashing_spans > 0))) + ] + fn force_unstake(origin, stash: T::AccountId, num_slashing_spans: u32) { ensure_root(origin)?; // remove all staking-related information. - Self::kill_stash(&stash)?; + Self::kill_stash(&stash, num_slashing_spans)?; // remove the lock. T::Currency::remove_lock(STAKING_ID, &stash); @@ -1627,27 +1992,38 @@ decl_module! { /// Force there to be a new era at the end of sessions indefinitely. /// + /// The dispatch origin must be Root. + /// /// # - /// - One storage write + /// - Base Weight: 2.05 µs + /// - Write: ForceEra /// # - #[weight = 5_000_000] + #[weight = 2 * WEIGHT_PER_MICROS + T::DbWeight::get().writes(1)] fn force_new_era_always(origin) { ensure_root(origin)?; ForceEra::put(Forcing::ForceAlways); } - /// Cancel enactment of a deferred slash. Can be called by either the root origin or - /// the `T::SlashCancelOrigin`. - /// passing the era and indices of the slashes for that era to kill. + /// Cancel enactment of a deferred slash. + /// + /// Can be called by the `T::SlashCancelOrigin`. + /// + /// Parameters: era and indices of the slashes for that era to kill. /// /// # - /// - One storage write. + /// Complexity: O(U + S) + /// with U unapplied slashes weighted with U=1000 + /// and S is the number of slash indices to be canceled. + /// - Base: 5870 + 34.61 * S µs + /// - Read: Unapplied Slashes + /// - Write: Unapplied Slashes /// # - #[weight = 1_000_000_000] + #[weight = T::DbWeight::get().reads_writes(1, 1) + .saturating_add(5_870 * WEIGHT_PER_MICROS) + .saturating_add((35 * WEIGHT_PER_MICROS).saturating_mul(slash_indices.len() as Weight)) + ] fn cancel_deferred_slash(origin, era: EraIndex, slash_indices: Vec) { - T::SlashCancelOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + T::SlashCancelOrigin::ensure_origin(origin)?; ensure!(!slash_indices.is_empty(), Error::::EmptyTargets); ensure!(is_sorted_and_unique(&slash_indices), Error::::NotSortedAndUnique); @@ -1664,69 +2040,6 @@ decl_module! { ::UnappliedSlashes::insert(&era, &unapplied); } - /// **This extrinsic will be removed after `MigrationEra + HistoryDepth` has passed, giving - /// opportunity for users to claim all rewards before moving to Simple Payouts. After this - /// time, you should use `payout_stakers` instead.** - /// - /// Make one nominator's payout for one era. - /// - /// - `who` is the controller account of the nominator to pay out. - /// - `era` may not be lower than one following the most recently paid era. If it is higher, - /// then it indicates an instruction to skip the payout of all previous eras. - /// - `validators` is the list of all validators that `who` had exposure to during `era`, - /// alongside the index of `who` in the clipped exposure of the validator. - /// I.e. each element is a tuple of - /// `(validator, index of `who` in clipped exposure of validator)`. - /// If it is incomplete, then less than the full reward will be paid out. - /// It must not exceed `MAX_NOMINATIONS`. - /// - /// WARNING: once an era is payed for a validator such validator can't claim the payout of - /// previous era. - /// - /// WARNING: Incorrect arguments here can result in loss of payout. Be very careful. - /// - /// # - /// - Number of storage read of `O(validators)`; `validators` is the argument of the call, - /// and is bounded by `MAX_NOMINATIONS`. - /// - Each storage read is `O(N)` size and decode complexity; `N` is the maximum - /// nominations that can be given to a single validator. - /// - Computation complexity: `O(MAX_NOMINATIONS * logN)`; `MAX_NOMINATIONS` is the - /// maximum number of validators that may be nominated by a single nominator, it is - /// bounded only economically (all nominators are required to place a minimum stake). - /// # - #[weight = 500_000_000] - fn payout_nominator(origin, era: EraIndex, validators: Vec<(T::AccountId, u32)>) - -> DispatchResult - { - let ctrl = ensure_signed(origin)?; - Self::do_payout_nominator(ctrl, era, validators) - } - - /// **This extrinsic will be removed after `MigrationEra + HistoryDepth` has passed, giving - /// opportunity for users to claim all rewards before moving to Simple Payouts. After this - /// time, you should use `payout_stakers` instead.** - /// - /// Make one validator's payout for one era. - /// - /// - `who` is the controller account of the validator to pay out. - /// - `era` may not be lower than one following the most recently paid era. If it is higher, - /// then it indicates an instruction to skip the payout of all previous eras. - /// - /// WARNING: once an era is payed for a validator such validator can't claim the payout of - /// previous era. - /// - /// WARNING: Incorrect arguments here can result in loss of payout. Be very careful. - /// - /// # - /// - Time complexity: O(1). - /// - Contains a limited number of reads and writes. - /// # - #[weight = 500_000_000] - fn payout_validator(origin, era: EraIndex) -> DispatchResult { - let ctrl = ensure_signed(origin)?; - Self::do_payout_validator(ctrl, era) - } - /// Pay out all the stakers behind a single validator for a single era. /// /// - `validator_stash` is the stash account of the validator. Their nominators, up to @@ -1741,8 +2054,24 @@ decl_module! { /// # /// - Time complexity: at most O(MaxNominatorRewardedPerValidator). /// - Contains a limited number of reads and writes. + /// ----------- + /// N is the Number of payouts for the validator (including the validator) + /// Base Weight: + /// - Reward Destination Staked: 110 + 54.2 * N µs (Median Slopes) + /// - Reward Destination Controller (Creating): 120 + 41.95 * N µs (Median Slopes) + /// DB Weight: + /// - Read: EraElectionStatus, CurrentEra, HistoryDepth, ErasValidatorReward, + /// ErasStakersClipped, ErasRewardPoints, ErasValidatorPrefs (8 items) + /// - Read Each: Bonded, Ledger, Payee, Locks, System Account (5 items) + /// - Write Each: System Account, Locks, Ledger (3 items) /// # - #[weight = 500_000_000] + #[weight = + 120 * WEIGHT_PER_MICROS + + 54 * WEIGHT_PER_MICROS * Weight::from(T::MaxNominatorRewardedPerValidator::get()) + + T::DbWeight::get().reads(7) + + T::DbWeight::get().reads(5) * Weight::from(T::MaxNominatorRewardedPerValidator::get() + 1) + + T::DbWeight::get().writes(3) * Weight::from(T::MaxNominatorRewardedPerValidator::get() + 1) + ] fn payout_stakers(origin, validator_stash: T::AccountId, era: EraIndex) -> DispatchResult { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); ensure_signed(origin)?; @@ -1755,11 +2084,21 @@ decl_module! { /// [`EraElectionStatus`] is `Closed`. /// /// # - /// - Time complexity: O(1). Bounded by `MAX_UNLOCKING_CHUNKS`. + /// - Time complexity: O(L), where L is unlocking chunks + /// - Bounded by `MAX_UNLOCKING_CHUNKS`. /// - Storage changes: Can't increase storage, only decrease it. + /// --------------- + /// - Base Weight: 34.51 µs * .048 L µs + /// - DB Weight: + /// - Reads: EraElectionStatus, Ledger, Locks, [Origin Account] + /// - Writes: [Origin Account], Locks, Ledger /// # - #[weight = 500_000_000] - fn rebond(origin, #[compact] value: BalanceOf) { + #[weight = + 35 * WEIGHT_PER_MICROS + + 50 * WEIGHT_PER_NANOS * (MAX_UNLOCKING_CHUNKS as Weight) + + T::DbWeight::get().reads_writes(3, 2) + ] + fn rebond(origin, #[compact] value: BalanceOf) -> DispatchResultWithPostInfo { ensure!(Self::era_election_status().is_closed(), Error::::CallNotAllowed); let controller = ensure_signed(origin)?; let ledger = Self::ledger(&controller).ok_or(Error::::NotController)?; @@ -1767,13 +2106,44 @@ decl_module! { let ledger = ledger.rebond(value); Self::update_ledger(&controller, &ledger); + Ok(Some( + 35 * WEIGHT_PER_MICROS + + 50 * WEIGHT_PER_NANOS * (ledger.unlocking.len() as Weight) + + T::DbWeight::get().reads_writes(3, 2) + ).into()) } - /// Set history_depth value. + /// Set `HistoryDepth` value. This function will delete any history information + /// when `HistoryDepth` is reduced. + /// + /// Parameters: + /// - `new_history_depth`: The new history depth you would like to set. + /// - `era_items_deleted`: The number of items that will be deleted by this dispatch. + /// This should report all the storage items that will be deleted by clearing old + /// era history. Needed to report an accurate weight for the dispatch. Trusted by + /// `Root` to report an accurate number. /// /// Origin must be root. - #[weight = (500_000_000, DispatchClass::Operational)] - fn set_history_depth(origin, #[compact] new_history_depth: EraIndex) { + /// + /// # + /// - E: Number of history depths removed, i.e. 10 -> 7 = 3 + /// - Base Weight: 29.13 * E µs + /// - DB Weight: + /// - Reads: Current Era, History Depth + /// - Writes: History Depth + /// - Clear Prefix Each: Era Stakers, EraStakersClipped, ErasValidatorPrefs + /// - Writes Each: ErasValidatorReward, ErasRewardPoints, ErasTotalStake, ErasStartSessionIndex + /// # + #[weight = { + let items = Weight::from(*_era_items_deleted); + T::DbWeight::get().reads_writes(2, 1) + .saturating_add(T::DbWeight::get().reads_writes(items, items)) + + }] + fn set_history_depth(origin, + #[compact] new_history_depth: EraIndex, + #[compact] _era_items_deleted: u32, + ) { ensure_root(origin)?; if let Some(current_era) = Self::current_era() { HistoryDepth::mutate(|history_depth| { @@ -1794,14 +2164,31 @@ decl_module! { /// This can be called from any origin. /// /// - `stash`: The stash account to reap. Its balance must be zero. - #[weight = 0] - fn reap_stash(_origin, stash: T::AccountId) { + /// + /// # + /// Complexity: O(S) where S is the number of slashing spans on the account. + /// Base Weight: 75.94 + 2.396 * S µs + /// DB Weight: + /// - Reads: Stash Account, Bonded, Slashing Spans, Locks + /// - Writes: Bonded, Slashing Spans (if S > 0), Ledger, Payee, Validators, Nominators, Stash Account, Locks + /// - Writes Each: SpanSlash * S + /// # + #[weight = T::DbWeight::get().reads_writes(4, 7) + .saturating_add(76 * WEIGHT_PER_MICROS) + .saturating_add( + WEIGHT_PER_MICROS.saturating_mul(2).saturating_mul(Weight::from(*num_slashing_spans)) + ) + .saturating_add(T::DbWeight::get().writes(Weight::from(*num_slashing_spans))) + // if slashing spans is non-zero, add 1 more write + .saturating_add(T::DbWeight::get().writes(Weight::from(*num_slashing_spans).min(1))) + ] + fn reap_stash(_origin, stash: T::AccountId, num_slashing_spans: u32) { ensure!(T::Currency::total_balance(&stash).is_zero(), Error::::FundedTarget); - Self::kill_stash(&stash)?; + Self::kill_stash(&stash, num_slashing_spans)?; T::Currency::remove_lock(STAKING_ID, &stash); } - /// Submit a phragmen result to the chain. If the solution: + /// Submit an election result to the chain. If the solution: /// /// 1. is valid. /// 2. has a better score than a potentially existing solution on chain. @@ -1814,7 +2201,7 @@ decl_module! { /// 2. `assignments`: the compact version of an assignment vector that encodes the edge /// weights. /// - /// Both of which may be computed using [`phragmen`], or any other algorithm. + /// Both of which may be computed using _phragmen_, or any other algorithm. /// /// Additionally, the submitter must provide: /// @@ -1846,51 +2233,26 @@ decl_module! { /// minimized (to ensure less variance) /// /// # - /// E: number of edges. m: size of winner committee. n: number of nominators. d: edge degree - /// (16 for now) v: number of on-chain validator candidates. - /// - /// NOTE: given a solution which is reduced, we can enable a new check the ensure `|E| < n + - /// m`. We don't do this _yet_, but our offchain worker code executes it nonetheless. - /// - /// major steps (all done in `check_and_replace_solution`): - /// - /// - Storage: O(1) read `ElectionStatus`. - /// - Storage: O(1) read `PhragmenScore`. - /// - Storage: O(1) read `ValidatorCount`. - /// - Storage: O(1) length read from `SnapshotValidators`. - /// - /// - Storage: O(v) reads of `AccountId` to fetch `snapshot_validators`. - /// - Memory: O(m) iterations to map winner index to validator id. - /// - Storage: O(n) reads `AccountId` to fetch `snapshot_nominators`. - /// - Memory: O(n + m) reads to map index to `AccountId` for un-compact. - /// - /// - Storage: O(e) accountid reads from `Nomination` to read correct nominations. - /// - Storage: O(e) calls into `slashable_balance_of_vote_weight` to convert ratio to staked. - /// - /// - Memory: build_support_map. O(e). - /// - Memory: evaluate_support: O(E). - /// - /// - Storage: O(e) writes to `QueuedElected`. - /// - Storage: O(1) write to `QueuedScore` - /// - /// The weight of this call is 1/10th of the blocks total weight. + /// See `crate::weight` module. /// # - #[weight = 100_000_000_000] + #[weight = weight::weight_for_submit_solution::(winners, compact, size)] pub fn submit_election_solution( origin, winners: Vec, - compact_assignments: CompactAssignments, - score: PhragmenScore, + compact: CompactAssignments, + score: ElectionScore, era: EraIndex, - ) { + size: ElectionSize, + ) -> DispatchResultWithPostInfo { let _who = ensure_signed(origin)?; Self::check_and_replace_solution( winners, - compact_assignments, + compact, ElectionCompute::Signed, score, era, - )? + size, + ) } /// Unsigned version of `submit_election_solution`. @@ -1898,26 +2260,34 @@ decl_module! { /// Note that this must pass the [`ValidateUnsigned`] check which only allows transactions /// from the local node to be included. In other words, only the block author can include a /// transaction in the block. - #[weight = 100_000_000_000] + /// + /// # + /// See `crate::weight` module. + /// # + #[weight = weight::weight_for_submit_solution::(winners, compact, size)] pub fn submit_election_solution_unsigned( origin, winners: Vec, - compact_assignments: CompactAssignments, - score: PhragmenScore, + compact: CompactAssignments, + score: ElectionScore, era: EraIndex, - ) { + size: ElectionSize, + ) -> DispatchResultWithPostInfo { ensure_none(origin)?; - Self::check_and_replace_solution( + let adjustments = Self::check_and_replace_solution( winners, - compact_assignments, + compact, ElectionCompute::Unsigned, score, era, - )? - // TODO: instead of returning an error, panic. This makes the entire produced block - // invalid. - // This ensures that block authors will not ever try and submit a solution which is not - // an improvement, since they will lose their authoring points/rewards. + size, + ).expect( + "An unsigned solution can only be submitted by validators; A validator should \ + always produce correct solutions, else this block should not be imported, thus \ + effectively depriving the validators from their authoring reward. Hence, this panic + is expected." + ); + Ok(adjustments) } } } @@ -1925,6 +2295,7 @@ decl_module! { impl Module { /// The total balance that can be slashed from a stash account as of right now. pub fn slashable_balance_of(stash: &T::AccountId) -> BalanceOf { + // Weight note: consider making the stake accessible through stash. Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default() } @@ -1939,12 +2310,18 @@ impl Module { /// /// This data is used to efficiently evaluate election results. returns `true` if the operation /// is successful. - fn create_stakers_snapshot() -> bool { + pub fn create_stakers_snapshot() -> (bool, Weight) { + let mut consumed_weight = 0; + let mut add_db_reads_writes = |reads, writes| { + consumed_weight += T::DbWeight::get().reads_writes(reads, writes); + }; let validators = >::iter().map(|(v, _)| v).collect::>(); let mut nominators = >::iter().map(|(n, _)| n).collect::>(); let num_validators = validators.len(); let num_nominators = nominators.len(); + add_db_reads_writes((num_validators + num_nominators) as Weight, 0); + if num_validators > MAX_VALIDATORS || num_nominators.saturating_add(num_validators) > MAX_NOMINATORS @@ -1957,14 +2334,15 @@ impl Module { num_nominators, MAX_NOMINATORS, ); - false + (false, consumed_weight) } else { // all validators nominate themselves; nominators.extend(validators.clone()); >::put(validators); >::put(nominators); - true + add_db_reads_writes(0, 2); + (true, consumed_weight) } } @@ -1974,143 +2352,6 @@ impl Module { >::kill(); } - fn do_payout_nominator(ctrl: T::AccountId, era: EraIndex, validators: Vec<(T::AccountId, u32)>) - -> DispatchResult - { - // validators len must not exceed `MAX_NOMINATIONS` to avoid querying more validator - // exposure than necessary. - if validators.len() > MAX_NOMINATIONS { - return Err(Error::::InvalidNumberOfNominations.into()); - } - // If migrate_era is not populated, then you should use `payout_stakers` - let migrate_era = MigrateEra::get().ok_or(Error::::InvalidEraToReward)?; - // This payout mechanism will only work for eras before the migration. - // Subsequent payouts should use `payout_stakers`. - ensure!(era < migrate_era, Error::::InvalidEraToReward); - let current_era = CurrentEra::get().ok_or(Error::::InvalidEraToReward)?; - ensure!(era <= current_era, Error::::InvalidEraToReward); - let history_depth = Self::history_depth(); - ensure!(era >= current_era.saturating_sub(history_depth), Error::::InvalidEraToReward); - - // Note: if era has no reward to be claimed, era may be future. better not to update - // `nominator_ledger.last_reward` in this case. - let era_payout = >::get(&era) - .ok_or_else(|| Error::::InvalidEraToReward)?; - - let mut nominator_ledger = >::get(&ctrl).ok_or_else(|| Error::::NotController)?; - - ensure!( - Self::era_election_status().is_closed() || Self::payee(&nominator_ledger.stash) != RewardDestination::Staked, - Error::::CallNotAllowed, - ); - - nominator_ledger.claimed_rewards.retain(|&x| x >= current_era.saturating_sub(history_depth)); - match nominator_ledger.claimed_rewards.binary_search(&era) { - Ok(_) => Err(Error::::AlreadyClaimed)?, - Err(pos) => nominator_ledger.claimed_rewards.insert(pos, era), - } - - >::insert(&ctrl, &nominator_ledger); - - let mut reward = Perbill::zero(); - let era_reward_points = >::get(&era); - - for (validator, nominator_index) in validators.into_iter() { - let commission = Self::eras_validator_prefs(&era, &validator).commission; - let validator_exposure = >::get(&era, &validator); - - if let Some(nominator_exposure) = validator_exposure.others - .get(nominator_index as usize) - { - if nominator_exposure.who != nominator_ledger.stash { - continue; - } - - let nominator_exposure_part = Perbill::from_rational_approximation( - nominator_exposure.value, - validator_exposure.total, - ); - let validator_point = era_reward_points.individual.get(&validator) - .map(|points| *points) - .unwrap_or_else(|| Zero::zero()); - let validator_point_part = Perbill::from_rational_approximation( - validator_point, - era_reward_points.total, - ); - reward = reward.saturating_add( - validator_point_part - .saturating_mul(Perbill::one().saturating_sub(commission)) - .saturating_mul(nominator_exposure_part) - ); - } - } - - if let Some(imbalance) = Self::make_payout(&nominator_ledger.stash, reward * era_payout) { - Self::deposit_event(RawEvent::Reward(ctrl, imbalance.peek())); - } - - Ok(()) - } - - fn do_payout_validator(ctrl: T::AccountId, era: EraIndex) -> DispatchResult { - // If migrate_era is not populated, then you should use `payout_stakers` - let migrate_era = MigrateEra::get().ok_or(Error::::InvalidEraToReward)?; - // This payout mechanism will only work for eras before the migration. - // Subsequent payouts should use `payout_stakers`. - ensure!(era < migrate_era, Error::::InvalidEraToReward); - let current_era = CurrentEra::get().ok_or(Error::::InvalidEraToReward)?; - ensure!(era <= current_era, Error::::InvalidEraToReward); - let history_depth = Self::history_depth(); - ensure!(era >= current_era.saturating_sub(history_depth), Error::::InvalidEraToReward); - - // Note: if era has no reward to be claimed, era may be future. better not to update - // `ledger.last_reward` in this case. - let era_payout = >::get(&era) - .ok_or_else(|| Error::::InvalidEraToReward)?; - - let mut ledger = >::get(&ctrl).ok_or_else(|| Error::::NotController)?; - - ensure!( - Self::era_election_status().is_closed() || Self::payee(&ledger.stash) != RewardDestination::Staked, - Error::::CallNotAllowed, - ); - - ledger.claimed_rewards.retain(|&x| x >= current_era.saturating_sub(history_depth)); - match ledger.claimed_rewards.binary_search(&era) { - Ok(_) => Err(Error::::AlreadyClaimed)?, - Err(pos) => ledger.claimed_rewards.insert(pos, era), - } - - >::insert(&ctrl, &ledger); - - let era_reward_points = >::get(&era); - let commission = Self::eras_validator_prefs(&era, &ledger.stash).commission; - let exposure = >::get(&era, &ledger.stash); - - let exposure_part = Perbill::from_rational_approximation( - exposure.own, - exposure.total, - ); - let validator_point = era_reward_points.individual.get(&ledger.stash) - .map(|points| *points) - .unwrap_or_else(|| Zero::zero()); - let validator_point_part = Perbill::from_rational_approximation( - validator_point, - era_reward_points.total, - ); - let reward = validator_point_part.saturating_mul( - commission.saturating_add( - Perbill::one().saturating_sub(commission).saturating_mul(exposure_part) - ) - ); - - if let Some(imbalance) = Self::make_payout(&ledger.stash, reward * era_payout) { - Self::deposit_event(RawEvent::Reward(ctrl, imbalance.peek())); - } - - Ok(()) - } - fn do_payout_stakers( validator_stash: T::AccountId, era: EraIndex, @@ -2121,13 +2362,6 @@ impl Module { let history_depth = Self::history_depth(); ensure!(era >= current_era.saturating_sub(history_depth), Error::::InvalidEraToReward); - // If there was no migration, then this function is always valid. - if let Some(migrate_era) = MigrateEra::get() { - // This payout mechanism will only work for eras on and after the migration. - // Payouts before then should use `payout_nominator`/`payout_validator`. - ensure!(migrate_era <= era, Error::::InvalidEraToReward); - } - // Note: if era has no reward to be claimed, era may be future. better not to update // `ledger.claimed_rewards` in this case. let era_payout = >::get(&era) @@ -2196,7 +2430,7 @@ impl Module { } // Lets now calculate how this is split to the nominators. - // Sort nominators by highest to lowest exposure, but only keep `max_nominator_payouts` of them. + // Reward only the clipped exposures. Note this is not necessarily sorted. for nominator in exposure.others.iter() { let nominator_exposure_part = Perbill::from_rational_approximation( nominator.value, @@ -2213,8 +2447,9 @@ impl Module { Ok(()) } - /// Update the ledger for a controller. This will also update the stash lock. The lock will - /// will lock the entire funds except paying for further transactions. + /// Update the ledger for a controller. + /// + /// This will also update the stash lock. fn update_ledger( controller: &T::AccountId, ledger: &StakingLedger> @@ -2241,7 +2476,7 @@ impl Module { match dest { RewardDestination::Controller => Self::bonded(stash) .and_then(|controller| - T::Currency::deposit_into_existing(&controller, amount).ok() + Some(T::Currency::deposit_creating(&controller, amount)) ), RewardDestination::Stash => T::Currency::deposit_into_existing(stash, amount).ok(), @@ -2276,16 +2511,19 @@ impl Module { Forcing::ForceAlways => (), Forcing::NotForcing if era_length >= T::SessionsPerEra::get() => (), _ => { - // not forcing, not a new era either. If final, set the flag. - if era_length + 1 >= T::SessionsPerEra::get() { + // Either `ForceNone`, or `NotForcing && era_length < T::SessionsPerEra::get()`. + if era_length + 1 == T::SessionsPerEra::get() { IsCurrentSessionFinal::put(true); + } else if era_length >= T::SessionsPerEra::get() { + // Should only happen when we are ready to trigger an era but we have ForceNone, + // otherwise previous arm would short circuit. + Self::close_election_window(); } return None }, } // new era. - IsCurrentSessionFinal::put(false); Self::new_era(session_index) } else { // Set initial era @@ -2294,31 +2532,36 @@ impl Module { } /// Basic and cheap checks that we perform in validate unsigned, and in the execution. - pub fn pre_dispatch_checks(score: PhragmenScore, era: EraIndex) -> Result<(), Error> { + /// + /// State reads: ElectionState, CurrentEr, QueuedScore. + /// + /// This function does weight refund in case of errors, which is based upon the fact that it is + /// called at the very beginning of the call site's function. + pub fn pre_dispatch_checks(score: ElectionScore, era: EraIndex) -> DispatchResultWithPostInfo { // discard solutions that are not in-time // check window open ensure!( Self::era_election_status().is_open(), - Error::::PhragmenEarlySubmission, + Error::::OffchainElectionEarlySubmission.with_weight(T::DbWeight::get().reads(1)), ); // check current era. if let Some(current_era) = Self::current_era() { ensure!( current_era == era, - Error::::PhragmenEarlySubmission, + Error::::OffchainElectionEarlySubmission.with_weight(T::DbWeight::get().reads(2)), ) } // assume the given score is valid. Is it better than what we have on-chain, if we have any? if let Some(queued_score) = Self::queued_score() { ensure!( - is_score_better(queued_score, score), - Error::::PhragmenWeakSubmission, + is_score_better(score, queued_score, T::MinSolutionScoreBump::get()), + Error::::OffchainElectionWeakSubmission.with_weight(T::DbWeight::get().reads(3)), ) } - Ok(()) + Ok(None.into()) } /// Checks a given solution and if correct and improved, writes it on chain as the queued result @@ -2327,22 +2570,47 @@ impl Module { winners: Vec, compact_assignments: CompactAssignments, compute: ElectionCompute, - claimed_score: PhragmenScore, + claimed_score: ElectionScore, era: EraIndex, - ) -> Result<(), Error> { + election_size: ElectionSize, + ) -> DispatchResultWithPostInfo { // Do the basic checks. era, claimed score and window open. Self::pre_dispatch_checks(claimed_score, era)?; + // the weight that we will refund in case of a correct submission. We compute this now + // because the data needed for it will be consumed further down. + let adjusted_weight = weight::weight_for_correct_submit_solution::( + &winners, + &compact_assignments, + &election_size, + ); // Check that the number of presented winners is sane. Most often we have more candidates - // that we need. Then it should be Self::validator_count(). Else it should be all the + // than we need. Then it should be `Self::validator_count()`. Else it should be all the // candidates. - let snapshot_length = >::decode_len() + let snapshot_validators_length = >::decode_len() + .map(|l| l as u32) .ok_or_else(|| Error::::SnapshotUnavailable)?; + // size of the solution must be correct. + ensure!( + snapshot_validators_length == u32::from(election_size.validators), + Error::::OffchainElectionBogusElectionSize, + ); + // check the winner length only here and when we know the length of the snapshot validators // length. - let desired_winners = Self::validator_count().min(snapshot_length as u32); - ensure!(winners.len() as u32 == desired_winners, Error::::PhragmenBogusWinnerCount); + let desired_winners = Self::validator_count().min(snapshot_validators_length); + ensure!(winners.len() as u32 == desired_winners, Error::::OffchainElectionBogusWinnerCount); + + let snapshot_nominators_len = >::decode_len() + .map(|l| l as u32) + .ok_or_else(|| Error::::SnapshotUnavailable)?; + + // rest of the size of the solution must be correct. + ensure!( + snapshot_nominators_len == election_size.nominators, + Error::::OffchainElectionBogusElectionSize, + ); // decode snapshot validators. let snapshot_validators = Self::snapshot_validators() @@ -2353,11 +2621,11 @@ impl Module { // NOTE: at the moment, since staking is explicitly blocking any offence until election // is closed, we don't check here if the account id at `snapshot_validators[widx]` is // actually a validator. If this ever changes, this loop needs to also check this. - snapshot_validators.get(widx as usize).cloned().ok_or(Error::::PhragmenBogusWinner) + snapshot_validators.get(widx as usize).cloned().ok_or(Error::::OffchainElectionBogusWinner) }).collect::, Error>>()?; // decode the rest of the snapshot. - let snapshot_nominators = >::snapshot_nominators() + let snapshot_nominators = Self::snapshot_nominators() .ok_or(Error::::SnapshotUnavailable)?; // helpers @@ -2375,7 +2643,7 @@ impl Module { ).map_err(|e| { // log the error since it is not propagated into the runtime error. log!(warn, "💸 un-compacting solution failed due to {:?}", e); - Error::::PhragmenBogusCompact + Error::::OffchainElectionBogusCompact })?; // check all nominators actually including the claimed vote. Also check correct self votes. @@ -2391,7 +2659,7 @@ impl Module { // have bigger problems. log!(error, "💸 detected an error in the staking locking and snapshot."); // abort. - return Err(Error::::PhragmenBogusNominator); + return Err(Error::::OffchainElectionBogusNominator.into()); } if !is_validator { @@ -2408,31 +2676,31 @@ impl Module { // each target in the provided distribution must be actually nominated by the // nominator after the last non-zero slash. if nomination.targets.iter().find(|&tt| tt == t).is_none() { - return Err(Error::::PhragmenBogusNomination); + return Err(Error::::OffchainElectionBogusNomination.into()); } if ::SlashingSpans::get(&t).map_or( false, |spans| nomination.submitted_in < spans.last_nonzero_slash(), ) { - return Err(Error::::PhragmenSlashedNomination); + return Err(Error::::OffchainElectionSlashedNomination.into()); } } } else { // a self vote - ensure!(distribution.len() == 1, Error::::PhragmenBogusSelfVote); - ensure!(distribution[0].0 == *who, Error::::PhragmenBogusSelfVote); + ensure!(distribution.len() == 1, Error::::OffchainElectionBogusSelfVote); + ensure!(distribution[0].0 == *who, Error::::OffchainElectionBogusSelfVote); // defensive only. A compact assignment of length one does NOT encode the weight and // it is always created to be 100%. ensure!( distribution[0].1 == OffchainAccuracy::one(), - Error::::PhragmenBogusSelfVote, + Error::::OffchainElectionBogusSelfVote, ); } } // convert into staked assignments. - let staked_assignments = sp_phragmen::assignment_ratio_to_staked( + let staked_assignments = sp_npos_elections::assignment_ratio_to_staked( assignments, Self::slashable_balance_of_vote_weight, ); @@ -2445,18 +2713,19 @@ impl Module { &staked_assignments, ); // This technically checks that all targets in all nominators were among the winners. - ensure!(num_error == 0, Error::::PhragmenBogusEdge); + ensure!(num_error == 0, Error::::OffchainElectionBogusEdge); // Check if the score is the same as the claimed one. let submitted_score = evaluate_support(&supports); - ensure!(submitted_score == claimed_score, Error::::PhragmenBogusScore); + ensure!(submitted_score == claimed_score, Error::::OffchainElectionBogusScore); // At last, alles Ok. Exposures and store the result. let exposures = Self::collect_exposure(supports); log!( info, - "💸 A better solution (with compute {:?}) has been validated and stored on chain.", + "💸 A better solution (with compute {:?} and score {:?}) has been validated and stored on chain.", compute, + submitted_score, ); // write new results. @@ -2467,8 +2736,10 @@ impl Module { }); QueuedScore::put(submitted_score); - Ok(()) + // emit event. + Self::deposit_event(RawEvent::SolutionStored(compute)); + Ok(Some(adjusted_weight).into()) } /// Start a session potentially starting an era. @@ -2586,6 +2857,17 @@ impl Module { maybe_new_validators } + + /// Remove all the storage items associated with the election. + fn close_election_window() { + // Close window. + >::put(ElectionStatus::Closed); + // Kill snapshots. + Self::kill_stakers_snapshot(); + // Don't track final session. + IsCurrentSessionFinal::put(false); + } + /// Select the new validator set at the end of the era. /// /// Runs [`try_do_phragmen`] and updates the following storage items: @@ -2606,12 +2888,9 @@ impl Module { elected_stashes, exposures, compute, - }) = Self::try_do_phragmen() { - // We have chosen the new validator set. Submission is no longer allowed. - >::put(ElectionStatus::Closed); - - // kill the snapshots. - Self::kill_stakers_snapshot(); + }) = Self::try_do_election() { + // Totally close the election round and data. + Self::close_election_window(); // Populate Stakers and write slot stake. let mut total_stake: BalanceOf = Zero::zero(); @@ -2622,7 +2901,7 @@ impl Module { let mut exposure_clipped = exposure; let clipped_max_len = T::MaxNominatorRewardedPerValidator::get() as usize; if exposure_clipped.others.len() > clipped_max_len { - exposure_clipped.others.sort_unstable_by(|a, b| a.value.cmp(&b.value).reverse()); + exposure_clipped.others.sort_by(|a, b| a.value.cmp(&b.value).reverse()); exposure_clipped.others.truncate(clipped_max_len); } >::insert(¤t_era, &stash, exposure_clipped); @@ -2655,12 +2934,12 @@ impl Module { } /// Select a new validator set from the assembled stakers and their role preferences. It tries - /// first to peek into [`QueuedElected`]. Otherwise, it runs a new phragmen. + /// first to peek into [`QueuedElected`]. Otherwise, it runs a new on-chain phragmen election. /// /// If [`QueuedElected`] and [`QueuedScore`] exists, they are both removed. No further storage /// is updated. - fn try_do_phragmen() -> Option>> { - // a phragmen result from either a stored submission or locally executed one. + fn try_do_election() -> Option>> { + // an election result from either a stored submission or locally executed one. let next_result = >::take().or_else(|| Self::do_phragmen_with_post_processing::(ElectionCompute::OnChain) ); @@ -2672,11 +2951,11 @@ impl Module { next_result } - /// Execute phragmen and return the new results. The edge weights are processed into support + /// Execute election and return the new results. The edge weights are processed into support /// values. /// - /// This is basically a wrapper around [`do_phragmen`] which translates `PhragmenResult` into - /// `ElectionResult`. + /// This is basically a wrapper around [`do_phragmen`] which translates + /// `PrimitiveElectionResult` into `ElectionResult`. /// /// No storage item is updated. fn do_phragmen_with_post_processing(compute: ElectionCompute) @@ -2691,7 +2970,7 @@ impl Module { .collect::>(); let assignments = phragmen_result.assignments; - let staked_assignments = sp_phragmen::assignment_ratio_to_staked( + let staked_assignments = sp_npos_elections::assignment_ratio_to_staked( assignments, Self::slashable_balance_of_vote_weight, ); @@ -2722,13 +3001,13 @@ impl Module { } } - /// Execute phragmen and return the new results. No post-processing is applied and the raw edge - /// weights are returned. + /// Execute phragmen election and return the new results. No post-processing is applied and the + /// raw edge weights are returned. /// /// Self votes are added and nominations before the most recent slashing span are reaped. /// /// No storage item is updated. - fn do_phragmen() -> Option> { + fn do_phragmen() -> Option> { let mut all_nominators: Vec<(T::AccountId, VoteWeight, Vec)> = Vec::new(); let mut all_validators = Vec::new(); for (validator, _) in >::iter() { @@ -2757,7 +3036,7 @@ impl Module { (n, s, ns) })); - elect::<_, Accuracy>( + seq_phragmen::<_, Accuracy>( Self::validator_count() as usize, Self::minimum_validator_count().max(1) as usize, all_validators, @@ -2765,14 +3044,14 @@ impl Module { ) } - /// Consume a set of [`Supports`] from [`sp_phragmen`] and collect them into a [`Exposure`] + /// Consume a set of [`Supports`] from [`sp_npos_elections`] and collect them into a [`Exposure`] fn collect_exposure(supports: SupportMap) -> Vec<(T::AccountId, Exposure>)> { let to_balance = |e: ExtendedBalance| >>::convert(e); supports.into_iter().map(|(validator, support)| { // build `struct exposure` from `support` - let mut others = Vec::new(); + let mut others = Vec::with_capacity(support.voters.len()); let mut own: BalanceOf = Zero::zero(); let mut total: BalanceOf = Zero::zero(); support.voters @@ -2804,16 +3083,18 @@ impl Module { /// This is called: /// - after a `withdraw_unbond()` call that frees all of a stash's bonded balance. /// - through `reap_stash()` if the balance has fallen to zero (through slashing). - fn kill_stash(stash: &T::AccountId) -> DispatchResult { - let controller = Bonded::::take(stash).ok_or(Error::::NotStash)?; + fn kill_stash(stash: &T::AccountId, num_slashing_spans: u32) -> DispatchResult { + let controller = >::get(stash).ok_or(Error::::NotStash)?; + + slashing::clear_stash_metadata::(stash, num_slashing_spans)?; + + >::remove(stash); >::remove(&controller); >::remove(stash); >::remove(stash); >::remove(stash); - slashing::clear_stash_metadata::(stash); - system::Module::::dec_ref(stash); Ok(()) @@ -2992,7 +3273,9 @@ impl Convert> } /// This is intended to be used with `FilterHistoricalOffences`. -impl OnOffenceHandler> for Module where +impl + OnOffenceHandler, Weight> +for Module where T: pallet_session::Trait::AccountId>, T: pallet_session::historical::Trait< FullIdentification = Exposure<::AccountId, BalanceOf>, @@ -3000,24 +3283,32 @@ impl OnOffenceHandler, T::SessionHandler: pallet_session::SessionHandler<::AccountId>, T::SessionManager: pallet_session::SessionManager<::AccountId>, - T::ValidatorIdOf: Convert<::AccountId, Option<::AccountId>> + T::ValidatorIdOf: Convert< + ::AccountId, + Option<::AccountId>, + >, { fn on_offence( offenders: &[OffenceDetails>], slash_fraction: &[Perbill], slash_session: SessionIndex, - ) -> Result<(), ()> { + ) -> Result { if !Self::can_report() { return Err(()) } let reward_proportion = SlashRewardFraction::get(); + let mut consumed_weight: Weight = 0; + let mut add_db_reads_writes = |reads, writes| { + consumed_weight += T::DbWeight::get().reads_writes(reads, writes); + }; let active_era = { let active_era = Self::active_era(); + add_db_reads_writes(1, 0); if active_era.is_none() { // this offence need not be re-submitted. - return Ok(()) + return Ok(consumed_weight) } active_era.expect("value checked not to be `None`; qed").index }; @@ -3026,6 +3317,7 @@ impl OnOffenceHandler OnOffenceHandler return Ok(()), // before bonding period. defensive - should be filtered out. Some(&(ref slash_era, _)) => *slash_era, + // before bonding period. defensive - should be filtered out. + None => return Ok(consumed_weight), } }; @@ -3048,14 +3342,18 @@ impl OnOffenceHandler OnOffenceHandler(unapplied); + { + let slash_cost = (6, 5); + let reward_cost = (2, 2); + add_db_reads_writes( + (1 + nominators_len) * slash_cost.0 + reward_cost.0 * reporters_len, + (1 + nominators_len) * slash_cost.1 + reward_cost.1 * reporters_len + ); + } } else { // defer to end of some `slash_defer_duration` from now. ::UnappliedSlashes::mutate( active_era, move |for_later| for_later.push(unapplied), ); + add_db_reads_writes(1, 1); } + } else { + add_db_reads_writes(4 /* fetch_spans */, 5 /* kick_out_if_recent */) } } - Ok(()) + Ok(consumed_weight) } fn can_report() -> bool { @@ -3117,11 +3434,9 @@ impl ReportOffence Ok(()) } } -} -impl From> for InvalidTransaction { - fn from(e: Error) -> Self { - InvalidTransaction::Custom(e.as_u8()) + fn is_known_offence(offenders: &[Offender], time_slot: &O::TimeSlot) -> bool { + R::is_known_offence(offenders, time_slot) } } @@ -3134,6 +3449,7 @@ impl frame_support::unsigned::ValidateUnsigned for Module { _, score, era, + _, ) = call { use offchain_election::DEFAULT_LONGEVITY; @@ -3146,9 +3462,14 @@ impl frame_support::unsigned::ValidateUnsigned for Module { } } - if let Err(e) = Self::pre_dispatch_checks(*score, *era) { - log!(debug, "validate unsigned pre dispatch checks failed due to {:?}.", e); - return InvalidTransaction::from(e).into(); + if let Err(error_with_post_info) = Self::pre_dispatch_checks(*score, *era) { + let invalid = to_invalid(error_with_post_info); + log!( + debug, + "validate unsigned pre dispatch checks failed due to error #{:?}.", + invalid, + ); + return invalid .into(); } log!(debug, "validateUnsigned succeeded for a solution at era {}.", era); @@ -3176,13 +3497,28 @@ impl frame_support::unsigned::ValidateUnsigned for Module { } } - fn pre_dispatch(_: &Self::Call) -> Result<(), TransactionValidityError> { - // IMPORTANT NOTE: By default, a sane `pre-dispatch` should always do the same checks as - // `validate_unsigned` and overriding this should be done with care. this module has only - // one unsigned entry point, in which we call into `>::pre_dispatch_checks()` - // which is all the important checks that we do in `validate_unsigned`. Hence, we can safely - // override this to save some time. - Ok(()) + fn pre_dispatch(call: &Self::Call) -> Result<(), TransactionValidityError> { + if let Call::submit_election_solution_unsigned( + _, + _, + score, + era, + _, + ) = call { + // IMPORTANT NOTE: These checks are performed in the dispatch call itself, yet we need + // to duplicate them here to prevent a block producer from putting a previously + // validated, yet no longer valid solution on chain. + // OPTIMISATION NOTE: we could skip this in the `submit_election_solution_unsigned` + // since we already do it here. The signed version needs it though. Yer for now we keep + // this duplicate check here so both signed and unsigned can use a singular + // `check_and_replace_solution`. + Self::pre_dispatch_checks(*score, *era) + .map(|_| ()) + .map_err(to_invalid) + .map_err(Into::into) + } else { + Err(InvalidTransaction::Call.into()) + } } } @@ -3190,3 +3526,14 @@ impl frame_support::unsigned::ValidateUnsigned for Module { fn is_sorted_and_unique(list: &[u32]) -> bool { list.windows(2).all(|w| w[0] < w[1]) } + +/// convert a DispatchErrorWithPostInfo to a custom InvalidTransaction with the inner code being the +/// error number. +fn to_invalid(error_with_post_info: DispatchErrorWithPostInfo) -> InvalidTransaction { + let error = error_with_post_info.error; + let error_number = match error { + DispatchError::Module { error, ..} => error, + _ => 0, + }; + InvalidTransaction::Custom(error_number) +} diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index b09d026eb3eea609d38dbd4f8c7ff176270e37b6..dcdacfbaacb04967c744ccb40aeee294e8c48e8c 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -1,22 +1,23 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Test utilities -use std::{collections::{HashSet, HashMap}, cell::RefCell}; +use std::{collections::HashSet, cell::RefCell}; use sp_runtime::Perbill; use sp_runtime::curve::PiecewiseLinear; use sp_runtime::traits::{IdentityLookup, Convert, SaturatedConversion, Zero}; @@ -27,16 +28,16 @@ use frame_support::{ assert_ok, impl_outer_origin, parameter_types, impl_outer_dispatch, impl_outer_event, StorageValue, StorageMap, StorageDoubleMap, IterableStorageMap, traits::{Currency, Get, FindAuthor, OnFinalize, OnInitialize}, - weights::Weight, + weights::{Weight, constants::RocksDbWeight}, }; use sp_io; -use sp_phragmen::{ - build_support_map, evaluate_support, reduce, ExtendedBalance, StakedAssignment, PhragmenScore, +use sp_npos_elections::{ + build_support_map, evaluate_support, reduce, ExtendedBalance, StakedAssignment, ElectionScore, VoteWeight, }; use crate::*; -const INIT_TIMESTAMP: u64 = 30_000; +pub const INIT_TIMESTAMP: u64 = 30_000; /// The AccountId alias in this test module. pub(crate) type AccountId = u64; @@ -152,7 +153,7 @@ impl Get for MaxIterations { } impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } impl_outer_dispatch! { @@ -199,6 +200,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; type BlockNumber = BlockNumber; @@ -211,9 +213,10 @@ impl frame_system::Trait for Test { type Event = MetaEvent; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = (); + type DbWeight = RocksDbWeight; type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -221,6 +224,7 @@ impl frame_system::Trait for Test { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl pallet_balances::Trait for Test { type Balance = Balance; @@ -228,6 +232,7 @@ impl pallet_balances::Trait for Test { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { pub const Offset: BlockNumber = 0; @@ -249,6 +254,7 @@ impl pallet_session::Trait for Test { type ValidatorIdOf = crate::StashOf; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; type NextSessionRotation = pallet_session::PeriodicSessions; + type WeightInfo = (); } impl pallet_session::historical::Trait for Test { @@ -268,6 +274,7 @@ impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } pallet_staking_reward_curve::build! { const I_NPOS: PiecewiseLinear<'static> = curve!( @@ -284,6 +291,7 @@ parameter_types! { pub const RewardCurve: &'static PiecewiseLinear<'static> = &I_NPOS; pub const MaxNominatorRewardedPerValidator: u32 = 64; pub const UnsignedPriority: u64 = 1 << 20; + pub const MinSolutionScoreBump: Perbill = Perbill::zero(); } thread_local! { @@ -319,8 +327,10 @@ impl Trait for Test { type ElectionLookahead = ElectionLookahead; type Call = Call; type MaxIterations = MaxIterations; + type MinSolutionScoreBump = MinSolutionScoreBump; type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type UnsignedPriority = UnsignedPriority; + type WeightInfo = (); } impl frame_system::offchain::SendTransactionTypes for Test where @@ -427,7 +437,7 @@ impl ExtBuilder { self.max_offchain_iterations = iterations; self } - pub fn offchain_phragmen_ext(self) -> Self { + pub fn offchain_election_ext(self) -> Self { self.session_per_era(4) .session_length(5) .election_lookahead(3) @@ -763,11 +773,23 @@ pub(crate) fn on_offence_now( on_offence_in_era(offenders, slash_fraction, now) } +pub(crate) fn add_slash(who: &AccountId) { + on_offence_now( + &[ + OffenceDetails { + offender: (who.clone(), Staking::eras_stakers(Staking::active_era().unwrap().index, who.clone())), + reporters: vec![], + }, + ], + &[Perbill::from_percent(10)], + ); +} + // winners will be chosen by simply their unweighted total backing stake. Nominator stake is // distributed evenly. -pub(crate) fn horrible_phragmen_with_post_processing( +pub(crate) fn horrible_npos_solution( do_reduce: bool, -) -> (CompactAssignments, Vec, PhragmenScore) { +) -> (CompactAssignments, Vec, ElectionScore) { let mut backing_stake_of: BTreeMap = BTreeMap::new(); // self stake @@ -839,7 +861,11 @@ pub(crate) fn horrible_phragmen_with_post_processing( let support = build_support_map::(&winners, &staked_assignment).0; let score = evaluate_support(&support); - assert!(sp_phragmen::is_score_better(score, better_score)); + assert!(sp_npos_elections::is_score_better::( + better_score, + score, + MinSolutionScoreBump::get(), + )); score }; @@ -859,7 +885,7 @@ pub(crate) fn horrible_phragmen_with_post_processing( // convert back to ratio assignment. This takes less space. let assignments_reduced = - sp_phragmen::assignment_staked_to_ratio::(staked_assignment); + sp_npos_elections::assignment_staked_to_ratio::(staked_assignment); let compact = CompactAssignments::from_assignment(assignments_reduced, nominator_index, validator_index) @@ -877,13 +903,13 @@ pub(crate) fn prepare_submission_with( do_reduce: bool, iterations: usize, tweak: impl FnOnce(&mut Vec>), -) -> (CompactAssignments, Vec, PhragmenScore) { - // run phragmen on the default stuff. - let sp_phragmen::PhragmenResult { +) -> (CompactAssignments, Vec, ElectionScore) { + // run election on the default stuff. + let sp_npos_elections::ElectionResult { winners, assignments, } = Staking::do_phragmen::().unwrap(); - let winners = sp_phragmen::to_without_backing(winners); + let winners = sp_npos_elections::to_without_backing(winners); let stake_of = |who: &AccountId| -> VoteWeight { >::convert( @@ -891,11 +917,11 @@ pub(crate) fn prepare_submission_with( ) }; - let mut staked = sp_phragmen::assignment_ratio_to_staked(assignments, stake_of); + let mut staked = sp_npos_elections::assignment_ratio_to_staked(assignments, stake_of); let (mut support_map, _) = build_support_map::(&winners, &staked); if iterations > 0 { - sp_phragmen::equalize( + sp_npos_elections::balance_solution( &mut staked, &mut support_map, Zero::zero(), @@ -932,11 +958,11 @@ pub(crate) fn prepare_submission_with( ) }; - let assignments_reduced = sp_phragmen::assignment_staked_to_ratio(staked); + let assignments_reduced = sp_npos_elections::assignment_staked_to_ratio(staked); // re-compute score by converting, yet again, into staked type let score = { - let staked = sp_phragmen::assignment_ratio_to_staked( + let staked = sp_npos_elections::assignment_ratio_to_staked( assignments_reduced.clone(), Staking::slashable_balance_of_vote_weight, ); @@ -960,38 +986,6 @@ pub(crate) fn prepare_submission_with( (compact, winners, score) } -/// Make all validator and nominator request their payment -pub(crate) fn make_all_reward_payment_before_migration(era: EraIndex) { - let validators_with_reward = ErasRewardPoints::::get(era).individual.keys() - .cloned() - .collect::>(); - - // reward nominators - let mut nominator_controllers = HashMap::new(); - for validator in Staking::eras_reward_points(era).individual.keys() { - let validator_exposure = Staking::eras_stakers_clipped(era, validator); - for (nom_index, nom) in validator_exposure.others.iter().enumerate() { - if let Some(nom_ctrl) = Staking::bonded(nom.who) { - nominator_controllers.entry(nom_ctrl) - .or_insert(vec![]) - .push((validator.clone(), nom_index as u32)); - } - } - } - for (nominator_controller, validators_with_nom_index) in nominator_controllers { - assert_ok!(Staking::payout_nominator( - Origin::signed(nominator_controller), - era, - validators_with_nom_index, - )); - } - - // reward validators - for validator_controller in validators_with_reward.iter().filter_map(Staking::bonded) { - assert_ok!(Staking::payout_validator(Origin::signed(validator_controller), era)); - } -} - /// Make all validator and nominator request their payment pub(crate) fn make_all_reward_payment(era: EraIndex) { let validators_with_reward = ErasRewardPoints::::get(era).individual.keys() diff --git a/frame/staking/src/offchain_election.rs b/frame/staking/src/offchain_election.rs index 2568638319394e45f72bdc844c790bd86bf3fad8..79f3a5c2d94fec73f2297e6a18de804c8d0f7d2b 100644 --- a/frame/staking/src/offchain_election.rs +++ b/frame/staking/src/offchain_election.rs @@ -1,54 +1,56 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Helpers for offchain worker election. use codec::Decode; use crate::{ Call, CompactAssignments, Module, NominatorIndex, OffchainAccuracy, Trait, ValidatorIndex, + ElectionSize, }; use frame_system::offchain::SubmitTransaction; -use sp_phragmen::{ - build_support_map, evaluate_support, reduce, Assignment, ExtendedBalance, PhragmenResult, - PhragmenScore, equalize, +use sp_npos_elections::{ + build_support_map, evaluate_support, reduce, Assignment, ExtendedBalance, ElectionResult, + ElectionScore, balance_solution, }; use sp_runtime::offchain::storage::StorageValueRef; use sp_runtime::{PerThing, RuntimeDebug, traits::{TrailingZeroInput, Zero}}; -use frame_support::{debug, traits::Get}; +use frame_support::traits::Get; use sp_std::{convert::TryInto, prelude::*}; /// Error types related to the offchain election machinery. #[derive(RuntimeDebug)] pub enum OffchainElectionError { - /// Phragmen election returned None. This means less candidate that minimum number of needed + /// election returned None. This means less candidate that minimum number of needed /// validators were present. The chain is in trouble and not much that we can do about it. ElectionFailed, /// Submission to the transaction pool failed. PoolSubmissionFailed, /// The snapshot data is not available. SnapshotUnavailable, - /// Error from phragmen crate. This usually relates to compact operation. - PhragmenError(sp_phragmen::Error), + /// Error from npos-election crate. This usually relates to compact operation. + InternalElectionError(sp_npos_elections::Error), /// One of the computed winners is invalid. InvalidWinner, } -impl From for OffchainElectionError { - fn from(e: sp_phragmen::Error) -> Self { - Self::PhragmenError(e) +impl From for OffchainElectionError { + fn from(e: sp_npos_elections::Error) -> Self { + Self::InternalElectionError(e) } } @@ -105,14 +107,14 @@ pub(crate) fn set_check_offchain_execution_status( /// unsigned transaction, without any signature. pub(crate) fn compute_offchain_election() -> Result<(), OffchainElectionError> { // compute raw solution. Note that we use `OffchainAccuracy`. - let PhragmenResult { + let ElectionResult { winners, assignments, } = >::do_phragmen::() .ok_or(OffchainElectionError::ElectionFailed)?; // process and prepare it for submission. - let (winners, compact, score) = prepare_submission::(assignments, winners, true)?; + let (winners, compact, score, size) = prepare_submission::(assignments, winners, true)?; // defensive-only: current era can never be none except genesis. let current_era = >::current_era().unwrap_or_default(); @@ -123,20 +125,27 @@ pub(crate) fn compute_offchain_election() -> Result<(), OffchainElecti compact, score, current_era, + size, ).into(); SubmitTransaction::>::submit_unsigned_transaction(call) .map_err(|_| OffchainElectionError::PoolSubmissionFailed) } -/// Takes a phragmen result and spits out some data that can be submitted to the chain. + +/// Takes an election result and spits out some data that can be submitted to the chain. /// /// This does a lot of stuff; read the inline comments. pub fn prepare_submission( assignments: Vec>, winners: Vec<(T::AccountId, ExtendedBalance)>, do_reduce: bool, -) -> Result<(Vec, CompactAssignments, PhragmenScore), OffchainElectionError> where +) -> Result<( + Vec, + CompactAssignments, + ElectionScore, + ElectionSize, +), OffchainElectionError> where ExtendedBalance: From<::Inner>, { // make sure that the snapshot is available. @@ -160,26 +169,26 @@ pub fn prepare_submission( }; // Clean winners. - let winners = sp_phragmen::to_without_backing(winners); + let winners = sp_npos_elections::to_without_backing(winners); // convert into absolute value and to obtain the reduced version. - let mut staked = sp_phragmen::assignment_ratio_to_staked( + let mut staked = sp_npos_elections::assignment_ratio_to_staked( assignments, >::slashable_balance_of_vote_weight, ); let (mut support_map, _) = build_support_map::(&winners, &staked); - // equalize a random number of times. + // balance a random number of times. let iterations_executed = match T::MaxIterations::get() { 0 => { - // Don't run equalize at all + // Don't run balance_solution at all 0 } iterations @ _ => { let seed = sp_io::offchain::random_seed(); let iterations = ::decode(&mut TrailingZeroInput::new(seed.as_ref())) .expect("input is padded with zeroes; qed") % iterations.saturating_add(1); - equalize( + balance_solution( &mut staked, &mut support_map, Zero::zero(), @@ -194,7 +203,8 @@ pub fn prepare_submission( } // Convert back to ratio assignment. This takes less space. - let low_accuracy_assignment = sp_phragmen::assignment_staked_to_ratio(staked); + let low_accuracy_assignment = sp_npos_elections::assignment_staked_to_ratio_normalized(staked) + .map_err(|e| OffchainElectionError::from(e))?; // convert back to staked to compute the score in the receiver's accuracy. This can be done // nicer, for now we do it as such since this code is not time-critical. This ensure that the @@ -205,7 +215,7 @@ pub fn prepare_submission( // assignment set is also all multiples of this value. After reduce, this no longer holds. Hence // converting to ratio thereafter is not trivially reversible. let score = { - let staked = sp_phragmen::assignment_ratio_to_staked( + let staked = sp_npos_elections::assignment_ratio_to_staked( low_accuracy_assignment.clone(), >::slashable_balance_of_vote_weight, ); @@ -234,12 +244,18 @@ pub fn prepare_submission( } } - debug::native::debug!( - target: "staking", + // both conversions are safe; snapshots are not created if they exceed. + let size = ElectionSize { + validators: snapshot_validators.len() as ValidatorIndex, + nominators: snapshot_nominators.len() as NominatorIndex, + }; + + crate::log!( + info, "prepared solution after {} equalization iterations with score {:?}", iterations_executed, score, ); - Ok((winners_indexed, compact, score)) + Ok((winners_indexed, compact, score, size)) } diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs index 26f0828989d733bfc720de288f33f0efcafd462d..af9a92f16a4636def4dcb99687ceabed183ae137 100644 --- a/frame/staking/src/slashing.rs +++ b/frame/staking/src/slashing.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! A slashing implementation for NPoS systems. //! @@ -50,11 +51,11 @@ use super::{ EraIndex, Trait, Module, Store, BalanceOf, Exposure, Perbill, SessionInterface, - NegativeImbalanceOf, UnappliedSlash, + NegativeImbalanceOf, UnappliedSlash, Error, }; -use sp_runtime::{traits::{Zero, Saturating}, RuntimeDebug}; +use sp_runtime::{traits::{Zero, Saturating}, RuntimeDebug, DispatchResult}; use frame_support::{ - StorageMap, StorageDoubleMap, + StorageMap, StorageDoubleMap, ensure, traits::{Currency, OnUnbalanced, Imbalance}, }; use sp_std::vec::Vec; @@ -100,7 +101,7 @@ pub struct SlashingSpans { impl SlashingSpans { // creates a new record of slashing spans for a stash, starting at the beginning // of the bonding period, relative to now. - fn new(window_start: EraIndex) -> Self { + pub(crate) fn new(window_start: EraIndex) -> Self { SlashingSpans { span_index: 0, last_start: window_start, @@ -115,7 +116,7 @@ impl SlashingSpans { // update the slashing spans to reflect the start of a new span at the era after `now` // returns `true` if a new span was started, `false` otherwise. `false` indicates // that internal state is unchanged. - fn end_span(&mut self, now: EraIndex) -> bool { + pub(crate) fn end_span(&mut self, now: EraIndex) -> bool { let next_start = now + 1; if next_start <= self.last_start { return false } @@ -369,7 +370,7 @@ fn slash_nominators( let mut era_slash = as Store>::NominatorSlashInEra::get( &slash_era, stash, - ).unwrap_or(Zero::zero()); + ).unwrap_or_else(|| Zero::zero()); era_slash += own_slash_difference; @@ -547,12 +548,19 @@ pub(crate) fn clear_era_metadata(obsolete_era: EraIndex) { } /// Clear slashing metadata for a dead account. -pub(crate) fn clear_stash_metadata(stash: &T::AccountId) { - let spans = match as Store>::SlashingSpans::take(stash) { - None => return, +pub(crate) fn clear_stash_metadata( + stash: &T::AccountId, + num_slashing_spans: u32, +) -> DispatchResult { + let spans = match as Store>::SlashingSpans::get(stash) { + None => return Ok(()), Some(s) => s, }; + ensure!(num_slashing_spans as usize >= spans.iter().count(), Error::::IncorrectSlashingSpans); + + as Store>::SlashingSpans::remove(stash); + // kill slashing-span metadata for account. // // this can only happen while the account is staked _if_ they are completely slashed. @@ -561,6 +569,8 @@ pub(crate) fn clear_stash_metadata(stash: &T::AccountId) { for span in spans.iter() { as Store>::SpanSlash::remove(&(stash.clone(), span.index)); } + + Ok(()) } // apply the slash to a stash account, deducting any missing funds from the reward diff --git a/frame/staking/src/testing_utils.rs b/frame/staking/src/testing_utils.rs index ede14c8cf733a944999511b2e923f8dd023f3642..02acd135e63e4ea89b4e5f6645663d22454ae615 100644 --- a/frame/staking/src/testing_utils.rs +++ b/frame/staking/src/testing_utils.rs @@ -1,225 +1,180 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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. +// 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. -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Testing utils for staking. Needs the `testing-utils` feature to be enabled. -//! -//! Note that these helpers should NOT be used with the actual crate tests, but are rather designed -//! for when the module is being externally tested (i.e. fuzzing, benchmarking, e2e tests). Enabling -//! this feature in the current crate's Cargo.toml will leak all of this into a normal release -//! build. Just don't do it. +//! Testing utils for staking. Provides some common functions to setup staking state, such as +//! bonding validators, nominators, and generating different types of solutions. use crate::*; -use codec::{Decode, Encode}; -use frame_support::assert_ok; +use crate::Module as Staking; +use frame_benchmarking::{account}; use frame_system::RawOrigin; -use pallet_indices::address::Address; -use rand::Rng; -use sp_core::hashing::blake2_256; -use sp_phragmen::{ - build_support_map, evaluate_support, reduce, Assignment, PhragmenScore, StakedAssignment, -}; - -const CTRL_PREFIX: u32 = 1000; -const NOMINATOR_PREFIX: u32 = 1_000_000; - -/// A dummy suer. -pub const USER: u32 = 999_999_999; - -/// Address type of the `T` -pub type AddressOf = Address<::AccountId, u32>; - -/// Random number in the range `[a, b]`. -pub fn random(a: u32, b: u32) -> u32 { - rand::thread_rng().gen_range(a, b) +use sp_io::hashing::blake2_256; +use rand_chacha::{rand_core::{RngCore, SeedableRng}, ChaChaRng}; +use sp_npos_elections::*; + +const SEED: u32 = 0; + +/// Grab a funded user. +pub fn create_funded_user(string: &'static str, n: u32, balance_factor: u32) -> T::AccountId { + let user = account(string, n, SEED); + let balance = T::Currency::minimum_balance() * balance_factor.into(); + T::Currency::make_free_balance_be(&user, balance); + // ensure T::CurrencyToVote will work correctly. + T::Currency::issue(balance); + user } -/// Set the desired validator count, with related storage items. -pub fn set_validator_count(to_elect: u32) { - ValidatorCount::put(to_elect); - MinimumValidatorCount::put(to_elect / 2); - >::put(ElectionStatus::Closed); +/// Create a stash and controller pair. +pub fn create_stash_controller(n: u32, balance_factor: u32) + -> Result<(T::AccountId, T::AccountId), &'static str> +{ + let stash = create_funded_user::("stash", n, balance_factor); + let controller = create_funded_user::("controller", n, balance_factor); + let controller_lookup: ::Source = T::Lookup::unlookup(controller.clone()); + let reward_destination = RewardDestination::Staked; + let amount = T::Currency::minimum_balance() * (balance_factor / 10).max(1).into(); + Staking::::bond(RawOrigin::Signed(stash.clone()).into(), controller_lookup, amount, reward_destination)?; + return Ok((stash, controller)) } -/// Build an account with the given index. -pub fn account(index: u32) -> T::AccountId { - let entropy = (b"benchmark/staking", index).using_encoded(blake2_256); - T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() +/// Create a stash and controller pair, where the controller is dead, and payouts go to controller. +/// This is used to test worst case payout scenarios. +pub fn create_stash_and_dead_controller(n: u32, balance_factor: u32) + -> Result<(T::AccountId, T::AccountId), &'static str> +{ + let stash = create_funded_user::("stash", n, balance_factor); + // controller has no funds + let controller = create_funded_user::("controller", n, 0); + let controller_lookup: ::Source = T::Lookup::unlookup(controller.clone()); + let reward_destination = RewardDestination::Controller; + let amount = T::Currency::minimum_balance() * (balance_factor / 10).max(1).into(); + Staking::::bond(RawOrigin::Signed(stash.clone()).into(), controller_lookup, amount, reward_destination)?; + return Ok((stash, controller)) } -/// Build an address given Index -pub fn address(index: u32) -> AddressOf { - pallet_indices::address::Address::Id(account::(index)) +/// create `max` validators. +pub fn create_validators( + max: u32, + balance_factor: u32, +) -> Result::Source>, &'static str> { + let mut validators: Vec<::Source> = Vec::with_capacity(max as usize); + for i in 0 .. max { + let (stash, controller) = create_stash_controller::(i, balance_factor)?; + let validator_prefs = ValidatorPrefs { + commission: Perbill::from_percent(50), + }; + Staking::::validate(RawOrigin::Signed(controller).into(), validator_prefs)?; + let stash_lookup: ::Source = T::Lookup::unlookup(stash); + validators.push(stash_lookup); + } + Ok(validators) } -/// Generate signed origin from `who`. -pub fn signed(who: T::AccountId) -> T::Origin { - RawOrigin::Signed(who).into() -} +/// This function generates validators and nominators who are randomly nominating +/// `edge_per_nominator` random validators (until `to_nominate` if provided). +/// +/// Parameters: +/// - `validators`: number of bonded validators +/// - `nominators`: number of bonded nominators. +/// - `edge_per_nominator`: number of edge (vote) per nominator. +/// - `randomize_stake`: whether to randomize the stakes. +/// - `to_nominate`: if `Some(n)`, only the first `n` bonded validator are voted upon. +/// Else, all of them are considered and `edge_per_nominator` random validators are voted for. +/// +/// Return the validators choosen to be nominated. +pub fn create_validators_with_nominators_for_era( + validators: u32, + nominators: u32, + edge_per_nominator: usize, + randomize_stake: bool, + to_nominate: Option, +) -> Result::Source>, &'static str> { + let mut validators_stash: Vec<::Source> + = Vec::with_capacity(validators as usize); + let mut rng = ChaChaRng::from_seed(SEED.using_encoded(blake2_256)); + + // Create validators + for i in 0 .. validators { + let balance_factor = if randomize_stake { rng.next_u32() % 255 + 10 } else { 100u32 }; + let (v_stash, v_controller) = create_stash_controller::(i, balance_factor)?; + let validator_prefs = ValidatorPrefs { + commission: Perbill::from_percent(50), + }; + Staking::::validate(RawOrigin::Signed(v_controller.clone()).into(), validator_prefs)?; + let stash_lookup: ::Source = T::Lookup::unlookup(v_stash.clone()); + validators_stash.push(stash_lookup.clone()); + } -/// Generate signed origin from `index`. -pub fn signed_account(index: u32) -> T::Origin { - signed::(account::(index)) -} + let to_nominate = to_nominate.unwrap_or(validators_stash.len() as u32) as usize; + let validator_choosen = validators_stash[0..to_nominate].to_vec(); + + // Create nominators + for j in 0 .. nominators { + let balance_factor = if randomize_stake { rng.next_u32() % 255 + 10 } else { 100u32 }; + let (_n_stash, n_controller) = create_stash_controller::( + u32::max_value() - j, + balance_factor, + )?; + + // Have them randomly validate + let mut available_validators = validator_choosen.clone(); + let mut selected_validators: Vec<::Source> = + Vec::with_capacity(edge_per_nominator); + + for _ in 0 .. validators.min(edge_per_nominator as u32) { + let selected = rng.next_u32() as usize % available_validators.len(); + let validator = available_validators.remove(selected); + selected_validators.push(validator); + } + Staking::::nominate(RawOrigin::Signed(n_controller.clone()).into(), selected_validators)?; + } -/// Bond a validator. -pub fn bond_validator(stash: T::AccountId, ctrl: u32, val: BalanceOf) -where - T::Lookup: StaticLookup>, -{ - let _ = T::Currency::make_free_balance_be(&stash, val); - assert_ok!(>::bond( - signed::(stash), - address::(ctrl), - val, - RewardDestination::Controller - )); - assert_ok!(>::validate( - signed_account::(ctrl), - ValidatorPrefs::default() - )); -} + ValidatorCount::put(validators); -pub fn bond_nominator( - stash: T::AccountId, - ctrl: u32, - val: BalanceOf, - target: Vec>, -) where - T::Lookup: StaticLookup>, -{ - let _ = T::Currency::make_free_balance_be(&stash, val); - assert_ok!(>::bond( - signed::(stash), - address::(ctrl), - val, - RewardDestination::Controller - )); - assert_ok!(>::nominate(signed_account::(ctrl), target)); + Ok(validator_choosen) } -/// Bond `nun_validators` validators and `num_nominator` nominators with `edge_per_voter` random -/// votes per nominator. -pub fn setup_chain_stakers(num_validators: u32, num_voters: u32, edge_per_voter: u32) -where - T::Lookup: StaticLookup>, -{ - (0..num_validators).for_each(|i| { - bond_validator::( - account::(i), - i + CTRL_PREFIX, - >::from(random(1, 1000)) * T::Currency::minimum_balance(), - ); - }); - - (0..num_voters).for_each(|i| { - let mut targets: Vec> = Vec::with_capacity(edge_per_voter as usize); - let mut all_targets = (0..num_validators) - .map(|t| address::(t)) - .collect::>(); - assert!(num_validators >= edge_per_voter); - (0..edge_per_voter).for_each(|_| { - let target = all_targets.remove(random(0, all_targets.len() as u32 - 1) as usize); - targets.push(target); - }); - bond_nominator::( - account::(i + NOMINATOR_PREFIX), - i + NOMINATOR_PREFIX + CTRL_PREFIX, - >::from(random(1, 1000)) * T::Currency::minimum_balance(), - targets, - ); - }); - - >::create_stakers_snapshot(); -} /// Build a _really bad_ but acceptable solution for election. This should always yield a solution /// which has a less score than the seq-phragmen. pub fn get_weak_solution( do_reduce: bool, -) -> (Vec, CompactAssignments, PhragmenScore) { +) -> (Vec, CompactAssignments, ElectionScore, ElectionSize) { let mut backing_stake_of: BTreeMap> = BTreeMap::new(); // self stake >::iter().for_each(|(who, _p)| { - *backing_stake_of.entry(who.clone()).or_insert(Zero::zero()) += + *backing_stake_of.entry(who.clone()).or_insert_with(|| Zero::zero()) += >::slashable_balance_of(&who) }); - // add nominator stuff - >::iter().for_each(|(who, nomination)| { - nomination.targets.into_iter().for_each(|v| { - *backing_stake_of.entry(v).or_insert(Zero::zero()) += - >::slashable_balance_of(&who) - }) - }); - - // elect winners + // elect winners. We chose the.. least backed ones. let mut sorted: Vec = backing_stake_of.keys().cloned().collect(); sorted.sort_by_key(|x| backing_stake_of.get(x).unwrap()); let winners: Vec = sorted .iter() + .rev() .cloned() .take(>::validator_count() as usize) .collect(); let mut staked_assignments: Vec> = Vec::new(); - >::iter().for_each(|(who, nomination)| { - let mut dist: Vec<(T::AccountId, ExtendedBalance)> = Vec::new(); - nomination.targets.into_iter().for_each(|v| { - if winners.iter().find(|&w| *w == v).is_some() { - dist.push((v, ExtendedBalance::zero())); - } - }); - - if dist.len() == 0 { - return; - } - - // assign real stakes. just split the stake. - let stake = , u64>>::convert( - >::slashable_balance_of(&who), - ) as ExtendedBalance; - - let mut sum: ExtendedBalance = Zero::zero(); - let dist_len = dist.len() as ExtendedBalance; - - // assign main portion - // only take the first half into account. This should highly imbalance stuff, which is good. - dist.iter_mut() - .take(if dist_len > 1 { - (dist_len as usize) / 2 - } else { - 1 - }) - .for_each(|(_, w)| { - let partial = stake / dist_len; - *w = partial; - sum += partial; - }); - - // assign the leftover to last. - let leftover = stake - sum; - let last = dist.last_mut().unwrap(); - last.1 += leftover; - - staked_assignments.push(StakedAssignment { - who, - distribution: dist, - }); - }); + // you could at this point start adding some of the nominator's stake, but for now we don't. + // This solution must be bad. // add self support to winners. winners.iter().for_each(|w| { @@ -254,28 +209,22 @@ pub fn get_weak_solution( .position(|x| x == a) .and_then(|i| >::try_into(i).ok()) }; - let stake_of = |who: &T::AccountId| -> ExtendedBalance { + let stake_of = |who: &T::AccountId| -> VoteWeight { , u64>>::convert( >::slashable_balance_of(who), - ) as ExtendedBalance + ) }; // convert back to ratio assignment. This takes less space. - let low_accuracy_assignment: Vec> = - staked_assignments - .into_iter() - .map(|sa| sa.into_assignment(true)) - .collect(); + let low_accuracy_assignment = assignment_staked_to_ratio_normalized(staked_assignments) + .expect("Failed to normalize"); // re-calculate score based on what the chain will decode. let score = { - let staked: Vec> = low_accuracy_assignment - .iter() - .map(|a| { - let stake = stake_of(&a.who); - a.clone().into_staked(stake, true) - }) - .collect(); + let staked = assignment_ratio_to_staked::<_, OffchainAccuracy, _>( + low_accuracy_assignment.clone(), + stake_of + ); let (support_map, _) = build_support_map::(winners.as_slice(), staked.as_slice()); @@ -303,15 +252,20 @@ pub fn get_weak_solution( }) .collect::>(); - (winners, compact, score) + let size = ElectionSize { + validators: snapshot_validators.len() as ValidatorIndex, + nominators: snapshot_nominators.len() as NominatorIndex, + }; + + (winners, compact, score, size) } /// Create a solution for seq-phragmen. This uses the same internal function as used by the offchain /// worker code. pub fn get_seq_phragmen_solution( do_reduce: bool, -) -> (Vec, CompactAssignments, PhragmenScore) { - let sp_phragmen::PhragmenResult { +) -> (Vec, CompactAssignments, ElectionScore, ElectionSize) { + let sp_npos_elections::ElectionResult { winners, assignments, } = >::do_phragmen::().unwrap(); @@ -319,29 +273,40 @@ pub fn get_seq_phragmen_solution( offchain_election::prepare_submission::(assignments, winners, do_reduce).unwrap() } -/// Remove all validator, nominators, votes and exposures. -pub fn clean(era: EraIndex) - where - ::AccountId: codec::EncodeLike, - u32: codec::EncodeLike, -{ - >::iter().for_each(|(k, _)| { - let ctrl = >::bonded(&k).unwrap(); - >::remove(&k); - >::remove(&k); - >::remove(&ctrl); - >::remove(k, era); - }); - >::iter().for_each(|(k, _)| >::remove(k)); - >::remove_all(); - >::remove_all(); - >::kill(); - QueuedScore::kill(); +/// Returns a solution in which only one winner is elected with just a self vote. +pub fn get_single_winner_solution( + winner: T::AccountId +) -> Result<(Vec, CompactAssignments, ElectionScore, ElectionSize), &'static str> { + let snapshot_validators = >::snapshot_validators().unwrap(); + let snapshot_nominators = >::snapshot_nominators().unwrap(); + + let val_index = snapshot_validators.iter().position(|x| *x == winner).ok_or("not a validator")?; + let nom_index = snapshot_nominators.iter().position(|x| *x == winner).ok_or("not a nominator")?; + + let stake = >::slashable_balance_of(&winner); + let stake = , VoteWeight>>::convert(stake) + as ExtendedBalance; + + let val_index = val_index as ValidatorIndex; + let nom_index = nom_index as NominatorIndex; + + let winners = vec![val_index]; + let compact = CompactAssignments { + votes1: vec![(nom_index, val_index)], + ..Default::default() + }; + let score = [stake, stake, stake * stake]; + let size = ElectionSize { + validators: snapshot_validators.len() as ValidatorIndex, + nominators: snapshot_nominators.len() as NominatorIndex, + }; + + Ok((winners, compact, score, size)) } /// get the active era. -pub fn active_era() -> EraIndex { - >::active_era().unwrap().index +pub fn current_era() -> EraIndex { + >::current_era().unwrap_or(0) } /// initialize the first era. @@ -351,3 +316,33 @@ pub fn init_active_era() { start: None, }) } + +/// Create random assignments for the given list of winners. Each assignment will have +/// MAX_NOMINATIONS edges. +pub fn create_assignments_for_offchain( + num_assignments: u32, + winners: Vec<::Source>, +) -> Result< + ( + Vec<(T::AccountId, ExtendedBalance)>, + Vec>, + ), + &'static str +> { + let ratio = OffchainAccuracy::from_rational_approximation(1, MAX_NOMINATIONS); + let assignments: Vec> = >::iter() + .take(num_assignments as usize) + .map(|(n, t)| Assignment { + who: n, + distribution: t.targets.iter().map(|v| (v.clone(), ratio)).collect(), + }) + .collect(); + + ensure!(assignments.len() == num_assignments as usize, "must bench for `a` assignments"); + + let winners = winners.into_iter().map(|v| { + (::lookup(v).unwrap(), 0) + }).collect(); + + Ok((winners, assignments)) +} diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 9cda151b707d5e1e6b2d0ffd41cab3e978c2aa62..278e5323876724a035c3795576957b40136c6c1d 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for the module. @@ -24,7 +25,7 @@ use sp_runtime::{ use sp_staking::offence::OffenceDetails; use frame_support::{ assert_ok, assert_noop, StorageMap, - traits::{Currency, ReservableCurrency, OnInitialize}, + traits::{Currency, ReservableCurrency, OnInitialize, OnFinalize}, }; use pallet_balances::Error as BalancesError; use substrate_test_utils::assert_eq_uvec; @@ -34,15 +35,19 @@ fn force_unstake_works() { ExtBuilder::default().build_and_execute(|| { // Account 11 is stashed and locked, and account 10 is the controller assert_eq!(Staking::bonded(&11), Some(10)); + // Adds 2 slashing spans + add_slash(&11); // Cant transfer assert_noop!( Balances::transfer(Origin::signed(11), 1, 10), BalancesError::::LiquidityRestrictions ); // Force unstake requires root. - assert_noop!(Staking::force_unstake(Origin::signed(11), 11), BadOrigin); + assert_noop!(Staking::force_unstake(Origin::signed(11), 11, 2), BadOrigin); + // Force unstake needs correct number of slashing spans (for weight calculation) + assert_noop!(Staking::force_unstake(Origin::signed(11), 11, 0), BadOrigin); // We now force them to unstake - assert_ok!(Staking::force_unstake(Origin::ROOT, 11)); + assert_ok!(Staking::force_unstake(Origin::root(), 11, 2)); // No longer bonded. assert_eq!(Staking::bonded(&11), None); // Transfer works. @@ -50,6 +55,24 @@ fn force_unstake_works() { }); } +#[test] +fn kill_stash_works() { + ExtBuilder::default().build_and_execute(|| { + // Account 11 is stashed and locked, and account 10 is the controller + assert_eq!(Staking::bonded(&11), Some(10)); + // Adds 2 slashing spans + add_slash(&11); + // Only can kill a stash account + assert_noop!(Staking::kill_stash(&12, 0), Error::::NotStash); + // Respects slashing span count + assert_noop!(Staking::kill_stash(&11, 0), Error::::IncorrectSlashingSpans); + // Correct inputs, everything works + assert_ok!(Staking::kill_stash(&11, 2)); + // No longer bonded. + assert_eq!(Staking::bonded(&11), None); + }); +} + #[test] fn basic_setup_works() { // Verifies initial conditions of mock @@ -314,7 +337,7 @@ fn staking_should_work() { claimed_rewards: vec![0], }) ); - // e.g. it cannot spend more than 500 that it has free from the total 2000 + // e.g. it cannot reserve more than 500 that it has free from the total 2000 assert_noop!( Balances::reserve(&3, 501), BalancesError::::LiquidityRestrictions @@ -383,41 +406,6 @@ fn no_candidate_emergency_condition() { #[test] fn nominating_and_rewards_should_work() { - // PHRAGMEN OUTPUT: running this test with the reference impl gives: - // - // Sequential Phragmén gives - // 10 is elected with stake 2200.0 and score 0.0003333333333333333 - // 20 is elected with stake 1800.0 and score 0.0005555555555555556 - - // 10 has load 0.0003333333333333333 and supported - // 10 with stake 1000.0 - // 20 has load 0.0005555555555555556 and supported - // 20 with stake 1000.0 - // 30 has load 0 and supported - // 30 with stake 0 - // 40 has load 0 and supported - // 40 with stake 0 - // 2 has load 0.0005555555555555556 and supported - // 10 with stake 600.0 20 with stake 400.0 30 with stake 0.0 - // 4 has load 0.0005555555555555556 and supported - // 10 with stake 600.0 20 with stake 400.0 40 with stake 0.0 - - // Sequential Phragmén with post processing gives - // 10 is elected with stake 2000.0 and score 0.0003333333333333333 - // 20 is elected with stake 2000.0 and score 0.0005555555555555556 - - // 10 has load 0.0003333333333333333 and supported - // 10 with stake 1000.0 - // 20 has load 0.0005555555555555556 and supported - // 20 with stake 1000.0 - // 30 has load 0 and supported - // 30 with stake 0 - // 40 has load 0 and supported - // 40 with stake 0 - // 2 has load 0.0005555555555555556 and supported - // 10 with stake 400.0 20 with stake 600.0 30 with stake 0 - // 4 has load 0.0005555555555555556 and supported - // 10 with stake 600.0 20 with stake 400.0 40 with stake 0.0 ExtBuilder::default() .nominate(false) .validator_pool(true) @@ -454,7 +442,7 @@ fn nominating_and_rewards_should_work() { mock::start_era(1); - // 10 and 20 have more votes, they will be chosen by phragmen. + // 10 and 20 have more votes, they will be chosen. assert_eq_uvec!(validator_controllers(), vec![20, 10]); // OLD validators must have already received some rewards. @@ -795,10 +783,10 @@ fn cannot_reserve_staked_balance() { assert_eq!(Balances::free_balance(11), 1000); // Confirm account 11 (via controller 10) is totally staked assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11).own, 1000); - // Confirm account 11 cannot transfer as a result + // Confirm account 11 cannot reserve as a result assert_noop!( Balances::reserve(&11, 1), - BalancesError::::LiquidityRestrictions + BalancesError::::LiquidityRestrictions, ); // Give account 11 extra free balance @@ -1023,7 +1011,10 @@ fn bond_extra_and_withdraw_unbonded_works() { unlocking: vec![], claimed_rewards: vec![], })); - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { total: 1000, own: 1000, others: vec![] }); + assert_eq!( + Staking::eras_stakers(Staking::active_era().unwrap().index, 11), + Exposure { total: 1000, own: 1000, others: vec![] } + ); // deposit the extra 100 units Staking::bond_extra(Origin::signed(11), 100).unwrap(); @@ -1036,7 +1027,10 @@ fn bond_extra_and_withdraw_unbonded_works() { claimed_rewards: vec![], })); // Exposure is a snapshot! only updated after the next era update. - assert_ne!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] }); + assert_ne!( + Staking::eras_stakers(Staking::active_era().unwrap().index, 11), + Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] } + ); // trigger next era. mock::start_era(2); @@ -1051,34 +1045,68 @@ fn bond_extra_and_withdraw_unbonded_works() { claimed_rewards: vec![], })); // Exposure is now updated. - assert_eq!(Staking::eras_stakers(Staking::active_era().unwrap().index, 11), Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] }); + assert_eq!( + Staking::eras_stakers(Staking::active_era().unwrap().index, 11), + Exposure { total: 1000 + 100, own: 1000 + 100, others: vec![] } + ); // Unbond almost all of the funds in stash. Staking::unbond(Origin::signed(10), 1000).unwrap(); - assert_eq!(Staking::ledger(&10), Some(StakingLedger { - stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], claimed_rewards: vec![] }) + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { + stash: 11, + total: 1000 + 100, + active: 100, + unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], + claimed_rewards: vec![] + }), ); // Attempting to free the balances now will fail. 2 eras need to pass. - Staking::withdraw_unbonded(Origin::signed(10)).unwrap(); - assert_eq!(Staking::ledger(&10), Some(StakingLedger { - stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], claimed_rewards: vec![] })); + assert_ok!(Staking::withdraw_unbonded(Origin::signed(10), 0)); + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { + stash: 11, + total: 1000 + 100, + active: 100, + unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], + claimed_rewards: vec![] + }), + ); // trigger next era. mock::start_era(3); // nothing yet - Staking::withdraw_unbonded(Origin::signed(10)).unwrap(); - assert_eq!(Staking::ledger(&10), Some(StakingLedger { - stash: 11, total: 1000 + 100, active: 100, unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], claimed_rewards: vec![] })); + assert_ok!(Staking::withdraw_unbonded(Origin::signed(10), 0)); + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { + stash: 11, + total: 1000 + 100, + active: 100, + unlocking: vec![UnlockChunk{ value: 1000, era: 2 + 3}], + claimed_rewards: vec![] + }), + ); // trigger next era. mock::start_era(5); - Staking::withdraw_unbonded(Origin::signed(10)).unwrap(); + assert_ok!(Staking::withdraw_unbonded(Origin::signed(10), 0)); // Now the value is free and the staking ledger is updated. - assert_eq!(Staking::ledger(&10), Some(StakingLedger { - stash: 11, total: 100, active: 100, unlocking: vec![], claimed_rewards: vec![] })); + assert_eq!( + Staking::ledger(&10), + Some(StakingLedger { + stash: 11, + total: 100, + active: 100, + unlocking: vec![], + claimed_rewards: vec![] + }), + ); }) } @@ -1101,7 +1129,7 @@ fn too_many_unbond_calls_should_not_work() { assert_noop!(Staking::unbond(Origin::signed(10), 1), Error::::NoMoreChunks); // free up. - assert_ok!(Staking::withdraw_unbonded(Origin::signed(10))); + assert_ok!(Staking::withdraw_unbonded(Origin::signed(10), 0)); // Can add again. assert_ok!(Staking::unbond(Origin::signed(10), 1)); @@ -1449,7 +1477,7 @@ fn on_free_balance_zero_stash_removes_validator() { assert_eq!(Balances::total_balance(&11), 0); // Reap the stash - assert_ok!(Staking::reap_stash(Origin::NONE, 11)); + assert_ok!(Staking::reap_stash(Origin::none(), 11, 0)); // Check storage items do not exist assert!(!>::contains_key(&10)); @@ -1505,7 +1533,7 @@ fn on_free_balance_zero_stash_removes_nominator() { assert_eq!(Balances::total_balance(&11), 0); // Reap the stash - assert_ok!(Staking::reap_stash(Origin::NONE, 11)); + assert_ok!(Staking::reap_stash(Origin::none(), 11, 0)); // Check storage items do not exist assert!(!>::contains_key(&10)); @@ -1619,14 +1647,14 @@ fn bond_with_no_staked_value() { mock::start_era(2); // not yet removed. - assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); + assert_ok!(Staking::withdraw_unbonded(Origin::signed(2), 0)); assert!(Staking::ledger(2).is_some()); assert_eq!(Balances::locks(&1)[0].amount, 5); mock::start_era(3); // poof. Account 1 is removed from the staking system. - assert_ok!(Staking::withdraw_unbonded(Origin::signed(2))); + assert_ok!(Staking::withdraw_unbonded(Origin::signed(2), 0)); assert!(Staking::ledger(2).is_none()); assert_eq!(Balances::locks(&1).len(), 0); }); @@ -1687,6 +1715,101 @@ fn bond_with_little_staked_value_bounded() { }); } +#[test] +fn bond_with_duplicate_vote_should_be_ignored_by_npos_election() { + ExtBuilder::default() + .validator_count(2) + .nominate(false) + .minimum_validator_count(1) + .build() + .execute_with(|| { + // disable the nominator + assert_ok!(Staking::chill(Origin::signed(100))); + // make stakes equal. + assert_ok!(Staking::bond_extra(Origin::signed(31), 999)); + + assert_eq!( + >::iter() + .map(|(v, _)| (v, Staking::ledger(v - 1).unwrap().total)) + .collect::>(), + vec![(31, 1000), (21, 1000), (11, 1000)], + ); + assert_eq!(>::iter().map(|(n, _)| n).collect::>(), vec![]); + + // give the man some money + let initial_balance = 1000; + for i in [1, 2, 3, 4,].iter() { + let _ = Balances::make_free_balance_be(i, initial_balance); + } + + assert_ok!(Staking::bond(Origin::signed(1), 2, 1000, RewardDestination::Controller)); + assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 11, 11, 21, 31,])); + + assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::Controller)); + assert_ok!(Staking::nominate(Origin::signed(4), vec![21, 31])); + + // winners should be 21 and 31. Otherwise this election is taking duplicates into account. + + let sp_npos_elections::ElectionResult { + winners, + assignments, + } = Staking::do_phragmen::().unwrap(); + let winners = sp_npos_elections::to_without_backing(winners); + + assert_eq!(winners, vec![31, 21]); + // only distribution to 21 and 31. + assert_eq!(assignments.iter().find(|a| a.who == 1).unwrap().distribution.len(), 2); + }); +} + +#[test] +fn bond_with_duplicate_vote_should_be_ignored_by_npos_election_elected() { + // same as above but ensures that even when the duple is being elected, everything is sane. + ExtBuilder::default() + .validator_count(2) + .nominate(false) + .minimum_validator_count(1) + .build() + .execute_with(|| { + // disable the nominator + assert_ok!(Staking::chill(Origin::signed(100))); + // make stakes equal. + assert_ok!(Staking::bond_extra(Origin::signed(31), 99)); + + assert_eq!( + >::iter() + .map(|(v, _)| (v, Staking::ledger(v - 1).unwrap().total)) + .collect::>(), + vec![(31, 100), (21, 1000), (11, 1000)], + ); + assert_eq!(>::iter().map(|(n, _)| n).collect::>(), vec![]); + + // give the man some money + let initial_balance = 1000; + for i in [1, 2, 3, 4,].iter() { + let _ = Balances::make_free_balance_be(i, initial_balance); + } + + assert_ok!(Staking::bond(Origin::signed(1), 2, 1000, RewardDestination::Controller)); + assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 11, 11, 21, 31,])); + + assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::Controller)); + assert_ok!(Staking::nominate(Origin::signed(4), vec![21, 31])); + + // winners should be 21 and 31. Otherwise this election is taking duplicates into account. + + let sp_npos_elections::ElectionResult { + winners, + assignments, + } = Staking::do_phragmen::().unwrap(); + + let winners = sp_npos_elections::to_without_backing(winners); + assert_eq!(winners, vec![21, 11]); + // only distribution to 21 and 31. + assert_eq!(assignments.iter().find(|a| a.who == 1).unwrap().distribution.len(), 2); + }); +} + #[test] fn new_era_elects_correct_number_of_validators() { ExtBuilder::default() @@ -1900,7 +2023,7 @@ fn offence_forces_new_era() { #[test] fn offence_ensures_new_era_without_clobbering() { ExtBuilder::default().build_and_execute(|| { - assert_ok!(Staking::force_new_era_always(Origin::ROOT)); + assert_ok!(Staking::force_new_era_always(Origin::root())); assert_eq!(Staking::force_era(), Forcing::ForceAlways); on_offence_now( @@ -2270,7 +2393,12 @@ fn garbage_collection_after_slashing() { assert_eq!(Balances::free_balance(11), 0); assert_eq!(Balances::total_balance(&11), 0); - assert_ok!(Staking::reap_stash(Origin::NONE, 11)); + let slashing_spans = ::SlashingSpans::get(&11).unwrap(); + assert_eq!(slashing_spans.iter().count(), 2); + + // reap_stash respects num_slashing_spans so that weight is accurate + assert_noop!(Staking::reap_stash(Origin::none(), 11, 0), Error::::IncorrectSlashingSpans); + assert_ok!(Staking::reap_stash(Origin::none(), 11, 2)); assert!(::SlashingSpans::get(&11).is_none()); assert_eq!(::SpanSlash::get(&(11, 0)).amount_slashed(), &0); @@ -2558,11 +2686,11 @@ fn remove_deferred() { // fails if empty assert_noop!( - Staking::cancel_deferred_slash(Origin::ROOT, 1, vec![]), + Staking::cancel_deferred_slash(Origin::root(), 1, vec![]), Error::::EmptyTargets ); - assert_ok!(Staking::cancel_deferred_slash(Origin::ROOT, 1, vec![0])); + assert_ok!(Staking::cancel_deferred_slash(Origin::root(), 1, vec![0])); assert_eq!(Balances::free_balance(11), 1000); assert_eq!(Balances::free_balance(101), 2000); @@ -2659,21 +2787,21 @@ fn remove_multi_deferred() { // fails if list is not sorted assert_noop!( - Staking::cancel_deferred_slash(Origin::ROOT, 1, vec![2, 0, 4]), + Staking::cancel_deferred_slash(Origin::root(), 1, vec![2, 0, 4]), Error::::NotSortedAndUnique ); // fails if list is not unique assert_noop!( - Staking::cancel_deferred_slash(Origin::ROOT, 1, vec![0, 2, 2]), + Staking::cancel_deferred_slash(Origin::root(), 1, vec![0, 2, 2]), Error::::NotSortedAndUnique ); // fails if bad index assert_noop!( - Staking::cancel_deferred_slash(Origin::ROOT, 1, vec![1, 2, 3, 4, 5]), + Staking::cancel_deferred_slash(Origin::root(), 1, vec![1, 2, 3, 4, 5]), Error::::InvalidSlashIndex ); - assert_ok!(Staking::cancel_deferred_slash(Origin::ROOT, 1, vec![0, 2, 4])); + assert_ok!(Staking::cancel_deferred_slash(Origin::root(), 1, vec![0, 2, 4])); let slashes = ::UnappliedSlashes::get(&1); assert_eq!(slashes.len(), 2); @@ -2682,10 +2810,13 @@ fn remove_multi_deferred() { }) } -mod offchain_phragmen { +mod offchain_election { use crate::*; use codec::Encode; - use frame_support::{assert_noop, assert_ok}; + use frame_support::{ + assert_noop, assert_ok, assert_err_with_weight, + dispatch::DispatchResultWithPostInfo, + }; use sp_runtime::transaction_validity::TransactionSource; use mock::*; use parking_lot::RwLock; @@ -2694,7 +2825,7 @@ mod offchain_phragmen { OffchainExt, TransactionPoolExt, }; use sp_io::TestExternalities; - use sp_phragmen::StakedAssignment; + use sp_npos_elections::StakedAssignment; use frame_support::traits::OffchainWorker; use std::sync::Arc; use substrate_test_utils::assert_eq_uvec; @@ -2705,7 +2836,7 @@ mod offchain_phragmen { /// setup a new set of validators and nominator storage items independent of the parent mock /// file. This produces a edge graph that can be reduced. - fn build_offchain_phragmen_test_ext() { + pub fn build_offchain_election_test_ext() { for i in (10..=40).step_by(10) { // Note: we respect the convention of the mock (10, 11 pairs etc.) since these accounts // have corresponding keys in session which makes everything more ergonomic and @@ -2730,9 +2861,9 @@ mod offchain_phragmen { let (offchain, offchain_state) = TestOffchainExt::new(); let (pool, pool_state) = TestTransactionPoolExt::new(); - let mut seed = [0_u8; 32]; - seed[0..4].copy_from_slice(&iterations.to_le_bytes()); - offchain_state.write().seed = seed; + let mut seed = [0_u8; 32]; + seed[0..4].copy_from_slice(&iterations.to_le_bytes()); + offchain_state.write().seed = seed; ext.register_extension(OffchainExt::new(offchain)); ext.register_extension(TransactionPoolExt::new(pool)); @@ -2740,6 +2871,29 @@ mod offchain_phragmen { pool_state } + fn election_size() -> ElectionSize { + ElectionSize { + validators: Staking::snapshot_validators().unwrap().len() as ValidatorIndex, + nominators: Staking::snapshot_nominators().unwrap().len() as NominatorIndex, + } + } + + fn submit_solution( + origin: Origin, + winners: Vec, + compact: CompactAssignments, + score: ElectionScore, + ) -> DispatchResultWithPostInfo { + Staking::submit_election_solution( + origin, + winners, + compact, + score, + current_era(), + election_size(), + ) + } + #[test] fn is_current_session_final_works() { ExtBuilder::default() @@ -2765,7 +2919,7 @@ mod offchain_phragmen { } #[test] - fn offchain_election_flag_is_triggered() { + fn offchain_window_is_triggered() { ExtBuilder::default() .session_per_era(5) .session_length(10) @@ -2825,16 +2979,13 @@ mod offchain_phragmen { } #[test] - fn offchain_election_flag_is_triggered_when_forcing() { + fn offchain_window_is_triggered_when_forcing() { ExtBuilder::default() .session_per_era(5) .session_length(10) .election_lookahead(3) .build() .execute_with(|| { - run_to_block(7); - assert_session_era!(0, 0); - run_to_block(12); ForceEra::put(Forcing::ForceNew); run_to_block(13); @@ -2842,11 +2993,90 @@ mod offchain_phragmen { run_to_block(17); // instead of 47 assert_eq!(Staking::era_election_status(), ElectionStatus::Open(17)); + + run_to_block(20); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + }) + } + + #[test] + fn offchain_window_is_triggered_when_force_always() { + ExtBuilder::default() + .session_per_era(5) + .session_length(10) + .election_lookahead(3) + .build() + .execute_with(|| { + + ForceEra::put(Forcing::ForceAlways); + run_to_block(16); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + + run_to_block(17); // instead of 37 + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(17)); + + run_to_block(20); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + + run_to_block(26); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + + run_to_block(27); // next one again + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(27)); }) } #[test] - fn election_on_chain_fallback_works() { + fn offchain_window_closes_when_forcenone() { + ExtBuilder::default() + .session_per_era(5) + .session_length(10) + .election_lookahead(3) + .build() + .execute_with(|| { + ForceEra::put(Forcing::ForceNone); + + run_to_block(36); + assert_session_era!(3, 0); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + + // opens + run_to_block(37); + assert_eq!(Staking::era_election_status(), ElectionStatus::Open(37)); + assert!(Staking::is_current_session_final()); + assert!(Staking::snapshot_validators().is_some()); + + // closes normally + run_to_block(40); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + assert!(!Staking::is_current_session_final()); + assert!(Staking::snapshot_validators().is_none()); + assert_session_era!(4, 0); + + run_to_block(47); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + assert_session_era!(4, 0); + + run_to_block(57); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + assert_session_era!(5, 0); + + run_to_block(67); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + + // Will not open again as scheduled + run_to_block(87); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + assert_session_era!(8, 0); + + run_to_block(90); + assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); + assert_session_era!(9, 0); + }) + } + + #[test] + fn offchain_window_on_chain_fallback_works() { ExtBuilder::default().build_and_execute(|| { start_session(1); start_session(2); @@ -2874,7 +3104,7 @@ mod offchain_phragmen { #[ignore] // This takes a few mins fn offchain_wont_work_if_snapshot_fails() { ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .build() .execute_with(|| { run_to_block(12); @@ -2898,7 +3128,7 @@ mod offchain_phragmen { #[test] fn staking_is_locked_when_election_window_open() { ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .election_lookahead(3) .build() .execute_with(|| { @@ -2920,7 +3150,7 @@ mod offchain_phragmen { // should check that we have a new validator set normally, event says that it comes from // offchain. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .build() .execute_with(|| { run_to_block(12); @@ -2928,16 +3158,30 @@ mod offchain_phragmen { assert!(Staking::snapshot_validators().is_some()); let (compact, winners, score) = prepare_submission_with(true, 2, |_| {}); - assert_ok!(Staking::submit_election_solution( + assert_ok!(submit_solution( Origin::signed(10), winners, compact, score, - current_era(), )); let queued_result = Staking::queued_elected().unwrap(); assert_eq!(queued_result.compute, ElectionCompute::Signed); + assert_eq!( + System::events() + .into_iter() + .map(|r| r.event) + .filter_map(|e| { + if let MetaEvent::staking(inner) = e { + Some(inner) + } else { + None + } + }) + .last() + .unwrap(), + RawEvent::SolutionStored(ElectionCompute::Signed), + ); run_to_block(15); assert_eq!(Staking::era_election_status(), ElectionStatus::Closed); @@ -2964,20 +3208,14 @@ mod offchain_phragmen { fn signed_result_can_be_submitted_later() { // same as `signed_result_can_be_submitted` but at a later block. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .build() .execute_with(|| { run_to_block(14); assert_eq!(Staking::era_election_status(), ElectionStatus::Open(12)); let (compact, winners, score) = prepare_submission_with(true, 2, |_| {}); - assert_ok!(Staking::submit_election_solution( - Origin::signed(10), - winners, - compact, - score, - current_era(), - )); + assert_ok!(submit_solution(Origin::signed(10), winners, compact, score)); let queued_result = Staking::queued_elected().unwrap(); assert_eq!(queued_result.compute, ElectionCompute::Signed); @@ -3008,7 +3246,7 @@ mod offchain_phragmen { // should check that we have a new validator set normally, event says that it comes from // offchain. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .build() .execute_with(|| { run_to_block(11); @@ -3020,15 +3258,17 @@ mod offchain_phragmen { let (compact, winners, score) = prepare_submission_with(true, 2, |_| {}); Staking::kill_stakers_snapshot(); - assert_noop!( + assert_err_with_weight!( Staking::submit_election_solution( Origin::signed(10), - winners, - compact, + winners.clone(), + compact.clone(), score, current_era(), + ElectionSize::default(), ), - Error::::PhragmenEarlySubmission, + Error::::OffchainElectionEarlySubmission, + Some(::DbWeight::get().reads(1)), ); }) } @@ -3037,35 +3277,34 @@ mod offchain_phragmen { fn weak_solution_is_rejected() { // A solution which is weaker than what we currently have on-chain is rejected. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .has_stakers(false) .validator_count(4) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); // a good solution let (compact, winners, score) = prepare_submission_with(true, 2, |_| {}); - assert_ok!(Staking::submit_election_solution( + assert_ok!(submit_solution( Origin::signed(10), winners, compact, score, - current_era(), )); // a bad solution - let (compact, winners, score) = horrible_phragmen_with_post_processing(false); - assert_noop!( - Staking::submit_election_solution( + let (compact, winners, score) = horrible_npos_solution(false); + assert_err_with_weight!( + submit_solution( Origin::signed(10), - winners, - compact, + winners.clone(), + compact.clone(), score, - current_era(), ), - Error::::PhragmenWeakSubmission, + Error::::OffchainElectionWeakSubmission, + Some(::DbWeight::get().reads(3)) ); }) } @@ -3074,32 +3313,30 @@ mod offchain_phragmen { fn better_solution_is_accepted() { // A solution which is better than what we currently have on-chain is accepted. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); // a meeeeh solution - let (compact, winners, score) = horrible_phragmen_with_post_processing(false); - assert_ok!(Staking::submit_election_solution( + let (compact, winners, score) = horrible_npos_solution(false); + assert_ok!(submit_solution( Origin::signed(10), winners, compact, score, - current_era(), )); // a better solution let (compact, winners, score) = prepare_submission_with(true, 2, |_| {}); - assert_ok!(Staking::submit_election_solution( + assert_ok!(submit_solution( Origin::signed(10), winners, compact, score, - current_era(), )); }) } @@ -3108,7 +3345,7 @@ mod offchain_phragmen { fn offchain_worker_runs_when_window_open() { // at the end of the first finalized block with ElectionStatus::open(_), it should execute. let mut ext = ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(2) .build(); let state = offchainify(&mut ext, 0); @@ -3150,7 +3387,7 @@ mod offchain_phragmen { // Offchain worker equalises based on the number provided by randomness. See the difference // in the priority, which comes from the computed score. let mut ext = ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(2) .max_offchain_iterations(2) .build(); @@ -3178,7 +3415,7 @@ mod offchain_phragmen { &inner, ), TransactionValidity::Ok(ValidTransaction { - // the proposed slot stake, with equalize. + // the proposed slot stake, with balance_solution. priority: UnsignedPriority::get() + 1250, requires: vec![], provides: vec![("StakingOffchain", active_era()).encode()], @@ -3192,7 +3429,7 @@ mod offchain_phragmen { #[test] fn mediocre_submission_from_authority_is_early_rejected() { let mut ext = ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .build(); let state = offchainify(&mut ext, 0); @@ -3200,12 +3437,11 @@ mod offchain_phragmen { run_to_block(12); // put a good solution on-chain let (compact, winners, score) = prepare_submission_with(true, 2, |_| {}); - assert_ok!(Staking::submit_election_solution( + assert_ok!(submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ),); // now run the offchain worker in the same chain state. @@ -3227,21 +3463,21 @@ mod offchain_phragmen { &inner, ), TransactionValidity::Err( - InvalidTransaction::Custom(>::PhragmenWeakSubmission.as_u8()).into(), + InvalidTransaction::Custom(>::OffchainElectionWeakSubmission.as_u8()).into(), ), ) }) } #[test] - fn invalid_phragmen_result_correct_number_of_winners() { + fn invalid_election_correct_number_of_winners() { ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); ValidatorCount::put(3); @@ -3250,6 +3486,28 @@ mod offchain_phragmen { assert_eq!(winners.len(), 3); + assert_noop!( + submit_solution( + Origin::signed(10), + winners, + compact, + score, + ), + Error::::OffchainElectionBogusWinnerCount, + ); + }) + } + + #[test] + fn invalid_election_solution_size() { + ExtBuilder::default() + .offchain_election_ext() + .build() + .execute_with(|| { + run_to_block(12); + + let (compact, winners, score) = prepare_submission_with(true, 2, |_| {}); + assert_noop!( Staking::submit_election_solution( Origin::signed(10), @@ -3257,22 +3515,23 @@ mod offchain_phragmen { compact, score, current_era(), + ElectionSize::default(), ), - Error::::PhragmenBogusWinnerCount, + Error::::OffchainElectionBogusElectionSize, ); }) } #[test] - fn invalid_phragmen_result_correct_number_of_winners_1() { + fn invalid_election_correct_number_of_winners_1() { // if we have too little validators, then the number of candidates is the bound. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(8) // we simply cannot elect 8 .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); ValidatorCount::put(3); @@ -3282,28 +3541,27 @@ mod offchain_phragmen { assert_eq!(winners.len(), 3); assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenBogusWinnerCount, + Error::::OffchainElectionBogusWinnerCount, ); }) } #[test] - fn invalid_phragmen_result_correct_number_of_winners_2() { + fn invalid_election_correct_number_of_winners_2() { // if we have too little validators, then the number of candidates is the bound. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(8) // we simply cannot elect 8 .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); let (compact, winners, score) = prepare_submission_with(true, 2, |_| {}); @@ -3311,26 +3569,25 @@ mod offchain_phragmen { assert_eq!(winners.len(), 4); // all good. We chose 4 and it works. - assert_ok!(Staking::submit_election_solution( + assert_ok!(submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ),); }) } #[test] - fn invalid_phragmen_result_out_of_bound_nominator_index() { + fn invalid_election_out_of_bound_nominator_index() { // A nominator index which is simply invalid ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); assert_eq!(Staking::snapshot_nominators().unwrap().len(), 5 + 4); @@ -3342,28 +3599,27 @@ mod offchain_phragmen { // The error type sadly cannot be more specific now. assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenBogusCompact, + Error::::OffchainElectionBogusCompact, ); }) } #[test] - fn invalid_phragmen_result_out_of_bound_validator_index() { + fn invalid_election_out_of_bound_validator_index() { // A validator index which is out of bound ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); assert_eq!(Staking::snapshot_nominators().unwrap().len(), 5 + 4); @@ -3375,28 +3631,27 @@ mod offchain_phragmen { // The error type sadly cannot be more specific now. assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenBogusCompact, + Error::::OffchainElectionBogusCompact, ); }) } #[test] - fn invalid_phragmen_result_out_of_bound_winner_index() { + fn invalid_election_out_of_bound_winner_index() { // A winner index which is simply invalid ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); assert_eq!(Staking::snapshot_nominators().unwrap().len(), 5 + 4); @@ -3407,29 +3662,28 @@ mod offchain_phragmen { let winners = vec![0, 1, 2, 4]; assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenBogusWinner, + Error::::OffchainElectionBogusWinner, ); }) } #[test] - fn invalid_phragmen_result_non_winner_validator_index() { + fn invalid_election_non_winner_validator_index() { // An edge that points to a correct validator index who is NOT a winner. This is very - // similar to the test that raises `PhragmenBogusNomination`. + // similar to the test that raises `OffchainElectionBogusNomination`. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(2) // we select only 2. .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); assert_eq!(Staking::snapshot_nominators().unwrap().len(), 5 + 4); @@ -3443,28 +3697,27 @@ mod offchain_phragmen { }); assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenBogusEdge, + Error::::OffchainElectionBogusEdge, ); }) } #[test] - fn invalid_phragmen_result_wrong_self_vote() { + fn invalid_election_wrong_self_vote() { // A self vote for someone else. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); let (compact, winners, score) = prepare_submission_with(true, 2, |a| { @@ -3479,28 +3732,27 @@ mod offchain_phragmen { }); assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenBogusSelfVote, + Error::::OffchainElectionBogusSelfVote, ); }) } #[test] - fn invalid_phragmen_result_wrong_self_vote_2() { + fn invalid_election_wrong_self_vote_2() { // A self validator voting for someone else next to self vote. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); let (compact, winners, score) = prepare_submission_with(true, 2, |a| { @@ -3515,28 +3767,27 @@ mod offchain_phragmen { // This raises score issue. assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenBogusSelfVote, + Error::::OffchainElectionBogusSelfVote, ); }) } #[test] - fn invalid_phragmen_result_over_stake() { + fn invalid_election_over_stake() { // Someone's edge ratios sums to more than 100%. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); // Note: we don't reduce here to be able to tweak votes3. votes3 will vanish if you @@ -3550,20 +3801,19 @@ mod offchain_phragmen { } assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenBogusCompact, + Error::::OffchainElectionBogusCompact, ); }) } #[test] - fn invalid_phragmen_result_under_stake() { + fn invalid_election_under_stake() { // at the time of this writing, we cannot under stake someone. The compact assignment works // in a way that some of the stakes are presented by the submitter, and the last one is read // from chain by subtracting the rest from total. Hence, the sum is always correct. @@ -3571,16 +3821,16 @@ mod offchain_phragmen { } #[test] - fn invalid_phragmen_result_invalid_target_stealing() { + fn invalid_election_invalid_target_stealing() { // A valid voter who voted for someone who is a candidate, and is a correct winner, but is // actually NOT nominated by this nominator. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); let (compact, winners, score) = prepare_submission_with(false, 0, |a| { @@ -3592,14 +3842,13 @@ mod offchain_phragmen { }); assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenBogusNomination, + Error::::OffchainElectionBogusNomination, ); }) } @@ -3610,12 +3859,12 @@ mod offchain_phragmen { // nomination should be disabled for the upcoming election. A solution must respect this // rule. ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); // finalize the round with fallback. This is needed since all nominator submission // are in era zero and we want this one to pass with no problems. @@ -3655,12 +3904,11 @@ mod offchain_phragmen { }); // can be submitted. - assert_ok!(Staking::submit_election_solution( + assert_ok!(submit_solution( Origin::signed(10), winners, compact, score, - current_era(), )); // a wrong solution. @@ -3674,42 +3922,40 @@ mod offchain_phragmen { // is rejected. assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenSlashedNomination, + Error::::OffchainElectionSlashedNomination, ); }) } #[test] - fn invalid_phragmen_result_wrong_score() { + fn invalid_election_wrong_score() { // A valid voter who's total distributed stake is more than what they bond ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() .execute_with(|| { - build_offchain_phragmen_test_ext(); + build_offchain_election_test_ext(); run_to_block(12); let (compact, winners, mut score) = prepare_submission_with(true, 2, |_| {}); score[0] += 1; assert_noop!( - Staking::submit_election_solution( + submit_solution( Origin::signed(10), winners, compact, score, - current_era(), ), - Error::::PhragmenBogusScore, + Error::::OffchainElectionBogusScore, ); }) } @@ -3717,7 +3963,7 @@ mod offchain_phragmen { #[test] fn offchain_storage_is_set() { let mut ext = ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .build(); let state = offchainify(&mut ext, 0); @@ -3741,7 +3987,7 @@ mod offchain_phragmen { #[test] fn offchain_storage_prevents_duplicate() { let mut ext = ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .build(); let _ = offchainify(&mut ext, 0); @@ -3786,7 +4032,7 @@ mod offchain_phragmen { #[should_panic] fn offence_is_blocked_when_window_open() { ExtBuilder::default() - .offchain_phragmen_ext() + .offchain_election_ext() .validator_count(4) .has_stakers(false) .build() @@ -4092,16 +4338,16 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( fn set_history_depth_works() { ExtBuilder::default().build_and_execute(|| { mock::start_era(10); - Staking::set_history_depth(Origin::ROOT, 20).unwrap(); + Staking::set_history_depth(Origin::root(), 20, 0).unwrap(); assert!(::ErasTotalStake::contains_key(10 - 4)); assert!(::ErasTotalStake::contains_key(10 - 5)); - Staking::set_history_depth(Origin::ROOT, 4).unwrap(); + Staking::set_history_depth(Origin::root(), 4, 0).unwrap(); assert!(::ErasTotalStake::contains_key(10 - 4)); assert!(!::ErasTotalStake::contains_key(10 - 5)); - Staking::set_history_depth(Origin::ROOT, 3).unwrap(); + Staking::set_history_depth(Origin::root(), 3, 0).unwrap(); assert!(!::ErasTotalStake::contains_key(10 - 4)); assert!(!::ErasTotalStake::contains_key(10 - 5)); - Staking::set_history_depth(Origin::ROOT, 8).unwrap(); + Staking::set_history_depth(Origin::root(), 8, 0).unwrap(); assert!(!::ErasTotalStake::contains_key(10 - 4)); assert!(!::ErasTotalStake::contains_key(10 - 5)); }); @@ -4275,326 +4521,108 @@ fn bond_during_era_correctly_populates_claimed_rewards() { }); } -/* These migration tests below can be removed once migration code is removed */ - #[test] -fn rewards_should_work_before_migration() { - // should check that before migration: - // * rewards get recorded per session - // * rewards get paid per Era - // * Check that nominators are also rewarded +fn offences_weight_calculated_correctly() { ExtBuilder::default().nominate(true).build_and_execute(|| { - MigrateEra::put(10); - let init_balance_10 = Balances::total_balance(&10); - let init_balance_11 = Balances::total_balance(&11); - let init_balance_20 = Balances::total_balance(&20); - let init_balance_21 = Balances::total_balance(&21); - let init_balance_100 = Balances::total_balance(&100); - let init_balance_101 = Balances::total_balance(&101); - - // Check state - Payee::::insert(11, RewardDestination::Controller); - Payee::::insert(21, RewardDestination::Controller); - Payee::::insert(101, RewardDestination::Controller); + // On offence with zero offenders: 4 Reads, 1 Write + let zero_offence_weight = ::DbWeight::get().reads_writes(4, 1); + assert_eq!(Staking::on_offence(&[], &[Perbill::from_percent(50)], 0), Ok(zero_offence_weight)); - >::reward_by_ids(vec![(11, 50)]); - >::reward_by_ids(vec![(11, 50)]); - // This is the second validator of the current elected set. - >::reward_by_ids(vec![(21, 50)]); + // On Offence with N offenders, Unapplied: 4 Reads, 1 Write + 4 Reads, 5 Writes + let n_offence_unapplied_weight = ::DbWeight::get().reads_writes(4, 1) + + ::DbWeight::get().reads_writes(4, 5); - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 10); // Test is meaningful if reward something + let offenders: Vec::AccountId, pallet_session::historical::IdentificationTuple>> + = (1..10).map(|i| + OffenceDetails { + offender: (i, Staking::eras_stakers(Staking::active_era().unwrap().index, i)), + reporters: vec![], + } + ).collect(); + assert_eq!(Staking::on_offence(&offenders, &[Perbill::from_percent(50)], 0), Ok(n_offence_unapplied_weight)); - start_session(1); - - assert_eq!(Balances::total_balance(&10), init_balance_10); - assert_eq!(Balances::total_balance(&11), init_balance_11); - assert_eq!(Balances::total_balance(&20), init_balance_20); - assert_eq!(Balances::total_balance(&21), init_balance_21); - assert_eq!(Balances::total_balance(&100), init_balance_100); - assert_eq!(Balances::total_balance(&101), init_balance_101); - assert_eq_uvec!(Session::validators(), vec![11, 21]); - assert_eq!(Staking::eras_reward_points(Staking::active_era().unwrap().index), EraRewardPoints { - total: 50*3, - individual: vec![(11, 100), (21, 50)].into_iter().collect(), - }); - let part_for_10 = Perbill::from_rational_approximation::(1000, 1125); - let part_for_20 = Perbill::from_rational_approximation::(1000, 1375); - let part_for_100_from_10 = Perbill::from_rational_approximation::(125, 1125); - let part_for_100_from_20 = Perbill::from_rational_approximation::(375, 1375); - - start_session(2); - start_session(3); - - assert_eq!(Staking::active_era().unwrap().index, 1); - mock::make_all_reward_payment_before_migration(0); - - assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * total_payout_0*2/3, 2); - assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); - assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0*1/3, 2); - assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); - assert_eq_error_rate!( - Balances::total_balance(&100), - init_balance_100 - + part_for_100_from_10 * total_payout_0 * 2/3 - + part_for_100_from_20 * total_payout_0 * 1/3, - 2 - ); - assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); - - assert_eq_uvec!(Session::validators(), vec![11, 21]); - >::reward_by_ids(vec![(11, 1)]); - - // Compute total payout now for whole duration as other parameter won't change - let total_payout_1 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_1 > 10); // Test is meaningful if reward something - - mock::start_era(2); - mock::make_all_reward_payment_before_migration(1); + // On Offence with one offenders, Applied + let one_offender = [ + OffenceDetails { + offender: (11, Staking::eras_stakers(Staking::active_era().unwrap().index, 11)), + reporters: vec![1], + }, + ]; - assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * (total_payout_0 * 2/3 + total_payout_1), 2); - assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); - assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0 * 1/3, 2); - assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); - assert_eq_error_rate!( - Balances::total_balance(&100), - init_balance_100 - + part_for_100_from_10 * (total_payout_0 * 2/3 + total_payout_1) - + part_for_100_from_20 * total_payout_0 * 1/3, - 2 - ); - assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); + let n = 1; // Number of offenders + let rw = 3 + 3 * n; // rw reads and writes + let one_offence_unapplied_weight = ::DbWeight::get().reads_writes(4, 1) + + ::DbWeight::get().reads_writes(rw, rw) + // One `slash_cost` + + ::DbWeight::get().reads_writes(6, 5) + // `slash_cost` * nominators (1) + + ::DbWeight::get().reads_writes(6, 5) + // `reward_cost` * reporters (1) + + ::DbWeight::get().reads_writes(2, 2); + + assert_eq!(Staking::on_offence(&one_offender, &[Perbill::from_percent(50)], 0), Ok(one_offence_unapplied_weight)); }); } #[test] -fn migrate_era_should_work() { - // should check that before and after migration: - // * rewards get recorded per session - // * rewards get paid per Era - // * Check that nominators are also rewarded - ExtBuilder::default().nominate(true).build_and_execute(|| { - MigrateEra::put(1); - let init_balance_10 = Balances::total_balance(&10); - let init_balance_11 = Balances::total_balance(&11); - let init_balance_20 = Balances::total_balance(&20); - let init_balance_21 = Balances::total_balance(&21); - let init_balance_100 = Balances::total_balance(&100); - let init_balance_101 = Balances::total_balance(&101); - - // Check state - Payee::::insert(11, RewardDestination::Controller); - Payee::::insert(21, RewardDestination::Controller); - Payee::::insert(101, RewardDestination::Controller); - - >::reward_by_ids(vec![(11, 50)]); - >::reward_by_ids(vec![(11, 50)]); - // This is the second validator of the current elected set. - >::reward_by_ids(vec![(21, 50)]); - - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 10); // Test is meaningful if reward something - - start_session(1); - - assert_eq!(Balances::total_balance(&10), init_balance_10); - assert_eq!(Balances::total_balance(&11), init_balance_11); - assert_eq!(Balances::total_balance(&20), init_balance_20); - assert_eq!(Balances::total_balance(&21), init_balance_21); - assert_eq!(Balances::total_balance(&100), init_balance_100); - assert_eq!(Balances::total_balance(&101), init_balance_101); - assert_eq_uvec!(Session::validators(), vec![11, 21]); - assert_eq!(Staking::eras_reward_points(Staking::active_era().unwrap().index), EraRewardPoints { - total: 50*3, - individual: vec![(11, 100), (21, 50)].into_iter().collect(), - }); - let part_for_10 = Perbill::from_rational_approximation::(1000, 1125); - let part_for_20 = Perbill::from_rational_approximation::(1000, 1375); - let part_for_100_from_10 = Perbill::from_rational_approximation::(125, 1125); - let part_for_100_from_20 = Perbill::from_rational_approximation::(375, 1375); - - start_session(2); - start_session(3); - - assert_eq!(Staking::active_era().unwrap().index, 1); - mock::make_all_reward_payment_before_migration(0); - - assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * total_payout_0*2/3, 2); - assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); - assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0*1/3, 2); - assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); - assert_eq_error_rate!( - Balances::total_balance(&100), - init_balance_100 - + part_for_100_from_10 * total_payout_0 * 2/3 - + part_for_100_from_20 * total_payout_0 * 1/3, - 2 - ); - assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); - - assert_eq_uvec!(Session::validators(), vec![11, 21]); - >::reward_by_ids(vec![(11, 1)]); - - // Compute total payout now for whole duration as other parameter won't change - let total_payout_1 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_1 > 10); // Test is meaningful if reward something - - mock::start_era(2); - mock::make_all_reward_payment(1); - - assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * (total_payout_0 * 2/3 + total_payout_1), 2); - assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); - assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0 * 1/3, 2); - assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); - assert_eq_error_rate!( - Balances::total_balance(&100), - init_balance_100 - + part_for_100_from_10 * (total_payout_0 * 2/3 + total_payout_1) - + part_for_100_from_20 * total_payout_0 * 1/3, - 2 - ); - assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); +fn on_initialize_weight_is_correct() { + ExtBuilder::default().has_stakers(false).build_and_execute(|| { + assert_eq!(Validators::::iter().count(), 0); + assert_eq!(Nominators::::iter().count(), 0); + // When this pallet has nothing, we do 4 reads each block + let base_weight = ::DbWeight::get().reads(4); + assert_eq!(base_weight, Staking::on_initialize(0)); }); -} - -#[test] -#[should_panic] -fn migrate_era_should_handle_error() { - ExtBuilder::default().nominate(true).build_and_execute(|| { - MigrateEra::put(1); - let init_balance_10 = Balances::total_balance(&10); - let init_balance_11 = Balances::total_balance(&11); - let init_balance_20 = Balances::total_balance(&20); - let init_balance_21 = Balances::total_balance(&21); - let init_balance_100 = Balances::total_balance(&100); - let init_balance_101 = Balances::total_balance(&101); - // Check state - Payee::::insert(11, RewardDestination::Controller); - Payee::::insert(21, RewardDestination::Controller); - Payee::::insert(101, RewardDestination::Controller); - - >::reward_by_ids(vec![(11, 50)]); - >::reward_by_ids(vec![(11, 50)]); - // This is the second validator of the current elected set. - >::reward_by_ids(vec![(21, 50)]); - - // Compute total payout now for whole duration as other parameter won't change - let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 10); // Test is meaningful if reward something - - start_session(1); - - assert_eq!(Balances::total_balance(&10), init_balance_10); - assert_eq!(Balances::total_balance(&11), init_balance_11); - assert_eq!(Balances::total_balance(&20), init_balance_20); - assert_eq!(Balances::total_balance(&21), init_balance_21); - assert_eq!(Balances::total_balance(&100), init_balance_100); - assert_eq!(Balances::total_balance(&101), init_balance_101); - assert_eq_uvec!(Session::validators(), vec![11, 21]); - assert_eq!(Staking::eras_reward_points(Staking::active_era().unwrap().index), EraRewardPoints { - total: 50*3, - individual: vec![(11, 100), (21, 50)].into_iter().collect(), - }); - - start_session(2); - start_session(3); - - assert_eq!(Staking::active_era().unwrap().index, 1); - mock::make_all_reward_payment(0); + ExtBuilder::default() + .offchain_election_ext() + .validator_count(4) + .has_stakers(false) + .build() + .execute_with(|| { + crate::tests::offchain_election::build_offchain_election_test_ext(); + run_to_block(11); + Staking::on_finalize(System::block_number()); + System::set_block_number((System::block_number() + 1).into()); + Timestamp::set_timestamp(System::block_number() * 1000 + INIT_TIMESTAMP); + Session::on_initialize(System::block_number()); + + assert_eq!(Validators::::iter().count(), 4); + assert_eq!(Nominators::::iter().count(), 5); + // With 4 validators and 5 nominator, we should increase weight by: + // - (4 + 5) reads + // - 3 Writes + let final_weight = ::DbWeight::get().reads_writes(4 + 9, 3); + assert_eq!(final_weight, Staking::on_initialize(System::block_number())); }); } + #[test] -#[should_panic] -fn migrate_era_should_handle_errors_2() { - // should check that before and after migration: - // * rewards get recorded per session - // * rewards get paid per Era - // * Check that nominators are also rewarded - ExtBuilder::default().nominate(true).build_and_execute(|| { - MigrateEra::put(1); - let init_balance_10 = Balances::total_balance(&10); - let init_balance_11 = Balances::total_balance(&11); - let init_balance_20 = Balances::total_balance(&20); - let init_balance_21 = Balances::total_balance(&21); - let init_balance_100 = Balances::total_balance(&100); - let init_balance_101 = Balances::total_balance(&101); +fn payout_creates_controller() { + // Here we will test validator can set `max_nominators_payout` and it works. + // We also test that `payout_extra_nominators` works. + ExtBuilder::default().has_stakers(false).build_and_execute(|| { + let balance = 1000; + // Create three validators: + bond_validator(11, 10, balance); // Default(64) - // Check state - Payee::::insert(11, RewardDestination::Controller); - Payee::::insert(21, RewardDestination::Controller); - Payee::::insert(101, RewardDestination::Controller); + // Create a stash/controller pair + bond_nominator(1234, 1337, 100, vec![11]); - >::reward_by_ids(vec![(11, 50)]); - >::reward_by_ids(vec![(11, 50)]); - // This is the second validator of the current elected set. - >::reward_by_ids(vec![(21, 50)]); + // kill controller + assert_ok!(Balances::transfer(Origin::signed(1337), 1234, 100)); + assert_eq!(Balances::free_balance(1337), 0); + mock::start_era(1); + Staking::reward_by_ids(vec![(11, 1)]); // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_0 > 10); // Test is meaningful if reward something - - start_session(1); - - assert_eq!(Balances::total_balance(&10), init_balance_10); - assert_eq!(Balances::total_balance(&11), init_balance_11); - assert_eq!(Balances::total_balance(&20), init_balance_20); - assert_eq!(Balances::total_balance(&21), init_balance_21); - assert_eq!(Balances::total_balance(&100), init_balance_100); - assert_eq!(Balances::total_balance(&101), init_balance_101); - assert_eq_uvec!(Session::validators(), vec![11, 21]); - assert_eq!(Staking::eras_reward_points(Staking::active_era().unwrap().index), EraRewardPoints { - total: 50*3, - individual: vec![(11, 100), (21, 50)].into_iter().collect(), - }); - let part_for_10 = Perbill::from_rational_approximation::(1000, 1125); - let part_for_20 = Perbill::from_rational_approximation::(1000, 1375); - let part_for_100_from_10 = Perbill::from_rational_approximation::(125, 1125); - let part_for_100_from_20 = Perbill::from_rational_approximation::(375, 1375); - - start_session(2); - start_session(3); - - assert_eq!(Staking::active_era().unwrap().index, 1); - mock::make_all_reward_payment_before_migration(0); - - assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * total_payout_0*2/3, 2); - assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); - assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0*1/3, 2); - assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); - assert_eq_error_rate!( - Balances::total_balance(&100), - init_balance_100 - + part_for_100_from_10 * total_payout_0 * 2/3 - + part_for_100_from_20 * total_payout_0 * 1/3, - 2 - ); - assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); - - assert_eq_uvec!(Session::validators(), vec![11, 21]); - >::reward_by_ids(vec![(11, 1)]); - - // Compute total payout now for whole duration as other parameter won't change - let total_payout_1 = current_total_payout_for_duration(3 * 1000); - assert!(total_payout_1 > 10); // Test is meaningful if reward something - + assert!(total_payout_0 > 100); // Test is meaningful if reward something mock::start_era(2); - mock::make_all_reward_payment_before_migration(1); + assert_ok!(Staking::payout_stakers(Origin::signed(1337), 11, 1)); - assert_eq_error_rate!(Balances::total_balance(&10), init_balance_10 + part_for_10 * (total_payout_0 * 2/3 + total_payout_1), 2); - assert_eq_error_rate!(Balances::total_balance(&11), init_balance_11, 2); - assert_eq_error_rate!(Balances::total_balance(&20), init_balance_20 + part_for_20 * total_payout_0 * 1/3, 2); - assert_eq_error_rate!(Balances::total_balance(&21), init_balance_21, 2); - assert_eq_error_rate!( - Balances::total_balance(&100), - init_balance_100 - + part_for_100_from_10 * (total_payout_0 * 2/3 + total_payout_1) - + part_for_100_from_20 * total_payout_0 * 1/3, - 2 - ); - assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); - }); + // Controller is created + assert!(Balances::free_balance(1337) > 0); + }) } diff --git a/frame/sudo/Cargo.toml b/frame/sudo/Cargo.toml index 25988b1fe30c945ba8b53ef48944057108d2c16d..eef6015055895b6600c8ae4875c526e87eb64f44 100644 --- a/frame/sudo/Cargo.toml +++ b/frame/sudo/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-sudo" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for sudo" @@ -13,15 +13,15 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/sudo/README.md b/frame/sudo/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fb8d1974c121a465cb8ae694285d8745b1a57a6b --- /dev/null +++ b/frame/sudo/README.md @@ -0,0 +1,70 @@ +# Sudo Module + +- [`sudo::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +The Sudo module allows for a single account (called the "sudo key") +to execute dispatchable functions that require a `Root` call +or designate a new account to replace them as the sudo key. +Only one account can be the sudo key at a time. + +## Interface + +### Dispatchable Functions + +Only the sudo key can call the dispatchable functions from the Sudo module. + +* `sudo` - Make a `Root` call to a dispatchable function. +* `set_key` - Assign a new account to be the sudo key. + +## Usage + +### Executing Privileged Functions + +The Sudo module itself is not intended to be used within other modules. +Instead, you can build "privileged functions" (i.e. functions that require `Root` origin) in other modules. +You can execute these privileged functions by calling `sudo` with the sudo key account. +Privileged functions cannot be directly executed via an extrinsic. + +Learn more about privileged functions and `Root` origin in the [`Origin`] type documentation. + +### Simple Code Snippet + +This is an example of a module that exposes a privileged function: + +```rust +use frame_support::{decl_module, dispatch}; +use frame_system::ensure_root; + +pub trait Trait: frame_system::Trait {} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + #[weight = 0] + pub fn privileged_function(origin) -> dispatch::DispatchResult { + ensure_root(origin)?; + + // do something... + + Ok(()) + } + } +} +``` + +## Genesis Config + +The Sudo module depends on the [`GenesisConfig`](./struct.GenesisConfig.html). +You need to set an initial superuser account as the sudo `key`. + +## Related Modules + +* [Democracy](../pallet_democracy/index.html) + +[`Call`]: ./enum.Call.html +[`Trait`]: ./trait.Trait.html +[`Origin`]: https://docs.substrate.dev/docs/substrate-types + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/sudo/src/lib.rs b/frame/sudo/src/lib.rs index 21ae841c79242a9e0083d48802ac926bc36e07a1..113fa0dccc6c7d3db79a5be8e8f4058e126fc794 100644 --- a/frame/sudo/src/lib.rs +++ b/frame/sudo/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Sudo Module //! @@ -52,7 +53,7 @@ //! //! ``` //! use frame_support::{decl_module, dispatch}; -//! use frame_system::{self as system, ensure_root}; +//! use frame_system::ensure_root; //! //! pub trait Trait: frame_system::Trait {} //! @@ -87,20 +88,29 @@ #![cfg_attr(not(feature = "std"), no_std)] use sp_std::prelude::*; -use sp_runtime::{DispatchResult, traits::{StaticLookup, Dispatchable}}; +use sp_runtime::{DispatchResult, traits::StaticLookup}; use frame_support::{ Parameter, decl_module, decl_event, decl_storage, decl_error, ensure, }; -use frame_support::weights::{Weight, GetDispatchInfo, FunctionOf, Pays}; -use frame_system::{self as system, ensure_signed}; +use frame_support::{ + weights::{Weight, GetDispatchInfo, Pays}, + traits::UnfilteredDispatchable, + dispatch::DispatchResultWithPostInfo, +}; +use frame_system::ensure_signed; + +#[cfg(test)] +mod mock; +#[cfg(test)] +mod tests; pub trait Trait: frame_system::Trait { /// The overarching event type. type Event: From> + Into<::Event>; /// A sudo-able call. - type Call: Parameter + Dispatchable + GetDispatchInfo; + type Call: Parameter + UnfilteredDispatchable + GetDispatchInfo; } decl_module! { @@ -120,18 +130,16 @@ decl_module! { /// - One DB write (event). /// - Weight of derivative `call` execution + 10,000. /// # - #[weight = FunctionOf( - |args: (&Box<::Call>,)| args.0.get_dispatch_info().weight + 10_000, - |args: (&Box<::Call>,)| args.0.get_dispatch_info().class, - Pays::Yes, - )] - fn sudo(origin, call: Box<::Call>) { + #[weight = (call.get_dispatch_info().weight + 10_000, call.get_dispatch_info().class)] + fn sudo(origin, call: Box<::Call>) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; ensure!(sender == Self::key(), Error::::RequireSudo); - let res = call.dispatch(frame_system::RawOrigin::Root.into()); + let res = call.dispatch_bypass_filter(frame_system::RawOrigin::Root.into()); Self::deposit_event(RawEvent::Sudid(res.map(|_| ()).map_err(|e| e.error))); + // Sudo user does not pay a fee. + Ok(Pays::No.into()) } /// Authenticates the sudo key and dispatches a function call with `Root` origin. @@ -144,18 +152,16 @@ decl_module! { /// - O(1). /// - The weight of this call is defined by the caller. /// # - #[weight = FunctionOf( - |(_, &weight): (&Box<::Call>,&Weight,)| weight, - |(call, _): (&Box<::Call>,&Weight,)| call.get_dispatch_info().class, - Pays::Yes, - )] - fn sudo_unchecked_weight(origin, call: Box<::Call>, _weight: Weight) { + #[weight = (*_weight, call.get_dispatch_info().class)] + fn sudo_unchecked_weight(origin, call: Box<::Call>, _weight: Weight) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; ensure!(sender == Self::key(), Error::::RequireSudo); - let res = call.dispatch(frame_system::RawOrigin::Root.into()); + let res = call.dispatch_bypass_filter(frame_system::RawOrigin::Root.into()); Self::deposit_event(RawEvent::Sudid(res.map(|_| ()).map_err(|e| e.error))); + // Sudo user does not pay a fee. + Ok(Pays::No.into()) } /// Authenticates the current sudo key and sets the given AccountId (`new`) as the new sudo key. @@ -168,7 +174,7 @@ decl_module! { /// - One DB change. /// # #[weight = 0] - fn set_key(origin, new: ::Source) { + fn set_key(origin, new: ::Source) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; ensure!(sender == Self::key(), Error::::RequireSudo); @@ -176,6 +182,8 @@ decl_module! { Self::deposit_event(RawEvent::KeyChanged(Self::key())); >::put(new); + // Sudo user does not pay a fee. + Ok(Pays::No.into()) } /// Authenticates the sudo key and dispatches a function call with `Signed` origin from @@ -189,23 +197,18 @@ decl_module! { /// - One DB write (event). /// - Weight of derivative `call` execution + 10,000. /// # - #[weight = FunctionOf( - |args: (&::Source, &Box<::Call>,)| { - args.1.get_dispatch_info().weight + 10_000 - }, - |args: (&::Source, &Box<::Call>,)| { - args.1.get_dispatch_info().class - }, - Pays::Yes, - )] - fn sudo_as(origin, who: ::Source, call: Box<::Call>) { + #[weight = (call.get_dispatch_info().weight + 10_000, call.get_dispatch_info().class)] + fn sudo_as(origin, + who: ::Source, + call: Box<::Call> + ) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; ensure!(sender == Self::key(), Error::::RequireSudo); let who = T::Lookup::lookup(who)?; - let res = match call.dispatch(frame_system::RawOrigin::Signed(who).into()) { + let res = match call.dispatch_bypass_filter(frame_system::RawOrigin::Signed(who).into()) { Ok(_) => true, Err(e) => { sp_runtime::print(e); @@ -214,17 +217,19 @@ decl_module! { }; Self::deposit_event(RawEvent::SudoAsDone(res)); + // Sudo user does not pay a fee. + Ok(Pays::No.into()) } } } decl_event!( pub enum Event where AccountId = ::AccountId { - /// A sudo just took place. + /// A sudo just took place. [result] Sudid(DispatchResult), - /// The sudoer just switched identity; the old key is supplied. + /// The [sudoer] just switched identity; the old key is supplied. KeyChanged(AccountId), - /// A sudo just took place. + /// A sudo just took place. [result] SudoAsDone(bool), } ); diff --git a/frame/sudo/src/mock.rs b/frame/sudo/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..5052d9c52d1b4245911fac94d212bf5e54ba9f54 --- /dev/null +++ b/frame/sudo/src/mock.rs @@ -0,0 +1,176 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Test utilities + +use super::*; +use frame_support::{ + impl_outer_origin, impl_outer_dispatch, impl_outer_event, parameter_types, + weights::Weight, +}; +use sp_core::H256; +use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; +use sp_io; +use crate as sudo; +use frame_support::traits::Filter; + +// Logger module to track execution. +pub mod logger { + use super::*; + use frame_system::ensure_root; + + pub trait Trait: frame_system::Trait { + type Event: From> + Into<::Event>; + } + + decl_storage! { + trait Store for Module as Logger { + AccountLog get(fn account_log): Vec; + I32Log get(fn i32_log): Vec; + } + } + + decl_event! { + pub enum Event where AccountId = ::AccountId { + AppendI32(i32, Weight), + AppendI32AndAccount(AccountId, i32, Weight), + } + } + + decl_module! { + pub struct Module for enum Call where origin: ::Origin { + fn deposit_event() = default; + + #[weight = *weight] + fn privileged_i32_log(origin, i: i32, weight: Weight){ + // Ensure that the `origin` is `Root`. + ensure_root(origin)?; + ::append(i); + Self::deposit_event(RawEvent::AppendI32(i, weight)); + } + + #[weight = *weight] + fn non_privileged_log(origin, i: i32, weight: Weight){ + // Ensure that the `origin` is some signed account. + let sender = ensure_signed(origin)?; + ::append(i); + >::append(sender.clone()); + Self::deposit_event(RawEvent::AppendI32AndAccount(sender, i, weight)); + } + } + } +} + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +mod test_events { + pub use crate::Event; +} + +impl_outer_event! { + pub enum TestEvent for Test { + frame_system, + sudo, + logger, + } +} + +impl_outer_dispatch! { + pub enum Call for Test where origin: Origin { + sudo::Sudo, + logger::Logger, + } +} + +// For testing the pallet, we construct most of a mock runtime. This means +// first constructing a configuration type (`Test`) which `impl`s each of the +// configuration traits of pallets we want to use. +#[derive(Clone, Eq, PartialEq)] +pub struct Test; + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} + +pub struct BlockEverything; +impl Filter for BlockEverything { + fn filter(_: &Call) -> bool { + false + } +} + +impl frame_system::Trait for Test { + type BaseCallFilter = BlockEverything; + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = TestEvent; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} + +// Implement the logger module's `Trait` on the Test runtime. +impl logger::Trait for Test { + type Event = TestEvent; +} + +// Implement the sudo module's `Trait` on the Test runtime. +impl Trait for Test { + type Event = TestEvent; + type Call = Call; +} + +// Assign back to type variables in order to make dispatched calls of these modules later. +pub type Sudo = Module; +pub type Logger = logger::Module; +pub type System = frame_system::Module; + +// New types for dispatchable functions. +pub type SudoCall = sudo::Call; +pub type LoggerCall = logger::Call; + +// Build test environment by setting the root `key` for the Genesis. +pub fn new_test_ext(root_key: u64) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + GenesisConfig::{ + key: root_key, + }.assimilate_storage(&mut t).unwrap(); + t.into() +} diff --git a/frame/sudo/src/tests.rs b/frame/sudo/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..79424d2824f9026d43d3ec04332896f545ba7eb2 --- /dev/null +++ b/frame/sudo/src/tests.rs @@ -0,0 +1,169 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Tests for the module. + +use super::*; +use mock::{ + Sudo, SudoCall, Origin, Call, Test, new_test_ext, LoggerCall, Logger, System, TestEvent, +}; +use frame_support::{assert_ok, assert_noop}; + +#[test] +fn test_setup_works() { + // Environment setup, logger storage, and sudo `key` retrieval should work as expected. + new_test_ext(1).execute_with(|| { + assert_eq!(Sudo::key(), 1u64); + assert_eq!(Logger::i32_log(), vec![]); + assert_eq!(Logger::account_log(), vec![]); + }); +} + +#[test] +fn sudo_basics() { + // Configure a default test environment and set the root `key` to 1. + new_test_ext(1).execute_with(|| { + // A privileged function should work when `sudo` is passed the root `key` as `origin`. + let call = Box::new(Call::Logger(LoggerCall::privileged_i32_log(42, 1_000))); + assert_ok!(Sudo::sudo(Origin::signed(1), call)); + assert_eq!(Logger::i32_log(), vec![42i32]); + + // A privileged function should not work when `sudo` is passed a non-root `key` as `origin`. + let call = Box::new(Call::Logger(LoggerCall::privileged_i32_log(42, 1_000))); + assert_noop!(Sudo::sudo(Origin::signed(2), call), Error::::RequireSudo); + }); +} + +#[test] +fn sudo_emits_events_correctly() { + new_test_ext(1).execute_with(|| { + // Set block number to 1 because events are not emitted on block 0. + System::set_block_number(1); + + // Should emit event to indicate success when called with the root `key` and `call` is `Ok`. + let call = Box::new(Call::Logger(LoggerCall::privileged_i32_log(42, 1))); + assert_ok!(Sudo::sudo(Origin::signed(1), call)); + let expected_event = TestEvent::sudo(RawEvent::Sudid(Ok(()))); + assert!(System::events().iter().any(|a| a.event == expected_event)); + }) +} + +#[test] +fn sudo_unchecked_weight_basics() { + new_test_ext(1).execute_with(|| { + // A privileged function should work when `sudo` is passed the root `key` as origin. + let call = Box::new(Call::Logger(LoggerCall::privileged_i32_log(42, 1_000))); + assert_ok!(Sudo::sudo_unchecked_weight(Origin::signed(1), call, 1_000)); + assert_eq!(Logger::i32_log(), vec![42i32]); + + // A privileged function should not work when called with a non-root `key`. + let call = Box::new(Call::Logger(LoggerCall::privileged_i32_log(42, 1_000))); + assert_noop!( + Sudo::sudo_unchecked_weight(Origin::signed(2), call, 1_000), + Error::::RequireSudo, + ); + // `I32Log` is unchanged after unsuccessful call. + assert_eq!(Logger::i32_log(), vec![42i32]); + + // Controls the dispatched weight. + let call = Box::new(Call::Logger(LoggerCall::privileged_i32_log(42, 1))); + let sudo_unchecked_weight_call = SudoCall::sudo_unchecked_weight(call, 1_000); + let info = sudo_unchecked_weight_call.get_dispatch_info(); + assert_eq!(info.weight, 1_000); + }); +} + +#[test] +fn sudo_unchecked_weight_emits_events_correctly() { + new_test_ext(1).execute_with(|| { + // Set block number to 1 because events are not emitted on block 0. + System::set_block_number(1); + + // Should emit event to indicate success when called with the root `key` and `call` is `Ok`. + let call = Box::new(Call::Logger(LoggerCall::privileged_i32_log(42, 1))); + assert_ok!(Sudo::sudo_unchecked_weight(Origin::signed(1), call, 1_000)); + let expected_event = TestEvent::sudo(RawEvent::Sudid(Ok(()))); + assert!(System::events().iter().any(|a| a.event == expected_event)); + }) +} + +#[test] +fn set_key_basics() { + new_test_ext(1).execute_with(|| { + // A root `key` can change the root `key` + assert_ok!(Sudo::set_key(Origin::signed(1), 2)); + assert_eq!(Sudo::key(), 2u64); + }); + + new_test_ext(1).execute_with(|| { + // A non-root `key` will trigger a `RequireSudo` error and a non-root `key` cannot change the root `key`. + assert_noop!(Sudo::set_key(Origin::signed(2), 3), Error::::RequireSudo); + }); +} + +#[test] +fn set_key_emits_events_correctly() { + new_test_ext(1).execute_with(|| { + // Set block number to 1 because events are not emitted on block 0. + System::set_block_number(1); + + // A root `key` can change the root `key`. + assert_ok!(Sudo::set_key(Origin::signed(1), 2)); + let expected_event = TestEvent::sudo(RawEvent::KeyChanged(1)); + assert!(System::events().iter().any(|a| a.event == expected_event)); + // Double check. + assert_ok!(Sudo::set_key(Origin::signed(2), 4)); + let expected_event = TestEvent::sudo(RawEvent::KeyChanged(2)); + assert!(System::events().iter().any(|a| a.event == expected_event)); + }); +} + +#[test] +fn sudo_as_basics() { + new_test_ext(1).execute_with(|| { + // A privileged function will not work when passed to `sudo_as`. + let call = Box::new(Call::Logger(LoggerCall::privileged_i32_log(42, 1_000))); + assert_ok!(Sudo::sudo_as(Origin::signed(1), 2, call)); + assert_eq!(Logger::i32_log(), vec![]); + assert_eq!(Logger::account_log(), vec![]); + + // A non-privileged function should not work when called with a non-root `key`. + let call = Box::new(Call::Logger(LoggerCall::non_privileged_log(42, 1))); + assert_noop!(Sudo::sudo_as(Origin::signed(3), 2, call), Error::::RequireSudo); + + // A non-privileged function will work when passed to `sudo_as` with the root `key`. + let call = Box::new(Call::Logger(LoggerCall::non_privileged_log(42, 1))); + assert_ok!(Sudo::sudo_as(Origin::signed(1), 2, call)); + assert_eq!(Logger::i32_log(), vec![42i32]); + // The correct user makes the call within `sudo_as`. + assert_eq!(Logger::account_log(), vec![2]); + }); +} + +#[test] +fn sudo_as_emits_events_correctly() { + new_test_ext(1).execute_with(|| { + // Set block number to 1 because events are not emitted on block 0. + System::set_block_number(1); + + // A non-privileged function will work when passed to `sudo_as` with the root `key`. + let call = Box::new(Call::Logger(LoggerCall::non_privileged_log(42, 1))); + assert_ok!(Sudo::sudo_as(Origin::signed(1), 2, call)); + let expected_event = TestEvent::sudo(RawEvent::SudoAsDone(true)); + assert!(System::events().iter().any(|a| a.event == expected_event)); + }); +} diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index 0168705da7e343f682dd38209a15bf93efbc126c..005638824b0ca692ba5f73777a5d480db5274156 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-support" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Support code for the runtime." @@ -14,25 +14,27 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] log = "0.4" serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -frame-metadata = { version = "11.0.0-dev", default-features = false, path = "../metadata" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-tracing = { version = "2.0.0-dev", default-features = false, path = "../../primitives/tracing" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-arithmetic = { version = "2.0.0-dev", default-features = false, path = "../../primitives/arithmetic" } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } -frame-support-procedural = { version = "2.0.0-dev", path = "./procedural" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +frame-metadata = { version = "11.0.0-rc6", default-features = false, path = "../metadata" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-tracing = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/tracing" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-arithmetic = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/arithmetic" } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/inherents" } +frame-support-procedural = { version = "2.0.0-rc6", path = "./procedural" } paste = "0.1.6" once_cell = { version = "1", default-features = false, optional = true } -sp-state-machine = { version = "0.8.0-dev", optional = true, path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-rc6", optional = true, path = "../../primitives/state-machine" } bitmask = { version = "0.5.0", default-features = false } impl-trait-for-tuples = "0.1.3" +smallvec = "1.4.1" [dev-dependencies] pretty_assertions = "0.6.1" -frame-system = { version = "2.0.0-dev", path = "../system" } +frame-system = { version = "2.0.0-rc6", path = "../system" } +parity-util-mem = { version = "0.7.0", features = ["primitive-types"] } [features] default = ["std"] diff --git a/frame/support/README.md b/frame/support/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2282870aca05ca8393e5d6bef1ddb059e0466a72 --- /dev/null +++ b/frame/support/README.md @@ -0,0 +1,3 @@ +Support code for the runtime. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/support/procedural/Cargo.toml b/frame/support/procedural/Cargo.toml index 55e551343214d0711945d6c3d3008d03086836dd..dc62a8379165435bd9faa2d3bf7bbf1a9ee4aa77 100644 --- a/frame/support/procedural/Cargo.toml +++ b/frame/support/procedural/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-support-procedural" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Proc macro of Support code for the runtime." @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] proc-macro = true [dependencies] -frame-support-procedural-tools = { version = "2.0.0-dev", path = "./tools" } +frame-support-procedural-tools = { version = "2.0.0-rc6", path = "./tools" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full"] } diff --git a/frame/support/procedural/src/construct_runtime/mod.rs b/frame/support/procedural/src/construct_runtime/mod.rs index b74a27e7ba936c982512438fc47d5ab7dd5dc379..57827b0673916da0b0002e6546f3ce46f8f90b80 100644 --- a/frame/support/procedural/src/construct_runtime/mod.rs +++ b/frame/support/procedural/src/construct_runtime/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. mod parse; @@ -58,7 +59,7 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result},`", + Please add this line: `System: frame_system::{Module, Call, Storage, Config, Event},`", )) } }; @@ -86,14 +87,19 @@ fn construct_runtime_parsed(definition: RuntimeDefinition) -> Result Result( ) -> TokenStream2 { let modules_tokens = module_declarations.filter_map(|module_declaration| { let maybe_config_part = module_declaration.find_part("Inherent"); - maybe_config_part.map(|config_part| { - let arg = config_part - .args - .as_ref() - .and_then(|parens| parens.content.inner.iter().next()) - .unwrap_or(&module_declaration.name); + maybe_config_part.map(|_| { let name = &module_declaration.name; - quote!(#name : #arg,) + quote!(#name,) }) }); quote!( #scrate::impl_outer_inherent!( - impl Inherents where Block = #block, UncheckedExtrinsic = #unchecked_extrinsic { + impl Inherents where + Block = #block, + UncheckedExtrinsic = #unchecked_extrinsic + { #(#modules_tokens)* } ); @@ -405,3 +411,17 @@ fn find_system_module<'a>( .find(|decl| decl.name == SYSTEM_MODULE_NAME) .map(|decl| &decl.module) } + +fn decl_integrity_test(scrate: &TokenStream2) -> TokenStream2 { + quote!( + #[cfg(test)] + mod __construct_runtime_integrity_test { + use super::*; + + #[test] + pub fn runtime_integrity_tests() { + ::integrity_test(); + } + } + ) +} diff --git a/frame/support/procedural/src/construct_runtime/parse.rs b/frame/support/procedural/src/construct_runtime/parse.rs index 4a81a7efd6b77ad09cad319a88eb16e8a4589e97..c8481480baac5e452b8294fec85bc367c59244ab 100644 --- a/frame/support/procedural/src/construct_runtime/parse.rs +++ b/frame/support/procedural/src/construct_runtime/parse.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use frame_support_procedural_tools::syn_ext as ext; use proc_macro2::Span; @@ -278,18 +279,6 @@ impl ModulePartKeyword { Ident::new(self.name(), self.span()) } - /// Returns `true` if this module part allows to have an argument. - /// - /// For example `Inherent(Timestamp)`. - fn allows_arg(&self) -> bool { - Self::all_allow_arg().iter().any(|n| *n == self.name()) - } - - /// Returns the names of all module parts that allow to have an argument. - fn all_allow_arg() -> &'static [&'static str] { - &["Inherent"] - } - /// Returns `true` if this module part is allowed to have generic arguments. fn allows_generic(&self) -> bool { Self::all_generic_arg().iter().any(|n| *n == self.name()) @@ -320,7 +309,6 @@ impl Spanned for ModulePartKeyword { pub struct ModulePart { pub keyword: ModulePartKeyword, pub generics: syn::Generics, - pub args: Option>>, } impl Parse for ModulePart { @@ -338,27 +326,10 @@ impl Parse for ModulePart { ); return Err(syn::Error::new(keyword.span(), msg)); } - let args = if input.peek(token::Paren) { - if !keyword.allows_arg() { - let syn::group::Parens { token: parens, .. } = syn::group::parse_parens(input)?; - let valid_names = ModulePart::format_names(ModulePartKeyword::all_allow_arg()); - let msg = format!( - "`{}` is not allowed to have arguments in parens. \ - Only the following modules are allowed to have arguments in parens: {}.", - keyword.name(), - valid_names, - ); - return Err(syn::Error::new(parens.span, msg)); - } - Some(input.parse()?) - } else { - None - }; Ok(Self { keyword, generics, - args, }) } } diff --git a/frame/support/procedural/src/lib.rs b/frame/support/procedural/src/lib.rs index 17b1efdcd488cb8ef68ffb499b6d459820c6522f..054d90d7bbaebfbc0324c523f6f048a56b3d6bef 100644 --- a/frame/support/procedural/src/lib.rs +++ b/frame/support/procedural/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. // tag::description[] //! Proc macro of Support code for the runtime. @@ -22,6 +23,7 @@ mod storage; mod construct_runtime; +mod transactional; use proc_macro::TokenStream; @@ -276,10 +278,8 @@ pub fn decl_storage(input: TokenStream) -> TokenStream { /// - `Event` or `Event` (if the event is generic) /// - `Origin` or `Origin` (if the origin is generic) /// - `Config` or `Config` (if the config is generic) -/// - `Inherent ( $(CALL),* )` - If the module provides/can check inherents. The optional parameter -/// is for modules that use a `Call` from a different module as -/// inherent. -/// - `ValidateUnsigned` - If the module validates unsigned extrinsics. +/// - `Inherent` - If the module provides/can check inherents. +/// - `ValidateUnsigned` - If the module validates unsigned extrinsics. /// /// # Note /// @@ -290,3 +290,28 @@ pub fn decl_storage(input: TokenStream) -> TokenStream { pub fn construct_runtime(input: TokenStream) -> TokenStream { construct_runtime::construct_runtime(input) } + +/// Execute the annotated function in a new storage transaction. +/// +/// The return type of the annotated function must be `Result`. All changes to storage performed +/// by the annotated function are discarded if it returns `Err`, or committed if `Ok`. +/// +/// #Example +/// +/// ```nocompile +/// #[transactional] +/// fn value_commits(v: u32) -> result::Result { +/// Value::set(v); +/// Ok(v) +/// } +/// +/// #[transactional] +/// fn value_rollbacks(v: u32) -> result::Result { +/// Value::set(v); +/// Err("nah") +/// } +/// ``` +#[proc_macro_attribute] +pub fn transactional(attr: TokenStream, input: TokenStream) -> TokenStream { + transactional::transactional(attr, input) +} diff --git a/frame/support/procedural/src/storage/genesis_config/builder_def.rs b/frame/support/procedural/src/storage/genesis_config/builder_def.rs index 87255ee481b37b8debf9d2ff25b55775e8fe46c2..a045794529c958d908dfbb34ff6b847c9af52235 100644 --- a/frame/support/procedural/src/storage/genesis_config/builder_def.rs +++ b/frame/support/procedural/src/storage/genesis_config/builder_def.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Builder logic definition used to build genesis storage. @@ -54,10 +55,16 @@ impl BuilderDef { data = Some(match &line.storage_type { StorageLineTypeDef::Simple(_) if line.is_option => quote_spanned!(builder.span() => - let data = (#builder)(self); + // NOTE: the type of `data` is specified when used later in the code + let builder: fn(&Self) -> _ = #builder; + let data = builder(self); let data = Option::as_ref(&data); ), - _ => quote_spanned!(builder.span() => let data = &(#builder)(self); ), + _ => quote_spanned!(builder.span() => + // NOTE: the type of `data` is specified when used later in the code + let builder: fn(&Self) -> _ = #builder; + let data = &builder(self); + ), }); } else if let Some(config) = &line.config { is_generic |= line.is_generic; diff --git a/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs b/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs index 9b6ddc92178bd6f981fde39c47933412c565c31e..6339134ea0d22681ac413b60613b66080dec10bd 100644 --- a/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs +++ b/frame/support/procedural/src/storage/genesis_config/genesis_config_def.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Genesis config definition. diff --git a/frame/support/procedural/src/storage/genesis_config/mod.rs b/frame/support/procedural/src/storage/genesis_config/mod.rs index eeeca150d9b9b8419922f73f1ef51ed3ce46e095..27fbdd2cd38b5c91e02e44a1c894a38f1906ec73 100644 --- a/frame/support/procedural/src/storage/genesis_config/mod.rs +++ b/frame/support/procedural/src/storage/genesis_config/mod.rs @@ -1,25 +1,26 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Declaration of genesis config structure and implementation of build storage trait and //! functions. use proc_macro2::{TokenStream, Span}; use quote::quote; -use super::{DeclStorageDefExt, instance_trait::DEFAULT_INSTANTIABLE_TRAIT_NAME}; +use super::DeclStorageDefExt; use genesis_config_def::GenesisConfigDef; use builder_def::BuilderDef; @@ -103,10 +104,9 @@ fn impl_build_storage( let name = syn::Ident::new(DEFAULT_INSTANCE_NAME, Span::call_site()); quote!( #name ) }); - let inherent_instance_bound = def.optional_instance_bound.clone().unwrap_or_else(|| { - let bound = syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site()); - quote!( #inherent_instance: #bound ) - }); + let inherent_instance_bound = quote!( + #inherent_instance: #scrate::traits::Instance + ); let build_storage_impl = quote!( <#runtime_generic: #runtime_trait, #inherent_instance_bound> diff --git a/frame/support/procedural/src/storage/getters.rs b/frame/support/procedural/src/storage/getters.rs index ae0e646fcd73aaf0d398d82755372dbfe9736da6..5507db4630596f32addac764289d3dd71efa643b 100644 --- a/frame/support/procedural/src/storage/getters.rs +++ b/frame/support/procedural/src/storage/getters.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Implementation of getters on module structure. diff --git a/frame/support/procedural/src/storage/instance_trait.rs b/frame/support/procedural/src/storage/instance_trait.rs index b2f0ad9c06c037d075a1781b0ceda194ce0d9133..a28c3ae622082300e8f2cfa29d639b15c5c1be42 100644 --- a/frame/support/procedural/src/storage/instance_trait.rs +++ b/frame/support/procedural/src/storage/instance_trait.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Implementation of the trait instance and the instance structures implementing it. //! (For not instantiable traits there is still the inherent instance implemented). @@ -23,7 +24,6 @@ use super::DeclStorageDefExt; const NUMBER_OF_INSTANCE: usize = 16; pub(crate) const INHERENT_INSTANCE_NAME: &str = "__InherentHiddenInstance"; -pub(crate) const DEFAULT_INSTANTIABLE_TRAIT_NAME: &str = "__GeneratedInstantiable"; // Used to generate an instance implementation. struct InstanceDef { @@ -35,7 +35,7 @@ struct InstanceDef { pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStream { let mut impls = TokenStream::new(); - impls.extend(create_instance_trait(def)); + impls.extend(reexport_instance_trait(scrate, def)); // Implementation of instances. if let Some(module_instance) = &def.module_instance { @@ -69,6 +69,8 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre .and_then(|i| i.instance_default.as_ref()) { impls.extend(quote! { + /// Hidden instance generated to be internally used when module is used without + /// instance. #[doc(hidden)] pub type #inherent_instance = #default_instance; }); @@ -76,7 +78,11 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre let instance_def = InstanceDef { prefix: String::new(), instance_struct: inherent_instance, - doc: quote!(#[doc(hidden)]), + doc: quote!( + /// Hidden instance generated to be internally used when module is used without + /// instance. + #[doc(hidden)] + ), }; impls.extend(create_and_impl_instance_struct(scrate, &instance_def, def)); } @@ -84,27 +90,19 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre impls } -fn create_instance_trait( +fn reexport_instance_trait( + scrate: &TokenStream, def: &DeclStorageDefExt, ) -> TokenStream { - let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone()) - .unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); - - let optional_hide = if def.module_instance.is_some() { - quote!() + if let Some(i) = def.module_instance.as_ref() { + let instance_trait = &i.instance_trait; + quote!( + /// Local import of frame_support::traits::Instance + // This import is not strictly needed but made in order not to have breaking change. + use #scrate::traits::Instance as #instance_trait; + ) } else { - quote!(#[doc(hidden)]) - }; - - quote! { - /// Tag a type as an instance of a module. - /// - /// Defines storage prefixes, they must be unique. - #optional_hide - pub trait #instance_trait: 'static { - /// The prefix used by any storage entry of an instance. - const PREFIX: &'static str; - } + quote!() } } @@ -113,8 +111,7 @@ fn create_and_impl_instance_struct( instance_def: &InstanceDef, def: &DeclStorageDefExt, ) -> TokenStream { - let instance_trait = def.module_instance.as_ref().map(|i| i.instance_trait.clone()) - .unwrap_or_else(|| syn::Ident::new(DEFAULT_INSTANTIABLE_TRAIT_NAME, Span::call_site())); + let instance_trait = quote!( #scrate::traits::Instance ); let instance_struct = &instance_def.instance_struct; let prefix = format!("{}{}", instance_def.prefix, def.crate_name.to_string()); diff --git a/frame/support/procedural/src/storage/metadata.rs b/frame/support/procedural/src/storage/metadata.rs index bb23c99d9df5160bc3f09d780c7960bcf9c0dfa2..065320cd018aef1061c05e8140777eec50efdbb8 100644 --- a/frame/support/procedural/src/storage/metadata.rs +++ b/frame/support/procedural/src/storage/metadata.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Implementation of `storage_metadata` on module structure, used by construct_runtime. diff --git a/frame/support/procedural/src/storage/mod.rs b/frame/support/procedural/src/storage/mod.rs index e8599c52a907173f5c19f1359bc43205667a749e..0aa0a3cad7cd1e1ec8b55f57781ffa2bf7265a51 100644 --- a/frame/support/procedural/src/storage/mod.rs +++ b/frame/support/procedural/src/storage/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! `decl_storage` input definition and expansion. @@ -248,7 +249,7 @@ impl StorageLineDefExt { StorageLineTypeDef::DoubleMap(map) => map.value.clone(), }; let is_option = ext::extract_type_option(&query_type).is_some(); - let value_type = ext::extract_type_option(&query_type).unwrap_or(query_type.clone()); + let value_type = ext::extract_type_option(&query_type).unwrap_or_else(|| query_type.clone()); let module_runtime_generic = &def.module_runtime_generic; let module_runtime_trait = &def.module_runtime_trait; @@ -327,7 +328,7 @@ impl StorageLineDefExt { pub enum StorageLineTypeDef { Map(MapDef), - DoubleMap(DoubleMapDef), + DoubleMap(Box), Simple(syn::Type), } @@ -415,6 +416,8 @@ pub fn decl_storage_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStr StorageMap as _, StorageDoubleMap as _, StoragePrefixedMap as _, + IterableStorageMap as _, + IterableStorageDoubleMap as _, }; #scrate_decl diff --git a/frame/support/procedural/src/storage/parse.rs b/frame/support/procedural/src/storage/parse.rs index beb9beff707b3c8254cb2ea1c5ff6418cc77e0b6..504af6d0ffcad1900ce0db8aea2670064cae7b7f 100644 --- a/frame/support/procedural/src/storage/parse.rs +++ b/frame/support/procedural/src/storage/parse.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Parsing of decl_storage input. @@ -197,7 +198,7 @@ impl_parse_for_opt!(DeclStorageBuild => keyword::build); #[derive(ToTokens, Debug)] enum DeclStorageType { Map(DeclStorageMap), - DoubleMap(DeclStorageDoubleMap), + DoubleMap(Box), Simple(syn::Type), } @@ -323,7 +324,16 @@ fn get_module_instance( instantiable: Option, default_instance: Option, ) -> syn::Result> { - let right_syntax = "Should be $Instance: $Instantiable = $DefaultInstance"; + let right_syntax = "Should be $I: $Instance = $DefaultInstance"; + + if instantiable.as_ref().map_or(false, |i| i != "Instance") { + let msg = format!( + "Instance trait must be named `Instance`, other names are no longer supported, because \ + it is now defined at frame_support::traits::Instance. Expect `Instance` found `{}`", + instantiable.as_ref().unwrap(), + ); + return Err(syn::Error::new(instantiable.span(), msg)); + } match (instance, instantiable, default_instance) { (Some(instance), Some(instantiable), default_instance) => { @@ -477,13 +487,13 @@ fn parse_storage_line_defs( } ), DeclStorageType::DoubleMap(map) => super::StorageLineTypeDef::DoubleMap( - super::DoubleMapDef { + Box::new(super::DoubleMapDef { hasher1: map.hasher1.inner.ok_or_else(no_hasher_error)?.into(), hasher2: map.hasher2.inner.ok_or_else(no_hasher_error)?.into(), key1: map.key1, key2: map.key2, value: map.value, - } + }) ), DeclStorageType::Simple(expr) => super::StorageLineTypeDef::Simple(expr), }; diff --git a/frame/support/procedural/src/storage/storage_struct.rs b/frame/support/procedural/src/storage/storage_struct.rs index cbd477354e820946a9f3f1692d70c3a7f2a52ca5..e89b06770a6c507475df5bf4daab7ee19ac979b0 100644 --- a/frame/support/procedural/src/storage/storage_struct.rs +++ b/frame/support/procedural/src/storage/storage_struct.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Implementation of storage structures and implementation of storage traits on them. @@ -85,7 +86,10 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre Ident::new(INHERENT_INSTANCE_NAME, Span::call_site()) }; - let storage_name_str = syn::LitStr::new(&line.name.to_string(), line.name.span()); + let storage_name_bstr = syn::LitByteStr::new( + line.name.to_string().as_ref(), + line.name.span() + ); let storage_generator_trait = &line.storage_generator_trait; let storage_struct = &line.storage_struct; @@ -102,11 +106,11 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre type Query = #query_type; fn module_prefix() -> &'static [u8] { - #instance_or_inherent::PREFIX.as_bytes() + <#instance_or_inherent as #scrate::traits::Instance>::PREFIX.as_bytes() } fn storage_prefix() -> &'static [u8] { - #storage_name_str.as_bytes() + #storage_name_bstr } fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { @@ -126,11 +130,11 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre for #storage_struct #optional_storage_where_clause { fn module_prefix() -> &'static [u8] { - #instance_or_inherent::PREFIX.as_bytes() + <#instance_or_inherent as #scrate::traits::Instance>::PREFIX.as_bytes() } fn storage_prefix() -> &'static [u8] { - #storage_name_str.as_bytes() + #storage_name_bstr } } @@ -141,11 +145,11 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre type Hasher = #scrate::#hasher; fn module_prefix() -> &'static [u8] { - #instance_or_inherent::PREFIX.as_bytes() + <#instance_or_inherent as #scrate::traits::Instance>::PREFIX.as_bytes() } fn storage_prefix() -> &'static [u8] { - #storage_name_str.as_bytes() + #storage_name_bstr } fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { @@ -166,11 +170,11 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre for #storage_struct #optional_storage_where_clause { fn module_prefix() -> &'static [u8] { - #instance_or_inherent::PREFIX.as_bytes() + <#instance_or_inherent as #scrate::traits::Instance>::PREFIX.as_bytes() } fn storage_prefix() -> &'static [u8] { - #storage_name_str.as_bytes() + #storage_name_bstr } } @@ -184,11 +188,11 @@ pub fn decl_and_impl(scrate: &TokenStream, def: &DeclStorageDefExt) -> TokenStre type Hasher2 = #scrate::#hasher2; fn module_prefix() -> &'static [u8] { - #instance_or_inherent::PREFIX.as_bytes() + <#instance_or_inherent as #scrate::traits::Instance>::PREFIX.as_bytes() } fn storage_prefix() -> &'static [u8] { - #storage_name_str.as_bytes() + #storage_name_bstr } fn from_optional_value_to_query(v: Option<#value_type>) -> Self::Query { diff --git a/frame/support/procedural/src/storage/store_trait.rs b/frame/support/procedural/src/storage/store_trait.rs index 96281e408e958342777aa53c4f973d6cfa9178a7..7efe65b5f31783596841e0c45a6083229ade15c5 100644 --- a/frame/support/procedural/src/storage/store_trait.rs +++ b/frame/support/procedural/src/storage/store_trait.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Declaration of store trait and implementation on module structure. diff --git a/frame/support/procedural/src/transactional.rs b/frame/support/procedural/src/transactional.rs new file mode 100644 index 0000000000000000000000000000000000000000..a001f44c4d482ba9d2df14a5308a7a5a0b0091b7 --- /dev/null +++ b/frame/support/procedural/src/transactional.rs @@ -0,0 +1,40 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, ItemFn}; + +pub fn transactional(_attr: TokenStream, input: TokenStream) -> TokenStream { + let ItemFn { attrs, vis, sig, block } = parse_macro_input!(input as ItemFn); + + let output = quote! { + #(#attrs)* + #vis #sig { + use frame_support::storage::{with_transaction, TransactionOutcome}; + with_transaction(|| { + let r = #block; + if r.is_ok() { + TransactionOutcome::Commit(r) + } else { + TransactionOutcome::Rollback(r) + } + }) + } + }; + output.into() +} diff --git a/frame/support/procedural/tools/Cargo.toml b/frame/support/procedural/tools/Cargo.toml index f64ad9b1e66edcd87640a73ce257ab0a74730713..131d47474e7f9e5996bd462bedd0d5ad43d4f3c7 100644 --- a/frame/support/procedural/tools/Cargo.toml +++ b/frame/support/procedural/tools/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-support-procedural-tools" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Proc macro helpers for procedural macros" @@ -12,7 +12,7 @@ description = "Proc macro helpers for procedural macros" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -frame-support-procedural-tools-derive = { version = "2.0.0-dev", path = "./derive" } +frame-support-procedural-tools-derive = { version = "2.0.0-rc6", path = "./derive" } proc-macro2 = "1.0.6" quote = "1.0.3" syn = { version = "1.0.7", features = ["full", "visit"] } diff --git a/frame/support/procedural/tools/derive/Cargo.toml b/frame/support/procedural/tools/derive/Cargo.toml index 75721508e8f0f138d7d4c64da1c1a4822530b00c..327409692f46450a00425991b482bc8d794d89d1 100644 --- a/frame/support/procedural/tools/derive/Cargo.toml +++ b/frame/support/procedural/tools/derive/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-support-procedural-tools-derive" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Use to derive parsing for parsing struct." diff --git a/frame/support/procedural/tools/derive/src/lib.rs b/frame/support/procedural/tools/derive/src/lib.rs index 0c5930892b1b5321857d05993170acebf7cd2515..6e5d6c896cbf8653da160ab9074101ce6bc2b543 100644 --- a/frame/support/procedural/tools/derive/src/lib.rs +++ b/frame/support/procedural/tools/derive/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // tag::description[] //! Use to derive parsing for parsing struct. @@ -29,7 +30,7 @@ pub(crate) fn fields_idents( fields: impl Iterator, ) -> impl Iterator { fields.enumerate().map(|(ix, field)| { - field.ident.clone().map(|i| quote!{#i}).unwrap_or_else(|| { + field.ident.map(|i| quote!{#i}).unwrap_or_else(|| { let f_ix: syn::Ident = syn::Ident::new(&format!("f_{}", ix), Span::call_site()); quote!( #f_ix ) }) @@ -40,7 +41,7 @@ pub(crate) fn fields_access( fields: impl Iterator, ) -> impl Iterator { fields.enumerate().map(|(ix, field)| { - field.ident.clone().map(|i| quote!( #i )).unwrap_or_else(|| { + field.ident.map(|i| quote!( #i )).unwrap_or_else(|| { let f_ix: syn::Index = syn::Index { index: ix as u32, span: Span::call_site(), diff --git a/frame/support/procedural/tools/src/lib.rs b/frame/support/procedural/tools/src/lib.rs index 102fee0e18ed0e2bd713967e99048f742273f21b..0033787a7c0450629c693037f73fd43e37d76504 100644 --- a/frame/support/procedural/tools/src/lib.rs +++ b/frame/support/procedural/tools/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. // tag::description[] //! Proc macro helpers for procedural macros diff --git a/frame/support/procedural/tools/src/syn_ext.rs b/frame/support/procedural/tools/src/syn_ext.rs index 45774372325aeebc6b6a89a4aef3efdb480a658d..2ba4cf3f28a11f1935ec50d76f025e543ae3cb06 100644 --- a/frame/support/procedural/tools/src/syn_ext.rs +++ b/frame/support/procedural/tools/src/syn_ext.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // tag::description[] //! Extension to syn types, mainly for parsing diff --git a/frame/support/src/debug.rs b/frame/support/src/debug.rs index 4b7ff6cc393366791d1225a4dbd048379a63b4d5..e4a48068460c6cc038577d7d8eae9304617094fa 100644 --- a/frame/support/src/debug.rs +++ b/frame/support/src/debug.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Runtime debugging and logging utilities. //! diff --git a/frame/support/src/dispatch.rs b/frame/support/src/dispatch.rs index df887fa2c42ca850adfed27451c0949bda299428..442a99effadbc646903661c86b6a7e374241ba5d 100644 --- a/frame/support/src/dispatch.rs +++ b/frame/support/src/dispatch.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Dispatch system. Contains a macro for defining runtime modules and //! generating values representing lazy module function calls. @@ -28,7 +29,7 @@ pub use crate::weights::{ PaysFee, PostDispatchInfo, WithPostDispatchInfo, }; pub use sp_runtime::{traits::Dispatchable, DispatchError}; -pub use crate::traits::{CallMetadata, GetCallMetadata, GetCallName}; +pub use crate::traits::{CallMetadata, GetCallMetadata, GetCallName, UnfilteredDispatchable}; /// The return typ of a `Dispatchable` in frame. When returned explicitly from /// a dispatchable function it allows overriding the default `PostDispatchInfo` @@ -46,15 +47,14 @@ pub type DispatchResult = Result<(), sp_runtime::DispatchError>; pub type DispatchErrorWithPostInfo = sp_runtime::DispatchErrorWithPostInfo; -/// Serializable version of Dispatchable. -/// This value can be used as a "function" in an extrinsic. +/// Serializable version of pallet dispatchable. pub trait Callable { - type Call: Dispatchable + Codec + Clone + PartialEq + Eq; + type Call: UnfilteredDispatchable + Codec + Clone + PartialEq + Eq; } // dirty hack to work around serde_derive issue // https://github.com/rust-lang/rust/issues/51331 -pub type CallableCallFor = >::Call; +pub type CallableCallFor = >::Call; /// A type that can be used as a parameter in a dispatchable function. /// @@ -70,7 +70,7 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_system::{self as system, Trait, ensure_signed}; +/// # use frame_system::{Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { /// @@ -112,7 +112,7 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_system::{self as system, Trait, ensure_signed}; +/// # use frame_system::{Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { /// #[weight = 0] @@ -147,7 +147,7 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch::{DispatchResultWithPostInfo, WithPostDispatchInfo}; -/// # use frame_system::{self as system, Trait, ensure_signed}; +/// # use frame_system::{Trait, ensure_signed}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { /// #[weight = 1_000_000] @@ -167,6 +167,28 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # fn main() {} /// ``` /// +/// ### Transactional Function Example +/// +/// Transactional function discards all changes to storage if it returns `Err`, or commits if +/// `Ok`, via the #\[transactional\] attribute. Note the attribute must be after #\[weight\]. +/// +/// ``` +/// # #[macro_use] +/// # extern crate frame_support; +/// # use frame_support::transactional; +/// # use frame_system::Trait; +/// decl_module! { +/// pub struct Module for enum Call where origin: T::Origin { +/// #[weight = 0] +/// #[transactional] +/// fn my_short_function(origin) { +/// // Your implementation +/// } +/// } +/// } +/// # fn main() {} +/// ``` +/// /// ### Privileged Function Example /// /// A privileged function checks that the origin of the call is `ROOT`. @@ -175,7 +197,7 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # #[macro_use] /// # extern crate frame_support; /// # use frame_support::dispatch; -/// # use frame_system::{self as system, Trait, ensure_signed, ensure_root}; +/// # use frame_system::{Trait, ensure_signed, ensure_root}; /// decl_module! { /// pub struct Module for enum Call where origin: T::Origin { /// #[weight = 0] @@ -189,6 +211,14 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// # fn main() {} /// ``` /// +/// ### Attributes on Functions +/// +/// Attributes on functions are supported, but must be in the order of: +/// 1. Optional #\[doc\] attribute. +/// 2. #\[weight\] attribute. +/// 3. Optional function attributes, for instance #\[transactional\]. Those function attributes will be written +/// only on the dispatchable functions implemented on `Module`, not on the `Call` enum variant. +/// /// ## Multiple Module Instances Example /// /// A Substrate module can be built such that multiple instances of the same module can be used within a single @@ -269,8 +299,11 @@ impl Parameter for T where T: Codec + EncodeLike + Clone + Eq + fmt::Debug {} /// * `fn on_finalize() -> frame_support::weights::Weight` /// /// * `offchain_worker`: Executes at the beginning of a block and produces extrinsics for a future block -/// upon completion. Using this function will implement the -/// [`OffchainWorker`](./traits/trait.OffchainWorker.html) trait. +/// upon completion. Using this function will implement the +/// [`OffchainWorker`](./traits/trait.OffchainWorker.html) trait. +/// * `integrity_test`: Executes in a test generated by `construct_runtime`, note it doesn't +/// execute in an externalities-provided environment. Implement +/// [`IntegrityTest`](./trait.IntegrityTest.html) trait. #[macro_export] macro_rules! decl_module { // Entry point #1. @@ -280,7 +313,7 @@ macro_rules! decl_module { $trait_instance:ident: $trait_name:ident $( , I: $instantiable:path $( = $module_default_instance:path )? )? > - for enum $call_type:ident where origin: $origin_type:ty $(, $where_ty:ty: $where_bound:path )* { + for enum $call_type:ident where origin: $origin_type:ty $(, $where_ty:ty: $where_bound:path )* $(,)? { $( $t:tt )* } ) => { @@ -289,7 +322,7 @@ macro_rules! decl_module { pub struct $mod_type< $trait_instance: $trait_name $(, I: $instantiable $(= $module_default_instance)?)? > - for enum $call_type where origin: $origin_type, system = system + for enum $call_type where origin: $origin_type, system = frame_system { $( $where_ty: $where_bound ),* } {} {} @@ -298,6 +331,7 @@ macro_rules! decl_module { {} {} {} + {} [] $($t)* ); @@ -313,6 +347,7 @@ macro_rules! decl_module { origin: $origin_type:ty, system = $system:ident $(, $where_ty:ty: $where_bound:path )* + $(,)? { $($t:tt)* } @@ -331,6 +366,7 @@ macro_rules! decl_module { {} {} {} + {} [] $($t)* ); @@ -349,6 +385,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $vis:vis fn deposit_event() = default; @@ -366,6 +403,7 @@ macro_rules! decl_module { { $( $offchain )* } { $( $constants )* } { $( $error_type )* } + { $( $integrity_test)* } [ $( $dispatchables )* ] $($rest)* ); @@ -382,6 +420,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $vis:vis fn deposit_event @@ -391,6 +430,29 @@ macro_rules! decl_module { "`deposit_event` function is reserved and must follow the syntax: `$vis:vis fn deposit_event() = default;`" ); }; + // Compile error on `deposit_event` being added a second time. + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )+ } + { $( $on_initialize:tt )* } + { $( $on_runtime_upgrade:tt )* } + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { $( $error_type:tt )* } + { $( $integrity_test:tt )* } + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + $vis:vis fn deposit_event() = default; + $($rest:tt)* + ) => { + compile_error!("`deposit_event` can only be passed once as input."); + }; // Add on_finalize (@normalize $(#[$attr:meta])* @@ -404,6 +466,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* fn on_finalize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } @@ -423,6 +486,7 @@ macro_rules! decl_module { { $( $offchain )* } { $( $constants )* } { $( $error_type )* } + { $( $integrity_test)* } [ $( $dispatchables )* ] $($rest)* ); @@ -440,6 +504,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* #[weight = $weight:expr] @@ -451,6 +516,30 @@ macro_rules! decl_module { `on_initialize` or `on_runtime_upgrade` instead" ); }; + // Compile error on `on_finalize` being added a second time. + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )* } + { $( $on_runtime_upgrade:tt )* } + { $( $on_finalize:tt )+ } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { $( $error_type:tt )* } + { $( $integrity_test:tt )* } + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + #[weight = $weight:expr] + fn on_finalize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } + $($rest:tt)* + ) => { + compile_error!("`on_finalize` can only be passed once as input."); + }; // compile_error on_runtime_upgrade, without a given weight removed syntax. (@normalize $(#[$attr:meta])* @@ -466,6 +555,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } @@ -490,6 +580,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* #[weight = $weight:expr] @@ -516,6 +607,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* } @@ -535,10 +627,98 @@ macro_rules! decl_module { { $( $offchain )* } { $( $constants )* } { $( $error_type )* } + { $( $integrity_test)* } [ $( $dispatchables )* ] $($rest)* ); }; + // Compile error on `on_runtime_upgrade` being added a second time. + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )* } + { $( $on_runtime_upgrade:tt )+ } + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { $( $error_type:tt )* } + { $( $integrity_test:tt )* } + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + fn on_runtime_upgrade( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* } + $($rest:tt)* + ) => { + compile_error!("`on_runtime_upgrade` can only be passed once as input."); + }; + // Add integrity_test + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )* } + { $( $on_runtime_upgrade:tt )* } + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { $( $error_type:tt )* } + {} + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + fn integrity_test() { $( $impl:tt )* } + $($rest:tt)* + ) => { + $crate::decl_module!(@normalize + $(#[$attr])* + pub struct $mod_type<$trait_instance: $trait_name$(, I: $instantiable $(= $module_default_instance)?)?> + for enum $call_type where origin: $origin_type, system = $system + { $( $other_where_bounds )* } + { $( $deposit_event )* } + { $( $on_initialize )* } + { $( $on_runtime_upgrade )* } + { $( $on_finalize )* } + { $( $offchain )* } + { $( $constants )* } + { $( $error_type )* } + { + $(#[doc = $doc_attr])* + fn integrity_test() { $( $impl)* } + } + [ $( $dispatchables )* ] + $($rest)* + ); + }; + // Compile error on `integrity_test` being added a second time. + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )* } + { $( $on_runtime_upgrade:tt )* } + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { $( $error_type:tt )* } + { $( $integrity_test:tt )+ } + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + fn integrity_test() { $( $impl:tt )* } + $($rest:tt)* + ) => { + compile_error!("`integrity_test` can only be passed once as input."); + }; // compile_error on_initialize, without a given weight removed syntax. (@normalize $(#[$attr:meta])* @@ -554,6 +734,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } @@ -578,6 +759,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* #[weight = $weight:expr] @@ -604,6 +786,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* } @@ -623,10 +806,34 @@ macro_rules! decl_module { { $( $offchain )* } { $( $constants )* } { $( $error_type )* } + { $( $integrity_test)* } [ $( $dispatchables )* ] $($rest)* ); }; + // Compile error on trying to add a second `on_initialize`. + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )+ } + { $( $on_runtime_upgrade:tt )* } + { $( $on_finalize:tt )* } + { $( $offchain:tt )* } + { $( $constants:tt )* } + { $( $error_type:tt )* } + { $( $integrity_test:tt )* } + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + fn on_initialize( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* } + $($rest:tt)* + ) => { + compile_error!("`on_initialize` can only be passed once as input."); + }; (@normalize $(#[$attr:meta])* pub struct $mod_type:ident< @@ -642,6 +849,7 @@ macro_rules! decl_module { { } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* fn offchain_worker( $( $param_name:ident : $param:ty ),* $(,)? ) { $( $impl:tt )* } @@ -661,11 +869,34 @@ macro_rules! decl_module { { fn offchain_worker( $( $param_name : $param ),* ) { $( $impl )* } } { $( $constants )* } { $( $error_type )* } + { $( $integrity_test)* } [ $( $dispatchables )* ] $($rest)* ); }; - + // Compile error on trying to add a second `offchain_worker`. + (@normalize + $(#[$attr:meta])* + pub struct $mod_type:ident< + $trait_instance:ident: $trait_name:ident$(, I: $instantiable:path $(= $module_default_instance:path)?)? + > + for enum $call_type:ident where origin: $origin_type:ty, system = $system:ident + { $( $other_where_bounds:tt )* } + { $( $deposit_event:tt )* } + { $( $on_initialize:tt )* } + { $( $on_runtime_upgrade:tt )* } + { $( $on_finalize:tt )* } + { $( $offchain:tt )+ } + { $( $constants:tt )* } + { $( $error_type:tt )* } + { $( $integrity_test:tt )* } + [ $( $dispatchables:tt )* ] + $(#[doc = $doc_attr:tt])* + fn offchain_worker( $( $param_name:ident : $param:ty ),* $(,)? ) -> $return:ty { $( $impl:tt )* } + $($rest:tt)* + ) => { + compile_error!("`offchain_worker` can only be passed once as input."); + }; // This puts a constant in the parsed constants list. (@normalize $(#[$attr:meta])* @@ -682,6 +913,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $( #[doc = $doc_attr:tt] )* const $name:ident: $ty:ty = $value:expr; @@ -706,6 +938,7 @@ macro_rules! decl_module { $name: $ty = $value; } { $( $error_type )* } + { $( $integrity_test)* } [ $( $dispatchables )* ] $($rest)* ); @@ -727,6 +960,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* type Error = $error_type:ty; @@ -746,6 +980,7 @@ macro_rules! decl_module { { $( $offchain )* } { $( $constants )* } { $error_type } + { $( $integrity_test)* } [ $( $dispatchables )* ] $($rest)* ); @@ -766,6 +1001,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { } + { $( $integrity_test:tt )* } [ $($t:tt)* ] $($rest:tt)* ) => { @@ -783,6 +1019,7 @@ macro_rules! decl_module { { $( $offchain )* } { $( $constants )* } { &'static str } + { $( $integrity_test)* } [ $($t)* ] $($rest)* ); @@ -804,9 +1041,11 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $error_type:ty } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* #[weight = $weight:expr] + $(#[$fn_attr:meta])* $fn_vis:vis fn $fn_name:ident( $origin:ident $( , $(#[$codec_attr:ident])* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } @@ -826,10 +1065,12 @@ macro_rules! decl_module { { $( $offchain )* } { $( $constants )* } { $error_type } + { $( $integrity_test)* } [ $( $dispatchables )* $(#[doc = $doc_attr])* #[weight = $weight] + $(#[$fn_attr])* $fn_vis fn $fn_name( $origin $( , $(#[$codec_attr])* $param_name : $param )* ) $( -> $result )* { $( $impl )* } @@ -854,8 +1095,10 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* + $(#[$fn_attr:meta])* $fn_vis:vis fn $fn_name:ident( $from:ident $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } @@ -880,9 +1123,11 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? + $(#[$fn_attr:meta])* $fn_vis:vis fn $fn_name:ident( $origin:ident : T::Origin $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } @@ -906,9 +1151,11 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? + $(#[$fn_attr:meta])* $fn_vis:vis fn $fn_name:ident( origin : $origin:ty $( , $( #[$codec_attr:ident] )* $param_name:ident : $param:ty )* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } @@ -932,9 +1179,11 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] $(#[doc = $doc_attr:tt])* $(#[weight = $weight:expr])? + $(#[$fn_attr:meta])* $fn_vis:vis fn $fn_name:ident( $( $(#[$codec_attr:ident])* $param_name:ident : $param:ty ),* $(,)? ) $( -> $result:ty )* { $( $impl:tt )* } @@ -959,6 +1208,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $( $error_type:tt )* } + { $( $integrity_test:tt )* } [ $( $dispatchables:tt )* ] ) => { $crate::decl_module!(@imp @@ -975,6 +1225,7 @@ macro_rules! decl_module { { $( $offchain )* } { $( $constants )* } { $( $error_type )* } + { $( $integrity_test)* } ); }; @@ -1004,6 +1255,7 @@ macro_rules! decl_module { impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> $module<$trait_instance $(, $instance)?> where $( $other_where_bounds )* { + /// Deposits an event using `frame_system::Module::deposit_event`. $vis fn deposit_event( event: impl Into<< $trait_instance as $trait_name $(<$instance>)? >::Event> ) { @@ -1080,6 +1332,34 @@ macro_rules! decl_module { {} }; + (@impl_integrity_test + $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; + { $( $other_where_bounds:tt )* } + $(#[doc = $doc_attr:tt])* + fn integrity_test() { $( $impl:tt )* } + ) => { + #[cfg(feature = "std")] + impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> + $crate::traits::IntegrityTest + for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* + { + $(#[doc = $doc_attr])* + fn integrity_test() { + $( $impl )* + } + } + }; + + (@impl_integrity_test + $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; + { $( $other_where_bounds:tt )* } + ) => { + #[cfg(feature = "std")] + impl<$trait_instance: $trait_name$(, $instance: $instantiable)?> + $crate::traits::IntegrityTest + for $module<$trait_instance$(, $instance)?> where $( $other_where_bounds )* + {} + }; (@impl_on_finalize $module:ident<$trait_instance:ident: $trait_name:ident$(, $instance:ident: $instantiable:path)?>; @@ -1166,13 +1446,13 @@ macro_rules! decl_module { $origin_ty:ty; $error_type:ty; $ignore:ident; - $(#[doc = $doc_attr:tt])* + $(#[$fn_attr:meta])* $vis:vis fn $name:ident ( $origin:ident $(, $param:ident : $param_ty:ty )* ) { $( $impl:tt )* } ) => { - $(#[doc = $doc_attr])* #[allow(unreachable_code)] + $(#[$fn_attr])* $vis fn $name( $origin: $origin_ty $(, $param: $param_ty )* ) -> $crate::dispatch::DispatchResult { @@ -1188,12 +1468,12 @@ macro_rules! decl_module { $origin_ty:ty; $error_type:ty; $ignore:ident; - $(#[doc = $doc_attr:tt])* + $(#[$fn_attr:meta])* $vis:vis fn $name:ident ( $origin:ident $(, $param:ident : $param_ty:ty )* ) -> $result:ty { $( $impl:tt )* } ) => { - $(#[doc = $doc_attr])* + $(#[$fn_attr])* $vis fn $name($origin: $origin_ty $(, $param: $param_ty )* ) -> $result { $crate::sp_tracing::enter_span!(stringify!($name)); $( $impl )* @@ -1325,6 +1605,7 @@ macro_rules! decl_module { $( $(#[doc = $doc_attr:tt])* #[weight = $weight:expr] + $(#[$fn_attr:meta])* $fn_vis:vis fn $fn_name:ident( $from:ident $( , $(#[$codec_attr:ident])* $param_name:ident : $param:ty)* ) $( -> $result:ty )* { $( $impl:tt )* } @@ -1339,6 +1620,7 @@ macro_rules! decl_module { { $( $offchain:tt )* } { $( $constants:tt )* } { $error_type:ty } + { $( $integrity_test:tt )* } ) => { $crate::__check_reserved_fn_name! { $( $fn_name )* } @@ -1365,7 +1647,6 @@ macro_rules! decl_module { $( $on_runtime_upgrade )* } - $crate::decl_module! { @impl_on_finalize $mod_type<$trait_instance: $trait_name $(, $instance: $instantiable)?>; @@ -1387,6 +1668,13 @@ macro_rules! decl_module { $( $deposit_event )* } + $crate::decl_module! { + @impl_integrity_test + $mod_type<$trait_instance: $trait_name $(, $instance: $instantiable)?>; + { $( $other_where_bounds )* } + $( $integrity_test )* + } + /// Can also be called using [`Call`]. /// /// [`Call`]: enum.Call.html @@ -1401,6 +1689,9 @@ macro_rules! decl_module { $error_type; $from; $(#[doc = $doc_attr])* + /// + /// NOTE: Calling this function will bypass origin filters. + $(#[$fn_attr])* $fn_vis fn $fn_name ( $from $(, $param_name : $param )* ) $( -> $result )* { $( $impl )* } @@ -1545,14 +1836,11 @@ macro_rules! decl_module { } } - impl<$trait_instance: $trait_name $(, $instance: $instantiable)?> $crate::dispatch::Dispatchable + impl<$trait_instance: $trait_name $(, $instance: $instantiable)?> $crate::traits::UnfilteredDispatchable for $call_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )* { - type Trait = $trait_instance; type Origin = $origin_type; - type Info = $crate::weights::DispatchInfo; - type PostInfo = $crate::weights::PostDispatchInfo; - fn dispatch(self, _origin: Self::Origin) -> $crate::dispatch::DispatchResultWithPostInfo { + fn dispatch_bypass_filter(self, _origin: Self::Origin) -> $crate::dispatch::DispatchResultWithPostInfo { match self { $( $call_type::$fn_name( $( $param_name ),* ) => { @@ -1573,17 +1861,6 @@ macro_rules! decl_module { type Call = $call_type<$trait_instance $(, $instance)?>; } - impl<$trait_instance: $trait_name $(, $instance: $instantiable)?> $mod_type<$trait_instance $(, $instance)?> - where $( $other_where_bounds )* - { - #[doc(hidden)] - pub fn dispatch>( - d: D, - origin: D::Origin - ) -> $crate::dispatch::DispatchResultWithPostInfo { - d.dispatch(origin) - } - } $crate::__dispatch_impl_metadata! { $mod_type<$trait_instance: $trait_name $(, $instance: $instantiable)?> { $( $other_where_bounds )* } @@ -1611,8 +1888,8 @@ macro_rules! decl_module { } } -pub trait IsSubType, R> { - fn is_sub_type(&self) -> Option<&CallableCallFor>; +pub trait IsSubType { + fn is_sub_type(&self) -> Option<&T>; } /// Implement a meta-dispatch module to dispatch to other dispatchers. @@ -1683,6 +1960,20 @@ macro_rules! impl_outer_dispatch { fn dispatch( self, origin: $origin, + ) -> $crate::dispatch::DispatchResultWithPostInfo { + if !::filter_call(&origin, &self) { + return $crate::sp_std::result::Result::Err($crate::dispatch::DispatchError::BadOrigin.into()) + } + + $crate::traits::UnfilteredDispatchable::dispatch_bypass_filter(self, origin) + } + } + + impl $crate::traits::UnfilteredDispatchable for $call_type { + type Origin = $origin; + fn dispatch_bypass_filter( + self, + origin: $origin, ) -> $crate::dispatch::DispatchResultWithPostInfo { $crate::impl_outer_dispatch! { @DISPATCH_MATCH @@ -1695,8 +1986,9 @@ macro_rules! impl_outer_dispatch { } } } + $( - impl $crate::dispatch::IsSubType<$camelcase, $runtime> for $call_type { + impl $crate::dispatch::IsSubType<$crate::dispatch::CallableCallFor<$camelcase, $runtime>> for $call_type { #[allow(unreachable_patterns)] fn is_sub_type(&self) -> Option<&$crate::dispatch::CallableCallFor<$camelcase, $runtime>> { match *self { @@ -1730,7 +2022,8 @@ macro_rules! impl_outer_dispatch { $origin { $( $generated )* - $call_type::$name(call) => call.dispatch($origin), + $call_type::$name(call) => + $crate::traits::UnfilteredDispatchable::dispatch_bypass_filter(call, $origin), } $index + 1; $( $rest ),* @@ -2010,6 +2303,9 @@ macro_rules! __check_reserved_fn_name { (offchain_worker $( $rest:ident )*) => { $crate::__check_reserved_fn_name!(@compile_error offchain_worker); }; + (integrity_test $( $rest:ident )*) => { + $crate::__check_reserved_fn_name!(@compile_error integrity_test); + }; ($t:ident $( $rest:ident )*) => { $crate::__check_reserved_fn_name!($( $rest )*); }; @@ -2045,29 +2341,45 @@ mod tests { use super::*; use crate::weights::{DispatchInfo, DispatchClass, Pays}; use crate::traits::{ - CallMetadata, GetCallMetadata, GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade + CallMetadata, GetCallMetadata, GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade, + IntegrityTest, }; pub trait Trait: system::Trait + Sized where Self::AccountId: From { - type Origin; type BlockNumber: Into; - type Call: From>; } pub mod system { - use super::*; + use codec::{Encode, Decode}; pub trait Trait { type AccountId; + type Call; + type BaseCallFilter; + type Origin: crate::traits::OriginTrait; } - pub fn ensure_root(_: R) -> DispatchResult { - Ok(()) + #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] + pub enum RawOrigin { + Root, + Signed(AccountId), + None, } + + impl From> for RawOrigin { + fn from(s: Option) -> RawOrigin { + match s { + Some(who) => RawOrigin::Signed(who), + None => RawOrigin::None, + } + } + } + + pub type Origin = RawOrigin<::AccountId>; } decl_module! { - pub struct Module for enum Call where origin: T::Origin, T::AccountId: From { + pub struct Module for enum Call where origin: T::Origin, system = system, T::AccountId: From { /// Hi, this is a comment. #[weight = 0] fn aux_0(_origin) -> DispatchResult { unreachable!() } @@ -2094,95 +2406,102 @@ mod tests { fn on_finalize(n: T::BlockNumber,) { if n.into() == 42 { panic!("on_finalize") } } fn on_runtime_upgrade() -> Weight { 10 } fn offchain_worker() {} + /// Some doc + fn integrity_test() { panic!("integrity_test") } } } const EXPECTED_METADATA: &'static [FunctionMetadata] = &[ - FunctionMetadata { - name: DecodeDifferent::Encode("aux_0"), - arguments: DecodeDifferent::Encode(&[]), - documentation: DecodeDifferent::Encode(&[ - " Hi, this is a comment." - ]) - }, - FunctionMetadata { - name: DecodeDifferent::Encode("aux_1"), - arguments: DecodeDifferent::Encode(&[ - FunctionArgumentMetadata { - name: DecodeDifferent::Encode("_data"), - ty: DecodeDifferent::Encode("Compact") - } - ]), - documentation: DecodeDifferent::Encode(&[]), - }, - FunctionMetadata { - name: DecodeDifferent::Encode("aux_2"), - arguments: DecodeDifferent::Encode(&[ - FunctionArgumentMetadata { - name: DecodeDifferent::Encode("_data"), - ty: DecodeDifferent::Encode("i32"), - }, - FunctionArgumentMetadata { - name: DecodeDifferent::Encode("_data2"), - ty: DecodeDifferent::Encode("String"), - } - ]), - documentation: DecodeDifferent::Encode(&[]), - }, - FunctionMetadata { - name: DecodeDifferent::Encode("aux_3"), - arguments: DecodeDifferent::Encode(&[]), - documentation: DecodeDifferent::Encode(&[]), - }, - FunctionMetadata { - name: DecodeDifferent::Encode("aux_4"), - arguments: DecodeDifferent::Encode(&[ - FunctionArgumentMetadata { - name: DecodeDifferent::Encode("_data"), - ty: DecodeDifferent::Encode("i32"), - } - ]), - documentation: DecodeDifferent::Encode(&[]), - }, - FunctionMetadata { - name: DecodeDifferent::Encode("aux_5"), - arguments: DecodeDifferent::Encode(&[ - FunctionArgumentMetadata { - name: DecodeDifferent::Encode("_data"), - ty: DecodeDifferent::Encode("i32"), - }, - FunctionArgumentMetadata { - name: DecodeDifferent::Encode("_data2"), - ty: DecodeDifferent::Encode("Compact") - } - ]), - documentation: DecodeDifferent::Encode(&[]), + FunctionMetadata { + name: DecodeDifferent::Encode("aux_0"), + arguments: DecodeDifferent::Encode(&[]), + documentation: DecodeDifferent::Encode(&[ + " Hi, this is a comment." + ]) + }, + FunctionMetadata { + name: DecodeDifferent::Encode("aux_1"), + arguments: DecodeDifferent::Encode(&[ + FunctionArgumentMetadata { + name: DecodeDifferent::Encode("_data"), + ty: DecodeDifferent::Encode("Compact") + } + ]), + documentation: DecodeDifferent::Encode(&[]), + }, + FunctionMetadata { + name: DecodeDifferent::Encode("aux_2"), + arguments: DecodeDifferent::Encode(&[ + FunctionArgumentMetadata { + name: DecodeDifferent::Encode("_data"), + ty: DecodeDifferent::Encode("i32"), }, - FunctionMetadata { - name: DecodeDifferent::Encode("operational"), - arguments: DecodeDifferent::Encode(&[]), - documentation: DecodeDifferent::Encode(&[]), + FunctionArgumentMetadata { + name: DecodeDifferent::Encode("_data2"), + ty: DecodeDifferent::Encode("String"), + } + ]), + documentation: DecodeDifferent::Encode(&[]), + }, + FunctionMetadata { + name: DecodeDifferent::Encode("aux_3"), + arguments: DecodeDifferent::Encode(&[]), + documentation: DecodeDifferent::Encode(&[]), + }, + FunctionMetadata { + name: DecodeDifferent::Encode("aux_4"), + arguments: DecodeDifferent::Encode(&[ + FunctionArgumentMetadata { + name: DecodeDifferent::Encode("_data"), + ty: DecodeDifferent::Encode("i32"), + } + ]), + documentation: DecodeDifferent::Encode(&[]), + }, + FunctionMetadata { + name: DecodeDifferent::Encode("aux_5"), + arguments: DecodeDifferent::Encode(&[ + FunctionArgumentMetadata { + name: DecodeDifferent::Encode("_data"), + ty: DecodeDifferent::Encode("i32"), }, - ]; + FunctionArgumentMetadata { + name: DecodeDifferent::Encode("_data2"), + ty: DecodeDifferent::Encode("Compact") + } + ]), + documentation: DecodeDifferent::Encode(&[]), + }, + FunctionMetadata { + name: DecodeDifferent::Encode("operational"), + arguments: DecodeDifferent::Encode(&[]), + documentation: DecodeDifferent::Encode(&[]), + }, + ]; pub struct TraitImpl {} impl Trait for TraitImpl { - type Origin = u32; type BlockNumber = u32; - type Call = OuterCall; } type Test = Module; + impl_outer_origin!{ + pub enum OuterOrigin for TraitImpl where system = system {} + } + impl_outer_dispatch! { - pub enum OuterCall for TraitImpl where origin: u32 { + pub enum OuterCall for TraitImpl where origin: OuterOrigin { self::Test, } } impl system::Trait for TraitImpl { + type Origin = OuterOrigin; type AccountId = u32; + type Call = OuterCall; + type BaseCallFilter = (); } #[test] @@ -2280,4 +2599,10 @@ mod tests { let module_names = OuterCall::get_module_names(); assert_eq!(["Test"], module_names); } + + #[test] + #[should_panic(expected = "integrity_test")] + fn integrity_test_should_work() { + as IntegrityTest>::integrity_test(); + } } diff --git a/frame/support/src/error.rs b/frame/support/src/error.rs index 115920f39a933440d61825661830cbc391588a9f..d758ad52e72b3ba7fe10ceee4d978c7bd722887c 100644 --- a/frame/support/src/error.rs +++ b/frame/support/src/error.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Macro for declaring a module error. @@ -46,7 +47,7 @@ pub use frame_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent}; /// } /// } /// -/// # use frame_system::{self as system, Trait}; +/// # use frame_system::Trait; /// /// // You need to register the error type in `decl_module!` as well to make the error /// // exported in the metadata. diff --git a/frame/support/src/hash.rs b/frame/support/src/hash.rs index 40cb1f612f7bf61e4a499e08feba56c1bfe6ea41..a5de205863d5ca8584e32b4b557e5b13eedbeeec 100644 --- a/frame/support/src/hash.rs +++ b/frame/support/src/hash.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Hash utilities. diff --git a/frame/support/src/inherent.rs b/frame/support/src/inherent.rs index 4e09bf9dd817398864bd8e71c86dd0e82befb4fd..e9b0c22692e9da09dd423a760962036d54b8e0d7 100644 --- a/frame/support/src/inherent.rs +++ b/frame/support/src/inherent.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. #[doc(hidden)] pub use crate::sp_std::vec::Vec; @@ -30,19 +31,20 @@ pub use sp_inherents::{InherentData, ProvideInherent, CheckInherentsResult, IsFa /// ```nocompile /// impl_outer_inherent! { /// impl Inherents where Block = Block, UncheckedExtrinsic = UncheckedExtrinsic { -/// timestamp: Timestamp, -/// consensus: Consensus, -/// /// Aura module using the `Timestamp` call. -/// aura: Timestamp, +/// timestamp, +/// consensus, +/// aura, /// } /// } /// ``` #[macro_export] macro_rules! impl_outer_inherent { ( - impl Inherents where Block = $block:ident, UncheckedExtrinsic = $uncheckedextrinsic:ident + impl Inherents where + Block = $block:ident, + UncheckedExtrinsic = $uncheckedextrinsic:ident { - $( $module:ident: $call:ident, )* + $( $module:ident, )* } ) => { trait InherentDataExt { @@ -54,15 +56,14 @@ macro_rules! impl_outer_inherent { impl InherentDataExt for $crate::inherent::InherentData { fn create_extrinsics(&self) -> $crate::inherent::Vec<<$block as $crate::inherent::BlockT>::Extrinsic> { - use $crate::inherent::ProvideInherent; - use $crate::inherent::Extrinsic; + use $crate::inherent::{ProvideInherent, Extrinsic}; let mut inherents = Vec::new(); $( if let Some(inherent) = $module::create_inherent(self) { inherents.push($uncheckedextrinsic::new( - Call::$call(inherent), + inherent.into(), None, ).expect("Runtime UncheckedExtrinsic is not Opaque, so it has to return `Some`; qed")); } @@ -73,6 +74,7 @@ macro_rules! impl_outer_inherent { fn check_extrinsics(&self, block: &$block) -> $crate::inherent::CheckInherentsResult { use $crate::inherent::{ProvideInherent, IsFatalError}; + use $crate::dispatch::IsSubType; let mut result = $crate::inherent::CheckInherentsResult::new(); for xt in block.extrinsics() { @@ -80,21 +82,18 @@ macro_rules! impl_outer_inherent { break } - $( - match xt.function { - Call::$call(ref call) => { - if let Err(e) = $module::check_inherent(call, self) { - result.put_error( - $module::INHERENT_IDENTIFIER, &e - ).expect("There is only one fatal error; qed"); - if e.is_fatal_error() { - return result - } + $({ + if let Some(call) = IsSubType::<_>::is_sub_type(&xt.function) { + if let Err(e) = $module::check_inherent(call, self) { + result.put_error( + $module::INHERENT_IDENTIFIER, &e + ).expect("There is only one fatal error; qed"); + if e.is_fatal_error() { + return result } } - _ => {}, } - )* + })* } $( @@ -105,10 +104,10 @@ macro_rules! impl_outer_inherent { return false } - match xt.function { - Call::$call(_) => true, - _ => false, - } + let call: Option<&<$module as ProvideInherent>::Call> = + xt.function.is_sub_type(); + + call.is_some() }); if !found { @@ -137,3 +136,139 @@ macro_rules! impl_outer_inherent { } }; } + +#[cfg(test)] +mod tests { + use super::*; + use sp_runtime::{traits, testing::{Header, self}}; + use crate::dispatch::IsSubType; + + #[derive(codec::Encode, codec::Decode, Clone, PartialEq, Eq, Debug, serde::Serialize)] + enum Call { + Test(CallTest), + Test2(CallTest2), + } + + impl From for Call { + fn from(call: CallTest) -> Self { + Self::Test(call) + } + } + + impl From for Call { + fn from(call: CallTest2) -> Self { + Self::Test2(call) + } + } + + impl IsSubType for Call { + fn is_sub_type(&self) -> Option<&CallTest> { + match self { + Self::Test(test) => Some(test), + _ => None, + } + } + } + + impl IsSubType for Call { + fn is_sub_type(&self) -> Option<&CallTest2> { + match self { + Self::Test2(test) => Some(test), + _ => None, + } + } + } + + #[derive(codec::Encode, codec::Decode, Clone, PartialEq, Eq, Debug, serde::Serialize)] + enum CallTest { + Something, + SomethingElse, + } + + #[derive(codec::Encode, codec::Decode, Clone, PartialEq, Eq, Debug, serde::Serialize)] + enum CallTest2 { + Something, + } + + struct ModuleTest; + impl ProvideInherent for ModuleTest { + type Call = CallTest; + type Error = sp_inherents::MakeFatalError<()>; + const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"test1235"; + + fn create_inherent(_: &InherentData) -> Option { + Some(CallTest::Something) + } + + fn check_inherent(call: &Self::Call, _: &InherentData) -> Result<(), Self::Error> { + match call { + CallTest::Something => Ok(()), + CallTest::SomethingElse => Err(().into()), + } + } + } + + struct ModuleTest2; + impl ProvideInherent for ModuleTest2 { + type Call = CallTest2; + type Error = sp_inherents::MakeFatalError<()>; + const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"test1234"; + + fn create_inherent(_: &InherentData) -> Option { + Some(CallTest2::Something) + } + } + + type Block = testing::Block; + + #[derive(codec::Encode, codec::Decode, Clone, PartialEq, Eq, Debug, serde::Serialize)] + struct Extrinsic { + function: Call, + } + + impl traits::Extrinsic for Extrinsic { + type Call = Call; + type SignaturePayload = (); + + fn new(function: Call, _: Option<()>) -> Option { + Some(Self { function }) + } + } + + parity_util_mem::malloc_size_of_is_0!(Extrinsic); + + impl_outer_inherent! { + impl Inherents where Block = Block, UncheckedExtrinsic = Extrinsic { + ModuleTest, + ModuleTest2, + } + } + + #[test] + fn create_inherents_works() { + let inherents = InherentData::new().create_extrinsics(); + + let expected = vec![ + Extrinsic { function: Call::Test(CallTest::Something) }, + Extrinsic { function: Call::Test2(CallTest2::Something) }, + ]; + assert_eq!(expected, inherents); + } + + #[test] + fn check_inherents_works() { + let block = Block::new( + Header::new_from_number(1), + vec![Extrinsic { function: Call::Test(CallTest::Something) }], + ); + + assert!(InherentData::new().check_extrinsics(&block).ok()); + + let block = Block::new( + Header::new_from_number(1), + vec![Extrinsic { function: Call::Test(CallTest::SomethingElse) }], + ); + + assert!(InherentData::new().check_extrinsics(&block).fatal_error()); + } +} diff --git a/frame/support/src/lib.rs b/frame/support/src/lib.rs index 6bad5985abcb64626f8cc931b2ce0e4c3a39a2d2..bdbdfc04a31f93dc1f666999f09eb62939221221 100644 --- a/frame/support/src/lib.rs +++ b/frame/support/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Support code for the runtime. @@ -29,11 +30,11 @@ pub use sp_tracing; #[cfg(feature = "std")] pub use serde; +pub use sp_core::Void; #[doc(hidden)] pub use sp_std; #[doc(hidden)] pub use codec; -use codec::{Decode, Encode}; #[cfg(feature = "std")] #[doc(hidden)] pub use once_cell; @@ -43,21 +44,21 @@ pub use paste; #[doc(hidden)] pub use sp_state_machine::BasicExternalities; #[doc(hidden)] -pub use sp_io::storage::root as storage_root; +pub use sp_io::{storage::root as storage_root, self}; #[doc(hidden)] pub use sp_runtime::RuntimeDebug; #[macro_use] pub mod debug; #[macro_use] +mod origin; +#[macro_use] pub mod dispatch; pub mod storage; mod hash; #[macro_use] pub mod event; #[macro_use] -mod origin; -#[macro_use] pub mod metadata; #[macro_use] pub mod inherent; @@ -83,21 +84,66 @@ pub use sp_runtime::{self, ConsensusEngineId, print, traits::Printable}; #[derive(Debug)] pub enum Never {} -/// Macro for easily creating a new implementation of the `Get` trait. Use similarly to -/// how you would declare a `const`: +/// Create new implementations of the [`Get`](crate::traits::Get) trait. +/// +/// The so-called parameter type can be created in three different ways: +/// +/// - Using `const` to create a parameter type that provides a `const` getter. +/// It is required that the `value` is const. +/// +/// - Declare the parameter type without `const` to have more freedom when creating the value. +/// +/// - Using `storage` to create a storage parameter type. This type is special as it tries to +/// load the value from the storage under a fixed key. If the value could not be found in the +/// storage, the given default value will be returned. It is required that the value implements +/// [`Encode`](codec::Encode) and [`Decode`](codec::Decode). The key for looking up the value +/// in the storage is built using the following formular: +/// +/// `twox_128(":" ++ NAME ++ ":")` where `NAME` is the name that is passed as type name. +/// +/// # Examples /// -/// ```no_compile +/// ``` +/// # use frame_support::traits::Get; +/// # use frame_support::parameter_types; +/// // This function cannot be used in a const context. +/// fn non_const_expression() -> u64 { 99 } +/// +/// const FIXED_VALUE: u64 = 10; /// parameter_types! { -/// pub const Argument: u64 = 42; +/// pub const Argument: u64 = 42 + FIXED_VALUE; +/// /// Visibility of the type is optional +/// OtherArgument: u64 = non_const_expression(); +/// pub storage StorageArgument: u64 = 5; /// } +/// /// trait Config { -/// type Parameter: Get; +/// type Parameter: Get; +/// type OtherParameter: Get; +/// type StorageParameter: Get; /// } +/// /// struct Runtime; /// impl Config for Runtime { -/// type Parameter = Argument; +/// type Parameter = Argument; +/// type OtherParameter = OtherArgument; +/// type StorageParameter = StorageArgument; +/// } +/// ``` +/// +/// # Invalid example: +/// +/// ```compile_fail +/// # use frame_support::traits::Get; +/// # use frame_support::parameter_types; +/// // This function cannot be used in a const context. +/// fn non_const_expression() -> u64 { 99 } +/// +/// parameter_types! { +/// pub const Argument: u64 = non_const_expression(); /// } /// ``` + #[macro_export] macro_rules! parameter_types { ( @@ -107,21 +153,89 @@ macro_rules! parameter_types { ) => ( $( #[ $attr ] )* $vis struct $name; - $crate::parameter_types!{IMPL $name , $type , $value} - $crate::parameter_types!{ $( $rest )* } + $crate::parameter_types!(IMPL_CONST $name , $type , $value); + $crate::parameter_types!( $( $rest )* ); + ); + ( + $( #[ $attr:meta ] )* + $vis:vis $name:ident: $type:ty = $value:expr; + $( $rest:tt )* + ) => ( + $( #[ $attr ] )* + $vis struct $name; + $crate::parameter_types!(IMPL $name, $type, $value); + $crate::parameter_types!( $( $rest )* ); + ); + ( + $( #[ $attr:meta ] )* + $vis:vis storage $name:ident: $type:ty = $value:expr; + $( $rest:tt )* + ) => ( + $( #[ $attr ] )* + $vis struct $name; + $crate::parameter_types!(IMPL_STORAGE $name, $type, $value); + $crate::parameter_types!( $( $rest )* ); ); () => (); - (IMPL $name:ident , $type:ty , $value:expr) => { + (IMPL_CONST $name:ident, $type:ty, $value:expr) => { + impl $name { + /// Returns the value of this parameter type. + pub const fn get() -> $type { + $value + } + } + + impl> $crate::traits::Get for $name { + fn get() -> I { + I::from($value) + } + } + }; + (IMPL $name:ident, $type:ty, $value:expr) => { impl $name { + /// Returns the value of this parameter type. pub fn get() -> $type { $value } } + impl> $crate::traits::Get for $name { fn get() -> I { I::from($value) } } + }; + (IMPL_STORAGE $name:ident, $type:ty, $value:expr) => { + impl $name { + /// Returns the key for this parameter type. + pub fn key() -> [u8; 16] { + $crate::sp_io::hashing::twox_128( + concat!(":", stringify!($name), ":").as_bytes() + ) + } + + /// Set the value of this parameter type in the storage. + /// + /// This needs to be executed in an externalities provided + /// environment. + pub fn set(value: &$type) { + $crate::storage::unhashed::put(&Self::key(), value); + } + + /// Returns the value of this parameter type. + /// + /// This needs to be executed in an externalities provided + /// environment. + pub fn get() -> $type { + $crate::storage::unhashed::get(&Self::key()).unwrap_or_else(|| $value) + } + } + + impl> $crate::traits::Get for $name { + fn get() -> I { + I::from(Self::get()) + } + } } } @@ -153,7 +267,7 @@ macro_rules! ord_parameter_types { } #[doc(inline)] -pub use frame_support_procedural::{decl_storage, construct_runtime}; +pub use frame_support_procedural::{decl_storage, construct_runtime, transactional}; /// Return Err of the expression: `return Err($expression);`. /// @@ -213,7 +327,21 @@ macro_rules! assert_err { #[cfg(feature = "std")] macro_rules! assert_err_ignore_postinfo { ( $x:expr , $y:expr $(,)? ) => { - assert_err!($x.map(|_| ()).map_err(|e| e.error), $y); + $crate::assert_err!($x.map(|_| ()).map_err(|e| e.error), $y); + } +} + +/// Assert an expression returns error with the given weight. +#[macro_export] +#[cfg(feature = "std")] +macro_rules! assert_err_with_weight { + ($call:expr, $err:expr, $weight:expr $(,)? ) => { + if let Err(dispatch_err_with_post) = $call { + $crate::assert_err!($call.map(|_| ()).map_err(|e| e.error), $err); + assert_eq!(dispatch_err_with_post.post_info.actual_weight, $weight.into()); + } else { + panic!("expected Err(_), got Ok(_).") + } } } @@ -236,11 +364,6 @@ macro_rules! assert_ok { } } -/// The void type - it cannot exist. -// Oh rust, you crack me up... -#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug)] -pub enum Void {} - #[cfg(feature = "std")] #[doc(hidden)] pub use serde::{Serialize, Deserialize}; @@ -253,7 +376,8 @@ mod tests { DecodeDifferent, StorageEntryMetadata, StorageMetadata, StorageEntryType, StorageEntryModifier, DefaultByteGetter, StorageHasher, }; - use sp_std::marker::PhantomData; + use sp_std::{marker::PhantomData, result}; + use sp_io::TestExternalities; pub trait Trait { type BlockNumber: Codec + EncodeLike + Default; @@ -299,7 +423,7 @@ mod tests { type Origin = u32; } - fn new_test_ext() -> sp_io::TestExternalities { + fn new_test_ext() -> TestExternalities { GenesisConfig::default().build_storage().unwrap().into() } @@ -505,6 +629,53 @@ mod tests { }); } + #[test] + fn double_map_mutate_exists_should_work() { + new_test_ext().execute_with(|| { + type DoubleMap = DataDM; + + let (key1, key2) = (11, 13); + + // mutated + DoubleMap::mutate_exists(key1, key2, |v| *v = Some(1)); + assert_eq!(DoubleMap::get(&key1, key2), 1); + + // removed if mutated to `None` + DoubleMap::mutate_exists(key1, key2, |v| *v = None); + assert!(!DoubleMap::contains_key(&key1, key2)); + }); + } + + #[test] + fn double_map_try_mutate_exists_should_work() { + new_test_ext().execute_with(|| { + type DoubleMap = DataDM; + type TestResult = result::Result<(), &'static str>; + + let (key1, key2) = (11, 13); + + // mutated if `Ok` + assert_ok!(DoubleMap::try_mutate_exists(key1, key2, |v| -> TestResult { + *v = Some(1); + Ok(()) + })); + assert_eq!(DoubleMap::get(&key1, key2), 1); + + // no-op if `Err` + assert_noop!(DoubleMap::try_mutate_exists(key1, key2, |v| -> TestResult { + *v = Some(2); + Err("nah") + }), "nah"); + + // removed if mutated to`None` + assert_ok!(DoubleMap::try_mutate_exists(key1, key2, |v| -> TestResult { + *v = None; + Ok(()) + })); + assert!(!DoubleMap::contains_key(&key1, key2)); + }); + } + const EXPECTED_METADATA: StorageMetadata = StorageMetadata { prefix: DecodeDifferent::Encode("Test"), entries: DecodeDifferent::Encode( @@ -634,4 +805,20 @@ mod tests { let metadata = Module::::storage_metadata(); pretty_assertions::assert_eq!(EXPECTED_METADATA, metadata); } + + parameter_types! { + storage StorageParameter: u64 = 10; + } + + #[test] + fn check_storage_parameter_type_works() { + TestExternalities::default().execute_with(|| { + assert_eq!(sp_io::hashing::twox_128(b":StorageParameter:"), StorageParameter::key()); + + assert_eq!(10, StorageParameter::get()); + + StorageParameter::set(&300); + assert_eq!(300, StorageParameter::get()); + }) + } } diff --git a/frame/support/src/metadata.rs b/frame/support/src/metadata.rs index 081f392b9ecf16d2bedbdcc90046a04ef4d7983b..aa7d71b52e0b6b183a797353986fd8d452b1559b 100644 --- a/frame/support/src/metadata.rs +++ b/frame/support/src/metadata.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. pub use frame_metadata::{ DecodeDifferent, FnEncode, RuntimeMetadata, ModuleMetadata, RuntimeMetadataLastVersion, @@ -289,6 +290,7 @@ mod tests { use super::*; pub trait Trait: 'static { + type BaseCallFilter; const ASSOCIATED_CONST: u64 = 500; type Origin: Into, Self::Origin>> + From>; @@ -296,6 +298,7 @@ mod tests { type BlockNumber: From + Encode; type SomeValue: Get; type ModuleToIndex: crate::traits::ModuleToIndex; + type Call; } decl_module! { @@ -313,7 +316,7 @@ mod tests { } ); - #[derive(Clone, PartialEq, Eq, Debug)] + #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] pub enum RawOrigin { Root, Signed(AccountId), @@ -410,7 +413,7 @@ mod tests { } impl_outer_origin! { - pub enum Origin for TestRuntime {} + pub enum Origin for TestRuntime where system = system {} } impl_outer_dispatch! { @@ -435,11 +438,13 @@ mod tests { } impl system::Trait for TestRuntime { + type BaseCallFilter = (); type Origin = Origin; type AccountId = u32; type BlockNumber = u32; type SomeValue = SystemValue; type ModuleToIndex = (); + type Call = Call; } impl_runtime_metadata!( diff --git a/frame/support/src/origin.rs b/frame/support/src/origin.rs index 43d2e70953af90b401c8b041d1cf76e35b9ba55c..df75f8dc65645ee78c5cc71df4830ea8ae43c52a 100644 --- a/frame/support/src/origin.rs +++ b/frame/support/src/origin.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Macros that define an Origin type. Every function call to your runtime has an origin which //! specifies where the extrinsic was generated from. @@ -32,7 +33,7 @@ macro_rules! impl_outer_origin { ) => { $crate::impl_outer_origin! { $(#[$attr])* - pub enum $name for $runtime where system = system { + pub enum $name for $runtime where system = frame_system { $( $rest_without_system )* } } @@ -44,19 +45,23 @@ macro_rules! impl_outer_origin { $( $rest_with_system:tt )* } ) => { - $crate::impl_outer_origin!( - $( #[$attr] )*; - $name; - $runtime; - $system; - Modules { $( $rest_with_system )* }; - ); + $crate::paste::item! { + $crate::impl_outer_origin!( + $( #[$attr] )*; + $name; + [< $name Caller >]; + $runtime; + $system; + Modules { $( $rest_with_system )* }; + ); + } }; // Generic + Instance ( $(#[$attr:meta])*; $name:ident; + $caller_name:ident; $runtime:ident; $system:ident; Modules { @@ -68,6 +73,7 @@ macro_rules! impl_outer_origin { $crate::impl_outer_origin!( $( #[$attr] )*; $name; + $caller_name; $runtime; $system; Modules { $( $( $rest_module )* )? }; @@ -79,6 +85,7 @@ macro_rules! impl_outer_origin { ( $(#[$attr:meta])*; $name:ident; + $caller_name:ident; $runtime:ident; $system:ident; Modules { @@ -90,6 +97,7 @@ macro_rules! impl_outer_origin { $crate::impl_outer_origin!( $( #[$attr] )*; $name; + $caller_name; $runtime; $system; Modules { $( $rest_module )* }; @@ -101,6 +109,7 @@ macro_rules! impl_outer_origin { ( $(#[$attr:meta])*; $name:ident; + $caller_name:ident; $runtime:ident; $system:ident; Modules { @@ -112,6 +121,7 @@ macro_rules! impl_outer_origin { $crate::impl_outer_origin!( $( #[$attr] )*; $name; + $caller_name; $runtime; $system; Modules { $( $( $rest_module )* )? }; @@ -123,6 +133,7 @@ macro_rules! impl_outer_origin { ( $(#[$attr:meta])*; $name:ident; + $caller_name:ident; $runtime:ident; $system:ident; Modules { @@ -134,6 +145,7 @@ macro_rules! impl_outer_origin { $crate::impl_outer_origin!( $( #[$attr] )*; $name; + $caller_name; $runtime; $system; Modules { $( $( $rest_module )* )? }; @@ -145,16 +157,82 @@ macro_rules! impl_outer_origin { ( $(#[$attr:meta])*; $name:ident; + $caller_name:ident; $runtime:ident; $system:ident; Modules { }; $( $module:ident $( < $generic:ident > )? $( { $generic_instance:ident } )? ,)* ) => { + // WARNING: All instance must hold the filter `frame_system::Trait::BaseCallFilter`, except + // when caller is system Root. One can use `OriginTrait::reset_filter` to do so. + #[derive(Clone)] + pub struct $name { + caller: $caller_name, + filter: $crate::sp_std::rc::Rc::Call) -> bool>>, + } + + #[cfg(not(feature = "std"))] + impl $crate::sp_std::fmt::Debug for $name { + fn fmt( + &self, + fmt: &mut $crate::sp_std::fmt::Formatter + ) -> $crate::sp_std::result::Result<(), $crate::sp_std::fmt::Error> { + fmt.write_str("") + } + } + + #[cfg(feature = "std")] + impl $crate::sp_std::fmt::Debug for $name { + fn fmt( + &self, + fmt: &mut $crate::sp_std::fmt::Formatter + ) -> $crate::sp_std::result::Result<(), $crate::sp_std::fmt::Error> { + fmt.debug_struct(stringify!($name)) + .field("caller", &self.caller) + .field("filter", &"[function ptr]") + .finish() + } + } + + impl $crate::traits::OriginTrait for $name { + type Call = <$runtime as $system::Trait>::Call; + type PalletsOrigin = $caller_name; + + fn add_filter(&mut self, filter: impl Fn(&Self::Call) -> bool + 'static) { + let f = self.filter.clone(); + + self.filter = $crate::sp_std::rc::Rc::new(Box::new(move |call| { + f(call) && filter(call) + })); + } + + fn reset_filter(&mut self) { + let filter = < + <$runtime as $system::Trait>::BaseCallFilter + as $crate::traits::Filter<<$runtime as $system::Trait>::Call> + >::filter; + + self.filter = $crate::sp_std::rc::Rc::new(Box::new(filter)); + } + + fn set_caller_from(&mut self, other: impl Into) { + self.caller = other.into().caller + } + + fn filter_call(&self, call: &Self::Call) -> bool { + (self.filter)(call) + } + + fn caller(&self) -> &Self::PalletsOrigin { + &self.caller + } + } + $crate::paste::item! { - #[derive(Clone, PartialEq, Eq, $crate::RuntimeDebug)] + #[derive(Clone, PartialEq, Eq, $crate::RuntimeDebug, $crate::codec::Encode, $crate::codec::Decode)] $(#[$attr])* #[allow(non_camel_case_types)] - pub enum $name { + pub enum $caller_name { system($system::Origin<$runtime>), $( [< $module $( _ $generic_instance )? >] @@ -167,20 +245,55 @@ macro_rules! impl_outer_origin { #[allow(dead_code)] impl $name { - pub const NONE: Self = $name::system($system::RawOrigin::None); - pub const ROOT: Self = $name::system($system::RawOrigin::Root); + /// Create with system none origin and `frame-system::Trait::BaseCallFilter`. + pub fn none() -> Self { + $system::RawOrigin::None.into() + } + /// Create with system root origin and no filter. + pub fn root() -> Self { + $system::RawOrigin::Root.into() + } + /// Create with system signed origin and `frame-system::Trait::BaseCallFilter`. pub fn signed(by: <$runtime as $system::Trait>::AccountId) -> Self { - $name::system($system::RawOrigin::Signed(by)) + $system::RawOrigin::Signed(by).into() + } + } + + impl From<$system::Origin<$runtime>> for $caller_name { + fn from(x: $system::Origin<$runtime>) -> Self { + $caller_name::system(x) } } impl From<$system::Origin<$runtime>> for $name { + /// Convert to runtime origin: + /// * root origin is built with no filter + /// * others use `frame-system::Trait::BaseCallFilter` fn from(x: $system::Origin<$runtime>) -> Self { - $name::system(x) + let o: $caller_name = x.into(); + o.into() } } + + impl From<$caller_name> for $name { + fn from(x: $caller_name) -> Self { + let mut o = $name { + caller: x, + filter: $crate::sp_std::rc::Rc::new(Box::new(|_| true)), + }; + + // Root has no filter + if !matches!(o.caller, $caller_name::system($system::Origin::<$runtime>::Root)) { + $crate::traits::OriginTrait::reset_filter(&mut o); + } + + o + } + } + impl Into<$crate::sp_std::result::Result<$system::Origin<$runtime>, $name>> for $name { + /// NOTE: converting to pallet origin loses the origin filter information. fn into(self) -> $crate::sp_std::result::Result<$system::Origin<$runtime>, Self> { - if let $name::system(l) = self { + if let $caller_name::system(l) = self.caller { Ok(l) } else { Err(self) @@ -188,15 +301,26 @@ macro_rules! impl_outer_origin { } } impl From::AccountId>> for $name { + /// Convert to runtime origin with caller being system signed or none and use filter + /// `frame-system::Trait::BaseCallFilter`. fn from(x: Option<<$runtime as $system::Trait>::AccountId>) -> Self { <$system::Origin<$runtime>>::from(x).into() } } + $( $crate::paste::item! { + impl From<$module::Origin < $( $generic )? $(, $module::$generic_instance )? > > for $caller_name { + fn from(x: $module::Origin < $( $generic )? $(, $module::$generic_instance )? >) -> Self { + $caller_name::[< $module $( _ $generic_instance )? >](x) + } + } + impl From<$module::Origin < $( $generic )? $(, $module::$generic_instance )? > > for $name { + /// Convert to runtime origin using `frame-system::Trait::BaseCallFilter`. fn from(x: $module::Origin < $( $generic )? $(, $module::$generic_instance )? >) -> Self { - $name::[< $module $( _ $generic_instance )? >](x) + let x: $caller_name = x.into(); + x.into() } } impl Into< @@ -205,11 +329,12 @@ macro_rules! impl_outer_origin { $name, >> for $name { + /// NOTE: converting to pallet origin loses the origin filter information. fn into(self) -> $crate::sp_std::result::Result< $module::Origin < $( $generic )? $(, $module::$generic_instance )? >, Self, > { - if let $name::[< $module $( _ $generic_instance )? >](l) = self { + if let $caller_name::[< $module $( _ $generic_instance )? >](l) = self.caller { Ok(l) } else { Err(self) @@ -223,12 +348,18 @@ macro_rules! impl_outer_origin { #[cfg(test)] mod tests { - mod system { + use codec::{Encode, Decode}; + use crate::traits::{Filter, OriginTrait}; + mod frame_system { + use super::*; + pub trait Trait { type AccountId; + type Call; + type BaseCallFilter; } - #[derive(Clone, PartialEq, Eq, Debug)] + #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] pub enum RawOrigin { Root, Signed(AccountId), @@ -248,22 +379,35 @@ mod tests { } mod origin_without_generic { - #[derive(Clone, PartialEq, Eq, Debug)] + use super::*; + + #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] pub struct Origin; } mod origin_with_generic { - #[derive(Clone, PartialEq, Eq, Debug)] + use super::*; + + #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] pub struct Origin { t: T } } - #[derive(Clone, PartialEq, Eq, Debug)] + #[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)] pub struct TestRuntime; - impl system::Trait for TestRuntime { + pub struct BaseCallFilter; + impl Filter for BaseCallFilter { + fn filter(c: &u32) -> bool { + *c % 2 == 0 + } + } + + impl frame_system::Trait for TestRuntime { type AccountId = u32; + type Call = u32; + type BaseCallFilter = BaseCallFilter; } impl_outer_origin!( @@ -281,20 +425,51 @@ mod tests { ); impl_outer_origin!( - pub enum OriginWithSystem for TestRuntime where system = system { + pub enum OriginWithSystem for TestRuntime where system = frame_system { origin_without_generic, origin_with_generic } ); impl_outer_origin!( - pub enum OriginWithSystem2 for TestRuntime where system = system { + pub enum OriginWithSystem2 for TestRuntime where system = frame_system { origin_with_generic, origin_without_generic, } ); impl_outer_origin!( - pub enum OriginEmpty for TestRuntime where system = system {} + pub enum OriginEmpty for TestRuntime where system = frame_system {} ); + + #[test] + fn test_default_filter() { + assert_eq!(OriginWithSystem::root().filter_call(&0), true); + assert_eq!(OriginWithSystem::root().filter_call(&1), true); + assert_eq!(OriginWithSystem::none().filter_call(&0), true); + assert_eq!(OriginWithSystem::none().filter_call(&1), false); + assert_eq!(OriginWithSystem::signed(0).filter_call(&0), true); + assert_eq!(OriginWithSystem::signed(0).filter_call(&1), false); + assert_eq!(OriginWithSystem::from(Some(0)).filter_call(&0), true); + assert_eq!(OriginWithSystem::from(Some(0)).filter_call(&1), false); + assert_eq!(OriginWithSystem::from(None).filter_call(&0), true); + assert_eq!(OriginWithSystem::from(None).filter_call(&1), false); + assert_eq!(OriginWithSystem::from(origin_without_generic::Origin).filter_call(&0), true); + assert_eq!(OriginWithSystem::from(origin_without_generic::Origin).filter_call(&1), false); + + let mut origin = OriginWithSystem::from(Some(0)); + + origin.add_filter(|c| *c % 2 == 1); + assert_eq!(origin.filter_call(&0), false); + assert_eq!(origin.filter_call(&1), false); + + origin.set_caller_from(OriginWithSystem::root()); + assert!(matches!(origin.caller, OriginWithSystemCaller::system(frame_system::RawOrigin::Root))); + assert_eq!(origin.filter_call(&0), false); + assert_eq!(origin.filter_call(&1), false); + + origin.reset_filter(); + assert_eq!(origin.filter_call(&0), true); + assert_eq!(origin.filter_call(&1), false); + } } diff --git a/frame/support/src/storage/child.rs b/frame/support/src/storage/child.rs index 658908d258a2ffee230b555a38aa18865e74c276..431b5e09303844db6bf212e325e251b22708c642 100644 --- a/frame/support/src/storage/child.rs +++ b/frame/support/src/storage/child.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Operation on runtime child storages. //! diff --git a/frame/support/src/storage/generator/double_map.rs b/frame/support/src/storage/generator/double_map.rs index 722a9dcabc7c21cfbef04048467340b6094850c5..3c82f4156a27182ff4f5edd382845aed3471ab90 100644 --- a/frame/support/src/storage/generator/double_map.rs +++ b/frame/support/src/storage/generator/double_map.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use sp_std::prelude::*; use sp_std::borrow::Borrow; @@ -227,6 +228,15 @@ impl storage::StorageDoubleMap for G where Self::try_mutate(k1, k2, |v| Ok::(f(v))).expect("`Never` can not be constructed; qed") } + fn mutate_exists(k1: KArg1, k2: KArg2, f: F) -> R + where + KArg1: EncodeLike, + KArg2: EncodeLike, + F: FnOnce(&mut Option) -> R, + { + Self::try_mutate_exists(k1, k2, |v| Ok::(f(v))).expect("`Never` can not be constructed; qed") + } + fn try_mutate(k1: KArg1, k2: KArg2, f: F) -> Result where KArg1: EncodeLike, KArg2: EncodeLike, @@ -245,6 +255,25 @@ impl storage::StorageDoubleMap for G where ret } + fn try_mutate_exists(k1: KArg1, k2: KArg2, f: F) -> Result + where + KArg1: EncodeLike, + KArg2: EncodeLike, + F: FnOnce(&mut Option) -> Result, + { + let final_key = Self::storage_double_map_final_key(k1, k2); + let mut val = unhashed::get(final_key.as_ref()); + + let ret = f(&mut val); + if ret.is_ok() { + match val { + Some(ref val) => unhashed::put(final_key.as_ref(), val), + None => unhashed::kill(final_key.as_ref()), + } + } + ret + } + fn append( k1: KArg1, k2: KArg2, diff --git a/frame/support/src/storage/generator/map.rs b/frame/support/src/storage/generator/map.rs index fa870ac07539f089de51a8efe768136de4b89732..fe932b797940b8ac8e8d08b74d1f96d984a7e0a6 100644 --- a/frame/support/src/storage/generator/map.rs +++ b/frame/support/src/storage/generator/map.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. #[cfg(not(feature = "std"))] use sp_std::prelude::*; diff --git a/frame/support/src/storage/generator/mod.rs b/frame/support/src/storage/generator/mod.rs index 07e75055f356a87435fc0ec700e5afdb0795c877..7df7dfd31739918562367edcfe97d8572414df7c 100644 --- a/frame/support/src/storage/generator/mod.rs +++ b/frame/support/src/storage/generator/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Generators are a set of trait on which storage traits are implemented. //! diff --git a/frame/support/src/storage/generator/value.rs b/frame/support/src/storage/generator/value.rs index 9cc36b637279f00aa19f025c94a287214d208a1b..2da3d91718438ffd6cfbf038f1f051992accf3ff 100644 --- a/frame/support/src/storage/generator/value.rs +++ b/frame/support/src/storage/generator/value.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use codec::{FullCodec, Encode, EncodeLike, Decode}; use crate::{ diff --git a/frame/support/src/storage/hashed.rs b/frame/support/src/storage/hashed.rs index a3ffddcb841053e341cb19d90044b596341eb492..96a487111a2af171f108d1627bdc9821498fcbe0 100644 --- a/frame/support/src/storage/hashed.rs +++ b/frame/support/src/storage/hashed.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Operation on runtime storage using hashed keys. diff --git a/frame/support/src/storage/migration.rs b/frame/support/src/storage/migration.rs index 264c3c644e144ee6d042e6323ee915a53f61acb9..75f90ba7b06cc2d9a36e7f48e3a9453aeed9923c 100644 --- a/frame/support/src/storage/migration.rs +++ b/frame/support/src/storage/migration.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Some utilities for helping access storage with arbitrary key types. diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 9214d931e353a6e4fdd96b2e9996b7ae5c449e41..347fd814136d77c682a47a5286fef367a0d4ffdb 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Stuff to do with the runtime's storage. @@ -20,6 +21,7 @@ use sp_std::{prelude::*, marker::PhantomData}; use codec::{FullCodec, FullEncode, Encode, EncodeLike, Decode}; use crate::hash::{Twox128, StorageHasher}; use sp_runtime::generic::{Digest, DigestItem}; +pub use sp_runtime::TransactionOutcome; pub mod unhashed; pub mod hashed; @@ -28,6 +30,25 @@ pub mod child; pub mod generator; pub mod migration; +/// Execute the supplied function in a new storage transaction. +/// +/// All changes to storage performed by the supplied function are discarded if the returned +/// outcome is `TransactionOutcome::Rollback`. +/// +/// Transactions can be nested to any depth. Commits happen to the parent transaction. +pub fn with_transaction(f: impl FnOnce() -> TransactionOutcome) -> R { + use sp_io::storage::{ + start_transaction, commit_transaction, rollback_transaction, + }; + use TransactionOutcome::*; + + start_transaction(); + match f() { + Commit(res) => { commit_transaction(); res }, + Rollback(res) => { rollback_transaction(); res }, + } +} + /// A trait for working with macro-generated storage values under the substrate storage API. /// /// Details on implementation can be found at @@ -345,6 +366,20 @@ pub trait StorageDoubleMap { KArg2: EncodeLike, F: FnOnce(&mut Self::Query) -> Result; + /// Mutate the value under the given keys. Deletes the item if mutated to a `None`. + fn mutate_exists(k1: KArg1, k2: KArg2, f: F) -> R + where + KArg1: EncodeLike, + KArg2: EncodeLike, + F: FnOnce(&mut Option) -> R; + + /// Mutate the item, only if an `Ok` value is returned. Deletes the item if mutated to a `None`. + fn try_mutate_exists(k1: KArg1, k2: KArg2, f: F) -> Result + where + KArg1: EncodeLike, + KArg2: EncodeLike, + F: FnOnce(&mut Option) -> Result; + /// Append the given item to the value in the storage. /// /// `V` is required to implement [`StorageAppend`]. diff --git a/frame/support/src/storage/unhashed.rs b/frame/support/src/storage/unhashed.rs index 1ecf46ef1864708b53e7e19073768196314be5b4..34b146b86f6ba0ecdf75e0bf3467ac76400f085d 100644 --- a/frame/support/src/storage/unhashed.rs +++ b/frame/support/src/storage/unhashed.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Operation on unhashed runtime storage. diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 0230937fc49c7a10fa9dce16cb80b9c6fd43d725..72a3850d2d37ea48fcf89402c48b5ce179f731d4 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Traits for FRAME. //! @@ -24,13 +25,276 @@ use sp_core::u32_trait::Value as U32; use sp_runtime::{ RuntimeDebug, ConsensusEngineId, DispatchResult, DispatchError, traits::{ MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput, Bounded, Zero, - BadOrigin + BadOrigin, AtLeast32BitUnsigned }, }; use crate::dispatch::Parameter; use crate::storage::StorageMap; +use crate::weights::Weight; use impl_trait_for_tuples::impl_for_tuples; +/// Re-expected for the macro. +#[doc(hidden)] +pub use sp_std::{mem::{swap, take}, cell::RefCell, vec::Vec, boxed::Box}; + +/// Simple trait for providing a filter over a reference to some type. +pub trait Filter { + /// Determine if a given value should be allowed through the filter (returns `true`) or not. + fn filter(_: &T) -> bool; +} + +impl Filter for () { + fn filter(_: &T) -> bool { true } +} + +/// Trait to add a constraint onto the filter. +pub trait FilterStack: Filter { + /// The type used to archive the stack. + type Stack; + + /// Add a new `constraint` onto the filter. + fn push(constraint: impl Fn(&T) -> bool + 'static); + + /// Removes the most recently pushed, and not-yet-popped, constraint from the filter. + fn pop(); + + /// Clear the filter, returning a value that may be used later to `restore` it. + fn take() -> Self::Stack; + + /// Restore the filter from a previous `take` operation. + fn restore(taken: Self::Stack); +} + +/// Guard type for pushing a constraint to a `FilterStack` and popping when dropped. +pub struct FilterStackGuard, T>(PhantomData<(F, T)>); + +/// Guard type for clearing all pushed constraints from a `FilterStack` and reinstating them when +/// dropped. +pub struct ClearFilterGuard, T>(Option, PhantomData); + +impl, T> FilterStackGuard { + /// Create a new instance, adding a new `constraint` onto the filter `T`, and popping it when + /// this instance is dropped. + pub fn new(constraint: impl Fn(&T) -> bool + 'static) -> Self { + F::push(constraint); + Self(PhantomData) + } +} + +impl, T> Drop for FilterStackGuard { + fn drop(&mut self) { + F::pop(); + } +} + +impl, T> ClearFilterGuard { + /// Create a new instance, adding a new `constraint` onto the filter `T`, and popping it when + /// this instance is dropped. + pub fn new() -> Self { + Self(Some(F::take()), PhantomData) + } +} + +impl, T> Drop for ClearFilterGuard { + fn drop(&mut self) { + if let Some(taken) = self.0.take() { + F::restore(taken); + } + } +} + +/// Simple trait for providing a filter over a reference to some type, given an instance of itself. +pub trait InstanceFilter: Sized + Send + Sync { + /// Determine if a given value should be allowed through the filter (returns `true`) or not. + fn filter(&self, _: &T) -> bool; + + /// Determines whether `self` matches at least everything that `_o` does. + fn is_superset(&self, _o: &Self) -> bool { false } +} + +impl InstanceFilter for () { + fn filter(&self, _: &T) -> bool { true } + fn is_superset(&self, _o: &Self) -> bool { true } +} + +#[macro_export] +macro_rules! impl_filter_stack { + ($target:ty, $base:ty, $call:ty, $module:ident) => { + #[cfg(feature = "std")] + mod $module { + #[allow(unused_imports)] + use super::*; + use $crate::traits::{swap, take, RefCell, Vec, Box, Filter, FilterStack}; + + thread_local! { + static FILTER: RefCell bool + 'static>>> = RefCell::new(Vec::new()); + } + + impl Filter<$call> for $target { + fn filter(call: &$call) -> bool { + <$base>::filter(call) && + FILTER.with(|filter| filter.borrow().iter().all(|f| f(call))) + } + } + + impl FilterStack<$call> for $target { + type Stack = Vec bool + 'static>>; + fn push(f: impl Fn(&$call) -> bool + 'static) { + FILTER.with(|filter| filter.borrow_mut().push(Box::new(f))); + } + fn pop() { + FILTER.with(|filter| filter.borrow_mut().pop()); + } + fn take() -> Self::Stack { + FILTER.with(|filter| take(filter.borrow_mut().as_mut())) + } + fn restore(mut s: Self::Stack) { + FILTER.with(|filter| swap(filter.borrow_mut().as_mut(), &mut s)); + } + } + } + + #[cfg(not(feature = "std"))] + mod $module { + #[allow(unused_imports)] + use super::*; + use $crate::traits::{swap, take, RefCell, Vec, Box, Filter, FilterStack}; + + struct ThisFilter(RefCell bool + 'static>>>); + // NOTE: Safe only in wasm (guarded above) because there's only one thread. + unsafe impl Send for ThisFilter {} + unsafe impl Sync for ThisFilter {} + + static FILTER: ThisFilter = ThisFilter(RefCell::new(Vec::new())); + + impl Filter<$call> for $target { + fn filter(call: &$call) -> bool { + <$base>::filter(call) && FILTER.0.borrow().iter().all(|f| f(call)) + } + } + + impl FilterStack<$call> for $target { + type Stack = Vec bool + 'static>>; + fn push(f: impl Fn(&$call) -> bool + 'static) { + FILTER.0.borrow_mut().push(Box::new(f)); + } + fn pop() { + FILTER.0.borrow_mut().pop(); + } + fn take() -> Self::Stack { + take(FILTER.0.borrow_mut().as_mut()) + } + fn restore(mut s: Self::Stack) { + swap(FILTER.0.borrow_mut().as_mut(), &mut s); + } + } + } + } +} + +/// Type that provide some integrity tests. +/// +/// This implemented for modules by `decl_module`. +#[impl_for_tuples(30)] +pub trait IntegrityTest { + /// Run integrity test. + /// + /// The test is not executed in a externalities provided environment. + fn integrity_test() {} +} + +#[cfg(test)] +mod test_impl_filter_stack { + use super::*; + + pub struct IsCallable; + pub struct BaseFilter; + impl Filter for BaseFilter { + fn filter(x: &u32) -> bool { x % 2 == 0 } + } + impl_filter_stack!( + crate::traits::test_impl_filter_stack::IsCallable, + crate::traits::test_impl_filter_stack::BaseFilter, + u32, + is_callable + ); + + #[test] + fn impl_filter_stack_should_work() { + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(IsCallable::filter(&42)); + assert!(!IsCallable::filter(&43)); + + IsCallable::push(|x| *x < 42); + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(!IsCallable::filter(&42)); + + IsCallable::push(|x| *x % 3 == 0); + assert!(IsCallable::filter(&36)); + assert!(!IsCallable::filter(&40)); + + IsCallable::pop(); + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(!IsCallable::filter(&42)); + + let saved = IsCallable::take(); + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(IsCallable::filter(&42)); + assert!(!IsCallable::filter(&43)); + + IsCallable::restore(saved); + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(!IsCallable::filter(&42)); + + IsCallable::pop(); + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(IsCallable::filter(&42)); + assert!(!IsCallable::filter(&43)); + } + + #[test] + fn guards_should_work() { + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(IsCallable::filter(&42)); + assert!(!IsCallable::filter(&43)); + { + let _guard_1 = FilterStackGuard::::new(|x| *x < 42); + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(!IsCallable::filter(&42)); + { + let _guard_2 = FilterStackGuard::::new(|x| *x % 3 == 0); + assert!(IsCallable::filter(&36)); + assert!(!IsCallable::filter(&40)); + } + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(!IsCallable::filter(&42)); + { + let _guard_2 = ClearFilterGuard::::new(); + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(IsCallable::filter(&42)); + assert!(!IsCallable::filter(&43)); + } + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(!IsCallable::filter(&42)); + } + assert!(IsCallable::filter(&36)); + assert!(IsCallable::filter(&40)); + assert!(IsCallable::filter(&42)); + assert!(!IsCallable::filter(&43)); + } +} + /// An abstraction of a value stored within storage, but possibly as part of a larger composite /// item. pub trait StoredMap { @@ -65,6 +329,10 @@ pub trait Happened { fn happened(t: &T); } +impl Happened for () { + fn happened(_: &T) {} +} + /// A shim for placing around a storage item in order to use it as a `StoredValue`. Ideally this /// wouldn't be needed as `StorageValue`s should blanket implement `StoredValue`s, however this /// would break the ability to have custom impls of `StoredValue`. The other workaround is to @@ -93,20 +361,23 @@ impl< fn get(k: &K) -> T { S::get(k) } fn is_explicit(k: &K) -> bool { S::contains_key(k) } fn insert(k: &K, t: T) { + let existed = S::contains_key(&k); S::insert(k, t); - if !S::contains_key(&k) { + if !existed { Created::happened(k); } } fn remove(k: &K) { - if S::contains_key(&k) { + let existed = S::contains_key(&k); + S::remove(k); + if existed { Removed::happened(&k); } - S::remove(k); } fn mutate(k: &K, f: impl FnOnce(&mut T) -> R) -> R { + let existed = S::contains_key(&k); let r = S::mutate(k, f); - if !S::contains_key(&k) { + if !existed { Created::happened(k); } r @@ -147,12 +418,19 @@ pub trait EstimateNextSessionRotation { /// /// None should be returned if the estimation fails to come to an answer fn estimate_next_session_rotation(now: BlockNumber) -> Option; + + /// Return the weight of calling `estimate_next_session_rotation` + fn weight(now: BlockNumber) -> Weight; } impl EstimateNextSessionRotation for () { fn estimate_next_session_rotation(_: BlockNumber) -> Option { Default::default() } + + fn weight(_: BlockNumber) -> Weight { + 0 + } } /// Something that can estimate at which block the next `new_session` will be triggered. This must @@ -160,12 +438,19 @@ impl EstimateNextSessionRotation for () { pub trait EstimateNextNewSession { /// Return the block number at which the next new session is estimated to happen. fn estimate_next_new_session(now: BlockNumber) -> Option; + + /// Return the weight of calling `estimate_next_new_session` + fn weight(now: BlockNumber) -> Weight; } impl EstimateNextNewSession for () { fn estimate_next_new_session(_: BlockNumber) -> Option { Default::default() } + + fn weight(_: BlockNumber) -> Weight { + 0 + } } /// Anything that can have a `::len()` method. @@ -180,9 +465,11 @@ impl Len for T where ::IntoIter: Ex } } -/// A trait for querying a single fixed value from a type. +/// A trait for querying a single value from a type. +/// +/// It is not required that the value is constant. pub trait Get { - /// Return a constant value. + /// Return the current value. fn get() -> T; } @@ -505,7 +792,7 @@ pub enum SignedImbalance>{ impl< P: Imbalance, N: Imbalance, - B: AtLeast32Bit + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default, + B: AtLeast32BitUnsigned + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default, > SignedImbalance { pub fn zero() -> Self { SignedImbalance::Positive(P::zero()) @@ -568,7 +855,8 @@ impl< /// Abstraction over a fungible assets system. pub trait Currency { /// The balance of an account. - type Balance: AtLeast32Bit + FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default; + type Balance: AtLeast32BitUnsigned + FullCodec + Copy + MaybeSerializeDeserialize + Debug + + Default; /// The opaque token type for an imbalance. This is returned by unbalanced operations /// and must be dealt with. It may be dropped but cannot be cloned. @@ -609,6 +897,14 @@ pub trait Currency { /// in the case of overflow. fn issue(amount: Self::Balance) -> Self::NegativeImbalance; + /// Produce a pair of imbalances that cancel each other out exactly. + /// + /// This is just the same as burning and issuing the same amount and has no effect on the + /// total issuance. + fn pair(amount: Self::Balance) -> (Self::PositiveImbalance, Self::NegativeImbalance) { + (Self::burn(amount.clone()), Self::issue(amount)) + } + /// The 'free' balance of a given account. /// /// This is the only balance that matters in terms of most operations on tokens. It alone @@ -736,6 +1032,7 @@ pub trait Currency { } /// Status of funds. +#[derive(PartialEq, Eq, Clone, Copy, Encode, Decode, RuntimeDebug)] pub enum BalanceStatus { /// Funds are free, as corresponding to `free` item in Balances. Free, @@ -941,7 +1238,7 @@ pub trait ChangeMembers { /// /// This resets any previous value of prime. fn change_members(incoming: &[AccountId], outgoing: &[AccountId], mut new: Vec) { - new.sort_unstable(); + new.sort(); Self::change_members_sorted(incoming, outgoing, &new[..]); } @@ -1142,11 +1439,19 @@ impl OnInitialize for Tuple { } } -/// The runtime upgrade trait. Implementing this lets you express what should happen -/// when the runtime upgrades, and changes may need to occur to your module. +/// The runtime upgrade trait. +/// +/// Implementing this lets you express what should happen when the runtime upgrades, +/// and changes may need to occur to your module. pub trait OnRuntimeUpgrade { /// Perform a module upgrade. /// + /// # Warning + /// + /// This function will be called before we initialized any runtime state, aka `on_initialize` + /// wasn't called yet. So, information like the block number and any other + /// block local data are not accessible. + /// /// Return the non-negotiable weight consumed for runtime upgrade. fn on_runtime_upgrade() -> crate::weights::Weight { 0 } } @@ -1193,17 +1498,26 @@ pub mod schedule { /// higher priority. pub type Priority = u8; + /// The dispatch time of a scheduled task. + #[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug)] + pub enum DispatchTime { + /// At specified block. + At(BlockNumber), + /// After specified number of blocks. + After(BlockNumber), + } + /// The highest priority. We invert the value so that normal sorting will place the highest /// priority at the beginning of the list. - pub const HIGHEST_PRORITY: Priority = 0; + pub const HIGHEST_PRIORITY: Priority = 0; /// Anything of this value or lower will definitely be scheduled on the block that they ask for, even /// if it breaches the `MaximumWeight` limitation. pub const HARD_DEADLINE: Priority = 63; /// The lowest priority. Most stuff should be around here. - pub const LOWEST_PRORITY: Priority = 255; + pub const LOWEST_PRIORITY: Priority = 255; /// A type that can be used as a scheduler. - pub trait Anon { + pub trait Anon { /// An address which can be used for removing a scheduled task. type Address: Codec + Clone + Eq + EncodeLike + Debug; @@ -1213,11 +1527,12 @@ pub mod schedule { /// /// Infallible. fn schedule( - when: BlockNumber, + when: DispatchTime, maybe_periodic: Option>, priority: Priority, + origin: Origin, call: Call - ) -> Self::Address; + ) -> Result; /// Cancel a scheduled task. If periodic, then it will cancel all further instances of that, /// also. @@ -1233,7 +1548,7 @@ pub mod schedule { } /// A type that can be used as a scheduler. - pub trait Named { + pub trait Named { /// An address which can be used for removing a scheduled task. type Address: Codec + Clone + Eq + EncodeLike + sp_std::fmt::Debug; @@ -1242,9 +1557,10 @@ pub mod schedule { /// - `id`: The identity of the task. This must be unique and will return an error if not. fn schedule_named( id: Vec, - when: BlockNumber, + when: DispatchTime, maybe_periodic: Option>, priority: Priority, + origin: Origin, call: Call ) -> Result; @@ -1277,6 +1593,77 @@ pub trait EnsureOrigin { fn successful_origin() -> OuterOrigin; } +/// Type that can be dispatched with an origin but without checking the origin filter. +/// +/// Implemented for pallet dispatchable type by `decl_module` and for runtime dispatchable by +/// `construct_runtime` and `impl_outer_dispatch`. +pub trait UnfilteredDispatchable { + /// The origin type of the runtime, (i.e. `frame_system::Trait::Origin`). + type Origin; + + /// Dispatch this call but do not check the filter in origin. + fn dispatch_bypass_filter(self, origin: Self::Origin) -> crate::dispatch::DispatchResultWithPostInfo; +} + +/// Methods available on `frame_system::Trait::Origin`. +pub trait OriginTrait: Sized { + /// Runtime call type, as in `frame_system::Trait::Call` + type Call; + + /// The caller origin, overarching type of all pallets origins. + type PalletsOrigin; + + /// Add a filter to the origin. + fn add_filter(&mut self, filter: impl Fn(&Self::Call) -> bool + 'static); + + /// Reset origin filters to default one, i.e `frame_system::Trait::BaseCallFilter`. + fn reset_filter(&mut self); + + /// Replace the caller with caller from the other origin + fn set_caller_from(&mut self, other: impl Into); + + /// Filter the call, if false then call is filtered out. + fn filter_call(&self, call: &Self::Call) -> bool; + + /// Get the caller. + fn caller(&self) -> &Self::PalletsOrigin; +} + +/// Trait to be used when types are exactly same. +/// +/// This allow to convert back and forth from type, a reference and a mutable reference. +pub trait IsType: Into + From { + /// Cast reference. + fn from_ref(t: &T) -> &Self; + + /// Cast reference. + fn into_ref(&self) -> &T; + + /// Cast mutable reference. + fn from_mut(t: &mut T) -> &mut Self; + + /// Cast mutable reference. + fn into_mut(&mut self) -> &mut T; +} + +impl IsType for T { + fn from_ref(t: &T) -> &Self { t } + fn into_ref(&self) -> &T { self } + fn from_mut(t: &mut T) -> &mut Self { t } + fn into_mut(&mut self) -> &mut T { self } +} + +/// An instance of a pallet in the storage. +/// +/// It is required that these instances are unique, to support multiple instances per pallet in the same runtime! +/// +/// E.g. for module MyModule default instance will have prefix "MyModule" and other instances +/// "InstanceNMyModule". +pub trait Instance: 'static { + /// Unique module prefix. E.g. "InstanceNMyModule" or "MyModule" + const PREFIX: &'static str ; +} + #[cfg(test)] mod tests { use super::*; diff --git a/frame/support/src/unsigned.rs b/frame/support/src/unsigned.rs index 3bc6f692affc20426f196792666fe1c0413c146f..16c434fe638bca64c9f1dd6a266af052852d9207 100644 --- a/frame/support/src/unsigned.rs +++ b/frame/support/src/unsigned.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. #[doc(hidden)] pub use crate::sp_runtime::traits::ValidateUnsigned; diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index 1d3862b60fb7c22b68509d1fe0d413faac387d7a..db1e25ca7ab2e08112c5defa8be035a34e5e8b95 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Primitives for transaction weighting. //! @@ -38,7 +39,7 @@ //! `Yes`**. //! //! ``` -//! # use frame_system::{self as system, Trait}; +//! # use frame_system::Trait; //! frame_support::decl_module! { //! pub struct Module for enum Call where origin: T::Origin { //! #[weight = 1000] @@ -51,7 +52,7 @@ //! 2.1 Define weight and class, **in which case `PaysFee` would be `Yes`**. //! //! ``` -//! # use frame_system::{self as system, Trait}; +//! # use frame_system::Trait; //! # use frame_support::weights::DispatchClass; //! frame_support::decl_module! { //! pub struct Module for enum Call where origin: T::Origin { @@ -65,7 +66,7 @@ //! 2.2 Define weight and `PaysFee`, **in which case `ClassifyDispatch` would be `Normal`**. //! //! ``` -//! # use frame_system::{self as system, Trait}; +//! # use frame_system::Trait; //! # use frame_support::weights::Pays; //! frame_support::decl_module! { //! pub struct Module for enum Call where origin: T::Origin { @@ -79,7 +80,7 @@ //! 3. Define all 3 parameters. //! //! ``` -//! # use frame_system::{self as system, Trait}; +//! # use frame_system::Trait; //! # use frame_support::weights::{DispatchClass, Pays}; //! frame_support::decl_module! { //! pub struct Module for enum Call where origin: T::Origin { @@ -99,7 +100,7 @@ //! all 3 are static values, providing a raw tuple is easier. //! //! ``` -//! # use frame_system::{self as system, Trait}; +//! # use frame_system::Trait; //! # use frame_support::weights::{DispatchClass, FunctionOf, Pays}; //! frame_support::decl_module! { //! pub struct Module for enum Call where origin: T::Origin { @@ -133,7 +134,10 @@ use sp_runtime::{ traits::SignedExtension, generic::{CheckedExtrinsic, UncheckedExtrinsic}, }; -use crate::dispatch::{DispatchErrorWithPostInfo, DispatchError}; +use crate::dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, DispatchError}; +use sp_runtime::traits::SaturatedConversion; +use sp_arithmetic::{Perbill, traits::{BaseArithmetic, Saturating, Unsigned}}; +use smallvec::{smallvec, SmallVec}; /// Re-export priority as type pub use sp_runtime::transaction_validity::TransactionPriority; @@ -259,23 +263,68 @@ pub trait GetDispatchInfo { } /// Weight information that is only available post dispatch. +/// NOTE: This can only be used to reduce the weight or fee, not increase it. #[derive(Clone, Copy, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)] pub struct PostDispatchInfo { /// Actual weight consumed by a call or `None` which stands for the worst case static weight. pub actual_weight: Option, + /// Whether this transaction should pay fees when all is said and done. + pub pays_fee: Pays, } impl PostDispatchInfo { /// Calculate how much (if any) weight was not used by the `Dispatchable`. pub fn calc_unspent(&self, info: &DispatchInfo) -> Weight { + info.weight - self.calc_actual_weight(info) + } + + /// Calculate how much weight was actually spent by the `Dispatchable`. + pub fn calc_actual_weight(&self, info: &DispatchInfo) -> Weight { if let Some(actual_weight) = self.actual_weight { - if actual_weight >= info.weight { - 0 - } else { - info.weight - actual_weight - } + actual_weight.min(info.weight) } else { - 0 + info.weight + } + } + + /// Determine if user should actually pay fees at the end of the dispatch. + pub fn pays_fee(&self, info: &DispatchInfo) -> Pays { + // If they originally were not paying fees, or the post dispatch info + // says they should not pay fees, then they don't pay fees. + // This is because the pre dispatch information must contain the + // worst case for weight and fees paid. + if info.pays_fee == Pays::No || self.pays_fee == Pays::No { + Pays::No + } else { + // Otherwise they pay. + Pays::Yes + } + } +} + +/// Extract the actual weight from a dispatch result if any or fall back to the default weight. +pub fn extract_actual_weight(result: &DispatchResultWithPostInfo, info: &DispatchInfo) -> Weight { + match result { + Ok(post_info) => &post_info, + Err(err) => &err.post_info, + }.calc_actual_weight(info) +} + +impl From<(Option, Pays)> for PostDispatchInfo { + fn from(post_weight_info: (Option, Pays)) -> Self { + let (actual_weight, pays_fee) = post_weight_info; + Self { + actual_weight, + pays_fee, + } + } +} + +impl From for PostDispatchInfo { + fn from(pays_fee: Pays) -> Self { + Self { + actual_weight: None, + pays_fee, } } } @@ -284,6 +333,7 @@ impl From> for PostDispatchInfo { fn from(actual_weight: Option) -> Self { Self { actual_weight, + pays_fee: Default::default(), } } } @@ -292,6 +342,7 @@ impl From<()> for PostDispatchInfo { fn from(_: ()) -> Self { Self { actual_weight: None, + pays_fee: Default::default(), } } } @@ -302,6 +353,11 @@ impl sp_runtime::traits::Printable for PostDispatchInfo { match self.actual_weight { Some(weight) => weight.print(), None => "max-weight".print(), + }; + "pays_fee=".print(); + match self.pays_fee { + Pays::Yes => "Yes".print(), + Pays::No => "No".print(), } } } @@ -325,7 +381,10 @@ impl WithPostDispatchInfo for T where { fn with_weight(self, actual_weight: Weight) -> DispatchErrorWithPostInfo { DispatchErrorWithPostInfo { - post_info: PostDispatchInfo { actual_weight: Some(actual_weight) }, + post_info: PostDispatchInfo { + actual_weight: Some(actual_weight), + pays_fee: Default::default(), + }, error: self.into(), } } @@ -412,9 +471,11 @@ impl PaysFee for (Weight, Pays) { /// with the same argument list as the dispatched, wrapped in a tuple. /// - `PF`: a `Pays` variant for whether this dispatch pays fee or not or a closure that /// returns a `Pays` variant with the same argument list as the dispatched, wrapped in a tuple. +#[deprecated = "Function arguments are available directly inside the annotation now."] pub struct FunctionOf(pub WD, pub CD, pub PF); // `WeighData` as a raw value +#[allow(deprecated)] impl WeighData for FunctionOf { fn weigh_data(&self, _: Args) -> Weight { self.0 @@ -422,6 +483,7 @@ impl WeighData for FunctionOf { } // `WeighData` as a closure +#[allow(deprecated)] impl WeighData for FunctionOf where WD : Fn(Args) -> Weight { @@ -431,6 +493,7 @@ impl WeighData for FunctionOf where } // `ClassifyDispatch` as a raw value +#[allow(deprecated)] impl ClassifyDispatch for FunctionOf { fn classify_dispatch(&self, _: Args) -> DispatchClass { self.1 @@ -438,6 +501,7 @@ impl ClassifyDispatch for FunctionOf } // `ClassifyDispatch` as a raw value +#[allow(deprecated)] impl ClassifyDispatch for FunctionOf where CD : Fn(Args) -> DispatchClass { @@ -447,6 +511,7 @@ impl ClassifyDispatch for FunctionOf where } // `PaysFee` as a raw value +#[allow(deprecated)] impl PaysFee for FunctionOf { fn pays_fee(&self, _: Args) -> Pays { self.2 @@ -454,6 +519,7 @@ impl PaysFee for FunctionOf { } // `PaysFee` as a closure +#[allow(deprecated)] impl PaysFee for FunctionOf where PF : Fn(Args) -> Pays { @@ -521,6 +587,90 @@ impl RuntimeDbWeight { } } +/// One coefficient and its position in the `WeightToFeePolynomial`. +/// +/// One term of polynomial is calculated as: +/// +/// ```ignore +/// coeff_integer * x^(degree) + coeff_frac * x^(degree) +/// ``` +/// +/// The `negative` value encodes whether the term is added or substracted from the +/// overall polynomial result. +#[derive(Clone, Encode, Decode)] +pub struct WeightToFeeCoefficient { + /// The integral part of the coefficient. + pub coeff_integer: Balance, + /// The fractional part of the coefficient. + pub coeff_frac: Perbill, + /// True iff the coefficient should be interpreted as negative. + pub negative: bool, + /// Degree/exponent of the term. + pub degree: u8, +} + +/// A list of coefficients that represent one polynomial. +pub type WeightToFeeCoefficients = SmallVec<[WeightToFeeCoefficient; 4]>; + +/// A trait that describes the weight to fee calculation as polynomial. +/// +/// An implementor should only implement the `polynomial` function. +pub trait WeightToFeePolynomial { + /// The type that is returned as result from polynomial evaluation. + type Balance: BaseArithmetic + From + Copy + Unsigned; + + /// Returns a polynomial that describes the weight to fee conversion. + /// + /// This is the only function that should be manually implemented. Please note + /// that all calculation is done in the probably unsigned `Balance` type. This means + /// that the order of coefficients is important as putting the negative coefficients + /// first will most likely saturate the result to zero mid evaluation. + fn polynomial() -> WeightToFeeCoefficients; + + /// Calculates the fee from the passed `weight` according to the `polynomial`. + /// + /// This should not be overriden in most circumstances. Calculation is done in the + /// `Balance` type and never overflows. All evaluation is saturating. + fn calc(weight: &Weight) -> Self::Balance { + Self::polynomial().iter().fold(Self::Balance::saturated_from(0u32), |mut acc, args| { + let w = Self::Balance::saturated_from(*weight).saturating_pow(args.degree.into()); + + // The sum could get negative. Therefore we only sum with the accumulator. + // The Perbill Mul implementation is non overflowing. + let frac = args.coeff_frac * w; + let integer = args.coeff_integer.saturating_mul(w); + + if args.negative { + acc = acc.saturating_sub(frac); + acc = acc.saturating_sub(integer); + } else { + acc = acc.saturating_add(frac); + acc = acc.saturating_add(integer); + } + + acc + }) + } +} + +/// Implementor of `WeightToFeePolynomial` that maps one unit of weight to one unit of fee. +pub struct IdentityFee(sp_std::marker::PhantomData); + +impl WeightToFeePolynomial for IdentityFee where + T: BaseArithmetic + From + Copy + Unsigned +{ + type Balance = T; + + fn polynomial() -> WeightToFeeCoefficients { + smallvec!(WeightToFeeCoefficient { + coeff_integer: 1u32.into(), + coeff_frac: Perbill::zero(), + negative: false, + degree: 1, + }) + } +} + #[cfg(test)] #[allow(dead_code)] mod tests { @@ -566,10 +716,10 @@ mod tests { fn f03(_origin) { unimplemented!(); } // weight = a x 10 + b - #[weight = FunctionOf(|args: (&u32, &u32)| (args.0 * 10 + args.1) as Weight, DispatchClass::Normal, Pays::Yes)] + #[weight = ((_a * 10 + _eb * 1) as Weight, DispatchClass::Normal, Pays::Yes)] fn f11(_origin, _a: u32, _eb: u32) { unimplemented!(); } - #[weight = FunctionOf(|_: (&u32, &u32)| 0, DispatchClass::Operational, Pays::Yes)] + #[weight = (0, DispatchClass::Operational, Pays::Yes)] fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); } #[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + 10_000] @@ -615,4 +765,91 @@ mod tests { assert_eq!(Call::::f21().get_dispatch_info().weight, 45600); assert_eq!(Call::::f2().get_dispatch_info().class, DispatchClass::Normal); } + + #[test] + fn extract_actual_weight_works() { + let pre = DispatchInfo { + weight: 1000, + .. Default::default() + }; + assert_eq!(extract_actual_weight(&Ok(Some(7).into()), &pre), 7); + assert_eq!(extract_actual_weight(&Ok(Some(1000).into()), &pre), 1000); + assert_eq!( + extract_actual_weight(&Err(DispatchError::BadOrigin.with_weight(9)), &pre), + 9 + ); + } + + #[test] + fn extract_actual_weight_caps_at_pre_weight() { + let pre = DispatchInfo { + weight: 1000, + .. Default::default() + }; + assert_eq!(extract_actual_weight(&Ok(Some(1250).into()), &pre), 1000); + assert_eq!( + extract_actual_weight(&Err(DispatchError::BadOrigin.with_weight(1300)), &pre), + 1000 + ); + } + + type Balance = u64; + + // 0.5x^3 + 2.333x2 + 7x - 10_000 + struct Poly; + impl WeightToFeePolynomial for Poly { + type Balance = Balance; + + fn polynomial() -> WeightToFeeCoefficients { + smallvec![ + WeightToFeeCoefficient { + coeff_integer: 0, + coeff_frac: Perbill::from_fraction(0.5), + negative: false, + degree: 3 + }, + WeightToFeeCoefficient { + coeff_integer: 2, + coeff_frac: Perbill::from_rational_approximation(1u32, 3u32), + negative: false, + degree: 2 + }, + WeightToFeeCoefficient { + coeff_integer: 7, + coeff_frac: Perbill::zero(), + negative: false, + degree: 1 + }, + WeightToFeeCoefficient { + coeff_integer: 10_000, + coeff_frac: Perbill::zero(), + negative: true, + degree: 0 + }, + ] + } + } + + #[test] + fn polynomial_works() { + assert_eq!(Poly::calc(&100), 514033); + assert_eq!(Poly::calc(&10_123), 518917034928); + } + + #[test] + fn polynomial_does_not_underflow() { + assert_eq!(Poly::calc(&0), 0); + } + + #[test] + fn polynomial_does_not_overflow() { + assert_eq!(Poly::calc(&Weight::max_value()), Balance::max_value() - 10_000); + } + + #[test] + fn identity_fee_works() { + assert_eq!(IdentityFee::::calc(&0), 0); + assert_eq!(IdentityFee::::calc(&50), 50); + assert_eq!(IdentityFee::::calc(&Weight::max_value()), Balance::max_value()); + } } diff --git a/frame/support/test/Cargo.toml b/frame/support/test/Cargo.toml index 77899788d2d96e6f876e97d11a9c4f31408146a4..f2f70fb95279e119770269df71f37a55e6305f91 100644 --- a/frame/support/test/Cargo.toml +++ b/frame/support/test/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-support-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -13,13 +13,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", default-features = false, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-io ={ path = "../../../primitives/io", default-features = false , version = "2.0.0-dev"} -sp-state-machine = { version = "0.8.0-dev", optional = true, path = "../../../primitives/state-machine" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../" } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/inherents" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-io = { version = "2.0.0-rc6", path = "../../../primitives/io", default-features = false } +sp-state-machine = { version = "0.8.0-rc6", optional = true, path = "../../../primitives/state-machine" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../" } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/inherents" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/std" } trybuild = "1.0.17" pretty_assertions = "0.6.1" rustversion = "1.0.0" @@ -33,6 +34,7 @@ std = [ "frame-support/std", "sp-inherents/std", "sp-core/std", + "sp-std/std", "sp-runtime/std", "sp-state-machine", ] diff --git a/frame/support/test/src/lib.rs b/frame/support/test/src/lib.rs index f62f5522680ebd724ed991f4ec2074a308df6c1b..c0baf448eed850511b2cdc33e307d6758739da8f 100644 --- a/frame/support/test/src/lib.rs +++ b/frame/support/test/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Test crate for frame_support. Allow to make use of `frame_support::decl_storage`. //! See tests directory. diff --git a/frame/support/test/tests/decl_error.rs b/frame/support/test/tests/construct_runtime.rs similarity index 71% rename from frame/support/test/tests/decl_error.rs rename to frame/support/test/tests/construct_runtime.rs index eb14ae7502fe3bbcd773575e0f776dea26e41448..10fc3319fb080fb34d70fd0dcddc3b991c4290ff 100644 --- a/frame/support/test/tests/decl_error.rs +++ b/frame/support/test/tests/construct_runtime.rs @@ -1,29 +1,38 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! General tests for construct_runtime macro, test for: +//! * error declareed with decl_error works +//! * integrity test is generated #![recursion_limit="128"] use sp_runtime::{generic, traits::{BlakeTwo256, Block as _, Verify}, DispatchError}; use sp_core::{H256, sr25519}; - +use sp_std::cell::RefCell; mod system; pub trait Currency {} +thread_local! { + pub static INTEGRITY_TEST_EXEC: RefCell = RefCell::new(0); +} + mod module1 { use super::*; @@ -64,6 +73,10 @@ mod module2 { pub fn fail(_origin) -> frame_support::dispatch::DispatchResult { Err(Error::::Something.into()) } + + fn integrity_test() { + INTEGRITY_TEST_EXEC.with(|i| *i.borrow_mut() += 1); + } } } @@ -88,12 +101,14 @@ pub type BlockNumber = u64; pub type Index = u64; impl system::Trait for Runtime { + type BaseCallFilter = (); type Hash = H256; type Origin = Origin; type BlockNumber = BlockNumber; type AccountId = AccountId; type Event = Event; type ModuleToIndex = ModuleToIndex; + type Call = Call; } frame_support::construct_runtime!( @@ -136,3 +151,9 @@ fn check_module2_error_type() { Err(DispatchError::Module { index: 2, error: 0, message: Some("Something") }), ); } + +#[test] +fn integrity_test_works() { + __construct_runtime_integrity_test::runtime_integrity_tests(); + assert_eq!(INTEGRITY_TEST_EXEC.with(|i| *i.borrow()), 1); +} diff --git a/frame/support/test/tests/construct_runtime_ui.rs b/frame/support/test/tests/construct_runtime_ui.rs index d094d73ba54e9a7de4dded597c5dd9f4aedfa97d..e1624c76830ae21849cd8dd6329476c779569bd6 100644 --- a/frame/support/test/tests/construct_runtime_ui.rs +++ b/frame/support/test/tests/construct_runtime_ui.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use std::env; diff --git a/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr b/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr index 442af9c01fa3469901f097055d01a120b0f630c7..2ebe0721eb381b54514a3f96445b10b335c350f9 100644 --- a/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr +++ b/frame/support/test/tests/construct_runtime_ui/missing_system_module.stderr @@ -1,4 +1,4 @@ -error: `System` module declaration is missing. Please add this line: `System: system::{Module, Call, Storage, Config, Event},` +error: `System` module declaration is missing. Please add this line: `System: frame_system::{Module, Call, Storage, Config, Event},` --> $DIR/missing_system_module.rs:8:2 | 8 | { diff --git a/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.rs b/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.rs deleted file mode 100644 index 9c752a2f39e2ad70f3acb2cd976abfcedf6455b8..0000000000000000000000000000000000000000 --- a/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.rs +++ /dev/null @@ -1,14 +0,0 @@ -use frame_support::construct_runtime; - -construct_runtime! { - pub enum Runtime where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: system::{Module}, - Balance: balances::::{Call(toto), Origin}, - } -} - -fn main() {} diff --git a/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.stderr b/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.stderr deleted file mode 100644 index 58f35720e31f739fb23eb3a50d7a09d970d7df05..0000000000000000000000000000000000000000 --- a/frame/support/test/tests/construct_runtime_ui/params_in_invalid_module.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: `Call` is not allowed to have arguments in parens. Only the following modules are allowed to have arguments in parens: `Inherent`. - --> $DIR/params_in_invalid_module.rs:10:40 - | -10 | Balance: balances::::{Call(toto), Origin}, - | ^^^^^^ diff --git a/frame/support/test/tests/decl_module_ui.rs b/frame/support/test/tests/decl_module_ui.rs new file mode 100644 index 0000000000000000000000000000000000000000..7df64bc52f41261ddedef6b2510347602697eb03 --- /dev/null +++ b/frame/support/test/tests/decl_module_ui.rs @@ -0,0 +1,26 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +#[rustversion::attr(not(stable), ignore)] +#[test] +fn decl_module_ui() { + // As trybuild is using `cargo check`, we don't need the real WASM binaries. + std::env::set_var("BUILD_DUMMY_WASM_BINARY", "1"); + + let t = trybuild::TestCases::new(); + t.compile_fail("tests/decl_module_ui/*.rs"); +} diff --git a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.rs b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.rs new file mode 100644 index 0000000000000000000000000000000000000000..4dbae05f07ff77869d3f7c6367079138d7cbf73f --- /dev/null +++ b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.rs @@ -0,0 +1,7 @@ +frame_support::decl_module! { + pub struct Module for enum Call where origin: T::Origin { + fn integrity_test() {} + + fn integrity_test() {} + } +} diff --git a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.stderr b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.stderr new file mode 100644 index 0000000000000000000000000000000000000000..d6498961d31c8006ec5f37218f9ff16b19fc80e4 --- /dev/null +++ b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.stderr @@ -0,0 +1,25 @@ +error: `integrity_test` can only be passed once as input. + --> $DIR/reserved_keyword_two_times_integrity_test.rs:1:1 + | +1 | / frame_support::decl_module! { +2 | | pub struct Module for enum Call where origin: T::Origin { +3 | | fn integrity_test() {} +4 | | +5 | | fn integrity_test() {} +6 | | } +7 | | } + | |_^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0601]: `main` function not found in crate `$CRATE` + --> $DIR/reserved_keyword_two_times_integrity_test.rs:1:1 + | +1 | / frame_support::decl_module! { +2 | | pub struct Module for enum Call where origin: T::Origin { +3 | | fn integrity_test() {} +4 | | +5 | | fn integrity_test() {} +6 | | } +7 | | } + | |_^ consider adding a `main` function to `$DIR/tests/decl_module_ui/reserved_keyword_two_times_integrity_test.rs` diff --git a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.rs b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.rs new file mode 100644 index 0000000000000000000000000000000000000000..4f05134997e81e380010ff74a462c81f8833ac4d --- /dev/null +++ b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.rs @@ -0,0 +1,11 @@ +frame_support::decl_module! { + pub struct Module for enum Call where origin: T::Origin { + fn on_initialize() -> Weight { + 0 + } + + fn on_initialize() -> Weight { + 0 + } + } +} diff --git a/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.stderr b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.stderr new file mode 100644 index 0000000000000000000000000000000000000000..8a9f025046b7ee57323afd3c6faa0b2c6d5cda43 --- /dev/null +++ b/frame/support/test/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.stderr @@ -0,0 +1,25 @@ +error: `on_initialize` can only be passed once as input. + --> $DIR/reserved_keyword_two_times_on_initialize.rs:1:1 + | +1 | / frame_support::decl_module! { +2 | | pub struct Module for enum Call where origin: T::Origin { +3 | | fn on_initialize() -> Weight { +4 | | 0 +... | +10 | | } +11 | | } + | |_^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0601]: `main` function not found in crate `$CRATE` + --> $DIR/reserved_keyword_two_times_on_initialize.rs:1:1 + | +1 | / frame_support::decl_module! { +2 | | pub struct Module for enum Call where origin: T::Origin { +3 | | fn on_initialize() -> Weight { +4 | | 0 +... | +10 | | } +11 | | } + | |_^ consider adding a `main` function to `$DIR/tests/decl_module_ui/reserved_keyword_two_times_on_initialize.rs` diff --git a/frame/support/test/tests/decl_storage.rs b/frame/support/test/tests/decl_storage.rs index 5ec5bbecfee2d1fe7b606452caebc6bbaa58acea..cda1d810d225ca55cfed587cc9322cf47566c999 100644 --- a/frame/support/test/tests/decl_storage.rs +++ b/frame/support/test/tests/decl_storage.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. #[cfg(test)] // Do not complain about unused `dispatch` and `dispatch_aux`. diff --git a/frame/support/test/tests/decl_storage_ui.rs b/frame/support/test/tests/decl_storage_ui.rs index 3aee5e98664131ee4d7f257016c601e10fe0f00d..56529d62c28ff7adefc43557cf4fbc75299c39a3 100644 --- a/frame/support/test/tests/decl_storage_ui.rs +++ b/frame/support/test/tests/decl_storage_ui.rs @@ -1,19 +1,21 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. +#[rustversion::attr(not(stable), ignore)] #[test] fn decl_storage_ui() { // As trybuild is using `cargo check`, we don't need the real WASM binaries. diff --git a/frame/support/test/tests/decl_storage_ui/config_duplicate.rs b/frame/support/test/tests/decl_storage_ui/config_duplicate.rs index 0f2759e740d7ddb81fc2edf244dab3b7422dd8c1..4d510da9f893652be1381babff9fe09980baf753 100644 --- a/frame/support/test/tests/decl_storage_ui/config_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/config_duplicate.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. pub trait Trait { type Origin; diff --git a/frame/support/test/tests/decl_storage_ui/config_duplicate.stderr b/frame/support/test/tests/decl_storage_ui/config_duplicate.stderr index 761e3f3b7982492444854ec669094eb948f0c409..61f7c0bbe64a5ae48c4353a069953a34b675b633 100644 --- a/frame/support/test/tests/decl_storage_ui/config_duplicate.stderr +++ b/frame/support/test/tests/decl_storage_ui/config_duplicate.stderr @@ -1,5 +1,5 @@ error: `config()`/`get()` with the same name already defined. - --> $DIR/config_duplicate.rs:29:21 + --> $DIR/config_duplicate.rs:30:21 | -29 | pub Value2 config(value): u32; +30 | pub Value2 config(value): u32; | ^^^^^ diff --git a/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs b/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs index a4e0158d5c5c50733905c8c8795f72416512c878..49897e625186855c41b1848036116df058a9d146 100644 --- a/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/config_get_duplicate.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. pub trait Trait { type Origin; diff --git a/frame/support/test/tests/decl_storage_ui/config_get_duplicate.stderr b/frame/support/test/tests/decl_storage_ui/config_get_duplicate.stderr index 34d040f4e14f19a8fbfc1e904675ec6dacc5e963..02e7d41080339069a9a20224d7bf4baad2ff86e5 100644 --- a/frame/support/test/tests/decl_storage_ui/config_get_duplicate.stderr +++ b/frame/support/test/tests/decl_storage_ui/config_get_duplicate.stderr @@ -1,5 +1,5 @@ error: `config()`/`get()` with the same name already defined. - --> $DIR/config_get_duplicate.rs:29:21 + --> $DIR/config_get_duplicate.rs:30:21 | -29 | pub Value2 config(value): u32; +30 | pub Value2 config(value): u32; | ^^^^^ diff --git a/frame/support/test/tests/decl_storage_ui/get_duplicate.rs b/frame/support/test/tests/decl_storage_ui/get_duplicate.rs index 9edbc25bf9d8327ae36339cb1d595b8713fdb572..2fa78f4d17c562d6aa3817fb3fd58cb4a1d9d6d2 100644 --- a/frame/support/test/tests/decl_storage_ui/get_duplicate.rs +++ b/frame/support/test/tests/decl_storage_ui/get_duplicate.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. pub trait Trait { type Origin; diff --git a/frame/support/test/tests/decl_storage_ui/get_duplicate.stderr b/frame/support/test/tests/decl_storage_ui/get_duplicate.stderr index 130244196f67e03bb40de703fbb127d7bdecbfc8..d9ce420a6f2143ac015c5a9aa33b5153954e1d94 100644 --- a/frame/support/test/tests/decl_storage_ui/get_duplicate.stderr +++ b/frame/support/test/tests/decl_storage_ui/get_duplicate.stderr @@ -1,5 +1,5 @@ error: `config()`/`get()` with the same name already defined. - --> $DIR/get_duplicate.rs:29:21 + --> $DIR/get_duplicate.rs:30:21 | -29 | pub Value2 get(fn value) config(): u32; +30 | pub Value2 get(fn value) config(): u32; | ^^^^^ diff --git a/frame/support/test/tests/final_keys.rs b/frame/support/test/tests/final_keys.rs index ae23c5a64c200af647f0cd4387495742026ccc6c..34da1752da052f5fbf268e270c11c6c9c7852d31 100644 --- a/frame/support/test/tests/final_keys.rs +++ b/frame/support/test/tests/final_keys.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use frame_support::storage::unhashed; use codec::Encode; @@ -52,12 +53,12 @@ mod instance { pub trait Trait: super::no_instance::Trait {} frame_support::decl_module! { - pub struct Module, I: Instantiable = DefaultInstance> + pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin {} } frame_support::decl_storage!{ - trait Store for Module, I: Instantiable = DefaultInstance> + trait Store for Module, I: Instance = DefaultInstance> as FinalKeysSome { pub Value config(value): u32; diff --git a/frame/support/test/tests/genesisconfig.rs b/frame/support/test/tests/genesisconfig.rs index bccffb737476b47fa9b8ebdccfce88139fb9370d..78b841d29501728e8e2eac048e6f2b465f19034b 100644 --- a/frame/support/test/tests/genesisconfig.rs +++ b/frame/support/test/tests/genesisconfig.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. pub trait Trait { type BlockNumber: codec::Codec + codec::EncodeLike + Default; diff --git a/frame/support/test/tests/instance.rs b/frame/support/test/tests/instance.rs index 5cb7fa1972a05f86ff13b3776f080368153431d4..33e8cc1fd6c0fb0c59b8f9b7c08665ddd92e5a46 100644 --- a/frame/support/test/tests/instance.rs +++ b/frame/support/test/tests/instance.rs @@ -1,21 +1,23 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. #![recursion_limit="128"] +use codec::{Codec, EncodeLike, Encode, Decode}; use sp_runtime::{generic, BuildStorage, traits::{BlakeTwo256, Block as _, Verify}}; use frame_support::{ Parameter, traits::Get, parameter_types, @@ -34,7 +36,6 @@ pub trait Currency {} // Test for: // * No default instance -// * Custom InstantiableTrait // * Origin, Inherent, Event mod module1 { use super::*; @@ -43,12 +44,13 @@ mod module1 { type Event: From> + Into<::Event>; type Origin: From>; type SomeParameter: Get; - type GenericType: Default + Clone + codec::Codec + codec::EncodeLike; + type GenericType: Default + Clone + Codec + EncodeLike; } frame_support::decl_module! { - pub struct Module, I: InstantiableThing> for enum Call where + pub struct Module, I: Instance> for enum Call where origin: ::Origin, + system = system, T::BlockNumber: From { fn offchain_worker() {} @@ -64,7 +66,7 @@ mod module1 { } frame_support::decl_storage! { - trait Store for Module, I: InstantiableThing> as Module1 where + trait Store for Module, I: Instance> as Module1 where T::BlockNumber: From + std::fmt::Display { pub Value config(value): T::GenericType; @@ -86,7 +88,7 @@ mod module1 { } } - #[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] + #[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug, Encode, Decode)] pub enum Origin, I> where T::BlockNumber: From { Members(u32), _Phantom(std::marker::PhantomData<(T, I)>), @@ -94,7 +96,7 @@ mod module1 { pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"12345678"; - impl, I: InstantiableThing> ProvideInherent for Module where + impl, I: Instance> ProvideInherent for Module where T::BlockNumber: From { type Call = Call; @@ -127,7 +129,8 @@ mod module2 { frame_support::decl_module! { pub struct Module, I: Instance=DefaultInstance> for enum Call where - origin: ::Origin + origin: ::Origin, + system = system { fn deposit_event() = default; } @@ -147,7 +150,7 @@ mod module2 { } } - #[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] + #[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug, Encode, Decode)] pub enum Origin, I=DefaultInstance> { Members(u32), _Phantom(std::marker::PhantomData<(T, I)>), @@ -232,12 +235,14 @@ pub type BlockNumber = u64; pub type Index = u64; impl system::Trait for Runtime { + type BaseCallFilter= (); type Hash = H256; type Origin = Origin; type BlockNumber = BlockNumber; type AccountId = AccountId; type Event = Event; type ModuleToIndex = (); + type Call = Call; } frame_support::construct_runtime!( diff --git a/frame/support/test/tests/issue2219.rs b/frame/support/test/tests/issue2219.rs index 8d8152a5ad0f35b7b2485acb13d49c56b2075392..7166f202c7325d2aed5a4a27ce1daaf08ad24398 100644 --- a/frame/support/test/tests/issue2219.rs +++ b/frame/support/test/tests/issue2219.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use frame_support::sp_runtime::generic; use frame_support::sp_runtime::traits::{BlakeTwo256, Block as _, Verify}; @@ -157,12 +158,14 @@ pub type Block = generic::Block; pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; impl system::Trait for Runtime { + type BaseCallFilter = (); type Hash = H256; type Origin = Origin; type BlockNumber = BlockNumber; type AccountId = AccountId; type Event = Event; type ModuleToIndex = (); + type Call = Call; } impl module::Trait for Runtime {} diff --git a/frame/support/test/tests/reserved_keyword.rs b/frame/support/test/tests/reserved_keyword.rs index 6f2bbb47474152b451d7cfe7667a099a02c50e65..382b2e498741fd6740dc7b1c94537706ce13ffac 100644 --- a/frame/support/test/tests/reserved_keyword.rs +++ b/frame/support/test/tests/reserved_keyword.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. #[rustversion::attr(not(stable), ignore)] #[test] diff --git a/frame/support/test/tests/storage_transaction.rs b/frame/support/test/tests/storage_transaction.rs new file mode 100644 index 0000000000000000000000000000000000000000..a9711ec267e54fa19c3dfd52d984c228685711e1 --- /dev/null +++ b/frame/support/test/tests/storage_transaction.rs @@ -0,0 +1,212 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use codec::{Encode, Decode, EncodeLike}; +use frame_support::{ + assert_ok, assert_noop, dispatch::{DispatchError, DispatchResult}, transactional, StorageMap, StorageValue, + storage::{with_transaction, TransactionOutcome::*}, +}; +use sp_io::TestExternalities; +use sp_std::result; + +pub trait Trait { + type Origin; + type BlockNumber: Encode + Decode + EncodeLike + Default + Clone; +} + +frame_support::decl_module! { + pub struct Module for enum Call where origin: T::Origin { + #[weight = 0] + #[transactional] + fn value_commits(_origin, v: u32) { + Value::set(v); + } + + #[weight = 0] + #[transactional] + fn value_rollbacks(_origin, v: u32) -> DispatchResult { + Value::set(v); + Err(DispatchError::Other("nah")) + } + } +} + +frame_support::decl_storage!{ + trait Store for Module as StorageTransactions { + pub Value: u32; + pub Map: map hasher(twox_64_concat) String => u32; + } +} + +struct Runtime; +impl Trait for Runtime { + type Origin = u32; + type BlockNumber = u32; +} + +#[test] +fn storage_transaction_basic_commit() { + TestExternalities::default().execute_with(|| { + + assert_eq!(Value::get(), 0); + assert!(!Map::contains_key("val0")); + + with_transaction(|| { + Value::set(99); + Map::insert("val0", 99); + assert_eq!(Value::get(), 99); + assert_eq!(Map::get("val0"), 99); + Commit(()) + }); + + assert_eq!(Value::get(), 99); + assert_eq!(Map::get("val0"), 99); + }); +} + +#[test] +fn storage_transaction_basic_rollback() { + TestExternalities::default().execute_with(|| { + + assert_eq!(Value::get(), 0); + assert_eq!(Map::get("val0"), 0); + + with_transaction(|| { + Value::set(99); + Map::insert("val0", 99); + assert_eq!(Value::get(), 99); + assert_eq!(Map::get("val0"), 99); + Rollback(()) + }); + + assert_eq!(Value::get(), 0); + assert_eq!(Map::get("val0"), 0); + }); +} + +#[test] +fn storage_transaction_rollback_then_commit() { + TestExternalities::default().execute_with(|| { + Value::set(1); + Map::insert("val1", 1); + + with_transaction(|| { + Value::set(2); + Map::insert("val1", 2); + Map::insert("val2", 2); + + with_transaction(|| { + Value::set(3); + Map::insert("val1", 3); + Map::insert("val2", 3); + Map::insert("val3", 3); + + assert_eq!(Value::get(), 3); + assert_eq!(Map::get("val1"), 3); + assert_eq!(Map::get("val2"), 3); + assert_eq!(Map::get("val3"), 3); + + Rollback(()) + }); + + assert_eq!(Value::get(), 2); + assert_eq!(Map::get("val1"), 2); + assert_eq!(Map::get("val2"), 2); + assert_eq!(Map::get("val3"), 0); + + Commit(()) + }); + + assert_eq!(Value::get(), 2); + assert_eq!(Map::get("val1"), 2); + assert_eq!(Map::get("val2"), 2); + assert_eq!(Map::get("val3"), 0); + }); +} + +#[test] +fn storage_transaction_commit_then_rollback() { + TestExternalities::default().execute_with(|| { + Value::set(1); + Map::insert("val1", 1); + + with_transaction(|| { + Value::set(2); + Map::insert("val1", 2); + Map::insert("val2", 2); + + with_transaction(|| { + Value::set(3); + Map::insert("val1", 3); + Map::insert("val2", 3); + Map::insert("val3", 3); + + assert_eq!(Value::get(), 3); + assert_eq!(Map::get("val1"), 3); + assert_eq!(Map::get("val2"), 3); + assert_eq!(Map::get("val3"), 3); + + Commit(()) + }); + + assert_eq!(Value::get(), 3); + assert_eq!(Map::get("val1"), 3); + assert_eq!(Map::get("val2"), 3); + assert_eq!(Map::get("val3"), 3); + + Rollback(()) + }); + + assert_eq!(Value::get(), 1); + assert_eq!(Map::get("val1"), 1); + assert_eq!(Map::get("val2"), 0); + assert_eq!(Map::get("val3"), 0); + }); +} + +#[test] +fn transactional_annotation() { + #[transactional] + fn value_commits(v: u32) -> result::Result { + Value::set(v); + Ok(v) + } + + #[transactional] + fn value_rollbacks(v: u32) -> result::Result { + Value::set(v); + Err("nah") + } + + TestExternalities::default().execute_with(|| { + assert_ok!(value_commits(2), 2); + assert_eq!(Value::get(), 2); + + assert_noop!(value_rollbacks(3), "nah"); + }); +} + +#[test] +fn transactional_annotation_in_decl_module() { + TestExternalities::default().execute_with(|| { + let origin = 0; + assert_ok!(>::value_commits(origin, 2)); + assert_eq!(Value::get(), 2); + + assert_noop!(>::value_rollbacks(origin, 3), "nah"); + }); +} diff --git a/frame/support/test/tests/system.rs b/frame/support/test/tests/system.rs index c7f60117bc526ec4e96745c9f74379e913b43316..8ca2e97789d549c85f6ce013f1550f8d121eef41 100644 --- a/frame/support/test/tests/system.rs +++ b/frame/support/test/tests/system.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use frame_support::codec::{Encode, Decode, EncodeLike}; @@ -20,15 +21,17 @@ pub trait Trait: 'static + Eq + Clone { type Origin: Into, Self::Origin>> + From>; + type BaseCallFilter: frame_support::traits::Filter; type BlockNumber: Decode + Encode + EncodeLike + Clone + Default; type Hash; type AccountId: Encode + EncodeLike + Decode; + type Call; type Event: From>; type ModuleToIndex: frame_support::traits::ModuleToIndex; } frame_support::decl_module! { - pub struct Module for enum Call where origin: T::Origin {} + pub struct Module for enum Call where origin: T::Origin, {} } impl Module { @@ -54,7 +57,7 @@ frame_support::decl_error! { } /// Origin for the system module. -#[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug, Encode, Decode)] pub enum RawOrigin { Root, Signed(AccountId), diff --git a/frame/system/Cargo.toml b/frame/system/Cargo.toml index 0e90009a16690799ed5e3a65049ef1c47267dc32..a3dbad0cb84b46d30b2a99ae562c709470276cda 100644 --- a/frame/system/Cargo.toml +++ b/frame/system/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-system" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME system module" @@ -13,19 +13,19 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { path = "../../primitives/io", default-features = false, version = "2.0.0-dev"} -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-version = { version = "2.0.0-dev", default-features = false, path = "../../primitives/version" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io", default-features = false } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-version = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/version" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -criterion = "0.2.11" -sp-externalities = { version = "0.8.0-dev", path = "../../primitives/externalities" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } +criterion = "0.3.3" +sp-externalities = { version = "0.8.0-rc6", path = "../../primitives/externalities" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client" } [features] default = ["std"] diff --git a/frame/system/README.md b/frame/system/README.md new file mode 100644 index 0000000000000000000000000000000000000000..46e48b6d52762741d6735f627c7da88d72676c10 --- /dev/null +++ b/frame/system/README.md @@ -0,0 +1,75 @@ +# System Module + +The System module provides low-level access to core types and cross-cutting utilities. +It acts as the base layer for other pallets to interact with the Substrate framework components. + +- [`system::Trait`](./trait.Trait.html) + +## Overview + +The System module defines the core data types used in a Substrate runtime. +It also provides several utility functions (see [`Module`](./struct.Module.html)) for other FRAME pallets. + +In addition, it manages the storage items for extrinsics data, indexes, event records, and digest items, +among other things that support the execution of the current block. + +It also handles low-level tasks like depositing logs, basic set up and take down of +temporary storage entries, and access to previous block hashes. + +## Interface + +### Dispatchable Functions + +The System module does not implement any dispatchable functions. + +### Public Functions + +See the [`Module`](./struct.Module.html) struct for details of publicly available functions. + +### Signed Extensions + +The System module defines the following extensions: + + - [`CheckWeight`]: Checks the weight and length of the block and ensure that it does not + exceed the limits. + - [`CheckNonce`]: Checks the nonce of the transaction. Contains a single payload of type + `T::Index`. + - [`CheckEra`]: Checks the era of the transaction. Contains a single payload of type `Era`. + - [`CheckGenesis`]: Checks the provided genesis hash of the transaction. Must be a part of the + signed payload of the transaction. + - [`CheckSpecVersion`]: Checks that the runtime version is the same as the one used to sign the + transaction. + - [`CheckTxVersion`]: Checks that the transaction version is the same as the one used to sign the + transaction. + +Lookup the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed +extensions included in a chain. + +## Usage + +### Prerequisites + +Import the System module and derive your module's configuration trait from the system trait. + +### Example - Get extrinsic count and parent hash for the current block + +```rust +use frame_support::{decl_module, dispatch}; +use frame_system::{self as system, ensure_signed}; + +pub trait Trait: system::Trait {} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + #[weight = 0] + pub fn system_module_example(origin) -> dispatch::DispatchResult { + let _sender = ensure_signed(origin)?; + let _extrinsic_count = >::extrinsic_count(); + let _parent_hash = >::parent_hash(); + Ok(()) + } + } +} +``` + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index 6594862e5c6d56647620b14218cc4e05d9850764..1b64b813e59101f8b187697f7c25082be764f585 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use criterion::{Criterion, criterion_group, criterion_main, black_box}; use frame_system as system; @@ -60,6 +61,7 @@ frame_support::parameter_types! { #[derive(Clone, Eq, PartialEq)] pub struct Runtime; impl system::Trait for Runtime { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -75,6 +77,7 @@ impl system::Trait for Runtime { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -82,6 +85,7 @@ impl system::Trait for Runtime { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl module::Trait for Runtime { diff --git a/frame/system/benchmarking/Cargo.toml b/frame/system/benchmarking/Cargo.toml index 0518bd705dc2658a96e94b1f7043832c1d1cf439..c0b5366b7a4cca004895ee996a16d965d93004df 100644 --- a/frame/system/benchmarking/Cargo.toml +++ b/frame/system/benchmarking/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-system-benchmarking" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME System benchmarking" @@ -12,17 +12,17 @@ description = "FRAME System benchmarking" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/runtime" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../../benchmarking" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../../system" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../../support" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../../primitives/core" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/runtime" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../../benchmarking" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../../system" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../../support" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../../primitives/core" } [dev-dependencies] serde = { version = "1.0.101" } -sp-io ={ path = "../../../primitives/io", version = "2.0.0-dev"} +sp-io ={ version = "2.0.0-rc6", path = "../../../primitives/io" } [features] default = ["std"] diff --git a/frame/system/benchmarking/README.md b/frame/system/benchmarking/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9718db58b37e9ae1c81b5b627fe27e51129cf418 --- /dev/null +++ b/frame/system/benchmarking/README.md @@ -0,0 +1 @@ +License: Apache-2.0 \ No newline at end of file diff --git a/frame/system/benchmarking/src/lib.rs b/frame/system/benchmarking/src/lib.rs index 22e6dba842741fc0deccb8230605af74bd8447e4..653d9536f17972925908290f97ee4d59ee6d6715 100644 --- a/frame/system/benchmarking/src/lib.rs +++ b/frame/system/benchmarking/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // Benchmarks for Utility Pallet @@ -23,14 +24,13 @@ use sp_std::vec; use sp_std::prelude::*; use sp_core::{ChangesTrieConfiguration, storage::well_known_keys}; use sp_runtime::traits::Hash; -use frame_benchmarking::{benchmarks, account}; +use frame_benchmarking::{benchmarks, whitelisted_caller}; +use frame_support::traits::Get; use frame_support::storage::{self, StorageMap}; use frame_system::{Module as System, Call, RawOrigin, DigestItemOf, AccountInfo}; mod mock; -const SEED: u32 = 0; - pub struct Module(System); pub trait Trait: frame_system::Trait {} @@ -38,29 +38,26 @@ benchmarks! { _ { } remark { - // # of Bytes - let b in 0 .. 16_384; + let b in 0 .. T::MaximumBlockLength::get(); let remark_message = vec![1; b as usize]; - let caller = account("caller", 0, SEED); + let caller = whitelisted_caller(); }: _(RawOrigin::Signed(caller), remark_message) set_heap_pages { - // Heap page size - let i in 0 .. u32::max_value(); - }: _(RawOrigin::Root, i.into()) + }: _(RawOrigin::Root, Default::default()) // `set_code` was not benchmarked because it is pretty hard to come up with a real // Wasm runtime to test the upgrade with. But this is okay because we will make // `set_code` take a full block anyway. + #[extra] set_code_without_checks { - // Version number - let b in 0 .. 16_384; - let code = vec![1; b as usize]; + // Assume Wasm ~4MB + let code = vec![1; 4_000_000 as usize]; }: _(RawOrigin::Root, code) verify { let current_code = storage::unhashed::get_raw(well_known_keys::CODE).ok_or("Code not stored.")?; - assert_eq!(current_code.len(), b as usize); + assert_eq!(current_code.len(), 4_000_000 as usize); } set_changes_trie_config { @@ -140,16 +137,15 @@ benchmarks! { } suicide { - let n in 1 .. 1000; - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); let account_info = AccountInfo:: { - nonce: n.into(), + nonce: 1337.into(), refcount: 0, data: T::AccountData::default() }; frame_system::Account::::insert(&caller, account_info); let new_account_info = System::::account(caller.clone()); - assert_eq!(new_account_info.nonce, n.into()); + assert_eq!(new_account_info.nonce, 1337.into()); }: _(RawOrigin::Signed(caller.clone())) verify { let account_info = System::::account(&caller); diff --git a/frame/system/benchmarking/src/mock.rs b/frame/system/benchmarking/src/mock.rs index 1e72665c1557910f7eaccc35c3f5237170177c95..050fd40afe1389576c630570a919e37aeccda5a6 100644 --- a/frame/system/benchmarking/src/mock.rs +++ b/frame/system/benchmarking/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Mock file for system benchmarking. @@ -29,7 +30,7 @@ type AccountIndex = u32; type BlockNumber = u64; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } #[derive(Debug, codec::Encode, codec::Decode)] @@ -50,6 +51,7 @@ impl Dispatchable for Call { pub struct Test; impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = AccountIndex; type BlockNumber = BlockNumber; @@ -65,6 +67,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = (); type AvailableBlockRatio = (); type MaximumBlockLength = (); type Version = (); @@ -72,6 +75,7 @@ impl frame_system::Trait for Test { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl crate::Trait for Test {} diff --git a/frame/system/rpc/runtime-api/Cargo.toml b/frame/system/rpc/runtime-api/Cargo.toml index 2097e112663f51190b85210df9a29c9d3730f536..3c6028b4f7a2b9f4942e81865922ecf3ab00485e 100644 --- a/frame/system/rpc/runtime-api/Cargo.toml +++ b/frame/system/rpc/runtime-api/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-system-rpc-runtime-api" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Runtime API definition required by System RPC extensions." @@ -12,8 +12,8 @@ description = "Runtime API definition required by System RPC extensions." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/api" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../../../../primitives/api" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } [features] default = ["std"] diff --git a/frame/system/rpc/runtime-api/README.md b/frame/system/rpc/runtime-api/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ab46c22a8be3345b13dc4674f3234cb8f511851b --- /dev/null +++ b/frame/system/rpc/runtime-api/README.md @@ -0,0 +1,7 @@ +Runtime API definition required by System RPC extensions. + +This API should be imported and implemented by the runtime, +of a node that wants to use the custom RPC extension +adding System access methods. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/system/rpc/runtime-api/src/lib.rs b/frame/system/rpc/runtime-api/src/lib.rs index 3b05bd162468e10e9a1d59712c2685332a5675bf..0ead94aabe016b739c4c8812618b1248d3116723 100644 --- a/frame/system/rpc/runtime-api/src/lib.rs +++ b/frame/system/rpc/runtime-api/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Runtime API definition required by System RPC extensions. //! diff --git a/frame/system/src/accounts.scale b/frame/system/src/accounts.scale deleted file mode 100644 index bfd7e6277f20c53ceb1d664235bb6af18ec538ed..0000000000000000000000000000000000000000 Binary files a/frame/system/src/accounts.scale and /dev/null differ diff --git a/frame/system/src/default_weights.rs b/frame/system/src/default_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..8a84cb0b7903a4190ea49c2ac3be81dac3892018 --- /dev/null +++ b/frame/system/src/default_weights.rs @@ -0,0 +1,57 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +#![allow(unused_parens)] + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +impl crate::WeightInfo for () { + // WARNING! Some components were not used: ["b"] + fn remark() -> Weight { + (1305000 as Weight) + } + fn set_heap_pages() -> Weight { + (2023000 as Weight) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + // WARNING! Some components were not used: ["d"] + fn set_changes_trie_config() -> Weight { + (10026000 as Weight) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(2 as Weight)) + } + fn set_storage(i: u32, ) -> Weight { + (0 as Weight) + .saturating_add((656000 as Weight).saturating_mul(i as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(i as Weight))) + } + fn kill_storage(i: u32, ) -> Weight { + (4327000 as Weight) + .saturating_add((478000 as Weight).saturating_mul(i as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(i as Weight))) + } + fn kill_prefix(p: u32, ) -> Weight { + (8349000 as Weight) + .saturating_add((838000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight))) + } + fn suicide() -> Weight { + (29247000 as Weight) + } +} diff --git a/frame/system/src/extensions/check_genesis.rs b/frame/system/src/extensions/check_genesis.rs new file mode 100644 index 0000000000000000000000000000000000000000..d0a346519ca23b8661cd92285ec2d72e5753b7a9 --- /dev/null +++ b/frame/system/src/extensions/check_genesis.rs @@ -0,0 +1,58 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use codec::{Encode, Decode}; +use crate::{Trait, Module}; +use sp_runtime::{ + traits::{SignedExtension, Zero}, + transaction_validity::TransactionValidityError, +}; + +/// Genesis hash check to provide replay protection between different networks. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct CheckGenesis(sp_std::marker::PhantomData); + +impl sp_std::fmt::Debug for CheckGenesis { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "CheckGenesis") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +impl CheckGenesis { + /// Creates new `SignedExtension` to check genesis hash. + pub fn new() -> Self { + Self(sp_std::marker::PhantomData) + } +} + +impl SignedExtension for CheckGenesis { + type AccountId = T::AccountId; + type Call = ::Call; + type AdditionalSigned = T::Hash; + type Pre = (); + const IDENTIFIER: &'static str = "CheckGenesis"; + + fn additional_signed(&self) -> Result { + Ok(>::block_hash(T::BlockNumber::zero())) + } +} diff --git a/frame/system/src/extensions/check_mortality.rs b/frame/system/src/extensions/check_mortality.rs new file mode 100644 index 0000000000000000000000000000000000000000..7e3f65d0324d705fd5f6b1ce460b249917907ff4 --- /dev/null +++ b/frame/system/src/extensions/check_mortality.rs @@ -0,0 +1,123 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use codec::{Encode, Decode}; +use crate::{Trait, Module, BlockHash}; +use frame_support::StorageMap; +use sp_runtime::{ + generic::Era, + traits::{SignedExtension, DispatchInfoOf, SaturatedConversion}, + transaction_validity::{ + ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, + }, +}; + +/// Check for transaction mortality. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct CheckMortality(Era, sp_std::marker::PhantomData); + +impl CheckMortality { + /// utility constructor. Used only in client/factory code. + pub fn from(era: Era) -> Self { + Self(era, sp_std::marker::PhantomData) + } +} + +impl sp_std::fmt::Debug for CheckMortality { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "CheckMortality({:?})", self.0) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +impl SignedExtension for CheckMortality { + type AccountId = T::AccountId; + type Call = T::Call; + type AdditionalSigned = T::Hash; + type Pre = (); + const IDENTIFIER: &'static str = "CheckMortality"; + + fn validate( + &self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> TransactionValidity { + let current_u64 = >::block_number().saturated_into::(); + let valid_till = self.0.death(current_u64); + Ok(ValidTransaction { + longevity: valid_till.saturating_sub(current_u64), + ..Default::default() + }) + } + + fn additional_signed(&self) -> Result { + let current_u64 = >::block_number().saturated_into::(); + let n = self.0.birth(current_u64).saturated_into::(); + if !>::contains_key(n) { + Err(InvalidTransaction::AncientBirthBlock.into()) + } else { + Ok(>::block_hash(n)) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::{Test, new_test_ext, System, CALL}; + use frame_support::weights::{DispatchClass, DispatchInfo, Pays}; + use sp_core::H256; + + #[test] + fn signed_ext_check_era_should_work() { + new_test_ext().execute_with(|| { + // future + assert_eq!( + CheckMortality::::from(Era::mortal(4, 2)).additional_signed().err().unwrap(), + InvalidTransaction::AncientBirthBlock.into(), + ); + + // correct + System::set_block_number(13); + >::insert(12, H256::repeat_byte(1)); + assert!(CheckMortality::::from(Era::mortal(4, 12)).additional_signed().is_ok()); + }) + } + + #[test] + fn signed_ext_check_era_should_change_longevity() { + new_test_ext().execute_with(|| { + let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes }; + let len = 0_usize; + let ext = ( + crate::CheckWeight::::default(), + CheckMortality::::from(Era::mortal(16, 256)), + ); + System::set_block_number(17); + >::insert(16, H256::repeat_byte(1)); + + assert_eq!(ext.validate(&1, CALL, &normal, len).unwrap().longevity, 15); + }) + } +} diff --git a/frame/system/src/extensions/check_nonce.rs b/frame/system/src/extensions/check_nonce.rs new file mode 100644 index 0000000000000000000000000000000000000000..1af3a1210aaf417c96019f03b43944184d435e22 --- /dev/null +++ b/frame/system/src/extensions/check_nonce.rs @@ -0,0 +1,145 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use codec::{Encode, Decode}; +use crate::Trait; +use frame_support::{ + weights::DispatchInfo, + StorageMap, +}; +use sp_runtime::{ + traits::{SignedExtension, DispatchInfoOf, Dispatchable, One}, + transaction_validity::{ + ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, + TransactionLongevity, TransactionPriority, + }, +}; +use sp_std::vec; + +/// Nonce check and increment to give replay protection for transactions. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct CheckNonce(#[codec(compact)] T::Index); + +impl CheckNonce { + /// utility constructor. Used only in client/factory code. + pub fn from(nonce: T::Index) -> Self { + Self(nonce) + } +} + +impl sp_std::fmt::Debug for CheckNonce { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "CheckNonce({})", self.0) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +impl SignedExtension for CheckNonce where + T::Call: Dispatchable +{ + type AccountId = T::AccountId; + type Call = T::Call; + type AdditionalSigned = (); + type Pre = (); + const IDENTIFIER: &'static str = "CheckNonce"; + + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } + + fn pre_dispatch( + self, + who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> Result<(), TransactionValidityError> { + let mut account = crate::Account::::get(who); + if self.0 != account.nonce { + return Err( + if self.0 < account.nonce { + InvalidTransaction::Stale + } else { + InvalidTransaction::Future + }.into() + ) + } + account.nonce += T::Index::one(); + crate::Account::::insert(who, account); + Ok(()) + } + + fn validate( + &self, + who: &Self::AccountId, + _call: &Self::Call, + info: &DispatchInfoOf, + _len: usize, + ) -> TransactionValidity { + // check index + let account = crate::Account::::get(who); + if self.0 < account.nonce { + return InvalidTransaction::Stale.into() + } + + let provides = vec![Encode::encode(&(who, self.0))]; + let requires = if account.nonce < self.0 { + vec![Encode::encode(&(who, self.0 - One::one()))] + } else { + vec![] + }; + + Ok(ValidTransaction { + priority: info.weight as TransactionPriority, + requires, + provides, + longevity: TransactionLongevity::max_value(), + propagate: true, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::{Test, new_test_ext, CALL}; + + #[test] + fn signed_ext_check_nonce_works() { + new_test_ext().execute_with(|| { + crate::Account::::insert(1, crate::AccountInfo { + nonce: 1, + refcount: 0, + data: 0, + }); + let info = DispatchInfo::default(); + let len = 0_usize; + // stale + assert!(CheckNonce::(0).validate(&1, CALL, &info, len).is_err()); + assert!(CheckNonce::(0).pre_dispatch(&1, CALL, &info, len).is_err()); + // correct + assert!(CheckNonce::(1).validate(&1, CALL, &info, len).is_ok()); + assert!(CheckNonce::(1).pre_dispatch(&1, CALL, &info, len).is_ok()); + // future + assert!(CheckNonce::(5).validate(&1, CALL, &info, len).is_ok()); + assert!(CheckNonce::(5).pre_dispatch(&1, CALL, &info, len).is_err()); + }) + } +} diff --git a/frame/system/src/extensions/check_spec_version.rs b/frame/system/src/extensions/check_spec_version.rs new file mode 100644 index 0000000000000000000000000000000000000000..8dc4d8d9ceddc52893795cda924366bdec44975f --- /dev/null +++ b/frame/system/src/extensions/check_spec_version.rs @@ -0,0 +1,58 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use crate::{Trait, Module}; +use codec::{Encode, Decode}; +use sp_runtime::{ + traits::SignedExtension, + transaction_validity::TransactionValidityError, +}; + +/// Ensure the runtime version registered in the transaction is the same as at present. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct CheckSpecVersion(sp_std::marker::PhantomData); + +impl sp_std::fmt::Debug for CheckSpecVersion { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "CheckSpecVersion") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +impl CheckSpecVersion { + /// Create new `SignedExtension` to check runtime version. + pub fn new() -> Self { + Self(sp_std::marker::PhantomData) + } +} + +impl SignedExtension for CheckSpecVersion { + type AccountId = T::AccountId; + type Call = ::Call; + type AdditionalSigned = u32; + type Pre = (); + const IDENTIFIER: &'static str = "CheckSpecVersion"; + + fn additional_signed(&self) -> Result { + Ok(>::runtime_version().spec_version) + } +} diff --git a/frame/system/src/extensions/check_tx_version.rs b/frame/system/src/extensions/check_tx_version.rs new file mode 100644 index 0000000000000000000000000000000000000000..ee6f3349365b9b9b21801eabd91ef32863a45007 --- /dev/null +++ b/frame/system/src/extensions/check_tx_version.rs @@ -0,0 +1,58 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use crate::{Trait, Module}; +use codec::{Encode, Decode}; +use sp_runtime::{ + traits::SignedExtension, + transaction_validity::TransactionValidityError, +}; + +/// Ensure the transaction version registered in the transaction is the same as at present. +#[derive(Encode, Decode, Clone, Eq, PartialEq)] +pub struct CheckTxVersion(sp_std::marker::PhantomData); + +impl sp_std::fmt::Debug for CheckTxVersion { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "CheckTxVersion") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +impl CheckTxVersion { + /// Create new `SignedExtension` to check transaction version. + pub fn new() -> Self { + Self(sp_std::marker::PhantomData) + } +} + +impl SignedExtension for CheckTxVersion { + type AccountId = T::AccountId; + type Call = ::Call; + type AdditionalSigned = u32; + type Pre = (); + const IDENTIFIER: &'static str = "CheckTxVersion"; + + fn additional_signed(&self) -> Result { + Ok(>::runtime_version().transaction_version) + } +} diff --git a/frame/system/src/extensions/check_weight.rs b/frame/system/src/extensions/check_weight.rs new file mode 100644 index 0000000000000000000000000000000000000000..1395aa87efbcfb54a1a9e9e8422aeb222318821c --- /dev/null +++ b/frame/system/src/extensions/check_weight.rs @@ -0,0 +1,650 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use crate::{Trait, Module}; +use codec::{Encode, Decode}; +use sp_runtime::{ + traits::{SignedExtension, DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Printable}, + transaction_validity::{ + ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, + TransactionPriority, + }, + Perbill, DispatchResult, +}; +use frame_support::{ + traits::{Get}, + weights::{PostDispatchInfo, DispatchInfo, DispatchClass}, + StorageValue, +}; + +/// Block resource (weight) limit check. +#[derive(Encode, Decode, Clone, Eq, PartialEq, Default)] +pub struct CheckWeight(sp_std::marker::PhantomData); + +impl CheckWeight where + T::Call: Dispatchable +{ + /// Get the quota ratio of each dispatch class type. This indicates that all operational and mandatory + /// dispatches can use the full capacity of any resource, while user-triggered ones can consume + /// a portion. + fn get_dispatch_limit_ratio(class: DispatchClass) -> Perbill { + match class { + DispatchClass::Operational | DispatchClass::Mandatory + => ::one(), + DispatchClass::Normal => T::AvailableBlockRatio::get(), + } + } + + /// Checks if the current extrinsic does not exceed `MaximumExtrinsicWeight` limit. + fn check_extrinsic_weight( + info: &DispatchInfoOf, + ) -> Result<(), TransactionValidityError> { + match info.class { + // Mandatory transactions are included in a block unconditionally, so + // we don't verify weight. + DispatchClass::Mandatory => Ok(()), + // Normal transactions must not exceed `MaximumExtrinsicWeight`. + DispatchClass::Normal => { + let maximum_weight = T::MaximumExtrinsicWeight::get(); + let extrinsic_weight = info.weight.saturating_add(T::ExtrinsicBaseWeight::get()); + if extrinsic_weight > maximum_weight { + Err(InvalidTransaction::ExhaustsResources.into()) + } else { + Ok(()) + } + }, + // For operational transactions we make sure it doesn't exceed + // the space alloted for `Operational` class. + DispatchClass::Operational => { + let maximum_weight = T::MaximumBlockWeight::get(); + let operational_limit = + Self::get_dispatch_limit_ratio(DispatchClass::Operational) * maximum_weight; + let operational_limit = + operational_limit.saturating_sub(T::BlockExecutionWeight::get()); + let extrinsic_weight = info.weight.saturating_add(T::ExtrinsicBaseWeight::get()); + if extrinsic_weight > operational_limit { + Err(InvalidTransaction::ExhaustsResources.into()) + } else { + Ok(()) + } + }, + } + } + + /// Checks if the current extrinsic can fit into the block with respect to block weight limits. + /// + /// Upon successes, it returns the new block weight as a `Result`. + fn check_block_weight( + info: &DispatchInfoOf, + ) -> Result { + let maximum_weight = T::MaximumBlockWeight::get(); + let mut all_weight = Module::::block_weight(); + match info.class { + // If we have a dispatch that must be included in the block, it ignores all the limits. + DispatchClass::Mandatory => { + let extrinsic_weight = info.weight.saturating_add(T::ExtrinsicBaseWeight::get()); + all_weight.add(extrinsic_weight, DispatchClass::Mandatory); + Ok(all_weight) + }, + // If we have a normal dispatch, we follow all the normal rules and limits. + DispatchClass::Normal => { + let normal_limit = Self::get_dispatch_limit_ratio(DispatchClass::Normal) * maximum_weight; + let extrinsic_weight = info.weight.checked_add(T::ExtrinsicBaseWeight::get()) + .ok_or(InvalidTransaction::ExhaustsResources)?; + all_weight.checked_add(extrinsic_weight, DispatchClass::Normal) + .map_err(|_| InvalidTransaction::ExhaustsResources)?; + if all_weight.get(DispatchClass::Normal) > normal_limit { + Err(InvalidTransaction::ExhaustsResources.into()) + } else { + Ok(all_weight) + } + }, + // If we have an operational dispatch, allow it if we have not used our full + // "operational space" (independent of existing fullness). + DispatchClass::Operational => { + let operational_limit = Self::get_dispatch_limit_ratio(DispatchClass::Operational) * maximum_weight; + let normal_limit = Self::get_dispatch_limit_ratio(DispatchClass::Normal) * maximum_weight; + let operational_space = operational_limit.saturating_sub(normal_limit); + + let extrinsic_weight = info.weight.checked_add(T::ExtrinsicBaseWeight::get()) + .ok_or(InvalidTransaction::ExhaustsResources)?; + all_weight.checked_add(extrinsic_weight, DispatchClass::Operational) + .map_err(|_| InvalidTransaction::ExhaustsResources)?; + + // If it would fit in normally, its okay + if all_weight.total() <= maximum_weight || + // If we have not used our operational space + all_weight.get(DispatchClass::Operational) <= operational_space { + Ok(all_weight) + } else { + Err(InvalidTransaction::ExhaustsResources.into()) + } + } + } + } + + /// Checks if the current extrinsic can fit into the block with respect to block length limits. + /// + /// Upon successes, it returns the new block length as a `Result`. + fn check_block_length( + info: &DispatchInfoOf, + len: usize, + ) -> Result { + let current_len = Module::::all_extrinsics_len(); + let maximum_len = T::MaximumBlockLength::get(); + let limit = Self::get_dispatch_limit_ratio(info.class) * maximum_len; + let added_len = len as u32; + let next_len = current_len.saturating_add(added_len); + if next_len > limit { + Err(InvalidTransaction::ExhaustsResources.into()) + } else { + Ok(next_len) + } + } + + /// get the priority of an extrinsic denoted by `info`. + fn get_priority(info: &DispatchInfoOf) -> TransactionPriority { + match info.class { + DispatchClass::Normal => info.weight.into(), + // Don't use up the whole priority space, to allow things like `tip` + // to be taken into account as well. + DispatchClass::Operational => TransactionPriority::max_value() / 2, + // Mandatory extrinsics are only for inherents; never transactions. + DispatchClass::Mandatory => TransactionPriority::min_value(), + } + } + + /// Creates new `SignedExtension` to check weight of the extrinsic. + pub fn new() -> Self { + Self(Default::default()) + } + + /// Do the pre-dispatch checks. This can be applied to both signed and unsigned. + /// + /// It checks and notes the new weight and length. + fn do_pre_dispatch( + info: &DispatchInfoOf, + len: usize, + ) -> Result<(), TransactionValidityError> { + let next_len = Self::check_block_length(info, len)?; + let next_weight = Self::check_block_weight(info)?; + Self::check_extrinsic_weight(info)?; + + crate::AllExtrinsicsLen::put(next_len); + crate::BlockWeight::put(next_weight); + Ok(()) + } + + /// Do the validate checks. This can be applied to both signed and unsigned. + /// + /// It only checks that the block weight and length limit will not exceed. + fn do_validate( + info: &DispatchInfoOf, + len: usize, + ) -> TransactionValidity { + // ignore the next length. If they return `Ok`, then it is below the limit. + let _ = Self::check_block_length(info, len)?; + // during validation we skip block limit check. Since the `validate_transaction` + // call runs on an empty block anyway, by this we prevent `on_initialize` weight + // consumption from causing false negatives. + Self::check_extrinsic_weight(info)?; + + Ok(ValidTransaction { priority: Self::get_priority(info), ..Default::default() }) + } +} + +impl SignedExtension for CheckWeight where + T::Call: Dispatchable +{ + type AccountId = T::AccountId; + type Call = T::Call; + type AdditionalSigned = (); + type Pre = (); + const IDENTIFIER: &'static str = "CheckWeight"; + + fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } + + fn pre_dispatch( + self, + _who: &Self::AccountId, + _call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result<(), TransactionValidityError> { + if info.class == DispatchClass::Mandatory { + Err(InvalidTransaction::MandatoryDispatch)? + } + Self::do_pre_dispatch(info, len) + } + + fn validate( + &self, + _who: &Self::AccountId, + _call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> TransactionValidity { + if info.class == DispatchClass::Mandatory { + Err(InvalidTransaction::MandatoryDispatch)? + } + Self::do_validate(info, len) + } + + fn pre_dispatch_unsigned( + _call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> Result<(), TransactionValidityError> { + Self::do_pre_dispatch(info, len) + } + + fn validate_unsigned( + _call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> TransactionValidity { + Self::do_validate(info, len) + } + + fn post_dispatch( + _pre: Self::Pre, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, + _len: usize, + result: &DispatchResult, + ) -> Result<(), TransactionValidityError> { + // Since mandatory dispatched do not get validated for being overweight, we are sensitive + // to them actually being useful. Block producers are thus not allowed to include mandatory + // extrinsics that result in error. + if let (DispatchClass::Mandatory, Err(e)) = (info.class, result) { + "Bad mandantory".print(); + e.print(); + + Err(InvalidTransaction::BadMandatory)? + } + + let unspent = post_info.calc_unspent(info); + if unspent > 0 { + crate::BlockWeight::mutate(|current_weight| { + current_weight.sub(unspent, info.class); + }) + } + + Ok(()) + } +} + +impl sp_std::fmt::Debug for CheckWeight { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "CheckWeight") + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{BlockWeight, AllExtrinsicsLen}; + use crate::mock::{Test, CALL, new_test_ext, System}; + use sp_std::marker::PhantomData; + use frame_support::{assert_ok, assert_noop}; + use frame_support::weights::{Weight, Pays}; + + fn normal_weight_limit() -> Weight { + ::AvailableBlockRatio::get() * ::MaximumBlockWeight::get() + } + + fn normal_length_limit() -> u32 { + ::AvailableBlockRatio::get() * ::MaximumBlockLength::get() + } + + #[test] + fn mandatory_extrinsic_doesnt_care_about_limits() { + fn check(call: impl FnOnce(&DispatchInfo, usize)) { + new_test_ext().execute_with(|| { + let max = DispatchInfo { + weight: Weight::max_value(), + class: DispatchClass::Mandatory, + ..Default::default() + }; + let len = 0_usize; + + call(&max, len); + }); + } + + check(|max, len| { + assert_ok!(CheckWeight::::do_pre_dispatch(max, len)); + assert_eq!(System::block_weight().total(), Weight::max_value()); + assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); + }); + check(|max, len| { + assert_ok!(CheckWeight::::do_validate(max, len)); + }); + } + + #[test] + fn normal_extrinsic_limited_by_maximum_extrinsic_weight() { + new_test_ext().execute_with(|| { + let max = DispatchInfo { + weight: ::MaximumExtrinsicWeight::get() + 1, + class: DispatchClass::Normal, + ..Default::default() + }; + let len = 0_usize; + + assert_noop!( + CheckWeight::::do_validate(&max, len), + InvalidTransaction::ExhaustsResources + ); + }); + } + + #[test] + fn operational_extrinsic_limited_by_operational_space_limit() { + new_test_ext().execute_with(|| { + let operational_limit = CheckWeight::::get_dispatch_limit_ratio( + DispatchClass::Operational + ) * ::MaximumBlockWeight::get(); + let base_weight = ::ExtrinsicBaseWeight::get(); + let block_base = ::BlockExecutionWeight::get(); + + let weight = operational_limit - base_weight - block_base; + let okay = DispatchInfo { + weight, + class: DispatchClass::Operational, + ..Default::default() + }; + let max = DispatchInfo { + weight: weight + 1, + class: DispatchClass::Operational, + ..Default::default() + }; + let len = 0_usize; + + assert_eq!( + CheckWeight::::do_validate(&okay, len), + Ok(ValidTransaction { + priority: CheckWeight::::get_priority(&okay), + ..Default::default() + }) + ); + assert_noop!( + CheckWeight::::do_validate(&max, len), + InvalidTransaction::ExhaustsResources + ); + }); + } + + #[test] + fn register_extra_weight_unchecked_doesnt_care_about_limits() { + new_test_ext().execute_with(|| { + System::register_extra_weight_unchecked(Weight::max_value(), DispatchClass::Normal); + assert_eq!(System::block_weight().total(), Weight::max_value()); + assert!(System::block_weight().total() > ::MaximumBlockWeight::get()); + }); + } + + #[test] + fn full_block_with_normal_and_operational() { + new_test_ext().execute_with(|| { + // Max block is 1024 + // Max normal is 768 (75%) + // 10 is taken for block execution weight + // So normal extrinsic can be 758 weight (-5 for base extrinsic weight) + // And Operational can be 256 to produce a full block (-5 for base) + let max_normal = DispatchInfo { weight: 753, ..Default::default() }; + let rest_operational = DispatchInfo { weight: 251, class: DispatchClass::Operational, ..Default::default() }; + + let len = 0_usize; + + assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); + assert_eq!(System::block_weight().total(), 768); + assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); + assert_eq!(::MaximumBlockWeight::get(), 1024); + assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); + // Checking single extrinsic should not take current block weight into account. + assert_eq!(CheckWeight::::check_extrinsic_weight(&rest_operational), Ok(())); + }); + } + + #[test] + fn dispatch_order_does_not_effect_weight_logic() { + new_test_ext().execute_with(|| { + // We switch the order of `full_block_with_normal_and_operational` + let max_normal = DispatchInfo { weight: 753, ..Default::default() }; + let rest_operational = DispatchInfo { weight: 251, class: DispatchClass::Operational, ..Default::default() }; + + let len = 0_usize; + + assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); + // Extra 15 here from block execution + base extrinsic weight + assert_eq!(System::block_weight().total(), 266); + assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); + assert_eq!(::MaximumBlockWeight::get(), 1024); + assert_eq!(System::block_weight().total(), ::MaximumBlockWeight::get()); + }); + } + + #[test] + fn operational_works_on_full_block() { + new_test_ext().execute_with(|| { + // An on_initialize takes up the whole block! (Every time!) + System::register_extra_weight_unchecked(Weight::max_value(), DispatchClass::Mandatory); + let dispatch_normal = DispatchInfo { weight: 251, class: DispatchClass::Normal, ..Default::default() }; + let dispatch_operational = DispatchInfo { weight: 251, class: DispatchClass::Operational, ..Default::default() }; + let len = 0_usize; + + assert_noop!( + CheckWeight::::do_pre_dispatch(&dispatch_normal, len), + InvalidTransaction::ExhaustsResources + ); + // Thank goodness we can still do an operational transaction to possibly save the blockchain. + assert_ok!(CheckWeight::::do_pre_dispatch(&dispatch_operational, len)); + // Not too much though + assert_noop!( + CheckWeight::::do_pre_dispatch(&dispatch_operational, len), + InvalidTransaction::ExhaustsResources + ); + // Even with full block, validity of single transaction should be correct. + assert_eq!(CheckWeight::::check_extrinsic_weight(&dispatch_operational), Ok(())); + }); + } + + #[test] + fn signed_ext_check_weight_works_operational_tx() { + new_test_ext().execute_with(|| { + let normal = DispatchInfo { weight: 100, ..Default::default() }; + let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: Pays::Yes }; + let len = 0_usize; + let normal_limit = normal_weight_limit(); + + // given almost full block + BlockWeight::mutate(|current_weight| { + current_weight.put(normal_limit, DispatchClass::Normal) + }); + // will not fit. + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len).is_err()); + // will fit. + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len).is_ok()); + + // likewise for length limit. + let len = 100_usize; + AllExtrinsicsLen::put(normal_length_limit()); + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len).is_err()); + assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len).is_ok()); + }) + } + + #[test] + fn signed_ext() { + new_test_ext().execute_with(|| { + let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes }; + let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: Pays::Yes }; + let len = 0_usize; + + let priority = CheckWeight::(PhantomData) + .validate(&1, CALL, &normal, len) + .unwrap() + .priority; + assert_eq!(priority, 100); + + let priority = CheckWeight::(PhantomData) + .validate(&1, CALL, &op, len) + .unwrap() + .priority; + assert_eq!(priority, u64::max_value() / 2); + }) + } + + #[test] + fn signed_ext_check_weight_block_size_works() { + new_test_ext().execute_with(|| { + let normal = DispatchInfo::default(); + let normal_limit = normal_weight_limit() as usize; + let reset_check_weight = |tx, s, f| { + AllExtrinsicsLen::put(0); + let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, tx, s); + if f { assert!(r.is_err()) } else { assert!(r.is_ok()) } + }; + + reset_check_weight(&normal, normal_limit - 1, false); + reset_check_weight(&normal, normal_limit, false); + reset_check_weight(&normal, normal_limit + 1, true); + + // Operational ones don't have this limit. + let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: Pays::Yes }; + reset_check_weight(&op, normal_limit, false); + reset_check_weight(&op, normal_limit + 100, false); + reset_check_weight(&op, 1024, false); + reset_check_weight(&op, 1025, true); + }) + } + + + #[test] + fn signed_ext_check_weight_works_normal_tx() { + new_test_ext().execute_with(|| { + let normal_limit = normal_weight_limit(); + let small = DispatchInfo { weight: 100, ..Default::default() }; + let medium = DispatchInfo { + weight: normal_limit - ::ExtrinsicBaseWeight::get(), + ..Default::default() + }; + let big = DispatchInfo { + weight: normal_limit - ::ExtrinsicBaseWeight::get() + 1, + ..Default::default() + }; + let len = 0_usize; + + let reset_check_weight = |i, f, s| { + BlockWeight::mutate(|current_weight| { + current_weight.put(s, DispatchClass::Normal) + }); + let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, i, len); + if f { assert!(r.is_err()) } else { assert!(r.is_ok()) } + }; + + reset_check_weight(&small, false, 0); + reset_check_weight(&medium, false, 0); + reset_check_weight(&big, true, 1); + }) + } + + #[test] + fn signed_ext_check_weight_refund_works() { + new_test_ext().execute_with(|| { + // This is half of the max block weight + let info = DispatchInfo { weight: 512, ..Default::default() }; + let post_info = PostDispatchInfo { + actual_weight: Some(128), + pays_fee: Default::default(), + }; + let len = 0_usize; + + // We allow 75% for normal transaction, so we put 25% - extrinsic base weight + BlockWeight::mutate(|current_weight| { + current_weight.put(256 - ::ExtrinsicBaseWeight::get(), DispatchClass::Normal) + }); + + let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); + assert_eq!(BlockWeight::get().total(), info.weight + 256); + + assert!( + CheckWeight::::post_dispatch(pre, &info, &post_info, len, &Ok(())) + .is_ok() + ); + assert_eq!( + BlockWeight::get().total(), + post_info.actual_weight.unwrap() + 256, + ); + }) + } + + #[test] + fn signed_ext_check_weight_actual_weight_higher_than_max_is_capped() { + new_test_ext().execute_with(|| { + let info = DispatchInfo { weight: 512, ..Default::default() }; + let post_info = PostDispatchInfo { + actual_weight: Some(700), + pays_fee: Default::default(), + }; + let len = 0_usize; + + BlockWeight::mutate(|current_weight| { + current_weight.put(128, DispatchClass::Normal) + }); + + let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); + assert_eq!( + BlockWeight::get().total(), + info.weight + 128 + ::ExtrinsicBaseWeight::get(), + ); + + assert!( + CheckWeight::::post_dispatch(pre, &info, &post_info, len, &Ok(())) + .is_ok() + ); + assert_eq!( + BlockWeight::get().total(), + info.weight + 128 + ::ExtrinsicBaseWeight::get(), + ); + }) + } + + #[test] + fn zero_weight_extrinsic_still_has_base_weight() { + new_test_ext().execute_with(|| { + let free = DispatchInfo { weight: 0, ..Default::default() }; + let len = 0_usize; + + // Initial weight from `BlockExecutionWeight` + assert_eq!(System::block_weight().total(), ::BlockExecutionWeight::get()); + let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &free, len); + assert!(r.is_ok()); + assert_eq!( + System::block_weight().total(), + ::ExtrinsicBaseWeight::get() + ::BlockExecutionWeight::get() + ); + }) + } +} diff --git a/frame/system/src/extensions/mod.rs b/frame/system/src/extensions/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..ff61353e2d176fbc1660e2a6787e370c6f15328c --- /dev/null +++ b/frame/system/src/extensions/mod.rs @@ -0,0 +1,24 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +pub mod check_genesis; +pub mod check_mortality; +pub mod check_nonce; +pub mod check_spec_version; +pub mod check_tx_version; +pub mod check_weight; + diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index ff6893d6290e8b8344578255e01791ea0832edd1..fcd31923a245359b1edb1ffc387a4e9bd366ac60 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # System Module //! @@ -53,7 +54,9 @@ //! - [`CheckEra`]: Checks the era of the transaction. Contains a single payload of type `Era`. //! - [`CheckGenesis`]: Checks the provided genesis hash of the transaction. Must be a part of the //! signed payload of the transaction. -//! - [`CheckVersion`]: Checks that the runtime version is the same as the one encoded in the +//! - [`CheckSpecVersion`]: Checks that the runtime version is the same as the one used to sign the +//! transaction. +//! - [`CheckTxVersion`]: Checks that the transaction version is the same as the one used to sign the //! transaction. //! //! Lookup the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed @@ -99,18 +102,14 @@ use sp_std::marker::PhantomData; use sp_std::fmt::Debug; use sp_version::RuntimeVersion; use sp_runtime::{ - RuntimeDebug, Perbill, DispatchOutcome, DispatchError, DispatchResult, - generic::{self, Era}, - transaction_validity::{ - ValidTransaction, TransactionPriority, TransactionLongevity, TransactionValidityError, - InvalidTransaction, TransactionValidity, - }, + RuntimeDebug, Perbill, DispatchError, Either, generic, traits::{ - self, CheckEqual, AtLeast32Bit, Zero, SignedExtension, Lookup, LookupError, - SimpleBitOps, Hash, Member, MaybeDisplay, BadOrigin, SaturatedConversion, + self, CheckEqual, AtLeast32Bit, Zero, Lookup, LookupError, + SimpleBitOps, Hash, Member, MaybeDisplay, BadOrigin, MaybeSerialize, MaybeSerializeDeserialize, MaybeMallocSizeOf, StaticLookup, One, Bounded, - Dispatchable, DispatchInfoOf, PostDispatchInfoOf, + Dispatchable, AtLeast32BitUnsigned }, + offchain::storage_lock::BlockNumberProvider, }; use sp_core::{ChangesTrieConfiguration, storage::well_known_keys}; @@ -119,12 +118,13 @@ use frame_support::{ storage, traits::{ Contains, Get, ModuleToIndex, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened, - StoredMap, EnsureOrigin, + StoredMap, EnsureOrigin, OriginTrait, Filter, }, weights::{ - Weight, RuntimeDbWeight, DispatchInfo, PostDispatchInfo, DispatchClass, - FunctionOf, Pays, - } + Weight, RuntimeDbWeight, DispatchInfo, DispatchClass, + extract_actual_weight, + }, + dispatch::DispatchResultWithPostInfo, }; use codec::{Encode, Decode, FullCodec, EncodeLike}; @@ -132,6 +132,22 @@ use codec::{Encode, Decode, FullCodec, EncodeLike}; use sp_io::TestExternalities; pub mod offchain; +#[cfg(test)] +pub(crate) mod mock; + +mod extensions; +mod weights; +#[cfg(test)] +mod tests; +mod default_weights; + +pub use extensions::{ + check_mortality::CheckMortality, check_genesis::CheckGenesis, check_nonce::CheckNonce, + check_spec_version::CheckSpecVersion, check_tx_version::CheckTxVersion, + check_weight::CheckWeight, +}; +// Backward compatible re-export. +pub use extensions::check_mortality::CheckMortality as CheckEra; /// Compute the trie root of a list of extrinsics. pub fn extrinsics_root(extrinsics: &[E]) -> H::Output { @@ -143,12 +159,27 @@ pub fn extrinsics_data_root(xts: Vec>) -> H::Output { H::ordered_trie_root(xts) } +pub trait WeightInfo { + fn remark() -> Weight; + fn set_heap_pages() -> Weight; + fn set_changes_trie_config() -> Weight; + fn set_storage(i: u32, ) -> Weight; + fn kill_storage(i: u32, ) -> Weight; + fn kill_prefix(p: u32, ) -> Weight; + fn suicide() -> Weight; +} + pub trait Trait: 'static + Eq + Clone { - /// The aggregated `Origin` type used by dispatchable calls. + /// The basic call filter to use in Origin. All origins are built with this filter as base, + /// except Root. + type BaseCallFilter: Filter; + + /// The `Origin` type used by dispatchable calls. type Origin: Into, Self::Origin>> + From> - + Clone; + + Clone + + OriginTrait; /// The aggregated `Call` type. type Call: Dispatchable + Debug; @@ -161,8 +192,9 @@ pub trait Trait: 'static + Eq + Clone { /// The block number type used by the runtime. type BlockNumber: - Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + AtLeast32Bit - + Default + Bounded + Copy + sp_std::hash::Hash + sp_std::str::FromStr + MaybeMallocSizeOf; + Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + + AtLeast32BitUnsigned + Default + Bounded + Copy + sp_std::hash::Hash + + sp_std::str::FromStr + MaybeMallocSizeOf; /// The output of the `Hashing` function. type Hash: @@ -208,6 +240,11 @@ pub trait Trait: 'static + Eq + Clone { /// The base weight of an Extrinsic in the block, independent of the of extrinsic being executed. type ExtrinsicBaseWeight: Get; + /// The maximal weight of a single Extrinsic. This should be set to at most + /// `MaximumBlockWeight - AverageOnInitializeWeight`. The limit only applies to extrinsics + /// containing `Normal` dispatch class calls. + type MaximumExtrinsicWeight: Get; + /// The maximum length of a block (in bytes). type MaximumBlockLength: Get; @@ -236,6 +273,8 @@ pub trait Trait: 'static + Eq + Clone { /// /// All resources should be cleaned up associated with the given account. type OnKilledAccount: OnKilledAccount; + + type SystemWeightInfo: WeightInfo; } pub type DigestOf = generic::Digest<::Hash>; @@ -275,7 +314,7 @@ pub struct EventRecord { } /// Origin for the System module. -#[derive(PartialEq, Eq, Clone, RuntimeDebug)] +#[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode)] pub enum RawOrigin { /// The system itself ordained this dispatch to happen: this is the highest privilege level. Root, @@ -357,60 +396,6 @@ impl From for LastRuntimeUpgradeInfo { } } -/// An object to track the currently used extrinsic weight in a block. -#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)] -pub struct ExtrinsicsWeight { - normal: Weight, - operational: Weight, -} - -impl ExtrinsicsWeight { - /// Returns the total weight consumed by all extrinsics in the block. - pub fn total(&self) -> Weight { - self.normal.saturating_add(self.operational) - } - - /// Add some weight of a specific dispatch class, saturating at the numeric bounds of `Weight`. - pub fn add(&mut self, weight: Weight, class: DispatchClass) { - let value = self.get_mut(class); - *value = value.saturating_add(weight); - } - - /// Try to add some weight of a specific dispatch class, returning Err(()) if overflow would occur. - pub fn checked_add(&mut self, weight: Weight, class: DispatchClass) -> Result<(), ()> { - let value = self.get_mut(class); - *value = value.checked_add(weight).ok_or(())?; - Ok(()) - } - - /// Subtract some weight of a specific dispatch class, saturating at the numeric bounds of `Weight`. - pub fn sub(&mut self, weight: Weight, class: DispatchClass) { - let value = self.get_mut(class); - *value = value.saturating_sub(weight); - } - - /// Get the current weight of a specific dispatch class. - pub fn get(&self, class: DispatchClass) -> Weight { - match class { - DispatchClass::Operational => self.operational, - DispatchClass::Normal | DispatchClass::Mandatory => self.normal, - } - } - - /// Get a mutable reference to the current weight of a specific dispatch class. - fn get_mut(&mut self, class: DispatchClass) -> &mut Weight { - match class { - DispatchClass::Operational => &mut self.operational, - DispatchClass::Normal | DispatchClass::Mandatory => &mut self.normal, - } - } - - /// Set the weight of a specific dispatch class. - pub fn put(&mut self, new: Weight, class: DispatchClass) { - *self.get_mut(class) = new; - } -} - decl_storage! { trait Store for Module as System { /// The full account information for a particular account ID. @@ -420,8 +405,8 @@ decl_storage! { /// Total extrinsics count for the current block. ExtrinsicCount: Option; - /// Total weight for all extrinsics for the current block. - AllExtrinsicsWeight: ExtrinsicsWeight; + /// The current weight for the block. + BlockWeight get(fn block_weight): weights::ExtrinsicsWeight; /// Total length (in bytes) for all extrinsics put together, for the current block. AllExtrinsicsLen: Option; @@ -498,15 +483,15 @@ decl_storage! { decl_event!( /// Event for the System module. pub enum Event where AccountId = ::AccountId { - /// An extrinsic completed successfully. + /// An extrinsic completed successfully. [info] ExtrinsicSuccess(DispatchInfo), - /// An extrinsic failed. + /// An extrinsic failed. [error, info] ExtrinsicFailed(DispatchError, DispatchInfo), /// `:code` was updated. CodeUpdated, - /// A new account was created. + /// A new [account] was created. NewAccount(AccountId), - /// An account was reaped. + /// An [account] was reaped. KilledAccount(AccountId), } ); @@ -556,11 +541,7 @@ decl_module! { /// A dispatch that will fill the block weight up to the given ratio. // TODO: This should only be available for testing, rather than in general usage, but // that's not possible at present (since it's within the decl_module macro). - #[weight = FunctionOf( - |(ratio,): (&Perbill,)| *ratio * T::MaximumBlockWeight::get(), - DispatchClass::Operational, - Pays::Yes, - )] + #[weight = *_ratio * T::MaximumBlockWeight::get()] fn fill_block(origin, _ratio: Perbill) { ensure_root(origin)?; } @@ -572,7 +553,7 @@ decl_module! { /// - Base Weight: 0.665 µs, independent of remark length. /// - No DB operations. /// # - #[weight = 700_000] + #[weight = T::SystemWeightInfo::remark()] fn remark(origin, _remark: Vec) { ensure_signed(origin)?; } @@ -585,7 +566,7 @@ decl_module! { /// - Base Weight: 1.405 µs /// - 1 write to HEAP_PAGES /// # - #[weight = (T::DbWeight::get().writes(1) + 1_500_000, DispatchClass::Operational)] + #[weight = (T::SystemWeightInfo::set_heap_pages(), DispatchClass::Operational)] fn set_heap_pages(origin, pages: u64) { ensure_root(origin)?; storage::unhashed::put_raw(well_known_keys::HEAP_PAGES, &pages.encode()); @@ -603,7 +584,8 @@ decl_module! { /// # #[weight = (T::MaximumBlockWeight::get(), DispatchClass::Operational)] pub fn set_code(origin, code: Vec) { - Self::can_set_code(origin, &code)?; + ensure_root(origin)?; + Self::can_set_code(&code)?; storage::unhashed::put_raw(well_known_keys::CODE, &code); Self::deposit_event(RawEvent::CodeUpdated); @@ -634,7 +616,7 @@ decl_module! { /// - DB Weight: /// - Writes: Changes Trie, System Digest /// # - #[weight = (T::DbWeight::get().writes(2) + 10_000_000, DispatchClass::Operational)] + #[weight = (T::SystemWeightInfo::set_changes_trie_config(), DispatchClass::Operational)] pub fn set_changes_trie_config(origin, changes_trie_config: Option) { ensure_root(origin)?; match changes_trie_config.clone() { @@ -659,13 +641,9 @@ decl_module! { /// - Base Weight: 0.568 * i µs /// - Writes: Number of items /// # - #[weight = FunctionOf( - |(items,): (&Vec,)| { - T::DbWeight::get().writes(items.len() as Weight) - .saturating_add((items.len() as Weight).saturating_mul(600_000)) - }, + #[weight = ( + T::SystemWeightInfo::set_storage(items.len() as u32), DispatchClass::Operational, - Pays::Yes, )] fn set_storage(origin, items: Vec) { ensure_root(origin)?; @@ -682,13 +660,9 @@ decl_module! { /// - Base Weight: .378 * i µs /// - Writes: Number of items /// # - #[weight = FunctionOf( - |(keys,): (&Vec,)| { - T::DbWeight::get().writes(keys.len() as Weight) - .saturating_add((keys.len() as Weight).saturating_mul(400_000)) - }, + #[weight = ( + T::SystemWeightInfo::kill_storage(keys.len() as u32), DispatchClass::Operational, - Pays::Yes, )] fn kill_storage(origin, keys: Vec) { ensure_root(origin)?; @@ -708,13 +682,9 @@ decl_module! { /// - Base Weight: 0.834 * P µs /// - Writes: Number of subkeys + 1 /// # - #[weight = FunctionOf( - |(_, &subkeys): (&Key, &u32)| { - T::DbWeight::get().writes(Weight::from(subkeys) + 1) - .saturating_add((Weight::from(subkeys) + 1).saturating_mul(850_000)) - }, + #[weight = ( + T::SystemWeightInfo::kill_prefix(_subkeys.saturating_add(1)), DispatchClass::Operational, - Pays::Yes, )] fn kill_prefix(origin, prefix: Key, _subkeys: u32) { ensure_root(origin)?; @@ -731,13 +701,13 @@ decl_module! { /// Base Weight: 8.626 µs /// No DB Read or Write operations because caller is already in overlay /// # - #[weight = (10_000_000, DispatchClass::Operational)] - fn suicide(origin) { + #[weight = (T::SystemWeightInfo::suicide(), DispatchClass::Operational)] + pub fn suicide(origin) { let who = ensure_signed(origin)?; let account = Account::::get(&who); ensure!(account.refcount == 0, Error::::NonZeroRefCount); ensure!(account.data == T::AccountData::default(), Error::::NonDefaultComposite); - Account::::remove(who); + Self::kill_account(&who); } } } @@ -837,6 +807,30 @@ impl EnsureOrigin for EnsureNever { } } +/// The "OR gate" implementation of `EnsureOrigin`. +/// +/// Origin check will pass if `L` or `R` origin check passes. `L` is tested first. +pub struct EnsureOneOf(sp_std::marker::PhantomData<(AccountId, L, R)>); +impl< + AccountId, + O: Into, O>> + From>, + L: EnsureOrigin, + R: EnsureOrigin, +> EnsureOrigin for EnsureOneOf { + type Success = Either; + fn try_origin(o: O) -> Result { + L::try_origin(o).map_or_else( + |o| R::try_origin(o).map(|o| Either::Right(o)), + |o| Ok(Either::Left(o)), + ) + } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin() -> O { + L::successful_origin() + } +} + /// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction). /// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise. pub fn ensure_signed(o: OuterOrigin) -> Result @@ -969,11 +963,6 @@ impl Module { ExtrinsicCount::get().unwrap_or_default() } - /// Gets the weight of all executed extrinsics. - pub fn all_extrinsics_weight() -> ExtrinsicsWeight { - AllExtrinsicsWeight::get() - } - pub fn all_extrinsics_len() -> u32 { AllExtrinsicsLen::get().unwrap_or_default() } @@ -994,7 +983,7 @@ impl Module { /// /// Another potential use-case could be for the `on_initialize` and `on_finalize` hooks. pub fn register_extra_weight_unchecked(weight: Weight, class: DispatchClass) { - AllExtrinsicsWeight::mutate(|current_weight| { + BlockWeight::mutate(|current_weight| { current_weight.add(weight, class); }); } @@ -1016,6 +1005,10 @@ impl Module { >::insert(*number - One::one(), parent_hash); >::put(txs_root); + // Remove previous block data from storage + BlockWeight::kill(); + + // Kill inspectable storage entries in state when `InitKind::Full`. if let InitKind::Full = kind { >::kill(); EventCount::kill(); @@ -1027,7 +1020,6 @@ impl Module { pub fn finalize() -> T::Header { ExecutionPhase::kill(); ExtrinsicCount::kill(); - AllExtrinsicsWeight::kill(); AllExtrinsicsLen::kill(); let number = >::take(); @@ -1117,12 +1109,21 @@ impl Module { /// Set the current block weight. This should only be used in some integration tests. #[cfg(any(feature = "std", test))] pub fn set_block_limits(weight: Weight, len: usize) { - AllExtrinsicsWeight::mutate(|current_weight| { + BlockWeight::mutate(|current_weight| { current_weight.put(weight, DispatchClass::Normal) }); AllExtrinsicsLen::put(len as u32); } + /// Reset events. Can be used as an alternative to + /// `initialize` for tests that don't need to bother with the other environment entries. + #[cfg(any(feature = "std", feature = "runtime-benchmarks", test))] + pub fn reset_events() { + >::kill(); + EventCount::kill(); + >::remove_all(); + } + /// Return the chain's current runtime version. pub fn runtime_version() -> RuntimeVersion { T::Version::get() } @@ -1147,13 +1148,14 @@ impl Module { } /// To be called immediately after an extrinsic has been applied. - pub fn note_applied_extrinsic(r: &DispatchOutcome, _encoded_len: u32, info: DispatchInfo) { + pub fn note_applied_extrinsic(r: &DispatchResultWithPostInfo, mut info: DispatchInfo) { + info.weight = extract_actual_weight(r, &info); Self::deposit_event( match r { - Ok(()) => RawEvent::ExtrinsicSuccess(info), + Ok(_) => RawEvent::ExtrinsicSuccess(info), Err(err) => { sp_runtime::print(err); - RawEvent::ExtrinsicFailed(err.clone(), info) + RawEvent::ExtrinsicFailed(err.error, info) }, } ); @@ -1213,20 +1215,16 @@ impl Module { "WARNING: Referenced account deleted. This is probably a bug." ); } - Module::::on_killed_account(who.clone()); } + Module::::on_killed_account(who.clone()); } /// Determine whether or not it is possible to update the code. /// - /// This function has no side effects and is idempotent, but is fairly - /// heavy. It is automatically called by `set_code`; in most cases, - /// a direct call to `set_code` is preferable. It is useful to call - /// `can_set_code` when it is desirable to perform the appropriate - /// runtime checks without actually changing the code yet. - pub fn can_set_code(origin: T::Origin, code: &[u8]) -> Result<(), sp_runtime::DispatchError> { - ensure_root(origin)?; - + /// Checks the given code if it is a valid runtime wasm blob by instantianting + /// it and extracting the runtime version of it. It checks that the runtime version + /// of the old and new runtime has the same spec name and that the spec version is increasing. + pub fn can_set_code(code: &[u8]) -> Result<(), sp_runtime::DispatchError> { let current_version = T::Version::get(); let new_version = sp_io::misc::runtime_version(&code) .and_then(|v| RuntimeVersion::decode(&mut &v[..]).ok()) @@ -1260,6 +1258,15 @@ impl Happened for CallKillAccount { } } +impl BlockNumberProvider for Module +{ + type BlockNumber = ::BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + Module::::block_number() + } +} + // Implement StoredMap for a simple single-item, kill-account-on-remove system. This works fine for // storing a single item which is required to not be empty/default for the account to exist. // Anything more complex will need more sophisticated logic. @@ -1329,314 +1336,6 @@ pub fn split_inner(option: Option, splitter: impl FnOnce(T) -> (R, S } } -/// resource limit check. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckWeight(PhantomData); - -impl CheckWeight where - T::Call: Dispatchable -{ - /// Get the quota ratio of each dispatch class type. This indicates that all operational and mandatory - /// dispatches can use the full capacity of any resource, while user-triggered ones can consume - /// a portion. - fn get_dispatch_limit_ratio(class: DispatchClass) -> Perbill { - match class { - DispatchClass::Operational | DispatchClass::Mandatory - => ::one(), - DispatchClass::Normal => T::AvailableBlockRatio::get(), - } - } - - /// Checks if the current extrinsic can fit into the block with respect to block weight limits. - /// - /// Upon successes, it returns the new block weight as a `Result`. - fn check_weight( - info: &DispatchInfoOf, - ) -> Result { - let maximum_weight = T::MaximumBlockWeight::get(); - let mut all_weight = Module::::all_extrinsics_weight(); - match info.class { - // If we have a dispatch that must be included in the block, it ignores all the limits. - DispatchClass::Mandatory => { - let extrinsic_weight = info.weight.saturating_add(T::ExtrinsicBaseWeight::get()); - all_weight.add(extrinsic_weight, DispatchClass::Mandatory); - Ok(all_weight) - }, - // If we have a normal dispatch, we follow all the normal rules and limits. - DispatchClass::Normal => { - let normal_limit = Self::get_dispatch_limit_ratio(DispatchClass::Normal) * maximum_weight; - let extrinsic_weight = info.weight.checked_add(T::ExtrinsicBaseWeight::get()) - .ok_or(InvalidTransaction::ExhaustsResources)?; - all_weight.checked_add(extrinsic_weight, DispatchClass::Normal) - .map_err(|_| InvalidTransaction::ExhaustsResources)?; - if all_weight.get(DispatchClass::Normal) > normal_limit { - Err(InvalidTransaction::ExhaustsResources.into()) - } else { - Ok(all_weight) - } - }, - // If we have an operational dispatch, allow it if we have not used our full - // "operational space" (independent of existing fullness). - DispatchClass::Operational => { - let operational_limit = Self::get_dispatch_limit_ratio(DispatchClass::Operational) * maximum_weight; - let normal_limit = Self::get_dispatch_limit_ratio(DispatchClass::Normal) * maximum_weight; - let operational_space = operational_limit.saturating_sub(normal_limit); - - let extrinsic_weight = info.weight.checked_add(T::ExtrinsicBaseWeight::get()) - .ok_or(InvalidTransaction::ExhaustsResources)?; - all_weight.checked_add(extrinsic_weight, DispatchClass::Operational) - .map_err(|_| InvalidTransaction::ExhaustsResources)?; - - // If it would fit in normally, its okay - if all_weight.total() <= maximum_weight || - // If we have not used our operational space - all_weight.get(DispatchClass::Operational) <= operational_space { - Ok(all_weight) - } else { - Err(InvalidTransaction::ExhaustsResources.into()) - } - } - } - } - - /// Checks if the current extrinsic can fit into the block with respect to block length limits. - /// - /// Upon successes, it returns the new block length as a `Result`. - fn check_block_length( - info: &DispatchInfoOf, - len: usize, - ) -> Result { - let current_len = Module::::all_extrinsics_len(); - let maximum_len = T::MaximumBlockLength::get(); - let limit = Self::get_dispatch_limit_ratio(info.class) * maximum_len; - let added_len = len as u32; - let next_len = current_len.saturating_add(added_len); - if next_len > limit { - Err(InvalidTransaction::ExhaustsResources.into()) - } else { - Ok(next_len) - } - } - - /// get the priority of an extrinsic denoted by `info`. - fn get_priority(info: &DispatchInfoOf) -> TransactionPriority { - match info.class { - DispatchClass::Normal => info.weight.into(), - DispatchClass::Operational => Bounded::max_value(), - // Mandatory extrinsics are only for inherents; never transactions. - DispatchClass::Mandatory => Bounded::min_value(), - } - } - - /// Creates new `SignedExtension` to check weight of the extrinsic. - pub fn new() -> Self { - Self(PhantomData) - } - - /// Do the pre-dispatch checks. This can be applied to both signed and unsigned. - /// - /// It checks and notes the new weight and length. - fn do_pre_dispatch( - info: &DispatchInfoOf, - len: usize, - ) -> Result<(), TransactionValidityError> { - let next_len = Self::check_block_length(info, len)?; - let next_weight = Self::check_weight(info)?; - AllExtrinsicsLen::put(next_len); - AllExtrinsicsWeight::put(next_weight); - Ok(()) - } - - /// Do the validate checks. This can be applied to both signed and unsigned. - /// - /// It only checks that the block weight and length limit will not exceed. - fn do_validate( - info: &DispatchInfoOf, - len: usize, - ) -> TransactionValidity { - // ignore the next weight and length. If they return `Ok`, then it is below the limit. - let _ = Self::check_block_length(info, len)?; - let _ = Self::check_weight(info)?; - - Ok(ValidTransaction { priority: Self::get_priority(info), ..Default::default() }) - } -} - -impl SignedExtension for CheckWeight where - T::Call: Dispatchable -{ - type AccountId = T::AccountId; - type Call = T::Call; - type AdditionalSigned = (); - type Pre = (); - const IDENTIFIER: &'static str = "CheckWeight"; - - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } - - fn pre_dispatch( - self, - _who: &Self::AccountId, - _call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result<(), TransactionValidityError> { - if info.class == DispatchClass::Mandatory { - Err(InvalidTransaction::MandatoryDispatch)? - } - Self::do_pre_dispatch(info, len) - } - - fn validate( - &self, - _who: &Self::AccountId, - _call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> TransactionValidity { - if info.class == DispatchClass::Mandatory { - Err(InvalidTransaction::MandatoryDispatch)? - } - Self::do_validate(info, len) - } - - fn pre_dispatch_unsigned( - _call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> Result<(), TransactionValidityError> { - Self::do_pre_dispatch(info, len) - } - - fn validate_unsigned( - _call: &Self::Call, - info: &DispatchInfoOf, - len: usize, - ) -> TransactionValidity { - Self::do_validate(info, len) - } - - fn post_dispatch( - _pre: Self::Pre, - info: &DispatchInfoOf, - post_info: &PostDispatchInfoOf, - _len: usize, - result: &DispatchResult, - ) -> Result<(), TransactionValidityError> { - // Since mandatory dispatched do not get validated for being overweight, we are sensitive - // to them actually being useful. Block producers are thus not allowed to include mandatory - // extrinsics that result in error. - if info.class == DispatchClass::Mandatory && result.is_err() { - Err(InvalidTransaction::BadMandatory)? - } - - let unspent = post_info.calc_unspent(info); - if unspent > 0 { - AllExtrinsicsWeight::mutate(|current_weight| { - current_weight.sub(unspent, info.class); - }) - } - - Ok(()) - } -} - -impl Debug for CheckWeight { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "CheckWeight") - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -/// Nonce check and increment to give replay protection for transactions. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckNonce(#[codec(compact)] T::Index); - -impl CheckNonce { - /// utility constructor. Used only in client/factory code. - pub fn from(nonce: T::Index) -> Self { - Self(nonce) - } -} - -impl Debug for CheckNonce { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "CheckNonce({})", self.0) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -impl SignedExtension for CheckNonce where - T::Call: Dispatchable -{ - type AccountId = T::AccountId; - type Call = T::Call; - type AdditionalSigned = (); - type Pre = (); - const IDENTIFIER: &'static str = "CheckNonce"; - - fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } - - fn pre_dispatch( - self, - who: &Self::AccountId, - _call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> Result<(), TransactionValidityError> { - let mut account = Account::::get(who); - if self.0 != account.nonce { - return Err( - if self.0 < account.nonce { - InvalidTransaction::Stale - } else { - InvalidTransaction::Future - }.into() - ) - } - account.nonce += T::Index::one(); - Account::::insert(who, account); - Ok(()) - } - - fn validate( - &self, - who: &Self::AccountId, - _call: &Self::Call, - info: &DispatchInfoOf, - _len: usize, - ) -> TransactionValidity { - // check index - let account = Account::::get(who); - if self.0 < account.nonce { - return InvalidTransaction::Stale.into() - } - - let provides = vec![Encode::encode(&(who, self.0))]; - let requires = if account.nonce < self.0 { - vec![Encode::encode(&(who, self.0 - One::one()))] - } else { - vec![] - }; - - Ok(ValidTransaction { - priority: info.weight as TransactionPriority, - requires, - provides, - longevity: TransactionLongevity::max_value(), - propagate: true, - }) - } -} impl IsDeadAccount for Module { fn is_dead_account(who: &T::AccountId) -> bool { @@ -1644,132 +1343,6 @@ impl IsDeadAccount for Module { } } -/// Check for transaction mortality. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckEra(Era, sp_std::marker::PhantomData); - -impl CheckEra { - /// utility constructor. Used only in client/factory code. - pub fn from(era: Era) -> Self { - Self(era, sp_std::marker::PhantomData) - } -} - -impl Debug for CheckEra { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "CheckEra({:?})", self.0) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -impl SignedExtension for CheckEra { - type AccountId = T::AccountId; - type Call = T::Call; - type AdditionalSigned = T::Hash; - type Pre = (); - const IDENTIFIER: &'static str = "CheckEra"; - - fn validate( - &self, - _who: &Self::AccountId, - _call: &Self::Call, - _info: &DispatchInfoOf, - _len: usize, - ) -> TransactionValidity { - let current_u64 = >::block_number().saturated_into::(); - let valid_till = self.0.death(current_u64); - Ok(ValidTransaction { - longevity: valid_till.saturating_sub(current_u64), - ..Default::default() - }) - } - - fn additional_signed(&self) -> Result { - let current_u64 = >::block_number().saturated_into::(); - let n = self.0.birth(current_u64).saturated_into::(); - if !>::contains_key(n) { - Err(InvalidTransaction::AncientBirthBlock.into()) - } else { - Ok(>::block_hash(n)) - } - } -} - -/// Nonce check and increment to give replay protection for transactions. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckGenesis(sp_std::marker::PhantomData); - -impl Debug for CheckGenesis { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "CheckGenesis") - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -impl CheckGenesis { - /// Creates new `SignedExtension` to check genesis hash. - pub fn new() -> Self { - Self(sp_std::marker::PhantomData) - } -} - -impl SignedExtension for CheckGenesis { - type AccountId = T::AccountId; - type Call = ::Call; - type AdditionalSigned = T::Hash; - type Pre = (); - const IDENTIFIER: &'static str = "CheckGenesis"; - - fn additional_signed(&self) -> Result { - Ok(>::block_hash(T::BlockNumber::zero())) - } -} - -/// Ensure the runtime version registered in the transaction is the same as at present. -#[derive(Encode, Decode, Clone, Eq, PartialEq)] -pub struct CheckVersion(sp_std::marker::PhantomData); - -impl Debug for CheckVersion { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - write!(f, "CheckVersion") - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -impl CheckVersion { - /// Create new `SignedExtension` to check runtime version. - pub fn new() -> Self { - Self(sp_std::marker::PhantomData) - } -} - -impl SignedExtension for CheckVersion { - type AccountId = T::AccountId; - type Call = ::Call; - type AdditionalSigned = u32; - type Pre = (); - const IDENTIFIER: &'static str = "CheckVersion"; - - fn additional_signed(&self) -> Result { - Ok(>::runtime_version().spec_version) - } -} - pub struct ChainContext(sp_std::marker::PhantomData); impl Default for ChainContext { fn default() -> Self { @@ -1785,700 +1358,3 @@ impl Lookup for ChainContext { ::lookup(s) } } - -#[cfg(test)] -pub(crate) mod tests { - use super::*; - use sp_std::cell::RefCell; - use sp_core::H256; - use sp_runtime::{traits::{BlakeTwo256, IdentityLookup, SignedExtension}, testing::Header, DispatchError}; - use frame_support::{impl_outer_origin, parameter_types, assert_ok, assert_noop}; - - impl_outer_origin! { - pub enum Origin for Test where system = super {} - } - - #[derive(Clone, Eq, PartialEq, Debug)] - pub struct Test; - - parameter_types! { - pub const BlockHashCount: u64 = 10; - pub const MaximumBlockWeight: Weight = 1024; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); - pub const MaximumBlockLength: u32 = 1024; - pub const Version: RuntimeVersion = RuntimeVersion { - spec_name: sp_version::create_runtime_str!("test"), - impl_name: sp_version::create_runtime_str!("system-test"), - authoring_version: 1, - spec_version: 1, - impl_version: 1, - apis: sp_version::create_apis_vec!([]), - transaction_version: 1, - }; - pub const BlockExecutionWeight: Weight = 10; - pub const ExtrinsicBaseWeight: Weight = 5; - pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { - read: 10, - write: 100, - }; - } - - thread_local!{ - pub static KILLED: RefCell> = RefCell::new(vec![]); - } - - pub struct RecordKilled; - impl OnKilledAccount for RecordKilled { - fn on_killed_account(who: &u64) { KILLED.with(|r| r.borrow_mut().push(*who)) } - } - - #[derive(Debug, codec::Encode, codec::Decode)] - pub struct Call; - - impl Dispatchable for Call { - type Origin = (); - type Trait = (); - type Info = DispatchInfo; - type PostInfo = PostDispatchInfo; - fn dispatch(self, _origin: Self::Origin) - -> sp_runtime::DispatchResultWithInfo { - panic!("Do not use dummy implementation for dispatch."); - } - } - - impl Trait for Test { - type Origin = Origin; - type Call = Call; - type Index = u64; - type BlockNumber = u64; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = u16; - type BlockHashCount = BlockHashCount; - type MaximumBlockWeight = MaximumBlockWeight; - type DbWeight = DbWeight; - type BlockExecutionWeight = BlockExecutionWeight; - type ExtrinsicBaseWeight = ExtrinsicBaseWeight; - type AvailableBlockRatio = AvailableBlockRatio; - type MaximumBlockLength = MaximumBlockLength; - type Version = Version; - type ModuleToIndex = (); - type AccountData = u32; - type OnNewAccount = (); - type OnKilledAccount = RecordKilled; - } - - impl From> for u16 { - fn from(e: Event) -> u16 { - match e { - Event::::ExtrinsicSuccess(..) => 100, - Event::::ExtrinsicFailed(..) => 101, - Event::::CodeUpdated => 102, - _ => 103, - } - } - } - - type System = Module; - - const CALL: &::Call = &Call; - - fn new_test_ext() -> sp_io::TestExternalities { - let mut ext: sp_io::TestExternalities = GenesisConfig::default().build_storage::().unwrap().into(); - // Add to each test the initial weight of a block - ext.execute_with(|| System::register_extra_weight_unchecked(::BlockExecutionWeight::get(), DispatchClass::Mandatory)); - ext - } - - fn normal_weight_limit() -> Weight { - ::AvailableBlockRatio::get() * ::MaximumBlockWeight::get() - } - - fn normal_length_limit() -> u32 { - ::AvailableBlockRatio::get() * ::MaximumBlockLength::get() - } - - #[test] - fn origin_works() { - let o = Origin::from(RawOrigin::::Signed(1u64)); - let x: Result, Origin> = o.into(); - assert_eq!(x, Ok(RawOrigin::::Signed(1u64))); - } - - #[test] - fn stored_map_works() { - new_test_ext().execute_with(|| { - System::insert(&0, 42); - assert!(System::allow_death(&0)); - - System::inc_ref(&0); - assert!(!System::allow_death(&0)); - - System::insert(&0, 69); - assert!(!System::allow_death(&0)); - - System::dec_ref(&0); - assert!(System::allow_death(&0)); - - assert!(KILLED.with(|r| r.borrow().is_empty())); - System::kill_account(&0); - assert_eq!(KILLED.with(|r| r.borrow().clone()), vec![0u64]); - }); - } - - #[test] - fn deposit_event_should_work() { - new_test_ext().execute_with(|| { - System::initialize( - &1, - &[0u8; 32].into(), - &[0u8; 32].into(), - &Default::default(), - InitKind::Full, - ); - System::note_finished_extrinsics(); - System::deposit_event(1u16); - System::finalize(); - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Finalization, - event: 1u16, - topics: vec![], - } - ] - ); - - System::initialize( - &2, - &[0u8; 32].into(), - &[0u8; 32].into(), - &Default::default(), - InitKind::Full, - ); - System::deposit_event(32u16); - System::note_finished_initialize(); - System::deposit_event(42u16); - System::note_applied_extrinsic(&Ok(()), 0, Default::default()); - System::note_applied_extrinsic(&Err(DispatchError::BadOrigin), 0, Default::default()); - System::note_finished_extrinsics(); - System::deposit_event(3u16); - System::finalize(); - assert_eq!( - System::events(), - vec![ - EventRecord { phase: Phase::Initialization, event: 32u16, topics: vec![] }, - EventRecord { phase: Phase::ApplyExtrinsic(0), event: 42u16, topics: vec![] }, - EventRecord { phase: Phase::ApplyExtrinsic(0), event: 100u16, topics: vec![] }, - EventRecord { phase: Phase::ApplyExtrinsic(1), event: 101u16, topics: vec![] }, - EventRecord { phase: Phase::Finalization, event: 3u16, topics: vec![] } - ] - ); - }); - } - - #[test] - fn deposit_event_topics() { - new_test_ext().execute_with(|| { - const BLOCK_NUMBER: u64 = 1; - - System::initialize( - &BLOCK_NUMBER, - &[0u8; 32].into(), - &[0u8; 32].into(), - &Default::default(), - InitKind::Full, - ); - System::note_finished_extrinsics(); - - let topics = vec![ - H256::repeat_byte(1), - H256::repeat_byte(2), - H256::repeat_byte(3), - ]; - - // We deposit a few events with different sets of topics. - System::deposit_event_indexed(&topics[0..3], 1u16); - System::deposit_event_indexed(&topics[0..1], 2u16); - System::deposit_event_indexed(&topics[1..2], 3u16); - - System::finalize(); - - // Check that topics are reflected in the event record. - assert_eq!( - System::events(), - vec![ - EventRecord { - phase: Phase::Finalization, - event: 1u16, - topics: topics[0..3].to_vec(), - }, - EventRecord { - phase: Phase::Finalization, - event: 2u16, - topics: topics[0..1].to_vec(), - }, - EventRecord { - phase: Phase::Finalization, - event: 3u16, - topics: topics[1..2].to_vec(), - } - ] - ); - - // Check that the topic-events mapping reflects the deposited topics. - // Note that these are indexes of the events. - assert_eq!( - System::event_topics(&topics[0]), - vec![(BLOCK_NUMBER, 0), (BLOCK_NUMBER, 1)], - ); - assert_eq!( - System::event_topics(&topics[1]), - vec![(BLOCK_NUMBER, 0), (BLOCK_NUMBER, 2)], - ); - assert_eq!( - System::event_topics(&topics[2]), - vec![(BLOCK_NUMBER, 0)], - ); - }); - } - - #[test] - fn prunes_block_hash_mappings() { - new_test_ext().execute_with(|| { - // simulate import of 15 blocks - for n in 1..=15 { - System::initialize( - &n, - &[n as u8 - 1; 32].into(), - &[0u8; 32].into(), - &Default::default(), - InitKind::Full, - ); - - System::finalize(); - } - - // first 5 block hashes are pruned - for n in 0..5 { - assert_eq!( - System::block_hash(n), - H256::zero(), - ); - } - - // the remaining 10 are kept - for n in 5..15 { - assert_eq!( - System::block_hash(n), - [n as u8; 32].into(), - ); - } - }) - } - - #[test] - fn signed_ext_check_nonce_works() { - new_test_ext().execute_with(|| { - Account::::insert(1, AccountInfo { nonce: 1, refcount: 0, data: 0 }); - let info = DispatchInfo::default(); - let len = 0_usize; - // stale - assert!(CheckNonce::(0).validate(&1, CALL, &info, len).is_err()); - assert!(CheckNonce::(0).pre_dispatch(&1, CALL, &info, len).is_err()); - // correct - assert!(CheckNonce::(1).validate(&1, CALL, &info, len).is_ok()); - assert!(CheckNonce::(1).pre_dispatch(&1, CALL, &info, len).is_ok()); - // future - assert!(CheckNonce::(5).validate(&1, CALL, &info, len).is_ok()); - assert!(CheckNonce::(5).pre_dispatch(&1, CALL, &info, len).is_err()); - }) - } - - #[test] - fn signed_ext_check_weight_works_normal_tx() { - new_test_ext().execute_with(|| { - let normal_limit = normal_weight_limit(); - let small = DispatchInfo { weight: 100, ..Default::default() }; - let medium = DispatchInfo { - weight: normal_limit - ::ExtrinsicBaseWeight::get(), - ..Default::default() - }; - let big = DispatchInfo { - weight: normal_limit - ::ExtrinsicBaseWeight::get() + 1, - ..Default::default() - }; - let len = 0_usize; - - let reset_check_weight = |i, f, s| { - AllExtrinsicsWeight::mutate(|current_weight| { - current_weight.put(s, DispatchClass::Normal) - }); - let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, i, len); - if f { assert!(r.is_err()) } else { assert!(r.is_ok()) } - }; - - reset_check_weight(&small, false, 0); - reset_check_weight(&medium, false, 0); - reset_check_weight(&big, true, 1); - }) - } - - #[test] - fn signed_ext_check_weight_refund_works() { - new_test_ext().execute_with(|| { - // This is half of the max block weight - let info = DispatchInfo { weight: 512, ..Default::default() }; - let post_info = PostDispatchInfo { actual_weight: Some(128), }; - let len = 0_usize; - - // We allow 75% for normal transaction, so we put 25% - extrinsic base weight - AllExtrinsicsWeight::mutate(|current_weight| { - current_weight.put(256 - ::ExtrinsicBaseWeight::get(), DispatchClass::Normal) - }); - - let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); - assert_eq!(AllExtrinsicsWeight::get().total(), info.weight + 256); - - assert!( - CheckWeight::::post_dispatch(pre, &info, &post_info, len, &Ok(())) - .is_ok() - ); - assert_eq!( - AllExtrinsicsWeight::get().total(), - post_info.actual_weight.unwrap() + 256, - ); - }) - } - - #[test] - fn signed_ext_check_weight_actual_weight_higher_than_max_is_capped() { - new_test_ext().execute_with(|| { - let info = DispatchInfo { weight: 512, ..Default::default() }; - let post_info = PostDispatchInfo { actual_weight: Some(700), }; - let len = 0_usize; - - AllExtrinsicsWeight::mutate(|current_weight| { - current_weight.put(128, DispatchClass::Normal) - }); - - let pre = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &info, len).unwrap(); - assert_eq!( - AllExtrinsicsWeight::get().total(), - info.weight + 128 + ::ExtrinsicBaseWeight::get(), - ); - - assert!( - CheckWeight::::post_dispatch(pre, &info, &post_info, len, &Ok(())) - .is_ok() - ); - assert_eq!( - AllExtrinsicsWeight::get().total(), - info.weight + 128 + ::ExtrinsicBaseWeight::get(), - ); - }) - } - - #[test] - fn zero_weight_extrinsic_still_has_base_weight() { - new_test_ext().execute_with(|| { - let free = DispatchInfo { weight: 0, ..Default::default() }; - let len = 0_usize; - - // Initial weight from `BlockExecutionWeight` - assert_eq!(System::all_extrinsics_weight().total(), ::BlockExecutionWeight::get()); - let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &free, len); - assert!(r.is_ok()); - assert_eq!( - System::all_extrinsics_weight().total(), - ::ExtrinsicBaseWeight::get() + ::BlockExecutionWeight::get() - ); - }) - } - - #[test] - fn mandatory_extrinsic_doesnt_care_about_limits() { - new_test_ext().execute_with(|| { - let max = DispatchInfo { - weight: Weight::max_value(), - class: DispatchClass::Mandatory, - ..Default::default() - }; - let len = 0_usize; - - assert_ok!(CheckWeight::::do_pre_dispatch(&max, len)); - assert_eq!(System::all_extrinsics_weight().total(), Weight::max_value()); - assert!(System::all_extrinsics_weight().total() > ::MaximumBlockWeight::get()); - }); - } - - #[test] - fn register_extra_weight_unchecked_doesnt_care_about_limits() { - new_test_ext().execute_with(|| { - System::register_extra_weight_unchecked(Weight::max_value(), DispatchClass::Normal); - assert_eq!(System::all_extrinsics_weight().total(), Weight::max_value()); - assert!(System::all_extrinsics_weight().total() > ::MaximumBlockWeight::get()); - }); - } - - #[test] - fn full_block_with_normal_and_operational() { - new_test_ext().execute_with(|| { - // Max block is 1024 - // Max normal is 768 (75%) - // 10 is taken for block execution weight - // So normal extrinsic can be 758 weight (-5 for base extrinsic weight) - // And Operational can be 256 to produce a full block (-5 for base) - let max_normal = DispatchInfo { weight: 753, ..Default::default() }; - let rest_operational = DispatchInfo { weight: 251, class: DispatchClass::Operational, ..Default::default() }; - - let len = 0_usize; - - assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); - assert_eq!(System::all_extrinsics_weight().total(), 768); - assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); - assert_eq!(::MaximumBlockWeight::get(), 1024); - assert_eq!(System::all_extrinsics_weight().total(), ::MaximumBlockWeight::get()); - }); - } - - #[test] - fn dispatch_order_does_not_effect_weight_logic() { - new_test_ext().execute_with(|| { - // We switch the order of `full_block_with_normal_and_operational` - let max_normal = DispatchInfo { weight: 753, ..Default::default() }; - let rest_operational = DispatchInfo { weight: 251, class: DispatchClass::Operational, ..Default::default() }; - - let len = 0_usize; - - assert_ok!(CheckWeight::::do_pre_dispatch(&rest_operational, len)); - // Extra 15 here from block execution + base extrinsic weight - assert_eq!(System::all_extrinsics_weight().total(), 266); - assert_ok!(CheckWeight::::do_pre_dispatch(&max_normal, len)); - assert_eq!(::MaximumBlockWeight::get(), 1024); - assert_eq!(System::all_extrinsics_weight().total(), ::MaximumBlockWeight::get()); - }); - } - - #[test] - fn operational_works_on_full_block() { - new_test_ext().execute_with(|| { - // An on_initialize takes up the whole block! (Every time!) - System::register_extra_weight_unchecked(Weight::max_value(), DispatchClass::Mandatory); - let dispatch_normal = DispatchInfo { weight: 251, class: DispatchClass::Normal, ..Default::default() }; - let dispatch_operational = DispatchInfo { weight: 251, class: DispatchClass::Operational, ..Default::default() }; - let len = 0_usize; - - assert_noop!(CheckWeight::::do_pre_dispatch(&dispatch_normal, len), InvalidTransaction::ExhaustsResources); - // Thank goodness we can still do an operational transaction to possibly save the blockchain. - assert_ok!(CheckWeight::::do_pre_dispatch(&dispatch_operational, len)); - // Not too much though - assert_noop!(CheckWeight::::do_pre_dispatch(&dispatch_operational, len), InvalidTransaction::ExhaustsResources); - }); - } - - #[test] - fn signed_ext_check_weight_works_operational_tx() { - new_test_ext().execute_with(|| { - let normal = DispatchInfo { weight: 100, ..Default::default() }; - let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: Pays::Yes }; - let len = 0_usize; - let normal_limit = normal_weight_limit(); - - // given almost full block - AllExtrinsicsWeight::mutate(|current_weight| { - current_weight.put(normal_limit, DispatchClass::Normal) - }); - // will not fit. - assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len).is_err()); - // will fit. - assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len).is_ok()); - - // likewise for length limit. - let len = 100_usize; - AllExtrinsicsLen::put(normal_length_limit()); - assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &normal, len).is_err()); - assert!(CheckWeight::(PhantomData).pre_dispatch(&1, CALL, &op, len).is_ok()); - }) - } - - #[test] - fn signed_ext_check_weight_priority_works() { - new_test_ext().execute_with(|| { - let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes }; - let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: Pays::Yes }; - let len = 0_usize; - - let priority = CheckWeight::(PhantomData) - .validate(&1, CALL, &normal, len) - .unwrap() - .priority; - assert_eq!(priority, 100); - - let priority = CheckWeight::(PhantomData) - .validate(&1, CALL, &op, len) - .unwrap() - .priority; - assert_eq!(priority, u64::max_value()); - }) - } - - #[test] - fn signed_ext_check_weight_block_size_works() { - new_test_ext().execute_with(|| { - let normal = DispatchInfo::default(); - let normal_limit = normal_weight_limit() as usize; - let reset_check_weight = |tx, s, f| { - AllExtrinsicsLen::put(0); - let r = CheckWeight::(PhantomData).pre_dispatch(&1, CALL, tx, s); - if f { assert!(r.is_err()) } else { assert!(r.is_ok()) } - }; - - reset_check_weight(&normal, normal_limit - 1, false); - reset_check_weight(&normal, normal_limit, false); - reset_check_weight(&normal, normal_limit + 1, true); - - // Operational ones don't have this limit. - let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: Pays::Yes }; - reset_check_weight(&op, normal_limit, false); - reset_check_weight(&op, normal_limit + 100, false); - reset_check_weight(&op, 1024, false); - reset_check_weight(&op, 1025, true); - }) - } - - #[test] - fn signed_ext_check_era_should_work() { - new_test_ext().execute_with(|| { - // future - assert_eq!( - CheckEra::::from(Era::mortal(4, 2)).additional_signed().err().unwrap(), - InvalidTransaction::AncientBirthBlock.into(), - ); - - // correct - System::set_block_number(13); - >::insert(12, H256::repeat_byte(1)); - assert!(CheckEra::::from(Era::mortal(4, 12)).additional_signed().is_ok()); - }) - } - - #[test] - fn signed_ext_check_era_should_change_longevity() { - new_test_ext().execute_with(|| { - let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes }; - let len = 0_usize; - let ext = ( - CheckWeight::(PhantomData), - CheckEra::::from(Era::mortal(16, 256)), - ); - System::set_block_number(17); - >::insert(16, H256::repeat_byte(1)); - - assert_eq!(ext.validate(&1, CALL, &normal, len).unwrap().longevity, 15); - }) - } - - - #[test] - fn set_code_checks_works() { - struct CallInWasm(Vec); - - impl sp_core::traits::CallInWasm for CallInWasm { - fn call_in_wasm( - &self, - _: &[u8], - _: Option>, - _: &str, - _: &[u8], - _: &mut dyn sp_externalities::Externalities, - _: sp_core::traits::MissingHostFunctions, - ) -> Result, String> { - Ok(self.0.clone()) - } - } - - let test_data = vec![ - ("test", 1, 2, Err(Error::::SpecVersionNeedsToIncrease)), - ("test", 1, 1, Err(Error::::SpecVersionNeedsToIncrease)), - ("test2", 1, 1, Err(Error::::InvalidSpecName)), - ("test", 2, 1, Ok(())), - ("test", 0, 1, Err(Error::::SpecVersionNeedsToIncrease)), - ("test", 1, 0, Err(Error::::SpecVersionNeedsToIncrease)), - ]; - - for (spec_name, spec_version, impl_version, expected) in test_data.into_iter() { - let version = RuntimeVersion { - spec_name: spec_name.into(), - spec_version, - impl_version, - ..Default::default() - }; - let call_in_wasm = CallInWasm(version.encode()); - - let mut ext = new_test_ext(); - ext.register_extension(sp_core::traits::CallInWasmExt::new(call_in_wasm)); - ext.execute_with(|| { - let res = System::set_code( - RawOrigin::Root.into(), - vec![1, 2, 3, 4], - ); - - assert_eq!(expected.map_err(DispatchError::from), res); - }); - } - } - - #[test] - fn set_code_with_real_wasm_blob() { - let executor = substrate_test_runtime_client::new_native_executor(); - let mut ext = new_test_ext(); - ext.register_extension(sp_core::traits::CallInWasmExt::new(executor)); - ext.execute_with(|| { - System::set_block_number(1); - System::set_code( - RawOrigin::Root.into(), - substrate_test_runtime_client::runtime::WASM_BINARY.to_vec(), - ).unwrap(); - - assert_eq!( - System::events(), - vec![EventRecord { phase: Phase::Initialization, event: 102u16, topics: vec![] }], - ); - }); - } - - #[test] - fn runtime_upgraded_with_set_storage() { - let executor = substrate_test_runtime_client::new_native_executor(); - let mut ext = new_test_ext(); - ext.register_extension(sp_core::traits::CallInWasmExt::new(executor)); - ext.execute_with(|| { - System::set_storage( - RawOrigin::Root.into(), - vec![( - well_known_keys::CODE.to_vec(), - substrate_test_runtime_client::runtime::WASM_BINARY.to_vec() - )], - ).unwrap(); - }); - } - - #[test] - fn events_not_emitted_during_genesis() { - new_test_ext().execute_with(|| { - // Block Number is zero at genesis - assert!(System::block_number().is_zero()); - System::on_created_account(Default::default()); - assert!(System::events().is_empty()); - // Events will be emitted starting on block 1 - System::set_block_number(1); - System::on_created_account(Default::default()); - assert!(System::events().len() == 1); - }); - } -} diff --git a/frame/system/src/mock.rs b/frame/system/src/mock.rs new file mode 100644 index 0000000000000000000000000000000000000000..d7c4d1c9e7b20d6717e1e940c1ef1d391c01a460 --- /dev/null +++ b/frame/system/src/mock.rs @@ -0,0 +1,125 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use crate::*; +use sp_std::cell::RefCell; +use sp_core::H256; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + testing::Header, +}; +use frame_support::{ + impl_outer_origin, parameter_types, + weights::PostDispatchInfo, +}; + +impl_outer_origin! { + pub enum Origin for Test where system = super {} +} + +#[derive(Clone, Eq, PartialEq, Debug, Default)] +pub struct Test; + +parameter_types! { + pub const BlockHashCount: u64 = 10; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumExtrinsicWeight: Weight = 768; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub const MaximumBlockLength: u32 = 1024; + pub Version: RuntimeVersion = RuntimeVersion { + spec_name: sp_version::create_runtime_str!("test"), + impl_name: sp_version::create_runtime_str!("system-test"), + authoring_version: 1, + spec_version: 1, + impl_version: 1, + apis: sp_version::create_apis_vec!([]), + transaction_version: 1, + }; + pub const BlockExecutionWeight: Weight = 10; + pub const ExtrinsicBaseWeight: Weight = 5; + pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { + read: 10, + write: 100, + }; +} + +thread_local!{ + pub static KILLED: RefCell> = RefCell::new(vec![]); +} + +pub struct RecordKilled; +impl OnKilledAccount for RecordKilled { + fn on_killed_account(who: &u64) { KILLED.with(|r| r.borrow_mut().push(*who)) } +} + +#[derive(Debug, codec::Encode, codec::Decode)] +pub struct Call; + +impl Dispatchable for Call { + type Origin = Origin; + type Trait = (); + type Info = DispatchInfo; + type PostInfo = PostDispatchInfo; + fn dispatch(self, _origin: Self::Origin) + -> sp_runtime::DispatchResultWithInfo { + panic!("Do not use dummy implementation for dispatch."); + } +} + +impl Trait for Test { + type BaseCallFilter = (); + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = DbWeight; + type BlockExecutionWeight = BlockExecutionWeight; + type ExtrinsicBaseWeight = ExtrinsicBaseWeight; + type MaximumExtrinsicWeight = MaximumExtrinsicWeight; + type AvailableBlockRatio = AvailableBlockRatio; + type MaximumBlockLength = MaximumBlockLength; + type Version = Version; + type ModuleToIndex = (); + type AccountData = u32; + type OnNewAccount = (); + type OnKilledAccount = RecordKilled; + type SystemWeightInfo = (); +} + +pub type System = Module; +pub type SysEvent = ::Event; + +pub const CALL: &::Call = &Call; + +/// Create new externalities for `System` module tests. +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut ext: sp_io::TestExternalities = GenesisConfig::default().build_storage::().unwrap().into(); + // Add to each test the initial weight of a block + ext.execute_with(|| System::register_extra_weight_unchecked( + ::BlockExecutionWeight::get(), + DispatchClass::Mandatory + )); + ext +} diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index 43003d657e6b5e64c92e138153d01fe92f42161d..6e6284b57fdc3f78082dad2ebbbb7fadd604fdf6 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Module helpers for off-chain calls. //! @@ -184,7 +185,7 @@ impl, X> Signer let generic_public = C::GenericPublic::from(key); let public = generic_public.into(); let account_id = public.clone().into_account(); - Account::new(index, account_id, public.clone()) + Account::new(index, account_id, public) }) } } @@ -637,7 +638,7 @@ pub trait SignedPayload: Encode { mod tests { use super::*; use codec::Decode; - use crate::tests::{Test as TestRuntime, Call}; + use crate::mock::{Test as TestRuntime, Call}; use sp_core::offchain::{testing, TransactionPoolExt}; use sp_runtime::testing::{UintAuthorityId, TestSignature, TestXt}; diff --git a/frame/system/src/tests.rs b/frame/system/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..55286d951cc27384c92fd45663d5d202c3fe1e3a --- /dev/null +++ b/frame/system/src/tests.rs @@ -0,0 +1,424 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use crate::*; +use mock::{*, Origin}; +use sp_core::H256; +use sp_runtime::DispatchError; +use frame_support::weights::WithPostDispatchInfo; + +#[test] +fn origin_works() { + let o = Origin::from(RawOrigin::::Signed(1u64)); + let x: Result, Origin> = o.into(); + assert_eq!(x.unwrap(), RawOrigin::::Signed(1u64)); +} + +#[test] +fn stored_map_works() { + new_test_ext().execute_with(|| { + System::insert(&0, 42); + assert!(System::allow_death(&0)); + + System::inc_ref(&0); + assert!(!System::allow_death(&0)); + + System::insert(&0, 69); + assert!(!System::allow_death(&0)); + + System::dec_ref(&0); + assert!(System::allow_death(&0)); + + assert!(KILLED.with(|r| r.borrow().is_empty())); + System::kill_account(&0); + assert_eq!(KILLED.with(|r| r.borrow().clone()), vec![0u64]); + }); +} + +#[test] +fn deposit_event_should_work() { + new_test_ext().execute_with(|| { + System::initialize( + &1, + &[0u8; 32].into(), + &[0u8; 32].into(), + &Default::default(), + InitKind::Full, + ); + System::note_finished_extrinsics(); + System::deposit_event(SysEvent::CodeUpdated); + System::finalize(); + assert_eq!( + System::events(), + vec![ + EventRecord { + phase: Phase::Finalization, + event: SysEvent::CodeUpdated, + topics: vec![], + } + ] + ); + + System::initialize( + &2, + &[0u8; 32].into(), + &[0u8; 32].into(), + &Default::default(), + InitKind::Full, + ); + System::deposit_event(SysEvent::NewAccount(32)); + System::note_finished_initialize(); + System::deposit_event(SysEvent::KilledAccount(42)); + System::note_applied_extrinsic(&Ok(().into()), Default::default()); + System::note_applied_extrinsic( + &Err(DispatchError::BadOrigin.into()), + Default::default() + ); + System::note_finished_extrinsics(); + System::deposit_event(SysEvent::NewAccount(3)); + System::finalize(); + assert_eq!( + System::events(), + vec![ + EventRecord { + phase: Phase::Initialization, + event: SysEvent::NewAccount(32), + topics: vec![], + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: SysEvent::KilledAccount(42), + topics: vec![] + }, + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: SysEvent::ExtrinsicSuccess(Default::default()), + topics: vec![] + }, + EventRecord { + phase: Phase::ApplyExtrinsic(1), + event: SysEvent::ExtrinsicFailed( + DispatchError::BadOrigin.into(), + Default::default() + ), + topics: vec![] + }, + EventRecord { + phase: Phase::Finalization, + event: SysEvent::NewAccount(3), + topics: vec![] + }, + ] + ); + }); +} + +#[test] +fn deposit_event_uses_actual_weight() { + new_test_ext().execute_with(|| { + System::initialize( + &1, + &[0u8; 32].into(), + &[0u8; 32].into(), + &Default::default(), + InitKind::Full, + ); + System::note_finished_initialize(); + + let pre_info = DispatchInfo { + weight: 1000, + .. Default::default() + }; + System::note_applied_extrinsic( + &Ok(Some(300).into()), + pre_info, + ); + System::note_applied_extrinsic( + &Ok(Some(1000).into()), + pre_info, + ); + System::note_applied_extrinsic( + // values over the pre info should be capped at pre dispatch value + &Ok(Some(1200).into()), + pre_info, + ); + System::note_applied_extrinsic( + &Err(DispatchError::BadOrigin.with_weight(999)), + pre_info, + ); + + assert_eq!( + System::events(), + vec![ + EventRecord { + phase: Phase::ApplyExtrinsic(0), + event: SysEvent::ExtrinsicSuccess( + DispatchInfo { + weight: 300, + .. Default::default() + }, + ), + topics: vec![] + }, + EventRecord { + phase: Phase::ApplyExtrinsic(1), + event: SysEvent::ExtrinsicSuccess( + DispatchInfo { + weight: 1000, + .. Default::default() + }, + ), + topics: vec![] + }, + EventRecord { + phase: Phase::ApplyExtrinsic(2), + event: SysEvent::ExtrinsicSuccess( + DispatchInfo { + weight: 1000, + .. Default::default() + }, + ), + topics: vec![] + }, + EventRecord { + phase: Phase::ApplyExtrinsic(3), + event: SysEvent::ExtrinsicFailed( + DispatchError::BadOrigin.into(), + DispatchInfo { + weight: 999, + .. Default::default() + }, + ), + topics: vec![] + }, + ] + ); + }); +} + +#[test] +fn deposit_event_topics() { + new_test_ext().execute_with(|| { + const BLOCK_NUMBER: u64 = 1; + + System::initialize( + &BLOCK_NUMBER, + &[0u8; 32].into(), + &[0u8; 32].into(), + &Default::default(), + InitKind::Full, + ); + System::note_finished_extrinsics(); + + let topics = vec![ + H256::repeat_byte(1), + H256::repeat_byte(2), + H256::repeat_byte(3), + ]; + + // We deposit a few events with different sets of topics. + System::deposit_event_indexed(&topics[0..3], SysEvent::NewAccount(1)); + System::deposit_event_indexed(&topics[0..1], SysEvent::NewAccount(2)); + System::deposit_event_indexed(&topics[1..2], SysEvent::NewAccount(3)); + + System::finalize(); + + // Check that topics are reflected in the event record. + assert_eq!( + System::events(), + vec![ + EventRecord { + phase: Phase::Finalization, + event: SysEvent::NewAccount(1), + topics: topics[0..3].to_vec(), + }, + EventRecord { + phase: Phase::Finalization, + event: SysEvent::NewAccount(2), + topics: topics[0..1].to_vec(), + }, + EventRecord { + phase: Phase::Finalization, + event: SysEvent::NewAccount(3), + topics: topics[1..2].to_vec(), + } + ] + ); + + // Check that the topic-events mapping reflects the deposited topics. + // Note that these are indexes of the events. + assert_eq!( + System::event_topics(&topics[0]), + vec![(BLOCK_NUMBER, 0), (BLOCK_NUMBER, 1)], + ); + assert_eq!( + System::event_topics(&topics[1]), + vec![(BLOCK_NUMBER, 0), (BLOCK_NUMBER, 2)], + ); + assert_eq!( + System::event_topics(&topics[2]), + vec![(BLOCK_NUMBER, 0)], + ); + }); +} + +#[test] +fn prunes_block_hash_mappings() { + new_test_ext().execute_with(|| { + // simulate import of 15 blocks + for n in 1..=15 { + System::initialize( + &n, + &[n as u8 - 1; 32].into(), + &[0u8; 32].into(), + &Default::default(), + InitKind::Full, + ); + + System::finalize(); + } + + // first 5 block hashes are pruned + for n in 0..5 { + assert_eq!( + System::block_hash(n), + H256::zero(), + ); + } + + // the remaining 10 are kept + for n in 5..15 { + assert_eq!( + System::block_hash(n), + [n as u8; 32].into(), + ); + } + }) +} + +#[test] +fn set_code_checks_works() { + struct CallInWasm(Vec); + + impl sp_core::traits::CallInWasm for CallInWasm { + fn call_in_wasm( + &self, + _: &[u8], + _: Option>, + _: &str, + _: &[u8], + _: &mut dyn sp_externalities::Externalities, + _: sp_core::traits::MissingHostFunctions, + ) -> Result, String> { + Ok(self.0.clone()) + } + } + + let test_data = vec![ + ("test", 1, 2, Err(Error::::SpecVersionNeedsToIncrease)), + ("test", 1, 1, Err(Error::::SpecVersionNeedsToIncrease)), + ("test2", 1, 1, Err(Error::::InvalidSpecName)), + ("test", 2, 1, Ok(())), + ("test", 0, 1, Err(Error::::SpecVersionNeedsToIncrease)), + ("test", 1, 0, Err(Error::::SpecVersionNeedsToIncrease)), + ]; + + for (spec_name, spec_version, impl_version, expected) in test_data.into_iter() { + let version = RuntimeVersion { + spec_name: spec_name.into(), + spec_version, + impl_version, + ..Default::default() + }; + let call_in_wasm = CallInWasm(version.encode()); + + let mut ext = new_test_ext(); + ext.register_extension(sp_core::traits::CallInWasmExt::new(call_in_wasm)); + ext.execute_with(|| { + let res = System::set_code( + RawOrigin::Root.into(), + vec![1, 2, 3, 4], + ); + + assert_eq!(expected.map_err(DispatchError::from), res); + }); + } +} + +#[test] +fn set_code_with_real_wasm_blob() { + let executor = substrate_test_runtime_client::new_native_executor(); + let mut ext = new_test_ext(); + ext.register_extension(sp_core::traits::CallInWasmExt::new(executor)); + ext.execute_with(|| { + System::set_block_number(1); + System::set_code( + RawOrigin::Root.into(), + substrate_test_runtime_client::runtime::wasm_binary_unwrap().to_vec(), + ).unwrap(); + + assert_eq!( + System::events(), + vec![EventRecord { + phase: Phase::Initialization, + event: SysEvent::CodeUpdated, + topics: vec![], + }], + ); + }); +} + +#[test] +fn runtime_upgraded_with_set_storage() { + let executor = substrate_test_runtime_client::new_native_executor(); + let mut ext = new_test_ext(); + ext.register_extension(sp_core::traits::CallInWasmExt::new(executor)); + ext.execute_with(|| { + System::set_storage( + RawOrigin::Root.into(), + vec![( + well_known_keys::CODE.to_vec(), + substrate_test_runtime_client::runtime::wasm_binary_unwrap().to_vec() + )], + ).unwrap(); + }); +} + +#[test] +fn events_not_emitted_during_genesis() { + new_test_ext().execute_with(|| { + // Block Number is zero at genesis + assert!(System::block_number().is_zero()); + System::on_created_account(Default::default()); + assert!(System::events().is_empty()); + // Events will be emitted starting on block 1 + System::set_block_number(1); + System::on_created_account(Default::default()); + assert!(System::events().len() == 1); + }); +} + +#[test] +fn ensure_one_of_works() { + fn ensure_root_or_signed(o: RawOrigin) -> Result, Origin> { + EnsureOneOf::, EnsureSigned>::try_origin(o.into()) + } + + assert_eq!(ensure_root_or_signed(RawOrigin::Root).unwrap(), Either::Left(())); + assert_eq!(ensure_root_or_signed(RawOrigin::Signed(0)).unwrap(), Either::Right(0)); + assert!(ensure_root_or_signed(RawOrigin::None).is_err()) +} diff --git a/frame/system/src/weights.rs b/frame/system/src/weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..93295093c4fb88aaff70c259d889a6ce1e352a04 --- /dev/null +++ b/frame/system/src/weights.rs @@ -0,0 +1,76 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +use codec::{Encode, Decode}; +use frame_support::weights::{Weight, DispatchClass}; +use sp_runtime::RuntimeDebug; + +/// An object to track the currently used extrinsic weight in a block. +#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode)] +pub struct ExtrinsicsWeight { + normal: Weight, + operational: Weight, +} + +impl ExtrinsicsWeight { + /// Returns the total weight consumed by all extrinsics in the block. + pub fn total(&self) -> Weight { + self.normal.saturating_add(self.operational) + } + + /// Add some weight of a specific dispatch class, saturating at the numeric bounds of `Weight`. + pub fn add(&mut self, weight: Weight, class: DispatchClass) { + let value = self.get_mut(class); + *value = value.saturating_add(weight); + } + + /// Try to add some weight of a specific dispatch class, returning Err(()) if overflow would + /// occur. + pub fn checked_add(&mut self, weight: Weight, class: DispatchClass) -> Result<(), ()> { + let value = self.get_mut(class); + *value = value.checked_add(weight).ok_or(())?; + Ok(()) + } + + /// Subtract some weight of a specific dispatch class, saturating at the numeric bounds of + /// `Weight`. + pub fn sub(&mut self, weight: Weight, class: DispatchClass) { + let value = self.get_mut(class); + *value = value.saturating_sub(weight); + } + + /// Get the current weight of a specific dispatch class. + pub fn get(&self, class: DispatchClass) -> Weight { + match class { + DispatchClass::Operational => self.operational, + DispatchClass::Normal | DispatchClass::Mandatory => self.normal, + } + } + + /// Get a mutable reference to the current weight of a specific dispatch class. + fn get_mut(&mut self, class: DispatchClass) -> &mut Weight { + match class { + DispatchClass::Operational => &mut self.operational, + DispatchClass::Normal | DispatchClass::Mandatory => &mut self.normal, + } + } + + /// Set the weight of a specific dispatch class. + pub fn put(&mut self, new: Weight, class: DispatchClass) { + *self.get_mut(class) = new; + } +} diff --git a/frame/timestamp/Cargo.toml b/frame/timestamp/Cargo.toml index 7691421bbfed16b4726d1eb1f3752fe8868026d8..db8e488dd5d9648f15368b9303089b72c36d8007 100644 --- a/frame/timestamp/Cargo.toml +++ b/frame/timestamp/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-timestamp" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME Timestamp Module" @@ -15,20 +15,20 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io", optional = true } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../primitives/timestamp" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io", optional = true } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/inherents" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/timestamp" } impl-trait-for-tuples = "0.1.3" [dev-dependencies] -sp-io ={ version = "2.0.0-dev", path = "../../primitives/io" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-rc6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } [features] default = ["std"] diff --git a/frame/timestamp/README.md b/frame/timestamp/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7cdbdf0e79b13856b78d5cc00a7abc35d7287df8 --- /dev/null +++ b/frame/timestamp/README.md @@ -0,0 +1,74 @@ +# Timestamp Module + +The Timestamp module provides functionality to get and set the on-chain time. + +- [`timestamp::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) +- [`Module`](./struct.Module.html) + +## Overview + +The Timestamp module allows the validators to set and validate a timestamp with each block. + +It uses inherents for timestamp data, which is provided by the block author and validated/verified +by other validators. The timestamp can be set only once per block and must be set each block. +There could be a constraint on how much time must pass before setting the new timestamp. + +**NOTE:** The Timestamp module is the recommended way to query the on-chain time instead of using +an approach based on block numbers. The block number based time measurement can cause issues +because of cumulative calculation errors and hence should be avoided. + +## Interface + +### Dispatchable Functions + +* `set` - Sets the current time. + +### Public functions + +* `get` - Gets the current time for the current block. If this function is called prior to +setting the timestamp, it will return the timestamp of the previous block. + +### Trait Getters + +* `MinimumPeriod` - Gets the minimum (and advised) period between blocks for the chain. + +## Usage + +The following example shows how to use the Timestamp module in your custom module to query the current timestamp. + +### Prerequisites + +Import the Timestamp module into your custom module and derive the module configuration +trait from the timestamp trait. + +### Get current timestamp + +```rust +use frame_support::{decl_module, dispatch}; +use frame_system::ensure_signed; + +pub trait Trait: timestamp::Trait {} + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + #[weight = 0] + pub fn get_time(origin) -> dispatch::DispatchResult { + let _sender = ensure_signed(origin)?; + let _now = >::get(); + Ok(()) + } + } +} +``` + +### Example from the FRAME + +The [Session module](https://github.com/paritytech/substrate/blob/master/frame/session/src/lib.rs) uses +the Timestamp module for session management. + +## Related Modules + +* [Session](../pallet_session/index.html) + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/timestamp/src/benchmarking.rs b/frame/timestamp/src/benchmarking.rs index c468bf82fba6f9570c471ce7aa615f2658db3389..1cd0f15ca01b936956694f1ade3e56c0b6f4859e 100644 --- a/frame/timestamp/src/benchmarking.rs +++ b/frame/timestamp/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Timestamp pallet benchmarking. @@ -22,7 +23,7 @@ use super::*; use sp_std::prelude::*; use frame_system::RawOrigin; use frame_support::{ensure, traits::OnFinalize}; -use frame_benchmarking::benchmarks; +use frame_benchmarking::{benchmarks, TrackedStorageKey}; use crate::Module as Timestamp; @@ -33,6 +34,13 @@ benchmarks! { set { let t in 1 .. MAX_TIME; + // Ignore write to `DidUpdate` since it transient. + let did_update_key = crate::DidUpdate::hashed_key().to_vec(); + frame_benchmarking::benchmarking::add_to_whitelist(TrackedStorageKey { + key: did_update_key, + has_been_read: false, + has_been_written: true, + }); }: _(RawOrigin::None, t.into()) verify { ensure!(Timestamp::::now() == t.into(), "Time was not set."); @@ -42,6 +50,9 @@ benchmarks! { let t in 1 .. MAX_TIME; Timestamp::::set(RawOrigin::None.into(), t.into())?; ensure!(DidUpdate::exists(), "Time was not set."); + // Ignore read/write to `DidUpdate` since it is transient. + let did_update_key = crate::DidUpdate::hashed_key().to_vec(); + frame_benchmarking::benchmarking::add_to_whitelist(did_update_key.into()); }: { Timestamp::::on_finalize(t.into()); } verify { ensure!(!DidUpdate::exists(), "Time was not removed."); diff --git a/frame/timestamp/src/default_weights.rs b/frame/timestamp/src/default_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..726b3444e2532eec6b1cc9df9305ea4f95eb3548 --- /dev/null +++ b/frame/timestamp/src/default_weights.rs @@ -0,0 +1,35 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +#![allow(unused_parens)] + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +impl crate::WeightInfo for () { + // WARNING! Some components were not used: ["t"] + fn set() -> Weight { + (9133000 as Weight) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + // WARNING! Some components were not used: ["t"] + fn on_finalize() -> Weight { + (5915000 as Weight) + } +} diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index cb27fc711ff639c2e779a49d3be954a43ddc4725..d74a94cb9201b3b786691f86a3d71a22bc6d6e4a 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Timestamp Module //! @@ -63,7 +64,7 @@ //! ``` //! use frame_support::{decl_module, dispatch}; //! # use pallet_timestamp as timestamp; -//! use frame_system::{self as system, ensure_signed}; +//! use frame_system::ensure_signed; //! //! pub trait Trait: timestamp::Trait {} //! @@ -92,6 +93,7 @@ #![cfg_attr(not(feature = "std"), no_std)] mod benchmarking; +mod default_weights; use sp_std::{result, cmp}; use sp_inherents::{ProvideInherent, InherentData, InherentIdentifier}; @@ -114,6 +116,11 @@ use sp_timestamp::{ OnTimestampSet, }; +pub trait WeightInfo { + fn set() -> Weight; + fn on_finalize() -> Weight; +} + /// The module configuration trait pub trait Trait: frame_system::Trait { /// Type used for expressing timestamp. @@ -128,6 +135,9 @@ pub trait Trait: frame_system::Trait { /// work with this to determine a sensible block time. e.g. For Aura, it will be double this /// period on default settings. type MinimumPeriod: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_module! { @@ -152,12 +162,9 @@ decl_module! { /// - `O(T)` where `T` complexity of `on_timestamp_set` /// - 1 storage read and 1 storage mutation (codec `O(1)`). (because of `DidUpdate::take` in `on_finalize`) /// - 1 event handler `on_timestamp_set` `O(T)`. - /// - Benchmark: 7.678 (min squares analysis) - /// - NOTE: This benchmark was done for a runtime with insignificant `on_timestamp_set` handlers. - /// New benchmarking is needed when adding new handlers. /// # #[weight = ( - T::DbWeight::get().reads_writes(2, 1) + 8_000_000, + T::WeightInfo::set(), DispatchClass::Mandatory )] fn set(origin, #[compact] now: T::Moment) { @@ -177,13 +184,12 @@ decl_module! { /// dummy `on_initialize` to return the weight used in `on_finalize`. fn on_initialize() -> Weight { // weight of `on_finalize` - 5_000_000 + T::WeightInfo::on_finalize() } /// # /// - `O(1)` /// - 1 storage deletion (codec `O(1)`). - /// - Benchmark: 4.928 µs (min squares analysis) /// # fn on_finalize() { assert!(::DidUpdate::take(), "Timestamp must be updated once in the block"); @@ -301,7 +307,7 @@ mod tests { } impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } #[derive(Clone, Eq, PartialEq)] @@ -313,6 +319,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -328,6 +335,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -335,6 +343,7 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { pub const MinimumPeriod: u64 = 5; @@ -343,6 +352,7 @@ mod tests { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } type Timestamp = Module; @@ -350,7 +360,7 @@ mod tests { fn timestamp_works() { new_test_ext().execute_with(|| { Timestamp::set_timestamp(42); - assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); + assert_ok!(Timestamp::set(Origin::none(), 69)); assert_eq!(Timestamp::now(), 69); }); } @@ -360,8 +370,8 @@ mod tests { fn double_timestamp_should_fail() { new_test_ext().execute_with(|| { Timestamp::set_timestamp(42); - assert_ok!(Timestamp::dispatch(Call::set(69), Origin::NONE)); - let _ = Timestamp::dispatch(Call::set(70), Origin::NONE); + assert_ok!(Timestamp::set(Origin::none(), 69)); + let _ = Timestamp::set(Origin::none(), 70); }); } @@ -370,7 +380,7 @@ mod tests { fn block_period_minimum_enforced() { new_test_ext().execute_with(|| { Timestamp::set_timestamp(42); - let _ = Timestamp::dispatch(Call::set(46), Origin::NONE); + let _ = Timestamp::set(Origin::none(), 46); }); } } diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index a969f3008688435c0401c0d91eb0988919d90a03..e0381b20aa472ffe7a4d9ded2923b70c2e2975c7 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/frame/transaction-payment/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-transaction-payment" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet to manage transaction payments" @@ -12,26 +12,31 @@ description = "FRAME pallet to manage transaction payments" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-dev", default-features = false, path = "./rpc/runtime-api" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +serde = { version = "1.0.101", optional = true } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-rc6", default-features = false, path = "./rpc/runtime-api" } +smallvec = "1.4.1" +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io", default-features = false } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core", default-features = false } [dev-dependencies] -sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } -sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +sp-storage = { version = "2.0.0-rc6", path = "../../primitives/storage" } [features] default = ["std"] std = [ + "serde", "codec/std", "sp-std/std", "sp-runtime/std", "frame-support/std", "frame-system/std", - "pallet-transaction-payment-rpc-runtime-api/std" + "pallet-transaction-payment-rpc-runtime-api/std", + "sp-io/std", + "sp-core/std", ] diff --git a/frame/transaction-payment/README.md b/frame/transaction-payment/README.md new file mode 100644 index 0000000000000000000000000000000000000000..10ad9579e92b7e66b8a87af0e9962cfc4ee77ae8 --- /dev/null +++ b/frame/transaction-payment/README.md @@ -0,0 +1,16 @@ +# Transaction Payment Module + +This module provides the basic logic needed to pay the absolute minimum amount needed for a +transaction to be included. This includes: + - _weight fee_: A fee proportional to amount of weight a transaction consumes. + - _length fee_: A fee proportional to the encoded length of the transaction. + - _tip_: An optional tip. Tip increases the priority of the transaction, giving it a higher + chance to be included by the transaction queue. + +Additionally, this module allows one to configure: + - The mapping between one unit of weight to one unit of fee via [`Trait::WeightToFee`]. + - A means of updating the fee for the next block, via defining a multiplier, based on the + final state of the chain at the end of the previous block. This can be configured via + [`Trait::FeeMultiplierUpdate`] + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/transaction-payment/rpc/Cargo.toml b/frame/transaction-payment/rpc/Cargo.toml index 35f421915af3975a6ad820523a45207a564af327..d3d03dd1a4d0ca7833cbc1aa73f20d21b81026ef 100644 --- a/frame/transaction-payment/rpc/Cargo.toml +++ b/frame/transaction-payment/rpc/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-transaction-payment-rpc" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "RPC interface for the transaction payment module." @@ -12,14 +12,14 @@ description = "RPC interface for the transaction payment module." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0" } -jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.5" -jsonrpc-derive = "14.0.3" -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-rpc = { version = "2.0.0-dev", path = "../../../primitives/rpc" } +codec = { package = "parity-scale-codec", version = "1.3.1" } +jsonrpc-core = "14.2.0" +jsonrpc-core-client = "14.2.0" +jsonrpc-derive = "14.2.1" +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-rpc = { version = "2.0.0-rc6", path = "../../../primitives/rpc" } serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-dev", path = "./runtime-api" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +pallet-transaction-payment-rpc-runtime-api = { version = "2.0.0-rc6", path = "./runtime-api" } diff --git a/frame/transaction-payment/rpc/README.md b/frame/transaction-payment/rpc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..21a8a7d37cae0a14d68052b6a07482e731e3b784 --- /dev/null +++ b/frame/transaction-payment/rpc/README.md @@ -0,0 +1,3 @@ +RPC interface for the transaction payment module. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/transaction-payment/rpc/runtime-api/Cargo.toml b/frame/transaction-payment/rpc/runtime-api/Cargo.toml index 1170e043eea84dccf37aef9ba1bd9bb35ad7bb08..42b9fb9e64d25c2d48b6fb923310a5214eacac61 100644 --- a/frame/transaction-payment/rpc/runtime-api/Cargo.toml +++ b/frame/transaction-payment/rpc/runtime-api/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-transaction-payment-rpc-runtime-api" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "RPC runtime API for transaction payment FRAME pallet" @@ -13,11 +13,11 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/api" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../../../support" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../../../../primitives/api" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../../../support" } [dev-dependencies] serde_json = "1.0.41" diff --git a/frame/transaction-payment/rpc/runtime-api/README.md b/frame/transaction-payment/rpc/runtime-api/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e453d9a3b7c8a0ff91baa003a5d3656293b28f5b --- /dev/null +++ b/frame/transaction-payment/rpc/runtime-api/README.md @@ -0,0 +1,3 @@ +Runtime API definition for transaction payment module. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/transaction-payment/rpc/runtime-api/src/lib.rs b/frame/transaction-payment/rpc/runtime-api/src/lib.rs index 77b6e3b45464e5bc7837ce619a43f7d283cc4bb7..5575f8f7d09508e65583f45b6792f90c4bf3bfb5 100644 --- a/frame/transaction-payment/rpc/runtime-api/src/lib.rs +++ b/frame/transaction-payment/rpc/runtime-api/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Runtime API definition for transaction payment module. @@ -25,7 +26,7 @@ use codec::{Encode, Codec, Decode}; use serde::{Serialize, Deserialize, Serializer, Deserializer}; use sp_runtime::traits::{MaybeDisplay, MaybeFromStr}; -/// Some information related to a dispatchable that can be queried from the runtime. +/// Information related to a dispatchable's class, weight, and fee that can be queried from the runtime. #[derive(Eq, PartialEq, Encode, Decode, Default)] #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] @@ -34,8 +35,8 @@ pub struct RuntimeDispatchInfo { pub weight: Weight, /// Class of this dispatch. pub class: DispatchClass, - /// The partial inclusion fee of this dispatch. This does not include tip or anything else which - /// is dependent on the signature (aka. depends on a `SignedExtension`). + /// The inclusion fee of this dispatch. This does not include a tip or anything else that + /// depends on the signature (i.e. depends on a `SignedExtension`). #[cfg_attr(feature = "std", serde(bound(serialize = "Balance: std::fmt::Display")))] #[cfg_attr(feature = "std", serde(serialize_with = "serialize_as_string"))] #[cfg_attr(feature = "std", serde(bound(deserialize = "Balance: std::str::FromStr")))] @@ -55,11 +56,10 @@ fn deserialize_from_string<'de, D: Deserializer<'de>, T: std::str::FromStr>(dese } sp_api::decl_runtime_apis! { - pub trait TransactionPaymentApi where + pub trait TransactionPaymentApi where Balance: Codec + MaybeDisplay + MaybeFromStr, - Extrinsic: Codec, { - fn query_info(uxt: Extrinsic, len: u32) -> RuntimeDispatchInfo; + fn query_info(uxt: Block::Extrinsic, len: u32) -> RuntimeDispatchInfo; } } diff --git a/frame/transaction-payment/rpc/src/lib.rs b/frame/transaction-payment/rpc/src/lib.rs index 945b0119d7236dd4108d84978fb017b736f318cf..5043f0257fc36a08bb64f22430753e28414cd892 100644 --- a/frame/transaction-payment/rpc/src/lib.rs +++ b/frame/transaction-payment/rpc/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! RPC interface for the transaction payment module. @@ -68,14 +69,13 @@ impl From for i64 { } } -impl TransactionPaymentApi<::Hash, RuntimeDispatchInfo> - for TransactionPayment +impl TransactionPaymentApi<::Hash, RuntimeDispatchInfo> + for TransactionPayment where Block: BlockT, C: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, - C::Api: TransactionPaymentRuntimeApi, + C::Api: TransactionPaymentRuntimeApi, Balance: Codec + MaybeDisplay + MaybeFromStr, - Extrinsic: Codec + Send + Sync + 'static, { fn query_info( &self, @@ -90,7 +90,7 @@ where let encoded_len = encoded_xt.len() as u32; - let uxt: Extrinsic = Decode::decode(&mut &*encoded_xt).map_err(|e| RpcError { + let uxt: Block::Extrinsic = Decode::decode(&mut &*encoded_xt).map_err(|e| RpcError { code: ErrorCode::ServerError(Error::DecodeError.into()), message: "Unable to query dispatch info.".into(), data: Some(format!("{:?}", e).into()), diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index f6334c658ac4c3cb26873b1e05b316707f59ac82..244b4280ade08f8daa638d599e8e038b34cbc08f 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Transaction Payment Module //! @@ -36,28 +37,181 @@ use codec::{Encode, Decode}; use frame_support::{ decl_storage, decl_module, traits::{Currency, Get, OnUnbalanced, ExistenceRequirement, WithdrawReason, Imbalance}, - weights::{Weight, DispatchInfo, PostDispatchInfo, GetDispatchInfo, Pays}, + weights::{ + Weight, DispatchInfo, PostDispatchInfo, GetDispatchInfo, Pays, WeightToFeePolynomial, + WeightToFeeCoefficient, + }, dispatch::DispatchResult, }; use sp_runtime::{ - Fixed128, + FixedU128, FixedPointNumber, FixedPointOperand, Perquintill, RuntimeDebug, transaction_validity::{ TransactionPriority, ValidTransaction, InvalidTransaction, TransactionValidityError, TransactionValidity, }, traits::{ Zero, Saturating, SignedExtension, SaturatedConversion, Convert, Dispatchable, - DispatchInfoOf, PostDispatchInfoOf, UniqueSaturatedFrom, UniqueSaturatedInto, + DispatchInfoOf, PostDispatchInfoOf, }, }; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; -type Multiplier = Fixed128; +/// Fee multiplier. +pub type Multiplier = FixedU128; + type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +/// A struct to update the weight multiplier per block. It implements `Convert`, meaning that it can convert the previous multiplier to the next one. This should +/// be called on `on_finalize` of a block, prior to potentially cleaning the weight data from the +/// system module. +/// +/// given: +/// s = previous block weight +/// s'= ideal block weight +/// m = maximum block weight +/// diff = (s - s')/m +/// v = 0.00001 +/// t1 = (v * diff) +/// t2 = (v * diff)^2 / 2 +/// then: +/// next_multiplier = prev_multiplier * (1 + t1 + t2) +/// +/// Where `(s', v)` must be given as the `Get` implementation of the `T` generic type. Moreover, `M` +/// must provide the minimum allowed value for the multiplier. Note that a runtime should ensure +/// with tests that the combination of this `M` and `V` is not such that the multiplier can drop to +/// zero and never recover. +/// +/// note that `s'` is interpreted as a portion in the _normal transaction_ capacity of the block. +/// For example, given `s' == 0.25` and `AvailableBlockRatio = 0.75`, then the target fullness is +/// _0.25 of the normal capacity_ and _0.1875 of the entire block_. +/// +/// This implementation implies the bound: +/// - `v ≤ p / k * (s − s')` +/// - or, solving for `p`: `p >= v * k * (s - s')` +/// +/// where `p` is the amount of change over `k` blocks. +/// +/// Hence: +/// - in a fully congested chain: `p >= v * k * (1 - s')`. +/// - in an empty chain: `p >= v * k * (-s')`. +/// +/// For example, when all blocks are full and there are 28800 blocks per day (default in `substrate-node`) +/// and v == 0.00001, s' == 0.1875, we'd have: +/// +/// p >= 0.00001 * 28800 * 0.8125 +/// p >= 0.234 +/// +/// Meaning that fees can change by around ~23% per day, given extreme congestion. +/// +/// More info can be found at: +/// https://w3f-research.readthedocs.io/en/latest/polkadot/Token%20Economics.html +pub struct TargetedFeeAdjustment(sp_std::marker::PhantomData<(T, S, V, M)>); + +/// Something that can convert the current multiplier to the next one. +pub trait MultiplierUpdate: Convert { + /// Minimum multiplier + fn min() -> Multiplier; + /// Target block saturation level + fn target() -> Perquintill; + /// Variability factor + fn variability() -> Multiplier; +} + +impl MultiplierUpdate for () { + fn min() -> Multiplier { + Default::default() + } + fn target() -> Perquintill { + Default::default() + } + fn variability() -> Multiplier { + Default::default() + } +} + +impl MultiplierUpdate for TargetedFeeAdjustment + where T: frame_system::Trait, S: Get, V: Get, M: Get, +{ + fn min() -> Multiplier { + M::get() + } + fn target() -> Perquintill { + S::get() + } + fn variability() -> Multiplier { + V::get() + } +} + +impl Convert for TargetedFeeAdjustment + where T: frame_system::Trait, S: Get, V: Get, M: Get, +{ + fn convert(previous: Multiplier) -> Multiplier { + // Defensive only. The multiplier in storage should always be at most positive. Nonetheless + // we recover here in case of errors, because any value below this would be stale and can + // never change. + let min_multiplier = M::get(); + let previous = previous.max(min_multiplier); + + // the computed ratio is only among the normal class. + let normal_max_weight = + ::AvailableBlockRatio::get() * + ::MaximumBlockWeight::get(); + let normal_block_weight = + >::block_weight() + .get(frame_support::weights::DispatchClass::Normal) + .min(normal_max_weight); + + let s = S::get(); + let v = V::get(); + + let target_weight = (s * normal_max_weight) as u128; + let block_weight = normal_block_weight as u128; + + // determines if the first_term is positive + let positive = block_weight >= target_weight; + let diff_abs = block_weight.max(target_weight) - block_weight.min(target_weight); + + // defensive only, a test case assures that the maximum weight diff can fit in Multiplier + // without any saturation. + let diff = Multiplier::saturating_from_rational(diff_abs, normal_max_weight.max(1)); + let diff_squared = diff.saturating_mul(diff); + + let v_squared_2 = v.saturating_mul(v) / Multiplier::saturating_from_integer(2); + + let first_term = v.saturating_mul(diff); + let second_term = v_squared_2.saturating_mul(diff_squared); + + if positive { + let excess = first_term.saturating_add(second_term).saturating_mul(previous); + previous.saturating_add(excess).max(min_multiplier) + } else { + // Defensive-only: first_term > second_term. Safe subtraction. + let negative = first_term.saturating_sub(second_term).saturating_mul(previous); + previous.saturating_sub(negative).max(min_multiplier) + } + } +} + +/// Storage releases of the module. +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug)] +enum Releases { + /// Original version of the module. + V1Ancient, + /// One that bumps the usage to FixedU128 from FixedI128. + V2, +} + +impl Default for Releases { + fn default() -> Self { + Releases::V1Ancient + } +} + pub trait Trait: frame_system::Trait { /// The currency type in which fees will be paid. type Currency: Currency + Send + Sync; @@ -71,15 +225,17 @@ pub trait Trait: frame_system::Trait { type TransactionByteFee: Get>; /// Convert a weight value into a deductible fee based on the currency type. - type WeightToFee: Convert>; + type WeightToFee: WeightToFeePolynomial>; /// Update the multiplier of the next block, based on the previous block's weight. - type FeeMultiplierUpdate: Convert; + type FeeMultiplierUpdate: MultiplierUpdate; } decl_storage! { trait Store for Module as TransactionPayment { - pub NextFeeMultiplier get(fn next_fee_multiplier): Multiplier = Multiplier::from_parts(0); + pub NextFeeMultiplier get(fn next_fee_multiplier): Multiplier = Multiplier::saturating_from_integer(1); + + StorageVersion build(|_: &GenesisConfig| Releases::V2): Releases; } } @@ -88,19 +244,65 @@ decl_module! { /// The fee to be paid for making a transaction; the per-byte portion. const TransactionByteFee: BalanceOf = T::TransactionByteFee::get(); + /// The polynomial that is applied in order to derive fee from weight. + const WeightToFee: Vec>> = + T::WeightToFee::polynomial().to_vec(); + fn on_finalize() { NextFeeMultiplier::mutate(|fm| { - *fm = T::FeeMultiplierUpdate::convert(*fm) + *fm = T::FeeMultiplierUpdate::convert(*fm); }); } + + fn integrity_test() { + // given weight == u64, we build multipliers from `diff` of two weight values, which can + // at most be MaximumBlockWeight. Make sure that this can fit in a multiplier without + // loss. + use sp_std::convert::TryInto; + assert!( + ::max_value() >= + Multiplier::checked_from_integer( + ::MaximumBlockWeight::get().try_into().unwrap() + ).unwrap(), + ); + + // This is the minimum value of the multiplier. Make sure that if we collapse to this + // value, we can recover with a reasonable amount of traffic. For this test we assert + // that if we collapse to minimum, the trend will be positive with a weight value + // which is 1% more than the target. + let min_value = T::FeeMultiplierUpdate::min(); + let mut target = + T::FeeMultiplierUpdate::target() * + (T::AvailableBlockRatio::get() * T::MaximumBlockWeight::get()); + + // add 1 percent; + let addition = target / 100; + if addition == 0 { + // this is most likely because in a test setup we set everything to (). + return; + } + target += addition; + + sp_io::TestExternalities::new_empty().execute_with(|| { + >::set_block_limits(target, 0); + let next = T::FeeMultiplierUpdate::convert(min_value); + assert!(next > min_value, "The minimum bound of the multiplier is too low. When \ + block saturation is more than target by 1% and multiplier is minimal then \ + the multiplier doesn't increase." + ); + }) + } } } -impl Module { +impl Module where + BalanceOf: FixedPointOperand +{ /// Query the data that we know about the fee of a given `call`. /// - /// As this module is not and cannot be aware of the internals of a signed extension, it only - /// interprets them as some encoded value and takes their length into account. + /// This module is not and cannot be aware of the internals of a signed extension, for example + /// a tip. It only interprets the extrinsic as some encoded value and accounts for its weight + /// and length, the runtime's extrinsic base weight, and the current fee multiplier. /// /// All dispatchables must be annotated with weight and will have some fee info. This function /// always returns. @@ -129,17 +331,24 @@ impl Module { /// Compute the final fee value for a particular transaction. /// /// The final fee is composed of: - /// - _base_fee_: This is the minimum amount a user pays for a transaction. - /// - _len_fee_: This is the amount paid merely to pay for size of the transaction. - /// - _weight_fee_: This amount is computed based on the weight of the transaction. Unlike - /// size-fee, this is not input dependent and reflects the _complexity_ of the execution - /// and the time it consumes. - /// - _targeted_fee_adjustment_: This is a multiplier that can tune the final fee based on + /// - `base_fee`: This is the minimum amount a user pays for a transaction. It is declared + /// as a base _weight_ in the runtime and converted to a fee using `WeightToFee`. + /// - `len_fee`: The length fee, the amount paid for the encoded length (in bytes) of the + /// transaction. + /// - `weight_fee`: This amount is computed based on the weight of the transaction. Weight + /// accounts for the execution time of a transaction. + /// - `targeted_fee_adjustment`: This is a multiplier that can tune the final fee based on /// the congestion of the network. - /// - (optional) _tip_: if included in the transaction, it will be added on top. Only signed - /// transactions can have a tip. + /// - (Optional) `tip`: If included in the transaction, the tip will be added on top. Only + /// signed transactions can have a tip. + /// + /// The base fee and adjusted weight and length fees constitute the _inclusion fee,_ which is + /// the minimum fee for a transaction to be included in a block. /// - /// final_fee = base_fee + targeted_fee_adjustment(len_fee + weight_fee) + tip; + /// ```ignore + /// inclusion_fee = base_fee + len_fee + [targeted_fee_adjustment * weight_fee]; + /// final_fee = inclusion_fee + tip; + /// ``` pub fn compute_fee( len: u32, info: &DispatchInfoOf, @@ -147,42 +356,72 @@ impl Module { ) -> BalanceOf where T::Call: Dispatchable, { - if info.pays_fee == Pays::Yes { + Self::compute_fee_raw(len, info.weight, tip, info.pays_fee) + } + + /// Compute the actual post dispatch fee for a particular transaction. + /// + /// Identical to `compute_fee` with the only difference that the post dispatch corrected + /// weight is used for the weight fee calculation. + pub fn compute_actual_fee( + len: u32, + info: &DispatchInfoOf, + post_info: &PostDispatchInfoOf, + tip: BalanceOf, + ) -> BalanceOf where + T::Call: Dispatchable, + { + Self::compute_fee_raw(len, post_info.calc_actual_weight(info), tip, post_info.pays_fee(info)) + } + + fn compute_fee_raw( + len: u32, + weight: Weight, + tip: BalanceOf, + pays_fee: Pays, + ) -> BalanceOf { + if pays_fee == Pays::Yes { let len = >::from(len); let per_byte = T::TransactionByteFee::get(); - let len_fee = per_byte.saturating_mul(len); - let unadjusted_weight_fee = Self::weight_to_fee(info.weight); - // the adjustable part of the fee - let adjustable_fee = len_fee.saturating_add(unadjusted_weight_fee); - let targeted_fee_adjustment = NextFeeMultiplier::get(); - let adjusted_fee = targeted_fee_adjustment.saturated_multiply_accumulate(adjustable_fee.saturated_into()); + // length fee. this is not adjusted. + let fixed_len_fee = per_byte.saturating_mul(len); + + // the adjustable part of the fee. + let unadjusted_weight_fee = Self::weight_to_fee(weight); + let multiplier = Self::next_fee_multiplier(); + // final adjusted weight fee. + let adjusted_weight_fee = multiplier.saturating_mul_int(unadjusted_weight_fee); let base_fee = Self::weight_to_fee(T::ExtrinsicBaseWeight::get()); - base_fee.saturating_add(adjusted_fee.saturated_into()).saturating_add(tip) + base_fee + .saturating_add(fixed_len_fee) + .saturating_add(adjusted_weight_fee) + .saturating_add(tip) } else { tip } } - /// Compute the fee for the specified weight. - /// - /// This fee is already adjusted by the per block fee adjustment factor and is therefore - /// the share that the weight contributes to the overall fee of a transaction. - pub fn weight_to_fee_with_adjustment(weight: Weight) -> Balance where - Balance: UniqueSaturatedFrom - { - let fee = UniqueSaturatedInto::::unique_saturated_into(Self::weight_to_fee(weight)); - UniqueSaturatedFrom::unique_saturated_from( - NextFeeMultiplier::get().saturated_multiply_accumulate(fee) - ) - } - fn weight_to_fee(weight: Weight) -> BalanceOf { // cap the weight to the maximum defined in runtime, otherwise it will be the // `Bounded` maximum of its data type, which is not desired. let capped_weight = weight.min(::MaximumBlockWeight::get()); - T::WeightToFee::convert(capped_weight) + T::WeightToFee::calc(&capped_weight) + } +} + +impl Convert> for Module where + T: Trait, + BalanceOf: FixedPointOperand, +{ + /// Compute the fee for the specified weight. + /// + /// This fee is already adjusted by the per block fee adjustment factor and is therefore the + /// share that the weight contributes to the overall fee of a transaction. It is mainly + /// for informational purposes and not used in the actual fee calculation. + fn convert(weight: Weight) -> BalanceOf { + NextFeeMultiplier::get().saturating_mul_int(Self::weight_to_fee(weight)) } } @@ -193,7 +432,7 @@ pub struct ChargeTransactionPayment(#[codec(compact)] Ba impl ChargeTransactionPayment where T::Call: Dispatchable, - BalanceOf: Send + Sync, + BalanceOf: Send + Sync + FixedPointOperand, { /// utility constructor. Used only in client/factory code. pub fn from(fee: BalanceOf) -> Self { @@ -242,14 +481,14 @@ impl sp_std::fmt::Debug for ChargeTransactionPayment } impl SignedExtension for ChargeTransactionPayment where - BalanceOf: Send + Sync + From, + BalanceOf: Send + Sync + From + FixedPointOperand, T::Call: Dispatchable, { const IDENTIFIER: &'static str = "ChargeTransactionPayment"; type AccountId = T::AccountId; type Call = T::Call; type AdditionalSigned = (); - type Pre = (BalanceOf, Self::AccountId, Option>); + type Pre = (BalanceOf, Self::AccountId, Option>, BalanceOf); fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } fn validate( @@ -275,20 +514,26 @@ impl SignedExtension for ChargeTransactionPayment whe info: &DispatchInfoOf, len: usize ) -> Result { - let (_, imbalance) = self.withdraw_fee(who, info, len)?; - Ok((self.0, who.clone(), imbalance)) + let (fee, imbalance) = self.withdraw_fee(who, info, len)?; + Ok((self.0, who.clone(), imbalance, fee)) } fn post_dispatch( pre: Self::Pre, info: &DispatchInfoOf, post_info: &PostDispatchInfoOf, - _len: usize, + len: usize, _result: &DispatchResult, ) -> Result<(), TransactionValidityError> { - let (tip, who, imbalance) = pre; + let (tip, who, imbalance, fee) = pre; if let Some(payed) = imbalance { - let refund = Module::::weight_to_fee_with_adjustment(post_info.calc_unspent(info)); + let actual_fee = Module::::compute_actual_fee( + len as u32, + info, + post_info, + tip, + ); + let refund = fee.saturating_sub(actual_fee); let actual_payment = match T::Currency::deposit_into_existing(&who, refund) { Ok(refund_imbalance) => { // The refund cannot be larger than the up front payed max weight. @@ -313,11 +558,13 @@ impl SignedExtension for ChargeTransactionPayment whe #[cfg(test)] mod tests { use super::*; - use core::num::NonZeroI128; use codec::Encode; use frame_support::{ - impl_outer_dispatch, impl_outer_origin, parameter_types, - weights::{DispatchClass, DispatchInfo, PostDispatchInfo, GetDispatchInfo, Weight}, + impl_outer_dispatch, impl_outer_origin, impl_outer_event, parameter_types, + weights::{ + DispatchClass, DispatchInfo, PostDispatchInfo, GetDispatchInfo, Weight, + WeightToFeePolynomial, WeightToFeeCoefficients, WeightToFeeCoefficient, + }, }; use pallet_balances::Call as BalancesCall; use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo; @@ -328,6 +575,7 @@ mod tests { Perbill, }; use std::cell::RefCell; + use smallvec::smallvec; const CALL: &::Call = &Call::Balances(BalancesCall::transfer(2, 69)); @@ -339,6 +587,13 @@ mod tests { } } + impl_outer_event! { + pub enum Event for Runtime { + system, + pallet_balances, + } + } + #[derive(Clone, PartialEq, Eq, Debug)] pub struct Runtime; @@ -364,6 +619,7 @@ mod tests { } impl frame_system::Trait for Runtime { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -373,12 +629,13 @@ mod tests { type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; - type Event = (); + type Event = Event; type BlockHashCount = BlockHashCount; type MaximumBlockWeight = MaximumBlockWeight; type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = ExtrinsicBaseWeight; + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -386,6 +643,7 @@ mod tests { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { @@ -394,10 +652,11 @@ mod tests { impl pallet_balances::Trait for Runtime { type Balance = u64; - type Event = (); + type Event = Event; type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } thread_local! { static TRANSACTION_BYTE_FEE: RefCell = RefCell::new(1); @@ -409,10 +668,17 @@ mod tests { fn get() -> u64 { TRANSACTION_BYTE_FEE.with(|v| *v.borrow()) } } - pub struct WeightToFee(u64); - impl Convert for WeightToFee { - fn convert(t: Weight) -> u64 { - WEIGHT_TO_FEE.with(|v| *v.borrow() * (t as u64)) + pub struct WeightToFee; + impl WeightToFeePolynomial for WeightToFee { + type Balance = u64; + + fn polynomial() -> WeightToFeeCoefficients { + smallvec![WeightToFeeCoefficient { + degree: 1, + coeff_frac: Perbill::zero(), + coeff_integer: WEIGHT_TO_FEE.with(|v| *v.borrow()), + negative: false, + }] } } @@ -491,16 +757,29 @@ mod tests { /// create a transaction info struct from weight. Handy to avoid building the whole struct. pub fn info_from_weight(w: Weight) -> DispatchInfo { - // pays: yes -- class: normal + // pays_fee: Pays::Yes -- class: DispatchClass::Normal DispatchInfo { weight: w, ..Default::default() } } fn post_info_from_weight(w: Weight) -> PostDispatchInfo { - PostDispatchInfo { actual_weight: Some(w), } + PostDispatchInfo { + actual_weight: Some(w), + pays_fee: Default::default(), + } + } + + fn post_info_from_pays(p: Pays) -> PostDispatchInfo { + PostDispatchInfo { + actual_weight: None, + pays_fee: p, + } } fn default_post_info() -> PostDispatchInfo { - PostDispatchInfo { actual_weight: None, } + PostDispatchInfo { + actual_weight: None, + pays_fee: Default::default(), + } } #[test] @@ -547,21 +826,21 @@ mod tests { .execute_with(|| { let len = 10; - NextFeeMultiplier::put(Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); + NextFeeMultiplier::put(Multiplier::saturating_from_rational(3, 2)); let pre = ChargeTransactionPayment::::from(5 /* tipped */) .pre_dispatch(&2, CALL, &info_from_weight(100), len) .unwrap(); - // 5 base fee, 3/2 * 10 byte fee, 3/2 * 100 weight fee, 5 tip - assert_eq!(Balances::free_balance(2), 200 - 5 - 15 - 150 - 5); + // 5 base fee, 10 byte fee, 3/2 * 100 weight fee, 5 tip + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 150 - 5); assert!( ChargeTransactionPayment:: ::post_dispatch(pre, &info_from_weight(100), &post_info_from_weight(50), len, &Ok(())) .is_ok() ); - // 75 (3/2 of the returned 50 units of weight ) is refunded - assert_eq!(Balances::free_balance(2), 200 - 5 - 15 - 75 - 5); + // 75 (3/2 of the returned 50 units of weight) is refunded + assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 75 - 5); }); } @@ -635,7 +914,7 @@ mod tests { .execute_with(|| { // all fees should be x1.5 - NextFeeMultiplier::put(Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); + NextFeeMultiplier::put(Multiplier::saturating_from_rational(3, 2)); let len = 10; assert!( @@ -643,7 +922,14 @@ mod tests { .pre_dispatch(&1, CALL, &info_from_weight(3), len) .is_ok() ); - assert_eq!(Balances::free_balance(1), 100 - 10 - 5 - (10 + 3) * 3 / 2); + assert_eq!( + Balances::free_balance(1), + 100 // original + - 10 // tip + - 5 // base + - 10 // len + - (3 * 3 / 2) // adjusted weight + ); }) } @@ -663,7 +949,7 @@ mod tests { .execute_with(|| { // all fees should be x1.5 - NextFeeMultiplier::put(Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); + NextFeeMultiplier::put(Multiplier::saturating_from_rational(3, 2)); assert_eq!( TransactionPayment::query_info(xt, len), @@ -672,10 +958,8 @@ mod tests { class: info.class, partial_fee: 5 * 2 /* base * weight_fee */ - + ( - len as u64 /* len * 1 */ - + info.weight.min(MaximumBlockWeight::get()) as u64 * 2 /* weight * weight_to_fee */ - ) * 3 / 2 + + len as u64 /* len * 1 */ + + info.weight.min(MaximumBlockWeight::get()) as u64 * 2 * 3 / 2 /* weight */ }, ); @@ -692,7 +976,7 @@ mod tests { .execute_with(|| { // Next fee multiplier is zero - assert_eq!(NextFeeMultiplier::get(), Fixed128::from_natural(0)); + assert_eq!(NextFeeMultiplier::get(), Multiplier::one()); // Tip only, no fees works let dispatch_info = DispatchInfo { @@ -731,8 +1015,8 @@ mod tests { .build() .execute_with(|| { - // Add a next fee multiplier - NextFeeMultiplier::put(Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())); // = 1/2 = .5 + // Add a next fee multiplier. Fees will be x3/2. + NextFeeMultiplier::put(Multiplier::saturating_from_rational(3, 2)); // Base fee is unaffected by multiplier let dispatch_info = DispatchInfo { weight: 0, @@ -748,10 +1032,44 @@ mod tests { pays_fee: Pays::Yes, }; // 123 weight, 456 length, 100 base - // adjustable fee = (123 * 1) + (456 * 10) = 4683 - // adjusted fee = (4683 * .5) + 4683 = 7024.5 -> 7024 - // final fee = 100 + 7024 + 789 tip = 7913 - assert_eq!(Module::::compute_fee(456, &dispatch_info, 789), 7913); + assert_eq!( + Module::::compute_fee(456, &dispatch_info, 789), + 100 + (3 * 123 / 2) + 4560 + 789, + ); + }); + } + + #[test] + fn compute_fee_works_with_negative_multiplier() { + ExtBuilder::default() + .base_weight(100) + .byte_fee(10) + .balance_factor(0) + .build() + .execute_with(|| + { + // Add a next fee multiplier. All fees will be x1/2. + NextFeeMultiplier::put(Multiplier::saturating_from_rational(1, 2)); + + // Base fee is unaffected by multiplier. + let dispatch_info = DispatchInfo { + weight: 0, + class: DispatchClass::Operational, + pays_fee: Pays::Yes, + }; + assert_eq!(Module::::compute_fee(0, &dispatch_info, 0), 100); + + // Everything works together. + let dispatch_info = DispatchInfo { + weight: 123, + class: DispatchClass::Operational, + pays_fee: Pays::Yes, + }; + // 123 weight, 456 length, 100 base + assert_eq!( + Module::::compute_fee(456, &dispatch_info, 789), + 100 + (123 / 2) + 4560 + 789, + ); }); } @@ -789,6 +1107,8 @@ mod tests { .build() .execute_with(|| { + // So events are emitted + System::set_block_number(10); let len = 10; let pre = ChargeTransactionPayment::::from(5 /* tipped */) .pre_dispatch(&2, CALL, &info_from_weight(100), len) @@ -805,6 +1125,14 @@ mod tests { .is_ok() ); assert_eq!(Balances::free_balance(2), 0); + // Transfer Event + assert!(System::events().iter().any(|event| { + event.event == Event::pallet_balances(pallet_balances::RawEvent::Transfer(2, 3, 80)) + })); + // Killed Event + assert!(System::events().iter().any(|event| { + event.event == Event::system(system::RawEvent::KilledAccount(2)) + })); }); } @@ -830,4 +1158,104 @@ mod tests { assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5); }); } + + #[test] + fn zero_transfer_on_free_transaction() { + ExtBuilder::default() + .balance_factor(10) + .base_weight(5) + .build() + .execute_with(|| + { + // So events are emitted + System::set_block_number(10); + let len = 10; + let dispatch_info = DispatchInfo { + weight: 100, + pays_fee: Pays::No, + class: DispatchClass::Normal, + }; + let user = 69; + let pre = ChargeTransactionPayment::::from(0) + .pre_dispatch(&user, CALL, &dispatch_info, len) + .unwrap(); + assert_eq!(Balances::total_balance(&user), 0); + assert!( + ChargeTransactionPayment:: + ::post_dispatch(pre, &dispatch_info, &default_post_info(), len, &Ok(())) + .is_ok() + ); + assert_eq!(Balances::total_balance(&user), 0); + // No events for such a scenario + assert_eq!(System::events().len(), 0); + }); + } + + #[test] + fn refund_consistent_with_actual_weight() { + ExtBuilder::default() + .balance_factor(10) + .base_weight(7) + .build() + .execute_with(|| + { + let info = info_from_weight(100); + let post_info = post_info_from_weight(33); + let prev_balance = Balances::free_balance(2); + let len = 10; + let tip = 5; + + NextFeeMultiplier::put(Multiplier::saturating_from_rational(5, 4)); + + let pre = ChargeTransactionPayment::::from(tip) + .pre_dispatch(&2, CALL, &info, len) + .unwrap(); + + ChargeTransactionPayment:: + ::post_dispatch(pre, &info, &post_info, len, &Ok(())) + .unwrap(); + + let refund_based_fee = prev_balance - Balances::free_balance(2); + let actual_fee = Module:: + ::compute_actual_fee(len as u32, &info, &post_info, tip); + + // 33 weight, 10 length, 7 base, 5 tip + assert_eq!(actual_fee, 7 + 10 + (33 * 5 / 4) + 5); + assert_eq!(refund_based_fee, actual_fee); + }); + } + + #[test] + fn post_info_can_change_pays_fee() { + ExtBuilder::default() + .balance_factor(10) + .base_weight(7) + .build() + .execute_with(|| + { + let info = info_from_weight(100); + let post_info = post_info_from_pays(Pays::No); + let prev_balance = Balances::free_balance(2); + let len = 10; + let tip = 5; + + NextFeeMultiplier::put(Multiplier::saturating_from_rational(5, 4)); + + let pre = ChargeTransactionPayment::::from(tip) + .pre_dispatch(&2, CALL, &info, len) + .unwrap(); + + ChargeTransactionPayment:: + ::post_dispatch(pre, &info, &post_info, len, &Ok(())) + .unwrap(); + + let refund_based_fee = prev_balance - Balances::free_balance(2); + let actual_fee = Module:: + ::compute_actual_fee(len as u32, &info, &post_info, tip); + + // Only 5 tip is paid + assert_eq!(actual_fee, 5); + assert_eq!(refund_based_fee, actual_fee); + }); + } } diff --git a/frame/treasury/Cargo.toml b/frame/treasury/Cargo.toml index c00ae225c1eaeda5180e8d6005f451305a92b439..b6ef83b32eda815553a86c0b68d2c9422b2236ea 100644 --- a/frame/treasury/Cargo.toml +++ b/frame/treasury/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-treasury" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet to manage treasury" @@ -13,18 +13,19 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -pallet-balances = { version = "2.0.0-dev", default-features = false, path = "../balances" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +pallet-balances = { version = "2.0.0-rc6", default-features = false, path = "../balances" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-io ={ version = "2.0.0-dev", path = "../../primitives/io" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-rc6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-storage = { version = "2.0.0-rc6", path = "../../primitives/storage" } [features] default = ["std"] diff --git a/frame/treasury/README.md b/frame/treasury/README.md new file mode 100644 index 0000000000000000000000000000000000000000..befb58118028477de5aeba1e5b5e825e315d76ce --- /dev/null +++ b/frame/treasury/README.md @@ -0,0 +1,72 @@ +# Treasury Module + +The Treasury module provides a "pot" of funds that can be managed by stakeholders in the +system and a structure for making spending proposals from this pot. + +- [`treasury::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +The Treasury Module itself provides the pot to store funds, and a means for stakeholders to +propose, approve, and deny expenditures. The chain will need to provide a method (e.g. +inflation, fees) for collecting funds. + +By way of example, the Council could vote to fund the Treasury with a portion of the block +reward and use the funds to pay developers. + +### Tipping + +A separate subsystem exists to allow for an agile "tipping" process, whereby a reward may be +given without first having a pre-determined stakeholder group come to consensus on how much +should be paid. + +A group of `Tippers` is determined through the config `Trait`. After half of these have declared +some amount that they believe a particular reported reason deserves, then a countdown period is +entered where any remaining members can declare their tip amounts also. After the close of the +countdown period, the median of all declared tips is paid to the reported beneficiary, along +with any finders fee, in case of a public (and bonded) original report. + +### Terminology + +- **Proposal:** A suggestion to allocate funds from the pot to a beneficiary. +- **Beneficiary:** An account who will receive the funds from a proposal iff +the proposal is approved. +- **Deposit:** Funds that a proposer must lock when making a proposal. The +deposit will be returned or slashed if the proposal is approved or rejected +respectively. +- **Pot:** Unspent funds accumulated by the treasury module. + +Tipping protocol: +- **Tipping:** The process of gathering declarations of amounts to tip and taking the median + amount to be transferred from the treasury to a beneficiary account. +- **Tip Reason:** The reason for a tip; generally a URL which embodies or explains why a + particular individual (identified by an account ID) is worthy of a recognition by the + treasury. +- **Finder:** The original public reporter of some reason for tipping. +- **Finders Fee:** Some proportion of the tip amount that is paid to the reporter of the tip, + rather than the main beneficiary. + +## Interface + +### Dispatchable Functions + +General spending/proposal protocol: +- `propose_spend` - Make a spending proposal and stake the required deposit. +- `set_pot` - Set the spendable balance of funds. +- `configure` - Configure the module's proposal requirements. +- `reject_proposal` - Reject a proposal, slashing the deposit. +- `approve_proposal` - Accept the proposal, returning the deposit. + +Tipping protocol: +- `report_awesome` - Report something worthy of a tip and register for a finders fee. +- `retract_tip` - Retract a previous (finders fee registered) report. +- `tip_new` - Report an item worthy of a tip and declare a specific amount to tip. +- `tip` - Declare or redeclare an amount to tip for a particular reason. +- `close_tip` - Close and pay out a tip. + +## GenesisConfig + +The Treasury module depends on the [`GenesisConfig`](./struct.GenesisConfig.html). + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index f901576c95d4b0c8d384737502654672ccd8a795..295326e1639ad5542ea02e0912a9fe917377043d 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Treasury pallet benchmarking. @@ -21,7 +22,7 @@ use super::*; use frame_system::RawOrigin; -use frame_benchmarking::{benchmarks, account}; +use frame_benchmarking::{benchmarks, account, whitelisted_caller}; use frame_support::traits::OnInitialize; use crate::Module as Treasury; @@ -44,7 +45,7 @@ fn setup_proposal(u: u32) -> ( // Create the pre-requisite information needed to create a `report_awesome`. fn setup_awesome(length: u32) -> (T::AccountId, Vec, T::AccountId) { - let caller = account("caller", 0, SEED); + let caller = whitelisted_caller(); let value = T::TipReportDepositBase::get() + T::TipReportDepositPerByte::get() * length.into() + T::Currency::minimum_balance(); @@ -115,6 +116,9 @@ benchmarks! { propose_spend { let u in 0 .. 1000; let (caller, value, beneficiary_lookup) = setup_proposal::(u); + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); }: _(RawOrigin::Signed(caller), value, beneficiary_lookup) reject_proposal { @@ -142,6 +146,9 @@ benchmarks! { report_awesome { let r in 0 .. MAX_BYTES; let (caller, reason, awesome_person) = setup_awesome::(r); + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); }: _(RawOrigin::Signed(caller), reason, awesome_person) retract_tip { @@ -154,6 +161,9 @@ benchmarks! { )?; let reason_hash = T::Hashing::hash(&reason[..]); let hash = T::Hashing::hash_of(&(&reason_hash, &awesome_person)); + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); }: _(RawOrigin::Signed(caller), hash) tip_new { @@ -161,6 +171,9 @@ benchmarks! { let t in 1 .. MAX_TIPPERS; let (caller, reason, beneficiary, value) = setup_tip::(r, t)?; + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); }: _(RawOrigin::Signed(caller), reason, beneficiary, value) tip { @@ -178,6 +191,9 @@ benchmarks! { ensure!(Tips::::contains_key(hash), "tip does not exist"); create_tips::(t - 1, hash.clone(), value)?; let caller = account("member", t - 1, SEED); + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); }: _(RawOrigin::Signed(caller), hash, value) close_tip { @@ -205,6 +221,9 @@ benchmarks! { create_tips::(t, hash.clone(), value)?; let caller = account("caller", t, SEED); + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); }: _(RawOrigin::Signed(caller), hash) on_initialize { diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index 270a710a2c29e31cd15435e3a242988c931b1dc7..af8d4a3cd0c2b0fec725a8e80ca4e81a5054855d 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Treasury Module //! @@ -101,7 +102,7 @@ use sp_runtime::{Permill, ModuleId, Percent, RuntimeDebug, traits::{ use frame_support::weights::{Weight, DispatchClass}; use frame_support::traits::{Contains, ContainsLengthBound, EnsureOrigin}; use codec::{Encode, Decode}; -use frame_system::{self as system, ensure_signed, ensure_root}; +use frame_system::{self as system, ensure_signed}; mod tests; mod benchmarking; @@ -110,6 +111,30 @@ type BalanceOf = <::Currency as Currency< = <::Currency as Currency<::AccountId>>::PositiveImbalance; type NegativeImbalanceOf = <::Currency as Currency<::AccountId>>::NegativeImbalance; +pub trait WeightInfo { + fn propose_spend(u: u32, ) -> Weight; + fn reject_proposal(u: u32, ) -> Weight; + fn approve_proposal(u: u32, ) -> Weight; + fn report_awesome(r: u32, ) -> Weight; + fn retract_tip(r: u32, ) -> Weight; + fn tip_new(r: u32, t: u32, ) -> Weight; + fn tip(t: u32, ) -> Weight; + fn close_tip(t: u32, ) -> Weight; + fn on_initialize(p: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn propose_spend(_u: u32, ) -> Weight { 1_000_000_000 } + fn reject_proposal(_u: u32, ) -> Weight { 1_000_000_000 } + fn approve_proposal(_u: u32, ) -> Weight { 1_000_000_000 } + fn report_awesome(_r: u32, ) -> Weight { 1_000_000_000 } + fn retract_tip(_r: u32, ) -> Weight { 1_000_000_000 } + fn tip_new(_r: u32, _t: u32, ) -> Weight { 1_000_000_000 } + fn tip(_t: u32, ) -> Weight { 1_000_000_000 } + fn close_tip(_t: u32, ) -> Weight { 1_000_000_000 } + fn on_initialize(_p: u32, ) -> Weight { 1_000_000_000 } +} + pub trait Trait: frame_system::Trait { /// The treasury's module id, used for deriving its sovereign account ID. type ModuleId: Get; @@ -158,6 +183,12 @@ pub trait Trait: frame_system::Trait { /// Percentage of spare funds (if any) that are burnt per spend period. type Burn: Get; + + /// Handler for the unbalanced decrease when treasury funds are burned. + type BurnDestination: OnUnbalanced>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } /// An index of a proposal. Just a `u32`. @@ -191,13 +222,17 @@ pub struct OpenTip< reason: Hash, /// The account to be tipped. who: AccountId, - /// The account who began this tip and the amount held on deposit. - finder: Option<(AccountId, Balance)>, + /// The account who began this tip. + finder: AccountId, + /// The amount held on deposit for this tip. + deposit: Balance, /// The block number at which this tip will close if `Some`. If `None`, then no closing is /// scheduled. closes: Option, /// The members who have voted for this tip. Sorted by AccountId. tips: Vec<(AccountId, Balance)>, + /// Whether this tip should result in the finder taking a fee. + finders_fee: bool, } decl_storage! { @@ -242,27 +277,27 @@ decl_event!( ::AccountId, ::Hash, { - /// New proposal. + /// New proposal. [proposal_index] Proposed(ProposalIndex), - /// We have ended a spend period and will now allocate funds. + /// We have ended a spend period and will now allocate funds. [budget_remaining] Spending(Balance), - /// Some funds have been allocated. + /// Some funds have been allocated. [proposal_index, award, beneficiary] Awarded(ProposalIndex, Balance, AccountId), - /// A proposal was rejected; funds were slashed. + /// A proposal was rejected; funds were slashed. [proposal_index, slashed] Rejected(ProposalIndex, Balance), - /// Some of our funds have been burnt. + /// Some of our funds have been burnt. [burn] Burnt(Balance), - /// Spending has finished; this is the amount that rolls over until next spend. + /// Spending has finished; this is the amount that rolls over until next spend. [budget_remaining] Rollover(Balance), - /// Some funds have been deposited. + /// Some funds have been deposited. [deposit] Deposit(Balance), - /// A new tip suggestion has been opened. + /// A new tip suggestion has been opened. [tip_hash] NewTip(Hash), - /// A tip suggestion has reached threshold and is closing. + /// A tip suggestion has reached threshold and is closing. [tip_hash] TipClosing(Hash), - /// A tip suggestion has been closed. + /// A tip suggestion has been closed. [tip_hash, who, payout] TipClosed(Hash, AccountId, Balance), - /// A tip suggestion has been retracted. + /// A tip suggestion has been retracted. [tip_hash] TipRetracted(Hash), } ); @@ -315,7 +350,7 @@ decl_module! { /// The amount held on deposit per byte within the tip report reason. const TipReportDepositPerByte: BalanceOf = T::TipReportDepositPerByte::get(); - + /// The treasury's module id, used for deriving its sovereign account ID. const ModuleId: ModuleId = T::ModuleId::get(); @@ -354,6 +389,8 @@ decl_module! { /// Reject a proposed spend. The original deposit will be slashed. /// + /// May only be called from `T::RejectOrigin`. + /// /// # /// - Complexity: O(1) /// - DbReads: `Proposals`, `rejected proposer account` @@ -361,9 +398,7 @@ decl_module! { /// # #[weight = (130_000_000 + T::DbWeight::get().reads_writes(2, 2), DispatchClass::Operational)] fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) { - T::RejectOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + T::RejectOrigin::ensure_origin(origin)?; let proposal = >::take(&proposal_id).ok_or(Error::::InvalidProposalIndex)?; let value = proposal.bond; @@ -376,6 +411,8 @@ decl_module! { /// Approve a proposal. At a later time, the proposal will be allocated to the beneficiary /// and the original deposit will be returned. /// + /// May only be called from `T::ApproveOrigin`. + /// /// # /// - Complexity: O(1). /// - DbReads: `Proposals`, `Approvals` @@ -383,9 +420,7 @@ decl_module! { /// # #[weight = (34_000_000 + T::DbWeight::get().reads_writes(2, 1), DispatchClass::Operational)] fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { - T::ApproveOrigin::try_origin(origin) - .map(|_| ()) - .or_else(ensure_root)?; + T::ApproveOrigin::ensure_origin(origin)?; ensure!(>::contains_key(proposal_id), Error::::InvalidProposalIndex); Approvals::mutate(|v| v.push(proposal_id)); @@ -427,8 +462,15 @@ decl_module! { T::Currency::reserve(&finder, deposit)?; Reasons::::insert(&reason_hash, &reason); - let finder = Some((finder, deposit)); - let tip = OpenTip { reason: reason_hash, who, finder, closes: None, tips: vec![] }; + let tip = OpenTip { + reason: reason_hash, + who, + finder, + deposit, + closes: None, + tips: vec![], + finders_fee: true + }; Tips::::insert(&hash, tip); Self::deposit_event(RawEvent::NewTip(hash)); } @@ -456,12 +498,13 @@ decl_module! { fn retract_tip(origin, hash: T::Hash) { let who = ensure_signed(origin)?; let tip = Tips::::get(&hash).ok_or(Error::::UnknownTip)?; - let (finder, deposit) = tip.finder.ok_or(Error::::NotFinder)?; - ensure!(finder == who, Error::::NotFinder); + ensure!(tip.finder == who, Error::::NotFinder); Reasons::::remove(&tip.reason); Tips::::remove(&hash); - let _ = T::Currency::unreserve(&who, deposit); + if !tip.deposit.is_zero() { + let _ = T::Currency::unreserve(&who, tip.deposit); + } Self::deposit_event(RawEvent::TipRetracted(hash)); } @@ -500,8 +543,16 @@ decl_module! { Reasons::::insert(&reason_hash, &reason); Self::deposit_event(RawEvent::NewTip(hash.clone())); - let tips = vec![(tipper, tip_value)]; - let tip = OpenTip { reason: reason_hash, who, finder: None, closes: None, tips }; + let tips = vec![(tipper.clone(), tip_value)]; + let tip = OpenTip { + reason: reason_hash, + who, + finder: tipper, + deposit: Zero::zero(), + closes: None, + tips, + finders_fee: false, + }; Tips::::insert(&hash, tip); } @@ -666,15 +717,17 @@ impl Module { let treasury = Self::account_id(); let max_payout = Self::pot(); let mut payout = tips[tips.len() / 2].1.min(max_payout); - if let Some((finder, deposit)) = tip.finder { - let _ = T::Currency::unreserve(&finder, deposit); - if finder != tip.who { + if !tip.deposit.is_zero() { + let _ = T::Currency::unreserve(&tip.finder, tip.deposit); + } + if tip.finders_fee { + if tip.finder != tip.who { // pay out the finder's fee. let finders_fee = T::TipFindersFee::get() * payout; payout -= finders_fee; // this should go through given we checked it's at most the free balance, but still // we only make a best-effort. - let _ = T::Currency::transfer(&treasury, &finder, finders_fee, KeepAlive); + let _ = T::Currency::transfer(&treasury, &tip.finder, finders_fee, KeepAlive); } } // same as above: best-effort only. @@ -721,7 +774,10 @@ impl Module { // burn some proportion of the remaining budget if we run a surplus. let burn = (T::Burn::get() * budget_remaining).min(budget_remaining); budget_remaining -= burn; - imbalance.subsume(T::Currency::burn(burn)); + + let (debit, credit) = T::Currency::pair(burn); + imbalance.subsume(debit); + T::BurnDestination::on_unbalanced(credit); Self::deposit_event(RawEvent::Burnt(burn)) } @@ -752,6 +808,55 @@ impl Module { // Must never be less than 0 but better be safe. .saturating_sub(T::Currency::minimum_balance()) } + + pub fn migrate_retract_tip_for_tip_new() { + /// An open tipping "motion". Retains all details of a tip including information on the finder + /// and the members who have voted. + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] + pub struct OldOpenTip< + AccountId: Parameter, + Balance: Parameter, + BlockNumber: Parameter, + Hash: Parameter, + > { + /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be + /// sensible. + reason: Hash, + /// The account to be tipped. + who: AccountId, + /// The account who began this tip and the amount held on deposit. + finder: Option<(AccountId, Balance)>, + /// The block number at which this tip will close if `Some`. If `None`, then no closing is + /// scheduled. + closes: Option, + /// The members who have voted for this tip. Sorted by AccountId. + tips: Vec<(AccountId, Balance)>, + } + + use frame_support::{Twox64Concat, migration::StorageKeyIterator}; + + for (hash, old_tip) in StorageKeyIterator::< + T::Hash, + OldOpenTip, T::BlockNumber, T::Hash>, + Twox64Concat, + >::new(b"Treasury", b"Tips").drain() + { + let (finder, deposit, finders_fee) = match old_tip.finder { + Some((finder, deposit)) => (finder, deposit, true), + None => (T::AccountId::default(), Zero::zero(), false), + }; + let new_tip = OpenTip { + reason: old_tip.reason, + who: old_tip.who, + finder, + deposit, + closes: old_tip.closes, + tips: old_tip.tips, + finders_fee + }; + Tips::::insert(hash, new_tip) + } + } } impl OnUnbalanced> for Module { diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 18b1d1c50eebd9c283e98861b736bd87f0fdd83a..59a41a263cc9fed430cf05e86015602a67e460e0 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Treasury pallet tests. @@ -32,7 +33,7 @@ use sp_runtime::{ }; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } @@ -59,6 +60,7 @@ parameter_types! { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -74,6 +76,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -81,6 +84,7 @@ impl frame_system::Trait for Test { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; @@ -91,6 +95,7 @@ impl pallet_balances::Trait for Test { type DustRemoval = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } thread_local! { static TEN_TO_FOURTEEN: RefCell> = RefCell::new(vec![10,11,12,13,14]); @@ -144,6 +149,8 @@ impl Trait for Test { type ProposalBondMinimum = ProposalBondMinimum; type SpendPeriod = SpendPeriod; type Burn = Burn; + type BurnDestination = (); // Just gets burned. + type WeightInfo = (); } type System = frame_system::Module; type Balances = pallet_balances::Module; @@ -269,7 +276,7 @@ fn close_tip_works() { assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::Premature); System::set_block_number(2); - assert_noop!(Treasury::close_tip(Origin::NONE, h.into()), BadOrigin); + assert_noop!(Treasury::close_tip(Origin::none(), h.into()), BadOrigin); assert_ok!(Treasury::close_tip(Origin::signed(0), h.into())); assert_eq!(Balances::free_balance(3), 10); @@ -290,6 +297,7 @@ fn close_tip_works() { #[test] fn retract_tip_works() { new_test_ext().execute_with(|| { + // with report awesome Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Treasury::report_awesome(Origin::signed(0), b"awesome.dot".to_vec(), 3)); let h = tip_hash(); @@ -300,6 +308,17 @@ fn retract_tip_works() { assert_ok!(Treasury::retract_tip(Origin::signed(0), h.clone())); System::set_block_number(2); assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::::UnknownTip); + + // with tip new + Balances::make_free_balance_be(&Treasury::account_id(), 101); + assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); + let h = tip_hash(); + assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); + assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); + assert_noop!(Treasury::retract_tip(Origin::signed(0), h.clone()), Error::::NotFinder); + assert_ok!(Treasury::retract_tip(Origin::signed(10), h.clone())); + System::set_block_number(2); + assert_noop!(Treasury::close_tip(Origin::signed(10), h.into()), Error::::UnknownTip); }); } @@ -379,7 +398,7 @@ fn accepted_spend_proposal_ignored_outside_spend_period() { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 0)); >::on_initialize(1); assert_eq!(Balances::free_balance(3), 0); @@ -406,7 +425,7 @@ fn rejected_spend_proposal_ignored_on_spend_period() { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); + assert_ok!(Treasury::reject_proposal(Origin::root(), 0)); >::on_initialize(2); assert_eq!(Balances::free_balance(3), 0); @@ -420,22 +439,22 @@ fn reject_already_rejected_spend_proposal_fails() { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); - assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); + assert_ok!(Treasury::reject_proposal(Origin::root(), 0)); + assert_noop!(Treasury::reject_proposal(Origin::root(), 0), Error::::InvalidProposalIndex); }); } #[test] fn reject_non_existent_spend_proposal_fails() { new_test_ext().execute_with(|| { - assert_noop!(Treasury::reject_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); + assert_noop!(Treasury::reject_proposal(Origin::root(), 0), Error::::InvalidProposalIndex); }); } #[test] fn accept_non_existent_spend_proposal_fails() { new_test_ext().execute_with(|| { - assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); + assert_noop!(Treasury::approve_proposal(Origin::root(), 0), Error::::InvalidProposalIndex); }); } @@ -445,8 +464,8 @@ fn accept_already_rejected_spend_proposal_fails() { Balances::make_free_balance_be(&Treasury::account_id(), 101); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_ok!(Treasury::reject_proposal(Origin::ROOT, 0)); - assert_noop!(Treasury::approve_proposal(Origin::ROOT, 0), Error::::InvalidProposalIndex); + assert_ok!(Treasury::reject_proposal(Origin::root(), 0)); + assert_noop!(Treasury::approve_proposal(Origin::root(), 0), Error::::InvalidProposalIndex); }); } @@ -457,7 +476,7 @@ fn accepted_spend_proposal_enacted_on_spend_period() { assert_eq!(Treasury::pot(), 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 0)); >::on_initialize(2); assert_eq!(Balances::free_balance(3), 100); @@ -472,7 +491,7 @@ fn pot_underflow_should_not_diminish() { assert_eq!(Treasury::pot(), 100); assert_ok!(Treasury::propose_spend(Origin::signed(0), 150, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 0)); >::on_initialize(2); assert_eq!(Treasury::pot(), 100); // Pot hasn't changed @@ -494,13 +513,13 @@ fn treasury_account_doesnt_get_deleted() { let treasury_balance = Balances::free_balance(&Treasury::account_id()); assert_ok!(Treasury::propose_spend(Origin::signed(0), treasury_balance, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 0)); >::on_initialize(2); assert_eq!(Treasury::pot(), 100); // Pot hasn't changed assert_ok!(Treasury::propose_spend(Origin::signed(0), Treasury::pot(), 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 1)); >::on_initialize(4); assert_eq!(Treasury::pot(), 0); // Pot is emptied @@ -524,9 +543,9 @@ fn inexistent_account_works() { assert_eq!(Treasury::pot(), 0); // Pot is empty assert_ok!(Treasury::propose_spend(Origin::signed(0), 99, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 0)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 0)); assert_ok!(Treasury::propose_spend(Origin::signed(0), 1, 3)); - assert_ok!(Treasury::approve_proposal(Origin::ROOT, 1)); + assert_ok!(Treasury::approve_proposal(Origin::root(), 1)); >::on_initialize(2); assert_eq!(Treasury::pot(), 0); // Pot hasn't changed assert_eq!(Balances::free_balance(3), 0); // Balance of `3` hasn't changed @@ -541,3 +560,97 @@ fn inexistent_account_works() { assert_eq!(Balances::free_balance(3), 99); // Balance of `3` has changed }); } + +#[test] +fn test_last_reward_migration() { + use sp_storage::Storage; + + let mut s = Storage::default(); + + #[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)] + pub struct OldOpenTip< + AccountId: Parameter, + Balance: Parameter, + BlockNumber: Parameter, + Hash: Parameter, + > { + /// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be + /// sensible. + reason: Hash, + /// The account to be tipped. + who: AccountId, + /// The account who began this tip and the amount held on deposit. + finder: Option<(AccountId, Balance)>, + /// The block number at which this tip will close if `Some`. If `None`, then no closing is + /// scheduled. + closes: Option, + /// The members who have voted for this tip. Sorted by AccountId. + tips: Vec<(AccountId, Balance)>, + } + + let reason1 = BlakeTwo256::hash(b"reason1"); + let hash1 = BlakeTwo256::hash_of(&(reason1, 10u64)); + + let old_tip_finder = OldOpenTip:: { + reason: reason1, + who: 10, + finder: Some((20, 30)), + closes: Some(13), + tips: vec![(40, 50), (60, 70)] + }; + + let reason2 = BlakeTwo256::hash(b"reason2"); + let hash2 = BlakeTwo256::hash_of(&(reason2, 20u64)); + + let old_tip_no_finder = OldOpenTip:: { + reason: reason2, + who: 20, + finder: None, + closes: Some(13), + tips: vec![(40, 50), (60, 70)] + }; + + let data = vec![ + ( + Tips::::hashed_key_for(hash1), + old_tip_finder.encode().to_vec() + ), + ( + Tips::::hashed_key_for(hash2), + old_tip_no_finder.encode().to_vec() + ), + ]; + + s.top = data.into_iter().collect(); + sp_io::TestExternalities::new(s).execute_with(|| { + Treasury::migrate_retract_tip_for_tip_new(); + + // Test w/ finder + assert_eq!( + Tips::::get(hash1), + Some(OpenTip { + reason: reason1, + who: 10, + finder: 20, + deposit: 30, + closes: Some(13), + tips: vec![(40, 50), (60, 70)], + finders_fee: true, + }) + ); + + // Test w/o finder + assert_eq!( + Tips::::get(hash2), + Some(OpenTip { + reason: reason2, + who: 20, + finder: Default::default(), + deposit: 0, + closes: Some(13), + tips: vec![(40, 50), (60, 70)], + finders_fee: false, + }) + ); + }); +} diff --git a/frame/utility/Cargo.toml b/frame/utility/Cargo.toml index a830f8ab5b57f405ac8ec94d1e3d63ee09e55c12..5ccc2085d9713faa289e546f89cf440d43759bba 100644 --- a/frame/utility/Cargo.toml +++ b/frame/utility/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-utility" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME utilities pallet" @@ -13,19 +13,19 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } [features] default = ["std"] diff --git a/frame/utility/README.md b/frame/utility/README.md new file mode 100644 index 0000000000000000000000000000000000000000..84bb12f15b5bbbb97c5a63ec246ce928c324297d --- /dev/null +++ b/frame/utility/README.md @@ -0,0 +1,38 @@ +# Utility Module +A stateless module with helpers for dispatch management which does no re-authentication. + +- [`utility::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +This module contains two basic pieces of functionality: +- Batch dispatch: A stateless operation, allowing any origin to execute multiple calls in a + single dispatch. This can be useful to amalgamate proposals, combining `set_code` with + corresponding `set_storage`s, for efficient multiple payouts with just a single signature + verify, or in combination with one of the other two dispatch functionality. +- Pseudonymal dispatch: A stateless operation, allowing a signed origin to execute a call from + an alternative signed origin. Each account has 2 * 2**16 possible "pseudonyms" (alternative + account IDs) and these can be stacked. This can be useful as a key management tool, where you + need multiple distinct accounts (e.g. as controllers for many staking accounts), but where + it's perfectly fine to have each of them controlled by the same underlying keypair. + Derivative accounts are, for the purposes of proxy filtering considered exactly the same as + the oigin and are thus hampered with the origin's filters. + +Since proxy filters are respected in all dispatches of this module, it should never need to be +filtered by any proxy. + +## Interface + +### Dispatchable Functions + +#### For batch dispatch +* `batch` - Dispatch multiple calls from the sender's origin. + +#### For pseudonymal dispatch +* `as_derivative` - Dispatch a call from a derivative signed origin. + +[`Call`]: ./enum.Call.html +[`Trait`]: ./trait.Trait.html + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/utility/src/benchmarking.rs b/frame/utility/src/benchmarking.rs index fc8783b49aa87aaf0813bcc467defae82abc7bf3..8ca0e216f2887a2265f568bbe907be19bfc91021 100644 --- a/frame/utility/src/benchmarking.rs +++ b/frame/utility/src/benchmarking.rs @@ -1,45 +1,36 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // Benchmarks for Utility Pallet #![cfg(feature = "runtime-benchmarks")] use super::*; -use frame_system::RawOrigin; -use frame_benchmarking::{benchmarks, account}; -use sp_runtime::traits::Saturating; - -use crate::Module as Utility; +use frame_system::{RawOrigin, EventRecord}; +use frame_benchmarking::{benchmarks, account, whitelisted_caller}; const SEED: u32 = 0; -fn setup_multi(s: u32, z: u32) -> Result<(Vec, Box<::Call>), &'static str>{ - let mut signatories: Vec = Vec::new(); - for i in 0 .. s { - let signatory = account("signatory", i, SEED); - // Give them some balance for a possible deposit - let deposit = T::MultisigDepositBase::get() + T::MultisigDepositFactor::get() * s.into(); - let balance = T::Currency::minimum_balance().saturating_mul(100.into()) + deposit; - T::Currency::make_free_balance_be(&signatory, balance); - signatories.push(signatory); - } - signatories.sort(); - let call: Box<::Call> = Box::new(frame_system::Call::remark(vec![0; z as usize]).into()); - return Ok((signatories, call)) +fn assert_last_event(generic_event: ::Event) { + let events = frame_system::Module::::events(); + let system_event: ::Event = generic_event.into(); + // compare to the last event record + let EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); } benchmarks! { @@ -52,99 +43,20 @@ benchmarks! { let call = frame_system::Call::remark(vec![]).into(); calls.push(call); } - let caller = account("caller", 0, SEED); + let caller = whitelisted_caller(); }: _(RawOrigin::Signed(caller), calls) + verify { + assert_last_event::(Event::BatchCompleted.into()) + } - as_sub { + as_derivative { let u in 0 .. 1000; let caller = account("caller", u, SEED); let call = Box::new(frame_system::Call::remark(vec![]).into()); + // Whitelist caller account from further DB operations. + let caller_key = frame_system::Account::::hashed_key_for(&caller); + frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); }: _(RawOrigin::Signed(caller), u as u16, call) - - as_multi_create { - // Signatories, need at least 2 total people - let s in 2 .. T::MaxSignatories::get() as u32; - // Transaction Length - let z in 0 .. 10_000; - let (mut signatories, call) = setup_multi::(s, z)?; - let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; - }: as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call) - - as_multi_approve { - // Signatories, need at least 2 people - let s in 2 .. T::MaxSignatories::get() as u32; - // Transaction Length - let z in 0 .. 10_000; - let (mut signatories, call) = setup_multi::(s, z)?; - let mut signatories2 = signatories.clone(); - let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; - // before the call, get the timepoint - let timepoint = Utility::::timepoint(); - // Create the multi - Utility::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone())?; - let caller2 = signatories2.remove(0); - }: as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call) - - as_multi_complete { - // Signatories, need at least 2 people - let s in 2 .. T::MaxSignatories::get() as u32; - // Transaction Length - let z in 0 .. 10_000; - let (mut signatories, call) = setup_multi::(s, z)?; - let mut signatories2 = signatories.clone(); - let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; - // before the call, get the timepoint - let timepoint = Utility::::timepoint(); - // Create the multi - Utility::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone())?; - // Everyone except the first person approves - for i in 1 .. s - 1 { - let mut signatories_loop = signatories2.clone(); - let caller_loop = signatories_loop.remove(i as usize); - Utility::::as_multi(RawOrigin::Signed(caller_loop).into(), s as u16, signatories_loop, Some(timepoint), call.clone())?; - } - let caller2 = signatories2.remove(0); - }: as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call) - - approve_as_multi_create { - // Signatories, need at least 2 people - let s in 2 .. T::MaxSignatories::get() as u32; - // Transaction Length - let z in 0 .. 10_000; - let (mut signatories, call) = setup_multi::(s, z)?; - let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; - let call_hash = call.using_encoded(blake2_256); - // Create the multi - }: approve_as_multi(RawOrigin::Signed(caller), s as u16, signatories, None, call_hash) - - approve_as_multi_approve { - // Signatories, need at least 2 people - let s in 2 .. T::MaxSignatories::get() as u32; - // Transaction Length - let z in 0 .. 10_000; - let (mut signatories, call) = setup_multi::(s, z)?; - let mut signatories2 = signatories.clone(); - let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; - let call_hash = call.using_encoded(blake2_256); - // before the call, get the timepoint - let timepoint = Utility::::timepoint(); - // Create the multi - Utility::::as_multi(RawOrigin::Signed(caller).into(), s as u16, signatories, None, call.clone())?; - let caller2 = signatories2.remove(0); - }: approve_as_multi(RawOrigin::Signed(caller2), s as u16, signatories2, Some(timepoint), call_hash) - - cancel_as_multi { - // Signatories, need at least 2 people - let s in 2 .. T::MaxSignatories::get() as u32; - // Transaction Length - let z in 0 .. 10_000; - let (mut signatories, call) = setup_multi::(s, z)?; - let caller = signatories.pop().ok_or("signatories should have len 2 or more")?; - let call_hash = call.using_encoded(blake2_256); - let timepoint = Utility::::timepoint(); - // Create the multi - Utility::::as_multi(RawOrigin::Signed(caller.clone()).into(), s as u16, signatories.clone(), None, call.clone())?; - }: _(RawOrigin::Signed(caller), s as u16, signatories, timepoint, call_hash) } #[cfg(test)] @@ -157,13 +69,7 @@ mod tests { fn test_benchmarks() { new_test_ext().execute_with(|| { assert_ok!(test_benchmark_batch::()); - assert_ok!(test_benchmark_as_sub::()); - assert_ok!(test_benchmark_as_multi_create::()); - assert_ok!(test_benchmark_as_multi_approve::()); - assert_ok!(test_benchmark_as_multi_complete::()); - assert_ok!(test_benchmark_approve_as_multi_create::()); - assert_ok!(test_benchmark_approve_as_multi_approve::()); - assert_ok!(test_benchmark_cancel_as_multi::()); + assert_ok!(test_benchmark_as_derivative::()); }); } } diff --git a/frame/utility/src/default_weights.rs b/frame/utility/src/default_weights.rs new file mode 100644 index 0000000000000000000000000000000000000000..d023dbddd4f8087b51820fb3b222980e1a599f98 --- /dev/null +++ b/frame/utility/src/default_weights.rs @@ -0,0 +1,34 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc5 + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +impl crate::WeightInfo for () { + fn batch(c: u32, ) -> Weight { + (16461000 as Weight) + .saturating_add((1982000 as Weight).saturating_mul(c as Weight)) + } + // WARNING! Some components were not used: ["u"] + fn as_derivative() -> Weight { + (4086000 as Weight) + } +} diff --git a/frame/utility/src/lib.rs b/frame/utility/src/lib.rs index 1ff71af53595bc01188a486e824ac13ce098b084..d67fdc85db5a5faa03c63dd1b8ab054b8b86c6fa 100644 --- a/frame/utility/src/lib.rs +++ b/frame/utility/src/lib.rs @@ -1,43 +1,43 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Utility Module -//! A module with helpers for dispatch management. +//! A stateless module with helpers for dispatch management which does no re-authentication. //! //! - [`utility::Trait`](./trait.Trait.html) //! - [`Call`](./enum.Call.html) //! //! ## Overview //! -//! This module contains three basic pieces of functionality, two of which are stateless: +//! This module contains two basic pieces of functionality: //! - Batch dispatch: A stateless operation, allowing any origin to execute multiple calls in a //! single dispatch. This can be useful to amalgamate proposals, combining `set_code` with //! corresponding `set_storage`s, for efficient multiple payouts with just a single signature //! verify, or in combination with one of the other two dispatch functionality. //! - Pseudonymal dispatch: A stateless operation, allowing a signed origin to execute a call from -//! an alternative signed origin. Each account has 2**16 possible "pseudonyms" (alternative +//! an alternative signed origin. Each account has 2 * 2**16 possible "pseudonyms" (alternative //! account IDs) and these can be stacked. This can be useful as a key management tool, where you //! need multiple distinct accounts (e.g. as controllers for many staking accounts), but where //! it's perfectly fine to have each of them controlled by the same underlying keypair. -//! - Multisig dispatch (stateful): A potentially stateful operation, allowing multiple signed -//! origins (accounts) to coordinate and dispatch a call from a well-known origin, derivable -//! deterministically from the set of account IDs and the threshold number of accounts from the -//! set that must approve it. In the case that the threshold is just one then this is a stateless -//! operation. This is useful for multisig wallets where cryptographic threshold signatures are -//! not available or desired. +//! Derivative accounts are, for the purposes of proxy filtering considered exactly the same as +//! the oigin and are thus hampered with the origin's filters. +//! +//! Since proxy filters are respected in all dispatches of this module, it should never need to be +//! filtered by any proxy. //! //! ## Interface //! @@ -47,13 +47,7 @@ //! * `batch` - Dispatch multiple calls from the sender's origin. //! //! #### For pseudonymal dispatch -//! * `as_sub` - Dispatch a call from a secondary ("sub") signed origin. -//! -//! #### For multisig dispatch -//! * `as_multi` - Approve and if possible dispatch a call from a composite origin formed from a -//! number of signed origins. -//! * `approve_as_multi` - Approve a call from a composite origin. -//! * `cancel_as_multi` - Cancel a call from a composite origin. +//! * `as_derivative` - Dispatch a call from a derivative signed origin. //! //! [`Call`]: ./enum.Call.html //! [`Trait`]: ./trait.Trait.html @@ -65,131 +59,49 @@ use sp_std::prelude::*; use codec::{Encode, Decode}; use sp_core::TypeId; use sp_io::hashing::blake2_256; -use frame_support::{decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug}; -use frame_support::{traits::{Get, ReservableCurrency, Currency}, - weights::{Weight, GetDispatchInfo, DispatchClass, FunctionOf, Pays}, - dispatch::{DispatchResultWithPostInfo, DispatchErrorWithPostInfo, PostDispatchInfo}, +use frame_support::{decl_module, decl_event, decl_storage, Parameter}; +use frame_support::{ + traits::{OriginTrait, UnfilteredDispatchable}, + weights::{Weight, GetDispatchInfo, DispatchClass}, dispatch::PostDispatchInfo, }; -use frame_system::{self as system, ensure_signed}; +use frame_system::{ensure_signed, ensure_root}; use sp_runtime::{DispatchError, DispatchResult, traits::Dispatchable}; mod tests; mod benchmarking; +mod default_weights; -type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub trait WeightInfo { + fn batch(c: u32, ) -> Weight; + fn as_derivative() -> Weight; +} /// Configuration trait. pub trait Trait: frame_system::Trait { /// The overarching event type. - type Event: From> + Into<::Event>; + type Event: From + Into<::Event>; /// The overarching call type. - type Call: Parameter + Dispatchable + GetDispatchInfo + From>; - - /// The currency mechanism. - type Currency: ReservableCurrency; - - /// The base amount of currency needed to reserve for creating a multisig execution. - /// - /// This is held for an additional storage item whose value size is - /// `4 + sizeof((BlockNumber, Balance, AccountId))` bytes. - type MultisigDepositBase: Get>; - - /// The amount of currency needed per unit threshold when creating a multisig execution. - /// - /// This is held for adding 32 bytes more into a pre-existing storage value. - type MultisigDepositFactor: Get>; - - /// The maximum amount of signatories allowed in the multisig. - type MaxSignatories: Get; -} - -/// A global extrinsic index, formed as the extrinsic index within a block, together with that -/// block's height. This allows a transaction in which a multisig operation of a particular -/// composite was created to be uniquely identified. -#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug)] -pub struct Timepoint { - /// The height of the chain at the point in time. - height: BlockNumber, - /// The index of the extrinsic at the point in time. - index: u32, -} + type Call: Parameter + Dispatchable + + GetDispatchInfo + From> + + UnfilteredDispatchable; -/// An open multisig operation. -#[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug)] -pub struct Multisig { - /// The extrinsic when the multisig operation was opened. - when: Timepoint, - /// The amount held in reserve of the `depositor`, to be returned once the operation ends. - deposit: Balance, - /// The account who opened it (i.e. the first to approve it). - depositor: AccountId, - /// The approvals achieved so far, including the depositor. Always sorted. - approvals: Vec, + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_storage! { - trait Store for Module as Utility { - /// The set of open multisig operations. - pub Multisigs: double_map - hasher(twox_64_concat) T::AccountId, hasher(blake2_128_concat) [u8; 32] - => Option, T::AccountId>>; - } -} - -decl_error! { - pub enum Error for Module { - /// Threshold is too low (zero). - ZeroThreshold, - /// Call is already approved by this signatory. - AlreadyApproved, - /// Call doesn't need any (more) approvals. - NoApprovalsNeeded, - /// There are too few signatories in the list. - TooFewSignatories, - /// There are too many signatories in the list. - TooManySignatories, - /// The signatories were provided out of order; they should be ordered. - SignatoriesOutOfOrder, - /// The sender was contained in the other signatories; it shouldn't be. - SenderInSignatories, - /// Multisig operation not found when attempting to cancel. - NotFound, - /// Only the account that originally created the multisig is able to cancel it. - NotOwner, - /// No timepoint was given, yet the multisig operation is already underway. - NoTimepoint, - /// A different timepoint was given to the multisig operation that is underway. - WrongTimepoint, - /// A timepoint was given, yet no multisig operation is underway. - UnexpectedTimepoint, - } + trait Store for Module as Utility {} } decl_event! { /// Events type. - pub enum Event where - AccountId = ::AccountId, - BlockNumber = ::BlockNumber, - CallHash = [u8; 32] - { + pub enum Event { /// Batch of dispatches did not complete fully. Index of first failing dispatch given, as - /// well as the error. + /// well as the error. [index, error] BatchInterrupted(u32, DispatchError), /// Batch of dispatches completed fully with no error. BatchCompleted, - /// A new multisig operation has begun. First param is the account that is approving, - /// second is the multisig account, third is hash of the call. - NewMultisig(AccountId, AccountId, CallHash), - /// A multisig operation has been approved by someone. First param is the account that is - /// approving, third is the multisig account, fourth is hash of the call. - MultisigApproval(AccountId, Timepoint, AccountId, CallHash), - /// A multisig operation has been executed. First param is the account that is - /// approving, third is the multisig account, fourth is hash of the call to be executed. - MultisigExecuted(AccountId, Timepoint, AccountId, CallHash, DispatchResult), - /// A multisig operation has been cancelled. First param is the account that is - /// cancelling, third is the multisig account, fourth is hash of the call. - MultisigCancelled(AccountId, Timepoint, AccountId, CallHash), } } @@ -201,40 +113,20 @@ impl TypeId for IndexedUtilityModuleId { const TYPE_ID: [u8; 4] = *b"suba"; } -mod weight_of { - use super::*; - - /// - Base Weight: - /// - Create: 46.55 + 0.089 * S µs - /// - Approve: 34.03 + .112 * S µs - /// - Complete: 40.36 + .225 * S µs - /// - DB Weight: - /// - Reads: Multisig Storage, [Caller Account] - /// - Writes: Multisig Storage, [Caller Account] - /// - Plus Call Weight - pub fn as_multi(other_sig_len: usize, call_weight: Weight) -> Weight { - call_weight - .saturating_add(45_000_000) - .saturating_add((other_sig_len as Weight).saturating_mul(250_000)) - .saturating_add(T::DbWeight::get().reads_writes(1, 1)) - } -} - decl_module! { pub struct Module for enum Call where origin: T::Origin { - type Error = Error; - /// Deposit one of this module's events by using the default implementation. fn deposit_event() = default; /// Send a batch of dispatch calls. /// - /// This will execute until the first one fails and then stop. - /// /// May be called from any origin. /// /// - `calls`: The calls to be dispatched from the same origin. /// + /// If origin is root then call are dispatch without checking origin filter. (This includes + /// bypassing `frame_system::Trait::BaseCallFilter`). + /// /// # /// - Base weight: 14.39 + .987 * c µs /// - Plus the sum of the weights of the `calls`. @@ -246,14 +138,13 @@ decl_module! { /// `BatchInterrupted` event is deposited, along with the number of successful calls made /// and the error of the failed call. If all were successful, then the `BatchCompleted` /// event is deposited. - #[weight = FunctionOf( - |args: (&Vec<::Call>,)| { - args.0.iter() - .map(|call| call.get_dispatch_info().weight) - .fold(15_000_000, |a: Weight, n| a.saturating_add(n).saturating_add(1_000_000)) - }, - |args: (&Vec<::Call>,)| { - let all_operational = args.0.iter() + #[weight = ( + calls.iter() + .map(|call| call.get_dispatch_info().weight) + .fold(0, |total: Weight, weight: Weight| total.saturating_add(weight)) + .saturating_add(T::WeightInfo::batch(calls.len() as u32)), + { + let all_operational = calls.iter() .map(|call| call.get_dispatch_info().class) .all(|class| class == DispatchClass::Operational); if all_operational { @@ -262,383 +153,55 @@ decl_module! { DispatchClass::Normal } }, - Pays::Yes, )] fn batch(origin, calls: Vec<::Call>) { + let is_root = ensure_root(origin.clone()).is_ok(); for (index, call) in calls.into_iter().enumerate() { - let result = call.dispatch(origin.clone()); + let result = if is_root { + call.dispatch_bypass_filter(origin.clone()) + } else { + call.dispatch(origin.clone()) + }; if let Err(e) = result { - Self::deposit_event(Event::::BatchInterrupted(index as u32, e.error)); + Self::deposit_event(Event::BatchInterrupted(index as u32, e.error)); return Ok(()); } } - Self::deposit_event(Event::::BatchCompleted); + Self::deposit_event(Event::BatchCompleted); } /// Send a call through an indexed pseudonym of the sender. /// - /// The dispatch origin for this call must be _Signed_. - /// - /// # - /// - Base weight: 2.861 µs - /// - Plus the weight of the `call` - /// # - #[weight = FunctionOf( - |args: (&u16, &Box<::Call>)| { - args.1.get_dispatch_info().weight.saturating_add(3_000_000) - }, - |args: (&u16, &Box<::Call>)| args.1.get_dispatch_info().class, - Pays::Yes, - )] - fn as_sub(origin, index: u16, call: Box<::Call>) -> DispatchResult { - let who = ensure_signed(origin)?; - let pseudonym = Self::sub_account_id(who, index); - call.dispatch(frame_system::RawOrigin::Signed(pseudonym).into()) - .map(|_| ()).map_err(|e| e.error) - } - - /// Register approval for a dispatch to be made from a deterministic composite account if - /// approved by a total of `threshold - 1` of `other_signatories`. + /// Filter from origin are passed along. The call will be dispatched with an origin which + /// use the same filter as the origin of this call. /// - /// If there are enough, then dispatch the call. + /// NOTE: If you need to ensure that any account-based filtering is not honored (i.e. + /// because you expect `proxy` to have been used prior in the call stack and you do not want + /// the call restrictions to apply to any sub-accounts), then use `as_multi_threshold_1` + /// in the Multisig pallet instead. /// - /// Payment: `MultisigDepositBase` will be reserved if this is the first approval, plus - /// `threshold` times `MultisigDepositFactor`. It is returned once this dispatch happens or - /// is cancelled. + /// NOTE: Prior to version *12, this was called `as_limited_sub`. /// /// The dispatch origin for this call must be _Signed_. - /// - /// - `threshold`: The total number of approvals for this dispatch before it is executed. - /// - `other_signatories`: The accounts (other than the sender) who can approve this - /// dispatch. May not be empty. - /// - `maybe_timepoint`: If this is the first approval, then this must be `None`. If it is - /// not the first approval, then it must be `Some`, with the timepoint (block number and - /// transaction index) of the first approval transaction. - /// - `call`: The call to be executed. - /// - /// NOTE: Unless this is the final approval, you will generally want to use - /// `approve_as_multi` instead, since it only requires a hash of the call. - /// - /// Result is equivalent to the dispatched result if `threshold` is exactly `1`. Otherwise - /// on success, result is `Ok` and the result from the interior call, if it was executed, - /// may be found in the deposited `MultisigExecuted` event. - /// - /// # - /// - `O(S + Z + Call)`. - /// - Up to one balance-reserve or unreserve operation. - /// - One passthrough operation, one insert, both `O(S)` where `S` is the number of - /// signatories. `S` is capped by `MaxSignatories`, with weight being proportional. - /// - One call encode & hash, both of complexity `O(Z)` where `Z` is tx-len. - /// - One encode & hash, both of complexity `O(S)`. - /// - Up to one binary search and insert (`O(logS + S)`). - /// - I/O: 1 read `O(S)`, up to 1 mutate `O(S)`. Up to one remove. - /// - One event. - /// - The weight of the `call`. - /// - Storage: inserts one item, value size bounded by `MaxSignatories`, with a - /// deposit taken for its lifetime of - /// `MultisigDepositBase + threshold * MultisigDepositFactor`. - /// ------------------------------- - /// - Base Weight: - /// - Create: 46.55 + 0.089 * S µs - /// - Approve: 34.03 + .112 * S µs - /// - Complete: 40.36 + .225 * S µs - /// - DB Weight: - /// - Reads: Multisig Storage, [Caller Account] - /// - Writes: Multisig Storage, [Caller Account] - /// - Plus Call Weight - /// # - #[weight = FunctionOf( - |args: (&u16, &Vec, &Option>, &Box<::Call>)| { - weight_of::as_multi::(args.1.len(),args.3.get_dispatch_info().weight) - }, - |args: (&u16, &Vec, &Option>, &Box<::Call>)| { - args.3.get_dispatch_info().class - }, - Pays::Yes, + #[weight = ( + T::WeightInfo::as_derivative() + .saturating_add(call.get_dispatch_info().weight), + call.get_dispatch_info().class, )] - fn as_multi(origin, - threshold: u16, - other_signatories: Vec, - maybe_timepoint: Option>, - call: Box<::Call>, - ) -> DispatchResultWithPostInfo { - let who = ensure_signed(origin)?; - ensure!(threshold >= 1, Error::::ZeroThreshold); - let max_sigs = T::MaxSignatories::get() as usize; - ensure!(!other_signatories.is_empty(), Error::::TooFewSignatories); - let other_signatories_len = other_signatories.len(); - ensure!(other_signatories_len < max_sigs, Error::::TooManySignatories); - let signatories = Self::ensure_sorted_and_insert(other_signatories, who.clone())?; - - let id = Self::multi_account_id(&signatories, threshold); - let call_hash = call.using_encoded(blake2_256); - - if let Some(mut m) = >::get(&id, call_hash) { - let timepoint = maybe_timepoint.ok_or(Error::::NoTimepoint)?; - ensure!(m.when == timepoint, Error::::WrongTimepoint); - if let Err(pos) = m.approvals.binary_search(&who) { - // we know threshold is greater than zero from the above ensure. - if (m.approvals.len() as u16) < threshold - 1 { - m.approvals.insert(pos, who.clone()); - >::insert(&id, call_hash, m); - Self::deposit_event(RawEvent::MultisigApproval(who, timepoint, id, call_hash)); - // Call is not made, so the actual weight does not include call - return Ok(Some(weight_of::as_multi::(other_signatories_len, 0)).into()) - } - } else { - if (m.approvals.len() as u16) < threshold { - Err(Error::::AlreadyApproved)? - } - } - - let result = call.dispatch(frame_system::RawOrigin::Signed(id.clone()).into()); - let _ = T::Currency::unreserve(&m.depositor, m.deposit); - >::remove(&id, call_hash); - Self::deposit_event(RawEvent::MultisigExecuted( - who, timepoint, id, call_hash, result.map(|_| ()).map_err(|e| e.error) - )); - return Ok(None.into()) - } else { - ensure!(maybe_timepoint.is_none(), Error::::UnexpectedTimepoint); - if threshold > 1 { - let deposit = T::MultisigDepositBase::get() - + T::MultisigDepositFactor::get() * threshold.into(); - T::Currency::reserve(&who, deposit)?; - >::insert(&id, call_hash, Multisig { - when: Self::timepoint(), - deposit, - depositor: who.clone(), - approvals: vec![who.clone()], - }); - Self::deposit_event(RawEvent::NewMultisig(who, id, call_hash)); - // Call is not made, so we can return that weight - return Ok(Some(weight_of::as_multi::(other_signatories_len, 0)).into()) - } else { - let result = call.dispatch(frame_system::RawOrigin::Signed(id).into()); - match result { - Ok(post_dispatch_info) => { - match post_dispatch_info.actual_weight { - Some(actual_weight) => return Ok(Some(weight_of::as_multi::(other_signatories_len, actual_weight)).into()), - None => return Ok(None.into()), - } - }, - Err(err) => { - match err.post_info.actual_weight { - Some(actual_weight) => { - let weight_used = weight_of::as_multi::(other_signatories_len, actual_weight); - return Err(DispatchErrorWithPostInfo { post_info: Some(weight_used).into(), error: err.error.into() }) - }, - None => { - return Err(err) - } - } - } - } - } - } - } - - /// Register approval for a dispatch to be made from a deterministic composite account if - /// approved by a total of `threshold - 1` of `other_signatories`. - /// - /// Payment: `MultisigDepositBase` will be reserved if this is the first approval, plus - /// `threshold` times `MultisigDepositFactor`. It is returned once this dispatch happens or - /// is cancelled. - /// - /// The dispatch origin for this call must be _Signed_. - /// - /// - `threshold`: The total number of approvals for this dispatch before it is executed. - /// - `other_signatories`: The accounts (other than the sender) who can approve this - /// dispatch. May not be empty. - /// - `maybe_timepoint`: If this is the first approval, then this must be `None`. If it is - /// not the first approval, then it must be `Some`, with the timepoint (block number and - /// transaction index) of the first approval transaction. - /// - `call_hash`: The hash of the call to be executed. - /// - /// NOTE: If this is the final approval, you will want to use `as_multi` instead. - /// - /// # - /// - `O(S)`. - /// - Up to one balance-reserve or unreserve operation. - /// - One passthrough operation, one insert, both `O(S)` where `S` is the number of - /// signatories. `S` is capped by `MaxSignatories`, with weight being proportional. - /// - One encode & hash, both of complexity `O(S)`. - /// - Up to one binary search and insert (`O(logS + S)`). - /// - I/O: 1 read `O(S)`, up to 1 mutate `O(S)`. Up to one remove. - /// - One event. - /// - Storage: inserts one item, value size bounded by `MaxSignatories`, with a - /// deposit taken for its lifetime of - /// `MultisigDepositBase + threshold * MultisigDepositFactor`. - /// ---------------------------------- - /// - Base Weight: - /// - Create: 44.71 + 0.088 * S - /// - Approve: 31.48 + 0.116 * S - /// - DB Weight: - /// - Read: Multisig Storage, [Caller Account] - /// - Write: Multisig Storage, [Caller Account] - /// # - #[weight = FunctionOf( - |args: (&u16, &Vec, &Option>, &[u8; 32])| { - T::DbWeight::get().reads_writes(1, 1) - .saturating_add(45_000_000) - .saturating_add((args.1.len() as Weight).saturating_mul(120_000)) - }, - DispatchClass::Normal, - Pays::Yes, - )] - fn approve_as_multi(origin, - threshold: u16, - other_signatories: Vec, - maybe_timepoint: Option>, - call_hash: [u8; 32], - ) -> DispatchResult { - let who = ensure_signed(origin)?; - ensure!(threshold >= 1, Error::::ZeroThreshold); - let max_sigs = T::MaxSignatories::get() as usize; - ensure!(!other_signatories.is_empty(), Error::::TooFewSignatories); - ensure!(other_signatories.len() < max_sigs, Error::::TooManySignatories); - let signatories = Self::ensure_sorted_and_insert(other_signatories, who.clone())?; - - let id = Self::multi_account_id(&signatories, threshold); - - if let Some(mut m) = >::get(&id, call_hash) { - let timepoint = maybe_timepoint.ok_or(Error::::NoTimepoint)?; - ensure!(m.when == timepoint, Error::::WrongTimepoint); - ensure!(m.approvals.len() < threshold as usize, Error::::NoApprovalsNeeded); - if let Err(pos) = m.approvals.binary_search(&who) { - m.approvals.insert(pos, who.clone()); - >::insert(&id, call_hash, m); - Self::deposit_event(RawEvent::MultisigApproval(who, timepoint, id, call_hash)); - } else { - Err(Error::::AlreadyApproved)? - } - } else { - if threshold > 1 { - ensure!(maybe_timepoint.is_none(), Error::::UnexpectedTimepoint); - let deposit = T::MultisigDepositBase::get() - + T::MultisigDepositFactor::get() * threshold.into(); - T::Currency::reserve(&who, deposit)?; - >::insert(&id, call_hash, Multisig { - when: Self::timepoint(), - deposit, - depositor: who.clone(), - approvals: vec![who.clone()], - }); - Self::deposit_event(RawEvent::NewMultisig(who, id, call_hash)); - } else { - Err(Error::::NoApprovalsNeeded)? - } - } - Ok(()) - } - - /// Cancel a pre-existing, on-going multisig transaction. Any deposit reserved previously - /// for this operation will be unreserved on success. - /// - /// The dispatch origin for this call must be _Signed_. - /// - /// - `threshold`: The total number of approvals for this dispatch before it is executed. - /// - `other_signatories`: The accounts (other than the sender) who can approve this - /// dispatch. May not be empty. - /// - `timepoint`: The timepoint (block number and transaction index) of the first approval - /// transaction for this dispatch. - /// - `call_hash`: The hash of the call to be executed. - /// - /// # - /// - `O(S)`. - /// - Up to one balance-reserve or unreserve operation. - /// - One passthrough operation, one insert, both `O(S)` where `S` is the number of - /// signatories. `S` is capped by `MaxSignatories`, with weight being proportional. - /// - One encode & hash, both of complexity `O(S)`. - /// - One event. - /// - I/O: 1 read `O(S)`, one remove. - /// - Storage: removes one item. - /// ---------------------------------- - /// - Base Weight: 37.6 + 0.084 * S - /// - DB Weight: - /// - Read: Multisig Storage, [Caller Account] - /// - Write: Multisig Storage, [Caller Account] - /// # - #[weight = FunctionOf( - |args: (&u16, &Vec, &Timepoint, &[u8; 32])| { - T::DbWeight::get().reads_writes(1, 1) - .saturating_add(40_000_000) - .saturating_add((args.1.len() as Weight).saturating_mul(100_000)) - }, - DispatchClass::Normal, - Pays::Yes, - )] - fn cancel_as_multi(origin, - threshold: u16, - other_signatories: Vec, - timepoint: Timepoint, - call_hash: [u8; 32], - ) -> DispatchResult { - let who = ensure_signed(origin)?; - ensure!(threshold >= 1, Error::::ZeroThreshold); - let max_sigs = T::MaxSignatories::get() as usize; - ensure!(!other_signatories.is_empty(), Error::::TooFewSignatories); - ensure!(other_signatories.len() < max_sigs, Error::::TooManySignatories); - let signatories = Self::ensure_sorted_and_insert(other_signatories, who.clone())?; - - let id = Self::multi_account_id(&signatories, threshold); - - let m = >::get(&id, call_hash) - .ok_or(Error::::NotFound)?; - ensure!(m.when == timepoint, Error::::WrongTimepoint); - ensure!(m.depositor == who, Error::::NotOwner); - - let _ = T::Currency::unreserve(&m.depositor, m.deposit); - >::remove(&id, call_hash); - - Self::deposit_event(RawEvent::MultisigCancelled(who, timepoint, id, call_hash)); - Ok(()) + fn as_derivative(origin, index: u16, call: Box<::Call>) -> DispatchResult { + let mut origin = origin; + let who = ensure_signed(origin.clone())?; + let pseudonym = Self::derivative_account_id(who, index); + origin.set_caller_from(frame_system::RawOrigin::Signed(pseudonym)); + call.dispatch(origin).map(|_| ()).map_err(|e| e.error) } } } impl Module { - /// Derive a sub-account ID from the owner account and the sub-account index. - pub fn sub_account_id(who: T::AccountId, index: u16) -> T::AccountId { + /// Derive a derivative account ID from the owner account and the sub-account index. + pub fn derivative_account_id(who: T::AccountId, index: u16) -> T::AccountId { let entropy = (b"modlpy/utilisuba", who, index).using_encoded(blake2_256); T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() } - - /// Derive a multi-account ID from the sorted list of accounts and the threshold that are - /// required. - /// - /// NOTE: `who` must be sorted. If it is not, then you'll get the wrong answer. - pub fn multi_account_id(who: &[T::AccountId], threshold: u16) -> T::AccountId { - let entropy = (b"modlpy/utilisuba", who, threshold).using_encoded(blake2_256); - T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() - } - - /// The current `Timepoint`. - pub fn timepoint() -> Timepoint { - Timepoint { - height: >::block_number(), - index: >::extrinsic_index().unwrap_or_default(), - } - } - - /// Check that signatories is sorted and doesn't contain sender, then insert sender. - fn ensure_sorted_and_insert(other_signatories: Vec, who: T::AccountId) - -> Result, DispatchError> - { - let mut signatories = other_signatories; - let mut maybe_last = None; - let mut index = 0; - for item in signatories.iter() { - if let Some(last) = maybe_last { - ensure!(last < item, Error::::SignatoriesOutOfOrder); - } - if item <= &who { - ensure!(item != &who, Error::::SenderInSignatories); - index += 1; - } - maybe_last = Some(item); - } - signatories.insert(index, who); - Ok(signatories) - } } diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index 360ff78d308c9235d85c04a1829eb01f3748b9b2..611c42907ca045a335d322ec786165e6213fb336 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // Tests for Utility Pallet @@ -22,7 +23,7 @@ use super::*; use frame_support::{ assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch, - weights::Weight, impl_outer_event + weights::Weight, impl_outer_event, dispatch::DispatchError, traits::Filter, storage, }; use sp_core::H256; use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; @@ -31,12 +32,11 @@ use crate as utility; impl_outer_origin! { pub enum Origin for Test where system = frame_system {} } - impl_outer_event! { pub enum TestEvent for Test { - system, + frame_system, pallet_balances, - utility, + utility, } } impl_outer_dispatch! { @@ -54,11 +54,12 @@ impl_outer_dispatch! { pub struct Test; parameter_types! { pub const BlockHashCount: u64 = 250; - pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockWeight: Weight = Weight::max_value(); pub const MaximumBlockLength: u32 = 2 * 1024; pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = TestBaseCallFilter; type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -74,6 +75,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -81,41 +83,52 @@ impl frame_system::Trait for Test { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { pub const ExistentialDeposit: u64 = 1; } impl pallet_balances::Trait for Test { type Balance = u64; - type Event = TestEvent; type DustRemoval = (); + type Event = TestEvent; type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { pub const MultisigDepositBase: u64 = 1; pub const MultisigDepositFactor: u64 = 1; pub const MaxSignatories: u16 = 3; } +pub struct TestBaseCallFilter; +impl Filter for TestBaseCallFilter { + fn filter(c: &Call) -> bool { + match *c { + Call::Balances(_) => true, + // For benchmarking, this acts as a noop call + Call::System(frame_system::Call::remark(..)) => true, + _ => false, + } + } +} impl Trait for Test { type Event = TestEvent; type Call = Call; - type Currency = Balances; - type MultisigDepositBase = MultisigDepositBase; - type MultisigDepositFactor = MultisigDepositFactor; - type MaxSignatories = MaxSignatories; + type WeightInfo = (); } type System = frame_system::Module; type Balances = pallet_balances::Module; type Utility = Module; +use frame_system::Call as SystemCall; use pallet_balances::Call as BalancesCall; use pallet_balances::Error as BalancesError; pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig:: { - balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 10)], + balances: vec![(1, 10), (2, 10), (3, 10), (4, 10), (5, 2)], }.assimilate_storage(&mut t).unwrap(); let mut ext = sp_io::TestExternalities::new(t); ext.execute_with(|| System::set_block_number(1)); @@ -123,271 +136,24 @@ pub fn new_test_ext() -> sp_io::TestExternalities { } fn last_event() -> TestEvent { - system::Module::::events().pop().map(|e| e.event).expect("Event expected") + frame_system::Module::::events().pop().map(|e| e.event).expect("Event expected") } fn expect_event>(e: E) { assert_eq!(last_event(), e.into()); } -fn now() -> Timepoint { - Utility::timepoint() -} - -#[test] -fn multisig_deposit_is_taken_and_returned() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); - assert_eq!(Balances::free_balance(1), 2); - assert_eq!(Balances::reserved_balance(1), 3); - - assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call)); - assert_eq!(Balances::free_balance(1), 5); - assert_eq!(Balances::reserved_balance(1), 0); - }); -} - -#[test] -fn cancel_multisig_returns_deposit() { - new_test_ext().execute_with(|| { - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone())); - assert_ok!(Utility::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone())); - assert_eq!(Balances::free_balance(1), 6); - assert_eq!(Balances::reserved_balance(1), 4); - assert_ok!( - Utility::cancel_as_multi(Origin::signed(1), 3, vec![2, 3], now(), hash.clone()), - ); - assert_eq!(Balances::free_balance(1), 10); - assert_eq!(Balances::reserved_balance(1), 0); - }); -} - -#[test] -fn timepoint_checking_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - - assert_noop!( - Utility::approve_as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), hash.clone()), - Error::::UnexpectedTimepoint, - ); - - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash)); - - assert_noop!( - Utility::as_multi(Origin::signed(2), 2, vec![1, 3], None, call.clone()), - Error::::NoTimepoint, - ); - let later = Timepoint { index: 1, .. now() }; - assert_noop!( - Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(later), call.clone()), - Error::::WrongTimepoint, - ); - }); -} - -#[test] -fn multisig_2_of_3_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash)); - assert_eq!(Balances::free_balance(6), 0); - - assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call)); - assert_eq!(Balances::free_balance(6), 15); - }); -} - -#[test] -fn multisig_3_of_3_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 3); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone())); - assert_ok!(Utility::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone())); - assert_eq!(Balances::free_balance(6), 0); - - assert_ok!(Utility::as_multi(Origin::signed(3), 3, vec![1, 2], Some(now()), call)); - assert_eq!(Balances::free_balance(6), 15); - }); -} - -#[test] -fn cancel_multisig_works() { - new_test_ext().execute_with(|| { - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 3, vec![2, 3], None, hash.clone())); - assert_ok!(Utility::approve_as_multi(Origin::signed(2), 3, vec![1, 3], Some(now()), hash.clone())); - assert_noop!( - Utility::cancel_as_multi(Origin::signed(2), 3, vec![1, 3], now(), hash.clone()), - Error::::NotOwner, - ); - assert_ok!( - Utility::cancel_as_multi(Origin::signed(1), 3, vec![2, 3], now(), hash.clone()), - ); - }); -} - -#[test] -fn multisig_2_of_3_as_multi_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); - assert_eq!(Balances::free_balance(6), 0); - - assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call)); - assert_eq!(Balances::free_balance(6), 15); - }); -} - -#[test] -fn multisig_2_of_3_as_multi_with_many_calls_works() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call1 = Box::new(Call::Balances(BalancesCall::transfer(6, 10))); - let call2 = Box::new(Call::Balances(BalancesCall::transfer(7, 5))); - - assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call1.clone())); - assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], None, call2.clone())); - assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call2)); - assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call1)); - - assert_eq!(Balances::free_balance(6), 10); - assert_eq!(Balances::free_balance(7), 5); - }); -} - -#[test] -fn multisig_2_of_3_cannot_reissue_same_call() { - new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 2); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 10))); - assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); - assert_ok!(Utility::as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), call.clone())); - assert_eq!(Balances::free_balance(multi), 5); - - assert_ok!(Utility::as_multi(Origin::signed(1), 2, vec![2, 3], None, call.clone())); - assert_ok!(Utility::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), call.clone())); - - let err = DispatchError::from(BalancesError::::InsufficientBalance).stripped(); - expect_event(RawEvent::MultisigExecuted(3, now(), multi, call.using_encoded(blake2_256), Err(err))); - }); -} - -#[test] -fn zero_threshold_fails() { - new_test_ext().execute_with(|| { - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - assert_noop!( - Utility::as_multi(Origin::signed(1), 0, vec![2], None, call), - Error::::ZeroThreshold, - ); - }); -} - -#[test] -fn too_many_signatories_fails() { - new_test_ext().execute_with(|| { - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - assert_noop!( - Utility::as_multi(Origin::signed(1), 2, vec![2, 3, 4], None, call.clone()), - Error::::TooManySignatories, - ); - }); -} - -#[test] -fn duplicate_approvals_are_ignored() { - new_test_ext().execute_with(|| { - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_ok!(Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], None, hash.clone())); - assert_noop!( - Utility::approve_as_multi(Origin::signed(1), 2, vec![2, 3], Some(now()), hash.clone()), - Error::::AlreadyApproved, - ); - assert_ok!(Utility::approve_as_multi(Origin::signed(2), 2, vec![1, 3], Some(now()), hash.clone())); - assert_noop!( - Utility::approve_as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), hash.clone()), - Error::::NoApprovalsNeeded, - ); - }); -} - #[test] -fn multisig_1_of_3_works() { +fn as_derivative_works() { new_test_ext().execute_with(|| { - let multi = Utility::multi_account_id(&[1, 2, 3][..], 1); - assert_ok!(Balances::transfer(Origin::signed(1), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(2), multi, 5)); - assert_ok!(Balances::transfer(Origin::signed(3), multi, 5)); - - let call = Box::new(Call::Balances(BalancesCall::transfer(6, 15))); - let hash = call.using_encoded(blake2_256); - assert_noop!( - Utility::approve_as_multi(Origin::signed(1), 1, vec![2, 3], None, hash.clone()), - Error::::NoApprovalsNeeded, - ); - assert_noop!( - Utility::as_multi(Origin::signed(4), 1, vec![2, 3], None, call.clone()), - BalancesError::::InsufficientBalance, - ); - assert_ok!(Utility::as_multi(Origin::signed(1), 1, vec![2, 3], None, call)); - - assert_eq!(Balances::free_balance(6), 15); - }); -} - -#[test] -fn as_sub_works() { - new_test_ext().execute_with(|| { - let sub_1_0 = Utility::sub_account_id(1, 0); + let sub_1_0 = Utility::derivative_account_id(1, 0); assert_ok!(Balances::transfer(Origin::signed(1), sub_1_0, 5)); - assert_noop!(Utility::as_sub( + assert_noop!(Utility::as_derivative( Origin::signed(1), 1, Box::new(Call::Balances(BalancesCall::transfer(6, 3))), ), BalancesError::::InsufficientBalance); - assert_ok!(Utility::as_sub( + assert_ok!(Utility::as_derivative( Origin::signed(1), 0, Box::new(Call::Balances(BalancesCall::transfer(2, 3))), @@ -397,17 +163,33 @@ fn as_sub_works() { }); } +#[test] +fn as_derivative_filters() { + new_test_ext().execute_with(|| { + assert_noop!(Utility::as_derivative( + Origin::signed(1), + 1, + Box::new(Call::System(frame_system::Call::suicide())), + ), DispatchError::BadOrigin); + }); +} + #[test] fn batch_with_root_works() { new_test_ext().execute_with(|| { + let k = b"a".to_vec(); + let call = Call::System(frame_system::Call::set_storage(vec![(k.clone(), k.clone())])); + assert!(!TestBaseCallFilter::filter(&call)); assert_eq!(Balances::free_balance(1), 10); assert_eq!(Balances::free_balance(2), 10); - assert_ok!(Utility::batch(Origin::ROOT, vec![ + assert_ok!(Utility::batch(Origin::root(), vec![ + Call::Balances(BalancesCall::force_transfer(1, 2, 5)), Call::Balances(BalancesCall::force_transfer(1, 2, 5)), - Call::Balances(BalancesCall::force_transfer(1, 2, 5)) + call, // Check filters are correctly bypassed ])); assert_eq!(Balances::free_balance(1), 0); assert_eq!(Balances::free_balance(2), 20); + assert_eq!(storage::unhashed::get_raw(&k), Some(k)); }); } @@ -427,6 +209,18 @@ fn batch_with_signed_works() { }); } +#[test] +fn batch_with_signed_filters() { + new_test_ext().execute_with(|| { + assert_ok!( + Utility::batch(Origin::signed(1), vec![ + Call::System(frame_system::Call::suicide()) + ]), + ); + expect_event(Event::BatchInterrupted(0, DispatchError::BadOrigin)); + }); +} + #[test] fn batch_early_exit_works() { new_test_ext().execute_with(|| { @@ -443,3 +237,20 @@ fn batch_early_exit_works() { assert_eq!(Balances::free_balance(2), 15); }); } + +#[test] +fn batch_weight_calculation_doesnt_overflow() { + new_test_ext().execute_with(|| { + let big_call = Call::System(SystemCall::fill_block(Perbill::from_percent(50))); + assert_eq!(big_call.get_dispatch_info().weight, Weight::max_value() / 2); + + // 3 * 50% saturates to 100% + let batch_call = Call::Utility(crate::Call::batch(vec![ + big_call.clone(), + big_call.clone(), + big_call.clone(), + ])); + + assert_eq!(batch_call.get_dispatch_info().weight, Weight::max_value()); + }); +} diff --git a/frame/vesting/Cargo.toml b/frame/vesting/Cargo.toml index 79430990c32474410bcb6ebfd1dae8cf7a34bec2..9ef11a2141ba0a30f67edf35face9fdf1582d5c9 100644 --- a/frame/vesting/Cargo.toml +++ b/frame/vesting/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-vesting" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for manage vesting" @@ -13,20 +13,20 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } enumflags2 = { version = "0.6.2" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -frame-benchmarking = { version = "2.0.0-dev", default-features = false, path = "../benchmarking", optional = true } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -pallet-balances = { version = "2.0.0-dev", path = "../balances" } -sp-storage = { version = "2.0.0-dev", path = "../../primitives/storage" } -hex-literal = "0.2.1" +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +sp-storage = { version = "2.0.0-rc6", path = "../../primitives/storage" } +hex-literal = "0.3.1" [features] default = ["std"] @@ -34,7 +34,6 @@ std = [ "serde", "codec/std", "sp-std/std", - "sp-io/std", "sp-runtime/std", "frame-support/std", "frame-system/std", diff --git a/frame/vesting/README.md b/frame/vesting/README.md new file mode 100644 index 0000000000000000000000000000000000000000..56f49db2647f11d591a46f17058eb6c6c45d097c --- /dev/null +++ b/frame/vesting/README.md @@ -0,0 +1,31 @@ +# Vesting Module + +- [`vesting::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) + +## Overview + +A simple module providing a means of placing a linear curve on an account's locked balance. This +module ensures that there is a lock in place preventing the balance to drop below the *unvested* +amount for any reason other than transaction fee payment. + +As the amount vested increases over time, the amount unvested reduces. However, locks remain in +place and explicit action is needed on behalf of the user to ensure that the amount locked is +equivalent to the amount remaining to be vested. This is done through a dispatchable function, +either `vest` (in typical case where the sender is calling on their own behalf) or `vest_other` +in case the sender is calling on another account's behalf. + +## Interface + +This module implements the `VestingSchedule` trait. + +### Dispatchable Functions + +- `vest` - Update the lock, reducing it in line with the amount "vested" so far. +- `vest_other` - Update the lock of another account, reducing it in line with the amount + "vested" so far. + +[`Call`]: ./enum.Call.html +[`Trait`]: ./trait.Trait.html + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/vesting/src/benchmarking.rs b/frame/vesting/src/benchmarking.rs index 10f19af65ee186ab1be9b5b0c6b5a194de1b3524..974289aac321817f0f9a83707adf2108e33b7025 100644 --- a/frame/vesting/src/benchmarking.rs +++ b/frame/vesting/src/benchmarking.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Vesting pallet benchmarking. @@ -21,7 +22,7 @@ use super::*; use frame_system::{RawOrigin, Module as System}; -use frame_benchmarking::{benchmarks, account}; +use frame_benchmarking::{benchmarks, account, whitelisted_caller}; use sp_runtime::traits::Bounded; use crate::Module as Vesting; @@ -63,7 +64,7 @@ benchmarks! { vest_locked { let l in 0 .. MAX_LOCKS; - let caller = account("caller", 0, SEED); + let caller = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); add_locks::(&caller, l as u8); add_vesting_schedule::(&caller)?; @@ -87,7 +88,7 @@ benchmarks! { vest_unlocked { let l in 0 .. MAX_LOCKS; - let caller = account("caller", 0, SEED); + let caller = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); add_locks::(&caller, l as u8); add_vesting_schedule::(&caller)?; @@ -124,7 +125,7 @@ benchmarks! { "Vesting schedule not added", ); - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); }: vest_other(RawOrigin::Signed(caller.clone()), other_lookup) verify { // Nothing happened since everything is still vested. @@ -151,7 +152,7 @@ benchmarks! { "Vesting schedule still active", ); - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); }: vest_other(RawOrigin::Signed(caller.clone()), other_lookup) verify { // Vesting schedule is removed! @@ -165,7 +166,7 @@ benchmarks! { vested_transfer { let l in 0 .. MAX_LOCKS; - let caller: T::AccountId = account("caller", 0, SEED); + let caller: T::AccountId = whitelisted_caller(); T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); let target: T::AccountId = account("target", 0, SEED); let target_lookup: ::Source = T::Lookup::unlookup(target.clone()); diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 6d1b88efbcd65325ee8d0f6cbbaa0045488618d1..c521af1e03c597a7e48aea1fd299f210d13f6849 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Vesting Module //! @@ -50,20 +51,35 @@ use sp_std::prelude::*; use sp_std::fmt::Debug; use codec::{Encode, Decode}; use sp_runtime::{DispatchResult, RuntimeDebug, traits::{ - StaticLookup, Zero, AtLeast32Bit, MaybeSerializeDeserialize, Convert + StaticLookup, Zero, AtLeast32BitUnsigned, MaybeSerializeDeserialize, Convert }}; -use frame_support::{decl_module, decl_event, decl_storage, decl_error, ensure}; +use frame_support::{decl_module, decl_event, decl_storage, decl_error, ensure, weights::Weight}; use frame_support::traits::{ Currency, LockableCurrency, VestingSchedule, WithdrawReason, LockIdentifier, - ExistenceRequirement, Get + ExistenceRequirement, Get, }; - -use frame_system::{self as system, ensure_signed}; +use frame_system::{ensure_signed, ensure_root}; mod benchmarking; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; +pub trait WeightInfo { + fn vest_locked(l: u32, ) -> Weight; + fn vest_unlocked(l: u32, ) -> Weight; + fn vest_other_locked(l: u32, ) -> Weight; + fn vest_other_unlocked(l: u32, ) -> Weight; + fn vested_transfer(l: u32, ) -> Weight; +} + +impl WeightInfo for () { + fn vest_locked(_l: u32, ) -> Weight { 1_000_000_000 } + fn vest_unlocked(_l: u32, ) -> Weight { 1_000_000_000 } + fn vest_other_locked(_l: u32, ) -> Weight { 1_000_000_000 } + fn vest_other_unlocked(_l: u32, ) -> Weight { 1_000_000_000 } + fn vested_transfer(_l: u32, ) -> Weight { 1_000_000_000 } +} + pub trait Trait: frame_system::Trait { /// The overarching event type. type Event: From> + Into<::Event>; @@ -76,6 +92,9 @@ pub trait Trait: frame_system::Trait { /// The minimum amount transferred to call `vested_transfer`. type MinVestedTransfer: Get>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } const VESTING_ID: LockIdentifier = *b"vesting "; @@ -92,8 +111,8 @@ pub struct VestingInfo { } impl< - Balance: AtLeast32Bit + Copy, - BlockNumber: AtLeast32Bit + Copy, + Balance: AtLeast32BitUnsigned + Copy, + BlockNumber: AtLeast32BitUnsigned + Copy, > VestingInfo { /// Amount locked at block `n`. pub fn locked_at< @@ -152,9 +171,10 @@ decl_storage! { decl_event!( pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { /// The amount vested has been updated. This could indicate more funds are available. The - /// balance given is the amount which is left unvested (and thus locked). + /// balance given is the amount which is left unvested (and thus locked). + /// [account, unvested] VestingUpdated(AccountId, Balance), - /// An account (given) has become fully vested. No further vesting can happen. + /// An [account] has become fully vested. No further vesting can happen. VestingCompleted(AccountId), } ); @@ -266,6 +286,47 @@ decl_module! { Ok(()) } + + /// Force a vested transfer. + /// + /// The dispatch origin for this call must be _Root_. + /// + /// - `source`: The account whose funds should be transferred. + /// - `target`: The account that should be transferred the vested funds. + /// - `amount`: The amount of funds to transfer and will be vested. + /// - `schedule`: The vesting schedule attached to the transfer. + /// + /// Emits `VestingCreated`. + /// + /// # + /// - `O(1)`. + /// - DbWeight: 4 Reads, 4 Writes + /// - Reads: Vesting Storage, Balances Locks, Target Account, Source Account + /// - Writes: Vesting Storage, Balances Locks, Target Account, Source Account + /// - Benchmark: 100.3 + .365 * l µs (min square analysis) + /// - Using 100 µs fixed. Assuming less than 50 locks on any user, else we may want factor in number of locks. + /// # + #[weight = 100_000_000 + T::DbWeight::get().reads_writes(4, 4)] + pub fn force_vested_transfer( + origin, + source: ::Source, + target: ::Source, + schedule: VestingInfo, T::BlockNumber>, + ) -> DispatchResult { + ensure_root(origin)?; + ensure!(schedule.locked >= T::MinVestedTransfer::get(), Error::::AmountLow); + + let target = T::Lookup::lookup(target)?; + let source = T::Lookup::lookup(source)?; + ensure!(!Vesting::::contains_key(&target), Error::::ExistingVestingSchedule); + + T::Currency::transfer(&source, &target, schedule.locked, ExistenceRequirement::AllowDeath)?; + + Self::add_vesting_schedule(&target, schedule.locked, schedule.per_block, schedule.starting_block) + .expect("user does not have an existing vesting schedule; q.e.d."); + + Ok(()) + } } } @@ -356,21 +417,17 @@ mod tests { traits::Get }; use sp_core::H256; - // The testing primitives are very useful for avoiding having to work with signatures - // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{ Perbill, testing::Header, - traits::{BlakeTwo256, IdentityLookup, Identity}, + traits::{BlakeTwo256, IdentityLookup, Identity, BadOrigin}, }; + use frame_system::RawOrigin; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } - // For testing the pallet, we construct most of a mock runtime. This means - // first constructing a configuration type (`Test`) which `impl`s each of the - // configuration traits of pallets we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -380,6 +437,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -395,6 +453,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -402,6 +461,7 @@ mod tests { type AccountData = pallet_balances::AccountData; type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl pallet_balances::Trait for Test { type Balance = u64; @@ -409,6 +469,7 @@ mod tests { type Event = (); type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; + type WeightInfo = (); } parameter_types! { pub const MinVestedTransfer: u64 = 256 * 2; @@ -418,6 +479,7 @@ mod tests { type Currency = Balances; type BlockNumberToBalance = Identity; type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = (); } type System = frame_system::Module; type Balances = pallet_balances::Module; @@ -716,4 +778,94 @@ mod tests { assert_eq!(user4_free_balance, 256 * 40); }); } + + #[test] + fn force_vested_transfer_works() { + ExtBuilder::default() + .existential_deposit(256) + .build() + .execute_with(|| { + let user3_free_balance = Balances::free_balance(&3); + let user4_free_balance = Balances::free_balance(&4); + assert_eq!(user3_free_balance, 256 * 30); + assert_eq!(user4_free_balance, 256 * 40); + // Account 4 should not have any vesting yet. + assert_eq!(Vesting::vesting(&4), None); + // Make the schedule for the new transfer. + let new_vesting_schedule = VestingInfo { + locked: 256 * 5, + per_block: 64, // Vesting over 20 blocks + starting_block: 10, + }; + assert_noop!(Vesting::force_vested_transfer(Some(4).into(), 3, 4, new_vesting_schedule), BadOrigin); + assert_ok!(Vesting::force_vested_transfer(RawOrigin::Root.into(), 3, 4, new_vesting_schedule)); + // Now account 4 should have vesting. + assert_eq!(Vesting::vesting(&4), Some(new_vesting_schedule)); + // Ensure the transfer happened correctly. + let user3_free_balance_updated = Balances::free_balance(&3); + assert_eq!(user3_free_balance_updated, 256 * 25); + let user4_free_balance_updated = Balances::free_balance(&4); + assert_eq!(user4_free_balance_updated, 256 * 45); + // Account 4 has 5 * 256 locked. + assert_eq!(Vesting::vesting_balance(&4), Some(256 * 5)); + + System::set_block_number(20); + assert_eq!(System::block_number(), 20); + + // Account 4 has 5 * 64 units vested by block 20. + assert_eq!(Vesting::vesting_balance(&4), Some(10 * 64)); + + System::set_block_number(30); + assert_eq!(System::block_number(), 30); + + // Account 4 has fully vested. + assert_eq!(Vesting::vesting_balance(&4), Some(0)); + }); + } + + #[test] + fn force_vested_transfer_correctly_fails() { + ExtBuilder::default() + .existential_deposit(256) + .build() + .execute_with(|| { + let user2_free_balance = Balances::free_balance(&2); + let user4_free_balance = Balances::free_balance(&4); + assert_eq!(user2_free_balance, 256 * 20); + assert_eq!(user4_free_balance, 256 * 40); + // Account 2 should already have a vesting schedule. + let user2_vesting_schedule = VestingInfo { + locked: 256 * 20, + per_block: 256, // Vesting over 20 blocks + starting_block: 10, + }; + assert_eq!(Vesting::vesting(&2), Some(user2_vesting_schedule)); + + // The vesting schedule we will try to create, fails due to pre-existence of schedule. + let new_vesting_schedule = VestingInfo { + locked: 256 * 5, + per_block: 64, // Vesting over 20 blocks + starting_block: 10, + }; + assert_noop!( + Vesting::force_vested_transfer(RawOrigin::Root.into(), 4, 2, new_vesting_schedule), + Error::::ExistingVestingSchedule, + ); + + // Fails due to too low transfer amount. + let new_vesting_schedule_too_low = VestingInfo { + locked: 256 * 1, + per_block: 64, + starting_block: 10, + }; + assert_noop!( + Vesting::force_vested_transfer(RawOrigin::Root.into(), 3, 4, new_vesting_schedule_too_low), + Error::::AmountLow, + ); + + // Verify no currency transfer happened. + assert_eq!(user2_free_balance, 256 * 20); + assert_eq!(user4_free_balance, 256 * 40); + }); + } } diff --git a/primitives/allocator/Cargo.toml b/primitives/allocator/Cargo.toml index 8530e0df0e7d22246eb4effa84ab35bd74fb7bab..6ee6c333344aa8b4114b6df1438e6f58d054b04b 100644 --- a/primitives/allocator/Cargo.toml +++ b/primitives/allocator/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-allocator" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Collection of allocator implementations." @@ -13,9 +13,9 @@ documentation = "https://docs.rs/sp-allocator" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-std = { version = "2.0.0-dev", path = "../std", default-features = false } -sp-core = { version = "2.0.0-dev", path = "../core", default-features = false } -sp-wasm-interface = { version = "2.0.0-dev", path = "../wasm-interface", default-features = false } +sp-std = { version = "2.0.0-rc6", path = "../std", default-features = false } +sp-core = { version = "2.0.0-rc6", path = "../core", default-features = false } +sp-wasm-interface = { version = "2.0.0-rc6", path = "../wasm-interface", default-features = false } log = { version = "0.4.8", optional = true } derive_more = { version = "0.99.2", optional = true } diff --git a/primitives/allocator/README.md b/primitives/allocator/README.md new file mode 100644 index 0000000000000000000000000000000000000000..361feaae591f903caad2ff1909e173f6a2240c0c --- /dev/null +++ b/primitives/allocator/README.md @@ -0,0 +1,6 @@ +Collection of allocator implementations. + +This crate provides the following allocator implementations: +- A freeing-bump allocator: [`FreeingBumpHeapAllocator`](freeing_bump::FreeingBumpHeapAllocator) + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/allocator/src/error.rs b/primitives/allocator/src/error.rs index 9357bc456003bd440f6067c41e567d1c8ad302b8..7b634af4d5b295e4fd0cc3691778186319bcde75 100644 --- a/primitives/allocator/src/error.rs +++ b/primitives/allocator/src/error.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. /// The error type used by the allocators. #[derive(sp_core::RuntimeDebug)] diff --git a/primitives/allocator/src/freeing_bump.rs b/primitives/allocator/src/freeing_bump.rs index 0d15ed11f74e0ba6fb22d1d3dde0b35e3e04f2ad..a9cb89c55b5712e805155b0ddf07fcce043b5696 100644 --- a/primitives/allocator/src/freeing_bump.rs +++ b/primitives/allocator/src/freeing_bump.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! This module implements a freeing-bump allocator. //! diff --git a/primitives/allocator/src/lib.rs b/primitives/allocator/src/lib.rs index 0efadbc7f6d60299ee5104600884b3f34692d8e5..b7cfce8048354d8f005af6e9c5d88d480bfa2e92 100644 --- a/primitives/allocator/src/lib.rs +++ b/primitives/allocator/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Collection of allocator implementations. //! diff --git a/primitives/api/Cargo.toml b/primitives/api/Cargo.toml index 43decc4f6e60b62e2057661469158e72d78a592d..e1e3dd76d4725f9c3bad86d64b3d9ebd4278373f 100644 --- a/primitives/api/Cargo.toml +++ b/primitives/api/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-api" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate runtime api primitives" @@ -12,17 +12,17 @@ description = "Substrate runtime api primitives" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-api-proc-macro = { version = "2.0.0-dev", path = "proc-macro" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } -sp-version = { version = "2.0.0-dev", default-features = false, path = "../version" } -sp-state-machine = { version = "0.8.0-dev", optional = true, path = "../../primitives/state-machine" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } +sp-api-proc-macro = { version = "2.0.0-rc6", path = "proc-macro" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../runtime" } +sp-version = { version = "2.0.0-rc6", default-features = false, path = "../version" } +sp-state-machine = { version = "0.8.0-rc6", optional = true, path = "../../primitives/state-machine" } hash-db = { version = "0.15.2", optional = true } [dev-dependencies] -sp-test-primitives = { version = "2.0.0-dev", path = "../test-primitives" } +sp-test-primitives = { version = "2.0.0-rc6", path = "../test-primitives" } [features] default = [ "std" ] diff --git a/primitives/api/README.md b/primitives/api/README.md new file mode 100644 index 0000000000000000000000000000000000000000..551de2f82e3659300fa4bad2f09cf5f373e794fc --- /dev/null +++ b/primitives/api/README.md @@ -0,0 +1,17 @@ +Substrate runtime api + +The Substrate runtime api is the crucial interface between the node and the runtime. +Every call that goes into the runtime is done with a runtime api. The runtime apis are not fixed. +Every Substrate user can define its own apis with +[`decl_runtime_apis`](macro.decl_runtime_apis.html) and implement them in +the runtime with [`impl_runtime_apis`](macro.impl_runtime_apis.html). + +Every Substrate runtime needs to implement the [`Core`] runtime api. This api provides the basic +functionality that every runtime needs to export. + +Besides the macros and the [`Core`] runtime api, this crates provides the [`Metadata`] runtime +api, the [`ApiExt`] trait, the [`CallApiAt`] trait and the [`ConstructRuntimeApi`] trait. + +On a meta level this implies, the client calls the generated API from the client perspective. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/api/proc-macro/Cargo.toml b/primitives/api/proc-macro/Cargo.toml index a970b3e750a87941b9cb4dd05f7411664e3a378c..b7d0bd16050c3bd92376066e78a00dbfe7d8c099 100644 --- a/primitives/api/proc-macro/Cargo.toml +++ b/primitives/api/proc-macro/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-api-proc-macro" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Macros for declaring and implementing runtime apis." diff --git a/primitives/api/proc-macro/src/decl_runtime_apis.rs b/primitives/api/proc-macro/src/decl_runtime_apis.rs index 440176bc468585e76cde32d3e07627e550d59a42..8294c8bfbd68428e15cefd410a15137c9a730d7e 100644 --- a/primitives/api/proc-macro/src/decl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/decl_runtime_apis.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use crate::utils::{ generate_crate_access, generate_hidden_includes, generate_runtime_mod_name_for_trait, @@ -190,7 +191,8 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result { input: &I, error_desc: &'static str, ) -> std::result::Result { - ::decode( + ::decode_with_depth_limit( + #crate_::MAX_EXTRINSIC_DEPTH, &mut &#crate_::Encode::encode(input)[..], ).map_err(|e| format!("{} {}", error_desc, e.what())) } @@ -250,7 +252,7 @@ fn generate_native_call_generators(decl: &ItemTrait) -> Result { } FnArg::Typed(arg) }, - r => r.clone(), + r => r, }); let (impl_generics, ty_generics, where_clause) = decl.generics.split_for_impl(); @@ -382,7 +384,7 @@ fn generate_call_api_at_calls(decl: &ItemTrait) -> Result { renames.push((version, prefix_function_with_trait(&trait_name, &old_name))); } - renames.sort_unstable_by(|l, r| r.cmp(l)); + renames.sort_by(|l, r| r.cmp(l)); let (versions, old_names) = renames.into_iter().fold( (Vec::new(), Vec::new()), |(mut versions, mut old_names), (version, old_name)| { diff --git a/primitives/api/proc-macro/src/impl_runtime_apis.rs b/primitives/api/proc-macro/src/impl_runtime_apis.rs index 72c833a18c8d3c2bc2e5a819f0ade423be04fdd2..85f5a1797b1e3202a784d14b5cbba1d1cb9a0713 100644 --- a/primitives/api/proc-macro/src/impl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/impl_runtime_apis.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use crate::utils::{ generate_crate_access, generate_hidden_includes, @@ -33,7 +34,7 @@ use syn::{ fold::{self, Fold}, parse_quote, }; -use std::{collections::HashSet, iter}; +use std::collections::HashSet; /// Unique identifier used to make the hidden includes unique for this macro. const HIDDEN_INCLUDES_ID: &str = "IMPL_RUNTIME_APIS"; @@ -70,10 +71,8 @@ fn generate_impl_call( let params = extract_parameter_names_types_and_borrows(signature, AllowSelfRefInParameters::No)?; let c = generate_crate_access(HIDDEN_INCLUDES_ID); - let c_iter = iter::repeat(&c); let fn_name = &signature.ident; - let fn_name_str = iter::repeat(fn_name.to_string()); - let input = iter::repeat(input); + let fn_name_str = fn_name.to_string(); let pnames = params.iter().map(|v| &v.0); let pnames2 = params.iter().map(|v| &v.0); let ptypes = params.iter().map(|v| &v.1); @@ -81,12 +80,14 @@ fn generate_impl_call( Ok( quote!( - #( - let #pnames : #ptypes = match #c_iter::Decode::decode(&mut #input) { - Ok(input) => input, + let (#( #pnames ),*) : ( #( #ptypes ),* ) = + match #c::DecodeLimit::decode_all_with_depth_limit( + #c::MAX_EXTRINSIC_DEPTH, + &#input, + ) { + Ok(res) => res, Err(e) => panic!("Bad input data provided to {}: {}", #fn_name_str, e.what()), }; - )* #[allow(deprecated)] <#runtime as #impl_trait>::#fn_name(#( #pborrow #pnames2 ),*) @@ -134,7 +135,7 @@ fn generate_impl_calls( /// Generate the dispatch function that is used in native to call into the runtime. fn generate_dispatch_function(impls: &[ItemImpl]) -> Result { - let data = Ident::new("data", Span::call_site()); + let data = Ident::new("__sp_api__input_data", Span::call_site()); let c = generate_crate_access(HIDDEN_INCLUDES_ID); let impl_calls = generate_impl_calls(impls, &data)? .into_iter() @@ -252,17 +253,18 @@ fn generate_runtime_api_base_structures() -> Result { { type StateBackend = C::StateBackend; - fn map_api_result std::result::Result, R, E>( + fn execute_in_transaction #crate_::TransactionOutcome, R>( &self, - map_call: F, - ) -> std::result::Result where Self: Sized { + call: F, + ) -> R where Self: Sized { + self.changes.borrow_mut().start_transaction(); *self.commit_on_success.borrow_mut() = false; - let res = map_call(self); + let res = call(self); *self.commit_on_success.borrow_mut() = true; - self.commit_on_ok(&res); + self.commit_or_rollback(matches!(res, #crate_::TransactionOutcome::Commit(_))); - res + res.into_inner() } fn has_api( @@ -365,6 +367,9 @@ fn generate_runtime_api_base_structures() -> Result { &self, call_api_at: F, ) -> std::result::Result<#crate_::NativeOrEncoded, E> { + if *self.commit_on_success.borrow() { + self.changes.borrow_mut().start_transaction(); + } let res = call_api_at( &self.call, self, @@ -375,16 +380,21 @@ fn generate_runtime_api_base_structures() -> Result { &self.recorder, ); - self.commit_on_ok(&res); + self.commit_or_rollback(res.is_ok()); res } - fn commit_on_ok(&self, res: &std::result::Result) { + fn commit_or_rollback(&self, commit: bool) { + let proof = "\ + We only close a transaction when we opened one ourself. + Other parts of the runtime that make use of transactions (state-machine) + also balance their transactions. The runtime cannot close client initiated + transactions. qed"; if *self.commit_on_success.borrow() { - if res.is_err() { - self.changes.borrow_mut().discard_prospective(); + if commit { + self.changes.borrow_mut().commit_transaction().expect(proof); } else { - self.changes.borrow_mut().commit_prospective(); + self.changes.borrow_mut().rollback_transaction().expect(proof); } } } @@ -407,7 +417,7 @@ fn extend_with_runtime_decl_path(mut trait_: Path) -> Path { }; let pos = trait_.segments.len() - 1; - trait_.segments.insert(pos, runtime.clone().into()); + trait_.segments.insert(pos, runtime.into()); trait_ } diff --git a/primitives/api/proc-macro/src/lib.rs b/primitives/api/proc-macro/src/lib.rs index 12f435bd166dff2a579346ff8a710faec6bf89ba..4dd48094683d9fd02dc46f9155260e8e79e43ff8 100644 --- a/primitives/api/proc-macro/src/lib.rs +++ b/primitives/api/proc-macro/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Macros for declaring and implementing runtime apis. diff --git a/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs b/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs index 0767c804a637e2983c52affc97c69f4aea47ce62..0e8f18e3e6f14a403d5a650d10d08d28ab6143a7 100644 --- a/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs +++ b/primitives/api/proc-macro/src/mock_impl_runtime_apis.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use crate::utils::{ generate_crate_access, generate_hidden_includes, @@ -72,11 +73,11 @@ fn implement_common_api_traits( impl #crate_::ApiExt<#block_type> for #self_ty { type StateBackend = #crate_::InMemoryBackend<#crate_::HashFor<#block_type>>; - fn map_api_result std::result::Result, R, E>( + fn execute_in_transaction #crate_::TransactionOutcome, R>( &self, - map_call: F, - ) -> std::result::Result where Self: Sized { - map_call(self) + call: F, + ) -> R where Self: Sized { + call(self).into_inner() } fn has_api( diff --git a/primitives/api/proc-macro/src/utils.rs b/primitives/api/proc-macro/src/utils.rs index 1a79cf6c1ef5b5f046ac98229b3f4203f46ce45b..534ddcfddd96e131a6d827c92386fd3aeb5945fe 100644 --- a/primitives/api/proc-macro/src/utils.rs +++ b/primitives/api/proc-macro/src/utils.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use proc_macro2::{TokenStream, Span}; diff --git a/primitives/api/src/lib.rs b/primitives/api/src/lib.rs index f8a22c45665ffd899f19b4e7200bd31a2a7c4bd4..bad6c03058322f7f45475c32ccc2260fcef573f6 100644 --- a/primitives/api/src/lib.rs +++ b/primitives/api/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Substrate runtime api //! @@ -57,7 +58,7 @@ pub use sp_runtime::{ Block as BlockT, GetNodeBlockType, GetRuntimeBlockType, HashFor, NumberFor, Header as HeaderT, Hash as HashT, }, - generic::BlockId, transaction_validity::TransactionValidity, RuntimeString, + generic::BlockId, transaction_validity::TransactionValidity, RuntimeString, TransactionOutcome, }; #[doc(hidden)] pub use sp_core::{offchain, ExecutionContext}; @@ -68,11 +69,14 @@ pub use sp_std::{slice, mem}; #[cfg(feature = "std")] use sp_std::result; #[doc(hidden)] -pub use codec::{Encode, Decode}; +pub use codec::{Encode, Decode, DecodeLimit}; use sp_core::OpaqueMetadata; #[cfg(feature = "std")] use std::{panic::UnwindSafe, cell::RefCell}; +/// Maximum nesting level for extrinsics. +pub const MAX_EXTRINSIC_DEPTH: u32 = 256; + /// Declares given traits as runtime apis. /// /// The macro will create two declarations, one for using on the client side and one for using @@ -352,15 +356,15 @@ pub trait ApiExt: ApiErrorExt { /// The state backend that is used to store the block states. type StateBackend: StateBackend>; - /// The given closure will be called with api instance. Inside the closure any api call is - /// allowed. After doing the api call, the closure is allowed to map the `Result` to a - /// different `Result` type. This can be important, as the internal data structure that keeps - /// track of modifications to the storage, discards changes when the `Result` is an `Err`. - /// On `Ok`, the structure commits the changes to an internal buffer. - fn map_api_result result::Result, R, E>( + /// Execute the given closure inside a new transaction. + /// + /// Depending on the outcome of the closure, the transaction is committed or rolled-back. + /// + /// The internal result of the closure is returned afterwards. + fn execute_in_transaction TransactionOutcome, R>( &self, - map_call: F, - ) -> result::Result where Self: Sized; + call: F, + ) -> R where Self: Sized; /// Checks if the given api is implemented and versions match. fn has_api( diff --git a/primitives/api/test/Cargo.toml b/primitives/api/test/Cargo.toml index a945399f1b66ea830721a630c546888ece019830..0c321429e13d490d9718c4d79666821e11c59e71 100644 --- a/primitives/api/test/Cargo.toml +++ b/primitives/api/test/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-api-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,22 +12,22 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-dev", path = "../" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-version = { version = "2.0.0-dev", path = "../../version" } -sp-runtime = { version = "2.0.0-dev", path = "../../runtime" } -sp-blockchain = { version = "2.0.0-dev", path = "../../blockchain" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -sc-block-builder = { version = "0.8.0-dev", path = "../../../client/block-builder" } -codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } +sp-api = { version = "2.0.0-rc6", path = "../" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../test-utils/runtime/client" } +sp-version = { version = "2.0.0-rc6", path = "../../version" } +sp-runtime = { version = "2.0.0-rc6", path = "../../runtime" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../blockchain" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sc-block-builder = { version = "0.8.0-rc6", path = "../../../client/block-builder" } +codec = { package = "parity-scale-codec", version = "1.3.1" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../../primitives/state-machine" } trybuild = "1.0.17" rustversion = "1.0.0" [dev-dependencies] criterion = "0.3.0" -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-core = { version = "2.0.0-dev", path = "../../core" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../test-utils/runtime/client" } +sp-core = { version = "2.0.0-rc6", path = "../../core" } [[bench]] name = "bench" diff --git a/primitives/api/test/benches/bench.rs b/primitives/api/test/benches/bench.rs index 9a90ca6e38b8501c4e7286d7919f56613d539df1..280b7079028735c897d0e5db517f41da2de0c0ef 100644 --- a/primitives/api/test/benches/bench.rs +++ b/primitives/api/test/benches/bench.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use criterion::{Criterion, criterion_group, criterion_main}; use substrate_test_runtime_client::{ diff --git a/primitives/api/test/tests/decl_and_impl.rs b/primitives/api/test/tests/decl_and_impl.rs index 4a8c8cd6628c895dec8bbf5a920b15684471380b..f16f0bbe71c562640fb5b89203433a795f811b33 100644 --- a/primitives/api/test/tests/decl_and_impl.rs +++ b/primitives/api/test/tests/decl_and_impl.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use sp_api::{ RuntimeApiInfo, decl_runtime_apis, impl_runtime_apis, mock_impl_runtime_apis, diff --git a/primitives/api/test/tests/runtime_calls.rs b/primitives/api/test/tests/runtime_calls.rs index a907ac80957200d8135ee50e3782420c134a3411..d72872959cefa7f0995b02737f84e614ee1c986f 100644 --- a/primitives/api/test/tests/runtime_calls.rs +++ b/primitives/api/test/tests/runtime_calls.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use sp_api::ProvideRuntimeApi; use substrate_test_runtime_client::{ @@ -196,13 +197,24 @@ fn record_proof_works() { None, 8, ); - execution_proof_check_on_trie_backend::<_, u64, _>( + execution_proof_check_on_trie_backend::<_, u64, _, _>( &backend, &mut overlay, &executor, - sp_core::tasks::executor(), + sp_core::testing::TaskExecutor::new(), "Core_execute_block", &block.encode(), &runtime_code, ).expect("Executes block while using the proof backend"); } + +#[test] +fn call_runtime_api_with_multiple_arguments() { + let client = TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::Both).build(); + + let data = vec![1, 2, 4, 5, 6, 7, 8, 8, 10, 12]; + let block_id = BlockId::Number(client.chain_info().best_number); + client.runtime_api() + .test_multiple_arguments(&block_id, data.clone(), data.clone(), data.len() as u32) + .unwrap(); +} diff --git a/primitives/api/test/tests/trybuild.rs b/primitives/api/test/tests/trybuild.rs index 910771f9389691d61b1c84069fdf6090e242f80b..2f7fd6d06bcd34c3724d6fa39422d4f7890392cc 100644 --- a/primitives/api/test/tests/trybuild.rs +++ b/primitives/api/test/tests/trybuild.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use std::env; diff --git a/primitives/api/test/tests/ui/declaring_old_block.rs b/primitives/api/test/tests/ui/declaring_old_block.rs index ba98bf9bf688317b4a8d6dd940b61112fba82485..fb741590282249c692af3b9233f59a95fa3b0b5b 100644 --- a/primitives/api/test/tests/ui/declaring_old_block.rs +++ b/primitives/api/test/tests/ui/declaring_old_block.rs @@ -1,5 +1,3 @@ -use sp_runtime::traits::Block as BlockT; - sp_api::decl_runtime_apis! { pub trait Api { fn test(); diff --git a/primitives/api/test/tests/ui/declaring_old_block.stderr b/primitives/api/test/tests/ui/declaring_old_block.stderr index 448dc38594321e5b7f11c0ccfeb4f4d6e6414862..50dd37582c603d5d355472e2003b1813d18ecb67 100644 --- a/primitives/api/test/tests/ui/declaring_old_block.stderr +++ b/primitives/api/test/tests/ui/declaring_old_block.stderr @@ -1,19 +1,11 @@ error: `Block: BlockT` generic parameter will be added automatically by the `decl_runtime_apis!` macro! If you try to use a different trait than the substrate `Block` trait, please rename it locally. - --> $DIR/declaring_old_block.rs:4:23 + --> $DIR/declaring_old_block.rs:2:23 | -4 | pub trait Api { +2 | pub trait Api { | ^^^^^^ error: `Block: BlockT` generic parameter will be added automatically by the `decl_runtime_apis!` macro! - --> $DIR/declaring_old_block.rs:4:16 + --> $DIR/declaring_old_block.rs:2:16 | -4 | pub trait Api { +2 | pub trait Api { | ^^^^^ - -warning: unused import: `sp_runtime::traits::Block as BlockT` - --> $DIR/declaring_old_block.rs:1:5 - | -1 | use sp_runtime::traits::Block as BlockT; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_imports)]` on by default diff --git a/primitives/api/test/tests/ui/declaring_own_block_with_different_name.rs b/primitives/api/test/tests/ui/declaring_own_block_with_different_name.rs index 67bb9cab10502cc7ef33fe9106d95221547a9a99..e3c7ae8a39ab748557c5d160f35e24dfcd0a353d 100644 --- a/primitives/api/test/tests/ui/declaring_own_block_with_different_name.rs +++ b/primitives/api/test/tests/ui/declaring_own_block_with_different_name.rs @@ -1,5 +1,3 @@ -use sp_runtime::traits::Block as BlockT; - sp_api::decl_runtime_apis! { pub trait Api { fn test(); diff --git a/primitives/api/test/tests/ui/declaring_own_block_with_different_name.stderr b/primitives/api/test/tests/ui/declaring_own_block_with_different_name.stderr index fe445b822dd88a25e340beb75fc834a5ff85febf..778de3c9d15f7ff9caf94b858182af78ff260bd1 100644 --- a/primitives/api/test/tests/ui/declaring_own_block_with_different_name.stderr +++ b/primitives/api/test/tests/ui/declaring_own_block_with_different_name.stderr @@ -1,13 +1,5 @@ error: `Block: BlockT` generic parameter will be added automatically by the `decl_runtime_apis!` macro! If you try to use a different trait than the substrate `Block` trait, please rename it locally. - --> $DIR/declaring_own_block_with_different_name.rs:4:19 + --> $DIR/declaring_own_block_with_different_name.rs:2:19 | -4 | pub trait Api { +2 | pub trait Api { | ^^^^^^ - -warning: unused import: `sp_runtime::traits::Block as BlockT` - --> $DIR/declaring_own_block_with_different_name.rs:1:5 - | -1 | use sp_runtime::traits::Block as BlockT; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_imports)]` on by default diff --git a/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr b/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr index 46f138fccd5ecdd1c57c7e24d6ccacd1bf7472dc..851d2b8a4b652b85833d2f83b645511dc693decb 100644 --- a/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr +++ b/primitives/api/test/tests/ui/impl_incorrect_method_signature.stderr @@ -19,7 +19,7 @@ error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for tr 14 | | } 15 | | } | |_- type in trait -16 | +16 | 17 | sp_api::impl_runtime_apis! { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found struct `std::string::String` | diff --git a/primitives/api/test/tests/ui/impl_two_traits_with_same_name.rs b/primitives/api/test/tests/ui/impl_two_traits_with_same_name.rs index 2122a6991ae5a9c6f38a0a9de9abdcc05b0641ca..76555a825dc8415c591455398ad931d43d6d7d5f 100644 --- a/primitives/api/test/tests/ui/impl_two_traits_with_same_name.rs +++ b/primitives/api/test/tests/ui/impl_two_traits_with_same_name.rs @@ -15,8 +15,6 @@ sp_api::decl_runtime_apis! { } mod second { - use super::*; - sp_api::decl_runtime_apis! { pub trait Api { fn test2(data: u64); diff --git a/primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr b/primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr index 24ee66f84b314d345dd7b5d86638293b140eedb1..17ee56d409a66e34fcaec32af8644385fe5ef520 100644 --- a/primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr +++ b/primitives/api/test/tests/ui/impl_two_traits_with_same_name.stderr @@ -1,13 +1,5 @@ error: Two traits with the same name detected! The trait name is used to generate its ID. Please rename one trait at the declaration! - --> $DIR/impl_two_traits_with_same_name.rs:32:15 + --> $DIR/impl_two_traits_with_same_name.rs:30:15 | -32 | impl second::Api for Runtime { +30 | impl second::Api for Runtime { | ^^^ - -warning: unused import: `super::*` - --> $DIR/impl_two_traits_with_same_name.rs:18:6 - | -18 | use super::*; - | ^^^^^^^^ - | - = note: `#[warn(unused_imports)]` on by default diff --git a/primitives/api/test/tests/ui/mock_only_one_block_type.rs b/primitives/api/test/tests/ui/mock_only_one_block_type.rs index 969b21d7378d75b6b2bb28c1ca118aa041015784..f49cafd23a00122bd53976c0656e0779f3d3fb5d 100644 --- a/primitives/api/test/tests/ui/mock_only_one_block_type.rs +++ b/primitives/api/test/tests/ui/mock_only_one_block_type.rs @@ -1,5 +1,3 @@ -use substrate_test_runtime_client::runtime::Block; - struct Block2; sp_api::decl_runtime_apis! { diff --git a/primitives/api/test/tests/ui/mock_only_one_block_type.stderr b/primitives/api/test/tests/ui/mock_only_one_block_type.stderr index 1abc8db726a160e151cb47abf6b745d5630b1851..1831d0485b473a3d33ca1bafce6c2fa67f6b78a2 100644 --- a/primitives/api/test/tests/ui/mock_only_one_block_type.stderr +++ b/primitives/api/test/tests/ui/mock_only_one_block_type.stderr @@ -1,19 +1,11 @@ error: Block type should be the same between all runtime apis. - --> $DIR/mock_only_one_block_type.rs:22:12 + --> $DIR/mock_only_one_block_type.rs:20:12 | -22 | impl Api2 for MockApi { +20 | impl Api2 for MockApi { | ^^^^^^ error: First block type found here - --> $DIR/mock_only_one_block_type.rs:18:11 + --> $DIR/mock_only_one_block_type.rs:16:11 | -18 | impl Api for MockApi { +16 | impl Api for MockApi { | ^^^^^ - -warning: unused import: `substrate_test_runtime_client::runtime::Block` - --> $DIR/mock_only_one_block_type.rs:1:5 - | -1 | use substrate_test_runtime_client::runtime::Block; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_imports)]` on by default diff --git a/primitives/api/test/tests/ui/mock_only_one_error_type.stderr b/primitives/api/test/tests/ui/mock_only_one_error_type.stderr index b190c2134fafa6d4312b856f391c905a1d5c72b3..65d05e83a7f69149947a4628b98224976a9e2659 100644 --- a/primitives/api/test/tests/ui/mock_only_one_error_type.stderr +++ b/primitives/api/test/tests/ui/mock_only_one_error_type.stderr @@ -5,21 +5,26 @@ error: Error type can not change between runtime apis | ^^^^ error[E0277]: the trait bound `u32: std::convert::From` is not satisfied - --> $DIR/mock_only_one_error_type.rs:15:1 - | -15 | / sp_api::mock_impl_runtime_apis! { -16 | | impl Api for MockApi { -17 | | type Error = u32; -18 | | -... | -26 | | } -27 | | } - | |_^ the trait `std::convert::From` is not implemented for `u32` - | - = help: the following implementations were found: - > - > - > - > - and 18 others - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + --> $DIR/mock_only_one_error_type.rs:15:1 + | +15 | / sp_api::mock_impl_runtime_apis! { +16 | | impl Api for MockApi { +17 | | type Error = u32; +18 | | +... | +26 | | } +27 | | } + | |_^ the trait `std::convert::From` is not implemented for `u32` + | + ::: $WORKSPACE/primitives/api/src/lib.rs:350:35 + | +350 | type Error: std::fmt::Debug + From; + | ------------ required by this bound in `sp_api_hidden_includes_DECL_RUNTIME_APIS::sp_api::ApiErrorExt` + | + = help: the following implementations were found: + > + > + > + > + and 18 others + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/primitives/api/test/tests/ui/mock_only_one_self_type.rs b/primitives/api/test/tests/ui/mock_only_one_self_type.rs index 4b29ec2a6ab07e7a08689549423e03687501543d..617031b4d5f1a1f37c974ed8d826f43e49003233 100644 --- a/primitives/api/test/tests/ui/mock_only_one_self_type.rs +++ b/primitives/api/test/tests/ui/mock_only_one_self_type.rs @@ -1,5 +1,3 @@ -use substrate_test_runtime_client::runtime::Block; - sp_api::decl_runtime_apis! { pub trait Api { fn test(data: u64); diff --git a/primitives/api/test/tests/ui/mock_only_one_self_type.stderr b/primitives/api/test/tests/ui/mock_only_one_self_type.stderr index 996d1d44c044c151bc5e57e93e83d3749e86a80c..5f1e29b281c8504d39a355028882099b40298810 100644 --- a/primitives/api/test/tests/ui/mock_only_one_self_type.stderr +++ b/primitives/api/test/tests/ui/mock_only_one_self_type.stderr @@ -1,19 +1,11 @@ error: Self type should not change between runtime apis - --> $DIR/mock_only_one_self_type.rs:21:23 + --> $DIR/mock_only_one_self_type.rs:19:23 | -21 | impl Api2 for MockApi2 { +19 | impl Api2 for MockApi2 { | ^^^^^^^^ error: First self type found here - --> $DIR/mock_only_one_self_type.rs:17:22 + --> $DIR/mock_only_one_self_type.rs:15:22 | -17 | impl Api for MockApi { +15 | impl Api for MockApi { | ^^^^^^^ - -warning: unused import: `substrate_test_runtime_client::runtime::Block` - --> $DIR/mock_only_one_self_type.rs:1:5 - | -1 | use substrate_test_runtime_client::runtime::Block; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_imports)]` on by default diff --git a/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr b/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr index cc2a5f05cd5ffea8251c8b280eae656ddf550d4f..c3e4850036090ddca3a06bd8c58f82ff78fc23e3 100644 --- a/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr +++ b/primitives/api/test/tests/ui/type_reference_in_impl_runtime_apis_call.stderr @@ -19,7 +19,7 @@ error[E0053]: method `Api_test_runtime_api_impl` has an incompatible type for tr 14 | | } 15 | | } | |_- type in trait -16 | +16 | 17 | sp_api::impl_runtime_apis! { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `&u64` | diff --git a/primitives/application-crypto/Cargo.toml b/primitives/application-crypto/Cargo.toml index be9e5e5a1116ddcf883c5cbd40ee5f026855ab38..cbfb5d3623446adde71adefd6a83dee9b71ad56f 100644 --- a/primitives/application-crypto/Cargo.toml +++ b/primitives/application-crypto/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-application-crypto" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" description = "Provides facilities for generating application specific crypto wrapper types." -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sp-application-crypto" @@ -14,11 +14,11 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../core" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } [features] default = [ "std" ] diff --git a/primitives/application-crypto/README.md b/primitives/application-crypto/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c86e33552f60605d5ca8e9db7e48621f24060f2f --- /dev/null +++ b/primitives/application-crypto/README.md @@ -0,0 +1,3 @@ +Traits and macros for constructing application specific strongly typed crypto wrappers. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/application-crypto/src/ecdsa.rs b/primitives/application-crypto/src/ecdsa.rs new file mode 100644 index 0000000000000000000000000000000000000000..287ac8f3afcff000b5de63223e8c1157b8794d4d --- /dev/null +++ b/primitives/application-crypto/src/ecdsa.rs @@ -0,0 +1,61 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Ecdsa crypto types. + +use crate::{RuntimePublic, KeyTypeId}; + +use sp_std::vec::Vec; + +pub use sp_core::ecdsa::*; + +mod app { + use sp_core::testing::ECDSA; + + crate::app_crypto!(super, ECDSA); + + impl crate::traits::BoundToRuntimeAppPublic for Public { + type Public = Self; + } +} + +pub use app::{Public as AppPublic, Signature as AppSignature}; +#[cfg(feature = "full_crypto")] +pub use app::Pair as AppPair; + +impl RuntimePublic for Public { + type Signature = Signature; + + fn all(key_type: KeyTypeId) -> crate::Vec { + sp_io::crypto::ecdsa_public_keys(key_type) + } + + fn generate_pair(key_type: KeyTypeId, seed: Option>) -> Self { + sp_io::crypto::ecdsa_generate(key_type, seed) + } + + fn sign>(&self, key_type: KeyTypeId, msg: &M) -> Option { + sp_io::crypto::ecdsa_sign(key_type, self, msg.as_ref()) + } + + fn verify>(&self, msg: &M, signature: &Self::Signature) -> bool { + sp_io::crypto::ecdsa_verify(&signature, msg.as_ref(), self) + } + + fn to_raw_vec(&self) -> Vec { + sp_core::crypto::Public::to_raw_vec(self) + } +} diff --git a/primitives/application-crypto/src/ed25519.rs b/primitives/application-crypto/src/ed25519.rs index 5be79ff4f7985a54e9eb0c34fb3552f3cf062bb1..e761745cf5425a9a51d1499b5c10e5b849aabae1 100644 --- a/primitives/application-crypto/src/ed25519.rs +++ b/primitives/application-crypto/src/ed25519.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Ed25519 crypto types. @@ -23,27 +24,13 @@ use sp_std::vec::Vec; pub use sp_core::ed25519::*; mod app { - use sp_core::crypto::{CryptoTypePublicPair, Public as TraitPublic}; use sp_core::testing::ED25519; - use sp_core::ed25519::CRYPTO_ID; crate::app_crypto!(super, ED25519); impl crate::traits::BoundToRuntimeAppPublic for Public { type Public = Self; } - - impl From for CryptoTypePublicPair { - fn from(key: Public) -> Self { - (&key).into() - } - } - - impl From<&Public> for CryptoTypePublicPair { - fn from(key: &Public) -> Self { - CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) - } - } } pub use app::{Public as AppPublic, Signature as AppSignature}; diff --git a/primitives/application-crypto/src/lib.rs b/primitives/application-crypto/src/lib.rs index b69b8b6877f792c09ae13014e8ca72b6bb064f6b..6b5cf8857fb5b754dd27613089e275c4f03ed50f 100644 --- a/primitives/application-crypto/src/lib.rs +++ b/primitives/application-crypto/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Traits and macros for constructing application specific strongly typed crypto wrappers. @@ -33,10 +34,15 @@ pub use codec; #[cfg(feature = "std")] pub use serde; #[doc(hidden)] -pub use sp_std::{ops::Deref, vec::Vec}; +pub use sp_std::{ + convert::TryFrom, + ops::Deref, + vec::Vec, +}; pub mod ed25519; pub mod sr25519; +pub mod ecdsa; mod traits; pub use traits::*; @@ -54,11 +60,11 @@ pub use traits::*; #[macro_export] macro_rules! app_crypto { ($module:ident, $key_type:expr) => { - $crate::app_crypto_public_full_crypto!($module::Public, $key_type); + $crate::app_crypto_public_full_crypto!($module::Public, $key_type, $module::CRYPTO_ID); $crate::app_crypto_public_common!($module::Public, $module::Signature, $key_type, $module::CRYPTO_ID); - $crate::app_crypto_signature_full_crypto!($module::Signature, $key_type); + $crate::app_crypto_signature_full_crypto!($module::Signature, $key_type, $module::CRYPTO_ID); $crate::app_crypto_signature_common!($module::Signature, $key_type); - $crate::app_crypto_pair!($module::Pair, $key_type); + $crate::app_crypto_pair!($module::Pair, $key_type, $module::CRYPTO_ID); }; } @@ -75,9 +81,9 @@ macro_rules! app_crypto { #[macro_export] macro_rules! app_crypto { ($module:ident, $key_type:expr) => { - $crate::app_crypto_public_not_full_crypto!($module::Public, $key_type); + $crate::app_crypto_public_not_full_crypto!($module::Public, $key_type, $module::CRYPTO_ID); $crate::app_crypto_public_common!($module::Public, $module::Signature, $key_type, $module::CRYPTO_ID); - $crate::app_crypto_signature_not_full_crypto!($module::Signature, $key_type); + $crate::app_crypto_signature_not_full_crypto!($module::Signature, $key_type, $module::CRYPTO_ID); $crate::app_crypto_signature_common!($module::Signature, $key_type); }; } @@ -86,7 +92,7 @@ macro_rules! app_crypto { /// Application-specific type whose identifier is `$key_type`. #[macro_export] macro_rules! app_crypto_pair { - ($pair:ty, $key_type:expr) => { + ($pair:ty, $key_type:expr, $crypto_type:expr) => { $crate::wrap!{ /// A generic `AppPublic` wrapper type over $pair crypto; this has no specific App. #[derive(Clone)] @@ -141,6 +147,7 @@ macro_rules! app_crypto_pair { type Pair = Pair; type Signature = Signature; const ID: $crate::KeyTypeId = $key_type; + const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type; } impl $crate::AppPair for Pair { @@ -183,7 +190,7 @@ macro_rules! app_crypto_pair_functions_if_std { #[doc(hidden)] #[macro_export] macro_rules! app_crypto_public_full_crypto { - ($public:ty, $key_type:expr) => { + ($public:ty, $key_type:expr, $crypto_type:expr) => { $crate::wrap!{ /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. #[derive( @@ -206,6 +213,7 @@ macro_rules! app_crypto_public_full_crypto { type Pair = Pair; type Signature = Signature; const ID: $crate::KeyTypeId = $key_type; + const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type; } } } @@ -217,7 +225,7 @@ macro_rules! app_crypto_public_full_crypto { #[doc(hidden)] #[macro_export] macro_rules! app_crypto_public_not_full_crypto { - ($public:ty, $key_type:expr) => { + ($public:ty, $key_type:expr, $crypto_type:expr) => { $crate::wrap!{ /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. #[derive( @@ -236,6 +244,7 @@ macro_rules! app_crypto_public_not_full_crypto { type Public = Public; type Signature = Signature; const ID: $crate::KeyTypeId = $key_type; + const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type; } } } @@ -259,6 +268,10 @@ macro_rules! app_crypto_public_common { impl $crate::Public for Public { fn from_slice(x: &[u8]) -> Self { Self(<$public>::from_slice(x)) } + + fn to_public_crypto_pair(&self) -> $crate::CryptoTypePublicPair { + $crate::CryptoTypePublicPair($crypto_type, self.to_raw_vec()) + } } impl $crate::AppPublic for Public { @@ -295,6 +308,21 @@ macro_rules! app_crypto_public_common { <$public as $crate::RuntimePublic>::to_raw_vec(&self.0) } } + + impl From for $crate::CryptoTypePublicPair { + fn from(key: Public) -> Self { + (&key).into() + } + } + + impl From<&Public> for $crate::CryptoTypePublicPair { + fn from(key: &Public) -> Self { + $crate::CryptoTypePublicPair( + $crypto_type, + $crate::Public::to_raw_vec(key), + ) + } + } } } @@ -357,7 +385,7 @@ macro_rules! app_crypto_public_common_if_std { #[doc(hidden)] #[macro_export] macro_rules! app_crypto_signature_full_crypto { - ($sig:ty, $key_type:expr) => { + ($sig:ty, $key_type:expr, $crypto_type:expr) => { $crate::wrap! { /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. #[derive(Clone, Default, Eq, PartialEq, @@ -379,6 +407,7 @@ macro_rules! app_crypto_signature_full_crypto { type Pair = Pair; type Signature = Signature; const ID: $crate::KeyTypeId = $key_type; + const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type; } } } @@ -390,7 +419,7 @@ macro_rules! app_crypto_signature_full_crypto { #[doc(hidden)] #[macro_export] macro_rules! app_crypto_signature_not_full_crypto { - ($sig:ty, $key_type:expr) => { + ($sig:ty, $key_type:expr, $crypto_type:expr) => { $crate::wrap! { /// A generic `AppPublic` wrapper type over $public crypto; this has no specific App. #[derive(Clone, Default, Eq, PartialEq, @@ -408,6 +437,7 @@ macro_rules! app_crypto_signature_not_full_crypto { type Public = Public; type Signature = Signature; const ID: $crate::KeyTypeId = $key_type; + const CRYPTO_ID: $crate::CryptoTypeId = $crypto_type; } } } @@ -432,6 +462,14 @@ macro_rules! app_crypto_signature_common { impl $crate::AppSignature for Signature { type Generic = $sig; } + + impl $crate::TryFrom<$crate::Vec> for Signature { + type Error = (); + + fn try_from(data: $crate::Vec) -> Result { + Ok(<$sig>::try_from(data.as_slice())?.into()) + } + } } } diff --git a/primitives/application-crypto/src/sr25519.rs b/primitives/application-crypto/src/sr25519.rs index a0f2cef1c4e45b6150be335ac271e3dd592febbe..4700e0f756717345ca68e1c320bdf185f4a6fa47 100644 --- a/primitives/application-crypto/src/sr25519.rs +++ b/primitives/application-crypto/src/sr25519.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Sr25519 crypto types. @@ -23,27 +24,13 @@ use sp_std::vec::Vec; pub use sp_core::sr25519::*; mod app { - use sp_core::crypto::{CryptoTypePublicPair, Public as TraitPublic}; use sp_core::testing::SR25519; - use sp_core::sr25519::CRYPTO_ID; crate::app_crypto!(super, SR25519); impl crate::traits::BoundToRuntimeAppPublic for Public { type Public = Self; } - - impl From for CryptoTypePublicPair { - fn from(key: Public) -> Self { - (&key).into() - } - } - - impl From<&Public> for CryptoTypePublicPair { - fn from(key: &Public) -> Self { - CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) - } - } } pub use app::{Public as AppPublic, Signature as AppSignature}; diff --git a/primitives/application-crypto/src/traits.rs b/primitives/application-crypto/src/traits.rs index 2983b143df1ec4206fba1e7a82870c059961c3e7..f06e194aefddf07a5ee377508b21f55ccd785156 100644 --- a/primitives/application-crypto/src/traits.rs +++ b/primitives/application-crypto/src/traits.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. #[cfg(feature = "full_crypto")] use sp_core::crypto::Pair; @@ -38,6 +39,8 @@ pub trait AppKey: 'static + Send + Sync + Sized + CryptoType + Clone { /// An identifier for this application-specific key type. const ID: KeyTypeId; + /// The identifier of the crypto type of this application-specific key type. + const CRYPTO_ID: CryptoTypeId; } /// Type which implements Hash in std, not when no-std (std variant). diff --git a/primitives/application-crypto/test/Cargo.toml b/primitives/application-crypto/test/Cargo.toml index 47b477ddd37df6e11207dd86e68d670d5a8e9225..1fb03856dd12a15016fc58b156166168b7b9727e 100644 --- a/primitives/application-crypto/test/Cargo.toml +++ b/primitives/application-crypto/test/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-application-crypto-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" description = "Integration tests for application-crypto" -license = "GPL-3.0" +license = "Apache-2.0" publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -13,8 +13,8 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../core" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sp-runtime = { version = "2.0.0-dev", path = "../../runtime" } -sp-api = { version = "2.0.0-dev", path = "../../api" } -sp-application-crypto = { version = "2.0.0-dev", path = "../" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../core" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../test-utils/runtime/client" } +sp-runtime = { version = "2.0.0-rc6", path = "../../runtime" } +sp-api = { version = "2.0.0-rc6", path = "../../api" } +sp-application-crypto = { version = "2.0.0-rc6", path = "../" } diff --git a/primitives/application-crypto/test/src/ecdsa.rs b/primitives/application-crypto/test/src/ecdsa.rs new file mode 100644 index 0000000000000000000000000000000000000000..9b5619b7c123e28ebc41559c69e52588f1e5ce76 --- /dev/null +++ b/primitives/application-crypto/test/src/ecdsa.rs @@ -0,0 +1,42 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Integration tests for ecdsa + +use sp_runtime::generic::BlockId; +use sp_core::{ + crypto::Pair, + testing::{KeyStore, ECDSA}, +}; +use substrate_test_runtime_client::{ + TestClientBuilder, DefaultTestClientBuilderExt, TestClientBuilderExt, + runtime::TestAPI, +}; +use sp_api::ProvideRuntimeApi; +use sp_application_crypto::ecdsa::{AppPair, AppPublic}; + +#[test] +fn ecdsa_works_in_runtime() { + let keystore = KeyStore::new(); + let test_client = TestClientBuilder::new().set_keystore(keystore.clone()).build(); + let (signature, public) = test_client.runtime_api() + .test_ecdsa_crypto(&BlockId::Number(0)) + .expect("Tests `ecdsa` crypto."); + + let supported_keys = keystore.read().keys(ECDSA).unwrap(); + assert!(supported_keys.contains(&public.clone().into())); + assert!(AppPair::verify(&signature, "ecdsa", &AppPublic::from(public))); +} diff --git a/primitives/application-crypto/test/src/ed25519.rs b/primitives/application-crypto/test/src/ed25519.rs index 1d72962829a53309ed4146a5f8657820ba15b697..ecdaabc30f10c06be086d3896080ee66a18cfc57 100644 --- a/primitives/application-crypto/test/src/ed25519.rs +++ b/primitives/application-crypto/test/src/ed25519.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Integration tests for ed25519 diff --git a/primitives/application-crypto/test/src/lib.rs b/primitives/application-crypto/test/src/lib.rs index cb045e81a7871c5b72003266656f17a346cc17bd..b78539239691adb9baa606c780d903eecec47265 100644 --- a/primitives/application-crypto/test/src/lib.rs +++ b/primitives/application-crypto/test/src/lib.rs @@ -1,22 +1,25 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Integration tests for application crypto #[cfg(test)] mod ed25519; #[cfg(test)] -mod sr25519; \ No newline at end of file +mod sr25519; +#[cfg(test)] +mod ecdsa; diff --git a/primitives/application-crypto/test/src/sr25519.rs b/primitives/application-crypto/test/src/sr25519.rs index f2c7c48b2bc91c0329ecaad7541be5f13f3f754c..55aaf1eac43b25aa8215b9bf7fc6dad4c45ba8d7 100644 --- a/primitives/application-crypto/test/src/sr25519.rs +++ b/primitives/application-crypto/test/src/sr25519.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Integration tests for sr25519 diff --git a/primitives/arithmetic/Cargo.toml b/primitives/arithmetic/Cargo.toml index 70efb4ac4a852df086d14a00f506c0ab826411d2..b4dd90736a21510b55086d80205917457cf8cd04 100644 --- a/primitives/arithmetic/Cargo.toml +++ b/primitives/arithmetic/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-arithmetic" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Minimal fixed point arithmetic primitives and types for runtime." @@ -14,18 +14,18 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } integer-sqrt = "0.1.2" num-traits = { version = "0.2.8", default-features = false } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-debug-derive = { version = "2.0.0-dev", default-features = false, path = "../../primitives/debug-derive" } -primitive-types = { version = "0.7.0", default-features = false } +sp-debug-derive = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/debug-derive" } [dev-dependencies] rand = "0.7.2" criterion = "0.3" serde_json = "1.0" +primitive-types = "0.7.0" [features] default = ["std"] @@ -35,7 +35,6 @@ std = [ "sp-std/std", "serde", "sp-debug-derive/std", - "primitive-types/std", ] [[bench]] diff --git a/primitives/arithmetic/README.md b/primitives/arithmetic/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e6e52c2a82696ba42e756458fff5839d2d88c09f --- /dev/null +++ b/primitives/arithmetic/README.md @@ -0,0 +1,3 @@ +Minimal fixed point arithmetic primitives and types for runtime. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/arithmetic/benches/bench.rs b/primitives/arithmetic/benches/bench.rs index 1dbcf260affc33cd6962ebd64dd58d8636e581ad..7a576c8af144bdd3e18b0c71236cbbeb13e9960e 100644 --- a/primitives/arithmetic/benches/bench.rs +++ b/primitives/arithmetic/benches/bench.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use criterion::{Criterion, Throughput, BenchmarkId, criterion_group, criterion_main}; use sp_arithmetic::biguint::{BigUint, Single}; diff --git a/primitives/arithmetic/fuzzer/Cargo.lock b/primitives/arithmetic/fuzzer/Cargo.lock deleted file mode 100644 index 3a4187437ae7312ec7016cb9e41638a018cfcbbf..0000000000000000000000000000000000000000 --- a/primitives/arithmetic/fuzzer/Cargo.lock +++ /dev/null @@ -1,401 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "arbitrary" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cf76cb6e2222ed0ea86b2b0ee2f71c96ec6edd5af42e84d59160e91b836ec4" - -[[package]] -name = "arrayvec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" - -[[package]] -name = "autocfg" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" - -[[package]] -name = "bitvec" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993f74b4c99c1908d156b8d2e0fb6277736b0ecbd833982fd1241d39b2766a6" - -[[package]] -name = "byte-slice-cast" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" - -[[package]] -name = "byteorder" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" - -[[package]] -name = "c2-chacha" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" -dependencies = [ - "ppv-lite86", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "fixed-hash" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "getrandom" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "honggfuzz" -version = "0.5.45" -dependencies = [ - "arbitrary", - "lazy_static", - "memmap", -] - -[[package]] -name = "impl-codec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be51a921b067b0eaca2fad532d9400041561aa922221cc65f95a85641c6bf53" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "integer-sqrt" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f65877bf7d44897a473350b1046277941cee20b263397e90869c50b6e766088b" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" - -[[package]] -name = "memmap" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" -dependencies = [ - "autocfg", -] - -[[package]] -name = "parity-scale-codec" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f509c5e67ca0605ee17dcd3f91ef41cadd685c75a298fb6261b781a5acb3f910" -dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0ec292e92e8ec7c58e576adacc1e3f399c597c8f263c42f18420abe58e7245" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" - -[[package]] -name = "primitive-types" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" -dependencies = [ - "fixed-hash", - "impl-codec", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e" -dependencies = [ - "toml", -] - -[[package]] -name = "proc-macro2" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" -dependencies = [ - "c2-chacha", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core", -] - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "serde" -version = "1.0.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sp-arithmetic" -version = "2.0.0-alpha.3" -dependencies = [ - "integer-sqrt", - "num-traits", - "parity-scale-codec", - "serde", - "sp-debug-derive", - "sp-std", -] - -[[package]] -name = "sp-arithmetic-fuzzer" -version = "2.0.0" -dependencies = [ - "honggfuzz", - "num-bigint", - "num-traits", - "primitive-types", - "sp-arithmetic", -] - -[[package]] -name = "sp-debug-derive" -version = "2.0.0-alpha.3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sp-std" -version = "2.0.0-alpha.3" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "syn" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "toml" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" -dependencies = [ - "serde", -] - -[[package]] -name = "uint" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75a4cdd7b87b28840dba13c483b9a88ee6bbf16ba5c951ee1ecfcf723078e0d" -dependencies = [ - "byteorder", - "crunchy", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "unicode-xid" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "winapi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/primitives/arithmetic/fuzzer/Cargo.toml b/primitives/arithmetic/fuzzer/Cargo.toml index f145c2cd9040c9594490a9674adca967d3dde447..3da97b18433e49e1fa71c37bdc371d7610820623 100644 --- a/primitives/arithmetic/fuzzer/Cargo.toml +++ b/primitives/arithmetic/fuzzer/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-arithmetic-fuzzer" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Fuzzer for fixed point arithmetic primitives." @@ -14,8 +14,8 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-arithmetic = { version = "2.0.0-dev", path = ".." } -honggfuzz = "0.5" +sp-arithmetic = { version = "2.0.0-rc6", path = ".." } +honggfuzz = "0.5.49" primitive-types = "0.7.0" num-bigint = "0.2" num-traits = "0.2" @@ -24,6 +24,10 @@ num-traits = "0.2" name = "biguint" path = "src/biguint.rs" +[[bin]] +name = "normalize" +path = "src/normalize.rs" + [[bin]] name = "per_thing_rational" path = "src/per_thing_rational.rs" @@ -31,3 +35,7 @@ path = "src/per_thing_rational.rs" [[bin]] name = "rational128" path = "src/rational128.rs" + +[[bin]] +name = "fixed_point" +path = "src/fixed_point.rs" diff --git a/primitives/arithmetic/fuzzer/src/biguint.rs b/primitives/arithmetic/fuzzer/src/biguint.rs index f217b080d25fa80c5c2199efb1440add203e9f06..9763245f4c7e0b699ad0a00694712efbbefadd72 100644 --- a/primitives/arithmetic/fuzzer/src/biguint.rs +++ b/primitives/arithmetic/fuzzer/src/biguint.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Running //! Running this fuzzer can be done with `cargo hfuzz run biguint`. `honggfuzz` CLI options can @@ -47,8 +48,8 @@ fn main() { digits_u.reverse(); digits_v.reverse(); - let num_u = num_bigint::BigUint::new(digits_u.clone()); - let num_v = num_bigint::BigUint::new(digits_v.clone()); + let num_u = num_bigint::BigUint::new(digits_u); + let num_v = num_bigint::BigUint::new(digits_v); if check_digit_lengths(&u, &v, 4) { assert_eq!(u.cmp(&v), ue.cmp(&ve)); @@ -145,14 +146,14 @@ fn main() { // Division if v.len() == 1 && v.get(0) != 0 { - let w = u.clone().div_unit(v.get(0)); - let num_w = num_u.clone() / &num_v; + let w = u.div_unit(v.get(0)); + let num_w = num_u / &num_v; assert_biguints_eq(&w, &num_w); } else if u.len() > v.len() && v.len() > 0 { let num_remainder = num_u.clone() % num_v.clone(); - let (w, remainder) = u.clone().div(&v, return_remainder).unwrap(); - let num_w = num_u.clone() / &num_v; + let (w, remainder) = u.div(&v, return_remainder).unwrap(); + let num_w = num_u / &num_v; assert_biguints_eq(&w, &num_w); diff --git a/primitives/arithmetic/fuzzer/src/fixed_point.rs b/primitives/arithmetic/fuzzer/src/fixed_point.rs new file mode 100644 index 0000000000000000000000000000000000000000..9a88197ac32adfbd1ada4ecc1a85805dc291cd91 --- /dev/null +++ b/primitives/arithmetic/fuzzer/src/fixed_point.rs @@ -0,0 +1,82 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! # Running +//! Running this fuzzer can be done with `cargo hfuzz run fixed_point`. `honggfuzz` CLI options can +//! be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. +//! +//! # Debugging a panic +//! Once a panic is found, it can be debugged with +//! `cargo hfuzz run-debug fixed_point hfuzz_workspace/fixed_point/*.fuzz`. +//! +//! # More information +//! More information about `honggfuzz` can be found +//! [here](https://docs.rs/honggfuzz/). + +use honggfuzz::fuzz; +use sp_arithmetic::{FixedPointNumber, FixedI64, traits::Saturating}; + +fn main() { + loop { + fuzz!(|data: (i32, i32)| { + let x: i128 = data.0.into(); + let y: i128 = data.1.into(); + + // Check `from_rational` and division are consistent. + if y != 0 { + let f1 = FixedI64::saturating_from_integer(x) / FixedI64::saturating_from_integer(y); + let f2 = FixedI64::saturating_from_rational(x, y); + assert_eq!(f1.into_inner(), f2.into_inner()); + } + + // Check `saturating_mul`. + let a = FixedI64::saturating_from_rational(2, 5); + let b = a.saturating_mul(FixedI64::saturating_from_integer(x)); + let n = b.into_inner() as i128; + let m = 2i128 * x * FixedI64::accuracy() as i128 / 5i128; + assert_eq!(n, m); + + // Check `saturating_mul` and division are inverse. + if x != 0 { + assert_eq!(a, b / FixedI64::saturating_from_integer(x)); + } + + // Check `reciprocal`. + let r = a.reciprocal().unwrap().reciprocal().unwrap(); + assert_eq!(a, r); + + // Check addition. + let a = FixedI64::saturating_from_integer(x); + let b = FixedI64::saturating_from_integer(y); + let c = FixedI64::saturating_from_integer(x.saturating_add(y)); + assert_eq!(a.saturating_add(b), c); + + // Check substraction. + let a = FixedI64::saturating_from_integer(x); + let b = FixedI64::saturating_from_integer(y); + let c = FixedI64::saturating_from_integer(x.saturating_sub(y)); + assert_eq!(a.saturating_sub(b), c); + + // Check `saturating_mul_acc_int`. + let a = FixedI64::saturating_from_rational(2, 5); + let b = a.saturating_mul_acc_int(x); + let xx = FixedI64::saturating_from_integer(x); + let d = a.saturating_mul(xx).saturating_add(xx).into_inner() as i128 / FixedI64::accuracy() as i128; + assert_eq!(b, d); + }); + } +} diff --git a/primitives/arithmetic/fuzzer/src/normalize.rs b/primitives/arithmetic/fuzzer/src/normalize.rs new file mode 100644 index 0000000000000000000000000000000000000000..34c4ef9cb0ab51e125c4a9a2a2535d8770a8b342 --- /dev/null +++ b/primitives/arithmetic/fuzzer/src/normalize.rs @@ -0,0 +1,62 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + + +//! # Running +//! Running this fuzzer can be done with `cargo hfuzz run normalize`. `honggfuzz` CLI options can +//! be used by setting `HFUZZ_RUN_ARGS`, such as `-n 4` to use 4 threads. +//! +//! # Debugging a panic +//! Once a panic is found, it can be debugged with +//! `cargo hfuzz run-debug normalize hfuzz_workspace/normalize/*.fuzz`. + +use honggfuzz::fuzz; +use sp_arithmetic::Normalizable; +use std::convert::TryInto; + +fn main() { + let sum_limit = u32::max_value() as u128; + let len_limit: usize = u32::max_value().try_into().unwrap(); + + loop { + fuzz!(|data: (Vec, u32)| { + let (data, norm) = data; + if data.len() == 0 { return; } + let pre_sum: u128 = data.iter().map(|x| *x as u128).sum(); + + let normalized = data.normalize(norm); + // error cases. + if pre_sum > sum_limit || data.len() > len_limit { + assert!(normalized.is_err()) + } else { + if let Ok(normalized) = normalized { + // if sum goes beyond u128, panic. + let sum: u128 = normalized.iter().map(|x| *x as u128).sum(); + + // if this function returns Ok(), then it will ALWAYS be accurate. + assert_eq!( + sum, + norm as u128, + "sums don't match {:?}, {}", + normalized, + norm, + ); + } + } + }) + } +} diff --git a/primitives/arithmetic/fuzzer/src/per_thing_rational.rs b/primitives/arithmetic/fuzzer/src/per_thing_rational.rs index c2dda3de2299cb713114a856c6eafbedf2d91be2..8ddbd0c6d59d97091a4430faca83a4317c2c052a 100644 --- a/primitives/arithmetic/fuzzer/src/per_thing_rational.rs +++ b/primitives/arithmetic/fuzzer/src/per_thing_rational.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Running //! Running this fuzzer can be done with `cargo hfuzz run per_thing_rational`. `honggfuzz` CLI options can @@ -113,10 +114,9 @@ fn main() { } } -fn assert_per_thing_equal_error(a: T, b: T, err: u128) { +fn assert_per_thing_equal_error(a: P, b: P, err: u128) { let a_abs = a.deconstruct().saturated_into::(); let b_abs = b.deconstruct().saturated_into::(); let diff = a_abs.max(b_abs) - a_abs.min(b_abs); - dbg!(&diff); assert!(diff <= err, "{:?} !~ {:?}", a, b); } diff --git a/primitives/arithmetic/fuzzer/src/rational128.rs b/primitives/arithmetic/fuzzer/src/rational128.rs index 586a165272244bc0ab8ee7a7ec5c5813de9b0a0e..7a33e46991aa1ed38ba581d2b594b9bf1f161be4 100644 --- a/primitives/arithmetic/fuzzer/src/rational128.rs +++ b/primitives/arithmetic/fuzzer/src/rational128.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! # Running //! Running this fuzzer can be done with `cargo hfuzz run rational128`. `honggfuzz` CLI options can diff --git a/primitives/arithmetic/src/biguint.rs b/primitives/arithmetic/src/biguint.rs index 6c3ca58a52d1f72c21fa548adcb5728e03be0ddf..41e2c759a59679a25eda9d42655eee83559cd4b4 100644 --- a/primitives/arithmetic/src/biguint.rs +++ b/primitives/arithmetic/src/biguint.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Infinite precision unsigned integer for substrate runtime. @@ -150,7 +151,7 @@ impl BigUint { // has the ability to cause this. There is nothing to do if the number already has 1 // limb only. call it a day and return. if self.len().is_zero() { return; } - let index = self.digits.iter().position(|&elem| elem != 0).unwrap_or(0); + let index = self.digits.iter().position(|&elem| elem != 0).unwrap_or(self.len() - 1); if index > 0 { self.digits = self.digits[index..].to_vec() @@ -580,19 +581,19 @@ pub mod tests { fn strip_works() { let mut a = BigUint::from_limbs(&[0, 1, 0]); a.lstrip(); - assert_eq!(a, BigUint { digits: vec![1, 0] }); + assert_eq!(a.digits, vec![1, 0]); let mut a = BigUint::from_limbs(&[0, 0, 1]); a.lstrip(); - assert_eq!(a, BigUint { digits: vec![1] }); + assert_eq!(a.digits, vec![1]); let mut a = BigUint::from_limbs(&[0, 0]); a.lstrip(); - assert_eq!(a, BigUint { digits: vec![0] }); + assert_eq!(a.digits, vec![0]); let mut a = BigUint::from_limbs(&[0, 0, 0]); a.lstrip(); - assert_eq!(a, BigUint { digits: vec![0] }); + assert_eq!(a.digits, vec![0]); } #[test] diff --git a/primitives/arithmetic/src/fixed128.rs b/primitives/arithmetic/src/fixed128.rs deleted file mode 100644 index a0fafe5ee3ece14ebb02921c0223912d44dff835..0000000000000000000000000000000000000000 --- a/primitives/arithmetic/src/fixed128.rs +++ /dev/null @@ -1,731 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -use codec::{Decode, Encode}; -use primitive_types::U256; -use crate::{ - traits::{Bounded, Saturating, UniqueSaturatedInto, SaturatedConversion}, - PerThing, Perquintill, -}; -use sp_std::{ - convert::{Into, TryFrom, TryInto}, - fmt, ops, - num::NonZeroI128, -}; - -#[cfg(feature = "std")] -use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; - -/// A signed fixed-point number. -/// Can hold any value in the range [-170_141_183_460_469_231_731, 170_141_183_460_469_231_731] -/// with fixed-point accuracy of 10 ** 18. -#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Fixed128(i128); - -const DIV: i128 = 1_000_000_000_000_000_000; - -impl Fixed128 { - /// Create self from a natural number. - /// - /// Note that this might be lossy. - pub fn from_natural(int: i128) -> Self { - Self(int.saturating_mul(DIV)) - } - - /// Accuracy of `Fixed128`. - pub const fn accuracy() -> i128 { - DIV - } - - /// Raw constructor. Equal to `parts / DIV`. - pub const fn from_parts(parts: i128) -> Self { - Self(parts) - } - - /// Creates self from a rational number. Equal to `n/d`. - /// - /// Note that this might be lossy. Only use this if you are sure that `n * DIV` can fit into an - /// i128. - pub fn from_rational>(n: N, d: NonZeroI128) -> Self { - let n = n.unique_saturated_into(); - Self(n.saturating_mul(DIV.into()) / d.get()) - } - - /// Consume self and return the inner raw `i128` value. - /// - /// Note this is a low level function, as the returned value is represented with accuracy. - pub fn deconstruct(self) -> i128 { - self.0 - } - - /// Takes the reciprocal(inverse) of Fixed128, 1/x - pub fn recip(&self) -> Option { - Self::from_natural(1i128).checked_div(self) - } - - /// Checked add. Same semantic to `num_traits::CheckedAdd`. - pub fn checked_add(&self, rhs: &Self) -> Option { - self.0.checked_add(rhs.0).map(Self) - } - - /// Checked sub. Same semantic to `num_traits::CheckedSub`. - pub fn checked_sub(&self, rhs: &Self) -> Option { - self.0.checked_sub(rhs.0).map(Self) - } - - /// Checked mul. Same semantic to `num_traits::CheckedMul`. - pub fn checked_mul(&self, rhs: &Self) -> Option { - let signum = self.0.signum() * rhs.0.signum(); - let mut lhs = self.0; - if lhs.is_negative() { - lhs = lhs.saturating_mul(-1); - } - let mut rhs: i128 = rhs.0.saturated_into(); - if rhs.is_negative() { - rhs = rhs.saturating_mul(-1); - } - - U256::from(lhs) - .checked_mul(U256::from(rhs)) - .and_then(|n| n.checked_div(U256::from(DIV))) - .and_then(|n| TryInto::::try_into(n).ok()) - .map(|n| Self(n * signum)) - } - - /// Checked div. Same semantic to `num_traits::CheckedDiv`. - pub fn checked_div(&self, rhs: &Self) -> Option { - if rhs.0.signum() == 0 { - return None; - } - if self.0 == 0 { - return Some(*self); - } - - let signum = self.0.signum() / rhs.0.signum(); - let mut lhs: i128 = self.0; - if lhs.is_negative() { - lhs = lhs.saturating_mul(-1); - } - let mut rhs: i128 = rhs.0.saturated_into(); - if rhs.is_negative() { - rhs = rhs.saturating_mul(-1); - } - - U256::from(lhs) - .checked_mul(U256::from(DIV)) - .and_then(|n| n.checked_div(U256::from(rhs))) - .and_then(|n| TryInto::::try_into(n).ok()) - .map(|n| Self(n * signum)) - } - - /// Checked mul for int type `N`. - pub fn checked_mul_int(&self, other: &N) -> Option - where - N: Copy + TryFrom + TryInto, - { - N::try_into(*other).ok().and_then(|rhs| { - let mut lhs = self.0; - if lhs.is_negative() { - lhs = lhs.saturating_mul(-1); - } - let mut rhs: i128 = rhs.saturated_into(); - let signum = self.0.signum() * rhs.signum(); - if rhs.is_negative() { - rhs = rhs.saturating_mul(-1); - } - - U256::from(lhs) - .checked_mul(U256::from(rhs)) - .and_then(|n| n.checked_div(U256::from(DIV))) - .and_then(|n| TryInto::::try_into(n).ok()) - .and_then(|n| TryInto::::try_into(n * signum).ok()) - }) - } - - /// Checked mul for int type `N`. - pub fn saturating_mul_int(&self, other: &N) -> N - where - N: Copy + TryFrom + TryInto + Bounded, - { - self.checked_mul_int(other).unwrap_or_else(|| { - N::try_into(*other) - .map(|n| n.signum()) - .map(|n| n * self.0.signum()) - .map(|signum| { - if signum.is_negative() { - Bounded::min_value() - } else { - Bounded::max_value() - } - }) - .unwrap_or(Bounded::max_value()) - }) - } - - /// Checked div for int type `N`. - pub fn checked_div_int(&self, other: &N) -> Option - where - N: Copy + TryFrom + TryInto, - { - N::try_into(*other) - .ok() - .and_then(|n| self.0.checked_div(n)) - .and_then(|n| n.checked_div(DIV)) - .and_then(|n| TryInto::::try_into(n).ok()) - } - - pub fn zero() -> Self { - Self(0) - } - - pub fn is_zero(&self) -> bool { - self.0 == 0 - } - - /// Saturating absolute value. Returning MAX if `parts` == i128::MIN instead of overflowing. - pub fn saturating_abs(&self) -> Self { - if self.0 == i128::min_value() { - return Fixed128::max_value(); - } - - if self.0.is_negative() { - Fixed128::from_parts(self.0 * -1) - } else { - *self - } - } - - pub fn is_positive(&self) -> bool { - self.0.is_positive() - } - - pub fn is_negative(&self) -> bool { - self.0.is_negative() - } - - /// Performs a saturated multiply and accumulate by unsigned number. - /// - /// Returns a saturated `int + (self * int)`. - pub fn saturated_multiply_accumulate(self, int: N) -> N - where - N: TryFrom + From + UniqueSaturatedInto + Bounded + Clone + Saturating + - ops::Rem + ops::Div + ops::Mul + - ops::Add, - { - let div = DIV as u128; - let positive = self.0 > 0; - // safe to convert as absolute value. - let parts = self.0.checked_abs().map(|v| v as u128).unwrap_or(i128::max_value() as u128 + 1); - - - // will always fit. - let natural_parts = parts / div; - // might saturate. - let natural_parts: N = natural_parts.saturated_into(); - // fractional parts can always fit into u64. - let perquintill_parts = (parts % div) as u64; - - let n = int.clone().saturating_mul(natural_parts); - let p = Perquintill::from_parts(perquintill_parts) * int.clone(); - - // everything that needs to be either added or subtracted from the original weight. - let excess = n.saturating_add(p); - - if positive { - int.saturating_add(excess) - } else { - int.saturating_sub(excess) - } - } -} - -/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait -/// for safe addition. -impl ops::Add for Fixed128 { - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Self(self.0 + rhs.0) - } -} - -/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait -/// for safe subtraction. -impl ops::Sub for Fixed128 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self::Output { - Self(self.0 - rhs.0) - } -} - -impl Saturating for Fixed128 { - fn saturating_add(self, rhs: Self) -> Self { - Self(self.0.saturating_add(rhs.0)) - } - - fn saturating_sub(self, rhs: Self) -> Self { - Self(self.0.saturating_sub(rhs.0)) - } - - fn saturating_mul(self, rhs: Self) -> Self { - self.checked_mul(&rhs).unwrap_or_else(|| { - if (self.0.signum() * rhs.0.signum()).is_negative() { - Bounded::min_value() - } else { - Bounded::max_value() - } - }) - } - - fn saturating_pow(self, exp: usize) -> Self { - if exp == 0 { - return Self::from_natural(1); - } - - let exp = exp as u64; - let msb_pos = 64 - exp.leading_zeros(); - - let mut result = Self::from_natural(1); - let mut pow_val = self; - for i in 0..msb_pos { - if ((1 << i) & exp) > 0 { - result = result.saturating_mul(pow_val); - } - pow_val = pow_val.saturating_mul(pow_val); - } - result - } -} - -impl Bounded for Fixed128 { - fn min_value() -> Self { - Self(Bounded::min_value()) - } - - fn max_value() -> Self { - Self(Bounded::max_value()) - } -} - -impl fmt::Debug for Fixed128 { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let integral = { - let int = self.0 / DIV; - let signum_for_zero = if int == 0 && self.is_negative() { "-" } else { "" }; - format!("{}{}", signum_for_zero, int) - }; - let fractional = format!("{:0>18}", (self.0 % DIV).abs()); - write!(f, "Fixed128({}.{})", integral, fractional) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { - Ok(()) - } -} - -impl From

for Fixed128 { - fn from(val: P) -> Self { - let accuracy = P::ACCURACY.saturated_into().max(1) as i128; - let value = val.deconstruct().saturated_into() as i128; - Fixed128::from_rational(value, NonZeroI128::new(accuracy).unwrap()) - } -} - -#[cfg(feature = "std")] -impl Fixed128 { - fn i128_str(&self) -> String { - format!("{}", &self.0) - } - - fn try_from_i128_str(s: &str) -> Result { - let parts: i128 = s.parse().map_err(|_| "invalid string input")?; - Ok(Self::from_parts(parts)) - } -} - -// Manual impl `Serialize` as serde_json does not support i128. -// TODO: remove impl if issue https://github.com/serde-rs/json/issues/548 fixed. -#[cfg(feature = "std")] -impl Serialize for Fixed128 { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&self.i128_str()) - } -} - -// Manual impl `Serialize` as serde_json does not support i128. -// TODO: remove impl if issue https://github.com/serde-rs/json/issues/548 fixed. -#[cfg(feature = "std")] -impl<'de> Deserialize<'de> for Fixed128 { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let s = String::deserialize(deserializer)?; - Fixed128::try_from_i128_str(&s).map_err(|err_str| de::Error::custom(err_str)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{Perbill, Percent, Permill, Perquintill}; - - fn max() -> Fixed128 { - Fixed128::max_value() - } - - fn min() -> Fixed128 { - Fixed128::min_value() - } - - #[test] - fn fixed128_semantics() { - let a = Fixed128::from_rational(5, NonZeroI128::new(2).unwrap()); - let b = Fixed128::from_rational(10, NonZeroI128::new(4).unwrap()); - assert_eq!(a.0, 5 * DIV / 2); - assert_eq!(a, b); - - let a = Fixed128::from_rational(-5, NonZeroI128::new(1).unwrap()); - assert_eq!(a, Fixed128::from_natural(-5)); - - let a = Fixed128::from_rational(5, NonZeroI128::new(-1).unwrap()); - assert_eq!(a, Fixed128::from_natural(-5)); - - // biggest value that can be created. - assert_ne!(max(), Fixed128::from_natural(170_141_183_460_469_231_731)); - assert_eq!(max(), Fixed128::from_natural(170_141_183_460_469_231_732)); - - // the smallest value that can be created. - assert_ne!(min(), Fixed128::from_natural(-170_141_183_460_469_231_731)); - assert_eq!(min(), Fixed128::from_natural(-170_141_183_460_469_231_732)); - } - - #[test] - fn fixed128_operation() { - let a = Fixed128::from_natural(2); - let b = Fixed128::from_natural(1); - assert_eq!(a.checked_add(&b), Some(Fixed128::from_natural(1 + 2))); - assert_eq!(a.checked_sub(&b), Some(Fixed128::from_natural(2 - 1))); - assert_eq!(a.checked_mul(&b), Some(Fixed128::from_natural(1 * 2))); - assert_eq!( - a.checked_div(&b), - Some(Fixed128::from_rational(2, NonZeroI128::new(1).unwrap())) - ); - - let a = Fixed128::from_rational(5, NonZeroI128::new(2).unwrap()); - let b = Fixed128::from_rational(3, NonZeroI128::new(2).unwrap()); - assert_eq!( - a.checked_add(&b), - Some(Fixed128::from_rational(8, NonZeroI128::new(2).unwrap())) - ); - assert_eq!( - a.checked_sub(&b), - Some(Fixed128::from_rational(2, NonZeroI128::new(2).unwrap())) - ); - assert_eq!( - a.checked_mul(&b), - Some(Fixed128::from_rational(15, NonZeroI128::new(4).unwrap())) - ); - assert_eq!( - a.checked_div(&b), - Some(Fixed128::from_rational(10, NonZeroI128::new(6).unwrap())) - ); - - let a = Fixed128::from_natural(120); - assert_eq!(a.checked_div_int(&2i32), Some(60)); - - let a = Fixed128::from_rational(20, NonZeroI128::new(1).unwrap()); - assert_eq!(a.checked_div_int(&2i32), Some(10)); - - let a = Fixed128::from_natural(120); - assert_eq!(a.checked_mul_int(&2i32), Some(240)); - - let a = Fixed128::from_rational(1, NonZeroI128::new(2).unwrap()); - assert_eq!(a.checked_mul_int(&20i32), Some(10)); - - let a = Fixed128::from_rational(-1, NonZeroI128::new(2).unwrap()); - assert_eq!(a.checked_mul_int(&20i32), Some(-10)); - } - - #[test] - fn saturating_mul_should_work() { - let a = Fixed128::from_natural(-1); - assert_eq!(min().saturating_mul(a), max()); - - assert_eq!(Fixed128::from_natural(125).saturating_mul(a).deconstruct(), -125 * DIV); - - let a = Fixed128::from_rational(1, NonZeroI128::new(5).unwrap()); - assert_eq!(Fixed128::from_natural(125).saturating_mul(a).deconstruct(), 25 * DIV); - } - - #[test] - fn saturating_mul_int_works() { - let a = Fixed128::from_rational(10, NonZeroI128::new(1).unwrap()); - assert_eq!(a.saturating_mul_int(&i32::max_value()), i32::max_value()); - - let a = Fixed128::from_rational(-10, NonZeroI128::new(1).unwrap()); - assert_eq!(a.saturating_mul_int(&i32::max_value()), i32::min_value()); - - let a = Fixed128::from_rational(3, NonZeroI128::new(1).unwrap()); - assert_eq!(a.saturating_mul_int(&100i8), i8::max_value()); - - let a = Fixed128::from_rational(10, NonZeroI128::new(1).unwrap()); - assert_eq!(a.saturating_mul_int(&123i128), 1230); - - let a = Fixed128::from_rational(-10, NonZeroI128::new(1).unwrap()); - assert_eq!(a.saturating_mul_int(&123i128), -1230); - - assert_eq!(max().saturating_mul_int(&2i128), 340_282_366_920_938_463_463); - - assert_eq!(max().saturating_mul_int(&i128::min_value()), i128::min_value()); - - assert_eq!(min().saturating_mul_int(&i128::max_value()), i128::min_value()); - - assert_eq!(min().saturating_mul_int(&i128::min_value()), i128::max_value()); - } - - #[test] - fn zero_works() { - assert_eq!(Fixed128::zero(), Fixed128::from_natural(0)); - } - - #[test] - fn is_zero_works() { - assert!(Fixed128::zero().is_zero()); - assert!(!Fixed128::from_natural(1).is_zero()); - } - - #[test] - fn checked_div_with_zero_should_be_none() { - let a = Fixed128::from_natural(1); - let b = Fixed128::from_natural(0); - assert_eq!(a.checked_div(&b), None); - assert_eq!(b.checked_div(&a), Some(b)); - } - - #[test] - fn checked_div_int_with_zero_should_be_none() { - let a = Fixed128::from_natural(1); - assert_eq!(a.checked_div_int(&0i32), None); - let a = Fixed128::from_natural(0); - assert_eq!(a.checked_div_int(&1i32), Some(0)); - } - - #[test] - fn checked_div_with_zero_dividend_should_be_zero() { - let a = Fixed128::zero(); - let b = Fixed128::from_parts(1); - - assert_eq!(a.checked_div(&b), Some(Fixed128::zero())); - } - - #[test] - fn under_flow_should_be_none() { - let b = Fixed128::from_natural(1); - assert_eq!(min().checked_sub(&b), None); - } - - #[test] - fn over_flow_should_be_none() { - let a = Fixed128::from_parts(i128::max_value() - 1); - let b = Fixed128::from_parts(2); - assert_eq!(a.checked_add(&b), None); - - let a = Fixed128::max_value(); - let b = Fixed128::from_rational(2, NonZeroI128::new(1).unwrap()); - assert_eq!(a.checked_mul(&b), None); - - let a = Fixed128::from_natural(255); - let b = 2u8; - assert_eq!(a.checked_mul_int(&b), None); - - let a = Fixed128::from_natural(256); - let b = 1u8; - assert_eq!(a.checked_div_int(&b), None); - - let a = Fixed128::from_natural(256); - let b = -1i8; - assert_eq!(a.checked_div_int(&b), None); - } - - #[test] - fn checked_div_int_should_work() { - // 256 / 10 = 25 (25.6 as int = 25) - let a = Fixed128::from_natural(256); - let result = a.checked_div_int(&10i128).unwrap(); - assert_eq!(result, 25); - - // 256 / 100 = 2 (2.56 as int = 2) - let a = Fixed128::from_natural(256); - let result = a.checked_div_int(&100i128).unwrap(); - assert_eq!(result, 2); - - // 256 / 1000 = 0 (0.256 as int = 0) - let a = Fixed128::from_natural(256); - let result = a.checked_div_int(&1000i128).unwrap(); - assert_eq!(result, 0); - - // 256 / -1 = -256 - let a = Fixed128::from_natural(256); - let result = a.checked_div_int(&-1i128).unwrap(); - assert_eq!(result, -256); - - // -256 / -1 = 256 - let a = Fixed128::from_natural(-256); - let result = a.checked_div_int(&-1i128).unwrap(); - assert_eq!(result, 256); - - // 10 / -5 = -2 - let a = Fixed128::from_rational(20, NonZeroI128::new(2).unwrap()); - let result = a.checked_div_int(&-5i128).unwrap(); - assert_eq!(result, -2); - - // -170_141_183_460_469_231_731 / -2 = 85_070_591_730_234_615_865 - let result = min().checked_div_int(&-2i128).unwrap(); - assert_eq!(result, 85_070_591_730_234_615_865); - - // 85_070_591_730_234_615_865 * -2 = -170_141_183_460_469_231_730 - let result = Fixed128::from_natural(result).checked_mul_int(&-2i128).unwrap(); - assert_eq!(result, -170_141_183_460_469_231_730); - } - - #[test] - fn perthing_into_fixed_i128() { - let ten_percent_percent: Fixed128 = Percent::from_percent(10).into(); - assert_eq!(ten_percent_percent.deconstruct(), DIV / 10); - - let ten_percent_permill: Fixed128 = Permill::from_percent(10).into(); - assert_eq!(ten_percent_permill.deconstruct(), DIV / 10); - - let ten_percent_perbill: Fixed128 = Perbill::from_percent(10).into(); - assert_eq!(ten_percent_perbill.deconstruct(), DIV / 10); - - let ten_percent_perquintill: Fixed128 = Perquintill::from_percent(10).into(); - assert_eq!(ten_percent_perquintill.deconstruct(), DIV / 10); - } - - #[test] - fn recip_should_work() { - let a = Fixed128::from_natural(2); - assert_eq!( - a.recip(), - Some(Fixed128::from_rational(1, NonZeroI128::new(2).unwrap())) - ); - - let a = Fixed128::from_natural(2); - assert_eq!(a.recip().unwrap().checked_mul_int(&4i32), Some(2i32)); - - let a = Fixed128::from_rational(100, NonZeroI128::new(121).unwrap()); - assert_eq!( - a.recip(), - Some(Fixed128::from_rational(121, NonZeroI128::new(100).unwrap())) - ); - - let a = Fixed128::from_rational(1, NonZeroI128::new(2).unwrap()); - assert_eq!(a.recip().unwrap().checked_mul(&a), Some(Fixed128::from_natural(1))); - - let a = Fixed128::from_natural(0); - assert_eq!(a.recip(), None); - - let a = Fixed128::from_rational(-1, NonZeroI128::new(2).unwrap()); - assert_eq!(a.recip(), Some(Fixed128::from_natural(-2))); - } - - #[test] - fn serialize_deserialize_should_work() { - let two_point_five = Fixed128::from_rational(5, NonZeroI128::new(2).unwrap()); - let serialized = serde_json::to_string(&two_point_five).unwrap(); - assert_eq!(serialized, "\"2500000000000000000\""); - let deserialized: Fixed128 = serde_json::from_str(&serialized).unwrap(); - assert_eq!(deserialized, two_point_five); - - let minus_two_point_five = Fixed128::from_rational(-5, NonZeroI128::new(2).unwrap()); - let serialized = serde_json::to_string(&minus_two_point_five).unwrap(); - assert_eq!(serialized, "\"-2500000000000000000\""); - let deserialized: Fixed128 = serde_json::from_str(&serialized).unwrap(); - assert_eq!(deserialized, minus_two_point_five); - } - - #[test] - fn saturating_abs_should_work() { - // normal - assert_eq!(Fixed128::from_parts(1).saturating_abs(), Fixed128::from_parts(1)); - assert_eq!(Fixed128::from_parts(-1).saturating_abs(), Fixed128::from_parts(1)); - - // saturating - assert_eq!(Fixed128::min_value().saturating_abs(), Fixed128::max_value()); - } - - #[test] - fn is_positive_negative_should_work() { - let positive = Fixed128::from_parts(1); - assert!(positive.is_positive()); - assert!(!positive.is_negative()); - - let negative = Fixed128::from_parts(-1); - assert!(!negative.is_positive()); - assert!(negative.is_negative()); - - let zero = Fixed128::zero(); - assert!(!zero.is_positive()); - assert!(!zero.is_negative()); - } - - #[test] - fn fmt_should_work() { - let positive = Fixed128::from_parts(1000000000000000001); - assert_eq!(format!("{:?}", positive), "Fixed128(1.000000000000000001)"); - let negative = Fixed128::from_parts(-1000000000000000001); - assert_eq!(format!("{:?}", negative), "Fixed128(-1.000000000000000001)"); - - let positive_fractional = Fixed128::from_parts(1); - assert_eq!(format!("{:?}", positive_fractional), "Fixed128(0.000000000000000001)"); - let negative_fractional = Fixed128::from_parts(-1); - assert_eq!(format!("{:?}", negative_fractional), "Fixed128(-0.000000000000000001)"); - - let zero = Fixed128::zero(); - assert_eq!(format!("{:?}", zero), "Fixed128(0.000000000000000000)"); - } - - #[test] - fn saturating_pow_should_work() { - assert_eq!(Fixed128::from_natural(2).saturating_pow(0), Fixed128::from_natural(1)); - assert_eq!(Fixed128::from_natural(2).saturating_pow(1), Fixed128::from_natural(2)); - assert_eq!(Fixed128::from_natural(2).saturating_pow(2), Fixed128::from_natural(4)); - assert_eq!(Fixed128::from_natural(2).saturating_pow(3), Fixed128::from_natural(8)); - assert_eq!(Fixed128::from_natural(2).saturating_pow(50), Fixed128::from_natural(1125899906842624)); - - assert_eq!(Fixed128::from_natural(1).saturating_pow(1000), Fixed128::from_natural(1)); - assert_eq!(Fixed128::from_natural(-1).saturating_pow(1000), Fixed128::from_natural(1)); - assert_eq!(Fixed128::from_natural(-1).saturating_pow(1001), Fixed128::from_natural(-1)); - assert_eq!(Fixed128::from_natural(1).saturating_pow(usize::max_value()), Fixed128::from_natural(1)); - assert_eq!(Fixed128::from_natural(-1).saturating_pow(usize::max_value()), Fixed128::from_natural(-1)); - assert_eq!(Fixed128::from_natural(-1).saturating_pow(usize::max_value() - 1), Fixed128::from_natural(1)); - - assert_eq!(Fixed128::from_natural(114209).saturating_pow(4), Fixed128::from_natural(170137997018538053761)); - assert_eq!(Fixed128::from_natural(114209).saturating_pow(5), Fixed128::max_value()); - - assert_eq!(Fixed128::from_natural(1).saturating_pow(usize::max_value()), Fixed128::from_natural(1)); - assert_eq!(Fixed128::from_natural(0).saturating_pow(usize::max_value()), Fixed128::from_natural(0)); - assert_eq!(Fixed128::from_natural(2).saturating_pow(usize::max_value()), Fixed128::max_value()); - } -} diff --git a/primitives/arithmetic/src/fixed64.rs b/primitives/arithmetic/src/fixed64.rs deleted file mode 100644 index 819982aa502c5caa1f169d48af19fd5908734bf8..0000000000000000000000000000000000000000 --- a/primitives/arithmetic/src/fixed64.rs +++ /dev/null @@ -1,381 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -use sp_std::{ - ops, prelude::*, - convert::{TryFrom, TryInto}, -}; -use codec::{Encode, Decode}; -use crate::{ - Perbill, - traits::{ - SaturatedConversion, CheckedSub, CheckedAdd, CheckedDiv, Bounded, UniqueSaturatedInto, Saturating - } -}; - -/// An unsigned fixed point number. Can hold any value in the range [-9_223_372_036, 9_223_372_036] -/// with fixed point accuracy of one billion. -#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Fixed64(i64); - -/// The accuracy of the `Fixed64` type. -const DIV: i64 = 1_000_000_000; - -impl Fixed64 { - /// creates self from a natural number. - /// - /// Note that this might be lossy. - pub fn from_natural(int: i64) -> Self { - Self(int.saturating_mul(DIV)) - } - - /// Return the accuracy of the type. Given that this function returns the value `X`, it means - /// that an instance composed of `X` parts (`Fixed64::from_parts(X)`) is equal to `1`. - pub fn accuracy() -> i64 { - DIV - } - - /// Consume self and return the inner value. - pub fn into_inner(self) -> i64 { self.0 } - - /// Raw constructor. Equal to `parts / 1_000_000_000`. - pub fn from_parts(parts: i64) -> Self { - Self(parts) - } - - /// creates self from a rational number. Equal to `n/d`. - /// - /// Note that this might be lossy. - pub fn from_rational(n: i64, d: u64) -> Self { - Self( - (i128::from(n).saturating_mul(i128::from(DIV)) / i128::from(d).max(1)) - .try_into() - .unwrap_or_else(|_| Bounded::max_value()) - ) - } - - /// Performs a saturated multiply and accumulate by unsigned number. - /// - /// Returns a saturated `int + (self * int)`. - pub fn saturated_multiply_accumulate(self, int: N) -> N - where - N: TryFrom + From + UniqueSaturatedInto + Bounded + Clone + Saturating + - ops::Rem + ops::Div + ops::Mul + - ops::Add, - { - let div = DIV as u64; - let positive = self.0 > 0; - // safe to convert as absolute value. - let parts = self.0.checked_abs().map(|v| v as u64).unwrap_or(i64::max_value() as u64 + 1); - - - // will always fit. - let natural_parts = parts / div; - // might saturate. - let natural_parts: N = natural_parts.saturated_into(); - // fractional parts can always fit into u32. - let perbill_parts = (parts % div) as u32; - - let n = int.clone().saturating_mul(natural_parts); - let p = Perbill::from_parts(perbill_parts) * int.clone(); - - // everything that needs to be either added or subtracted from the original weight. - let excess = n.saturating_add(p); - - if positive { - int.saturating_add(excess) - } else { - int.saturating_sub(excess) - } - } - - pub fn is_negative(&self) -> bool { - self.0.is_negative() - } -} - -impl Saturating for Fixed64 { - fn saturating_add(self, rhs: Self) -> Self { - Self(self.0.saturating_add(rhs.0)) - } - - fn saturating_mul(self, rhs: Self) -> Self { - let a = self.0 as i128; - let b = rhs.0 as i128; - let res = a * b / DIV as i128; - Self(res.saturated_into()) - } - - fn saturating_sub(self, rhs: Self) -> Self { - Self(self.0.saturating_sub(rhs.0)) - } - - fn saturating_pow(self, exp: usize) -> Self { - if exp == 0 { - return Self::from_natural(1); - } - - let exp = exp as u64; - let msb_pos = 64 - exp.leading_zeros(); - - let mut result = Self::from_natural(1); - let mut pow_val = self; - for i in 0..msb_pos { - if ((1 << i) & exp) > 0 { - result = result.saturating_mul(pow_val); - } - pow_val = pow_val.saturating_mul(pow_val); - } - result - } -} - -/// Use `Saturating` trait for safe addition. -impl ops::Add for Fixed64 { - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Self(self.0 + rhs.0) - } -} - -/// Use `Saturating` trait for safe subtraction. -impl ops::Sub for Fixed64 { - type Output = Self; - - fn sub(self, rhs: Self) -> Self::Output { - Self(self.0 - rhs.0) - } -} - -/// Use `CheckedDiv` trait for safe division. -impl ops::Div for Fixed64 { - type Output = Self; - - fn div(self, rhs: Self) -> Self::Output { - if rhs.0 == 0 { - panic!("attempt to divide by zero"); - } - let (n, d) = if rhs.0 < 0 { - (-self.0, rhs.0.abs() as u64) - } else { - (self.0, rhs.0 as u64) - }; - Fixed64::from_rational(n, d) - } -} - -impl CheckedSub for Fixed64 { - fn checked_sub(&self, rhs: &Self) -> Option { - self.0.checked_sub(rhs.0).map(Self) - } -} - -impl CheckedAdd for Fixed64 { - fn checked_add(&self, rhs: &Self) -> Option { - self.0.checked_add(rhs.0).map(Self) - } -} - -impl CheckedDiv for Fixed64 { - fn checked_div(&self, rhs: &Self) -> Option { - if rhs.0 == 0 { - None - } else { - Some(*self / *rhs) - } - } -} - -impl sp_std::fmt::Debug for Fixed64 { - #[cfg(feature = "std")] - fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - let integral = { - let int = self.0 / DIV; - let signum_for_zero = if int == 0 && self.is_negative() { "-" } else { "" }; - format!("{}{}", signum_for_zero, int) - }; - let fractional = format!("{:0>9}", (self.0 % DIV).abs()); - write!(f, "Fixed64({}.{})", integral, fractional) - } - - #[cfg(not(feature = "std"))] - fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn max() -> Fixed64 { - Fixed64::from_parts(i64::max_value()) - } - - #[test] - fn fixed64_semantics() { - assert_eq!(Fixed64::from_rational(5, 2).0, 5 * 1_000_000_000 / 2); - assert_eq!(Fixed64::from_rational(5, 2), Fixed64::from_rational(10, 4)); - assert_eq!(Fixed64::from_rational(5, 0), Fixed64::from_rational(5, 1)); - - // biggest value that can be created. - assert_ne!(max(), Fixed64::from_natural(9_223_372_036)); - assert_eq!(max(), Fixed64::from_natural(9_223_372_037)); - } - - #[test] - fn fixed_64_growth_decrease_curve() { - let test_set = vec![0u32, 1, 10, 1000, 1_000_000_000]; - - // negative (1/2) - let mut fm = Fixed64::from_rational(-1, 2); - test_set.clone().into_iter().for_each(|i| { - assert_eq!(fm.saturated_multiply_accumulate(i) as i32, i as i32 - i as i32 / 2); - }); - - // unit (1) multiplier - fm = Fixed64::from_parts(0); - test_set.clone().into_iter().for_each(|i| { - assert_eq!(fm.saturated_multiply_accumulate(i), i); - }); - - // i.5 multiplier - fm = Fixed64::from_rational(1, 2); - test_set.clone().into_iter().for_each(|i| { - assert_eq!(fm.saturated_multiply_accumulate(i), i * 3 / 2); - }); - - // dual multiplier - fm = Fixed64::from_rational(1, 1); - test_set.clone().into_iter().for_each(|i| { - assert_eq!(fm.saturated_multiply_accumulate(i), i * 2); - }); - } - - macro_rules! saturating_mul_acc_test { - ($num_type:tt) => { - assert_eq!( - Fixed64::from_rational(100, 1).saturated_multiply_accumulate(10 as $num_type), - 1010, - ); - assert_eq!( - Fixed64::from_rational(100, 2).saturated_multiply_accumulate(10 as $num_type), - 510, - ); - assert_eq!( - Fixed64::from_rational(100, 3).saturated_multiply_accumulate(0 as $num_type), - 0, - ); - assert_eq!( - Fixed64::from_rational(5, 1).saturated_multiply_accumulate($num_type::max_value()), - $num_type::max_value() - ); - assert_eq!( - max().saturated_multiply_accumulate($num_type::max_value()), - $num_type::max_value() - ); - } - } - - #[test] - fn fixed64_multiply_accumulate_works() { - saturating_mul_acc_test!(u32); - saturating_mul_acc_test!(u64); - saturating_mul_acc_test!(u128); - } - - #[test] - fn div_works() { - let a = Fixed64::from_rational(12, 10); - let b = Fixed64::from_rational(10, 1); - assert_eq!(a / b, Fixed64::from_rational(12, 100)); - - let a = Fixed64::from_rational(12, 10); - let b = Fixed64::from_rational(1, 100); - assert_eq!(a / b, Fixed64::from_rational(120, 1)); - - let a = Fixed64::from_rational(12, 100); - let b = Fixed64::from_rational(10, 1); - assert_eq!(a / b, Fixed64::from_rational(12, 1000)); - - let a = Fixed64::from_rational(12, 100); - let b = Fixed64::from_rational(1, 100); - assert_eq!(a / b, Fixed64::from_rational(12, 1)); - - let a = Fixed64::from_rational(-12, 10); - let b = Fixed64::from_rational(10, 1); - assert_eq!(a / b, Fixed64::from_rational(-12, 100)); - - let a = Fixed64::from_rational(12, 10); - let b = Fixed64::from_rational(-10, 1); - assert_eq!(a / b, Fixed64::from_rational(-12, 100)); - - let a = Fixed64::from_rational(-12, 10); - let b = Fixed64::from_rational(-10, 1); - assert_eq!(a / b, Fixed64::from_rational(12, 100)); - } - - #[test] - #[should_panic(expected = "attempt to divide by zero")] - fn div_zero() { - let a = Fixed64::from_rational(12, 10); - let b = Fixed64::from_natural(0); - let _ = a / b; - } - - #[test] - fn checked_div_zero() { - let a = Fixed64::from_rational(12, 10); - let b = Fixed64::from_natural(0); - assert_eq!(a.checked_div(&b), None); - } - - #[test] - fn checked_div_non_zero() { - let a = Fixed64::from_rational(12, 10); - let b = Fixed64::from_rational(1, 100); - assert_eq!(a.checked_div(&b), Some(Fixed64::from_rational(120, 1))); - } - - #[test] - fn saturating_mul_should_work() { - assert_eq!(Fixed64::from_natural(100).saturating_mul(Fixed64::from_natural(100)), Fixed64::from_natural(10000)); - } - - #[test] - fn saturating_pow_should_work() { - assert_eq!(Fixed64::from_natural(2).saturating_pow(0), Fixed64::from_natural(1)); - assert_eq!(Fixed64::from_natural(2).saturating_pow(1), Fixed64::from_natural(2)); - assert_eq!(Fixed64::from_natural(2).saturating_pow(2), Fixed64::from_natural(4)); - assert_eq!(Fixed64::from_natural(2).saturating_pow(3), Fixed64::from_natural(8)); - assert_eq!(Fixed64::from_natural(2).saturating_pow(20), Fixed64::from_natural(1048576)); - - assert_eq!(Fixed64::from_natural(1).saturating_pow(1000), Fixed64::from_natural(1)); - assert_eq!(Fixed64::from_natural(-1).saturating_pow(1000), Fixed64::from_natural(1)); - assert_eq!(Fixed64::from_natural(-1).saturating_pow(1001), Fixed64::from_natural(-1)); - assert_eq!(Fixed64::from_natural(1).saturating_pow(usize::max_value()), Fixed64::from_natural(1)); - assert_eq!(Fixed64::from_natural(-1).saturating_pow(usize::max_value()), Fixed64::from_natural(-1)); - assert_eq!(Fixed64::from_natural(-1).saturating_pow(usize::max_value() - 1), Fixed64::from_natural(1)); - - assert_eq!(Fixed64::from_natural(309).saturating_pow(4), Fixed64::from_natural(9_116_621_361)); - assert_eq!(Fixed64::from_natural(309).saturating_pow(5), Fixed64::from_parts(i64::max_value())); - - assert_eq!(Fixed64::from_natural(1).saturating_pow(usize::max_value()), Fixed64::from_natural(1)); - assert_eq!(Fixed64::from_natural(0).saturating_pow(usize::max_value()), Fixed64::from_natural(0)); - assert_eq!(Fixed64::from_natural(2).saturating_pow(usize::max_value()), Fixed64::from_parts(i64::max_value())); - } -} diff --git a/primitives/arithmetic/src/fixed_point.rs b/primitives/arithmetic/src/fixed_point.rs new file mode 100644 index 0000000000000000000000000000000000000000..59c237efb626075fcacf20ceb6d9bf75658d761c --- /dev/null +++ b/primitives/arithmetic/src/fixed_point.rs @@ -0,0 +1,1622 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Decimal Fixed Point implementations for Substrate runtime. + +use sp_std::{ops::{self, Add, Sub, Mul, Div}, fmt::Debug, prelude::*, convert::{TryInto, TryFrom}}; +use codec::{Encode, Decode}; +use crate::{ + helpers_128bit::multiply_by_rational, PerThing, + traits::{ + SaturatedConversion, CheckedSub, CheckedAdd, CheckedMul, CheckedDiv, CheckedNeg, + Bounded, Saturating, UniqueSaturatedInto, Zero, One + }, +}; + +#[cfg(feature = "std")] +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + +/// Integer types that can be used to interact with `FixedPointNumber` implementations. +pub trait FixedPointOperand: Copy + Clone + Bounded + Zero + Saturating + + PartialOrd + UniqueSaturatedInto + TryFrom + CheckedNeg {} + +impl FixedPointOperand for i128 {} +impl FixedPointOperand for u128 {} +impl FixedPointOperand for i64 {} +impl FixedPointOperand for u64 {} +impl FixedPointOperand for i32 {} +impl FixedPointOperand for u32 {} +impl FixedPointOperand for i16 {} +impl FixedPointOperand for u16 {} +impl FixedPointOperand for i8 {} +impl FixedPointOperand for u8 {} + +/// Something that implements a decimal fixed point number. +/// +/// The precision is given by `Self::DIV`, i.e. `1 / DIV` can be represented. +/// +/// Each type can store numbers from `Self::Inner::min_value() / Self::DIV` +/// to `Self::Inner::max_value() / Self::DIV`. +/// This is also referred to as the _accuracy_ of the type in the documentation. +pub trait FixedPointNumber: + Sized + Copy + Default + Debug + + Saturating + Bounded + + Eq + PartialEq + Ord + PartialOrd + + CheckedSub + CheckedAdd + CheckedMul + CheckedDiv + + Add + Sub + Div + Mul +{ + /// The underlying data type used for this fixed point number. + type Inner: Debug + One + CheckedMul + CheckedDiv + FixedPointOperand; + + /// Precision of this fixed point implementation. It should be a power of `10`. + const DIV: Self::Inner; + + /// Indicates if this fixed point implementation is signed or not. + const SIGNED: bool; + + /// Precision of this fixed point implementation. + fn accuracy() -> Self::Inner { + Self::DIV + } + + /// Builds this type from an integer number. + fn from_inner(int: Self::Inner) -> Self; + + /// Consumes `self` and returns the inner raw value. + fn into_inner(self) -> Self::Inner; + + /// Creates self from an integer number `int`. + /// + /// Returns `Self::max` or `Self::min` if `int` exceeds accuracy. + fn saturating_from_integer(int: N) -> Self { + let mut n: I129 = int.into(); + n.value = n.value.saturating_mul(Self::DIV.saturated_into()); + Self::from_inner(from_i129(n).unwrap_or_else(|| to_bound(int, 0))) + } + + /// Creates `self` from an integer number `int`. + /// + /// Returns `None` if `int` exceeds accuracy. + fn checked_from_integer(int: Self::Inner) -> Option { + int.checked_mul(&Self::DIV).map(|inner| Self::from_inner(inner)) + } + + /// Creates `self` from a rational number. Equal to `n / d`. + /// + /// Panics if `d = 0`. Returns `Self::max` or `Self::min` if `n / d` exceeds accuracy. + fn saturating_from_rational(n: N, d: D) -> Self { + if d == D::zero() { + panic!("attempt to divide by zero") + } + Self::checked_from_rational(n, d).unwrap_or_else(|| to_bound(n, d)) + } + + /// Creates `self` from a rational number. Equal to `n / d`. + /// + /// Returns `None` if `d == 0` or `n / d` exceeds accuracy. + fn checked_from_rational(n: N, d: D) -> Option { + if d == D::zero() { + return None + } + + let n: I129 = n.into(); + let d: I129 = d.into(); + let negative = n.negative != d.negative; + + multiply_by_rational(n.value, Self::DIV.unique_saturated_into(), d.value).ok() + .and_then(|value| from_i129(I129 { value, negative })) + .map(|inner| Self::from_inner(inner)) + } + + /// Checked multiplication for integer type `N`. Equal to `self * n`. + /// + /// Returns `None` if the result does not fit in `N`. + fn checked_mul_int(self, n: N) -> Option { + let lhs: I129 = self.into_inner().into(); + let rhs: I129 = n.into(); + let negative = lhs.negative != rhs.negative; + + multiply_by_rational(lhs.value, rhs.value, Self::DIV.unique_saturated_into()).ok() + .and_then(|value| from_i129(I129 { value, negative })) + } + + /// Saturating multiplication for integer type `N`. Equal to `self * n`. + /// + /// Returns `N::min` or `N::max` if the result does not fit in `N`. + fn saturating_mul_int(self, n: N) -> N { + self.checked_mul_int(n).unwrap_or_else(|| to_bound(self.into_inner(), n)) + } + + /// Checked division for integer type `N`. Equal to `self / d`. + /// + /// Returns `None` if the result does not fit in `N` or `d == 0`. + fn checked_div_int(self, d: N) -> Option { + let lhs: I129 = self.into_inner().into(); + let rhs: I129 = d.into(); + let negative = lhs.negative != rhs.negative; + + lhs.value.checked_div(rhs.value) + .and_then(|n| n.checked_div(Self::DIV.unique_saturated_into())) + .and_then(|value| from_i129(I129 { value, negative })) + } + + /// Saturating division for integer type `N`. Equal to `self / d`. + /// + /// Panics if `d == 0`. Returns `N::min` or `N::max` if the result does not fit in `N`. + fn saturating_div_int(self, d: N) -> N { + if d == N::zero() { + panic!("attempt to divide by zero") + } + self.checked_div_int(d).unwrap_or_else(|| to_bound(self.into_inner(), d)) + } + + /// Saturating multiplication for integer type `N`, adding the result back. + /// Equal to `self * n + n`. + /// + /// Returns `N::min` or `N::max` if the multiplication or final result does not fit in `N`. + fn saturating_mul_acc_int(self, n: N) -> N { + if self.is_negative() && n > N::zero() { + n.saturating_sub(Self::zero().saturating_sub(self).saturating_mul_int(n)) + } else { + self.saturating_mul_int(n).saturating_add(n) + } + } + + /// Saturating absolute value. + /// + /// Returns `Self::max` if `self == Self::min`. + fn saturating_abs(self) -> Self { + let inner = self.into_inner(); + if inner >= Self::Inner::zero() { + self + } else { + Self::from_inner(inner.checked_neg().unwrap_or_else(|| Self::Inner::max_value())) + } + } + + /// Takes the reciprocal (inverse). Equal to `1 / self`. + /// + /// Returns `None` if `self = 0`. + fn reciprocal(self) -> Option { + Self::one().checked_div(&self) + } + + /// Returns zero. + fn zero() -> Self { + Self::from_inner(Self::Inner::zero()) + } + + /// Checks if the number is zero. + fn is_zero(&self) -> bool { + self.into_inner() == Self::Inner::zero() + } + + /// Returns one. + fn one() -> Self { + Self::from_inner(Self::DIV) + } + + /// Checks if the number is one. + fn is_one(&self) -> bool { + self.into_inner() == Self::Inner::one() + } + + /// Returns `true` if `self` is positive and `false` if the number is zero or negative. + fn is_positive(self) -> bool { + self.into_inner() > Self::Inner::zero() + } + + /// Returns `true` if `self` is negative and `false` if the number is zero or positive. + fn is_negative(self) -> bool { + self.into_inner() < Self::Inner::zero() + } + + /// Returns the integer part. + fn trunc(self) -> Self { + self.into_inner().checked_div(&Self::DIV) + .expect("panics only if DIV is zero, DIV is not zero; qed") + .checked_mul(&Self::DIV) + .map(|inner| Self::from_inner(inner)) + .expect("can not overflow since fixed number is >= integer part") + } + + /// Returns the fractional part. + /// + /// Note: the returned fraction will be non-negative for negative numbers, + /// except in the case where the integer part is zero. + fn frac(self) -> Self { + let integer = self.trunc(); + let fractional = self.saturating_sub(integer); + if integer == Self::zero() { + fractional + } else { + fractional.saturating_abs() + } + } + + /// Returns the smallest integer greater than or equal to a number. + /// + /// Saturates to `Self::max` (truncated) if the result does not fit. + fn ceil(self) -> Self { + if self.is_negative() { + self.trunc() + } else { + if self.frac() == Self::zero() { + self + } else { + self.saturating_add(Self::one()).trunc() + } + } + } + + /// Returns the largest integer less than or equal to a number. + /// + /// Saturates to `Self::min` (truncated) if the result does not fit. + fn floor(self) -> Self { + if self.is_negative() { + self.saturating_sub(Self::one()).trunc() + } else { + self.trunc() + } + } + + /// Returns the number rounded to the nearest integer. Rounds half-way cases away from 0.0. + /// + /// Saturates to `Self::min` or `Self::max` (truncated) if the result does not fit. + fn round(self) -> Self { + let n = self.frac().saturating_mul(Self::saturating_from_integer(10)); + if n < Self::saturating_from_integer(5) { + self.trunc() + } else { + if self.is_positive() { + self.saturating_add(Self::one()).trunc() + } else { + self.saturating_sub(Self::one()).trunc() + } + } + } +} + +/// Data type used as intermediate storage in some computations to avoid overflow. +struct I129 { + value: u128, + negative: bool, +} + +impl From for I129 { + fn from(n: N) -> I129 { + if n < N::zero() { + let value: u128 = n.checked_neg() + .map(|n| n.unique_saturated_into()) + .unwrap_or_else(|| N::max_value().unique_saturated_into().saturating_add(1)); + I129 { value, negative: true } + } else { + I129 { value: n.unique_saturated_into(), negative: false } + } + } +} + +/// Transforms an `I129` to `N` if it is possible. +fn from_i129(n: I129) -> Option { + let max_plus_one: u128 = N::max_value().unique_saturated_into().saturating_add(1); + if n.negative && N::min_value() < N::zero() && n.value == max_plus_one { + Some(N::min_value()) + } else { + let unsigned_inner: N = n.value.try_into().ok()?; + let inner = if n.negative { unsigned_inner.checked_neg()? } else { unsigned_inner }; + Some(inner) + } +} + +/// Returns `R::max` if the sign of `n * m` is positive, `R::min` otherwise. +fn to_bound(n: N, m: D) -> R { + if (n < N::zero()) != (m < D::zero()) { + R::min_value() + } else { + R::max_value() + } +} + +macro_rules! implement_fixed { + ( + $name:ident, + $test_mod:ident, + $inner_type:ty, + $signed:tt, + $div:tt, + $title:expr $(,)? + ) => { + /// A fixed point number representation in the range. + /// + #[doc = $title] + #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] + pub struct $name($inner_type); + + impl From<$inner_type> for $name { + fn from(int: $inner_type) -> Self { + $name::saturating_from_integer(int) + } + } + + impl From<(N, D)> for $name { + fn from(r: (N, D)) -> Self { + $name::saturating_from_rational(r.0, r.1) + } + } + + impl FixedPointNumber for $name { + type Inner = $inner_type; + + const DIV: Self::Inner = $div; + const SIGNED: bool = $signed; + + fn from_inner(inner: Self::Inner) -> Self { + Self(inner) + } + + fn into_inner(self) -> Self::Inner { + self.0 + } + } + + impl $name { + /// const version of `FixedPointNumber::from_inner`. + pub const fn from_inner(inner: $inner_type) -> Self { + Self(inner) + } + + #[cfg(any(feature = "std", test))] + pub fn from_fraction(x: f64) -> Self { + Self((x * (::DIV as f64)) as $inner_type) + } + + #[cfg(any(feature = "std", test))] + pub fn to_fraction(self) -> f64 { + self.0 as f64 / ::DIV as f64 + } + } + + impl Saturating for $name { + fn saturating_add(self, rhs: Self) -> Self { + Self(self.0.saturating_add(rhs.0)) + } + + fn saturating_sub(self, rhs: Self) -> Self { + Self(self.0.saturating_sub(rhs.0)) + } + + fn saturating_mul(self, rhs: Self) -> Self { + self.checked_mul(&rhs).unwrap_or_else(|| to_bound(self.0, rhs.0)) + } + + fn saturating_pow(self, exp: usize) -> Self { + if exp == 0 { + return Self::saturating_from_integer(1); + } + + let exp = exp as u32; + let msb_pos = 32 - exp.leading_zeros(); + + let mut result = Self::saturating_from_integer(1); + let mut pow_val = self; + for i in 0..msb_pos { + if ((1 << i) & exp) > 0 { + result = result.saturating_mul(pow_val); + } + pow_val = pow_val.saturating_mul(pow_val); + } + result + } + } + + impl ops::Neg for $name { + type Output = Self; + + fn neg(self) -> Self::Output { + Self(::Inner::zero() - self.0) + } + } + + impl ops::Add for $name { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } + } + + impl ops::Sub for $name { + type Output = Self; + + fn sub(self, rhs: Self) -> Self::Output { + Self(self.0 - rhs.0) + } + } + + impl ops::Mul for $name { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + self.checked_mul(&rhs) + .unwrap_or_else(|| panic!("attempt to multiply with overflow")) + } + } + + impl ops::Div for $name { + type Output = Self; + + fn div(self, rhs: Self) -> Self::Output { + if rhs.0 == 0 { + panic!("attempt to divide by zero") + } + self.checked_div(&rhs) + .unwrap_or_else(|| panic!("attempt to divide with overflow")) + } + } + + impl CheckedSub for $name { + fn checked_sub(&self, rhs: &Self) -> Option { + self.0.checked_sub(rhs.0).map(Self) + } + } + + impl CheckedAdd for $name { + fn checked_add(&self, rhs: &Self) -> Option { + self.0.checked_add(rhs.0).map(Self) + } + } + + impl CheckedDiv for $name { + fn checked_div(&self, other: &Self) -> Option { + if other.0 == 0 { + return None + } + + let lhs: I129 = self.0.into(); + let rhs: I129 = other.0.into(); + let negative = lhs.negative != rhs.negative; + + multiply_by_rational(lhs.value, Self::DIV as u128, rhs.value).ok() + .and_then(|value| from_i129(I129 { value, negative })) + .map(Self) + } + } + + impl CheckedMul for $name { + fn checked_mul(&self, other: &Self) -> Option { + let lhs: I129 = self.0.into(); + let rhs: I129 = other.0.into(); + let negative = lhs.negative != rhs.negative; + + multiply_by_rational(lhs.value, rhs.value, Self::DIV as u128).ok() + .and_then(|value| from_i129(I129 { value, negative })) + .map(Self) + } + } + + impl Bounded for $name { + fn min_value() -> Self { + Self(::Inner::min_value()) + } + + fn max_value() -> Self { + Self(::Inner::max_value()) + } + } + + impl sp_std::fmt::Debug for $name { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + let integral = { + let int = self.0 / Self::accuracy(); + let signum_for_zero = if int == 0 && self.is_negative() { "-" } else { "" }; + format!("{}{}", signum_for_zero, int) + }; + let precision = (Self::accuracy() as f64).log10() as usize; + let fractional = format!("{:0>weight$}", ((self.0 % Self::accuracy()) as i128).abs(), weight=precision); + write!(f, "{}({}.{})", stringify!($name), integral, fractional) + } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } + } + + impl From

for $name { + fn from(p: P) -> Self { + let accuracy = P::ACCURACY.saturated_into(); + let value = p.deconstruct().saturated_into(); + $name::saturating_from_rational(value, accuracy) + } + } + + #[cfg(feature = "std")] + impl sp_std::fmt::Display for $name { + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + write!(f, "{}", self.0) + } + } + + #[cfg(feature = "std")] + impl sp_std::str::FromStr for $name { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + let inner: ::Inner = s.parse() + .map_err(|_| "invalid string input for fixed point number")?; + Ok(Self::from_inner(inner)) + } + } + + // Manual impl `Serialize` as serde_json does not support i128. + // TODO: remove impl if issue https://github.com/serde-rs/json/issues/548 fixed. + #[cfg(feature = "std")] + impl Serialize for $name { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.to_string()) + } + } + + // Manual impl `Deserialize` as serde_json does not support i128. + // TODO: remove impl if issue https://github.com/serde-rs/json/issues/548 fixed. + #[cfg(feature = "std")] + impl<'de> Deserialize<'de> for $name { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + use sp_std::str::FromStr; + let s = String::deserialize(deserializer)?; + $name::from_str(&s).map_err(|err_str| de::Error::custom(err_str)) + } + } + + #[cfg(test)] + mod $test_mod { + use super::*; + use crate::{Perbill, Percent, Permill, Perquintill}; + + fn max() -> $name { + $name::max_value() + } + + fn min() -> $name { + $name::min_value() + } + + fn precision() -> usize { + ($name::accuracy() as f64).log10() as usize + } + + #[test] + fn macro_preconditions() { + assert!($name::DIV > 0); + } + + #[test] + fn from_i129_works() { + let a = I129 { + value: 1, + negative: true, + }; + + // Can't convert negative number to unsigned. + assert_eq!(from_i129::(a), None); + + let a = I129 { + value: u128::max_value() - 1, + negative: false, + }; + + // Max - 1 value fits. + assert_eq!(from_i129::(a), Some(u128::max_value() - 1)); + + let a = I129 { + value: u128::max_value(), + negative: false, + }; + + // Max value fits. + assert_eq!(from_i129::(a), Some(u128::max_value())); + + let a = I129 { + value: i128::max_value() as u128 + 1, + negative: true, + }; + + // Min value fits. + assert_eq!(from_i129::(a), Some(i128::min_value())); + + let a = I129 { + value: i128::max_value() as u128 + 1, + negative: false, + }; + + // Max + 1 does not fit. + assert_eq!(from_i129::(a), None); + + let a = I129 { + value: i128::max_value() as u128, + negative: false, + }; + + // Max value fits. + assert_eq!(from_i129::(a), Some(i128::max_value())); + } + + #[test] + fn to_bound_works() { + let a = 1i32; + let b = 1i32; + + // Pos + Pos => Max. + assert_eq!(to_bound::<_, _, i32>(a, b), i32::max_value()); + + let a = -1i32; + let b = -1i32; + + // Neg + Neg => Max. + assert_eq!(to_bound::<_, _, i32>(a, b), i32::max_value()); + + let a = 1i32; + let b = -1i32; + + // Pos + Neg => Min. + assert_eq!(to_bound::<_, _, i32>(a, b), i32::min_value()); + + let a = -1i32; + let b = 1i32; + + // Neg + Pos => Min. + assert_eq!(to_bound::<_, _, i32>(a, b), i32::min_value()); + + let a = 1i32; + let b = -1i32; + + // Pos + Neg => Min (unsigned). + assert_eq!(to_bound::<_, _, u32>(a, b), 0); + } + + #[test] + fn op_neg_works() { + let a = $name::zero(); + let b = -a; + + // Zero. + assert_eq!(a, b); + + if $name::SIGNED { + let a = $name::saturating_from_integer(5); + let b = -a; + + // Positive. + assert_eq!($name::saturating_from_integer(-5), b); + + let a = $name::saturating_from_integer(-5); + let b = -a; + + // Negative + assert_eq!($name::saturating_from_integer(5), b); + + let a = $name::max_value(); + let b = -a; + + // Max. + assert_eq!($name::min_value() + $name::from_inner(1), b); + + let a = $name::min_value() + $name::from_inner(1); + let b = -a; + + // Min. + assert_eq!($name::max_value(), b); + + } + } + + #[test] + fn op_checked_add_overflow_works() { + let a = $name::max_value(); + let b = 1.into(); + assert!(a.checked_add(&b).is_none()); + } + + #[test] + fn op_add_works() { + let a = $name::saturating_from_rational(5, 2); + let b = $name::saturating_from_rational(1, 2); + + // Positive case: 6/2 = 3. + assert_eq!($name::saturating_from_integer(3), a + b); + + if $name::SIGNED { + // Negative case: 4/2 = 2. + let b = $name::saturating_from_rational(1, -2); + assert_eq!($name::saturating_from_integer(2), a + b); + } + } + + #[test] + fn op_checked_sub_underflow_works() { + let a = $name::min_value(); + let b = 1.into(); + assert!(a.checked_sub(&b).is_none()); + } + + #[test] + fn op_sub_works() { + let a = $name::saturating_from_rational(5, 2); + let b = $name::saturating_from_rational(1, 2); + + assert_eq!($name::saturating_from_integer(2), a - b); + assert_eq!($name::saturating_from_integer(-2), b.saturating_sub(a)); + } + + #[test] + fn op_checked_mul_overflow_works() { + let a = $name::max_value(); + let b = 2.into(); + assert!(a.checked_mul(&b).is_none()); + } + + #[test] + fn op_mul_works() { + let a = $name::saturating_from_integer(42); + let b = $name::saturating_from_integer(2); + assert_eq!($name::saturating_from_integer(84), a * b); + + let a = $name::saturating_from_integer(42); + let b = $name::saturating_from_integer(-2); + assert_eq!($name::saturating_from_integer(-84), a * b); + } + + #[test] + #[should_panic(expected = "attempt to divide by zero")] + fn op_div_panics_on_zero_divisor() { + let a = $name::saturating_from_integer(1); + let b = 0.into(); + let _c = a / b; + } + + #[test] + fn op_checked_div_overflow_works() { + if $name::SIGNED { + let a = $name::min_value(); + let b = $name::zero().saturating_sub($name::one()); + assert!(a.checked_div(&b).is_none()); + } + } + + #[test] + fn op_div_works() { + let a = $name::saturating_from_integer(42); + let b = $name::saturating_from_integer(2); + assert_eq!($name::saturating_from_integer(21), a / b); + + if $name::SIGNED { + let a = $name::saturating_from_integer(42); + let b = $name::saturating_from_integer(-2); + assert_eq!($name::saturating_from_integer(-21), a / b); + } + } + + #[test] + fn saturating_from_integer_works() { + let inner_max = <$name as FixedPointNumber>::Inner::max_value(); + let inner_min = <$name as FixedPointNumber>::Inner::min_value(); + let accuracy = $name::accuracy(); + + // Cases where integer fits. + let a = $name::saturating_from_integer(42); + assert_eq!(a.into_inner(), 42 * accuracy); + + let a = $name::saturating_from_integer(-42); + assert_eq!(a.into_inner(), 0.saturating_sub(42 * accuracy)); + + // Max/min integers that fit. + let a = $name::saturating_from_integer(inner_max / accuracy); + assert_eq!(a.into_inner(), (inner_max / accuracy) * accuracy); + + let a = $name::saturating_from_integer(inner_min / accuracy); + assert_eq!(a.into_inner(), (inner_min / accuracy) * accuracy); + + // Cases where integer doesn't fit, so it saturates. + let a = $name::saturating_from_integer(inner_max / accuracy + 1); + assert_eq!(a.into_inner(), inner_max); + + let a = $name::saturating_from_integer((inner_min / accuracy).saturating_sub(1)); + assert_eq!(a.into_inner(), inner_min); + } + + #[test] + fn checked_from_integer_works() { + let inner_max = <$name as FixedPointNumber>::Inner::max_value(); + let inner_min = <$name as FixedPointNumber>::Inner::min_value(); + let accuracy = $name::accuracy(); + + // Case where integer fits. + let a = $name::checked_from_integer(42) + .expect("42 * accuracy <= inner_max; qed"); + assert_eq!(a.into_inner(), 42 * accuracy); + + // Max integer that fit. + let a = $name::checked_from_integer(inner_max / accuracy) + .expect("(inner_max / accuracy) * accuracy <= inner_max; qed"); + assert_eq!(a.into_inner(), (inner_max / accuracy) * accuracy); + + // Case where integer doesn't fit, so it returns `None`. + let a = $name::checked_from_integer(inner_max / accuracy + 1); + assert_eq!(a, None); + + if $name::SIGNED { + // Case where integer fits. + let a = $name::checked_from_integer(0.saturating_sub(42)) + .expect("-42 * accuracy >= inner_min; qed"); + assert_eq!(a.into_inner(), 0 - 42 * accuracy); + + // Min integer that fit. + let a = $name::checked_from_integer(inner_min / accuracy) + .expect("(inner_min / accuracy) * accuracy <= inner_min; qed"); + assert_eq!(a.into_inner(), (inner_min / accuracy) * accuracy); + + // Case where integer doesn't fit, so it returns `None`. + let a = $name::checked_from_integer(inner_min / accuracy - 1); + assert_eq!(a, None); + } + } + + #[test] + fn from_inner_works() { + let inner_max = <$name as FixedPointNumber>::Inner::max_value(); + let inner_min = <$name as FixedPointNumber>::Inner::min_value(); + + assert_eq!(max(), $name::from_inner(inner_max)); + assert_eq!(min(), $name::from_inner(inner_min)); + } + + #[test] + #[should_panic(expected = "attempt to divide by zero")] + fn saturating_from_rational_panics_on_zero_divisor() { + let _ = $name::saturating_from_rational(1, 0); + } + + #[test] + fn saturating_from_rational_works() { + let inner_max = <$name as FixedPointNumber>::Inner::max_value(); + let inner_min = <$name as FixedPointNumber>::Inner::min_value(); + let accuracy = $name::accuracy(); + + let a = $name::saturating_from_rational(5, 2); + + // Positive case: 2.5 + assert_eq!(a.into_inner(), 25 * accuracy / 10); + + // Max - 1. + let a = $name::saturating_from_rational(inner_max - 1, accuracy); + assert_eq!(a.into_inner(), inner_max - 1); + + // Min + 1. + let a = $name::saturating_from_rational(inner_min + 1, accuracy); + assert_eq!(a.into_inner(), inner_min + 1); + + // Max. + let a = $name::saturating_from_rational(inner_max, accuracy); + assert_eq!(a.into_inner(), inner_max); + + // Min. + let a = $name::saturating_from_rational(inner_min, accuracy); + assert_eq!(a.into_inner(), inner_min); + + // Zero. + let a = $name::saturating_from_rational(0, 1); + assert_eq!(a.into_inner(), 0); + + if $name::SIGNED { + // Negative case: -2.5 + let a = $name::saturating_from_rational(-5, 2); + assert_eq!(a.into_inner(), 0 - 25 * accuracy / 10); + + // Other negative case: -2.5 + let a = $name::saturating_from_rational(5, -2); + assert_eq!(a.into_inner(), 0 - 25 * accuracy / 10); + + // Other positive case: 2.5 + let a = $name::saturating_from_rational(-5, -2); + assert_eq!(a.into_inner(), 25 * accuracy / 10); + + // Max + 1, saturates. + let a = $name::saturating_from_rational(inner_max as u128 + 1, accuracy); + assert_eq!(a.into_inner(), inner_max); + + // Min - 1, saturates. + let a = $name::saturating_from_rational(inner_max as u128 + 2, 0 - accuracy); + assert_eq!(a.into_inner(), inner_min); + + let a = $name::saturating_from_rational(inner_max, 0 - accuracy); + assert_eq!(a.into_inner(), 0 - inner_max); + + let a = $name::saturating_from_rational(inner_min, 0 - accuracy); + assert_eq!(a.into_inner(), inner_max); + + let a = $name::saturating_from_rational(inner_min + 1, 0 - accuracy); + assert_eq!(a.into_inner(), inner_max); + + let a = $name::saturating_from_rational(inner_min, 0 - 1); + assert_eq!(a.into_inner(), inner_max); + + let a = $name::saturating_from_rational(inner_max, 0 - 1); + assert_eq!(a.into_inner(), inner_min); + + let a = $name::saturating_from_rational(inner_max, 0 - inner_max); + assert_eq!(a.into_inner(), 0 - accuracy); + + let a = $name::saturating_from_rational(0 - inner_max, inner_max); + assert_eq!(a.into_inner(), 0 - accuracy); + + let a = $name::saturating_from_rational(inner_max, 0 - 3 * accuracy); + assert_eq!(a.into_inner(), 0 - inner_max / 3); + + let a = $name::saturating_from_rational(inner_min, 0 - accuracy / 3); + assert_eq!(a.into_inner(), inner_max); + + let a = $name::saturating_from_rational(1, 0 - accuracy); + assert_eq!(a.into_inner(), 0.saturating_sub(1)); + + let a = $name::saturating_from_rational(inner_min, inner_min); + assert_eq!(a.into_inner(), accuracy); + + // Out of accuracy. + let a = $name::saturating_from_rational(1, 0 - accuracy - 1); + assert_eq!(a.into_inner(), 0); + } + + let a = $name::saturating_from_rational(inner_max - 1, accuracy); + assert_eq!(a.into_inner(), inner_max - 1); + + let a = $name::saturating_from_rational(inner_min + 1, accuracy); + assert_eq!(a.into_inner(), inner_min + 1); + + let a = $name::saturating_from_rational(inner_max, 1); + assert_eq!(a.into_inner(), inner_max); + + let a = $name::saturating_from_rational(inner_min, 1); + assert_eq!(a.into_inner(), inner_min); + + let a = $name::saturating_from_rational(inner_max, inner_max); + assert_eq!(a.into_inner(), accuracy); + + let a = $name::saturating_from_rational(inner_max, 3 * accuracy); + assert_eq!(a.into_inner(), inner_max / 3); + + let a = $name::saturating_from_rational(inner_min, 2 * accuracy); + assert_eq!(a.into_inner(), inner_min / 2); + + let a = $name::saturating_from_rational(inner_min, accuracy / 3); + assert_eq!(a.into_inner(), inner_min); + + let a = $name::saturating_from_rational(1, accuracy); + assert_eq!(a.into_inner(), 1); + + // Out of accuracy. + let a = $name::saturating_from_rational(1, accuracy + 1); + assert_eq!(a.into_inner(), 0); + } + + #[test] + fn checked_from_rational_works() { + let inner_max = <$name as FixedPointNumber>::Inner::max_value(); + let inner_min = <$name as FixedPointNumber>::Inner::min_value(); + let accuracy = $name::accuracy(); + + // Divide by zero => None. + let a = $name::checked_from_rational(1, 0); + assert_eq!(a, None); + + // Max - 1. + let a = $name::checked_from_rational(inner_max - 1, accuracy).unwrap(); + assert_eq!(a.into_inner(), inner_max - 1); + + // Min + 1. + let a = $name::checked_from_rational(inner_min + 1, accuracy).unwrap(); + assert_eq!(a.into_inner(), inner_min + 1); + + // Max. + let a = $name::checked_from_rational(inner_max, accuracy).unwrap(); + assert_eq!(a.into_inner(), inner_max); + + // Min. + let a = $name::checked_from_rational(inner_min, accuracy).unwrap(); + assert_eq!(a.into_inner(), inner_min); + + // Max + 1 => Overflow => None. + let a = $name::checked_from_rational(inner_min, 0.saturating_sub(accuracy)); + assert_eq!(a, None); + + if $name::SIGNED { + // Min - 1 => Underflow => None. + let a = $name::checked_from_rational(inner_max as u128 + 2, 0.saturating_sub(accuracy)); + assert_eq!(a, None); + + let a = $name::checked_from_rational(inner_max, 0 - 3 * accuracy).unwrap(); + assert_eq!(a.into_inner(), 0 - inner_max / 3); + + let a = $name::checked_from_rational(inner_min, 0 - accuracy / 3); + assert_eq!(a, None); + + let a = $name::checked_from_rational(1, 0 - accuracy).unwrap(); + assert_eq!(a.into_inner(), 0.saturating_sub(1)); + + let a = $name::checked_from_rational(1, 0 - accuracy - 1).unwrap(); + assert_eq!(a.into_inner(), 0); + + let a = $name::checked_from_rational(inner_min, accuracy / 3); + assert_eq!(a, None); + } + + let a = $name::checked_from_rational(inner_max, 3 * accuracy).unwrap(); + assert_eq!(a.into_inner(), inner_max / 3); + + let a = $name::checked_from_rational(inner_min, 2 * accuracy).unwrap(); + assert_eq!(a.into_inner(), inner_min / 2); + + let a = $name::checked_from_rational(1, accuracy).unwrap(); + assert_eq!(a.into_inner(), 1); + + let a = $name::checked_from_rational(1, accuracy + 1).unwrap(); + assert_eq!(a.into_inner(), 0); + } + + #[test] + fn checked_mul_int_works() { + let a = $name::saturating_from_integer(2); + // Max - 1. + assert_eq!(a.checked_mul_int((i128::max_value() - 1) / 2), Some(i128::max_value() - 1)); + // Max. + assert_eq!(a.checked_mul_int(i128::max_value() / 2), Some(i128::max_value() - 1)); + // Max + 1 => None. + assert_eq!(a.checked_mul_int(i128::max_value() / 2 + 1), None); + + if $name::SIGNED { + // Min - 1. + assert_eq!(a.checked_mul_int((i128::min_value() + 1) / 2), Some(i128::min_value() + 2)); + // Min. + assert_eq!(a.checked_mul_int(i128::min_value() / 2), Some(i128::min_value())); + // Min + 1 => None. + assert_eq!(a.checked_mul_int(i128::min_value() / 2 - 1), None); + + let b = $name::saturating_from_rational(1, -2); + assert_eq!(b.checked_mul_int(42i128), Some(-21)); + assert_eq!(b.checked_mul_int(u128::max_value()), None); + assert_eq!(b.checked_mul_int(i128::max_value()), Some(i128::max_value() / -2)); + assert_eq!(b.checked_mul_int(i128::min_value()), Some(i128::min_value() / -2)); + } + + let a = $name::saturating_from_rational(1, 2); + assert_eq!(a.checked_mul_int(42i128), Some(21)); + assert_eq!(a.checked_mul_int(i128::max_value()), Some(i128::max_value() / 2)); + assert_eq!(a.checked_mul_int(i128::min_value()), Some(i128::min_value() / 2)); + + let c = $name::saturating_from_integer(255); + assert_eq!(c.checked_mul_int(2i8), None); + assert_eq!(c.checked_mul_int(2i128), Some(510)); + assert_eq!(c.checked_mul_int(i128::max_value()), None); + assert_eq!(c.checked_mul_int(i128::min_value()), None); + } + + #[test] + fn saturating_mul_int_works() { + let a = $name::saturating_from_integer(2); + // Max - 1. + assert_eq!(a.saturating_mul_int((i128::max_value() - 1) / 2), i128::max_value() - 1); + // Max. + assert_eq!(a.saturating_mul_int(i128::max_value() / 2), i128::max_value() - 1); + // Max + 1 => saturates to max. + assert_eq!(a.saturating_mul_int(i128::max_value() / 2 + 1), i128::max_value()); + + // Min - 1. + assert_eq!(a.saturating_mul_int((i128::min_value() + 1) / 2), i128::min_value() + 2); + // Min. + assert_eq!(a.saturating_mul_int(i128::min_value() / 2), i128::min_value()); + // Min + 1 => saturates to min. + assert_eq!(a.saturating_mul_int(i128::min_value() / 2 - 1), i128::min_value()); + + if $name::SIGNED { + let b = $name::saturating_from_rational(1, -2); + assert_eq!(b.saturating_mul_int(42i32), -21); + assert_eq!(b.saturating_mul_int(i128::max_value()), i128::max_value() / -2); + assert_eq!(b.saturating_mul_int(i128::min_value()), i128::min_value() / -2); + assert_eq!(b.saturating_mul_int(u128::max_value()), u128::min_value()); + } + + let a = $name::saturating_from_rational(1, 2); + assert_eq!(a.saturating_mul_int(42i32), 21); + assert_eq!(a.saturating_mul_int(i128::max_value()), i128::max_value() / 2); + assert_eq!(a.saturating_mul_int(i128::min_value()), i128::min_value() / 2); + + let c = $name::saturating_from_integer(255); + assert_eq!(c.saturating_mul_int(2i8), i8::max_value()); + assert_eq!(c.saturating_mul_int(-2i8), i8::min_value()); + assert_eq!(c.saturating_mul_int(i128::max_value()), i128::max_value()); + assert_eq!(c.saturating_mul_int(i128::min_value()), i128::min_value()); + } + + #[test] + fn checked_mul_works() { + let inner_max = <$name as FixedPointNumber>::Inner::max_value(); + let inner_min = <$name as FixedPointNumber>::Inner::min_value(); + + let a = $name::saturating_from_integer(2); + + // Max - 1. + let b = $name::from_inner(inner_max - 1); + assert_eq!(a.checked_mul(&(b/2.into())), Some(b)); + + // Max. + let c = $name::from_inner(inner_max); + assert_eq!(a.checked_mul(&(c/2.into())), Some(b)); + + // Max + 1 => None. + let e = $name::from_inner(1); + assert_eq!(a.checked_mul(&(c/2.into()+e)), None); + + if $name::SIGNED { + // Min + 1. + let b = $name::from_inner(inner_min + 1) / 2.into(); + let c = $name::from_inner(inner_min + 2); + assert_eq!(a.checked_mul(&b), Some(c)); + + // Min. + let b = $name::from_inner(inner_min) / 2.into(); + let c = $name::from_inner(inner_min); + assert_eq!(a.checked_mul(&b), Some(c)); + + // Min - 1 => None. + let b = $name::from_inner(inner_min) / 2.into() - $name::from_inner(1); + assert_eq!(a.checked_mul(&b), None); + + let c = $name::saturating_from_integer(255); + let b = $name::saturating_from_rational(1, -2); + + assert_eq!(b.checked_mul(&42.into()), Some(0.saturating_sub(21).into())); + assert_eq!(b.checked_mul(&$name::max_value()), $name::max_value().checked_div(&0.saturating_sub(2).into())); + assert_eq!(b.checked_mul(&$name::min_value()), $name::min_value().checked_div(&0.saturating_sub(2).into())); + assert_eq!(c.checked_mul(&$name::min_value()), None); + } + + let a = $name::saturating_from_rational(1, 2); + let c = $name::saturating_from_integer(255); + + assert_eq!(a.checked_mul(&42.into()), Some(21.into())); + assert_eq!(c.checked_mul(&2.into()), Some(510.into())); + assert_eq!(c.checked_mul(&$name::max_value()), None); + assert_eq!(a.checked_mul(&$name::max_value()), $name::max_value().checked_div(&2.into())); + assert_eq!(a.checked_mul(&$name::min_value()), $name::min_value().checked_div(&2.into())); + } + + #[test] + fn checked_div_int_works() { + let inner_max = <$name as FixedPointNumber>::Inner::max_value(); + let inner_min = <$name as FixedPointNumber>::Inner::min_value(); + let accuracy = $name::accuracy(); + + let a = $name::from_inner(inner_max); + let b = $name::from_inner(inner_min); + let c = $name::zero(); + let d = $name::one(); + let e = $name::saturating_from_integer(6); + let f = $name::saturating_from_integer(5); + + assert_eq!(e.checked_div_int(2.into()), Some(3)); + assert_eq!(f.checked_div_int(2.into()), Some(2)); + + assert_eq!(a.checked_div_int(i128::max_value()), Some(0)); + assert_eq!(a.checked_div_int(2), Some(inner_max / (2 * accuracy))); + assert_eq!(a.checked_div_int(inner_max / accuracy), Some(1)); + assert_eq!(a.checked_div_int(1i8), None); + + if b < c { + // Not executed by unsigned inners. + assert_eq!(a.checked_div_int(0.saturating_sub(2)), Some(0.saturating_sub(inner_max / (2 * accuracy)))); + assert_eq!(a.checked_div_int(0.saturating_sub(inner_max / accuracy)), Some(0.saturating_sub(1))); + assert_eq!(b.checked_div_int(i128::min_value()), Some(0)); + assert_eq!(b.checked_div_int(inner_min / accuracy), Some(1)); + assert_eq!(b.checked_div_int(1i8), None); + assert_eq!(b.checked_div_int(0.saturating_sub(2)), Some(0.saturating_sub(inner_min / (2 * accuracy)))); + assert_eq!(b.checked_div_int(0.saturating_sub(inner_min / accuracy)), Some(0.saturating_sub(1))); + assert_eq!(c.checked_div_int(i128::min_value()), Some(0)); + assert_eq!(d.checked_div_int(i32::min_value()), Some(0)); + } + + assert_eq!(b.checked_div_int(2), Some(inner_min / (2 * accuracy))); + + assert_eq!(c.checked_div_int(1), Some(0)); + assert_eq!(c.checked_div_int(i128::max_value()), Some(0)); + assert_eq!(c.checked_div_int(1i8), Some(0)); + + assert_eq!(d.checked_div_int(1), Some(1)); + assert_eq!(d.checked_div_int(i32::max_value()), Some(0)); + assert_eq!(d.checked_div_int(1i8), Some(1)); + + assert_eq!(a.checked_div_int(0), None); + assert_eq!(b.checked_div_int(0), None); + assert_eq!(c.checked_div_int(0), None); + assert_eq!(d.checked_div_int(0), None); + } + + #[test] + #[should_panic(expected = "attempt to divide by zero")] + fn saturating_div_int_panics_when_divisor_is_zero() { + let _ = $name::one().saturating_div_int(0); + } + + #[test] + fn saturating_div_int_works() { + let inner_max = <$name as FixedPointNumber>::Inner::max_value(); + let inner_min = <$name as FixedPointNumber>::Inner::min_value(); + let accuracy = $name::accuracy(); + + let a = $name::saturating_from_integer(5); + assert_eq!(a.saturating_div_int(2), 2); + + let a = $name::min_value(); + assert_eq!(a.saturating_div_int(1i128), (inner_min / accuracy) as i128); + + if $name::SIGNED { + let a = $name::saturating_from_integer(5); + assert_eq!(a.saturating_div_int(-2), -2); + + let a = $name::min_value(); + assert_eq!(a.saturating_div_int(-1i128), (inner_max / accuracy) as i128); + } + } + + #[test] + fn saturating_abs_works() { + let inner_max = <$name as FixedPointNumber>::Inner::max_value(); + let inner_min = <$name as FixedPointNumber>::Inner::min_value(); + + assert_eq!($name::from_inner(inner_max).saturating_abs(), $name::max_value()); + assert_eq!($name::zero().saturating_abs(), 0.into()); + + if $name::SIGNED { + assert_eq!($name::from_inner(inner_min).saturating_abs(), $name::max_value()); + assert_eq!($name::saturating_from_rational(-1, 2).saturating_abs(), (1, 2).into()); + } + } + + #[test] + fn saturating_mul_acc_int_works() { + assert_eq!($name::zero().saturating_mul_acc_int(42i8), 42i8); + assert_eq!($name::one().saturating_mul_acc_int(42i8), 2 * 42i8); + + assert_eq!($name::one().saturating_mul_acc_int(i128::max_value()), i128::max_value()); + assert_eq!($name::one().saturating_mul_acc_int(i128::min_value()), i128::min_value()); + + assert_eq!($name::one().saturating_mul_acc_int(u128::max_value() / 2), u128::max_value() - 1); + assert_eq!($name::one().saturating_mul_acc_int(u128::min_value()), u128::min_value()); + + if $name::SIGNED { + let a = $name::saturating_from_rational(-1, 2); + assert_eq!(a.saturating_mul_acc_int(42i8), 21i8); + assert_eq!(a.saturating_mul_acc_int(42u8), 21u8); + assert_eq!(a.saturating_mul_acc_int(u128::max_value() - 1), u128::max_value() / 2); + } + } + + #[test] + fn saturating_pow_should_work() { + assert_eq!($name::saturating_from_integer(2).saturating_pow(0), $name::saturating_from_integer(1)); + assert_eq!($name::saturating_from_integer(2).saturating_pow(1), $name::saturating_from_integer(2)); + assert_eq!($name::saturating_from_integer(2).saturating_pow(2), $name::saturating_from_integer(4)); + assert_eq!($name::saturating_from_integer(2).saturating_pow(3), $name::saturating_from_integer(8)); + assert_eq!($name::saturating_from_integer(2).saturating_pow(50), + $name::saturating_from_integer(1125899906842624i64)); + + assert_eq!($name::saturating_from_integer(1).saturating_pow(1000), (1).into()); + assert_eq!($name::saturating_from_integer(1).saturating_pow(usize::max_value()), (1).into()); + + if $name::SIGNED { + // Saturating. + assert_eq!($name::saturating_from_integer(2).saturating_pow(68), $name::max_value()); + + assert_eq!($name::saturating_from_integer(-1).saturating_pow(1000), (1).into()); + assert_eq!($name::saturating_from_integer(-1).saturating_pow(1001), 0.saturating_sub(1).into()); + assert_eq!($name::saturating_from_integer(-1).saturating_pow(usize::max_value()), 0.saturating_sub(1).into()); + assert_eq!($name::saturating_from_integer(-1).saturating_pow(usize::max_value() - 1), (1).into()); + } + + assert_eq!($name::saturating_from_integer(114209).saturating_pow(5), $name::max_value()); + + assert_eq!($name::saturating_from_integer(1).saturating_pow(usize::max_value()), (1).into()); + assert_eq!($name::saturating_from_integer(0).saturating_pow(usize::max_value()), (0).into()); + assert_eq!($name::saturating_from_integer(2).saturating_pow(usize::max_value()), $name::max_value()); + } + + #[test] + fn checked_div_works() { + let inner_max = <$name as FixedPointNumber>::Inner::max_value(); + let inner_min = <$name as FixedPointNumber>::Inner::min_value(); + + let a = $name::from_inner(inner_max); + let b = $name::from_inner(inner_min); + let c = $name::zero(); + let d = $name::one(); + let e = $name::saturating_from_integer(6); + let f = $name::saturating_from_integer(5); + + assert_eq!(e.checked_div(&2.into()), Some(3.into())); + assert_eq!(f.checked_div(&2.into()), Some((5, 2).into())); + + assert_eq!(a.checked_div(&inner_max.into()), Some(1.into())); + assert_eq!(a.checked_div(&2.into()), Some($name::from_inner(inner_max / 2))); + assert_eq!(a.checked_div(&$name::max_value()), Some(1.into())); + assert_eq!(a.checked_div(&d), Some(a)); + + if b < c { + // Not executed by unsigned inners. + assert_eq!(a.checked_div(&0.saturating_sub(2).into()), Some($name::from_inner(0.saturating_sub(inner_max / 2)))); + assert_eq!(a.checked_div(&-$name::max_value()), Some(0.saturating_sub(1).into())); + assert_eq!(b.checked_div(&0.saturating_sub(2).into()), Some($name::from_inner(0.saturating_sub(inner_min / 2)))); + assert_eq!(c.checked_div(&$name::max_value()), Some(0.into())); + assert_eq!(b.checked_div(&b), Some($name::one())); + } + + assert_eq!(b.checked_div(&2.into()), Some($name::from_inner(inner_min / 2))); + assert_eq!(b.checked_div(&a), Some(0.saturating_sub(1).into())); + assert_eq!(c.checked_div(&1.into()), Some(0.into())); + assert_eq!(d.checked_div(&1.into()), Some(1.into())); + + assert_eq!(a.checked_div(&$name::one()), Some(a)); + assert_eq!(b.checked_div(&$name::one()), Some(b)); + assert_eq!(c.checked_div(&$name::one()), Some(c)); + assert_eq!(d.checked_div(&$name::one()), Some(d)); + + assert_eq!(a.checked_div(&$name::zero()), None); + assert_eq!(b.checked_div(&$name::zero()), None); + assert_eq!(c.checked_div(&$name::zero()), None); + assert_eq!(d.checked_div(&$name::zero()), None); + } + + #[test] + fn is_positive_negative_works() { + let one = $name::one(); + assert!(one.is_positive()); + assert!(!one.is_negative()); + + let zero = $name::zero(); + assert!(!zero.is_positive()); + assert!(!zero.is_negative()); + + if $signed { + let minus_one = $name::saturating_from_integer(-1); + assert!(minus_one.is_negative()); + assert!(!minus_one.is_positive()); + } + } + + #[test] + fn trunc_works() { + let n = $name::saturating_from_rational(5, 2).trunc(); + assert_eq!(n, $name::saturating_from_integer(2)); + + if $name::SIGNED { + let n = $name::saturating_from_rational(-5, 2).trunc(); + assert_eq!(n, $name::saturating_from_integer(-2)); + } + } + + #[test] + fn frac_works() { + let n = $name::saturating_from_rational(5, 2); + let i = n.trunc(); + let f = n.frac(); + + assert_eq!(n, i + f); + + let n = $name::saturating_from_rational(5, 2) + .frac() + .saturating_mul(10.into()); + assert_eq!(n, 5.into()); + + let n = $name::saturating_from_rational(1, 2) + .frac() + .saturating_mul(10.into()); + assert_eq!(n, 5.into()); + + if $name::SIGNED { + let n = $name::saturating_from_rational(-5, 2); + let i = n.trunc(); + let f = n.frac(); + assert_eq!(n, i - f); + + // The sign is attached to the integer part unless it is zero. + let n = $name::saturating_from_rational(-5, 2) + .frac() + .saturating_mul(10.into()); + assert_eq!(n, 5.into()); + + let n = $name::saturating_from_rational(-1, 2) + .frac() + .saturating_mul(10.into()); + assert_eq!(n, 0.saturating_sub(5).into()); + } + } + + #[test] + fn ceil_works() { + let n = $name::saturating_from_rational(5, 2); + assert_eq!(n.ceil(), 3.into()); + + let n = $name::saturating_from_rational(-5, 2); + assert_eq!(n.ceil(), 0.saturating_sub(2).into()); + + // On the limits: + let n = $name::max_value(); + assert_eq!(n.ceil(), n.trunc()); + + let n = $name::min_value(); + assert_eq!(n.ceil(), n.trunc()); + } + + #[test] + fn floor_works() { + let n = $name::saturating_from_rational(5, 2); + assert_eq!(n.floor(), 2.into()); + + let n = $name::saturating_from_rational(-5, 2); + assert_eq!(n.floor(), 0.saturating_sub(3).into()); + + // On the limits: + let n = $name::max_value(); + assert_eq!(n.floor(), n.trunc()); + + let n = $name::min_value(); + assert_eq!(n.floor(), n.trunc()); + } + + #[test] + fn round_works() { + let n = $name::zero(); + assert_eq!(n.round(), n); + + let n = $name::one(); + assert_eq!(n.round(), n); + + let n = $name::saturating_from_rational(5, 2); + assert_eq!(n.round(), 3.into()); + + let n = $name::saturating_from_rational(-5, 2); + assert_eq!(n.round(), 0.saturating_sub(3).into()); + + // Saturating: + let n = $name::max_value(); + assert_eq!(n.round(), n.trunc()); + + let n = $name::min_value(); + assert_eq!(n.round(), n.trunc()); + + // On the limit: + + // floor(max - 1) + 0.33.. + let n = $name::max_value() + .saturating_sub(1.into()) + .trunc() + .saturating_add((1, 3).into()); + + assert_eq!(n.round(), ($name::max_value() - 1.into()).trunc()); + + // floor(max - 1) + 0.5 + let n = $name::max_value() + .saturating_sub(1.into()) + .trunc() + .saturating_add((1, 2).into()); + + assert_eq!(n.round(), $name::max_value().trunc()); + + if $name::SIGNED { + // floor(min + 1) - 0.33.. + let n = $name::min_value() + .saturating_add(1.into()) + .trunc() + .saturating_sub((1, 3).into()); + + assert_eq!(n.round(), ($name::min_value() + 1.into()).trunc()); + + // floor(min + 1) - 0.5 + let n = $name::min_value() + .saturating_add(1.into()) + .trunc() + .saturating_sub((1, 2).into()); + + assert_eq!(n.round(), $name::min_value().trunc()); + } + } + + #[test] + fn perthing_into_works() { + let ten_percent_percent: $name = Percent::from_percent(10).into(); + assert_eq!(ten_percent_percent.into_inner(), $name::accuracy() / 10); + + let ten_percent_permill: $name = Permill::from_percent(10).into(); + assert_eq!(ten_percent_permill.into_inner(), $name::accuracy() / 10); + + let ten_percent_perbill: $name = Perbill::from_percent(10).into(); + assert_eq!(ten_percent_perbill.into_inner(), $name::accuracy() / 10); + + let ten_percent_perquintill: $name = Perquintill::from_percent(10).into(); + assert_eq!(ten_percent_perquintill.into_inner(), $name::accuracy() / 10); + } + + #[test] + fn fmt_should_work() { + let zero = $name::zero(); + assert_eq!(format!("{:?}", zero), format!("{}(0.{:0>weight$})", stringify!($name), 0, weight=precision())); + + let one = $name::one(); + assert_eq!(format!("{:?}", one), format!("{}(1.{:0>weight$})", stringify!($name), 0, weight=precision())); + + let frac = $name::saturating_from_rational(1, 2); + assert_eq!(format!("{:?}", frac), format!("{}(0.{:0weight$})", stringify!($name), 0, weight=precision())); + + let frac = $name::saturating_from_rational(-314, 100); + assert_eq!(format!("{:?}", frac), format!("{}(-3.{:0. +// 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. //! Some helper functions to work with 128bit numbers. Note that the functionality provided here is //! only sensible to use with 128bit numbers because for smaller sizes, you can always rely on diff --git a/primitives/arithmetic/src/lib.rs b/primitives/arithmetic/src/lib.rs index fb70b13a15312b4cee434c6dc9a58ef234bad444..e54c6c833d141f5b120c95d26a37ac408addb319 100644 --- a/primitives/arithmetic/src/lib.rs +++ b/primitives/arithmetic/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Minimal fixed point arithmetic primitives and types for runtime. @@ -36,23 +37,472 @@ pub mod biguint; pub mod helpers_128bit; pub mod traits; mod per_things; -mod fixed64; -mod fixed128; +mod fixed_point; mod rational128; -pub use fixed64::Fixed64; -pub use fixed128::Fixed128; -pub use per_things::{PerThing, Percent, PerU16, Permill, Perbill, Perquintill}; +pub use fixed_point::{FixedPointNumber, FixedPointOperand, FixedI64, FixedI128, FixedU128}; +pub use per_things::{PerThing, InnerOf, UpperOf, Percent, PerU16, Permill, Perbill, Perquintill}; pub use rational128::Rational128; +use sp_std::{prelude::*, cmp::Ordering, fmt::Debug, convert::TryInto}; +use traits::{BaseArithmetic, One, Zero, SaturatedConversion, Unsigned}; + +/// Trait for comparing two numbers with an threshold. +/// +/// Returns: +/// - `Ordering::Greater` if `self` is greater than `other + threshold`. +/// - `Ordering::Less` if `self` is less than `other - threshold`. +/// - `Ordering::Equal` otherwise. +pub trait ThresholdOrd { + /// Compare if `self` is `threshold` greater or less than `other`. + fn tcmp(&self, other: &T, epsilon: T) -> Ordering; +} + +impl ThresholdOrd for T +where + T: Ord + PartialOrd + Copy + Clone + traits::Zero + traits::Saturating, +{ + fn tcmp(&self, other: &T, threshold: T) -> Ordering { + // early exit. + if threshold.is_zero() { + return self.cmp(&other) + } + + let upper_bound = other.saturating_add(threshold); + let lower_bound = other.saturating_sub(threshold); + + if upper_bound <= lower_bound { + // defensive only. Can never happen. + self.cmp(&other) + } else { + // upper_bound is guaranteed now to be bigger than lower. + match (self.cmp(&lower_bound), self.cmp(&upper_bound)) { + (Ordering::Greater, Ordering::Greater) => Ordering::Greater, + (Ordering::Less, Ordering::Less) => Ordering::Less, + _ => Ordering::Equal, + } + } + + } +} + +/// A collection-like object that is made of values of type `T` and can normalize its individual +/// values around a centric point. +/// +/// Note that the order of items in the collection may affect the result. +pub trait Normalizable { + /// Normalize self around `targeted_sum`. + /// + /// Only returns `Ok` if the new sum of results is guaranteed to be equal to `targeted_sum`. + /// Else, returns an error explaining why it failed to do so. + fn normalize(&self, targeted_sum: T) -> Result, &'static str>; +} + +macro_rules! impl_normalize_for_numeric { + ($($numeric:ty),*) => { + $( + impl Normalizable<$numeric> for Vec<$numeric> { + fn normalize(&self, targeted_sum: $numeric) -> Result, &'static str> { + normalize(self.as_ref(), targeted_sum) + } + } + )* + }; +} + +impl_normalize_for_numeric!(u8, u16, u32, u64, u128); + +impl Normalizable

for Vec

{ + fn normalize(&self, targeted_sum: P) -> Result, &'static str> { + let inners = self.iter().map(|p| p.clone().deconstruct().into()).collect::>(); + let normalized = normalize(inners.as_ref(), targeted_sum.deconstruct().into())?; + Ok(normalized.into_iter().map(|i: UpperOf

| P::from_parts(i.saturated_into())).collect()) + } +} + + +/// Normalize `input` so that the sum of all elements reaches `targeted_sum`. +/// +/// This implementation is currently in a balanced position between being performant and accurate. +/// +/// 1. We prefer storing original indices, and sorting the `input` only once. This will save the +/// cost of sorting per round at the cost of a little bit of memory. +/// 2. The granularity of increment/decrements is determined by the number of elements in `input` +/// and their sum difference with `targeted_sum`, namely `diff = diff(sum(input), target_sum)`. +/// This value is then distributed into `per_round = diff / input.len()` and `leftover = diff % +/// round`. First, per_round is applied to all elements of input, and then we move to leftover, +/// in which case we add/subtract 1 by 1 until `leftover` is depleted. +/// +/// When the sum is less than the target, the above approach always holds. In this case, then each +/// individual element is also less than target. Thus, by adding `per_round` to each item, neither +/// of them can overflow the numeric bound of `T`. In fact, neither of the can go beyond +/// `target_sum`*. +/// +/// If sum is more than target, there is small twist. The subtraction of `per_round` +/// form each element might go below zero. In this case, we saturate and add the error to the +/// `leftover` value. This ensures that the result will always stay accurate, yet it might cause the +/// execution to become increasingly slow, since leftovers are applied one by one. +/// +/// All in all, the complicated case above is rare to happen in all substrate use cases, hence we +/// opt for it due to its simplicity. +/// +/// This function will return an error is if length of `input` cannot fit in `T`, or if `sum(input)` +/// cannot fit inside `T`. +/// +/// * This proof is used in the implementation as well. +pub fn normalize(input: &[T], targeted_sum: T) -> Result, &'static str> + where T: Clone + Copy + Ord + BaseArithmetic + Unsigned + Debug, +{ + // compute sum and return error if failed. + let mut sum = T::zero(); + for t in input.iter() { + sum = sum.checked_add(t).ok_or("sum of input cannot fit in `T`")?; + } + + // convert count and return error if failed. + let count = input.len(); + let count_t: T = count.try_into().map_err(|_| "length of `inputs` cannot fit in `T`")?; + + // Nothing to do here. + if count.is_zero() { + return Ok(Vec::::new()); + } + + let diff = targeted_sum.max(sum) - targeted_sum.min(sum); + if diff.is_zero() { + return Ok(input.to_vec()); + } + + let needs_bump = targeted_sum > sum; + let per_round = diff / count_t; + let mut leftover = diff % count_t; + + // sort output once based on diff. This will require more data transfer and saving original + // index, but we sort only twice instead: once now and once at the very end. + let mut output_with_idx = input.iter().cloned().enumerate().collect::>(); + output_with_idx.sort_by_key(|x| x.1); + + if needs_bump { + // must increase the values a bit. Bump from the min element. Index of minimum is now zero + // because we did a sort. If at any point the min goes greater or equal the `max_threshold`, + // we move to the next minimum. + let mut min_index = 0; + // at this threshold we move to next index. + let threshold = targeted_sum / count_t; + + if !per_round.is_zero() { + for _ in 0..count { + output_with_idx[min_index].1 = output_with_idx[min_index].1 + .checked_add(&per_round) + .expect("Proof provided in the module doc; qed."); + if output_with_idx[min_index].1 >= threshold { + min_index += 1; + min_index = min_index % count; + } + } + } + + // continue with the previous min_index + while !leftover.is_zero() { + output_with_idx[min_index].1 = output_with_idx[min_index].1 + .checked_add(&T::one()) + .expect("Proof provided in the module doc; qed."); + if output_with_idx[min_index].1 >= threshold { + min_index += 1; + min_index = min_index % count; + } + leftover -= One::one() + } + } else { + // must decrease the stakes a bit. decrement from the max element. index of maximum is now + // last. if at any point the max goes less or equal the `min_threshold`, we move to the next + // maximum. + let mut max_index = count - 1; + // at this threshold we move to next index. + let threshold = output_with_idx + .first() + .expect("length of input is greater than zero; it must have a first; qed") + .1; + + if !per_round.is_zero() { + for _ in 0..count { + output_with_idx[max_index].1 = output_with_idx[max_index].1 + .checked_sub(&per_round) + .unwrap_or_else(|| { + let remainder = per_round - output_with_idx[max_index].1; + leftover += remainder; + output_with_idx[max_index].1.saturating_sub(per_round) + }); + if output_with_idx[max_index].1 <= threshold { + max_index = max_index.checked_sub(1).unwrap_or(count - 1); + } + } + } + + // continue with the previous max_index + while !leftover.is_zero() { + if let Some(next) = output_with_idx[max_index].1.checked_sub(&One::one()) { + output_with_idx[max_index].1 = next; + if output_with_idx[max_index].1 <= threshold { + max_index = max_index.checked_sub(1).unwrap_or(count - 1); + } + leftover -= One::one() + } else { + max_index = max_index.checked_sub(1).unwrap_or(count - 1); + } + } + } + + debug_assert_eq!( + output_with_idx.iter().fold(T::zero(), |acc, (_, x)| acc + *x), + targeted_sum, + "sum({:?}) != {:?}", + output_with_idx, + targeted_sum, + ); + + // sort again based on the original index. + output_with_idx.sort_by_key(|x| x.0); + Ok(output_with_idx.into_iter().map(|(_, t)| t).collect()) +} + #[cfg(test)] -mod tests { +mod normalize_tests { use super::*; + #[test] + fn work_for_all_types() { + macro_rules! test_for { + ($type:ty) => { + assert_eq!( + normalize(vec![8 as $type, 9, 7, 10].as_ref(), 40).unwrap(), + vec![10, 10, 10, 10], + ); + } + } + // it should work for all types as long as the length of vector can be converted to T. + test_for!(u128); + test_for!(u64); + test_for!(u32); + test_for!(u16); + test_for!(u8); + } + + #[test] + fn fails_on_if_input_sum_large() { + assert!(normalize(vec![1u8; 255].as_ref(), 10).is_ok()); + assert_eq!( + normalize(vec![1u8; 256].as_ref(), 10), + Err("sum of input cannot fit in `T`"), + ); + } + + #[test] + fn does_not_fail_on_subtraction_overflow() { + assert_eq!( + normalize(vec![1u8, 100, 100].as_ref(), 10).unwrap(), + vec![1, 9, 0], + ); + assert_eq!( + normalize(vec![1u8, 8, 9].as_ref(), 1).unwrap(), + vec![0, 1, 0], + ); + } + + #[test] + fn works_for_vec() { + assert_eq!(vec![8u32, 9, 7, 10].normalize(40).unwrap(), vec![10u32, 10, 10, 10]); + } + + #[test] + fn works_for_per_thing() { + assert_eq!( + vec![ + Perbill::from_percent(33), + Perbill::from_percent(33), + Perbill::from_percent(33) + ].normalize(Perbill::one()).unwrap(), + vec![ + Perbill::from_parts(333333334), + Perbill::from_parts(333333333), + Perbill::from_parts(333333333), + ] + ); + + assert_eq!( + vec![ + Perbill::from_percent(20), + Perbill::from_percent(15), + Perbill::from_percent(30) + ].normalize(Perbill::one()).unwrap(), + vec![ + Perbill::from_parts(316666668), + Perbill::from_parts(383333332), + Perbill::from_parts(300000000), + ] + ); + } + + #[test] + fn can_work_for_peru16() { + // Peru16 is a rather special case; since inner type is exactly the same as capacity, we + // could have a situation where the sum cannot be calculated in the inner type. Calculating + // using the upper type of the per_thing should assure this to be okay. + assert_eq!( + vec![ + PerU16::from_percent(40), + PerU16::from_percent(40), + PerU16::from_percent(40), + ].normalize(PerU16::one()).unwrap(), + vec![ + PerU16::from_parts(21845), // 33% + PerU16::from_parts(21845), // 33% + PerU16::from_parts(21845), // 33% + ] + ); + } + + #[test] + fn normalize_works_all_le() { + assert_eq!( + normalize(vec![8u32, 9, 7, 10].as_ref(), 40).unwrap(), + vec![10, 10, 10, 10], + ); + + assert_eq!( + normalize(vec![7u32, 7, 7, 7].as_ref(), 40).unwrap(), + vec![10, 10, 10, 10], + ); + + assert_eq!( + normalize(vec![7u32, 7, 7, 10].as_ref(), 40).unwrap(), + vec![11, 11, 8, 10], + ); + + assert_eq!( + normalize(vec![7u32, 8, 7, 10].as_ref(), 40).unwrap(), + vec![11, 8, 11, 10], + ); + + assert_eq!( + normalize(vec![7u32, 7, 8, 10].as_ref(), 40).unwrap(), + vec![11, 11, 8, 10], + ); + } + + #[test] + fn normalize_works_some_ge() { + assert_eq!( + normalize(vec![8u32, 11, 9, 10].as_ref(), 40).unwrap(), + vec![10, 11, 9, 10], + ); + } + + #[test] + fn always_inc_min() { + assert_eq!( + normalize(vec![10u32, 7, 10, 10].as_ref(), 40).unwrap(), + vec![10, 10, 10, 10], + ); + assert_eq!( + normalize(vec![10u32, 10, 7, 10].as_ref(), 40).unwrap(), + vec![10, 10, 10, 10], + ); + assert_eq!( + normalize(vec![10u32, 10, 10, 7].as_ref(), 40).unwrap(), + vec![10, 10, 10, 10], + ); + } + + #[test] + fn normalize_works_all_ge() { + assert_eq!( + normalize(vec![12u32, 11, 13, 10].as_ref(), 40).unwrap(), + vec![10, 10, 10, 10], + ); + + assert_eq!( + normalize(vec![13u32, 13, 13, 13].as_ref(), 40).unwrap(), + vec![10, 10, 10, 10], + ); + + assert_eq!( + normalize(vec![13u32, 13, 13, 10].as_ref(), 40).unwrap(), + vec![12, 9, 9, 10], + ); + + assert_eq!( + normalize(vec![13u32, 12, 13, 10].as_ref(), 40).unwrap(), + vec![9, 12, 9, 10], + ); + + assert_eq!( + normalize(vec![13u32, 13, 12, 10].as_ref(), 40).unwrap(), + vec![9, 9, 12, 10], + ); + } +} + +#[cfg(test)] +mod threshold_compare_tests { + use super::*; + use crate::traits::Saturating; + use sp_std::cmp::Ordering; + + #[test] + fn epsilon_ord_works() { + let b = 115u32; + let e = Perbill::from_percent(10).mul_ceil(b); + + // [115 - 11,5 (103,5), 115 + 11,5 (126,5)] is all equal + assert_eq!(103u32.tcmp(&b, e), Ordering::Equal); + assert_eq!(104u32.tcmp(&b, e), Ordering::Equal); + assert_eq!(115u32.tcmp(&b, e), Ordering::Equal); + assert_eq!(120u32.tcmp(&b, e), Ordering::Equal); + assert_eq!(126u32.tcmp(&b, e), Ordering::Equal); + assert_eq!(127u32.tcmp(&b, e), Ordering::Equal); + + assert_eq!(128u32.tcmp(&b, e), Ordering::Greater); + assert_eq!(102u32.tcmp(&b, e), Ordering::Less); + } + + #[test] + fn epsilon_ord_works_with_small_epc() { + let b = 115u32; + // way less than 1 percent. threshold will be zero. Result should be same as normal ord. + let e = Perbill::from_parts(100) * b; + + // [115 - 11,5 (103,5), 115 + 11,5 (126,5)] is all equal + assert_eq!(103u32.tcmp(&b, e), 103u32.cmp(&b)); + assert_eq!(104u32.tcmp(&b, e), 104u32.cmp(&b)); + assert_eq!(115u32.tcmp(&b, e), 115u32.cmp(&b)); + assert_eq!(120u32.tcmp(&b, e), 120u32.cmp(&b)); + assert_eq!(126u32.tcmp(&b, e), 126u32.cmp(&b)); + assert_eq!(127u32.tcmp(&b, e), 127u32.cmp(&b)); + + assert_eq!(128u32.tcmp(&b, e), 128u32.cmp(&b)); + assert_eq!(102u32.tcmp(&b, e), 102u32.cmp(&b)); + } + #[test] fn peru16_rational_does_not_overflow() { // A historical example that will panic only for per_thing type that are created with // maximum capacity of their type, e.g. PerU16. let _ = PerU16::from_rational_approximation(17424870u32, 17424870); } + + #[test] + fn saturating_mul_works() { + assert_eq!(Saturating::saturating_mul(2, i32::min_value()), i32::min_value()); + assert_eq!(Saturating::saturating_mul(2, i32::max_value()), i32::max_value()); + } + + #[test] + fn saturating_pow_works() { + assert_eq!(Saturating::saturating_pow(i32::min_value(), 0), 1); + assert_eq!(Saturating::saturating_pow(i32::max_value(), 0), 1); + assert_eq!(Saturating::saturating_pow(i32::min_value(), 3), i32::min_value()); + assert_eq!(Saturating::saturating_pow(i32::min_value(), 2), i32::max_value()); + assert_eq!(Saturating::saturating_pow(i32::max_value(), 2), i32::max_value()); + } } diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index 56fc562cd1a926cd3d33b8ccee48dabe6c13bb24..cf53988b33d31c4103714433c82a29d65eedd05e 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; @@ -20,21 +21,29 @@ use serde::{Serialize, Deserialize}; use sp_std::{ops, fmt, prelude::*, convert::TryInto}; use codec::{Encode, CompactAs}; use crate::traits::{ - SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, Bounded, Zero, + SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, Bounded, Zero, Unsigned, }; use sp_debug_derive::RuntimeDebug; +/// Get the inner type of a `PerThing`. +pub type InnerOf

=

::Inner; + +/// Get the upper type of a `PerThing`. +pub type UpperOf

=

=

::Hash; @@ -140,6 +140,8 @@ pub type BlockHash

= <

::Block as BlockT>::Hash; pub type TransactionFor

= <

::Block as BlockT>::Extrinsic; /// Type of transactions event stream for a pool. pub type TransactionStatusStreamFor

= TransactionStatusStream, BlockHash

>; +/// Transaction type for a local pool. +pub type LocalTransactionFor

= <

::Block as BlockT>::Extrinsic; /// Typical future type used in transaction pool api. pub type PoolFuture = std::pin::Pin> + Send>>; @@ -161,7 +163,7 @@ pub trait InPoolTransaction { /// Get priority of the transaction. fn priority(&self) -> &TransactionPriority; /// Get longevity of the transaction. - fn longevity(&self) ->&TransactionLongevity; + fn longevity(&self) -> &TransactionLongevity; /// Get transaction dependencies. fn requires(&self) -> &[TransactionTag]; /// Get tags that transaction provides. @@ -246,16 +248,14 @@ pub trait TransactionPool: Send + Sync { /// Events that the transaction pool listens for. pub enum ChainEvent { - /// New blocks have been added to the chain - NewBlock { - /// Is this the new best block. - is_new_best: bool, - /// Id of the just imported block. - id: BlockId, - /// Header of the just imported block - header: B::Header, - /// List of retracted blocks ordered by block number. - retracted: Vec, + /// New best block have been added to the chain + NewBestBlock { + /// Hash of the block. + hash: B::Hash, + /// Tree route from old best to new best parent that was calculated on import. + /// + /// If `None`, no re-org happened on import. + tree_route: Option>>, }, /// An existing block has been finalized. Finalized { @@ -270,6 +270,28 @@ pub trait MaintainedTransactionPool: TransactionPool { fn maintain(&self, event: ChainEvent) -> Pin + Send>>; } +/// Transaction pool interface for submitting local transactions that exposes a +/// blocking interface for submission. +pub trait LocalTransactionPool: Send + Sync { + /// Block type. + type Block: BlockT; + /// Transaction hash type. + type Hash: Hash + Eq + Member + Serialize; + /// Error type. + type Error: From + crate::error::IntoPoolError; + + /// Submits the given local unverified transaction to the pool blocking the + /// current thread for any necessary pre-verification. + /// NOTE: It MUST NOT be used for transactions that originate from the + /// network or RPC, since the validation is performed with + /// `TransactionSource::Local`. + fn submit_local( + &self, + at: &BlockId, + xt: LocalTransactionFor, + ) -> Result; +} + /// An abstraction for transaction pool. /// /// This trait is used by offchain calls to be able to submit transactions. @@ -288,7 +310,7 @@ pub trait OffchainSubmitTransaction: Send + Sync { ) -> Result<(), ()>; } -impl OffchainSubmitTransaction for TPool { +impl OffchainSubmitTransaction for TPool { fn submit_at( &self, at: &BlockId, @@ -300,15 +322,14 @@ impl OffchainSubmitTransaction for TPool { extrinsic ); - let result = futures::executor::block_on(self.submit_one( - &at, TransactionSource::Local, extrinsic, - )); + let result = self.submit_local(&at, extrinsic); - result.map(|_| ()) - .map_err(|e| log::warn!( + result.map(|_| ()).map_err(|e| { + log::warn!( target: "txpool", "(offchain call) Error submitting a transaction to the pool: {:?}", e - )) + ) + }) } } diff --git a/primitives/transaction-pool/src/runtime_api.rs b/primitives/transaction-pool/src/runtime_api.rs index fa2e51653b284fcde5ca6362017c4ec813c48a0a..9080c023f58909cf739f87ce60fe917074fc9776 100644 --- a/primitives/transaction-pool/src/runtime_api.rs +++ b/primitives/transaction-pool/src/runtime_api.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Tagged Transaction Queue Runtime API. diff --git a/primitives/trie/Cargo.toml b/primitives/trie/Cargo.toml index c010b3262d7e22f0cff38c10324e0aef2ddc3dd9..7705c80270c13d9829d9f55da3857c6133d4f925 100644 --- a/primitives/trie/Cargo.toml +++ b/primitives/trie/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-trie" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] description = "Patricia trie stuff using a parity-scale-codec node format" repository = "https://github.com/paritytech/substrate/" -license = "GPL-3.0" +license = "Apache-2.0" edition = "2018" homepage = "https://substrate.dev" documentation = "https://docs.rs/sp-trie" @@ -17,20 +17,20 @@ name = "bench" harness = false [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } hash-db = { version = "0.15.2", default-features = false } -trie-db = { version = "0.20.1", default-features = false } +trie-db = { version = "0.22.0", default-features = false } trie-root = { version = "0.16.0", default-features = false } -memory-db = { version = "0.20.0", default-features = false } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } +memory-db = { version = "0.24.0", default-features = false } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../core" } [dev-dependencies] -trie-bench = "0.21.0" +trie-bench = "0.25.0" trie-standardmap = "0.15.2" -criterion = "0.2.11" -hex-literal = "0.2.1" -sp-runtime = { version = "2.0.0-dev", path = "../runtime" } +criterion = "0.3.3" +hex-literal = "0.3.1" +sp-runtime = { version = "2.0.0-rc6", path = "../runtime" } [features] default = ["std"] @@ -43,3 +43,4 @@ std = [ "trie-root/std", "sp-core/std", ] +memory-tracker = [] diff --git a/primitives/trie/README.md b/primitives/trie/README.md new file mode 100644 index 0000000000000000000000000000000000000000..634ba4bdead26d4a77e4c284866bf0cb37b3d93c --- /dev/null +++ b/primitives/trie/README.md @@ -0,0 +1,3 @@ +Utility functions to interact with Substrate's Base-16 Modified Merkle Patricia tree ("trie"). + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/trie/src/lib.rs b/primitives/trie/src/lib.rs index f328b71750ba42a2252b19f71375f2db10d34076..73a4a8029b2d71d08f6cf8c9b7a39cec003d27d4 100644 --- a/primitives/trie/src/lib.rs +++ b/primitives/trie/src/lib.rs @@ -24,9 +24,7 @@ mod node_codec; mod storage_proof; mod trie_stream; -use sp_std::boxed::Box; -use sp_std::marker::PhantomData; -use sp_std::vec::Vec; +use sp_std::{boxed::Box, marker::PhantomData, vec::Vec, borrow::Borrow}; use hash_db::{Hasher, Prefix}; use trie_db::proof::{generate_proof, verify_proof}; pub use trie_db::proof::VerifyError; @@ -53,6 +51,7 @@ pub struct Layout(sp_std::marker::PhantomData); impl TrieLayout for Layout { const USE_EXTENSION: bool = false; + const ALLOW_EMPTY: bool = true; type Hash = H; type Codec = NodeCodec; } @@ -79,6 +78,11 @@ impl TrieConfiguration for Layout { } } +#[cfg(not(feature = "memory-tracker"))] +type MemTracker = memory_db::NoopTracker; +#[cfg(feature = "memory-tracker")] +type MemTracker = memory_db::MemCounter; + /// TrieDB error over `TrieConfiguration` trait. pub type TrieError = trie_db::TrieError, CError>; /// Reexport from `hash_db`, with genericity set for `Hasher` trait. @@ -89,13 +93,19 @@ pub type HashDB<'a, H> = dyn hash_db::HashDB + 'a; /// Reexport from `hash_db`, with genericity set for `Hasher` trait. /// This uses a `KeyFunction` for prefixing keys internally (avoiding /// key conflict for non random keys). -pub type PrefixedMemoryDB = memory_db::MemoryDB, trie_db::DBValue>; +pub type PrefixedMemoryDB = memory_db::MemoryDB< + H, memory_db::PrefixedKey, trie_db::DBValue, MemTracker +>; /// Reexport from `hash_db`, with genericity set for `Hasher` trait. /// This uses a noops `KeyFunction` (key addressing must be hashed or using /// an encoding scheme that avoid key conflict). -pub type MemoryDB = memory_db::MemoryDB, trie_db::DBValue>; +pub type MemoryDB = memory_db::MemoryDB< + H, memory_db::HashKey, trie_db::DBValue, MemTracker, +>; /// Reexport from `hash_db`, with genericity set for `Hasher` trait. -pub type GenericMemoryDB = memory_db::MemoryDB; +pub type GenericMemoryDB = memory_db::MemoryDB< + H, KF, trie_db::DBValue, MemTracker +>; /// Persistent trie database read-access interface for the a given hasher. pub type TrieDB<'a, L> = trie_db::TrieDB<'a, L>; @@ -162,23 +172,27 @@ pub fn verify_trie_proof<'a, L: TrieConfiguration, I, K, V>( } /// Determine a trie root given a hash DB and delta values. -pub fn delta_trie_root( +pub fn delta_trie_root( db: &mut DB, mut root: TrieHash, delta: I ) -> Result, Box>> where - I: IntoIterator)>, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]>, + I: IntoIterator, + A: Borrow<[u8]>, + B: Borrow>, + V: Borrow<[u8]>, DB: hash_db::HashDB, { { let mut trie = TrieDBMut::::from_existing(&mut *db, &mut root)?; + let mut delta = delta.into_iter().collect::>(); + delta.sort_by(|l, r| l.0.borrow().cmp(r.0.borrow())); + for (key, change) in delta { - match change { - Some(val) => trie.insert(key.as_ref(), val.as_ref())?, - None => trie.remove(key.as_ref())?, + match change.borrow() { + Some(val) => trie.insert(key.borrow(), val.borrow())?, + None => trie.remove(key.borrow())?, }; } } @@ -230,16 +244,17 @@ pub fn child_trie_root( /// Determine a child trie root given a hash DB and delta values. H is the default hasher, /// but a generic implementation may ignore this type parameter and use other hashers. -pub fn child_delta_trie_root( +pub fn child_delta_trie_root( keyspace: &[u8], db: &mut DB, root_data: RD, delta: I, ) -> Result<::Out, Box>> where - I: IntoIterator)>, - A: AsRef<[u8]> + Ord, - B: AsRef<[u8]>, + I: IntoIterator, + A: Borrow<[u8]>, + B: Borrow>, + V: Borrow<[u8]>, RD: AsRef<[u8]>, DB: hash_db::HashDB { @@ -247,19 +262,12 @@ pub fn child_delta_trie_root( // root is fetched from DB, not writable by runtime, so it's always valid. root.as_mut().copy_from_slice(root_data.as_ref()); - { - let mut db = KeySpacedDBMut::new(&mut *db, keyspace); - let mut trie = TrieDBMut::::from_existing(&mut db, &mut root)?; - - for (key, change) in delta { - match change { - Some(val) => trie.insert(key.as_ref(), val.as_ref())?, - None => trie.remove(key.as_ref())?, - }; - } - } - - Ok(root) + let mut db = KeySpacedDBMut::new(&mut *db, keyspace); + delta_trie_root::( + &mut db, + root, + delta, + ) } /// Call `f` for all keys in a child trie. @@ -456,7 +464,7 @@ mod trie_constants { #[cfg(test)] mod tests { use super::*; - use codec::{Encode, Compact}; + use codec::{Encode, Decode, Compact}; use sp_core::Blake2Hasher; use hash_db::{HashDB, Hasher}; use trie_db::{DBValue, TrieMut, Trie, NodeCodec as NodeCodecT}; @@ -565,7 +573,7 @@ mod tests { count: 1000, }; let mut d = st.make(); - d.sort_unstable_by(|&(ref a, _), &(ref b, _)| a.cmp(b)); + d.sort_by(|&(ref a, _), &(ref b, _)| a.cmp(b)); let dr = d.iter().map(|v| (&v.0[..], &v.1[..])).collect(); check_equivalent::(&dr); check_iteration::(&dr); @@ -844,4 +852,34 @@ mod tests { ).is_err() ); } + + #[test] + fn generate_storage_root_with_proof_works_independently_from_the_delta_order() { + let proof = StorageProof::decode(&mut &include_bytes!("../test-res/proof")[..]).unwrap(); + let storage_root = sp_core::H256::decode( + &mut &include_bytes!("../test-res/storage_root")[..], + ).unwrap(); + // Delta order that is "invalid" so that it would require a different proof. + let invalid_delta = Vec::<(Vec, Option>)>::decode( + &mut &include_bytes!("../test-res/invalid-delta-order")[..], + ).unwrap(); + // Delta order that is "valid" + let valid_delta = Vec::<(Vec, Option>)>::decode( + &mut &include_bytes!("../test-res/valid-delta-order")[..], + ).unwrap(); + + let proof_db = proof.into_memory_db::(); + let first_storage_root = delta_trie_root::( + &mut proof_db.clone(), + storage_root, + valid_delta, + ).unwrap(); + let second_storage_root = delta_trie_root::( + &mut proof_db.clone(), + storage_root, + invalid_delta, + ).unwrap(); + + assert_eq!(first_storage_root, second_storage_root); + } } diff --git a/primitives/trie/test-res/invalid-delta-order b/primitives/trie/test-res/invalid-delta-order new file mode 100644 index 0000000000000000000000000000000000000000..e46f280dc29bb2cbc3a28faeabe51efc747ba4af Binary files /dev/null and b/primitives/trie/test-res/invalid-delta-order differ diff --git a/primitives/trie/test-res/proof b/primitives/trie/test-res/proof new file mode 100644 index 0000000000000000000000000000000000000000..278bea0bfbbc7fb16364eddbded70c884dd7ab71 Binary files /dev/null and b/primitives/trie/test-res/proof differ diff --git a/primitives/trie/test-res/storage_root b/primitives/trie/test-res/storage_root new file mode 100644 index 0000000000000000000000000000000000000000..758626802e15fce51207139cc5c67589f0c55878 --- /dev/null +++ b/primitives/trie/test-res/storage_root @@ -0,0 +1 @@ +=[42%JP hKw)R 0ԭu \ No newline at end of file diff --git a/primitives/trie/test-res/valid-delta-order b/primitives/trie/test-res/valid-delta-order new file mode 100644 index 0000000000000000000000000000000000000000..4df6e62ec133b05cab2b53f00c8a4286eef70865 Binary files /dev/null and b/primitives/trie/test-res/valid-delta-order differ diff --git a/primitives/utils/Cargo.toml b/primitives/utils/Cargo.toml index 79a3a3315474748bf61a7504c72689650ef9d8a2..b21dba40a9d9b89b9bd1083144acf4e768260c7d 100644 --- a/primitives/utils/Cargo.toml +++ b/primitives/utils/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-utils" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "I/O for Substrate runtimes" @@ -12,7 +12,8 @@ description = "I/O for Substrate runtimes" futures = "0.3.4" futures-core = "0.3.4" lazy_static = "1.4.0" -prometheus = "0.8.0" +prometheus = { version = "0.9.0", default-features = false } +futures-timer = "3.0.2" [features] default = ["metered"] diff --git a/primitives/utils/README.md b/primitives/utils/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b0e04a3f4f1988e1a8ef88a9686e32d20bbcc4f8 --- /dev/null +++ b/primitives/utils/README.md @@ -0,0 +1,3 @@ +Utilities Primitives for Substrate + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/utils/src/lib.rs b/primitives/utils/src/lib.rs index 385a9b6689896102d5e43fc0eda53bb170f0443c..77bcd096561b45befcee7f80a0611108ce756830 100644 --- a/primitives/utils/src/lib.rs +++ b/primitives/utils/src/lib.rs @@ -1,20 +1,22 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Utilities Primitives for Substrate pub mod metrics; -pub mod mpsc; \ No newline at end of file +pub mod mpsc; +pub mod status_sinks; diff --git a/primitives/utils/src/metrics.rs b/primitives/utils/src/metrics.rs index 160714fdca1cd8a6bc2864a38fead5bf7fa4cf56..a66589b5927fe2fa6386f5f2024e0e342f665825 100644 --- a/primitives/utils/src/metrics.rs +++ b/primitives/utils/src/metrics.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Metering primitives and globals @@ -22,8 +23,8 @@ use prometheus::{ core::{ AtomicU64, GenericGauge, GenericCounter }, }; -#[cfg(features = "metered")] -use prometheus::{core::GenericGaugeVec, Opts}; +#[cfg(feature = "metered")] +use prometheus::{core::GenericCounterVec, Opts}; lazy_static! { @@ -36,9 +37,9 @@ lazy_static! { ).expect("Creating of statics doesn't fail. qed"); } -#[cfg(features = "metered")] +#[cfg(feature = "metered")] lazy_static! { - pub static ref UNBOUNDED_CHANNELS_COUNTER : GenericGaugeVec = GenericGaugeVec::new( + pub static ref UNBOUNDED_CHANNELS_COUNTER : GenericCounterVec = GenericCounterVec::new( Opts::new("unbounded_channel_len", "Items in each mpsc::unbounded instance"), &["entity", "action"] // 'name of channel, send|received|dropped ).expect("Creating of statics doesn't fail. qed"); @@ -51,7 +52,7 @@ pub fn register_globals(registry: &Registry) -> Result<(), PrometheusError> { registry.register(Box::new(TOKIO_THREADS_ALIVE.clone()))?; registry.register(Box::new(TOKIO_THREADS_TOTAL.clone()))?; - #[cfg(features = "metered")] + #[cfg(feature = "metered")] registry.register(Box::new(UNBOUNDED_CHANNELS_COUNTER.clone()))?; Ok(()) diff --git a/primitives/utils/src/mpsc.rs b/primitives/utils/src/mpsc.rs index 42fb287c18d892ea204b60131dbea20c9f7ee43c..70baa006bdcdc0d86b99aec71859361806f9044c 100644 --- a/primitives/utils/src/mpsc.rs +++ b/primitives/utils/src/mpsc.rs @@ -1,22 +1,23 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Features to meter unbounded channels -#[cfg(not(features = "metered"))] +#[cfg(not(feature = "metered"))] mod inner { // just aliased, non performance implications use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender}; @@ -30,22 +31,29 @@ mod inner { } -#[cfg(features = "metered")] +#[cfg(feature = "metered")] mod inner { //tracing implementation use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender, TryRecvError, TrySendError, SendError }; - use futures::{sink::Sink, task::{Poll, Context}, stream::Stream}; + use futures::{sink::Sink, task::{Poll, Context}, stream::{Stream, FusedStream}}; use std::pin::Pin; use crate::metrics::UNBOUNDED_CHANNELS_COUNTER; /// Wrapper Type around `UnboundedSender` that increases the global /// measure when a message is added - #[derive(Debug, Clone)] + #[derive(Debug)] pub struct TracingUnboundedSender(&'static str, UnboundedSender); + // Strangely, deriving `Clone` requires that `T` is also `Clone`. + impl Clone for TracingUnboundedSender { + fn clone(&self) -> Self { + Self(self.0, self.1.clone()) + } + } + /// Wrapper Type around `UnboundedReceiver` that decreases the global /// measure when a message is polled #[derive(Debug)] @@ -87,7 +95,7 @@ mod inner { /// Proxy function to mpsc::UnboundedSender pub fn unbounded_send(&self, msg: T) -> Result<(), TrySendError> { self.1.unbounded_send(msg).map(|s|{ - UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, &"send"]).incr(); + UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, &"send"]).inc(); s }) } @@ -103,13 +111,19 @@ mod inner { fn consume(&mut self) { // consume all items, make sure to reflect the updated count let mut count = 0; - while let Ok(Some(..)) = self.try_next() { - count += 1; - } + loop { + if self.1.is_terminated() { + break; + } + match self.try_next() { + Ok(Some(..)) => count += 1, + _ => break + } + } // and discount the messages if count > 0 { - UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, &"dropped"]).incr_by(count); + UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, &"dropped"]).inc_by(count); } } @@ -126,7 +140,7 @@ mod inner { pub fn try_next(&mut self) -> Result, TryRecvError> { self.1.try_next().map(|s| { if s.is_some() { - UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, &"received"]).incr(); + UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, &"received"]).inc(); } s }) @@ -152,7 +166,7 @@ mod inner { match Pin::new(&mut s.1).poll_next(cx) { Poll::Ready(msg) => { if msg.is_some() { - UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[self.0, "received"]).incr(); + UNBOUNDED_CHANNELS_COUNTER.with_label_values(&[s.0, "received"]).inc(); } Poll::Ready(msg) } @@ -163,6 +177,11 @@ mod inner { } } + impl FusedStream for TracingUnboundedReceiver { + fn is_terminated(&self) -> bool { + self.1.is_terminated() + } + } impl Sink for TracingUnboundedSender { type Error = SendError; diff --git a/primitives/utils/src/status_sinks.rs b/primitives/utils/src/status_sinks.rs new file mode 100644 index 0000000000000000000000000000000000000000..65a560af4eaa52a8eb3fa49cd0d5e6bc38527be7 --- /dev/null +++ b/primitives/utils/src/status_sinks.rs @@ -0,0 +1,207 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use crate::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; +use futures::{prelude::*, lock::Mutex}; +use futures_timer::Delay; +use std::{pin::Pin, task::{Poll, Context}, time::Duration}; + +/// Holds a list of `UnboundedSender`s, each associated with a certain time period. Every time the +/// period elapses, we push an element on the sender. +/// +/// Senders are removed only when they are closed. +pub struct StatusSinks { + /// Should only be locked by `next`. + inner: Mutex>, + /// Sending side of `Inner::entries_rx`. + entries_tx: TracingUnboundedSender>, +} + +struct Inner { + /// The actual entries of the list. + entries: stream::FuturesUnordered>, + /// Receives new entries and puts them in `entries`. + entries_rx: TracingUnboundedReceiver>, +} + +struct YieldAfter { + delay: Delay, + interval: Duration, + sender: Option>, +} + +impl StatusSinks { + /// Builds a new empty collection. + pub fn new() -> StatusSinks { + let (entries_tx, entries_rx) = tracing_unbounded("status-sinks-entries"); + + StatusSinks { + inner: Mutex::new(Inner { + entries: stream::FuturesUnordered::new(), + entries_rx, + }), + entries_tx, + } + } + + /// Adds a sender to the collection. + /// + /// The `interval` is the time period between two pushes on the sender. + pub fn push(&self, interval: Duration, sender: TracingUnboundedSender) { + let _ = self.entries_tx.unbounded_send(YieldAfter { + delay: Delay::new(interval), + interval, + sender: Some(sender), + }); + } + + /// Waits until one of the sinks is ready, then returns an object that can be used to send + /// an element on said sink. + /// + /// If the object isn't used to send an element, the slot is skipped. + pub async fn next(&self) -> ReadySinkEvent<'_, T> { + // This is only ever locked by `next`, which means that one `next` at a time can run. + let mut inner = self.inner.lock().await; + let inner = &mut *inner; + + loop { + // Future that produces the next ready entry in `entries`, or doesn't produce anything if + // the list is empty. + let next_ready_entry = { + let entries = &mut inner.entries; + async move { + if let Some(v) = entries.next().await { + v + } else { + loop { + futures::pending!() + } + } + } + }; + + futures::select!{ + new_entry = inner.entries_rx.next() => { + if let Some(new_entry) = new_entry { + inner.entries.push(new_entry); + } + }, + (sender, interval) = next_ready_entry.fuse() => { + return ReadySinkEvent { + sinks: self, + sender: Some(sender), + interval, + } + } + } + } + } +} + +/// One of the sinks is ready. +#[must_use] +pub struct ReadySinkEvent<'a, T> { + sinks: &'a StatusSinks, + sender: Option>, + interval: Duration, +} + +impl<'a, T> ReadySinkEvent<'a, T> { + /// Sends an element on the sender. + pub fn send(mut self, element: T) { + if let Some(sender) = self.sender.take() { + if sender.unbounded_send(element).is_ok() { + let _ = self.sinks.entries_tx.unbounded_send(YieldAfter { + // Note that since there's a small delay between the moment a task is + // woken up and the moment it is polled, the period is actually not + // `interval` but `interval + `. We ignore this problem in + // practice. + delay: Delay::new(self.interval), + interval: self.interval, + sender: Some(sender), + }); + } + } + } +} + +impl<'a, T> Drop for ReadySinkEvent<'a, T> { + fn drop(&mut self) { + if let Some(sender) = self.sender.take() { + if sender.is_closed() { + return; + } + + let _ = self.sinks.entries_tx.unbounded_send(YieldAfter { + delay: Delay::new(self.interval), + interval: self.interval, + sender: Some(sender), + }); + } + } +} + +impl futures::Future for YieldAfter { + type Output = (TracingUnboundedSender, Duration); + + fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { + let this = Pin::into_inner(self); + + match Pin::new(&mut this.delay).poll(cx) { + Poll::Pending => Poll::Pending, + Poll::Ready(()) => { + let sender = this.sender.take() + .expect("sender is always Some unless the future is finished; qed"); + Poll::Ready((sender, this.interval)) + } + } + } +} + +#[cfg(test)] +mod tests { + use crate::mpsc::tracing_unbounded; + use super::StatusSinks; + use futures::prelude::*; + use std::time::Duration; + + #[test] + fn works() { + // We're not testing that the `StatusSink` properly enforces an order in the intervals, as + // this easily causes test failures on busy CPUs. + + let status_sinks = StatusSinks::new(); + + let (tx, rx) = tracing_unbounded("test"); + status_sinks.push(Duration::from_millis(100), tx); + + let mut val_order = 5; + + futures::executor::block_on(futures::future::select( + Box::pin(async move { + loop { + let ev = status_sinks.next().await; + val_order += 1; + ev.send(val_order); + } + }), + Box::pin(async { + let items: Vec = rx.take(3).collect().await; + assert_eq!(items, [6, 7, 8]); + }) + )); + } +} diff --git a/primitives/version/Cargo.toml b/primitives/version/Cargo.toml index 1d492ee41c4061083aebbe35a70a26f23d437f12..7db79ba0003661c9d3f6842bd12b6e0d23a6398b 100644 --- a/primitives/version/Cargo.toml +++ b/primitives/version/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-version" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Version module for the Substrate runtime; Provides a function that returns the runtime version." @@ -14,11 +14,11 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -impl-serde = { version = "0.2.3", optional = true } +impl-serde = { version = "0.3.1", optional = true } serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/version/README.md b/primitives/version/README.md new file mode 100644 index 0000000000000000000000000000000000000000..84f0ae57d9dbeef1c84e4e01a8769b5f886e4501 --- /dev/null +++ b/primitives/version/README.md @@ -0,0 +1,3 @@ +Version module for the Substrate runtime; Provides a function that returns the runtime version. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/version/src/lib.rs b/primitives/version/src/lib.rs index 613b23156a59bca110fd532385d69d304dbe7a96..133d0497a2584ff936f19d48d2dac31d9405f534 100644 --- a/primitives/version/src/lib.rs +++ b/primitives/version/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Version module for the Substrate runtime; Provides a function that returns the runtime version. diff --git a/primitives/wasm-interface/Cargo.toml b/primitives/wasm-interface/Cargo.toml index 8bea87d4902d4b5186965ad93d4286ed8eda26d6..e4ce84eaf0e6b95a546ea8ae4491f9d6500df89c 100644 --- a/primitives/wasm-interface/Cargo.toml +++ b/primitives/wasm-interface/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-wasm-interface" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Types and traits for interfacing between the host and the wasm runtime." @@ -15,8 +15,8 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] wasmi = { version = "0.6.2", optional = true } impl-trait-for-tuples = "0.1.2" -sp-std = { version = "2.0.0-dev", path = "../std", default-features = false } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", path = "../std", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } [features] default = [ "std" ] diff --git a/primitives/wasm-interface/README.md b/primitives/wasm-interface/README.md new file mode 100644 index 0000000000000000000000000000000000000000..7e6c46581ae43c19b3b9b73d3d2b7975017c1a38 --- /dev/null +++ b/primitives/wasm-interface/README.md @@ -0,0 +1,3 @@ +Types and traits for interfacing between the host and the wasm runtime. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/wasm-interface/src/lib.rs b/primitives/wasm-interface/src/lib.rs index 1601590e9082dd7cfe8c24e78eba8ba1ce663026..c432a966056c5333903d1d1f589211cfb8748811 100644 --- a/primitives/wasm-interface/src/lib.rs +++ b/primitives/wasm-interface/src/lib.rs @@ -1,24 +1,26 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Types and traits for interfacing between the host and the wasm runtime. #![cfg_attr(not(feature = "std"), no_std)] use sp_std::{ + vec, borrow::Cow, marker::PhantomData, mem, iter::Iterator, result, vec::Vec, }; @@ -274,8 +276,7 @@ impl PartialEq for dyn Function { pub trait FunctionContext { /// Read memory from `address` into a vector. fn read_memory(&self, address: Pointer, size: WordSize) -> Result> { - let mut vec = Vec::with_capacity(size as usize); - vec.resize(size as usize, 0); + let mut vec = vec![0; size as usize]; self.read_memory_into(address, &mut vec)?; Ok(vec) } diff --git a/primitives/wasm-interface/src/wasmi_impl.rs b/primitives/wasm-interface/src/wasmi_impl.rs index dea8519b711a7ef88a863bec5457a15116381546..5931671c97ed49afba78dc88624aa9ef4f570f25 100644 --- a/primitives/wasm-interface/src/wasmi_impl.rs +++ b/primitives/wasm-interface/src/wasmi_impl.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Implementation of conversions between Substrate and wasmi types. diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index 43979be55329a70aad5386b86a9d5e0443bdcfbc..92bc9c71db5c8cc7d7a1e0adee9d337ba09d807a 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -1,11 +1,21 @@ [package] name = "substrate-test-utils" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" +description = "Substrate test utilities" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +futures = { version = "0.3.1", features = ["compat"] } +substrate-test-utils-derive = { version = "0.8.0-rc6", path = "./derive" } +tokio = { version = "0.2.13", features = ["macros"] } + +[dev-dependencies] +sc-service = { version = "0.8.0-rc6", path = "../client/service" } +trybuild = { version = "1.0", features = ["diff"] } diff --git a/test-utils/client/Cargo.toml b/test-utils/client/Cargo.toml index 37c99292ec910ec90ad8d5d255dee0840654985f..29f5acd5b38a4728c5932ad193161fffada526ae 100644 --- a/test-utils/client/Cargo.toml +++ b/test-utils/client/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "substrate-test-client" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false @@ -12,17 +12,22 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-client-api = { version = "2.0.0-dev", path = "../../client/api" } -sc-client-db = { version = "0.8.0-dev", features = ["test-helpers"], path = "../../client/db" } -sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } -sc-executor = { version = "0.8.0-dev", path = "../../client/executor" } -sc-consensus = { version = "0.8.0-dev", path = "../../client/consensus/common" } -sc-service = { version = "0.8.0-dev", default-features = false, features = ["test-helpers"], path = "../../client/service" } +codec = { package = "parity-scale-codec", version = "1.3.1" } futures = "0.3.4" +futures01 = { package = "futures", version = "0.1.29" } hash-db = "0.15.2" -sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } -codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +hex = "0.4" +serde = "1.0.55" +serde_json = "1.0.55" +sc-client-api = { version = "2.0.0-rc6", path = "../../client/api" } +sc-client-db = { version = "0.8.0-rc6", features = ["test-helpers"], path = "../../client/db" } +sc-consensus = { version = "0.8.0-rc6", path = "../../client/consensus/common" } +sc-executor = { version = "0.8.0-rc6", path = "../../client/executor" } +sc-light = { version = "2.0.0-rc6", path = "../../client/light" } +sc-service = { version = "0.8.0-rc6", default-features = false, features = ["test-helpers"], path = "../../client/service" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sp-consensus = { version = "0.8.0-rc6", path = "../../primitives/consensus/common" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-keyring = { version = "2.0.0-rc6", path = "../../primitives/keyring" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } diff --git a/test-utils/client/src/client_ext.rs b/test-utils/client/src/client_ext.rs index d663dda7a9323981772e3f88778b8c607ba911c8..a74bd3258ef0f97782fbba780e8c01d26124f480 100644 --- a/test-utils/client/src/client_ext.rs +++ b/test-utils/client/src/client_ext.rs @@ -1,23 +1,25 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Client extension for tests. use sc_service::client::Client; use sc_client_api::backend::Finalizer; +use sc_client_api::client::BlockBackend; use sp_consensus::{ BlockImportParams, BlockImport, BlockOrigin, Error as ConsensusError, ForkChoiceStrategy, diff --git a/test-utils/client/src/lib.rs b/test-utils/client/src/lib.rs index 22173ca04edb0d6325a1b3217dc03bd7bb7c4725..f64e7e3cfb7e8d292264bab4ee78f879811204fd 100644 --- a/test-utils/client/src/lib.rs +++ b/test-utils/client/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Client testing utilities. @@ -22,7 +23,7 @@ pub mod client_ext; pub use sc_client_api::{ execution_extensions::{ExecutionStrategies, ExecutionExtensions}, - ForkBlocks, BadBlocks, CloneableSpawn, + ForkBlocks, BadBlocks, }; pub use sc_client_db::{Backend, self}; pub use sp_consensus; @@ -32,20 +33,24 @@ pub use sp_keyring::{ ed25519::Keyring as Ed25519Keyring, sr25519::Keyring as Sr25519Keyring, }; -pub use sp_core::{traits::BareCryptoStorePtr, tasks::executor as tasks_executor}; +pub use sp_core::traits::BareCryptoStorePtr; pub use sp_runtime::{Storage, StorageChild}; pub use sp_state_machine::ExecutionStrategy; -pub use sc_service::client; +pub use sc_service::{RpcHandlers, RpcSession, client}; pub use self::client_ext::{ClientExt, ClientBlockImportExt}; +use std::pin::Pin; use std::sync::Arc; -use std::collections::HashMap; +use std::collections::{HashSet, HashMap}; +use futures::{future::{Future, FutureExt}, stream::StreamExt}; +use serde::Deserialize; use sp_core::storage::ChildInfo; -use sp_runtime::traits::{Block as BlockT, BlakeTwo256}; +use sp_runtime::{OpaqueExtrinsic, codec::Encode, traits::{Block as BlockT, BlakeTwo256}}; use sc_service::client::{LocalCallExecutor, ClientConfig}; +use sc_client_api::BlockchainEvents; /// Test client light database backend. -pub type LightBackend = client::light::backend::Backend< +pub type LightBackend = sc_light::Backend< sc_client_db::light::LightStorage, BlakeTwo256, >; @@ -249,8 +254,200 @@ impl TestClientBuilder< let executor = executor.into().unwrap_or_else(|| NativeExecutor::new(WasmExecutionMethod::Interpreted, None, 8) ); - let executor = LocalCallExecutor::new(self.backend.clone(), executor, tasks_executor(), Default::default()); + let executor = LocalCallExecutor::new( + self.backend.clone(), + executor, + Box::new(sp_core::testing::TaskExecutor::new()), + Default::default(), + ); self.build_with_executor(executor) } } + +/// The output of an RPC transaction. +pub struct RpcTransactionOutput { + /// The output string of the transaction if any. + pub result: Option, + /// The session object. + pub session: RpcSession, + /// An async receiver if data will be returned via a callback. + pub receiver: futures01::sync::mpsc::Receiver, +} + +impl std::fmt::Debug for RpcTransactionOutput { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "RpcTransactionOutput {{ result: {:?}, session, receiver }}", self.result) + } +} + +/// An error for when the RPC call fails. +#[derive(Deserialize, Debug)] +pub struct RpcTransactionError { + /// A Number that indicates the error type that occurred. + pub code: i64, + /// A String providing a short description of the error. + pub message: String, + /// A Primitive or Structured value that contains additional information about the error. + pub data: Option, +} + +impl std::fmt::Display for RpcTransactionError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + std::fmt::Debug::fmt(self, f) + } +} + +/// An extension trait for `RpcHandlers`. +pub trait RpcHandlersExt { + /// Send a transaction through the RpcHandlers. + fn send_transaction( + &self, + extrinsic: OpaqueExtrinsic, + ) -> Pin> + Send>>; +} + +impl RpcHandlersExt for RpcHandlers { + fn send_transaction( + &self, + extrinsic: OpaqueExtrinsic, + ) -> Pin> + Send>> { + let (tx, rx) = futures01::sync::mpsc::channel(0); + let mem = RpcSession::new(tx.into()); + Box::pin(self + .rpc_query( + &mem, + &format!( + r#"{{ + "jsonrpc": "2.0", + "method": "author_submitExtrinsic", + "params": ["0x{}"], + "id": 0 + }}"#, + hex::encode(extrinsic.encode()) + ), + ) + .map(move |result| parse_rpc_result(result, mem, rx)) + ) + } +} + +pub(crate) fn parse_rpc_result( + result: Option, + session: RpcSession, + receiver: futures01::sync::mpsc::Receiver, +) -> Result { + if let Some(ref result) = result { + let json: serde_json::Value = serde_json::from_str(result) + .expect("the result can only be a JSONRPC string; qed"); + let error = json + .as_object() + .expect("JSON result is always an object; qed") + .get("error"); + + if let Some(error) = error { + return Err( + serde_json::from_value(error.clone()) + .expect("the JSONRPC result's error is always valid; qed") + ) + } + } + + Ok(RpcTransactionOutput { + result, + session, + receiver, + }) +} + +/// An extension trait for `BlockchainEvents`. +pub trait BlockchainEventsExt +where + C: BlockchainEvents, + B: BlockT, +{ + /// Wait for `count` blocks to be imported in the node and then exit. This function will not return if no blocks + /// are ever created, thus you should restrict the maximum amount of time of the test execution. + fn wait_for_blocks(&self, count: usize) -> Pin + Send>>; +} + +impl BlockchainEventsExt for C +where + C: BlockchainEvents, + B: BlockT, +{ + fn wait_for_blocks(&self, count: usize) -> Pin + Send>> { + assert!(count > 0, "'count' argument must be greater than 0"); + + let mut import_notification_stream = self.import_notification_stream(); + let mut blocks = HashSet::new(); + + Box::pin(async move { + while let Some(notification) = import_notification_stream.next().await { + if notification.is_new_best { + blocks.insert(notification.hash); + if blocks.len() == count { + break; + } + } + } + }) + } +} + +#[cfg(test)] +mod tests { + use sc_service::RpcSession; + + fn create_session_and_receiver() -> (RpcSession, futures01::sync::mpsc::Receiver) { + let (tx, rx) = futures01::sync::mpsc::channel(0); + let mem = RpcSession::new(tx.into()); + + (mem, rx) + } + + #[test] + fn parses_error_properly() { + let (mem, rx) = create_session_and_receiver(); + assert!(super::parse_rpc_result(None, mem, rx).is_ok()); + + let (mem, rx) = create_session_and_receiver(); + assert!( + super::parse_rpc_result(Some(r#"{ + "jsonrpc": "2.0", + "result": 19, + "id": 1 + }"#.to_string()), mem, rx) + .is_ok(), + ); + + let (mem, rx) = create_session_and_receiver(); + let error = super::parse_rpc_result(Some(r#"{ + "jsonrpc": "2.0", + "error": { + "code": -32601, + "message": "Method not found" + }, + "id": 1 + }"#.to_string()), mem, rx) + .unwrap_err(); + assert_eq!(error.code, -32601); + assert_eq!(error.message, "Method not found"); + assert!(error.data.is_none()); + + let (mem, rx) = create_session_and_receiver(); + let error = super::parse_rpc_result(Some(r#"{ + "jsonrpc": "2.0", + "error": { + "code": -32601, + "message": "Method not found", + "data": 42 + }, + "id": 1 + }"#.to_string()), mem, rx) + .unwrap_err(); + assert_eq!(error.code, -32601); + assert_eq!(error.message, "Method not found"); + assert!(error.data.is_some()); + } +} diff --git a/test-utils/derive/Cargo.toml b/test-utils/derive/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..e9dcc586c50ddccb7b62708ac26c907aa231bc0d --- /dev/null +++ b/test-utils/derive/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "substrate-test-utils-derive" +version = "0.8.0-rc6" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "Substrate test utilities macros" + +[dependencies] +quote = "1.0.6" +syn = { version = "1.0.33", features = ["full"] } +proc-macro-crate = "0.1.4" + +[lib] +proc-macro = true diff --git a/test-utils/derive/src/lib.rs b/test-utils/derive/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..f5d627068963f5ce18b808a9528d4950d10561a6 --- /dev/null +++ b/test-utils/derive/src/lib.rs @@ -0,0 +1,107 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use proc_macro::{Span, TokenStream}; +use proc_macro_crate::crate_name; +use quote::quote; +use std::env; + +#[proc_macro_attribute] +pub fn test(args: TokenStream, item: TokenStream) -> TokenStream { + impl_test(args, item) +} + +fn impl_test(args: TokenStream, item: TokenStream) -> TokenStream { + let input = syn::parse_macro_input!(item as syn::ItemFn); + let args = syn::parse_macro_input!(args as syn::AttributeArgs); + + parse_knobs(input, args).unwrap_or_else(|e| e.to_compile_error().into()) +} + +fn parse_knobs( + mut input: syn::ItemFn, + args: syn::AttributeArgs, +) -> Result { + let sig = &mut input.sig; + let body = &input.block; + let attrs = &input.attrs; + let vis = input.vis; + + if sig.inputs.len() != 1 { + let msg = "the test function accepts only one argument of type sc_service::TaskExecutor"; + return Err(syn::Error::new_spanned(&sig, msg)); + } + let (task_executor_name, task_executor_type) = match sig.inputs.pop().map(|x| x.into_value()) { + Some(syn::FnArg::Typed(x)) => (x.pat, x.ty), + _ => { + let msg = + "the test function accepts only one argument of type sc_service::TaskExecutor"; + return Err(syn::Error::new_spanned(&sig, msg)); + } + }; + + let crate_name = if env::var("CARGO_PKG_NAME").unwrap() == "substrate-test-utils" { + syn::Ident::new("substrate_test_utils", Span::call_site().into()) + } else { + let crate_name = crate_name("substrate-test-utils") + .map_err(|e| syn::Error::new_spanned(&sig, e))?; + + syn::Ident::new(&crate_name, Span::call_site().into()) + }; + + let header = { + quote! { + #[#crate_name::tokio::test(#(#args)*)] + } + }; + + let result = quote! { + #header + #(#attrs)* + #vis #sig { + use #crate_name::futures::future::FutureExt; + + let #task_executor_name: #task_executor_type = (|fut, _| { + #crate_name::tokio::spawn(fut).map(drop) + }) + .into(); + let timeout_task = #crate_name::tokio::time::delay_for( + std::time::Duration::from_secs( + std::env::var("SUBSTRATE_TEST_TIMEOUT") + .ok() + .and_then(|x| x.parse().ok()) + .unwrap_or(600)) + ).fuse(); + let actual_test_task = async move { + #body + } + .fuse(); + + #crate_name::futures::pin_mut!(timeout_task, actual_test_task); + + #crate_name::futures::select! { + _ = timeout_task => { + panic!("The test took too long!"); + }, + _ = actual_test_task => {}, + } + } + }; + + Ok(result.into()) +} diff --git a/test-utils/runtime/Cargo.toml b/test-utils/runtime/Cargo.toml index 00aa157529127fa13d9319bb88f7362d661d476c..6b354f5f6e9f4c82f342a01e1a42eef3b098c2ec 100644 --- a/test-utils/runtime/Cargo.toml +++ b/test-utils/runtime/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "substrate-test-runtime" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false @@ -13,35 +13,35 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } -sp-consensus-aura = { version = "0.8.0-dev", default-features = false, path = "../../primitives/consensus/aura" } -sp-consensus-babe = { version = "0.8.0-dev", default-features = false, path = "../../primitives/consensus/babe" } -sp-block-builder = { version = "2.0.0-dev", default-features = false, path = "../../primitives/block-builder" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -frame-executive = { version = "2.0.0-dev", default-features = false, path = "../../frame/executive" } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } -sp-keyring = { version = "2.0.0-dev", optional = true, path = "../../primitives/keyring" } -memory-db = { version = "0.20.0", default-features = false } -sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-dev"} -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false, version = "2.0.0-dev"} -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../../frame/support" } -sp-version = { version = "2.0.0-dev", default-features = false, path = "../../primitives/version" } -sp-session = { version = "2.0.0-dev", default-features = false, path = "../../primitives/session" } -sp-api = { version = "2.0.0-dev", default-features = false, path = "../../primitives/api" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -pallet-babe = { version = "2.0.0-dev", default-features = false, path = "../../frame/babe" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../../frame/system" } -frame-system-rpc-runtime-api = { version = "2.0.0-dev", default-features = false, path = "../../frame/system/rpc/runtime-api" } -pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../frame/timestamp" } -sp-finality-grandpa = { version = "2.0.0-dev", default-features = false, path = "../../primitives/finality-grandpa" } -sp-trie = { version = "2.0.0-dev", default-features = false, path = "../../primitives/trie" } -sp-transaction-pool = { version = "2.0.0-dev", default-features = false, path = "../../primitives/transaction-pool" } -trie-db = { version = "0.20.1", default-features = false } -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } -sc-service = { version = "0.8.0-dev", default-features = false, optional = true, features = ["test-helpers"], path = "../../client/service" } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/application-crypto" } +sp-consensus-aura = { version = "0.8.0-rc6", default-features = false, path = "../../primitives/consensus/aura" } +sp-consensus-babe = { version = "0.8.0-rc6", default-features = false, path = "../../primitives/consensus/babe" } +sp-block-builder = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/block-builder" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +frame-executive = { version = "2.0.0-rc6", default-features = false, path = "../../frame/executive" } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/inherents" } +sp-keyring = { version = "2.0.0-rc6", optional = true, path = "../../primitives/keyring" } +memory-db = { version = "0.24.0", default-features = false } +sp-offchain = { path = "../../primitives/offchain", default-features = false, version = "2.0.0-rc6"} +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-runtime-interface = { path = "../../primitives/runtime-interface", default-features = false, version = "2.0.0-rc6"} +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../../frame/support" } +sp-version = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/version" } +sp-session = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/session" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/api" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +pallet-babe = { version = "2.0.0-rc6", default-features = false, path = "../../frame/babe" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../../frame/system" } +frame-system-rpc-runtime-api = { version = "2.0.0-rc6", default-features = false, path = "../../frame/system/rpc/runtime-api" } +pallet-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../frame/timestamp" } +sp-finality-grandpa = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/finality-grandpa" } +sp-trie = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/trie" } +sp-transaction-pool = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/transaction-pool" } +trie-db = { version = "0.22.0", default-features = false } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } +sc-service = { version = "0.8.0-rc6", default-features = false, optional = true, features = ["test-helpers"], path = "../../client/service" } # 3rd party cfg-if = "0.1.10" @@ -49,10 +49,10 @@ log = { version = "0.4.8", optional = true } serde = { version = "1.0.101", optional = true, features = ["derive"] } [dev-dependencies] -sc-block-builder = { version = "0.8.0-dev", path = "../../client/block-builder" } -sc-executor = { version = "0.8.0-dev", path = "../../client/executor" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "./client" } -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +sc-block-builder = { version = "0.8.0-rc6", path = "../../client/block-builder" } +sc-executor = { version = "0.8.0-rc6", path = "../../client/executor" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "./client" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../utils/wasm-builder-runner" } diff --git a/test-utils/runtime/build.rs b/test-utils/runtime/build.rs index 1fd3d52b2f860b0d3e73676b5fc1a707964e101d..6082738de419d5ca590911aba35bbbad8af01d8c 100644 --- a/test-utils/runtime/build.rs +++ b/test-utils/runtime/build.rs @@ -1,25 +1,26 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use wasm_builder_runner::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("1.0.9", "../../utils/wasm-builder") + .with_wasm_builder_from_crates_or_path("2.0.0", "../../utils/wasm-builder") .export_heap_base() // Note that we set the stack-size to 1MB explicitly even though it is set // to this value by default. This is because some of our tests (`restoration_of_globals`) diff --git a/test-utils/runtime/client/Cargo.toml b/test-utils/runtime/client/Cargo.toml index f622878404f44ae2c4fd9941615bf7ed6127da98..3406ca6f95cc8e7729c518f522a62f5ba34ed81f 100644 --- a/test-utils/runtime/client/Cargo.toml +++ b/test-utils/runtime/client/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "substrate-test-runtime-client" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false @@ -12,16 +12,17 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -sc-block-builder = { version = "0.8.0-dev", path = "../../../client/block-builder" } -substrate-test-client = { version = "2.0.0-dev", path = "../../client" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -substrate-test-runtime = { version = "2.0.0-dev", path = "../../runtime" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-client-api = { version = "2.0.0-dev", path = "../../../client/api" } -sc-consensus = { version = "0.8.0-dev", path = "../../../client/consensus/common" } -sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service" } +sc-light = { version = "2.0.0-rc6", path = "../../../client/light" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sc-block-builder = { version = "0.8.0-rc6", path = "../../../client/block-builder" } +substrate-test-client = { version = "2.0.0-rc6", path = "../../client" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +substrate-test-runtime = { version = "2.0.0-rc6", path = "../../runtime" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +codec = { package = "parity-scale-codec", version = "1.3.1" } +sc-client-api = { version = "2.0.0-rc6", path = "../../../client/api" } +sc-consensus = { version = "0.8.0-rc6", path = "../../../client/consensus/common" } +sc-service = { version = "0.8.0-rc6", default-features = false, path = "../../../client/service" } futures = "0.3.4" diff --git a/test-utils/runtime/client/src/block_builder_ext.rs b/test-utils/runtime/client/src/block_builder_ext.rs index 3a9f54d06cb2b4bdcb22d2029abb08343bce5ec6..cc0bbc69e8fc1063f5aa700d732399c17900e2bb 100644 --- a/test-utils/runtime/client/src/block_builder_ext.rs +++ b/test-utils/runtime/client/src/block_builder_ext.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Block Builder extensions for tests. diff --git a/test-utils/runtime/client/src/lib.rs b/test-utils/runtime/client/src/lib.rs index 7b51d88e069b0ad7a056c3bac17901213d524e69..5b343f7748eada844260ad27bfe9ee4a709c68da 100644 --- a/test-utils/runtime/client/src/lib.rs +++ b/test-utils/runtime/client/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Client testing utilities. @@ -34,12 +35,9 @@ use sp_core::{sr25519, ChangesTrieConfiguration}; use sp_core::storage::{ChildInfo, Storage, StorageChild}; use substrate_test_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Hash as HashT, NumberFor, HashFor}; -use sc_service::client::{ - light::fetcher::{ - Fetcher, - RemoteHeaderRequest, RemoteReadRequest, RemoteReadChildRequest, - RemoteCallRequest, RemoteChangesRequest, RemoteBodyRequest, - }, +use sc_client_api::light::{ + RemoteCallRequest, RemoteChangesRequest, RemoteBodyRequest, + Fetcher, RemoteHeaderRequest, RemoteReadRequest, RemoteReadChildRequest, }; /// A prelude to import in tests. @@ -77,10 +75,10 @@ pub type Executor = client::LocalCallExecutor< pub type LightBackend = substrate_test_client::LightBackend; /// Test client light executor. -pub type LightExecutor = client::light::call_executor::GenesisCallExecutor< +pub type LightExecutor = sc_light::GenesisCallExecutor< LightBackend, client::LocalCallExecutor< - client::light::backend::Backend< + sc_light::Backend< sc_client_db::light::LightStorage, HashFor >, @@ -349,10 +347,15 @@ pub fn new_light() -> ( ) { let storage = sc_client_db::light::LightStorage::new_test(); - let blockchain = Arc::new(client::light::blockchain::Blockchain::new(storage)); - let backend = Arc::new(LightBackend::new(blockchain.clone())); + let blockchain = Arc::new(sc_light::Blockchain::new(storage)); + let backend = Arc::new(LightBackend::new(blockchain)); let executor = new_native_executor(); - let local_call_executor = client::LocalCallExecutor::new(backend.clone(), executor, sp_core::tasks::executor(), Default::default()); + let local_call_executor = client::LocalCallExecutor::new( + backend.clone(), + executor, + Box::new(sp_core::testing::TaskExecutor::new()), + Default::default(), + ); let call_executor = LightExecutor::new( backend.clone(), local_call_executor, diff --git a/test-utils/runtime/client/src/trait_tests.rs b/test-utils/runtime/client/src/trait_tests.rs index 2a377fabba1294a1343eb0c6475d70848bde4acd..b240a42a785559b9b878570f78999cc2e91ef054 100644 --- a/test-utils/runtime/client/src/trait_tests.rs +++ b/test-utils/runtime/client/src/trait_tests.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! tests that should hold for all implementations of certain traits. //! to test implementations without duplication. @@ -283,7 +284,7 @@ pub fn test_children_for_backend(backend: Arc) where Default::default(), false, ).unwrap().build().unwrap().block; - client.import(BlockOrigin::Own, b4.clone()).unwrap(); + client.import(BlockOrigin::Own, b4).unwrap(); // // B2 -> C3 let mut builder = client.new_block_at( @@ -412,7 +413,7 @@ pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc C3 let mut builder = client.new_block_at( @@ -428,7 +429,7 @@ pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc D2 let mut builder = client.new_block_at( @@ -444,7 +445,7 @@ pub fn test_blockchain_query_by_number_gets_canonical(backend: Arc. +// 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. //! Tool for creating the genesis block. use std::collections::BTreeMap; use sp_io::hashing::{blake2_256, twox_128}; -use super::{AuthorityId, AccountId, WASM_BINARY, system}; +use super::{AuthorityId, AccountId, wasm_binary_unwrap, system}; use codec::{Encode, KeyedVec, Joiner}; use sp_core::{ChangesTrieConfiguration, map}; use sp_core::storage::{well_known_keys, Storage}; @@ -46,7 +47,7 @@ impl GenesisConfig { ) -> Self { GenesisConfig { changes_trie_config, - authorities: authorities.clone(), + authorities: authorities, balances: endowed_accounts.into_iter().map(|a| (a, balance)).collect(), heap_pages_override, extra_storage, @@ -54,7 +55,7 @@ impl GenesisConfig { } pub fn genesis_map(&self) -> Storage { - let wasm_runtime = WASM_BINARY.to_vec(); + let wasm_runtime = wasm_binary_unwrap().to_vec(); let mut map: BTreeMap, Vec> = self.balances.iter() .map(|&(ref account, balance)| (account.to_keyed_vec(b"balance:"), vec![].and(&balance))) .map(|(k, v)| (blake2_256(&k[..])[..].to_vec(), v.to_vec())) diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 1003a0c593d5db25a80023184f831a5b774f234f..f5e30de838a68424776eb9937b5474f29faec413 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The Substrate runtime. This can be compiled with #[no_std], ready for Wasm. @@ -25,8 +26,8 @@ pub mod system; use sp_std::{prelude::*, marker::PhantomData}; use codec::{Encode, Decode, Input, Error}; -use sp_core::{OpaqueMetadata, RuntimeDebug, ChangesTrieConfiguration}; -use sp_application_crypto::{ed25519, sr25519, RuntimeAppPublic}; +use sp_core::{offchain::KeyTypeId, ChangesTrieConfiguration, OpaqueMetadata, RuntimeDebug}; +use sp_application_crypto::{ed25519, sr25519, ecdsa, RuntimeAppPublic}; use trie_db::{TrieMut, Trie}; use sp_trie::PrefixedMemoryDB; use sp_trie::trie_types::{TrieDB, TrieDBMut}; @@ -48,18 +49,30 @@ use sp_version::RuntimeVersion; pub use sp_core::hash::H256; #[cfg(any(feature = "std", test))] use sp_version::NativeVersion; -use frame_support::{impl_outer_origin, parameter_types, weights::{Weight, RuntimeDbWeight}}; +use frame_support::{ + impl_outer_origin, parameter_types, + traits::KeyOwnerProofSystem, + weights::{RuntimeDbWeight, Weight}, +}; use sp_inherents::{CheckInherentsResult, InherentData}; use cfg_if::cfg_if; // Ensure Babe and Aura use the same crypto to simplify things a bit. pub use sp_consensus_babe::{AuthorityId, SlotNumber, AllowedSlots}; + pub type AuraId = sp_consensus_aura::sr25519::AuthorityId; // Include the WASM binary #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +#[cfg(feature = "std")] +/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. +pub fn wasm_binary_unwrap() -> &'static [u8] { + WASM_BINARY.expect("Development wasm binary is not available. Testing is only \ + supported with the flag disabled.") +} + /// Test runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("test"), @@ -183,7 +196,7 @@ impl ExtrinsicT for Extrinsic { } impl sp_runtime::traits::Dispatchable for Extrinsic { - type Origin = (); + type Origin = Origin; type Trait = (); type Info = (); type PostInfo = (); @@ -193,10 +206,20 @@ impl sp_runtime::traits::Dispatchable for Extrinsic { } impl Extrinsic { + /// Convert `&self` into `&Transfer`. + /// + /// Panics if this is no `Transfer` extrinsic. pub fn transfer(&self) -> &Transfer { + self.try_transfer().expect("cannot convert to transfer ref") + } + + /// Try to convert `&self` into `&Transfer`. + /// + /// Returns `None` if this is no `Transfer` extrinsic. + pub fn try_transfer(&self) -> Option<&Transfer> { match self { - Extrinsic::Transfer { ref transfer, .. } => transfer, - _ => panic!("cannot convert to transfer ref"), + Extrinsic::Transfer { ref transfer, .. } => Some(transfer), + _ => None, } } } @@ -207,6 +230,8 @@ pub type AccountSignature = sr25519::Signature; pub type AccountId = ::Signer; /// A simple hash type for all our hashing. pub type Hash = H256; +/// The hashing algorithm used. +pub type Hashing = BlakeTwo256; /// The block number type used in this runtime. pub type BlockNumber = u64; /// Index of a transaction. @@ -218,7 +243,7 @@ pub type Digest = sp_runtime::generic::Digest; /// A test block. pub type Block = sp_runtime::generic::Block; /// A test block's header. -pub type Header = sp_runtime::generic::Header; +pub type Header = sp_runtime::generic::Header; /// Run whatever tests we have. pub fn run_tests(mut input: &[u8]) -> Vec { @@ -304,8 +329,15 @@ cfg_if! { /// /// Returns the signature generated for the message `sr25519`. fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic); + /// Test that `ecdsa` crypto works in the runtime. + /// + /// Returns the signature generated for the message `ecdsa`. + fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic); /// Run various tests against storage. fn test_storage(); + /// Test that ensures that we can call a function that takes multiple + /// arguments. + fn test_multiple_arguments(data: Vec, other: Vec, num: u32); } } } else { @@ -346,8 +378,15 @@ cfg_if! { /// /// Returns the signature generated for the message `sr25519`. fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic); + /// Test that `ecdsa` crypto works in the runtime. + /// + /// Returns the signature generated for the message `ecdsa`. + fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic); /// Run various tests against storage. fn test_storage(); + /// Test that ensures that we can call a function that takes multiple + /// arguments. + fn test_multiple_arguments(data: Vec, other: Vec, num: u32); } } } @@ -378,7 +417,7 @@ impl From> for Event { } parameter_types! { - pub const BlockHashCount: BlockNumber = 250; + pub const BlockHashCount: BlockNumber = 2400; pub const MinimumPeriod: u64 = 5; pub const MaximumBlockWeight: Weight = 4 * 1024 * 1024; pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { @@ -390,12 +429,13 @@ parameter_types! { } impl frame_system::Trait for Runtime { + type BaseCallFilter = (); type Origin = Origin; type Call = Extrinsic; type Index = u64; type BlockNumber = u64; type Hash = H256; - type Hashing = BlakeTwo256; + type Hashing = Hashing; type AccountId = u64; type Lookup = IdentityLookup; type Header = Header; @@ -405,6 +445,7 @@ impl frame_system::Trait for Runtime { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type MaximumBlockLength = MaximumBlockLength; type AvailableBlockRatio = AvailableBlockRatio; type Version = (); @@ -412,6 +453,7 @@ impl frame_system::Trait for Runtime { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl pallet_timestamp::Trait for Runtime { @@ -419,6 +461,7 @@ impl pallet_timestamp::Trait for Runtime { type Moment = u64; type OnTimestampSet = (); type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } parameter_types! { @@ -433,6 +476,18 @@ impl pallet_babe::Trait for Runtime { // are manually adding the digests. normally in this situation you'd use // pallet_babe::SameAuthoritiesForever. type EpochChangeTrigger = pallet_babe::ExternalTrigger; + + type KeyOwnerProofSystem = (); + + type KeyOwnerProof = + >::Proof; + + type KeyOwnerIdentification = >::IdentificationTuple; + + type HandleEquivocation = (); } /// Adds one to the given input and returns the final result. @@ -456,7 +511,7 @@ fn code_using_trie() -> u64 { let mut root = sp_std::default::Default::default(); let _ = { let v = &pairs; - let mut t = TrieDBMut::::new(&mut mdb, &mut root); + let mut t = TrieDBMut::::new(&mut mdb, &mut root); for i in 0..v.len() { let key: &[u8]= &v[i].0; let val: &[u8] = &v[i].1; @@ -467,7 +522,7 @@ fn code_using_trie() -> u64 { t }; - if let Ok(trie) = TrieDB::::new(&mdb, &root) { + if let Ok(trie) = TrieDB::::new(&mdb, &root) { if let Ok(iter) = trie.iter() { let mut iter_pairs = Vec::new(); for pair in iter { @@ -484,6 +539,7 @@ impl_opaque_keys! { pub struct SessionKeys { pub ed25519: ed25519::AppPublic, pub sr25519: sr25519::AppPublic, + pub ecdsa: ecdsa::AppPublic, } } @@ -619,10 +675,19 @@ cfg_if! { test_sr25519_crypto() } + fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic) { + test_ecdsa_crypto() + } + fn test_storage() { test_read_storage(); test_read_child_storage(); } + + fn test_multiple_arguments(data: Vec, other: Vec, num: u32) { + assert_eq!(&data[..], &other[..]); + assert_eq!(data.len(), num as usize); + } } impl sp_consensus_aura::AuraApi for Runtime { @@ -651,6 +716,22 @@ cfg_if! { fn current_epoch_start() -> SlotNumber { >::current_epoch_start() } + + fn submit_report_equivocation_unsigned_extrinsic( + _equivocation_proof: sp_consensus_babe::EquivocationProof< + ::Header, + >, + _key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + + fn generate_key_ownership_proof( + _slot_number: sp_consensus_babe::SlotNumber, + _authority_id: sp_consensus_babe::AuthorityId, + ) -> Option { + None + } } impl sp_offchain::OffchainWorkerApi for Runtime { @@ -677,7 +758,7 @@ cfg_if! { Vec::new() } - fn submit_report_equivocation_extrinsic( + fn submit_report_equivocation_unsigned_extrinsic( _equivocation_proof: sp_finality_grandpa::EquivocationProof< ::Hash, NumberFor, @@ -836,10 +917,19 @@ cfg_if! { test_sr25519_crypto() } + fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic) { + test_ecdsa_crypto() + } + fn test_storage() { test_read_storage(); test_read_child_storage(); } + + fn test_multiple_arguments(data: Vec, other: Vec, num: u32) { + assert_eq!(&data[..], &other[..]); + assert_eq!(data.len(), num as usize); + } } impl sp_consensus_aura::AuraApi for Runtime { @@ -868,6 +958,22 @@ cfg_if! { fn current_epoch_start() -> SlotNumber { >::current_epoch_start() } + + fn submit_report_equivocation_unsigned_extrinsic( + _equivocation_proof: sp_consensus_babe::EquivocationProof< + ::Header, + >, + _key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof, + ) -> Option<()> { + None + } + + fn generate_key_ownership_proof( + _slot_number: sp_consensus_babe::SlotNumber, + _authority_id: sp_consensus_babe::AuthorityId, + ) -> Option { + None + } } impl sp_offchain::OffchainWorkerApi for Runtime { @@ -928,6 +1034,22 @@ fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic) { (signature, public0) } +fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic) { + let public0 = ecdsa::AppPublic::generate_pair(None); + let public1 = ecdsa::AppPublic::generate_pair(None); + let public2 = ecdsa::AppPublic::generate_pair(None); + + let all = ecdsa::AppPublic::all(); + assert!(all.contains(&public0)); + assert!(all.contains(&public1)); + assert!(all.contains(&public2)); + + let signature = public0.sign(&"ecdsa").expect("Generates a valid `ecdsa` signature."); + + assert!(public0.verify(&"ecdsa", &signature)); + (signature, public0) +} + fn test_read_storage() { const KEY: &[u8] = b":read_storage"; sp_io::storage::set(KEY, b"test"); diff --git a/test-utils/runtime/src/system.rs b/test-utils/runtime/src/system.rs index 9cfec187ddb797a619f87e52ffd71952c1b792bf..818487a89e518c35ed7a8942fa0e862e0c13804a 100644 --- a/test-utils/runtime/src/system.rs +++ b/test-utils/runtime/src/system.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! System manager: Handles all of the top-level stuff; executing block/transaction, setting code //! and depositing logs. @@ -341,7 +342,7 @@ mod tests { use sp_io::TestExternalities; use substrate_test_runtime_client::{AccountKeyring, Sr25519Keyring}; - use crate::{Header, Transfer, WASM_BINARY}; + use crate::{Header, Transfer, wasm_binary_unwrap}; use sp_core::{NeverNativeValue, map, traits::{CodeExecutor, RuntimeCode}}; use sc_executor::{NativeExecutor, WasmExecutionMethod, native_executor_instance}; use sp_io::hashing::twox_128; @@ -364,7 +365,7 @@ mod tests { Sr25519Keyring::Charlie.to_raw_public() ]; TestExternalities::new_with_code( - WASM_BINARY, + wasm_binary_unwrap(), sp_core::storage::Storage { top: map![ twox_128(b"latest").to_vec() => vec![69u8; 32], @@ -406,7 +407,7 @@ mod tests { block_import_works(|b, ext| { let mut ext = ext.ext(); let runtime_code = RuntimeCode { - code_fetcher: &sp_core::traits::WrappedRuntimeCode(WASM_BINARY.into()), + code_fetcher: &sp_core::traits::WrappedRuntimeCode(wasm_binary_unwrap().into()), hash: Vec::new(), heap_pages: None, }; @@ -506,7 +507,7 @@ mod tests { block_import_with_transaction_works(|b, ext| { let mut ext = ext.ext(); let runtime_code = RuntimeCode { - code_fetcher: &sp_core::traits::WrappedRuntimeCode(WASM_BINARY.into()), + code_fetcher: &sp_core::traits::WrappedRuntimeCode(wasm_binary_unwrap().into()), hash: Vec::new(), heap_pages: None, }; diff --git a/test-utils/runtime/transaction-pool/Cargo.toml b/test-utils/runtime/transaction-pool/Cargo.toml index 9ccf9d2e448701cad8bd25b3dae3a55ad6930856..ee0992c44be4666cdcaea56c178371aad1f6f58c 100644 --- a/test-utils/runtime/transaction-pool/Cargo.toml +++ b/test-utils/runtime/transaction-pool/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "substrate-test-runtime-transaction-pool" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false @@ -12,12 +12,12 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../client" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../client" } parking_lot = "0.10.0" -codec = { package = "parity-scale-codec", version = "1.3.0" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } -sc-transaction-graph = { version = "2.0.0-dev", path = "../../../client/transaction-pool/graph" } +codec = { package = "parity-scale-codec", version = "1.3.1" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../../primitives/transaction-pool" } +sc-transaction-graph = { version = "2.0.0-rc6", path = "../../../client/transaction-pool/graph" } futures = { version = "0.3.1", features = ["compat"] } derive_more = "0.99.2" diff --git a/test-utils/runtime/transaction-pool/src/lib.rs b/test-utils/runtime/transaction-pool/src/lib.rs index 432c9e520d1b178c0dc2567a35be82873d9ee687..f772ba9b02d5c129c2fef658e4890a0270bb0113 100644 --- a/test-utils/runtime/transaction-pool/src/lib.rs +++ b/test-utils/runtime/transaction-pool/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Test utils for the transaction pool together with the test runtime. //! @@ -22,17 +23,19 @@ use codec::Encode; use parking_lot::RwLock; use sp_runtime::{ generic::{self, BlockId}, - traits::{BlakeTwo256, Hash as HashT}, + traits::{BlakeTwo256, Hash as HashT, Block as _, Header as _}, transaction_validity::{ TransactionValidity, ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionSource, }, }; -use std::collections::{HashSet, HashMap}; +use std::collections::{HashSet, HashMap, BTreeMap}; use substrate_test_runtime_client::{ runtime::{Index, AccountId, Block, BlockNumber, Extrinsic, Hash, Header, Transfer}, AccountKeyring::{self, *}, }; +use sp_blockchain::CachedHeaderMetadata; +use futures::future::ready; /// Error type used by [`TestApi`]. #[derive(Debug, derive_more::From, derive_more::Display)] @@ -50,11 +53,31 @@ impl std::error::Error for Error { } } +pub enum IsBestBlock { + Yes, + No, +} + +impl IsBestBlock { + pub fn is_best(&self) -> bool { + matches!(self, Self::Yes) + } +} + +impl From for IsBestBlock { + fn from(is_best: bool) -> Self { + if is_best { + Self::Yes + } else { + Self::No + } + } +} + #[derive(Default)] pub struct ChainState { - pub block_by_number: HashMap>, - pub block_by_hash: HashMap>, - pub header_by_number: HashMap, + pub block_by_number: BTreeMap>, + pub block_by_hash: HashMap, pub nonces: HashMap, pub invalid_hashes: HashSet, } @@ -69,11 +92,7 @@ pub struct TestApi { impl TestApi { /// Test Api with Alice nonce set initially. pub fn with_alice_nonce(nonce: u64) -> Self { - let api = TestApi { - valid_modifier: RwLock::new(Box::new(|_| {})), - chain: Default::default(), - validation_requests: RwLock::new(Default::default()), - }; + let api = Self::empty(); api.chain.write().nonces.insert(Alice.into(), nonce); @@ -88,6 +107,9 @@ impl TestApi { validation_requests: RwLock::new(Default::default()), }; + // Push genesis block + api.push_block(0, Vec::new(), true); + api } @@ -96,49 +118,73 @@ impl TestApi { *self.valid_modifier.write() = modifier; } - /// Push block as a part of canonical chain under given number. - pub fn push_block(&self, block_number: BlockNumber, xts: Vec) -> Header { - let mut chain = self.chain.write(); - chain.block_by_number.insert(block_number, xts.clone()); - let header = Header { - number: block_number, - digest: Default::default(), - extrinsics_root: Default::default(), - parent_hash: block_number + /// Push block under given number. + pub fn push_block( + &self, + block_number: BlockNumber, + xts: Vec, + is_best_block: bool, + ) -> Header { + let parent_hash = { + let chain = self.chain.read(); + block_number .checked_sub(1) .and_then(|num| { - chain.header_by_number.get(&num) - .cloned().map(|h| h.hash()) - }).unwrap_or_default(), - state_root: Default::default(), + chain.block_by_number + .get(&num) + .map(|blocks| { + blocks[0].0.header.hash() + }) + }).unwrap_or_default() }; - chain.block_by_hash.insert(header.hash(), xts); - chain.header_by_number.insert(block_number, header.clone()); - header + + self.push_block_with_parent(parent_hash, xts, is_best_block) } - /// Push a block without a number. + /// Push a block using the given `parent`. /// - /// As a part of non-canonical chain. - pub fn push_fork_block(&self, block_hash: Hash, xts: Vec) { - let mut chain = self.chain.write(); - chain.block_by_hash.insert(block_hash, xts); - } + /// Panics if `parent` does not exists. + pub fn push_block_with_parent( + &self, + parent: Hash, + xts: Vec, + is_best_block: bool, + ) -> Header { + // `Hash::default()` is the genesis parent hash + let block_number = if parent == Hash::default() { + 0 + } else { + *self.chain.read() + .block_by_hash + .get(&parent) + .expect("`parent` exists") + .header() + .number() + 1 + }; - pub fn push_fork_block_with_parent(&self, parent: Hash, xts: Vec) -> Header { - let mut chain = self.chain.write(); - let blocknum = chain.block_by_number.keys().max().expect("block_by_number shouldn't be empty"); let header = Header { - number: *blocknum, + number: block_number, digest: Default::default(), - extrinsics_root: Default::default(), + extrinsics_root: Hash::random(), parent_hash: parent, state_root: Default::default(), }; - chain.block_by_hash.insert(header.hash(), xts); + + self.add_block(Block::new(header.clone(), xts), is_best_block); + header } + /// Add a block to the internal state. + pub fn add_block(&self, block: Block, is_best_block: bool) { + let hash = block.header.hash(); + let block_number = block.header.number().clone(); + + let mut chain = self.chain.write(); + chain.block_by_hash.insert(hash, block.clone()); + chain.block_by_number.entry(block_number).or_default().push((block, is_best_block.into())); + } + fn hash_and_length_inner(ex: &Extrinsic) -> (Hash, usize) { let encoded = ex.encode(); (BlakeTwo256::hash(&encoded), encoded.len()) @@ -169,33 +215,71 @@ impl TestApi { let mut chain = self.chain.write(); chain.nonces.entry(account).and_modify(|n| *n += 1).or_insert(1); } + + /// Calculate a tree route between the two given blocks. + pub fn tree_route( + &self, + from: Hash, + to: Hash, + ) -> Result, Error> { + sp_blockchain::tree_route(self, from, to) + } } impl sc_transaction_graph::ChainApi for TestApi { type Block = Block; - type Hash = Hash; type Error = Error; type ValidationFuture = futures::future::Ready>; type BodyFuture = futures::future::Ready>, Error>>; fn validate_transaction( &self, - _at: &BlockId, + at: &BlockId, _source: TransactionSource, uxt: sc_transaction_graph::ExtrinsicFor, ) -> Self::ValidationFuture { self.validation_requests.write().push(uxt.clone()); - let chain_nonce = self.chain.read().nonces.get(&uxt.transfer().from).cloned().unwrap_or(0); - let requires = if chain_nonce == uxt.transfer().nonce { - vec![] + match self.block_id_to_number(at) { + Ok(Some(number)) => { + let found_best = self.chain + .read() + .block_by_number + .get(&number) + .map(|blocks| blocks.iter().any(|b| b.1.is_best())) + .unwrap_or(false); + + // If there is no best block, we don't know based on which block we should validate + // the transaction. (This is not required for this test function, but in real + // environment it would fail because of this). + if !found_best { + return ready(Ok( + Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(1)).into()) + )) + } + }, + Ok(None) => return ready(Ok( + Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(2)).into()) + )), + Err(e) => return ready(Err(e)), + } + + let (requires, provides) = if let Some(transfer) = uxt.try_transfer() { + let chain_nonce = self.chain.read().nonces.get(&transfer.from).cloned().unwrap_or(0); + let requires = if chain_nonce == transfer.nonce { + vec![] + } else { + vec![vec![chain_nonce as u8]] + }; + let provides = vec![vec![transfer.nonce as u8]]; + + (requires, provides) } else { - vec![vec![chain_nonce as u8]] + (Vec::new(), vec![uxt.encode()]) }; - let provides = vec![vec![uxt.transfer().nonce as u8]]; if self.chain.read().invalid_hashes.contains(&self.hash_and_length(&uxt).0) { - return futures::future::ready(Ok( + return ready(Ok( Err(TransactionValidityError::Invalid(InvalidTransaction::Custom(0)).into()) )) } @@ -210,14 +294,21 @@ impl sc_transaction_graph::ChainApi for TestApi { (self.valid_modifier.read())(&mut validity); - futures::future::ready(Ok(Ok(validity))) + ready(Ok(Ok(validity))) } fn block_id_to_number( &self, at: &BlockId, ) -> Result>, Error> { - Ok(Some(number_of(at))) + Ok(match at { + generic::BlockId::Hash(x) => self.chain + .read() + .block_by_hash + .get(x) + .map(|b| *b.header.number()), + generic::BlockId::Number(num) => Some(*num), + }) } fn block_id_to_hash( @@ -226,34 +317,60 @@ impl sc_transaction_graph::ChainApi for TestApi { ) -> Result>, Error> { Ok(match at { generic::BlockId::Hash(x) => Some(x.clone()), - generic::BlockId::Number(num) => { - self.chain.read() - .header_by_number.get(num) - .map(|h| h.hash()) - .or_else(|| Some(Default::default())) - }, + generic::BlockId::Number(num) => self.chain + .read() + .block_by_number + .get(num) + .and_then(|blocks| blocks.iter().find(|b| b.1.is_best()).map(|b| b.0.header().hash())), }) } fn hash_and_length( &self, ex: &sc_transaction_graph::ExtrinsicFor, - ) -> (Self::Hash, usize) { + ) -> (Hash, usize) { Self::hash_and_length_inner(ex) } fn block_body(&self, id: &BlockId) -> Self::BodyFuture { futures::future::ready(Ok(match id { - BlockId::Number(num) => self.chain.read().block_by_number.get(num).cloned(), - BlockId::Hash(hash) => self.chain.read().block_by_hash.get(hash).cloned(), + BlockId::Number(num) => self.chain + .read() + .block_by_number + .get(num) + .map(|b| b[0].0.extrinsics().to_vec()), + BlockId::Hash(hash) => self.chain + .read() + .block_by_hash + .get(hash) + .map(|b| b.extrinsics().to_vec()), })) } } -fn number_of(at: &BlockId) -> u64 { - match at { - generic::BlockId::Number(n) => *n as u64, - _ => 0, +impl sp_blockchain::HeaderMetadata for TestApi { + type Error = Error; + + fn header_metadata( + &self, + hash: Hash, + ) -> Result, Self::Error> { + let chain = self.chain.read(); + let block = chain.block_by_hash.get(&hash).expect("Hash exists"); + + Ok(block.header().into()) + } + + fn insert_header_metadata( + &self, + _: Hash, + _: CachedHeaderMetadata, + ) { + unimplemented!("Not implemented for tests") + } + + fn remove_header_metadata(&self, _: Hash) { + unimplemented!("Not implemented for tests") } } @@ -270,4 +387,3 @@ pub fn uxt(who: AccountKeyring, nonce: Index) -> Extrinsic { let signature = transfer.using_encoded(|e| who.sign(e)).into(); Extrinsic::Transfer { transfer, signature, exhaust_resources_when_not_first: false } } - diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index c1a18a1fa7a3bce7a8ede30b7d3750323a736183..224eacd5129e39c7b79b75bddf65d70cbed2e38e 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -1,21 +1,45 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Test utils +#[doc(hidden)] +pub use futures; +/// Marks async function to be executed by an async runtime and provide a `TaskExecutor`, suitable +/// to test environment. +/// +/// # Requirements +/// +/// You must have tokio in the `[dev-dependencies]` of your crate to use this macro. +/// +/// # Example +/// +/// ``` +/// #[substrate_test_utils::test] +/// async fn basic_test(task_executor: TaskExecutor) { +/// assert!(true); +/// // create your node in here and use task_executor +/// // then don't forget to gracefully shutdown your node before exit +/// } +/// ``` +pub use substrate_test_utils_derive::test; +#[doc(hidden)] +pub use tokio; + /// Panic when the vectors are different, without taking the order into account. /// /// # Examples @@ -37,7 +61,7 @@ /// ``` #[macro_export] macro_rules! assert_eq_uvec { - ( $x:expr, $y:expr ) => { + ( $x:expr, $y:expr $(,)? ) => { $crate::__assert_eq_uvec!($x, $y); $crate::__assert_eq_uvec!($y, $x); } diff --git a/test-utils/test-crate/Cargo.toml b/test-utils/test-crate/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..cf7f28151874efe9e6b71a10df51668b4b23068f --- /dev/null +++ b/test-utils/test-crate/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "substrate-test-utils-test-crate" +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +publish = false + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dev-dependencies] +tokio = { version = "0.2.13", features = ["macros"] } +test-utils = { version = "2.0.0-rc6", path = "..", package = "substrate-test-utils" } +sc-service = { version = "0.8.0-rc6", path = "../../client/service" } diff --git a/test-utils/test-crate/src/main.rs b/test-utils/test-crate/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..209f29f76132d4e7a436d7551b2e18d4a0a83b5d --- /dev/null +++ b/test-utils/test-crate/src/main.rs @@ -0,0 +1,25 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +#[cfg(test)] +#[test_utils::test] +async fn basic_test(_: sc_service::TaskExecutor) { + assert!(true); +} + +fn main() {} diff --git a/test-utils/tests/basic.rs b/test-utils/tests/basic.rs new file mode 100644 index 0000000000000000000000000000000000000000..3e96bfe83d3a77805cc5acdd3f4ade4db55bdb7f --- /dev/null +++ b/test-utils/tests/basic.rs @@ -0,0 +1,58 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use sc_service::{TaskExecutor, TaskType}; + +#[substrate_test_utils::test] +async fn basic_test(_: TaskExecutor) { + assert!(true); +} + +#[substrate_test_utils::test] +#[should_panic(expected = "boo!")] +async fn panicking_test(_: TaskExecutor) { + panic!("boo!"); +} + +#[substrate_test_utils::test(max_threads = 2)] +async fn basic_test_with_args(_: TaskExecutor) { + assert!(true); +} + +#[substrate_test_utils::test] +async fn rename_argument(ex: TaskExecutor) { + let ex2 = ex.clone(); + ex2.spawn(Box::pin(async { () }), TaskType::Blocking); + assert!(true); +} + +#[substrate_test_utils::test] +#[should_panic(expected = "test took too long")] +// NOTE: enable this test only after setting SUBSTRATE_TEST_TIMEOUT to a smaller value +// +// SUBSTRATE_TEST_TIMEOUT=1 cargo test -- --ignored timeout +#[ignore] +async fn timeout(_: TaskExecutor) { + tokio::time::delay_for(std::time::Duration::from_secs( + std::env::var("SUBSTRATE_TEST_TIMEOUT") + .expect("env var SUBSTRATE_TEST_TIMEOUT has been provided by the user") + .parse::() + .unwrap() + 1, + )) + .await; +} diff --git a/test-utils/tests/ui.rs b/test-utils/tests/ui.rs new file mode 100644 index 0000000000000000000000000000000000000000..1f3b466c7dd6ed55ff35c12c496f825bed77d908 --- /dev/null +++ b/test-utils/tests/ui.rs @@ -0,0 +1,24 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +#[test] +fn substrate_test_utils_derive_trybuild() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/missing-func-parameter.rs"); + t.compile_fail("tests/ui/too-many-func-parameters.rs"); +} diff --git a/test-utils/tests/ui/missing-func-parameter.rs b/test-utils/tests/ui/missing-func-parameter.rs new file mode 100644 index 0000000000000000000000000000000000000000..bd34a76902ef9f4eea4f6bff3708d006bc0a6535 --- /dev/null +++ b/test-utils/tests/ui/missing-func-parameter.rs @@ -0,0 +1,24 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +#[substrate_test_utils::test] +async fn missing_func_parameter() { + assert!(true); +} + +fn main() {} diff --git a/test-utils/tests/ui/missing-func-parameter.stderr b/test-utils/tests/ui/missing-func-parameter.stderr new file mode 100644 index 0000000000000000000000000000000000000000..fbe0bc69918e88321e01eaea9392b483be7b717c --- /dev/null +++ b/test-utils/tests/ui/missing-func-parameter.stderr @@ -0,0 +1,5 @@ +error: the test function accepts only one argument of type sc_service::TaskExecutor + --> $DIR/missing-func-parameter.rs:20:1 + | +20 | async fn missing_func_parameter() { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test-utils/tests/ui/too-many-func-parameters.rs b/test-utils/tests/ui/too-many-func-parameters.rs new file mode 100644 index 0000000000000000000000000000000000000000..9aeadc2a88430683670f0d70fcd4a288bbe84eff --- /dev/null +++ b/test-utils/tests/ui/too-many-func-parameters.rs @@ -0,0 +1,27 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +#[allow(unused_imports)] +use sc_service::TaskExecutor; + +#[substrate_test_utils::test] +async fn too_many_func_parameters(task_executor_1: TaskExecutor, task_executor_2: TaskExecutor) { + assert!(true); +} + +fn main() {} diff --git a/test-utils/tests/ui/too-many-func-parameters.stderr b/test-utils/tests/ui/too-many-func-parameters.stderr new file mode 100644 index 0000000000000000000000000000000000000000..e30bb4ed8ee8560940acca97e2e60c055e4a4593 --- /dev/null +++ b/test-utils/tests/ui/too-many-func-parameters.stderr @@ -0,0 +1,5 @@ +error: the test function accepts only one argument of type sc_service::TaskExecutor + --> $DIR/too-many-func-parameters.rs:23:1 + | +23 | async fn too_many_func_parameters(task_executor_1: TaskExecutor, task_executor_2: TaskExecutor) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/utils/browser/Cargo.toml b/utils/browser/Cargo.toml index 868f32e34ab3630077878eb0dea954a2bf5d62a9..085939ffdcf26d9f6a319ddf5973d0ff4776d901 100644 --- a/utils/browser/Cargo.toml +++ b/utils/browser/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "substrate-browser-utils" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Utilities for creating a browser light-client." edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -15,21 +15,19 @@ targets = ["x86_64-unknown-linux-gnu"] futures = { version = "0.3", features = ["compat"] } futures01 = { package = "futures", version = "0.1.29" } log = "0.4.8" -libp2p-wasm-ext = { version = "0.18.0", features = ["websocket"] } +libp2p-wasm-ext = { version = "0.21", features = ["websocket"] } console_error_panic_hook = "0.1.6" console_log = "0.1.2" js-sys = "0.3.34" wasm-bindgen = "0.2.57" wasm-bindgen-futures = "0.4.7" -kvdb-web = "0.5" -sp-database = { version = "2.0.0-dev", path = "../../primitives/database" } -sc-informant = { version = "0.8.0-dev", path = "../../client/informant" } -sc-service = { version = "0.8.0-dev", path = "../../client/service", default-features = false } -sc-network = { path = "../../client/network", version = "0.8.0-dev"} -sc-chain-spec = { path = "../../client/chain-spec", version = "2.0.0-dev"} +kvdb-web = "0.7" +sp-database = { version = "2.0.0-rc6", path = "../../primitives/database" } +sc-informant = { version = "0.8.0-rc6", path = "../../client/informant" } +sc-service = { version = "0.8.0-rc6", path = "../../client/service", default-features = false } +sc-network = { path = "../../client/network", version = "0.8.0-rc6"} +sc-chain-spec = { path = "../../client/chain-spec", version = "2.0.0-rc6"} -# Imported just for the `no_cc` feature -clear_on_drop = { version = "0.2.3", features = ["no_cc"] } # Imported just for the `wasm-bindgen` feature rand6 = { package = "rand", version = "0.6", features = ["wasm-bindgen"] } rand = { version = "0.7", features = ["wasm-bindgen"] } diff --git a/utils/browser/README.md b/utils/browser/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9718db58b37e9ae1c81b5b627fe27e51129cf418 --- /dev/null +++ b/utils/browser/README.md @@ -0,0 +1 @@ +License: Apache-2.0 \ No newline at end of file diff --git a/utils/browser/src/lib.rs b/utils/browser/src/lib.rs index 4281a23af197441a8e3024fe04f64f50e5fd632f..ffd0a134be19e687a8c6a744d7ce675f4860b038 100644 --- a/utils/browser/src/lib.rs +++ b/utils/browser/src/lib.rs @@ -1,31 +1,32 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use futures01::sync::mpsc as mpsc01; use log::{debug, info}; -use std::sync::Arc; use sc_network::config::TransportConfig; use sc_service::{ - AbstractService, RpcSession, Role, Configuration, + RpcSession, Role, Configuration, TaskManager, RpcHandlers, config::{DatabaseConfig, KeystoreConfig, NetworkConfiguration}, GenericChainSpec, RuntimeGenesis }; use wasm_bindgen::prelude::*; -use futures::{prelude::*, channel::{oneshot, mpsc}, future::{poll_fn, ok}, compat::*}; -use std::task::Poll; +use futures::{ + prelude::*, channel::{oneshot, mpsc}, compat::*, future::{ready, ok, select} +}; use std::pin::Pin; use sc_chain_spec::Extension; use libp2p_wasm_ext::{ExtTransport, ffi}; @@ -63,7 +64,10 @@ where network, telemetry_endpoints: chain_spec.telemetry_endpoints().clone(), chain_spec: Box::new(chain_spec), - task_executor: Arc::new(move |fut, _| wasm_bindgen_futures::spawn_local(fut)), + task_executor: (|fut, _| { + wasm_bindgen_futures::spawn_local(fut); + async {} + }).into(), telemetry_external_transport: Some(transport), role: Role::Light, database: { @@ -78,13 +82,14 @@ where disable_grandpa: Default::default(), execution_strategies: Default::default(), force_authoring: Default::default(), - impl_name: "parity-substrate", - impl_version: "0.0.0", + impl_name: String::from("parity-substrate"), + impl_version: String::from("0.0.0"), offchain_worker: Default::default(), prometheus_config: Default::default(), pruning: Default::default(), rpc_cors: Default::default(), rpc_http: Default::default(), + rpc_ipc: Default::default(), rpc_ws: Default::default(), rpc_ws_max_connections: Default::default(), rpc_methods: Default::default(), @@ -96,6 +101,11 @@ where wasm_method: Default::default(), max_runtime_instances: 8, announce_block: true, + base_path: None, + informant_output_format: sc_informant::OutputFormat { + enable_color: false, + prefix: String::new(), + }, }; Ok(config) @@ -114,36 +124,25 @@ struct RpcMessage { } /// Create a Client object that connects to a service. -pub fn start_client(mut service: impl AbstractService) -> Client { - // Spawn informant - wasm_bindgen_futures::spawn_local( - sc_informant::build(&service, sc_informant::OutputFormat::Plain).map(drop) - ); - +pub fn start_client(mut task_manager: TaskManager, rpc_handlers: RpcHandlers) -> Client { // We dispatch a background task responsible for processing the service. // // The main action performed by the code below consists in polling the service with // `service.poll()`. // The rest consists in handling RPC requests. - let (rpc_send_tx, mut rpc_send_rx) = mpsc::unbounded::(); - wasm_bindgen_futures::spawn_local(poll_fn(move |cx| { - loop { - match Pin::new(&mut rpc_send_rx).poll_next(cx) { - Poll::Ready(Some(message)) => { - let fut = service - .rpc_query(&message.session, &message.rpc_json) - .boxed(); - let _ = message.send_back.send(fut); - }, - Poll::Pending => break, - Poll::Ready(None) => return Poll::Ready(()), - } - } - - Pin::new(&mut service) - .poll(cx) - .map(drop) - })); + let (rpc_send_tx, rpc_send_rx) = mpsc::unbounded::(); + wasm_bindgen_futures::spawn_local( + select( + rpc_send_rx.for_each(move |message| { + let fut = rpc_handlers.rpc_query(&message.session, &message.rpc_json); + let _ = message.send_back.send(fut); + ready(()) + }), + Box::pin(async move { + let _ = task_manager.future().await; + }), + ).map(drop) + ); Client { rpc_send_tx, diff --git a/utils/build-script-utils/Cargo.toml b/utils/build-script-utils/Cargo.toml index 89c584808ab50a11d0359c60780f0dd63ca55979..383f38bcb0b1263b16895c8a705152dafece3972 100644 --- a/utils/build-script-utils/Cargo.toml +++ b/utils/build-script-utils/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "substrate-build-script-utils" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Crate with utility functions for `build.rs` scripts." diff --git a/utils/build-script-utils/README.md b/utils/build-script-utils/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1c184f67326e3c3170b1a92767deffbdcbfa9c70 --- /dev/null +++ b/utils/build-script-utils/README.md @@ -0,0 +1,3 @@ +Crate with utility functions for `build.rs` scripts. + +License: Apache-2.0 \ No newline at end of file diff --git a/utils/build-script-utils/src/git.rs b/utils/build-script-utils/src/git.rs index 10f5446cb44f709e9208b89105d8246bf14ea23b..29c6a325fe7e929b757c365511af598ae1ac1713 100644 --- a/utils/build-script-utils/src/git.rs +++ b/utils/build-script-utils/src/git.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use std::{env, fs, fs::File, io, io::Read, path::PathBuf}; diff --git a/utils/build-script-utils/src/lib.rs b/utils/build-script-utils/src/lib.rs index 57a1e7c5cdb3e8cae406b4e6d49b1dbc8cc27fb6..512e6dcaefda71686d53825a7446fc0c1568be28 100644 --- a/utils/build-script-utils/src/lib.rs +++ b/utils/build-script-utils/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Crate with utility functions for `build.rs` scripts. diff --git a/utils/build-script-utils/src/version.rs b/utils/build-script-utils/src/version.rs index 01a97c6f383dde71f383cb0a9d5e617a380d0ac7..103fd5b1d24acff1f2ce77dd2a4b2a13387226ac 100644 --- a/utils/build-script-utils/src/version.rs +++ b/utils/build-script-utils/src/version.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use platforms::*; use std::{borrow::Cow, process::Command}; @@ -30,11 +31,11 @@ pub fn generate_cargo_keys() { } Ok(o) => { println!("cargo:warning=Git command failed with status: {}", o.status); - Cow::from("unknown-commit") + Cow::from("unknown") }, Err(err) => { println!("cargo:warning=Failed to execute git command: {}", err); - Cow::from("unknown-commit") + Cow::from("unknown") }, }; diff --git a/utils/fork-tree/Cargo.toml b/utils/fork-tree/Cargo.toml index c18826d16fe506ea506953189590b6389971279e..b02fee519df094b79949737221c394b48507c0e7 100644 --- a/utils/fork-tree/Cargo.toml +++ b/utils/fork-tree/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "fork-tree" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Utility library for managing tree-like ordered data with logic for pruning the tree while finalizing nodes." @@ -13,4 +13,4 @@ documentation = "https://docs.rs/fork-tree" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.1", features = ["derive"] } diff --git a/utils/fork-tree/README.md b/utils/fork-tree/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fef7db57f68f21ed590bc6df8e3a3444dc544476 --- /dev/null +++ b/utils/fork-tree/README.md @@ -0,0 +1,4 @@ +Utility library for managing tree-like ordered data with logic for pruning +the tree while finalizing nodes. + +License: Apache-2.0 \ No newline at end of file diff --git a/utils/fork-tree/src/lib.rs b/utils/fork-tree/src/lib.rs index be543e135f14510025df46504d7d7e7b0b53d9d6..1d01c53417649ac1d3df2802dbe43063ebf8c9e7 100644 --- a/utils/fork-tree/src/lib.rs +++ b/utils/fork-tree/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Utility library for managing tree-like ordered data with logic for pruning //! the tree while finalizing nodes. @@ -131,7 +132,7 @@ impl ForkTree where let mut root = root .expect("find_node_index_where will return array with at least one index; \ - this results in at least one item in removed; qed"); + this results in at least one item in removed; qed"); let mut removed = old_roots; diff --git a/utils/frame/benchmarking-cli/Cargo.toml b/utils/frame/benchmarking-cli/Cargo.toml index b02f42d7593fae6f38feab02be31022a0c56e499..0ecb3b883e82b78df9dcf50676e354feda48c7a4 100644 --- a/utils/frame/benchmarking-cli/Cargo.toml +++ b/utils/frame/benchmarking-cli/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "frame-benchmarking-cli" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "CLI for benchmarking FRAME" @@ -12,18 +12,18 @@ description = "CLI for benchmarking FRAME" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -frame-benchmarking = { version = "2.0.0-dev", path = "../../../frame/benchmarking" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sc-service = { version = "0.8.0-dev", default-features = false, path = "../../../client/service" } -sc-cli = { version = "0.8.0-dev", path = "../../../client/cli" } -sc-client-db = { version = "0.8.0-dev", path = "../../../client/db" } -sc-executor = { version = "0.8.0-dev", path = "../../../client/executor" } -sp-externalities = { version = "0.8.0-dev", path = "../../../primitives/externalities" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } +frame-benchmarking = { version = "2.0.0-rc6", path = "../../../frame/benchmarking" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sc-service = { version = "0.8.0-rc6", default-features = false, path = "../../../client/service" } +sc-cli = { version = "0.8.0-rc6", path = "../../../client/cli" } +sc-client-db = { version = "0.8.0-rc6", path = "../../../client/db" } +sc-executor = { version = "0.8.0-rc6", path = "../../../client/executor" } +sp-externalities = { version = "0.8.0-rc6", path = "../../../primitives/externalities" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../../primitives/state-machine" } structopt = "0.3.8" -codec = { version = "1.3.0", package = "parity-scale-codec" } +codec = { version = "1.3.1", package = "parity-scale-codec" } [features] default = ["db"] -db = ["sc-client-db/kvdb-rocksdb", "sc-client-db/parity-db"] +db = ["sc-client-db/with-kvdb-rocksdb", "sc-client-db/with-parity-db"] diff --git a/utils/frame/benchmarking-cli/README.md b/utils/frame/benchmarking-cli/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9718db58b37e9ae1c81b5b627fe27e51129cf418 --- /dev/null +++ b/utils/frame/benchmarking-cli/README.md @@ -0,0 +1 @@ +License: Apache-2.0 \ No newline at end of file diff --git a/utils/frame/benchmarking-cli/src/command.rs b/utils/frame/benchmarking-cli/src/command.rs index ebca380baff2db82c2f9598449f0bc6f78395e86..688e393bd605a5fc712df065b6719495fbde9ec6 100644 --- a/utils/frame/benchmarking-cli/src/command.rs +++ b/utils/frame/benchmarking-cli/src/command.rs @@ -1,32 +1,35 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use crate::BenchmarkCmd; use codec::{Decode, Encode}; -use frame_benchmarking::{Analysis, BenchmarkBatch}; +use frame_benchmarking::{Analysis, BenchmarkBatch, BenchmarkSelector}; use sc_cli::{SharedParams, CliConfiguration, ExecutionStrategy, Result}; use sc_client_db::BenchmarkingState; use sc_executor::NativeExecutor; use sp_state_machine::StateMachine; use sp_externalities::Extensions; use sc_service::{Configuration, NativeExecutionDispatch}; -use sp_runtime::{ - traits::{Block as BlockT, Header as HeaderT, NumberFor}, +use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor}; +use sp_core::{ + testing::KeyStore, + traits::KeystoreExt, + offchain::{OffchainExt, testing::TestOffchainExt}, }; -use sp_core::{tasks, testing::KeyStore, traits::KeystoreExt}; use std::fmt::Debug; impl BenchmarkCmd { @@ -49,12 +52,14 @@ impl BenchmarkCmd { let state = BenchmarkingState::::new(genesis_storage, cache_size)?; let executor = NativeExecutor::::new( wasm_method, - None, // heap pages + self.heap_pages, 2, // The runtime instances cache size. ); let mut extensions = Extensions::default(); extensions.register(KeystoreExt(KeyStore::new())); + let (offchain, _) = TestOffchainExt::new(); + extensions.register(OffchainExt::new(offchain)); let result = StateMachine::<_, _, NumberFor, _>::new( &state, @@ -70,10 +75,11 @@ impl BenchmarkCmd { self.highest_range_values.clone(), self.steps.clone(), self.repeat, + self.extra, ).encode(), extensions, &sp_state_machine::backend::BackendRuntimeCode::new(&state).runtime_code()?, - tasks::executor(), + sp_core::testing::TaskExecutor::new(), ) .execute(strategy.into()) .map_err(|e| format!("Error executing runtime benchmark: {:?}", e))?; @@ -82,46 +88,79 @@ impl BenchmarkCmd { .map_err(|e| format!("Failed to decode benchmark results: {:?}", e))?; match results { - Ok(batches) => for batch in batches.into_iter() { - // Print benchmark metadata - println!( - "Pallet: {:?}, Extrinsic: {:?}, Lowest values: {:?}, Highest values: {:?}, Steps: {:?}, Repeat: {:?}", - String::from_utf8(batch.pallet).expect("Encoded from String; qed"), - String::from_utf8(batch.benchmark).expect("Encoded from String; qed"), - self.lowest_range_values, - self.highest_range_values, - self.steps, - self.repeat, - ); - - // Skip raw data + analysis if there are no results - if batch.results.len() == 0 { continue } - - if self.raw_data { - // Print the table header - batch.results[0].0.iter().for_each(|param| print!("{:?},", param.0)); - - print!("extrinsic_time,storage_root_time\n"); - // Print the values - batch.results.iter().for_each(|result| { - let parameters = &result.0; - parameters.iter().for_each(|param| print!("{:?},", param.1)); - // Print extrinsic time and storage root time - print!("{:?},{:?}\n", result.1, result.2); - }); - - println!(); + Ok(batches) => { + // If we are going to output results to a file... + if self.output { + if self.weight_trait { + let mut file = crate::writer::open_file("traits.rs")?; + crate::writer::write_trait(&mut file, batches.clone())?; + } else { + crate::writer::write_results(&batches)?; + } } - // Conduct analysis. - if !self.no_median_slopes { - if let Some(analysis) = Analysis::median_slopes(&batch.results) { - println!("Median Slopes Analysis\n========\n{}", analysis); + for batch in batches.into_iter() { + // Print benchmark metadata + println!( + "Pallet: {:?}, Extrinsic: {:?}, Lowest values: {:?}, Highest values: {:?}, Steps: {:?}, Repeat: {:?}", + String::from_utf8(batch.pallet).expect("Encoded from String; qed"), + String::from_utf8(batch.benchmark).expect("Encoded from String; qed"), + self.lowest_range_values, + self.highest_range_values, + self.steps, + self.repeat, + ); + + // Skip raw data + analysis if there are no results + if batch.results.is_empty() { continue } + + if self.raw_data { + // Print the table header + batch.results[0].components.iter().for_each(|param| print!("{:?},", param.0)); + + print!("extrinsic_time,storage_root_time,reads,repeat_reads,writes,repeat_writes\n"); + // Print the values + batch.results.iter().for_each(|result| { + let parameters = &result.components; + parameters.iter().for_each(|param| print!("{:?},", param.1)); + // Print extrinsic time and storage root time + print!("{:?},{:?},{:?},{:?},{:?},{:?}\n", + result.extrinsic_time, + result.storage_root_time, + result.reads, + result.repeat_reads, + result.writes, + result.repeat_writes, + ); + }); + + println!(); } - } - if !self.no_min_squares { - if let Some(analysis) = Analysis::min_squares_iqr(&batch.results) { - println!("Min Squares Analysis\n========\n{}", analysis); + + // Conduct analysis. + if !self.no_median_slopes { + println!("Median Slopes Analysis\n========"); + if let Some(analysis) = Analysis::median_slopes(&batch.results, BenchmarkSelector::ExtrinsicTime) { + println!("-- Extrinsic Time --\n{}", analysis); + } + if let Some(analysis) = Analysis::median_slopes(&batch.results, BenchmarkSelector::Reads) { + println!("Reads = {:?}", analysis); + } + if let Some(analysis) = Analysis::median_slopes(&batch.results, BenchmarkSelector::Writes) { + println!("Writes = {:?}", analysis); + } + } + if !self.no_min_squares { + println!("Min Squares Analysis\n========"); + if let Some(analysis) = Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::ExtrinsicTime) { + println!("-- Extrinsic Time --\n{}", analysis); + } + if let Some(analysis) = Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::Reads) { + println!("Reads = {:?}", analysis); + } + if let Some(analysis) = Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::Writes) { + println!("Writes = {:?}", analysis); + } } } }, diff --git a/utils/frame/benchmarking-cli/src/lib.rs b/utils/frame/benchmarking-cli/src/lib.rs index 96204d1ae576382feb3ac68ab9b5c26ed5a90d61..c2a228fc86aefeb8817f77979be8c8e14f1e3952 100644 --- a/utils/frame/benchmarking-cli/src/lib.rs +++ b/utils/frame/benchmarking-cli/src/lib.rs @@ -1,26 +1,28 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. mod command; +mod writer; use sc_cli::{ExecutionStrategy, WasmExecutionMethod}; use std::fmt::Debug; /// The `benchmark` command used to benchmark FRAME Pallets. -#[derive(Debug, structopt::StructOpt, Clone)] +#[derive(Debug, structopt::StructOpt)] pub struct BenchmarkCmd { /// Select a FRAME Pallet to benchmark, or `*` for all (in which case `extrinsic` must be `*`). #[structopt(short, long)] @@ -58,6 +60,22 @@ pub struct BenchmarkCmd { #[structopt(long)] pub no_min_squares: bool, + /// Output the benchmarks to a Rust file. + #[structopt(long)] + pub output: bool, + + /// Output the trait definition to a Rust file. + #[structopt(long)] + pub weight_trait: bool, + + /// Set the heap pages while running benchmarks. + #[structopt(long)] + pub heap_pages: Option, + + /// Display and run extra benchmarks that would otherwise not be needed for weight construction. + #[structopt(long)] + pub extra: bool, + #[allow(missing_docs)] #[structopt(flatten)] pub shared_params: sc_cli::SharedParams, diff --git a/utils/frame/benchmarking-cli/src/writer.rs b/utils/frame/benchmarking-cli/src/writer.rs new file mode 100644 index 0000000000000000000000000000000000000000..964c1bf5fc1125e456c00cbb6f343de6a6e6b7e6 --- /dev/null +++ b/utils/frame/benchmarking-cli/src/writer.rs @@ -0,0 +1,225 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +// Outputs benchmark results to Rust files that can be ingested by the runtime. + +use std::fs::{File, OpenOptions}; +use std::io::prelude::*; +use frame_benchmarking::{BenchmarkBatch, BenchmarkSelector, Analysis}; +use sp_runtime::traits::Zero; + +const VERSION: &'static str = env!("CARGO_PKG_VERSION"); + +pub fn open_file(path: &str) -> Result { + OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(path) +} + +pub fn write_trait(file: &mut File, batches: Vec) -> Result<(), std::io::Error> { + let mut current_pallet = Vec::::new(); + + // Skip writing if there are no batches + if batches.is_empty() { return Ok(()) } + + for batch in &batches { + // Skip writing if there are no results + if batch.results.is_empty() { continue } + + let pallet_string = String::from_utf8(batch.pallet.clone()).unwrap(); + let benchmark_string = String::from_utf8(batch.benchmark.clone()).unwrap(); + + // only create new trait definitions when we go to a new pallet + if batch.pallet != current_pallet { + if !current_pallet.is_empty() { + // close trait + write!(file, "}}\n")?; + } + + // trait wrapper + write!(file, "// {}\n", pallet_string)?; + write!(file, "pub trait WeightInfo {{\n")?; + + current_pallet = batch.pallet.clone() + } + + // function name + write!(file, "\tfn {}(", benchmark_string)?; + + // params + let components = &batch.results[0].components; + for component in components { + write!(file, "{:?}: u32, ", component.0)?; + } + // return value + write!(file, ") -> Weight;\n")?; + } + + // final close trait + write!(file, "}}\n")?; + + Ok(()) +} + +pub fn write_results(batches: &[BenchmarkBatch]) -> Result<(), std::io::Error> { + let mut current_pallet = Vec::::new(); + + // Skip writing if there are no batches + if batches.is_empty() { return Ok(()) } + + let mut batches_iter = batches.iter().peekable(); + + let first_pallet = String::from_utf8( + batches_iter.peek().expect("we checked that batches is not empty").pallet.clone() + ).unwrap(); + let mut file = open_file(&(first_pallet + ".rs"))?; + + + while let Some(batch) = batches_iter.next() { + // Skip writing if there are no results + if batch.results.is_empty() { continue } + + let pallet_string = String::from_utf8(batch.pallet.clone()).unwrap(); + let benchmark_string = String::from_utf8(batch.benchmark.clone()).unwrap(); + + // only create new trait definitions when we go to a new pallet + if batch.pallet != current_pallet { + // auto-generation note + write!( + file, + "//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {}\n\n", + VERSION, + )?; + + // allow statements + write!( + file, + "#![allow(unused_parens)]\n#![allow(unused_imports)]\n\n", + )?; + + // general imports + write!( + file, + "use frame_support::weights::{{Weight, constants::RocksDbWeight as DbWeight}};\n\n" + )?; + + // struct for weights + write!(file, "pub struct WeightInfo;\n")?; + + // trait wrapper + write!(file, "impl {}::WeightInfo for WeightInfo {{\n", pallet_string)?; + + current_pallet = batch.pallet.clone() + } + + // Analysis results + let extrinsic_time = Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::ExtrinsicTime).unwrap(); + let reads = Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::Reads).unwrap(); + let writes = Analysis::min_squares_iqr(&batch.results, BenchmarkSelector::Writes).unwrap(); + + // Analysis data may include components that are not used, this filters out anything whose value is zero. + let mut used_components = Vec::new(); + let mut used_extrinsic_time = Vec::new(); + let mut used_reads = Vec::new(); + let mut used_writes = Vec::new(); + extrinsic_time.slopes.iter().zip(extrinsic_time.names.iter()).for_each(|(slope, name)| { + if !slope.is_zero() { + if !used_components.contains(&name) { used_components.push(name); } + used_extrinsic_time.push((slope, name)); + } + }); + reads.slopes.iter().zip(reads.names.iter()).for_each(|(slope, name)| { + if !slope.is_zero() { + if !used_components.contains(&name) { used_components.push(name); } + used_reads.push((slope, name)); + } + }); + writes.slopes.iter().zip(writes.names.iter()).for_each(|(slope, name)| { + if !slope.is_zero() { + if !used_components.contains(&name) { used_components.push(name); } + used_writes.push((slope, name)); + } + }); + + let all_components = batch.results[0].components + .iter() + .map(|(name, _)| -> String { return name.to_string() }) + .collect::>(); + if all_components.len() != used_components.len() { + let mut unused_components = all_components; + unused_components.retain(|x| !used_components.contains(&x)); + write!(file, "\t// WARNING! Some components were not used: {:?}\n", unused_components)?; + } + + // function name + write!(file, "\tfn {}(", benchmark_string)?; + // params + for component in used_components { + write!(file, "{}: u32, ", component)?; + } + // return value + write!(file, ") -> Weight {{\n")?; + + write!(file, "\t\t({} as Weight)\n", extrinsic_time.base.saturating_mul(1000))?; + used_extrinsic_time.iter().try_for_each(|(slope, name)| -> Result<(), std::io::Error> { + write!(file, "\t\t\t.saturating_add(({} as Weight).saturating_mul({} as Weight))\n", + slope.saturating_mul(1000), + name, + ) + })?; + + if !reads.base.is_zero() { + write!(file, "\t\t\t.saturating_add(DbWeight::get().reads({} as Weight))\n", reads.base)?; + } + used_reads.iter().try_for_each(|(slope, name)| -> Result<(), std::io::Error> { + write!(file, "\t\t\t.saturating_add(DbWeight::get().reads(({} as Weight).saturating_mul({} as Weight)))\n", + slope, + name, + ) + })?; + + if !writes.base.is_zero() { + write!(file, "\t\t\t.saturating_add(DbWeight::get().writes({} as Weight))\n", writes.base)?; + } + used_writes.iter().try_for_each(|(slope, name)| -> Result<(), std::io::Error> { + write!(file, "\t\t\t.saturating_add(DbWeight::get().writes(({} as Weight).saturating_mul({} as Weight)))\n", + slope, + name, + ) + })?; + + // close function + write!(file, "\t}}\n")?; + + // Check if this is the end of the iterator + if let Some(next) = batches_iter.peek() { + // Next pallet is different than current pallet, so we close up the file and open a new one. + if next.pallet != current_pallet { + write!(file, "}}\n")?; + let next_pallet = String::from_utf8(next.pallet.clone()).unwrap(); + file = open_file(&(next_pallet + ".rs"))?; + } + } else { + // This is the end of the iterator, so we close up the final file. + write!(file, "}}\n")?; + } + } + + Ok(()) +} diff --git a/utils/frame/frame-utilities-cli/Cargo.toml b/utils/frame/frame-utilities-cli/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5be62eff0ab531ee21cebb3d30edc77ba4de8087 --- /dev/null +++ b/utils/frame/frame-utilities-cli/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "substrate-frame-cli" +version = "2.0.0-rc6" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "cli interface for FRAME" +documentation = "https://docs.rs/substrate-frame-cli" + +[dependencies] +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sc-cli = { version = "0.8.0-rc6", path = "../../../client/cli" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +structopt = "0.3.8" +frame-system = { version = "2.0.0-rc6", path = "../../../frame/system" } + +[dev-dependencies] + +[features] +default = [] diff --git a/utils/frame/frame-utilities-cli/README.md b/utils/frame/frame-utilities-cli/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b1e4f869af7580687e663c5bf2e3c89a1badd35a --- /dev/null +++ b/utils/frame/frame-utilities-cli/README.md @@ -0,0 +1,3 @@ +frame-system CLI utilities + +License: Apache-2.0 \ No newline at end of file diff --git a/utils/frame/frame-utilities-cli/src/lib.rs b/utils/frame/frame-utilities-cli/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..872cfc99a63dc13670c2f5ec2f1a66e300634e1d --- /dev/null +++ b/utils/frame/frame-utilities-cli/src/lib.rs @@ -0,0 +1,23 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! frame-system CLI utilities + +mod module_id; + +pub use module_id::ModuleIdCmd; + diff --git a/utils/frame/frame-utilities-cli/src/module_id.rs b/utils/frame/frame-utilities-cli/src/module_id.rs new file mode 100644 index 0000000000000000000000000000000000000000..cc76c70d0fa8e511c889377840202c403da26106 --- /dev/null +++ b/utils/frame/frame-utilities-cli/src/module_id.rs @@ -0,0 +1,94 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Implementation of the `moduleid` subcommand + +use sc_cli::{ + Error, utils::print_from_uri, CryptoSchemeFlag, + OutputTypeFlag, KeystoreParams, with_crypto_scheme, +}; +use sp_runtime::ModuleId; +use sp_runtime::traits::AccountIdConversion; +use sp_core::crypto::{Ss58Codec, Ss58AddressFormat}; +use std::convert::{TryInto, TryFrom}; +use structopt::StructOpt; + +/// The `moduleid` command +#[derive(Debug, StructOpt)] +#[structopt( + name = "moduleid", + about = "Inspect a module ID address" +)] +pub struct ModuleIdCmd { + /// The module ID used to derive the account + id: String, + + /// network address format + #[structopt( + long, + value_name = "NETWORK", + possible_values = &Ss58AddressFormat::all_names()[..], + parse(try_from_str = Ss58AddressFormat::try_from), + case_insensitive = true, + )] + pub network: Option, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub output_scheme: OutputTypeFlag, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub crypto_scheme: CryptoSchemeFlag, + + #[allow(missing_docs)] + #[structopt(flatten)] + pub keystore_params: KeystoreParams, +} + +impl ModuleIdCmd { + /// runs the command + pub fn run(&self) -> Result<(), Error> + where + R: frame_system::Trait, + R::AccountId: Ss58Codec, + { + if self.id.len() != 8 { + Err("a module id must be a string of 8 characters")? + } + let password = self.keystore_params.read_password()?; + + let id_fixed_array: [u8; 8] = self.id.as_bytes() + .try_into() + .map_err(|_| "Cannot convert argument to moduleid: argument should be 8-character string")?; + + let account_id: R::AccountId = ModuleId(id_fixed_array).into_account(); + + with_crypto_scheme!( + self.crypto_scheme.scheme, + print_from_uri( + &account_id.to_ss58check_with_version(self.network.clone().unwrap_or_default()), + password, + self.network, + self.output_scheme.output_type.clone() + ) + ); + + Ok(()) + } +} + diff --git a/utils/frame/rpc/support/Cargo.toml b/utils/frame/rpc/support/Cargo.toml index c635471bb930476ef84e0f84dafa31f6e43b2489..784fe90cdf304f3e7865fa8e6158e54c1038776d 100644 --- a/utils/frame/rpc/support/Cargo.toml +++ b/utils/frame/rpc/support/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "substrate-frame-rpc-support" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies ", "Andrew Dirksen "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate RPC for FRAME's support" @@ -13,14 +13,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] futures = { version = "0.3.0", features = ["compat"] } -jsonrpc-client-transports = { version = "14.0.5", default-features = false, features = ["http"] } -jsonrpc-core = "14" -codec = { package = "parity-scale-codec", version = "1" } +jsonrpc-client-transports = { version = "14.2.0", default-features = false, features = ["http"] } +jsonrpc-core = "14.2.0" +codec = { package = "parity-scale-codec", version = "1.3.1" } serde = "1" -frame-support = { version = "2.0.0-dev", path = "../../../../frame/support" } -sp-storage = { version = "2.0.0-dev", path = "../../../../primitives/storage" } -sc-rpc-api = { version = "0.8.0-dev", path = "../../../../client/rpc-api" } +frame-support = { version = "2.0.0-rc6", path = "../../../../frame/support" } +sp-storage = { version = "2.0.0-rc6", path = "../../../../primitives/storage" } +sc-rpc-api = { version = "0.8.0-rc6", path = "../../../../client/rpc-api" } [dev-dependencies] -frame-system = { version = "2.0.0-dev", path = "../../../../frame/system" } +frame-system = { version = "2.0.0-rc6", path = "../../../../frame/system" } tokio = "0.2" diff --git a/utils/frame/rpc/support/README.md b/utils/frame/rpc/support/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ca5750612931ce385a2251b86a350afca5dd97da --- /dev/null +++ b/utils/frame/rpc/support/README.md @@ -0,0 +1,4 @@ +Combines [sc_rpc_api::state::StateClient] with [frame_support::storage::generator] traits +to provide strongly typed chain state queries over rpc. + +License: Apache-2.0 \ No newline at end of file diff --git a/utils/frame/rpc/support/src/lib.rs b/utils/frame/rpc/support/src/lib.rs index 118f5709a6b7044712002d851fc49dbbd2b5eb6a..dc87d6185209deba1c02a4f0f8abb3973f361199 100644 --- a/utils/frame/rpc/support/src/lib.rs +++ b/utils/frame/rpc/support/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Combines [sc_rpc_api::state::StateClient] with [frame_support::storage::generator] traits //! to provide strongly typed chain state queries over rpc. diff --git a/utils/frame/rpc/system/Cargo.toml b/utils/frame/rpc/system/Cargo.toml index 7d57e6b988234258db412d1e0280b131874199c5..0f1e27efc70377129bad04a0d4106e16d1506d9e 100644 --- a/utils/frame/rpc/system/Cargo.toml +++ b/utils/frame/rpc/system/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "substrate-frame-rpc-system" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME's system exposed over Substrate RPC" @@ -12,22 +12,24 @@ description = "FRAME's system exposed over Substrate RPC" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sc-client-api = { version = "2.0.0-dev", path = "../../../../client/api" } -codec = { package = "parity-scale-codec", version = "1.3.0" } +sc-client-api = { version = "2.0.0-rc6", path = "../../../../client/api" } +codec = { package = "parity-scale-codec", version = "1.3.1" } futures = { version = "0.3.4", features = ["compat"] } -jsonrpc-core = "14.0.3" -jsonrpc-core-client = "14.0.5" -jsonrpc-derive = "14.0.3" +jsonrpc-core = "14.2.0" +jsonrpc-core-client = "14.2.0" +jsonrpc-derive = "14.2.1" log = "0.4.8" serde = { version = "1.0.101", features = ["derive"] } -sp-runtime = { version = "2.0.0-dev", path = "../../../../primitives/runtime" } -sp-api = { version = "2.0.0-dev", path = "../../../../primitives/api" } -frame-system-rpc-runtime-api = { version = "2.0.0-dev", path = "../../../../frame/system/rpc/runtime-api" } -sp-core = { version = "2.0.0-dev", path = "../../../../primitives/core" } -sp-blockchain = { version = "2.0.0-dev", path = "../../../../primitives/blockchain" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../../../primitives/transaction-pool" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../../primitives/runtime" } +sp-api = { version = "2.0.0-rc6", path = "../../../../primitives/api" } +frame-system-rpc-runtime-api = { version = "2.0.0-rc6", path = "../../../../frame/system/rpc/runtime-api" } +sp-core = { version = "2.0.0-rc6", path = "../../../../primitives/core" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../../primitives/blockchain" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../../../primitives/transaction-pool" } +sp-block-builder = { version = "2.0.0-rc6", path = "../../../../primitives/block-builder" } +sc-rpc-api = { version = "0.8.0-rc6", path = "../../../../client/rpc-api" } [dev-dependencies] -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../../test-utils/runtime/client" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../../test-utils/runtime/client" } env_logger = "0.7.0" -sc-transaction-pool = { version = "2.0.0-dev", path = "../../../../client/transaction-pool" } +sc-transaction-pool = { version = "2.0.0-rc6", path = "../../../../client/transaction-pool" } diff --git a/utils/frame/rpc/system/README.md b/utils/frame/rpc/system/README.md new file mode 100644 index 0000000000000000000000000000000000000000..38986983d93c5b3794f93c56d50840de9a4ead18 --- /dev/null +++ b/utils/frame/rpc/system/README.md @@ -0,0 +1,3 @@ +System FRAME specific RPC methods. + +License: Apache-2.0 \ No newline at end of file diff --git a/utils/frame/rpc/system/src/lib.rs b/utils/frame/rpc/system/src/lib.rs index 8dff3a641d1edf435ef50853c0a32ca9ad45ff8d..2bb46369fea544437d086f36144770644baf568d 100644 --- a/utils/frame/rpc/system/src/lib.rs +++ b/utils/frame/rpc/system/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! System FRAME specific RPC methods. @@ -21,8 +22,8 @@ use std::sync::Arc; use codec::{self, Codec, Decode, Encode}; use sc_client_api::light::{future_header, RemoteBlockchain, Fetcher, RemoteCallRequest}; use jsonrpc_core::{ - Error, ErrorCode, - futures::future::{result, Future}, + Error as RpcError, ErrorCode, + futures::future::{self as rpc_future,result, Future}, }; use jsonrpc_derive::rpc; use futures::future::{ready, TryFutureExt}; @@ -34,18 +35,20 @@ use sp_runtime::{ generic::BlockId, traits, }; -use sp_core::hexdisplay::HexDisplay; +use sp_core::{hexdisplay::HexDisplay, Bytes}; use sp_transaction_pool::{TransactionPool, InPoolTransaction}; +use sp_block_builder::BlockBuilder; +use sc_rpc_api::DenyUnsafe; pub use frame_system_rpc_runtime_api::AccountNonceApi; pub use self::gen_client::Client as SystemClient; /// Future that resolves to account nonce. -pub type FutureResult = Box + Send>; +pub type FutureResult = Box + Send>; /// System RPC methods. #[rpc] -pub trait SystemApi { +pub trait SystemApi { /// Returns the next valid index (aka nonce) for given account. /// /// This method takes into consideration all pending transactions @@ -53,34 +56,57 @@ pub trait SystemApi { /// it fallbacks to query the index from the runtime (aka. state nonce). #[rpc(name = "system_accountNextIndex", alias("account_nextIndex"))] fn nonce(&self, account: AccountId) -> FutureResult; + + /// Dry run an extrinsic at a given block. Return SCALE encoded ApplyExtrinsicResult. + #[rpc(name = "system_dryRun", alias("system_dryRunAt"))] + fn dry_run(&self, extrinsic: Bytes, at: Option) -> FutureResult; } -const RUNTIME_ERROR: i64 = 1; +/// Error type of this RPC api. +pub enum Error { + /// The transaction was not decodable. + DecodeError, + /// The call to runtime failed. + RuntimeError, +} + +impl From for i64 { + fn from(e: Error) -> i64 { + match e { + Error::RuntimeError => 1, + Error::DecodeError => 2, + } + } +} /// An implementation of System-specific RPC methods on full client. pub struct FullSystem { client: Arc, pool: Arc

, + deny_unsafe: DenyUnsafe, _marker: std::marker::PhantomData, } impl FullSystem { /// Create new `FullSystem` given client and transaction pool. - pub fn new(client: Arc, pool: Arc

) -> Self { + pub fn new(client: Arc, pool: Arc

, deny_unsafe: DenyUnsafe,) -> Self { FullSystem { client, pool, + deny_unsafe, _marker: Default::default(), } } } -impl SystemApi for FullSystem +impl SystemApi<::Hash, AccountId, Index> + for FullSystem where C: sp_api::ProvideRuntimeApi, C: HeaderBackend, C: Send + Sync + 'static, C::Api: AccountNonceApi, + C::Api: BlockBuilder, P: TransactionPool + 'static, Block: traits::Block, AccountId: Clone + std::fmt::Display + Codec, @@ -92,8 +118,8 @@ where let best = self.client.info().best_hash; let at = BlockId::hash(best); - let nonce = api.account_nonce(&at, account.clone()).map_err(|e| Error { - code: ErrorCode::ServerError(RUNTIME_ERROR), + let nonce = api.account_nonce(&at, account.clone()).map_err(|e| RpcError { + code: ErrorCode::ServerError(Error::RuntimeError.into()), message: "Unable to query nonce.".into(), data: Some(format!("{:?}", e).into()), })?; @@ -103,6 +129,38 @@ where Box::new(result(get_nonce())) } + + fn dry_run(&self, extrinsic: Bytes, at: Option<::Hash>) -> FutureResult { + if let Err(err) = self.deny_unsafe.check_if_safe() { + return Box::new(rpc_future::err(err.into())); + } + + let dry_run = || { + let api = self.client.runtime_api(); + let at = BlockId::::hash(at.unwrap_or_else(|| + // If the block hash is not supplied assume the best block. + self.client.info().best_hash + )); + + let uxt: ::Extrinsic = Decode::decode(&mut &*extrinsic).map_err(|e| RpcError { + code: ErrorCode::ServerError(Error::DecodeError.into()), + message: "Unable to dry run extrinsic.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + let result = api.apply_extrinsic(&at, uxt) + .map_err(|e| RpcError { + code: ErrorCode::ServerError(Error::RuntimeError.into()), + message: "Unable to dry run extrinsic.".into(), + data: Some(format!("{:?}", e).into()), + })?; + + Ok(Encode::encode(&result).into()) + }; + + + Box::new(result(dry_run())) + } } /// An implementation of System-specific RPC methods on light client. @@ -130,7 +188,8 @@ impl LightSystem { } } -impl SystemApi for LightSystem +impl SystemApi<::Hash, AccountId, Index> + for LightSystem where P: TransactionPool + 'static, C: HeaderBackend, @@ -164,8 +223,8 @@ where ).compat(); let future_nonce = future_nonce.and_then(|nonce| Decode::decode(&mut &nonce[..]) .map_err(|e| ClientError::CallResultDecode("Cannot decode account nonce", e))); - let future_nonce = future_nonce.map_err(|e| Error { - code: ErrorCode::ServerError(RUNTIME_ERROR), + let future_nonce = future_nonce.map_err(|e| RpcError { + code: ErrorCode::ServerError(Error::RuntimeError.into()), message: "Unable to query nonce.".into(), data: Some(format!("{:?}", e).into()), }); @@ -175,6 +234,14 @@ where Box::new(future_nonce) } + + fn dry_run(&self, _extrinsic: Bytes, _at: Option<::Hash>) -> FutureResult { + Box::new(result(Err(RpcError { + code: ErrorCode::MethodNotFound, + message: "Unable to dry run extrinsic.".into(), + data: None, + }))) + } } /// Adjust account nonce from state, so that tx with the nonce will be @@ -196,7 +263,7 @@ fn adjust_nonce( // `provides` tag. And increment the nonce if we find a transaction // that matches the current one. let mut current_nonce = nonce.clone(); - let mut current_tag = (account.clone(), nonce.clone()).encode(); + let mut current_tag = (account.clone(), nonce).encode(); for tx in pool.ready() { log::debug!( target: "rpc", @@ -221,23 +288,22 @@ mod tests { use super::*; use futures::executor::block_on; - use substrate_test_runtime_client::{ - runtime::Transfer, - AccountKeyring, - }; - use sc_transaction_pool::{BasicPool, FullChainApi}; + use substrate_test_runtime_client::{runtime::Transfer, AccountKeyring}; + use sc_transaction_pool::BasicPool; + use sp_runtime::{ApplyExtrinsicResult, transaction_validity::{TransactionValidityError, InvalidTransaction}}; #[test] fn should_return_next_nonce_for_some_account() { - // given let _ = env_logger::try_init(); + + // given let client = Arc::new(substrate_test_runtime_client::new()); - let pool = Arc::new( - BasicPool::new( - Default::default(), - Arc::new(FullChainApi::new(client.clone())), - None, - ).0 + let spawner = sp_core::testing::TaskExecutor::new(); + let pool = BasicPool::new_full( + Default::default(), + None, + spawner, + client.clone(), ); let source = sp_runtime::transaction_validity::TransactionSource::External; @@ -256,7 +322,7 @@ mod tests { let ext1 = new_transaction(1); block_on(pool.submit_one(&BlockId::number(0), source, ext1)).unwrap(); - let accounts = FullSystem::new(client, pool); + let accounts = FullSystem::new(client, pool, DenyUnsafe::Yes); // when let nonce = accounts.nonce(AccountKeyring::Alice.into()); @@ -264,4 +330,91 @@ mod tests { // then assert_eq!(nonce.wait().unwrap(), 2); } + + #[test] + fn dry_run_should_deny_unsafe() { + let _ = env_logger::try_init(); + + // given + let client = Arc::new(substrate_test_runtime_client::new()); + let spawner = sp_core::testing::TaskExecutor::new(); + let pool = BasicPool::new_full( + Default::default(), + None, + spawner, + client.clone(), + ); + + let accounts = FullSystem::new(client, pool, DenyUnsafe::Yes); + + // when + let res = accounts.dry_run(vec![].into(), None); + + // then + assert_eq!(res.wait(), Err(RpcError::method_not_found())); + } + + #[test] + fn dry_run_should_work() { + let _ = env_logger::try_init(); + + // given + let client = Arc::new(substrate_test_runtime_client::new()); + let spawner = sp_core::testing::TaskExecutor::new(); + let pool = BasicPool::new_full( + Default::default(), + None, + spawner, + client.clone(), + ); + + let accounts = FullSystem::new(client, pool, DenyUnsafe::No); + + let tx = Transfer { + from: AccountKeyring::Alice.into(), + to: AccountKeyring::Bob.into(), + amount: 5, + nonce: 0, + }.into_signed_tx(); + + // when + let res = accounts.dry_run(tx.encode().into(), None); + + // then + let bytes = res.wait().unwrap().0; + let apply_res: ApplyExtrinsicResult = Decode::decode(&mut bytes.as_slice()).unwrap(); + assert_eq!(apply_res, Ok(Ok(()))); + } + + #[test] + fn dry_run_should_indicate_error() { + let _ = env_logger::try_init(); + + // given + let client = Arc::new(substrate_test_runtime_client::new()); + let spawner = sp_core::testing::TaskExecutor::new(); + let pool = BasicPool::new_full( + Default::default(), + None, + spawner, + client.clone(), + ); + + let accounts = FullSystem::new(client, pool, DenyUnsafe::No); + + let tx = Transfer { + from: AccountKeyring::Alice.into(), + to: AccountKeyring::Bob.into(), + amount: 5, + nonce: 100, + }.into_signed_tx(); + + // when + let res = accounts.dry_run(tx.encode().into(), None); + + // then + let bytes = res.wait().unwrap().0; + let apply_res: ApplyExtrinsicResult = Decode::decode(&mut bytes.as_slice()).unwrap(); + assert_eq!(apply_res, Err(TransactionValidityError::Invalid(InvalidTransaction::Stale))); + } } diff --git a/utils/prometheus/Cargo.toml b/utils/prometheus/Cargo.toml index 0b46540903159f86d4ece7774d76973750b505b6..4ed4575ccf70989d3a498c893cc6f4200f4f709c 100644 --- a/utils/prometheus/Cargo.toml +++ b/utils/prometheus/Cargo.toml @@ -1,8 +1,8 @@ [package] description = "Endpoint to expose Prometheus metrics" name = "substrate-prometheus-endpoint" -version = "0.8.0-dev" -license = "GPL-3.0" +version = "0.8.0-rc6" +license = "Apache-2.0" authors = ["Parity Technologies "] edition = "2018" homepage = "https://substrate.dev" @@ -13,11 +13,11 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] log = "0.4.8" -prometheus = "0.8" +prometheus = { version = "0.9", default-features = false } futures-util = { version = "0.3.1", default-features = false, features = ["io"] } derive_more = "0.99" [target.'cfg(not(target_os = "unknown"))'.dependencies] -async-std = { version = "1.0.1", features = ["unstable"] } +async-std = { version = "1.6.2", features = ["unstable"] } hyper = { version = "0.13.1", default-features = false, features = ["stream"] } tokio = "0.2" diff --git a/utils/prometheus/src/lib.rs b/utils/prometheus/src/lib.rs index 9030704cb746ffbb4fa9ebfe5f468751a67a28d2..be7050a8a07369ccf83db3a572bcec77e8a67521 100644 --- a/utils/prometheus/src/lib.rs +++ b/utils/prometheus/src/lib.rs @@ -31,6 +31,9 @@ use std::net::SocketAddr; #[cfg(not(target_os = "unknown"))] mod networking; +mod sourced; + +pub use sourced::{SourcedCounter, SourcedGauge, MetricSource}; #[cfg(target_os = "unknown")] pub use unknown_os::init_prometheus; diff --git a/utils/prometheus/src/networking.rs b/utils/prometheus/src/networking.rs index 5c8c036d4459761bde9055fc2b593d91a9e3a0af..92b9fedf6c79a9174b74362b7aa2e542722cb51c 100644 --- a/utils/prometheus/src/networking.rs +++ b/utils/prometheus/src/networking.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use async_std::pin::Pin; use std::task::{Poll, Context}; diff --git a/utils/prometheus/src/sourced.rs b/utils/prometheus/src/sourced.rs new file mode 100644 index 0000000000000000000000000000000000000000..58f60e4969bb8c8bd79b0a1c8c0ab6109feef83c --- /dev/null +++ b/utils/prometheus/src/sourced.rs @@ -0,0 +1,143 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Metrics that are collected from existing sources. + +use prometheus::core::{Collector, Desc, Describer, Number, Opts}; +use prometheus::proto; +use std::{cmp::Ordering, marker::PhantomData}; + +/// A counter whose values are obtained from an existing source. +/// +/// > **Note*: The counter values provided by the source `S` +/// > must be monotonically increasing. Otherwise use a +/// > [`SourcedGauge`] instead. +pub type SourcedCounter = SourcedMetric; + +/// A gauge whose values are obtained from an existing source. +pub type SourcedGauge = SourcedMetric; + +/// The type of a sourced counter. +#[derive(Copy, Clone)] +pub enum Counter {} + +/// The type of a sourced gauge. +#[derive(Copy, Clone)] +pub enum Gauge {} + +/// A metric whose values are obtained from an existing source, +/// instead of being independently recorded. +#[derive(Debug, Clone)] +pub struct SourcedMetric { + source: S, + desc: Desc, + _type: PhantomData, +} + +/// A source of values for a [`SourcedMetric`]. +pub trait MetricSource: Sync + Send + Clone { + /// The type of the collected values. + type N: Number; + /// Collects the current values of the metrics from the source. + fn collect(&self, set: impl FnMut(&[&str], Self::N)); +} + +impl SourcedMetric { + /// Creates a new metric that obtains its values from the given source. + pub fn new(opts: &Opts, source: S) -> prometheus::Result { + let desc = opts.describe()?; + Ok(Self { source, desc, _type: PhantomData }) + } +} + +impl Collector for SourcedMetric { + fn desc(&self) -> Vec<&Desc> { + vec![&self.desc] + } + + fn collect(&self) -> Vec { + let mut counters = Vec::new(); + + self.source.collect(|label_values, value| { + let mut m = proto::Metric::default(); + + match T::proto() { + proto::MetricType::COUNTER => { + let mut c = proto::Counter::default(); + c.set_value(value.into_f64()); + m.set_counter(c); + } + proto::MetricType::GAUGE => { + let mut g = proto::Gauge::default(); + g.set_value(value.into_f64()); + m.set_gauge(g); + } + t => { + log::error!("Unsupported sourced metric type: {:?}", t); + } + } + + debug_assert_eq!(self.desc.variable_labels.len(), label_values.len()); + match self.desc.variable_labels.len().cmp(&label_values.len()) { + Ordering::Greater => + log::warn!("Missing label values for sourced metric {}", self.desc.fq_name), + Ordering::Less => + log::warn!("Too many label values for sourced metric {}", self.desc.fq_name), + Ordering::Equal => {} + } + + m.set_label(self.desc.variable_labels.iter().zip(label_values) + .map(|(l_name, l_value)| { + let mut l = proto::LabelPair::default(); + l.set_name(l_name.to_string()); + l.set_value(l_value.to_string()); + l + }) + .chain(self.desc.const_label_pairs.iter().cloned()) + .collect::>()); + + counters.push(m); + }); + + let mut m = proto::MetricFamily::default(); + m.set_name(self.desc.fq_name.clone()); + m.set_help(self.desc.help.clone()); + m.set_field_type(T::proto()); + m.set_metric(counters); + + vec![m] + } +} + +/// Types of metrics that can obtain their values from an existing source. +pub trait SourcedType: private::Sealed + Sync + Send { + #[doc(hidden)] + fn proto() -> proto::MetricType; +} + +impl SourcedType for Counter { + fn proto() -> proto::MetricType { proto::MetricType::COUNTER } +} + +impl SourcedType for Gauge { + fn proto() -> proto::MetricType { proto::MetricType::GAUGE } +} + +mod private { + pub trait Sealed {} + impl Sealed for super::Counter {} + impl Sealed for super::Gauge {} +} diff --git a/utils/wasm-builder-runner/Cargo.toml b/utils/wasm-builder-runner/Cargo.toml index 75e55b35b47900d9762c4f8a6a6358a5d4f113c9..346807d2e97f41397279f25b2e4bb861bcf1cec0 100644 --- a/utils/wasm-builder-runner/Cargo.toml +++ b/utils/wasm-builder-runner/Cargo.toml @@ -6,7 +6,7 @@ description = "Runner for substrate-wasm-builder" edition = "2018" readme = "README.md" repository = "https://github.com/paritytech/substrate/" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" [package.metadata.docs.rs] diff --git a/utils/wasm-builder-runner/src/lib.rs b/utils/wasm-builder-runner/src/lib.rs index cea7d38641cd73fc1e0f9e80bf4b372d48c75dbb..7990ea2bb97d126fe8ac6065690db2b482a213f7 100644 --- a/utils/wasm-builder-runner/src/lib.rs +++ b/utils/wasm-builder-runner/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # WASM builder runner //! @@ -465,7 +466,7 @@ fn check_provide_dummy_wasm_binary() -> bool { fn provide_dummy_wasm_binary(file_path: &Path) { fs::write( file_path, - "pub const WASM_BINARY: &[u8] = &[]; pub const WASM_BINARY_BLOATY: &[u8] = &[];", + "pub const WASM_BINARY: Option<&[u8]> = None; pub const WASM_BINARY_BLOATY: Option<&[u8]> = None;", ).expect("Writing dummy WASM binary should not fail"); } diff --git a/utils/wasm-builder/Cargo.toml b/utils/wasm-builder/Cargo.toml index ca31cd159347d6cc9540dcd1ab137001a2b3e2fd..5e90625620508267e3928c999b0079f03d9a202a 100644 --- a/utils/wasm-builder/Cargo.toml +++ b/utils/wasm-builder/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "substrate-wasm-builder" -version = "1.0.10" +version = "2.0.0" authors = ["Parity Technologies "] description = "Utility for building WASM binaries" edition = "2018" readme = "README.md" repository = "https://github.com/paritytech/substrate/" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" [package.metadata.docs.rs] @@ -14,10 +14,10 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] build-helper = "0.1.1" -cargo_metadata = "0.9.0" +cargo_metadata = "0.10.0" tempfile = "3.1.0" toml = "0.5.4" -walkdir = "2.2.9" +walkdir = "2.3.1" fs2 = "0.4.3" wasm-gc-api = "0.1.11" atty = "0.2.13" diff --git a/utils/wasm-builder/README.md b/utils/wasm-builder/README.md index 5f4ca615d5065dca62e1d9c7d0463975c52acb2c..b72e7e16d4ff4110597e4f44119d571842b79e3e 100644 --- a/utils/wasm-builder/README.md +++ b/utils/wasm-builder/README.md @@ -1,11 +1,11 @@ -# WASM builder is a utility for building a project as a WASM binary +# Wasm builder is a utility for building a project as a Wasm binary -The WASM builder is a tool that integrates the process of building the WASM binary of your project into the main +The Wasm builder is a tool that integrates the process of building the WASM binary of your project into the main `cargo` build process. ## Project setup -A project that should be compiled as a WASM binary needs to: +A project that should be compiled as a Wasm binary needs to: 1. Add a `build.rs` file. 2. Add `substrate-wasm-builder` as dependency into `build-dependencies`. @@ -31,12 +31,20 @@ As the final step, you need to add the following to your project: include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); ``` -This will include the generated WASM binary as two constants `WASM_BINARY` and `WASM_BINARY_BLOATY`. -The former is a compact WASM binary and the latter is not compacted. +This will include the generated Wasm binary as two constants `WASM_BINARY` and `WASM_BINARY_BLOATY`. +The former is a compact Wasm binary and the latter is not compacted. + +### Feature + +Wasm builder supports to enable cargo features while building the Wasm binary. By default it will +enable all features in the wasm build that are enabled for the native build except the +`default` and `std` features. Besides that, wasm builder supports the special `runtime-wasm` +feature. This `runtime-wasm` feature will be enabled by the wasm builder when it compiles the +Wasm binary. If this feature is not present, it will not be enabled. ## Environment variables -By using environment variables, you can configure which WASM binaries are built and how: +By using environment variables, you can configure which Wasm binaries are built and how: - `SKIP_WASM_BUILD` - Skips building any wasm binary. This is useful when only native should be recompiled. - `BUILD_DUMMY_WASM_BINARY` - Builds dummy wasm binaries. These dummy binaries are empty and useful @@ -44,7 +52,7 @@ By using environment variables, you can configure which WASM binaries are built - `WASM_BUILD_TYPE` - Sets the build type for building wasm binaries. Supported values are `release` or `debug`. By default the build type is equal to the build type used by the main build. - `TRIGGER_WASM_BUILD` - Can be set to trigger a wasm build. On subsequent calls the value of the variable - needs to change. As WASM builder instructs `cargo` to watch for file changes + needs to change. As wasm builder instructs `cargo` to watch for file changes this environment variable should only be required in certain circumstances. - `WASM_BUILD_RUSTFLAGS` - Extend `RUSTFLAGS` given to `cargo build` while building the wasm binary. - `WASM_BUILD_NO_COLOR` - Disable color output of the wasm build. @@ -59,7 +67,7 @@ be `NODE_RUNTIME`. ## Prerequisites: -WASM builder requires the following prerequisites for building the WASM binary: +Wasm builder requires the following prerequisites for building the Wasm binary: - rust nightly + `wasm32-unknown-unknown` toolchain @@ -67,4 +75,4 @@ If a specific rust nightly is installed with `rustup`, it is important that the as well. For example if installing the rust nightly from 20.02.2020 using `rustup install nightly-2020-02-20`, the wasm target needs to be installed as well `rustup target add wasm32-unknown-unknown --toolchain nightly-2020-02-20`. -License: GPL-3.0 +License: Apache-2.0 diff --git a/utils/wasm-builder/src/lib.rs b/utils/wasm-builder/src/lib.rs index 195527a122725129e0a23058fe675dcc72e4320a..ab64db56fec3427466ca11407991f29628b7a555 100644 --- a/utils/wasm-builder/src/lib.rs +++ b/utils/wasm-builder/src/lib.rs @@ -1,27 +1,28 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! # WASM builder is a utility for building a project as a WASM binary +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! # Wasm builder is a utility for building a project as a Wasm binary //! -//! The WASM builder is a tool that integrates the process of building the WASM binary of your project into the main +//! The Wasm builder is a tool that integrates the process of building the WASM binary of your project into the main //! `cargo` build process. //! //! ## Project setup //! -//! A project that should be compiled as a WASM binary needs to: +//! A project that should be compiled as a Wasm binary needs to: //! //! 1. Add a `build.rs` file. //! 2. Add `substrate-wasm-builder` as dependency into `build-dependencies`. @@ -47,12 +48,20 @@ //! include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); //! ``` //! -//! This will include the generated WASM binary as two constants `WASM_BINARY` and `WASM_BINARY_BLOATY`. -//! The former is a compact WASM binary and the latter is not compacted. +//! This will include the generated Wasm binary as two constants `WASM_BINARY` and `WASM_BINARY_BLOATY`. +//! The former is a compact Wasm binary and the latter is not compacted. +//! +//! ### Feature +//! +//! Wasm builder supports to enable cargo features while building the Wasm binary. By default it will +//! enable all features in the wasm build that are enabled for the native build except the +//! `default` and `std` features. Besides that, wasm builder supports the special `runtime-wasm` +//! feature. This `runtime-wasm` feature will be enabled by the wasm builder when it compiles the +//! Wasm binary. If this feature is not present, it will not be enabled. //! //! ## Environment variables //! -//! By using environment variables, you can configure which WASM binaries are built and how: +//! By using environment variables, you can configure which Wasm binaries are built and how: //! //! - `SKIP_WASM_BUILD` - Skips building any wasm binary. This is useful when only native should be recompiled. //! - `BUILD_DUMMY_WASM_BINARY` - Builds dummy wasm binaries. These dummy binaries are empty and useful @@ -60,7 +69,7 @@ //! - `WASM_BUILD_TYPE` - Sets the build type for building wasm binaries. Supported values are `release` or `debug`. //! By default the build type is equal to the build type used by the main build. //! - `TRIGGER_WASM_BUILD` - Can be set to trigger a wasm build. On subsequent calls the value of the variable -//! needs to change. As WASM builder instructs `cargo` to watch for file changes +//! needs to change. As wasm builder instructs `cargo` to watch for file changes //! this environment variable should only be required in certain circumstances. //! - `WASM_BUILD_RUSTFLAGS` - Extend `RUSTFLAGS` given to `cargo build` while building the wasm binary. //! - `WASM_BUILD_NO_COLOR` - Disable color output of the wasm build. @@ -75,7 +84,7 @@ //! //! ## Prerequisites: //! -//! WASM builder requires the following prerequisites for building the WASM binary: +//! Wasm builder requires the following prerequisites for building the Wasm binary: //! //! - rust nightly + `wasm32-unknown-unknown` toolchain //! @@ -163,11 +172,11 @@ pub fn build_project_with_default_rustflags( file_name.into(), format!( r#" - pub const WASM_BINARY: &[u8] = include_bytes!("{wasm_binary}"); - pub const WASM_BINARY_BLOATY: &[u8] = include_bytes!("{wasm_binary_bloaty}"); + pub const WASM_BINARY: Option<&[u8]> = Some(include_bytes!("{wasm_binary}")); + pub const WASM_BINARY_BLOATY: Option<&[u8]> = Some(include_bytes!("{wasm_binary_bloaty}")); "#, - wasm_binary = wasm_binary.wasm_binary_path(), - wasm_binary_bloaty = bloaty.wasm_binary_bloaty_path(), + wasm_binary = wasm_binary.wasm_binary_path_escaped(), + wasm_binary_bloaty = bloaty.wasm_binary_bloaty_path_escaped(), ), ); } @@ -180,7 +189,18 @@ fn check_skip_build() -> bool { /// Write to the given `file` if the `content` is different. fn write_file_if_changed(file: PathBuf, content: String) { if fs::read_to_string(&file).ok().as_ref() != Some(&content) { - fs::write(&file, content).expect(&format!("Writing `{}` can not fail!", file.display())); + fs::write(&file, content).unwrap_or_else(|_| panic!("Writing `{}` can not fail!", file.display())); + } +} + +/// Copy `src` to `dst` if the `dst` does not exist or is different. +fn copy_file_if_changed(src: PathBuf, dst: PathBuf) { + let src_file = fs::read_to_string(&src).ok(); + let dst_file = fs::read_to_string(&dst).ok(); + + if src_file != dst_file { + fs::copy(&src, &dst) + .unwrap_or_else(|_| panic!("Copying `{}` to `{}` can not fail; qed", src.display(), dst.display())); } } diff --git a/utils/wasm-builder/src/prerequisites.rs b/utils/wasm-builder/src/prerequisites.rs index da118a71f98dae9da4243a2b3eaaff8e1aed8b69..d7c15095762e8a17ec8effab1e6da2e7ecc2572d 100644 --- a/utils/wasm-builder/src/prerequisites.rs +++ b/utils/wasm-builder/src/prerequisites.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use std::fs; diff --git a/utils/wasm-builder/src/wasm_project.rs b/utils/wasm-builder/src/wasm_project.rs index 6248f81935242ab4d43d5ded8e8cb52e34ee6059..6f8f47881b03fa83d01eda8ba54ad9d0eb1cc4fe 100644 --- a/utils/wasm-builder/src/wasm_project.rs +++ b/utils/wasm-builder/src/wasm_project.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use crate::write_file_if_changed; @@ -25,7 +26,7 @@ use toml::value::Table; use build_helper::rerun_if_changed; -use cargo_metadata::MetadataCommand; +use cargo_metadata::{MetadataCommand, Metadata}; use walkdir::WalkDir; @@ -37,9 +38,9 @@ use itertools::Itertools; pub struct WasmBinaryBloaty(PathBuf); impl WasmBinaryBloaty { - /// Returns the path to the bloaty wasm binary. - pub fn wasm_binary_bloaty_path(&self) -> String { - self.0.display().to_string().replace('\\', "/") + /// Returns the escaped path to the bloaty wasm binary. + pub fn wasm_binary_bloaty_path_escaped(&self) -> String { + self.0.display().to_string().escape_default().to_string() } } @@ -48,8 +49,13 @@ pub struct WasmBinary(PathBuf); impl WasmBinary { /// Returns the path to the wasm binary. - pub fn wasm_binary_path(&self) -> String { - self.0.display().to_string().replace('\\', "/") + pub fn wasm_binary_path(&self) -> &Path { + &self.0 + } + + /// Returns the escaped path to the wasm binary. + pub fn wasm_binary_path_escaped(&self) -> String { + self.0.display().to_string().escape_default().to_string() } } @@ -199,7 +205,7 @@ fn find_and_clear_workspace_members(wasm_workspace: &Path) -> Vec { .map(|d| d.into_path()) .filter(|p| p.is_dir()) .filter_map(|p| p.file_name().map(|f| f.to_owned()).and_then(|s| s.into_string().ok())) - .filter(|f| !f.starts_with(".") && f != "target") + .filter(|f| !f.starts_with('.') && f != "target") .collect::>(); let mut i = 0; @@ -296,10 +302,23 @@ fn create_wasm_workspace_project(wasm_workspace: &Path, workspace_root_path: &Pa wasm_workspace_toml.insert("patch".into(), patch.into()); } - fs::write( + write_file_if_changed( wasm_workspace.join("Cargo.toml"), toml::to_string_pretty(&wasm_workspace_toml).expect("Wasm workspace toml is valid; qed"), - ).expect("WASM workspace `Cargo.toml` writing can not fail; qed"); + ); +} + +/// Find a package by the given `manifest_path` in the metadata. +/// +/// Panics if the package could not be found. +fn find_package_by_manifest_path<'a>( + manifest_path: &Path, + crate_metadata: &'a cargo_metadata::Metadata, +) -> &'a cargo_metadata::Package { + crate_metadata.packages + .iter() + .find(|p| p.manifest_path == manifest_path) + .expect("Wasm project exists in its own metadata; qed") } /// Get a list of enabled features for the project. @@ -307,10 +326,7 @@ fn project_enabled_features( cargo_manifest: &Path, crate_metadata: &cargo_metadata::Metadata, ) -> Vec { - let package = crate_metadata.packages - .iter() - .find(|p| p.manifest_path == cargo_manifest) - .expect("Wasm project exists in its own metadata; qed"); + let package = find_package_by_manifest_path(cargo_manifest, crate_metadata); let mut enabled_features = package.features.keys() .filter(|f| { @@ -332,23 +348,34 @@ fn project_enabled_features( enabled_features } +/// Returns if the project has the `runtime-wasm` feature +fn has_runtime_wasm_feature_declared( + cargo_manifest: &Path, + crate_metadata: &cargo_metadata::Metadata, +) -> bool { + let package = find_package_by_manifest_path(cargo_manifest, crate_metadata); + + package.features.keys().any(|k| k == "runtime-wasm") +} + /// Create the project used to build the wasm binary. /// /// # Returns /// The path to the created project. -fn create_project( - cargo_manifest: &Path, - wasm_workspace: &Path, - crate_metadata: &cargo_metadata::Metadata, -) -> PathBuf { +fn create_project(cargo_manifest: &Path, wasm_workspace: &Path, crate_metadata: &Metadata) -> PathBuf { let crate_name = get_crate_name(cargo_manifest); let crate_path = cargo_manifest.parent().expect("Parent path exists; qed"); let wasm_binary = get_wasm_binary_name(cargo_manifest); let project_folder = wasm_workspace.join(&crate_name); - fs::create_dir_all(project_folder.join("src")).expect("Wasm project dir create can not fail; qed"); + fs::create_dir_all(project_folder.join("src")) + .expect("Wasm project dir create can not fail; qed"); - let enabled_features = project_enabled_features(&cargo_manifest, &crate_metadata); + let mut enabled_features = project_enabled_features(&cargo_manifest, &crate_metadata); + + if has_runtime_wasm_feature_declared(cargo_manifest, crate_metadata) { + enabled_features.push("runtime-wasm".into()); + } write_file_if_changed( project_folder.join("Cargo.toml"), @@ -380,8 +407,7 @@ fn create_project( if let Some(crate_lock_file) = find_cargo_lock(cargo_manifest) { // Use the `Cargo.lock` of the main project. - fs::copy(crate_lock_file, wasm_workspace.join("Cargo.lock")) - .expect("Copying the `Cargo.lock` can not fail; qed"); + crate::copy_file_if_changed(crate_lock_file, wasm_workspace.join("Cargo.lock")); } project_folder @@ -513,22 +539,33 @@ fn generate_rerun_if_changed_instructions( .exec() .expect("`cargo metadata` can not fail!"); - // Start with the dependencies of the crate we want to compile for wasm. - let mut dependencies = metadata.packages + let package = metadata.packages .iter() .find(|p| p.manifest_path == cargo_manifest) - .expect("The crate package is contained in its own metadata; qed") - .dependencies - .iter() - .collect::>(); + .expect("The crate package is contained in its own metadata; qed"); + + // Start with the dependencies of the crate we want to compile for wasm. + let mut dependencies = package.dependencies.iter().collect::>(); // Collect all packages by follow the dependencies of all packages we find. let mut packages = HashSet::new(); + packages.insert(DeduplicatePackage::from(package)); + while let Some(dependency) = dependencies.pop() { + let path_or_git_dep = dependency.source + .as_ref() + .map(|s| s.starts_with("git+")) + .unwrap_or(true); + let package = metadata.packages .iter() .filter(|p| !p.manifest_path.starts_with(wasm_workspace)) - .find(|p| dependency.req.matches(&p.version) && dependency.name == p.name); + .find(|p| { + // Check that the name matches and that the version matches or this is + // a git or path dep. A git or path dependency can only occur once, so we don't + // need to check the version. + (path_or_git_dep || dependency.req.matches(&p.version)) && dependency.name == p.name + }); if let Some(package) = package { if packages.insert(DeduplicatePackage::from(package)) { @@ -538,21 +575,7 @@ fn generate_rerun_if_changed_instructions( } // Make sure that if any file/folder of a dependency change, we need to rerun the `build.rs` - packages.into_iter() - .filter(|p| !p.manifest_path.starts_with(wasm_workspace)) - .for_each(|package| { - let mut manifest_path = package.manifest_path.clone(); - if manifest_path.ends_with("Cargo.toml") { - manifest_path.pop(); - } - - rerun_if_changed(&manifest_path); - - WalkDir::new(manifest_path) - .into_iter() - .filter_map(|p| p.ok()) - .for_each(|p| rerun_if_changed(p.path())); - }); + packages.iter().for_each(package_rerun_if_changed); // Register our env variables println!("cargo:rerun-if-env-changed={}", crate::SKIP_BUILD_ENV); @@ -562,8 +585,32 @@ fn generate_rerun_if_changed_instructions( println!("cargo:rerun-if-env-changed={}", crate::WASM_BUILD_TOOLCHAIN); } -/// Copy the WASM binary to the target directory set in `WASM_TARGET_DIRECTORY` environment variable. -/// If the variable is not set, this is a no-op. +/// Track files and paths related to the given package to rerun `build.rs` on any relevant change. +fn package_rerun_if_changed(package: &DeduplicatePackage) { + let mut manifest_path = package.manifest_path.clone(); + if manifest_path.ends_with("Cargo.toml") { + manifest_path.pop(); + } + + WalkDir::new(&manifest_path) + .into_iter() + .filter_entry(|p| { + // Ignore this entry if it is a directory that contains a `Cargo.toml` that is not the + // `Cargo.toml` related to the current package. This is done to ignore sub-crates of a crate. + // If such a sub-crate is a dependency, it will be processed independently anyway. + p.path() == manifest_path + || !p.path().is_dir() + || !p.path().join("Cargo.toml").exists() + }) + .filter_map(|p| p.ok().map(|p| p.into_path())) + .filter(|p| { + p.is_dir() || p.extension().map(|e| e == "rs" || e == "toml").unwrap_or_default() + }) + .for_each(|p| rerun_if_changed(p)); +} + +/// Copy the WASM binary to the target directory set in `WASM_TARGET_DIRECTORY` environment +/// variable. If the variable is not set, this is a no-op. fn copy_wasm_to_target_directory(cargo_manifest: &Path, wasm_binary: &WasmBinary) { let target_dir = match env::var(crate::WASM_TARGET_DIRECTORY) { Ok(path) => PathBuf::from(path),

::Upper; + /// Something that implements a fixed point ration with an arbitrary granularity `X`, as _parts per /// `X`_. pub trait PerThing: Sized + Saturating + Copy + Default + Eq + PartialEq + Ord + PartialOrd + Bounded + fmt::Debug { /// The data type used to build this per-thingy. - type Inner: BaseArithmetic + Copy + fmt::Debug; + type Inner: BaseArithmetic + Unsigned + Copy + fmt::Debug; /// A data type larger than `Self::Inner`, used to avoid overflow in some computations. /// It must be able to compute `ACCURACY^2`. - type Upper: BaseArithmetic + Copy + From + TryInto + fmt::Debug; + type Upper: + BaseArithmetic + Copy + From + TryInto + + UniqueSaturatedInto + Unsigned + fmt::Debug; /// The accuracy of this type. const ACCURACY: Self::Inner; @@ -85,7 +94,7 @@ pub trait PerThing: /// ``` fn mul_floor(self, b: N) -> N where N: Clone + From + UniqueSaturatedInto + ops::Rem + - ops::Div + ops::Mul + ops::Add + ops::Div + ops::Mul + ops::Add + Unsigned { overflow_prune_mul::(b, self.deconstruct(), Rounding::Down) } @@ -107,7 +116,7 @@ pub trait PerThing: /// ``` fn mul_ceil(self, b: N) -> N where N: Clone + From + UniqueSaturatedInto + ops::Rem + - ops::Div + ops::Mul + ops::Add + ops::Div + ops::Mul + ops::Add + Unsigned { overflow_prune_mul::(b, self.deconstruct(), Rounding::Up) } @@ -123,7 +132,8 @@ pub trait PerThing: /// ``` fn saturating_reciprocal_mul(self, b: N) -> N where N: Clone + From + UniqueSaturatedInto + ops::Rem + - ops::Div + ops::Mul + ops::Add + Saturating + ops::Div + ops::Mul + ops::Add + Saturating + + Unsigned { saturating_reciprocal_mul::(b, self.deconstruct(), Rounding::Nearest) } @@ -142,7 +152,8 @@ pub trait PerThing: /// ``` fn saturating_reciprocal_mul_floor(self, b: N) -> N where N: Clone + From + UniqueSaturatedInto + ops::Rem + - ops::Div + ops::Mul + ops::Add + Saturating + ops::Div + ops::Mul + ops::Add + Saturating + + Unsigned { saturating_reciprocal_mul::(b, self.deconstruct(), Rounding::Down) } @@ -161,7 +172,8 @@ pub trait PerThing: /// ``` fn saturating_reciprocal_mul_ceil(self, b: N) -> N where N: Clone + From + UniqueSaturatedInto + ops::Rem + - ops::Div + ops::Mul + ops::Add + Saturating + ops::Div + ops::Mul + ops::Add + Saturating + + Unsigned { saturating_reciprocal_mul::(b, self.deconstruct(), Rounding::Up) } @@ -189,14 +201,14 @@ pub trait PerThing: /// # fn main () { /// // 989/100 is technically closer to 99%. /// assert_eq!( - /// Percent::from_rational_approximation(989, 1000), + /// Percent::from_rational_approximation(989u64, 1000), /// Percent::from_parts(98), /// ); /// # } /// ``` fn from_rational_approximation(p: N, q: N) -> Self where N: Clone + Ord + From + TryInto + TryInto + - ops::Div + ops::Rem + ops::Add; + ops::Div + ops::Rem + ops::Add + Unsigned; } /// The rounding method to use. @@ -218,7 +230,7 @@ fn saturating_reciprocal_mul( ) -> N where N: Clone + From + UniqueSaturatedInto + ops::Div + ops::Mul + ops::Add + ops::Rem + Saturating, + Output=N> + ops::Add + ops::Rem + Saturating + Unsigned, P: PerThing, { let maximum: N = P::ACCURACY.into(); @@ -239,7 +251,7 @@ fn overflow_prune_mul( ) -> N where N: Clone + From + UniqueSaturatedInto + ops::Div + ops::Mul + ops::Add + ops::Rem, + Output=N> + ops::Add + ops::Rem + Unsigned, P: PerThing, { let maximum: N = P::ACCURACY.into(); @@ -265,7 +277,7 @@ fn rational_mul_correction( ) -> N where N: From + UniqueSaturatedInto + ops::Div + ops::Mul + ops::Add + ops::Rem, + Output=N> + ops::Add + ops::Rem + Unsigned, P: PerThing, { let numer_upper = P::Upper::from(numer); @@ -311,8 +323,7 @@ macro_rules! implement_per_thing { /// #[doc = $title] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] - #[derive(Encode, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, - RuntimeDebug, CompactAs)] + #[derive(Encode, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RuntimeDebug, CompactAs)] pub struct $name($type); impl PerThing for $name { @@ -327,14 +338,15 @@ macro_rules! implement_per_thing { /// Build this type from a number of parts per thing. fn from_parts(parts: Self::Inner) -> Self { Self(parts.min($max)) } + /// NOTE: saturate to 0 or 1 if x is beyond `[0, 1]` #[cfg(feature = "std")] fn from_fraction(x: f64) -> Self { - Self::from_parts((x * $max as f64) as Self::Inner) + Self::from_parts((x.max(0.).min(1.) * $max as f64) as Self::Inner) } fn from_rational_approximation(p: N, q: N) -> Self where N: Clone + Ord + From + TryInto + TryInto - + ops::Div + ops::Rem + ops::Add + + ops::Div + ops::Rem + ops::Add + Unsigned { let div_ceil = |x: N, f: N| -> N { let mut o = x.clone() / f.clone(); @@ -382,7 +394,6 @@ macro_rules! implement_per_thing { impl $name { /// From an explicitly defined number of parts per maximum of the type. /// - /// This can be called at compile time. // needed only for peru16. Since peru16 is the only type in which $max == // $type::max_value(), rustc is being a smart-a** here by warning that the comparison // is not needed. @@ -398,9 +409,9 @@ macro_rules! implement_per_thing { Self(([x, 100][(x > 100) as usize] as $upper_type * $max as $upper_type / 100) as $type) } - /// See [`PerThing::one`]. - pub fn one() -> Self { - ::one() + /// See [`PerThing::one`] + pub const fn one() -> Self { + Self::from_parts($max) } /// See [`PerThing::is_one`]. @@ -409,8 +420,8 @@ macro_rules! implement_per_thing { } /// See [`PerThing::zero`]. - pub fn zero() -> Self { - ::zero() + pub const fn zero() -> Self { + Self::from_parts(0) } /// See [`PerThing::is_zero`]. @@ -419,8 +430,8 @@ macro_rules! implement_per_thing { } /// See [`PerThing::deconstruct`]. - pub fn deconstruct(self) -> $type { - PerThing::deconstruct(self) + pub const fn deconstruct(self) -> $type { + self.0 } /// See [`PerThing::square`]. @@ -438,7 +449,8 @@ macro_rules! implement_per_thing { pub fn from_rational_approximation(p: N, q: N) -> Self where N: Clone + Ord + From<$type> + TryInto<$type> + TryInto<$upper_type> + ops::Div + ops::Rem + - ops::Add { + ops::Add + Unsigned + { ::from_rational_approximation(p, q) } @@ -446,7 +458,8 @@ macro_rules! implement_per_thing { pub fn mul_floor(self, b: N) -> N where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + ops::Div + ops::Mul + - ops::Add { + ops::Add + Unsigned + { PerThing::mul_floor(self, b) } @@ -454,7 +467,8 @@ macro_rules! implement_per_thing { pub fn mul_ceil(self, b: N) -> N where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + ops::Div + ops::Mul + - ops::Add { + ops::Add + Unsigned + { PerThing::mul_ceil(self, b) } @@ -462,7 +476,8 @@ macro_rules! implement_per_thing { pub fn saturating_reciprocal_mul(self, b: N) -> N where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + ops::Div + ops::Mul + ops::Add + - Saturating { + Saturating + Unsigned + { PerThing::saturating_reciprocal_mul(self, b) } @@ -470,7 +485,8 @@ macro_rules! implement_per_thing { pub fn saturating_reciprocal_mul_floor(self, b: N) -> N where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + ops::Div + ops::Mul + ops::Add + - Saturating { + Saturating + Unsigned + { PerThing::saturating_reciprocal_mul_floor(self, b) } @@ -478,7 +494,8 @@ macro_rules! implement_per_thing { pub fn saturating_reciprocal_mul_ceil(self, b: N) -> N where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem + ops::Div + ops::Mul + ops::Add + - Saturating { + Saturating + Unsigned + { PerThing::saturating_reciprocal_mul_ceil(self, b) } } @@ -566,13 +583,19 @@ macro_rules! implement_per_thing { } } + impl Default for $name { + fn default() -> Self { + ::zero() + } + } + /// Non-overflow multiplication. /// /// This is tailored to be used with a balance type. impl ops::Mul for $name where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem - + ops::Div + ops::Mul + ops::Add, + + ops::Div + ops::Mul + ops::Add + Unsigned, { type Output = N; fn mul(self, b: N) -> Self::Output { @@ -671,6 +694,8 @@ macro_rules! implement_per_thing { assert_eq!($name::from_fraction(0.0), $name::from_parts(Zero::zero())); assert_eq!($name::from_fraction(0.1), $name::from_parts($max / 10)); assert_eq!($name::from_fraction(1.0), $name::from_parts($max)); + assert_eq!($name::from_fraction(2.0), $name::from_parts($max)); + assert_eq!($name::from_fraction(-1.0), $name::from_parts(Zero::zero())); } macro_rules! u256ify { @@ -1129,10 +1154,67 @@ macro_rules! implement_per_thing { 1, ); } + + #[test] + #[allow(unused)] + fn const_fns_work() { + const C1: $name = $name::from_percent(50); + const C2: $name = $name::one(); + const C3: $name = $name::zero(); + const C4: $name = $name::from_parts(1); + + // deconstruct is also const, hence it can be called in const rhs. + const C5: bool = C1.deconstruct() == 0; + } } }; } +macro_rules! implement_per_thing_with_perthousand { + ( + $name:ident, + $test_mod:ident, + $pt_test_mod:ident, + [$($test_units:tt),+], + $max:tt, + $type:ty, + $upper_type:ty, + $title:expr $(,)? + ) => { + implement_per_thing! { + $name, $test_mod, [ $( $test_units ),+ ], $max, $type, $upper_type, $title, + } + impl $name { + /// Converts a percent into `Self`. Equal to `x / 1000`. + /// + /// This can be created at compile time. + pub const fn from_perthousand(x: $type) -> Self { + Self(([x, 1000][(x > 1000) as usize] as $upper_type * $max as $upper_type / 1000) as $type) + } + } + #[cfg(test)] + mod $pt_test_mod { + use super::$name; + use crate::traits::Zero; + + #[test] + fn from_perthousand_works() { + // some really basic stuff + assert_eq!($name::from_perthousand(00), $name::from_parts(Zero::zero())); + assert_eq!($name::from_perthousand(100), $name::from_parts($max / 10)); + assert_eq!($name::from_perthousand(1000), $name::from_parts($max)); + assert_eq!($name::from_perthousand(2000), $name::from_parts($max)); + } + + #[test] + #[allow(unused)] + fn const_fns_work() { + const C1: $name = $name::from_perthousand(500); + } + } + } +} + implement_per_thing!( Percent, test_per_cent, @@ -1142,36 +1224,40 @@ implement_per_thing!( u16, "_Percent_", ); -implement_per_thing!( +implement_per_thing_with_perthousand!( PerU16, test_peru16, + test_peru16_extra, [u32, u64, u128], 65535_u16, u16, u32, "_Parts per 65535_", ); -implement_per_thing!( +implement_per_thing_with_perthousand!( Permill, test_permill, + test_permill_extra, [u32, u64, u128], 1_000_000u32, u32, u64, "_Parts per Million_", ); -implement_per_thing!( +implement_per_thing_with_perthousand!( Perbill, test_perbill, + test_perbill_extra, [u32, u64, u128], 1_000_000_000u32, u32, u64, "_Parts per Billion_", ); -implement_per_thing!( +implement_per_thing_with_perthousand!( Perquintill, test_perquintill, + test_perquintill_extra, [u64, u128], 1_000_000_000_000_000_000u64, u64, diff --git a/primitives/arithmetic/src/rational128.rs b/primitives/arithmetic/src/rational128.rs index 248df70794c635efc726255e5130ed8dc70ac037..947c7bc537d19fc1906a4e2e29d0b3f9947338e5 100644 --- a/primitives/arithmetic/src/rational128.rs +++ b/primitives/arithmetic/src/rational128.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use sp_std::{cmp::Ordering, prelude::*}; use crate::helpers_128bit; @@ -214,7 +215,7 @@ mod tests { assert_eq!(r(MAX128 - 10, MAX128).to_den(10), Ok(r(10, 10))); assert_eq!(r(MAX128 / 2, MAX128).to_den(10), Ok(r(5, 10))); - // large to perbill. This is very well needed for phragmen. + // large to perbill. This is very well needed for npos-elections. assert_eq!( r(MAX128 / 2, MAX128).to_den(1000_000_000), Ok(r(500_000_000, 1000_000_000)) @@ -359,6 +360,15 @@ mod tests { multiply_by_rational(1_000_000_000, MAX128 / 8, MAX128 / 2).unwrap(), 250000000, ); + + assert_eq!( + multiply_by_rational( + 29459999999999999988000u128, + 1000000000000000000u128, + 10000000000000000000u128 + ).unwrap(), + 2945999999999999998800u128 + ); } #[test] diff --git a/primitives/arithmetic/src/traits.rs b/primitives/arithmetic/src/traits.rs index 4201a41364bea35752286b6d9c1de277ee6a6121..ce645cfe65d94326c26fd5e4996324187e7913c7 100644 --- a/primitives/arithmetic/src/traits.rs +++ b/primitives/arithmetic/src/traits.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Primitive traits for the runtime arithmetic. @@ -20,8 +21,8 @@ use sp_std::{self, convert::{TryFrom, TryInto}}; use codec::HasCompact; pub use integer_sqrt::IntegerSquareRoot; pub use num_traits::{ - Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, - CheckedShl, CheckedShr, checked_pow + Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedNeg, + CheckedShl, CheckedShr, checked_pow, Signed, Unsigned, }; use sp_std::ops::{ Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, @@ -78,6 +79,11 @@ pub trait AtLeast32Bit: BaseArithmetic + From + From {} impl + From> AtLeast32Bit for T {} +/// A meta trait for arithmetic. Same as [`AtLeast32Bit `], but also bounded to be unsigned. +pub trait AtLeast32BitUnsigned: AtLeast32Bit + Unsigned {} + +impl AtLeast32BitUnsigned for T {} + /// Just like `From` except that if the source value is too big to fit into the destination type /// then it'll saturate the destination. pub trait UniqueSaturatedFrom: Sized { @@ -144,7 +150,15 @@ impl Self { - checked_pow(self, exp).unwrap_or_else(Bounded::max_value) + let neg = self < T::zero() && exp % 2 != 0; + checked_pow(self, exp) + .unwrap_or_else(|| + if neg { + Bounded::min_value() + } else { + Bounded::max_value() + } + ) } } diff --git a/primitives/authority-discovery/Cargo.toml b/primitives/authority-discovery/Cargo.toml index 32f67d5e6e0261a2310b70c0fea8d4f9d21a1dec..d201f6a70ac055c8a85d5c4398e8536d9c7a25a7 100644 --- a/primitives/authority-discovery/Cargo.toml +++ b/primitives/authority-discovery/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-authority-discovery" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] description = "Authority discovery primitives" edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,11 +12,11 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../application-crypto" } -codec = { package = "parity-scale-codec", default-features = false, version = "1.3.0" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../application-crypto" } +codec = { package = "parity-scale-codec", default-features = false, version = "1.3.1" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../runtime" } [features] default = ["std"] diff --git a/primitives/authority-discovery/README.md b/primitives/authority-discovery/README.md new file mode 100644 index 0000000000000000000000000000000000000000..65c2e22dde004483fdcff27d9a4b4392753bff3a --- /dev/null +++ b/primitives/authority-discovery/README.md @@ -0,0 +1,3 @@ +Runtime Api to help discover authorities. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/authority-discovery/src/lib.rs b/primitives/authority-discovery/src/lib.rs index 68680ad75946545f93d8d0c5ef5c3004a3623efc..8903a7f3837553806912770243bf6b18e3a3aadf 100644 --- a/primitives/authority-discovery/src/lib.rs +++ b/primitives/authority-discovery/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Runtime Api to help discover authorities. @@ -22,24 +23,11 @@ use sp_std::vec::Vec; mod app { use sp_application_crypto::{ - CryptoTypePublicPair, key_types::AUTHORITY_DISCOVERY, - Public as _, app_crypto, - sr25519}; + sr25519, + }; app_crypto!(sr25519, AUTHORITY_DISCOVERY); - - impl From for CryptoTypePublicPair { - fn from(key: Public) -> Self { - (&key).into() - } - } - - impl From<&Public> for CryptoTypePublicPair { - fn from(key: &Public) -> Self { - CryptoTypePublicPair(sr25519::CRYPTO_ID, key.to_raw_vec()) - } - } } sp_application_crypto::with_pair! { diff --git a/primitives/authorship/Cargo.toml b/primitives/authorship/Cargo.toml index 7bc01953ef8dd1c59d5ed9c0e8222d97259b177e..a5a4977c696d68f5ed8192aa407c04d1e0d9cb33 100644 --- a/primitives/authorship/Cargo.toml +++ b/primitives/authorship/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-authorship" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] description = "Authorship primitives" edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,10 +12,10 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../inherents" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../inherents" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } [features] default = [ "std" ] diff --git a/primitives/authorship/README.md b/primitives/authorship/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1aa1805cfc5e7740a55d416d66a8e1dbdcbedb3c --- /dev/null +++ b/primitives/authorship/README.md @@ -0,0 +1,3 @@ +Authorship Primitives + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/authorship/src/lib.rs b/primitives/authorship/src/lib.rs index 53dac56dc473c20d3f18e717a396ac13b80eb7b3..a760c546a25d7f2947b374b25965fc5192e53a2e 100644 --- a/primitives/authorship/src/lib.rs +++ b/primitives/authorship/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Authorship Primitives diff --git a/primitives/block-builder/Cargo.toml b/primitives/block-builder/Cargo.toml index 70bb5e12d37a202330d6d98af82f092f4e578671..d6ac505c1b7ddf5a245ab79d63eddc50d57c0b9a 100644 --- a/primitives/block-builder/Cargo.toml +++ b/primitives/block-builder/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-block-builder" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "The block builder runtime api." @@ -12,11 +12,11 @@ description = "The block builder runtime api." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } -sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../inherents" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../runtime" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../api" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../inherents" } [features] default = [ "std" ] diff --git a/primitives/block-builder/README.md b/primitives/block-builder/README.md new file mode 100644 index 0000000000000000000000000000000000000000..433197d3be9e4104606809bab2834e16e8bcf065 --- /dev/null +++ b/primitives/block-builder/README.md @@ -0,0 +1,3 @@ +The block builder runtime api. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/block-builder/src/lib.rs b/primitives/block-builder/src/lib.rs index 732c937c1a0858514c3841d3dad5419b5749b519..6367a18afa6151aea69c80c7c65b455d33c1933e 100644 --- a/primitives/block-builder/src/lib.rs +++ b/primitives/block-builder/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The block builder runtime api. diff --git a/primitives/blockchain/Cargo.toml b/primitives/blockchain/Cargo.toml index d5cf80b775196a0892af2a33325fd1653d799388..044130c08e59269dc875022f9f015ea92f094c6f 100644 --- a/primitives/blockchain/Cargo.toml +++ b/primitives/blockchain/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-blockchain" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate blockchain traits and primitives." @@ -12,14 +12,14 @@ documentation = "https://docs.rs/sp-blockchain" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] - [dependencies] log = "0.4.8" lru = "0.4.0" parking_lot = "0.10.0" derive_more = "0.99.2" -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-consensus = { version = "0.8.0-dev", path = "../consensus/common" } -sp-runtime = { version = "2.0.0-dev", path = "../runtime" } -sp-block-builder = { version = "2.0.0-dev", path = "../block-builder" } -sp-state-machine = { version = "0.8.0-dev", path = "../state-machine" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-consensus = { version = "0.8.0-rc6", path = "../consensus/common" } +sp-runtime = { version = "2.0.0-rc6", path = "../runtime" } +sp-block-builder = { version = "2.0.0-rc6", path = "../block-builder" } +sp-state-machine = { version = "0.8.0-rc6", path = "../state-machine" } +sp-database = { version = "2.0.0-rc6", path = "../database" } diff --git a/primitives/blockchain/README.md b/primitives/blockchain/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8298bfd7ae60a5d9a6be9c24ae4c7831e72f2bd0 --- /dev/null +++ b/primitives/blockchain/README.md @@ -0,0 +1,3 @@ +Substrate blockchain traits and primitives. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/blockchain/src/backend.rs b/primitives/blockchain/src/backend.rs index 45d627a1c27224a6c0349b9b5f2c11353b5d3a0b..1328dfb5752fc0544e33c6b9934965dd3158dded 100644 --- a/primitives/blockchain/src/backend.rs +++ b/primitives/blockchain/src/backend.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Substrate blockchain trait diff --git a/primitives/blockchain/src/error.rs b/primitives/blockchain/src/error.rs index e479b8abe918ee881dbb4fa79cdf824cfe6fb14e..bc412e8358c8d93de893a49ee81b86559b4dfaab 100644 --- a/primitives/blockchain/src/error.rs +++ b/primitives/blockchain/src/error.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Substrate client possible errors. @@ -129,6 +130,8 @@ pub enum Error { IncompletePipeline, #[display(fmt = "Transaction pool not ready for block production.")] TransactionPoolNotReady, + #[display(fmt = "Database: {}", _0)] + DatabaseError(sp_database::error::DatabaseError), /// A convenience variant for String #[display(fmt = "{}", _0)] Msg(String), diff --git a/primitives/blockchain/src/header_metadata.rs b/primitives/blockchain/src/header_metadata.rs index b7df03187db37b0a56114ad09e650c2d8098871a..b8d9c5c9345812c36e9271e859a81b61ae21f2fc 100644 --- a/primitives/blockchain/src/header_metadata.rs +++ b/primitives/blockchain/src/header_metadata.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Implements tree backend, cached header metadata and algorithms //! to compute routes efficiently over the tree of headers. @@ -136,7 +137,8 @@ pub fn tree_route>( from = backend.header_metadata(from.parent)?; } - // add the pivot block. and append the reversed to-branch (note that it's reverse order originals) + // add the pivot block. and append the reversed to-branch + // (note that it's reverse order originals) let pivot = from_branch.len(); from_branch.push(HashAndNumber { number: to.number, @@ -181,18 +183,24 @@ pub struct HashAndNumber { /// Tree route from C to E2. Retracted empty. Common is C, enacted [E1, E2] /// C -> E1 -> E2 /// ``` -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct TreeRoute { route: Vec>, pivot: usize, } impl TreeRoute { - /// Get a slice of all retracted blocks in reverse order (towards common ancestor) + /// Get a slice of all retracted blocks in reverse order (towards common ancestor). pub fn retracted(&self) -> &[HashAndNumber] { &self.route[..self.pivot] } + /// Convert into all retracted blocks in reverse order (towards common ancestor). + pub fn into_retracted(mut self) -> Vec> { + self.route.truncate(self.pivot); + self.route + } + /// Get the common ancestor block. This might be one of the two blocks of the /// route. pub fn common_block(&self) -> &HashAndNumber { @@ -212,8 +220,15 @@ pub trait HeaderMetadata { /// Error used in case the header metadata is not found. type Error; - fn header_metadata(&self, hash: Block::Hash) -> Result, Self::Error>; - fn insert_header_metadata(&self, hash: Block::Hash, header_metadata: CachedHeaderMetadata); + fn header_metadata( + &self, + hash: Block::Hash, + ) -> Result, Self::Error>; + fn insert_header_metadata( + &self, + hash: Block::Hash, + header_metadata: CachedHeaderMetadata, + ); fn remove_header_metadata(&self, hash: Block::Hash); } diff --git a/primitives/blockchain/src/lib.rs b/primitives/blockchain/src/lib.rs index 8f83c7aec5d9d13cc18e929a48bd224c43a2ce46..27b9c3585e9caa673460f000ae3c8adb88fb94c0 100644 --- a/primitives/blockchain/src/lib.rs +++ b/primitives/blockchain/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Substrate blockchain traits and primitives. diff --git a/primitives/chain-spec/Cargo.toml b/primitives/chain-spec/Cargo.toml index 585decc68d02b86cfe9a7631b796bc82a16cf9f2..6abbf80a6dbea851174afed233ecb0cc2afdfb6e 100644 --- a/primitives/chain-spec/Cargo.toml +++ b/primitives/chain-spec/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-chain-spec" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate chain configurations types." diff --git a/primitives/chain-spec/README.md b/primitives/chain-spec/README.md new file mode 100644 index 0000000000000000000000000000000000000000..375f14a441ab606693d987b9f21567d66a865e62 --- /dev/null +++ b/primitives/chain-spec/README.md @@ -0,0 +1,3 @@ +Types and traits related to chain specifications. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/chain-spec/src/lib.rs b/primitives/chain-spec/src/lib.rs index 13ebc09b6c0f0646b92d21056bbc1ef217f0ca3d..869fae8236b7674ba0eb8d02b86cb382686dd840 100644 --- a/primitives/chain-spec/src/lib.rs +++ b/primitives/chain-spec/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Types and traits related to chain specifications. diff --git a/primitives/consensus/aura/Cargo.toml b/primitives/consensus/aura/Cargo.toml index 574b80bd3d3902b959c55429d44e2fc2f21d96f3..b708f34efa47df3b70816892cb512678e9b715b4 100644 --- a/primitives/consensus/aura/Cargo.toml +++ b/primitives/consensus/aura/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-consensus-aura" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,13 +12,13 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../application-crypto" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../std" } -sp-api = { version = "2.0.0-dev", default-features = false, path = "../../api" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../runtime" } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../inherents" } -sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../timestamp" } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../../application-crypto" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../std" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../../api" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../runtime" } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../inherents" } +sp-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../timestamp" } [features] default = ["std"] diff --git a/primitives/consensus/aura/README.md b/primitives/consensus/aura/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0f360ae67eb28a9145ad4c83980f6dff9a9d22f1 --- /dev/null +++ b/primitives/consensus/aura/README.md @@ -0,0 +1,3 @@ +Primitives for Aura. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/consensus/aura/src/inherents.rs b/primitives/consensus/aura/src/inherents.rs index 77ec03c6f43425bbaa1c4983c95f9585590b75b1..a18bd3370306196ddafc15e339457e4c5d1918ec 100644 --- a/primitives/consensus/aura/src/inherents.rs +++ b/primitives/consensus/aura/src/inherents.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. /// Contains the inherents for the AURA module diff --git a/primitives/consensus/aura/src/lib.rs b/primitives/consensus/aura/src/lib.rs index 2dda5b28bf825e7716578298ac9340013f1dd087..cf0bcf2218a06440ec815b84a16650a8f9eef0a1 100644 --- a/primitives/consensus/aura/src/lib.rs +++ b/primitives/consensus/aura/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Primitives for Aura. diff --git a/primitives/consensus/babe/Cargo.toml b/primitives/consensus/babe/Cargo.toml index ca097d6a32d870e141e0fffcb789420bcdf8030d..e817a017cbec6878f938b94e2243d94133610325 100644 --- a/primitives/consensus/babe/Cargo.toml +++ b/primitives/consensus/babe/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-consensus-babe" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Primitives for BABE consensus" edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,16 +12,18 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../application-crypto" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../../application-crypto" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } merlin = { version = "2.0", default-features = false } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../std" } -sp-api = { version = "2.0.0-dev", default-features = false, path = "../../api" } -sp-consensus = { version = "0.8.0-dev", optional = true, path = "../common" } -sp-consensus-vrf = { version = "0.8.0-dev", path = "../vrf", default-features = false } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../inherents" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../runtime" } -sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../timestamp" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../std" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../../api" } +sp-consensus = { version = "0.8.0-rc6", optional = true, path = "../common" } +sp-consensus-slots = { version = "0.8.0-rc6", default-features = false, path = "../slots" } +sp-consensus-vrf = { version = "0.8.0-rc6", path = "../vrf", default-features = false } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../core" } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../inherents" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../runtime" } +sp-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../timestamp" } [features] default = ["std"] @@ -32,7 +34,9 @@ std = [ "sp-std/std", "sp-api/std", "sp-consensus", + "sp-consensus-slots/std", "sp-consensus-vrf/std", + "sp-core/std", "sp-inherents/std", "sp-runtime/std", "sp-timestamp/std", diff --git a/primitives/consensus/babe/README.md b/primitives/consensus/babe/README.md new file mode 100644 index 0000000000000000000000000000000000000000..54bae05fd6db72a167bc8fd687e2d6a91a8a47ba --- /dev/null +++ b/primitives/consensus/babe/README.md @@ -0,0 +1,3 @@ +Primitives for BABE. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/consensus/babe/src/digests.rs b/primitives/consensus/babe/src/digests.rs index 24be9b1b1455927ec1558d721bb539dd995a9a5c..a680ca0656c3a5ffe1f2a11f7aee8b40abcf97af 100644 --- a/primitives/consensus/babe/src/digests.rs +++ b/primitives/consensus/babe/src/digests.rs @@ -1,33 +1,30 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Private implementation details of BABE digests. -#[cfg(feature = "std")] -use super::{BABE_ENGINE_ID, AuthoritySignature}; -use super::{AuthorityId, AuthorityIndex, SlotNumber, BabeAuthorityWeight, BabeEpochConfiguration, AllowedSlots}; -#[cfg(feature = "std")] -use sp_runtime::{DigestItem, generic::OpaqueDigestItemId}; -#[cfg(feature = "std")] -use std::fmt::Debug; -use codec::{Decode, Encode}; -#[cfg(feature = "std")] -use codec::Codec; +use super::{ + AllowedSlots, AuthorityId, AuthorityIndex, AuthoritySignature, BabeAuthorityWeight, + BabeEpochConfiguration, SlotNumber, BABE_ENGINE_ID, +}; +use codec::{Codec, Decode, Encode}; use sp_std::vec::Vec; -use sp_runtime::RuntimeDebug; +use sp_runtime::{generic::OpaqueDigestItemId, DigestItem, RuntimeDebug}; + use sp_consensus_vrf::schnorrkel::{Randomness, VRFOutput, VRFProof}; /// Raw BABE primary slot assignment pre-digest. @@ -150,7 +147,6 @@ impl From for BabeEpochConfiguration { } /// A digest item which is usable with BABE consensus. -#[cfg(feature = "std")] pub trait CompatibleDigestItem: Sized { /// Construct a digest item which contains a BABE pre-digest. fn babe_pre_digest(seal: PreDigest) -> Self; @@ -171,9 +167,8 @@ pub trait CompatibleDigestItem: Sized { fn as_next_config_descriptor(&self) -> Option; } -#[cfg(feature = "std")] impl CompatibleDigestItem for DigestItem where - Hash: Debug + Send + Sync + Eq + Clone + Codec + 'static + Hash: Send + Sync + Eq + Clone + Codec + 'static { fn babe_pre_digest(digest: PreDigest) -> Self { DigestItem::PreRuntime(BABE_ENGINE_ID, digest.encode()) diff --git a/primitives/consensus/babe/src/inherents.rs b/primitives/consensus/babe/src/inherents.rs index 7c0744ac6e13ac21f4fc1fc01afd071d93e745ec..5384183f9e67835902387a2f92e401a2bf9546b4 100644 --- a/primitives/consensus/babe/src/inherents.rs +++ b/primitives/consensus/babe/src/inherents.rs @@ -1,18 +1,20 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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. +// 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. -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . //! Inherents for BABE use sp_inherents::{Error, InherentData, InherentIdentifier}; diff --git a/primitives/consensus/babe/src/lib.rs b/primitives/consensus/babe/src/lib.rs index 5f26349ef98eb784104ce59d40d8349c1cafa3d0..54f05d7bc51da5cf47706349132ea4e9981b419f 100644 --- a/primitives/consensus/babe/src/lib.rs +++ b/primitives/consensus/babe/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Primitives for BABE. #![deny(warnings)] @@ -22,15 +23,21 @@ pub mod digests; pub mod inherents; +pub use merlin::Transcript; pub use sp_consensus_vrf::schnorrkel::{ - Randomness, VRF_PROOF_LENGTH, VRF_OUTPUT_LENGTH, RANDOMNESS_LENGTH + Randomness, RANDOMNESS_LENGTH, VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH, }; -pub use merlin::Transcript; -use codec::{Encode, Decode}; +use codec::{Decode, Encode}; +#[cfg(feature = "std")] +use sp_core::vrf::{VRFTranscriptData, VRFTranscriptValue}; +use sp_runtime::{traits::Header, ConsensusEngineId, RuntimeDebug}; use sp_std::vec::Vec; -use sp_runtime::{ConsensusEngineId, RuntimeDebug}; -use crate::digests::{NextEpochDescriptor, NextConfigDescriptor}; + +use crate::digests::{NextConfigDescriptor, NextEpochDescriptor}; + +/// Key type for BABE module. +pub const KEY_TYPE: sp_core::crypto::KeyTypeId = sp_application_crypto::key_types::BABE; mod app { use sp_application_crypto::{app_crypto, key_types::BABE, sr25519}; @@ -70,7 +77,10 @@ pub const MEDIAN_ALGORITHM_CARDINALITY: usize = 1200; // arbitrary suggestion by pub type AuthorityIndex = u32; /// A slot number. -pub type SlotNumber = u64; +pub use sp_consensus_slots::SlotNumber; + +/// An equivocation proof for multiple block authorships on the same slot (i.e. double vote). +pub type EquivocationProof = sp_consensus_slots::EquivocationProof; /// The weight of an authority. // NOTE: we use a unique name for the weight to avoid conflicts with other @@ -93,6 +103,23 @@ pub fn make_transcript( transcript } +/// Make a VRF transcript data container +#[cfg(feature = "std")] +pub fn make_transcript_data( + randomness: &Randomness, + slot_number: u64, + epoch: u64, +) -> VRFTranscriptData { + VRFTranscriptData { + label: &BABE_ENGINE_ID, + items: vec![ + ("slot number", VRFTranscriptValue::U64(slot_number)), + ("current epoch", VRFTranscriptValue::U64(epoch)), + ("chain randomness", VRFTranscriptValue::Bytes(&randomness[..])), + ] + } +} + /// An consensus log item for BABE. #[derive(Decode, Encode, Clone, PartialEq, Eq)] pub enum ConsensusLog { @@ -236,6 +263,93 @@ pub struct BabeEpochConfiguration { pub allowed_slots: AllowedSlots, } +/// Verifies the equivocation proof by making sure that: both headers have +/// different hashes, are targetting the same slot, and have valid signatures by +/// the same authority. +pub fn check_equivocation_proof(proof: EquivocationProof) -> bool +where + H: Header, +{ + use digests::*; + use sp_application_crypto::RuntimeAppPublic; + + let find_pre_digest = |header: &H| { + header + .digest() + .logs() + .iter() + .find_map(|log| log.as_babe_pre_digest()) + }; + + let verify_seal_signature = |mut header: H, offender: &AuthorityId| { + let seal = header.digest_mut().pop()?.as_babe_seal()?; + let pre_hash = header.hash(); + + if !offender.verify(&pre_hash.as_ref(), &seal) { + return None; + } + + Some(()) + }; + + let verify_proof = || { + // we must have different headers for the equivocation to be valid + if proof.first_header.hash() == proof.second_header.hash() { + return None; + } + + let first_pre_digest = find_pre_digest(&proof.first_header)?; + let second_pre_digest = find_pre_digest(&proof.second_header)?; + + // both headers must be targetting the same slot and it must + // be the same as the one in the proof. + if proof.slot_number != first_pre_digest.slot_number() || + first_pre_digest.slot_number() != second_pre_digest.slot_number() + { + return None; + } + + // both headers must have been authored by the same authority + if first_pre_digest.authority_index() != second_pre_digest.authority_index() { + return None; + } + + // we finally verify that the expected authority has signed both headers and + // that the signature is valid. + verify_seal_signature(proof.first_header, &proof.offender)?; + verify_seal_signature(proof.second_header, &proof.offender)?; + + Some(()) + }; + + // NOTE: we isolate the verification code into an helper function that + // returns `Option<()>` so that we can use `?` to deal with any intermediate + // errors and discard the proof as invalid. + verify_proof().is_some() +} + +/// An opaque type used to represent the key ownership proof at the runtime API +/// boundary. The inner value is an encoded representation of the actual key +/// ownership proof which will be parameterized when defining the runtime. At +/// the runtime API boundary this type is unknown and as such we keep this +/// opaque representation, implementors of the runtime API will have to make +/// sure that all usages of `OpaqueKeyOwnershipProof` refer to the same type. +#[derive(Decode, Encode, PartialEq)] +pub struct OpaqueKeyOwnershipProof(Vec); +impl OpaqueKeyOwnershipProof { + /// Create a new `OpaqueKeyOwnershipProof` using the given encoded + /// representation. + pub fn new(inner: Vec) -> OpaqueKeyOwnershipProof { + OpaqueKeyOwnershipProof(inner) + } + + /// Try to decode this `OpaqueKeyOwnershipProof` into the given concrete key + /// ownership proof type. + pub fn decode(self) -> Option { + Decode::decode(&mut &self.0[..]).ok() + } +} + sp_api::decl_runtime_apis! { /// API necessary for block authorship with BABE. #[api_version(2)] @@ -249,5 +363,34 @@ sp_api::decl_runtime_apis! { /// Returns the slot number that started the current epoch. fn current_epoch_start() -> SlotNumber; + + /// Generates a proof of key ownership for the given authority in the + /// current epoch. An example usage of this module is coupled with the + /// session historical module to prove that a given authority key is + /// tied to a given staking identity during a specific session. Proofs + /// of key ownership are necessary for submitting equivocation reports. + /// NOTE: even though the API takes a `slot_number` as parameter the current + /// implementations ignores this parameter and instead relies on this + /// method being called at the correct block height, i.e. any point at + /// which the epoch for the given slot is live on-chain. Future + /// implementations will instead use indexed data through an offchain + /// worker, not requiring older states to be available. + fn generate_key_ownership_proof( + slot_number: SlotNumber, + authority_id: AuthorityId, + ) -> Option; + + /// Submits an unsigned extrinsic to report an equivocation. The caller + /// must provide the equivocation proof and a key ownership proof + /// (should be obtained using `generate_key_ownership_proof`). The + /// extrinsic will be unsigned and should only be accepted for local + /// authorship (not to be broadcast to the network). This method returns + /// `None` when creation of the extrinsic fails, e.g. if equivocation + /// reporting is disabled for the given runtime (i.e. this method is + /// hardcoded to return `None`). Only useful in an offchain context. + fn submit_report_equivocation_unsigned_extrinsic( + equivocation_proof: EquivocationProof, + key_owner_proof: OpaqueKeyOwnershipProof, + ) -> Option<()>; } } diff --git a/primitives/consensus/common/Cargo.toml b/primitives/consensus/common/Cargo.toml index 7101dde2fc3aa3e49ffd9533078ec98527c00391..7af0cbd949a73cb1933abe395d8dc0dcb41f50fb 100644 --- a/primitives/consensus/common/Cargo.toml +++ b/primitives/consensus/common/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-consensus" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Common utilities for building and using consensus engines in substrate." @@ -15,23 +15,27 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] derive_more = "0.99.2" -libp2p = { version = "0.18.1", default-features = false } +libp2p = { version = "0.24.0", default-features = false } log = "0.4.8" -sp-core = { path= "../../core", version = "2.0.0-dev"} -sp-inherents = { version = "2.0.0-dev", path = "../../inherents" } -sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } +sp-core = { path= "../../core", version = "2.0.0-rc6"} +sp-inherents = { version = "2.0.0-rc6", path = "../../inherents" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../../primitives/state-machine" } futures = { version = "0.3.1", features = ["thread-pool"] } futures-timer = "3.0.1" -sp-std = { version = "2.0.0-dev", path = "../../std" } -sp-version = { version = "2.0.0-dev", path = "../../version" } -sp-runtime = { version = "2.0.0-dev", path = "../../runtime" } -sp-utils = { version = "2.0.0-dev", path = "../../utils" } -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } +sp-std = { version = "2.0.0-rc6", path = "../../std" } +sp-version = { version = "2.0.0-rc6", path = "../../version" } +sp-runtime = { version = "2.0.0-rc6", path = "../../runtime" } +sp-utils = { version = "2.0.0-rc6", path = "../../utils" } +sp-trie = { version = "2.0.0-rc6", path = "../../trie" } +sp-api = { version = "2.0.0-rc6", path = "../../api" } +codec = { package = "parity-scale-codec", version = "1.3.1", features = ["derive"] } parking_lot = "0.10.0" serde = { version = "1.0", features = ["derive"] } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../../utils/prometheus", version = "0.8.0-rc6"} +wasm-timer = "0.2.4" [dev-dependencies] -sp-test-primitives = { version = "2.0.0-dev", path = "../../test-primitives" } +sp-test-primitives = { version = "2.0.0-rc6", path = "../../test-primitives" } [features] default = [] diff --git a/primitives/consensus/common/README.md b/primitives/consensus/common/README.md new file mode 100644 index 0000000000000000000000000000000000000000..963bb0fbdba4af4de706c5303003f8036016291d --- /dev/null +++ b/primitives/consensus/common/README.md @@ -0,0 +1,7 @@ +Common utilities for building and using consensus engines in substrate. + +Much of this crate is _unstable_ and thus the API is likely to undergo +change. Implementors of traits should not rely on the interfaces to remain +the same. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/consensus/common/src/block_import.rs b/primitives/consensus/common/src/block_import.rs index eb90ac9f1d4df6ceb0ecba42bca4b7911cce7de5..5e593da1163d77a65be2ca7bfaa9cd9f4114d71b 100644 --- a/primitives/consensus/common/src/block_import.rs +++ b/primitives/consensus/common/src/block_import.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Block import helpers. diff --git a/primitives/consensus/common/src/block_validation.rs b/primitives/consensus/common/src/block_validation.rs index e8054f3ae40d7291b62604876ab9a639267f2632..66f960f16fff396fe40a6f3e38ff5a0d84ffc17e 100644 --- a/primitives/consensus/common/src/block_validation.rs +++ b/primitives/consensus/common/src/block_validation.rs @@ -36,7 +36,10 @@ impl, B: Block> Chain for Arc { #[derive(Debug, PartialEq, Eq)] pub enum Validation { /// Valid block announcement. - Success, + Success { + /// Is this the new best block of the node? + is_new_best: bool, + }, /// Invalid block announcement. Failure, } @@ -49,18 +52,10 @@ pub trait BlockAnnounceValidator { /// Default implementation of `BlockAnnounceValidator`. #[derive(Debug)] -pub struct DefaultBlockAnnounceValidator { - chain: C -} - -impl DefaultBlockAnnounceValidator { - pub fn new(chain: C) -> Self { - Self { chain } - } -} +pub struct DefaultBlockAnnounceValidator; -impl> BlockAnnounceValidator for DefaultBlockAnnounceValidator { +impl BlockAnnounceValidator for DefaultBlockAnnounceValidator { fn validate(&mut self, _h: &B::Header, _d: &[u8]) -> Result> { - Ok(Validation::Success) + Ok(Validation::Success { is_new_best: false }) } } diff --git a/primitives/consensus/common/src/error.rs b/primitives/consensus/common/src/error.rs index d7e396223a2c53611856642631f363025107f486..0da749589013d8ce2a8328ac6c1f647b83ba2005 100644 --- a/primitives/consensus/common/src/error.rs +++ b/primitives/consensus/common/src/error.rs @@ -1,22 +1,23 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Error types in Consensus use sp_version::RuntimeVersion; -use sp_core::ed25519::{Public, Signature}; +use sp_core::ed25519::Public; use std::error; /// Result type alias. @@ -48,7 +49,7 @@ pub enum Error { CannotPropose, /// Error checking signature #[display(fmt="Message signature {:?} by {:?} is invalid.", _0, _1)] - InvalidSignature(Signature, Public), + InvalidSignature(Vec, Vec), /// Invalid authorities set received from the runtime. #[display(fmt="Current state of blockchain has invalid authorities set")] InvalidAuthoritiesSet, @@ -79,6 +80,9 @@ pub enum Error { #[display(fmt="Chain lookup failed: {}", _0)] #[from(ignore)] ChainLookup(String), + /// Signing failed + #[display(fmt="Failed to sign using key: {:?}. Reason: {}", _0, _1)] + CannotSign(Vec, String) } impl error::Error for Error { diff --git a/primitives/consensus/common/src/evaluation.rs b/primitives/consensus/common/src/evaluation.rs index 5542042fedb1c186dae948b7da1b91e7c57fd9e2..76fcd5310b06af6daf0704b964059a3d0e95ad36 100644 --- a/primitives/consensus/common/src/evaluation.rs +++ b/primitives/consensus/common/src/evaluation.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Block evaluation and evaluation errors. diff --git a/primitives/consensus/common/src/import_queue.rs b/primitives/consensus/common/src/import_queue.rs index 2da0bcac0c17b8b6661bd5fcedf0f7ef7e1a691c..9d25786441ac96fc4fb756ec3a6a92833f143a16 100644 --- a/primitives/consensus/common/src/import_queue.rs +++ b/primitives/consensus/common/src/import_queue.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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 Queue primitive: something which can verify and import blocks. //! @@ -26,15 +27,24 @@ //! queues to be instantiated simply. use std::collections::HashMap; + use sp_runtime::{Justification, traits::{Block as BlockT, Header as _, NumberFor}}; -use crate::error::Error as ConsensusError; -use crate::block_import::{ - BlockImport, BlockOrigin, BlockImportParams, ImportedAux, JustificationImport, ImportResult, - BlockCheckParams, FinalityProofImport, -}; +use crate::{ + error::Error as ConsensusError, + block_import::{ + BlockImport, BlockOrigin, BlockImportParams, ImportedAux, JustificationImport, ImportResult, + BlockCheckParams, FinalityProofImport, + }, + metrics::Metrics, +}; pub use basic_queue::BasicQueue; +/// A commonly-used Import Queue type. +/// +/// This defines the transaction type of the `BasicQueue` to be the transaction type for a client. +pub type DefaultImportQueue = BasicQueue>; + mod basic_queue; pub mod buffered_link; @@ -185,6 +195,17 @@ pub fn import_single_block, Transaction>( block_origin: BlockOrigin, block: IncomingBlock, verifier: &mut V, +) -> Result>, BlockImportError> { + import_single_block_metered(import_handle, block_origin, block, verifier, None) +} + +/// Single block import function with metering. +pub(crate) fn import_single_block_metered, Transaction>( + import_handle: &mut dyn BlockImport, + block_origin: BlockOrigin, + block: IncomingBlock, + verifier: &mut V, + metrics: Option, ) -> Result>, BlockImportError> { let peer = block.origin; @@ -206,8 +227,8 @@ pub fn import_single_block, Transaction>( let hash = header.hash(); let parent_hash = header.parent_hash().clone(); - let import_error = |e| { - match e { + let import_handler = |import| { + match import { Ok(ImportResult::AlreadyInChain) => { trace!(target: "sync", "Block already in chain {}: {:?}", number, hash); Ok(BlockImportResult::ImportedKnown(number)) @@ -231,7 +252,8 @@ pub fn import_single_block, Transaction>( } } }; - match import_error(import_handle.check_block(BlockCheckParams { + + match import_handler(import_handle.check_block(BlockCheckParams { hash, number, parent_hash, @@ -242,6 +264,7 @@ pub fn import_single_block, Transaction>( r => return Ok(r), // Any other successful result means that the block is already imported. } + let started = wasm_timer::Instant::now(); let (mut import_block, maybe_keys) = verifier.verify(block_origin, header, justification, block.body) .map_err(|msg| { if let Some(ref peer) = peer { @@ -249,14 +272,21 @@ pub fn import_single_block, Transaction>( } else { trace!(target: "sync", "Verifying {}({}) failed: {}", number, hash, msg); } + if let Some(metrics) = metrics.as_ref() { + metrics.report_verification(false, started.elapsed()); + } BlockImportError::VerificationFailed(peer.clone(), msg) })?; + if let Some(metrics) = metrics.as_ref() { + metrics.report_verification(true, started.elapsed()); + } + let mut cache = HashMap::new(); if let Some(keys) = maybe_keys { cache.extend(keys.into_iter()); } import_block.allow_missing_state = block.allow_missing_state; - import_error(import_handle.import_block(import_block.convert_transaction(), cache)) + import_handler(import_handle.import_block(import_block.convert_transaction(), cache)) } diff --git a/primitives/consensus/common/src/import_queue/basic_queue.rs b/primitives/consensus/common/src/import_queue/basic_queue.rs index f2b830e890e4040bff14f294e9c450078a4f9ddd..e59f7ab5b601c720fda1ffb4af45767156b2f3b2 100644 --- a/primitives/consensus/common/src/import_queue/basic_queue.rs +++ b/primitives/consensus/common/src/import_queue/basic_queue.rs @@ -1,31 +1,36 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use std::{mem, pin::Pin, time::Duration, marker::PhantomData}; use futures::{prelude::*, task::Context, task::Poll}; use futures_timer::Delay; use sp_runtime::{Justification, traits::{Block as BlockT, Header as HeaderT, NumberFor}}; use sp_utils::mpsc::{TracingUnboundedSender, tracing_unbounded}; - -use crate::block_import::BlockOrigin; -use crate::import_queue::{ - BlockImportResult, BlockImportError, Verifier, BoxBlockImport, BoxFinalityProofImport, - BoxJustificationImport, ImportQueue, Link, Origin, - IncomingBlock, import_single_block, - buffered_link::{self, BufferedLinkSender, BufferedLinkReceiver} +use prometheus_endpoint::Registry; + +use crate::{ + block_import::BlockOrigin, + import_queue::{ + BlockImportResult, BlockImportError, Verifier, BoxBlockImport, BoxFinalityProofImport, + BoxJustificationImport, ImportQueue, Link, Origin, + IncomingBlock, import_single_block_metered, + buffered_link::{self, BufferedLinkSender, BufferedLinkReceiver}, + }, + metrics::Metrics, }; /// Interface to a basic block import queue that is importing blocks sequentially in a separate @@ -56,15 +61,22 @@ impl BasicQueue { block_import: BoxBlockImport, justification_import: Option>, finality_proof_import: Option>, - spawner: &impl sp_core::traits::SpawnBlocking, + spawner: &impl sp_core::traits::SpawnNamed, + prometheus_registry: Option<&Registry>, ) -> Self { let (result_sender, result_port) = buffered_link::buffered_link(); + let metrics = prometheus_registry.and_then(|r| + Metrics::register(r) + .map_err(|err| { log::warn!("Failed to register Prometheus metrics: {}", err); }) + .ok() + ); let (future, worker_sender) = BlockImportWorker::new( result_sender, verifier, block_import, justification_import, finality_proof_import, + metrics, ); spawner.spawn_blocking("basic-block-import-worker", future.boxed()); @@ -84,7 +96,13 @@ impl ImportQueue for BasicQueue } trace!(target: "sync", "Scheduling {} blocks for import", blocks.len()); - let _ = self.sender.unbounded_send(ToWorkerMsg::ImportBlocks(origin, blocks)); + let res = self.sender.unbounded_send(ToWorkerMsg::ImportBlocks(origin, blocks)); + if res.is_err() { + log::error!( + target: "sync", + "import_blocks: Background import task is no longer alive" + ); + } } fn import_justification( @@ -94,10 +112,16 @@ impl ImportQueue for BasicQueue number: NumberFor, justification: Justification ) { - let _ = self.sender + let res = self.sender .unbounded_send( - ToWorkerMsg::ImportJustification(who.clone(), hash, number, justification) + ToWorkerMsg::ImportJustification(who, hash, number, justification) + ); + if res.is_err() { + log::error!( + target: "sync", + "import_justification: Background import task is no longer alive" ); + } } fn import_finality_proof( @@ -108,14 +132,22 @@ impl ImportQueue for BasicQueue finality_proof: Vec, ) { trace!(target: "sync", "Scheduling finality proof of {}/{} for import", number, hash); - let _ = self.sender + let res = self.sender .unbounded_send( ToWorkerMsg::ImportFinalityProof(who, hash, number, finality_proof) ); + if res.is_err() { + log::error!( + target: "sync", + "import_finality_proof: Background import task is no longer alive" + ); + } } fn poll_actions(&mut self, cx: &mut Context, link: &mut dyn Link) { - self.result_port.poll_actions(cx, link); + if self.result_port.poll_actions(cx, link).is_err() { + log::error!(target: "sync", "poll_actions: Background import task is no longer alive"); + } } } @@ -132,6 +164,7 @@ struct BlockImportWorker { justification_import: Option>, finality_proof_import: Option>, delay_between_blocks: Duration, + metrics: Option, _phantom: PhantomData, } @@ -142,6 +175,7 @@ impl BlockImportWorker { block_import: BoxBlockImport, justification_import: Option>, finality_proof_import: Option>, + metrics: Option, ) -> (impl Future + Send, TracingUnboundedSender>) { let (sender, mut port) = tracing_unbounded("mpsc_block_import_worker"); @@ -150,6 +184,7 @@ impl BlockImportWorker { justification_import, finality_proof_import, delay_between_blocks: Duration::new(0, 0), + metrics, _phantom: PhantomData, }; @@ -210,7 +245,7 @@ impl BlockImportWorker { // a `Future` into `importing`. let (bi, verif) = block_import_verifier.take() .expect("block_import_verifier is always Some; qed"); - importing = Some(worker.import_a_batch_of_blocks(bi, verif, origin, blocks)); + importing = Some(worker.import_batch(bi, verif, origin, blocks)); }, ToWorkerMsg::ImportFinalityProof(who, hash, number, proof) => { let (_, verif) = block_import_verifier.as_mut() @@ -232,16 +267,17 @@ impl BlockImportWorker { /// /// For lifetime reasons, the `BlockImport` implementation must be passed by value, and is /// yielded back in the output once the import is finished. - fn import_a_batch_of_blocks>( + fn import_batch>( &mut self, block_import: BoxBlockImport, verifier: V, origin: BlockOrigin, - blocks: Vec> + blocks: Vec>, ) -> impl Future, V)> { let mut result_sender = self.result_sender.clone(); + let metrics = self.metrics.clone(); - import_many_blocks(block_import, origin, blocks, verifier, self.delay_between_blocks) + import_many_blocks(block_import, origin, blocks, verifier, self.delay_between_blocks, metrics) .then(move |(imported, count, results, block_import, verifier)| { result_sender.blocks_processed(imported, count, results); future::ready((block_import, verifier)) @@ -312,6 +348,7 @@ fn import_many_blocks, Transaction>( blocks: Vec>, verifier: V, delay_between_blocks: Duration, + metrics: Option, ) -> impl Future< Output = ( usize, @@ -361,9 +398,9 @@ fn import_many_blocks, Transaction>( None => { // No block left to import, success! let import_handle = import_handle.take() - .expect("Future polled again after it has finished"); + .expect("Future polled again after it has finished (import handle is None)"); let verifier = verifier.take() - .expect("Future polled again after it has finished"); + .expect("Future polled again after it has finished (verifier handle is None)"); let results = mem::replace(&mut results, Vec::new()); return Poll::Ready((imported, count, results, import_handle, verifier)); }, @@ -373,9 +410,9 @@ fn import_many_blocks, Transaction>( // therefore `import_handle` and `verifier` are always `Some` here. It is illegal to poll // a `Future` again after it has ended. let import_handle = import_handle.as_mut() - .expect("Future polled again after it has finished"); + .expect("Future polled again after it has finished (import handle is None)"); let verifier = verifier.as_mut() - .expect("Future polled again after it has finished"); + .expect("Future polled again after it has finished (verifier handle is None)"); let block_number = block.header.as_ref().map(|h| h.number().clone()); let block_hash = block.hash; @@ -383,14 +420,19 @@ fn import_many_blocks, Transaction>( Err(BlockImportError::Cancelled) } else { // The actual import. - import_single_block( + import_single_block_metered( &mut **import_handle, blocks_origin.clone(), block, verifier, + metrics.clone(), ) }; + if let Some(metrics) = metrics.as_ref() { + metrics.report_import::(&import_result); + } + if import_result.is_ok() { trace!(target: "sync", "Block imported successfully {:?} ({})", block_number, block_hash); imported += 1; diff --git a/primitives/consensus/common/src/import_queue/buffered_link.rs b/primitives/consensus/common/src/import_queue/buffered_link.rs index ea77fc97f0e8a28e889ea8c13c1644a2f968a734..a37d4c53c260394dc335842d7723ace983d39472 100644 --- a/primitives/consensus/common/src/import_queue/buffered_link.rs +++ b/primitives/consensus/common/src/import_queue/buffered_link.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Provides the `buffered_link` utility. //! @@ -49,7 +50,7 @@ use crate::import_queue::{Origin, Link, BlockImportResult, BlockImportError}; pub fn buffered_link() -> (BufferedLinkSender, BufferedLinkReceiver) { let (tx, rx) = tracing_unbounded("mpsc_buffered_link"); let tx = BufferedLinkSender { tx }; - let rx = BufferedLinkReceiver { rx }; + let rx = BufferedLinkReceiver { rx: rx.fuse() }; (tx, rx) } @@ -126,7 +127,7 @@ impl Link for BufferedLinkSender { /// See [`buffered_link`]. pub struct BufferedLinkReceiver { - rx: TracingUnboundedReceiver>, + rx: stream::Fuse>>, } impl BufferedLinkReceiver { @@ -136,12 +137,14 @@ impl BufferedLinkReceiver { /// This method should behave in a way similar to `Future::poll`. It can register the current /// task and notify later when more actions are ready to be polled. To continue the comparison, /// it is as if this method always returned `Poll::Pending`. - pub fn poll_actions(&mut self, cx: &mut Context, link: &mut dyn Link) { + /// + /// Returns an error if the corresponding [`BufferedLinkSender`] has been closed. + pub fn poll_actions(&mut self, cx: &mut Context, link: &mut dyn Link) -> Result<(), ()> { loop { - let msg = if let Poll::Ready(Some(msg)) = Stream::poll_next(Pin::new(&mut self.rx), cx) { - msg - } else { - break + let msg = match Stream::poll_next(Pin::new(&mut self.rx), cx) { + Poll::Ready(Some(msg)) => msg, + Poll::Ready(None) => break Err(()), + Poll::Pending => break Ok(()), }; match msg { @@ -161,7 +164,7 @@ impl BufferedLinkReceiver { /// Close the channel. pub fn close(&mut self) { - self.rx.close() + self.rx.get_mut().close() } } diff --git a/primitives/consensus/common/src/lib.rs b/primitives/consensus/common/src/lib.rs index 9f338ad1d4e75741bb02bca67005c1d316909565..fa4f233c680facb91dfd05b8b9a151d803429eb5 100644 --- a/primitives/consensus/common/src/lib.rs +++ b/primitives/consensus/common/src/lib.rs @@ -44,6 +44,7 @@ pub mod block_import; mod select_chain; pub mod import_queue; pub mod evaluation; +mod metrics; // block size limit. const MAX_BLOCK_SIZE: usize = 4 * 1024 * 1024 + 512; @@ -55,6 +56,7 @@ pub use block_import::{ }; pub use select_chain::SelectChain; pub use sp_state_machine::Backend as StateBackend; +pub use import_queue::DefaultImportQueue; /// Block status. #[derive(Debug, PartialEq, Eq)] @@ -71,7 +73,9 @@ pub enum BlockStatus { Unknown, } -/// Environment producer for a Consensus instance. Creates proposer instance and communication streams. +/// Environment for a Consensus instance. +/// +/// Creates proposer instance. pub trait Environment { /// The proposer type this creates. type Proposer: Proposer + Send + 'static; @@ -154,7 +158,7 @@ pub trait Proposer { /// /// Returns a future that resolves to a [`Proposal`] or to [`Error`]. fn propose( - &mut self, + self, inherent_data: InherentData, inherent_digests: DigestFor, max_duration: Duration, @@ -208,6 +212,7 @@ pub trait CanAuthorWith { /// Checks if the node can author blocks by using /// [`NativeVersion::can_author_with`](sp_version::NativeVersion::can_author_with). +#[derive(Clone)] pub struct CanAuthorWithNativeVersion(T); impl CanAuthorWithNativeVersion { @@ -235,6 +240,7 @@ impl, Block: BlockT> CanAuthorWith CanAuthorWith for AlwaysCanAuthor { @@ -243,6 +249,16 @@ impl CanAuthorWith for AlwaysCanAuthor { } } +/// Never can author. +#[derive(Clone)] +pub struct NeverCanAuthor; + +impl CanAuthorWith for NeverCanAuthor { + fn can_author_with(&self, _: &BlockId) -> Result<(), String> { + Err("Authoring is always disabled.".to_string()) + } +} + /// A type from which a slot duration can be obtained. pub trait SlotData { /// Gets the slot duration. diff --git a/primitives/consensus/common/src/metrics.rs b/primitives/consensus/common/src/metrics.rs new file mode 100644 index 0000000000000000000000000000000000000000..f9326fac062dcc786eaa898af7112e919f20fd98 --- /dev/null +++ b/primitives/consensus/common/src/metrics.rs @@ -0,0 +1,80 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! Metering tools for consensus + +use prometheus_endpoint::{register, U64, Registry, PrometheusError, Opts, CounterVec, HistogramVec, HistogramOpts}; + +use sp_runtime::traits::{Block as BlockT, NumberFor}; + +use crate::import_queue::{BlockImportResult, BlockImportError}; + +/// Generic Prometheus metrics for common consensus functionality. +#[derive(Clone)] +pub(crate) struct Metrics { + pub import_queue_processed: CounterVec, + pub block_verification_time: HistogramVec, +} + +impl Metrics { + pub(crate) fn register(registry: &Registry) -> Result { + Ok(Self { + import_queue_processed: register( + CounterVec::new( + Opts::new("import_queue_processed_total", "Blocks processed by import queue"), + &["result"] // 'success or failure + )?, + registry, + )?, + block_verification_time: register( + HistogramVec::new( + HistogramOpts::new( + "block_verification_time", + "Histogram of time taken to import blocks", + ), + &["result"], + )?, + registry, + )?, + }) + } + + pub fn report_import( + &self, + result: &Result>, BlockImportError>, + ) { + let label = match result { + Ok(_) => "success", + Err(BlockImportError::IncompleteHeader(_)) => "incomplete_header", + Err(BlockImportError::VerificationFailed(_,_)) => "verification_failed", + Err(BlockImportError::BadBlock(_)) => "bad_block", + Err(BlockImportError::MissingState) => "missing_state", + Err(BlockImportError::UnknownParent) => "unknown_parent", + Err(BlockImportError::Cancelled) => "cancelled", + Err(BlockImportError::Other(_)) => "failed", + }; + + self.import_queue_processed.with_label_values( + &[label] + ).inc(); + } + + pub fn report_verification(&self, success: bool, time: std::time::Duration) { + self.block_verification_time.with_label_values( + &[if success { "success" } else { "verification_failed" }] + ).observe(time.as_secs_f64()); + } +} diff --git a/primitives/consensus/common/src/offline_tracker.rs b/primitives/consensus/common/src/offline_tracker.rs index b4959503b1d394403de4434865dd10d3f43c61ea..b96498041f25d39fc55e12d9d5fd99cb3e974ce9 100644 --- a/primitives/consensus/common/src/offline_tracker.rs +++ b/primitives/consensus/common/src/offline_tracker.rs @@ -1,23 +1,25 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tracks offline validators. use std::collections::HashMap; -use std::time::{Instant, Duration}; +use std::time::Duration; +use wasm_timer::Instant; // time before we report a validator. const REPORT_TIME: Duration = Duration::from_secs(60 * 5); diff --git a/primitives/consensus/pow/Cargo.toml b/primitives/consensus/pow/Cargo.toml index a7bcb6a000fed5d30b74e027cc32ef56a3f82d2b..03376907a93f2257c638156e71405c07b4e10809 100644 --- a/primitives/consensus/pow/Cargo.toml +++ b/primitives/consensus/pow/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-consensus-pow" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Primitives for Aura consensus" edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,11 +12,11 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-api = { version = "2.0.0-dev", default-features = false, path = "../../api" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../runtime" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../core" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../../api" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../runtime" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../core" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } [features] default = ["std"] diff --git a/primitives/consensus/pow/README.md b/primitives/consensus/pow/README.md new file mode 100644 index 0000000000000000000000000000000000000000..881864377649804e610fddecce9e9a3eb8624856 --- /dev/null +++ b/primitives/consensus/pow/README.md @@ -0,0 +1,3 @@ +Primitives for Substrate Proof-of-Work (PoW) consensus. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/consensus/pow/src/lib.rs b/primitives/consensus/pow/src/lib.rs index fa8f75d1be64c3e014cfa43f5cb15801dd84a851..79c9b6f16c3bd9e3cb91dec5a9e2fa40f9d3c43c 100644 --- a/primitives/consensus/pow/src/lib.rs +++ b/primitives/consensus/pow/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Primitives for Substrate Proof-of-Work (PoW) consensus. diff --git a/primitives/consensus/slots/Cargo.toml b/primitives/consensus/slots/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..ada913b645c7bec2975c61fe69a4c2595ffd82cc --- /dev/null +++ b/primitives/consensus/slots/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "sp-consensus-slots" +version = "0.8.0-rc6" +authors = ["Parity Technologies "] +description = "Primitives for slots-based consensus" +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +sp-runtime = { version = "2.0.0-rc2", default-features = false, path = "../../runtime" } + +[features] +default = ["std"] +std = [ + "codec/std", + "sp-runtime/std", +] diff --git a/primitives/consensus/slots/README.md b/primitives/consensus/slots/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f451c32888a47843c1f679a17d8db06d23811272 --- /dev/null +++ b/primitives/consensus/slots/README.md @@ -0,0 +1,3 @@ +Primitives for slots-based consensus engines. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/consensus/slots/src/lib.rs b/primitives/consensus/slots/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..f898cf9da6e2a0e19e0bd89b0c6868fea4a7aff1 --- /dev/null +++ b/primitives/consensus/slots/src/lib.rs @@ -0,0 +1,41 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Primitives for slots-based consensus engines. + +#![cfg_attr(not(feature = "std"), no_std)] + +use codec::{Decode, Encode}; + +/// A slot number. +pub type SlotNumber = u64; + +/// Represents an equivocation proof. An equivocation happens when a validator +/// produces more than one block on the same slot. The proof of equivocation +/// are the given distinct headers that were signed by the validator and which +/// include the slot number. +#[derive(Clone, Debug, Decode, Encode, PartialEq)] +pub struct EquivocationProof { + /// Returns the authority id of the equivocator. + pub offender: Id, + /// The slot number at which the equivocation happened. + pub slot_number: SlotNumber, + /// The first header involved in the equivocation. + pub first_header: Header, + /// The second header involved in the equivocation. + pub second_header: Header, +} diff --git a/primitives/consensus/vrf/Cargo.toml b/primitives/consensus/vrf/Cargo.toml index 92d8a77cb4edfe847d05393e65e320646a231ae8..7cf064e9f62918d6065ba3edb25f551bcb38553a 100644 --- a/primitives/consensus/vrf/Cargo.toml +++ b/primitives/consensus/vrf/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-consensus-vrf" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] description = "Primitives for VRF based consensus" edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" repository = "https://github.com/paritytech/substrate/" homepage = "https://substrate.dev" @@ -14,9 +14,9 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { version = "1.0.0", package = "parity-scale-codec", default-features = false } schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"], default-features = false } -sp-std = { version = "2.0.0-dev", path = "../../std", default-features = false } -sp-core = { version = "2.0.0-dev", path = "../../core", default-features = false } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../runtime" } +sp-std = { version = "2.0.0-rc6", path = "../../std", default-features = false } +sp-core = { version = "2.0.0-rc6", path = "../../core", default-features = false } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../runtime" } [features] default = ["std"] diff --git a/primitives/consensus/vrf/README.md b/primitives/consensus/vrf/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d66490e023b3869c7d3c5a20c86dc5f69ba8a8ef --- /dev/null +++ b/primitives/consensus/vrf/README.md @@ -0,0 +1,3 @@ +Primitives for VRF-based consensus engines. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/consensus/vrf/src/lib.rs b/primitives/consensus/vrf/src/lib.rs index 4ec6e376d6829f15937e38d569c9edf1779b0927..430e11974bcd44cc6a3919ef1d8ad84af1357ddb 100644 --- a/primitives/consensus/vrf/src/lib.rs +++ b/primitives/consensus/vrf/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Primitives for VRF-based consensus engines. #![cfg_attr(not(feature = "std"), no_std)] diff --git a/primitives/consensus/vrf/src/schnorrkel.rs b/primitives/consensus/vrf/src/schnorrkel.rs index c1c2a7c21ab9e37b30df128e79065111b566ddca..65e68375865d05bb6e19929985abad3908218c4c 100644 --- a/primitives/consensus/vrf/src/schnorrkel.rs +++ b/primitives/consensus/vrf/src/schnorrkel.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Schnorrkel-based VRF. diff --git a/primitives/core/Cargo.toml b/primitives/core/Cargo.toml index 2ab23d23c4a0e691770941cb74bef3ac3d6a405b..1375fa228bfd1168a67b3f6387cb3ed68e7912d8 100644 --- a/primitives/core/Cargo.toml +++ b/primitives/core/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-core" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Shareable Substrate types." @@ -13,8 +13,9 @@ documentation = "https://docs.rs/sp-core" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +derive_more = "0.99.2" +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } log = { version = "0.4.8", default-features = false } serde = { version = "1.0.101", optional = true, features = ["derive"] } byteorder = { version = "1.3.2", default-features = false } @@ -30,16 +31,18 @@ tiny-bip39 = { version = "0.7", optional = true } regex = { version = "1.3.1", optional = true } num-traits = { version = "0.2.8", default-features = false } zeroize = { version = "1.0.0", default-features = false } +secrecy = { version = "0.6.0", default-features = false } lazy_static = { version = "1.4.0", default-features = false, optional = true } parking_lot = { version = "0.10.0", optional = true } -sp-debug-derive = { version = "2.0.0-dev", path = "../debug-derive" } -sp-externalities = { version = "0.8.0-dev", optional = true, path = "../externalities" } -sp-storage = { version = "2.0.0-dev", default-features = false, path = "../storage" } -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } +sp-debug-derive = { version = "2.0.0-rc6", path = "../debug-derive" } +sp-externalities = { version = "0.8.0-rc6", optional = true, path = "../externalities" } +sp-storage = { version = "2.0.0-rc6", default-features = false, path = "../storage" } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } futures = { version = "0.3.1", optional = true } +dyn-clonable = { version = "0.9.0", optional = true } # full crypto -ed25519-dalek = { version = "1.0.0-pre.3", default-features = false, features = ["u64_backend", "alloc"], optional = true } +ed25519-dalek = { version = "1.0.0-pre.4", default-features = false, features = ["u64_backend", "alloc"], optional = true } blake2-rfc = { version = "0.2.18", default-features = false, optional = true } tiny-keccak = { version = "2.0.1", features = ["keccak"], optional = true } schnorrkel = { version = "0.9.1", features = ["preaudit_deprecated", "u64_backend"], default-features = false, optional = true } @@ -49,15 +52,16 @@ twox-hash = { version = "1.5.0", default-features = false, optional = true } libsecp256k1 = { version = "0.3.2", default-features = false, features = ["hmac"], optional = true } merlin = { version = "2.0", default-features = false, optional = true } -sp-runtime-interface = { version = "2.0.0-dev", default-features = false, path = "../runtime-interface" } +sp-runtime-interface = { version = "2.0.0-rc6", default-features = false, path = "../runtime-interface" } [dev-dependencies] -sp-serializer = { version = "2.0.0-dev", path = "../serializer" } +sp-serializer = { version = "2.0.0-rc6", path = "../serializer" } pretty_assertions = "0.6.1" -hex-literal = "0.2.1" +hex-literal = "0.3.1" rand = "0.7.2" -criterion = "0.2.11" +criterion = "0.3.3" serde_json = "1.0" +rand_chacha = "0.2.2" [[bench]] name = "bench" @@ -104,9 +108,11 @@ std = [ "sp-storage/std", "sp-runtime-interface/std", "zeroize/alloc", + "secrecy/alloc", "futures", "futures/thread-pool", "libsecp256k1/std", + "dyn-clonable", ] # This feature enables all crypto primitives for `no_std` builds like microcontrollers diff --git a/primitives/core/benches/bench.rs b/primitives/core/benches/bench.rs index 7db9d72e6b5b0d6afa04c28f07c91c6491a4c541..dc57af459daa0f53c80aa67795e2d4f62d2fc2f3 100644 --- a/primitives/core/benches/bench.rs +++ b/primitives/core/benches/bench.rs @@ -13,6 +13,7 @@ // limitations under the License. + #[macro_use] extern crate criterion; @@ -106,9 +107,29 @@ fn bench_sr25519(c: &mut Criterion) { }, vec![32, 1024, 1024 * 1024]); } +fn bench_ecdsa(c: &mut Criterion) { + c.bench_function_over_inputs("signing - ecdsa", |b, &msg_size| { + let msg = (0..msg_size) + .map(|_| rand::random::()) + .collect::>(); + let key = sp_core::ecdsa::Pair::generate().0; + b.iter(|| key.sign(&msg)) + }, vec![32, 1024, 1024 * 1024]); + + c.bench_function_over_inputs("verifying - ecdsa", |b, &msg_size| { + let msg = (0..msg_size) + .map(|_| rand::random::()) + .collect::>(); + let key = sp_core::ecdsa::Pair::generate().0; + let sig = key.sign(&msg); + let public = key.public(); + b.iter(|| sp_core::ecdsa::Pair::verify(&sig, &msg, &public)) + }, vec![32, 1024, 1024 * 1024]); +} + criterion_group!{ name = benches; config = Criterion::default().warm_up_time(Duration::from_millis(500)).without_plots(); - targets = bench_hash_128_fix_size, bench_hash_128_dyn_size, bench_ed25519, bench_sr25519 + targets = bench_hash_128_fix_size, bench_hash_128_dyn_size, bench_ed25519, bench_sr25519, bench_ecdsa } criterion_main!(benches); diff --git a/primitives/core/src/changes_trie.rs b/primitives/core/src/changes_trie.rs index cb21ffe13df969141cb056056694914e4006ca9e..1d88242e43d69729d2c3e37697f63fc81d75f364 100644 --- a/primitives/core/src/changes_trie.rs +++ b/primitives/core/src/changes_trie.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Substrate changes trie configuration. diff --git a/primitives/core/src/crypto.rs b/primitives/core/src/crypto.rs index f725e94a42adab46d1c9a55977c17a8b8f72ad36..77a339ac7c6260c16069a738bff4a8c79aa363e5 100644 --- a/primitives/core/src/crypto.rs +++ b/primitives/core/src/crypto.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // tag::description[] //! Cryptographic utilities. @@ -36,10 +37,16 @@ use regex::Regex; use base58::{FromBase58, ToBase58}; #[cfg(feature = "std")] use crate::hexdisplay::HexDisplay; -use zeroize::Zeroize; #[doc(hidden)] pub use sp_std::ops::Deref; use sp_runtime_interface::pass_by::PassByInner; +/// Trait to zeroize a memory buffer. +pub use zeroize::Zeroize; +/// Trait for accessing reference to `SecretString`. +pub use secrecy::ExposeSecret; +/// A store for sensitive data. +#[cfg(feature = "std")] +pub use secrecy::SecretString; /// The root phrase for our publicly known keys. pub const DEV_PHRASE: &str = "bottom drive obey lake curtain smoke basket hold race lonely fit walk"; @@ -78,51 +85,6 @@ impl> UncheckedInto for S { } } -/// A store for sensitive data. -/// -/// Calls `Zeroize::zeroize` upon `Drop`. -#[derive(Clone)] -pub struct Protected(T); - -impl AsRef for Protected { - fn as_ref(&self) -> &T { - &self.0 - } -} - -impl sp_std::ops::Deref for Protected { - type Target = T; - - fn deref(&self) -> &T { - &self.0 - } -} - -#[cfg(feature = "std")] -impl std::fmt::Debug for Protected { - fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(fmt, "") - } -} - -impl From for Protected { - fn from(t: T) -> Self { - Protected(t) - } -} - -impl Zeroize for Protected { - fn zeroize(&mut self) { - self.0.zeroize() - } -} - -impl Drop for Protected { - fn drop(&mut self) { - self.zeroize() - } -} - /// An error with the interpretation of a secret. #[derive(Debug, Clone, PartialEq, Eq)] #[cfg(feature = "full_crypto")] @@ -218,7 +180,7 @@ impl DeriveJunction { impl> From for DeriveJunction { fn from(j: T) -> DeriveJunction { let j = j.as_ref(); - let (code, hard) = if j.starts_with("/") { + let (code, hard) = if j.starts_with('/') { (&j[1..], true) } else { (j, false) @@ -303,7 +265,6 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { } /// Return the ss58-check string for this key. - #[cfg(feature = "std")] fn to_ss58check_with_version(&self, version: Ss58AddressFormat) -> String { let mut v = vec![version.into()]; @@ -312,9 +273,11 @@ pub trait Ss58Codec: Sized + AsMut<[u8]> + AsRef<[u8]> + Default { v.extend(&r.as_bytes()[0..2]); v.to_base58() } + /// Return the ss58-check string for this key. #[cfg(feature = "std")] fn to_ss58check(&self) -> String { self.to_ss58check_with_version(*DEFAULT_VERSION.lock()) } + /// Some if the string is a properly encoded SS58Check address, optionally with /// a derivation path following. #[cfg(feature = "std")] @@ -355,18 +318,31 @@ lazy_static::lazy_static! { macro_rules! ss58_address_format { ( $( $identifier:tt => ($number:expr, $name:expr, $desc:tt) )* ) => ( /// A known address (sub)format/network ID for SS58. - #[derive(Copy, Clone, PartialEq, Eq)] + #[derive(Copy, Clone, PartialEq, Eq, crate::RuntimeDebug)] pub enum Ss58AddressFormat { $(#[doc = $desc] $identifier),*, /// Use a manually provided numeric value. Custom(u8), } + #[cfg(feature = "std")] + impl std::fmt::Display for Ss58AddressFormat { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } + } + static ALL_SS58_ADDRESS_FORMATS: [Ss58AddressFormat; 0 $(+ { let _ = $number; 1})*] = [ $(Ss58AddressFormat::$identifier),*, ]; impl Ss58AddressFormat { + /// names of all address formats + pub fn all_names() -> &'static [&'static str] { + &[ + $($name),*, + ] + } /// All known address formats. pub fn all() -> &'static [Ss58AddressFormat] { &ALL_SS58_ADDRESS_FORMATS @@ -396,22 +372,43 @@ macro_rules! ss58_address_format { fn try_from(x: u8) -> Result { match x { $($number => Ok(Ss58AddressFormat::$identifier)),*, - _ => Err(()), + _ => { + #[cfg(feature = "std")] + match Ss58AddressFormat::default() { + Ss58AddressFormat::Custom(n) if n == x => Ok(Ss58AddressFormat::Custom(x)), + _ => Err(()), + } + + #[cfg(not(feature = "std"))] + Err(()) + }, } } } + /// Error encountered while parsing `Ss58AddressFormat` from &'_ str + /// unit struct for now. + #[derive(Copy, Clone, PartialEq, Eq, crate::RuntimeDebug)] + pub struct ParseError; + impl<'a> TryFrom<&'a str> for Ss58AddressFormat { - type Error = (); + type Error = ParseError; - fn try_from(x: &'a str) -> Result { + fn try_from(x: &'a str) -> Result { match x { $($name => Ok(Ss58AddressFormat::$identifier)),*, - a => a.parse::().map(Ss58AddressFormat::Custom).map_err(|_| ()), + a => a.parse::().map(Ss58AddressFormat::Custom).map_err(|_| ParseError), } } } + #[cfg(feature = "std")] + impl std::fmt::Display for ParseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "failed to parse network value as u8") + } + } + #[cfg(feature = "std")] impl Default for Ss58AddressFormat { fn default() -> Self { @@ -441,6 +438,8 @@ ss58_address_format!( (2, "kusama", "Kusama Relay-chain, standard account (*25519).") Reserved3 => (3, "reserved3", "Reserved for future use (3).") + KatalChainAccount => + (4, "katalchain", "Katal Chain, standard account (*25519).") PlasmAccount => (5, "plasm", "Plasm Network, standard account (*25519).") BifrostAccount => @@ -457,20 +456,30 @@ ss58_address_format!( (11, "laminar", "Laminar mainnet, standard account (*25519).") PolymathAccount => (12, "polymath", "Polymath network, standard account (*25519).") + SubstraTeeAccount => + (13, "substratee", "Any SubstraTEE off-chain network private account (*25519).") KulupuAccount => (16, "kulupu", "Kulupu mainnet, standard account (*25519).") DarwiniaAccount => (18, "darwinia", "Darwinia Chain mainnet, standard account (*25519).") + StafiAccount => + (20, "stafi", "Stafi mainnet, standard account (*25519).") + SubsocialAccount => + (28, "subsocial", "Subsocial network, standard account (*25519).") + PhalaAccount => + (30, "phala", "Phala Network, standard account (*25519).") RobonomicsAccount => (32, "robonomics", "Any Robonomics network standard account (*25519).") + DataHighwayAccount => + (33, "datahighway", "DataHighway mainnet, standard account (*25519).") CentrifugeAccount => (36, "centrifuge", "Centrifuge Chain mainnet, standard account (*25519).") SubstrateAccount => (42, "substrate", "Any Substrate network, standard account (*25519).") Reserved43 => (43, "reserved43", "Reserved for future use (43).") - SubstraTeeAccount => - (44, "substratee", "Any SubstraTEE off-chain network private account (*25519).") + ChainXAccount => + (44, "chainx", "ChainX mainnet, standard account (*25519).") Reserved46 => (46, "reserved46", "Reserved for future use (46).") Reserved47 => @@ -559,6 +568,8 @@ pub trait Public: /// Return a slice filled with raw data. fn as_slice(&self) -> &[u8] { self.as_ref() } + /// Return `CryptoTypePublicPair` from public key. + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair; } /// An opaque 32-byte cryptographic identifier. @@ -671,6 +682,23 @@ impl<'de> serde::Deserialize<'de> for AccountId32 { } } +#[cfg(feature = "std")] +impl sp_std::str::FromStr for AccountId32 { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + let hex_or_ss58_without_prefix = s.trim_start_matches("0x"); + if hex_or_ss58_without_prefix.len() == 64 { + let mut bytes = [0u8; 32]; + hex::decode_to_slice(hex_or_ss58_without_prefix, &mut bytes) + .map_err(|_| "invalid hex address.") + .map(|_| Self::from(bytes)) + } else { + Self::from_ss58check(s).map_err(|_| "invalid ss58 address.") + } + } +} + #[cfg(feature = "std")] pub use self::dummy::*; @@ -706,6 +734,11 @@ mod dummy { #[cfg(feature = "std")] fn to_raw_vec(&self) -> Vec { vec![] } fn as_slice(&self) -> &[u8] { b"" } + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { + CryptoTypePublicPair( + CryptoTypeId(*b"dumm"), Public::to_raw_vec(self) + ) + } } impl Pair for Dummy { @@ -1061,6 +1094,11 @@ mod tests { fn to_raw_vec(&self) -> Vec { vec![] } + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { + CryptoTypePublicPair( + CryptoTypeId(*b"dumm"), self.to_raw_vec(), + ) + } } impl Pair for TestPair { type Public = TestPublic; @@ -1173,4 +1211,31 @@ mod tests { Ok(TestPair::Standard{phrase: "hello world".to_owned(), password: Some("password".to_owned()), path: vec![DeriveJunction::soft(1), DeriveJunction::hard("DOT")]}) ); } + + #[test] + fn accountid_32_from_str_works() { + use std::str::FromStr; + assert!(AccountId32::from_str("5G9VdMwXvzza9pS8qE8ZHJk3CheHW9uucBn9ngW4C1gmmzpv").is_ok()); + assert!(AccountId32::from_str("5c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").is_ok()); + assert!(AccountId32::from_str("0x5c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").is_ok()); + + assert_eq!( + AccountId32::from_str("99G9VdMwXvzza9pS8qE8ZHJk3CheHW9uucBn9ngW4C1gmmzpv").unwrap_err(), + "invalid ss58 address.", + ); + assert_eq!( + AccountId32::from_str("gc55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(), + "invalid hex address.", + ); + assert_eq!( + AccountId32::from_str("0xgc55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(), + "invalid hex address.", + ); + + // valid hex but invalid length will be treated as ss58. + assert_eq!( + AccountId32::from_str("55c55177d67b064bb5d189a3e1ddad9bc6646e02e64d6e308f5acbb1533ac430d").unwrap_err(), + "invalid ss58 address.", + ); + } } diff --git a/primitives/core/src/ecdsa.rs b/primitives/core/src/ecdsa.rs index 8a45157844f3af20ce5ded4ce3dc28f6008a5983..da6b7614c7fb55b5b7972a719c9460a845ddbc53 100644 --- a/primitives/core/src/ecdsa.rs +++ b/primitives/core/src/ecdsa.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // tag::description[] //! Simple ECDSA API. @@ -36,7 +37,8 @@ use crate::{hashing::blake2_256, crypto::{Pair as TraitPair, DeriveJunction, Sec use crate::crypto::Ss58Codec; #[cfg(feature = "std")] use serde::{de, Serializer, Serialize, Deserializer, Deserialize}; -use crate::crypto::{Public as TraitPublic, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; +use crate::crypto::{Public as TraitPublic, CryptoTypePublicPair, UncheckedFrom, CryptoType, Derive, CryptoTypeId}; +use sp_runtime_interface::pass_by::PassByInner; #[cfg(feature = "full_crypto")] use secp256k1::{PublicKey, SecretKey}; @@ -50,7 +52,7 @@ pub const CRYPTO_ID: CryptoTypeId = CryptoTypeId(*b"ecds"); type Seed = [u8; 32]; /// The ECDSA compressed public key. -#[derive(Clone, Encode, Decode)] +#[derive(Clone, Encode, Decode, PassByInner)] pub struct Public([u8; 33]); impl PartialOrd for Public { @@ -118,6 +120,22 @@ impl TraitPublic for Public { r.copy_from_slice(data); Self(r) } + + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { + CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) + } +} + +impl From for CryptoTypePublicPair { + fn from(key: Public) -> Self { + (&key).into() + } +} + +impl From<&Public> for CryptoTypePublicPair { + fn from(key: &Public) -> Self { + CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) + } } impl Derive for Public {} @@ -173,12 +191,17 @@ impl std::fmt::Display for Public { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for Public { +impl sp_std::fmt::Debug for Public { + #[cfg(feature = "std")] fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let s = self.to_ss58check(); write!(f, "{} ({}...)", crate::hexdisplay::HexDisplay::from(&self.as_ref()), &s[0..8]) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } } #[cfg(feature = "std")] @@ -204,7 +227,7 @@ impl sp_std::hash::Hash for Public { } /// A signature (a 512-bit value, plus 8 bits for recovery ID). -#[derive(Encode, Decode)] +#[derive(Encode, Decode, PassByInner)] pub struct Signature([u8; 65]); impl sp_std::convert::TryFrom<&[u8]> for Signature { @@ -284,11 +307,16 @@ impl AsMut<[u8]> for Signature { } } -#[cfg(feature = "std")] -impl std::fmt::Debug for Signature { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl sp_std::fmt::Debug for Signature { + #[cfg(feature = "std")] + fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { write!(f, "{}", crate::hexdisplay::HexDisplay::from(&self.0)) } + + #[cfg(not(feature = "std"))] + fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result { + Ok(()) + } } #[cfg(feature = "full_crypto")] @@ -524,7 +552,7 @@ impl CryptoType for Pair { mod test { use super::*; use hex_literal::hex; - use crate::crypto::DEV_PHRASE; + use crate::crypto::{DEV_PHRASE, set_default_ss58_version}; use serde_json; #[test] @@ -648,6 +676,22 @@ mod test { assert_eq!(cmp, public); } + #[test] + fn ss58check_custom_format_works() { + use crate::crypto::Ss58AddressFormat; + // temp save default format version + let default_format = Ss58AddressFormat::default(); + // set current ss58 version is custom "200" `Ss58AddressFormat::Custom(200)` + set_default_ss58_version(Ss58AddressFormat::Custom(200)); + // custom addr encoded by version 200 + let addr = "2X64kMNEWAW5KLZMSKcGKEc96MyuaRsRUku7vomuYxKgqjVCRj"; + Public::from_ss58check(&addr).unwrap(); + set_default_ss58_version(default_format); + // set current ss58 version to default version + let addr = "KWAfgC2aRG5UVD6CpbPQXCx4YZZUhvWqqAJE6qcYc9Rtr6g5C"; + Public::from_ss58check(&addr).unwrap(); + } + #[test] fn signature_serialization_works() { let pair = Pair::from_seed(b"12345678901234567890123456789012"); diff --git a/primitives/core/src/ed25519.rs b/primitives/core/src/ed25519.rs index abeac05388d2773e7ba80f60d6b4e9193ebe2fcd..fcc84c5c2edcf6045be4ec4cc9ce0a2d8ea95012 100644 --- a/primitives/core/src/ed25519.rs +++ b/primitives/core/src/ed25519.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // tag::description[] //! Simple Ed25519 API. @@ -28,6 +29,8 @@ use codec::{Encode, Decode}; use blake2_rfc; #[cfg(feature = "full_crypto")] use core::convert::TryFrom; +#[cfg(feature = "full_crypto")] +use ed25519_dalek::{Signer as _, Verifier as _}; #[cfg(feature = "std")] use substrate_bip39::seed_from_entropy; #[cfg(feature = "std")] @@ -377,20 +380,24 @@ impl TraitPublic for Public { r.copy_from_slice(data); Public(r) } + + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { + CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) + } } impl Derive for Public {} impl From for CryptoTypePublicPair { - fn from(key: Public) -> Self { - (&key).into() - } + fn from(key: Public) -> Self { + (&key).into() + } } impl From<&Public> for CryptoTypePublicPair { - fn from(key: &Public) -> Self { - CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) - } + fn from(key: &Public) -> Self { + CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) + } } /// Derive a single hard junction. @@ -508,7 +515,7 @@ impl TraitPair for Pair { Err(_) => return false, }; - let sig = match ed25519_dalek::Signature::from_bytes(sig) { + let sig = match ed25519_dalek::Signature::try_from(sig) { Ok(s) => s, Err(_) => return false }; diff --git a/primitives/core/src/hash.rs b/primitives/core/src/hash.rs index 424fefbe6a47028f773699a0f27a1a78a7f66ae4..20a6788c3207029eacba04c0e8faae79ee1ef3fd 100644 --- a/primitives/core/src/hash.rs +++ b/primitives/core/src/hash.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! A fixed hash type. diff --git a/primitives/core/src/hasher.rs b/primitives/core/src/hasher.rs index 28da432da7142b1a8ada83946088a03eb90d54ee..8ccaa4d90a78d7e697750f18f0b35fbcb8351396 100644 --- a/primitives/core/src/hasher.rs +++ b/primitives/core/src/hasher.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Substrate Blake2b Hasher implementation @@ -35,3 +36,23 @@ pub mod blake2 { } } } + +pub mod keccak { + use hash_db::Hasher; + use hash256_std_hasher::Hash256StdHasher; + use crate::hash::H256; + + /// Concrete implementation of Hasher using Keccak 256-bit hashes + #[derive(Debug)] + pub struct KeccakHasher; + + impl Hasher for KeccakHasher { + type Out = H256; + type StdHasher = Hash256StdHasher; + const LENGTH: usize = 32; + + fn hash(x: &[u8]) -> Self::Out { + crate::hashing::keccak_256(x).into() + } + } +} diff --git a/primitives/core/src/hashing.rs b/primitives/core/src/hashing.rs index d958da6c321380301d087cd40951bc3c50c12b2f..f61700a5a43cdcff29946cfffaa39131187236a9 100644 --- a/primitives/core/src/hashing.rs +++ b/primitives/core/src/hashing.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Hashing functions. diff --git a/primitives/core/src/hexdisplay.rs b/primitives/core/src/hexdisplay.rs index 14fedc205c49ebd87b2af807975f3c6d7ddf0c72..9d2b7a12d032ecfa1f99febe302e5486351da0bd 100644 --- a/primitives/core/src/hexdisplay.rs +++ b/primitives/core/src/hexdisplay.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Wrapper type for byte collections that outputs hex. @@ -66,7 +67,7 @@ impl AsBytesRef for [u8] { fn as_bytes_ref(&self) -> &[u8] { &self } } -impl AsBytesRef for Vec { +impl AsBytesRef for sp_std::vec::Vec { fn as_bytes_ref(&self) -> &[u8] { &self } } @@ -83,6 +84,7 @@ impl_non_endians!([u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 48], [u8; 56], [u8; 64], [u8; 65], [u8; 80], [u8; 96], [u8; 112], [u8; 128]); /// Format into ASCII + # + hex, suitable for storage key preimages. +#[cfg(feature = "std")] pub fn ascii_format(asciish: &[u8]) -> String { let mut r = String::new(); let mut latch = false; diff --git a/primitives/core/src/lib.rs b/primitives/core/src/lib.rs index 9da56018e95d7abeececd5122f371a1766d05bb3..2a40972166e1496f26cdf4abe3f7648abcb61e04 100644 --- a/primitives/core/src/lib.rs +++ b/primitives/core/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Shareable Substrate types. @@ -49,9 +50,9 @@ pub use impl_serde::serialize as bytes; #[cfg(feature = "full_crypto")] pub mod hashing; + #[cfg(feature = "full_crypto")] pub use hashing::{blake2_128, blake2_256, twox_64, twox_128, twox_256, keccak_256}; -#[cfg(feature = "std")] pub mod hexdisplay; pub mod crypto; @@ -71,7 +72,7 @@ mod changes_trie; pub mod traits; pub mod testing; #[cfg(feature = "std")] -pub mod tasks; +pub mod vrf; pub use self::hash::{H160, H256, H512, convert_hash}; pub use self::uint::{U256, U512}; @@ -82,6 +83,8 @@ pub use crypto::{DeriveJunction, Pair, Public}; pub use hash_db::Hasher; #[cfg(feature = "std")] pub use self::hasher::blake2::Blake2Hasher; +#[cfg(feature = "std")] +pub use self::hasher::keccak::KeccakHasher; pub use sp_storage as storage; @@ -90,9 +93,16 @@ pub use sp_std; /// Context for executing a call into the runtime. pub enum ExecutionContext { - /// Context for general importing (including own blocks). + /// Context used for general block import (including locally authored blocks). Importing, - /// Context used when syncing the blockchain. + /// Context used for importing blocks as part of an initial sync of the blockchain. + /// + /// We distinguish between major sync and import so that validators who are running + /// their initial sync (or catching up after some time offline) can use the faster + /// native runtime (since we can reasonably assume the network as a whole has already + /// come to a broad conensus on the block and it probably hasn't been crafted + /// specifically to attack this node), but when importing blocks at the head of the + /// chain in normal operation they can use the safer Wasm version. Syncing, /// Context used for block construction. BlockConstruction, @@ -321,6 +331,11 @@ pub fn to_substrate_wasm_fn_return_value(value: &impl Encode) -> u64 { res } +/// The void type - it cannot exist. +// Oh rust, you crack me up... +#[derive(Clone, Decode, Encode, Eq, PartialEq, RuntimeDebug)] +pub enum Void {} + /// Macro for creating `Maybe*` marker traits. /// /// Such a maybe-marker trait requires the given bound when `feature = std` and doesn't require diff --git a/primitives/core/src/offchain/mod.rs b/primitives/core/src/offchain/mod.rs index e792d71afca3b41bf8f312d34dba2859ae324986..b2ff3552135ce935a2e8d3a79c7533baa5afa117 100644 --- a/primitives/core/src/offchain/mod.rs +++ b/primitives/core/src/offchain/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Offchain workers types @@ -36,6 +37,9 @@ pub trait OffchainStorage: Clone + Send + Sync { /// Persist a value in storage under given key and prefix. fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]); + /// Clear a storage entry under given key and prefix. + fn remove(&mut self, prefix: &[u8], key: &[u8]); + /// Retrieve a value from storage under given key and prefix. fn get(&self, prefix: &[u8], key: &[u8]) -> Option>; @@ -218,7 +222,7 @@ pub struct Duration(u64); impl Duration { /// Create new duration representing given number of milliseconds. - pub fn from_millis(millis: u64) -> Self { + pub const fn from_millis(millis: u64) -> Self { Duration(millis) } @@ -345,9 +349,15 @@ pub trait Externalities: Send { /// Sets a value in the local storage. /// /// Note this storage is not part of the consensus, it's only accessible by - /// offchain worker tasks running on the same machine. It IS persisted between runs. + /// offchain worker tasks running on the same machine. It _is_ persisted between runs. fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]); + /// Removes a value in the local storage. + /// + /// Note this storage is not part of the consensus, it's only accessible by + /// offchain worker tasks running on the same machine. It _is_ persisted between runs. + fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]); + /// Sets a value in the local storage if it matches current value. /// /// Since multiple offchain workers may be running concurrently, to prevent @@ -356,7 +366,7 @@ pub trait Externalities: Send { /// Returns `true` if the value has been set, `false` otherwise. /// /// Note this storage is not part of the consensus, it's only accessible by - /// offchain worker tasks running on the same machine. It IS persisted between runs. + /// offchain worker tasks running on the same machine. It _is_ persisted between runs. fn local_storage_compare_and_set( &mut self, kind: StorageKind, @@ -369,7 +379,7 @@ pub trait Externalities: Send { /// /// If the value does not exist in the storage `None` will be returned. /// Note this storage is not part of the consensus, it's only accessible by - /// offchain worker tasks running on the same machine. It IS persisted between runs. + /// offchain worker tasks running on the same machine. It _is_ persisted between runs. fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option>; /// Initiates a http request given HTTP verb and the URL. @@ -512,6 +522,10 @@ impl Externalities for Box { (&mut **self).local_storage_set(kind, key, value) } + fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { + (&mut **self).local_storage_clear(kind, key) + } + fn local_storage_compare_and_set( &mut self, kind: StorageKind, @@ -617,6 +631,11 @@ impl Externalities for LimitedExternalities { self.externalities.local_storage_set(kind, key, value) } + fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { + self.check(Capability::OffchainWorkerDbWrite, "local_storage_clear"); + self.externalities.local_storage_clear(kind, key) + } + fn local_storage_compare_and_set( &mut self, kind: StorageKind, diff --git a/primitives/core/src/offchain/storage.rs b/primitives/core/src/offchain/storage.rs index 830c25392b7426e1f48257487fbbe09fdf8fdd99..7d7c711ed95f046ccf33e1e3d2e8262c9d2bb06a 100644 --- a/primitives/core/src/offchain/storage.rs +++ b/primitives/core/src/offchain/storage.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! In-memory implementation of offchain workers database. @@ -50,6 +51,11 @@ impl OffchainStorage for InMemOffchainStorage { self.storage.insert(key, value.to_vec()); } + fn remove(&mut self, prefix: &[u8], key: &[u8]) { + let key: Vec = prefix.iter().chain(key).cloned().collect(); + self.storage.remove(&key); + } + fn get(&self, prefix: &[u8], key: &[u8]) -> Option> { let key: Vec = prefix.iter().chain(key).cloned().collect(); self.storage.get(&key).cloned() @@ -95,8 +101,9 @@ pub enum OffchainOverlayedChange { pub enum OffchainOverlayedChanges { /// Writing overlay changes to the offchain worker database is disabled by configuration. Disabled, - /// Overlay changes can be recorded using the inner collection of this variant. - Enabled(HashMap, OffchainOverlayedChange>), + /// Overlay changes can be recorded using the inner collection of this variant, + /// where the identifier is the tuple of `(prefix, key)`. + Enabled(HashMap<(Vec, Vec), OffchainOverlayedChange>), } impl Default for OffchainOverlayedChanges { @@ -134,23 +141,21 @@ impl OffchainOverlayedChanges { /// Remove a key and its associated value from the offchain database. pub fn remove(&mut self, prefix: &[u8], key: &[u8]) { if let Self::Enabled(ref mut storage) = self { - let key: Vec = prefix.iter().chain(key).cloned().collect(); - let _ = storage.insert(key, OffchainOverlayedChange::Remove); + let _ = storage.insert((prefix.to_vec(), key.to_vec()), OffchainOverlayedChange::Remove); } } /// Set the value associated with a key under a prefix to the value provided. pub fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) { if let Self::Enabled(ref mut storage) = self { - let key = prefix.iter().chain(key).cloned().collect(); - let _ = storage.insert(key, OffchainOverlayedChange::SetValue(value.to_vec())); + let _ = storage.insert((prefix.to_vec(), key.to_vec()), OffchainOverlayedChange::SetValue(value.to_vec())); } } /// Obtain a associated value to the given key in storage with prefix. pub fn get(&self, prefix: &[u8], key: &[u8]) -> Option { if let Self::Enabled(ref storage) = self { - let key: Vec = prefix.iter().chain(key).cloned().collect(); + let key = (prefix.to_vec(), key.to_vec()); storage.get(&key).cloned() } else { None @@ -162,11 +167,11 @@ use std::collections::hash_map; /// Iterate by reference over the prepared offchain worker storage changes. pub struct OffchainOverlayedChangesIter<'i> { - inner: Option, OffchainOverlayedChange>>, + inner: Option, Vec), OffchainOverlayedChange>>, } impl<'i> Iterator for OffchainOverlayedChangesIter<'i> { - type Item = (&'i Vec, &'i OffchainOverlayedChange); + type Item = (&'i (Vec, Vec), &'i OffchainOverlayedChange); fn next(&mut self) -> Option { if let Some(ref mut iter) = self.inner { iter.next() @@ -191,11 +196,11 @@ impl<'i> OffchainOverlayedChangesIter<'i> { /// Iterate by value over the prepared offchain worker storage changes. pub struct OffchainOverlayedChangesIntoIter { - inner: Option,OffchainOverlayedChange>>, + inner: Option,Vec),OffchainOverlayedChange>>, } impl Iterator for OffchainOverlayedChangesIntoIter { - type Item = (Vec, OffchainOverlayedChange); + type Item = ((Vec, Vec), OffchainOverlayedChange); fn next(&mut self) -> Option { if let Some(ref mut iter) = self.inner { iter.next() @@ -219,11 +224,11 @@ impl OffchainOverlayedChangesIntoIter { /// Iterate over all items while draining them from the collection. pub struct OffchainOverlayedChangesDrain<'d> { - inner: Option,OffchainOverlayedChange>>, + inner: Option, Vec), OffchainOverlayedChange>>, } impl<'d> Iterator for OffchainOverlayedChangesDrain<'d> { - type Item = (Vec, OffchainOverlayedChange); + type Item = ((Vec, Vec), OffchainOverlayedChange); fn next(&mut self) -> Option { if let Some(ref mut iter) = self.inner { iter.next() @@ -280,9 +285,13 @@ mod test { ooc.set(STORAGE_PREFIX, b"ppp", b"rrr"); let mut iter = ooc.into_iter(); - let mut k = STORAGE_PREFIX.to_vec(); - k.extend_from_slice(&b"ppp"[..]); - assert_eq!(iter.next(), Some((k, OffchainOverlayedChange::SetValue(b"rrr".to_vec())))); + assert_eq!( + iter.next(), + Some( + ((STORAGE_PREFIX.to_vec(), b"ppp".to_vec()), + OffchainOverlayedChange::SetValue(b"rrr".to_vec())) + ) + ); assert_eq!(iter.next(), None); } } diff --git a/primitives/core/src/offchain/testing.rs b/primitives/core/src/offchain/testing.rs index b889374a47c2fd26baee2f0fdcec28a6a73cc786..c939c5cfccc14773e1ad4fe59026766da4d79d75 100644 --- a/primitives/core/src/offchain/testing.rs +++ b/primitives/core/src/offchain/testing.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Utilities for offchain calls testing. //! @@ -20,12 +21,12 @@ //! the extra APIs. use std::{ - collections::BTreeMap, + collections::{BTreeMap, VecDeque}, sync::Arc, }; use crate::offchain::{ self, - storage::InMemOffchainStorage, + storage::{InMemOffchainStorage, OffchainOverlayedChange, OffchainOverlayedChanges}, HttpError, HttpRequestId as RequestId, HttpRequestStatus as RequestStatus, @@ -35,6 +36,7 @@ use crate::offchain::{ TransactionPool, OffchainStorage, }; + use parking_lot::RwLock; /// Pending request. @@ -60,6 +62,57 @@ pub struct PendingRequest { pub response_headers: Vec<(String, String)>, } +/// Sharable "persistent" offchain storage for test. +#[derive(Debug, Clone, Default)] +pub struct TestPersistentOffchainDB { + persistent: Arc>, +} + +impl TestPersistentOffchainDB { + /// Create a new and empty offchain storage db for persistent items + pub fn new() -> Self { + Self { + persistent: Arc::new(RwLock::new(InMemOffchainStorage::default())) + } + } + + /// Apply a set of off-chain changes directly to the test backend + pub fn apply_offchain_changes(&mut self, changes: &mut OffchainOverlayedChanges) { + let mut me = self.persistent.write(); + for ((_prefix, key), value_operation) in changes.drain() { + match value_operation { + OffchainOverlayedChange::SetValue(val) => me.set(b"", key.as_slice(), val.as_slice()), + OffchainOverlayedChange::Remove => me.remove(b"", key.as_slice()), + } + } + } +} + +impl OffchainStorage for TestPersistentOffchainDB { + fn set(&mut self, prefix: &[u8], key: &[u8], value: &[u8]) { + self.persistent.write().set(prefix, key, value); + } + + fn remove(&mut self, prefix: &[u8], key: &[u8]) { + self.persistent.write().remove(prefix, key); + } + + fn get(&self, prefix: &[u8], key: &[u8]) -> Option> { + self.persistent.read().get(prefix, key) + } + + fn compare_and_set( + &mut self, + prefix: &[u8], + key: &[u8], + old_value: Option<&[u8]>, + new_value: &[u8], + ) -> bool { + self.persistent.write().compare_and_set(prefix, key, old_value, new_value) + } +} + + /// Internal state of the externalities. /// /// This can be used in tests to respond or assert stuff about interactions. @@ -67,15 +120,16 @@ pub struct PendingRequest { pub struct OffchainState { /// A list of pending requests. pub requests: BTreeMap, - expected_requests: BTreeMap, + // Queue of requests that the test is expected to perform (in order). + expected_requests: VecDeque, /// Persistent local storage - pub persistent_storage: InMemOffchainStorage, + pub persistent_storage: TestPersistentOffchainDB, /// Local storage pub local_storage: InMemOffchainStorage, - /// Current timestamp (unix millis) - pub timestamp: u64, /// A supposedly random seed. pub seed: [u8; 32], + /// A timestamp simulating the current time. + pub timestamp: Timestamp, } impl OffchainState { @@ -103,8 +157,8 @@ impl OffchainState { } fn fulfill_expected(&mut self, id: u16) { - if let Some(mut req) = self.expected_requests.remove(&RequestId(id)) { - let response = req.response.take().expect("Response checked while added."); + if let Some(mut req) = self.expected_requests.pop_back() { + let response = req.response.take().expect("Response checked when added."); let headers = std::mem::take(&mut req.response_headers); self.fulfill_pending_request(id, req, response, headers); } @@ -116,11 +170,12 @@ impl OffchainState { /// before running the actual code that utilizes them (for instance before calling into runtime). /// Expected request has to be fulfilled before this struct is dropped, /// the `response` and `response_headers` fields will be used to return results to the callers. - pub fn expect_request(&mut self, id: u16, expected: PendingRequest) { + /// Requests are expected to be performed in the insertion order. + pub fn expect_request(&mut self, expected: PendingRequest) { if expected.response.is_none() { panic!("Expected request needs to have a response."); } - self.expected_requests.insert(RequestId(id), expected); + self.expected_requests.push_front(expected); } } @@ -144,6 +199,13 @@ impl TestOffchainExt { let state = ext.0.clone(); (ext, state) } + + /// Create new `TestOffchainExt` and a reference to the internal state. + pub fn with_offchain_db(offchain_db: TestPersistentOffchainDB) -> (Self, Arc>) { + let (ext, state) = Self::new(); + ext.0.write().persistent_storage = offchain_db; + (ext, state) + } } impl offchain::Externalities for TestOffchainExt { @@ -159,11 +221,11 @@ impl offchain::Externalities for TestOffchainExt { } fn timestamp(&mut self) -> Timestamp { - Timestamp::from_unix_millis(self.0.read().timestamp) + self.0.read().timestamp } - fn sleep_until(&mut self, _deadline: Timestamp) { - unimplemented!("not needed in tests so far") + fn sleep_until(&mut self, deadline: Timestamp) { + self.0.write().timestamp = deadline; } fn random_seed(&mut self) -> [u8; 32] { @@ -173,9 +235,17 @@ impl offchain::Externalities for TestOffchainExt { fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) { let mut state = self.0.write(); match kind { - StorageKind::LOCAL => &mut state.local_storage, - StorageKind::PERSISTENT => &mut state.persistent_storage, - }.set(b"", key, value); + StorageKind::LOCAL => state.local_storage.set(b"", key, value), + StorageKind::PERSISTENT => state.persistent_storage.set(b"", key, value), + }; + } + + fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { + let mut state = self.0.write(); + match kind { + StorageKind::LOCAL => state.local_storage.remove(b"", key), + StorageKind::PERSISTENT => state.persistent_storage.remove(b"", key), + }; } fn local_storage_compare_and_set( @@ -187,17 +257,17 @@ impl offchain::Externalities for TestOffchainExt { ) -> bool { let mut state = self.0.write(); match kind { - StorageKind::LOCAL => &mut state.local_storage, - StorageKind::PERSISTENT => &mut state.persistent_storage, - }.compare_and_set(b"", key, old_value, new_value) + StorageKind::LOCAL => state.local_storage.compare_and_set(b"", key, old_value, new_value), + StorageKind::PERSISTENT => state.persistent_storage.compare_and_set(b"", key, old_value, new_value), + } } fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option> { let state = self.0.read(); match kind { - StorageKind::LOCAL => &state.local_storage, - StorageKind::PERSISTENT => &state.persistent_storage, - }.get(b"", key) + StorageKind::LOCAL => state.local_storage.get(b"", key), + StorageKind::PERSISTENT => state.persistent_storage.get(b"", key), + } } fn http_request_start(&mut self, method: &str, uri: &str, meta: &[u8]) -> Result { @@ -289,7 +359,7 @@ impl offchain::Externalities for TestOffchainExt { if let Some(req) = state.requests.get_mut(&request_id) { let response = req.response .as_mut() - .expect(&format!("No response provided for request: {:?}", request_id)); + .unwrap_or_else(|| panic!("No response provided for request: {:?}", request_id)); if req.read >= response.len() { // Remove the pending request as per spec. diff --git a/primitives/core/src/sandbox.rs b/primitives/core/src/sandbox.rs index 73fbcfb572ee355f645dc716f197ef8f29a7292d..4cb5bd41d5826bd3f7d8a581f424d368a11cf070 100644 --- a/primitives/core/src/sandbox.rs +++ b/primitives/core/src/sandbox.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Definition of a sandbox environment. diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index cadfb25776b83552ee2ef8794660dd3a4ef34f73..b015347e9aa280d8189d8212c247699ee4be31f8 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // tag::description[] //! Simple sr25519 (Schnorr-Ristretto) API. @@ -391,18 +392,22 @@ impl TraitPublic for Public { r.copy_from_slice(data); Public(r) } + + fn to_public_crypto_pair(&self) -> CryptoTypePublicPair { + CryptoTypePublicPair(CRYPTO_ID, self.to_raw_vec()) + } } impl From for CryptoTypePublicPair { - fn from(key: Public) -> Self { - (&key).into() - } + fn from(key: Public) -> Self { + (&key).into() + } } impl From<&Public> for CryptoTypePublicPair { - fn from(key: &Public) -> Self { - CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) - } + fn from(key: &Public) -> Self { + CryptoTypePublicPair(CRYPTO_ID, key.to_raw_vec()) + } } #[cfg(feature = "std")] diff --git a/primitives/core/src/tasks.rs b/primitives/core/src/tasks.rs deleted file mode 100644 index 199a185e5371a0efdd272e824d934d07f994d1e3..0000000000000000000000000000000000000000 --- a/primitives/core/src/tasks.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Module for low-level asynchronous processing. - -use crate::traits::CloneableSpawn; -use futures::{executor, task}; - -/// Simple task executor. -/// -/// Uses single thread for scheduling tasks. Can be cloned and used in -/// runtime host (implements `CloneableSpawn`). -#[derive(Debug, Clone)] -pub struct Executor { - pool: executor::ThreadPool, -} - -impl Executor { - fn new() -> Self { - Self { - pool: executor::ThreadPool::builder().pool_size(1).create() - .expect("Failed to create task executor") - } - } -} - -impl task::Spawn for Executor { - fn spawn_obj(&self, future: task::FutureObj<'static, ()>) - -> Result<(), task::SpawnError> { - self.pool.spawn_obj(future) - } -} - -impl CloneableSpawn for Executor { - fn clone(&self) -> Box { - Box::new(Clone::clone(self)) - } -} - -/// Create tasks executor. -pub fn executor() -> Box { - Box::new(Executor::new()) -} \ No newline at end of file diff --git a/primitives/core/src/testing.rs b/primitives/core/src/testing.rs index f818865d2197e434573146174f190ed7284d4617..5c4af736c4f5344db2c8f3a421e97c1daff6dd75 100644 --- a/primitives/core/src/testing.rs +++ b/primitives/core/src/testing.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Types that should only be used for testing! @@ -20,15 +21,19 @@ use crate::crypto::KeyTypeId; #[cfg(feature = "std")] use crate::{ crypto::{Pair, Public, CryptoTypePublicPair}, - ed25519, sr25519, - traits::BareCryptoStoreError + ed25519, sr25519, ecdsa, + traits::Error, + vrf::{VRFTranscriptData, VRFSignature, make_transcript}, }; #[cfg(feature = "std")] use std::collections::HashSet; + /// Key type for generic Ed25519 key. pub const ED25519: KeyTypeId = KeyTypeId(*b"ed25"); /// Key type for generic Sr 25519 key. pub const SR25519: KeyTypeId = KeyTypeId(*b"sr25"); +/// Key type for generic Sr 25519 key. +pub const ECDSA: KeyTypeId = KeyTypeId(*b"ecds"); /// A keystore implementation usable in tests. #[cfg(feature = "std")] @@ -61,11 +66,19 @@ impl KeyStore { ) } + fn ecdsa_key_pair(&self, id: KeyTypeId, pub_key: &ecdsa::Public) -> Option { + self.keys.get(&id) + .and_then(|inner| + inner.get(pub_key.as_slice()) + .map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid")) + ) + } + } #[cfg(feature = "std")] impl crate::traits::BareCryptoStore for KeyStore { - fn keys(&self, id: KeyTypeId) -> Result, BareCryptoStoreError> { + fn keys(&self, id: KeyTypeId) -> Result, Error> { self.keys .get(&id) .map(|map| { @@ -73,10 +86,11 @@ impl crate::traits::BareCryptoStore for KeyStore { .fold(Vec::new(), |mut v, k| { v.push(CryptoTypePublicPair(sr25519::CRYPTO_ID, k.clone())); v.push(CryptoTypePublicPair(ed25519::CRYPTO_ID, k.clone())); + v.push(CryptoTypePublicPair(ecdsa::CRYPTO_ID, k.clone())); v })) }) - .unwrap_or(Ok(vec![])) + .unwrap_or_else(|| Ok(vec![])) } fn sr25519_public_keys(&self, id: KeyTypeId) -> Vec { @@ -94,11 +108,11 @@ impl crate::traits::BareCryptoStore for KeyStore { &mut self, id: KeyTypeId, seed: Option<&str>, - ) -> Result { + ) -> Result { match seed { Some(seed) => { let pair = sr25519::Pair::from_string(seed, None) - .map_err(|_| BareCryptoStoreError::ValidationError("Generates an `sr25519` pair.".to_owned()))?; + .map_err(|_| Error::ValidationError("Generates an `sr25519` pair.".to_owned()))?; self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); Ok(pair.public()) }, @@ -125,11 +139,11 @@ impl crate::traits::BareCryptoStore for KeyStore { &mut self, id: KeyTypeId, seed: Option<&str>, - ) -> Result { + ) -> Result { match seed { Some(seed) => { let pair = ed25519::Pair::from_string(seed, None) - .map_err(|_| BareCryptoStoreError::ValidationError("Generates an `ed25519` pair.".to_owned()))?; + .map_err(|_| Error::ValidationError("Generates an `ed25519` pair.".to_owned()))?; self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); Ok(pair.public()) }, @@ -141,6 +155,37 @@ impl crate::traits::BareCryptoStore for KeyStore { } } + fn ecdsa_public_keys(&self, id: KeyTypeId) -> Vec { + self.keys.get(&id) + .map(|keys| + keys.values() + .map(|s| ecdsa::Pair::from_string(s, None).expect("`ecdsa` seed slice is valid")) + .map(|p| p.public()) + .collect() + ) + .unwrap_or_default() + } + + fn ecdsa_generate_new( + &mut self, + id: KeyTypeId, + seed: Option<&str>, + ) -> Result { + match seed { + Some(seed) => { + let pair = ecdsa::Pair::from_string(seed, None) + .map_err(|_| Error::ValidationError("Generates an `ecdsa` pair.".to_owned()))?; + self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), seed.into()); + Ok(pair.public()) + }, + None => { + let (pair, phrase, _) = ecdsa::Pair::generate_with_phrase(None); + self.keys.entry(id).or_default().insert(pair.public().to_raw_vec(), phrase); + Ok(pair.public()) + } + } + } + fn insert_unknown(&mut self, id: KeyTypeId, suri: &str, public: &[u8]) -> Result<(), ()> { self.keys.entry(id).or_default().insert(public.to_owned(), suri.to_string()); Ok(()) @@ -158,7 +203,7 @@ impl crate::traits::BareCryptoStore for KeyStore { &self, id: KeyTypeId, keys: Vec, - ) -> std::result::Result, BareCryptoStoreError> { + ) -> std::result::Result, Error> { let provided_keys = keys.into_iter().collect::>(); let all_keys = self.keys(id)?.into_iter().collect::>(); @@ -170,25 +215,48 @@ impl crate::traits::BareCryptoStore for KeyStore { id: KeyTypeId, key: &CryptoTypePublicPair, msg: &[u8], - ) -> Result, BareCryptoStoreError> { + ) -> Result, Error> { use codec::Encode; match key.0 { ed25519::CRYPTO_ID => { let key_pair: ed25519::Pair = self .ed25519_key_pair(id, &ed25519::Public::from_slice(key.1.as_slice())) - .ok_or(BareCryptoStoreError::PairNotFound("ed25519".to_owned()))?; + .ok_or_else(|| Error::PairNotFound("ed25519".to_owned()))?; return Ok(key_pair.sign(msg).encode()); } sr25519::CRYPTO_ID => { let key_pair: sr25519::Pair = self .sr25519_key_pair(id, &sr25519::Public::from_slice(key.1.as_slice())) - .ok_or(BareCryptoStoreError::PairNotFound("sr25519".to_owned()))?; + .ok_or_else(|| Error::PairNotFound("sr25519".to_owned()))?; return Ok(key_pair.sign(msg).encode()); } - _ => Err(BareCryptoStoreError::KeyNotSupported(id)) + ecdsa::CRYPTO_ID => { + let key_pair: ecdsa::Pair = self + .ecdsa_key_pair(id, &ecdsa::Public::from_slice(key.1.as_slice())) + .ok_or_else(|| Error::PairNotFound("ecdsa".to_owned()))?; + return Ok(key_pair.sign(msg).encode()); + } + _ => Err(Error::KeyNotSupported(id)) } } + + fn sr25519_vrf_sign( + &self, + key_type: KeyTypeId, + public: &sr25519::Public, + transcript_data: VRFTranscriptData, + ) -> Result { + let transcript = make_transcript(transcript_data); + let pair = self.sr25519_key_pair(key_type, public) + .ok_or_else(|| Error::PairNotFound("Not found".to_owned()))?; + + let (inout, proof, _) = pair.as_ref().vrf_sign(transcript); + Ok(VRFSignature { + output: inout.to_output(), + proof, + }) + } } /// Macro for exporting functions from wasm in with the expected signature for using it with the @@ -291,16 +359,16 @@ macro_rules! wasm_export_functions { }; } -/// An executor that supports spawning blocking futures in tests. +/// A task executor that can be used in tests. /// /// Internally this just wraps a `ThreadPool` with a pool size of `8`. This /// should ensure that we have enough threads in tests for spawning blocking futures. #[cfg(feature = "std")] #[derive(Clone)] -pub struct SpawnBlockingExecutor(futures::executor::ThreadPool); +pub struct TaskExecutor(futures::executor::ThreadPool); #[cfg(feature = "std")] -impl SpawnBlockingExecutor { +impl TaskExecutor { /// Create a new instance of `Self`. pub fn new() -> Self { let mut builder = futures::executor::ThreadPoolBuilder::new(); @@ -309,10 +377,13 @@ impl SpawnBlockingExecutor { } #[cfg(feature = "std")] -impl crate::traits::SpawnBlocking for SpawnBlockingExecutor { +impl crate::traits::SpawnNamed for TaskExecutor { fn spawn_blocking(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) { self.0.spawn_ok(future); } + fn spawn(&self, _: &'static str, future: futures::future::BoxFuture<'static, ()>) { + self.0.spawn_ok(future); + } } #[cfg(test)] @@ -320,6 +391,7 @@ mod tests { use super::*; use crate::sr25519; use crate::testing::{ED25519, SR25519}; + use crate::vrf::VRFTranscriptValue; #[test] fn store_key_and_extract() { @@ -351,4 +423,42 @@ mod tests { assert!(public_keys.contains(&key_pair.public().into())); } + + #[test] + fn vrf_sign() { + let store = KeyStore::new(); + + let secret_uri = "//Alice"; + let key_pair = sr25519::Pair::from_string(secret_uri, None).expect("Generates key pair"); + + let transcript_data = VRFTranscriptData { + label: b"Test", + items: vec![ + ("one", VRFTranscriptValue::U64(1)), + ("two", VRFTranscriptValue::U64(2)), + ("three", VRFTranscriptValue::Bytes("test".as_bytes())), + ] + }; + + let result = store.read().sr25519_vrf_sign( + SR25519, + &key_pair.public(), + transcript_data.clone(), + ); + assert!(result.is_err()); + + store.write().insert_unknown( + SR25519, + secret_uri, + key_pair.public().as_ref(), + ).expect("Inserts unknown key"); + + let result = store.read().sr25519_vrf_sign( + SR25519, + &key_pair.public(), + transcript_data, + ); + + assert!(result.is_ok()); + } } diff --git a/primitives/core/src/traits.rs b/primitives/core/src/traits.rs index 133a4a4e1958a7e696578a615da5f17634c2b307..ab409b60d9c7095c6133eda8c4d2fc2ed15a6eaf 100644 --- a/primitives/core/src/traits.rs +++ b/primitives/core/src/traits.rs @@ -1,26 +1,27 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Shareable Substrate traits. use crate::{ crypto::{KeyTypeId, CryptoTypePublicPair}, - ed25519, sr25519, + vrf::{VRFTranscriptData, VRFSignature}, + ed25519, sr25519, ecdsa, }; - use std::{ borrow::Cow, fmt::{Debug, Display}, @@ -31,17 +32,22 @@ use std::{ pub use sp_externalities::{Externalities, ExternalitiesExt}; /// BareCryptoStore error -#[derive(Debug)] -pub enum BareCryptoStoreError { +#[derive(Debug, derive_more::Display)] +pub enum Error { /// Public key type is not supported + #[display(fmt="Key not supported: {:?}", _0)] KeyNotSupported(KeyTypeId), /// Pair not found for public key and KeyTypeId + #[display(fmt="Pair was not found: {}", _0)] PairNotFound(String), /// Validation error + #[display(fmt="Validation error: {}", _0)] ValidationError(String), /// Keystore unavailable + #[display(fmt="Keystore unavailable")] Unavailable, /// Programming errors + #[display(fmt="An unknown keystore error occurred: {}", _0)] Other(String) } @@ -58,7 +64,7 @@ pub trait BareCryptoStore: Send + Sync { &mut self, id: KeyTypeId, seed: Option<&str>, - ) -> Result; + ) -> Result; /// Returns all ed25519 public keys for the given key type. fn ed25519_public_keys(&self, id: KeyTypeId) -> Vec; /// Generate a new ed25519 key pair for the given key type and an optional seed. @@ -70,7 +76,19 @@ pub trait BareCryptoStore: Send + Sync { &mut self, id: KeyTypeId, seed: Option<&str>, - ) -> Result; + ) -> Result; + /// Returns all ecdsa public keys for the given key type. + fn ecdsa_public_keys(&self, id: KeyTypeId) -> Vec; + /// Generate a new ecdsa key pair for the given key type and an optional seed. + /// + /// If the given seed is `Some(_)`, the key pair will only be stored in memory. + /// + /// Returns the public key of the generated key pair. + fn ecdsa_generate_new( + &mut self, + id: KeyTypeId, + seed: Option<&str>, + ) -> Result; /// Insert a new key. This doesn't require any known of the crypto; but a public key must be /// manually provided. @@ -90,11 +108,11 @@ pub trait BareCryptoStore: Send + Sync { &self, id: KeyTypeId, keys: Vec - ) -> Result, BareCryptoStoreError>; + ) -> Result, Error>; /// List all supported keys /// /// Returns a set of public keys the signer supports. - fn keys(&self, id: KeyTypeId) -> Result, BareCryptoStoreError>; + fn keys(&self, id: KeyTypeId) -> Result, Error>; /// Checks if the private keys for the given public key and key type combinations exist. /// @@ -113,7 +131,7 @@ pub trait BareCryptoStore: Send + Sync { id: KeyTypeId, key: &CryptoTypePublicPair, msg: &[u8], - ) -> Result, BareCryptoStoreError>; + ) -> Result, Error>; /// Sign with any key /// @@ -126,7 +144,7 @@ pub trait BareCryptoStore: Send + Sync { id: KeyTypeId, keys: Vec, msg: &[u8] - ) -> Result<(CryptoTypePublicPair, Vec), BareCryptoStoreError> { + ) -> Result<(CryptoTypePublicPair, Vec), Error> { if keys.len() == 1 { return self.sign_with(id, &keys[0], msg).map(|s| (keys[0].clone(), s)); } else { @@ -136,7 +154,7 @@ pub trait BareCryptoStore: Send + Sync { } } } - Err(BareCryptoStoreError::KeyNotSupported(id)) + Err(Error::KeyNotSupported(id)) } /// Sign with all keys @@ -145,15 +163,36 @@ pub trait BareCryptoStore: Send + Sync { /// each key given that the key is supported. /// /// Returns a list of `Result`s each representing the SCALE encoded - /// signature of each key or a BareCryptoStoreError for non-supported keys. + /// signature of each key or a Error for non-supported keys. fn sign_with_all( &self, id: KeyTypeId, keys: Vec, msg: &[u8], - ) -> Result, BareCryptoStoreError>>, ()>{ + ) -> Result, Error>>, ()>{ Ok(keys.iter().map(|k| self.sign_with(id, k, msg)).collect()) } + + /// Generate VRF signature for given transcript data. + /// + /// Receives KeyTypeId and Public key to be able to map + /// them to a private key that exists in the keystore which + /// is, in turn, used for signing the provided transcript. + /// + /// Returns a result containing the signature data. + /// Namely, VRFOutput and VRFProof which are returned + /// inside the `VRFSignature` container struct. + /// + /// This function will return an error in the cases where + /// the public key and key type provided do not match a private + /// key in the keystore. Or, in the context of remote signing + /// an error could be a network one. + fn sr25519_vrf_sign( + &self, + key_type: KeyTypeId, + public: &sr25519::Public, + transcript_data: VRFTranscriptData, + ) -> Result; } /// A pointer to the key store. @@ -313,28 +352,37 @@ impl CallInWasmExt { } } -/// Something that can spawn tasks and also can be cloned. -pub trait CloneableSpawn: futures::task::Spawn + Send + Sync { - /// Clone as heap-allocated handle. - fn clone(&self) -> Box; -} - sp_externalities::decl_extension! { /// Task executor extension. - pub struct TaskExecutorExt(Box); + pub struct TaskExecutorExt(Box); } impl TaskExecutorExt { /// New instance of task executor extension. - pub fn new(spawn_handle: Box) -> Self { - Self(spawn_handle) + pub fn new(spawn_handle: impl SpawnNamed + Send + 'static) -> Self { + Self(Box::new(spawn_handle)) } } -/// Something that can spawn a blocking future. -pub trait SpawnBlocking { +/// Something that can spawn futures (blocking and non-blocking) with an assigned name. +#[dyn_clonable::clonable] +pub trait SpawnNamed: Clone + Send + Sync { /// Spawn the given blocking future. /// /// The given `name` is used to identify the future in tracing. fn spawn_blocking(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>); + /// Spawn the given non-blocking future. + /// + /// The given `name` is used to identify the future in tracing. + fn spawn(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>); +} + +impl SpawnNamed for Box { + fn spawn_blocking(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>) { + (**self).spawn_blocking(name, future) + } + + fn spawn(&self, name: &'static str, future: futures::future::BoxFuture<'static, ()>) { + (**self).spawn(name, future) + } } diff --git a/primitives/core/src/u32_trait.rs b/primitives/core/src/u32_trait.rs index 975b4aa90990e7ea4c80cd31e5b4a438fdd2d628..6f73e1f6ba7190e9274dfb6958002917faab92d3 100644 --- a/primitives/core/src/u32_trait.rs +++ b/primitives/core/src/u32_trait.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! An u32 trait with "values" as impl'd types. diff --git a/primitives/core/src/uint.rs b/primitives/core/src/uint.rs index e666137c08161d897707def5fadde55a9d2f1abe..ef1adc4a0e0ee7fa2ac30d0f3f5a3bc70ece1c82 100644 --- a/primitives/core/src/uint.rs +++ b/primitives/core/src/uint.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! An unsigned fixed-size integer. diff --git a/primitives/core/src/vrf.rs b/primitives/core/src/vrf.rs new file mode 100644 index 0000000000000000000000000000000000000000..d392587cb72e7acaec7139e81a6ca531bc2b3b67 --- /dev/null +++ b/primitives/core/src/vrf.rs @@ -0,0 +1,99 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! VRF-specifc data types and helpers + +use codec::Encode; +use merlin::Transcript; +use schnorrkel::vrf::{VRFOutput, VRFProof}; +/// An enum whose variants represent possible +/// accepted values to construct the VRF transcript +#[derive(Clone, Encode)] +pub enum VRFTranscriptValue<'a> { + /// Value is an array of bytes + Bytes(&'a [u8]), + /// Value is a u64 integer + U64(u64), +} +/// VRF Transcript data +#[derive(Clone, Encode)] +pub struct VRFTranscriptData<'a> { + /// The transcript's label + pub label: &'static [u8], + /// Additional data to be registered into the transcript + pub items: Vec<(&'static str, VRFTranscriptValue<'a>)>, +} +/// VRF signature data +pub struct VRFSignature { + /// The VRFOutput serialized + pub output: VRFOutput, + /// The calculated VRFProof + pub proof: VRFProof, +} + +/// Construct a `Transcript` object from data. +/// +/// Returns `merlin::Transcript` +pub fn make_transcript(data: VRFTranscriptData) -> Transcript { + let mut transcript = Transcript::new(data.label); + for (label, value) in data.items.into_iter() { + match value { + VRFTranscriptValue::Bytes(bytes) => { + transcript.append_message(label.as_bytes(), &bytes); + }, + VRFTranscriptValue::U64(val) => { + transcript.append_u64(label.as_bytes(), val); + } + } + } + transcript +} + + +#[cfg(test)] +mod tests { + use super::*; + use crate::vrf::VRFTranscriptValue; + use rand::RngCore; + use rand_chacha::{ + rand_core::SeedableRng, + ChaChaRng, + }; + + #[test] + fn transcript_creation_matches() { + let mut orig_transcript = Transcript::new(b"My label"); + orig_transcript.append_u64(b"one", 1); + orig_transcript.append_message(b"two", "test".as_bytes()); + + let new_transcript = make_transcript(VRFTranscriptData { + label: b"My label", + items: vec![ + ("one", VRFTranscriptValue::U64(1)), + ("two", VRFTranscriptValue::Bytes("test".as_bytes())), + ], + }); + let test = |t: Transcript| -> [u8; 16] { + let mut b = [0u8; 16]; + t.build_rng() + .finalize(&mut ChaChaRng::from_seed([0u8;32])) + .fill_bytes(&mut b); + b + }; + debug_assert!(test(orig_transcript) == test(new_transcript)); + } +} diff --git a/primitives/database/Cargo.toml b/primitives/database/Cargo.toml index 2ab86de61d65f12c597ce9db46e23f06b0b71ed2..da909ddc6518ac0529fa761f2bd213aa00124dac 100644 --- a/primitives/database/Cargo.toml +++ b/primitives/database/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-database" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate database trait." @@ -11,4 +11,4 @@ documentation = "https://docs.rs/sp-database" [dependencies] parking_lot = "0.10.0" -kvdb = "0.5.0" +kvdb = "0.7.0" diff --git a/primitives/database/README.md b/primitives/database/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cd0677eb9eb44ef3d26f1cfecdb1bdbbd371536a --- /dev/null +++ b/primitives/database/README.md @@ -0,0 +1,3 @@ +The main database trait, allowing Substrate to store data persistently. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/database/src/error.rs b/primitives/database/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..2e5d4557a9791bd71512d7f8ef3e0203011c6705 --- /dev/null +++ b/primitives/database/src/error.rs @@ -0,0 +1,35 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +/// The error type for database operations. +#[derive(Debug)] +pub struct DatabaseError(pub Box); + +impl std::fmt::Display for DatabaseError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl std::error::Error for DatabaseError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + None + } +} + +/// A specialized `Result` type for database operations. +pub type Result = std::result::Result; diff --git a/primitives/database/src/kvdb.rs b/primitives/database/src/kvdb.rs index 85a324b5c105f757e9c264b7b9a696ac612faefb..f436979aaf4c14cf093fcf6a854ec06172331b8b 100644 --- a/primitives/database/src/kvdb.rs +++ b/primitives/database/src/kvdb.rs @@ -1,24 +1,25 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. /// A wrapper around `kvdb::Database` that implements `sp_database::Database` trait use ::kvdb::{DBTransaction, KeyValueDB}; -use crate::{Database, Change, Transaction, ColumnId}; +use crate::{Database, Change, ColumnId, Transaction, error}; struct DbAdapter(D); @@ -37,7 +38,7 @@ pub fn as_database(db: D) -> std::sync::Arc Database for DbAdapter { - fn commit(&self, transaction: Transaction) { + fn commit(&self, transaction: Transaction) -> error::Result<()> { let mut tx = DBTransaction::new(); for change in transaction.0.into_iter() { match change { @@ -46,7 +47,7 @@ impl Database for DbAdapter { _ => unimplemented!(), } } - handle_err(self.0.write(tx)); + self.0.write(tx).map_err(|e| error::DatabaseError(Box::new(e))) } fn get(&self, col: ColumnId, key: &[u8]) -> Option> { diff --git a/primitives/database/src/lib.rs b/primitives/database/src/lib.rs index bd9bd2eb54c28c9189891e06689723f86284062e..1908eb49bb6c68cdbff1f39adc274d51452e2a0a 100644 --- a/primitives/database/src/lib.rs +++ b/primitives/database/src/lib.rs @@ -1,21 +1,23 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The main database trait, allowing Substrate to store data persistently. +pub mod error; mod mem; mod kvdb; @@ -81,20 +83,22 @@ impl Transaction { pub trait Database: Send + Sync { /// Commit the `transaction` to the database atomically. Any further calls to `get` or `lookup` /// will reflect the new state. - fn commit(&self, transaction: Transaction) { + fn commit(&self, transaction: Transaction) -> error::Result<()> { for change in transaction.0.into_iter() { match change { Change::Set(col, key, value) => self.set(col, &key, &value), Change::Remove(col, key) => self.remove(col, &key), Change::Store(hash, preimage) => self.store(&hash, &preimage), Change::Release(hash) => self.release(&hash), - } + }?; } + + Ok(()) } /// Commit the `transaction` to the database atomically. Any further calls to `get` or `lookup` /// will reflect the new state. - fn commit_ref<'a>(&self, transaction: &mut dyn Iterator>) { + fn commit_ref<'a>(&self, transaction: &mut dyn Iterator>) -> error::Result<()> { let mut tx = Transaction::new(); for change in transaction { match change { @@ -104,13 +108,13 @@ pub trait Database: Send + Sync { ChangeRef::Release(hash) => tx.release(hash), } } - self.commit(tx); + self.commit(tx) } /// Retrieve the value previously stored against `key` or `None` if /// `key` is not currently in the database. fn get(&self, col: ColumnId, key: &[u8]) -> Option>; - + /// Call `f` with the value previously stored against `key`. /// /// This may be faster than `get` since it doesn't allocate. @@ -118,24 +122,24 @@ pub trait Database: Send + Sync { fn with_get(&self, col: ColumnId, key: &[u8], f: &mut dyn FnMut(&[u8])) { self.get(col, key).map(|v| f(&v)); } - + /// Set the value of `key` in `col` to `value`, replacing anything that is there currently. - fn set(&self, col: ColumnId, key: &[u8], value: &[u8]) { + fn set(&self, col: ColumnId, key: &[u8], value: &[u8]) -> error::Result<()> { let mut t = Transaction::new(); t.set(col, key, value); - self.commit(t); + self.commit(t) } /// Remove the value of `key` in `col`. - fn remove(&self, col: ColumnId, key: &[u8]) { + fn remove(&self, col: ColumnId, key: &[u8]) -> error::Result<()> { let mut t = Transaction::new(); t.remove(col, key); - self.commit(t); + self.commit(t) } /// Retrieve the first preimage previously `store`d for `hash` or `None` if no preimage is /// currently stored. fn lookup(&self, hash: &H) -> Option>; - + /// Call `f` with the preimage stored for `hash` and return the result, or `None` if no preimage /// is currently stored. /// @@ -144,23 +148,29 @@ pub trait Database: Send + Sync { fn with_lookup(&self, hash: &H, f: &mut dyn FnMut(&[u8])) { self.lookup(hash).map(|v| f(&v)); } - + /// Store the `preimage` of `hash` into the database, so that it may be looked up later with /// `Database::lookup`. This may be called multiple times, but `Database::lookup` but subsequent /// calls will ignore `preimage` and simply increase the number of references on `hash`. - fn store(&self, hash: &H, preimage: &[u8]) { + fn store(&self, hash: &H, preimage: &[u8]) -> error::Result<()> { let mut t = Transaction::new(); t.store(hash.clone(), preimage); - self.commit(t); + self.commit(t) } - + /// Release the preimage of `hash` from the database. An equal number of these to the number of /// corresponding `store`s must have been given before it is legal for `Database::lookup` to /// be unable to provide the preimage. - fn release(&self, hash: &H) { + fn release(&self, hash: &H) -> error::Result<()> { let mut t = Transaction::new(); t.release(hash.clone()); - self.commit(t); + self.commit(t) + } +} + +impl std::fmt::Debug for dyn Database { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Database") } } diff --git a/primitives/database/src/mem.rs b/primitives/database/src/mem.rs index 09d6149bed174b9225d31ca53fc24a59893c8171..51cb854334d50ab9449bc96e6c96a188df044218 100644 --- a/primitives/database/src/mem.rs +++ b/primitives/database/src/mem.rs @@ -1,23 +1,24 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! In-memory implementation of `Database` use std::collections::HashMap; -use crate::{Database, Transaction, ColumnId, Change}; +use crate::{Database, Change, ColumnId, Transaction, error}; use parking_lot::RwLock; #[derive(Default)] @@ -28,7 +29,7 @@ pub struct MemDb Database for MemDb where H: Clone + Send + Sync + Eq + PartialEq + Default + std::hash::Hash { - fn commit(&self, transaction: Transaction) { + fn commit(&self, transaction: Transaction) -> error::Result<()> { let mut s = self.0.write(); for change in transaction.0.into_iter() { match change { @@ -38,6 +39,8 @@ impl Database for MemDb Change::Release(hash) => { s.1.remove(&hash); }, } } + + Ok(()) } fn get(&self, col: ColumnId, key: &[u8]) -> Option> { diff --git a/primitives/debug-derive/Cargo.toml b/primitives/debug-derive/Cargo.toml index a3e9d91fd2825dbe70da48ee2e4b78e6a549e267..99481782693f32ffc3952d912b2d8a3b14b411a7 100644 --- a/primitives/debug-derive/Cargo.toml +++ b/primitives/debug-derive/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-debug-derive" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Macros to derive runtime debug implementation." diff --git a/primitives/debug-derive/src/impls.rs b/primitives/debug-derive/src/impls.rs index b0e6dfa3eec4b9790901eef8b6dce5696250b622..1757b294d9d490191b968e4d5d0a5440d198f04f 100644 --- a/primitives/debug-derive/src/impls.rs +++ b/primitives/debug-derive/src/impls.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use quote::quote; use proc_macro2::TokenStream; diff --git a/primitives/debug-derive/src/lib.rs b/primitives/debug-derive/src/lib.rs index 68bbb94e1b006bba81ccead4a7fefb72f9b2354e..db370f890810dedcc78a9bbba19f7b23fb59412f 100644 --- a/primitives/debug-derive/src/lib.rs +++ b/primitives/debug-derive/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Macros to derive runtime debug implementation. //! diff --git a/primitives/debug-derive/tests/tests.rs b/primitives/debug-derive/tests/tests.rs index 77b3d53a2d4ad0189d58e22afbaa8455d07458ec..6a03762b1c65535462d96fc58e793886f1949369 100644 --- a/primitives/debug-derive/tests/tests.rs +++ b/primitives/debug-derive/tests/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use sp_debug_derive::RuntimeDebug; diff --git a/primitives/externalities/Cargo.toml b/primitives/externalities/Cargo.toml index 9d7cd1df6b7fe5f652feec480fe25fd3346b416f..17184ca69402f3c5e76cf716aed2273e841d5d83 100644 --- a/primitives/externalities/Cargo.toml +++ b/primitives/externalities/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sp-externalities" -version = "0.8.0-dev" -license = "GPL-3.0" +version = "0.8.0-rc6" +license = "Apache-2.0" authors = ["Parity Technologies "] edition = "2018" homepage = "https://substrate.dev" @@ -13,7 +13,7 @@ documentation = "https://docs.rs/sp-externalities" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-storage = { version = "2.0.0-dev", path = "../storage" } -sp-std = { version = "2.0.0-dev", path = "../std" } +sp-storage = { version = "2.0.0-rc6", path = "../storage" } +sp-std = { version = "2.0.0-rc6", path = "../std" } environmental = { version = "1.1.1" } -codec = { package = "parity-scale-codec", version = "1.3.0" } +codec = { package = "parity-scale-codec", version = "1.3.1" } diff --git a/primitives/externalities/README.md b/primitives/externalities/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3141b2609e6375063dc42b089489451973393cba --- /dev/null +++ b/primitives/externalities/README.md @@ -0,0 +1,9 @@ +Substrate externalities abstraction + +The externalities mainly provide access to storage and to registered extensions. Extensions +are for example the keystore or the offchain externalities. These externalities are used to +access the node from the runtime via the runtime interfaces. + +This crate exposes the main [`Externalities`] trait. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/externalities/src/extensions.rs b/primitives/externalities/src/extensions.rs index f38f256bb9e68456d14da43c80ed24eefeeabb0f..08d81e46c88fc92d0027ab513965a511d48b8316 100644 --- a/primitives/externalities/src/extensions.rs +++ b/primitives/externalities/src/extensions.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Externalities extensions storage. //! @@ -107,9 +108,9 @@ pub struct Extensions { } impl std::fmt::Debug for Extensions { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Extensions: ({})", self.extensions.len()) - } + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Extensions: ({})", self.extensions.len()) + } } impl Extensions { diff --git a/primitives/externalities/src/lib.rs b/primitives/externalities/src/lib.rs index 2b584b512e4993b363127124f2866cfcb7b1565d..01570e0bfadd3679fa72d3d5715d85fa2d082e1e 100644 --- a/primitives/externalities/src/lib.rs +++ b/primitives/externalities/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Substrate externalities abstraction //! @@ -24,7 +25,7 @@ use std::any::{Any, TypeId}; -use sp_storage::ChildInfo; +use sp_storage::{ChildInfo, TrackedStorageKey}; pub use scope_limited::{set_and_run_with_externalities, with_externalities}; pub use extensions::{Extension, Extensions, ExtensionStore}; @@ -194,6 +195,29 @@ pub trait Externalities: ExtensionStore { /// The returned hash is defined by the `Block` and is SCALE encoded. fn storage_changes_root(&mut self, parent: &[u8]) -> Result>, ()>; + /// Start a new nested transaction. + /// + /// This allows to either commit or roll back all changes made after this call to the + /// top changes or the default child changes. For every transaction there cam be a + /// matching call to either `storage_rollback_transaction` or `storage_commit_transaction`. + /// Any transactions that are still open after returning from runtime are committed + /// automatically. + /// + /// Changes made without any open transaction are committed immediately. + fn storage_start_transaction(&mut self); + + /// Rollback the last transaction started by `storage_start_transaction`. + /// + /// Any changes made during that storage transaction are discarded. Returns an error when + /// no transaction is open that can be closed. + fn storage_rollback_transaction(&mut self) -> Result<(), ()>; + + /// Commit the last transaction started by `storage_start_transaction`. + /// + /// Any changes made during that storage transaction are committed. Returns an error when + /// no transaction is open that can be closed. + fn storage_commit_transaction(&mut self) -> Result<(), ()>; + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /// Benchmarking related functionality and shouldn't be used anywhere else! /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -209,6 +233,34 @@ pub trait Externalities: ExtensionStore { /// /// Commits all changes to the database and clears all caches. fn commit(&mut self); + + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /// Benchmarking related functionality and shouldn't be used anywhere else! + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /// + /// Gets the current read/write count for the benchmarking process. + fn read_write_count(&self) -> (u32, u32, u32, u32); + + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /// Benchmarking related functionality and shouldn't be used anywhere else! + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /// + /// Resets read/write count for the benchmarking process. + fn reset_read_write_count(&mut self); + + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /// Benchmarking related functionality and shouldn't be used anywhere else! + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /// + /// Gets the current DB tracking whitelist. + fn get_whitelist(&self) -> Vec; + + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /// Benchmarking related functionality and shouldn't be used anywhere else! + /// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /// + /// Adds new storage keys to the DB tracking whitelist. + fn set_whitelist(&mut self, new: Vec); } /// Extension for the [`Externalities`] trait. diff --git a/primitives/externalities/src/scope_limited.rs b/primitives/externalities/src/scope_limited.rs index 263858aa5f5ced3b3c16dfbadf3a701737823d26..1f70276f02d36658edf58a4bf873c045f7891b4a 100644 --- a/primitives/externalities/src/scope_limited.rs +++ b/primitives/externalities/src/scope_limited.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Stores the externalities in an `environmental` value to make it scope limited available. diff --git a/primitives/finality-grandpa/Cargo.toml b/primitives/finality-grandpa/Cargo.toml index 3f0d3f0d14b93de5dfc75aba4a122f418db2273f..8309eccccb0b3afb8dd9fa39cf1cd68e43e3f5e2 100644 --- a/primitives/finality-grandpa/Cargo.toml +++ b/primitives/finality-grandpa/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-finality-grandpa" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Primitives for GRANDPA integration, suitable for WASM compilation." @@ -14,15 +14,15 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../application-crypto" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../application-crypto" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } grandpa = { package = "finality-grandpa", version = "0.12.3", default-features = false, features = ["derive-codec"] } log = { version = "0.4.8", optional = true } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../api" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../core" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } [features] default = ["std"] diff --git a/primitives/finality-grandpa/README.md b/primitives/finality-grandpa/README.md new file mode 100644 index 0000000000000000000000000000000000000000..77a7abca2eef3fa2da9b8c2580c1c0ae7f1d184b --- /dev/null +++ b/primitives/finality-grandpa/README.md @@ -0,0 +1,3 @@ +Primitives for GRANDPA integration, suitable for WASM compilation. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/finality-grandpa/src/lib.rs b/primitives/finality-grandpa/src/lib.rs index 7cc8ddf5cc515287108b0b30b79c725c594870cc..2ba2159d8bb04e08fdde27e61c577d37b5eee64c 100644 --- a/primitives/finality-grandpa/src/lib.rs +++ b/primitives/finality-grandpa/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Primitives for GRANDPA integration, suitable for WASM compilation. @@ -28,6 +29,8 @@ use codec::{Encode, Decode, Input, Codec}; use sp_runtime::{ConsensusEngineId, RuntimeDebug, traits::NumberFor}; use sp_std::borrow::Cow; use sp_std::vec::Vec; +#[cfg(feature = "std")] +use sp_core::traits::BareCryptoStorePtr; #[cfg(feature = "std")] use log::debug; @@ -253,7 +256,7 @@ impl Equivocation { /// Verifies the equivocation proof by making sure that both votes target /// different blocks and that its signatures are valid. -pub fn check_equivocation_proof(report: EquivocationProof) -> Result<(), ()> +pub fn check_equivocation_proof(report: EquivocationProof) -> bool where H: Clone + Encode + PartialEq, N: Clone + Encode + PartialEq, @@ -266,27 +269,27 @@ where if $equivocation.first.0.target_hash == $equivocation.second.0.target_hash && $equivocation.first.0.target_number == $equivocation.second.0.target_number { - return Err(()); + return false; } // check signatures on both votes are valid - check_message_signature( + let valid_first = check_message_signature( &$message($equivocation.first.0), &$equivocation.identity, &$equivocation.first.1, $equivocation.round_number, report.set_id, - )?; + ); - check_message_signature( + let valid_second = check_message_signature( &$message($equivocation.second.0), &$equivocation.identity, &$equivocation.second.1, $equivocation.round_number, report.set_id, - )?; + ); - return Ok(()); + return valid_first && valid_second; }; } @@ -328,7 +331,7 @@ pub fn check_message_signature( signature: &AuthoritySignature, round: RoundNumber, set_id: SetId, -) -> Result<(), ()> +) -> bool where H: Encode, N: Encode, @@ -347,7 +350,7 @@ pub fn check_message_signature_with_buffer( round: RoundNumber, set_id: SetId, buf: &mut Vec, -) -> Result<(), ()> +) -> bool where H: Encode, N: Encode, @@ -356,38 +359,45 @@ where localized_payload_with_buffer(round, set_id, message, buf); - if id.verify(&buf, signature) { - Ok(()) - } else { + let valid = id.verify(&buf, signature); + + if !valid { #[cfg(feature = "std")] debug!(target: "afg", "Bad signature on message from {:?}", id); - - Err(()) } + + valid } /// Localizes the message to the given set and round and signs the payload. #[cfg(feature = "std")] pub fn sign_message( + keystore: &BareCryptoStorePtr, message: grandpa::Message, - pair: &AuthorityPair, + public: AuthorityId, round: RoundNumber, set_id: SetId, -) -> grandpa::SignedMessage +) -> Option> where H: Encode, N: Encode, { - use sp_core::Pair; + use sp_core::crypto::Public; + use sp_application_crypto::AppKey; + use sp_std::convert::TryInto; let encoded = localized_payload(round, set_id, &message); - let signature = pair.sign(&encoded[..]); + let signature = keystore.read() + .sign_with(AuthorityId::ID, &public.to_public_crypto_pair(), &encoded[..]) + .ok()? + .try_into() + .ok()?; - grandpa::SignedMessage { + Some(grandpa::SignedMessage { message, signature, - id: pair.public(), - } + id: public, + }) } /// WASM function call to check for pending changes. @@ -487,16 +497,15 @@ sp_api::decl_runtime_apis! { /// is finalized by the authorities from block B-1. fn grandpa_authorities() -> AuthorityList; - /// Submits an extrinsic to report an equivocation. The caller must - /// provide the equivocation proof and a key ownership proof (should be - /// obtained using `generate_key_ownership_proof`). This method will - /// sign the extrinsic with any reporting keys available in the keystore - /// and will push the transaction to the pool. This method returns `None` - /// when creation of the extrinsic fails, either due to unavailability - /// of keys to sign, or because equivocation reporting is disabled for - /// the given runtime (i.e. this method is hardcoded to return `None`). - /// Only useful in an offchain context. - fn submit_report_equivocation_extrinsic( + /// Submits an unsigned extrinsic to report an equivocation. The caller + /// must provide the equivocation proof and a key ownership proof + /// (should be obtained using `generate_key_ownership_proof`). The + /// extrinsic will be unsigned and should only be accepted for local + /// authorship (not to be broadcast to the network). This method returns + /// `None` when creation of the extrinsic fails, e.g. if equivocation + /// reporting is disabled for the given runtime (i.e. this method is + /// hardcoded to return `None`). Only useful in an offchain context. + fn submit_report_equivocation_unsigned_extrinsic( equivocation_proof: EquivocationProof>, key_owner_proof: OpaqueKeyOwnershipProof, ) -> Option<()>; diff --git a/primitives/finality-tracker/Cargo.toml b/primitives/finality-tracker/Cargo.toml index a111c6267526aeaabc29a019364a793356d65376..31db1e683a819dca7a60db289301cac5880ee230 100644 --- a/primitives/finality-tracker/Cargo.toml +++ b/primitives/finality-tracker/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-finality-tracker" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME module that tracks the last finalized block, as perceived by block authors." @@ -12,9 +12,9 @@ description = "FRAME module that tracks the last finalized block, as perceived b targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } [features] default = ["std"] diff --git a/primitives/finality-tracker/README.md b/primitives/finality-tracker/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f9778e38a2bce2e6893af78090253765a54986fa --- /dev/null +++ b/primitives/finality-tracker/README.md @@ -0,0 +1,3 @@ +FRAME module that tracks the last finalized block, as perceived by block authors. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/finality-tracker/src/lib.rs b/primitives/finality-tracker/src/lib.rs index a7157139dc1050699682824ae2763a76b01dec7b..fea40039056068a04f2f40054b7255763be8b7a5 100644 --- a/primitives/finality-tracker/src/lib.rs +++ b/primitives/finality-tracker/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! FRAME module that tracks the last finalized block, as perceived by block authors. diff --git a/primitives/inherents/Cargo.toml b/primitives/inherents/Cargo.toml index 084d275882a197afb829eb05cd02f956860f7390..c6744925966599c9227afb8b76ead7e7fa90e303 100644 --- a/primitives/inherents/Cargo.toml +++ b/primitives/inherents/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-inherents" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Provides types and traits for creating and checking inherents." @@ -15,9 +15,9 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] parking_lot = { version = "0.10.0", optional = true } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../core" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } derive_more = { version = "0.99.2", optional = true } [features] diff --git a/primitives/inherents/README.md b/primitives/inherents/README.md new file mode 100644 index 0000000000000000000000000000000000000000..78aa625fe85692b1d53164415a5b2086d5704186 --- /dev/null +++ b/primitives/inherents/README.md @@ -0,0 +1,17 @@ +Provides types and traits for creating and checking inherents. + +Each inherent is added to a produced block. Each runtime decides on which inherents it +wants to attach to its blocks. All data that is required for the runtime to create the inherents +is stored in the `InherentData`. This `InherentData` is constructed by the node and given to +the runtime. + +Types that provide data for inherents, should implement `InherentDataProvider` and need to be +registered at `InherentDataProviders`. + +In the runtime, modules need to implement `ProvideInherent` when they can create and/or check +inherents. By implementing `ProvideInherent`, a module is not enforced to create an inherent. +A module can also just check given inherents. For using a module as inherent provider, it needs +to be registered by the `construct_runtime!` macro. The macro documentation gives more +information on how that is done. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/inherents/src/lib.rs b/primitives/inherents/src/lib.rs index e63382cdf2e4622b76b08c88dcae0b87c867ed97..98942969535285081b7bb42774867c566dbfd830 100644 --- a/primitives/inherents/src/lib.rs +++ b/primitives/inherents/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Provides types and traits for creating and checking inherents. //! diff --git a/primitives/io/Cargo.toml b/primitives/io/Cargo.toml index 93c8cc9d38b40cc4d1404f97874a9642daca628d..a08451db24389cca288f12052bc74f35d5411586 100644 --- a/primitives/io/Cargo.toml +++ b/primitives/io/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-io" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "I/O for Substrate runtimes" @@ -14,16 +14,17 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } hash-db = { version = "0.15.2", default-features = false } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../core" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } libsecp256k1 = { version = "0.3.4", optional = true } -sp-state-machine = { version = "0.8.0-dev", optional = true, path = "../../primitives/state-machine" } -sp-wasm-interface = { version = "2.0.0-dev", path = "../../primitives/wasm-interface", default-features = false } -sp-runtime-interface = { version = "2.0.0-dev", default-features = false, path = "../runtime-interface" } -sp-trie = { version = "2.0.0-dev", optional = true, path = "../../primitives/trie" } -sp-externalities = { version = "0.8.0-dev", optional = true, path = "../externalities" } +sp-state-machine = { version = "0.8.0-rc6", optional = true, path = "../../primitives/state-machine" } +sp-wasm-interface = { version = "2.0.0-rc6", path = "../../primitives/wasm-interface", default-features = false } +sp-runtime-interface = { version = "2.0.0-rc6", default-features = false, path = "../runtime-interface" } +sp-trie = { version = "2.0.0-rc6", optional = true, path = "../../primitives/trie" } +sp-externalities = { version = "0.8.0-rc6", optional = true, path = "../externalities" } +sp-tracing = { version = "2.0.0-rc6", default-features = false, path = "../tracing" } log = { version = "0.4.8", optional = true } futures = { version = "0.3.1", features = ["thread-pool"], optional = true } parking_lot = { version = "0.10.0", optional = true } diff --git a/primitives/io/README.md b/primitives/io/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a24370cc566b359b2b3aeab195d185dec34f7e78 --- /dev/null +++ b/primitives/io/README.md @@ -0,0 +1,3 @@ +I/O host interface for substrate runtime. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/io/src/batch_verifier.rs b/primitives/io/src/batch_verifier.rs index ab2ee629d326db329a24667557a06631994ec576..39229b1200b9197243979db09a8678b07d18f1a4 100644 --- a/primitives/io/src/batch_verifier.rs +++ b/primitives/io/src/batch_verifier.rs @@ -1,24 +1,25 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Batch/parallel verification. -use sp_core::{ed25519, sr25519, crypto::Pair, traits::CloneableSpawn}; +use sp_core::{ed25519, sr25519, ecdsa, crypto::Pair, traits::SpawnNamed}; use std::sync::{Arc, atomic::{AtomicBool, Ordering as AtomicOrdering}}; -use futures::{future::FutureExt, task::FutureObj, channel::oneshot}; +use futures::{future::FutureExt, channel::oneshot}; #[derive(Debug, Clone)] struct Sr25519BatchItem { @@ -34,14 +35,14 @@ struct Sr25519BatchItem { /// call `verify_and_clear to get a result. After that, batch verifier is ready for the /// next batching job. pub struct BatchVerifier { - scheduler: Box, + scheduler: Box, sr25519_items: Vec, invalid: Arc, pending_tasks: Vec>, } impl BatchVerifier { - pub fn new(scheduler: Box) -> Self { + pub fn new(scheduler: Box) -> Self { BatchVerifier { scheduler, sr25519_items: Default::default(), @@ -50,26 +51,37 @@ impl BatchVerifier { } } + /// Spawn a verification task. + /// + /// Returns `false` if there was already an invalid verification or if + /// the verification could not be spawned. fn spawn_verification_task( - &mut self, f: impl FnOnce() -> bool + Send + 'static, - ) -> Result<(), ()> { + &mut self, + f: impl FnOnce() -> bool + Send + 'static, + name: &'static str, + ) -> bool { // there is already invalid transaction encountered - if self.invalid.load(AtomicOrdering::Relaxed) { return Err(()); } + if self.invalid.load(AtomicOrdering::Relaxed) { return false; } let invalid_clone = self.invalid.clone(); let (sender, receiver) = oneshot::channel(); self.pending_tasks.push(receiver); - self.scheduler.spawn_obj(FutureObj::new(async move { - if !f() { - invalid_clone.store(true, AtomicOrdering::Relaxed); - } - if sender.send(()).is_err() { - // sanity - log::warn!("Verification halted while result was pending"); - invalid_clone.store(true, AtomicOrdering::Relaxed); - } - }.boxed())).map_err(drop) + self.scheduler.spawn( + name, + async move { + if !f() { + invalid_clone.store(true, AtomicOrdering::Relaxed); + } + if sender.send(()).is_err() { + // sanity + log::warn!("Verification halted while result was pending"); + invalid_clone.store(true, AtomicOrdering::Relaxed); + } + }.boxed(), + ); + + true } /// Push ed25519 signature to verify. @@ -82,17 +94,10 @@ impl BatchVerifier { pub_key: ed25519::Public, message: Vec, ) -> bool { - if self.invalid.load(AtomicOrdering::Relaxed) { return false; } - - if self.spawn_verification_task(move || ed25519::Pair::verify(&signature, &message, &pub_key)).is_err() { - log::debug!( - target: "runtime", - "Batch-verification returns false because failed to spawn background task.", - ); - - return false; - } - true + self.spawn_verification_task( + move || ed25519::Pair::verify(&signature, &message, &pub_key), + "substrate_ed25519_verify", + ) } /// Push sr25519 signature to verify. @@ -110,17 +115,29 @@ impl BatchVerifier { if self.sr25519_items.len() >= 128 { let items = std::mem::take(&mut self.sr25519_items); - if self.spawn_verification_task(move || Self::verify_sr25519_batch(items)).is_err() { - log::debug!( - target: "runtime", - "Batch-verification returns false because failed to spawn background task.", - ); - - return false; - } + self.spawn_verification_task( + move || Self::verify_sr25519_batch(items), + "substrate_sr25519_verify", + ) + } else { + true } + } - true + /// Push ecdsa signature to verify. + /// + /// Returns false if some of the pushed signatures before already failed the check + /// (in this case it won't verify anything else) + pub fn push_ecdsa( + &mut self, + signature: ecdsa::Signature, + pub_key: ecdsa::Public, + message: Vec, + ) -> bool { + self.spawn_verification_task( + move || ecdsa::Pair::verify(&signature, &message, &pub_key), + "substrate_ecdsa_verify", + ) } fn verify_sr25519_batch(items: Vec) -> bool { @@ -151,23 +168,24 @@ impl BatchVerifier { if pending.len() > 0 { let (sender, receiver) = std::sync::mpsc::channel(); - if self.scheduler.spawn_obj(FutureObj::new(async move { - futures::future::join_all(pending).await; - sender.send(()) - .expect("Channel never panics if receiver is live. \ - Receiver is always live until received this data; qed. "); - }.boxed())).is_err() { - log::debug!( + self.scheduler.spawn( + "substrate_batch_verify_join", + async move { + futures::future::join_all(pending).await; + sender.send(()) + .expect("Channel never panics if receiver is live. \ + Receiver is always live until received this data; qed. "); + }.boxed(), + ); + + if receiver.recv().is_err() { + log::warn!( target: "runtime", - "Batch-verification returns false because failed to spawn background task.", + "Haven't received async result from verification task. Returning false.", ); return false; } - if receiver.recv().is_err() { - log::warn!(target: "runtime", "Haven't received async result from verification task. Returning false."); - return false; - } } log::trace!( diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index f5d692469f0a8a6eb9a76106c9d3e5424804866c..59d1c4f37ef275cd510d015e8911c0a9f8f32632 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! I/O host interface for substrate runtime. @@ -41,7 +42,7 @@ use sp_core::{ }; use sp_core::{ - crypto::KeyTypeId, ed25519, sr25519, H256, LogLevel, + crypto::KeyTypeId, ed25519, sr25519, ecdsa, H256, LogLevel, offchain::{ Timestamp, HttpRequestId, HttpRequestStatus, HttpError, StorageKind, OpaqueNetworkState, }, @@ -133,7 +134,7 @@ pub trait Storage { /// /// The hashing algorithm is defined by the `Block`. /// - /// Returns the SCALE encoded hash. + /// Returns a `Vec` that holds the SCALE encoded hash. fn root(&mut self) -> Vec { self.storage_root() } @@ -143,7 +144,7 @@ pub trait Storage { /// /// The hashing algorithm is defined by the `Block`. /// - /// Returns an `Some(_)` which holds the SCALE encoded hash or `None` when + /// Returns `Some(Vec)` which holds the SCALE encoded hash or `None` when /// changes trie is disabled. fn changes_root(&mut self, parent_hash: &[u8]) -> Option> { self.storage_changes_root(parent_hash) @@ -154,13 +155,52 @@ pub trait Storage { fn next_key(&mut self, key: &[u8]) -> Option> { self.next_storage_key(&key) } + + /// Start a new nested transaction. + /// + /// This allows to either commit or roll back all changes that are made after this call. + /// For every transaction there must be a matching call to either `rollback_transaction` + /// or `commit_transaction`. This is also effective for all values manipulated using the + /// `DefaultChildStorage` API. + /// + /// # Warning + /// + /// This is a low level API that is potentially dangerous as it can easily result + /// in unbalanced transactions. For example, FRAME users should use high level storage + /// abstractions. + fn start_transaction(&mut self) { + self.storage_start_transaction(); + } + + /// Rollback the last transaction started by `start_transaction`. + /// + /// Any changes made during that transaction are discarded. + /// + /// # Panics + /// + /// Will panic if there is no open transaction. + fn rollback_transaction(&mut self) { + self.storage_rollback_transaction() + .expect("No open transaction that can be rolled back."); + } + + /// Commit the last transaction started by `start_transaction`. + /// + /// Any changes made during that transaction are committed. + /// + /// # Panics + /// + /// Will panic if there is no open transaction. + fn commit_transaction(&mut self) { + self.storage_commit_transaction() + .expect("No open transaction that can be committed."); + } } /// Interface for accessing the child storage for default child trie, /// from within the runtime. #[runtime_interface] pub trait DefaultChildStorage { - /// Get a default child storage value for a given key. /// /// Parameter `storage_key` is the unprefixed location of the root of the child trie in the parent trie. @@ -215,7 +255,7 @@ pub trait DefaultChildStorage { /// Clear a child storage key. /// /// For the default child storage at `storage_key`, clear value at `key`. - fn clear ( + fn clear( &mut self, storage_key: &[u8], key: &[u8], @@ -265,7 +305,7 @@ pub trait DefaultChildStorage { /// "Commit" all existing operations and compute the resulting child storage root. /// The hashing algorithm is defined by the `Block`. /// - /// Returns the SCALE encoded hash. + /// Returns a `Vec` that holds the SCALE encoded hash. fn root( &mut self, storage_key: &[u8], @@ -299,6 +339,16 @@ pub trait Trie { fn blake2_256_ordered_root(input: Vec>) -> H256 { Layout::::ordered_trie_root(input) } + + /// A trie root formed from the iterated items. + fn keccak_256_root(input: Vec<(Vec, Vec)>) -> H256 { + Layout::::trie_root(input) + } + + /// A trie root formed from the enumerated items. + fn keccak_256_ordered_root(input: Vec>) -> H256 { + Layout::::ordered_trie_root(input) + } } /// Interface that provides miscellaneous functions for communicating between the runtime and the node. @@ -328,7 +378,8 @@ pub trait Misc { /// Extract the runtime version of the given wasm blob by calling `Core_version`. /// - /// Returns the SCALE encoded runtime version and `None` if the call failed. + /// Returns `None` if calling the function failed for any reason or `Some(Vec)` where + /// the `Vec` holds the SCALE encoded runtime version. /// /// # Performance /// @@ -403,68 +454,63 @@ pub trait Crypto { /// Verify `ed25519` signature. /// - /// Returns `true` when the verification is either successful or batched. - /// If no batching verification extension registered, this will return the result - /// of verification immediately. If batching verification extension is registered - /// caller should call `crypto::finish_batch_verify` to actualy check all submitted - /// signatures. + /// Returns `true` when the verification was successful. fn ed25519_verify( sig: &ed25519::Signature, msg: &[u8], pub_key: &ed25519::Public, ) -> bool { - // TODO: see #5554, this is used outside of externalities context/runtime, thus this manual - // `with_externalities`. - // - // This `with_externalities(..)` block returns Some(Some(result)) if signature verification was successfully - // batched, everything else (Some(None)/None) means it was not batched and needs to be verified. - let evaluated = sp_externalities::with_externalities(|mut instance| - instance.extension::().map( - |extension| extension.push_ed25519( - sig.clone(), - pub_key.clone(), - msg.to_vec(), - ) - ) - ); + ed25519::Pair::verify(sig, msg, pub_key) + } - match evaluated { - Some(Some(val)) => val, - _ => ed25519::Pair::verify(sig, msg, pub_key), - } + /// Register a `ed25519` signature for batch verification. + /// + /// Batch verification must be enabled by calling [`start_batch_verify`]. + /// If batch verification is not enabled, the signature will be verified immediatley. + /// To get the result of the batch verification, [`finish_batch_verify`] + /// needs to be called. + /// + /// Returns `true` when the verification is either successful or batched. + fn ed25519_batch_verify( + &mut self, + sig: &ed25519::Signature, + msg: &[u8], + pub_key: &ed25519::Public, + ) -> bool { + self.extension::().map( + |extension| extension.push_ed25519(sig.clone(), pub_key.clone(), msg.to_vec()) + ).unwrap_or_else(|| ed25519_verify(sig, msg, pub_key)) } /// Verify `sr25519` signature. /// - /// Returns `true` when the verification is either successful or batched. - /// If no batching verification extension registered, this will return the result - /// of verification immediately. If batching verification extension is registered, - /// caller should call `crypto::finish_batch_verify` to actualy check all submitted + /// Returns `true` when the verification was successful. #[version(2)] fn sr25519_verify( sig: &sr25519::Signature, msg: &[u8], pub_key: &sr25519::Public, ) -> bool { - // TODO: see #5554, this is used outside of externalities context/runtime, thus this manual - // `with_externalities`. - // - // This `with_externalities(..)` block returns Some(Some(result)) if signature verification was successfully - // batched, everything else (Some(None)/None) means it was not batched and needs to be verified. - let evaluated = sp_externalities::with_externalities(|mut instance| - instance.extension::().map( - |extension| extension.push_sr25519( - sig.clone(), - pub_key.clone(), - msg.to_vec(), - ) - ) - ); + sr25519::Pair::verify(sig, msg, pub_key) + } - match evaluated { - Some(Some(val)) => val, - _ => sr25519::Pair::verify(sig, msg, pub_key), - } + /// Register a `sr25519` signature for batch verification. + /// + /// Batch verification must be enabled by calling [`start_batch_verify`]. + /// If batch verification is not enabled, the signature will be verified immediatley. + /// To get the result of the batch verification, [`finish_batch_verify`] + /// needs to be called. + /// + /// Returns `true` when the verification is either successful or batched. + fn sr25519_batch_verify( + &mut self, + sig: &sr25519::Signature, + msg: &[u8], + pub_key: &sr25519::Public, + ) -> bool { + self.extension::().map( + |extension| extension.push_sr25519(sig.clone(), pub_key.clone(), msg.to_vec()) + ).unwrap_or_else(|| sr25519_verify(sig, msg, pub_key)) } /// Start verification extension. @@ -544,6 +590,77 @@ pub trait Crypto { sr25519::Pair::verify_deprecated(sig, msg, pubkey) } + /// Returns all `ecdsa` public keys for the given key id from the keystore. + fn ecdsa_public_keys(&mut self, id: KeyTypeId) -> Vec { + self.extension::() + .expect("No `keystore` associated for the current context!") + .read() + .ecdsa_public_keys(id) + } + + /// Generate an `ecdsa` key for the given key type using an optional `seed` and + /// store it in the keystore. + /// + /// The `seed` needs to be a valid utf8. + /// + /// Returns the public key. + fn ecdsa_generate(&mut self, id: KeyTypeId, seed: Option>) -> ecdsa::Public { + let seed = seed.as_ref().map(|s| std::str::from_utf8(&s).expect("Seed is valid utf8!")); + self.extension::() + .expect("No `keystore` associated for the current context!") + .write() + .ecdsa_generate_new(id, seed) + .expect("`ecdsa_generate` failed") + } + + /// Sign the given `msg` with the `ecdsa` key that corresponds to the given public key and + /// key type in the keystore. + /// + /// Returns the signature. + fn ecdsa_sign( + &mut self, + id: KeyTypeId, + pub_key: &ecdsa::Public, + msg: &[u8], + ) -> Option { + self.extension::() + .expect("No `keystore` associated for the current context!") + .read() + .sign_with(id, &pub_key.into(), msg) + .map(|sig| ecdsa::Signature::from_slice(sig.as_slice())) + .ok() + } + + /// Verify `ecdsa` signature. + /// + /// Returns `true` when the verification was successful. + fn ecdsa_verify( + sig: &ecdsa::Signature, + msg: &[u8], + pub_key: &ecdsa::Public, + ) -> bool { + ecdsa::Pair::verify(sig, msg, pub_key) + } + + /// Register a `ecdsa` signature for batch verification. + /// + /// Batch verification must be enabled by calling [`start_batch_verify`]. + /// If batch verification is not enabled, the signature will be verified immediatley. + /// To get the result of the batch verification, [`finish_batch_verify`] + /// needs to be called. + /// + /// Returns `true` when the verification is either successful or batched. + fn ecdsa_batch_verify( + &mut self, + sig: &ecdsa::Signature, + msg: &[u8], + pub_key: &ecdsa::Public, + ) -> bool { + self.extension::().map( + |extension| extension.push_ecdsa(sig.clone(), pub_key.clone(), msg.to_vec()) + ).unwrap_or_else(|| ecdsa_verify(sig, msg, pub_key)) + } + /// Verify and recover a SECP256k1 ECDSA signature. /// /// - `sig` is passed in RSV format. V should be either `0/1` or `27/28`. @@ -711,6 +828,16 @@ pub trait Offchain { .local_storage_set(kind, key, value) } + /// Remove a value from the local storage. + /// + /// Note this storage is not part of the consensus, it's only accessible by + /// offchain worker tasks running on the same machine. It IS persisted between runs. + fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) { + self.extension::() + .expect("local_storage_clear can be called only in the offchain worker context") + .local_storage_clear(kind, key) + } + /// Sets a value in the local storage if it matches current value. /// /// Since multiple offchain workers may be running concurrently, to prevent @@ -870,6 +997,55 @@ pub trait Logging { } } +#[cfg(feature = "std")] +sp_externalities::decl_extension! { + /// Extension to allow running traces in wasm via Proxy + pub struct TracingProxyExt(sp_tracing::proxy::TracingProxy); +} + +/// Interface that provides functions for profiling the runtime. +#[runtime_interface] +pub trait WasmTracing { + /// To create and enter a `tracing` span, using `sp_tracing::proxy` + /// Returns 0 value to indicate that no further traces should be attempted + fn enter_span(&mut self, target: &str, name: &str) -> u64 { + if sp_tracing::wasm_tracing_enabled() { + match self.extension::() { + Some(proxy) => return proxy.enter_span(target, name), + None => { + if self.register_extension(TracingProxyExt(sp_tracing::proxy::TracingProxy::new())).is_ok() { + if let Some(proxy) = self.extension::() { + return proxy.enter_span(target, name); + } + } else { + log::warn!( + target: "tracing", + "Unable to register extension: TracingProxyExt" + ); + } + } + } + } + log::debug!( + target: "tracing", + "Notify to runtime that tracing is disabled." + ); + 0 + } + + /// Exit a `tracing` span, using `sp_tracing::proxy` + fn exit_span(&mut self, id: u64) { + if let Some(proxy) = self.extension::() { + proxy.exit_span(id) + } else { + log::warn!( + target: "tracing", + "Unable to load extension: TracingProxyExt" + ); + } + } +} + /// Wasm-only interface that provides functions for interacting with the sandbox. #[runtime_interface(wasm_only)] pub trait Sandbox { @@ -1016,6 +1192,7 @@ pub type SubstrateHostFunctions = ( storage::HostFunctions, default_child_storage::HostFunctions, misc::HostFunctions, + wasm_tracing::HostFunctions, offchain::HostFunctions, crypto::HostFunctions, hashing::HostFunctions, @@ -1029,9 +1206,10 @@ pub type SubstrateHostFunctions = ( #[cfg(test)] mod tests { use super::*; - use sp_core::map; use sp_state_machine::BasicExternalities; - use sp_core::storage::Storage; + use sp_core::{ + storage::Storage, map, traits::TaskExecutorExt, testing::TaskExecutor, + }; use std::any::TypeId; #[test] @@ -1096,8 +1274,10 @@ mod tests { } #[test] - fn dynamic_extensions_work() { - let mut ext = BasicExternalities::with_tasks_executor(); + fn batch_verify_start_finish_works() { + let mut ext = BasicExternalities::default(); + ext.register_extension(TaskExecutorExt::new(TaskExecutor::new())); + ext.execute_with(|| { crypto::start_batch_verify(); }); @@ -1105,7 +1285,7 @@ mod tests { assert!(ext.extensions().get_mut(TypeId::of::()).is_some()); ext.execute_with(|| { - crypto::finish_batch_verify(); + assert!(crypto::finish_batch_verify()); }); assert!(ext.extensions().get_mut(TypeId::of::()).is_none()); @@ -1113,18 +1293,19 @@ mod tests { #[test] fn long_sr25519_batching() { - let mut ext = BasicExternalities::with_tasks_executor(); + let mut ext = BasicExternalities::default(); + ext.register_extension(TaskExecutorExt::new(TaskExecutor::new())); ext.execute_with(|| { let pair = sr25519::Pair::generate_with_phrase(None).0; crypto::start_batch_verify(); for it in 0..70 { let msg = format!("Schnorrkel {}!", it); let signature = pair.sign(msg.as_bytes()); - crypto::sr25519_verify(&signature, msg.as_bytes(), &pair.public()); + crypto::sr25519_batch_verify(&signature, msg.as_bytes(), &pair.public()); } // push invlaid - crypto::sr25519_verify( + crypto::sr25519_batch_verify( &Default::default(), &Vec::new(), &Default::default(), @@ -1135,7 +1316,7 @@ mod tests { for it in 0..70 { let msg = format!("Schnorrkel {}!", it); let signature = pair.sign(msg.as_bytes()); - crypto::sr25519_verify(&signature, msg.as_bytes(), &pair.public()); + crypto::sr25519_batch_verify(&signature, msg.as_bytes(), &pair.public()); } assert!(crypto::finish_batch_verify()); }); @@ -1143,11 +1324,12 @@ mod tests { #[test] fn batching_works() { - let mut ext = BasicExternalities::with_tasks_executor(); + let mut ext = BasicExternalities::default(); + ext.register_extension(TaskExecutorExt::new(TaskExecutor::new())); ext.execute_with(|| { // invalid ed25519 signature crypto::start_batch_verify(); - crypto::ed25519_verify( + crypto::ed25519_batch_verify( &Default::default(), &Vec::new(), &Default::default(), @@ -1160,12 +1342,12 @@ mod tests { let pair = ed25519::Pair::generate_with_phrase(None).0; let msg = b"Important message"; let signature = pair.sign(msg); - crypto::ed25519_verify(&signature, msg, &pair.public()); + crypto::ed25519_batch_verify(&signature, msg, &pair.public()); let pair = ed25519::Pair::generate_with_phrase(None).0; let msg = b"Even more important message"; let signature = pair.sign(msg); - crypto::ed25519_verify(&signature, msg, &pair.public()); + crypto::ed25519_batch_verify(&signature, msg, &pair.public()); assert!(crypto::finish_batch_verify()); @@ -1175,9 +1357,9 @@ mod tests { let pair = ed25519::Pair::generate_with_phrase(None).0; let msg = b"Important message"; let signature = pair.sign(msg); - crypto::ed25519_verify(&signature, msg, &pair.public()); + crypto::ed25519_batch_verify(&signature, msg, &pair.public()); - crypto::ed25519_verify( + crypto::ed25519_batch_verify( &Default::default(), &Vec::new(), &Default::default(), @@ -1191,17 +1373,17 @@ mod tests { let pair = ed25519::Pair::generate_with_phrase(None).0; let msg = b"Ed25519 batching"; let signature = pair.sign(msg); - crypto::ed25519_verify(&signature, msg, &pair.public()); + crypto::ed25519_batch_verify(&signature, msg, &pair.public()); let pair = sr25519::Pair::generate_with_phrase(None).0; let msg = b"Schnorrkel rules"; let signature = pair.sign(msg); - crypto::sr25519_verify(&signature, msg, &pair.public()); + crypto::sr25519_batch_verify(&signature, msg, &pair.public()); let pair = sr25519::Pair::generate_with_phrase(None).0; let msg = b"Schnorrkel batches!"; let signature = pair.sign(msg); - crypto::sr25519_verify(&signature, msg, &pair.public()); + crypto::sr25519_batch_verify(&signature, msg, &pair.public()); assert!(crypto::finish_batch_verify()); @@ -1211,9 +1393,9 @@ mod tests { let pair = sr25519::Pair::generate_with_phrase(None).0; let msg = b"Schnorrkcel!"; let signature = pair.sign(msg); - crypto::sr25519_verify(&signature, msg, &pair.public()); + crypto::sr25519_batch_verify(&signature, msg, &pair.public()); - crypto::sr25519_verify( + crypto::sr25519_batch_verify( &Default::default(), &Vec::new(), &Default::default(), diff --git a/primitives/keyring/Cargo.toml b/primitives/keyring/Cargo.toml index 23e243239a553322b75878422f3c8e22d8e9ce29..e3634d9bb5f942df99f47e7ded938681704a7796 100644 --- a/primitives/keyring/Cargo.toml +++ b/primitives/keyring/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-keyring" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Keyring support code for the runtime. A set of test accounts." @@ -14,7 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-core = { version = "2.0.0-dev", path = "../core" } -sp-runtime = { version = "2.0.0-dev", path = "../runtime" } +sp-core = { version = "2.0.0-rc6", path = "../core" } +sp-runtime = { version = "2.0.0-rc6", path = "../runtime" } lazy_static = "1.4.0" strum = { version = "0.16.0", features = ["derive"] } diff --git a/primitives/keyring/README.md b/primitives/keyring/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1610f237df97a8a96f5017f0c15c686661de36e4 --- /dev/null +++ b/primitives/keyring/README.md @@ -0,0 +1,3 @@ +Support code for the runtime. A set of test accounts. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/keyring/src/ed25519.rs b/primitives/keyring/src/ed25519.rs index 197b9ded8794b2cc93418af09572c2d0dae9e24f..17882027387c538e4ab4b9a96312ba32488984d5 100644 --- a/primitives/keyring/src/ed25519.rs +++ b/primitives/keyring/src/ed25519.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Support code for the runtime. A set of test accounts. diff --git a/primitives/keyring/src/lib.rs b/primitives/keyring/src/lib.rs index 18f8cdf2c4ab9c8ce8e97e9f1dfe6a315460a7dc..55ed14d294f1dc7cb82d8e516d14bbca4c08f03b 100644 --- a/primitives/keyring/src/lib.rs +++ b/primitives/keyring/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Support code for the runtime. A set of test accounts. diff --git a/primitives/keyring/src/sr25519.rs b/primitives/keyring/src/sr25519.rs index 476997f2db79b00b79b3214bd8f20f6d49898ffb..80397f0de9fc12d42eae2776b484651954270a90 100644 --- a/primitives/keyring/src/sr25519.rs +++ b/primitives/keyring/src/sr25519.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Support code for the runtime. A set of test accounts. diff --git a/primitives/phragmen/Cargo.toml b/primitives/npos-elections/Cargo.toml similarity index 57% rename from primitives/phragmen/Cargo.toml rename to primitives/npos-elections/Cargo.toml index 29fc0ed41e40878bfd6981efb0ae551d7a28ab05..26043df84f7a7108ff8e45b75f499e1a33249f09 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/npos-elections/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "sp-phragmen" -version = "2.0.0-dev" +name = "sp-npos-elections" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -description = "Phragmen primitives" +description = "NPoS election algorithm primitives" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] @@ -14,15 +14,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -sp-phragmen-compact = { version = "2.0.0-dev", path = "./compact" } -sp-arithmetic = { version = "2.0.0-dev", default-features = false, path = "../arithmetic" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +sp-npos-elections-compact = { version = "2.0.0-rc6", path = "./compact" } +sp-arithmetic = { version = "2.0.0-rc6", default-features = false, path = "../arithmetic" } [dev-dependencies] -substrate-test-utils = { version = "2.0.0-dev", path = "../../test-utils" } +substrate-test-utils = { version = "2.0.0-rc6", path = "../../test-utils" } rand = "0.7.3" -sp-phragmen = { version = "2.0.0-dev", path = "." } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } [features] default = ["std"] diff --git a/primitives/npos-elections/README.md b/primitives/npos-elections/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a98351a6d89a715c62709dfd9188a2ddf55fee62 --- /dev/null +++ b/primitives/npos-elections/README.md @@ -0,0 +1,12 @@ +A set of election algorithms to be used with a substrate runtime, typically within the staking +sub-system. Notable implementation include + +- [`seq_phragmen`]: Implements the Phragmén Sequential Method. An un-ranked, relatively fast + election method that ensures PJR, but does not provide a constant factor approximation of the + maximin problem. +- [`balance_solution`]: Implements the star balancing algorithm. This iterative process can + increase a solutions score, as described in [`evaluate_support`]. + +More information can be found at: https://arxiv.org/abs/2004.12990 + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/phragmen/benches/phragmen.rs b/primitives/npos-elections/benches/phragmen.rs similarity index 91% rename from primitives/phragmen/benches/phragmen.rs rename to primitives/npos-elections/benches/phragmen.rs index e274586f601d5588ddeeedf2e88c8149c473bd7c..e2385665bf0655ef422db11aa96baf05ffa4ed4c 100644 --- a/primitives/phragmen/benches/phragmen.rs +++ b/primitives/npos-elections/benches/phragmen.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. + //! Benchmarks of the phragmen election algorithm. //! Note that execution times will not be accurate in an absolute scale, since //! - Everything is executed in the context of `TestExternalities` @@ -24,10 +25,15 @@ extern crate test; use test::Bencher; use rand::{self, Rng}; -use sp_phragmen::{PhragmenResult, VoteWeight}; +use sp_npos_elections::{ElectionResult, VoteWeight}; use std::collections::BTreeMap; -use sp_runtime::{Perbill, traits::Zero}; +use sp_runtime::{Perbill, PerThing, traits::Zero}; +use sp_npos_elections::{ + balance_solution, assignment_ratio_to_staked, build_support_map, to_without_backing, VoteWeight, + ExtendedBalance, Assignment, StakedAssignment, IdentifierT, assignment_ratio_to_staked, + seq_phragmen, +}; // default params. Each will be scaled by the benchmarks individually. const VALIDATORS: u64 = 100; @@ -41,13 +47,7 @@ const PREFIX: AccountId = 1000_000; type AccountId = u64; mod bench_closure_and_slice { - use sp_phragmen::{ - VoteWeight, ExtendedBalance, Assignment, StakedAssignment, IdentifierT, - assignment_ratio_to_staked, - }; - use sp_runtime::{Perbill, PerThing}; - use rand::{self, Rng, RngCore}; - use test::Bencher; + use super::*; fn random_assignment() -> Assignment { let mut rng = rand::thread_rng(); @@ -59,8 +59,8 @@ mod bench_closure_and_slice { } /// Converts a vector of ratio assignments into ones with absolute budget value. - pub fn assignment_ratio_to_staked_slice( - ratio: Vec>, + pub fn assignment_ratio_to_staked_slice( + ratio: Vec>, stakes: &[VoteWeight], ) -> Vec> where @@ -134,7 +134,7 @@ fn do_phragmen( }); b.iter(|| { - let PhragmenResult { winners, assignments } = sp_phragmen::elect::( + let ElectionResult { winners, assignments } = seq_phragmen::( to_elect, Zero::zero(), candidates.clone(), @@ -145,14 +145,13 @@ fn do_phragmen( *stake_of_tree.get(who).unwrap() }; - // Do the benchmarking with equalize. + // Do the benchmarking with balancing. if eq_iters > 0 { - use sp_phragmen::{equalize, assignment_ratio_to_staked, build_support_map, to_without_backing}; let staked = assignment_ratio_to_staked(assignments, &stake_of); let winners = to_without_backing(winners); let mut support = build_support_map(winners.as_ref(), staked.as_ref()).0; - equalize( + balance_solution( staked.into_iter().map(|a| (a.clone(), stake_of(&a.who))).collect(), &mut support, eq_tolerance, diff --git a/primitives/phragmen/compact/Cargo.toml b/primitives/npos-elections/compact/Cargo.toml similarity index 76% rename from primitives/phragmen/compact/Cargo.toml rename to primitives/npos-elections/compact/Cargo.toml index 386116f2683ae9998e5b02e70477065f903cfd59..7f55fe6bea1539dd25aaf7aea2c42dfdaa8b5086 100644 --- a/primitives/phragmen/compact/Cargo.toml +++ b/primitives/npos-elections/compact/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "sp-phragmen-compact" -version = "2.0.0-dev" +name = "sp-npos-elections-compact" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -description = "Phragmen Compact Solution" +description = "NPoS Compact Solution Type" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/npos-elections/compact/src/assignment.rs b/primitives/npos-elections/compact/src/assignment.rs new file mode 100644 index 0000000000000000000000000000000000000000..8b61076521d7cfe0f20925d814b22ca8dcf198ca --- /dev/null +++ b/primitives/npos-elections/compact/src/assignment.rs @@ -0,0 +1,205 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Code generation for the ratio assignment type' compact representation. + +use crate::field_name_for; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; + +fn from_impl(count: usize) -> TokenStream2 { + let from_impl_single = { + let name = field_name_for(1); + quote!(1 => compact.#name.push( + ( + index_of_voter(&who).or_invalid_index()?, + index_of_target(&distribution[0].0).or_invalid_index()?, + ) + ),) + }; + + let from_impl_double = { + let name = field_name_for(2); + quote!(2 => compact.#name.push( + ( + index_of_voter(&who).or_invalid_index()?, + ( + index_of_target(&distribution[0].0).or_invalid_index()?, + distribution[0].1, + ), + index_of_target(&distribution[1].0).or_invalid_index()?, + ) + ),) + }; + + let from_impl_rest = (3..=count).map(|c| { + let inner = (0..c-1).map(|i| + quote!((index_of_target(&distribution[#i].0).or_invalid_index()?, distribution[#i].1),) + ).collect::(); + + let field_name = field_name_for(c); + let last_index = c - 1; + let last = quote!(index_of_target(&distribution[#last_index].0).or_invalid_index()?); + + quote!( + #c => compact.#field_name.push( + ( + index_of_voter(&who).or_invalid_index()?, + [#inner], + #last, + ) + ), + ) + }).collect::(); + + quote!( + #from_impl_single + #from_impl_double + #from_impl_rest + ) +} + +fn into_impl(count: usize, per_thing: syn::Type) -> TokenStream2 { + let into_impl_single = { + let name = field_name_for(1); + quote!( + for (voter_index, target_index) in self.#name { + assignments.push(_npos::Assignment { + who: voter_at(voter_index).or_invalid_index()?, + distribution: vec![ + (target_at(target_index).or_invalid_index()?, #per_thing::one()) + ], + }) + } + ) + }; + + let into_impl_double = { + let name = field_name_for(2); + quote!( + for (voter_index, (t1_idx, p1), t2_idx) in self.#name { + if p1 >= #per_thing::one() { + return Err(_npos::Error::CompactStakeOverflow); + } + + // defensive only. Since Percent doesn't have `Sub`. + let p2 = _npos::sp_arithmetic::traits::Saturating::saturating_sub( + #per_thing::one(), + p1, + ); + + assignments.push( _npos::Assignment { + who: voter_at(voter_index).or_invalid_index()?, + distribution: vec![ + (target_at(t1_idx).or_invalid_index()?, p1), + (target_at(t2_idx).or_invalid_index()?, p2), + ] + }); + } + ) + }; + + let into_impl_rest = (3..=count).map(|c| { + let name = field_name_for(c); + quote!( + for (voter_index, inners, t_last_idx) in self.#name { + let mut sum = #per_thing::zero(); + let mut inners_parsed = inners + .iter() + .map(|(ref t_idx, p)| { + sum = _npos::sp_arithmetic::traits::Saturating::saturating_add(sum, *p); + let target = target_at(*t_idx).or_invalid_index()?; + Ok((target, *p)) + }) + .collect::, _npos::Error>>()?; + + if sum >= #per_thing::one() { + return Err(_npos::Error::CompactStakeOverflow); + } + + // defensive only. Since Percent doesn't have `Sub`. + let p_last = _npos::sp_arithmetic::traits::Saturating::saturating_sub( + #per_thing::one(), + sum, + ); + + inners_parsed.push((target_at(t_last_idx).or_invalid_index()?, p_last)); + + assignments.push(_npos::Assignment { + who: voter_at(voter_index).or_invalid_index()?, + distribution: inners_parsed, + }); + } + ) + }).collect::(); + + quote!( + #into_impl_single + #into_impl_double + #into_impl_rest + ) +} + +pub(crate) fn assignment( + ident: syn::Ident, + voter_type: syn::Type, + target_type: syn::Type, + weight_type: syn::Type, + count: usize, +) -> TokenStream2 { + let from_impl = from_impl(count); + let into_impl = into_impl(count, weight_type.clone()); + + quote!( + use _npos::__OrInvalidIndex; + impl #ident { + pub fn from_assignment( + assignments: Vec<_npos::Assignment>, + index_of_voter: FV, + index_of_target: FT, + ) -> Result + where + A: _npos::IdentifierT, + for<'r> FV: Fn(&'r A) -> Option<#voter_type>, + for<'r> FT: Fn(&'r A) -> Option<#target_type>, + { + let mut compact: #ident = Default::default(); + + for _npos::Assignment { who, distribution } in assignments { + match distribution.len() { + 0 => continue, + #from_impl + _ => { + return Err(_npos::Error::CompactTargetOverflow); + } + } + }; + Ok(compact) + } + + pub fn into_assignment( + self, + voter_at: impl Fn(#voter_type) -> Option, + target_at: impl Fn(#target_type) -> Option, + ) -> Result>, _npos::Error> { + let mut assignments: Vec<_npos::Assignment> = Default::default(); + #into_impl + Ok(assignments) + } + } + ) +} diff --git a/primitives/npos-elections/compact/src/codec.rs b/primitives/npos-elections/compact/src/codec.rs new file mode 100644 index 0000000000000000000000000000000000000000..6c5a3bc2134d3bee1df3c5e011348bd366d16d7f --- /dev/null +++ b/primitives/npos-elections/compact/src/codec.rs @@ -0,0 +1,203 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Code generation for the ratio assignment type' encode/decode impl. + +use crate::field_name_for; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; + +pub(crate) fn codec_impl( + ident: syn::Ident, + voter_type: syn::Type, + target_type: syn::Type, + weight_type: syn::Type, + count: usize, +) -> TokenStream2 { + let encode = encode_impl(ident.clone(), count); + let decode = decode_impl(ident, voter_type, target_type, weight_type, count); + + quote! { + #encode + #decode + } +} + +fn decode_impl( + ident: syn::Ident, + voter_type: syn::Type, + target_type: syn::Type, + weight_type: syn::Type, + count: usize, +) -> TokenStream2 { + let decode_impl_single = { + let name = field_name_for(1); + quote! { + let #name = + < + Vec<(_npos::codec::Compact<#voter_type>, _npos::codec::Compact<#target_type>)> + as + _npos::codec::Decode + >::decode(value)?; + let #name = #name + .into_iter() + .map(|(v, t)| (v.0, t.0)) + .collect::>(); + } + }; + + let decode_impl_double = { + let name = field_name_for(2); + quote! { + let #name = + < + Vec<( + _npos::codec::Compact<#voter_type>, + (_npos::codec::Compact<#target_type>, _npos::codec::Compact<#weight_type>), + _npos::codec::Compact<#target_type>, + )> + as + _npos::codec::Decode + >::decode(value)?; + let #name = #name + .into_iter() + .map(|(v, (t1, w), t2)| (v.0, (t1.0, w.0), t2.0)) + .collect::>(); + } + }; + + let decode_impl_rest = (3..=count).map(|c| { + let name = field_name_for(c); + + let inner_impl = (0..c-1).map(|i| + quote! { ( (inner[#i].0).0, (inner[#i].1).0 ), } + ).collect::(); + + quote! { + let #name = + < + Vec<( + _npos::codec::Compact<#voter_type>, + [(_npos::codec::Compact<#target_type>, _npos::codec::Compact<#weight_type>); #c-1], + _npos::codec::Compact<#target_type>, + )> + as _npos::codec::Decode + >::decode(value)?; + let #name = #name + .into_iter() + .map(|(v, inner, t_last)| ( + v.0, + [ #inner_impl ], + t_last.0, + )) + .collect::>(); + } + }).collect::(); + + + let all_field_names = (1..=count).map(|c| { + let name = field_name_for(c); + quote! { #name, } + }).collect::(); + + quote!( + impl _npos::codec::Decode for #ident { + fn decode(value: &mut I) -> Result { + #decode_impl_single + #decode_impl_double + #decode_impl_rest + + // The above code generates variables with the decoded value with the same name as + // filed names of the struct, i.e. `let votes4 = decode_value_of_votes4`. All we + // have to do is collect them into the main struct now. + Ok(#ident { #all_field_names }) + } + } + ) +} + +// General attitude is that we will convert inner values to `Compact` and then use the normal +// `Encode` implementation. +fn encode_impl(ident: syn::Ident, count: usize) -> TokenStream2 { + let encode_impl_single = { + let name = field_name_for(1); + quote! { + let #name = self.#name + .iter() + .map(|(v, t)| ( + _npos::codec::Compact(v.clone()), + _npos::codec::Compact(t.clone()), + )) + .collect::>(); + #name.encode_to(&mut r); + } + }; + + let encode_impl_double = { + let name = field_name_for(2); + quote! { + let #name = self.#name + .iter() + .map(|(v, (t1, w), t2)| ( + _npos::codec::Compact(v.clone()), + ( + _npos::codec::Compact(t1.clone()), + _npos::codec::Compact(w.clone()) + ), + _npos::codec::Compact(t2.clone()), + )) + .collect::>(); + #name.encode_to(&mut r); + } + }; + + let encode_impl_rest = (3..=count).map(|c| { + let name = field_name_for(c); + + // we use the knowledge of the length to avoid copy_from_slice. + let inners_compact_array = (0..c-1).map(|i| + quote!{( + _npos::codec::Compact(inner[#i].0.clone()), + _npos::codec::Compact(inner[#i].1.clone()), + ),} + ).collect::(); + + quote! { + let #name = self.#name + .iter() + .map(|(v, inner, t_last)| ( + _npos::codec::Compact(v.clone()), + [ #inners_compact_array ], + _npos::codec::Compact(t_last.clone()), + )) + .collect::>(); + #name.encode_to(&mut r); + } + }).collect::(); + + quote!( + impl _npos::codec::Encode for #ident { + fn encode(&self) -> Vec { + let mut r = vec![]; + #encode_impl_single + #encode_impl_double + #encode_impl_rest + r + } + } + ) +} diff --git a/primitives/npos-elections/compact/src/lib.rs b/primitives/npos-elections/compact/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..03526d17981f94ffde04d121140cecfaae53d9f6 --- /dev/null +++ b/primitives/npos-elections/compact/src/lib.rs @@ -0,0 +1,314 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Proc macro for a npos compact assignment. + +use proc_macro::TokenStream; +use proc_macro2::{TokenStream as TokenStream2, Span, Ident}; +use proc_macro_crate::crate_name; +use quote::quote; +use syn::{parse::{Parse, ParseStream, Result}}; + +mod assignment; +mod codec; + +// prefix used for struct fields in compact. +const PREFIX: &'static str = "votes"; + +pub(crate) fn syn_err(message: &'static str) -> syn::Error { + syn::Error::new(Span::call_site(), message) +} + +/// Generates a struct to store the election result in a small way. This can encode a structure +/// which is the equivalent of a `sp_npos_elections::Assignment<_>`. +/// +/// The following data types can be configured by the macro. +/// +/// - The identifier of the voter. This can be any type that supports `parity-scale-codec`'s compact +/// encoding. +/// - The identifier of the target. This can be any type that supports `parity-scale-codec`'s +/// compact encoding. +/// - The accuracy of the ratios. This must be one of the `PerThing` types defined in +/// `sp-arithmetic`. +/// +/// Moreover, the maximum number of edges per voter (distribution per assignment) also need to be +/// specified. Attempting to convert from/to an assignment with more distributions will fail. +/// +/// +/// For example, the following generates a public struct with name `TestSolution` with `u16` voter +/// type, `u8` target type and `Perbill` accuracy with maximum of 8 edges per voter. +/// +/// ```ignore +/// generate_solution_type!(pub struct TestSolution::(8)) +/// ``` +/// +/// The given struct provides function to convert from/to Assignment: +/// +/// - [`from_assignment()`]. +/// - [`fn into_assignment()`]. +/// +/// The generated struct is by default deriving both `Encode` and `Decode`. This is okay but could +/// lead to many 0s in the solution. If prefixed with `#[compact]`, then a custom compact encoding +/// for numbers will be used, similar to how `parity-scale-codec`'s `Compact` works. +/// +/// ```ignore +/// generate_solution_type!( +/// #[compact] +/// pub struct TestSolutionCompact::(8) +/// ) +/// ``` +#[proc_macro] +pub fn generate_solution_type(item: TokenStream) -> TokenStream { + let SolutionDef { + vis, + ident, + count, + voter_type, + target_type, + weight_type, + compact_encoding, + } = syn::parse_macro_input!(item as SolutionDef); + + let imports = imports().unwrap_or_else(|e| e.to_compile_error()); + + let solution_struct = struct_def( + vis, + ident.clone(), + count, + voter_type.clone(), + target_type.clone(), + weight_type.clone(), + compact_encoding, + ).unwrap_or_else(|e| e.to_compile_error()); + + let assignment_impls = assignment::assignment( + ident.clone(), + voter_type.clone(), + target_type.clone(), + weight_type.clone(), + count, + ); + + quote!( + #imports + #solution_struct + #assignment_impls + ).into() +} + +fn struct_def( + vis: syn::Visibility, + ident: syn::Ident, + count: usize, + voter_type: syn::Type, + target_type: syn::Type, + weight_type: syn::Type, + compact_encoding: bool, +) -> Result { + if count <= 2 { + Err(syn_err("cannot build compact solution struct with capacity less than 3."))? + } + + let singles = { + let name = field_name_for(1); + quote!( + #name: Vec<(#voter_type, #target_type)>, + ) + }; + + let doubles = { + let name = field_name_for(2); + quote!( + #name: Vec<(#voter_type, (#target_type, #weight_type), #target_type)>, + ) + }; + + let rest = (3..=count).map(|c| { + let field_name = field_name_for(c); + let array_len = c - 1; + quote!( + #field_name: Vec<( + #voter_type, + [(#target_type, #weight_type); #array_len], + #target_type + )>, + ) + }).collect::(); + + + let len_impl = (1..=count).map(|c| { + let field_name = field_name_for(c); + quote!( + all_len = all_len.saturating_add(self.#field_name.len()); + ) + }).collect::(); + + let edge_count_impl = (1..count).map(|c| { + let field_name = field_name_for(c); + quote!( + all_edges = all_edges.saturating_add( + self.#field_name.len().saturating_mul(#c as usize) + ); + ) + }).collect::(); + + let derives_and_maybe_compact_encoding = if compact_encoding { + // custom compact encoding. + let compact_impl = codec::codec_impl( + ident.clone(), + voter_type.clone(), + target_type.clone(), + weight_type.clone(), + count, + ); + quote!{ + #compact_impl + #[derive(Default, PartialEq, Eq, Clone, Debug)] + } + } else { + // automatically derived. + quote!(#[derive(Default, PartialEq, Eq, Clone, Debug, _npos::codec::Encode, _npos::codec::Decode)]) + }; + + Ok(quote! ( + /// A struct to encode a election assignment in a compact way. + #derives_and_maybe_compact_encoding + #vis struct #ident { #singles #doubles #rest } + + impl _npos::VotingLimit for #ident { + const LIMIT: usize = #count; + } + + impl #ident { + /// Get the length of all the assignments that this type is encoding. This is basically + /// the same as the number of assignments, or the number of voters in total. + pub fn len(&self) -> usize { + let mut all_len = 0usize; + #len_impl + all_len + } + + /// Get the total count of edges. + pub fn edge_count(&self) -> usize { + let mut all_edges = 0usize; + #edge_count_impl + all_edges + } + + /// Get the average edge count. + pub fn average_edge_count(&self) -> usize { + self.edge_count().checked_div(self.len()).unwrap_or(0) + } + } + )) +} + +fn imports() -> Result { + if std::env::var("CARGO_PKG_NAME").unwrap() == "sp-npos-elections" { + Ok(quote! { + use crate as _npos; + }) + } else { + match crate_name("sp-npos-elections") { + Ok(sp_npos_elections) => { + let ident = syn::Ident::new(&sp_npos_elections, Span::call_site()); + Ok(quote!( extern crate #ident as _npos; )) + }, + Err(e) => Err(syn::Error::new(Span::call_site(), &e)), + } + } +} + +struct SolutionDef { + vis: syn::Visibility, + ident: syn::Ident, + voter_type: syn::Type, + target_type: syn::Type, + weight_type: syn::Type, + count: usize, + compact_encoding: bool, +} + +fn check_compact_attr(input: ParseStream) -> Result { + let mut attrs = input.call(syn::Attribute::parse_outer).unwrap_or_default(); + if attrs.len() == 1 { + let attr = attrs.pop().expect("Vec with len 1 can be popped."); + if attr.path.segments.len() == 1 { + let segment = attr.path.segments.first().expect("Vec with len 1 can be popped."); + if segment.ident == Ident::new("compact", Span::call_site()) { + Ok(true) + } else { + Err(syn_err("generate_solution_type macro can only accept #[compact] attribute.")) + } + } else { + Err(syn_err("generate_solution_type macro can only accept #[compact] attribute.")) + } + } else { + Ok(false) + } +} + +/// #[compact] pub struct CompactName::() +impl Parse for SolutionDef { + fn parse(input: ParseStream) -> syn::Result { + // optional #[compact] + let compact_encoding = check_compact_attr(input)?; + + // struct + let vis: syn::Visibility = input.parse()?; + let _ = ::parse(input)?; + let ident: syn::Ident = input.parse()?; + + // :: + let _ = ::parse(input)?; + let generics: syn::AngleBracketedGenericArguments = input.parse()?; + + if generics.args.len() != 3 { + return Err(syn_err("Must provide 3 generic args.")) + } + + let mut types: Vec = generics.args.iter().map(|t| + match t { + syn::GenericArgument::Type(ty) => Ok(ty.clone()), + _ => Err(syn_err("Wrong type of generic provided. Must be a `type`.")), + } + ).collect::>()?; + + let weight_type = types.pop().expect("Vector of length 3 can be popped; qed"); + let target_type = types.pop().expect("Vector of length 2 can be popped; qed"); + let voter_type = types.pop().expect("Vector of length 1 can be popped; qed"); + + // () + let count_expr: syn::ExprParen = input.parse()?; + let expr = count_expr.expr; + let expr_lit = match *expr { + syn::Expr::Lit(count_lit) => count_lit.lit, + _ => return Err(syn_err("Count must be literal.")) + }; + let int_lit = match expr_lit { + syn::Lit::Int(int_lit) => int_lit, + _ => return Err(syn_err("Count must be int literal.")) + }; + let count = int_lit.base10_parse::()?; + + Ok(Self { vis, ident, voter_type, target_type, weight_type, count, compact_encoding } ) + } +} + +fn field_name_for(n: usize) -> Ident { + Ident::new(&format!("{}{}", PREFIX, n), Span::call_site()) +} diff --git a/primitives/phragmen/fuzzer/.gitignore b/primitives/npos-elections/fuzzer/.gitignore similarity index 100% rename from primitives/phragmen/fuzzer/.gitignore rename to primitives/npos-elections/fuzzer/.gitignore diff --git a/primitives/phragmen/fuzzer/Cargo.lock b/primitives/npos-elections/fuzzer/Cargo.lock similarity index 99% rename from primitives/phragmen/fuzzer/Cargo.lock rename to primitives/npos-elections/fuzzer/Cargo.lock index 3ef2a2732424a3ddd412192dc01ac0647c36ffe1..cd172421aeb28f8cddde2902801dfd322aaddd2c 100644 --- a/primitives/phragmen/fuzzer/Cargo.lock +++ b/primitives/npos-elections/fuzzer/Cargo.lock @@ -540,7 +540,7 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.19.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "198831fe8722331a395bc199a5d08efbc197497ef354cb4c77b969c02ffc0fc4" dependencies = [ @@ -1234,20 +1234,20 @@ dependencies = [ ] [[package]] -name = "sp-phragmen" +name = "sp-npos-elections" version = "2.0.0-alpha.3" dependencies = [ "parity-scale-codec", "serde", "sp-core", - "sp-phragmen-compact", + "sp-npos-elections-compact", "sp-runtime", "sp-std", ] [[package]] -name = "sp-phragmen-compact" -version = "2.0.0-dev" +name = "sp-npos-elections-compact" +version = "2.0.0-rc3" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1256,12 +1256,12 @@ dependencies = [ ] [[package]] -name = "sp-phragmen-fuzzer" +name = "sp-npos-elections-fuzzer" version = "2.0.0" dependencies = [ "honggfuzz", "rand 0.7.3", - "sp-phragmen", + "sp-npos-elections", ] [[package]] diff --git a/primitives/phragmen/fuzzer/Cargo.toml b/primitives/npos-elections/fuzzer/Cargo.toml similarity index 57% rename from primitives/phragmen/fuzzer/Cargo.toml rename to primitives/npos-elections/fuzzer/Cargo.toml index 7f7aef1961d518864759cd7b1a4b745ed9d9c378..f0c9442aade5fe27aa62e3e124048d8271cbdf32 100644 --- a/primitives/phragmen/fuzzer/Cargo.toml +++ b/primitives/npos-elections/fuzzer/Cargo.toml @@ -1,22 +1,22 @@ [package] -name = "sp-phragmen-fuzzer" +name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Fuzzer for phragmén implementation." -documentation = "https://docs.rs/sp-phragmen-fuzzer" +documentation = "https://docs.rs/sp-npos-elections-fuzzer" publish = false [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-phragmen = { version = "2.0.0-dev", path = ".." } -sp-std = { version = "2.0.0-dev", path = "../../std" } -sp-runtime = { version = "2.0.0-dev", path = "../../runtime" } +sp-npos-elections = { version = "2.0.0-rc6", path = ".." } +sp-std = { version = "2.0.0-rc6", path = "../../std" } +sp-runtime = { version = "2.0.0-rc6", path = "../../runtime" } honggfuzz = "0.5" rand = { version = "0.7.3", features = ["std", "small_rng"] } @@ -25,5 +25,5 @@ name = "reduce" path = "src/reduce.rs" [[bin]] -name = "equalize" -path = "src/equalize.rs" +name = "balance_solution" +path = "src/balance_solution.rs" diff --git a/primitives/phragmen/fuzzer/src/equalize.rs b/primitives/npos-elections/fuzzer/src/balance_solution.rs similarity index 69% rename from primitives/phragmen/fuzzer/src/equalize.rs rename to primitives/npos-elections/fuzzer/src/balance_solution.rs index cb4f98c4eb15284be7de03bbbefa90b5d027e82c..13f9b29706aed09da15537e6493b95995a692ff0 100644 --- a/primitives/phragmen/fuzzer/src/equalize.rs +++ b/primitives/npos-elections/fuzzer/src/balance_solution.rs @@ -1,20 +1,21 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Fuzzing fro the equalize algorithm +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Fuzzing fro the balance_solution algorithm //! //! It ensures that any solution which gets equalized will lead into a better or equally scored //! one. @@ -22,9 +23,9 @@ mod common; use common::to_range; use honggfuzz::fuzz; -use sp_phragmen::{ - equalize, assignment_ratio_to_staked, build_support_map, to_without_backing, elect, - PhragmenResult, VoteWeight, evaluate_support, is_score_better, +use sp_npos_elections::{ + balance_solution, assignment_ratio_to_staked, build_support_map, to_without_backing, seq_phragmen, + ElectionResult, VoteWeight, evaluate_support, is_score_better, }; use sp_std::collections::btree_map::BTreeMap; use sp_runtime::Perbill; @@ -38,7 +39,7 @@ fn generate_random_phragmen_result( to_elect: usize, edge_per_voter: u64, mut rng: impl RngCore, -) -> (PhragmenResult, BTreeMap) { +) -> (ElectionResult, BTreeMap) { let prefix = 100_000; // Note, it is important that stakes are always bigger than ed and let base_stake: u64 = 1_000_000_000; @@ -72,7 +73,7 @@ fn generate_random_phragmen_result( }); ( - elect::( + seq_phragmen::( to_elect, 0, candidates, @@ -85,7 +86,14 @@ fn generate_random_phragmen_result( fn main() { loop { fuzz!(|data: (usize, usize, usize, usize, usize, u64)| { - let (mut target_count, mut voter_count, mut iterations, mut edge_per_voter, mut to_elect, seed) = data; + let ( + mut target_count, + mut voter_count, + mut iterations, + mut edge_per_voter, + mut to_elect, + seed, + ) = data; let rng = rand::rngs::SmallRng::seed_from_u64(seed); target_count = to_range(target_count, 50, 2000); voter_count = to_range(voter_count, 50, 1000); @@ -94,7 +102,7 @@ fn main() { edge_per_voter = to_range(edge_per_voter, 1, target_count); println!("++ [{} / {} / {} / {}]", voter_count, target_count, to_elect, iterations); - let (PhragmenResult { winners, assignments }, stake_of_tree) = generate_random_phragmen_result( + let (ElectionResult { winners, assignments }, stake_of_tree) = generate_random_phragmen_result( voter_count as u64, target_count as u64, to_elect, @@ -106,7 +114,7 @@ fn main() { *stake_of_tree.get(who).unwrap() }; - let mut staked = assignment_ratio_to_staked(assignments.clone(), &stake_of); + let mut staked = assignment_ratio_to_staked(assignments, &stake_of); let winners = to_without_backing(winners); let mut support = build_support_map(winners.as_ref(), staked.as_ref()).0; @@ -116,7 +124,7 @@ fn main() { return; } - let i = equalize( + let i = balance_solution( &mut staked, &mut support, 10, @@ -130,7 +138,7 @@ fn main() { return; } - let enhance = is_score_better(initial_score, final_score); + let enhance = is_score_better(final_score, initial_score, Perbill::zero()); println!( "iter = {} // {:?} -> {:?} [{}]", @@ -139,6 +147,7 @@ fn main() { final_score, enhance, ); + // if more than one iteration has been done, or they must be equal. assert!(enhance || initial_score == final_score || i == 0) }); diff --git a/primitives/npos-elections/fuzzer/src/common.rs b/primitives/npos-elections/fuzzer/src/common.rs new file mode 100644 index 0000000000000000000000000000000000000000..89fed14cfaeabb55a9658245170105e2304511e8 --- /dev/null +++ b/primitives/npos-elections/fuzzer/src/common.rs @@ -0,0 +1,30 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Common fuzzing utils. + +/// converts x into the range [a, b] in a pseudo-fair way. +pub fn to_range(x: usize, a: usize, b: usize) -> usize { + // does not work correctly if b < 2 * a + assert!(b >= 2 * a); + let collapsed = x % b; + if collapsed >= a { + collapsed + } else { + collapsed + a + } +} diff --git a/primitives/phragmen/fuzzer/src/reduce.rs b/primitives/npos-elections/fuzzer/src/reduce.rs similarity index 83% rename from primitives/phragmen/fuzzer/src/reduce.rs rename to primitives/npos-elections/fuzzer/src/reduce.rs index f0a16466636e3fe6e271ea039113c59d46345b4d..d08a440a6291ff18190090d16f0c43f5ffa24707 100644 --- a/primitives/phragmen/fuzzer/src/reduce.rs +++ b/primitives/npos-elections/fuzzer/src/reduce.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Fuzzing for the reduce algorithm. //! @@ -33,7 +34,7 @@ use honggfuzz::fuzz; mod common; use common::to_range; -use sp_phragmen::{StakedAssignment, ExtendedBalance, build_support_map, reduce}; +use sp_npos_elections::{StakedAssignment, ExtendedBalance, build_support_map, reduce}; use rand::{self, Rng, SeedableRng, RngCore}; type Balance = u128; diff --git a/primitives/npos-elections/src/helpers.rs b/primitives/npos-elections/src/helpers.rs new file mode 100644 index 0000000000000000000000000000000000000000..063eac70c57fd77325da73c99581532977f315ee --- /dev/null +++ b/primitives/npos-elections/src/helpers.rs @@ -0,0 +1,134 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Helper methods for npos-elections. + +use crate::{Assignment, ExtendedBalance, VoteWeight, IdentifierT, StakedAssignment, WithApprovalOf, Error}; +use sp_arithmetic::{PerThing, InnerOf}; +use sp_std::prelude::*; + +/// Converts a vector of ratio assignments into ones with absolute budget value. +/// +/// Note that this will NOT attempt at normalizing the result. +pub fn assignment_ratio_to_staked( + ratio: Vec>, + stake_of: FS, +) -> Vec> +where + for<'r> FS: Fn(&'r A) -> VoteWeight, + P: sp_std::ops::Mul, + ExtendedBalance: From>, +{ + ratio + .into_iter() + .map(|a| { + let stake = stake_of(&a.who); + a.into_staked(stake.into()) + }) + .collect() +} + +/// Same as [`assignment_ratio_to_staked`] and try and do normalization. +pub fn assignment_ratio_to_staked_normalized( + ratio: Vec>, + stake_of: FS, +) -> Result>, Error> +where + for<'r> FS: Fn(&'r A) -> VoteWeight, + P: sp_std::ops::Mul, + ExtendedBalance: From>, +{ + let mut staked = assignment_ratio_to_staked(ratio, &stake_of); + staked.iter_mut().map(|a| + a.try_normalize(stake_of(&a.who).into()).map_err(|err| Error::ArithmeticError(err)) + ).collect::>()?; + Ok(staked) +} + +/// Converts a vector of staked assignments into ones with ratio values. +/// +/// Note that this will NOT attempt at normalizing the result. +pub fn assignment_staked_to_ratio( + staked: Vec>, +) -> Vec> +where + ExtendedBalance: From>, +{ + staked.into_iter().map(|a| a.into_assignment()).collect() +} + +/// Same as [`assignment_staked_to_ratio`] and try and do normalization. +pub fn assignment_staked_to_ratio_normalized( + staked: Vec>, +) -> Result>, Error> +where + ExtendedBalance: From>, +{ + let mut ratio = staked.into_iter().map(|a| a.into_assignment()).collect::>(); + ratio.iter_mut().map(|a| + a.try_normalize().map_err(|err| Error::ArithmeticError(err)) + ).collect::>()?; + Ok(ratio) +} + +/// consumes a vector of winners with backing stake to just winners. +pub fn to_without_backing(winners: Vec>) -> Vec { + winners.into_iter().map(|(who, _)| who).collect::>() +} + +#[cfg(test)] +mod tests { + use super::*; + use sp_arithmetic::Perbill; + + #[test] + fn into_staked_works() { + let assignments = vec![ + Assignment { + who: 1u32, + distribution: vec![ + (10u32, Perbill::from_fraction(0.5)), + (20, Perbill::from_fraction(0.5)), + ], + }, + Assignment { + who: 2u32, + distribution: vec![ + (10, Perbill::from_fraction(0.33)), + (20, Perbill::from_fraction(0.67)), + ], + }, + ]; + + let stake_of = |_: &u32| -> VoteWeight { 100 }; + let staked = assignment_ratio_to_staked(assignments, stake_of); + + assert_eq!( + staked, + vec![ + StakedAssignment { + who: 1u32, + distribution: vec![(10u32, 50), (20, 50),] + }, + StakedAssignment { + who: 2u32, + distribution: vec![(10u32, 33), (20, 67),] + } + ] + ); + } +} diff --git a/primitives/phragmen/src/lib.rs b/primitives/npos-elections/src/lib.rs similarity index 76% rename from primitives/phragmen/src/lib.rs rename to primitives/npos-elections/src/lib.rs index 9aaa96150ff7471a56cfaed0137c1ad1df2483d0..58a69a116914f1f3c15f52de0cdf3f339efb99a5 100644 --- a/primitives/phragmen/src/lib.rs +++ b/primitives/npos-elections/src/lib.rs @@ -1,41 +1,36 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Rust implementation of the Phragmén election algorithm. This is used in several pallets to -//! optimally distribute the weight of a set of voters among an elected set of candidates. In the -//! context of staking this is mapped to validators and nominators. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! A set of election algorithms to be used with a substrate runtime, typically within the staking +//! sub-system. Notable implementation include //! -//! The algorithm has two phases: -//! - Sequential phragmen: performed in [`elect`] function which is first pass of the distribution -//! The results are not optimal but the execution time is less. -//! - Equalize post-processing: tries to further distribute the weight fairly among candidates. -//! Incurs more execution time. +//! - [`seq_phragmen`]: Implements the Phragmén Sequential Method. An un-ranked, relatively fast +//! election method that ensures PJR, but does not provide a constant factor approximation of the +//! maximin problem. +//! - [`balance_solution`]: Implements the star balancing algorithm. This iterative process can +//! increase a solutions score, as described in [`evaluate_support`]. //! -//! The main objective of the assignments done by phragmen is to maximize the minimum backed -//! candidate in the elected set. -//! -//! Reference implementation: https://github.com/w3f/consensus -//! Further details: -//! https://research.web3.foundation/en/latest/polkadot/NPoS/4.%20Sequential%20Phragm%C3%A9n%E2%80%99s%20method/ +//! More information can be found at: https://arxiv.org/abs/2004.12990 #![cfg_attr(not(feature = "std"), no_std)] use sp_std::{prelude::*, collections::btree_map::BTreeMap, fmt::Debug, cmp::Ordering, convert::TryFrom}; use sp_arithmetic::{ - PerThing, Rational128, + PerThing, Rational128, ThresholdOrd, InnerOf, Normalizable, helpers_128bit::multiply_by_rational, traits::{Zero, Saturating, Bounded, SaturatedConversion}, }; @@ -65,8 +60,22 @@ pub use codec; #[doc(hidden)] pub use sp_arithmetic; +/// Simple Extension trait to easily convert `None` from index closures to `Err`. +/// +/// This is only generated and re-exported for the compact solution code to use. +#[doc(hidden)] +pub trait __OrInvalidIndex { + fn or_invalid_index(self) -> Result; +} + +impl __OrInvalidIndex for Option { + fn or_invalid_index(self) -> Result { + self.ok_or(Error::CompactInvalidIndex) + } +} + // re-export the compact solution type. -pub use sp_phragmen_compact::generate_compact_solution_type; +pub use sp_npos_elections_compact::generate_solution_type; /// A trait to limit the number of votes per voter. The generated compact type will implement this. pub trait VotingLimit { @@ -89,6 +98,8 @@ pub enum Error { CompactTargetOverflow, /// One of the index functions returned none. CompactInvalidIndex, + /// An error occurred in some arithmetic operation. + ArithmeticError(&'static str), } /// A type which is used in the API of this crate as a numeric weight of a vote, most often the @@ -99,7 +110,7 @@ pub type VoteWeight = u64; pub type ExtendedBalance = u128; /// The score of an assignment. This can be computed from the support map via [`evaluate_support`]. -pub type PhragmenScore = [ExtendedBalance; 3]; +pub type ElectionScore = [ExtendedBalance; 3]; /// A winner, with their respective approval stake. pub type WithApprovalOf = (A, ExtendedBalance); @@ -109,7 +120,7 @@ pub type WithApprovalOf = (A, ExtendedBalance); /// bigger than u64::max_value() is needed. For maximum accuracy we simply use u128; const DEN: u128 = u128::max_value(); -/// A candidate entity for phragmen election. +/// A candidate entity for the election. #[derive(Clone, Default, Debug)] struct Candidate { /// Identifier. @@ -146,9 +157,9 @@ struct Edge { candidate_index: usize, } -/// Final result of the phragmen election. +/// Final result of the election. #[derive(Debug)] -pub struct PhragmenResult { +pub struct ElectionResult { /// Just winners zipped with their approval stake. Note that the approval stake is merely the /// sub of their received stake and could be used for very basic sorting and approval voting. pub winners: Vec>, @@ -160,16 +171,16 @@ pub struct PhragmenResult { /// A voter's stake assignment among a set of targets, represented as ratios. #[derive(Debug, Clone, Default)] #[cfg_attr(feature = "std", derive(PartialEq, Eq, Encode, Decode))] -pub struct Assignment { +pub struct Assignment { /// Voter's identifier. pub who: AccountId, /// The distribution of the voter's stake. - pub distribution: Vec<(AccountId, T)>, + pub distribution: Vec<(AccountId, P)>, } -impl Assignment +impl Assignment where - ExtendedBalance: From<::Inner>, + ExtendedBalance: From>, { /// Convert from a ratio assignment into one with absolute values aka. [`StakedAssignment`]. /// @@ -178,50 +189,49 @@ where /// distribution's sum is exactly equal to the total budget, by adding or subtracting the /// remainder from the last distribution. /// - /// If an edge ratio is [`Bounded::max_value()`], it is dropped. This edge can never mean + /// If an edge ratio is [`Bounded::min_value()`], it is dropped. This edge can never mean /// anything useful. - pub fn into_staked(self, stake: ExtendedBalance, fill: bool) -> StakedAssignment + pub fn into_staked(self, stake: ExtendedBalance) -> StakedAssignment where - T: sp_std::ops::Mul, + P: sp_std::ops::Mul, { - let mut sum: ExtendedBalance = Bounded::min_value(); - let mut distribution = self - .distribution + let distribution = self.distribution .into_iter() .filter_map(|(target, p)| { // if this ratio is zero, then skip it. - if p == Bounded::min_value() { + if p.is_zero() { None } else { // NOTE: this mul impl will always round to the nearest number, so we might both // overflow and underflow. let distribution_stake = p * stake; - // defensive only. We assume that balance cannot exceed extended balance. - sum = sum.saturating_add(distribution_stake); Some((target, distribution_stake)) } }) .collect::>(); - if fill { - // NOTE: we can do this better. - // https://revs.runtime-revolution.com/getting-100-with-rounded-percentages-273ffa70252b - if let Some(leftover) = stake.checked_sub(sum) { - if let Some(last) = distribution.last_mut() { - last.1 = last.1.saturating_add(leftover); - } - } else if let Some(excess) = sum.checked_sub(stake) { - if let Some(last) = distribution.last_mut() { - last.1 = last.1.saturating_sub(excess); - } - } - } - StakedAssignment { who: self.who, distribution, } } + + /// Try and normalize this assignment. + /// + /// If `Ok(())` is returned, then the assignment MUST have been successfully normalized to 100%. + pub fn try_normalize(&mut self) -> Result<(), &'static str> { + self.distribution + .iter() + .map(|(_, p)| *p) + .collect::>() + .normalize(P::one()) + .map(|normalized_ratios| + self.distribution + .iter_mut() + .zip(normalized_ratios) + .for_each(|((_, old), corrected)| { *old = corrected; }) + ) + } } /// A voter's stake assignment among a set of targets, represented as absolute values in the scale @@ -248,42 +258,23 @@ impl StakedAssignment { /// /// If an edge stake is so small that it cannot be represented in `T`, it is ignored. This edge /// can never be re-created and does not mean anything useful anymore. - pub fn into_assignment(self, fill: bool) -> Assignment + pub fn into_assignment(self) -> Assignment where - ExtendedBalance: From<::Inner>, + ExtendedBalance: From>, + AccountId: IdentifierT, { - let accuracy: u128 = T::ACCURACY.saturated_into(); - let mut sum: u128 = Zero::zero(); - let stake = self.distribution.iter().map(|x| x.1).sum(); - let mut distribution = self - .distribution + let stake = self.total(); + let distribution = self.distribution .into_iter() .filter_map(|(target, w)| { - let per_thing = T::from_rational_approximation(w, stake); + let per_thing = P::from_rational_approximation(w, stake); if per_thing == Bounded::min_value() { None } else { - sum += per_thing.clone().deconstruct().saturated_into(); Some((target, per_thing)) } }) - .collect::>(); - - if fill { - if let Some(leftover) = accuracy.checked_sub(sum) { - if let Some(last) = distribution.last_mut() { - last.1 = last.1.saturating_add( - T::from_parts(leftover.saturated_into()) - ); - } - } else if let Some(excess) = sum.checked_sub(accuracy) { - if let Some(last) = distribution.last_mut() { - last.1 = last.1.saturating_sub( - T::from_parts(excess.saturated_into()) - ); - } - } - } + .collect::>(); Assignment { who: self.who, @@ -291,16 +282,40 @@ impl StakedAssignment { } } + /// Try and normalize this assignment. + /// + /// If `Ok(())` is returned, then the assignment MUST have been successfully normalized to + /// `stake`. + /// + /// NOTE: current implementation of `.normalize` is almost safe to `expect()` upon. The only + /// error case is when the input cannot fit in `T`, or the sum of input cannot fit in `T`. + /// Sadly, both of these are dependent upon the implementation of `VoteLimit`, i.e. the limit + /// of edges per voter which is enforced from upstream. Hence, at this crate, we prefer + /// returning a result and a use the name prefix `try_`. + pub fn try_normalize(&mut self, stake: ExtendedBalance) -> Result<(), &'static str> { + self.distribution + .iter() + .map(|(_, ref weight)| *weight) + .collect::>() + .normalize(stake) + .map(|normalized_weights| + self.distribution + .iter_mut() + .zip(normalized_weights.into_iter()) + .for_each(|((_, weight), corrected)| { *weight = corrected; }) + ) + } + /// Get the total stake of this assignment (aka voter budget). pub fn total(&self) -> ExtendedBalance { self.distribution.iter().fold(Zero::zero(), |a, b| a.saturating_add(b.1)) } } -/// A structure to demonstrate the phragmen result from the perspective of the candidate, i.e. how +/// A structure to demonstrate the election result from the perspective of the candidate, i.e. how /// much support each candidate is receiving. /// -/// This complements the [`PhragmenResult`] and is needed to run the equalize post-processing. +/// This complements the [`ElectionResult`] and is needed to run the balancing post-processing. /// /// This, at the current version, resembles the `Exposure` defined in the Staking pallet, yet /// they do not necessarily have to be the same. @@ -331,12 +346,12 @@ pub type SupportMap = BTreeMap>; /// responsibility of the caller to make sure only those candidates who have a sensible economic /// value are passed in. From the perspective of this function, a candidate can easily be among the /// winner with no backing stake. -pub fn elect( +pub fn seq_phragmen( candidate_count: usize, minimum_candidate_count: usize, initial_candidates: Vec, initial_voters: Vec<(AccountId, VoteWeight, Vec)>, -) -> Option> where +) -> Option> where AccountId: Default + Ord + Clone, R: PerThing, { @@ -370,6 +385,10 @@ pub fn elect( voters.extend(initial_voters.into_iter().map(|(who, voter_stake, votes)| { let mut edges: Vec> = Vec::with_capacity(votes.len()); for v in votes { + if edges.iter().any(|e| e.who == v) { + // duplicate edge. + continue; + } if let Some(idx) = c_idx_cache.get(&v) { // This candidate is valid + already cached. candidates[*idx].approval_stake = candidates[*idx].approval_stake @@ -387,7 +406,6 @@ pub fn elect( // we have already checked that we have more candidates than minimum_candidate_count. - // run phragmen. let to_elect = candidate_count.min(candidates.len()); elected_candidates = Vec::with_capacity(candidate_count); assigned = Vec::with_capacity(candidate_count); @@ -416,7 +434,7 @@ pub fn elect( n.load.n(), n.budget, c.approval_stake, - ).unwrap_or(Bounded::max_value()); + ).unwrap_or_else(|_| Bounded::max_value()); let temp_d = n.load.d(); let temp = Rational128::from(temp_n, temp_d); c.score = c.score.lazy_saturating_add(temp); @@ -470,14 +488,14 @@ pub fn elect( n.load.n(), ) // If result cannot fit in u128. Not much we can do about it. - .unwrap_or(Bounded::max_value()); + .unwrap_or_else(|_| Bounded::max_value()); TryFrom::try_from(parts) // If the result cannot fit into R::Inner. Defensive only. This can // never happen. `desired_scale * e / n`, where `e / n < 1` always // yields a value smaller than `desired_scale`, which will fit into // R::Inner. - .unwrap_or(Bounded::max_value()) + .unwrap_or_else(|_| Bounded::max_value()) } else { // defensive only. Both edge and voter loads are built from // scores, hence MUST have the same denominator. @@ -523,13 +541,13 @@ pub fn elect( } } - Some(PhragmenResult { + Some(ElectionResult { winners: elected_candidates, assignments: assigned, }) } -/// Build the support map from the given phragmen result. It maps a flat structure like +/// Build the support map from the given election result. It maps a flat structure like /// /// ```nocompile /// assignments: vec![ @@ -587,7 +605,7 @@ pub fn build_support_map( (supports, errors) } -/// Evaluate a phragmen result, given the support map. The returned tuple contains: +/// Evaluate a support map. The returned tuple contains: /// /// - Minimum support. This value must be **maximized**. /// - Sum of all supports. This value must be **maximized**. @@ -596,7 +614,7 @@ pub fn build_support_map( /// `O(E)` where `E` is the total number of edges. pub fn evaluate_support( support: &SupportMap, -) -> PhragmenScore { +) -> ElectionScore { let mut min_support = ExtendedBalance::max_value(); let mut sum: ExtendedBalance = Zero::zero(); // NOTE: The third element might saturate but fine for now since this will run on-chain and need @@ -613,38 +631,51 @@ pub fn evaluate_support( [min_support, sum, sum_squared] } -/// Compares two sets of phragmen scores based on desirability and returns true if `that` is -/// better than `this`. +/// Compares two sets of election scores based on desirability and returns true if `this` is +/// better than `that`. /// -/// Evaluation is done in a lexicographic manner. +/// Evaluation is done in a lexicographic manner, and if each element of `this` is `that * epsilon` +/// greater or less than `that`. /// /// Note that the third component should be minimized. -pub fn is_score_better(this: PhragmenScore, that: PhragmenScore) -> bool { - match that +pub fn is_score_better(this: ElectionScore, that: ElectionScore, epsilon: P) -> bool + where ExtendedBalance: From> +{ + match this .iter() .enumerate() - .map(|(i, e)| e.cmp(&this[i])) - .collect::>() + .map(|(i, e)| ( + e.ge(&that[i]), + e.tcmp(&that[i], epsilon.mul_ceil(that[i])), + )) + .collect::>() .as_slice() { - [Ordering::Greater, _, _] => true, - [Ordering::Equal, Ordering::Greater, _] => true, - [Ordering::Equal, Ordering::Equal, Ordering::Less] => true, + // epsilon better in the score[0], accept. + [(_, Ordering::Greater), _, _] => true, + + // less than epsilon better in score[0], but more than epsilon better in the second. + [(true, Ordering::Equal), (_, Ordering::Greater), _] => true, + + // less than epsilon better in score[0, 1], but more than epsilon better in the third + [(true, Ordering::Equal), (true, Ordering::Equal), (_, Ordering::Less)] => true, + + // anything else is not a good score. _ => false, } } -/// Performs equalize post-processing to the output of the election algorithm. This happens in +/// Performs balancing post-processing to the output of the election algorithm. This happens in /// rounds. The number of rounds and the maximum diff-per-round tolerance can be tuned through input /// parameters. /// /// Returns the number of iterations that were preformed. /// -/// - `assignments`: exactly the same is the output of phragmen. +/// - `assignments`: exactly the same as the output of [`seq_phragmen`]. /// - `supports`: mutable reference to s `SupportMap`. This parameter is updated. /// - `tolerance`: maximum difference that can occur before an early quite happens. /// - `iterations`: maximum number of iterations that will be processed. -pub fn equalize( +pub fn balance_solution( assignments: &mut Vec>, supports: &mut SupportMap, tolerance: ExtendedBalance, @@ -658,7 +689,7 @@ pub fn equalize( for assignment in assignments.iter_mut() { let voter_budget = assignment.total(); let StakedAssignment { who, distribution } = assignment; - let diff = do_equalize( + let diff = do_balancing( who, voter_budget, distribution, @@ -675,9 +706,9 @@ pub fn equalize( } } -/// actually perform equalize. same interface is `equalize`. Just called in loops with a check for +/// actually perform balancing. same interface is `balance_solution`. Just called in loops with a check for /// maximum difference. -fn do_equalize( +fn do_balancing( voter: &AccountId, budget: ExtendedBalance, elected_edges: &mut Vec<(AccountId, ExtendedBalance)>, @@ -732,7 +763,7 @@ fn do_equalize( e.1 = 0; }); - elected_edges.sort_unstable_by_key(|e| + elected_edges.sort_by_key(|e| if let Some(e) = support_map.get(&e.0) { e.total } else { Zero::zero() } ); diff --git a/primitives/phragmen/src/mock.rs b/primitives/npos-elections/src/mock.rs similarity index 87% rename from primitives/phragmen/src/mock.rs rename to primitives/npos-elections/src/mock.rs index cf9c90334bc588bb21855e1ed346ec99a3d1fe95..9b25f6f5f2e37ef685c2f078e04c39d7f53caa8b 100644 --- a/primitives/phragmen/src/mock.rs +++ b/primitives/npos-elections/src/mock.rs @@ -1,24 +1,25 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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. +// 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. -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Mock file for phragmen. +//! Mock file for npos-elections. #![cfg(test)] -use crate::{elect, PhragmenResult, Assignment, VoteWeight, ExtendedBalance}; +use crate::{seq_phragmen, ElectionResult, Assignment, VoteWeight, ExtendedBalance}; use sp_arithmetic::{PerThing, traits::{SaturatedConversion, Zero, One}}; use sp_std::collections::btree_map::BTreeMap; use sp_runtime::assert_eq_error_rate; @@ -50,18 +51,18 @@ pub(crate) struct _Edge { pub(crate) struct _Support { pub own: f64, pub total: f64, - pub others: Vec<_PhragmenAssignment>, + pub others: Vec<_Assignment>, } -pub(crate) type _PhragmenAssignment = (A, f64); +pub(crate) type _Assignment = (A, f64); pub(crate) type _SupportMap = BTreeMap>; pub(crate) type AccountId = u64; #[derive(Debug, Clone)] -pub(crate) struct _PhragmenResult { +pub(crate) struct _ElectionResult { pub winners: Vec<(A, ExtendedBalance)>, - pub assignments: Vec<(A, Vec<_PhragmenAssignment>)> + pub assignments: Vec<(A, Vec<_Assignment>)> } pub(crate) fn auto_generate_self_voters(candidates: &[A]) -> Vec<(A, Vec)> { @@ -74,12 +75,12 @@ pub(crate) fn elect_float( initial_candidates: Vec, initial_voters: Vec<(A, Vec)>, stake_of: FS, -) -> Option<_PhragmenResult> where +) -> Option<_ElectionResult> where A: Default + Ord + Copy, for<'r> FS: Fn(&'r A) -> VoteWeight, { let mut elected_candidates: Vec<(A, ExtendedBalance)>; - let mut assigned: Vec<(A, Vec<_PhragmenAssignment>)>; + let mut assigned: Vec<(A, Vec<_Assignment>)>; let mut c_idx_cache = BTreeMap::::new(); let num_voters = initial_candidates.len() + initial_voters.len(); let mut voters: Vec<_Voter> = Vec::with_capacity(num_voters); @@ -171,14 +172,14 @@ pub(crate) fn elect_float( } } - Some(_PhragmenResult { + Some(_ElectionResult { winners: elected_candidates, assignments: assigned, }) } pub(crate) fn equalize_float( - mut assignments: Vec<(A, Vec<_PhragmenAssignment>)>, + mut assignments: Vec<(A, Vec<_Assignment>)>, supports: &mut _SupportMap, tolerance: f64, iterations: usize, @@ -210,7 +211,7 @@ pub(crate) fn equalize_float( pub(crate) fn do_equalize_float( voter: &A, budget_balance: VoteWeight, - elected_edges: &mut Vec<_PhragmenAssignment>, + elected_edges: &mut Vec<_Assignment>, support_map: &mut _SupportMap, tolerance: f64 ) -> f64 where @@ -263,7 +264,7 @@ pub(crate) fn do_equalize_float( e.1 = 0.0; }); - elected_edges.sort_unstable_by(|x, y| + elected_edges.sort_by(|x, y| support_map.get(&x.0) .and_then(|x| support_map.get(&y.0).and_then(|y| x.total.partial_cmp(&y.total))) .unwrap_or(sp_std::cmp::Ordering::Equal) @@ -325,7 +326,7 @@ pub(crate) fn run_and_compare( min_to_elect: usize, ) { // run fixed point code. - let PhragmenResult { winners, assignments } = elect::<_, Output>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Output>( to_elect, min_to_elect, candidates.clone(), @@ -365,7 +366,7 @@ pub(crate) fn run_and_compare( } pub(crate) fn build_support_map_float( - result: &mut _PhragmenResult, + result: &mut _ElectionResult, stake_of: FS, ) -> _SupportMap where for<'r> FS: Fn(&'r AccountId) -> VoteWeight diff --git a/primitives/phragmen/src/node.rs b/primitives/npos-elections/src/node.rs similarity index 90% rename from primitives/phragmen/src/node.rs rename to primitives/npos-elections/src/node.rs index 432c537052ebb5c3e9c5921233554f545cc50ffa..d18c0e9016b64450606a2c2320d317770c5586f9 100644 --- a/primitives/phragmen/src/node.rs +++ b/primitives/npos-elections/src/node.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! (very) Basic implementation of a graph node used in the reduce algorithm. diff --git a/primitives/phragmen/src/reduce.rs b/primitives/npos-elections/src/reduce.rs similarity index 97% rename from primitives/phragmen/src/reduce.rs rename to primitives/npos-elections/src/reduce.rs index 7153a9383c341437b7537bea892542344319b330..6d458a5fffb3864d97ec5843a4a2e5f7894a2992 100644 --- a/primitives/phragmen/src/reduce.rs +++ b/primitives/npos-elections/src/reduce.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Rust implementation of the Phragmén reduce algorithm. This can be used by any off chain //! application to reduce cycles from the edge assignment, which will result in smaller size. @@ -361,11 +362,11 @@ fn reduce_all(assignments: &mut Vec>) -> u32 // create both. let voter_node = tree .entry(voter_id.clone()) - .or_insert(Node::new(voter_id).into_ref()) + .or_insert_with(|| Node::new(voter_id).into_ref()) .clone(); let target_node = tree .entry(target_id.clone()) - .or_insert(Node::new(target_id).into_ref()) + .or_insert_with(|| Node::new(target_id).into_ref()) .clone(); // If one exists but the other one doesn't, or if both does not, then set the existing @@ -639,8 +640,8 @@ fn reduce_all(assignments: &mut Vec>) -> u32 num_changed } -/// Reduce the given [`Vec>`]. This removes redundant edges from without changing the -/// overall backing of any of the elected candidates. +/// Reduce the given [`Vec>`]. This removes redundant edges from +/// without changing the overall backing of any of the elected candidates. /// /// Returns the number of edges removed. /// diff --git a/primitives/phragmen/src/tests.rs b/primitives/npos-elections/src/tests.rs similarity index 55% rename from primitives/phragmen/src/tests.rs rename to primitives/npos-elections/src/tests.rs index 720a0a3f7524a754d4bd7f4112ff3978b4d436ae..8e99d2222e885ca67fdb39973a676b1209c698cc 100644 --- a/primitives/phragmen/src/tests.rs +++ b/primitives/npos-elections/src/tests.rs @@ -1,27 +1,26 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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. +// 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. -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . - -//! Tests for phragmen. - -#![cfg(test)] +//! Tests for npos-elections. use crate::mock::*; use crate::{ - elect, equalize, build_support_map, is_score_better, helpers::*, - Support, StakedAssignment, Assignment, PhragmenResult, ExtendedBalance, + seq_phragmen, balance_solution, build_support_map, is_score_better, helpers::*, + Support, StakedAssignment, Assignment, ElectionResult, ExtendedBalance, }; use substrate_test_utils::assert_eq_uvec; use sp_arithmetic::{Perbill, Permill, Percent, PerU16}; @@ -82,7 +81,7 @@ fn phragmen_poc_works() { ]; let stake_of = create_stake_of(&[(10, 10), (20, 20), (30, 30)]); - let PhragmenResult { winners, assignments } = elect::<_, Perbill>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( 2, 2, candidates, @@ -145,7 +144,7 @@ fn phragmen_poc_works() { Support:: { total: 35, voters: vec![(20, 20), (30, 15)] }, ); - equalize( + balance_solution( &mut staked, &mut support_map, 0, @@ -239,11 +238,14 @@ fn phragmen_accuracy_on_large_scale_only_validators() { (5, (u64::max_value() - 2).into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, Perbill>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( 2, 2, candidates.clone(), - auto_generate_self_voters(&candidates).iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), + auto_generate_self_voters(&candidates) + .iter() + .map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())) + .collect::>(), ).unwrap(); assert_eq_uvec!(winners, vec![(1, 18446744073709551614u128), (5, 18446744073709551613u128)]); @@ -269,7 +271,7 @@ fn phragmen_accuracy_on_large_scale_validators_and_nominators() { (14, u64::max_value().into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, Perbill>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( 2, 2, candidates, @@ -312,7 +314,7 @@ fn phragmen_accuracy_on_small_scale_self_vote() { (30, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, Perbill>( + let ElectionResult { winners, assignments: _ } = seq_phragmen::<_, Perbill>( 3, 3, candidates, @@ -342,7 +344,7 @@ fn phragmen_accuracy_on_small_scale_no_self_vote() { (3, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, Perbill>( + let ElectionResult { winners, assignments: _ } = seq_phragmen::<_, Perbill>( 3, 3, candidates, @@ -375,7 +377,7 @@ fn phragmen_large_scale_test() { (50, 990000000000000000), ]); - let PhragmenResult { winners, assignments } = elect::<_, Perbill>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( 2, 2, candidates, @@ -401,7 +403,7 @@ fn phragmen_large_scale_test_2() { (50, nom_budget.into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, Perbill>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( 2, 2, candidates, @@ -477,7 +479,7 @@ fn elect_has_no_entry_barrier() { (2, 10), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, Perbill>( + let ElectionResult { winners, assignments: _ } = seq_phragmen::<_, Perbill>( 3, 3, candidates, @@ -504,7 +506,7 @@ fn minimum_to_elect_is_respected() { (2, 10), ]); - let maybe_result = elect::<_, Perbill>( + let maybe_result = seq_phragmen::<_, Perbill>( 10, 10, candidates, @@ -530,7 +532,7 @@ fn self_votes_should_be_kept() { (1, 8), ]); - let result = elect::<_, Perbill>( + let result = seq_phragmen::<_, Perbill>( 2, 2, candidates, @@ -569,7 +571,7 @@ fn self_votes_should_be_kept() { &Support { total: 24u128, voters: vec![(20u64, 20u128), (1u64, 4u128)] }, ); - equalize( + balance_solution( &mut staked_assignments, &mut supports, 0, @@ -587,80 +589,407 @@ fn self_votes_should_be_kept() { } #[test] -fn assignment_convert_works() { - let staked = StakedAssignment { - who: 1 as AccountId, - distribution: vec![ - (20, 100 as ExtendedBalance), - (30, 25), - ], - }; +fn duplicate_target_is_ignored() { + let candidates = vec![1, 2, 3]; + let voters = vec![ + (10, 100, vec![1, 1, 2, 3]), + (20, 100, vec![2, 3]), + (30, 50, vec![1, 1, 2]), + ]; - let assignment = staked.clone().into_assignment(true); - assert_eq!( - assignment, - Assignment { - who: 1, - distribution: vec![ - (20, Perbill::from_percent(80)), - (30, Perbill::from_percent(20)), - ] - } - ); + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( + 2, + 2, + candidates, + voters, + ).unwrap(); + let winners = to_without_backing(winners); + assert_eq!(winners, vec![(2), (3)]); assert_eq!( - assignment.into_staked(125, true), - staked, + assignments + .into_iter() + .map(|x| (x.who, x.distribution.into_iter().map(|(w, _)| w).collect::>())) + .collect::>(), + vec![ + (10, vec![2, 3]), + (20, vec![2, 3]), + (30, vec![2]), + ], ); } #[test] -fn score_comparison_is_lexicographical() { - // only better in the fist parameter, worse in the other two ✅ - assert_eq!( - is_score_better([10, 20, 30], [12, 10, 35]), - true, - ); +fn duplicate_target_is_ignored_when_winner() { + let candidates = vec![1, 2, 3]; + let voters = vec![ + (10, 100, vec![1, 1, 2, 3]), + (20, 100, vec![1, 2]), + ]; - // worse in the first, better in the other two ❌ - assert_eq!( - is_score_better([10, 20, 30], [9, 30, 10]), - false, - ); + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( + 2, + 2, + candidates, + voters, + ).unwrap(); + let winners = to_without_backing(winners); - // equal in the first, the second one dictates. + assert_eq!(winners, vec![1, 2]); assert_eq!( - is_score_better([10, 20, 30], [10, 25, 40]), - true, + assignments + .into_iter() + .map(|x| (x.who, x.distribution.into_iter().map(|(w, _)| w).collect::>())) + .collect::>(), + vec![ + (10, vec![1, 2]), + (20, vec![1, 2]), + ], ); +} - // equal in the first two, the last one dictates. - assert_eq!( - is_score_better([10, 20, 30], [10, 20, 40]), - false, - ); +mod assignment_convert_normalize { + use super::*; + #[test] + fn assignment_convert_works() { + let staked = StakedAssignment { + who: 1 as AccountId, + distribution: vec![ + (20, 100 as ExtendedBalance), + (30, 25), + ], + }; + + let assignment = staked.clone().into_assignment(); + assert_eq!( + assignment, + Assignment { + who: 1, + distribution: vec![ + (20, Perbill::from_percent(80)), + (30, Perbill::from_percent(20)), + ] + } + ); + + assert_eq!( + assignment.into_staked(125), + staked, + ); + } + + #[test] + fn assignment_convert_will_not_normalize() { + assert_eq!( + Assignment { + who: 1, + distribution: vec![ + (2, Perbill::from_percent(33)), + (3, Perbill::from_percent(66)), + ] + }.into_staked(100), + StakedAssignment { + who: 1, + distribution: vec![ + (2, 33), + (3, 66), + // sum is not 100! + ], + }, + ); + + assert_eq!( + StakedAssignment { + who: 1, + distribution: vec![ + (2, 333_333_333_333_333), + (3, 333_333_333_333_333), + (4, 666_666_666_666_333), + ], + }.into_assignment(), + Assignment { + who: 1, + distribution: vec![ + (2, Perbill::from_parts(250000000)), + (3, Perbill::from_parts(250000000)), + (4, Perbill::from_parts(499999999)), + // sum is not 100%! + ] + }, + ) + } + + #[test] + fn assignment_can_normalize() { + let mut a = Assignment { + who: 1, + distribution: vec![ + (2, Perbill::from_parts(330000000)), + (3, Perbill::from_parts(660000000)), + // sum is not 100%! + ] + }; + a.try_normalize().unwrap(); + assert_eq!( + a, + Assignment { + who: 1, + distribution: vec![ + (2, Perbill::from_parts(340000000)), + (3, Perbill::from_parts(660000000)), + ] + }, + ); + } + + #[test] + fn staked_assignment_can_normalize() { + let mut a = StakedAssignment { + who: 1, + distribution: vec![ + (2, 33), + (3, 66), + ] + }; + a.try_normalize(100).unwrap(); + assert_eq!( + a, + StakedAssignment { + who: 1, + distribution: vec![ + (2, 34), + (3, 66), + ] + }, + ); + } } -mod compact { +mod score { + use super::*; + #[test] + fn score_comparison_is_lexicographical_no_epsilon() { + let epsilon = Perbill::zero(); + // only better in the fist parameter, worse in the other two ✅ + assert_eq!( + is_score_better([12, 10, 35], [10, 20, 30], epsilon), + true, + ); + + // worse in the first, better in the other two ❌ + assert_eq!( + is_score_better([9, 30, 10], [10, 20, 30], epsilon), + false, + ); + + // equal in the first, the second one dictates. + assert_eq!( + is_score_better([10, 25, 40], [10, 20, 30], epsilon), + true, + ); + + // equal in the first two, the last one dictates. + assert_eq!( + is_score_better([10, 20, 40], [10, 20, 30], epsilon), + false, + ); + } + + #[test] + fn score_comparison_with_epsilon() { + let epsilon = Perbill::from_percent(1); + + { + // no more than 1 percent (10) better in the first param. + assert_eq!( + is_score_better([1009, 5000, 100000], [1000, 5000, 100000], epsilon), + false, + ); + + // now equal, still not better. + assert_eq!( + is_score_better([1010, 5000, 100000], [1000, 5000, 100000], epsilon), + false, + ); + + // now it is. + assert_eq!( + is_score_better([1011, 5000, 100000], [1000, 5000, 100000], epsilon), + true, + ); + } + + { + // First score score is epsilon better, but first score is no longer `ge`. Then this is + // still not a good solution. + assert_eq!( + is_score_better([999, 6000, 100000], [1000, 5000, 100000], epsilon), + false, + ); + } + + { + // first score is equal or better, but not epsilon. Then second one is the determinant. + assert_eq!( + is_score_better([1005, 5000, 100000], [1000, 5000, 100000], epsilon), + false, + ); + + assert_eq!( + is_score_better([1005, 5050, 100000], [1000, 5000, 100000], epsilon), + false, + ); + + assert_eq!( + is_score_better([1005, 5051, 100000], [1000, 5000, 100000], epsilon), + true, + ); + } + + { + // first score and second are equal or less than epsilon more, third is determinant. + assert_eq!( + is_score_better([1005, 5025, 100000], [1000, 5000, 100000], epsilon), + false, + ); + + assert_eq!( + is_score_better([1005, 5025, 99_000], [1000, 5000, 100000], epsilon), + false, + ); + + assert_eq!( + is_score_better([1005, 5025, 98_999], [1000, 5000, 100000], epsilon), + true, + ); + } + } + + #[test] + fn score_comparison_large_value() { + // some random value taken from eras in kusama. + let initial = [12488167277027543u128, 5559266368032409496, 118749283262079244270992278287436446]; + // this claim is 0.04090% better in the third component. It should be accepted as better if + // epsilon is smaller than 5/10_0000 + let claim = [12488167277027543u128, 5559266368032409496, 118700736389524721358337889258988054]; + + assert_eq!( + is_score_better( + claim.clone(), + initial.clone(), + Perbill::from_rational_approximation(1u32, 10_000), + ), + true, + ); + + assert_eq!( + is_score_better( + claim.clone(), + initial.clone(), + Perbill::from_rational_approximation(2u32, 10_000), + ), + true, + ); + + assert_eq!( + is_score_better( + claim.clone(), + initial.clone(), + Perbill::from_rational_approximation(3u32, 10_000), + ), + true, + ); + + assert_eq!( + is_score_better( + claim.clone(), + initial.clone(), + Perbill::from_rational_approximation(4u32, 10_000), + ), + true, + ); + + assert_eq!( + is_score_better( + claim.clone(), + initial.clone(), + Perbill::from_rational_approximation(5u32, 10_000), + ), + false, + ); + } +} + +mod solution_type { use codec::{Decode, Encode}; - use crate::{generate_compact_solution_type, VoteWeight}; - use super::{AccountId}; - // these need to come from the same dev-dependency `sp-phragmen`, not from the crate. - use sp_phragmen::{Assignment, StakedAssignment, Error as PhragmenError, ExtendedBalance}; - use sp_std::{convert::{TryInto, TryFrom}, fmt::Debug}; + use super::AccountId; + // these need to come from the same dev-dependency `sp-npos-elections`, not from the crate. + use crate::{ + generate_solution_type, Assignment, + Error as PhragmenError, + }; + use sp_std::{convert::TryInto, fmt::Debug}; use sp_arithmetic::Percent; - type Accuracy = Percent; + type TestAccuracy = Percent; - generate_compact_solution_type!(TestCompact, 16); + generate_solution_type!(pub struct TestSolutionCompact::(16)); + + #[allow(dead_code)] + mod __private { + // This is just to make sure that that the compact can be generated in a scope without any + // imports. + use crate::generate_solution_type; + use sp_arithmetic::Percent; + generate_solution_type!( + #[compact] + struct InnerTestSolutionCompact::(12) + ); + + } + + #[test] + fn solution_struct_works_with_and_without_compact() { + // we use u32 size to make sure compact is smaller. + let without_compact = { + generate_solution_type!(pub struct InnerTestSolution::(16)); + let compact = InnerTestSolution { + votes1: vec![(2, 20), (4, 40)], + votes2: vec![ + (1, (10, TestAccuracy::from_percent(80)), 11), + (5, (50, TestAccuracy::from_percent(85)), 51), + ], + ..Default::default() + }; + + compact.encode().len() + }; + + let with_compact = { + generate_solution_type!(#[compact] pub struct InnerTestSolutionCompact::(16)); + let compact = InnerTestSolutionCompact { + votes1: vec![(2, 20), (4, 40)], + votes2: vec![ + (1, (10, TestAccuracy::from_percent(80)), 11), + (5, (50, TestAccuracy::from_percent(85)), 51), + ], + ..Default::default() + }; + + compact.encode().len() + }; + + dbg!(with_compact, without_compact); + assert!(with_compact < without_compact); + } #[test] - fn compact_struct_is_codec() { - let compact = TestCompact::<_, _, _> { - votes1: vec![(2u64, 20), (4, 40)], + fn solution_struct_is_codec() { + let compact = TestSolutionCompact { + votes1: vec![(2, 20), (4, 40)], votes2: vec![ - (1, (10, Accuracy::from_percent(80)), 11), - (5, (50, Accuracy::from_percent(85)), 51), + (1, (10, TestAccuracy::from_percent(80)), 11), + (5, (50, TestAccuracy::from_percent(85)), 51), ], ..Default::default() }; @@ -671,16 +1000,12 @@ mod compact { compact, Decode::decode(&mut &encoded[..]).unwrap(), ); + assert_eq!(compact.len(), 4); + assert_eq!(compact.edge_count(), 2 + 4); } - fn basic_ratio_test_with() where - V: codec::Codec + Copy + Default + PartialEq + Eq + TryInto + TryFrom + From + Debug, - T: codec::Codec + Copy + Default + PartialEq + Eq + TryInto + TryFrom + From + Debug, - >::Error: std::fmt::Debug, - >::Error: std::fmt::Debug, - >::Error: std::fmt::Debug, - >::Error: std::fmt::Debug, - { + #[test] + fn basic_from_and_into_compact_works_assignments() { let voters = vec![ 2 as AccountId, 4, @@ -703,306 +1028,141 @@ mod compact { let assignments = vec![ Assignment { who: 2 as AccountId, - distribution: vec![(20u64, Accuracy::from_percent(100))] + distribution: vec![(20u64, TestAccuracy::from_percent(100))] }, Assignment { who: 4, - distribution: vec![(40, Accuracy::from_percent(100))], + distribution: vec![(40, TestAccuracy::from_percent(100))], }, Assignment { who: 1, distribution: vec![ - (10, Accuracy::from_percent(80)), - (11, Accuracy::from_percent(20)) + (10, TestAccuracy::from_percent(80)), + (11, TestAccuracy::from_percent(20)) ], }, Assignment { who: 5, distribution: vec![ - (50, Accuracy::from_percent(85)), - (51, Accuracy::from_percent(15)), + (50, TestAccuracy::from_percent(85)), + (51, TestAccuracy::from_percent(15)), ] }, Assignment { who: 3, distribution: vec![ - (30, Accuracy::from_percent(50)), - (31, Accuracy::from_percent(25)), - (32, Accuracy::from_percent(25)), + (30, TestAccuracy::from_percent(50)), + (31, TestAccuracy::from_percent(25)), + (32, TestAccuracy::from_percent(25)), ], }, ]; - let voter_index = |a: &AccountId| -> Option { + let voter_index = |a: &AccountId| -> Option { voters.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() }; - let target_index = |a: &AccountId| -> Option { + let target_index = |a: &AccountId| -> Option { targets.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() }; - let compacted = >::from_assignment( + let compacted = TestSolutionCompact::from_assignment( assignments.clone(), voter_index, target_index, ).unwrap(); + // basically number of assignments that it is encoding. + assert_eq!(compacted.len(), assignments.len()); assert_eq!( - compacted, - TestCompact { - votes1: vec![(V::from(0u8), T::from(2u8)), (V::from(1u8), T::from(6u8))], - votes2: vec![ - (V::from(2u8), (T::from(0u8), Accuracy::from_percent(80)), T::from(1u8)), - (V::from(3u8), (T::from(7u8), Accuracy::from_percent(85)), T::from(8u8)), - ], - votes3: vec![ - ( - V::from(4), - [(T::from(3u8), Accuracy::from_percent(50)), (T::from(4u8), Accuracy::from_percent(25))], - T::from(5u8), - ), - ], - ..Default::default() - } + compacted.edge_count(), + assignments.iter().fold(0, |a, b| a + b.distribution.len()), ); - let voter_at = |a: V| -> Option { voters.get(>::try_into(a).unwrap()).cloned() }; - let target_at = |a: T| -> Option { targets.get(>::try_into(a).unwrap()).cloned() }; - - assert_eq!( - compacted.into_assignment(voter_at, target_at).unwrap(), - assignments, - ); - } - - #[test] - fn basic_from_and_into_compact_works_assignments() { - basic_ratio_test_with::(); - basic_ratio_test_with::(); - basic_ratio_test_with::(); - } - - #[test] - fn basic_from_and_into_compact_works_staked_assignments() { - let voters = vec![ - 2 as AccountId, - 4, - 1, - 5, - 3, - ]; - let targets = vec![ - 10 as AccountId, 11, - 20, - 30, 31, 32, - 40, - 50, 51, - ]; - - let assignments = vec![ - StakedAssignment { - who: 2 as AccountId, - distribution: vec![(20, 100 as ExtendedBalance)] - }, - StakedAssignment { - who: 4, - distribution: vec![(40, 100)], - }, - StakedAssignment { - who: 1, - distribution: vec![ - (10, 80), - (11, 20) - ], - }, - StakedAssignment { - who: 5, distribution: - vec![ - (50, 85), - (51, 15), - ] - }, - StakedAssignment { - who: 3, - distribution: vec![ - (30, 50), - (31, 25), - (32, 25), - ], - }, - ]; - - let voter_index = |a: &AccountId| -> Option { - voters.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() - }; - let target_index = |a: &AccountId| -> Option { - targets.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() - }; - - let compacted = >::from_staked( - assignments.clone(), - voter_index, - target_index, - ).unwrap(); - assert_eq!( compacted, - TestCompact { + TestSolutionCompact { votes1: vec![(0, 2), (1, 6)], votes2: vec![ - (2, (0, 80), 1), - (3, (7, 85), 8), + (2, (0, TestAccuracy::from_percent(80)), 1), + (3, (7, TestAccuracy::from_percent(85)), 8), ], votes3: vec![ - (4, [(3, 50), (4, 25)], 5), + ( + 4, + [(3, TestAccuracy::from_percent(50)), (4, TestAccuracy::from_percent(25))], + 5, + ), ], ..Default::default() } ); - let max_of_fn = |_: &AccountId| -> VoteWeight { 100 }; - let voter_at = |a: u16| -> Option { voters.get(a as usize).cloned() }; - let target_at = |a: u16| -> Option { targets.get(a as usize).cloned() }; - - assert_eq!( - compacted.into_staked( - max_of_fn, - voter_at, - target_at, - ).unwrap(), - assignments, - ); - } - - #[test] - fn compact_into_stake_must_report_overflow() { - // The last edge which is computed from the rest should ALWAYS be positive. - // in votes2 - let compact = TestCompact:: { - votes1: Default::default(), - votes2: vec![(0, (1, 10), 2)], - ..Default::default() + let voter_at = |a: u32| -> Option { + voters.get(>::try_into(a).unwrap()).cloned() }; - - let entity_at = |a: u16| -> Option { Some(a as AccountId) }; - let max_of = |_: &AccountId| -> VoteWeight { 5 }; - - assert_eq!( - compact.into_staked(&max_of, &entity_at, &entity_at).unwrap_err(), - PhragmenError::CompactStakeOverflow, - ); - - // in votes3 onwards - let compact = TestCompact:: { - votes1: Default::default(), - votes2: Default::default(), - votes3: vec![(0, [(1, 7), (2, 8)], 3)], - ..Default::default() + let target_at = |a: u8| -> Option { + targets.get(>::try_into(a).unwrap()).cloned() }; assert_eq!( - compact.into_staked(&max_of, &entity_at, &entity_at).unwrap_err(), - PhragmenError::CompactStakeOverflow, - ); - - // Also if equal - let compact = TestCompact:: { - votes1: Default::default(), - votes2: Default::default(), - // 5 is total, we cannot leave none for 30 here. - votes3: vec![(0, [(1, 3), (2, 2)], 3)], - ..Default::default() - }; - - assert_eq!( - compact.into_staked(&max_of, &entity_at, &entity_at).unwrap_err(), - PhragmenError::CompactStakeOverflow, + compacted.into_assignment(voter_at, target_at).unwrap(), + assignments, ); } #[test] fn compact_into_assignment_must_report_overflow() { // in votes2 - let compact = TestCompact:: { + let compact = TestSolutionCompact { votes1: Default::default(), - votes2: vec![(0, (1, Accuracy::from_percent(100)), 2)], + votes2: vec![(0, (1, TestAccuracy::from_percent(100)), 2)], ..Default::default() }; - let entity_at = |a: u16| -> Option { Some(a as AccountId) }; + let voter_at = |a: u32| -> Option { Some(a as AccountId) }; + let target_at = |a: u8| -> Option { Some(a as AccountId) }; + assert_eq!( - compact.into_assignment(&entity_at, &entity_at).unwrap_err(), + compact.into_assignment(&voter_at, &target_at).unwrap_err(), PhragmenError::CompactStakeOverflow, ); // in votes3 onwards - let compact = TestCompact:: { + let compact = TestSolutionCompact { votes1: Default::default(), votes2: Default::default(), - votes3: vec![(0, [(1, Accuracy::from_percent(70)), (2, Accuracy::from_percent(80))], 3)], + votes3: vec![(0, [(1, TestAccuracy::from_percent(70)), (2, TestAccuracy::from_percent(80))], 3)], ..Default::default() }; assert_eq!( - compact.into_assignment(&entity_at, &entity_at).unwrap_err(), + compact.into_assignment(&voter_at, &target_at).unwrap_err(), PhragmenError::CompactStakeOverflow, ); } #[test] fn target_count_overflow_is_detected() { - let assignments = vec![ - StakedAssignment { - who: 1 as AccountId, - distribution: (10..26).map(|i| (i as AccountId, i as ExtendedBalance)).collect::>(), - }, - ]; - - let entity_index = |a: &AccountId| -> Option { Some(*a as u16) }; - - let compacted = >::from_staked( - assignments.clone(), - entity_index, - entity_index, - ); - - assert!(compacted.is_ok()); - - let assignments = vec![ - StakedAssignment { - who: 1 as AccountId, - distribution: (10..27).map(|i| (i as AccountId, i as ExtendedBalance)).collect::>(), - }, - ]; - - let compacted = >::from_staked( - assignments.clone(), - entity_index, - entity_index, - ); - - assert_eq!( - compacted.unwrap_err(), - PhragmenError::CompactTargetOverflow, - ); + let voter_index = |a: &AccountId| -> Option { Some(*a as u32) }; + let target_index = |a: &AccountId| -> Option { Some(*a as u8) }; let assignments = vec![ Assignment { who: 1 as AccountId, - distribution: (10..27).map(|i| (i as AccountId, Percent::from_parts(i as u8))).collect::>(), + distribution: + (10..27) + .map(|i| (i as AccountId, Percent::from_parts(i as u8))) + .collect::>(), }, ]; - let compacted = >::from_assignment( + let compacted = TestSolutionCompact::from_assignment( assignments.clone(), - entity_index, - entity_index, - ); - - assert_eq!( - compacted.unwrap_err(), - PhragmenError::CompactTargetOverflow, + voter_index, + target_index, ); + assert_eq!(compacted.unwrap_err(), PhragmenError::CompactTargetOverflow); } #[test] @@ -1011,24 +1171,24 @@ mod compact { let targets = vec![10 as AccountId, 11]; let assignments = vec![ - StakedAssignment { + Assignment { who: 1 as AccountId, - distribution: vec![(10, 100 as ExtendedBalance), (11, 100)] + distribution: vec![(10, Percent::from_percent(50)), (11, Percent::from_percent(50))], }, - StakedAssignment { + Assignment { who: 2, distribution: vec![], }, ]; - let voter_index = |a: &AccountId| -> Option { + let voter_index = |a: &AccountId| -> Option { voters.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() }; - let target_index = |a: &AccountId| -> Option { + let target_index = |a: &AccountId| -> Option { targets.iter().position(|x| x == a).map(TryInto::try_into).unwrap().ok() }; - let compacted = >::from_staked( + let compacted = TestSolutionCompact::from_assignment( assignments.clone(), voter_index, target_index, @@ -1036,9 +1196,9 @@ mod compact { assert_eq!( compacted, - TestCompact { + TestSolutionCompact { votes1: Default::default(), - votes2: vec![(0, (0, 100), 1)], + votes2: vec![(0, (0, Percent::from_percent(50)), 1)], ..Default::default() } ); diff --git a/primitives/offchain/Cargo.toml b/primitives/offchain/Cargo.toml index ebd0fa12d41dc73c7969d8f398885fddb022a541..46c4f2144f937b67bf27390a4376f772594a1cb8 100644 --- a/primitives/offchain/Cargo.toml +++ b/primitives/offchain/Cargo.toml @@ -1,8 +1,8 @@ [package] description = "Substrate offchain workers primitives" name = "sp-offchain" -version = "2.0.0-dev" -license = "GPL-3.0" +version = "2.0.0-rc6" +license = "Apache-2.0" authors = ["Parity Technologies "] edition = "2018" homepage = "https://substrate.dev" @@ -12,12 +12,12 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } -sp-api = { version = "2.0.0-dev", default-features = false, path = "../api" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../runtime" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../core" } +sp-api = { version = "2.0.0-rc6", default-features = false, path = "../api" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../runtime" } [dev-dependencies] -sp-state-machine = { version = "0.8.0-dev", default-features = false, path = "../state-machine" } +sp-state-machine = { version = "0.8.0-rc6", default-features = false, path = "../state-machine" } [features] default = ["std"] diff --git a/primitives/offchain/README.md b/primitives/offchain/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a8620d3bb9d5b2a6d45e27404891cece853eafc8 --- /dev/null +++ b/primitives/offchain/README.md @@ -0,0 +1,3 @@ +The Offchain Worker runtime api primitives. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/offchain/src/lib.rs b/primitives/offchain/src/lib.rs index 8f043d712a8404ebecfec138210fd72490303fea..fa5ab808df8a107f7033ccb73aa0a92b832e15fb 100644 --- a/primitives/offchain/src/lib.rs +++ b/primitives/offchain/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! The Offchain Worker runtime api primitives. diff --git a/primitives/panic-handler/Cargo.toml b/primitives/panic-handler/Cargo.toml index b5adb9cb5483fd32b13840a23377aa52a1ad7bce..eb0e3bd9a2a85b3f1a85de053948819ea32ee2cc 100644 --- a/primitives/panic-handler/Cargo.toml +++ b/primitives/panic-handler/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-panic-handler" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Custom panic hook with bug report link" diff --git a/primitives/panic-handler/README.md b/primitives/panic-handler/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c08396960f4c953abda24049359cbb6649dbc7d2 --- /dev/null +++ b/primitives/panic-handler/README.md @@ -0,0 +1,10 @@ +Custom panic hook with bug report link + +This crate provides the [`set`] function, which wraps around [`std::panic::set_hook`] and +sets up a panic hook that prints a backtrace and invites the user to open an issue to the +given URL. + +By default, the panic handler aborts the process by calling [`std::process::exit`]. This can +temporarily be disabled by using an [`AbortGuard`]. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/panic-handler/src/lib.rs b/primitives/panic-handler/src/lib.rs index c0f70d9d145c893dc38700e362c224a132cff808..2ac30dd636914464b8c6a3d6d1e2da06e8f7347a 100644 --- a/primitives/panic-handler/src/lib.rs +++ b/primitives/panic-handler/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Custom panic hook with bug report link //! @@ -51,11 +52,12 @@ enum OnPanic { /// /// The `bug_url` parameter is an invitation for users to visit that URL to submit a bug report /// in the case where a panic happens. -pub fn set(bug_url: &'static str, version: &str) { +pub fn set(bug_url: &str, version: &str) { panic::set_hook(Box::new({ let version = version.to_string(); + let bug_url = bug_url.to_string(); move |c| { - panic_hook(c, bug_url, &version) + panic_hook(c, &bug_url, &version) } })); } @@ -129,7 +131,7 @@ impl Drop for AbortGuard { } /// Function being called when a panic happens. -fn panic_hook(info: &PanicInfo, report_url: &'static str, version: &str) { +fn panic_hook(info: &PanicInfo, report_url: &str, version: &str) { let location = info.location(); let file = location.as_ref().map(|l| l.file()).unwrap_or(""); let line = location.as_ref().map(|l| l.line()).unwrap_or(0); diff --git a/primitives/phragmen/compact/src/assignment.rs b/primitives/phragmen/compact/src/assignment.rs deleted file mode 100644 index 4630a494fc77562dfd4aab6bbc8bf83ca75bd961..0000000000000000000000000000000000000000 --- a/primitives/phragmen/compact/src/assignment.rs +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Code generation for the ratio assignment type. - -use crate::field_name_for; -use proc_macro2::{TokenStream as TokenStream2}; -use syn::{GenericArgument}; -use quote::quote; - -fn from_impl(count: usize) -> TokenStream2 { - let from_impl_single = { - let name = field_name_for(1); - quote!(1 => compact.#name.push( - ( - index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, - index_of_target(&distribution[0].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, - ) - ),) - }; - - let from_impl_double = { - let name = field_name_for(2); - quote!(2 => compact.#name.push( - ( - index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, - ( - index_of_target(&distribution[0].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, - distribution[0].1, - ), - index_of_target(&distribution[1].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, - ) - ),) - }; - - let from_impl_rest = (3..=count).map(|c| { - let inner = (0..c-1).map(|i| - quote!((index_of_target(&distribution[#i].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, distribution[#i].1),) - ).collect::(); - - let field_name = field_name_for(c); - let last_index = c - 1; - let last = quote!(index_of_target(&distribution[#last_index].0).ok_or(_phragmen::Error::CompactInvalidIndex)?); - - quote!( - #c => compact.#field_name.push((index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, [#inner], #last)), - ) - }).collect::(); - - quote!( - #from_impl_single - #from_impl_double - #from_impl_rest - ) -} - -fn into_impl(count: usize) -> TokenStream2 { - let into_impl_single = { - let name = field_name_for(1); - quote!( - for (voter_index, target_index) in self.#name { - assignments.push(_phragmen::Assignment { - who: voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, - distribution: vec![ - (target_at(target_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, Accuracy::one()) - ], - }) - } - ) - }; - - let into_impl_double = { - let name = field_name_for(2); - quote!( - for (voter_index, (t1_idx, p1), t2_idx) in self.#name { - if p1 >= Accuracy::one() { - return Err(_phragmen::Error::CompactStakeOverflow); - } - - // defensive only. Since Percent doesn't have `Sub`. - let p2 = _phragmen::sp_arithmetic::traits::Saturating::saturating_sub( - Accuracy::one(), - p1, - ); - - assignments.push( _phragmen::Assignment { - who: voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, - distribution: vec![ - (target_at(t1_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, p1), - (target_at(t2_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, p2), - ] - }); - } - ) - }; - - let into_impl_rest = (3..=count).map(|c| { - let name = field_name_for(c); - quote!( - for (voter_index, inners, t_last_idx) in self.#name { - let mut sum = Accuracy::zero(); - let mut inners_parsed = inners - .iter() - .map(|(ref t_idx, p)| { - sum = _phragmen::sp_arithmetic::traits::Saturating::saturating_add(sum, *p); - let target = target_at(*t_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?; - Ok((target, *p)) - }) - .collect::, _phragmen::Error>>()?; - - if sum >= Accuracy::one() { - return Err(_phragmen::Error::CompactStakeOverflow); - } - - // defensive only. Since Percent doesn't have `Sub`. - let p_last = _phragmen::sp_arithmetic::traits::Saturating::saturating_sub( - Accuracy::one(), - sum, - ); - - inners_parsed.push((target_at(t_last_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, p_last)); - - assignments.push(_phragmen::Assignment { - who: voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, - distribution: inners_parsed, - }); - } - ) - }).collect::(); - - quote!( - #into_impl_single - #into_impl_double - #into_impl_rest - ) -} - -pub(crate) fn assignment( - ident: syn::Ident, - voter_type: GenericArgument, - target_type: GenericArgument, - count: usize, -) -> TokenStream2 { - - let from_impl = from_impl(count); - let into_impl = into_impl(count); - - quote!( - impl< - #voter_type: _phragmen::codec::Codec + Default + Copy, - #target_type: _phragmen::codec::Codec + Default + Copy, - Accuracy: - _phragmen::codec::Codec + Default + Clone + _phragmen::sp_arithmetic::PerThing + - PartialOrd, - > - #ident<#voter_type, #target_type, Accuracy> - { - pub fn from_assignment( - assignments: Vec<_phragmen::Assignment>, - index_of_voter: FV, - index_of_target: FT, - ) -> Result - where - for<'r> FV: Fn(&'r A) -> Option<#voter_type>, - for<'r> FT: Fn(&'r A) -> Option<#target_type>, - A: _phragmen::IdentifierT, - { - let mut compact: #ident< - #voter_type, - #target_type, - Accuracy, - > = Default::default(); - - for _phragmen::Assignment { who, distribution } in assignments { - match distribution.len() { - 0 => continue, - #from_impl - _ => { - return Err(_phragmen::Error::CompactTargetOverflow); - } - } - }; - Ok(compact) - } - - pub fn into_assignment( - self, - voter_at: impl Fn(#voter_type) -> Option, - target_at: impl Fn(#target_type) -> Option, - ) -> Result>, _phragmen::Error> { - let mut assignments: Vec<_phragmen::Assignment> = Default::default(); - #into_impl - Ok(assignments) - } - } - ) -} diff --git a/primitives/phragmen/compact/src/lib.rs b/primitives/phragmen/compact/src/lib.rs deleted file mode 100644 index 9406f944c396ebd170f9e393d7383de878ac69aa..0000000000000000000000000000000000000000 --- a/primitives/phragmen/compact/src/lib.rs +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Proc macro for phragmen compact assignment. - -use proc_macro::TokenStream; -use proc_macro2::{TokenStream as TokenStream2, Span, Ident}; -use proc_macro_crate::crate_name; -use quote::quote; -use syn::{GenericArgument, Type, parse::{Parse, ParseStream, Result}}; - -mod assignment; -mod staked; - -// prefix used for struct fields in compact. -const PREFIX: &'static str = "votes"; - -/// Generates a struct to store the phragmen assignments in a compact way. The struct can only store -/// distributions up to the given input count. The given count must be greater than 2. -/// -/// ```ignore -/// // generate a struct with nominator and edge weight u128, with maximum supported -/// // edge per voter of 16. -/// generate_compact_solution_type(pub TestCompact, 16) -/// ``` -/// -/// This generates: -/// -/// ```ignore -/// pub struct TestCompact { -/// votes1: Vec<(V, T)>, -/// votes2: Vec<(V, (T, W), T)>, -/// votes3: Vec<(V, [(T, W); 2usize], T)>, -/// votes4: Vec<(V, [(T, W); 3usize], T)>, -/// votes5: Vec<(V, [(T, W); 4usize], T)>, -/// votes6: Vec<(V, [(T, W); 5usize], T)>, -/// votes7: Vec<(V, [(T, W); 6usize], T)>, -/// votes8: Vec<(V, [(T, W); 7usize], T)>, -/// votes9: Vec<(V, [(T, W); 8usize], T)>, -/// votes10: Vec<(V, [(T, W); 9usize], T)>, -/// votes11: Vec<(V, [(T, W); 10usize], T)>, -/// votes12: Vec<(V, [(T, W); 11usize], T)>, -/// votes13: Vec<(V, [(T, W); 12usize], T)>, -/// votes14: Vec<(V, [(T, W); 13usize], T)>, -/// votes15: Vec<(V, [(T, W); 14usize], T)>, -/// votes16: Vec<(V, [(T, W); 15usize], T)>, -/// } -/// ``` -/// -/// The generic arguments are: -/// - `V`: identifier/index for voter (nominator) types. -/// - `T` identifier/index for candidate (validator) types. -/// - `W` weight type. -/// -/// Some conversion implementations are provided by default if -/// - `W` is u128, or -/// - `W` is anything that implements `PerThing` (such as `Perbill`) -/// -/// The ideas behind the structure are as follows: -/// -/// - For single distribution, no weight is stored. The weight is known to be 100%. -/// - For all the rest, the weight if the last distribution is omitted. This value can be computed -/// from the rest. -/// -#[proc_macro] -pub fn generate_compact_solution_type(item: TokenStream) -> TokenStream { - let CompactSolutionDef { - vis, - ident, - count, - } = syn::parse_macro_input!(item as CompactSolutionDef); - - let voter_type = GenericArgument::Type(Type::Verbatim(quote!(V))); - let target_type = GenericArgument::Type(Type::Verbatim(quote!(T))); - let weight_type = GenericArgument::Type(Type::Verbatim(quote!(W))); - - let imports = imports().unwrap_or_else(|e| e.to_compile_error()); - - let compact_def = struct_def( - vis, - ident.clone(), - count, - voter_type.clone(), - target_type.clone(), - weight_type, - ).unwrap_or_else(|e| e.to_compile_error()); - - let assignment_impls = assignment::assignment( - ident.clone(), - voter_type.clone(), - target_type.clone(), - count, - ); - - let staked_impls = staked::staked( - ident, - voter_type, - target_type, - count, - ); - - quote!( - #imports - #compact_def - #assignment_impls - #staked_impls - ).into() -} - -fn struct_def( - vis: syn::Visibility, - ident: syn::Ident, - count: usize, - voter_type: GenericArgument, - target_type: GenericArgument, - weight_type: GenericArgument, -) -> Result { - if count <= 2 { - Err(syn::Error::new( - Span::call_site(), - "cannot build compact solution struct with capacity less than 2." - ))? - } - - let singles = { - let name = field_name_for(1); - quote!(#name: Vec<(#voter_type, #target_type)>,) - }; - - let doubles = { - let name = field_name_for(2); - quote!(#name: Vec<(#voter_type, (#target_type, #weight_type), #target_type)>,) - }; - - let rest = (3..=count).map(|c| { - let field_name = field_name_for(c); - let array_len = c - 1; - quote!( - #field_name: Vec<( - #voter_type, - [(#target_type, #weight_type); #array_len], - #target_type - )>, - ) - }).collect::(); - - Ok(quote! ( - /// A struct to encode a Phragmen assignment in a compact way. - #[derive( - Default, - PartialEq, - Eq, - Clone, - Debug, - _phragmen::codec::Encode, - _phragmen::codec::Decode, - )] - #vis struct #ident<#voter_type, #target_type, #weight_type> { - // _marker: sp_std::marker::PhantomData, - #singles - #doubles - #rest - } - - impl<#voter_type, #target_type, #weight_type> _phragmen::VotingLimit - for #ident<#voter_type, #target_type, #weight_type> - { - const LIMIT: usize = #count; - } - )) -} - -fn imports() -> Result { - let sp_phragmen_imports = match crate_name("sp-phragmen") { - Ok(sp_phragmen) => { - let ident = syn::Ident::new(&sp_phragmen, Span::call_site()); - quote!( extern crate #ident as _phragmen; ) - } - Err(e) => return Err(syn::Error::new(Span::call_site(), &e)), - }; - - Ok(quote!( - #sp_phragmen_imports - )) -} - -struct CompactSolutionDef { - vis: syn::Visibility, - ident: syn::Ident, - count: usize, -} - -impl Parse for CompactSolutionDef { - fn parse(input: ParseStream) -> syn::Result { - let vis: syn::Visibility = input.parse()?; - let ident: syn::Ident = input.parse()?; - let _ = ::parse(input)?; - let count_literal: syn::LitInt = input.parse()?; - let count = count_literal.base10_parse::()?; - Ok(Self { vis, ident, count } ) - } -} - -fn field_name_for(n: usize) -> Ident { - Ident::new(&format!("{}{}", PREFIX, n), Span::call_site()) -} diff --git a/primitives/phragmen/compact/src/staked.rs b/primitives/phragmen/compact/src/staked.rs deleted file mode 100644 index 81ccb5c55927c5633a07feccad842c4c3119a4e6..0000000000000000000000000000000000000000 --- a/primitives/phragmen/compact/src/staked.rs +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Code generation for the staked assignment type. - -use crate::field_name_for; -use proc_macro2::{TokenStream as TokenStream2}; -use syn::{GenericArgument}; -use quote::quote; - -fn from_impl(count: usize) -> TokenStream2 { - let from_impl_single = { - let name = field_name_for(1); - quote!(1 => compact.#name.push( - ( - index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, - index_of_target(&distribution[0].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, - ) - ),) - }; - - let from_impl_double = { - let name = field_name_for(2); - quote!(2 => compact.#name.push( - ( - index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, - ( - index_of_target(&distribution[0].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, - distribution[0].1, - ), - index_of_target(&distribution[1].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, - ) - ),) - }; - - let from_impl_rest = (3..=count).map(|c| { - let inner = (0..c-1).map(|i| - quote!((index_of_target(&distribution[#i].0).ok_or(_phragmen::Error::CompactInvalidIndex)?, distribution[#i].1),) - ).collect::(); - - let field_name = field_name_for(c); - let last_index = c - 1; - let last = quote!(index_of_target(&distribution[#last_index].0).ok_or(_phragmen::Error::CompactInvalidIndex)?); - - quote!( - #c => compact.#field_name.push((index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, [#inner], #last)), - ) - }).collect::(); - - quote!( - #from_impl_single - #from_impl_double - #from_impl_rest - ) -} - -fn into_impl(count: usize) -> TokenStream2 { - let into_impl_single = { - let name = field_name_for(1); - quote!( - for (voter_index, target_index) in self.#name { - let who = voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?; - let all_stake: u128 = max_of(&who).into(); - assignments.push(_phragmen::StakedAssignment { - who, - distribution: vec![(target_at(target_index).ok_or(_phragmen::Error::CompactInvalidIndex)?, all_stake)], - }) - } - ) - }; - - let into_impl_double = { - let name = field_name_for(2); - quote!( - for (voter_index, (t1_idx, w1), t2_idx) in self.#name { - let who = voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?; - let all_stake: u128 = max_of(&who).into(); - - if w1 >= all_stake { - return Err(_phragmen::Error::CompactStakeOverflow); - } - - // w2 is ensured to be positive. - let w2 = all_stake - w1; - assignments.push( _phragmen::StakedAssignment { - who, - distribution: vec![ - (target_at(t1_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, w1), - (target_at(t2_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, w2), - ] - }); - } - ) - }; - - let into_impl_rest = (3..=count).map(|c| { - let name = field_name_for(c); - quote!( - for (voter_index, inners, t_last_idx) in self.#name { - let who = voter_at(voter_index).ok_or(_phragmen::Error::CompactInvalidIndex)?; - let mut sum = u128::min_value(); - let all_stake: u128 = max_of(&who).into(); - - let mut inners_parsed = inners - .iter() - .map(|(ref t_idx, w)| { - sum = sum.saturating_add(*w); - let target = target_at(*t_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?; - Ok((target, *w)) - }).collect::, _phragmen::Error>>()?; - - if sum >= all_stake { - return Err(_phragmen::Error::CompactStakeOverflow); - } - // w_last is proved to be positive. - let w_last = all_stake - sum; - - inners_parsed.push((target_at(t_last_idx).ok_or(_phragmen::Error::CompactInvalidIndex)?, w_last)); - - assignments.push(_phragmen::StakedAssignment { - who, - distribution: inners_parsed, - }); - } - ) - }).collect::(); - - quote!( - #into_impl_single - #into_impl_double - #into_impl_rest - ) -} - -pub(crate) fn staked( - ident: syn::Ident, - voter_type: GenericArgument, - target_type: GenericArgument, - count: usize, -) -> TokenStream2 { - - let from_impl = from_impl(count); - let into_impl = into_impl(count); - - quote!( - impl< - #voter_type: _phragmen::codec::Codec + Default + Copy, - #target_type: _phragmen::codec::Codec + Default + Copy, - > - #ident<#voter_type, #target_type, u128> - { - /// Generate self from a vector of `StakedAssignment`. - pub fn from_staked( - assignments: Vec<_phragmen::StakedAssignment>, - index_of_voter: FV, - index_of_target: FT, - ) -> Result - where - for<'r> FV: Fn(&'r A) -> Option<#voter_type>, - for<'r> FT: Fn(&'r A) -> Option<#target_type>, - A: _phragmen::IdentifierT - { - let mut compact: #ident<#voter_type, #target_type, u128> = Default::default(); - for _phragmen::StakedAssignment { who, distribution } in assignments { - match distribution.len() { - 0 => continue, - #from_impl - _ => { - return Err(_phragmen::Error::CompactTargetOverflow); - } - } - }; - Ok(compact) - } - - /// Convert self into `StakedAssignment`. The given function should return the total - /// weight of a voter. It is used to subtract the sum of all the encoded weights to - /// infer the last one. - pub fn into_staked( - self, - max_of: FM, - voter_at: impl Fn(#voter_type) -> Option, - target_at: impl Fn(#target_type) -> Option, - ) - -> Result>, _phragmen::Error> - where - for<'r> FM: Fn(&'r A) -> u64, - A: _phragmen::IdentifierT, - { - let mut assignments: Vec<_phragmen::StakedAssignment> = Default::default(); - #into_impl - Ok(assignments) - } - } - ) -} diff --git a/primitives/phragmen/src/helpers.rs b/primitives/phragmen/src/helpers.rs deleted file mode 100644 index 6b1497e3ad752e5c428ad3b0544913af95cd4d53..0000000000000000000000000000000000000000 --- a/primitives/phragmen/src/helpers.rs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Helper methods for phragmen. - -use crate::{Assignment, ExtendedBalance, VoteWeight, IdentifierT, StakedAssignment, WithApprovalOf}; -use sp_arithmetic::PerThing; -use sp_std::prelude::*; - -/// Converts a vector of ratio assignments into ones with absolute budget value. -pub fn assignment_ratio_to_staked( - ratio: Vec>, - stake_of: FS, -) -> Vec> -where - for<'r> FS: Fn(&'r A) -> VoteWeight, - T: sp_std::ops::Mul, - ExtendedBalance: From<::Inner>, -{ - ratio - .into_iter() - .map(|a| { - let stake = stake_of(&a.who); - a.into_staked(stake.into(), true) - }) - .collect() -} - -/// Converts a vector of staked assignments into ones with ratio values. -pub fn assignment_staked_to_ratio( - staked: Vec>, -) -> Vec> -where - ExtendedBalance: From<::Inner>, -{ - staked.into_iter().map(|a| a.into_assignment(true)).collect() -} - -/// consumes a vector of winners with backing stake to just winners. -pub fn to_without_backing(winners: Vec>) -> Vec { - winners.into_iter().map(|(who, _)| who).collect::>() -} - -#[cfg(test)] -mod tests { - use super::*; - use sp_arithmetic::Perbill; - - #[test] - fn into_staked_works() { - let assignments = vec![ - Assignment { - who: 1u32, - distribution: vec![ - (10u32, Perbill::from_fraction(0.5)), - (20, Perbill::from_fraction(0.5)), - ], - }, - Assignment { - who: 2u32, - distribution: vec![ - (10, Perbill::from_fraction(0.33)), - (20, Perbill::from_fraction(0.67)), - ], - }, - ]; - - let stake_of = |_: &u32| -> VoteWeight { 100 }; - let staked = assignment_ratio_to_staked(assignments, stake_of); - - assert_eq!( - staked, - vec![ - StakedAssignment { - who: 1u32, - distribution: vec![(10u32, 50), (20, 50),] - }, - StakedAssignment { - who: 2u32, - distribution: vec![(10u32, 33), (20, 67),] - } - ] - ); - } -} diff --git a/primitives/rpc/Cargo.toml b/primitives/rpc/Cargo.toml index 740b429c0c8fb6a30b845da7ae4a7321af8dfe89..a524ccfe78597297a884f8f93cfe2bb543c01de1 100644 --- a/primitives/rpc/Cargo.toml +++ b/primitives/rpc/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-rpc" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate RPC primitives and utilities." @@ -13,7 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", features = ["derive"] } -sp-core = { version = "2.0.0-dev", path = "../core" } +sp-core = { version = "2.0.0-rc6", path = "../core" } [dev-dependencies] serde_json = "1.0.41" diff --git a/primitives/rpc/README.md b/primitives/rpc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8a9c17edd4755be7c9b040bde1019ea85fabb1be --- /dev/null +++ b/primitives/rpc/README.md @@ -0,0 +1,3 @@ +Substrate RPC primitives and utilities. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/rpc/src/lib.rs b/primitives/rpc/src/lib.rs index 7c22daf5cd94fce09ba1d967de8b99469299d2cf..c479f0df8b60e9acb8755526d6e7a01737920eff 100644 --- a/primitives/rpc/src/lib.rs +++ b/primitives/rpc/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Substrate RPC primitives and utilities. diff --git a/primitives/rpc/src/list.rs b/primitives/rpc/src/list.rs index 469eae3d1479aab9412addd006badf70eee44907..a80d5a22272c84e4b220a1110138a7405295bc7a 100644 --- a/primitives/rpc/src/list.rs +++ b/primitives/rpc/src/list.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! RPC a lenient list or value type. diff --git a/primitives/rpc/src/number.rs b/primitives/rpc/src/number.rs index 1d41dd234f7043c80ae2c257e563c41586c0df51..3d7e74753526c9a756cdd1a9b9f4d9f0d78a1b6d 100644 --- a/primitives/rpc/src/number.rs +++ b/primitives/rpc/src/number.rs @@ -1,78 +1,93 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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. +// 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. -// You should have received a copy of the GNU General Public License -// along with Substrate. If not, see . +//! A number type that can be serialized both as a number or a string that encodes a number in a +//! string. -//! Chain RPC Block number type. - -use serde::{Serialize, Deserialize}; use std::{convert::TryFrom, fmt::Debug}; +use serde::{Serialize, Deserialize}; use sp_core::U256; -/// RPC Block number type +/// A number type that can be serialized both as a number or a string that encodes a number in a +/// string. +/// +/// We allow two representations of the block number as input. Either we deserialize to the type +/// that is specified in the block type or we attempt to parse given hex value. /// -/// We allow two representations of the block number as input. -/// Either we deserialize to the type that is specified in the block type -/// or we attempt to parse given hex value. -/// We do that for consistency with the returned type, default generic header -/// serializes block number as hex to avoid overflows in JavaScript. -#[derive(Serialize, Deserialize, Debug, PartialEq)] +/// The primary motivation for having this type is to avoid overflows when using big integers in +/// JavaScript (which we consider as an important RPC API consumer). +#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)] #[serde(untagged)] -pub enum NumberOrHex { - /// The original header number type of block. - Number(Number), - /// Hex representation of the block number. +pub enum NumberOrHex { + /// The number represented directly. + Number(u64), + /// Hex representation of the number. Hex(U256), } -impl + From + Debug + PartialOrd> NumberOrHex { - /// Attempts to convert into concrete block number. - /// - /// Fails in case hex number is too big. - pub fn to_number(self) -> Result { - let num = match self { - NumberOrHex::Number(n) => n, - NumberOrHex::Hex(h) => { - let l = h.low_u64(); - if U256::from(l) != h { - return Err(format!("`{}` does not fit into u64 type; unsupported for now.", h)) - } else { - Number::try_from(l) - .map_err(|_| format!("`{}` does not fit into block number type.", h))? - } - }, - }; - // FIXME <2329>: Database seems to limit the block number to u32 for no reason - if num > Number::from(u32::max_value()) { - return Err(format!("`{:?}` > u32::max_value(), the max block number is u32.", num)) +impl NumberOrHex { + /// Converts this number into an U256. + pub fn into_u256(self) -> U256 { + match self { + NumberOrHex::Number(n) => n.into(), + NumberOrHex::Hex(h) => h, } - Ok(num) } } -impl From for NumberOrHex { +impl From for NumberOrHex { fn from(n: u64) -> Self { NumberOrHex::Number(n) } } -impl From for NumberOrHex { +impl From for NumberOrHex { fn from(n: U256) -> Self { NumberOrHex::Hex(n) } } +/// An error type that signals an out-of-range conversion attempt. +pub struct TryFromIntError(pub(crate) ()); + +impl TryFrom for u32 { + type Error = TryFromIntError; + fn try_from(num_or_hex: NumberOrHex) -> Result { + let num_or_hex = num_or_hex.into_u256(); + if num_or_hex > U256::from(u32::max_value()) { + return Err(TryFromIntError(())); + } else { + Ok(num_or_hex.as_u32()) + } + } +} + +impl TryFrom for u64 { + type Error = TryFromIntError; + fn try_from(num_or_hex: NumberOrHex) -> Result { + let num_or_hex = num_or_hex.into_u256(); + if num_or_hex > U256::from(u64::max_value()) { + return Err(TryFromIntError(())); + } else { + Ok(num_or_hex.as_u64()) + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -80,10 +95,11 @@ mod tests { #[test] fn should_serialize_and_deserialize() { - assert_deser(r#""0x1234""#, NumberOrHex::::Hex(0x1234.into())); - assert_deser(r#""0x0""#, NumberOrHex::::Hex(0.into())); - assert_deser(r#"5"#, NumberOrHex::Number(5_u64)); - assert_deser(r#"10000"#, NumberOrHex::Number(10000_u32)); - assert_deser(r#"0"#, NumberOrHex::Number(0_u16)); + assert_deser(r#""0x1234""#, NumberOrHex::Hex(0x1234.into())); + assert_deser(r#""0x0""#, NumberOrHex::Hex(0.into())); + assert_deser(r#"5"#, NumberOrHex::Number(5)); + assert_deser(r#"10000"#, NumberOrHex::Number(10000)); + assert_deser(r#"0"#, NumberOrHex::Number(0)); + assert_deser(r#"1000000000000"#, NumberOrHex::Number(1000000000000)); } } diff --git a/primitives/runtime-interface/Cargo.toml b/primitives/runtime-interface/Cargo.toml index 1d0ae8f95120d1d6157ebf1c3a553a1eefe75b60..466e5eeccf5ebe080fa5c09dc4c2fad1a1e2c150 100644 --- a/primitives/runtime-interface/Cargo.toml +++ b/primitives/runtime-interface/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-runtime-interface" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate runtime interface" @@ -13,20 +13,21 @@ documentation = "https://docs.rs/sp-runtime-interface/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-wasm-interface = { version = "2.0.0-dev", path = "../wasm-interface", default-features = false } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -sp-tracing = { version = "2.0.0-dev", default-features = false, path = "../tracing" } -sp-runtime-interface-proc-macro = { version = "2.0.0-dev", path = "proc-macro" } -sp-externalities = { version = "0.8.0-dev", optional = true, path = "../externalities" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } +sp-wasm-interface = { version = "2.0.0-rc6", path = "../wasm-interface", default-features = false } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +sp-tracing = { version = "2.0.0-rc6", default-features = false, path = "../tracing" } +sp-runtime-interface-proc-macro = { version = "2.0.0-rc6", path = "proc-macro" } +sp-externalities = { version = "0.8.0-rc6", optional = true, path = "../externalities" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false } static_assertions = "1.0.0" primitive-types = { version = "0.7.0", default-features = false } +sp-storage = { version = "2.0.0-rc6", default-features = false, path = "../storage" } [dev-dependencies] -sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "test-wasm" } -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } -sp-core = { version = "2.0.0-dev", path = "../core" } -sp-io = { version = "2.0.0-dev", path = "../io" } +sp-runtime-interface-test-wasm = { version = "2.0.0-rc6", path = "test-wasm" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } +sp-core = { version = "2.0.0-rc6", path = "../core" } +sp-io = { version = "2.0.0-rc6", path = "../io" } rustversion = "1.0.0" trybuild = "1.0.23" diff --git a/primitives/runtime-interface/README.md b/primitives/runtime-interface/README.md new file mode 100644 index 0000000000000000000000000000000000000000..666bfe4d5a86117a2719f2225c134d1f47b9c844 --- /dev/null +++ b/primitives/runtime-interface/README.md @@ -0,0 +1,88 @@ +Substrate runtime interface + +This crate provides types, traits and macros around runtime interfaces. A runtime interface is +a fixed interface between a Substrate runtime and a Substrate node. For a native runtime the +interface maps to a direct function call of the implementation. For a wasm runtime the interface +maps to an external function call. These external functions are exported by the wasm executor +and they map to the same implementation as the native calls. + +# Using a type in a runtime interface + +Any type that should be used in a runtime interface as argument or return value needs to +implement [`RIType`]. The associated type [`FFIType`](RIType::FFIType) is the type that is used +in the FFI function to represent the actual type. For example `[T]` is represented by an `u64`. +The slice pointer and the length will be mapped to an `u64` value. For more information see +this [table](#ffi-type-and-conversion). The FFI function definition is used when calling from +the wasm runtime into the node. + +Traits are used to convert from a type to the corresponding [`RIType::FFIType`]. +Depending on where and how a type should be used in a function signature, a combination of the +following traits need to be implemented: + +1. Pass as function argument: [`wasm::IntoFFIValue`] and [`host::FromFFIValue`] +2. As function return value: [`wasm::FromFFIValue`] and [`host::IntoFFIValue`] +3. Pass as mutable function argument: [`host::IntoPreallocatedFFIValue`] + +The traits are implemented for most of the common types like `[T]`, `Vec`, arrays and +primitive types. + +For custom types, we provide the [`PassBy`](pass_by::PassBy) trait and strategies that define +how a type is passed between the wasm runtime and the node. Each strategy also provides a derive +macro to simplify the implementation. + +# Performance + +To not waste any more performance when calling into the node, not all types are SCALE encoded +when being passed as arguments between the wasm runtime and the node. For most types that +are raw bytes like `Vec`, `[u8]` or `[u8; N]` we pass them directly, without SCALE encoding +them in front of. The implementation of [`RIType`] each type provides more information on how +the data is passed. + +# Declaring a runtime interface + +Declaring a runtime interface is similar to declaring a trait in Rust: + +```rust +#[sp_runtime_interface::runtime_interface] +trait RuntimeInterface { + fn some_function(value: &[u8]) -> bool { + value.iter().all(|v| *v > 125) + } +} +``` + +For more information on declaring a runtime interface, see +[`#[runtime_interface]`](attr.runtime_interface.html). + +# FFI type and conversion + +The following table documents how values of types are passed between the wasm and +the host side and how they are converted into the corresponding type. + +| Type | FFI type | Conversion | +|----|----|----| +| `u8` | `u8` | `Identity` | +| `u16` | `u16` | `Identity` | +| `u32` | `u32` | `Identity` | +| `u64` | `u64` | `Identity` | +| `i128` | `u32` | `v.as_ptr()` (pointer to a 16 byte array) | +| `i8` | `i8` | `Identity` | +| `i16` | `i16` | `Identity` | +| `i32` | `i32` | `Identity` | +| `i64` | `i64` | `Identity` | +| `u128` | `u32` | `v.as_ptr()` (pointer to a 16 byte array) | +| `bool` | `u8` | `if v { 1 } else { 0 }` | +| `&str` | `u64` | v.len() 32bit << 32 | v.as_ptr() 32bit | +| `&[u8]` | `u64` | v.len() 32bit << 32 | v.as_ptr() 32bit | +| `Vec` | `u64` | v.len() 32bit << 32 | v.as_ptr() 32bit | +| `Vec where T: Encode` | `u64` | `let e = v.encode();`

e.len() 32bit << 32 | e.as_ptr() 32bit | +| `&[T] where T: Encode` | `u64` | `let e = v.encode();`

e.len() 32bit << 32 | e.as_ptr() 32bit | +| `[u8; N]` | `u32` | `v.as_ptr()` | +| `*const T` | `u32` | `Identity` | +| `Option` | `u64` | `let e = v.encode();`

e.len() 32bit << 32 | e.as_ptr() 32bit | +| [`T where T: PassBy`](pass_by::Inner) | Depends on inner | Depends on inner | +| [`T where T: PassBy`](pass_by::Codec) | `u64`| v.len() 32bit << 32 | v.as_ptr() 32bit | + +`Identity` means that the value is converted directly into the corresponding FFI type. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/runtime-interface/proc-macro/Cargo.toml b/primitives/runtime-interface/proc-macro/Cargo.toml index 28fe00cc390dde62b1cef847e9019ec6917a4479..006e8ec6c46949b5f51639b813c721639b73c32b 100644 --- a/primitives/runtime-interface/proc-macro/Cargo.toml +++ b/primitives/runtime-interface/proc-macro/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-runtime-interface-proc-macro" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "This crate provides procedural macros for usage within the context of the Substrate runtime interface." diff --git a/primitives/runtime-interface/proc-macro/src/lib.rs b/primitives/runtime-interface/proc-macro/src/lib.rs index 2ed8b1a2281b727ca7e9333272111d81dfb8591f..2f5b9de1c14e7da9dd07113cfe71facb6d97f776 100644 --- a/primitives/runtime-interface/proc-macro/src/lib.rs +++ b/primitives/runtime-interface/proc-macro/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! This crate provides procedural macros for usage within the context of the Substrate runtime //! interface. diff --git a/primitives/runtime-interface/proc-macro/src/pass_by/codec.rs b/primitives/runtime-interface/proc-macro/src/pass_by/codec.rs index 5e30870a82d2e7831a43a454451fbe68e5926dc4..5e51440938456b41628ca89a6736970e6e51b65d 100644 --- a/primitives/runtime-interface/proc-macro/src/pass_by/codec.rs +++ b/primitives/runtime-interface/proc-macro/src/pass_by/codec.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Derive macro implementation of `PassBy` with the associated type set to `Codec`. //! diff --git a/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs b/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs index 5d5b3ae43bdf5f0014c4355914b544c7d3529727..35ed9c0cb802f6ce105c8f18caf23957c4e9d3cb 100644 --- a/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs +++ b/primitives/runtime-interface/proc-macro/src/pass_by/enum_.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Derive macro implementation of `PassBy` with the associated type set to `Enum`. //! diff --git a/primitives/runtime-interface/proc-macro/src/pass_by/inner.rs b/primitives/runtime-interface/proc-macro/src/pass_by/inner.rs index 2e1caaa96c61fa4c2f501a7c8efcc9fe924e877e..cf3bb965d0743b04be7367416b43773fc0c2beee 100644 --- a/primitives/runtime-interface/proc-macro/src/pass_by/inner.rs +++ b/primitives/runtime-interface/proc-macro/src/pass_by/inner.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Derive macro implementation of `PassBy` with the associated type set to `Inner` and of the //! helper trait `PassByInner`. diff --git a/primitives/runtime-interface/proc-macro/src/pass_by/mod.rs b/primitives/runtime-interface/proc-macro/src/pass_by/mod.rs index 1466af598ea7cafac655f0efd0034b1d9e7b017a..ff5ea4849af77cb650d5f2ec0535441a7ead395a 100644 --- a/primitives/runtime-interface/proc-macro/src/pass_by/mod.rs +++ b/primitives/runtime-interface/proc-macro/src/pass_by/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! All the `PassBy*` derive implementations. diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs index 8e83556f045085a887cbc4a68838a8988f23045f..6760e9656113a9e8b3cfd0e7246a514ce915a477 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/bare_function_interface.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Generates the bare function interface for a given trait definition. //! diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs index 46de98c3c3f706ea30f3ca4f95ed5f7ab53d9f32..721eed649c25d5d0244615194f185b672c2bd1e3 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Generates the extern host functions and the implementation for these host functions. //! diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/mod.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/mod.rs index 1c88198d6ea44fa04a5bc11878f8fa8d0b075833..c9b6edf68fd5a48ec9f56200b3b2154c267baebe 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/mod.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. use crate::utils::generate_runtime_interface_include; diff --git a/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs b/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs index 542c4ca4b8c37b3519a4bb103897c80d83145b4d..70015d02426d4de85be697f303873ed756dbb246 100644 --- a/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs +++ b/primitives/runtime-interface/proc-macro/src/runtime_interface/trait_decl_impl.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Checks the trait declaration, makes the trait declaration module local, removes all method //! default implementations and implements the trait for `&mut dyn Externalities`. diff --git a/primitives/runtime-interface/src/host.rs b/primitives/runtime-interface/src/host.rs index cf03e6623af591ac39966e0808913223c42dd7bd..4a01291e68455dc74a16040c31992dd818d64764 100644 --- a/primitives/runtime-interface/src/host.rs +++ b/primitives/runtime-interface/src/host.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Traits required by the runtime interface from the host side. diff --git a/primitives/runtime-interface/src/impls.rs b/primitives/runtime-interface/src/impls.rs index 084b5e11eb3b128c61aae7eefe7bc9baabe71413..da57cf086beef3497fac5e8104269e4c5e49d248 100644 --- a/primitives/runtime-interface/src/impls.rs +++ b/primitives/runtime-interface/src/impls.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Provides implementations for the runtime interface traits. @@ -364,6 +365,10 @@ impl PassBy for Option { type PassBy = Codec; } +impl PassBy for (u32, u32, u32, u32) { + type PassBy = Codec; +} + /// Implement `PassBy` with `Inner` for the given fixed sized hash types. macro_rules! for_primitive_types { { $( $hash:ident $n:expr ),* $(,)? } => { @@ -532,3 +537,7 @@ impl PassBy for sp_wasm_interface::ValueType { impl PassBy for sp_wasm_interface::Value { type PassBy = Codec; } + +impl PassBy for sp_storage::TrackedStorageKey { + type PassBy = Codec; +} diff --git a/primitives/runtime-interface/src/lib.rs b/primitives/runtime-interface/src/lib.rs index 4f748825e5bc1d889bf2eaa024516d0ce722a632..562f94b278efcc60fd21b754dfcf4e1e65f88ab3 100644 --- a/primitives/runtime-interface/src/lib.rs +++ b/primitives/runtime-interface/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Substrate runtime interface //! diff --git a/primitives/runtime-interface/src/pass_by.rs b/primitives/runtime-interface/src/pass_by.rs index d6767b5ebbe93dfb131c13564b4f900d6bdca0bd..5ccb3a5e96ee1168ea2cdb73a2d92b6bc3bb376a 100644 --- a/primitives/runtime-interface/src/pass_by.rs +++ b/primitives/runtime-interface/src/pass_by.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Provides the [`PassBy`](PassBy) trait to simplify the implementation of the //! runtime interface traits for custom types. diff --git a/primitives/runtime-interface/src/util.rs b/primitives/runtime-interface/src/util.rs index fa7016a2b01a6632632e7b11ea618763e04b0381..604e37e8be3976c369bae2f82173f3fb484f914c 100644 --- a/primitives/runtime-interface/src/util.rs +++ b/primitives/runtime-interface/src/util.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Various utilities that help interfacing with wasm runtime code. diff --git a/primitives/runtime-interface/src/wasm.rs b/primitives/runtime-interface/src/wasm.rs index a0801c2bfb5a9aca7c937ef276306428f44630e0..5511f60e30d214e9473088ce58c4573dc83264f9 100644 --- a/primitives/runtime-interface/src/wasm.rs +++ b/primitives/runtime-interface/src/wasm.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Traits required by the runtime interface from the wasm side. diff --git a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml index f992cad69b0f8df53a9cace9db3be21044637907..ff86713c5436271809fee48e463bfa9db70cce7c 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml +++ b/primitives/runtime-interface/test-wasm-deprecated/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-runtime-interface-test-wasm-deprecated" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false @@ -13,10 +13,10 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-runtime-interface = { version = "2.0.0-dev", default-features = false, path = "../" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../io" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../core" } +sp-runtime-interface = { version = "2.0.0-rc6", default-features = false, path = "../" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../core" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/primitives/runtime-interface/test-wasm-deprecated/build.rs b/primitives/runtime-interface/test-wasm-deprecated/build.rs index 647b4768141d2203155bf5325f9ff87f7d9c2446..a2f09a460e69da62a7ebf410cef5c6420cb09e3d 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/build.rs +++ b/primitives/runtime-interface/test-wasm-deprecated/build.rs @@ -1,25 +1,26 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use wasm_builder_runner::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("1.0.9", "../../../utils/wasm-builder") + .with_wasm_builder_from_crates_or_path("2.0.0", "../../../utils/wasm-builder") .export_heap_base() .import_memory() .build() diff --git a/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs b/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs index 29d28c75faafb9b4864479568c819e9bc3178477..174cdb8cdf85a394073726fa3e71196a93c37702 100644 --- a/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs +++ b/primitives/runtime-interface/test-wasm-deprecated/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for the runtime interface traits and proc macros. @@ -25,8 +26,16 @@ use sp_runtime_interface::runtime_interface; #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +#[cfg(feature = "std")] +/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. +pub fn wasm_binary_unwrap() -> &'static [u8] { + WASM_BINARY.expect("Development wasm binary is not available. Testing is only \ + supported with the flag disabled.") +} + /// This function is not used, but we require it for the compiler to include `sp-io`. /// `sp-io` is required for its panic and oom handler. +#[cfg(not(feature = "std"))] #[no_mangle] pub fn import_sp_io() { sp_io::misc::print_utf8(&[]); @@ -49,4 +58,4 @@ wasm_export_functions! { assert!(!test_api::test_versionning(142)); assert!(!test_api::test_versionning(0)); } -} \ No newline at end of file +} diff --git a/primitives/runtime-interface/test-wasm/Cargo.toml b/primitives/runtime-interface/test-wasm/Cargo.toml index f9e64a5027a68a7befd47b4cd58523411187266f..bfe2016ea5189f4d40987af3f865b0033c421c64 100644 --- a/primitives/runtime-interface/test-wasm/Cargo.toml +++ b/primitives/runtime-interface/test-wasm/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sp-runtime-interface-test-wasm" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" build = "build.rs" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" publish = false @@ -13,10 +13,10 @@ publish = false targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-runtime-interface = { version = "2.0.0-dev", default-features = false, path = "../" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../io" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../core" } +sp-runtime-interface = { version = "2.0.0-rc6", default-features = false, path = "../" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../io" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../core" } [build-dependencies] wasm-builder-runner = { version = "1.0.5", package = "substrate-wasm-builder-runner", path = "../../../utils/wasm-builder-runner" } diff --git a/primitives/runtime-interface/test-wasm/build.rs b/primitives/runtime-interface/test-wasm/build.rs index 647b4768141d2203155bf5325f9ff87f7d9c2446..a2f09a460e69da62a7ebf410cef5c6420cb09e3d 100644 --- a/primitives/runtime-interface/test-wasm/build.rs +++ b/primitives/runtime-interface/test-wasm/build.rs @@ -1,25 +1,26 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use wasm_builder_runner::WasmBuilder; fn main() { WasmBuilder::new() .with_current_project() - .with_wasm_builder_from_crates_or_path("1.0.9", "../../../utils/wasm-builder") + .with_wasm_builder_from_crates_or_path("2.0.0", "../../../utils/wasm-builder") .export_heap_base() .import_memory() .build() diff --git a/primitives/runtime-interface/test-wasm/src/lib.rs b/primitives/runtime-interface/test-wasm/src/lib.rs index 700c77854a8b3e003c56c1b25d2c0ba904550fd1..28895df2214d17a63b6310579eed4adf5f843484 100644 --- a/primitives/runtime-interface/test-wasm/src/lib.rs +++ b/primitives/runtime-interface/test-wasm/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for the runtime interface traits and proc macros. @@ -29,6 +30,13 @@ use sp_core::{sr25519::Public, wasm_export_functions}; #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +#[cfg(feature = "std")] +/// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics. +pub fn wasm_binary_unwrap() -> &'static [u8] { + WASM_BINARY.expect("Development wasm binary is not available. Testing is only \ + supported with the flag disabled.") +} + /// Used in the `test_array_as_mutable_reference` test. const TEST_ARRAY: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; diff --git a/primitives/runtime-interface/test/Cargo.toml b/primitives/runtime-interface/test/Cargo.toml index 03f0122b2200b2e8684d06599b60a1a9a599320f..39a48d10b141e16f3bf27131d099cf6a010e1a94 100644 --- a/primitives/runtime-interface/test/Cargo.toml +++ b/primitives/runtime-interface/test/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-runtime-interface-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,12 +12,12 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-runtime-interface = { version = "2.0.0-dev", path = "../" } -sc-executor = { version = "0.8.0-dev", path = "../../../client/executor" } -sp-runtime-interface-test-wasm = { version = "2.0.0-dev", path = "../test-wasm" } -sp-runtime-interface-test-wasm-deprecated = { version = "2.0.0-dev", path = "../test-wasm-deprecated" } -sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } -sp-runtime = { version = "2.0.0-dev", path = "../../runtime" } -sp-core = { version = "2.0.0-dev", path = "../../core" } -sp-io = { version = "2.0.0-dev", path = "../../io" } -tracing = "0.1.13" +sp-runtime-interface = { version = "2.0.0-rc6", path = "../" } +sc-executor = { version = "0.8.0-rc6", path = "../../../client/executor" } +sp-runtime-interface-test-wasm = { version = "2.0.0-rc6", path = "../test-wasm" } +sp-runtime-interface-test-wasm-deprecated = { version = "2.0.0-rc6", path = "../test-wasm-deprecated" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../../primitives/state-machine" } +sp-runtime = { version = "2.0.0-rc6", path = "../../runtime" } +sp-core = { version = "2.0.0-rc6", path = "../../core" } +sp-io = { version = "2.0.0-rc6", path = "../../io" } +tracing = "0.1.18" diff --git a/primitives/runtime-interface/test/src/lib.rs b/primitives/runtime-interface/test/src/lib.rs index 57be4d03b1417bdedbc1a79fade0a0b9e3547cca..c213c977829e6f57b4a4cafdab21bca13052b4d9 100644 --- a/primitives/runtime-interface/test/src/lib.rs +++ b/primitives/runtime-interface/test/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Integration tests for runtime interface primitives #![cfg(test)] @@ -21,8 +22,8 @@ use sp_runtime_interface::*; -use sp_runtime_interface_test_wasm::{WASM_BINARY, test_api::HostFunctions}; -use sp_runtime_interface_test_wasm_deprecated::WASM_BINARY as WASM_BINARY_DEPRECATED; +use sp_runtime_interface_test_wasm::{wasm_binary_unwrap, test_api::HostFunctions}; +use sp_runtime_interface_test_wasm_deprecated::wasm_binary_unwrap as wasm_binary_deprecated_unwrap; use sp_wasm_interface::HostFunctions as HostFunctionsT; use sc_executor::CallInWasm; @@ -54,7 +55,6 @@ fn call_wasm_method_with_result( &mut ext_ext, sp_core::traits::MissingHostFunctions::Disallow, ).map_err(|e| format!("Failed to execute `{}`: {}", method, e))?; - Ok(ext) } @@ -64,17 +64,17 @@ fn call_wasm_method(binary: &[u8], method: &str) -> TestExte #[test] fn test_return_data() { - call_wasm_method::(&WASM_BINARY[..], "test_return_data"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_return_data"); } #[test] fn test_return_option_data() { - call_wasm_method::(&WASM_BINARY[..], "test_return_option_data"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_return_option_data"); } #[test] fn test_set_storage() { - let mut ext = call_wasm_method::(&WASM_BINARY[..], "test_set_storage"); + let mut ext = call_wasm_method::(&wasm_binary_unwrap()[..], "test_set_storage"); let expected = "world"; assert_eq!(expected.as_bytes(), &ext.ext().storage("hello".as_bytes()).unwrap()[..]); @@ -82,27 +82,27 @@ fn test_set_storage() { #[test] fn test_return_value_into_mutable_reference() { - call_wasm_method::(&WASM_BINARY[..], "test_return_value_into_mutable_reference"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_return_value_into_mutable_reference"); } #[test] fn test_get_and_return_array() { - call_wasm_method::(&WASM_BINARY[..], "test_get_and_return_array"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_get_and_return_array"); } #[test] fn test_array_as_mutable_reference() { - call_wasm_method::(&WASM_BINARY[..], "test_array_as_mutable_reference"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_array_as_mutable_reference"); } #[test] fn test_return_input_public_key() { - call_wasm_method::(&WASM_BINARY[..], "test_return_input_public_key"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_return_input_public_key"); } #[test] fn host_function_not_found() { - let err = call_wasm_method_with_result::<()>(&WASM_BINARY[..], "test_return_data").unwrap_err(); + let err = call_wasm_method_with_result::<()>(&wasm_binary_unwrap()[..], "test_return_data").unwrap_err(); assert!(err.contains("Instantiation: Export ")); assert!(err.contains(" not found")); @@ -111,46 +111,46 @@ fn host_function_not_found() { #[test] #[should_panic(expected = "Invalid utf8 data provided")] fn test_invalid_utf8_data_should_return_an_error() { - call_wasm_method::(&WASM_BINARY[..], "test_invalid_utf8_data_should_return_an_error"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_invalid_utf8_data_should_return_an_error"); } #[test] fn test_overwrite_native_function_implementation() { - call_wasm_method::(&WASM_BINARY[..], "test_overwrite_native_function_implementation"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_overwrite_native_function_implementation"); } #[test] fn test_u128_i128_as_parameter_and_return_value() { - call_wasm_method::(&WASM_BINARY[..], "test_u128_i128_as_parameter_and_return_value"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_u128_i128_as_parameter_and_return_value"); } #[test] fn test_vec_return_value_memory_is_freed() { - call_wasm_method::(&WASM_BINARY[..], "test_vec_return_value_memory_is_freed"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_vec_return_value_memory_is_freed"); } #[test] fn test_encoded_return_value_memory_is_freed() { - call_wasm_method::(&WASM_BINARY[..], "test_encoded_return_value_memory_is_freed"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_encoded_return_value_memory_is_freed"); } #[test] fn test_array_return_value_memory_is_freed() { - call_wasm_method::(&WASM_BINARY[..], "test_array_return_value_memory_is_freed"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_array_return_value_memory_is_freed"); } #[test] fn test_versionining_with_new_host_works() { // We call to the new wasm binary with new host function. call_wasm_method::( - &WASM_BINARY[..], + &wasm_binary_unwrap()[..], "test_versionning_works", ); // we call to the old wasm binary with a new host functions // old versions of host functions should be called and test should be ok! call_wasm_method::( - &WASM_BINARY_DEPRECATED[..], + &wasm_binary_deprecated_unwrap()[..], "test_versionning_works", ); } @@ -192,7 +192,7 @@ fn test_tracing() { let _guard = tracing::subscriber::set_default(subscriber.clone()); // Call some method to generate a trace - call_wasm_method::(&WASM_BINARY[..], "test_return_data"); + call_wasm_method::(&wasm_binary_unwrap()[..], "test_return_data"); let inner = subscriber.0.lock().unwrap(); assert!(inner.spans.contains("return_input_version_1")); diff --git a/primitives/runtime-interface/tests/ui.rs b/primitives/runtime-interface/tests/ui.rs index 910771f9389691d61b1c84069fdf6090e242f80b..2f7fd6d06bcd34c3724d6fa39422d4f7890392cc 100644 --- a/primitives/runtime-interface/tests/ui.rs +++ b/primitives/runtime-interface/tests/ui.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. use std::env; diff --git a/primitives/runtime/Cargo.toml b/primitives/runtime/Cargo.toml index dcb0e2260090ca0a812d8e11bab5a707666c974c..f47b3605205ffd4fb8ce333ead2ef1a0ce4ce4f7 100644 --- a/primitives/runtime/Cargo.toml +++ b/primitives/runtime/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sp-runtime" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Runtime Modules shared primitive types." @@ -15,24 +15,25 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true, features = ["derive"] } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../core" } -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../application-crypto" } -sp-arithmetic = { version = "2.0.0-dev", default-features = false, path = "../arithmetic" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../std" } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../io" } +codec = { package = "parity-scale-codec", version = "1.3.1", default-features = false, features = ["derive"] } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../core" } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../application-crypto" } +sp-arithmetic = { version = "2.0.0-rc6", default-features = false, path = "../arithmetic" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../io" } log = { version = "0.4.8", optional = true } paste = "0.1.6" rand = { version = "0.7.2", optional = true } impl-trait-for-tuples = "0.1.3" -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../inherents" } -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../inherents" } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } hash256-std-hasher = { version = "0.15.2", default-features = false } +either = { version = "1.5", default-features = false } [dev-dependencies] serde_json = "1.0.41" rand = "0.7.2" -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } [features] bench = [] @@ -51,4 +52,5 @@ std = [ "sp-inherents/std", "parity-util-mem/std", "hash256-std-hasher/std", + "either/use_std", ] diff --git a/primitives/runtime/README.md b/primitives/runtime/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1515cd8e2961b5a72fee1d39297e51305d16b0a6 --- /dev/null +++ b/primitives/runtime/README.md @@ -0,0 +1,3 @@ +Runtime Modules shared primitive types. + +License: Apache-2.0 \ No newline at end of file diff --git a/primitives/runtime/src/curve.rs b/primitives/runtime/src/curve.rs index b00cbed6525a16cf6f1db35eed8f5b6e225437f3..27eb89a76947e039b396870ae3a3e2dc772f6b57 100644 --- a/primitives/runtime/src/curve.rs +++ b/primitives/runtime/src/curve.rs @@ -1,22 +1,23 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Provides some utilities to define a piecewise linear function. -use crate::{Perbill, traits::{AtLeast32Bit, SaturatedConversion}}; +use crate::{Perbill, traits::{AtLeast32BitUnsigned, SaturatedConversion}}; use core::ops::Sub; /// Piecewise Linear function in [0, 1] -> [0, 1]. @@ -35,7 +36,7 @@ fn abs_sub + Clone>(a: N, b: N) -> N where { impl<'a> PiecewiseLinear<'a> { /// Compute `f(n/d)*d` with `n <= d`. This is useful to avoid loss of precision. pub fn calculate_for_fraction_times_denominator(&self, n: N, d: N) -> N where - N: AtLeast32Bit + Clone + N: AtLeast32BitUnsigned + Clone { let n = n.min(d.clone()); @@ -79,7 +80,7 @@ impl<'a> PiecewiseLinear<'a> { // This is guaranteed not to overflow on whatever values nor lose precision. // `q` must be superior to zero. fn multiply_by_rational_saturating(value: N, p: u32, q: u32) -> N - where N: AtLeast32Bit + Clone + where N: AtLeast32BitUnsigned + Clone { let q = q.max(1); diff --git a/primitives/runtime/src/generic/block.rs b/primitives/runtime/src/generic/block.rs index fb07d6c215d81f3a241926da6252c12686fc2f28..4a758b7416dec568876a769ff4dbcf1f69b00385 100644 --- a/primitives/runtime/src/generic/block.rs +++ b/primitives/runtime/src/generic/block.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Generic implementation of a block and associated items. diff --git a/primitives/runtime/src/generic/checked_extrinsic.rs b/primitives/runtime/src/generic/checked_extrinsic.rs index a329f334c0d7707edc8a4e07ada8eac443accce2..f355308a59f9704d7f7343dcd904d8458ad63184 100644 --- a/primitives/runtime/src/generic/checked_extrinsic.rs +++ b/primitives/runtime/src/generic/checked_extrinsic.rs @@ -1,24 +1,26 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Generic implementation of an extrinsic that has passed the verification //! stage. use crate::traits::{ - self, Member, MaybeDisplay, SignedExtension, Dispatchable, DispatchInfoOf, ValidateUnsigned, + self, Member, MaybeDisplay, SignedExtension, Dispatchable, DispatchInfoOf, PostDispatchInfoOf, + ValidateUnsigned, }; use crate::transaction_validity::{TransactionValidity, TransactionSource}; @@ -66,7 +68,7 @@ where self, info: &DispatchInfoOf, len: usize, - ) -> crate::ApplyExtrinsicResult { + ) -> crate::ApplyExtrinsicResultWithInfo> { let (maybe_who, pre) = if let Some((id, extra)) = self.signed { let pre = Extra::pre_dispatch(extra, &id, &self.function, info, len)?; (Some(id), pre) @@ -80,8 +82,7 @@ where Ok(info) => info, Err(err) => err.post_info, }; - let res = res.map(|_| ()).map_err(|e| e.error); - Extra::post_dispatch(pre, info, &post_info, len, &res)?; + Extra::post_dispatch(pre, info, &post_info, len, &res.map(|_| ()).map_err(|e| e.error))?; Ok(res) } } diff --git a/primitives/runtime/src/generic/digest.rs b/primitives/runtime/src/generic/digest.rs index 44c1559aaa088dfbb9d51a116f88311df8bd1611..ec0963e5ba002c15490ef63034d7c8aa43a3d596 100644 --- a/primitives/runtime/src/generic/digest.rs +++ b/primitives/runtime/src/generic/digest.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Generic implementation of a digest. diff --git a/primitives/runtime/src/generic/era.rs b/primitives/runtime/src/generic/era.rs index 37b4b495fef540eb3b942098e3f54f11dfd41d1e..9bfab517a92caab182dba4d6a652757eb47158d4 100644 --- a/primitives/runtime/src/generic/era.rs +++ b/primitives/runtime/src/generic/era.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Generic implementation of an unchecked (pre-verification) extrinsic. diff --git a/primitives/runtime/src/generic/header.rs b/primitives/runtime/src/generic/header.rs index 5efb36603d572fd7be350f7b046e8b5969408cc6..e6c800e5787ff2e7e0f7efb77efffacbc2be9c7e 100644 --- a/primitives/runtime/src/generic/header.rs +++ b/primitives/runtime/src/generic/header.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Generic implementation of a block header. @@ -20,7 +21,7 @@ use serde::{Deserialize, Serialize}; use crate::codec::{Decode, Encode, Codec, Input, Output, HasCompact, EncodeAsRef, Error}; use crate::traits::{ - self, Member, AtLeast32Bit, SimpleBitOps, Hash as HashT, + self, Member, AtLeast32BitUnsigned, SimpleBitOps, Hash as HashT, MaybeSerializeDeserialize, MaybeSerialize, MaybeDisplay, MaybeMallocSizeOf, }; @@ -122,7 +123,7 @@ impl codec::EncodeLike for Header where impl traits::Header for Header where Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + MaybeDisplay + - AtLeast32Bit + Codec + Copy + Into + TryFrom + sp_std::str::FromStr + + AtLeast32BitUnsigned + Codec + Copy + Into + TryFrom + sp_std::str::FromStr + MaybeMallocSizeOf, Hash: HashT, Hash::Output: Default + sp_std::hash::Hash + Copy + Member + Ord + @@ -170,7 +171,8 @@ impl traits::Header for Header where } impl Header where - Number: Member + sp_std::hash::Hash + Copy + MaybeDisplay + AtLeast32Bit + Codec + Into + TryFrom, + Number: Member + sp_std::hash::Hash + Copy + MaybeDisplay + AtLeast32BitUnsigned + Codec + + Into + TryFrom, Hash: HashT, Hash::Output: Default + sp_std::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec, { diff --git a/primitives/runtime/src/generic/mod.rs b/primitives/runtime/src/generic/mod.rs index 5e9928ba1909ab2aa114babaadcc1cc774131e60..2a25c063ead7345c9428a920de39780ab5eedb35 100644 --- a/primitives/runtime/src/generic/mod.rs +++ b/primitives/runtime/src/generic/mod.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. // tag::description[] //! Generic implementations of Extrinsic/Header/Block. diff --git a/primitives/runtime/src/generic/tests.rs b/primitives/runtime/src/generic/tests.rs index de2f4a19d99cf7b366af00ef24ea322a6fc0ce68..56138094fa0246e5f25b173a7cf11a596e2e96be 100644 --- a/primitives/runtime/src/generic/tests.rs +++ b/primitives/runtime/src/generic/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Tests for the generic implementations of Extrinsic/Header/Block. diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index 4eb96ff960bcc72d65fd12d0567bd7206945d131..d16d404ddfd0e9207771b606d224d54df7288998 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Generic implementation of an unchecked (pre-verification) extrinsic. @@ -26,6 +27,7 @@ use crate::{ }, generic::CheckedExtrinsic, transaction_validity::{TransactionValidityError, InvalidTransaction}, + OpaqueExtrinsic, }; const TRANSACTION_VERSION: u8 = 4; @@ -315,6 +317,23 @@ where } } +impl From> + for OpaqueExtrinsic +where + Address: Encode, + Signature: Encode, + Call: Encode, + Extra: SignedExtension, +{ + fn from(extrinsic: UncheckedExtrinsic) -> Self { + OpaqueExtrinsic::from_bytes(extrinsic.encode().as_slice()) + .expect( + "both OpaqueExtrinsic and UncheckedExtrinsic have encoding that is compatible with \ + raw Vec encoding; qed" + ) + } +} + #[cfg(test)] mod tests { use super::*; @@ -423,4 +442,13 @@ mod tests { let as_vec: Vec = Decode::decode(&mut encoded.as_slice()).unwrap(); assert_eq!(as_vec.encode(), encoded); } + + #[test] + fn conversion_to_opaque() { + let ux = Ex::new_unsigned(vec![0u8; 0]); + let encoded = ux.encode(); + let opaque: OpaqueExtrinsic = ux.into(); + let opaque_encoded = opaque.encode(); + assert_eq!(opaque_encoded, encoded); + } } diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index b55edbd88d7f12ea6aa946b31a57d69bd0628f49..eb8bbb38a6ffe8dfeeaffb9a29fd754520edf11f 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Runtime Modules shared primitive types. @@ -70,8 +71,8 @@ pub use sp_core::RuntimeDebug; /// Re-export top-level arithmetic stuff. pub use sp_arithmetic::{ - Perquintill, Perbill, Permill, Percent, PerU16, Rational128, Fixed64, Fixed128, - PerThing, traits::SaturatedConversion, + PerThing, traits::SaturatedConversion, Perquintill, Perbill, Permill, Percent, PerU16, InnerOf, + Rational128, FixedI64, FixedI128, FixedU128, FixedPointNumber, FixedPointOperand, }; /// Re-export 128 bit helpers. pub use sp_arithmetic::helpers_128bit; @@ -80,6 +81,8 @@ pub use sp_arithmetic::biguint; pub use random_number_generator::RandomNumberGenerator; +pub use either::Either; + /// An abstraction over justification for a block's validity under a consensus algorithm. /// /// Essentially a finality proof. The exact formulation will vary between consensus @@ -156,7 +159,7 @@ impl BuildStorage for () { fn assimilate_storage( &self, _: &mut sp_core::storage::Storage, - )-> Result<(), String> { + ) -> Result<(), String> { Err("`assimilate_storage` not implemented for `()`".into()) } } @@ -373,16 +376,16 @@ impl From for DispatchOutcome { } } -/// This is the legacy return type of `Dispatchable`. It is still exposed for compatibilty -/// reasons. The new return type is `DispatchResultWithInfo`. -/// FRAME runtimes should use frame_support::dispatch::DispatchResult +/// This is the legacy return type of `Dispatchable`. It is still exposed for compatibility reasons. +/// The new return type is `DispatchResultWithInfo`. FRAME runtimes should use +/// `frame_support::dispatch::DispatchResult`. pub type DispatchResult = sp_std::result::Result<(), DispatchError>; /// Return type of a `Dispatchable` which contains the `DispatchResult` and additional information /// about the `Dispatchable` that is only known post dispatch. pub type DispatchResultWithInfo = sp_std::result::Result>; -/// Reason why a dispatch call failed +/// Reason why a dispatch call failed. #[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)] #[cfg_attr(feature = "std", derive(Serialize))] pub enum DispatchError { @@ -392,11 +395,11 @@ pub enum DispatchError { CannotLookup, /// A bad origin. BadOrigin, - /// A custom error in a module + /// A custom error in a module. Module { - /// Module index, matching the metadata module index + /// Module index, matching the metadata module index. index: u8, - /// Module specific error value + /// Module specific error value. error: u8, /// Optional error message. #[codec(skip)] @@ -404,15 +407,15 @@ pub enum DispatchError { }, } -/// Result of a `Dispatchable` which contains the `DispatchResult` and additional information -/// about the `Dispatchable` that is only known post dispatch. +/// Result of a `Dispatchable` which contains the `DispatchResult` and additional information about +/// the `Dispatchable` that is only known post dispatch. #[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)] pub struct DispatchErrorWithPostInfo where Info: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable { - /// Addditional information about the `Dispatchable` which is only known post dispatch. + /// Additional information about the `Dispatchable` which is only known post dispatch. pub post_info: Info, - /// The actual `DispatchResult` indicating whether the dispatch was succesfull. + /// The actual `DispatchResult` indicating whether the dispatch was successful. pub error: DispatchError, } @@ -535,6 +538,10 @@ pub type DispatchOutcome = Result<(), DispatchError>; /// - The extrinsic supplied a bad signature. This transaction won't become valid ever. pub type ApplyExtrinsicResult = Result; +/// Same as `ApplyExtrinsicResult` but augmented with `PostDispatchInfo` on success. +pub type ApplyExtrinsicResultWithInfo = + Result, transaction_validity::TransactionValidityError>; + /// Verify a signature on an encoded value in a lazy manner. This can be /// an optimization if the signature scheme has an "unsigned" escape hash. pub fn verify_encoded_lazy( @@ -707,7 +714,14 @@ macro_rules! assert_eq_error_rate { /// Simple blob to hold an extrinsic without committing to its format and ensure it is serialized /// correctly. #[derive(PartialEq, Eq, Clone, Default, Encode, Decode)] -pub struct OpaqueExtrinsic(pub Vec); +pub struct OpaqueExtrinsic(Vec); + +impl OpaqueExtrinsic { + /// Convert an encoded extrinsic to an `OpaqueExtrinsic`. + pub fn from_bytes(mut bytes: &[u8]) -> Result { + OpaqueExtrinsic::decode(&mut bytes) + } +} #[cfg(feature = "std")] impl parity_util_mem::MallocSizeOf for OpaqueExtrinsic { @@ -787,6 +801,23 @@ impl Drop for SignatureBatching { } } +/// Describes on what should happen with a storage transaction. +pub enum TransactionOutcome { + /// Commit the transaction. + Commit(R), + /// Rollback the transaction. + Rollback(R), +} + +impl TransactionOutcome { + /// Convert into the inner type. + pub fn into_inner(self) -> R { + match self { + Self::Commit(r) => r, + Self::Rollback(r) => r, + } + } +} #[cfg(test)] mod tests { @@ -840,7 +871,11 @@ mod tests { #[test] #[should_panic(expected = "Signature verification has not been called")] fn batching_still_finishes_when_not_called_directly() { - let mut ext = sp_state_machine::BasicExternalities::with_tasks_executor(); + let mut ext = sp_state_machine::BasicExternalities::default(); + ext.register_extension( + sp_core::traits::TaskExecutorExt::new(sp_core::testing::TaskExecutor::new()), + ); + ext.execute_with(|| { let _batching = SignatureBatching::start(); sp_io::crypto::sr25519_verify( diff --git a/primitives/runtime/src/offchain/http.rs b/primitives/runtime/src/offchain/http.rs index bbc929526b75998c181346a87eeaa3e532dc441c..12a0fcf1e5b45cb5c7cb258950ef561c11a6797a 100644 --- a/primitives/runtime/src/offchain/http.rs +++ b/primitives/runtime/src/offchain/http.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! A high-level helpers for making HTTP requests from Offchain Workers. //! diff --git a/primitives/runtime/src/offchain/mod.rs b/primitives/runtime/src/offchain/mod.rs index 9f0f949eaeb8df483df75b680fc1b872ae91ea4f..fe5844ce3004b62286968cf829e4b71793515446 100644 --- a/primitives/runtime/src/offchain/mod.rs +++ b/primitives/runtime/src/offchain/mod.rs @@ -1,22 +1,24 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! A collection of higher lever helpers for offchain calls. pub mod http; pub mod storage; +pub mod storage_lock; pub use sp_core::offchain::*; diff --git a/primitives/runtime/src/offchain/storage.rs b/primitives/runtime/src/offchain/storage.rs index 681bc14451e116e52c71f1f239d7ff539ded9c8e..2f62d400c0b950b326f70edae145de259eb16e7d 100644 --- a/primitives/runtime/src/offchain/storage.rs +++ b/primitives/runtime/src/offchain/storage.rs @@ -1,18 +1,19 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! A set of storage helpers for offchain workers. @@ -49,6 +50,11 @@ impl<'a> StorageValueRef<'a> { }) } + /// Remove the associated value from the storage. + pub fn clear(&mut self) { + sp_io::offchain::local_storage_clear(self.kind, self.key) + } + /// Retrieve & decode the value from storage. /// /// Note that if you want to do some checks based on the value @@ -66,7 +72,8 @@ impl<'a> StorageValueRef<'a> { /// Function `f` should return a new value that we should attempt to write to storage. /// This function returns: /// 1. `Ok(Ok(T))` in case the value has been successfully set. - /// 2. `Ok(Err(T))` in case the value was returned, but it couldn't have been set. + /// 2. `Ok(Err(T))` in case the value was calculated by the passed closure `f`, + /// but it could not be stored. /// 3. `Err(_)` in case `f` returns an error. pub fn mutate(&self, f: F) -> Result, E> where T: codec::Codec, diff --git a/primitives/runtime/src/offchain/storage_lock.rs b/primitives/runtime/src/offchain/storage_lock.rs new file mode 100644 index 0000000000000000000000000000000000000000..a3838f21fd13d55ce3dc71386597cb25741753fd --- /dev/null +++ b/primitives/runtime/src/offchain/storage_lock.rs @@ -0,0 +1,593 @@ +// Copyright 2019-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +//! # Off-chain Storage Lock +//! +//! A storage-based lock with a defined expiry time. +//! +//! The lock is using Local Storage and allows synchronizing access to critical +//! section of your code for concurrently running Off-chain Workers. Usage of +//! `PERSISTENT` variant of the storage persists the lock value across a full node +//! restart or re-orgs. +//! +//! A use case for the lock is to make sure that a particular section of the +//! code is only run by one Off-chain Worker at a time. This may include +//! performing a side-effect (i.e. an HTTP call) or alteration of single or +//! multiple Local Storage entries. +//! +//! One use case would be collective updates of multiple data items or append / +//! remove of i.e. sets, vectors which are stored in the off-chain storage DB. +//! +//! ## Example: +//! +//! ```rust +//! # use codec::{Decode, Encode, Codec}; +//! // in your off-chain worker code +//! use sp_runtime::offchain::{ +//! storage::StorageValueRef, +//! storage_lock::{StorageLock, Time}, +//! }; +//! +//! fn append_to_in_storage_vec<'a, T>(key: &'a [u8], _: T) where T: Codec { +//! // `access::lock` defines the storage entry which is used for +//! // persisting the lock in the underlying database. +//! // The entry name _must_ be unique and can be interpreted as a +//! // unique mutex instance reference tag. +//! let mut lock = StorageLock::

> for Author Client: HeaderBackend + ProvideRuntimeApi + Send + Sync + 'static, Client::Api: SessionKeys, { - type Metadata = crate::metadata::Metadata; + type Metadata = crate::Metadata; fn insert_key( &self, diff --git a/client/rpc/src/author/tests.rs b/client/rpc/src/author/tests.rs index de2ee92fe3674c869bb4d954b973c81d28160f01..5a8c58520ac43e7077978595111d114fac5140fd 100644 --- a/client/rpc/src/author/tests.rs +++ b/client/rpc/src/author/tests.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use super::*; @@ -30,7 +32,7 @@ use substrate_test_runtime_client::{ DefaultTestClientBuilderExt, TestClientBuilderExt, Backend, Client, }; use sc_transaction_pool::{BasicPool, FullChainApi}; -use tokio::runtime; +use futures::{executor, compat::Future01CompatExt}; fn uxt(sender: AccountKeyring, nonce: u64) -> Extrinsic { let tx = Transfer { @@ -48,7 +50,6 @@ type FullTransactionPool = BasicPool< >; struct TestSetup { - pub runtime: runtime::Runtime, pub client: Arc>, pub keystore: BareCryptoStorePtr, pub pool: Arc, @@ -57,18 +58,17 @@ struct TestSetup { impl Default for TestSetup { fn default() -> Self { let keystore = KeyStore::new(); - let client = Arc::new( - substrate_test_runtime_client::TestClientBuilder::new() - .set_keystore(keystore.clone()) - .build() - ); - let pool = Arc::new(BasicPool::new( + let client_builder = substrate_test_runtime_client::TestClientBuilder::new(); + let client = Arc::new(client_builder.set_keystore(keystore.clone()).build()); + + let spawner = sp_core::testing::TaskExecutor::new(); + let pool = BasicPool::new_full( Default::default(), - Arc::new(FullChainApi::new(client.clone())), None, - ).0); + spawner, + client.clone(), + ); TestSetup { - runtime: runtime::Runtime::new().expect("Failed to create runtime in test setup"), client, keystore, pool, @@ -81,7 +81,7 @@ impl TestSetup { Author { client: self.client.clone(), pool: self.pool.clone(), - subscriptions: Subscriptions::new(Arc::new(self.runtime.executor())), + subscriptions: SubscriptionManager::new(Arc::new(crate::testing::TaskExecutor)), keystore: self.keystore.clone(), deny_unsafe: DenyUnsafe::No, } @@ -121,16 +121,26 @@ fn submit_rich_transaction_should_not_cause_error() { #[test] fn should_watch_extrinsic() { //given - let mut setup = TestSetup::default(); + let setup = TestSetup::default(); let p = setup.author(); let (subscriber, id_rx, data) = jsonrpc_pubsub::typed::Subscriber::new_test("test"); // when - p.watch_extrinsic(Default::default(), subscriber, uxt(AccountKeyring::Alice, 0).encode().into()); + p.watch_extrinsic( + Default::default(), + subscriber, + uxt(AccountKeyring::Alice, 0).encode().into(), + ); + + let id = executor::block_on(id_rx.compat()).unwrap().unwrap(); + assert_matches!(id, SubscriptionId::String(_)); + + let id = match id { + SubscriptionId::String(id) => id, + _ => unreachable!(), + }; - // then - assert_eq!(setup.runtime.block_on(id_rx), Ok(Ok(1.into()))); // check notifications let replacement = { let tx = Transfer { @@ -142,22 +152,29 @@ fn should_watch_extrinsic() { tx.into_signed_tx() }; AuthorApi::submit_extrinsic(&p, replacement.encode().into()).wait().unwrap(); - let (res, data) = setup.runtime.block_on(data.into_future()).unwrap(); - assert_eq!( - res, - Some(r#"{"jsonrpc":"2.0","method":"test","params":{"result":"ready","subscription":1}}"#.into()) - ); + let (res, data) = executor::block_on(data.into_future().compat()).unwrap(); + + let expected = Some(format!( + r#"{{"jsonrpc":"2.0","method":"test","params":{{"result":"ready","subscription":"{}"}}}}"#, + id, + )); + assert_eq!(res, expected); + let h = blake2_256(&replacement.encode()); - assert_eq!( - setup.runtime.block_on(data.into_future()).unwrap().0, - Some(format!(r#"{{"jsonrpc":"2.0","method":"test","params":{{"result":{{"usurped":"0x{}"}},"subscription":1}}}}"#, HexDisplay::from(&h))) - ); + let expected = Some(format!( + r#"{{"jsonrpc":"2.0","method":"test","params":{{"result":{{"usurped":"0x{}"}},"subscription":"{}"}}}}"#, + HexDisplay::from(&h), + id, + )); + + let res = executor::block_on(data.into_future().compat()).unwrap().0; + assert_eq!(res, expected); } #[test] fn should_return_watch_validation_error() { //given - let mut setup = TestSetup::default(); + let setup = TestSetup::default(); let p = setup.author(); let (subscriber, id_rx, _data) = jsonrpc_pubsub::typed::Subscriber::new_test("test"); @@ -166,7 +183,7 @@ fn should_return_watch_validation_error() { p.watch_extrinsic(Default::default(), subscriber, uxt(AccountKeyring::Alice, 179).encode().into()); // then - let res = setup.runtime.block_on(id_rx).unwrap(); + let res = executor::block_on(id_rx.compat()).unwrap(); assert!(res.is_err(), "Expected the transaction to be rejected as invalid."); } diff --git a/client/rpc/src/chain/chain_full.rs b/client/rpc/src/chain/chain_full.rs index c1b062754bdac41eff2a2c3c04ad1375b09ce915..816dbba8664172a2cf467a5dc723386e689823d3 100644 --- a/client/rpc/src/chain/chain_full.rs +++ b/client/rpc/src/chain/chain_full.rs @@ -18,8 +18,8 @@ use std::sync::Arc; use rpc::futures::future::result; +use jsonrpc_pubsub::manager::SubscriptionManager; -use sc_rpc_api::Subscriptions; use sc_client_api::{BlockchainEvents, BlockBackend}; use sp_runtime::{generic::{BlockId, SignedBlock}, traits::{Block as BlockT}}; @@ -32,14 +32,14 @@ pub struct FullChain { /// Substrate client. client: Arc, /// Current subscriptions. - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, /// phantom member to pin the block type _phantom: PhantomData, } impl FullChain { /// Create new Chain API RPC handler. - pub fn new(client: Arc, subscriptions: Subscriptions) -> Self { + pub fn new(client: Arc, subscriptions: SubscriptionManager) -> Self { Self { client, subscriptions, @@ -56,7 +56,7 @@ impl ChainBackend for FullChain whe &self.client } - fn subscriptions(&self) -> &Subscriptions { + fn subscriptions(&self) -> &SubscriptionManager { &self.subscriptions } diff --git a/client/rpc/src/chain/chain_light.rs b/client/rpc/src/chain/chain_light.rs index 059233089d05d1559880c2ace86975d2d562fffd..8a4afbed71c165708fd5d4b0effca47abe6995f7 100644 --- a/client/rpc/src/chain/chain_light.rs +++ b/client/rpc/src/chain/chain_light.rs @@ -19,8 +19,8 @@ use std::sync::Arc; use futures::{future::ready, FutureExt, TryFutureExt}; use rpc::futures::future::{result, Future, Either}; +use jsonrpc_pubsub::manager::SubscriptionManager; -use sc_rpc_api::Subscriptions; use sc_client_api::light::{Fetcher, RemoteBodyRequest, RemoteBlockchain}; use sp_runtime::{ generic::{BlockId, SignedBlock}, @@ -37,7 +37,7 @@ pub struct LightChain { /// Substrate client. client: Arc, /// Current subscriptions. - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, /// Remote blockchain reference remote_blockchain: Arc>, /// Remote fetcher reference. @@ -48,7 +48,7 @@ impl> LightChain { /// Create new Chain API RPC handler. pub fn new( client: Arc, - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, remote_blockchain: Arc>, fetcher: Arc, ) -> Self { @@ -70,7 +70,7 @@ impl ChainBackend for LightChain &Subscriptions { + fn subscriptions(&self) -> &SubscriptionManager { &self.subscriptions } diff --git a/client/rpc/src/chain/mod.rs b/client/rpc/src/chain/mod.rs index bd2e41bd4b685b37ac913f21b2c65580578aba1e..cb67d9ba23166e36d0c5106f0333e9d4385e850d 100644 --- a/client/rpc/src/chain/mod.rs +++ b/client/rpc/src/chain/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate blockchain API. @@ -30,9 +32,8 @@ use rpc::{ futures::{stream, Future, Sink, Stream}, }; -use sc_rpc_api::Subscriptions; use sc_client_api::{BlockchainEvents, light::{Fetcher, RemoteBlockchain}}; -use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId, manager::SubscriptionManager}; use sp_rpc::{number::NumberOrHex, list::ListOrValue}; use sp_runtime::{ generic::{BlockId, SignedBlock}, @@ -55,7 +56,7 @@ trait ChainBackend: Send + Sync + 'static fn client(&self) -> &Arc; /// Get subscriptions reference. - fn subscriptions(&self) -> &Subscriptions; + fn subscriptions(&self) -> &SubscriptionManager; /// Tries to unwrap passed block hash, or uses best block hash otherwise. fn unwrap_or_best(&self, hash: Option) -> Block::Hash { @@ -74,17 +75,27 @@ trait ChainBackend: Send + Sync + 'static /// Get hash of the n-th block in the canon chain. /// /// By default returns latest block hash. - fn block_hash( - &self, - number: Option>>, - ) -> Result> { - Ok(match number { - None => Some(self.client().info().best_hash), - Some(num_or_hex) => self.client() - .header(BlockId::number(num_or_hex.to_number()?)) - .map_err(client_err)? - .map(|h| h.hash()), - }) + fn block_hash(&self, number: Option) -> Result> { + match number { + None => Ok(Some(self.client().info().best_hash)), + Some(num_or_hex) => { + use std::convert::TryInto; + + // FIXME <2329>: Database seems to limit the block number to u32 for no reason + let block_num: u32 = num_or_hex.try_into().map_err(|_| { + Error::from(format!( + "`{:?}` > u32::max_value(), the max block number is u32.", + num_or_hex + )) + })?; + let block_num = >::from(block_num); + Ok(self + .client() + .header(BlockId::number(block_num)) + .map_err(client_err)? + .map(|h| h.hash())) + } + } } /// Get hash of the last finalized block in the canon chain. @@ -95,7 +106,7 @@ trait ChainBackend: Send + Sync + 'static /// All new head subscription fn subscribe_all_heads( &self, - _metadata: crate::metadata::Metadata, + _metadata: crate::Metadata, subscriber: Subscriber, ) { subscribe_headers( @@ -112,7 +123,7 @@ trait ChainBackend: Send + Sync + 'static /// Unsubscribe from all head subscription. fn unsubscribe_all_heads( &self, - _metadata: Option, + _metadata: Option, id: SubscriptionId, ) -> RpcResult { Ok(self.subscriptions().cancel(id)) @@ -121,7 +132,7 @@ trait ChainBackend: Send + Sync + 'static /// New best head subscription fn subscribe_new_heads( &self, - _metadata: crate::metadata::Metadata, + _metadata: crate::Metadata, subscriber: Subscriber, ) { subscribe_headers( @@ -139,7 +150,7 @@ trait ChainBackend: Send + Sync + 'static /// Unsubscribe from new best head subscription. fn unsubscribe_new_heads( &self, - _metadata: Option, + _metadata: Option, id: SubscriptionId, ) -> RpcResult { Ok(self.subscriptions().cancel(id)) @@ -148,7 +159,7 @@ trait ChainBackend: Send + Sync + 'static /// Finalized head subscription fn subscribe_finalized_heads( &self, - _metadata: crate::metadata::Metadata, + _metadata: crate::Metadata, subscriber: Subscriber, ) { subscribe_headers( @@ -165,7 +176,7 @@ trait ChainBackend: Send + Sync + 'static /// Unsubscribe from finalized head subscription. fn unsubscribe_finalized_heads( &self, - _metadata: Option, + _metadata: Option, id: SubscriptionId, ) -> RpcResult { Ok(self.subscriptions().cancel(id)) @@ -175,7 +186,7 @@ trait ChainBackend: Send + Sync + 'static /// Create new state API that works on full node. pub fn new_full( client: Arc, - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, ) -> Chain where Block: BlockT + 'static, @@ -189,7 +200,7 @@ pub fn new_full( /// Create new state API that works on light node. pub fn new_light>( client: Arc, - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, remote_blockchain: Arc>, fetcher: Arc, ) -> Chain @@ -219,7 +230,7 @@ impl ChainApi, Block::Hash, Block::Header, Signe Block: BlockT + 'static, Client: HeaderBackend + BlockchainEvents + 'static, { - type Metadata = crate::metadata::Metadata; + type Metadata = crate::Metadata; fn header(&self, hash: Option) -> FutureResult> { self.backend.header(hash) @@ -232,7 +243,7 @@ impl ChainApi, Block::Hash, Block::Header, Signe fn block_hash( &self, - number: Option>>> + number: Option>, ) -> Result>> { match number { None => self.backend.block_hash(None).map(ListOrValue::Value), @@ -277,7 +288,7 @@ impl ChainApi, Block::Hash, Block::Header, Signe /// Subscribe to new headers. fn subscribe_headers( client: &Arc, - subscriptions: &Subscriptions, + subscriptions: &SubscriptionManager, subscriber: Subscriber, best_block_hash: G, stream: F, diff --git a/client/rpc/src/chain/tests.rs b/client/rpc/src/chain/tests.rs index 68d904919b3d74faba6b8bb4add1f56776ab0e9c..b36fc4eab1d865f5a3c97e2d615d88cf33955274 100644 --- a/client/rpc/src/chain/tests.rs +++ b/client/rpc/src/chain/tests.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use super::*; use assert_matches::assert_matches; @@ -23,14 +25,13 @@ use substrate_test_runtime_client::{ }; use sp_rpc::list::ListOrValue; use sc_block_builder::BlockBuilderProvider; +use futures::{executor, compat::{Future01CompatExt, Stream01CompatExt}}; +use crate::testing::TaskExecutor; #[test] fn should_return_header() { - let core = tokio::runtime::Runtime::new().unwrap(); - let remote = core.executor(); - let client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let api = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); assert_matches!( api.header(Some(client.genesis_hash()).into()).wait(), @@ -61,11 +62,8 @@ fn should_return_header() { #[test] fn should_return_a_block() { - let core = tokio::runtime::Runtime::new().unwrap(); - let remote = core.executor(); - let mut client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let api = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); let block = client.new_block(Default::default()).unwrap().build().unwrap().block; let block_hash = block.hash(); @@ -115,11 +113,8 @@ fn should_return_a_block() { #[test] fn should_return_block_hash() { - let core = ::tokio::runtime::Runtime::new().unwrap(); - let remote = core.executor(); - let mut client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let api = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); assert_matches!( api.block_hash(None.into()), @@ -154,7 +149,7 @@ fn should_return_block_hash() { ); assert_matches!( - api.block_hash(Some(vec![0u64.into(), 1.into(), 2.into()].into())), + api.block_hash(Some(vec![0u64.into(), 1u64.into(), 2u64.into()].into())), Ok(ListOrValue::List(list)) if list == &[client.genesis_hash().into(), block.hash().into(), None] ); } @@ -162,11 +157,8 @@ fn should_return_block_hash() { #[test] fn should_return_finalized_hash() { - let core = ::tokio::runtime::Runtime::new().unwrap(); - let remote = core.executor(); - let mut client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let api = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); assert_matches!( api.finalized_head(), @@ -192,76 +184,79 @@ fn should_return_finalized_hash() { #[test] fn should_notify_about_latest_block() { - let mut core = ::tokio::runtime::Runtime::new().unwrap(); - let remote = core.executor(); let (subscriber, id, transport) = Subscriber::new_test("test"); { let mut client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let api = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); api.subscribe_all_heads(Default::default(), subscriber); // assert id assigned - assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); + assert!(matches!( + executor::block_on(id.compat()), + Ok(Ok(SubscriptionId::String(_))) + )); let block = client.new_block(Default::default()).unwrap().build().unwrap().block; client.import(BlockOrigin::Own, block).unwrap(); } // assert initial head sent. - let (notification, next) = core.block_on(transport.into_future()).unwrap(); + let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap(); assert!(notification.is_some()); // assert notification sent to transport - let (notification, next) = core.block_on(next.into_future()).unwrap(); + let (notification, next) = executor::block_on(next.into_future().compat()).unwrap(); assert!(notification.is_some()); // no more notifications on this channel - assert_eq!(core.block_on(next.into_future()).unwrap().0, None); + assert_eq!(executor::block_on(next.into_future().compat()).unwrap().0, None); } #[test] fn should_notify_about_best_block() { - let mut core = ::tokio::runtime::Runtime::new().unwrap(); - let remote = core.executor(); let (subscriber, id, transport) = Subscriber::new_test("test"); { let mut client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let api = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); api.subscribe_new_heads(Default::default(), subscriber); // assert id assigned - assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); + assert!(matches!( + executor::block_on(id.compat()), + Ok(Ok(SubscriptionId::String(_))) + )); let block = client.new_block(Default::default()).unwrap().build().unwrap().block; client.import(BlockOrigin::Own, block).unwrap(); } // assert initial head sent. - let (notification, next) = core.block_on(transport.into_future()).unwrap(); + let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap(); assert!(notification.is_some()); // assert notification sent to transport - let (notification, next) = core.block_on(next.into_future()).unwrap(); + let (notification, next) = executor::block_on(next.into_future().compat()).unwrap(); assert!(notification.is_some()); // no more notifications on this channel - assert_eq!(core.block_on(next.into_future()).unwrap().0, None); + assert_eq!(executor::block_on(Stream01CompatExt::compat(next).into_future()).0, None); } #[test] fn should_notify_about_finalized_block() { - let mut core = ::tokio::runtime::Runtime::new().unwrap(); - let remote = core.executor(); let (subscriber, id, transport) = Subscriber::new_test("test"); { let mut client = Arc::new(substrate_test_runtime_client::new()); - let api = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let api = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); api.subscribe_finalized_heads(Default::default(), subscriber); // assert id assigned - assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); + assert!(matches!( + executor::block_on(id.compat()), + Ok(Ok(SubscriptionId::String(_))) + )); let block = client.new_block(Default::default()).unwrap().build().unwrap().block; client.import(BlockOrigin::Own, block).unwrap(); @@ -269,11 +264,11 @@ fn should_notify_about_finalized_block() { } // assert initial head sent. - let (notification, next) = core.block_on(transport.into_future()).unwrap(); + let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap(); assert!(notification.is_some()); // assert notification sent to transport - let (notification, next) = core.block_on(next.into_future()).unwrap(); + let (notification, next) = executor::block_on(next.into_future().compat()).unwrap(); assert!(notification.is_some()); // no more notifications on this channel - assert_eq!(core.block_on(next.into_future()).unwrap().0, None); + assert_eq!(executor::block_on(next.into_future().compat()).unwrap().0, None); } diff --git a/client/rpc/src/lib.rs b/client/rpc/src/lib.rs index c4389913b4ffdda3ae4bb233583f55cc2d947dc2..434859a39c2f4761b9e7553ea05c6fde16bd09ce 100644 --- a/client/rpc/src/lib.rs +++ b/client/rpc/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate RPC implementation. //! @@ -20,10 +22,12 @@ #![warn(missing_docs)] -mod metadata; +use futures::{compat::Future01CompatExt, FutureExt}; +use rpc::futures::future::{Executor, ExecuteError, Future}; +use sp_core::traits::SpawnNamed; +use std::sync::Arc; -pub use sc_rpc_api::{DenyUnsafe, Subscriptions}; -pub use self::metadata::Metadata; +pub use sc_rpc_api::{DenyUnsafe, Metadata}; pub use rpc::IoHandlerExtension as RpcExtension; pub mod author; @@ -31,3 +35,27 @@ pub mod chain; pub mod offchain; pub mod state; pub mod system; + +#[cfg(any(test, feature = "test-helpers"))] +pub mod testing; + +/// Task executor that is being used by RPC subscriptions. +#[derive(Clone)] +pub struct SubscriptionTaskExecutor(Arc); + +impl SubscriptionTaskExecutor { + /// Create a new `Self` with the given spawner. + pub fn new(spawn: impl SpawnNamed + 'static) -> Self { + Self(Arc::new(spawn)) + } +} + +impl Executor + Send>> for SubscriptionTaskExecutor { + fn execute( + &self, + future: Box + Send>, + ) -> Result<(), ExecuteError + Send>>> { + self.0.spawn("substrate-rpc-subscription", future.compat().map(drop).boxed()); + Ok(()) + } +} diff --git a/client/rpc/src/offchain/mod.rs b/client/rpc/src/offchain/mod.rs index 16c03395c738784c44de30682e3fb10c6f1ae15b..f8d2bb6a50f9c653491dc0536e019ad99ce20aa1 100644 --- a/client/rpc/src/offchain/mod.rs +++ b/client/rpc/src/offchain/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate offchain API. diff --git a/client/rpc/src/offchain/tests.rs b/client/rpc/src/offchain/tests.rs index cb05f3d4dbb890499ff140ac6e913e62b29c46d0..f65971a7ffe8ae278495dfb80921e979806c187a 100644 --- a/client/rpc/src/offchain/tests.rs +++ b/client/rpc/src/offchain/tests.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use super::*; use assert_matches::assert_matches; diff --git a/client/rpc/src/state/mod.rs b/client/rpc/src/state/mod.rs index d1f4e2c5f9c164ac800c0c56f45f41d49a6089dc..01c7c5f1eb40cefac0a8bc64e966086ba4d18f56 100644 --- a/client/rpc/src/state/mod.rs +++ b/client/rpc/src/state/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate state API. @@ -23,10 +25,10 @@ mod state_light; mod tests; use std::sync::Arc; -use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId, manager::SubscriptionManager}; use rpc::{Result as RpcResult, futures::{Future, future::result}}; -use sc_rpc_api::{Subscriptions, state::ReadProof}; +use sc_rpc_api::state::ReadProof; use sc_client_api::light::{RemoteBlockchain, Fetcher}; use sp_core::{Bytes, storage::{StorageKey, PrefixedStorageKey, StorageData, StorageChangeSet}}; use sp_version::RuntimeVersion; @@ -95,14 +97,14 @@ pub trait StateBackend: Send + Sync + 'static ) -> FutureResult>; /// Returns the size of a storage entry at a block's state. + /// + /// If data is available at `key`, it is returned. Else, the sum of values who's key has `key` + /// prefix is returned, i.e. all the storage (double) maps that have this prefix. fn storage_size( &self, block: Option, key: StorageKey, - ) -> FutureResult> { - Box::new(self.storage(block, key) - .map(|x| x.map(|x| x.0.len() as u64))) - } + ) -> FutureResult>; /// Returns the runtime metadata as an opaque blob. fn metadata(&self, block: Option) -> FutureResult; @@ -138,21 +140,21 @@ pub trait StateBackend: Send + Sync + 'static /// New runtime version subscription fn subscribe_runtime_version( &self, - _meta: crate::metadata::Metadata, + _meta: crate::Metadata, subscriber: Subscriber, ); /// Unsubscribe from runtime version subscription fn unsubscribe_runtime_version( &self, - _meta: Option, + _meta: Option, id: SubscriptionId, ) -> RpcResult; /// New storage subscription fn subscribe_storage( &self, - _meta: crate::metadata::Metadata, + _meta: crate::Metadata, subscriber: Subscriber>, keys: Option>, ); @@ -160,7 +162,7 @@ pub trait StateBackend: Send + Sync + 'static /// Unsubscribe from storage subscription fn unsubscribe_storage( &self, - _meta: Option, + _meta: Option, id: SubscriptionId, ) -> RpcResult; } @@ -168,7 +170,7 @@ pub trait StateBackend: Send + Sync + 'static /// Create new state API that works on full node. pub fn new_full( client: Arc, - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, ) -> (State, ChildState) where Block: BlockT + 'static, @@ -189,7 +191,7 @@ pub fn new_full( /// Create new state API that works on light node. pub fn new_light>( client: Arc, - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, remote_blockchain: Arc>, fetcher: Arc, ) -> (State, ChildState) @@ -228,7 +230,7 @@ impl StateApi for State Block: BlockT + 'static, Client: Send + Sync + 'static, { - type Metadata = crate::metadata::Metadata; + type Metadata = crate::Metadata; fn call(&self, method: String, data: Bytes, block: Option) -> FutureResult { self.backend.call(block, method, data) @@ -388,7 +390,7 @@ impl ChildStateApi for ChildState Block: BlockT + 'static, Client: Send + Sync + 'static, { - type Metadata = crate::metadata::Metadata; + type Metadata = crate::Metadata; fn storage( &self, diff --git a/client/rpc/src/state/state_full.rs b/client/rpc/src/state/state_full.rs index 82f87e9acf22352c122412ee9f7cba5522414786..fda73cea271103c6b797293750459f3c9e0b952e 100644 --- a/client/rpc/src/state/state_full.rs +++ b/client/rpc/src/state/state_full.rs @@ -21,10 +21,10 @@ use std::sync::Arc; use std::ops::Range; use futures::{future, StreamExt as _, TryStreamExt as _}; use log::warn; -use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId, manager::SubscriptionManager}; use rpc::{Result as RpcResult, futures::{stream, Future, Sink, Stream, future::result}}; -use sc_rpc_api::{Subscriptions, state::ReadProof}; +use sc_rpc_api::state::ReadProof; use sc_client_api::backend::Backend; use sp_blockchain::{Result as ClientResult, Error as ClientError, HeaderMetadata, CachedHeaderMetadata, HeaderBackend}; use sc_client_api::BlockchainEvents; @@ -60,7 +60,7 @@ struct QueryStorageRange { /// State API backend for full nodes. pub struct FullState { client: Arc, - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, _phantom: PhantomData<(BE, Block)> } @@ -72,7 +72,7 @@ impl FullState Block: BlockT + 'static, { /// Create new state API backend for full nodes. - pub fn new(client: Arc, subscriptions: Subscriptions) -> Self { + pub fn new(client: Arc, subscriptions: SubscriptionManager) -> Self { Self { client, subscriptions, _phantom: PhantomData } } @@ -298,6 +298,36 @@ impl StateBackend for FullState, + key: StorageKey, + ) -> FutureResult> { + let block = match self.block_or_best(block) { + Ok(b) => b, + Err(e) => return Box::new(result(Err(client_err(e)))), + }; + + match self.client.storage(&BlockId::Hash(block), &key) { + Ok(Some(d)) => return Box::new(result(Ok(Some(d.0.len() as u64)))), + Err(e) => return Box::new(result(Err(client_err(e)))), + Ok(None) => {}, + } + + Box::new(result( + self.client.storage_pairs(&BlockId::Hash(block), &key) + .map(|kv| { + let item_sum = kv.iter().map(|(_, v)| v.0.len() as u64).sum::(); + if item_sum > 0 { + Some(item_sum) + } else { + None + } + }) + .map_err(client_err) + )) + } + fn storage_hash( &self, block: Option, @@ -373,7 +403,7 @@ impl StateBackend for FullState, ) { let stream = match self.client.storage_changes_notification_stream( @@ -424,7 +454,7 @@ impl StateBackend for FullState, + _meta: Option, id: SubscriptionId, ) -> RpcResult { Ok(self.subscriptions.cancel(id)) @@ -432,7 +462,7 @@ impl StateBackend for FullState>, keys: Option>, ) { @@ -484,7 +514,7 @@ impl StateBackend for FullState, + _meta: Option, id: SubscriptionId, ) -> RpcResult { Ok(self.subscriptions.cancel(id)) diff --git a/client/rpc/src/state/state_light.rs b/client/rpc/src/state/state_light.rs index af5d4248e3a422e2bfc759bc40c0b269ee68ccfc..8f4dce08b3fb61478add4218d3c6bd1f73bae47b 100644 --- a/client/rpc/src/state/state_light.rs +++ b/client/rpc/src/state/state_light.rs @@ -28,7 +28,7 @@ use futures::{ StreamExt as _, TryStreamExt as _, }; use hash_db::Hasher; -use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId}; +use jsonrpc_pubsub::{typed::Subscriber, SubscriptionId, manager::SubscriptionManager}; use log::warn; use parking_lot::Mutex; use rpc::{ @@ -38,7 +38,7 @@ use rpc::{ futures::stream::Stream, }; -use sc_rpc_api::{Subscriptions, state::ReadProof}; +use sc_rpc_api::state::ReadProof; use sp_blockchain::{Error as ClientError, HeaderBackend}; use sc_client_api::{ BlockchainEvents, @@ -63,7 +63,7 @@ type StorageMap = HashMap>; #[derive(Clone)] pub struct LightState, Client> { client: Arc, - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, version_subscriptions: SimpleSubscriptions, storage_subscriptions: Arc>>, remote_blockchain: Arc>, @@ -143,7 +143,7 @@ impl + 'static, Client> LightState, - subscriptions: Subscriptions, + subscriptions: SubscriptionManager, remote_blockchain: Arc>, fetcher: Arc, ) -> Self { @@ -214,6 +214,14 @@ impl StateBackend for LightState, + _: StorageKey, + ) -> FutureResult> { + Box::new(result(Err(client_err(ClientError::NotAvailableOnLightClient)))) + } + fn storage( &self, block: Option, @@ -289,7 +297,7 @@ impl StateBackend for LightState>, keys: Option> ) { @@ -384,7 +392,7 @@ impl StateBackend for LightState, + _meta: Option, id: SubscriptionId, ) -> RpcResult { if !self.subscriptions.cancel(id.clone()) { @@ -412,7 +420,7 @@ impl StateBackend for LightState, ) { self.subscriptions.add(subscriber, move |sink| { @@ -459,7 +467,7 @@ impl StateBackend for LightState, + _meta: Option, id: SubscriptionId, ) -> RpcResult { Ok(self.subscriptions.cancel(id)) @@ -539,7 +547,7 @@ fn resolve_header>( maybe_header.then(move |result| ready(result.and_then(|maybe_header| - maybe_header.ok_or(ClientError::UnknownBlock(format!("{}", block))) + maybe_header.ok_or_else(|| ClientError::UnknownBlock(format!("{}", block))) ).map_err(client_err)), ) } diff --git a/client/rpc/src/state/tests.rs b/client/rpc/src/state/tests.rs index da904f3fdc6c5f17e294e0b118d5174d3268cf91..b6677a1f2ffb4b0f9e7be3398506677dadee5b91 100644 --- a/client/rpc/src/state/tests.rs +++ b/client/rpc/src/state/tests.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use super::*; use super::state_full::split_range; @@ -31,6 +33,8 @@ use substrate_test_runtime_client::{ runtime, }; use sp_runtime::generic::BlockId; +use crate::testing::TaskExecutor; +use futures::{executor, compat::Future01CompatExt}; const STORAGE_KEY: &[u8] = b"child"; @@ -46,13 +50,15 @@ fn should_return_storage() { const CHILD_VALUE: &[u8] = b"hello world !"; let child_info = ChildInfo::new_default(STORAGE_KEY); - let mut core = tokio::runtime::Runtime::new().unwrap(); let client = TestClientBuilder::new() .add_extra_storage(KEY.to_vec(), VALUE.to_vec()) .add_extra_child_storage(&child_info, KEY.to_vec(), CHILD_VALUE.to_vec()) + // similar to a map with two keys + .add_extra_storage(b":map:acc1".to_vec(), vec![1, 2]) + .add_extra_storage(b":map:acc2".to_vec(), vec![1, 2, 3]) .build(); let genesis_hash = client.genesis_hash(); - let (client, child) = new_full(Arc::new(client), Subscriptions::new(Arc::new(core.executor()))); + let (client, child) = new_full(Arc::new(client), SubscriptionManager::new(Arc::new(TaskExecutor))); let key = StorageKey(KEY.to_vec()); assert_eq!( @@ -70,24 +76,27 @@ fn should_return_storage() { VALUE.len(), ); assert_eq!( - core.block_on( + client.storage_size(StorageKey(b":map".to_vec()), None).wait().unwrap().unwrap() as usize, + 2 + 3, + ); + assert_eq!( + executor::block_on( child.storage(prefixed_storage_key(), key, Some(genesis_hash).into()) .map(|x| x.map(|x| x.0.len())) + .compat(), ).unwrap().unwrap() as usize, CHILD_VALUE.len(), ); - } #[test] fn should_return_child_storage() { let child_info = ChildInfo::new_default(STORAGE_KEY); - let core = tokio::runtime::Runtime::new().unwrap(); let client = Arc::new(substrate_test_runtime_client::TestClientBuilder::new() .add_child_storage(&child_info, "key", vec![42_u8]) .build()); let genesis_hash = client.genesis_hash(); - let (_client, child) = new_full(client, Subscriptions::new(Arc::new(core.executor()))); + let (_client, child) = new_full(client, SubscriptionManager::new(Arc::new(TaskExecutor))); let child_key = prefixed_storage_key(); let key = StorageKey(b"key".to_vec()); @@ -120,10 +129,9 @@ fn should_return_child_storage() { #[test] fn should_call_contract() { - let core = tokio::runtime::Runtime::new().unwrap(); let client = Arc::new(substrate_test_runtime_client::new()); let genesis_hash = client.genesis_hash(); - let (client, _child) = new_full(client, Subscriptions::new(Arc::new(core.executor()))); + let (client, _child) = new_full(client, SubscriptionManager::new(Arc::new(TaskExecutor))); assert_matches!( client.call("balanceOf".into(), Bytes(vec![1,2,3]), Some(genesis_hash).into()).wait(), @@ -133,18 +141,19 @@ fn should_call_contract() { #[test] fn should_notify_about_storage_changes() { - let mut core = tokio::runtime::Runtime::new().unwrap(); - let remote = core.executor(); let (subscriber, id, transport) = Subscriber::new_test("test"); { let mut client = Arc::new(substrate_test_runtime_client::new()); - let (api, _child) = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let (api, _child) = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); api.subscribe_storage(Default::default(), subscriber, None.into()); // assert id assigned - assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); + assert!(matches!( + executor::block_on(id.compat()), + Ok(Ok(SubscriptionId::String(_))) + )); let mut builder = client.new_block(Default::default()).unwrap(); builder.push_transfer(runtime::Transfer { @@ -158,21 +167,19 @@ fn should_notify_about_storage_changes() { } // assert notification sent to transport - let (notification, next) = core.block_on(transport.into_future()).unwrap(); + let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap(); assert!(notification.is_some()); // no more notifications on this channel - assert_eq!(core.block_on(next.into_future()).unwrap().0, None); + assert_eq!(executor::block_on(next.into_future().compat()).unwrap().0, None); } #[test] fn should_send_initial_storage_changes_and_notifications() { - let mut core = tokio::runtime::Runtime::new().unwrap(); - let remote = core.executor(); let (subscriber, id, transport) = Subscriber::new_test("test"); { let mut client = Arc::new(substrate_test_runtime_client::new()); - let (api, _child) = new_full(client.clone(), Subscriptions::new(Arc::new(remote))); + let (api, _child) = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); let alice_balance_key = blake2_256(&runtime::system::balance_of_key(AccountKeyring::Alice.into())); @@ -181,7 +188,10 @@ fn should_send_initial_storage_changes_and_notifications() { ]).into()); // assert id assigned - assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); + assert!(matches!( + executor::block_on(id.compat()), + Ok(Ok(SubscriptionId::String(_))) + )); let mut builder = client.new_block(Default::default()).unwrap(); builder.push_transfer(runtime::Transfer { @@ -195,20 +205,19 @@ fn should_send_initial_storage_changes_and_notifications() { } // assert initial values sent to transport - let (notification, next) = core.block_on(transport.into_future()).unwrap(); + let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap(); assert!(notification.is_some()); // assert notification sent to transport - let (notification, next) = core.block_on(next.into_future()).unwrap(); + let (notification, next) = executor::block_on(next.into_future().compat()).unwrap(); assert!(notification.is_some()); // no more notifications on this channel - assert_eq!(core.block_on(next.into_future()).unwrap().0, None); + assert_eq!(executor::block_on(next.into_future().compat()).unwrap().0, None); } #[test] fn should_query_storage() { fn run_tests(mut client: Arc, has_changes_trie_config: bool) { - let core = tokio::runtime::Runtime::new().unwrap(); - let (api, _child) = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let (api, _child) = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); let mut add_block = |nonce| { let mut builder = client.new_block(Default::default()).unwrap(); @@ -424,10 +433,8 @@ fn should_split_ranges() { #[test] fn should_return_runtime_version() { - let core = tokio::runtime::Runtime::new().unwrap(); - let client = Arc::new(substrate_test_runtime_client::new()); - let (api, _child) = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let (api, _child) = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\ \"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",3],\ @@ -446,24 +453,27 @@ fn should_return_runtime_version() { #[test] fn should_notify_on_runtime_version_initially() { - let mut core = tokio::runtime::Runtime::new().unwrap(); let (subscriber, id, transport) = Subscriber::new_test("test"); { let client = Arc::new(substrate_test_runtime_client::new()); - let (api, _child) = new_full(client.clone(), Subscriptions::new(Arc::new(core.executor()))); + let (api, _child) = new_full(client.clone(), SubscriptionManager::new(Arc::new(TaskExecutor))); api.subscribe_runtime_version(Default::default(), subscriber); // assert id assigned - assert_eq!(core.block_on(id), Ok(Ok(SubscriptionId::Number(1)))); + assert!(matches!( + executor::block_on(id.compat()), + Ok(Ok(SubscriptionId::String(_))) + )); + } // assert initial version sent. - let (notification, next) = core.block_on(transport.into_future()).unwrap(); + let (notification, next) = executor::block_on(transport.into_future().compat()).unwrap(); assert!(notification.is_some()); // no more notifications on this channel - assert_eq!(core.block_on(next.into_future()).unwrap().0, None); + assert_eq!(executor::block_on(next.into_future().compat()).unwrap().0, None); } #[test] diff --git a/client/rpc/src/system/mod.rs b/client/rpc/src/system/mod.rs index 2a19e5412ed4f6a01c74f76377c314de5fecc738..4b8abbe1444620e23467edfef567d9fd0f71c570 100644 --- a/client/rpc/src/system/mod.rs +++ b/client/rpc/src/system/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate system API. diff --git a/client/rpc/src/system/tests.rs b/client/rpc/src/system/tests.rs index d0ec6951260fac346973e9c2b35f8992b8315f7a..dfe1fcc415159719ad59ea6a2798be7aa6efcaca 100644 --- a/client/rpc/src/system/tests.rs +++ b/client/rpc/src/system/tests.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use super::*; @@ -20,7 +22,8 @@ use sc_network::{self, PeerId}; use sc_network::config::Role; use substrate_test_runtime_client::runtime::Block; use assert_matches::assert_matches; -use futures::{prelude::*, channel::mpsc}; +use futures::prelude::*; +use sp_utils::mpsc::tracing_unbounded; use std::thread; struct Status { @@ -44,7 +47,7 @@ impl Default for Status { fn api>>(sync: T) -> System { let status = sync.into().unwrap_or_default(); let should_have_peers = !status.is_dev; - let (tx, rx) = mpsc::unbounded(); + let (tx, rx) = tracing_unbounded("rpc_system_tests"); thread::spawn(move || { futures::executor::block_on(rx.for_each(move |request| { match request { @@ -84,8 +87,8 @@ fn api>>(sync: T) -> System { external_addresses: Default::default(), connected_peers: Default::default(), not_connected_peers: Default::default(), - average_download_per_sec: 0, - average_upload_per_sec: 0, + total_bytes_inbound: 0, + total_bytes_outbound: 0, peerset: serde_json::Value::Null, }).unwrap()); }, @@ -279,8 +282,8 @@ fn system_network_state() { external_addresses: Default::default(), connected_peers: Default::default(), not_connected_peers: Default::default(), - average_download_per_sec: 0, - average_upload_per_sec: 0, + total_bytes_inbound: 0, + total_bytes_outbound: 0, peerset: serde_json::Value::Null, } ); diff --git a/client/rpc/src/testing.rs b/client/rpc/src/testing.rs new file mode 100644 index 0000000000000000000000000000000000000000..9530ff0020644813e481f6340d7d6eba2142da31 --- /dev/null +++ b/client/rpc/src/testing.rs @@ -0,0 +1,45 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +//! Testing utils used by the RPC tests. + +use rpc::futures::future as future01; +use futures::{executor, compat::Future01CompatExt, FutureExt}; + +// Executor shared by all tests. +// +// This shared executor is used to prevent `Too many open files` errors +// on systems with a lot of cores. +lazy_static::lazy_static! { + static ref EXECUTOR: executor::ThreadPool = executor::ThreadPool::new() + .expect("Failed to create thread pool executor for tests"); +} + +type Boxed01Future01 = Box + Send + 'static>; + +/// Executor for use in testing +pub struct TaskExecutor; +impl future01::Executor for TaskExecutor { + fn execute( + &self, + future: Boxed01Future01, + ) -> std::result::Result<(), future01::ExecuteError>{ + EXECUTOR.spawn_ok(future.compat().map(drop)); + Ok(()) + } +} diff --git a/client/service/Cargo.toml b/client/service/Cargo.toml index e5f6e229c7020f2e228cea7e1d190e3b496b0a16..fc4d3298a41d547ce8acd965ecb820e44ef73c2e 100644 --- a/client/service/Cargo.toml +++ b/client/service/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-service" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate service. Starts a thread that spins up the network, client, and extrinsic pool. Manages communication between them." @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] default = ["db"] # The RocksDB feature activates the RocksDB database backend. If it is not activated, and you pass # a path to a database, an error will be produced at runtime. -db = ["sc-client-db/kvdb-rocksdb", "sc-client-db/parity-db"] +db = ["sc-client-db/with-kvdb-rocksdb", "sc-client-db/with-parity-db"] wasmtime = [ "sc-executor/wasmtime", ] @@ -26,6 +26,8 @@ test-helpers = [] derive_more = "0.99.2" futures01 = { package = "futures", version = "0.1.29" } futures = { version = "0.3.4", features = ["compat"] } +jsonrpc-pubsub = "14.2" +jsonrpc-core = "14.2" rand = "0.7.3" parking_lot = "0.10.0" lazy_static = "1.4.0" @@ -38,52 +40,50 @@ pin-project = "0.4.8" hash-db = "0.15.2" serde = "1.0.101" serde_json = "1.0.41" -sysinfo = "0.13.3" -sc-keystore = { version = "2.0.0-dev", path = "../keystore" } -sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-trie = { version = "2.0.0-dev", path = "../../primitives/trie" } -sp-externalities = { version = "0.8.0-dev", path = "../../primitives/externalities" } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } -sp-version = { version = "2.0.0-dev", path = "../../primitives/version" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-session = { version = "2.0.0-dev", path = "../../primitives/session" } -sp-state-machine = { version = "0.8.0-dev", path = "../../primitives/state-machine" } -sp-application-crypto = { version = "2.0.0-dev", path = "../../primitives/application-crypto" } -sp-consensus = { version = "0.8.0-dev", path = "../../primitives/consensus/common" } -sc-network = { version = "0.8.0-dev", path = "../network" } -sc-chain-spec = { version = "2.0.0-dev", path = "../chain-spec" } -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } -sc-client-db = { version = "0.8.0-dev", default-features = false, path = "../db" } -codec = { package = "parity-scale-codec", version = "1.3.0" } -sc-executor = { version = "0.8.0-dev", path = "../executor" } -sc-transaction-pool = { version = "2.0.0-dev", path = "../transaction-pool" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } -sc-rpc-server = { version = "2.0.0-dev", path = "../rpc-servers" } -sc-rpc = { version = "2.0.0-dev", path = "../rpc" } -sc-block-builder = { version = "0.8.0-dev", path = "../block-builder" } -sp-block-builder = { version = "2.0.0-dev", path = "../../primitives/block-builder" } - -sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } -sc-offchain = { version = "2.0.0-dev", path = "../offchain" } -parity-multiaddr = { package = "parity-multiaddr", version = "0.7.3" } -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus" , version = "0.8.0-dev"} -sc-tracing = { version = "2.0.0-dev", path = "../tracing" } -tracing = "0.1.10" -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } - - -[target.'cfg(all(any(unix, windows), not(target_os = "android")))'.dependencies] -netstat2 = "0.8.1" - -[target.'cfg(target_os = "linux")'.dependencies] -procfs = '0.7.8' +sc-keystore = { version = "2.0.0-rc6", path = "../keystore" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-trie = { version = "2.0.0-rc6", path = "../../primitives/trie" } +sp-externalities = { version = "0.8.0-rc6", path = "../../primitives/externalities" } +sp-utils = { version = "2.0.0-rc6", path = "../../primitives/utils" } +sp-version = { version = "2.0.0-rc6", path = "../../primitives/version" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-session = { version = "2.0.0-rc6", path = "../../primitives/session" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../primitives/state-machine" } +sp-application-crypto = { version = "2.0.0-rc6", path = "../../primitives/application-crypto" } +sp-consensus = { version = "0.8.0-rc6", path = "../../primitives/consensus/common" } +sp-inherents = { version = "2.0.0-rc6", path = "../../primitives/inherents" } +sc-network = { version = "0.8.0-rc6", path = "../network" } +sc-chain-spec = { version = "2.0.0-rc6", path = "../chain-spec" } +sc-light = { version = "2.0.0-rc6", path = "../light" } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } +sc-client-db = { version = "0.8.0-rc6", default-features = false, path = "../db" } +codec = { package = "parity-scale-codec", version = "1.3.4" } +sc-executor = { version = "0.8.0-rc6", path = "../executor" } +sc-transaction-pool = { version = "2.0.0-rc6", path = "../transaction-pool" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../primitives/transaction-pool" } +sc-rpc-server = { version = "2.0.0-rc6", path = "../rpc-servers" } +sc-rpc = { version = "2.0.0-rc6", path = "../rpc" } +sc-block-builder = { version = "0.8.0-rc6", path = "../block-builder" } +sp-block-builder = { version = "2.0.0-rc6", path = "../../primitives/block-builder" } +sc-informant = { version = "0.8.0-rc2", path = "../informant" } +sc-telemetry = { version = "2.0.0-rc6", path = "../telemetry" } +sc-offchain = { version = "2.0.0-rc6", path = "../offchain" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-rc6"} +sc-tracing = { version = "2.0.0-rc6", path = "../tracing" } +tracing = "0.1.18" +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } +[target.'cfg(not(target_os = "unknown"))'.dependencies] +tempfile = "3.1.0" +directories = "2.0.2" [dev-dependencies] -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } -sp-consensus-babe = { version = "0.8.0-dev", path = "../../primitives/consensus/babe" } -grandpa = { version = "0.8.0-dev", package = "sc-finality-grandpa", path = "../finality-grandpa" } -grandpa-primitives = { version = "2.0.0-dev", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client" } +sp-consensus-babe = { version = "0.8.0-rc6", path = "../../primitives/consensus/babe" } +grandpa = { version = "0.8.0-rc6", package = "sc-finality-grandpa", path = "../finality-grandpa" } +grandpa-primitives = { version = "2.0.0-rc6", package = "sp-finality-grandpa", path = "../../primitives/finality-grandpa" } +tokio = { version = "0.2", default-features = false } +async-std = { version = "1.6", default-features = false } diff --git a/client/service/README.md b/client/service/README.md new file mode 100644 index 0000000000000000000000000000000000000000..26f940f16df02328ad03e728e2a033ce3013acc6 --- /dev/null +++ b/client/service/README.md @@ -0,0 +1,4 @@ +Substrate service. Starts a thread that spins up the network, client, and extrinsic pool. +Manages communication between them. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index b1726810945647f7d409188efc846ddba4926501..8ad95511f77d317944ccac5ac27bee2e22c431c1 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -1,105 +1,116 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . - -use crate::{Service, NetworkStatus, NetworkState, error::Error, DEFAULT_PROTOCOL_ID, MallocSizeOfWasm}; -use crate::{start_rpc_servers, build_network_future, TransactionPoolAdapter, TaskManager, SpawnTaskHandle}; -use crate::status_sinks; -use crate::config::{Configuration, KeystoreConfig, PrometheusConfig, OffchainWorkerConfig}; -use crate::metrics::MetricsService; +// along with this program. If not, see . + +use crate::{ + NetworkStatus, NetworkState, error::Error, DEFAULT_PROTOCOL_ID, MallocSizeOfWasm, + TelemetryConnectionSinks, RpcHandlers, NetworkStatusSinks, + start_rpc_servers, build_network_future, TransactionPoolAdapter, TaskManager, SpawnTaskHandle, + status_sinks, metrics::MetricsService, + client::{light, Client, ClientConfig}, + config::{Configuration, KeystoreConfig, PrometheusConfig}, +}; use sc_client_api::{ - self, BlockchainEvents, backend::RemoteBackend, light::RemoteBlockchain, execution_extensions::ExtensionsFactory, - ExecutorProvider, CallExecutor, ForkBlocks, BadBlocks, CloneableSpawn, UsageProvider, + light::RemoteBlockchain, ForkBlocks, BadBlocks, UsageProvider, ExecutorProvider, }; -use crate::client::{Client, ClientConfig}; use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender}; use sc_chain_spec::get_extension; use sp_consensus::{ - block_validation::{BlockAnnounceValidator, DefaultBlockAnnounceValidator}, + block_validation::{BlockAnnounceValidator, DefaultBlockAnnounceValidator, Chain}, import_queue::ImportQueue, }; -use futures::{ - Future, FutureExt, StreamExt, - future::ready, -}; +use futures::{FutureExt, StreamExt, future::ready, channel::oneshot}; +use jsonrpc_pubsub::manager::SubscriptionManager; use sc_keystore::Store as Keystore; use log::{info, warn, error}; use sc_network::config::{Role, FinalityProofProvider, OnDemand, BoxFinalityProofRequestBuilder}; -use sc_network::{NetworkService, NetworkStateInfo}; -use parking_lot::{Mutex, RwLock}; +use sc_network::NetworkService; +use parking_lot::RwLock; use sp_runtime::generic::BlockId; use sp_runtime::traits::{ - Block as BlockT, NumberFor, SaturatedConversion, HashFor, + Block as BlockT, SaturatedConversion, HashFor, Zero, BlockIdTo, }; -use sp_api::ProvideRuntimeApi; +use sp_api::{ProvideRuntimeApi, CallApiAt}; use sc_executor::{NativeExecutor, NativeExecutionDispatch, RuntimeInfo}; -use std::{ - collections::HashMap, - io::{Read, Write, Seek}, - marker::PhantomData, sync::Arc, pin::Pin -}; +use std::{collections::HashMap, sync::Arc}; use wasm_timer::SystemTime; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; -use sp_transaction_pool::{MaintainedTransactionPool, ChainEvent}; -use sp_blockchain; +use sp_transaction_pool::MaintainedTransactionPool; use prometheus_endpoint::Registry; use sc_client_db::{Backend, DatabaseSettings}; -use sp_core::traits::CodeExecutor; +use sp_core::traits::{CodeExecutor, SpawnNamed}; use sp_runtime::BuildStorage; -use sc_client_api::execution_extensions::ExecutionExtensions; -use sp_core::storage::Storage; - -pub type BackgroundTask = Pin + Send>>; - -/// Aggregator for the components required to build a service. -/// -/// # Usage -/// -/// Call [`ServiceBuilder::new_full`] or [`ServiceBuilder::new_light`], then call the various -/// `with_` methods to add the required components that you built yourself: -/// -/// - [`with_select_chain`](ServiceBuilder::with_select_chain) -/// - [`with_import_queue`](ServiceBuilder::with_import_queue) -/// - [`with_finality_proof_provider`](ServiceBuilder::with_finality_proof_provider) -/// - [`with_transaction_pool`](ServiceBuilder::with_transaction_pool) -/// -/// After this is done, call [`build`](ServiceBuilder::build) to construct the service. -/// -/// The order in which the `with_*` methods are called doesn't matter, as the correct binding of -/// generics is done when you call `build`. -/// -pub struct ServiceBuilder +use sc_client_api::{ + BlockBackend, BlockchainEvents, + backend::StorageProvider, + proof_provider::ProofProvider, + execution_extensions::ExecutionExtensions +}; +use sp_blockchain::{HeaderMetadata, HeaderBackend}; + +/// A utility trait for building an RPC extension given a `DenyUnsafe` instance. +/// This is useful since at service definition time we don't know whether the +/// specific interface where the RPC extension will be exposed is safe or not. +/// This trait allows us to lazily build the RPC extension whenever we bind the +/// service to an interface. +pub trait RpcExtensionBuilder { + /// The type of the RPC extension that will be built. + type Output: sc_rpc::RpcExtension; + + /// Returns an instance of the RPC extension for a particular `DenyUnsafe` + /// value, e.g. the RPC extension might not expose some unsafe methods. + fn build(&self, deny: sc_rpc::DenyUnsafe, subscriptions: SubscriptionManager) -> Self::Output; +} + +impl RpcExtensionBuilder for F where + F: Fn(sc_rpc::DenyUnsafe, SubscriptionManager) -> R, + R: sc_rpc::RpcExtension, { - config: Configuration, - pub (crate) client: Arc, - backend: Arc, - task_manager: TaskManager, - keystore: Arc>, - fetcher: Option, - select_chain: Option, - pub (crate) import_queue: TImpQu, - finality_proof_request_builder: Option, - finality_proof_provider: Option, - transaction_pool: Arc, - rpc_extensions: TRpc, - remote_backend: Option>>, - marker: PhantomData<(TBl, TRtApi)>, - block_announce_validator_builder: Option) -> Box + Send> + Send>>, + type Output = R; + + fn build(&self, deny: sc_rpc::DenyUnsafe, subscriptions: SubscriptionManager) -> Self::Output { + (*self)(deny, subscriptions) + } } +/// A utility struct for implementing an `RpcExtensionBuilder` given a cloneable +/// `RpcExtension`, the resulting builder will simply ignore the provided +/// `DenyUnsafe` instance and return a static `RpcExtension` instance. +pub struct NoopRpcExtensionBuilder(pub R); + +impl RpcExtensionBuilder for NoopRpcExtensionBuilder where + R: Clone + sc_rpc::RpcExtension, +{ + type Output = R; + + fn build(&self, _deny: sc_rpc::DenyUnsafe, _subscriptions: SubscriptionManager) -> Self::Output { + self.0.clone() + } +} + +impl From for NoopRpcExtensionBuilder where + R: sc_rpc::RpcExtension, +{ + fn from(e: R) -> NoopRpcExtensionBuilder { + NoopRpcExtensionBuilder(e) + } +} + + /// Full client type. pub type TFullClient = Client< TFullBackend, @@ -118,27 +129,24 @@ pub type TFullCallExecutor = crate::client::LocalCallExecutor< >; /// Light client type. -pub type TLightClient = Client< - TLightBackend, - TLightCallExecutor, - TBl, - TRtApi, +pub type TLightClient = TLightClientWithBackend< + TBl, TRtApi, TExecDisp, TLightBackend >; /// Light client backend type. -pub type TLightBackend = crate::client::light::backend::Backend< +pub type TLightBackend = sc_light::Backend< sc_client_db::light::LightStorage, HashFor, >; /// Light call executor type. -pub type TLightCallExecutor = crate::client::light::call_executor::GenesisCallExecutor< - crate::client::light::backend::Backend< +pub type TLightCallExecutor = sc_light::GenesisCallExecutor< + sc_light::Backend< sc_client_db::light::LightStorage, HashFor >, crate::client::LocalCallExecutor< - crate::client::light::backend::Backend< + sc_light::Backend< sc_client_db::light::LightStorage, HashFor >, @@ -153,6 +161,31 @@ type TFullParts = ( TaskManager, ); +type TLightParts = ( + Arc>, + Arc>, + Arc>, + TaskManager, + Arc>, +); + +/// Light client backend type with a specific hash type. +pub type TLightBackendWithHash = sc_light::Backend< + sc_client_db::light::LightStorage, + THash, +>; + +/// Light client type with a specific backend. +pub type TLightClientWithBackend = Client< + TBackend, + sc_light::GenesisCallExecutor< + TBackend, + crate::client::LocalCallExecutor>, + >, + TBl, + TRtApi, +>; + /// Creates a new full client for the given config. pub fn new_full_client( config: &Configuration, @@ -163,7 +196,8 @@ pub fn new_full_client( new_full_parts(config).map(|parts| parts.0) } -fn new_full_parts( +/// Create the initial parts of a full node. +pub fn new_full_parts( config: &Configuration, ) -> Result, Error> where TBl: BlockT, @@ -230,6 +264,63 @@ fn new_full_parts( Ok((client, backend, keystore, task_manager)) } +/// Create the initial parts of a light node. +pub fn new_light_parts( + config: &Configuration +) -> Result, Error> where + TBl: BlockT, + TExecDisp: NativeExecutionDispatch + 'static, +{ + + let task_manager = { + let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); + TaskManager::new(config.task_executor.clone(), registry)? + }; + + let keystore = match &config.keystore { + KeystoreConfig::Path { path, password } => Keystore::open( + path.clone(), + password.clone() + )?, + KeystoreConfig::InMemory => Keystore::new_in_memory(), + }; + + let executor = NativeExecutor::::new( + config.wasm_method, + config.default_heap_pages, + config.max_runtime_instances, + ); + + let db_storage = { + let db_settings = sc_client_db::DatabaseSettings { + state_cache_size: config.state_cache_size, + state_cache_child_ratio: + config.state_cache_child_ratio.map(|v| (v, 100)), + pruning: config.pruning.clone(), + source: config.database.clone(), + }; + sc_client_db::light::LightStorage::new(db_settings)? + }; + let light_blockchain = sc_light::new_light_blockchain(db_storage); + let fetch_checker = Arc::new( + sc_light::new_fetch_checker::<_, TBl, _>( + light_blockchain.clone(), + executor.clone(), + Box::new(task_manager.spawn_handle()), + ), + ); + let on_demand = Arc::new(sc_network::config::OnDemand::new(fetch_checker)); + let backend = sc_light::new_light_backend(light_blockchain); + let client = Arc::new(light::new_light( + backend.clone(), + config.chain_spec.as_storage_builder(), + executor, + Box::new(task_manager.spawn_handle()), + config.prometheus_config.as_ref().map(|config| config.registry.clone()), + )?); + + Ok((client, backend, keystore, task_manager, on_demand)) +} /// Create an instance of db-backed client. pub fn new_client( @@ -239,7 +330,7 @@ pub fn new_client( fork_blocks: ForkBlocks, bad_blocks: BadBlocks, execution_extensions: ExecutionExtensions, - spawn_handle: Box, + spawn_handle: Box, prometheus_registry: Option, config: ClientConfig, ) -> Result<( @@ -276,987 +367,589 @@ pub fn new_client( )) } -impl ServiceBuilder<(), (), (), (), (), (), (), (), (), (), ()> { - /// Start the service builder with a configuration. - pub fn new_full( - config: Configuration, - ) -> Result, - Arc>, - (), - (), - BoxFinalityProofRequestBuilder, - Arc>, - (), - (), - TFullBackend, - >, Error> { - let (client, backend, keystore, task_manager) = new_full_parts(&config)?; - - let client = Arc::new(client); - - Ok(ServiceBuilder { - config, - client, - backend, - keystore, - task_manager, - fetcher: None, - select_chain: None, - import_queue: (), - finality_proof_request_builder: None, - finality_proof_provider: None, - transaction_pool: Arc::new(()), - rpc_extensions: Default::default(), - remote_backend: None, - block_announce_validator_builder: None, - marker: PhantomData, - }) - } - - /// Start the service builder with a configuration. - pub fn new_light( - config: Configuration, - ) -> Result, - Arc>, - (), - (), - BoxFinalityProofRequestBuilder, - Arc>, - (), - (), - TLightBackend, - >, Error> { - let task_manager = { - let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); - TaskManager::new(config.task_executor.clone(), registry)? - }; - - let keystore = match &config.keystore { - KeystoreConfig::Path { path, password } => Keystore::open( - path.clone(), - password.clone() - )?, - KeystoreConfig::InMemory => Keystore::new_in_memory(), - }; +/// Parameters to pass into `build`. +pub struct SpawnTasksParams<'a, TBl: BlockT, TCl, TExPool, TRpc, Backend> { + /// The service configuration. + pub config: Configuration, + /// A shared client returned by `new_full_parts`/`new_light_parts`. + pub client: Arc, + /// A shared backend returned by `new_full_parts`/`new_light_parts`. + pub backend: Arc, + /// A task manager returned by `new_full_parts`/`new_light_parts`. + pub task_manager: &'a mut TaskManager, + /// A shared keystore returned by `new_full_parts`/`new_light_parts`. + pub keystore: Arc>, + /// An optional, shared data fetcher for light clients. + pub on_demand: Option>>, + /// A shared transaction pool. + pub transaction_pool: Arc, + /// A RPC extension builder. Use `NoopRpcExtensionBuilder` if you just want to pass in the + /// extensions directly. + pub rpc_extensions_builder: Box + Send>, + /// An optional, shared remote blockchain instance. Used for light clients. + pub remote_blockchain: Option>>, + /// A shared network instance. + pub network: Arc::Hash>>, + /// Sinks to propagate network status updates. + pub network_status_sinks: NetworkStatusSinks, + /// A Sender for RPC requests. + pub system_rpc_tx: TracingUnboundedSender>, + /// Shared Telemetry connection sinks, + pub telemetry_connection_sinks: TelemetryConnectionSinks, +} - let executor = NativeExecutor::::new( - config.wasm_method, - config.default_heap_pages, - config.max_runtime_instances, - ); +/// Build a shared offchain workers instance. +pub fn build_offchain_workers( + config: &Configuration, + backend: Arc, + spawn_handle: SpawnTaskHandle, + client: Arc, + network: Arc::Hash>>, +) -> Option>> + where + TBl: BlockT, TBackend: sc_client_api::Backend, + >::OffchainStorage: 'static, + TCl: Send + Sync + ProvideRuntimeApi + BlockchainEvents + 'static, + >::Api: sc_offchain::OffchainWorkerApi, +{ + let offchain_workers = match backend.offchain_storage() { + Some(db) => { + Some(Arc::new(sc_offchain::OffchainWorkers::new(client.clone(), db))) + }, + None => { + warn!("Offchain workers disabled, due to lack of offchain storage support in backend."); + None + }, + }; - let db_storage = { - let db_settings = sc_client_db::DatabaseSettings { - state_cache_size: config.state_cache_size, - state_cache_child_ratio: - config.state_cache_child_ratio.map(|v| (v, 100)), - pruning: config.pruning.clone(), - source: config.database.clone(), - }; - sc_client_db::light::LightStorage::new(db_settings)? - }; - let light_blockchain = crate::client::light::new_light_blockchain(db_storage); - let fetch_checker = Arc::new( - crate::client::light::new_fetch_checker::<_, TBl, _>( - light_blockchain.clone(), - executor.clone(), - Box::new(task_manager.spawn_handle()), - ), + // Inform the offchain worker about new imported blocks + if let Some(offchain) = offchain_workers.clone() { + spawn_handle.spawn( + "offchain-notifications", + sc_offchain::notification_future( + config.role.is_authority(), + client.clone(), + offchain, + Clone::clone(&spawn_handle), + network.clone() + ) ); - let fetcher = Arc::new(sc_network::config::OnDemand::new(fetch_checker)); - let backend = crate::client::light::new_light_backend(light_blockchain); - let remote_blockchain = backend.remote_blockchain(); - let client = Arc::new(crate::client::light::new_light( - backend.clone(), - config.chain_spec.as_storage_builder(), - executor, - Box::new(task_manager.spawn_handle()), - config.prometheus_config.as_ref().map(|config| config.registry.clone()), - )?); - - Ok(ServiceBuilder { - config, - client, - backend, - task_manager, - keystore, - fetcher: Some(fetcher.clone()), - select_chain: None, - import_queue: (), - finality_proof_request_builder: None, - finality_proof_provider: None, - transaction_pool: Arc::new(()), - rpc_extensions: Default::default(), - remote_backend: Some(remote_blockchain), - block_announce_validator_builder: None, - marker: PhantomData, - }) } -} - -impl - ServiceBuilder { - /// Returns a reference to the client that was stored in this builder. - pub fn client(&self) -> &Arc { - &self.client - } + offchain_workers +} - /// Returns a reference to the backend that was used in this builder. - pub fn backend(&self) -> &Arc { - &self.backend - } +/// Spawn the tasks that are required to run a node. +pub fn spawn_tasks( + params: SpawnTasksParams, +) -> Result + where + TCl: ProvideRuntimeApi + HeaderMetadata + Chain + + BlockBackend + BlockIdTo + ProofProvider + + HeaderBackend + BlockchainEvents + ExecutorProvider + UsageProvider + + StorageProvider + CallApiAt + + Send + 'static, + >::Api: + sp_api::Metadata + + sc_offchain::OffchainWorkerApi + + sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_session::SessionKeys + + sp_api::ApiErrorExt + + sp_api::ApiExt, + TBl: BlockT, + TBackend: 'static + sc_client_api::backend::Backend + Send, + TExPool: MaintainedTransactionPool::Hash> + + MallocSizeOfWasm + 'static, + TRpc: sc_rpc::RpcExtension +{ + let SpawnTasksParams { + mut config, + task_manager, + client, + on_demand, + backend, + keystore, + transaction_pool, + rpc_extensions_builder, + remote_blockchain, + network, network_status_sinks, system_rpc_tx, + telemetry_connection_sinks, + } = params; + + let chain_info = client.usage_info().chain; + + sp_session::generate_initial_session_keys( + client.clone(), + &BlockId::Hash(chain_info.best_hash), + config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default(), + )?; + + info!("📦 Highest known block at #{}", chain_info.best_number); + telemetry!( + SUBSTRATE_INFO; + "node.start"; + "height" => chain_info.best_number.saturated_into::(), + "best" => ?chain_info.best_hash + ); - /// Returns a reference to the select-chain that was stored in this builder. - pub fn select_chain(&self) -> Option<&TSc> { - self.select_chain.as_ref() - } + let spawn_handle = task_manager.spawn_handle(); - /// Returns a reference to the keystore - pub fn keystore(&self) -> Arc> { - self.keystore.clone() - } + // Inform the tx pool about imported and finalized blocks. + spawn_handle.spawn( + "txpool-notifications", + sc_transaction_pool::notification_future(client.clone(), transaction_pool.clone()), + ); - /// Returns a reference to the transaction pool stored in this builder - pub fn pool(&self) -> Arc { - self.transaction_pool.clone() - } + spawn_handle.spawn( + "on-transaction-imported", + transaction_notifications(transaction_pool.clone(), network.clone()), + ); - /// Returns a reference to the fetcher, only available if builder - /// was created with `new_light`. - pub fn fetcher(&self) -> Option - where TFchr: Clone + // Prometheus metrics. + let metrics_service = if let Some(PrometheusConfig { port, registry }) = + config.prometheus_config.clone() { - self.fetcher.clone() - } - - /// Returns a reference to the remote_backend, only available if builder - /// was created with `new_light`. - pub fn remote_backend(&self) -> Option>> { - self.remote_backend.clone() - } - - /// Defines which head-of-chain strategy to use. - pub fn with_opt_select_chain( - self, - select_chain_builder: impl FnOnce( - &Configuration, &Arc, - ) -> Result, Error> - ) -> Result, Error> { - let select_chain = select_chain_builder(&self.config, &self.backend)?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions: self.rpc_extensions, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } + // Set static metrics. + let metrics = MetricsService::with_prometheus(®istry, &config)?; + spawn_handle.spawn( + "prometheus-endpoint", + prometheus_endpoint::init_prometheus(port, registry).map(drop) + ); - /// Defines which head-of-chain strategy to use. - pub fn with_select_chain( - self, - builder: impl FnOnce(&Configuration, &Arc) -> Result, - ) -> Result, Error> { - self.with_opt_select_chain(|cfg, b| builder(cfg, b).map(Option::Some)) - } + metrics + } else { + MetricsService::new() + }; - /// Defines which import queue to use. - pub fn with_import_queue( - self, - builder: impl FnOnce(&Configuration, Arc, Option, Arc, &SpawnTaskHandle) - -> Result - ) -> Result, Error> - where TSc: Clone { - let import_queue = builder( - &self.config, - self.client.clone(), - self.select_chain.clone(), - self.transaction_pool.clone(), - &self.task_manager.spawn_handle(), - )?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions: self.rpc_extensions, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } + // Periodically notify the telemetry. + spawn_handle.spawn("telemetry-periodic-send", telemetry_periodic_send( + client.clone(), transaction_pool.clone(), metrics_service, network_status_sinks.clone() + )); - /// Defines which strategy to use for providing finality proofs. - pub fn with_opt_finality_proof_provider( - self, - builder: impl FnOnce(Arc, Arc) -> Result>>, Error> - ) -> Result>, - TExPool, - TRpc, - Backend, - >, Error> { - let finality_proof_provider = builder(self.client.clone(), self.backend.clone())?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions: self.rpc_extensions, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } + // Periodically send the network state to the telemetry. + spawn_handle.spawn( + "telemetry-periodic-network-state", + telemetry_periodic_network_state(network_status_sinks.clone()), + ); - /// Defines which strategy to use for providing finality proofs. - pub fn with_finality_proof_provider( - self, - build: impl FnOnce(Arc, Arc) -> Result>, Error> - ) -> Result>, - TExPool, - TRpc, - Backend, - >, Error> { - self.with_opt_finality_proof_provider(|client, backend| build(client, backend).map(Option::Some)) - } + // RPC + let gen_handler = |deny_unsafe: sc_rpc::DenyUnsafe| gen_handler( + deny_unsafe, &config, task_manager.spawn_handle(), client.clone(), transaction_pool.clone(), + keystore.clone(), on_demand.clone(), remote_blockchain.clone(), &*rpc_extensions_builder, + backend.offchain_storage(), system_rpc_tx.clone() + ); + let rpc = start_rpc_servers(&config, gen_handler)?; + // This is used internally, so don't restrict access to unsafe RPC + let rpc_handlers = RpcHandlers(Arc::new(gen_handler(sc_rpc::DenyUnsafe::No).into())); + + // Telemetry + let telemetry = config.telemetry_endpoints.clone().and_then(|endpoints| { + if endpoints.is_empty() { + // we don't want the telemetry to be initialized if telemetry_endpoints == Some([]) + return None; + } - /// Defines which import queue to use. - pub fn with_import_queue_and_opt_fprb( - self, - builder: impl FnOnce( - &Configuration, - Arc, - Arc, - Option, - Option, - Arc, - &SpawnTaskHandle, - ) -> Result<(UImpQu, Option), Error> - ) -> Result, Error> - where TSc: Clone, TFchr: Clone { - let (import_queue, fprb) = builder( - &self.config, - self.client.clone(), - self.backend.clone(), - self.fetcher.clone(), - self.select_chain.clone(), - self.transaction_pool.clone(), - &self.task_manager.spawn_handle(), - )?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue, - finality_proof_request_builder: fprb, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions: self.rpc_extensions, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } + let genesis_hash = match client.block_hash(Zero::zero()) { + Ok(Some(hash)) => hash, + _ => Default::default(), + }; - /// Defines which import queue to use. - pub fn with_import_queue_and_fprb( - self, - builder: impl FnOnce( - &Configuration, - Arc, - Arc, - Option, - Option, - Arc, - &SpawnTaskHandle, - ) -> Result<(UImpQu, UFprb), Error> - ) -> Result, Error> - where TSc: Clone, TFchr: Clone { - self.with_import_queue_and_opt_fprb(|cfg, cl, b, f, sc, tx, tb| - builder(cfg, cl, b, f, sc, tx, tb) - .map(|(q, f)| (q, Some(f))) - ) - } + Some(build_telemetry( + &mut config, endpoints, telemetry_connection_sinks.clone(), network.clone(), + task_manager.spawn_handle(), genesis_hash, + )) + }); - /// Defines which transaction pool to use. - pub fn with_transaction_pool( - self, - transaction_pool_builder: impl FnOnce( - sc_transaction_pool::txpool::Options, - Arc, - Option, - Option<&Registry>, - ) -> Result<(UExPool, Option), Error> - ) -> Result, Error> - where TSc: Clone, TFchr: Clone { - let (transaction_pool, background_task) = transaction_pool_builder( - self.config.transaction_pool.clone(), - self.client.clone(), - self.fetcher.clone(), - self.config.prometheus_config.as_ref().map(|config| &config.registry), - )?; - - if let Some(background_task) = background_task{ - self.task_manager.spawn_handle().spawn("txpool-background", background_task); + // Instrumentation + if let Some(tracing_targets) = config.tracing_targets.as_ref() { + let subscriber = sc_tracing::ProfilingSubscriber::new( + config.tracing_receiver, tracing_targets + ); + match tracing::subscriber::set_global_default(subscriber) { + Ok(_) => (), + Err(e) => error!(target: "tracing", "Unable to set global default subscriber {}", e), } - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - task_manager: self.task_manager, - backend: self.backend, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: Arc::new(transaction_pool), - rpc_extensions: self.rpc_extensions, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) } - /// Defines the RPC extensions to use. - pub fn with_rpc_extensions( - self, - rpc_ext_builder: impl FnOnce(&Self) -> Result, - ) -> Result, Error> - where TSc: Clone, TFchr: Clone { - let rpc_extensions = rpc_ext_builder(&self)?; - - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions, - remote_backend: self.remote_backend, - block_announce_validator_builder: self.block_announce_validator_builder, - marker: self.marker, - }) - } + // Spawn informant task + spawn_handle.spawn("informant", sc_informant::build( + client.clone(), + network_status_sinks.clone().0, + transaction_pool.clone(), + config.informant_output_format, + )); - /// Defines the `BlockAnnounceValidator` to use. `DefaultBlockAnnounceValidator` will be used by - /// default. - pub fn with_block_announce_validator( - self, - block_announce_validator_builder: - impl FnOnce(Arc) -> Box + Send> + Send + 'static, - ) -> Result, Error> - where TSc: Clone, TFchr: Clone { - Ok(ServiceBuilder { - config: self.config, - client: self.client, - backend: self.backend, - task_manager: self.task_manager, - keystore: self.keystore, - fetcher: self.fetcher, - select_chain: self.select_chain, - import_queue: self.import_queue, - finality_proof_request_builder: self.finality_proof_request_builder, - finality_proof_provider: self.finality_proof_provider, - transaction_pool: self.transaction_pool, - rpc_extensions: self.rpc_extensions, - remote_backend: self.remote_backend, - block_announce_validator_builder: Some(Box::new(block_announce_validator_builder)), - marker: self.marker, - }) - } -} + task_manager.keep_alive((telemetry, config.base_path, rpc, rpc_handlers.clone())); -/// Implemented on `ServiceBuilder`. Allows running block commands, such as import/export/validate -/// components to the builder. -pub trait ServiceBuilderCommand { - /// Block type this API operates on. - type Block: BlockT; - /// Native execution dispatch required by some commands. - type NativeDispatch: NativeExecutionDispatch + 'static; - /// Starts the process of importing blocks. - fn import_blocks( - self, - input: impl Read + Seek + Send + 'static, - force: bool, - ) -> Pin> + Send>>; - - /// Performs the blocks export. - fn export_blocks( - self, - output: impl Write + 'static, - from: NumberFor, - to: Option>, - binary: bool - ) -> Pin>>>; - - /// Performs a revert of `blocks` blocks. - fn revert_chain( - &self, - blocks: NumberFor - ) -> Result<(), Error>; - - /// Re-validate known block. - fn check_block( - self, - block: BlockId - ) -> Pin> + Send>>; - - /// Export the raw state at the given `block`. If `block` is `None`, the - /// best block will be used. - fn export_raw_state( - &self, - block: Option>, - ) -> Result; + Ok(rpc_handlers) } -impl -ServiceBuilder< - TBl, - TRtApi, - Client, - Arc>, - TSc, - TImpQu, - BoxFinalityProofRequestBuilder, - Arc>, - TExPool, - TRpc, - TBackend, -> where - Client: ProvideRuntimeApi, - as ProvideRuntimeApi>::Api: - sp_api::Metadata + - sc_offchain::OffchainWorkerApi + - sp_transaction_pool::runtime_api::TaggedTransactionQueue + - sp_session::SessionKeys + - sp_api::ApiErrorExt + - sp_api::ApiExt, - TBl: BlockT, - TRtApi: 'static + Send + Sync, - TBackend: 'static + sc_client_api::backend::Backend + Send, - TExec: 'static + CallExecutor + Send + Sync + Clone, - TSc: Clone, - TImpQu: 'static + ImportQueue, - TExPool: MaintainedTransactionPool::Hash> + MallocSizeOfWasm + 'static, - TRpc: sc_rpc::RpcExtension + Clone, +async fn transaction_notifications( + transaction_pool: Arc, + network: Arc::Hash>> +) + where + TBl: BlockT, + TExPool: MaintainedTransactionPool::Hash>, { + // transaction notifications + transaction_pool.import_notification_stream() + .for_each(move |hash| { + network.propagate_transaction(hash); + let status = transaction_pool.status(); + telemetry!(SUBSTRATE_INFO; "txpool.import"; + "ready" => status.ready, + "future" => status.future + ); + ready(()) + }) + .await; +} - /// Set an ExecutionExtensionsFactory - pub fn with_execution_extensions_factory(self, execution_extensions_factory: Box) -> Result { - self.client.execution_extensions().set_extensions_factory(execution_extensions_factory); - Ok(self) - } - - /// Builds the service. - pub fn build(self) -> Result, - TSc, - NetworkStatus, - NetworkService::Hash>, - TExPool, - sc_offchain::OffchainWorkers< - Client, - TBackend::OffchainStorage, - TBl - >, - >, Error> - where TExec: CallExecutor, - { - let ServiceBuilder { - marker: _, - mut config, - client, - task_manager, - fetcher: on_demand, - backend, - keystore, - select_chain, - import_queue, - finality_proof_request_builder, - finality_proof_provider, - transaction_pool, - rpc_extensions, - remote_backend, - block_announce_validator_builder, - } = self; - - sp_session::generate_initial_session_keys( - client.clone(), - &BlockId::Hash(client.chain_info().best_hash), - config.dev_key_seed.clone().map(|s| vec![s]).unwrap_or_default(), - )?; - - // A side-channel for essential tasks to communicate shutdown. - let (essential_failed_tx, essential_failed_rx) = tracing_unbounded("mpsc_essential_tasks"); - - let import_queue = Box::new(import_queue); - let chain_info = client.chain_info(); - let chain_spec = &config.chain_spec; +// Periodically notify the telemetry. +async fn telemetry_periodic_send( + client: Arc, + transaction_pool: Arc, + mut metrics_service: MetricsService, + network_status_sinks: NetworkStatusSinks, +) + where + TBl: BlockT, + TCl: ProvideRuntimeApi + UsageProvider, + TExPool: MaintainedTransactionPool::Hash>, +{ + let (state_tx, state_rx) = tracing_unbounded::<(NetworkStatus<_>, NetworkState)>("mpsc_netstat1"); + network_status_sinks.0.push(std::time::Duration::from_millis(5000), state_tx); + state_rx.for_each(move |(net_status, _)| { + let info = client.usage_info(); + metrics_service.tick( + &info, + &transaction_pool.status(), + &net_status, + ); + ready(()) + }).await; +} - let version = config.impl_version; - info!("📦 Highest known block at #{}", chain_info.best_number); +async fn telemetry_periodic_network_state( + network_status_sinks: NetworkStatusSinks, +) { + // Periodically send the network state to the telemetry. + let (netstat_tx, netstat_rx) = tracing_unbounded::<(NetworkStatus<_>, NetworkState)>("mpsc_netstat2"); + network_status_sinks.0.push(std::time::Duration::from_secs(30), netstat_tx); + netstat_rx.for_each(move |(_, network_state)| { telemetry!( SUBSTRATE_INFO; - "node.start"; - "height" => chain_info.best_number.saturated_into::(), - "best" => ?chain_info.best_hash + "system.network_state"; + "state" => network_state, ); + ready(()) + }).await; +} - // make transaction pool available for off-chain runtime calls. - client.execution_extensions() - .register_transaction_pool(Arc::downgrade(&transaction_pool) as _); - - let transaction_pool_adapter = Arc::new(TransactionPoolAdapter { - imports_external_transactions: !matches!(config.role, Role::Light), - pool: transaction_pool.clone(), - client: client.clone(), - }); - - let protocol_id = { - let protocol_id_full = match chain_spec.protocol_id() { - Some(pid) => pid, - None => { - warn!("Using default protocol ID {:?} because none is configured in the \ - chain specs", DEFAULT_PROTOCOL_ID - ); - DEFAULT_PROTOCOL_ID - } - }.as_bytes(); - sc_network::config::ProtocolId::from(protocol_id_full) - }; - - let block_announce_validator = if let Some(f) = block_announce_validator_builder { - f(client.clone()) - } else { - Box::new(DefaultBlockAnnounceValidator::new(client.clone())) - }; - - let network_params = sc_network::config::Params { - role: config.role.clone(), - executor: { - let spawn_handle = task_manager.spawn_handle(); - Some(Box::new(move |fut| { - spawn_handle.spawn("libp2p-node", fut); - })) - }, - network_config: config.network.clone(), - chain: client.clone(), - finality_proof_provider, - finality_proof_request_builder, - on_demand: on_demand.clone(), - transaction_pool: transaction_pool_adapter.clone() as _, - import_queue, - protocol_id, - block_announce_validator, - metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()) - }; - - let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); - let network_mut = sc_network::NetworkWorker::new(network_params)?; - let network = network_mut.service().clone(); - let network_status_sinks = Arc::new(Mutex::new(status_sinks::StatusSinks::new())); - - let offchain_storage = backend.offchain_storage(); - let offchain_workers = match (config.offchain_worker.clone(), offchain_storage.clone()) { - (OffchainWorkerConfig {enabled: true, .. }, Some(db)) => { - Some(Arc::new(sc_offchain::OffchainWorkers::new(client.clone(), db))) - }, - (OffchainWorkerConfig {enabled: true, .. }, None) => { - warn!("Offchain workers disabled, due to lack of offchain storage support in backend."); - None - }, - _ => None, - }; +fn build_telemetry( + config: &mut Configuration, + endpoints: sc_telemetry::TelemetryEndpoints, + telemetry_connection_sinks: TelemetryConnectionSinks, + network: Arc::Hash>>, + spawn_handle: SpawnTaskHandle, + genesis_hash: ::Hash, +) -> sc_telemetry::Telemetry { + let is_authority = config.role.is_authority(); + let network_id = network.local_peer_id().to_base58(); + let name = config.network.node_name.clone(); + let impl_name = config.impl_name.clone(); + let impl_version = config.impl_version.clone(); + let chain_name = config.chain_spec.name().to_owned(); + let telemetry = sc_telemetry::init_telemetry(sc_telemetry::TelemetryConfig { + endpoints, + wasm_external_transport: config.telemetry_external_transport.take(), + }); + let startup_time = SystemTime::UNIX_EPOCH.elapsed() + .map(|dur| dur.as_millis()) + .unwrap_or(0); + + spawn_handle.spawn( + "telemetry-worker", + telemetry.clone() + .for_each(move |event| { + // Safe-guard in case we add more events in the future. + let sc_telemetry::TelemetryEvent::Connected = event; + + telemetry!(SUBSTRATE_INFO; "system.connected"; + "name" => name.clone(), + "implementation" => impl_name.clone(), + "version" => impl_version.clone(), + "config" => "", + "chain" => chain_name.clone(), + "genesis_hash" => ?genesis_hash, + "authority" => is_authority, + "startup_time" => startup_time, + "network_id" => network_id.clone() + ); - let spawn_handle = task_manager.spawn_handle(); - - { - // block notifications - let txpool = Arc::downgrade(&transaction_pool); - let offchain = offchain_workers.as_ref().map(Arc::downgrade); - let notifications_spawn_handle = task_manager.spawn_handle(); - let network_state_info: Arc = network.clone(); - let is_validator = config.role.is_authority(); - - let (import_stream, finality_stream) = ( - client.import_notification_stream().map(|n| ChainEvent::NewBlock { - id: BlockId::Hash(n.hash), - header: n.header, - retracted: n.retracted, - is_new_best: n.is_new_best, - }), - client.finality_notification_stream().map(|n| ChainEvent::Finalized { - hash: n.hash - }) - ); - let events = futures::stream::select(import_stream, finality_stream) - .for_each(move |event| { - // offchain worker is only interested in block import events - if let ChainEvent::NewBlock { ref header, is_new_best, .. } = event { - let offchain = offchain.as_ref().and_then(|o| o.upgrade()); - match offchain { - Some(offchain) if is_new_best => { - notifications_spawn_handle.spawn( - "offchain-on-block", - offchain.on_block_imported( - &header, - network_state_info.clone(), - is_validator, - ), - ); - }, - Some(_) => log::debug!( - target: "sc_offchain", - "Skipping offchain workers for non-canon block: {:?}", - header, - ), - _ => {}, - } - }; - - let txpool = txpool.upgrade(); - if let Some(txpool) = txpool.as_ref() { - notifications_spawn_handle.spawn( - "txpool-maintain", - txpool.maintain(event), - ); - } - - ready(()) + telemetry_connection_sinks.0.lock().retain(|sink| { + sink.unbounded_send(()).is_ok() }); + ready(()) + }) + ); - spawn_handle.spawn( - "txpool-and-offchain-notif", - events, - ); - } - - { - // extrinsic notifications - let network = Arc::downgrade(&network); - let transaction_pool_ = transaction_pool.clone(); - let events = transaction_pool.import_notification_stream() - .for_each(move |hash| { - if let Some(network) = network.upgrade() { - network.propagate_extrinsic(hash); - } - let status = transaction_pool_.status(); - telemetry!(SUBSTRATE_INFO; "txpool.import"; - "ready" => status.ready, - "future" => status.future - ); - ready(()) - }); + telemetry +} - spawn_handle.spawn( - "on-transaction-imported", - events, - ); - } +fn gen_handler( + deny_unsafe: sc_rpc::DenyUnsafe, + config: &Configuration, + spawn_handle: SpawnTaskHandle, + client: Arc, + transaction_pool: Arc, + keystore: Arc>, + on_demand: Option>>, + remote_blockchain: Option>>, + rpc_extensions_builder: &(dyn RpcExtensionBuilder + Send), + offchain_storage: Option<>::OffchainStorage>, + system_rpc_tx: TracingUnboundedSender> +) -> jsonrpc_pubsub::PubSubHandler + where + TBl: BlockT, + TCl: ProvideRuntimeApi + BlockchainEvents + HeaderBackend + + HeaderMetadata + ExecutorProvider + + CallApiAt + ProofProvider + + StorageProvider + BlockBackend + Send + Sync + 'static, + TExPool: MaintainedTransactionPool::Hash> + 'static, + TBackend: sc_client_api::backend::Backend + 'static, + TRpc: sc_rpc::RpcExtension, + >::Api: + sp_session::SessionKeys + + sp_api::Metadata, +{ + use sc_rpc::{chain, state, author, system, offchain}; + + let system_info = sc_rpc::system::SystemInfo { + chain_name: config.chain_spec.name().into(), + impl_name: config.impl_name.clone(), + impl_version: config.impl_version.clone(), + properties: config.chain_spec.properties(), + chain_type: config.chain_spec.chain_type(), + }; - // Prometheus metrics. - let mut metrics_service = if let Some(PrometheusConfig { port, registry }) = config.prometheus_config.clone() { - // Set static metrics. - - - let role_bits = match config.role { - Role::Full => 1u64, - Role::Light => 2u64, - Role::Sentry { .. } => 3u64, - Role::Authority { .. } => 4u64, - }; - let metrics = MetricsService::with_prometheus( - ®istry, - &config.network.node_name, - &config.impl_version, - role_bits, - )?; - spawn_handle.spawn( - "prometheus-endpoint", - prometheus_endpoint::init_prometheus(port, registry).map(drop) - ); + let task_executor = sc_rpc::SubscriptionTaskExecutor::new(spawn_handle); + let subscriptions = SubscriptionManager::new(Arc::new(task_executor)); - metrics - } else { - MetricsService::new() - }; + let (chain, state, child_state) = if let (Some(remote_blockchain), Some(on_demand)) = + (remote_blockchain, on_demand) { + // Light clients + let chain = sc_rpc::chain::new_light( + client.clone(), + subscriptions.clone(), + remote_blockchain.clone(), + on_demand.clone(), + ); + let (state, child_state) = sc_rpc::state::new_light( + client.clone(), + subscriptions.clone(), + remote_blockchain.clone(), + on_demand, + ); + (chain, state, child_state) - // Periodically notify the telemetry. - let transaction_pool_ = transaction_pool.clone(); - let client_ = client.clone(); - let (state_tx, state_rx) = tracing_unbounded::<(NetworkStatus<_>, NetworkState)>("mpsc_netstat1"); - network_status_sinks.lock().push(std::time::Duration::from_millis(5000), state_tx); - let tel_task = state_rx.for_each(move |(net_status, _)| { - let info = client_.usage_info(); - metrics_service.tick( - &info, - &transaction_pool_.status(), - &net_status, - ); - ready(()) - }); + } else { + // Full nodes + let chain = sc_rpc::chain::new_full(client.clone(), subscriptions.clone()); + let (state, child_state) = sc_rpc::state::new_full(client.clone(), subscriptions.clone()); + (chain, state, child_state) + }; - spawn_handle.spawn( - "telemetry-periodic-send", - tel_task, - ); + let author = sc_rpc::author::Author::new( + client, + transaction_pool, + subscriptions.clone(), + keystore, + deny_unsafe, + ); + let system = system::System::new(system_info, system_rpc_tx, deny_unsafe); + + let maybe_offchain_rpc = offchain_storage + .map(|storage| { + let offchain = sc_rpc::offchain::Offchain::new(storage, deny_unsafe); + // FIXME: Use plain Option (don't collect into HashMap) when we upgrade to jsonrpc 14.1 + // https://github.com/paritytech/jsonrpc/commit/20485387ed06a48f1a70bf4d609a7cde6cf0accf + let delegate = offchain::OffchainApi::to_delegate(offchain); + delegate.into_iter().collect::>() + }).unwrap_or_default(); + + sc_rpc_server::rpc_handler(( + state::StateApi::to_delegate(state), + state::ChildStateApi::to_delegate(child_state), + chain::ChainApi::to_delegate(chain), + maybe_offchain_rpc, + author::AuthorApi::to_delegate(author), + system::SystemApi::to_delegate(system), + rpc_extensions_builder.build(deny_unsafe, subscriptions), + )) +} - // Periodically send the network state to the telemetry. - let (netstat_tx, netstat_rx) = tracing_unbounded::<(NetworkStatus<_>, NetworkState)>("mpsc_netstat2"); - network_status_sinks.lock().push(std::time::Duration::from_secs(30), netstat_tx); - let tel_task_2 = netstat_rx.for_each(move |(_, network_state)| { - telemetry!( - SUBSTRATE_INFO; - "system.network_state"; - "state" => network_state, - ); - ready(()) - }); - spawn_handle.spawn( - "telemetry-periodic-network-state", - tel_task_2, - ); +/// Parameters to pass into `build_network`. +pub struct BuildNetworkParams<'a, TBl: BlockT, TExPool, TImpQu, TCl> { + /// The service configuration. + pub config: &'a Configuration, + /// A shared client returned by `new_full_parts`/`new_light_parts`. + pub client: Arc, + /// A shared transaction pool. + pub transaction_pool: Arc, + /// A handle for spawning tasks. + pub spawn_handle: SpawnTaskHandle, + /// An import queue. + pub import_queue: TImpQu, + /// An optional, shared data fetcher for light clients. + pub on_demand: Option>>, + /// A block annouce validator builder. + pub block_announce_validator_builder: Option) -> Box + Send> + Send + >>, + /// An optional finality proof request builder. + pub finality_proof_request_builder: Option>, + /// An optional, shared finality proof request provider. + pub finality_proof_provider: Option>>, +} - // RPC - let (system_rpc_tx, system_rpc_rx) = tracing_unbounded("mpsc_system_rpc"); - let gen_handler = |deny_unsafe: sc_rpc::DenyUnsafe| { - use sc_rpc::{chain, state, author, system, offchain}; - - let system_info = sc_rpc::system::SystemInfo { - chain_name: chain_spec.name().into(), - impl_name: config.impl_name.into(), - impl_version: config.impl_version.into(), - properties: chain_spec.properties().clone(), - chain_type: chain_spec.chain_type().clone(), - }; - - let subscriptions = sc_rpc::Subscriptions::new(Arc::new(task_manager.spawn_handle())); - - let (chain, state, child_state) = if let (Some(remote_backend), Some(on_demand)) = - (remote_backend.as_ref(), on_demand.as_ref()) { - // Light clients - let chain = sc_rpc::chain::new_light( - client.clone(), - subscriptions.clone(), - remote_backend.clone(), - on_demand.clone() - ); - let (state, child_state) = sc_rpc::state::new_light( - client.clone(), - subscriptions.clone(), - remote_backend.clone(), - on_demand.clone() +/// Build the network service, the network status sinks and an RPC sender. +pub fn build_network( + params: BuildNetworkParams +) -> Result< + ( + Arc::Hash>>, + NetworkStatusSinks, + TracingUnboundedSender>, + NetworkStarter, + ), + Error +> + where + TBl: BlockT, + TCl: ProvideRuntimeApi + HeaderMetadata + Chain + + BlockBackend + BlockIdTo + ProofProvider + + HeaderBackend + BlockchainEvents + 'static, + TExPool: MaintainedTransactionPool::Hash> + 'static, + TImpQu: ImportQueue + 'static, +{ + let BuildNetworkParams { + config, client, transaction_pool, spawn_handle, import_queue, on_demand, + block_announce_validator_builder, finality_proof_request_builder, finality_proof_provider, + } = params; + + let transaction_pool_adapter = Arc::new(TransactionPoolAdapter { + imports_external_transactions: !matches!(config.role, Role::Light), + pool: transaction_pool, + client: client.clone(), + }); + + let protocol_id = { + let protocol_id_full = match config.chain_spec.protocol_id() { + Some(pid) => pid, + None => { + warn!("Using default protocol ID {:?} because none is configured in the \ + chain specs", DEFAULT_PROTOCOL_ID ); - (chain, state, child_state) + DEFAULT_PROTOCOL_ID + } + }.as_bytes(); + sc_network::config::ProtocolId::from(protocol_id_full) + }; - } else { - // Full nodes - let chain = sc_rpc::chain::new_full(client.clone(), subscriptions.clone()); - let (state, child_state) = sc_rpc::state::new_full(client.clone(), subscriptions.clone()); - (chain, state, child_state) - }; + let block_announce_validator = if let Some(f) = block_announce_validator_builder { + f(client.clone()) + } else { + Box::new(DefaultBlockAnnounceValidator) + }; - let author = sc_rpc::author::Author::new( - client.clone(), - transaction_pool.clone(), - subscriptions, - keystore.clone(), - deny_unsafe, - ); - let system = system::System::new(system_info, system_rpc_tx.clone(), deny_unsafe); - - let maybe_offchain_rpc = offchain_storage.clone() - .map(|storage| { - let offchain = sc_rpc::offchain::Offchain::new(storage, deny_unsafe); - // FIXME: Use plain Option (don't collect into HashMap) when we upgrade to jsonrpc 14.1 - // https://github.com/paritytech/jsonrpc/commit/20485387ed06a48f1a70bf4d609a7cde6cf0accf - let delegate = offchain::OffchainApi::to_delegate(offchain); - delegate.into_iter().collect::>() - }).unwrap_or_default(); - - sc_rpc_server::rpc_handler(( - state::StateApi::to_delegate(state), - state::ChildStateApi::to_delegate(child_state), - chain::ChainApi::to_delegate(chain), - maybe_offchain_rpc, - author::AuthorApi::to_delegate(author), - system::SystemApi::to_delegate(system), - rpc_extensions.clone(), - )) - }; - let rpc = start_rpc_servers(&config, gen_handler)?; - // This is used internally, so don't restrict access to unsafe RPC - let rpc_handlers = gen_handler(sc_rpc::DenyUnsafe::No); - - // The network worker is responsible for gathering all network messages and processing - // them. This is quite a heavy task, and at the time of the writing of this comment it - // frequently happens that this future takes several seconds or in some situations - // even more than a minute until it has processed its entire queue. This is clearly an - // issue, and ideally we would like to fix the network future to take as little time as - // possible, but we also take the extra harm-prevention measure to execute the networking - // future using `spawn_blocking`. - spawn_handle.spawn_blocking( - "network-worker", - build_network_future( - config.role.clone(), - network_mut, - client.clone(), - network_status_sinks.clone(), - system_rpc_rx, - has_bootnodes, - config.announce_block, - ), - ); + let network_params = sc_network::config::Params { + role: config.role.clone(), + executor: { + let spawn_handle = Clone::clone(&spawn_handle); + Some(Box::new(move |fut| { + spawn_handle.spawn("libp2p-node", fut); + })) + }, + network_config: config.network.clone(), + chain: client.clone(), + finality_proof_provider, + finality_proof_request_builder, + on_demand: on_demand, + transaction_pool: transaction_pool_adapter as _, + import_queue: Box::new(import_queue), + protocol_id, + block_announce_validator, + metrics_registry: config.prometheus_config.as_ref().map(|config| config.registry.clone()) + }; - let telemetry_connection_sinks: Arc>>> = Default::default(); - - // Telemetry - let telemetry = config.telemetry_endpoints.clone().map(|endpoints| { - let is_authority = config.role.is_authority(); - let network_id = network.local_peer_id().to_base58(); - let name = config.network.node_name.clone(); - let impl_name = config.impl_name.to_owned(); - let version = version.clone(); - let chain_name = config.chain_spec.name().to_owned(); - let telemetry_connection_sinks_ = telemetry_connection_sinks.clone(); - let telemetry = sc_telemetry::init_telemetry(sc_telemetry::TelemetryConfig { - endpoints, - wasm_external_transport: config.telemetry_external_transport.take(), - }); - let startup_time = SystemTime::UNIX_EPOCH.elapsed() - .map(|dur| dur.as_millis()) - .unwrap_or(0); - let future = telemetry.clone() - .for_each(move |event| { - // Safe-guard in case we add more events in the future. - let sc_telemetry::TelemetryEvent::Connected = event; - - telemetry!(SUBSTRATE_INFO; "system.connected"; - "name" => name.clone(), - "implementation" => impl_name.clone(), - "version" => version.clone(), - "config" => "", - "chain" => chain_name.clone(), - "authority" => is_authority, - "startup_time" => startup_time, - "network_id" => network_id.clone() - ); - - telemetry_connection_sinks_.lock().retain(|sink| { - sink.unbounded_send(()).is_ok() - }); - ready(()) - }); + let has_bootnodes = !network_params.network_config.boot_nodes.is_empty(); + let network_mut = sc_network::NetworkWorker::new(network_params)?; + let network = network_mut.service().clone(); + let network_status_sinks = NetworkStatusSinks::new(Arc::new(status_sinks::StatusSinks::new())); + + let (system_rpc_tx, system_rpc_rx) = tracing_unbounded("mpsc_system_rpc"); + + let future = build_network_future( + config.role.clone(), + network_mut, + client, + network_status_sinks.clone(), + system_rpc_rx, + has_bootnodes, + config.announce_block, + ); - spawn_handle.spawn( - "telemetry-worker", - future, + // TODO: Normally, one is supposed to pass a list of notifications protocols supported by the + // node through the `NetworkConfiguration` struct. But because this function doesn't know in + // advance which components, such as GrandPa or Polkadot, will be plugged on top of the + // service, it is unfortunately not possible to do so without some deep refactoring. To bypass + // this problem, the `NetworkService` provides a `register_notifications_protocol` method that + // can be called even after the network has been initialized. However, we want to avoid the + // situation where `register_notifications_protocol` is called *after* the network actually + // connects to other peers. For this reason, we delay the process of the network future until + // the user calls `NetworkStarter::start_network`. + // + // This entire hack should eventually be removed in favour of passing the list of protocols + // through the configuration. + // + // See also https://github.com/paritytech/substrate/issues/6827 + let (network_start_tx, network_start_rx) = oneshot::channel(); + + // The network worker is responsible for gathering all network messages and processing + // them. This is quite a heavy task, and at the time of the writing of this comment it + // frequently happens that this future takes several seconds or in some situations + // even more than a minute until it has processed its entire queue. This is clearly an + // issue, and ideally we would like to fix the network future to take as little time as + // possible, but we also take the extra harm-prevention measure to execute the networking + // future using `spawn_blocking`. + spawn_handle.spawn_blocking("network-worker", async move { + if network_start_rx.await.is_err() { + debug_assert!(false); + log::warn!( + "The NetworkStart returned as part of `build_network` has been silently dropped" ); + // This `return` might seem unnecessary, but we don't want to make it look like + // everything is working as normal even though the user is clearly misusing the API. + return; + } - telemetry - }); + future.await + }); - // Instrumentation - if let Some(tracing_targets) = config.tracing_targets.as_ref() { - let subscriber = sc_tracing::ProfilingSubscriber::new( - config.tracing_receiver, tracing_targets - ); - match tracing::subscriber::set_global_default(subscriber) { - Ok(_) => (), - Err(e) => error!(target: "tracing", "Unable to set global default subscriber {}", e), - } - } + Ok((network, network_status_sinks, system_rpc_tx, NetworkStarter(network_start_tx))) +} - Ok(Service { - client, - task_manager, - network, - network_status_sinks, - select_chain, - transaction_pool, - essential_failed_tx, - essential_failed_rx, - rpc_handlers, - _rpc: rpc, - _telemetry: telemetry, - _offchain_workers: offchain_workers, - _telemetry_on_connect_sinks: telemetry_connection_sinks.clone(), - keystore, - marker: PhantomData::, - prometheus_registry: config.prometheus_config.map(|config| config.registry) - }) +/// Object used to start the network. +#[must_use] +pub struct NetworkStarter(oneshot::Sender<()>); + +impl NetworkStarter { + /// Start the network. Call this after all sub-components have been initialized. + /// + /// > **Note**: If you don't call this function, the networking will not work. + pub fn start_network(self) { + let _ = self.0.send(()); } } diff --git a/client/service/src/chain_ops.rs b/client/service/src/chain_ops.rs deleted file mode 100644 index 612e9310d182bbd4b0319f2f06c7246e7faf5c75..0000000000000000000000000000000000000000 --- a/client/service/src/chain_ops.rs +++ /dev/null @@ -1,343 +0,0 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Chain utilities. - -use crate::error; -use crate::builder::{ServiceBuilderCommand, ServiceBuilder}; -use crate::error::Error; -use sc_chain_spec::ChainSpec; -use log::{warn, info}; -use futures::{future, prelude::*}; -use sp_runtime::traits::{ - Block as BlockT, NumberFor, One, Zero, Header, SaturatedConversion -}; -use sp_runtime::generic::{BlockId, SignedBlock}; -use codec::{Decode, Encode, IoReader}; -use crate::client::{Client, LocalCallExecutor}; -use sp_consensus::{ - BlockOrigin, - import_queue::{IncomingBlock, Link, BlockImportError, BlockImportResult, ImportQueue}, -}; -use sc_executor::{NativeExecutor, NativeExecutionDispatch}; -use sp_core::storage::{StorageKey, well_known_keys, ChildInfo, Storage, StorageChild, StorageMap}; -use sc_client_api::{StorageProvider, BlockBackend, UsageProvider}; - -use std::{io::{Read, Write, Seek}, pin::Pin, collections::HashMap}; - -/// Build a chain spec json -pub fn build_spec(spec: &dyn ChainSpec, raw: bool) -> error::Result { - spec.as_json(raw).map_err(Into::into) -} - -impl< - TBl, TRtApi, TBackend, - TExecDisp, TFchr, TSc, TImpQu, TFprb, TFpp, - TExPool, TRpc, Backend -> ServiceBuilderCommand for ServiceBuilder< - TBl, TRtApi, - Client>, TBl, TRtApi>, - TFchr, TSc, TImpQu, TFprb, TFpp, TExPool, TRpc, Backend -> where - TBl: BlockT, - TBackend: 'static + sc_client_api::backend::Backend + Send, - TExecDisp: 'static + NativeExecutionDispatch, - TImpQu: 'static + ImportQueue, - TRtApi: 'static + Send + Sync, - Self: Send + 'static, -{ - type Block = TBl; - type NativeDispatch = TExecDisp; - - fn import_blocks( - mut self, - input: impl Read + Seek + Send + 'static, - force: bool, - ) -> Pin> + Send>> { - struct WaitLink { - imported_blocks: u64, - has_error: bool, - } - - impl WaitLink { - fn new() -> WaitLink { - WaitLink { - imported_blocks: 0, - has_error: false, - } - } - } - - impl Link for WaitLink { - fn blocks_processed( - &mut self, - imported: usize, - _count: usize, - results: Vec<(Result>, BlockImportError>, B::Hash)> - ) { - self.imported_blocks += imported as u64; - - for result in results { - if let (Err(err), hash) = result { - warn!("There was an error importing block with hash {:?}: {:?}", hash, err); - self.has_error = true; - break; - } - } - } - } - - let mut io_reader_input = IoReader(input); - let mut count = None::; - let mut read_block_count = 0; - let mut link = WaitLink::new(); - - // Importing blocks is implemented as a future, because we want the operation to be - // interruptible. - // - // Every time we read a block from the input or import a bunch of blocks from the import - // queue, the `Future` re-schedules itself and returns `Poll::Pending`. - // This makes it possible either to interleave other operations in-between the block imports, - // or to stop the operation completely. - let import = future::poll_fn(move |cx| { - let client = &self.client; - let queue = &mut self.import_queue; - - // Start by reading the number of blocks if not done so already. - let count = match count { - Some(c) => c, - None => { - let c: u64 = match Decode::decode(&mut io_reader_input) { - Ok(c) => c, - Err(err) => { - let err = format!("Error reading file: {}", err); - return std::task::Poll::Ready(Err(From::from(err))); - }, - }; - info!("📦 Importing {} blocks", c); - count = Some(c); - c - } - }; - - // Read blocks from the input. - if read_block_count < count { - match SignedBlock::::decode(&mut io_reader_input) { - Ok(signed) => { - let (header, extrinsics) = signed.block.deconstruct(); - let hash = header.hash(); - // import queue handles verification and importing it into the client - queue.import_blocks(BlockOrigin::File, vec![ - IncomingBlock:: { - hash, - header: Some(header), - body: Some(extrinsics), - justification: signed.justification, - origin: None, - allow_missing_state: false, - import_existing: force, - } - ]); - } - Err(e) => { - warn!("Error reading block data at {}: {}", read_block_count, e); - return std::task::Poll::Ready(Ok(())); - } - } - - read_block_count += 1; - if read_block_count % 1000 == 0 { - info!("#{} blocks were added to the queue", read_block_count); - } - - cx.waker().wake_by_ref(); - return std::task::Poll::Pending; - } - - let blocks_before = link.imported_blocks; - queue.poll_actions(cx, &mut link); - - if link.has_error { - info!( - "Stopping after #{} blocks because of an error", - link.imported_blocks, - ); - return std::task::Poll::Ready(Ok(())); - } - - if link.imported_blocks / 1000 != blocks_before / 1000 { - info!( - "#{} blocks were imported (#{} left)", - link.imported_blocks, - count - link.imported_blocks - ); - } - - if link.imported_blocks >= count { - info!("🎉 Imported {} blocks. Best: #{}", read_block_count, client.chain_info().best_number); - return std::task::Poll::Ready(Ok(())); - - } else { - // Polling the import queue will re-schedule the task when ready. - return std::task::Poll::Pending; - } - }); - Box::pin(import) - } - - fn export_blocks( - self, - mut output: impl Write + 'static, - from: NumberFor, - to: Option>, - binary: bool - ) -> Pin>>> { - let mut block = from; - - let last = match to { - Some(v) if v.is_zero() => One::one(), - Some(v) => v, - None => self.client.chain_info().best_number, - }; - - let mut wrote_header = false; - - // Exporting blocks is implemented as a future, because we want the operation to be - // interruptible. - // - // Every time we write a block to the output, the `Future` re-schedules itself and returns - // `Poll::Pending`. - // This makes it possible either to interleave other operations in-between the block exports, - // or to stop the operation completely. - let export = future::poll_fn(move |cx| { - let client = &self.client; - - if last < block { - return std::task::Poll::Ready(Err("Invalid block range specified".into())); - } - - if !wrote_header { - info!("Exporting blocks from #{} to #{}", block, last); - if binary { - let last_: u64 = last.saturated_into::(); - let block_: u64 = block.saturated_into::(); - let len: u64 = last_ - block_ + 1; - output.write_all(&len.encode())?; - } - wrote_header = true; - } - - match client.block(&BlockId::number(block))? { - Some(block) => { - if binary { - output.write_all(&block.encode())?; - } else { - serde_json::to_writer(&mut output, &block) - .map_err(|e| format!("Error writing JSON: {}", e))?; - } - }, - // Reached end of the chain. - None => return std::task::Poll::Ready(Ok(())), - } - if (block % 10000.into()).is_zero() { - info!("#{}", block); - } - if block == last { - return std::task::Poll::Ready(Ok(())); - } - block += One::one(); - - // Re-schedule the task in order to continue the operation. - cx.waker().wake_by_ref(); - std::task::Poll::Pending - }); - - Box::pin(export) - } - - fn revert_chain( - &self, - blocks: NumberFor - ) -> Result<(), Error> { - let reverted = self.client.revert(blocks)?; - let info = self.client.chain_info(); - - if reverted.is_zero() { - info!("There aren't any non-finalized blocks to revert."); - } else { - info!("Reverted {} blocks. Best: #{} ({})", reverted, info.best_number, info.best_hash); - } - Ok(()) - } - - fn check_block( - self, - block_id: BlockId - ) -> Pin> + Send>> { - match self.client.block(&block_id) { - Ok(Some(block)) => { - let mut buf = Vec::new(); - 1u64.encode_to(&mut buf); - block.encode_to(&mut buf); - let reader = std::io::Cursor::new(buf); - self.import_blocks(reader, true) - } - Ok(None) => Box::pin(future::err("Unknown block".into())), - Err(e) => Box::pin(future::err(format!("Error reading block: {:?}", e).into())), - } - } - - fn export_raw_state( - &self, - block: Option>, - ) -> Result { - let block = block.unwrap_or_else( - || BlockId::Hash(self.client.usage_info().chain.best_hash) - ); - - let empty_key = StorageKey(Vec::new()); - let mut top_storage = self.client.storage_pairs(&block, &empty_key)?; - let mut children_default = HashMap::new(); - - // Remove all default child storage roots from the top storage and collect the child storage - // pairs. - while let Some(pos) = top_storage - .iter() - .position(|(k, _)| k.0.starts_with(well_known_keys::DEFAULT_CHILD_STORAGE_KEY_PREFIX)) { - let (key, _) = top_storage.swap_remove(pos); - - let key = StorageKey( - key.0[well_known_keys::DEFAULT_CHILD_STORAGE_KEY_PREFIX.len()..].to_vec(), - ); - let child_info = ChildInfo::new_default(&key.0); - - let keys = self.client.child_storage_keys(&block, &child_info, &empty_key)?; - let mut pairs = StorageMap::new(); - keys.into_iter().try_for_each(|k| { - if let Some(value) = self.client.child_storage(&block, &child_info, &k)? { - pairs.insert(k.0, value.0); - } - - Ok::<_, Error>(()) - })?; - - children_default.insert(key.0, StorageChild { child_info, data: pairs }); - } - - let top = top_storage.into_iter().map(|(k, v)| (k.0, v.0)).collect(); - Ok(Storage { top, children_default }) - } -} diff --git a/client/service/src/chain_ops/check_block.rs b/client/service/src/chain_ops/check_block.rs new file mode 100644 index 0000000000000000000000000000000000000000..34baeb55445a88ec41d2e729ecdc4c4eb782c1f6 --- /dev/null +++ b/client/service/src/chain_ops/check_block.rs @@ -0,0 +1,51 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use crate::error::Error; +use futures::{future, prelude::*}; +use sp_runtime::traits::Block as BlockT; +use sp_runtime::generic::BlockId; +use codec::Encode; +use sp_consensus::import_queue::ImportQueue; +use sc_client_api::{BlockBackend, UsageProvider}; + +use std::pin::Pin; +use std::sync::Arc; +use crate::chain_ops::import_blocks; + +/// Re-validate known block. +pub fn check_block( + client: Arc, + import_queue: IQ, + block_id: BlockId +) -> Pin> + Send>> +where + C: BlockBackend + UsageProvider + Send + Sync + 'static, + B: BlockT + for<'de> serde::Deserialize<'de>, + IQ: ImportQueue + 'static, +{ + match client.block(&block_id) { + Ok(Some(block)) => { + let mut buf = Vec::new(); + 1u64.encode_to(&mut buf); + block.encode_to(&mut buf); + let reader = std::io::Cursor::new(buf); + import_blocks(client, import_queue, reader, true, true) + } + Ok(None) => Box::pin(future::err("Unknown block".into())), + Err(e) => Box::pin(future::err(format!("Error reading block: {:?}", e).into())), + } +} diff --git a/client/service/src/chain_ops/export_blocks.rs b/client/service/src/chain_ops/export_blocks.rs new file mode 100644 index 0000000000000000000000000000000000000000..2f32cbf7fbdb7cf08cdb1fdb618ac5d6c0ef5cec --- /dev/null +++ b/client/service/src/chain_ops/export_blocks.rs @@ -0,0 +1,104 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use crate::error::Error; +use log::info; +use futures::{future, prelude::*}; +use sp_runtime::traits::{ + Block as BlockT, NumberFor, One, Zero, SaturatedConversion +}; +use sp_runtime::generic::BlockId; +use codec::Encode; + +use std::{io::Write, pin::Pin}; +use sc_client_api::{BlockBackend, UsageProvider}; +use std::sync::Arc; +use std::task::Poll; + +/// Performs the blocks export. +pub fn export_blocks( + client: Arc, + mut output: impl Write + 'static, + from: NumberFor, + to: Option>, + binary: bool +) -> Pin>>> +where + C: BlockBackend + UsageProvider + 'static, + B: BlockT, +{ + let mut block = from; + + let last = match to { + Some(v) if v.is_zero() => One::one(), + Some(v) => v, + None => client.usage_info().chain.best_number, + }; + + let mut wrote_header = false; + + // Exporting blocks is implemented as a future, because we want the operation to be + // interruptible. + // + // Every time we write a block to the output, the `Future` re-schedules itself and returns + // `Poll::Pending`. + // This makes it possible either to interleave other operations in-between the block exports, + // or to stop the operation completely. + let export = future::poll_fn(move |cx| { + let client = &client; + + if last < block { + return Poll::Ready(Err("Invalid block range specified".into())); + } + + if !wrote_header { + info!("Exporting blocks from #{} to #{}", block, last); + if binary { + let last_: u64 = last.saturated_into::(); + let block_: u64 = block.saturated_into::(); + let len: u64 = last_ - block_ + 1; + output.write_all(&len.encode())?; + } + wrote_header = true; + } + + match client.block(&BlockId::number(block))? { + Some(block) => { + if binary { + output.write_all(&block.encode())?; + } else { + serde_json::to_writer(&mut output, &block) + .map_err(|e| format!("Error writing JSON: {}", e))?; + } + }, + // Reached end of the chain. + None => return Poll::Ready(Ok(())), + } + if (block % 10000.into()).is_zero() { + info!("#{}", block); + } + if block == last { + return Poll::Ready(Ok(())); + } + block += One::one(); + + // Re-schedule the task in order to continue the operation. + cx.waker().wake_by_ref(); + Poll::Pending + }); + + Box::pin(export) +} diff --git a/client/service/src/chain_ops/export_raw_state.rs b/client/service/src/chain_ops/export_raw_state.rs new file mode 100644 index 0000000000000000000000000000000000000000..3fe44dbdb142d29f1737896e21f7a077f1dd68f8 --- /dev/null +++ b/client/service/src/chain_ops/export_raw_state.rs @@ -0,0 +1,71 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use crate::error::Error; +use sp_runtime::traits::Block as BlockT; +use sp_runtime::generic::BlockId; +use sp_core::storage::{StorageKey, well_known_keys, ChildInfo, Storage, StorageChild, StorageMap}; +use sc_client_api::{StorageProvider, UsageProvider}; + +use std::{collections::HashMap, sync::Arc}; + +/// Export the raw state at the given `block`. If `block` is `None`, the +/// best block will be used. +pub fn export_raw_state( + client: Arc, + block: Option>, +) -> Result +where + C: UsageProvider + StorageProvider, + B: BlockT, + BA: sc_client_api::backend::Backend, +{ + let block = block.unwrap_or_else( + || BlockId::Hash(client.usage_info().chain.best_hash) + ); + + let empty_key = StorageKey(Vec::new()); + let mut top_storage = client.storage_pairs(&block, &empty_key)?; + let mut children_default = HashMap::new(); + + // Remove all default child storage roots from the top storage and collect the child storage + // pairs. + while let Some(pos) = top_storage + .iter() + .position(|(k, _)| k.0.starts_with(well_known_keys::DEFAULT_CHILD_STORAGE_KEY_PREFIX)) { + let (key, _) = top_storage.swap_remove(pos); + + let key = StorageKey( + key.0[well_known_keys::DEFAULT_CHILD_STORAGE_KEY_PREFIX.len()..].to_vec(), + ); + let child_info = ChildInfo::new_default(&key.0); + + let keys = client.child_storage_keys(&block, &child_info, &empty_key)?; + let mut pairs = StorageMap::new(); + keys.into_iter().try_for_each(|k| { + if let Some(value) = client.child_storage(&block, &child_info, &k)? { + pairs.insert(k.0, value.0); + } + + Ok::<_, Error>(()) + })?; + + children_default.insert(key.0, StorageChild { child_info, data: pairs }); + } + + let top = top_storage.into_iter().map(|(k, v)| (k.0, v.0)).collect(); + Ok(Storage { top, children_default }) +} diff --git a/client/service/src/chain_ops/import_blocks.rs b/client/service/src/chain_ops/import_blocks.rs new file mode 100644 index 0000000000000000000000000000000000000000..46ad0d0501d93f5292274a734a511d8c249be583 --- /dev/null +++ b/client/service/src/chain_ops/import_blocks.rs @@ -0,0 +1,472 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use crate::error; +use crate::error::Error; +use sc_chain_spec::ChainSpec; +use log::{warn, info}; +use futures::{future, prelude::*}; +use sp_runtime::traits::{ + Block as BlockT, NumberFor, Zero, Header, MaybeSerializeDeserialize, +}; +use sp_runtime::generic::SignedBlock; +use codec::{Decode, IoReader as CodecIoReader}; +use sp_consensus::{ + BlockOrigin, + import_queue::{IncomingBlock, Link, BlockImportError, BlockImportResult, ImportQueue}, +}; + +use std::{io::{Read, Seek}, pin::Pin}; +use std::time::{Duration, Instant}; +use futures_timer::Delay; +use std::task::Poll; +use serde_json::{de::IoRead as JsonIoRead, Deserializer, StreamDeserializer}; +use std::convert::{TryFrom, TryInto}; +use sp_runtime::traits::{CheckedDiv, Saturating}; +use sc_client_api::UsageProvider; + +/// Number of blocks we will add to the queue before waiting for the queue to catch up. +const MAX_PENDING_BLOCKS: u64 = 1_024; + +/// Number of milliseconds to wait until next poll. +const DELAY_TIME: u64 = 2_000; + +/// Number of milliseconds that must have passed between two updates. +const TIME_BETWEEN_UPDATES: u64 = 3_000; + +use std::sync::Arc; + +/// Build a chain spec json +pub fn build_spec(spec: &dyn ChainSpec, raw: bool) -> error::Result { + spec.as_json(raw).map_err(Into::into) +} + + +/// Helper enum that wraps either a binary decoder (from parity-scale-codec), or a JSON decoder +/// (from serde_json). Implements the Iterator Trait, calling `next()` will decode the next +/// SignedBlock and return it. +enum BlockIter where + R: std::io::Read + std::io::Seek, +{ + Binary { + // Total number of blocks we are expecting to decode. + num_expected_blocks: u64, + // Number of blocks we have decoded thus far. + read_block_count: u64, + // Reader to the data, used for decoding new blocks. + reader: CodecIoReader, + }, + Json { + // Nubmer of blocks we have decoded thus far. + read_block_count: u64, + // Stream to the data, used for decoding new blocks. + reader: StreamDeserializer<'static, JsonIoRead, SignedBlock>, + }, +} + +impl BlockIter where + R: Read + Seek + 'static, + B: BlockT + MaybeSerializeDeserialize, +{ + fn new(input: R, binary: bool) -> Result { + if binary { + let mut reader = CodecIoReader(input); + // If the file is encoded in binary format, it is expected to first specify the number + // of blocks that are going to be decoded. We read it and add it to our enum struct. + let num_expected_blocks: u64 = Decode::decode(&mut reader) + .map_err(|e| format!("Failed to decode the number of blocks: {:?}", e))?; + Ok(BlockIter::Binary { + num_expected_blocks, + read_block_count: 0, + reader, + }) + } else { + let stream_deser = Deserializer::from_reader(input) + .into_iter::>(); + Ok(BlockIter::Json { + reader: stream_deser, + read_block_count: 0, + }) + } + } + + /// Returns the number of blocks read thus far. + fn read_block_count(&self) -> u64 { + match self { + BlockIter::Binary { read_block_count, .. } + | BlockIter::Json { read_block_count, .. } + => *read_block_count, + } + } + + /// Returns the total number of blocks to be imported, if possible. + fn num_expected_blocks(&self) -> Option { + match self { + BlockIter::Binary { num_expected_blocks, ..} => Some(*num_expected_blocks), + BlockIter::Json {..} => None + } + } +} + +impl Iterator for BlockIter where + R: Read + Seek + 'static, + B: BlockT + MaybeSerializeDeserialize, +{ + type Item = Result, String>; + + fn next(&mut self) -> Option { + match self { + BlockIter::Binary { num_expected_blocks, read_block_count, reader } => { + if read_block_count < num_expected_blocks { + let block_result: Result, _> = SignedBlock::::decode(reader) + .map_err(|e| e.to_string()); + *read_block_count += 1; + Some(block_result) + } else { + // `read_block_count` == `num_expected_blocks` so we've read enough blocks. + None + } + } + BlockIter::Json { reader, read_block_count } => { + let res = Some(reader.next()?.map_err(|e| e.to_string())); + *read_block_count += 1; + res + } + } + } +} + +/// Imports the SignedBlock to the queue. +fn import_block_to_queue( + signed_block: SignedBlock, + queue: &mut TImpQu, + force: bool +) where + TBl: BlockT + MaybeSerializeDeserialize, + TImpQu: 'static + ImportQueue, +{ + let (header, extrinsics) = signed_block.block.deconstruct(); + let hash = header.hash(); + // import queue handles verification and importing it into the client. + queue.import_blocks(BlockOrigin::File, vec![ + IncomingBlock:: { + hash, + header: Some(header), + body: Some(extrinsics), + justification: signed_block.justification, + origin: None, + allow_missing_state: false, + import_existing: force, + } + ]); +} + +/// Returns true if we have imported every block we were supposed to import, else returns false. +fn importing_is_done( + num_expected_blocks: Option, + read_block_count: u64, + imported_blocks: u64 +) -> bool { + if let Some(num_expected_blocks) = num_expected_blocks { + imported_blocks >= num_expected_blocks + } else { + imported_blocks >= read_block_count + } +} + +/// Structure used to log the block importing speed. +struct Speedometer { + best_number: NumberFor, + last_number: Option>, + last_update: Instant, +} + +impl Speedometer { + /// Creates a fresh Speedometer. + fn new() -> Self { + Self { + best_number: NumberFor::::from(0), + last_number: None, + last_update: Instant::now(), + } + } + + /// Calculates `(best_number - last_number) / (now - last_update)` and + /// logs the speed of import. + fn display_speed(&self) { + // Number of milliseconds elapsed since last time. + let elapsed_ms = { + let elapsed = self.last_update.elapsed(); + let since_last_millis = elapsed.as_secs() * 1000; + let since_last_subsec_millis = elapsed.subsec_millis() as u64; + since_last_millis + since_last_subsec_millis + }; + + // Number of blocks that have been imported since last time. + let diff = match self.last_number { + None => return, + Some(n) => self.best_number.saturating_sub(n) + }; + + if let Ok(diff) = TryInto::::try_into(diff) { + // If the number of blocks can be converted to a regular integer, then it's easy: just + // do the math and turn it into a `f64`. + let speed = diff.saturating_mul(10_000).checked_div(u128::from(elapsed_ms)) + .map_or(0.0, |s| s as f64) / 10.0; + info!("📦 Current best block: {} ({:4.1} bps)", self.best_number, speed); + } else { + // If the number of blocks can't be converted to a regular integer, then we need a more + // algebraic approach and we stay within the realm of integers. + let one_thousand = NumberFor::::from(1_000); + let elapsed = NumberFor::::from( + >::try_from(elapsed_ms).unwrap_or(u32::max_value()) + ); + + let speed = diff.saturating_mul(one_thousand).checked_div(&elapsed) + .unwrap_or_else(Zero::zero); + info!("📦 Current best block: {} ({} bps)", self.best_number, speed) + } + } + + /// Updates the Speedometer. + fn update(&mut self, best_number: NumberFor) { + self.last_number = Some(self.best_number); + self.best_number = best_number; + self.last_update = Instant::now(); + } + + // If more than TIME_BETWEEN_UPDATES has elapsed since last update, + // then print and update the speedometer. + fn notify_user(&mut self, best_number: NumberFor) { + let delta = Duration::from_millis(TIME_BETWEEN_UPDATES); + if Instant::now().duration_since(self.last_update) >= delta { + self.display_speed(); + self.update(best_number); + } + } +} + +/// Different State that the `import_blocks` future could be in. +enum ImportState where + R: Read + Seek + 'static, + B: BlockT + MaybeSerializeDeserialize, +{ + /// We are reading from the BlockIter structure, adding those blocks to the queue if possible. + Reading{block_iter: BlockIter}, + /// The queue is full (contains at least MAX_PENDING_BLOCKS blocks) and we are waiting for it to + /// catch up. + WaitingForImportQueueToCatchUp{ + block_iter: BlockIter, + delay: Delay, + block: SignedBlock + }, + // We have added all the blocks to the queue but they are still being processed. + WaitingForImportQueueToFinish{ + num_expected_blocks: Option, + read_block_count: u64, + delay: Delay, + }, +} + +/// Starts the process of importing blocks. +pub fn import_blocks( + client: Arc, + mut import_queue: IQ, + input: impl Read + Seek + Send + 'static, + force: bool, + binary: bool, +) -> Pin> + Send>> +where + C: UsageProvider + Send + Sync + 'static, + B: BlockT + for<'de> serde::Deserialize<'de>, + IQ: ImportQueue + 'static, +{ + struct WaitLink { + imported_blocks: u64, + has_error: bool, + } + + impl WaitLink { + fn new() -> WaitLink { + WaitLink { + imported_blocks: 0, + has_error: false, + } + } + } + + impl Link for WaitLink { + fn blocks_processed( + &mut self, + imported: usize, + _num_expected_blocks: usize, + results: Vec<(Result>, BlockImportError>, B::Hash)> + ) { + self.imported_blocks += imported as u64; + + for result in results { + if let (Err(err), hash) = result { + warn!("There was an error importing block with hash {:?}: {:?}", hash, err); + self.has_error = true; + break; + } + } + } + } + + let mut link = WaitLink::new(); + let block_iter_res: Result, String> = BlockIter::new(input, binary); + + let block_iter = match block_iter_res { + Ok(block_iter) => block_iter, + Err(e) => { + // We've encountered an error while creating the block iterator + // so we can just return a future that returns an error. + return future::ready(Err(Error::Other(e))).boxed() + } + }; + + let mut state = Some(ImportState::Reading{block_iter}); + let mut speedometer = Speedometer::::new(); + + // Importing blocks is implemented as a future, because we want the operation to be + // interruptible. + // + // Every time we read a block from the input or import a bunch of blocks from the import + // queue, the `Future` re-schedules itself and returns `Poll::Pending`. + // This makes it possible either to interleave other operations in-between the block imports, + // or to stop the operation completely. + let import = future::poll_fn(move |cx| { + let client = &client; + let queue = &mut import_queue; + match state.take().expect("state should never be None; qed") { + ImportState::Reading{mut block_iter} => { + match block_iter.next() { + None => { + // The iterator is over: we now need to wait for the import queue to finish. + let num_expected_blocks = block_iter.num_expected_blocks(); + let read_block_count = block_iter.read_block_count(); + let delay = Delay::new(Duration::from_millis(DELAY_TIME)); + state = Some(ImportState::WaitingForImportQueueToFinish { + num_expected_blocks, read_block_count, delay + }); + }, + Some(block_result) => { + let read_block_count = block_iter.read_block_count(); + match block_result { + Ok(block) => { + if read_block_count - link.imported_blocks >= MAX_PENDING_BLOCKS { + // The queue is full, so do not add this block and simply wait + // until the queue has made some progress. + let delay = Delay::new(Duration::from_millis(DELAY_TIME)); + state = Some(ImportState::WaitingForImportQueueToCatchUp { + block_iter, delay, block + }); + } else { + // Queue is not full, we can keep on adding blocks to the queue. + import_block_to_queue(block, queue, force); + state = Some(ImportState::Reading{block_iter}); + } + } + Err(e) => { + return Poll::Ready( + Err(Error::Other( + format!("Error reading block #{}: {}", read_block_count, e) + ))) + } + } + } + } + }, + ImportState::WaitingForImportQueueToCatchUp{block_iter, mut delay, block} => { + let read_block_count = block_iter.read_block_count(); + if read_block_count - link.imported_blocks >= MAX_PENDING_BLOCKS { + // Queue is still full, so wait until there is room to insert our block. + match Pin::new(&mut delay).poll(cx) { + Poll::Pending => { + state = Some(ImportState::WaitingForImportQueueToCatchUp { + block_iter, delay, block + }); + return Poll::Pending + }, + Poll::Ready(_) => { + delay.reset(Duration::from_millis(DELAY_TIME)); + }, + } + state = Some(ImportState::WaitingForImportQueueToCatchUp { + block_iter, delay, block + }); + } else { + // Queue is no longer full, so we can add our block to the queue. + import_block_to_queue(block, queue, force); + // Switch back to Reading state. + state = Some(ImportState::Reading{block_iter}); + } + }, + ImportState::WaitingForImportQueueToFinish { + num_expected_blocks, read_block_count, mut delay + } => { + // All the blocks have been added to the queue, which doesn't mean they + // have all been properly imported. + if importing_is_done(num_expected_blocks, read_block_count, link.imported_blocks) { + // Importing is done, we can log the result and return. + info!( + "🎉 Imported {} blocks. Best: #{}", + read_block_count, client.usage_info().chain.best_number + ); + return Poll::Ready(Ok(())) + } else { + // Importing is not done, we still have to wait for the queue to finish. + // Wait for the delay, because we know the queue is lagging behind. + match Pin::new(&mut delay).poll(cx) { + Poll::Pending => { + state = Some(ImportState::WaitingForImportQueueToFinish { + num_expected_blocks, read_block_count, delay + }); + return Poll::Pending + }, + Poll::Ready(_) => { + delay.reset(Duration::from_millis(DELAY_TIME)); + }, + } + + state = Some(ImportState::WaitingForImportQueueToFinish { + num_expected_blocks, read_block_count, delay + }); + } + } + } + + queue.poll_actions(cx, &mut link); + + let best_number = client.usage_info().chain.best_number; + speedometer.notify_user(best_number); + + if link.has_error { + return Poll::Ready(Err( + Error::Other( + format!("Stopping after #{} blocks because of an error", link.imported_blocks) + ) + )) + } + + cx.waker().wake_by_ref(); + Poll::Pending + }); + Box::pin(import) +} diff --git a/primitives/phragmen/fuzzer/src/common.rs b/client/service/src/chain_ops/mod.rs similarity index 71% rename from primitives/phragmen/fuzzer/src/common.rs rename to client/service/src/chain_ops/mod.rs index 3429dcb20adde2e260d66cf9be76df9f0420ec39..af6e6f632fc06438f8396c158425d57d30727ecd 100644 --- a/primitives/phragmen/fuzzer/src/common.rs +++ b/client/service/src/chain_ops/mod.rs @@ -14,16 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -//! Common fuzzing utils. +//! Chain utilities. -/// converts x into the range [a, b] in a pseudo-fair way. -pub fn to_range(x: usize, a: usize, b: usize) -> usize { - // does not work correctly if b < 2*a - assert!(b > 2 * a); - let collapsed = x % b; - if collapsed >= a { - collapsed - } else { - collapsed + a - } -} +mod check_block; +mod export_blocks; +mod export_raw_state; +mod import_blocks; +mod revert_chain; + +pub use check_block::*; +pub use export_blocks::*; +pub use export_raw_state::*; +pub use import_blocks::*; +pub use revert_chain::*; diff --git a/client/service/src/chain_ops/revert_chain.rs b/client/service/src/chain_ops/revert_chain.rs new file mode 100644 index 0000000000000000000000000000000000000000..eaee2c03f9b316b0759ea5add478a32557ccad18 --- /dev/null +++ b/client/service/src/chain_ops/revert_chain.rs @@ -0,0 +1,43 @@ +// Copyright 2017-2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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 Substrate. If not, see . + +use crate::error::Error; +use log::info; +use sp_runtime::traits::{Block as BlockT, NumberFor, Zero}; +use sc_client_api::{Backend, UsageProvider}; +use std::sync::Arc; + +/// Performs a revert of `blocks` blocks. +pub fn revert_chain( + client: Arc, + backend: Arc, + blocks: NumberFor +) -> Result<(), Error> +where + B: BlockT, + C: UsageProvider, + BA: Backend, +{ + let reverted = backend.revert(blocks, false)?; + let info = client.usage_info().chain; + + if reverted.0.is_zero() { + info!("There aren't any non-finalized blocks to revert."); + } else { + info!("Reverted {} blocks. Best: #{} ({})", reverted.0, info.best_number, info.best_hash); + } + Ok(()) +} diff --git a/client/service/src/client/block_rules.rs b/client/service/src/client/block_rules.rs index e5614511817d35b5f2dbe4ebfb9501c5410553ec..be84614c2a5905a322c562daae3df51f0148e8f6 100644 --- a/client/service/src/client/block_rules.rs +++ b/client/service/src/client/block_rules.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Client fixed chain specification rules @@ -28,7 +30,7 @@ use sc_client_api::{ForkBlocks, BadBlocks}; pub enum LookupResult { /// Specification rules do not contain any special rules about this block NotSpecial, - /// The bock is known to be bad and should not be imported + /// The block is known to be bad and should not be imported KnownBad, /// There is a specified canonical block hash for the given height Expected(B::Hash) @@ -50,11 +52,16 @@ impl BlockRules { bad_blocks: BadBlocks, ) -> Self { Self { - bad: bad_blocks.unwrap_or(HashSet::new()), - forks: fork_blocks.unwrap_or(vec![]).into_iter().collect(), + bad: bad_blocks.unwrap_or_else(|| HashSet::new()), + forks: fork_blocks.unwrap_or_else(|| vec![]).into_iter().collect(), } } + /// Mark a new block as bad. + pub fn mark_bad(&mut self, hash: B::Hash) { + self.bad.insert(hash); + } + /// Check if there's any rule affecting the given block. pub fn lookup(&self, number: NumberFor, hash: &B::Hash) -> LookupResult { if let Some(hash_for_height) = self.forks.get(&number) { @@ -64,7 +71,7 @@ impl BlockRules { } if self.bad.contains(hash) { - return LookupResult::KnownBad; + return LookupResult::KnownBad } LookupResult::NotSpecial diff --git a/client/service/src/client/call_executor.rs b/client/service/src/client/call_executor.rs index 229e7478e939f818977c268e2b57e9fae9422a5f..1919c76ff489b7701c27b3bc495530daab0bf6d8 100644 --- a/client/service/src/client/call_executor.rs +++ b/client/service/src/client/call_executor.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{sync::Arc, panic::UnwindSafe, result, cell::RefCell}; use codec::{Encode, Decode}; @@ -25,9 +27,12 @@ use sp_state_machine::{ }; use sc_executor::{RuntimeVersion, RuntimeInfo, NativeVersion}; use sp_externalities::Extensions; -use sp_core::{NativeOrEncoded, NeverNativeValue, traits::CodeExecutor, offchain::storage::OffchainOverlayedChanges}; +use sp_core::{ + NativeOrEncoded, NeverNativeValue, traits::{CodeExecutor, SpawnNamed}, + offchain::storage::OffchainOverlayedChanges, +}; use sp_api::{ProofRecorder, InitializeBlock, StorageTransactionCache}; -use sc_client_api::{backend, call_executor::CallExecutor, CloneableSpawn}; +use sc_client_api::{backend, call_executor::CallExecutor}; use super::client::ClientConfig; /// Call executor that executes methods locally, querying all required @@ -35,7 +40,7 @@ use super::client::ClientConfig; pub struct LocalCallExecutor { backend: Arc, executor: E, - spawn_handle: Box, + spawn_handle: Box, client_config: ClientConfig, } @@ -44,7 +49,7 @@ impl LocalCallExecutor { pub fn new( backend: Arc, executor: E, - spawn_handle: Box, + spawn_handle: Box, client_config: ClientConfig, ) -> Self { LocalCallExecutor { @@ -240,7 +245,7 @@ where method: &str, call_data: &[u8] ) -> Result<(Vec, StorageProof), sp_blockchain::Error> { - sp_state_machine::prove_execution_on_trie_backend::<_, _, NumberFor, _>( + sp_state_machine::prove_execution_on_trie_backend::<_, _, NumberFor, _, _>( trie_state, overlay, &self.executor, diff --git a/client/service/src/client/client.rs b/client/service/src/client/client.rs index bc992291bdbf2bdba57cacb746d26860854c0324..d0859f4ee0392d2efb8c161c79f5a69aba8607b5 100644 --- a/client/service/src/client/client.rs +++ b/client/service/src/client/client.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate Client @@ -26,8 +28,9 @@ use parking_lot::{Mutex, RwLock}; use codec::{Encode, Decode}; use hash_db::Prefix; use sp_core::{ - ChangesTrieConfiguration, convert_hash, NativeOrEncoded, - storage::{StorageKey, PrefixedStorageKey, StorageData, well_known_keys, ChildInfo}, + convert_hash, + storage::{well_known_keys, ChildInfo, PrefixedStorageKey, StorageData, StorageKey}, + ChangesTrieConfiguration, ExecutionContext, NativeOrEncoded, }; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; use sp_runtime::{ @@ -78,25 +81,24 @@ use sc_client_api::{ KeyIterator, CallExecutor, ExecutorProvider, ProofProvider, cht, UsageProvider }; -use sp_utils::mpsc::tracing_unbounded; +use sp_utils::mpsc::{TracingUnboundedSender, tracing_unbounded}; use sp_blockchain::Error; use prometheus_endpoint::Registry; use super::{ - genesis, - light::{call_executor::prove_execution, fetcher::ChangesProof}, - block_rules::{BlockRules, LookupResult as BlockLookupResult}, + genesis, block_rules::{BlockRules, LookupResult as BlockLookupResult}, }; -use futures::channel::mpsc; +use sc_light::{call_executor::prove_execution, fetcher::ChangesProof}; +use rand::Rng; #[cfg(feature="test-helpers")] use { - sp_core::traits::CodeExecutor, - sc_client_api::{CloneableSpawn, in_mem}, + sp_core::traits::{CodeExecutor, SpawnNamed}, + sc_client_api::in_mem, sc_executor::RuntimeInfo, super::call_executor::LocalCallExecutor, }; -type NotificationSinks = Mutex>>; +type NotificationSinks = Mutex>>; /// Substrate Client pub struct Client where Block: BlockT { @@ -147,7 +149,7 @@ pub fn new_in_mem( genesis_storage: &S, keystore: Option, prometheus_registry: Option, - spawn_handle: Box, + spawn_handle: Box, config: ClientConfig, ) -> sp_blockchain::Result, @@ -187,7 +189,7 @@ pub fn new_with_backend( executor: E, build_genesis_storage: &S, keystore: Option, - spawn_handle: Box, + spawn_handle: Box, prometheus_registry: Option, config: ClientConfig, ) -> sp_blockchain::Result, Block, RA>> @@ -351,13 +353,6 @@ impl Client where self.executor.runtime_version(id) } - /// Get block hash by number. - pub fn block_hash(&self, - block_number: <::Header as HeaderT>::Number - ) -> sp_blockchain::Result> { - self.backend.blockchain().hash(block_number) - } - /// Reads given header and generates CHT-based header proof for CHT of given size. pub fn header_proof_with_cht_size( &self, @@ -661,8 +656,6 @@ impl Client where if let Ok(ImportResult::Imported(ref aux)) = result { if aux.is_new_best { - use rand::Rng; - // don't send telemetry block import events during initial sync for every // block to avoid spamming the telemetry server, these events will be randomly // sent at a rate of 1/10. @@ -753,11 +746,6 @@ impl Client where ) = storage_changes.into_inner(); if self.config.offchain_indexing_api { - // if let Some(mut offchain_storage) = self.backend.offchain_storage() { - // offchain_sc.iter().for_each(|(k,v)| { - // offchain_storage.set(b"block-import-info", k,v) - // }); - // } operation.op.update_offchain_storage(offchain_sc)?; } @@ -786,15 +774,15 @@ impl Client where NewBlockState::Normal }; - let retracted = if is_new_best { + let tree_route = if is_new_best && info.best_hash != parent_hash { let route_from_best = sp_blockchain::tree_route( self.backend.blockchain(), info.best_hash, parent_hash, )?; - route_from_best.retracted().iter().rev().map(|e| e.hash.clone()).collect() + Some(route_from_best) } else { - Vec::default() + None }; trace!( @@ -825,7 +813,7 @@ impl Client where header: import_headers.into_post(), is_new_best, storage_changes, - retracted, + tree_route, }) } @@ -864,9 +852,15 @@ impl Client where // block. (true, ref mut storage_changes @ None, Some(ref body)) => { let runtime_api = self.runtime_api(); + let execution_context = if import_block.origin == BlockOrigin::NetworkInitialSync { + ExecutionContext::Syncing + } else { + ExecutionContext::Importing + }; - runtime_api.execute_block( + runtime_api.execute_block_with_context( &at, + execution_context, Block::new(import_block.header.clone(), body.clone()), )?; @@ -954,7 +948,7 @@ impl Client where // we'll send notifications spuriously in that case. const MAX_TO_NOTIFY: usize = 256; let enacted = route_from_finalized.enacted(); - let start = enacted.len() - ::std::cmp::min(enacted.len(), MAX_TO_NOTIFY); + let start = enacted.len() - std::cmp::min(enacted.len(), MAX_TO_NOTIFY); for finalized in &enacted[start..] { operation.notify_finalized.push(finalized.hash); } @@ -978,14 +972,27 @@ impl Client where return Ok(()); } - for finalized_hash in notify_finalized { - let header = self.header(&BlockId::Hash(finalized_hash))? - .expect("header already known to exist in DB because it is indicated in the tree route; qed"); + // We assume the list is sorted and only want to inform the + // telemetry once about the finalized block. + if let Some(last) = notify_finalized.last() { + let header = self.header(&BlockId::Hash(*last))? + .expect( + "Header already known to exist in DB because it is \ + indicated in the tree route; qed" + ); telemetry!(SUBSTRATE_INFO; "notify.finalized"; "height" => format!("{}", header.number()), - "best" => ?finalized_hash, + "best" => ?last, ); + } + + for finalized_hash in notify_finalized { + let header = self.header(&BlockId::Hash(finalized_hash))? + .expect( + "Header already known to exist in DB because it is \ + indicated in the tree route; qed" + ); let notification = FinalityNotification { header, @@ -1034,7 +1041,7 @@ impl Client where origin: notify_import.origin, header: notify_import.header, is_new_best: notify_import.is_new_best, - retracted: notify_import.retracted, + tree_route: notify_import.tree_route.map(Arc::new), }; self.import_notification_sinks.lock() @@ -1047,20 +1054,31 @@ impl Client where /// reverted past the last finalized block. Returns the number of blocks /// that were successfully reverted. pub fn revert(&self, n: NumberFor) -> sp_blockchain::Result> { - Ok(self.backend.revert(n, false)?) + let (number, _) = self.backend.revert(n, false)?; + Ok(number) } - /// Attempts to revert the chain by `n` blocks disregarding finality. This - /// method will revert any finalized blocks as requested and can potentially - /// leave the node in an inconsistent state. Other modules in the system that - /// persist data and that rely on finality (e.g. consensus parts) will be - /// unaffected by the revert. Use this method with caution and making sure - /// that no other data needs to be reverted for consistency aside from the - /// block data. + /// Attempts to revert the chain by `n` blocks disregarding finality. This method will revert + /// any finalized blocks as requested and can potentially leave the node in an inconsistent + /// state. Other modules in the system that persist data and that rely on finality + /// (e.g. consensus parts) will be unaffected by the revert. Use this method with caution and + /// making sure that no other data needs to be reverted for consistency aside from the block + /// data. If `blacklist` is set to true, will also blacklist reverted blocks from finalizing + /// again. The blacklist is reset upon client restart. /// /// Returns the number of blocks that were successfully reverted. - pub fn unsafe_revert(&self, n: NumberFor) -> sp_blockchain::Result> { - Ok(self.backend.revert(n, true)?) + pub fn unsafe_revert( + &mut self, + n: NumberFor, + blacklist: bool, + ) -> sp_blockchain::Result> { + let (number, reverted) = self.backend.revert(n, true)?; + if blacklist { + for b in reverted { + self.block_rules.mark_bad(b); + } + } + Ok(number) } /// Get blockchain info. @@ -1911,6 +1929,10 @@ impl BlockBackend for Client fn justification(&self, id: &BlockId) -> sp_blockchain::Result> { self.backend.blockchain().justification(*id) } + + fn block_hash(&self, number: NumberFor) -> sp_blockchain::Result> { + self.backend.blockchain().hash(number) + } } impl backend::AuxStore for Client diff --git a/client/service/src/client/genesis.rs b/client/service/src/client/genesis.rs index 41dbccc517390ff0a3884a59b35989327e546e06..4df08025e38264ab0a5f5b09631c95e4681d1b10 100644 --- a/client/service/src/client/genesis.rs +++ b/client/service/src/client/genesis.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Tool for creating the genesis block. diff --git a/client/service/src/client/light.rs b/client/service/src/client/light.rs new file mode 100644 index 0000000000000000000000000000000000000000..e8e1286eccdb0f487c1e628fea5787ddcc7f0795 --- /dev/null +++ b/client/service/src/client/light.rs @@ -0,0 +1,75 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +//! Light client utilities. + +use std::sync::Arc; + +use sc_executor::RuntimeInfo; +use sp_core::traits::{CodeExecutor, SpawnNamed}; +use sp_runtime::BuildStorage; +use sp_runtime::traits::{Block as BlockT, HashFor}; +use sp_blockchain::Result as ClientResult; +use prometheus_endpoint::Registry; + +use super::{call_executor::LocalCallExecutor, client::{Client, ClientConfig}}; +use sc_client_api::light::Storage as BlockchainStorage; +use sc_light::{Backend, GenesisCallExecutor}; + + +/// Create an instance of light client. +pub fn new_light( + backend: Arc>>, + genesis_storage: &dyn BuildStorage, + code_executor: E, + spawn_handle: Box, + prometheus_registry: Option, +) -> ClientResult< + Client< + Backend>, + GenesisCallExecutor< + Backend>, + LocalCallExecutor>, E> + >, + B, + RA + > + > + where + B: BlockT, + S: BlockchainStorage + 'static, + E: CodeExecutor + RuntimeInfo + Clone + 'static, +{ + let local_executor = LocalCallExecutor::new( + backend.clone(), + code_executor, + spawn_handle.clone(), + ClientConfig::default() + ); + let executor = GenesisCallExecutor::new(backend.clone(), local_executor); + Client::new( + backend, + executor, + genesis_storage, + Default::default(), + Default::default(), + Default::default(), + prometheus_registry, + ClientConfig::default(), + ) +} diff --git a/client/service/src/client/light/mod.rs b/client/service/src/client/light/mod.rs deleted file mode 100644 index 9b3c3f5b29042a16ce402505a80a989f44269382..0000000000000000000000000000000000000000 --- a/client/service/src/client/light/mod.rs +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -//! Light client components. - -pub mod backend; -pub mod blockchain; -pub mod call_executor; -pub mod fetcher; - -use std::sync::Arc; - -use sc_executor::RuntimeInfo; -use sp_core::traits::CodeExecutor; -use sp_runtime::BuildStorage; -use sp_runtime::traits::{Block as BlockT, HashFor}; -use sp_blockchain::Result as ClientResult; -use prometheus_endpoint::Registry; - -use super::call_executor::LocalCallExecutor; -use super::client::{Client,ClientConfig}; -use sc_client_api::{ - light::Storage as BlockchainStorage, CloneableSpawn, -}; -use self::backend::Backend; -use self::blockchain::Blockchain; -use self::call_executor::GenesisCallExecutor; -use self::fetcher::LightDataChecker; - -/// Create an instance of light client blockchain backend. -pub fn new_light_blockchain>(storage: S) -> Arc> { - Arc::new(Blockchain::new(storage)) -} - -/// Create an instance of light client backend. -pub fn new_light_backend(blockchain: Arc>) -> Arc>> - where - B: BlockT, - S: BlockchainStorage, -{ - Arc::new(Backend::new(blockchain)) -} - -/// Create an instance of light client. -pub fn new_light( - backend: Arc>>, - genesis_storage: &dyn BuildStorage, - code_executor: E, - spawn_handle: Box, - prometheus_registry: Option, -) -> ClientResult< - Client< - Backend>, - GenesisCallExecutor< - Backend>, - LocalCallExecutor>, E> - >, - B, - RA - > - > - where - B: BlockT, - S: BlockchainStorage + 'static, - E: CodeExecutor + RuntimeInfo + Clone + 'static, -{ - let local_executor = LocalCallExecutor::new(backend.clone(), code_executor, spawn_handle.clone(), ClientConfig::default()); - let executor = GenesisCallExecutor::new(backend.clone(), local_executor); - Client::new( - backend, - executor, - genesis_storage, - Default::default(), - Default::default(), - Default::default(), - prometheus_registry, - ClientConfig::default(), - ) -} - -/// Create an instance of fetch data checker. -pub fn new_fetch_checker>( - blockchain: Arc>, - executor: E, - spawn_handle: Box, -) -> LightDataChecker, B, S> - where - E: CodeExecutor, -{ - LightDataChecker::new(blockchain, executor, spawn_handle) -} diff --git a/client/service/src/client/mod.rs b/client/service/src/client/mod.rs index fe3ad992b6690dcf0e9aae19bb3e855d4078581a..7c96f61a7867a6f68aab035e69494db8e53d748a 100644 --- a/client/service/src/client/mod.rs +++ b/client/service/src/client/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate Client and associated logic. //! diff --git a/client/service/src/config.rs b/client/service/src/config.rs index e0de85b56d598667b2774788825e6e4da847cb47..15783a87f9917ae2818bdb4ef14bc11fdf9a5fa8 100644 --- a/client/service/src/config.rs +++ b/client/service/src/config.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Service configuration. @@ -22,23 +24,26 @@ pub use sc_network::config::{ExtTransport, MultiaddrWithPeerId, NetworkConfigura pub use sc_executor::WasmExecutionMethod; use sc_client_api::execution_extensions::ExecutionStrategies; -use std::{future::Future, path::{PathBuf, Path}, pin::Pin, net::SocketAddr, sync::Arc}; +use std::{io, future::Future, path::{PathBuf, Path}, pin::Pin, net::SocketAddr, sync::Arc}; pub use sc_transaction_pool::txpool::Options as TransactionPoolOptions; use sc_chain_spec::ChainSpec; -use sp_core::crypto::Protected; +use sp_core::crypto::SecretString; pub use sc_telemetry::TelemetryEndpoints; use prometheus_endpoint::Registry; +#[cfg(not(target_os = "unknown"))] +use tempfile::TempDir; /// Service configuration. +#[derive(Debug)] pub struct Configuration { /// Implementation name - pub impl_name: &'static str, + pub impl_name: String, /// Implementation version (see sc-cli to see an example of format) - pub impl_version: &'static str, + pub impl_version: String, /// Node role. pub role: Role, /// How to spawn background tasks. Mandatory, otherwise creating a `Service` will error. - pub task_executor: Arc + Send>>, TaskType) + Send + Sync>, + pub task_executor: TaskExecutor, /// Extrinsic pool configuration. pub transaction_pool: TransactionPoolOptions, /// Network configuration. @@ -63,6 +68,8 @@ pub struct Configuration { pub rpc_http: Option, /// RPC over Websockets binding address. `None` if disabled. pub rpc_ws: Option, + /// RPC over IPC binding path. `None` if disabled. + pub rpc_ipc: Option, /// Maximum number of connections for WebSockets RPC server. `None` if default. pub rpc_ws_max_connections: Option, /// CORS settings for HTTP & WS servers. `None` if all origins are allowed. @@ -100,6 +107,10 @@ pub struct Configuration { pub max_runtime_instances: usize, /// Announce block automatically after they have been imported pub announce_block: bool, + /// Base path of the configuration + pub base_path: Option, + /// Configuration of the output format that the informant uses. + pub informant_output_format: sc_informant::OutputFormat, } /// Type for tasks spawned by the executor. @@ -112,14 +123,14 @@ pub enum TaskType { } /// Configuration of the client keystore. -#[derive(Clone)] +#[derive(Debug, Clone)] pub enum KeystoreConfig { /// Keystore at a path on-disk. Recommended for native nodes. Path { /// The path of the keystore. path: PathBuf, /// Node keystore's password. - password: Option> + password: Option }, /// In-memory keystore. Recommended for in-browser nodes. InMemory, @@ -135,7 +146,7 @@ impl KeystoreConfig { } } /// Configuration of the database of the client. -#[derive(Clone, Default)] +#[derive(Debug, Clone, Default)] pub struct OffchainWorkerConfig { /// If this is allowed. pub enabled: bool, @@ -144,7 +155,7 @@ pub struct OffchainWorkerConfig { } /// Configuration of the Prometheus endpoint. -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct PrometheusConfig { /// Port to use. pub port: SocketAddr, @@ -170,6 +181,11 @@ impl Configuration { pub fn display_role(&self) -> String { self.role.to_string() } + + /// Returns the prometheus metrics registry, if available. + pub fn prometheus_registry<'a>(&'a self) -> Option<&'a Registry> { + self.prometheus_config.as_ref().map(|config| &config.registry) + } } /// Available RPC methods. @@ -189,3 +205,119 @@ impl Default for RpcMethods { RpcMethods::Auto } } + +/// The base path that is used for everything that needs to be write on disk to run a node. +#[derive(Debug)] +pub enum BasePath { + /// A temporary directory is used as base path and will be deleted when dropped. + #[cfg(not(target_os = "unknown"))] + Temporary(TempDir), + /// A path on the disk. + Permanenent(PathBuf), +} + +impl BasePath { + /// Create a `BasePath` instance using a temporary directory prefixed with "substrate" and use + /// it as base path. + /// + /// Note: the temporary directory will be created automatically and deleted when the `BasePath` + /// instance is dropped. + #[cfg(not(target_os = "unknown"))] + pub fn new_temp_dir() -> io::Result { + Ok(BasePath::Temporary( + tempfile::Builder::new().prefix("substrate").tempdir()?, + )) + } + + /// Create a `BasePath` instance based on an existing path on disk. + /// + /// Note: this function will not ensure that the directory exist nor create the directory. It + /// will also not delete the directory when the instance is dropped. + pub fn new>(path: P) -> BasePath { + BasePath::Permanenent(path.as_ref().to_path_buf()) + } + + /// Create a base path from values describing the project. + #[cfg(not(target_os = "unknown"))] + pub fn from_project(qualifier: &str, organization: &str, application: &str) -> BasePath { + BasePath::new( + directories::ProjectDirs::from(qualifier, organization, application) + .expect("app directories exist on all supported platforms; qed") + .data_local_dir(), + ) + } + + /// Retrieve the base path. + pub fn path(&self) -> &Path { + match self { + #[cfg(not(target_os = "unknown"))] + BasePath::Temporary(temp_dir) => temp_dir.path(), + BasePath::Permanenent(path) => path.as_path(), + } + } +} + +impl std::convert::From for BasePath { + fn from(path: PathBuf) -> Self { + BasePath::new(path) + } +} + +// NOTE: here for code readability. +pub(crate) type SomeFuture = Pin + Send>>; +pub(crate) type JoinFuture = Pin + Send>>; + +/// Callable object that execute tasks. +/// +/// This struct can be created easily using `Into`. +/// +/// # Examples +/// +/// ## Using tokio +/// +/// ``` +/// # use sc_service::TaskExecutor; +/// use futures::future::FutureExt; +/// use tokio::runtime::Runtime; +/// +/// let runtime = Runtime::new().unwrap(); +/// let handle = runtime.handle().clone(); +/// let task_executor: TaskExecutor = (move |future, _task_type| { +/// handle.spawn(future).map(|_| ()) +/// }).into(); +/// ``` +/// +/// ## Using async-std +/// +/// ``` +/// # use sc_service::TaskExecutor; +/// let task_executor: TaskExecutor = (|future, _task_type| { +/// // NOTE: async-std's JoinHandle is not a Result so we don't need to map the result +/// async_std::task::spawn(future) +/// }).into(); +/// ``` +#[derive(Clone)] +pub struct TaskExecutor(Arc JoinFuture + Send + Sync>); + +impl std::fmt::Debug for TaskExecutor { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "TaskExecutor") + } +} + +impl std::convert::From for TaskExecutor +where + F: Fn(SomeFuture, TaskType) -> FUT + Send + Sync + 'static, + FUT: Future + Send + 'static, +{ + fn from(func: F) -> Self { + Self(Arc::new(move |fut, tt| Box::pin(func(fut, tt)))) + } +} + +impl TaskExecutor { + /// Spawns a new asynchronous task. + pub fn spawn(&self, future: SomeFuture, task_type: TaskType) -> JoinFuture { + self.0(future, task_type) + } +} diff --git a/client/service/src/error.rs b/client/service/src/error.rs index 5a78a1878923080ee05d2c5c46568356b8a71a59..ffe1b39405501d224b7c56f40facb11776775f10 100644 --- a/client/service/src/error.rs +++ b/client/service/src/error.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Errors that can occur during the service operation. diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index ad42a2b39f61fe02d417d1f35558baa9626cbb66..d19b9f5ea247d7467ba549a5de8f79287475e611 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -1,27 +1,28 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate service. Starts a thread that spins up the network, client, and extrinsic pool. //! Manages communication between them. #![warn(missing_docs)] -#![recursion_limit="128"] +#![recursion_limit = "1024"] pub mod config; -#[macro_use] pub mod chain_ops; pub mod error; @@ -31,40 +32,35 @@ mod builder; pub mod client; #[cfg(not(feature = "test-helpers"))] mod client; -mod status_sinks; mod task_manager; use std::{io, pin::Pin}; -use std::marker::PhantomData; use std::net::SocketAddr; use std::collections::HashMap; use std::time::Duration; -use wasm_timer::Instant; -use std::task::{Poll, Context}; +use std::task::Poll; use parking_lot::Mutex; -use client::Client; -use futures::{ - Future, FutureExt, Stream, StreamExt, - compat::*, - sink::SinkExt, - task::{Spawn, FutureObj, SpawnError}, -}; -use sc_network::{NetworkService, network_state::NetworkState, PeerId}; -use log::{log, warn, debug, error, Level}; +use futures::{Future, FutureExt, Stream, StreamExt, stream, compat::*}; +use sc_network::{NetworkStatus, network_state::NetworkState, PeerId}; +use log::{warn, debug, error}; use codec::{Encode, Decode}; use sp_runtime::generic::BlockId; -use sp_runtime::traits::{NumberFor, Block as BlockT}; +use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use parity_util_mem::MallocSizeOf; -use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}; +use sp_utils::{status_sinks, mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender}}; pub use self::error::Error; pub use self::builder::{ - new_full_client, new_client, - ServiceBuilder, ServiceBuilderCommand, TFullClient, TLightClient, TFullBackend, TLightBackend, - TFullCallExecutor, TLightCallExecutor, + new_full_client, new_client, new_full_parts, new_light_parts, + spawn_tasks, build_network, BuildNetworkParams, NetworkStarter, build_offchain_workers, + SpawnTasksParams, TFullClient, TLightClient, TFullBackend, TLightBackend, + TLightBackendWithHash, TLightClientWithBackend, + TFullCallExecutor, TLightCallExecutor, RpcExtensionBuilder, NoopRpcExtensionBuilder, +}; +pub use config::{ + BasePath, Configuration, DatabaseConfig, PruningMode, Role, RpcMethods, TaskExecutor, TaskType, }; -pub use config::{Configuration, DatabaseConfig, PruningMode, Role, RpcMethods, TaskType}; pub use sc_chain_spec::{ ChainSpec, GenericChainSpec, Properties, RuntimeGenesis, Extension as ChainSpecExtension, NoExtension, ChainType, @@ -82,13 +78,10 @@ pub use sc_network::config::{ }; pub use sc_tracing::TracingReceiver; pub use task_manager::SpawnTaskHandle; -use task_manager::TaskManager; -use sp_blockchain::{HeaderBackend, HeaderMetadata}; -use sp_api::{ApiExt, ConstructRuntimeApi, ApiErrorExt}; -use sc_client_api::{ - Backend as BackendT, BlockchainEvents, CallExecutor, UsageProvider, -}; -use sp_block_builder::BlockBuilder; +pub use task_manager::TaskManager; +pub use sp_consensus::import_queue::ImportQueue; +use sc_client_api::BlockchainEvents; +pub use sc_keystore::KeyStorePtr as KeyStore; const DEFAULT_PROTOCOL_ID: &str = "sup"; @@ -102,79 +95,11 @@ impl MallocSizeOfWasm for T {} #[cfg(target_os = "unknown")] impl MallocSizeOfWasm for T {} -/// Substrate service. -pub struct Service { - client: Arc, - task_manager: TaskManager, - select_chain: Option, - network: Arc, - /// Sinks to propagate network status updates. - /// For each element, every time the `Interval` fires we push an element on the sender. - network_status_sinks: Arc>>, - transaction_pool: Arc, - /// Send a signal when a spawned essential task has concluded. The next time - /// the service future is polled it should complete with an error. - essential_failed_tx: TracingUnboundedSender<()>, - /// A receiver for spawned essential-tasks concluding. - essential_failed_rx: TracingUnboundedReceiver<()>, - rpc_handlers: sc_rpc_server::RpcHandler, - _rpc: Box, - _telemetry: Option, - _telemetry_on_connect_sinks: Arc>>>, - _offchain_workers: Option>, - keystore: sc_keystore::KeyStorePtr, - marker: PhantomData, - prometheus_registry: Option, -} - -impl Unpin for Service {} - -/// Abstraction over a Substrate service. -pub trait AbstractService: Future> + Send + Unpin + Spawn + 'static { - /// Type of block of this chain. - type Block: BlockT; - /// Backend storage for the client. - type Backend: 'static + BackendT; - /// How to execute calls towards the runtime. - type CallExecutor: 'static + CallExecutor + Send + Sync + Clone; - /// API that the runtime provides. - type RuntimeApi: Send + Sync; - /// Chain selection algorithm. - type SelectChain: sp_consensus::SelectChain; - /// Transaction pool. - type TransactionPool: TransactionPool + MallocSizeOfWasm; - /// The generic Client type, the bounds here are the ones specifically required by - /// internal crates like sc_informant. - type Client: - HeaderMetadata + UsageProvider - + BlockchainEvents + HeaderBackend + Send + Sync; - - /// Get event stream for telemetry connection established events. - fn telemetry_on_connect_stream(&self) -> TracingUnboundedReceiver<()>; - - /// return a shared instance of Telemetry (if enabled) - fn telemetry(&self) -> Option; - - /// Spawns a task in the background that runs the future passed as parameter. - /// - /// Information about this task will be reported to Prometheus. - /// - /// The task name is a `&'static str` as opposed to a `String`. The reason for that is that - /// in order to avoid memory consumption issues with the Prometheus metrics, the set of - /// possible task names has to be bounded. - fn spawn_task(&self, name: &'static str, task: impl Future + Send + 'static); - - /// Spawns a task in the background that runs the future passed as - /// parameter. The given task is considered essential, i.e. if it errors we - /// trigger a service exit. - fn spawn_essential_task(&self, name: &'static str, task: impl Future + Send + 'static); - - /// Returns a handle for spawning tasks. - fn spawn_task_handle(&self) -> SpawnTaskHandle; - - /// Returns the keystore that stores keys. - fn keystore(&self) -> sc_keystore::KeyStorePtr; +/// RPC handlers that can perform RPC queries. +#[derive(Clone)] +pub struct RpcHandlers(Arc>); +impl RpcHandlers { /// Starts an RPC query. /// /// The query is passed as a string and must be a JSON text similar to what an HTTP client @@ -184,170 +109,82 @@ pub trait AbstractService: Future> + Send + Unpin + S /// /// If the request subscribes you to events, the `Sender` in the `RpcSession` object is used to /// send back spontaneous events. - fn rpc_query(&self, mem: &RpcSession, request: &str) -> Pin> + Send>>; - - /// Get shared client instance. - fn client(&self) -> Arc; - - /// Get clone of select chain. - fn select_chain(&self) -> Option; - - /// Get shared network instance. - fn network(&self) - -> Arc::Hash>>; - - /// Returns a receiver that periodically receives a status of the network. - fn network_status(&self, interval: Duration) -> TracingUnboundedReceiver<(NetworkStatus, NetworkState)>; - - /// Get shared transaction pool instance. - fn transaction_pool(&self) -> Arc; - - /// Get a handle to a future that will resolve on exit. - #[deprecated(note = "Use `spawn_task`/`spawn_essential_task` instead, those functions will attach on_exit signal.")] - fn on_exit(&self) -> ::exit_future::Exit; - - /// Get the prometheus metrics registry, if available. - fn prometheus_registry(&self) -> Option; -} - -impl AbstractService for - Service, TSc, NetworkStatus, - NetworkService, TExPool, TOc> -where - TBl: BlockT, - TBackend: 'static + BackendT, - TExec: 'static + CallExecutor + Send + Sync + Clone, - TRtApi: 'static + Send + Sync + ConstructRuntimeApi>, - >>::RuntimeApi: - sp_api::Core - + ApiExt - + ApiErrorExt - + BlockBuilder, - TSc: sp_consensus::SelectChain + 'static + Clone + Send + Unpin, - TExPool: 'static + TransactionPool + MallocSizeOfWasm, - TOc: 'static + Send + Sync, -{ - type Block = TBl; - type Backend = TBackend; - type CallExecutor = TExec; - type RuntimeApi = TRtApi; - type SelectChain = TSc; - type TransactionPool = TExPool; - type Client = Client; - - fn telemetry_on_connect_stream(&self) -> TracingUnboundedReceiver<()> { - let (sink, stream) = tracing_unbounded("mpsc_telemetry_on_connect"); - self._telemetry_on_connect_sinks.lock().push(sink); - stream - } - - fn telemetry(&self) -> Option { - self._telemetry.as_ref().map(|t| t.clone()) - } - - fn keystore(&self) -> sc_keystore::KeyStorePtr { - self.keystore.clone() - } - - fn spawn_task(&self, name: &'static str, task: impl Future + Send + 'static) { - self.task_manager.spawn(name, task) - } - - fn spawn_essential_task(&self, name: &'static str, task: impl Future + Send + 'static) { - let mut essential_failed = self.essential_failed_tx.clone(); - let essential_task = std::panic::AssertUnwindSafe(task) - .catch_unwind() - .map(move |_| { - error!("Essential task `{}` failed. Shutting down service.", name); - let _ = essential_failed.send(()); - }); - - let _ = self.spawn_task(name, essential_task); - } - - fn spawn_task_handle(&self) -> SpawnTaskHandle { - self.task_manager.spawn_handle() - } - - fn rpc_query(&self, mem: &RpcSession, request: &str) -> Pin> + Send>> { - Box::pin( - self.rpc_handlers.handle_request(request, mem.metadata.clone()) - .compat() - .map(|res| res.expect("this should never fail")) - ) + pub fn rpc_query(&self, mem: &RpcSession, request: &str) + -> Pin> + Send>> { + self.0.handle_request(request, mem.metadata.clone()) + .compat() + .map(|res| res.expect("this should never fail")) + .boxed() } - fn client(&self) -> Arc { - self.client.clone() - } - - fn select_chain(&self) -> Option { - self.select_chain.clone() + /// Provides access to the underlying `MetaIoHandler` + pub fn io_handler(&self) -> Arc> { + self.0.clone() } +} - fn network(&self) - -> Arc::Hash>> - { - self.network.clone() +/// Sinks to propagate network status updates. +/// For each element, every time the `Interval` fires we push an element on the sender. +#[derive(Clone)] +pub struct NetworkStatusSinks( + Arc, NetworkState)>>, +); + +impl NetworkStatusSinks { + fn new( + sinks: Arc, NetworkState)>> + ) -> Self { + Self(sinks) } - fn network_status(&self, interval: Duration) -> TracingUnboundedReceiver<(NetworkStatus, NetworkState)> { + /// Returns a receiver that periodically receives a status of the network. + pub fn network_status(&self, interval: Duration) + -> TracingUnboundedReceiver<(NetworkStatus, NetworkState)> { let (sink, stream) = tracing_unbounded("mpsc_network_status"); - self.network_status_sinks.lock().push(interval, sink); + self.0.push(interval, sink); stream } - - fn transaction_pool(&self) -> Arc { - self.transaction_pool.clone() - } - - fn on_exit(&self) -> exit_future::Exit { - self.task_manager.on_exit() - } - - fn prometheus_registry(&self) -> Option { - self.prometheus_registry.clone() - } } -impl Future for - Service -{ - type Output = Result<(), Error>; - - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { - let this = Pin::into_inner(self); - - match Pin::new(&mut this.essential_failed_rx).poll_next(cx) { - Poll::Pending => {}, - Poll::Ready(_) => { - // Ready(None) should not be possible since we hold a live - // sender. - return Poll::Ready(Err(Error::Other("Essential task failed.".into()))); - } - } +/// Sinks to propagate telemetry connection established events. +#[derive(Default, Clone)] +pub struct TelemetryConnectionSinks(Arc>>>); - // The service future never ends. - Poll::Pending +impl TelemetryConnectionSinks { + /// Get event stream for telemetry connection established events. + pub fn on_connect_stream(&self) -> TracingUnboundedReceiver<()> { + let (sink, stream) =tracing_unbounded("mpsc_telemetry_on_connect"); + self.0.lock().push(sink); + stream } } -impl Spawn for - Service -{ - fn spawn_obj( - &self, - future: FutureObj<'static, ()> - ) -> Result<(), SpawnError> { - self.task_manager.spawn_handle().spawn("unnamed", future); - Ok(()) - } +/// An imcomplete set of chain components, but enough to run the chain ops subcommands. +pub struct PartialComponents { + /// A shared client instance. + pub client: Arc, + /// A shared backend instance. + pub backend: Arc, + /// The chain task manager. + pub task_manager: TaskManager, + /// A shared keystore instance. + pub keystore: KeyStore, + /// A chain selection algorithm instance. + pub select_chain: SelectChain, + /// An import queue. + pub import_queue: ImportQueue, + /// A shared transaction pool. + pub transaction_pool: Arc, + /// A registry of all providers of `InherentData`. + pub inherent_data_providers: sp_inherents::InherentDataProviders, + /// Everything else that needs to be passed into the main build function. + pub other: Other, } /// Builds a never-ending future that continuously polls the network. /// /// The `status_sink` contain a list of senders to send a periodic network status to. -fn build_network_future< +async fn build_network_future< B: BlockT, C: BlockchainEvents, H: sc_network::ExHashT @@ -355,155 +192,150 @@ fn build_network_future< role: Role, mut network: sc_network::NetworkWorker, client: Arc, - status_sinks: Arc, NetworkState)>>>, + status_sinks: NetworkStatusSinks, mut rpc_rx: TracingUnboundedReceiver>, should_have_peers: bool, announce_imported_blocks: bool, -) -> impl Future { +) { let mut imported_blocks_stream = client.import_notification_stream().fuse(); - let mut finality_notification_stream = client.finality_notification_stream().fuse(); - futures::future::poll_fn(move |cx| { - let before_polling = Instant::now(); + // Stream of finalized blocks reported by the client. + let mut finality_notification_stream = { + let mut finality_notification_stream = client.finality_notification_stream().fuse(); - // We poll `imported_blocks_stream`. - while let Poll::Ready(Some(notification)) = Pin::new(&mut imported_blocks_stream).poll_next(cx) { - network.on_block_imported(notification.header, notification.is_new_best); + // We tweak the `Stream` in order to merge together multiple items if they happen to be + // ready. This way, we only get the latest finalized block. + stream::poll_fn(move |cx| { + let mut last = None; + while let Poll::Ready(Some(item)) = Pin::new(&mut finality_notification_stream).poll_next(cx) { + last = Some(item); + } + if let Some(last) = last { + Poll::Ready(Some(last)) + } else { + Poll::Pending + } + }).fuse() + }; + + loop { + futures::select!{ + // List of blocks that the client has imported. + notification = imported_blocks_stream.next() => { + let notification = match notification { + Some(n) => n, + // If this stream is shut down, that means the client has shut down, and the + // most appropriate thing to do for the network future is to shut down too. + None => return, + }; + + if announce_imported_blocks { + network.service().announce_block(notification.hash, Vec::new()); + } - if announce_imported_blocks { - network.service().announce_block(notification.hash, Vec::new()); + if let sp_consensus::BlockOrigin::Own = notification.origin { + network.service().own_block_imported( + notification.hash, + notification.header.number().clone(), + ); + } } - } - // We poll `finality_notification_stream`, but we only take the last event. - let mut last = None; - while let Poll::Ready(Some(item)) = Pin::new(&mut finality_notification_stream).poll_next(cx) { - last = Some(item); - } - if let Some(notification) = last { - network.on_block_finalized(notification.hash, notification.header); - } + // List of blocks that the client has finalized. + notification = finality_notification_stream.select_next_some() => { + network.on_block_finalized(notification.hash, notification.header); + } - // Poll the RPC requests and answer them. - while let Poll::Ready(Some(request)) = Pin::new(&mut rpc_rx).poll_next(cx) { - match request { - sc_rpc::system::Request::Health(sender) => { - let _ = sender.send(sc_rpc::system::Health { - peers: network.peers_debug_info().len(), - is_syncing: network.service().is_major_syncing(), - should_have_peers, - }); - }, - sc_rpc::system::Request::LocalPeerId(sender) => { - let _ = sender.send(network.local_peer_id().to_base58()); - }, - sc_rpc::system::Request::LocalListenAddresses(sender) => { - let peer_id = network.local_peer_id().clone().into(); - let p2p_proto_suffix = sc_network::multiaddr::Protocol::P2p(peer_id); - let addresses = network.listen_addresses() - .map(|addr| addr.clone().with(p2p_proto_suffix.clone()).to_string()) - .collect(); - let _ = sender.send(addresses); - }, - sc_rpc::system::Request::Peers(sender) => { - let _ = sender.send(network.peers_debug_info().into_iter().map(|(peer_id, p)| - sc_rpc::system::PeerInfo { - peer_id: peer_id.to_base58(), - roles: format!("{:?}", p.roles), - protocol_version: p.protocol_version, - best_hash: p.best_hash, - best_number: p.best_number, - } - ).collect()); - } - sc_rpc::system::Request::NetworkState(sender) => { - if let Some(network_state) = serde_json::to_value(&network.network_state()).ok() { - let _ = sender.send(network_state); + // Answer incoming RPC requests. + request = rpc_rx.select_next_some() => { + match request { + sc_rpc::system::Request::Health(sender) => { + let _ = sender.send(sc_rpc::system::Health { + peers: network.peers_debug_info().len(), + is_syncing: network.service().is_major_syncing(), + should_have_peers, + }); + }, + sc_rpc::system::Request::LocalPeerId(sender) => { + let _ = sender.send(network.local_peer_id().to_base58()); + }, + sc_rpc::system::Request::LocalListenAddresses(sender) => { + let peer_id = network.local_peer_id().clone().into(); + let p2p_proto_suffix = sc_network::multiaddr::Protocol::P2p(peer_id); + let addresses = network.listen_addresses() + .map(|addr| addr.clone().with(p2p_proto_suffix.clone()).to_string()) + .collect(); + let _ = sender.send(addresses); + }, + sc_rpc::system::Request::Peers(sender) => { + let _ = sender.send(network.peers_debug_info().into_iter().map(|(peer_id, p)| + sc_rpc::system::PeerInfo { + peer_id: peer_id.to_base58(), + roles: format!("{:?}", p.roles), + protocol_version: p.protocol_version, + best_hash: p.best_hash, + best_number: p.best_number, + } + ).collect()); } - } - sc_rpc::system::Request::NetworkAddReservedPeer(peer_addr, sender) => { - let x = network.add_reserved_peer(peer_addr) - .map_err(sc_rpc::system::error::Error::MalformattedPeerArg); - let _ = sender.send(x); - } - sc_rpc::system::Request::NetworkRemoveReservedPeer(peer_id, sender) => { - let _ = match peer_id.parse::() { - Ok(peer_id) => { - network.remove_reserved_peer(peer_id); - sender.send(Ok(())) + sc_rpc::system::Request::NetworkState(sender) => { + if let Some(network_state) = serde_json::to_value(&network.network_state()).ok() { + let _ = sender.send(network_state); } - Err(e) => sender.send(Err(sc_rpc::system::error::Error::MalformattedPeerArg( - e.to_string(), - ))), - }; - } - sc_rpc::system::Request::NodeRoles(sender) => { - use sc_rpc::system::NodeRole; + } + sc_rpc::system::Request::NetworkAddReservedPeer(peer_addr, sender) => { + let x = network.add_reserved_peer(peer_addr) + .map_err(sc_rpc::system::error::Error::MalformattedPeerArg); + let _ = sender.send(x); + } + sc_rpc::system::Request::NetworkRemoveReservedPeer(peer_id, sender) => { + let _ = match peer_id.parse::() { + Ok(peer_id) => { + network.remove_reserved_peer(peer_id); + sender.send(Ok(())) + } + Err(e) => sender.send(Err(sc_rpc::system::error::Error::MalformattedPeerArg( + e.to_string(), + ))), + }; + } + sc_rpc::system::Request::NodeRoles(sender) => { + use sc_rpc::system::NodeRole; - let node_role = match role { - Role::Authority { .. } => NodeRole::Authority, - Role::Light => NodeRole::LightClient, - Role::Full => NodeRole::Full, - Role::Sentry { .. } => NodeRole::Sentry, - }; + let node_role = match role { + Role::Authority { .. } => NodeRole::Authority, + Role::Light => NodeRole::LightClient, + Role::Full => NodeRole::Full, + Role::Sentry { .. } => NodeRole::Sentry, + }; - let _ = sender.send(vec![node_role]); + let _ = sender.send(vec![node_role]); + } } - }; - } + } - // Interval report for the external API. - status_sinks.lock().poll(cx, || { - let status = NetworkStatus { - sync_state: network.sync_state(), - best_seen_block: network.best_seen_block(), - num_sync_peers: network.num_sync_peers(), - num_connected_peers: network.num_connected_peers(), - num_active_peers: network.num_active_peers(), - average_download_per_sec: network.average_download_per_sec(), - average_upload_per_sec: network.average_upload_per_sec(), - }; - let state = network.network_state(); - (status, state) - }); - - // Main network polling. - if let Poll::Ready(Ok(())) = Pin::new(&mut network).poll(cx).map_err(|err| { - warn!(target: "service", "Error in network: {:?}", err); - }) { - return Poll::Ready(()); + // The network worker has done something. Nothing special to do, but could be + // used in the future to perform actions in response of things that happened on + // the network. + _ = (&mut network).fuse() => {} + + // At a regular interval, we send the state of the network on what is called + // the "status sinks". + ready_sink = status_sinks.0.next().fuse() => { + let status = NetworkStatus { + sync_state: network.sync_state(), + best_seen_block: network.best_seen_block(), + num_sync_peers: network.num_sync_peers(), + num_connected_peers: network.num_connected_peers(), + num_active_peers: network.num_active_peers(), + total_bytes_inbound: network.total_bytes_inbound(), + total_bytes_outbound: network.total_bytes_outbound(), + }; + let state = network.network_state(); + ready_sink.send((status, state)); + } } - - // Now some diagnostic for performances. - let polling_dur = before_polling.elapsed(); - log!( - target: "service", - if polling_dur >= Duration::from_secs(1) { Level::Warn } else { Level::Trace }, - "⚠️ Polling the network future took {:?}", - polling_dur - ); - - Poll::Pending - }) -} - -/// Overview status of the network. -#[derive(Clone)] -pub struct NetworkStatus { - /// Current global sync state. - pub sync_state: sc_network::SyncState, - /// Target sync block number. - pub best_seen_block: Option>, - /// Number of peers participating in syncing. - pub num_sync_peers: u32, - /// Total number of connected peers - pub num_connected_peers: usize, - /// Total number of active peers. - pub num_active_peers: usize, - /// Downloaded bytes per second averaged over the past few seconds. - pub average_download_per_sec: u64, - /// Uploaded bytes per second averaged over the past few seconds. - pub average_upload_per_sec: u64, + } } #[cfg(not(target_os = "unknown"))] @@ -519,6 +351,16 @@ mod waiting { } } + pub struct IpcServer(pub Option); + impl Drop for IpcServer { + fn drop(&mut self) { + if let Some(server) = self.0.take() { + server.close_handle().close(); + let _ = server.wait(); + } + } + } + pub struct WsServer(pub Option); impl Drop for WsServer { fn drop(&mut self) { @@ -554,8 +396,8 @@ fn start_rpc_servers sc_rpc_server::RpcHandler, methods: &RpcMethods) -> sc_rpc::DenyUnsafe { - let is_exposed_addr = addr.map(|x| x.ip().is_loopback()).unwrap_or(false); + fn deny_unsafe(addr: &SocketAddr, methods: &RpcMethods) -> sc_rpc::DenyUnsafe { + let is_exposed_addr = !addr.ip().is_loopback(); match (is_exposed_addr, methods) { | (_, RpcMethods::Unsafe) | (false, RpcMethods::Auto) => sc_rpc::DenyUnsafe::No, @@ -564,12 +406,13 @@ fn start_rpc_servers sc_rpc_server::RpcHandler sc_rpc_server::RpcHandler. +// along with this program. If not, see . -use std::convert::TryFrom; +use std::{convert::TryFrom, time::SystemTime}; -use crate::NetworkStatus; -use prometheus_endpoint::{register, Gauge, U64, F64, Registry, PrometheusError, Opts, GaugeVec}; +use crate::{NetworkStatus, config::Configuration}; +use prometheus_endpoint::{register, Gauge, U64, Registry, PrometheusError, Opts, GaugeVec}; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; use sp_runtime::traits::{NumberFor, Block, SaturatedConversion, UniqueSaturatedInto}; use sp_transaction_pool::PoolStatus; use sp_utils::metrics::register_globals; use sc_client_api::ClientInfo; - -use sysinfo::{self, ProcessExt, SystemExt}; - -#[cfg(all(any(unix, windows), not(target_os = "android")))] -use netstat2::{ - TcpState, ProtocolSocketInfo, iterate_sockets_info, AddressFamilyFlags, ProtocolFlags, -}; +use sc_network::config::Role; +use wasm_timer::Instant; struct PrometheusMetrics { - // system - #[cfg(all(any(unix, windows), not(target_os = "android")))] - load_avg: GaugeVec, - - // process - cpu_usage_percentage: Gauge, - memory_usage_bytes: Gauge, - threads: Gauge, - open_files: GaugeVec, - - #[cfg(all(any(unix, windows), not(target_os = "android")))] - netstat: GaugeVec, - - // -- inner counters // generic info block_height: GaugeVec, number_leaves: Gauge, ready_transactions_number: Gauge, // I/O - network_per_sec_bytes: GaugeVec, database_cache: Gauge, state_cache: Gauge, state_db: GaugeVec, } impl PrometheusMetrics { - fn setup(registry: &Registry, name: &str, version: &str, roles: u64) - -> Result - { + fn setup( + registry: &Registry, + name: &str, + version: &str, + roles: u64, + ) -> Result { register(Gauge::::with_opts( Opts::new( "build_info", @@ -77,40 +62,14 @@ impl PrometheusMetrics { register_globals(registry)?; - Ok(Self { - // system - #[cfg(all(any(unix, windows), not(target_os = "android")))] - load_avg: register(GaugeVec::new( - Opts::new("load_avg", "System load average"), - &["over"] - )?, registry)?, - - // process - memory_usage_bytes: register(Gauge::new( - "memory_usage_bytes", "Node memory (resident set size) usage", - )?, registry)?, - - cpu_usage_percentage: register(Gauge::new( - "cpu_usage_percentage", "Node CPU usage", - )?, registry)?, - - #[cfg(all(any(unix, windows), not(target_os = "android")))] - netstat: register(GaugeVec::new( - Opts::new("netstat_tcp", "Current TCP connections "), - &["status"] - )?, registry)?, - - threads: register(Gauge::new( - "threads", "Number of threads used by the process", - )?, registry)?, - - open_files: register(GaugeVec::new( - Opts::new("open_file_handles", "Open file handlers held by the process"), - &["fd_type"] - )?, registry)?, - - // --- internal + let start_time_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) + .unwrap_or_default(); + register(Gauge::::new( + "process_start_time_seconds", + "Number of seconds between the UNIX epoch and the moment the process started", + )?, registry)?.set(start_time_since_epoch.as_secs()); + Ok(Self { // generic internals block_height: register(GaugeVec::new( Opts::new("block_height", "Block height info of the chain"), @@ -126,10 +85,6 @@ impl PrometheusMetrics { )?, registry)?, // I/ O - network_per_sec_bytes: register(GaugeVec::new( - Opts::new("network_per_sec_bytes", "Networking bytes per second"), - &["direction"] - )?, registry)?, database_cache: register(Gauge::new( "database_cache_bytes", "RocksDB cache size in bytes", )?, registry)?, @@ -144,167 +99,45 @@ impl PrometheusMetrics { } } -#[cfg(all(any(unix, windows), not(target_os = "android")))] -#[derive(Default)] -struct ConnectionsCount { - listen: u64, - established: u64, - starting: u64, - closing: u64, - closed: u64, - other: u64 -} - -#[derive(Default)] -struct FdCounter { - paths: u64, - sockets: u64, - net: u64, - pipes: u64, - anon_inode: u64, - mem: u64, - other: u64, -} - -#[derive(Default)] -struct ProcessInfo { - cpu_usage: f64, - memory: u64, - threads: Option, - open_fd: Option, -} - pub struct MetricsService { metrics: Option, - #[cfg(all(any(unix, windows), not(target_os = "android")))] - system: sysinfo::System, - pid: Option, -} - -#[cfg(target_os = "linux")] -impl MetricsService { - fn inner_new(metrics: Option) -> Self { - let process = procfs::process::Process::myself() - .expect("Procfs doesn't fail on unix. qed"); - - Self { - metrics, - system: sysinfo::System::new(), - pid: Some(process.pid), - } - } - - fn process_info(&mut self) -> ProcessInfo { - let pid = self.pid.clone().expect("unix always has a pid. qed"); - let mut info = self.process_info_for(&pid); - let process = procfs::process::Process::new(pid).expect("Our process exists. qed."); - info.threads = process.stat().ok().map(|s| - u64::try_from(s.num_threads).expect("There are no negative thread counts. qed"), - ); - info.open_fd = process.fd().ok().map(|i| - i.into_iter().fold(FdCounter::default(), |mut f, info| { - match info.target { - procfs::process::FDTarget::Path(_) => f.paths += 1, - procfs::process::FDTarget::Socket(_) => f.sockets += 1, - procfs::process::FDTarget::Net(_) => f.net += 1, - procfs::process::FDTarget::Pipe(_) => f.pipes += 1, - procfs::process::FDTarget::AnonInode(_) => f.anon_inode += 1, - procfs::process::FDTarget::MemFD(_) => f.mem += 1, - procfs::process::FDTarget::Other(_,_) => f.other += 1, - }; - f - }) - ); - info - } -} - -#[cfg(all(any(unix, windows), not(target_os = "android"), not(target_os = "linux")))] -impl MetricsService { - fn inner_new(metrics: Option) -> Self { - Self { - metrics, - system: sysinfo::System::new(), - pid: sysinfo::get_current_pid().ok(), - } - } - - fn process_info(&mut self) -> ProcessInfo { - self.pid.map(|pid| self.process_info_for(&pid)).unwrap_or_default() - } + last_update: Instant, + last_total_bytes_inbound: u64, + last_total_bytes_outbound: u64, } - -#[cfg(not(all(any(unix, windows), not(target_os = "android"))))] impl MetricsService { - fn inner_new(metrics: Option) -> Self { - Self { - metrics, - pid: None, - } - } - - fn process_info(&mut self) -> ProcessInfo { - ProcessInfo::default() - } -} - - -impl MetricsService { - pub fn with_prometheus(registry: &Registry, name: &str, version: &str, roles: u64) - -> Result - { - PrometheusMetrics::setup(registry, name, version, roles).map(|p| { - Self::inner_new(Some(p)) - }) - } - pub fn new() -> Self { - Self::inner_new(None) - } - - #[cfg(all(any(unix, windows), not(target_os = "android")))] - fn process_info_for(&mut self, pid: &sysinfo::Pid) -> ProcessInfo { - let mut info = ProcessInfo::default(); - if self.system.refresh_process(*pid) { - let prc = self.system.get_process(*pid) - .expect("Above refresh_process succeeds, this must be Some(), qed"); - info.cpu_usage = prc.cpu_usage().into(); - info.memory = prc.memory(); + MetricsService { + metrics: None, + last_total_bytes_inbound: 0, + last_total_bytes_outbound: 0, + last_update: Instant::now(), } - info } - #[cfg(all(any(unix, windows), not(target_os = "android")))] - fn connections_info(&self) -> Option { - self.pid.as_ref().and_then(|pid| { - let af_flags = AddressFamilyFlags::IPV4 | AddressFamilyFlags::IPV6; - let proto_flags = ProtocolFlags::TCP; - let netstat_pid = *pid as u32; - - iterate_sockets_info(af_flags, proto_flags).ok().map(|iter| - iter.filter_map(|r| - r.ok().and_then(|s| { - match s.protocol_socket_info { - ProtocolSocketInfo::Tcp(info) - if s.associated_pids.contains(&netstat_pid) => Some(info.state), - _ => None - } - }) - ).fold(ConnectionsCount::default(), |mut counter, socket_state| { - match socket_state { - TcpState::Listen => counter.listen += 1, - TcpState::Established => counter.established += 1, - TcpState::Closed => counter.closed += 1, - TcpState::SynSent | TcpState::SynReceived => counter.starting += 1, - TcpState::FinWait1 | TcpState::FinWait2 | TcpState::CloseWait - | TcpState::Closing | TcpState::LastAck => counter.closing += 1, - _ => counter.other += 1 - } - - counter - }) - ) + pub fn with_prometheus( + registry: &Registry, + config: &Configuration, + ) -> Result { + let role_bits = match config.role { + Role::Full => 1u64, + Role::Light => 2u64, + Role::Sentry { .. } => 3u64, + Role::Authority { .. } => 4u64, + }; + + PrometheusMetrics::setup( + registry, + &config.network.node_name, + &config.impl_version, + role_bits, + ) + .map(|p| MetricsService { + metrics: Some(p), + last_total_bytes_inbound: 0, + last_total_bytes_outbound: 0, + last_update: Instant::now(), }) } @@ -314,16 +147,30 @@ impl MetricsService { txpool_status: &PoolStatus, net_status: &NetworkStatus, ) { + let now = Instant::now(); + let elapsed = (now - self.last_update).as_secs(); let best_number = info.chain.best_number.saturated_into::(); let best_hash = info.chain.best_hash; let num_peers = net_status.num_connected_peers; let finalized_number: u64 = info.chain.finalized_number.saturated_into::(); - let bandwidth_download = net_status.average_download_per_sec; - let bandwidth_upload = net_status.average_upload_per_sec; - let best_seen_block = net_status.best_seen_block + let total_bytes_inbound = net_status.total_bytes_inbound; + let total_bytes_outbound = net_status.total_bytes_outbound; + let best_seen_block = net_status + .best_seen_block .map(|num: NumberFor| num.unique_saturated_into() as u64); - let process_info = self.process_info(); + + let diff_bytes_inbound = total_bytes_inbound - self.last_total_bytes_inbound; + let diff_bytes_outbound = total_bytes_outbound - self.last_total_bytes_outbound; + let (avg_bytes_per_sec_inbound, avg_bytes_per_sec_outbound) = + if elapsed > 0 { + self.last_total_bytes_inbound = total_bytes_inbound; + self.last_total_bytes_outbound = total_bytes_outbound; + (diff_bytes_inbound / elapsed, diff_bytes_outbound / elapsed) + } else { + (diff_bytes_inbound, diff_bytes_outbound) + }; + self.last_update = now; telemetry!( SUBSTRATE_INFO; @@ -332,12 +179,10 @@ impl MetricsService { "height" => best_number, "best" => ?best_hash, "txcount" => txpool_status.ready, - "cpu" => process_info.cpu_usage, - "memory" => process_info.memory, "finalized_height" => finalized_number, "finalized_hash" => ?info.chain.finalized_hash, - "bandwidth_download" => bandwidth_download, - "bandwidth_upload" => bandwidth_upload, + "bandwidth_download" => avg_bytes_per_sec_inbound, + "bandwidth_upload" => avg_bytes_per_sec_outbound, "used_state_cache_size" => info.usage.as_ref() .map(|usage| usage.memory.state_cache.as_bytes()) .unwrap_or(0), @@ -353,34 +198,15 @@ impl MetricsService { ); if let Some(metrics) = self.metrics.as_ref() { - metrics.cpu_usage_percentage.set(process_info.cpu_usage as f64); - // `sysinfo::Process::memory` returns memory usage in KiB and not bytes. - metrics.memory_usage_bytes.set(process_info.memory * 1024); - - if let Some(threads) = process_info.threads { - metrics.threads.set(threads); - } - - if let Some(fd_info) = process_info.open_fd { - metrics.open_files.with_label_values(&["paths"]).set(fd_info.paths); - metrics.open_files.with_label_values(&["mem"]).set(fd_info.mem); - metrics.open_files.with_label_values(&["sockets"]).set(fd_info.sockets); - metrics.open_files.with_label_values(&["net"]).set(fd_info.net); - metrics.open_files.with_label_values(&["pipe"]).set(fd_info.pipes); - metrics.open_files.with_label_values(&["anon_inode"]).set(fd_info.anon_inode); - metrics.open_files.with_label_values(&["other"]).set(fd_info.other); - } - - - metrics.network_per_sec_bytes.with_label_values(&["download"]).set( - net_status.average_download_per_sec, - ); - metrics.network_per_sec_bytes.with_label_values(&["upload"]).set( - net_status.average_upload_per_sec, - ); + metrics + .block_height + .with_label_values(&["finalized"]) + .set(finalized_number); + metrics + .block_height + .with_label_values(&["best"]) + .set(best_number); - metrics.block_height.with_label_values(&["finalized"]).set(finalized_number); - metrics.block_height.with_label_values(&["best"]).set(best_number); if let Ok(leaves) = u64::try_from(info.chain.number_leaves) { metrics.number_leaves.set(leaves); } @@ -405,23 +231,6 @@ impl MetricsService { info.memory.state_db.pinned.as_bytes() as u64, ); } - - #[cfg(all(any(unix, windows), not(target_os = "android")))] - { - let load = self.system.get_load_average(); - metrics.load_avg.with_label_values(&["1min"]).set(load.one); - metrics.load_avg.with_label_values(&["5min"]).set(load.five); - metrics.load_avg.with_label_values(&["15min"]).set(load.fifteen); - - if let Some(conns) = self.connections_info() { - metrics.netstat.with_label_values(&["listen"]).set(conns.listen); - metrics.netstat.with_label_values(&["established"]).set(conns.established); - metrics.netstat.with_label_values(&["starting"]).set(conns.starting); - metrics.netstat.with_label_values(&["closing"]).set(conns.closing); - metrics.netstat.with_label_values(&["closed"]).set(conns.closed); - metrics.netstat.with_label_values(&["other"]).set(conns.other); - } - } } } } diff --git a/client/service/src/status_sinks.rs b/client/service/src/status_sinks.rs deleted file mode 100644 index 4b1dce52f9a319ee02c2033f0214fffd6fe56a86..0000000000000000000000000000000000000000 --- a/client/service/src/status_sinks.rs +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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 Substrate. If not, see . - -use futures::{Stream, stream::futures_unordered::FuturesUnordered}; -use std::time::Duration; -use std::pin::Pin; -use std::task::{Poll, Context}; -use futures_timer::Delay; -use sp_utils::mpsc::TracingUnboundedSender; - -/// Holds a list of `UnboundedSender`s, each associated with a certain time period. Every time the -/// period elapses, we push an element on the sender. -/// -/// Senders are removed only when they are closed. -pub struct StatusSinks { - entries: FuturesUnordered>, -} - -struct YieldAfter { - delay: Delay, - interval: Duration, - sender: Option>, -} - -impl StatusSinks { - /// Builds a new empty collection. - pub fn new() -> StatusSinks { - StatusSinks { - entries: FuturesUnordered::new(), - } - } - - /// Adds a sender to the collection. - /// - /// The `interval` is the time period between two pushes on the sender. - pub fn push(&mut self, interval: Duration, sender: TracingUnboundedSender) { - self.entries.push(YieldAfter { - delay: Delay::new(interval), - interval, - sender: Some(sender), - }) - } - - /// Processes all the senders. If any sender is ready, calls the `status_grab` function and - /// pushes what it returns to the sender. - /// - /// This function doesn't return anything, but it should be treated as if it implicitly - /// returns `Poll::Pending`. In particular, it should be called again when the task - /// is waken up. - /// - /// # Panic - /// - /// Panics if not called within the context of a task. - pub fn poll(&mut self, cx: &mut Context, mut status_grab: impl FnMut() -> T) { - loop { - match Pin::new(&mut self.entries).poll_next(cx) { - Poll::Ready(Some((sender, interval))) => { - let status = status_grab(); - if sender.unbounded_send(status).is_ok() { - self.entries.push(YieldAfter { - // Note that since there's a small delay between the moment a task is - // waken up and the moment it is polled, the period is actually not - // `interval` but `interval + `. We ignore this problem in - // practice. - delay: Delay::new(interval), - interval, - sender: Some(sender), - }); - } - } - Poll::Ready(None) | - Poll::Pending => break, - } - } - } -} - -impl futures::Future for YieldAfter { - type Output = (TracingUnboundedSender, Duration); - - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll { - let this = Pin::into_inner(self); - - match Pin::new(&mut this.delay).poll(cx) { - Poll::Pending => Poll::Pending, - Poll::Ready(()) => { - let sender = this.sender.take() - .expect("sender is always Some unless the future is finished; qed"); - Poll::Ready((sender, this.interval)) - } - } - } -} - -#[cfg(test)] -mod tests { - use super::StatusSinks; - use futures::prelude::*; - use futures::channel::mpsc; - use std::time::Duration; - use std::task::Poll; - - #[test] - fn works() { - // We're not testing that the `StatusSink` properly enforces an order in the intervals, as - // this easily causes test failures on busy CPUs. - - let mut status_sinks = StatusSinks::new(); - - let (tx, rx) = mpsc::unbounded(); - status_sinks.push(Duration::from_millis(100), tx); - - let mut val_order = 5; - - futures::executor::block_on(futures::future::select( - futures::future::poll_fn(move |cx| { - status_sinks.poll(cx, || { val_order += 1; val_order }); - Poll::<()>::Pending - }), - Box::pin(async { - let items: Vec = rx.take(3).collect().await; - assert_eq!(items, [6, 7, 8]); - }) - )); - } -} diff --git a/client/service/src/task_manager.rs b/client/service/src/task_manager.rs deleted file mode 100644 index 553ca9c326d8ba344c9add9d87dfa1cc83b9ed3f..0000000000000000000000000000000000000000 --- a/client/service/src/task_manager.rs +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. -// This file is part of Substrate. - -// Substrate 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. - -// Substrate 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. - -//! Substrate service tasks management module. - -use std::{panic, pin::Pin, result::Result, sync::Arc}; -use exit_future::Signal; -use log::debug; -use futures::{ - Future, FutureExt, - future::{select, Either, BoxFuture}, - compat::*, - task::{Spawn, FutureObj, SpawnError}, -}; -use prometheus_endpoint::{ - exponential_buckets, register, - PrometheusError, - CounterVec, HistogramOpts, HistogramVec, Opts, Registry, U64 -}; -use sc_client_api::CloneableSpawn; -use crate::config::TaskType; - -mod prometheus_future; - -/// Type alias for service task executor (usually runtime). -pub type ServiceTaskExecutor = Arc + Send>>, TaskType) + Send + Sync>; - -/// An handle for spawning tasks in the service. -#[derive(Clone)] -pub struct SpawnTaskHandle { - on_exit: exit_future::Exit, - executor: ServiceTaskExecutor, - metrics: Option, -} - -impl SpawnTaskHandle { - /// Spawns the given task with the given name. - /// - /// Note that the `name` is a `&'static str`. The reason for this choice is that statistics - /// about this task are getting reported to the Prometheus endpoint (if enabled), and that - /// therefore the set of possible task names must be bounded. - /// - /// In other words, it would be a bad idea for someone to do for example - /// `spawn(format!("{:?}", some_public_key))`. - pub fn spawn(&self, name: &'static str, task: impl Future + Send + 'static) { - self.spawn_inner(name, task, TaskType::Async) - } - - /// Spawns the blocking task with the given name. See also `spawn`. - pub fn spawn_blocking(&self, name: &'static str, task: impl Future + Send + 'static) { - self.spawn_inner(name, task, TaskType::Blocking) - } - - /// Helper function that implements the spawning logic. See `spawn` and `spawn_blocking`. - fn spawn_inner( - &self, - name: &'static str, - task: impl Future + Send + 'static, - task_type: TaskType, - ) { - let on_exit = self.on_exit.clone(); - let metrics = self.metrics.clone(); - - // Note that we increase the started counter here and not within the future. This way, - // we could properly visualize on Prometheus situations where the spawning doesn't work. - if let Some(metrics) = &self.metrics { - metrics.tasks_spawned.with_label_values(&[name]).inc(); - // We do a dummy increase in order for the task to show up in metrics. - metrics.tasks_ended.with_label_values(&[name, "finished"]).inc_by(0); - } - - let future = async move { - if let Some(metrics) = metrics { - // Add some wrappers around `task`. - let task = { - let poll_duration = metrics.poll_duration.with_label_values(&[name]); - let poll_start = metrics.poll_start.with_label_values(&[name]); - let inner = prometheus_future::with_poll_durations(poll_duration, poll_start, task); - // The logic of `AssertUnwindSafe` here is ok considering that we throw - // away the `Future` after it has panicked. - panic::AssertUnwindSafe(inner).catch_unwind() - }; - futures::pin_mut!(task); - - match select(on_exit, task).await { - Either::Right((Err(payload), _)) => { - metrics.tasks_ended.with_label_values(&[name, "panic"]).inc(); - panic::resume_unwind(payload) - } - Either::Right((Ok(()), _)) => { - metrics.tasks_ended.with_label_values(&[name, "finished"]).inc(); - } - Either::Left(((), _)) => { - // The `on_exit` has triggered. - metrics.tasks_ended.with_label_values(&[name, "interrupted"]).inc(); - } - } - - } else { - futures::pin_mut!(task); - let _ = select(on_exit, task).await; - } - }; - - (self.executor)(Box::pin(future), task_type); - } -} - -impl Spawn for SpawnTaskHandle { - fn spawn_obj(&self, future: FutureObj<'static, ()>) - -> Result<(), SpawnError> { - self.spawn("unnamed", future); - Ok(()) - } -} - -impl sp_core::traits::SpawnBlocking for SpawnTaskHandle { - fn spawn_blocking(&self, name: &'static str, future: BoxFuture<'static, ()>) { - self.spawn_blocking(name, future); - } -} - -impl sc_client_api::CloneableSpawn for SpawnTaskHandle { - fn clone(&self) -> Box { - Box::new(Clone::clone(self)) - } -} - -type Boxed01Future01 = Box + Send + 'static>; - -impl futures01::future::Executor for SpawnTaskHandle { - fn execute(&self, future: Boxed01Future01) -> Result<(), futures01::future::ExecuteError>{ - self.spawn("unnamed", future.compat().map(drop)); - Ok(()) - } -} - -/// Helper struct to manage background/async tasks in Service. -pub struct TaskManager { - /// A future that resolves when the service has exited, this is useful to - /// make sure any internally spawned futures stop when the service does. - on_exit: exit_future::Exit, - /// A signal that makes the exit future above resolve, fired on service drop. - signal: Option, - /// How to spawn background tasks. - executor: ServiceTaskExecutor, - /// Prometheus metric where to report the polling times. - metrics: Option, -} - -impl TaskManager { - /// If a Prometheus registry is passed, it will be used to report statistics about the - /// service tasks. - pub(super) fn new( - executor: ServiceTaskExecutor, - prometheus_registry: Option<&Registry> - ) -> Result { - let (signal, on_exit) = exit_future::signal(); - - let metrics = prometheus_registry.map(Metrics::register).transpose()?; - - Ok(Self { - on_exit, - signal: Some(signal), - executor, - metrics, - }) - } - - /// Spawn background/async task, which will be aware on exit signal. - /// - /// See also the documentation of [`SpawnTaskHandler::spawn`]. - pub(super) fn spawn(&self, name: &'static str, task: impl Future + Send + 'static) { - self.spawn_handle().spawn(name, task) - } - - pub(super) fn spawn_handle(&self) -> SpawnTaskHandle { - SpawnTaskHandle { - on_exit: self.on_exit.clone(), - executor: self.executor.clone(), - metrics: self.metrics.clone(), - } - } - - /// Clone on exit signal. - pub(super) fn on_exit(&self) -> exit_future::Exit { - self.on_exit.clone() - } -} - -impl Drop for TaskManager { - fn drop(&mut self) { - debug!(target: "service", "Tasks manager shutdown"); - if let Some(signal) = self.signal.take() { - let _ = signal.fire(); - } - } -} - -#[derive(Clone)] -struct Metrics { - // This list is ordered alphabetically - poll_duration: HistogramVec, - poll_start: CounterVec, - tasks_spawned: CounterVec, - tasks_ended: CounterVec, -} - -impl Metrics { - fn register(registry: &Registry) -> Result { - Ok(Self { - poll_duration: register(HistogramVec::new( - HistogramOpts { - common_opts: Opts::new( - "tasks_polling_duration", - "Duration in seconds of each invocation of Future::poll" - ), - buckets: exponential_buckets(0.001, 4.0, 9) - .expect("function parameters are constant and always valid; qed"), - }, - &["task_name"] - )?, registry)?, - poll_start: register(CounterVec::new( - Opts::new( - "tasks_polling_started_total", - "Total number of times we started invoking Future::poll" - ), - &["task_name"] - )?, registry)?, - tasks_spawned: register(CounterVec::new( - Opts::new( - "tasks_spawned_total", - "Total number of tasks that have been spawned on the Service" - ), - &["task_name"] - )?, registry)?, - tasks_ended: register(CounterVec::new( - Opts::new( - "tasks_ended_total", - "Total number of tasks for which Future::poll has returned Ready(()) or panicked" - ), - &["task_name", "reason"] - )?, registry)?, - }) - } -} diff --git a/client/service/src/task_manager/mod.rs b/client/service/src/task_manager/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..88a44e1360d7fac789ab7f5efd23401bcfecf872 --- /dev/null +++ b/client/service/src/task_manager/mod.rs @@ -0,0 +1,401 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate 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. + +// Substrate 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. + +//! Substrate service tasks management module. + +use std::{panic, result::Result, pin::Pin}; +use exit_future::Signal; +use log::{debug, error}; +use futures::{ + Future, FutureExt, StreamExt, + future::{select, Either, BoxFuture, join_all, try_join_all, pending}, + sink::SinkExt, +}; +use prometheus_endpoint::{ + exponential_buckets, register, + PrometheusError, + CounterVec, HistogramOpts, HistogramVec, Opts, Registry, U64 +}; +use sp_utils::mpsc::{TracingUnboundedSender, TracingUnboundedReceiver, tracing_unbounded}; +use crate::{config::{TaskExecutor, TaskType, JoinFuture}, Error}; + +mod prometheus_future; +#[cfg(test)] +mod tests; + +/// An handle for spawning tasks in the service. +#[derive(Clone)] +pub struct SpawnTaskHandle { + on_exit: exit_future::Exit, + executor: TaskExecutor, + metrics: Option, + task_notifier: TracingUnboundedSender, +} + +impl SpawnTaskHandle { + /// Spawns the given task with the given name. + /// + /// Note that the `name` is a `&'static str`. The reason for this choice is that statistics + /// about this task are getting reported to the Prometheus endpoint (if enabled), and that + /// therefore the set of possible task names must be bounded. + /// + /// In other words, it would be a bad idea for someone to do for example + /// `spawn(format!("{:?}", some_public_key))`. + pub fn spawn(&self, name: &'static str, task: impl Future + Send + 'static) { + self.spawn_inner(name, task, TaskType::Async) + } + + /// Spawns the blocking task with the given name. See also `spawn`. + pub fn spawn_blocking(&self, name: &'static str, task: impl Future + Send + 'static) { + self.spawn_inner(name, task, TaskType::Blocking) + } + + /// Helper function that implements the spawning logic. See `spawn` and `spawn_blocking`. + fn spawn_inner( + &self, + name: &'static str, + task: impl Future + Send + 'static, + task_type: TaskType, + ) { + if self.task_notifier.is_closed() { + debug!("Attempt to spawn a new task has been prevented: {}", name); + return; + } + + let on_exit = self.on_exit.clone(); + let metrics = self.metrics.clone(); + + // Note that we increase the started counter here and not within the future. This way, + // we could properly visualize on Prometheus situations where the spawning doesn't work. + if let Some(metrics) = &self.metrics { + metrics.tasks_spawned.with_label_values(&[name]).inc(); + // We do a dummy increase in order for the task to show up in metrics. + metrics.tasks_ended.with_label_values(&[name, "finished"]).inc_by(0); + } + + let future = async move { + if let Some(metrics) = metrics { + // Add some wrappers around `task`. + let task = { + let poll_duration = metrics.poll_duration.with_label_values(&[name]); + let poll_start = metrics.poll_start.with_label_values(&[name]); + let inner = prometheus_future::with_poll_durations(poll_duration, poll_start, task); + // The logic of `AssertUnwindSafe` here is ok considering that we throw + // away the `Future` after it has panicked. + panic::AssertUnwindSafe(inner).catch_unwind() + }; + futures::pin_mut!(task); + + match select(on_exit, task).await { + Either::Right((Err(payload), _)) => { + metrics.tasks_ended.with_label_values(&[name, "panic"]).inc(); + panic::resume_unwind(payload) + } + Either::Right((Ok(()), _)) => { + metrics.tasks_ended.with_label_values(&[name, "finished"]).inc(); + } + Either::Left(((), _)) => { + // The `on_exit` has triggered. + metrics.tasks_ended.with_label_values(&[name, "interrupted"]).inc(); + } + } + + } else { + futures::pin_mut!(task); + let _ = select(on_exit, task).await; + } + }; + + let join_handle = self.executor.spawn(Box::pin(future), task_type); + let mut task_notifier = self.task_notifier.clone(); + self.executor.spawn( + Box::pin(async move { + if let Err(err) = task_notifier.send(join_handle).await { + error!("Could not send spawned task handle to queue: {}", err); + } + }), + TaskType::Async, + ); + } +} + +impl sp_core::traits::SpawnNamed for SpawnTaskHandle { + fn spawn_blocking(&self, name: &'static str, future: BoxFuture<'static, ()>) { + self.spawn_blocking(name, future); + } + + fn spawn(&self, name: &'static str, future: BoxFuture<'static, ()>) { + self.spawn(name, future); + } +} + +/// A wrapper over `SpawnTaskHandle` that will notify a receiver whenever any +/// task spawned through it fails. The service should be on the receiver side +/// and will shut itself down whenever it receives any message, i.e. an +/// essential task has failed. +pub struct SpawnEssentialTaskHandle { + essential_failed_tx: TracingUnboundedSender<()>, + inner: SpawnTaskHandle, +} + +impl SpawnEssentialTaskHandle { + /// Creates a new `SpawnEssentialTaskHandle`. + pub fn new( + essential_failed_tx: TracingUnboundedSender<()>, + spawn_task_handle: SpawnTaskHandle, + ) -> SpawnEssentialTaskHandle { + SpawnEssentialTaskHandle { + essential_failed_tx, + inner: spawn_task_handle, + } + } + + /// Spawns the given task with the given name. + /// + /// See also [`SpawnTaskHandle::spawn`]. + pub fn spawn(&self, name: &'static str, task: impl Future + Send + 'static) { + self.spawn_inner(name, task, TaskType::Async) + } + + /// Spawns the blocking task with the given name. + /// + /// See also [`SpawnTaskHandle::spawn_blocking`]. + pub fn spawn_blocking( + &self, + name: &'static str, + task: impl Future + Send + 'static, + ) { + self.spawn_inner(name, task, TaskType::Blocking) + } + + fn spawn_inner( + &self, + name: &'static str, + task: impl Future + Send + 'static, + task_type: TaskType, + ) { + let essential_failed = self.essential_failed_tx.clone(); + let essential_task = std::panic::AssertUnwindSafe(task) + .catch_unwind() + .map(move |_| { + log::error!("Essential task `{}` failed. Shutting down service.", name); + let _ = essential_failed.close_channel(); + }); + + let _ = self.inner.spawn_inner(name, essential_task, task_type); + } +} + +/// Helper struct to manage background/async tasks in Service. +pub struct TaskManager { + /// A future that resolves when the service has exited, this is useful to + /// make sure any internally spawned futures stop when the service does. + on_exit: exit_future::Exit, + /// A signal that makes the exit future above resolve, fired on service drop. + signal: Option, + /// How to spawn background tasks. + executor: TaskExecutor, + /// Prometheus metric where to report the polling times. + metrics: Option, + /// Send a signal when a spawned essential task has concluded. The next time + /// the service future is polled it should complete with an error. + essential_failed_tx: TracingUnboundedSender<()>, + /// A receiver for spawned essential-tasks concluding. + essential_failed_rx: TracingUnboundedReceiver<()>, + /// Things to keep alive until the task manager is dropped. + keep_alive: Box, + /// A sender to a stream of background tasks. This is used for the completion future. + task_notifier: TracingUnboundedSender, + /// This future will complete when all the tasks are joined and the stream is closed. + completion_future: JoinFuture, + /// A list of other `TaskManager`'s to terminate and gracefully shutdown when the parent + /// terminates and gracefully shutdown. Also ends the parent `future()` if a child's essential + /// task fails. + children: Vec, +} + +impl TaskManager { + /// If a Prometheus registry is passed, it will be used to report statistics about the + /// service tasks. + pub(super) fn new( + executor: TaskExecutor, + prometheus_registry: Option<&Registry> + ) -> Result { + let (signal, on_exit) = exit_future::signal(); + + // A side-channel for essential tasks to communicate shutdown. + let (essential_failed_tx, essential_failed_rx) = tracing_unbounded("mpsc_essential_tasks"); + + let metrics = prometheus_registry.map(Metrics::register).transpose()?; + + let (task_notifier, background_tasks) = tracing_unbounded("mpsc_background_tasks"); + // NOTE: for_each_concurrent will await on all the JoinHandle futures at the same time. It + // is possible to limit this but it's actually better for the memory foot print to await + // them all to not accumulate anything on that stream. + let completion_future = executor.spawn( + Box::pin(background_tasks.for_each_concurrent(None, |x| x)), + TaskType::Async, + ); + + Ok(Self { + on_exit, + signal: Some(signal), + executor, + metrics, + essential_failed_tx, + essential_failed_rx, + keep_alive: Box::new(()), + task_notifier, + completion_future, + children: Vec::new(), + }) + } + + /// Get a handle for spawning tasks. + pub fn spawn_handle(&self) -> SpawnTaskHandle { + SpawnTaskHandle { + on_exit: self.on_exit.clone(), + executor: self.executor.clone(), + metrics: self.metrics.clone(), + task_notifier: self.task_notifier.clone(), + } + } + + /// Get a handle for spawning essential tasks. + pub fn spawn_essential_handle(&self) -> SpawnEssentialTaskHandle { + SpawnEssentialTaskHandle::new(self.essential_failed_tx.clone(), self.spawn_handle()) + } + + /// Send the signal for termination, prevent new tasks to be created, await for all the existing + /// tasks to be finished and drop the object. You can consider this as an async drop. + /// + /// It's always better to call and await this function before exiting the process as background + /// tasks may be running in the background. If the process exit and the background tasks are not + /// cancelled, this will lead to objects not getting dropped properly. + /// + /// This is an issue in some cases as some of our dependencies do require that we drop all the + /// objects properly otherwise it triggers a SIGABRT on exit. + pub fn clean_shutdown(mut self) -> Pin + Send>> { + self.terminate(); + let children_shutdowns = self.children.into_iter().map(|x| x.clean_shutdown()); + let keep_alive = self.keep_alive; + let completion_future = self.completion_future; + + Box::pin(async move { + join_all(children_shutdowns).await; + completion_future.await; + drop(keep_alive); + }) + } + + /// Return a future that will end with success if the signal to terminate was sent + /// (`self.terminate()`) or with an error if an essential task fails. + /// + /// # Warning + /// + /// This function will not wait until the end of the remaining task. You must call and await + /// `clean_shutdown()` after this. + pub fn future<'a>(&'a mut self) -> Pin> + Send + 'a>> { + Box::pin(async move { + let mut t1 = self.essential_failed_rx.next().fuse(); + let mut t2 = self.on_exit.clone().fuse(); + let mut t3 = try_join_all( + self.children.iter_mut().map(|x| x.future()) + // Never end this future if there is no error because if there is no children, + // it must not stop + .chain(std::iter::once(pending().boxed())) + ).fuse(); + + futures::select! { + _ = t1 => Err(Error::Other("Essential task failed.".into())), + _ = t2 => Ok(()), + res = t3 => Err(res.map(|_| ()).expect_err("this future never ends; qed")), + } + }) + } + + /// Signal to terminate all the running tasks. + pub fn terminate(&mut self) { + if let Some(signal) = self.signal.take() { + let _ = signal.fire(); + // NOTE: this will prevent new tasks to be spawned + self.task_notifier.close_channel(); + for child in self.children.iter_mut() { + child.terminate(); + } + } + } + + /// Set what the task manager should keep alive, can be called multiple times. + pub fn keep_alive(&mut self, to_keep_alive: T) { + // allows this fn to safely called multiple times. + use std::mem; + let old = mem::replace(&mut self.keep_alive, Box::new(())); + self.keep_alive = Box::new((to_keep_alive, old)); + } + + /// Register another TaskManager to terminate and gracefully shutdown when the parent + /// terminates and gracefully shutdown. Also ends the parent `future()` if a child's essential + /// task fails. (But don't end the parent if a child's normal task fails.) + pub fn add_child(&mut self, child: TaskManager) { + self.children.push(child); + } +} + +#[derive(Clone)] +struct Metrics { + // This list is ordered alphabetically + poll_duration: HistogramVec, + poll_start: CounterVec, + tasks_spawned: CounterVec, + tasks_ended: CounterVec, +} + +impl Metrics { + fn register(registry: &Registry) -> Result { + Ok(Self { + poll_duration: register(HistogramVec::new( + HistogramOpts { + common_opts: Opts::new( + "tasks_polling_duration", + "Duration in seconds of each invocation of Future::poll" + ), + buckets: exponential_buckets(0.001, 4.0, 9) + .expect("function parameters are constant and always valid; qed"), + }, + &["task_name"] + )?, registry)?, + poll_start: register(CounterVec::new( + Opts::new( + "tasks_polling_started_total", + "Total number of times we started invoking Future::poll" + ), + &["task_name"] + )?, registry)?, + tasks_spawned: register(CounterVec::new( + Opts::new( + "tasks_spawned_total", + "Total number of tasks that have been spawned on the Service" + ), + &["task_name"] + )?, registry)?, + tasks_ended: register(CounterVec::new( + Opts::new( + "tasks_ended_total", + "Total number of tasks for which Future::poll has returned Ready(()) or panicked" + ), + &["task_name", "reason"] + )?, registry)?, + }) + } +} diff --git a/client/service/src/task_manager/tests.rs b/client/service/src/task_manager/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..27d9b0b9e9ad9334faa66589002ef10605ee9323 --- /dev/null +++ b/client/service/src/task_manager/tests.rs @@ -0,0 +1,310 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use crate::config::TaskExecutor; +use crate::task_manager::TaskManager; +use futures::{future::FutureExt, pin_mut, select}; +use parking_lot::Mutex; +use std::any::Any; +use std::sync::Arc; +use std::time::Duration; + +#[derive(Clone, Debug)] +struct DropTester(Arc>); + +struct DropTesterRef(DropTester); + +impl DropTester { + fn new() -> DropTester { + DropTester(Arc::new(Mutex::new(0))) + } + + fn new_ref(&self) -> DropTesterRef { + *self.0.lock() += 1; + DropTesterRef(self.clone()) + } +} + +impl PartialEq for DropTester { + fn eq(&self, other: &usize) -> bool { + &*self.0.lock() == other + } +} + +impl Drop for DropTesterRef { + fn drop(&mut self) { + *(self.0).0.lock() -= 1; + } +} + +#[test] +fn ensure_drop_tester_working() { + let drop_tester = DropTester::new(); + assert_eq!(drop_tester, 0); + let drop_tester_ref_1 = drop_tester.new_ref(); + assert_eq!(drop_tester, 1); + let drop_tester_ref_2 = drop_tester.new_ref(); + assert_eq!(drop_tester, 2); + drop(drop_tester_ref_1); + assert_eq!(drop_tester, 1); + drop(drop_tester_ref_2); + assert_eq!(drop_tester, 0); +} + +async fn run_background_task(_keep_alive: impl Any) { + loop { + tokio::time::delay_for(Duration::from_secs(1)).await; + } +} + +async fn run_background_task_blocking(duration: Duration, _keep_alive: impl Any) { + loop { + // block for X sec (not interruptible) + std::thread::sleep(duration); + // await for 1 sec (interruptible) + tokio::time::delay_for(Duration::from_secs(1)).await; + } +} + +#[test] +fn ensure_tasks_are_awaited_on_shutdown() { + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + let handle = runtime.handle().clone(); + let task_executor: TaskExecutor = (move |future, _| handle.spawn(future).map(|_| ())).into(); + + let task_manager = TaskManager::new(task_executor, None).unwrap(); + let spawn_handle = task_manager.spawn_handle(); + let drop_tester = DropTester::new(); + spawn_handle.spawn("task1", run_background_task(drop_tester.new_ref())); + spawn_handle.spawn("task2", run_background_task(drop_tester.new_ref())); + assert_eq!(drop_tester, 2); + // allow the tasks to even start + runtime.block_on(async { tokio::time::delay_for(Duration::from_secs(1)).await }); + assert_eq!(drop_tester, 2); + runtime.block_on(task_manager.clean_shutdown()); + assert_eq!(drop_tester, 0); +} + +#[test] +fn ensure_keep_alive_during_shutdown() { + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + let handle = runtime.handle().clone(); + let task_executor: TaskExecutor = (move |future, _| handle.spawn(future).map(|_| ())).into(); + + let mut task_manager = TaskManager::new(task_executor, None).unwrap(); + let spawn_handle = task_manager.spawn_handle(); + let drop_tester = DropTester::new(); + task_manager.keep_alive(drop_tester.new_ref()); + spawn_handle.spawn("task1", run_background_task(())); + assert_eq!(drop_tester, 1); + // allow the tasks to even start + runtime.block_on(async { tokio::time::delay_for(Duration::from_secs(1)).await }); + assert_eq!(drop_tester, 1); + runtime.block_on(task_manager.clean_shutdown()); + assert_eq!(drop_tester, 0); +} + +#[test] +fn ensure_blocking_futures_are_awaited_on_shutdown() { + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + let handle = runtime.handle().clone(); + let task_executor: TaskExecutor = (move |future, _| handle.spawn(future).map(|_| ())).into(); + + let task_manager = TaskManager::new(task_executor, None).unwrap(); + let spawn_handle = task_manager.spawn_handle(); + let drop_tester = DropTester::new(); + spawn_handle.spawn( + "task1", + run_background_task_blocking(Duration::from_secs(3), drop_tester.new_ref()), + ); + spawn_handle.spawn( + "task2", + run_background_task_blocking(Duration::from_secs(3), drop_tester.new_ref()), + ); + assert_eq!(drop_tester, 2); + // allow the tasks to even start + runtime.block_on(async { tokio::time::delay_for(Duration::from_secs(1)).await }); + assert_eq!(drop_tester, 2); + runtime.block_on(task_manager.clean_shutdown()); + assert_eq!(drop_tester, 0); +} + +#[test] +fn ensure_no_task_can_be_spawn_after_terminate() { + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + let handle = runtime.handle().clone(); + let task_executor: TaskExecutor = (move |future, _| handle.spawn(future).map(|_| ())).into(); + + let mut task_manager = TaskManager::new(task_executor, None).unwrap(); + let spawn_handle = task_manager.spawn_handle(); + let drop_tester = DropTester::new(); + spawn_handle.spawn("task1", run_background_task(drop_tester.new_ref())); + spawn_handle.spawn("task2", run_background_task(drop_tester.new_ref())); + assert_eq!(drop_tester, 2); + // allow the tasks to even start + runtime.block_on(async { tokio::time::delay_for(Duration::from_secs(1)).await }); + assert_eq!(drop_tester, 2); + task_manager.terminate(); + spawn_handle.spawn("task3", run_background_task(drop_tester.new_ref())); + runtime.block_on(task_manager.clean_shutdown()); + assert_eq!(drop_tester, 0); +} + +#[test] +fn ensure_task_manager_future_ends_when_task_manager_terminated() { + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + let handle = runtime.handle().clone(); + let task_executor: TaskExecutor = (move |future, _| handle.spawn(future).map(|_| ())).into(); + + let mut task_manager = TaskManager::new(task_executor, None).unwrap(); + let spawn_handle = task_manager.spawn_handle(); + let drop_tester = DropTester::new(); + spawn_handle.spawn("task1", run_background_task(drop_tester.new_ref())); + spawn_handle.spawn("task2", run_background_task(drop_tester.new_ref())); + assert_eq!(drop_tester, 2); + // allow the tasks to even start + runtime.block_on(async { tokio::time::delay_for(Duration::from_secs(1)).await }); + assert_eq!(drop_tester, 2); + task_manager.terminate(); + runtime.block_on(task_manager.future()).expect("future has ended without error"); + runtime.block_on(task_manager.clean_shutdown()); + assert_eq!(drop_tester, 0); +} + +#[test] +fn ensure_task_manager_future_ends_with_error_when_essential_task_fails() { + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + let handle = runtime.handle().clone(); + let task_executor: TaskExecutor = (move |future, _| handle.spawn(future).map(|_| ())).into(); + + let mut task_manager = TaskManager::new(task_executor, None).unwrap(); + let spawn_handle = task_manager.spawn_handle(); + let spawn_essential_handle = task_manager.spawn_essential_handle(); + let drop_tester = DropTester::new(); + spawn_handle.spawn("task1", run_background_task(drop_tester.new_ref())); + spawn_handle.spawn("task2", run_background_task(drop_tester.new_ref())); + assert_eq!(drop_tester, 2); + // allow the tasks to even start + runtime.block_on(async { tokio::time::delay_for(Duration::from_secs(1)).await }); + assert_eq!(drop_tester, 2); + spawn_essential_handle.spawn("task3", async { panic!("task failed") }); + runtime.block_on(task_manager.future()).expect_err("future()'s Result must be Err"); + assert_eq!(drop_tester, 2); + runtime.block_on(task_manager.clean_shutdown()); + assert_eq!(drop_tester, 0); +} + +#[test] +fn ensure_children_tasks_ends_when_task_manager_terminated() { + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + let handle = runtime.handle().clone(); + let task_executor: TaskExecutor = (move |future, _| handle.spawn(future).map(|_| ())).into(); + + let mut task_manager = TaskManager::new(task_executor.clone(), None).unwrap(); + let child_1 = TaskManager::new(task_executor.clone(), None).unwrap(); + let spawn_handle_child_1 = child_1.spawn_handle(); + let child_2 = TaskManager::new(task_executor.clone(), None).unwrap(); + let spawn_handle_child_2 = child_2.spawn_handle(); + task_manager.add_child(child_1); + task_manager.add_child(child_2); + let spawn_handle = task_manager.spawn_handle(); + let drop_tester = DropTester::new(); + spawn_handle.spawn("task1", run_background_task(drop_tester.new_ref())); + spawn_handle.spawn("task2", run_background_task(drop_tester.new_ref())); + spawn_handle_child_1.spawn("task3", run_background_task(drop_tester.new_ref())); + spawn_handle_child_2.spawn("task4", run_background_task(drop_tester.new_ref())); + assert_eq!(drop_tester, 4); + // allow the tasks to even start + runtime.block_on(async { tokio::time::delay_for(Duration::from_secs(1)).await }); + assert_eq!(drop_tester, 4); + task_manager.terminate(); + runtime.block_on(task_manager.future()).expect("future has ended without error"); + runtime.block_on(task_manager.clean_shutdown()); + assert_eq!(drop_tester, 0); +} + +#[test] +fn ensure_task_manager_future_ends_with_error_when_childs_essential_task_fails() { + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + let handle = runtime.handle().clone(); + let task_executor: TaskExecutor = (move |future, _| handle.spawn(future).map(|_| ())).into(); + + let mut task_manager = TaskManager::new(task_executor.clone(), None).unwrap(); + let child_1 = TaskManager::new(task_executor.clone(), None).unwrap(); + let spawn_handle_child_1 = child_1.spawn_handle(); + let spawn_essential_handle_child_1 = child_1.spawn_essential_handle(); + let child_2 = TaskManager::new(task_executor.clone(), None).unwrap(); + let spawn_handle_child_2 = child_2.spawn_handle(); + task_manager.add_child(child_1); + task_manager.add_child(child_2); + let spawn_handle = task_manager.spawn_handle(); + let drop_tester = DropTester::new(); + spawn_handle.spawn("task1", run_background_task(drop_tester.new_ref())); + spawn_handle.spawn("task2", run_background_task(drop_tester.new_ref())); + spawn_handle_child_1.spawn("task3", run_background_task(drop_tester.new_ref())); + spawn_handle_child_2.spawn("task4", run_background_task(drop_tester.new_ref())); + assert_eq!(drop_tester, 4); + // allow the tasks to even start + runtime.block_on(async { tokio::time::delay_for(Duration::from_secs(1)).await }); + assert_eq!(drop_tester, 4); + spawn_essential_handle_child_1.spawn("task5", async { panic!("task failed") }); + runtime.block_on(task_manager.future()).expect_err("future()'s Result must be Err"); + assert_eq!(drop_tester, 4); + runtime.block_on(task_manager.clean_shutdown()); + assert_eq!(drop_tester, 0); +} + +#[test] +fn ensure_task_manager_future_continues_when_childs_not_essential_task_fails() { + let mut runtime = tokio::runtime::Runtime::new().unwrap(); + let handle = runtime.handle().clone(); + let task_executor: TaskExecutor = (move |future, _| handle.spawn(future).map(|_| ())).into(); + + let mut task_manager = TaskManager::new(task_executor.clone(), None).unwrap(); + let child_1 = TaskManager::new(task_executor.clone(), None).unwrap(); + let spawn_handle_child_1 = child_1.spawn_handle(); + let child_2 = TaskManager::new(task_executor.clone(), None).unwrap(); + let spawn_handle_child_2 = child_2.spawn_handle(); + task_manager.add_child(child_1); + task_manager.add_child(child_2); + let spawn_handle = task_manager.spawn_handle(); + let drop_tester = DropTester::new(); + spawn_handle.spawn("task1", run_background_task(drop_tester.new_ref())); + spawn_handle.spawn("task2", run_background_task(drop_tester.new_ref())); + spawn_handle_child_1.spawn("task3", run_background_task(drop_tester.new_ref())); + spawn_handle_child_2.spawn("task4", run_background_task(drop_tester.new_ref())); + assert_eq!(drop_tester, 4); + // allow the tasks to even start + runtime.block_on(async { tokio::time::delay_for(Duration::from_secs(1)).await }); + assert_eq!(drop_tester, 4); + spawn_handle_child_1.spawn("task5", async { panic!("task failed") }); + runtime.block_on(async { + let t1 = task_manager.future().fuse(); + let t2 = tokio::time::delay_for(Duration::from_secs(3)).fuse(); + + pin_mut!(t1, t2); + + select! { + res = t1 => panic!("task should not have stopped: {:?}", res), + _ = t2 => {}, + } + }); + assert_eq!(drop_tester, 4); + runtime.block_on(task_manager.clean_shutdown()); + assert_eq!(drop_tester, 0); +} diff --git a/client/service/test/Cargo.toml b/client/service/test/Cargo.toml index 094f6bcff0411c3659d7e10c78de9fd7fe521bff..501843dc5b6cace6a30009d68d777f977b92232e 100644 --- a/client/service/test/Cargo.toml +++ b/client/service/test/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-service-test" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" publish = false homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,7 +12,7 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -hex-literal = "0.2.1" +hex-literal = "0.3.1" tempfile = "3.1.0" tokio = "0.1.22" futures01 = { package = "futures", version = "0.1.29" } @@ -20,24 +20,25 @@ log = "0.4.8" env_logger = "0.7.0" fdlimit = "0.1.4" parking_lot = "0.10.0" -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-api = { version = "2.0.0-dev", path = "../../../primitives/api" } -sp-state-machine = { version = "0.8.0-dev", path = "../../../primitives/state-machine" } -sp-externalities = { version = "0.8.0-dev", path = "../../../primitives/externalities" } -sp-trie = { version = "2.0.0-dev", path = "../../../primitives/trie" } -sp-storage = { version = "2.0.0-dev", path = "../../../primitives/storage" } -sc-client-db = { version = "0.8.0-dev", default-features = false, path = "../../db" } +sc-light = { version = "2.0.0-rc6", path = "../../light" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-api = { version = "2.0.0-rc6", path = "../../../primitives/api" } +sp-state-machine = { version = "0.8.0-rc6", path = "../../../primitives/state-machine" } +sp-externalities = { version = "0.8.0-rc6", path = "../../../primitives/externalities" } +sp-trie = { version = "2.0.0-rc6", path = "../../../primitives/trie" } +sp-storage = { version = "2.0.0-rc6", path = "../../../primitives/storage" } +sc-client-db = { version = "0.8.0-rc6", default-features = false, path = "../../db" } futures = { version = "0.3.1", features = ["compat"] } -sc-service = { version = "0.8.0-dev", default-features = false, features = ["test-helpers"], path = "../../service" } -sc-network = { version = "0.8.0-dev", path = "../../network" } -sp-consensus = { version = "0.8.0-dev", path = "../../../primitives/consensus/common" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } -substrate-test-runtime = { version = "2.0.0-dev", path = "../../../test-utils/runtime" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../../test-utils/runtime/client" } -sc-client-api = { version = "2.0.0-dev", path = "../../api" } -sc-block-builder = { version = "0.8.0-dev", path = "../../block-builder" } -sc-executor = { version = "0.8.0-dev", path = "../../executor" } -sp-panic-handler = { version = "2.0.0-dev", path = "../../../primitives/panic-handler" } -parity-scale-codec = "1.3.0" +sc-service = { version = "0.8.0-rc6", default-features = false, features = ["test-helpers"], path = "../../service" } +sc-network = { version = "0.8.0-rc6", path = "../../network" } +sp-consensus = { version = "0.8.0-rc6", path = "../../../primitives/consensus/common" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../../primitives/transaction-pool" } +substrate-test-runtime = { version = "2.0.0-rc6", path = "../../../test-utils/runtime" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../../test-utils/runtime/client" } +sc-client-api = { version = "2.0.0-rc6", path = "../../api" } +sc-block-builder = { version = "0.8.0-rc6", path = "../../block-builder" } +sc-executor = { version = "0.8.0-rc6", path = "../../executor" } +sp-panic-handler = { version = "2.0.0-rc6", path = "../../../primitives/panic-handler" } +parity-scale-codec = "1.3.4" diff --git a/client/service/test/src/client/db.rs b/client/service/test/src/client/db.rs index bc175652c9f79f36fd3b67c18b96beb68781dedb..36d49732246e579d610a707d827c0b5d49c00ea6 100644 --- a/client/service/test/src/client/db.rs +++ b/client/service/test/src/client/db.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use sp_core::offchain::{OffchainStorage, storage::InMemOffchainStorage}; use std::sync::Arc; @@ -52,4 +54,4 @@ fn in_memory_offchain_storage() { assert!(!storage.compare_and_set(b"B", b"A", Some(b""), b"Y")); assert!(storage.compare_and_set(b"B", b"A", None, b"X")); assert_eq!(storage.get(b"B", b"A"), Some(b"X".to_vec())); -} \ No newline at end of file +} diff --git a/client/service/test/src/client/light.rs b/client/service/test/src/client/light.rs index 76e48828ee429c1128b6d7b448d1d3d95fd8c817..ffc84ad47b8f376b7f807e04376b36618278b086 100644 --- a/client/service/test/src/client/light.rs +++ b/client/service/test/src/client/light.rs @@ -1,19 +1,22 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . -use sc_service::client::light::{ +// along with this program. If not, see . + +use sc_light::{ call_executor::{ GenesisCallExecutor, check_execution_proof, @@ -34,10 +37,16 @@ use substrate_test_runtime_client::{ runtime::{Hash, Block, Header}, TestClient, ClientBlockImportExt, }; use sp_api::{InitializeBlock, StorageTransactionCache, ProofRecorder, OffchainOverlayedChanges}; -use sp_consensus::{BlockOrigin}; +use sp_consensus::BlockOrigin; use sc_executor::{NativeExecutor, WasmExecutionMethod, RuntimeVersion, NativeVersion}; -use sp_core::{H256, tasks::executor as tasks_executor, NativeOrEncoded}; -use sc_client_api::{blockchain::Info, backend::NewBlockState, Backend as ClientBackend, ProofProvider, in_mem::{Backend as InMemBackend, Blockchain as InMemoryBlockchain}, AuxStore, Storage, CallExecutor, cht, ExecutionStrategy, StorageProof, BlockImportOperation, RemoteCallRequest, StorageProvider, ChangesProof, RemoteBodyRequest, RemoteReadRequest, RemoteChangesRequest, FetchChecker, RemoteReadChildRequest, RemoteHeaderRequest}; +use sp_core::{H256, NativeOrEncoded, testing::TaskExecutor}; +use sc_client_api::{ + blockchain::Info, backend::NewBlockState, Backend as ClientBackend, ProofProvider, + in_mem::{Backend as InMemBackend, Blockchain as InMemoryBlockchain}, + AuxStore, Storage, CallExecutor, cht, ExecutionStrategy, StorageProof, BlockImportOperation, + RemoteCallRequest, StorageProvider, ChangesProof, RemoteBodyRequest, RemoteReadRequest, + RemoteChangesRequest, FetchChecker, RemoteReadChildRequest, RemoteHeaderRequest, BlockBackend, +}; use sp_externalities::Extensions; use sc_block_builder::BlockBuilderProvider; use sp_blockchain::{ @@ -308,7 +317,7 @@ fn execution_proof_is_generated_and_checked() { // check remote execution proof locally let local_result = check_execution_proof::<_, _, BlakeTwo256>( &local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), &RemoteCallRequest { block: substrate_test_runtime_client::runtime::Hash::default(), header: remote_header, @@ -336,7 +345,7 @@ fn execution_proof_is_generated_and_checked() { // check remote execution proof locally let execution_result = check_execution_proof_with_make_header::<_, _, BlakeTwo256, _>( &local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), &RemoteCallRequest { block: substrate_test_runtime_client::runtime::Hash::default(), header: remote_header, @@ -470,7 +479,7 @@ fn prepare_for_read_proof_check() -> (TestChecker, Header, StorageProof, u32) { let local_checker = LightDataChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), ); (local_checker, remote_block_header, remote_read_proof, heap_pages) } @@ -518,7 +527,7 @@ fn prepare_for_read_child_proof_check() -> (TestChecker, Header, StorageProof, V let local_checker = LightDataChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), ); (local_checker, remote_block_header, remote_read_proof, child_value) } @@ -549,7 +558,7 @@ fn prepare_for_header_proof_check(insert_cht: bool) -> (TestChecker, Hash, Heade let local_checker = LightDataChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), ); (local_checker, local_cht_root, remote_block_header, remote_header_proof) } @@ -633,7 +642,7 @@ fn changes_proof_is_generated_and_checked_when_headers_are_not_pruned() { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), ); let local_checker = &local_checker as &dyn FetchChecker; let max = remote_client.chain_info().best_number; @@ -677,7 +686,7 @@ fn changes_proof_is_generated_and_checked_when_headers_are_not_pruned() { match local_result == expected_result { true => (), false => panic!(format!("Failed test {}: local = {:?}, expected = {:?}", - index, local_result, expected_result)), + index, local_result, expected_result)), } } } @@ -708,7 +717,7 @@ fn changes_proof_is_generated_and_checked_when_headers_are_pruned() { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(local_storage)), local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), ); // check proof on local client @@ -743,7 +752,7 @@ fn check_changes_proof_fails_if_proof_is_wrong() { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), ); let local_checker = &local_checker as &dyn FetchChecker; let max = remote_client.chain_info().best_number; @@ -831,10 +840,10 @@ fn check_changes_tries_proof_fails_if_proof_is_wrong() { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), ); assert!(local_checker.check_changes_tries_proof(4, &remote_proof.roots, - remote_proof.roots_proof.clone()).is_err()); + remote_proof.roots_proof.clone()).is_err()); // fails when proof is broken let mut local_storage = DummyStorage::new(); @@ -842,7 +851,7 @@ fn check_changes_tries_proof_fails_if_proof_is_wrong() { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(local_storage)), local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), ); let result = local_checker.check_changes_tries_proof( 4, &remote_proof.roots, StorageProof::empty() @@ -860,7 +869,7 @@ fn check_body_proof_faulty() { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), ); let body_request = RemoteBodyRequest { @@ -884,7 +893,7 @@ fn check_body_proof_of_same_data_should_succeed() { let local_checker = TestChecker::new( Arc::new(DummyBlockchain::new(DummyStorage::new())), local_executor(), - tasks_executor(), + Box::new(TaskExecutor::new()), ); let body_request = RemoteBodyRequest { diff --git a/client/service/test/src/client/mod.rs b/client/service/test/src/client/mod.rs index e81d1ebb5364bc404cec0bb80539a0c385b77ee7..8d073df272fd9ab574b8de37db68c856cc717df0 100644 --- a/client/service/test/src/client/mod.rs +++ b/client/service/test/src/client/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use parity_scale_codec::{Encode, Decode, Joiner}; use sc_executor::native_executor_instance; @@ -38,8 +40,7 @@ use sp_runtime::traits::{ use substrate_test_runtime::TestAPI; use sp_state_machine::backend::Backend as _; use sp_api::{ProvideRuntimeApi, OffchainOverlayedChanges}; -use sp_core::tasks::executor as tasks_executor; -use sp_core::{H256, ChangesTrieConfiguration, blake2_256}; +use sp_core::{H256, ChangesTrieConfiguration, blake2_256, testing::TaskExecutor}; use std::collections::{HashMap, HashSet}; use std::sync::Arc; use sp_consensus::{ @@ -163,6 +164,7 @@ fn construct_block( let mut offchain_overlay = OffchainOverlayedChanges::default(); let backend_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&backend); let runtime_code = backend_runtime_code.runtime_code().expect("Code is part of the backend"); + let task_executor = Box::new(TaskExecutor::new()); StateMachine::new( backend, @@ -174,7 +176,7 @@ fn construct_block( &header.encode(), Default::default(), &runtime_code, - tasks_executor(), + task_executor.clone() as Box<_>, ).execute( ExecutionStrategy::NativeElseWasm, ).unwrap(); @@ -190,7 +192,7 @@ fn construct_block( &tx.encode(), Default::default(), &runtime_code, - tasks_executor(), + task_executor.clone() as Box<_>, ).execute( ExecutionStrategy::NativeElseWasm, ).unwrap(); @@ -206,7 +208,7 @@ fn construct_block( &[], Default::default(), &runtime_code, - tasks_executor(), + task_executor.clone() as Box<_>, ).execute( ExecutionStrategy::NativeElseWasm, ).unwrap(); @@ -260,7 +262,7 @@ fn construct_genesis_should_work_with_native() { &b1data, Default::default(), &runtime_code, - tasks_executor(), + TaskExecutor::new(), ).execute( ExecutionStrategy::NativeElseWasm, ).unwrap(); @@ -296,7 +298,7 @@ fn construct_genesis_should_work_with_wasm() { &b1data, Default::default(), &runtime_code, - tasks_executor(), + TaskExecutor::new(), ).execute( ExecutionStrategy::AlwaysWasm, ).unwrap(); @@ -332,7 +334,7 @@ fn construct_genesis_with_bad_transaction_should_panic() { &b1data, Default::default(), &runtime_code, - tasks_executor(), + TaskExecutor::new(), ).execute( ExecutionStrategy::NativeElseWasm, ); @@ -1741,7 +1743,7 @@ fn cleans_up_closed_notification_sinks_on_block_import() { &substrate_test_runtime_client::GenesisParameters::default().genesis_storage(), None, None, - sp_core::tasks::executor(), + Box::new(TaskExecutor::new()), Default::default(), ) .unwrap(); diff --git a/client/service/test/src/lib.rs b/client/service/test/src/lib.rs index fd6774136597c0044a4814aa94c1dbaafe9c0281..0d589cee7e12d220319b939d77db03021e5196f7 100644 --- a/client/service/test/src/lib.rs +++ b/client/service/test/src/lib.rs @@ -1,48 +1,53 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Service integration test utils. use std::iter; -use std::sync::{Arc, Mutex, MutexGuard}; +use std::sync::Arc; use std::net::Ipv4Addr; use std::pin::Pin; use std::time::Duration; -use log::info; +use log::{info, debug}; use futures01::{Future, Stream, Poll}; use futures::{FutureExt as _, TryFutureExt as _}; use tempfile::TempDir; use tokio::{runtime::Runtime, prelude::FutureExt}; use tokio::timer::Interval; use sc_service::{ - AbstractService, + TaskManager, GenericChainSpec, ChainSpecExtension, Configuration, - config::{DatabaseConfig, KeystoreConfig}, + config::{BasePath, DatabaseConfig, KeystoreConfig}, RuntimeGenesis, Role, Error, - TaskType, + TaskExecutor, + client::Client, }; use sp_blockchain::HeaderBackend; use sc_network::{multiaddr, Multiaddr}; use sc_network::config::{NetworkConfiguration, TransportConfig}; use sp_runtime::{generic::BlockId, traits::Block as BlockT}; use sp_transaction_pool::TransactionPool; +use sc_client_api::{Backend, CallExecutor}; +use parking_lot::Mutex; #[cfg(test)] mod client; @@ -52,47 +57,100 @@ const MAX_WAIT_TIME: Duration = Duration::from_secs(60 * 3); struct TestNet { runtime: Runtime, - authority_nodes: Vec<(usize, SyncService, U, Multiaddr)>, - full_nodes: Vec<(usize, SyncService, U, Multiaddr)>, - light_nodes: Vec<(usize, SyncService, Multiaddr)>, + authority_nodes: Vec<(usize, F, U, Multiaddr)>, + full_nodes: Vec<(usize, F, U, Multiaddr)>, + light_nodes: Vec<(usize, L, Multiaddr)>, chain_spec: GenericChainSpec, base_port: u16, nodes: usize, } -/// Wraps around an `Arc` and implements `Future`. -pub struct SyncService(Arc>); +pub trait TestNetNode: Clone + Future + Send + 'static { + type Block: BlockT; + type Backend: Backend; + type Executor: CallExecutor + Send + Sync; + type RuntimeApi: Send + Sync; + type TransactionPool: TransactionPool; -impl SyncService { - pub fn get(&self) -> MutexGuard { - self.0.lock().unwrap() - } + fn client(&self) -> Arc>; + fn transaction_pool(&self) -> Arc; + fn network(&self) -> Arc::Hash>>; } -impl Clone for SyncService { - fn clone(&self) -> Self { - Self(self.0.clone()) +pub struct TestNetComponents { + task_manager: Arc>, + client: Arc>, + transaction_pool: Arc, + network: Arc::Hash>>, +} + +impl +TestNetComponents { + pub fn new( + task_manager: TaskManager, + client: Arc>, + network: Arc::Hash>>, + transaction_pool: Arc, + ) -> Self { + Self { + client, transaction_pool, network, + task_manager: Arc::new(Mutex::new(task_manager)), + } } } -impl From for SyncService { - fn from(service: T) -> Self { - SyncService(Arc::new(Mutex::new(service))) + +impl Clone for +TestNetComponents { + fn clone(&self) -> Self { + Self { + task_manager: self.task_manager.clone(), + client: self.client.clone(), + transaction_pool: self.transaction_pool.clone(), + network: self.network.clone(), + } } } -impl> + Unpin> Future for SyncService { +impl Future for + TestNetComponents +{ type Item = (); type Error = sc_service::Error; fn poll(&mut self) -> Poll { - let mut f = self.0.lock().unwrap(); - futures::compat::Compat::new(&mut *f).poll() + futures::compat::Compat::new(&mut self.task_manager.lock().future()).poll() + } +} + +impl TestNetNode for +TestNetComponents + where + TBl: BlockT, + TBackend: sc_client_api::Backend + Send + Sync + 'static, + TExec: CallExecutor + Send + Sync + 'static, + TRtApi: Send + Sync + 'static, + TExPool: TransactionPool + Send + Sync + 'static, +{ + type Block = TBl; + type Backend = TBackend; + type Executor = TExec; + type RuntimeApi = TRtApi; + type TransactionPool = TExPool; + + fn client(&self) -> Arc> { + self.client.clone() + } + fn transaction_pool(&self) -> Arc { + self.transaction_pool.clone() + } + fn network(&self) -> Arc::Hash>> { + self.network.clone() } } impl TestNet -where F: Send + 'static, L: Send +'static, U: Clone + Send + 'static +where F: Clone + Send + 'static, L: Clone + Send +'static, U: Clone + Send + 'static { pub fn run_until_all_full( &mut self, @@ -100,8 +158,8 @@ where F: Send + 'static, L: Send +'static, U: Clone + Send + 'static light_predicate: LP, ) where - FP: Send + Fn(usize, &SyncService) -> bool + 'static, - LP: Send + Fn(usize, &SyncService) -> bool + 'static, + FP: Send + Fn(usize, &F) -> bool + 'static, + LP: Send + Fn(usize, &L) -> bool + 'static, { let full_nodes = self.full_nodes.clone(); let light_nodes = self.light_nodes.clone(); @@ -140,7 +198,7 @@ fn node_config, role: Role, - task_executor: Arc + Send>>, TaskType) + Send + Sync>, + task_executor: TaskExecutor, key_seed: Option, base_port: u16, root: &TempDir, @@ -171,8 +229,8 @@ fn node_config TestNet where - F: AbstractService, - L: AbstractService, + F: TestNetNode, + L: TestNetNode, E: ChainSpecExtension + Clone + 'static + Send, G: RuntimeGenesis + 'static, { @@ -252,58 +313,67 @@ impl TestNet where authorities: impl Iterator Result<(F, U), Error>)> ) { let executor = self.runtime.executor(); + let task_executor: TaskExecutor = { + let executor = executor.clone(); + (move |fut: Pin + Send>>, _| { + executor.spawn(fut.unit_error().compat()); + async {} + }).into() + }; for (key, authority) in authorities { - let task_executor = { - let executor = executor.clone(); - Arc::new(move |fut: Pin + Send>>, _| executor.spawn(fut.unit_error().compat())) - }; let node_config = node_config( self.nodes, &self.chain_spec, Role::Authority { sentry_nodes: Vec::new() }, - task_executor, + task_executor.clone(), Some(key), self.base_port, &temp, ); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); let (service, user_data) = authority(node_config).expect("Error creating test node service"); - let service = SyncService::from(service); executor.spawn(service.clone().map_err(|_| ())); - let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().clone().into())); + let addr = addr.with(multiaddr::Protocol::P2p(service.network().local_peer_id().clone().into())); self.authority_nodes.push((self.nodes, service, user_data, addr)); self.nodes += 1; } for full in full { - let task_executor = { - let executor = executor.clone(); - Arc::new(move |fut: Pin + Send>>, _| executor.spawn(fut.unit_error().compat())) - }; - let node_config = node_config(self.nodes, &self.chain_spec, Role::Full, task_executor, None, self.base_port, &temp); + let node_config = node_config( + self.nodes, + &self.chain_spec, + Role::Full, + task_executor.clone(), + None, + self.base_port, + &temp, + ); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); let (service, user_data) = full(node_config).expect("Error creating test node service"); - let service = SyncService::from(service); executor.spawn(service.clone().map_err(|_| ())); - let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().clone().into())); + let addr = addr.with(multiaddr::Protocol::P2p(service.network().local_peer_id().clone().into())); self.full_nodes.push((self.nodes, service, user_data, addr)); self.nodes += 1; } for light in light { - let task_executor = { - let executor = executor.clone(); - Arc::new(move |fut: Pin + Send>>, _| executor.spawn(fut.unit_error().compat())) - }; - let node_config = node_config(self.nodes, &self.chain_spec, Role::Light, task_executor, None, self.base_port, &temp); + let node_config = node_config( + self.nodes, + &self.chain_spec, + Role::Light, + task_executor.clone(), + None, + self.base_port, + &temp, + ); let addr = node_config.network.listen_addresses.iter().next().unwrap().clone(); - let service = SyncService::from(light(node_config).expect("Error creating test node service")); + let service = light(node_config).expect("Error creating test node service"); executor.spawn(service.clone().map_err(|_| ())); - let addr = addr.with(multiaddr::Protocol::P2p(service.get().network().local_peer_id().clone().into())); + let addr = addr.with(multiaddr::Protocol::P2p(service.network().local_peer_id().clone().into())); self.light_nodes.push((self.nodes, service, addr)); self.nodes += 1; } @@ -322,9 +392,9 @@ pub fn connectivity( E: ChainSpecExtension + Clone + 'static + Send, G: RuntimeGenesis + 'static, Fb: Fn(Configuration) -> Result, - F: AbstractService, + F: TestNetNode, Lb: Fn(Configuration) -> Result, - L: AbstractService, + L: TestNetNode, { const NUM_FULL_NODES: usize = 5; const NUM_LIGHT_NODES: usize = 5; @@ -348,19 +418,25 @@ pub fn connectivity( info!("Checking star topology"); let first_address = network.full_nodes[0].3.clone(); for (_, service, _, _) in network.full_nodes.iter().skip(1) { - service.get().network().add_reserved_peer(first_address.to_string()) + service.network().add_reserved_peer(first_address.to_string()) .expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { - service.get().network().add_reserved_peer(first_address.to_string()) + service.network().add_reserved_peer(first_address.to_string()) .expect("Error adding reserved peer"); } network.run_until_all_full( - move |_index, service| service.get().network().num_connected() - == expected_full_connections, - move |_index, service| service.get().network().num_connected() - == expected_light_connections, + move |_index, service| { + let connected = service.network().num_connected(); + debug!("Got {}/{} full connections...", connected, expected_full_connections); + connected == expected_full_connections + }, + move |_index, service| { + let connected = service.network().num_connected(); + debug!("Got {}/{} light connections...", connected, expected_light_connections); + connected == expected_light_connections + }, ); network.runtime @@ -389,24 +465,30 @@ pub fn connectivity( for i in 0..max_nodes { if i != 0 { if let Some((_, service, _, node_id)) = network.full_nodes.get(i) { - service.get().network().add_reserved_peer(address.to_string()) + service.network().add_reserved_peer(address.to_string()) .expect("Error adding reserved peer"); address = node_id.clone(); } } if let Some((_, service, node_id)) = network.light_nodes.get(i) { - service.get().network().add_reserved_peer(address.to_string()) + service.network().add_reserved_peer(address.to_string()) .expect("Error adding reserved peer"); address = node_id.clone(); } } network.run_until_all_full( - move |_index, service| service.get().network().num_connected() - == expected_full_connections, - move |_index, service| service.get().network().num_connected() - == expected_light_connections, + move |_index, service| { + let connected = service.network().num_connected(); + debug!("Got {}/{} full connections...", connected, expected_full_connections); + connected == expected_full_connections + }, + move |_index, service| { + let connected = service.network().num_connected(); + debug!("Got {}/{} light connections...", connected, expected_light_connections); + connected == expected_light_connections + }, ); } temp.close().expect("Error removing temp dir"); @@ -421,9 +503,9 @@ pub fn sync( mut extrinsic_factory: ExF ) where Fb: Fn(Configuration) -> Result<(F, U), Error>, - F: AbstractService, + F: TestNetNode, Lb: Fn(Configuration) -> Result, - L: AbstractService, + L: TestNetNode, B: FnMut(&F, &mut U), ExF: FnMut(&F, &U) -> ::Extrinsic, U: Clone + Send + 'static, @@ -437,7 +519,7 @@ pub fn sync( let temp = tempdir_with_prefix("substrate-sync-test"); let mut network = TestNet::new( &temp, - spec.clone(), + spec, (0..NUM_FULL_NODES).map(|_| { |cfg| full_builder(cfg) }), (0..NUM_LIGHT_NODES).map(|_| { |cfg| light_builder(cfg) }), // Note: this iterator is empty but we can't just use `iter::empty()`, otherwise @@ -453,38 +535,41 @@ pub fn sync( info!("Generating #{}", i + 1); } - make_block_and_import(&first_service.get(), first_user_data); + make_block_and_import(&first_service, first_user_data); } + network.full_nodes[0].1.network().update_chain(); network.full_nodes[0].3.clone() }; info!("Running sync"); for (_, service, _, _) in network.full_nodes.iter().skip(1) { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + service.network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + service.network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } network.run_until_all_full( |_index, service| - service.get().client().info().best_number == (NUM_BLOCKS as u32).into(), + service.client().info().best_number == (NUM_BLOCKS as u32).into(), |_index, service| - service.get().client().info().best_number == (NUM_BLOCKS as u32).into(), + service.client().info().best_number == (NUM_BLOCKS as u32).into(), ); info!("Checking extrinsic propagation"); let first_service = network.full_nodes[0].1.clone(); let first_user_data = &network.full_nodes[0].2; - let best_block = BlockId::number(first_service.get().client().info().best_number); - let extrinsic = extrinsic_factory(&first_service.get(), first_user_data); + let best_block = BlockId::number(first_service.client().info().best_number); + let extrinsic = extrinsic_factory(&first_service, first_user_data); let source = sp_transaction_pool::TransactionSource::External; futures::executor::block_on( - first_service.get().transaction_pool().submit_one(&best_block, source, extrinsic) + first_service.transaction_pool().submit_one(&best_block, source, extrinsic) ).expect("failed to submit extrinsic"); network.run_until_all_full( - |_index, service| service.get().transaction_pool().ready().count() == 1, + |_index, service| service.transaction_pool().ready().count() == 1, |_index, _service| true, ); } @@ -496,9 +581,9 @@ pub fn consensus( authorities: impl IntoIterator ) where Fb: Fn(Configuration) -> Result, - F: AbstractService, + F: TestNetNode, Lb: Fn(Configuration) -> Result, - L: AbstractService, + L: TestNetNode, E: ChainSpecExtension + Clone + 'static + Send, G: RuntimeGenesis + 'static, { @@ -508,7 +593,7 @@ pub fn consensus( let temp = tempdir_with_prefix("substrate-consensus-test"); let mut network = TestNet::new( &temp, - spec.clone(), + spec, (0..NUM_FULL_NODES / 2).map(|_| { |cfg| full_builder(cfg).map(|s| (s, ())) }), (0..NUM_LIGHT_NODES / 2).map(|_| { |cfg| light_builder(cfg) }), authorities.into_iter().map(|key| (key, { |cfg| full_builder(cfg).map(|s| (s, ())) })), @@ -518,19 +603,22 @@ pub fn consensus( info!("Checking consensus"); let first_address = network.authority_nodes[0].3.clone(); for (_, service, _, _) in network.full_nodes.iter() { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + service.network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + service.network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } for (_, service, _, _) in network.authority_nodes.iter().skip(1) { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + service.network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } network.run_until_all_full( |_index, service| - service.get().client().info().finalized_number >= (NUM_BLOCKS as u32 / 2).into(), + service.client().info().finalized_number >= (NUM_BLOCKS as u32 / 2).into(), |_index, service| - service.get().client().info().best_number >= (NUM_BLOCKS as u32 / 2).into(), + service.client().info().best_number >= (NUM_BLOCKS as u32 / 2).into(), ); info!("Adding more peers"); @@ -543,15 +631,17 @@ pub fn consensus( (0..0).map(|_| (String::new(), { |cfg| full_builder(cfg).map(|s| (s, ())) })), ); for (_, service, _, _) in network.full_nodes.iter() { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + service.network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } for (_, service, _) in network.light_nodes.iter() { - service.get().network().add_reserved_peer(first_address.to_string()).expect("Error adding reserved peer"); + service.network().add_reserved_peer(first_address.to_string()) + .expect("Error adding reserved peer"); } network.run_until_all_full( |_index, service| - service.get().client().info().finalized_number >= (NUM_BLOCKS as u32).into(), + service.client().info().finalized_number >= (NUM_BLOCKS as u32).into(), |_index, service| - service.get().client().info().best_number >= (NUM_BLOCKS as u32).into(), + service.client().info().best_number >= (NUM_BLOCKS as u32).into(), ); } diff --git a/client/state-db/Cargo.toml b/client/state-db/Cargo.toml index c2d2f2eb0badf5a60a8db5c5af44790eb6e125a8..f78e0ca505a61f1dbacb7486027662d1324ef5d2 100644 --- a/client/state-db/Cargo.toml +++ b/client/state-db/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-state-db" -version = "0.8.0-dev" +version = "0.8.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "State database maintenance. Handles canonicalization and pruning in the database." @@ -14,10 +14,10 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] parking_lot = "0.10.0" log = "0.4.8" -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -codec = { package = "parity-scale-codec", version = "1.3.0", features = ["derive"] } -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +codec = { package = "parity-scale-codec", version = "1.3.4", features = ["derive"] } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } parity-util-mem-derive = "0.1.0" [dev-dependencies] diff --git a/client/state-db/README.md b/client/state-db/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a02b3929088fc8289a22d4a372101ca703cb6876 --- /dev/null +++ b/client/state-db/README.md @@ -0,0 +1,16 @@ +State database maintenance. Handles canonicalization and pruning in the database. The input to +this module is a `ChangeSet` which is basically a list of key-value pairs (trie nodes) that +were added or deleted during block execution. + +# Canonicalization. +Canonicalization window tracks a tree of blocks identified by header hash. The in-memory +overlay allows to get any node that was inserted in any of the blocks within the window. +The tree is journaled to the backing database and rebuilt on startup. +Canonicalization function selects one root from the top of the tree and discards all other roots and +their subtrees. + +# Pruning. +See `RefWindow` for pruning algorithm details. `StateDb` prunes on each canonicalization until pruning +constraints are satisfied. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/state-db/src/lib.rs b/client/state-db/src/lib.rs index 94d51c89126485167228606da10db2aff4df1cc3..61470894e487e3884bc873301ff17e39345a0877 100644 --- a/client/state-db/src/lib.rs +++ b/client/state-db/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! State database maintenance. Handles canonicalization and pruning in the database. The input to //! this module is a `ChangeSet` which is basically a list of key-value pairs (trie nodes) that diff --git a/client/state-db/src/noncanonical.rs b/client/state-db/src/noncanonical.rs index 6a743e7d45913bc684961a300494b5e4154339f6..d77f20c50d05f30916f024666607dc7f3f16d440 100644 --- a/client/state-db/src/noncanonical.rs +++ b/client/state-db/src/noncanonical.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Canonicalization window. //! Maintains trees of block overlays and allows discarding trees/roots diff --git a/client/state-db/src/pruning.rs b/client/state-db/src/pruning.rs index 6921beea916564a779ab7543c2d9e10d9c67b5da..69b07c285fad8318152611d9473c508367a9f73c 100644 --- a/client/state-db/src/pruning.rs +++ b/client/state-db/src/pruning.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Pruning window. //! diff --git a/client/state-db/src/test.rs b/client/state-db/src/test.rs index accafa9bf831fb323b7f0247080f85d08d1c3f4d..11ce4ad8226202d0f08a9e77bdddfb8e7772deaa 100644 --- a/client/state-db/src/test.rs +++ b/client/state-db/src/test.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Test utils diff --git a/client/telemetry/Cargo.toml b/client/telemetry/Cargo.toml index 0928d1d2a151822643e58781b8da23178acc6f9c..3ad82f56125028ddfc0685a7fe9bd541077bb7ed 100644 --- a/client/telemetry/Cargo.toml +++ b/client/telemetry/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "sc-telemetry" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] description = "Telemetry utils" edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" documentation = "https://docs.rs/sc-telemetry" @@ -14,12 +14,11 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] -bytes = "0.5" parking_lot = "0.10.0" futures = "0.3.4" futures-timer = "3.0.1" wasm-timer = "0.2.0" -libp2p = { version = "0.18.1", default-features = false, features = ["websocket", "wasm-ext", "tcp", "dns"] } +libp2p = { version = "0.24.0", default-features = false, features = ["dns", "tcp-async-std", "wasm-ext", "websocket"] } log = "0.4.8" pin-project = "0.4.6" rand = "0.7.2" diff --git a/client/telemetry/README.md b/client/telemetry/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8fdf9e500722dd8ffc7835c628baab063ed64f17 --- /dev/null +++ b/client/telemetry/README.md @@ -0,0 +1,45 @@ +Telemetry utilities. + +Calling `init_telemetry` registers a global `slog` logger using `slog_scope::set_global_logger`. +After that, calling `slog_scope::with_logger` will return a logger that sends information to +the telemetry endpoints. The `telemetry!` macro is a short-cut for calling +`slog_scope::with_logger` followed with `slog_log!`. + +Note that you are supposed to only ever use `telemetry!` and not `slog_scope::with_logger` at +the moment. Substrate may eventually be reworked to get proper `slog` support, including sending +information to the telemetry. + +The [`Telemetry`] struct implements `Stream` and must be polled regularly (or sent to a +background thread/task) in order for the telemetry to properly function. Dropping the object +will also deregister the global logger and replace it with a logger that discards messages. +The `Stream` generates [`TelemetryEvent`]s. + +> **Note**: Cloning the [`Telemetry`] and polling from multiple clones has an unspecified behaviour. + +# Example + +```rust +use futures::prelude::*; + +let telemetry = sc_telemetry::init_telemetry(sc_telemetry::TelemetryConfig { + endpoints: sc_telemetry::TelemetryEndpoints::new(vec![ + // The `0` is the maximum verbosity level of messages to send to this endpoint. + ("wss://example.com".into(), 0) + ]).expect("Invalid URL or multiaddr provided"), + // Can be used to pass an external implementation of WebSockets. + wasm_external_transport: None, +}); + +// The `telemetry` object implements `Stream` and must be processed. +std::thread::spawn(move || { + futures::executor::block_on(telemetry.for_each(|_| future::ready(()))); +}); + +// Sends a message on the telemetry. +sc_telemetry::telemetry!(sc_telemetry::SUBSTRATE_INFO; "test"; + "foo" => "bar", +) +``` + + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/telemetry/src/lib.rs b/client/telemetry/src/lib.rs index 6c90d6bbcca9f3a60fc765e056abd908c0ea0636..6a5ac0e0cb3122925ed0e12e62431742cbe20a02 100644 --- a/client/telemetry/src/lib.rs +++ b/client/telemetry/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Telemetry utilities. //! @@ -121,6 +123,13 @@ impl TelemetryEndpoints { } } +impl TelemetryEndpoints { + /// Return `true` if there are no telemetry endpoints, `false` otherwise. + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + /// Parses a WebSocket URL into a libp2p `Multiaddr`. fn url_to_multiaddr(url: &str) -> Result { // First, assume that we have a `Multiaddr`. diff --git a/client/telemetry/src/worker.rs b/client/telemetry/src/worker.rs index 8f43bb612a10503d0d8968821bc90f1469140f85..e01ac62d12dc36fdab9e4feebec33eed662ba93c 100644 --- a/client/telemetry/src/worker.rs +++ b/client/telemetry/src/worker.rs @@ -1,18 +1,20 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Contains the object that makes the telemetry work. //! @@ -26,7 +28,6 @@ //! events indicating what happened since the latest polling. //! -use bytes::BytesMut; use futures::{prelude::*, ready}; use libp2p::{core::transport::OptionalTransport, Multiaddr, Transport, wasm_ext}; use log::{trace, warn, error}; @@ -59,8 +60,8 @@ impl, I> StreamAndSink for T {} type WsTrans = libp2p::core::transport::boxed::Boxed< Pin, + Vec, + Item = Result, io::Error>, Error = io::Error > + Send>>, io::Error @@ -90,12 +91,12 @@ impl TelemetryWorker { libp2p::websocket::framed::WsConfig::new(inner) .and_then(|connec, _| { let connec = connec - .with(|item: BytesMut| { + .with(|item| { let item = libp2p::websocket::framed::OutgoingData::Binary(item); future::ready(Ok::<_, io::Error>(item)) }) .try_filter(|item| future::ready(item.is_data())) - .map_ok(|data| BytesMut::from(data.as_ref())); + .map_ok(|data| data.into_bytes()); future::ready(Ok::<_, io::Error>(connec)) }) }); @@ -187,7 +188,7 @@ impl TelemetryWorker { /// For some context, we put this object around the `wasm_ext::ExtTransport` in order to make sure /// that each telemetry message maps to one single call to `write` in the WASM FFI. #[pin_project::pin_project] -struct StreamSink(#[pin] T, Option); +struct StreamSink(#[pin] T, Option>); impl From for StreamSink { fn from(inner: T) -> StreamSink { @@ -196,15 +197,15 @@ impl From for StreamSink { } impl Stream for StreamSink { - type Item = Result; + type Item = Result, io::Error>; fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { let this = self.project(); - let mut buf = [0; 128]; + let mut buf = vec![0; 128]; match ready!(AsyncRead::poll_read(this.0, cx, &mut buf)) { Ok(0) => Poll::Ready(None), Ok(n) => { - let buf: BytesMut = buf[..n].into(); + buf.truncate(n); Poll::Ready(Some(Ok(buf))) }, Err(err) => Poll::Ready(Some(Err(err))), @@ -230,7 +231,7 @@ impl StreamSink { } } -impl Sink for StreamSink { +impl Sink> for StreamSink { type Error = io::Error; fn poll_ready(self: Pin<&mut Self>, cx: &mut Context) -> Poll> { @@ -238,7 +239,7 @@ impl Sink for StreamSink { Poll::Ready(Ok(())) } - fn start_send(self: Pin<&mut Self>, item: BytesMut) -> Result<(), Self::Error> { + fn start_send(self: Pin<&mut Self>, item: Vec) -> Result<(), Self::Error> { let this = self.project(); debug_assert!(this.1.is_none()); *this.1 = Some(item); diff --git a/client/telemetry/src/worker/node.rs b/client/telemetry/src/worker/node.rs index 454f504d660050995cba1f6c122c311ba35741ee..eef7ca7e815536aaaa26f8e2d20f17dc67e2f1e5 100644 --- a/client/telemetry/src/worker/node.rs +++ b/client/telemetry/src/worker/node.rs @@ -1,22 +1,23 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Contains the `Node` struct, which handles communications with a single telemetry endpoint. -use bytes::BytesMut; use futures::prelude::*; use futures_timer::Delay; use libp2p::Multiaddr; @@ -55,7 +56,7 @@ struct NodeSocketConnected { /// Where to send data. sink: TTrans::Output, /// Queue of packets to send. - pending: VecDeque, + pending: VecDeque>, /// If true, we need to flush the sink. need_flush: bool, /// A timeout for the socket to write data. @@ -101,15 +102,15 @@ impl Node { impl Node where TTrans: Clone + Unpin, TTrans::Dial: Unpin, - TTrans::Output: Sink - + Stream> + TTrans::Output: Sink, Error = TSinkErr> + + Stream, TSinkErr>> + Unpin, TSinkErr: fmt::Debug { /// Sends a WebSocket frame to the node. Returns an error if we are not connected to the node. /// /// After calling this method, you should call `poll` in order for it to be properly processed. - pub fn send_message(&mut self, payload: impl Into) -> Result<(), ()> { + pub fn send_message(&mut self, payload: impl Into>) -> Result<(), ()> { if let NodeSocket::Connected(NodeSocketConnected { pending, .. }) = &mut self.socket { if pending.len() <= MAX_PENDING { trace!(target: "telemetry", "Adding log entry to queue for {:?}", self.addr); @@ -201,8 +202,8 @@ fn gen_rand_reconnect_delay() -> Delay { } impl NodeSocketConnected -where TTrans::Output: Sink - + Stream> +where TTrans::Output: Sink, Error = TSinkErr> + + Stream, TSinkErr>> + Unpin { /// Processes the queue of messages for the connected socket. diff --git a/client/tracing/Cargo.toml b/client/tracing/Cargo.toml index 23f44fd057570e4aae988a2d316e51aea01e3150..40ab1bd460359bf3c463e5d579cb344c0ebda1f4 100644 --- a/client/tracing/Cargo.toml +++ b/client/tracing/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sc-tracing" -version = "2.0.0-dev" -license = "GPL-3.0" +version = "2.0.0-rc6" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" authors = ["Parity Technologies "] edition = "2018" homepage = "https://substrate.dev" @@ -15,12 +15,12 @@ targets = ["x86_64-unknown-linux-gnu"] erased-serde = "0.3.9" log = { version = "0.4.8" } parking_lot = "0.10.0" +rustc-hash = "1.1.0" serde = "1.0.101" serde_json = "1.0.41" slog = { version = "2.5.2", features = ["nested-values"] } -tracing-core = "0.1.7" +tracing = "0.1.18" +tracing-subscriber = "0.2.10" +sp-tracing = { version = "2.0.0-rc2", path = "../../primitives/tracing" } -sc-telemetry = { version = "2.0.0-dev", path = "../telemetry" } - -[dev-dependencies] -tracing = "0.1.10" +sc-telemetry = { version = "2.0.0-rc6", path = "../telemetry" } diff --git a/client/tracing/README.md b/client/tracing/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b008436df9bbedd136f79be15c10ec5a7c7b9a07 --- /dev/null +++ b/client/tracing/README.md @@ -0,0 +1,11 @@ +Instrumentation implementation for substrate. + +This crate is unstable and the API and usage may change. + +# Usage + +See `sp-tracing` for examples on how to use tracing. + +Currently we provide `Log` (default), `Telemetry` variants for `Receiver` + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/tracing/src/lib.rs b/client/tracing/src/lib.rs index d450700ed3c49f9f41d27999aad6753fbe5f84bf..f642b00720f1ad13db5b136b58e14e1c7c4fda41 100644 --- a/client/tracing/src/lib.rs +++ b/client/tracing/src/lib.rs @@ -24,24 +24,37 @@ //! //! Currently we provide `Log` (default), `Telemetry` variants for `Receiver` -use std::collections::HashMap; +use rustc_hash::FxHashMap; use std::fmt; use std::sync::atomic::{AtomicU64, Ordering}; use std::time::{Duration, Instant}; use parking_lot::Mutex; use serde::ser::{Serialize, Serializer, SerializeMap}; -use slog::{SerdeValue, Value}; -use tracing_core::{ +use tracing::{ event::Event, field::{Visit, Field}, Level, metadata::Metadata, span::{Attributes, Id, Record}, - subscriber::Subscriber + subscriber::Subscriber, }; +use tracing_subscriber::CurrentSpan; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; +use sp_tracing::proxy::{WASM_NAME_KEY, WASM_TARGET_KEY, WASM_TRACE_IDENTIFIER}; + +const ZERO_DURATION: Duration = Duration::from_nanos(0); +const PROXY_TARGET: &'static str = "sp_tracing::proxy"; + +/// Responsible for assigning ids to new spans, which are not re-used. +pub struct ProfilingSubscriber { + next_id: AtomicU64, + targets: Vec<(String, Level)>, + trace_handler: Box, + span_data: Mutex>, + current_span: CurrentSpan, +} /// Used to configure how to receive the metrics #[derive(Debug, Clone)] @@ -58,69 +71,141 @@ impl Default for TracingReceiver { } } +/// A handler for tracing `SpanDatum` +pub trait TraceHandler: Send + Sync { + /// Process a `SpanDatum` + fn handle_span(&self, span: SpanDatum); + /// Process a `TraceEvent` + fn handle_event(&self, event: TraceEvent); +} + +/// Represents a tracing event, complete with values #[derive(Debug)] -struct SpanDatum { - id: u64, - name: &'static str, - target: &'static str, - level: Level, - line: u32, - start_time: Instant, - overall_time: Duration, - values: Visitor, +pub struct TraceEvent { + pub name: &'static str, + pub target: String, + pub level: Level, + pub values: Values, + pub parent_id: Option, +} + +/// Represents a single instance of a tracing span +#[derive(Debug)] +pub struct SpanDatum { + /// id for this span + pub id: Id, + /// id of the parent span, if any + pub parent_id: Option, + /// Name of this span + pub name: String, + /// Target, typically module + pub target: String, + /// Tracing Level - ERROR, WARN, INFO, DEBUG or TRACE + pub level: Level, + /// Line number in source + pub line: u32, + /// Time that the span was last entered + pub start_time: Instant, + /// Total duration of span while entered + pub overall_time: Duration, + /// Values recorded to this span + pub values: Values, +} + +/// Holds associated values for a tracing span +#[derive(Default, Clone, Debug)] +pub struct Values { + /// HashMap of `bool` values + pub bool_values: FxHashMap, + /// HashMap of `i64` values + pub i64_values: FxHashMap, + /// HashMap of `u64` values + pub u64_values: FxHashMap, + /// HashMap of `String` values + pub string_values: FxHashMap, } -#[derive(Clone, Debug)] -struct Visitor(Vec<(String, String)>); +impl Values { + /// Returns a new instance of Values + pub fn new() -> Self { + Default::default() + } + + /// Checks if all individual collections are empty + pub fn is_empty(&self) -> bool { + self.bool_values.is_empty() && + self.i64_values.is_empty() && + self.u64_values.is_empty() && + self.string_values.is_empty() + } +} -impl Visit for Visitor { +impl Visit for Values { fn record_i64(&mut self, field: &Field, value: i64) { - self.record_debug(field, &value) + self.i64_values.insert(field.name().to_string(), value); } fn record_u64(&mut self, field: &Field, value: u64) { - self.record_debug(field, &value) + self.u64_values.insert(field.name().to_string(), value); } fn record_bool(&mut self, field: &Field, value: bool) { - self.record_debug(field, &value) + self.bool_values.insert(field.name().to_string(), value); + } + + fn record_str(&mut self, field: &Field, value: &str) { + self.string_values.insert(field.name().to_string(), value.to_owned()); } fn record_debug(&mut self, field: &Field, value: &dyn std::fmt::Debug) { - self.0.push((field.name().to_string(), format!("{:?}",value))); + self.string_values.insert(field.name().to_string(), format!("{:?}", value).to_owned()); } } -impl Serialize for Visitor { +impl Serialize for Values { fn serialize(&self, serializer: S) -> Result where S: Serializer, { - let mut map = serializer.serialize_map(Some(self.0.len()))?; - for (k, v) in &self.0 { + let len = self.bool_values.len() + self.i64_values.len() + self.u64_values.len() + self.string_values.len(); + let mut map = serializer.serialize_map(Some(len))?; + for (k, v) in &self.bool_values { + map.serialize_entry(k, v)?; + } + for (k, v) in &self.i64_values { + map.serialize_entry(k, v)?; + } + for (k, v) in &self.u64_values { + map.serialize_entry(k, v)?; + } + for (k, v) in &self.string_values { map.serialize_entry(k, v)?; } map.end() } } -impl fmt::Display for Visitor { +impl fmt::Display for Values { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let values = self.0.iter().map(|(k,v)| format!("{}={}",k,v)).collect::>().join(", "); + let bool_iter = self.bool_values.iter().map(|(k, v)| format!("{}={}", k, v)); + let i64_iter = self.i64_values.iter().map(|(k, v)| format!("{}={}", k, v)); + let u64_iter = self.u64_values.iter().map(|(k, v)| format!("{}={}", k, v)); + let string_iter = self.string_values.iter().map(|(k, v)| format!("{}=\"{}\"", k, v)); + let values = bool_iter.chain(i64_iter).chain(u64_iter).chain(string_iter).collect::>().join(", "); write!(f, "{}", values) } } -impl SerdeValue for Visitor { +impl slog::SerdeValue for Values { fn as_serde(&self) -> &dyn erased_serde::Serialize { self } - fn to_sendable(&self) -> Box { + fn to_sendable(&self) -> Box { Box::new(self.clone()) } } -impl Value for Visitor { +impl slog::Value for Values { fn serialize( &self, _record: &slog::Record, @@ -131,26 +216,46 @@ impl Value for Visitor { } } -/// Responsible for assigning ids to new spans, which are not re-used. -pub struct ProfilingSubscriber { - next_id: AtomicU64, - targets: Vec<(String, Level)>, - receiver: TracingReceiver, - span_data: Mutex>, -} - impl ProfilingSubscriber { - /// Takes a `Receiver` and a comma separated list of targets, - /// either with a level: "pallet=trace" - /// or without: "pallet". - pub fn new(receiver: TracingReceiver, targets: &str) -> Self { + /// Takes a `TracingReceiver` and a comma separated list of targets, + /// either with a level: "pallet=trace,frame=debug" + /// or without: "pallet,frame" in which case the level defaults to `trace`. + /// wasm_tracing indicates whether to enable wasm traces + pub fn new(receiver: TracingReceiver, targets: &str) -> ProfilingSubscriber { + match receiver { + TracingReceiver::Log => Self::new_with_handler(Box::new(LogTraceHandler), targets), + TracingReceiver::Telemetry => Self::new_with_handler( + Box::new(TelemetryTraceHandler), + targets, + ), + } + } + + /// Allows use of a custom TraceHandler to create a new instance of ProfilingSubscriber. + /// Takes a comma separated list of targets, + /// either with a level, eg: "pallet=trace" + /// or without: "pallet" in which case the level defaults to `trace`. + /// wasm_tracing indicates whether to enable wasm traces + pub fn new_with_handler(trace_handler: Box, targets: &str) + -> ProfilingSubscriber + { let targets: Vec<_> = targets.split(',').map(|s| parse_target(s)).collect(); ProfilingSubscriber { next_id: AtomicU64::new(1), targets, - receiver, - span_data: Mutex::new(HashMap::new()), + trace_handler, + span_data: Mutex::new(FxHashMap::default()), + current_span: Default::default() + } + } + + fn check_target(&self, target: &str, level: &Level) -> bool { + for t in &self.targets { + if target.starts_with(t.0.as_str()) && level <= &t.1 { + return true; + } } + false } } @@ -173,105 +278,374 @@ fn parse_target(s: &str) -> (String, Level) { impl Subscriber for ProfilingSubscriber { fn enabled(&self, metadata: &Metadata<'_>) -> bool { - for t in &self.targets { - if metadata.target().starts_with(t.0.as_str()) && metadata.level() <= &t.1 { - log::debug!("Enabled target: {}, level: {}", metadata.target(), metadata.level()); - return true; - } else { - log::debug!("Disabled target: {}, level: {}", metadata.target(), metadata.level()); - } + if metadata.target() == PROXY_TARGET || self.check_target(metadata.target(), metadata.level()) { + log::debug!(target: "tracing", "Enabled target: {}, level: {}", metadata.target(), metadata.level()); + true + } else { + log::debug!(target: "tracing", "Disabled target: {}, level: {}", metadata.target(), metadata.level()); + false } - false } fn new_span(&self, attrs: &Attributes<'_>) -> Id { - let id = self.next_id.fetch_add(1, Ordering::Relaxed); - let mut values = Visitor(Vec::new()); + let id = Id::from_u64(self.next_id.fetch_add(1, Ordering::Relaxed)); + let mut values = Values::default(); attrs.record(&mut values); + // If this is a wasm trace, check if target/level is enabled + if let Some(wasm_target) = values.string_values.get(WASM_TARGET_KEY) { + if !self.check_target(wasm_target, attrs.metadata().level()) { + return id + } + } let span_datum = SpanDatum { - id, - name: attrs.metadata().name(), - target: attrs.metadata().target(), + id: id.clone(), + parent_id: attrs.parent().cloned().or_else(|| self.current_span.id()), + name: attrs.metadata().name().to_owned(), + target: attrs.metadata().target().to_owned(), level: attrs.metadata().level().clone(), line: attrs.metadata().line().unwrap_or(0), start_time: Instant::now(), - overall_time: Duration::from_nanos(0), + overall_time: ZERO_DURATION, values, }; - self.span_data.lock().insert(id, span_datum); - Id::from_u64(id) + self.span_data.lock().insert(id.clone(), span_datum); + id } - fn record(&self, _span: &Id, _values: &Record<'_>) {} + fn record(&self, span: &Id, values: &Record<'_>) { + let mut span_data = self.span_data.lock(); + if let Some(s) = span_data.get_mut(span) { + values.record(&mut s.values); + } + } fn record_follows_from(&self, _span: &Id, _follows: &Id) {} - fn event(&self, _event: &Event<'_>) {} + fn event(&self, event: &Event<'_>) { + let mut values = Values::default(); + event.record(&mut values); + let trace_event = TraceEvent { + name: event.metadata().name(), + target: event.metadata().target().to_owned(), + level: event.metadata().level().clone(), + values, + parent_id: event.parent().cloned().or_else(|| self.current_span.id()), + }; + self.trace_handler.handle_event(trace_event); + } fn enter(&self, span: &Id) { + self.current_span.enter(span.clone()); let mut span_data = self.span_data.lock(); let start_time = Instant::now(); - if let Some(mut s) = span_data.get_mut(&span.into_u64()) { + if let Some(mut s) = span_data.get_mut(&span) { s.start_time = start_time; - } else { - log::warn!("Tried to enter span {:?} that has already been closed!", span); } } fn exit(&self, span: &Id) { - let mut span_data = self.span_data.lock(); + self.current_span.exit(); let end_time = Instant::now(); - if let Some(mut s) = span_data.get_mut(&span.into_u64()) { + let mut span_data = self.span_data.lock(); + if let Some(mut s) = span_data.get_mut(&span) { s.overall_time = end_time - s.start_time + s.overall_time; } } fn try_close(&self, span: Id) -> bool { - let mut span_data = self.span_data.lock(); - if let Some(data) = span_data.remove(&span.into_u64()) { - self.send_span(data); + let span_datum = { + let mut span_data = self.span_data.lock(); + span_data.remove(&span) + }; + if let Some(mut span_datum) = span_datum { + if span_datum.name == WASM_TRACE_IDENTIFIER { + span_datum.values.bool_values.insert("wasm".to_owned(), true); + if let Some(n) = span_datum.values.string_values.remove(WASM_NAME_KEY) { + span_datum.name = n; + } + if let Some(t) = span_datum.values.string_values.remove(WASM_TARGET_KEY) { + span_datum.target = t; + } + if self.check_target(&span_datum.target, &span_datum.level) { + self.trace_handler.handle_span(span_datum); + } + } else { + self.trace_handler.handle_span(span_datum); + } }; true } } -impl ProfilingSubscriber { - fn send_span(&self, span_datum: SpanDatum) { - match self.receiver { - TracingReceiver::Log => print_log(span_datum), - TracingReceiver::Telemetry => send_telemetry(span_datum), +/// TraceHandler for sending span data to the logger +pub struct LogTraceHandler; + +fn log_level(level: Level) -> log::Level { + match level { + Level::TRACE => log::Level::Trace, + Level::DEBUG => log::Level::Debug, + Level::INFO => log::Level::Info, + Level::WARN => log::Level::Warn, + Level::ERROR => log::Level::Error, + } +} + +impl TraceHandler for LogTraceHandler { + fn handle_span(&self, span_datum: SpanDatum) { + if span_datum.values.is_empty() { + log::log!( + log_level(span_datum.level), + "{}: {}, time: {}, id: {}, parent_id: {:?}", + span_datum.target, + span_datum.name, + span_datum.overall_time.as_nanos(), + span_datum.id.into_u64(), + span_datum.parent_id.map(|s| s.into_u64()), + ); + } else { + log::log!( + log_level(span_datum.level), + "{}: {}, time: {}, id: {}, parent_id: {:?}, values: {}", + span_datum.target, + span_datum.name, + span_datum.overall_time.as_nanos(), + span_datum.id.into_u64(), + span_datum.parent_id.map(|s| s.into_u64()), + span_datum.values, + ); } } + + fn handle_event(&self, event: TraceEvent) { + log::log!( + log_level(event.level), + "{}, parent_id: {:?}, {}", + event.target, + event.parent_id.map(|s| s.into_u64()), + event.values, + ); + } } -fn print_log(span_datum: SpanDatum) { - if span_datum.values.0.is_empty() { - log::info!("TRACING: {} {}: {}, line: {}, time: {}", - span_datum.level, - span_datum.target, - span_datum.name, - span_datum.line, - span_datum.overall_time.as_nanos(), +/// TraceHandler for sending span data to telemetry, +/// Please see telemetry documentation for details on how to specify endpoints and +/// set the required telemetry level to activate tracing messages +pub struct TelemetryTraceHandler; + +impl TraceHandler for TelemetryTraceHandler { + fn handle_span(&self, span_datum: SpanDatum) { + telemetry!(SUBSTRATE_INFO; "tracing.profiling"; + "name" => span_datum.name, + "target" => span_datum.target, + "time" => span_datum.overall_time.as_nanos(), + "id" => span_datum.id.into_u64(), + "parent_id" => span_datum.parent_id.map(|i| i.into_u64()), + "values" => span_datum.values ); - } else { - log::info!("TRACING: {} {}: {}, line: {}, time: {}, {}", - span_datum.level, - span_datum.target, - span_datum.name, - span_datum.line, - span_datum.overall_time.as_nanos(), - span_datum.values + } + + fn handle_event(&self, event: TraceEvent) { + telemetry!(SUBSTRATE_INFO; "tracing.event"; + "name" => event.name, + "target" => event.target, + "parent_id" => event.parent_id.map(|i| i.into_u64()), + "values" => event.values ); } } -fn send_telemetry(span_datum: SpanDatum) { - telemetry!(SUBSTRATE_INFO; "tracing.profiling"; - "name" => span_datum.name, - "target" => span_datum.target, - "line" => span_datum.line, - "time" => span_datum.overall_time.as_nanos(), - "values" => span_datum.values - ); -} +#[cfg(test)] +mod tests { + use super::*; + use std::sync::Arc; + + struct TestTraceHandler { + spans: Arc>>, + events: Arc>>, + } + + impl TraceHandler for TestTraceHandler { + fn handle_span(&self, sd: SpanDatum) { + self.spans.lock().push(sd); + } + + fn handle_event(&self, event: TraceEvent) { + self.events.lock().push(event); + } + } + + fn setup_subscriber() -> (ProfilingSubscriber, Arc>>, Arc>>) { + let spans = Arc::new(Mutex::new(Vec::new())); + let events = Arc::new(Mutex::new(Vec::new())); + let handler = TestTraceHandler { + spans: spans.clone(), + events: events.clone(), + }; + let test_subscriber = ProfilingSubscriber::new_with_handler( + Box::new(handler), + "test_target" + ); + (test_subscriber, spans, events) + } + + #[test] + fn test_span() { + let (sub, spans, events) = setup_subscriber(); + let _sub_guard = tracing::subscriber::set_default(sub); + let span = tracing::info_span!(target: "test_target", "test_span1"); + assert_eq!(spans.lock().len(), 0); + assert_eq!(events.lock().len(), 0); + let _guard = span.enter(); + assert_eq!(spans.lock().len(), 0); + assert_eq!(events.lock().len(), 0); + drop(_guard); + drop(span); + assert_eq!(spans.lock().len(), 1); + assert_eq!(events.lock().len(), 0); + let sd = spans.lock().remove(0); + assert_eq!(sd.name, "test_span1"); + assert_eq!(sd.target, "test_target"); + let time: u128 = sd.overall_time.as_nanos(); + assert!(time > 0); + } + + #[test] + fn test_span_parent_id() { + let (sub, spans, _events) = setup_subscriber(); + let _sub_guard = tracing::subscriber::set_default(sub); + let span1 = tracing::info_span!(target: "test_target", "test_span1"); + let _guard1 = span1.enter(); + let span2 = tracing::info_span!(target: "test_target", "test_span2"); + let _guard2 = span2.enter(); + drop(_guard2); + drop(span2); + let sd2 = spans.lock().remove(0); + drop(_guard1); + drop(span1); + let sd1 = spans.lock().remove(0); + assert_eq!(sd1.id, sd2.parent_id.unwrap()) + } + + #[test] + fn test_span_values() { + let (sub, spans, _events) = setup_subscriber(); + let _sub_guard = tracing::subscriber::set_default(sub); + let test_bool = true; + let test_u64 = 1u64; + let test_i64 = 2i64; + let test_str = "test_str"; + let span = tracing::info_span!( + target: "test_target", + "test_span1", + test_bool, + test_u64, + test_i64, + test_str + ); + let _guard = span.enter(); + drop(_guard); + drop(span); + let sd = spans.lock().remove(0); + assert_eq!(sd.name, "test_span1"); + assert_eq!(sd.target, "test_target"); + let values = sd.values; + assert_eq!(values.bool_values.get("test_bool").unwrap(), &test_bool); + assert_eq!(values.u64_values.get("test_u64").unwrap(), &test_u64); + assert_eq!(values.i64_values.get("test_i64").unwrap(), &test_i64); + assert_eq!(values.string_values.get("test_str").unwrap(), &test_str.to_owned()); + } + + #[test] + fn test_event() { + let (sub, _spans, events) = setup_subscriber(); + let _sub_guard = tracing::subscriber::set_default(sub); + tracing::event!(target: "test_target", tracing::Level::INFO, "test_event"); + let mut te1 = events.lock().remove(0); + assert_eq!(te1.values.string_values.remove(&"message".to_owned()).unwrap(), "test_event".to_owned()); + } + + #[test] + fn test_event_parent_id() { + let (sub, spans, events) = setup_subscriber(); + let _sub_guard = tracing::subscriber::set_default(sub); + + // enter span + let span1 = tracing::info_span!(target: "test_target", "test_span1"); + let _guard1 = span1.enter(); + // emit event + tracing::event!(target: "test_target", tracing::Level::INFO, "test_event"); + + //exit span + drop(_guard1); + drop(span1); + + let sd1 = spans.lock().remove(0); + let te1 = events.lock().remove(0); + + assert_eq!(sd1.id, te1.parent_id.unwrap()); + } + + #[test] + fn test_parent_id_with_threads() { + use std::sync::mpsc; + use std::thread; + + let (sub, spans, events) = setup_subscriber(); + let _sub_guard = tracing::subscriber::set_global_default(sub); + let span1 = tracing::info_span!(target: "test_target", "test_span1"); + let _guard1 = span1.enter(); + + let (tx, rx) = mpsc::channel(); + let handle = thread::spawn(move || { + let span2 = tracing::info_span!(target: "test_target", "test_span2"); + let _guard2 = span2.enter(); + // emit event + tracing::event!(target: "test_target", tracing::Level::INFO, "test_event1"); + for msg in rx.recv() { + if msg == false { + break; + } + } + // gard2 and span2 dropped / exited + }); + + // wait for Event to be dispatched and stored + while events.lock().is_empty() { + thread::sleep(Duration::from_millis(1)); + } + + // emit new event (will be second item in Vec) while span2 still active in other thread + tracing::event!(target: "test_target", tracing::Level::INFO, "test_event2"); + + // stop thread and drop span + let _ = tx.send(false); + let _ = handle.join(); + + // wait for Span to be dispatched and stored + while spans.lock().is_empty() { + thread::sleep(Duration::from_millis(1)); + } + let span2 = spans.lock().remove(0); + let event1 = events.lock().remove(0); + drop(_guard1); + drop(span1); + + // emit event with no parent + tracing::event!(target: "test_target", tracing::Level::INFO, "test_event3"); + + let span1 = spans.lock().remove(0); + let event2 = events.lock().remove(0); + + assert_eq!(event1.values.string_values.get("message").unwrap(), "test_event1"); + assert_eq!(event2.values.string_values.get("message").unwrap(), "test_event2"); + assert!(span1.parent_id.is_none()); + assert!(span2.parent_id.is_none()); + assert_eq!(span2.id, event1.parent_id.unwrap()); + assert_eq!(span1.id, event2.parent_id.unwrap()); + assert_ne!(span2.id, span1.id); + + let event3 = events.lock().remove(0); + assert!(event3.parent_id.is_none()); + } +} diff --git a/client/transaction-pool/Cargo.toml b/client/transaction-pool/Cargo.toml index 6d4f69676c6308858ff30006d6136ab04abe16b5..f6ef1b1322f81ed3a931d9d0d487c461f74de19e 100644 --- a/client/transaction-pool/Cargo.toml +++ b/client/transaction-pool/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-transaction-pool" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Substrate transaction pool implementation." @@ -12,29 +12,31 @@ description = "Substrate transaction pool implementation." targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0" } +codec = { package = "parity-scale-codec", version = "1.3.4" } derive_more = "0.99.2" futures = { version = "0.3.1", features = ["compat"] } futures-diagnose = "1.0" intervalier = "0.4.0" log = "0.4.8" -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } parking_lot = "0.10.0" -prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-dev"} -sc-client-api = { version = "2.0.0-dev", path = "../api" } -sc-transaction-graph = { version = "2.0.0-dev", path = "./graph" } -sp-api = { version = "2.0.0-dev", path = "../../primitives/api" } -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", path = "../../primitives/runtime" } -sp-tracing = { version = "2.0.0-dev", path = "../../primitives/tracing" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../primitives/transaction-pool" } -sp-blockchain = { version = "2.0.0-dev", path = "../../primitives/blockchain" } -sp-utils = { version = "2.0.0-dev", path = "../../primitives/utils" } +prometheus-endpoint = { package = "substrate-prometheus-endpoint", path = "../../utils/prometheus", version = "0.8.0-rc6"} +sc-client-api = { version = "2.0.0-rc6", path = "../api" } +sc-transaction-graph = { version = "2.0.0-rc6", path = "./graph" } +sp-api = { version = "2.0.0-rc6", path = "../../primitives/api" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", path = "../../primitives/runtime" } +sp-tracing = { version = "2.0.0-rc6", path = "../../primitives/tracing" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../primitives/transaction-pool" } +sp-blockchain = { version = "2.0.0-rc6", path = "../../primitives/blockchain" } +sp-utils = { version = "2.0.0-rc6", path = "../../primitives/utils" } wasm-timer = "0.2" [dev-dependencies] assert_matches = "1.3.0" hex = "0.4" -sp-keyring = { version = "2.0.0-dev", path = "../../primitives/keyring" } -substrate-test-runtime-transaction-pool = { version = "2.0.0-dev", path = "../../test-utils/runtime/transaction-pool" } -substrate-test-runtime-client = { version = "2.0.0-dev", path = "../../test-utils/runtime/client" } +sp-keyring = { version = "2.0.0-rc6", path = "../../primitives/keyring" } +sp-consensus = { version = "0.8.0-rc6", path = "../../primitives/consensus/common" } +substrate-test-runtime-transaction-pool = { version = "2.0.0-rc6", path = "../../test-utils/runtime/transaction-pool" } +substrate-test-runtime-client = { version = "2.0.0-rc6", path = "../../test-utils/runtime/client" } +sc-block-builder = { version = "0.8.0-rc6", path = "../block-builder" } diff --git a/client/transaction-pool/README.md b/client/transaction-pool/README.md new file mode 100644 index 0000000000000000000000000000000000000000..15e4641c1f48d9d2c245e2e373620411669efdba --- /dev/null +++ b/client/transaction-pool/README.md @@ -0,0 +1,3 @@ +Substrate transaction pool implementation. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/transaction-pool/graph/Cargo.toml b/client/transaction-pool/graph/Cargo.toml index 842d54f920a71acc70ef31ce2fa2d474099808a7..7255cf3df30da4bd294fa97b797886ce3a02793e 100644 --- a/client/transaction-pool/graph/Cargo.toml +++ b/client/transaction-pool/graph/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "sc-transaction-graph" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Generic Transaction Pool" @@ -18,18 +18,19 @@ log = "0.4.8" parking_lot = "0.10.0" serde = { version = "1.0.101", features = ["derive"] } wasm-timer = "0.2" -sp-blockchain = { version = "2.0.0-dev", path = "../../../primitives/blockchain" } -sp-utils = { version = "2.0.0-dev", path = "../../../primitives/utils" } -sp-core = { version = "2.0.0-dev", path = "../../../primitives/core" } -sp-runtime = { version = "2.0.0-dev", path = "../../../primitives/runtime" } -sp-transaction-pool = { version = "2.0.0-dev", path = "../../../primitives/transaction-pool" } -parity-util-mem = { version = "0.6.1", default-features = false, features = ["primitive-types"] } +sp-blockchain = { version = "2.0.0-rc6", path = "../../../primitives/blockchain" } +sp-utils = { version = "2.0.0-rc6", path = "../../../primitives/utils" } +sp-core = { version = "2.0.0-rc6", path = "../../../primitives/core" } +sp-runtime = { version = "2.0.0-rc6", path = "../../../primitives/runtime" } +sp-transaction-pool = { version = "2.0.0-rc6", path = "../../../primitives/transaction-pool" } +parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] } linked-hash-map = "0.5.2" +retain_mut = "0.1.1" [dev-dependencies] assert_matches = "1.3.0" -codec = { package = "parity-scale-codec", version = "1.3.0" } -substrate-test-runtime = { version = "2.0.0-dev", path = "../../../test-utils/runtime" } +codec = { package = "parity-scale-codec", version = "1.3.4" } +substrate-test-runtime = { version = "2.0.0-rc6", path = "../../../test-utils/runtime" } criterion = "0.3" [[bench]] diff --git a/client/transaction-pool/graph/README.md b/client/transaction-pool/graph/README.md new file mode 100644 index 0000000000000000000000000000000000000000..bc9cd929122f16d88af886f13ac8aa9c37bc460c --- /dev/null +++ b/client/transaction-pool/graph/README.md @@ -0,0 +1,8 @@ +Generic Transaction Pool + +The pool is based on dependency graph between transactions +and their priority. +The pool is able to return an iterator that traverses transaction +graph in the correct order taking into account priorities and dependencies. + +License: GPL-3.0-or-later WITH Classpath-exception-2.0 \ No newline at end of file diff --git a/client/transaction-pool/graph/benches/basics.rs b/client/transaction-pool/graph/benches/basics.rs index 23b4dba3488061429a39c04bcd717b55ee007c78..bb10086bd4a558330d8d36e4bf3b92d791fdcae4 100644 --- a/client/transaction-pool/graph/benches/basics.rs +++ b/client/transaction-pool/graph/benches/basics.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use criterion::{criterion_group, criterion_main, Criterion}; @@ -49,7 +51,6 @@ fn to_tag(nonce: u64, from: AccountId) -> Tag { impl ChainApi for TestApi { type Block = Block; - type Hash = H256; type Error = sp_transaction_pool::error::Error; type ValidationFuture = Ready>; type BodyFuture = Ready>>>; @@ -105,7 +106,7 @@ impl ChainApi for TestApi { }) } - fn hash_and_length(&self, uxt: &ExtrinsicFor) -> (Self::Hash, usize) { + fn hash_and_length(&self, uxt: &ExtrinsicFor) -> (H256, usize) { let encoded = uxt.encode(); (blake2_256(&encoded).into(), encoded.len()) } diff --git a/client/transaction-pool/graph/src/base_pool.rs b/client/transaction-pool/graph/src/base_pool.rs index 38151e9bfd23b87b3fd4511022eaa7f9953ab46a..81d8e802c2c9eb536d16f0ad2f192e645d674e78 100644 --- a/client/transaction-pool/graph/src/base_pool.rs +++ b/client/transaction-pool/graph/src/base_pool.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! A basic version of the dependency graph. //! @@ -259,6 +261,11 @@ impl BasePool bool { + self.future.contains(tx_hash) || self.ready.contains(tx_hash) + } + /// Imports transaction to the pool. /// /// The pool consists of two parts: Future and Ready. @@ -270,8 +277,8 @@ impl BasePool, ) -> error::Result> { - if self.future.contains(&tx.hash) || self.ready.contains(&tx.hash) { - return Err(error::Error::AlreadyImported(Box::new(tx.hash.clone()))) + if self.is_imported(&tx.hash) { + return Err(error::Error::AlreadyImported(Box::new(tx.hash))) } let tx = WaitingTransaction::new( diff --git a/client/transaction-pool/graph/src/error.rs b/client/transaction-pool/graph/src/error.rs index 6fd7748e369aba3508251c04f976a49a0214b312..392ddaa39be6f2d809792985b283cf5630d09792 100644 --- a/client/transaction-pool/graph/src/error.rs +++ b/client/transaction-pool/graph/src/error.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Transaction pool errors. diff --git a/client/transaction-pool/graph/src/future.rs b/client/transaction-pool/graph/src/future.rs index 76181c837f988586d72ebd3568b4c31a35ac6b8d..80e6825d4ff9d3097f485d8fe86ca388ef0a3197 100644 --- a/client/transaction-pool/graph/src/future.rs +++ b/client/transaction-pool/graph/src/future.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{ collections::{HashMap, HashSet}, diff --git a/client/transaction-pool/graph/src/lib.rs b/client/transaction-pool/graph/src/lib.rs index ed10ef38d2bfd868eda7504b74bbe3018dee0c6f..bf220ce22973a97190ad7a0d5da2ba50e9e0acd6 100644 --- a/client/transaction-pool/graph/src/lib.rs +++ b/client/transaction-pool/graph/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Generic Transaction Pool //! @@ -30,14 +32,13 @@ mod pool; mod ready; mod rotator; mod validated_pool; +mod tracked_map; pub mod base_pool; pub mod watcher; pub use self::base_pool::Transaction; pub use self::pool::{ - Pool, - Options, ChainApi, EventStream, ExtrinsicFor, - BlockHash, ExHash, NumberFor, TransactionFor, - ValidatedTransaction, + Pool, Options, ChainApi, EventStream, ExtrinsicFor, ExtrinsicHash, + BlockHash, NumberFor, TransactionFor, ValidatedTransaction, }; diff --git a/client/transaction-pool/graph/src/listener.rs b/client/transaction-pool/graph/src/listener.rs index 602c75e09981460cc50f8ec2f0a9021bbc0863dc..1bc3720fa6b85e8eea21b75d1a15bffd9f210758 100644 --- a/client/transaction-pool/graph/src/listener.rs +++ b/client/transaction-pool/graph/src/listener.rs @@ -1,39 +1,41 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{ - collections::HashMap, hash, + collections::HashMap, hash, fmt::Debug, }; use linked_hash_map::LinkedHashMap; use serde::Serialize; -use crate::{watcher, ChainApi, BlockHash}; +use crate::{watcher, ChainApi, ExtrinsicHash, BlockHash}; use log::{debug, trace, warn}; use sp_runtime::traits; /// Extrinsic pool default listener. pub struct Listener { - watchers: HashMap>>, - finality_watchers: LinkedHashMap, Vec>, + watchers: HashMap>>, + finality_watchers: LinkedHashMap, Vec>, } /// Maximum number of blocks awaiting finality at any time. const MAX_FINALITY_WATCHERS: usize = 512; -impl Default for Listener { +impl Default for Listener { fn default() -> Self { Listener { watchers: Default::default(), @@ -43,7 +45,7 @@ impl Default for Listener { } impl Listener { - fn fire(&mut self, hash: &H, fun: F) where F: FnOnce(&mut watcher::Sender>) { + fn fire(&mut self, hash: &H, fun: F) where F: FnOnce(&mut watcher::Sender>) { let clean = if let Some(h) = self.watchers.get_mut(hash) { fun(h); h.is_done() @@ -59,7 +61,7 @@ impl Listener { /// Creates a new watcher for given verified extrinsic. /// /// The watcher can be used to subscribe to life-cycle events of that extrinsic. - pub fn create_watcher(&mut self, hash: H) -> watcher::Watcher> { + pub fn create_watcher(&mut self, hash: H) -> watcher::Watcher> { let sender = self.watchers.entry(hash.clone()).or_insert_with(watcher::Sender::default); sender.new_watcher(hash) } @@ -72,7 +74,7 @@ impl Listener { /// New transaction was added to the ready pool or promoted from the future pool. pub fn ready(&mut self, tx: &H, old: Option<&H>) { - trace!(target: "txpool", "[{:?}] Ready (replaced: {:?})", tx, old); + trace!(target: "txpool", "[{:?}] Ready (replaced with {:?})", tx, old); self.fire(tx, |watcher| watcher.ready()); if let Some(old) = old { self.fire(old, |watcher| watcher.usurped(tx.clone())); @@ -87,7 +89,7 @@ impl Listener { /// Transaction was dropped from the pool because of the limit. pub fn dropped(&mut self, tx: &H, by: Option<&H>) { - trace!(target: "txpool", "[{:?}] Dropped (replaced by {:?})", tx, by); + trace!(target: "txpool", "[{:?}] Dropped (replaced with {:?})", tx, by); self.fire(tx, |watcher| match by { Some(t) => watcher.usurped(t.clone()), None => watcher.dropped(), @@ -97,9 +99,9 @@ impl Listener { /// Transaction was removed as invalid. pub fn invalid(&mut self, tx: &H, warn: bool) { if warn { - warn!(target: "txpool", "Extrinsic invalid: {:?}", tx); + warn!(target: "txpool", "[{:?}] Extrinsic invalid", tx); } else { - debug!(target: "txpool", "Extrinsic invalid: {:?}", tx); + debug!(target: "txpool", "[{:?}] Extrinsic invalid", tx); } self.fire(tx, |watcher| watcher.invalid()); } @@ -132,6 +134,7 @@ impl Listener { pub fn finalized(&mut self, block_hash: BlockHash) { if let Some(hashes) = self.finality_watchers.remove(&block_hash) { for hash in hashes { + log::debug!(target: "txpool", "[{:?}] Sent finalization event (block {:?})", hash, block_hash); self.fire(&hash, |s| s.finalized(block_hash)) } } diff --git a/client/transaction-pool/graph/src/pool.rs b/client/transaction-pool/graph/src/pool.rs index 0b817b155d8ecaef12aee3461e0e475d20b15a86..56ff550d7754f67abf170a92d1ab164b75f7d6b8 100644 --- a/client/transaction-pool/graph/src/pool.rs +++ b/client/transaction-pool/graph/src/pool.rs @@ -1,60 +1,59 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{ - hash, collections::HashMap, sync::Arc, }; -use crate::base_pool as base; -use crate::watcher::Watcher; -use serde::Serialize; +use crate::{base_pool as base, watcher::Watcher}; -use futures::{Future, FutureExt}; +use futures::Future; use sp_runtime::{ generic::BlockId, - traits::{self, SaturatedConversion}, + traits::{self, SaturatedConversion, Block as BlockT}, transaction_validity::{ TransactionValidity, TransactionTag as Tag, TransactionValidityError, TransactionSource, }, }; use sp_transaction_pool::error; use wasm_timer::Instant; -use sp_utils::mpsc::TracingUnboundedReceiver; +use futures::channel::mpsc::Receiver; use crate::validated_pool::ValidatedPool; pub use crate::validated_pool::ValidatedTransaction; /// Modification notification event stream type; -pub type EventStream = TracingUnboundedReceiver; +pub type EventStream = Receiver; -/// Extrinsic hash type for a pool. -pub type ExHash = ::Hash; /// Block hash type for a pool. pub type BlockHash = <::Block as traits::Block>::Hash; +/// Extrinsic hash type for a pool. +pub type ExtrinsicHash = <::Block as traits::Block>::Hash; /// Extrinsic type for a pool. pub type ExtrinsicFor = <::Block as traits::Block>::Extrinsic; /// Block number type for the ChainApi pub type NumberFor = traits::NumberFor<::Block>; /// A type of transaction stored in the pool -pub type TransactionFor = Arc, ExtrinsicFor>>; +pub type TransactionFor = Arc, ExtrinsicFor>>; /// A type of validated transaction stored in the pool. pub type ValidatedTransactionFor = ValidatedTransaction< - ExHash, + ExtrinsicHash, ExtrinsicFor, ::Error, >; @@ -62,15 +61,15 @@ pub type ValidatedTransactionFor = ValidatedTransaction< /// Concrete extrinsic validation and query logic. pub trait ChainApi: Send + Sync { /// Block type. - type Block: traits::Block; - /// Transaction Hash type - type Hash: hash::Hash + Eq + traits::Member + Serialize; + type Block: BlockT; /// Error type. type Error: From + error::IntoPoolError; /// Validate transaction future. type ValidationFuture: Future> + Send + Unpin; /// Body future (since block body might be remote) - type BodyFuture: Future::Extrinsic>>, Self::Error>> + Unpin + Send + 'static; + type BodyFuture: Future< + Output = Result::Extrinsic>>, Self::Error> + > + Unpin + Send + 'static; /// Verify extrinsic at given block. fn validate_transaction( @@ -81,13 +80,19 @@ pub trait ChainApi: Send + Sync { ) -> Self::ValidationFuture; /// Returns a block number given the block id. - fn block_id_to_number(&self, at: &BlockId) -> Result>, Self::Error>; + fn block_id_to_number( + &self, + at: &BlockId, + ) -> Result>, Self::Error>; /// Returns a block hash given the block id. - fn block_id_to_hash(&self, at: &BlockId) -> Result>, Self::Error>; + fn block_id_to_hash( + &self, + at: &BlockId, + ) -> Result::Hash>, Self::Error>; /// Returns hash and encoding length of the extrinsic. - fn hash_and_length(&self, uxt: &ExtrinsicFor) -> (Self::Hash, usize); + fn hash_and_length(&self, uxt: &ExtrinsicFor) -> (ExtrinsicHash, usize); /// Returns a block body given the block id. fn block_body(&self, at: &BlockId) -> Self::BodyFuture; @@ -120,6 +125,14 @@ impl Default for Options { } } +/// Should we check that the transaction is banned +/// in the pool, before we verify it? +#[derive(Copy, Clone)] +enum CheckBannedBeforeVerify { + Yes, + No, +} + /// Extrinsics pool that performs validation. pub struct Pool { validated_pool: Arc>, @@ -128,7 +141,6 @@ pub struct Pool { #[cfg(not(target_os = "unknown"))] impl parity_util_mem::MallocSizeOf for Pool where - B::Hash: parity_util_mem::MallocSizeOf, ExtrinsicFor: parity_util_mem::MallocSizeOf, { fn size_of(&self, ops: &mut parity_util_mem::MallocSizeOfOps) -> usize { @@ -145,23 +157,29 @@ impl Pool { } /// Imports a bunch of unverified extrinsics to the pool - pub async fn submit_at( + pub async fn submit_at( + &self, + at: &BlockId, + source: TransactionSource, + xts: impl IntoIterator>, + ) -> Result, B::Error>>, B::Error> { + let xts = xts.into_iter().map(|xt| (source, xt)); + let validated_transactions = self.verify(at, xts, CheckBannedBeforeVerify::Yes).await?; + Ok(self.validated_pool.submit(validated_transactions.into_iter().map(|(_, tx)| tx))) + } + + /// Resubmit the given extrinsics to the pool. + /// + /// This does not check if a transaction is banned, before we verify it again. + pub async fn resubmit_at( &self, at: &BlockId, source: TransactionSource, - xts: T, - force: bool, - ) -> Result, B::Error>>, B::Error> where - T: IntoIterator>, - { - let validated_pool = self.validated_pool.clone(); + xts: impl IntoIterator>, + ) -> Result, B::Error>>, B::Error> { let xts = xts.into_iter().map(|xt| (source, xt)); - self.verify(at, xts, force) - .map(move |validated_transactions| validated_transactions - .map(|validated_transactions| validated_pool.submit(validated_transactions - .into_iter() - .map(|(_, tx)| tx)))) - .await + let validated_transactions = self.verify(at, xts, CheckBannedBeforeVerify::No).await?; + Ok(self.validated_pool.submit(validated_transactions.into_iter().map(|(_, tx)| tx))) } /// Imports one unverified extrinsic to the pool @@ -170,13 +188,9 @@ impl Pool { at: &BlockId, source: TransactionSource, xt: ExtrinsicFor, - ) -> Result, B::Error> { - self.submit_at(at, source, std::iter::once(xt), false) - .map(|import_result| import_result.and_then(|mut import_result| import_result - .pop() - .expect("One extrinsic passed; one result returned; qed") - )) - .await + ) -> Result, B::Error> { + let res = self.submit_at(at, source, std::iter::once(xt)).await?.pop(); + res.expect("One extrinsic passed; one result returned; qed") } /// Import a single extrinsic and starts to watch their progress in the pool. @@ -185,10 +199,14 @@ impl Pool { at: &BlockId, source: TransactionSource, xt: ExtrinsicFor, - ) -> Result, BlockHash>, B::Error> { + ) -> Result, ExtrinsicHash>, B::Error> { let block_number = self.resolve_block_number(at)?; let (_, tx) = self.verify_one( - at, block_number, source, xt, false + at, + block_number, + source, + xt, + CheckBannedBeforeVerify::Yes, ).await; self.validated_pool.submit_and_watch(tx) } @@ -196,7 +214,7 @@ impl Pool { /// Resubmit some transaction that were validated elsewhere. pub fn resubmit( &self, - revalidated_transactions: HashMap, ValidatedTransactionFor>, + revalidated_transactions: HashMap, ValidatedTransactionFor>, ) { let now = Instant::now(); @@ -213,7 +231,11 @@ impl Pool { /// Used to clear the pool from transactions that were part of recently imported block. /// The main difference from the `prune` is that we do not revalidate any transactions /// and ignore unknown passed hashes. - pub fn prune_known(&self, at: &BlockId, hashes: &[ExHash]) -> Result<(), B::Error> { + pub fn prune_known( + &self, + at: &BlockId, + hashes: &[ExtrinsicHash], + ) -> Result<(), B::Error> { // Get details of all extrinsics that are already in the pool let in_pool_tags = self.validated_pool.extrinsics_tags(hashes) .into_iter().filter_map(|x| x).flat_map(|x| x); @@ -297,7 +319,7 @@ impl Pool { &self, at: &BlockId, tags: impl IntoIterator, - known_imported_hashes: impl IntoIterator> + Clone, + known_imported_hashes: impl IntoIterator> + Clone, ) -> Result<(), B::Error> { log::debug!(target: "txpool", "Pruning at {:?}", at); // Prune all transactions that provide given tags @@ -320,7 +342,11 @@ impl Pool { .into_iter() .map(|tx| (tx.source, tx.data.clone())); - let reverified_transactions = self.verify(at, pruned_transactions, false).await?; + let reverified_transactions = self.verify( + at, + pruned_transactions, + CheckBannedBeforeVerify::Yes, + ).await?; log::trace!(target: "txpool", "Pruning at {:?}. Resubmitting transactions.", at); // And finally - submit reverified transactions back to the pool @@ -334,7 +360,7 @@ impl Pool { } /// Returns transaction hash - pub fn hash_of(&self, xt: &ExtrinsicFor) -> ExHash { + pub fn hash_of(&self, xt: &ExtrinsicFor) -> ExtrinsicHash { self.validated_pool.api().hash_and_length(xt).0 } @@ -350,23 +376,17 @@ impl Pool { &self, at: &BlockId, xts: impl IntoIterator)>, - force: bool, - ) -> Result, ValidatedTransactionFor>, B::Error> { + check: CheckBannedBeforeVerify, + ) -> Result, ValidatedTransactionFor>, B::Error> { // we need a block number to compute tx validity let block_number = self.resolve_block_number(at)?; - let mut result = HashMap::new(); - - for (hash, validated_tx) in - futures::future::join_all( - xts.into_iter() - .map(|(source, xt)| self.verify_one(at, block_number, source, xt, force)) - ) - .await - { - result.insert(hash, validated_tx); - } - Ok(result) + let res = futures::future::join_all( + xts.into_iter() + .map(|(source, xt)| self.verify_one(at, block_number, source, xt, check)) + ).await.into_iter().collect::>(); + + Ok(res) } /// Returns future that validates single transaction at given block. @@ -376,14 +396,13 @@ impl Pool { block_number: NumberFor, source: TransactionSource, xt: ExtrinsicFor, - force: bool, - ) -> (ExHash, ValidatedTransactionFor) { + check: CheckBannedBeforeVerify, + ) -> (ExtrinsicHash, ValidatedTransactionFor) { let (hash, bytes) = self.validated_pool.api().hash_and_length(&xt); - if !force && self.validated_pool.is_banned(&hash) { - return ( - hash.clone(), - ValidatedTransaction::Invalid(hash, error::Error::TemporarilyBanned.into()), - ) + + let ignore_banned = matches!(check, CheckBannedBeforeVerify::No); + if let Err(err) = self.validated_pool.check_is_known(&hash, ignore_banned) { + return (hash.clone(), ValidatedTransaction::Invalid(hash, err.into())) } let validation_result = self.validated_pool.api().validate_transaction( @@ -442,9 +461,12 @@ mod tests { use futures::executor::block_on; use super::*; use sp_transaction_pool::TransactionStatus; - use sp_runtime::transaction_validity::{ValidTransaction, InvalidTransaction, TransactionSource}; + use sp_runtime::{ + traits::Hash, + transaction_validity::{ValidTransaction, InvalidTransaction, TransactionSource}, + }; use codec::Encode; - use substrate_test_runtime::{Block, Extrinsic, Transfer, H256, AccountId}; + use substrate_test_runtime::{Block, Extrinsic, Transfer, H256, AccountId, Hashing}; use assert_matches::assert_matches; use wasm_timer::Instant; use crate::base_pool::Limit; @@ -455,14 +477,13 @@ mod tests { #[derive(Clone, Debug, Default)] struct TestApi { delay: Arc>>>, - invalidate: Arc>>, - clear_requirements: Arc>>, - add_requirements: Arc>>, + invalidate: Arc>>, + clear_requirements: Arc>>, + add_requirements: Arc>>, } impl ChainApi for TestApi { type Block = Block; - type Hash = u64; type Error = error::Error; type ValidationFuture = futures::future::Ready>; type BodyFuture = futures::future::Ready>>>; @@ -516,7 +537,10 @@ mod tests { } /// Returns a block number given the block id. - fn block_id_to_number(&self, at: &BlockId) -> Result>, Self::Error> { + fn block_id_to_number( + &self, + at: &BlockId, + ) -> Result>, Self::Error> { Ok(match at { BlockId::Number(num) => Some(*num), BlockId::Hash(_) => None, @@ -524,7 +548,10 @@ mod tests { } /// Returns a block hash given the block id. - fn block_id_to_hash(&self, at: &BlockId) -> Result>, Self::Error> { + fn block_id_to_hash( + &self, + at: &BlockId, + ) -> Result::Hash>, Self::Error> { Ok(match at { BlockId::Number(num) => Some(H256::from_low_u64_be(*num)).into(), BlockId::Hash(_) => None, @@ -532,12 +559,10 @@ mod tests { } /// Hash the extrinsic. - fn hash_and_length(&self, uxt: &ExtrinsicFor) -> (Self::Hash, usize) { - let len = uxt.encode().len(); - ( - (H256::from(uxt.transfer().from.clone()).to_low_u64_be() << 5) + uxt.transfer().nonce, - len - ) + fn hash_and_length(&self, uxt: &ExtrinsicFor) -> (BlockHash, usize) { + let encoded = uxt.encode(); + let len = encoded.len(); + (Hashing::hash(&encoded), len) } fn block_body(&self, _id: &BlockId) -> Self::BodyFuture { @@ -597,19 +622,19 @@ mod tests { #[test] fn should_notify_about_pool_events() { - let stream = { + let (stream, hash0, hash1) = { // given let pool = pool(); let stream = pool.validated_pool().import_notification_stream(); // when - let _hash = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { + let hash0 = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, nonce: 0, }))).unwrap(); - let _hash = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { + let hash1 = block_on(pool.submit_one(&BlockId::Number(0), SOURCE, uxt(Transfer { from: AccountId::from_h256(H256::from_low_u64_be(1)), to: AccountId::from_h256(H256::from_low_u64_be(2)), amount: 5, @@ -625,13 +650,14 @@ mod tests { assert_eq!(pool.validated_pool().status().ready, 2); assert_eq!(pool.validated_pool().status().future, 1); - stream + + (stream, hash0, hash1) }; // then let mut it = futures::executor::block_on_stream(stream); - assert_eq!(it.next(), Some(32)); - assert_eq!(it.next(), Some(33)); + assert_eq!(it.next(), Some(hash0)); + assert_eq!(it.next(), Some(hash1)); assert_eq!(it.next(), None); } @@ -793,7 +819,10 @@ mod tests { // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); assert_eq!(stream.next(), Some(TransactionStatus::Ready)); - assert_eq!(stream.next(), Some(TransactionStatus::InBlock(H256::from_low_u64_be(2).into()))); + assert_eq!( + stream.next(), + Some(TransactionStatus::InBlock(H256::from_low_u64_be(2).into())), + ); } #[test] @@ -810,14 +839,19 @@ mod tests { assert_eq!(pool.validated_pool().status().future, 0); // when - block_on(pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![2u64])).unwrap(); + block_on( + pool.prune_tags(&BlockId::Number(2), vec![vec![0u8]], vec![watcher.hash().clone()]), + ).unwrap(); assert_eq!(pool.validated_pool().status().ready, 0); assert_eq!(pool.validated_pool().status().future, 0); // then let mut stream = futures::executor::block_on_stream(watcher.into_stream()); assert_eq!(stream.next(), Some(TransactionStatus::Ready)); - assert_eq!(stream.next(), Some(TransactionStatus::InBlock(H256::from_low_u64_be(2).into()))); + assert_eq!( + stream.next(), + Some(TransactionStatus::InBlock(H256::from_low_u64_be(2).into())), + ); } #[test] diff --git a/client/transaction-pool/graph/src/ready.rs b/client/transaction-pool/graph/src/ready.rs index c856535a6165140844a339d0539aa291236a561f..cbdb25078931ef33a701b8db635ae516f580c594 100644 --- a/client/transaction-pool/graph/src/ready.rs +++ b/client/transaction-pool/graph/src/ready.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{ collections::{HashMap, HashSet, BTreeSet}, @@ -23,15 +25,17 @@ use std::{ use serde::Serialize; use log::trace; -use parking_lot::RwLock; use sp_runtime::traits::Member; use sp_runtime::transaction_validity::{ TransactionTag as Tag, }; use sp_transaction_pool::error; -use crate::future::WaitingTransaction; -use crate::base_pool::Transaction; +use crate::{ + base_pool::Transaction, + future::WaitingTransaction, + tracked_map::{self, ReadOnlyTrackedMap, TrackedMap}, +}; /// An in-pool transaction reference. /// @@ -111,11 +115,17 @@ pub struct ReadyTransactions { /// tags that are provided by Ready transactions provided_tags: HashMap, /// Transactions that are ready (i.e. don't have any requirements external to the pool) - ready: Arc>>>, + ready: TrackedMap>, /// Best transactions that are ready to be included to the block without any other previous transaction. best: BTreeSet>, } +impl tracked_map::Size for ReadyTx { + fn size(&self) -> usize { + self.transaction.transaction.bytes + } +} + impl Default for ReadyTransactions { fn default() -> Self { ReadyTransactions { @@ -265,12 +275,7 @@ impl ReadyTransactions { ) -> Vec>> { let mut removed = vec![]; let mut ready = self.ready.write(); - loop { - let hash = match to_remove.pop() { - Some(hash) => hash, - None => return removed, - }; - + while let Some(hash) = to_remove.pop() { if let Some(mut tx) = ready.remove(&hash) { let invalidated = tx.transaction.transaction.provides .iter() @@ -309,6 +314,8 @@ impl ReadyTransactions { removed.push(tx.transaction.transaction); } } + + removed } /// Removes transactions that provide given tag. @@ -320,17 +327,16 @@ impl ReadyTransactions { let mut removed = vec![]; let mut to_remove = vec![tag]; - loop { - let tag = match to_remove.pop() { - Some(tag) => tag, - None => return removed, - }; - + while let Some(tag) = to_remove.pop() { let res = self.provided_tags.remove(&tag) - .and_then(|hash| self.ready.write().remove(&hash)); + .and_then(|hash| self.ready.write().remove(&hash)); if let Some(tx) = res { let unlocks = tx.unlocks; + + // Make sure we remove it from best txs + self.best.remove(&tx.transaction); + let tx = tx.transaction.transaction; // prune previous transactions as well @@ -393,6 +399,8 @@ impl ReadyTransactions { removed.push(tx); } } + + removed } /// Checks if the transaction is providing the same tags as other transactions. @@ -466,18 +474,18 @@ impl ReadyTransactions { /// Returns number of transactions in this queue. pub fn len(&self) -> usize { - self.ready.read().len() + self.ready.len() } /// Returns sum of encoding lengths of all transactions in this queue. pub fn bytes(&self) -> usize { - self.ready.read().values().fold(0, |acc, tx| acc + tx.transaction.transaction.bytes) + self.ready.bytes() } } /// Iterator of ready transactions ordered by priority. pub struct BestIterator { - all: Arc>>>, + all: ReadOnlyTrackedMap>, awaiting: HashMap)>, best: BTreeSet>, } @@ -530,7 +538,7 @@ impl Iterator for BestIterator { } } - return Some(best.transaction.clone()) + return Some(best.transaction) } } } diff --git a/client/transaction-pool/graph/src/rotator.rs b/client/transaction-pool/graph/src/rotator.rs index be96174d1d91696832201bae8d9c6db4d1d0769f..65e21d0d4b5068262a6caf00add896ab51f4a710 100644 --- a/client/transaction-pool/graph/src/rotator.rs +++ b/client/transaction-pool/graph/src/rotator.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Rotate extrinsic inside the pool. //! diff --git a/client/transaction-pool/graph/src/tracked_map.rs b/client/transaction-pool/graph/src/tracked_map.rs new file mode 100644 index 0000000000000000000000000000000000000000..c799eb0b96ea146b16951d3822502a55940b763b --- /dev/null +++ b/client/transaction-pool/graph/src/tracked_map.rs @@ -0,0 +1,189 @@ +// This file is part of Substrate. + +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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 . + +use std::{ + collections::HashMap, + sync::{Arc, atomic::{AtomicIsize, Ordering as AtomicOrdering}}, +}; +use parking_lot::{RwLock, RwLockWriteGuard, RwLockReadGuard}; + +/// Something that can report it's size. +pub trait Size { + fn size(&self) -> usize; +} + +/// Map with size tracking. +/// +/// Size reported might be slightly off and only approximately true. +#[derive(Debug, parity_util_mem::MallocSizeOf)] +pub struct TrackedMap { + index: Arc>>, + bytes: AtomicIsize, + length: AtomicIsize, +} + +impl Default for TrackedMap { + fn default() -> Self { + Self { + index: Arc::new(HashMap::default().into()), + bytes: 0.into(), + length: 0.into(), + } + } +} + +impl TrackedMap { + /// Current tracked length of the content. + pub fn len(&self) -> usize { + std::cmp::max(self.length.load(AtomicOrdering::Relaxed), 0) as usize + } + + /// Current sum of content length. + pub fn bytes(&self) -> usize { + std::cmp::max(self.bytes.load(AtomicOrdering::Relaxed), 0) as usize + } + + /// Read-only clone of the interior. + pub fn clone(&self) -> ReadOnlyTrackedMap { + ReadOnlyTrackedMap(self.index.clone()) + } + + /// Lock map for read. + pub fn read<'a>(&'a self) -> TrackedMapReadAccess<'a, K, V> { + TrackedMapReadAccess { + inner_guard: self.index.read(), + } + } + + /// Lock map for write. + pub fn write<'a>(&'a self) -> TrackedMapWriteAccess<'a, K, V> { + TrackedMapWriteAccess { + inner_guard: self.index.write(), + bytes: &self.bytes, + length: &self.length, + } + } +} + +/// Read-only access to map. +/// +/// The only thing can be done is .read(). +pub struct ReadOnlyTrackedMap(Arc>>); + +impl ReadOnlyTrackedMap +where + K: Eq + std::hash::Hash +{ + /// Lock map for read. + pub fn read<'a>(&'a self) -> TrackedMapReadAccess<'a, K, V> { + TrackedMapReadAccess { + inner_guard: self.0.read(), + } + } +} + +pub struct TrackedMapReadAccess<'a, K, V> { + inner_guard: RwLockReadGuard<'a, HashMap>, +} + +impl<'a, K, V> TrackedMapReadAccess<'a, K, V> +where + K: Eq + std::hash::Hash +{ + /// Returns true if map contains key. + pub fn contains_key(&self, key: &K) -> bool { + self.inner_guard.contains_key(key) + } + + /// Returns reference to the contained value by key, if exists. + pub fn get(&self, key: &K) -> Option<&V> { + self.inner_guard.get(key) + } + + /// Returns iterator over all values. + pub fn values(&self) -> std::collections::hash_map::Values { + self.inner_guard.values() + } +} + +pub struct TrackedMapWriteAccess<'a, K, V> { + bytes: &'a AtomicIsize, + length: &'a AtomicIsize, + inner_guard: RwLockWriteGuard<'a, HashMap>, +} + +impl<'a, K, V> TrackedMapWriteAccess<'a, K, V> +where + K: Eq + std::hash::Hash, V: Size +{ + /// Insert value and return previous (if any). + pub fn insert(&mut self, key: K, val: V) -> Option { + let new_bytes = val.size(); + self.bytes.fetch_add(new_bytes as isize, AtomicOrdering::Relaxed); + self.length.fetch_add(1, AtomicOrdering::Relaxed); + self.inner_guard.insert(key, val).and_then(|old_val| { + self.bytes.fetch_sub(old_val.size() as isize, AtomicOrdering::Relaxed); + self.length.fetch_sub(1, AtomicOrdering::Relaxed); + Some(old_val) + }) + } + + /// Remove value by key. + pub fn remove(&mut self, key: &K) -> Option { + let val = self.inner_guard.remove(key); + if let Some(size) = val.as_ref().map(Size::size) { + self.bytes.fetch_sub(size as isize, AtomicOrdering::Relaxed); + self.length.fetch_sub(1, AtomicOrdering::Relaxed); + } + val + } + + /// Returns mutable reference to the contained value by key, if exists. + pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { + self.inner_guard.get_mut(key) + } +} + +#[cfg(test)] +mod tests { + + use super::*; + + impl Size for i32 { + fn size(&self) -> usize { *self as usize / 10 } + } + + #[test] + fn basic() { + let map = TrackedMap::default(); + map.write().insert(5, 10); + map.write().insert(6, 20); + + assert_eq!(map.bytes(), 3); + assert_eq!(map.len(), 2); + + map.write().insert(6, 30); + + assert_eq!(map.bytes(), 4); + assert_eq!(map.len(), 2); + + map.write().remove(&6); + assert_eq!(map.bytes(), 1); + assert_eq!(map.len(), 1); + } +} \ No newline at end of file diff --git a/client/transaction-pool/graph/src/validated_pool.rs b/client/transaction-pool/graph/src/validated_pool.rs index 19f491bb1d383f0e88e030effe922a2dd2c2aa1f..86c2e75832f07fa02343a4e681b5429211adff17 100644 --- a/client/transaction-pool/graph/src/validated_pool.rs +++ b/client/transaction-pool/graph/src/validated_pool.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use std::{ collections::{HashSet, HashMap}, @@ -20,12 +22,11 @@ use std::{ sync::Arc, }; -use crate::{base_pool as base, BlockHash}; +use crate::base_pool as base; use crate::listener::Listener; use crate::rotator::PoolRotator; use crate::watcher::Watcher; use serde::Serialize; -use log::{debug, warn}; use parking_lot::{Mutex, RwLock}; use sp_runtime::{ @@ -35,10 +36,13 @@ use sp_runtime::{ }; use sp_transaction_pool::{error, PoolStatus}; use wasm_timer::Instant; -use sp_utils::mpsc::{tracing_unbounded, TracingUnboundedSender}; +use futures::channel::mpsc::{channel, Sender}; +use retain_mut::RetainMut; use crate::base_pool::PruneStatus; -use crate::pool::{EventStream, Options, ChainApi, ExHash, ExtrinsicFor, TransactionFor}; +use crate::pool::{ + EventStream, Options, ChainApi, BlockHash, ExtrinsicHash, ExtrinsicFor, TransactionFor, +}; /// Pre-validated transaction. Validated pool only accepts transactions wrapped in this enum. #[derive(Debug)] @@ -81,7 +85,7 @@ impl ValidatedTransaction { /// A type of validated transaction stored in the pool. pub type ValidatedTransactionFor = ValidatedTransaction< - ExHash, + ExtrinsicHash, ExtrinsicFor, ::Error, >; @@ -90,19 +94,18 @@ pub type ValidatedTransactionFor = ValidatedTransaction< pub struct ValidatedPool { api: Arc, options: Options, - listener: RwLock, B>>, + listener: RwLock, B>>, pool: RwLock, + ExtrinsicHash, ExtrinsicFor, >>, - import_notification_sinks: Mutex>>>, - rotator: PoolRotator>, + import_notification_sinks: Mutex>>>, + rotator: PoolRotator>, } #[cfg(not(target_os = "unknown"))] impl parity_util_mem::MallocSizeOf for ValidatedPool where - B::Hash: parity_util_mem::MallocSizeOf, ExtrinsicFor: parity_util_mem::MallocSizeOf, { fn size_of(&self, ops: &mut parity_util_mem::MallocSizeOfOps) -> usize { @@ -126,19 +129,39 @@ impl ValidatedPool { } /// Bans given set of hashes. - pub fn ban(&self, now: &Instant, hashes: impl IntoIterator>) { + pub fn ban(&self, now: &Instant, hashes: impl IntoIterator>) { self.rotator.ban(now, hashes) } /// Returns true if transaction with given hash is currently banned from the pool. - pub fn is_banned(&self, hash: &ExHash) -> bool { + pub fn is_banned(&self, hash: &ExtrinsicHash) -> bool { self.rotator.is_banned(hash) } + /// A fast check before doing any further processing of a transaction, like validation. + /// + /// If `ingore_banned` is `true`, it will not check if the transaction is banned. + /// + /// It checks if the transaction is already imported or banned. If so, it returns an error. + pub fn check_is_known( + &self, + tx_hash: &ExtrinsicHash, + ignore_banned: bool, + ) -> Result<(), B::Error> { + if !ignore_banned && self.is_banned(tx_hash) { + Err(error::Error::TemporarilyBanned.into()) + } else if self.pool.read().is_imported(tx_hash) { + Err(error::Error::AlreadyImported(Box::new(tx_hash.clone())).into()) + } else { + Ok(()) + } + } + /// Imports a bunch of pre-validated transactions to the pool. - pub fn submit(&self, txs: T) -> Vec, B::Error>> where - T: IntoIterator> - { + pub fn submit( + &self, + txs: impl IntoIterator>, + ) -> Vec, B::Error>> { let results = txs.into_iter() .map(|validated_tx| self.submit_one(validated_tx)) .collect::>(); @@ -157,14 +180,26 @@ impl ValidatedPool { } /// Submit single pre-validated transaction to the pool. - fn submit_one(&self, tx: ValidatedTransactionFor) -> Result, B::Error> { + fn submit_one(&self, tx: ValidatedTransactionFor) -> Result, B::Error> { match tx { ValidatedTransaction::Valid(tx) => { let imported = self.pool.write().import(tx)?; if let base::Imported::Ready { ref hash, .. } = imported { self.import_notification_sinks.lock() - .retain(|sink| sink.unbounded_send(hash.clone()).is_ok()); + .retain_mut(|sink| { + match sink.try_send(hash.clone()) { + Ok(()) => true, + Err(e) => { + if e.is_full() { + log::warn!(target: "txpool", "[{:?}] Trying to notify an import but the channel is full", hash); + true + } else { + false + } + }, + } + }); } let mut listener = self.listener.write(); @@ -182,16 +217,16 @@ impl ValidatedPool { } } - fn enforce_limits(&self) -> HashSet> { + fn enforce_limits(&self) -> HashSet> { let status = self.pool.read().status(); let ready_limit = &self.options.ready; let future_limit = &self.options.future; - debug!(target: "txpool", "Pool Status: {:?}", status); + log::debug!(target: "txpool", "Pool Status: {:?}", status); if ready_limit.is_exceeded(status.ready, status.ready_bytes) || future_limit.is_exceeded(status.future, status.future_bytes) { - debug!( + log::debug!( target: "txpool", "Enforcing limits ({}/{}kB ready, {}/{}kB future", ready_limit.count, ready_limit.total_bytes / 1024, @@ -207,8 +242,11 @@ impl ValidatedPool { self.rotator.ban(&Instant::now(), removed.iter().map(|x| x.clone())); removed }; + if !removed.is_empty() { + log::debug!(target: "txpool", "Enforcing limits: {} dropped", removed.len()); + } + // run notifications - debug!(target: "txpool", "Enforcing limits: {} dropped", removed.len()); let mut listener = self.listener.write(); for h in &removed { listener.dropped(h, None); @@ -224,7 +262,7 @@ impl ValidatedPool { pub fn submit_and_watch( &self, tx: ValidatedTransactionFor, - ) -> Result, BlockHash>, B::Error> { + ) -> Result, ExtrinsicHash>, B::Error> { match tx { ValidatedTransaction::Valid(tx) => { let hash = self.api.hash_and_length(&tx.data).0; @@ -246,7 +284,7 @@ impl ValidatedPool { /// /// Removes and then submits passed transactions and all dependent transactions. /// Transactions that are missing from the pool are not submitted. - pub fn resubmit(&self, mut updated_transactions: HashMap, ValidatedTransactionFor>) { + pub fn resubmit(&self, mut updated_transactions: HashMap, ValidatedTransactionFor>) { #[derive(Debug, Clone, Copy, PartialEq)] enum Status { Future, Ready, Failed, Dropped }; @@ -322,7 +360,7 @@ impl ValidatedPool { // we do not want to fail if single transaction import has failed // nor we do want to propagate this error, because it could tx unknown to caller // => let's just notify listeners (and issue debug message) - warn!( + log::warn!( target: "txpool", "[{:?}] Removing invalid transaction from update: {}", hash, @@ -365,7 +403,7 @@ impl ValidatedPool { } /// For each extrinsic, returns tags that it provides (if known), or None (if it is unknown). - pub fn extrinsics_tags(&self, hashes: &[ExHash]) -> Vec>> { + pub fn extrinsics_tags(&self, hashes: &[ExtrinsicHash]) -> Vec>> { self.pool.read().by_hashes(&hashes) .into_iter() .map(|existing_in_pool| existing_in_pool @@ -374,7 +412,7 @@ impl ValidatedPool { } /// Get ready transaction by hash - pub fn ready_by_hash(&self, hash: &ExHash) -> Option> { + pub fn ready_by_hash(&self, hash: &ExtrinsicHash) -> Option> { self.pool.read().ready_by_hash(hash) } @@ -382,7 +420,7 @@ impl ValidatedPool { pub fn prune_tags( &self, tags: impl IntoIterator, - ) -> Result, ExtrinsicFor>, B::Error> { + ) -> Result, ExtrinsicFor>, B::Error> { // Perform tag-based pruning in the base pool let status = self.pool.write().prune_tags(tags); // Notify event listeners of all transactions @@ -404,8 +442,8 @@ impl ValidatedPool { pub fn resubmit_pruned( &self, at: &BlockId, - known_imported_hashes: impl IntoIterator> + Clone, - pruned_hashes: Vec>, + known_imported_hashes: impl IntoIterator> + Clone, + pruned_hashes: Vec>, pruned_xts: Vec>, ) -> Result<(), B::Error> { debug_assert_eq!(pruned_hashes.len(), pruned_xts.len()); @@ -436,7 +474,7 @@ impl ValidatedPool { pub fn fire_pruned( &self, at: &BlockId, - hashes: impl Iterator>, + hashes: impl Iterator>, ) -> Result<(), B::Error> { let header_hash = self.api.block_id_to_hash(at)? .ok_or_else(|| error::Error::InvalidBlockId(format!("{:?}", at)).into())?; @@ -469,7 +507,7 @@ impl ValidatedPool { .map(|tx| tx.hash.clone()) .collect::>() }; - let futures_to_remove: Vec> = { + let futures_to_remove: Vec> = { let p = self.pool.read(); let mut hashes = Vec::new(); for tx in p.futures() { @@ -490,7 +528,7 @@ impl ValidatedPool { /// Get rotator reference. #[cfg(test)] - pub fn rotator(&self) -> &PoolRotator> { + pub fn rotator(&self) -> &PoolRotator> { &self.rotator } @@ -503,14 +541,16 @@ impl ValidatedPool { /// /// Consumers of this stream should use the `ready` method to actually get the /// pending transactions in the right order. - pub fn import_notification_stream(&self) -> EventStream> { - let (sink, stream) = tracing_unbounded("mpsc_import_notifications"); + pub fn import_notification_stream(&self) -> EventStream> { + const CHANNEL_BUFFER_SIZE: usize = 1024; + + let (sink, stream) = channel(CHANNEL_BUFFER_SIZE); self.import_notification_sinks.lock().push(sink); stream } /// Invoked when extrinsics are broadcasted. - pub fn on_broadcasted(&self, propagated: HashMap, Vec>) { + pub fn on_broadcasted(&self, propagated: HashMap, Vec>) { let mut listener = self.listener.write(); for (hash, peers) in propagated.into_iter() { listener.broadcasted(&hash, peers); @@ -523,20 +563,20 @@ impl ValidatedPool { /// to prevent them from entering the pool right away. /// Note this is not the case for the dependent transactions - those may /// still be valid so we want to be able to re-import them. - pub fn remove_invalid(&self, hashes: &[ExHash]) -> Vec> { + pub fn remove_invalid(&self, hashes: &[ExtrinsicHash]) -> Vec> { // early exit in case there is no invalid transactions. if hashes.is_empty() { return vec![]; } - debug!(target: "txpool", "Removing invalid transactions: {:?}", hashes); + log::debug!(target: "txpool", "Removing invalid transactions: {:?}", hashes); // temporarily ban invalid transactions self.rotator.ban(&Instant::now(), hashes.iter().cloned()); let invalid = self.pool.write().remove_subtree(hashes); - debug!(target: "txpool", "Removed invalid transactions: {:?}", invalid); + log::debug!(target: "txpool", "Removed invalid transactions: {:?}", invalid); let mut listener = self.listener.write(); for tx in &invalid { @@ -558,7 +598,7 @@ impl ValidatedPool { /// Notify all watchers that transactions in the block with hash have been finalized pub async fn on_block_finalized(&self, block_hash: BlockHash) -> Result<(), B::Error> { - debug!(target: "txpool", "Attempting to notify watchers of finalization for {}", block_hash); + log::trace!(target: "txpool", "Attempting to notify watchers of finalization for {}", block_hash); self.listener.write().finalized(block_hash); Ok(()) } diff --git a/client/transaction-pool/graph/src/watcher.rs b/client/transaction-pool/graph/src/watcher.rs index d54cc2718b7cbf40f33633df249d7a8d36da826a..9d9a91bb23f69acb0ad42a1eba4dcadecc856c66 100644 --- a/client/transaction-pool/graph/src/watcher.rs +++ b/client/transaction-pool/graph/src/watcher.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Extrinsics status updates. diff --git a/client/transaction-pool/src/api.rs b/client/transaction-pool/src/api.rs index bd7e11a3a69520d03b027309532e48697f0d5db2..c6671fd5bd7f0cfbe13a99b99104de731a61cd55 100644 --- a/client/transaction-pool/src/api.rs +++ b/client/transaction-pool/src/api.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Chain api required for the transaction pool. @@ -23,9 +25,7 @@ use futures::{ }; use sc_client_api::{ - blockchain::HeaderBackend, - light::{Fetcher, RemoteCallRequest, RemoteBodyRequest}, - BlockBackend, + blockchain::HeaderBackend, light::{Fetcher, RemoteCallRequest, RemoteBodyRequest}, BlockBackend, }; use sp_runtime::{ generic::BlockId, traits::{self, Block as BlockT, BlockIdTo, Header as HeaderT, Hash as HashT}, @@ -33,22 +33,38 @@ use sp_runtime::{ }; use sp_transaction_pool::runtime_api::TaggedTransactionQueue; use sp_api::{ProvideRuntimeApi, ApiExt}; +use prometheus_endpoint::Registry as PrometheusRegistry; -use crate::error::{self, Error}; +use crate::{metrics::{ApiMetrics, ApiMetricsExt}, error::{self, Error}}; /// The transaction pool logic for full client. pub struct FullChainApi { client: Arc, pool: ThreadPool, _marker: PhantomData, + metrics: Option>, } -impl FullChainApi where - Block: BlockT, - Client: ProvideRuntimeApi + BlockIdTo, -{ +impl FullChainApi { /// Create new transaction pool logic. - pub fn new(client: Arc) -> Self { + pub fn new( + client: Arc, + prometheus: Option<&PrometheusRegistry>, + ) -> Self { + let metrics = prometheus.map(ApiMetrics::register).and_then(|r| { + match r { + Err(err) => { + log::warn!( + target: "txpool", + "Failed to register transaction pool api prometheus metrics: {:?}", + err, + ); + None + }, + Ok(api) => Some(Arc::new(api)) + } + }); + FullChainApi { client, pool: ThreadPoolBuilder::new() @@ -56,22 +72,25 @@ impl FullChainApi where .name_prefix("txpool-verifier") .create() .expect("Failed to spawn verifier threads, that are critical for node operation."), - _marker: Default::default() + _marker: Default::default(), + metrics, } } } -impl sc_transaction_graph::ChainApi for FullChainApi where +impl sc_transaction_graph::ChainApi for FullChainApi +where Block: BlockT, Client: ProvideRuntimeApi + BlockBackend + BlockIdTo, Client: Send + Sync + 'static, Client::Api: TaggedTransactionQueue, - sp_api::ApiErrorFor: Send, + sp_api::ApiErrorFor: Send + std::fmt::Display, { type Block = Block; - type Hash = Block::Hash; type Error = error::Error; - type ValidationFuture = Pin> + Send>>; + type ValidationFuture = Pin< + Box> + Send> + >; type BodyFuture = Ready::Extrinsic>>>>; fn block_body(&self, id: &BlockId) -> Self::BodyFuture { @@ -88,29 +107,19 @@ impl sc_transaction_graph::ChainApi for FullChainApi, _>( - &at, |v| v >= 2, - ) - .unwrap_or_default() - }; - - sp_tracing::enter_span!("runtime::validate_transaction"); - let res = if has_v2 { - runtime_api.validate_transaction(&at, source, uxt) - } else { - #[allow(deprecated)] // old validate_transaction - runtime_api.validate_transaction_before_version_2(&at, uxt) - }; - let res = res.map_err(|e| Error::RuntimeApi(format!("{:?}", e))); - if let Err(e) = tx.send(res) { - log::warn!("Unable to send a validate transaction result: {:?}", e); - } - })); + let metrics = self.metrics.clone(); + metrics.report(|m| m.validations_scheduled.inc()); + + self.pool.spawn_ok(futures_diagnose::diagnose( + "validate-transaction", + async move { + let res = validate_transaction_blocking(&*client, &at, source, uxt); + if let Err(e) = tx.send(res) { + log::warn!("Unable to send a validate transaction result: {:?}", e); + } + metrics.report(|m| m.validations_finished.inc()); + }, + )); Box::pin(async move { match rx.await { @@ -134,13 +143,72 @@ impl sc_transaction_graph::ChainApi for FullChainApi) -> (Self::Hash, usize) { + fn hash_and_length( + &self, + ex: &sc_transaction_graph::ExtrinsicFor, + ) -> (sc_transaction_graph::ExtrinsicHash, usize) { ex.using_encoded(|x| { ( as traits::Hash>::hash(x), x.len()) }) } } +/// Helper function to validate a transaction using a full chain API. +/// This method will call into the runtime to perform the validation. +fn validate_transaction_blocking( + client: &Client, + at: &BlockId, + source: TransactionSource, + uxt: sc_transaction_graph::ExtrinsicFor>, +) -> error::Result +where + Block: BlockT, + Client: ProvideRuntimeApi + BlockBackend + BlockIdTo, + Client: Send + Sync + 'static, + Client::Api: TaggedTransactionQueue, + sp_api::ApiErrorFor: Send + std::fmt::Display, +{ + sp_tracing::enter_span!("validate_transaction"); + let runtime_api = client.runtime_api(); + let has_v2 = sp_tracing::tracing_span! { "check_version"; + runtime_api + .has_api_with::, _>(&at, |v| v >= 2) + .unwrap_or_default() + }; + + sp_tracing::enter_span!("runtime::validate_transaction"); + let res = if has_v2 { + runtime_api.validate_transaction(&at, source, uxt) + } else { + #[allow(deprecated)] // old validate_transaction + runtime_api.validate_transaction_before_version_2(&at, uxt) + }; + + res.map_err(|e| Error::RuntimeApi(e.to_string())) +} + +impl FullChainApi +where + Block: BlockT, + Client: ProvideRuntimeApi + BlockBackend + BlockIdTo, + Client: Send + Sync + 'static, + Client::Api: TaggedTransactionQueue, + sp_api::ApiErrorFor: Send + std::fmt::Display, +{ + /// Validates a transaction by calling into the runtime, same as + /// `validate_transaction` but blocks the current thread when performing + /// validation. Only implemented for `FullChainApi` since we can call into + /// the runtime locally. + pub fn validate_transaction_blocking( + &self, + at: &BlockId, + source: TransactionSource, + uxt: sc_transaction_graph::ExtrinsicFor, + ) -> error::Result { + validate_transaction_blocking(&*self.client, at, source, uxt) + } +} + /// The transaction pool logic for light client. pub struct LightChainApi { client: Arc, @@ -148,11 +216,7 @@ pub struct LightChainApi { _phantom: PhantomData, } -impl LightChainApi where - Block: BlockT, - Client: HeaderBackend, - F: Fetcher, -{ +impl LightChainApi { /// Create new transaction pool logic. pub fn new(client: Arc, fetcher: Arc) -> Self { LightChainApi { @@ -163,16 +227,23 @@ impl LightChainApi where } } -impl sc_transaction_graph::ChainApi for LightChainApi where - Block: BlockT, - Client: HeaderBackend + 'static, - F: Fetcher + 'static, +impl sc_transaction_graph::ChainApi for + LightChainApi where + Block: BlockT, + Client: HeaderBackend + 'static, + F: Fetcher + 'static, { type Block = Block; - type Hash = Block::Hash; type Error = error::Error; - type ValidationFuture = Box> + Send + Unpin>; - type BodyFuture = Pin::Extrinsic>>>> + Send>>; + type ValidationFuture = Box< + dyn Future> + Send + Unpin + >; + type BodyFuture = Pin< + Box< + dyn Future::Extrinsic>>>> + + Send + > + >; fn validate_transaction( &self, @@ -209,15 +280,24 @@ impl sc_transaction_graph::ChainApi for LightChainApi) -> error::Result>> { + fn block_id_to_number( + &self, + at: &BlockId, + ) -> error::Result>> { Ok(self.client.block_number_from_id(at)?) } - fn block_id_to_hash(&self, at: &BlockId) -> error::Result>> { + fn block_id_to_hash( + &self, + at: &BlockId, + ) -> error::Result>> { Ok(self.client.block_hash_from_id(at)?) } - fn hash_and_length(&self, ex: &sc_transaction_graph::ExtrinsicFor) -> (Self::Hash, usize) { + fn hash_and_length( + &self, + ex: &sc_transaction_graph::ExtrinsicFor, + ) -> (sc_transaction_graph::ExtrinsicHash, usize) { ex.using_encoded(|x| { (<::Hashing as HashT>::hash(x), x.len()) }) @@ -225,7 +305,7 @@ impl sc_transaction_graph::ChainApi for LightChainApi) -> Self::BodyFuture { let header = self.client.header(*id) - .and_then(|h| h.ok_or(sp_blockchain::Error::UnknownBlock(format!("{}", id)))); + .and_then(|h| h.ok_or_else(|| sp_blockchain::Error::UnknownBlock(format!("{}", id)))); let header = match header { Ok(header) => header, Err(err) => { diff --git a/client/transaction-pool/src/error.rs b/client/transaction-pool/src/error.rs index fa48b387c41d88ebfeab55278d777ff31b0dc1f0..c0f795df1801a0c59313aac28346bb6797ff04b7 100644 --- a/client/transaction-pool/src/error.rs +++ b/client/transaction-pool/src/error.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Transaction pool error. diff --git a/client/transaction-pool/src/lib.rs b/client/transaction-pool/src/lib.rs index e095191c574fad94fb8f3bec7d2ce8c5e5f55a03..0b6a1e935b9d0d8c4bdfeaac3dab34629c437865 100644 --- a/client/transaction-pool/src/lib.rs +++ b/client/transaction-pool/src/lib.rs @@ -1,18 +1,20 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Substrate transaction pool implementation. @@ -26,41 +28,52 @@ mod metrics; pub mod error; -#[cfg(any(feature = "test-helpers", test))] +#[cfg(test)] pub mod testing; pub use sc_transaction_graph as txpool; pub use crate::api::{FullChainApi, LightChainApi}; -use std::{collections::HashMap, sync::Arc, pin::Pin}; -use futures::{prelude::*, future::ready, channel::oneshot}; +use std::{collections::{HashMap, HashSet}, sync::Arc, pin::Pin, convert::TryInto}; +use futures::{prelude::*, future::{self, ready}, channel::oneshot}; use parking_lot::Mutex; use sp_runtime::{ generic::BlockId, traits::{Block as BlockT, NumberFor, AtLeast32Bit, Extrinsic, Zero}, }; +use sp_core::traits::SpawnNamed; use sp_transaction_pool::{ TransactionPool, PoolStatus, ImportNotificationStream, TxHash, TransactionFor, TransactionStatusStreamFor, MaintainedTransactionPool, PoolFuture, ChainEvent, TransactionSource, }; +use sc_transaction_graph::{ChainApi, ExtrinsicHash}; use wasm_timer::Instant; use prometheus_endpoint::Registry as PrometheusRegistry; use crate::metrics::MetricsLink as PrometheusMetrics; -type BoxedReadyIterator = Box>> + Send>; +type BoxedReadyIterator = Box< + dyn Iterator>> + Send +>; -type ReadyIteratorFor = BoxedReadyIterator, sc_transaction_graph::ExtrinsicFor>; +type ReadyIteratorFor = BoxedReadyIterator< + sc_transaction_graph::ExtrinsicHash, sc_transaction_graph::ExtrinsicFor +>; type PolledIterator = Pin> + Send>>; +/// A transaction pool for a full node. +pub type FullPool = BasicPool, Block>; +/// A transaction pool for a light node. +pub type LightPool = BasicPool, Block>; + /// Basic implementation of transaction pool that can be customized by providing PoolApi. pub struct BasicPool where Block: BlockT, - PoolApi: sc_transaction_graph::ChainApi, + PoolApi: ChainApi, { pool: Arc>, api: Arc, @@ -114,8 +127,7 @@ impl ReadyPoll { #[cfg(not(target_os = "unknown"))] impl parity_util_mem::MallocSizeOf for BasicPool where - PoolApi: sc_transaction_graph::ChainApi, - PoolApi::Hash: parity_util_mem::MallocSizeOf, + PoolApi: ChainApi, Block: BlockT, { fn size_of(&self, ops: &mut parity_util_mem::MallocSizeOfOps) -> usize { @@ -144,20 +156,8 @@ pub enum RevalidationType { impl BasicPool where Block: BlockT, - PoolApi: sc_transaction_graph::ChainApi + 'static, + PoolApi: ChainApi + 'static, { - /// Create new basic transaction pool with provided api. - /// - /// It will also optionally return background task that might be started by the - /// caller. - pub fn new( - options: sc_transaction_graph::Options, - pool_api: Arc, - prometheus: Option<&PrometheusRegistry>, - ) -> (Self, Option + Send>>>) { - Self::with_revalidation_type(options, pool_api, prometheus, RevalidationType::Full) - } - /// Create new basic transaction pool with provided api, for tests. #[cfg(test)] pub fn new_test( @@ -187,7 +187,8 @@ impl BasicPool pool_api: Arc, prometheus: Option<&PrometheusRegistry>, revalidation_type: RevalidationType, - ) -> (Self, Option + Send>>>) { + spawner: impl SpawnNamed, + ) -> Self { let pool = Arc::new(sc_transaction_graph::Pool::new(options, pool_api.clone())); let (revalidation_queue, background_task) = match revalidation_type { RevalidationType::Light => (revalidation::RevalidationQueue::new(pool_api.clone(), pool.clone()), None), @@ -197,22 +198,23 @@ impl BasicPool }, }; - ( - BasicPool { - api: pool_api, - pool, - revalidation_queue: Arc::new(revalidation_queue), - revalidation_strategy: Arc::new(Mutex::new( - match revalidation_type { - RevalidationType::Light => RevalidationStrategy::Light(RevalidationStatus::NotScheduled), - RevalidationType::Full => RevalidationStrategy::Always, - } - )), - ready_poll: Default::default(), - metrics: PrometheusMetrics::new(prometheus), - }, - background_task, - ) + if let Some(background_task) = background_task { + spawner.spawn("txpool-background", background_task); + } + + BasicPool { + api: pool_api, + pool, + revalidation_queue: Arc::new(revalidation_queue), + revalidation_strategy: Arc::new(Mutex::new( + match revalidation_type { + RevalidationType::Light => RevalidationStrategy::Light(RevalidationStatus::NotScheduled), + RevalidationType::Full => RevalidationStrategy::Always, + } + )), + ready_poll: Default::default(), + metrics: PrometheusMetrics::new(prometheus), + } } /// Gets shared reference to the underlying pool. @@ -224,11 +226,13 @@ impl BasicPool impl TransactionPool for BasicPool where Block: BlockT, - PoolApi: 'static + sc_transaction_graph::ChainApi, + PoolApi: 'static + ChainApi, { type Block = PoolApi::Block; - type Hash = sc_transaction_graph::ExHash; - type InPoolTransaction = sc_transaction_graph::base_pool::Transaction, TransactionFor>; + type Hash = sc_transaction_graph::ExtrinsicHash; + type InPoolTransaction = sc_transaction_graph::base_pool::Transaction< + TxHash, TransactionFor + >; type Error = PoolApi::Error; fn submit_at( @@ -240,15 +244,9 @@ impl TransactionPool for BasicPool let pool = self.pool.clone(); let at = *at; - self.metrics.report(|metrics| metrics.validations_scheduled.inc_by(xts.len() as u64)); + self.metrics.report(|metrics| metrics.submitted_transactions.inc_by(xts.len() as u64)); - let metrics = self.metrics.clone(); - async move { - let tx_count = xts.len(); - let res = pool.submit_at(&at, source, xts, false).await; - metrics.report(|metrics| metrics.validations_finished.inc_by(tx_count as u64)); - res - }.boxed() + async move { pool.submit_at(&at, source, xts).await }.boxed() } fn submit_one( @@ -260,16 +258,9 @@ impl TransactionPool for BasicPool let pool = self.pool.clone(); let at = *at; - self.metrics.report(|metrics| metrics.validations_scheduled.inc()); - - let metrics = self.metrics.clone(); - async move { - let res = pool.submit_one(&at, source, xt).await; - - metrics.report(|metrics| metrics.validations_finished.inc()); - res + self.metrics.report(|metrics| metrics.submitted_transactions.inc()); - }.boxed() + async move { pool.submit_one(&at, source, xt).await }.boxed() } fn submit_and_watch( @@ -281,22 +272,19 @@ impl TransactionPool for BasicPool let at = *at; let pool = self.pool.clone(); - self.metrics.report(|metrics| metrics.validations_scheduled.inc()); + self.metrics.report(|metrics| metrics.submitted_transactions.inc()); - let metrics = self.metrics.clone(); async move { - let result = pool.submit_and_watch(&at, source, xt) + pool.submit_and_watch(&at, source, xt) .map(|result| result.map(|watcher| Box::new(watcher.into_stream()) as _)) - .await; - - metrics.report(|metrics| metrics.validations_finished.inc()); - - result + .await }.boxed() } fn remove_invalid(&self, hashes: &[TxHash]) -> Vec> { - self.pool.validated_pool().remove_invalid(hashes) + let removed = self.pool.validated_pool().remove_invalid(hashes); + self.metrics.report(|metrics| metrics.validations_invalid.inc_by(removed.len() as u64)); + removed } fn status(&self) -> PoolStatus { @@ -321,6 +309,7 @@ impl TransactionPool for BasicPool fn ready_at(&self, at: NumberFor) -> PolledIterator { if self.ready_poll.lock().updated_at() >= at { + log::trace!(target: "txpool", "Transaction pool already processed block #{}", at); let iterator: ReadyIteratorFor = Box::new(self.pool.validated_pool().ready()); return Box::pin(futures::future::ready(iterator)); } @@ -341,6 +330,109 @@ impl TransactionPool for BasicPool } } +impl LightPool +where + Block: BlockT, + Client: sp_blockchain::HeaderBackend + 'static, + Fetcher: sc_client_api::Fetcher + 'static, +{ + /// Create new basic transaction pool for a light node with the provided api. + pub fn new_light( + options: sc_transaction_graph::Options, + prometheus: Option<&PrometheusRegistry>, + spawner: impl SpawnNamed, + client: Arc, + fetcher: Arc, + ) -> Self { + let pool_api = Arc::new(LightChainApi::new(client, fetcher)); + Self::with_revalidation_type( + options, pool_api, prometheus, RevalidationType::Light, spawner, + ) + } +} + +impl FullPool +where + Block: BlockT, + Client: sp_api::ProvideRuntimeApi + + sc_client_api::BlockBackend + + sp_runtime::traits::BlockIdTo, + Client: sc_client_api::ExecutorProvider + Send + Sync + 'static, + Client::Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue, + sp_api::ApiErrorFor: Send + std::fmt::Display, +{ + /// Create new basic transaction pool for a full node with the provided api. + pub fn new_full( + options: sc_transaction_graph::Options, + prometheus: Option<&PrometheusRegistry>, + spawner: impl SpawnNamed, + client: Arc, + ) -> Arc { + let pool_api = Arc::new(FullChainApi::new(client.clone(), prometheus)); + let pool = Arc::new(Self::with_revalidation_type( + options, pool_api, prometheus, RevalidationType::Full, spawner + )); + + // make transaction pool available for off-chain runtime calls. + client.execution_extensions().register_transaction_pool(&pool); + + pool + } +} + +impl sp_transaction_pool::LocalTransactionPool + for BasicPool, Block> +where + Block: BlockT, + Client: sp_api::ProvideRuntimeApi + + sc_client_api::BlockBackend + + sp_runtime::traits::BlockIdTo, + Client: Send + Sync + 'static, + Client::Api: sp_transaction_pool::runtime_api::TaggedTransactionQueue, + sp_api::ApiErrorFor: Send + std::fmt::Display, +{ + type Block = Block; + type Hash = sc_transaction_graph::ExtrinsicHash>; + type Error = as ChainApi>::Error; + + fn submit_local( + &self, + at: &BlockId, + xt: sp_transaction_pool::LocalTransactionFor, + ) -> Result { + use sc_transaction_graph::ValidatedTransaction; + use sp_runtime::traits::SaturatedConversion; + use sp_runtime::transaction_validity::TransactionValidityError; + + let validity = self + .api + .validate_transaction_blocking(at, TransactionSource::Local, xt.clone())? + .map_err(|e| { + Self::Error::Pool(match e { + TransactionValidityError::Invalid(i) => i.into(), + TransactionValidityError::Unknown(u) => u.into(), + }) + })?; + + let (hash, bytes) = self.pool.validated_pool().api().hash_and_length(&xt); + let block_number = self + .api + .block_id_to_number(at)? + .ok_or_else(|| error::Error::BlockIdConversion(format!("{:?}", at)))?; + + let validated = ValidatedTransaction::valid_at( + block_number.saturated_into::(), + hash.clone(), + TransactionSource::Local, + xt, + bytes, + validity, + ); + + self.pool.validated_pool().submit(vec![validated]).remove(0) + } +} + #[cfg_attr(test, derive(Debug))] enum RevalidationStatus { /// The revalidation has never been completed. @@ -425,22 +517,51 @@ impl RevalidationStatus { } } +/// Prune the known txs for the given block. +async fn prune_known_txs_for_block>( + block_id: BlockId, + api: &Api, + pool: &sc_transaction_graph::Pool, +) -> Vec> { + let hashes = api.block_body(&block_id).await + .unwrap_or_else(|e| { + log::warn!("Prune known transactions: error request {:?}!", e); + None + }) + .unwrap_or_default() + .into_iter() + .map(|tx| pool.hash_of(&tx)) + .collect::>(); + + log::trace!(target: "txpool", "Pruning transactions: {:?}", hashes); + + if let Err(e) = pool.prune_known(&block_id, &hashes) { + log::error!("Cannot prune known in the pool {:?}!", e); + } + + hashes +} + impl MaintainedTransactionPool for BasicPool where Block: BlockT, - PoolApi: 'static + sc_transaction_graph::ChainApi, + PoolApi: 'static + ChainApi, { fn maintain(&self, event: ChainEvent) -> Pin + Send>> { match event { - ChainEvent::NewBlock { id, retracted, .. } => { - let id = id.clone(); + ChainEvent::NewBestBlock { hash, tree_route } => { let pool = self.pool.clone(); let api = self.api.clone(); + let id = BlockId::hash(hash); let block_number = match api.block_id_to_number(&id) { Ok(Some(number)) => number, _ => { - log::trace!(target: "txpool", "Skipping chain event - no number for that block {:?}", id); + log::trace!( + target: "txpool", + "Skipping chain event - no number for that block {:?}", + id, + ); return Box::pin(ready(())); } }; @@ -451,40 +572,56 @@ impl MaintainedTransactionPool for BasicPool Some(20.into()), ); let revalidation_strategy = self.revalidation_strategy.clone(); - let retracted = retracted.clone(); let revalidation_queue = self.revalidation_queue.clone(); let ready_poll = self.ready_poll.clone(); + let metrics = self.metrics.clone(); async move { - // We don't query block if we won't prune anything - if !pool.validated_pool().status().is_empty() { - let hashes = api.block_body(&id).await - .unwrap_or_else(|e| { - log::warn!("Prune known transactions: error request {:?}!", e); - None - }) - .unwrap_or_default() - .into_iter() - .map(|tx| pool.hash_of(&tx)) - .collect::>(); - - if let Err(e) = pool.prune_known(&id, &hashes) { - log::error!("Cannot prune known in the pool {:?}!", e); + // We keep track of everything we prune so that later we won't add + // tranactions with those hashes from the retracted blocks. + let mut pruned_log = HashSet::>::new(); + + // If there is a tree route, we use this to prune known tx based on the enacted + // blocks. Before pruning enacted transactions, we inform the listeners about + // retracted blocks and their transactions. This order is important, because + // if we enact and retract the same transaction at the same time, we want to + // send first the retract and than the prune event. + if let Some(ref tree_route) = tree_route { + for retracted in tree_route.retracted() { + // notify txs awaiting finality that it has been retracted + pool.validated_pool().on_block_retracted(retracted.hash.clone()); } + + future::join_all( + tree_route + .enacted() + .iter() + .map(|h| + prune_known_txs_for_block( + BlockId::Hash(h.hash.clone()), + &*api, + &*pool, + ), + ), + ).await.into_iter().for_each(|enacted_log|{ + pruned_log.extend(enacted_log); + }) } - let extra_pool = pool.clone(); - // After #5200 lands, this arguably might be moved to the handler of "all blocks notification". - ready_poll.lock().trigger(block_number, move || Box::new(extra_pool.validated_pool().ready())); + pruned_log.extend(prune_known_txs_for_block(id.clone(), &*api, &*pool).await); - if next_action.resubmit { + metrics.report( + |metrics| metrics.block_transactions_pruned.inc_by(pruned_log.len() as u64) + ); + + if let (true, Some(tree_route)) = (next_action.resubmit, tree_route) { let mut resubmit_transactions = Vec::new(); - for retracted_hash in retracted { - // notify txs awaiting finality that it has been retracted - pool.validated_pool().on_block_retracted(retracted_hash.clone()); + for retracted in tree_route.retracted() { + let hash = retracted.hash.clone(); - let block_transactions = api.block_body(&BlockId::hash(retracted_hash.clone())).await + let block_transactions = api.block_body(&BlockId::hash(hash)) + .await .unwrap_or_else(|e| { log::warn!("Failed to fetch block body {:?}!", e); None @@ -493,29 +630,66 @@ impl MaintainedTransactionPool for BasicPool .into_iter() .filter(|tx| tx.is_signed().unwrap_or(true)); - resubmit_transactions.extend(block_transactions); + let mut resubmitted_to_report = 0; + + resubmit_transactions.extend( + block_transactions.into_iter().filter(|tx| { + let tx_hash = pool.hash_of(&tx); + let contains = pruned_log.contains(&tx_hash); + + // need to count all transactions, not just filtered, here + resubmitted_to_report += 1; + + if !contains { + log::debug!( + target: "txpool", + "[{:?}]: Resubmitting from retracted block {:?}", + tx_hash, + hash, + ); + } + !contains + }) + ); + + metrics.report( + |metrics| metrics.block_transactions_resubmitted.inc_by(resubmitted_to_report) + ); } - if let Err(e) = pool.submit_at( + + if let Err(e) = pool.resubmit_at( &id, // These transactions are coming from retracted blocks, we should // simply consider them external. TransactionSource::External, resubmit_transactions, - true ).await { log::debug!( target: "txpool", - "[{:?}] Error re-submitting transactions: {:?}", id, e + "[{:?}] Error re-submitting transactions: {:?}", + id, + e, ) } } + let extra_pool = pool.clone(); + // After #5200 lands, this arguably might be moved to the + // handler of "all blocks notification". + ready_poll.lock().trigger( + block_number, + move || Box::new(extra_pool.validated_pool().ready()), + ); + if next_action.revalidate { - let hashes = pool.validated_pool().ready().map(|tx| tx.hash.clone()).collect(); + let hashes = pool.validated_pool() + .ready() + .map(|tx| tx.hash.clone()) + .collect(); revalidation_queue.revalidate_later(block_number, hashes).await; - } - revalidation_strategy.lock().clear(); + revalidation_strategy.lock().clear(); + } }.boxed() } ChainEvent::Finalized { hash } => { @@ -533,3 +707,25 @@ impl MaintainedTransactionPool for BasicPool } } } + +/// Inform the transaction pool about imported and finalized blocks. +pub async fn notification_future( + client: Arc, + txpool: Arc +) + where + Block: BlockT, + Client: sc_client_api::BlockchainEvents, + Pool: MaintainedTransactionPool, +{ + let import_stream = client.import_notification_stream() + .filter_map(|n| ready(n.try_into().ok())) + .fuse(); + let finality_stream = client.finality_notification_stream() + .map(Into::into) + .fuse(); + + futures::stream::select(import_stream, finality_stream) + .for_each(|evt| txpool.maintain(evt)) + .await +} diff --git a/client/transaction-pool/src/metrics.rs b/client/transaction-pool/src/metrics.rs index 78e49b3ca53af732d28bd48ea65dc65b74835264..376e6dfe94488611db828fdbce0f5f9294c1747d 100644 --- a/client/transaction-pool/src/metrics.rs +++ b/client/transaction-pool/src/metrics.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Transaction pool Prometheus metrics. @@ -43,11 +45,55 @@ impl MetricsLink { /// Transaction pool Prometheus metrics. pub struct Metrics { + pub submitted_transactions: Counter, + pub validations_invalid: Counter, + pub block_transactions_pruned: Counter, + pub block_transactions_resubmitted: Counter, +} + +impl Metrics { + pub fn register(registry: &Registry) -> Result { + Ok(Self { + submitted_transactions: register( + Counter::new( + "sub_txpool_submitted_transactions", + "Total number of transactions submitted", + )?, + registry, + )?, + validations_invalid: register( + Counter::new( + "sub_txpool_validations_invalid", + "Total number of transactions that were removed from the pool as invalid", + )?, + registry, + )?, + block_transactions_pruned: register( + Counter::new( + "sub_txpool_block_transactions_pruned", + "Total number of transactions that was requested to be pruned by block events", + )?, + registry, + )?, + block_transactions_resubmitted: register( + Counter::new( + "sub_txpool_block_transactions_resubmitted", + "Total number of transactions that was requested to be resubmitted by block events", + )?, + registry, + )?, + }) + } +} + +/// Transaction pool api Prometheus metrics. +pub struct ApiMetrics { pub validations_scheduled: Counter, pub validations_finished: Counter, } -impl Metrics { +impl ApiMetrics { + /// Register the metrics at the given Prometheus registry. pub fn register(registry: &Registry) -> Result { Ok(Self { validations_scheduled: register( @@ -67,3 +113,17 @@ impl Metrics { }) } } + +/// An extension trait for [`ApiMetrics`]. +pub trait ApiMetricsExt { + /// Report an event to the metrics. + fn report(&self, report: impl FnOnce(&ApiMetrics)); +} + +impl ApiMetricsExt for Option> { + fn report(&self, report: impl FnOnce(&ApiMetrics)) { + if let Some(metrics) = self.as_ref() { + report(metrics) + } + } +} diff --git a/client/transaction-pool/src/revalidation.rs b/client/transaction-pool/src/revalidation.rs index f203bf08a0cf0321d084de6ff7efaf96905f466b..7be8688eaea5db287e05c9e9f56f5d227655664c 100644 --- a/client/transaction-pool/src/revalidation.rs +++ b/client/transaction-pool/src/revalidation.rs @@ -1,24 +1,26 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Pool periodic revalidation. use std::{sync::Arc, pin::Pin, collections::{HashMap, HashSet, BTreeMap}}; -use sc_transaction_graph::{ChainApi, Pool, ExHash, NumberFor, ValidatedTransaction}; +use sc_transaction_graph::{ChainApi, Pool, ExtrinsicHash, NumberFor, ValidatedTransaction}; use sp_runtime::traits::{Zero, SaturatedConversion}; use sp_runtime::generic::BlockId; use sp_runtime::transaction_validity::TransactionValidityError; @@ -32,12 +34,12 @@ const BACKGROUND_REVALIDATION_INTERVAL: Duration = Duration::from_millis(200); #[cfg(test)] pub const BACKGROUND_REVALIDATION_INTERVAL: Duration = Duration::from_millis(1); -const BACKGROUND_REVALIDATION_BATCH_SIZE: usize = 20; +const MIN_BACKGROUND_REVALIDATION_BATCH_SIZE: usize = 20; /// Payload from queue to worker. struct WorkerPayload { at: NumberFor, - transactions: Vec>, + transactions: Vec>, } /// Async revalidation worker. @@ -47,8 +49,8 @@ struct RevalidationWorker { api: Arc, pool: Arc>, best_block: NumberFor, - block_ordered: BTreeMap, HashSet>>, - members: HashMap, NumberFor>, + block_ordered: BTreeMap, HashSet>>, + members: HashMap, NumberFor>, } impl Unpin for RevalidationWorker {} @@ -61,18 +63,22 @@ async fn batch_revalidate( pool: Arc>, api: Arc, at: NumberFor, - batch: impl IntoIterator>, + batch: impl IntoIterator>, ) { let mut invalid_hashes = Vec::new(); let mut revalidated = HashMap::new(); - for ext_hash in batch { - let ext = match pool.validated_pool().ready_by_hash(&ext_hash) { - Some(ext) => ext, - None => continue, - }; - - match api.validate_transaction(&BlockId::Number(at), ext.source, ext.data.clone()).await { + let validation_results = futures::future::join_all( + batch.into_iter().filter_map(|ext_hash| { + pool.validated_pool().ready_by_hash(&ext_hash).map(|ext| { + api.validate_transaction(&BlockId::Number(at), ext.source, ext.data.clone()) + .map(move |validation_result| (validation_result, ext_hash, ext)) + }) + }) + ).await; + + for (validation_result, ext_hash, ext) in validation_results { + match validation_result { Ok(Err(TransactionValidityError::Invalid(err))) => { log::debug!(target: "txpool", "[{:?}]: Revalidation: invalid {:?}", ext_hash, err); invalid_hashes.push(ext_hash); @@ -127,22 +133,22 @@ impl RevalidationWorker { } } - fn prepare_batch(&mut self) -> Vec> { + fn prepare_batch(&mut self) -> Vec> { let mut queued_exts = Vec::new(); - let mut left = BACKGROUND_REVALIDATION_BATCH_SIZE; + let mut left = std::cmp::max(MIN_BACKGROUND_REVALIDATION_BATCH_SIZE, self.members.len() / 4); // Take maximum of count transaction by order // which they got into the pool while left > 0 { let first_block = match self.block_ordered.keys().next().cloned() { - Some(bn) => bn, - None => break, + Some(bn) => bn, + None => break, }; let mut block_drained = false; if let Some(extrinsics) = self.block_ordered.get_mut(&first_block) { let to_queue = extrinsics.iter().take(left).cloned().collect::>(); if to_queue.len() == extrinsics.len() { - block_drained = true; + block_drained = true; } else { for xt in &to_queue { extrinsics.remove(xt); @@ -153,7 +159,7 @@ impl RevalidationWorker { } if block_drained { - self.block_ordered.remove(&first_block); + self.block_ordered.remove(&first_block); } } @@ -176,7 +182,7 @@ impl RevalidationWorker { for ext_hash in transactions { // we don't add something that already scheduled for revalidation if self.members.contains_key(&ext_hash) { - log::debug!( + log::trace!( target: "txpool", "[{:?}] Skipped adding for revalidation: Already there.", ext_hash, @@ -205,8 +211,7 @@ impl RevalidationWorker { mut self, from_queue: TracingUnboundedReceiver>, interval: R, - ) where R: Send, R::Guard: Send - { + ) where R: Send, R::Guard: Send { let interval = interval.into_stream().fuse(); let from_queue = from_queue.fuse(); futures::pin_mut!(interval, from_queue); @@ -243,6 +248,16 @@ impl RevalidationWorker { Some(worker_payload) => { this.best_block = worker_payload.at; this.push(worker_payload); + + if this.members.len() > 0 { + log::debug!( + target: "txpool", + "Updated revalidation queue at {:?}. Transactions: {:?}", + this.best_block, + this.members, + ); + } + continue; }, // R.I.P. worker! @@ -282,9 +297,7 @@ where api: Arc, pool: Arc>, interval: R, - ) -> (Self, Pin + Send>>) - where R: Send + 'static, R::Guard: Send - { + ) -> (Self, Pin + Send>>) where R: Send + 'static, R::Guard: Send { let (to_worker, from_queue) = tracing_unbounded("mpsc_revalidation_queue"); let worker = RevalidationWorker::new(api.clone(), pool.clone()); @@ -322,16 +335,22 @@ where /// If queue configured with background worker, this will return immediately. /// If queue configured without background worker, this will resolve after /// revalidation is actually done. - pub async fn revalidate_later(&self, at: NumberFor, transactions: Vec>) { + pub async fn revalidate_later( + &self, + at: NumberFor, + transactions: Vec>, + ) { if transactions.len() > 0 { - log::debug!(target: "txpool", "Added {} transactions to revalidation queue", transactions.len()); + log::debug!( + target: "txpool", "Sent {} transactions to revalidation queue", + transactions.len(), + ); } if let Some(ref to_worker) = self.background { if let Err(e) = to_worker.unbounded_send(WorkerPayload { at, transactions }) { log::warn!(target: "txpool", "Failed to update background worker: {:?}", e); } - return; } else { let pool = self.pool.clone(); let api = self.api.clone(); @@ -347,9 +366,7 @@ mod tests { use sp_transaction_pool::TransactionSource; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; use futures::executor::block_on; - use substrate_test_runtime_client::{ - AccountKeyring::*, - }; + use substrate_test_runtime_client::AccountKeyring::*; fn setup() -> (Arc, Pool) { let test_api = Arc::new(TestApi::empty()); diff --git a/client/transaction-pool/src/testing/mod.rs b/client/transaction-pool/src/testing/mod.rs index a8f40c6b6475b57656bb0f373851f2162f283be5..350c4137c37b23a5d1fdfde94f0b19acde7cbdb4 100644 --- a/client/transaction-pool/src/testing/mod.rs +++ b/client/transaction-pool/src/testing/mod.rs @@ -1,18 +1,20 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . //! Tests for top-level transaction pool api diff --git a/client/transaction-pool/src/testing/pool.rs b/client/transaction-pool/src/testing/pool.rs index 45fb6f42c321fab9dfe038506d60fb79ec527ee6..8fa742cd419a339657c23783adebf81da2a9fccc 100644 --- a/client/transaction-pool/src/testing/pool.rs +++ b/client/transaction-pool/src/testing/pool.rs @@ -1,34 +1,40 @@ -// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate is free software: you can redistribute it and/or modify +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// 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. -// Substrate is distributed in the hope that it will be useful, +// 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 +// 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 Substrate. If not, see . +// along with this program. If not, see . use crate::*; use sp_transaction_pool::TransactionStatus; -use futures::executor::block_on; +use futures::executor::{block_on, block_on_stream}; use txpool::{self, Pool}; use sp_runtime::{ generic::BlockId, transaction_validity::{ValidTransaction, TransactionSource, InvalidTransaction}, }; use substrate_test_runtime_client::{ - runtime::{Block, Hash, Index, Header, Extrinsic, Transfer}, - AccountKeyring::*, + runtime::{Block, Hash, Index, Header, Extrinsic, Transfer}, AccountKeyring::*, + ClientBlockImportExt, }; use substrate_test_runtime_transaction_pool::{TestApi, uxt}; use futures::{prelude::*, task::Poll}; use codec::Encode; +use std::collections::BTreeSet; +use sc_client_api::client::BlockchainEvents; +use sc_block_builder::BlockBuilderProvider; +use sp_consensus::BlockOrigin; fn pool() -> Pool { Pool::new(Default::default(), TestApi::with_alice_nonce(209).into()) @@ -40,7 +46,7 @@ fn maintained_pool() -> ( intervalier::BackSignalControl, ) { let (pool, background_task, notifier) = BasicPool::new_test( - std::sync::Arc::new(TestApi::with_alice_nonce(209)) + Arc::new(TestApi::with_alice_nonce(209)), ); let thread_pool = futures::executor::ThreadPool::new().unwrap(); @@ -48,16 +54,6 @@ fn maintained_pool() -> ( (pool, thread_pool, notifier) } -fn header(number: u64) -> Header { - Header { - number, - digest: Default::default(), - extrinsics_root: Default::default(), - parent_hash: Default::default(), - state_root: Default::default(), - } -} - const SOURCE: TransactionSource = TransactionSource::External; #[test] @@ -110,6 +106,7 @@ fn prune_tags_should_work() { let pending: Vec<_> = pool.validated_pool().ready().map(|a| a.data.transfer().nonce).collect(); assert_eq!(pending, vec![209, 210]); + pool.validated_pool().api().push_block(1, Vec::new(), true); block_on( pool.prune_tags( &BlockId::number(1), @@ -138,6 +135,26 @@ fn should_ban_invalid_transactions() { block_on(pool.submit_one(&BlockId::number(0), SOURCE, uxt.clone())).unwrap_err(); } +#[test] +fn only_prune_on_new_best() { + let pool = maintained_pool().0; + let uxt = uxt(Alice, 209); + + let _ = block_on( + pool.submit_and_watch(&BlockId::number(0), SOURCE, uxt.clone()) + ).expect("1. Imported"); + pool.api.push_block(1, vec![uxt.clone()], true); + assert_eq!(pool.status().ready, 1); + + let header = pool.api.push_block(2, vec![uxt], true); + let event = ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, + }; + block_on(pool.maintain(event)); + assert_eq!(pool.status().ready, 0); +} + #[test] fn should_correctly_prune_transactions_providing_more_than_one_tag() { let api = Arc::new(TestApi::with_alice_nonce(209)); @@ -151,6 +168,7 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { // remove the transaction that just got imported. api.increment_nonce(Alice.into()); + api.push_block(1, Vec::new(), true); block_on(pool.prune_tags(&BlockId::number(1), vec![vec![209]], vec![])).expect("1. Pruned"); assert_eq!(pool.validated_pool().status().ready, 0); // it's re-imported to future @@ -158,6 +176,7 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { // so now let's insert another transaction that also provides the 155 api.increment_nonce(Alice.into()); + api.push_block(2, Vec::new(), true); let xt = uxt(Alice, 211); block_on(pool.submit_one(&BlockId::number(2), SOURCE, xt.clone())).expect("2. Imported"); assert_eq!(pool.validated_pool().status().ready, 1); @@ -167,30 +186,32 @@ fn should_correctly_prune_transactions_providing_more_than_one_tag() { // prune it and make sure the pool is empty api.increment_nonce(Alice.into()); + api.push_block(3, Vec::new(), true); block_on(pool.prune_tags(&BlockId::number(3), vec![vec![155]], vec![])).expect("2. Pruned"); assert_eq!(pool.validated_pool().status().ready, 0); assert_eq!(pool.validated_pool().status().future, 2); } -fn block_event(id: u64) -> ChainEvent { - ChainEvent::NewBlock { - id: BlockId::number(id), - is_new_best: true, - retracted: vec![], - header: header(id), +fn block_event(header: Header) -> ChainEvent { + ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, } } -fn block_event_with_retracted(id: u64, retracted: Vec) -> ChainEvent { - ChainEvent::NewBlock { - id: BlockId::number(id), - is_new_best: true, - retracted: retracted, - header: header(id), +fn block_event_with_retracted( + header: Header, + retracted_start: Hash, + api: &TestApi, +) -> ChainEvent { + let tree_route = api.tree_route(retracted_start, header.parent_hash).expect("Tree route exists"); + + ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: Some(Arc::new(tree_route)), } } - #[test] fn should_prune_old_during_maintenance() { let xt = uxt(Alice, 209); @@ -200,9 +221,9 @@ fn should_prune_old_during_maintenance() { block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); - pool.api.push_block(1, vec![xt.clone()]); + let header = pool.api.push_block(1, vec![xt.clone()], true); - block_on(pool.maintain(block_event(1))); + block_on(pool.maintain(block_event(header))); assert_eq!(pool.status().ready, 0); } @@ -217,9 +238,9 @@ fn should_revalidate_during_maintenance() { assert_eq!(pool.status().ready, 2); assert_eq!(pool.api.validation_requests().len(), 2); - pool.api.push_block(1, vec![xt1.clone()]); + let header = pool.api.push_block(1, vec![xt1.clone()], true); - block_on(pool.maintain(block_event(1))); + block_on(pool.maintain(block_event(header))); assert_eq!(pool.status().ready, 1); block_on(notifier.next()); @@ -230,37 +251,54 @@ fn should_revalidate_during_maintenance() { #[test] fn should_resubmit_from_retracted_during_maintenance() { let xt = uxt(Alice, 209); - let retracted_hash = Hash::random(); let (pool, _guard, _notifier) = maintained_pool(); block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); - pool.api.push_block(1, vec![]); - pool.api.push_fork_block(retracted_hash, vec![xt.clone()]); + let header = pool.api.push_block(1, vec![], true); + let fork_header = pool.api.push_block(1, vec![], false); - let event = block_event_with_retracted(1, vec![retracted_hash]); + let event = block_event_with_retracted(header, fork_header.hash(), &*pool.api); block_on(pool.maintain(event)); assert_eq!(pool.status().ready, 1); } + +#[test] +fn should_not_resubmit_from_retracted_during_maintenance_if_tx_is_also_in_enacted() { + let xt = uxt(Alice, 209); + + let (pool, _guard, _notifier) = maintained_pool(); + + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); + assert_eq!(pool.status().ready, 1); + + let header = pool.api.push_block(1, vec![xt.clone()], true); + let fork_header = pool.api.push_block(1, vec![xt], false); + + let event = block_event_with_retracted(header, fork_header.hash(), &*pool.api); + + block_on(pool.maintain(event)); + assert_eq!(pool.status().ready, 0); +} + #[test] fn should_not_retain_invalid_hashes_from_retracted() { let xt = uxt(Alice, 209); - let retracted_hash = Hash::random(); let (pool, _guard, mut notifier) = maintained_pool(); block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); - pool.api.push_block(1, vec![]); - pool.api.push_fork_block(retracted_hash, vec![xt.clone()]); + let header = pool.api.push_block(1, vec![], true); + let fork_header = pool.api.push_block(1, vec![xt.clone()], false); pool.api.add_invalid(&xt); - let event = block_event_with_retracted(1, vec![retracted_hash]); + let event = block_event_with_retracted(header, fork_header.hash(), &*pool.api); block_on(pool.maintain(event)); block_on(notifier.next()); @@ -277,17 +315,17 @@ fn should_revalidate_transaction_multiple_times() { block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); - pool.api.push_block(1, vec![xt.clone()]); + let header = pool.api.push_block(1, vec![xt.clone()], true); - block_on(pool.maintain(block_event(1))); + block_on(pool.maintain(block_event(header))); block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 1); - pool.api.push_block(2, vec![]); + let header = pool.api.push_block(2, vec![], true); pool.api.add_invalid(&xt); - block_on(pool.maintain(block_event(2))); + block_on(pool.maintain(block_event(header))); block_on(notifier.next()); assert_eq!(pool.status().ready, 0); @@ -301,19 +339,19 @@ fn should_revalidate_across_many_blocks() { let (pool, _guard, mut notifier) = maintained_pool(); - block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt1.clone())).expect("1. Imported"); - block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt2.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt1.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt2.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 2); - pool.api.push_block(1, vec![]); - block_on(pool.maintain(block_event(1))); + let header = pool.api.push_block(1, vec![], true); + block_on(pool.maintain(block_event(header))); block_on(notifier.next()); - block_on(pool.submit_one(&BlockId::number(2), SOURCE, xt3.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt3.clone())).expect("1. Imported"); assert_eq!(pool.status().ready, 3); - pool.api.push_block(2, vec![xt1.clone()]); - block_on(pool.maintain(block_event(2))); + let header = pool.api.push_block(2, vec![xt1.clone()], true); + block_on(pool.maintain(block_event(header))); block_on(notifier.next()); assert_eq!(pool.status().ready, 2); @@ -358,7 +396,8 @@ fn should_push_watchers_during_maintaince() { pool.api.add_invalid(&tx4); // clear timer events if any - block_on(pool.maintain(block_event(0))); + let header = pool.api.push_block(1, vec![], true); + block_on(pool.maintain(block_event(header))); block_on(notifier.next()); // then @@ -375,8 +414,9 @@ fn should_push_watchers_during_maintaince() { ); // when - let header_hash = pool.api.push_block(1, vec![tx0, tx1, tx2]).hash(); - block_on(pool.maintain(block_event(1))); + let header = pool.api.push_block(2, vec![tx0, tx1, tx2], true); + let header_hash = header.hash(); + block_on(pool.maintain(block_event(header))); let event = ChainEvent::Finalized { hash: header_hash.clone() }; block_on(pool.maintain(event)); @@ -387,15 +427,24 @@ fn should_push_watchers_during_maintaince() { // events for hash2 are: Ready, InBlock assert_eq!( futures::executor::block_on_stream(watcher0).collect::>(), - vec![TransactionStatus::Ready, TransactionStatus::InBlock(header_hash.clone()), TransactionStatus::Finalized(header_hash.clone())], + vec![ + TransactionStatus::Ready, + TransactionStatus::InBlock(header_hash.clone()), + TransactionStatus::Finalized(header_hash.clone())], ); assert_eq!( futures::executor::block_on_stream(watcher1).collect::>(), - vec![TransactionStatus::Ready, TransactionStatus::InBlock(header_hash.clone()), TransactionStatus::Finalized(header_hash.clone())], + vec![ + TransactionStatus::Ready, + TransactionStatus::InBlock(header_hash.clone()), + TransactionStatus::Finalized(header_hash.clone())], ); assert_eq!( futures::executor::block_on_stream(watcher2).collect::>(), - vec![TransactionStatus::Ready, TransactionStatus::InBlock(header_hash.clone()), TransactionStatus::Finalized(header_hash.clone())], + vec![ + TransactionStatus::Ready, + TransactionStatus::InBlock(header_hash.clone()), + TransactionStatus::Finalized(header_hash.clone())], ); } @@ -414,19 +463,17 @@ fn can_track_heap_size() { fn finalization() { let xt = uxt(Alice, 209); let api = TestApi::with_alice_nonce(209); - api.push_block(1, vec![]); + api.push_block(1, vec![], true); let (pool, _background, _) = BasicPool::new_test(api.into()); let watcher = block_on( pool.submit_and_watch(&BlockId::number(1), SOURCE, xt.clone()) ).expect("1. Imported"); - pool.api.push_block(2, vec![xt.clone()]); - - let header = pool.api.chain().read().header_by_number.get(&2).cloned().unwrap(); - let event = ChainEvent::NewBlock { - id: BlockId::Hash(header.hash()), - is_new_best: true, - header: header.clone(), - retracted: vec![] + pool.api.push_block(2, vec![xt.clone()], true); + + let header = pool.api.chain().read().block_by_number.get(&2).unwrap()[0].0.header().clone(); + let event = ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, }; block_on(pool.maintain(event)); @@ -444,7 +491,7 @@ fn finalization() { fn fork_aware_finalization() { let api = TestApi::empty(); // starting block A1 (last finalized.) - api.push_block(1, vec![]); + api.push_block(1, vec![], true); let (pool, _background, _) = BasicPool::new_test(api.into()); let mut canon_watchers = vec![]; @@ -465,21 +512,18 @@ fn fork_aware_finalization() { let c2; let d2; - // block B1 { let watcher = block_on( pool.submit_and_watch(&BlockId::number(1), SOURCE, from_alice.clone()) ).expect("1. Imported"); - let header = pool.api.push_block(2, vec![from_alice.clone()]); + let header = pool.api.push_block(2, vec![from_alice.clone()], true); canon_watchers.push((watcher, header.hash())); assert_eq!(pool.status().ready, 1); - let event = ChainEvent::NewBlock { - id: BlockId::Number(2), - is_new_best: true, - header: header.clone(), - retracted: vec![], + let event = ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, }; b1 = header.hash(); block_on(pool.maintain(event)); @@ -490,16 +534,14 @@ fn fork_aware_finalization() { // block C2 { - let header = pool.api.push_fork_block_with_parent(b1, vec![from_dave.clone()]); + let header = pool.api.push_block_with_parent(b1, vec![from_dave.clone()], true); from_dave_watcher = block_on( pool.submit_and_watch(&BlockId::number(1), SOURCE, from_dave.clone()) ).expect("1. Imported"); assert_eq!(pool.status().ready, 1); - let event = ChainEvent::NewBlock { - id: BlockId::Hash(header.hash()), - is_new_best: true, - header: header.clone(), - retracted: vec![] + let event = ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, }; c2 = header.hash(); block_on(pool.maintain(event)); @@ -512,13 +554,11 @@ fn fork_aware_finalization() { pool.submit_and_watch(&BlockId::number(1), SOURCE, from_bob.clone()) ).expect("1. Imported"); assert_eq!(pool.status().ready, 1); - let header = pool.api.push_fork_block_with_parent(c2, vec![from_bob.clone()]); + let header = pool.api.push_block_with_parent(c2, vec![from_bob.clone()], true); - let event = ChainEvent::NewBlock { - id: BlockId::Hash(header.hash()), - is_new_best: true, - header: header.clone(), - retracted: vec![] + let event = ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, }; d2 = header.hash(); block_on(pool.maintain(event)); @@ -531,17 +571,13 @@ fn fork_aware_finalization() { pool.submit_and_watch(&BlockId::number(1), SOURCE, from_charlie.clone()) ).expect("1.Imported"); assert_eq!(pool.status().ready, 1); - let header = pool.api.push_block(3, vec![from_charlie.clone()]); + let header = pool.api.push_block(3, vec![from_charlie.clone()], true); canon_watchers.push((watcher, header.hash())); - let event = ChainEvent::NewBlock { - id: BlockId::Number(3), - is_new_best: true, - header: header.clone(), - retracted: vec![c2, d2], - }; + let event = block_event_with_retracted(header.clone(), d2, &*pool.api); block_on(pool.maintain(event)); assert_eq!(pool.status().ready, 2); + let event = ChainEvent::Finalized { hash: header.hash() }; block_on(pool.maintain(event)); } @@ -553,14 +589,12 @@ fn fork_aware_finalization() { pool.submit_and_watch(&BlockId::number(1), SOURCE, xt.clone()) ).expect("1. Imported"); assert_eq!(pool.status().ready, 3); - let header = pool.api.push_block(4, vec![xt.clone()]); + let header = pool.api.push_block(4, vec![xt.clone()], true); canon_watchers.push((w, header.hash())); - let event = ChainEvent::NewBlock { - id: BlockId::Hash(header.hash()), - is_new_best: true, - header: header.clone(), - retracted: vec![] + let event = ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, }; d1 = header.hash(); block_on(pool.maintain(event)); @@ -573,13 +607,11 @@ fn fork_aware_finalization() { // block e1 { - let header = pool.api.push_block(5, vec![from_dave, from_bob]); + let header = pool.api.push_block(5, vec![from_dave, from_bob], true); e1 = header.hash(); - let event = ChainEvent::NewBlock { - id: BlockId::Hash(header.hash()), - is_new_best: true, - header: header.clone(), - retracted: vec![] + let event = ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, }; block_on(pool.maintain(event)); assert_eq!(pool.status().ready, 0); @@ -597,7 +629,7 @@ fn fork_aware_finalization() { { - let mut stream= futures::executor::block_on_stream(from_dave_watcher); + let mut stream = futures::executor::block_on_stream(from_dave_watcher); assert_eq!(stream.next(), Some(TransactionStatus::Ready)); assert_eq!(stream.next(), Some(TransactionStatus::InBlock(c2.clone()))); assert_eq!(stream.next(), Some(TransactionStatus::Retracted(c2))); @@ -608,7 +640,7 @@ fn fork_aware_finalization() { } { - let mut stream= futures::executor::block_on_stream(from_bob_watcher); + let mut stream = futures::executor::block_on_stream(from_bob_watcher); assert_eq!(stream.next(), Some(TransactionStatus::Ready)); assert_eq!(stream.next(), Some(TransactionStatus::InBlock(d2.clone()))); assert_eq!(stream.next(), Some(TransactionStatus::Retracted(d2))); @@ -619,11 +651,236 @@ fn fork_aware_finalization() { } } +/// Tests that when pruning and retracing a tx by the same event, we generate +/// the correct events in the correct order. +#[test] +fn prune_and_retract_tx_at_same_time() { + let api = TestApi::empty(); + // starting block A1 (last finalized.) + api.push_block(1, vec![], true); + + let (pool, _background, _) = BasicPool::new_test(api.into()); + + let from_alice = uxt(Alice, 1); + pool.api.increment_nonce(Alice.into()); + + let watcher = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, from_alice.clone()) + ).expect("1. Imported"); + + // Block B1 + let b1 = { + let header = pool.api.push_block(2, vec![from_alice.clone()], true); + assert_eq!(pool.status().ready, 1); + + let event = ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, + }; + block_on(pool.maintain(event)); + assert_eq!(pool.status().ready, 0); + header.hash() + }; + + // Block B2 + let b2 = { + let header = pool.api.push_block(2, vec![from_alice.clone()], false); + assert_eq!(pool.status().ready, 0); + + let event = block_event_with_retracted(header.clone(), b1, &*pool.api); + block_on(pool.maintain(event)); + assert_eq!(pool.status().ready, 0); + + let event = ChainEvent::Finalized { hash: header.hash() }; + block_on(pool.maintain(event)); + + header.hash() + }; + + { + let mut stream = futures::executor::block_on_stream(watcher); + assert_eq!(stream.next(), Some(TransactionStatus::Ready)); + assert_eq!(stream.next(), Some(TransactionStatus::InBlock(b1.clone()))); + assert_eq!(stream.next(), Some(TransactionStatus::Retracted(b1))); + assert_eq!(stream.next(), Some(TransactionStatus::InBlock(b2.clone()))); + assert_eq!(stream.next(), Some(TransactionStatus::Finalized(b2))); + assert_eq!(stream.next(), None); + } +} + + +/// This test ensures that transactions from a fork are re-submitted if +/// the forked block is not part of the retracted blocks. This happens as the +/// retracted block list only contains the route from the old best to the new +/// best, without any further forks. +/// +/// Given the following: +/// +/// -> D0 (old best, tx0) +/// / +/// C - -> D1 (tx1) +/// \ +/// -> D2 (new best) +/// +/// Retracted will contain `D0`, but we need to re-submit `tx0` and `tx1` as both +/// blocks are not part of the canonical chain. +#[test] +fn resubmit_tx_of_fork_that_is_not_part_of_retracted() { + let api = TestApi::empty(); + // starting block A1 (last finalized.) + api.push_block(1, vec![], true); + + let (pool, _background, _) = BasicPool::new_test(api.into()); + + let tx0 = uxt(Alice, 1); + let tx1 = uxt(Dave, 2); + pool.api.increment_nonce(Alice.into()); + pool.api.increment_nonce(Dave.into()); + + let d0; + + // Block D0 + { + let _ = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, tx0.clone()) + ).expect("1. Imported"); + let header = pool.api.push_block(2, vec![tx0.clone()], true); + assert_eq!(pool.status().ready, 1); + + let event = ChainEvent::NewBestBlock { + hash: header.hash(), + tree_route: None, + }; + d0 = header.hash(); + block_on(pool.maintain(event)); + assert_eq!(pool.status().ready, 0); + } + + // Block D1 + { + let _ = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, tx1.clone()) + ).expect("1. Imported"); + pool.api.push_block(2, vec![tx1.clone()], false); + assert_eq!(pool.status().ready, 1); + } + + // Block D2 + { + let header = pool.api.push_block(2, vec![], false); + let event = block_event_with_retracted(header, d0, &*pool.api); + block_on(pool.maintain(event)); + assert_eq!(pool.status().ready, 2); + } +} + +#[test] +fn resubmit_from_retracted_fork() { + let api = TestApi::empty(); + // starting block A1 (last finalized.) + api.push_block(1, vec![], true); + + let (pool, _background, _) = BasicPool::new_test(api.into()); + + let tx0 = uxt(Alice, 1); + let tx1 = uxt(Dave, 2); + let tx2 = uxt(Bob, 3); + + // Transactions of the fork that will be enacted later + let tx3 = uxt(Eve, 1); + let tx4 = uxt(Ferdie, 2); + let tx5 = uxt(One, 3); + + pool.api.increment_nonce(Alice.into()); + pool.api.increment_nonce(Dave.into()); + pool.api.increment_nonce(Bob.into()); + pool.api.increment_nonce(Eve.into()); + pool.api.increment_nonce(Ferdie.into()); + pool.api.increment_nonce(One.into()); + + // Block D0 + { + let _ = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, tx0.clone()) + ).expect("1. Imported"); + let header = pool.api.push_block(2, vec![tx0.clone()], true); + assert_eq!(pool.status().ready, 1); + + block_on(pool.maintain(block_event(header))); + assert_eq!(pool.status().ready, 0); + } + + // Block E0 + { + let _ = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, tx1.clone()) + ).expect("1. Imported"); + let header = pool.api.push_block(3, vec![tx1.clone()], true); + block_on(pool.maintain(block_event(header))); + assert_eq!(pool.status().ready, 0); + } + + // Block F0 + let f0 = { + let _ = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, tx2.clone()) + ).expect("1. Imported"); + let header = pool.api.push_block(4, vec![tx2.clone()], true); + block_on(pool.maintain(block_event(header.clone()))); + assert_eq!(pool.status().ready, 0); + header.hash() + }; + + // Block D1 + let d1 = { + let _ = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, tx3.clone()) + ).expect("1. Imported"); + let header = pool.api.push_block(2, vec![tx3.clone()], true); + assert_eq!(pool.status().ready, 1); + header.hash() + }; + + // Block E1 + let e1 = { + let _ = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, tx4.clone()) + ).expect("1. Imported"); + let header = pool.api.push_block_with_parent(d1.clone(), vec![tx4.clone()], true); + assert_eq!(pool.status().ready, 2); + header.hash() + }; + + // Block F1 + let f1_header = { + let _ = block_on( + pool.submit_and_watch(&BlockId::number(1), SOURCE, tx5.clone()) + ).expect("1. Imported"); + let header = pool.api.push_block_with_parent(e1.clone(), vec![tx5.clone()], true); + // Don't announce the block event to the pool directly, because we will + // re-org to this block. + assert_eq!(pool.status().ready, 3); + header + }; + + let ready = pool.ready().map(|t| t.data.encode()).collect::>(); + let expected_ready = vec![tx3, tx4, tx5].iter().map(Encode::encode).collect::>(); + assert_eq!(expected_ready, ready); + + let event = block_event_with_retracted(f1_header, f0, &*pool.api); + block_on(pool.maintain(event)); + + assert_eq!(pool.status().ready, 3); + let ready = pool.ready().map(|t| t.data.encode()).collect::>(); + let expected_ready = vec![tx0, tx1, tx2].iter().map(Encode::encode).collect::>(); + assert_eq!(expected_ready, ready); +} + #[test] fn ready_set_should_not_resolve_before_block_update() { let (pool, _guard, _notifier) = maintained_pool(); let xt1 = uxt(Alice, 209); - block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt1.clone())).expect("1. Imported"); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt1.clone())).expect("1. Imported"); assert!(pool.ready_at(1).now_or_never().is_none()); } @@ -631,12 +888,12 @@ fn ready_set_should_not_resolve_before_block_update() { #[test] fn ready_set_should_resolve_after_block_update() { let (pool, _guard, _notifier) = maintained_pool(); - pool.api.push_block(1, vec![]); + let header = pool.api.push_block(1, vec![], true); let xt1 = uxt(Alice, 209); block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt1.clone())).expect("1. Imported"); - block_on(pool.maintain(block_event(1))); + block_on(pool.maintain(block_event(header))); assert!(pool.ready_at(1).now_or_never().is_some()); } @@ -644,7 +901,7 @@ fn ready_set_should_resolve_after_block_update() { #[test] fn ready_set_should_eventually_resolve_when_block_update_arrives() { let (pool, _guard, _notifier) = maintained_pool(); - pool.api.push_block(1, vec![]); + let header = pool.api.push_block(1, vec![], true); let xt1 = uxt(Alice, 209); @@ -658,7 +915,7 @@ fn ready_set_should_eventually_resolve_when_block_update_arrives() { panic!("Ready set should not be ready before block update!"); } - block_on(pool.maintain(block_event(1))); + block_on(pool.maintain(block_event(header))); match ready_set_future.poll_unpin(&mut context) { Poll::Pending => { @@ -676,8 +933,9 @@ fn should_not_accept_old_signatures() { use std::convert::TryFrom; let client = Arc::new(substrate_test_runtime_client::new()); + let pool = Arc::new( - BasicPool::new_test(Arc::new(FullChainApi::new(client))).0 + BasicPool::new_test(Arc::new(FullChainApi::new(client, None))).0 ); let transfer = Transfer { @@ -693,7 +951,11 @@ fn should_not_accept_old_signatures() { "c427eb672e8c441c86d31f1a81b22b43102058e9ce237cabe9897ea5099ffd426cd1c6a1f4f2869c3df57901d36bedcb295657adb3a4355add86ed234eb83108" ).expect("hex invalid")[..]).expect("signature construction failed"); - let xt = Extrinsic::Transfer { transfer, signature: old_singature, exhaust_resources_when_not_first: false }; + let xt = Extrinsic::Transfer { + transfer, + signature: old_singature, + exhaust_resources_when_not_first: false, + }; assert_matches::assert_matches!( block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())), @@ -703,3 +965,76 @@ fn should_not_accept_old_signatures() { "Should be invalid transaction with bad proof", ); } + +#[test] +fn import_notification_to_pool_maintain_works() { + let mut client = Arc::new(substrate_test_runtime_client::new()); + + let pool = Arc::new( + BasicPool::new_test(Arc::new(FullChainApi::new(client.clone(), None))).0 + ); + + // Prepare the extrisic, push it to the pool and check that it was added. + let xt = uxt(Alice, 0); + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); + assert_eq!(pool.status().ready, 1); + + let mut import_stream = block_on_stream(client.import_notification_stream()); + + // Build the block with the transaction included + let mut block_builder = client.new_block(Default::default()).unwrap(); + block_builder.push(xt).unwrap(); + let block = block_builder.build().unwrap().block; + client.import(BlockOrigin::Own, block).unwrap(); + + // Get the notification of the block import and maintain the pool with it, + // Now, the pool should not contain any transactions. + let evt = import_stream.next().expect("Importing a block leads to an event"); + block_on(pool.maintain(evt.try_into().expect("Imported as new best block"))); + assert_eq!(pool.status().ready, 0); +} + +// When we prune transactions, we need to make sure that we remove +#[test] +fn pruning_a_transaction_should_remove_it_from_best_transaction() { + let (pool, _guard, _notifier) = maintained_pool(); + + let xt1 = Extrinsic::IncludeData(Vec::new()); + + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt1.clone())).expect("1. Imported"); + let header = pool.api.push_block(1, vec![xt1.clone()], true); + + // This will prune `xt1`. + block_on(pool.maintain(block_event(header))); + + // Submit the tx again. + block_on(pool.submit_one(&BlockId::number(1), SOURCE, xt1.clone())).expect("2. Imported"); + + let mut iterator = block_on(pool.ready_at(1)); + + assert_eq!(iterator.next().unwrap().data, xt1.clone()); + + // If the tx was not removed from the best txs, the tx would be + // returned a second time by the iterator. + assert!(iterator.next().is_none()); +} + +#[test] +fn only_revalidate_on_best_block() { + let xt = uxt(Alice, 209); + + let (pool, _guard, mut notifier) = maintained_pool(); + + block_on(pool.submit_one(&BlockId::number(0), SOURCE, xt.clone())).expect("1. Imported"); + assert_eq!(pool.status().ready, 1); + + let header = pool.api.push_block(1, vec![], true); + + pool.api.push_block(2, vec![], false); + pool.api.push_block(2, vec![], false); + + block_on(pool.maintain(block_event(header))); + block_on(notifier.next()); + + assert_eq!(pool.status().ready, 1); +} diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 31e489ffe5dbfef804345b361dbfd21493143529..254c64819bd6aebd8f7eb758023af567a43e32c9 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,6 +6,212 @@ The format is based on [Keep a Changelog]. ## Unreleased +## 2.0.0-rc5 -> 2.0.0-rc6 – Rock Hyrax + +Runtime +------- + +* Custom Codec Implenetation for NPoS Election (#6720) +* Successful `note_imminent_preimage` is free (#6793) +* pallet-democracy use of weightinfo (#6783) +* Update Balances Pallet to use `WeightInfo` (#6610) +* pallet-evm: add builtin support for the four basic Ethereum precompiles (#6743) +* Allow `PostDispatchInfo` to disable fees (#6749) +* pallet-evm: add support for tuple-based precompile declarations (#6681) +* grandpa: allow noting that the set has stalled (#6725) + +Client +------ + +* Merge Subkey into sc-cli (#4954) +* RpcHandlers Refactorings (#6846) +* client/authority-discovery: Introduce AuthorityDiscoveryService (#6760) +* Implement tracing::Event handling & parent_id for spans and events (#6672) +* Move to upstream wasmtime, refactor globals snapshot (#6759) +* Revalidate transactions only on latest best block (#6824) +* Allow task manager to have children (#6771) +* client/network: Expose DHT query duration to Prometheus (#6784) +* client/network: Add peers to DHT only if protocols match (#6549) +* Name all the tasks! (#6726) +* Child nodes can be handled by adding a child `TaskManager` to the parent's `TaskManager` (#6771) + +API +--- + +* pow: add access to pre-digest for algorithm verifiers (#6900) +* babe, aura, pow: only call check_inherents if authoring version is compatible (#6862) +* Implement 'transactional' annotation for runtime functions. (#6763) +* seal: Change prefix and module name from "ext_" to "seal_" for contract callable functions (#6798) +* Add Subscription RPC for Grandpa Finality (#5732) +* seal: Fix and improve error reporting (#6773) +* Allow blacklisting blocks from being finalized again after block revert (#6301) +* BABE slot and epoch event notifications (#6563) +* Add `memory-tracker` feature to `sp-trie` to fix wasm panic (#6745) + +## 2.0.0-rc4 -> 2.0.0-rc5 – River Dolphin + +Runtime +------- + +* Support using system storage directly for EVM balance and nonce (#6659) +* Properly filter out duplicate voters in elections. (#6693) +* Treasury burning can be directed (#6671) +* identity: Don't let subs be re-registered (#6667) +* Regression test to ensure we don't break deterministic builds in wasm (#6597) +* allow to specify schedule time as a relative value (#6578) +* Make signature batching use specialized methods (#6616) +* Rename `CheckEra` to `CheckMortality` (#6619) +* Add `WeightInfo` to all pallets with benchmarks. (#6575) +* Don't require module name in inherents (#6576) +* pallet-evm: return Ok(()) when EVM execution fails (#6493) +* Make the encoded-Call Vec explicitly so in metadata (#6566) +* Allow specify schedule dispatch origin (#6387) +* pallet-evm: customizable chain id (#6537) +* Refactor as_sub to make things clearer. (#6503) + +Client +------ + +* Update wasmtime to (almost) lastest master (#6662) +* Update to latest sysinfo prevents leaking fd-handlers (#6708) +* Tracing values (#6679) +* Graceful shutdown for the task manager (#6654) +* Update substrate-networking Grafana dashboard (#6649) +* *: Update to libp2p v0.21.1 (#6559) +* Send Status message on all newly-opened legacy substreams (#6593) +* babe: report equivocations (#6362) +* Support synching of blocks that are not `new_best` (#6508) +* Remove the service, replacing it with a struct of individual chain components (#6352) +* Fix tx-pool returning the same transaction multiple times (#6535) + +API +--- + +* Better handling of stable-only build (#6569) +* Remove the service builder (#6557) +* seal: Prevent contracts from going below subsistence (#6623) +* seal: Rework contracts API (#6573) +* Make evm errors public (#6598) +* Add log rotation (#6564) +* decl_module! macro: use 'frame_system' instead of `system` as default ident (#6500) +* Restrict `Protected` to some heap types. (#6471) + +## 2.0.0-rc3 -> 2.0.0-rc4 (Rhinoceros) + +Runtime +------- + +* Staking Payout Creates Controller (#6496) +* `pallet-scheduler`: Check that `when` is not in the past (#6480) +* Fix `sp-api` handling of multiple arguments (#6484) +* Fix issues with `Operational` transactions validity and prioritization. (#6435) +* pallet-atomic-swap: generialized swap action (#6421) +* Avoid multisig reentrancy (#6445) +* Root origin use no filter by default. Scheduler and Democracy dispatch without asserting BaseCallFilter (#6408) +* Scale and increase validator count (#6417) +* Pallet: Atomic Swap (#6349) +* Restrict remove_proxies (#6383) +* Stored call in multisig (#6319) +* Allow Sudo to do anything (#6375) +* vesting: Force Vested Transfer (#6368) +* Add events for balance reserve and unreserve functions (#6330) +* Introduce frozen indices. (#6307) + +Client +------ + +* client/network/service: Add primary dimension to connection metrics (#6472) +* Fix Babe secondary plain slots claiming (#6451) +* add network propagated metrics (#6438) +* client/authority-discovery: Compare PeerIds and not Multihashes (#6414) +* Update sync chain info on own block import (#6424) +* Remove --legacy-network-protocol CLI flag (#6411) +* Runtime interface to add support for tracing from wasm (#6381) +* Remove penalty on duplicate Status message (#6377) +* Fix the broken weight multiplier update function (#6334) +* client/authority-discovery: Don't add own address to priority group (#6370) +* Split the service initialisation up into seperate functions (#6332) +* Fix transaction pool event sending (#6341) +* Add a [prefix]_process_start_time_seconds metric (#6315) +* new crate sc-light (#6235) +* Allow adding a prefix to the informant (#6174) + +API +--- + +* seal: Remove ext_dispatch_call and ext_get_runtime_storage (#6464) +* seal: Refactor ext_gas_price (#6478) +* Implement nested storage transactions (#6269) +* Allow empty values in the storage (#6364) +* add system_dryRun (#6300) +* Introduce in-origin filtering (#6318) +* add extend_lock for StorageLock (#6323) +* Deprecate FunctionOf and remove its users (#6340) +* transaction-pool: expose blocking api for tx submission (#6325) + + +## 2.0.0-rc2 -> 2.0.0-rc3 + +Runtime +------- + +* Introduce stacked filtering (#6273) +* Allow "anonymous" proxied accounts (#6236) +* Allow over-weight collective proposals to be closed (#6163) +* Fix Election when ForceNone V1 (#6166) + +Client +------ + +* Make transaction pool prune transactions only of canonical blocks (#6123) +* Rename all the election operations (#6245) +* Sentry nodes and validator nodes also imply reserved (#6251) +* Fix peerset not filtering incoming connections in reserved-only (#6249) +* Use Subscription Manager from `jsonrpc-pubsub` (#6208) +* Add a Substrate networking Grafana dashboard template (#6171) +* Add subkey inspect-node-key (#6153) + +## 2.0.0-rc1 -> 2.0.0-rc2 + +(nothing of note) + +## 2.0.0-alpha.8 -> 2.0.0-rc1 + +Runtime +------- + +* Allow operational recovery path if on_initialize use fullblock. (#6089) +* Maximum extrinsic weight limit (#6067) + +Client +------ + +* Add JSON format to import blocks and set it as default (#5816) +* Upgrade to libp2p v0.19 - Changes the default PeerId representation (#6064) + + +## 2.0.0-alpha.7 -> 2.0.0-alpha.8 + +**License Changed** +From this release forward, the code is released under a new – more relaxed – license scheme: Client (`sc-*`) is released under "GPL 3.0 or newer with the Classpath Exception", while primitives, FRAME, the pallets, utils and test-utils are released under "Apache 2.0". More details in the [Relax licensing scheme PR](https://github.com/paritytech/substrate/pull/5947). + +Runtime +------- + +* Democracy weight (#5828) +* Make `Digest` support `StorageAppend` (#5922) + +Client +------ + +* Meter block import results via prometheus (#6025) +* Added RuntimePublic for ecdsa public key. (#6029) +* Benchmarks for elections-phragmen pallet (#5845) +* Monitor transactions rejected from the pool as invalid (#5992) +* client/network: Remove default Kademlia DHT in favor of per protocol DHT (#5993) +* Allow passing multiple --log CLI options (#5982) +* client: Replace `unsafe_rpc_expose` with an `RpcMethods` enum (#5729) + ## 2.0.0-alpha.6 -> 2.0.0-alpha.7 Runtime diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 7559a9ee2b27f547fae30ea98ace8f8ad8e694f4..d9342de399503bd157ebb9779ee38db1ecda736f 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -18,15 +18,7 @@ # are more recognizable on GitHub, you can use them for mentioning unlike an email. # - The latest matching rule, if multiple, takes precedence. -# Wasm execution and the wasm side of Substrate Runtime Interface -/client/executor/ @pepyakin -/primitives/io/ @pepyakin @NikVolf - -# Crypto, execution extensions, etc. -/primitives/core/ @NikVolf - # Block production -/primitives/authorship/ @NikVolf /client/basic-authorship/ @NikVolf # Sandboxing capability of Substrate Runtime @@ -41,45 +33,32 @@ /client/offchain/ @tomusdrw /primitives/offchain/ @tomusdrw -# Everything that has RPC in it -/bin/node/rpc/ @tomusdrw -/bin/node/rpc-client/ @tomusdrw -/client/rpc/ @tomusdrw -/primitives/rpc/ @tomusdrw - # GRANDPA, BABE, consensus stuff -/frame/babe/ @andresilva @DemiMarie-parity +/frame/babe/ @andresilva /frame/grandpa/ @andresilva /client/finality-grandpa/ @andresilva -/client/consensus/babe/ @andresilva @DemiMarie-parity -/client/consensus/slots/ @andresilva @DemiMarie-parity +/client/consensus/babe/ @andresilva +/client/consensus/slots/ @andresilva /client/consensus/pow/ @sorpaas /primitives/consensus/pow/ @sorpaas # Contracts /frame/contracts/ @pepyakin -/frame/contracts/src/wasm/runtime.rs @Robbepop # EVM /frame/evm/ @sorpaas -# NPoS and Governance and Phragmén +# NPoS and election /frame/staking/ @kianenigma /frame/elections/ @kianenigma /frame/elections-phragmen/ @kianenigma -/primitives/phragmen/ @kianenigma +/primitives/npos-elections/ @kianenigma # Fixed point arithmetic /primitives/sp-arithmetic/ @kianenigma -# End to end testing of substrate node -/bin/node/executor/ @kianenigma - # Transaction weight stuff -/frame/support/src/weights.rs @kianenigma - -# Support crates -/frame/support/ @kianenigma +/frame/support/src/weights.rs @shawntabrizi # Authority discovery /client/authority-discovery/ @mxinden @@ -87,7 +66,3 @@ # Prometheus endpoint /utils/prometheus/ @mxinden - -# CLI API -/client/cli @cecton -/client/cli-derive @cecton diff --git a/docs/CODE_OF_CONDUCT.adoc b/docs/CODE_OF_CONDUCT.md similarity index 77% rename from docs/CODE_OF_CONDUCT.adoc rename to docs/CODE_OF_CONDUCT.md index 0f7de7c7efee14bc03258e0aa4f5e7771a912067..400c9b3901e26a7e5a1840816897ed31927156f5 100644 --- a/docs/CODE_OF_CONDUCT.adoc +++ b/docs/CODE_OF_CONDUCT.md @@ -1,10 +1,10 @@ -= Contributor Covenant Code of Conduct +# Contributor Covenant Code of Conduct -== Our Pledge +## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. -== Our Standards +## Our Standards Examples of behavior that contributes to creating a positive environment include: @@ -22,29 +22,31 @@ Examples of unacceptable behavior by participants include: * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting -=== Facilitation, Not Strong Arming +### Facilitation, Not Strongarming -We recognize that this software is merely a tool for users to create and maintain their blockchain of preference. We see that blockchains are naturally community platforms with users being the ultimate decision makers. We assert that good software will maximize user agency by facilitate user-expression on the network. As such: +We recognise that this software is merely a tool for users to create and maintain their blockchain of preference. We see that blockchains are naturally community platforms with users being the ultimate decision makers. We assert that good software will maximise user agency by facilitate user-expression on the network. As such: * This project will strive to give users as much choice as is both reasonable and possible over what protocol they adhere to; but * use of the project's technical forums, commenting systems, pull requests and issue trackers as a means to express individual protocol preferences is forbidden. -== Our Responsibilities +## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. -== Scope +## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. -== Enforcement +## Enforcement -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at admin@parity.io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at . The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. -== Attribution +## Attribution -This Code of Conduct is adapted from the http://contributor-covenant.org[Contributor Covenant], version 1.4, available at http://contributor-covenant.org/version/1/4 +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://contributor-covenant.org/version/1/4 + +[homepage]: https://contributor-covenant.org diff --git a/docs/CONTRIBUTING.adoc b/docs/CONTRIBUTING.adoc index b573aef50d874b304f3b135b4cffd08811fcfdea..491e24aeaec8516a60dc2d7d2ca49d4ba599ab62 100644 --- a/docs/CONTRIBUTING.adoc +++ b/docs/CONTRIBUTING.adoc @@ -14,22 +14,35 @@ There are a few basic ground-rules for contributors (including the maintainer(s) . **Non-master branches**, prefixed with a short name moniker (e.g. `gav-my-feature`) must be used for ongoing work. . **All modifications** must be made in a **pull-request** to solicit feedback from other contributors. . A pull-request *must not be merged until CI* has finished successfully. -. Contributors should adhere to the https://wiki.parity.io/Substrate-Style-Guide[house coding style]. +. Contributors should adhere to the ./STYLE_GUIDE.md[house coding style]. == Merge Process -Merging pull requests once CI is successful: +*In General* -. A PR needs to be reviewed and approved by project maintainers unless: - - it does not alter any logic (e.g. comments, dependencies, docs), then it may be tagged https://github.com/paritytech/substrate/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+label%3AA2-insubstantial[`insubstantial`] and merged by its author once CI is complete. - - it is an urgent fix with no large change to logic, then it may be merged after a non-author contributor has approved the review once CI is complete. +A PR needs to be reviewed and approved by project maintainers unless: +- it does not alter any logic (e.g. comments, dependencies, docs), then it may be tagged https://github.com/paritytech/substrate/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Aopen+label%3AA2-insubstantial[`insubstantial`] and merged by its author once CI is complete. +- it is an urgent fix with no large change to logic, then it may be merged after a non-author contributor has approved the review once CI is complete. + +*Labels TLDR:* + +- `A-*` Pull request status. ONE REQUIRED. +- `B-*` Changelog and/or Runtime-upgrade post composition markers. ONE REQUIRED. (used by automation) +- `C-*` Release notes release-priority markers. EXACTLY ONE REQUIRED. (used by automation) +- `D-*` More general tags on the PR denoting various implications and requirements. + +*Process:* + +. Please tag each PR with exactly one `A`, `B` and `C` label at the minimum. . Once a PR is ready for review please add the https://github.com/paritytech/substrate/pulls?q=is%3Apr+is%3Aopen+label%3AA0-pleasereview[`A0-pleasereview`] label. Generally PRs should sit with this label for 48 hours in order to garner feedback. It may be merged before if all relevant parties had a look at it. -. If the first review is not an approval, swap `A0-pleasereview` to any label `[A3, A7]` to indicate that the PR has received some feedback, but needs further work. For example. https://github.com/paritytech/substrate/labels/A3-inprogress[`A3-inprogress`] is a general indicator that the PR is work in progress and https://github.com/paritytech/substrate/labels/A4-gotissues[`A4-gotissues`] means that it has significant problems that need fixing. Once the work is done, change the label back to `A0-pleasereview`. You might end up swapping a few times back and forth to climb up the A label group. Once a PR is https://github.com/paritytech/substrate/labels/A8-mergeoncegreen[`A8-mergeoncegreen`], it is ready to merge. +. If the first review is not an approval, swap `A0-pleasereview` to any label `[A3, A7]` to indicate that the PR has received some feedback, but needs further work. For example. https://github.com/paritytech/substrate/labels/A3-inprogress[`A3-inprogress`] is a general indicator that the PR is work in progress and https://github.com/paritytech/substrate/labels/A4-gotissues[`A4-gotissues`] means that it has significant problems that need fixing. Once the work is done, change the label back to `A0-pleasereview`. You might end up swapping a few times back and forth to climb up the A label group. Once a PR is https://github.com/paritytech/substrate/labels/A8-mergeoncegreen[`A8-mergeoncegreen`], it is ready to merge. . PRs must be tagged with respect to _release notes_ with https://github.com/paritytech/substrate/labels/B0-silent[`B0-silent`] and `B1-..`. The former indicates that no changes should be mentioned in any release notes. The latter indicates that the changes should be reported in the corresponding release note -. PRs that break the external API must be tagged with https://github.com/paritytech/substrate/labels/B2-breaksapi[`B2-breaksapi`], when it changes the FRAME or consensus of running system with https://github.com/paritytech/substrate/labels/B3-breaksconsensus[`B3-breaksconsensus`] -. No PR should be merged until all reviews' comments are addressed. +. PRs that break the external API must be tagged with https://github.com/paritytech/substrate/labels/D2-breaksapi[`D2-breaksapi`], when it changes the FRAME or consensus of running system with https://github.com/paritytech/substrate/labels/B3-breaksconsensus[`B3-breaksconsensus`]. +. PRs should be labeled with their release importance via the `C1-C9`. +. PRs should be categorized into projects. +. No PR should be merged until all reviews' comments are addressed and CI is successful. *Reviewing pull requests*: @@ -49,19 +62,19 @@ When reviewing a pull request, the end-goal is to suggest useful changes to the === Updating Polkadot as well -**All pull requests will be checked agains either Polkadot master, or your provided Polkadot companion PR**. That is, If your PR changes the external APIs or interfaces used by Polkadot. If you tagged the PR with `breaksapi` or `breaksconsensus` this is most certainly the case, in all other cases check for it by running step 1 below. +**All pull requests will be checked against either Polkadot master, or your provided Polkadot companion PR**. That is, If your PR changes the external APIs or interfaces used by Polkadot. If you tagged the PR with `breaksapi` or `breaksconsensus` this is most certainly the case, in all other cases check for it by running step 1 below. To create a Polkadot companion PR: . Pull latest Polkadot master (or clone it, if you haven't yet). . Override your local cargo config to point to your local substrate (pointing to your WIP branch): place `paths = ["path/to/substrate"]` in `~/.cargo/config`. . Make the changes required and build polkadot locally. -. Submit all this as a PR against the Polkadot Repo. Link to your Polkadot PR in the _description_ of your Substrate PR as "polkadot companion: [URL]" OR use the same name for your Polkdadot branch as the Substrate branch. +. Submit all this as a PR against the Polkadot Repo. Link to your Polkadot PR in the _description_ of your Substrate PR as "polkadot companion: [URL]" . Now you should see that the `check_polkadot` CI job will build your Substrate PR agains the mentioned Polkadot branch in your PR description. . Wait for reviews on both -. Once both PRs have been green lit, they can both be merged 🍻. +. Once both PRs have been green lit, they can both be merged 🍻. -If your PR is reviewed well, but a Polkadot PR is missing, signal it with https://github.com/paritytech/substrate/labels/A7-needspolkadotpr[`A7-needspolkadotpr`] to prevent it from getting automatically merged. +If your PR is reviewed well, but a Polkadot PR is missing, signal it with https://github.com/paritytech/substrate/labels/A7-needspolkadotpr[`A7-needspolkadotpr`] to prevent it from getting automatically merged. As there might be multiple pending PRs that might conflict with one another, a) you should not merge the substrate PR until the Polkadot PR has also been reviewed and b) both should be merged pretty quickly after another to not block others. @@ -69,6 +82,14 @@ As there might be multiple pending PRs that might conflict with one another, a) We use https://github.com/paritytech/substrate/labels[labels] to manage PRs and issues and communicate state of a PR. Please familiarize yourself with them. Furthermore we are organizing issues in https://github.com/paritytech/substrate/milestones[milestones]. Best way to get started is to a pick a ticket from the current milestone tagged https://github.com/paritytech/substrate/issues?q=is%3Aissue+is%3Aopen+label%3AQ2-easy[`easy`] or https://github.com/paritytech/substrate/issues?q=is%3Aissue+is%3Aopen+label%3AQ3-medium[`medium`] and get going or https://github.com/paritytech/substrate/issues?q=is%3Aissue+is%3Aopen+label%3AX1-mentor[`mentor`] and get in contact with the mentor offering their support on that larger task. +== Issues +Please label issues with the following labels: + +. `I-*` Issue severity and type. EXACTLY ONE REQUIRED. +. `P-*` Issue priority. AT MOST ONE ALLOWED. +. `Q-*` Issue difficulty. AT MOST ONE ALLOWED. +. `Z-*` More general tags on the issue, denoting context and resolution. + == Releases Declaring formal releases remains the prerogative of the project maintainer(s). diff --git a/docs/PULL_REQUEST_TEMPLATE.md b/docs/PULL_REQUEST_TEMPLATE.md index fa2c15e6c02fea0f8f8bba9e27059f0e0617b2d6..8ca6ba9b01fe21795d8ce57a99c736ac67220586 100644 --- a/docs/PULL_REQUEST_TEMPLATE.md +++ b/docs/PULL_REQUEST_TEMPLATE.md @@ -6,17 +6,24 @@ Before you submitting, please check that: - What does it do? - What important points reviewers should know? - Is there something left for follow-up PRs? -- [ ] You labeled the PR with appropriate labels if you have permissions to do so. +- [ ] You labeled the PR appropriately if you have permissions to do so: + - [ ] `A*` for PR status (**one required**) + - [ ] `B*` for changelog (**one required**) + - [ ] `C*` for release notes (**exactly one required**) + - [ ] `D*` for various implications/requirements + - [ ] Github's project assignment - [ ] You mentioned a related issue if this PR related to it, e.g. `Fixes #228` or `Related #1337`. - [ ] You asked any particular reviewers to review. If you aren't sure, start with GH suggestions. -- [ ] Your PR adheres [the style guide](https://wiki.parity.io/Substrate-Style-Guide) - - In particular, mind the maximal line length. +- [ ] Your PR adheres to [the style guide](https://wiki.parity.io/Substrate-Style-Guide) + - In particular, mind the maximal line length of 100 (120 in exceptional circumstances). - There is no commented code checked in unless necessary. - Any panickers have a proof or removed. - [ ] You bumped the runtime version if there are breaking changes in the **runtime**. - [ ] You updated any rustdocs which may have changed - [ ] Has the PR altered the external API or interfaces used by Polkadot? Do you have the corresponding Polkadot PR ready? +Refer to [the contributing guide](https://github.com/paritytech/substrate/blob/master/docs/CONTRIBUTING.adoc) for details. + After you've read this notice feel free to remove it. Thank you! diff --git a/docs/README.adoc b/docs/README.adoc index 51e7748b67c094194e8b1a810fe92e8cfe4d32d8..d1daeed07b5dc2c47bc934d4265d09d35bc48ea9 100644 --- a/docs/README.adoc +++ b/docs/README.adoc @@ -523,7 +523,7 @@ include::CONTRIBUTING.adoc[] === Contributor Code of Conduct -include::CODE_OF_CONDUCT.adoc[] +include::CODE_OF_CONDUCT.md[] == License diff --git a/docs/STYLE_GUIDE.md b/docs/STYLE_GUIDE.md new file mode 100644 index 0000000000000000000000000000000000000000..e6f217f2b4859efea50393e76a568a42d3e45f2a --- /dev/null +++ b/docs/STYLE_GUIDE.md @@ -0,0 +1,146 @@ +--- +title: Style Guide for Rust in Substrate +--- + +# Formatting + +- Indent using tabs. +- Lines should be longer than 100 characters long only in exceptional circumstances and certainly + no longer than 120. For this purpose, tabs are considered 4 characters wide. +- Indent levels should be greater than 5 only in exceptional circumstances and certainly no + greater than 8. If they are greater than 5, then consider using `let` or auxiliary functions in + order to strip out complex inline expressions. +- Never have spaces on a line prior to a non-whitespace character +- Follow-on lines are only ever a single indent from the original line. + +```rust +fn calculation(some_long_variable_a: i8, some_long_variable_b: i8) -> bool { + let x = some_long_variable_a * some_long_variable_b + - some_long_variable_b / some_long_variable_a + + sqrt(some_long_variable_a) - sqrt(some_long_variable_b); + x > 10 +} +``` + +- Indent level should follow open parens/brackets, but should be collapsed to the smallest number + of levels actually used: + +```rust +fn calculate( + some_long_variable_a: f32, + some_long_variable_b: f32, + some_long_variable_c: f32, +) -> f32 { + (-some_long_variable_b + sqrt( + // two parens open, but since we open & close them both on the + // same line, only one indent level is used + some_long_variable_b * some_long_variable_b + - 4 * some_long_variable_a * some_long_variable_c + // both closed here at beginning of line, so back to the original indent + // level + )) / (2 * some_long_variable_a) +} +``` + +- `where` is indented, and its items are indented one further. +- Argument lists or function invocations that are too long to fit on one line are indented + similarly to code blocks, and once one param is indented in such a way, all others should be, + too. Run-on parameter lists are also acceptable for single-line run-ons of basic function calls. + +```rust +// OK +fn foo( + really_long_parameter_name_1: SomeLongTypeName, + really_long_parameter_name_2: SomeLongTypeName, + shrt_nm_1: u8, + shrt_nm_2: u8, +) { + ... +} + +// NOT OK +fn foo(really_long_parameter_name_1: SomeLongTypeName, really_long_parameter_name_2: SomeLongTypeName, + shrt_nm_1: u8, shrt_nm_2: u8) { + ... +} +``` + +```rust +{ + // Complex line (not just a function call, also a let statement). Full + // structure. + let (a, b) = bar( + really_long_parameter_name_1, + really_long_parameter_name_2, + shrt_nm_1, + shrt_nm_2, + ); + + // Long, simple function call. + waz( + really_long_parameter_name_1, + really_long_parameter_name_2, + shrt_nm_1, + shrt_nm_2, + ); + + // Short function call. Inline. + baz(a, b); +} +``` + +- Always end last item of a multi-line comma-delimited set with `,` when legal: + +```rust +struct Point { + x: T, + y: T, // <-- Multiline comma-delimited lists end with a trailing , +} + +// Single line comma-delimited items do not have a trailing `,` +enum Meal { Breakfast, Lunch, Dinner }; +``` + +- Avoid trailing `;`s where unneeded. + +```rust +if condition { + return 1 // <-- no ; here +} +``` + +- `match` arms may be either blocks or have a trailing `,` but not both. +- Blocks should not be used unnecessarily. + +```rust +match meal { + Meal::Breakfast => "eggs", + Meal::Lunch => { check_diet(); recipe() }, +// Meal::Dinner => { return Err("Fasting") } // WRONG + Meal::Dinner => return Err("Fasting"), +} +``` + +# Style + +- Panickers require explicit proofs they don't trigger. Calling `unwrap` is discouraged. The + exception to this rule is test code. Avoiding panickers by restructuring code is preferred if + feasible. + +```rust +let mut target_path = + self.path().expect( + "self is instance of DiskDirectory;\ + DiskDirectory always returns path;\ + qed" + ); +``` + +- Unsafe code requires explicit proofs just as panickers do. When introducing unsafe code, + consider tradeoffs between efficiency on one hand and reliability, maintenance costs, and + security on the other. Here is a list of questions that may help evaluating the tradeoff while + preparing or reviewing a PR: + - how much more performant or compact the resulting code will be using unsafe code, + - how likely is it that invariants could be violated, + - are issues stemming from the use of unsafe code caught by existing tests/tooling, + - what are the consequences if the problems slip into production. diff --git a/docs/media/sub.gif b/docs/media/sub.gif new file mode 100644 index 0000000000000000000000000000000000000000..d8d73d9171aac0751961206256cf1d219416814e Binary files /dev/null and b/docs/media/sub.gif differ diff --git a/frame/assets/Cargo.toml b/frame/assets/Cargo.toml index 4e09ea8aa51e8f5f39d87e5ea8294fca26f065e4..bb7c2828c3062d7818aa2613475c9d05a105e547 100644 --- a/frame/assets/Cargo.toml +++ b/frame/assets/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-assets" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME asset management pallet" @@ -13,18 +13,18 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] serde = { version = "1.0.101", optional = true } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } # Needed for various traits. In our case, `OnFinalize`. -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } # Needed for type-safe access to storage DB. -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } # `system` module provides us with all sorts of useful stuff and macros depend on it being around. -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } -sp-std = { version = "2.0.0-dev", path = "../../primitives/std" } -sp-io = { version = "2.0.0-dev", path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-std = { version = "2.0.0-rc6", path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } [features] default = ["std"] diff --git a/frame/assets/README.md b/frame/assets/README.md new file mode 100644 index 0000000000000000000000000000000000000000..dca51b7c296f115f9e253041f66f0c5d3a1f127b --- /dev/null +++ b/frame/assets/README.md @@ -0,0 +1,116 @@ +# Assets Module + +A simple, secure module for dealing with fungible assets. + +## Overview + +The Assets module provides functionality for asset management of fungible asset classes +with a fixed supply, including: + +* Asset Issuance +* Asset Transfer +* Asset Destruction + +To use it in your runtime, you need to implement the assets [`Trait`](./trait.Trait.html). + +The supported dispatchable functions are documented in the [`Call`](./enum.Call.html) enum. + +### Terminology + +* **Asset issuance:** The creation of a new asset, whose total supply will belong to the + account that issues the asset. +* **Asset transfer:** The action of transferring assets from one account to another. +* **Asset destruction:** The process of an account removing its entire holding of an asset. +* **Fungible asset:** An asset whose units are interchangeable. +* **Non-fungible asset:** An asset for which each unit has unique characteristics. + +### Goals + +The assets system in Substrate is designed to make the following possible: + +* Issue a unique asset to its creator's account. +* Move assets between accounts. +* Remove an account's balance of an asset when requested by that account's owner and update + the asset's total supply. + +## Interface + +### Dispatchable Functions + +* `issue` - Issues the total supply of a new fungible asset to the account of the caller of the function. +* `transfer` - Transfers an `amount` of units of fungible asset `id` from the balance of +the function caller's account (`origin`) to a `target` account. +* `destroy` - Destroys the entire holding of a fungible asset `id` associated with the account +that called the function. + +Please refer to the [`Call`](./enum.Call.html) enum and its associated variants for documentation on each function. + +### Public Functions + + +* `balance` - Get the asset `id` balance of `who`. +* `total_supply` - Get the total supply of an asset `id`. + +Please refer to the [`Module`](./struct.Module.html) struct for details on publicly available functions. + +## Usage + +The following example shows how to use the Assets module in your runtime by exposing public functions to: + +* Issue a new fungible asset for a token distribution event (airdrop). +* Query the fungible asset holding balance of an account. +* Query the total supply of a fungible asset that has been issued. + +### Prerequisites + +Import the Assets module and types and derive your runtime's configuration traits from the Assets module trait. + +### Simple Code Snippet + +```rust +use pallet_assets as assets; +use frame_support::{decl_module, dispatch, ensure}; +use frame_system::ensure_signed; + +pub trait Trait: assets::Trait { } + +decl_module! { + pub struct Module for enum Call where origin: T::Origin { + pub fn issue_token_airdrop(origin) -> dispatch::DispatchResult { + let sender = ensure_signed(origin).map_err(|e| e.as_str())?; + + const ACCOUNT_ALICE: u64 = 1; + const ACCOUNT_BOB: u64 = 2; + const COUNT_AIRDROP_RECIPIENTS: u64 = 2; + const TOKENS_FIXED_SUPPLY: u64 = 100; + + ensure!(!COUNT_AIRDROP_RECIPIENTS.is_zero(), "Divide by zero error."); + + let asset_id = Self::next_asset_id(); + + >::mutate(|asset_id| *asset_id += 1); + >::insert((asset_id, &ACCOUNT_ALICE), TOKENS_FIXED_SUPPLY / COUNT_AIRDROP_RECIPIENTS); + >::insert((asset_id, &ACCOUNT_BOB), TOKENS_FIXED_SUPPLY / COUNT_AIRDROP_RECIPIENTS); + >::insert(asset_id, TOKENS_FIXED_SUPPLY); + + Self::deposit_event(RawEvent::Issued(asset_id, sender, TOKENS_FIXED_SUPPLY)); + Ok(()) + } + } +} +``` + +## Assumptions + +Below are assumptions that must be held when using this module. If any of +them are violated, the behavior of this module is undefined. + +* The total count of assets should be less than + `Trait::AssetId::max_value()`. + +## Related Modules + +* [`System`](../frame_system/index.html) +* [`Support`](../frame_support/index.html) + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 1aaedd4c74d79ce948606481249c538de95308f9..79bc9136ef4a70d737d2a4e59fe6448c58c971af 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Assets Module //! @@ -86,7 +87,7 @@ //! ```rust,ignore //! use pallet_assets as assets; //! use frame_support::{decl_module, dispatch, ensure}; -//! use frame_system::{self as system, ensure_signed}; +//! use frame_system::ensure_signed; //! //! pub trait Trait: assets::Trait { } //! @@ -133,8 +134,8 @@ #![cfg_attr(not(feature = "std"), no_std)] use frame_support::{Parameter, decl_module, decl_event, decl_storage, decl_error, ensure}; -use sp_runtime::traits::{Member, AtLeast32Bit, Zero, StaticLookup}; -use frame_system::{self as system, ensure_signed}; +use sp_runtime::traits::{Member, AtLeast32Bit, AtLeast32BitUnsigned, Zero, StaticLookup}; +use frame_system::ensure_signed; use sp_runtime::traits::One; /// The module configuration trait. @@ -143,7 +144,7 @@ pub trait Trait: frame_system::Trait { type Event: From> + Into<::Event>; /// The units in which we record balances. - type Balance: Member + Parameter + AtLeast32Bit + Default + Copy; + type Balance: Member + Parameter + AtLeast32BitUnsigned + Default + Copy; /// The arithmetic type of asset identifier. type AssetId: Parameter + AtLeast32Bit + Default + Copy; @@ -229,11 +230,11 @@ decl_event! { ::Balance, ::AssetId, { - /// Some assets were issued. + /// Some assets were issued. [asset_id, owner, total_supply] Issued(AssetId, AccountId, Balance), - /// Some assets were transferred. + /// Some assets were transferred. [asset_id, from, to, amount] Transferred(AssetId, AccountId, AccountId, Balance), - /// Some assets were destroyed. + /// Some assets were destroyed. [asset_id, owner, balance] Destroyed(AssetId, AccountId, Balance), } } @@ -256,6 +257,8 @@ decl_storage! { /// The next asset identifier up for grabs. NextAssetId get(fn next_asset_id): T::AssetId; /// The total unit supply of an asset. + /// + /// TWOX-NOTE: `AssetId` is trusted, so this is safe. TotalSupply: map hasher(twox_64_concat) T::AssetId => T::Balance; } } @@ -281,17 +284,12 @@ mod tests { use frame_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types, weights::Weight}; use sp_core::H256; - // The testing primitives are very useful for avoiding having to work with signatures - // or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header}; impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } - // For testing the pallet, we construct most of a mock runtime. This means - // first constructing a configuration type (`Test`) which `impl`s each of the - // configuration traits of pallets we want to use. #[derive(Clone, Eq, PartialEq)] pub struct Test; parameter_types! { @@ -301,6 +299,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type Call = (); @@ -316,6 +315,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -323,6 +323,7 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl Trait for Test { type Event = (); @@ -331,8 +332,6 @@ mod tests { } type Assets = Module; - // This function basically just builds a genesis storage key/value store according to - // our desired mockup. fn new_test_ext() -> sp_io::TestExternalities { frame_system::GenesisConfig::default().build_storage::().unwrap().into() } diff --git a/frame/atomic-swap/Cargo.toml b/frame/atomic-swap/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..982cd7d6cb88bedeb977b06c6fcecff0a539baa8 --- /dev/null +++ b/frame/atomic-swap/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "pallet-atomic-swap" +version = "2.0.0-rc6" +authors = ["Parity Technologies "] +edition = "2018" +license = "Apache-2.0" +homepage = "https://substrate.dev" +repository = "https://github.com/paritytech/substrate/" +description = "FRAME atomic swap pallet" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +serde = { version = "1.0.101", optional = true } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } + +[dev-dependencies] +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } + +[features] +default = ["std"] +std = [ + "serde", + "codec/std", + "frame-support/std", + "frame-system/std", + "sp-runtime/std", + "sp-std/std", + "sp-io/std", + "sp-core/std", +] diff --git a/frame/atomic-swap/README.md b/frame/atomic-swap/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f2be32554cb21c78289c85006cd81594e1b3c2bd --- /dev/null +++ b/frame/atomic-swap/README.md @@ -0,0 +1,23 @@ +# Atomic Swap + +A module for atomically sending funds. + +- [`atomic_swap::Trait`](./trait.Trait.html) +- [`Call`](./enum.Call.html) +- [`Module`](./struct.Module.html) + +## Overview + +A module for atomically sending funds from an origin to a target. A proof +is used to allow the target to approve (claim) the swap. If the swap is not +claimed within a specified duration of time, the sender may cancel it. + +## Interface + +### Dispatchable Functions + +* `create_swap` - called by a sender to register a new atomic swap +* `claim_swap` - called by the target to approve a swap +* `cancel_swap` - may be called by a sender after a specified duration + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/atomic-swap/src/lib.rs b/frame/atomic-swap/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..65794792d0aa4ca1368b825e94e2c7eda49c4e7c --- /dev/null +++ b/frame/atomic-swap/src/lib.rs @@ -0,0 +1,322 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! # Atomic Swap +//! +//! A module for atomically sending funds. +//! +//! - [`atomic_swap::Trait`](./trait.Trait.html) +//! - [`Call`](./enum.Call.html) +//! - [`Module`](./struct.Module.html) +//! +//! ## Overview +//! +//! A module for atomically sending funds from an origin to a target. A proof +//! is used to allow the target to approve (claim) the swap. If the swap is not +//! claimed within a specified duration of time, the sender may cancel it. +//! +//! ## Interface +//! +//! ### Dispatchable Functions +//! +//! * `create_swap` - called by a sender to register a new atomic swap +//! * `claim_swap` - called by the target to approve a swap +//! * `cancel_swap` - may be called by a sender after a specified duration + +// Ensure we're `no_std` when compiling for Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +mod tests; + +use sp_std::{prelude::*, marker::PhantomData, ops::{Deref, DerefMut}}; +use sp_io::hashing::blake2_256; +use frame_support::{ + Parameter, decl_module, decl_storage, decl_event, decl_error, ensure, + traits::{Get, Currency, ReservableCurrency, BalanceStatus}, + weights::Weight, + dispatch::DispatchResult, +}; +use frame_system::{self as system, ensure_signed}; +use codec::{Encode, Decode}; +use sp_runtime::RuntimeDebug; + +/// Pending atomic swap operation. +#[derive(Clone, Eq, PartialEq, RuntimeDebug, Encode, Decode)] +pub struct PendingSwap { + /// Source of the swap. + pub source: T::AccountId, + /// Action of this swap. + pub action: T::SwapAction, + /// End block of the lock. + pub end_block: T::BlockNumber, +} + +/// Hashed proof type. +pub type HashedProof = [u8; 32]; + +/// Definition of a pending atomic swap action. It contains the following three phrases: +/// +/// - **Reserve**: reserve the resources needed for a swap. This is to make sure that **Claim** +/// succeeds with best efforts. +/// - **Claim**: claim any resources reserved in the first phrase. +/// - **Cancel**: cancel any resources reserved in the first phrase. +pub trait SwapAction { + /// Reserve the resources needed for the swap, from the given `source`. The reservation is + /// allowed to fail. If that is the case, the the full swap creation operation is cancelled. + fn reserve(&self, source: &AccountId) -> DispatchResult; + /// Claim the reserved resources, with `source` and `target`. Returns whether the claim + /// succeeds. + fn claim(&self, source: &AccountId, target: &AccountId) -> bool; + /// Weight for executing the operation. + fn weight(&self) -> Weight; + /// Cancel the resources reserved in `source`. + fn cancel(&self, source: &AccountId); +} + +/// A swap action that only allows transferring balances. +#[derive(Clone, RuntimeDebug, Eq, PartialEq, Encode, Decode)] +pub struct BalanceSwapAction> { + value: >::Balance, + _marker: PhantomData, +} + +impl BalanceSwapAction where C: ReservableCurrency { + /// Create a new swap action value of balance. + pub fn new(value: >::Balance) -> Self { + Self { value, _marker: PhantomData } + } +} + +impl Deref for BalanceSwapAction where C: ReservableCurrency { + type Target = >::Balance; + + fn deref(&self) -> &Self::Target { + &self.value + } +} + +impl DerefMut for BalanceSwapAction where C: ReservableCurrency { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.value + } +} + +impl SwapAction for BalanceSwapAction + where C: ReservableCurrency +{ + fn reserve(&self, source: &AccountId) -> DispatchResult { + C::reserve(&source, self.value) + } + + fn claim(&self, source: &AccountId, target: &AccountId) -> bool { + C::repatriate_reserved(source, target, self.value, BalanceStatus::Free).is_ok() + } + + fn weight(&self) -> Weight { + T::DbWeight::get().reads_writes(1, 1) + } + + fn cancel(&self, source: &AccountId) { + C::unreserve(source, self.value); + } +} + +/// Atomic swap's pallet configuration trait. +pub trait Trait: frame_system::Trait { + /// The overarching event type. + type Event: From> + Into<::Event>; + /// Swap action. + type SwapAction: SwapAction + Parameter; + /// Limit of proof size. + /// + /// Atomic swap is only atomic if once the proof is revealed, both parties can submit the proofs + /// on-chain. If A is the one that generates the proof, then it requires that either: + /// - A's blockchain has the same proof length limit as B's blockchain. + /// - Or A's blockchain has shorter proof length limit as B's blockchain. + /// + /// If B sees A is on a blockchain with larger proof length limit, then it should kindly refuse + /// to accept the atomic swap request if A generates the proof, and asks that B generates the + /// proof instead. + type ProofLimit: Get; +} + +decl_storage! { + trait Store for Module as AtomicSwap { + pub PendingSwaps: double_map + hasher(twox_64_concat) T::AccountId, hasher(blake2_128_concat) HashedProof + => Option>; + } +} + +decl_error! { + pub enum Error for Module { + /// Swap already exists. + AlreadyExist, + /// Swap proof is invalid. + InvalidProof, + /// Proof is too large. + ProofTooLarge, + /// Source does not match. + SourceMismatch, + /// Swap has already been claimed. + AlreadyClaimed, + /// Swap does not exist. + NotExist, + /// Claim action mismatch. + ClaimActionMismatch, + /// Duration has not yet passed for the swap to be cancelled. + DurationNotPassed, + } +} + +decl_event!( + /// Event of atomic swap pallet. + pub enum Event where + AccountId = ::AccountId, + PendingSwap = PendingSwap, + { + /// Swap created. [account, proof, swap] + NewSwap(AccountId, HashedProof, PendingSwap), + /// Swap claimed. The last parameter indicates whether the execution succeeds. + /// [account, proof, success] + SwapClaimed(AccountId, HashedProof, bool), + /// Swap cancelled. [account, proof] + SwapCancelled(AccountId, HashedProof), + } +); + +decl_module! { + /// Module definition of atomic swap pallet. + pub struct Module for enum Call where origin: T::Origin { + type Error = Error; + + fn deposit_event() = default; + + /// Register a new atomic swap, declaring an intention to send funds from origin to target + /// on the current blockchain. The target can claim the fund using the revealed proof. If + /// the fund is not claimed after `duration` blocks, then the sender can cancel the swap. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `target`: Receiver of the atomic swap. + /// - `hashed_proof`: The blake2_256 hash of the secret proof. + /// - `balance`: Funds to be sent from origin. + /// - `duration`: Locked duration of the atomic swap. For safety reasons, it is recommended + /// that the revealer uses a shorter duration than the counterparty, to prevent the + /// situation where the revealer reveals the proof too late around the end block. + #[weight = T::DbWeight::get().reads_writes(1, 1).saturating_add(40_000_000)] + fn create_swap( + origin, + target: T::AccountId, + hashed_proof: HashedProof, + action: T::SwapAction, + duration: T::BlockNumber, + ) { + let source = ensure_signed(origin)?; + ensure!( + !PendingSwaps::::contains_key(&target, hashed_proof), + Error::::AlreadyExist + ); + + action.reserve(&source)?; + + let swap = PendingSwap { + source, + action, + end_block: frame_system::Module::::block_number() + duration, + }; + PendingSwaps::::insert(target.clone(), hashed_proof.clone(), swap.clone()); + + Self::deposit_event( + RawEvent::NewSwap(target, hashed_proof, swap) + ); + } + + /// Claim an atomic swap. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `proof`: Revealed proof of the claim. + /// - `action`: Action defined in the swap, it must match the entry in blockchain. Otherwise + /// the operation fails. This is used for weight calculation. + #[weight = T::DbWeight::get().reads_writes(1, 1) + .saturating_add(40_000_000) + .saturating_add((proof.len() as Weight).saturating_mul(100)) + .saturating_add(action.weight()) + ] + fn claim_swap( + origin, + proof: Vec, + action: T::SwapAction, + ) -> DispatchResult { + ensure!( + proof.len() <= T::ProofLimit::get() as usize, + Error::::ProofTooLarge, + ); + + let target = ensure_signed(origin)?; + let hashed_proof = blake2_256(&proof); + + let swap = PendingSwaps::::get(&target, hashed_proof) + .ok_or(Error::::InvalidProof)?; + ensure!(swap.action == action, Error::::ClaimActionMismatch); + + let succeeded = swap.action.claim(&swap.source, &target); + + PendingSwaps::::remove(target.clone(), hashed_proof.clone()); + + Self::deposit_event( + RawEvent::SwapClaimed(target, hashed_proof, succeeded) + ); + + Ok(()) + } + + /// Cancel an atomic swap. Only possible after the originally set duration has passed. + /// + /// The dispatch origin for this call must be _Signed_. + /// + /// - `target`: Target of the original atomic swap. + /// - `hashed_proof`: Hashed proof of the original atomic swap. + #[weight = T::DbWeight::get().reads_writes(1, 1).saturating_add(40_000_000)] + fn cancel_swap( + origin, + target: T::AccountId, + hashed_proof: HashedProof, + ) { + let source = ensure_signed(origin)?; + + let swap = PendingSwaps::::get(&target, hashed_proof) + .ok_or(Error::::NotExist)?; + ensure!( + swap.source == source, + Error::::SourceMismatch, + ); + ensure!( + frame_system::Module::::block_number() >= swap.end_block, + Error::::DurationNotPassed, + ); + + swap.action.cancel(&swap.source); + PendingSwaps::::remove(&target, hashed_proof.clone()); + + Self::deposit_event( + RawEvent::SwapCancelled(target, hashed_proof) + ); + } + } +} diff --git a/frame/atomic-swap/src/tests.rs b/frame/atomic-swap/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..6690a24d364d6eaf9a3f34f9990bc4106584dfaa --- /dev/null +++ b/frame/atomic-swap/src/tests.rs @@ -0,0 +1,154 @@ +#![cfg(test)] + +use super::*; + +use frame_support::{ + impl_outer_origin, parameter_types, weights::Weight, +}; +use sp_core::H256; +use sp_runtime::{ + Perbill, + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; + +impl_outer_origin! { + pub enum Origin for Test where system = frame_system {} +} + +#[derive(Clone, Eq, Debug, PartialEq)] +pub struct Test; +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const MaximumBlockWeight: Weight = 1024; + pub const MaximumBlockLength: u32 = 2 * 1024; + pub const AvailableBlockRatio: Perbill = Perbill::one(); +} +impl frame_system::Trait for Test { + type BaseCallFilter = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = (); + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = (); + type BlockHashCount = BlockHashCount; + type MaximumBlockWeight = MaximumBlockWeight; + type DbWeight = (); + type BlockExecutionWeight = (); + type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; + type MaximumBlockLength = MaximumBlockLength; + type AvailableBlockRatio = AvailableBlockRatio; + type Version = (); + type ModuleToIndex = (); + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); +} +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} +impl pallet_balances::Trait for Test { + type Balance = u64; + type DustRemoval = (); + type Event = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); +} +parameter_types! { + pub const ProofLimit: u32 = 1024; + pub const ExpireDuration: u64 = 100; +} +impl Trait for Test { + type Event = (); + type SwapAction = BalanceSwapAction; + type ProofLimit = ProofLimit; +} +type System = frame_system::Module; +type Balances = pallet_balances::Module; +type AtomicSwap = Module; + +const A: u64 = 1; +const B: u64 = 2; + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + let genesis = pallet_balances::GenesisConfig:: { + balances: vec![ + (A, 100), + (B, 200), + ], + }; + genesis.assimilate_storage(&mut t).unwrap(); + t.into() +} + +#[test] +fn two_party_successful_swap() { + let mut chain1 = new_test_ext(); + let mut chain2 = new_test_ext(); + + // A generates a random proof. Keep it secret. + let proof: [u8; 2] = [4, 2]; + // The hashed proof is the blake2_256 hash of the proof. This is public. + let hashed_proof = blake2_256(&proof); + + // A creates the swap on chain1. + chain1.execute_with(|| { + AtomicSwap::create_swap( + Origin::signed(A), + B, + hashed_proof.clone(), + BalanceSwapAction::new(50), + 1000, + ).unwrap(); + + assert_eq!(Balances::free_balance(A), 100 - 50); + assert_eq!(Balances::free_balance(B), 200); + }); + + // B creates the swap on chain2. + chain2.execute_with(|| { + AtomicSwap::create_swap( + Origin::signed(B), + A, + hashed_proof.clone(), + BalanceSwapAction::new(75), + 1000, + ).unwrap(); + + assert_eq!(Balances::free_balance(A), 100); + assert_eq!(Balances::free_balance(B), 200 - 75); + }); + + // A reveals the proof and claims the swap on chain2. + chain2.execute_with(|| { + AtomicSwap::claim_swap( + Origin::signed(A), + proof.to_vec(), + BalanceSwapAction::new(75), + ).unwrap(); + + assert_eq!(Balances::free_balance(A), 100 + 75); + assert_eq!(Balances::free_balance(B), 200 - 75); + }); + + // B use the revealed proof to claim the swap on chain1. + chain1.execute_with(|| { + AtomicSwap::claim_swap( + Origin::signed(B), + proof.to_vec(), + BalanceSwapAction::new(50), + ).unwrap(); + + assert_eq!(Balances::free_balance(A), 100 - 50); + assert_eq!(Balances::free_balance(B), 200 + 50); + }); +} diff --git a/frame/aura/Cargo.toml b/frame/aura/Cargo.toml index 623cf80df7b24a26b7b0d0567e3cfc8e6f7272f3..283462f5cc601c4cc0a2675dec3b983fc13b8d9a 100644 --- a/frame/aura/Cargo.toml +++ b/frame/aura/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-aura" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME AURA consensus pallet" @@ -12,23 +12,23 @@ description = "FRAME AURA consensus pallet" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/application-crypto" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/inherents" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -pallet-session = { version = "2.0.0-dev", default-features = false, path = "../session" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -sp-consensus-aura = { path = "../../primitives/consensus/aura", default-features = false, version = "0.8.0-dev"} -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../primitives/timestamp" } -pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../timestamp" } +pallet-session = { version = "2.0.0-rc6", default-features = false, path = "../session" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +sp-consensus-aura = { version = "0.8.0-rc6", path = "../../primitives/consensus/aura", default-features = false } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +sp-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/timestamp" } +pallet-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../timestamp" } [dev-dependencies] +sp-core = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/core" } +sp-io ={ version = "2.0.0-rc6", path = "../../primitives/io" } lazy_static = "1.4.0" parking_lot = "0.10.0" @@ -38,8 +38,6 @@ std = [ "sp-application-crypto/std", "codec/std", "sp-inherents/std", - "sp-io/std", - "sp-core/std", "sp-std/std", "serde", "sp-runtime/std", diff --git a/frame/aura/README.md b/frame/aura/README.md new file mode 100644 index 0000000000000000000000000000000000000000..59747493193edb1cbdb0ac38a932affc8f4c51d9 --- /dev/null +++ b/frame/aura/README.md @@ -0,0 +1,28 @@ +# Aura Module + +- [`aura::Trait`](./trait.Trait.html) +- [`Module`](./struct.Module.html) + +## Overview + +The Aura module extends Aura consensus by managing offline reporting. + +## Interface + +### Public Functions + +- `slot_duration` - Determine the Aura slot-duration based on the Timestamp module configuration. + +## Related Modules + +- [Timestamp](../pallet_timestamp/index.html): The Timestamp module is used in Aura to track +consensus rounds (via `slots`). + +## References + +If you're interested in hacking on this module, it is useful to understand the interaction with +`substrate/primitives/inherents/src/lib.rs` and, specifically, the required implementation of +[`ProvideInherent`](../sp_inherents/trait.ProvideInherent.html) and +[`ProvideInherentData`](../sp_inherents/trait.ProvideInherentData.html) to create and check inherents. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/aura/src/lib.rs b/frame/aura/src/lib.rs index e2aafde9efe6ef699bcd61ef861fe7104dd7e331..ca3d1f15f421bfae638a69a45f012a76e407e54a 100644 --- a/frame/aura/src/lib.rs +++ b/frame/aura/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Aura Module //! @@ -161,6 +162,27 @@ impl FindAuthor for Module { } } +/// We can not implement `FindAuthor` twice, because the compiler does not know if +/// `u32 == T::AuthorityId` and thus, prevents us to implement the trait twice. +#[doc(hidden)] +pub struct FindAccountFromAuthorIndex(sp_std::marker::PhantomData<(T, Inner)>); + +impl> FindAuthor + for FindAccountFromAuthorIndex +{ + fn find_author<'a, I>(digests: I) -> Option + where I: 'a + IntoIterator + { + let i = Inner::find_author(digests)?; + + let validators = >::authorities(); + validators.get(i as usize).map(|k| k.clone()) + } +} + +/// Find the authority ID of the Aura authority who authored the current block. +pub type AuraAuthorId = FindAccountFromAuthorIndex>; + impl IsMember for Module { fn is_member(authority_id: &T::AuthorityId) -> bool { Self::authorities() diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index 8154ef4c9f50db3dd99a760e4cfd7e8bee00bac8..9277cb14f3002487197f6073357552dd009104ee 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -1,18 +1,19 @@ -// Copyright 2018-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2018-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Test utilities @@ -29,7 +30,7 @@ use sp_io; use sp_core::H256; impl_outer_origin!{ - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } // Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted. @@ -45,6 +46,7 @@ parameter_types! { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -60,6 +62,7 @@ impl frame_system::Trait for Test { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -67,12 +70,14 @@ impl frame_system::Trait for Test { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl pallet_timestamp::Trait for Test { type Moment = u64; type OnTimestampSet = Aura; type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); } impl Trait for Test { diff --git a/frame/aura/src/tests.rs b/frame/aura/src/tests.rs index a7cb5503c4712acb79c0902be5f9a707e6f7ad07..ca0fc3de3763809d1f7d4c50d4adf862b8e9305d 100644 --- a/frame/aura/src/tests.rs +++ b/frame/aura/src/tests.rs @@ -1,18 +1,19 @@ -// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 -// Substrate 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 Substrate. If not, see . +// 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. //! Tests for the module. diff --git a/frame/authority-discovery/Cargo.toml b/frame/authority-discovery/Cargo.toml index 5f267b3159561345bb30d0b734f89b36d25acc6e..26fa250d72034dd96950f6e812f0d6d8c793c55d 100644 --- a/frame/authority-discovery/Cargo.toml +++ b/frame/authority-discovery/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-authority-discovery" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "FRAME pallet for authority discovery" @@ -12,20 +12,20 @@ description = "FRAME pallet for authority discovery" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-authority-discovery = { version = "2.0.0-dev", default-features = false, path = "../../primitives/authority-discovery" } -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } +sp-authority-discovery = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/authority-discovery" } +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/application-crypto" } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } serde = { version = "1.0.101", optional = true } -sp-io = { version = "2.0.0-dev", default-features = false, path = "../../primitives/io" } -pallet-session = { version = "2.0.0-dev", features = ["historical" ], path = "../session", default-features = false } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } +pallet-session = { version = "2.0.0-rc6", features = ["historical" ], path = "../session", default-features = false } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } [dev-dependencies] -sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-io = { version = "2.0.0-rc6", path = "../../primitives/io" } +sp-staking = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/staking" } [features] default = ["std"] @@ -33,8 +33,6 @@ std = [ "sp-application-crypto/std", "sp-authority-discovery/std", "codec/std", - "sp-core/std", - "sp-io/std", "sp-std/std", "serde", "pallet-session/std", diff --git a/frame/authority-discovery/README.md b/frame/authority-discovery/README.md new file mode 100644 index 0000000000000000000000000000000000000000..9a534dcbeb6f8f98ec2260176ca4075f81179194 --- /dev/null +++ b/frame/authority-discovery/README.md @@ -0,0 +1,6 @@ +# Authority discovery module. + +This module is used by the `client/authority-discovery` to retrieve the +current set of authorities. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index ca3e293ae740e69dad63f366cdc34c38023fe046..55e32b21dcb94ccf152cbe5c70c8ff0d222c314c 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! # Authority discovery module. //! @@ -122,6 +123,7 @@ mod tests { type ValidatorIdOf = ConvertInto; type DisabledValidatorsThreshold = DisabledValidatorsThreshold; type NextSessionRotation = pallet_session::PeriodicSessions; + type WeightInfo = (); } impl pallet_session::historical::Trait for Test { @@ -142,6 +144,7 @@ mod tests { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = BlockNumber; @@ -157,6 +160,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -164,10 +168,11 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } impl_outer_origin! { - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } pub struct TestSessionHandler; diff --git a/frame/authorship/Cargo.toml b/frame/authorship/Cargo.toml index 98776c0e00d012a35d3d4faa5d82f6b8622b5655..f351b2d6670adf2c351d4000fb14f2293ed398f4 100644 --- a/frame/authorship/Cargo.toml +++ b/frame/authorship/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "pallet-authorship" -version = "2.0.0-dev" +version = "2.0.0-rc6" description = "Block and Uncle Author tracking for the FRAME" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" @@ -12,27 +12,27 @@ repository = "https://github.com/paritytech/substrate/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-core = { version = "2.0.0-dev", default-features = false, path = "../../primitives/core" } -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } -sp-authorship = { version = "2.0.0-dev", default-features = false, path = "../../primitives/authorship" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -sp-io ={ path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/inherents" } +sp-authorship = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/authorship" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } impl-trait-for-tuples = "0.1.3" +[dev-dependencies] +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } +sp-io ={ version = "2.0.0-rc6", path = "../../primitives/io" } + [features] default = ["std"] std = [ "codec/std", - "sp-core/std", "sp-inherents/std", "sp-runtime/std", "sp-std/std", "frame-support/std", "frame-system/std", - "sp-io/std", "sp-authorship/std", ] diff --git a/frame/authorship/README.md b/frame/authorship/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d61747da3e101b4989b517a77c166cf98cbce6fe --- /dev/null +++ b/frame/authorship/README.md @@ -0,0 +1,5 @@ +Authorship tracking for FRAME runtimes. + +This tracks the current author of the block and recent uncles. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index e799ec2367e84e6627e23396f15b34e620db0bc5..91cad247cac578247104075f27cb7ffaa4ac1135 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -1,18 +1,19 @@ -// Copyright 2019-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. -// Substrate 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. - -// Substrate 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 Substrate. If not, see . +// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. //! Authorship tracking for FRAME runtimes. //! @@ -403,7 +404,7 @@ mod tests { use frame_support::{parameter_types, impl_outer_origin, ConsensusEngineId, weights::Weight}; impl_outer_origin!{ - pub enum Origin for Test where system = frame_system {} + pub enum Origin for Test where system = frame_system {} } #[derive(Clone, Eq, PartialEq)] @@ -417,6 +418,7 @@ mod tests { } impl frame_system::Trait for Test { + type BaseCallFilter = (); type Origin = Origin; type Index = u64; type BlockNumber = u64; @@ -432,6 +434,7 @@ mod tests { type DbWeight = (); type BlockExecutionWeight = (); type ExtrinsicBaseWeight = (); + type MaximumExtrinsicWeight = MaximumBlockWeight; type AvailableBlockRatio = AvailableBlockRatio; type MaximumBlockLength = MaximumBlockLength; type Version = (); @@ -439,6 +442,7 @@ mod tests { type AccountData = (); type OnNewAccount = (); type OnKilledAccount = (); + type SystemWeightInfo = (); } parameter_types! { diff --git a/frame/babe/Cargo.toml b/frame/babe/Cargo.toml index 631b4ac4d4abdda90fd6c810a4943aa28401d9d5..5b59dd6b2781904e6e3ad04fdf459b812e2693fd 100644 --- a/frame/babe/Cargo.toml +++ b/frame/babe/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "pallet-babe" -version = "2.0.0-dev" +version = "2.0.0-rc6" authors = ["Parity Technologies "] edition = "2018" -license = "GPL-3.0" +license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Consensus extension module for BABE consensus. Collects on-chain randomness from VRF outputs and manages epoch transitions." @@ -12,41 +12,53 @@ description = "Consensus extension module for BABE consensus. Collects on-chain targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] } +frame-benchmarking = { version = "2.0.0-rc6", default-features = false, path = "../benchmarking", optional = true } +frame-support = { version = "2.0.0-rc6", default-features = false, path = "../support" } +frame-system = { version = "2.0.0-rc6", default-features = false, path = "../system" } +pallet-authorship = { version = "2.0.0-rc6", default-features = false, path = "../authorship" } +pallet-session = { version = "2.0.0-rc6", default-features = false, path = "../session" } +pallet-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../timestamp" } serde = { version = "1.0.101", optional = true } -sp-inherents = { version = "2.0.0-dev", default-features = false, path = "../../primitives/inherents" } -sp-application-crypto = { version = "2.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } -sp-std = { version = "2.0.0-dev", default-features = false, path = "../../primitives/std" } -sp-runtime = { version = "2.0.0-dev", default-features = false, path = "../../primitives/runtime" } -sp-staking = { version = "2.0.0-dev", default-features = false, path = "../../primitives/staking" } -frame-support = { version = "2.0.0-dev", default-features = false, path = "../support" } -frame-system = { version = "2.0.0-dev", default-features = false, path = "../system" } -pallet-timestamp = { version = "2.0.0-dev", default-features = false, path = "../timestamp" } -sp-timestamp = { version = "2.0.0-dev", default-features = false, path = "../../primitives/timestamp" } -pallet-session = { version = "2.0.0-dev", default-features = false, path = "../session" } -sp-consensus-babe = { version = "0.8.0-dev", default-features = false, path = "../../primitives/consensus/babe" } -sp-consensus-vrf = { version = "0.8.0-dev", default-features = false, path = "../../primitives/consensus/vrf" } -sp-io = { path = "../../primitives/io", default-features = false , version = "2.0.0-dev"} +sp-application-crypto = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/application-crypto" } +sp-consensus-babe = { version = "0.8.0-rc6", default-features = false, path = "../../primitives/consensus/babe" } +sp-consensus-vrf = { version = "0.8.0-rc6", default-features = false, path = "../../primitives/consensus/vrf" } +sp-inherents = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/inherents" } +sp-io = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/runtime" } +sp-session = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/session" } +sp-staking = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/staking" } +sp-std = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/std" } +sp-timestamp = { version = "2.0.0-rc6", default-features = false, path = "../../primitives/timestamp" } [dev-dependencies] -sp-core = { version = "2.0.0-dev", path = "../../primitives/core" } +frame-benchmarking = { version = "2.0.0-rc6", path = "../benchmarking" } +pallet-balances = { version = "2.0.0-rc6", path = "../balances" } +pallet-offences = { version = "2.0.0-rc6", path = "../offences" } +pallet-staking = { version = "2.0.0-rc6", path = "../staking" } +pallet-staking-reward-curve = { version = "2.0.0-rc6", path = "../staking/reward-curve" } +sp-core = { version = "2.0.0-rc6", path = "../../primitives/core" } [features] default = ["std"] std = [ - "serde", "codec/std", - "sp-std/std", - "sp-application-crypto/std", + "frame-benchmarking/std", "frame-support/std", - "sp-runtime/std", - "sp-staking/std", "frame-system/std", + "pallet-authorship/std", + "pallet-session/std", "pallet-timestamp/std", - "sp-timestamp/std", - "sp-inherents/std", + "serde", + "sp-application-crypto/std", "sp-consensus-babe/std", "sp-consensus-vrf/std", - "pallet-session/std", + "sp-inherents/std", "sp-io/std", + "sp-runtime/std", + "sp-session/std", + "sp-staking/std", + "sp-std/std", + "sp-timestamp/std", ] +runtime-benchmarks = ["frame-benchmarking"] diff --git a/frame/babe/README.md b/frame/babe/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6f20be89efc0cd57bcf4ab1a082f1f5198e42fa7 --- /dev/null +++ b/frame/babe/README.md @@ -0,0 +1,4 @@ +Consensus extension module for BABE consensus. Collects on-chain randomness +from VRF outputs and manages epoch transitions. + +License: Apache-2.0 \ No newline at end of file diff --git a/frame/babe/src/benchmarking.rs b/frame/babe/src/benchmarking.rs new file mode 100644 index 0000000000000000000000000000000000000000..8ee4a5913c885290bd42f07a094db982937af37c --- /dev/null +++ b/frame/babe/src/benchmarking.rs @@ -0,0 +1,106 @@ +// This file is part of Substrate. + +// Copyright (C) 2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// 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. + +//! Benchmarks for the BABE Pallet. + +use super::*; +use frame_benchmarking::benchmarks; + +type Header = sp_runtime::generic::Header; + +benchmarks! { + _ { } + + check_equivocation_proof { + let x in 0 .. 1; + + // NOTE: generated with the test below `test_generate_equivocation_report_blob`. + // the output is not deterministic since keys are generated randomly (and therefore + // signature content changes). it should not affect the benchmark. + // with the current benchmark setup it is not possible to generate this programatically + // from the benchmark setup. + const EQUIVOCATION_PROOF_BLOB: [u8; 416] = [ + 222, 241, 46, 66, 243, 228, 135, 233, 177, 64, 149, 170, 141, 92, 193, 106, 51, 73, 31, + 27, 80, 218, 220, 248, 129, 29, 20, 128, 243, 250, 134, 39, 11, 0, 0, 0, 0, 0, 0, 0, + 158, 4, 7, 240, 67, 153, 134, 190, 251, 196, 229, 95, 136, 165, 234, 228, 255, 18, 2, + 187, 76, 125, 108, 50, 67, 33, 196, 108, 38, 115, 179, 86, 40, 36, 27, 5, 105, 58, 228, + 94, 198, 65, 212, 218, 213, 61, 170, 21, 51, 249, 182, 121, 101, 91, 204, 25, 31, 87, + 219, 208, 43, 119, 211, 185, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, 66, 65, 66, 69, 52, 2, 0, 0, 0, 0, 11, + 0, 0, 0, 0, 0, 0, 0, 5, 66, 65, 66, 69, 1, 1, 188, 192, 217, 91, 138, 78, 217, 80, 8, + 29, 140, 55, 242, 210, 170, 184, 73, 98, 135, 212, 236, 209, 115, 52, 200, 79, 175, + 172, 242, 161, 199, 47, 236, 93, 101, 95, 43, 34, 141, 16, 247, 220, 33, 59, 31, 197, + 27, 7, 196, 62, 12, 238, 236, 124, 136, 191, 29, 36, 22, 238, 242, 202, 57, 139, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 40, 23, 175, 153, 83, 6, 33, 65, 123, 51, 80, 223, 126, 186, 226, 225, 240, 105, 28, + 169, 9, 54, 11, 138, 46, 194, 201, 250, 48, 242, 125, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, 66, 65, + 66, 69, 52, 2, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 5, 66, 65, 66, 69, 1, 1, 142, 12, + 124, 11, 167, 227, 103, 88, 78, 23, 228, 33, 96, 41, 207, 183, 227, 189, 114, 70, 254, + 30, 128, 243, 233, 83, 214, 45, 74, 182, 120, 119, 64, 243, 219, 119, 63, 240, 205, + 123, 231, 82, 205, 174, 143, 70, 2, 86, 182, 20, 16, 141, 145, 91, 116, 195, 58, 223, + 175, 145, 255, 7, 121, 133 + ]; + + let equivocation_proof1: sp_consensus_babe::EquivocationProof